ZGlmZiAtLWdpdCBhL3NyYy9NYWtlZmlsZS5hbSBiL3NyYy9NYWtlZmlsZS5hbQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wNzM2NzNhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL01ha2VmaWxlLmFtCkBAIC0wLDAgKzEsODI1IEBACisjIyBQcm9jZXNzIHRoaXMgZmlsZSB3aXRoIGF1dG9tYWtlIHRvIHByb2R1Y2UgTWFrZWZpbGUuaW4KKworaWYgSEFWRV9aTElCCitHWkNIRUNLUFJPR1JBTVMgPSB6Y2d6aXAgemNndW56aXAKK0daSEVBREVSUyA9IGdvb2dsZS9wcm90b2J1Zi9pby9nemlwX3N0cmVhbS5oCitHWlRFU1RTID0gZ29vZ2xlL3Byb3RvYnVmL2lvL2d6aXBfc3RyZWFtX3VuaXR0ZXN0LnNoCitaTElCX0RFRiA9IC1ESEFWRV9aTElCPTEKK2Vsc2UKK0daQ0hFQ0tQUk9HUkFNUyA9CitHWkhFQURFUlMgPQorR1pURVNUUyA9CitaTElCX0RFRiA9CitlbmRpZgorCitpZiBIQVZFX1BUSFJFQUQKK1BUSFJFQURfREVGID0gLURIQVZFX1BUSFJFQUQ9MQorZWxzZQorUFRIUkVBRF9ERUYgPQorZW5kaWYKKworaWYgR0NDCisjIFRoZXNlIGFyZSBnb29kIHdhcm5pbmdzIHRvIHR1cm4gb24gYnkgZGVmYXVsdAorTk9fT1BUX0NYWEZMQUdTID0gJChQVEhSRUFEX0NGTEFHUykgJChQVEhSRUFEX0RFRikgJChaTElCX0RFRikgLVdhbGwgLVd3cml0ZS1zdHJpbmdzIC1Xb3ZlcmxvYWRlZC12aXJ0dWFsIC1Xbm8tc2lnbi1jb21wYXJlCitlbHNlCitOT19PUFRfQ1hYRkxBR1MgPSAkKFBUSFJFQURfQ0ZMQUdTKSAkKFBUSFJFQURfREVGKSAkKFpMSUJfREVGKQorZW5kaWYKKworQU1fQ1hYRkxBR1MgPSAkKE5PX09QVF9DWFhGTEFHUykgJChQUk9UT0JVRl9PUFRfRkxBRykKKworQU1fTERGTEFHUyA9ICQoUFRIUkVBRF9DRkxBR1MpCisKKyMgSWYgSSBzYXkgImRpc3RfaW5jbHVkZV9EQVRBIiwgYXV0b21ha2UgY29tcGxhaW5zIHRoYXQgJChpbmNsdWRlZGlyKSBpcyBub3QKKyMgYSAibGVnaXRpbWF0ZSIgZGlyZWN0b3J5IGZvciBEQVRBLiAgU2NyZXcgeW91LCBhdXRvbWFrZS4KK3Byb3RvZGlyID0gJChpbmNsdWRlZGlyKQorbm9iYXNlX2Rpc3RfcHJvdG9fREFUQSA9IGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgZ29vZ2xlL3Byb3RvYnVmL2FueS5wcm90byAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICBnb29nbGUvcHJvdG9idWYvYXBpLnByb3RvICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgIGdvb2dsZS9wcm90b2J1Zi9kdXJhdGlvbi5wcm90byAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgZ29vZ2xlL3Byb3RvYnVmL2VtcHR5LnByb3RvICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICBnb29nbGUvcHJvdG9idWYvZmllbGRfbWFzay5wcm90byAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgIGdvb2dsZS9wcm90b2J1Zi9zb3VyY2VfY29udGV4dC5wcm90byBcCisgICAgICAgICAgICAgICAgICAgICAgICAgZ29vZ2xlL3Byb3RvYnVmL3N0cnVjdC5wcm90byAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICBnb29nbGUvcHJvdG9idWYvdGltZXN0YW1wLnByb3RvICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgIGdvb2dsZS9wcm90b2J1Zi90eXBlLnByb3RvICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgZ29vZ2xlL3Byb3RvYnVmL3dyYXBwZXJzLnByb3RvICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLnByb3RvCisKKyMgTm90IHN1cmUgd2h5IHRoZXNlIGRvbid0IGdldCBjbGVhbmVkIGF1dG9tYXRpY2FsbHkuCitjbGVhbi1sb2NhbDoKKwlybSAtZiAqLmxvVAorCitDTEVBTkZJTEVTID0gJChwcm90b2Nfb3V0cHV0cykgdW5pdHRlc3RfcHJvdG9fbWlkZGxlbWFuIFwKKyAgICAgICAgICAgICB0ZXN0emlwLmphciB0ZXN0emlwLmxpc3QgdGVzdHppcC5wcm90byB0ZXN0emlwLnppcAorCitNQUlOVEFJTkVSQ0xFQU5GSUxFUyA9ICAgXAorICBNYWtlZmlsZS5pbgorCitub2Jhc2VfaW5jbHVkZV9IRUFERVJTID0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljX3NlcXVlbmNlX251bS5oICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wcy5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX3Bvd2VyLmggICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc19hcm02NF9nY2MuaCAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfYXJtX2djYy5oICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX2FybV9xbnguaCAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc19hdG9taWN3b3JkX2NvbXBhdC5oIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfZ2VuZXJpY19nY2MuaCAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX21hY29zeC5oICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc19taXBzX2djYy5oICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfcG5hY2wuaCAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX3NvbGFyaXMuaCAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc190c2FuLmggICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfeDg2X2djYy5oICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX3g4Nl9tc3ZjLmggICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvc3R1YnMvY2FsbGJhY2suaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2J5dGVzdHJlYW0uaCAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jYXN0cy5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2Zhc3RtZW0uaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9oYXNoLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvc3R1YnMvbG9nZ2luZy5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL21hY3Jvcy5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9tdXRleC5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvc3R1YnMvb25jZS5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3BsYXRmb3JtX21hY3Jvcy5oICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9wb3J0LmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvc3R1YnMvc2NvcGVkX3B0ci5oICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaW5nbGV0b24uaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RhdHVzLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0bF91dGlsLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJpbmdwaWVjZS5oICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvc3R1YnMvdGVtcGxhdGVfdXRpbC5oICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3R5cGVfdHJhaXRzLmggICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9hbnkucGIuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvYXBpLnBiLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2FueS5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9hcmVuYS5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvYXJlbmFzdHJpbmcuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3JfZGF0YWJhc2UuaCAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2R1cmF0aW9uLnBiLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9keW5hbWljX21lc3NhZ2UuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvZW1wdHkucGIuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2V4dGVuc2lvbl9zZXQuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9maWVsZF9tYXNrLnBiLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX2VudW1fcmVmbGVjdGlvbi5oICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9lbnVtX3V0aWwuaCAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfbWVzc2FnZV9yZWZsZWN0aW9uLmggICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX21lc3NhZ2VfdXRpbC5oICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL21hcF9lbnRyeS5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9tYXBfZW50cnlfbGl0ZS5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvbWFwX2ZpZWxkLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL21hcF9maWVsZF9pbmwuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9tYXBfZmllbGRfbGl0ZS5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvbWFwLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL21hcF90eXBlX2hhbmRsZXIuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9tZXNzYWdlLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvbWVzc2FnZV9saXRlLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL21ldGFkYXRhLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9yZWZsZWN0aW9uLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvcmVmbGVjdGlvbl9vcHMuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3JlcGVhdGVkX2ZpZWxkLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9yZXBlYXRlZF9maWVsZF9yZWZsZWN0aW9uLmggICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvc2VydmljZS5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3NvdXJjZV9jb250ZXh0LnBiLmggICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHJ1Y3QucGIuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdGV4dF9mb3JtYXQuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3RpbWVzdGFtcC5wYi5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi90eXBlLnBiLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5rbm93bl9maWVsZF9zZXQuaCAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0LmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdF9saXRlLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZV9pbmwuaCAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3dyYXBwZXJzLnBiLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW0uaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAkKEdaSEVBREVSUykgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9pby9zdHJ0b2QuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvaW8vdG9rZW5pemVyLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW0uaCAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX2ltcGwuaCAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbV9pbXBsX2xpdGUuaCAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvZGVfZ2VuZXJhdG9yLmggICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jb21tYW5kX2xpbmVfaW50ZXJmYWNlLmggICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvaW1wb3J0ZXIuaCAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BhcnNlci5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wbHVnaW4uaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLnBiLmggICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZ2VuZXJhdG9yLmggICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX2dlbmVyYXRvci5oICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9uYW1lcy5oICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9nZW5lcmF0b3IuaCAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbmFtZXMuaCAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZ2VuZXJhdG9yLmggICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2pzL2pzX2dlbmVyYXRvci5oICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfZ2VuZXJhdG9yLmggICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX2hlbHBlcnMuaCAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3B5dGhvbi9weXRob25fZ2VuZXJhdG9yLmggICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9ydWJ5L3J1YnlfZ2VuZXJhdG9yLmggICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC90eXBlX3Jlc29sdmVyLmggICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3V0aWwvZmllbGRfY29tcGFyYXRvci5oICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi91dGlsL2ZpZWxkX21hc2tfdXRpbC5oICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9qc29uX3V0aWwuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3V0aWwvdGltZV91dGlsLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi91dGlsL3R5cGVfcmVzb2x2ZXJfdXRpbC5oICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9tZXNzYWdlX2RpZmZlcmVuY2VyLmgKKworbGliX0xUTElCUkFSSUVTID0gbGlicHJvdG9idWYtbGl0ZS5sYSBsaWJwcm90b2J1Zi5sYSBsaWJwcm90b2MubGEKKworbGlicHJvdG9idWZfbGl0ZV9sYV9MSUJBREQgPSAkKFBUSFJFQURfTElCUykKK2xpYnByb3RvYnVmX2xpdGVfbGFfTERGTEFHUyA9IC12ZXJzaW9uLWluZm8gMTA6MDowIC1leHBvcnQtZHluYW1pYyAtbm8tdW5kZWZpbmVkCitsaWJwcm90b2J1Zl9saXRlX2xhX1NPVVJDRVMgPSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX3g4Nl9nY2MuY2MgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX3g4Nl9tc3ZjLmNjICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9ieXRlc3RyZWFtLmNjICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9ieXRlc3RyZWFtLmggICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9oYXNoLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9pbnQxMjguY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9pbnQxMjguaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9tYXBfdXRpbC5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9tYXRodXRpbC5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9vbmNlLmNjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaGFyZWRfcHRyLmggICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdGF0dXMuY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdGF0dXMuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdGF0dXNfbWFjcm9zLmggICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdGF0dXNvci5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdGF0dXNvci5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJpbmdwaWVjZS5jYyAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJpbmdwaWVjZS5oICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJpbmdwcmludGYuY2MgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJpbmdwcmludGYuaCAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1Y3R1cmFsbHlfdmFsaWQuY2MgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmNjICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy90aW1lLmNjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9zdHVicy90aW1lLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9hcmVuYS5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9hcmVuYXN0cmluZy5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9leHRlbnNpb25fc2V0LmNjICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfbWVzc2FnZV91dGlsLmNjICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9tZXNzYWdlX2xpdGUuY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9yZXBlYXRlZF9maWVsZC5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdF9saXRlLmNjICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW0uY2MgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW1faW5sLmggICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtLmNjICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX2ltcGxfbGl0ZS5jYworCitsaWJwcm90b2J1Zl9sYV9MSUJBREQgPSAkKFBUSFJFQURfTElCUykKK2xpYnByb3RvYnVmX2xhX0xERkxBR1MgPSAtdmVyc2lvbi1pbmZvIDEwOjA6MCAtZXhwb3J0LWR5bmFtaWMgLW5vLXVuZGVmaW5lZAorbGlicHJvdG9idWZfbGFfU09VUkNFUyA9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAkKGxpYnByb3RvYnVmX2xpdGVfbGFfU09VUkNFUykgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvYW55LnBiLmNjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvYXBpLnBiLmNjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvc3R1YnMvbWF0aGxpbWl0cy5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvc3R1YnMvbWF0aGxpbWl0cy5oICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvYW55LmNjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvcl9kYXRhYmFzZS5jYyAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvZHVyYXRpb24ucGIuY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvZHluYW1pY19tZXNzYWdlLmNjICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvZW1wdHkucGIuY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvZXh0ZW5zaW9uX3NldF9oZWF2eS5jYyAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvZmllbGRfbWFzay5wYi5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX21lc3NhZ2VfcmVmbGVjdGlvbi5jYyAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvbWFwX2ZpZWxkLmNjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvbWVzc2FnZS5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvcmVmbGVjdGlvbl9pbnRlcm5hbC5oICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvcmVmbGVjdGlvbl9vcHMuY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvc2VydmljZS5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvc291cmNlX2NvbnRleHQucGIuY2MgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvc3RydWN0LnBiLmNjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvc3R1YnMvc3Vic3RpdHV0ZS5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvc3R1YnMvc3Vic3RpdHV0ZS5oICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdGV4dF9mb3JtYXQuY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdGltZXN0YW1wLnBiLmNjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdHlwZS5wYi5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5rbm93bl9maWVsZF9zZXQuY2MgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvd3JhcHBlcnMucGIuY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvaW8vZ3ppcF9zdHJlYW0uY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvaW8vc3RydG9kLmNjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvaW8vdG9rZW5pemVyLmNjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbV9pbXBsLmNjICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvaW1wb3J0ZXIuY2MgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGFyc2VyLmNjICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9maWVsZF9jb21wYXJhdG9yLmNjICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9maWVsZF9tYXNrX3V0aWwuY2MgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9jb25zdGFudHMuaCAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9kYXRhcGllY2UuY2MgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9kYXRhcGllY2UuaCAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9kZWZhdWx0X3ZhbHVlX29iamVjdHdyaXRlci5jYyAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9kZWZhdWx0X3ZhbHVlX29iamVjdHdyaXRlci5oICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9lcnJvcl9saXN0ZW5lci5jYyAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9lcnJvcl9saXN0ZW5lci5oICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9leHBlY3Rpbmdfb2JqZWN0d3JpdGVyLmggICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9maWVsZF9tYXNrX3V0aWxpdHkuY2MgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9maWVsZF9tYXNrX3V0aWxpdHkuaCAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9qc29uX2VzY2FwaW5nLmNjICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9qc29uX2VzY2FwaW5nLmggICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9qc29uX29iamVjdHdyaXRlci5jYyAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9qc29uX29iamVjdHdyaXRlci5oICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9qc29uX3N0cmVhbV9wYXJzZXIuY2MgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9qc29uX3N0cmVhbV9wYXJzZXIuaCAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9sb2NhdGlvbl90cmFja2VyLmggICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9tb2NrX2Vycm9yX2xpc3RlbmVyLmggICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9vYmplY3RfbG9jYXRpb25fdHJhY2tlci5oICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9vYmplY3Rfc291cmNlLmggICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9vYmplY3Rfd3JpdGVyLmNjICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9vYmplY3Rfd3JpdGVyLmggICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9wcm90b3N0cmVhbV9vYmplY3Rzb3VyY2UuY2MgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9wcm90b3N0cmVhbV9vYmplY3Rzb3VyY2UuaCAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9wcm90b3N0cmVhbV9vYmplY3R3cml0ZXIuY2MgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9wcm90b3N0cmVhbV9vYmplY3R3cml0ZXIuaCAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9wcm90b193cml0ZXIuY2MgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9wcm90b193cml0ZXIuaCAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9zdHJ1Y3R1cmVkX29iamVjdHdyaXRlci5oICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90eXBlX2luZm8uY2MgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90eXBlX2luZm8uaCAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90eXBlX2luZm9fdGVzdF9oZWxwZXIuY2MgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90eXBlX2luZm9fdGVzdF9oZWxwZXIuaCAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC91dGlsaXR5LmNjICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC91dGlsaXR5LmggICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9qc29uX3V0aWwuY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9tZXNzYWdlX2RpZmZlcmVuY2VyLmNjICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC90aW1lX3V0aWwuY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC90eXBlX3Jlc29sdmVyX3V0aWwuY2MKKworbm9kaXN0X2xpYnByb3RvYnVmX2xhX1NPVVJDRVMgPSAkKG5vZGlzdF9saWJwcm90b2J1Zl9saXRlX2xhX1NPVVJDRVMpCisKK2xpYnByb3RvY19sYV9MSUJBREQgPSAkKFBUSFJFQURfTElCUykgbGlicHJvdG9idWYubGEKK2xpYnByb3RvY19sYV9MREZMQUdTID0gLXZlcnNpb24taW5mbyAxMDowOjAgLWV4cG9ydC1keW5hbWljIC1uby11bmRlZmluZWQKK2xpYnByb3RvY19sYV9TT1VSQ0VTID0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvZGVfZ2VuZXJhdG9yLmNjICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvbW1hbmRfbGluZV9pbnRlcmZhY2UuY2MgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BsdWdpbi5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BsdWdpbi5wYi5jYyAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3N1YnByb2Nlc3MuY2MgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3N1YnByb2Nlc3MuaCAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3ppcF93cml0ZXIuY2MgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3ppcF93cml0ZXIuaCAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZW51bS5jYyAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZW51bS5oICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZW51bV9maWVsZC5jYyAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZW51bV9maWVsZC5oICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZXh0ZW5zaW9uLmNjICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZXh0ZW5zaW9uLmggICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZmllbGQuY2MgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZmllbGQuaCAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZmlsZS5jYyAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZmlsZS5oICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZ2VuZXJhdG9yLmNjICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfaGVscGVycy5jYyAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfaGVscGVycy5oICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfbWFwX2ZpZWxkLmNjICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfbWFwX2ZpZWxkLmggICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfbWVzc2FnZS5jYyAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfbWVzc2FnZS5oICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfbWVzc2FnZV9maWVsZC5jYyAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfbWVzc2FnZV9maWVsZC5oICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfb3B0aW9ucy5oICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfcHJpbWl0aXZlX2ZpZWxkLmNjICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfcHJpbWl0aXZlX2ZpZWxkLmggICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfc2VydmljZS5jYyAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfc2VydmljZS5oICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfc3RyaW5nX2ZpZWxkLmNjICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfc3RyaW5nX2ZpZWxkLmggICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9jb250ZXh0LmNjICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9jb250ZXh0LmggICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9lbnVtLmNjICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9lbnVtX2xpdGUuY2MgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9lbnVtX2ZpZWxkLmNjICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9lbnVtX2ZpZWxkLmggICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9lbnVtX2ZpZWxkX2xpdGUuY2MgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9lbnVtX2ZpZWxkX2xpdGUuaCAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9lbnVtLmggICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9lbnVtX2xpdGUuaCAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9leHRlbnNpb24uY2MgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9leHRlbnNpb24uaCAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9leHRlbnNpb25fbGl0ZS5jYyAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9leHRlbnNpb25fbGl0ZS5oICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9maWVsZC5jYyAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9maWVsZC5oICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9maWxlLmNjICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9maWxlLmggICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9nZW5lcmF0b3IuY2MgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9nZW5lcmF0b3JfZmFjdG9yeS5jYyAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9nZW5lcmF0b3JfZmFjdG9yeS5oICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9oZWxwZXJzLmNjICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9oZWxwZXJzLmggICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9sYXp5X21lc3NhZ2VfZmllbGQuY2MgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9sYXp5X21lc3NhZ2VfZmllbGQuaCAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9sYXp5X21lc3NhZ2VfZmllbGRfbGl0ZS5jY1wKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9sYXp5X21lc3NhZ2VfZmllbGRfbGl0ZS5oIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tYXBfZmllbGQuY2MgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tYXBfZmllbGQuaCAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tYXBfZmllbGRfbGl0ZS5jYyAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tYXBfZmllbGRfbGl0ZS5oICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tZXNzYWdlLmNjICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tZXNzYWdlX2xpdGUuY2MgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tZXNzYWdlX2J1aWxkZXIuY2MgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tZXNzYWdlX2J1aWxkZXJfbGl0ZS5jYyAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tZXNzYWdlX2ZpZWxkLmNjICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tZXNzYWdlX2ZpZWxkLmggICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tZXNzYWdlX2ZpZWxkX2xpdGUuY2MgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tZXNzYWdlX2ZpZWxkX2xpdGUuaCAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tZXNzYWdlLmggICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tZXNzYWdlX2xpdGUuaCAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tZXNzYWdlX2J1aWxkZXIuaCAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tZXNzYWdlX2J1aWxkZXJfbGl0ZS5oICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9uYW1lX3Jlc29sdmVyLmNjICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9uYW1lX3Jlc29sdmVyLmggICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9wcmltaXRpdmVfZmllbGQuY2MgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9wcmltaXRpdmVfZmllbGQuaCAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9wcmltaXRpdmVfZmllbGRfbGl0ZS5jYyAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9wcmltaXRpdmVfZmllbGRfbGl0ZS5oICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9zaGFyZWRfY29kZV9nZW5lcmF0b3IuY2MgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9zaGFyZWRfY29kZV9nZW5lcmF0b3IuaCAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9zZXJ2aWNlLmNjICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9zZXJ2aWNlLmggICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9zdHJpbmdfZmllbGQuY2MgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9zdHJpbmdfZmllbGQuaCAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9zdHJpbmdfZmllbGRfbGl0ZS5jYyAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9zdHJpbmdfZmllbGRfbGl0ZS5oICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9kb2NfY29tbWVudC5jYyAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9kb2NfY29tbWVudC5oICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2pzL2pzX2dlbmVyYXRvci5jYyAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2VudW0uY2MgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2VudW0uaCAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2VudW1fZmllbGQuY2MgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2VudW1fZmllbGQuaCAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2V4dGVuc2lvbi5jYyAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2V4dGVuc2lvbi5oICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2ZpZWxkLmNjICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2ZpZWxkLmggICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2ZpbGUuY2MgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2ZpbGUuaCAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2dlbmVyYXRvci5jYyAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2dlbmVyYXRvci5oICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2hlbHBlcnMuY2MgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2hlbHBlcnMuaCAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX21hcF9maWVsZC5jYyAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX21hcF9maWVsZC5oICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX21lc3NhZ2UuY2MgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX21lc3NhZ2UuaCAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX21lc3NhZ2VfZmllbGQuY2MgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX21lc3NhZ2VfZmllbGQuaCAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX3BhcmFtcy5oICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX3ByaW1pdGl2ZV9maWVsZC5jYyBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19wcmltaXRpdmVfZmllbGQuaCBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfZW51bS5jYyAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfZW51bS5oICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfZW51bV9maWVsZC5jYyBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfZW51bV9maWVsZC5oICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfZXh0ZW5zaW9uLmNjICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfZXh0ZW5zaW9uLmggICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfZmllbGQuY2MgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfZmllbGQuaCAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfZmlsZS5jYyAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfZmlsZS5oICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfZ2VuZXJhdG9yLmNjICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfaGVscGVycy5jYyAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfaGVscGVycy5oICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfbWFwX2ZpZWxkLmNjICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfbWFwX2ZpZWxkLmggICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfbWVzc2FnZS5jYyAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfbWVzc2FnZS5oICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfbWVzc2FnZV9maWVsZC5jYyBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfbWVzc2FnZV9maWVsZC5oIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19vbmVvZi5jYyAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19vbmVvZi5oICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19wcmltaXRpdmVfZmllbGQuY2MgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX3ByaW1pdGl2ZV9maWVsZC5oIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3B5dGhvbi9weXRob25fZ2VuZXJhdG9yLmNjICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3J1YnkvcnVieV9nZW5lcmF0b3IuY2MgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfZG9jX2NvbW1lbnQuY2MgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfZG9jX2NvbW1lbnQuaCAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfZW51bS5jYyAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfZW51bS5oICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfZW51bV9maWVsZC5jYyAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfZW51bV9maWVsZC5oICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfZmllbGRfYmFzZS5jYyAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfZmllbGRfYmFzZS5oICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfZ2VuZXJhdG9yLmNjICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfaGVscGVycy5jYyAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfaGVscGVycy5oICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfbWFwX2ZpZWxkLmNjICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfbWFwX2ZpZWxkLmggICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfbWVzc2FnZS5jYyAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfbWVzc2FnZS5oICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfbWVzc2FnZV9maWVsZC5jYyAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfbWVzc2FnZV9maWVsZC5oICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfcHJpbWl0aXZlX2ZpZWxkLmNjICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfcHJpbWl0aXZlX2ZpZWxkLmggICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfcmVmbGVjdGlvbl9jbGFzcy5jYyAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9yZWZsZWN0aW9uX2NsYXNzLmggICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX3JlcGVhdGVkX2VudW1fZmllbGQuY2MgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9yZXBlYXRlZF9lbnVtX2ZpZWxkLmggXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9yZXBlYXRlZF9tZXNzYWdlX2ZpZWxkLmNjIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfcmVwZWF0ZWRfbWVzc2FnZV9maWVsZC5oIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfcmVwZWF0ZWRfcHJpbWl0aXZlX2ZpZWxkLmNjIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfcmVwZWF0ZWRfcHJpbWl0aXZlX2ZpZWxkLmggXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9zb3VyY2VfZ2VuZXJhdG9yX2Jhc2UuY2MgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9zb3VyY2VfZ2VuZXJhdG9yX2Jhc2UuaCBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX3dyYXBwZXJfZmllbGQuY2MgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX3dyYXBwZXJfZmllbGQuaAorCitiaW5fUFJPR1JBTVMgPSBwcm90b2MKK3Byb3RvY19MREFERCA9ICQoUFRIUkVBRF9MSUJTKSBsaWJwcm90b2J1Zi5sYSBsaWJwcm90b2MubGEKK3Byb3RvY19TT1VSQ0VTID0gZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL21haW4uY2MKKworIyBUZXN0cyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitwcm90b2NfaW5wdXRzID0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9hbnlfdGVzdC5wcm90byAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX3Rlc3RfYmFkX2lkZW50aWZpZXJzLnByb3RvICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9tYXBfbGl0ZV91bml0dGVzdC5wcm90byAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9tYXBfcHJvdG8yX3VuaXR0ZXN0LnByb3RvICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9tYXBfdW5pdHRlc3QucHJvdG8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9hcmVuYS5wcm90byAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9jdXN0b21fb3B0aW9ucy5wcm90byAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9kcm9wX3Vua25vd25fZmllbGRzLnByb3RvICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9lbWJlZF9vcHRpbWl6ZV9mb3IucHJvdG8gICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9lbXB0eS5wcm90byAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9lbm9ybW91c19kZXNjcmlwdG9yLnByb3RvICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9pbXBvcnRfbGl0ZS5wcm90byAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9pbXBvcnQucHJvdG8gICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9pbXBvcnRfcHVibGljX2xpdGUucHJvdG8gICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9pbXBvcnRfcHVibGljLnByb3RvICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9saXRlX2ltcG9ydHNfbm9ubGl0ZS5wcm90byAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9saXRlLnByb3RvICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9tc2V0LnByb3RvICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9tc2V0X3dpcmVfZm9ybWF0LnByb3RvICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9ub19hcmVuYV9saXRlLnByb3RvICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9ub19hcmVuYV9pbXBvcnQucHJvdG8gICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9ub19hcmVuYS5wcm90byAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9ub19maWVsZF9wcmVzZW5jZS5wcm90byAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9ub19nZW5lcmljX3NlcnZpY2VzLnByb3RvICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9vcHRpbWl6ZV9mb3IucHJvdG8gICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9wcmVzZXJ2ZV91bmtub3duX2VudW0yLnByb3RvICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9wcmVzZXJ2ZV91bmtub3duX2VudW0ucHJvdG8gICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wcm90byAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9wcm90bzNfYXJlbmEucHJvdG8gICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF93ZWxsX2tub3duX3R5cGVzLnByb3RvICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3Rlc3RkYXRhL2FueXMucHJvdG8gICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3Rlc3RkYXRhL2Jvb2tzLnByb3RvICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3Rlc3RkYXRhL2RlZmF1bHRfdmFsdWUucHJvdG8gICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3Rlc3RkYXRhL2RlZmF1bHRfdmFsdWVfdGVzdC5wcm90byBcCisgIGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3Rlc3RkYXRhL2ZpZWxkX21hc2sucHJvdG8gICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3Rlc3RkYXRhL21hcHMucHJvdG8gICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3Rlc3RkYXRhL29uZW9mcy5wcm90byAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3Rlc3RkYXRhL3N0cnVjdC5wcm90byAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3Rlc3RkYXRhL3RpbWVzdGFtcF9kdXJhdGlvbi5wcm90byBcCisgIGdvb2dsZS9wcm90b2J1Zi91dGlsL2pzb25fZm9ybWF0X3Byb3RvMy5wcm90byAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi91dGlsL21lc3NhZ2VfZGlmZmVyZW5jZXJfdW5pdHRlc3QucHJvdG8gICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX3Rlc3RfbGFyZ2VfZW51bV92YWx1ZS5wcm90bworCitFWFRSQV9ESVNUID0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICQocHJvdG9jX2lucHV0cykgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHNvbGFyaXMvbGlic3RkYysrLmxhICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9pby9nemlwX3N0cmVhbS5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9pby9nemlwX3N0cmVhbV91bml0dGVzdC5zaCAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi90ZXN0ZGF0YS9nb2xkZW5fbWVzc2FnZSAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi90ZXN0ZGF0YS9nb2xkZW5fbWVzc2FnZV9vbmVvZl9pbXBsZW1lbnRlZCAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi90ZXN0ZGF0YS9nb2xkZW5fbWVzc2FnZV9wcm90bzMgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi90ZXN0ZGF0YS9nb2xkZW5fcGFja2VkX2ZpZWxkc19tZXNzYWdlICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi90ZXN0ZGF0YS9iYWRfdXRmOF9zdHJpbmcgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi90ZXN0ZGF0YS9tYXBfdGVzdF9kYXRhLnR4dCAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi90ZXN0ZGF0YS90ZXh0X2Zvcm1hdF91bml0dGVzdF9kYXRhLnR4dCAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi90ZXN0ZGF0YS90ZXh0X2Zvcm1hdF91bml0dGVzdF9kYXRhX29uZW9mX2ltcGxlbWVudGVkLnR4dCAgXAorICBnb29nbGUvcHJvdG9idWYvdGVzdGRhdGEvdGV4dF9mb3JtYXRfdW5pdHRlc3RfZGF0YV9wb2ludHkudHh0ICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3Rlc3RkYXRhL3RleHRfZm9ybWF0X3VuaXR0ZXN0X2RhdGFfcG9pbnR5X29uZW9mLnR4dCAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi90ZXN0ZGF0YS90ZXh0X2Zvcm1hdF91bml0dGVzdF9leHRlbnNpb25zX2RhdGEudHh0ICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdGVzdGRhdGEvdGV4dF9mb3JtYXRfdW5pdHRlc3RfZXh0ZW5zaW9uc19kYXRhX3BvaW50eS50eHQgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3BhY2thZ2VfaW5mby5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2lvL3BhY2thZ2VfaW5mby5oICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3J1YnkvcnVieV9nZW5lcmF0ZWRfY29kZS5wcm90byAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3J1YnkvcnVieV9nZW5lcmF0ZWRfY29kZS5yYiAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BhY2thZ2VfaW5mby5oICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3ppcF9vdXRwdXRfdW5pdHRlc3Quc2gKKworcHJvdG9jX2xpdGVfb3V0cHV0cyA9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvbWFwX2xpdGVfdW5pdHRlc3QucGIuY2MgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvbWFwX2xpdGVfdW5pdHRlc3QucGIuaCAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfbGl0ZS5wYi5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfbGl0ZS5wYi5oICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fYXJlbmFfbGl0ZS5wYi5jYyAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fYXJlbmFfbGl0ZS5wYi5oICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X2xpdGUucGIuY2MgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X2xpdGUucGIuaCAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X3B1YmxpY19saXRlLnBiLmNjICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X3B1YmxpY19saXRlLnBiLmgKKworcHJvdG9jX291dHB1dHMgPSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAkKHByb3RvY19saXRlX291dHB1dHMpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvYW55X3Rlc3QucGIuY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvYW55X3Rlc3QucGIuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF90ZXN0X2JhZF9pZGVudGlmaWVycy5wYi5jYyAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF90ZXN0X2JhZF9pZGVudGlmaWVycy5wYi5oICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF90ZXN0X2xhcmdlX2VudW1fdmFsdWUucGIuY2MgICAgXAorICBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF90ZXN0X2xhcmdlX2VudW1fdmFsdWUucGIuaCAgICAgXAorICBnb29nbGUvcHJvdG9idWYvbWFwX3Byb3RvMl91bml0dGVzdC5wYi5jYyAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvbWFwX3Byb3RvMl91bml0dGVzdC5wYi5oICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvbWFwX3VuaXR0ZXN0LnBiLmNjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvbWFwX3VuaXR0ZXN0LnBiLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfYXJlbmEucGIuY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfYXJlbmEucGIuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfY3VzdG9tX29wdGlvbnMucGIuY2MgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfY3VzdG9tX29wdGlvbnMucGIuaCAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfZHJvcF91bmtub3duX2ZpZWxkcy5wYi5jYyAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfZHJvcF91bmtub3duX2ZpZWxkcy5wYi5oICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfZW1iZWRfb3B0aW1pemVfZm9yLnBiLmNjICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfZW1iZWRfb3B0aW1pemVfZm9yLnBiLmggICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfZW1wdHkucGIuY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfZW1wdHkucGIuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfZW5vcm1vdXNfZGVzY3JpcHRvci5wYi5jYyAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfZW5vcm1vdXNfZGVzY3JpcHRvci5wYi5oICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0LnBiLmNjICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0LnBiLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wYi5jYyAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wYi5oICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfbGl0ZV9pbXBvcnRzX25vbmxpdGUucGIuY2MgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfbGl0ZV9pbXBvcnRzX25vbmxpdGUucGIuaCAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfbXNldC5wYi5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfbXNldC5wYi5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfbXNldF93aXJlX2Zvcm1hdC5wYi5jYyAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfbXNldF93aXJlX2Zvcm1hdC5wYi5oICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fYXJlbmFfaW1wb3J0LnBiLmNjICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fYXJlbmFfaW1wb3J0LnBiLmggICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fYXJlbmEucGIuY2MgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fYXJlbmEucGIuaCAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fZmllbGRfcHJlc2VuY2UucGIuY2MgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fZmllbGRfcHJlc2VuY2UucGIuaCAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fZ2VuZXJpY19zZXJ2aWNlcy5wYi5jYyAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fZ2VuZXJpY19zZXJ2aWNlcy5wYi5oICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfb3B0aW1pemVfZm9yLnBiLmNjICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfb3B0aW1pemVfZm9yLnBiLmggICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucGIuY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucGIuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJlc2VydmVfdW5rbm93bl9lbnVtMi5wYi5jYyAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJlc2VydmVfdW5rbm93bl9lbnVtMi5wYi5oICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJlc2VydmVfdW5rbm93bl9lbnVtLnBiLmNjICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJlc2VydmVfdW5rbm93bl9lbnVtLnBiLmggICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJvdG8zX2FyZW5hLnBiLmNjICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJvdG8zX2FyZW5hLnBiLmggICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfd2VsbF9rbm93bl90eXBlcy5wYi5jYyAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfd2VsbF9rbm93bl90eXBlcy5wYi5oICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90ZXN0ZGF0YS9hbnlzLnBiLmNjICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90ZXN0ZGF0YS9hbnlzLnBiLmggICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90ZXN0ZGF0YS9ib29rcy5wYi5jYyAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90ZXN0ZGF0YS9ib29rcy5wYi5oICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90ZXN0ZGF0YS9kZWZhdWx0X3ZhbHVlLnBiLmNjICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90ZXN0ZGF0YS9kZWZhdWx0X3ZhbHVlLnBiLmggICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90ZXN0ZGF0YS9kZWZhdWx0X3ZhbHVlX3Rlc3QucGIuY2MgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90ZXN0ZGF0YS9kZWZhdWx0X3ZhbHVlX3Rlc3QucGIuaCAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90ZXN0ZGF0YS9maWVsZF9tYXNrLnBiLmNjICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90ZXN0ZGF0YS9maWVsZF9tYXNrLnBiLmggICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90ZXN0ZGF0YS9tYXBzLnBiLmNjICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90ZXN0ZGF0YS9tYXBzLnBiLmggICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90ZXN0ZGF0YS9vbmVvZnMucGIuY2MgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90ZXN0ZGF0YS9vbmVvZnMucGIuaCAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90ZXN0ZGF0YS9zdHJ1Y3QucGIuY2MgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90ZXN0ZGF0YS9zdHJ1Y3QucGIuaCAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90ZXN0ZGF0YS90aW1lc3RhbXBfZHVyYXRpb24ucGIuY2MgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90ZXN0ZGF0YS90aW1lc3RhbXBfZHVyYXRpb24ucGIuaCAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9qc29uX2Zvcm1hdF9wcm90bzMucGIuY2MgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9qc29uX2Zvcm1hdF9wcm90bzMucGIuaCAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9tZXNzYWdlX2RpZmZlcmVuY2VyX3VuaXR0ZXN0LnBiLmNjICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9tZXNzYWdlX2RpZmZlcmVuY2VyX3VuaXR0ZXN0LnBiLmgKKworQlVJTFRfU09VUkNFUyA9ICQocHJvdG9jX291dHB1dHMpCisKK2lmIFVTRV9FWFRFUk5BTF9QUk9UT0MKKwordW5pdHRlc3RfcHJvdG9fbWlkZGxlbWFuOiAkKHByb3RvY19pbnB1dHMpCisJJChQUk9UT0MpIC1JJChzcmNkaXIpIC0tY3BwX291dD0uICReCisJdG91Y2ggdW5pdHRlc3RfcHJvdG9fbWlkZGxlbWFuCisKK2Vsc2UKKworIyBXZSBoYXZlIHRvIGNkIHRvICQoc3JjZGlyKSBiZWZvcmUgZXhlY3V0aW5nIHByb3RvYyBiZWNhdXNlICQocHJvdG9jX2lucHV0cykgaXMKKyMgcmVsYXRpdmUgdG8gc3JjZGlyLCB3aGljaCBtYXkgbm90IGJlIHRoZSBzYW1lIGFzIHRoZSBjdXJyZW50IGRpcmVjdG9yeSB3aGVuCisjIGJ1aWxkaW5nIG91dC1vZi10cmVlLgordW5pdHRlc3RfcHJvdG9fbWlkZGxlbWFuOiBwcm90b2MkKEVYRUVYVCkgJChwcm90b2NfaW5wdXRzKQorCW9sZHB3ZD1gcHdkYCAmJiAoIGNkICQoc3JjZGlyKSAmJiAkJG9sZHB3ZC9wcm90b2MkKEVYRUVYVCkgLUkuIC0tY3BwX291dD0kJG9sZHB3ZCAkKHByb3RvY19pbnB1dHMpICkKKwl0b3VjaCB1bml0dGVzdF9wcm90b19taWRkbGVtYW4KKworZW5kaWYKKworJChwcm90b2Nfb3V0cHV0cyk6IHVuaXR0ZXN0X3Byb3RvX21pZGRsZW1hbgorCitDT01NT05fVEVTVF9TT1VSQ0VTID0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9hcmVuYV90ZXN0X3V0aWwuY2MgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9hcmVuYV90ZXN0X3V0aWwuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9tYXBfdGVzdF91dGlsLmNjICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9tYXBfdGVzdF91dGlsLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9tYXBfdGVzdF91dGlsX2ltcGwuaCAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi90ZXN0X3V0aWwuY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi90ZXN0X3V0aWwuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2dvb2dsZXRlc3QuY2MgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2dvb2dsZXRlc3QuaCAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2ZpbGUuY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2ZpbGUuaAorCitjaGVja19QUk9HUkFNUyA9IHByb3RvYyBwcm90b2J1Zi10ZXN0IHByb3RvYnVmLWxhenktZGVzY3JpcHRvci10ZXN0IFwKKyAgICAgICAgICAgICAgICAgcHJvdG9idWYtbGl0ZS10ZXN0IHRlc3RfcGx1Z2luIHByb3RvYnVmLWxpdGUtYXJlbmEtdGVzdCBcCisgICAgICAgICAgICAgICAgICQoR1pDSEVDS1BST0dSQU1TKQorcHJvdG9idWZfdGVzdF9MREFERCA9ICQoUFRIUkVBRF9MSUJTKSBsaWJwcm90b2J1Zi5sYSBsaWJwcm90b2MubGEgXAorICAgICAgICAgICAgICAgICAgICAgIC4uL2dtb2NrL2d0ZXN0L2xpYi9saWJndGVzdC5sYSAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgIC4uL2dtb2NrL2xpYi9saWJnbW9jay5sYSAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgIC4uL2dtb2NrL2xpYi9saWJnbW9ja19tYWluLmxhCitwcm90b2J1Zl90ZXN0X0NQUEZMQUdTID0gLUkkKHNyY2RpcikvLi4vZ21vY2svZ3Rlc3QvaW5jbHVkZSBcCisgICAgICAgICAgICAgICAgICAgICAgICAgLUkkKHNyY2RpcikvLi4vZ21vY2svaW5jbHVkZQorIyBEaXNhYmxlIG9wdGltaXphdGlvbiBmb3IgdGVzdHMgdW5sZXNzIHRoZSB1c2VyIGV4cGxpY2l0bHkgYXNrZWQgZm9yIGl0LAorIyBzaW5jZSB0ZXN0X3V0aWwuY2MgdGFrZXMgZm9yZXZlciB0byBjb21waWxlIHdpdGggb3B0aW1pemF0aW9uICh3aXRoIEdDQykuCisjIFNlZSBjb25maWd1cmUuYWMgZm9yIG1vcmUgaW5mby4KK3Byb3RvYnVmX3Rlc3RfQ1hYRkxBR1MgPSAkKE5PX09QVF9DWFhGTEFHUykKK3Byb3RvYnVmX3Rlc3RfU09VUkNFUyA9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2J5dGVzdHJlYW1fdW5pdHRlc3QuY2MgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbl91bml0dGVzdC5jYyAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2ludDEyOF91bml0dGVzdC5jYyAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL29uY2VfdW5pdHRlc3QuY2MgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0YXR1c29yX3Rlc3QuY2MgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0YXR1c190ZXN0LmNjICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cmluZ3BpZWNlX3VuaXR0ZXN0LmNjICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cmluZ3ByaW50Zl91bml0dGVzdC5jYyAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnVjdHVyYWxseV92YWxpZF91bml0dGVzdC5jYyAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWxfdW5pdHRlc3QuY2MgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3RlbXBsYXRlX3V0aWxfdW5pdHRlc3QuY2MgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3RpbWVfdGVzdC5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3R5cGVfdHJhaXRzX3VuaXR0ZXN0LmNjICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2FueV90ZXN0LmNjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2FyZW5hc3RyaW5nX3VuaXR0ZXN0LmNjICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2FyZW5hX3VuaXR0ZXN0LmNjICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3JfZGF0YWJhc2VfdW5pdHRlc3QuY2MgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3JfdW5pdHRlc3QuY2MgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2Ryb3BfdW5rbm93bl9maWVsZHNfdGVzdC5jYyAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2R5bmFtaWNfbWVzc2FnZV91bml0dGVzdC5jYyAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2V4dGVuc2lvbl9zZXRfdW5pdHRlc3QuY2MgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9tZXNzYWdlX3JlZmxlY3Rpb25fdW5pdHRlc3QuY2MgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL21hcF9maWVsZF90ZXN0LmNjICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL21hcF90ZXN0LmNjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL21lc3NhZ2VfdW5pdHRlc3QuY2MgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL25vX2ZpZWxkX3ByZXNlbmNlX3Rlc3QuY2MgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3ByZXNlcnZlX3Vua25vd25fZW51bV90ZXN0LmNjICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3Byb3RvM19hcmVuYV91bml0dGVzdC5jYyAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3JlZmxlY3Rpb25fb3BzX3VuaXR0ZXN0LmNjICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3JlcGVhdGVkX2ZpZWxkX3JlZmxlY3Rpb25fdW5pdHRlc3QuY2MgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3JlcGVhdGVkX2ZpZWxkX3VuaXR0ZXN0LmNjICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3RleHRfZm9ybWF0X3VuaXR0ZXN0LmNjICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3Vua25vd25fZmllbGRfc2V0X3VuaXR0ZXN0LmNjICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3dlbGxfa25vd25fdHlwZXNfdW5pdHRlc3QuY2MgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0X3VuaXR0ZXN0LmNjICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbV91bml0dGVzdC5jYyAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXJfdW5pdHRlc3QuY2MgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2lvL3Rva2VuaXplcl91bml0dGVzdC5jYyAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1fdW5pdHRlc3QuY2MgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvbW1hbmRfbGluZV9pbnRlcmZhY2VfdW5pdHRlc3QuY2MgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2ltcG9ydGVyX3VuaXR0ZXN0LmNjICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL21vY2tfY29kZV9nZW5lcmF0b3IuY2MgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL21vY2tfY29kZV9nZW5lcmF0b3IuaCAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BhcnNlcl91bml0dGVzdC5jYyAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfYm9vdHN0cmFwX3VuaXR0ZXN0LmNjICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfdW5pdHRlc3QuaCAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfdW5pdHRlc3QuY2MgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfcGx1Z2luX3VuaXR0ZXN0LmNjICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9tZXRhZGF0YV90ZXN0LmNjICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9wbHVnaW5fdW5pdHRlc3QuY2MgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9kb2NfY29tbWVudF91bml0dGVzdC5jYyAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19oZWxwZXJzX3VuaXR0ZXN0LmNjIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3B5dGhvbi9weXRob25fcGx1Z2luX3VuaXR0ZXN0LmNjICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3J1YnkvcnVieV9nZW5lcmF0b3JfdW5pdHRlc3QuY2MgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfZ2VuZXJhdG9yX3VuaXR0ZXN0LmNjIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3V0aWwvZmllbGRfY29tcGFyYXRvcl90ZXN0LmNjICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3V0aWwvZmllbGRfbWFza191dGlsX3Rlc3QuY2MgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvZGVmYXVsdF92YWx1ZV9vYmplY3R3cml0ZXJfdGVzdC5jYyBcCisgIGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL2pzb25fb2JqZWN0d3JpdGVyX3Rlc3QuY2MgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL2pzb25fc3RyZWFtX3BhcnNlcl90ZXN0LmNjICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3Byb3Rvc3RyZWFtX29iamVjdHNvdXJjZV90ZXN0LmNjIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvcHJvdG9zdHJlYW1fb2JqZWN0d3JpdGVyX3Rlc3QuY2MgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90eXBlX2luZm9fdGVzdF9oZWxwZXIuY2MgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9qc29uX3V0aWxfdGVzdC5jYyAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC9tZXNzYWdlX2RpZmZlcmVuY2VyX3VuaXR0ZXN0LmNjICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC90aW1lX3V0aWxfdGVzdC5jYyAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdXRpbC90eXBlX3Jlc29sdmVyX3V0aWxfdGVzdC5jYyAgICAgICAgICAgICAgXAorICAkKENPTU1PTl9URVNUX1NPVVJDRVMpCisKKworbm9kaXN0X3Byb3RvYnVmX3Rlc3RfU09VUkNFUyA9ICQocHJvdG9jX291dHB1dHMpCisKKyMgUnVuIGNwcF91bml0dGVzdCBhZ2FpbiB3aXRoIFBST1RPQlVGX1RFU1RfTk9fREVTQ1JJUFRPUlMgZGVmaW5lZC4KK3Byb3RvYnVmX2xhenlfZGVzY3JpcHRvcl90ZXN0X0xEQUREID0gJChQVEhSRUFEX0xJQlMpIGxpYnByb3RvYnVmLmxhIFwKKyAgICAgICAgICAgICAgICAgICAgICBsaWJwcm90b2MubGEgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAuLi9nbW9jay9ndGVzdC9saWIvbGliZ3Rlc3QubGEgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAuLi9nbW9jay9saWIvbGliZ21vY2subGEgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAuLi9nbW9jay9saWIvbGliZ21vY2tfbWFpbi5sYQorcHJvdG9idWZfbGF6eV9kZXNjcmlwdG9yX3Rlc3RfQ1BQRkxBR1MgPSAtSSQoc3JjZGlyKS8uLi9nbW9jay9pbmNsdWRlICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLUkkKHNyY2RpcikvLi4vZ21vY2svZ3Rlc3QvaW5jbHVkZSBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC1EUFJPVE9CVUZfVEVTVF9OT19ERVNDUklQVE9SUworcHJvdG9idWZfbGF6eV9kZXNjcmlwdG9yX3Rlc3RfQ1hYRkxBR1MgPSAkKE5PX09QVF9DWFhGTEFHUykKK3Byb3RvYnVmX2xhenlfZGVzY3JpcHRvcl90ZXN0X1NPVVJDRVMgPSAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfdW5pdHRlc3QuY2MgICAgICAgICAgICAgICAgIFwKKyAgJChDT01NT05fVEVTVF9TT1VSQ0VTKQorbm9kaXN0X3Byb3RvYnVmX2xhenlfZGVzY3JpcHRvcl90ZXN0X1NPVVJDRVMgPSAkKHByb3RvY19vdXRwdXRzKQorCitDT01NT05fTElURV9URVNUX1NPVVJDRVMgPSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2FyZW5hX3Rlc3RfdXRpbC5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvYXJlbmFfdGVzdF91dGlsLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9tYXBfbGl0ZV90ZXN0X3V0aWwuY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL21hcF9saXRlX3Rlc3RfdXRpbC5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvdGVzdF91dGlsX2xpdGUuY2MgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi90ZXN0X3V0aWxfbGl0ZS5oCisKKyMgQnVpbGQgbGl0ZV91bml0dGVzdCBzZXBhcmF0ZWx5LCBzaW5jZSBpdCBkb2Vzbid0IHVzZSBndGVzdC4gSXQgY2FuJ3QKKyMgZGVwZW5kIG9uIGd0ZXN0IGJlY2F1c2Ugb3VyIGludGVybmFsIHZlcnNpb24gb2YgZ3Rlc3QgZGVwZW5kIG9uIHByb3RvCisjIGZ1bGwgcnVudGltZSBhbmQgd2Ugd2FudCB0byBtYWtlIHN1cmUgdGhpcyB0ZXN0IGJ1aWxkcyB3aXRob3V0IGZ1bGwKKyMgcnVudGltZS4KK3Byb3RvYnVmX2xpdGVfdGVzdF9MREFERCA9ICQoUFRIUkVBRF9MSUJTKSBsaWJwcm90b2J1Zi1saXRlLmxhCitwcm90b2J1Zl9saXRlX3Rlc3RfQ1hYRkxBR1MgPSAkKE5PX09QVF9DWFhGTEFHUykKK3Byb3RvYnVmX2xpdGVfdGVzdF9TT1VSQ0VTID0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBnb29nbGUvcHJvdG9idWYvbGl0ZV91bml0dGVzdC5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICQoQ09NTU9OX0xJVEVfVEVTVF9TT1VSQ0VTKQorbm9kaXN0X3Byb3RvYnVmX2xpdGVfdGVzdF9TT1VSQ0VTID0gJChwcm90b2NfbGl0ZV9vdXRwdXRzKQorCisjIGxpdGVfYXJlbmFfdW5pdHRlc3QgZGVwZW5kcyBvbiBndGVzdCBiZWNhdXNlIHRlYm9yaW5nQCBmb3VuZCB0aGF0IHdpdGhvdXQKKyMgZ3Rlc3Qgd2hlbiBidWlsZGluZyB0aGUgdGVzdCBpbnRlcm5hbGx5IG91ciBtZW1vcnkgc2FuaXRpemVyIGRvZXNuJ3QgZGV0ZWN0CisjIG1lbW9yeSBsZWFrcyAoZG9uJ3Qga25vdyB3aHkpLgorcHJvdG9idWZfbGl0ZV9hcmVuYV90ZXN0X0xEQUREID0gJChQVEhSRUFEX0xJQlMpIGxpYnByb3RvYnVmLWxpdGUubGEgXAorICAgICAgICAgICAgICAgICAgICAgIC4uL2dtb2NrL2d0ZXN0L2xpYi9saWJndGVzdC5sYSAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgIC4uL2dtb2NrL2xpYi9saWJnbW9jay5sYSAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgIC4uL2dtb2NrL2xpYi9saWJnbW9ja19tYWluLmxhCitwcm90b2J1Zl9saXRlX2FyZW5hX3Rlc3RfQ1BQRkxBR1MgPSAtSSQoc3JjZGlyKS8uLi9nbW9jay9pbmNsdWRlICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC1JJChzcmNkaXIpLy4uL2dtb2NrL2d0ZXN0L2luY2x1ZGUKK3Byb3RvYnVmX2xpdGVfYXJlbmFfdGVzdF9DWFhGTEFHUyA9ICQoTk9fT1BUX0NYWEZMQUdTKQorcHJvdG9idWZfbGl0ZV9hcmVuYV90ZXN0X1NPVVJDRVMgPSAgICAgICBcCisgIGdvb2dsZS9wcm90b2J1Zi9saXRlX2FyZW5hX3VuaXR0ZXN0LmNjIFwKKyAgJChDT01NT05fTElURV9URVNUX1NPVVJDRVMpCitub2Rpc3RfcHJvdG9idWZfbGl0ZV9hcmVuYV90ZXN0X1NPVVJDRVMgPSAkKHByb3RvY19saXRlX291dHB1dHMpCisKKyMgVGVzdCBwbHVnaW4gYmluYXJ5LgordGVzdF9wbHVnaW5fTERBREQgPSAkKFBUSFJFQURfTElCUykgbGlicHJvdG9idWYubGEgbGlicHJvdG9jLmxhIFwKKyAgICAgICAgICAgICAgICAgICAgLi4vZ21vY2svZ3Rlc3QvbGliL2xpYmd0ZXN0LmxhCit0ZXN0X3BsdWdpbl9DUFBGTEFHUyA9IC1JJChzcmNkaXIpLy4uL2dtb2NrL2d0ZXN0L2luY2x1ZGUKK3Rlc3RfcGx1Z2luX1NPVVJDRVMgPSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL21vY2tfY29kZV9nZW5lcmF0b3IuY2MgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZmlsZS5jYyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZmlsZS5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3Rlc3RfcGx1Z2luLmNjCisKK2lmIEhBVkVfWkxJQgoremNnemlwX0xEQUREID0gJChQVEhSRUFEX0xJQlMpIGxpYnByb3RvYnVmLmxhCit6Y2d6aXBfU09VUkNFUyA9IGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL3pjZ3ppcC5jYworCit6Y2d1bnppcF9MREFERCA9ICQoUFRIUkVBRF9MSUJTKSBsaWJwcm90b2J1Zi5sYQoremNndW56aXBfU09VUkNFUyA9IGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL3pjZ3VuemlwLmNjCitlbmRpZgorCitURVNUUyA9IHByb3RvYnVmLXRlc3QgcHJvdG9idWYtbGF6eS1kZXNjcmlwdG9yLXRlc3QgcHJvdG9idWYtbGl0ZS10ZXN0IFwKKyAgICAgICAgZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3ppcF9vdXRwdXRfdW5pdHRlc3Quc2ggJChHWlRFU1RTKSAgICAgXAorICAgICAgICBwcm90b2J1Zi1saXRlLWFyZW5hLXRlc3QKZGlmZiAtLWdpdCBhL3NyYy9SRUFETUUubWQgYi9zcmMvUkVBRE1FLm1kCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRlMzEyYzAKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvUkVBRE1FLm1kCkBAIC0wLDAgKzEsMjA5IEBACitQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitbIVtCdWlsZCBTdGF0dXNdKGh0dHBzOi8vdHJhdmlzLWNpLm9yZy9nb29nbGUvcHJvdG9idWYuc3ZnP2JyYW5jaD1tYXN0ZXIpXShodHRwczovL3RyYXZpcy1jaS5vcmcvZ29vZ2xlL3Byb3RvYnVmKSBbIVtCdWlsZCBzdGF0dXNdKGh0dHBzOi8vY2kuYXBwdmV5b3IuY29tL2FwaS9wcm9qZWN0cy9zdGF0dXMvNzNjdGVlNnVhNHcycnVpbj9zdmc9dHJ1ZSldKGh0dHBzOi8vY2kuYXBwdmV5b3IuY29tL3Byb2plY3QvcHJvdG9idWYvcHJvdG9idWYpCisKK0NvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuCisKK2h0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisKK0MrKyBJbnN0YWxsYXRpb24gLSBVbml4CistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitUbyBidWlsZCBwcm90b2J1ZiBmcm9tIHNvdXJjZSwgdGhlIGZvbGxvd2luZyB0b29scyBhcmUgbmVlZGVkOgorCisgICogYXV0b2NvbmYKKyAgKiBhdXRvbWFrZQorICAqIGxpYnRvb2wKKyAgKiBjdXJsICh1c2VkIHRvIGRvd25sb2FkIGdtb2NrKQorCitPbiBVYnVudHUsIHlvdSBjYW4gaW5zdGFsbCB0aGVtIHdpdGg6CisKKyAgJCBzdWRvIGFwdC1nZXQgaW5zdGFsbCBhdXRvY29uZiBhdXRvbWFrZSBsaWJ0b29sIGN1cmwKKworT24gb3RoZXIgcGxhdGZvcm1zLCBwbGVhc2UgdXNlIHRoZSBjb3JyZXNwb25kaW5nIHBhY2thZ2UgbWFuYWdpbmcgdG9vbCB0bworaW5zdGFsbCB0aGVtIGJlZm9yZSBwcm9jZWVkaW5nLgorCitJZiB5b3UgZ2V0IHRoZSBzb3VyY2UgZnJvbSBnaXRodWIsIHlvdSBuZWVkIHRvIGdlbmVyYXRlIHRoZSBjb25maWd1cmUgc2NyaXB0CitmaXJzdDoKKworICAgICQgLi9hdXRvZ2VuLnNoCisKK1RoaXMgd2lsbCBkb3dubG9hZCBnbW9jayBzb3VyY2UgKHdoaWNoIGlzIHVzZWQgZm9yIEMrKyBQcm90b2NvbCBCdWZmZXIKK3VuaXQtdGVzdHMpIHRvIHRoZSBjdXJyZW50IGRpcmVjdG9yeSBhbmQgcnVuIGF1dG9tYWtlLCBhdXRvY29uZiwgZXRjLgordG8gZ2VuZXJhdGUgdGhlIGNvbmZpZ3VyZSBzY3JpcHQgYW5kIHZhcmlvdXMgdGVtcGxhdGUgbWFrZWZpbGVzLgorCitZb3UgY2FuIHNraXAgdGhpcyBzdGVwIGlmIHlvdSBhcmUgdXNpbmcgYSByZWxlYXNlIHBhY2thZ2UgKHdoaWNoIGFscmVhZHkKK2NvbnRhaW5zIGdtb2NrIGFuZCB0aGUgY29uZmlndXJlIHNjcmlwdCkuCisKK1RvIGJ1aWxkIGFuZCBpbnN0YWxsIHRoZSBDKysgUHJvdG9jb2wgQnVmZmVyIHJ1bnRpbWUgYW5kIHRoZSBQcm90b2NvbAorQnVmZmVyIGNvbXBpbGVyIChwcm90b2MpIGV4ZWN1dGUgdGhlIGZvbGxvd2luZzoKKworICAgICQgLi9jb25maWd1cmUKKyAgICAkIG1ha2UKKyAgICAkIG1ha2UgY2hlY2sKKyAgICAkIHN1ZG8gbWFrZSBpbnN0YWxsCisgICAgJCBzdWRvIGxkY29uZmlnICMgcmVmcmVzaCBzaGFyZWQgbGlicmFyeSBjYWNoZS4KKworSWYgIm1ha2UgY2hlY2siIGZhaWxzLCB5b3UgY2FuIHN0aWxsIGluc3RhbGwsIGJ1dCBpdCBpcyBsaWtlbHkgdGhhdAorc29tZSBmZWF0dXJlcyBvZiB0aGlzIGxpYnJhcnkgd2lsbCBub3Qgd29yayBjb3JyZWN0bHkgb24geW91ciBzeXN0ZW0uCitQcm9jZWVkIGF0IHlvdXIgb3duIHJpc2suCisKK0ZvciBhZHZhbmNlZCB1c2FnZSBpbmZvcm1hdGlvbiBvbiBjb25maWd1cmUgYW5kIG1ha2UsIHBsZWFzZSByZWZlciB0byB0aGUKK2F1dG9jb25mIGRvY3VtZW50YXRpb246CisKKyAgaHR0cDovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2F1dG9jb25mL21hbnVhbC9hdXRvY29uZi5odG1sI1J1bm5pbmctY29uZmlndXJlLVNjcmlwdHMKKworKipIaW50IG9uIGluc3RhbGwgbG9jYXRpb24qKgorCisgIEJ5IGRlZmF1bHQsIHRoZSBwYWNrYWdlIHdpbGwgYmUgaW5zdGFsbGVkIHRvIC91c3IvbG9jYWwuICBIb3dldmVyLAorICBvbiBtYW55IHBsYXRmb3JtcywgL3Vzci9sb2NhbC9saWIgaXMgbm90IHBhcnQgb2YgTERfTElCUkFSWV9QQVRILgorICBZb3UgY2FuIGFkZCBpdCwgYnV0IGl0IG1heSBiZSBlYXNpZXIgdG8ganVzdCBpbnN0YWxsIHRvIC91c3IKKyAgaW5zdGVhZC4gIFRvIGRvIHRoaXMsIGludm9rZSBjb25maWd1cmUgYXMgZm9sbG93czoKKworICAgIC4vY29uZmlndXJlIC0tcHJlZml4PS91c3IKKworICBJZiB5b3UgYWxyZWFkeSBidWlsdCB0aGUgcGFja2FnZSB3aXRoIGEgZGlmZmVyZW50IHByZWZpeCwgbWFrZSBzdXJlCisgIHRvIHJ1biAibWFrZSBjbGVhbiIgYmVmb3JlIGJ1aWxkaW5nIGFnYWluLgorCisqKkNvbXBpbGluZyBkZXBlbmRlbnQgcGFja2FnZXMqKgorCisgIFRvIGNvbXBpbGUgYSBwYWNrYWdlIHRoYXQgdXNlcyBQcm90b2NvbCBCdWZmZXJzLCB5b3UgbmVlZCB0byBwYXNzCisgIHZhcmlvdXMgZmxhZ3MgdG8geW91ciBjb21waWxlciBhbmQgbGlua2VyLiAgQXMgb2YgdmVyc2lvbiAyLjIuMCwKKyAgUHJvdG9jb2wgQnVmZmVycyBpbnRlZ3JhdGVzIHdpdGggcGtnLWNvbmZpZyB0byBtYW5hZ2UgdGhpcy4gIElmIHlvdQorICBoYXZlIHBrZy1jb25maWcgaW5zdGFsbGVkLCB0aGVuIHlvdSBjYW4gaW52b2tlIGl0IHRvIGdldCBhIGxpc3Qgb2YKKyAgZmxhZ3MgbGlrZSBzbzoKKworICAgIHBrZy1jb25maWcgLS1jZmxhZ3MgcHJvdG9idWYgICAgICAgICAjIHByaW50IGNvbXBpbGVyIGZsYWdzCisgICAgcGtnLWNvbmZpZyAtLWxpYnMgcHJvdG9idWYgICAgICAgICAgICMgcHJpbnQgbGlua2VyIGZsYWdzCisgICAgcGtnLWNvbmZpZyAtLWNmbGFncyAtLWxpYnMgcHJvdG9idWYgICMgcHJpbnQgYm90aAorCisgIEZvciBleGFtcGxlOgorCisgICAgYysrIG15X3Byb2dyYW0uY2MgbXlfcHJvdG8ucGIuY2MgYHBrZy1jb25maWcgLS1jZmxhZ3MgLS1saWJzIHByb3RvYnVmYAorCisgIE5vdGUgdGhhdCBwYWNrYWdlcyB3cml0dGVuIHByaW9yIHRvIHRoZSAyLjIuMCByZWxlYXNlIG9mIFByb3RvY29sCisgIEJ1ZmZlcnMgbWF5IG5vdCB5ZXQgaW50ZWdyYXRlIHdpdGggcGtnLWNvbmZpZyB0byBnZXQgZmxhZ3MsIGFuZCBtYXkKKyAgbm90IHBhc3MgdGhlIGNvcnJlY3Qgc2V0IG9mIGZsYWdzIHRvIGNvcnJlY3RseSBsaW5rIGFnYWluc3QKKyAgbGlicHJvdG9idWYuICBJZiB0aGUgcGFja2FnZSBpbiBxdWVzdGlvbiB1c2VzIGF1dG9jb25mLCB5b3UgY2FuCisgIG9mdGVuIGZpeCB0aGUgcHJvYmxlbSBieSBpbnZva2luZyBpdHMgY29uZmlndXJlIHNjcmlwdCBsaWtlOgorCisgICAgY29uZmlndXJlIENYWEZMQUdTPSIkKHBrZy1jb25maWcgLS1jZmxhZ3MgcHJvdG9idWYpIiBcCisgICAgICAgICAgICAgIExJQlM9IiQocGtnLWNvbmZpZyAtLWxpYnMgcHJvdG9idWYpIgorCisgIFRoaXMgd2lsbCBmb3JjZSBpdCB0byB1c2UgdGhlIGNvcnJlY3QgZmxhZ3MuCisKKyAgSWYgeW91IGFyZSB3cml0aW5nIGFuIGF1dG9jb25mLWJhc2VkIHBhY2thZ2UgdGhhdCB1c2VzIFByb3RvY29sCisgIEJ1ZmZlcnMsIHlvdSBzaG91bGQgcHJvYmFibHkgdXNlIHRoZSBQS0dfQ0hFQ0tfTU9EVUxFUyBtYWNybyBpbiB5b3VyCisgIGNvbmZpZ3VyZSBzY3JpcHQgbGlrZToKKworICAgIFBLR19DSEVDS19NT0RVTEVTKFtwcm90b2J1Zl0sIFtwcm90b2J1Zl0pCisKKyAgU2VlIHRoZSBwa2ctY29uZmlnIG1hbiBwYWdlIGZvciBtb3JlIGluZm8uCisKKyAgSWYgeW91IG9ubHkgd2FudCBwcm90b2J1Zi1saXRlLCBzdWJzdGl0dXRlICJwcm90b2J1Zi1saXRlIiBpbiBwbGFjZQorICBvZiAicHJvdG9idWYiIGluIHRoZXNlIGV4YW1wbGVzLgorCisqKk5vdGUgZm9yIE1hYyB1c2VycyoqCisKKyAgRm9yIGEgTWFjIHN5c3RlbSwgVW5peCB0b29scyBhcmUgbm90IGF2YWlsYWJsZSBieSBkZWZhdWx0LiBZb3Ugd2lsbCBmaXJzdCBuZWVkCisgIHRvIGluc3RhbGwgWGNvZGUgZnJvbSB0aGUgTWFjIEFwcFN0b3JlIGFuZCB0aGVuIHJ1biB0aGUgZm9sbG93aW5nIGNvbW1hbmQgZnJvbQorICBhIHRlcm1pbmFsOgorCisgICAgJCBzdWRvIHhjb2RlLXNlbGVjdCAtLWluc3RhbGwKKworICBUbyBpbnN0YWxsIFVuaXggdG9vbHMsIHlvdSBjYW4gaW5zdGFsbCAicG9ydCIgZm9sbG93aW5nIHRoZSBpbnN0cnVjdGlvbnMgYXQKKyAgaHR0cHM6Ly93d3cubWFjcG9ydHMub3JnIC4gVGhpcyB3aWxsIHJlc2lkZSBpbiAvb3B0L2xvY2FsL2Jpbi9wb3J0IGZvciBtb3N0CisgIE1hYyBpbnN0YWxsYXRpb25zLgorCisgICAgJCBzdWRvIC9vcHQvbG9jYWwvYmluL3BvcnQgaW5zdGFsbCBhdXRvY29uZiBhdXRvbWFrZSBsaWJ0b29sCisKKyAgVGhlbiBmb2xsb3cgdGhlIFVuaXggaW5zdHJ1Y3Rpb25zIGFib3ZlLgorCisqKk5vdGUgZm9yIGNyb3NzLWNvbXBpbGluZyoqCisKKyAgVGhlIG1ha2VmaWxlcyBub3JtYWxseSBpbnZva2UgdGhlIHByb3RvYyBleGVjdXRhYmxlIHRoYXQgdGhleSBqdXN0CisgIGJ1aWx0IGluIG9yZGVyIHRvIGJ1aWxkIHRlc3RzLiAgV2hlbiBjcm9zcy1jb21waWxpbmcsIHRoZSBwcm90b2MKKyAgZXhlY3V0YWJsZSBtYXkgbm90IGJlIGV4ZWN1dGFibGUgb24gdGhlIGhvc3QgbWFjaGluZS4gIEluIHRoaXMgY2FzZSwKKyAgeW91IG11c3QgYnVpbGQgYSBjb3B5IG9mIHByb3RvYyBmb3IgdGhlIGhvc3QgbWFjaGluZSBmaXJzdCwgdGhlbiB1c2UKKyAgdGhlIC0td2l0aC1wcm90b2Mgb3B0aW9uIHRvIHRlbGwgY29uZmlndXJlIHRvIHVzZSBpdCBpbnN0ZWFkLiAgRm9yCisgIGV4YW1wbGU6CisKKyAgICAuL2NvbmZpZ3VyZSAtLXdpdGgtcHJvdG9jPXByb3RvYworCisgIFRoaXMgd2lsbCB1c2UgdGhlIGluc3RhbGxlZCBwcm90b2MgKGZvdW5kIGluIHlvdXIgJFBBVEgpIGluc3RlYWQgb2YKKyAgdHJ5aW5nIHRvIGV4ZWN1dGUgdGhlIG9uZSBidWlsdCBkdXJpbmcgdGhlIGJ1aWxkIHByb2Nlc3MuICBZb3UgY2FuCisgIGFsc28gdXNlIGFuIGV4ZWN1dGFibGUgdGhhdCBoYXNuJ3QgYmVlbiBpbnN0YWxsZWQuICBGb3IgZXhhbXBsZSwgaWYKKyAgeW91IGJ1aWx0IHRoZSBwcm90b2J1ZiBwYWNrYWdlIGZvciB5b3VyIGhvc3QgbWFjaGluZSBpbiAuLi9ob3N0LAorICB5b3UgbWlnaHQgZG86CisKKyAgICAuL2NvbmZpZ3VyZSAtLXdpdGgtcHJvdG9jPS4uL2hvc3Qvc3JjL3Byb3RvYworCisgIEVpdGhlciB3YXksIHlvdSBtdXN0IG1ha2Ugc3VyZSB0aGF0IHRoZSBwcm90b2MgZXhlY3V0YWJsZSB5b3UgdXNlCisgIGhhcyB0aGUgc2FtZSB2ZXJzaW9uIGFzIHRoZSBwcm90b2J1ZiBzb3VyY2UgY29kZSB5b3UgYXJlIHRyeWluZyB0bworICB1c2UgaXQgd2l0aC4KKworKipOb3RlIGZvciBTb2xhcmlzIHVzZXJzKioKKworICBTb2xhcmlzIDEwIHg4NiBoYXMgYSBidWcgdGhhdCB3aWxsIG1ha2UgbGlua2luZyBmYWlsLCBjb21wbGFpbmluZworICBhYm91dCBsaWJzdGRjKysubGEgYmVpbmcgaW52YWxpZC4gIFdlIGhhdmUgaW5jbHVkZWQgYSB3b3JrLWFyb3VuZAorICBpbiB0aGlzIHBhY2thZ2UuICBUbyB1c2UgdGhlIHdvcmstYXJvdW5kLCBydW4gY29uZmlndXJlIGFzIGZvbGxvd3M6CisKKyAgICAuL2NvbmZpZ3VyZSBMREZMQUdTPS1MJFBXRC9zcmMvc29sYXJpcworCisgIFNlZSBzcmMvc29sYXJpcy9saWJzdGRjKysubGEgZm9yIG1vcmUgaW5mbyBvbiB0aGlzIGJ1Zy4KKworKipOb3RlIGZvciBIUCBDKysgVHJ1NjQgdXNlcnMqKgorCisgIFRvIGNvbXBpbGUgaW52b2tlIGNvbmZpZ3VyZSBhcyBmb2xsb3dzOgorCisgICAgLi9jb25maWd1cmUgQ1hYRkxBR1M9Ii1PIC1zdGQgYW5zaSAtaWVlZSAtRF9fVVNFX1NURF9JT1NUUkVBTSIKKworICBBbHNvLCB5b3Ugd2lsbCBuZWVkIHRvIHVzZSBnbWFrZSBpbnN0ZWFkIG9mIG1ha2UuCisKKyoqTm90ZSBmb3IgQUlYIHVzZXJzKioKKworICBDb21waWxlIHVzaW5nIHRoZSBJQk0geGxDIEMrKyBjb21waWxlciBhcyBmb2xsb3dzOgorCisgICAgLi9jb25maWd1cmUgQ1hYPXhsQworCisgIEFsc28sIHlvdSB3aWxsIG5lZWQgdG8gdXNlIEdOVSBgbWFrZWAgKGBnbWFrZWApIGluc3RlYWQgb2YgQUlYIGBtYWtlYC4KKworQysrIEluc3RhbGxhdGlvbiAtIFdpbmRvd3MKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0lmIHlvdSBvbmx5IG5lZWQgdGhlIHByb3RvYyBiaW5hcnksIHlvdSBjYW4gZG93bmxvYWQgaXQgZnJvbSB0aGUgcmVsZWFzZQorcGFnZToKKworICBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL3Byb3RvYnVmL3JlbGVhc2VzCisKK0luIHRoZSBkb3dubG9hZHMgc2VjdGlvbiwgZG93bmxvYWQgdGhlIHppcCBmaWxlIHByb3RvYy0kVkVSU0lPTi13aW4zMi56aXAuCitJdCBjb250YWlucyB0aGUgcHJvdG9jIGJpbmFyeSBhcyB3ZWxsIGFzIHB1YmxpYyBwcm90byBmaWxlcyBvZiBwcm90b2J1ZgorbGlicmFyeS4KKworVG8gYnVpbGQgZnJvbSBzb3VyY2UgdXNpbmcgTWljcm9zb2Z0IFZpc3VhbCBDKyssIHNlZSBjbWFrZS9SRUFETUUubWQuCisKK1RvIGJ1aWxkIGZyb20gc291cmNlIHVzaW5nIEN5Z3dpbiBvciBNaW5HVywgZm9sbG93IHRoZSBVbml4IGluc3RhbGxhdGlvbgoraW5zdHJ1Y3Rpb25zLCBhYm92ZS4KKworQmluYXJ5IENvbXBhdGliaWxpdHkgV2FybmluZworLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitEdWUgdG8gdGhlIG5hdHVyZSBvZiBDKyssIGl0IGlzIHVubGlrZWx5IHRoYXQgYW55IHR3byB2ZXJzaW9ucyBvZiB0aGUKK1Byb3RvY29sIEJ1ZmZlcnMgQysrIHJ1bnRpbWUgbGlicmFyaWVzIHdpbGwgaGF2ZSBjb21wYXRpYmxlIEFCSXMuCitUaGF0IGlzLCBpZiB5b3UgbGlua2VkIGFuIGV4ZWN1dGFibGUgYWdhaW5zdCBhbiBvbGRlciB2ZXJzaW9uIG9mCitsaWJwcm90b2J1ZiwgaXQgaXMgdW5saWtlbHkgdG8gd29yayB3aXRoIGEgbmV3ZXIgdmVyc2lvbiB3aXRob3V0CityZS1jb21waWxpbmcuICBUaGlzIHByb2JsZW0sIHdoZW4gaXQgb2NjdXJzLCB3aWxsIG5vcm1hbGx5IGJlIGRldGVjdGVkCitpbW1lZGlhdGVseSBvbiBzdGFydHVwIG9mIHlvdXIgYXBwLiAgU3RpbGwsIHlvdSBtYXkgd2FudCB0byBjb25zaWRlcgordXNpbmcgc3RhdGljIGxpbmthZ2UuICBZb3UgY2FuIGNvbmZpZ3VyZSB0aGlzIHBhY2thZ2UgdG8gaW5zdGFsbAorc3RhdGljIGxpYnJhcmllcyBvbmx5IHVzaW5nOgorCisgICAgLi9jb25maWd1cmUgLS1kaXNhYmxlLXNoYXJlZAorCitVc2FnZQorLS0tLS0KKworVGhlIGNvbXBsZXRlIGRvY3VtZW50YXRpb24gZm9yIFByb3RvY29sIEJ1ZmZlcnMgaXMgYXZhaWxhYmxlIHZpYSB0aGUKK3dlYiBhdDoKKworICAgIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2FueS5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvYW55LmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYzY2EwNmIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2FueS5jYwpAQCAtMCwwICsxLDExNCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvYW55Lmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKK25hbWVzcGFjZSB7CitzdHJpbmcgR2V0VHlwZVVybChjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlKSB7CisgIHJldHVybiBzdHJpbmcoa1R5cGVHb29nbGVBcGlzQ29tUHJlZml4KSArIG1lc3NhZ2UtPmZ1bGxfbmFtZSgpOworfQorCit9ICAvLyBuYW1lc3BhY2UKKworY29uc3QgY2hhciBrQW55RnVsbFR5cGVOYW1lW10gPSAiZ29vZ2xlLnByb3RvYnVmLkFueSI7Citjb25zdCBjaGFyIGtUeXBlR29vZ2xlQXBpc0NvbVByZWZpeFtdID0gInR5cGUuZ29vZ2xlYXBpcy5jb20vIjsKK2NvbnN0IGNoYXIga1R5cGVHb29nbGVQcm9kQ29tUHJlZml4W10gPSAidHlwZS5nb29nbGVwcm9kLmNvbS8iOworCitBbnlNZXRhZGF0YTo6QW55TWV0YWRhdGEoVXJsVHlwZSogdHlwZV91cmwsIFZhbHVlVHlwZSogdmFsdWUpCisgICAgOiB0eXBlX3VybF8odHlwZV91cmwpLCB2YWx1ZV8odmFsdWUpIHsKK30KKwordm9pZCBBbnlNZXRhZGF0YTo6UGFja0Zyb20oY29uc3QgTWVzc2FnZSYgbWVzc2FnZSkgeworICB0eXBlX3VybF8tPlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nKCksCisgICAgICAgICAgICAgICAgICAgICAgICBHZXRUeXBlVXJsKG1lc3NhZ2UuR2V0RGVzY3JpcHRvcigpKSk7CisgIG1lc3NhZ2UuU2VyaWFsaXplVG9TdHJpbmcodmFsdWVfLT5NdXRhYmxlTm9BcmVuYSgKKyAgICAgICY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSkpOworfQorCitib29sIEFueU1ldGFkYXRhOjpVbnBhY2tUbyhNZXNzYWdlKiBtZXNzYWdlKSBjb25zdCB7CisgIGlmICghSW50ZXJuYWxJcyhtZXNzYWdlLT5HZXREZXNjcmlwdG9yKCkpKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIHJldHVybiBtZXNzYWdlLT5QYXJzZUZyb21TdHJpbmcoCisgICAgICB2YWx1ZV8tPkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nKCkpKTsKK30KKworYm9vbCBBbnlNZXRhZGF0YTo6SW50ZXJuYWxJcyhjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSBjb25zdCB7CisgIGNvbnN0IHN0cmluZyB0eXBlX3VybCA9IHR5cGVfdXJsXy0+R2V0Tm9BcmVuYSgKKyAgICAgICAgICAgICAmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmcoKSk7CisgIGNvbnN0IHN0cmluZyBmdWxsX25hbWUgPSBkZXNjcmlwdG9yLT5mdWxsX25hbWUoKTsKKyAgaWYgKHR5cGVfdXJsLmxlbmd0aCgpIDwgZnVsbF9uYW1lLmxlbmd0aCgpKSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgcmV0dXJuICgwID09IHR5cGVfdXJsLmNvbXBhcmUoCisgICAgdHlwZV91cmwubGVuZ3RoKCkgLSBmdWxsX25hbWUubGVuZ3RoKCksCisgICAgZnVsbF9uYW1lLmxlbmd0aCgpLAorICAgIGZ1bGxfbmFtZSkpOworfQorCitib29sIFBhcnNlQW55VHlwZVVybChjb25zdCBzdHJpbmcmIHR5cGVfdXJsLCBzdHJpbmcqIGZ1bGxfdHlwZV9uYW1lKSB7CisgIHN0YXRpYyBjb25zdCBjaGFyKiBwcmVmaXhbXSA9IHsKKyAgICBrVHlwZUdvb2dsZUFwaXNDb21QcmVmaXgsCisgICAga1R5cGVHb29nbGVQcm9kQ29tUHJlZml4CisgIH07CisgIGZvciAoaW50IGkgPSAwOyBpIDwgMjsgaSsrKSB7CisgICAgY29uc3QgaW50IHByZWZpeF9sZW4gPSBzdHJsZW4ocHJlZml4W2ldKTsKKyAgICBpZiAoc3RybmNtcCh0eXBlX3VybC5jX3N0cigpLCBwcmVmaXhbaV0sIHByZWZpeF9sZW4pID09IDApIHsKKyAgICAgIGZ1bGxfdHlwZV9uYW1lLT5hc3NpZ24odHlwZV91cmwuZGF0YSgpICsgcHJlZml4X2xlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZV91cmwuc2l6ZSgpIC0gcHJlZml4X2xlbik7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIGZhbHNlOworfQorCisKK2Jvb2wgR2V0QW55RmllbGREZXNjcmlwdG9ycyhjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvcioqIHR5cGVfdXJsX2ZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvcioqIHZhbHVlX2ZpZWxkKSB7CisgICAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciA9IG1lc3NhZ2UuR2V0RGVzY3JpcHRvcigpOworICAgIGlmIChkZXNjcmlwdG9yLT5mdWxsX25hbWUoKSAhPSBrQW55RnVsbFR5cGVOYW1lKSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgICp0eXBlX3VybF9maWVsZCA9IGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TnVtYmVyKDEpOworICAgICp2YWx1ZV9maWVsZCA9IGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TnVtYmVyKDIpOworICAgIHJldHVybiAoKnR5cGVfdXJsX2ZpZWxkICE9IE5VTEwgJiYKKyAgICAgICAgICAgICgqdHlwZV91cmxfZmllbGQpLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX1NUUklORyAmJgorICAgICAgICAgICAgKnZhbHVlX2ZpZWxkICE9IE5VTEwgJiYKKyAgICAgICAgICAgICgqdmFsdWVfZmllbGQpLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX0JZVEVTKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvYW55LmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2FueS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM4ZGJlZjEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2FueS5oCkBAIC0wLDAgKzEsOTEgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9BTllfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9BTllfSF9fCisKKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWVzc2FnZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9hcmVuYXN0cmluZy5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW50ZXJuYWwgeworCisvLyBIZWxwZXIgY2xhc3MgdXNlZCB0byBpbXBsZW1lbnQgZ29vZ2xlOjpwcm90b2J1Zjo6QW55LgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEFueU1ldGFkYXRhIHsKKyAgdHlwZWRlZiBBcmVuYVN0cmluZ1B0ciBVcmxUeXBlOworICB0eXBlZGVmIEFyZW5hU3RyaW5nUHRyIFZhbHVlVHlwZTsKKyBwdWJsaWM6CisgIC8vIEFueU1ldGFkYXRhIGRvZXMgbm90IHRha2Ugb3duZXJzaGlwIG9mICJ0eXBlX3VybCIgYW5kICJ2YWx1ZSIuCisgIEFueU1ldGFkYXRhKFVybFR5cGUqIHR5cGVfdXJsLCBWYWx1ZVR5cGUqIHZhbHVlKTsKKworICB2b2lkIFBhY2tGcm9tKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UpOworCisgIGJvb2wgVW5wYWNrVG8oTWVzc2FnZSogbWVzc2FnZSkgY29uc3Q7CisKKyAgdGVtcGxhdGU8dHlwZW5hbWUgVD4KKyAgYm9vbCBJcygpIGNvbnN0IHsKKyAgICByZXR1cm4gSW50ZXJuYWxJcyhUOjpkZWZhdWx0X2luc3RhbmNlKCkuR2V0RGVzY3JpcHRvcigpKTsKKyAgfQorCisgcHJpdmF0ZToKKyAgYm9vbCBJbnRlcm5hbElzKGNvbnN0IERlc2NyaXB0b3IqIG1lc3NhZ2UpIGNvbnN0OworCisgIFVybFR5cGUqIHR5cGVfdXJsXzsKKyAgVmFsdWVUeXBlKiB2YWx1ZV87CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEFueU1ldGFkYXRhKTsKK307CisKK2V4dGVybiBjb25zdCBjaGFyIGtBbnlGdWxsVHlwZU5hbWVbXTsgICAgICAgICAgLy8gImdvb2dsZS5wcm90b2J1Zi5BbnkiLgorZXh0ZXJuIGNvbnN0IGNoYXIga1R5cGVHb29nbGVBcGlzQ29tUHJlZml4W107ICAvLyAidHlwZS5nb29nbGVhcGlzLmNvbS8iLgorZXh0ZXJuIGNvbnN0IGNoYXIga1R5cGVHb29nbGVQcm9kQ29tUHJlZml4W107ICAvLyAidHlwZS5nb29nbGVwcm9kLmNvbS8iLgorCisvLyBHZXQgdGhlIHByb3RvIHR5cGUgbmFtZSBmcm9tIEFueTo6dHlwZV91cmwgdmFsdWUuIEZvciBleGFtcGxlLCBwYXNzaW5nCisvLyAidHlwZS5nb29nbGVhcGlzLmNvbS9ycGMuUXVlcnlPcmlnaW4iIHdpbGwgcmV0dXJuICJycGMuUXVlcnlPcmlnaW4iIGluCisvLyAqZnVsbF90eXBlX25hbWUuIFJldHVybnMgZmFsc2UgaWYgdHlwZV91cmwgZG9lcyBub3Qgc3RhcnQgd2l0aAorLy8gInR5cGUuZ29vZ2xlYXBpcy5jb20iIG9yICJ0eXBlLmdvb2dsZXByb2QuY29tIi4KK2Jvb2wgUGFyc2VBbnlUeXBlVXJsKGNvbnN0IHN0cmluZyYgdHlwZV91cmwsIHN0cmluZyogZnVsbF90eXBlX25hbWUpOworCisvLyBTZWUgaWYgbWVzc2FnZSBpcyBvZiB0eXBlIGdvb2dsZS5wcm90b2J1Zi5BbnksIGlmIHNvLCByZXR1cm4gdGhlIGRlc2NyaXB0b3JzCisvLyBmb3IgInR5cGVfdXJsIiBhbmQgInZhbHVlIiBmaWVsZHMuCitib29sIEdldEFueUZpZWxkRGVzY3JpcHRvcnMoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqKiB0eXBlX3VybF9maWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqKiB2YWx1ZV9maWVsZCk7CisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0FOWV9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvYW55LnBiLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9hbnkucGIuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGJmNTIzYgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvYW55LnBiLmNjCkBAIC0wLDAgKzEsNDgzIEBACisvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQorLy8gc291cmNlOiBnb29nbGUvcHJvdG9idWYvYW55LnByb3RvCisKKyNkZWZpbmUgSU5URVJOQUxfU1VQUFJFU1NfUFJPVE9CVUZfRklFTERfREVQUkVDQVRJT04KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvYW55LnBiLmg+CisKKyNpbmNsdWRlIDxhbGdvcml0aG0+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3BvcnQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvb25jZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZV9pbmwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfbWVzc2FnZV9yZWZsZWN0aW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3JlZmxlY3Rpb25fb3BzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0Lmg+CisvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW5jbHVkZXMpCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworbmFtZXNwYWNlIHsKKworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBBbnlfZGVzY3JpcHRvcl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24qCisgIEFueV9yZWZsZWN0aW9uXyA9IE5VTEw7CisKK30gIC8vIG5hbWVzcGFjZQorCisKK3ZvaWQgcHJvdG9idWZfQXNzaWduRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmFueV8yZXByb3RvKCkgeworICBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmYW55XzJlcHJvdG8oKTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlRGVzY3JpcHRvciogZmlsZSA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUG9vbDo6Z2VuZXJhdGVkX3Bvb2woKS0+RmluZEZpbGVCeU5hbWUoCisgICAgICAiZ29vZ2xlL3Byb3RvYnVmL2FueS5wcm90byIpOworICBHT09HTEVfQ0hFQ0soZmlsZSAhPSBOVUxMKTsKKyAgQW55X2Rlc2NyaXB0b3JfID0gZmlsZS0+bWVzc2FnZV90eXBlKDApOworICBzdGF0aWMgY29uc3QgaW50IEFueV9vZmZzZXRzX1syXSA9IHsKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEFueSwgdHlwZV91cmxfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEFueSwgdmFsdWVfKSwKKyAgfTsKKyAgQW55X3JlZmxlY3Rpb25fID0KKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6TmV3R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24oCisgICAgICBBbnlfZGVzY3JpcHRvcl8sCisgICAgICBBbnk6OmRlZmF1bHRfaW5zdGFuY2VfLAorICAgICAgQW55X29mZnNldHNfLAorICAgICAgLTEsCisgICAgICAtMSwKKyAgICAgIC0xLAorICAgICAgc2l6ZW9mKEFueSksCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEFueSwgX2ludGVybmFsX21ldGFkYXRhXyksCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEFueSwgX2lzX2RlZmF1bHRfaW5zdGFuY2VfKSk7Cit9CisKK25hbWVzcGFjZSB7CisKK0dPT0dMRV9QUk9UT0JVRl9ERUNMQVJFX09OQ0UocHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNfb25jZV8pOworaW5saW5lIHZvaWQgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCkgeworICA6Omdvb2dsZTo6cHJvdG9idWY6Okdvb2dsZU9uY2VJbml0KCZwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc19vbmNlXywKKyAgICAgICAgICAgICAgICAgJnByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZhbnlfMmVwcm90byk7Cit9CisKK3ZvaWQgcHJvdG9idWZfUmVnaXN0ZXJUeXBlcyhjb25zdCA6OnN0ZDo6c3RyaW5nJikgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZE1lc3NhZ2UoCisgICAgICBBbnlfZGVzY3JpcHRvcl8sICZBbnk6OmRlZmF1bHRfaW5zdGFuY2UoKSk7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCit2b2lkIHByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZmFueV8yZXByb3RvKCkgeworICBkZWxldGUgQW55OjpkZWZhdWx0X2luc3RhbmNlXzsKKyAgZGVsZXRlIEFueV9yZWZsZWN0aW9uXzsKK30KKwordm9pZCBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmYW55XzJlcHJvdG8oKSB7CisgIHN0YXRpYyBib29sIGFscmVhZHlfaGVyZSA9IGZhbHNlOworICBpZiAoYWxyZWFkeV9oZXJlKSByZXR1cm47CisgIGFscmVhZHlfaGVyZSA9IHRydWU7CisgIEdPT0dMRV9QUk9UT0JVRl9WRVJJRllfVkVSU0lPTjsKKworICA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQb29sOjpJbnRlcm5hbEFkZEdlbmVyYXRlZEZpbGUoCisgICAgIlxuXDAzMWdvb2dsZS9wcm90b2J1Zi9hbnkucHJvdG9cMDIyXDAxN2dvb2dsZS5wcm90IgorICAgICJvYnVmXCImXG5cMDAzQW55XDAyMlwwMjBcblwwMTB0eXBlX3VybFwwMzBcMDAxIFwwMDEoXHRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIgorICAgICIgXDAwMShcMDE0QktcblwwMjNjb20uZ29vZ2xlLnByb3RvYnVmQlwwMTBBbnlQcm90b1BcMDAxXDI0MCIKKyAgICAiXDAwMVwwMDFcMjQyXDAwMlwwMDNHUEJcMjUyXDAwMlwwMzZHb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlwZSIKKyAgICAic2JcMDA2cHJvdG8zIiwgMTY5KTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZEZpbGUoCisgICAgImdvb2dsZS9wcm90b2J1Zi9hbnkucHJvdG8iLCAmcHJvdG9idWZfUmVnaXN0ZXJUeXBlcyk7CisgIEFueTo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBuZXcgQW55KCk7CisgIEFueTo6ZGVmYXVsdF9pbnN0YW5jZV8tPkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpPblNodXRkb3duKCZwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZhbnlfMmVwcm90byk7Cit9CisKKy8vIEZvcmNlIEFkZERlc2NyaXB0b3JzKCkgdG8gYmUgY2FsbGVkIGF0IHN0YXRpYyBpbml0aWFsaXphdGlvbiB0aW1lLgorc3RydWN0IFN0YXRpY0Rlc2NyaXB0b3JJbml0aWFsaXplcl9nb29nbGVfMmZwcm90b2J1Zl8yZmFueV8yZXByb3RvIHsKKyAgU3RhdGljRGVzY3JpcHRvckluaXRpYWxpemVyX2dvb2dsZV8yZnByb3RvYnVmXzJmYW55XzJlcHJvdG8oKSB7CisgICAgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmFueV8yZXByb3RvKCk7CisgIH0KK30gc3RhdGljX2Rlc2NyaXB0b3JfaW5pdGlhbGl6ZXJfZ29vZ2xlXzJmcHJvdG9idWZfMmZhbnlfMmVwcm90b187CisKK25hbWVzcGFjZSB7CisKK3N0YXRpYyB2b2lkIE1lcmdlRnJvbUZhaWwoaW50IGxpbmUpIEdPT0dMRV9BVFRSSUJVVEVfQ09MRDsKK3N0YXRpYyB2b2lkIE1lcmdlRnJvbUZhaWwoaW50IGxpbmUpIHsKKyAgR09PR0xFX0NIRUNLKGZhbHNlKSA8PCBfX0ZJTEVfXyA8PCAiOiIgPDwgbGluZTsKK30KKworfSAgLy8gbmFtZXNwYWNlCisKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCit2b2lkIEFueTo6UGFja0Zyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBtZXNzYWdlKSB7CisgIF9hbnlfbWV0YWRhdGFfLlBhY2tGcm9tKG1lc3NhZ2UpOworfQorCitib29sIEFueTo6VW5wYWNrVG8oOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKiBtZXNzYWdlKSBjb25zdCB7CisgIHJldHVybiBfYW55X21ldGFkYXRhXy5VbnBhY2tUbyhtZXNzYWdlKTsKK30KKworI2lmICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCitjb25zdCBpbnQgQW55OjprVHlwZVVybEZpZWxkTnVtYmVyOworY29uc3QgaW50IEFueTo6a1ZhbHVlRmllbGROdW1iZXI7CisjZW5kaWYgIC8vICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCisKK0FueTo6QW55KCkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSwgX2FueV9tZXRhZGF0YV8oJnR5cGVfdXJsXywgJnZhbHVlXykgeworICBTaGFyZWRDdG9yKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuQW55KQorfQorCit2b2lkIEFueTo6SW5pdEFzRGVmYXVsdEluc3RhbmNlKCkgeworICBfaXNfZGVmYXVsdF9pbnN0YW5jZV8gPSB0cnVlOworfQorCitBbnk6OkFueShjb25zdCBBbnkmIGZyb20pCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksCisgICAgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSwKKyAgICBfYW55X21ldGFkYXRhXygmdHlwZV91cmxfLCAmdmFsdWVfKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29weV9jb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuQW55KQorfQorCit2b2lkIEFueTo6U2hhcmVkQ3RvcigpIHsKKyAgICBfaXNfZGVmYXVsdF9pbnN0YW5jZV8gPSBmYWxzZTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmcoKTsKKyAgX2NhY2hlZF9zaXplXyA9IDA7CisgIHR5cGVfdXJsXy5VbnNhZmVTZXREZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIHZhbHVlXy5VbnNhZmVTZXREZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CisKK0FueTo6fkFueSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGRlc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLkFueSkKKyAgU2hhcmVkRHRvcigpOworfQorCit2b2lkIEFueTo6U2hhcmVkRHRvcigpIHsKKyAgdHlwZV91cmxfLkRlc3Ryb3lOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIHZhbHVlXy5EZXN0cm95Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBpZiAodGhpcyAhPSBkZWZhdWx0X2luc3RhbmNlXykgeworICB9Cit9CisKK3ZvaWQgQW55OjpTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdCB7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSBzaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogQW55OjpkZXNjcmlwdG9yKCkgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgcmV0dXJuIEFueV9kZXNjcmlwdG9yXzsKK30KKworY29uc3QgQW55JiBBbnk6OmRlZmF1bHRfaW5zdGFuY2UoKSB7CisgIGlmIChkZWZhdWx0X2luc3RhbmNlXyA9PSBOVUxMKSBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmYW55XzJlcHJvdG8oKTsKKyAgcmV0dXJuICpkZWZhdWx0X2luc3RhbmNlXzsKK30KKworQW55KiBBbnk6OmRlZmF1bHRfaW5zdGFuY2VfID0gTlVMTDsKKworQW55KiBBbnk6Ok5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3QgeworICBBbnkqIG4gPSBuZXcgQW55OworICBpZiAoYXJlbmEgIT0gTlVMTCkgeworICAgIGFyZW5hLT5Pd24obik7CisgIH0KKyAgcmV0dXJuIG47Cit9CisKK3ZvaWQgQW55OjpDbGVhcigpIHsKKyAgdHlwZV91cmxfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgdmFsdWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKworYm9vbCBBbnk6Ok1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCkgeworI2RlZmluZSBET18oRVhQUkVTU0lPTikgaWYgKCEoRVhQUkVTU0lPTikpIGdvdG8gZmFpbHVyZQorICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiB0YWc7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdGFydDpnb29nbGUucHJvdG9idWYuQW55KQorICBmb3IgKDs7KSB7CisgICAgOjpzdGQ6OnBhaXI8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyLCBib29sPiBwID0gaW5wdXQtPlJlYWRUYWdXaXRoQ3V0b2ZmKDEyNyk7CisgICAgdGFnID0gcC5maXJzdDsKKyAgICBpZiAoIXAuc2Vjb25kKSBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgIHN3aXRjaCAoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ0ZpZWxkTnVtYmVyKHRhZykpIHsKKyAgICAgIC8vIG9wdGlvbmFsIHN0cmluZyB0eXBlX3VybCA9IDE7CisgICAgICBjYXNlIDE6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAxMCkgeworICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFN0cmluZygKKyAgICAgICAgICAgICAgICBpbnB1dCwgdGhpcy0+bXV0YWJsZV90eXBlX3VybCgpKSk7CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpWZXJpZnlVdGY4U3RyaW5nKAorICAgICAgICAgICAgdGhpcy0+dHlwZV91cmwoKS5kYXRhKCksIHRoaXMtPnR5cGVfdXJsKCkubGVuZ3RoKCksCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UEFSU0UsCisgICAgICAgICAgICAiZ29vZ2xlLnByb3RvYnVmLkFueS50eXBlX3VybCIpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDE4KSkgZ290byBwYXJzZV92YWx1ZTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIGJ5dGVzIHZhbHVlID0gMjsKKyAgICAgIGNhc2UgMjogeworICAgICAgICBpZiAodGFnID09IDE4KSB7CisgICAgICAgICBwYXJzZV92YWx1ZToKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRCeXRlcygKKyAgICAgICAgICAgICAgICBpbnB1dCwgdGhpcy0+bXV0YWJsZV92YWx1ZSgpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdEF0RW5kKCkpIGdvdG8gc3VjY2VzczsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGRlZmF1bHQ6IHsKKyAgICAgIGhhbmRsZV91bnVzdWFsOgorICAgICAgICBpZiAodGFnID09IDAgfHwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdXaXJlVHlwZSh0YWcpID09CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRU5EX0dST1VQKSB7CisgICAgICAgICAgZ290byBzdWNjZXNzOworICAgICAgICB9CisgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U2tpcEZpZWxkKGlucHV0LCB0YWcpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CitzdWNjZXNzOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3VjY2Vzczpnb29nbGUucHJvdG9idWYuQW55KQorICByZXR1cm4gdHJ1ZTsKK2ZhaWx1cmU6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9mYWlsdXJlOmdvb2dsZS5wcm90b2J1Zi5BbnkpCisgIHJldHVybiBmYWxzZTsKKyN1bmRlZiBET18KK30KKwordm9pZCBBbnk6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkFueSkKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIHR5cGVfdXJsID0gMTsKKyAgaWYgKHRoaXMtPnR5cGVfdXJsKCkuc2l6ZSgpID4gMCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpWZXJpZnlVdGY4U3RyaW5nKAorICAgICAgdGhpcy0+dHlwZV91cmwoKS5kYXRhKCksIHRoaXMtPnR5cGVfdXJsKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5BbnkudHlwZV91cmwiKTsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdNYXliZUFsaWFzZWQoCisgICAgICAxLCB0aGlzLT50eXBlX3VybCgpLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgYnl0ZXMgdmFsdWUgPSAyOworICBpZiAodGhpcy0+dmFsdWUoKS5zaXplKCkgPiAwKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlQnl0ZXNNYXliZUFsaWFzZWQoCisgICAgICAyLCB0aGlzLT52YWx1ZSgpLCBvdXRwdXQpOworICB9CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9lbmQ6Z29vZ2xlLnByb3RvYnVmLkFueSkKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogQW55OjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIHRhcmdldCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5BbnkpCisgIC8vIG9wdGlvbmFsIHN0cmluZyB0eXBlX3VybCA9IDE7CisgIGlmICh0aGlzLT50eXBlX3VybCgpLnNpemUoKSA+IDApIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VmVyaWZ5VXRmOFN0cmluZygKKyAgICAgIHRoaXMtPnR5cGVfdXJsKCkuZGF0YSgpLCB0aGlzLT50eXBlX3VybCgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuQW55LnR5cGVfdXJsIik7CisgICAgdGFyZ2V0ID0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ1RvQXJyYXkoCisgICAgICAgIDEsIHRoaXMtPnR5cGVfdXJsKCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBieXRlcyB2YWx1ZSA9IDI7CisgIGlmICh0aGlzLT52YWx1ZSgpLnNpemUoKSA+IDApIHsKKyAgICB0YXJnZXQgPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlQnl0ZXNUb0FycmF5KAorICAgICAgICAyLCB0aGlzLT52YWx1ZSgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9lbmQ6Z29vZ2xlLnByb3RvYnVmLkFueSkKKyAgcmV0dXJuIHRhcmdldDsKK30KKworaW50IEFueTo6Qnl0ZVNpemUoKSBjb25zdCB7CisgIGludCB0b3RhbF9zaXplID0gMDsKKworICAvLyBvcHRpb25hbCBzdHJpbmcgdHlwZV91cmwgPSAxOworICBpZiAodGhpcy0+dHlwZV91cmwoKS5zaXplKCkgPiAwKSB7CisgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTdHJpbmdTaXplKAorICAgICAgICB0aGlzLT50eXBlX3VybCgpKTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGJ5dGVzIHZhbHVlID0gMjsKKyAgaWYgKHRoaXMtPnZhbHVlKCkuc2l6ZSgpID4gMCkgeworICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6Qnl0ZXNTaXplKAorICAgICAgICB0aGlzLT52YWx1ZSgpKTsKKyAgfQorCisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSB0b3RhbF9zaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKKyAgcmV0dXJuIHRvdGFsX3NpemU7Cit9CisKK3ZvaWQgQW55OjpNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGNvbnN0IEFueSogc291cmNlID0gCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpEeW5hbWljQ2FzdFRvR2VuZXJhdGVkPGNvbnN0IEFueT4oCisgICAgICAgICAgJmZyb20pOworICBpZiAoc291cmNlID09IE5VTEwpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpSZWZsZWN0aW9uT3BzOjpNZXJnZShmcm9tLCB0aGlzKTsKKyAgfSBlbHNlIHsKKyAgICBNZXJnZUZyb20oKnNvdXJjZSk7CisgIH0KK30KKwordm9pZCBBbnk6Ok1lcmdlRnJvbShjb25zdCBBbnkmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgaWYgKGZyb20udHlwZV91cmwoKS5zaXplKCkgPiAwKSB7CisKKyAgICB0eXBlX3VybF8uQXNzaWduV2l0aERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBmcm9tLnR5cGVfdXJsXyk7CisgIH0KKyAgaWYgKGZyb20udmFsdWUoKS5zaXplKCkgPiAwKSB7CisKKyAgICB2YWx1ZV8uQXNzaWduV2l0aERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBmcm9tLnZhbHVlXyk7CisgIH0KK30KKwordm9pZCBBbnk6OkNvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK3ZvaWQgQW55OjpDb3B5RnJvbShjb25zdCBBbnkmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCitib29sIEFueTo6SXNJbml0aWFsaXplZCgpIGNvbnN0IHsKKworICByZXR1cm4gdHJ1ZTsKK30KKwordm9pZCBBbnk6OlN3YXAoQW55KiBvdGhlcikgeworICBpZiAob3RoZXIgPT0gdGhpcykgcmV0dXJuOworICBJbnRlcm5hbFN3YXAob3RoZXIpOworfQordm9pZCBBbnk6OkludGVybmFsU3dhcChBbnkqIG90aGVyKSB7CisgIHR5cGVfdXJsXy5Td2FwKCZvdGhlci0+dHlwZV91cmxfKTsKKyAgdmFsdWVfLlN3YXAoJm90aGVyLT52YWx1ZV8pOworICBfaW50ZXJuYWxfbWV0YWRhdGFfLlN3YXAoJm90aGVyLT5faW50ZXJuYWxfbWV0YWRhdGFfKTsKKyAgc3RkOjpzd2FwKF9jYWNoZWRfc2l6ZV8sIG90aGVyLT5fY2FjaGVkX3NpemVfKTsKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBBbnk6OkdldE1ldGFkYXRhKCkgY29uc3QgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBtZXRhZGF0YTsKKyAgbWV0YWRhdGEuZGVzY3JpcHRvciA9IEFueV9kZXNjcmlwdG9yXzsKKyAgbWV0YWRhdGEucmVmbGVjdGlvbiA9IEFueV9yZWZsZWN0aW9uXzsKKyAgcmV0dXJuIG1ldGFkYXRhOworfQorCisjaWYgUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisvLyBBbnkKKworLy8gb3B0aW9uYWwgc3RyaW5nIHR5cGVfdXJsID0gMTsKK3ZvaWQgQW55OjpjbGVhcl90eXBlX3VybCgpIHsKKyAgdHlwZV91cmxfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyBjb25zdCA6OnN0ZDo6c3RyaW5nJiBBbnk6OnR5cGVfdXJsKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5BbnkudHlwZV91cmwpCisgIHJldHVybiB0eXBlX3VybF8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgQW55OjpzZXRfdHlwZV91cmwoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgCisgIHR5cGVfdXJsXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5BbnkudHlwZV91cmwpCit9Cisgdm9pZCBBbnk6OnNldF90eXBlX3VybChjb25zdCBjaGFyKiB2YWx1ZSkgeworICAKKyAgdHlwZV91cmxfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuQW55LnR5cGVfdXJsKQorfQorIHZvaWQgQW55OjpzZXRfdHlwZV91cmwoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIAorICB0eXBlX3VybF8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLkFueS50eXBlX3VybCkKK30KKyA6OnN0ZDo6c3RyaW5nKiBBbnk6Om11dGFibGVfdHlwZV91cmwoKSB7CisgIAorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuQW55LnR5cGVfdXJsKQorICByZXR1cm4gdHlwZV91cmxfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CisgOjpzdGQ6OnN0cmluZyogQW55OjpyZWxlYXNlX3R5cGVfdXJsKCkgeworICAKKyAgcmV0dXJuIHR5cGVfdXJsXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgQW55OjpzZXRfYWxsb2NhdGVkX3R5cGVfdXJsKDo6c3RkOjpzdHJpbmcqIHR5cGVfdXJsKSB7CisgIGlmICh0eXBlX3VybCAhPSBOVUxMKSB7CisgICAgCisgIH0gZWxzZSB7CisgICAgCisgIH0KKyAgdHlwZV91cmxfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB0eXBlX3VybCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5BbnkudHlwZV91cmwpCit9CisKKy8vIG9wdGlvbmFsIGJ5dGVzIHZhbHVlID0gMjsKK3ZvaWQgQW55OjpjbGVhcl92YWx1ZSgpIHsKKyAgdmFsdWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyBjb25zdCA6OnN0ZDo6c3RyaW5nJiBBbnk6OnZhbHVlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5BbnkudmFsdWUpCisgIHJldHVybiB2YWx1ZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgQW55OjpzZXRfdmFsdWUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgCisgIHZhbHVlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5BbnkudmFsdWUpCit9Cisgdm9pZCBBbnk6OnNldF92YWx1ZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICAKKyAgdmFsdWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuQW55LnZhbHVlKQorfQorIHZvaWQgQW55OjpzZXRfdmFsdWUoY29uc3Qgdm9pZCogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIAorICB2YWx1ZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLkFueS52YWx1ZSkKK30KKyA6OnN0ZDo6c3RyaW5nKiBBbnk6Om11dGFibGVfdmFsdWUoKSB7CisgIAorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuQW55LnZhbHVlKQorICByZXR1cm4gdmFsdWVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CisgOjpzdGQ6OnN0cmluZyogQW55OjpyZWxlYXNlX3ZhbHVlKCkgeworICAKKyAgcmV0dXJuIHZhbHVlXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgQW55OjpzZXRfYWxsb2NhdGVkX3ZhbHVlKDo6c3RkOjpzdHJpbmcqIHZhbHVlKSB7CisgIGlmICh2YWx1ZSAhPSBOVUxMKSB7CisgICAgCisgIH0gZWxzZSB7CisgICAgCisgIH0KKyAgdmFsdWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5BbnkudmFsdWUpCit9CisKKyNlbmRpZiAgLy8gUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisKKy8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChuYW1lc3BhY2Vfc2NvcGUpCisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZ2xvYmFsX3Njb3BlKQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9hbnkucGIuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvYW55LnBiLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTc5ODJlYwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvYW55LnBiLmgKQEAgLTAsMCArMSwyNTAgQEAKKy8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCisvLyBzb3VyY2U6IGdvb2dsZS9wcm90b2J1Zi9hbnkucHJvdG8KKworI2lmbmRlZiBQUk9UT0JVRl9nb29nbGVfMmZwcm90b2J1Zl8yZmFueV8yZXByb3RvX19JTkNMVURFRAorI2RlZmluZSBQUk9UT0JVRl9nb29nbGVfMmZwcm90b2J1Zl8yZmFueV8yZXByb3RvX19JTkNMVURFRAorCisjaW5jbHVkZSA8c3RyaW5nPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorCisjaWYgR09PR0xFX1BST1RPQlVGX1ZFUlNJT04gPCAzMDAwMDAwCisjZXJyb3IgVGhpcyBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgYSBuZXdlciB2ZXJzaW9uIG9mIHByb3RvYyB3aGljaCBpcworI2Vycm9yIGluY29tcGF0aWJsZSB3aXRoIHlvdXIgUHJvdG9jb2wgQnVmZmVyIGhlYWRlcnMuICBQbGVhc2UgdXBkYXRlCisjZXJyb3IgeW91ciBoZWFkZXJzLgorI2VuZGlmCisjaWYgMzAwMDAwMCA8IEdPT0dMRV9QUk9UT0JVRl9NSU5fUFJPVE9DX1ZFUlNJT04KKyNlcnJvciBUaGlzIGZpbGUgd2FzIGdlbmVyYXRlZCBieSBhbiBvbGRlciB2ZXJzaW9uIG9mIHByb3RvYyB3aGljaCBpcworI2Vycm9yIGluY29tcGF0aWJsZSB3aXRoIHlvdXIgUHJvdG9jb2wgQnVmZmVyIGhlYWRlcnMuICBQbGVhc2UKKyNlcnJvciByZWdlbmVyYXRlIHRoaXMgZmlsZSB3aXRoIGEgbmV3ZXIgdmVyc2lvbiBvZiBwcm90b2MuCisjZW5kaWYKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9hcmVuYS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9hcmVuYXN0cmluZy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfbWVzc2FnZV91dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21ldGFkYXRhLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21lc3NhZ2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcmVwZWF0ZWRfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZXh0ZW5zaW9uX3NldC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bmtub3duX2ZpZWxkX3NldC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9hbnkuaD4KKy8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbmNsdWRlcykKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCisvLyBJbnRlcm5hbCBpbXBsZW1lbnRhdGlvbiBkZXRhaWwgLS0gZG8gbm90IGNhbGwgdGhlc2UuCit2b2lkIExJQlBST1RPQlVGX0VYUE9SVCBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmYW55XzJlcHJvdG8oKTsKK3ZvaWQgcHJvdG9idWZfQXNzaWduRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmFueV8yZXByb3RvKCk7Cit2b2lkIHByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZmFueV8yZXByb3RvKCk7CisKK2NsYXNzIEFueTsKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgQW55IDogcHVibGljIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSB7CisgcHVibGljOgorICBBbnkoKTsKKyAgdmlydHVhbCB+QW55KCk7CisKKyAgQW55KGNvbnN0IEFueSYgZnJvbSk7CisKKyAgaW5saW5lIEFueSYgb3BlcmF0b3I9KGNvbnN0IEFueSYgZnJvbSkgeworICAgIENvcHlGcm9tKGZyb20pOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIHN0YXRpYyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIGRlc2NyaXB0b3IoKTsKKyAgc3RhdGljIGNvbnN0IEFueSYgZGVmYXVsdF9pbnN0YW5jZSgpOworCisgIC8vIGltcGxlbWVudHMgQW55IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgdm9pZCBQYWNrRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIG1lc3NhZ2UpOworICBib29sIFVucGFja1RvKDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSogbWVzc2FnZSkgY29uc3Q7CisgIHRlbXBsYXRlPHR5cGVuYW1lIFQ+IGJvb2wgSXMoKSBjb25zdCB7CisgICAgcmV0dXJuIF9hbnlfbWV0YWRhdGFfLklzPFQ+KCk7CisgIH0KKworICB2b2lkIFN3YXAoQW55KiBvdGhlcik7CisKKyAgLy8gaW1wbGVtZW50cyBNZXNzYWdlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBpbmxpbmUgQW55KiBOZXcoKSBjb25zdCB7IHJldHVybiBOZXcoTlVMTCk7IH0KKworICBBbnkqIE5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3Q7CisgIHZvaWQgQ29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCBBbnkmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCBBbnkmIGZyb20pOworICB2b2lkIENsZWFyKCk7CisgIGJvb2wgSXNJbml0aWFsaXplZCgpIGNvbnN0OworCisgIGludCBCeXRlU2l6ZSgpIGNvbnN0OworICBib29sIE1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KTsKKyAgdm9pZCBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSg6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBvdXRwdXQpIGNvbnN0OworICBpbnQgR2V0Q2FjaGVkU2l6ZSgpIGNvbnN0IHsgcmV0dXJuIF9jYWNoZWRfc2l6ZV87IH0KKyAgcHJpdmF0ZToKKyAgdm9pZCBTaGFyZWRDdG9yKCk7CisgIHZvaWQgU2hhcmVkRHRvcigpOworICB2b2lkIFNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0OworICB2b2lkIEludGVybmFsU3dhcChBbnkqIG90aGVyKTsKKyAgcHJpdmF0ZToKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hTm9WaXJ0dWFsKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLmFyZW5hKCk7CisgIH0KKyAgaW5saW5lIHZvaWQqIE1heWJlQXJlbmFQdHIoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ucmF3X2FyZW5hX3B0cigpOworICB9CisgIHB1YmxpYzoKKworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEdldE1ldGFkYXRhKCkgY29uc3Q7CisKKyAgLy8gbmVzdGVkIHR5cGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBhY2Nlc3NvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIG9wdGlvbmFsIHN0cmluZyB0eXBlX3VybCA9IDE7CisgIHZvaWQgY2xlYXJfdHlwZV91cmwoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrVHlwZVVybEZpZWxkTnVtYmVyID0gMTsKKyAgY29uc3QgOjpzdGQ6OnN0cmluZyYgdHlwZV91cmwoKSBjb25zdDsKKyAgdm9pZCBzZXRfdHlwZV91cmwoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpOworICB2b2lkIHNldF90eXBlX3VybChjb25zdCBjaGFyKiB2YWx1ZSk7CisgIHZvaWQgc2V0X3R5cGVfdXJsKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIDo6c3RkOjpzdHJpbmcqIG11dGFibGVfdHlwZV91cmwoKTsKKyAgOjpzdGQ6OnN0cmluZyogcmVsZWFzZV90eXBlX3VybCgpOworICB2b2lkIHNldF9hbGxvY2F0ZWRfdHlwZV91cmwoOjpzdGQ6OnN0cmluZyogdHlwZV91cmwpOworCisgIC8vIG9wdGlvbmFsIGJ5dGVzIHZhbHVlID0gMjsKKyAgdm9pZCBjbGVhcl92YWx1ZSgpOworICBzdGF0aWMgY29uc3QgaW50IGtWYWx1ZUZpZWxkTnVtYmVyID0gMjsKKyAgY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUoKSBjb25zdDsKKyAgdm9pZCBzZXRfdmFsdWUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpOworICB2b2lkIHNldF92YWx1ZShjb25zdCBjaGFyKiB2YWx1ZSk7CisgIHZvaWQgc2V0X3ZhbHVlKGNvbnN0IHZvaWQqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIDo6c3RkOjpzdHJpbmcqIG11dGFibGVfdmFsdWUoKTsKKyAgOjpzdGQ6OnN0cmluZyogcmVsZWFzZV92YWx1ZSgpOworICB2b2lkIHNldF9hbGxvY2F0ZWRfdmFsdWUoOjpzdGQ6OnN0cmluZyogdmFsdWUpOworCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpnb29nbGUucHJvdG9idWYuQW55KQorIHByaXZhdGU6CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6SW50ZXJuYWxNZXRhZGF0YVdpdGhBcmVuYSBfaW50ZXJuYWxfbWV0YWRhdGFfOworICBib29sIF9pc19kZWZhdWx0X2luc3RhbmNlXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QXJlbmFTdHJpbmdQdHIgdHlwZV91cmxfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBcmVuYVN0cmluZ1B0ciB2YWx1ZV87CisgIG11dGFibGUgaW50IF9jYWNoZWRfc2l6ZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFueU1ldGFkYXRhIF9hbnlfbWV0YWRhdGFfOworICBmcmllbmQgdm9pZCBMSUJQUk9UT0JVRl9FWFBPUlQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmFueV8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZhbnlfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZhbnlfMmVwcm90bygpOworCisgIHZvaWQgSW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIHN0YXRpYyBBbnkqIGRlZmF1bHRfaW5zdGFuY2VfOworfTsKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKyNpZiAhUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisvLyBBbnkKKworLy8gb3B0aW9uYWwgc3RyaW5nIHR5cGVfdXJsID0gMTsKK2lubGluZSB2b2lkIEFueTo6Y2xlYXJfdHlwZV91cmwoKSB7CisgIHR5cGVfdXJsXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgY29uc3QgOjpzdGQ6OnN0cmluZyYgQW55Ojp0eXBlX3VybCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuQW55LnR5cGVfdXJsKQorICByZXR1cm4gdHlwZV91cmxfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIEFueTo6c2V0X3R5cGVfdXJsKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIAorICB0eXBlX3VybF8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuQW55LnR5cGVfdXJsKQorfQoraW5saW5lIHZvaWQgQW55OjpzZXRfdHlwZV91cmwoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgCisgIHR5cGVfdXJsXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLkFueS50eXBlX3VybCkKK30KK2lubGluZSB2b2lkIEFueTo6c2V0X3R5cGVfdXJsKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICAKKyAgdHlwZV91cmxfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5BbnkudHlwZV91cmwpCit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogQW55OjptdXRhYmxlX3R5cGVfdXJsKCkgeworICAKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkFueS50eXBlX3VybCkKKyAgcmV0dXJuIHR5cGVfdXJsXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIEFueTo6cmVsZWFzZV90eXBlX3VybCgpIHsKKyAgCisgIHJldHVybiB0eXBlX3VybF8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIEFueTo6c2V0X2FsbG9jYXRlZF90eXBlX3VybCg6OnN0ZDo6c3RyaW5nKiB0eXBlX3VybCkgeworICBpZiAodHlwZV91cmwgIT0gTlVMTCkgeworICAgIAorICB9IGVsc2UgeworICAgIAorICB9CisgIHR5cGVfdXJsXy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdHlwZV91cmwpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuQW55LnR5cGVfdXJsKQorfQorCisvLyBvcHRpb25hbCBieXRlcyB2YWx1ZSA9IDI7CitpbmxpbmUgdm9pZCBBbnk6OmNsZWFyX3ZhbHVlKCkgeworICB2YWx1ZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEFueTo6dmFsdWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkFueS52YWx1ZSkKKyAgcmV0dXJuIHZhbHVlXy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBBbnk6OnNldF92YWx1ZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICAKKyAgdmFsdWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkFueS52YWx1ZSkKK30KK2lubGluZSB2b2lkIEFueTo6c2V0X3ZhbHVlKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIAorICB2YWx1ZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5BbnkudmFsdWUpCit9CitpbmxpbmUgdm9pZCBBbnk6OnNldF92YWx1ZShjb25zdCB2b2lkKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgCisgIHZhbHVlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuQW55LnZhbHVlKQorfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIEFueTo6bXV0YWJsZV92YWx1ZSgpIHsKKyAgCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5BbnkudmFsdWUpCisgIHJldHVybiB2YWx1ZV8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBBbnk6OnJlbGVhc2VfdmFsdWUoKSB7CisgIAorICByZXR1cm4gdmFsdWVfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBBbnk6OnNldF9hbGxvY2F0ZWRfdmFsdWUoOjpzdGQ6OnN0cmluZyogdmFsdWUpIHsKKyAgaWYgKHZhbHVlICE9IE5VTEwpIHsKKyAgICAKKyAgfSBlbHNlIHsKKyAgICAKKyAgfQorICB2YWx1ZV8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkFueS52YWx1ZSkKK30KKworI2VuZGlmICAvLyAhUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisKKy8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChuYW1lc3BhY2Vfc2NvcGUpCisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZ2xvYmFsX3Njb3BlKQorCisjZW5kaWYgIC8vIFBST1RPQlVGX2dvb2dsZV8yZnByb3RvYnVmXzJmYW55XzJlcHJvdG9fX0lOQ0xVREVECmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2FueS5wcm90byBiL3NyYy9nb29nbGUvcHJvdG9idWYvYW55LnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU4YTE4YmMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2FueS5wcm90bwpAQCAtMCwwICsxLDk5IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworc3ludGF4ID0gInByb3RvMyI7CisKK3BhY2thZ2UgZ29vZ2xlLnByb3RvYnVmOworCitvcHRpb24gY3NoYXJwX25hbWVzcGFjZSA9ICJHb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlwZXMiOworb3B0aW9uIGphdmFfcGFja2FnZSA9ICJjb20uZ29vZ2xlLnByb3RvYnVmIjsKK29wdGlvbiBqYXZhX291dGVyX2NsYXNzbmFtZSA9ICJBbnlQcm90byI7CitvcHRpb24gamF2YV9tdWx0aXBsZV9maWxlcyA9IHRydWU7CitvcHRpb24gamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2ggPSB0cnVlOworb3B0aW9uIG9iamNfY2xhc3NfcHJlZml4ID0gIkdQQiI7CisKKy8vIGBBbnlgIGNvbnRhaW5zIGFuIGFyYml0cmFyeSBzZXJpYWxpemVkIG1lc3NhZ2UgYWxvbmcgd2l0aCBhIFVSTAorLy8gdGhhdCBkZXNjcmliZXMgdGhlIHR5cGUgb2YgdGhlIHNlcmlhbGl6ZWQgbWVzc2FnZS4KKy8vCisvLworLy8gSlNPTgorLy8gPT09PQorLy8gVGhlIEpTT04gcmVwcmVzZW50YXRpb24gb2YgYW4gYEFueWAgdmFsdWUgdXNlcyB0aGUgcmVndWxhcgorLy8gcmVwcmVzZW50YXRpb24gb2YgdGhlIGRlc2VyaWFsaXplZCwgZW1iZWRkZWQgbWVzc2FnZSwgd2l0aCBhbgorLy8gYWRkaXRpb25hbCBmaWVsZCBgQHR5cGVgIHdoaWNoIGNvbnRhaW5zIHRoZSB0eXBlIFVSTC4gRXhhbXBsZToKKy8vCisvLyAgICAgcGFja2FnZSBnb29nbGUucHJvZmlsZTsKKy8vICAgICBtZXNzYWdlIFBlcnNvbiB7CisvLyAgICAgICBzdHJpbmcgZmlyc3RfbmFtZSA9IDE7CisvLyAgICAgICBzdHJpbmcgbGFzdF9uYW1lID0gMjsKKy8vICAgICB9CisvLworLy8gICAgIHsKKy8vICAgICAgICJAdHlwZSI6ICJ0eXBlLmdvb2dsZWFwaXMuY29tL2dvb2dsZS5wcm9maWxlLlBlcnNvbiIsCisvLyAgICAgICAiZmlyc3ROYW1lIjogPHN0cmluZz4sCisvLyAgICAgICAibGFzdE5hbWUiOiA8c3RyaW5nPgorLy8gICAgIH0KKy8vCisvLyBJZiB0aGUgZW1iZWRkZWQgbWVzc2FnZSB0eXBlIGlzIHdlbGwta25vd24gYW5kIGhhcyBhIGN1c3RvbSBKU09OCisvLyByZXByZXNlbnRhdGlvbiwgdGhhdCByZXByZXNlbnRhdGlvbiB3aWxsIGJlIGVtYmVkZGVkIGFkZGluZyBhIGZpZWxkCisvLyBgdmFsdWVgIHdoaWNoIGhvbGRzIHRoZSBjdXN0b20gSlNPTiBpbiBhZGRpdGlvbiB0byB0aGUgYEB0eXBlYAorLy8gZmllbGQuIEV4YW1wbGUgKGZvciBtZXNzYWdlIFtnb29nbGUucHJvdG9idWYuRHVyYXRpb25dW10pOgorLy8KKy8vICAgICB7CisvLyAgICAgICAiQHR5cGUiOiAidHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUucHJvdG9idWYuRHVyYXRpb24iLAorLy8gICAgICAgInZhbHVlIjogIjEuMjEycyIKKy8vICAgICB9CisvLworbWVzc2FnZSBBbnkgeworICAvLyBBIFVSTC9yZXNvdXJjZSBuYW1lIHdob3NlIGNvbnRlbnQgZGVzY3JpYmVzIHRoZSB0eXBlIG9mIHRoZQorICAvLyBzZXJpYWxpemVkIG1lc3NhZ2UuCisgIC8vCisgIC8vIEZvciBVUkxzIHdoaWNoIHVzZSB0aGUgc2NoZW1hIGBodHRwYCwgYGh0dHBzYCwgb3Igbm8gc2NoZW1hLCB0aGUKKyAgLy8gZm9sbG93aW5nIHJlc3RyaWN0aW9ucyBhbmQgaW50ZXJwcmV0YXRpb25zIGFwcGx5OgorICAvLworICAvLyAqIElmIG5vIHNjaGVtYSBpcyBwcm92aWRlZCwgYGh0dHBzYCBpcyBhc3N1bWVkLgorICAvLyAqIFRoZSBsYXN0IHNlZ21lbnQgb2YgdGhlIFVSTCdzIHBhdGggbXVzdCByZXByZXNlbnQgdGhlIGZ1bGx5CisgIC8vICAgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIHR5cGUgKGFzIGluIGBwYXRoL2dvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbmApLgorICAvLyAqIEFuIEhUVFAgR0VUIG9uIHRoZSBVUkwgbXVzdCB5aWVsZCBhIFtnb29nbGUucHJvdG9idWYuVHlwZV1bXQorICAvLyAgIHZhbHVlIGluIGJpbmFyeSBmb3JtYXQsIG9yIHByb2R1Y2UgYW4gZXJyb3IuCisgIC8vICogQXBwbGljYXRpb25zIGFyZSBhbGxvd2VkIHRvIGNhY2hlIGxvb2t1cCByZXN1bHRzIGJhc2VkIG9uIHRoZQorICAvLyAgIFVSTCwgb3IgaGF2ZSB0aGVtIHByZWNvbXBpbGVkIGludG8gYSBiaW5hcnkgdG8gYXZvaWQgYW55CisgIC8vICAgbG9va3VwLiBUaGVyZWZvcmUsIGJpbmFyeSBjb21wYXRpYmlsaXR5IG5lZWRzIHRvIGJlIHByZXNlcnZlZAorICAvLyAgIG9uIGNoYW5nZXMgdG8gdHlwZXMuIChVc2UgdmVyc2lvbmVkIHR5cGUgbmFtZXMgdG8gbWFuYWdlCisgIC8vICAgYnJlYWtpbmcgY2hhbmdlcy4pCisgIC8vCisgIC8vIFNjaGVtYXMgb3RoZXIgdGhhbiBgaHR0cGAsIGBodHRwc2AgKG9yIHRoZSBlbXB0eSBzY2hlbWEpIG1pZ2h0IGJlCisgIC8vIHVzZWQgd2l0aCBpbXBsZW1lbnRhdGlvbiBzcGVjaWZpYyBzZW1hbnRpY3MuCisgIC8vCisgIHN0cmluZyB0eXBlX3VybCA9IDE7CisKKyAgLy8gTXVzdCBiZSB2YWxpZCBzZXJpYWxpemVkIGRhdGEgb2YgdGhlIGFib3ZlIHNwZWNpZmllZCB0eXBlLgorICBieXRlcyB2YWx1ZSA9IDI7Cit9CmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2FueV90ZXN0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9hbnlfdGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xYmZhYTYzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9hbnlfdGVzdC5jYwpAQCAtMCwwICsxLDg5IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9hbnlfdGVzdC5wYi5oPgorI2luY2x1ZGUgPGd0ZXN0L2d0ZXN0Lmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSB7CisKK1RFU1QoQW55VGVzdCwgVGVzdFBhY2tBbmRVbnBhY2spIHsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RBbnkgc3VibWVzc2FnZTsKKyAgc3VibWVzc2FnZS5zZXRfaW50MzJfdmFsdWUoMTIzNDUpOworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEFueSBtZXNzYWdlOworICBtZXNzYWdlLm11dGFibGVfYW55X3ZhbHVlKCktPlBhY2tGcm9tKHN1Ym1lc3NhZ2UpOworCisgIHN0cmluZyBkYXRhID0gbWVzc2FnZS5TZXJpYWxpemVBc1N0cmluZygpOworCisgIEFTU0VSVF9UUlVFKG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKGRhdGEpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfYW55X3ZhbHVlKCkpOworICBBU1NFUlRfVFJVRShtZXNzYWdlLmFueV92YWx1ZSgpLlVucGFja1RvKCZzdWJtZXNzYWdlKSk7CisgIEVYUEVDVF9FUSgxMjM0NSwgc3VibWVzc2FnZS5pbnQzMl92YWx1ZSgpKTsKK30KKworVEVTVChBbnlUZXN0LCBUZXN0UGFja0FuZFVucGFja0FueSkgeworICAvLyBXZSBjYW4gcGFjayBhIEFueSBtZXNzYWdlIGluc2lkZSBhbm90aGVyIEFueSBtZXNzYWdlLgorICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEFueSBzdWJtZXNzYWdlOworICBzdWJtZXNzYWdlLnNldF9pbnQzMl92YWx1ZSgxMjM0NSk7CisgIGdvb2dsZTo6cHJvdG9idWY6OkFueSBhbnk7CisgIGFueS5QYWNrRnJvbShzdWJtZXNzYWdlKTsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RBbnkgbWVzc2FnZTsKKyAgbWVzc2FnZS5tdXRhYmxlX2FueV92YWx1ZSgpLT5QYWNrRnJvbShhbnkpOworCisgIHN0cmluZyBkYXRhID0gbWVzc2FnZS5TZXJpYWxpemVBc1N0cmluZygpOworCisgIEFTU0VSVF9UUlVFKG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKGRhdGEpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfYW55X3ZhbHVlKCkpOworICBBU1NFUlRfVFJVRShtZXNzYWdlLmFueV92YWx1ZSgpLlVucGFja1RvKCZhbnkpKTsKKyAgQVNTRVJUX1RSVUUoYW55LlVucGFja1RvKCZzdWJtZXNzYWdlKSk7CisgIEVYUEVDVF9FUSgxMjM0NSwgc3VibWVzc2FnZS5pbnQzMl92YWx1ZSgpKTsKK30KKworVEVTVChBbnlUZXN0LCBUZXN0SXMpIHsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RBbnkgc3VibWVzc2FnZTsKKyAgc3VibWVzc2FnZS5zZXRfaW50MzJfdmFsdWUoMTIzNDUpOworICBnb29nbGU6OnByb3RvYnVmOjpBbnkgYW55OworICBhbnkuUGFja0Zyb20oc3VibWVzc2FnZSk7CisgIEFTU0VSVF9UUlVFKGFueS5QYXJzZUZyb21TdHJpbmcoYW55LlNlcmlhbGl6ZUFzU3RyaW5nKCkpKTsKKyAgRVhQRUNUX1RSVUUoYW55LklzPHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0QW55PigpKTsKKyAgRVhQRUNUX0ZBTFNFKGFueS5Jczxnb29nbGU6OnByb3RvYnVmOjpBbnk+KCkpOworCisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0QW55IG1lc3NhZ2U7CisgIG1lc3NhZ2UubXV0YWJsZV9hbnlfdmFsdWUoKS0+UGFja0Zyb20oYW55KTsKKyAgQVNTRVJUX1RSVUUobWVzc2FnZS5QYXJzZUZyb21TdHJpbmcobWVzc2FnZS5TZXJpYWxpemVBc1N0cmluZygpKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmFueV92YWx1ZSgpLklzPHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0QW55PigpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5hbnlfdmFsdWUoKS5Jczxnb29nbGU6OnByb3RvYnVmOjpBbnk+KCkpOworfQorCit9ICAvLyBuYW1lc3BhY2UKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2FueV90ZXN0LnByb3RvIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9hbnlfdGVzdC5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wYzViMzBiCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9hbnlfdGVzdC5wcm90bwpAQCAtMCwwICsxLDQxIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworc3ludGF4ID0gInByb3RvMyI7CisKK3BhY2thZ2UgcHJvdG9idWZfdW5pdHRlc3Q7CisKK2ltcG9ydCAiZ29vZ2xlL3Byb3RvYnVmL2FueS5wcm90byI7CisKK21lc3NhZ2UgVGVzdEFueSB7CisgIGludDMyIGludDMyX3ZhbHVlID0gMTsKKyAgZ29vZ2xlLnByb3RvYnVmLkFueSBhbnlfdmFsdWUgPSAyOworICByZXBlYXRlZCBnb29nbGUucHJvdG9idWYuQW55IHJlcGVhdGVkX2FueV92YWx1ZSA9IDM7Cit9CmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2FwaS5wYi5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvYXBpLnBiLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU1ODlhODkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2FwaS5wYi5jYwpAQCAtMCwwICsxLDE5ODMgQEAKKy8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCisvLyBzb3VyY2U6IGdvb2dsZS9wcm90b2J1Zi9hcGkucHJvdG8KKworI2RlZmluZSBJTlRFUk5BTF9TVVBQUkVTU19QUk9UT0JVRl9GSUVMRF9ERVBSRUNBVElPTgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9hcGkucGIuaD4KKworI2luY2x1ZGUgPGFsZ29yaXRobT4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvcG9ydC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9vbmNlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdF9saXRlX2lubC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9tZXNzYWdlX3JlZmxlY3Rpb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcmVmbGVjdGlvbl9vcHMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuaD4KKy8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbmNsdWRlcykKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCituYW1lc3BhY2UgeworCitjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIEFwaV9kZXNjcmlwdG9yXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbioKKyAgQXBpX3JlZmxlY3Rpb25fID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogTWV0aG9kX2Rlc2NyaXB0b3JfID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKgorICBNZXRob2RfcmVmbGVjdGlvbl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBNaXhpbl9kZXNjcmlwdG9yXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbioKKyAgTWl4aW5fcmVmbGVjdGlvbl8gPSBOVUxMOworCit9ICAvLyBuYW1lc3BhY2UKKworCit2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZhcGlfMmVwcm90bygpIHsKKyAgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmFwaV8yZXByb3RvKCk7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZURlc2NyaXB0b3IqIGZpbGUgPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclBvb2w6OmdlbmVyYXRlZF9wb29sKCktPkZpbmRGaWxlQnlOYW1lKAorICAgICAgImdvb2dsZS9wcm90b2J1Zi9hcGkucHJvdG8iKTsKKyAgR09PR0xFX0NIRUNLKGZpbGUgIT0gTlVMTCk7CisgIEFwaV9kZXNjcmlwdG9yXyA9IGZpbGUtPm1lc3NhZ2VfdHlwZSgwKTsKKyAgc3RhdGljIGNvbnN0IGludCBBcGlfb2Zmc2V0c19bN10gPSB7CisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChBcGksIG5hbWVfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEFwaSwgbWV0aG9kc18pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoQXBpLCBvcHRpb25zXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChBcGksIHZlcnNpb25fKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEFwaSwgc291cmNlX2NvbnRleHRfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEFwaSwgbWl4aW5zXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChBcGksIHN5bnRheF8pLAorICB9OworICBBcGlfcmVmbGVjdGlvbl8gPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpOZXdHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbigKKyAgICAgIEFwaV9kZXNjcmlwdG9yXywKKyAgICAgIEFwaTo6ZGVmYXVsdF9pbnN0YW5jZV8sCisgICAgICBBcGlfb2Zmc2V0c18sCisgICAgICAtMSwKKyAgICAgIC0xLAorICAgICAgLTEsCisgICAgICBzaXplb2YoQXBpKSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoQXBpLCBfaW50ZXJuYWxfbWV0YWRhdGFfKSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoQXBpLCBfaXNfZGVmYXVsdF9pbnN0YW5jZV8pKTsKKyAgTWV0aG9kX2Rlc2NyaXB0b3JfID0gZmlsZS0+bWVzc2FnZV90eXBlKDEpOworICBzdGF0aWMgY29uc3QgaW50IE1ldGhvZF9vZmZzZXRzX1s3XSA9IHsKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKE1ldGhvZCwgbmFtZV8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoTWV0aG9kLCByZXF1ZXN0X3R5cGVfdXJsXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChNZXRob2QsIHJlcXVlc3Rfc3RyZWFtaW5nXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChNZXRob2QsIHJlc3BvbnNlX3R5cGVfdXJsXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChNZXRob2QsIHJlc3BvbnNlX3N0cmVhbWluZ18pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoTWV0aG9kLCBvcHRpb25zXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChNZXRob2QsIHN5bnRheF8pLAorICB9OworICBNZXRob2RfcmVmbGVjdGlvbl8gPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpOZXdHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbigKKyAgICAgIE1ldGhvZF9kZXNjcmlwdG9yXywKKyAgICAgIE1ldGhvZDo6ZGVmYXVsdF9pbnN0YW5jZV8sCisgICAgICBNZXRob2Rfb2Zmc2V0c18sCisgICAgICAtMSwKKyAgICAgIC0xLAorICAgICAgLTEsCisgICAgICBzaXplb2YoTWV0aG9kKSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoTWV0aG9kLCBfaW50ZXJuYWxfbWV0YWRhdGFfKSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoTWV0aG9kLCBfaXNfZGVmYXVsdF9pbnN0YW5jZV8pKTsKKyAgTWl4aW5fZGVzY3JpcHRvcl8gPSBmaWxlLT5tZXNzYWdlX3R5cGUoMik7CisgIHN0YXRpYyBjb25zdCBpbnQgTWl4aW5fb2Zmc2V0c19bMl0gPSB7CisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChNaXhpbiwgbmFtZV8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoTWl4aW4sIHJvb3RfKSwKKyAgfTsKKyAgTWl4aW5fcmVmbGVjdGlvbl8gPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpOZXdHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbigKKyAgICAgIE1peGluX2Rlc2NyaXB0b3JfLAorICAgICAgTWl4aW46OmRlZmF1bHRfaW5zdGFuY2VfLAorICAgICAgTWl4aW5fb2Zmc2V0c18sCisgICAgICAtMSwKKyAgICAgIC0xLAorICAgICAgLTEsCisgICAgICBzaXplb2YoTWl4aW4pLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChNaXhpbiwgX2ludGVybmFsX21ldGFkYXRhXyksCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKE1peGluLCBfaXNfZGVmYXVsdF9pbnN0YW5jZV8pKTsKK30KKworbmFtZXNwYWNlIHsKKworR09PR0xFX1BST1RPQlVGX0RFQ0xBUkVfT05DRShwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc19vbmNlXyk7CitpbmxpbmUgdm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKSB7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6R29vZ2xlT25jZUluaXQoJnByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzX29uY2VfLAorICAgICAgICAgICAgICAgICAmcHJvdG9idWZfQXNzaWduRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmFwaV8yZXByb3RvKTsKK30KKwordm9pZCBwcm90b2J1Zl9SZWdpc3RlclR5cGVzKGNvbnN0IDo6c3RkOjpzdHJpbmcmKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VGYWN0b3J5OjpJbnRlcm5hbFJlZ2lzdGVyR2VuZXJhdGVkTWVzc2FnZSgKKyAgICAgIEFwaV9kZXNjcmlwdG9yXywgJkFwaTo6ZGVmYXVsdF9pbnN0YW5jZSgpKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZE1lc3NhZ2UoCisgICAgICBNZXRob2RfZGVzY3JpcHRvcl8sICZNZXRob2Q6OmRlZmF1bHRfaW5zdGFuY2UoKSk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZUZhY3Rvcnk6OkludGVybmFsUmVnaXN0ZXJHZW5lcmF0ZWRNZXNzYWdlKAorICAgICAgTWl4aW5fZGVzY3JpcHRvcl8sICZNaXhpbjo6ZGVmYXVsdF9pbnN0YW5jZSgpKTsKK30KKworfSAgLy8gbmFtZXNwYWNlCisKK3ZvaWQgcHJvdG9idWZfU2h1dGRvd25GaWxlX2dvb2dsZV8yZnByb3RvYnVmXzJmYXBpXzJlcHJvdG8oKSB7CisgIGRlbGV0ZSBBcGk6OmRlZmF1bHRfaW5zdGFuY2VfOworICBkZWxldGUgQXBpX3JlZmxlY3Rpb25fOworICBkZWxldGUgTWV0aG9kOjpkZWZhdWx0X2luc3RhbmNlXzsKKyAgZGVsZXRlIE1ldGhvZF9yZWZsZWN0aW9uXzsKKyAgZGVsZXRlIE1peGluOjpkZWZhdWx0X2luc3RhbmNlXzsKKyAgZGVsZXRlIE1peGluX3JlZmxlY3Rpb25fOworfQorCit2b2lkIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZhcGlfMmVwcm90bygpIHsKKyAgc3RhdGljIGJvb2wgYWxyZWFkeV9oZXJlID0gZmFsc2U7CisgIGlmIChhbHJlYWR5X2hlcmUpIHJldHVybjsKKyAgYWxyZWFkeV9oZXJlID0gdHJ1ZTsKKyAgR09PR0xFX1BST1RPQlVGX1ZFUklGWV9WRVJTSU9OOworCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6cHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZnNvdXJjZV81ZmNvbnRleHRfMmVwcm90bygpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OnByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZ0eXBlXzJlcHJvdG8oKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUG9vbDo6SW50ZXJuYWxBZGRHZW5lcmF0ZWRGaWxlKAorICAgICJcblwwMzFnb29nbGUvcHJvdG9idWYvYXBpLnByb3RvXDAyMlwwMTdnb29nbGUucHJvdCIKKyAgICAib2J1ZlwwMzIkZ29vZ2xlL3Byb3RvYnVmL3NvdXJjZV9jb250ZXh0LnBybyIKKyAgICAidG9cMDMyXDAzMmdvb2dsZS9wcm90b2J1Zi90eXBlLnByb3RvXCJcMjAxXDAwMlxuXDAwM0FwaVwwMjJcMDE0IgorICAgICJcblwwMDRuYW1lXDAzMFwwMDEgXDAwMShcdFwwMjIoXG5cMDA3bWV0aG9kc1wwMzBcMDAyIFwwMDMoXDAxMzJcMDI3Lmdvb2dsZS5wIgorICAgICJyb3RvYnVmLk1ldGhvZFwwMjIoXG5cMDA3b3B0aW9uc1wwMzBcMDAzIFwwMDMoXDAxMzJcMDI3Lmdvb2dsZSIKKyAgICAiLnByb3RvYnVmLk9wdGlvblwwMjJcMDE3XG5cMDA3dmVyc2lvblwwMzBcMDA0IFwwMDEoXHRcMDIyNlxuXDAxNnNvdSIKKyAgICAicmNlX2NvbnRleHRcMDMwXDAwNSBcMDAxKFwwMTMyXDAzNi5nb29nbGUucHJvdG9idWYuU291ciIKKyAgICAiY2VDb250ZXh0XDAyMiZcblwwMDZtaXhpbnNcMDMwXDAwNiBcMDAzKFwwMTMyXDAyNi5nb29nbGUucHJvdG8iCisgICAgImJ1Zi5NaXhpblwwMjJcJ1xuXDAwNnN5bnRheFwwMzBcMDA3IFwwMDEoXDAxNjJcMDI3Lmdvb2dsZS5wcm90byIKKyAgICAiYnVmLlN5bnRheFwiXDMyNVwwMDFcblwwMDZNZXRob2RcMDIyXDAxNFxuXDAwNG5hbWVcMDMwXDAwMSBcMDAxKFx0XDAyMlwwMzBcblwwMjByIgorICAgICJlcXVlc3RfdHlwZV91cmxcMDMwXDAwMiBcMDAxKFx0XDAyMlwwMzFcblwwMjFyZXF1ZXN0X3N0cmVhbWkiCisgICAgIm5nXDAzMFwwMDMgXDAwMShcMDEwXDAyMlwwMzFcblwwMjFyZXNwb25zZV90eXBlX3VybFwwMzBcMDA0IFwwMDEoXHRcMDIyXDAzMlxuXDAyMnIiCisgICAgImVzcG9uc2Vfc3RyZWFtaW5nXDAzMFwwMDUgXDAwMShcMDEwXDAyMihcblwwMDdvcHRpb25zXDAzMFwwMDYgXDAwMyhcMDEzIgorICAgICIyXDAyNy5nb29nbGUucHJvdG9idWYuT3B0aW9uXDAyMlwnXG5cMDA2c3ludGF4XDAzMFwwMDcgXDAwMSgiCisgICAgIlwwMTYyXDAyNy5nb29nbGUucHJvdG9idWYuU3ludGF4XCIjXG5cMDA1TWl4aW5cMDIyXDAxNFxuXDAwNG4iCisgICAgImFtZVwwMzBcMDAxIFwwMDEoXHRcMDIyXDAxNFxuXDAwNHJvb3RcMDMwXDAwMiBcMDAxKFx0QktcblwwMjNjb20uZ29vZ2xlLnByIgorICAgICJvdG9idWZCXDAxMEFwaVByb3RvUFwwMDFcMjQwXDAwMVwwMDFcMjQyXDAwMlwwMDNHUEJcMjUyXDAwMlwwMzZHb29nbGUuUHJvIgorICAgICJ0b2J1Zi5XZWxsS25vd25UeXBlc2JcMDA2cHJvdG8zIiwgNzA4KTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZEZpbGUoCisgICAgImdvb2dsZS9wcm90b2J1Zi9hcGkucHJvdG8iLCAmcHJvdG9idWZfUmVnaXN0ZXJUeXBlcyk7CisgIEFwaTo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBuZXcgQXBpKCk7CisgIE1ldGhvZDo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBuZXcgTWV0aG9kKCk7CisgIE1peGluOjpkZWZhdWx0X2luc3RhbmNlXyA9IG5ldyBNaXhpbigpOworICBBcGk6OmRlZmF1bHRfaW5zdGFuY2VfLT5Jbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgTWV0aG9kOjpkZWZhdWx0X2luc3RhbmNlXy0+SW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIE1peGluOjpkZWZhdWx0X2luc3RhbmNlXy0+SW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6Ok9uU2h1dGRvd24oJnByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZmFwaV8yZXByb3RvKTsKK30KKworLy8gRm9yY2UgQWRkRGVzY3JpcHRvcnMoKSB0byBiZSBjYWxsZWQgYXQgc3RhdGljIGluaXRpYWxpemF0aW9uIHRpbWUuCitzdHJ1Y3QgU3RhdGljRGVzY3JpcHRvckluaXRpYWxpemVyX2dvb2dsZV8yZnByb3RvYnVmXzJmYXBpXzJlcHJvdG8geworICBTdGF0aWNEZXNjcmlwdG9ySW5pdGlhbGl6ZXJfZ29vZ2xlXzJmcHJvdG9idWZfMmZhcGlfMmVwcm90bygpIHsKKyAgICBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmYXBpXzJlcHJvdG8oKTsKKyAgfQorfSBzdGF0aWNfZGVzY3JpcHRvcl9pbml0aWFsaXplcl9nb29nbGVfMmZwcm90b2J1Zl8yZmFwaV8yZXByb3RvXzsKKworbmFtZXNwYWNlIHsKKworc3RhdGljIHZvaWQgTWVyZ2VGcm9tRmFpbChpbnQgbGluZSkgR09PR0xFX0FUVFJJQlVURV9DT0xEOworc3RhdGljIHZvaWQgTWVyZ2VGcm9tRmFpbChpbnQgbGluZSkgeworICBHT09HTEVfQ0hFQ0soZmFsc2UpIDw8IF9fRklMRV9fIDw8ICI6IiA8PCBsaW5lOworfQorCit9ICAvLyBuYW1lc3BhY2UKKworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKyNpZiAhZGVmaW5lZChfTVNDX1ZFUikgfHwgX01TQ19WRVIgPj0gMTkwMAorY29uc3QgaW50IEFwaTo6a05hbWVGaWVsZE51bWJlcjsKK2NvbnN0IGludCBBcGk6OmtNZXRob2RzRmllbGROdW1iZXI7Citjb25zdCBpbnQgQXBpOjprT3B0aW9uc0ZpZWxkTnVtYmVyOworY29uc3QgaW50IEFwaTo6a1ZlcnNpb25GaWVsZE51bWJlcjsKK2NvbnN0IGludCBBcGk6OmtTb3VyY2VDb250ZXh0RmllbGROdW1iZXI7Citjb25zdCBpbnQgQXBpOjprTWl4aW5zRmllbGROdW1iZXI7Citjb25zdCBpbnQgQXBpOjprU3ludGF4RmllbGROdW1iZXI7CisjZW5kaWYgIC8vICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCisKK0FwaTo6QXBpKCkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5BcGkpCit9CisKK3ZvaWQgQXBpOjpJbml0QXNEZWZhdWx0SW5zdGFuY2UoKSB7CisgIF9pc19kZWZhdWx0X2luc3RhbmNlXyA9IHRydWU7CisgIHNvdXJjZV9jb250ZXh0XyA9IGNvbnN0X2Nhc3Q8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29udGV4dCo+KCY6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvbnRleHQ6OmRlZmF1bHRfaW5zdGFuY2UoKSk7Cit9CisKK0FwaTo6QXBpKGNvbnN0IEFwaSYgZnJvbSkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwKKyAgICBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICBNZXJnZUZyb20oZnJvbSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb3B5X2NvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5BcGkpCit9CisKK3ZvaWQgQXBpOjpTaGFyZWRDdG9yKCkgeworICAgIF9pc19kZWZhdWx0X2luc3RhbmNlXyA9IGZhbHNlOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZygpOworICBfY2FjaGVkX3NpemVfID0gMDsKKyAgbmFtZV8uVW5zYWZlU2V0RGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICB2ZXJzaW9uXy5VbnNhZmVTZXREZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIHNvdXJjZV9jb250ZXh0XyA9IE5VTEw7CisgIHN5bnRheF8gPSAwOworfQorCitBcGk6On5BcGkoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChkZXN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5BcGkpCisgIFNoYXJlZER0b3IoKTsKK30KKwordm9pZCBBcGk6OlNoYXJlZER0b3IoKSB7CisgIG5hbWVfLkRlc3Ryb3lOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIHZlcnNpb25fLkRlc3Ryb3lOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGlmICh0aGlzICE9IGRlZmF1bHRfaW5zdGFuY2VfKSB7CisgICAgZGVsZXRlIHNvdXJjZV9jb250ZXh0XzsKKyAgfQorfQorCit2b2lkIEFwaTo6U2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3QgeworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIEFwaTo6ZGVzY3JpcHRvcigpIHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIHJldHVybiBBcGlfZGVzY3JpcHRvcl87Cit9CisKK2NvbnN0IEFwaSYgQXBpOjpkZWZhdWx0X2luc3RhbmNlKCkgeworICBpZiAoZGVmYXVsdF9pbnN0YW5jZV8gPT0gTlVMTCkgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmFwaV8yZXByb3RvKCk7CisgIHJldHVybiAqZGVmYXVsdF9pbnN0YW5jZV87Cit9CisKK0FwaSogQXBpOjpkZWZhdWx0X2luc3RhbmNlXyA9IE5VTEw7CisKK0FwaSogQXBpOjpOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0IHsKKyAgQXBpKiBuID0gbmV3IEFwaTsKKyAgaWYgKGFyZW5hICE9IE5VTEwpIHsKKyAgICBhcmVuYS0+T3duKG4pOworICB9CisgIHJldHVybiBuOworfQorCit2b2lkIEFwaTo6Q2xlYXIoKSB7CisgIG5hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgdmVyc2lvbl8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBpZiAoR2V0QXJlbmFOb1ZpcnR1YWwoKSA9PSBOVUxMICYmIHNvdXJjZV9jb250ZXh0XyAhPSBOVUxMKSBkZWxldGUgc291cmNlX2NvbnRleHRfOworICBzb3VyY2VfY29udGV4dF8gPSBOVUxMOworICBzeW50YXhfID0gMDsKKyAgbWV0aG9kc18uQ2xlYXIoKTsKKyAgb3B0aW9uc18uQ2xlYXIoKTsKKyAgbWl4aW5zXy5DbGVhcigpOworfQorCitib29sIEFwaTo6TWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KSB7CisjZGVmaW5lIERPXyhFWFBSRVNTSU9OKSBpZiAoIShFWFBSRVNTSU9OKSkgZ290byBmYWlsdXJlCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIHRhZzsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5BcGkpCisgIGZvciAoOzspIHsKKyAgICA6OnN0ZDo6cGFpcjwgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIsIGJvb2w+IHAgPSBpbnB1dC0+UmVhZFRhZ1dpdGhDdXRvZmYoMTI3KTsKKyAgICB0YWcgPSBwLmZpcnN0OworICAgIGlmICghcC5zZWNvbmQpIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgc3dpdGNoICg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnRmllbGROdW1iZXIodGFnKSkgeworICAgICAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICAgICAgY2FzZSAxOiB7CisgICAgICAgIGlmICh0YWcgPT0gMTApIHsKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoCisgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPm11dGFibGVfbmFtZSgpKSk7CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpWZXJpZnlVdGY4U3RyaW5nKAorICAgICAgICAgICAgdGhpcy0+bmFtZSgpLmRhdGEoKSwgdGhpcy0+bmFtZSgpLmxlbmd0aCgpLAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlBBUlNFLAorICAgICAgICAgICAgImdvb2dsZS5wcm90b2J1Zi5BcGkubmFtZSIpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDE4KSkgZ290byBwYXJzZV9tZXRob2RzOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5NZXRob2QgbWV0aG9kcyA9IDI7CisgICAgICBjYXNlIDI6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAxOCkgeworICAgICAgICAgcGFyc2VfbWV0aG9kczoKKyAgICAgICAgICBET18oaW5wdXQtPkluY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCkpOworICAgICAgICAgcGFyc2VfbG9vcF9tZXRob2RzOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZE1lc3NhZ2VOb1ZpcnR1YWxOb1JlY3Vyc2lvbkRlcHRoKAorICAgICAgICAgICAgICAgIGlucHV0LCBhZGRfbWV0aG9kcygpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygxOCkpIGdvdG8gcGFyc2VfbG9vcF9tZXRob2RzOworICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygyNikpIGdvdG8gcGFyc2VfbG9vcF9vcHRpb25zOworICAgICAgICBpbnB1dC0+VW5zYWZlRGVjcmVtZW50UmVjdXJzaW9uRGVwdGgoKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuT3B0aW9uIG9wdGlvbnMgPSAzOworICAgICAgY2FzZSAzOiB7CisgICAgICAgIGlmICh0YWcgPT0gMjYpIHsKKyAgICAgICAgICBET18oaW5wdXQtPkluY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCkpOworICAgICAgICAgcGFyc2VfbG9vcF9vcHRpb25zOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZE1lc3NhZ2VOb1ZpcnR1YWxOb1JlY3Vyc2lvbkRlcHRoKAorICAgICAgICAgICAgICAgIGlucHV0LCBhZGRfb3B0aW9ucygpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygyNikpIGdvdG8gcGFyc2VfbG9vcF9vcHRpb25zOworICAgICAgICBpbnB1dC0+VW5zYWZlRGVjcmVtZW50UmVjdXJzaW9uRGVwdGgoKTsKKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMzQpKSBnb3RvIHBhcnNlX3ZlcnNpb247CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCBzdHJpbmcgdmVyc2lvbiA9IDQ7CisgICAgICBjYXNlIDQ6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAzNCkgeworICAgICAgICAgcGFyc2VfdmVyc2lvbjoKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoCisgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPm11dGFibGVfdmVyc2lvbigpKSk7CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpWZXJpZnlVdGY4U3RyaW5nKAorICAgICAgICAgICAgdGhpcy0+dmVyc2lvbigpLmRhdGEoKSwgdGhpcy0+dmVyc2lvbigpLmxlbmd0aCgpLAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlBBUlNFLAorICAgICAgICAgICAgImdvb2dsZS5wcm90b2J1Zi5BcGkudmVyc2lvbiIpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDQyKSkgZ290byBwYXJzZV9zb3VyY2VfY29udGV4dDsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCBzb3VyY2VfY29udGV4dCA9IDU7CisgICAgICBjYXNlIDU6IHsKKyAgICAgICAgaWYgKHRhZyA9PSA0MikgeworICAgICAgICAgcGFyc2Vfc291cmNlX2NvbnRleHQ6CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkTWVzc2FnZU5vVmlydHVhbCgKKyAgICAgICAgICAgICAgIGlucHV0LCBtdXRhYmxlX3NvdXJjZV9jb250ZXh0KCkpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDUwKSkgZ290byBwYXJzZV9taXhpbnM7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLk1peGluIG1peGlucyA9IDY7CisgICAgICBjYXNlIDY6IHsKKyAgICAgICAgaWYgKHRhZyA9PSA1MCkgeworICAgICAgICAgcGFyc2VfbWl4aW5zOgorICAgICAgICAgIERPXyhpbnB1dC0+SW5jcmVtZW50UmVjdXJzaW9uRGVwdGgoKSk7CisgICAgICAgICBwYXJzZV9sb29wX21peGluczoKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRNZXNzYWdlTm9WaXJ0dWFsTm9SZWN1cnNpb25EZXB0aCgKKyAgICAgICAgICAgICAgICBpbnB1dCwgYWRkX21peGlucygpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg1MCkpIGdvdG8gcGFyc2VfbG9vcF9taXhpbnM7CisgICAgICAgIGlucHV0LT5VbnNhZmVEZWNyZW1lbnRSZWN1cnNpb25EZXB0aCgpOworICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg1NikpIGdvdG8gcGFyc2Vfc3ludGF4OworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5TeW50YXggc3ludGF4ID0gNzsKKyAgICAgIGNhc2UgNzogeworICAgICAgICBpZiAodGFnID09IDU2KSB7CisgICAgICAgICBwYXJzZV9zeW50YXg6CisgICAgICAgICAgaW50IHZhbHVlOworICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgaW50LCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9FTlVNPigKKyAgICAgICAgICAgICAgICAgaW5wdXQsICZ2YWx1ZSkpKTsKKyAgICAgICAgICBzZXRfc3ludGF4KHN0YXRpY19jYXN0PCA6Omdvb2dsZTo6cHJvdG9idWY6OlN5bnRheCA+KHZhbHVlKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdEF0RW5kKCkpIGdvdG8gc3VjY2VzczsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGRlZmF1bHQ6IHsKKyAgICAgIGhhbmRsZV91bnVzdWFsOgorICAgICAgICBpZiAodGFnID09IDAgfHwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdXaXJlVHlwZSh0YWcpID09CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRU5EX0dST1VQKSB7CisgICAgICAgICAgZ290byBzdWNjZXNzOworICAgICAgICB9CisgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U2tpcEZpZWxkKGlucHV0LCB0YWcpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CitzdWNjZXNzOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3VjY2Vzczpnb29nbGUucHJvdG9idWYuQXBpKQorICByZXR1cm4gdHJ1ZTsKK2ZhaWx1cmU6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9mYWlsdXJlOmdvb2dsZS5wcm90b2J1Zi5BcGkpCisgIHJldHVybiBmYWxzZTsKKyN1bmRlZiBET18KK30KKwordm9pZCBBcGk6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkFwaSkKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICBpZiAodGhpcy0+bmFtZSgpLnNpemUoKSA+IDApIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VmVyaWZ5VXRmOFN0cmluZygKKyAgICAgIHRoaXMtPm5hbWUoKS5kYXRhKCksIHRoaXMtPm5hbWUoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLkFwaS5uYW1lIik7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nTWF5YmVBbGlhc2VkKAorICAgICAgMSwgdGhpcy0+bmFtZSgpLCBvdXRwdXQpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5NZXRob2QgbWV0aG9kcyA9IDI7CisgIGZvciAodW5zaWduZWQgaW50IGkgPSAwLCBuID0gdGhpcy0+bWV0aG9kc19zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgMiwgdGhpcy0+bWV0aG9kcyhpKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuT3B0aW9uIG9wdGlvbnMgPSAzOworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPm9wdGlvbnNfc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlTWVzc2FnZU1heWJlVG9BcnJheSgKKyAgICAgIDMsIHRoaXMtPm9wdGlvbnMoaSksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgdmVyc2lvbiA9IDQ7CisgIGlmICh0aGlzLT52ZXJzaW9uKCkuc2l6ZSgpID4gMCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpWZXJpZnlVdGY4U3RyaW5nKAorICAgICAgdGhpcy0+dmVyc2lvbigpLmRhdGEoKSwgdGhpcy0+dmVyc2lvbigpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuQXBpLnZlcnNpb24iKTsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdNYXliZUFsaWFzZWQoCisgICAgICA0LCB0aGlzLT52ZXJzaW9uKCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQgc291cmNlX2NvbnRleHQgPSA1OworICBpZiAodGhpcy0+aGFzX3NvdXJjZV9jb250ZXh0KCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgNSwgKnRoaXMtPnNvdXJjZV9jb250ZXh0Xywgb3V0cHV0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuTWl4aW4gbWl4aW5zID0gNjsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT5taXhpbnNfc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlTWVzc2FnZU1heWJlVG9BcnJheSgKKyAgICAgIDYsIHRoaXMtPm1peGlucyhpKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuU3ludGF4IHN5bnRheCA9IDc7CisgIGlmICh0aGlzLT5zeW50YXgoKSAhPSAwKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlRW51bSgKKyAgICAgIDcsIHRoaXMtPnN5bnRheCgpLCBvdXRwdXQpOworICB9CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9lbmQ6Z29vZ2xlLnByb3RvYnVmLkFwaSkKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogQXBpOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIHRhcmdldCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5BcGkpCisgIC8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKKyAgaWYgKHRoaXMtPm5hbWUoKS5zaXplKCkgPiAwKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlZlcmlmeVV0ZjhTdHJpbmcoCisgICAgICB0aGlzLT5uYW1lKCkuZGF0YSgpLCB0aGlzLT5uYW1lKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5BcGkubmFtZSIpOworICAgIHRhcmdldCA9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdUb0FycmF5KAorICAgICAgICAxLCB0aGlzLT5uYW1lKCksIHRhcmdldCk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLk1ldGhvZCBtZXRob2RzID0gMjsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT5tZXRob2RzX3NpemUoKTsgaSA8IG47IGkrKykgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjoKKyAgICAgIFdyaXRlTWVzc2FnZU5vVmlydHVhbFRvQXJyYXkoCisgICAgICAgIDIsIHRoaXMtPm1ldGhvZHMoaSksIHRhcmdldCk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLk9wdGlvbiBvcHRpb25zID0gMzsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT5vcHRpb25zX3NpemUoKTsgaSA8IG47IGkrKykgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjoKKyAgICAgIFdyaXRlTWVzc2FnZU5vVmlydHVhbFRvQXJyYXkoCisgICAgICAgIDMsIHRoaXMtPm9wdGlvbnMoaSksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgdmVyc2lvbiA9IDQ7CisgIGlmICh0aGlzLT52ZXJzaW9uKCkuc2l6ZSgpID4gMCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpWZXJpZnlVdGY4U3RyaW5nKAorICAgICAgdGhpcy0+dmVyc2lvbigpLmRhdGEoKSwgdGhpcy0+dmVyc2lvbigpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuQXBpLnZlcnNpb24iKTsKKyAgICB0YXJnZXQgPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nVG9BcnJheSgKKyAgICAgICAgNCwgdGhpcy0+dmVyc2lvbigpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0IHNvdXJjZV9jb250ZXh0ID0gNTsKKyAgaWYgKHRoaXMtPmhhc19zb3VyY2VfY29udGV4dCgpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OgorICAgICAgV3JpdGVNZXNzYWdlTm9WaXJ0dWFsVG9BcnJheSgKKyAgICAgICAgNSwgKnRoaXMtPnNvdXJjZV9jb250ZXh0XywgdGFyZ2V0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuTWl4aW4gbWl4aW5zID0gNjsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT5taXhpbnNfc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OgorICAgICAgV3JpdGVNZXNzYWdlTm9WaXJ0dWFsVG9BcnJheSgKKyAgICAgICAgNiwgdGhpcy0+bWl4aW5zKGkpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5TeW50YXggc3ludGF4ID0gNzsKKyAgaWYgKHRoaXMtPnN5bnRheCgpICE9IDApIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVFbnVtVG9BcnJheSgKKyAgICAgIDcsIHRoaXMtPnN5bnRheCgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9lbmQ6Z29vZ2xlLnByb3RvYnVmLkFwaSkKKyAgcmV0dXJuIHRhcmdldDsKK30KKworaW50IEFwaTo6Qnl0ZVNpemUoKSBjb25zdCB7CisgIGludCB0b3RhbF9zaXplID0gMDsKKworICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgIGlmICh0aGlzLT5uYW1lKCkuc2l6ZSgpID4gMCkgeworICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U3RyaW5nU2l6ZSgKKyAgICAgICAgdGhpcy0+bmFtZSgpKTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIHN0cmluZyB2ZXJzaW9uID0gNDsKKyAgaWYgKHRoaXMtPnZlcnNpb24oKS5zaXplKCkgPiAwKSB7CisgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTdHJpbmdTaXplKAorICAgICAgICB0aGlzLT52ZXJzaW9uKCkpOworICB9CisKKyAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0IHNvdXJjZV9jb250ZXh0ID0gNTsKKyAgaWYgKHRoaXMtPmhhc19zb3VyY2VfY29udGV4dCgpKSB7CisgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpNZXNzYWdlU2l6ZU5vVmlydHVhbCgKKyAgICAgICAgKnRoaXMtPnNvdXJjZV9jb250ZXh0Xyk7CisgIH0KKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLlN5bnRheCBzeW50YXggPSA3OworICBpZiAodGhpcy0+c3ludGF4KCkgIT0gMCkgeworICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6RW51bVNpemUodGhpcy0+c3ludGF4KCkpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5NZXRob2QgbWV0aG9kcyA9IDI7CisgIHRvdGFsX3NpemUgKz0gMSAqIHRoaXMtPm1ldGhvZHNfc2l6ZSgpOworICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPm1ldGhvZHNfc2l6ZSgpOyBpKyspIHsKKyAgICB0b3RhbF9zaXplICs9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6TWVzc2FnZVNpemVOb1ZpcnR1YWwoCisgICAgICAgIHRoaXMtPm1ldGhvZHMoaSkpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5PcHRpb24gb3B0aW9ucyA9IDM7CisgIHRvdGFsX3NpemUgKz0gMSAqIHRoaXMtPm9wdGlvbnNfc2l6ZSgpOworICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPm9wdGlvbnNfc2l6ZSgpOyBpKyspIHsKKyAgICB0b3RhbF9zaXplICs9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6TWVzc2FnZVNpemVOb1ZpcnR1YWwoCisgICAgICAgIHRoaXMtPm9wdGlvbnMoaSkpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5NaXhpbiBtaXhpbnMgPSA2OworICB0b3RhbF9zaXplICs9IDEgKiB0aGlzLT5taXhpbnNfc2l6ZSgpOworICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPm1peGluc19zaXplKCk7IGkrKykgeworICAgIHRvdGFsX3NpemUgKz0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpNZXNzYWdlU2l6ZU5vVmlydHVhbCgKKyAgICAgICAgdGhpcy0+bWl4aW5zKGkpKTsKKyAgfQorCisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSB0b3RhbF9zaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKKyAgcmV0dXJuIHRvdGFsX3NpemU7Cit9CisKK3ZvaWQgQXBpOjpNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGNvbnN0IEFwaSogc291cmNlID0gCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpEeW5hbWljQ2FzdFRvR2VuZXJhdGVkPGNvbnN0IEFwaT4oCisgICAgICAgICAgJmZyb20pOworICBpZiAoc291cmNlID09IE5VTEwpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpSZWZsZWN0aW9uT3BzOjpNZXJnZShmcm9tLCB0aGlzKTsKKyAgfSBlbHNlIHsKKyAgICBNZXJnZUZyb20oKnNvdXJjZSk7CisgIH0KK30KKwordm9pZCBBcGk6Ok1lcmdlRnJvbShjb25zdCBBcGkmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgbWV0aG9kc18uTWVyZ2VGcm9tKGZyb20ubWV0aG9kc18pOworICBvcHRpb25zXy5NZXJnZUZyb20oZnJvbS5vcHRpb25zXyk7CisgIG1peGluc18uTWVyZ2VGcm9tKGZyb20ubWl4aW5zXyk7CisgIGlmIChmcm9tLm5hbWUoKS5zaXplKCkgPiAwKSB7CisKKyAgICBuYW1lXy5Bc3NpZ25XaXRoRGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGZyb20ubmFtZV8pOworICB9CisgIGlmIChmcm9tLnZlcnNpb24oKS5zaXplKCkgPiAwKSB7CisKKyAgICB2ZXJzaW9uXy5Bc3NpZ25XaXRoRGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGZyb20udmVyc2lvbl8pOworICB9CisgIGlmIChmcm9tLmhhc19zb3VyY2VfY29udGV4dCgpKSB7CisgICAgbXV0YWJsZV9zb3VyY2VfY29udGV4dCgpLT46Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvbnRleHQ6Ok1lcmdlRnJvbShmcm9tLnNvdXJjZV9jb250ZXh0KCkpOworICB9CisgIGlmIChmcm9tLnN5bnRheCgpICE9IDApIHsKKyAgICBzZXRfc3ludGF4KGZyb20uc3ludGF4KCkpOworICB9Cit9CisKK3ZvaWQgQXBpOjpDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCit2b2lkIEFwaTo6Q29weUZyb20oY29uc3QgQXBpJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKworYm9vbCBBcGk6OklzSW5pdGlhbGl6ZWQoKSBjb25zdCB7CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgQXBpOjpTd2FwKEFwaSogb3RoZXIpIHsKKyAgaWYgKG90aGVyID09IHRoaXMpIHJldHVybjsKKyAgSW50ZXJuYWxTd2FwKG90aGVyKTsKK30KK3ZvaWQgQXBpOjpJbnRlcm5hbFN3YXAoQXBpKiBvdGhlcikgeworICBuYW1lXy5Td2FwKCZvdGhlci0+bmFtZV8pOworICBtZXRob2RzXy5VbnNhZmVBcmVuYVN3YXAoJm90aGVyLT5tZXRob2RzXyk7CisgIG9wdGlvbnNfLlVuc2FmZUFyZW5hU3dhcCgmb3RoZXItPm9wdGlvbnNfKTsKKyAgdmVyc2lvbl8uU3dhcCgmb3RoZXItPnZlcnNpb25fKTsKKyAgc3RkOjpzd2FwKHNvdXJjZV9jb250ZXh0Xywgb3RoZXItPnNvdXJjZV9jb250ZXh0Xyk7CisgIG1peGluc18uVW5zYWZlQXJlbmFTd2FwKCZvdGhlci0+bWl4aW5zXyk7CisgIHN0ZDo6c3dhcChzeW50YXhfLCBvdGhlci0+c3ludGF4Xyk7CisgIF9pbnRlcm5hbF9tZXRhZGF0YV8uU3dhcCgmb3RoZXItPl9pbnRlcm5hbF9tZXRhZGF0YV8pOworICBzdGQ6OnN3YXAoX2NhY2hlZF9zaXplXywgb3RoZXItPl9jYWNoZWRfc2l6ZV8pOworfQorCis6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEFwaTo6R2V0TWV0YWRhdGEoKSBjb25zdCB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIG1ldGFkYXRhOworICBtZXRhZGF0YS5kZXNjcmlwdG9yID0gQXBpX2Rlc2NyaXB0b3JfOworICBtZXRhZGF0YS5yZWZsZWN0aW9uID0gQXBpX3JlZmxlY3Rpb25fOworICByZXR1cm4gbWV0YWRhdGE7Cit9CisKKyNpZiBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKy8vIEFwaQorCisvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7Cit2b2lkIEFwaTo6Y2xlYXJfbmFtZSgpIHsKKyAgbmFtZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEFwaTo6bmFtZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuQXBpLm5hbWUpCisgIHJldHVybiBuYW1lXy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBBcGk6OnNldF9uYW1lKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIAorICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5BcGkubmFtZSkKK30KKyB2b2lkIEFwaTo6c2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgCisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuQXBpLm5hbWUpCit9Cisgdm9pZCBBcGk6OnNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICAKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLkFwaS5uYW1lKQorfQorIDo6c3RkOjpzdHJpbmcqIEFwaTo6bXV0YWJsZV9uYW1lKCkgeworICAKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkFwaS5uYW1lKQorICByZXR1cm4gbmFtZV8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyA6OnN0ZDo6c3RyaW5nKiBBcGk6OnJlbGVhc2VfbmFtZSgpIHsKKyAgCisgIHJldHVybiBuYW1lXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgQXBpOjpzZXRfYWxsb2NhdGVkX25hbWUoOjpzdGQ6OnN0cmluZyogbmFtZSkgeworICBpZiAobmFtZSAhPSBOVUxMKSB7CisgICAgCisgIH0gZWxzZSB7CisgICAgCisgIH0KKyAgbmFtZV8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIG5hbWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuQXBpLm5hbWUpCit9CisKKy8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuTWV0aG9kIG1ldGhvZHMgPSAyOworaW50IEFwaTo6bWV0aG9kc19zaXplKCkgY29uc3QgeworICByZXR1cm4gbWV0aG9kc18uc2l6ZSgpOworfQordm9pZCBBcGk6OmNsZWFyX21ldGhvZHMoKSB7CisgIG1ldGhvZHNfLkNsZWFyKCk7Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGhvZCYgQXBpOjptZXRob2RzKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5BcGkubWV0aG9kcykKKyAgcmV0dXJuIG1ldGhvZHNfLkdldChpbmRleCk7Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGhvZCogQXBpOjptdXRhYmxlX21ldGhvZHMoaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5BcGkubWV0aG9kcykKKyAgcmV0dXJuIG1ldGhvZHNfLk11dGFibGUoaW5kZXgpOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpNZXRob2QqIEFwaTo6YWRkX21ldGhvZHMoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLkFwaS5tZXRob2RzKQorICByZXR1cm4gbWV0aG9kc18uQWRkKCk7Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0aG9kID4qCitBcGk6Om11dGFibGVfbWV0aG9kcygpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuQXBpLm1ldGhvZHMpCisgIHJldHVybiAmbWV0aG9kc187Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0aG9kID4mCitBcGk6Om1ldGhvZHMoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5BcGkubWV0aG9kcykKKyAgcmV0dXJuIG1ldGhvZHNfOworfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLk9wdGlvbiBvcHRpb25zID0gMzsKK2ludCBBcGk6Om9wdGlvbnNfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIG9wdGlvbnNfLnNpemUoKTsKK30KK3ZvaWQgQXBpOjpjbGVhcl9vcHRpb25zKCkgeworICBvcHRpb25zXy5DbGVhcigpOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpPcHRpb24mIEFwaTo6b3B0aW9ucyhpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuQXBpLm9wdGlvbnMpCisgIHJldHVybiBvcHRpb25zXy5HZXQoaW5kZXgpOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpPcHRpb24qIEFwaTo6bXV0YWJsZV9vcHRpb25zKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuQXBpLm9wdGlvbnMpCisgIHJldHVybiBvcHRpb25zXy5NdXRhYmxlKGluZGV4KTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6T3B0aW9uKiBBcGk6OmFkZF9vcHRpb25zKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5BcGkub3B0aW9ucykKKyAgcmV0dXJuIG9wdGlvbnNfLkFkZCgpOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbiA+KgorQXBpOjptdXRhYmxlX29wdGlvbnMoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkFwaS5vcHRpb25zKQorICByZXR1cm4gJm9wdGlvbnNfOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbiA+JgorQXBpOjpvcHRpb25zKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuQXBpLm9wdGlvbnMpCisgIHJldHVybiBvcHRpb25zXzsKK30KKworLy8gb3B0aW9uYWwgc3RyaW5nIHZlcnNpb24gPSA0Owordm9pZCBBcGk6OmNsZWFyX3ZlcnNpb24oKSB7CisgIHZlcnNpb25fLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyBjb25zdCA6OnN0ZDo6c3RyaW5nJiBBcGk6OnZlcnNpb24oKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkFwaS52ZXJzaW9uKQorICByZXR1cm4gdmVyc2lvbl8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgQXBpOjpzZXRfdmVyc2lvbihjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICAKKyAgdmVyc2lvbl8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuQXBpLnZlcnNpb24pCit9Cisgdm9pZCBBcGk6OnNldF92ZXJzaW9uKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIAorICB2ZXJzaW9uXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLkFwaS52ZXJzaW9uKQorfQorIHZvaWQgQXBpOjpzZXRfdmVyc2lvbihjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgCisgIHZlcnNpb25fLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5BcGkudmVyc2lvbikKK30KKyA6OnN0ZDo6c3RyaW5nKiBBcGk6Om11dGFibGVfdmVyc2lvbigpIHsKKyAgCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5BcGkudmVyc2lvbikKKyAgcmV0dXJuIHZlcnNpb25fLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CisgOjpzdGQ6OnN0cmluZyogQXBpOjpyZWxlYXNlX3ZlcnNpb24oKSB7CisgIAorICByZXR1cm4gdmVyc2lvbl8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIEFwaTo6c2V0X2FsbG9jYXRlZF92ZXJzaW9uKDo6c3RkOjpzdHJpbmcqIHZlcnNpb24pIHsKKyAgaWYgKHZlcnNpb24gIT0gTlVMTCkgeworICAgIAorICB9IGVsc2UgeworICAgIAorICB9CisgIHZlcnNpb25fLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2ZXJzaW9uKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkFwaS52ZXJzaW9uKQorfQorCisvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQgc291cmNlX2NvbnRleHQgPSA1OworYm9vbCBBcGk6Omhhc19zb3VyY2VfY29udGV4dCgpIGNvbnN0IHsKKyAgcmV0dXJuICFfaXNfZGVmYXVsdF9pbnN0YW5jZV8gJiYgc291cmNlX2NvbnRleHRfICE9IE5VTEw7Cit9Cit2b2lkIEFwaTo6Y2xlYXJfc291cmNlX2NvbnRleHQoKSB7CisgIGlmIChHZXRBcmVuYU5vVmlydHVhbCgpID09IE5VTEwgJiYgc291cmNlX2NvbnRleHRfICE9IE5VTEwpIGRlbGV0ZSBzb3VyY2VfY29udGV4dF87CisgIHNvdXJjZV9jb250ZXh0XyA9IE5VTEw7Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvbnRleHQmIEFwaTo6c291cmNlX2NvbnRleHQoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkFwaS5zb3VyY2VfY29udGV4dCkKKyAgcmV0dXJuIHNvdXJjZV9jb250ZXh0XyAhPSBOVUxMID8gKnNvdXJjZV9jb250ZXh0XyA6ICpkZWZhdWx0X2luc3RhbmNlXy0+c291cmNlX2NvbnRleHRfOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb250ZXh0KiBBcGk6Om11dGFibGVfc291cmNlX2NvbnRleHQoKSB7CisgIAorICBpZiAoc291cmNlX2NvbnRleHRfID09IE5VTEwpIHsKKyAgICBzb3VyY2VfY29udGV4dF8gPSBuZXcgOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb250ZXh0OworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5BcGkuc291cmNlX2NvbnRleHQpCisgIHJldHVybiBzb3VyY2VfY29udGV4dF87Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvbnRleHQqIEFwaTo6cmVsZWFzZV9zb3VyY2VfY29udGV4dCgpIHsKKyAgCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29udGV4dCogdGVtcCA9IHNvdXJjZV9jb250ZXh0XzsKKyAgc291cmNlX2NvbnRleHRfID0gTlVMTDsKKyAgcmV0dXJuIHRlbXA7Cit9Cit2b2lkIEFwaTo6c2V0X2FsbG9jYXRlZF9zb3VyY2VfY29udGV4dCg6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvbnRleHQqIHNvdXJjZV9jb250ZXh0KSB7CisgIGRlbGV0ZSBzb3VyY2VfY29udGV4dF87CisgIHNvdXJjZV9jb250ZXh0XyA9IHNvdXJjZV9jb250ZXh0OworICBpZiAoc291cmNlX2NvbnRleHQpIHsKKyAgICAKKyAgfSBlbHNlIHsKKyAgICAKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuQXBpLnNvdXJjZV9jb250ZXh0KQorfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLk1peGluIG1peGlucyA9IDY7CitpbnQgQXBpOjptaXhpbnNfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIG1peGluc18uc2l6ZSgpOworfQordm9pZCBBcGk6OmNsZWFyX21peGlucygpIHsKKyAgbWl4aW5zXy5DbGVhcigpOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNaXhpbiYgQXBpOjptaXhpbnMoaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkFwaS5taXhpbnMpCisgIHJldHVybiBtaXhpbnNfLkdldChpbmRleCk7Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6Ok1peGluKiBBcGk6Om11dGFibGVfbWl4aW5zKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuQXBpLm1peGlucykKKyAgcmV0dXJuIG1peGluc18uTXV0YWJsZShpbmRleCk7Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6Ok1peGluKiBBcGk6OmFkZF9taXhpbnMoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLkFwaS5taXhpbnMpCisgIHJldHVybiBtaXhpbnNfLkFkZCgpOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1peGluID4qCitBcGk6Om11dGFibGVfbWl4aW5zKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5BcGkubWl4aW5zKQorICByZXR1cm4gJm1peGluc187Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWl4aW4gPiYKK0FwaTo6bWl4aW5zKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuQXBpLm1peGlucykKKyAgcmV0dXJuIG1peGluc187Cit9CisKKy8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuU3ludGF4IHN5bnRheCA9IDc7Cit2b2lkIEFwaTo6Y2xlYXJfc3ludGF4KCkgeworICBzeW50YXhfID0gMDsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OlN5bnRheCBBcGk6OnN5bnRheCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuQXBpLnN5bnRheCkKKyAgcmV0dXJuIHN0YXRpY19jYXN0PCA6Omdvb2dsZTo6cHJvdG9idWY6OlN5bnRheCA+KHN5bnRheF8pOworfQorIHZvaWQgQXBpOjpzZXRfc3ludGF4KDo6Z29vZ2xlOjpwcm90b2J1Zjo6U3ludGF4IHZhbHVlKSB7CisgIAorICBzeW50YXhfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkFwaS5zeW50YXgpCit9CisKKyNlbmRpZiAgLy8gUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworI2lmICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCitjb25zdCBpbnQgTWV0aG9kOjprTmFtZUZpZWxkTnVtYmVyOworY29uc3QgaW50IE1ldGhvZDo6a1JlcXVlc3RUeXBlVXJsRmllbGROdW1iZXI7Citjb25zdCBpbnQgTWV0aG9kOjprUmVxdWVzdFN0cmVhbWluZ0ZpZWxkTnVtYmVyOworY29uc3QgaW50IE1ldGhvZDo6a1Jlc3BvbnNlVHlwZVVybEZpZWxkTnVtYmVyOworY29uc3QgaW50IE1ldGhvZDo6a1Jlc3BvbnNlU3RyZWFtaW5nRmllbGROdW1iZXI7Citjb25zdCBpbnQgTWV0aG9kOjprT3B0aW9uc0ZpZWxkTnVtYmVyOworY29uc3QgaW50IE1ldGhvZDo6a1N5bnRheEZpZWxkTnVtYmVyOworI2VuZGlmICAvLyAhZGVmaW5lZChfTVNDX1ZFUikgfHwgX01TQ19WRVIgPj0gMTkwMAorCitNZXRob2Q6Ok1ldGhvZCgpCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgeworICBTaGFyZWRDdG9yKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuTWV0aG9kKQorfQorCit2b2lkIE1ldGhvZDo6SW5pdEFzRGVmYXVsdEluc3RhbmNlKCkgeworICBfaXNfZGVmYXVsdF9pbnN0YW5jZV8gPSB0cnVlOworfQorCitNZXRob2Q6Ok1ldGhvZChjb25zdCBNZXRob2QmIGZyb20pCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksCisgICAgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29weV9jb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuTWV0aG9kKQorfQorCit2b2lkIE1ldGhvZDo6U2hhcmVkQ3RvcigpIHsKKyAgICBfaXNfZGVmYXVsdF9pbnN0YW5jZV8gPSBmYWxzZTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmcoKTsKKyAgX2NhY2hlZF9zaXplXyA9IDA7CisgIG5hbWVfLlVuc2FmZVNldERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgcmVxdWVzdF90eXBlX3VybF8uVW5zYWZlU2V0RGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICByZXF1ZXN0X3N0cmVhbWluZ18gPSBmYWxzZTsKKyAgcmVzcG9uc2VfdHlwZV91cmxfLlVuc2FmZVNldERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgcmVzcG9uc2Vfc3RyZWFtaW5nXyA9IGZhbHNlOworICBzeW50YXhfID0gMDsKK30KKworTWV0aG9kOjp+TWV0aG9kKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZGVzdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuTWV0aG9kKQorICBTaGFyZWREdG9yKCk7Cit9CisKK3ZvaWQgTWV0aG9kOjpTaGFyZWREdG9yKCkgeworICBuYW1lXy5EZXN0cm95Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICByZXF1ZXN0X3R5cGVfdXJsXy5EZXN0cm95Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICByZXNwb25zZV90eXBlX3VybF8uRGVzdHJveU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgaWYgKHRoaXMgIT0gZGVmYXVsdF9pbnN0YW5jZV8pIHsKKyAgfQorfQorCit2b2lkIE1ldGhvZDo6U2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3QgeworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIE1ldGhvZDo6ZGVzY3JpcHRvcigpIHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIHJldHVybiBNZXRob2RfZGVzY3JpcHRvcl87Cit9CisKK2NvbnN0IE1ldGhvZCYgTWV0aG9kOjpkZWZhdWx0X2luc3RhbmNlKCkgeworICBpZiAoZGVmYXVsdF9pbnN0YW5jZV8gPT0gTlVMTCkgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmFwaV8yZXByb3RvKCk7CisgIHJldHVybiAqZGVmYXVsdF9pbnN0YW5jZV87Cit9CisKK01ldGhvZCogTWV0aG9kOjpkZWZhdWx0X2luc3RhbmNlXyA9IE5VTEw7CisKK01ldGhvZCogTWV0aG9kOjpOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0IHsKKyAgTWV0aG9kKiBuID0gbmV3IE1ldGhvZDsKKyAgaWYgKGFyZW5hICE9IE5VTEwpIHsKKyAgICBhcmVuYS0+T3duKG4pOworICB9CisgIHJldHVybiBuOworfQorCit2b2lkIE1ldGhvZDo6Q2xlYXIoKSB7CisjZGVmaW5lIFpSX0hFTFBFUl8oZikgcmVpbnRlcnByZXRfY2FzdDxjaGFyKj4oXAorICAmcmVpbnRlcnByZXRfY2FzdDxNZXRob2QqPigxNiktPmYpCisKKyNkZWZpbmUgWlJfKGZpcnN0LCBsYXN0KSBkbyB7XAorICA6Om1lbXNldCgmZmlyc3QsIDAsXAorICAgICAgICAgICBaUl9IRUxQRVJfKGxhc3QpIC0gWlJfSEVMUEVSXyhmaXJzdCkgKyBzaXplb2YobGFzdCkpO1wKK30gd2hpbGUgKDApCisKKyAgWlJfKHJlcXVlc3Rfc3RyZWFtaW5nXywgc3ludGF4Xyk7CisgIG5hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgcmVxdWVzdF90eXBlX3VybF8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICByZXNwb25zZV90eXBlX3VybF8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworCisjdW5kZWYgWlJfSEVMUEVSXworI3VuZGVmIFpSXworCisgIG9wdGlvbnNfLkNsZWFyKCk7Cit9CisKK2Jvb2wgTWV0aG9kOjpNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyNkZWZpbmUgRE9fKEVYUFJFU1NJT04pIGlmICghKEVYUFJFU1NJT04pKSBnb3RvIGZhaWx1cmUKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgdGFnOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZCkKKyAgZm9yICg7OykgeworICAgIDo6c3RkOjpwYWlyPCA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiwgYm9vbD4gcCA9IGlucHV0LT5SZWFkVGFnV2l0aEN1dG9mZigxMjcpOworICAgIHRhZyA9IHAuZmlyc3Q7CisgICAgaWYgKCFwLnNlY29uZCkgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICBzd2l0Y2ggKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdGaWVsZE51bWJlcih0YWcpKSB7CisgICAgICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgICAgICBjYXNlIDE6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAxMCkgeworICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFN0cmluZygKKyAgICAgICAgICAgICAgICBpbnB1dCwgdGhpcy0+bXV0YWJsZV9uYW1lKCkpKTsKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlZlcmlmeVV0ZjhTdHJpbmcoCisgICAgICAgICAgICB0aGlzLT5uYW1lKCkuZGF0YSgpLCB0aGlzLT5uYW1lKCkubGVuZ3RoKCksCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UEFSU0UsCisgICAgICAgICAgICAiZ29vZ2xlLnByb3RvYnVmLk1ldGhvZC5uYW1lIikpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMTgpKSBnb3RvIHBhcnNlX3JlcXVlc3RfdHlwZV91cmw7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCBzdHJpbmcgcmVxdWVzdF90eXBlX3VybCA9IDI7CisgICAgICBjYXNlIDI6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAxOCkgeworICAgICAgICAgcGFyc2VfcmVxdWVzdF90eXBlX3VybDoKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoCisgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPm11dGFibGVfcmVxdWVzdF90eXBlX3VybCgpKSk7CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpWZXJpZnlVdGY4U3RyaW5nKAorICAgICAgICAgICAgdGhpcy0+cmVxdWVzdF90eXBlX3VybCgpLmRhdGEoKSwgdGhpcy0+cmVxdWVzdF90eXBlX3VybCgpLmxlbmd0aCgpLAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlBBUlNFLAorICAgICAgICAgICAgImdvb2dsZS5wcm90b2J1Zi5NZXRob2QucmVxdWVzdF90eXBlX3VybCIpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDI0KSkgZ290byBwYXJzZV9yZXF1ZXN0X3N0cmVhbWluZzsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIGJvb2wgcmVxdWVzdF9zdHJlYW1pbmcgPSAzOworICAgICAgY2FzZSAzOiB7CisgICAgICAgIGlmICh0YWcgPT0gMjQpIHsKKyAgICAgICAgIHBhcnNlX3JlcXVlc3Rfc3RyZWFtaW5nOgorICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgYm9vbCwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfQk9PTD4oCisgICAgICAgICAgICAgICAgIGlucHV0LCAmcmVxdWVzdF9zdHJlYW1pbmdfKSkpOworCisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygzNCkpIGdvdG8gcGFyc2VfcmVzcG9uc2VfdHlwZV91cmw7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCBzdHJpbmcgcmVzcG9uc2VfdHlwZV91cmwgPSA0OworICAgICAgY2FzZSA0OiB7CisgICAgICAgIGlmICh0YWcgPT0gMzQpIHsKKyAgICAgICAgIHBhcnNlX3Jlc3BvbnNlX3R5cGVfdXJsOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFN0cmluZygKKyAgICAgICAgICAgICAgICBpbnB1dCwgdGhpcy0+bXV0YWJsZV9yZXNwb25zZV90eXBlX3VybCgpKSk7CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpWZXJpZnlVdGY4U3RyaW5nKAorICAgICAgICAgICAgdGhpcy0+cmVzcG9uc2VfdHlwZV91cmwoKS5kYXRhKCksIHRoaXMtPnJlc3BvbnNlX3R5cGVfdXJsKCkubGVuZ3RoKCksCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UEFSU0UsCisgICAgICAgICAgICAiZ29vZ2xlLnByb3RvYnVmLk1ldGhvZC5yZXNwb25zZV90eXBlX3VybCIpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDQwKSkgZ290byBwYXJzZV9yZXNwb25zZV9zdHJlYW1pbmc7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCBib29sIHJlc3BvbnNlX3N0cmVhbWluZyA9IDU7CisgICAgICBjYXNlIDU6IHsKKyAgICAgICAgaWYgKHRhZyA9PSA0MCkgeworICAgICAgICAgcGFyc2VfcmVzcG9uc2Vfc3RyZWFtaW5nOgorICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgYm9vbCwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfQk9PTD4oCisgICAgICAgICAgICAgICAgIGlucHV0LCAmcmVzcG9uc2Vfc3RyZWFtaW5nXykpKTsKKworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNTApKSBnb3RvIHBhcnNlX29wdGlvbnM7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLk9wdGlvbiBvcHRpb25zID0gNjsKKyAgICAgIGNhc2UgNjogeworICAgICAgICBpZiAodGFnID09IDUwKSB7CisgICAgICAgICBwYXJzZV9vcHRpb25zOgorICAgICAgICAgIERPXyhpbnB1dC0+SW5jcmVtZW50UmVjdXJzaW9uRGVwdGgoKSk7CisgICAgICAgICBwYXJzZV9sb29wX29wdGlvbnM6CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkTWVzc2FnZU5vVmlydHVhbE5vUmVjdXJzaW9uRGVwdGgoCisgICAgICAgICAgICAgICAgaW5wdXQsIGFkZF9vcHRpb25zKCkpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDUwKSkgZ290byBwYXJzZV9sb29wX29wdGlvbnM7CisgICAgICAgIGlucHV0LT5VbnNhZmVEZWNyZW1lbnRSZWN1cnNpb25EZXB0aCgpOworICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg1NikpIGdvdG8gcGFyc2Vfc3ludGF4OworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5TeW50YXggc3ludGF4ID0gNzsKKyAgICAgIGNhc2UgNzogeworICAgICAgICBpZiAodGFnID09IDU2KSB7CisgICAgICAgICBwYXJzZV9zeW50YXg6CisgICAgICAgICAgaW50IHZhbHVlOworICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgaW50LCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9FTlVNPigKKyAgICAgICAgICAgICAgICAgaW5wdXQsICZ2YWx1ZSkpKTsKKyAgICAgICAgICBzZXRfc3ludGF4KHN0YXRpY19jYXN0PCA6Omdvb2dsZTo6cHJvdG9idWY6OlN5bnRheCA+KHZhbHVlKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdEF0RW5kKCkpIGdvdG8gc3VjY2VzczsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGRlZmF1bHQ6IHsKKyAgICAgIGhhbmRsZV91bnVzdWFsOgorICAgICAgICBpZiAodGFnID09IDAgfHwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdXaXJlVHlwZSh0YWcpID09CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRU5EX0dST1VQKSB7CisgICAgICAgICAgZ290byBzdWNjZXNzOworICAgICAgICB9CisgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U2tpcEZpZWxkKGlucHV0LCB0YWcpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CitzdWNjZXNzOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3VjY2Vzczpnb29nbGUucHJvdG9idWYuTWV0aG9kKQorICByZXR1cm4gdHJ1ZTsKK2ZhaWx1cmU6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9mYWlsdXJlOmdvb2dsZS5wcm90b2J1Zi5NZXRob2QpCisgIHJldHVybiBmYWxzZTsKKyN1bmRlZiBET18KK30KKwordm9pZCBNZXRob2Q6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZCkKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICBpZiAodGhpcy0+bmFtZSgpLnNpemUoKSA+IDApIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VmVyaWZ5VXRmOFN0cmluZygKKyAgICAgIHRoaXMtPm5hbWUoKS5kYXRhKCksIHRoaXMtPm5hbWUoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLk1ldGhvZC5uYW1lIik7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nTWF5YmVBbGlhc2VkKAorICAgICAgMSwgdGhpcy0+bmFtZSgpLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIHJlcXVlc3RfdHlwZV91cmwgPSAyOworICBpZiAodGhpcy0+cmVxdWVzdF90eXBlX3VybCgpLnNpemUoKSA+IDApIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VmVyaWZ5VXRmOFN0cmluZygKKyAgICAgIHRoaXMtPnJlcXVlc3RfdHlwZV91cmwoKS5kYXRhKCksIHRoaXMtPnJlcXVlc3RfdHlwZV91cmwoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLk1ldGhvZC5yZXF1ZXN0X3R5cGVfdXJsIik7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nTWF5YmVBbGlhc2VkKAorICAgICAgMiwgdGhpcy0+cmVxdWVzdF90eXBlX3VybCgpLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgYm9vbCByZXF1ZXN0X3N0cmVhbWluZyA9IDM7CisgIGlmICh0aGlzLT5yZXF1ZXN0X3N0cmVhbWluZygpICE9IDApIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCb29sKDMsIHRoaXMtPnJlcXVlc3Rfc3RyZWFtaW5nKCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgcmVzcG9uc2VfdHlwZV91cmwgPSA0OworICBpZiAodGhpcy0+cmVzcG9uc2VfdHlwZV91cmwoKS5zaXplKCkgPiAwKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlZlcmlmeVV0ZjhTdHJpbmcoCisgICAgICB0aGlzLT5yZXNwb25zZV90eXBlX3VybCgpLmRhdGEoKSwgdGhpcy0+cmVzcG9uc2VfdHlwZV91cmwoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLk1ldGhvZC5yZXNwb25zZV90eXBlX3VybCIpOworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ01heWJlQWxpYXNlZCgKKyAgICAgIDQsIHRoaXMtPnJlc3BvbnNlX3R5cGVfdXJsKCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBib29sIHJlc3BvbnNlX3N0cmVhbWluZyA9IDU7CisgIGlmICh0aGlzLT5yZXNwb25zZV9zdHJlYW1pbmcoKSAhPSAwKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlQm9vbCg1LCB0aGlzLT5yZXNwb25zZV9zdHJlYW1pbmcoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuT3B0aW9uIG9wdGlvbnMgPSA2OworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPm9wdGlvbnNfc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlTWVzc2FnZU1heWJlVG9BcnJheSgKKyAgICAgIDYsIHRoaXMtPm9wdGlvbnMoaSksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLlN5bnRheCBzeW50YXggPSA3OworICBpZiAodGhpcy0+c3ludGF4KCkgIT0gMCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUVudW0oCisgICAgICA3LCB0aGlzLT5zeW50YXgoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfZW5kOmdvb2dsZS5wcm90b2J1Zi5NZXRob2QpCit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIE1ldGhvZDo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiB0YXJnZXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9zdGFydDpnb29nbGUucHJvdG9idWYuTWV0aG9kKQorICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgIGlmICh0aGlzLT5uYW1lKCkuc2l6ZSgpID4gMCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpWZXJpZnlVdGY4U3RyaW5nKAorICAgICAgdGhpcy0+bmFtZSgpLmRhdGEoKSwgdGhpcy0+bmFtZSgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuTWV0aG9kLm5hbWUiKTsKKyAgICB0YXJnZXQgPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nVG9BcnJheSgKKyAgICAgICAgMSwgdGhpcy0+bmFtZSgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIHJlcXVlc3RfdHlwZV91cmwgPSAyOworICBpZiAodGhpcy0+cmVxdWVzdF90eXBlX3VybCgpLnNpemUoKSA+IDApIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VmVyaWZ5VXRmOFN0cmluZygKKyAgICAgIHRoaXMtPnJlcXVlc3RfdHlwZV91cmwoKS5kYXRhKCksIHRoaXMtPnJlcXVlc3RfdHlwZV91cmwoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLk1ldGhvZC5yZXF1ZXN0X3R5cGVfdXJsIik7CisgICAgdGFyZ2V0ID0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ1RvQXJyYXkoCisgICAgICAgIDIsIHRoaXMtPnJlcXVlc3RfdHlwZV91cmwoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGJvb2wgcmVxdWVzdF9zdHJlYW1pbmcgPSAzOworICBpZiAodGhpcy0+cmVxdWVzdF9zdHJlYW1pbmcoKSAhPSAwKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlQm9vbFRvQXJyYXkoMywgdGhpcy0+cmVxdWVzdF9zdHJlYW1pbmcoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIHN0cmluZyByZXNwb25zZV90eXBlX3VybCA9IDQ7CisgIGlmICh0aGlzLT5yZXNwb25zZV90eXBlX3VybCgpLnNpemUoKSA+IDApIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VmVyaWZ5VXRmOFN0cmluZygKKyAgICAgIHRoaXMtPnJlc3BvbnNlX3R5cGVfdXJsKCkuZGF0YSgpLCB0aGlzLT5yZXNwb25zZV90eXBlX3VybCgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuTWV0aG9kLnJlc3BvbnNlX3R5cGVfdXJsIik7CisgICAgdGFyZ2V0ID0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ1RvQXJyYXkoCisgICAgICAgIDQsIHRoaXMtPnJlc3BvbnNlX3R5cGVfdXJsKCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBib29sIHJlc3BvbnNlX3N0cmVhbWluZyA9IDU7CisgIGlmICh0aGlzLT5yZXNwb25zZV9zdHJlYW1pbmcoKSAhPSAwKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlQm9vbFRvQXJyYXkoNSwgdGhpcy0+cmVzcG9uc2Vfc3RyZWFtaW5nKCksIHRhcmdldCk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLk9wdGlvbiBvcHRpb25zID0gNjsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT5vcHRpb25zX3NpemUoKTsgaSA8IG47IGkrKykgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjoKKyAgICAgIFdyaXRlTWVzc2FnZU5vVmlydHVhbFRvQXJyYXkoCisgICAgICAgIDYsIHRoaXMtPm9wdGlvbnMoaSksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLlN5bnRheCBzeW50YXggPSA3OworICBpZiAodGhpcy0+c3ludGF4KCkgIT0gMCkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUVudW1Ub0FycmF5KAorICAgICAgNywgdGhpcy0+c3ludGF4KCksIHRhcmdldCk7CisgIH0KKworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X2VuZDpnb29nbGUucHJvdG9idWYuTWV0aG9kKQorICByZXR1cm4gdGFyZ2V0OworfQorCitpbnQgTWV0aG9kOjpCeXRlU2l6ZSgpIGNvbnN0IHsKKyAgaW50IHRvdGFsX3NpemUgPSAwOworCisgIC8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKKyAgaWYgKHRoaXMtPm5hbWUoKS5zaXplKCkgPiAwKSB7CisgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTdHJpbmdTaXplKAorICAgICAgICB0aGlzLT5uYW1lKCkpOworICB9CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIHJlcXVlc3RfdHlwZV91cmwgPSAyOworICBpZiAodGhpcy0+cmVxdWVzdF90eXBlX3VybCgpLnNpemUoKSA+IDApIHsKKyAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlN0cmluZ1NpemUoCisgICAgICAgIHRoaXMtPnJlcXVlc3RfdHlwZV91cmwoKSk7CisgIH0KKworICAvLyBvcHRpb25hbCBib29sIHJlcXVlc3Rfc3RyZWFtaW5nID0gMzsKKyAgaWYgKHRoaXMtPnJlcXVlc3Rfc3RyZWFtaW5nKCkgIT0gMCkgeworICAgIHRvdGFsX3NpemUgKz0gMSArIDE7CisgIH0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgcmVzcG9uc2VfdHlwZV91cmwgPSA0OworICBpZiAodGhpcy0+cmVzcG9uc2VfdHlwZV91cmwoKS5zaXplKCkgPiAwKSB7CisgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTdHJpbmdTaXplKAorICAgICAgICB0aGlzLT5yZXNwb25zZV90eXBlX3VybCgpKTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGJvb2wgcmVzcG9uc2Vfc3RyZWFtaW5nID0gNTsKKyAgaWYgKHRoaXMtPnJlc3BvbnNlX3N0cmVhbWluZygpICE9IDApIHsKKyAgICB0b3RhbF9zaXplICs9IDEgKyAxOworICB9CisKKyAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5TeW50YXggc3ludGF4ID0gNzsKKyAgaWYgKHRoaXMtPnN5bnRheCgpICE9IDApIHsKKyAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkVudW1TaXplKHRoaXMtPnN5bnRheCgpKTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuT3B0aW9uIG9wdGlvbnMgPSA2OworICB0b3RhbF9zaXplICs9IDEgKiB0aGlzLT5vcHRpb25zX3NpemUoKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT5vcHRpb25zX3NpemUoKTsgaSsrKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1lc3NhZ2VTaXplTm9WaXJ0dWFsKAorICAgICAgICB0aGlzLT5vcHRpb25zKGkpKTsKKyAgfQorCisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSB0b3RhbF9zaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKKyAgcmV0dXJuIHRvdGFsX3NpemU7Cit9CisKK3ZvaWQgTWV0aG9kOjpNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGNvbnN0IE1ldGhvZCogc291cmNlID0gCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpEeW5hbWljQ2FzdFRvR2VuZXJhdGVkPGNvbnN0IE1ldGhvZD4oCisgICAgICAgICAgJmZyb20pOworICBpZiAoc291cmNlID09IE5VTEwpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpSZWZsZWN0aW9uT3BzOjpNZXJnZShmcm9tLCB0aGlzKTsKKyAgfSBlbHNlIHsKKyAgICBNZXJnZUZyb20oKnNvdXJjZSk7CisgIH0KK30KKwordm9pZCBNZXRob2Q6Ok1lcmdlRnJvbShjb25zdCBNZXRob2QmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgb3B0aW9uc18uTWVyZ2VGcm9tKGZyb20ub3B0aW9uc18pOworICBpZiAoZnJvbS5uYW1lKCkuc2l6ZSgpID4gMCkgeworCisgICAgbmFtZV8uQXNzaWduV2l0aERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBmcm9tLm5hbWVfKTsKKyAgfQorICBpZiAoZnJvbS5yZXF1ZXN0X3R5cGVfdXJsKCkuc2l6ZSgpID4gMCkgeworCisgICAgcmVxdWVzdF90eXBlX3VybF8uQXNzaWduV2l0aERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBmcm9tLnJlcXVlc3RfdHlwZV91cmxfKTsKKyAgfQorICBpZiAoZnJvbS5yZXF1ZXN0X3N0cmVhbWluZygpICE9IDApIHsKKyAgICBzZXRfcmVxdWVzdF9zdHJlYW1pbmcoZnJvbS5yZXF1ZXN0X3N0cmVhbWluZygpKTsKKyAgfQorICBpZiAoZnJvbS5yZXNwb25zZV90eXBlX3VybCgpLnNpemUoKSA+IDApIHsKKworICAgIHJlc3BvbnNlX3R5cGVfdXJsXy5Bc3NpZ25XaXRoRGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGZyb20ucmVzcG9uc2VfdHlwZV91cmxfKTsKKyAgfQorICBpZiAoZnJvbS5yZXNwb25zZV9zdHJlYW1pbmcoKSAhPSAwKSB7CisgICAgc2V0X3Jlc3BvbnNlX3N0cmVhbWluZyhmcm9tLnJlc3BvbnNlX3N0cmVhbWluZygpKTsKKyAgfQorICBpZiAoZnJvbS5zeW50YXgoKSAhPSAwKSB7CisgICAgc2V0X3N5bnRheChmcm9tLnN5bnRheCgpKTsKKyAgfQorfQorCit2b2lkIE1ldGhvZDo6Q29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKwordm9pZCBNZXRob2Q6OkNvcHlGcm9tKGNvbnN0IE1ldGhvZCYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK2Jvb2wgTWV0aG9kOjpJc0luaXRpYWxpemVkKCkgY29uc3QgeworCisgIHJldHVybiB0cnVlOworfQorCit2b2lkIE1ldGhvZDo6U3dhcChNZXRob2QqIG90aGVyKSB7CisgIGlmIChvdGhlciA9PSB0aGlzKSByZXR1cm47CisgIEludGVybmFsU3dhcChvdGhlcik7Cit9Cit2b2lkIE1ldGhvZDo6SW50ZXJuYWxTd2FwKE1ldGhvZCogb3RoZXIpIHsKKyAgbmFtZV8uU3dhcCgmb3RoZXItPm5hbWVfKTsKKyAgcmVxdWVzdF90eXBlX3VybF8uU3dhcCgmb3RoZXItPnJlcXVlc3RfdHlwZV91cmxfKTsKKyAgc3RkOjpzd2FwKHJlcXVlc3Rfc3RyZWFtaW5nXywgb3RoZXItPnJlcXVlc3Rfc3RyZWFtaW5nXyk7CisgIHJlc3BvbnNlX3R5cGVfdXJsXy5Td2FwKCZvdGhlci0+cmVzcG9uc2VfdHlwZV91cmxfKTsKKyAgc3RkOjpzd2FwKHJlc3BvbnNlX3N0cmVhbWluZ18sIG90aGVyLT5yZXNwb25zZV9zdHJlYW1pbmdfKTsKKyAgb3B0aW9uc18uVW5zYWZlQXJlbmFTd2FwKCZvdGhlci0+b3B0aW9uc18pOworICBzdGQ6OnN3YXAoc3ludGF4Xywgb3RoZXItPnN5bnRheF8pOworICBfaW50ZXJuYWxfbWV0YWRhdGFfLlN3YXAoJm90aGVyLT5faW50ZXJuYWxfbWV0YWRhdGFfKTsKKyAgc3RkOjpzd2FwKF9jYWNoZWRfc2l6ZV8sIG90aGVyLT5fY2FjaGVkX3NpemVfKTsKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBNZXRob2Q6OkdldE1ldGFkYXRhKCkgY29uc3QgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBtZXRhZGF0YTsKKyAgbWV0YWRhdGEuZGVzY3JpcHRvciA9IE1ldGhvZF9kZXNjcmlwdG9yXzsKKyAgbWV0YWRhdGEucmVmbGVjdGlvbiA9IE1ldGhvZF9yZWZsZWN0aW9uXzsKKyAgcmV0dXJuIG1ldGFkYXRhOworfQorCisjaWYgUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisvLyBNZXRob2QKKworLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOwordm9pZCBNZXRob2Q6OmNsZWFyX25hbWUoKSB7CisgIG5hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyBjb25zdCA6OnN0ZDo6c3RyaW5nJiBNZXRob2Q6Om5hbWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZC5uYW1lKQorICByZXR1cm4gbmFtZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgTWV0aG9kOjpzZXRfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICAKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuTWV0aG9kLm5hbWUpCit9Cisgdm9pZCBNZXRob2Q6OnNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIAorICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZC5uYW1lKQorfQorIHZvaWQgTWV0aG9kOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgCisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5NZXRob2QubmFtZSkKK30KKyA6OnN0ZDo6c3RyaW5nKiBNZXRob2Q6Om11dGFibGVfbmFtZSgpIHsKKyAgCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5NZXRob2QubmFtZSkKKyAgcmV0dXJuIG5hbWVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CisgOjpzdGQ6OnN0cmluZyogTWV0aG9kOjpyZWxlYXNlX25hbWUoKSB7CisgIAorICByZXR1cm4gbmFtZV8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIE1ldGhvZDo6c2V0X2FsbG9jYXRlZF9uYW1lKDo6c3RkOjpzdHJpbmcqIG5hbWUpIHsKKyAgaWYgKG5hbWUgIT0gTlVMTCkgeworICAgIAorICB9IGVsc2UgeworICAgIAorICB9CisgIG5hbWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBuYW1lKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZC5uYW1lKQorfQorCisvLyBvcHRpb25hbCBzdHJpbmcgcmVxdWVzdF90eXBlX3VybCA9IDI7Cit2b2lkIE1ldGhvZDo6Y2xlYXJfcmVxdWVzdF90eXBlX3VybCgpIHsKKyAgcmVxdWVzdF90eXBlX3VybF8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIGNvbnN0IDo6c3RkOjpzdHJpbmcmIE1ldGhvZDo6cmVxdWVzdF90eXBlX3VybCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuTWV0aG9kLnJlcXVlc3RfdHlwZV91cmwpCisgIHJldHVybiByZXF1ZXN0X3R5cGVfdXJsXy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBNZXRob2Q6OnNldF9yZXF1ZXN0X3R5cGVfdXJsKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIAorICByZXF1ZXN0X3R5cGVfdXJsXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5NZXRob2QucmVxdWVzdF90eXBlX3VybCkKK30KKyB2b2lkIE1ldGhvZDo6c2V0X3JlcXVlc3RfdHlwZV91cmwoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgCisgIHJlcXVlc3RfdHlwZV91cmxfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuTWV0aG9kLnJlcXVlc3RfdHlwZV91cmwpCit9Cisgdm9pZCBNZXRob2Q6OnNldF9yZXF1ZXN0X3R5cGVfdXJsKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICAKKyAgcmVxdWVzdF90eXBlX3VybF8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZC5yZXF1ZXN0X3R5cGVfdXJsKQorfQorIDo6c3RkOjpzdHJpbmcqIE1ldGhvZDo6bXV0YWJsZV9yZXF1ZXN0X3R5cGVfdXJsKCkgeworICAKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZC5yZXF1ZXN0X3R5cGVfdXJsKQorICByZXR1cm4gcmVxdWVzdF90eXBlX3VybF8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyA6OnN0ZDo6c3RyaW5nKiBNZXRob2Q6OnJlbGVhc2VfcmVxdWVzdF90eXBlX3VybCgpIHsKKyAgCisgIHJldHVybiByZXF1ZXN0X3R5cGVfdXJsXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgTWV0aG9kOjpzZXRfYWxsb2NhdGVkX3JlcXVlc3RfdHlwZV91cmwoOjpzdGQ6OnN0cmluZyogcmVxdWVzdF90eXBlX3VybCkgeworICBpZiAocmVxdWVzdF90eXBlX3VybCAhPSBOVUxMKSB7CisgICAgCisgIH0gZWxzZSB7CisgICAgCisgIH0KKyAgcmVxdWVzdF90eXBlX3VybF8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHJlcXVlc3RfdHlwZV91cmwpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuTWV0aG9kLnJlcXVlc3RfdHlwZV91cmwpCit9CisKKy8vIG9wdGlvbmFsIGJvb2wgcmVxdWVzdF9zdHJlYW1pbmcgPSAzOwordm9pZCBNZXRob2Q6OmNsZWFyX3JlcXVlc3Rfc3RyZWFtaW5nKCkgeworICByZXF1ZXN0X3N0cmVhbWluZ18gPSBmYWxzZTsKK30KKyBib29sIE1ldGhvZDo6cmVxdWVzdF9zdHJlYW1pbmcoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZC5yZXF1ZXN0X3N0cmVhbWluZykKKyAgcmV0dXJuIHJlcXVlc3Rfc3RyZWFtaW5nXzsKK30KKyB2b2lkIE1ldGhvZDo6c2V0X3JlcXVlc3Rfc3RyZWFtaW5nKGJvb2wgdmFsdWUpIHsKKyAgCisgIHJlcXVlc3Rfc3RyZWFtaW5nXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5NZXRob2QucmVxdWVzdF9zdHJlYW1pbmcpCit9CisKKy8vIG9wdGlvbmFsIHN0cmluZyByZXNwb25zZV90eXBlX3VybCA9IDQ7Cit2b2lkIE1ldGhvZDo6Y2xlYXJfcmVzcG9uc2VfdHlwZV91cmwoKSB7CisgIHJlc3BvbnNlX3R5cGVfdXJsXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CisgY29uc3QgOjpzdGQ6OnN0cmluZyYgTWV0aG9kOjpyZXNwb25zZV90eXBlX3VybCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuTWV0aG9kLnJlc3BvbnNlX3R5cGVfdXJsKQorICByZXR1cm4gcmVzcG9uc2VfdHlwZV91cmxfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIE1ldGhvZDo6c2V0X3Jlc3BvbnNlX3R5cGVfdXJsKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIAorICByZXNwb25zZV90eXBlX3VybF8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuTWV0aG9kLnJlc3BvbnNlX3R5cGVfdXJsKQorfQorIHZvaWQgTWV0aG9kOjpzZXRfcmVzcG9uc2VfdHlwZV91cmwoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgCisgIHJlc3BvbnNlX3R5cGVfdXJsXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZC5yZXNwb25zZV90eXBlX3VybCkKK30KKyB2b2lkIE1ldGhvZDo6c2V0X3Jlc3BvbnNlX3R5cGVfdXJsKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICAKKyAgcmVzcG9uc2VfdHlwZV91cmxfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5NZXRob2QucmVzcG9uc2VfdHlwZV91cmwpCit9CisgOjpzdGQ6OnN0cmluZyogTWV0aG9kOjptdXRhYmxlX3Jlc3BvbnNlX3R5cGVfdXJsKCkgeworICAKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZC5yZXNwb25zZV90eXBlX3VybCkKKyAgcmV0dXJuIHJlc3BvbnNlX3R5cGVfdXJsXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIDo6c3RkOjpzdHJpbmcqIE1ldGhvZDo6cmVsZWFzZV9yZXNwb25zZV90eXBlX3VybCgpIHsKKyAgCisgIHJldHVybiByZXNwb25zZV90eXBlX3VybF8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIE1ldGhvZDo6c2V0X2FsbG9jYXRlZF9yZXNwb25zZV90eXBlX3VybCg6OnN0ZDo6c3RyaW5nKiByZXNwb25zZV90eXBlX3VybCkgeworICBpZiAocmVzcG9uc2VfdHlwZV91cmwgIT0gTlVMTCkgeworICAgIAorICB9IGVsc2UgeworICAgIAorICB9CisgIHJlc3BvbnNlX3R5cGVfdXJsXy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgcmVzcG9uc2VfdHlwZV91cmwpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuTWV0aG9kLnJlc3BvbnNlX3R5cGVfdXJsKQorfQorCisvLyBvcHRpb25hbCBib29sIHJlc3BvbnNlX3N0cmVhbWluZyA9IDU7Cit2b2lkIE1ldGhvZDo6Y2xlYXJfcmVzcG9uc2Vfc3RyZWFtaW5nKCkgeworICByZXNwb25zZV9zdHJlYW1pbmdfID0gZmFsc2U7Cit9CisgYm9vbCBNZXRob2Q6OnJlc3BvbnNlX3N0cmVhbWluZygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuTWV0aG9kLnJlc3BvbnNlX3N0cmVhbWluZykKKyAgcmV0dXJuIHJlc3BvbnNlX3N0cmVhbWluZ187Cit9Cisgdm9pZCBNZXRob2Q6OnNldF9yZXNwb25zZV9zdHJlYW1pbmcoYm9vbCB2YWx1ZSkgeworICAKKyAgcmVzcG9uc2Vfc3RyZWFtaW5nXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5NZXRob2QucmVzcG9uc2Vfc3RyZWFtaW5nKQorfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLk9wdGlvbiBvcHRpb25zID0gNjsKK2ludCBNZXRob2Q6Om9wdGlvbnNfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIG9wdGlvbnNfLnNpemUoKTsKK30KK3ZvaWQgTWV0aG9kOjpjbGVhcl9vcHRpb25zKCkgeworICBvcHRpb25zXy5DbGVhcigpOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpPcHRpb24mIE1ldGhvZDo6b3B0aW9ucyhpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuTWV0aG9kLm9wdGlvbnMpCisgIHJldHVybiBvcHRpb25zXy5HZXQoaW5kZXgpOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpPcHRpb24qIE1ldGhvZDo6bXV0YWJsZV9vcHRpb25zKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuTWV0aG9kLm9wdGlvbnMpCisgIHJldHVybiBvcHRpb25zXy5NdXRhYmxlKGluZGV4KTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6T3B0aW9uKiBNZXRob2Q6OmFkZF9vcHRpb25zKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5NZXRob2Qub3B0aW9ucykKKyAgcmV0dXJuIG9wdGlvbnNfLkFkZCgpOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbiA+KgorTWV0aG9kOjptdXRhYmxlX29wdGlvbnMoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZC5vcHRpb25zKQorICByZXR1cm4gJm9wdGlvbnNfOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbiA+JgorTWV0aG9kOjpvcHRpb25zKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuTWV0aG9kLm9wdGlvbnMpCisgIHJldHVybiBvcHRpb25zXzsKK30KKworLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5TeW50YXggc3ludGF4ID0gNzsKK3ZvaWQgTWV0aG9kOjpjbGVhcl9zeW50YXgoKSB7CisgIHN5bnRheF8gPSAwOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6U3ludGF4IE1ldGhvZDo6c3ludGF4KCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5NZXRob2Quc3ludGF4KQorICByZXR1cm4gc3RhdGljX2Nhc3Q8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6U3ludGF4ID4oc3ludGF4Xyk7Cit9Cisgdm9pZCBNZXRob2Q6OnNldF9zeW50YXgoOjpnb29nbGU6OnByb3RvYnVmOjpTeW50YXggdmFsdWUpIHsKKyAgCisgIHN5bnRheF8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuTWV0aG9kLnN5bnRheCkKK30KKworI2VuZGlmICAvLyBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisjaWYgIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKK2NvbnN0IGludCBNaXhpbjo6a05hbWVGaWVsZE51bWJlcjsKK2NvbnN0IGludCBNaXhpbjo6a1Jvb3RGaWVsZE51bWJlcjsKKyNlbmRpZiAgLy8gIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKKworTWl4aW46Ok1peGluKCkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5NaXhpbikKK30KKwordm9pZCBNaXhpbjo6SW5pdEFzRGVmYXVsdEluc3RhbmNlKCkgeworICBfaXNfZGVmYXVsdF9pbnN0YW5jZV8gPSB0cnVlOworfQorCitNaXhpbjo6TWl4aW4oY29uc3QgTWl4aW4mIGZyb20pCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksCisgICAgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29weV9jb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuTWl4aW4pCit9CisKK3ZvaWQgTWl4aW46OlNoYXJlZEN0b3IoKSB7CisgICAgX2lzX2RlZmF1bHRfaW5zdGFuY2VfID0gZmFsc2U7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSAwOworICBuYW1lXy5VbnNhZmVTZXREZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIHJvb3RfLlVuc2FmZVNldERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKworTWl4aW46On5NaXhpbigpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGRlc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLk1peGluKQorICBTaGFyZWREdG9yKCk7Cit9CisKK3ZvaWQgTWl4aW46OlNoYXJlZER0b3IoKSB7CisgIG5hbWVfLkRlc3Ryb3lOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIHJvb3RfLkRlc3Ryb3lOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGlmICh0aGlzICE9IGRlZmF1bHRfaW5zdGFuY2VfKSB7CisgIH0KK30KKwordm9pZCBNaXhpbjo6U2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3QgeworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIE1peGluOjpkZXNjcmlwdG9yKCkgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgcmV0dXJuIE1peGluX2Rlc2NyaXB0b3JfOworfQorCitjb25zdCBNaXhpbiYgTWl4aW46OmRlZmF1bHRfaW5zdGFuY2UoKSB7CisgIGlmIChkZWZhdWx0X2luc3RhbmNlXyA9PSBOVUxMKSBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmYXBpXzJlcHJvdG8oKTsKKyAgcmV0dXJuICpkZWZhdWx0X2luc3RhbmNlXzsKK30KKworTWl4aW4qIE1peGluOjpkZWZhdWx0X2luc3RhbmNlXyA9IE5VTEw7CisKK01peGluKiBNaXhpbjo6TmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdCB7CisgIE1peGluKiBuID0gbmV3IE1peGluOworICBpZiAoYXJlbmEgIT0gTlVMTCkgeworICAgIGFyZW5hLT5Pd24obik7CisgIH0KKyAgcmV0dXJuIG47Cit9CisKK3ZvaWQgTWl4aW46OkNsZWFyKCkgeworICBuYW1lXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIHJvb3RfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKworYm9vbCBNaXhpbjo6TWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KSB7CisjZGVmaW5lIERPXyhFWFBSRVNTSU9OKSBpZiAoIShFWFBSRVNTSU9OKSkgZ290byBmYWlsdXJlCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIHRhZzsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5NaXhpbikKKyAgZm9yICg7OykgeworICAgIDo6c3RkOjpwYWlyPCA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiwgYm9vbD4gcCA9IGlucHV0LT5SZWFkVGFnV2l0aEN1dG9mZigxMjcpOworICAgIHRhZyA9IHAuZmlyc3Q7CisgICAgaWYgKCFwLnNlY29uZCkgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICBzd2l0Y2ggKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdGaWVsZE51bWJlcih0YWcpKSB7CisgICAgICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgICAgICBjYXNlIDE6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAxMCkgeworICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFN0cmluZygKKyAgICAgICAgICAgICAgICBpbnB1dCwgdGhpcy0+bXV0YWJsZV9uYW1lKCkpKTsKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlZlcmlmeVV0ZjhTdHJpbmcoCisgICAgICAgICAgICB0aGlzLT5uYW1lKCkuZGF0YSgpLCB0aGlzLT5uYW1lKCkubGVuZ3RoKCksCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UEFSU0UsCisgICAgICAgICAgICAiZ29vZ2xlLnByb3RvYnVmLk1peGluLm5hbWUiKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygxOCkpIGdvdG8gcGFyc2Vfcm9vdDsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIHN0cmluZyByb290ID0gMjsKKyAgICAgIGNhc2UgMjogeworICAgICAgICBpZiAodGFnID09IDE4KSB7CisgICAgICAgICBwYXJzZV9yb290OgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFN0cmluZygKKyAgICAgICAgICAgICAgICBpbnB1dCwgdGhpcy0+bXV0YWJsZV9yb290KCkpKTsKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlZlcmlmeVV0ZjhTdHJpbmcoCisgICAgICAgICAgICB0aGlzLT5yb290KCkuZGF0YSgpLCB0aGlzLT5yb290KCkubGVuZ3RoKCksCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UEFSU0UsCisgICAgICAgICAgICAiZ29vZ2xlLnByb3RvYnVmLk1peGluLnJvb3QiKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdEF0RW5kKCkpIGdvdG8gc3VjY2VzczsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGRlZmF1bHQ6IHsKKyAgICAgIGhhbmRsZV91bnVzdWFsOgorICAgICAgICBpZiAodGFnID09IDAgfHwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdXaXJlVHlwZSh0YWcpID09CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRU5EX0dST1VQKSB7CisgICAgICAgICAgZ290byBzdWNjZXNzOworICAgICAgICB9CisgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U2tpcEZpZWxkKGlucHV0LCB0YWcpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CitzdWNjZXNzOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3VjY2Vzczpnb29nbGUucHJvdG9idWYuTWl4aW4pCisgIHJldHVybiB0cnVlOworZmFpbHVyZToKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX2ZhaWx1cmU6Z29vZ2xlLnByb3RvYnVmLk1peGluKQorICByZXR1cm4gZmFsc2U7CisjdW5kZWYgRE9fCit9CisKK3ZvaWQgTWl4aW46OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLk1peGluKQorICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgIGlmICh0aGlzLT5uYW1lKCkuc2l6ZSgpID4gMCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpWZXJpZnlVdGY4U3RyaW5nKAorICAgICAgdGhpcy0+bmFtZSgpLmRhdGEoKSwgdGhpcy0+bmFtZSgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuTWl4aW4ubmFtZSIpOworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ01heWJlQWxpYXNlZCgKKyAgICAgIDEsIHRoaXMtPm5hbWUoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIHN0cmluZyByb290ID0gMjsKKyAgaWYgKHRoaXMtPnJvb3QoKS5zaXplKCkgPiAwKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlZlcmlmeVV0ZjhTdHJpbmcoCisgICAgICB0aGlzLT5yb290KCkuZGF0YSgpLCB0aGlzLT5yb290KCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5NaXhpbi5yb290Iik7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nTWF5YmVBbGlhc2VkKAorICAgICAgMiwgdGhpcy0+cm9vdCgpLCBvdXRwdXQpOworICB9CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9lbmQ6Z29vZ2xlLnByb3RvYnVmLk1peGluKQorfQorCis6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBNaXhpbjo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiB0YXJnZXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9zdGFydDpnb29nbGUucHJvdG9idWYuTWl4aW4pCisgIC8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKKyAgaWYgKHRoaXMtPm5hbWUoKS5zaXplKCkgPiAwKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlZlcmlmeVV0ZjhTdHJpbmcoCisgICAgICB0aGlzLT5uYW1lKCkuZGF0YSgpLCB0aGlzLT5uYW1lKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5NaXhpbi5uYW1lIik7CisgICAgdGFyZ2V0ID0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ1RvQXJyYXkoCisgICAgICAgIDEsIHRoaXMtPm5hbWUoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIHN0cmluZyByb290ID0gMjsKKyAgaWYgKHRoaXMtPnJvb3QoKS5zaXplKCkgPiAwKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlZlcmlmeVV0ZjhTdHJpbmcoCisgICAgICB0aGlzLT5yb290KCkuZGF0YSgpLCB0aGlzLT5yb290KCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5NaXhpbi5yb290Iik7CisgICAgdGFyZ2V0ID0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ1RvQXJyYXkoCisgICAgICAgIDIsIHRoaXMtPnJvb3QoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfZW5kOmdvb2dsZS5wcm90b2J1Zi5NaXhpbikKKyAgcmV0dXJuIHRhcmdldDsKK30KKworaW50IE1peGluOjpCeXRlU2l6ZSgpIGNvbnN0IHsKKyAgaW50IHRvdGFsX3NpemUgPSAwOworCisgIC8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKKyAgaWYgKHRoaXMtPm5hbWUoKS5zaXplKCkgPiAwKSB7CisgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTdHJpbmdTaXplKAorICAgICAgICB0aGlzLT5uYW1lKCkpOworICB9CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIHJvb3QgPSAyOworICBpZiAodGhpcy0+cm9vdCgpLnNpemUoKSA+IDApIHsKKyAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlN0cmluZ1NpemUoCisgICAgICAgIHRoaXMtPnJvb3QoKSk7CisgIH0KKworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gdG90YWxfc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7CisgIHJldHVybiB0b3RhbF9zaXplOworfQorCit2b2lkIE1peGluOjpNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGNvbnN0IE1peGluKiBzb3VyY2UgPSAKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkR5bmFtaWNDYXN0VG9HZW5lcmF0ZWQ8Y29uc3QgTWl4aW4+KAorICAgICAgICAgICZmcm9tKTsKKyAgaWYgKHNvdXJjZSA9PSBOVUxMKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6UmVmbGVjdGlvbk9wczo6TWVyZ2UoZnJvbSwgdGhpcyk7CisgIH0gZWxzZSB7CisgICAgTWVyZ2VGcm9tKCpzb3VyY2UpOworICB9Cit9CisKK3ZvaWQgTWl4aW46Ok1lcmdlRnJvbShjb25zdCBNaXhpbiYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBpZiAoZnJvbS5uYW1lKCkuc2l6ZSgpID4gMCkgeworCisgICAgbmFtZV8uQXNzaWduV2l0aERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBmcm9tLm5hbWVfKTsKKyAgfQorICBpZiAoZnJvbS5yb290KCkuc2l6ZSgpID4gMCkgeworCisgICAgcm9vdF8uQXNzaWduV2l0aERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBmcm9tLnJvb3RfKTsKKyAgfQorfQorCit2b2lkIE1peGluOjpDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCit2b2lkIE1peGluOjpDb3B5RnJvbShjb25zdCBNaXhpbiYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK2Jvb2wgTWl4aW46OklzSW5pdGlhbGl6ZWQoKSBjb25zdCB7CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgTWl4aW46OlN3YXAoTWl4aW4qIG90aGVyKSB7CisgIGlmIChvdGhlciA9PSB0aGlzKSByZXR1cm47CisgIEludGVybmFsU3dhcChvdGhlcik7Cit9Cit2b2lkIE1peGluOjpJbnRlcm5hbFN3YXAoTWl4aW4qIG90aGVyKSB7CisgIG5hbWVfLlN3YXAoJm90aGVyLT5uYW1lXyk7CisgIHJvb3RfLlN3YXAoJm90aGVyLT5yb290Xyk7CisgIF9pbnRlcm5hbF9tZXRhZGF0YV8uU3dhcCgmb3RoZXItPl9pbnRlcm5hbF9tZXRhZGF0YV8pOworICBzdGQ6OnN3YXAoX2NhY2hlZF9zaXplXywgb3RoZXItPl9jYWNoZWRfc2l6ZV8pOworfQorCis6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIE1peGluOjpHZXRNZXRhZGF0YSgpIGNvbnN0IHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgbWV0YWRhdGE7CisgIG1ldGFkYXRhLmRlc2NyaXB0b3IgPSBNaXhpbl9kZXNjcmlwdG9yXzsKKyAgbWV0YWRhdGEucmVmbGVjdGlvbiA9IE1peGluX3JlZmxlY3Rpb25fOworICByZXR1cm4gbWV0YWRhdGE7Cit9CisKKyNpZiBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKy8vIE1peGluCisKKy8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKK3ZvaWQgTWl4aW46OmNsZWFyX25hbWUoKSB7CisgIG5hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyBjb25zdCA6OnN0ZDo6c3RyaW5nJiBNaXhpbjo6bmFtZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuTWl4aW4ubmFtZSkKKyAgcmV0dXJuIG5hbWVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIE1peGluOjpzZXRfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICAKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuTWl4aW4ubmFtZSkKK30KKyB2b2lkIE1peGluOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICAKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5NaXhpbi5uYW1lKQorfQorIHZvaWQgTWl4aW46OnNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICAKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLk1peGluLm5hbWUpCit9CisgOjpzdGQ6OnN0cmluZyogTWl4aW46Om11dGFibGVfbmFtZSgpIHsKKyAgCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5NaXhpbi5uYW1lKQorICByZXR1cm4gbmFtZV8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyA6OnN0ZDo6c3RyaW5nKiBNaXhpbjo6cmVsZWFzZV9uYW1lKCkgeworICAKKyAgcmV0dXJuIG5hbWVfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBNaXhpbjo6c2V0X2FsbG9jYXRlZF9uYW1lKDo6c3RkOjpzdHJpbmcqIG5hbWUpIHsKKyAgaWYgKG5hbWUgIT0gTlVMTCkgeworICAgIAorICB9IGVsc2UgeworICAgIAorICB9CisgIG5hbWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBuYW1lKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLk1peGluLm5hbWUpCit9CisKKy8vIG9wdGlvbmFsIHN0cmluZyByb290ID0gMjsKK3ZvaWQgTWl4aW46OmNsZWFyX3Jvb3QoKSB7CisgIHJvb3RfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyBjb25zdCA6OnN0ZDo6c3RyaW5nJiBNaXhpbjo6cm9vdCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuTWl4aW4ucm9vdCkKKyAgcmV0dXJuIHJvb3RfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIE1peGluOjpzZXRfcm9vdChjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICAKKyAgcm9vdF8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuTWl4aW4ucm9vdCkKK30KKyB2b2lkIE1peGluOjpzZXRfcm9vdChjb25zdCBjaGFyKiB2YWx1ZSkgeworICAKKyAgcm9vdF8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5NaXhpbi5yb290KQorfQorIHZvaWQgTWl4aW46OnNldF9yb290KGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICAKKyAgcm9vdF8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLk1peGluLnJvb3QpCit9CisgOjpzdGQ6OnN0cmluZyogTWl4aW46Om11dGFibGVfcm9vdCgpIHsKKyAgCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5NaXhpbi5yb290KQorICByZXR1cm4gcm9vdF8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyA6OnN0ZDo6c3RyaW5nKiBNaXhpbjo6cmVsZWFzZV9yb290KCkgeworICAKKyAgcmV0dXJuIHJvb3RfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBNaXhpbjo6c2V0X2FsbG9jYXRlZF9yb290KDo6c3RkOjpzdHJpbmcqIHJvb3QpIHsKKyAgaWYgKHJvb3QgIT0gTlVMTCkgeworICAgIAorICB9IGVsc2UgeworICAgIAorICB9CisgIHJvb3RfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCByb290KTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLk1peGluLnJvb3QpCit9CisKKyNlbmRpZiAgLy8gUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisKKy8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChuYW1lc3BhY2Vfc2NvcGUpCisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZ2xvYmFsX3Njb3BlKQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9hcGkucGIuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvYXBpLnBiLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTFkY2E0ZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvYXBpLnBiLmgKQEAgLTAsMCArMSw5NzYgQEAKKy8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCisvLyBzb3VyY2U6IGdvb2dsZS9wcm90b2J1Zi9hcGkucHJvdG8KKworI2lmbmRlZiBQUk9UT0JVRl9nb29nbGVfMmZwcm90b2J1Zl8yZmFwaV8yZXByb3RvX19JTkNMVURFRAorI2RlZmluZSBQUk9UT0JVRl9nb29nbGVfMmZwcm90b2J1Zl8yZmFwaV8yZXByb3RvX19JTkNMVURFRAorCisjaW5jbHVkZSA8c3RyaW5nPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorCisjaWYgR09PR0xFX1BST1RPQlVGX1ZFUlNJT04gPCAzMDAwMDAwCisjZXJyb3IgVGhpcyBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgYSBuZXdlciB2ZXJzaW9uIG9mIHByb3RvYyB3aGljaCBpcworI2Vycm9yIGluY29tcGF0aWJsZSB3aXRoIHlvdXIgUHJvdG9jb2wgQnVmZmVyIGhlYWRlcnMuICBQbGVhc2UgdXBkYXRlCisjZXJyb3IgeW91ciBoZWFkZXJzLgorI2VuZGlmCisjaWYgMzAwMDAwMCA8IEdPT0dMRV9QUk9UT0JVRl9NSU5fUFJPVE9DX1ZFUlNJT04KKyNlcnJvciBUaGlzIGZpbGUgd2FzIGdlbmVyYXRlZCBieSBhbiBvbGRlciB2ZXJzaW9uIG9mIHByb3RvYyB3aGljaCBpcworI2Vycm9yIGluY29tcGF0aWJsZSB3aXRoIHlvdXIgUHJvdG9jb2wgQnVmZmVyIGhlYWRlcnMuICBQbGVhc2UKKyNlcnJvciByZWdlbmVyYXRlIHRoaXMgZmlsZSB3aXRoIGEgbmV3ZXIgdmVyc2lvbiBvZiBwcm90b2MuCisjZW5kaWYKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9hcmVuYS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9hcmVuYXN0cmluZy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfbWVzc2FnZV91dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21ldGFkYXRhLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21lc3NhZ2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcmVwZWF0ZWRfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZXh0ZW5zaW9uX3NldC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bmtub3duX2ZpZWxkX3NldC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zb3VyY2VfY29udGV4dC5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90eXBlLnBiLmg+CisvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW5jbHVkZXMpCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworLy8gSW50ZXJuYWwgaW1wbGVtZW50YXRpb24gZGV0YWlsIC0tIGRvIG5vdCBjYWxsIHRoZXNlLgordm9pZCBMSUJQUk9UT0JVRl9FWFBPUlQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmFwaV8yZXByb3RvKCk7Cit2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZhcGlfMmVwcm90bygpOwordm9pZCBwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZhcGlfMmVwcm90bygpOworCitjbGFzcyBBcGk7CitjbGFzcyBNZXRob2Q7CitjbGFzcyBNaXhpbjsKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgQXBpIDogcHVibGljIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSB7CisgcHVibGljOgorICBBcGkoKTsKKyAgdmlydHVhbCB+QXBpKCk7CisKKyAgQXBpKGNvbnN0IEFwaSYgZnJvbSk7CisKKyAgaW5saW5lIEFwaSYgb3BlcmF0b3I9KGNvbnN0IEFwaSYgZnJvbSkgeworICAgIENvcHlGcm9tKGZyb20pOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIHN0YXRpYyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIGRlc2NyaXB0b3IoKTsKKyAgc3RhdGljIGNvbnN0IEFwaSYgZGVmYXVsdF9pbnN0YW5jZSgpOworCisgIHZvaWQgU3dhcChBcGkqIG90aGVyKTsKKworICAvLyBpbXBsZW1lbnRzIE1lc3NhZ2UgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIGlubGluZSBBcGkqIE5ldygpIGNvbnN0IHsgcmV0dXJuIE5ldyhOVUxMKTsgfQorCisgIEFwaSogTmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdDsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIENvcHlGcm9tKGNvbnN0IEFwaSYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IEFwaSYgZnJvbSk7CisgIHZvaWQgQ2xlYXIoKTsKKyAgYm9vbCBJc0luaXRpYWxpemVkKCkgY29uc3Q7CisKKyAgaW50IEJ5dGVTaXplKCkgY29uc3Q7CisgIGJvb2wgTWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpOworICB2b2lkIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIG91dHB1dCkgY29uc3Q7CisgIGludCBHZXRDYWNoZWRTaXplKCkgY29uc3QgeyByZXR1cm4gX2NhY2hlZF9zaXplXzsgfQorICBwcml2YXRlOgorICB2b2lkIFNoYXJlZEN0b3IoKTsKKyAgdm9pZCBTaGFyZWREdG9yKCk7CisgIHZvaWQgU2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3Q7CisgIHZvaWQgSW50ZXJuYWxTd2FwKEFwaSogb3RoZXIpOworICBwcml2YXRlOgorICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogR2V0QXJlbmFOb1ZpcnR1YWwoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8uYXJlbmEoKTsKKyAgfQorICBpbmxpbmUgdm9pZCogTWF5YmVBcmVuYVB0cigpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5yYXdfYXJlbmFfcHRyKCk7CisgIH0KKyAgcHVibGljOgorCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgR2V0TWV0YWRhdGEoKSBjb25zdDsKKworICAvLyBuZXN0ZWQgdHlwZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIGFjY2Vzc29ycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICB2b2lkIGNsZWFyX25hbWUoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrTmFtZUZpZWxkTnVtYmVyID0gMTsKKyAgY29uc3QgOjpzdGQ6OnN0cmluZyYgbmFtZSgpIGNvbnN0OworICB2b2lkIHNldF9uYW1lKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKTsKKyAgdm9pZCBzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSk7CisgIHZvaWQgc2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKTsKKyAgOjpzdGQ6OnN0cmluZyogbXV0YWJsZV9uYW1lKCk7CisgIDo6c3RkOjpzdHJpbmcqIHJlbGVhc2VfbmFtZSgpOworICB2b2lkIHNldF9hbGxvY2F0ZWRfbmFtZSg6OnN0ZDo6c3RyaW5nKiBuYW1lKTsKKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLk1ldGhvZCBtZXRob2RzID0gMjsKKyAgaW50IG1ldGhvZHNfc2l6ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX21ldGhvZHMoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrTWV0aG9kc0ZpZWxkTnVtYmVyID0gMjsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRob2QmIG1ldGhvZHMoaW50IGluZGV4KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRob2QqIG11dGFibGVfbWV0aG9kcyhpbnQgaW5kZXgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGhvZCogYWRkX21ldGhvZHMoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGhvZCA+KgorICAgICAgbXV0YWJsZV9tZXRob2RzKCk7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRob2QgPiYKKyAgICAgIG1ldGhvZHMoKSBjb25zdDsKKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLk9wdGlvbiBvcHRpb25zID0gMzsKKyAgaW50IG9wdGlvbnNfc2l6ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX29wdGlvbnMoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrT3B0aW9uc0ZpZWxkTnVtYmVyID0gMzsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpPcHRpb24mIG9wdGlvbnMoaW50IGluZGV4KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpPcHRpb24qIG11dGFibGVfb3B0aW9ucyhpbnQgaW5kZXgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbiogYWRkX29wdGlvbnMoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbiA+KgorICAgICAgbXV0YWJsZV9vcHRpb25zKCk7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpPcHRpb24gPiYKKyAgICAgIG9wdGlvbnMoKSBjb25zdDsKKworICAvLyBvcHRpb25hbCBzdHJpbmcgdmVyc2lvbiA9IDQ7CisgIHZvaWQgY2xlYXJfdmVyc2lvbigpOworICBzdGF0aWMgY29uc3QgaW50IGtWZXJzaW9uRmllbGROdW1iZXIgPSA0OworICBjb25zdCA6OnN0ZDo6c3RyaW5nJiB2ZXJzaW9uKCkgY29uc3Q7CisgIHZvaWQgc2V0X3ZlcnNpb24oY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpOworICB2b2lkIHNldF92ZXJzaW9uKGNvbnN0IGNoYXIqIHZhbHVlKTsKKyAgdm9pZCBzZXRfdmVyc2lvbihjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpOworICA6OnN0ZDo6c3RyaW5nKiBtdXRhYmxlX3ZlcnNpb24oKTsKKyAgOjpzdGQ6OnN0cmluZyogcmVsZWFzZV92ZXJzaW9uKCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF92ZXJzaW9uKDo6c3RkOjpzdHJpbmcqIHZlcnNpb24pOworCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCBzb3VyY2VfY29udGV4dCA9IDU7CisgIGJvb2wgaGFzX3NvdXJjZV9jb250ZXh0KCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfc291cmNlX2NvbnRleHQoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrU291cmNlQ29udGV4dEZpZWxkTnVtYmVyID0gNTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb250ZXh0JiBzb3VyY2VfY29udGV4dCgpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvbnRleHQqIG11dGFibGVfc291cmNlX2NvbnRleHQoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb250ZXh0KiByZWxlYXNlX3NvdXJjZV9jb250ZXh0KCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF9zb3VyY2VfY29udGV4dCg6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvbnRleHQqIHNvdXJjZV9jb250ZXh0KTsKKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLk1peGluIG1peGlucyA9IDY7CisgIGludCBtaXhpbnNfc2l6ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX21peGlucygpOworICBzdGF0aWMgY29uc3QgaW50IGtNaXhpbnNGaWVsZE51bWJlciA9IDY7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWl4aW4mIG1peGlucyhpbnQgaW5kZXgpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1peGluKiBtdXRhYmxlX21peGlucyhpbnQgaW5kZXgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1peGluKiBhZGRfbWl4aW5zKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpNaXhpbiA+KgorICAgICAgbXV0YWJsZV9taXhpbnMoKTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1peGluID4mCisgICAgICBtaXhpbnMoKSBjb25zdDsKKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLlN5bnRheCBzeW50YXggPSA3OworICB2b2lkIGNsZWFyX3N5bnRheCgpOworICBzdGF0aWMgY29uc3QgaW50IGtTeW50YXhGaWVsZE51bWJlciA9IDc7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6U3ludGF4IHN5bnRheCgpIGNvbnN0OworICB2b2lkIHNldF9zeW50YXgoOjpnb29nbGU6OnByb3RvYnVmOjpTeW50YXggdmFsdWUpOworCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpnb29nbGUucHJvdG9idWYuQXBpKQorIHByaXZhdGU6CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6SW50ZXJuYWxNZXRhZGF0YVdpdGhBcmVuYSBfaW50ZXJuYWxfbWV0YWRhdGFfOworICBib29sIF9pc19kZWZhdWx0X2luc3RhbmNlXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QXJlbmFTdHJpbmdQdHIgbmFtZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRob2QgPiBtZXRob2RzXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbiA+IG9wdGlvbnNfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBcmVuYVN0cmluZ1B0ciB2ZXJzaW9uXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb250ZXh0KiBzb3VyY2VfY29udGV4dF87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpNaXhpbiA+IG1peGluc187CisgIGludCBzeW50YXhfOworICBtdXRhYmxlIGludCBfY2FjaGVkX3NpemVfOworICBmcmllbmQgdm9pZCBMSUJQUk9UT0JVRl9FWFBPUlQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmFwaV8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZhcGlfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZhcGlfMmVwcm90bygpOworCisgIHZvaWQgSW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIHN0YXRpYyBBcGkqIGRlZmF1bHRfaW5zdGFuY2VfOworfTsKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIE1ldGhvZCA6IHB1YmxpYyA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UgeworIHB1YmxpYzoKKyAgTWV0aG9kKCk7CisgIHZpcnR1YWwgfk1ldGhvZCgpOworCisgIE1ldGhvZChjb25zdCBNZXRob2QmIGZyb20pOworCisgIGlubGluZSBNZXRob2QmIG9wZXJhdG9yPShjb25zdCBNZXRob2QmIGZyb20pIHsKKyAgICBDb3B5RnJvbShmcm9tKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworICBzdGF0aWMgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKCk7CisgIHN0YXRpYyBjb25zdCBNZXRob2QmIGRlZmF1bHRfaW5zdGFuY2UoKTsKKworICB2b2lkIFN3YXAoTWV0aG9kKiBvdGhlcik7CisKKyAgLy8gaW1wbGVtZW50cyBNZXNzYWdlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBpbmxpbmUgTWV0aG9kKiBOZXcoKSBjb25zdCB7IHJldHVybiBOZXcoTlVMTCk7IH0KKworICBNZXRob2QqIE5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3Q7CisgIHZvaWQgQ29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCBNZXRob2QmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCBNZXRob2QmIGZyb20pOworICB2b2lkIENsZWFyKCk7CisgIGJvb2wgSXNJbml0aWFsaXplZCgpIGNvbnN0OworCisgIGludCBCeXRlU2l6ZSgpIGNvbnN0OworICBib29sIE1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KTsKKyAgdm9pZCBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSg6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBvdXRwdXQpIGNvbnN0OworICBpbnQgR2V0Q2FjaGVkU2l6ZSgpIGNvbnN0IHsgcmV0dXJuIF9jYWNoZWRfc2l6ZV87IH0KKyAgcHJpdmF0ZToKKyAgdm9pZCBTaGFyZWRDdG9yKCk7CisgIHZvaWQgU2hhcmVkRHRvcigpOworICB2b2lkIFNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0OworICB2b2lkIEludGVybmFsU3dhcChNZXRob2QqIG90aGVyKTsKKyAgcHJpdmF0ZToKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hTm9WaXJ0dWFsKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLmFyZW5hKCk7CisgIH0KKyAgaW5saW5lIHZvaWQqIE1heWJlQXJlbmFQdHIoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ucmF3X2FyZW5hX3B0cigpOworICB9CisgIHB1YmxpYzoKKworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEdldE1ldGFkYXRhKCkgY29uc3Q7CisKKyAgLy8gbmVzdGVkIHR5cGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBhY2Nlc3NvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKKyAgdm9pZCBjbGVhcl9uYW1lKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga05hbWVGaWVsZE51bWJlciA9IDE7CisgIGNvbnN0IDo6c3RkOjpzdHJpbmcmIG5hbWUoKSBjb25zdDsKKyAgdm9pZCBzZXRfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUpOworICB2b2lkIHNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIDo6c3RkOjpzdHJpbmcqIG11dGFibGVfbmFtZSgpOworICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlX25hbWUoKTsKKyAgdm9pZCBzZXRfYWxsb2NhdGVkX25hbWUoOjpzdGQ6OnN0cmluZyogbmFtZSk7CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIHJlcXVlc3RfdHlwZV91cmwgPSAyOworICB2b2lkIGNsZWFyX3JlcXVlc3RfdHlwZV91cmwoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrUmVxdWVzdFR5cGVVcmxGaWVsZE51bWJlciA9IDI7CisgIGNvbnN0IDo6c3RkOjpzdHJpbmcmIHJlcXVlc3RfdHlwZV91cmwoKSBjb25zdDsKKyAgdm9pZCBzZXRfcmVxdWVzdF90eXBlX3VybChjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X3JlcXVlc3RfdHlwZV91cmwoY29uc3QgY2hhciogdmFsdWUpOworICB2b2lkIHNldF9yZXF1ZXN0X3R5cGVfdXJsKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIDo6c3RkOjpzdHJpbmcqIG11dGFibGVfcmVxdWVzdF90eXBlX3VybCgpOworICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlX3JlcXVlc3RfdHlwZV91cmwoKTsKKyAgdm9pZCBzZXRfYWxsb2NhdGVkX3JlcXVlc3RfdHlwZV91cmwoOjpzdGQ6OnN0cmluZyogcmVxdWVzdF90eXBlX3VybCk7CisKKyAgLy8gb3B0aW9uYWwgYm9vbCByZXF1ZXN0X3N0cmVhbWluZyA9IDM7CisgIHZvaWQgY2xlYXJfcmVxdWVzdF9zdHJlYW1pbmcoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrUmVxdWVzdFN0cmVhbWluZ0ZpZWxkTnVtYmVyID0gMzsKKyAgYm9vbCByZXF1ZXN0X3N0cmVhbWluZygpIGNvbnN0OworICB2b2lkIHNldF9yZXF1ZXN0X3N0cmVhbWluZyhib29sIHZhbHVlKTsKKworICAvLyBvcHRpb25hbCBzdHJpbmcgcmVzcG9uc2VfdHlwZV91cmwgPSA0OworICB2b2lkIGNsZWFyX3Jlc3BvbnNlX3R5cGVfdXJsKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga1Jlc3BvbnNlVHlwZVVybEZpZWxkTnVtYmVyID0gNDsKKyAgY29uc3QgOjpzdGQ6OnN0cmluZyYgcmVzcG9uc2VfdHlwZV91cmwoKSBjb25zdDsKKyAgdm9pZCBzZXRfcmVzcG9uc2VfdHlwZV91cmwoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpOworICB2b2lkIHNldF9yZXNwb25zZV90eXBlX3VybChjb25zdCBjaGFyKiB2YWx1ZSk7CisgIHZvaWQgc2V0X3Jlc3BvbnNlX3R5cGVfdXJsKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIDo6c3RkOjpzdHJpbmcqIG11dGFibGVfcmVzcG9uc2VfdHlwZV91cmwoKTsKKyAgOjpzdGQ6OnN0cmluZyogcmVsZWFzZV9yZXNwb25zZV90eXBlX3VybCgpOworICB2b2lkIHNldF9hbGxvY2F0ZWRfcmVzcG9uc2VfdHlwZV91cmwoOjpzdGQ6OnN0cmluZyogcmVzcG9uc2VfdHlwZV91cmwpOworCisgIC8vIG9wdGlvbmFsIGJvb2wgcmVzcG9uc2Vfc3RyZWFtaW5nID0gNTsKKyAgdm9pZCBjbGVhcl9yZXNwb25zZV9zdHJlYW1pbmcoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrUmVzcG9uc2VTdHJlYW1pbmdGaWVsZE51bWJlciA9IDU7CisgIGJvb2wgcmVzcG9uc2Vfc3RyZWFtaW5nKCkgY29uc3Q7CisgIHZvaWQgc2V0X3Jlc3BvbnNlX3N0cmVhbWluZyhib29sIHZhbHVlKTsKKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLk9wdGlvbiBvcHRpb25zID0gNjsKKyAgaW50IG9wdGlvbnNfc2l6ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX29wdGlvbnMoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrT3B0aW9uc0ZpZWxkTnVtYmVyID0gNjsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpPcHRpb24mIG9wdGlvbnMoaW50IGluZGV4KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpPcHRpb24qIG11dGFibGVfb3B0aW9ucyhpbnQgaW5kZXgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbiogYWRkX29wdGlvbnMoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbiA+KgorICAgICAgbXV0YWJsZV9vcHRpb25zKCk7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpPcHRpb24gPiYKKyAgICAgIG9wdGlvbnMoKSBjb25zdDsKKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLlN5bnRheCBzeW50YXggPSA3OworICB2b2lkIGNsZWFyX3N5bnRheCgpOworICBzdGF0aWMgY29uc3QgaW50IGtTeW50YXhGaWVsZE51bWJlciA9IDc7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6U3ludGF4IHN5bnRheCgpIGNvbnN0OworICB2b2lkIHNldF9zeW50YXgoOjpnb29nbGU6OnByb3RvYnVmOjpTeW50YXggdmFsdWUpOworCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpnb29nbGUucHJvdG9idWYuTWV0aG9kKQorIHByaXZhdGU6CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6SW50ZXJuYWxNZXRhZGF0YVdpdGhBcmVuYSBfaW50ZXJuYWxfbWV0YWRhdGFfOworICBib29sIF9pc19kZWZhdWx0X2luc3RhbmNlXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QXJlbmFTdHJpbmdQdHIgbmFtZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFyZW5hU3RyaW5nUHRyIHJlcXVlc3RfdHlwZV91cmxfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBcmVuYVN0cmluZ1B0ciByZXNwb25zZV90eXBlX3VybF87CisgIGJvb2wgcmVxdWVzdF9zdHJlYW1pbmdfOworICBib29sIHJlc3BvbnNlX3N0cmVhbWluZ187CisgIGludCBzeW50YXhfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6T3B0aW9uID4gb3B0aW9uc187CisgIG11dGFibGUgaW50IF9jYWNoZWRfc2l6ZV87CisgIGZyaWVuZCB2b2lkIExJQlBST1RPQlVGX0VYUE9SVCBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmYXBpXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfQXNzaWduRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmFwaV8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZmFwaV8yZXByb3RvKCk7CisKKyAgdm9pZCBJbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgc3RhdGljIE1ldGhvZCogZGVmYXVsdF9pbnN0YW5jZV87Cit9OworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgTWl4aW4gOiBwdWJsaWMgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlIHsKKyBwdWJsaWM6CisgIE1peGluKCk7CisgIHZpcnR1YWwgfk1peGluKCk7CisKKyAgTWl4aW4oY29uc3QgTWl4aW4mIGZyb20pOworCisgIGlubGluZSBNaXhpbiYgb3BlcmF0b3I9KGNvbnN0IE1peGluJiBmcm9tKSB7CisgICAgQ29weUZyb20oZnJvbSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgc3RhdGljIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogZGVzY3JpcHRvcigpOworICBzdGF0aWMgY29uc3QgTWl4aW4mIGRlZmF1bHRfaW5zdGFuY2UoKTsKKworICB2b2lkIFN3YXAoTWl4aW4qIG90aGVyKTsKKworICAvLyBpbXBsZW1lbnRzIE1lc3NhZ2UgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIGlubGluZSBNaXhpbiogTmV3KCkgY29uc3QgeyByZXR1cm4gTmV3KE5VTEwpOyB9CisKKyAgTWl4aW4qIE5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3Q7CisgIHZvaWQgQ29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCBNaXhpbiYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IE1peGluJiBmcm9tKTsKKyAgdm9pZCBDbGVhcigpOworICBib29sIElzSW5pdGlhbGl6ZWQoKSBjb25zdDsKKworICBpbnQgQnl0ZVNpemUoKSBjb25zdDsKKyAgYm9vbCBNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCk7CisgIHZvaWQgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogb3V0cHV0KSBjb25zdDsKKyAgaW50IEdldENhY2hlZFNpemUoKSBjb25zdCB7IHJldHVybiBfY2FjaGVkX3NpemVfOyB9CisgIHByaXZhdGU6CisgIHZvaWQgU2hhcmVkQ3RvcigpOworICB2b2lkIFNoYXJlZER0b3IoKTsKKyAgdm9pZCBTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdDsKKyAgdm9pZCBJbnRlcm5hbFN3YXAoTWl4aW4qIG90aGVyKTsKKyAgcHJpdmF0ZToKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hTm9WaXJ0dWFsKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLmFyZW5hKCk7CisgIH0KKyAgaW5saW5lIHZvaWQqIE1heWJlQXJlbmFQdHIoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ucmF3X2FyZW5hX3B0cigpOworICB9CisgIHB1YmxpYzoKKworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEdldE1ldGFkYXRhKCkgY29uc3Q7CisKKyAgLy8gbmVzdGVkIHR5cGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBhY2Nlc3NvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKKyAgdm9pZCBjbGVhcl9uYW1lKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga05hbWVGaWVsZE51bWJlciA9IDE7CisgIGNvbnN0IDo6c3RkOjpzdHJpbmcmIG5hbWUoKSBjb25zdDsKKyAgdm9pZCBzZXRfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUpOworICB2b2lkIHNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIDo6c3RkOjpzdHJpbmcqIG11dGFibGVfbmFtZSgpOworICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlX25hbWUoKTsKKyAgdm9pZCBzZXRfYWxsb2NhdGVkX25hbWUoOjpzdGQ6OnN0cmluZyogbmFtZSk7CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIHJvb3QgPSAyOworICB2b2lkIGNsZWFyX3Jvb3QoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrUm9vdEZpZWxkTnVtYmVyID0gMjsKKyAgY29uc3QgOjpzdGQ6OnN0cmluZyYgcm9vdCgpIGNvbnN0OworICB2b2lkIHNldF9yb290KGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKTsKKyAgdm9pZCBzZXRfcm9vdChjb25zdCBjaGFyKiB2YWx1ZSk7CisgIHZvaWQgc2V0X3Jvb3QoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKTsKKyAgOjpzdGQ6OnN0cmluZyogbXV0YWJsZV9yb290KCk7CisgIDo6c3RkOjpzdHJpbmcqIHJlbGVhc2Vfcm9vdCgpOworICB2b2lkIHNldF9hbGxvY2F0ZWRfcm9vdCg6OnN0ZDo6c3RyaW5nKiByb290KTsKKworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6Z29vZ2xlLnByb3RvYnVmLk1peGluKQorIHByaXZhdGU6CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6SW50ZXJuYWxNZXRhZGF0YVdpdGhBcmVuYSBfaW50ZXJuYWxfbWV0YWRhdGFfOworICBib29sIF9pc19kZWZhdWx0X2luc3RhbmNlXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QXJlbmFTdHJpbmdQdHIgbmFtZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFyZW5hU3RyaW5nUHRyIHJvb3RfOworICBtdXRhYmxlIGludCBfY2FjaGVkX3NpemVfOworICBmcmllbmQgdm9pZCBMSUJQUk9UT0JVRl9FWFBPUlQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmFwaV8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZhcGlfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZhcGlfMmVwcm90bygpOworCisgIHZvaWQgSW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIHN0YXRpYyBNaXhpbiogZGVmYXVsdF9pbnN0YW5jZV87Cit9OworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworI2lmICFQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKy8vIEFwaQorCisvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CitpbmxpbmUgdm9pZCBBcGk6OmNsZWFyX25hbWUoKSB7CisgIG5hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBBcGk6Om5hbWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkFwaS5uYW1lKQorICByZXR1cm4gbmFtZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgQXBpOjpzZXRfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICAKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuQXBpLm5hbWUpCit9CitpbmxpbmUgdm9pZCBBcGk6OnNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIAorICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLkFwaS5uYW1lKQorfQoraW5saW5lIHZvaWQgQXBpOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgCisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5BcGkubmFtZSkKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBBcGk6Om11dGFibGVfbmFtZSgpIHsKKyAgCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5BcGkubmFtZSkKKyAgcmV0dXJuIG5hbWVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogQXBpOjpyZWxlYXNlX25hbWUoKSB7CisgIAorICByZXR1cm4gbmFtZV8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIEFwaTo6c2V0X2FsbG9jYXRlZF9uYW1lKDo6c3RkOjpzdHJpbmcqIG5hbWUpIHsKKyAgaWYgKG5hbWUgIT0gTlVMTCkgeworICAgIAorICB9IGVsc2UgeworICAgIAorICB9CisgIG5hbWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBuYW1lKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkFwaS5uYW1lKQorfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLk1ldGhvZCBtZXRob2RzID0gMjsKK2lubGluZSBpbnQgQXBpOjptZXRob2RzX3NpemUoKSBjb25zdCB7CisgIHJldHVybiBtZXRob2RzXy5zaXplKCk7Cit9CitpbmxpbmUgdm9pZCBBcGk6OmNsZWFyX21ldGhvZHMoKSB7CisgIG1ldGhvZHNfLkNsZWFyKCk7Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRob2QmIEFwaTo6bWV0aG9kcyhpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuQXBpLm1ldGhvZHMpCisgIHJldHVybiBtZXRob2RzXy5HZXQoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0aG9kKiBBcGk6Om11dGFibGVfbWV0aG9kcyhpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkFwaS5tZXRob2RzKQorICByZXR1cm4gbWV0aG9kc18uTXV0YWJsZShpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRob2QqIEFwaTo6YWRkX21ldGhvZHMoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLkFwaS5tZXRob2RzKQorICByZXR1cm4gbWV0aG9kc18uQWRkKCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGhvZCA+KgorQXBpOjptdXRhYmxlX21ldGhvZHMoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkFwaS5tZXRob2RzKQorICByZXR1cm4gJm1ldGhvZHNfOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRob2QgPiYKK0FwaTo6bWV0aG9kcygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkFwaS5tZXRob2RzKQorICByZXR1cm4gbWV0aG9kc187Cit9CisKKy8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuT3B0aW9uIG9wdGlvbnMgPSAzOworaW5saW5lIGludCBBcGk6Om9wdGlvbnNfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIG9wdGlvbnNfLnNpemUoKTsKK30KK2lubGluZSB2b2lkIEFwaTo6Y2xlYXJfb3B0aW9ucygpIHsKKyAgb3B0aW9uc18uQ2xlYXIoKTsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbiYgQXBpOjpvcHRpb25zKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5BcGkub3B0aW9ucykKKyAgcmV0dXJuIG9wdGlvbnNfLkdldChpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpPcHRpb24qIEFwaTo6bXV0YWJsZV9vcHRpb25zKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuQXBpLm9wdGlvbnMpCisgIHJldHVybiBvcHRpb25zXy5NdXRhYmxlKGluZGV4KTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbiogQXBpOjphZGRfb3B0aW9ucygpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuQXBpLm9wdGlvbnMpCisgIHJldHVybiBvcHRpb25zXy5BZGQoKTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6T3B0aW9uID4qCitBcGk6Om11dGFibGVfb3B0aW9ucygpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuQXBpLm9wdGlvbnMpCisgIHJldHVybiAmb3B0aW9uc187Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbiA+JgorQXBpOjpvcHRpb25zKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuQXBpLm9wdGlvbnMpCisgIHJldHVybiBvcHRpb25zXzsKK30KKworLy8gb3B0aW9uYWwgc3RyaW5nIHZlcnNpb24gPSA0OworaW5saW5lIHZvaWQgQXBpOjpjbGVhcl92ZXJzaW9uKCkgeworICB2ZXJzaW9uXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgY29uc3QgOjpzdGQ6OnN0cmluZyYgQXBpOjp2ZXJzaW9uKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5BcGkudmVyc2lvbikKKyAgcmV0dXJuIHZlcnNpb25fLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIEFwaTo6c2V0X3ZlcnNpb24oY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgCisgIHZlcnNpb25fLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkFwaS52ZXJzaW9uKQorfQoraW5saW5lIHZvaWQgQXBpOjpzZXRfdmVyc2lvbihjb25zdCBjaGFyKiB2YWx1ZSkgeworICAKKyAgdmVyc2lvbl8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5BcGkudmVyc2lvbikKK30KK2lubGluZSB2b2lkIEFwaTo6c2V0X3ZlcnNpb24oY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIAorICB2ZXJzaW9uXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuQXBpLnZlcnNpb24pCit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogQXBpOjptdXRhYmxlX3ZlcnNpb24oKSB7CisgIAorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuQXBpLnZlcnNpb24pCisgIHJldHVybiB2ZXJzaW9uXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIEFwaTo6cmVsZWFzZV92ZXJzaW9uKCkgeworICAKKyAgcmV0dXJuIHZlcnNpb25fLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBBcGk6OnNldF9hbGxvY2F0ZWRfdmVyc2lvbig6OnN0ZDo6c3RyaW5nKiB2ZXJzaW9uKSB7CisgIGlmICh2ZXJzaW9uICE9IE5VTEwpIHsKKyAgICAKKyAgfSBlbHNlIHsKKyAgICAKKyAgfQorICB2ZXJzaW9uXy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmVyc2lvbik7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5BcGkudmVyc2lvbikKK30KKworLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0IHNvdXJjZV9jb250ZXh0ID0gNTsKK2lubGluZSBib29sIEFwaTo6aGFzX3NvdXJjZV9jb250ZXh0KCkgY29uc3QgeworICByZXR1cm4gIV9pc19kZWZhdWx0X2luc3RhbmNlXyAmJiBzb3VyY2VfY29udGV4dF8gIT0gTlVMTDsKK30KK2lubGluZSB2b2lkIEFwaTo6Y2xlYXJfc291cmNlX2NvbnRleHQoKSB7CisgIGlmIChHZXRBcmVuYU5vVmlydHVhbCgpID09IE5VTEwgJiYgc291cmNlX2NvbnRleHRfICE9IE5VTEwpIGRlbGV0ZSBzb3VyY2VfY29udGV4dF87CisgIHNvdXJjZV9jb250ZXh0XyA9IE5VTEw7Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb250ZXh0JiBBcGk6OnNvdXJjZV9jb250ZXh0KCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5BcGkuc291cmNlX2NvbnRleHQpCisgIHJldHVybiBzb3VyY2VfY29udGV4dF8gIT0gTlVMTCA/ICpzb3VyY2VfY29udGV4dF8gOiAqZGVmYXVsdF9pbnN0YW5jZV8tPnNvdXJjZV9jb250ZXh0XzsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvbnRleHQqIEFwaTo6bXV0YWJsZV9zb3VyY2VfY29udGV4dCgpIHsKKyAgCisgIGlmIChzb3VyY2VfY29udGV4dF8gPT0gTlVMTCkgeworICAgIHNvdXJjZV9jb250ZXh0XyA9IG5ldyA6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvbnRleHQ7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkFwaS5zb3VyY2VfY29udGV4dCkKKyAgcmV0dXJuIHNvdXJjZV9jb250ZXh0XzsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvbnRleHQqIEFwaTo6cmVsZWFzZV9zb3VyY2VfY29udGV4dCgpIHsKKyAgCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29udGV4dCogdGVtcCA9IHNvdXJjZV9jb250ZXh0XzsKKyAgc291cmNlX2NvbnRleHRfID0gTlVMTDsKKyAgcmV0dXJuIHRlbXA7Cit9CitpbmxpbmUgdm9pZCBBcGk6OnNldF9hbGxvY2F0ZWRfc291cmNlX2NvbnRleHQoOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb250ZXh0KiBzb3VyY2VfY29udGV4dCkgeworICBkZWxldGUgc291cmNlX2NvbnRleHRfOworICBzb3VyY2VfY29udGV4dF8gPSBzb3VyY2VfY29udGV4dDsKKyAgaWYgKHNvdXJjZV9jb250ZXh0KSB7CisgICAgCisgIH0gZWxzZSB7CisgICAgCisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkFwaS5zb3VyY2VfY29udGV4dCkKK30KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5NaXhpbiBtaXhpbnMgPSA2OworaW5saW5lIGludCBBcGk6Om1peGluc19zaXplKCkgY29uc3QgeworICByZXR1cm4gbWl4aW5zXy5zaXplKCk7Cit9CitpbmxpbmUgdm9pZCBBcGk6OmNsZWFyX21peGlucygpIHsKKyAgbWl4aW5zXy5DbGVhcigpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWl4aW4mIEFwaTo6bWl4aW5zKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5BcGkubWl4aW5zKQorICByZXR1cm4gbWl4aW5zXy5HZXQoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWl4aW4qIEFwaTo6bXV0YWJsZV9taXhpbnMoaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5BcGkubWl4aW5zKQorICByZXR1cm4gbWl4aW5zXy5NdXRhYmxlKGluZGV4KTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6Ok1peGluKiBBcGk6OmFkZF9taXhpbnMoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLkFwaS5taXhpbnMpCisgIHJldHVybiBtaXhpbnNfLkFkZCgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpNaXhpbiA+KgorQXBpOjptdXRhYmxlX21peGlucygpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuQXBpLm1peGlucykKKyAgcmV0dXJuICZtaXhpbnNfOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpNaXhpbiA+JgorQXBpOjptaXhpbnMoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5BcGkubWl4aW5zKQorICByZXR1cm4gbWl4aW5zXzsKK30KKworLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5TeW50YXggc3ludGF4ID0gNzsKK2lubGluZSB2b2lkIEFwaTo6Y2xlYXJfc3ludGF4KCkgeworICBzeW50YXhfID0gMDsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlN5bnRheCBBcGk6OnN5bnRheCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuQXBpLnN5bnRheCkKKyAgcmV0dXJuIHN0YXRpY19jYXN0PCA6Omdvb2dsZTo6cHJvdG9idWY6OlN5bnRheCA+KHN5bnRheF8pOworfQoraW5saW5lIHZvaWQgQXBpOjpzZXRfc3ludGF4KDo6Z29vZ2xlOjpwcm90b2J1Zjo6U3ludGF4IHZhbHVlKSB7CisgIAorICBzeW50YXhfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkFwaS5zeW50YXgpCit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gTWV0aG9kCisKKy8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKK2lubGluZSB2b2lkIE1ldGhvZDo6Y2xlYXJfbmFtZSgpIHsKKyAgbmFtZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIE1ldGhvZDo6bmFtZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuTWV0aG9kLm5hbWUpCisgIHJldHVybiBuYW1lXy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBNZXRob2Q6OnNldF9uYW1lKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIAorICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5NZXRob2QubmFtZSkKK30KK2lubGluZSB2b2lkIE1ldGhvZDo6c2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgCisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuTWV0aG9kLm5hbWUpCit9CitpbmxpbmUgdm9pZCBNZXRob2Q6OnNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICAKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZC5uYW1lKQorfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIE1ldGhvZDo6bXV0YWJsZV9uYW1lKCkgeworICAKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZC5uYW1lKQorICByZXR1cm4gbmFtZV8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBNZXRob2Q6OnJlbGVhc2VfbmFtZSgpIHsKKyAgCisgIHJldHVybiBuYW1lXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgTWV0aG9kOjpzZXRfYWxsb2NhdGVkX25hbWUoOjpzdGQ6OnN0cmluZyogbmFtZSkgeworICBpZiAobmFtZSAhPSBOVUxMKSB7CisgICAgCisgIH0gZWxzZSB7CisgICAgCisgIH0KKyAgbmFtZV8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIG5hbWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuTWV0aG9kLm5hbWUpCit9CisKKy8vIG9wdGlvbmFsIHN0cmluZyByZXF1ZXN0X3R5cGVfdXJsID0gMjsKK2lubGluZSB2b2lkIE1ldGhvZDo6Y2xlYXJfcmVxdWVzdF90eXBlX3VybCgpIHsKKyAgcmVxdWVzdF90eXBlX3VybF8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIE1ldGhvZDo6cmVxdWVzdF90eXBlX3VybCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuTWV0aG9kLnJlcXVlc3RfdHlwZV91cmwpCisgIHJldHVybiByZXF1ZXN0X3R5cGVfdXJsXy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBNZXRob2Q6OnNldF9yZXF1ZXN0X3R5cGVfdXJsKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIAorICByZXF1ZXN0X3R5cGVfdXJsXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5NZXRob2QucmVxdWVzdF90eXBlX3VybCkKK30KK2lubGluZSB2b2lkIE1ldGhvZDo6c2V0X3JlcXVlc3RfdHlwZV91cmwoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgCisgIHJlcXVlc3RfdHlwZV91cmxfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuTWV0aG9kLnJlcXVlc3RfdHlwZV91cmwpCit9CitpbmxpbmUgdm9pZCBNZXRob2Q6OnNldF9yZXF1ZXN0X3R5cGVfdXJsKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICAKKyAgcmVxdWVzdF90eXBlX3VybF8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZC5yZXF1ZXN0X3R5cGVfdXJsKQorfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIE1ldGhvZDo6bXV0YWJsZV9yZXF1ZXN0X3R5cGVfdXJsKCkgeworICAKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZC5yZXF1ZXN0X3R5cGVfdXJsKQorICByZXR1cm4gcmVxdWVzdF90eXBlX3VybF8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBNZXRob2Q6OnJlbGVhc2VfcmVxdWVzdF90eXBlX3VybCgpIHsKKyAgCisgIHJldHVybiByZXF1ZXN0X3R5cGVfdXJsXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgTWV0aG9kOjpzZXRfYWxsb2NhdGVkX3JlcXVlc3RfdHlwZV91cmwoOjpzdGQ6OnN0cmluZyogcmVxdWVzdF90eXBlX3VybCkgeworICBpZiAocmVxdWVzdF90eXBlX3VybCAhPSBOVUxMKSB7CisgICAgCisgIH0gZWxzZSB7CisgICAgCisgIH0KKyAgcmVxdWVzdF90eXBlX3VybF8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHJlcXVlc3RfdHlwZV91cmwpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuTWV0aG9kLnJlcXVlc3RfdHlwZV91cmwpCit9CisKKy8vIG9wdGlvbmFsIGJvb2wgcmVxdWVzdF9zdHJlYW1pbmcgPSAzOworaW5saW5lIHZvaWQgTWV0aG9kOjpjbGVhcl9yZXF1ZXN0X3N0cmVhbWluZygpIHsKKyAgcmVxdWVzdF9zdHJlYW1pbmdfID0gZmFsc2U7Cit9CitpbmxpbmUgYm9vbCBNZXRob2Q6OnJlcXVlc3Rfc3RyZWFtaW5nKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5NZXRob2QucmVxdWVzdF9zdHJlYW1pbmcpCisgIHJldHVybiByZXF1ZXN0X3N0cmVhbWluZ187Cit9CitpbmxpbmUgdm9pZCBNZXRob2Q6OnNldF9yZXF1ZXN0X3N0cmVhbWluZyhib29sIHZhbHVlKSB7CisgIAorICByZXF1ZXN0X3N0cmVhbWluZ18gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuTWV0aG9kLnJlcXVlc3Rfc3RyZWFtaW5nKQorfQorCisvLyBvcHRpb25hbCBzdHJpbmcgcmVzcG9uc2VfdHlwZV91cmwgPSA0OworaW5saW5lIHZvaWQgTWV0aG9kOjpjbGVhcl9yZXNwb25zZV90eXBlX3VybCgpIHsKKyAgcmVzcG9uc2VfdHlwZV91cmxfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBNZXRob2Q6OnJlc3BvbnNlX3R5cGVfdXJsKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5NZXRob2QucmVzcG9uc2VfdHlwZV91cmwpCisgIHJldHVybiByZXNwb25zZV90eXBlX3VybF8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgTWV0aG9kOjpzZXRfcmVzcG9uc2VfdHlwZV91cmwoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgCisgIHJlc3BvbnNlX3R5cGVfdXJsXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5NZXRob2QucmVzcG9uc2VfdHlwZV91cmwpCit9CitpbmxpbmUgdm9pZCBNZXRob2Q6OnNldF9yZXNwb25zZV90eXBlX3VybChjb25zdCBjaGFyKiB2YWx1ZSkgeworICAKKyAgcmVzcG9uc2VfdHlwZV91cmxfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuTWV0aG9kLnJlc3BvbnNlX3R5cGVfdXJsKQorfQoraW5saW5lIHZvaWQgTWV0aG9kOjpzZXRfcmVzcG9uc2VfdHlwZV91cmwoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIAorICByZXNwb25zZV90eXBlX3VybF8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZC5yZXNwb25zZV90eXBlX3VybCkKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBNZXRob2Q6Om11dGFibGVfcmVzcG9uc2VfdHlwZV91cmwoKSB7CisgIAorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuTWV0aG9kLnJlc3BvbnNlX3R5cGVfdXJsKQorICByZXR1cm4gcmVzcG9uc2VfdHlwZV91cmxfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogTWV0aG9kOjpyZWxlYXNlX3Jlc3BvbnNlX3R5cGVfdXJsKCkgeworICAKKyAgcmV0dXJuIHJlc3BvbnNlX3R5cGVfdXJsXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgTWV0aG9kOjpzZXRfYWxsb2NhdGVkX3Jlc3BvbnNlX3R5cGVfdXJsKDo6c3RkOjpzdHJpbmcqIHJlc3BvbnNlX3R5cGVfdXJsKSB7CisgIGlmIChyZXNwb25zZV90eXBlX3VybCAhPSBOVUxMKSB7CisgICAgCisgIH0gZWxzZSB7CisgICAgCisgIH0KKyAgcmVzcG9uc2VfdHlwZV91cmxfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCByZXNwb25zZV90eXBlX3VybCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5NZXRob2QucmVzcG9uc2VfdHlwZV91cmwpCit9CisKKy8vIG9wdGlvbmFsIGJvb2wgcmVzcG9uc2Vfc3RyZWFtaW5nID0gNTsKK2lubGluZSB2b2lkIE1ldGhvZDo6Y2xlYXJfcmVzcG9uc2Vfc3RyZWFtaW5nKCkgeworICByZXNwb25zZV9zdHJlYW1pbmdfID0gZmFsc2U7Cit9CitpbmxpbmUgYm9vbCBNZXRob2Q6OnJlc3BvbnNlX3N0cmVhbWluZygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuTWV0aG9kLnJlc3BvbnNlX3N0cmVhbWluZykKKyAgcmV0dXJuIHJlc3BvbnNlX3N0cmVhbWluZ187Cit9CitpbmxpbmUgdm9pZCBNZXRob2Q6OnNldF9yZXNwb25zZV9zdHJlYW1pbmcoYm9vbCB2YWx1ZSkgeworICAKKyAgcmVzcG9uc2Vfc3RyZWFtaW5nXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5NZXRob2QucmVzcG9uc2Vfc3RyZWFtaW5nKQorfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLk9wdGlvbiBvcHRpb25zID0gNjsKK2lubGluZSBpbnQgTWV0aG9kOjpvcHRpb25zX3NpemUoKSBjb25zdCB7CisgIHJldHVybiBvcHRpb25zXy5zaXplKCk7Cit9CitpbmxpbmUgdm9pZCBNZXRob2Q6OmNsZWFyX29wdGlvbnMoKSB7CisgIG9wdGlvbnNfLkNsZWFyKCk7Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpPcHRpb24mIE1ldGhvZDo6b3B0aW9ucyhpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuTWV0aG9kLm9wdGlvbnMpCisgIHJldHVybiBvcHRpb25zXy5HZXQoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6T3B0aW9uKiBNZXRob2Q6Om11dGFibGVfb3B0aW9ucyhpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZC5vcHRpb25zKQorICByZXR1cm4gb3B0aW9uc18uTXV0YWJsZShpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpPcHRpb24qIE1ldGhvZDo6YWRkX29wdGlvbnMoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZC5vcHRpb25zKQorICByZXR1cm4gb3B0aW9uc18uQWRkKCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbiA+KgorTWV0aG9kOjptdXRhYmxlX29wdGlvbnMoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZC5vcHRpb25zKQorICByZXR1cm4gJm9wdGlvbnNfOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpPcHRpb24gPiYKK01ldGhvZDo6b3B0aW9ucygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZC5vcHRpb25zKQorICByZXR1cm4gb3B0aW9uc187Cit9CisKKy8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuU3ludGF4IHN5bnRheCA9IDc7CitpbmxpbmUgdm9pZCBNZXRob2Q6OmNsZWFyX3N5bnRheCgpIHsKKyAgc3ludGF4XyA9IDA7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpTeW50YXggTWV0aG9kOjpzeW50YXgoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZC5zeW50YXgpCisgIHJldHVybiBzdGF0aWNfY2FzdDwgOjpnb29nbGU6OnByb3RvYnVmOjpTeW50YXggPihzeW50YXhfKTsKK30KK2lubGluZSB2b2lkIE1ldGhvZDo6c2V0X3N5bnRheCg6Omdvb2dsZTo6cHJvdG9idWY6OlN5bnRheCB2YWx1ZSkgeworICAKKyAgc3ludGF4XyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5NZXRob2Quc3ludGF4KQorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIE1peGluCisKKy8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKK2lubGluZSB2b2lkIE1peGluOjpjbGVhcl9uYW1lKCkgeworICBuYW1lXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgY29uc3QgOjpzdGQ6OnN0cmluZyYgTWl4aW46Om5hbWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLk1peGluLm5hbWUpCisgIHJldHVybiBuYW1lXy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBNaXhpbjo6c2V0X25hbWUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgCisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLk1peGluLm5hbWUpCit9CitpbmxpbmUgdm9pZCBNaXhpbjo6c2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgCisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuTWl4aW4ubmFtZSkKK30KK2lubGluZSB2b2lkIE1peGluOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgCisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5NaXhpbi5uYW1lKQorfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIE1peGluOjptdXRhYmxlX25hbWUoKSB7CisgIAorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuTWl4aW4ubmFtZSkKKyAgcmV0dXJuIG5hbWVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogTWl4aW46OnJlbGVhc2VfbmFtZSgpIHsKKyAgCisgIHJldHVybiBuYW1lXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgTWl4aW46OnNldF9hbGxvY2F0ZWRfbmFtZSg6OnN0ZDo6c3RyaW5nKiBuYW1lKSB7CisgIGlmIChuYW1lICE9IE5VTEwpIHsKKyAgICAKKyAgfSBlbHNlIHsKKyAgICAKKyAgfQorICBuYW1lXy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgbmFtZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5NaXhpbi5uYW1lKQorfQorCisvLyBvcHRpb25hbCBzdHJpbmcgcm9vdCA9IDI7CitpbmxpbmUgdm9pZCBNaXhpbjo6Y2xlYXJfcm9vdCgpIHsKKyAgcm9vdF8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIE1peGluOjpyb290KCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5NaXhpbi5yb290KQorICByZXR1cm4gcm9vdF8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgTWl4aW46OnNldF9yb290KGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIAorICByb290Xy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5NaXhpbi5yb290KQorfQoraW5saW5lIHZvaWQgTWl4aW46OnNldF9yb290KGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIAorICByb290Xy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLk1peGluLnJvb3QpCit9CitpbmxpbmUgdm9pZCBNaXhpbjo6c2V0X3Jvb3QoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIAorICByb290Xy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuTWl4aW4ucm9vdCkKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBNaXhpbjo6bXV0YWJsZV9yb290KCkgeworICAKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLk1peGluLnJvb3QpCisgIHJldHVybiByb290Xy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIE1peGluOjpyZWxlYXNlX3Jvb3QoKSB7CisgIAorICByZXR1cm4gcm9vdF8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIE1peGluOjpzZXRfYWxsb2NhdGVkX3Jvb3QoOjpzdGQ6OnN0cmluZyogcm9vdCkgeworICBpZiAocm9vdCAhPSBOVUxMKSB7CisgICAgCisgIH0gZWxzZSB7CisgICAgCisgIH0KKyAgcm9vdF8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHJvb3QpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuTWl4aW4ucm9vdCkKK30KKworI2VuZGlmICAvLyAhUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworCisvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobmFtZXNwYWNlX3Njb3BlKQorCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGdsb2JhbF9zY29wZSkKKworI2VuZGlmICAvLyBQUk9UT0JVRl9nb29nbGVfMmZwcm90b2J1Zl8yZmFwaV8yZXByb3RvX19JTkNMVURFRApkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9hcGkucHJvdG8gYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2FwaS5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kYmU4N2I4Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9hcGkucHJvdG8KQEAgLTAsMCArMSwyMDIgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitzeW50YXggPSAicHJvdG8zIjsKKworcGFja2FnZSBnb29nbGUucHJvdG9idWY7CisKK2ltcG9ydCAiZ29vZ2xlL3Byb3RvYnVmL3NvdXJjZV9jb250ZXh0LnByb3RvIjsKK2ltcG9ydCAiZ29vZ2xlL3Byb3RvYnVmL3R5cGUucHJvdG8iOworCitvcHRpb24gY3NoYXJwX25hbWVzcGFjZSA9ICJHb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlwZXMiOworb3B0aW9uIGphdmFfcGFja2FnZSA9ICJjb20uZ29vZ2xlLnByb3RvYnVmIjsKK29wdGlvbiBqYXZhX291dGVyX2NsYXNzbmFtZSA9ICJBcGlQcm90byI7CitvcHRpb24gamF2YV9tdWx0aXBsZV9maWxlcyA9IHRydWU7CitvcHRpb24gamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2ggPSB0cnVlOworb3B0aW9uIG9iamNfY2xhc3NfcHJlZml4ID0gIkdQQiI7CisKKy8vIEFwaSBpcyBhIGxpZ2h0LXdlaWdodCBkZXNjcmlwdG9yIGZvciBhIHByb3RvY29sIGJ1ZmZlciBzZXJ2aWNlLgorbWVzc2FnZSBBcGkgeworCisgIC8vIFRoZSBmdWxseSBxdWFsaWZpZWQgbmFtZSBvZiB0aGlzIGFwaSwgaW5jbHVkaW5nIHBhY2thZ2UgbmFtZQorICAvLyBmb2xsb3dlZCBieSB0aGUgYXBpJ3Mgc2ltcGxlIG5hbWUuCisgIHN0cmluZyBuYW1lID0gMTsKKworICAvLyBUaGUgbWV0aG9kcyBvZiB0aGlzIGFwaSwgaW4gdW5zcGVjaWZpZWQgb3JkZXIuCisgIHJlcGVhdGVkIE1ldGhvZCBtZXRob2RzID0gMjsKKworICAvLyBBbnkgbWV0YWRhdGEgYXR0YWNoZWQgdG8gdGhlIEFQSS4KKyAgcmVwZWF0ZWQgT3B0aW9uIG9wdGlvbnMgPSAzOworCisgIC8vIEEgdmVyc2lvbiBzdHJpbmcgZm9yIHRoaXMgYXBpLiBJZiBzcGVjaWZpZWQsIG11c3QgaGF2ZSB0aGUgZm9ybQorICAvLyBgbWFqb3ItdmVyc2lvbi5taW5vci12ZXJzaW9uYCwgYXMgaW4gYDEuMTBgLiBJZiB0aGUgbWlub3IgdmVyc2lvbgorICAvLyBpcyBvbWl0dGVkLCBpdCBkZWZhdWx0cyB0byB6ZXJvLiBJZiB0aGUgZW50aXJlIHZlcnNpb24gZmllbGQgaXMKKyAgLy8gZW1wdHksIHRoZSBtYWpvciB2ZXJzaW9uIGlzIGRlcml2ZWQgZnJvbSB0aGUgcGFja2FnZSBuYW1lLCBhcworICAvLyBvdXRsaW5lZCBiZWxvdy4gSWYgdGhlIGZpZWxkIGlzIG5vdCBlbXB0eSwgdGhlIHZlcnNpb24gaW4gdGhlCisgIC8vIHBhY2thZ2UgbmFtZSB3aWxsIGJlIHZlcmlmaWVkIHRvIGJlIGNvbnNpc3RlbnQgd2l0aCB3aGF0IGlzCisgIC8vIHByb3ZpZGVkIGhlcmUuCisgIC8vCisgIC8vIFRoZSB2ZXJzaW9uaW5nIHNjaGVtYSB1c2VzIFtzZW1hbnRpYworICAvLyB2ZXJzaW9uaW5nXShodHRwOi8vc2VtdmVyLm9yZykgd2hlcmUgdGhlIG1ham9yIHZlcnNpb24gbnVtYmVyCisgIC8vIGluZGljYXRlcyBhIGJyZWFraW5nIGNoYW5nZSBhbmQgdGhlIG1pbm9yIHZlcnNpb24gYW4gYWRkaXRpdmUsCisgIC8vIG5vbi1icmVha2luZyBjaGFuZ2UuIEJvdGggdmVyc2lvbiBudW1iZXJzIGFyZSBzaWduYWxzIHRvIHVzZXJzCisgIC8vIHdoYXQgdG8gZXhwZWN0IGZyb20gZGlmZmVyZW50IHZlcnNpb25zLCBhbmQgc2hvdWxkIGJlIGNhcmVmdWxseQorICAvLyBjaG9zZW4gYmFzZWQgb24gdGhlIHByb2R1Y3QgcGxhbi4KKyAgLy8KKyAgLy8gVGhlIG1ham9yIHZlcnNpb24gaXMgYWxzbyByZWZsZWN0ZWQgaW4gdGhlIHBhY2thZ2UgbmFtZSBvZiB0aGUKKyAgLy8gQVBJLCB3aGljaCBtdXN0IGVuZCBpbiBgdjxtYWpvci12ZXJzaW9uPmAsIGFzIGluCisgIC8vIGBnb29nbGUuZmVhdHVyZS52MWAuIEZvciBtYWpvciB2ZXJzaW9ucyAwIGFuZCAxLCB0aGUgc3VmZml4IGNhbgorICAvLyBiZSBvbWl0dGVkLiBaZXJvIG1ham9yIHZlcnNpb25zIG11c3Qgb25seSBiZSB1c2VkIGZvcgorICAvLyBleHBlcmltZW50YWwsIG5vbmUtR0EgYXBpcy4KKyAgLy8KKyAgLy8KKyAgc3RyaW5nIHZlcnNpb24gPSA0OworCisgIC8vIFNvdXJjZSBjb250ZXh0IGZvciB0aGUgcHJvdG9jb2wgYnVmZmVyIHNlcnZpY2UgcmVwcmVzZW50ZWQgYnkgdGhpcworICAvLyBtZXNzYWdlLgorICBTb3VyY2VDb250ZXh0IHNvdXJjZV9jb250ZXh0ID0gNTsKKworICAvLyBJbmNsdWRlZCBBUElzLiBTZWUgW01peGluXVtdLgorICByZXBlYXRlZCBNaXhpbiBtaXhpbnMgPSA2OworCisgIC8vIFRoZSBzb3VyY2Ugc3ludGF4IG9mIHRoZSBzZXJ2aWNlLgorICBTeW50YXggc3ludGF4ID0gNzsKK30KKworLy8gTWV0aG9kIHJlcHJlc2VudHMgYSBtZXRob2Qgb2YgYW4gYXBpLgorbWVzc2FnZSBNZXRob2QgeworCisgIC8vIFRoZSBzaW1wbGUgbmFtZSBvZiB0aGlzIG1ldGhvZC4KKyAgc3RyaW5nIG5hbWUgPSAxOworCisgIC8vIEEgVVJMIG9mIHRoZSBpbnB1dCBtZXNzYWdlIHR5cGUuCisgIHN0cmluZyByZXF1ZXN0X3R5cGVfdXJsID0gMjsKKworICAvLyBJZiB0cnVlLCB0aGUgcmVxdWVzdCBpcyBzdHJlYW1lZC4KKyAgYm9vbCByZXF1ZXN0X3N0cmVhbWluZyA9IDM7CisKKyAgLy8gVGhlIFVSTCBvZiB0aGUgb3V0cHV0IG1lc3NhZ2UgdHlwZS4KKyAgc3RyaW5nIHJlc3BvbnNlX3R5cGVfdXJsID0gNDsKKworICAvLyBJZiB0cnVlLCB0aGUgcmVzcG9uc2UgaXMgc3RyZWFtZWQuCisgIGJvb2wgcmVzcG9uc2Vfc3RyZWFtaW5nID0gNTsKKworICAvLyBBbnkgbWV0YWRhdGEgYXR0YWNoZWQgdG8gdGhlIG1ldGhvZC4KKyAgcmVwZWF0ZWQgT3B0aW9uIG9wdGlvbnMgPSA2OworCisgIC8vIFRoZSBzb3VyY2Ugc3ludGF4IG9mIHRoaXMgbWV0aG9kLgorICBTeW50YXggc3ludGF4ID0gNzsKK30KKworLy8gRGVjbGFyZXMgYW4gQVBJIHRvIGJlIGluY2x1ZGVkIGluIHRoaXMgQVBJLiBUaGUgaW5jbHVkaW5nIEFQSSBtdXN0CisvLyByZWRlY2xhcmUgYWxsIHRoZSBtZXRob2RzIGZyb20gdGhlIGluY2x1ZGVkIEFQSSwgYnV0IGRvY3VtZW50YXRpb24KKy8vIGFuZCBvcHRpb25zIGFyZSBpbmhlcml0ZWQgYXMgZm9sbG93czoKKy8vCisvLyAtIElmIGFmdGVyIGNvbW1lbnQgYW5kIHdoaXRlc3BhY2Ugc3RyaXBwaW5nLCB0aGUgZG9jdW1lbnRhdGlvbgorLy8gICBzdHJpbmcgb2YgdGhlIHJlZGVjbGFyZWQgbWV0aG9kIGlzIGVtcHR5LCBpdCB3aWxsIGJlIGluaGVyaXRlZAorLy8gICBmcm9tIHRoZSBvcmlnaW5hbCBtZXRob2QuCisvLworLy8gLSBFYWNoIGFubm90YXRpb24gYmVsb25naW5nIHRvIHRoZSBzZXJ2aWNlIGNvbmZpZyAoaHR0cCwKKy8vICAgdmlzaWJpbGl0eSkgd2hpY2ggaXMgbm90IHNldCBpbiB0aGUgcmVkZWNsYXJlZCBtZXRob2Qgd2lsbCBiZQorLy8gICBpbmhlcml0ZWQuCisvLworLy8gLSBJZiBhbiBodHRwIGFubm90YXRpb24gaXMgaW5oZXJpdGVkLCB0aGUgcGF0aCBwYXR0ZXJuIHdpbGwgYmUKKy8vICAgbW9kaWZpZWQgYXMgZm9sbG93cy4gQW55IHZlcnNpb24gcHJlZml4IHdpbGwgYmUgcmVwbGFjZWQgYnkgdGhlCisvLyAgIHZlcnNpb24gb2YgdGhlIGluY2x1ZGluZyBBUEkgcGx1cyB0aGUgW3Jvb3RdW10gcGF0aCBpZiBzcGVjaWZpZWQuCisvLworLy8gRXhhbXBsZSBvZiBhIHNpbXBsZSBtaXhpbjoKKy8vCisvLyAgICAgcGFja2FnZSBnb29nbGUuYWNsLnYxOworLy8gICAgIHNlcnZpY2UgQWNjZXNzQ29udHJvbCB7CisvLyAgICAgICAvLyBHZXQgdGhlIHVuZGVybHlpbmcgQUNMIG9iamVjdC4KKy8vICAgICAgIHJwYyBHZXRBY2woR2V0QWNsUmVxdWVzdCkgcmV0dXJucyAoQWNsKSB7CisvLyAgICAgICAgIG9wdGlvbiAoZ29vZ2xlLmFwaS5odHRwKS5nZXQgPSAiL3YxL3tyZXNvdXJjZT0qKn06Z2V0QWNsIjsKKy8vICAgICAgIH0KKy8vICAgICB9CisvLworLy8gICAgIHBhY2thZ2UgZ29vZ2xlLnN0b3JhZ2UudjI7CisvLyAgICAgc2VydmljZSBTdG9yYWdlIHsKKy8vICAgICAgIHJwYyBHZXRBY2woR2V0QWNsUmVxdWVzdCkgcmV0dXJucyAoQWNsKTsKKy8vCisvLyAgICAgICAvLyBHZXQgYSBkYXRhIHJlY29yZC4KKy8vICAgICAgIHJwYyBHZXREYXRhKEdldERhdGFSZXF1ZXN0KSByZXR1cm5zIChEYXRhKSB7CisvLyAgICAgICAgIG9wdGlvbiAoZ29vZ2xlLmFwaS5odHRwKS5nZXQgPSAiL3YyL3tyZXNvdXJjZT0qKn0iOworLy8gICAgICAgfQorLy8gICAgIH0KKy8vCisvLyBFeGFtcGxlIG9mIGEgbWl4aW4gY29uZmlndXJhdGlvbjoKKy8vCisvLyAgICAgYXBpczoKKy8vICAgICAtIG5hbWU6IGdvb2dsZS5zdG9yYWdlLnYyLlN0b3JhZ2UKKy8vICAgICAgIG1peGluczoKKy8vICAgICAgIC0gbmFtZTogZ29vZ2xlLmFjbC52MS5BY2Nlc3NDb250cm9sCisvLworLy8gVGhlIG1peGluIGNvbnN0cnVjdCBpbXBsaWVzIHRoYXQgYWxsIG1ldGhvZHMgaW4gYEFjY2Vzc0NvbnRyb2xgIGFyZQorLy8gYWxzbyBkZWNsYXJlZCB3aXRoIHNhbWUgbmFtZSBhbmQgcmVxdWVzdC9yZXNwb25zZSB0eXBlcyBpbgorLy8gYFN0b3JhZ2VgLiBBIGRvY3VtZW50YXRpb24gZ2VuZXJhdG9yIG9yIGFubm90YXRpb24gcHJvY2Vzc29yIHdpbGwKKy8vIHNlZSB0aGUgZWZmZWN0aXZlIGBTdG9yYWdlLkdldEFjbGAgbWV0aG9kIGFmdGVyIGluaGVydGluZworLy8gZG9jdW1lbnRhdGlvbiBhbmQgYW5ub3RhdGlvbnMgYXMgZm9sbG93czoKKy8vCisvLyAgICAgc2VydmljZSBTdG9yYWdlIHsKKy8vICAgICAgIC8vIEdldCB0aGUgdW5kZXJseWluZyBBQ0wgb2JqZWN0LgorLy8gICAgICAgcnBjIEdldEFjbChHZXRBY2xSZXF1ZXN0KSByZXR1cm5zIChBY2wpIHsKKy8vICAgICAgICAgb3B0aW9uIChnb29nbGUuYXBpLmh0dHApLmdldCA9ICIvdjIve3Jlc291cmNlPSoqfTpnZXRBY2wiOworLy8gICAgICAgfQorLy8gICAgICAgLi4uCisvLyAgICAgfQorLy8KKy8vIE5vdGUgaG93IHRoZSB2ZXJzaW9uIGluIHRoZSBwYXRoIHBhdHRlcm4gY2hhbmdlZCBmcm9tIGB2MWAgdG8gYHYyYC4KKy8vCisvLyBJZiB0aGUgYHJvb3RgIGZpZWxkIGluIHRoZSBtaXhpbiBpcyBzcGVjaWZpZWQsIGl0IHNob3VsZCBiZSBhCisvLyByZWxhdGl2ZSBwYXRoIHVuZGVyIHdoaWNoIGluaGVyaXRlZCBIVFRQIHBhdGhzIGFyZSBwbGFjZWQuIEV4YW1wbGU6CisvLworLy8gICAgIGFwaXM6CisvLyAgICAgLSBuYW1lOiBnb29nbGUuc3RvcmFnZS52Mi5TdG9yYWdlCisvLyAgICAgICBtaXhpbnM6CisvLyAgICAgICAtIG5hbWU6IGdvb2dsZS5hY2wudjEuQWNjZXNzQ29udHJvbAorLy8gICAgICAgICByb290OiBhY2xzCisvLworLy8gVGhpcyBpbXBsaWVzIHRoZSBmb2xsb3dpbmcgaW5oZXJpdGVkIEhUVFAgYW5ub3RhdGlvbjoKKy8vCisvLyAgICAgc2VydmljZSBTdG9yYWdlIHsKKy8vICAgICAgIC8vIEdldCB0aGUgdW5kZXJseWluZyBBQ0wgb2JqZWN0LgorLy8gICAgICAgcnBjIEdldEFjbChHZXRBY2xSZXF1ZXN0KSByZXR1cm5zIChBY2wpIHsKKy8vICAgICAgICAgb3B0aW9uIChnb29nbGUuYXBpLmh0dHApLmdldCA9ICIvdjIvYWNscy97cmVzb3VyY2U9Kip9OmdldEFjbCI7CisvLyAgICAgICB9CisvLyAgICAgICAuLi4KKy8vICAgICB9CittZXNzYWdlIE1peGluIHsKKyAgLy8gVGhlIGZ1bGx5IHF1YWxpZmllZCBuYW1lIG9mIHRoZSBBUEkgd2hpY2ggaXMgaW5jbHVkZWQuCisgIHN0cmluZyBuYW1lID0gMTsKKworICAvLyBJZiBub24tZW1wdHkgc3BlY2lmaWVzIGEgcGF0aCB1bmRlciB3aGljaCBpbmhlcml0ZWQgSFRUUCBwYXRocworICAvLyBhcmUgcm9vdGVkLgorICBzdHJpbmcgcm9vdCA9IDI7Cit9CmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2FyZW5hLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9hcmVuYS5jYwpuZXcgZmlsZSBtb2RlIDEwMDc1NQppbmRleCAwMDAwMDAwLi5jZDBiMjFhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9hcmVuYS5jYwpAQCAtMCwwICsxLDMwNiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvYXJlbmEuaD4KKworI2lmZGVmIEFERFJFU1NfU0FOSVRJWkVSCisjaW5jbHVkZSA8c2FuaXRpemVyL2FzYW5faW50ZXJmYWNlLmg+CisjZW5kaWYKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCitnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6U2VxdWVuY2VOdW1iZXIgQXJlbmE6OmxpZmVjeWNsZV9pZF9nZW5lcmF0b3JfOworI2lmIGRlZmluZWQoR09PR0xFX1BST1RPQlVGX05PX1RIUkVBRExPQ0FMKQorQXJlbmE6OlRocmVhZENhY2hlJiBBcmVuYTo6dGhyZWFkX2NhY2hlKCkgeworICBzdGF0aWMgaW50ZXJuYWw6OlRocmVhZExvY2FsU3RvcmFnZTxUaHJlYWRDYWNoZT4qIHRocmVhZF9jYWNoZV8gPQorICAgICAgbmV3IGludGVybmFsOjpUaHJlYWRMb2NhbFN0b3JhZ2U8VGhyZWFkQ2FjaGU+KCk7CisgIHJldHVybiAqdGhyZWFkX2NhY2hlXy0+R2V0KCk7Cit9CisjZWxpZiBkZWZpbmVkKFBST1RPQlVGX1VTRV9ETExTKQorQXJlbmE6OlRocmVhZENhY2hlJiBBcmVuYTo6dGhyZWFkX2NhY2hlKCkgeworICBzdGF0aWMgR09PR0xFX1RIUkVBRF9MT0NBTCBUaHJlYWRDYWNoZSB0aHJlYWRfY2FjaGVfID0geyAtMSwgTlVMTCB9OworICByZXR1cm4gdGhyZWFkX2NhY2hlXzsKK30KKyNlbHNlCitHT09HTEVfVEhSRUFEX0xPQ0FMIEFyZW5hOjpUaHJlYWRDYWNoZSBBcmVuYTo6dGhyZWFkX2NhY2hlXyA9IHsgLTEsIE5VTEwgfTsKKyNlbmRpZgorCit2b2lkIEFyZW5hOjpJbml0KCkgeworICBsaWZlY3ljbGVfaWRfID0gbGlmZWN5Y2xlX2lkX2dlbmVyYXRvcl8uR2V0TmV4dCgpOworICBibG9ja3NfID0gMDsKKyAgaGludF8gPSAwOworICBvd25zX2ZpcnN0X2Jsb2NrXyA9IHRydWU7CisgIGNsZWFudXBfbGlzdF8gPSAwOworCisgIGlmIChvcHRpb25zXy5pbml0aWFsX2Jsb2NrICE9IE5VTEwgJiYgb3B0aW9uc18uaW5pdGlhbF9ibG9ja19zaXplID4gMCkgeworICAgIEdPT0dMRV9DSEVDS19HRShvcHRpb25zXy5pbml0aWFsX2Jsb2NrX3NpemUsIHNpemVvZihCbG9jaykpCisgICAgICAgIDw8ICI6IEluaXRpYWwgYmxvY2sgc2l6ZSB0b28gc21hbGwgZm9yIGhlYWRlci4iOworCisgICAgLy8gQWRkIGZpcnN0IHVub3duZWQgYmxvY2sgdG8gbGlzdC4KKyAgICBCbG9jayogZmlyc3RfYmxvY2sgPSByZWludGVycHJldF9jYXN0PEJsb2NrKj4ob3B0aW9uc18uaW5pdGlhbF9ibG9jayk7CisgICAgZmlyc3RfYmxvY2stPnNpemUgPSBvcHRpb25zXy5pbml0aWFsX2Jsb2NrX3NpemU7CisgICAgZmlyc3RfYmxvY2stPnBvcyA9IGtIZWFkZXJTaXplOworICAgIGZpcnN0X2Jsb2NrLT5uZXh0ID0gTlVMTDsKKyAgICAvLyBUaHJlYWQgd2hpY2ggY2FsbHMgSW5pdCgpIG93bnMgdGhlIGZpcnN0IGJsb2NrLiBUaGlzIGFsbG93cyB0aGUKKyAgICAvLyBzaW5nbGUtdGhyZWFkZWQgY2FzZSB0byBhbGxvY2F0ZSBvbiB0aGUgZmlyc3QgYmxvY2sgd2l0aG91dCB0YWtpbmcgYW55CisgICAgLy8gbG9ja3MuCisgICAgZmlyc3RfYmxvY2stPm93bmVyID0gJnRocmVhZF9jYWNoZSgpOworICAgIFNldFRocmVhZENhY2hlQmxvY2soZmlyc3RfYmxvY2spOworICAgIEFkZEJsb2NrSW50ZXJuYWwoZmlyc3RfYmxvY2spOworICAgIG93bnNfZmlyc3RfYmxvY2tfID0gZmFsc2U7CisgIH0KKworICAvLyBDYWxsIHRoZSBpbml0aWFsaXphdGlvbiBob29rCisgIGlmIChvcHRpb25zXy5vbl9hcmVuYV9pbml0ICE9IE5VTEwpIHsKKyAgICBob29rc19jb29raWVfID0gb3B0aW9uc18ub25fYXJlbmFfaW5pdCh0aGlzKTsKKyAgfSBlbHNlIHsKKyAgICBob29rc19jb29raWVfID0gTlVMTDsKKyAgfQorfQorCitBcmVuYTo6fkFyZW5hKCkgeworICB1aW50NjQgc3BhY2VfYWxsb2NhdGVkID0gUmVzZXRJbnRlcm5hbCgpOworCisgIC8vIENhbGwgdGhlIGRlc3RydWN0aW9uIGhvb2sKKyAgaWYgKG9wdGlvbnNfLm9uX2FyZW5hX2Rlc3RydWN0aW9uICE9IE5VTEwpIHsKKyAgICBvcHRpb25zXy5vbl9hcmVuYV9kZXN0cnVjdGlvbih0aGlzLCBob29rc19jb29raWVfLCBzcGFjZV9hbGxvY2F0ZWQpOworICB9Cit9CisKK3VpbnQ2NCBBcmVuYTo6UmVzZXQoKSB7CisgIC8vIEludmFsaWRhdGUgYW55IFRocmVhZENhY2hlcyBwb2ludGluZyB0byBhbnkgYmxvY2tzIHdlIGp1c3QgZGVzdHJveWVkLgorICBsaWZlY3ljbGVfaWRfID0gbGlmZWN5Y2xlX2lkX2dlbmVyYXRvcl8uR2V0TmV4dCgpOworICByZXR1cm4gUmVzZXRJbnRlcm5hbCgpOworfQorCit1aW50NjQgQXJlbmE6OlJlc2V0SW50ZXJuYWwoKSB7CisgIENsZWFudXBMaXN0KCk7CisgIHVpbnQ2NCBzcGFjZV9hbGxvY2F0ZWQgPSBGcmVlQmxvY2tzKCk7CisKKyAgLy8gQ2FsbCB0aGUgcmVzZXQgaG9vaworICBpZiAob3B0aW9uc18ub25fYXJlbmFfcmVzZXQgIT0gTlVMTCkgeworICAgIG9wdGlvbnNfLm9uX2FyZW5hX3Jlc2V0KHRoaXMsIGhvb2tzX2Nvb2tpZV8sIHNwYWNlX2FsbG9jYXRlZCk7CisgIH0KKworICByZXR1cm4gc3BhY2VfYWxsb2NhdGVkOworfQorCitBcmVuYTo6QmxvY2sqIEFyZW5hOjpOZXdCbG9jayh2b2lkKiBtZSwgQmxvY2sqIG15X2xhc3RfYmxvY2ssIHNpemVfdCBuLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IHN0YXJ0X2Jsb2NrX3NpemUsIHNpemVfdCBtYXhfYmxvY2tfc2l6ZSkgeworICBzaXplX3Qgc2l6ZTsKKyAgaWYgKG15X2xhc3RfYmxvY2sgIT0gTlVMTCkgeworICAgIC8vIERvdWJsZSB0aGUgY3VycmVudCBibG9jayBzaXplLCB1cCB0byBhIGxpbWl0LgorICAgIHNpemUgPSAyICogKG15X2xhc3RfYmxvY2stPnNpemUpOworICAgIGlmIChzaXplID4gbWF4X2Jsb2NrX3NpemUpIHNpemUgPSBtYXhfYmxvY2tfc2l6ZTsKKyAgfSBlbHNlIHsKKyAgICBzaXplID0gc3RhcnRfYmxvY2tfc2l6ZTsKKyAgfQorICBpZiAobiA+IHNpemUgLSBrSGVhZGVyU2l6ZSkgeworICAgIC8vIFRPRE8oc2FuamF5KTogQ2hlY2sgaWYgbiArIGtIZWFkZXJTaXplIHdvdWxkIG92ZXJmbG93CisgICAgc2l6ZSA9IGtIZWFkZXJTaXplICsgbjsKKyAgfQorCisgIEJsb2NrKiBiID0gcmVpbnRlcnByZXRfY2FzdDxCbG9jayo+KG9wdGlvbnNfLmJsb2NrX2FsbG9jKHNpemUpKTsKKyAgYi0+cG9zID0ga0hlYWRlclNpemUgKyBuOworICBiLT5zaXplID0gc2l6ZTsKKyAgaWYgKGItPmF2YWlsKCkgPT0gMCkgeworICAgIC8vIERvIG5vdCBhdHRlbXB0IHRvIHJldXNlIHRoaXMgYmxvY2suCisgICAgYi0+b3duZXIgPSBOVUxMOworICB9IGVsc2UgeworICAgIGItPm93bmVyID0gbWU7CisgIH0KKyNpZmRlZiBBRERSRVNTX1NBTklUSVpFUgorICAvLyBQb2lzb24gdGhlIHJlc3Qgb2YgdGhlIGJsb2NrIGZvciBBU0FOLiBJdCB3YXMgdW5wb2lzb25lZCBieSB0aGUgdW5kZXJseWluZworICAvLyBtYWxsb2MgYnV0IGl0J3Mgbm90IHlldCB1c2FibGUgdW50aWwgd2UgcmV0dXJuIGl0IGFzIHBhcnQgb2YgYW4gYWxsb2NhdGlvbi4KKyAgQVNBTl9QT0lTT05fTUVNT1JZX1JFR0lPTigKKyAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8Y2hhcio+KGIpICsgYi0+cG9zLCBiLT5zaXplIC0gYi0+cG9zKTsKKyNlbmRpZgorICByZXR1cm4gYjsKK30KKwordm9pZCBBcmVuYTo6QWRkQmxvY2soQmxvY2sqIGIpIHsKKyAgTXV0ZXhMb2NrIGwoJmJsb2Nrc19sb2NrXyk7CisgIEFkZEJsb2NrSW50ZXJuYWwoYik7Cit9CisKK3ZvaWQgQXJlbmE6OkFkZEJsb2NrSW50ZXJuYWwoQmxvY2sqIGIpIHsKKyAgYi0+bmV4dCA9IHJlaW50ZXJwcmV0X2Nhc3Q8QmxvY2sqPihnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6Tm9CYXJyaWVyX0xvYWQoJmJsb2Nrc18pKTsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlJlbGVhc2VfU3RvcmUoJmJsb2Nrc18sIHJlaW50ZXJwcmV0X2Nhc3Q8Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkF0b21pY1dvcmQ+KGIpKTsKKyAgaWYgKGItPmF2YWlsKCkgIT0gMCkgeworICAgIC8vIERpcmVjdCBmdXR1cmUgYWxsb2NhdGlvbnMgdG8gdGhpcyBibG9jay4KKyAgICBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6UmVsZWFzZV9TdG9yZSgmaGludF8sIHJlaW50ZXJwcmV0X2Nhc3Q8Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkF0b21pY1dvcmQ+KGIpKTsKKyAgfQorfQorCit2b2lkIEFyZW5hOjpBZGRMaXN0Tm9kZSh2b2lkKiBlbGVtLCB2b2lkICgqY2xlYW51cCkodm9pZCopKSB7CisgIE5vZGUqIG5vZGUgPSByZWludGVycHJldF9jYXN0PE5vZGUqPihBbGxvY2F0ZUFsaWduZWQoc2l6ZW9mKE5vZGUpKSk7CisgIG5vZGUtPmVsZW0gPSBlbGVtOworICBub2RlLT5jbGVhbnVwID0gY2xlYW51cDsKKyAgbm9kZS0+bmV4dCA9IHJlaW50ZXJwcmV0X2Nhc3Q8Tm9kZSo+KAorICAgICAgZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6Ok5vQmFycmllcl9BdG9taWNFeGNoYW5nZSgmY2xlYW51cF9saXN0XywKKyAgICAgICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkF0b21pY1dvcmQ+KG5vZGUpKSk7Cit9CisKK3ZvaWQqIEFyZW5hOjpBbGxvY2F0ZUFsaWduZWQoY29uc3Qgc3RkOjp0eXBlX2luZm8qIGFsbG9jYXRlZCwgc2l6ZV90IG4pIHsKKyAgLy8gQWxpZ24gbiB0byBuZXh0IG11bHRpcGxlIG9mIDggKGZyb20gSGFja2VyJ3MgRGVsaWdodCwgQ2hhcHRlciAzLikKKyAgbiA9IChuICsgNykgJiAtODsKKworICAvLyBNb25pdG9yIGFsbG9jYXRpb24gaWYgbmVlZGVkLgorICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoaG9va3NfY29va2llXyAhPSBOVUxMKSAmJgorICAgICAgb3B0aW9uc18ub25fYXJlbmFfYWxsb2NhdGlvbiAhPSBOVUxMKSB7CisgICAgb3B0aW9uc18ub25fYXJlbmFfYWxsb2NhdGlvbihhbGxvY2F0ZWQsIG4sIGhvb2tzX2Nvb2tpZV8pOworICB9CisKKyAgLy8gSWYgdGhpcyB0aHJlYWQgYWxyZWFkeSBvd25zIGEgYmxvY2sgaW4gdGhpcyBhcmVuYSB0aGVuIHRyeSB0byB1c2UgdGhhdC4KKyAgLy8gVGhpcyBmYXN0IHBhdGggb3B0aW1pemVzIHRoZSBjYXNlIHdoZXJlIG11bHRpcGxlIHRocmVhZHMgYWxsb2NhdGUgZnJvbSB0aGUKKyAgLy8gc2FtZSBhcmVuYS4KKyAgaWYgKHRocmVhZF9jYWNoZSgpLmxhc3RfbGlmZWN5Y2xlX2lkX3NlZW4gPT0gbGlmZWN5Y2xlX2lkXyAmJgorICAgICAgdGhyZWFkX2NhY2hlKCkubGFzdF9ibG9ja191c2VkXyAhPSBOVUxMKSB7CisgICAgaWYgKHRocmVhZF9jYWNoZSgpLmxhc3RfYmxvY2tfdXNlZF8tPmF2YWlsKCkgPCBuKSB7CisgICAgICByZXR1cm4gU2xvd0FsbG9jKG4pOworICAgIH0KKyAgICByZXR1cm4gQWxsb2NGcm9tQmxvY2sodGhyZWFkX2NhY2hlKCkubGFzdF9ibG9ja191c2VkXywgbik7CisgIH0KKworICAvLyBDaGVjayB3aGV0aGVyIHdlIG93biB0aGUgbGFzdCBhY2Nlc3NlZCBibG9jayBvbiB0aGlzIGFyZW5hLgorICAvLyBUaGlzIGZhc3QgcGF0aCBvcHRpbWl6ZXMgdGhlIGNhc2Ugd2hlcmUgYSBzaW5nbGUgdGhyZWFkIHVzZXMgbXVsdGlwbGUKKyAgLy8gYXJlbmFzLgorICB2b2lkKiBtZSA9ICZ0aHJlYWRfY2FjaGUoKTsKKyAgQmxvY2sqIGIgPSByZWludGVycHJldF9jYXN0PEJsb2NrKj4oZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFjcXVpcmVfTG9hZCgmaGludF8pKTsKKyAgaWYgKCFiIHx8IGItPm93bmVyICE9IG1lIHx8IGItPmF2YWlsKCkgPCBuKSB7CisgICAgcmV0dXJuIFNsb3dBbGxvYyhuKTsKKyAgfQorICByZXR1cm4gQWxsb2NGcm9tQmxvY2soYiwgbik7Cit9CisKK3ZvaWQqIEFyZW5hOjpBbGxvY0Zyb21CbG9jayhCbG9jayogYiwgc2l6ZV90IG4pIHsKKyAgc2l6ZV90IHAgPSBiLT5wb3M7CisgIGItPnBvcyA9IHAgKyBuOworI2lmZGVmIEFERFJFU1NfU0FOSVRJWkVSCisgIEFTQU5fVU5QT0lTT05fTUVNT1JZX1JFR0lPTihyZWludGVycHJldF9jYXN0PGNoYXIqPihiKSArIHAsIG4pOworI2VuZGlmCisgIHJldHVybiByZWludGVycHJldF9jYXN0PGNoYXIqPihiKSArIHA7Cit9CisKK3ZvaWQqIEFyZW5hOjpTbG93QWxsb2Moc2l6ZV90IG4pIHsKKyAgdm9pZCogbWUgPSAmdGhyZWFkX2NhY2hlKCk7CisgIEJsb2NrKiBiID0gRmluZEJsb2NrKG1lKTsgIC8vIEZpbmQgYmxvY2sgb3duZWQgYnkgbWUuCisgIC8vIFNlZSBpZiBhbGxvY2F0aW9uIGZpdHMgaW4gbXkgbGF0ZXN0IGJsb2NrLgorICBpZiAoYiAhPSBOVUxMICYmIGItPmF2YWlsKCkgPj0gbikgeworICAgIFNldFRocmVhZENhY2hlQmxvY2soYik7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6Ok5vQmFycmllcl9TdG9yZSgmaGludF8sIHJlaW50ZXJwcmV0X2Nhc3Q8Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkF0b21pY1dvcmQ+KGIpKTsKKyAgICByZXR1cm4gQWxsb2NGcm9tQmxvY2soYiwgbik7CisgIH0KKyAgYiA9IE5ld0Jsb2NrKG1lLCBiLCBuLCBvcHRpb25zXy5zdGFydF9ibG9ja19zaXplLCBvcHRpb25zXy5tYXhfYmxvY2tfc2l6ZSk7CisgIEFkZEJsb2NrKGIpOworICBpZiAoYi0+b3duZXIgPT0gbWUpIHsgIC8vIElmIHRoaXMgYmxvY2sgY2FuIGJlIHJldXNlZCAoc2VlIE5ld0Jsb2NrKCkpLgorICAgIFNldFRocmVhZENhY2hlQmxvY2soYik7CisgIH0KKyAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8Y2hhcio+KGIpICsga0hlYWRlclNpemU7Cit9CisKK3VpbnQ2NCBBcmVuYTo6U3BhY2VBbGxvY2F0ZWQoKSBjb25zdCB7CisgIHVpbnQ2NCBzcGFjZV9hbGxvY2F0ZWQgPSAwOworICBCbG9jayogYiA9IHJlaW50ZXJwcmV0X2Nhc3Q8QmxvY2sqPihnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6Tm9CYXJyaWVyX0xvYWQoJmJsb2Nrc18pKTsKKyAgd2hpbGUgKGIgIT0gTlVMTCkgeworICAgIHNwYWNlX2FsbG9jYXRlZCArPSAoYi0+c2l6ZSk7CisgICAgYiA9IGItPm5leHQ7CisgIH0KKyAgcmV0dXJuIHNwYWNlX2FsbG9jYXRlZDsKK30KKwordWludDY0IEFyZW5hOjpTcGFjZVVzZWQoKSBjb25zdCB7CisgIHVpbnQ2NCBzcGFjZV91c2VkID0gMDsKKyAgQmxvY2sqIGIgPSByZWludGVycHJldF9jYXN0PEJsb2NrKj4oZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6Ok5vQmFycmllcl9Mb2FkKCZibG9ja3NfKSk7CisgIHdoaWxlIChiICE9IE5VTEwpIHsKKyAgICBzcGFjZV91c2VkICs9IChiLT5wb3MgLSBrSGVhZGVyU2l6ZSk7CisgICAgYiA9IGItPm5leHQ7CisgIH0KKyAgcmV0dXJuIHNwYWNlX3VzZWQ7Cit9CisKK3VpbnQ2NCBBcmVuYTo6RnJlZUJsb2NrcygpIHsKKyAgdWludDY0IHNwYWNlX2FsbG9jYXRlZCA9IDA7CisgIEJsb2NrKiBiID0gcmVpbnRlcnByZXRfY2FzdDxCbG9jayo+KGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpOb0JhcnJpZXJfTG9hZCgmYmxvY2tzXykpOworICBCbG9jayogZmlyc3RfYmxvY2sgPSBOVUxMOworICB3aGlsZSAoYiAhPSBOVUxMKSB7CisgICAgc3BhY2VfYWxsb2NhdGVkICs9IChiLT5zaXplKTsKKyAgICBCbG9jayogbmV4dCA9IGItPm5leHQ7CisgICAgaWYgKG5leHQgIT0gTlVMTCkgeworICAgICAgb3B0aW9uc18uYmxvY2tfZGVhbGxvYyhiLCBiLT5zaXplKTsKKyAgICB9IGVsc2UgeworICAgICAgaWYgKG93bnNfZmlyc3RfYmxvY2tfKSB7CisgICAgICAgIG9wdGlvbnNfLmJsb2NrX2RlYWxsb2MoYiwgYi0+c2l6ZSk7CisgICAgICB9IGVsc2UgeworICAgICAgICAvLyBVc2VyIHBhc3NlZCBpbiB0aGUgZmlyc3QgYmxvY2ssIHNraXAgZnJlZSdpbmcgdGhlIG1lbW9yeS4KKyAgICAgICAgZmlyc3RfYmxvY2sgPSBiOworICAgICAgfQorICAgIH0KKyAgICBiID0gbmV4dDsKKyAgfQorICBibG9ja3NfID0gMDsKKyAgaGludF8gPSAwOworICBpZiAoIW93bnNfZmlyc3RfYmxvY2tfKSB7CisgICAgLy8gTWFrZSB0aGUgZmlyc3QgYmxvY2sgdGhhdCB3YXMgcGFzc2VkIGluIHRocm91Z2ggQXJlbmFPcHRpb25zCisgICAgLy8gYXZhaWxhYmxlIGZvciByZXVzZS4KKyAgICBmaXJzdF9ibG9jay0+cG9zID0ga0hlYWRlclNpemU7CisgICAgLy8gVGhyZWFkIHdoaWNoIGNhbGxzIFJlc2V0KCkgb3ducyB0aGUgZmlyc3QgYmxvY2suIFRoaXMgYWxsb3dzIHRoZQorICAgIC8vIHNpbmdsZS10aHJlYWRlZCBjYXNlIHRvIGFsbG9jYXRlIG9uIHRoZSBmaXJzdCBibG9jayB3aXRob3V0IHRha2luZyBhbnkKKyAgICAvLyBsb2Nrcy4KKyAgICBmaXJzdF9ibG9jay0+b3duZXIgPSAmdGhyZWFkX2NhY2hlKCk7CisgICAgU2V0VGhyZWFkQ2FjaGVCbG9jayhmaXJzdF9ibG9jayk7CisgICAgQWRkQmxvY2tJbnRlcm5hbChmaXJzdF9ibG9jayk7CisgIH0KKyAgcmV0dXJuIHNwYWNlX2FsbG9jYXRlZDsKK30KKwordm9pZCBBcmVuYTo6Q2xlYW51cExpc3QoKSB7CisgIE5vZGUqIGhlYWQgPQorICAgICAgcmVpbnRlcnByZXRfY2FzdDxOb2RlKj4oZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6Ok5vQmFycmllcl9Mb2FkKCZjbGVhbnVwX2xpc3RfKSk7CisgIHdoaWxlIChoZWFkICE9IE5VTEwpIHsKKyAgICBoZWFkLT5jbGVhbnVwKGhlYWQtPmVsZW0pOworICAgIGhlYWQgPSBoZWFkLT5uZXh0OworICB9CisgIGNsZWFudXBfbGlzdF8gPSAwOworfQorCitBcmVuYTo6QmxvY2sqIEFyZW5hOjpGaW5kQmxvY2sodm9pZCogbWUpIHsKKyAgLy8gVE9ETyhzYW5qYXkpOiBXZSBtaWdodCB3YW50IHRvIGtlZXAgYSBzZXBhcmF0ZSBsaXN0IHdpdGggb25lCisgIC8vIGVudHJ5IHBlciB0aHJlYWQuCisgIEJsb2NrKiBiID0gcmVpbnRlcnByZXRfY2FzdDxCbG9jayo+KGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBY3F1aXJlX0xvYWQoJmJsb2Nrc18pKTsKKyAgd2hpbGUgKGIgIT0gTlVMTCAmJiBiLT5vd25lciAhPSBtZSkgeworICAgIGIgPSBiLT5uZXh0OworICB9CisgIHJldHVybiBiOworfQorCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvYXJlbmEuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvYXJlbmEuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YWQ5NGZhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9hcmVuYS5oCkBAIC0wLDAgKzEsOTE1IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQVJFTkFfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9BUkVOQV9IX18KKworI2luY2x1ZGUgPGxpbWl0cz4KKyNpZmRlZiBtYXgKKyN1bmRlZiBtYXggIC8vIFZpc3VhbCBTdHVkaW8gZGVmaW5lcyB0aGlzIG1hY3JvCisjZW5kaWYKKyNpZiBfX2NwbHVzcGx1cyA+PSAyMDExMDNMCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3R5cGVfdHJhaXRzLmg+CisjZW5kaWYKKyNpZiBkZWZpbmVkKF9NU0NfVkVSKSAmJiAhX0hBU19FWENFUFRJT05TCisvLyBXb3JrIGFyb3VuZCBidWdzIGluIE1TVkMgPHR5cGVpbmZvPiBoZWFkZXIgd2hlbiBfSEFTX0VYQ0VQVElPTlM9MC4KKyNpbmNsdWRlIDxleGNlcHRpb24+CisjaW5jbHVkZSA8dHlwZWluZm8+CituYW1lc3BhY2Ugc3RkIHsKK3VzaW5nIHR5cGVfaW5mbyA9IDo6dHlwZV9pbmZvOworfQorI2Vsc2UKKyNpbmNsdWRlIDx0eXBlaW5mbz4KKyNlbmRpZgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY19zZXF1ZW5jZV9udW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9sb2dnaW5nLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL211dGV4Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3R5cGVfdHJhaXRzLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworY2xhc3MgQXJlbmE7ICAgICAgIC8vIGRlZmluZWQgYmVsb3cKK2NsYXNzIE1lc3NhZ2U7ICAgICAvLyBtZXNzYWdlLmgKKworbmFtZXNwYWNlIGludGVybmFsIHsKK2NsYXNzIEFyZW5hU3RyaW5nOyAvLyBhcmVuYXN0cmluZy5oCitjbGFzcyBMYXp5RmllbGQ7ICAgLy8gbGF6eV9maWVsZC5oCisKK3RlbXBsYXRlPHR5cGVuYW1lIFR5cGU+CitjbGFzcyBHZW5lcmljVHlwZUhhbmRsZXI7IC8vIHJlcGVhdGVkX2ZpZWxkLmgKKworLy8gVGVtcGxhdGVkIGNsZWFudXAgbWV0aG9kcy4KK3RlbXBsYXRlPHR5cGVuYW1lIFQ+IHZvaWQgYXJlbmFfZGVzdHJ1Y3Rfb2JqZWN0KHZvaWQqIG9iamVjdCkgeworICByZWludGVycHJldF9jYXN0PFQqPihvYmplY3QpLT5+VCgpOworfQordGVtcGxhdGU8dHlwZW5hbWUgVD4gdm9pZCBhcmVuYV9kZWxldGVfb2JqZWN0KHZvaWQqIG9iamVjdCkgeworICBkZWxldGUgcmVpbnRlcnByZXRfY2FzdDxUKj4ob2JqZWN0KTsKK30KK2lubGluZSB2b2lkIGFyZW5hX2ZyZWUodm9pZCogb2JqZWN0LCBzaXplX3QgLyogc2l6ZSAqLykgeworICBmcmVlKG9iamVjdCk7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorCisvLyBBcmVuYU9wdGlvbnMgcHJvdmlkZXMgb3B0aW9uYWwgYWRkaXRpb25hbCBwYXJhbWV0ZXJzIHRvIGFyZW5hIGNvbnN0cnVjdGlvbgorLy8gdGhhdCBjb250cm9sIGl0cyBibG9jay1hbGxvY2F0aW9uIGJlaGF2aW9yLgorc3RydWN0IEFyZW5hT3B0aW9ucyB7CisgIC8vIFRoaXMgZGVmaW5lcyB0aGUgc2l6ZSBvZiB0aGUgZmlyc3QgYmxvY2sgcmVxdWVzdGVkIGZyb20gdGhlIHN5c3RlbSBtYWxsb2MuCisgIC8vIFN1YnNlcXVlbnQgYmxvY2sgc2l6ZXMgd2lsbCBpbmNyZWFzZSBpbiBhIGdlb21ldHJpYyBzZXJpZXMgdXAgdG8gYSBtYXhpbXVtLgorICBzaXplX3Qgc3RhcnRfYmxvY2tfc2l6ZTsKKworICAvLyBUaGlzIGRlZmluZXMgdGhlIG1heGltdW0gYmxvY2sgc2l6ZSByZXF1ZXN0ZWQgZnJvbSBzeXN0ZW0gbWFsbG9jICh1bmxlc3MgYW4KKyAgLy8gaW5kaXZpZHVhbCBhcmVuYSBhbGxvY2F0aW9uIHJlcXVlc3Qgb2NjdXJzIHdpdGggYSBzaXplIGxhcmdlciB0aGFuIHRoaXMKKyAgLy8gbWF4aW11bSkuIFJlcXVlc3RlZCBibG9jayBzaXplcyBpbmNyZWFzZSB1cCB0byB0aGlzIHZhbHVlLCB0aGVuIHJlbWFpbgorICAvLyBoZXJlLgorICBzaXplX3QgbWF4X2Jsb2NrX3NpemU7CisKKyAgLy8gQW4gaW5pdGlhbCBibG9jayBvZiBtZW1vcnkgZm9yIHRoZSBhcmVuYSB0byB1c2UsIG9yIE5VTEwgZm9yIG5vbmUuIElmCisgIC8vIHByb3ZpZGVkLCB0aGUgYmxvY2sgbXVzdCBsaXZlIGF0IGxlYXN0IGFzIGxvbmcgYXMgdGhlIGFyZW5hIGl0c2VsZi4gVGhlCisgIC8vIGNyZWF0b3Igb2YgdGhlIEFyZW5hIHJldGFpbnMgb3duZXJzaGlwIG9mIHRoZSBibG9jayBhZnRlciB0aGUgQXJlbmEgaXMKKyAgLy8gZGVzdHJveWVkLgorICBjaGFyKiBpbml0aWFsX2Jsb2NrOworCisgIC8vIFRoZSBzaXplIG9mIHRoZSBpbml0aWFsIGJsb2NrLCBpZiBwcm92aWRlZC4KKyAgc2l6ZV90IGluaXRpYWxfYmxvY2tfc2l6ZTsKKworICAvLyBBIGZ1bmN0aW9uIHBvaW50ZXIgdG8gYW4gYWxsb2MgbWV0aG9kIHRoYXQgcmV0dXJucyBtZW1vcnkgYmxvY2tzIG9mIHNpemUKKyAgLy8gcmVxdWVzdGVkLiBCeSBkZWZhdWx0LCBpdCBjb250YWlucyBhIHB0ciB0byB0aGUgbWFsbG9jIGZ1bmN0aW9uLgorICAvLworICAvLyBOT1RFOiBibG9ja19hbGxvYyBhbmQgZGVhbGxvYyBmdW5jdGlvbnMgYXJlIGV4cGVjdGVkIHRvIGJlaGF2ZSBsaWtlCisgIC8vIG1hbGxvYyBhbmQgZnJlZSwgaW5jbHVkaW5nIEFzYW4gcG9pc29uaW5nLgorICB2b2lkKiAoKmJsb2NrX2FsbG9jKShzaXplX3QpOworICAvLyBBIGZ1bmN0aW9uIHBvaW50ZXIgdG8gYSBkZWFsbG9jIG1ldGhvZCB0aGF0IHRha2VzIG93bmVyc2hpcCBvZiB0aGUgYmxvY2tzCisgIC8vIGZyb20gdGhlIGFyZW5hLiBCeSBkZWZhdWx0LCBpdCBjb250YWlucyBhIHB0ciB0byBhIHdyYXBwZXIgZnVuY3Rpb24gdGhhdAorICAvLyBjYWxscyBmcmVlLgorICB2b2lkICgqYmxvY2tfZGVhbGxvYykodm9pZCosIHNpemVfdCk7CisKKyAgLy8gSG9va3MgZm9yIGFkZGluZyBleHRlcm5hbCBmdW5jdGlvbmFsaXR5IHN1Y2ggYXMgdXNlci1zcGVjaWZpYyBtZXRyaWNzCisgIC8vIGNvbGxlY3Rpb24sIHNwZWNpZmljIGRlYnVnZ2luZyBhYmlsaXRpZXMsIGV0Yy4KKyAgLy8gSW5pdCBob29rIG1heSByZXR1cm4gYSBwb2ludGVyIHRvIGEgY29va2llIHRvIGJlIHN0b3JlZCBpbiB0aGUgYXJlbmEuCisgIC8vIHJlc2V0IGFuZCBkZXN0cnVjdGlvbiBob29rcyB3aWxsIHRoZW4gYmUgY2FsbGVkIHdpdGggdGhlIHNhbWUgY29va2llCisgIC8vIHBvaW50ZXIuIFRoaXMgYWxsb3dzIHVzIHRvIHNhdmUgYW4gZXh0ZXJuYWwgb2JqZWN0IHBlciBhcmVuYSBpbnN0YW5jZSBhbmQKKyAgLy8gdXNlIGl0IG9uIHRoZSBvdGhlciBob29rcyAoTm90ZTogSXQgaXMganVzdCBhcyBsZWdhbCBmb3IgaW5pdCB0byByZXR1cm4KKyAgLy8gTlVMTCBhbmQgbm90IHVzZSB0aGUgY29va2llIGZlYXR1cmUpLgorICAvLyBvbl9hcmVuYV9yZXNldCBhbmQgb25fYXJlbmFfZGVzdHJ1Y3Rpb24gYWxzbyByZWNlaXZlIHRoZSBzcGFjZSB1c2VkIGluCisgIC8vIHRoZSBhcmVuYSBqdXN0IGJlZm9yZSB0aGUgcmVzZXQuCisgIHZvaWQqICgqb25fYXJlbmFfaW5pdCkoQXJlbmEqIGFyZW5hKTsKKyAgdm9pZCAoKm9uX2FyZW5hX3Jlc2V0KShBcmVuYSogYXJlbmEsIHZvaWQqIGNvb2tpZSwgdWludDY0IHNwYWNlX3VzZWQpOworICB2b2lkICgqb25fYXJlbmFfZGVzdHJ1Y3Rpb24pKEFyZW5hKiBhcmVuYSwgdm9pZCogY29va2llLCB1aW50NjQgc3BhY2VfdXNlZCk7CisKKyAgLy8gdHlwZV9pbmZvIGlzIHByb21pc2VkIHRvIGJlIHN0YXRpYyAtIGl0cyBsaWZldGltZSBleHRlbmRzIHRvCisgIC8vIG1hdGNoIHByb2dyYW0ncyBsaWZldGltZSAoSXQgaXMgZ2l2ZW4gYnkgdHlwZWlkIG9wZXJhdG9yKS4KKyAgLy8gTm90ZTogdHlwZWlkKHZvaWQpIHdpbGwgYmUgcGFzc2VkIGFzIGFsbG9jYXRlZF90eXBlIGV2ZXJ5IHRpbWUgd2UKKyAgLy8gaW50ZW50aW9uYWxseSB3YW50IHRvIGF2b2lkIG1vbml0b3JpbmcgYW4gYWxsb2NhdGlvbi4gKGkuZS4gaW50ZXJuYWwKKyAgLy8gYWxsb2NhdGlvbnMgZm9yIG1hbmFnaW5nIHRoZSBhcmVuYSkKKyAgdm9pZCAoKm9uX2FyZW5hX2FsbG9jYXRpb24pKGNvbnN0IHN0ZDo6dHlwZV9pbmZvKiBhbGxvY2F0ZWRfdHlwZSwKKyAgICAgIHVpbnQ2NCBhbGxvY19zaXplLCB2b2lkKiBjb29raWUpOworCisgIEFyZW5hT3B0aW9ucygpCisgICAgICA6IHN0YXJ0X2Jsb2NrX3NpemUoa0RlZmF1bHRTdGFydEJsb2NrU2l6ZSksCisgICAgICAgIG1heF9ibG9ja19zaXplKGtEZWZhdWx0TWF4QmxvY2tTaXplKSwKKyAgICAgICAgaW5pdGlhbF9ibG9jayhOVUxMKSwKKyAgICAgICAgaW5pdGlhbF9ibG9ja19zaXplKDApLAorICAgICAgICBibG9ja19hbGxvYygmbWFsbG9jKSwKKyAgICAgICAgYmxvY2tfZGVhbGxvYygmaW50ZXJuYWw6OmFyZW5hX2ZyZWUpLAorICAgICAgICBvbl9hcmVuYV9pbml0KE5VTEwpLAorICAgICAgICBvbl9hcmVuYV9yZXNldChOVUxMKSwKKyAgICAgICAgb25fYXJlbmFfZGVzdHJ1Y3Rpb24oTlVMTCksCisgICAgICAgIG9uX2FyZW5hX2FsbG9jYXRpb24oTlVMTCkge30KKworIHByaXZhdGU6CisgIC8vIENvbnN0YW50cyBkZWZpbmUgZGVmYXVsdCBzdGFydGluZyBibG9jayBzaXplIGFuZCBtYXggYmxvY2sgc2l6ZSBmb3IKKyAgLy8gYXJlbmEgYWxsb2NhdG9yIGJlaGF2aW9yIC0tIHNlZSBkZXNjcmlwdGlvbnMgYWJvdmUuCisgIHN0YXRpYyBjb25zdCBzaXplX3Qga0RlZmF1bHRTdGFydEJsb2NrU2l6ZSA9IDI1NjsKKyAgc3RhdGljIGNvbnN0IHNpemVfdCBrRGVmYXVsdE1heEJsb2NrU2l6ZSAgID0gODE5MjsKK307CisKKy8vIFN1cHBvcnQgZm9yIG5vbi1SVFRJIGVudmlyb25tZW50cy4gKFRoZSBtZXRyaWNzIGhvb2tzIEFQSSB1c2VzIHR5cGUKKy8vIGluZm9ybWF0aW9uLikKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX05PX1JUVEkKKyNkZWZpbmUgUlRUSV9UWVBFX0lEKHR5cGUpICgmdHlwZWlkKHR5cGUpKQorI2Vsc2UKKyNkZWZpbmUgUlRUSV9UWVBFX0lEKHR5cGUpIChOVUxMKQorI2VuZGlmCisKKy8vIEFyZW5hIGFsbG9jYXRvci4gQXJlbmEgYWxsb2NhdGlvbiByZXBsYWNlcyBvcmRpbmFyeSAoaGVhcC1iYXNlZCkgYWxsb2NhdGlvbgorLy8gd2l0aCBuZXcvZGVsZXRlLCBhbmQgaW1wcm92ZXMgcGVyZm9ybWFuY2UgYnkgYWdncmVnYXRpbmcgYWxsb2NhdGlvbnMgaW50bworLy8gbGFyZ2VyIGJsb2NrcyBhbmQgZnJlZWluZyBhbGxvY2F0aW9ucyBhbGwgYXQgb25jZS4gUHJvdG9jb2wgbWVzc2FnZXMgYXJlCisvLyBhbGxvY2F0ZWQgb24gYW4gYXJlbmEgYnkgdXNpbmcgQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VD4oQXJlbmEqKSwgYmVsb3csIGFuZAorLy8gYXJlIGF1dG9tYXRpY2FsbHkgZnJlZWQgd2hlbiB0aGUgYXJlbmEgaXMgZGVzdHJveWVkLgorLy8KKy8vIFRoaXMgaXMgYSB0aHJlYWQtc2FmZSBpbXBsZW1lbnRhdGlvbjogbXVsdGlwbGUgdGhyZWFkcyBtYXkgYWxsb2NhdGUgZnJvbSB0aGUKKy8vIGFyZW5hIGNvbmN1cnJlbnRseS4gRGVzdHJ1Y3Rpb24gaXMgbm90IHRocmVhZC1zYWZlIGFuZCB0aGUgZGVzdHJ1Y3RpbmcKKy8vIHRocmVhZCBtdXN0IHN5bmNocm9uaXplIHdpdGggdXNlcnMgb2YgdGhlIGFyZW5hIGZpcnN0LgorLy8KKy8vIEFuIGFyZW5hIHByb3ZpZGVzIHR3byBhbGxvY2F0aW9uIGludGVyZmFjZXM6IENyZWF0ZU1lc3NhZ2U8VD4sIHdoaWNoIHdvcmtzCisvLyBmb3IgYXJlbmEtZW5hYmxlZCBwcm90bzIgbWVzc2FnZSB0eXBlcyBhcyB3ZWxsIGFzIG90aGVyIHR5cGVzIHRoYXQgc2F0aXNmeQorLy8gdGhlIGFwcHJvcHJpYXRlIHByb3RvY29sIChkZXNjcmliZWQgYmVsb3cpLCBhbmQgQ3JlYXRlPFQ+LCB3aGljaCB3b3JrcyBmb3IKKy8vIGFueSBhcmJpdHJhcnkgdHlwZSBULiBDcmVhdGVNZXNzYWdlPFQ+IGlzIGJldHRlciB3aGVuIHRoZSB0eXBlIFQgc3VwcG9ydHMgaXQsCisvLyBiZWNhdXNlIHRoaXMgaW50ZXJmYWNlIChpKSBwYXNzZXMgdGhlIGFyZW5hIHBvaW50ZXIgdG8gdGhlIGNyZWF0ZWQgb2JqZWN0IHNvCisvLyB0aGF0IGl0cyBzdWItb2JqZWN0cyBhbmQgaW50ZXJuYWwgYWxsb2NhdGlvbnMgY2FuIHVzZSB0aGUgYXJlbmEgdG9vLCBhbmQgKGlpKQorLy8gZWxpZGVzIHRoZSBvYmplY3QncyBkZXN0cnVjdG9yIGNhbGwgd2hlbiBwb3NzaWJsZS4gQ3JlYXRlPFQ+IGRvZXMgbm90IHBsYWNlCisvLyBhbnkgc3BlY2lhbCByZXF1aXJlbWVudHMgb24gdGhlIHR5cGUgVCwgYW5kIHdpbGwgaW52b2tlIHRoZSBvYmplY3QncworLy8gZGVzdHJ1Y3RvciB3aGVuIHRoZSBhcmVuYSBpcyBkZXN0cm95ZWQuCisvLworLy8gVGhlIGFyZW5hIG1lc3NhZ2UgYWxsb2NhdGlvbiBwcm90b2NvbCwgcmVxdWlyZWQgYnkgQ3JlYXRlTWVzc2FnZTxUPiwgaXMgYXMKKy8vIGZvbGxvd3M6CisvLworLy8gLSBUaGUgdHlwZSBUIG11c3QgaGF2ZSAoYXQgbGVhc3QpIHR3byBjb25zdHJ1Y3RvcnM6IGEgY29uc3RydWN0b3Igd2l0aCBubworLy8gICBhcmd1bWVudHMsIGNhbGxlZCB3aGVuIGEgVCBpcyBhbGxvY2F0ZWQgb24gdGhlIGhlYXA7IGFuZCBhIGNvbnN0cnVjdG9yIHdpdGgKKy8vICAgYSBnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJndW1lbnQsIGNhbGxlZCB3aGVuIGEgVCBpcyBhbGxvY2F0ZWQgb24gYW4gYXJlbmEuIElmIHRoZQorLy8gICBzZWNvbmQgY29uc3RydWN0b3IgaXMgY2FsbGVkIHdpdGggYSBOVUxMIGFyZW5hIHBvaW50ZXIsIGl0IG11c3QgYmUKKy8vICAgZXF1aXZhbGVudCB0byBpbnZva2luZyB0aGUgZmlyc3QgKG5vLWFyZ3VtZW50KSBjb25zdHJ1Y3Rvci4KKy8vCisvLyAtIFRoZSB0eXBlIFQgbXVzdCBoYXZlIGEgcGFydGljdWxhciB0eXBlIHRyYWl0OiBhIG5lc3RlZCB0eXBlCisvLyAgIHxJbnRlcm5hbEFyZW5hQ29uc3RydWN0YWJsZV98LiBUaGlzIGlzIHVzdWFsbHkgYSB0eXBlZGVmIHRvIHx2b2lkfC4gSWYgbm8KKy8vICAgc3VjaCB0eXBlIHRyYWl0IGV4aXN0cywgdGhlbiB0aGUgaW5zdGFudGlhdGlvbiBDcmVhdGVNZXNzYWdlPFQ+IHdpbGwgZmFpbAorLy8gICB0byBjb21waWxlLgorLy8KKy8vIC0gVGhlIHR5cGUgVCAqbWF5KiBoYXZlIHRoZSB0eXBlIHRyYWl0IHxEZXN0cnVjdG9yU2tpcHBhYmxlX3wuIElmIHRoaXMgdHlwZQorLy8gICB0cmFpdCBpcyBwcmVzZW50IGluIHRoZSB0eXBlLCB0aGVuIGl0cyBkZXN0cnVjdG9yIHdpbGwgbm90IGJlIGNhbGxlZCBpZiBhbmQKKy8vICAgb25seSBpZiBpdCB3YXMgcGFzc2VkIGEgbm9uLU5VTEwgYXJlbmEgcG9pbnRlci4gSWYgdGhpcyB0eXBlIHRyYWl0IGlzIG5vdAorLy8gICBwcmVzZW50IG9uIHRoZSB0eXBlLCB0aGVuIGl0cyBkZXN0cnVjdG9yIGlzIGFsd2F5cyBjYWxsZWQgd2hlbiB0aGUKKy8vICAgY29udGFpbmluZyBhcmVuYSBpcyBkZXN0cm95ZWQuCisvLworLy8gLSBPbmUtIGFuZCB0d28tdXNlci1hcmd1bWVudCBmb3JtcyBvZiBDcmVhdGVNZXNzYWdlPFQ+KCkgYWxzbyBleGlzdCB0aGF0CisvLyAgIGZvcndhcmQgdGhlc2UgY29uc3RydWN0b3IgYXJndW1lbnRzIHRvIFQncyBjb25zdHJ1Y3RvcjogZm9yIGV4YW1wbGUsCisvLyAgIENyZWF0ZU1lc3NhZ2U8VD4oQXJlbmEqLCBhcmcxLCBhcmcyKSBmb3J3YXJkcyB0byBhIGNvbnN0cnVjdG9yIFQoQXJlbmEqLAorLy8gICBhcmcxLCBhcmcyKS4KKy8vCisvLyBUaGlzIHByb3RvY29sIGlzIGltcGxlbWVudGVkIGJ5IGFsbCBhcmVuYS1lbmFibGVkIHByb3RvMiBtZXNzYWdlIGNsYXNzZXMgYXMKKy8vIHdlbGwgYXMgUmVwZWF0ZWRQdHJGaWVsZC4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBBcmVuYSB7CisgcHVibGljOgorICAvLyBBcmVuYSBjb25zdHJ1Y3RvciB0YWtpbmcgY3VzdG9tIG9wdGlvbnMuIFNlZSBBcmVuYU9wdGlvbnMgYmVsb3cgZm9yCisgIC8vIGRlc2NyaXB0aW9ucyBvZiB0aGUgb3B0aW9ucyBhdmFpbGFibGUuCisgIGV4cGxpY2l0IEFyZW5hKGNvbnN0IEFyZW5hT3B0aW9ucyYgb3B0aW9ucykgOiBvcHRpb25zXyhvcHRpb25zKSB7CisgICAgSW5pdCgpOworICB9CisKKyAgLy8gRGVmYXVsdCBjb25zdHJ1Y3RvciB3aXRoIHNlbnNpYmxlIGRlZmF1bHQgb3B0aW9ucywgdHVuZWQgZm9yIGF2ZXJhZ2UKKyAgLy8gdXNlLWNhc2VzLgorICBBcmVuYSgpIHsKKyAgICBJbml0KCk7CisgIH0KKworICAvLyBEZXN0cnVjdG9yIGRlbGV0ZXMgYWxsIG93bmVkIGhlYXAgYWxsb2NhdGVkIG9iamVjdHMsIGFuZCBkZXN0cnVjdHMgb2JqZWN0cworICAvLyB0aGF0IGhhdmUgbm9uLXRyaXZpYWwgZGVzdHJ1Y3RvcnMsIGV4Y2VwdCBmb3IgcHJvdG8yIG1lc3NhZ2Ugb2JqZWN0cyB3aG9zZQorICAvLyBkZXN0cnVjdG9ycyBjYW4gYmUgc2tpcHBlZC4gQWxzbywgZnJlZXMgYWxsIGJsb2NrcyBleGNlcHQgdGhlIGluaXRpYWwgYmxvY2sKKyAgLy8gaWYgaXQgd2FzIHBhc3NlZCBpbi4KKyAgfkFyZW5hKCk7CisKKyAgLy8gQVBJIHRvIGNyZWF0ZSBwcm90bzIgbWVzc2FnZSBvYmplY3RzIG9uIHRoZSBhcmVuYS4gSWYgdGhlIGFyZW5hIHBhc3NlZCBpbgorICAvLyBpcyBOVUxMLCB0aGVuIGEgaGVhcCBhbGxvY2F0ZWQgb2JqZWN0IGlzIHJldHVybmVkLiBUeXBlIFQgbXVzdCBiZSBhIG1lc3NhZ2UKKyAgLy8gZGVmaW5lZCBpbiBhIC5wcm90byBmaWxlIHdpdGggY2NfZW5hYmxlX2FyZW5hcyBzZXQgdG8gdHJ1ZSwgb3RoZXJ3aXNlIGEKKyAgLy8gY29tcGlsYXRpb24gZXJyb3Igd2lsbCBvY2N1ci4KKyAgLy8KKyAgLy8gUmVwZWF0ZWRGaWVsZCBhbmQgUmVwZWF0ZWRQdHJGaWVsZCBtYXkgYWxzbyBiZSBpbnN0YW50aWF0ZWQgZGlyZWN0bHkgb24gYW4KKyAgLy8gYXJlbmEgd2l0aCB0aGlzIG1ldGhvZC4KKyAgLy8KKyAgLy8gVGhpcyBmdW5jdGlvbiBhbHNvIGFjY2VwdHMgYW55IHR5cGUgVCB0aGF0IHNhdGlzZmllcyB0aGUgYXJlbmEgbWVzc2FnZQorICAvLyBhbGxvY2F0aW9uIHByb3RvY29sLCBkb2N1bWVudGVkIGFib3ZlLgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4gR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FCisgIHN0YXRpYyBUKiBDcmVhdGVNZXNzYWdlKDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSB7CisgICAgaWYgKGFyZW5hID09IE5VTEwpIHsKKyAgICAgIHJldHVybiBuZXcgVDsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIGFyZW5hLT5DcmVhdGVNZXNzYWdlSW50ZXJuYWw8VD4oc3RhdGljX2Nhc3Q8VCo+KDApKTsKKyAgICB9CisgIH0KKworICAvLyBPbmUtYXJndW1lbnQgZm9ybSBvZiBDcmVhdGVNZXNzYWdlLiBUaGlzIGlzIHVzZWZ1bCBmb3IgY29uc3RydWN0aW5nIG9iamVjdHMKKyAgLy8gdGhhdCBpbXBsZW1lbnQgdGhlIGFyZW5hIG1lc3NhZ2UgY29uc3RydWN0aW9uIHByb3RvY29sIGRlc2NyaWJlZCBhYm92ZSBidXQKKyAgLy8gdGFrZSBhZGRpdGlvbmFsIGNvbnN0cnVjdG9yIGFyZ3VtZW50cy4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIEFyZz4gR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FCisgIHN0YXRpYyBUKiBDcmVhdGVNZXNzYWdlKDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hLCBjb25zdCBBcmcmIGFyZykgeworICAgIGlmIChhcmVuYSA9PSBOVUxMKSB7CisgICAgICByZXR1cm4gbmV3IFQoTlVMTCwgYXJnKTsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIGFyZW5hLT5DcmVhdGVNZXNzYWdlSW50ZXJuYWw8VD4oc3RhdGljX2Nhc3Q8VCo+KDApLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJnKTsKKyAgICB9CisgIH0KKworICAvLyBUd28tYXJndW1lbnQgZm9ybSBvZiBDcmVhdGVNZXNzYWdlLiBUaGlzIGlzIHVzZWZ1bCBmb3IgY29uc3RydWN0aW5nIG9iamVjdHMKKyAgLy8gdGhhdCBpbXBsZW1lbnQgdGhlIGFyZW5hIG1lc3NhZ2UgY29uc3RydWN0aW9uIHByb3RvY29sIGRlc2NyaWJlZCBhYm92ZSBidXQKKyAgLy8gdGFrZSBhZGRpdGlvbmFsIGNvbnN0cnVjdG9yIGFyZ3VtZW50cy4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIEFyZzEsIHR5cGVuYW1lIEFyZzI+IEdPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORQorICBzdGF0aWMgVCogQ3JlYXRlTWVzc2FnZSg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQXJnMSYgYXJnMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQXJnMiYgYXJnMikgeworICAgIGlmIChhcmVuYSA9PSBOVUxMKSB7CisgICAgICByZXR1cm4gbmV3IFQoTlVMTCwgYXJnMSwgYXJnMik7CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiBhcmVuYS0+Q3JlYXRlTWVzc2FnZUludGVybmFsPFQ+KHN0YXRpY19jYXN0PFQqPigwKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZzEsIGFyZzIpOworICAgIH0KKyAgfQorCisgIC8vIEFQSSB0byBjcmVhdGUgYW55IG9iamVjdHMgb24gdGhlIGFyZW5hLiBOb3RlIHRoYXQgb25seSB0aGUgb2JqZWN0IHdpbGwKKyAgLy8gYmUgY3JlYXRlZCBvbiB0aGUgYXJlbmE7IHRoZSB1bmRlcmx5aW5nIHB0cnMgKGluIGNhc2Ugb2YgYSBwcm90bzIgbWVzc2FnZSkKKyAgLy8gd2lsbCBiZSBzdGlsbCBoZWFwIGFsbG9jYXRlZC4gUHJvdG8gbWVzc2FnZXMgc2hvdWxkIHVzdWFsbHkgYmUgYWxsb2NhdGVkCisgIC8vIHdpdGggQ3JlYXRlTWVzc2FnZTxUPigpIGluc3RlYWQuCisgIC8vCisgIC8vIE5vdGUgdGhhdCBldmVuIGlmIFQgc2F0aXNmaWVzIHRoZSBhcmVuYSBtZXNzYWdlIGNvbnN0cnVjdGlvbiBwcm90b2NvbAorICAvLyAoSW50ZXJuYWxBcmVuYUNvbnN0cnVjdGFibGVfIHRyYWl0IGFuZCBvcHRpb25hbCBEZXN0cnVjdG9yU2tpcHBhYmxlXworICAvLyB0cmFpdCksIGFzIGRlc2NyaWJlZCBhYm92ZSwgdGhpcyBmdW5jdGlvbiBkb2VzIG5vdCBmb2xsb3cgdGhlIHByb3RvY29sOworICAvLyBpbnN0ZWFkLCBpdCB0cmVhdHMgVCBhcyBhIGJsYWNrLWJveCB0eXBlLCBqdXN0IGFzIGlmIGl0IGRpZCBub3QgaGF2ZSB0aGVzZQorICAvLyB0cmFpdHMuIFNwZWNpZmljYWxseSwgVCdzIGNvbnN0cnVjdG9yIGFyZ3VtZW50cyB3aWxsIGFsd2F5cyBiZSBvbmx5IHRob3NlCisgIC8vIHBhc3NlZCB0byBDcmVhdGU8VD4oKSAtLSBubyBhZGRpdGlvbmFsIGFyZW5hIHBvaW50ZXIgaXMgaW1wbGljaXRseSBhZGRlZC4KKyAgLy8gRnVydGhlcm1vcmUsIHRoZSBkZXN0cnVjdG9yIHdpbGwgYWx3YXlzIGJlIGNhbGxlZCBhdCBhcmVuYSBkZXN0cnVjdGlvbiB0aW1lCisgIC8vICh1bmxlc3MgdGhlIGRlc3RydWN0b3IgaXMgdHJpdmlhbCkuIEhlbmNlLCBmcm9tIFQncyBwb2ludCBvZiB2aWV3LCBpdCBpcyBhcworICAvLyBpZiB0aGUgb2JqZWN0IHdlcmUgYWxsb2NhdGVkIG9uIHRoZSBoZWFwIChleGNlcHQgdGhhdCB0aGUgdW5kZXJseWluZyBtZW1vcnkKKyAgLy8gaXMgb2J0YWluZWQgZnJvbSB0aGUgYXJlbmEpLgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4gR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FCisgIHN0YXRpYyBUKiBDcmVhdGUoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIHsKKyAgICBpZiAoYXJlbmEgPT0gTlVMTCkgeworICAgICAgcmV0dXJuIG5ldyBUKCk7CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiBhcmVuYS0+Q3JlYXRlSW50ZXJuYWw8VD4oZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6Omhhc190cml2aWFsX2Rlc3RydWN0b3I8VD46OnZhbHVlKTsKKyAgICB9CisgIH0KKworICAvLyBWZXJzaW9uIG9mIHRoZSBhYm92ZSB3aXRoIG9uZSBjb25zdHJ1Y3RvciBhcmd1bWVudCBmb3IgdGhlIGNyZWF0ZWQgb2JqZWN0LgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgQXJnPiBHT09HTEVfQVRUUklCVVRFX0FMV0FZU19JTkxJTkUKKyAgc3RhdGljIFQqIENyZWF0ZSg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSwgY29uc3QgQXJnJiBhcmcpIHsKKyAgICBpZiAoYXJlbmEgPT0gTlVMTCkgeworICAgICAgcmV0dXJuIG5ldyBUKGFyZyk7CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiBhcmVuYS0+Q3JlYXRlSW50ZXJuYWw8VD4oZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6Omhhc190cml2aWFsX2Rlc3RydWN0b3I8VD46OnZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmcpOworICAgIH0KKyAgfQorCisgIC8vIFZlcnNpb24gb2YgdGhlIGFib3ZlIHdpdGggdHdvIGNvbnN0cnVjdG9yIGFyZ3VtZW50cyBmb3IgdGhlIGNyZWF0ZWQgb2JqZWN0LgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgQXJnMSwgdHlwZW5hbWUgQXJnMj4gR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FCisgIHN0YXRpYyBUKiBDcmVhdGUoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEsIGNvbnN0IEFyZzEmIGFyZzEsIGNvbnN0IEFyZzImIGFyZzIpIHsKKyAgICBpZiAoYXJlbmEgPT0gTlVMTCkgeworICAgICAgcmV0dXJuIG5ldyBUKGFyZzEsIGFyZzIpOworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gYXJlbmEtPkNyZWF0ZUludGVybmFsPFQ+KGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpoYXNfdHJpdmlhbF9kZXN0cnVjdG9yPFQ+Ojp2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJnMSwgYXJnMik7CisgICAgfQorICB9CisKKyAgLy8gVmVyc2lvbiBvZiB0aGUgYWJvdmUgd2l0aCB0aHJlZSBjb25zdHJ1Y3RvciBhcmd1bWVudHMgZm9yIHRoZSBjcmVhdGVkCisgIC8vIG9iamVjdC4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIEFyZzEsIHR5cGVuYW1lIEFyZzIsIHR5cGVuYW1lIEFyZzM+CisgIEdPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORSBzdGF0aWMgVCogQ3JlYXRlKDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFyZzEmIGFyZzEsIGNvbnN0IEFyZzImIGFyZzIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQXJnMyYgYXJnMykgeworICAgIGlmIChhcmVuYSA9PSBOVUxMKSB7CisgICAgICByZXR1cm4gbmV3IFQoYXJnMSwgYXJnMiwgYXJnMyk7CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiBhcmVuYS0+Q3JlYXRlSW50ZXJuYWw8VD4oZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6Omhhc190cml2aWFsX2Rlc3RydWN0b3I8VD46OnZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmcxLCBhcmcyLCBhcmczKTsKKyAgICB9CisgIH0KKworICAvLyBWZXJzaW9uIG9mIHRoZSBhYm92ZSB3aXRoIGZvdXIgY29uc3RydWN0b3IgYXJndW1lbnRzIGZvciB0aGUgY3JlYXRlZAorICAvLyBvYmplY3QuCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBULCB0eXBlbmFtZSBBcmcxLCB0eXBlbmFtZSBBcmcyLCB0eXBlbmFtZSBBcmczLAorICAgICAgICAgICAgdHlwZW5hbWUgQXJnND4KKyAgR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FIHN0YXRpYyBUKiBDcmVhdGUoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQXJnMSYgYXJnMSwgY29uc3QgQXJnMiYgYXJnMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBBcmczJiBhcmczLCBjb25zdCBBcmc0JiBhcmc0KSB7CisgICAgaWYgKGFyZW5hID09IE5VTEwpIHsKKyAgICAgIHJldHVybiBuZXcgVChhcmcxLCBhcmcyLCBhcmczLCBhcmc0KTsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIGFyZW5hLT5DcmVhdGVJbnRlcm5hbDxUPihnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6aGFzX3RyaXZpYWxfZGVzdHJ1Y3RvcjxUPjo6dmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZzEsIGFyZzIsIGFyZzMsIGFyZzQpOworICAgIH0KKyAgfQorCisgIC8vIFZlcnNpb24gb2YgdGhlIGFib3ZlIHdpdGggZml2ZSBjb25zdHJ1Y3RvciBhcmd1bWVudHMgZm9yIHRoZSBjcmVhdGVkCisgIC8vIG9iamVjdC4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIEFyZzEsIHR5cGVuYW1lIEFyZzIsIHR5cGVuYW1lIEFyZzMsCisgICAgICAgICAgICB0eXBlbmFtZSBBcmc0LCB0eXBlbmFtZSBBcmc1PgorICBHT09HTEVfQVRUUklCVVRFX0FMV0FZU19JTkxJTkUgc3RhdGljIFQqIENyZWF0ZSg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBBcmcxJiBhcmcxLCBjb25zdCBBcmcyJiBhcmcyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFyZzMmIGFyZzMsIGNvbnN0IEFyZzQmIGFyZzQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQXJnNSYgYXJnNSkgeworICAgIGlmIChhcmVuYSA9PSBOVUxMKSB7CisgICAgICByZXR1cm4gbmV3IFQoYXJnMSwgYXJnMiwgYXJnMywgYXJnNCwgYXJnNSk7CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiBhcmVuYS0+Q3JlYXRlSW50ZXJuYWw8VD4oZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6Omhhc190cml2aWFsX2Rlc3RydWN0b3I8VD46OnZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmcxLCBhcmcyLCBhcmczLCBhcmc0LCBhcmc1KTsKKyAgICB9CisgIH0KKworICAvLyBWZXJzaW9uIG9mIHRoZSBhYm92ZSB3aXRoIHNpeCBjb25zdHJ1Y3RvciBhcmd1bWVudHMgZm9yIHRoZSBjcmVhdGVkCisgIC8vIG9iamVjdC4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIEFyZzEsIHR5cGVuYW1lIEFyZzIsIHR5cGVuYW1lIEFyZzMsCisgICAgICAgICAgICB0eXBlbmFtZSBBcmc0LCB0eXBlbmFtZSBBcmc1LCB0eXBlbmFtZSBBcmc2PgorICBHT09HTEVfQVRUUklCVVRFX0FMV0FZU19JTkxJTkUgc3RhdGljIFQqIENyZWF0ZSg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBBcmcxJiBhcmcxLCBjb25zdCBBcmcyJiBhcmcyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFyZzMmIGFyZzMsIGNvbnN0IEFyZzQmIGFyZzQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQXJnNSYgYXJnNSwgY29uc3QgQXJnNiYgYXJnNikgeworICAgIGlmIChhcmVuYSA9PSBOVUxMKSB7CisgICAgICByZXR1cm4gbmV3IFQoYXJnMSwgYXJnMiwgYXJnMywgYXJnNCwgYXJnNSwgYXJnNik7CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiBhcmVuYS0+Q3JlYXRlSW50ZXJuYWw8VD4oZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6Omhhc190cml2aWFsX2Rlc3RydWN0b3I8VD46OnZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmcxLCBhcmcyLCBhcmczLCBhcmc0LCBhcmc1LCBhcmc2KTsKKyAgICB9CisgIH0KKworICAvLyBWZXJzaW9uIG9mIHRoZSBhYm92ZSB3aXRoIHNldmVuIGNvbnN0cnVjdG9yIGFyZ3VtZW50cyBmb3IgdGhlIGNyZWF0ZWQKKyAgLy8gb2JqZWN0LgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgQXJnMSwgdHlwZW5hbWUgQXJnMiwgdHlwZW5hbWUgQXJnMywKKyAgICAgICAgICAgIHR5cGVuYW1lIEFyZzQsIHR5cGVuYW1lIEFyZzUsIHR5cGVuYW1lIEFyZzYsIHR5cGVuYW1lIEFyZzc+CisgIEdPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORSBzdGF0aWMgVCogQ3JlYXRlKDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFyZzEmIGFyZzEsIGNvbnN0IEFyZzImIGFyZzIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQXJnMyYgYXJnMywgY29uc3QgQXJnNCYgYXJnNCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBBcmc1JiBhcmc1LCBjb25zdCBBcmc2JiBhcmc2LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFyZzcmIGFyZzcpIHsKKyAgICBpZiAoYXJlbmEgPT0gTlVMTCkgeworICAgICAgcmV0dXJuIG5ldyBUKGFyZzEsIGFyZzIsIGFyZzMsIGFyZzQsIGFyZzUsIGFyZzYsIGFyZzcpOworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gYXJlbmEtPkNyZWF0ZUludGVybmFsPFQ+KGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpoYXNfdHJpdmlhbF9kZXN0cnVjdG9yPFQ+Ojp2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJnMSwgYXJnMiwgYXJnMywgYXJnNCwgYXJnNSwgYXJnNiwgYXJnNyk7CisgICAgfQorICB9CisKKyAgLy8gVmVyc2lvbiBvZiB0aGUgYWJvdmUgd2l0aCBlaWdodCBjb25zdHJ1Y3RvciBhcmd1bWVudHMgZm9yIHRoZSBjcmVhdGVkCisgIC8vIG9iamVjdC4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIEFyZzEsIHR5cGVuYW1lIEFyZzIsIHR5cGVuYW1lIEFyZzMsCisgICAgICAgICAgICB0eXBlbmFtZSBBcmc0LCB0eXBlbmFtZSBBcmc1LCB0eXBlbmFtZSBBcmc2LCB0eXBlbmFtZSBBcmc3LAorICAgICAgICAgICAgdHlwZW5hbWUgQXJnOD4KKyAgR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FIHN0YXRpYyBUKiBDcmVhdGUoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQXJnMSYgYXJnMSwgY29uc3QgQXJnMiYgYXJnMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBBcmczJiBhcmczLCBjb25zdCBBcmc0JiBhcmc0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFyZzUmIGFyZzUsIGNvbnN0IEFyZzYmIGFyZzYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQXJnNyYgYXJnNywgY29uc3QgQXJnOCYgYXJnOCkgeworICAgIGlmIChhcmVuYSA9PSBOVUxMKSB7CisgICAgICByZXR1cm4gbmV3IFQoYXJnMSwgYXJnMiwgYXJnMywgYXJnNCwgYXJnNSwgYXJnNiwgYXJnNywgYXJnOCk7CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiBhcmVuYS0+Q3JlYXRlSW50ZXJuYWw8VD4oCisgICAgICAgICAgZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6Omhhc190cml2aWFsX2Rlc3RydWN0b3I8VD46OnZhbHVlLAorICAgICAgICAgIGFyZzEsIGFyZzIsIGFyZzMsIGFyZzQsIGFyZzUsIGFyZzYsIGFyZzcsIGFyZzgpOworICAgIH0KKyAgfQorCisgIC8vIENyZWF0ZSBhbiBhcnJheSBvZiBvYmplY3QgdHlwZSBUIG9uIHRoZSBhcmVuYSAqd2l0aG91dCogaW52b2tpbmcgdGhlCisgIC8vIGNvbnN0cnVjdG9yIG9mIFQuIElmIGBhcmVuYWAgaXMgbnVsbCwgdGhlbiB0aGUgcmV0dXJuIHZhbHVlIHNob3VsZCBiZSBmcmVlZAorICAvLyB3aXRoIGBkZWxldGVbXSB4O2AgKG9yIGA6Om9wZXJhdG9yIGRlbGV0ZVtdKHgpO2ApLgorICAvLyBUbyBlbnN1cmUgc2FmZSB1c2VzLCB0aGlzIGZ1bmN0aW9uIGNoZWNrcyBhdCBjb21waWxlIHRpbWUKKyAgLy8gKHdoZW4gY29tcGlsZWQgYXMgQysrMTEpIHRoYXQgVCBpcyB0cml2aWFsbHkgZGVmYXVsdC1jb25zdHJ1Y3RpYmxlIGFuZAorICAvLyB0cml2aWFsbHkgZGVzdHJ1Y3RpYmxlLgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4gR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FCisgIHN0YXRpYyBUKiBDcmVhdGVBcnJheSg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSwgc2l6ZV90IG51bV9lbGVtZW50cykgeworICAgIEdPT0dMRV9DSEVDS19MRShudW1fZWxlbWVudHMsCisgICAgICAgICAgICAgc3RkOjpudW1lcmljX2xpbWl0czxzaXplX3Q+OjptYXgoKSAvIHNpemVvZihUKSkKKyAgICAgICAgPDwgIlJlcXVlc3RlZCBzaXplIGlzIHRvbyBsYXJnZSB0byBmaXQgaW50byBzaXplX3QuIjsKKyAgICBpZiAoYXJlbmEgPT0gTlVMTCkgeworICAgICAgcmV0dXJuIHN0YXRpY19jYXN0PFQqPig6Om9wZXJhdG9yIG5ld1tdKG51bV9lbGVtZW50cyAqIHNpemVvZihUKSkpOworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gYXJlbmEtPkNyZWF0ZUludGVybmFsUmF3QXJyYXk8VD4obnVtX2VsZW1lbnRzKTsKKyAgICB9CisgIH0KKworICAvLyBSZXR1cm5zIHRoZSB0b3RhbCBzcGFjZSB1c2VkIGJ5IHRoZSBhcmVuYSwgd2hpY2ggaXMgdGhlIHN1bXMgb2YgdGhlIHNpemVzCisgIC8vIG9mIHRoZSB1bmRlcmx5aW5nIGJsb2Nrcy4gVGhlIHRvdGFsIHNwYWNlIHVzZWQgbWF5IG5vdCBpbmNsdWRlIHRoZSBuZXcKKyAgLy8gYmxvY2tzIHRoYXQgYXJlIGFsbG9jYXRlZCBieSB0aGlzIGFyZW5hIGZyb20gb3RoZXIgdGhyZWFkcyBjb25jdXJyZW50bHkKKyAgLy8gd2l0aCB0aGUgY2FsbCB0byB0aGlzIG1ldGhvZC4KKyAgR09PR0xFX0FUVFJJQlVURV9OT0lOTElORSB1aW50NjQgU3BhY2VBbGxvY2F0ZWQoKSBjb25zdDsKKyAgLy8gQXMgYWJvdmUsIGJ1dCBkb2VzIG5vdCBpbmNsdWRlIGFueSBmcmVlIHNwYWNlIGluIHVuZGVybHlpbmcgYmxvY2tzLgorICBHT09HTEVfQVRUUklCVVRFX05PSU5MSU5FIHVpbnQ2NCBTcGFjZVVzZWQoKSBjb25zdDsKKworICAvLyBGcmVlcyBhbGwgc3RvcmFnZSBhbGxvY2F0ZWQgYnkgdGhpcyBhcmVuYSBhZnRlciBjYWxsaW5nIGRlc3RydWN0b3JzCisgIC8vIHJlZ2lzdGVyZWQgd2l0aCBPd25EZXN0cnVjdG9yKCkgYW5kIGZyZWVpbmcgb2JqZWN0cyByZWdpc3RlcmVkIHdpdGggT3duKCkuCisgIC8vIEFueSBvYmplY3RzIGFsbG9jYXRlZCBvbiB0aGlzIGFyZW5hIGFyZSB1bnVzYWJsZSBhZnRlciB0aGlzIGNhbGwuIEl0IGFsc28KKyAgLy8gcmV0dXJucyB0aGUgdG90YWwgc3BhY2UgdXNlZCBieSB0aGUgYXJlbmEgd2hpY2ggaXMgdGhlIHN1bXMgb2YgdGhlIHNpemVzCisgIC8vIG9mIHRoZSBhbGxvY2F0ZWQgYmxvY2tzLiBUaGlzIG1ldGhvZCBpcyBub3QgdGhyZWFkLXNhZmUuCisgIEdPT0dMRV9BVFRSSUJVVEVfTk9JTkxJTkUgdWludDY0IFJlc2V0KCk7CisKKyAgLy8gQWRkcyB8b2JqZWN0fCB0byBhIGxpc3Qgb2YgaGVhcC1hbGxvY2F0ZWQgb2JqZWN0cyB0byBiZSBmcmVlZCB3aXRoIHxkZWxldGV8CisgIC8vIHdoZW4gdGhlIGFyZW5hIGlzIGRlc3Ryb3llZCBvciByZXNldC4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFQ+IEdPT0dMRV9BVFRSSUJVVEVfTk9JTkxJTkUKKyAgdm9pZCBPd24oVCogb2JqZWN0KSB7CisgICAgT3duSW50ZXJuYWwob2JqZWN0LCBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6aXNfY29udmVydGlibGU8VCosIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSo+KCkpOworICB9CisKKyAgLy8gQWRkcyB8b2JqZWN0fCB0byBhIGxpc3Qgb2Ygb2JqZWN0cyB3aG9zZSBkZXN0cnVjdG9ycyB3aWxsIGJlIG1hbnVhbGx5CisgIC8vIGNhbGxlZCB3aGVuIHRoZSBhcmVuYSBpcyBkZXN0cm95ZWQgb3IgcmVzZXQuIFRoaXMgZGlmZmVycyBmcm9tIE93bigpIGluCisgIC8vIHRoYXQgaXQgZG9lcyBub3QgZnJlZSB0aGUgdW5kZXJseWluZyBtZW1vcnkgd2l0aCB8ZGVsZXRlfDsgaGVuY2UsIGl0IGlzCisgIC8vIG5vcm1hbGx5IG9ubHkgdXNlZCBmb3Igb2JqZWN0cyB0aGF0IGFyZSBwbGFjZW1lbnQtbmV3ZWQgaW50bworICAvLyBhcmVuYS1hbGxvY2F0ZWQgbWVtb3J5LgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4gR09PR0xFX0FUVFJJQlVURV9OT0lOTElORQorICB2b2lkIE93bkRlc3RydWN0b3IoVCogb2JqZWN0KSB7CisgICAgaWYgKG9iamVjdCAhPSBOVUxMKSB7CisgICAgICBBZGRMaXN0Tm9kZShvYmplY3QsICZpbnRlcm5hbDo6YXJlbmFfZGVzdHJ1Y3Rfb2JqZWN0PFQ+KTsKKyAgICB9CisgIH0KKworICAvLyBBZGRzIGEgY3VzdG9tIG1lbWJlciBmdW5jdGlvbiBvbiBhbiBvYmplY3QgdG8gdGhlIGxpc3Qgb2YgZGVzdHJ1Y3RvcnMgdGhhdAorICAvLyB3aWxsIGJlIG1hbnVhbGx5IGNhbGxlZCB3aGVuIHRoZSBhcmVuYSBpcyBkZXN0cm95ZWQgb3IgcmVzZXQuIFRoaXMgZGlmZmVycworICAvLyBmcm9tIE93bkRlc3RydWN0b3IoKSBpbiB0aGF0IGFueSBtZW1iZXIgZnVuY3Rpb24gbWF5IGJlIHNwZWNpZmllZCwgbm90IG9ubHkKKyAgLy8gdGhlIGNsYXNzIGRlc3RydWN0b3IuCisgIEdPT0dMRV9BVFRSSUJVVEVfTk9JTkxJTkUgdm9pZCBPd25DdXN0b21EZXN0cnVjdG9yKHZvaWQqIG9iamVjdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICgqZGVzdHJ1Y3QpKHZvaWQqKSkgeworICAgIEFkZExpc3ROb2RlKG9iamVjdCwgZGVzdHJ1Y3QpOworICB9CisKKyAgLy8gUmV0cmlldmVzIHRoZSBhcmVuYSBhc3NvY2lhdGVkIHdpdGggfHZhbHVlfCBpZiB8dmFsdWV8IGlzIGFuIGFyZW5hLWNhcGFibGUKKyAgLy8gbWVzc2FnZSwgb3IgTlVMTCBvdGhlcndpc2UuIFRoaXMgZGlmZmVycyBmcm9tIHZhbHVlLT5HZXRBcmVuYSgpIGluIHRoYXQgdGhlCisgIC8vIGxhdHRlciBpcyBhIHZpcnR1YWwgY2FsbCwgd2hpbGUgdGhpcyBtZXRob2QgaXMgYSB0ZW1wbGF0ZWQgY2FsbCB0aGF0CisgIC8vIHJlc29sdmVzIGF0IGNvbXBpbGUtdGltZS4KKyAgdGVtcGxhdGU8dHlwZW5hbWUgVD4gR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FCisgIHN0YXRpYyA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYShjb25zdCBUKiB2YWx1ZSkgeworICAgIHJldHVybiBHZXRBcmVuYUludGVybmFsKHZhbHVlLCBzdGF0aWNfY2FzdDxUKj4oMCkpOworICB9CisKKyBwcml2YXRlOgorICBzdHJ1Y3QgSW50ZXJuYWxJc0FyZW5hQ29uc3RydWN0YWJsZUhlbHBlciB7CisgICAgdGVtcGxhdGU8dHlwZW5hbWUgVT4KKyAgICBzdGF0aWMgY2hhciBBcmVuYUNvbnN0cnVjdGFibGUoCisgICAgICAgIGNvbnN0IHR5cGVuYW1lIFU6OkludGVybmFsQXJlbmFDb25zdHJ1Y3RhYmxlXyopOworICAgIHRlbXBsYXRlPHR5cGVuYW1lIFU+CisgICAgc3RhdGljIGRvdWJsZSBBcmVuYUNvbnN0cnVjdGFibGUoLi4uKTsKKyAgfTsKKworIHB1YmxpYzoKKyAgLy8gSGVscGVyIHR5cGV0cmFpdCB0aGF0IGluZGljYXRlcyBzdXBwb3J0IGZvciBhcmVuYXMgaW4gYSB0eXBlIFQgYXQgY29tcGlsZQorICAvLyB0aW1lLiBUaGlzIGlzIHB1YmxpYyBvbmx5IHRvIGFsbG93IGNvbnN0cnVjdGlvbiBvZiBoaWdoZXItbGV2ZWwgdGVtcGxhdGVkCisgIC8vIHV0aWxpdGllcy4gaXNfYXJlbmFfY29uc3RydWN0YWJsZTxUPjo6dmFsdWUgaXMgdHJ1ZSBpZiB0aGUgbWVzc2FnZSB0eXBlIFQKKyAgLy8gaGFzIGFyZW5hIHN1cHBvcnQgZW5hYmxlZCwgYW5kIGZhbHNlIG90aGVyd2lzZS4KKyAgLy8KKyAgLy8gVGhpcyBpcyBpbnNpZGUgQXJlbmEgYmVjYXVzZSBvbmx5IEFyZW5hIGhhcyB0aGUgZnJpZW5kIHJlbGF0aW9uc2hpcHMKKyAgLy8gbmVjZXNzYXJ5IHRvIHNlZSB0aGUgdW5kZXJseWluZyBnZW5lcmF0ZWQgY29kZSB0cmFpdHMuCisgIHRlbXBsYXRlPHR5cGVuYW1lIFQ+CisgIHN0cnVjdCBpc19hcmVuYV9jb25zdHJ1Y3RhYmxlIDoKKyAgICAgIHB1YmxpYyBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6aW50ZWdyYWxfY29uc3RhbnQ8Ym9vbCwKKyAgICAgICAgICBzaXplb2YoSW50ZXJuYWxJc0FyZW5hQ29uc3RydWN0YWJsZUhlbHBlcjo6QXJlbmFDb25zdHJ1Y3RhYmxlPAorICAgICAgICAgICAgICAgICBjb25zdCBUPihzdGF0aWNfY2FzdDxjb25zdCBUKj4oMCkpKSA9PSBzaXplb2YoY2hhcik+IHsKKyAgfTsKKworIHByaXZhdGU6CisgIC8vIEJsb2NrcyBhcmUgdmFyaWFibGUgbGVuZ3RoIG1hbGxvYy1lZCBvYmplY3RzLiAgVGhlIGZvbGxvd2luZyBzdHJ1Y3R1cmUKKyAgLy8gZGVzY3JpYmVzIHRoZSBjb21tb24gaGVhZGVyIGZvciBhbGwgYmxvY2tzLgorICBzdHJ1Y3QgQmxvY2sgeworICAgIHZvaWQqIG93bmVyOyAgIC8vICZUaHJlYWRDYWNoZSBvZiB0aHJlYWQgdGhhdCBvd25zIHRoaXMgYmxvY2ssIG9yCisgICAgICAgICAgICAgICAgICAgLy8gJnRoaXMtPm93bmVyIGlmIG5vdCB5ZXQgb3duZWQgYnkgYSB0aHJlYWQuCisgICAgQmxvY2sqIG5leHQ7ICAgLy8gTmV4dCBibG9jayBpbiBhcmVuYSAobWF5IGhhdmUgZGlmZmVyZW50IG93bmVyKQorICAgIC8vICgoY2hhciopICZibG9jaykgKyBwb3MgaXMgbmV4dCBhdmFpbGFibGUgYnl0ZS4gSXQgaXMgYWx3YXlzCisgICAgLy8gYWxpZ25lZCBhdCBhIG11bHRpcGxlIG9mIDggYnl0ZXMuCisgICAgc2l6ZV90IHBvczsKKyAgICBzaXplX3Qgc2l6ZTsgIC8vIHRvdGFsIHNpemUgb2YgdGhlIGJsb2NrLgorICAgIEdPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORSBzaXplX3QgYXZhaWwoKSBjb25zdCB7IHJldHVybiBzaXplIC0gcG9zOyB9CisgICAgLy8gZGF0YSBmb2xsb3dzCisgIH07CisKKyAgdGVtcGxhdGU8dHlwZW5hbWUgVHlwZT4gZnJpZW5kIGNsYXNzIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyaWNUeXBlSGFuZGxlcjsKKyAgZnJpZW5kIGNsYXNzIE1vY2tBcmVuYTsgICAgICAgICAgICAgIC8vIEZvciB1bml0LXRlc3RpbmcuCisgIGZyaWVuZCBjbGFzcyBpbnRlcm5hbDo6QXJlbmFTdHJpbmc7ICAvLyBGb3IgQWxsb2NhdGVBbGlnbmVkLgorICBmcmllbmQgY2xhc3MgaW50ZXJuYWw6OkxhenlGaWVsZDsgICAgLy8gRm9yIENyZWF0ZU1heWJlTWVzc2FnZS4KKworICBzdHJ1Y3QgVGhyZWFkQ2FjaGUgeworICAgIC8vIFRoZSBUaHJlYWRDYWNoZSBpcyBjb25zaWRlcmVkIHZhbGlkIGFzIGxvbmcgYXMgdGhpcyBtYXRjaGVzIHRoZQorICAgIC8vIGxpZmVjeWNsZV9pZCBvZiB0aGUgYXJlbmEgYmVpbmcgdXNlZC4KKyAgICBpbnQ2NCBsYXN0X2xpZmVjeWNsZV9pZF9zZWVuOworICAgIEJsb2NrKiBsYXN0X2Jsb2NrX3VzZWRfOworICB9OworCisgIHN0YXRpYyBjb25zdCBzaXplX3Qga0hlYWRlclNpemUgPSBzaXplb2YoQmxvY2spOworICBzdGF0aWMgZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlNlcXVlbmNlTnVtYmVyIGxpZmVjeWNsZV9pZF9nZW5lcmF0b3JfOworI2lmIGRlZmluZWQoR09PR0xFX1BST1RPQlVGX05PX1RIUkVBRExPQ0FMKQorICAvLyBBbmRyb2lkIG5kayBkb2VzIG5vdCBzdXBwb3J0IEdPT0dMRV9USFJFQURfTE9DQUwga2V5d29yZCBzbyB3ZSB1c2UgYSBjdXN0b20gdGhyZWFkCisgIC8vIGxvY2FsIHN0b3JhZ2UgY2xhc3Mgd2UgaW1wbGVtZW50ZWQuCisgIC8vIGlPUyBhbHNvIGRvZXMgbm90IHN1cHBvcnQgdGhlIEdPT0dMRV9USFJFQURfTE9DQUwga2V5d29yZC4KKyAgc3RhdGljIFRocmVhZENhY2hlJiB0aHJlYWRfY2FjaGUoKTsKKyNlbGlmIGRlZmluZWQoUFJPVE9CVUZfVVNFX0RMTFMpCisgIC8vIFRocmVhZCBsb2NhbCB2YXJpYWJsZXMgY2Fubm90IGJlIGV4cG9zZWQgdGhyb3VnaCBETEwgaW50ZXJmYWNlIGJ1dCB3ZSBjYW4KKyAgLy8gd3JhcCB0aGVtIGluIHN0YXRpYyBmdW5jdGlvbnMuCisgIHN0YXRpYyBUaHJlYWRDYWNoZSYgdGhyZWFkX2NhY2hlKCk7CisjZWxzZQorICBzdGF0aWMgR09PR0xFX1RIUkVBRF9MT0NBTCBUaHJlYWRDYWNoZSB0aHJlYWRfY2FjaGVfOworICBzdGF0aWMgVGhyZWFkQ2FjaGUmIHRocmVhZF9jYWNoZSgpIHsgcmV0dXJuIHRocmVhZF9jYWNoZV87IH0KKyNlbmRpZgorCisgIC8vIFNGSU5BRSBmb3Igc2tpcHBpbmcgYWRkaXRpb24gdG8gZGVsZXRlIGxpc3QgZm9yIGEgbWVzc2FnZSB0eXBlIHdoZW4gY3JlYXRlZAorICAvLyB3aXRoIENyZWF0ZU1lc3NhZ2UuIFRoaXMgaXMgbWFpbmx5IHRvIHNraXAgcHJvdG8yL3Byb3RvMSBtZXNzYWdlIG9iamVjdHMKKyAgLy8gd2l0aCBjY19lbmFibGVfYXJlbmFzPXRydWUgZnJvbSBiZWluZyBwYXJ0IG9mIHRoZSBkZWxldGUgbGlzdC4gQWxzbywgbm90ZSwKKyAgLy8gY29tcGlsZXIgd2lsbCBvcHRpbWl6ZSBvdXQgdGhlIGJyYW5jaCBpbiBDcmVhdGVJbnRlcm5hbDxUPi4KKyAgdGVtcGxhdGU8dHlwZW5hbWUgVD4KKyAgc3RhdGljIGlubGluZSBib29sIFNraXBEZWxldGVMaXN0KHR5cGVuYW1lIFQ6OkRlc3RydWN0b3JTa2lwcGFibGVfKikgeworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgLy8gRm9yIG1lc3NhZ2Ugb2JqZWN0cyB0aGF0IGRvbid0IGhhdmUgdGhlIERlc3RydWN0b3JTa2lwcGFibGVfIHRyYWl0LCB3ZQorICAvLyBhbHdheXMgYWRkIHRvIHRoZSBkZWxldGUgbGlzdC4KKyAgdGVtcGxhdGU8dHlwZW5hbWUgVD4KKyAgc3RhdGljIGlubGluZSBib29sIFNraXBEZWxldGVMaXN0KC4uLikgeworICAgIHJldHVybiBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6aGFzX3RyaXZpYWxfZGVzdHJ1Y3RvcjxUPjo6dmFsdWU7CisgIH0KKworIHByaXZhdGU6CisgIHN0cnVjdCBJbnRlcm5hbElzRGVzdHJ1Y3RvclNraXBwYWJsZUhlbHBlciB7CisgICAgdGVtcGxhdGU8dHlwZW5hbWUgVT4KKyAgICBzdGF0aWMgY2hhciBEZXN0cnVjdG9yU2tpcHBhYmxlKAorICAgICAgICBjb25zdCB0eXBlbmFtZSBVOjpEZXN0cnVjdG9yU2tpcHBhYmxlXyopOworICAgIHRlbXBsYXRlPHR5cGVuYW1lIFU+CisgICAgc3RhdGljIGRvdWJsZSBEZXN0cnVjdG9yU2tpcHBhYmxlKC4uLik7CisgIH07CisKKyBwdWJsaWM6CisgIC8vIEhlbHBlciB0eXBldHJhaXQgdGhhdCBpbmRpY2F0ZXMgd2hldGhlciB0aGUgZGVzY3RydWN0b3Igb2YgdHlwZSBUIHNob3VsZCBiZQorICAvLyBjYWxsZWQgd2hlbiBhcmVuYSBpcyBkZXN0cm95ZWQgYXQgY29tcGlsZSB0aW1lLiBUaGlzIGlzIG9ubHkgdG8gYWxsb3cKKyAgLy8gY29uc3RydWN0aW9uIG9mIGhpZ2hlci1sZXZlbCB0ZW1wbGF0ZWQgdXRpbGl0aWVzLgorICAvLyBpc19kZXN0cnVjdG9yX3NraXBwYWJsZTxUPjo6dmFsdWUgaXMgdHJ1ZSBpZiB0aGUgZGVzdHJ1Y3RvciBvZiB0aGUgbWVzc2FnZQorICAvLyB0eXBlIFQgc2hvdWxkIG5vdCBiZSBjYWxsZWQgd2hlbiBhcmVuYSBpcyBkZXN0cm95ZWQgb3IgZmFsc2Ugb3RoZXJ3aXNlLgorICAvLyBUaGlzIGlzIGluc2lkZSBBcmVuYSBiZWNhdXNlIG9ubHkgQXJlbmEgaGFzIHRoZSBmcmllbmQgcmVsYXRpb25zaGlwcworICAvLyBuZWNlc3NhcnkgdG8gc2VlIHRoZSB1bmRlcmx5aW5nIGdlbmVyYXRlZCBjb2RlIHRyYWl0cy4KKyAgdGVtcGxhdGU8dHlwZW5hbWUgVD4KKyAgc3RydWN0IGlzX2Rlc3RydWN0b3Jfc2tpcHBhYmxlCisgICAgICA6IHB1YmxpYyBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6aW50ZWdyYWxfY29uc3RhbnQ8CisgICAgICAgICAgICBib29sLAorICAgICAgICAgICAgc2l6ZW9mKEludGVybmFsSXNEZXN0cnVjdG9yU2tpcHBhYmxlSGVscGVyOjpEZXN0cnVjdG9yU2tpcHBhYmxlPAorICAgICAgICAgICAgICAgICAgIGNvbnN0IFQ+KHN0YXRpY19jYXN0PGNvbnN0IFQqPigwKSkpID09IHNpemVvZihjaGFyKSB8fAorICAgICAgICAgICAgICAgIGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpoYXNfdHJpdmlhbF9kZXN0cnVjdG9yPFQ+Ojp2YWx1ZT4ge307CisKKyAgLy8gQ3JlYXRlTWVzc2FnZTxUPiByZXF1aXJlcyB0aGF0IFQgc3VwcG9ydHMgYXJlbmFzLCBidXQgdGhpcyBwcml2YXRlIG1ldGhvZAorICAvLyB3b3JrcyB3aGV0aGVyIG9yIG5vdCBUIHN1cHBvcnRzIGFyZW5hcy4gVGhlc2UgYXJlIG5vdCBleHBvc2VkIHRvIHVzZXIgY29kZQorICAvLyBhcyBpdCBjYW4gY2F1c2UgY29uZnVzaW5nIEFQSSB1c2FnZXMsIGFuZCBlbmQgdXAgaGF2aW5nIGRvdWJsZSBmcmVlIGluCisgIC8vIHVzZXIgY29kZS4gVGhlc2UgYXJlIHVzZWQgb25seSBpbnRlcm5hbGx5IGZyb20gTGF6eUZpZWxkIGFuZCBSZXBlYXRlZAorICAvLyBmaWVsZHMsIHNpbmNlIHRoZXkgYXJlIGRlc2lnbmVkIHRvIHdvcmsgaW4gYWxsIG1vZGUgY29tYmluYXRpb25zLgorICB0ZW1wbGF0ZTx0eXBlbmFtZSBNc2c+IEdPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORQorICBzdGF0aWMgTXNnKiBDcmVhdGVNYXliZU1lc3NhZ2UoCisgICAgICBBcmVuYSogYXJlbmEsIHR5cGVuYW1lIE1zZzo6SW50ZXJuYWxBcmVuYUNvbnN0cnVjdGFibGVfKikgeworICAgIHJldHVybiBDcmVhdGVNZXNzYWdlPE1zZz4oYXJlbmEpOworICB9CisKKyAgdGVtcGxhdGU8dHlwZW5hbWUgVD4gR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FCisgIHN0YXRpYyBUKiBDcmVhdGVNYXliZU1lc3NhZ2UoQXJlbmEqIGFyZW5hLCAuLi4pIHsKKyAgICByZXR1cm4gQ3JlYXRlPFQ+KGFyZW5hKTsKKyAgfQorCisgIC8vIEp1c3QgYWxsb2NhdGUgdGhlIHJlcXVpcmVkIHNpemUgZm9yIHRoZSBnaXZlbiB0eXBlIGFzc3VtaW5nIHRoZQorICAvLyB0eXBlIGhhcyBhIHRyaXZpYWwgY29uc3RydWN0b3IuCisgIHRlbXBsYXRlPHR5cGVuYW1lIFQ+IEdPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORQorICBUKiBDcmVhdGVJbnRlcm5hbFJhd0FycmF5KHNpemVfdCBudW1fZWxlbWVudHMpIHsKKyAgICBHT09HTEVfQ0hFQ0tfTEUobnVtX2VsZW1lbnRzLAorICAgICAgICAgICAgIHN0ZDo6bnVtZXJpY19saW1pdHM8c2l6ZV90Pjo6bWF4KCkgLyBzaXplb2YoVCkpCisgICAgICAgIDw8ICJSZXF1ZXN0ZWQgc2l6ZSBpcyB0b28gbGFyZ2UgdG8gZml0IGludG8gc2l6ZV90LiI7CisgICAgcmV0dXJuIHN0YXRpY19jYXN0PFQqPigKKyAgICAgICAgQWxsb2NhdGVBbGlnbmVkKFJUVElfVFlQRV9JRChUKSwgc2l6ZW9mKFQpICogbnVtX2VsZW1lbnRzKSk7CisgIH0KKworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4gR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FCisgIFQqIENyZWF0ZUludGVybmFsKGJvb2wgc2tpcF9leHBsaWNpdF9vd25lcnNoaXApIHsKKyAgICBUKiB0ID0gbmV3IChBbGxvY2F0ZUFsaWduZWQoUlRUSV9UWVBFX0lEKFQpLCBzaXplb2YoVCkpKSBUKCk7CisgICAgaWYgKCFza2lwX2V4cGxpY2l0X293bmVyc2hpcCkgeworICAgICAgQWRkTGlzdE5vZGUodCwgJmludGVybmFsOjphcmVuYV9kZXN0cnVjdF9vYmplY3Q8VD4pOworICAgIH0KKyAgICByZXR1cm4gdDsKKyAgfQorCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBULCB0eXBlbmFtZSBBcmc+IEdPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORQorICBUKiBDcmVhdGVJbnRlcm5hbChib29sIHNraXBfZXhwbGljaXRfb3duZXJzaGlwLCBjb25zdCBBcmcmIGFyZykgeworICAgIFQqIHQgPSBuZXcgKEFsbG9jYXRlQWxpZ25lZChSVFRJX1RZUEVfSUQoVCksIHNpemVvZihUKSkpIFQoYXJnKTsKKyAgICBpZiAoIXNraXBfZXhwbGljaXRfb3duZXJzaGlwKSB7CisgICAgICBBZGRMaXN0Tm9kZSh0LCAmaW50ZXJuYWw6OmFyZW5hX2Rlc3RydWN0X29iamVjdDxUPik7CisgICAgfQorICAgIHJldHVybiB0OworICB9CisKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIEFyZzEsIHR5cGVuYW1lIEFyZzI+IEdPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORQorICBUKiBDcmVhdGVJbnRlcm5hbCgKKyAgICAgIGJvb2wgc2tpcF9leHBsaWNpdF9vd25lcnNoaXAsIGNvbnN0IEFyZzEmIGFyZzEsIGNvbnN0IEFyZzImIGFyZzIpIHsKKyAgICBUKiB0ID0gbmV3IChBbGxvY2F0ZUFsaWduZWQoUlRUSV9UWVBFX0lEKFQpLCBzaXplb2YoVCkpKSBUKGFyZzEsIGFyZzIpOworICAgIGlmICghc2tpcF9leHBsaWNpdF9vd25lcnNoaXApIHsKKyAgICAgIEFkZExpc3ROb2RlKHQsICZpbnRlcm5hbDo6YXJlbmFfZGVzdHJ1Y3Rfb2JqZWN0PFQ+KTsKKyAgICB9CisgICAgcmV0dXJuIHQ7CisgIH0KKworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgQXJnMSwgdHlwZW5hbWUgQXJnMiwgdHlwZW5hbWUgQXJnMz4KKyAgR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FIFQqIENyZWF0ZUludGVybmFsKGJvb2wgc2tpcF9leHBsaWNpdF9vd25lcnNoaXAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFyZzEmIGFyZzEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFyZzImIGFyZzIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFyZzMmIGFyZzMpIHsKKyAgICBUKiB0ID0gbmV3IChBbGxvY2F0ZUFsaWduZWQoUlRUSV9UWVBFX0lEKFQpLCBzaXplb2YoVCkpKQorICAgICAgICBUKGFyZzEsIGFyZzIsIGFyZzMpOworICAgIGlmICghc2tpcF9leHBsaWNpdF9vd25lcnNoaXApIHsKKyAgICAgIEFkZExpc3ROb2RlKHQsICZpbnRlcm5hbDo6YXJlbmFfZGVzdHJ1Y3Rfb2JqZWN0PFQ+KTsKKyAgICB9CisgICAgcmV0dXJuIHQ7CisgIH0KKworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgQXJnMSwgdHlwZW5hbWUgQXJnMiwgdHlwZW5hbWUgQXJnMywKKyAgICAgICAgICAgIHR5cGVuYW1lIEFyZzQ+CisgIEdPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORSBUKiBDcmVhdGVJbnRlcm5hbChib29sIHNraXBfZXhwbGljaXRfb3duZXJzaGlwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBBcmcxJiBhcmcxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBBcmcyJiBhcmcyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBBcmczJiBhcmczLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBBcmc0JiBhcmc0KSB7CisgICAgVCogdCA9IG5ldyAoQWxsb2NhdGVBbGlnbmVkKFJUVElfVFlQRV9JRChUKSwgc2l6ZW9mKFQpKSkKKyAgICAgICAgVChhcmcxLCBhcmcyLCBhcmczLCBhcmc0KTsKKyAgICBpZiAoIXNraXBfZXhwbGljaXRfb3duZXJzaGlwKSB7CisgICAgICBBZGRMaXN0Tm9kZSh0LCAmaW50ZXJuYWw6OmFyZW5hX2Rlc3RydWN0X29iamVjdDxUPik7CisgICAgfQorICAgIHJldHVybiB0OworICB9CisKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIEFyZzEsIHR5cGVuYW1lIEFyZzIsIHR5cGVuYW1lIEFyZzMsCisgICAgICAgICAgICB0eXBlbmFtZSBBcmc0LCB0eXBlbmFtZSBBcmc1PgorICBHT09HTEVfQVRUUklCVVRFX0FMV0FZU19JTkxJTkUgVCogQ3JlYXRlSW50ZXJuYWwoYm9vbCBza2lwX2V4cGxpY2l0X293bmVyc2hpcCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQXJnMSYgYXJnMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQXJnMiYgYXJnMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQXJnMyYgYXJnMywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQXJnNCYgYXJnNCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQXJnNSYgYXJnNSkgeworICAgIFQqIHQgPSBuZXcgKEFsbG9jYXRlQWxpZ25lZChSVFRJX1RZUEVfSUQoVCksIHNpemVvZihUKSkpCisgICAgICAgIFQoYXJnMSwgYXJnMiwgYXJnMywgYXJnNCwgYXJnNSk7CisgICAgaWYgKCFza2lwX2V4cGxpY2l0X293bmVyc2hpcCkgeworICAgICAgQWRkTGlzdE5vZGUodCwgJmludGVybmFsOjphcmVuYV9kZXN0cnVjdF9vYmplY3Q8VD4pOworICAgIH0KKyAgICByZXR1cm4gdDsKKyAgfQorCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBULCB0eXBlbmFtZSBBcmcxLCB0eXBlbmFtZSBBcmcyLCB0eXBlbmFtZSBBcmczLAorICAgICAgICAgICAgdHlwZW5hbWUgQXJnNCwgdHlwZW5hbWUgQXJnNSwgdHlwZW5hbWUgQXJnNj4KKyAgR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FIFQqIENyZWF0ZUludGVybmFsKGJvb2wgc2tpcF9leHBsaWNpdF9vd25lcnNoaXAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFyZzEmIGFyZzEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFyZzImIGFyZzIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFyZzMmIGFyZzMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFyZzQmIGFyZzQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFyZzUmIGFyZzUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFyZzYmIGFyZzYpIHsKKyAgICBUKiB0ID0gbmV3IChBbGxvY2F0ZUFsaWduZWQoUlRUSV9UWVBFX0lEKFQpLCBzaXplb2YoVCkpKQorICAgICAgICBUKGFyZzEsIGFyZzIsIGFyZzMsIGFyZzQsIGFyZzUsIGFyZzYpOworICAgIGlmICghc2tpcF9leHBsaWNpdF9vd25lcnNoaXApIHsKKyAgICAgIEFkZExpc3ROb2RlKHQsICZpbnRlcm5hbDo6YXJlbmFfZGVzdHJ1Y3Rfb2JqZWN0PFQ+KTsKKyAgICB9CisgICAgcmV0dXJuIHQ7CisgIH0KKworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgQXJnMSwgdHlwZW5hbWUgQXJnMiwgdHlwZW5hbWUgQXJnMywKKyAgICAgICAgICAgIHR5cGVuYW1lIEFyZzQsIHR5cGVuYW1lIEFyZzUsIHR5cGVuYW1lIEFyZzYsIHR5cGVuYW1lIEFyZzc+CisgIEdPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORSBUKiBDcmVhdGVJbnRlcm5hbChib29sIHNraXBfZXhwbGljaXRfb3duZXJzaGlwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBBcmcxJiBhcmcxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBBcmcyJiBhcmcyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBBcmczJiBhcmczLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBBcmc0JiBhcmc0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBBcmc1JiBhcmc1LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBBcmc2JiBhcmc2LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBBcmc3JiBhcmc3KSB7CisgICAgVCogdCA9IG5ldyAoQWxsb2NhdGVBbGlnbmVkKFJUVElfVFlQRV9JRChUKSwgc2l6ZW9mKFQpKSkKKyAgICAgICAgVChhcmcxLCBhcmcyLCBhcmczLCBhcmc0LCBhcmc1LCBhcmc2LCBhcmc3KTsKKyAgICBpZiAoIXNraXBfZXhwbGljaXRfb3duZXJzaGlwKSB7CisgICAgICBBZGRMaXN0Tm9kZSh0LCAmaW50ZXJuYWw6OmFyZW5hX2Rlc3RydWN0X29iamVjdDxUPik7CisgICAgfQorICAgIHJldHVybiB0OworICB9CisKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIEFyZzEsIHR5cGVuYW1lIEFyZzIsIHR5cGVuYW1lIEFyZzMsCisgICAgICAgICAgICB0eXBlbmFtZSBBcmc0LCB0eXBlbmFtZSBBcmc1LCB0eXBlbmFtZSBBcmc2LCB0eXBlbmFtZSBBcmc3LAorICAgICAgICAgICAgdHlwZW5hbWUgQXJnOD4KKyAgR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FIFQqIENyZWF0ZUludGVybmFsKGJvb2wgc2tpcF9leHBsaWNpdF9vd25lcnNoaXAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFyZzEmIGFyZzEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFyZzImIGFyZzIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFyZzMmIGFyZzMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFyZzQmIGFyZzQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFyZzUmIGFyZzUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFyZzYmIGFyZzYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFyZzcmIGFyZzcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFyZzgmIGFyZzgpIHsKKyAgICBUKiB0ID0gbmV3IChBbGxvY2F0ZUFsaWduZWQoUlRUSV9UWVBFX0lEKFQpLCBzaXplb2YoVCkpKQorICAgICAgICBUKGFyZzEsIGFyZzIsIGFyZzMsIGFyZzQsIGFyZzUsIGFyZzYsIGFyZzcsIGFyZzgpOworICAgIGlmICghc2tpcF9leHBsaWNpdF9vd25lcnNoaXApIHsKKyAgICAgIEFkZExpc3ROb2RlKHQsICZpbnRlcm5hbDo6YXJlbmFfZGVzdHJ1Y3Rfb2JqZWN0PFQ+KTsKKyAgICB9CisgICAgcmV0dXJuIHQ7CisgIH0KKworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4gR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FCisgIFQqIENyZWF0ZU1lc3NhZ2VJbnRlcm5hbCh0eXBlbmFtZSBUOjpJbnRlcm5hbEFyZW5hQ29uc3RydWN0YWJsZV8qKSB7CisgICAgcmV0dXJuIENyZWF0ZUludGVybmFsPFQsIEFyZW5hKj4oU2tpcERlbGV0ZUxpc3Q8VD4oc3RhdGljX2Nhc3Q8VCo+KDApKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzKTsKKyAgfQorCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBULCB0eXBlbmFtZSBBcmc+IEdPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORQorICBUKiBDcmVhdGVNZXNzYWdlSW50ZXJuYWwodHlwZW5hbWUgVDo6SW50ZXJuYWxBcmVuYUNvbnN0cnVjdGFibGVfKiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFyZyYgYXJnKSB7CisgICAgcmV0dXJuIENyZWF0ZUludGVybmFsPFQsIEFyZW5hKj4oU2tpcERlbGV0ZUxpc3Q8VD4oc3RhdGljX2Nhc3Q8VCo+KDApKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLCBhcmcpOworICB9CisKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIEFyZzEsIHR5cGVuYW1lIEFyZzI+IEdPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORQorICBUKiBDcmVhdGVNZXNzYWdlSW50ZXJuYWwodHlwZW5hbWUgVDo6SW50ZXJuYWxBcmVuYUNvbnN0cnVjdGFibGVfKiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFyZzEmIGFyZzEsIGNvbnN0IEFyZzImIGFyZzIpIHsKKyAgICByZXR1cm4gQ3JlYXRlSW50ZXJuYWw8VCwgQXJlbmEqPihTa2lwRGVsZXRlTGlzdDxUPihzdGF0aWNfY2FzdDxUKj4oMCkpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMsIGFyZzEsIGFyZzIpOworICB9CisKKyAgLy8gQ3JlYXRlSW5BcmVuYVN0b3JhZ2UgaXMgdXNlZCB0byBpbXBsZW1lbnQgbWFwIGZpZWxkLiBXaXRob3V0IGl0LAorICAvLyBnb29nbGU6OnByb3RvYnVmOjpNYXAgbmVlZCB0byBjYWxsIGdlbmVyYXRlZCBtZXNzYWdlJ3MgcHJvdGVjdGVkIGFyZW5hIGNvbnN0cnVjdG9yLAorICAvLyB3aGljaCBuZWVkcyB0byBkZWNsYXJlIGdvb2dsZTo6cHJvdG9idWY6Ok1hcCBhcyBmcmllbmQgb2YgZ2VuZXJhdGVkIG1lc3NhZ2UuCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUPgorICBzdGF0aWMgdm9pZCBDcmVhdGVJbkFyZW5hU3RvcmFnZShUKiBwdHIsIEFyZW5hKiBhcmVuYSkgeworICAgIENyZWF0ZUluQXJlbmFTdG9yYWdlSW50ZXJuYWwocHRyLCBhcmVuYSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVuYW1lIGlzX2FyZW5hX2NvbnN0cnVjdGFibGU8VD46OnR5cGUoKSk7CisgICAgUmVnaXN0ZXJEZXN0cnVjdG9ySW50ZXJuYWwocHRyLCBhcmVuYSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlbmFtZSBpc19kZXN0cnVjdG9yX3NraXBwYWJsZTxUPjo6dHlwZSgpKTsKKyAgfQorCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUPgorICBzdGF0aWMgdm9pZCBDcmVhdGVJbkFyZW5hU3RvcmFnZUludGVybmFsKAorICAgICAgVCogcHRyLCBBcmVuYSogYXJlbmEsIGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjp0cnVlX3R5cGUpIHsKKyAgICBuZXcgKHB0cikgVChhcmVuYSk7CisgIH0KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CisgIHN0YXRpYyB2b2lkIENyZWF0ZUluQXJlbmFTdG9yYWdlSW50ZXJuYWwoCisgICAgICBUKiBwdHIsIEFyZW5hKiBhcmVuYSwgZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OmZhbHNlX3R5cGUpIHsKKyAgICBuZXcgKHB0cikgVDsKKyAgfQorCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUPgorICBzdGF0aWMgdm9pZCBSZWdpc3RlckRlc3RydWN0b3JJbnRlcm5hbCgKKyAgICAgIFQqIHB0ciwgQXJlbmEqIGFyZW5hLCBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6dHJ1ZV90eXBlKSB7fQorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4KKyAgc3RhdGljIHZvaWQgUmVnaXN0ZXJEZXN0cnVjdG9ySW50ZXJuYWwoCisgICAgICBUKiBwdHIsIEFyZW5hKiBhcmVuYSwgZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OmZhbHNlX3R5cGUpIHsKKyAgICBhcmVuYS0+T3duRGVzdHJ1Y3RvcihwdHIpOworICB9CisKKyAgLy8gVGhlc2UgaW1wbGVtZW50IE93bigpLCB3aGljaCByZWdpc3RlcnMgYW4gb2JqZWN0IGZvciBkZWxldGlvbiAoZGVzdHJ1Y3RvcgorICAvLyBjYWxsIGFuZCBvcGVyYXRvciBkZWxldGUoKSkuIFRoZSBzZWNvbmQgcGFyYW1ldGVyIGhhcyB0eXBlICd0cnVlX3R5cGUnIGlmIFQKKyAgLy8gaXMgYSBzdWJ0eXBlIG9mIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSBhbmQgJ2ZhbHNlX3R5cGUnIG90aGVyd2lzZS4gQ29sbGFwc2luZworICAvLyBhbGwgdGVtcGxhdGUgaW5zdGFudGlhdGlvbnMgdG8gb25lIGZvciBnZW5lcmljIE1lc3NhZ2UgcmVkdWNlcyBjb2RlIHNpemUsCisgIC8vIHVzaW5nIHRoZSB2aXJ0dWFsIGRlc3RydWN0b3IgaW5zdGVhZC4KKyAgdGVtcGxhdGU8dHlwZW5hbWUgVD4gR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FCisgIHZvaWQgT3duSW50ZXJuYWwoVCogb2JqZWN0LCBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6dHJ1ZV90eXBlKSB7CisgICAgaWYgKG9iamVjdCAhPSBOVUxMKSB7CisgICAgICBBZGRMaXN0Tm9kZShvYmplY3QsICZpbnRlcm5hbDo6YXJlbmFfZGVsZXRlX29iamVjdDwgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlID4pOworICAgIH0KKyAgfQorICB0ZW1wbGF0ZTx0eXBlbmFtZSBUPiBHT09HTEVfQVRUUklCVVRFX0FMV0FZU19JTkxJTkUKKyAgdm9pZCBPd25JbnRlcm5hbChUKiBvYmplY3QsIGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpmYWxzZV90eXBlKSB7CisgICAgaWYgKG9iamVjdCAhPSBOVUxMKSB7CisgICAgICBBZGRMaXN0Tm9kZShvYmplY3QsICZpbnRlcm5hbDo6YXJlbmFfZGVsZXRlX29iamVjdDxUPik7CisgICAgfQorICB9CisKKyAgLy8gSW1wbGVtZW50YXRpb24gZm9yIEdldEFyZW5hKCkuIE9ubHkgbWVzc2FnZSBvYmplY3RzIHdpdGgKKyAgLy8gSW50ZXJuYWxBcmVuYUNvbnN0cnVjdGFibGVfIHRhZ3MgY2FuIGJlIGFzc29jaWF0ZWQgd2l0aCBhbiBhcmVuYSwgYW5kIHN1Y2gKKyAgLy8gb2JqZWN0cyBtdXN0IGltcGxlbWVudCBhIEdldEFyZW5hTm9WaXJ0dWFsKCkgbWV0aG9kLgorICB0ZW1wbGF0ZTx0eXBlbmFtZSBUPiBHT09HTEVfQVRUUklCVVRFX0FMV0FZU19JTkxJTkUKKyAgc3RhdGljIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hSW50ZXJuYWwoCisgICAgICBjb25zdCBUKiB2YWx1ZSwgdHlwZW5hbWUgVDo6SW50ZXJuYWxBcmVuYUNvbnN0cnVjdGFibGVfKikgeworICAgIHJldHVybiB2YWx1ZS0+R2V0QXJlbmFOb1ZpcnR1YWwoKTsKKyAgfQorCisgIHRlbXBsYXRlPHR5cGVuYW1lIFQ+IEdPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORQorICBzdGF0aWMgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogR2V0QXJlbmFJbnRlcm5hbChjb25zdCBUKiB2YWx1ZSwgLi4uKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKworICAvLyBBbGxvY2F0ZSBhbmQgYWxzbyBvcHRpb25hbGx5IGNhbGwgb25fYXJlbmFfYWxsb2NhdGlvbiBjYWxsYmFjayB3aXRoIHRoZQorICAvLyBhbGxvY2F0ZWQgdHlwZSBpbmZvIHdoZW4gdGhlIGhvb2tzIGFyZSBpbiBwbGFjZSBpbiBBcmVuYU9wdGlvbnMgYW5kCisgIC8vIHRoZSBjb29raWUgaXMgbm90IG51bGwuCisgIHZvaWQqIEFsbG9jYXRlQWxpZ25lZChjb25zdCBzdGQ6OnR5cGVfaW5mbyogYWxsb2NhdGVkLCBzaXplX3Qgbik7CisKKyAgLy8gQWxsb2NhdGUgYW4gaW50ZXJuYWwgYWxsb2NhdGlvbiwgYXZvaWRpbmcgb3B0aW9uYWwgdHlwZWQgbW9uaXRvcmluZy4KKyAgR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FIHZvaWQqIEFsbG9jYXRlQWxpZ25lZChzaXplX3QgbikgeworICAgIHJldHVybiBBbGxvY2F0ZUFsaWduZWQoTlVMTCwgbik7CisgIH0KKworICB2b2lkIEluaXQoKTsKKworICAvLyBGcmVlIGFsbCBibG9ja3MgYW5kIHJldHVybiB0aGUgdG90YWwgc3BhY2UgdXNlZCB3aGljaCBpcyB0aGUgc3VtcyBvZiBzaXplcworICAvLyBvZiB0aGUgYWxsIHRoZSBhbGxvY2F0ZWQgYmxvY2tzLgorICB1aW50NjQgRnJlZUJsb2NrcygpOworCisgIC8vIEFkZCBvYmplY3QgcG9pbnRlciBhbmQgY2xlYW51cCBmdW5jdGlvbiBwb2ludGVyIHRvIHRoZSBsaXN0LgorICAvLyBUT0RPKHJvaGFuYW5pbCwgY2ZhbGxpbik6IFdlIGNvdWxkIHBhc3MgaW4gYSBzdWItYXJlbmEgaW50byB0aGlzIG1ldGhvZAorICAvLyB0byBhdm9pZCBwb2xsdXRpbmcgYmxvY2tzIG9mIHRoaXMgYXJlbmEgd2l0aCBsaXN0IG5vZGVzLiBUaGlzIHdvdWxkIGhlbHAgaW4KKyAgLy8gbWl4ZWQgbW9kZSAod2hlcmUgbWFueSBwcm90b2J1ZnMgaGF2ZSBjY19lbmFibGVfYXJlbmFzPWZhbHNlKSwgYW5kIGlzIGFuCisgIC8vIGFsdGVybmF0aXZlIHRvIGEgY2h1bmtlZCBsaW5rZWQtbGlzdCwgYnV0IHdpdGggZXh0cmEgb3ZlcmhlYWQgb2YgKm5leHQuCisgIHZvaWQgQWRkTGlzdE5vZGUodm9pZCogZWxlbSwgdm9pZCAoKmNsZWFudXApKHZvaWQqKSk7CisgIC8vIERlbGV0ZSBvciBEZXN0cnVjdCBhbGwgb2JqZWN0cyBvd25lZCBieSB0aGUgYXJlbmEuCisgIHZvaWQgQ2xlYW51cExpc3QoKTsKKyAgdWludDY0IFJlc2V0SW50ZXJuYWwoKTsKKworICBpbmxpbmUgdm9pZCBTZXRUaHJlYWRDYWNoZUJsb2NrKEJsb2NrKiBibG9jaykgeworICAgIHRocmVhZF9jYWNoZSgpLmxhc3RfYmxvY2tfdXNlZF8gPSBibG9jazsKKyAgICB0aHJlYWRfY2FjaGUoKS5sYXN0X2xpZmVjeWNsZV9pZF9zZWVuID0gbGlmZWN5Y2xlX2lkXzsKKyAgfQorCisgIGludDY0IGxpZmVjeWNsZV9pZF87ICAvLyBVbmlxdWUgZm9yIGVhY2ggYXJlbmEuIENoYW5nZXMgb24gUmVzZXQoKS4KKworICBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QXRvbWljV29yZCBibG9ja3NfOyAgLy8gSGVhZCBvZiBsaW5rZWQgbGlzdCBvZiBhbGwgYWxsb2NhdGVkIGJsb2NrcworICBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QXRvbWljV29yZCBoaW50XzsgICAgLy8gRmFzdCB0aHJlYWQtbG9jYWwgYmxvY2sgYWNjZXNzCisKKyAgLy8gTm9kZSBjb250YWlucyB0aGUgcHRyIG9mIHRoZSBvYmplY3QgdG8gYmUgY2xlYW5lZCB1cCBhbmQgdGhlIGFzc29jaWF0ZWQKKyAgLy8gY2xlYW51cCBmdW5jdGlvbiBwdHIuCisgIHN0cnVjdCBOb2RlIHsKKyAgICB2b2lkKiBlbGVtOyAgICAgICAgICAgICAgLy8gUG9pbnRlciB0byB0aGUgb2JqZWN0IHRvIGJlIGNsZWFuZWQgdXAuCisgICAgdm9pZCAoKmNsZWFudXApKHZvaWQqKTsgIC8vIEZ1bmN0aW9uIHBvaW50ZXIgdG8gdGhlIGRlc3RydWN0b3Igb3IgZGVsZXRlci4KKyAgICBOb2RlKiBuZXh0OyAgICAgICAgICAgICAgLy8gTmV4dCBub2RlIGluIHRoZSBsaXN0LgorICB9OworCisgIGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBdG9taWNXb3JkIGNsZWFudXBfbGlzdF87ICAvLyBIZWFkIG9mIGEgbGlua2VkIGxpc3Qgb2Ygbm9kZXMgY29udGFpbmluZyBvYmplY3QKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcHRycyBhbmQgY2xlYW51cCBtZXRob2RzLgorCisgIGJvb2wgb3duc19maXJzdF9ibG9ja187ICAgIC8vIEluZGljYXRlcyB0aGF0IGFyZW5hIG93bnMgdGhlIGZpcnN0IGJsb2NrCisgIE11dGV4IGJsb2Nrc19sb2NrXzsKKworICB2b2lkIEFkZEJsb2NrKEJsb2NrKiBiKTsKKyAgLy8gQWNjZXNzIG11c3QgYmUgc3luY2hyb25pemVkLCBlaXRoZXIgYnkgYmxvY2tzX2xvY2tfIG9yIGJ5IGJlaW5nIGNhbGxlZCBmcm9tCisgIC8vIEluaXQoKS9SZXNldCgpLgorICB2b2lkIEFkZEJsb2NrSW50ZXJuYWwoQmxvY2sqIGIpOworICB2b2lkKiBTbG93QWxsb2Moc2l6ZV90IG4pOworICBCbG9jayogRmluZEJsb2NrKHZvaWQqIG1lKTsKKyAgQmxvY2sqIE5ld0Jsb2NrKHZvaWQqIG1lLCBCbG9jayogbXlfbGFzdF9ibG9jaywgc2l6ZV90IG4sCisgICAgICAgICAgICAgICAgICBzaXplX3Qgc3RhcnRfYmxvY2tfc2l6ZSwgc2l6ZV90IG1heF9ibG9ja19zaXplKTsKKyAgc3RhdGljIHZvaWQqIEFsbG9jRnJvbUJsb2NrKEJsb2NrKiBiLCBzaXplX3Qgbik7CisgIHRlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIFQ+CisgIGZyaWVuZCBjbGFzcyBNYXA7CisKKyAgLy8gVGhlIGFyZW5hIG1heSBzYXZlIGEgY29va2llIGl0IHJlY2VpdmVzIGZyb20gdGhlIGV4dGVybmFsIG9uX2luaXQgaG9vaworICAvLyBhbmQgdGhlbiB1c2UgaXQgd2hlbiBjYWxsaW5nIHRoZSBvbl9yZXNldCBhbmQgb25fZGVzdHJ1Y3Rpb24gaG9va3MuCisgIHZvaWQqIGhvb2tzX2Nvb2tpZV87CisKKyAgQXJlbmFPcHRpb25zIG9wdGlvbnNfOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhBcmVuYSk7Cit9OworCisvLyBEZWZpbmVkIGFib3ZlIGZvciBzdXBwb3J0aW5nIGVudmlyb25tZW50cyB3aXRob3V0IFJUVEkuCisjdW5kZWYgUlRUSV9UWVBFX0lECisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9BUkVOQV9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvYXJlbmFfbmMuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2FyZW5hX25jLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYyZjA4NDIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2FyZW5hX25jLmNjCkBAIC0wLDAgKzEsNDUgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBOZWdhdGl2ZSBjb21waWxhdGlvbiB0ZXN0IGZvciBhcmVuYSB1c2FnZS4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9hcmVuYS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wYi5oPgorCisjaWZkZWYgVEVTVF9BUkVOQV9QUklWQVRFX0NPTlNUUlVDVE9SCisKK25hbWVzcGFjZSBnb29nbGUgewordm9pZCBBcmVuYVByaXZhdGVDb25zdHJ1Y3RvcigpIHsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEgYXJlbmE7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZSgmYXJlbmEpOworfQorCisjZW5kaWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvYXJlbmFfbmNfdGVzdC5weSBiL3NyYy9nb29nbGUvcHJvdG9idWYvYXJlbmFfbmNfdGVzdC5weQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44N2E2OWIyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9hcmVuYV9uY190ZXN0LnB5CkBAIC0wLDAgKzEsNjEgQEAKKyMhIC91c3IvYmluL2VudiBweXRob24KKyMKKyMgUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisjIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorIyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworIworIyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKyMgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorIyBtZXQ6CisjCisjICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisjIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKyMgICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorIyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisjIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKyMgZGlzdHJpYnV0aW9uLgorIyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisjIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisjIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisjCisjIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKyMgIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKyMgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisjIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisjIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorIyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisjIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorIyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKyMgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorIyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKyMgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworIiIiTmVnYXRpdmUgY29tcGlsYXRpb24gdW5pdCB0ZXN0cyBmb3IgYXJlbmEgQVBJLiIiIgorCitpbXBvcnQgdW5pdHRlc3QKKworZnJvbSBnb29nbGUzLnRlc3RpbmcucHliYXNlIGltcG9ydCBmYWtlX3RhcmdldF91dGlsCitpbXBvcnQgdW5pdHRlc3QKKworCitjbGFzcyBBcmVuYU5jVGVzdCh1bml0dGVzdC5UZXN0Q2FzZSk6CisKKyAgZGVmIHRlc3RDb21waWxlckVycm9ycyhzZWxmKToKKyAgICAiIiJSdW5zIGEgbGlzdCBvZiB0ZXN0cyB0byB2ZXJpZnkgY29tcGlsZXIgZXJyb3IgbWVzc2FnZXMuIiIiCisKKyAgICAjIERlZmluZXMgYSBsaXN0IG9mIHRlc3Qgc3BlY3MsIHdoZXJlIGVhY2ggZWxlbWVudCBpcyBhIHR1cGxlCisgICAgIyAodGVzdCBuYW1lLCBsaXN0IG9mIHJlZ2V4ZXMgZm9yIG1hdGNoaW5nIHRoZSBjb21waWxlciBlcnJvcnMpLgorICAgIHRlc3Rfc3BlY3MgPSBbCisgICAgICAgICgnQVJFTkFfUFJJVkFURV9DT05TVFJVQ1RPUicsCisgICAgICAgICBbcidjYWxsaW5nIGEgcHJvdGVjdGVkIGNvbnN0cnVjdG9yJ10pLAorICAgICAgICAoJ1NBTklUWScsIE5vbmUpXQorCisgICAgZmFrZV90YXJnZXRfdXRpbC5Bc3NlcnRDY0NvbXBpbGVyRXJyb3JzKAorICAgICAgICBzZWxmLCAgICAgICAgICAgICAgICAgICAgICAgICAjIFRoZSBjdXJyZW50IHRlc3QgY2FzZS4KKyAgICAgICAgJ2dvb2dsZTMvZ29vZ2xlL3Byb3RvYnVmL2FyZW5hX25jJywgICMgVGhlIGZha2UgdGFyZ2V0IGZpbGUuCisgICAgICAgICdhcmVuYV9uYy5vJywgICAgICAgICAgICAgICAgICMgVGhlIHN1Yi10YXJnZXQgdG8gYnVpbGQuCisgICAgICAgIHRlc3Rfc3BlY3MgICAgICAgICAgICAgICAgICAgICMgTGlzdCBvZiB0ZXN0IHNwZWNpZmljYXRpb25zLgorICAgICAgICApCisKK2lmIF9fbmFtZV9fID09ICdfX21haW5fXyc6CisgIHVuaXR0ZXN0Lm1haW4oKQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9hcmVuYV90ZXN0X3V0aWwuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2FyZW5hX3Rlc3RfdXRpbC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZjljNWJkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9hcmVuYV90ZXN0X3V0aWwuY2MKQEAgLTAsMCArMSw1MCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbG9nZ2luZy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvYXJlbmFfdGVzdF91dGlsLmg+CisKKworI2RlZmluZSBFWFBFQ1RfRVEgR09PR0xFX0NIRUNLX0VRCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKK05vSGVhcENoZWNrZXI6On5Ob0hlYXBDaGVja2VyKCkgeworICBjYXB0dXJlX2FsbG9jLlVuaG9vaygpOworICBFWFBFQ1RfRVEoMCwgY2FwdHVyZV9hbGxvYy5hbGxvY19jb3VudCgpKTsKKyAgRVhQRUNUX0VRKDAsIGNhcHR1cmVfYWxsb2MuZnJlZV9jb3VudCgpKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvYXJlbmFfdGVzdF91dGlsLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2FyZW5hX3Rlc3RfdXRpbC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY5MGNjNzAKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2FyZW5hX3Rlc3RfdXRpbC5oCkBAIC0wLDAgKzEsNjAgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9BUkVOQV9URVNUX1VUSUxfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9BUkVOQV9URVNUX1VUSUxfSF9fCisKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKworY2xhc3MgTm9IZWFwQ2hlY2tlciB7CisgcHVibGljOgorICBOb0hlYXBDaGVja2VyKCkgeworICAgIGNhcHR1cmVfYWxsb2MuSG9vaygpOworICB9CisgIH5Ob0hlYXBDaGVja2VyKCk7CisgcHJpdmF0ZToKKyAgY2xhc3MgTmV3RGVsZXRlQ2FwdHVyZSB7CisgICBwdWJsaWM6CisgICAgLy8gVE9PRCh4aWFvZmVuZyk6IEltcGxlbWVudCB0aGlzIGZvciBvcGVuc291cmNlIHByb3RvYnVmLgorICAgIHZvaWQgSG9vaygpIHt9CisgICAgdm9pZCBVbmhvb2soKSB7fQorICAgIGludCBhbGxvY19jb3VudCgpIHsgcmV0dXJuIDA7IH0KKyAgICBpbnQgZnJlZV9jb3VudCgpIHsgcmV0dXJuIDA7IH0KKyAgfSBjYXB0dXJlX2FsbG9jOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQVJFTkFfVEVTVF9VVElMX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9hcmVuYV91bml0dGVzdC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvYXJlbmFfdW5pdHRlc3QuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmI2N2Y0NAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvYXJlbmFfdW5pdHRlc3QuY2MKQEAgLTAsMCArMSwxMjk2IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9hcmVuYS5oPgorCisjaW5jbHVkZSA8YWxnb3JpdGhtPgorI2luY2x1ZGUgPGNzdHJpbmc+CisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDx0eXBlaW5mbz4KKyNpbmNsdWRlIDx2ZWN0b3I+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbG9nZ2luZy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc2NvcGVkX3B0ci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9hcmVuYV90ZXN0X3V0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdF91dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2FyZW5hLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X25vX2FyZW5hLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX2ltcGxfbGl0ZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2V4dGVuc2lvbl9zZXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWVzc2FnZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tZXNzYWdlX2xpdGUuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcmVwZWF0ZWRfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bmtub3duX2ZpZWxkX3NldC5oPgorI2luY2x1ZGUgPGd0ZXN0L2d0ZXN0Lmg+CisKKworbmFtZXNwYWNlIGdvb2dsZSB7Cit1c2luZyBwcm90bzJfYXJlbmFfdW5pdHRlc3Q6OkFyZW5hTWVzc2FnZTsKK3VzaW5nIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXM7Cit1c2luZyBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnM7Cit1c2luZyBwcm90b2J1Zl91bml0dGVzdDo6VGVzdE9uZW9mMjsKK3VzaW5nIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0RW1wdHlNZXNzYWdlOworCituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIHsKKworY2xhc3MgTm90aWZpZXIgeworIHB1YmxpYzoKKyAgTm90aWZpZXIoKSA6IGNvdW50XygwKSB7fQorICB2b2lkIE5vdGlmeSgpIHsKKyAgICBjb3VudF8rKzsKKyAgfQorICBpbnQgR2V0Q291bnQoKSB7CisgICAgcmV0dXJuIGNvdW50XzsKKyAgfQorCisgcHJpdmF0ZToKKyAgaW50IGNvdW50XzsKK307CisKK2NsYXNzIFNpbXBsZURhdGFUeXBlIHsKKyBwdWJsaWM6CisgIFNpbXBsZURhdGFUeXBlKCkgOiBub3RpZmllcl8oTlVMTCkge30KKyAgdm9pZCBTZXROb3RpZmllcihOb3RpZmllciogbm90aWZpZXIpIHsKKyAgICBub3RpZmllcl8gPSBub3RpZmllcjsKKyAgfQorICB2aXJ0dWFsIH5TaW1wbGVEYXRhVHlwZSgpIHsKKyAgICBpZiAobm90aWZpZXJfICE9IE5VTEwpIHsKKyAgICAgIG5vdGlmaWVyXy0+Tm90aWZ5KCk7CisgICAgfQorICB9OworIHByaXZhdGU6CisgIE5vdGlmaWVyKiBub3RpZmllcl87Cit9OworCisvLyBBIHNpbXBsZSBjbGFzcyB0aGF0IGRvZXMgbm90IGFsbG93IGNvcHlpbmcgYW5kIHNvIGNhbm5vdCBiZSB1c2VkIGFzIGEKKy8vIHBhcmFtZXRlciB0eXBlIHdpdGhvdXQgImNvbnN0ICYiLgorY2xhc3MgUGxlYXNlRG9udENvcHlNZSB7CisgcHVibGljOgorICBleHBsaWNpdCBQbGVhc2VEb250Q29weU1lKGludCB2YWx1ZSkgOiB2YWx1ZV8odmFsdWUpIHt9CisKKyAgaW50IHZhbHVlKCkgY29uc3QgeyByZXR1cm4gdmFsdWVfOyB9CisKKyBwcml2YXRlOgorICBpbnQgdmFsdWVfOworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoUGxlYXNlRG9udENvcHlNZSk7Cit9OworCisvLyBBIGNsYXNzIHRoYXQgdGFrZXMgZm91ciBkaWZmZXJlbnQgdHlwZXMgYXMgY29uc3RydWN0b3IgYXJndW1lbnRzLgorY2xhc3MgTXVzdEJlQ29uc3RydWN0ZWRXaXRoT25lVGhyb3VnaEZvdXIgeworIHB1YmxpYzoKKyAgTXVzdEJlQ29uc3RydWN0ZWRXaXRoT25lVGhyb3VnaEZvdXIoCisgICAgICBpbnQgb25lLCBjb25zdCBjaGFyKiB0d28sIGNvbnN0IHN0cmluZyYgdGhyZWUsCisgICAgICBjb25zdCBQbGVhc2VEb250Q29weU1lKiBmb3VyKQorICAgICAgOiBvbmVfKG9uZSksIHR3b18odHdvKSwgdGhyZWVfKHRocmVlKSwgZm91cl8oZm91cikge30KKworICBpbnQgb25lXzsKKyAgY29uc3QgY2hhciogY29uc3QgdHdvXzsKKyAgc3RyaW5nIHRocmVlXzsKKyAgY29uc3QgUGxlYXNlRG9udENvcHlNZSogZm91cl87CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoTXVzdEJlQ29uc3RydWN0ZWRXaXRoT25lVGhyb3VnaEZvdXIpOworfTsKKworLy8gQSBjbGFzcyB0aGF0IHRha2VzIGVpZ2h0IGRpZmZlcmVudCB0eXBlcyBhcyBjb25zdHJ1Y3RvciBhcmd1bWVudHMuCitjbGFzcyBNdXN0QmVDb25zdHJ1Y3RlZFdpdGhPbmVUaHJvdWdoRWlnaHQgeworIHB1YmxpYzoKKyAgTXVzdEJlQ29uc3RydWN0ZWRXaXRoT25lVGhyb3VnaEVpZ2h0KAorICAgICAgaW50IG9uZSwgY29uc3QgY2hhciogdHdvLCBjb25zdCBzdHJpbmcmIHRocmVlLAorICAgICAgY29uc3QgUGxlYXNlRG9udENvcHlNZSogZm91ciwgaW50IGZpdmUsIGNvbnN0IGNoYXIqIHNpeCwKKyAgICAgIGNvbnN0IHN0cmluZyYgc2V2ZW4sIGNvbnN0IHN0cmluZyYgZWlnaHQpCisgICAgICA6IG9uZV8ob25lKSwgdHdvXyh0d28pLCB0aHJlZV8odGhyZWUpLCBmb3VyXyhmb3VyKSwgZml2ZV8oZml2ZSksCisgICAgICAgIHNpeF8oc2l4KSwgc2V2ZW5fKHNldmVuKSwgZWlnaHRfKGVpZ2h0KSB7fQorCisgIGludCBvbmVfOworICBjb25zdCBjaGFyKiBjb25zdCB0d29fOworICBzdHJpbmcgdGhyZWVfOworICBjb25zdCBQbGVhc2VEb250Q29weU1lKiBmb3VyXzsKKyAgaW50IGZpdmVfOworICBjb25zdCBjaGFyKiBjb25zdCBzaXhfOworICBzdHJpbmcgc2V2ZW5fOworICBzdHJpbmcgZWlnaHRfOworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKE11c3RCZUNvbnN0cnVjdGVkV2l0aE9uZVRocm91Z2hFaWdodCk7Cit9OworCit9ICAvLyBuYW1lc3BhY2UKKworVEVTVChBcmVuYVRlc3QsIEFyZW5hQ29uc3RydWN0YWJsZSkgeworICBFWFBFQ1RfVFJVRShBcmVuYTo6aXNfYXJlbmFfY29uc3RydWN0YWJsZTxUZXN0QWxsVHlwZXM+Ojp0eXBlOjp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKEFyZW5hOjppc19hcmVuYV9jb25zdHJ1Y3RhYmxlPGNvbnN0IFRlc3RBbGxUeXBlcz46OnR5cGU6OnZhbHVlKTsKKyAgRVhQRUNUX0ZBTFNFKEFyZW5hOjppc19hcmVuYV9jb25zdHJ1Y3RhYmxlPEFyZW5hPjo6dHlwZTo6dmFsdWUpOworfQorCitURVNUKEFyZW5hVGVzdCwgQmFzaWNDcmVhdGUpIHsKKyAgQXJlbmEgYXJlbmE7CisgIEVYUEVDVF9UUlVFKEFyZW5hOjpDcmVhdGU8aW50MzI+KCZhcmVuYSkgIT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKEFyZW5hOjpDcmVhdGU8aW50NjQ+KCZhcmVuYSkgIT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKEFyZW5hOjpDcmVhdGU8ZmxvYXQ+KCZhcmVuYSkgIT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKEFyZW5hOjpDcmVhdGU8ZG91YmxlPigmYXJlbmEpICE9IE5VTEwpOworICBFWFBFQ1RfVFJVRShBcmVuYTo6Q3JlYXRlPHN0cmluZz4oJmFyZW5hKSAhPSBOVUxMKTsKKyAgYXJlbmEuT3duKG5ldyBpbnQzMik7CisgIGFyZW5hLk93bihuZXcgaW50NjQpOworICBhcmVuYS5Pd24obmV3IGZsb2F0KTsKKyAgYXJlbmEuT3duKG5ldyBkb3VibGUpOworICBhcmVuYS5Pd24obmV3IHN0cmluZyk7CisgIGFyZW5hLk93bjxpbnQ+KE5VTEwpOworICBOb3RpZmllciBub3RpZmllcjsKKyAgU2ltcGxlRGF0YVR5cGUqIGRhdGEgPSBBcmVuYTo6Q3JlYXRlPFNpbXBsZURhdGFUeXBlPigmYXJlbmEpOworICBkYXRhLT5TZXROb3RpZmllcigmbm90aWZpZXIpOworICBkYXRhID0gbmV3IFNpbXBsZURhdGFUeXBlOworICBkYXRhLT5TZXROb3RpZmllcigmbm90aWZpZXIpOworICBhcmVuYS5Pd24oZGF0YSk7CisgIGFyZW5hLlJlc2V0KCk7CisgIEVYUEVDVF9FUSgyLCBub3RpZmllci5HZXRDb3VudCgpKTsKK30KKworVEVTVChBcmVuYVRlc3QsIENyZWF0ZVdpdGhGb3VyQ29uc3RydWN0b3JBcmd1bWVudHMpIHsKKyAgQXJlbmEgYXJlbmE7CisgIGNvbnN0IHN0cmluZyB0aHJlZSgiMyIpOworICBjb25zdCBQbGVhc2VEb250Q29weU1lIGZvdXIoNCk7CisgIGNvbnN0IE11c3RCZUNvbnN0cnVjdGVkV2l0aE9uZVRocm91Z2hGb3VyKiBuZXdfb2JqZWN0ID0KKyAgICAgIEFyZW5hOjpDcmVhdGU8TXVzdEJlQ29uc3RydWN0ZWRXaXRoT25lVGhyb3VnaEZvdXI+KAorICAgICAgICAgICZhcmVuYSwgMSwgIjIiLCB0aHJlZSwgJmZvdXIpOworICBFWFBFQ1RfVFJVRShuZXdfb2JqZWN0ICE9IE5VTEwpOworICBBU1NFUlRfRVEoMSwgbmV3X29iamVjdC0+b25lXyk7CisgIEFTU0VSVF9TVFJFUSgiMiIsIG5ld19vYmplY3QtPnR3b18pOworICBBU1NFUlRfRVEoIjMiLCBuZXdfb2JqZWN0LT50aHJlZV8pOworICBBU1NFUlRfRVEoNCwgbmV3X29iamVjdC0+Zm91cl8tPnZhbHVlKCkpOworfQorCitURVNUKEFyZW5hVGVzdCwgQ3JlYXRlV2l0aEVpZ2h0Q29uc3RydWN0b3JBcmd1bWVudHMpIHsKKyAgQXJlbmEgYXJlbmE7CisgIGNvbnN0IHN0cmluZyB0aHJlZSgiMyIpOworICBjb25zdCBQbGVhc2VEb250Q29weU1lIGZvdXIoNCk7CisgIGNvbnN0IHN0cmluZyBzZXZlbigiNyIpOworICBjb25zdCBzdHJpbmcgZWlnaHQoIjgiKTsKKyAgY29uc3QgTXVzdEJlQ29uc3RydWN0ZWRXaXRoT25lVGhyb3VnaEVpZ2h0KiBuZXdfb2JqZWN0ID0KKyAgICAgIEFyZW5hOjpDcmVhdGU8TXVzdEJlQ29uc3RydWN0ZWRXaXRoT25lVGhyb3VnaEVpZ2h0PigKKyAgICAgICAgICAmYXJlbmEsIDEsICIyIiwgdGhyZWUsICZmb3VyLCA1LCAiNiIsIHNldmVuLCBlaWdodCk7CisgIEVYUEVDVF9UUlVFKG5ld19vYmplY3QgIT0gTlVMTCk7CisgIEFTU0VSVF9FUSgxLCBuZXdfb2JqZWN0LT5vbmVfKTsKKyAgQVNTRVJUX1NUUkVRKCIyIiwgbmV3X29iamVjdC0+dHdvXyk7CisgIEFTU0VSVF9FUSgiMyIsIG5ld19vYmplY3QtPnRocmVlXyk7CisgIEFTU0VSVF9FUSg0LCBuZXdfb2JqZWN0LT5mb3VyXy0+dmFsdWUoKSk7CisgIEFTU0VSVF9FUSg1LCBuZXdfb2JqZWN0LT5maXZlXyk7CisgIEFTU0VSVF9TVFJFUSgiNiIsIG5ld19vYmplY3QtPnNpeF8pOworICBBU1NFUlRfRVEoIjciLCBuZXdfb2JqZWN0LT5zZXZlbl8pOworICBBU1NFUlRfRVEoIjgiLCBuZXdfb2JqZWN0LT5laWdodF8pOworfQorCitURVNUKEFyZW5hVGVzdCwgSW5pdGlhbEJsb2NrVG9vU21hbGwpIHsKKyAgLy8gQ29uc3RydWN0IGEgc21hbGwgKDY0IGJ5dGUpIGluaXRpYWwgYmxvY2sgb2YgbWVtb3J5IHRvIGJlIHVzZWQgYnkgdGhlCisgIC8vIGFyZW5hIGFsbG9jYXRvcjsgdGhlbiwgYWxsb2NhdGUgYW4gb2JqZWN0IHdoaWNoIHdpbGwgbm90IGZpdCBpbiB0aGUKKyAgLy8gaW5pdGlhbCBibG9jay4KKyAgc3RkOjp2ZWN0b3I8Y2hhcj4gYXJlbmFfYmxvY2soNjQpOworICBBcmVuYU9wdGlvbnMgb3B0aW9uczsKKyAgb3B0aW9ucy5pbml0aWFsX2Jsb2NrID0gJmFyZW5hX2Jsb2NrWzBdOworICBvcHRpb25zLmluaXRpYWxfYmxvY2tfc2l6ZSA9IGFyZW5hX2Jsb2NrLnNpemUoKTsKKyAgQXJlbmEgYXJlbmEob3B0aW9ucyk7CisKKyAgY2hhciogcCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmE6OkNyZWF0ZUFycmF5PGNoYXI+KCZhcmVuYSwgOTYpOworICB1aW50cHRyX3QgYWxsb2NhdGlvbiA9IHJlaW50ZXJwcmV0X2Nhc3Q8dWludHB0cl90PihwKTsKKworICAvLyBFbnN1cmUgdGhhdCB0aGUgYXJlbmEgYWxsb2NhdG9yIGRpZCBub3QgcmV0dXJuIG1lbW9yeSBwb2ludGluZyBpbnRvIHRoZQorICAvLyBpbml0aWFsIGJsb2NrIG9mIG1lbW9yeS4KKyAgdWludHB0cl90IGFyZW5hX3N0YXJ0ID0gcmVpbnRlcnByZXRfY2FzdDx1aW50cHRyX3Q+KCZhcmVuYV9ibG9ja1swXSk7CisgIHVpbnRwdHJfdCBhcmVuYV9lbmQgPSBhcmVuYV9zdGFydCArIGFyZW5hX2Jsb2NrLnNpemUoKTsKKyAgRVhQRUNUX0ZBTFNFKGFsbG9jYXRpb24gPj0gYXJlbmFfc3RhcnQgJiYgYWxsb2NhdGlvbiA8IGFyZW5hX2VuZCk7CisKKyAgLy8gV3JpdGUgdG8gdGhlIG1lbW9yeSB3ZSBhbGxvY2F0ZWQ7IHRoaXMgc2hvdWxkIChidXQgaXMgbm90IGd1YXJhbnRlZWQgdG8pCisgIC8vIHRyaWdnZXIgYSBjaGVjayBmb3IgaGVhcCBjb3JydXB0aW9uIGlmIHRoZSBvYmplY3Qgd2FzIGFsbG9jYXRlZCBmcm9tIHRoZQorICAvLyBpbml0aWFsbHktcHJvdmlkZWQgYmxvY2suCisgIG1lbXNldChwLCAnXDAnLCA5Nik7Cit9CisKK1RFU1QoQXJlbmFUZXN0LCBQYXJzaW5nKSB7CisgIFRlc3RBbGxUeXBlcyBvcmlnaW5hbDsKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmb3JpZ2luYWwpOworCisgIC8vIFRlc3QgbWVtb3J5IGxlYWsuCisgIEFyZW5hIGFyZW5hOworICBUZXN0QWxsVHlwZXMqIGFyZW5hX21lc3NhZ2UgPSBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxUZXN0QWxsVHlwZXM+KCZhcmVuYSk7CisgIGFyZW5hX21lc3NhZ2UtPlBhcnNlRnJvbVN0cmluZyhvcmlnaW5hbC5TZXJpYWxpemVBc1N0cmluZygpKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEZpZWxkc1NldCgqYXJlbmFfbWVzc2FnZSk7CisKKyAgLy8gVGVzdCB0aGF0IHN0cmluZyBmaWVsZHMgaGF2ZSBudWxsIHRlcm1pbmF0b3IgYnl0ZXMgKGVhcmxpZXIgYnVnKS4KKyAgRVhQRUNUX0VRKHN0cmxlbihvcmlnaW5hbC5vcHRpb25hbF9zdHJpbmcoKS5jX3N0cigpKSwKKyAgICAgICAgICAgIHN0cmxlbihhcmVuYV9tZXNzYWdlLT5vcHRpb25hbF9zdHJpbmcoKS5jX3N0cigpKSk7Cit9CisKK1RFU1QoQXJlbmFUZXN0LCBVbmtub3duRmllbGRzKSB7CisgIFRlc3RBbGxUeXBlcyBvcmlnaW5hbDsKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmb3JpZ2luYWwpOworCisgIC8vIFRlc3QgYmFzaWMgcGFyc2luZyBpbnRvIChwb3B1bGF0aW5nKSBhbmQgcmVhZGluZyBvdXQgb2YgdW5rbm93biBmaWVsZHMgb24KKyAgLy8gYW4gYXJlbmEuCisgIEFyZW5hIGFyZW5hOworICBUZXN0RW1wdHlNZXNzYWdlKiBhcmVuYV9tZXNzYWdlID0KKyAgICAgIEFyZW5hOjpDcmVhdGVNZXNzYWdlPFRlc3RFbXB0eU1lc3NhZ2U+KCZhcmVuYSk7CisgIGFyZW5hX21lc3NhZ2UtPlBhcnNlRnJvbVN0cmluZyhvcmlnaW5hbC5TZXJpYWxpemVBc1N0cmluZygpKTsKKworICBUZXN0QWxsVHlwZXMgY29waWVkOworICBjb3BpZWQuUGFyc2VGcm9tU3RyaW5nKGFyZW5hX21lc3NhZ2UtPlNlcmlhbGl6ZUFzU3RyaW5nKCkpOworICBUZXN0VXRpbDo6RXhwZWN0QWxsRmllbGRzU2V0KGNvcGllZCk7CisKKyAgLy8gRXhlcmNpc2UgVUZTIG1hbnVhbCBtYW5pcHVsYXRpb24gKHNldHRlcnMpLgorICBhcmVuYV9tZXNzYWdlID0gQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEVtcHR5TWVzc2FnZT4oJmFyZW5hKTsKKyAgYXJlbmFfbWVzc2FnZS0+bXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5BZGRWYXJpbnQoCisgICAgICBUZXN0QWxsVHlwZXM6OmtPcHRpb25hbEludDMyRmllbGROdW1iZXIsIDQyKTsKKyAgY29waWVkLkNsZWFyKCk7CisgIGNvcGllZC5QYXJzZUZyb21TdHJpbmcoYXJlbmFfbWVzc2FnZS0+U2VyaWFsaXplQXNTdHJpbmcoKSk7CisgIEVYUEVDVF9UUlVFKGNvcGllZC5oYXNfb3B0aW9uYWxfaW50MzIoKSk7CisgIEVYUEVDVF9FUSg0MiwgY29waWVkLm9wdGlvbmFsX2ludDMyKCkpOworCisgIC8vIEV4ZXJjaXNlIFVGUyBzd2FwIHBhdGguCisgIFRlc3RFbXB0eU1lc3NhZ2UqIGFyZW5hX21lc3NhZ2VfMiA9CisgICAgICBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxUZXN0RW1wdHlNZXNzYWdlPigmYXJlbmEpOworICBhcmVuYV9tZXNzYWdlXzItPlN3YXAoYXJlbmFfbWVzc2FnZSk7CisgIGNvcGllZC5DbGVhcigpOworICBjb3BpZWQuUGFyc2VGcm9tU3RyaW5nKGFyZW5hX21lc3NhZ2VfMi0+U2VyaWFsaXplQXNTdHJpbmcoKSk7CisgIEVYUEVDVF9UUlVFKGNvcGllZC5oYXNfb3B0aW9uYWxfaW50MzIoKSk7CisgIEVYUEVDVF9FUSg0MiwgY29waWVkLm9wdGlvbmFsX2ludDMyKCkpOworCisgIC8vIFRlc3QgZmllbGQgbWFuaXB1bGF0aW9uLgorICBUZXN0RW1wdHlNZXNzYWdlKiBhcmVuYV9tZXNzYWdlXzMgPQorICAgICAgQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEVtcHR5TWVzc2FnZT4oJmFyZW5hKTsKKyAgYXJlbmFfbWVzc2FnZV8zLT5tdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkFkZFZhcmludCgxMDAwLCA0Mik7CisgIGFyZW5hX21lc3NhZ2VfMy0+bXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5BZGRGaXhlZDMyKDEwMDEsIDQyKTsKKyAgYXJlbmFfbWVzc2FnZV8zLT5tdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkFkZEZpeGVkNjQoMTAwMiwgNDIpOworICBhcmVuYV9tZXNzYWdlXzMtPm11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+QWRkTGVuZ3RoRGVsaW1pdGVkKDEwMDMpOworICBhcmVuYV9tZXNzYWdlXzMtPm11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+RGVsZXRlU3VicmFuZ2UoMCwgMik7CisgIGFyZW5hX21lc3NhZ2VfMy0+bXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5EZWxldGVCeU51bWJlcigxMDAyKTsKKyAgYXJlbmFfbWVzc2FnZV8zLT5tdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkRlbGV0ZUJ5TnVtYmVyKDEwMDMpOworICBFWFBFQ1RfVFJVRShhcmVuYV9tZXNzYWdlXzMtPnVua25vd25fZmllbGRzKCkuZW1wdHkoKSk7Cit9CisKK1RFU1QoQXJlbmFUZXN0LCBTd2FwKSB7CisgIEFyZW5hIGFyZW5hMTsKKyAgQXJlbmEgYXJlbmEyOworICBUZXN0QWxsVHlwZXMqIGFyZW5hMV9tZXNzYWdlOworICBUZXN0QWxsVHlwZXMqIGFyZW5hMl9tZXNzYWdlOworCisgIC8vIENhc2UgMTogU3dhcCgpLCBubyBVRlMgb24gZWl0aGVyIG1lc3NhZ2UsIGJvdGggbWVzc2FnZXMgb24gZGlmZmVyZW50CisgIC8vIGFyZW5hcy4gQXJlbmEgcG9pbnRlcnMgc2hvdWxkIHJlbWFpbiB0aGUgc2FtZSBhZnRlciBzd2FwLgorICBhcmVuYTFfbWVzc2FnZSA9IEFyZW5hOjpDcmVhdGVNZXNzYWdlPFRlc3RBbGxUeXBlcz4oJmFyZW5hMSk7CisgIGFyZW5hMl9tZXNzYWdlID0gQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEFsbFR5cGVzPigmYXJlbmEyKTsKKyAgYXJlbmExX21lc3NhZ2UtPlN3YXAoYXJlbmEyX21lc3NhZ2UpOworICBFWFBFQ1RfRVEoJmFyZW5hMSwgYXJlbmExX21lc3NhZ2UtPkdldEFyZW5hKCkpOworICBFWFBFQ1RfRVEoJmFyZW5hMiwgYXJlbmEyX21lc3NhZ2UtPkdldEFyZW5hKCkpOworCisgIC8vIENhc2UgMjogU3dhcCgpLCBVRlMgb24gb25lIG1lc3NhZ2UsIGJvdGggbWVzc2FnZXMgb24gZGlmZmVyZW50IGFyZW5hcy4KKyAgYXJlbmExX21lc3NhZ2UgPSBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxUZXN0QWxsVHlwZXM+KCZhcmVuYTEpOworICBhcmVuYTJfbWVzc2FnZSA9IEFyZW5hOjpDcmVhdGVNZXNzYWdlPFRlc3RBbGxUeXBlcz4oJmFyZW5hMik7CisgIGFyZW5hMV9tZXNzYWdlLT5tdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkFkZFZhcmludCgxLCA0Mik7CisgIGFyZW5hMV9tZXNzYWdlLT5Td2FwKGFyZW5hMl9tZXNzYWdlKTsKKyAgRVhQRUNUX0VRKCZhcmVuYTEsIGFyZW5hMV9tZXNzYWdlLT5HZXRBcmVuYSgpKTsKKyAgRVhQRUNUX0VRKCZhcmVuYTIsIGFyZW5hMl9tZXNzYWdlLT5HZXRBcmVuYSgpKTsKKyAgRVhQRUNUX0VRKDAsIGFyZW5hMV9tZXNzYWdlLT51bmtub3duX2ZpZWxkcygpLmZpZWxkX2NvdW50KCkpOworICBFWFBFQ1RfRVEoMSwgYXJlbmEyX21lc3NhZ2UtPnVua25vd25fZmllbGRzKCkuZmllbGRfY291bnQoKSk7CisgIEVYUEVDVF9FUSg0MiwgYXJlbmEyX21lc3NhZ2UtPnVua25vd25fZmllbGRzKCkuZmllbGQoMCkudmFyaW50KCkpOworCisgIC8vIENhc2UgMzogU3dhcCgpLCBVRlMgb24gYm90aCBtZXNzYWdlcywgYm90aCBtZXNzYWdlcyBvbiBkaWZmZXJlbnQgYXJlbmFzLgorICBhcmVuYTFfbWVzc2FnZSA9IEFyZW5hOjpDcmVhdGVNZXNzYWdlPFRlc3RBbGxUeXBlcz4oJmFyZW5hMSk7CisgIGFyZW5hMl9tZXNzYWdlID0gQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEFsbFR5cGVzPigmYXJlbmEyKTsKKyAgYXJlbmExX21lc3NhZ2UtPm11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+QWRkVmFyaW50KDEsIDQyKTsKKyAgYXJlbmEyX21lc3NhZ2UtPm11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+QWRkVmFyaW50KDIsIDg0KTsKKyAgYXJlbmExX21lc3NhZ2UtPlN3YXAoYXJlbmEyX21lc3NhZ2UpOworICBFWFBFQ1RfRVEoJmFyZW5hMSwgYXJlbmExX21lc3NhZ2UtPkdldEFyZW5hKCkpOworICBFWFBFQ1RfRVEoJmFyZW5hMiwgYXJlbmEyX21lc3NhZ2UtPkdldEFyZW5hKCkpOworICBFWFBFQ1RfRVEoMSwgYXJlbmExX21lc3NhZ2UtPnVua25vd25fZmllbGRzKCkuZmllbGRfY291bnQoKSk7CisgIEVYUEVDVF9FUSgxLCBhcmVuYTJfbWVzc2FnZS0+dW5rbm93bl9maWVsZHMoKS5maWVsZF9jb3VudCgpKTsKKyAgRVhQRUNUX0VRKDg0LCBhcmVuYTFfbWVzc2FnZS0+dW5rbm93bl9maWVsZHMoKS5maWVsZCgwKS52YXJpbnQoKSk7CisgIEVYUEVDVF9FUSg0MiwgYXJlbmEyX21lc3NhZ2UtPnVua25vd25fZmllbGRzKCkuZmllbGQoMCkudmFyaW50KCkpOworfQorCitURVNUKEFyZW5hVGVzdCwgU2V0QWxsb2NhdGVkTWVzc2FnZSkgeworICBBcmVuYSBhcmVuYTsKKyAgVGVzdEFsbFR5cGVzICphcmVuYV9tZXNzYWdlID0gQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEFsbFR5cGVzPigmYXJlbmEpOworICBUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2UqIG5lc3RlZCA9IG5ldyBUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2U7CisgIG5lc3RlZC0+c2V0X2JiKDExOCk7CisgIGFyZW5hX21lc3NhZ2UtPnNldF9hbGxvY2F0ZWRfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UobmVzdGVkKTsKKyAgRVhQRUNUX0VRKDExOCwgYXJlbmFfbWVzc2FnZS0+b3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKS5iYigpKTsKKworICBwcm90b2J1Zl91bml0dGVzdF9ub19hcmVuYTo6VGVzdE5vQXJlbmFNZXNzYWdlIG5vX2FyZW5hX21lc3NhZ2U7CisgIEVYUEVDVF9GQUxTRShub19hcmVuYV9tZXNzYWdlLmhhc19hcmVuYV9tZXNzYWdlKCkpOworICBub19hcmVuYV9tZXNzYWdlLnNldF9hbGxvY2F0ZWRfYXJlbmFfbWVzc2FnZShOVUxMKTsKKyAgRVhQRUNUX0ZBTFNFKG5vX2FyZW5hX21lc3NhZ2UuaGFzX2FyZW5hX21lc3NhZ2UoKSk7CisgIG5vX2FyZW5hX21lc3NhZ2Uuc2V0X2FsbG9jYXRlZF9hcmVuYV9tZXNzYWdlKG5ldyBBcmVuYU1lc3NhZ2UpOworICBFWFBFQ1RfVFJVRShub19hcmVuYV9tZXNzYWdlLmhhc19hcmVuYV9tZXNzYWdlKCkpOworfQorCitURVNUKEFyZW5hVGVzdCwgUmVsZWFzZU1lc3NhZ2UpIHsKKyAgQXJlbmEgYXJlbmE7CisgIFRlc3RBbGxUeXBlcyogYXJlbmFfbWVzc2FnZSA9IEFyZW5hOjpDcmVhdGVNZXNzYWdlPFRlc3RBbGxUeXBlcz4oJmFyZW5hKTsKKyAgYXJlbmFfbWVzc2FnZS0+bXV0YWJsZV9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpLT5zZXRfYmIoMTE4KTsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2U+IG5lc3RlZCgKKyAgICAgIGFyZW5hX21lc3NhZ2UtPnJlbGVhc2Vfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKSk7CisgIEVYUEVDVF9FUSgxMTgsIG5lc3RlZC0+YmIoKSk7CisKKyAgVGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlKiByZWxlYXNlZF9udWxsID0KKyAgICAgIGFyZW5hX21lc3NhZ2UtPnJlbGVhc2Vfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKTsKKyAgRVhQRUNUX0VRKE5VTEwsIHJlbGVhc2VkX251bGwpOworfQorCitURVNUKEFyZW5hVGVzdCwgU2V0QWxsb2NhdGVkU3RyaW5nKSB7CisgIEFyZW5hIGFyZW5hOworICBUZXN0QWxsVHlwZXMqIGFyZW5hX21lc3NhZ2UgPSBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxUZXN0QWxsVHlwZXM+KCZhcmVuYSk7CisgIHN0cmluZyogYWxsb2NhdGVkX3N0ciA9IG5ldyBzdHJpbmcoImhlbGxvIik7CisgIGFyZW5hX21lc3NhZ2UtPnNldF9hbGxvY2F0ZWRfb3B0aW9uYWxfc3RyaW5nKGFsbG9jYXRlZF9zdHIpOworICBFWFBFQ1RfRVEoImhlbGxvIiwgYXJlbmFfbWVzc2FnZS0+b3B0aW9uYWxfc3RyaW5nKCkpOworfQorCitURVNUKEFyZW5hVGVzdCwgUmVsZWFzZVN0cmluZykgeworICBBcmVuYSBhcmVuYTsKKyAgVGVzdEFsbFR5cGVzKiBhcmVuYV9tZXNzYWdlID0gQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEFsbFR5cGVzPigmYXJlbmEpOworICBhcmVuYV9tZXNzYWdlLT5zZXRfb3B0aW9uYWxfc3RyaW5nKCJoZWxsbyIpOworICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPHN0cmluZz4gcmVsZWFzZWRfc3RyKAorICAgICAgYXJlbmFfbWVzc2FnZS0+cmVsZWFzZV9vcHRpb25hbF9zdHJpbmcoKSk7CisgIEVYUEVDVF9FUSgiaGVsbG8iLCAqcmVsZWFzZWRfc3RyKTsKKworICAvLyBUZXN0IGRlZmF1bHQgdmFsdWUuCit9CisKKworVEVTVChBcmVuYVRlc3QsIFN3YXBCZXR3ZWVuQXJlbmFzV2l0aEFsbEZpZWxkc1NldCkgeworICBBcmVuYSBhcmVuYTE7CisgIFRlc3RBbGxUeXBlcyogYXJlbmExX21lc3NhZ2UgPSBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxUZXN0QWxsVHlwZXM+KCZhcmVuYTEpOworICB7CisgICAgQXJlbmEgYXJlbmEyOworICAgIFRlc3RBbGxUeXBlcyogYXJlbmEyX21lc3NhZ2UgPSBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxUZXN0QWxsVHlwZXM+KCZhcmVuYTIpOworICAgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoYXJlbmEyX21lc3NhZ2UpOworICAgIGFyZW5hMl9tZXNzYWdlLT5Td2FwKGFyZW5hMV9tZXNzYWdlKTsKKyAgICBzdHJpbmcgb3V0cHV0OworICAgIGFyZW5hMl9tZXNzYWdlLT5TZXJpYWxpemVUb1N0cmluZygmb3V0cHV0KTsKKyAgICBFWFBFQ1RfRVEoMCwgb3V0cHV0LnNpemUoKSk7CisgIH0KKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEZpZWxkc1NldCgqYXJlbmExX21lc3NhZ2UpOworfQorCitURVNUKEFyZW5hVGVzdCwgU3dhcEJldHdlZW5BcmVuYUFuZE5vbkFyZW5hV2l0aEFsbEZpZWxkc1NldCkgeworICBUZXN0QWxsVHlwZXMgbm9uX2FyZW5hX21lc3NhZ2U7CisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm5vbl9hcmVuYV9tZXNzYWdlKTsKKyAgeworICAgIEFyZW5hIGFyZW5hMjsKKyAgICBUZXN0QWxsVHlwZXMqIGFyZW5hMl9tZXNzYWdlID0gQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEFsbFR5cGVzPigmYXJlbmEyKTsKKyAgICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKGFyZW5hMl9tZXNzYWdlKTsKKyAgICBhcmVuYTJfbWVzc2FnZS0+U3dhcCgmbm9uX2FyZW5hX21lc3NhZ2UpOworICAgIFRlc3RVdGlsOjpFeHBlY3RBbGxGaWVsZHNTZXQoKmFyZW5hMl9tZXNzYWdlKTsKKyAgICBUZXN0VXRpbDo6RXhwZWN0QWxsRmllbGRzU2V0KG5vbl9hcmVuYV9tZXNzYWdlKTsKKyAgfQorfQorCitURVNUKEFyZW5hVGVzdCwgVW5zYWZlQXJlbmFTd2FwKSB7CisgIEFyZW5hIHNoYXJlZF9hcmVuYTsKKyAgVGVzdEFsbFR5cGVzKiBtZXNzYWdlMSA9IEFyZW5hOjpDcmVhdGVNZXNzYWdlPFRlc3RBbGxUeXBlcz4oJnNoYXJlZF9hcmVuYSk7CisgIFRlc3RBbGxUeXBlcyogbWVzc2FnZTIgPSBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxUZXN0QWxsVHlwZXM+KCZzaGFyZWRfYXJlbmEpOworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKG1lc3NhZ2UxKTsKKyAgbWVzc2FnZTEtPlVuc2FmZUFyZW5hU3dhcChtZXNzYWdlMik7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxGaWVsZHNTZXQoKm1lc3NhZ2UyKTsKK30KKworVEVTVChBcmVuYVRlc3QsIFN3YXBCZXR3ZWVuQXJlbmFzVXNpbmdSZWZsZWN0aW9uKSB7CisgIEFyZW5hIGFyZW5hMTsKKyAgVGVzdEFsbFR5cGVzKiBhcmVuYTFfbWVzc2FnZSA9IEFyZW5hOjpDcmVhdGVNZXNzYWdlPFRlc3RBbGxUeXBlcz4oJmFyZW5hMSk7CisgIHsKKyAgICBBcmVuYSBhcmVuYTI7CisgICAgVGVzdEFsbFR5cGVzKiBhcmVuYTJfbWVzc2FnZSA9IEFyZW5hOjpDcmVhdGVNZXNzYWdlPFRlc3RBbGxUeXBlcz4oJmFyZW5hMik7CisgICAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcyhhcmVuYTJfbWVzc2FnZSk7CisgICAgY29uc3QgUmVmbGVjdGlvbiogciA9IGFyZW5hMl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCk7CisgICAgci0+U3dhcChhcmVuYTFfbWVzc2FnZSwgYXJlbmEyX21lc3NhZ2UpOworICAgIHN0cmluZyBvdXRwdXQ7CisgICAgYXJlbmEyX21lc3NhZ2UtPlNlcmlhbGl6ZVRvU3RyaW5nKCZvdXRwdXQpOworICAgIEVYUEVDVF9FUSgwLCBvdXRwdXQuc2l6ZSgpKTsKKyAgfQorICBUZXN0VXRpbDo6RXhwZWN0QWxsRmllbGRzU2V0KCphcmVuYTFfbWVzc2FnZSk7Cit9CisKK1RFU1QoQXJlbmFUZXN0LCBTd2FwQmV0d2VlbkFyZW5hQW5kTm9uQXJlbmFVc2luZ1JlZmxlY3Rpb24pIHsKKyAgVGVzdEFsbFR5cGVzIG5vbl9hcmVuYV9tZXNzYWdlOworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZub25fYXJlbmFfbWVzc2FnZSk7CisgIHsKKyAgICBBcmVuYSBhcmVuYTI7CisgICAgVGVzdEFsbFR5cGVzKiBhcmVuYTJfbWVzc2FnZSA9IEFyZW5hOjpDcmVhdGVNZXNzYWdlPFRlc3RBbGxUeXBlcz4oJmFyZW5hMik7CisgICAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcyhhcmVuYTJfbWVzc2FnZSk7CisgICAgY29uc3QgUmVmbGVjdGlvbiogciA9IGFyZW5hMl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCk7CisgICAgci0+U3dhcCgmbm9uX2FyZW5hX21lc3NhZ2UsIGFyZW5hMl9tZXNzYWdlKTsKKyAgICBUZXN0VXRpbDo6RXhwZWN0QWxsRmllbGRzU2V0KCphcmVuYTJfbWVzc2FnZSk7CisgICAgVGVzdFV0aWw6OkV4cGVjdEFsbEZpZWxkc1NldChub25fYXJlbmFfbWVzc2FnZSk7CisgIH0KK30KKworVEVTVChBcmVuYVRlc3QsIFJlbGVhc2VGcm9tQXJlbmFNZXNzYWdlTWFrZXNDb3B5KSB7CisgIFRlc3RBbGxUeXBlczo6TmVzdGVkTWVzc2FnZSogbmVzdGVkX21zZyA9IE5VTEw7CisgIHN0cmluZyogbmVzdGVkX3N0cmluZyA9IE5VTEw7CisgIHsKKyAgICBBcmVuYSBhcmVuYTsKKyAgICBUZXN0QWxsVHlwZXMqIGFyZW5hX21lc3NhZ2UgPSBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxUZXN0QWxsVHlwZXM+KCZhcmVuYSk7CisgICAgYXJlbmFfbWVzc2FnZS0+bXV0YWJsZV9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpLT5zZXRfYmIoNDIpOworICAgICphcmVuYV9tZXNzYWdlLT5tdXRhYmxlX29wdGlvbmFsX3N0cmluZygpID0gIkhlbGxvIjsKKyAgICBuZXN0ZWRfbXNnID0gYXJlbmFfbWVzc2FnZS0+cmVsZWFzZV9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpOworICAgIG5lc3RlZF9zdHJpbmcgPSBhcmVuYV9tZXNzYWdlLT5yZWxlYXNlX29wdGlvbmFsX3N0cmluZygpOworICB9CisgIEVYUEVDVF9FUSg0MiwgbmVzdGVkX21zZy0+YmIoKSk7CisgIEVYUEVDVF9FUSgiSGVsbG8iLCAqbmVzdGVkX3N0cmluZyk7CisgIGRlbGV0ZSBuZXN0ZWRfbXNnOworICBkZWxldGUgbmVzdGVkX3N0cmluZzsKK30KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfTk9fUlRUSQorVEVTVChBcmVuYVRlc3QsIFJlbGVhc2VGcm9tQXJlbmFNZXNzYWdlVXNpbmdSZWZsZWN0aW9uTWFrZXNDb3B5KSB7CisgIFRlc3RBbGxUeXBlczo6TmVzdGVkTWVzc2FnZSogbmVzdGVkX21zZyA9IE5VTEw7CisgIC8vIE5vdGU6IG5vIHN0cmluZzogcmVmbGVjdGlvbiBBUEkgb25seSBzdXBwb3J0cyByZWxlYXNpbmcgc3VibWVzc2FnZXMuCisgIHsKKyAgICBBcmVuYSBhcmVuYTsKKyAgICBUZXN0QWxsVHlwZXMqIGFyZW5hX21lc3NhZ2UgPSBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxUZXN0QWxsVHlwZXM+KCZhcmVuYSk7CisgICAgYXJlbmFfbWVzc2FnZS0+bXV0YWJsZV9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpLT5zZXRfYmIoNDIpOworICAgIGNvbnN0IFJlZmxlY3Rpb24qIHIgPSBhcmVuYV9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCk7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmID0gYXJlbmFfbWVzc2FnZS0+R2V0RGVzY3JpcHRvcigpLT5GaW5kRmllbGRCeU5hbWUoCisgICAgICAgICJvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSIpOworICAgIG5lc3RlZF9tc2cgPSBzdGF0aWNfY2FzdDxUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2UqPigKKyAgICAgICAgci0+UmVsZWFzZU1lc3NhZ2UoYXJlbmFfbWVzc2FnZSwgZikpOworICB9CisgIEVYUEVDVF9FUSg0MiwgbmVzdGVkX21zZy0+YmIoKSk7CisgIGRlbGV0ZSBuZXN0ZWRfbXNnOworfQorI2VuZGlmICAvLyAhR09PR0xFX1BST1RPQlVGX05PX1JUVEkKKworVEVTVChBcmVuYVRlc3QsIFVuc2FmZUFyZW5hUmVsZWFzZURvZXNOb3RNYWtlQ29weSkgeworICBBcmVuYSBhcmVuYTsKKyAgVGVzdEFsbFR5cGVzKiBhcmVuYV9tZXNzYWdlID0gQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEFsbFR5cGVzPigmYXJlbmEpOworICBUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2UqIG5lc3RlZF9tc2cgPSBOVUxMOworICBUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2UqIG9yaWdfbmVzdGVkX21zZyA9IE5VTEw7CisgIHN0cmluZyogbmVzdGVkX3N0cmluZyA9IE5VTEw7CisgIHN0cmluZyogb3JpZ19uZXN0ZWRfc3RyaW5nID0gTlVMTDsKKyAgYXJlbmFfbWVzc2FnZS0+bXV0YWJsZV9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpLT5zZXRfYmIoNDIpOworICAqYXJlbmFfbWVzc2FnZS0+bXV0YWJsZV9vcHRpb25hbF9zdHJpbmcoKSA9ICJIZWxsbyI7CisgIG9yaWdfbmVzdGVkX21zZyA9IGFyZW5hX21lc3NhZ2UtPm11dGFibGVfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKTsKKyAgb3JpZ19uZXN0ZWRfc3RyaW5nID0gYXJlbmFfbWVzc2FnZS0+bXV0YWJsZV9vcHRpb25hbF9zdHJpbmcoKTsKKyAgbmVzdGVkX21zZyA9IGFyZW5hX21lc3NhZ2UtPnVuc2FmZV9hcmVuYV9yZWxlYXNlX29wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCk7CisgIG5lc3RlZF9zdHJpbmcgPSBhcmVuYV9tZXNzYWdlLT51bnNhZmVfYXJlbmFfcmVsZWFzZV9vcHRpb25hbF9zdHJpbmcoKTsKKworICBFWFBFQ1RfRVEob3JpZ19uZXN0ZWRfbXNnLCBuZXN0ZWRfbXNnKTsKKyAgRVhQRUNUX0VRKG9yaWdfbmVzdGVkX3N0cmluZywgbmVzdGVkX3N0cmluZyk7CisgIC8vIFJlbGVhc2VkIHBvaW50ZXJzIHN0aWxsIG9uIGFyZW5hOyBubyAnZGVsZXRlJyBjYWxscyBuZWVkZWQgaGVyZS4KK30KKworVEVTVChBcmVuYVRlc3QsIFNldEFsbG9jYXRlZEFjcm9zc0FyZW5hcykgeworICBBcmVuYSBhcmVuYTE7CisgIFRlc3RBbGxUeXBlcyogYXJlbmExX21lc3NhZ2UgPSBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxUZXN0QWxsVHlwZXM+KCZhcmVuYTEpOworICBUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2UqIGhlYXBfc3VibWVzc2FnZSA9CisgICAgICBuZXcgVGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlKCk7CisgIGhlYXBfc3VibWVzc2FnZS0+c2V0X2JiKDQyKTsKKyAgYXJlbmExX21lc3NhZ2UtPnNldF9hbGxvY2F0ZWRfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoaGVhcF9zdWJtZXNzYWdlKTsKKyAgLy8gU2hvdWxkIGtlZXAgc2FtZSBvYmplY3QgYW5kIGFkZCB0byBhcmVuYSdzIE93bigpLWxpc3QuCisgIEVYUEVDVF9FUShoZWFwX3N1Ym1lc3NhZ2UsCisgICAgICAgICAgICBhcmVuYTFfbWVzc2FnZS0+bXV0YWJsZV9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpKTsKKyAgeworICAgIEFyZW5hIGFyZW5hMjsKKyAgICBUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2UqIGFyZW5hMl9zdWJtZXNzYWdlID0KKyAgICAgICAgQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlPigmYXJlbmEyKTsKKyAgICBhcmVuYTJfc3VibWVzc2FnZS0+c2V0X2JiKDQyKTsKKyAgICBhcmVuYTFfbWVzc2FnZS0+c2V0X2FsbG9jYXRlZF9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZShhcmVuYTJfc3VibWVzc2FnZSk7CisgICAgRVhQRUNUX05FKGFyZW5hMl9zdWJtZXNzYWdlLAorICAgICAgICAgICAgICBhcmVuYTFfbWVzc2FnZS0+bXV0YWJsZV9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpKTsKKyAgfQorCisgIFRlc3RBbGxUeXBlczo6TmVzdGVkTWVzc2FnZSogYXJlbmExX3N1Ym1lc3NhZ2UgPQorICAgICAgQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlPigmYXJlbmExKTsKKyAgYXJlbmExX3N1Ym1lc3NhZ2UtPnNldF9iYig0Mik7CisgIFRlc3RBbGxUeXBlcyogaGVhcF9tZXNzYWdlID0gbmV3IFRlc3RBbGxUeXBlczsKKyAgaGVhcF9tZXNzYWdlLT5zZXRfYWxsb2NhdGVkX29wdGlvbmFsX25lc3RlZF9tZXNzYWdlKGFyZW5hMV9zdWJtZXNzYWdlKTsKKyAgRVhQRUNUX05FKGFyZW5hMV9zdWJtZXNzYWdlLAorICAgICAgICAgICAgaGVhcF9tZXNzYWdlLT5tdXRhYmxlX29wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCkpOworICBkZWxldGUgaGVhcF9tZXNzYWdlOworfQorCitURVNUKEFyZW5hVGVzdCwgU2V0QWxsb2NhdGVkQWNyb3NzQXJlbmFzV2l0aFJlZmxlY3Rpb24pIHsKKyAgLy8gU2FtZSBhcyBhYm92ZSwgd2l0aCByZWZsZWN0aW9uLgorICBBcmVuYSBhcmVuYTE7CisgIFRlc3RBbGxUeXBlcyogYXJlbmExX21lc3NhZ2UgPSBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxUZXN0QWxsVHlwZXM+KCZhcmVuYTEpOworICBjb25zdCBSZWZsZWN0aW9uKiByID0gYXJlbmExX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKTsKKyAgY29uc3QgRGVzY3JpcHRvciogZCA9IGFyZW5hMV9tZXNzYWdlLT5HZXREZXNjcmlwdG9yKCk7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogbXNnX2ZpZWxkID0gZC0+RmluZEZpZWxkQnlOYW1lKAorICAgICAgIm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlIik7CisgIFRlc3RBbGxUeXBlczo6TmVzdGVkTWVzc2FnZSogaGVhcF9zdWJtZXNzYWdlID0KKyAgICAgIG5ldyBUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2UoKTsKKyAgaGVhcF9zdWJtZXNzYWdlLT5zZXRfYmIoNDIpOworICByLT5TZXRBbGxvY2F0ZWRNZXNzYWdlKGFyZW5hMV9tZXNzYWdlLCBoZWFwX3N1Ym1lc3NhZ2UsIG1zZ19maWVsZCk7CisgIC8vIFNob3VsZCBrZWVwIHNhbWUgb2JqZWN0IGFuZCBhZGQgdG8gYXJlbmEncyBPd24oKS1saXN0LgorICBFWFBFQ1RfRVEoaGVhcF9zdWJtZXNzYWdlLAorICAgICAgICAgICAgYXJlbmExX21lc3NhZ2UtPm11dGFibGVfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKSk7CisgIHsKKyAgICBBcmVuYSBhcmVuYTI7CisgICAgVGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlKiBhcmVuYTJfc3VibWVzc2FnZSA9CisgICAgICAgIEFyZW5hOjpDcmVhdGVNZXNzYWdlPFRlc3RBbGxUeXBlczo6TmVzdGVkTWVzc2FnZT4oJmFyZW5hMik7CisgICAgYXJlbmEyX3N1Ym1lc3NhZ2UtPnNldF9iYig0Mik7CisgICAgci0+U2V0QWxsb2NhdGVkTWVzc2FnZShhcmVuYTFfbWVzc2FnZSwgYXJlbmEyX3N1Ym1lc3NhZ2UsIG1zZ19maWVsZCk7CisgICAgRVhQRUNUX05FKGFyZW5hMl9zdWJtZXNzYWdlLAorICAgICAgICAgICAgICBhcmVuYTFfbWVzc2FnZS0+bXV0YWJsZV9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpKTsKKyAgfQorCisgIFRlc3RBbGxUeXBlczo6TmVzdGVkTWVzc2FnZSogYXJlbmExX3N1Ym1lc3NhZ2UgPQorICAgICAgQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlPigmYXJlbmExKTsKKyAgYXJlbmExX3N1Ym1lc3NhZ2UtPnNldF9iYig0Mik7CisgIFRlc3RBbGxUeXBlcyogaGVhcF9tZXNzYWdlID0gbmV3IFRlc3RBbGxUeXBlczsKKyAgci0+U2V0QWxsb2NhdGVkTWVzc2FnZShoZWFwX21lc3NhZ2UsIGFyZW5hMV9zdWJtZXNzYWdlLCBtc2dfZmllbGQpOworICBFWFBFQ1RfTkUoYXJlbmExX3N1Ym1lc3NhZ2UsCisgICAgICAgICAgICBoZWFwX21lc3NhZ2UtPm11dGFibGVfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKSk7CisgIGRlbGV0ZSBoZWFwX21lc3NhZ2U7Cit9CisKK1RFU1QoQXJlbmFUZXN0LCBBZGRBbGxvY2F0ZWRXaXRoUmVmbGVjdGlvbikgeworICBBcmVuYSBhcmVuYTE7CisgIEFyZW5hTWVzc2FnZSogYXJlbmExX21lc3NhZ2UgPSBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxBcmVuYU1lc3NhZ2U+KCZhcmVuYTEpOworICBjb25zdCBSZWZsZWN0aW9uKiByID0gYXJlbmExX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKTsKKyAgY29uc3QgRGVzY3JpcHRvciogZCA9IGFyZW5hMV9tZXNzYWdlLT5HZXREZXNjcmlwdG9yKCk7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmQgPQorICAgICAgZC0+RmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF9pbXBvcnRfbm9fYXJlbmFfbWVzc2FnZSIpOworICAvLyBNZXNzYWdlIHdpdGggY2NfZW5hYmxlX2FyZW5hcyA9IGZhbHNlOworICByLT5BZGRNZXNzYWdlKGFyZW5hMV9tZXNzYWdlLCBmZCk7CisgIHItPkFkZE1lc3NhZ2UoYXJlbmExX21lc3NhZ2UsIGZkKTsKKyAgci0+QWRkTWVzc2FnZShhcmVuYTFfbWVzc2FnZSwgZmQpOworICBFWFBFQ1RfRVEoMywgci0+RmllbGRTaXplKCphcmVuYTFfbWVzc2FnZSwgZmQpKTsKKyAgLy8gTWVzc2FnZSB3aXRoIGNjX2VuYWJsZV9hcmVuYXMgPSB0cnVlOworICBmZCA9IGQtPkZpbmRGaWVsZEJ5TmFtZSgicmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UiKTsKKyAgci0+QWRkTWVzc2FnZShhcmVuYTFfbWVzc2FnZSwgZmQpOworICByLT5BZGRNZXNzYWdlKGFyZW5hMV9tZXNzYWdlLCBmZCk7CisgIHItPkFkZE1lc3NhZ2UoYXJlbmExX21lc3NhZ2UsIGZkKTsKKyAgRVhQRUNUX0VRKDMsIHItPkZpZWxkU2l6ZSgqYXJlbmExX21lc3NhZ2UsIGZkKSk7Cit9CisKK1RFU1QoQXJlbmFUZXN0LCBSZXBlYXRlZFB0ckZpZWxkQWRkQ2xlYXJlZFRlc3QpIHsKKyAgeworICAgIFJlcGVhdGVkUHRyRmllbGQ8VGVzdEFsbFR5cGVzPiByZXBlYXRlZF9maWVsZDsKKyAgICBFWFBFQ1RfVFJVRShyZXBlYXRlZF9maWVsZC5lbXB0eSgpKTsKKyAgICBFWFBFQ1RfRVEoMCwgcmVwZWF0ZWRfZmllbGQuc2l6ZSgpKTsKKyAgICAvLyBPd25lcnNoaXAgaXMgcGFzc2VkIHRvIHJlcGVhdGVkX2ZpZWxkLgorICAgIFRlc3RBbGxUeXBlcyogY2xlYXJlZCA9IG5ldyBUZXN0QWxsVHlwZXMoKTsKKyAgICByZXBlYXRlZF9maWVsZC5BZGRDbGVhcmVkKGNsZWFyZWQpOworICAgIEVYUEVDVF9UUlVFKHJlcGVhdGVkX2ZpZWxkLmVtcHR5KCkpOworICAgIEVYUEVDVF9FUSgwLCByZXBlYXRlZF9maWVsZC5zaXplKCkpOworICB9CisgIHsKKyAgICBSZXBlYXRlZFB0ckZpZWxkPFRlc3RBbGxUeXBlcz4gcmVwZWF0ZWRfZmllbGQ7CisgICAgRVhQRUNUX1RSVUUocmVwZWF0ZWRfZmllbGQuZW1wdHkoKSk7CisgICAgRVhQRUNUX0VRKDAsIHJlcGVhdGVkX2ZpZWxkLnNpemUoKSk7CisgICAgLy8gT3duZXJzaGlwIGlzIHBhc3NlZCB0byByZXBlYXRlZF9maWVsZC4KKyAgICBUZXN0QWxsVHlwZXMqIGNsZWFyZWQgPSBuZXcgVGVzdEFsbFR5cGVzKCk7CisgICAgcmVwZWF0ZWRfZmllbGQuQWRkQWxsb2NhdGVkKGNsZWFyZWQpOworICAgIEVYUEVDVF9GQUxTRShyZXBlYXRlZF9maWVsZC5lbXB0eSgpKTsKKyAgICBFWFBFQ1RfRVEoMSwgcmVwZWF0ZWRfZmllbGQuc2l6ZSgpKTsKKyAgfQorfQorCitURVNUKEFyZW5hVGVzdCwgQWRkQWxsb2NhdGVkVG9SZXBlYXRlZEZpZWxkKSB7CisgIC8vIEhlYXAtPmFyZW5hIGNhc2UuCisgIEFyZW5hIGFyZW5hMTsKKyAgVGVzdEFsbFR5cGVzKiBhcmVuYTFfbWVzc2FnZSA9IEFyZW5hOjpDcmVhdGVNZXNzYWdlPFRlc3RBbGxUeXBlcz4oJmFyZW5hMSk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7IGkrKykgeworICAgIFRlc3RBbGxUeXBlczo6TmVzdGVkTWVzc2FnZSogaGVhcF9zdWJtZXNzYWdlID0KKyAgICAgICAgbmV3IFRlc3RBbGxUeXBlczo6TmVzdGVkTWVzc2FnZSgpOworICAgIGhlYXBfc3VibWVzc2FnZS0+c2V0X2JiKDQyKTsKKyAgICBhcmVuYTFfbWVzc2FnZS0+bXV0YWJsZV9yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSgpLT4KKyAgICAgICAgQWRkQWxsb2NhdGVkKGhlYXBfc3VibWVzc2FnZSk7CisgICAgLy8gU2hvdWxkIG5vdCBjb3B5IG9iamVjdCAtLSB3aWxsIHVzZSBhcmVuYV8tPk93bigpLgorICAgIEVYUEVDVF9FUShoZWFwX3N1Ym1lc3NhZ2UsCisgICAgICAgICAgICAgICZhcmVuYTFfbWVzc2FnZS0+cmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UoaSkpOworICAgIEVYUEVDVF9FUSg0MiwgYXJlbmExX21lc3NhZ2UtPnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlKGkpLmJiKCkpOworICB9CisKKyAgLy8gQXJlbmExLT5BcmVuYTIgY2FzZS4KKyAgYXJlbmExX21lc3NhZ2UtPkNsZWFyKCk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7IGkrKykgeworICAgIEFyZW5hIGFyZW5hMjsKKyAgICBUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2UqIGFyZW5hMl9zdWJtZXNzYWdlID0KKyAgICAgICAgQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlPigmYXJlbmEyKTsKKyAgICBhcmVuYTJfc3VibWVzc2FnZS0+c2V0X2JiKDQyKTsKKyAgICBhcmVuYTFfbWVzc2FnZS0+bXV0YWJsZV9yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSgpLT4KKyAgICAgICAgQWRkQWxsb2NhdGVkKGFyZW5hMl9zdWJtZXNzYWdlKTsKKyAgICAvLyBTaG91bGQgY29weSBvYmplY3QuCisgICAgRVhQRUNUX05FKGFyZW5hMl9zdWJtZXNzYWdlLAorICAgICAgICAgICAgICAmYXJlbmExX21lc3NhZ2UtPnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlKGkpKTsKKyAgICBFWFBFQ1RfRVEoNDIsIGFyZW5hMV9tZXNzYWdlLT5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZShpKS5iYigpKTsKKyAgfQorCisgIC8vIEFyZW5hLT5oZWFwIGNhc2UuCisgIFRlc3RBbGxUeXBlcyogaGVhcF9tZXNzYWdlID0gbmV3IFRlc3RBbGxUeXBlcygpOworICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyBpKyspIHsKKyAgICBBcmVuYSBhcmVuYTI7CisgICAgVGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlKiBhcmVuYTJfc3VibWVzc2FnZSA9CisgICAgICAgIEFyZW5hOjpDcmVhdGVNZXNzYWdlPFRlc3RBbGxUeXBlczo6TmVzdGVkTWVzc2FnZT4oJmFyZW5hMik7CisgICAgYXJlbmEyX3N1Ym1lc3NhZ2UtPnNldF9iYig0Mik7CisgICAgaGVhcF9tZXNzYWdlLT5tdXRhYmxlX3JlcGVhdGVkX25lc3RlZF9tZXNzYWdlKCktPgorICAgICAgICBBZGRBbGxvY2F0ZWQoYXJlbmEyX3N1Ym1lc3NhZ2UpOworICAgIC8vIFNob3VsZCBjb3B5IG9iamVjdC4KKyAgICBFWFBFQ1RfTkUoYXJlbmEyX3N1Ym1lc3NhZ2UsCisgICAgICAgICAgICAgICZoZWFwX21lc3NhZ2UtPnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlKGkpKTsKKyAgICBFWFBFQ1RfRVEoNDIsIGhlYXBfbWVzc2FnZS0+cmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UoaSkuYmIoKSk7CisgIH0KKyAgZGVsZXRlIGhlYXBfbWVzc2FnZTsKKworICAvLyBIZWFwLWFyZW5hIGNhc2UgZm9yIHN0cmluZ3MgKHdoaWNoIGFyZSBub3QgYXJlbmEtYWxsb2NhdGVkKS4KKyAgYXJlbmExX21lc3NhZ2UtPkNsZWFyKCk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7IGkrKykgeworICAgIHN0cmluZyogcyA9IG5ldyBzdHJpbmcoIlRlc3QiKTsKKyAgICBhcmVuYTFfbWVzc2FnZS0+bXV0YWJsZV9yZXBlYXRlZF9zdHJpbmcoKS0+CisgICAgICAgIEFkZEFsbG9jYXRlZChzKTsKKyAgICAvLyBTaG91bGQgbm90IGNvcHkuCisgICAgRVhQRUNUX0VRKHMsICZhcmVuYTFfbWVzc2FnZS0+cmVwZWF0ZWRfc3RyaW5nKGkpKTsKKyAgICBFWFBFQ1RfRVEoIlRlc3QiLCBhcmVuYTFfbWVzc2FnZS0+cmVwZWF0ZWRfc3RyaW5nKGkpKTsKKyAgfQorfQorCitURVNUKEFyZW5hVGVzdCwgQWRkQWxsb2NhdGVkVG9SZXBlYXRlZEZpZWxkVmlhUmVmbGVjdGlvbikgeworICAvLyBIZWFwLT5hcmVuYSBjYXNlLgorICBBcmVuYSBhcmVuYTE7CisgIFRlc3RBbGxUeXBlcyogYXJlbmExX21lc3NhZ2UgPSBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxUZXN0QWxsVHlwZXM+KCZhcmVuYTEpOworICBjb25zdCBSZWZsZWN0aW9uKiByID0gYXJlbmExX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKTsKKyAgY29uc3QgRGVzY3JpcHRvciogZCA9IGFyZW5hMV9tZXNzYWdlLT5HZXREZXNjcmlwdG9yKCk7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmQgPQorICAgICAgZC0+RmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSIpOworICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyBpKyspIHsKKyAgICBUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2UqIGhlYXBfc3VibWVzc2FnZSA9CisgICAgICAgIG5ldyBUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2U7CisgICAgaGVhcF9zdWJtZXNzYWdlLT5zZXRfYmIoNDIpOworICAgIHItPkFkZEFsbG9jYXRlZE1lc3NhZ2UoYXJlbmExX21lc3NhZ2UsIGZkLCBoZWFwX3N1Ym1lc3NhZ2UpOworICAgIC8vIFNob3VsZCBub3QgY29weSBvYmplY3QgLS0gd2lsbCB1c2UgYXJlbmFfLT5Pd24oKS4KKyAgICBFWFBFQ1RfRVEoaGVhcF9zdWJtZXNzYWdlLAorICAgICAgICAgICAgICAmYXJlbmExX21lc3NhZ2UtPnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlKGkpKTsKKyAgICBFWFBFQ1RfRVEoNDIsIGFyZW5hMV9tZXNzYWdlLT5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZShpKS5iYigpKTsKKyAgfQorCisgIC8vIEFyZW5hMS0+QXJlbmEyIGNhc2UuCisgIGFyZW5hMV9tZXNzYWdlLT5DbGVhcigpOworICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyBpKyspIHsKKyAgICBBcmVuYSBhcmVuYTI7CisgICAgVGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlKiBhcmVuYTJfc3VibWVzc2FnZSA9CisgICAgICAgIEFyZW5hOjpDcmVhdGVNZXNzYWdlPFRlc3RBbGxUeXBlczo6TmVzdGVkTWVzc2FnZT4oJmFyZW5hMik7CisgICAgYXJlbmEyX3N1Ym1lc3NhZ2UtPnNldF9iYig0Mik7CisgICAgci0+QWRkQWxsb2NhdGVkTWVzc2FnZShhcmVuYTFfbWVzc2FnZSwgZmQsIGFyZW5hMl9zdWJtZXNzYWdlKTsKKyAgICAvLyBTaG91bGQgY29weSBvYmplY3QuCisgICAgRVhQRUNUX05FKGFyZW5hMl9zdWJtZXNzYWdlLAorICAgICAgICAgICAgICAmYXJlbmExX21lc3NhZ2UtPnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlKGkpKTsKKyAgICBFWFBFQ1RfRVEoNDIsIGFyZW5hMV9tZXNzYWdlLT5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZShpKS5iYigpKTsKKyAgfQorCisgIC8vIEFyZW5hLT5oZWFwIGNhc2UuCisgIFRlc3RBbGxUeXBlcyogaGVhcF9tZXNzYWdlID0gbmV3IFRlc3RBbGxUeXBlczsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgaSsrKSB7CisgICAgQXJlbmEgYXJlbmEyOworICAgIFRlc3RBbGxUeXBlczo6TmVzdGVkTWVzc2FnZSogYXJlbmEyX3N1Ym1lc3NhZ2UgPQorICAgICAgICBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2U+KCZhcmVuYTIpOworICAgIGFyZW5hMl9zdWJtZXNzYWdlLT5zZXRfYmIoNDIpOworICAgIHItPkFkZEFsbG9jYXRlZE1lc3NhZ2UoaGVhcF9tZXNzYWdlLCBmZCwgYXJlbmEyX3N1Ym1lc3NhZ2UpOworICAgIC8vIFNob3VsZCBjb3B5IG9iamVjdC4KKyAgICBFWFBFQ1RfTkUoYXJlbmEyX3N1Ym1lc3NhZ2UsCisgICAgICAgICAgICAgICZoZWFwX21lc3NhZ2UtPnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlKGkpKTsKKyAgICBFWFBFQ1RfRVEoNDIsIGhlYXBfbWVzc2FnZS0+cmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UoaSkuYmIoKSk7CisgIH0KKyAgZGVsZXRlIGhlYXBfbWVzc2FnZTsKK30KKworVEVTVChBcmVuYVRlc3QsIFJlbGVhc2VMYXN0UmVwZWF0ZWRGaWVsZCkgeworICAvLyBSZWxlYXNlIGZyb20gYXJlbmEtYWxsb2NhdGVkIHJlcGVhdGVkIGZpZWxkIGFuZCBlbnN1cmUgdGhhdCByZXR1cm5lZCBvYmplY3QKKyAgLy8gaXMgaGVhcC1hbGxvY2F0ZWQuCisgIEFyZW5hIGFyZW5hOworICBUZXN0QWxsVHlwZXMqIGFyZW5hX21lc3NhZ2UgPSBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxUZXN0QWxsVHlwZXM+KCZhcmVuYSk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7IGkrKykgeworICAgIFRlc3RBbGxUeXBlczo6TmVzdGVkTWVzc2FnZSogbmVzdGVkID0KKyAgICAgICAgQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlPigmYXJlbmEpOworICAgIG5lc3RlZC0+c2V0X2JiKDQyKTsKKyAgICBhcmVuYV9tZXNzYWdlLT5tdXRhYmxlX3JlcGVhdGVkX25lc3RlZF9tZXNzYWdlKCktPkFkZEFsbG9jYXRlZChuZXN0ZWQpOworICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgaSsrKSB7CisgICAgY29uc3QgVGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlICpvcmlnX3N1Ym1lc3NhZ2UgPQorICAgICAgICAmYXJlbmFfbWVzc2FnZS0+cmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UoMTAgLSAxIC0gaSk7ICAvLyBsYXN0IGVsZW1lbnQKKyAgICBUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2UgKnJlbGVhc2VkID0KKyAgICAgICAgYXJlbmFfbWVzc2FnZS0+bXV0YWJsZV9yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSgpLT5SZWxlYXNlTGFzdCgpOworICAgIEVYUEVDVF9ORShyZWxlYXNlZCwgb3JpZ19zdWJtZXNzYWdlKTsKKyAgICBFWFBFQ1RfRVEoNDIsIHJlbGVhc2VkLT5iYigpKTsKKyAgICBkZWxldGUgcmVsZWFzZWQ7CisgIH0KKworICAvLyBUZXN0IFVuc2FmZUFyZW5hUmVsZWFzZUxhc3QoKS4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgaSsrKSB7CisgICAgVGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlKiBuZXN0ZWQgPQorICAgICAgICBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2U+KCZhcmVuYSk7CisgICAgbmVzdGVkLT5zZXRfYmIoNDIpOworICAgIGFyZW5hX21lc3NhZ2UtPm11dGFibGVfcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UoKS0+QWRkQWxsb2NhdGVkKG5lc3RlZCk7CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyBpKyspIHsKKyAgICBjb25zdCBUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2UgKm9yaWdfc3VibWVzc2FnZSA9CisgICAgICAgICZhcmVuYV9tZXNzYWdlLT5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSgxMCAtIDEgLSBpKTsgIC8vIGxhc3QgZWxlbWVudAorICAgIFRlc3RBbGxUeXBlczo6TmVzdGVkTWVzc2FnZSAqcmVsZWFzZWQgPQorICAgICAgICBhcmVuYV9tZXNzYWdlLT5tdXRhYmxlX3JlcGVhdGVkX25lc3RlZF9tZXNzYWdlKCktPgorICAgICAgICBVbnNhZmVBcmVuYVJlbGVhc2VMYXN0KCk7CisgICAgRVhQRUNUX0VRKHJlbGVhc2VkLCBvcmlnX3N1Ym1lc3NhZ2UpOworICAgIEVYUEVDVF9FUSg0MiwgcmVsZWFzZWQtPmJiKCkpOworICAgIC8vIG5vIGRlbGV0ZSAtLSB8cmVsZWFzZWR8IGlzIG9uIHRoZSBhcmVuYS4KKyAgfQorCisgIC8vIFRlc3Qgc3RyaW5nIGNhc2UgYXMgd2VsbC4gUmVsZWFzZUxhc3QoKSBpbiB0aGlzIGNhc2UgbXVzdCBjb3B5IHRoZSBzdHJpbmcsCisgIC8vIGV2ZW4gdGhvdWdoIGl0IHdhcyBvcmlnaW5hbGx5IGhlYXAtYWxsb2NhdGVkIGFuZCBpdHMgcG9pbnRlciB3YXMgc2ltcGx5CisgIC8vIGFwcGVuZGVkIHRvIHRoZSByZXBlYXRlZCBmaWVsZCdzIGludGVybmFsIHZlY3RvciwgYmVjYXVzZSB0aGUgc3RyaW5nIHdhcworICAvLyBwbGFjZWQgb24gdGhlIGFyZW5hJ3MgZGVzdHJ1Y3RvciBsaXN0IGFuZCBjYW5ub3QgYmUgcmVtb3ZlZCBmcm9tIHRoYXQgbGlzdAorICAvLyAoc28gdGhlIGFyZW5hIHBlcm1hbmVudGx5IG93bnMgdGhlIG9yaWdpbmFsIGluc3RhbmNlKS4KKyAgYXJlbmFfbWVzc2FnZS0+Q2xlYXIoKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgaSsrKSB7CisgICAgc3RyaW5nKiBzID0gbmV3IHN0cmluZygiVGVzdCIpOworICAgIGFyZW5hX21lc3NhZ2UtPm11dGFibGVfcmVwZWF0ZWRfc3RyaW5nKCktPkFkZEFsbG9jYXRlZChzKTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyBpKyspIHsKKyAgICBjb25zdCBzdHJpbmcqIG9yaWdfZWxlbWVudCA9ICZhcmVuYV9tZXNzYWdlLT5yZXBlYXRlZF9zdHJpbmcoMTAgLSAxIC0gaSk7CisgICAgc3RyaW5nKiByZWxlYXNlZCA9IGFyZW5hX21lc3NhZ2UtPm11dGFibGVfcmVwZWF0ZWRfc3RyaW5nKCktPlJlbGVhc2VMYXN0KCk7CisgICAgRVhQRUNUX05FKHJlbGVhc2VkLCBvcmlnX2VsZW1lbnQpOworICAgIEVYUEVDVF9FUSgiVGVzdCIsICpyZWxlYXNlZCk7CisgICAgZGVsZXRlIHJlbGVhc2VkOworICB9Cit9CisKK1RFU1QoQXJlbmFUZXN0LCBVbnNhZmVBcmVuYVJlbGVhc2VBZGQpIHsKKyAgLy8gVXNlIHVuc2FmZV9hcmVuYV9yZWxlYXNlKCkgYW5kIHVuc2FmZV9hcmVuYV9zZXRfYWxsb2NhdGVkKCkgdG8gdHJhbnNmZXIgYW4KKyAgLy8gYXJlbmEtYWxsb2NhdGVkIHN0cmluZyBmcm9tIG9uZSBtZXNzYWdlIHRvIGFub3RoZXIuCisgIEFyZW5hIGFyZW5hOworICBUZXN0QWxsVHlwZXMqIG1lc3NhZ2UxID0gQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEFsbFR5cGVzPigmYXJlbmEpOworICBUZXN0QWxsVHlwZXMqIG1lc3NhZ2UyID0gQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEFsbFR5cGVzPigmYXJlbmEpOworICBzdHJpbmcqIGFyZW5hX3N0cmluZyA9IEFyZW5hOjpDcmVhdGU8c3RyaW5nPigmYXJlbmEpOworICAqYXJlbmFfc3RyaW5nID0gIlRlc3QgY29udGVudCI7CisKKyAgbWVzc2FnZTEtPnVuc2FmZV9hcmVuYV9zZXRfYWxsb2NhdGVkX29wdGlvbmFsX3N0cmluZyhhcmVuYV9zdHJpbmcpOworICBFWFBFQ1RfRVEoYXJlbmFfc3RyaW5nLCBtZXNzYWdlMS0+bXV0YWJsZV9vcHRpb25hbF9zdHJpbmcoKSk7CisgIG1lc3NhZ2UyLT51bnNhZmVfYXJlbmFfc2V0X2FsbG9jYXRlZF9vcHRpb25hbF9zdHJpbmcoCisgICAgICBtZXNzYWdlMS0+dW5zYWZlX2FyZW5hX3JlbGVhc2Vfb3B0aW9uYWxfc3RyaW5nKCkpOworICBFWFBFQ1RfRVEoYXJlbmFfc3RyaW5nLCBtZXNzYWdlMi0+bXV0YWJsZV9vcHRpb25hbF9zdHJpbmcoKSk7Cit9CisKK1RFU1QoQXJlbmFUZXN0LCBVbnNhZmVBcmVuYUFkZEFsbG9jYXRlZCkgeworICBBcmVuYSBhcmVuYTsKKyAgVGVzdEFsbFR5cGVzKiBtZXNzYWdlID0gQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEFsbFR5cGVzPigmYXJlbmEpOworICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyBpKyspIHsKKyAgICBzdHJpbmcqIGFyZW5hX3N0cmluZyA9IEFyZW5hOjpDcmVhdGU8c3RyaW5nPigmYXJlbmEpOworICAgIG1lc3NhZ2UtPm11dGFibGVfcmVwZWF0ZWRfc3RyaW5nKCktPlVuc2FmZUFyZW5hQWRkQWxsb2NhdGVkKGFyZW5hX3N0cmluZyk7CisgICAgRVhQRUNUX0VRKGFyZW5hX3N0cmluZywgbWVzc2FnZS0+bXV0YWJsZV9yZXBlYXRlZF9zdHJpbmcoaSkpOworICB9Cit9CisKK1RFU1QoQXJlbmFUZXN0LCBVbnNhZmVBcmVuYVJlbGVhc2UpIHsKKyAgQXJlbmEgYXJlbmE7CisgIFRlc3RBbGxUeXBlcyogbWVzc2FnZSA9IEFyZW5hOjpDcmVhdGVNZXNzYWdlPFRlc3RBbGxUeXBlcz4oJmFyZW5hKTsKKworICBzdHJpbmcqIHMgPSBuZXcgc3RyaW5nKCJ0ZXN0IHN0cmluZyIpOworICBtZXNzYWdlLT51bnNhZmVfYXJlbmFfc2V0X2FsbG9jYXRlZF9vcHRpb25hbF9zdHJpbmcocyk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UtPmhhc19vcHRpb25hbF9zdHJpbmcoKSk7CisgIEVYUEVDVF9FUSgidGVzdCBzdHJpbmciLCBtZXNzYWdlLT5vcHRpb25hbF9zdHJpbmcoKSk7CisgIHMgPSBtZXNzYWdlLT51bnNhZmVfYXJlbmFfcmVsZWFzZV9vcHRpb25hbF9zdHJpbmcoKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UtPmhhc19vcHRpb25hbF9zdHJpbmcoKSk7CisgIGRlbGV0ZSBzOworCisgIHMgPSBuZXcgc3RyaW5nKCJ0ZXN0IHN0cmluZyIpOworICBtZXNzYWdlLT51bnNhZmVfYXJlbmFfc2V0X2FsbG9jYXRlZF9vbmVvZl9zdHJpbmcocyk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UtPmhhc19vbmVvZl9zdHJpbmcoKSk7CisgIEVYUEVDVF9FUSgidGVzdCBzdHJpbmciLCBtZXNzYWdlLT5vbmVvZl9zdHJpbmcoKSk7CisgIHMgPSBtZXNzYWdlLT51bnNhZmVfYXJlbmFfcmVsZWFzZV9vbmVvZl9zdHJpbmcoKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UtPmhhc19vbmVvZl9zdHJpbmcoKSk7CisgIGRlbGV0ZSBzOworfQorCitURVNUKEFyZW5hVGVzdCwgQXJlbmFPbmVvZlJlZmxlY3Rpb24pIHsKKyAgQXJlbmEgYXJlbmE7CisgIFRlc3RBbGxUeXBlcyogbWVzc2FnZSA9IEFyZW5hOjpDcmVhdGVNZXNzYWdlPFRlc3RBbGxUeXBlcz4oJmFyZW5hKTsKKyAgY29uc3QgRGVzY3JpcHRvciogZGVzYyA9IG1lc3NhZ2UtPkdldERlc2NyaXB0b3IoKTsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbCA9IG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKTsKKworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHN0cmluZ19maWVsZCA9IGRlc2MtPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICJvbmVvZl9zdHJpbmciKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBtc2dfZmllbGQgPSBkZXNjLT5GaW5kRmllbGRCeU5hbWUoCisgICAgICAib25lb2ZfbmVzdGVkX21lc3NhZ2UiKTsKKyAgY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBvbmVvZiA9IGRlc2MtPkZpbmRPbmVvZkJ5TmFtZSgKKyAgICAgICJvbmVvZl9maWVsZCIpOworCisgIHJlZmwtPlNldFN0cmluZyhtZXNzYWdlLCBzdHJpbmdfZmllbGQsICJUZXN0IHZhbHVlIik7CisgIEVYUEVDVF9UUlVFKHJlZmwtPkhhc09uZW9mKCptZXNzYWdlLCBvbmVvZikpOworICByZWZsLT5DbGVhck9uZW9mKG1lc3NhZ2UsIG9uZW9mKTsKKyAgRVhQRUNUX0ZBTFNFKHJlZmwtPkhhc09uZW9mKCptZXNzYWdlLCBvbmVvZikpOworCisgIE1lc3NhZ2UqIHN1Ym1zZyA9IHJlZmwtPk11dGFibGVNZXNzYWdlKG1lc3NhZ2UsIG1zZ19maWVsZCk7CisgIEVYUEVDVF9UUlVFKHJlZmwtPkhhc09uZW9mKCptZXNzYWdlLCBvbmVvZikpOworICByZWZsLT5DbGVhck9uZW9mKG1lc3NhZ2UsIG9uZW9mKTsKKyAgRVhQRUNUX0ZBTFNFKHJlZmwtPkhhc09uZW9mKCptZXNzYWdlLCBvbmVvZikpOworICByZWZsLT5NdXRhYmxlTWVzc2FnZShtZXNzYWdlLCBtc2dfZmllbGQpOworICBFWFBFQ1RfVFJVRShyZWZsLT5IYXNPbmVvZigqbWVzc2FnZSwgb25lb2YpKTsKKyAgc3VibXNnID0gcmVmbC0+UmVsZWFzZU1lc3NhZ2UobWVzc2FnZSwgbXNnX2ZpZWxkKTsKKyAgRVhQRUNUX0ZBTFNFKHJlZmwtPkhhc09uZW9mKCptZXNzYWdlLCBvbmVvZikpOworICBFWFBFQ1RfVFJVRShzdWJtc2ctPkdldEFyZW5hKCkgPT0gTlVMTCk7CisgIGRlbGV0ZSBzdWJtc2c7Cit9CisKK25hbWVzcGFjZSB7Cit2b2lkIFRlc3RTd2FwUmVwZWF0ZWRGaWVsZChBcmVuYSogYXJlbmExLCBBcmVuYSogYXJlbmEyKSB7CisgIC8vIFRlc3QgInNhZmUiIChjb3B5aW5nKSBzZW1hbnRpY3MgZm9yIGRpcmVjdCBTd2FwKCkgb24gUmVwZWF0ZWRQdHJGaWVsZAorICAvLyBiZXR3ZWVuIGFyZW5hcy4KKyAgUmVwZWF0ZWRQdHJGaWVsZDxUZXN0QWxsVHlwZXM+IGZpZWxkMShhcmVuYTEpOworICBSZXBlYXRlZFB0ckZpZWxkPFRlc3RBbGxUeXBlcz4gZmllbGQyKGFyZW5hMik7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7IGkrKykgeworICAgIFRlc3RBbGxUeXBlcyogdCA9IEFyZW5hOjpDcmVhdGVNZXNzYWdlPFRlc3RBbGxUeXBlcz4oYXJlbmExKTsKKyAgICB0LT5zZXRfb3B0aW9uYWxfc3RyaW5nKCJmaWVsZDEiKTsKKyAgICB0LT5zZXRfb3B0aW9uYWxfaW50MzIoaSk7CisgICAgaWYgKGFyZW5hMSAhPSBOVUxMKSB7CisgICAgICBmaWVsZDEuVW5zYWZlQXJlbmFBZGRBbGxvY2F0ZWQodCk7CisgICAgfSBlbHNlIHsKKyAgICAgIGZpZWxkMS5BZGRBbGxvY2F0ZWQodCk7CisgICAgfQorICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgNTsgaSsrKSB7CisgICAgVGVzdEFsbFR5cGVzKiB0ID0gQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEFsbFR5cGVzPihhcmVuYTIpOworICAgIHQtPnNldF9vcHRpb25hbF9zdHJpbmcoImZpZWxkMiIpOworICAgIHQtPnNldF9vcHRpb25hbF9pbnQzMihpKTsKKyAgICBpZiAoYXJlbmEyICE9IE5VTEwpIHsKKyAgICAgIGZpZWxkMi5VbnNhZmVBcmVuYUFkZEFsbG9jYXRlZCh0KTsKKyAgICB9IGVsc2UgeworICAgICAgZmllbGQyLkFkZEFsbG9jYXRlZCh0KTsKKyAgICB9CisgIH0KKyAgZmllbGQxLlN3YXAoJmZpZWxkMik7CisgIEVYUEVDVF9FUSg1LCBmaWVsZDEuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEwLCBmaWVsZDIuc2l6ZSgpKTsKKyAgRVhQRUNUX1RSVUUoc3RyaW5nKCJmaWVsZDEiKSA9PSBmaWVsZDIuR2V0KDApLm9wdGlvbmFsX3N0cmluZygpKTsKKyAgRVhQRUNUX1RSVUUoc3RyaW5nKCJmaWVsZDIiKSA9PSBmaWVsZDEuR2V0KDApLm9wdGlvbmFsX3N0cmluZygpKTsKKyAgLy8gRW5zdXJlIHRoYXQgZmllbGRzIHJldGFpbmVkIHRoZWlyIG9yaWdpbmFsIG9yZGVyOgorICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkMS5zaXplKCk7IGkrKykgeworICAgIEVYUEVDVF9FUShpLCBmaWVsZDEuR2V0KGkpLm9wdGlvbmFsX2ludDMyKCkpOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGQyLnNpemUoKTsgaSsrKSB7CisgICAgRVhQRUNUX0VRKGksIGZpZWxkMi5HZXQoaSkub3B0aW9uYWxfaW50MzIoKSk7CisgIH0KK30KK30gIC8vIG5hbWVzcGFjZQorCitURVNUKEFyZW5hVGVzdCwgU3dhcFJlcGVhdGVkRmllbGQpIHsKKyAgQXJlbmEgYXJlbmE7CisgIFRlc3RTd2FwUmVwZWF0ZWRGaWVsZCgmYXJlbmEsICZhcmVuYSk7Cit9CisKK1RFU1QoQXJlbmFUZXN0LCBTd2FwUmVwZWF0ZWRGaWVsZFdpdGhEaWZmZXJlbnRBcmVuYXMpIHsKKyAgQXJlbmEgYXJlbmExOworICBBcmVuYSBhcmVuYTI7CisgIFRlc3RTd2FwUmVwZWF0ZWRGaWVsZCgmYXJlbmExLCAmYXJlbmEyKTsKK30KKworVEVTVChBcmVuYVRlc3QsIFN3YXBSZXBlYXRlZEZpZWxkV2l0aE5vQXJlbmFPblJpZ2h0SGFuZFNpZGUpIHsKKyAgQXJlbmEgYXJlbmE7CisgIFRlc3RTd2FwUmVwZWF0ZWRGaWVsZCgmYXJlbmEsIE5VTEwpOworfQorCitURVNUKEFyZW5hVGVzdCwgU3dhcFJlcGVhdGVkRmllbGRXaXRoTm9BcmVuYU9uTGVmdEhhbmRTaWRlKSB7CisgIEFyZW5hIGFyZW5hOworICBUZXN0U3dhcFJlcGVhdGVkRmllbGQoTlVMTCwgJmFyZW5hKTsKK30KKworVEVTVChBcmVuYVRlc3QsIEV4dGVuc2lvbnNPbkFyZW5hKSB7CisgIEFyZW5hIGFyZW5hOworICAvLyBFbnN1cmUgbm8gbGVha3MuCisgIFRlc3RBbGxFeHRlbnNpb25zKiBtZXNzYWdlX2V4dCA9CisgICAgICBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxUZXN0QWxsRXh0ZW5zaW9ucz4oJmFyZW5hKTsKKyAgbWVzc2FnZV9leHQtPlNldEV4dGVuc2lvbigKKyAgICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpvcHRpb25hbF9pbnQzMl9leHRlbnNpb24sIDQyKTsKKyAgbWVzc2FnZV9leHQtPlNldEV4dGVuc2lvbigKKyAgICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpvcHRpb25hbF9zdHJpbmdfZXh0ZW5zaW9uLCBzdHJpbmcoInRlc3QiKSk7CisgIG1lc3NhZ2VfZXh0LT5NdXRhYmxlRXh0ZW5zaW9uKAorICAgICAgcHJvdG9idWZfdW5pdHRlc3Q6Om9wdGlvbmFsX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiktPnNldF9iYig0Mik7Cit9CisKK1RFU1QoQXJlbmFUZXN0LCBSZXBlYXRlZEZpZWxkT25BcmVuYSkgeworICAvLyBQcmVhbGxvY2F0ZSBhbiBpbml0aWFsIGFyZW5hIGJsb2NrIHRvIGF2b2lkIG1hbGxvY3MgZHVyaW5nIGhvb2tlZCByZWdpb24uCisgIHN0ZDo6dmVjdG9yPGNoYXI+IGFyZW5hX2Jsb2NrKDEwMjQgKiAxMDI0KTsKKyAgQXJlbmFPcHRpb25zIG9wdGlvbnM7CisgIG9wdGlvbnMuaW5pdGlhbF9ibG9jayA9ICZhcmVuYV9ibG9ja1swXTsKKyAgb3B0aW9ucy5pbml0aWFsX2Jsb2NrX3NpemUgPSBhcmVuYV9ibG9jay5zaXplKCk7CisgIEFyZW5hIGFyZW5hKG9wdGlvbnMpOworCisgIHsKKyAgICBpbnRlcm5hbDo6Tm9IZWFwQ2hlY2tlciBub19oZWFwOworCisgICAgLy8gRmlsbCBzb21lIHJlcGVhdGVkIGZpZWxkcyBvbiB0aGUgYXJlbmEgdG8gdGVzdCBmb3IgbGVha3MuIEFsc28gdmVyaWZ5IG5vCisgICAgLy8gbWVtb3J5IGFsbG9jYXRpb25zLgorICAgIFJlcGVhdGVkRmllbGQ8aW50MzI+IHJlcGVhdGVkX2ludDMyKCZhcmVuYSk7CisgICAgUmVwZWF0ZWRQdHJGaWVsZDxUZXN0QWxsVHlwZXM+IHJlcGVhdGVkX21lc3NhZ2UoJmFyZW5hKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwMDsgaSsrKSB7CisgICAgICByZXBlYXRlZF9pbnQzMi5BZGQoNDIpOworICAgICAgcmVwZWF0ZWRfbWVzc2FnZS5BZGQoKS0+c2V0X29wdGlvbmFsX2ludDMyKDQyKTsKKyAgICAgIEVYUEVDVF9FUSgmYXJlbmEsIHJlcGVhdGVkX21lc3NhZ2UuR2V0KDApLkdldEFyZW5hKCkpOworICAgICAgY29uc3QgVGVzdEFsbFR5cGVzKiBtc2dfaW5fcmVwZWF0ZWRfZmllbGQgPSAmcmVwZWF0ZWRfbWVzc2FnZS5HZXQoMCk7CisgICAgICBUZXN0QWxsVHlwZXMqIG1zZyA9IHJlcGVhdGVkX21lc3NhZ2UuVW5zYWZlQXJlbmFSZWxlYXNlTGFzdCgpOworICAgICAgRVhQRUNUX0VRKG1zZ19pbl9yZXBlYXRlZF9maWVsZCwgbXNnKTsKKyAgICB9CisKKyAgICAvLyBVbnNhZmVBcmVuYUV4dHJhY3RTdWJyYW5nZSAoaSkgc2hvdWxkIG5vdCBsZWFrIGFuZCAoaWkpIHNob3VsZCByZXR1cm4KKyAgICAvLyBvbi1hcmVuYSBwb2ludGVycy4KKyAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyBpKyspIHsKKyAgICAgIHJlcGVhdGVkX21lc3NhZ2UuQWRkKCktPnNldF9vcHRpb25hbF9pbnQzMig0Mik7CisgICAgfQorICAgIFRlc3RBbGxUeXBlcyogZXh0cmFjdGVkX21lc3NhZ2VzWzVdOworICAgIHJlcGVhdGVkX21lc3NhZ2UuVW5zYWZlQXJlbmFFeHRyYWN0U3VicmFuZ2UoMCwgNSwgZXh0cmFjdGVkX21lc3NhZ2VzKTsKKyAgICBFWFBFQ1RfRVEoJmFyZW5hLCByZXBlYXRlZF9tZXNzYWdlLkdldCgwKS5HZXRBcmVuYSgpKTsKKyAgICBFWFBFQ1RfRVEoNSwgcmVwZWF0ZWRfbWVzc2FnZS5zaXplKCkpOworICB9CisKKyAgLy8gTm93LCBvdXRzaWRlIHRoZSBzY29wZSBvZiB0aGUgTm9IZWFwQ2hlY2tlciwgdGVzdCBFeHRyYWN0U3VicmFuZ2UncyBjb3B5aW5nCisgIC8vIHNlbWFudGljcy4KKyAgeworICAgIFJlcGVhdGVkUHRyRmllbGQ8VGVzdEFsbFR5cGVzPiByZXBlYXRlZF9tZXNzYWdlKCZhcmVuYSk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDA7IGkrKykgeworICAgICAgcmVwZWF0ZWRfbWVzc2FnZS5BZGQoKS0+c2V0X29wdGlvbmFsX2ludDMyKDQyKTsKKyAgICB9CisKKyAgICBUZXN0QWxsVHlwZXMqIGV4dHJhY3RlZF9tZXNzYWdlc1s1XTsKKyAgICAvLyBFeHRyYWN0U3VicmFuZ2Ugc2hvdWxkIGNvcHkgdG8gdGhlIGhlYXAuCisgICAgcmVwZWF0ZWRfbWVzc2FnZS5FeHRyYWN0U3VicmFuZ2UoMCwgNSwgZXh0cmFjdGVkX21lc3NhZ2VzKTsKKyAgICBFWFBFQ1RfRVEoTlVMTCwgZXh0cmFjdGVkX21lc3NhZ2VzWzBdLT5HZXRBcmVuYSgpKTsKKyAgICAvLyBXZSBuZWVkIHRvIGZyZWUgdGhlIGhlYXAtYWxsb2NhdGVkIG1lc3NhZ2VzIHRvIHByZXZlbnQgYSBsZWFrLgorICAgIGZvciAoaW50IGkgPSAwOyBpIDwgNTsgaSsrKSB7CisgICAgICBkZWxldGUgZXh0cmFjdGVkX21lc3NhZ2VzW2ldOworICAgICAgZXh0cmFjdGVkX21lc3NhZ2VzW2ldID0gTlVMTDsKKyAgICB9CisgIH0KKworICAvLyBOb3cgY2hlY2sgdGhhdCB3ZSBjYW4gY3JlYXRlIFJlcGVhdGVkRmllbGRzL1JlcGVhdGVkUHRyRmllbGRzIHRoZW1zZWx2ZXMgb24KKyAgLy8gdGhlIGFyZW5hLiBUaGV5IGhhdmUgdGhlIG5lY2Vzc2FyeSB0eXBlIHRyYWl0cyBzbyB0aGF0IHRoZXkgY2FuIGJlaGF2ZSBsaWtlCisgIC8vIG1lc3NhZ2VzIGluIHRoaXMgd2F5LiBUaGlzIGlzIHVzZWZ1bCBmb3IgaGlnaGVyLWxldmVsIGdlbmVyaWMgdGVtcGxhdGVkCisgIC8vIGNvZGUgdGhhdCBtYXkgYWxsb2NhdGUgbWVzc2FnZXMgb3IgcmVwZWF0ZWQgZmllbGRzIG9mIG1lc3NhZ2VzIG9uIGFuIGFyZW5hLgorICB7CisgICAgUmVwZWF0ZWRQdHJGaWVsZDxUZXN0QWxsVHlwZXM+KiByZXBlYXRlZF9wdHJfb25fYXJlbmEgPQorICAgICAgICBBcmVuYTo6Q3JlYXRlTWVzc2FnZTwgUmVwZWF0ZWRQdHJGaWVsZDxUZXN0QWxsVHlwZXM+ID4oJmFyZW5hKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyBpKyspIHsKKyAgICAgIC8vIEFkZCBzb21lIGVsZW1lbnRzIGFuZCBsZXQgdGhlIGxlYWstY2hlY2tlciBlbnN1cmUgdGhhdCBldmVyeXRoaW5nIGlzCisgICAgICAvLyBmcmVlZC4KKyAgICAgIHJlcGVhdGVkX3B0cl9vbl9hcmVuYS0+QWRkKCk7CisgICAgfQorCisgICAgUmVwZWF0ZWRGaWVsZDxpbnQ+KiByZXBlYXRlZF9pbnRfb25fYXJlbmEgPQorICAgICAgICBBcmVuYTo6Q3JlYXRlTWVzc2FnZTwgUmVwZWF0ZWRGaWVsZDxpbnQ+ID4oJmFyZW5hKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwMDsgaSsrKSB7CisgICAgICByZXBlYXRlZF9pbnRfb25fYXJlbmEtPkFkZChpKTsKKyAgICB9CisKKyAgfQorCisgIGFyZW5hLlJlc2V0KCk7Cit9CisKKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfTk9fUlRUSQorVEVTVChBcmVuYVRlc3QsIE11dGFibGVNZXNzYWdlUmVmbGVjdGlvbikgeworICBBcmVuYSBhcmVuYTsKKyAgVGVzdEFsbFR5cGVzKiBtZXNzYWdlID0gQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEFsbFR5cGVzPigmYXJlbmEpOworICBjb25zdCBSZWZsZWN0aW9uKiByID0gbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpOworICBjb25zdCBEZXNjcmlwdG9yKiBkID0gbWVzc2FnZS0+R2V0RGVzY3JpcHRvcigpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZC0+RmluZEZpZWxkQnlOYW1lKCJvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSIpOworICBUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2UqIHN1Ym1lc3NhZ2UgPQorICAgICAgc3RhdGljX2Nhc3Q8VGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlKj4oCisgICAgICAgICAgci0+TXV0YWJsZU1lc3NhZ2UobWVzc2FnZSwgZmllbGQpKTsKKyAgVGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlKiBzdWJtZXNzYWdlX2V4cGVjdGVkID0KKyAgICAgIG1lc3NhZ2UtPm11dGFibGVfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKTsKKworICBFWFBFQ1RfRVEoc3VibWVzc2FnZV9leHBlY3RlZCwgc3VibWVzc2FnZSk7CisgIEVYUEVDVF9FUSgmYXJlbmEsIHN1Ym1lc3NhZ2UtPkdldEFyZW5hKCkpOworCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogb25lb2ZfZmllbGQgPSBkLT5GaW5kRmllbGRCeU5hbWUoIm9uZW9mX25lc3RlZF9tZXNzYWdlIik7CisgIHN1Ym1lc3NhZ2UgPSBzdGF0aWNfY2FzdDxUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2UqPigKKyAgICAgIHItPk11dGFibGVNZXNzYWdlKG1lc3NhZ2UsIG9uZW9mX2ZpZWxkKSk7CisgIHN1Ym1lc3NhZ2VfZXhwZWN0ZWQgPSBtZXNzYWdlLT5tdXRhYmxlX29uZW9mX25lc3RlZF9tZXNzYWdlKCk7CisKKyAgRVhQRUNUX0VRKHN1Ym1lc3NhZ2VfZXhwZWN0ZWQsIHN1Ym1lc3NhZ2UpOworICBFWFBFQ1RfRVEoJmFyZW5hLCBzdWJtZXNzYWdlLT5HZXRBcmVuYSgpKTsKK30KKyNlbmRpZiAgLy8gIUdPT0dMRV9QUk9UT0JVRl9OT19SVFRJCisKKworbmFtZXNwYWNlIHsKKwordm9pZCBGaWxsQXJlbmFBd2FyZUZpZWxkcyhUZXN0QWxsVHlwZXMqIG1lc3NhZ2UpIHsKKyAgc3RyaW5nIHRlc3Rfc3RyaW5nID0gImhlbGxvIHdvcmxkIjsKKyAgbWVzc2FnZS0+c2V0X29wdGlvbmFsX2ludDMyKDQyKTsKKyAgbWVzc2FnZS0+c2V0X29wdGlvbmFsX3N0cmluZyh0ZXN0X3N0cmluZyk7CisgIG1lc3NhZ2UtPnNldF9vcHRpb25hbF9ieXRlcyh0ZXN0X3N0cmluZyk7CisgIG1lc3NhZ2UtPm11dGFibGVfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKS0+c2V0X2JiKDQyKTsKKworICBtZXNzYWdlLT5zZXRfb25lb2ZfdWludDMyKDQyKTsKKyAgbWVzc2FnZS0+bXV0YWJsZV9vbmVvZl9uZXN0ZWRfbWVzc2FnZSgpLT5zZXRfYmIoNDIpOworICBtZXNzYWdlLT5zZXRfb25lb2Zfc3RyaW5nKHRlc3Rfc3RyaW5nKTsKKyAgbWVzc2FnZS0+c2V0X29uZW9mX2J5dGVzKHRlc3Rfc3RyaW5nKTsKKworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfaW50MzIoNDIpOworICAvLyBObyByZXBlYXRlZCBzdHJpbmc6IG5vdCB5ZXQgYXJlbmEtYXdhcmUuCisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSgpLT5zZXRfYmIoNDIpOworICBtZXNzYWdlLT5tdXRhYmxlX29wdGlvbmFsX2xhenlfbWVzc2FnZSgpLT5zZXRfYmIoNDIpOworfQorCit9CisKKy8vIFRlc3Q6IG5vIGFsbG9jYXRpb25zIG9jY3VyIG9uIGhlYXAgd2hpbGUgdG91Y2hpbmcgYWxsIHN1cHBvcnRlZCBmaWVsZCB0eXBlcy4KK1RFU1QoQXJlbmFUZXN0LCBOb0hlYXBBbGxvY2F0aW9uc1Rlc3QpIHsKKyAgLy8gQWxsb2NhdGUgYSBsYXJnZSBpbml0aWFsIGJsb2NrIHRvIGF2b2lkIG1hbGxvY3MgZHVyaW5nIGhvb2tlZCB0ZXN0LgorICBzdGQ6OnZlY3RvcjxjaGFyPiBhcmVuYV9ibG9jaygxMjggKiAxMDI0KTsKKyAgQXJlbmFPcHRpb25zIG9wdGlvbnM7CisgIG9wdGlvbnMuaW5pdGlhbF9ibG9jayA9ICZhcmVuYV9ibG9ja1swXTsKKyAgb3B0aW9ucy5pbml0aWFsX2Jsb2NrX3NpemUgPSBhcmVuYV9ibG9jay5zaXplKCk7CisgIEFyZW5hIGFyZW5hKG9wdGlvbnMpOworCisgIHsKKworICAgIFRlc3RBbGxUeXBlcyogbWVzc2FnZSA9IEFyZW5hOjpDcmVhdGVNZXNzYWdlPFRlc3RBbGxUeXBlcz4oJmFyZW5hKTsKKyAgICBGaWxsQXJlbmFBd2FyZUZpZWxkcyhtZXNzYWdlKTsKKyAgfQorCisgIGFyZW5hLlJlc2V0KCk7Cit9CisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX05PX1JUVEkKKy8vIFRlc3QgY29uc3RydWN0aW9uIG9uIGFuIGFyZW5hIHZpYSBnZW5lcmljIE1lc3NhZ2VMaXRlIGludGVyZmFjZS4gV2Ugc2hvdWxkIGJlCisvLyBhYmxlIHRvIHN1Y2Nlc3NmdWxseSBkZXNlcmlhbGl6ZSBvbiB0aGUgYXJlbmEgd2l0aG91dCBpbmN1cnJpbmcgaGVhcAorLy8gYWxsb2NhdGlvbnMsIGkuZS4sIGV2ZXJ5dGhpbmcgc2hvdWxkIHN0aWxsIGJlIGFyZW5hLWFsbG9jYXRpb24tYXdhcmUuCitURVNUKEFyZW5hVGVzdCwgTWVzc2FnZUxpdGVPbkFyZW5hKSB7CisgIHN0ZDo6dmVjdG9yPGNoYXI+IGFyZW5hX2Jsb2NrKDEyOCAqIDEwMjQpOworICBBcmVuYU9wdGlvbnMgb3B0aW9uczsKKyAgb3B0aW9ucy5pbml0aWFsX2Jsb2NrID0gJmFyZW5hX2Jsb2NrWzBdOworICBvcHRpb25zLmluaXRpYWxfYmxvY2tfc2l6ZSA9IGFyZW5hX2Jsb2NrLnNpemUoKTsKKyAgQXJlbmEgYXJlbmEob3B0aW9ucyk7CisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VMaXRlKiBwcm90b3R5cGUgPSAmVGVzdEFsbFR5cGVzOjpkZWZhdWx0X2luc3RhbmNlKCk7CisKKyAgVGVzdEFsbFR5cGVzIGluaXRpYWxfbWVzc2FnZTsKKyAgRmlsbEFyZW5hQXdhcmVGaWVsZHMoJmluaXRpYWxfbWVzc2FnZSk7CisgIHN0cmluZyBzZXJpYWxpemVkOworICBpbml0aWFsX21lc3NhZ2UuU2VyaWFsaXplVG9TdHJpbmcoJnNlcmlhbGl6ZWQpOworCisgIHsKKworICAgIGdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VMaXRlKiBnZW5lcmljX21lc3NhZ2UgPSBwcm90b3R5cGUtPk5ldygmYXJlbmEpOworICAgIEVYUEVDVF9UUlVFKGdlbmVyaWNfbWVzc2FnZSAhPSBOVUxMKTsKKyAgICBFWFBFQ1RfRVEoJmFyZW5hLCBnZW5lcmljX21lc3NhZ2UtPkdldEFyZW5hKCkpOworICAgIEVYUEVDVF9UUlVFKGdlbmVyaWNfbWVzc2FnZS0+UGFyc2VGcm9tU3RyaW5nKHNlcmlhbGl6ZWQpKTsKKyAgICBUZXN0QWxsVHlwZXMqIGRlc2VyaWFsaXplZCA9IHN0YXRpY19jYXN0PFRlc3RBbGxUeXBlcyo+KGdlbmVyaWNfbWVzc2FnZSk7CisgICAgRVhQRUNUX0VRKDQyLCBkZXNlcmlhbGl6ZWQtPm9wdGlvbmFsX2ludDMyKCkpOworICB9CisKKyAgYXJlbmEuUmVzZXQoKTsKK30KKyNlbmRpZiAgLy8gIUdPT0dMRV9QUk9UT0JVRl9OT19SVFRJCisKKworLy8gUmVwZWF0ZWRGaWVsZCBzaG91bGQgc3VwcG9ydCBub24tUE9EIHR5cGVzLCBhbmQgaW52b2tlIGNvbnN0cnVjdG9ycyBhbmQKKy8vIGRlc3RydWN0b3JzIGFwcHJvcHJpYXRlbHksIGJlY2F1c2UgaXQncyB1c2VkIHRoaXMgd2F5IGJ5IGxvdHMgb2Ygb3RoZXIgY29kZQorLy8gKGV2ZW4gaWYgdGhpcyB3YXMgbm90IGl0cyBvcmlnaW5hbCBpbnRlbnQpLgorVEVTVChBcmVuYVRlc3QsIFJlcGVhdGVkRmllbGRXaXRoTm9uUE9EVHlwZSkgeworICB7CisgICAgUmVwZWF0ZWRGaWVsZDxzdHJpbmc+IGZpZWxkX29uX2hlYXA7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDA7IGkrKykgeworICAgICAgKmZpZWxkX29uX2hlYXAuQWRkKCkgPSAidGVzdCBzdHJpbmcgbG9uZyBlbm91Z2ggdG8gZXhjZWVkIGlubGluZSBidWZmZXIiOworICAgIH0KKyAgfQorICB7CisgICAgQXJlbmEgYXJlbmE7CisgICAgUmVwZWF0ZWRGaWVsZDxzdHJpbmc+IGZpZWxkX29uX2FyZW5hKCZhcmVuYSk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDA7IGkrKykgeworICAgICAgKmZpZWxkX29uX2FyZW5hLkFkZCgpID0gInRlc3Qgc3RyaW5nIGxvbmcgZW5vdWdoIHRvIGV4Y2VlZCBpbmxpbmUgYnVmZmVyIjsKKyAgICB9CisgIH0KK30KKworLy8gQWxpZ24gbiB0byBuZXh0IG11bHRpcGxlIG9mIDgKK25hbWVzcGFjZSB7Cit1aW50NjQgQWxpZ244KHVpbnQ2NCBuKSB7IHJldHVybiAobiArIDcpICYgLTg7IH0KK30gIC8vIG5hbWVzcGFjZQorCitURVNUKEFyZW5hVGVzdCwgU3BhY2VBbGxvY2F0ZWRfYW5kX1VzZWQpIHsKKyAgQXJlbmFPcHRpb25zIG9wdGlvbnM7CisgIG9wdGlvbnMuc3RhcnRfYmxvY2tfc2l6ZSA9IDI1NjsKKyAgb3B0aW9ucy5tYXhfYmxvY2tfc2l6ZSA9IDgxOTI7CisgIEFyZW5hIGFyZW5hXzEob3B0aW9ucyk7CisgIEVYUEVDVF9FUSgwLCBhcmVuYV8xLlNwYWNlQWxsb2NhdGVkKCkpOworICBFWFBFQ1RfRVEoMCwgYXJlbmFfMS5TcGFjZVVzZWQoKSk7CisgIEVYUEVDVF9FUSgwLCBhcmVuYV8xLlJlc2V0KCkpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hOjpDcmVhdGVBcnJheTxjaGFyPigmYXJlbmFfMSwgMzIwKTsKKyAgLy8gQXJlbmEgd2lsbCBhbGxvY2F0ZSBzbGlnaHRseSBtb3JlIHRoYW4gMzIwIGZvciB0aGUgYmxvY2sgaGVhZGVycy4KKyAgRVhQRUNUX0xFKDMyMCwgYXJlbmFfMS5TcGFjZUFsbG9jYXRlZCgpKTsKKyAgRVhQRUNUX0VRKEFsaWduOCgzMjApLCBhcmVuYV8xLlNwYWNlVXNlZCgpKTsKKyAgRVhQRUNUX0xFKDMyMCwgYXJlbmFfMS5SZXNldCgpKTsKKworICAvLyBUZXN0IHdpdGggaW5pdGlhbCBibG9jay4KKyAgc3RkOjp2ZWN0b3I8Y2hhcj4gYXJlbmFfYmxvY2soMTAyNCk7CisgIG9wdGlvbnMuaW5pdGlhbF9ibG9jayA9ICZhcmVuYV9ibG9ja1swXTsKKyAgb3B0aW9ucy5pbml0aWFsX2Jsb2NrX3NpemUgPSBhcmVuYV9ibG9jay5zaXplKCk7CisgIEFyZW5hIGFyZW5hXzIob3B0aW9ucyk7CisgIEVYUEVDVF9FUSgxMDI0LCBhcmVuYV8yLlNwYWNlQWxsb2NhdGVkKCkpOworICBFWFBFQ1RfRVEoMCwgYXJlbmFfMi5TcGFjZVVzZWQoKSk7CisgIEVYUEVDVF9FUSgxMDI0LCBhcmVuYV8yLlJlc2V0KCkpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hOjpDcmVhdGVBcnJheTxjaGFyPigmYXJlbmFfMiwgNTUpOworICBFWFBFQ1RfRVEoMTAyNCwgYXJlbmFfMi5TcGFjZUFsbG9jYXRlZCgpKTsKKyAgRVhQRUNUX0VRKEFsaWduOCg1NSksIGFyZW5hXzIuU3BhY2VVc2VkKCkpOworICBFWFBFQ1RfRVEoMTAyNCwgYXJlbmFfMi5SZXNldCgpKTsKKworICAvLyBSZXNldCBvcHRpb25zIHRvIHRlc3QgZG91YmxpbmcgcG9saWN5IGV4cGxpY2l0bHkuCisgIG9wdGlvbnMuaW5pdGlhbF9ibG9jayA9IE5VTEw7CisgIG9wdGlvbnMuaW5pdGlhbF9ibG9ja19zaXplID0gMDsKKyAgQXJlbmEgYXJlbmFfMyhvcHRpb25zKTsKKyAgRVhQRUNUX0VRKDAsIGFyZW5hXzMuU3BhY2VVc2VkKCkpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hOjpDcmVhdGVBcnJheTxjaGFyPigmYXJlbmFfMywgMTkwKTsKKyAgRVhQRUNUX0VRKDI1NiwgYXJlbmFfMy5TcGFjZUFsbG9jYXRlZCgpKTsKKyAgRVhQRUNUX0VRKEFsaWduOCgxOTApLCBhcmVuYV8zLlNwYWNlVXNlZCgpKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYTo6Q3JlYXRlQXJyYXk8Y2hhcj4oJmFyZW5hXzMsIDcwKTsKKyAgRVhQRUNUX0VRKDI1NiArIDUxMiwgYXJlbmFfMy5TcGFjZUFsbG9jYXRlZCgpKTsKKyAgRVhQRUNUX0VRKEFsaWduOCgxOTApICsgQWxpZ244KDcwKSwgYXJlbmFfMy5TcGFjZVVzZWQoKSk7CisgIEVYUEVDVF9FUSgyNTYgKyA1MTIsIGFyZW5hXzMuUmVzZXQoKSk7Cit9CisKK1RFU1QoQXJlbmFUZXN0LCBBbGlnbm1lbnQpIHsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSBhcmVuYTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAyMDA7IGkrKykgeworICAgIHZvaWQqIHAgPSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hOjpDcmVhdGVBcnJheTxjaGFyPigmYXJlbmEsIGkpOworICAgIEdPT0dMRV9DSEVDS19FUShyZWludGVycHJldF9jYXN0PHVpbnRwdHJfdD4ocCkgJSA4LCAwKSA8PCBpIDw8ICI6ICIgPDwgcDsKKyAgfQorfQorCitURVNUKEFyZW5hVGVzdCwgR2V0QXJlbmFTaG91bGRSZXR1cm5UaGVBcmVuYUZvckFyZW5hQWxsb2NhdGVkTWVzc2FnZXMpIHsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSBhcmVuYTsKKyAgQXJlbmFNZXNzYWdlKiBtZXNzYWdlID0gQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8QXJlbmFNZXNzYWdlPigmYXJlbmEpOworICBjb25zdCBBcmVuYU1lc3NhZ2UqIGNvbnN0X3BvaW50ZXJfdG9fbWVzc2FnZSA9IG1lc3NhZ2U7CisgIEVYUEVDVF9FUSgmYXJlbmEsIEFyZW5hOjpHZXRBcmVuYShtZXNzYWdlKSk7CisgIEVYUEVDVF9FUSgmYXJlbmEsIEFyZW5hOjpHZXRBcmVuYShjb25zdF9wb2ludGVyX3RvX21lc3NhZ2UpKTsKK30KKworVEVTVChBcmVuYVRlc3QsIEdldEFyZW5hU2hvdWxkUmV0dXJuTnVsbEZvck5vbkFyZW5hQWxsb2NhdGVkTWVzc2FnZXMpIHsKKyAgQXJlbmFNZXNzYWdlIG1lc3NhZ2U7CisgIGNvbnN0IEFyZW5hTWVzc2FnZSogY29uc3RfcG9pbnRlcl90b19tZXNzYWdlID0gJm1lc3NhZ2U7CisgIEVYUEVDVF9FUShOVUxMLCBBcmVuYTo6R2V0QXJlbmEoJm1lc3NhZ2UpKTsKKyAgRVhQRUNUX0VRKE5VTEwsIEFyZW5hOjpHZXRBcmVuYShjb25zdF9wb2ludGVyX3RvX21lc3NhZ2UpKTsKK30KKworVEVTVChBcmVuYVRlc3QsIFVuc2FmZVNldEFsbG9jYXRlZE9uQXJlbmEpIHsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSBhcmVuYTsKKyAgVGVzdEFsbFR5cGVzKiBtZXNzYWdlID0gQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEFsbFR5cGVzPigmYXJlbmEpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS0+aGFzX29wdGlvbmFsX3N0cmluZygpKTsKKworICBzdHJpbmcgb3duZWRfc3RyaW5nID0gInRlc3Qgd2l0aCBsb25nIGVub3VnaCBjb250ZW50IHRvIGhlYXAtYWxsb2NhdGUiOworICBtZXNzYWdlLT51bnNhZmVfYXJlbmFfc2V0X2FsbG9jYXRlZF9vcHRpb25hbF9zdHJpbmcoJm93bmVkX3N0cmluZyk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UtPmhhc19vcHRpb25hbF9zdHJpbmcoKSk7CisKKyAgbWVzc2FnZS0+dW5zYWZlX2FyZW5hX3NldF9hbGxvY2F0ZWRfb3B0aW9uYWxfc3RyaW5nKE5VTEwpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS0+aGFzX29wdGlvbmFsX3N0cmluZygpKTsKK30KKworLy8gQSBoZWxwZXIgdXRpbGl0eSBjbGFzcyB0byBvbmx5IGNvbnRhaW4gc3RhdGljIGhvb2sgZnVuY3Rpb25zLCBzb21lCisvLyBjb3VudGVycyB0byBiZSB1c2VkIHRvIHZlcmlmeSB0aGUgY291bnRlcnMgaGF2ZSBiZWVuIGNhbGxlZCBhbmQgYSBjb29raWUKKy8vIHZhbHVlIHRvIGJlIHZlcmlmaWVkLgorY2xhc3MgQXJlbmFIb29rc1Rlc3RVdGlsIHsKKyBwdWJsaWM6CisgIHN0YXRpYyB2b2lkKiBvbl9pbml0KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSB7CisgICAgKytudW1faW5pdDsKKyAgICBpbnQqIGNvb2tpZSA9IG5ldyBpbnQoa0Nvb2tpZVZhbHVlKTsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8dm9pZCo+KGNvb2tpZSk7CisgIH0KKworICBzdGF0aWMgdm9pZCBvbl9hbGxvY2F0aW9uKGNvbnN0IHN0ZDo6dHlwZV9pbmZvKiAvKnVudXNlZCovLCB1aW50NjQgYWxsb2Nfc2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkKiBjb29raWUpIHsKKyAgICArK251bV9hbGxvY2F0aW9uczsKKyAgICBpbnQgY29va2llX3ZhbHVlID0gKnN0YXRpY19jYXN0PGludCo+KGNvb2tpZSk7CisgICAgRVhQRUNUX0VRKGtDb29raWVWYWx1ZSwgY29va2llX3ZhbHVlKTsKKyAgfQorCisgIHN0YXRpYyB2b2lkIG9uX3Jlc2V0KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hLCB2b2lkKiBjb29raWUsCisgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ2NCBzcGFjZV91c2VkKSB7CisgICAgKytudW1fcmVzZXQ7CisgICAgaW50IGNvb2tpZV92YWx1ZSA9ICpzdGF0aWNfY2FzdDxpbnQqPihjb29raWUpOworICAgIEVYUEVDVF9FUShrQ29va2llVmFsdWUsIGNvb2tpZV92YWx1ZSk7CisgIH0KKworICBzdGF0aWMgdm9pZCBvbl9kZXN0cnVjdGlvbig6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSwgdm9pZCogY29va2llLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50NjQgc3BhY2VfdXNlZCkgeworICAgICsrbnVtX2Rlc3RydWN0OworICAgIGludCBjb29raWVfdmFsdWUgPSAqc3RhdGljX2Nhc3Q8aW50Kj4oY29va2llKTsKKyAgICBFWFBFQ1RfRVEoa0Nvb2tpZVZhbHVlLCBjb29raWVfdmFsdWUpOworICAgIGRlbGV0ZSBzdGF0aWNfY2FzdDxpbnQqPihjb29raWUpOworICB9CisKKyAgc3RhdGljIGNvbnN0IGludCBrQ29va2llVmFsdWUgPSA5OTk7CisgIHN0YXRpYyB1aW50MzIgbnVtX2luaXQ7CisgIHN0YXRpYyB1aW50MzIgbnVtX2FsbG9jYXRpb25zOworICBzdGF0aWMgdWludDMyIG51bV9yZXNldDsKKyAgc3RhdGljIHVpbnQzMiBudW1fZGVzdHJ1Y3Q7Cit9OwordWludDMyIEFyZW5hSG9va3NUZXN0VXRpbDo6bnVtX2luaXQgPSAwOwordWludDMyIEFyZW5hSG9va3NUZXN0VXRpbDo6bnVtX2FsbG9jYXRpb25zID0gMDsKK3VpbnQzMiBBcmVuYUhvb2tzVGVzdFV0aWw6Om51bV9yZXNldCA9IDA7Cit1aW50MzIgQXJlbmFIb29rc1Rlc3RVdGlsOjpudW1fZGVzdHJ1Y3QgPSAwOworY29uc3QgaW50IEFyZW5hSG9va3NUZXN0VXRpbDo6a0Nvb2tpZVZhbHVlOworCisvLyBUZXN0IHRoZSBob29rcyBhcmUgY29ycmVjdGx5IGNhbGxlZCBhbmQgdGhhdCB0aGUgY29va2llIGlzIHBhc3NlZC4KK1RFU1QoQXJlbmFUZXN0LCBBcmVuYUhvb2tzU2FuaXR5KSB7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmFPcHRpb25zIG9wdGlvbnM7CisgIG9wdGlvbnMub25fYXJlbmFfaW5pdCA9IEFyZW5hSG9va3NUZXN0VXRpbDo6b25faW5pdDsKKyAgb3B0aW9ucy5vbl9hcmVuYV9hbGxvY2F0aW9uID0gQXJlbmFIb29rc1Rlc3RVdGlsOjpvbl9hbGxvY2F0aW9uOworICBvcHRpb25zLm9uX2FyZW5hX3Jlc2V0ID0gQXJlbmFIb29rc1Rlc3RVdGlsOjpvbl9yZXNldDsKKyAgb3B0aW9ucy5vbl9hcmVuYV9kZXN0cnVjdGlvbiA9IEFyZW5hSG9va3NUZXN0VXRpbDo6b25fZGVzdHJ1Y3Rpb247CisKKyAgLy8gU2NvcGUgZm9yIGRlZmluaW5nIHRoZSBhcmVuYQorICB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSBhcmVuYShvcHRpb25zKTsKKyAgICBFWFBFQ1RfRVEoMSwgQXJlbmFIb29rc1Rlc3RVdGlsOjpudW1faW5pdCk7CisgICAgRVhQRUNUX0VRKDAsIEFyZW5hSG9va3NUZXN0VXRpbDo6bnVtX2FsbG9jYXRpb25zKTsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hOjpDcmVhdGU8dWludDY0PigmYXJlbmEpOworICAgIGlmIChnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6aGFzX3RyaXZpYWxfZGVzdHJ1Y3Rvcjx1aW50NjQ+Ojp2YWx1ZSkgeworICAgICAgRVhQRUNUX0VRKDEsIEFyZW5hSG9va3NUZXN0VXRpbDo6bnVtX2FsbG9jYXRpb25zKTsKKyAgICB9IGVsc2UgeworICAgICAgRVhQRUNUX0VRKDIsIEFyZW5hSG9va3NUZXN0VXRpbDo6bnVtX2FsbG9jYXRpb25zKTsKKyAgICB9CisgICAgYXJlbmEuUmVzZXQoKTsKKyAgICBhcmVuYS5SZXNldCgpOworICAgIEVYUEVDVF9FUSgyLCBBcmVuYUhvb2tzVGVzdFV0aWw6Om51bV9yZXNldCk7CisgIH0KKyAgRVhQRUNUX0VRKDMsIEFyZW5hSG9va3NUZXN0VXRpbDo6bnVtX3Jlc2V0KTsKKyAgRVhQRUNUX0VRKDEsIEFyZW5hSG9va3NUZXN0VXRpbDo6bnVtX2Rlc3RydWN0KTsKK30KKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2FyZW5hc3RyaW5nLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9hcmVuYXN0cmluZy5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jY2U2MWQ3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9hcmVuYXN0cmluZy5jYwpAQCAtMCwwICsxLDUzIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gVGhlIEFyZW5hU3RyaW5nIGltcGxlbWVudGF0aW9uIGlzIG5vdCBpbmNsdWRlZCBpbiB0aGUgb3Blbi1zb3VyY2UgcmVsZWFzZS4gRG8KKy8vIG5vdCBpbmNsdWRlIHRoaXMgZmlsZSBpbiB0aGUgZGlzdHJpYnV0aW9uLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2FyZW5hc3RyaW5nLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKKwordm9pZCBBcmVuYVN0cmluZ1B0cjo6QXNzaWduV2l0aERlZmF1bHQoY29uc3QgOjpzdGQ6OnN0cmluZyogZGVmYXVsdF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFyZW5hU3RyaW5nUHRyIHZhbHVlKSB7CisgIGNvbnN0IDo6c3RkOjpzdHJpbmcqIG1lID0gKlVuc2FmZVJhd1N0cmluZ1BvaW50ZXIoKTsKKyAgY29uc3QgOjpzdGQ6OnN0cmluZyogb3RoZXIgPSAqdmFsdWUuVW5zYWZlUmF3U3RyaW5nUG9pbnRlcigpOworICAvLyBJZiB0aGUgcG9pbnRlcnMgYXJlIHRoZSBzYW1lIHRoZW4gZG8gbm90aGluZy4KKyAgaWYgKG1lICE9IG90aGVyKSB7CisgICAgU2V0Tm9BcmVuYShkZWZhdWx0X3ZhbHVlLCB2YWx1ZS5HZXROb0FyZW5hKGRlZmF1bHRfdmFsdWUpKTsKKyAgfQorfQorCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9hcmVuYXN0cmluZy5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9hcmVuYXN0cmluZy5oCm5ldyBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IDAwMDAwMDAuLmUyZTJmMjUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2FyZW5hc3RyaW5nLmgKQEAgLTAsMCArMSwzMTMgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9BUkVOQVNUUklOR19IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0FSRU5BU1RSSU5HX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2xvZ2dpbmcuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2Zhc3RtZW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvYXJlbmEuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX21lc3NhZ2VfdXRpbC5oPgorCisKKworLy8gVGhpcyBpcyB0aGUgaW1wbGVtZW50YXRpb24gb2YgYXJlbmEgc3RyaW5nIGZpZWxkcyB3cml0dGVuIGZvciB0aGUgb3Blbi1zb3VyY2UKKy8vIHJlbGVhc2UuIFRoZSBBcmVuYVN0cmluZ1B0ciBzdHJ1Y3QgYmVsb3cgaXMgYW4gaW50ZXJuYWwgaW1wbGVtZW50YXRpb24gY2xhc3MKKy8vIGFuZCAqc2hvdWxkIG5vdCBiZSB1c2VkKiBieSB1c2VyIGNvZGUuIEl0IGlzIHVzZWQgdG8gY29sbGVjdCBzdHJpbmcKKy8vIG9wZXJhdGlvbnMgdG9nZXRoZXIgaW50byBvbmUgcGxhY2UgYW5kIGFic3RyYWN0IGF3YXkgdGhlIHVuZGVybHlpbmcKKy8vIHN0cmluZy1maWVsZCBwb2ludGVyIHJlcHJlc2VudGF0aW9uLCBzbyB0aGF0IChmb3IgZXhhbXBsZSkgYW4gYWx0ZXJuYXRlCisvLyBpbXBsZW1lbnRhdGlvbiB0aGF0IGtuZXcgbW9yZSBhYm91dCA6OnN0ZDo6c3RyaW5nJ3MgaW50ZXJuYWxzIGNvdWxkIGludGVncmF0ZSBtb3JlCisvLyBjbG9zZWx5IHdpdGggdGhlIGFyZW5hIGFsbG9jYXRvci4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKworc3RydWN0IExJQlBST1RPQlVGX0VYUE9SVCBBcmVuYVN0cmluZ1B0ciB7CisgIGlubGluZSB2b2lkIFNldChjb25zdCA6OnN0ZDo6c3RyaW5nKiBkZWZhdWx0X3ZhbHVlLAorICAgICAgICAgICAgICAgICAgY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSB7CisgICAgaWYgKHB0cl8gPT0gZGVmYXVsdF92YWx1ZSkgeworICAgICAgQ3JlYXRlSW5zdGFuY2UoYXJlbmEsICZ2YWx1ZSk7CisgICAgfSBlbHNlIHsKKyAgICAgICpwdHJfID0gdmFsdWU7CisgICAgfQorICB9CisKKyAgLy8gQmFzaWMgYWNjZXNzb3JzLgorICBpbmxpbmUgY29uc3QgOjpzdGQ6OnN0cmluZyYgR2V0KGNvbnN0IDo6c3RkOjpzdHJpbmcqIC8qIGRlZmF1bHRfdmFsdWUgKi8pIGNvbnN0IHsKKyAgICByZXR1cm4gKnB0cl87CisgIH0KKworICBpbmxpbmUgOjpzdGQ6OnN0cmluZyogTXV0YWJsZShjb25zdCA6OnN0ZDo6c3RyaW5nKiBkZWZhdWx0X3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIHsKKyAgICBpZiAocHRyXyA9PSBkZWZhdWx0X3ZhbHVlKSB7CisgICAgICBDcmVhdGVJbnN0YW5jZShhcmVuYSwgZGVmYXVsdF92YWx1ZSk7CisgICAgfQorICAgIHJldHVybiBwdHJfOworICB9CisKKyAgLy8gUmVsZWFzZSByZXR1cm5zIGEgOjpzdGQ6OnN0cmluZyogaW5zdGFuY2UgdGhhdCBpcyBoZWFwLWFsbG9jYXRlZCBhbmQgaXMgbm90CisgIC8vIE93bigpJ2QgYnkgYW55IGFyZW5hLiBJZiB0aGUgZmllbGQgd2FzIG5vdCBzZXQsIGl0IHJldHVybnMgTlVMTC4gVGhlIGNhbGxlcgorICAvLyByZXRhaW5zIG93bmVyc2hpcC4gQ2xlYXJzIHRoaXMgZmllbGQgYmFjayB0byBOVUxMIHN0YXRlLiBVc2VkIHRvIGltcGxlbWVudAorICAvLyByZWxlYXNlXzxmaWVsZD4oKSBtZXRob2RzIG9uIGdlbmVyYXRlZCBjbGFzc2VzLgorICBpbmxpbmUgOjpzdGQ6OnN0cmluZyogUmVsZWFzZShjb25zdCA6OnN0ZDo6c3RyaW5nKiBkZWZhdWx0X3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIHsKKyAgICBpZiAocHRyXyA9PSBkZWZhdWx0X3ZhbHVlKSB7CisgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgOjpzdGQ6OnN0cmluZyogcmVsZWFzZWQgPSBOVUxMOworICAgIGlmIChhcmVuYSAhPSBOVUxMKSB7CisgICAgICAvLyBwdHJfIGlzIG93bmVkIGJ5IHRoZSBhcmVuYSAtLSB3ZSBuZWVkIHRvIHJldHVybiBhIGNvcHkuCisgICAgICByZWxlYXNlZCA9IG5ldyA6OnN0ZDo6c3RyaW5nKCpwdHJfKTsKKyAgICB9IGVsc2UgeworICAgICAgcmVsZWFzZWQgPSBwdHJfOworICAgIH0KKyAgICBwdHJfID0gY29uc3RfY2FzdDwgOjpzdGQ6OnN0cmluZyogPihkZWZhdWx0X3ZhbHVlKTsKKyAgICByZXR1cm4gcmVsZWFzZWQ7CisgIH0KKworICAvLyBVbnNhZmVBcmVuYVJlbGVhc2UgcmV0dXJucyBhIDo6c3RkOjpzdHJpbmcqLCBidXQgaXQgbWF5IGJlIGFyZW5hLW93bmVkIChpLmUuCisgIC8vIGhhdmUgaXRzIGRlc3RydWN0b3IgYWxyZWFkeSByZWdpc3RlcmVkKSBpZiBhcmVuYSAhPSBOVUxMLiBJZiB0aGUgZmllbGQgd2FzCisgIC8vIG5vdCBzZXQsIHRoaXMgcmV0dXJucyBOVUxMLiBUaGlzIG1ldGhvZCBjbGVhcnMgdGhpcyBmaWVsZCBiYWNrIHRvIE5VTEwKKyAgLy8gc3RhdGUuIFVzZWQgdG8gaW1wbGVtZW50IHVuc2FmZV9hcmVuYV9yZWxlYXNlXzxmaWVsZD4oKSBtZXRob2RzIG9uCisgIC8vIGdlbmVyYXRlZCBjbGFzc2VzLgorICBpbmxpbmUgOjpzdGQ6OnN0cmluZyogVW5zYWZlQXJlbmFSZWxlYXNlKGNvbnN0IDo6c3RkOjpzdHJpbmcqIGRlZmF1bHRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIC8qIGFyZW5hICovKSB7CisgICAgaWYgKHB0cl8gPT0gZGVmYXVsdF92YWx1ZSkgeworICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIDo6c3RkOjpzdHJpbmcqIHJlbGVhc2VkID0gcHRyXzsKKyAgICBwdHJfID0gY29uc3RfY2FzdDwgOjpzdGQ6OnN0cmluZyogPihkZWZhdWx0X3ZhbHVlKTsKKyAgICByZXR1cm4gcmVsZWFzZWQ7CisgIH0KKworICAvLyBUYWtlcyBhIHN0cmluZyB0aGF0IGlzIGhlYXAtYWxsb2NhdGVkLCBhbmQgdGFrZXMgb3duZXJzaGlwLiBUaGUgc3RyaW5nJ3MKKyAgLy8gZGVzdHJ1Y3RvciBpcyByZWdpc3RlcmVkIHdpdGggdGhlIGFyZW5hLiBVc2VkIHRvIGltcGxlbWVudAorICAvLyBzZXRfYWxsb2NhdGVkXzxmaWVsZD4gaW4gZ2VuZXJhdGVkIGNsYXNzZXMuCisgIGlubGluZSB2b2lkIFNldEFsbG9jYXRlZChjb25zdCA6OnN0ZDo6c3RyaW5nKiBkZWZhdWx0X3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgOjpzdGQ6OnN0cmluZyogdmFsdWUsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSB7CisgICAgaWYgKGFyZW5hID09IE5VTEwgJiYgcHRyXyAhPSBkZWZhdWx0X3ZhbHVlKSB7CisgICAgICBEZXN0cm95KGRlZmF1bHRfdmFsdWUsIGFyZW5hKTsKKyAgICB9CisgICAgaWYgKHZhbHVlICE9IE5VTEwpIHsKKyAgICAgIHB0cl8gPSB2YWx1ZTsKKyAgICAgIGlmIChhcmVuYSAhPSBOVUxMKSB7CisgICAgICAgIGFyZW5hLT5Pd24odmFsdWUpOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICBwdHJfID0gY29uc3RfY2FzdDwgOjpzdGQ6OnN0cmluZyogPihkZWZhdWx0X3ZhbHVlKTsKKyAgICB9CisgIH0KKworICAvLyBUYWtlcyBhIHN0cmluZyB0aGF0IGhhcyBsaWZldGltZSBlcXVhbCB0byB0aGUgYXJlbmEncyBsaWZldGltZS4gVGhlIGFyZW5hCisgIC8vIG11c3QgYmUgbm9uLW51bGwuIEl0IGlzIHNhZmUgb25seSB0byBwYXNzIHRoaXMgbWV0aG9kIGEgdmFsdWUgcmV0dXJuZWQgYnkKKyAgLy8gVW5zYWZlQXJlbmFSZWxlYXNlKCkgb24gYW5vdGhlciBmaWVsZCBvZiBhIG1lc3NhZ2UgaW4gdGhlIHNhbWUgYXJlbmEuIFVzZWQKKyAgLy8gdG8gaW1wbGVtZW50IHVuc2FmZV9hcmVuYV9zZXRfYWxsb2NhdGVkXzxmaWVsZD4gaW4gZ2VuZXJhdGVkIGNsYXNzZXMuCisgIGlubGluZSB2b2lkIFVuc2FmZUFyZW5hU2V0QWxsb2NhdGVkKGNvbnN0IDo6c3RkOjpzdHJpbmcqIGRlZmF1bHRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDo6c3RkOjpzdHJpbmcqIHZhbHVlLCA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiAvKiBhcmVuYSAqLykgeworICAgIGlmICh2YWx1ZSAhPSBOVUxMKSB7CisgICAgICBwdHJfID0gdmFsdWU7CisgICAgfSBlbHNlIHsKKyAgICAgIHB0cl8gPSBjb25zdF9jYXN0PCA6OnN0ZDo6c3RyaW5nKiA+KGRlZmF1bHRfdmFsdWUpOworICAgIH0KKyAgfQorCisgIC8vIFN3YXBzIGludGVybmFsIHBvaW50ZXJzLiBBcmVuYS1zYWZldHkgc2VtYW50aWNzOiB0aGlzIGlzIGd1YXJkZWQgYnkgdGhlCisgIC8vIGxvZ2ljIGluIFN3YXAoKS9VbnNhZmVBcmVuYVN3YXAoKSBhdCB0aGUgbWVzc2FnZSBsZXZlbCwgc28gdGhpcyBtZXRob2QgaXMKKyAgLy8gJ3Vuc2FmZScgaWYgY2FsbGVkIGRpcmVjdGx5LgorICBHT09HTEVfQVRUUklCVVRFX0FMV0FZU19JTkxJTkUgdm9pZCBTd2FwKEFyZW5hU3RyaW5nUHRyKiBvdGhlcikgeworICAgIHN0ZDo6c3dhcChwdHJfLCBvdGhlci0+cHRyXyk7CisgIH0KKworICAvLyBGcmVlcyBzdG9yYWdlIChpZiBub3Qgb24gYW4gYXJlbmEpIGFuZCBzZXRzIGZpZWxkIHRvIGRlZmF1bHQgdmFsdWUuCisgIGlubGluZSB2b2lkIERlc3Ryb3koY29uc3QgOjpzdGQ6OnN0cmluZyogZGVmYXVsdF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgeworICAgIGlmIChhcmVuYSA9PSBOVUxMICYmIHB0cl8gIT0gZGVmYXVsdF92YWx1ZSkgeworICAgICAgZGVsZXRlIHB0cl87CisgICAgfQorICAgIHB0cl8gPSBjb25zdF9jYXN0PCA6OnN0ZDo6c3RyaW5nKiA+KGRlZmF1bHRfdmFsdWUpOworICB9CisKKyAgLy8gQ2xlYXJzIGNvbnRlbnQsIGJ1dCBrZWVwcyBhbGxvY2F0ZWQgc3RyaW5nIGlmIGFyZW5hICE9IE5VTEwsIHRvIGF2b2lkIHRoZQorICAvLyBvdmVyaGVhZCBvZiBoZWFwIG9wZXJhdGlvbnMuIEFmdGVyIHRoaXMgcmV0dXJucywgdGhlIGNvbnRlbnQgKGFzIHNlZW4gYnkKKyAgLy8gdGhlIHVzZXIpIHdpbGwgYWx3YXlzIGJlIHRoZSBlbXB0eSBzdHJpbmcuIEFzc3VtZXMgdGhhdCB8ZGVmYXVsdF92YWx1ZXwKKyAgLy8gaXMgYW4gZW1wdHkgc3RyaW5nLgorICBpbmxpbmUgdm9pZCBDbGVhclRvRW1wdHkoY29uc3QgOjpzdGQ6OnN0cmluZyogZGVmYXVsdF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIC8qIGFyZW5hICovKSB7CisgICAgaWYgKHB0cl8gPT0gZGVmYXVsdF92YWx1ZSkgeworICAgICAgLy8gQWxyZWFkeSBzZXQgdG8gZGVmYXVsdCAod2hpY2ggaXMgZW1wdHkpIC0tIGRvIG5vdGhpbmcuCisgICAgfSBlbHNlIHsKKyAgICAgIHB0cl8tPmNsZWFyKCk7CisgICAgfQorICB9CisKKyAgLy8gQ2xlYXJzIGNvbnRlbnQsIGJ1dCBrZWVwcyBhbGxvY2F0ZWQgc3RyaW5nIGlmIGFyZW5hICE9IE5VTEwsIHRvIGF2b2lkIHRoZQorICAvLyBvdmVyaGVhZCBvZiBoZWFwIG9wZXJhdGlvbnMuIEFmdGVyIHRoaXMgcmV0dXJucywgdGhlIGNvbnRlbnQgKGFzIHNlZW4gYnkKKyAgLy8gdGhlIHVzZXIpIHdpbGwgYWx3YXlzIGJlIGVxdWFsIHRvIHxkZWZhdWx0X3ZhbHVlfC4KKyAgaW5saW5lIHZvaWQgQ2xlYXJUb0RlZmF1bHQoY29uc3QgOjpzdGQ6OnN0cmluZyogZGVmYXVsdF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogLyogYXJlbmEgKi8pIHsKKyAgICBpZiAocHRyXyA9PSBkZWZhdWx0X3ZhbHVlKSB7CisgICAgICAvLyBBbHJlYWR5IHNldCB0byBkZWZhdWx0IC0tIGRvIG5vdGhpbmcuCisgICAgfSBlbHNlIHsKKyAgICAgIC8vIEhhdmUgYW5vdGhlciBhbGxvY2F0ZWQgc3RyaW5nIC0tIHJhdGhlciB0aGFuIHRocm93aW5nIHRoaXMgYXdheSBhbmQKKyAgICAgIC8vIHJlc2V0dGluZyBwdHJfIHRvIHRoZSBjYW5vbmljYWwgZGVmYXVsdCBzdHJpbmcgaW5zdGFuY2UsIHdlIGp1c3QgcmV1c2UKKyAgICAgIC8vIHRoaXMgaW5zdGFuY2UuCisgICAgICAqcHRyXyA9ICpkZWZhdWx0X3ZhbHVlOworICAgIH0KKyAgfQorCisgIC8vIENhbGxlZCBmcm9tIGdlbmVyYXRlZCBjb2RlIC8gcmVmbGVjdGlvbiBydW50aW1lIG9ubHkuIFJlc2V0cyB2YWx1ZSB0byBwb2ludAorICAvLyB0byBhIGRlZmF1bHQgc3RyaW5nIHBvaW50ZXIsIHdpdGggdGhlIHNlbWFudGljcyB0aGF0IHRoaXMgQXJlbmFTdHJpbmdQdHIKKyAgLy8gZG9lcyBub3Qgb3duIHRoZSBwb2ludGVkLXRvIG1lbW9yeS4gRGlzcmVnYXJkcyBpbml0aWFsIHZhbHVlIG9mIHB0cl8gKHNvCisgIC8vIHRoaXMgaXMgdGhlICpPTkxZKiBzYWZlIG1ldGhvZCB0byBjYWxsIGFmdGVyIGNvbnN0cnVjdGlvbiBvciB3aGVuCisgIC8vIHJlaW5pdGlhbGl6aW5nIGFmdGVyIGJlY29taW5nIHRoZSBhY3RpdmUgZmllbGQgaW4gYSBvbmVvZiB1bmlvbikuCisgIGlubGluZSB2b2lkIFVuc2FmZVNldERlZmF1bHQoY29uc3QgOjpzdGQ6OnN0cmluZyogZGVmYXVsdF92YWx1ZSkgeworICAgIC8vIENhc3RpbmcgYXdheSAnY29uc3QnIGlzIHNhZmUgaGVyZTogYWNjZXNzb3JzIGVuc3VyZSB0aGF0IHB0cl8gaXMgb25seQorICAgIC8vIHJldHVybmVkIGFzIGEgY29uc3QgaWYgaXQgaXMgZXF1YWwgdG8gZGVmYXVsdF92YWx1ZS4KKyAgICBwdHJfID0gY29uc3RfY2FzdDwgOjpzdGQ6OnN0cmluZyogPihkZWZhdWx0X3ZhbHVlKTsKKyAgfQorCisgIC8vIFRoZSAnTm9BcmVuYScgdmFyaWFudHMgb2YgbWV0aG9kcyBiZWxvdyBhc3N1bWUgYXJlbmEgPT0gTlVMTCBhbmQgYXJlCisgIC8vIG9wdGltaXplZCB0byBwcm92aWRlIHZlcnkgbGl0dGxlIG92ZXJoZWFkIHJlbGF0aXZlIHRvIGEgcmF3IHN0cmluZyBwb2ludGVyCisgIC8vICh3aGlsZSBzdGlsbCBiZWluZyBpbi1tZW1vcnkgY29tcGF0aWJsZSB3aXRoIG90aGVyIGNvZGUgdGhhdCBhc3N1bWVzCisgIC8vIEFyZW5hU3RyaW5nUHRyKS4gTm90ZSB0aGUgaW52YXJpYW50IHRoYXQgYSBjbGFzcyBpbnN0YW5jZSB0aGF0IGhhcyBvbmx5CisgIC8vIGV2ZXIgYmVlbiBtdXRhdGVkIGJ5IE5vQXJlbmEgbWV0aG9kcyBtdXN0ICpvbmx5KiBiZSBpbiB0aGUgU3RyaW5nIHN0YXRlCisgIC8vIChpLmUuLCB0YWcgYml0cyBhcmUgbm90IHVzZWQpLCAqTkVWRVIqIEFyZW5hU3RyaW5nLiBUaGlzIGFsbG93cyBhbGwKKyAgLy8gdGFnZ2VkLXBvaW50ZXIgbWFuaXB1bGF0aW9ucyB0byBiZSBhdm9pZGVkLgorICBpbmxpbmUgdm9pZCBTZXROb0FyZW5hKGNvbnN0IDo6c3RkOjpzdHJpbmcqIGRlZmF1bHRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgICBpZiAocHRyXyA9PSBkZWZhdWx0X3ZhbHVlKSB7CisgICAgICBDcmVhdGVJbnN0YW5jZU5vQXJlbmEoJnZhbHVlKTsKKyAgICB9IGVsc2UgeworICAgICAgKnB0cl8gPSB2YWx1ZTsKKyAgICB9CisgIH0KKworICB2b2lkIEFzc2lnbldpdGhEZWZhdWx0KGNvbnN0IDo6c3RkOjpzdHJpbmcqIGRlZmF1bHRfdmFsdWUsIEFyZW5hU3RyaW5nUHRyIHZhbHVlKTsKKworICBpbmxpbmUgY29uc3QgOjpzdGQ6OnN0cmluZyYgR2V0Tm9BcmVuYShjb25zdCA6OnN0ZDo6c3RyaW5nKiAvKiBkZWZhdWx0X3ZhbHVlICovKSBjb25zdCB7CisgICAgcmV0dXJuICpwdHJfOworICB9CisKKyAgaW5saW5lIDo6c3RkOjpzdHJpbmcqIE11dGFibGVOb0FyZW5hKGNvbnN0IDo6c3RkOjpzdHJpbmcqIGRlZmF1bHRfdmFsdWUpIHsKKyAgICBpZiAocHRyXyA9PSBkZWZhdWx0X3ZhbHVlKSB7CisgICAgICBDcmVhdGVJbnN0YW5jZU5vQXJlbmEoZGVmYXVsdF92YWx1ZSk7CisgICAgfQorICAgIHJldHVybiBwdHJfOworICB9CisKKyAgaW5saW5lIDo6c3RkOjpzdHJpbmcqIFJlbGVhc2VOb0FyZW5hKGNvbnN0IDo6c3RkOjpzdHJpbmcqIGRlZmF1bHRfdmFsdWUpIHsKKyAgICBpZiAocHRyXyA9PSBkZWZhdWx0X3ZhbHVlKSB7CisgICAgICByZXR1cm4gTlVMTDsKKyAgICB9IGVsc2UgeworICAgICAgOjpzdGQ6OnN0cmluZyogcmVsZWFzZWQgPSBwdHJfOworICAgICAgcHRyXyA9IGNvbnN0X2Nhc3Q8IDo6c3RkOjpzdHJpbmcqID4oZGVmYXVsdF92YWx1ZSk7CisgICAgICByZXR1cm4gcmVsZWFzZWQ7CisgICAgfQorICB9CisKKyAgaW5saW5lIHZvaWQgU2V0QWxsb2NhdGVkTm9BcmVuYShjb25zdCA6OnN0ZDo6c3RyaW5nKiBkZWZhdWx0X3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDo6c3RkOjpzdHJpbmcqIHZhbHVlKSB7CisgICAgaWYgKHB0cl8gIT0gZGVmYXVsdF92YWx1ZSkgeworICAgICAgZGVsZXRlIHB0cl87CisgICAgfQorICAgIGlmICh2YWx1ZSAhPSBOVUxMKSB7CisgICAgICBwdHJfID0gdmFsdWU7CisgICAgfSBlbHNlIHsKKyAgICAgIHB0cl8gPSBjb25zdF9jYXN0PCA6OnN0ZDo6c3RyaW5nKiA+KGRlZmF1bHRfdmFsdWUpOworICAgIH0KKyAgfQorCisgIGlubGluZSB2b2lkIERlc3Ryb3lOb0FyZW5hKGNvbnN0IDo6c3RkOjpzdHJpbmcqIGRlZmF1bHRfdmFsdWUpIHsKKyAgICBpZiAocHRyXyAhPSBkZWZhdWx0X3ZhbHVlKSB7CisgICAgICBkZWxldGUgcHRyXzsKKyAgICB9CisgICAgcHRyXyA9IE5VTEw7CisgIH0KKworICBpbmxpbmUgdm9pZCBDbGVhclRvRW1wdHlOb0FyZW5hKGNvbnN0IDo6c3RkOjpzdHJpbmcqIGRlZmF1bHRfdmFsdWUpIHsKKyAgICBpZiAocHRyXyA9PSBkZWZhdWx0X3ZhbHVlKSB7CisgICAgICAvLyBOb3RoaW5nOiBhbHJlYWR5IGVxdWFsIHRvIGRlZmF1bHQgKHdoaWNoIGlzIHRoZSBlbXB0eSBzdHJpbmcpLgorICAgIH0gZWxzZSB7CisgICAgICBwdHJfLT5jbGVhcigpOworICAgIH0KKyAgfQorCisgIGlubGluZSB2b2lkIENsZWFyVG9EZWZhdWx0Tm9BcmVuYShjb25zdCA6OnN0ZDo6c3RyaW5nKiBkZWZhdWx0X3ZhbHVlKSB7CisgICAgaWYgKHB0cl8gPT0gZGVmYXVsdF92YWx1ZSkgeworICAgICAgLy8gTm90aGluZzogYWxyZWFkeSBzZXQgdG8gZGVmYXVsdC4KKyAgICB9IGVsc2UgeworICAgICAgLy8gUmV1c2UgZXhpc3RpbmcgYWxsb2NhdGVkIGluc3RhbmNlLgorICAgICAgKnB0cl8gPSAqZGVmYXVsdF92YWx1ZTsKKyAgICB9CisgIH0KKworICAvLyBJbnRlcm5hbCBhY2Nlc3NvciB1c2VkIG9ubHkgYXQgcGFyc2UgdGltZSB0byBwcm92aWRlIGRpcmVjdCBhY2Nlc3MgdG8gdGhlCisgIC8vIHJhdyBwb2ludGVyIGZyb20gdGhlIHNoYXJlZCBwYXJzZSByb3V0aW5lIChpbiB0aGUgbm9uLWFyZW5hcyBjYXNlKS4gVGhlCisgIC8vIHBhcnNlIHJvdXRpbmUgZG9lcyB0aGUgc3RyaW5nIGFsbG9jYXRpb24gaW4gb3JkZXIgdG8gc2F2ZSBjb2RlIHNpemUgaW4gdGhlCisgIC8vIGdlbmVyYXRlZCBwYXJzaW5nIGNvZGUuCisgIGlubGluZSA6OnN0ZDo6c3RyaW5nKiogVW5zYWZlUmF3U3RyaW5nUG9pbnRlcigpIHsKKyAgICByZXR1cm4gJnB0cl87CisgIH0KKworIHByaXZhdGU6CisgIDo6c3RkOjpzdHJpbmcqIHB0cl87CisKKyAgR09PR0xFX0FUVFJJQlVURV9OT0lOTElORSB2b2lkIENyZWF0ZUluc3RhbmNlKDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCA6OnN0ZDo6c3RyaW5nKiBpbml0aWFsX3ZhbHVlKSB7CisgICAgLy8gQXNzdW1lcyBwdHJfIGlzIG5vdCBOVUxMLgorICAgIGlmIChpbml0aWFsX3ZhbHVlICE9IE5VTEwpIHsKKyAgICAgIHB0cl8gPSBuZXcgOjpzdGQ6OnN0cmluZygqaW5pdGlhbF92YWx1ZSk7CisgICAgfSBlbHNlIHsKKyAgICAgIHB0cl8gPSBuZXcgOjpzdGQ6OnN0cmluZygpOworICAgIH0KKyAgICBpZiAoYXJlbmEgIT0gTlVMTCkgeworICAgICAgYXJlbmEtPk93bihwdHJfKTsKKyAgICB9CisgIH0KKyAgR09PR0xFX0FUVFJJQlVURV9OT0lOTElORSB2b2lkIENyZWF0ZUluc3RhbmNlTm9BcmVuYShjb25zdCA6OnN0ZDo6c3RyaW5nKiBpbml0aWFsX3ZhbHVlKSB7CisgICAgaWYgKGluaXRpYWxfdmFsdWUgIT0gTlVMTCkgeworICAgICAgcHRyXyA9IG5ldyA6OnN0ZDo6c3RyaW5nKCppbml0aWFsX3ZhbHVlKTsKKyAgICB9IGVsc2UgeworICAgICAgcHRyXyA9IG5ldyA6OnN0ZDo6c3RyaW5nKCk7CisgICAgfQorICB9Cit9OworCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCisKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQVJFTkFTVFJJTkdfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2FyZW5hc3RyaW5nX3VuaXR0ZXN0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9hcmVuYXN0cmluZ191bml0dGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZmI1ODJiCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9hcmVuYXN0cmluZ191bml0dGVzdC5jYwpAQCAtMCwwICsxLDExMyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIGFyZW5hc3RyaW5nX3VuaXR0ZXN0LmNjIGlzIG5vdCBvcGVuLXNvdXJjZWQuIERvIG5vdCBpbmNsdWRlIGluIG9wZW4tc291cmNlCisvLyBkaXN0cmlidXRpb24uCisKKy8vIEJhc2VkIG9uIG12ZWxzQCdzIGZyYW5rZW5zdHJpbmcuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvYXJlbmFzdHJpbmcuaD4KKworI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxtZW1vcnk+CisjaWZuZGVmIF9TSEFSRURfUFRSX0gKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc2hhcmVkX3B0ci5oPgorI2VuZGlmCisjaW5jbHVkZSA8Y3N0ZGxpYj4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9sb2dnaW5nLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGd0ZXN0L2d0ZXN0Lmg+CisKK25hbWVzcGFjZSBnb29nbGUgewordXNpbmcgZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFyZW5hU3RyaW5nOwordXNpbmcgZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFyZW5hU3RyaW5nUHRyOworCituYW1lc3BhY2UgcHJvdG9idWYgeworCisKK3N0YXRpYyBzdHJpbmcgV3JhcFN0cmluZyhjb25zdCBjaGFyKiB2YWx1ZSkgeworICByZXR1cm4gdmFsdWU7Cit9CisKKy8vIFRlc3QgQXJlbmFTdHJpbmdQdHIgd2l0aCBhcmVuYSA9PSBOVUxMLgorVEVTVChBcmVuYVN0cmluZ1B0clRlc3QsIEFyZW5hU3RyaW5nUHRyT25IZWFwKSB7CisgIEFyZW5hU3RyaW5nUHRyIGZpZWxkOworICA6OnN0ZDo6c3RyaW5nIGRlZmF1bHRfdmFsdWUgPSAiZGVmYXVsdCI7CisgIGZpZWxkLlVuc2FmZVNldERlZmF1bHQoJmRlZmF1bHRfdmFsdWUpOworICBFWFBFQ1RfRVEoc3RyaW5nKCJkZWZhdWx0IiksIGZpZWxkLkdldCgmZGVmYXVsdF92YWx1ZSkpOworICBmaWVsZC5TZXQoJmRlZmF1bHRfdmFsdWUsIFdyYXBTdHJpbmcoIlRlc3Qgc2hvcnQiKSwgTlVMTCk7CisgIEVYUEVDVF9FUShzdHJpbmcoIlRlc3Qgc2hvcnQiKSwgZmllbGQuR2V0KCZkZWZhdWx0X3ZhbHVlKSk7CisgIGZpZWxkLlNldCgmZGVmYXVsdF92YWx1ZSwgV3JhcFN0cmluZygiVGVzdCBsb25nIGxvbmcgbG9uZyBsb25nIHZhbHVlIiksIE5VTEwpOworICBFWFBFQ1RfRVEoc3RyaW5nKCJUZXN0IGxvbmcgbG9uZyBsb25nIGxvbmcgdmFsdWUiKSwgZmllbGQuR2V0KCZkZWZhdWx0X3ZhbHVlKSk7CisgIGZpZWxkLlNldCgmZGVmYXVsdF92YWx1ZSwgc3RyaW5nKCIiKSwgTlVMTCk7CisgIGZpZWxkLkRlc3Ryb3koJmRlZmF1bHRfdmFsdWUsIE5VTEwpOworCisgIEFyZW5hU3RyaW5nUHRyIGZpZWxkMjsKKyAgZmllbGQyLlVuc2FmZVNldERlZmF1bHQoJmRlZmF1bHRfdmFsdWUpOworICA6OnN0ZDo6c3RyaW5nKiBtdXQgPSBmaWVsZDIuTXV0YWJsZSgmZGVmYXVsdF92YWx1ZSwgTlVMTCk7CisgIEVYUEVDVF9FUShtdXQsIGZpZWxkMi5NdXRhYmxlKCZkZWZhdWx0X3ZhbHVlLCBOVUxMKSk7CisgIEVYUEVDVF9FUShtdXQsICZmaWVsZDIuR2V0KCZkZWZhdWx0X3ZhbHVlKSk7CisgIEVYUEVDVF9ORSgmZGVmYXVsdF92YWx1ZSwgbXV0KTsKKyAgRVhQRUNUX0VRKHN0cmluZygiZGVmYXVsdCIpLCAqbXV0KTsKKyAgKm11dCA9ICJUZXN0IGxvbmcgbG9uZyBsb25nIGxvbmcgdmFsdWUiOyAgLy8gZW5zdXJlIHN0cmluZyBhbGxvY2F0ZXMgc3RvcmFnZQorICBFWFBFQ1RfRVEoc3RyaW5nKCJUZXN0IGxvbmcgbG9uZyBsb25nIGxvbmcgdmFsdWUiKSwgZmllbGQyLkdldCgmZGVmYXVsdF92YWx1ZSkpOworICBmaWVsZDIuRGVzdHJveSgmZGVmYXVsdF92YWx1ZSwgTlVMTCk7Cit9CisKK1RFU1QoQXJlbmFTdHJpbmdQdHJUZXN0LCBBcmVuYVN0cmluZ1B0ck9uQXJlbmEpIHsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEgYXJlbmE7CisgIEFyZW5hU3RyaW5nUHRyIGZpZWxkOworICA6OnN0ZDo6c3RyaW5nIGRlZmF1bHRfdmFsdWUgPSAiZGVmYXVsdCI7CisgIGZpZWxkLlVuc2FmZVNldERlZmF1bHQoJmRlZmF1bHRfdmFsdWUpOworICBFWFBFQ1RfRVEoc3RyaW5nKCJkZWZhdWx0IiksIGZpZWxkLkdldCgmZGVmYXVsdF92YWx1ZSkpOworICBmaWVsZC5TZXQoJmRlZmF1bHRfdmFsdWUsIFdyYXBTdHJpbmcoIlRlc3Qgc2hvcnQiKSwgJmFyZW5hKTsKKyAgRVhQRUNUX0VRKHN0cmluZygiVGVzdCBzaG9ydCIpLCBmaWVsZC5HZXQoJmRlZmF1bHRfdmFsdWUpKTsKKyAgZmllbGQuU2V0KCZkZWZhdWx0X3ZhbHVlLCBXcmFwU3RyaW5nKCJUZXN0IGxvbmcgbG9uZyBsb25nIGxvbmcgdmFsdWUiKSwgJmFyZW5hKTsKKyAgRVhQRUNUX0VRKHN0cmluZygiVGVzdCBsb25nIGxvbmcgbG9uZyBsb25nIHZhbHVlIiksCisgICAgICAgICAgICBmaWVsZC5HZXQoJmRlZmF1bHRfdmFsdWUpKTsKKyAgZmllbGQuU2V0KCZkZWZhdWx0X3ZhbHVlLCBzdHJpbmcoIiIpLCAmYXJlbmEpOworICBmaWVsZC5EZXN0cm95KCZkZWZhdWx0X3ZhbHVlLCAmYXJlbmEpOworCisgIEFyZW5hU3RyaW5nUHRyIGZpZWxkMjsKKyAgZmllbGQyLlVuc2FmZVNldERlZmF1bHQoJmRlZmF1bHRfdmFsdWUpOworICA6OnN0ZDo6c3RyaW5nKiBtdXQgPSBmaWVsZDIuTXV0YWJsZSgmZGVmYXVsdF92YWx1ZSwgJmFyZW5hKTsKKyAgRVhQRUNUX0VRKG11dCwgZmllbGQyLk11dGFibGUoJmRlZmF1bHRfdmFsdWUsICZhcmVuYSkpOworICBFWFBFQ1RfRVEobXV0LCAmZmllbGQyLkdldCgmZGVmYXVsdF92YWx1ZSkpOworICBFWFBFQ1RfTkUoJmRlZmF1bHRfdmFsdWUsIG11dCk7CisgIEVYUEVDVF9FUShzdHJpbmcoImRlZmF1bHQiKSwgKm11dCk7CisgICptdXQgPSAiVGVzdCBsb25nIGxvbmcgbG9uZyBsb25nIHZhbHVlIjsgIC8vIGVuc3VyZSBzdHJpbmcgYWxsb2NhdGVzIHN0b3JhZ2UKKyAgRVhQRUNUX0VRKHN0cmluZygiVGVzdCBsb25nIGxvbmcgbG9uZyBsb25nIHZhbHVlIiksCisgICAgICAgICAgICBmaWVsZDIuR2V0KCZkZWZhdWx0X3ZhbHVlKSk7CisgIGZpZWxkMi5EZXN0cm95KCZkZWZhdWx0X3ZhbHVlLCAmYXJlbmEpOworfQorCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY29kZV9nZW5lcmF0b3IuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvZGVfZ2VuZXJhdG9yLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ3M2ViNGUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvZGVfZ2VuZXJhdG9yLmNjCkBAIC0wLDAgKzEsODUgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jb2RlX2dlbmVyYXRvci5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2xvZ2dpbmcuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKKworQ29kZUdlbmVyYXRvcjo6fkNvZGVHZW5lcmF0b3IoKSB7fQorR2VuZXJhdG9yQ29udGV4dDo6fkdlbmVyYXRvckNvbnRleHQoKSB7fQorCitpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0qCitHZW5lcmF0b3JDb250ZXh0OjpPcGVuRm9yQXBwZW5kKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUpIHsKKyAgcmV0dXJuIE5VTEw7Cit9CisKK2lvOjpaZXJvQ29weU91dHB1dFN0cmVhbSogR2VuZXJhdG9yQ29udGV4dDo6T3BlbkZvckluc2VydCgKKyAgICBjb25zdCBzdHJpbmcmIGZpbGVuYW1lLCBjb25zdCBzdHJpbmcmIGluc2VydGlvbl9wb2ludCkgeworICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiVGhpcyBHZW5lcmF0b3JDb250ZXh0IGRvZXMgbm90IHN1cHBvcnQgaW5zZXJ0aW9uLiI7CisgIHJldHVybiBOVUxMOyAgLy8gbWFrZSBjb21waWxlciBoYXBweQorfQorCit2b2lkIEdlbmVyYXRvckNvbnRleHQ6Okxpc3RQYXJzZWRGaWxlcygKKyAgICB2ZWN0b3I8Y29uc3QgRmlsZURlc2NyaXB0b3IqPiogb3V0cHV0KSB7CisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJUaGlzIEdlbmVyYXRvckNvbnRleHQgZG9lcyBub3Qgc3VwcG9ydCBMaXN0UGFyc2VkRmlsZXMiOworfQorCisvLyBQYXJzZXMgYSBzZXQgb2YgY29tbWEtZGVsaW1pdGVkIG5hbWUvdmFsdWUgcGFpcnMuCit2b2lkIFBhcnNlR2VuZXJhdG9yUGFyYW1ldGVyKGNvbnN0IHN0cmluZyYgdGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjdG9yPHBhaXI8c3RyaW5nLCBzdHJpbmc+ID4qIG91dHB1dCkgeworICB2ZWN0b3I8c3RyaW5nPiBwYXJ0cyA9IFNwbGl0KHRleHQsICIsIiwgdHJ1ZSk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYXJ0cy5zaXplKCk7IGkrKykgeworICAgIHN0cmluZzo6c2l6ZV90eXBlIGVxdWFsc19wb3MgPSBwYXJ0c1tpXS5maW5kX2ZpcnN0X29mKCc9Jyk7CisgICAgcGFpcjxzdHJpbmcsIHN0cmluZz4gdmFsdWU7CisgICAgaWYgKGVxdWFsc19wb3MgPT0gc3RyaW5nOjpucG9zKSB7CisgICAgICB2YWx1ZS5maXJzdCA9IHBhcnRzW2ldOworICAgICAgdmFsdWUuc2Vjb25kID0gIiI7CisgICAgfSBlbHNlIHsKKyAgICAgIHZhbHVlLmZpcnN0ID0gcGFydHNbaV0uc3Vic3RyKDAsIGVxdWFsc19wb3MpOworICAgICAgdmFsdWUuc2Vjb25kID0gcGFydHNbaV0uc3Vic3RyKGVxdWFsc19wb3MgKyAxKTsKKyAgICB9CisgICAgb3V0cHV0LT5wdXNoX2JhY2sodmFsdWUpOworICB9Cit9CisKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvZGVfZ2VuZXJhdG9yLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvZGVfZ2VuZXJhdG9yLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjk4OWYxNQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY29kZV9nZW5lcmF0b3IuaApAQCAtMCwwICsxLDE3NiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorLy8KKy8vIERlZmluZXMgdGhlIGFic3RyYWN0IGludGVyZmFjZSBpbXBsZW1lbnRlZCBieSBlYWNoIG9mIHRoZSBsYW5ndWFnZS1zcGVjaWZpYworLy8gY29kZSBnZW5lcmF0b3JzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DT0RFX0dFTkVSQVRPUl9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NPREVfR0VORVJBVE9SX0hfXworCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDx2ZWN0b3I+CisjaW5jbHVkZSA8dXRpbGl0eT4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCituYW1lc3BhY2UgaW8geyBjbGFzcyBaZXJvQ29weU91dHB1dFN0cmVhbTsgfQorY2xhc3MgRmlsZURlc2NyaXB0b3I7CisKK25hbWVzcGFjZSBjb21waWxlciB7CisKKy8vIERlZmluZWQgaW4gdGhpcyBmaWxlLgorY2xhc3MgQ29kZUdlbmVyYXRvcjsKK2NsYXNzIEdlbmVyYXRvckNvbnRleHQ7CisKKy8vIFRoZSBhYnN0cmFjdCBpbnRlcmZhY2UgdG8gYSBjbGFzcyB3aGljaCBnZW5lcmF0ZXMgY29kZSBpbXBsZW1lbnRpbmcgYQorLy8gcGFydGljdWxhciBwcm90byBmaWxlIGluIGEgcGFydGljdWxhciBsYW5ndWFnZS4gIEEgbnVtYmVyIG9mIHRoZXNlIG1heQorLy8gYmUgcmVnaXN0ZXJlZCB3aXRoIENvbW1hbmRMaW5lSW50ZXJmYWNlIHRvIHN1cHBvcnQgdmFyaW91cyBsYW5ndWFnZXMuCitjbGFzcyBMSUJQUk9UT0NfRVhQT1JUIENvZGVHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgaW5saW5lIENvZGVHZW5lcmF0b3IoKSB7fQorICB2aXJ0dWFsIH5Db2RlR2VuZXJhdG9yKCk7CisKKyAgLy8gR2VuZXJhdGVzIGNvZGUgZm9yIHRoZSBnaXZlbiBwcm90byBmaWxlLCBnZW5lcmF0aW5nIG9uZSBvciBtb3JlIGZpbGVzIGluCisgIC8vIHRoZSBnaXZlbiBvdXRwdXQgZGlyZWN0b3J5LgorICAvLworICAvLyBBIHBhcmFtZXRlciB0byBiZSBwYXNzZWQgdG8gdGhlIGdlbmVyYXRvciBjYW4gYmUgc3BlY2lmaWVkIG9uIHRoZQorICAvLyBjb21tYW5kIGxpbmUuICBUaGlzIGlzIGludGVuZGVkIHRvIGJlIHVzZWQgYnkgSmF2YSBhbmQgc2ltaWxhciBsYW5ndWFnZXMKKyAgLy8gdG8gc3BlY2lmeSB3aGljaCBzcGVjaWZpYyBjbGFzcyBmcm9tIHRoZSBwcm90byBmaWxlIGlzIHRvIGJlIGdlbmVyYXRlZCwKKyAgLy8gdGhvdWdoIGl0IGNvdWxkIGhhdmUgb3RoZXIgdXNlcyBhcyB3ZWxsLiAgSXQgaXMgZW1wdHkgaWYgbm8gcGFyYW1ldGVyIHdhcworICAvLyBnaXZlbi4KKyAgLy8KKyAgLy8gUmV0dXJucyB0cnVlIGlmIHN1Y2Nlc3NmdWwuICBPdGhlcndpc2UsIHNldHMgKmVycm9yIHRvIGEgZGVzY3JpcHRpb24gb2YKKyAgLy8gdGhlIHByb2JsZW0gKGUuZy4gImludmFsaWQgcGFyYW1ldGVyIikgYW5kIHJldHVybnMgZmFsc2UuCisgIHZpcnR1YWwgYm9vbCBHZW5lcmF0ZShjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgcGFyYW1ldGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgR2VuZXJhdG9yQ29udGV4dCogZ2VuZXJhdG9yX2NvbnRleHQsCisgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcqIGVycm9yKSBjb25zdCA9IDA7CisKKyAgLy8gR2VuZXJhdGVzIGNvZGUgZm9yIGFsbCBnaXZlbiBwcm90byBmaWxlcywgZ2VuZXJhdGluZyBvbmUgb3IgbW9yZSBmaWxlcyBpbgorICAvLyB0aGUgZ2l2ZW4gb3V0cHV0IGRpcmVjdG9yeS4KKyAgLy8KKyAgLy8gVGhpcyBtZXRob2Qgc2hvdWxkIGJlIGNhbGxlZCBpbnN0ZWFkIG9mIHxHZW5lcmF0ZSgpfCB3aGVuCisgIC8vIHxIYXNHZW5lcmF0ZUFsbCgpfCByZXR1cm5zIHx0cnVlfC4gSXQgaXMgdXNlZCB0byBlbXVsYXRlIGxlZ2FjeSBzZW1hbnRpY3MKKyAgLy8gd2hlbiBtb3JlIHRoYW4gb25lIGAucHJvdG9gIGZpbGUgaXMgc3BlY2lmaWVkIG9uIG9uZSBjb21waWxlciBpbnZvY2F0aW9uLgorICAvLworICAvLyBXQVJOSU5HOiBQbGVhc2UgZG8gbm90IHVzZSB1bmxlc3MgbGVnYWN5IHNlbWFudGljcyBmb3JjZSB0aGUgY29kZSBnZW5lcmF0b3IKKyAgLy8gdG8gcHJvZHVjZSBhIHNpbmdsZSBvdXRwdXQgZmlsZSBmb3IgYWxsIGlucHV0IGZpbGVzLCBvciBvdGhlcndpc2UgcmVxdWlyZQorICAvLyBhbiBleGFtaW5hdGlvbiBvZiBhbGwgaW5wdXQgZmlsZXMgZmlyc3QuIFRoZSBjYW5vbmljYWwgY29kZSBnZW5lcmF0b3IKKyAgLy8gZGVzaWduIHByb2R1Y2VzIG9uZSBvdXRwdXQgZmlsZSBwZXIgaW5wdXQgLnByb3RvIGZpbGUsIGFuZCB3ZSBkbyBub3Qgd2lzaAorICAvLyB0byBlbmNvdXJhZ2UgYWx0ZXJuYXRlIGRlc2lnbnMuCisgIC8vCisgIC8vIEEgcGFyYW1ldGVyIGlzIGdpdmVuIGFzIHBhc3NlZCBvbiB0aGUgY29tbWFuZCBsaW5lLCBhcyBpbiB8R2VuZXJhdGUoKXwKKyAgLy8gYWJvdmUuCisgIC8vCisgIC8vIFJldHVybnMgdHJ1ZSBpZiBzdWNjZXNzZnVsLiAgT3RoZXJ3aXNlLCBzZXRzICplcnJvciB0byBhIGRlc2NyaXB0aW9uIG9mCisgIC8vIHRoZSBwcm9ibGVtIChlLmcuICJpbnZhbGlkIHBhcmFtZXRlciIpIGFuZCByZXR1cm5zIGZhbHNlLgorICB2aXJ0dWFsIGJvb2wgR2VuZXJhdGVBbGwoY29uc3QgdmVjdG9yPGNvbnN0IEZpbGVEZXNjcmlwdG9yKj4mIGZpbGVzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBwYXJhbWV0ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBHZW5lcmF0b3JDb250ZXh0KiBnZW5lcmF0b3JfY29udGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyogZXJyb3IpIGNvbnN0IHsKKyAgICAqZXJyb3IgPSAiVW5pbXBsZW1lbnRlZCBHZW5lcmF0ZUFsbCgpIG1ldGhvZC4iOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgY29kZSBnZW5lcmF0b3IgZXhwZWN0cyB0byByZWNlaXZlIGFsbCBGaWxlRGVzY3JpcHRvcnMKKyAgLy8gYXQgb25jZSAodmlhIHxHZW5lcmF0ZUFsbCgpfCksIHJhdGhlciB0aGFuIG9uZSBhdCBhIHRpbWUgKHZpYQorICAvLyB8R2VuZXJhdGUoKXwpLiBUaGlzIGlzIHJlcXVpcmVkIHRvIGltcGxlbWVudCBsZWdhY3kgc2VtYW50aWNzLgorICB2aXJ0dWFsIGJvb2wgSGFzR2VuZXJhdGVBbGwoKSBjb25zdCB7IHJldHVybiBmYWxzZTsgfQorCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKENvZGVHZW5lcmF0b3IpOworfTsKKworLy8gQ29kZUdlbmVyYXRvcnMgZ2VuZXJhdGUgb25lIG9yIG1vcmUgZmlsZXMgaW4gYSBnaXZlbiBkaXJlY3RvcnkuICBUaGlzCisvLyBhYnN0cmFjdCBpbnRlcmZhY2UgcmVwcmVzZW50cyB0aGUgZGlyZWN0b3J5IHRvIHdoaWNoIHRoZSBDb2RlR2VuZXJhdG9yIGlzCisvLyB0byB3cml0ZSBhbmQgb3RoZXIgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGNvbnRleHQgaW4gd2hpY2ggdGhlIEdlbmVyYXRvcgorLy8gcnVucy4KK2NsYXNzIExJQlBST1RPQ19FWFBPUlQgR2VuZXJhdG9yQ29udGV4dCB7CisgcHVibGljOgorICBpbmxpbmUgR2VuZXJhdG9yQ29udGV4dCgpIHt9CisgIHZpcnR1YWwgfkdlbmVyYXRvckNvbnRleHQoKTsKKworICAvLyBPcGVucyB0aGUgZ2l2ZW4gZmlsZSwgdHJ1bmNhdGluZyBpdCBpZiBpdCBleGlzdHMsIGFuZCByZXR1cm5zIGEKKyAgLy8gWmVyb0NvcHlPdXRwdXRTdHJlYW0gdGhhdCB3cml0ZXMgdG8gdGhlIGZpbGUuICBUaGUgY2FsbGVyIHRha2VzIG93bmVyc2hpcAorICAvLyBvZiB0aGUgcmV0dXJuZWQgb2JqZWN0LiAgVGhpcyBtZXRob2QgbmV2ZXIgZmFpbHMgKGEgZHVtbXkgc3RyZWFtIHdpbGwgYmUKKyAgLy8gcmV0dXJuZWQgaW5zdGVhZCkuCisgIC8vCisgIC8vIFRoZSBmaWxlbmFtZSBnaXZlbiBzaG91bGQgYmUgcmVsYXRpdmUgdG8gdGhlIHJvb3Qgb2YgdGhlIHNvdXJjZSB0cmVlLgorICAvLyBFLmcuIHRoZSBDKysgZ2VuZXJhdG9yLCB3aGVuIGdlbmVyYXRpbmcgY29kZSBmb3IgImZvby9iYXIucHJvdG8iLCB3aWxsCisgIC8vIGdlbmVyYXRlIHRoZSBmaWxlcyAiZm9vL2Jhci5wYi5oIiBhbmQgImZvby9iYXIucGIuY2MiOyBub3RlIHRoYXQKKyAgLy8gImZvby8iIGlzIGluY2x1ZGVkIGluIHRoZXNlIGZpbGVuYW1lcy4gIFRoZSBmaWxlbmFtZSBpcyBub3QgYWxsb3dlZCB0bworICAvLyBjb250YWluICIuIiBvciAiLi4iIGNvbXBvbmVudHMuCisgIHZpcnR1YWwgaW86Olplcm9Db3B5T3V0cHV0U3RyZWFtKiBPcGVuKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUpID0gMDsKKworICAvLyBTaW1pbGFyIHRvIE9wZW4oKSBidXQgdGhlIG91dHB1dCB3aWxsIGJlIGFwcGVuZGVkIHRvIHRoZSBmaWxlIGlmIGV4aXN0cworICB2aXJ0dWFsIGlvOjpaZXJvQ29weU91dHB1dFN0cmVhbSogT3BlbkZvckFwcGVuZChjb25zdCBzdHJpbmcmIGZpbGVuYW1lKTsKKworICAvLyBDcmVhdGVzIGEgWmVyb0NvcHlPdXRwdXRTdHJlYW0gd2hpY2ggd2lsbCBpbnNlcnQgY29kZSBpbnRvIHRoZSBnaXZlbiBmaWxlCisgIC8vIGF0IHRoZSBnaXZlbiBpbnNlcnRpb24gcG9pbnQuICBTZWUgcGx1Z2luLnByb3RvIChwbHVnaW4ucGIuaCkgZm9yIG1vcmUKKyAgLy8gaW5mb3JtYXRpb24gb24gaW5zZXJ0aW9uIHBvaW50cy4gIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uCisgIC8vIGFzc2VydC1mYWlscyAtLSBpdCBleGlzdHMgb25seSBmb3IgYmFja3dhcmRzLWNvbXBhdGliaWxpdHkuCisgIC8vCisgIC8vIFdBUk5JTkc6ICBUaGlzIGZlYXR1cmUgaXMgY3VycmVudGx5IEVYUEVSSU1FTlRBTCBhbmQgaXMgc3ViamVjdCB0byBjaGFuZ2UuCisgIHZpcnR1YWwgaW86Olplcm9Db3B5T3V0cHV0U3RyZWFtKiBPcGVuRm9ySW5zZXJ0KAorICAgICAgY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSwgY29uc3Qgc3RyaW5nJiBpbnNlcnRpb25fcG9pbnQpOworCisgIC8vIFJldHVybnMgYSB2ZWN0b3Igb2YgRmlsZURlc2NyaXB0b3JzIGZvciBhbGwgdGhlIGZpbGVzIGJlaW5nIGNvbXBpbGVkCisgIC8vIGluIHRoaXMgcnVuLiAgVXNlZnVsIGZvciBsYW5ndWFnZXMsIHN1Y2ggYXMgR28sIHRoYXQgdHJlYXQgZmlsZXMKKyAgLy8gZGlmZmVyZW50bHkgd2hlbiBjb21waWxlZCBhcyBhIHNldCByYXRoZXIgdGhhbiBpbmRpdmlkdWFsbHkuCisgIHZpcnR1YWwgdm9pZCBMaXN0UGFyc2VkRmlsZXModmVjdG9yPGNvbnN0IEZpbGVEZXNjcmlwdG9yKj4qIG91dHB1dCk7CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoR2VuZXJhdG9yQ29udGV4dCk7Cit9OworCisvLyBUaGUgdHlwZSBHZW5lcmF0b3JDb250ZXh0IHdhcyBvbmNlIGNhbGxlZCBPdXRwdXREaXJlY3RvcnkuIFRoaXMgdHlwZWRlZgorLy8gcHJvdmlkZXMgYmFja3dhcmQgY29tcGF0aWJpbGl0eS4KK3R5cGVkZWYgR2VuZXJhdG9yQ29udGV4dCBPdXRwdXREaXJlY3Rvcnk7CisKKy8vIFNldmVyYWwgY29kZSBnZW5lcmF0b3JzIHRyZWF0IHRoZSBwYXJhbWV0ZXIgYXJndW1lbnQgYXMgaG9sZGluZyBhCisvLyBsaXN0IG9mIG9wdGlvbnMgc2VwYXJhdGVkIGJ5IGNvbW1hcy4gIFRoaXMgaGVscGVyIGZ1bmN0aW9uIHBhcnNlcworLy8gYSBzZXQgb2YgY29tbWEtZGVsaW1pdGVkIG5hbWUvdmFsdWUgcGFpcnM6IGUuZy4sCisvLyAgICJmb289YmFyLGJheixxdXg9Y29yZ2UiCisvLyBwYXJzZXMgdG8gdGhlIHBhaXJzOgorLy8gICAoImZvbyIsICJiYXIiKSwgKCJiYXoiLCAiIiksICgicXV4IiwgImNvcmdlIikKK2V4dGVybiB2b2lkIFBhcnNlR2VuZXJhdG9yUGFyYW1ldGVyKGNvbnN0IHN0cmluZyYsCisgICAgICAgICAgICB2ZWN0b3I8cGFpcjxzdHJpbmcsIHN0cmluZz4gPiopOworCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DT0RFX0dFTkVSQVRPUl9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY29tbWFuZF9saW5lX2ludGVyZmFjZS5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY29tbWFuZF9saW5lX2ludGVyZmFjZS5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zYTgxNmIwCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jb21tYW5kX2xpbmVfaW50ZXJmYWNlLmNjCkBAIC0wLDAgKzEsMTg3MiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvbW1hbmRfbGluZV9pbnRlcmZhY2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvcGxhdGZvcm1fbWFjcm9zLmg+CisKKyNpbmNsdWRlIDxzdGRpby5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CisjaW5jbHVkZSA8ZmNudGwuaD4KKyNpZmRlZiBfTVNDX1ZFUgorI2luY2x1ZGUgPGlvLmg+CisjaW5jbHVkZSA8ZGlyZWN0Lmg+CisjZWxzZQorI2luY2x1ZGUgPHVuaXN0ZC5oPgorI2VuZGlmCisjaW5jbHVkZSA8ZXJybm8uaD4KKyNpbmNsdWRlIDxpb3N0cmVhbT4KKyNpbmNsdWRlIDxjdHlwZS5oPgorCisjaWZkZWYgR09PR0xFX1BST1RPQlVGX0FSQ0hfU1BBUkMgCisjaW5jbHVkZSA8bGltaXRzLmg+IC8vRm9yIFBBVEhfTUFYCisjZW5kaWYKKworI2luY2x1ZGUgPG1lbW9yeT4KKyNpZm5kZWYgX1NIQVJFRF9QVFJfSAorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaGFyZWRfcHRyLmg+CisjZW5kaWYKKworI2lmZGVmIF9fQVBQTEVfXworI2luY2x1ZGUgPG1hY2gtby9keWxkLmg+CisjZW5kaWYKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RyaW5ncHJpbnRmLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2ltcG9ydGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvZGVfZ2VuZXJhdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BsdWdpbi5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9zdWJwcm9jZXNzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3ppcF93cml0ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXh0X2Zvcm1hdC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9keW5hbWljX21lc3NhZ2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2xvZ2dpbmcuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdWJzdGl0dXRlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL21hcF91dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0bF91dGlsLmg+CisKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKKworI2lmIGRlZmluZWQoX1dJTjMyKQorI2RlZmluZSBta2RpcihuYW1lLCBtb2RlKSBta2RpcihuYW1lKQorI2lmbmRlZiBXX09LCisjZGVmaW5lIFdfT0sgMDIgIC8vIG5vdCBkZWZpbmVkIGJ5IE1TVkMgZm9yIHdoYXRldmVyIHJlYXNvbgorI2VuZGlmCisjaWZuZGVmIEZfT0sKKyNkZWZpbmUgRl9PSyAwMCAgLy8gbm90IGRlZmluZWQgYnkgTVNWQyBmb3Igd2hhdGV2ZXIgcmVhc29uCisjZW5kaWYKKyNpZm5kZWYgU1RESU5fRklMRU5PCisjZGVmaW5lIFNURElOX0ZJTEVOTyAwCisjZW5kaWYKKyNpZm5kZWYgU1RET1VUX0ZJTEVOTworI2RlZmluZSBTVERPVVRfRklMRU5PIDEKKyNlbmRpZgorI2VuZGlmCisKKyNpZm5kZWYgT19CSU5BUlkKKyNpZmRlZiBfT19CSU5BUlkKKyNkZWZpbmUgT19CSU5BUlkgX09fQklOQVJZCisjZWxzZQorI2RlZmluZSBPX0JJTkFSWSAwICAgICAvLyBJZiB0aGlzIGlzbid0IGRlZmluZWQsIHRoZSBwbGF0Zm9ybSBkb2Vzbid0IG5lZWQgaXQuCisjZW5kaWYKKyNlbmRpZgorCituYW1lc3BhY2UgeworI2lmIGRlZmluZWQoX1dJTjMyKSAmJiAhZGVmaW5lZChfX0NZR1dJTl9fKQorc3RhdGljIGNvbnN0IGNoYXIqIGtQYXRoU2VwYXJhdG9yID0gIjsiOworI2Vsc2UKK3N0YXRpYyBjb25zdCBjaGFyKiBrUGF0aFNlcGFyYXRvciA9ICI6IjsKKyNlbmRpZgorCisvLyBSZXR1cm5zIHRydWUgaWYgdGhlIHRleHQgbG9va3MgbGlrZSBhIFdpbmRvd3Mtc3R5bGUgYWJzb2x1dGUgcGF0aCwgc3RhcnRpbmcKKy8vIHdpdGggYSBkcml2ZSBsZXR0ZXIuICBFeGFtcGxlOiAgIkM6XGZvbyIuICBUT0RPKGtlbnRvbik6ICBTaGFyZSB0aGlzIHdpdGgKKy8vIGNvcHkgaW4gaW1wb3J0ZXIuY2M/CitzdGF0aWMgYm9vbCBJc1dpbmRvd3NBYnNvbHV0ZVBhdGgoY29uc3Qgc3RyaW5nJiB0ZXh0KSB7CisjaWYgZGVmaW5lZChfV0lOMzIpIHx8IGRlZmluZWQoX19DWUdXSU5fXykKKyAgcmV0dXJuIHRleHQuc2l6ZSgpID49IDMgJiYgdGV4dFsxXSA9PSAnOicgJiYKKyAgICAgICAgIGlzYWxwaGEodGV4dFswXSkgJiYKKyAgICAgICAgICh0ZXh0WzJdID09ICcvJyB8fCB0ZXh0WzJdID09ICdcXCcpICYmCisgICAgICAgICB0ZXh0LmZpbmRfbGFzdF9vZignOicpID09IDE7CisjZWxzZQorICByZXR1cm4gZmFsc2U7CisjZW5kaWYKK30KKwordm9pZCBTZXRGZFRvVGV4dE1vZGUoaW50IGZkKSB7CisjaWZkZWYgX1dJTjMyCisgIGlmIChfc2V0bW9kZShmZCwgX09fVEVYVCkgPT0gLTEpIHsKKyAgICAvLyBUaGlzIHNob3VsZCBuZXZlciBoYXBwZW4sIEkgdGhpbmsuCisgICAgR09PR0xFX0xPRyhXQVJOSU5HKSA8PCAiX3NldG1vZGUoIiA8PCBmZCA8PCAiLCBfT19URVhUKTogIiA8PCBzdHJlcnJvcihlcnJubyk7CisgIH0KKyNlbmRpZgorICAvLyAoVGV4dCBhbmQgYmluYXJ5IGFyZSB0aGUgc2FtZSBvbiBub24tV2luZG93cyBwbGF0Zm9ybXMuKQorfQorCit2b2lkIFNldEZkVG9CaW5hcnlNb2RlKGludCBmZCkgeworI2lmZGVmIF9XSU4zMgorICBpZiAoX3NldG1vZGUoZmQsIF9PX0JJTkFSWSkgPT0gLTEpIHsKKyAgICAvLyBUaGlzIHNob3VsZCBuZXZlciBoYXBwZW4sIEkgdGhpbmsuCisgICAgR09PR0xFX0xPRyhXQVJOSU5HKSA8PCAiX3NldG1vZGUoIiA8PCBmZCA8PCAiLCBfT19CSU5BUlkpOiAiIDw8IHN0cmVycm9yKGVycm5vKTsKKyAgfQorI2VuZGlmCisgIC8vIChUZXh0IGFuZCBiaW5hcnkgYXJlIHRoZSBzYW1lIG9uIG5vbi1XaW5kb3dzIHBsYXRmb3Jtcy4pCit9CisKK3ZvaWQgQWRkVHJhaWxpbmdTbGFzaChzdHJpbmcqIHBhdGgpIHsKKyAgaWYgKCFwYXRoLT5lbXB0eSgpICYmIHBhdGgtPmF0KHBhdGgtPnNpemUoKSAtIDEpICE9ICcvJykgeworICAgIHBhdGgtPnB1c2hfYmFjaygnLycpOworICB9Cit9CisKK2Jvb2wgVmVyaWZ5RGlyZWN0b3J5RXhpc3RzKGNvbnN0IHN0cmluZyYgcGF0aCkgeworICBpZiAocGF0aC5lbXB0eSgpKSByZXR1cm4gdHJ1ZTsKKworICBpZiAoYWNjZXNzKHBhdGguY19zdHIoKSwgRl9PSykgPT0gLTEpIHsKKyAgICBzdGQ6OmNlcnIgPDwgcGF0aCA8PCAiOiAiIDw8IHN0cmVycm9yKGVycm5vKSA8PCBzdGQ6OmVuZGw7CisgICAgcmV0dXJuIGZhbHNlOworICB9IGVsc2UgeworICAgIHJldHVybiB0cnVlOworICB9Cit9CisKKy8vIFRyeSB0byBjcmVhdGUgdGhlIHBhcmVudCBkaXJlY3Rvcnkgb2YgdGhlIGdpdmVuIGZpbGUsIGNyZWF0aW5nIHRoZSBwYXJlbnQncworLy8gcGFyZW50IGlmIG5lY2Vzc2FyeSwgYW5kIHNvIG9uLiAgVGhlIGZ1bGwgZmlsZSBuYW1lIGlzIGFjdHVhbGx5CisvLyAocHJlZml4ICsgZmlsZW5hbWUpLCBidXQgd2UgYXNzdW1lIHxwcmVmaXh8IGFscmVhZHkgZXhpc3RzIGFuZCBvbmx5IGNyZWF0ZQorLy8gZGlyZWN0b3JpZXMgbGlzdGVkIGluIHxmaWxlbmFtZXwuCitib29sIFRyeUNyZWF0ZVBhcmVudERpcmVjdG9yeShjb25zdCBzdHJpbmcmIHByZWZpeCwgY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSkgeworICAvLyBSZWN1cnNpdmVseSBjcmVhdGUgcGFyZW50IGRpcmVjdG9yaWVzIHRvIHRoZSBvdXRwdXQgZmlsZS4KKyAgdmVjdG9yPHN0cmluZz4gcGFydHMgPSBTcGxpdChmaWxlbmFtZSwgIi8iLCB0cnVlKTsKKyAgc3RyaW5nIHBhdGhfc29fZmFyID0gcHJlZml4OworICBmb3IgKGludCBpID0gMDsgaSA8IHBhcnRzLnNpemUoKSAtIDE7IGkrKykgeworICAgIHBhdGhfc29fZmFyICs9IHBhcnRzW2ldOworICAgIGlmIChta2RpcihwYXRoX3NvX2Zhci5jX3N0cigpLCAwNzc3KSAhPSAwKSB7CisgICAgICBpZiAoZXJybm8gIT0gRUVYSVNUKSB7CisgICAgICAgIHN0ZDo6Y2VyciA8PCBmaWxlbmFtZSA8PCAiOiB3aGlsZSB0cnlpbmcgdG8gY3JlYXRlIGRpcmVjdG9yeSAiCisgICAgICAgICAgICAgICAgICA8PCBwYXRoX3NvX2ZhciA8PCAiOiAiIDw8IHN0cmVycm9yKGVycm5vKSA8PCBzdGQ6OmVuZGw7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICB9CisgICAgcGF0aF9zb19mYXIgKz0gJy8nOworICB9CisKKyAgcmV0dXJuIHRydWU7Cit9CisKKy8vIEdldCB0aGUgYWJzb2x1dGUgcGF0aCBvZiB0aGlzIHByb3RvYyBiaW5hcnkuCitib29sIEdldFByb3RvY0Fic29sdXRlUGF0aChzdHJpbmcqIHBhdGgpIHsKKyNpZmRlZiBfV0lOMzIKKyAgY2hhciBidWZmZXJbTUFYX1BBVEhdOworICBpbnQgbGVuID0gR2V0TW9kdWxlRmlsZU5hbWVBKE5VTEwsIGJ1ZmZlciwgTUFYX1BBVEgpOworI2VsaWYgX19BUFBMRV9fCisgIGNoYXIgYnVmZmVyW1BBVEhfTUFYXTsKKyAgaW50IGxlbiA9IDA7CisKKyAgY2hhciBkaXJ0eWJ1ZmZlcltQQVRIX01BWF07CisgIHVpbnQzMl90IHNpemUgPSBzaXplb2YoZGlydHlidWZmZXIpOworICBpZiAoX05TR2V0RXhlY3V0YWJsZVBhdGgoZGlydHlidWZmZXIsICZzaXplKSA9PSAwKSB7CisgICAgcmVhbHBhdGgoZGlydHlidWZmZXIsIGJ1ZmZlcik7CisgICAgbGVuID0gc3RybGVuKGJ1ZmZlcik7CisgIH0KKyNlbHNlCisgIGNoYXIgYnVmZmVyW1BBVEhfTUFYXTsKKyAgaW50IGxlbiA9IHJlYWRsaW5rKCIvcHJvYy9zZWxmL2V4ZSIsIGJ1ZmZlciwgUEFUSF9NQVgpOworI2VuZGlmCisgIGlmIChsZW4gPiAwKSB7CisgICAgcGF0aC0+YXNzaWduKGJ1ZmZlciwgbGVuKTsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KK30KKworLy8gV2hldGhlciBhIHBhdGggaXMgd2hlcmUgZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8gYW5kIG90aGVyIHdlbGwta25vd24KKy8vIHR5cGUgcHJvdG9zIGFyZSBpbnN0YWxsZWQuCitib29sIElzSW5zdGFsbGVkUHJvdG9QYXRoKGNvbnN0IHN0cmluZyYgcGF0aCkgeworICAvLyBDaGVja2luZyB0aGUgZGVzY3JpcHRvci5wcm90byBmaWxlIHNob3VsZCBiZSBnb29kIGVub3VnaC4KKyAgc3RyaW5nIGZpbGVfcGF0aCA9IHBhdGggKyAiL2dvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvIjsKKyAgcmV0dXJuIGFjY2VzcyhmaWxlX3BhdGguY19zdHIoKSwgRl9PSykgIT0gLTE7Cit9CisKKy8vIEFkZCB0aGUgcGF0aHMgd2hlcmUgZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXRvci5wcm90byBhbmQgb3RoZXIgd2VsbC1rbm93bgorLy8gdHlwZSBwcm90b3MgYXJlIGluc3RhbGxlZC4KK3ZvaWQgQWRkRGVmYXVsdFByb3RvUGF0aHModmVjdG9yPHBhaXI8c3RyaW5nLCBzdHJpbmc+ID4qIHBhdGhzKSB7CisgIC8vIFRPRE8oeGlhb2ZlbmcpOiBUaGUgY29kZSBjdXJyZW50bHkgb25seSBjaGVja3MgcmVsYXRpdmUgcGF0aHMgb2Ygd2hlcmUKKyAgLy8gdGhlIHByb3RvYyBiaW5hcnkgaXMgaW5zdGFsbGVkLiBXZSBwcm9iYWJseSBzaG91bGQgbWFrZSBpdCBoYW5kbGUgbW9yZQorICAvLyBjYXNlcyB0aGFuIHRoYXQuCisgIHN0cmluZyBwYXRoOworICBpZiAoIUdldFByb3RvY0Fic29sdXRlUGF0aCgmcGF0aCkpIHsKKyAgICByZXR1cm47CisgIH0KKyAgLy8gU3RyaXAgdGhlIGJpbmFyeSBuYW1lLgorICBzaXplX3QgcG9zID0gcGF0aC5maW5kX2xhc3Rfb2YoIi9cXCIpOworICBpZiAocG9zID09IHN0cmluZzo6bnBvcyB8fCBwb3MgPT0gMCkgeworICAgIHJldHVybjsKKyAgfQorICBwYXRoID0gcGF0aC5zdWJzdHIoMCwgcG9zKTsKKyAgLy8gQ2hlY2sgdGhlIGJpbmFyeSdzIGRpcmVjdG9yeS4KKyAgaWYgKElzSW5zdGFsbGVkUHJvdG9QYXRoKHBhdGgpKSB7CisgICAgcGF0aHMtPnB1c2hfYmFjayhwYWlyPHN0cmluZywgc3RyaW5nPigiIiwgcGF0aCkpOworICAgIHJldHVybjsKKyAgfQorICAvLyBDaGVjayBpZiB0aGVyZSBpcyBhbiBpbmNsdWRlIHN1YmRpcmVjdG9yeS4KKyAgaWYgKElzSW5zdGFsbGVkUHJvdG9QYXRoKHBhdGggKyAiL2luY2x1ZGUiKSkgeworICAgIHBhdGhzLT5wdXNoX2JhY2socGFpcjxzdHJpbmcsIHN0cmluZz4oIiIsIHBhdGggKyAiL2luY2x1ZGUiKSk7CisgICAgcmV0dXJuOworICB9CisgIC8vIENoZWNrIGlmIHRoZSB1cHBlciBsZXZlbCBkaXJlY3RvcnkgaGFzIGFuICJpbmNsdWRlIiBzdWJkaXJlY3RvcnkuCisgIHBvcyA9IHBhdGguZmluZF9sYXN0X29mKCIvXFwiKTsKKyAgaWYgKHBvcyA9PSBzdHJpbmc6Om5wb3MgfHwgcG9zID09IDApIHsKKyAgICByZXR1cm47CisgIH0KKyAgcGF0aCA9IHBhdGguc3Vic3RyKDAsIHBvcyk7CisgIGlmIChJc0luc3RhbGxlZFByb3RvUGF0aChwYXRoICsgIi9pbmNsdWRlIikpIHsKKyAgICBwYXRocy0+cHVzaF9iYWNrKHBhaXI8c3RyaW5nLCBzdHJpbmc+KCIiLCBwYXRoICsgIi9pbmNsdWRlIikpOworICAgIHJldHVybjsKKyAgfQorfQorfSAgLy8gbmFtZXNwYWNlCisKKy8vIEEgTXVsdGlGaWxlRXJyb3JDb2xsZWN0b3IgdGhhdCBwcmludHMgZXJyb3JzIHRvIHN0ZGVyci4KK2NsYXNzIENvbW1hbmRMaW5lSW50ZXJmYWNlOjpFcnJvclByaW50ZXIgOiBwdWJsaWMgTXVsdGlGaWxlRXJyb3JDb2xsZWN0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIGlvOjpFcnJvckNvbGxlY3RvciB7CisgcHVibGljOgorICBFcnJvclByaW50ZXIoRXJyb3JGb3JtYXQgZm9ybWF0LCBEaXNrU291cmNlVHJlZSAqdHJlZSA9IE5VTEwpCisgICAgOiBmb3JtYXRfKGZvcm1hdCksIHRyZWVfKHRyZWUpIHt9CisgIH5FcnJvclByaW50ZXIoKSB7fQorCisgIC8vIGltcGxlbWVudHMgTXVsdGlGaWxlRXJyb3JDb2xsZWN0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIHZvaWQgQWRkRXJyb3IoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSwgaW50IGxpbmUsIGludCBjb2x1bW4sCisgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBtZXNzYWdlKSB7CisgICAgQWRkRXJyb3JPcldhcm5pbmcoZmlsZW5hbWUsIGxpbmUsIGNvbHVtbiwgbWVzc2FnZSwgImVycm9yIiwgc3RkOjpjZXJyKTsKKyAgfQorCisgIHZvaWQgQWRkV2FybmluZyhjb25zdCBzdHJpbmcmIGZpbGVuYW1lLCBpbnQgbGluZSwgaW50IGNvbHVtbiwKKyAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgbWVzc2FnZSkgeworICAgIEFkZEVycm9yT3JXYXJuaW5nKGZpbGVuYW1lLCBsaW5lLCBjb2x1bW4sIG1lc3NhZ2UsICJ3YXJuaW5nIiwgc3RkOjpjbG9nKTsKKyAgfQorCisgIC8vIGltcGxlbWVudHMgaW86OkVycm9yQ29sbGVjdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIHZvaWQgQWRkRXJyb3IoaW50IGxpbmUsIGludCBjb2x1bW4sIGNvbnN0IHN0cmluZyYgbWVzc2FnZSkgeworICAgIEFkZEVycm9yKCJpbnB1dCIsIGxpbmUsIGNvbHVtbiwgbWVzc2FnZSk7CisgIH0KKworICB2b2lkIEFkZFdhcm5pbmcoaW50IGxpbmUsIGludCBjb2x1bW4sIGNvbnN0IHN0cmluZyYgbWVzc2FnZSkgeworICAgIEFkZEVycm9yT3JXYXJuaW5nKCJpbnB1dCIsIGxpbmUsIGNvbHVtbiwgbWVzc2FnZSwgIndhcm5pbmciLCBzdGQ6OmNsb2cpOworICB9CisKKyBwcml2YXRlOgorICB2b2lkIEFkZEVycm9yT3JXYXJuaW5nKAorICAgICAgY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSwgaW50IGxpbmUsIGludCBjb2x1bW4sCisgICAgICBjb25zdCBzdHJpbmcmIG1lc3NhZ2UsIGNvbnN0IHN0cmluZyYgdHlwZSwgb3N0cmVhbSYgb3V0KSB7CisgICAgLy8gUHJpbnQgZnVsbCBwYXRoIHdoZW4gcnVubmluZyB1bmRlciBNU1ZTCisgICAgc3RyaW5nIGRmaWxlOworICAgIGlmIChmb3JtYXRfID09IENvbW1hbmRMaW5lSW50ZXJmYWNlOjpFUlJPUl9GT1JNQVRfTVNWUyAmJgorICAgICAgICB0cmVlXyAhPSBOVUxMICYmCisgICAgICAgIHRyZWVfLT5WaXJ0dWFsRmlsZVRvRGlza0ZpbGUoZmlsZW5hbWUsICZkZmlsZSkpIHsKKyAgICAgIG91dCA8PCBkZmlsZTsKKyAgICB9IGVsc2UgeworICAgICAgb3V0IDw8IGZpbGVuYW1lOworICAgIH0KKworICAgIC8vIFVzZXJzIHR5cGljYWxseSBleHBlY3QgMS1iYXNlZCBsaW5lL2NvbHVtbiBudW1iZXJzLCBzbyB3ZSBhZGQgMQorICAgIC8vIHRvIGVhY2ggaGVyZS4KKyAgICBpZiAobGluZSAhPSAtMSkgeworICAgICAgLy8gQWxsb3cgZm9yIGJvdGggR0NDLSBhbmQgVmlzdWFsLVN0dWRpby1jb21wYXRpYmxlIG91dHB1dC4KKyAgICAgIHN3aXRjaCAoZm9ybWF0XykgeworICAgICAgICBjYXNlIENvbW1hbmRMaW5lSW50ZXJmYWNlOjpFUlJPUl9GT1JNQVRfR0NDOgorICAgICAgICAgIG91dCA8PCAiOiIgPDwgKGxpbmUgKyAxKSA8PCAiOiIgPDwgKGNvbHVtbiArIDEpOworICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIENvbW1hbmRMaW5lSW50ZXJmYWNlOjpFUlJPUl9GT1JNQVRfTVNWUzoKKyAgICAgICAgICBvdXQgPDwgIigiIDw8IChsaW5lICsgMSkgPDwgIikgOiAiCisgICAgICAgICAgICAgIDw8IHR5cGUgPDwgIiBpbiBjb2x1bW49IiA8PCAoY29sdW1uICsgMSk7CisgICAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorCisgICAgaWYgKHR5cGUgPT0gIndhcm5pbmciKSB7CisgICAgICBvdXQgPDwgIjogd2FybmluZzogIiA8PCBtZXNzYWdlIDw8IHN0ZDo6ZW5kbDsKKyAgICB9IGVsc2UgeworICAgICAgb3V0IDw8ICI6ICIgPDwgbWVzc2FnZSA8PCBzdGQ6OmVuZGw7CisgICAgfQorICB9CisKKyAgY29uc3QgRXJyb3JGb3JtYXQgZm9ybWF0XzsKKyAgRGlza1NvdXJjZVRyZWUgKnRyZWVfOworfTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBBIEdlbmVyYXRvckNvbnRleHQgaW1wbGVtZW50YXRpb24gdGhhdCBidWZmZXJzIGZpbGVzIGluIG1lbW9yeSwgdGhlbiBkdW1wcworLy8gdGhlbSBhbGwgdG8gZGlzayBvbiBkZW1hbmQuCitjbGFzcyBDb21tYW5kTGluZUludGVyZmFjZTo6R2VuZXJhdG9yQ29udGV4dEltcGwgOiBwdWJsaWMgR2VuZXJhdG9yQ29udGV4dCB7CisgcHVibGljOgorICBHZW5lcmF0b3JDb250ZXh0SW1wbChjb25zdCB2ZWN0b3I8Y29uc3QgRmlsZURlc2NyaXB0b3IqPiYgcGFyc2VkX2ZpbGVzKTsKKyAgfkdlbmVyYXRvckNvbnRleHRJbXBsKCk7CisKKyAgLy8gV3JpdGUgYWxsIGZpbGVzIGluIHRoZSBkaXJlY3RvcnkgdG8gZGlzayBhdCB0aGUgZ2l2ZW4gb3V0cHV0IGxvY2F0aW9uLAorICAvLyB3aGljaCBtdXN0IGVuZCBpbiBhICcvJy4KKyAgYm9vbCBXcml0ZUFsbFRvRGlzayhjb25zdCBzdHJpbmcmIHByZWZpeCk7CisKKyAgLy8gV3JpdGUgdGhlIGNvbnRlbnRzIG9mIHRoaXMgZGlyZWN0b3J5IHRvIGEgWklQLWZvcm1hdCBhcmNoaXZlIHdpdGggdGhlCisgIC8vIGdpdmVuIG5hbWUuCisgIGJvb2wgV3JpdGVBbGxUb1ppcChjb25zdCBzdHJpbmcmIGZpbGVuYW1lKTsKKworICAvLyBBZGQgYSBib2lsZXJwbGF0ZSBNRVRBLUlORi9NQU5JRkVTVC5NRiBmaWxlIGFzIHJlcXVpcmVkIGJ5IHRoZSBKYXZhIEpBUgorICAvLyBmb3JtYXQsIHVubGVzcyBvbmUgaGFzIGFscmVhZHkgYmVlbiB3cml0dGVuLgorICB2b2lkIEFkZEphck1hbmlmZXN0KCk7CisKKyAgLy8gR2V0IG5hbWUgb2YgYWxsIG91dHB1dCBmaWxlcy4KKyAgdm9pZCBHZXRPdXRwdXRGaWxlbmFtZXModmVjdG9yPHN0cmluZz4qIG91dHB1dF9maWxlbmFtZXMpOworCisgIC8vIGltcGxlbWVudHMgR2VuZXJhdG9yQ29udGV4dCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICBpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0qIE9wZW4oY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSk7CisgIGlvOjpaZXJvQ29weU91dHB1dFN0cmVhbSogT3BlbkZvckFwcGVuZChjb25zdCBzdHJpbmcmIGZpbGVuYW1lKTsKKyAgaW86Olplcm9Db3B5T3V0cHV0U3RyZWFtKiBPcGVuRm9ySW5zZXJ0KAorICAgICAgY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSwgY29uc3Qgc3RyaW5nJiBpbnNlcnRpb25fcG9pbnQpOworICB2b2lkIExpc3RQYXJzZWRGaWxlcyh2ZWN0b3I8Y29uc3QgRmlsZURlc2NyaXB0b3IqPiogb3V0cHV0KSB7CisgICAgKm91dHB1dCA9IHBhcnNlZF9maWxlc187CisgIH0KKworIHByaXZhdGU6CisgIGZyaWVuZCBjbGFzcyBNZW1vcnlPdXRwdXRTdHJlYW07CisKKyAgLy8gbWFwIGluc3RlYWQgb2YgaGFzaF9tYXAgc28gdGhhdCBmaWxlcyBhcmUgd3JpdHRlbiBpbiBvcmRlciAoZ29vZCB3aGVuCisgIC8vIHdyaXRpbmcgemlwcykuCisgIG1hcDxzdHJpbmcsIHN0cmluZyo+IGZpbGVzXzsKKyAgY29uc3QgdmVjdG9yPGNvbnN0IEZpbGVEZXNjcmlwdG9yKj4mIHBhcnNlZF9maWxlc187CisgIGJvb2wgaGFkX2Vycm9yXzsKK307CisKK2NsYXNzIENvbW1hbmRMaW5lSW50ZXJmYWNlOjpNZW1vcnlPdXRwdXRTdHJlYW0KKyAgICA6IHB1YmxpYyBpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0geworIHB1YmxpYzoKKyAgTWVtb3J5T3V0cHV0U3RyZWFtKEdlbmVyYXRvckNvbnRleHRJbXBsKiBkaXJlY3RvcnksIGNvbnN0IHN0cmluZyYgZmlsZW5hbWUsCisgICAgICAgICAgICAgICAgICAgICBib29sIGFwcGVuZF9tb2RlKTsKKyAgTWVtb3J5T3V0cHV0U3RyZWFtKEdlbmVyYXRvckNvbnRleHRJbXBsKiBkaXJlY3RvcnksIGNvbnN0IHN0cmluZyYgZmlsZW5hbWUsCisgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIGluc2VydGlvbl9wb2ludCk7CisgIHZpcnR1YWwgfk1lbW9yeU91dHB1dFN0cmVhbSgpOworCisgIC8vIGltcGxlbWVudHMgWmVyb0NvcHlPdXRwdXRTdHJlYW0gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIHZpcnR1YWwgYm9vbCBOZXh0KHZvaWQqKiBkYXRhLCBpbnQqIHNpemUpIHsgcmV0dXJuIGlubmVyXy0+TmV4dChkYXRhLCBzaXplKTsgfQorICB2aXJ0dWFsIHZvaWQgQmFja1VwKGludCBjb3VudCkgICAgICAgICAgICB7ICAgICAgICBpbm5lcl8tPkJhY2tVcChjb3VudCk7ICAgIH0KKyAgdmlydHVhbCBpbnQ2NCBCeXRlQ291bnQoKSBjb25zdCAgICAgICAgICAgeyByZXR1cm4gaW5uZXJfLT5CeXRlQ291bnQoKTsgICAgICB9CisKKyBwcml2YXRlOgorICAvLyBXaGVyZSB0byBpbnNlcnQgdGhlIHN0cmluZyB3aGVuIGl0J3MgZG9uZS4KKyAgR2VuZXJhdG9yQ29udGV4dEltcGwqIGRpcmVjdG9yeV87CisgIHN0cmluZyBmaWxlbmFtZV87CisgIHN0cmluZyBpbnNlcnRpb25fcG9pbnRfOworCisgIC8vIFRoZSBzdHJpbmcgd2UncmUgYnVpbGRpbmcuCisgIHN0cmluZyBkYXRhXzsKKworICAvLyBXaGV0aGVyIHdlIHNob3VsZCBhcHBlbmQgdGhlIG91dHB1dCBzdHJlYW0gdG8gdGhlIGV4aXN0aW5nIGZpbGUuCisgIGJvb2wgYXBwZW5kX21vZGVfOworCisgIC8vIFN0cmluZ091dHB1dFN0cmVhbSB3cml0aW5nIHRvIGRhdGFfLgorICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPGlvOjpTdHJpbmdPdXRwdXRTdHJlYW0+IGlubmVyXzsKK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworQ29tbWFuZExpbmVJbnRlcmZhY2U6OkdlbmVyYXRvckNvbnRleHRJbXBsOjpHZW5lcmF0b3JDb250ZXh0SW1wbCgKKyAgICBjb25zdCB2ZWN0b3I8Y29uc3QgRmlsZURlc2NyaXB0b3IqPiYgcGFyc2VkX2ZpbGVzKQorICAgIDogcGFyc2VkX2ZpbGVzXyhwYXJzZWRfZmlsZXMpLAorICAgICAgaGFkX2Vycm9yXyhmYWxzZSkgeworfQorCitDb21tYW5kTGluZUludGVyZmFjZTo6R2VuZXJhdG9yQ29udGV4dEltcGw6On5HZW5lcmF0b3JDb250ZXh0SW1wbCgpIHsKKyAgU1RMRGVsZXRlVmFsdWVzKCZmaWxlc18pOworfQorCitib29sIENvbW1hbmRMaW5lSW50ZXJmYWNlOjpHZW5lcmF0b3JDb250ZXh0SW1wbDo6V3JpdGVBbGxUb0Rpc2soCisgICAgY29uc3Qgc3RyaW5nJiBwcmVmaXgpIHsKKyAgaWYgKGhhZF9lcnJvcl8pIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBpZiAoIVZlcmlmeURpcmVjdG9yeUV4aXN0cyhwcmVmaXgpKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgZm9yIChtYXA8c3RyaW5nLCBzdHJpbmcqPjo6Y29uc3RfaXRlcmF0b3IgaXRlciA9IGZpbGVzXy5iZWdpbigpOworICAgICAgIGl0ZXIgIT0gZmlsZXNfLmVuZCgpOyArK2l0ZXIpIHsKKyAgICBjb25zdCBzdHJpbmcmIHJlbGF0aXZlX2ZpbGVuYW1lID0gaXRlci0+Zmlyc3Q7CisgICAgY29uc3QgY2hhciogZGF0YSA9IGl0ZXItPnNlY29uZC0+ZGF0YSgpOworICAgIGludCBzaXplID0gaXRlci0+c2Vjb25kLT5zaXplKCk7CisKKyAgICBpZiAoIVRyeUNyZWF0ZVBhcmVudERpcmVjdG9yeShwcmVmaXgsIHJlbGF0aXZlX2ZpbGVuYW1lKSkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBzdHJpbmcgZmlsZW5hbWUgPSBwcmVmaXggKyByZWxhdGl2ZV9maWxlbmFtZTsKKworICAgIC8vIENyZWF0ZSB0aGUgb3V0cHV0IGZpbGUuCisgICAgaW50IGZpbGVfZGVzY3JpcHRvcjsKKyAgICBkbyB7CisgICAgICBmaWxlX2Rlc2NyaXB0b3IgPQorICAgICAgICBvcGVuKGZpbGVuYW1lLmNfc3RyKCksIE9fV1JPTkxZIHwgT19DUkVBVCB8IE9fVFJVTkMgfCBPX0JJTkFSWSwgMDY2Nik7CisgICAgfSB3aGlsZSAoZmlsZV9kZXNjcmlwdG9yIDwgMCAmJiBlcnJubyA9PSBFSU5UUik7CisKKyAgICBpZiAoZmlsZV9kZXNjcmlwdG9yIDwgMCkgeworICAgICAgaW50IGVycm9yID0gZXJybm87CisgICAgICBzdGQ6OmNlcnIgPDwgZmlsZW5hbWUgPDwgIjogIiA8PCBzdHJlcnJvcihlcnJvcik7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLy8gV3JpdGUgdGhlIGZpbGUuCisgICAgd2hpbGUgKHNpemUgPiAwKSB7CisgICAgICBpbnQgd3JpdGVfcmVzdWx0OworICAgICAgZG8geworICAgICAgICB3cml0ZV9yZXN1bHQgPSB3cml0ZShmaWxlX2Rlc2NyaXB0b3IsIGRhdGEsIHNpemUpOworICAgICAgfSB3aGlsZSAod3JpdGVfcmVzdWx0IDwgMCAmJiBlcnJubyA9PSBFSU5UUik7CisKKyAgICAgIGlmICh3cml0ZV9yZXN1bHQgPD0gMCkgeworICAgICAgICAvLyBXcml0ZSBlcnJvci4KKworICAgICAgICAvLyBGSVhNRShrZW50b24pOiAgQWNjb3JkaW5nIHRvIHRoZSBtYW4gcGFnZSwgaWYgd3JpdGUoKSByZXR1cm5zIHplcm8sCisgICAgICAgIC8vICAgdGhlcmUgd2FzIG5vIGVycm9yOyB3cml0ZSgpIHNpbXBseSBkaWQgbm90IHdyaXRlIGFueXRoaW5nLiAgSXQncworICAgICAgICAvLyAgIHVuY2xlYXIgdW5kZXIgd2hhdCBjaXJjdW1zdGFuY2VzIHRoaXMgbWlnaHQgaGFwcGVuLCBidXQgcHJlc3VtYWJseQorICAgICAgICAvLyAgIGVycm5vIHdvbid0IGJlIHNldCBpbiB0aGlzIGNhc2UuICBJIGFtIGNvbmZ1c2VkIGFzIHRvIGhvdyBzdWNoIGFuCisgICAgICAgIC8vICAgZXZlbnQgc2hvdWxkIGJlIGhhbmRsZWQuICBGb3Igbm93IEknbSB0cmVhdGluZyBpdCBhcyBhbiBlcnJvciwKKyAgICAgICAgLy8gICBzaW5jZSByZXRyeWluZyBzZWVtcyBsaWtlIGl0IGNvdWxkIGxlYWQgdG8gYW4gaW5maW5pdGUgbG9vcC4gIEkKKyAgICAgICAgLy8gICBzdXNwZWN0IHRoaXMgbmV2ZXIgYWN0dWFsbHkgaGFwcGVucyBhbnl3YXkuCisKKyAgICAgICAgaWYgKHdyaXRlX3Jlc3VsdCA8IDApIHsKKyAgICAgICAgICBpbnQgZXJyb3IgPSBlcnJubzsKKyAgICAgICAgICBzdGQ6OmNlcnIgPDwgZmlsZW5hbWUgPDwgIjogd3JpdGU6ICIgPDwgc3RyZXJyb3IoZXJyb3IpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHN0ZDo6Y2VyciA8PCBmaWxlbmFtZSA8PCAiOiB3cml0ZSgpIHJldHVybmVkIHplcm8/IiA8PCBzdGQ6OmVuZGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICBkYXRhICs9IHdyaXRlX3Jlc3VsdDsKKyAgICAgIHNpemUgLT0gd3JpdGVfcmVzdWx0OworICAgIH0KKworICAgIGlmIChjbG9zZShmaWxlX2Rlc2NyaXB0b3IpICE9IDApIHsKKyAgICAgIGludCBlcnJvciA9IGVycm5vOworICAgICAgc3RkOjpjZXJyIDw8IGZpbGVuYW1lIDw8ICI6IGNsb3NlOiAiIDw8IHN0cmVycm9yKGVycm9yKTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0KKworICByZXR1cm4gdHJ1ZTsKK30KKworYm9vbCBDb21tYW5kTGluZUludGVyZmFjZTo6R2VuZXJhdG9yQ29udGV4dEltcGw6OldyaXRlQWxsVG9aaXAoCisgICAgY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSkgeworICBpZiAoaGFkX2Vycm9yXykgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vIENyZWF0ZSB0aGUgb3V0cHV0IGZpbGUuCisgIGludCBmaWxlX2Rlc2NyaXB0b3I7CisgIGRvIHsKKyAgICBmaWxlX2Rlc2NyaXB0b3IgPQorICAgICAgb3BlbihmaWxlbmFtZS5jX3N0cigpLCBPX1dST05MWSB8IE9fQ1JFQVQgfCBPX1RSVU5DIHwgT19CSU5BUlksIDA2NjYpOworICB9IHdoaWxlIChmaWxlX2Rlc2NyaXB0b3IgPCAwICYmIGVycm5vID09IEVJTlRSKTsKKworICBpZiAoZmlsZV9kZXNjcmlwdG9yIDwgMCkgeworICAgIGludCBlcnJvciA9IGVycm5vOworICAgIHN0ZDo6Y2VyciA8PCBmaWxlbmFtZSA8PCAiOiAiIDw8IHN0cmVycm9yKGVycm9yKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLyBDcmVhdGUgdGhlIFppcFdyaXRlcgorICBpbzo6RmlsZU91dHB1dFN0cmVhbSBzdHJlYW0oZmlsZV9kZXNjcmlwdG9yKTsKKyAgWmlwV3JpdGVyIHppcF93cml0ZXIoJnN0cmVhbSk7CisKKyAgZm9yIChtYXA8c3RyaW5nLCBzdHJpbmcqPjo6Y29uc3RfaXRlcmF0b3IgaXRlciA9IGZpbGVzXy5iZWdpbigpOworICAgICAgIGl0ZXIgIT0gZmlsZXNfLmVuZCgpOyArK2l0ZXIpIHsKKyAgICB6aXBfd3JpdGVyLldyaXRlKGl0ZXItPmZpcnN0LCAqaXRlci0+c2Vjb25kKTsKKyAgfQorCisgIHppcF93cml0ZXIuV3JpdGVEaXJlY3RvcnkoKTsKKworICBpZiAoc3RyZWFtLkdldEVycm5vKCkgIT0gMCkgeworICAgIHN0ZDo6Y2VyciA8PCBmaWxlbmFtZSA8PCAiOiAiIDw8IHN0cmVycm9yKHN0cmVhbS5HZXRFcnJubygpKSA8PCBzdGQ6OmVuZGw7CisgIH0KKworICBpZiAoIXN0cmVhbS5DbG9zZSgpKSB7CisgICAgc3RkOjpjZXJyIDw8IGZpbGVuYW1lIDw8ICI6ICIgPDwgc3RyZXJyb3Ioc3RyZWFtLkdldEVycm5vKCkpIDw8IHN0ZDo6ZW5kbDsKKyAgfQorCisgIHJldHVybiB0cnVlOworfQorCit2b2lkIENvbW1hbmRMaW5lSW50ZXJmYWNlOjpHZW5lcmF0b3JDb250ZXh0SW1wbDo6QWRkSmFyTWFuaWZlc3QoKSB7CisgIHN0cmluZyoqIG1hcF9zbG90ID0gJmZpbGVzX1siTUVUQS1JTkYvTUFOSUZFU1QuTUYiXTsKKyAgaWYgKCptYXBfc2xvdCA9PSBOVUxMKSB7CisgICAgKm1hcF9zbG90ID0gbmV3IHN0cmluZygKKyAgICAgICAgIk1hbmlmZXN0LVZlcnNpb246IDEuMFxuIgorICAgICAgICAiQ3JlYXRlZC1CeTogMS42LjAgKHByb3RvYylcbiIKKyAgICAgICAgIlxuIik7CisgIH0KK30KKwordm9pZCBDb21tYW5kTGluZUludGVyZmFjZTo6R2VuZXJhdG9yQ29udGV4dEltcGw6OkdldE91dHB1dEZpbGVuYW1lcygKKyAgICB2ZWN0b3I8c3RyaW5nPiogb3V0cHV0X2ZpbGVuYW1lcykgeworICBmb3IgKG1hcDxzdHJpbmcsIHN0cmluZyo+OjppdGVyYXRvciBpdGVyID0gZmlsZXNfLmJlZ2luKCk7CisgICAgICAgaXRlciAhPSBmaWxlc18uZW5kKCk7ICsraXRlcikgeworICAgIG91dHB1dF9maWxlbmFtZXMtPnB1c2hfYmFjayhpdGVyLT5maXJzdCk7CisgIH0KK30KKworaW86Olplcm9Db3B5T3V0cHV0U3RyZWFtKiBDb21tYW5kTGluZUludGVyZmFjZTo6R2VuZXJhdG9yQ29udGV4dEltcGw6Ok9wZW4oCisgICAgY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSkgeworICByZXR1cm4gbmV3IE1lbW9yeU91dHB1dFN0cmVhbSh0aGlzLCBmaWxlbmFtZSwgZmFsc2UpOworfQorCitpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0qCitDb21tYW5kTGluZUludGVyZmFjZTo6R2VuZXJhdG9yQ29udGV4dEltcGw6Ok9wZW5Gb3JBcHBlbmQoCisgICAgY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSkgeworICByZXR1cm4gbmV3IE1lbW9yeU91dHB1dFN0cmVhbSh0aGlzLCBmaWxlbmFtZSwgdHJ1ZSk7Cit9CisKK2lvOjpaZXJvQ29weU91dHB1dFN0cmVhbSoKK0NvbW1hbmRMaW5lSW50ZXJmYWNlOjpHZW5lcmF0b3JDb250ZXh0SW1wbDo6T3BlbkZvckluc2VydCgKKyAgICBjb25zdCBzdHJpbmcmIGZpbGVuYW1lLCBjb25zdCBzdHJpbmcmIGluc2VydGlvbl9wb2ludCkgeworICByZXR1cm4gbmV3IE1lbW9yeU91dHB1dFN0cmVhbSh0aGlzLCBmaWxlbmFtZSwgaW5zZXJ0aW9uX3BvaW50KTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitDb21tYW5kTGluZUludGVyZmFjZTo6TWVtb3J5T3V0cHV0U3RyZWFtOjpNZW1vcnlPdXRwdXRTdHJlYW0oCisgICAgR2VuZXJhdG9yQ29udGV4dEltcGwqIGRpcmVjdG9yeSwgY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSwgYm9vbCBhcHBlbmRfbW9kZSkKKyAgICA6IGRpcmVjdG9yeV8oZGlyZWN0b3J5KSwKKyAgICAgIGZpbGVuYW1lXyhmaWxlbmFtZSksCisgICAgICBhcHBlbmRfbW9kZV8oYXBwZW5kX21vZGUpLAorICAgICAgaW5uZXJfKG5ldyBpbzo6U3RyaW5nT3V0cHV0U3RyZWFtKCZkYXRhXykpIHsKK30KKworQ29tbWFuZExpbmVJbnRlcmZhY2U6Ok1lbW9yeU91dHB1dFN0cmVhbTo6TWVtb3J5T3V0cHV0U3RyZWFtKAorICAgIEdlbmVyYXRvckNvbnRleHRJbXBsKiBkaXJlY3RvcnksIGNvbnN0IHN0cmluZyYgZmlsZW5hbWUsCisgICAgY29uc3Qgc3RyaW5nJiBpbnNlcnRpb25fcG9pbnQpCisgICAgOiBkaXJlY3RvcnlfKGRpcmVjdG9yeSksCisgICAgICBmaWxlbmFtZV8oZmlsZW5hbWUpLAorICAgICAgaW5zZXJ0aW9uX3BvaW50XyhpbnNlcnRpb25fcG9pbnQpLAorICAgICAgaW5uZXJfKG5ldyBpbzo6U3RyaW5nT3V0cHV0U3RyZWFtKCZkYXRhXykpIHsKK30KKworQ29tbWFuZExpbmVJbnRlcmZhY2U6Ok1lbW9yeU91dHB1dFN0cmVhbTo6fk1lbW9yeU91dHB1dFN0cmVhbSgpIHsKKyAgLy8gTWFrZSBzdXJlIGFsbCBkYXRhIGhhcyBiZWVuIHdyaXR0ZW4uCisgIGlubmVyXy5yZXNldCgpOworCisgIC8vIEluc2VydCBpbnRvIHRoZSBkaXJlY3RvcnkuCisgIHN0cmluZyoqIG1hcF9zbG90ID0gJmRpcmVjdG9yeV8tPmZpbGVzX1tmaWxlbmFtZV9dOworCisgIGlmIChpbnNlcnRpb25fcG9pbnRfLmVtcHR5KCkpIHsKKyAgICAvLyBUaGlzIHdhcyBqdXN0IGEgcmVndWxhciBPcGVuKCkuCisgICAgaWYgKCptYXBfc2xvdCAhPSBOVUxMKSB7CisgICAgICBpZiAoYXBwZW5kX21vZGVfKSB7CisgICAgICAgICgqbWFwX3Nsb3QpLT5hcHBlbmQoZGF0YV8pOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc3RkOjpjZXJyIDw8IGZpbGVuYW1lXyA8PCAiOiBUcmllZCB0byB3cml0ZSB0aGUgc2FtZSBmaWxlIHR3aWNlLiIKKyAgICAgICAgICAgICAgICAgIDw8IHN0ZDo6ZW5kbDsKKyAgICAgICAgZGlyZWN0b3J5Xy0+aGFkX2Vycm9yXyA9IHRydWU7CisgICAgICB9CisgICAgICByZXR1cm47CisgICAgfQorCisgICAgKm1hcF9zbG90ID0gbmV3IHN0cmluZzsKKyAgICAoKm1hcF9zbG90KS0+c3dhcChkYXRhXyk7CisgIH0gZWxzZSB7CisgICAgLy8gVGhpcyB3YXMgYW4gT3BlbkZvckluc2VydCgpLgorCisgICAgLy8gSWYgdGhlIGRhdGEgZG9lbnMndCBlbmQgd2l0aCBhIGNsZWFuIGxpbmUgYnJlYWssIGFkZCBvbmUuCisgICAgaWYgKCFkYXRhXy5lbXB0eSgpICYmIGRhdGFfW2RhdGFfLnNpemUoKSAtIDFdICE9ICdcbicpIHsKKyAgICAgIGRhdGFfLnB1c2hfYmFjaygnXG4nKTsKKyAgICB9CisKKyAgICAvLyBGaW5kIHRoZSBmaWxlIHdlIGFyZSBnb2luZyB0byBpbnNlcnQgaW50by4KKyAgICBpZiAoKm1hcF9zbG90ID09IE5VTEwpIHsKKyAgICAgIHN0ZDo6Y2VyciA8PCBmaWxlbmFtZV8KKyAgICAgICAgICAgICAgICA8PCAiOiBUcmllZCB0byBpbnNlcnQgaW50byBmaWxlIHRoYXQgZG9lc24ndCBleGlzdC4iCisgICAgICAgICAgICAgICAgPDwgc3RkOjplbmRsOworICAgICAgZGlyZWN0b3J5Xy0+aGFkX2Vycm9yXyA9IHRydWU7CisgICAgICByZXR1cm47CisgICAgfQorICAgIHN0cmluZyogdGFyZ2V0ID0gKm1hcF9zbG90OworCisgICAgLy8gRmluZCB0aGUgaW5zZXJ0aW9uIHBvaW50LgorICAgIHN0cmluZyBtYWdpY19zdHJpbmcgPSBzdHJpbmdzOjpTdWJzdGl0dXRlKAorICAgICAgICAiQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KCQwKSIsIGluc2VydGlvbl9wb2ludF8pOworICAgIHN0cmluZzo6c2l6ZV90eXBlIHBvcyA9IHRhcmdldC0+ZmluZChtYWdpY19zdHJpbmcpOworCisgICAgaWYgKHBvcyA9PSBzdHJpbmc6Om5wb3MpIHsKKyAgICAgIHN0ZDo6Y2VyciA8PCBmaWxlbmFtZV8gPDwgIjogaW5zZXJ0aW9uIHBvaW50IFwiIiA8PCBpbnNlcnRpb25fcG9pbnRfCisgICAgICAgICAgICAgICAgPDwgIlwiIG5vdCBmb3VuZC4iIDw8IHN0ZDo6ZW5kbDsKKyAgICAgIGRpcmVjdG9yeV8tPmhhZF9lcnJvcl8gPSB0cnVlOworICAgICAgcmV0dXJuOworICAgIH0KKworICAgIC8vIFNlZWsgYmFja3dhcmRzIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGxpbmUsIHdoaWNoIGlzIHdoZXJlIHdlIHdpbGwKKyAgICAvLyBpbnNlcnQgdGhlIGRhdGEuICBOb3RlIHRoYXQgdGhpcyBoYXMgdGhlIGVmZmVjdCBvZiBwdXNoaW5nIHRoZSBpbnNlcnRpb24KKyAgICAvLyBwb2ludCBkb3duLCBzbyB0aGUgZGF0YSBpcyBpbnNlcnRlZCBiZWZvcmUgaXQuICBUaGlzIGlzIGludGVudGlvbmFsCisgICAgLy8gYmVjYXVzZSBpdCBtZWFucyB0aGF0IG11bHRpcGxlIGluc2VydGlvbnMgYXQgdGhlIHNhbWUgcG9pbnQgd2lsbCBlbmQKKyAgICAvLyB1cCBpbiB0aGUgZXhwZWN0ZWQgb3JkZXIgaW4gdGhlIGZpbmFsIG91dHB1dC4KKyAgICBwb3MgPSB0YXJnZXQtPmZpbmRfbGFzdF9vZignXG4nLCBwb3MpOworICAgIGlmIChwb3MgPT0gc3RyaW5nOjpucG9zKSB7CisgICAgICAvLyBJbnNlcnRpb24gcG9pbnQgaXMgb24gdGhlIGZpcnN0IGxpbmUuCisgICAgICBwb3MgPSAwOworICAgIH0gZWxzZSB7CisgICAgICAvLyBBZHZhbmNlIHRvIGNoYXJhY3RlciBhZnRlciAnXG4nLgorICAgICAgKytwb3M7CisgICAgfQorCisgICAgLy8gRXh0cmFjdCBpbmRlbnQuCisgICAgc3RyaW5nIGluZGVudF8oKnRhcmdldCwgcG9zLCB0YXJnZXQtPmZpbmRfZmlyc3Rfbm90X29mKCIgXHQiLCBwb3MpIC0gcG9zKTsKKworICAgIGlmIChpbmRlbnRfLmVtcHR5KCkpIHsKKyAgICAgIC8vIE5vIGluZGVudC4gIFRoaXMgbWFrZXMgdGhpbmdzIGVhc2llci4KKyAgICAgIHRhcmdldC0+aW5zZXJ0KHBvcywgZGF0YV8pOworICAgIH0gZWxzZSB7CisgICAgICAvLyBDYWxjdWxhdGUgaG93IG11Y2ggc3BhY2Ugd2UgbmVlZC4KKyAgICAgIGludCBpbmRlbnRfc2l6ZSA9IDA7CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGRhdGFfLnNpemUoKTsgaSsrKSB7CisgICAgICAgIGlmIChkYXRhX1tpXSA9PSAnXG4nKSBpbmRlbnRfc2l6ZSArPSBpbmRlbnRfLnNpemUoKTsKKyAgICAgIH0KKworICAgICAgLy8gTWFrZSBhIGhvbGUgZm9yIGl0LgorICAgICAgdGFyZ2V0LT5pbnNlcnQocG9zLCBkYXRhXy5zaXplKCkgKyBpbmRlbnRfc2l6ZSwgJ1wwJyk7CisKKyAgICAgIC8vIE5vdyBjb3B5IGluIHRoZSBkYXRhLgorICAgICAgc3RyaW5nOjpzaXplX3R5cGUgZGF0YV9wb3MgPSAwOworICAgICAgY2hhciogdGFyZ2V0X3B0ciA9IHN0cmluZ19hc19hcnJheSh0YXJnZXQpICsgcG9zOworICAgICAgd2hpbGUgKGRhdGFfcG9zIDwgZGF0YV8uc2l6ZSgpKSB7CisgICAgICAgIC8vIENvcHkgaW5kZW50LgorICAgICAgICBtZW1jcHkodGFyZ2V0X3B0ciwgaW5kZW50Xy5kYXRhKCksIGluZGVudF8uc2l6ZSgpKTsKKyAgICAgICAgdGFyZ2V0X3B0ciArPSBpbmRlbnRfLnNpemUoKTsKKworICAgICAgICAvLyBDb3B5IGxpbmUgZnJvbSBkYXRhXy4KKyAgICAgICAgLy8gV2UgYWxyZWFkeSBndWFyYW50ZWVkIHRoYXQgZGF0YV8gZW5kcyB3aXRoIGEgbmV3bGluZSAoYWJvdmUpLCBzbyB0aGlzCisgICAgICAgIC8vIHNlYXJjaCBjYW4ndCBmYWlsLgorICAgICAgICBzdHJpbmc6OnNpemVfdHlwZSBsaW5lX2xlbmd0aCA9CisgICAgICAgICAgICBkYXRhXy5maW5kX2ZpcnN0X29mKCdcbicsIGRhdGFfcG9zKSArIDEgLSBkYXRhX3BvczsKKyAgICAgICAgbWVtY3B5KHRhcmdldF9wdHIsIGRhdGFfLmRhdGEoKSArIGRhdGFfcG9zLCBsaW5lX2xlbmd0aCk7CisgICAgICAgIHRhcmdldF9wdHIgKz0gbGluZV9sZW5ndGg7CisgICAgICAgIGRhdGFfcG9zICs9IGxpbmVfbGVuZ3RoOworICAgICAgfQorCisgICAgICBHT09HTEVfQ0hFQ0tfRVEodGFyZ2V0X3B0ciwKKyAgICAgICAgICBzdHJpbmdfYXNfYXJyYXkodGFyZ2V0KSArIHBvcyArIGRhdGFfLnNpemUoKSArIGluZGVudF9zaXplKTsKKyAgICB9CisgIH0KK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitDb21tYW5kTGluZUludGVyZmFjZTo6Q29tbWFuZExpbmVJbnRlcmZhY2UoKQorICA6IG1vZGVfKE1PREVfQ09NUElMRSksCisgICAgcHJpbnRfbW9kZV8oUFJJTlRfTk9ORSksCisgICAgZXJyb3JfZm9ybWF0XyhFUlJPUl9GT1JNQVRfR0NDKSwKKyAgICBpbXBvcnRzX2luX2Rlc2NyaXB0b3Jfc2V0XyhmYWxzZSksCisgICAgc291cmNlX2luZm9faW5fZGVzY3JpcHRvcl9zZXRfKGZhbHNlKSwKKyAgICBkaXNhbGxvd19zZXJ2aWNlc18oZmFsc2UpLAorICAgIGlucHV0c19hcmVfcHJvdG9fcGF0aF9yZWxhdGl2ZV8oZmFsc2UpIHt9CitDb21tYW5kTGluZUludGVyZmFjZTo6fkNvbW1hbmRMaW5lSW50ZXJmYWNlKCkge30KKwordm9pZCBDb21tYW5kTGluZUludGVyZmFjZTo6UmVnaXN0ZXJHZW5lcmF0b3IoY29uc3Qgc3RyaW5nJiBmbGFnX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2RlR2VuZXJhdG9yKiBnZW5lcmF0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIGhlbHBfdGV4dCkgeworICBHZW5lcmF0b3JJbmZvIGluZm87CisgIGluZm8uZmxhZ19uYW1lID0gZmxhZ19uYW1lOworICBpbmZvLmdlbmVyYXRvciA9IGdlbmVyYXRvcjsKKyAgaW5mby5oZWxwX3RleHQgPSBoZWxwX3RleHQ7CisgIGdlbmVyYXRvcnNfYnlfZmxhZ19uYW1lX1tmbGFnX25hbWVdID0gaW5mbzsKK30KKwordm9pZCBDb21tYW5kTGluZUludGVyZmFjZTo6UmVnaXN0ZXJHZW5lcmF0b3IoY29uc3Qgc3RyaW5nJiBmbGFnX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIG9wdGlvbl9mbGFnX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2RlR2VuZXJhdG9yKiBnZW5lcmF0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIGhlbHBfdGV4dCkgeworICBHZW5lcmF0b3JJbmZvIGluZm87CisgIGluZm8uZmxhZ19uYW1lID0gZmxhZ19uYW1lOworICBpbmZvLm9wdGlvbl9mbGFnX25hbWUgPSBvcHRpb25fZmxhZ19uYW1lOworICBpbmZvLmdlbmVyYXRvciA9IGdlbmVyYXRvcjsKKyAgaW5mby5oZWxwX3RleHQgPSBoZWxwX3RleHQ7CisgIGdlbmVyYXRvcnNfYnlfZmxhZ19uYW1lX1tmbGFnX25hbWVdID0gaW5mbzsKKyAgZ2VuZXJhdG9yc19ieV9vcHRpb25fbmFtZV9bb3B0aW9uX2ZsYWdfbmFtZV0gPSBpbmZvOworfQorCit2b2lkIENvbW1hbmRMaW5lSW50ZXJmYWNlOjpBbGxvd1BsdWdpbnMoY29uc3Qgc3RyaW5nJiBleGVfbmFtZV9wcmVmaXgpIHsKKyAgcGx1Z2luX3ByZWZpeF8gPSBleGVfbmFtZV9wcmVmaXg7Cit9CisKK2ludCBDb21tYW5kTGluZUludGVyZmFjZTo6UnVuKGludCBhcmdjLCBjb25zdCBjaGFyKiBjb25zdCBhcmd2W10pIHsKKyAgQ2xlYXIoKTsKKyAgc3dpdGNoIChQYXJzZUFyZ3VtZW50cyhhcmdjLCBhcmd2KSkgeworICAgIGNhc2UgUEFSU0VfQVJHVU1FTlRfRE9ORV9BTkRfRVhJVDoKKyAgICAgIHJldHVybiAwOworICAgIGNhc2UgUEFSU0VfQVJHVU1FTlRfRkFJTDoKKyAgICAgIHJldHVybiAxOworICAgIGNhc2UgUEFSU0VfQVJHVU1FTlRfRE9ORV9BTkRfQ09OVElOVUU6CisgICAgICBicmVhazsKKyAgfQorCisgIEFkZERlZmF1bHRQcm90b1BhdGhzKCZwcm90b19wYXRoXyk7CisKKyAgLy8gU2V0IHVwIHRoZSBzb3VyY2UgdHJlZS4KKyAgRGlza1NvdXJjZVRyZWUgc291cmNlX3RyZWU7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgcHJvdG9fcGF0aF8uc2l6ZSgpOyBpKyspIHsKKyAgICBzb3VyY2VfdHJlZS5NYXBQYXRoKHByb3RvX3BhdGhfW2ldLmZpcnN0LCBwcm90b19wYXRoX1tpXS5zZWNvbmQpOworICB9CisKKyAgLy8gTWFwIGlucHV0IGZpbGVzIHRvIHZpcnR1YWwgcGF0aHMgaWYgbmVjZXNzYXJ5LgorICBpZiAoIWlucHV0c19hcmVfcHJvdG9fcGF0aF9yZWxhdGl2ZV8pIHsKKyAgICBpZiAoIU1ha2VJbnB1dHNCZVByb3RvUGF0aFJlbGF0aXZlKCZzb3VyY2VfdHJlZSkpIHsKKyAgICAgIHJldHVybiAxOworICAgIH0KKyAgfQorCisgIC8vIEFsbG9jYXRlIHRoZSBJbXBvcnRlci4KKyAgRXJyb3JQcmludGVyIGVycm9yX2NvbGxlY3RvcihlcnJvcl9mb3JtYXRfLCAmc291cmNlX3RyZWUpOworICBJbXBvcnRlciBpbXBvcnRlcigmc291cmNlX3RyZWUsICZlcnJvcl9jb2xsZWN0b3IpOworCisgIHZlY3Rvcjxjb25zdCBGaWxlRGVzY3JpcHRvcio+IHBhcnNlZF9maWxlczsKKworICAvLyBQYXJzZSBlYWNoIGZpbGUuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgaW5wdXRfZmlsZXNfLnNpemUoKTsgaSsrKSB7CisgICAgLy8gSW1wb3J0IHRoZSBmaWxlLgorICAgIGltcG9ydGVyLkFkZFVudXNlZEltcG9ydFRyYWNrRmlsZShpbnB1dF9maWxlc19baV0pOworICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBwYXJzZWRfZmlsZSA9IGltcG9ydGVyLkltcG9ydChpbnB1dF9maWxlc19baV0pOworICAgIGltcG9ydGVyLkNsZWFyVW51c2VkSW1wb3J0VHJhY2tGaWxlcygpOworICAgIGlmIChwYXJzZWRfZmlsZSA9PSBOVUxMKSByZXR1cm4gMTsKKyAgICBwYXJzZWRfZmlsZXMucHVzaF9iYWNrKHBhcnNlZF9maWxlKTsKKworICAgIC8vIEVuZm9yY2UgLS1kaXNhbGxvd19zZXJ2aWNlcy4KKyAgICBpZiAoZGlzYWxsb3dfc2VydmljZXNfICYmIHBhcnNlZF9maWxlLT5zZXJ2aWNlX2NvdW50KCkgPiAwKSB7CisgICAgICBjZXJyIDw8IHBhcnNlZF9maWxlLT5uYW1lKCkgPDwgIjogVGhpcyBmaWxlIGNvbnRhaW5zIHNlcnZpY2VzLCBidXQgIgorICAgICAgICAgICAgICAiLS1kaXNhbGxvd19zZXJ2aWNlcyB3YXMgdXNlZC4iIDw8IGVuZGw7CisgICAgICByZXR1cm4gMTsKKyAgICB9CisgIH0KKworICAvLyBXZSBjb25zdHJ1Y3QgYSBzZXBhcmF0ZSBHZW5lcmF0b3JDb250ZXh0IGZvciBlYWNoIG91dHB1dCBsb2NhdGlvbi4gIE5vdGUKKyAgLy8gdGhhdCB0d28gY29kZSBnZW5lcmF0b3JzIG1heSBvdXRwdXQgdG8gdGhlIHNhbWUgbG9jYXRpb24sIGluIHdoaWNoIGNhc2UKKyAgLy8gdGhleSBzaG91bGQgc2hhcmUgYSBzaW5nbGUgR2VuZXJhdG9yQ29udGV4dCBzbyB0aGF0IE9wZW5Gb3JJbnNlcnQoKSB3b3Jrcy4KKyAgR2VuZXJhdG9yQ29udGV4dE1hcCBvdXRwdXRfZGlyZWN0b3JpZXM7CisKKyAgLy8gR2VuZXJhdGUgb3V0cHV0LgorICBpZiAobW9kZV8gPT0gTU9ERV9DT01QSUxFKSB7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBvdXRwdXRfZGlyZWN0aXZlc18uc2l6ZSgpOyBpKyspIHsKKyAgICAgIHN0cmluZyBvdXRwdXRfbG9jYXRpb24gPSBvdXRwdXRfZGlyZWN0aXZlc19baV0ub3V0cHV0X2xvY2F0aW9uOworICAgICAgaWYgKCFIYXNTdWZmaXhTdHJpbmcob3V0cHV0X2xvY2F0aW9uLCAiLnppcCIpICYmCisgICAgICAgICAgIUhhc1N1ZmZpeFN0cmluZyhvdXRwdXRfbG9jYXRpb24sICIuamFyIikpIHsKKyAgICAgICAgQWRkVHJhaWxpbmdTbGFzaCgmb3V0cHV0X2xvY2F0aW9uKTsKKyAgICAgIH0KKyAgICAgIEdlbmVyYXRvckNvbnRleHRJbXBsKiogbWFwX3Nsb3QgPSAmb3V0cHV0X2RpcmVjdG9yaWVzW291dHB1dF9sb2NhdGlvbl07CisKKyAgICAgIGlmICgqbWFwX3Nsb3QgPT0gTlVMTCkgeworICAgICAgICAvLyBGaXJzdCB0aW1lIHdlJ3ZlIHNlZW4gdGhpcyBvdXRwdXQgbG9jYXRpb24uCisgICAgICAgICptYXBfc2xvdCA9IG5ldyBHZW5lcmF0b3JDb250ZXh0SW1wbChwYXJzZWRfZmlsZXMpOworICAgICAgfQorCisgICAgICBpZiAoIUdlbmVyYXRlT3V0cHV0KHBhcnNlZF9maWxlcywgb3V0cHV0X2RpcmVjdGl2ZXNfW2ldLCAqbWFwX3Nsb3QpKSB7CisgICAgICAgIFNUTERlbGV0ZVZhbHVlcygmb3V0cHV0X2RpcmVjdG9yaWVzKTsKKyAgICAgICAgcmV0dXJuIDE7CisgICAgICB9CisgICAgfQorICB9CisKKyAgLy8gV3JpdGUgYWxsIG91dHB1dCB0byBkaXNrLgorICBmb3IgKEdlbmVyYXRvckNvbnRleHRNYXA6Oml0ZXJhdG9yIGl0ZXIgPSBvdXRwdXRfZGlyZWN0b3JpZXMuYmVnaW4oKTsKKyAgICAgICBpdGVyICE9IG91dHB1dF9kaXJlY3Rvcmllcy5lbmQoKTsgKytpdGVyKSB7CisgICAgY29uc3Qgc3RyaW5nJiBsb2NhdGlvbiA9IGl0ZXItPmZpcnN0OworICAgIEdlbmVyYXRvckNvbnRleHRJbXBsKiBkaXJlY3RvcnkgPSBpdGVyLT5zZWNvbmQ7CisgICAgaWYgKEhhc1N1ZmZpeFN0cmluZyhsb2NhdGlvbiwgIi8iKSkgeworICAgICAgaWYgKCFkaXJlY3RvcnktPldyaXRlQWxsVG9EaXNrKGxvY2F0aW9uKSkgeworICAgICAgICBTVExEZWxldGVWYWx1ZXMoJm91dHB1dF9kaXJlY3Rvcmllcyk7CisgICAgICAgIHJldHVybiAxOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICBpZiAoSGFzU3VmZml4U3RyaW5nKGxvY2F0aW9uLCAiLmphciIpKSB7CisgICAgICAgIGRpcmVjdG9yeS0+QWRkSmFyTWFuaWZlc3QoKTsKKyAgICAgIH0KKworICAgICAgaWYgKCFkaXJlY3RvcnktPldyaXRlQWxsVG9aaXAobG9jYXRpb24pKSB7CisgICAgICAgIFNUTERlbGV0ZVZhbHVlcygmb3V0cHV0X2RpcmVjdG9yaWVzKTsKKyAgICAgICAgcmV0dXJuIDE7CisgICAgICB9CisgICAgfQorICB9CisKKyAgaWYgKCFkZXBlbmRlbmN5X291dF9uYW1lXy5lbXB0eSgpKSB7CisgICAgaWYgKCFHZW5lcmF0ZURlcGVuZGVuY3lNYW5pZmVzdEZpbGUocGFyc2VkX2ZpbGVzLCBvdXRwdXRfZGlyZWN0b3JpZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnNvdXJjZV90cmVlKSkgeworICAgICAgcmV0dXJuIDE7CisgICAgfQorICB9CisKKyAgU1RMRGVsZXRlVmFsdWVzKCZvdXRwdXRfZGlyZWN0b3JpZXMpOworCisgIGlmICghZGVzY3JpcHRvcl9zZXRfbmFtZV8uZW1wdHkoKSkgeworICAgIGlmICghV3JpdGVEZXNjcmlwdG9yU2V0KHBhcnNlZF9maWxlcykpIHsKKyAgICAgIHJldHVybiAxOworICAgIH0KKyAgfQorCisgIGlmIChtb2RlXyA9PSBNT0RFX0VOQ09ERSB8fCBtb2RlXyA9PSBNT0RFX0RFQ09ERSkgeworICAgIGlmIChjb2RlY190eXBlXy5lbXB0eSgpKSB7CisgICAgICAvLyBIQUNLOiAgRGVmaW5lIGFuIEVtcHR5TWVzc2FnZSB0eXBlIHRvIHVzZSBmb3IgZGVjb2RpbmcuCisgICAgICBEZXNjcmlwdG9yUG9vbCBwb29sOworICAgICAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlOworICAgICAgZmlsZS5zZXRfbmFtZSgiZW1wdHlfbWVzc2FnZS5wcm90byIpOworICAgICAgZmlsZS5hZGRfbWVzc2FnZV90eXBlKCktPnNldF9uYW1lKCJFbXB0eU1lc3NhZ2UiKTsKKyAgICAgIEdPT0dMRV9DSEVDSyhwb29sLkJ1aWxkRmlsZShmaWxlKSAhPSBOVUxMKTsKKyAgICAgIGNvZGVjX3R5cGVfID0gIkVtcHR5TWVzc2FnZSI7CisgICAgICBpZiAoIUVuY29kZU9yRGVjb2RlKCZwb29sKSkgeworICAgICAgICByZXR1cm4gMTsKKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgaWYgKCFFbmNvZGVPckRlY29kZShpbXBvcnRlci5wb29sKCkpKSB7CisgICAgICAgIHJldHVybiAxOworICAgICAgfQorICAgIH0KKyAgfQorCisgIGlmIChtb2RlXyA9PSBNT0RFX1BSSU5UKSB7CisgICAgc3dpdGNoIChwcmludF9tb2RlXykgeworICAgICAgY2FzZSBQUklOVF9GUkVFX0ZJRUxEUzoKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYXJzZWRfZmlsZXMuc2l6ZSgpOyArK2kpIHsKKyAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmQgPSBwYXJzZWRfZmlsZXNbaV07CisgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBmZC0+bWVzc2FnZV90eXBlX2NvdW50KCk7ICsraikgeworICAgICAgICAgICAgUHJpbnRGcmVlRmllbGROdW1iZXJzKGZkLT5tZXNzYWdlX3R5cGUoaikpOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgUFJJTlRfTk9ORToKKyAgICAgICAgR09PR0xFX0xPRyhFUlJPUikgPDwgIklmIHRoZSBjb2RlIHJlYWNoZXMgaGVyZSwgaXQgdXN1YWxseSBtZWFucyBhIGJ1ZyBvZiAiCisgICAgICAgICAgICAgICAgICAgICAiZmxhZyBwYXJzaW5nIGluIHRoZSBDb21tb25hZExpbmVJbnRlcmZhY2UuIjsKKyAgICAgICAgcmV0dXJuIDE7CisKKyAgICAgIC8vIERvIG5vdCBhZGQgYSBkZWZhdWx0IGNhc2UuCisgICAgfQorICB9CisKKyAgcmV0dXJuIDA7Cit9CisKK3ZvaWQgQ29tbWFuZExpbmVJbnRlcmZhY2U6OkNsZWFyKCkgeworICAvLyBDbGVhciBhbGwgbWVtYmVycyB0aGF0IGFyZSBzZXQgYnkgUnVuKCkuICBOb3RlIHRoYXQgd2UgbXVzdCBub3QgY2xlYXIKKyAgLy8gbWVtYmVycyB3aGljaCBhcmUgc2V0IGJ5IG90aGVyIG1ldGhvZHMgYmVmb3JlIFJ1bigpIGlzIGNhbGxlZC4KKyAgZXhlY3V0YWJsZV9uYW1lXy5jbGVhcigpOworICBwcm90b19wYXRoXy5jbGVhcigpOworICBpbnB1dF9maWxlc18uY2xlYXIoKTsKKyAgb3V0cHV0X2RpcmVjdGl2ZXNfLmNsZWFyKCk7CisgIGNvZGVjX3R5cGVfLmNsZWFyKCk7CisgIGRlc2NyaXB0b3Jfc2V0X25hbWVfLmNsZWFyKCk7CisgIGRlcGVuZGVuY3lfb3V0X25hbWVfLmNsZWFyKCk7CisKKyAgbW9kZV8gPSBNT0RFX0NPTVBJTEU7CisgIHByaW50X21vZGVfID0gUFJJTlRfTk9ORTsKKyAgaW1wb3J0c19pbl9kZXNjcmlwdG9yX3NldF8gPSBmYWxzZTsKKyAgc291cmNlX2luZm9faW5fZGVzY3JpcHRvcl9zZXRfID0gZmFsc2U7CisgIGRpc2FsbG93X3NlcnZpY2VzXyA9IGZhbHNlOworfQorCitib29sIENvbW1hbmRMaW5lSW50ZXJmYWNlOjpNYWtlSW5wdXRzQmVQcm90b1BhdGhSZWxhdGl2ZSgKKyAgICBEaXNrU291cmNlVHJlZSogc291cmNlX3RyZWUpIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbnB1dF9maWxlc18uc2l6ZSgpOyBpKyspIHsKKyAgICBzdHJpbmcgdmlydHVhbF9maWxlLCBzaGFkb3dpbmdfZGlza19maWxlOworICAgIHN3aXRjaCAoc291cmNlX3RyZWUtPkRpc2tGaWxlVG9WaXJ0dWFsRmlsZSgKKyAgICAgICAgaW5wdXRfZmlsZXNfW2ldLCAmdmlydHVhbF9maWxlLCAmc2hhZG93aW5nX2Rpc2tfZmlsZSkpIHsKKyAgICAgIGNhc2UgRGlza1NvdXJjZVRyZWU6OlNVQ0NFU1M6CisgICAgICAgIGlucHV0X2ZpbGVzX1tpXSA9IHZpcnR1YWxfZmlsZTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIERpc2tTb3VyY2VUcmVlOjpTSEFET1dFRDoKKyAgICAgICAgc3RkOjpjZXJyIDw8IGlucHV0X2ZpbGVzX1tpXQorICAgICAgICAgICAgICAgICAgPDwgIjogSW5wdXQgaXMgc2hhZG93ZWQgaW4gdGhlIC0tcHJvdG9fcGF0aCBieSBcIiIKKyAgICAgICAgICAgICAgICAgIDw8IHNoYWRvd2luZ19kaXNrX2ZpbGUKKyAgICAgICAgICAgICAgICAgIDw8ICJcIi4gIEVpdGhlciB1c2UgdGhlIGxhdHRlciBmaWxlIGFzIHlvdXIgaW5wdXQgb3IgcmVvcmRlciAiCisgICAgICAgICAgICAgICAgICAgICAidGhlIC0tcHJvdG9fcGF0aCBzbyB0aGF0IHRoZSBmb3JtZXIgZmlsZSdzIGxvY2F0aW9uICIKKyAgICAgICAgICAgICAgICAgICAgICJjb21lcyBmaXJzdC4iIDw8IHN0ZDo6ZW5kbDsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgY2FzZSBEaXNrU291cmNlVHJlZTo6Q0FOTk9UX09QRU46CisgICAgICAgIHN0ZDo6Y2VyciA8PCBpbnB1dF9maWxlc19baV0gPDwgIjogIiA8PCBzdHJlcnJvcihlcnJubykgPDwgc3RkOjplbmRsOworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBjYXNlIERpc2tTb3VyY2VUcmVlOjpOT19NQVBQSU5HOgorICAgICAgICAvLyBGaXJzdCBjaGVjayBpZiB0aGUgZmlsZSBleGlzdHMgYXQgYWxsLgorICAgICAgICBpZiAoYWNjZXNzKGlucHV0X2ZpbGVzX1tpXS5jX3N0cigpLCBGX09LKSA8IDApIHsKKyAgICAgICAgICAvLyBGaWxlIGRvZXMgbm90IGV2ZW4gZXhpc3QuCisgICAgICAgICAgc3RkOjpjZXJyIDw8IGlucHV0X2ZpbGVzX1tpXSA8PCAiOiAiIDw8IHN0cmVycm9yKEVOT0VOVCkgPDwgc3RkOjplbmRsOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHN0ZDo6Y2VycgorICAgICAgICAgICAgICA8PCBpbnB1dF9maWxlc19baV0KKyAgICAgICAgICAgICAgPDwgIjogRmlsZSBkb2VzIG5vdCByZXNpZGUgd2l0aGluIGFueSBwYXRoICIKKyAgICAgICAgICAgICAgICAgInNwZWNpZmllZCB1c2luZyAtLXByb3RvX3BhdGggKG9yIC1JKS4gIFlvdSBtdXN0IHNwZWNpZnkgYSAiCisgICAgICAgICAgICAgICAgICItLXByb3RvX3BhdGggd2hpY2ggZW5jb21wYXNzZXMgdGhpcyBmaWxlLiAgTm90ZSB0aGF0IHRoZSAiCisgICAgICAgICAgICAgICAgICJwcm90b19wYXRoIG11c3QgYmUgYW4gZXhhY3QgcHJlZml4IG9mIHRoZSAucHJvdG8gZmlsZSAiCisgICAgICAgICAgICAgICAgICJuYW1lcyAtLSBwcm90b2MgaXMgdG9vIGR1bWIgdG8gZmlndXJlIG91dCB3aGVuIHR3byBwYXRocyAiCisgICAgICAgICAgICAgICAgICIoZS5nLiBhYnNvbHV0ZSBhbmQgcmVsYXRpdmUpIGFyZSBlcXVpdmFsZW50IChpdCdzIGhhcmRlciAiCisgICAgICAgICAgICAgICAgICJ0aGFuIHlvdSB0aGluaykuIiA8PCBzdGQ6OmVuZGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgfQorCisgIHJldHVybiB0cnVlOworfQorCitDb21tYW5kTGluZUludGVyZmFjZTo6UGFyc2VBcmd1bWVudFN0YXR1cworQ29tbWFuZExpbmVJbnRlcmZhY2U6OlBhcnNlQXJndW1lbnRzKGludCBhcmdjLCBjb25zdCBjaGFyKiBjb25zdCBhcmd2W10pIHsKKyAgZXhlY3V0YWJsZV9uYW1lXyA9IGFyZ3ZbMF07CisKKyAgLy8gSXRlcmF0ZSB0aHJvdWdoIGFsbCBhcmd1bWVudHMgYW5kIHBhcnNlIHRoZW0uCisgIGZvciAoaW50IGkgPSAxOyBpIDwgYXJnYzsgaSsrKSB7CisgICAgc3RyaW5nIG5hbWUsIHZhbHVlOworCisgICAgaWYgKFBhcnNlQXJndW1lbnQoYXJndltpXSwgJm5hbWUsICZ2YWx1ZSkpIHsKKyAgICAgIC8vIFJldHVybmVkIHRydWUgPT4gVXNlIHRoZSBuZXh0IGFyZ3VtZW50IGFzIHRoZSBmbGFnIHZhbHVlLgorICAgICAgaWYgKGkgKyAxID09IGFyZ2MgfHwgYXJndltpKzFdWzBdID09ICctJykgeworICAgICAgICBzdGQ6OmNlcnIgPDwgIk1pc3NpbmcgdmFsdWUgZm9yIGZsYWc6ICIgPDwgbmFtZSA8PCBzdGQ6OmVuZGw7CisgICAgICAgIGlmIChuYW1lID09ICItLWRlY29kZSIpIHsKKyAgICAgICAgICBzdGQ6OmNlcnIgPDwgIlRvIGRlY29kZSBhbiB1bmtub3duIG1lc3NhZ2UsIHVzZSAtLWRlY29kZV9yYXcuIgorICAgICAgICAgICAgICAgICAgICA8PCBzdGQ6OmVuZGw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIFBBUlNFX0FSR1VNRU5UX0ZBSUw7CisgICAgICB9IGVsc2UgeworICAgICAgICArK2k7CisgICAgICAgIHZhbHVlID0gYXJndltpXTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBQYXJzZUFyZ3VtZW50U3RhdHVzIHN0YXR1cyA9IEludGVycHJldEFyZ3VtZW50KG5hbWUsIHZhbHVlKTsKKyAgICBpZiAoc3RhdHVzICE9IFBBUlNFX0FSR1VNRU5UX0RPTkVfQU5EX0NPTlRJTlVFKQorICAgICAgcmV0dXJuIHN0YXR1czsKKyAgfQorCisgIC8vIElmIG5vIC0tcHJvdG9fcGF0aCB3YXMgZ2l2ZW4sIHVzZSB0aGUgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeS4KKyAgaWYgKHByb3RvX3BhdGhfLmVtcHR5KCkpIHsKKyAgICAvLyBEb24ndCB1c2UgbWFrZV9wYWlyIGFzIHRoZSBvbGQvZGVmYXVsdCBzdGFuZGFyZCBsaWJyYXJ5IG9uIFNvbGFyaXMKKyAgICAvLyBkb2Vzbid0IHN1cHBvcnQgaXQgd2l0aG91dCBleHBsaWNpdCB0ZW1wbGF0ZSBwYXJhbWV0ZXJzLCB3aGljaCBhcmUKKyAgICAvLyBpbmNvbXBhdGlibGUgd2l0aCBDKysweCdzIG1ha2VfcGFpci4KKyAgICBwcm90b19wYXRoXy5wdXNoX2JhY2socGFpcjxzdHJpbmcsIHN0cmluZz4oIiIsICIuIikpOworICB9CisKKyAgLy8gQ2hlY2sgc29tZSBlcnJyb3IgY2FzZXMuCisgIGJvb2wgZGVjb2RpbmdfcmF3ID0gKG1vZGVfID09IE1PREVfREVDT0RFKSAmJiBjb2RlY190eXBlXy5lbXB0eSgpOworICBpZiAoZGVjb2RpbmdfcmF3ICYmICFpbnB1dF9maWxlc18uZW1wdHkoKSkgeworICAgIHN0ZDo6Y2VyciA8PCAiV2hlbiB1c2luZyAtLWRlY29kZV9yYXcsIG5vIGlucHV0IGZpbGVzIHNob3VsZCBiZSBnaXZlbi4iCisgICAgICAgICAgICAgIDw8IHN0ZDo6ZW5kbDsKKyAgICByZXR1cm4gUEFSU0VfQVJHVU1FTlRfRkFJTDsKKyAgfSBlbHNlIGlmICghZGVjb2RpbmdfcmF3ICYmIGlucHV0X2ZpbGVzXy5lbXB0eSgpKSB7CisgICAgc3RkOjpjZXJyIDw8ICJNaXNzaW5nIGlucHV0IGZpbGUuIiA8PCBzdGQ6OmVuZGw7CisgICAgcmV0dXJuIFBBUlNFX0FSR1VNRU5UX0ZBSUw7CisgIH0KKyAgaWYgKG1vZGVfID09IE1PREVfQ09NUElMRSAmJiBvdXRwdXRfZGlyZWN0aXZlc18uZW1wdHkoKSAmJgorICAgICAgZGVzY3JpcHRvcl9zZXRfbmFtZV8uZW1wdHkoKSkgeworICAgIHN0ZDo6Y2VyciA8PCAiTWlzc2luZyBvdXRwdXQgZGlyZWN0aXZlcy4iIDw8IHN0ZDo6ZW5kbDsKKyAgICByZXR1cm4gUEFSU0VfQVJHVU1FTlRfRkFJTDsKKyAgfQorICBpZiAobW9kZV8gIT0gTU9ERV9DT01QSUxFICYmICFkZXBlbmRlbmN5X291dF9uYW1lXy5lbXB0eSgpKSB7CisgICAgc3RkOjpjZXJyIDw8ICJDYW4gb25seSB1c2UgLS1kZXBlbmRlbmN5X291dD1GSUxFIHdoZW4gZ2VuZXJhdGluZyBjb2RlLiIKKyAgICAgICAgICAgICAgPDwgc3RkOjplbmRsOworICAgIHJldHVybiBQQVJTRV9BUkdVTUVOVF9GQUlMOworICB9CisgIGlmICghZGVwZW5kZW5jeV9vdXRfbmFtZV8uZW1wdHkoKSAmJiBpbnB1dF9maWxlc18uc2l6ZSgpID4gMSkgeworICAgIHN0ZDo6Y2VycgorICAgICAgICA8PCAiQ2FuIG9ubHkgcHJvY2VzcyBvbmUgaW5wdXQgZmlsZSB3aGVuIHVzaW5nIC0tZGVwZW5kZW5jeV9vdXQ9RklMRS4iCisgICAgICAgIDw8IHN0ZDo6ZW5kbDsKKyAgICByZXR1cm4gUEFSU0VfQVJHVU1FTlRfRkFJTDsKKyAgfQorICBpZiAoaW1wb3J0c19pbl9kZXNjcmlwdG9yX3NldF8gJiYgZGVzY3JpcHRvcl9zZXRfbmFtZV8uZW1wdHkoKSkgeworICAgIHN0ZDo6Y2VyciA8PCAiLS1pbmNsdWRlX2ltcG9ydHMgb25seSBtYWtlcyBzZW5zZSB3aGVuIGNvbWJpbmVkIHdpdGggIgorICAgICAgICAgICAgICAgICAiLS1kZXNjcmlwdG9yX3NldF9vdXQuIiA8PCBzdGQ6OmVuZGw7CisgIH0KKyAgaWYgKHNvdXJjZV9pbmZvX2luX2Rlc2NyaXB0b3Jfc2V0XyAmJiBkZXNjcmlwdG9yX3NldF9uYW1lXy5lbXB0eSgpKSB7CisgICAgc3RkOjpjZXJyIDw8ICItLWluY2x1ZGVfc291cmNlX2luZm8gb25seSBtYWtlcyBzZW5zZSB3aGVuIGNvbWJpbmVkIHdpdGggIgorICAgICAgICAgICAgICAgICAiLS1kZXNjcmlwdG9yX3NldF9vdXQuIiA8PCBzdGQ6OmVuZGw7CisgIH0KKworICByZXR1cm4gUEFSU0VfQVJHVU1FTlRfRE9ORV9BTkRfQ09OVElOVUU7Cit9CisKK2Jvb2wgQ29tbWFuZExpbmVJbnRlcmZhY2U6OlBhcnNlQXJndW1lbnQoY29uc3QgY2hhciogYXJnLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcqIG5hbWUsIHN0cmluZyogdmFsdWUpIHsKKyAgYm9vbCBwYXJzZWRfdmFsdWUgPSBmYWxzZTsKKworICBpZiAoYXJnWzBdICE9ICctJykgeworICAgIC8vIE5vdCBhIGZsYWcuCisgICAgbmFtZS0+Y2xlYXIoKTsKKyAgICBwYXJzZWRfdmFsdWUgPSB0cnVlOworICAgICp2YWx1ZSA9IGFyZzsKKyAgfSBlbHNlIGlmIChhcmdbMV0gPT0gJy0nKSB7CisgICAgLy8gVHdvIGRhc2hlczogIE11bHRpLWNoYXJhY3RlciBuYW1lLCB3aXRoICc9JyBzZXBhcmF0aW5nIG5hbWUgYW5kCisgICAgLy8gICB2YWx1ZS4KKyAgICBjb25zdCBjaGFyKiBlcXVhbHNfcG9zID0gc3RyY2hyKGFyZywgJz0nKTsKKyAgICBpZiAoZXF1YWxzX3BvcyAhPSBOVUxMKSB7CisgICAgICAqbmFtZSA9IHN0cmluZyhhcmcsIGVxdWFsc19wb3MgLSBhcmcpOworICAgICAgKnZhbHVlID0gZXF1YWxzX3BvcyArIDE7CisgICAgICBwYXJzZWRfdmFsdWUgPSB0cnVlOworICAgIH0gZWxzZSB7CisgICAgICAqbmFtZSA9IGFyZzsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgLy8gT25lIGRhc2g6ICBPbmUtY2hhcmFjdGVyIG5hbWUsIGFsbCBzdWJzZXF1ZW50IGNoYXJhY3RlcnMgYXJlIHRoZQorICAgIC8vICAgdmFsdWUuCisgICAgaWYgKGFyZ1sxXSA9PSAnXDAnKSB7CisgICAgICAvLyBhcmcgaXMganVzdCAiLSIuICBXZSB0cmVhdCB0aGlzIGFzIGFuIGlucHV0IGZpbGUsIGV4Y2VwdCB0aGF0IGF0CisgICAgICAvLyBwcmVzZW50IHRoaXMgd2lsbCBqdXN0IGxlYWQgdG8gYSAiZmlsZSBub3QgZm91bmQiIGVycm9yLgorICAgICAgbmFtZS0+Y2xlYXIoKTsKKyAgICAgICp2YWx1ZSA9IGFyZzsKKyAgICAgIHBhcnNlZF92YWx1ZSA9IHRydWU7CisgICAgfSBlbHNlIHsKKyAgICAgICpuYW1lID0gc3RyaW5nKGFyZywgMik7CisgICAgICAqdmFsdWUgPSBhcmcgKyAyOworICAgICAgcGFyc2VkX3ZhbHVlID0gIXZhbHVlLT5lbXB0eSgpOworICAgIH0KKyAgfQorCisgIC8vIE5lZWQgdG8gcmV0dXJuIHRydWUgaWZmIHRoZSBuZXh0IGFyZyBzaG91bGQgYmUgdXNlZCBhcyB0aGUgdmFsdWUgZm9yIHRoaXMKKyAgLy8gb25lLCBmYWxzZSBvdGhlcndpc2UuCisKKyAgaWYgKHBhcnNlZF92YWx1ZSkgeworICAgIC8vIFdlIGFscmVhZHkgcGFyc2VkIGEgdmFsdWUgZm9yIHRoaXMgZmxhZy4KKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBpZiAoKm5hbWUgPT0gIi1oIiB8fCAqbmFtZSA9PSAiLS1oZWxwIiB8fAorICAgICAgKm5hbWUgPT0gIi0tZGlzYWxsb3dfc2VydmljZXMiIHx8CisgICAgICAqbmFtZSA9PSAiLS1pbmNsdWRlX2ltcG9ydHMiIHx8CisgICAgICAqbmFtZSA9PSAiLS1pbmNsdWRlX3NvdXJjZV9pbmZvIiB8fAorICAgICAgKm5hbWUgPT0gIi0tdmVyc2lvbiIgfHwKKyAgICAgICpuYW1lID09ICItLWRlY29kZV9yYXciIHx8CisgICAgICAqbmFtZSA9PSAiLS1wcmludF9mcmVlX2ZpZWxkX251bWJlcnMiKSB7CisgICAgLy8gSEFDSzogIFRoZXNlIGFyZSB0aGUgb25seSBmbGFncyB0aGF0IGRvbid0IHRha2UgYSB2YWx1ZS4KKyAgICAvLyAgIFRoZXkgcHJvYmFibHkgc2hvdWxkIG5vdCBiZSBoYXJkLWNvZGVkIGxpa2UgdGhpcyBidXQgZm9yIG5vdyBpdCdzCisgICAgLy8gICBub3Qgd29ydGggZG9pbmcgYmV0dGVyLgorICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vIE5leHQgYXJndW1lbnQgaXMgdGhlIGZsYWcgdmFsdWUuCisgIHJldHVybiB0cnVlOworfQorCitDb21tYW5kTGluZUludGVyZmFjZTo6UGFyc2VBcmd1bWVudFN0YXR1cworQ29tbWFuZExpbmVJbnRlcmZhY2U6OkludGVycHJldEFyZ3VtZW50KGNvbnN0IHN0cmluZyYgbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHZhbHVlKSB7CisgIGlmIChuYW1lLmVtcHR5KCkpIHsKKyAgICAvLyBOb3QgYSBmbGFnLiAgSnVzdCBhIGZpbGVuYW1lLgorICAgIGlmICh2YWx1ZS5lbXB0eSgpKSB7CisgICAgICBzdGQ6OmNlcnIKKyAgICAgICAgICA8PCAiWW91IHNlZW0gdG8gaGF2ZSBwYXNzZWQgYW4gZW1wdHkgc3RyaW5nIGFzIG9uZSBvZiB0aGUgIgorICAgICAgICAgICAgICJhcmd1bWVudHMgdG8gIiA8PCBleGVjdXRhYmxlX25hbWVfCisgICAgICAgICAgPDwgIi4gIFRoaXMgaXMgYWN0dWFsbHkgIgorICAgICAgICAgICAgICJzb3J0IG9mIGhhcmQgdG8gZG8uICBDb25ncmF0cy4gIFVuZm9ydHVuYXRlbHkgaXQgaXMgbm90IHZhbGlkICIKKyAgICAgICAgICAgICAiaW5wdXQgc28gdGhlIHByb2dyYW0gaXMgZ29pbmcgdG8gZGllIG5vdy4iIDw8IHN0ZDo6ZW5kbDsKKyAgICAgIHJldHVybiBQQVJTRV9BUkdVTUVOVF9GQUlMOworICAgIH0KKworICAgIGlucHV0X2ZpbGVzXy5wdXNoX2JhY2sodmFsdWUpOworCisgIH0gZWxzZSBpZiAobmFtZSA9PSAiLUkiIHx8IG5hbWUgPT0gIi0tcHJvdG9fcGF0aCIpIHsKKyAgICAvLyBKYXZhJ3MgLWNsYXNzcGF0aCAoYW5kIHNvbWUgb3RoZXIgbGFuZ3VhZ2VzKSBkZWxpbWl0cyBwYXRoIGNvbXBvbmVudHMKKyAgICAvLyB3aXRoIGNvbG9ucy4gIExldCdzIGFjY2VwdCB0aGF0IHN5bnRheCB0b28ganVzdCB0byBtYWtlIHRoaW5ncyBtb3JlCisgICAgLy8gaW50dWl0aXZlLgorICAgIHZlY3RvcjxzdHJpbmc+IHBhcnRzID0gU3BsaXQoCisgICAgICAgIHZhbHVlLCBrUGF0aFNlcGFyYXRvciwgdHJ1ZSk7CisKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhcnRzLnNpemUoKTsgaSsrKSB7CisgICAgICBzdHJpbmcgdmlydHVhbF9wYXRoOworICAgICAgc3RyaW5nIGRpc2tfcGF0aDsKKworICAgICAgc3RyaW5nOjpzaXplX3R5cGUgZXF1YWxzX3BvcyA9IHBhcnRzW2ldLmZpbmRfZmlyc3Rfb2YoJz0nKTsKKyAgICAgIGlmIChlcXVhbHNfcG9zID09IHN0cmluZzo6bnBvcykgeworICAgICAgICB2aXJ0dWFsX3BhdGggPSAiIjsKKyAgICAgICAgZGlza19wYXRoID0gcGFydHNbaV07CisgICAgICB9IGVsc2UgeworICAgICAgICB2aXJ0dWFsX3BhdGggPSBwYXJ0c1tpXS5zdWJzdHIoMCwgZXF1YWxzX3Bvcyk7CisgICAgICAgIGRpc2tfcGF0aCA9IHBhcnRzW2ldLnN1YnN0cihlcXVhbHNfcG9zICsgMSk7CisgICAgICB9CisKKyAgICAgIGlmIChkaXNrX3BhdGguZW1wdHkoKSkgeworICAgICAgICBzdGQ6OmNlcnIKKyAgICAgICAgICAgIDw8ICItLXByb3RvX3BhdGggcGFzc2VkIGVtcHR5IGRpcmVjdG9yeSBuYW1lLiAgKFVzZSBcIi5cIiBmb3IgIgorICAgICAgICAgICAgICAgImN1cnJlbnQgZGlyZWN0b3J5LikiIDw8IHN0ZDo6ZW5kbDsKKyAgICAgICAgcmV0dXJuIFBBUlNFX0FSR1VNRU5UX0ZBSUw7CisgICAgICB9CisKKyAgICAgIC8vIE1ha2Ugc3VyZSBkaXNrIHBhdGggZXhpc3RzLCB3YXJuIG90aGVyd2lzZS4KKyAgICAgIGlmIChhY2Nlc3MoZGlza19wYXRoLmNfc3RyKCksIEZfT0spIDwgMCkgeworICAgICAgICBzdGQ6OmNlcnIgPDwgZGlza19wYXRoIDw8ICI6IHdhcm5pbmc6IGRpcmVjdG9yeSBkb2VzIG5vdCBleGlzdC4iCisgICAgICAgICAgICAgICAgICA8PCBzdGQ6OmVuZGw7CisgICAgICB9CisKKyAgICAgIC8vIERvbid0IHVzZSBtYWtlX3BhaXIgYXMgdGhlIG9sZC9kZWZhdWx0IHN0YW5kYXJkIGxpYnJhcnkgb24gU29sYXJpcworICAgICAgLy8gZG9lc24ndCBzdXBwb3J0IGl0IHdpdGhvdXQgZXhwbGljaXQgdGVtcGxhdGUgcGFyYW1ldGVycywgd2hpY2ggYXJlCisgICAgICAvLyBpbmNvbXBhdGlibGUgd2l0aCBDKysweCdzIG1ha2VfcGFpci4KKyAgICAgIHByb3RvX3BhdGhfLnB1c2hfYmFjayhwYWlyPHN0cmluZywgc3RyaW5nPih2aXJ0dWFsX3BhdGgsIGRpc2tfcGF0aCkpOworICAgIH0KKworICB9IGVsc2UgaWYgKG5hbWUgPT0gIi1vIiB8fCBuYW1lID09ICItLWRlc2NyaXB0b3Jfc2V0X291dCIpIHsKKyAgICBpZiAoIWRlc2NyaXB0b3Jfc2V0X25hbWVfLmVtcHR5KCkpIHsKKyAgICAgIHN0ZDo6Y2VyciA8PCBuYW1lIDw8ICIgbWF5IG9ubHkgYmUgcGFzc2VkIG9uY2UuIiA8PCBzdGQ6OmVuZGw7CisgICAgICByZXR1cm4gUEFSU0VfQVJHVU1FTlRfRkFJTDsKKyAgICB9CisgICAgaWYgKHZhbHVlLmVtcHR5KCkpIHsKKyAgICAgIHN0ZDo6Y2VyciA8PCBuYW1lIDw8ICIgcmVxdWlyZXMgYSBub24tZW1wdHkgdmFsdWUuIiA8PCBzdGQ6OmVuZGw7CisgICAgICByZXR1cm4gUEFSU0VfQVJHVU1FTlRfRkFJTDsKKyAgICB9CisgICAgaWYgKG1vZGVfICE9IE1PREVfQ09NUElMRSkgeworICAgICAgc3RkOjpjZXJyCisgICAgICAgICAgPDwgIkNhbm5vdCB1c2UgLS1lbmNvZGUgb3IgLS1kZWNvZGUgYW5kIGdlbmVyYXRlIGRlc2NyaXB0b3JzIGF0IHRoZSAiCisgICAgICAgICAgICAgInNhbWUgdGltZS4iIDw8IHN0ZDo6ZW5kbDsKKyAgICAgIHJldHVybiBQQVJTRV9BUkdVTUVOVF9GQUlMOworICAgIH0KKyAgICBkZXNjcmlwdG9yX3NldF9uYW1lXyA9IHZhbHVlOworCisgIH0gZWxzZSBpZiAobmFtZSA9PSAiLS1kZXBlbmRlbmN5X291dCIpIHsKKyAgICBpZiAoIWRlcGVuZGVuY3lfb3V0X25hbWVfLmVtcHR5KCkpIHsKKyAgICAgIHN0ZDo6Y2VyciA8PCBuYW1lIDw8ICIgbWF5IG9ubHkgYmUgcGFzc2VkIG9uY2UuIiA8PCBzdGQ6OmVuZGw7CisgICAgICByZXR1cm4gUEFSU0VfQVJHVU1FTlRfRkFJTDsKKyAgICB9CisgICAgaWYgKHZhbHVlLmVtcHR5KCkpIHsKKyAgICAgIHN0ZDo6Y2VyciA8PCBuYW1lIDw8ICIgcmVxdWlyZXMgYSBub24tZW1wdHkgdmFsdWUuIiA8PCBzdGQ6OmVuZGw7CisgICAgICByZXR1cm4gUEFSU0VfQVJHVU1FTlRfRkFJTDsKKyAgICB9CisgICAgZGVwZW5kZW5jeV9vdXRfbmFtZV8gPSB2YWx1ZTsKKworICB9IGVsc2UgaWYgKG5hbWUgPT0gIi0taW5jbHVkZV9pbXBvcnRzIikgeworICAgIGlmIChpbXBvcnRzX2luX2Rlc2NyaXB0b3Jfc2V0XykgeworICAgICAgc3RkOjpjZXJyIDw8IG5hbWUgPDwgIiBtYXkgb25seSBiZSBwYXNzZWQgb25jZS4iIDw8IHN0ZDo6ZW5kbDsKKyAgICAgIHJldHVybiBQQVJTRV9BUkdVTUVOVF9GQUlMOworICAgIH0KKyAgICBpbXBvcnRzX2luX2Rlc2NyaXB0b3Jfc2V0XyA9IHRydWU7CisKKyAgfSBlbHNlIGlmIChuYW1lID09ICItLWluY2x1ZGVfc291cmNlX2luZm8iKSB7CisgICAgaWYgKHNvdXJjZV9pbmZvX2luX2Rlc2NyaXB0b3Jfc2V0XykgeworICAgICAgc3RkOjpjZXJyIDw8IG5hbWUgPDwgIiBtYXkgb25seSBiZSBwYXNzZWQgb25jZS4iIDw8IHN0ZDo6ZW5kbDsKKyAgICAgIHJldHVybiBQQVJTRV9BUkdVTUVOVF9GQUlMOworICAgIH0KKyAgICBzb3VyY2VfaW5mb19pbl9kZXNjcmlwdG9yX3NldF8gPSB0cnVlOworCisgIH0gZWxzZSBpZiAobmFtZSA9PSAiLWgiIHx8IG5hbWUgPT0gIi0taGVscCIpIHsKKyAgICBQcmludEhlbHBUZXh0KCk7CisgICAgcmV0dXJuIFBBUlNFX0FSR1VNRU5UX0RPTkVfQU5EX0VYSVQ7ICAvLyBFeGl0IHdpdGhvdXQgcnVubmluZyBjb21waWxlci4KKworICB9IGVsc2UgaWYgKG5hbWUgPT0gIi0tdmVyc2lvbiIpIHsKKyAgICBpZiAoIXZlcnNpb25faW5mb18uZW1wdHkoKSkgeworICAgICAgc3RkOjpjb3V0IDw8IHZlcnNpb25faW5mb18gPDwgc3RkOjplbmRsOworICAgIH0KKyAgICBjb3V0IDw8ICJsaWJwcm90b2MgIgorICAgICAgICAgPDwgcHJvdG9idWY6OmludGVybmFsOjpWZXJzaW9uU3RyaW5nKEdPT0dMRV9QUk9UT0JVRl9WRVJTSU9OKQorICAgICAgICAgPDwgZW5kbDsKKyAgICByZXR1cm4gUEFSU0VfQVJHVU1FTlRfRE9ORV9BTkRfRVhJVDsgIC8vIEV4aXQgd2l0aG91dCBydW5uaW5nIGNvbXBpbGVyLgorCisgIH0gZWxzZSBpZiAobmFtZSA9PSAiLS1kaXNhbGxvd19zZXJ2aWNlcyIpIHsKKyAgICBkaXNhbGxvd19zZXJ2aWNlc18gPSB0cnVlOworCisgIH0gZWxzZSBpZiAobmFtZSA9PSAiLS1lbmNvZGUiIHx8IG5hbWUgPT0gIi0tZGVjb2RlIiB8fAorICAgICAgICAgICAgIG5hbWUgPT0gIi0tZGVjb2RlX3JhdyIpIHsKKyAgICBpZiAobW9kZV8gIT0gTU9ERV9DT01QSUxFKSB7CisgICAgICBzdGQ6OmNlcnIgPDwgIk9ubHkgb25lIG9mIC0tZW5jb2RlIGFuZCAtLWRlY29kZSBjYW4gYmUgc3BlY2lmaWVkLiIKKyAgICAgICAgICAgICAgICA8PCBzdGQ6OmVuZGw7CisgICAgICByZXR1cm4gUEFSU0VfQVJHVU1FTlRfRkFJTDsKKyAgICB9CisgICAgaWYgKCFvdXRwdXRfZGlyZWN0aXZlc18uZW1wdHkoKSB8fCAhZGVzY3JpcHRvcl9zZXRfbmFtZV8uZW1wdHkoKSkgeworICAgICAgc3RkOjpjZXJyIDw8ICJDYW5ub3QgdXNlICIgPDwgbmFtZQorICAgICAgICAgICAgICAgIDw8ICIgYW5kIGdlbmVyYXRlIGNvZGUgb3IgZGVzY3JpcHRvcnMgYXQgdGhlIHNhbWUgdGltZS4iCisgICAgICAgICAgICAgICAgPDwgc3RkOjplbmRsOworICAgICAgcmV0dXJuIFBBUlNFX0FSR1VNRU5UX0ZBSUw7CisgICAgfQorCisgICAgbW9kZV8gPSAobmFtZSA9PSAiLS1lbmNvZGUiKSA/IE1PREVfRU5DT0RFIDogTU9ERV9ERUNPREU7CisKKyAgICBpZiAodmFsdWUuZW1wdHkoKSAmJiBuYW1lICE9ICItLWRlY29kZV9yYXciKSB7CisgICAgICBzdGQ6OmNlcnIgPDwgIlR5cGUgbmFtZSBmb3IgIiA8PCBuYW1lIDw8ICIgY2Fubm90IGJlIGJsYW5rLiIgPDwgc3RkOjplbmRsOworICAgICAgaWYgKG5hbWUgPT0gIi0tZGVjb2RlIikgeworICAgICAgICBzdGQ6OmNlcnIgPDwgIlRvIGRlY29kZSBhbiB1bmtub3duIG1lc3NhZ2UsIHVzZSAtLWRlY29kZV9yYXcuIgorICAgICAgICAgICAgICAgICAgPDwgc3RkOjplbmRsOworICAgICAgfQorICAgICAgcmV0dXJuIFBBUlNFX0FSR1VNRU5UX0ZBSUw7CisgICAgfSBlbHNlIGlmICghdmFsdWUuZW1wdHkoKSAmJiBuYW1lID09ICItLWRlY29kZV9yYXciKSB7CisgICAgICBzdGQ6OmNlcnIgPDwgIi0tZGVjb2RlX3JhdyBkb2VzIG5vdCB0YWtlIGEgcGFyYW1ldGVyLiIgPDwgc3RkOjplbmRsOworICAgICAgcmV0dXJuIFBBUlNFX0FSR1VNRU5UX0ZBSUw7CisgICAgfQorCisgICAgY29kZWNfdHlwZV8gPSB2YWx1ZTsKKworICB9IGVsc2UgaWYgKG5hbWUgPT0gIi0tZXJyb3JfZm9ybWF0IikgeworICAgIGlmICh2YWx1ZSA9PSAiZ2NjIikgeworICAgICAgZXJyb3JfZm9ybWF0XyA9IEVSUk9SX0ZPUk1BVF9HQ0M7CisgICAgfSBlbHNlIGlmICh2YWx1ZSA9PSAibXN2cyIpIHsKKyAgICAgIGVycm9yX2Zvcm1hdF8gPSBFUlJPUl9GT1JNQVRfTVNWUzsKKyAgICB9IGVsc2UgeworICAgICAgc3RkOjpjZXJyIDw8ICJVbmtub3duIGVycm9yIGZvcm1hdDogIiA8PCB2YWx1ZSA8PCBzdGQ6OmVuZGw7CisgICAgICByZXR1cm4gUEFSU0VfQVJHVU1FTlRfRkFJTDsKKyAgICB9CisKKyAgfSBlbHNlIGlmIChuYW1lID09ICItLXBsdWdpbiIpIHsKKyAgICBpZiAocGx1Z2luX3ByZWZpeF8uZW1wdHkoKSkgeworICAgICAgc3RkOjpjZXJyIDw8ICJUaGlzIGNvbXBpbGVyIGRvZXMgbm90IHN1cHBvcnQgcGx1Z2lucy4iIDw8IHN0ZDo6ZW5kbDsKKyAgICAgIHJldHVybiBQQVJTRV9BUkdVTUVOVF9GQUlMOworICAgIH0KKworICAgIHN0cmluZyBwbHVnaW5fbmFtZTsKKyAgICBzdHJpbmcgcGF0aDsKKworICAgIHN0cmluZzo6c2l6ZV90eXBlIGVxdWFsc19wb3MgPSB2YWx1ZS5maW5kX2ZpcnN0X29mKCc9Jyk7CisgICAgaWYgKGVxdWFsc19wb3MgPT0gc3RyaW5nOjpucG9zKSB7CisgICAgICAvLyBVc2UgdGhlIGJhc2VuYW1lIG9mIHRoZSBmaWxlLgorICAgICAgc3RyaW5nOjpzaXplX3R5cGUgc2xhc2hfcG9zID0gdmFsdWUuZmluZF9sYXN0X29mKCcvJyk7CisgICAgICBpZiAoc2xhc2hfcG9zID09IHN0cmluZzo6bnBvcykgeworICAgICAgICBwbHVnaW5fbmFtZSA9IHZhbHVlOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcGx1Z2luX25hbWUgPSB2YWx1ZS5zdWJzdHIoc2xhc2hfcG9zICsgMSk7CisgICAgICB9CisgICAgICBwYXRoID0gdmFsdWU7CisgICAgfSBlbHNlIHsKKyAgICAgIHBsdWdpbl9uYW1lID0gdmFsdWUuc3Vic3RyKDAsIGVxdWFsc19wb3MpOworICAgICAgcGF0aCA9IHZhbHVlLnN1YnN0cihlcXVhbHNfcG9zICsgMSk7CisgICAgfQorCisgICAgcGx1Z2luc19bcGx1Z2luX25hbWVdID0gcGF0aDsKKworICB9IGVsc2UgaWYgKG5hbWUgPT0gIi0tcHJpbnRfZnJlZV9maWVsZF9udW1iZXJzIikgeworICAgIGlmIChtb2RlXyAhPSBNT0RFX0NPTVBJTEUpIHsKKyAgICAgIHN0ZDo6Y2VyciA8PCAiQ2Fubm90IHVzZSAiIDw8IG5hbWUKKyAgICAgICAgICAgICAgICA8PCAiIGFuZCB1c2UgLS1lbmNvZGUsIC0tZGVjb2RlIG9yIHByaW50ICIKKyAgICAgICAgICAgICAgICA8PCAib3RoZXIgaW5mbyBhdCB0aGUgc2FtZSB0aW1lLiIgPDwgc3RkOjplbmRsOworICAgICAgcmV0dXJuIFBBUlNFX0FSR1VNRU5UX0ZBSUw7CisgICAgfQorICAgIGlmICghb3V0cHV0X2RpcmVjdGl2ZXNfLmVtcHR5KCkgfHwgIWRlc2NyaXB0b3Jfc2V0X25hbWVfLmVtcHR5KCkpIHsKKyAgICAgIHN0ZDo6Y2VyciA8PCAiQ2Fubm90IHVzZSAiIDw8IG5hbWUKKyAgICAgICAgICAgICAgICA8PCAiIGFuZCBnZW5lcmF0ZSBjb2RlIG9yIGRlc2NyaXB0b3JzIGF0IHRoZSBzYW1lIHRpbWUuIgorICAgICAgICAgICAgICAgIDw8IHN0ZDo6ZW5kbDsKKyAgICAgIHJldHVybiBQQVJTRV9BUkdVTUVOVF9GQUlMOworICAgIH0KKyAgICBtb2RlXyA9IE1PREVfUFJJTlQ7CisgICAgcHJpbnRfbW9kZV8gPSBQUklOVF9GUkVFX0ZJRUxEUzsKKyAgfSBlbHNlIHsKKyAgICAvLyBTb21lIG90aGVyIGZsYWcuICBMb29rIGl0IHVwIGluIHRoZSBnZW5lcmF0b3JzIGxpc3QuCisgICAgY29uc3QgR2VuZXJhdG9ySW5mbyogZ2VuZXJhdG9yX2luZm8gPQorICAgICAgICBGaW5kT3JOdWxsKGdlbmVyYXRvcnNfYnlfZmxhZ19uYW1lXywgbmFtZSk7CisgICAgaWYgKGdlbmVyYXRvcl9pbmZvID09IE5VTEwgJiYKKyAgICAgICAgKHBsdWdpbl9wcmVmaXhfLmVtcHR5KCkgfHwgIUhhc1N1ZmZpeFN0cmluZyhuYW1lLCAiX291dCIpKSkgeworICAgICAgLy8gQ2hlY2sgaWYgaXQncyBhIGdlbmVyYXRvciBvcHRpb24gZmxhZy4KKyAgICAgIGdlbmVyYXRvcl9pbmZvID0gRmluZE9yTnVsbChnZW5lcmF0b3JzX2J5X29wdGlvbl9uYW1lXywgbmFtZSk7CisgICAgICBpZiAoZ2VuZXJhdG9yX2luZm8gPT0gTlVMTCkgeworICAgICAgICBzdGQ6OmNlcnIgPDwgIlVua25vd24gZmxhZzogIiA8PCBuYW1lIDw8IHN0ZDo6ZW5kbDsKKyAgICAgICAgcmV0dXJuIFBBUlNFX0FSR1VNRU5UX0ZBSUw7CisgICAgICB9IGVsc2UgeworICAgICAgICBzdHJpbmcqIHBhcmFtZXRlcnMgPSAmZ2VuZXJhdG9yX3BhcmFtZXRlcnNfW2dlbmVyYXRvcl9pbmZvLT5mbGFnX25hbWVdOworICAgICAgICBpZiAoIXBhcmFtZXRlcnMtPmVtcHR5KCkpIHsKKyAgICAgICAgICBwYXJhbWV0ZXJzLT5hcHBlbmQoIiwiKTsKKyAgICAgICAgfQorICAgICAgICBwYXJhbWV0ZXJzLT5hcHBlbmQodmFsdWUpOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICAvLyBJdCdzIGFuIG91dHB1dCBmbGFnLiAgQWRkIGl0IHRvIHRoZSBvdXRwdXQgZGlyZWN0aXZlcy4KKyAgICAgIGlmIChtb2RlXyAhPSBNT0RFX0NPTVBJTEUpIHsKKyAgICAgICAgc3RkOjpjZXJyIDw8ICJDYW5ub3QgdXNlIC0tZW5jb2RlLCAtLWRlY29kZSBvciBwcmludCAucHJvdG8gaW5mbyBhbmQgIgorICAgICAgICAgICAgICAgICAgICAgImdlbmVyYXRlIGNvZGUgYXQgdGhlIHNhbWUgdGltZS4iIDw8IHN0ZDo6ZW5kbDsKKyAgICAgICAgcmV0dXJuIFBBUlNFX0FSR1VNRU5UX0ZBSUw7CisgICAgICB9CisKKyAgICAgIE91dHB1dERpcmVjdGl2ZSBkaXJlY3RpdmU7CisgICAgICBkaXJlY3RpdmUubmFtZSA9IG5hbWU7CisgICAgICBpZiAoZ2VuZXJhdG9yX2luZm8gPT0gTlVMTCkgeworICAgICAgICBkaXJlY3RpdmUuZ2VuZXJhdG9yID0gTlVMTDsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGRpcmVjdGl2ZS5nZW5lcmF0b3IgPSBnZW5lcmF0b3JfaW5mby0+Z2VuZXJhdG9yOworICAgICAgfQorCisgICAgICAvLyBTcGxpdCB2YWx1ZSBhdCAnOicgdG8gc2VwYXJhdGUgdGhlIGdlbmVyYXRvciBwYXJhbWV0ZXIgZnJvbSB0aGUKKyAgICAgIC8vIGZpbGVuYW1lLiAgSG93ZXZlciwgYXZvaWQgZG9pbmcgdGhpcyBpZiB0aGUgY29sb24gaXMgcGFydCBvZiBhIHZhbGlkCisgICAgICAvLyBXaW5kb3dzLXN0eWxlIGFic29sdXRlIHBhdGguCisgICAgICBzdHJpbmc6OnNpemVfdHlwZSBjb2xvbl9wb3MgPSB2YWx1ZS5maW5kX2ZpcnN0X29mKCc6Jyk7CisgICAgICBpZiAoY29sb25fcG9zID09IHN0cmluZzo6bnBvcyB8fCBJc1dpbmRvd3NBYnNvbHV0ZVBhdGgodmFsdWUpKSB7CisgICAgICAgIGRpcmVjdGl2ZS5vdXRwdXRfbG9jYXRpb24gPSB2YWx1ZTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGRpcmVjdGl2ZS5wYXJhbWV0ZXIgPSB2YWx1ZS5zdWJzdHIoMCwgY29sb25fcG9zKTsKKyAgICAgICAgZGlyZWN0aXZlLm91dHB1dF9sb2NhdGlvbiA9IHZhbHVlLnN1YnN0cihjb2xvbl9wb3MgKyAxKTsKKyAgICAgIH0KKworICAgICAgb3V0cHV0X2RpcmVjdGl2ZXNfLnB1c2hfYmFjayhkaXJlY3RpdmUpOworICAgIH0KKyAgfQorCisgIHJldHVybiBQQVJTRV9BUkdVTUVOVF9ET05FX0FORF9DT05USU5VRTsKK30KKwordm9pZCBDb21tYW5kTGluZUludGVyZmFjZTo6UHJpbnRIZWxwVGV4dCgpIHsKKyAgLy8gU29ycnkgZm9yIGluZGVudGF0aW9uIGhlcmU7IGxpbmUgd3JhcHBpbmcgd291bGQgYmUgdWdsaWVyLgorICBzdGQ6OmNlcnIgPDwKKyJVc2FnZTogIiA8PCBleGVjdXRhYmxlX25hbWVfIDw8ICIgW09QVElPTl0gUFJPVE9fRklMRVNcbiIKKyJQYXJzZSBQUk9UT19GSUxFUyBhbmQgZ2VuZXJhdGUgb3V0cHV0IGJhc2VkIG9uIHRoZSBvcHRpb25zIGdpdmVuOlxuIgorIiAgLUlQQVRILCAtLXByb3RvX3BhdGg9UEFUSCAgIFNwZWNpZnkgdGhlIGRpcmVjdG9yeSBpbiB3aGljaCB0byBzZWFyY2ggZm9yXG4iCisiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1wb3J0cy4gIE1heSBiZSBzcGVjaWZpZWQgbXVsdGlwbGUgdGltZXM7XG4iCisiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlyZWN0b3JpZXMgd2lsbCBiZSBzZWFyY2hlZCBpbiBvcmRlci4gIElmIG5vdFxuIgorIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdpdmVuLCB0aGUgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeSBpcyB1c2VkLlxuIgorIiAgLS12ZXJzaW9uICAgICAgICAgICAgICAgICAgIFNob3cgdmVyc2lvbiBpbmZvIGFuZCBleGl0LlxuIgorIiAgLWgsIC0taGVscCAgICAgICAgICAgICAgICAgIFNob3cgdGhpcyB0ZXh0IGFuZCBleGl0LlxuIgorIiAgLS1lbmNvZGU9TUVTU0FHRV9UWVBFICAgICAgIFJlYWQgYSB0ZXh0LWZvcm1hdCBtZXNzYWdlIG9mIHRoZSBnaXZlbiB0eXBlXG4iCisiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJvbSBzdGFuZGFyZCBpbnB1dCBhbmQgd3JpdGUgaXQgaW4gYmluYXJ5XG4iCisiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG8gc3RhbmRhcmQgb3V0cHV0LiAgVGhlIG1lc3NhZ2UgdHlwZSBtdXN0XG4iCisiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmUgZGVmaW5lZCBpbiBQUk9UT19GSUxFUyBvciB0aGVpciBpbXBvcnRzLlxuIgorIiAgLS1kZWNvZGU9TUVTU0FHRV9UWVBFICAgICAgIFJlYWQgYSBiaW5hcnkgbWVzc2FnZSBvZiB0aGUgZ2l2ZW4gdHlwZSBmcm9tXG4iCisiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhbmRhcmQgaW5wdXQgYW5kIHdyaXRlIGl0IGluIHRleHQgZm9ybWF0XG4iCisiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG8gc3RhbmRhcmQgb3V0cHV0LiAgVGhlIG1lc3NhZ2UgdHlwZSBtdXN0XG4iCisiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmUgZGVmaW5lZCBpbiBQUk9UT19GSUxFUyBvciB0aGVpciBpbXBvcnRzLlxuIgorIiAgLS1kZWNvZGVfcmF3ICAgICAgICAgICAgICAgIFJlYWQgYW4gYXJiaXRyYXJ5IHByb3RvY29sIG1lc3NhZ2UgZnJvbVxuIgorIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YW5kYXJkIGlucHV0IGFuZCB3cml0ZSB0aGUgcmF3IHRhZy92YWx1ZVxuIgorIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhaXJzIGluIHRleHQgZm9ybWF0IHRvIHN0YW5kYXJkIG91dHB1dC4gIE5vXG4iCisiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUFJPVE9fRklMRVMgc2hvdWxkIGJlIGdpdmVuIHdoZW4gdXNpbmcgdGhpc1xuIgorIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZsYWcuXG4iCisiICAtb0ZJTEUsICAgICAgICAgICAgICAgICAgICAgV3JpdGVzIGEgRmlsZURlc2NyaXB0b3JTZXQgKGEgcHJvdG9jb2wgYnVmZmVyLFxuIgorIiAgICAtLWRlc2NyaXB0b3Jfc2V0X291dD1GSUxFIGRlZmluZWQgaW4gZGVzY3JpcHRvci5wcm90bykgY29udGFpbmluZyBhbGwgb2ZcbiIKKyIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgaW5wdXQgZmlsZXMgdG8gRklMRS5cbiIKKyIgIC0taW5jbHVkZV9pbXBvcnRzICAgICAgICAgICBXaGVuIHVzaW5nIC0tZGVzY3JpcHRvcl9zZXRfb3V0LCBhbHNvIGluY2x1ZGVcbiIKKyIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbGwgZGVwZW5kZW5jaWVzIG9mIHRoZSBpbnB1dCBmaWxlcyBpbiB0aGVcbiIKKyIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXQsIHNvIHRoYXQgdGhlIHNldCBpcyBzZWxmLWNvbnRhaW5lZC5cbiIKKyIgIC0taW5jbHVkZV9zb3VyY2VfaW5mbyAgICAgICBXaGVuIHVzaW5nIC0tZGVzY3JpcHRvcl9zZXRfb3V0LCBkbyBub3Qgc3RyaXBcbiIKKyIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTb3VyY2VDb2RlSW5mbyBmcm9tIHRoZSBGaWxlRGVzY3JpcHRvclByb3RvLlxuIgorIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMgcmVzdWx0cyBpbiB2YXN0bHkgbGFyZ2VyIGRlc2NyaXB0b3JzIHRoYXRcbiIKKyIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmNsdWRlIGluZm9ybWF0aW9uIGFib3V0IHRoZSBvcmlnaW5hbFxuIgorIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2F0aW9uIG9mIGVhY2ggZGVjbCBpbiB0aGUgc291cmNlIGZpbGUgYXNcbiIKKyIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3ZWxsIGFzIHN1cnJvdW5kaW5nIGNvbW1lbnRzLlxuIgorIiAgLS1kZXBlbmRlbmN5X291dD1GSUxFICAgICAgIFdyaXRlIGEgZGVwZW5kZW5jeSBvdXRwdXQgZmlsZSBpbiB0aGUgZm9ybWF0XG4iCisiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwZWN0ZWQgYnkgbWFrZS4gVGhpcyB3cml0ZXMgdGhlIHRyYW5zaXRpdmVcbiIKKyIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXQgb2YgaW5wdXQgZmlsZSBwYXRocyB0byBGSUxFXG4iCisiICAtLWVycm9yX2Zvcm1hdD1GT1JNQVQgICAgICAgU2V0IHRoZSBmb3JtYXQgaW4gd2hpY2ggdG8gcHJpbnQgZXJyb3JzLlxuIgorIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZPUk1BVCBtYXkgYmUgJ2djYycgKHRoZSBkZWZhdWx0KSBvciAnbXN2cydcbiIKKyIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTWljcm9zb2Z0IFZpc3VhbCBTdHVkaW8gZm9ybWF0KS5cbiIKKyIgIC0tcHJpbnRfZnJlZV9maWVsZF9udW1iZXJzICBQcmludCB0aGUgZnJlZSBmaWVsZCBudW1iZXJzIG9mIHRoZSBtZXNzYWdlc1xuIgorIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmluZWQgaW4gdGhlIGdpdmVuIHByb3RvIGZpbGVzLiBHcm91cHMgc2hhcmVcbiIKKyIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgc2FtZSBmaWVsZCBudW1iZXIgc3BhY2Ugd2l0aCB0aGUgcGFyZW50IFxuIgorIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuIEV4dGVuc2lvbiByYW5nZXMgYXJlIGNvdW50ZWQgYXMgXG4iCisiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2NjdXBpZWQgZmllbGRzIG51bWJlcnMuXG4iCisgICAgICA8PCBzdGQ6OmVuZGw7CisgIGlmICghcGx1Z2luX3ByZWZpeF8uZW1wdHkoKSkgeworICAgIHN0ZDo6Y2VyciA8PAorIiAgLS1wbHVnaW49RVhFQ1VUQUJMRSAgICAgICAgIFNwZWNpZmllcyBhIHBsdWdpbiBleGVjdXRhYmxlIHRvIHVzZS5cbiIKKyIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOb3JtYWxseSwgcHJvdG9jIHNlYXJjaGVzIHRoZSBQQVRIIGZvclxuIgorIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsdWdpbnMsIGJ1dCB5b3UgbWF5IHNwZWNpZnkgYWRkaXRpb25hbFxuIgorIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4ZWN1dGFibGVzIG5vdCBpbiB0aGUgcGF0aCB1c2luZyB0aGlzIGZsYWcuXG4iCisiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQWRkaXRpb25hbGx5LCBFWEVDVVRBQkxFIG1heSBiZSBvZiB0aGUgZm9ybVxuIgorIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5BTUU9UEFUSCwgaW4gd2hpY2ggY2FzZSB0aGUgZ2l2ZW4gcGx1Z2luIG5hbWVcbiIKKyIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpcyBtYXBwZWQgdG8gdGhlIGdpdmVuIGV4ZWN1dGFibGUgZXZlbiBpZlxuIgorIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBleGVjdXRhYmxlJ3Mgb3duIG5hbWUgZGlmZmVycy4iIDw8IHN0ZDo6ZW5kbDsKKyAgfQorCisgIGZvciAoR2VuZXJhdG9yTWFwOjppdGVyYXRvciBpdGVyID0gZ2VuZXJhdG9yc19ieV9mbGFnX25hbWVfLmJlZ2luKCk7CisgICAgICAgaXRlciAhPSBnZW5lcmF0b3JzX2J5X2ZsYWdfbmFtZV8uZW5kKCk7ICsraXRlcikgeworICAgIC8vIEZJWE1FKGtlbnRvbik6ICBJZiB0aGUgdGV4dCBpcyBsb25nIGVub3VnaCBpdCB3aWxsIHdyYXAsIHdoaWNoIGlzIHVnbHksCisgICAgLy8gICBidXQgZml4aW5nIHRoaXMgbmljZWx5IChlLmcuIHNwbGl0dGluZyBvbiBzcGFjZXMpIGlzIHByb2JhYmx5IG1vcmUKKyAgICAvLyAgIHRyb3VibGUgdGhhbiBpdCdzIHdvcnRoLgorICAgIHN0ZDo6Y2VyciA8PCAiICAiIDw8IGl0ZXItPmZpcnN0IDw8ICI9T1VUX0RJUiAiCisgICAgICAgICAgICAgIDw8IHN0cmluZygxOSAtIGl0ZXItPmZpcnN0LnNpemUoKSwgJyAnKSAgLy8gU3BhY2VzIGZvciBhbGlnbm1lbnQuCisgICAgICAgICAgICAgIDw8IGl0ZXItPnNlY29uZC5oZWxwX3RleHQgPDwgc3RkOjplbmRsOworICB9Cit9CisKK2Jvb2wgQ29tbWFuZExpbmVJbnRlcmZhY2U6OkdlbmVyYXRlT3V0cHV0KAorICAgIGNvbnN0IHZlY3Rvcjxjb25zdCBGaWxlRGVzY3JpcHRvcio+JiBwYXJzZWRfZmlsZXMsCisgICAgY29uc3QgT3V0cHV0RGlyZWN0aXZlJiBvdXRwdXRfZGlyZWN0aXZlLAorICAgIEdlbmVyYXRvckNvbnRleHQqIGdlbmVyYXRvcl9jb250ZXh0KSB7CisgIC8vIENhbGwgdGhlIGdlbmVyYXRvci4KKyAgc3RyaW5nIGVycm9yOworICBpZiAob3V0cHV0X2RpcmVjdGl2ZS5nZW5lcmF0b3IgPT0gTlVMTCkgeworICAgIC8vIFRoaXMgaXMgYSBwbHVnaW4uCisgICAgR09PR0xFX0NIRUNLKEhhc1ByZWZpeFN0cmluZyhvdXRwdXRfZGlyZWN0aXZlLm5hbWUsICItLSIpICYmCisgICAgICAgICAgSGFzU3VmZml4U3RyaW5nKG91dHB1dF9kaXJlY3RpdmUubmFtZSwgIl9vdXQiKSkKKyAgICAgICAgPDwgIkJhZCBuYW1lIGZvciBwbHVnaW4gZ2VuZXJhdG9yOiAiIDw8IG91dHB1dF9kaXJlY3RpdmUubmFtZTsKKworICAgIC8vIFN0cmlwIHRoZSAiLS0iIGFuZCAiX291dCIgYW5kIGFkZCB0aGUgcGx1Z2luIHByZWZpeC4KKyAgICBzdHJpbmcgcGx1Z2luX25hbWUgPSBwbHVnaW5fcHJlZml4XyArICJnZW4tIiArCisgICAgICAgIG91dHB1dF9kaXJlY3RpdmUubmFtZS5zdWJzdHIoMiwgb3V0cHV0X2RpcmVjdGl2ZS5uYW1lLnNpemUoKSAtIDYpOworCisgICAgaWYgKCFHZW5lcmF0ZVBsdWdpbk91dHB1dChwYXJzZWRfZmlsZXMsIHBsdWdpbl9uYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0X2RpcmVjdGl2ZS5wYXJhbWV0ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW5lcmF0b3JfY29udGV4dCwgJmVycm9yKSkgeworICAgICAgc3RkOjpjZXJyIDw8IG91dHB1dF9kaXJlY3RpdmUubmFtZSA8PCAiOiAiIDw8IGVycm9yIDw8IHN0ZDo6ZW5kbDsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgLy8gUmVndWxhciBnZW5lcmF0b3IuCisgICAgc3RyaW5nIHBhcmFtZXRlcnMgPSBvdXRwdXRfZGlyZWN0aXZlLnBhcmFtZXRlcjsKKyAgICBpZiAoIWdlbmVyYXRvcl9wYXJhbWV0ZXJzX1tvdXRwdXRfZGlyZWN0aXZlLm5hbWVdLmVtcHR5KCkpIHsKKyAgICAgIGlmICghcGFyYW1ldGVycy5lbXB0eSgpKSB7CisgICAgICAgIHBhcmFtZXRlcnMuYXBwZW5kKCIsIik7CisgICAgICB9CisgICAgICBwYXJhbWV0ZXJzLmFwcGVuZChnZW5lcmF0b3JfcGFyYW1ldGVyc19bb3V0cHV0X2RpcmVjdGl2ZS5uYW1lXSk7CisgICAgfQorICAgIGlmIChvdXRwdXRfZGlyZWN0aXZlLmdlbmVyYXRvci0+SGFzR2VuZXJhdGVBbGwoKSkgeworICAgICAgaWYgKCFvdXRwdXRfZGlyZWN0aXZlLmdlbmVyYXRvci0+R2VuZXJhdGVBbGwoCisgICAgICAgICAgcGFyc2VkX2ZpbGVzLCBwYXJhbWV0ZXJzLCBnZW5lcmF0b3JfY29udGV4dCwgJmVycm9yKSkgeworICAgICAgICAgIC8vIEdlbmVyYXRvciByZXR1cm5lZCBhbiBlcnJvci4KKyAgICAgICAgICBzdGQ6OmNlcnIgPDwgb3V0cHV0X2RpcmVjdGl2ZS5uYW1lIDw8ICI6ICIKKyAgICAgICAgICAgICAgICAgICAgPDwgIjogIiA8PCBlcnJvciA8PCBzdGQ6OmVuZGw7CisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhcnNlZF9maWxlcy5zaXplKCk7IGkrKykgeworICAgICAgICBpZiAoIW91dHB1dF9kaXJlY3RpdmUuZ2VuZXJhdG9yLT5HZW5lcmF0ZShwYXJzZWRfZmlsZXNbaV0sIHBhcmFtZXRlcnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlbmVyYXRvcl9jb250ZXh0LCAmZXJyb3IpKSB7CisgICAgICAgICAgLy8gR2VuZXJhdG9yIHJldHVybmVkIGFuIGVycm9yLgorICAgICAgICAgIHN0ZDo6Y2VyciA8PCBvdXRwdXRfZGlyZWN0aXZlLm5hbWUgPDwgIjogIiA8PCBwYXJzZWRfZmlsZXNbaV0tPm5hbWUoKQorICAgICAgICAgICAgICAgICAgICA8PCAiOiAiIDw8IGVycm9yIDw8IHN0ZDo6ZW5kbDsKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgIH0KKworICByZXR1cm4gdHJ1ZTsKK30KKworYm9vbCBDb21tYW5kTGluZUludGVyZmFjZTo6R2VuZXJhdGVEZXBlbmRlbmN5TWFuaWZlc3RGaWxlKAorICAgIGNvbnN0IHZlY3Rvcjxjb25zdCBGaWxlRGVzY3JpcHRvcio+JiBwYXJzZWRfZmlsZXMsCisgICAgY29uc3QgR2VuZXJhdG9yQ29udGV4dE1hcCYgb3V0cHV0X2RpcmVjdG9yaWVzLAorICAgIERpc2tTb3VyY2VUcmVlKiBzb3VyY2VfdHJlZSkgeworICBGaWxlRGVzY3JpcHRvclNldCBmaWxlX3NldDsKKworICBzZXQ8Y29uc3QgRmlsZURlc2NyaXB0b3IqPiBhbHJlYWR5X3NlZW47CisgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFyc2VkX2ZpbGVzLnNpemUoKTsgaSsrKSB7CisgICAgR2V0VHJhbnNpdGl2ZURlcGVuZGVuY2llcyhwYXJzZWRfZmlsZXNbaV0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmFscmVhZHlfc2VlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVfc2V0Lm11dGFibGVfZmlsZSgpKTsKKyAgfQorCisgIHZlY3RvcjxzdHJpbmc+IG91dHB1dF9maWxlbmFtZXM7CisgIGZvciAoR2VuZXJhdG9yQ29udGV4dE1hcDo6Y29uc3RfaXRlcmF0b3IgaXRlciA9IG91dHB1dF9kaXJlY3Rvcmllcy5iZWdpbigpOworICAgICAgIGl0ZXIgIT0gb3V0cHV0X2RpcmVjdG9yaWVzLmVuZCgpOyArK2l0ZXIpIHsKKyAgICBjb25zdCBzdHJpbmcmIGxvY2F0aW9uID0gaXRlci0+Zmlyc3Q7CisgICAgR2VuZXJhdG9yQ29udGV4dEltcGwqIGRpcmVjdG9yeSA9IGl0ZXItPnNlY29uZDsKKyAgICB2ZWN0b3I8c3RyaW5nPiByZWxhdGl2ZV9vdXRwdXRfZmlsZW5hbWVzOworICAgIGRpcmVjdG9yeS0+R2V0T3V0cHV0RmlsZW5hbWVzKCZyZWxhdGl2ZV9vdXRwdXRfZmlsZW5hbWVzKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlbGF0aXZlX291dHB1dF9maWxlbmFtZXMuc2l6ZSgpOyBpKyspIHsKKyAgICAgIHN0cmluZyBvdXRwdXRfZmlsZW5hbWUgPSBsb2NhdGlvbiArIHJlbGF0aXZlX291dHB1dF9maWxlbmFtZXNbaV07CisgICAgICBpZiAob3V0cHV0X2ZpbGVuYW1lLmNvbXBhcmUoMCwgMiwgIi4vIikgPT0gMCkgeworICAgICAgICBvdXRwdXRfZmlsZW5hbWUgPSBvdXRwdXRfZmlsZW5hbWUuc3Vic3RyKDIpOworICAgICAgfQorICAgICAgb3V0cHV0X2ZpbGVuYW1lcy5wdXNoX2JhY2sob3V0cHV0X2ZpbGVuYW1lKTsKKyAgICB9CisgIH0KKworICBpbnQgZmQ7CisgIGRvIHsKKyAgICBmZCA9IG9wZW4oZGVwZW5kZW5jeV9vdXRfbmFtZV8uY19zdHIoKSwKKyAgICAgICAgICAgICAgT19XUk9OTFkgfCBPX0NSRUFUIHwgT19UUlVOQyB8IE9fQklOQVJZLCAwNjY2KTsKKyAgfSB3aGlsZSAoZmQgPCAwICYmIGVycm5vID09IEVJTlRSKTsKKworICBpZiAoZmQgPCAwKSB7CisgICAgcGVycm9yKGRlcGVuZGVuY3lfb3V0X25hbWVfLmNfc3RyKCkpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIGlvOjpGaWxlT3V0cHV0U3RyZWFtIG91dChmZCk7CisgIGlvOjpQcmludGVyIHByaW50ZXIoJm91dCwgJyQnKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IG91dHB1dF9maWxlbmFtZXMuc2l6ZSgpOyBpKyspIHsKKyAgICBwcmludGVyLlByaW50KG91dHB1dF9maWxlbmFtZXNbaV0uY19zdHIoKSk7CisgICAgaWYgKGkgPT0gb3V0cHV0X2ZpbGVuYW1lcy5zaXplKCkgLSAxKSB7CisgICAgICBwcmludGVyLlByaW50KCI6Iik7CisgICAgfSBlbHNlIHsKKyAgICAgIHByaW50ZXIuUHJpbnQoIiBcXFxuIik7CisgICAgfQorICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlX3NldC5maWxlX3NpemUoKTsgaSsrKSB7CisgICAgY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byYgZmlsZSA9IGZpbGVfc2V0LmZpbGUoaSk7CisgICAgY29uc3Qgc3RyaW5nJiB2aXJ0dWFsX2ZpbGUgPSBmaWxlLm5hbWUoKTsKKyAgICBzdHJpbmcgZGlza19maWxlOworICAgIGlmIChzb3VyY2VfdHJlZSAmJgorICAgICAgICBzb3VyY2VfdHJlZS0+VmlydHVhbEZpbGVUb0Rpc2tGaWxlKHZpcnR1YWxfZmlsZSwgJmRpc2tfZmlsZSkpIHsKKyAgICAgIHByaW50ZXIuUHJpbnQoIiAkZGlza19maWxlJCIsICJkaXNrX2ZpbGUiLCBkaXNrX2ZpbGUpOworICAgICAgaWYgKGkgPCBmaWxlX3NldC5maWxlX3NpemUoKSAtIDEpIHByaW50ZXIuUHJpbnQoIlxcXG4iKTsKKyAgICB9IGVsc2UgeworICAgICAgc3RkOjpjZXJyIDw8ICJVbmFibGUgdG8gaWRlbnRpZnkgcGF0aCBmb3IgZmlsZSAiIDw8IHZpcnR1YWxfZmlsZQorICAgICAgICAgICAgICAgIDw8IHN0ZDo6ZW5kbDsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0KKworICByZXR1cm4gdHJ1ZTsKK30KKworYm9vbCBDb21tYW5kTGluZUludGVyZmFjZTo6R2VuZXJhdGVQbHVnaW5PdXRwdXQoCisgICAgY29uc3QgdmVjdG9yPGNvbnN0IEZpbGVEZXNjcmlwdG9yKj4mIHBhcnNlZF9maWxlcywKKyAgICBjb25zdCBzdHJpbmcmIHBsdWdpbl9uYW1lLAorICAgIGNvbnN0IHN0cmluZyYgcGFyYW1ldGVyLAorICAgIEdlbmVyYXRvckNvbnRleHQqIGdlbmVyYXRvcl9jb250ZXh0LAorICAgIHN0cmluZyogZXJyb3IpIHsKKyAgQ29kZUdlbmVyYXRvclJlcXVlc3QgcmVxdWVzdDsKKyAgQ29kZUdlbmVyYXRvclJlc3BvbnNlIHJlc3BvbnNlOworCisgIC8vIEJ1aWxkIHRoZSByZXF1ZXN0LgorICBpZiAoIXBhcmFtZXRlci5lbXB0eSgpKSB7CisgICAgcmVxdWVzdC5zZXRfcGFyYW1ldGVyKHBhcmFtZXRlcik7CisgIH0KKworICBzZXQ8Y29uc3QgRmlsZURlc2NyaXB0b3IqPiBhbHJlYWR5X3NlZW47CisgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFyc2VkX2ZpbGVzLnNpemUoKTsgaSsrKSB7CisgICAgcmVxdWVzdC5hZGRfZmlsZV90b19nZW5lcmF0ZShwYXJzZWRfZmlsZXNbaV0tPm5hbWUoKSk7CisgICAgR2V0VHJhbnNpdGl2ZURlcGVuZGVuY2llcyhwYXJzZWRfZmlsZXNbaV0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlLCAgLy8gSW5jbHVkZSBqc29uX25hbWUgZm9yIHBsdWdpbnMuCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlLCAgLy8gSW5jbHVkZSBzb3VyY2UgY29kZSBpbmZvLgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmFscmVhZHlfc2VlbiwgcmVxdWVzdC5tdXRhYmxlX3Byb3RvX2ZpbGUoKSk7CisgIH0KKworICAvLyBJbnZva2UgdGhlIHBsdWdpbi4KKyAgU3VicHJvY2VzcyBzdWJwcm9jZXNzOworCisgIGlmIChwbHVnaW5zXy5jb3VudChwbHVnaW5fbmFtZSkgPiAwKSB7CisgICAgc3VicHJvY2Vzcy5TdGFydChwbHVnaW5zX1twbHVnaW5fbmFtZV0sIFN1YnByb2Nlc3M6OkVYQUNUX05BTUUpOworICB9IGVsc2UgeworICAgIHN1YnByb2Nlc3MuU3RhcnQocGx1Z2luX25hbWUsIFN1YnByb2Nlc3M6OlNFQVJDSF9QQVRIKTsKKyAgfQorCisgIHN0cmluZyBjb21tdW5pY2F0ZV9lcnJvcjsKKyAgaWYgKCFzdWJwcm9jZXNzLkNvbW11bmljYXRlKHJlcXVlc3QsICZyZXNwb25zZSwgJmNvbW11bmljYXRlX2Vycm9yKSkgeworICAgICplcnJvciA9IHN0cmluZ3M6OlN1YnN0aXR1dGUoIiQwOiAkMSIsIHBsdWdpbl9uYW1lLCBjb21tdW5pY2F0ZV9lcnJvcik7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8gV3JpdGUgdGhlIGZpbGVzLiAgV2UgZG8gdGhpcyBldmVuIGlmIHRoZXJlIHdhcyBhIGdlbmVyYXRvciBlcnJvciBpbiBvcmRlcgorICAvLyB0byBtYXRjaCB0aGUgYmVoYXZpb3Igb2YgYSBjb21waWxlZC1pbiBnZW5lcmF0b3IuCisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8aW86Olplcm9Db3B5T3V0cHV0U3RyZWFtPiBjdXJyZW50X291dHB1dDsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXNwb25zZS5maWxlX3NpemUoKTsgaSsrKSB7CisgICAgY29uc3QgQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpGaWxlJiBvdXRwdXRfZmlsZSA9IHJlc3BvbnNlLmZpbGUoaSk7CisKKyAgICBpZiAoIW91dHB1dF9maWxlLmluc2VydGlvbl9wb2ludCgpLmVtcHR5KCkpIHsKKyAgICAgIC8vIE9wZW4gYSBmaWxlIGZvciBpbnNlcnQuCisgICAgICAvLyBXZSByZXNldCBjdXJyZW50X291dHB1dCB0byBOVUxMIGZpcnN0IHNvIHRoYXQgdGhlIG9sZCBmaWxlIGlzIGNsb3NlZAorICAgICAgLy8gYmVmb3JlIHRoZSBuZXcgb25lIGlzIG9wZW5lZC4KKyAgICAgIGN1cnJlbnRfb3V0cHV0LnJlc2V0KCk7CisgICAgICBjdXJyZW50X291dHB1dC5yZXNldChnZW5lcmF0b3JfY29udGV4dC0+T3BlbkZvckluc2VydCgKKyAgICAgICAgICBvdXRwdXRfZmlsZS5uYW1lKCksIG91dHB1dF9maWxlLmluc2VydGlvbl9wb2ludCgpKSk7CisgICAgfSBlbHNlIGlmICghb3V0cHV0X2ZpbGUubmFtZSgpLmVtcHR5KCkpIHsKKyAgICAgIC8vIFN0YXJ0aW5nIGEgbmV3IGZpbGUuICBPcGVuIGl0LgorICAgICAgLy8gV2UgcmVzZXQgY3VycmVudF9vdXRwdXQgdG8gTlVMTCBmaXJzdCBzbyB0aGF0IHRoZSBvbGQgZmlsZSBpcyBjbG9zZWQKKyAgICAgIC8vIGJlZm9yZSB0aGUgbmV3IG9uZSBpcyBvcGVuZWQuCisgICAgICBjdXJyZW50X291dHB1dC5yZXNldCgpOworICAgICAgY3VycmVudF9vdXRwdXQucmVzZXQoZ2VuZXJhdG9yX2NvbnRleHQtPk9wZW4ob3V0cHV0X2ZpbGUubmFtZSgpKSk7CisgICAgfSBlbHNlIGlmIChjdXJyZW50X291dHB1dCA9PSBOVUxMKSB7CisgICAgICAqZXJyb3IgPSBzdHJpbmdzOjpTdWJzdGl0dXRlKAorICAgICAgICAiJDA6IEZpcnN0IGZpbGUgY2h1bmsgcmV0dXJuZWQgYnkgcGx1Z2luIGRpZCBub3Qgc3BlY2lmeSBhIGZpbGUgbmFtZS4iLAorICAgICAgICBwbHVnaW5fbmFtZSk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLy8gVXNlIENvZGVkT3V0cHV0U3RyZWFtIGZvciBjb252ZW5pZW5jZTsgb3RoZXJ3aXNlIHdlJ2QgbmVlZCB0byBwcm92aWRlCisgICAgLy8gb3VyIG93biBidWZmZXItY29weWluZyBsb29wLgorICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSB3cml0ZXIoY3VycmVudF9vdXRwdXQuZ2V0KCkpOworICAgIHdyaXRlci5Xcml0ZVN0cmluZyhvdXRwdXRfZmlsZS5jb250ZW50KCkpOworICB9CisKKyAgLy8gQ2hlY2sgZm9yIGVycm9ycy4KKyAgaWYgKCFyZXNwb25zZS5lcnJvcigpLmVtcHR5KCkpIHsKKyAgICAvLyBHZW5lcmF0b3IgcmV0dXJuZWQgYW4gZXJyb3IuCisgICAgKmVycm9yID0gcmVzcG9uc2UuZXJyb3IoKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICByZXR1cm4gdHJ1ZTsKK30KKworYm9vbCBDb21tYW5kTGluZUludGVyZmFjZTo6RW5jb2RlT3JEZWNvZGUoY29uc3QgRGVzY3JpcHRvclBvb2wqIHBvb2wpIHsKKyAgLy8gTG9vayB1cCB0aGUgdHlwZS4KKyAgY29uc3QgRGVzY3JpcHRvciogdHlwZSA9IHBvb2wtPkZpbmRNZXNzYWdlVHlwZUJ5TmFtZShjb2RlY190eXBlXyk7CisgIGlmICh0eXBlID09IE5VTEwpIHsKKyAgICBzdGQ6OmNlcnIgPDwgIlR5cGUgbm90IGRlZmluZWQ6ICIgPDwgY29kZWNfdHlwZV8gPDwgc3RkOjplbmRsOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIER5bmFtaWNNZXNzYWdlRmFjdG9yeSBkeW5hbWljX2ZhY3RvcnkocG9vbCk7CisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8TWVzc2FnZT4gbWVzc2FnZShkeW5hbWljX2ZhY3RvcnkuR2V0UHJvdG90eXBlKHR5cGUpLT5OZXcoKSk7CisKKyAgaWYgKG1vZGVfID09IE1PREVfRU5DT0RFKSB7CisgICAgU2V0RmRUb1RleHRNb2RlKFNURElOX0ZJTEVOTyk7CisgICAgU2V0RmRUb0JpbmFyeU1vZGUoU1RET1VUX0ZJTEVOTyk7CisgIH0gZWxzZSB7CisgICAgU2V0RmRUb0JpbmFyeU1vZGUoU1RESU5fRklMRU5PKTsKKyAgICBTZXRGZFRvVGV4dE1vZGUoU1RET1VUX0ZJTEVOTyk7CisgIH0KKworICBpbzo6RmlsZUlucHV0U3RyZWFtIGluKFNURElOX0ZJTEVOTyk7CisgIGlvOjpGaWxlT3V0cHV0U3RyZWFtIG91dChTVERPVVRfRklMRU5PKTsKKworICBpZiAobW9kZV8gPT0gTU9ERV9FTkNPREUpIHsKKyAgICAvLyBJbnB1dCBpcyB0ZXh0LgorICAgIEVycm9yUHJpbnRlciBlcnJvcl9jb2xsZWN0b3IoZXJyb3JfZm9ybWF0Xyk7CisgICAgVGV4dEZvcm1hdDo6UGFyc2VyIHBhcnNlcjsKKyAgICBwYXJzZXIuUmVjb3JkRXJyb3JzVG8oJmVycm9yX2NvbGxlY3Rvcik7CisgICAgcGFyc2VyLkFsbG93UGFydGlhbE1lc3NhZ2UodHJ1ZSk7CisKKyAgICBpZiAoIXBhcnNlci5QYXJzZSgmaW4sIG1lc3NhZ2UuZ2V0KCkpKSB7CisgICAgICBzdGQ6OmNlcnIgPDwgIkZhaWxlZCB0byBwYXJzZSBpbnB1dC4iIDw8IHN0ZDo6ZW5kbDsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgLy8gSW5wdXQgaXMgYmluYXJ5LgorICAgIGlmICghbWVzc2FnZS0+UGFyc2VQYXJ0aWFsRnJvbVplcm9Db3B5U3RyZWFtKCZpbikpIHsKKyAgICAgIHN0ZDo6Y2VyciA8PCAiRmFpbGVkIHRvIHBhcnNlIGlucHV0LiIgPDwgc3RkOjplbmRsOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgfQorCisgIGlmICghbWVzc2FnZS0+SXNJbml0aWFsaXplZCgpKSB7CisgICAgc3RkOjpjZXJyIDw8ICJ3YXJuaW5nOiAgSW5wdXQgbWVzc2FnZSBpcyBtaXNzaW5nIHJlcXVpcmVkIGZpZWxkczogICIKKyAgICAgICAgICAgICAgPDwgbWVzc2FnZS0+SW5pdGlhbGl6YXRpb25FcnJvclN0cmluZygpIDw8IHN0ZDo6ZW5kbDsKKyAgfQorCisgIGlmIChtb2RlXyA9PSBNT0RFX0VOQ09ERSkgeworICAgIC8vIE91dHB1dCBpcyBiaW5hcnkuCisgICAgaWYgKCFtZXNzYWdlLT5TZXJpYWxpemVQYXJ0aWFsVG9aZXJvQ29weVN0cmVhbSgmb3V0KSkgeworICAgICAgc3RkOjpjZXJyIDw8ICJvdXRwdXQ6IEkvTyBlcnJvci4iIDw8IHN0ZDo6ZW5kbDsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgLy8gT3V0cHV0IGlzIHRleHQuCisgICAgaWYgKCFUZXh0Rm9ybWF0OjpQcmludCgqbWVzc2FnZSwgJm91dCkpIHsKKyAgICAgIHN0ZDo6Y2VyciA8PCAib3V0cHV0OiBJL08gZXJyb3IuIiA8PCBzdGQ6OmVuZGw7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICB9CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgQ29tbWFuZExpbmVJbnRlcmZhY2U6OldyaXRlRGVzY3JpcHRvclNldCgKKyAgICBjb25zdCB2ZWN0b3I8Y29uc3QgRmlsZURlc2NyaXB0b3IqPiBwYXJzZWRfZmlsZXMpIHsKKyAgRmlsZURlc2NyaXB0b3JTZXQgZmlsZV9zZXQ7CisKKyAgaWYgKGltcG9ydHNfaW5fZGVzY3JpcHRvcl9zZXRfKSB7CisgICAgc2V0PGNvbnN0IEZpbGVEZXNjcmlwdG9yKj4gYWxyZWFkeV9zZWVuOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFyc2VkX2ZpbGVzLnNpemUoKTsgaSsrKSB7CisgICAgICBHZXRUcmFuc2l0aXZlRGVwZW5kZW5jaWVzKHBhcnNlZF9maWxlc1tpXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSwgIC8vIEluY2x1ZGUganNvbl9uYW1lCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZV9pbmZvX2luX2Rlc2NyaXB0b3Jfc2V0XywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmFscmVhZHlfc2VlbiwgZmlsZV9zZXQubXV0YWJsZV9maWxlKCkpOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICBzZXQ8Y29uc3QgRmlsZURlc2NyaXB0b3IqPiBhbHJlYWR5X3NlZW47CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYXJzZWRfZmlsZXMuc2l6ZSgpOyBpKyspIHsKKyAgICAgIGlmICghYWxyZWFkeV9zZWVuLmluc2VydChwYXJzZWRfZmlsZXNbaV0pLnNlY29uZCkgeworICAgICAgICBjb250aW51ZTsKKyAgICAgIH0KKyAgICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8qIGZpbGVfcHJvdG8gPSBmaWxlX3NldC5hZGRfZmlsZSgpOworICAgICAgcGFyc2VkX2ZpbGVzW2ldLT5Db3B5VG8oZmlsZV9wcm90byk7CisgICAgICBwYXJzZWRfZmlsZXNbaV0tPkNvcHlKc29uTmFtZVRvKGZpbGVfcHJvdG8pOworICAgICAgaWYgKHNvdXJjZV9pbmZvX2luX2Rlc2NyaXB0b3Jfc2V0XykgeworICAgICAgICBwYXJzZWRfZmlsZXNbaV0tPkNvcHlTb3VyY2VDb2RlSW5mb1RvKGZpbGVfcHJvdG8pOworICAgICAgfQorICAgIH0KKyAgfQorCisgIGludCBmZDsKKyAgZG8geworICAgIGZkID0gb3BlbihkZXNjcmlwdG9yX3NldF9uYW1lXy5jX3N0cigpLAorICAgICAgICAgICAgICBPX1dST05MWSB8IE9fQ1JFQVQgfCBPX1RSVU5DIHwgT19CSU5BUlksIDA2NjYpOworICB9IHdoaWxlIChmZCA8IDAgJiYgZXJybm8gPT0gRUlOVFIpOworCisgIGlmIChmZCA8IDApIHsKKyAgICBwZXJyb3IoZGVzY3JpcHRvcl9zZXRfbmFtZV8uY19zdHIoKSk7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgaW86OkZpbGVPdXRwdXRTdHJlYW0gb3V0KGZkKTsKKyAgaWYgKCFmaWxlX3NldC5TZXJpYWxpemVUb1plcm9Db3B5U3RyZWFtKCZvdXQpKSB7CisgICAgc3RkOjpjZXJyIDw8IGRlc2NyaXB0b3Jfc2V0X25hbWVfIDw8ICI6ICIgPDwgc3RyZXJyb3Iob3V0LkdldEVycm5vKCkpCisgICAgICAgICAgICAgIDw8IHN0ZDo6ZW5kbDsKKyAgICBvdXQuQ2xvc2UoKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgaWYgKCFvdXQuQ2xvc2UoKSkgeworICAgIHN0ZDo6Y2VyciA8PCBkZXNjcmlwdG9yX3NldF9uYW1lXyA8PCAiOiAiIDw8IHN0cmVycm9yKG91dC5HZXRFcnJubygpKQorICAgICAgICAgICAgICA8PCBzdGQ6OmVuZGw7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgQ29tbWFuZExpbmVJbnRlcmZhY2U6OkdldFRyYW5zaXRpdmVEZXBlbmRlbmNpZXMoCisgICAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUsCisgICAgYm9vbCBpbmNsdWRlX2pzb25fbmFtZSwKKyAgICBib29sIGluY2x1ZGVfc291cmNlX2NvZGVfaW5mbywKKyAgICBzZXQ8Y29uc3QgRmlsZURlc2NyaXB0b3IqPiogYWxyZWFkeV9zZWVuLAorICAgIFJlcGVhdGVkUHRyRmllbGQ8RmlsZURlc2NyaXB0b3JQcm90bz4qIG91dHB1dCkgeworICBpZiAoIWFscmVhZHlfc2Vlbi0+aW5zZXJ0KGZpbGUpLnNlY29uZCkgeworICAgIC8vIEFscmVhZHkgc2F3IHRoaXMgZmlsZS4gIFNraXAuCisgICAgcmV0dXJuOworICB9CisKKyAgLy8gQWRkIGFsbCBkZXBlbmRlbmNpZXMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZS0+ZGVwZW5kZW5jeV9jb3VudCgpOyBpKyspIHsKKyAgICBHZXRUcmFuc2l0aXZlRGVwZW5kZW5jaWVzKGZpbGUtPmRlcGVuZGVuY3koaSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmNsdWRlX2pzb25fbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluY2x1ZGVfc291cmNlX2NvZGVfaW5mbywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFscmVhZHlfc2Vlbiwgb3V0cHV0KTsKKyAgfQorCisgIC8vIEFkZCB0aGlzIGZpbGUuCisgIEZpbGVEZXNjcmlwdG9yUHJvdG8qIG5ld19kZXNjcmlwdG9yID0gb3V0cHV0LT5BZGQoKTsKKyAgZmlsZS0+Q29weVRvKG5ld19kZXNjcmlwdG9yKTsKKyAgaWYgKGluY2x1ZGVfanNvbl9uYW1lKSB7CisgICAgZmlsZS0+Q29weUpzb25OYW1lVG8obmV3X2Rlc2NyaXB0b3IpOworICB9CisgIGlmIChpbmNsdWRlX3NvdXJjZV9jb2RlX2luZm8pIHsKKyAgICBmaWxlLT5Db3B5U291cmNlQ29kZUluZm9UbyhuZXdfZGVzY3JpcHRvcik7CisgIH0KK30KKworbmFtZXNwYWNlIHsKKworLy8gVXRpbGl0eSBmdW5jdGlvbiBmb3IgUHJpbnRGcmVlRmllbGROdW1iZXJzLgorLy8gU3RvcmVzIG9jY3VwaWVkIHJhbmdlcyBpbnRvIHRoZSByYW5nZXMgcGFyYW1ldGVyLCBhbmQgbmV4dCBsZXZlbCBvZiBzdWIKKy8vIG1lc3NhZ2UgdHlwZXMgaW50byB0aGUgbmVzdGVkX21lc3NhZ2VzIHBhcmFtZXRlci4gIFRoZSBGaWVsZFJhbmdlIGlzIGxlZnQKKy8vIGluY2x1c2l2ZSwgcmlnaHQgZXhjbHVzaXZlLiBpLmUuIFthLCBiKS4KKy8vCisvLyBOZXN0ZWQgTWVzc2FnZXM6CisvLyBOb3RlIHRoYXQgaXQgb25seSBzdG9yZXMgdGhlIG5lc3RlZCBtZXNzYWdlIHR5cGUsIGlmZiB0aGUgbmVzdGVkIHR5cGUgaXMKKy8vIGVpdGhlciBhIGRpcmVjdCBjaGlsZCBvZiB0aGUgZ2l2ZW4gZGVzY3JpcHRvciwgb3IgdGhlIG5lc3RlZCB0eXBlIGlzIGEKKy8vIGRlY2VuZGVudCBvZiB0aGUgZ2l2ZW4gZGVzY3JpcHRvciBhbmQgYWxsIHRoZSBub2RlcyBiZXR3ZWVuIHRoZQorLy8gbmVzdGVkIHR5cGUgYW5kIHRoZSBnaXZlbiBkZXNjcmlwdG9yIGFyZSBncm91cCB0eXBlcy4gZS5nLgorLy8KKy8vIG1lc3NhZ2UgRm9vIHsKKy8vICAgbWVzc2FnZSBCYXIgeworLy8gICAgIG1lc3NhZ2UgTmVzdGVkQmFyIHt9CisvLyAgIH0KKy8vICAgZ3JvdXAgQmF6ID0gMSB7CisvLyAgICAgZ3JvdXAgTmVzdGVkQmF6R3JvdXAgPSAyIHsKKy8vICAgICAgIG1lc3NhZ2UgUXV6IHsKKy8vICAgICAgICAgbWVzc2FnZSBOZXN0ZWRRdXoge30KKy8vICAgICAgIH0KKy8vICAgICB9CisvLyAgICAgbWVzc2FnZSBOZXN0ZWRCYXoge30KKy8vICAgfQorLy8gfQorLy8KKy8vIEluIHRoaXMgY2FzZSwgQmFyLCBRdXogYW5kIE5lc3RlZEJheiB3aWxsIGJlIGFkZGVkIGludG8gdGhlIG5lc3RlZCB0eXBlcy4KKy8vIFNpbmNlIGZyZWUgZmllbGQgbnVtYmVycyBvZiBncm91cCB0eXBlcyB3aWxsIG5vdCBiZSBwcmludGVkLCB0aGlzIG1ha2VzIHN1cmUKKy8vIHRoZSBuZXN0ZWQgbWVzc2FnZSB0eXBlcyBpbiBncm91cHMgd2lsbCBub3QgYmUgZHJvcHBlZC4gVGhlIG5lc3RlZF9tZXNzYWdlcworLy8gcGFyYW1ldGVyIHdpbGwgY29udGFpbiB0aGUgZGlyZWN0IGNoaWxkcmVuICh3aGVuIGdyb3VwcyBhcmUgaWdub3JlZCBpbiB0aGUKKy8vIHRyZWUpIG9mIHRoZSBnaXZlbiBkZXNjcmlwdG9yIGZvciB0aGUgY2FsbGVyIHRvIHRyYXZlcnNlLiBUaGUgZGVjbGFyYXRpb24KKy8vIG9yZGVyIG9mIHRoZSBuZXN0ZWQgbWVzc2FnZXMgaXMgYWxzbyBwcmVzZXJ2ZWQuCit0eXBlZGVmIHBhaXI8aW50LCBpbnQ+IEZpZWxkUmFuZ2U7Cit2b2lkIEdhdGhlck9jY3VwaWVkRmllbGRSYW5nZXMoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXQ8RmllbGRSYW5nZT4qIHJhbmdlcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWN0b3I8Y29uc3QgRGVzY3JpcHRvcio+KiBuZXN0ZWRfbWVzc2FnZXMpIHsKKyAgc2V0PGNvbnN0IERlc2NyaXB0b3IqPiBncm91cHM7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvci0+ZmllbGRfY291bnQoKTsgKytpKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmZCA9IGRlc2NyaXB0b3ItPmZpZWxkKGkpOworICAgIHJhbmdlcy0+aW5zZXJ0KEZpZWxkUmFuZ2UoZmQtPm51bWJlcigpLCBmZC0+bnVtYmVyKCkgKyAxKSk7CisgICAgaWYgKGZkLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQKSB7CisgICAgICBncm91cHMuaW5zZXJ0KGZkLT5tZXNzYWdlX3R5cGUoKSk7CisgICAgfQorICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvci0+ZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCk7ICsraSkgeworICAgIHJhbmdlcy0+aW5zZXJ0KEZpZWxkUmFuZ2UoZGVzY3JpcHRvci0+ZXh0ZW5zaW9uX3JhbmdlKGkpLT5zdGFydCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0b3ItPmV4dGVuc2lvbl9yYW5nZShpKS0+ZW5kKSk7CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yLT5yZXNlcnZlZF9yYW5nZV9jb3VudCgpOyArK2kpIHsKKyAgICByYW5nZXMtPmluc2VydChGaWVsZFJhbmdlKGRlc2NyaXB0b3ItPnJlc2VydmVkX3JhbmdlKGkpLT5zdGFydCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0b3ItPnJlc2VydmVkX3JhbmdlKGkpLT5lbmQpKTsKKyAgfQorICAvLyBIYW5kbGUgdGhlIG5lc3RlZCBtZXNzYWdlcy9ncm91cHMgaW4gZGVjbGFyYXRpb24gb3JkZXIgdG8gbWFrZSBpdAorICAvLyBwb3N0LW9yZGVyIHN0cmljdC4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yLT5uZXN0ZWRfdHlwZV9jb3VudCgpOyArK2kpIHsKKyAgICBjb25zdCBEZXNjcmlwdG9yKiBuZXN0ZWRfZGVzYyA9IGRlc2NyaXB0b3ItPm5lc3RlZF90eXBlKGkpOworICAgIGlmIChncm91cHMuZmluZChuZXN0ZWRfZGVzYykgIT0gZ3JvdXBzLmVuZCgpKSB7CisgICAgICBHYXRoZXJPY2N1cGllZEZpZWxkUmFuZ2VzKG5lc3RlZF9kZXNjLCByYW5nZXMsIG5lc3RlZF9tZXNzYWdlcyk7CisgICAgfSBlbHNlIHsKKyAgICAgIG5lc3RlZF9tZXNzYWdlcy0+cHVzaF9iYWNrKG5lc3RlZF9kZXNjKTsKKyAgICB9CisgIH0KK30KKworLy8gVXRpbGl0eSBmdW5jdGlvbiBmb3IgUHJpbnRGcmVlRmllbGROdW1iZXJzLgorLy8gQWN0dWFsbHkgcHJpbnRzIHRoZSBmb3JtYXR0ZWQgZnJlZSBmaWVsZCBudW1iZXJzIGZvciBnaXZlbiBtZXNzYWdlIG5hbWUgYW5kCisvLyBvY2N1cGllZCByYW5nZXMuCit2b2lkIEZvcm1hdEZyZWVGaWVsZE51bWJlcnMoY29uc3Qgc3RyaW5nJiBuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNldDxGaWVsZFJhbmdlPiYgcmFuZ2VzKSB7CisgIHN0cmluZyBvdXRwdXQ7CisgIFN0cmluZ0FwcGVuZEYoJm91dHB1dCwgIiUtMzVzIGZyZWU6IiwgbmFtZS5jX3N0cigpKTsKKyAgaW50IG5leHRfZnJlZV9udW1iZXIgPSAxOworICBmb3IgKHNldDxGaWVsZFJhbmdlPjo6Y29uc3RfaXRlcmF0b3IgaSA9IHJhbmdlcy5iZWdpbigpOworICAgICAgIGkgIT0gcmFuZ2VzLmVuZCgpOyArK2kpIHsKKyAgICAvLyBUaGlzIGhhcHBlbnMgd2hlbiBncm91cHMgcmUtdXNlIHBhcmVudCBmaWVsZCBudW1iZXJzLCBpbiB3aGljaAorICAgIC8vIGNhc2Ugd2Ugc2tpcCB0aGUgRmllbGRSYW5nZSBlbnRpcmVseS4KKyAgICBpZiAobmV4dF9mcmVlX251bWJlciA+PSBpLT5zZWNvbmQpIGNvbnRpbnVlOworCisgICAgaWYgKG5leHRfZnJlZV9udW1iZXIgPCBpLT5maXJzdCkgeworICAgICAgaWYgKG5leHRfZnJlZV9udW1iZXIgKyAxID09IGktPmZpcnN0KSB7CisgICAgICAgIC8vIFNpbmdsZXRvbgorICAgICAgICBTdHJpbmdBcHBlbmRGKCZvdXRwdXQsICIgJWQiLCBuZXh0X2ZyZWVfbnVtYmVyKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIC8vIFJhbmdlCisgICAgICAgIFN0cmluZ0FwcGVuZEYoJm91dHB1dCwgIiAlZC0lZCIsIG5leHRfZnJlZV9udW1iZXIsIGktPmZpcnN0IC0gMSk7CisgICAgICB9CisgICAgfQorICAgIG5leHRfZnJlZV9udW1iZXIgPSBpLT5zZWNvbmQ7CisgIH0KKyAgaWYgKG5leHRfZnJlZV9udW1iZXIgPD0gRmllbGREZXNjcmlwdG9yOjprTWF4TnVtYmVyKSB7CisgICAgU3RyaW5nQXBwZW5kRigmb3V0cHV0LCAiICVkLUlORiIsIG5leHRfZnJlZV9udW1iZXIpOworICB9CisgIHN0ZDo6Y291dCA8PCBvdXRwdXQgPDwgc3RkOjplbmRsOworfQorCit9ICAvLyBuYW1lc3BhY2UKKwordm9pZCBDb21tYW5kTGluZUludGVyZmFjZTo6UHJpbnRGcmVlRmllbGROdW1iZXJzKAorICAgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgc2V0PEZpZWxkUmFuZ2U+IHJhbmdlczsKKyAgdmVjdG9yPGNvbnN0IERlc2NyaXB0b3IqPiBuZXN0ZWRfbWVzc2FnZXM7CisgIEdhdGhlck9jY3VwaWVkRmllbGRSYW5nZXMoZGVzY3JpcHRvciwgJnJhbmdlcywgJm5lc3RlZF9tZXNzYWdlcyk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBuZXN0ZWRfbWVzc2FnZXMuc2l6ZSgpOyArK2kpIHsKKyAgICBQcmludEZyZWVGaWVsZE51bWJlcnMobmVzdGVkX21lc3NhZ2VzW2ldKTsKKyAgfQorICBGb3JtYXRGcmVlRmllbGROdW1iZXJzKGRlc2NyaXB0b3ItPmZ1bGxfbmFtZSgpLCByYW5nZXMpOworfQorCisKKworfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY29tbWFuZF9saW5lX2ludGVyZmFjZS5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jb21tYW5kX2xpbmVfaW50ZXJmYWNlLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjE5NmZmYwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY29tbWFuZF9saW5lX2ludGVyZmFjZS5oCkBAIC0wLDAgKzEsMzkzIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisvLworLy8gSW1wbGVtZW50cyB0aGUgUHJvdG9jb2wgQ29tcGlsZXIgZnJvbnQtZW5kIHN1Y2ggdGhhdCBpdCBtYXkgYmUgcmV1c2VkIGJ5CisvLyBjdXN0b20gY29tcGlsZXJzIHdyaXR0ZW4gdG8gc3VwcG9ydCBvdGhlciBsYW5ndWFnZXMuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NPTU1BTkRfTElORV9JTlRFUkZBQ0VfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DT01NQU5EX0xJTkVfSU5URVJGQUNFX0hfXworCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9oYXNoLmg+CisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPHZlY3Rvcj4KKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8c2V0PgorI2luY2x1ZGUgPHV0aWxpdHk+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworY2xhc3MgRGVzY3JpcHRvcjsgICAgICAgICAgICAvLyBkZXNjcmlwdG9yLmgKK2NsYXNzIERlc2NyaXB0b3JQb29sOyAgICAgICAgLy8gZGVzY3JpcHRvci5oCitjbGFzcyBGaWxlRGVzY3JpcHRvcjsgICAgICAgIC8vIGRlc2NyaXB0b3IuaAorY2xhc3MgRmlsZURlc2NyaXB0b3JQcm90bzsgICAvLyBkZXNjcmlwdG9yLnBiLmgKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+IGNsYXNzIFJlcGVhdGVkUHRyRmllbGQ7ICAvLyByZXBlYXRlZF9maWVsZC5oCisKK25hbWVzcGFjZSBjb21waWxlciB7CisKK2NsYXNzIENvZGVHZW5lcmF0b3I7ICAgICAgICAvLyBjb2RlX2dlbmVyYXRvci5oCitjbGFzcyBHZW5lcmF0b3JDb250ZXh0OyAgICAgIC8vIGNvZGVfZ2VuZXJhdG9yLmgKK2NsYXNzIERpc2tTb3VyY2VUcmVlOyAgICAgICAvLyBpbXBvcnRlci5oCisKKy8vIFRoaXMgY2xhc3MgaW1wbGVtZW50cyB0aGUgY29tbWFuZC1saW5lIGludGVyZmFjZSB0byB0aGUgcHJvdG9jb2wgY29tcGlsZXIuCisvLyBJdCBpcyBkZXNpZ25lZCB0byBtYWtlIGl0IHZlcnkgZWFzeSB0byBjcmVhdGUgYSBjdXN0b20gcHJvdG9jb2wgY29tcGlsZXIKKy8vIHN1cHBvcnRpbmcgdGhlIGxhbmd1YWdlcyBvZiB5b3VyIGNob2ljZS4gIEZvciBleGFtcGxlLCBpZiB5b3Ugd2FudGVkIHRvCisvLyBjcmVhdGUgYSBjdXN0b20gcHJvdG9jb2wgY29tcGlsZXIgYmluYXJ5IHdoaWNoIGluY2x1ZGVzIGJvdGggdGhlIHJlZ3VsYXIKKy8vIEMrKyBzdXBwb3J0IHBsdXMgc3VwcG9ydCBmb3IgeW91ciBvd24gY3VzdG9tIG91dHB1dCAiRm9vIiwgeW91IHdvdWxkCisvLyB3cml0ZSBhIGNsYXNzICJGb29HZW5lcmF0b3IiIHdoaWNoIGltcGxlbWVudHMgdGhlIENvZGVHZW5lcmF0b3IgaW50ZXJmYWNlLAorLy8gdGhlbiB3cml0ZSBhIG1haW4oKSBwcm9jZWR1cmUgbGlrZSB0aGlzOgorLy8KKy8vICAgaW50IG1haW4oaW50IGFyZ2MsIGNoYXIqIGFyZ3ZbXSkgeworLy8gICAgIGdvb2dsZTo6cHJvdG9idWY6OmNvbXBpbGVyOjpDb21tYW5kTGluZUludGVyZmFjZSBjbGk7CisvLworLy8gICAgIC8vIFN1cHBvcnQgZ2VuZXJhdGlvbiBvZiBDKysgc291cmNlIGFuZCBoZWFkZXJzLgorLy8gICAgIGdvb2dsZTo6cHJvdG9idWY6OmNvbXBpbGVyOjpjcHA6OkNwcEdlbmVyYXRvciBjcHBfZ2VuZXJhdG9yOworLy8gICAgIGNsaS5SZWdpc3RlckdlbmVyYXRvcigiLS1jcHBfb3V0IiwgJmNwcF9nZW5lcmF0b3IsCisvLyAgICAgICAiR2VuZXJhdGUgQysrIHNvdXJjZSBhbmQgaGVhZGVyLiIpOworLy8KKy8vICAgICAvLyBTdXBwb3J0IGdlbmVyYXRpb24gb2YgRm9vIGNvZGUuCisvLyAgICAgRm9vR2VuZXJhdG9yIGZvb19nZW5lcmF0b3I7CisvLyAgICAgY2xpLlJlZ2lzdGVyR2VuZXJhdG9yKCItLWZvb19vdXQiLCAmZm9vX2dlbmVyYXRvciwKKy8vICAgICAgICJHZW5lcmF0ZSBGb28gZmlsZS4iKTsKKy8vCisvLyAgICAgcmV0dXJuIGNsaS5SdW4oYXJnYywgYXJndik7CisvLyAgIH0KKy8vCisvLyBUaGUgY29tcGlsZXIgaXMgaW52b2tlZCB3aXRoIHN5bnRheCBsaWtlOgorLy8gICBwcm90b2MgLS1jcHBfb3V0PW91dGRpciAtLWZvb19vdXQ9b3V0ZGlyIC0tcHJvdG9fcGF0aD1zcmMgc3JjL2Zvby5wcm90bworLy8KKy8vIEZvciBhIGZ1bGwgZGVzY3JpcHRpb24gb2YgdGhlIGNvbW1hbmQtbGluZSBzeW50YXgsIGludm9rZSBpdCB3aXRoIC0taGVscC4KK2NsYXNzIExJQlBST1RPQ19FWFBPUlQgQ29tbWFuZExpbmVJbnRlcmZhY2UgeworIHB1YmxpYzoKKyAgQ29tbWFuZExpbmVJbnRlcmZhY2UoKTsKKyAgfkNvbW1hbmRMaW5lSW50ZXJmYWNlKCk7CisKKyAgLy8gUmVnaXN0ZXIgYSBjb2RlIGdlbmVyYXRvciBmb3IgYSBsYW5ndWFnZS4KKyAgLy8KKyAgLy8gUGFyYW1ldGVyczoKKyAgLy8gKiBmbGFnX25hbWU6IFRoZSBjb21tYW5kLWxpbmUgZmxhZyB1c2VkIHRvIHNwZWNpZnkgYW4gb3V0cHV0IGZpbGUgb2YKKyAgLy8gICB0aGlzIHR5cGUuICBUaGUgbmFtZSBtdXN0IHN0YXJ0IHdpdGggYSAnLScuICBJZiB0aGUgbmFtZSBpcyBsb25nZXIKKyAgLy8gICB0aGFuIG9uZSBsZXR0ZXIsIGl0IG11c3Qgc3RhcnQgd2l0aCB0d28gJy0ncy4KKyAgLy8gKiBnZW5lcmF0b3I6IFRoZSBDb2RlR2VuZXJhdG9yIHdoaWNoIHdpbGwgYmUgY2FsbGVkIHRvIGdlbmVyYXRlIGZpbGVzCisgIC8vICAgb2YgdGhpcyB0eXBlLgorICAvLyAqIGhlbHBfdGV4dDogVGV4dCBkZXNjcmliaW5nIHRoaXMgZmxhZyBpbiB0aGUgLS1oZWxwIG91dHB1dC4KKyAgLy8KKyAgLy8gU29tZSBnZW5lcmF0b3JzIGFjY2VwdCBleHRyYSBwYXJhbWV0ZXJzLiAgWW91IGNhbiBzcGVjaWZ5IHRoaXMgcGFyYW1ldGVyCisgIC8vIG9uIHRoZSBjb21tYW5kLWxpbmUgYnkgcGxhY2luZyBpdCBiZWZvcmUgdGhlIG91dHB1dCBkaXJlY3RvcnksIHNlcGFyYXRlZAorICAvLyBieSBhIGNvbG9uOgorICAvLyAgIHByb3RvYyAtLWZvb19vdXQ9ZW5hYmxlX2JhcjpvdXRkaXIKKyAgLy8gVGhlIHRleHQgYmVmb3JlIHRoZSBjb2xvbiBpcyBwYXNzZWQgdG8gQ29kZUdlbmVyYXRvcjo6R2VuZXJhdGUoKSBhcyB0aGUKKyAgLy8gInBhcmFtZXRlciIuCisgIHZvaWQgUmVnaXN0ZXJHZW5lcmF0b3IoY29uc3Qgc3RyaW5nJiBmbGFnX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgQ29kZUdlbmVyYXRvciogZ2VuZXJhdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgaGVscF90ZXh0KTsKKworICAvLyBSZWdpc3RlciBhIGNvZGUgZ2VuZXJhdG9yIGZvciBhIGxhbmd1YWdlLgorICAvLyBCZXNpZGVzIGZsYWdfbmFtZSB5b3UgY2FuIHNwZWNpZnkgYW5vdGhlciBvcHRpb25fZmxhZ19uYW1lIHRoYXQgY291bGQgYmUKKyAgLy8gdXNlZCB0byBwYXNzIGV4dHJhIHBhcmFtZXRlcnMgdG8gdGhlIHJlZ2lzdGVyZWQgY29kZSBnZW5lcmF0b3IuCisgIC8vIFN1cHBvc2UgeW91IGhhdmUgcmVnaXN0ZXJlZCBhIGdlbmVyYXRvciBieSBjYWxsaW5nOgorICAvLyAgIGNvbW1hbmRfbGluZV9pbnRlcmZhY2UuUmVnaXN0ZXJHZW5lcmF0b3IoIi0tZm9vX291dCIsICItLWZvb19vcHQiLCAuLi4pCisgIC8vIFRoZW4geW91IGNvdWxkIGludm9rZSB0aGUgY29tcGlsZXIgd2l0aCBhIGNvbW1hbmQgbGlrZToKKyAgLy8gICBwcm90b2MgLS1mb29fb3V0PWVuYWJsZV9iYXI6b3V0ZGlyIC0tZm9vX29wdD1lbmFibGVfYmF6CisgIC8vIFRoaXMgd2lsbCBwYXNzICJlbmFibGVfYmFyLGVuYWJsZV9iYXoiIGFzIHRoZSBwYXJhbWV0ZXIgdG8gdGhlIGdlbmVyYXRvci4KKyAgdm9pZCBSZWdpc3RlckdlbmVyYXRvcihjb25zdCBzdHJpbmcmIGZsYWdfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIG9wdGlvbl9mbGFnX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgQ29kZUdlbmVyYXRvciogZ2VuZXJhdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgaGVscF90ZXh0KTsKKworICAvLyBFbmFibGVzICJwbHVnaW5zIi4gIEluIHRoaXMgbW9kZSwgaWYgYSBjb21tYW5kLWxpbmUgZmxhZyBlbmRzIHdpdGggIl9vdXQiCisgIC8vIGJ1dCBkb2VzIG5vdCBtYXRjaCBhbnkgcmVnaXN0ZXJlZCBnZW5lcmF0b3IsIHRoZSBjb21waWxlciB3aWxsIGF0dGVtcHQgdG8KKyAgLy8gZmluZCBhICJwbHVnaW4iIHRvIGltcGxlbWVudCB0aGUgZ2VuZXJhdG9yLiAgUGx1Z2lucyBhcmUganVzdCBleGVjdXRhYmxlcy4KKyAgLy8gVGhleSBzaG91bGQgbGl2ZSBzb21ld2hlcmUgaW4gdGhlIFBBVEguCisgIC8vCisgIC8vIFRoZSBjb21waWxlciBkZXRlcm1pbmVzIHRoZSBleGVjdXRhYmxlIG5hbWUgdG8gc2VhcmNoIGZvciBieSBjb25jYXRlbmF0aW5nCisgIC8vIGV4ZV9uYW1lX3ByZWZpeCB3aXRoIHRoZSB1bnJlY29nbml6ZWQgZmxhZyBuYW1lLCByZW1vdmluZyAiX291dCIuICBTbywgZm9yCisgIC8vIGV4YW1wbGUsIGlmIGV4ZV9uYW1lX3ByZWZpeCBpcyAicHJvdG9jLSIgYW5kIHlvdSBwYXNzIHRoZSBmbGFnIC0tZm9vX291dCwKKyAgLy8gdGhlIGNvbXBpbGVyIHdpbGwgdHJ5IHRvIHJ1biB0aGUgcHJvZ3JhbSAicHJvdG9jLWZvbyIuCisgIC8vCisgIC8vIFRoZSBwbHVnaW4gcHJvZ3JhbSBzaG91bGQgaW1wbGVtZW50IHRoZSBmb2xsb3dpbmcgdXNhZ2U6CisgIC8vICAgcGx1Z2luIFstLW91dD1PVVRESVJdIFstLXBhcmFtZXRlcj1QQVJBTUVURVJdIFBST1RPX0ZJTEVTIDwgREVTQ1JJUFRPUlMKKyAgLy8gLS1vdXQgaW5kaWNhdGVzIHRoZSBvdXRwdXQgZGlyZWN0b3J5IChhcyBwYXNzZWQgdG8gdGhlIC0tZm9vX291dAorICAvLyBwYXJhbWV0ZXIpOyBpZiBvbWl0dGVkLCB0aGUgY3VycmVudCBkaXJlY3Rvcnkgc2hvdWxkIGJlIHVzZWQuICAtLXBhcmFtZXRlcgorICAvLyBnaXZlcyB0aGUgZ2VuZXJhdG9yIHBhcmFtZXRlciwgaWYgYW55IHdhcyBwcm92aWRlZC4gIFRoZSBQUk9UT19GSUxFUyBsaXN0CisgIC8vIHRoZSAucHJvdG8gZmlsZXMgd2hpY2ggd2VyZSBnaXZlbiBvbiB0aGUgY29tcGlsZXIgY29tbWFuZC1saW5lOyB0aGVzZSBhcmUKKyAgLy8gdGhlIGZpbGVzIGZvciB3aGljaCB0aGUgcGx1Z2luIGlzIGV4cGVjdGVkIHRvIGdlbmVyYXRlIG91dHB1dCBjb2RlLgorICAvLyBGaW5hbGx5LCBERVNDUklQVE9SUyBpcyBhbiBlbmNvZGVkIEZpbGVEZXNjcmlwdG9yU2V0IChhcyBkZWZpbmVkIGluCisgIC8vIGRlc2NyaXB0b3IucHJvdG8pLiAgVGhpcyBpcyBwaXBlZCB0byB0aGUgcGx1Z2luJ3Mgc3RkaW4uICBUaGUgc2V0IHdpbGwKKyAgLy8gaW5jbHVkZSBkZXNjcmlwdG9ycyBmb3IgYWxsIHRoZSBmaWxlcyBsaXN0ZWQgaW4gUFJPVE9fRklMRVMgYXMgd2VsbCBhcworICAvLyBhbGwgZmlsZXMgdGhhdCB0aGV5IGltcG9ydC4gIFRoZSBwbHVnaW4gTVVTVCBOT1QgYXR0ZW1wdCB0byByZWFkIHRoZQorICAvLyBQUk9UT19GSUxFUyBkaXJlY3RseSAtLSBpdCBtdXN0IHVzZSB0aGUgRmlsZURlc2NyaXB0b3JTZXQuCisgIC8vCisgIC8vIFRoZSBwbHVnaW4gc2hvdWxkIGdlbmVyYXRlIHdoYXRldmVyIGZpbGVzIGFyZSBuZWNlc3NhcnksIGFzIGNvZGUgZ2VuZXJhdG9ycworICAvLyBub3JtYWxseSBkby4gIEl0IHNob3VsZCB3cml0ZSB0aGUgbmFtZXMgb2YgYWxsIGZpbGVzIGl0IGdlbmVyYXRlcyB0bworICAvLyBzdGRvdXQuICBUaGUgbmFtZXMgc2hvdWxkIGJlIHJlbGF0aXZlIHRvIHRoZSBvdXRwdXQgZGlyZWN0b3J5LCBOT1QgYWJzb2x1dGUKKyAgLy8gbmFtZXMgb3IgcmVsYXRpdmUgdG8gdGhlIGN1cnJlbnQgZGlyZWN0b3J5LiAgSWYgYW55IGVycm9ycyBvY2N1ciwgZXJyb3IKKyAgLy8gbWVzc2FnZXMgc2hvdWxkIGJlIHdyaXR0ZW4gdG8gc3RkZXJyLiAgSWYgYW4gZXJyb3IgaXMgZmF0YWwsIHRoZSBwbHVnaW4KKyAgLy8gc2hvdWxkIGV4aXQgd2l0aCBhIG5vbi16ZXJvIGV4aXQgY29kZS4KKyAgdm9pZCBBbGxvd1BsdWdpbnMoY29uc3Qgc3RyaW5nJiBleGVfbmFtZV9wcmVmaXgpOworCisgIC8vIFJ1biB0aGUgUHJvdG9jb2wgQ29tcGlsZXIgd2l0aCB0aGUgZ2l2ZW4gY29tbWFuZC1saW5lIHBhcmFtZXRlcnMuCisgIC8vIFJldHVybnMgdGhlIGVycm9yIGNvZGUgd2hpY2ggc2hvdWxkIGJlIHJldHVybmVkIGJ5IG1haW4oKS4KKyAgLy8KKyAgLy8gSXQgbWF5IG5vdCBiZSBzYWZlIHRvIGNhbGwgUnVuKCkgaW4gYSBtdWx0aS10aHJlYWRlZCBlbnZpcm9ubWVudCBiZWNhdXNlCisgIC8vIGl0IGNhbGxzIHN0cmVycm9yKCkuICBJJ20gbm90IHN1cmUgd2h5IHlvdSdkIHdhbnQgdG8gZG8gdGhpcyBhbnl3YXkuCisgIGludCBSdW4oaW50IGFyZ2MsIGNvbnN0IGNoYXIqIGNvbnN0IGFyZ3ZbXSk7CisKKyAgLy8gQ2FsbCBTZXRJbnB1dHNBcmVDd2RSZWxhdGl2ZSh0cnVlKSBpZiB0aGUgaW5wdXQgZmlsZXMgZ2l2ZW4gb24gdGhlIGNvbW1hbmQKKyAgLy8gbGluZSBzaG91bGQgYmUgaW50ZXJwcmV0ZWQgcmVsYXRpdmUgdG8gdGhlIHByb3RvIGltcG9ydCBwYXRoIHNwZWNpZmllZAorICAvLyB1c2luZyAtLXByb3RvX3BhdGggb3IgLUkgZmxhZ3MuICBPdGhlcndpc2UsIGlucHV0IGZpbGUgbmFtZXMgd2lsbCBiZQorICAvLyBpbnRlcnByZXRlZCByZWxhdGl2ZSB0byB0aGUgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeSAob3IgYXMgYWJzb2x1dGUKKyAgLy8gcGF0aHMgaWYgdGhleSBzdGFydCB3aXRoICcvJyksIHRob3VnaCB0aGV5IG11c3Qgc3RpbGwgcmVzaWRlIGluc2lkZQorICAvLyBhIGRpcmVjdG9yeSBnaXZlbiBieSAtLXByb3RvX3BhdGggb3IgdGhlIGNvbXBpbGVyIHdpbGwgZmFpbC4gIFRoZSBsYXR0ZXIKKyAgLy8gbW9kZSBpcyBnZW5lcmFsbHkgbW9yZSBpbnR1aXRpdmUgYW5kIGVhc2llciB0byB1c2UsIGVzcGVjaWFsbHkgZS5nLiB3aGVuCisgIC8vIGRlZmluaW5nIGltcGxpY2l0IHJ1bGVzIGluIE1ha2VmaWxlcy4KKyAgdm9pZCBTZXRJbnB1dHNBcmVQcm90b1BhdGhSZWxhdGl2ZShib29sIGVuYWJsZSkgeworICAgIGlucHV0c19hcmVfcHJvdG9fcGF0aF9yZWxhdGl2ZV8gPSBlbmFibGU7CisgIH0KKworICAvLyBQcm92aWRlcyBzb21lIHRleHQgd2hpY2ggd2lsbCBiZSBwcmludGVkIHdoZW4gdGhlIC0tdmVyc2lvbiBmbGFnIGlzCisgIC8vIHVzZWQuICBUaGUgdmVyc2lvbiBvZiBsaWJwcm90b2Mgd2lsbCBhbHNvIGJlIHByaW50ZWQgb24gdGhlIG5leHQgbGluZQorICAvLyBhZnRlciB0aGlzIHRleHQuCisgIHZvaWQgU2V0VmVyc2lvbkluZm8oY29uc3Qgc3RyaW5nJiB0ZXh0KSB7CisgICAgdmVyc2lvbl9pbmZvXyA9IHRleHQ7CisgIH0KKworCisgcHJpdmF0ZToKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBjbGFzcyBFcnJvclByaW50ZXI7CisgIGNsYXNzIEdlbmVyYXRvckNvbnRleHRJbXBsOworICBjbGFzcyBNZW1vcnlPdXRwdXRTdHJlYW07CisgIHR5cGVkZWYgaGFzaF9tYXA8c3RyaW5nLCBHZW5lcmF0b3JDb250ZXh0SW1wbCo+IEdlbmVyYXRvckNvbnRleHRNYXA7CisKKyAgLy8gQ2xlYXIgc3RhdGUgZnJvbSBwcmV2aW91cyBSdW4oKS4KKyAgdm9pZCBDbGVhcigpOworCisgIC8vIFJlbWFwcyBlYWNoIGZpbGUgaW4gaW5wdXRfZmlsZXNfIHNvIHRoYXQgaXQgaXMgcmVsYXRpdmUgdG8gb25lIG9mIHRoZQorICAvLyBkaXJlY3RvcmllcyBpbiBwcm90b19wYXRoXy4gIFJldHVybnMgZmFsc2UgaWYgYW4gZXJyb3Igb2NjdXJyZWQuICBUaGlzCisgIC8vIGlzIG9ubHkgdXNlZCBpZiBpbnB1dHNfYXJlX3Byb3RvX3BhdGhfcmVsYXRpdmVfIGlzIGZhbHNlLgorICBib29sIE1ha2VJbnB1dHNCZVByb3RvUGF0aFJlbGF0aXZlKAorICAgIERpc2tTb3VyY2VUcmVlKiBzb3VyY2VfdHJlZSk7CisKKyAgLy8gUmV0dXJuIHN0YXR1cyBmb3IgUGFyc2VBcmd1bWVudHMoKSBhbmQgSW50ZXJwcmV0QXJndW1lbnQoKS4KKyAgZW51bSBQYXJzZUFyZ3VtZW50U3RhdHVzIHsKKyAgICBQQVJTRV9BUkdVTUVOVF9ET05FX0FORF9DT05USU5VRSwKKyAgICBQQVJTRV9BUkdVTUVOVF9ET05FX0FORF9FWElULAorICAgIFBBUlNFX0FSR1VNRU5UX0ZBSUwKKyAgfTsKKworICAvLyBQYXJzZSBhbGwgY29tbWFuZC1saW5lIGFyZ3VtZW50cy4KKyAgUGFyc2VBcmd1bWVudFN0YXR1cyBQYXJzZUFyZ3VtZW50cyhpbnQgYXJnYywgY29uc3QgY2hhciogY29uc3QgYXJndltdKTsKKworICAvLyBQYXJzZXMgYSBjb21tYW5kLWxpbmUgYXJndW1lbnQgaW50byBhIG5hbWUvdmFsdWUgcGFpci4gIFJldHVybnMKKyAgLy8gdHJ1ZSBpZiB0aGUgbmV4dCBhcmd1bWVudCBpbiB0aGUgYXJndiBzaG91bGQgYmUgdXNlZCBhcyB0aGUgdmFsdWUsCisgIC8vIGZhbHNlIG90aGVyd2lzZS4KKyAgLy8KKyAgLy8gRXhhbXBsZXM6CisgIC8vICAgIi1Jc3JjL3Byb3RvcyIgLT4KKyAgLy8gICAgIG5hbWUgPSAiLUkiLCB2YWx1ZSA9ICJzcmMvcHJvdG9zIgorICAvLyAgICItLWNwcF9vdXQ9c3JjL2Zvby5wYjIuY2MiIC0+CisgIC8vICAgICBuYW1lID0gIi0tY3BwX291dCIsIHZhbHVlID0gInNyYy9mb28ucGIyLmNjIgorICAvLyAgICJmb28ucHJvdG8iIC0+CisgIC8vICAgICBuYW1lID0gIiIsIHZhbHVlID0gImZvby5wcm90byIKKyAgYm9vbCBQYXJzZUFyZ3VtZW50KGNvbnN0IGNoYXIqIGFyZywgc3RyaW5nKiBuYW1lLCBzdHJpbmcqIHZhbHVlKTsKKworICAvLyBJbnRlcnByZXRzIGFyZ3VtZW50cyBwYXJzZWQgd2l0aCBQYXJzZUFyZ3VtZW50LgorICBQYXJzZUFyZ3VtZW50U3RhdHVzIEludGVycHJldEFyZ3VtZW50KGNvbnN0IHN0cmluZyYgbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHZhbHVlKTsKKworICAvLyBQcmludCB0aGUgLS1oZWxwIHRleHQgdG8gc3RkZXJyLgorICB2b2lkIFByaW50SGVscFRleHQoKTsKKworICAvLyBHZW5lcmF0ZSB0aGUgZ2l2ZW4gb3V0cHV0IGZpbGUgZnJvbSB0aGUgZ2l2ZW4gaW5wdXQuCisgIHN0cnVjdCBPdXRwdXREaXJlY3RpdmU7ICAvLyBzZWUgYmVsb3cKKyAgYm9vbCBHZW5lcmF0ZU91dHB1dChjb25zdCB2ZWN0b3I8Y29uc3QgRmlsZURlc2NyaXB0b3IqPiYgcGFyc2VkX2ZpbGVzLAorICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE91dHB1dERpcmVjdGl2ZSYgb3V0cHV0X2RpcmVjdGl2ZSwKKyAgICAgICAgICAgICAgICAgICAgICBHZW5lcmF0b3JDb250ZXh0KiBnZW5lcmF0b3JfY29udGV4dCk7CisgIGJvb2wgR2VuZXJhdGVQbHVnaW5PdXRwdXQoY29uc3QgdmVjdG9yPGNvbnN0IEZpbGVEZXNjcmlwdG9yKj4mIHBhcnNlZF9maWxlcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHBsdWdpbl9uYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgcGFyYW1ldGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdlbmVyYXRvckNvbnRleHQqIGdlbmVyYXRvcl9jb250ZXh0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyogZXJyb3IpOworCisgIC8vIEltcGxlbWVudHMgLS1lbmNvZGUgYW5kIC0tZGVjb2RlLgorICBib29sIEVuY29kZU9yRGVjb2RlKGNvbnN0IERlc2NyaXB0b3JQb29sKiBwb29sKTsKKworICAvLyBJbXBsZW1lbnRzIHRoZSAtLWRlc2NyaXB0b3Jfc2V0X291dCBvcHRpb24uCisgIGJvb2wgV3JpdGVEZXNjcmlwdG9yU2V0KGNvbnN0IHZlY3Rvcjxjb25zdCBGaWxlRGVzY3JpcHRvcio+IHBhcnNlZF9maWxlcyk7CisKKyAgLy8gSW1wbGVtZW50cyB0aGUgLS1kZXBlbmRlbmN5X291dCBvcHRpb24KKyAgYm9vbCBHZW5lcmF0ZURlcGVuZGVuY3lNYW5pZmVzdEZpbGUoCisgICAgICBjb25zdCB2ZWN0b3I8Y29uc3QgRmlsZURlc2NyaXB0b3IqPiYgcGFyc2VkX2ZpbGVzLAorICAgICAgY29uc3QgR2VuZXJhdG9yQ29udGV4dE1hcCYgb3V0cHV0X2RpcmVjdG9yaWVzLAorICAgICAgRGlza1NvdXJjZVRyZWUqIHNvdXJjZV90cmVlKTsKKworICAvLyBHZXQgYWxsIHRyYW5zaXRpdmUgZGVwZW5kZW5jaWVzIG9mIHRoZSBnaXZlbiBmaWxlIChpbmNsdWRpbmcgdGhlIGZpbGUKKyAgLy8gaXRzZWxmKSwgYWRkaW5nIHRoZW0gdG8gdGhlIGdpdmVuIGxpc3Qgb2YgRmlsZURlc2NyaXB0b3JQcm90b3MuICBUaGUKKyAgLy8gcHJvdG9zIHdpbGwgYmUgb3JkZXJlZCBzdWNoIHRoYXQgZXZlcnkgZmlsZSBpcyBsaXN0ZWQgYmVmb3JlIGFueSBmaWxlIHRoYXQKKyAgLy8gZGVwZW5kcyBvbiBpdCwgc28gdGhhdCB5b3UgY2FuIGNhbGwgRGVzY3JpcHRvclBvb2w6OkJ1aWxkRmlsZSgpIG9uIHRoZW0KKyAgLy8gaW4gb3JkZXIuICBBbnkgZmlsZXMgaW4gKmFscmVhZHlfc2VlbiB3aWxsIG5vdCBiZSBhZGRlZCwgYW5kIGVhY2ggZmlsZQorICAvLyBhZGRlZCB3aWxsIGJlIGluc2VydGVkIGludG8gKmFscmVhZHlfc2Vlbi4gIElmIGluY2x1ZGVfc291cmNlX2NvZGVfaW5mbyBpcworICAvLyB0cnVlIHRoZW4gaW5jbHVkZSB0aGUgc291cmNlIGNvZGUgaW5mb3JtYXRpb24gaW4gdGhlIEZpbGVEZXNjcmlwdG9yUHJvdG9zLgorICAvLyBJZiBpbmNsdWRlX2pzb25fbmFtZSBpcyB0cnVlLCBwb3B1bGF0ZSB0aGUganNvbl9uYW1lIGZpZWxkIG9mCisgIC8vIEZpZWxkRGVzY3JpcHRvclByb3RvIGZvciBhbGwgZmllbGRzLgorICBzdGF0aWMgdm9pZCBHZXRUcmFuc2l0aXZlRGVwZW5kZW5jaWVzKAorICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUsCisgICAgICBib29sIGluY2x1ZGVfanNvbl9uYW1lLAorICAgICAgYm9vbCBpbmNsdWRlX3NvdXJjZV9jb2RlX2luZm8sCisgICAgICBzZXQ8Y29uc3QgRmlsZURlc2NyaXB0b3IqPiogYWxyZWFkeV9zZWVuLAorICAgICAgUmVwZWF0ZWRQdHJGaWVsZDxGaWxlRGVzY3JpcHRvclByb3RvPiogb3V0cHV0KTsKKworICAvLyBJbXBsZW1lbnRzIHRoZSAtLXByaW50X2ZyZWVfZmllbGRfbnVtYmVycy4gVGhpcyBmdW5jdGlvbiBwcmludHMgZnJlZSBmaWVsZAorICAvLyBudW1iZXJzIGludG8gc3Rkb3V0IGZvciB0aGUgbWVzc2FnZSBhbmQgaXQncyBuZXN0ZWQgbWVzc2FnZSB0eXBlcyBpbgorICAvLyBwb3N0LW9yZGVyLCBpLmUuIG5lc3RlZCB0eXBlcyBmaXJzdC4gUHJpbnRlZCByYW5nZSBhcmUgbGVmdC1yaWdodAorICAvLyBpbmNsdXNpdmUsIGkuZS4gW2EsIGJdLgorICAvLworICAvLyBHcm91cHM6CisgIC8vIEZvciBoaXN0b3JpY2FsIHJlYXNvbnMsIGdyb3VwcyBhcmUgY29uc2lkZXJlZCB0byBzaGFyZSB0aGUgc2FtZQorICAvLyBmaWVsZCBudW1iZXIgc3BhY2Ugd2l0aCB0aGUgcGFyZW50IG1lc3NhZ2UsIHRodXMgaXQgd2lsbCBub3QgcHJpbnQgZnJlZQorICAvLyBmaWVsZCBudW1iZXJzIGZvciBncm91cHMuIFRoZSBmaWVsZCBudW1iZXJzIHVzZWQgaW4gdGhlIGdyb3VwcyBhcmUKKyAgLy8gZXhjbHVkZWQgaW4gdGhlIGZyZWUgZmllbGQgbnVtYmVycyBvZiB0aGUgcGFyZW50IG1lc3NhZ2UuCisgIC8vCisgIC8vIEV4dGVuc2lvbiBSYW5nZXM6CisgIC8vIEV4dGVuc2lvbiByYW5nZXMgYXJlIGNvbnNpZGVyZWQgb2N1cHBpZWQgZmllbGQgbnVtYmVycyBhbmQgdGhleSB3aWxsIG5vdCBiZQorICAvLyBsaXN0ZWQgYXMgZnJlZSBudW1iZXJzIGluIHRoZSBvdXRwdXQuCisgIHZvaWQgUHJpbnRGcmVlRmllbGROdW1iZXJzKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gVGhlIG5hbWUgb2YgdGhlIGV4ZWN1dGFibGUgYXMgaW52b2tlZCAoaS5lLiBhcmd2WzBdKS4KKyAgc3RyaW5nIGV4ZWN1dGFibGVfbmFtZV87CisKKyAgLy8gVmVyc2lvbiBpbmZvIHNldCB3aXRoIFNldFZlcnNpb25JbmZvKCkuCisgIHN0cmluZyB2ZXJzaW9uX2luZm9fOworCisgIC8vIFJlZ2lzdGVyZWQgZ2VuZXJhdG9ycy4KKyAgc3RydWN0IEdlbmVyYXRvckluZm8geworICAgIHN0cmluZyBmbGFnX25hbWU7CisgICAgc3RyaW5nIG9wdGlvbl9mbGFnX25hbWU7CisgICAgQ29kZUdlbmVyYXRvciogZ2VuZXJhdG9yOworICAgIHN0cmluZyBoZWxwX3RleHQ7CisgIH07CisgIHR5cGVkZWYgbWFwPHN0cmluZywgR2VuZXJhdG9ySW5mbz4gR2VuZXJhdG9yTWFwOworICBHZW5lcmF0b3JNYXAgZ2VuZXJhdG9yc19ieV9mbGFnX25hbWVfOworICBHZW5lcmF0b3JNYXAgZ2VuZXJhdG9yc19ieV9vcHRpb25fbmFtZV87CisgIC8vIEEgbWFwIGZyb20gZ2VuZXJhdG9yIG5hbWVzIHRvIHRoZSBwYXJhbWV0ZXJzIHNwZWNpZmllZCB1c2luZyB0aGUgb3B0aW9uCisgIC8vIGZsYWcuIEZvciBleGFtcGxlLCBpZiB0aGUgdXNlciBpbnZva2VzIHRoZSBjb21waWxlciB3aXRoOgorICAvLyAgIHByb3RvYyAtLWZvb19vdXQ9b3V0cHV0ZGlyIC0tZm9vX29wdD1lbmFibGVfYmFyIC4uLgorICAvLyBUaGVuIHRoZXJlIHdpbGwgYmUgYW4gZW50cnkgKCItLWZvb19vdXQiLCAiZW5hYmxlX2JhciIpIGluIHRoaXMgbWFwLgorICBtYXA8c3RyaW5nLCBzdHJpbmc+IGdlbmVyYXRvcl9wYXJhbWV0ZXJzXzsKKworICAvLyBTZWUgQWxsb3dQbHVnaW5zKCkuICBJZiB0aGlzIGlzIGVtcHR5LCBwbHVnaW5zIGFyZW4ndCBhbGxvd2VkLgorICBzdHJpbmcgcGx1Z2luX3ByZWZpeF87CisKKyAgLy8gTWFwcyBzcGVjaWZpYyBwbHVnaW4gbmFtZXMgdG8gZmlsZXMuICBXaGVuIGV4ZWN1dGluZyBhIHBsdWdpbiwgdGhpcyBtYXAKKyAgLy8gaXMgc2VhcmNoZWQgZmlyc3QgdG8gZmluZCB0aGUgcGx1Z2luIGV4ZWN1dGFibGUuICBJZiBub3QgZm91bmQgaGVyZSwgdGhlCisgIC8vIFBBVEggKG9yIG90aGVyIE9TLXNwZWNpZmljIHNlYXJjaCBzdHJhdGVneSkgaXMgc2VhcmNoZWQuCisgIG1hcDxzdHJpbmcsIHN0cmluZz4gcGx1Z2luc187CisKKyAgLy8gU3R1ZmYgcGFyc2VkIGZyb20gY29tbWFuZCBsaW5lLgorICBlbnVtIE1vZGUgeworICAgIE1PREVfQ09NUElMRSwgIC8vIE5vcm1hbCBtb2RlOiAgcGFyc2UgLnByb3RvIGZpbGVzIGFuZCBjb21waWxlIHRoZW0uCisgICAgTU9ERV9FTkNPREUsICAgLy8gLS1lbmNvZGU6ICByZWFkIHRleHQgZnJvbSBzdGRpbiwgd3JpdGUgYmluYXJ5IHRvIHN0ZG91dC4KKyAgICBNT0RFX0RFQ09ERSwgICAvLyAtLWRlY29kZTogIHJlYWQgYmluYXJ5IGZyb20gc3RkaW4sIHdyaXRlIHRleHQgdG8gc3Rkb3V0LgorICAgIE1PREVfUFJJTlQsICAgIC8vIFByaW50IG1vZGU6IHByaW50IGluZm8gb2YgdGhlIGdpdmVuIC5wcm90byBmaWxlcyBhbmQgZXhpdC4KKyAgfTsKKworICBNb2RlIG1vZGVfOworCisgIGVudW0gUHJpbnRNb2RlIHsKKyAgICBQUklOVF9OT05FLCAgICAgICAgICAgICAgIC8vIE5vdCBpbiBNT0RFX1BSSU5UCisgICAgUFJJTlRfRlJFRV9GSUVMRFMsICAgICAgICAvLyAtLXByaW50X2ZyZWVfZmllbGRzCisgIH07CisKKyAgUHJpbnRNb2RlIHByaW50X21vZGVfOworCisgIGVudW0gRXJyb3JGb3JtYXQgeworICAgIEVSUk9SX0ZPUk1BVF9HQ0MsICAgLy8gR0NDIGVycm9yIG91dHB1dCBmb3JtYXQgKGRlZmF1bHQpLgorICAgIEVSUk9SX0ZPUk1BVF9NU1ZTICAgLy8gVmlzdWFsIFN0dWRpbyBvdXRwdXQgKC0tZXJyb3JfZm9ybWF0PW1zdnMpLgorICB9OworCisgIEVycm9yRm9ybWF0IGVycm9yX2Zvcm1hdF87CisKKyAgdmVjdG9yPHBhaXI8c3RyaW5nLCBzdHJpbmc+ID4gcHJvdG9fcGF0aF87ICAvLyBTZWFyY2ggcGF0aCBmb3IgcHJvdG8gZmlsZXMuCisgIHZlY3RvcjxzdHJpbmc+IGlucHV0X2ZpbGVzXzsgICAgICAgICAgICAgICAgLy8gTmFtZXMgb2YgdGhlIGlucHV0IHByb3RvIGZpbGVzLgorCisgIC8vIG91dHB1dF9kaXJlY3RpdmVzXyBsaXN0cyBhbGwgdGhlIGZpbGVzIHdlIGFyZSBzdXBwb3NlZCB0byBvdXRwdXQgYW5kIHdoYXQKKyAgLy8gZ2VuZXJhdG9yIHRvIHVzZSBmb3IgZWFjaC4KKyAgc3RydWN0IE91dHB1dERpcmVjdGl2ZSB7CisgICAgc3RyaW5nIG5hbWU7ICAgICAgICAgICAgICAgIC8vIEUuZy4gIi0tZm9vX291dCIKKyAgICBDb2RlR2VuZXJhdG9yKiBnZW5lcmF0b3I7ICAgLy8gTlVMTCBmb3IgcGx1Z2lucworICAgIHN0cmluZyBwYXJhbWV0ZXI7CisgICAgc3RyaW5nIG91dHB1dF9sb2NhdGlvbjsKKyAgfTsKKyAgdmVjdG9yPE91dHB1dERpcmVjdGl2ZT4gb3V0cHV0X2RpcmVjdGl2ZXNfOworCisgIC8vIFdoZW4gdXNpbmcgLS1lbmNvZGUgb3IgLS1kZWNvZGUsIHRoaXMgbmFtZXMgdGhlIHR5cGUgd2UgYXJlIGVuY29kaW5nIG9yCisgIC8vIGRlY29kaW5nLiAgKEVtcHR5IHN0cmluZyBpbmRpY2F0ZXMgLS1kZWNvZGVfcmF3LikKKyAgc3RyaW5nIGNvZGVjX3R5cGVfOworCisgIC8vIElmIC0tZGVzY3JpcHRvcl9zZXRfb3V0IHdhcyBnaXZlbiwgdGhpcyBpcyB0aGUgZmlsZW5hbWUgdG8gd2hpY2ggdGhlCisgIC8vIEZpbGVEZXNjcmlwdG9yU2V0IHNob3VsZCBiZSB3cml0dGVuLiAgT3RoZXJ3aXNlLCBlbXB0eS4KKyAgc3RyaW5nIGRlc2NyaXB0b3Jfc2V0X25hbWVfOworCisgIC8vIElmIC0tZGVwZW5kZW5jeV9vdXQgd2FzIGdpdmVuLCB0aGlzIGlzIHRoZSBwYXRoIHRvIHRoZSBmaWxlIHdoZXJlIHRoZQorICAvLyBkZXBlbmRlbmN5IGZpbGUgd2lsbCBiZSB3cml0dGVuLiBPdGhlcndpc2UsIGVtcHR5LgorICBzdHJpbmcgZGVwZW5kZW5jeV9vdXRfbmFtZV87CisKKyAgLy8gVHJ1ZSBpZiAtLWluY2x1ZGVfaW1wb3J0cyB3YXMgZ2l2ZW4sIG1lYW5pbmcgdGhhdCB3ZSBzaG91bGQKKyAgLy8gd3JpdGUgYWxsIHRyYW5zaXRpdmUgZGVwZW5kZW5jaWVzIHRvIHRoZSBEZXNjcmlwdG9yU2V0LiAgT3RoZXJ3aXNlLCBvbmx5CisgIC8vIHRoZSAucHJvdG8gZmlsZXMgbGlzdGVkIG9uIHRoZSBjb21tYW5kLWxpbmUgYXJlIGFkZGVkLgorICBib29sIGltcG9ydHNfaW5fZGVzY3JpcHRvcl9zZXRfOworCisgIC8vIFRydWUgaWYgLS1pbmNsdWRlX3NvdXJjZV9pbmZvIHdhcyBnaXZlbiwgbWVhbmluZyB0aGF0IHdlIHNob3VsZCBub3Qgc3RyaXAKKyAgLy8gU291cmNlQ29kZUluZm8gZnJvbSB0aGUgRGVzY3JpcHRvclNldC4KKyAgYm9vbCBzb3VyY2VfaW5mb19pbl9kZXNjcmlwdG9yX3NldF87CisKKyAgLy8gV2FzIHRoZSAtLWRpc2FsbG93X3NlcnZpY2VzIGZsYWcgdXNlZD8KKyAgYm9vbCBkaXNhbGxvd19zZXJ2aWNlc187CisKKyAgLy8gU2VlIFNldElucHV0c0FyZVByb3RvUGF0aFJlbGF0aXZlKCkuCisgIGJvb2wgaW5wdXRzX2FyZV9wcm90b19wYXRoX3JlbGF0aXZlXzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoQ29tbWFuZExpbmVJbnRlcmZhY2UpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ09NTUFORF9MSU5FX0lOVEVSRkFDRV9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY29tbWFuZF9saW5lX2ludGVyZmFjZV91bml0dGVzdC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY29tbWFuZF9saW5lX2ludGVyZmFjZV91bml0dGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZGEwMDdkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jb21tYW5kX2xpbmVfaW50ZXJmYWNlX3VuaXR0ZXN0LmNjCkBAIC0wLDAgKzEsMTgyOSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisjaW5jbHVkZSA8c3lzL3N0YXQuaD4KKyNpbmNsdWRlIDxmY250bC5oPgorI2lmZGVmIF9NU0NfVkVSCisjaW5jbHVkZSA8aW8uaD4KKyNlbHNlCisjaW5jbHVkZSA8dW5pc3RkLmg+CisjZW5kaWYKKyNpbmNsdWRlIDxtZW1vcnk+CisjaWZuZGVmIF9TSEFSRURfUFRSX0gKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc2hhcmVkX3B0ci5oPgorI2VuZGlmCisjaW5jbHVkZSA8dmVjdG9yPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvbW1hbmRfbGluZV9pbnRlcmZhY2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY29kZV9nZW5lcmF0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9maWxlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL21vY2tfY29kZV9nZW5lcmF0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvc3VicHJvY2Vzcy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZmlsZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N1YnN0aXR1dGUuaD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2dvb2dsZXRlc3QuaD4KKyNpbmNsdWRlIDxndGVzdC9ndGVzdC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworCisvLyBEaXNhYmxlIHRoZSB3aG9sZSB0ZXN0IHdoZW4gd2UgdXNlIHRjbWFsbG9jIGZvciAiZHJhY29uaWFuIiBoZWFwIGNoZWNrcywgaW4KKy8vIHdoaWNoIGNhc2UgdGNtYWxsb2Mgd2lsbCBwcmludCB3YXJuaW5ncyB0aGF0IGZhaWwgdGhlIHBsdWdpbiB0ZXN0cy4KKyNpZiAhR09PR0xFX1BST1RPQlVGX0hFQVBfQ0hFQ0tfRFJBQ09OSUFOCisKKyNpZiBkZWZpbmVkKF9XSU4zMikKKyNpZm5kZWYgU1RESU5fRklMRU5PCisjZGVmaW5lIFNURElOX0ZJTEVOTyAwCisjZW5kaWYKKyNpZm5kZWYgU1RET1VUX0ZJTEVOTworI2RlZmluZSBTVERPVVRfRklMRU5PIDEKKyNlbmRpZgorI2lmbmRlZiBGX09LCisjZGVmaW5lIEZfT0sgMDAgIC8vIG5vdCBkZWZpbmVkIGJ5IE1TVkMgZm9yIHdoYXRldmVyIHJlYXNvbgorI2VuZGlmCisjZW5kaWYKKworbmFtZXNwYWNlIHsKKworYm9vbCBGaWxlRXhpc3RzKGNvbnN0IHN0cmluZyYgcGF0aCkgeworICByZXR1cm4gRmlsZTo6RXhpc3RzKHBhdGgpOworfQorCitjbGFzcyBDb21tYW5kTGluZUludGVyZmFjZVRlc3QgOiBwdWJsaWMgdGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICB2aXJ0dWFsIHZvaWQgU2V0VXAoKTsKKyAgdmlydHVhbCB2b2lkIFRlYXJEb3duKCk7CisKKyAgLy8gUnVucyB0aGUgQ29tbWFuZExpbmVJbnRlcmZhY2Ugd2l0aCB0aGUgZ2l2ZW4gY29tbWFuZCBsaW5lLiAgVGhlCisgIC8vIGNvbW1hbmQgaXMgYXV0b21hdGljYWxseSBzcGxpdCBvbiBzcGFjZXMsIGFuZCB0aGUgc3RyaW5nICIkdG1wZGlyIgorICAvLyBpcyByZXBsYWNlZCB3aXRoIFRlc3RUZW1wRGlyKCkuCisgIHZvaWQgUnVuKGNvbnN0IHN0cmluZyYgY29tbWFuZCk7CisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgLy8gTWV0aG9kcyB0byBzZXQgdXAgdGhlIHRlc3QgKGNhbGxlZCBiZWZvcmUgUnVuKCkpLgorCisgIGNsYXNzIE51bGxDb2RlR2VuZXJhdG9yOworCisgIC8vIE5vcm1hbGx5IHBsdWdpbnMgYXJlIGFsbG93ZWQgZm9yIGFsbCB0ZXN0cy4gIENhbGwgdGhpcyB0byBleHBsaWNpdGx5CisgIC8vIGRpc2FibGUgdGhlbS4KKyAgdm9pZCBEaXNhbGxvd1BsdWdpbnMoKSB7IGRpc2FsbG93X3BsdWdpbnNfID0gdHJ1ZTsgfQorCisgIC8vIENyZWF0ZSBhIHRlbXAgZmlsZSB3aXRoaW4gdGVtcF9kaXJlY3RvcnlfIHdpdGggdGhlIGdpdmVuIG5hbWUuCisgIC8vIFRoZSBjb250YWluaW5nIGRpcmVjdG9yeSBpcyBhbHNvIGNyZWF0ZWQgaWYgbmVjZXNzYXJ5LgorICB2b2lkIENyZWF0ZVRlbXBGaWxlKGNvbnN0IHN0cmluZyYgbmFtZSwgY29uc3Qgc3RyaW5nJiBjb250ZW50cyk7CisKKyAgLy8gQ3JlYXRlIGEgc3ViZGlyZWN0b3J5IHdpdGhpbiB0ZW1wX2RpcmVjdG9yeV8uCisgIHZvaWQgQ3JlYXRlVGVtcERpcihjb25zdCBzdHJpbmcmIG5hbWUpOworCisjaWZkZWYgUFJPVE9CVUZfT1BFTlNPVVJDRQorICAvLyBDaGFuZ2Ugd29ya2luZyBkaXJlY3RvcnkgdG8gdGVtcCBkaXJlY3RvcnkuCisgIHZvaWQgU3dpdGNoVG9UZW1wRGlyZWN0b3J5KCkgeworICAgIEZpbGU6OkNoYW5nZVdvcmtpbmdEaXJlY3RvcnkodGVtcF9kaXJlY3RvcnlfKTsKKyAgfQorI2Vsc2UgIC8vICFQUk9UT0JVRl9PUEVOU09VUkNFCisgIC8vIFRPRE8odGVib3JpbmcpOiBGaWd1cmUgb3V0IGhvdyB0byBjaGFuZ2UgYW5kIGdldCB3b3JraW5nIGRpcmVjdG9yeSBpbgorICAvLyBnb29nbGUzLgorI2VuZGlmICAvLyAhUFJPVE9CVUZfT1BFTlNPVVJDRQorCisgIHZvaWQgU2V0SW5wdXRzQXJlUHJvdG9QYXRoUmVsYXRpdmUoYm9vbCBlbmFibGUpIHsKKyAgICBjbGlfLlNldElucHV0c0FyZVByb3RvUGF0aFJlbGF0aXZlKGVuYWJsZSk7CisgIH0KKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAvLyBNZXRob2RzIHRvIGNoZWNrIHRoZSB0ZXN0IHJlc3VsdHMgKGNhbGxlZCBhZnRlciBSdW4oKSkuCisKKyAgLy8gQ2hlY2tzIHRoYXQgbm8gdGV4dCB3YXMgd3JpdHRlbiB0byBzdGRlcnIgZHVyaW5nIFJ1bigpLCBhbmQgUnVuKCkKKyAgLy8gcmV0dXJuZWQgMC4KKyAgdm9pZCBFeHBlY3ROb0Vycm9ycygpOworCisgIC8vIENoZWNrcyB0aGF0IFJ1bigpIHJldHVybmVkIG5vbi16ZXJvIGFuZCB0aGUgc3RkZXJyIG91dHB1dCBpcyBleGFjdGx5CisgIC8vIHRoZSB0ZXh0IGdpdmVuLiAgZXhwZWN0ZWRfdGVzdCBtYXkgY29udGFpbiByZWZlcmVuY2VzIHRvICIkdG1wZGlyIiwKKyAgLy8gd2hpY2ggd2lsbCBiZSByZXBsYWNlZCBieSB0aGUgdGVtcG9yYXJ5IGRpcmVjdG9yeSBwYXRoLgorICB2b2lkIEV4cGVjdEVycm9yVGV4dChjb25zdCBzdHJpbmcmIGV4cGVjdGVkX3RleHQpOworCisgIC8vIENoZWNrcyB0aGF0IFJ1bigpIHJldHVybmVkIG5vbi16ZXJvIGFuZCB0aGUgc3RkZXJyIGNvbnRhaW5zIHRoZSBnaXZlbgorICAvLyBzdWJzdHJpbmcuCisgIHZvaWQgRXhwZWN0RXJyb3JTdWJzdHJpbmcoY29uc3Qgc3RyaW5nJiBleHBlY3RlZF9zdWJzdHJpbmcpOworCisgIC8vIExpa2UgRXhwZWN0RXJyb3JTdWJzdHJpbmcsIGJ1dCBjaGVja3MgdGhhdCBSdW4oKSByZXR1cm5lZCB6ZXJvLgorICB2b2lkIEV4cGVjdEVycm9yU3Vic3RyaW5nV2l0aFplcm9SZXR1cm5Db2RlKAorICAgICAgY29uc3Qgc3RyaW5nJiBleHBlY3RlZF9zdWJzdHJpbmcpOworCisgIC8vIENoZWNrcyB0aGF0IHRoZSBjYXB0dXJlZCBzdGRvdXQgaXMgdGhlIHNhbWUgYXMgdGhlIGV4cGVjdGVkX3RleHQuCisgIHZvaWQgRXhwZWN0Q2FwdHVyZWRTdGRvdXQoY29uc3Qgc3RyaW5nJiBleHBlY3RlZF90ZXh0KTsKKworICAvLyBSZXR1cm5zIHRydWUgaWYgRXhwZWN0RXJyb3JTdWJzdHJpbmcoZXhwZWN0ZWRfc3Vic3RyaW5nKSB3b3VsZCBwYXNzLCBidXQKKyAgLy8gZG9lcyBub3QgZmFpbCBvdGhlcndpc2UuCisgIGJvb2wgSGFzQWx0ZXJuYXRlRXJyb3JTdWJzdHJpbmcoY29uc3Qgc3RyaW5nJiBleHBlY3RlZF9zdWJzdHJpbmcpOworCisgIC8vIENoZWNrcyB0aGF0IE1vY2tDb2RlR2VuZXJhdG9yOjpHZW5lcmF0ZSgpIHdhcyBjYWxsZWQgaW4gdGhlIGdpdmVuCisgIC8vIGNvbnRleHQgKG9yIHRoZSBnZW5lcmF0b3IgaW4gdGVzdF9wbHVnaW4uY2MsIHdoaWNoIHByb2R1Y2VzIHRoZSBzYW1lCisgIC8vIG91dHB1dCkuICBUaGF0IGlzLCB0aGlzIHRlc3RzIGlmIHRoZSBnZW5lcmF0b3Igd2l0aCB0aGUgZ2l2ZW4gbmFtZQorICAvLyB3YXMgY2FsbGVkIHdpdGggdGhlIGdpdmVuIHBhcmFtZXRlciBhbmQgcHJvdG8gZmlsZSBhbmQgcHJvZHVjZWQgdGhlCisgIC8vIGdpdmVuIG91dHB1dCBmaWxlLiAgVGhpcyBpcyBjaGVja2VkIGJ5IHJlYWRpbmcgdGhlIG91dHB1dCBmaWxlIGFuZAorICAvLyBjaGVja2luZyB0aGF0IGl0IGNvbnRhaW5zIHRoZSBjb250ZW50IHRoYXQgTW9ja0NvZGVHZW5lcmF0b3Igd291bGQKKyAgLy8gZ2VuZXJhdGUgZ2l2ZW4gdGhlc2UgaW5wdXRzLiAgbWVzc2FnZV9uYW1lIGlzIHRoZSBuYW1lIG9mIHRoZSBmaXJzdAorICAvLyBtZXNzYWdlIHRoYXQgYXBwZWFyZWQgaW4gdGhlIHByb3RvIGZpbGU7IHRoaXMgaXMganVzdCB0byBtYWtlIGV4dHJhCisgIC8vIHN1cmUgdGhhdCB0aGUgY29ycmVjdCBmaWxlIHdhcyBwYXJzZWQuCisgIHZvaWQgRXhwZWN0R2VuZXJhdGVkKGNvbnN0IHN0cmluZyYgZ2VuZXJhdG9yX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgcGFyYW1ldGVyLAorICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHByb3RvX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgbWVzc2FnZV9uYW1lKTsKKyAgdm9pZCBFeHBlY3RHZW5lcmF0ZWQoY29uc3Qgc3RyaW5nJiBnZW5lcmF0b3JfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBwYXJhbWV0ZXIsCisgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgcHJvdG9fbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBtZXNzYWdlX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgb3V0cHV0X2RpcmVjdG9yeSk7CisgIHZvaWQgRXhwZWN0R2VuZXJhdGVkV2l0aE11bHRpcGxlSW5wdXRzKGNvbnN0IHN0cmluZyYgZ2VuZXJhdG9yX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgYWxsX3Byb3RvX25hbWVzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHByb3RvX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgbWVzc2FnZV9uYW1lKTsKKyAgdm9pZCBFeHBlY3RHZW5lcmF0ZWRXaXRoSW5zZXJ0aW9ucyhjb25zdCBzdHJpbmcmIGdlbmVyYXRvcl9uYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgcGFyYW1ldGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgaW5zZXJ0aW9ucywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHByb3RvX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBtZXNzYWdlX25hbWUpOworCisgIHZvaWQgRXhwZWN0TnVsbENvZGVHZW5lcmF0b3JDYWxsZWQoY29uc3Qgc3RyaW5nJiBwYXJhbWV0ZXIpOworCisgIHZvaWQgUmVhZERlc2NyaXB0b3JTZXQoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlRGVzY3JpcHRvclNldCogZGVzY3JpcHRvcl9zZXQpOworCisgIHZvaWQgRXhwZWN0RmlsZUNvbnRlbnQoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIGNvbnRlbnQpOworCisgcHJpdmF0ZToKKyAgLy8gVGhlIG9iamVjdCB3ZSBhcmUgdGVzdGluZy4KKyAgQ29tbWFuZExpbmVJbnRlcmZhY2UgY2xpXzsKKworICAvLyBXYXMgRGlzYWxsb3dQbHVnaW5zKCkgY2FsbGVkPworICBib29sIGRpc2FsbG93X3BsdWdpbnNfOworCisgIC8vIFdlIGNyZWF0ZSBhIGRpcmVjdG9yeSB3aXRoaW4gVGVzdFRlbXBEaXIoKSBpbiBvcmRlciB0byBhZGQgZXh0cmEKKyAgLy8gcHJvdGVjdGlvbiBhZ2FpbnN0IGFjY2lkZW50YWxseSBkZWxldGluZyB1c2VyIGZpbGVzIChzaW5jZSB3ZSByZWN1cnNpdmVseQorICAvLyBkZWxldGUgdGhpcyBkaXJlY3RvcnkgZHVyaW5nIHRoZSB0ZXN0KS4gIFRoaXMgaXMgdGhlIGZ1bGwgcGF0aCBvZiB0aGF0CisgIC8vIGRpcmVjdG9yeS4KKyAgc3RyaW5nIHRlbXBfZGlyZWN0b3J5XzsKKworICAvLyBUaGUgcmVzdWx0IG9mIFJ1bigpLgorICBpbnQgcmV0dXJuX2NvZGVfOworCisgIC8vIFRoZSBjYXB0dXJlZCBzdGRlcnIgb3V0cHV0LgorICBzdHJpbmcgZXJyb3JfdGV4dF87CisKKyAgLy8gVGhlIGNhcHR1cmVkIHN0ZG91dC4KKyAgc3RyaW5nIGNhcHR1cmVkX3N0ZG91dF87CisKKyAgLy8gUG9pbnRlcnMgd2hpY2ggbmVlZCB0byBiZSBkZWxldGVkIGxhdGVyLgorICB2ZWN0b3I8Q29kZUdlbmVyYXRvcio+IG1vY2tfZ2VuZXJhdG9yc190b19kZWxldGVfOworCisgIE51bGxDb2RlR2VuZXJhdG9yKiBudWxsX2dlbmVyYXRvcl87Cit9OworCitjbGFzcyBDb21tYW5kTGluZUludGVyZmFjZVRlc3Q6Ok51bGxDb2RlR2VuZXJhdG9yIDogcHVibGljIENvZGVHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgTnVsbENvZGVHZW5lcmF0b3IoKSA6IGNhbGxlZF8oZmFsc2UpIHt9CisgIH5OdWxsQ29kZUdlbmVyYXRvcigpIHt9CisKKyAgbXV0YWJsZSBib29sIGNhbGxlZF87CisgIG11dGFibGUgc3RyaW5nIHBhcmFtZXRlcl87CisKKyAgLy8gaW1wbGVtZW50cyBDb2RlR2VuZXJhdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgYm9vbCBHZW5lcmF0ZShjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSwKKyAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHBhcmFtZXRlciwKKyAgICAgICAgICAgICAgICBHZW5lcmF0b3JDb250ZXh0KiBjb250ZXh0LAorICAgICAgICAgICAgICAgIHN0cmluZyogZXJyb3IpIGNvbnN0IHsKKyAgICBjYWxsZWRfID0gdHJ1ZTsKKyAgICBwYXJhbWV0ZXJfID0gcGFyYW1ldGVyOworICAgIHJldHVybiB0cnVlOworICB9Cit9OworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK3ZvaWQgQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0OjpTZXRVcCgpIHsKKyAgLy8gTW9zdCBvZiB0aGVzZSB0ZXN0cyB3ZXJlIHdyaXR0ZW4gYmVmb3JlIHRoaXMgb3B0aW9uIHdhcyBhZGRlZCwgc28gd2UKKyAgLy8gcnVuIHdpdGggdGhlIG9wdGlvbiBvbiAod2hpY2ggdXNlZCB0byBiZSB0aGUgb25seSB3YXkpIGV4Y2VwdCBpbiBjZXJ0YWluCisgIC8vIHRlc3RzIHdoZXJlIHdlIHR1cm4gaXQgb2ZmLgorICBjbGlfLlNldElucHV0c0FyZVByb3RvUGF0aFJlbGF0aXZlKHRydWUpOworCisgIHRlbXBfZGlyZWN0b3J5XyA9IFRlc3RUZW1wRGlyKCkgKyAiL3Byb3RvMl9jbGlfdGVzdF90ZW1wIjsKKworICAvLyBJZiB0aGUgdGVtcCBkaXJlY3RvcnkgYWxyZWFkeSBleGlzdHMsIGl0IG11c3QgYmUgbGVmdCBvdmVyIGZyb20gYQorICAvLyBwcmV2aW91cyBydW4uICBEZWxldGUgaXQuCisgIGlmIChGaWxlRXhpc3RzKHRlbXBfZGlyZWN0b3J5XykpIHsKKyAgICBGaWxlOjpEZWxldGVSZWN1cnNpdmVseSh0ZW1wX2RpcmVjdG9yeV8sIE5VTEwsIE5VTEwpOworICB9CisKKyAgLy8gQ3JlYXRlIHRoZSB0ZW1wIGRpcmVjdG9yeS4KKyAgR09PR0xFX0NIRUNLX09LKEZpbGU6OkNyZWF0ZURpcih0ZW1wX2RpcmVjdG9yeV8sIDA3NzcpKTsKKworICAvLyBSZWdpc3RlciBnZW5lcmF0b3JzLgorICBDb2RlR2VuZXJhdG9yKiBnZW5lcmF0b3IgPSBuZXcgTW9ja0NvZGVHZW5lcmF0b3IoInRlc3RfZ2VuZXJhdG9yIik7CisgIG1vY2tfZ2VuZXJhdG9yc190b19kZWxldGVfLnB1c2hfYmFjayhnZW5lcmF0b3IpOworICBjbGlfLlJlZ2lzdGVyR2VuZXJhdG9yKCItLXRlc3Rfb3V0IiwgIi0tdGVzdF9vcHQiLCBnZW5lcmF0b3IsICJUZXN0IG91dHB1dC4iKTsKKyAgY2xpXy5SZWdpc3RlckdlbmVyYXRvcigiLXQiLCBnZW5lcmF0b3IsICJUZXN0IG91dHB1dC4iKTsKKworICBnZW5lcmF0b3IgPSBuZXcgTW9ja0NvZGVHZW5lcmF0b3IoImFsdF9nZW5lcmF0b3IiKTsKKyAgbW9ja19nZW5lcmF0b3JzX3RvX2RlbGV0ZV8ucHVzaF9iYWNrKGdlbmVyYXRvcik7CisgIGNsaV8uUmVnaXN0ZXJHZW5lcmF0b3IoIi0tYWx0X291dCIsIGdlbmVyYXRvciwgIkFsdCBvdXRwdXQuIik7CisKKyAgZ2VuZXJhdG9yID0gbnVsbF9nZW5lcmF0b3JfID0gbmV3IE51bGxDb2RlR2VuZXJhdG9yKCk7CisgIG1vY2tfZ2VuZXJhdG9yc190b19kZWxldGVfLnB1c2hfYmFjayhnZW5lcmF0b3IpOworICBjbGlfLlJlZ2lzdGVyR2VuZXJhdG9yKCItLW51bGxfb3V0IiwgZ2VuZXJhdG9yLCAiTnVsbCBvdXRwdXQuIik7CisKKyAgZGlzYWxsb3dfcGx1Z2luc18gPSBmYWxzZTsKK30KKwordm9pZCBDb21tYW5kTGluZUludGVyZmFjZVRlc3Q6OlRlYXJEb3duKCkgeworICAvLyBEZWxldGUgdGhlIHRlbXAgZGlyZWN0b3J5LgorICBpZiAoRmlsZUV4aXN0cyh0ZW1wX2RpcmVjdG9yeV8pKSB7CisgICAgRmlsZTo6RGVsZXRlUmVjdXJzaXZlbHkodGVtcF9kaXJlY3RvcnlfLCBOVUxMLCBOVUxMKTsKKyAgfQorCisgIC8vIERlbGV0ZSBhbGwgdGhlIE1vY2tDb2RlR2VuZXJhdG9ycy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBtb2NrX2dlbmVyYXRvcnNfdG9fZGVsZXRlXy5zaXplKCk7IGkrKykgeworICAgIGRlbGV0ZSBtb2NrX2dlbmVyYXRvcnNfdG9fZGVsZXRlX1tpXTsKKyAgfQorICBtb2NrX2dlbmVyYXRvcnNfdG9fZGVsZXRlXy5jbGVhcigpOworfQorCit2b2lkIENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdDo6UnVuKGNvbnN0IHN0cmluZyYgY29tbWFuZCkgeworICB2ZWN0b3I8c3RyaW5nPiBhcmdzID0gU3BsaXQoY29tbWFuZCwgIiAiLCB0cnVlKTsKKworICBpZiAoIWRpc2FsbG93X3BsdWdpbnNfKSB7CisgICAgY2xpXy5BbGxvd1BsdWdpbnMoInByZWZpeC0iKTsKKyNpZm5kZWYgR09PR0xFX1RISVJEX1BBUlRZX1BST1RPQlVGCisgICAgc3RyaW5nIHBsdWdpbl9wYXRoOworI2lmZGVmIEdPT0dMRV9QUk9UT0JVRl9URVNUX1BMVUdJTl9QQVRICisgICAgcGx1Z2luX3BhdGggPSBHT09HTEVfUFJPVE9CVUZfVEVTVF9QTFVHSU5fUEFUSDsKKyNlbHNlCisgICAgY29uc3QgY2hhciogcG9zc2libGVfcGF0aHNbXSA9IHsKKyAgICAgIC8vIFdoZW4gYnVpbGRpbmcgd2l0aCBzaGFyZWQgbGlicmFyaWVzLCBsaWJ0b29sIGhpZGVzIHRoZSByZWFsIGV4ZWN1dGFibGUKKyAgICAgIC8vIGluIC5saWJzIGFuZCBwdXRzIGEgZmFrZSB3cmFwcGVyIGluIHRoZSBjdXJyZW50IGRpcmVjdG9yeS4KKyAgICAgIC8vIFVuZm9ydHVuYXRlbHksIGR1ZSB0byBhbiBhcHBhcmVudCBidWcgb24gQ3lnd2luL01pbkdXLCBpZiBvbmUgcHJvZ3JhbQorICAgICAgLy8gd3JhcHBlZCBpbiB0aGlzIHdheSAoZS5nLiBwcm90b2J1Zi10ZXN0cy5leGUpIHRyaWVzIHRvIGV4ZWN1dGUgYW5vdGhlcgorICAgICAgLy8gcHJvZ3JhbSB3cmFwcGVkIGluIHRoaXMgd2F5IChlLmcuIHRlc3RfcGx1Z2luLmV4ZSksIHRoZSBsYXR0ZXIgZmFpbHMKKyAgICAgIC8vIHdpdGggZXJyb3IgY29kZSAxMjcgYW5kIG5vIGV4cGxhbmF0aW9uIG1lc3NhZ2UuICBQcmVzdW1hYmx5IHRoZSBwcm9ibGVtCisgICAgICAvLyBpcyB0aGF0IHRoZSB3cmFwcGVyIGZvciBwcm90b2J1Zi10ZXN0cy5leGUgc2V0IHNvbWUgZW52aXJvbm1lbnQKKyAgICAgIC8vIHZhcmlhYmxlcyB0aGF0IGNvbmZ1c2UgdGhlIHdyYXBwZXIgZm9yIHRlc3RfcGx1Z2luLmV4ZS4gIEx1Y2tpbHksIGl0CisgICAgICAvLyB0dXJucyBvdXQgdGhhdCBpZiB3ZSBzaW1wbHkgaW52b2tlIHRoZSB3cmFwcGVkIHRlc3RfcGx1Z2luLmV4ZQorICAgICAgLy8gZGlyZWN0bHksIGl0IHdvcmtzIC0tIEkgZ3Vlc3MgdGhlIGVudmlyb25tZW50IHZhcmlhYmxlcyBzZXQgYnkgdGhlCisgICAgICAvLyBwcm90b2J1Zi10ZXN0cy5leGUgd3JhcHBlciBoYXBwZW4gdG8gYmUgY29ycmVjdCBmb3IgaXQgdG9vLiAgU28gd2UgZG8KKyAgICAgIC8vIHRoYXQuCisgICAgICAiLmxpYnMvdGVzdF9wbHVnaW4uZXhlIiwgIC8vIFdpbjMyIHcvYXV0b3Rvb2wgKEN5Z3dpbiAvIE1pbkdXKQorICAgICAgInRlc3RfcGx1Z2luLmV4ZSIsICAgICAgICAvLyBPdGhlciBXaW4zMiAoTVNWQykKKyAgICAgICJ0ZXN0X3BsdWdpbiIsICAgICAgICAgICAgLy8gVW5peAorICAgIH07CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBHT09HTEVfQVJSQVlTSVpFKHBvc3NpYmxlX3BhdGhzKTsgaSsrKSB7CisgICAgICBpZiAoYWNjZXNzKHBvc3NpYmxlX3BhdGhzW2ldLCBGX09LKSA9PSAwKSB7CisgICAgICAgIHBsdWdpbl9wYXRoID0gcG9zc2libGVfcGF0aHNbaV07CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyNlbmRpZgorCisgICAgaWYgKHBsdWdpbl9wYXRoLmVtcHR5KCkpIHsKKyNlbHNlCisgICAgc3RyaW5nIHBsdWdpbl9wYXRoID0gInRoaXJkX3BhcnR5L3Byb3RvYnVmL3Rlc3RfcGx1Z2luIjsKKworICAgIGlmIChhY2Nlc3MocGx1Z2luX3BhdGguY19zdHIoKSwgRl9PSykgIT0gMCkgeworI2VuZGlmICAvLyBHT09HTEVfVEhJUkRfUEFSVFlfUFJPVE9CVUYKKyAgICAgIEdPT0dMRV9MT0coRVJST1IpCisgICAgICAgICAgPDwgIlBsdWdpbiBleGVjdXRhYmxlIG5vdCBmb3VuZC4gIFBsdWdpbiB0ZXN0cyBhcmUgbGlrZWx5IHRvIGZhaWwuIjsKKyAgICB9IGVsc2UgeworICAgICAgYXJncy5wdXNoX2JhY2soIi0tcGx1Z2luPXByZWZpeC1nZW4tcGx1Zz0iICsgcGx1Z2luX3BhdGgpOworICAgIH0KKyAgfQorCisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9hcnJheTxjb25zdCBjaGFyICogPiBhcmd2KG5ldyBjb25zdCBjaGFyKiBbYXJncy5zaXplKCldKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGFyZ3Muc2l6ZSgpOyBpKyspIHsKKyAgICBhcmdzW2ldID0gU3RyaW5nUmVwbGFjZShhcmdzW2ldLCAiJHRtcGRpciIsIHRlbXBfZGlyZWN0b3J5XywgdHJ1ZSk7CisgICAgYXJndltpXSA9IGFyZ3NbaV0uY19zdHIoKTsKKyAgfQorCisgIC8vIFRPRE8oamllbHVvKTogQ3lnd2luIGRvZXNuJ3Qgd29yayB3ZWxsIGlmIHdlIHRyeSB0byBjYXB0dXJlIHN0ZGVyciBhbmQKKyAgLy8gc3Rkb3V0IGF0IHRoZSBzYW1lIHRpbWUuIE5lZWQgdG8gZmlndXJlIG91dCB3aHkgYW5kIGFkZCB0aGlzIGNhcHR1cmUgYmFjaworICAvLyBmb3IgQ3lnd2luLgorI2lmICFkZWZpbmVkKF9fQ1lHV0lOX18pCisgIENhcHR1cmVUZXN0U3Rkb3V0KCk7CisjZW5kaWYKKyAgQ2FwdHVyZVRlc3RTdGRlcnIoKTsKKworICByZXR1cm5fY29kZV8gPSBjbGlfLlJ1bihhcmdzLnNpemUoKSwgYXJndi5nZXQoKSk7CisKKyAgZXJyb3JfdGV4dF8gPSBHZXRDYXB0dXJlZFRlc3RTdGRlcnIoKTsKKyNpZiAhZGVmaW5lZChfX0NZR1dJTl9fKQorICBjYXB0dXJlZF9zdGRvdXRfID0gR2V0Q2FwdHVyZWRUZXN0U3Rkb3V0KCk7CisjZW5kaWYKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdDo6Q3JlYXRlVGVtcEZpbGUoCisgICAgY29uc3Qgc3RyaW5nJiBuYW1lLAorICAgIGNvbnN0IHN0cmluZyYgY29udGVudHMpIHsKKyAgLy8gQ3JlYXRlIHBhcmVudCBkaXJlY3RvcnksIGlmIG5lY2Vzc2FyeS4KKyAgc3RyaW5nOjpzaXplX3R5cGUgc2xhc2hfcG9zID0gbmFtZS5maW5kX2xhc3Rfb2YoJy8nKTsKKyAgaWYgKHNsYXNoX3BvcyAhPSBzdHJpbmc6Om5wb3MpIHsKKyAgICBzdHJpbmcgZGlyID0gbmFtZS5zdWJzdHIoMCwgc2xhc2hfcG9zKTsKKyAgICBpZiAoIUZpbGVFeGlzdHModGVtcF9kaXJlY3RvcnlfICsgIi8iICsgZGlyKSkgeworICAgICAgR09PR0xFX0NIRUNLX09LKEZpbGU6OlJlY3Vyc2l2ZWx5Q3JlYXRlRGlyKHRlbXBfZGlyZWN0b3J5XyArICIvIiArIGRpciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDA3NzcpKTsKKyAgICB9CisgIH0KKworICAvLyBXcml0ZSBmaWxlLgorICBzdHJpbmcgZnVsbF9uYW1lID0gdGVtcF9kaXJlY3RvcnlfICsgIi8iICsgbmFtZTsKKyAgR09PR0xFX0NIRUNLX09LKEZpbGU6OlNldENvbnRlbnRzKGZ1bGxfbmFtZSwgY29udGVudHMsIHRydWUpKTsKK30KKwordm9pZCBDb21tYW5kTGluZUludGVyZmFjZVRlc3Q6OkNyZWF0ZVRlbXBEaXIoY29uc3Qgc3RyaW5nJiBuYW1lKSB7CisgIEdPT0dMRV9DSEVDS19PSyhGaWxlOjpSZWN1cnNpdmVseUNyZWF0ZURpcih0ZW1wX2RpcmVjdG9yeV8gKyAiLyIgKyBuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwNzc3KSk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBDb21tYW5kTGluZUludGVyZmFjZVRlc3Q6OkV4cGVjdE5vRXJyb3JzKCkgeworICBFWFBFQ1RfRVEoMCwgcmV0dXJuX2NvZGVfKTsKKyAgRVhQRUNUX0VRKCIiLCBlcnJvcl90ZXh0Xyk7Cit9CisKK3ZvaWQgQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0OjpFeHBlY3RFcnJvclRleHQoY29uc3Qgc3RyaW5nJiBleHBlY3RlZF90ZXh0KSB7CisgIEVYUEVDVF9ORSgwLCByZXR1cm5fY29kZV8pOworICBFWFBFQ1RfRVEoU3RyaW5nUmVwbGFjZShleHBlY3RlZF90ZXh0LCAiJHRtcGRpciIsIHRlbXBfZGlyZWN0b3J5XywgdHJ1ZSksCisgICAgICAgICAgICBlcnJvcl90ZXh0Xyk7Cit9CisKK3ZvaWQgQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0OjpFeHBlY3RFcnJvclN1YnN0cmluZygKKyAgICBjb25zdCBzdHJpbmcmIGV4cGVjdGVkX3N1YnN0cmluZykgeworICBFWFBFQ1RfTkUoMCwgcmV0dXJuX2NvZGVfKTsKKyAgRVhQRUNUX1BSRURfRk9STUFUMih0ZXN0aW5nOjpJc1N1YnN0cmluZywgZXhwZWN0ZWRfc3Vic3RyaW5nLCBlcnJvcl90ZXh0Xyk7Cit9CisKK3ZvaWQgQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0OjpFeHBlY3RFcnJvclN1YnN0cmluZ1dpdGhaZXJvUmV0dXJuQ29kZSgKKyAgICBjb25zdCBzdHJpbmcmIGV4cGVjdGVkX3N1YnN0cmluZykgeworICBFWFBFQ1RfRVEoMCwgcmV0dXJuX2NvZGVfKTsKKyAgRVhQRUNUX1BSRURfRk9STUFUMih0ZXN0aW5nOjpJc1N1YnN0cmluZywgZXhwZWN0ZWRfc3Vic3RyaW5nLCBlcnJvcl90ZXh0Xyk7Cit9CisKK2Jvb2wgQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0OjpIYXNBbHRlcm5hdGVFcnJvclN1YnN0cmluZygKKyAgICBjb25zdCBzdHJpbmcmIGV4cGVjdGVkX3N1YnN0cmluZykgeworICBFWFBFQ1RfTkUoMCwgcmV0dXJuX2NvZGVfKTsKKyAgcmV0dXJuIGVycm9yX3RleHRfLmZpbmQoZXhwZWN0ZWRfc3Vic3RyaW5nKSAhPSBzdHJpbmc6Om5wb3M7Cit9CisKK3ZvaWQgQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0OjpFeHBlY3RHZW5lcmF0ZWQoCisgICAgY29uc3Qgc3RyaW5nJiBnZW5lcmF0b3JfbmFtZSwKKyAgICBjb25zdCBzdHJpbmcmIHBhcmFtZXRlciwKKyAgICBjb25zdCBzdHJpbmcmIHByb3RvX25hbWUsCisgICAgY29uc3Qgc3RyaW5nJiBtZXNzYWdlX25hbWUpIHsKKyAgTW9ja0NvZGVHZW5lcmF0b3I6OkV4cGVjdEdlbmVyYXRlZCgKKyAgICAgIGdlbmVyYXRvcl9uYW1lLCBwYXJhbWV0ZXIsICIiLCBwcm90b19uYW1lLCBtZXNzYWdlX25hbWUsIHByb3RvX25hbWUsCisgICAgICB0ZW1wX2RpcmVjdG9yeV8pOworfQorCit2b2lkIENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdDo6RXhwZWN0R2VuZXJhdGVkKAorICAgIGNvbnN0IHN0cmluZyYgZ2VuZXJhdG9yX25hbWUsCisgICAgY29uc3Qgc3RyaW5nJiBwYXJhbWV0ZXIsCisgICAgY29uc3Qgc3RyaW5nJiBwcm90b19uYW1lLAorICAgIGNvbnN0IHN0cmluZyYgbWVzc2FnZV9uYW1lLAorICAgIGNvbnN0IHN0cmluZyYgb3V0cHV0X2RpcmVjdG9yeSkgeworICBNb2NrQ29kZUdlbmVyYXRvcjo6RXhwZWN0R2VuZXJhdGVkKAorICAgICAgZ2VuZXJhdG9yX25hbWUsIHBhcmFtZXRlciwgIiIsIHByb3RvX25hbWUsIG1lc3NhZ2VfbmFtZSwgcHJvdG9fbmFtZSwKKyAgICAgIHRlbXBfZGlyZWN0b3J5XyArICIvIiArIG91dHB1dF9kaXJlY3RvcnkpOworfQorCit2b2lkIENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdDo6RXhwZWN0R2VuZXJhdGVkV2l0aE11bHRpcGxlSW5wdXRzKAorICAgIGNvbnN0IHN0cmluZyYgZ2VuZXJhdG9yX25hbWUsCisgICAgY29uc3Qgc3RyaW5nJiBhbGxfcHJvdG9fbmFtZXMsCisgICAgY29uc3Qgc3RyaW5nJiBwcm90b19uYW1lLAorICAgIGNvbnN0IHN0cmluZyYgbWVzc2FnZV9uYW1lKSB7CisgIE1vY2tDb2RlR2VuZXJhdG9yOjpFeHBlY3RHZW5lcmF0ZWQoCisgICAgICBnZW5lcmF0b3JfbmFtZSwgIiIsICIiLCBwcm90b19uYW1lLCBtZXNzYWdlX25hbWUsCisgICAgICBhbGxfcHJvdG9fbmFtZXMsCisgICAgICB0ZW1wX2RpcmVjdG9yeV8pOworfQorCit2b2lkIENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdDo6RXhwZWN0R2VuZXJhdGVkV2l0aEluc2VydGlvbnMoCisgICAgY29uc3Qgc3RyaW5nJiBnZW5lcmF0b3JfbmFtZSwKKyAgICBjb25zdCBzdHJpbmcmIHBhcmFtZXRlciwKKyAgICBjb25zdCBzdHJpbmcmIGluc2VydGlvbnMsCisgICAgY29uc3Qgc3RyaW5nJiBwcm90b19uYW1lLAorICAgIGNvbnN0IHN0cmluZyYgbWVzc2FnZV9uYW1lKSB7CisgIE1vY2tDb2RlR2VuZXJhdG9yOjpFeHBlY3RHZW5lcmF0ZWQoCisgICAgICBnZW5lcmF0b3JfbmFtZSwgcGFyYW1ldGVyLCBpbnNlcnRpb25zLCBwcm90b19uYW1lLCBtZXNzYWdlX25hbWUsCisgICAgICBwcm90b19uYW1lLCB0ZW1wX2RpcmVjdG9yeV8pOworfQorCit2b2lkIENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdDo6RXhwZWN0TnVsbENvZGVHZW5lcmF0b3JDYWxsZWQoCisgICAgY29uc3Qgc3RyaW5nJiBwYXJhbWV0ZXIpIHsKKyAgRVhQRUNUX1RSVUUobnVsbF9nZW5lcmF0b3JfLT5jYWxsZWRfKTsKKyAgRVhQRUNUX0VRKHBhcmFtZXRlciwgbnVsbF9nZW5lcmF0b3JfLT5wYXJhbWV0ZXJfKTsKK30KKwordm9pZCBDb21tYW5kTGluZUludGVyZmFjZVRlc3Q6OlJlYWREZXNjcmlwdG9yU2V0KAorICAgIGNvbnN0IHN0cmluZyYgZmlsZW5hbWUsIEZpbGVEZXNjcmlwdG9yU2V0KiBkZXNjcmlwdG9yX3NldCkgeworICBzdHJpbmcgcGF0aCA9IHRlbXBfZGlyZWN0b3J5XyArICIvIiArIGZpbGVuYW1lOworICBzdHJpbmcgZmlsZV9jb250ZW50czsKKyAgR09PR0xFX0NIRUNLX09LKEZpbGU6OkdldENvbnRlbnRzKHBhdGgsICZmaWxlX2NvbnRlbnRzLCB0cnVlKSk7CisKKyAgaWYgKCFkZXNjcmlwdG9yX3NldC0+UGFyc2VGcm9tU3RyaW5nKGZpbGVfY29udGVudHMpKSB7CisgICAgRkFJTCgpIDw8ICJDb3VsZCBub3QgcGFyc2UgZmlsZSBjb250ZW50czogIiA8PCBwYXRoOworICB9Cit9CisKK3ZvaWQgQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0OjpFeHBlY3RDYXB0dXJlZFN0ZG91dCgKKyAgICBjb25zdCBzdHJpbmcmIGV4cGVjdGVkX3RleHQpIHsKKyAgRVhQRUNUX0VRKGV4cGVjdGVkX3RleHQsIGNhcHR1cmVkX3N0ZG91dF8pOworfQorCisKK3ZvaWQgQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0OjpFeHBlY3RGaWxlQ29udGVudCgKKyAgICBjb25zdCBzdHJpbmcmIGZpbGVuYW1lLCBjb25zdCBzdHJpbmcmIGNvbnRlbnQpIHsKKyAgc3RyaW5nIHBhdGggPSB0ZW1wX2RpcmVjdG9yeV8gKyAiLyIgKyBmaWxlbmFtZTsKKyAgc3RyaW5nIGZpbGVfY29udGVudHM7CisgIEdPT0dMRV9DSEVDS19PSyhGaWxlOjpHZXRDb250ZW50cyhwYXRoLCAmZmlsZV9jb250ZW50cywgdHJ1ZSkpOworCisgIEVYUEVDVF9FUShTdHJpbmdSZXBsYWNlKGNvbnRlbnQsICIkdG1wZGlyIiwgdGVtcF9kaXJlY3RvcnlfLCB0cnVlKSwKKyAgICAgICAgICAgIGZpbGVfY29udGVudHMpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK1RFU1RfRihDb21tYW5kTGluZUludGVyZmFjZVRlc3QsIEJhc2ljT3V0cHV0KSB7CisgIC8vIFRlc3QgdGhhdCB0aGUgY29tbW9uIGNhc2Ugd29ya3MuCisKKyAgQ3JlYXRlVGVtcEZpbGUoImZvby5wcm90byIsCisgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgIm1lc3NhZ2UgRm9vIHt9XG4iKTsKKworICBSdW4oInByb3RvY29sX2NvbXBpbGVyIC0tdGVzdF9vdXQ9JHRtcGRpciAiCisgICAgICAiLS1wcm90b19wYXRoPSR0bXBkaXIgZm9vLnByb3RvIik7CisKKyAgRXhwZWN0Tm9FcnJvcnMoKTsKKyAgRXhwZWN0R2VuZXJhdGVkKCJ0ZXN0X2dlbmVyYXRvciIsICIiLCAiZm9vLnByb3RvIiwgIkZvbyIpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBCYXNpY1BsdWdpbikgeworICAvLyBUZXN0IHRoYXQgYmFzaWMgcGx1Z2lucyB3b3JrLgorCisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIEZvbyB7fVxuIik7CisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAtLXBsdWdfb3V0PSR0bXBkaXIgIgorICAgICAgIi0tcHJvdG9fcGF0aD0kdG1wZGlyIGZvby5wcm90byIpOworCisgIEV4cGVjdE5vRXJyb3JzKCk7CisgIEV4cGVjdEdlbmVyYXRlZCgidGVzdF9wbHVnaW4iLCAiIiwgImZvby5wcm90byIsICJGb28iKTsKK30KKworVEVTVF9GKENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdCwgR2VuZXJhdG9yQW5kUGx1Z2luKSB7CisgIC8vIEludm9rZSBhIGdlbmVyYXRvciBhbmQgYSBwbHVnaW4gYXQgdGhlIHNhbWUgdGltZS4KKworICBDcmVhdGVUZW1wRmlsZSgiZm9vLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAibWVzc2FnZSBGb28ge31cbiIpOworCisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgLS10ZXN0X291dD0kdG1wZGlyIC0tcGx1Z19vdXQ9JHRtcGRpciAiCisgICAgICAiLS1wcm90b19wYXRoPSR0bXBkaXIgZm9vLnByb3RvIik7CisKKyAgRXhwZWN0Tm9FcnJvcnMoKTsKKyAgRXhwZWN0R2VuZXJhdGVkKCJ0ZXN0X2dlbmVyYXRvciIsICIiLCAiZm9vLnByb3RvIiwgIkZvbyIpOworICBFeHBlY3RHZW5lcmF0ZWQoInRlc3RfcGx1Z2luIiwgIiIsICJmb28ucHJvdG8iLCAiRm9vIik7Cit9CisKK1RFU1RfRihDb21tYW5kTGluZUludGVyZmFjZVRlc3QsIE11bHRpcGxlSW5wdXRzKSB7CisgIC8vIFRlc3QgcGFyc2luZyBtdWx0aXBsZSBpbnB1dCBmaWxlcy4KKworICBDcmVhdGVUZW1wRmlsZSgiZm9vLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAibWVzc2FnZSBGb28ge31cbiIpOworICBDcmVhdGVUZW1wRmlsZSgiYmFyLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAibWVzc2FnZSBCYXIge31cbiIpOworCisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgLS10ZXN0X291dD0kdG1wZGlyIC0tcGx1Z19vdXQ9JHRtcGRpciAiCisgICAgICAiLS1wcm90b19wYXRoPSR0bXBkaXIgZm9vLnByb3RvIGJhci5wcm90byIpOworCisgIEV4cGVjdE5vRXJyb3JzKCk7CisgIEV4cGVjdEdlbmVyYXRlZFdpdGhNdWx0aXBsZUlucHV0cygidGVzdF9nZW5lcmF0b3IiLCAiZm9vLnByb3RvLGJhci5wcm90byIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZm9vLnByb3RvIiwgIkZvbyIpOworICBFeHBlY3RHZW5lcmF0ZWRXaXRoTXVsdGlwbGVJbnB1dHMoInRlc3RfZ2VuZXJhdG9yIiwgImZvby5wcm90byxiYXIucHJvdG8iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImJhci5wcm90byIsICJCYXIiKTsKKyAgRXhwZWN0R2VuZXJhdGVkV2l0aE11bHRpcGxlSW5wdXRzKCJ0ZXN0X3BsdWdpbiIsICJmb28ucHJvdG8sYmFyLnByb3RvIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJmb28ucHJvdG8iLCAiRm9vIik7CisgIEV4cGVjdEdlbmVyYXRlZFdpdGhNdWx0aXBsZUlucHV0cygidGVzdF9wbHVnaW4iLCAiZm9vLnByb3RvLGJhci5wcm90byIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYmFyLnByb3RvIiwgIkJhciIpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBNdWx0aXBsZUlucHV0c1dpdGhJbXBvcnQpIHsKKyAgLy8gVGVzdCBwYXJzaW5nIG11bHRpcGxlIGlucHV0IGZpbGVzIHdpdGggYW4gaW1wb3J0IG9mIGEgc2VwYXJhdGUgZmlsZS4KKworICBDcmVhdGVUZW1wRmlsZSgiZm9vLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAibWVzc2FnZSBGb28ge31cbiIpOworICBDcmVhdGVUZW1wRmlsZSgiYmFyLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAiaW1wb3J0IFwiYmF6LnByb3RvXCI7XG4iCisgICAgIm1lc3NhZ2UgQmFyIHtcbiIKKyAgICAiICBvcHRpb25hbCBCYXogYSA9IDE7XG4iCisgICAgIn1cbiIpOworICBDcmVhdGVUZW1wRmlsZSgiYmF6LnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAibWVzc2FnZSBCYXoge31cbiIpOworCisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgLS10ZXN0X291dD0kdG1wZGlyIC0tcGx1Z19vdXQ9JHRtcGRpciAiCisgICAgICAiLS1wcm90b19wYXRoPSR0bXBkaXIgZm9vLnByb3RvIGJhci5wcm90byIpOworCisgIEV4cGVjdE5vRXJyb3JzKCk7CisgIEV4cGVjdEdlbmVyYXRlZFdpdGhNdWx0aXBsZUlucHV0cygidGVzdF9nZW5lcmF0b3IiLCAiZm9vLnByb3RvLGJhci5wcm90byIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZm9vLnByb3RvIiwgIkZvbyIpOworICBFeHBlY3RHZW5lcmF0ZWRXaXRoTXVsdGlwbGVJbnB1dHMoInRlc3RfZ2VuZXJhdG9yIiwgImZvby5wcm90byxiYXIucHJvdG8iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImJhci5wcm90byIsICJCYXIiKTsKKyAgRXhwZWN0R2VuZXJhdGVkV2l0aE11bHRpcGxlSW5wdXRzKCJ0ZXN0X3BsdWdpbiIsICJmb28ucHJvdG8sYmFyLnByb3RvIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJmb28ucHJvdG8iLCAiRm9vIik7CisgIEV4cGVjdEdlbmVyYXRlZFdpdGhNdWx0aXBsZUlucHV0cygidGVzdF9wbHVnaW4iLCAiZm9vLnByb3RvLGJhci5wcm90byIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYmFyLnByb3RvIiwgIkJhciIpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBDcmVhdGVEaXJlY3RvcnkpIHsKKyAgLy8gVGVzdCB0aGF0IHdoZW4gd2Ugb3V0cHV0IHRvIGEgc3ViLWRpcmVjdG9yeSwgaXQgaXMgY3JlYXRlZC4KKworICBDcmVhdGVUZW1wRmlsZSgiYmFyL2Jhei9mb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIEZvbyB7fVxuIik7CisgIENyZWF0ZVRlbXBEaXIoIm91dCIpOworICBDcmVhdGVUZW1wRGlyKCJwbHVnb3V0Iik7CisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAtLXRlc3Rfb3V0PSR0bXBkaXIvb3V0IC0tcGx1Z19vdXQ9JHRtcGRpci9wbHVnb3V0ICIKKyAgICAgICItLXByb3RvX3BhdGg9JHRtcGRpciBiYXIvYmF6L2Zvby5wcm90byIpOworCisgIEV4cGVjdE5vRXJyb3JzKCk7CisgIEV4cGVjdEdlbmVyYXRlZCgidGVzdF9nZW5lcmF0b3IiLCAiIiwgImJhci9iYXovZm9vLnByb3RvIiwgIkZvbyIsICJvdXQiKTsKKyAgRXhwZWN0R2VuZXJhdGVkKCJ0ZXN0X3BsdWdpbiIsICIiLCAiYmFyL2Jhei9mb28ucHJvdG8iLCAiRm9vIiwgInBsdWdvdXQiKTsKK30KKworVEVTVF9GKENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdCwgR2VuZXJhdG9yUGFyYW1ldGVycykgeworICAvLyBUZXN0IHRoYXQgZ2VuZXJhdG9yIHBhcmFtZXRlcnMgYXJlIGNvcnJlY3RseSBwYXJzZWQgZnJvbSB0aGUgY29tbWFuZCBsaW5lLgorCisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIEZvbyB7fVxuIik7CisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAtLXRlc3Rfb3V0PVRlc3RQYXJhbWV0ZXI6JHRtcGRpciAiCisgICAgICAiLS1wbHVnX291dD1UZXN0UGx1Z2luUGFyYW1ldGVyOiR0bXBkaXIgIgorICAgICAgIi0tcHJvdG9fcGF0aD0kdG1wZGlyIGZvby5wcm90byIpOworCisgIEV4cGVjdE5vRXJyb3JzKCk7CisgIEV4cGVjdEdlbmVyYXRlZCgidGVzdF9nZW5lcmF0b3IiLCAiVGVzdFBhcmFtZXRlciIsICJmb28ucHJvdG8iLCAiRm9vIik7CisgIEV4cGVjdEdlbmVyYXRlZCgidGVzdF9wbHVnaW4iLCAiVGVzdFBsdWdpblBhcmFtZXRlciIsICJmb28ucHJvdG8iLCAiRm9vIik7Cit9CisKK1RFU1RfRihDb21tYW5kTGluZUludGVyZmFjZVRlc3QsIEV4dHJhR2VuZXJhdG9yUGFyYW1ldGVycykgeworICAvLyBUZXN0IHRoYXQgZ2VuZXJhdG9yIHBhcmFtZXRlcnMgc3BlY2lmaWVkIHdpdGggdGhlIG9wdGlvbiBmbGFnIGFyZQorICAvLyBjb3JyZWN0bHkgcGFzc2VkIHRvIHRoZSBjb2RlIGdlbmVyYXRvci4KKworICBDcmVhdGVUZW1wRmlsZSgiZm9vLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAibWVzc2FnZSBGb28ge31cbiIpOworICAvLyBDcmVhdGUgdGhlICJhIiBhbmQgImIiIHN1Yi1kaXJlY3Rvcmllcy4KKyAgQ3JlYXRlVGVtcERpcigiYSIpOworICBDcmVhdGVUZW1wRGlyKCJiIik7CisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAiCisgICAgICAiLS10ZXN0X29wdD1mb28xICIKKyAgICAgICItLXRlc3Rfb3V0PWJhcjokdG1wZGlyL2EgIgorICAgICAgIi0tdGVzdF9vcHQ9Zm9vMiAiCisgICAgICAiLS10ZXN0X291dD1iYXo6JHRtcGRpci9iICIKKyAgICAgICItLXRlc3Rfb3B0PWZvbzMgIgorICAgICAgIi0tcHJvdG9fcGF0aD0kdG1wZGlyIGZvby5wcm90byIpOworCisgIEV4cGVjdE5vRXJyb3JzKCk7CisgIEV4cGVjdEdlbmVyYXRlZCgKKyAgICAgICJ0ZXN0X2dlbmVyYXRvciIsICJiYXIsZm9vMSxmb28yLGZvbzMiLCAiZm9vLnByb3RvIiwgIkZvbyIsICJhIik7CisgIEV4cGVjdEdlbmVyYXRlZCgKKyAgICAgICJ0ZXN0X2dlbmVyYXRvciIsICJiYXosZm9vMSxmb28yLGZvbzMiLCAiZm9vLnByb3RvIiwgIkZvbyIsICJiIik7Cit9CisKK1RFU1RfRihDb21tYW5kTGluZUludGVyZmFjZVRlc3QsIEluc2VydCkgeworICAvLyBUZXN0IHJ1bm5pbmcgYSBnZW5lcmF0b3IgdGhhdCBpbnNlcnRzIGNvZGUgaW50byBhbm90aGVyJ3Mgb3V0cHV0LgorCisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIEZvbyB7fVxuIik7CisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAiCisgICAgICAiLS10ZXN0X291dD1UZXN0UGFyYW1ldGVyOiR0bXBkaXIgIgorICAgICAgIi0tcGx1Z19vdXQ9VGVzdFBsdWdpblBhcmFtZXRlcjokdG1wZGlyICIKKyAgICAgICItLXRlc3Rfb3V0PWluc2VydD10ZXN0X2dlbmVyYXRvcix0ZXN0X3BsdWdpbjokdG1wZGlyICIKKyAgICAgICItLXBsdWdfb3V0PWluc2VydD10ZXN0X2dlbmVyYXRvcix0ZXN0X3BsdWdpbjokdG1wZGlyICIKKyAgICAgICItLXByb3RvX3BhdGg9JHRtcGRpciBmb28ucHJvdG8iKTsKKworICBFeHBlY3ROb0Vycm9ycygpOworICBFeHBlY3RHZW5lcmF0ZWRXaXRoSW5zZXJ0aW9ucygKKyAgICAgICJ0ZXN0X2dlbmVyYXRvciIsICJUZXN0UGFyYW1ldGVyIiwgInRlc3RfZ2VuZXJhdG9yLHRlc3RfcGx1Z2luIiwKKyAgICAgICJmb28ucHJvdG8iLCAiRm9vIik7CisgIEV4cGVjdEdlbmVyYXRlZFdpdGhJbnNlcnRpb25zKAorICAgICAgInRlc3RfcGx1Z2luIiwgIlRlc3RQbHVnaW5QYXJhbWV0ZXIiLCAidGVzdF9nZW5lcmF0b3IsdGVzdF9wbHVnaW4iLAorICAgICAgImZvby5wcm90byIsICJGb28iKTsKK30KKworI2lmIGRlZmluZWQoX1dJTjMyKQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBXaW5kb3dzT3V0cHV0UGF0aCkgeworICAvLyBUZXN0IHRoYXQgdGhlIG91dHB1dCBwYXRoIGNhbiBiZSBhIFdpbmRvd3Mtc3R5bGUgcGF0aC4KKworICBDcmVhdGVUZW1wRmlsZSgiZm9vLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIpOworCisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgLS1udWxsX291dD1DOlxcICIKKyAgICAgICItLXByb3RvX3BhdGg9JHRtcGRpciBmb28ucHJvdG8iKTsKKworICBFeHBlY3ROb0Vycm9ycygpOworICBFeHBlY3ROdWxsQ29kZUdlbmVyYXRvckNhbGxlZCgiIik7Cit9CisKK1RFU1RfRihDb21tYW5kTGluZUludGVyZmFjZVRlc3QsIFdpbmRvd3NPdXRwdXRQYXRoQW5kUGFyYW1ldGVyKSB7CisgIC8vIFRlc3QgdGhhdCB3ZSBjYW4gaGF2ZSBhIHdpbmRvd3Mtc3R5bGUgb3V0cHV0IHBhdGggYW5kIGEgcGFyYW1ldGVyLgorCisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIik7CisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAtLW51bGxfb3V0PWJhcjpDOlxcICIKKyAgICAgICItLXByb3RvX3BhdGg9JHRtcGRpciBmb28ucHJvdG8iKTsKKworICBFeHBlY3ROb0Vycm9ycygpOworICBFeHBlY3ROdWxsQ29kZUdlbmVyYXRvckNhbGxlZCgiYmFyIik7Cit9CisKK1RFU1RfRihDb21tYW5kTGluZUludGVyZmFjZVRlc3QsIFRyYWlsaW5nQmFja3NsYXNoKSB7CisgIC8vIFRlc3QgdGhhdCB0aGUgZGlyZWN0b3JpZXMgY2FuIGVuZCBpbiBiYWNrc2xhc2hlcy4gIFNvbWUgdXNlcnMgY2xhaW0gdGhpcworICAvLyBkb2Vzbid0IHdvcmsgb24gdGhlaXIgc3lzdGVtLgorCisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIEZvbyB7fVxuIik7CisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAtLXRlc3Rfb3V0PSR0bXBkaXJcXCAiCisgICAgICAiLS1wcm90b19wYXRoPSR0bXBkaXJcXCBmb28ucHJvdG8iKTsKKworICBFeHBlY3ROb0Vycm9ycygpOworICBFeHBlY3RHZW5lcmF0ZWQoInRlc3RfZ2VuZXJhdG9yIiwgIiIsICJmb28ucHJvdG8iLCAiRm9vIik7Cit9CisKKyNlbmRpZiAgLy8gZGVmaW5lZChfV0lOMzIpIHx8IGRlZmluZWQoX19DWUdXSU5fXykKKworVEVTVF9GKENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdCwgUGF0aExvb2t1cCkgeworICAvLyBUZXN0IHRoYXQgc3BlY2lmeWluZyBtdWx0aXBsZSBkaXJlY3RvcmllcyBpbiB0aGUgcHJvdG8gc2VhcmNoIHBhdGggd29ya3MuCisKKyAgQ3JlYXRlVGVtcEZpbGUoImIvYmFyLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAibWVzc2FnZSBCYXIge31cbiIpOworICBDcmVhdGVUZW1wRmlsZSgiYS9mb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJpbXBvcnQgXCJiYXIucHJvdG9cIjtcbiIKKyAgICAibWVzc2FnZSBGb28ge1xuIgorICAgICIgIG9wdGlvbmFsIEJhciBhID0gMTtcbiIKKyAgICAifVxuIik7CisgIENyZWF0ZVRlbXBGaWxlKCJiL2Zvby5wcm90byIsICJ0aGlzIHNob3VsZCBub3QgYmUgcGFyc2VkXG4iKTsKKworICBSdW4oInByb3RvY29sX2NvbXBpbGVyIC0tdGVzdF9vdXQ9JHRtcGRpciAiCisgICAgICAiLS1wcm90b19wYXRoPSR0bXBkaXIvYSAtLXByb3RvX3BhdGg9JHRtcGRpci9iIGZvby5wcm90byIpOworCisgIEV4cGVjdE5vRXJyb3JzKCk7CisgIEV4cGVjdEdlbmVyYXRlZCgidGVzdF9nZW5lcmF0b3IiLCAiIiwgImZvby5wcm90byIsICJGb28iKTsKK30KKworVEVTVF9GKENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdCwgQ29sb25EZWxpbWl0ZWRQYXRoKSB7CisgIC8vIFNhbWUgYXMgUGF0aExvb2t1cCwgYnV0IHdlIHByb3ZpZGUgdGhlIHByb3RvX3BhdGggaW4gYSBzaW5nbGUgZmxhZy4KKworICBDcmVhdGVUZW1wRmlsZSgiYi9iYXIucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIEJhciB7fVxuIik7CisgIENyZWF0ZVRlbXBGaWxlKCJhL2Zvby5wcm90byIsCisgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgImltcG9ydCBcImJhci5wcm90b1wiO1xuIgorICAgICJtZXNzYWdlIEZvbyB7XG4iCisgICAgIiAgb3B0aW9uYWwgQmFyIGEgPSAxO1xuIgorICAgICJ9XG4iKTsKKyAgQ3JlYXRlVGVtcEZpbGUoImIvZm9vLnByb3RvIiwgInRoaXMgc2hvdWxkIG5vdCBiZSBwYXJzZWRcbiIpOworCisjdW5kZWYgUEFUSF9TRVBBUkFUT1IKKyNpZiBkZWZpbmVkKF9XSU4zMikKKyNkZWZpbmUgUEFUSF9TRVBBUkFUT1IgIjsiCisjZWxzZQorI2RlZmluZSBQQVRIX1NFUEFSQVRPUiAiOiIKKyNlbmRpZgorCisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgLS10ZXN0X291dD0kdG1wZGlyICIKKyAgICAgICItLXByb3RvX3BhdGg9JHRtcGRpci9hIiBQQVRIX1NFUEFSQVRPUiAiJHRtcGRpci9iIGZvby5wcm90byIpOworCisjdW5kZWYgUEFUSF9TRVBBUkFUT1IKKworICBFeHBlY3ROb0Vycm9ycygpOworICBFeHBlY3RHZW5lcmF0ZWQoInRlc3RfZ2VuZXJhdG9yIiwgIiIsICJmb28ucHJvdG8iLCAiRm9vIik7Cit9CisKK1RFU1RfRihDb21tYW5kTGluZUludGVyZmFjZVRlc3QsIE5vblJvb3RNYXBwaW5nKSB7CisgIC8vIFRlc3Qgc2V0dGluZyB1cCBhIHNlYXJjaCBwYXRoIG1hcHBpbmcgYSBkaXJlY3RvcnkgdG8gYSBub24tcm9vdCBsb2NhdGlvbi4KKworICBDcmVhdGVUZW1wRmlsZSgiZm9vLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAibWVzc2FnZSBGb28ge31cbiIpOworCisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgLS10ZXN0X291dD0kdG1wZGlyICIKKyAgICAgICItLXByb3RvX3BhdGg9YmFyPSR0bXBkaXIgYmFyL2Zvby5wcm90byIpOworCisgIEV4cGVjdE5vRXJyb3JzKCk7CisgIEV4cGVjdEdlbmVyYXRlZCgidGVzdF9nZW5lcmF0b3IiLCAiIiwgImJhci9mb28ucHJvdG8iLCAiRm9vIik7Cit9CisKK1RFU1RfRihDb21tYW5kTGluZUludGVyZmFjZVRlc3QsIE11bHRpcGxlR2VuZXJhdG9ycykgeworICAvLyBUZXN0IHRoYXQgd2UgY2FuIGhhdmUgbXVsdGlwbGUgZ2VuZXJhdG9ycyBhbmQgdXNlIGJvdGggaW4gb25lIGludm9jYXRpb24sCisgIC8vIGVhY2ggd2l0aCBhIGRpZmZlcmVudCBvdXRwdXQgZGlyZWN0b3J5LgorCisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIEZvbyB7fVxuIik7CisgIC8vIENyZWF0ZSB0aGUgImEiIGFuZCAiYiIgc3ViLWRpcmVjdG9yaWVzLgorICBDcmVhdGVUZW1wRGlyKCJhIik7CisgIENyZWF0ZVRlbXBEaXIoImIiKTsKKworICBSdW4oInByb3RvY29sX2NvbXBpbGVyICIKKyAgICAgICItLXRlc3Rfb3V0PSR0bXBkaXIvYSAiCisgICAgICAiLS1hbHRfb3V0PSR0bXBkaXIvYiAiCisgICAgICAiLS1wcm90b19wYXRoPSR0bXBkaXIgZm9vLnByb3RvIik7CisKKyAgRXhwZWN0Tm9FcnJvcnMoKTsKKyAgRXhwZWN0R2VuZXJhdGVkKCJ0ZXN0X2dlbmVyYXRvciIsICIiLCAiZm9vLnByb3RvIiwgIkZvbyIsICJhIik7CisgIEV4cGVjdEdlbmVyYXRlZCgiYWx0X2dlbmVyYXRvciIsICIiLCAiZm9vLnByb3RvIiwgIkZvbyIsICJiIik7Cit9CisKK1RFU1RfRihDb21tYW5kTGluZUludGVyZmFjZVRlc3QsIERpc2FsbG93U2VydmljZXNOb1NlcnZpY2VzKSB7CisgIC8vIFRlc3QgdGhhdCAtLWRpc2FsbG93X3NlcnZpY2VzIGRvZXNuJ3QgY2F1c2UgYSBwcm9ibGVtIHdoZW4gdGhlcmUgYXJlIG5vCisgIC8vIHNlcnZpY2VzLgorCisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIEZvbyB7fVxuIik7CisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAtLWRpc2FsbG93X3NlcnZpY2VzIC0tdGVzdF9vdXQ9JHRtcGRpciAiCisgICAgICAiLS1wcm90b19wYXRoPSR0bXBkaXIgZm9vLnByb3RvIik7CisKKyAgRXhwZWN0Tm9FcnJvcnMoKTsKKyAgRXhwZWN0R2VuZXJhdGVkKCJ0ZXN0X2dlbmVyYXRvciIsICIiLCAiZm9vLnByb3RvIiwgIkZvbyIpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBEaXNhbGxvd1NlcnZpY2VzSGFzU2VydmljZSkgeworICAvLyBUZXN0IHRoYXQgLS1kaXNhbGxvd19zZXJ2aWNlcyBwcm9kdWNlcyBhbiBlcnJvciB3aGVuIHRoZXJlIGFyZSBzZXJ2aWNlcy4KKworICBDcmVhdGVUZW1wRmlsZSgiZm9vLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAibWVzc2FnZSBGb28ge31cbiIKKyAgICAic2VydmljZSBCYXIge31cbiIpOworCisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgLS1kaXNhbGxvd19zZXJ2aWNlcyAtLXRlc3Rfb3V0PSR0bXBkaXIgIgorICAgICAgIi0tcHJvdG9fcGF0aD0kdG1wZGlyIGZvby5wcm90byIpOworCisgIEV4cGVjdEVycm9yU3Vic3RyaW5nKCJmb28ucHJvdG86IFRoaXMgZmlsZSBjb250YWlucyBzZXJ2aWNlcyIpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBBbGxvd1NlcnZpY2VzSGFzU2VydmljZSkgeworICAvLyBUZXN0IHRoYXQgc2VydmljZXMgd29yayBmaW5lIGFzIGxvbmcgYXMgLS1kaXNhbGxvd19zZXJ2aWNlcyBpcyBub3QgdXNlZC4KKworICBDcmVhdGVUZW1wRmlsZSgiZm9vLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAibWVzc2FnZSBGb28ge31cbiIKKyAgICAic2VydmljZSBCYXIge31cbiIpOworCisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgLS10ZXN0X291dD0kdG1wZGlyICIKKyAgICAgICItLXByb3RvX3BhdGg9JHRtcGRpciBmb28ucHJvdG8iKTsKKworICBFeHBlY3ROb0Vycm9ycygpOworICBFeHBlY3RHZW5lcmF0ZWQoInRlc3RfZ2VuZXJhdG9yIiwgIiIsICJmb28ucHJvdG8iLCAiRm9vIik7Cit9CisKK1RFU1RfRihDb21tYW5kTGluZUludGVyZmFjZVRlc3QsIEN3ZFJlbGF0aXZlSW5wdXRzKSB7CisgIC8vIFRlc3QgdGhhdCB3ZSBjYW4gYWNjZXB0IHdvcmtpbmctZGlyZWN0b3J5LXJlbGF0aXZlIGlucHV0IGZpbGVzLgorCisgIFNldElucHV0c0FyZVByb3RvUGF0aFJlbGF0aXZlKGZhbHNlKTsKKworICBDcmVhdGVUZW1wRmlsZSgiZm9vLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAibWVzc2FnZSBGb28ge31cbiIpOworCisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgLS10ZXN0X291dD0kdG1wZGlyICIKKyAgICAgICItLXByb3RvX3BhdGg9JHRtcGRpciAkdG1wZGlyL2Zvby5wcm90byIpOworCisgIEV4cGVjdE5vRXJyb3JzKCk7CisgIEV4cGVjdEdlbmVyYXRlZCgidGVzdF9nZW5lcmF0b3IiLCAiIiwgImZvby5wcm90byIsICJGb28iKTsKK30KKworVEVTVF9GKENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdCwgV3JpdGVEZXNjcmlwdG9yU2V0KSB7CisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIEZvbyB7fVxuIik7CisgIENyZWF0ZVRlbXBGaWxlKCJiYXIucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJpbXBvcnQgXCJmb28ucHJvdG9cIjtcbiIKKyAgICAibWVzc2FnZSBCYXIge1xuIgorICAgICIgIG9wdGlvbmFsIEZvbyBmb28gPSAxO1xuIgorICAgICJ9XG4iKTsKKworICBSdW4oInByb3RvY29sX2NvbXBpbGVyIC0tZGVzY3JpcHRvcl9zZXRfb3V0PSR0bXBkaXIvZGVzY3JpcHRvcl9zZXQgIgorICAgICAgIi0tcHJvdG9fcGF0aD0kdG1wZGlyIGJhci5wcm90byIpOworCisgIEV4cGVjdE5vRXJyb3JzKCk7CisKKyAgRmlsZURlc2NyaXB0b3JTZXQgZGVzY3JpcHRvcl9zZXQ7CisgIFJlYWREZXNjcmlwdG9yU2V0KCJkZXNjcmlwdG9yX3NldCIsICZkZXNjcmlwdG9yX3NldCk7CisgIGlmIChIYXNGYXRhbEZhaWx1cmUoKSkgcmV0dXJuOworICBFWFBFQ1RfRVEoMSwgZGVzY3JpcHRvcl9zZXQuZmlsZV9zaXplKCkpOworICBFWFBFQ1RfRVEoImJhci5wcm90byIsIGRlc2NyaXB0b3Jfc2V0LmZpbGUoMCkubmFtZSgpKTsKKyAgLy8gRGVzY3JpcHRvciBzZXQgc2hvdWxkIG5vdCBoYXZlIHNvdXJjZSBjb2RlIGluZm8uCisgIEVYUEVDVF9GQUxTRShkZXNjcmlwdG9yX3NldC5maWxlKDApLmhhc19zb3VyY2VfY29kZV9pbmZvKCkpOworICAvLyBEZXNjcmlwdG9yIHNldCBzaG91bGQgaGF2ZSBqc29uX25hbWUuCisgIEVYUEVDVF9FUSgiQmFyIiwgZGVzY3JpcHRvcl9zZXQuZmlsZSgwKS5tZXNzYWdlX3R5cGUoMCkubmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJmb28iLCBkZXNjcmlwdG9yX3NldC5maWxlKDApLm1lc3NhZ2VfdHlwZSgwKS5maWVsZCgwKS5uYW1lKCkpOworICBFWFBFQ1RfVFJVRShkZXNjcmlwdG9yX3NldC5maWxlKDApLm1lc3NhZ2VfdHlwZSgwKS5maWVsZCgwKS5oYXNfanNvbl9uYW1lKCkpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBXcml0ZURlc2NyaXB0b3JTZXRXaXRoRHVwbGljYXRlcykgeworICBDcmVhdGVUZW1wRmlsZSgiZm9vLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAibWVzc2FnZSBGb28ge31cbiIpOworICBDcmVhdGVUZW1wRmlsZSgiYmFyLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAiaW1wb3J0IFwiZm9vLnByb3RvXCI7XG4iCisgICAgIm1lc3NhZ2UgQmFyIHtcbiIKKyAgICAiICBvcHRpb25hbCBGb28gZm9vID0gMTtcbiIKKyAgICAifVxuIik7CisgIENyZWF0ZVRlbXBGaWxlKCJiYXoucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJpbXBvcnQgXCJmb28ucHJvdG9cIjtcbiIKKyAgICAibWVzc2FnZSBCYXoge1xuIgorICAgICIgIG9wdGlvbmFsIEZvbyBmb28gPSAxO1xuIgorICAgICJ9XG4iKTsKKworICBSdW4oInByb3RvY29sX2NvbXBpbGVyIC0tZGVzY3JpcHRvcl9zZXRfb3V0PSR0bXBkaXIvZGVzY3JpcHRvcl9zZXQgIgorICAgICAgIi0tcHJvdG9fcGF0aD0kdG1wZGlyIGJhci5wcm90byBmb28ucHJvdG8gYmFyLnByb3RvIGJhei5wcm90byIpOworCisgIEV4cGVjdE5vRXJyb3JzKCk7CisKKyAgRmlsZURlc2NyaXB0b3JTZXQgZGVzY3JpcHRvcl9zZXQ7CisgIFJlYWREZXNjcmlwdG9yU2V0KCJkZXNjcmlwdG9yX3NldCIsICZkZXNjcmlwdG9yX3NldCk7CisgIGlmIChIYXNGYXRhbEZhaWx1cmUoKSkgcmV0dXJuOworICBFWFBFQ1RfRVEoMywgZGVzY3JpcHRvcl9zZXQuZmlsZV9zaXplKCkpOworICBFWFBFQ1RfRVEoImJhci5wcm90byIsIGRlc2NyaXB0b3Jfc2V0LmZpbGUoMCkubmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJmb28ucHJvdG8iLCBkZXNjcmlwdG9yX3NldC5maWxlKDEpLm5hbWUoKSk7CisgIEVYUEVDVF9FUSgiYmF6LnByb3RvIiwgZGVzY3JpcHRvcl9zZXQuZmlsZSgyKS5uYW1lKCkpOworICAvLyBEZXNjcmlwdG9yIHNldCBzaG91bGQgbm90IGhhdmUgc291cmNlIGNvZGUgaW5mby4KKyAgRVhQRUNUX0ZBTFNFKGRlc2NyaXB0b3Jfc2V0LmZpbGUoMCkuaGFzX3NvdXJjZV9jb2RlX2luZm8oKSk7CisgIC8vIERlc2NyaXB0b3Igc2V0IHNob3VsZCBoYXZlIGpzb25fbmFtZS4KKyAgRVhQRUNUX0VRKCJCYXIiLCBkZXNjcmlwdG9yX3NldC5maWxlKDApLm1lc3NhZ2VfdHlwZSgwKS5uYW1lKCkpOworICBFWFBFQ1RfRVEoImZvbyIsIGRlc2NyaXB0b3Jfc2V0LmZpbGUoMCkubWVzc2FnZV90eXBlKDApLmZpZWxkKDApLm5hbWUoKSk7CisgIEVYUEVDVF9UUlVFKGRlc2NyaXB0b3Jfc2V0LmZpbGUoMCkubWVzc2FnZV90eXBlKDApLmZpZWxkKDApLmhhc19qc29uX25hbWUoKSk7Cit9CisKK1RFU1RfRihDb21tYW5kTGluZUludGVyZmFjZVRlc3QsIFdyaXRlRGVzY3JpcHRvclNldFdpdGhTb3VyY2VJbmZvKSB7CisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIEZvbyB7fVxuIik7CisgIENyZWF0ZVRlbXBGaWxlKCJiYXIucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJpbXBvcnQgXCJmb28ucHJvdG9cIjtcbiIKKyAgICAibWVzc2FnZSBCYXIge1xuIgorICAgICIgIG9wdGlvbmFsIEZvbyBmb28gPSAxO1xuIgorICAgICJ9XG4iKTsKKworICBSdW4oInByb3RvY29sX2NvbXBpbGVyIC0tZGVzY3JpcHRvcl9zZXRfb3V0PSR0bXBkaXIvZGVzY3JpcHRvcl9zZXQgIgorICAgICAgIi0taW5jbHVkZV9zb3VyY2VfaW5mbyAtLXByb3RvX3BhdGg9JHRtcGRpciBiYXIucHJvdG8iKTsKKworICBFeHBlY3ROb0Vycm9ycygpOworCisgIEZpbGVEZXNjcmlwdG9yU2V0IGRlc2NyaXB0b3Jfc2V0OworICBSZWFkRGVzY3JpcHRvclNldCgiZGVzY3JpcHRvcl9zZXQiLCAmZGVzY3JpcHRvcl9zZXQpOworICBpZiAoSGFzRmF0YWxGYWlsdXJlKCkpIHJldHVybjsKKyAgRVhQRUNUX0VRKDEsIGRlc2NyaXB0b3Jfc2V0LmZpbGVfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKCJiYXIucHJvdG8iLCBkZXNjcmlwdG9yX3NldC5maWxlKDApLm5hbWUoKSk7CisgIC8vIFNvdXJjZSBjb2RlIGluZm8gaW5jbHVkZWQuCisgIEVYUEVDVF9UUlVFKGRlc2NyaXB0b3Jfc2V0LmZpbGUoMCkuaGFzX3NvdXJjZV9jb2RlX2luZm8oKSk7Cit9CisKK1RFU1RfRihDb21tYW5kTGluZUludGVyZmFjZVRlc3QsIFdyaXRlVHJhbnNpdGl2ZURlc2NyaXB0b3JTZXQpIHsKKyAgQ3JlYXRlVGVtcEZpbGUoImZvby5wcm90byIsCisgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgIm1lc3NhZ2UgRm9vIHt9XG4iKTsKKyAgQ3JlYXRlVGVtcEZpbGUoImJhci5wcm90byIsCisgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgImltcG9ydCBcImZvby5wcm90b1wiO1xuIgorICAgICJtZXNzYWdlIEJhciB7XG4iCisgICAgIiAgb3B0aW9uYWwgRm9vIGZvbyA9IDE7XG4iCisgICAgIn1cbiIpOworCisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgLS1kZXNjcmlwdG9yX3NldF9vdXQ9JHRtcGRpci9kZXNjcmlwdG9yX3NldCAiCisgICAgICAiLS1pbmNsdWRlX2ltcG9ydHMgLS1wcm90b19wYXRoPSR0bXBkaXIgYmFyLnByb3RvIik7CisKKyAgRXhwZWN0Tm9FcnJvcnMoKTsKKworICBGaWxlRGVzY3JpcHRvclNldCBkZXNjcmlwdG9yX3NldDsKKyAgUmVhZERlc2NyaXB0b3JTZXQoImRlc2NyaXB0b3Jfc2V0IiwgJmRlc2NyaXB0b3Jfc2V0KTsKKyAgaWYgKEhhc0ZhdGFsRmFpbHVyZSgpKSByZXR1cm47CisgIEVYUEVDVF9FUSgyLCBkZXNjcmlwdG9yX3NldC5maWxlX3NpemUoKSk7CisgIGlmIChkZXNjcmlwdG9yX3NldC5maWxlKDApLm5hbWUoKSA9PSAiYmFyLnByb3RvIikgeworICAgIHN0ZDo6c3dhcChkZXNjcmlwdG9yX3NldC5tdXRhYmxlX2ZpbGUoKS0+bXV0YWJsZV9kYXRhKClbMF0sCisgICAgICAgICAgICAgIGRlc2NyaXB0b3Jfc2V0Lm11dGFibGVfZmlsZSgpLT5tdXRhYmxlX2RhdGEoKVsxXSk7CisgIH0KKyAgRVhQRUNUX0VRKCJmb28ucHJvdG8iLCBkZXNjcmlwdG9yX3NldC5maWxlKDApLm5hbWUoKSk7CisgIEVYUEVDVF9FUSgiYmFyLnByb3RvIiwgZGVzY3JpcHRvcl9zZXQuZmlsZSgxKS5uYW1lKCkpOworICAvLyBEZXNjcmlwdG9yIHNldCBzaG91bGQgbm90IGhhdmUgc291cmNlIGNvZGUgaW5mby4KKyAgRVhQRUNUX0ZBTFNFKGRlc2NyaXB0b3Jfc2V0LmZpbGUoMCkuaGFzX3NvdXJjZV9jb2RlX2luZm8oKSk7CisgIEVYUEVDVF9GQUxTRShkZXNjcmlwdG9yX3NldC5maWxlKDEpLmhhc19zb3VyY2VfY29kZV9pbmZvKCkpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBXcml0ZVRyYW5zaXRpdmVEZXNjcmlwdG9yU2V0V2l0aFNvdXJjZUluZm8pIHsKKyAgQ3JlYXRlVGVtcEZpbGUoImZvby5wcm90byIsCisgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgIm1lc3NhZ2UgRm9vIHt9XG4iKTsKKyAgQ3JlYXRlVGVtcEZpbGUoImJhci5wcm90byIsCisgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgImltcG9ydCBcImZvby5wcm90b1wiO1xuIgorICAgICJtZXNzYWdlIEJhciB7XG4iCisgICAgIiAgb3B0aW9uYWwgRm9vIGZvbyA9IDE7XG4iCisgICAgIn1cbiIpOworCisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgLS1kZXNjcmlwdG9yX3NldF9vdXQ9JHRtcGRpci9kZXNjcmlwdG9yX3NldCAiCisgICAgICAiLS1pbmNsdWRlX2ltcG9ydHMgLS1pbmNsdWRlX3NvdXJjZV9pbmZvIC0tcHJvdG9fcGF0aD0kdG1wZGlyIGJhci5wcm90byIpOworCisgIEV4cGVjdE5vRXJyb3JzKCk7CisKKyAgRmlsZURlc2NyaXB0b3JTZXQgZGVzY3JpcHRvcl9zZXQ7CisgIFJlYWREZXNjcmlwdG9yU2V0KCJkZXNjcmlwdG9yX3NldCIsICZkZXNjcmlwdG9yX3NldCk7CisgIGlmIChIYXNGYXRhbEZhaWx1cmUoKSkgcmV0dXJuOworICBFWFBFQ1RfRVEoMiwgZGVzY3JpcHRvcl9zZXQuZmlsZV9zaXplKCkpOworICBpZiAoZGVzY3JpcHRvcl9zZXQuZmlsZSgwKS5uYW1lKCkgPT0gImJhci5wcm90byIpIHsKKyAgICBzdGQ6OnN3YXAoZGVzY3JpcHRvcl9zZXQubXV0YWJsZV9maWxlKCktPm11dGFibGVfZGF0YSgpWzBdLAorICAgICAgICAgICAgICBkZXNjcmlwdG9yX3NldC5tdXRhYmxlX2ZpbGUoKS0+bXV0YWJsZV9kYXRhKClbMV0pOworICB9CisgIEVYUEVDVF9FUSgiZm9vLnByb3RvIiwgZGVzY3JpcHRvcl9zZXQuZmlsZSgwKS5uYW1lKCkpOworICBFWFBFQ1RfRVEoImJhci5wcm90byIsIGRlc2NyaXB0b3Jfc2V0LmZpbGUoMSkubmFtZSgpKTsKKyAgLy8gU291cmNlIGNvZGUgaW5mbyBpbmNsdWRlZC4KKyAgRVhQRUNUX1RSVUUoZGVzY3JpcHRvcl9zZXQuZmlsZSgwKS5oYXNfc291cmNlX2NvZGVfaW5mbygpKTsKKyAgRVhQRUNUX1RSVUUoZGVzY3JpcHRvcl9zZXQuZmlsZSgxKS5oYXNfc291cmNlX2NvZGVfaW5mbygpKTsKK30KKworI2lmZGVmIF9XSU4zMgorLy8gVE9ETyh0ZWJvcmluZyk6IEZpZ3VyZSBvdXQgaG93IHRvIHdyaXRlIHRlc3Qgb24gd2luZG93cy4KKyNlbHNlCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBXcml0ZURlcGVuZGVuY3lNYW5pZmVzdEZpbGVHaXZlblR3b0lucHV0cykgeworICBDcmVhdGVUZW1wRmlsZSgiZm9vLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAibWVzc2FnZSBGb28ge31cbiIpOworICBDcmVhdGVUZW1wRmlsZSgiYmFyLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAiaW1wb3J0IFwiZm9vLnByb3RvXCI7XG4iCisgICAgIm1lc3NhZ2UgQmFyIHtcbiIKKyAgICAiICBvcHRpb25hbCBGb28gZm9vID0gMTtcbiIKKyAgICAifVxuIik7CisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAtLWRlcGVuZGVuY3lfb3V0PSR0bXBkaXIvbWFuaWZlc3QgIgorICAgICAgIi0tdGVzdF9vdXQ9JHRtcGRpciAtLXByb3RvX3BhdGg9JHRtcGRpciBiYXIucHJvdG8gZm9vLnByb3RvIik7CisKKyAgRXhwZWN0RXJyb3JUZXh0KAorICAgICAgIkNhbiBvbmx5IHByb2Nlc3Mgb25lIGlucHV0IGZpbGUgd2hlbiB1c2luZyAtLWRlcGVuZGVuY3lfb3V0PUZJTEUuXG4iKTsKK30KKworI2lmZGVmIFBST1RPQlVGX09QRU5TT1VSQ0UKK1RFU1RfRihDb21tYW5kTGluZUludGVyZmFjZVRlc3QsIFdyaXRlRGVwZW5kZW5jeU1hbmlmZXN0RmlsZSkgeworICBDcmVhdGVUZW1wRmlsZSgiZm9vLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAibWVzc2FnZSBGb28ge31cbiIpOworICBDcmVhdGVUZW1wRmlsZSgiYmFyLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAiaW1wb3J0IFwiZm9vLnByb3RvXCI7XG4iCisgICAgIm1lc3NhZ2UgQmFyIHtcbiIKKyAgICAiICBvcHRpb25hbCBGb28gZm9vID0gMTtcbiIKKyAgICAifVxuIik7CisKKyAgc3RyaW5nIGN1cnJlbnRfd29ya2luZ19kaXJlY3RvcnkgPSBnZXRjd2QoTlVMTCwgMCk7CisgIFN3aXRjaFRvVGVtcERpcmVjdG9yeSgpOworCisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgLS1kZXBlbmRlbmN5X291dD1tYW5pZmVzdCAtLXRlc3Rfb3V0PS4gIgorICAgICAgImJhci5wcm90byIpOworCisgIEV4cGVjdE5vRXJyb3JzKCk7CisKKyAgRXhwZWN0RmlsZUNvbnRlbnQoIm1hbmlmZXN0IiwKKyAgICAgICAgICAgICAgICAgICAgImJhci5wcm90by5Nb2NrQ29kZUdlbmVyYXRvci50ZXN0X2dlbmVyYXRvcjogIgorICAgICAgICAgICAgICAgICAgICAiZm9vLnByb3RvXFxcbiBiYXIucHJvdG8iKTsKKworICBGaWxlOjpDaGFuZ2VXb3JraW5nRGlyZWN0b3J5KGN1cnJlbnRfd29ya2luZ19kaXJlY3RvcnkpOworfQorI2Vsc2UgIC8vICFQUk9UT0JVRl9PUEVOU09VUkNFCisvLyBUT0RPKHRlYm9yaW5nKTogRmlndXJlIG91dCBob3cgdG8gY2hhbmdlIGFuZCBnZXQgd29ya2luZyBkaXJlY3RvcnkgaW4KKy8vIGdvb2dsZTMuCisjZW5kaWYgIC8vICFQUk9UT0JVRl9PUEVOU09VUkNFCisKK1RFU1RfRihDb21tYW5kTGluZUludGVyZmFjZVRlc3QsIFdyaXRlRGVwZW5kZW5jeU1hbmlmZXN0RmlsZUZvckFic29sdXRlUGF0aCkgeworICBDcmVhdGVUZW1wRmlsZSgiZm9vLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAibWVzc2FnZSBGb28ge31cbiIpOworICBDcmVhdGVUZW1wRmlsZSgiYmFyLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAiaW1wb3J0IFwiZm9vLnByb3RvXCI7XG4iCisgICAgIm1lc3NhZ2UgQmFyIHtcbiIKKyAgICAiICBvcHRpb25hbCBGb28gZm9vID0gMTtcbiIKKyAgICAifVxuIik7CisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAtLWRlcGVuZGVuY3lfb3V0PSR0bXBkaXIvbWFuaWZlc3QgIgorICAgICAgIi0tdGVzdF9vdXQ9JHRtcGRpciAtLXByb3RvX3BhdGg9JHRtcGRpciBiYXIucHJvdG8iKTsKKworICBFeHBlY3ROb0Vycm9ycygpOworCisgIEV4cGVjdEZpbGVDb250ZW50KCJtYW5pZmVzdCIsCisgICAgICAgICAgICAgICAgICAgICIkdG1wZGlyL2Jhci5wcm90by5Nb2NrQ29kZUdlbmVyYXRvci50ZXN0X2dlbmVyYXRvcjogIgorICAgICAgICAgICAgICAgICAgICAiJHRtcGRpci9mb28ucHJvdG9cXFxuICR0bXBkaXIvYmFyLnByb3RvIik7Cit9CisjZW5kaWYgIC8vICFfV0lOMzIKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBQYXJzZUVycm9ycykgeworICAvLyBUZXN0IHRoYXQgcGFyc2UgZXJyb3JzIGFyZSByZXBvcnRlZC4KKworICBDcmVhdGVUZW1wRmlsZSgiZm9vLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAiYmFkc3ludGF4XG4iKTsKKworICBSdW4oInByb3RvY29sX2NvbXBpbGVyIC0tdGVzdF9vdXQ9JHRtcGRpciAiCisgICAgICAiLS1wcm90b19wYXRoPSR0bXBkaXIgZm9vLnByb3RvIik7CisKKyAgRXhwZWN0RXJyb3JUZXh0KAorICAgICJmb28ucHJvdG86MjoxOiBFeHBlY3RlZCB0b3AtbGV2ZWwgc3RhdGVtZW50IChlLmcuIFwibWVzc2FnZVwiKS5cbiIpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBQYXJzZUVycm9yc011bHRpcGxlRmlsZXMpIHsKKyAgLy8gVGVzdCB0aGF0IHBhcnNlIGVycm9ycyBhcmUgcmVwb3J0ZWQgZnJvbSBtdWx0aXBsZSBmaWxlcy4KKworICAvLyBXZSBzZXQgdXAgZmlsZXMgc3VjaCB0aGF0IGZvby5wcm90byBhY3R1YWxseSBkZXBlbmRzIG9uIGJhci5wcm90byBpbgorICAvLyB0d28gd2F5czogIERpcmVjdGx5IGFuZCB0aHJvdWdoIGJhei5wcm90by4gIGJhci5wcm90bydzIGVycm9ycyBzaG91bGQKKyAgLy8gb25seSBiZSByZXBvcnRlZCBvbmNlLgorICBDcmVhdGVUZW1wRmlsZSgiYmFyLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAiYmFkc3ludGF4XG4iKTsKKyAgQ3JlYXRlVGVtcEZpbGUoImJhei5wcm90byIsCisgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgImltcG9ydCBcImJhci5wcm90b1wiO1xuIik7CisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJpbXBvcnQgXCJiYXIucHJvdG9cIjtcbiIKKyAgICAiaW1wb3J0IFwiYmF6LnByb3RvXCI7XG4iKTsKKworICBSdW4oInByb3RvY29sX2NvbXBpbGVyIC0tdGVzdF9vdXQ9JHRtcGRpciAiCisgICAgICAiLS1wcm90b19wYXRoPSR0bXBkaXIgZm9vLnByb3RvIik7CisKKyAgRXhwZWN0RXJyb3JUZXh0KAorICAgICJiYXIucHJvdG86MjoxOiBFeHBlY3RlZCB0b3AtbGV2ZWwgc3RhdGVtZW50IChlLmcuIFwibWVzc2FnZVwiKS5cbiIKKyAgICAiYmF6LnByb3RvOiBJbXBvcnQgXCJiYXIucHJvdG9cIiB3YXMgbm90IGZvdW5kIG9yIGhhZCBlcnJvcnMuXG4iCisgICAgImZvby5wcm90bzogSW1wb3J0IFwiYmFyLnByb3RvXCIgd2FzIG5vdCBmb3VuZCBvciBoYWQgZXJyb3JzLlxuIgorICAgICJmb28ucHJvdG86IEltcG9ydCBcImJhei5wcm90b1wiIHdhcyBub3QgZm91bmQgb3IgaGFkIGVycm9ycy5cbiIpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBJbnB1dE5vdEZvdW5kRXJyb3IpIHsKKyAgLy8gVGVzdCB3aGF0IGhhcHBlbnMgaWYgdGhlIGlucHV0IGZpbGUgaXMgbm90IGZvdW5kLgorCisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgLS10ZXN0X291dD0kdG1wZGlyICIKKyAgICAgICItLXByb3RvX3BhdGg9JHRtcGRpciBmb28ucHJvdG8iKTsKKworICBFeHBlY3RFcnJvclRleHQoCisgICAgImZvby5wcm90bzogRmlsZSBub3QgZm91bmQuXG4iKTsKK30KKworVEVTVF9GKENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdCwgQ3dkUmVsYXRpdmVJbnB1dE5vdEZvdW5kRXJyb3IpIHsKKyAgLy8gVGVzdCB3aGF0IGhhcHBlbnMgd2hlbiBhIHdvcmtpbmctZGlyZWN0b3J5LXJlbGF0aXZlIGlucHV0IGZpbGUgaXMgbm90CisgIC8vIGZvdW5kLgorCisgIFNldElucHV0c0FyZVByb3RvUGF0aFJlbGF0aXZlKGZhbHNlKTsKKworICBSdW4oInByb3RvY29sX2NvbXBpbGVyIC0tdGVzdF9vdXQ9JHRtcGRpciAiCisgICAgICAiLS1wcm90b19wYXRoPSR0bXBkaXIgJHRtcGRpci9mb28ucHJvdG8iKTsKKworICBFeHBlY3RFcnJvclRleHQoCisgICAgIiR0bXBkaXIvZm9vLnByb3RvOiBObyBzdWNoIGZpbGUgb3IgZGlyZWN0b3J5XG4iKTsKK30KKworVEVTVF9GKENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdCwgQ3dkUmVsYXRpdmVJbnB1dE5vdE1hcHBlZEVycm9yKSB7CisgIC8vIFRlc3Qgd2hhdCBoYXBwZW5zIHdoZW4gYSB3b3JraW5nLWRpcmVjdG9yeS1yZWxhdGl2ZSBpbnB1dCBmaWxlIGlzIG5vdAorICAvLyBtYXBwZWQgdG8gYSB2aXJ0dWFsIHBhdGguCisKKyAgU2V0SW5wdXRzQXJlUHJvdG9QYXRoUmVsYXRpdmUoZmFsc2UpOworCisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIEZvbyB7fVxuIik7CisKKyAgLy8gQ3JlYXRlIGEgZGlyZWN0b3J5IGNhbGxlZCAiYmFyIiBzbyB0aGF0IHdlIGNhbiBwb2ludCAtLXByb3RvX3BhdGggYXQgaXQuCisgIENyZWF0ZVRlbXBGaWxlKCJiYXIvZHVtbXkiLCAiIik7CisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAtLXRlc3Rfb3V0PSR0bXBkaXIgIgorICAgICAgIi0tcHJvdG9fcGF0aD0kdG1wZGlyL2JhciAkdG1wZGlyL2Zvby5wcm90byIpOworCisgIEV4cGVjdEVycm9yVGV4dCgKKyAgICAiJHRtcGRpci9mb28ucHJvdG86IEZpbGUgZG9lcyBub3QgcmVzaWRlIHdpdGhpbiBhbnkgcGF0aCAiCisgICAgICAic3BlY2lmaWVkIHVzaW5nIC0tcHJvdG9fcGF0aCAob3IgLUkpLiAgWW91IG11c3Qgc3BlY2lmeSBhICIKKyAgICAgICItLXByb3RvX3BhdGggd2hpY2ggZW5jb21wYXNzZXMgdGhpcyBmaWxlLiAgTm90ZSB0aGF0IHRoZSAiCisgICAgICAicHJvdG9fcGF0aCBtdXN0IGJlIGFuIGV4YWN0IHByZWZpeCBvZiB0aGUgLnByb3RvIGZpbGUgIgorICAgICAgIm5hbWVzIC0tIHByb3RvYyBpcyB0b28gZHVtYiB0byBmaWd1cmUgb3V0IHdoZW4gdHdvIHBhdGhzICIKKyAgICAgICIoZS5nLiBhYnNvbHV0ZSBhbmQgcmVsYXRpdmUpIGFyZSBlcXVpdmFsZW50IChpdCdzIGhhcmRlciAiCisgICAgICAidGhhbiB5b3UgdGhpbmspLlxuIik7Cit9CisKK1RFU1RfRihDb21tYW5kTGluZUludGVyZmFjZVRlc3QsIEN3ZFJlbGF0aXZlSW5wdXROb3RGb3VuZEFuZE5vdE1hcHBlZEVycm9yKSB7CisgIC8vIENoZWNrIHdoYXQgaGFwcGVucyBpZiB0aGUgaW5wdXQgZmlsZSBpcyBub3QgZm91bmQgKmFuZCogaXMgbm90IG1hcHBlZAorICAvLyBpbiB0aGUgcHJvdG9fcGF0aC4KKworICBTZXRJbnB1dHNBcmVQcm90b1BhdGhSZWxhdGl2ZShmYWxzZSk7CisKKyAgLy8gQ3JlYXRlIGEgZGlyZWN0b3J5IGNhbGxlZCAiYmFyIiBzbyB0aGF0IHdlIGNhbiBwb2ludCAtLXByb3RvX3BhdGggYXQgaXQuCisgIENyZWF0ZVRlbXBGaWxlKCJiYXIvZHVtbXkiLCAiIik7CisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAtLXRlc3Rfb3V0PSR0bXBkaXIgIgorICAgICAgIi0tcHJvdG9fcGF0aD0kdG1wZGlyL2JhciAkdG1wZGlyL2Zvby5wcm90byIpOworCisgIEV4cGVjdEVycm9yVGV4dCgKKyAgICAiJHRtcGRpci9mb28ucHJvdG86IE5vIHN1Y2ggZmlsZSBvciBkaXJlY3RvcnlcbiIpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBDd2RSZWxhdGl2ZUlucHV0U2hhZG93ZWRFcnJvcikgeworICAvLyBUZXN0IHdoYXQgaGFwcGVucyB3aGVuIGEgd29ya2luZy1kaXJlY3RvcnktcmVsYXRpdmUgaW5wdXQgZmlsZSBpcyBzaGFkb3dlZAorICAvLyBieSBhbm90aGVyIGZpbGUgaW4gdGhlIHZpcnR1YWwgcGF0aC4KKworICBTZXRJbnB1dHNBcmVQcm90b1BhdGhSZWxhdGl2ZShmYWxzZSk7CisKKyAgQ3JlYXRlVGVtcEZpbGUoImZvby9mb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIEZvbyB7fVxuIik7CisgIENyZWF0ZVRlbXBGaWxlKCJiYXIvZm9vLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAibWVzc2FnZSBCYXIge31cbiIpOworCisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgLS10ZXN0X291dD0kdG1wZGlyICIKKyAgICAgICItLXByb3RvX3BhdGg9JHRtcGRpci9mb28gLS1wcm90b19wYXRoPSR0bXBkaXIvYmFyICIKKyAgICAgICIkdG1wZGlyL2Jhci9mb28ucHJvdG8iKTsKKworICBFeHBlY3RFcnJvclRleHQoCisgICAgIiR0bXBkaXIvYmFyL2Zvby5wcm90bzogSW5wdXQgaXMgc2hhZG93ZWQgaW4gdGhlIC0tcHJvdG9fcGF0aCAiCisgICAgImJ5IFwiJHRtcGRpci9mb28vZm9vLnByb3RvXCIuICBFaXRoZXIgdXNlIHRoZSBsYXR0ZXIgIgorICAgICJmaWxlIGFzIHlvdXIgaW5wdXQgb3IgcmVvcmRlciB0aGUgLS1wcm90b19wYXRoIHNvIHRoYXQgdGhlICIKKyAgICAiZm9ybWVyIGZpbGUncyBsb2NhdGlvbiBjb21lcyBmaXJzdC5cbiIpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBQcm90b1BhdGhOb3RGb3VuZEVycm9yKSB7CisgIC8vIFRlc3Qgd2hhdCBoYXBwZW5zIGlmIHRoZSBpbnB1dCBmaWxlIGlzIG5vdCBmb3VuZC4KKworICBSdW4oInByb3RvY29sX2NvbXBpbGVyIC0tdGVzdF9vdXQ9JHRtcGRpciAiCisgICAgICAiLS1wcm90b19wYXRoPSR0bXBkaXIvZm9vIGZvby5wcm90byIpOworCisgIEV4cGVjdEVycm9yVGV4dCgKKyAgICAiJHRtcGRpci9mb286IHdhcm5pbmc6IGRpcmVjdG9yeSBkb2VzIG5vdCBleGlzdC5cbiIKKyAgICAiZm9vLnByb3RvOiBGaWxlIG5vdCBmb3VuZC5cbiIpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBNaXNzaW5nSW5wdXRFcnJvcikgeworICAvLyBUZXN0IHRoYXQgd2UgZ2V0IGFuIGVycm9yIGlmIG5vIGlucHV0cyBhcmUgZ2l2ZW4uCisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAtLXRlc3Rfb3V0PSR0bXBkaXIgIgorICAgICAgIi0tcHJvdG9fcGF0aD0kdG1wZGlyIik7CisKKyAgRXhwZWN0RXJyb3JUZXh0KCJNaXNzaW5nIGlucHV0IGZpbGUuXG4iKTsKK30KKworVEVTVF9GKENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdCwgTWlzc2luZ091dHB1dEVycm9yKSB7CisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIEZvbyB7fVxuIik7CisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAtLXByb3RvX3BhdGg9JHRtcGRpciBmb28ucHJvdG8iKTsKKworICBFeHBlY3RFcnJvclRleHQoIk1pc3Npbmcgb3V0cHV0IGRpcmVjdGl2ZXMuXG4iKTsKK30KKworVEVTVF9GKENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdCwgT3V0cHV0V3JpdGVFcnJvcikgeworICBDcmVhdGVUZW1wRmlsZSgiZm9vLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAibWVzc2FnZSBGb28ge31cbiIpOworCisgIHN0cmluZyBvdXRwdXRfZmlsZSA9CisgICAgICBNb2NrQ29kZUdlbmVyYXRvcjo6R2V0T3V0cHV0RmlsZU5hbWUoInRlc3RfZ2VuZXJhdG9yIiwgImZvby5wcm90byIpOworCisgIC8vIENyZWF0ZSBhIGRpcmVjdG9yeSBibG9ja2luZyBvdXIgb3V0cHV0IGxvY2F0aW9uLgorICBDcmVhdGVUZW1wRGlyKG91dHB1dF9maWxlKTsKKworICBSdW4oInByb3RvY29sX2NvbXBpbGVyIC0tdGVzdF9vdXQ9JHRtcGRpciAiCisgICAgICAiLS1wcm90b19wYXRoPSR0bXBkaXIgZm9vLnByb3RvIik7CisKKyAgLy8gTW9ja0NvZGVHZW5lcmF0b3Igbm8gbG9uZ2VyIGRldGVjdHMgYW4gZXJyb3IgYmVjYXVzZSB3ZSBhY3R1YWxseSB3cml0ZSB0bworICAvLyBhbiBpbi1tZW1vcnkgbG9jYXRpb24gZmlyc3QsIHRoZW4gZHVtcCB0byBkaXNrIGF0IHRoZSBlbmQuICBUaGlzIGlzIG5vCisgIC8vIGJpZyBkZWFsLgorICAvLyAgIEV4cGVjdEVycm9yU3Vic3RyaW5nKCJNb2NrQ29kZUdlbmVyYXRvciBkZXRlY3RlZCB3cml0ZSBlcnJvci4iKTsKKworI2lmIGRlZmluZWQoX1dJTjMyKSAmJiAhZGVmaW5lZChfX0NZR1dJTl9fKQorICAvLyBXaW5kb3dzIHdpdGggTVNWQ1JULmRsbCBwcm9kdWNlcyBFUEVSTSBpbnN0ZWFkIG9mIEVJU0RJUi4KKyAgaWYgKEhhc0FsdGVybmF0ZUVycm9yU3Vic3RyaW5nKG91dHB1dF9maWxlICsgIjogUGVybWlzc2lvbiBkZW5pZWQiKSkgeworICAgIHJldHVybjsKKyAgfQorI2VuZGlmCisKKyAgRXhwZWN0RXJyb3JTdWJzdHJpbmcob3V0cHV0X2ZpbGUgKyAiOiBJcyBhIGRpcmVjdG9yeSIpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBQbHVnaW5PdXRwdXRXcml0ZUVycm9yKSB7CisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIEZvbyB7fVxuIik7CisKKyAgc3RyaW5nIG91dHB1dF9maWxlID0KKyAgICAgIE1vY2tDb2RlR2VuZXJhdG9yOjpHZXRPdXRwdXRGaWxlTmFtZSgidGVzdF9wbHVnaW4iLCAiZm9vLnByb3RvIik7CisKKyAgLy8gQ3JlYXRlIGEgZGlyZWN0b3J5IGJsb2NraW5nIG91ciBvdXRwdXQgbG9jYXRpb24uCisgIENyZWF0ZVRlbXBEaXIob3V0cHV0X2ZpbGUpOworCisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgLS1wbHVnX291dD0kdG1wZGlyICIKKyAgICAgICItLXByb3RvX3BhdGg9JHRtcGRpciBmb28ucHJvdG8iKTsKKworI2lmIGRlZmluZWQoX1dJTjMyKSAmJiAhZGVmaW5lZChfX0NZR1dJTl9fKQorICAvLyBXaW5kb3dzIHdpdGggTVNWQ1JULmRsbCBwcm9kdWNlcyBFUEVSTSBpbnN0ZWFkIG9mIEVJU0RJUi4KKyAgaWYgKEhhc0FsdGVybmF0ZUVycm9yU3Vic3RyaW5nKG91dHB1dF9maWxlICsgIjogUGVybWlzc2lvbiBkZW5pZWQiKSkgeworICAgIHJldHVybjsKKyAgfQorI2VuZGlmCisKKyAgRXhwZWN0RXJyb3JTdWJzdHJpbmcob3V0cHV0X2ZpbGUgKyAiOiBJcyBhIGRpcmVjdG9yeSIpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBPdXRwdXREaXJlY3RvcnlOb3RGb3VuZEVycm9yKSB7CisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIEZvbyB7fVxuIik7CisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAtLXRlc3Rfb3V0PSR0bXBkaXIvbm9zdWNoZGlyICIKKyAgICAgICItLXByb3RvX3BhdGg9JHRtcGRpciBmb28ucHJvdG8iKTsKKworICBFeHBlY3RFcnJvclN1YnN0cmluZygibm9zdWNoZGlyLzogTm8gc3VjaCBmaWxlIG9yIGRpcmVjdG9yeSIpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBQbHVnaW5PdXRwdXREaXJlY3RvcnlOb3RGb3VuZEVycm9yKSB7CisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIEZvbyB7fVxuIik7CisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAtLXBsdWdfb3V0PSR0bXBkaXIvbm9zdWNoZGlyICIKKyAgICAgICItLXByb3RvX3BhdGg9JHRtcGRpciBmb28ucHJvdG8iKTsKKworICBFeHBlY3RFcnJvclN1YnN0cmluZygibm9zdWNoZGlyLzogTm8gc3VjaCBmaWxlIG9yIGRpcmVjdG9yeSIpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBPdXRwdXREaXJlY3RvcnlJc0ZpbGVFcnJvcikgeworICBDcmVhdGVUZW1wRmlsZSgiZm9vLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAibWVzc2FnZSBGb28ge31cbiIpOworCisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgLS10ZXN0X291dD0kdG1wZGlyL2Zvby5wcm90byAiCisgICAgICAiLS1wcm90b19wYXRoPSR0bXBkaXIgZm9vLnByb3RvIik7CisKKyNpZiBkZWZpbmVkKF9XSU4zMikgJiYgIWRlZmluZWQoX19DWUdXSU5fXykKKyAgLy8gV2luZG93cyB3aXRoIE1TVkNSVC5kbGwgcHJvZHVjZXMgRUlOVkFMIGluc3RlYWQgb2YgRU5PVERJUi4KKyAgaWYgKEhhc0FsdGVybmF0ZUVycm9yU3Vic3RyaW5nKCJmb28ucHJvdG8vOiBJbnZhbGlkIGFyZ3VtZW50IikpIHsKKyAgICByZXR1cm47CisgIH0KKyNlbmRpZgorCisgIEV4cGVjdEVycm9yU3Vic3RyaW5nKCJmb28ucHJvdG8vOiBOb3QgYSBkaXJlY3RvcnkiKTsKK30KKworVEVTVF9GKENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdCwgR2VuZXJhdG9yRXJyb3IpIHsKKyAgQ3JlYXRlVGVtcEZpbGUoImZvby5wcm90byIsCisgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgIm1lc3NhZ2UgTW9ja0NvZGVHZW5lcmF0b3JfRXJyb3Ige31cbiIpOworCisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgLS10ZXN0X291dD0kdG1wZGlyICIKKyAgICAgICItLXByb3RvX3BhdGg9JHRtcGRpciBmb28ucHJvdG8iKTsKKworICBFeHBlY3RFcnJvclN1YnN0cmluZygKKyAgICAgICItLXRlc3Rfb3V0OiBmb28ucHJvdG86IFNhdyBtZXNzYWdlIHR5cGUgTW9ja0NvZGVHZW5lcmF0b3JfRXJyb3IuIik7Cit9CisKK1RFU1RfRihDb21tYW5kTGluZUludGVyZmFjZVRlc3QsIEdlbmVyYXRvclBsdWdpbkVycm9yKSB7CisgIC8vIFRlc3QgYSBnZW5lcmF0b3IgcGx1Z2luIHRoYXQgcmV0dXJucyBhbiBlcnJvci4KKworICBDcmVhdGVUZW1wRmlsZSgiZm9vLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAibWVzc2FnZSBNb2NrQ29kZUdlbmVyYXRvcl9FcnJvciB7fVxuIik7CisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAtLXBsdWdfb3V0PVRlc3RQYXJhbWV0ZXI6JHRtcGRpciAiCisgICAgICAiLS1wcm90b19wYXRoPSR0bXBkaXIgZm9vLnByb3RvIik7CisKKyAgRXhwZWN0RXJyb3JTdWJzdHJpbmcoCisgICAgICAiLS1wbHVnX291dDogZm9vLnByb3RvOiBTYXcgbWVzc2FnZSB0eXBlIE1vY2tDb2RlR2VuZXJhdG9yX0Vycm9yLiIpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBHZW5lcmF0b3JQbHVnaW5GYWlsKSB7CisgIC8vIFRlc3QgYSBnZW5lcmF0b3IgcGx1Z2luIHRoYXQgZXhpdHMgd2l0aCBhbiBlcnJvciBjb2RlLgorCisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIE1vY2tDb2RlR2VuZXJhdG9yX0V4aXQge31cbiIpOworCisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgLS1wbHVnX291dD1UZXN0UGFyYW1ldGVyOiR0bXBkaXIgIgorICAgICAgIi0tcHJvdG9fcGF0aD0kdG1wZGlyIGZvby5wcm90byIpOworCisgIEV4cGVjdEVycm9yU3Vic3RyaW5nKCJTYXcgbWVzc2FnZSB0eXBlIE1vY2tDb2RlR2VuZXJhdG9yX0V4aXQuIik7CisgIEV4cGVjdEVycm9yU3Vic3RyaW5nKAorICAgICAgIi0tcGx1Z19vdXQ6IHByZWZpeC1nZW4tcGx1ZzogUGx1Z2luIGZhaWxlZCB3aXRoIHN0YXR1cyBjb2RlIDEyMy4iKTsKK30KKworVEVTVF9GKENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdCwgR2VuZXJhdG9yUGx1Z2luQ3Jhc2gpIHsKKyAgLy8gVGVzdCBhIGdlbmVyYXRvciBwbHVnaW4gdGhhdCBjcmFzaGVzLgorCisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIE1vY2tDb2RlR2VuZXJhdG9yX0Fib3J0IHt9XG4iKTsKKworICBSdW4oInByb3RvY29sX2NvbXBpbGVyIC0tcGx1Z19vdXQ9VGVzdFBhcmFtZXRlcjokdG1wZGlyICIKKyAgICAgICItLXByb3RvX3BhdGg9JHRtcGRpciBmb28ucHJvdG8iKTsKKworICBFeHBlY3RFcnJvclN1YnN0cmluZygiU2F3IG1lc3NhZ2UgdHlwZSBNb2NrQ29kZUdlbmVyYXRvcl9BYm9ydC4iKTsKKworI2lmZGVmIF9XSU4zMgorICAvLyBXaW5kb3dzIGRvZXNuJ3QgaGF2ZSBzaWduYWxzLiAgSXQgbG9va3MgbGlrZSBhYm9ydCgpaW5nIGNhdXNlcyB0aGUgcHJvY2VzcworICAvLyB0byBleGl0IHdpdGggc3RhdHVzIGNvZGUgMywgYnV0IGxldCdzIG5vdCBkZXBlbmQgb24gdGhlIGV4YWN0IG51bWJlciBoZXJlLgorICBFeHBlY3RFcnJvclN1YnN0cmluZygKKyAgICAgICItLXBsdWdfb3V0OiBwcmVmaXgtZ2VuLXBsdWc6IFBsdWdpbiBmYWlsZWQgd2l0aCBzdGF0dXMgY29kZSIpOworI2Vsc2UKKyAgLy8gRG9uJ3QgZGVwZW5kIG9uIHRoZSBleGFjdCBzaWduYWwgbnVtYmVyLgorICBFeHBlY3RFcnJvclN1YnN0cmluZygKKyAgICAgICItLXBsdWdfb3V0OiBwcmVmaXgtZ2VuLXBsdWc6IFBsdWdpbiBraWxsZWQgYnkgc2lnbmFsIik7CisjZW5kaWYKK30KKworVEVTVF9GKENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdCwgUGx1Z2luUmVjZWl2ZXNTb3VyY2VDb2RlSW5mbykgeworICBDcmVhdGVUZW1wRmlsZSgiZm9vLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAibWVzc2FnZSBNb2NrQ29kZUdlbmVyYXRvcl9IYXNTb3VyY2VDb2RlSW5mbyB7fVxuIik7CisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAtLXBsdWdfb3V0PSR0bXBkaXIgLS1wcm90b19wYXRoPSR0bXBkaXIgZm9vLnByb3RvIik7CisKKyAgRXhwZWN0RXJyb3JTdWJzdHJpbmcoCisgICAgICAiU2F3IG1lc3NhZ2UgdHlwZSBNb2NrQ29kZUdlbmVyYXRvcl9IYXNTb3VyY2VDb2RlSW5mbzogMS4iKTsKK30KKworVEVTVF9GKENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdCwgUGx1Z2luUmVjZWl2ZXNKc29uTmFtZSkgeworICBDcmVhdGVUZW1wRmlsZSgiZm9vLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAibWVzc2FnZSBNb2NrQ29kZUdlbmVyYXRvcl9IYXNKc29uTmFtZSB7XG4iCisgICAgIiAgb3B0aW9uYWwgaW50MzIgdmFsdWUgPSAxO1xuIgorICAgICJ9XG4iKTsKKworICBSdW4oInByb3RvY29sX2NvbXBpbGVyIC0tcGx1Z19vdXQ9JHRtcGRpciAtLXByb3RvX3BhdGg9JHRtcGRpciBmb28ucHJvdG8iKTsKKworICBFeHBlY3RFcnJvclN1YnN0cmluZygiU2F3IGpzb25fbmFtZTogMSIpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBHZW5lcmF0b3JQbHVnaW5Ob3RGb3VuZCkgeworICAvLyBUZXN0IHdoYXQgaGFwcGVucyBpZiB0aGUgcGx1Z2luIGlzbid0IGZvdW5kLgorCisgIENyZWF0ZVRlbXBGaWxlKCJlcnJvci5wcm90byIsCisgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgIm1lc3NhZ2UgRm9vIHt9XG4iKTsKKworICBSdW4oInByb3RvY29sX2NvbXBpbGVyIC0tYmFkcGx1Z19vdXQ9VGVzdFBhcmFtZXRlcjokdG1wZGlyICIKKyAgICAgICItLXBsdWdpbj1wcmVmaXgtZ2VuLWJhZHBsdWc9bm9fc3VjaF9maWxlICIKKyAgICAgICItLXByb3RvX3BhdGg9JHRtcGRpciBlcnJvci5wcm90byIpOworCisjaWZkZWYgX1dJTjMyCisgIEV4cGVjdEVycm9yU3Vic3RyaW5nKCItLWJhZHBsdWdfb3V0OiBwcmVmaXgtZ2VuLWJhZHBsdWc6ICIgKworICAgICAgU3VicHJvY2Vzczo6V2luMzJFcnJvck1lc3NhZ2UoRVJST1JfRklMRV9OT1RfRk9VTkQpKTsKKyNlbHNlCisgIC8vIEVycm9yIHdyaXR0ZW4gdG8gc3Rkb3V0IGJ5IGNoaWxkIHByb2Nlc3MgYWZ0ZXIgZXhlYygpIGZhaWxzLgorICBFeHBlY3RFcnJvclN1YnN0cmluZygKKyAgICAgICJub19zdWNoX2ZpbGU6IHByb2dyYW0gbm90IGZvdW5kIG9yIGlzIG5vdCBleGVjdXRhYmxlIik7CisKKyAgLy8gRXJyb3Igd3JpdHRlbiBieSBwYXJlbnQgcHJvY2VzcyB3aGVuIGNoaWxkIGZhaWxzLgorICBFeHBlY3RFcnJvclN1YnN0cmluZygKKyAgICAgICItLWJhZHBsdWdfb3V0OiBwcmVmaXgtZ2VuLWJhZHBsdWc6IFBsdWdpbiBmYWlsZWQgd2l0aCBzdGF0dXMgY29kZSAxLiIpOworI2VuZGlmCit9CisKK1RFU1RfRihDb21tYW5kTGluZUludGVyZmFjZVRlc3QsIEdlbmVyYXRvclBsdWdpbk5vdEFsbG93ZWQpIHsKKyAgLy8gVGVzdCB3aGF0IGhhcHBlbnMgaWYgcGx1Z2lucyBhcmVuJ3QgYWxsb3dlZC4KKworICBDcmVhdGVUZW1wRmlsZSgiZXJyb3IucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIEZvbyB7fVxuIik7CisKKyAgRGlzYWxsb3dQbHVnaW5zKCk7CisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgLS1wbHVnX291dD1UZXN0UGFyYW1ldGVyOiR0bXBkaXIgIgorICAgICAgIi0tcHJvdG9fcGF0aD0kdG1wZGlyIGVycm9yLnByb3RvIik7CisKKyAgRXhwZWN0RXJyb3JTdWJzdHJpbmcoIlVua25vd24gZmxhZzogLS1wbHVnX291dCIpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBIZWxwVGV4dCkgeworICBSdW4oInRlc3RfZXhlY19uYW1lIC0taGVscCIpOworCisgIEV4cGVjdEVycm9yU3Vic3RyaW5nV2l0aFplcm9SZXR1cm5Db2RlKCJVc2FnZTogdGVzdF9leGVjX25hbWUgIik7CisgIEV4cGVjdEVycm9yU3Vic3RyaW5nV2l0aFplcm9SZXR1cm5Db2RlKCItLXRlc3Rfb3V0PU9VVF9ESVIiKTsKKyAgRXhwZWN0RXJyb3JTdWJzdHJpbmdXaXRoWmVyb1JldHVybkNvZGUoIlRlc3Qgb3V0cHV0LiIpOworICBFeHBlY3RFcnJvclN1YnN0cmluZ1dpdGhaZXJvUmV0dXJuQ29kZSgiLS1hbHRfb3V0PU9VVF9ESVIiKTsKKyAgRXhwZWN0RXJyb3JTdWJzdHJpbmdXaXRoWmVyb1JldHVybkNvZGUoIkFsdCBvdXRwdXQuIik7Cit9CisKK1RFU1RfRihDb21tYW5kTGluZUludGVyZmFjZVRlc3QsIEdjY0Zvcm1hdEVycm9ycykgeworICAvLyBUZXN0IC0tZXJyb3JfZm9ybWF0PWdjYyAod2hpY2ggaXMgdGhlIGRlZmF1bHQsIGJ1dCB3ZSB3YW50IHRvIHZlcmlmeQorICAvLyB0aGF0IGl0IGNhbiBiZSBzZXQgZXhwbGljaXRseSkuCisKKyAgQ3JlYXRlVGVtcEZpbGUoImZvby5wcm90byIsCisgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgImJhZHN5bnRheFxuIik7CisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAtLXRlc3Rfb3V0PSR0bXBkaXIgIgorICAgICAgIi0tcHJvdG9fcGF0aD0kdG1wZGlyIC0tZXJyb3JfZm9ybWF0PWdjYyBmb28ucHJvdG8iKTsKKworICBFeHBlY3RFcnJvclRleHQoCisgICAgImZvby5wcm90bzoyOjE6IEV4cGVjdGVkIHRvcC1sZXZlbCBzdGF0ZW1lbnQgKGUuZy4gXCJtZXNzYWdlXCIpLlxuIik7Cit9CisKK1RFU1RfRihDb21tYW5kTGluZUludGVyZmFjZVRlc3QsIE1zdnNGb3JtYXRFcnJvcnMpIHsKKyAgLy8gVGVzdCAtLWVycm9yX2Zvcm1hdD1tc3ZzCisKKyAgQ3JlYXRlVGVtcEZpbGUoImZvby5wcm90byIsCisgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgImJhZHN5bnRheFxuIik7CisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAtLXRlc3Rfb3V0PSR0bXBkaXIgIgorICAgICAgIi0tcHJvdG9fcGF0aD0kdG1wZGlyIC0tZXJyb3JfZm9ybWF0PW1zdnMgZm9vLnByb3RvIik7CisKKyAgRXhwZWN0RXJyb3JUZXh0KAorICAgICIkdG1wZGlyL2Zvby5wcm90bygyKSA6IGVycm9yIGluIGNvbHVtbj0xOiBFeHBlY3RlZCB0b3AtbGV2ZWwgc3RhdGVtZW50ICIKKyAgICAgICIoZS5nLiBcIm1lc3NhZ2VcIikuXG4iKTsKK30KKworVEVTVF9GKENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdCwgSW52YWxpZEVycm9yRm9ybWF0KSB7CisgIC8vIFRlc3QgLS1lcnJvcl9mb3JtYXQ9bXN2cworCisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJiYWRzeW50YXhcbiIpOworCisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgLS10ZXN0X291dD0kdG1wZGlyICIKKyAgICAgICItLXByb3RvX3BhdGg9JHRtcGRpciAtLWVycm9yX2Zvcm1hdD1pbnZhbGlkIGZvby5wcm90byIpOworCisgIEV4cGVjdEVycm9yVGV4dCgKKyAgICAiVW5rbm93biBlcnJvciBmb3JtYXQ6IGludmFsaWRcbiIpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBGbGFnIHBhcnNpbmcgdGVzdHMKKworVEVTVF9GKENvbW1hbmRMaW5lSW50ZXJmYWNlVGVzdCwgUGFyc2VTaW5nbGVDaGFyYWN0ZXJGbGFnKSB7CisgIC8vIFRlc3QgdGhhdCBhIHNpbmdsZS1jaGFyYWN0ZXIgZmxhZyB3b3Jrcy4KKworICBDcmVhdGVUZW1wRmlsZSgiZm9vLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAibWVzc2FnZSBGb28ge31cbiIpOworCisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgLXQkdG1wZGlyICIKKyAgICAgICItLXByb3RvX3BhdGg9JHRtcGRpciBmb28ucHJvdG8iKTsKKworICBFeHBlY3ROb0Vycm9ycygpOworICBFeHBlY3RHZW5lcmF0ZWQoInRlc3RfZ2VuZXJhdG9yIiwgIiIsICJmb28ucHJvdG8iLCAiRm9vIik7Cit9CisKK1RFU1RfRihDb21tYW5kTGluZUludGVyZmFjZVRlc3QsIFBhcnNlU3BhY2VEZWxpbWl0ZWRWYWx1ZSkgeworICAvLyBUZXN0IHRoYXQgc2VwYXJhdGluZyB0aGUgZmxhZyB2YWx1ZSB3aXRoIGEgc3BhY2Ugd29ya3MuCisKKyAgQ3JlYXRlVGVtcEZpbGUoImZvby5wcm90byIsCisgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgIm1lc3NhZ2UgRm9vIHt9XG4iKTsKKworICBSdW4oInByb3RvY29sX2NvbXBpbGVyIC0tdGVzdF9vdXQgJHRtcGRpciAiCisgICAgICAiLS1wcm90b19wYXRoPSR0bXBkaXIgZm9vLnByb3RvIik7CisKKyAgRXhwZWN0Tm9FcnJvcnMoKTsKKyAgRXhwZWN0R2VuZXJhdGVkKCJ0ZXN0X2dlbmVyYXRvciIsICIiLCAiZm9vLnByb3RvIiwgIkZvbyIpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBQYXJzZVNpbmdsZUNoYXJhY3RlclNwYWNlRGVsaW1pdGVkVmFsdWUpIHsKKyAgLy8gVGVzdCB0aGF0IHNlcGFyYXRpbmcgdGhlIGZsYWcgdmFsdWUgd2l0aCBhIHNwYWNlIHdvcmtzIGZvcgorICAvLyBzaW5nbGUtY2hhcmFjdGVyIGZsYWdzLgorCisgIENyZWF0ZVRlbXBGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJtZXNzYWdlIEZvbyB7fVxuIik7CisKKyAgUnVuKCJwcm90b2NvbF9jb21waWxlciAtdCAkdG1wZGlyICIKKyAgICAgICItLXByb3RvX3BhdGg9JHRtcGRpciBmb28ucHJvdG8iKTsKKworICBFeHBlY3ROb0Vycm9ycygpOworICBFeHBlY3RHZW5lcmF0ZWQoInRlc3RfZ2VuZXJhdG9yIiwgIiIsICJmb28ucHJvdG8iLCAiRm9vIik7Cit9CisKK1RFU1RfRihDb21tYW5kTGluZUludGVyZmFjZVRlc3QsIE1pc3NpbmdWYWx1ZUVycm9yKSB7CisgIC8vIFRlc3QgdGhhdCB3ZSBnZXQgYW4gZXJyb3IgaWYgYSBmbGFnIGlzIG1pc3NpbmcgaXRzIHZhbHVlLgorCisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgLS10ZXN0X291dCAtLXByb3RvX3BhdGg9JHRtcGRpciBmb28ucHJvdG8iKTsKKworICBFeHBlY3RFcnJvclRleHQoIk1pc3NpbmcgdmFsdWUgZm9yIGZsYWc6IC0tdGVzdF9vdXRcbiIpOworfQorCitURVNUX0YoQ29tbWFuZExpbmVJbnRlcmZhY2VUZXN0LCBNaXNzaW5nVmFsdWVBdEVuZEVycm9yKSB7CisgIC8vIFRlc3QgdGhhdCB3ZSBnZXQgYW4gZXJyb3IgaWYgdGhlIGxhc3QgYXJndW1lbnQgaXMgYSBmbGFnIHJlcXVpcmluZyBhCisgIC8vIHZhbHVlLgorCisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgLS10ZXN0X291dCIpOworCisgIEV4cGVjdEVycm9yVGV4dCgiTWlzc2luZyB2YWx1ZSBmb3IgZmxhZzogLS10ZXN0X291dFxuIik7Cit9CisKK1RFU1RfRihDb21tYW5kTGluZUludGVyZmFjZVRlc3QsIFByaW50RnJlZUZpZWxkTnVtYmVycykgeworICBDcmVhdGVUZW1wRmlsZSgKKyAgICAgICJmb28ucHJvdG8iLAorICAgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgICAicGFja2FnZSBmb287XG4iCisgICAgICAibWVzc2FnZSBGb28ge1xuIgorICAgICAgIiAgb3B0aW9uYWwgaW50MzIgYSA9IDI7XG4iCisgICAgICAiICBvcHRpb25hbCBzdHJpbmcgYiA9IDQ7XG4iCisgICAgICAiICBvcHRpb25hbCBzdHJpbmcgYyA9IDU7XG4iCisgICAgICAiICBvcHRpb25hbCBpbnQ2NCBkID0gODtcbiIKKyAgICAgICIgIG9wdGlvbmFsIGRvdWJsZSBlID0gMTA7XG4iCisgICAgICAifVxuIik7CisgIENyZWF0ZVRlbXBGaWxlKAorICAgICAgImJhci5wcm90byIsCisgICAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAgICJtZXNzYWdlIEJhciB7XG4iCisgICAgICAiICBvcHRpb25hbCBpbnQzMiBhID0gMjtcbiIKKyAgICAgICIgIGV4dGVuc2lvbnMgNCB0byA1O1xuIgorICAgICAgIiAgb3B0aW9uYWwgaW50NjQgZCA9IDg7XG4iCisgICAgICAiICBleHRlbnNpb25zIDEwO1xuIgorICAgICAgIn1cbiIpOworICBDcmVhdGVUZW1wRmlsZSgKKyAgICAgICJiYXoucHJvdG8iLAorICAgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgICAibWVzc2FnZSBCYXoge1xuIgorICAgICAgIiAgb3B0aW9uYWwgaW50MzIgYSA9IDI7XG4iCisgICAgICAiICBvcHRpb25hbCBpbnQ2NCBkID0gODtcbiIKKyAgICAgICIgIGV4dGVuc2lvbnMgMTUgdG8gbWF4O1xuIiAgLy8gdW5vcmRlcmVkLgorICAgICAgIiAgZXh0ZW5zaW9ucyAxMztcbiIKKyAgICAgICIgIGV4dGVuc2lvbnMgMTAgdG8gMTI7XG4iCisgICAgICAiICBleHRlbnNpb25zIDU7XG4iCisgICAgICAiICBleHRlbnNpb25zIDQ7XG4iCisgICAgICAifVxuIik7CisgIENyZWF0ZVRlbXBGaWxlKAorICAgICAgInF1ei5wcm90byIsCisgICAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAgICJtZXNzYWdlIFF1eiB7XG4iCisgICAgICAiICBtZXNzYWdlIEZvbyB7fVxuIiAgLy8gbmVzdGVkIG1lc3NhZ2UKKyAgICAgICIgIG9wdGlvbmFsIGludDMyIGEgPSAyO1xuIgorICAgICAgIiAgb3B0aW9uYWwgZ3JvdXAgQyA9IDQge1xuIgorICAgICAgIiAgICBvcHRpb25hbCBpbnQzMiBkID0gNTtcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICIgIGV4dGVuc2lvbnMgOCB0byAxMDtcbiIKKyAgICAgICIgIG9wdGlvbmFsIGdyb3VwIEUgPSAxMSB7XG4iCisgICAgICAiICAgIG9wdGlvbmFsIGludDMyIGYgPSA5O1xuIiAgICAvLyBleHBsaWNpdGx5IHJldXNlIGV4dGVuc2lvbiByYW5nZSA4LTEwCisgICAgICAiICAgIG9wdGlvbmFsIGdyb3VwIEcgPSAxNSB7XG4iICAvLyBuZXN0ZWQgZ3JvdXAKKyAgICAgICIgICAgICBtZXNzYWdlIEZvbyB7fVxuIiAgICAgICAgIC8vIG5lc3RlZCBtZXNzYWdlIGluc2lkZSBuZXN0ZWQgZ3JvdXAKKyAgICAgICIgICAgfVxuIgorICAgICAgIiAgfVxuIgorICAgICAgIn1cbiIpOworCisgIFJ1bigicHJvdG9jb2xfY29tcGlsZXIgLS1wcmludF9mcmVlX2ZpZWxkX251bWJlcnMgLS1wcm90b19wYXRoPSR0bXBkaXIgIgorICAgICAgImZvby5wcm90byBiYXIucHJvdG8gYmF6LnByb3RvIHF1ei5wcm90byIpOworCisgIEV4cGVjdE5vRXJyb3JzKCk7CisKKyAgLy8gVE9ETyhqaWVsdW8pOiBDeWd3aW4gZG9lc24ndCB3b3JrIHdlbGwgaWYgd2UgdHJ5IHRvIGNhcHR1cmUgc3RkZXJyIGFuZAorICAvLyBzdGRvdXQgYXQgdGhlIHNhbWUgdGltZS4gTmVlZCB0byBmaWd1cmUgb3V0IHdoeSBhbmQgYWRkIHRoaXMgdGVzdCBiYWNrCisgIC8vIGZvciBDeWd3aW4uCisjaWYgIWRlZmluZWQoX19DWUdXSU5fXykKKyAgRXhwZWN0Q2FwdHVyZWRTdGRvdXQoCisgICAgICAiZm9vLkZvbyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJlZTogMSAzIDYtNyA5IDExLUlORlxuIgorICAgICAgIkJhciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyZWU6IDEgMyA2LTcgOSAxMS1JTkZcbiIKKyAgICAgICJCYXogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmVlOiAxIDMgNi03IDkgMTRcbiIKKyAgICAgICJRdXouRm9vICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmVlOiAxLUlORlxuIgorICAgICAgIlF1ei5FLkcuRm9vICAgICAgICAgICAgICAgICAgICAgICAgIGZyZWU6IDEtSU5GXG4iCisgICAgICAiUXV6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJlZTogMSAzIDYtNyAxMi0xNCAxNi1JTkZcbiIpOworI2VuZGlmCit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworLy8gVGVzdCBmb3IgLS1lbmNvZGUgYW5kIC0tZGVjb2RlLiAgTm90ZSB0aGF0IGl0IHdvdWxkIGJlIGVhc2llciB0byBkbyB0aGlzCisvLyB0ZXN0IGFzIGEgc2hlbGwgc2NyaXB0LCBidXQgd2UnZCBsaWtlIHRvIGJlIGFibGUgdG8gcnVuIHRoZSB0ZXN0IG9uCisvLyBwbGF0Zm9ybXMgdGhhdCBkb24ndCBoYXZlIGEgQm91cm5lLWNvbXBhdGlibGUgc2hlbGwgYXZhaWxhYmxlIChlc3BlY2lhbGx5CisvLyBXaW5kb3dzL01TVkMpLgorY2xhc3MgRW5jb2RlRGVjb2RlVGVzdCA6IHB1YmxpYyB0ZXN0aW5nOjpUZXN0IHsKKyBwcm90ZWN0ZWQ6CisgIHZpcnR1YWwgdm9pZCBTZXRVcCgpIHsKKyAgICBkdXBlZF9zdGRpbl8gPSBkdXAoU1RESU5fRklMRU5PKTsKKyAgfQorCisgIHZpcnR1YWwgdm9pZCBUZWFyRG93bigpIHsKKyAgICBkdXAyKGR1cGVkX3N0ZGluXywgU1RESU5fRklMRU5PKTsKKyAgICBjbG9zZShkdXBlZF9zdGRpbl8pOworICB9CisKKyAgdm9pZCBSZWRpcmVjdFN0ZGluRnJvbVRleHQoY29uc3Qgc3RyaW5nJiBpbnB1dCkgeworICAgIHN0cmluZyBmaWxlbmFtZSA9IFRlc3RUZW1wRGlyKCkgKyAiL3Rlc3Rfc3RkaW4iOworICAgIEdPT0dMRV9DSEVDS19PSyhGaWxlOjpTZXRDb250ZW50cyhmaWxlbmFtZSwgaW5wdXQsIHRydWUpKTsKKyAgICBHT09HTEVfQ0hFQ0soUmVkaXJlY3RTdGRpbkZyb21GaWxlKGZpbGVuYW1lKSk7CisgIH0KKworICBib29sIFJlZGlyZWN0U3RkaW5Gcm9tRmlsZShjb25zdCBzdHJpbmcmIGZpbGVuYW1lKSB7CisgICAgaW50IGZkID0gb3BlbihmaWxlbmFtZS5jX3N0cigpLCBPX1JET05MWSk7CisgICAgaWYgKGZkIDwgMCkgcmV0dXJuIGZhbHNlOworICAgIGR1cDIoZmQsIFNURElOX0ZJTEVOTyk7CisgICAgY2xvc2UoZmQpOworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgLy8gUmVtb3ZlICdccicgY2hhcmFjdGVycyBmcm9tIHRleHQuCisgIHN0cmluZyBTdHJpcENSKGNvbnN0IHN0cmluZyYgdGV4dCkgeworICAgIHN0cmluZyByZXN1bHQ7CisKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHRleHQuc2l6ZSgpOyBpKyspIHsKKyAgICAgIGlmICh0ZXh0W2ldICE9ICdccicpIHsKKyAgICAgICAgcmVzdWx0LnB1c2hfYmFjayh0ZXh0W2ldKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICByZXR1cm4gcmVzdWx0OworICB9CisKKyAgZW51bSBUeXBlIHsgVEVYVCwgQklOQVJZIH07CisgIGVudW0gUmV0dXJuQ29kZSB7IFNVQ0NFU1MsIEVSUk9SIH07CisKKyAgYm9vbCBSdW4oY29uc3Qgc3RyaW5nJiBjb21tYW5kKSB7CisgICAgdmVjdG9yPHN0cmluZz4gYXJnczsKKyAgICBhcmdzLnB1c2hfYmFjaygicHJvdG9jIik7CisgICAgU3BsaXRTdHJpbmdVc2luZyhjb21tYW5kLCAiICIsICZhcmdzKTsKKyAgICBhcmdzLnB1c2hfYmFjaygiLS1wcm90b19wYXRoPSIgKyBUZXN0U291cmNlRGlyKCkpOworCisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX2FycmF5PGNvbnN0IGNoYXIgKiA+IGFyZ3YobmV3IGNvbnN0IGNoYXIqIFthcmdzLnNpemUoKV0pOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXJncy5zaXplKCk7IGkrKykgeworICAgICAgYXJndltpXSA9IGFyZ3NbaV0uY19zdHIoKTsKKyAgICB9CisKKyAgICBDb21tYW5kTGluZUludGVyZmFjZSBjbGk7CisgICAgY2xpLlNldElucHV0c0FyZVByb3RvUGF0aFJlbGF0aXZlKHRydWUpOworCisgICAgQ2FwdHVyZVRlc3RTdGRvdXQoKTsKKyAgICBDYXB0dXJlVGVzdFN0ZGVycigpOworCisgICAgaW50IHJlc3VsdCA9IGNsaS5SdW4oYXJncy5zaXplKCksIGFyZ3YuZ2V0KCkpOworCisgICAgY2FwdHVyZWRfc3Rkb3V0XyA9IEdldENhcHR1cmVkVGVzdFN0ZG91dCgpOworICAgIGNhcHR1cmVkX3N0ZGVycl8gPSBHZXRDYXB0dXJlZFRlc3RTdGRlcnIoKTsKKworICAgIHJldHVybiByZXN1bHQgPT0gMDsKKyAgfQorCisgIHZvaWQgRXhwZWN0U3Rkb3V0TWF0Y2hlc0JpbmFyeUZpbGUoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSkgeworICAgIHN0cmluZyBleHBlY3RlZF9vdXRwdXQ7CisgICAgR09PR0xFX0NIRUNLX09LKEZpbGU6OkdldENvbnRlbnRzKGZpbGVuYW1lLCAmZXhwZWN0ZWRfb3V0cHV0LCB0cnVlKSk7CisKKyAgICAvLyBEb24ndCB1c2UgRVhQRUNUX0VRIGJlY2F1c2Ugd2UgZG9uJ3Qgd2FudCB0byBwcmludCByYXcgYmluYXJ5IGRhdGEgdG8KKyAgICAvLyBzdGRvdXQgb24gZmFpbHVyZS4KKyAgICBFWFBFQ1RfVFJVRShjYXB0dXJlZF9zdGRvdXRfID09IGV4cGVjdGVkX291dHB1dCk7CisgIH0KKworICB2b2lkIEV4cGVjdFN0ZG91dE1hdGNoZXNUZXh0RmlsZShjb25zdCBzdHJpbmcmIGZpbGVuYW1lKSB7CisgICAgc3RyaW5nIGV4cGVjdGVkX291dHB1dDsKKyAgICBHT09HTEVfQ0hFQ0tfT0soRmlsZTo6R2V0Q29udGVudHMoZmlsZW5hbWUsICZleHBlY3RlZF9vdXRwdXQsIHRydWUpKTsKKworICAgIEV4cGVjdFN0ZG91dE1hdGNoZXNUZXh0KGV4cGVjdGVkX291dHB1dCk7CisgIH0KKworICB2b2lkIEV4cGVjdFN0ZG91dE1hdGNoZXNUZXh0KGNvbnN0IHN0cmluZyYgZXhwZWN0ZWRfdGV4dCkgeworICAgIEVYUEVDVF9FUShTdHJpcENSKGV4cGVjdGVkX3RleHQpLCBTdHJpcENSKGNhcHR1cmVkX3N0ZG91dF8pKTsKKyAgfQorCisgIHZvaWQgRXhwZWN0U3RkZXJyTWF0Y2hlc1RleHQoY29uc3Qgc3RyaW5nJiBleHBlY3RlZF90ZXh0KSB7CisgICAgRVhQRUNUX0VRKFN0cmlwQ1IoZXhwZWN0ZWRfdGV4dCksIFN0cmlwQ1IoY2FwdHVyZWRfc3RkZXJyXykpOworICB9CisKKyBwcml2YXRlOgorICBpbnQgZHVwZWRfc3RkaW5fOworICBzdHJpbmcgY2FwdHVyZWRfc3Rkb3V0XzsKKyAgc3RyaW5nIGNhcHR1cmVkX3N0ZGVycl87Cit9OworCitURVNUX0YoRW5jb2RlRGVjb2RlVGVzdCwgRW5jb2RlKSB7CisgIFJlZGlyZWN0U3RkaW5Gcm9tRmlsZShUZXN0U291cmNlRGlyKCkgKyAiL2dvb2dsZS9wcm90b2J1Zi8iCisgICAgInRlc3RkYXRhL3RleHRfZm9ybWF0X3VuaXR0ZXN0X2RhdGFfb25lb2ZfaW1wbGVtZW50ZWQudHh0Iik7CisgIEVYUEVDVF9UUlVFKFJ1bigiZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnByb3RvICIKKyAgICAgICAgICAgICAgICAgICItLWVuY29kZT1wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMiKSk7CisgIEV4cGVjdFN0ZG91dE1hdGNoZXNCaW5hcnlGaWxlKFRlc3RTb3VyY2VEaXIoKSArCisgICAgIi9nb29nbGUvcHJvdG9idWYvdGVzdGRhdGEvZ29sZGVuX21lc3NhZ2Vfb25lb2ZfaW1wbGVtZW50ZWQiKTsKKyAgRXhwZWN0U3RkZXJyTWF0Y2hlc1RleHQoIiIpOworfQorCitURVNUX0YoRW5jb2RlRGVjb2RlVGVzdCwgRGVjb2RlKSB7CisgIFJlZGlyZWN0U3RkaW5Gcm9tRmlsZShUZXN0U291cmNlRGlyKCkgKworICAgICIvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RkYXRhL2dvbGRlbl9tZXNzYWdlX29uZW9mX2ltcGxlbWVudGVkIik7CisgIEVYUEVDVF9UUlVFKFJ1bigiZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnByb3RvICIKKyAgICAgICAgICAgICAgICAgICItLWRlY29kZT1wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMiKSk7CisgIEV4cGVjdFN0ZG91dE1hdGNoZXNUZXh0RmlsZShUZXN0U291cmNlRGlyKCkgKworICAgICIvZ29vZ2xlL3Byb3RvYnVmLyIKKyAgICAidGVzdGRhdGEvdGV4dF9mb3JtYXRfdW5pdHRlc3RfZGF0YV9vbmVvZl9pbXBsZW1lbnRlZC50eHQiKTsKKyAgRXhwZWN0U3RkZXJyTWF0Y2hlc1RleHQoIiIpOworfQorCitURVNUX0YoRW5jb2RlRGVjb2RlVGVzdCwgUGFydGlhbCkgeworICBSZWRpcmVjdFN0ZGluRnJvbVRleHQoIiIpOworICBFWFBFQ1RfVFJVRShSdW4oImdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wcm90byAiCisgICAgICAgICAgICAgICAgICAiLS1lbmNvZGU9cHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIikpOworICBFeHBlY3RTdGRvdXRNYXRjaGVzVGV4dCgiIik7CisgIEV4cGVjdFN0ZGVyck1hdGNoZXNUZXh0KAorICAgICJ3YXJuaW5nOiAgSW5wdXQgbWVzc2FnZSBpcyBtaXNzaW5nIHJlcXVpcmVkIGZpZWxkczogIGEsIGIsIGNcbiIpOworfQorCitURVNUX0YoRW5jb2RlRGVjb2RlVGVzdCwgRGVjb2RlUmF3KSB7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKyAgbWVzc2FnZS5zZXRfb3B0aW9uYWxfaW50MzIoMTIzKTsKKyAgbWVzc2FnZS5zZXRfb3B0aW9uYWxfc3RyaW5nKCJmb28iKTsKKyAgc3RyaW5nIGRhdGE7CisgIG1lc3NhZ2UuU2VyaWFsaXplVG9TdHJpbmcoJmRhdGEpOworCisgIFJlZGlyZWN0U3RkaW5Gcm9tVGV4dChkYXRhKTsKKyAgRVhQRUNUX1RSVUUoUnVuKCItLWRlY29kZV9yYXciKSk7CisgIEV4cGVjdFN0ZG91dE1hdGNoZXNUZXh0KCIxOiAxMjNcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIjE0OiBcImZvb1wiXG4iKTsKKyAgRXhwZWN0U3RkZXJyTWF0Y2hlc1RleHQoIiIpOworfQorCitURVNUX0YoRW5jb2RlRGVjb2RlVGVzdCwgVW5rbm93blR5cGUpIHsKKyAgRVhQRUNUX0ZBTFNFKFJ1bigiZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnByb3RvICIKKyAgICAgICAgICAgICAgICAgICAiLS1lbmNvZGU9Tm9TdWNoVHlwZSIpKTsKKyAgRXhwZWN0U3Rkb3V0TWF0Y2hlc1RleHQoIiIpOworICBFeHBlY3RTdGRlcnJNYXRjaGVzVGV4dCgiVHlwZSBub3QgZGVmaW5lZDogTm9TdWNoVHlwZVxuIik7Cit9CisKK1RFU1RfRihFbmNvZGVEZWNvZGVUZXN0LCBQcm90b1BhcnNlRXJyb3IpIHsKKyAgRVhQRUNUX0ZBTFNFKFJ1bigiZ29vZ2xlL3Byb3RvYnVmL25vX3N1Y2hfZmlsZS5wcm90byAiCisgICAgICAgICAgICAgICAgICAgIi0tZW5jb2RlPU5vU3VjaFR5cGUiKSk7CisgIEV4cGVjdFN0ZG91dE1hdGNoZXNUZXh0KCIiKTsKKyAgRXhwZWN0U3RkZXJyTWF0Y2hlc1RleHQoCisgICAgImdvb2dsZS9wcm90b2J1Zi9ub19zdWNoX2ZpbGUucHJvdG86IEZpbGUgbm90IGZvdW5kLlxuIik7Cit9CisKK30gIC8vIGFub255bW91cyBuYW1lc3BhY2UKKworI2VuZGlmICAvLyAhR09PR0xFX1BST1RPQlVGX0hFQVBfQ0hFQ0tfRFJBQ09OSUFOCisKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfYm9vdHN0cmFwX3VuaXR0ZXN0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2Jvb3RzdHJhcF91bml0dGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jM2U5ZmU3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2Jvb3RzdHJhcF91bml0dGVzdC5jYwpAQCAtMCwwICsxLDE1OCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorLy8KKy8vIFRoaXMgdGVzdCBpbnN1cmVzIHRoYXQgZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIue2gsY2N9IG1hdGNoIGV4YWN0bHkKKy8vIHdoYXQgd291bGQgYmUgZ2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBjb21waWxlci4gIFRoZXNlIGZpbGVzIGFyZSBub3QKKy8vIGdlbmVyYXRlZCBhdXRvbWF0aWNhbGx5IGF0IGJ1aWxkIHRpbWUgYmVjYXVzZSB0aGV5IGFyZSBjb21waWxlZCBpbnRvIHRoZQorLy8gcHJvdG9jb2wgY29tcGlsZXIgaXRzZWxmLiAgU28sIGlmIHRoZXkgd2VyZSBhdXRvLWdlbmVyYXRlZCwgeW91J2QgaGF2ZSBhCisvLyBjaGlja2VuLWFuZC1lZ2cgcHJvYmxlbS4KKy8vCisvLyBJZiB0aGlzIHRlc3QgZmFpbHMsIHJ1biB0aGUgc2NyaXB0CisvLyAiZ2VuZXJhdGVfZGVzY3JpcHRvcl9wcm90by5zaCIgYW5kIGFkZAorLy8gZGVzY3JpcHRvci5wYi57aCxjY30gdG8geW91ciBjaGFuZ2VsaXN0LgorCisjaW5jbHVkZSA8bWFwPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZ2VuZXJhdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2ltcG9ydGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbV9pbXBsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL21hcF91dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0bF91dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3Vic3RpdHV0ZS5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZmlsZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2dvb2dsZXRlc3QuaD4KKyNpbmNsdWRlIDxndGVzdC9ndGVzdC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGNwcCB7CisKK25hbWVzcGFjZSB7CisKK2NsYXNzIE1vY2tFcnJvckNvbGxlY3RvciA6IHB1YmxpYyBNdWx0aUZpbGVFcnJvckNvbGxlY3RvciB7CisgcHVibGljOgorICBNb2NrRXJyb3JDb2xsZWN0b3IoKSB7fQorICB+TW9ja0Vycm9yQ29sbGVjdG9yKCkge30KKworICBzdHJpbmcgdGV4dF87CisKKyAgLy8gaW1wbGVtZW50cyBFcnJvckNvbGxlY3RvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgdm9pZCBBZGRFcnJvcihjb25zdCBzdHJpbmcmIGZpbGVuYW1lLCBpbnQgbGluZSwgaW50IGNvbHVtbiwKKyAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIG1lc3NhZ2UpIHsKKyAgICBzdHJpbmdzOjpTdWJzdGl0dXRlQW5kQXBwZW5kKCZ0ZXh0XywgIiQwOiQxOiQyOiAkM1xuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVuYW1lLCBsaW5lLCBjb2x1bW4sIG1lc3NhZ2UpOworICB9Cit9OworCitjbGFzcyBNb2NrR2VuZXJhdG9yQ29udGV4dCA6IHB1YmxpYyBHZW5lcmF0b3JDb250ZXh0IHsKKyBwdWJsaWM6CisgIE1vY2tHZW5lcmF0b3JDb250ZXh0KCkge30KKyAgfk1vY2tHZW5lcmF0b3JDb250ZXh0KCkgeworICAgIFNUTERlbGV0ZVZhbHVlcygmZmlsZXNfKTsKKyAgfQorCisgIHZvaWQgRXhwZWN0RmlsZU1hdGNoZXMoY29uc3Qgc3RyaW5nJiB2aXJ0dWFsX2ZpbGVuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgcGh5c2ljYWxfZmlsZW5hbWUpIHsKKyAgICBzdHJpbmcqIGV4cGVjdGVkX2NvbnRlbnRzID0gRmluZFB0ck9yTnVsbChmaWxlc18sIHZpcnR1YWxfZmlsZW5hbWUpOworICAgIEFTU0VSVF9UUlVFKGV4cGVjdGVkX2NvbnRlbnRzICE9IE5VTEwpCisgICAgICA8PCAiR2VuZXJhdG9yIGZhaWxlZCB0byBnZW5lcmF0ZSBmaWxlOiAiIDw8IHZpcnR1YWxfZmlsZW5hbWU7CisKKyAgICBzdHJpbmcgYWN0dWFsX2NvbnRlbnRzOworICAgIEdPT0dMRV9DSEVDS19PSygKKyAgICAgICAgRmlsZTo6R2V0Q29udGVudHMoVGVzdFNvdXJjZURpcigpICsgIi8iICsgcGh5c2ljYWxfZmlsZW5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICZhY3R1YWxfY29udGVudHMsIHRydWUpKTsKKyAgICBFWFBFQ1RfVFJVRShhY3R1YWxfY29udGVudHMgPT0gKmV4cGVjdGVkX2NvbnRlbnRzKQorICAgICAgPDwgcGh5c2ljYWxfZmlsZW5hbWUgPDwgIiBuZWVkcyB0byBiZSByZWdlbmVyYXRlZC4gIFBsZWFzZSBydW4gIgorICAgICAgICAgImdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9yZWxlYXNlX2NvbXBpbGVyLnNoIGFuZCAiCisgICAgICAgICAiZ2VuZXJhdGVfZGVzY3JpcHRvcl9wcm90by5zaC4gVGhlbiBhZGQgdGhpcyBmaWxlICIKKyAgICAgICAgICJ0byB5b3VyIENMLiI7CisgIH0KKworICAvLyBpbXBsZW1lbnRzIEdlbmVyYXRvckNvbnRleHQgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICB2aXJ0dWFsIGlvOjpaZXJvQ29weU91dHB1dFN0cmVhbSogT3Blbihjb25zdCBzdHJpbmcmIGZpbGVuYW1lKSB7CisgICAgc3RyaW5nKiogbWFwX3Nsb3QgPSAmZmlsZXNfW2ZpbGVuYW1lXTsKKyAgICBpZiAoKm1hcF9zbG90ICE9IE5VTEwpIGRlbGV0ZSAqbWFwX3Nsb3Q7CisgICAgKm1hcF9zbG90ID0gbmV3IHN0cmluZzsKKworICAgIHJldHVybiBuZXcgaW86OlN0cmluZ091dHB1dFN0cmVhbSgqbWFwX3Nsb3QpOworICB9CisKKyBwcml2YXRlOgorICBtYXA8c3RyaW5nLCBzdHJpbmcqPiBmaWxlc187Cit9OworCitURVNUKEJvb3RzdHJhcFRlc3QsIEdlbmVyYXRlZERlc2NyaXB0b3JNYXRjaGVzKSB7CisgIE1vY2tFcnJvckNvbGxlY3RvciBlcnJvcl9jb2xsZWN0b3I7CisgIERpc2tTb3VyY2VUcmVlIHNvdXJjZV90cmVlOworICBzb3VyY2VfdHJlZS5NYXBQYXRoKCIiLCBUZXN0U291cmNlRGlyKCkpOworICBJbXBvcnRlciBpbXBvcnRlcigmc291cmNlX3RyZWUsICZlcnJvcl9jb2xsZWN0b3IpOworICBjb25zdCBGaWxlRGVzY3JpcHRvciogcHJvdG9fZmlsZSA9CisgICAgaW1wb3J0ZXIuSW1wb3J0KCJnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90byIpOworICBjb25zdCBGaWxlRGVzY3JpcHRvciogcGx1Z2luX3Byb3RvX2ZpbGUgPQorICAgIGltcG9ydGVyLkltcG9ydCgiZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BsdWdpbi5wcm90byIpOworICBFWFBFQ1RfRVEoIiIsIGVycm9yX2NvbGxlY3Rvci50ZXh0Xyk7CisgIEFTU0VSVF9UUlVFKHByb3RvX2ZpbGUgIT0gTlVMTCk7CisgIEFTU0VSVF9UUlVFKHBsdWdpbl9wcm90b19maWxlICE9IE5VTEwpOworCisgIENwcEdlbmVyYXRvciBnZW5lcmF0b3I7CisgIE1vY2tHZW5lcmF0b3JDb250ZXh0IGNvbnRleHQ7CisgIHN0cmluZyBlcnJvcjsKKyAgc3RyaW5nIHBhcmFtZXRlciA9ICJkbGxleHBvcnRfZGVjbD1MSUJQUk9UT0JVRl9FWFBPUlQiOworICBBU1NFUlRfVFJVRShnZW5lcmF0b3IuR2VuZXJhdGUocHJvdG9fZmlsZSwgcGFyYW1ldGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmNvbnRleHQsICZlcnJvcikpOworICBwYXJhbWV0ZXIgPSAiZGxsZXhwb3J0X2RlY2w9TElCUFJPVE9DX0VYUE9SVCI7CisgIEFTU0VSVF9UUlVFKGdlbmVyYXRvci5HZW5lcmF0ZShwbHVnaW5fcHJvdG9fZmlsZSwgcGFyYW1ldGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmNvbnRleHQsICZlcnJvcikpOworCisgIGNvbnRleHQuRXhwZWN0RmlsZU1hdGNoZXMoImdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmgiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oIik7CisgIGNvbnRleHQuRXhwZWN0RmlsZU1hdGNoZXMoImdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmNjIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuY2MiKTsKKyAgY29udGV4dC5FeHBlY3RGaWxlTWF0Y2hlcygiZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BsdWdpbi5wYi5oIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BsdWdpbi5wYi5oIik7CisgIGNvbnRleHQuRXhwZWN0RmlsZU1hdGNoZXMoImdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wbHVnaW4ucGIuY2MiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLnBiLmNjIik7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCit9ICAvLyBuYW1lc3BhY2UgY3BwCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2VudW0uY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZW51bS5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xYTExYmNlCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2VudW0uY2MKQEAgLTAsMCArMSwzMDcgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2luY2x1ZGUgPG1hcD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2VudW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGNwcCB7CisKK25hbWVzcGFjZSB7CisvLyBUaGUgR09PR0xFX0FSUkFZU0laRSBjb25zdGFudCBpcyB0aGUgbWF4IGVudW0gdmFsdWUgcGx1cyAxLiBJZiB0aGUgbWF4IGVudW0gdmFsdWUKKy8vIGlzIDo6Z29vZ2xlOjpwcm90b2J1Zjo6a2ludDMybWF4LCBHT09HTEVfQVJSQVlTSVpFIHdpbGwgb3ZlcmZsb3cuIEluIHN1Y2ggY2FzZXMgd2Ugc2hvdWxkIG9taXQgdGhlCisvLyBnZW5lcmF0aW9uIG9mIHRoZSBHT09HTEVfQVJSQVlTSVpFIGNvbnN0YW50LgorYm9vbCBTaG91bGRHZW5lcmF0ZUFycmF5U2l6ZShjb25zdCBFbnVtRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBpbnQzMiBtYXhfdmFsdWUgPSBkZXNjcmlwdG9yLT52YWx1ZSgwKS0+bnVtYmVyKCk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvci0+dmFsdWVfY291bnQoKTsgaSsrKSB7CisgICAgaWYgKGRlc2NyaXB0b3ItPnZhbHVlKGkpLT5udW1iZXIoKSA+IG1heF92YWx1ZSkgeworICAgICAgbWF4X3ZhbHVlID0gZGVzY3JpcHRvci0+dmFsdWUoaSktPm51bWJlcigpOworICAgIH0KKyAgfQorICByZXR1cm4gbWF4X3ZhbHVlICE9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6a2ludDMybWF4OworfQorfSAgLy8gbmFtZXNwYWNlCisKK0VudW1HZW5lcmF0b3I6OkVudW1HZW5lcmF0b3IoY29uc3QgRW51bURlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE9wdGlvbnMmIG9wdGlvbnMpCisgIDogZGVzY3JpcHRvcl8oZGVzY3JpcHRvciksCisgICAgY2xhc3NuYW1lXyhDbGFzc05hbWUoZGVzY3JpcHRvciwgZmFsc2UpKSwKKyAgICBvcHRpb25zXyhvcHRpb25zKSwKKyAgICBnZW5lcmF0ZV9hcnJheV9zaXplXyhTaG91bGRHZW5lcmF0ZUFycmF5U2l6ZShkZXNjcmlwdG9yKSkgeworfQorCitFbnVtR2VuZXJhdG9yOjp+RW51bUdlbmVyYXRvcigpIHt9CisKK3ZvaWQgRW51bUdlbmVyYXRvcjo6RmlsbEZvcndhcmREZWNsYXJhdGlvbihzZXQ8c3RyaW5nPiogZW51bV9uYW1lcykgeworICBpZiAoIW9wdGlvbnNfLnByb3RvX2gpIHsKKyAgICByZXR1cm47CisgIH0KKyAgZW51bV9uYW1lcy0+aW5zZXJ0KGNsYXNzbmFtZV8pOworfQorCit2b2lkIEVudW1HZW5lcmF0b3I6OkdlbmVyYXRlRGVmaW5pdGlvbihpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcnM7CisgIHZhcnNbImNsYXNzbmFtZSJdID0gY2xhc3NuYW1lXzsKKyAgdmFyc1sic2hvcnRfbmFtZSJdID0gZGVzY3JpcHRvcl8tPm5hbWUoKTsKKyAgdmFyc1siZW51bWJhc2UiXSA9IGNsYXNzbmFtZV8gKyAob3B0aW9uc18ucHJvdG9faCA/ICIgOiBpbnQiIDogIiIpOworCisgIHByaW50ZXItPlByaW50KHZhcnMsICJlbnVtICRlbnVtYmFzZSQge1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIG1pbl92YWx1ZSA9IGRlc2NyaXB0b3JfLT52YWx1ZSgwKTsKKyAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogbWF4X3ZhbHVlID0gZGVzY3JpcHRvcl8tPnZhbHVlKDApOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPnZhbHVlX2NvdW50KCk7IGkrKykgeworICAgIHZhcnNbIm5hbWUiXSA9IEVudW1WYWx1ZU5hbWUoZGVzY3JpcHRvcl8tPnZhbHVlKGkpKTsKKyAgICAvLyBJbiBDKyssIGFuIHZhbHVlIG9mIC0yMTQ3NDgzNjQ4IGdldHMgaW50ZXJwcmV0ZWQgYXMgdGhlIG5lZ2F0aXZlIG9mCisgICAgLy8gMjE0NzQ4MzY0OCwgYW5kIHNpbmNlIDIxNDc0ODM2NDggY2FuJ3QgZml0IGluIGFuIGludGVnZXIsIHRoaXMgcHJvZHVjZXMgYQorICAgIC8vIGNvbXBpbGVyIHdhcm5pbmcuICBUaGlzIHdvcmtzIGFyb3VuZCB0aGF0IGlzc3VlLgorICAgIHZhcnNbIm51bWJlciJdID0gSW50MzJUb1N0cmluZyhkZXNjcmlwdG9yXy0+dmFsdWUoaSktPm51bWJlcigpKTsKKyAgICB2YXJzWyJwcmVmaXgiXSA9IChkZXNjcmlwdG9yXy0+Y29udGFpbmluZ190eXBlKCkgPT0gTlVMTCkgPworICAgICAgIiIgOiBjbGFzc25hbWVfICsgIl8iOworCisgICAgaWYgKGkgPiAwKSBwcmludGVyLT5QcmludCgiLFxuIik7CisgICAgcHJpbnRlci0+UHJpbnQodmFycywgIiRwcmVmaXgkJG5hbWUkID0gJG51bWJlciQiKTsKKworICAgIGlmIChkZXNjcmlwdG9yXy0+dmFsdWUoaSktPm51bWJlcigpIDwgbWluX3ZhbHVlLT5udW1iZXIoKSkgeworICAgICAgbWluX3ZhbHVlID0gZGVzY3JpcHRvcl8tPnZhbHVlKGkpOworICAgIH0KKyAgICBpZiAoZGVzY3JpcHRvcl8tPnZhbHVlKGkpLT5udW1iZXIoKSA+IG1heF92YWx1ZS0+bnVtYmVyKCkpIHsKKyAgICAgIG1heF92YWx1ZSA9IGRlc2NyaXB0b3JfLT52YWx1ZShpKTsKKyAgICB9CisgIH0KKworICBpZiAoSGFzUHJlc2VydmluZ1Vua25vd25FbnVtU2VtYW50aWNzKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgLy8gRm9yIG5ldyBlbnVtIHNlbWFudGljczogZ2VuZXJhdGUgbWluIGFuZCBtYXggc2VudGluZWwgdmFsdWVzIGVxdWFsIHRvCisgICAgLy8gSU5UMzJfTUlOIGFuZCBJTlQzMl9NQVgKKyAgICBpZiAoZGVzY3JpcHRvcl8tPnZhbHVlX2NvdW50KCkgPiAwKSBwcmludGVyLT5QcmludCgiLFxuIik7CisgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICAgIiRjbGFzc25hbWUkXyRwcmVmaXgkSU5UX01JTl9TRU5USU5FTF9ET19OT1RfVVNFXyA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6a2ludDMybWluLFxuIgorICAgICAgICAiJGNsYXNzbmFtZSRfJHByZWZpeCRJTlRfTUFYX1NFTlRJTkVMX0RPX05PVF9VU0VfID0gOjpnb29nbGU6OnByb3RvYnVmOjpraW50MzJtYXgiKTsKKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoIlxufTtcbiIpOworCisgIHZhcnNbIm1pbl9uYW1lIl0gPSBFbnVtVmFsdWVOYW1lKG1pbl92YWx1ZSk7CisgIHZhcnNbIm1heF9uYW1lIl0gPSBFbnVtVmFsdWVOYW1lKG1heF92YWx1ZSk7CisKKyAgaWYgKG9wdGlvbnNfLmRsbGV4cG9ydF9kZWNsLmVtcHR5KCkpIHsKKyAgICB2YXJzWyJkbGxleHBvcnQiXSA9ICIiOworICB9IGVsc2UgeworICAgIHZhcnNbImRsbGV4cG9ydCJdID0gb3B0aW9uc18uZGxsZXhwb3J0X2RlY2wgKyAiICI7CisgIH0KKworICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICIkZGxsZXhwb3J0JGJvb2wgJGNsYXNzbmFtZSRfSXNWYWxpZChpbnQgdmFsdWUpO1xuIgorICAgICJjb25zdCAkY2xhc3NuYW1lJCAkcHJlZml4JCRzaG9ydF9uYW1lJF9NSU4gPSAkcHJlZml4JCRtaW5fbmFtZSQ7XG4iCisgICAgImNvbnN0ICRjbGFzc25hbWUkICRwcmVmaXgkJHNob3J0X25hbWUkX01BWCA9ICRwcmVmaXgkJG1heF9uYW1lJDtcbiIpOworCisgIGlmIChnZW5lcmF0ZV9hcnJheV9zaXplXykgeworICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAiY29uc3QgaW50ICRwcmVmaXgkJHNob3J0X25hbWUkX0FSUkFZU0laRSA9ICIKKyAgICAgICIkcHJlZml4JCRzaG9ydF9uYW1lJF9NQVggKyAxO1xuXG4iKTsKKyAgfQorCisgIGlmIChIYXNEZXNjcmlwdG9yTWV0aG9kcyhkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAiJGRsbGV4cG9ydCRjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yKiAkY2xhc3NuYW1lJF9kZXNjcmlwdG9yKCk7XG4iKTsKKyAgICAvLyBUaGUgX05hbWUgYW5kIF9QYXJzZSBtZXRob2RzCisgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICJpbmxpbmUgY29uc3QgOjpzdGQ6OnN0cmluZyYgJGNsYXNzbmFtZSRfTmFtZSgkY2xhc3NuYW1lJCB2YWx1ZSkge1xuIgorICAgICAgIiAgcmV0dXJuIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6Ok5hbWVPZkVudW0oXG4iCisgICAgICAiICAgICRjbGFzc25hbWUkX2Rlc2NyaXB0b3IoKSwgdmFsdWUpO1xuIgorICAgICAgIn1cbiIpOworICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAiaW5saW5lIGJvb2wgJGNsYXNzbmFtZSRfUGFyc2UoXG4iCisgICAgICAiICAgIGNvbnN0IDo6c3RkOjpzdHJpbmcmIG5hbWUsICRjbGFzc25hbWUkKiB2YWx1ZSkge1xuIgorICAgICAgIiAgcmV0dXJuIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlBhcnNlTmFtZWRFbnVtPCRjbGFzc25hbWUkPihcbiIKKyAgICAgICIgICAgJGNsYXNzbmFtZSRfZGVzY3JpcHRvcigpLCBuYW1lLCB2YWx1ZSk7XG4iCisgICAgICAifVxuIik7CisgIH0KK30KKwordm9pZCBFbnVtR2VuZXJhdG9yOjoKK0dlbmVyYXRlR2V0RW51bURlc2NyaXB0b3JTcGVjaWFsaXphdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICAidGVtcGxhdGUgPD4gc3RydWN0IGlzX3Byb3RvX2VudW08ICRjbGFzc25hbWUkPiA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OnRydWVfdHlwZSAiCisgICAgICAie307XG4iLAorICAgICAgImNsYXNzbmFtZSIsIENsYXNzTmFtZShkZXNjcmlwdG9yXywgdHJ1ZSkpOworICBpZiAoSGFzRGVzY3JpcHRvck1ldGhvZHMoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJ0ZW1wbGF0ZSA8PlxuIgorICAgICAgImlubGluZSBjb25zdCBFbnVtRGVzY3JpcHRvciogR2V0RW51bURlc2NyaXB0b3I8ICRjbGFzc25hbWUkPigpIHtcbiIKKyAgICAgICIgIHJldHVybiAkY2xhc3NuYW1lJF9kZXNjcmlwdG9yKCk7XG4iCisgICAgICAifVxuIiwKKyAgICAgICJjbGFzc25hbWUiLCBDbGFzc05hbWUoZGVzY3JpcHRvcl8sIHRydWUpKTsKKyAgfQorfQorCit2b2lkIEVudW1HZW5lcmF0b3I6OkdlbmVyYXRlU3ltYm9sSW1wb3J0cyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcnM7CisgIHZhcnNbIm5lc3RlZF9uYW1lIl0gPSBkZXNjcmlwdG9yXy0+bmFtZSgpOworICB2YXJzWyJjbGFzc25hbWUiXSA9IGNsYXNzbmFtZV87CisgIHByaW50ZXItPlByaW50KHZhcnMsICJ0eXBlZGVmICRjbGFzc25hbWUkICRuZXN0ZWRfbmFtZSQ7XG4iKTsKKworICBmb3IgKGludCBqID0gMDsgaiA8IGRlc2NyaXB0b3JfLT52YWx1ZV9jb3VudCgpOyBqKyspIHsKKyAgICB2YXJzWyJ0YWciXSA9IEVudW1WYWx1ZU5hbWUoZGVzY3JpcHRvcl8tPnZhbHVlKGopKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgInN0YXRpYyBjb25zdCAkbmVzdGVkX25hbWUkICR0YWckID0gJGNsYXNzbmFtZSRfJHRhZyQ7XG4iKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgInN0YXRpYyBpbmxpbmUgYm9vbCAkbmVzdGVkX25hbWUkX0lzVmFsaWQoaW50IHZhbHVlKSB7XG4iCisgICAgIiAgcmV0dXJuICRjbGFzc25hbWUkX0lzVmFsaWQodmFsdWUpO1xuIgorICAgICJ9XG4iCisgICAgInN0YXRpYyBjb25zdCAkbmVzdGVkX25hbWUkICRuZXN0ZWRfbmFtZSRfTUlOID1cbiIKKyAgICAiICAkY2xhc3NuYW1lJF8kbmVzdGVkX25hbWUkX01JTjtcbiIKKyAgICAic3RhdGljIGNvbnN0ICRuZXN0ZWRfbmFtZSQgJG5lc3RlZF9uYW1lJF9NQVggPVxuIgorICAgICIgICRjbGFzc25hbWUkXyRuZXN0ZWRfbmFtZSRfTUFYO1xuIik7CisgIGlmIChnZW5lcmF0ZV9hcnJheV9zaXplXykgeworICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAic3RhdGljIGNvbnN0IGludCAkbmVzdGVkX25hbWUkX0FSUkFZU0laRSA9XG4iCisgICAgICAiICAkY2xhc3NuYW1lJF8kbmVzdGVkX25hbWUkX0FSUkFZU0laRTtcbiIpOworICB9CisKKyAgaWYgKEhhc0Rlc2NyaXB0b3JNZXRob2RzKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICJzdGF0aWMgaW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bURlc2NyaXB0b3IqXG4iCisgICAgICAiJG5lc3RlZF9uYW1lJF9kZXNjcmlwdG9yKCkge1xuIgorICAgICAgIiAgcmV0dXJuICRjbGFzc25hbWUkX2Rlc2NyaXB0b3IoKTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgInN0YXRpYyBpbmxpbmUgY29uc3QgOjpzdGQ6OnN0cmluZyYgJG5lc3RlZF9uYW1lJF9OYW1lKCRuZXN0ZWRfbmFtZSQgdmFsdWUpIHtcbiIKKyAgICAgICIgIHJldHVybiAkY2xhc3NuYW1lJF9OYW1lKHZhbHVlKTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgInN0YXRpYyBpbmxpbmUgYm9vbCAkbmVzdGVkX25hbWUkX1BhcnNlKGNvbnN0IDo6c3RkOjpzdHJpbmcmIG5hbWUsXG4iCisgICAgICAiICAgICRuZXN0ZWRfbmFtZSQqIHZhbHVlKSB7XG4iCisgICAgICAiICByZXR1cm4gJGNsYXNzbmFtZSRfUGFyc2UobmFtZSwgdmFsdWUpO1xuIgorICAgICAgIn1cbiIpOworICB9Cit9CisKK3ZvaWQgRW51bUdlbmVyYXRvcjo6R2VuZXJhdGVEZXNjcmlwdG9ySW5pdGlhbGl6ZXIoCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIsIGludCBpbmRleCkgeworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcnM7CisgIHZhcnNbImNsYXNzbmFtZSJdID0gY2xhc3NuYW1lXzsKKyAgdmFyc1siaW5kZXgiXSA9IFNpbXBsZUl0b2EoaW5kZXgpOworCisgIGlmIChkZXNjcmlwdG9yXy0+Y29udGFpbmluZ190eXBlKCkgPT0gTlVMTCkgeworICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAiJGNsYXNzbmFtZSRfZGVzY3JpcHRvcl8gPSBmaWxlLT5lbnVtX3R5cGUoJGluZGV4JCk7XG4iKTsKKyAgfSBlbHNlIHsKKyAgICB2YXJzWyJwYXJlbnQiXSA9IENsYXNzTmFtZShkZXNjcmlwdG9yXy0+Y29udGFpbmluZ190eXBlKCksIGZhbHNlKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgIiRjbGFzc25hbWUkX2Rlc2NyaXB0b3JfID0gJHBhcmVudCRfZGVzY3JpcHRvcl8tPmVudW1fdHlwZSgkaW5kZXgkKTtcbiIpOworICB9Cit9CisKK3ZvaWQgRW51bUdlbmVyYXRvcjo6R2VuZXJhdGVNZXRob2RzKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyczsKKyAgdmFyc1siY2xhc3NuYW1lIl0gPSBjbGFzc25hbWVfOworCisgIGlmIChIYXNEZXNjcmlwdG9yTWV0aG9kcyhkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAiY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvciogJGNsYXNzbmFtZSRfZGVzY3JpcHRvcigpIHtcbiIKKyAgICAgICIgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpO1xuIgorICAgICAgIiAgcmV0dXJuICRjbGFzc25hbWUkX2Rlc2NyaXB0b3JfO1xuIgorICAgICAgIn1cbiIpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAiYm9vbCAkY2xhc3NuYW1lJF9Jc1ZhbGlkKGludCB2YWx1ZSkge1xuIgorICAgICIgIHN3aXRjaCh2YWx1ZSkge1xuIik7CisKKyAgLy8gTXVsdGlwbGUgdmFsdWVzIG1heSBoYXZlIHRoZSBzYW1lIG51bWJlci4gIE1ha2Ugc3VyZSB3ZSBvbmx5IGNvdmVyCisgIC8vIGVhY2ggbnVtYmVyIG9uY2UgYnkgZmlyc3QgY29uc3RydWN0aW5nIGEgc2V0IGNvbnRhaW5pbmcgYWxsIHZhbGlkCisgIC8vIG51bWJlcnMsIHRoZW4gcHJpbnRpbmcgYSBjYXNlIHN0YXRlbWVudCBmb3IgZWFjaCBlbGVtZW50LgorCisgIHNldDxpbnQ+IG51bWJlcnM7CisgIGZvciAoaW50IGogPSAwOyBqIDwgZGVzY3JpcHRvcl8tPnZhbHVlX2NvdW50KCk7IGorKykgeworICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIHZhbHVlID0gZGVzY3JpcHRvcl8tPnZhbHVlKGopOworICAgIG51bWJlcnMuaW5zZXJ0KHZhbHVlLT5udW1iZXIoKSk7CisgIH0KKworICBmb3IgKHNldDxpbnQ+OjppdGVyYXRvciBpdGVyID0gbnVtYmVycy5iZWdpbigpOworICAgICAgIGl0ZXIgIT0gbnVtYmVycy5lbmQoKTsgKytpdGVyKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiICAgIGNhc2UgJG51bWJlciQ6XG4iLAorICAgICAgIm51bWJlciIsIEludDMyVG9TdHJpbmcoKml0ZXIpKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgIiAgICAgIHJldHVybiB0cnVlO1xuIgorICAgICIgICAgZGVmYXVsdDpcbiIKKyAgICAiICAgICAgcmV0dXJuIGZhbHNlO1xuIgorICAgICIgIH1cbiIKKyAgICAifVxuIgorICAgICJcbiIpOworCisgIGlmIChkZXNjcmlwdG9yXy0+Y29udGFpbmluZ190eXBlKCkgIT0gTlVMTCkgeworICAgIC8vIFdlIG5lZWQgdG8gImRlZmluZSIgdGhlIHN0YXRpYyBjb25zdGFudHMgd2hpY2ggd2VyZSBkZWNsYXJlZCBpbiB0aGUKKyAgICAvLyBoZWFkZXIsIHRvIGdpdmUgdGhlIGxpbmtlciBhIHBsYWNlIHRvIHB1dCB0aGVtLiAgT3IgYXQgbGVhc3QgdGhlIEMrKworICAgIC8vIHN0YW5kYXJkIHNheXMgd2UgaGF2ZSB0by4gIE1TVkMgYWN0dWFsbHkgaW5zaXN0cyB0aGF0IHdlIGRvIF9ub3RfIGRlZmluZQorICAgIC8vIHRoZW0gYWdhaW4gaW4gdGhlIC5jYyBmaWxlLCBwcmlvciB0byBWQysrIDIwMTUuCisgICAgcHJpbnRlci0+UHJpbnQoIiNpZiAhZGVmaW5lZChfTVNDX1ZFUikgfHwgX01TQ19WRVIgPj0gMTkwMFxuIik7CisKKyAgICB2YXJzWyJwYXJlbnQiXSA9IENsYXNzTmFtZShkZXNjcmlwdG9yXy0+Y29udGFpbmluZ190eXBlKCksIGZhbHNlKTsKKyAgICB2YXJzWyJuZXN0ZWRfbmFtZSJdID0gZGVzY3JpcHRvcl8tPm5hbWUoKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT52YWx1ZV9jb3VudCgpOyBpKyspIHsKKyAgICAgIHZhcnNbInZhbHVlIl0gPSBFbnVtVmFsdWVOYW1lKGRlc2NyaXB0b3JfLT52YWx1ZShpKSk7CisgICAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgICAiY29uc3QgJGNsYXNzbmFtZSQgJHBhcmVudCQ6OiR2YWx1ZSQ7XG4iKTsKKyAgICB9CisgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICJjb25zdCAkY2xhc3NuYW1lJCAkcGFyZW50JDo6JG5lc3RlZF9uYW1lJF9NSU47XG4iCisgICAgICAiY29uc3QgJGNsYXNzbmFtZSQgJHBhcmVudCQ6OiRuZXN0ZWRfbmFtZSRfTUFYO1xuIik7CisgICAgaWYgKGdlbmVyYXRlX2FycmF5X3NpemVfKSB7CisgICAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgICAiY29uc3QgaW50ICRwYXJlbnQkOjokbmVzdGVkX25hbWUkX0FSUkFZU0laRTtcbiIpOworICAgIH0KKworICAgIHByaW50ZXItPlByaW50KCIjZW5kaWYgIC8vICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwXG4iKTsKKyAgfQorfQorCit9ICAvLyBuYW1lc3BhY2UgY3BwCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2VudW0uaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9lbnVtLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjNhYTcyZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9lbnVtLmgKQEAgLTAsMCArMSwxMTAgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1BQX0VOVU1fSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DUFBfRU5VTV9IX18KKworI2luY2x1ZGUgPHNldD4KKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfb3B0aW9ucy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworICBuYW1lc3BhY2UgaW8geworICAgIGNsYXNzIFByaW50ZXI7ICAgICAgICAgICAgIC8vIHByaW50ZXIuaAorICB9Cit9CisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGNwcCB7CisKK2NsYXNzIEVudW1HZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgLy8gU2VlIGdlbmVyYXRvci5jYyBmb3IgdGhlIG1lYW5pbmcgb2YgZGxsZXhwb3J0X2RlY2wuCisgIGV4cGxpY2l0IEVudW1HZW5lcmF0b3IoY29uc3QgRW51bURlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT3B0aW9ucyYgb3B0aW9ucyk7CisgIH5FbnVtR2VuZXJhdG9yKCk7CisKKyAgLy8gSGVhZGVyIHN0dWZmLgorCisgIC8vIEZpbGxzIHRoZSBuYW1lIHRvIHVzZSB3aGVuIGRlY2xhcmluZyB0aGUgZW51bS4gVGhpcyBpcyBmb3IgdXNlIHdoZW4KKyAgLy8gZ2VuZXJhdGluZyBvdGhlciAucHJvdG8uaCBmaWxlcy4gVGhpcyBjb2RlIHNob3VsZCBiZSBwbGFjZWQgd2l0aGluIHRoZQorICAvLyBlbnVtJ3MgcGFja2FnZSBuYW1lc3BhY2UsIGJ1dCBOT1Qgd2l0aGluIGFueSBjbGFzcywgZXZlbiBmb3IgbmVzdGVkCisgIC8vIGVudW1zLgorICB2b2lkIEZpbGxGb3J3YXJkRGVjbGFyYXRpb24oc2V0PHN0cmluZz4qIGVudW1fbmFtZXMpOworCisgIC8vIEdlbmVyYXRlIGhlYWRlciBjb2RlIGRlZmluaW5nIHRoZSBlbnVtLiAgVGhpcyBjb2RlIHNob3VsZCBiZSBwbGFjZWQKKyAgLy8gd2l0aGluIHRoZSBlbnVtJ3MgcGFja2FnZSBuYW1lc3BhY2UsIGJ1dCBOT1Qgd2l0aGluIGFueSBjbGFzcywgZXZlbiBmb3IKKyAgLy8gbmVzdGVkIGVudW1zLgorICB2b2lkIEdlbmVyYXRlRGVmaW5pdGlvbihpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyAgLy8gR2VuZXJhdGUgc3BlY2lhbGl6YXRpb24gb2YgR2V0RW51bURlc2NyaXB0b3I8TXlFbnVtPigpLgorICAvLyBQcmVjb25kaXRpb246IGluIDo6Z29vZ2xlOjpwcm90b2J1ZiBuYW1lc3BhY2UuCisgIHZvaWQgR2VuZXJhdGVHZXRFbnVtRGVzY3JpcHRvclNwZWNpYWxpemF0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyAgLy8gRm9yIGVudW1zIG5lc3RlZCB3aXRoaW4gYSBtZXNzYWdlLCBnZW5lcmF0ZSBjb2RlIHRvIGltcG9ydCBhbGwgdGhlIGVudW0ncworICAvLyBzeW1ib2xzIChlLmcuIHRoZSBlbnVtIHR5cGUgbmFtZSwgYWxsIGl0cyB2YWx1ZXMsIGV0Yy4pIGludG8gdGhlIGNsYXNzJ3MKKyAgLy8gbmFtZXNwYWNlLiAgVGhpcyBzaG91bGQgYmUgcGxhY2VkIGluc2lkZSB0aGUgY2xhc3MgZGVmaW5pdGlvbiBpbiB0aGUKKyAgLy8gaGVhZGVyLgorICB2b2lkIEdlbmVyYXRlU3ltYm9sSW1wb3J0cyhpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyAgLy8gU291cmNlIGZpbGUgc3R1ZmYuCisKKyAgLy8gR2VuZXJhdGUgY29kZSB0aGF0IGluaXRpYWxpemVzIHRoZSBnbG9iYWwgdmFyaWFibGUgc3RvcmluZyB0aGUgZW51bSdzCisgIC8vIGRlc2NyaXB0b3IuCisgIHZvaWQgR2VuZXJhdGVEZXNjcmlwdG9ySW5pdGlhbGl6ZXIoaW86OlByaW50ZXIqIHByaW50ZXIsIGludCBpbmRleCk7CisKKyAgLy8gR2VuZXJhdGUgbm9uLWlubGluZSBtZXRob2RzIHJlbGF0ZWQgdG8gdGhlIGVudW0sIHN1Y2ggYXMgSXNWYWxpZFZhbHVlKCkuCisgIC8vIEdvZXMgaW4gdGhlIC5jYyBmaWxlLgorICB2b2lkIEdlbmVyYXRlTWV0aG9kcyhpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyBwcml2YXRlOgorICBjb25zdCBFbnVtRGVzY3JpcHRvciogZGVzY3JpcHRvcl87CisgIHN0cmluZyBjbGFzc25hbWVfOworICBPcHRpb25zIG9wdGlvbnNfOworICAvLyB3aGV0aGVyIHRvIGdlbmVyYXRlIHRoZSAqX0FSUkFZU0laRSBjb25zdGFudC4KKyAgYm9vbCBnZW5lcmF0ZV9hcnJheV9zaXplXzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoRW51bUdlbmVyYXRvcik7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgY3BwCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DUFBfRU5VTV9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9lbnVtX2ZpZWxkLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2VudW1fZmllbGQuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODI0ZTIyMAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9lbnVtX2ZpZWxkLmNjCkBAIC0wLDAgKzEsNTA3IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9lbnVtX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfaGVscGVycy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBjcHAgeworCituYW1lc3BhY2UgeworCit2b2lkIFNldEVudW1WYXJpYWJsZXMoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgIG1hcDxzdHJpbmcsIHN0cmluZz4qIHZhcmlhYmxlcywKKyAgICAgICAgICAgICAgICAgICAgICBjb25zdCBPcHRpb25zJiBvcHRpb25zKSB7CisgIFNldENvbW1vbkZpZWxkVmFyaWFibGVzKGRlc2NyaXB0b3IsIHZhcmlhYmxlcywgb3B0aW9ucyk7CisgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIGRlZmF1bHRfdmFsdWUgPSBkZXNjcmlwdG9yLT5kZWZhdWx0X3ZhbHVlX2VudW0oKTsKKyAgKCp2YXJpYWJsZXMpWyJ0eXBlIl0gPSBDbGFzc05hbWUoZGVzY3JpcHRvci0+ZW51bV90eXBlKCksIHRydWUpOworICAoKnZhcmlhYmxlcylbImRlZmF1bHQiXSA9IEludDMyVG9TdHJpbmcoZGVmYXVsdF92YWx1ZS0+bnVtYmVyKCkpOworICAoKnZhcmlhYmxlcylbImZ1bGxfbmFtZSJdID0gZGVzY3JpcHRvci0+ZnVsbF9uYW1lKCk7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK0VudW1GaWVsZEdlbmVyYXRvcjo6CitFbnVtRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgIGNvbnN0IE9wdGlvbnMmIG9wdGlvbnMpCisgIDogZGVzY3JpcHRvcl8oZGVzY3JpcHRvcikgeworICBTZXRFbnVtVmFyaWFibGVzKGRlc2NyaXB0b3IsICZ2YXJpYWJsZXNfLCBvcHRpb25zKTsKK30KKworRW51bUZpZWxkR2VuZXJhdG9yOjp+RW51bUZpZWxkR2VuZXJhdG9yKCkge30KKwordm9pZCBFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVQcml2YXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAiaW50ICRuYW1lJF87XG4iKTsKK30KKwordm9pZCBFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVBY2Nlc3NvckRlY2xhcmF0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkdHlwZSQgJG5hbWUkKCkgY29uc3QkZGVwcmVjYXRpb24kO1xuIgorICAgICJ2b2lkIHNldF8kbmFtZSQoJHR5cGUkIHZhbHVlKSRkZXByZWNhdGlvbiQ7XG4iKTsKK30KKwordm9pZCBFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVJbmxpbmVBY2Nlc3NvckRlZmluaXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaXNfaW5saW5lKSBjb25zdCB7CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyaWFibGVzKHZhcmlhYmxlc18pOworICB2YXJpYWJsZXNbImlubGluZSJdID0gaXNfaW5saW5lID8gImlubGluZSIgOiAiIjsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICIkaW5saW5lJCAkdHlwZSQgJGNsYXNzbmFtZSQ6OiRuYW1lJCgpIGNvbnN0IHtcbiIKKyAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0OiRmdWxsX25hbWUkKVxuIgorICAgICIgIHJldHVybiBzdGF0aWNfY2FzdDwgJHR5cGUkID4oJG5hbWUkXyk7XG4iCisgICAgIn1cbiIKKyAgICAiJGlubGluZSQgdm9pZCAkY2xhc3NuYW1lJDo6c2V0XyRuYW1lJCgkdHlwZSQgdmFsdWUpIHtcbiIpOworICBpZiAoIUhhc1ByZXNlcnZpbmdVbmtub3duRW51bVNlbWFudGljcyhkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAiICBhc3NlcnQoJHR5cGUkX0lzVmFsaWQodmFsdWUpKTtcbiIpOworICB9CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAiICAkc2V0X2hhc2JpdCRcbiIKKyAgICAiICAkbmFtZSRfID0gdmFsdWU7XG4iCisgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDokZnVsbF9uYW1lJClcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQ2xlYXJpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sICIkbmFtZSRfID0gJGRlZmF1bHQkO1xuIik7Cit9CisKK3ZvaWQgRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgInNldF8kbmFtZSQoZnJvbS4kbmFtZSQoKSk7XG4iKTsKK30KKwordm9pZCBFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTd2FwcGluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgInN0ZDo6c3dhcCgkbmFtZSRfLCBvdGhlci0+JG5hbWUkXyk7XG4iKTsKK30KKwordm9pZCBFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVDb25zdHJ1Y3RvckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgIiRuYW1lJF8gPSAkZGVmYXVsdCQ7XG4iKTsKK30KKwordm9pZCBFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZXJnZUZyb21Db2RlZFN0cmVhbShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpbnQgdmFsdWU7XG4iCisgICAgIkRPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8XG4iCisgICAgIiAgICAgICAgIGludCwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfRU5VTT4oXG4iCisgICAgIiAgICAgICBpbnB1dCwgJnZhbHVlKSkpO1xuIik7CisgIGlmIChIYXNQcmVzZXJ2aW5nVW5rbm93bkVudW1TZW1hbnRpY3MoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgInNldF8kbmFtZSQoc3RhdGljX2Nhc3Q8ICR0eXBlJCA+KHZhbHVlKSk7XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImlmICgkdHlwZSRfSXNWYWxpZCh2YWx1ZSkpIHtcbiIKKyAgICAgICIgIHNldF8kbmFtZSQoc3RhdGljX2Nhc3Q8ICR0eXBlJCA+KHZhbHVlKSk7XG4iKTsKKyAgICBpZiAoVXNlVW5rbm93bkZpZWxkU2V0KGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAifSBlbHNlIHtcbiIKKyAgICAgICAgIiAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5BZGRWYXJpbnQoJG51bWJlciQsIHZhbHVlKTtcbiIpOworICAgIH0gZWxzZSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIn0gZWxzZSB7XG4iCisgICAgICAgICIgIHVua25vd25fZmllbGRzX3N0cmVhbS5Xcml0ZVZhcmludDMyKHRhZyk7XG4iCisgICAgICAgICIgIHVua25vd25fZmllbGRzX3N0cmVhbS5Xcml0ZVZhcmludDMyKHZhbHVlKTtcbiIpOworICAgIH0KKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIn1cbiIpOworICB9Cit9CisKK3ZvaWQgRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUVudW0oXG4iCisgICAgIiAgJG51bWJlciQsIHRoaXMtPiRuYW1lJCgpLCBvdXRwdXQpO1xuIik7Cit9CisKK3ZvaWQgRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJ0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVFbnVtVG9BcnJheShcbiIKKyAgICAiICAkbnVtYmVyJCwgdGhpcy0+JG5hbWUkKCksIHRhcmdldCk7XG4iKTsKK30KKwordm9pZCBFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVCeXRlU2l6ZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJ0b3RhbF9zaXplICs9ICR0YWdfc2l6ZSQgK1xuIgorICAgICIgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpFbnVtU2l6ZSh0aGlzLT4kbmFtZSQoKSk7XG4iKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitFbnVtT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitFbnVtT25lb2ZGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBPcHRpb25zJiBvcHRpb25zKQorICA6IEVudW1GaWVsZEdlbmVyYXRvcihkZXNjcmlwdG9yLCBvcHRpb25zKSB7CisgIFNldENvbW1vbk9uZW9mRmllbGRWYXJpYWJsZXMoZGVzY3JpcHRvciwgJnZhcmlhYmxlc18pOworfQorCitFbnVtT25lb2ZGaWVsZEdlbmVyYXRvcjo6fkVudW1PbmVvZkZpZWxkR2VuZXJhdG9yKCkge30KKwordm9pZCBFbnVtT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUlubGluZUFjY2Vzc29yRGVmaW5pdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc19pbmxpbmUpIGNvbnN0IHsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXModmFyaWFibGVzXyk7CisgIHZhcmlhYmxlc1siaW5saW5lIl0gPSBpc19pbmxpbmUgPyAiaW5saW5lIiA6ICIiOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXMsCisgICAgIiRpbmxpbmUkICR0eXBlJCAkY2xhc3NuYW1lJDo6JG5hbWUkKCkgY29uc3Qge1xuIgorICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6JGZ1bGxfbmFtZSQpXG4iCisgICAgIiAgaWYgKGhhc18kbmFtZSQoKSkge1xuIgorICAgICIgICAgcmV0dXJuIHN0YXRpY19jYXN0PCAkdHlwZSQgPigkb25lb2ZfcHJlZml4JCRuYW1lJF8pO1xuIgorICAgICIgIH1cbiIKKyAgICAiICByZXR1cm4gc3RhdGljX2Nhc3Q8ICR0eXBlJCA+KCRkZWZhdWx0JCk7XG4iCisgICAgIn1cbiIKKyAgICAiJGlubGluZSQgdm9pZCAkY2xhc3NuYW1lJDo6c2V0XyRuYW1lJCgkdHlwZSQgdmFsdWUpIHtcbiIpOworICBpZiAoIUhhc1ByZXNlcnZpbmdVbmtub3duRW51bVNlbWFudGljcyhkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAiICBhc3NlcnQoJHR5cGUkX0lzVmFsaWQodmFsdWUpKTtcbiIpOworICB9CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAiICBpZiAoIWhhc18kbmFtZSQoKSkge1xuIgorICAgICIgICAgY2xlYXJfJG9uZW9mX25hbWUkKCk7XG4iCisgICAgIiAgICBzZXRfaGFzXyRuYW1lJCgpO1xuIgorICAgICIgIH1cbiIKKyAgICAiICAkb25lb2ZfcHJlZml4JCRuYW1lJF8gPSB2YWx1ZTtcbiIKKyAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0OiRmdWxsX25hbWUkKVxuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBFbnVtT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUNsZWFyaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAiJG9uZW9mX3ByZWZpeCQkbmFtZSRfID0gJGRlZmF1bHQkO1xuIik7Cit9CisKK3ZvaWQgRW51bU9uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTd2FwcGluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gRG9uJ3QgcHJpbnQgYW55IHN3YXBwaW5nIGNvZGUuIFN3YXBwaW5nIHRoZSB1bmlvbiB3aWxsIHN3YXAgdGhpcyBmaWVsZC4KK30KKwordm9pZCBFbnVtT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUNvbnN0cnVjdG9yQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIgICRjbGFzc25hbWUkX2RlZmF1bHRfb25lb2ZfaW5zdGFuY2VfLT4kbmFtZSRfID0gJGRlZmF1bHQkO1xuIik7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworUmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3I6OgorUmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT3B0aW9ucyYgb3B0aW9ucykKKyAgOiBkZXNjcmlwdG9yXyhkZXNjcmlwdG9yKSB7CisgIFNldEVudW1WYXJpYWJsZXMoZGVzY3JpcHRvciwgJnZhcmlhYmxlc18sIG9wdGlvbnMpOworfQorCitSZXBlYXRlZEVudW1GaWVsZEdlbmVyYXRvcjo6flJlcGVhdGVkRW51bUZpZWxkR2VuZXJhdG9yKCkge30KKwordm9pZCBSZXBlYXRlZEVudW1GaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVByaXZhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRGaWVsZDxpbnQ+ICRuYW1lJF87XG4iKTsKKyAgaWYgKGRlc2NyaXB0b3JfLT5pc19wYWNrZWQoKQorICAgICAgJiYgSGFzR2VuZXJhdGVkTWV0aG9kcyhkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAibXV0YWJsZSBpbnQgXyRuYW1lJF9jYWNoZWRfYnl0ZV9zaXplXztcbiIpOworICB9Cit9CisKK3ZvaWQgUmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVBY2Nlc3NvckRlY2xhcmF0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkdHlwZSQgJG5hbWUkKGludCBpbmRleCkgY29uc3QkZGVwcmVjYXRpb24kO1xuIgorICAgICJ2b2lkIHNldF8kbmFtZSQoaW50IGluZGV4LCAkdHlwZSQgdmFsdWUpJGRlcHJlY2F0aW9uJDtcbiIKKyAgICAidm9pZCBhZGRfJG5hbWUkKCR0eXBlJCB2YWx1ZSkkZGVwcmVjYXRpb24kO1xuIik7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRGaWVsZDxpbnQ+JiAkbmFtZSQoKSBjb25zdCRkZXByZWNhdGlvbiQ7XG4iCisgICAgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRGaWVsZDxpbnQ+KiBtdXRhYmxlXyRuYW1lJCgpJGRlcHJlY2F0aW9uJDtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlSW5saW5lQWNjZXNzb3JEZWZpbml0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGlzX2lubGluZSkgY29uc3QgeworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlcyh2YXJpYWJsZXNfKTsKKyAgdmFyaWFibGVzWyJpbmxpbmUiXSA9IGlzX2lubGluZSA/ICJpbmxpbmUiIDogIiI7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAiJGlubGluZSQgJHR5cGUkICRjbGFzc25hbWUkOjokbmFtZSQoaW50IGluZGV4KSBjb25zdCB7XG4iCisgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDokZnVsbF9uYW1lJClcbiIKKyAgICAiICByZXR1cm4gc3RhdGljX2Nhc3Q8ICR0eXBlJCA+KCRuYW1lJF8uR2V0KGluZGV4KSk7XG4iCisgICAgIn1cbiIKKyAgICAiJGlubGluZSQgdm9pZCAkY2xhc3NuYW1lJDo6c2V0XyRuYW1lJChpbnQgaW5kZXgsICR0eXBlJCB2YWx1ZSkge1xuIik7CisgIGlmICghSGFzUHJlc2VydmluZ1Vua25vd25FbnVtU2VtYW50aWNzKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICIgIGFzc2VydCgkdHlwZSRfSXNWYWxpZCh2YWx1ZSkpO1xuIik7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICIgICRuYW1lJF8uU2V0KGluZGV4LCB2YWx1ZSk7XG4iCisgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDokZnVsbF9uYW1lJClcbiIKKyAgICAifVxuIgorICAgICIkaW5saW5lJCB2b2lkICRjbGFzc25hbWUkOjphZGRfJG5hbWUkKCR0eXBlJCB2YWx1ZSkge1xuIik7CisgIGlmICghSGFzUHJlc2VydmluZ1Vua25vd25FbnVtU2VtYW50aWNzKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICIgIGFzc2VydCgkdHlwZSRfSXNWYWxpZCh2YWx1ZSkpO1xuIik7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICIgICRuYW1lJF8uQWRkKHZhbHVlKTtcbiIKKyAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOiRmdWxsX25hbWUkKVxuIgorICAgICJ9XG4iKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICIkaW5saW5lJCBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkRmllbGQ8aW50PiZcbiIKKyAgICAiJGNsYXNzbmFtZSQ6OiRuYW1lJCgpIGNvbnN0IHtcbiIKKyAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDokZnVsbF9uYW1lJClcbiIKKyAgICAiICByZXR1cm4gJG5hbWUkXztcbiIKKyAgICAifVxuIgorICAgICIkaW5saW5lJCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkRmllbGQ8aW50PipcbiIKKyAgICAiJGNsYXNzbmFtZSQ6Om11dGFibGVfJG5hbWUkKCkge1xuIgorICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6JGZ1bGxfbmFtZSQpXG4iCisgICAgIiAgcmV0dXJuICYkbmFtZSRfO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEVudW1GaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUNsZWFyaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAiJG5hbWUkXy5DbGVhcigpO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAiJG5hbWUkXy5NZXJnZUZyb20oZnJvbS4kbmFtZSRfKTtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU3dhcHBpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sICIkbmFtZSRfLlVuc2FmZUFyZW5hU3dhcCgmb3RoZXItPiRuYW1lJF8pO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVDb25zdHJ1Y3RvckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gTm90IG5lZWRlZCBmb3IgcmVwZWF0ZWQgZmllbGRzLgorfQorCit2b2lkIFJlcGVhdGVkRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2VGcm9tQ29kZWRTdHJlYW0oaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gRG9uJ3QgdXNlIFJlYWRSZXBlYXRlZFByaW1pdGl2ZSBoZXJlIHNvIHRoYXQgdGhlIGVudW0gY2FuIGJlIHZhbGlkYXRlZC4KKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaW50IHZhbHVlO1xuIgorICAgICJET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPFxuIgorICAgICIgICAgICAgICBpbnQsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0VOVU0+KFxuIgorICAgICIgICAgICAgaW5wdXQsICZ2YWx1ZSkpKTtcbiIpOworICBpZiAoSGFzUHJlc2VydmluZ1Vua25vd25FbnVtU2VtYW50aWNzKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJhZGRfJG5hbWUkKHN0YXRpY19jYXN0PCAkdHlwZSQgPih2YWx1ZSkpO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJpZiAoJHR5cGUkX0lzVmFsaWQodmFsdWUpKSB7XG4iCisgICAgICAiICBhZGRfJG5hbWUkKHN0YXRpY19jYXN0PCAkdHlwZSQgPih2YWx1ZSkpO1xuIik7CisgICAgaWYgKFVzZVVua25vd25GaWVsZFNldChkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgIn0gZWxzZSB7XG4iCisgICAgICAgICIgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+QWRkVmFyaW50KCRudW1iZXIkLCB2YWx1ZSk7XG4iKTsKKyAgICB9IGVsc2UgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJ9IGVsc2Uge1xuIgorICAgICAgICAiICB1bmtub3duX2ZpZWxkc19zdHJlYW0uV3JpdGVWYXJpbnQzMih0YWcpO1xuIgorICAgICAgICAiICB1bmtub3duX2ZpZWxkc19zdHJlYW0uV3JpdGVWYXJpbnQzMih2YWx1ZSk7XG4iKTsKKyAgICB9CisgICAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworICB9Cit9CisKK3ZvaWQgUmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZXJnZUZyb21Db2RlZFN0cmVhbVdpdGhQYWNraW5nKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmICghZGVzY3JpcHRvcl8tPmlzX3BhY2tlZCgpKSB7CisgICAgICAvLyBUaGlzIHBhdGggaXMgcmFyZWx5IGV4ZWN1dGVkLCBzbyB3ZSB1c2UgYSBub24taW5saW5lZCBpbXBsZW1lbnRhdGlvbi4KKyAgICBpZiAoSGFzUHJlc2VydmluZ1Vua25vd25FbnVtU2VtYW50aWNzKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAiRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjoiCisgICAgICAgICAgICAgICAgICAgICJXaXJlRm9ybWF0TGl0ZTo6UmVhZFBhY2tlZEVudW1QcmVzZXJ2ZVVua25vd25zKFxuIgorICAgICAgICAiICAgICAgIGlucHV0LFxuIgorICAgICAgICAiICAgICAgICRudW1iZXIkLFxuIgorICAgICAgICAiICAgICAgIE5VTEwsXG4iCisgICAgICAgICIgICAgICAgTlVMTCxcbiIKKyAgICAgICAgIiAgICAgICB0aGlzLT5tdXRhYmxlXyRuYW1lJCgpKSkpO1xuIik7CisgICAgfSBlbHNlIGlmIChVc2VVbmtub3duRmllbGRTZXQoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICJET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlJlYWRQYWNrZWRFbnVtUHJlc2VydmVVbmtub3ducyhcbiIKKyAgICAgICAgIiAgICAgICBpbnB1dCxcbiIKKyAgICAgICAgIiAgICAgICAkbnVtYmVyJCxcbiIKKyAgICAgICAgIiAgICAgICAkdHlwZSRfSXNWYWxpZCxcbiIKKyAgICAgICAgIiAgICAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCksXG4iCisgICAgICAgICIgICAgICAgdGhpcy0+bXV0YWJsZV8kbmFtZSQoKSkpKTtcbiIpOworICAgIH0gZWxzZSB7CisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAiRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjoiCisgICAgICAgICAgICAgICAgICAgICAiV2lyZUZvcm1hdExpdGU6OlJlYWRQYWNrZWRFbnVtUHJlc2VydmVVbmtub3ducyhcbiIKKyAgICAgICAgIiAgICAgICBpbnB1dCxcbiIKKyAgICAgICAgIiAgICAgICAkbnVtYmVyJCxcbiIKKyAgICAgICAgIiAgICAgICAkdHlwZSRfSXNWYWxpZCxcbiIKKyAgICAgICAgIiAgICAgICAmdW5rbm93bl9maWVsZHNfc3RyZWFtLFxuIgorICAgICAgICAiICAgICAgIHRoaXMtPm11dGFibGVfJG5hbWUkKCkpKSk7XG4iKTsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICI6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiBsZW5ndGg7XG4iCisgICAgICAiRE9fKGlucHV0LT5SZWFkVmFyaW50MzIoJmxlbmd0aCkpO1xuIgorICAgICAgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW06OkxpbWl0IGxpbWl0ID0gIgorICAgICAgICAgICJpbnB1dC0+UHVzaExpbWl0KGxlbmd0aCk7XG4iCisgICAgICAid2hpbGUgKGlucHV0LT5CeXRlc1VudGlsTGltaXQoKSA+IDApIHtcbiIKKyAgICAgICIgIGludCB2YWx1ZTtcbiIKKyAgICAgICIgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8XG4iCisgICAgICAiICAgICAgICAgaW50LCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9FTlVNPihcbiIKKyAgICAgICIgICAgICAgaW5wdXQsICZ2YWx1ZSkpKTtcbiIpOworICAgIGlmIChIYXNQcmVzZXJ2aW5nVW5rbm93bkVudW1TZW1hbnRpY3MoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiICBhZGRfJG5hbWUkKHN0YXRpY19jYXN0PCAkdHlwZSQgPih2YWx1ZSkpO1xuIik7CisgICAgfSBlbHNlIHsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiICBpZiAoJHR5cGUkX0lzVmFsaWQodmFsdWUpKSB7XG4iCisgICAgICAiICAgIGFkZF8kbmFtZSQoc3RhdGljX2Nhc3Q8ICR0eXBlJCA+KHZhbHVlKSk7XG4iCisgICAgICAiICB9IGVsc2Uge1xuIik7CisgICAgICBpZiAoVXNlVW5rbm93bkZpZWxkU2V0KGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICIgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5BZGRWYXJpbnQoJG51bWJlciQsIHZhbHVlKTtcbiIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgIiAgICB1bmtub3duX2ZpZWxkc19zdHJlYW0uV3JpdGVWYXJpbnQzMih0YWcpO1xuIgorICAgICAgICAiICAgIHVua25vd25fZmllbGRzX3N0cmVhbS5Xcml0ZVZhcmludDMyKHZhbHVlKTtcbiIpOworICAgICAgfQorICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiICB9XG4iKTsKKyAgICB9CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJ9XG4iCisgICAgICAiaW5wdXQtPlBvcExpbWl0KGxpbWl0KTtcbiIpOworICB9Cit9CisKK3ZvaWQgUmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKGRlc2NyaXB0b3JfLT5pc19wYWNrZWQoKSkgeworICAgIC8vIFdyaXRlIHRoZSB0YWcgYW5kIHRoZSBzaXplLgorICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaWYgKHRoaXMtPiRuYW1lJF9zaXplKCkgPiAwKSB7XG4iCisgICAgICAiICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVUYWcoXG4iCisgICAgICAiICAgICRudW1iZXIkLFxuIgorICAgICAgIiAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCxcbiIKKyAgICAgICIgICAgb3V0cHV0KTtcbiIKKyAgICAgICIgIG91dHB1dC0+V3JpdGVWYXJpbnQzMihfJG5hbWUkX2NhY2hlZF9ieXRlX3NpemVfKTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+JG5hbWUkX3NpemUoKTsgaSsrKSB7XG4iKTsKKyAgaWYgKGRlc2NyaXB0b3JfLT5pc19wYWNrZWQoKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVFbnVtTm9UYWcoXG4iCisgICAgICAiICAgIHRoaXMtPiRuYW1lJChpKSwgb3V0cHV0KTtcbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVFbnVtKFxuIgorICAgICAgIiAgICAkbnVtYmVyJCwgdGhpcy0+JG5hbWUkKGkpLCBvdXRwdXQpO1xuIik7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworfQorCit2b2lkIFJlcGVhdGVkRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoZGVzY3JpcHRvcl8tPmlzX3BhY2tlZCgpKSB7CisgICAgLy8gV3JpdGUgdGhlIHRhZyBhbmQgdGhlIHNpemUuCisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJpZiAodGhpcy0+JG5hbWUkX3NpemUoKSA+IDApIHtcbiIKKyAgICAgICIgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVRhZ1RvQXJyYXkoXG4iCisgICAgICAiICAgICRudW1iZXIkLFxuIgorICAgICAgIiAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCxcbiIKKyAgICAgICIgICAgdGFyZ2V0KTtcbiIKKyAgICAgICIgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZVZhcmludDMyVG9BcnJheSgiCisgICAgICAiICAgIF8kbmFtZSRfY2FjaGVkX2J5dGVfc2l6ZV8sIHRhcmdldCk7XG4iCisgICAgICAifVxuIik7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPiRuYW1lJF9zaXplKCk7IGkrKykge1xuIik7CisgIGlmIChkZXNjcmlwdG9yXy0+aXNfcGFja2VkKCkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlRW51bU5vVGFnVG9BcnJheShcbiIKKyAgICAgICIgICAgdGhpcy0+JG5hbWUkKGkpLCB0YXJnZXQpO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUVudW1Ub0FycmF5KFxuIgorICAgICAgIiAgICAkbnVtYmVyJCwgdGhpcy0+JG5hbWUkKGkpLCB0YXJnZXQpO1xuIik7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworfQorCit2b2lkIFJlcGVhdGVkRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnl0ZVNpemUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAie1xuIgorICAgICIgIGludCBkYXRhX3NpemUgPSAwO1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+JG5hbWUkX3NpemUoKTsgaSsrKSB7XG4iCisgICAgICAiICBkYXRhX3NpemUgKz0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkVudW1TaXplKFxuIgorICAgICAgIiAgICB0aGlzLT4kbmFtZSQoaSkpO1xuIgorICAgICAgIn1cbiIpOworCisgIGlmIChkZXNjcmlwdG9yXy0+aXNfcGFja2VkKCkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImlmIChkYXRhX3NpemUgPiAwKSB7XG4iCisgICAgICAiICB0b3RhbF9zaXplICs9ICR0YWdfc2l6ZSQgK1xuIgorICAgICAgIiAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6SW50MzJTaXplKGRhdGFfc2l6ZSk7XG4iCisgICAgICAifVxuIgorICAgICAgIkdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7XG4iCisgICAgICAiXyRuYW1lJF9jYWNoZWRfYnl0ZV9zaXplXyA9IGRhdGFfc2l6ZTtcbiIKKyAgICAgICJHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTtcbiIKKyAgICAgICJ0b3RhbF9zaXplICs9IGRhdGFfc2l6ZTtcbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAidG90YWxfc2l6ZSArPSAkdGFnX3NpemUkICogdGhpcy0+JG5hbWUkX3NpemUoKSArIGRhdGFfc2l6ZTtcbiIpOworICB9CisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworfQorCit9ICAvLyBuYW1lc3BhY2UgY3BwCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2VudW1fZmllbGQuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9lbnVtX2ZpZWxkLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWIxZDAxZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9lbnVtX2ZpZWxkLmgKQEAgLTAsMCArMSwxMjUgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1BQX0VOVU1fRklFTERfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DUFBfRU5VTV9GSUVMRF9IX18KKworI2luY2x1ZGUgPG1hcD4KKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZmllbGQuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBjcHAgeworCitjbGFzcyBFbnVtRmllbGRHZW5lcmF0b3IgOiBwdWJsaWMgRmllbGRHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgRW51bUZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE9wdGlvbnMmIG9wdGlvbnMpOworICB+RW51bUZpZWxkR2VuZXJhdG9yKCk7CisKKyAgLy8gaW1wbGVtZW50cyBGaWVsZEdlbmVyYXRvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgdm9pZCBHZW5lcmF0ZVByaXZhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUFjY2Vzc29yRGVjbGFyYXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUlubGluZUFjY2Vzc29yRGVmaW5pdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaXNfaW5saW5lKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUNsZWFyaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTd2FwcGluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQ29uc3RydWN0b3JDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU1lcmdlRnJvbUNvZGVkU3RyZWFtKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUJ5dGVTaXplKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKworIHByb3RlY3RlZDoKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXNfOworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEVudW1GaWVsZEdlbmVyYXRvcik7Cit9OworCitjbGFzcyBFbnVtT25lb2ZGaWVsZEdlbmVyYXRvciA6IHB1YmxpYyBFbnVtRmllbGRHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgRW51bU9uZW9mRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBPcHRpb25zJiBvcHRpb25zKTsKKyAgfkVudW1PbmVvZkZpZWxkR2VuZXJhdG9yKCk7CisKKyAgLy8gaW1wbGVtZW50cyBGaWVsZEdlbmVyYXRvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgdm9pZCBHZW5lcmF0ZUlubGluZUFjY2Vzc29yRGVmaW5pdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaXNfaW5saW5lKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUNsZWFyaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTd2FwcGluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQ29uc3RydWN0b3JDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhFbnVtT25lb2ZGaWVsZEdlbmVyYXRvcik7Cit9OworCitjbGFzcyBSZXBlYXRlZEVudW1GaWVsZEdlbmVyYXRvciA6IHB1YmxpYyBGaWVsZEdlbmVyYXRvciB7CisgcHVibGljOgorICBleHBsaWNpdCBSZXBlYXRlZEVudW1GaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE9wdGlvbnMmIG9wdGlvbnMpOworICB+UmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3IoKTsKKworICAvLyBpbXBsZW1lbnRzIEZpZWxkR2VuZXJhdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICB2b2lkIEdlbmVyYXRlUHJpdmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQWNjZXNzb3JEZWNsYXJhdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSW5saW5lQWNjZXNzb3JEZWZpbml0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc19pbmxpbmUpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQ2xlYXJpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVN3YXBwaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVDb25zdHJ1Y3RvckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2VGcm9tQ29kZWRTdHJlYW0oaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2VGcm9tQ29kZWRTdHJlYW1XaXRoUGFja2luZyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCeXRlU2l6ZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyBwcml2YXRlOgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlc187CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFJlcGVhdGVkRW51bUZpZWxkR2VuZXJhdG9yKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBjcHAKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NQUF9FTlVNX0ZJRUxEX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2V4dGVuc2lvbi5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9leHRlbnNpb24uY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzQyZjE2MgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9leHRlbnNpb24uY2MKQEAgLTAsMCArMSwyMTAgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2V4dGVuc2lvbi5oPgorI2luY2x1ZGUgPG1hcD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgY3BwIHsKKworbmFtZXNwYWNlIHsKKworLy8gUmV0dXJucyB0aGUgZnVsbHktcXVhbGlmaWVkIGNsYXNzIG5hbWUgb2YgdGhlIG1lc3NhZ2UgdGhhdCB0aGlzIGZpZWxkCisvLyBleHRlbmRzLiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgaW4gdGhlIEdvb2dsZS1pbnRlcm5hbCBjb2RlIHRvIGhhbmRsZSBzb21lCisvLyBsZWdhY3kgY2FzZXMuCitzdHJpbmcgRXh0ZW5kZWVDbGFzc05hbWUoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIGNvbnN0IERlc2NyaXB0b3IqIGV4dGVuZGVlID0gZGVzY3JpcHRvci0+Y29udGFpbmluZ190eXBlKCk7CisgIHJldHVybiBDbGFzc05hbWUoZXh0ZW5kZWUsIHRydWUpOworfQorCit9ICAvLyBhbm9ueW1vdXMgbmFtZXNwYWNlCisKK0V4dGVuc2lvbkdlbmVyYXRvcjo6RXh0ZW5zaW9uR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE9wdGlvbnMmIG9wdGlvbnMpCisgIDogZGVzY3JpcHRvcl8oZGVzY3JpcHRvciksCisgICAgb3B0aW9uc18ob3B0aW9ucykgeworICAvLyBDb25zdHJ1Y3QgdHlwZV90cmFpdHNfLgorICBpZiAoZGVzY3JpcHRvcl8tPmlzX3JlcGVhdGVkKCkpIHsKKyAgICB0eXBlX3RyYWl0c18gPSAiUmVwZWF0ZWQiOworICB9CisKKyAgc3dpdGNoIChkZXNjcmlwdG9yXy0+Y3BwX3R5cGUoKSkgeworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0VOVU06CisgICAgICB0eXBlX3RyYWl0c18uYXBwZW5kKCJFbnVtVHlwZVRyYWl0czwgIik7CisgICAgICB0eXBlX3RyYWl0c18uYXBwZW5kKENsYXNzTmFtZShkZXNjcmlwdG9yXy0+ZW51bV90eXBlKCksIHRydWUpKTsKKyAgICAgIHR5cGVfdHJhaXRzXy5hcHBlbmQoIiwgIik7CisgICAgICB0eXBlX3RyYWl0c18uYXBwZW5kKENsYXNzTmFtZShkZXNjcmlwdG9yXy0+ZW51bV90eXBlKCksIHRydWUpKTsKKyAgICAgIHR5cGVfdHJhaXRzXy5hcHBlbmQoIl9Jc1ZhbGlkPiIpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HOgorICAgICAgdHlwZV90cmFpdHNfLmFwcGVuZCgiU3RyaW5nVHlwZVRyYWl0cyIpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRToKKyAgICAgIHR5cGVfdHJhaXRzXy5hcHBlbmQoIk1lc3NhZ2VUeXBlVHJhaXRzPCAiKTsKKyAgICAgIHR5cGVfdHJhaXRzXy5hcHBlbmQoQ2xhc3NOYW1lKGRlc2NyaXB0b3JfLT5tZXNzYWdlX3R5cGUoKSwgdHJ1ZSkpOworICAgICAgdHlwZV90cmFpdHNfLmFwcGVuZCgiID4iKTsKKyAgICAgIGJyZWFrOworICAgIGRlZmF1bHQ6CisgICAgICB0eXBlX3RyYWl0c18uYXBwZW5kKCJQcmltaXRpdmVUeXBlVHJhaXRzPCAiKTsKKyAgICAgIHR5cGVfdHJhaXRzXy5hcHBlbmQoUHJpbWl0aXZlVHlwZU5hbWUoZGVzY3JpcHRvcl8tPmNwcF90eXBlKCkpKTsKKyAgICAgIHR5cGVfdHJhaXRzXy5hcHBlbmQoIiA+Iik7CisgICAgICBicmVhazsKKyAgfQorfQorCitFeHRlbnNpb25HZW5lcmF0b3I6On5FeHRlbnNpb25HZW5lcmF0b3IoKSB7fQorCit2b2lkIEV4dGVuc2lvbkdlbmVyYXRvcjo6R2VuZXJhdGVEZWNsYXJhdGlvbihpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcnM7CisgIHZhcnNbImV4dGVuZGVlIiAgICAgXSA9IEV4dGVuZGVlQ2xhc3NOYW1lKGRlc2NyaXB0b3JfKTsKKyAgdmFyc1sibnVtYmVyIiAgICAgICBdID0gU2ltcGxlSXRvYShkZXNjcmlwdG9yXy0+bnVtYmVyKCkpOworICB2YXJzWyJ0eXBlX3RyYWl0cyIgIF0gPSB0eXBlX3RyYWl0c187CisgIHZhcnNbIm5hbWUiICAgICAgICAgXSA9IGRlc2NyaXB0b3JfLT5uYW1lKCk7CisgIHZhcnNbImZpZWxkX3R5cGUiICAgXSA9IFNpbXBsZUl0b2Eoc3RhdGljX2Nhc3Q8aW50PihkZXNjcmlwdG9yXy0+dHlwZSgpKSk7CisgIHZhcnNbInBhY2tlZCIgICAgICAgXSA9IGRlc2NyaXB0b3JfLT5vcHRpb25zKCkucGFja2VkKCkgPyAidHJ1ZSIgOiAiZmFsc2UiOworICB2YXJzWyJjb25zdGFudF9uYW1lIl0gPSBGaWVsZENvbnN0YW50TmFtZShkZXNjcmlwdG9yXyk7CisKKyAgLy8gSWYgdGhpcyBpcyBhIGNsYXNzIG1lbWJlciwgaXQgbmVlZHMgdG8gYmUgZGVjbGFyZWQgInN0YXRpYyIuICBPdGhlcndpc2UsCisgIC8vIGl0IG5lZWRzIHRvIGJlICJleHRlcm4iLiAgSW4gdGhlIGxhdHRlciBjYXNlLCBpdCBhbHNvIG5lZWRzIHRoZSBETEwKKyAgLy8gZXhwb3J0L2ltcG9ydCBzcGVjaWZpZXIuCisgIGlmIChkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX3Njb3BlKCkgPT0gTlVMTCkgeworICAgIHZhcnNbInF1YWxpZmllciJdID0gImV4dGVybiI7CisgICAgaWYgKCFvcHRpb25zXy5kbGxleHBvcnRfZGVjbC5lbXB0eSgpKSB7CisgICAgICB2YXJzWyJxdWFsaWZpZXIiXSA9IG9wdGlvbnNfLmRsbGV4cG9ydF9kZWNsICsgIiAiICsgdmFyc1sicXVhbGlmaWVyIl07CisgICAgfQorICB9IGVsc2UgeworICAgIHZhcnNbInF1YWxpZmllciJdID0gInN0YXRpYyI7CisgIH0KKworICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICJzdGF0aWMgY29uc3QgaW50ICRjb25zdGFudF9uYW1lJCA9ICRudW1iZXIkO1xuIgorICAgICIkcXVhbGlmaWVyJCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpFeHRlbnNpb25JZGVudGlmaWVyPCAkZXh0ZW5kZWUkLFxuIgorICAgICIgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6JHR5cGVfdHJhaXRzJCwgJGZpZWxkX3R5cGUkLCAkcGFja2VkJCA+XG4iCisgICAgIiAgJG5hbWUkO1xuIgorICAgICk7CisKK30KKwordm9pZCBFeHRlbnNpb25HZW5lcmF0b3I6OkdlbmVyYXRlRGVmaW5pdGlvbihpbzo6UHJpbnRlciogcHJpbnRlcikgeworICAvLyBJZiB0aGlzIGlzIGEgY2xhc3MgbWVtYmVyLCBpdCBuZWVkcyB0byBiZSBkZWNsYXJlZCBpbiBpdHMgY2xhc3Mgc2NvcGUuCisgIHN0cmluZyBzY29wZSA9IChkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX3Njb3BlKCkgPT0gTlVMTCkgPyAiIiA6CisgICAgQ2xhc3NOYW1lKGRlc2NyaXB0b3JfLT5leHRlbnNpb25fc2NvcGUoKSwgZmFsc2UpICsgIjo6IjsKKyAgc3RyaW5nIG5hbWUgPSBzY29wZSArIGRlc2NyaXB0b3JfLT5uYW1lKCk7CisKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJzOworICB2YXJzWyJleHRlbmRlZSIgICAgIF0gPSBFeHRlbmRlZUNsYXNzTmFtZShkZXNjcmlwdG9yXyk7CisgIHZhcnNbInR5cGVfdHJhaXRzIiAgXSA9IHR5cGVfdHJhaXRzXzsKKyAgdmFyc1sibmFtZSIgICAgICAgICBdID0gbmFtZTsKKyAgdmFyc1siY29uc3RhbnRfbmFtZSJdID0gRmllbGRDb25zdGFudE5hbWUoZGVzY3JpcHRvcl8pOworICB2YXJzWyJkZWZhdWx0IiAgICAgIF0gPSBEZWZhdWx0VmFsdWUoZGVzY3JpcHRvcl8pOworICB2YXJzWyJmaWVsZF90eXBlIiAgIF0gPSBTaW1wbGVJdG9hKHN0YXRpY19jYXN0PGludD4oZGVzY3JpcHRvcl8tPnR5cGUoKSkpOworICB2YXJzWyJwYWNrZWQiICAgICAgIF0gPSBkZXNjcmlwdG9yXy0+b3B0aW9ucygpLnBhY2tlZCgpID8gInRydWUiIDogImZhbHNlIjsKKyAgdmFyc1sic2NvcGUiICAgICAgICBdID0gc2NvcGU7CisKKyAgaWYgKGRlc2NyaXB0b3JfLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9TVFJJTkcpIHsKKyAgICAvLyBXZSBuZWVkIHRvIGRlY2xhcmUgYSBnbG9iYWwgc3RyaW5nIHdoaWNoIHdpbGwgY29udGFpbiB0aGUgZGVmYXVsdCB2YWx1ZS4KKyAgICAvLyBXZSBjYW5ub3QgZGVjbGFyZSBpdCBhdCBjbGFzcyBzY29wZSBiZWNhdXNlIHRoYXQgd291bGQgcmVxdWlyZSBleHBvc2luZworICAgIC8vIGl0IGluIHRoZSBoZWFkZXIgd2hpY2ggd291bGQgYmUgYW5ub3lpbmcgZm9yIG90aGVyIHJlYXNvbnMuICBTbyB3ZQorICAgIC8vIHJlcGxhY2UgOjogd2l0aCBfIGluIHRoZSBuYW1lIGFuZCBkZWNsYXJlIGl0IGFzIGEgZ2xvYmFsLgorICAgIHN0cmluZyBnbG9iYWxfbmFtZSA9IFN0cmluZ1JlcGxhY2UobmFtZSwgIjo6IiwgIl8iLCB0cnVlKTsKKyAgICB2YXJzWyJnbG9iYWxfbmFtZSJdID0gZ2xvYmFsX25hbWU7CisgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICJjb25zdCA6OnN0ZDo6c3RyaW5nICRnbG9iYWxfbmFtZSRfZGVmYXVsdCgkZGVmYXVsdCQpO1xuIik7CisKKyAgICAvLyBVcGRhdGUgdGhlIGRlZmF1bHQgdG8gcmVmZXIgdG8gdGhlIHN0cmluZyBnbG9iYWwuCisgICAgdmFyc1siZGVmYXVsdCJdID0gZ2xvYmFsX25hbWUgKyAiX2RlZmF1bHQiOworICB9CisKKyAgLy8gTGlrZXdpc2UsIGNsYXNzIG1lbWJlcnMgbmVlZCB0byBkZWNsYXJlIHRoZSBmaWVsZCBjb25zdGFudCB2YXJpYWJsZS4KKyAgaWYgKGRlc2NyaXB0b3JfLT5leHRlbnNpb25fc2NvcGUoKSAhPSBOVUxMKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICIjaWYgIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDBcbiIKKyAgICAgICJjb25zdCBpbnQgJHNjb3BlJCRjb25zdGFudF9uYW1lJDtcbiIKKyAgICAgICIjZW5kaWZcbiIpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAiOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RXh0ZW5zaW9uSWRlbnRpZmllcjwgJGV4dGVuZGVlJCxcbiIKKyAgICAiICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OiR0eXBlX3RyYWl0cyQsICRmaWVsZF90eXBlJCwgJHBhY2tlZCQgPlxuIgorICAgICIgICRuYW1lJCgkY29uc3RhbnRfbmFtZSQsICRkZWZhdWx0JCk7XG4iKTsKK30KKwordm9pZCBFeHRlbnNpb25HZW5lcmF0b3I6OkdlbmVyYXRlUmVnaXN0cmF0aW9uKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyczsKKyAgdmFyc1siZXh0ZW5kZWUiICAgXSA9IEV4dGVuZGVlQ2xhc3NOYW1lKGRlc2NyaXB0b3JfKTsKKyAgdmFyc1sibnVtYmVyIiAgICAgXSA9IFNpbXBsZUl0b2EoZGVzY3JpcHRvcl8tPm51bWJlcigpKTsKKyAgdmFyc1siZmllbGRfdHlwZSIgXSA9IFNpbXBsZUl0b2Eoc3RhdGljX2Nhc3Q8aW50PihkZXNjcmlwdG9yXy0+dHlwZSgpKSk7CisgIHZhcnNbImlzX3JlcGVhdGVkIl0gPSBkZXNjcmlwdG9yXy0+aXNfcmVwZWF0ZWQoKSA/ICJ0cnVlIiA6ICJmYWxzZSI7CisgIHZhcnNbImlzX3BhY2tlZCIgIF0gPSAoZGVzY3JpcHRvcl8tPmlzX3JlcGVhdGVkKCkgJiYKKyAgICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdG9yXy0+b3B0aW9ucygpLnBhY2tlZCgpKQorICAgICAgICAgICAgICAgICAgICAgICAgPyAidHJ1ZSIgOiAiZmFsc2UiOworCisgIHN3aXRjaCAoZGVzY3JpcHRvcl8tPmNwcF90eXBlKCkpIHsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9FTlVNOgorICAgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICAgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkV4dGVuc2lvblNldDo6UmVnaXN0ZXJFbnVtRXh0ZW5zaW9uKFxuIgorICAgICAgICAiICAmJGV4dGVuZGVlJDo6ZGVmYXVsdF9pbnN0YW5jZSgpLFxuIgorICAgICAgICAiICAkbnVtYmVyJCwgJGZpZWxkX3R5cGUkLCAkaXNfcmVwZWF0ZWQkLCAkaXNfcGFja2VkJCxcbiIpOworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICIgICYkdHlwZSRfSXNWYWxpZCk7XG4iLAorICAgICAgICAidHlwZSIsIENsYXNzTmFtZShkZXNjcmlwdG9yXy0+ZW51bV90eXBlKCksIHRydWUpKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U6CisgICAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgICAiOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RXh0ZW5zaW9uU2V0OjpSZWdpc3Rlck1lc3NhZ2VFeHRlbnNpb24oXG4iCisgICAgICAgICIgICYkZXh0ZW5kZWUkOjpkZWZhdWx0X2luc3RhbmNlKCksXG4iCisgICAgICAgICIgICRudW1iZXIkLCAkZmllbGRfdHlwZSQsICRpc19yZXBlYXRlZCQsICRpc19wYWNrZWQkLFxuIik7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIiAgJiR0eXBlJDo6ZGVmYXVsdF9pbnN0YW5jZSgpKTtcbiIsCisgICAgICAgICJ0eXBlIiwgQ2xhc3NOYW1lKGRlc2NyaXB0b3JfLT5tZXNzYWdlX3R5cGUoKSwgdHJ1ZSkpOworICAgICAgYnJlYWs7CisgICAgZGVmYXVsdDoKKyAgICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAgICI6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpFeHRlbnNpb25TZXQ6OlJlZ2lzdGVyRXh0ZW5zaW9uKFxuIgorICAgICAgICAiICAmJGV4dGVuZGVlJDo6ZGVmYXVsdF9pbnN0YW5jZSgpLFxuIgorICAgICAgICAiICAkbnVtYmVyJCwgJGZpZWxkX3R5cGUkLCAkaXNfcmVwZWF0ZWQkLCAkaXNfcGFja2VkJCk7XG4iKTsKKyAgICAgIGJyZWFrOworICB9Cit9CisKK30gIC8vIG5hbWVzcGFjZSBjcHAKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZXh0ZW5zaW9uLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZXh0ZW5zaW9uLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWMxY2FmMQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9leHRlbnNpb24uaApAQCAtMCwwICsxLDg2IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NQUF9FWFRFTlNJT05fSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DUFBfRVhURU5TSU9OX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9vcHRpb25zLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKyAgY2xhc3MgRmllbGREZXNjcmlwdG9yOyAgICAgICAvLyBkZXNjcmlwdG9yLmgKKyAgbmFtZXNwYWNlIGlvIHsKKyAgICBjbGFzcyBQcmludGVyOyAgICAgICAgICAgICAvLyBwcmludGVyLmgKKyAgfQorfQorCituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBjcHAgeworCisvLyBHZW5lcmF0ZXMgY29kZSBmb3IgYW4gZXh0ZW5zaW9uLCB3aGljaCBtYXkgYmUgd2l0aGluIHRoZSBzY29wZSBvZiBzb21lCisvLyBtZXNzYWdlIG9yIG1heSBiZSBhdCBmaWxlIHNjb3BlLiAgVGhpcyBpcyBtdWNoIHNpbXBsZXIgdGhhbiBGaWVsZEdlbmVyYXRvcgorLy8gc2luY2UgZXh0ZW5zaW9ucyBhcmUganVzdCBzaW1wbGUgaWRlbnRpZmllcnMgd2l0aCBpbnRlcmVzdGluZyB0eXBlcy4KK2NsYXNzIEV4dGVuc2lvbkdlbmVyYXRvciB7CisgcHVibGljOgorICAvLyBTZWUgZ2VuZXJhdG9yLmNjIGZvciB0aGUgbWVhbmluZyBvZiBkbGxleHBvcnRfZGVjbC4KKyAgZXhwbGljaXQgRXh0ZW5zaW9uR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE9wdGlvbnMmIG9wdGlvbnMpOworICB+RXh0ZW5zaW9uR2VuZXJhdG9yKCk7CisKKyAgLy8gSGVhZGVyIHN0dWZmLgorICB2b2lkIEdlbmVyYXRlRGVjbGFyYXRpb24oaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIC8vIFNvdXJjZSBmaWxlIHN0dWZmLgorICB2b2lkIEdlbmVyYXRlRGVmaW5pdGlvbihpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyAgLy8gR2VuZXJhdGUgY29kZSB0byByZWdpc3RlciB0aGUgZXh0ZW5zaW9uLgorICB2b2lkIEdlbmVyYXRlUmVnaXN0cmF0aW9uKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworIHByaXZhdGU6CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcl87CisgIHN0cmluZyB0eXBlX3RyYWl0c187CisgIE9wdGlvbnMgb3B0aW9uc187CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEV4dGVuc2lvbkdlbmVyYXRvcik7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgY3BwCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DUFBfTUVTU0FHRV9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9maWVsZC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9maWVsZC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ZDQ3ZDRlCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2ZpZWxkLmNjCkBAIC0wLDAgKzEsMTk4IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9maWVsZC5oPgorI2luY2x1ZGUgPG1lbW9yeT4KKyNpZm5kZWYgX1NIQVJFRF9QVFJfSAorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaGFyZWRfcHRyLmg+CisjZW5kaWYKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9wcmltaXRpdmVfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9zdHJpbmdfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9lbnVtX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfbWFwX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfbWVzc2FnZV9maWVsZC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbG9nZ2luZy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGNwcCB7CisKK3VzaW5nIGludGVybmFsOjpXaXJlRm9ybWF0OworCit2b2lkIFNldENvbW1vbkZpZWxkVmFyaWFibGVzKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwPHN0cmluZywgc3RyaW5nPiogdmFyaWFibGVzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBPcHRpb25zJiBvcHRpb25zKSB7CisgICgqdmFyaWFibGVzKVsibmFtZSJdID0gRmllbGROYW1lKGRlc2NyaXB0b3IpOworICAoKnZhcmlhYmxlcylbImluZGV4Il0gPSBTaW1wbGVJdG9hKGRlc2NyaXB0b3ItPmluZGV4KCkpOworICAoKnZhcmlhYmxlcylbIm51bWJlciJdID0gU2ltcGxlSXRvYShkZXNjcmlwdG9yLT5udW1iZXIoKSk7CisgICgqdmFyaWFibGVzKVsiY2xhc3NuYW1lIl0gPSBDbGFzc05hbWUoRmllbGRTY29wZShkZXNjcmlwdG9yKSwgZmFsc2UpOworICAoKnZhcmlhYmxlcylbImRlY2xhcmVkX3R5cGUiXSA9IERlY2xhcmVkVHlwZU1ldGhvZE5hbWUoZGVzY3JpcHRvci0+dHlwZSgpKTsKKworICAvLyBub25fbnVsbF9wdHJfdG9fbmFtZSBpcyB1c2FibGUgb25seSBpZiBoYXNfJG5hbWUkIGlzIHRydWUuICBJdCB5aWVsZHMgYQorICAvLyBwb2ludGVyIHRoYXQgd2lsbCBub3QgYmUgTlVMTC4gIFN1YmNsYXNzZXMgb2YgRmllbGRHZW5lcmF0b3IgbWF5IHNldAorICAvLyAoKnZhcmlhYmxlcylbIm5vbl9udWxsX3B0cl90b19uYW1lIl0gZGlmZmVyZW50bHkuCisgICgqdmFyaWFibGVzKVsibm9uX251bGxfcHRyX3RvX25hbWUiXSA9CisgICAgICBTdHJDYXQoIiZ0aGlzLT4iLCBGaWVsZE5hbWUoZGVzY3JpcHRvciksICIoKSIpOworCisgICgqdmFyaWFibGVzKVsidGFnX3NpemUiXSA9IFNpbXBsZUl0b2EoCisgICAgV2lyZUZvcm1hdDo6VGFnU2l6ZShkZXNjcmlwdG9yLT5udW1iZXIoKSwgZGVzY3JpcHRvci0+dHlwZSgpKSk7CisgICgqdmFyaWFibGVzKVsiZGVwcmVjYXRpb24iXSA9IGRlc2NyaXB0b3ItPm9wdGlvbnMoKS5kZXByZWNhdGVkKCkKKyAgICAgID8gIiBQUk9UT0JVRl9ERVBSRUNBVEVEIiA6ICIiOworCisgICgqdmFyaWFibGVzKVsiY3BwZ2V0Il0gPSAiR2V0IjsKKworICBpZiAoSGFzRmllbGRQcmVzZW5jZShkZXNjcmlwdG9yLT5maWxlKCkpKSB7CisgICAgKCp2YXJpYWJsZXMpWyJzZXRfaGFzYml0Il0gPQorICAgICAgICAic2V0X2hhc18iICsgRmllbGROYW1lKGRlc2NyaXB0b3IpICsgIigpOyI7CisgICAgKCp2YXJpYWJsZXMpWyJjbGVhcl9oYXNiaXQiXSA9CisgICAgICAgICJjbGVhcl9oYXNfIiArIEZpZWxkTmFtZShkZXNjcmlwdG9yKSArICIoKTsiOworICB9IGVsc2UgeworICAgICgqdmFyaWFibGVzKVsic2V0X2hhc2JpdCJdID0gIiI7CisgICAgKCp2YXJpYWJsZXMpWyJjbGVhcl9oYXNiaXQiXSA9ICIiOworICB9CisKKyAgLy8gQnkgZGVmYXVsdCwgZW1wdHkgc3RyaW5nLCBzbyB0aGF0IGdlbmVyaWMgY29kZSB1c2VkIGZvciBib3RoIG9uZW9mcyBhbmQKKyAgLy8gc2luZ3VsYXIgZmllbGRzIGNhbiBiZSB3cml0dGVuLgorICAoKnZhcmlhYmxlcylbIm9uZW9mX3ByZWZpeCJdID0gIiI7Cit9CisKK3ZvaWQgU2V0Q29tbW9uT25lb2ZGaWVsZFZhcmlhYmxlcyhjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwPHN0cmluZywgc3RyaW5nPiogdmFyaWFibGVzKSB7CisgIGNvbnN0IHN0cmluZyBwcmVmaXggPSBkZXNjcmlwdG9yLT5jb250YWluaW5nX29uZW9mKCktPm5hbWUoKSArICJfLiI7CisgICgqdmFyaWFibGVzKVsib25lb2ZfcHJlZml4Il0gPSBwcmVmaXg7CisgICgqdmFyaWFibGVzKVsib25lb2ZfbmFtZSJdID0gZGVzY3JpcHRvci0+Y29udGFpbmluZ19vbmVvZigpLT5uYW1lKCk7CisgICgqdmFyaWFibGVzKVsibm9uX251bGxfcHRyX3RvX25hbWUiXSA9CisgICAgICBTdHJDYXQocHJlZml4LCAoKnZhcmlhYmxlcylbIm5hbWUiXSwgIl8iKTsKK30KKworRmllbGRHZW5lcmF0b3I6On5GaWVsZEdlbmVyYXRvcigpIHt9CisKK3ZvaWQgRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZXJnZUZyb21Db2RlZFN0cmVhbVdpdGhQYWNraW5nKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIFJlYWNoaW5nIGhlcmUgaW5kaWNhdGVzIGEgYnVnLiBDYXNlcyBhcmU6CisgIC8vICAgLSBUaGlzIEZpZWxkR2VuZXJhdG9yIHNob3VsZCBzdXBwb3J0IHBhY2tpbmcsIGJ1dCB0aGlzIG1ldGhvZCBzaG91bGQgYmUKKyAgLy8gICAgIG92ZXJyaWRkZW4uCisgIC8vICAgLSBUaGlzIEZpZWxkR2VuZXJhdG9yIGRvZXNuJ3Qgc3VwcG9ydCBwYWNraW5nLCBhbmQgdGhpcyBtZXRob2Qgc2hvdWxkCisgIC8vICAgICBuZXZlciBoYXZlIGJlZW4gY2FsbGVkLgorICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiR2VuZXJhdGVNZXJnZUZyb21Db2RlZFN0cmVhbVdpdGhQYWNraW5nKCkgIgorICAgICAgICAgICAgIDw8ICJjYWxsZWQgb24gZmllbGQgZ2VuZXJhdG9yIHRoYXQgZG9lcyBub3Qgc3VwcG9ydCBwYWNraW5nLiI7CisKK30KKworRmllbGRHZW5lcmF0b3JNYXA6OkZpZWxkR2VuZXJhdG9yTWFwKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT3B0aW9ucyYgb3B0aW9ucykKKyAgICA6IGRlc2NyaXB0b3JfKGRlc2NyaXB0b3IpLAorICAgICAgZmllbGRfZ2VuZXJhdG9yc18oCisgICAgICAgICAgbmV3IGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8RmllbGRHZW5lcmF0b3I+W2Rlc2NyaXB0b3ItPmZpZWxkX2NvdW50KCldKSB7CisgIC8vIENvbnN0cnVjdCBhbGwgdGhlIEZpZWxkR2VuZXJhdG9ycy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBmaWVsZF9nZW5lcmF0b3JzX1tpXS5yZXNldChNYWtlR2VuZXJhdG9yKGRlc2NyaXB0b3ItPmZpZWxkKGkpLCBvcHRpb25zKSk7CisgIH0KK30KKworRmllbGRHZW5lcmF0b3IqIEZpZWxkR2VuZXJhdG9yTWFwOjpNYWtlR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT3B0aW9ucyYgb3B0aW9ucykgeworICBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkpIHsKKyAgICBzd2l0Y2ggKGZpZWxkLT5jcHBfdHlwZSgpKSB7CisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgICBpZiAoZmllbGQtPmlzX21hcCgpKSB7CisgICAgICAgICAgcmV0dXJuIG5ldyBNYXBGaWVsZEdlbmVyYXRvcihmaWVsZCwgb3B0aW9ucyk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgcmV0dXJuIG5ldyBSZXBlYXRlZE1lc3NhZ2VGaWVsZEdlbmVyYXRvcihmaWVsZCwgb3B0aW9ucyk7CisgICAgICAgIH0KKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORzoKKyAgICAgICAgc3dpdGNoIChmaWVsZC0+b3B0aW9ucygpLmN0eXBlKCkpIHsKKyAgICAgICAgICBkZWZhdWx0OiAgLy8gUmVwZWF0ZWRTdHJpbmdGaWVsZEdlbmVyYXRvciBoYW5kbGVzIHVua25vd24gY3R5cGVzLgorICAgICAgICAgIGNhc2UgRmllbGRPcHRpb25zOjpTVFJJTkc6CisgICAgICAgICAgICByZXR1cm4gbmV3IFJlcGVhdGVkU3RyaW5nRmllbGRHZW5lcmF0b3IoZmllbGQsIG9wdGlvbnMpOworICAgICAgICB9CisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9FTlVNOgorICAgICAgICByZXR1cm4gbmV3IFJlcGVhdGVkRW51bUZpZWxkR2VuZXJhdG9yKGZpZWxkLCBvcHRpb25zKTsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHJldHVybiBuZXcgUmVwZWF0ZWRQcmltaXRpdmVGaWVsZEdlbmVyYXRvcihmaWVsZCwgb3B0aW9ucyk7CisgICAgfQorICB9IGVsc2UgaWYgKGZpZWxkLT5jb250YWluaW5nX29uZW9mKCkpIHsKKyAgICBzd2l0Y2ggKGZpZWxkLT5jcHBfdHlwZSgpKSB7CisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgICByZXR1cm4gbmV3IE1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yKGZpZWxkLCBvcHRpb25zKTsKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORzoKKyAgICAgICAgc3dpdGNoIChmaWVsZC0+b3B0aW9ucygpLmN0eXBlKCkpIHsKKyAgICAgICAgICBkZWZhdWx0OiAgLy8gU3RyaW5nT25lb2ZGaWVsZEdlbmVyYXRvciBoYW5kbGVzIHVua25vd24gY3R5cGVzLgorICAgICAgICAgIGNhc2UgRmllbGRPcHRpb25zOjpTVFJJTkc6CisgICAgICAgICAgICByZXR1cm4gbmV3IFN0cmluZ09uZW9mRmllbGRHZW5lcmF0b3IoZmllbGQsIG9wdGlvbnMpOworICAgICAgICB9CisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9FTlVNOgorICAgICAgICByZXR1cm4gbmV3IEVudW1PbmVvZkZpZWxkR2VuZXJhdG9yKGZpZWxkLCBvcHRpb25zKTsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHJldHVybiBuZXcgUHJpbWl0aXZlT25lb2ZGaWVsZEdlbmVyYXRvcihmaWVsZCwgb3B0aW9ucyk7CisgICAgfQorICB9IGVsc2UgeworICAgIHN3aXRjaCAoZmllbGQtPmNwcF90eXBlKCkpIHsKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U6CisgICAgICAgIHJldHVybiBuZXcgTWVzc2FnZUZpZWxkR2VuZXJhdG9yKGZpZWxkLCBvcHRpb25zKTsKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORzoKKyAgICAgICAgc3dpdGNoIChmaWVsZC0+b3B0aW9ucygpLmN0eXBlKCkpIHsKKyAgICAgICAgICBkZWZhdWx0OiAgLy8gU3RyaW5nRmllbGRHZW5lcmF0b3IgaGFuZGxlcyB1bmtub3duIGN0eXBlcy4KKyAgICAgICAgICBjYXNlIEZpZWxkT3B0aW9uczo6U1RSSU5HOgorICAgICAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmdGaWVsZEdlbmVyYXRvcihmaWVsZCwgb3B0aW9ucyk7CisgICAgICAgIH0KKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0VOVU06CisgICAgICAgIHJldHVybiBuZXcgRW51bUZpZWxkR2VuZXJhdG9yKGZpZWxkLCBvcHRpb25zKTsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHJldHVybiBuZXcgUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IoZmllbGQsIG9wdGlvbnMpOworICAgIH0KKyAgfQorfQorCitGaWVsZEdlbmVyYXRvck1hcDo6fkZpZWxkR2VuZXJhdG9yTWFwKCkge30KKworY29uc3QgRmllbGRHZW5lcmF0b3ImIEZpZWxkR2VuZXJhdG9yTWFwOjpnZXQoCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3QgeworICBHT09HTEVfQ0hFQ0tfRVEoZmllbGQtPmNvbnRhaW5pbmdfdHlwZSgpLCBkZXNjcmlwdG9yXyk7CisgIHJldHVybiAqZmllbGRfZ2VuZXJhdG9yc19bZmllbGQtPmluZGV4KCldOworfQorCisKK30gIC8vIG5hbWVzcGFjZSBjcHAKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZmllbGQuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9maWVsZC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFkN2Y4MjMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZmllbGQuaApAQCAtMCwwICsxLDIyNSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DUFBfRklFTERfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DUFBfRklFTERfSF9fCisKKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorI2luY2x1ZGUgPHN0cmluZz4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfb3B0aW9ucy5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisgIG5hbWVzcGFjZSBpbyB7CisgICAgY2xhc3MgUHJpbnRlcjsgICAgICAgICAgICAgLy8gcHJpbnRlci5oCisgIH0KK30KKworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgY3BwIHsKKworLy8gSGVscGVyIGZ1bmN0aW9uOiBzZXQgdmFyaWFibGVzIGluIHRoZSBtYXAgdGhhdCBhcmUgdGhlIHNhbWUgZm9yIGFsbAorLy8gZmllbGQgY29kZSBnZW5lcmF0b3JzLgorLy8gWyduYW1lJywgJ2luZGV4JywgJ251bWJlcicsICdjbGFzc25hbWUnLCAnZGVjbGFyZWRfdHlwZScsICd0YWdfc2l6ZScsCisvLyAnZGVwcmVjYXRpb24nXS4KK3ZvaWQgU2V0Q29tbW9uRmllbGRWYXJpYWJsZXMoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXA8c3RyaW5nLCBzdHJpbmc+KiB2YXJpYWJsZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE9wdGlvbnMmIG9wdGlvbnMpOworCit2b2lkIFNldENvbW1vbk9uZW9mRmllbGRWYXJpYWJsZXMoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcDxzdHJpbmcsIHN0cmluZz4qIHZhcmlhYmxlcyk7CisKK2NsYXNzIEZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIEZpZWxkR2VuZXJhdG9yKCkge30KKyAgdmlydHVhbCB+RmllbGRHZW5lcmF0b3IoKTsKKworICAvLyBHZW5lcmF0ZSBsaW5lcyBvZiBjb2RlIGRlY2xhcmluZyBtZW1iZXJzIGZpZWxkcyBvZiB0aGUgbWVzc2FnZSBjbGFzcworICAvLyBuZWVkZWQgdG8gcmVwcmVzZW50IHRoaXMgZmllbGQuICBUaGVzZSBhcmUgcGxhY2VkIGluc2lkZSB0aGUgbWVzc2FnZQorICAvLyBjbGFzcy4KKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlUHJpdmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0ID0gMDsKKworICAvLyBHZW5lcmF0ZSBzdGF0aWMgZGVmYXVsdCB2YXJpYWJsZSBmb3IgdGhpcyBmaWVsZC4gVGhlc2UgYXJlIHBsYWNlZCBpbnNpZGUKKyAgLy8gdGhlIG1lc3NhZ2UgY2xhc3MuIE1vc3QgZmllbGQgdHlwZXMgZG9uJ3QgbmVlZCB0aGlzLCBzbyB0aGUgZGVmYXVsdAorICAvLyBpbXBsZW1lbnRhdGlvbiBpcyBlbXB0eS4KKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlU3RhdGljTWVtYmVycyhpbzo6UHJpbnRlciogLypwcmludGVyKi8pIGNvbnN0IHt9CisKKyAgLy8gR2VuZXJhdGUgcHJvdG90eXBlcyBmb3IgYWNjZXNzb3JzIHRoYXQgd2lsbCBtYW5pcHVsYXRlIGltcG9ydGVkCisgIC8vIG1lc3NhZ2VzIGlubGluZS4gIFRoZXNlIGFyZSBmb3IgLnByb3RvLmggaGVhZGVycy4KKyAgLy8KKyAgLy8gSW4gLnByb3RvLmggbW9kZSwgdGhlIGhlYWRlcnMgb2YgaW1wb3J0cyBhcmUgbm90ICNpbmNsdWRlZC4gSG93ZXZlciwKKyAgLy8gZnVuY3Rpb25zIHRoYXQgbWFuaXB1bGF0ZSB0aGUgaW1wb3J0ZWQgbWVzc2FnZSB0eXBlcyBuZWVkIGFjY2VzcyB0bworICAvLyB0aGUgY2xhc3MgZGVmaW5pdGlvbiBvZiB0aGUgaW1wb3J0ZWQgbWVzc2FnZSwgbWVhbmluZyB0aGF0IHRoZSBoZWFkZXJzCisgIC8vIG11c3QgYmUgI2luY2x1ZGVkLiBUbyBnZXQgYXJvdW5kIHRoaXMsIGZ1bmN0aW9ucyB0aGF0IG1hbmlwdWxhdGUKKyAgLy8gaW1wb3J0ZWQgbWVzc2FnZSBvYmplY3RzIGFyZSBkZWZpbmVkIGFzIGRlcGVuZGVudCBmdW5jdGlvbnMgaW4gYSBiYXNlCisgIC8vIHRlbXBsYXRlIGNsYXNzLiBCeSBtYWtpbmcgdGhlbSBkZXBlbmRlbnQgdGVtcGxhdGUgZnVuY3Rpb25zLCB0aGUKKyAgLy8gZnVuY3Rpb24gdGVtcGxhdGVzIHdpbGwgbm90IGJlIGluc3RhbnRpYXRlZCB1bnRpbCB0aGV5IGFyZSBjYWxsZWQsIHNvCisgIC8vIHdlIGNhbiBkZWZlciB0byB0aG9zZSB0cmFuc2xhdGlvbiB1bml0cyB0byAjaW5jbHVkZSB0aGUgbmVjZXNzYXJ5CisgIC8vIGdlbmVyYXRlZCBoZWFkZXJzLgorICAvLworICAvLyBTZWU6CisgIC8vIGh0dHA6Ly9lbi5jcHByZWZlcmVuY2UuY29tL3cvY3BwL2xhbmd1YWdlL2NsYXNzX3RlbXBsYXRlI0ltcGxpY2l0X2luc3RhbnRpYXRpb24KKyAgLy8KKyAgLy8gTW9zdCBmaWVsZCB0eXBlcyBkb24ndCBuZWVkIHRoaXMsIHNvIHRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIGlzIGVtcHR5LgorICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVEZXBlbmRlbnRBY2Nlc3NvckRlY2xhcmF0aW9ucygKKyAgICAgIGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7fQorCisgIC8vIEdlbmVyYXRlIHByb3RvdHlwZXMgZm9yIGFsbCBvZiB0aGUgYWNjZXNzb3IgZnVuY3Rpb25zIHJlbGF0ZWQgdG8gdGhpcworICAvLyBmaWVsZC4gIFRoZXNlIGFyZSBwbGFjZWQgaW5zaWRlIHRoZSBjbGFzcyBkZWZpbml0aW9uLgorICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVBY2Nlc3NvckRlY2xhcmF0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgPSAwOworCisgIC8vIEdlbmVyYXRlIGlubGluZSBkZWZpbml0aW9ucyBvZiBkZXBlbmVudCBhY2Nlc3NvciBmdW5jdGlvbnMgZm9yIHRoaXMgZmllbGQuCisgIC8vIFRoZXNlIGFyZSBwbGFjZWQgaW5zaWRlIHRoZSBoZWFkZXIgYWZ0ZXIgYWxsIGNsYXNzIGRlZmluaXRpb25zLgorICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVEZXBlbmRlbnRJbmxpbmVBY2Nlc3NvckRlZmluaXRpb25zKAorICAgIGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7fQorCisgIC8vIEdlbmVyYXRlIGlubGluZSBkZWZpbml0aW9ucyBvZiBhY2Nlc3NvciBmdW5jdGlvbnMgZm9yIHRoaXMgZmllbGQuCisgIC8vIFRoZXNlIGFyZSBwbGFjZWQgaW5zaWRlIHRoZSBoZWFkZXIgYWZ0ZXIgYWxsIGNsYXNzIGRlZmluaXRpb25zLgorICAvLyBJbiBub24tLnByb3RvLmggbW9kZSwgdGhpcyBnZW5lcmF0ZXMgZGVwZW5kZW50IGFjY2Vzc29yIGZ1bmN0aW9ucyBhcyB3ZWxsLgorICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVJbmxpbmVBY2Nlc3NvckRlZmluaXRpb25zKAorICAgIGlvOjpQcmludGVyKiBwcmludGVyLCBib29sIGlzX2lubGluZSkgY29uc3QgPSAwOworCisgIC8vIEdlbmVyYXRlIGRlZmluaXRpb25zIG9mIGFjY2Vzc29ycyB0aGF0IGFyZW4ndCBpbmxpbmVkLiAgVGhlc2UgYXJlCisgIC8vIHBsYWNlZCBzb21ld2hlcmUgaW4gdGhlIC5jYyBmaWxlLgorICAvLyBNb3N0IGZpZWxkIHR5cGVzIGRvbid0IG5lZWQgdGhpcywgc28gdGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gaXMgZW1wdHkuCisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZU5vbklubGluZUFjY2Vzc29yRGVmaW5pdGlvbnMoCisgICAgaW86OlByaW50ZXIqIC8qcHJpbnRlciovKSBjb25zdCB7fQorCisgIC8vIEdlbmVyYXRlIGxpbmVzIG9mIGNvZGUgKHN0YXRlbWVudHMsIG5vdCBkZWNsYXJhdGlvbnMpIHdoaWNoIGNsZWFyIHRoZQorICAvLyBmaWVsZC4gIFRoaXMgaXMgdXNlZCB0byBkZWZpbmUgdGhlIGNsZWFyXyRuYW1lJCgpIG1ldGhvZCBhcyB3ZWxsIGFzCisgIC8vIHRoZSBDbGVhcigpIG1ldGhvZCBmb3IgdGhlIHdob2xlIG1lc3NhZ2UuCisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZUNsZWFyaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgPSAwOworCisgIC8vIEdlbmVyYXRlIGxpbmVzIG9mIGNvZGUgKHN0YXRlbWVudHMsIG5vdCBkZWNsYXJhdGlvbnMpIHdoaWNoIG1lcmdlcyB0aGUKKyAgLy8gY29udGVudHMgb2YgdGhlIGZpZWxkIGZyb20gdGhlIGN1cnJlbnQgbWVzc2FnZSB0byB0aGUgdGFyZ2V0IG1lc3NhZ2UsCisgIC8vIHdoaWNoIGlzIHN0b3JlZCBpbiB0aGUgZ2VuZXJhdGVkIGNvZGUgdmFyaWFibGUgImZyb20iLgorICAvLyBUaGlzIGlzIHVzZWQgdG8gZmlsbCBpbiB0aGUgTWVyZ2VGcm9tIG1ldGhvZCBmb3IgdGhlIHdob2xlIG1lc3NhZ2UuCisgIC8vIERldGFpbHMgb2YgdGhpcyB1c2FnZSBjYW4gYmUgZm91bmQgaW4gbWVzc2FnZS5jYyB1bmRlciB0aGUKKyAgLy8gR2VuZXJhdGVNZXJnZUZyb20gbWV0aG9kLgorICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgPSAwOworCisgIC8vIEdlbmVyYXRlIGxpbmVzIG9mIGNvZGUgKHN0YXRlbWVudHMsIG5vdCBkZWNsYXJhdGlvbnMpIHdoaWNoIHN3YXBzCisgIC8vIHRoaXMgZmllbGQgYW5kIHRoZSBjb3JyZXNwb25kaW5nIGZpZWxkIG9mIGFub3RoZXIgbWVzc2FnZSwgd2hpY2gKKyAgLy8gaXMgc3RvcmVkIGluIHRoZSBnZW5lcmF0ZWQgY29kZSB2YXJpYWJsZSAib3RoZXIiLiBUaGlzIGlzIHVzZWQgdG8KKyAgLy8gZGVmaW5lIHRoZSBTd2FwIG1ldGhvZC4gRGV0YWlscyBvZiB1c2FnZSBjYW4gYmUgZm91bmQgaW4KKyAgLy8gbWVzc2FnZS5jYyB1bmRlciB0aGUgR2VuZXJhdGVTd2FwIG1ldGhvZC4KKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlU3dhcHBpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCA9IDA7CisKKyAgLy8gR2VuZXJhdGUgaW5pdGlhbGl6YXRpb24gY29kZSBmb3IgcHJpdmF0ZSBtZW1iZXJzIGRlY2xhcmVkIGJ5CisgIC8vIEdlbmVyYXRlUHJpdmF0ZU1lbWJlcnMoKS4gVGhlc2UgZ28gaW50byB0aGUgbWVzc2FnZSBjbGFzcydzIFNoYXJlZEN0b3IoKQorICAvLyBtZXRob2QsIGludm9rZWQgYnkgZWFjaCBvZiB0aGUgZ2VuZXJhdGVkIGNvbnN0cnVjdG9ycy4KKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlQ29uc3RydWN0b3JDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCA9IDA7CisKKyAgLy8gR2VuZXJhdGUgYW55IGNvZGUgdGhhdCBuZWVkcyB0byBnbyBpbiB0aGUgY2xhc3MncyBTaGFyZWREdG9yKCkgbWV0aG9kLAorICAvLyBpbnZva2VkIGJ5IHRoZSBkZXN0cnVjdG9yLgorICAvLyBNb3N0IGZpZWxkIHR5cGVzIGRvbid0IG5lZWQgdGhpcywgc28gdGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gaXMgZW1wdHkuCisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZURlc3RydWN0b3JDb2RlKGlvOjpQcmludGVyKiAvKnByaW50ZXIqLykgY29uc3Qge30KKworICAvLyBHZW5lcmF0ZSBhIG1hbnVhbCBkZXN0cnVjdG9yIGludm9jYXRpb24gZm9yIHVzZSB3aGVuIHRoZSBtZXNzYWdlIGlzIG9uIGFuCisgIC8vIGFyZW5hLiBUaGUgY29kZSB0aGF0IHRoaXMgbWV0aG9kIGdlbmVyYXRlcyB3aWxsIGJlIGV4ZWN1dGVkIGluc2lkZSBhCisgIC8vIHNoYXJlZC1mb3ItdGhlLXdob2xlLW1lc3NhZ2UtY2xhc3MgbWV0aG9kIHJlZ2lzdGVyZWQgd2l0aCBPd25EZXN0cnVjdG9yKCkuCisgIC8vIFRoZSBtZXRob2Qgc2hvdWxkIHJldHVybiB8dHJ1ZXwgaWYgaXQgZ2VuZXJhdGVkIGFueSBjb2RlIHRoYXQgcmVxdWlyZXMgYQorICAvLyBjYWxsOyB0aGlzIGFsbG93cyB0aGUgbWVzc2FnZSBnZW5lcmF0b3IgdG8gZWxpbWluYXRlIHRoZSBPd25EZXN0cnVjdG9yKCkKKyAgLy8gcmVnaXN0cmF0aW9uIGlmIG5vIGZpZWxkcyByZXF1aXJlIGl0LgorICB2aXJ0dWFsIGJvb2wgR2VuZXJhdGVBcmVuYURlc3RydWN0b3JDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8gR2VuZXJhdGUgY29kZSB0aGF0IGFsbG9jYXRlcyB0aGUgZmllbGRzJ3MgZGVmYXVsdCBpbnN0YW5jZS4KKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlRGVmYXVsdEluc3RhbmNlQWxsb2NhdG9yKGlvOjpQcmludGVyKiAvKnByaW50ZXIqLykKKyAgICAgIGNvbnN0IHt9CisKKyAgLy8gR2VuZXJhdGUgY29kZSB0aGF0IHNob3VsZCBiZSBydW4gd2hlbiBTaHV0ZG93blByb3RvYnVmTGlicmFyeSgpIGlzIGNhbGxlZCwKKyAgLy8gdG8gZGVsZXRlIGFsbCBkeW5hbWljYWxseS1hbGxvY2F0ZWQgb2JqZWN0cy4KKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlU2h1dGRvd25Db2RlKGlvOjpQcmludGVyKiAvKnByaW50ZXIqLykgY29uc3Qge30KKworICAvLyBHZW5lcmF0ZSBsaW5lcyB0byBkZWNvZGUgdGhpcyBmaWVsZCwgd2hpY2ggd2lsbCBiZSBwbGFjZWQgaW5zaWRlIHRoZQorICAvLyBtZXNzYWdlJ3MgTWVyZ2VGcm9tQ29kZWRTdHJlYW0oKSBtZXRob2QuCisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZU1lcmdlRnJvbUNvZGVkU3RyZWFtKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCA9IDA7CisKKyAgLy8gR2VuZXJhdGUgbGluZXMgdG8gZGVjb2RlIHRoaXMgZmllbGQgZnJvbSBhIHBhY2tlZCB2YWx1ZSwgd2hpY2ggd2lsbCBiZQorICAvLyBwbGFjZWQgaW5zaWRlIHRoZSBtZXNzYWdlJ3MgTWVyZ2VGcm9tQ29kZWRTdHJlYW0oKSBtZXRob2QuCisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZU1lcmdlRnJvbUNvZGVkU3RyZWFtV2l0aFBhY2tpbmcoaW86OlByaW50ZXIqIHByaW50ZXIpCisgICAgICBjb25zdDsKKworICAvLyBHZW5lcmF0ZSBsaW5lcyB0byBzZXJpYWxpemUgdGhpcyBmaWVsZCwgd2hpY2ggYXJlIHBsYWNlZCB3aXRoaW4gdGhlCisgIC8vIG1lc3NhZ2UncyBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoKSBtZXRob2QuCisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgPSAwOworCisgIC8vIEdlbmVyYXRlIGxpbmVzIHRvIHNlcmlhbGl6ZSB0aGlzIGZpZWxkIGRpcmVjdGx5IHRvIHRoZSBhcnJheSAidGFyZ2V0IiwKKyAgLy8gd2hpY2ggYXJlIHBsYWNlZCB3aXRoaW4gdGhlIG1lc3NhZ2UncyBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KCkKKyAgLy8gbWV0aG9kLiBUaGlzIG11c3QgYWxzbyBhZHZhbmNlICJ0YXJnZXQiIHBhc3QgdGhlIHdyaXR0ZW4gYnl0ZXMuCisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoCisgICAgICBpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgPSAwOworCisgIC8vIEdlbmVyYXRlIGxpbmVzIHRvIGNvbXB1dGUgdGhlIHNlcmlhbGl6ZWQgc2l6ZSBvZiB0aGlzIGZpZWxkLCB3aGljaAorICAvLyBhcmUgcGxhY2VkIGluIHRoZSBtZXNzYWdlJ3MgQnl0ZVNpemUoKSBtZXRob2QuCisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZUJ5dGVTaXplKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCA9IDA7CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoRmllbGRHZW5lcmF0b3IpOworfTsKKworLy8gQ29udmVuaWVuY2UgY2xhc3Mgd2hpY2ggY29uc3RydWN0cyBGaWVsZEdlbmVyYXRvcnMgZm9yIGEgRGVzY3JpcHRvci4KK2NsYXNzIEZpZWxkR2VuZXJhdG9yTWFwIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IEZpZWxkR2VuZXJhdG9yTWFwKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGNvbnN0IE9wdGlvbnMmIG9wdGlvbnMpOworICB+RmllbGRHZW5lcmF0b3JNYXAoKTsKKworICBjb25zdCBGaWVsZEdlbmVyYXRvciYgZ2V0KGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcl87CisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9hcnJheTxnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPEZpZWxkR2VuZXJhdG9yPiA+IGZpZWxkX2dlbmVyYXRvcnNfOworCisgIHN0YXRpYyBGaWVsZEdlbmVyYXRvciogTWFrZUdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT3B0aW9ucyYgb3B0aW9ucyk7CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEZpZWxkR2VuZXJhdG9yTWFwKTsKK307CisKKworfSAgLy8gbmFtZXNwYWNlIGNwcAorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1BQX0ZJRUxEX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2ZpbGUuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZmlsZS5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zN2U0YmFlCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2ZpbGUuY2MKQEAgLTAsMCArMSwxMDQzIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9maWxlLmg+CisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPG1lbW9yeT4KKyNpZm5kZWYgX1NIQVJFRF9QVFJfSAorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaGFyZWRfcHRyLmg+CisjZW5kaWYKKyNpbmNsdWRlIDxzZXQ+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9lbnVtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfc2VydmljZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2V4dGVuc2lvbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9tZXNzYWdlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBjcHAgeworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK0ZpbGVHZW5lcmF0b3I6OkZpbGVHZW5lcmF0b3IoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUsIGNvbnN0IE9wdGlvbnMmIG9wdGlvbnMpCisgICAgOiBmaWxlXyhmaWxlKSwKKyAgICAgIG1lc3NhZ2VfZ2VuZXJhdG9yc18oCisgICAgICAgICAgbmV3IGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8TWVzc2FnZUdlbmVyYXRvcj5bZmlsZS0+bWVzc2FnZV90eXBlX2NvdW50KCldKSwKKyAgICAgIGVudW1fZ2VuZXJhdG9yc18oCisgICAgICAgICAgbmV3IGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8RW51bUdlbmVyYXRvcj5bZmlsZS0+ZW51bV90eXBlX2NvdW50KCldKSwKKyAgICAgIHNlcnZpY2VfZ2VuZXJhdG9yc18oCisgICAgICAgICAgbmV3IGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8U2VydmljZUdlbmVyYXRvcj5bZmlsZS0+c2VydmljZV9jb3VudCgpXSksCisgICAgICBleHRlbnNpb25fZ2VuZXJhdG9yc18oCisgICAgICAgICAgbmV3IGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8RXh0ZW5zaW9uR2VuZXJhdG9yPltmaWxlLT5leHRlbnNpb25fY291bnQoKV0pLAorICAgICAgb3B0aW9uc18ob3B0aW9ucykgeworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZS0+bWVzc2FnZV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIG1lc3NhZ2VfZ2VuZXJhdG9yc19baV0ucmVzZXQoCisgICAgICBuZXcgTWVzc2FnZUdlbmVyYXRvcihmaWxlLT5tZXNzYWdlX3R5cGUoaSksIG9wdGlvbnMpKTsKKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZS0+ZW51bV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIGVudW1fZ2VuZXJhdG9yc19baV0ucmVzZXQoCisgICAgICBuZXcgRW51bUdlbmVyYXRvcihmaWxlLT5lbnVtX3R5cGUoaSksIG9wdGlvbnMpKTsKKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZS0+c2VydmljZV9jb3VudCgpOyBpKyspIHsKKyAgICBzZXJ2aWNlX2dlbmVyYXRvcnNfW2ldLnJlc2V0KAorICAgICAgbmV3IFNlcnZpY2VHZW5lcmF0b3IoZmlsZS0+c2VydmljZShpKSwgb3B0aW9ucykpOworICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlLT5leHRlbnNpb25fY291bnQoKTsgaSsrKSB7CisgICAgZXh0ZW5zaW9uX2dlbmVyYXRvcnNfW2ldLnJlc2V0KAorICAgICAgbmV3IEV4dGVuc2lvbkdlbmVyYXRvcihmaWxlLT5leHRlbnNpb24oaSksIG9wdGlvbnMpKTsKKyAgfQorCisgIFNwbGl0U3RyaW5nVXNpbmcoZmlsZV8tPnBhY2thZ2UoKSwgIi4iLCAmcGFja2FnZV9wYXJ0c18pOworfQorCitGaWxlR2VuZXJhdG9yOjp+RmlsZUdlbmVyYXRvcigpIHt9CisKK3ZvaWQgRmlsZUdlbmVyYXRvcjo6R2VuZXJhdGVQcm90b0hlYWRlcihpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBpZiAoIW9wdGlvbnNfLnByb3RvX2gpIHsKKyAgICByZXR1cm47CisgIH0KKworICBzdHJpbmcgZmlsZW5hbWVfaWRlbnRpZmllciA9IEZpbGVuYW1lSWRlbnRpZmllcihmaWxlXy0+bmFtZSgpKTsKKyAgR2VuZXJhdGVUb3BIZWFkZXJHdWFyZChwcmludGVyLCBmaWxlbmFtZV9pZGVudGlmaWVyKTsKKworCisgIEdlbmVyYXRlTGlicmFyeUluY2x1ZGVzKHByaW50ZXIpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPnB1YmxpY19kZXBlbmRlbmN5X2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBkZXAgPSBmaWxlXy0+cHVibGljX2RlcGVuZGVuY3koaSk7CisgICAgY29uc3QgY2hhciogZXh0ZW5zaW9uID0gIi5wcm90by5oIjsKKyAgICBzdHJpbmcgZGVwZW5kZW5jeSA9IFN0cmlwUHJvdG8oZGVwLT5uYW1lKCkpICsgZXh0ZW5zaW9uOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIiNpbmNsdWRlIFwiJGRlcGVuZGVuY3kkXCIgIC8vIElXWVUgcHJhZ21hOiBleHBvcnRcbiIsCisgICAgICAiZGVwZW5kZW5jeSIsIGRlcGVuZGVuY3kpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIi8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbmNsdWRlcylcbiIpOworCisKKyAgR2VuZXJhdGVGb3J3YXJkRGVjbGFyYXRpb25zKHByaW50ZXIpOworCisgIC8vIE9wZW4gbmFtZXNwYWNlLgorICBHZW5lcmF0ZU5hbWVzcGFjZU9wZW5lcnMocHJpbnRlcik7CisKKyAgR2VuZXJhdGVHbG9iYWxTdGF0ZUZ1bmN0aW9uRGVjbGFyYXRpb25zKHByaW50ZXIpOworCisgIHByaW50ZXItPlByaW50KCJcbiIpOworCisgIEdlbmVyYXRlRW51bURlZmluaXRpb25zKHByaW50ZXIpOworCisgIHByaW50ZXItPlByaW50KGtUaGlja1NlcGFyYXRvcik7CisgIHByaW50ZXItPlByaW50KCJcbiIpOworCisgIEdlbmVyYXRlTWVzc2FnZURlZmluaXRpb25zKHByaW50ZXIpOworCisgIHByaW50ZXItPlByaW50KCJcbiIpOworICBwcmludGVyLT5QcmludChrVGhpY2tTZXBhcmF0b3IpOworICBwcmludGVyLT5QcmludCgiXG4iKTsKKworICBHZW5lcmF0ZVNlcnZpY2VEZWZpbml0aW9ucyhwcmludGVyKTsKKworICBHZW5lcmF0ZUV4dGVuc2lvbklkZW50aWZpZXJzKHByaW50ZXIpOworCisgIHByaW50ZXItPlByaW50KCJcbiIpOworICBwcmludGVyLT5QcmludChrVGhpY2tTZXBhcmF0b3IpOworICBwcmludGVyLT5QcmludCgiXG4iKTsKKworICBHZW5lcmF0ZUlubGluZUZ1bmN0aW9uRGVmaW5pdGlvbnMocHJpbnRlcik7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIlxuIgorICAgICIvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobmFtZXNwYWNlX3Njb3BlKVxuIgorICAgICJcbiIpOworCisgIC8vIENsb3NlIHVwIG5hbWVzcGFjZS4KKyAgR2VuZXJhdGVOYW1lc3BhY2VDbG9zZXJzKHByaW50ZXIpOworCisgIC8vIFdlIG5lZWQgdG8gc3BlY2lhbGl6ZSBzb21lIHRlbXBsYXRlcyBpbiB0aGUgOjpnb29nbGU6OnByb3RvYnVmIG5hbWVzcGFjZToKKyAgR2VuZXJhdGVQcm90bzJOYW1lc3BhY2VFbnVtU3BlY2lhbGl6YXRpb25zKHByaW50ZXIpOworCisgIHByaW50ZXItPlByaW50KAorICAgICJcbiIKKyAgICAiLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGdsb2JhbF9zY29wZSlcbiIKKyAgICAiXG4iKTsKKworICBHZW5lcmF0ZUJvdHRvbUhlYWRlckd1YXJkKHByaW50ZXIsIGZpbGVuYW1lX2lkZW50aWZpZXIpOworfQorCit2b2lkIEZpbGVHZW5lcmF0b3I6OkdlbmVyYXRlUEJIZWFkZXIoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgc3RyaW5nIGZpbGVuYW1lX2lkZW50aWZpZXIgPQorICAgICAgRmlsZW5hbWVJZGVudGlmaWVyKGZpbGVfLT5uYW1lKCkgKyAob3B0aW9uc18ucHJvdG9faCA/ICIucGIuaCIgOiAiIikpOworICBHZW5lcmF0ZVRvcEhlYWRlckd1YXJkKHByaW50ZXIsIGZpbGVuYW1lX2lkZW50aWZpZXIpOworCisgIGlmIChvcHRpb25zXy5wcm90b19oKSB7CisgICAgcHJpbnRlci0+UHJpbnQoIiNpbmNsdWRlIFwiJGJhc2VuYW1lJC5wcm90by5oXCIgIC8vIElXWVUgcHJhZ21hOiBleHBvcnRcbiIsCisgICAgICAgICAgICAgICAgICAgImJhc2VuYW1lIiwgU3RyaXBQcm90byhmaWxlXy0+bmFtZSgpKSk7CisgIH0gZWxzZSB7CisgICAgR2VuZXJhdGVMaWJyYXJ5SW5jbHVkZXMocHJpbnRlcik7CisgIH0KKyAgR2VuZXJhdGVEZXBlbmRlbmN5SW5jbHVkZXMocHJpbnRlcik7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIi8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbmNsdWRlcylcbiIpOworCisKKworICAvLyBPcGVuIG5hbWVzcGFjZS4KKyAgR2VuZXJhdGVOYW1lc3BhY2VPcGVuZXJzKHByaW50ZXIpOworCisgIGlmICghb3B0aW9uc18ucHJvdG9faCkgeworICAgIEdlbmVyYXRlR2xvYmFsU3RhdGVGdW5jdGlvbkRlY2xhcmF0aW9ucyhwcmludGVyKTsKKyAgICBHZW5lcmF0ZU1lc3NhZ2VGb3J3YXJkRGVjbGFyYXRpb25zKHByaW50ZXIpOworCisgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisKKyAgICBHZW5lcmF0ZUVudW1EZWZpbml0aW9ucyhwcmludGVyKTsKKworICAgIHByaW50ZXItPlByaW50KGtUaGlja1NlcGFyYXRvcik7CisgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisKKyAgICBHZW5lcmF0ZU1lc3NhZ2VEZWZpbml0aW9ucyhwcmludGVyKTsKKworICAgIHByaW50ZXItPlByaW50KCJcbiIpOworICAgIHByaW50ZXItPlByaW50KGtUaGlja1NlcGFyYXRvcik7CisgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisKKyAgICBHZW5lcmF0ZVNlcnZpY2VEZWZpbml0aW9ucyhwcmludGVyKTsKKworICAgIEdlbmVyYXRlRXh0ZW5zaW9uSWRlbnRpZmllcnMocHJpbnRlcik7CisKKyAgICBwcmludGVyLT5QcmludCgiXG4iKTsKKyAgICBwcmludGVyLT5QcmludChrVGhpY2tTZXBhcmF0b3IpOworICAgIHByaW50ZXItPlByaW50KCJcbiIpOworCisgICAgR2VuZXJhdGVJbmxpbmVGdW5jdGlvbkRlZmluaXRpb25zKHByaW50ZXIpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIlxuIgorICAgICIvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobmFtZXNwYWNlX3Njb3BlKVxuIik7CisKKyAgLy8gQ2xvc2UgdXAgbmFtZXNwYWNlLgorICBHZW5lcmF0ZU5hbWVzcGFjZUNsb3NlcnMocHJpbnRlcik7CisKKyAgaWYgKCFvcHRpb25zXy5wcm90b19oKSB7CisgICAgLy8gV2UgbmVlZCB0byBzcGVjaWFsaXplIHNvbWUgdGVtcGxhdGVzIGluIHRoZSA6Omdvb2dsZTo6cHJvdG9idWYgbmFtZXNwYWNlOgorICAgIEdlbmVyYXRlUHJvdG8yTmFtZXNwYWNlRW51bVNwZWNpYWxpemF0aW9ucyhwcmludGVyKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KAorICAgICJcbiIKKyAgICAiLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGdsb2JhbF9zY29wZSlcbiIKKyAgICAiXG4iKTsKKworICBHZW5lcmF0ZUJvdHRvbUhlYWRlckd1YXJkKHByaW50ZXIsIGZpbGVuYW1lX2lkZW50aWZpZXIpOworfQorCit2b2lkIEZpbGVHZW5lcmF0b3I6OkdlbmVyYXRlU291cmNlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIGJvb2wgd2VsbF9rbm93biA9IElzV2VsbEtub3duTWVzc2FnZShmaWxlXyk7CisgIHN0cmluZyBoZWFkZXIgPQorICAgICAgU3RyaXBQcm90byhmaWxlXy0+bmFtZSgpKSArIChvcHRpb25zXy5wcm90b19oID8gIi5wcm90by5oIiA6ICIucGIuaCIpOworICBwcmludGVyLT5QcmludCgKKyAgICAiLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCFcbiIKKyAgICAiLy8gc291cmNlOiAkZmlsZW5hbWUkXG4iCisgICAgIlxuIgorICAgIC8vIFRoZSBnZW5lcmF0ZWQgY29kZSBjYWxscyBhY2Nlc3NvcnMgdGhhdCBtaWdodCBiZSBkZXByZWNhdGVkLiBXZSBkb24ndAorICAgIC8vIHdhbnQgdGhlIGNvbXBpbGVyIHRvIHdhcm4gaW4gZ2VuZXJhdGVkIGNvZGUuCisgICAgIiNkZWZpbmUgSU5URVJOQUxfU1VQUFJFU1NfUFJPVE9CVUZfRklFTERfREVQUkVDQVRJT05cbiIKKyAgICAiI2luY2x1ZGUgJGxlZnQkJGhlYWRlciQkcmlnaHQkXG4iCisgICAgIlxuIgorICAgICIjaW5jbHVkZSA8YWxnb3JpdGhtPlxuIiAgICAvLyBmb3Igc3dhcCgpCisgICAgIlxuIgorICAgICIjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPlxuIgorICAgICIjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3BvcnQuaD5cbiIKKyAgICAiI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9vbmNlLmg+XG4iCisgICAgIiNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmg+XG4iCisgICAgIiNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZV9pbmwuaD5cbiIsCisgICAgImZpbGVuYW1lIiwgZmlsZV8tPm5hbWUoKSwKKyAgICAiaGVhZGVyIiwgaGVhZGVyLAorICAgICJsZWZ0Iiwgd2VsbF9rbm93biA/ICI8IiA6ICJcIiIsCisgICAgInJpZ2h0Iiwgd2VsbF9rbm93biA/ICI+IiA6ICJcIiIpOworCisgIC8vIFVua25vd24gZmllbGRzIGltcGxlbWVudGF0aW9uIGluIGxpdGUgbW9kZSB1c2VzIFN0cmluZ091dHB1dFN0cmVhbQorICBpZiAoIVVzZVVua25vd25GaWVsZFNldChmaWxlXykgJiYgZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpID4gMCkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIiNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbV9pbXBsX2xpdGUuaD5cbiIpOworICB9CisKKyAgaWYgKEhhc0Rlc2NyaXB0b3JNZXRob2RzKGZpbGVfKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIiNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPlxuIgorICAgICAgIiNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX21lc3NhZ2VfcmVmbGVjdGlvbi5oPlxuIgorICAgICAgIiNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcmVmbGVjdGlvbl9vcHMuaD5cbiIKKyAgICAgICIjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0Lmg+XG4iKTsKKyAgfQorCisgIGlmIChvcHRpb25zXy5wcm90b19oKSB7CisgICAgLy8gVXNlIHRoZSBzbWFsbGVyIC5wcm90by5oIGZpbGVzLgorICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPmRlcGVuZGVuY3lfY291bnQoKTsgaSsrKSB7CisgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvciogZGVwID0gZmlsZV8tPmRlcGVuZGVuY3koaSk7CisgICAgICBjb25zdCBjaGFyKiBleHRlbnNpb24gPSAiLnByb3RvLmgiOworICAgICAgc3RyaW5nIGRlcGVuZGVuY3kgPSBTdHJpcFByb3RvKGRlcC0+bmFtZSgpKSArIGV4dGVuc2lvbjsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICIjaW5jbHVkZSBcIiRkZXBlbmRlbmN5JFwiXG4iLAorICAgICAgICAgICJkZXBlbmRlbmN5IiwgZGVwZW5kZW5jeSk7CisgICAgfQorICB9CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIi8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbmNsdWRlcylcbiIpOworCisgIEdlbmVyYXRlTmFtZXNwYWNlT3BlbmVycyhwcmludGVyKTsKKworICBpZiAoSGFzRGVzY3JpcHRvck1ldGhvZHMoZmlsZV8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiXG4iCisgICAgICAibmFtZXNwYWNlIHtcbiIKKyAgICAgICJcbiIpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICAgIG1lc3NhZ2VfZ2VuZXJhdG9yc19baV0tPkdlbmVyYXRlRGVzY3JpcHRvckRlY2xhcmF0aW9ucyhwcmludGVyKTsKKyAgICB9CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+ZW51bV90eXBlX2NvdW50KCk7IGkrKykgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yKiAkbmFtZSRfZGVzY3JpcHRvcl8gPSBOVUxMO1xuIiwKKyAgICAgICAgIm5hbWUiLCBDbGFzc05hbWUoZmlsZV8tPmVudW1fdHlwZShpKSwgZmFsc2UpKTsKKyAgICB9CisKKyAgICBpZiAoSGFzR2VuZXJpY1NlcnZpY2VzKGZpbGVfKSkgeworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+c2VydmljZV9jb3VudCgpOyBpKyspIHsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgImNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6U2VydmljZURlc2NyaXB0b3IqICRuYW1lJF9kZXNjcmlwdG9yXyA9IE5VTEw7XG4iLAorICAgICAgICAgICJuYW1lIiwgZmlsZV8tPnNlcnZpY2UoaSktPm5hbWUoKSk7CisgICAgICB9CisgICAgfQorCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiXG4iCisgICAgICAifSAgLy8gbmFtZXNwYWNlXG4iCisgICAgICAiXG4iKTsKKyAgfQorCisgIC8vIERlZmluZSBvdXIgZXh0ZXJuYWxseS12aXNpYmxlIEJ1aWxkRGVzY3JpcHRvcnMoKSBmdW5jdGlvbi4gIChGb3IgdGhlIGxpdGUKKyAgLy8gbGlicmFyeSwgYWxsIHRoaXMgZG9lcyBpcyBpbml0aWFsaXplIGRlZmF1bHQgaW5zdGFuY2VzLikKKyAgR2VuZXJhdGVCdWlsZERlc2NyaXB0b3JzKHByaW50ZXIpOworCisgIC8vIEdlbmVyYXRlIGVudW1zLgorICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5lbnVtX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgZW51bV9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVNZXRob2RzKHByaW50ZXIpOworICB9CisKKyAgLy8gR2VuZXJhdGUgY2xhc3Nlcy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+bWVzc2FnZV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIGlmIChpID09IDAgJiYgSGFzR2VuZXJhdGVkTWV0aG9kcyhmaWxlXykpIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICJcbiIKKyAgICAgICAgICAibmFtZXNwYWNlIHtcbiIKKyAgICAgICAgICAiXG4iCisgICAgICAgICAgInN0YXRpYyB2b2lkIE1lcmdlRnJvbUZhaWwoaW50IGxpbmUpIEdPT0dMRV9BVFRSSUJVVEVfQ09MRDtcbiIKKyAgICAgICAgICAic3RhdGljIHZvaWQgTWVyZ2VGcm9tRmFpbChpbnQgbGluZSkge1xuIgorICAgICAgICAgICIgIEdPT0dMRV9DSEVDSyhmYWxzZSkgPDwgX19GSUxFX18gPDwgXCI6XCIgPDwgbGluZTtcbiIKKyAgICAgICAgICAifVxuIgorICAgICAgICAgICJcbiIKKyAgICAgICAgICAifSAgLy8gbmFtZXNwYWNlXG4iCisgICAgICAgICAgIlxuIik7CisgICAgfQorICAgIHByaW50ZXItPlByaW50KCJcbiIpOworICAgIHByaW50ZXItPlByaW50KGtUaGlja1NlcGFyYXRvcik7CisgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisgICAgbWVzc2FnZV9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVDbGFzc01ldGhvZHMocHJpbnRlcik7CisKKyAgICBwcmludGVyLT5QcmludCgiI2lmIFBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSU1xuIik7CisgICAgLy8gR2VuZXJhdGUgY2xhc3MgaW5saW5lIG1ldGhvZHMuCisgICAgbWVzc2FnZV9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVJbmxpbmVNZXRob2RzKHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGlzX2lubGluZSA9ICovIGZhbHNlKTsKKyAgICBwcmludGVyLT5QcmludCgiI2VuZGlmICAvLyBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlNcbiIpOworICB9CisKKyAgaWYgKEhhc0dlbmVyaWNTZXJ2aWNlcyhmaWxlXykpIHsKKyAgICAvLyBHZW5lcmF0ZSBzZXJ2aWNlcy4KKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5zZXJ2aWNlX2NvdW50KCk7IGkrKykgeworICAgICAgaWYgKGkgPT0gMCkgcHJpbnRlci0+UHJpbnQoIlxuIik7CisgICAgICBwcmludGVyLT5QcmludChrVGhpY2tTZXBhcmF0b3IpOworICAgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisgICAgICBzZXJ2aWNlX2dlbmVyYXRvcnNfW2ldLT5HZW5lcmF0ZUltcGxlbWVudGF0aW9uKHByaW50ZXIpOworICAgIH0KKyAgfQorCisgIC8vIERlZmluZSBleHRlbnNpb25zLgorICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5leHRlbnNpb25fY291bnQoKTsgaSsrKSB7CisgICAgZXh0ZW5zaW9uX2dlbmVyYXRvcnNfW2ldLT5HZW5lcmF0ZURlZmluaXRpb24ocHJpbnRlcik7CisgIH0KKworICBwcmludGVyLT5QcmludCgKKyAgICAiXG4iCisgICAgIi8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChuYW1lc3BhY2Vfc2NvcGUpXG4iKTsKKworICBHZW5lcmF0ZU5hbWVzcGFjZUNsb3NlcnMocHJpbnRlcik7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIlxuIgorICAgICIvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZ2xvYmFsX3Njb3BlKVxuIik7Cit9CisKK2NsYXNzIEZpbGVHZW5lcmF0b3I6OkZvcndhcmREZWNsYXJhdGlvbnMgeworIHB1YmxpYzoKKyAgfkZvcndhcmREZWNsYXJhdGlvbnMoKSB7CisgICAgZm9yIChtYXA8c3RyaW5nLCBGb3J3YXJkRGVjbGFyYXRpb25zICo+OjppdGVyYXRvciBpdCA9IG5hbWVzcGFjZXNfLmJlZ2luKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmQgPSBuYW1lc3BhY2VzXy5lbmQoKTsKKyAgICAgICAgIGl0ICE9IGVuZDsgKytpdCkgeworICAgICAgZGVsZXRlIGl0LT5zZWNvbmQ7CisgICAgfQorICAgIG5hbWVzcGFjZXNfLmNsZWFyKCk7CisgIH0KKworICBGb3J3YXJkRGVjbGFyYXRpb25zKiBBZGRPckdldE5hbWVzcGFjZShjb25zdCBzdHJpbmcmIG5zX25hbWUpIHsKKyAgICBGb3J3YXJkRGVjbGFyYXRpb25zKiYgbnMgPSBuYW1lc3BhY2VzX1tuc19uYW1lXTsKKyAgICBpZiAobnMgPT0gTlVMTCkgeworICAgICAgbnMgPSBuZXcgRm9yd2FyZERlY2xhcmF0aW9uczsKKyAgICB9CisgICAgcmV0dXJuIG5zOworICB9CisKKyAgc2V0PHN0cmluZz4mIGNsYXNzZXMoKSB7IHJldHVybiBjbGFzc2VzXzsgfQorICBzZXQ8c3RyaW5nPiYgZW51bXMoKSB7IHJldHVybiBlbnVtc187IH0KKworICB2b2lkIFByaW50KGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgICAgZm9yIChzZXQ8c3RyaW5nPjo6Y29uc3RfaXRlcmF0b3IgaXQgPSBlbnVtc18uYmVnaW4oKSwgZW5kID0gZW51bXNfLmVuZCgpOworICAgICAgICAgaXQgIT0gZW5kOyArK2l0KSB7CisgICAgICBwcmludGVyLT5QcmludCgiZW51bSAkZW51bW5hbWUkIDogaW50O1xuIgorICAgICAgICAgICAgICAgICAgICAgImJvb2wgJGVudW1uYW1lJF9Jc1ZhbGlkKGludCB2YWx1ZSk7XG4iLAorICAgICAgICAgICAgICAgICAgICAgImVudW1uYW1lIiwgaXQtPmNfc3RyKCkpOworICAgIH0KKyAgICBmb3IgKHNldDxzdHJpbmc+Ojpjb25zdF9pdGVyYXRvciBpdCA9IGNsYXNzZXNfLmJlZ2luKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5kID0gY2xhc3Nlc18uZW5kKCk7CisgICAgICAgICBpdCAhPSBlbmQ7ICsraXQpIHsKKyAgICAgIHByaW50ZXItPlByaW50KCJjbGFzcyAkY2xhc3NuYW1lJDtcbiIsICJjbGFzc25hbWUiLCBpdC0+Y19zdHIoKSk7CisgICAgfQorICAgIGZvciAobWFwPHN0cmluZywgRm9yd2FyZERlY2xhcmF0aW9ucyAqPjo6Y29uc3RfaXRlcmF0b3IKKyAgICAgICAgICAgICBpdCA9IG5hbWVzcGFjZXNfLmJlZ2luKCksCisgICAgICAgICAgICAgZW5kID0gbmFtZXNwYWNlc18uZW5kKCk7CisgICAgICAgICBpdCAhPSBlbmQ7ICsraXQpIHsKKyAgICAgIHByaW50ZXItPlByaW50KCJuYW1lc3BhY2UgJG5zbmFtZSQge1xuIiwKKyAgICAgICAgICAgICAgICAgICAgICJuc25hbWUiLCBpdC0+Zmlyc3QpOworICAgICAgaXQtPnNlY29uZC0+UHJpbnQocHJpbnRlcik7CisgICAgICBwcmludGVyLT5QcmludCgifSAgLy8gbmFtZXNwYWNlICRuc25hbWUkXG4iLAorICAgICAgICAgICAgICAgICAgICAgIm5zbmFtZSIsIGl0LT5maXJzdCk7CisgICAgfQorICB9CisKKworIHByaXZhdGU6CisgIG1hcDxzdHJpbmcsIEZvcndhcmREZWNsYXJhdGlvbnMqPiBuYW1lc3BhY2VzXzsKKyAgc2V0PHN0cmluZz4gY2xhc3Nlc187CisgIHNldDxzdHJpbmc+IGVudW1zXzsKK307CisKK3ZvaWQgRmlsZUdlbmVyYXRvcjo6R2VuZXJhdGVCdWlsZERlc2NyaXB0b3JzKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIC8vIEFkZERlc2NyaXB0b3JzKCkgaXMgYSBmaWxlLWxldmVsIHByb2NlZHVyZSB3aGljaCBhZGRzIHRoZSBlbmNvZGVkCisgIC8vIEZpbGVEZXNjcmlwdG9yUHJvdG8gZm9yIHRoaXMgLnByb3RvIGZpbGUgdG8gdGhlIGdsb2JhbCBEZXNjcmlwdG9yUG9vbCBmb3IKKyAgLy8gZ2VuZXJhdGVkIGZpbGVzIChEZXNjcmlwdG9yUG9vbDo6Z2VuZXJhdGVkX3Bvb2woKSkuIEl0IGVpdGhlciBydW5zIGF0CisgIC8vIHN0YXRpYyBpbml0aWFsaXphdGlvbiB0aW1lIChieSBkZWZhdWx0KSBvciB3aGVuIGRlZmF1bHRfaW5zdGFuY2UoKSBpcworICAvLyBjYWxsZWQgZm9yIHRoZSBmaXJzdCB0aW1lIChpbiBMSVRFX1JVTlRJTUUgbW9kZSB3aXRoCisgIC8vIEdPT0dMRV9QUk9UT0JVRl9OT19TVEFUSUNfSU5JVElBTElaRVIgZmxhZyBlbmFibGVkKS4gVGhpcyBwcm9jZWR1cmUgYWxzbworICAvLyBjb25zdHJ1Y3RzIGRlZmF1bHQgaW5zdGFuY2VzIGFuZCByZWdpc3RlcnMgZXh0ZW5zaW9ucy4KKyAgLy8KKyAgLy8gSXRzIHNpYmxpbmcsIEFzc2lnbkRlc2NyaXB0b3JzKCksIGFjdHVhbGx5IHB1bGxzIHRoZSBjb21waWxlZAorICAvLyBGaWxlRGVzY3JpcHRvciBmcm9tIHRoZSBEZXNjcmlwdG9yUG9vbCBhbmQgdXNlcyBpdCB0byBwb3B1bGF0ZSBhbGwgb2YKKyAgLy8gdGhlIGdsb2JhbCB2YXJpYWJsZXMgd2hpY2ggc3RvcmUgcG9pbnRlcnMgdG8gdGhlIGRlc2NyaXB0b3Igb2JqZWN0cy4KKyAgLy8gSXQgYWxzbyBjb25zdHJ1Y3RzIHRoZSByZWZsZWN0aW9uIG9iamVjdHMuICBJdCBpcyBjYWxsZWQgdGhlIGZpcnN0IHRpbWUKKyAgLy8gYW55b25lIGNhbGxzIGRlc2NyaXB0b3IoKSBvciBHZXRSZWZsZWN0aW9uKCkgb24gb25lIG9mIHRoZSB0eXBlcyBkZWZpbmVkCisgIC8vIGluIHRoZSBmaWxlLgorCisgIC8vIEluIG9wdGltaXplX2ZvciA9IExJVEVfUlVOVElNRSBtb2RlLCB3ZSBkb24ndCBnZW5lcmF0ZSBBc3NpZ25EZXNjcmlwdG9ycygpCisgIC8vIGFuZCB3ZSBvbmx5IHVzZSBBZGREZXNjcmlwdG9ycygpIHRvIGFsbG9jYXRlIGRlZmF1bHQgaW5zdGFuY2VzLgorICBpZiAoSGFzRGVzY3JpcHRvck1ldGhvZHMoZmlsZV8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiXG4iCisgICAgICAidm9pZCAkYXNzaWduZGVzY3JpcHRvcnNuYW1lJCgpIHtcbiIsCisgICAgICAiYXNzaWduZGVzY3JpcHRvcnNuYW1lIiwgR2xvYmFsQXNzaWduRGVzY3JpcHRvcnNOYW1lKGZpbGVfLT5uYW1lKCkpKTsKKyAgICBwcmludGVyLT5JbmRlbnQoKTsKKworICAgIC8vIE1ha2Ugc3VyZSB0aGUgZmlsZSBoYXMgZm91bmQgaXRzIHdheSBpbnRvIHRoZSBwb29sLiAgSWYgYSBkZXNjcmlwdG9yCisgICAgLy8gaXMgcmVxdWVzdGVkICpkdXJpbmcqIHN0YXRpYyBpbml0IHRoZW4gQWRkRGVzY3JpcHRvcnMoKSBtYXkgbm90IGhhdmUKKyAgICAvLyBiZWVuIGNhbGxlZCB5ZXQsIHNvIHdlIGNhbGwgaXQgbWFudWFsbHkuICBOb3RlIHRoYXQgaXQncyBmaW5lIGlmCisgICAgLy8gQWRkRGVzY3JpcHRvcnMoKSBpcyBjYWxsZWQgbXVsdGlwbGUgdGltZXMuCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiJGFkZGRlc2NyaXB0b3JzbmFtZSQoKTtcbiIsCisgICAgICAiYWRkZGVzY3JpcHRvcnNuYW1lIiwgR2xvYmFsQWRkRGVzY3JpcHRvcnNOYW1lKGZpbGVfLT5uYW1lKCkpKTsKKworICAgIC8vIEdldCB0aGUgZmlsZSdzIGRlc2NyaXB0b3IgZnJvbSB0aGUgcG9vbC4KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVEZXNjcmlwdG9yKiBmaWxlID1cbiIKKyAgICAgICIgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclBvb2w6OmdlbmVyYXRlZF9wb29sKCktPkZpbmRGaWxlQnlOYW1lKFxuIgorICAgICAgIiAgICBcIiRmaWxlbmFtZSRcIik7XG4iCisgICAgICAvLyBOb3RlIHRoYXQgdGhpcyBHT09HTEVfQ0hFQ0sgaXMgbmVjZXNzYXJ5IHRvIHByZXZlbnQgYSB3YXJuaW5nIGFib3V0ICJmaWxlIgorICAgICAgLy8gYmVpbmcgdW51c2VkIHdoZW4gY29tcGlsaW5nIGFuIGVtcHR5IC5wcm90byBmaWxlLgorICAgICAgIkdPT0dMRV9DSEVDSyhmaWxlICE9IE5VTEwpO1xuIiwKKyAgICAgICJmaWxlbmFtZSIsIGZpbGVfLT5uYW1lKCkpOworCisgICAgLy8gR28gdGhyb3VnaCBhbGwgdGhlIHN0dWZmIGRlZmluZWQgaW4gdGhpcyBmaWxlIGFuZCBnZW5lcmF0ZWQgY29kZSB0bworICAgIC8vIGFzc2lnbiB0aGUgZ2xvYmFsIGRlc2NyaXB0b3IgcG9pbnRlcnMgYmFzZWQgb24gdGhlIGZpbGUgZGVzY3JpcHRvci4KKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5tZXNzYWdlX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgICBtZXNzYWdlX2dlbmVyYXRvcnNfW2ldLT5HZW5lcmF0ZURlc2NyaXB0b3JJbml0aWFsaXplcihwcmludGVyLCBpKTsKKyAgICB9CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+ZW51bV90eXBlX2NvdW50KCk7IGkrKykgeworICAgICAgZW51bV9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVEZXNjcmlwdG9ySW5pdGlhbGl6ZXIocHJpbnRlciwgaSk7CisgICAgfQorICAgIGlmIChIYXNHZW5lcmljU2VydmljZXMoZmlsZV8pKSB7CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5zZXJ2aWNlX2NvdW50KCk7IGkrKykgeworICAgICAgICBzZXJ2aWNlX2dlbmVyYXRvcnNfW2ldLT5HZW5lcmF0ZURlc2NyaXB0b3JJbml0aWFsaXplcihwcmludGVyLCBpKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAifVxuIgorICAgICAgIlxuIik7CisKKyAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgIC8vIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOiAgVGhlIGZpcnN0IHRpbWUgaXQgaXMgY2FsbGVkLCBjYWxscworICAgIC8vIEFzc2lnbkRlc2NyaXB0b3JzKCkuICBBbGwgbGF0ZXIgdGltZXMsIHdhaXRzIGZvciB0aGUgZmlyc3QgY2FsbCB0bworICAgIC8vIGNvbXBsZXRlIGFuZCB0aGVuIHJldHVybnMuCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAibmFtZXNwYWNlIHtcbiIKKyAgICAgICJcbiIKKyAgICAgICJHT09HTEVfUFJPVE9CVUZfREVDTEFSRV9PTkNFKHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzX29uY2VfKTtcbiIKKyAgICAgICJpbmxpbmUgdm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKSB7XG4iCisgICAgICAiICA6Omdvb2dsZTo6cHJvdG9idWY6Okdvb2dsZU9uY2VJbml0KCZwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc19vbmNlXyxcbiIKKyAgICAgICIgICAgICAgICAgICAgICAgICYkYXNzaWduZGVzY3JpcHRvcnNuYW1lJCk7XG4iCisgICAgICAifVxuIgorICAgICAgIlxuIiwKKyAgICAgICJhc3NpZ25kZXNjcmlwdG9yc25hbWUiLCBHbG9iYWxBc3NpZ25EZXNjcmlwdG9yc05hbWUoZmlsZV8tPm5hbWUoKSkpOworCisgICAgLy8gcHJvdG9idWZfUmVnaXN0ZXJUeXBlcygpOiAgQ2FsbHMKKyAgICAvLyBNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZFR5cGUoKSBmb3IgZWFjaCBtZXNzYWdlIHR5cGUuCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAidm9pZCBwcm90b2J1Zl9SZWdpc3RlclR5cGVzKGNvbnN0IDo6c3RkOjpzdHJpbmcmKSB7XG4iCisgICAgICAiICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTtcbiIpOworICAgIHByaW50ZXItPkluZGVudCgpOworCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+bWVzc2FnZV90eXBlX2NvdW50KCk7IGkrKykgeworICAgICAgbWVzc2FnZV9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVUeXBlUmVnaXN0cmF0aW9ucyhwcmludGVyKTsKKyAgICB9CisKKyAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAifVxuIgorICAgICAgIlxuIgorICAgICAgIn0gIC8vIG5hbWVzcGFjZVxuIik7CisgIH0KKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIFNodXRkb3duRmlsZSgpOiAgRGVsZXRlcyBkZXNjcmlwdG9ycywgZGVmYXVsdCBpbnN0YW5jZXMsIGV0Yy4gb24gc2h1dGRvd24uCisgIHByaW50ZXItPlByaW50KAorICAgICJcbiIKKyAgICAidm9pZCAkc2h1dGRvd25maWxlbmFtZSQoKSB7XG4iLAorICAgICJzaHV0ZG93bmZpbGVuYW1lIiwgR2xvYmFsU2h1dGRvd25GaWxlTmFtZShmaWxlXy0+bmFtZSgpKSk7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBtZXNzYWdlX2dlbmVyYXRvcnNfW2ldLT5HZW5lcmF0ZVNodXRkb3duQ29kZShwcmludGVyKTsKKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIn1cblxuIik7CisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBOb3cgZ2VuZXJhdGUgdGhlIEFkZERlc2NyaXB0b3JzKCkgZnVuY3Rpb24uCisgIFByaW50SGFuZGxpbmdPcHRpb25hbFN0YXRpY0luaXRpYWxpemVycygKKyAgICBmaWxlXywgcHJpbnRlciwKKyAgICAvLyBXaXRoIHN0YXRpYyBpbml0aWFsaXplcnMuCisgICAgLy8gTm90ZSB0aGF0IHdlIGRvbid0IG5lZWQgYW55IHNwZWNpYWwgc3luY2hyb25pemF0aW9uIGluIHRoZSBmb2xsb3dpbmcgY29kZQorICAgIC8vIGJlY2F1c2UgaXQgaXMgY2FsbGVkIGF0IHN0YXRpYyBpbml0IHRpbWUgYmVmb3JlIGFueSB0aHJlYWRzIGV4aXN0LgorICAgICJ2b2lkICRhZGRkZXNjcmlwdG9yc25hbWUkKCkge1xuIgorICAgICIgIHN0YXRpYyBib29sIGFscmVhZHlfaGVyZSA9IGZhbHNlO1xuIgorICAgICIgIGlmIChhbHJlYWR5X2hlcmUpIHJldHVybjtcbiIKKyAgICAiICBhbHJlYWR5X2hlcmUgPSB0cnVlO1xuIgorICAgICIgIEdPT0dMRV9QUk9UT0JVRl9WRVJJRllfVkVSU0lPTjtcbiIKKyAgICAiXG4iLAorICAgIC8vIFdpdGhvdXQuCisgICAgInZvaWQgJGFkZGRlc2NyaXB0b3JzbmFtZSRfaW1wbCgpIHtcbiIKKyAgICAiICBHT09HTEVfUFJPVE9CVUZfVkVSSUZZX1ZFUlNJT047XG4iCisgICAgIlxuIiwKKyAgICAvLyBWYXJzLgorICAgICJhZGRkZXNjcmlwdG9yc25hbWUiLCBHbG9iYWxBZGREZXNjcmlwdG9yc05hbWUoZmlsZV8tPm5hbWUoKSkpOworCisgIHByaW50ZXItPkluZGVudCgpOworCisgIC8vIENhbGwgdGhlIEFkZERlc2NyaXB0b3JzKCkgbWV0aG9kcyBmb3IgYWxsIG9mIG91ciBkZXBlbmRlbmNpZXMsIHRvIG1ha2UKKyAgLy8gc3VyZSB0aGV5IGdldCBhZGRlZCBmaXJzdC4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+ZGVwZW5kZW5jeV9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBGaWxlRGVzY3JpcHRvciogZGVwZW5kZW5jeSA9IGZpbGVfLT5kZXBlbmRlbmN5KGkpOworICAgIC8vIFByaW50IHRoZSBuYW1lc3BhY2UgcHJlZml4IGZvciB0aGUgZGVwZW5kZW5jeS4KKyAgICBzdHJpbmcgYWRkX2Rlc2NfbmFtZSA9IFF1YWxpZmllZEZpbGVMZXZlbFN5bWJvbCgKKyAgICAgICAgZGVwZW5kZW5jeS0+cGFja2FnZSgpLCBHbG9iYWxBZGREZXNjcmlwdG9yc05hbWUoZGVwZW5kZW5jeS0+bmFtZSgpKSk7CisgICAgLy8gQ2FsbCBpdHMgQWRkRGVzY3JpcHRvcnMgZnVuY3Rpb24uCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiJG5hbWUkKCk7XG4iLAorICAgICAgIm5hbWUiLCBhZGRfZGVzY19uYW1lKTsKKyAgfQorCisgIGlmIChIYXNEZXNjcmlwdG9yTWV0aG9kcyhmaWxlXykpIHsKKyAgICAvLyBFbWJlZCB0aGUgZGVzY3JpcHRvci4gIFdlIHNpbXBseSBzZXJpYWxpemUgdGhlIGVudGlyZSBGaWxlRGVzY3JpcHRvclByb3RvCisgICAgLy8gYW5kIGVtYmVkIGl0IGFzIGEgc3RyaW5nIGxpdGVyYWwsIHdoaWNoIGlzIHBhcnNlZCBhbmQgYnVpbHQgaW50byByZWFsCisgICAgLy8gZGVzY3JpcHRvcnMgYXQgaW5pdGlhbGl6YXRpb24gdGltZS4KKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGVfcHJvdG87CisgICAgZmlsZV8tPkNvcHlUbygmZmlsZV9wcm90byk7CisgICAgc3RyaW5nIGZpbGVfZGF0YTsKKyAgICBmaWxlX3Byb3RvLlNlcmlhbGl6ZVRvU3RyaW5nKCZmaWxlX2RhdGEpOworCisjaWZkZWYgX01TQ19WRVIKKyAgICBib29sIGJyZWFrZG93bl9sYXJnZV9maWxlID0gdHJ1ZTsKKyNlbHNlCisgICAgYm9vbCBicmVha2Rvd25fbGFyZ2VfZmlsZSA9IGZhbHNlOworI2VuZGlmCisgICAgLy8gV29ya2Fyb3VuZCBmb3IgTVNWQzogIkVycm9yIEMxMDkxOiBjb21waWxlciBsaW1pdDogc3RyaW5nIGV4Y2VlZHMgNjU1MzUKKyAgICAvLyBieXRlcyBpbiBsZW5ndGgiLiBEZWNsYXJlIGEgc3RhdGljIGFycmF5IG9mIGNoYXJhY3RlcnMgcmF0aGVyIHRoYW4gdXNlIGEKKyAgICAvLyBzdHJpbmcgbGl0ZXJhbC4KKyAgICBpZiAoYnJlYWtkb3duX2xhcmdlX2ZpbGUgJiYgZmlsZV9kYXRhLnNpemUoKSA+IDY1NTM1KSB7CisgICAgICAvLyBUaGlzIGhhcyB0byBiZSBleHBsaWNpdGx5IG1hcmtlZCBhcyBhIHNpZ25lZCBjaGFyIGJlY2F1c2UgdGhlIGdlbmVyYXRlZAorICAgICAgLy8gY29kZSBwdXRzIG5lZ2F0aXZlIHZhbHVlcyBpbiB0aGUgYXJyYXksIGFuZCBzb21ldGltZXMgcGxhaW4gY2hhciBpcworICAgICAgLy8gdW5zaWduZWQuIFRoYXQgaW1wbGljaXQgbmFycm93aW5nIGNvbnZlcnNpb24gaXMgbm90IGFsbG93ZWQgaW4gQysrMTEuCisgICAgICAvLyA8aHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy80NDM0MTQwL25hcnJvd2luZy1jb252ZXJzaW9ucy1pbi1jMHgtaXMtaXQtanVzdC1tZS1vci1kb2VzLXRoaXMtc291bmQtbGlrZS1hLWJyZWFraW4+CisgICAgICAvLyBoYXMgZGV0YWlscyBvbiB3aHkuCisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAic3RhdGljIGNvbnN0IHNpZ25lZCBjaGFyIGRlc2NyaXB0b3JbXSA9IHtcbiIpOworICAgICAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgICAgIC8vIE9ubHkgd3JpdGUgMjUgYnl0ZXMgcGVyIGxpbmUuCisgICAgICBzdGF0aWMgY29uc3QgaW50IGtCeXRlc1BlckxpbmUgPSAyNTsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV9kYXRhLnNpemUoKTspIHsKKyAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGtCeXRlc1BlckxpbmUgJiYgaSA8IGZpbGVfZGF0YS5zaXplKCk7ICsraSwgKytqKSB7CisgICAgICAgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAgICAgICAiJGNoYXIkLCAiLAorICAgICAgICAgICAgICAgICJjaGFyIiwgU2ltcGxlSXRvYShmaWxlX2RhdGFbaV0pKTsKKyAgICAgICAgICB9CisgICAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgICAgICJcbiIpOworICAgICAgfQorCisgICAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAifTtcbiIpOworCisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAiOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUG9vbDo6SW50ZXJuYWxBZGRHZW5lcmF0ZWRGaWxlKGRlc2NyaXB0b3IsICRzaXplJCk7XG4iLAorICAgICAgICAgICJzaXplIiwgU2ltcGxlSXRvYShmaWxlX2RhdGEuc2l6ZSgpKSk7CisKKyAgICB9IGVsc2UgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICI6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQb29sOjpJbnRlcm5hbEFkZEdlbmVyYXRlZEZpbGUoIik7CisKKyAgICAgIC8vIE9ubHkgd3JpdGUgNDAgYnl0ZXMgcGVyIGxpbmUuCisgICAgICBzdGF0aWMgY29uc3QgaW50IGtCeXRlc1BlckxpbmUgPSA0MDsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV9kYXRhLnNpemUoKTsgaSArPSBrQnl0ZXNQZXJMaW5lKSB7CisgICAgICAgIHByaW50ZXItPlByaW50KCJcbiAgXCIkZGF0YSRcIiIsCisgICAgICAgICAgICAgICAgICAgICAgICJkYXRhIiwKKyAgICAgICAgICAgICAgICAgICAgICAgRXNjYXBlVHJpZ3JhcGhzKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0VzY2FwZShmaWxlX2RhdGEuc3Vic3RyKGksIGtCeXRlc1BlckxpbmUpKSkpOworICAgIH0KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIiwgJHNpemUkKTtcbiIsCisgICAgICAgICJzaXplIiwgU2ltcGxlSXRvYShmaWxlX2RhdGEuc2l6ZSgpKSk7CisgICAgfQorCisgICAgLy8gQ2FsbCBNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZEZpbGUoKS4KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICI6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VGYWN0b3J5OjpJbnRlcm5hbFJlZ2lzdGVyR2VuZXJhdGVkRmlsZShcbiIKKyAgICAgICIgIFwiJGZpbGVuYW1lJFwiLCAmcHJvdG9idWZfUmVnaXN0ZXJUeXBlcyk7XG4iLAorICAgICAgImZpbGVuYW1lIiwgZmlsZV8tPm5hbWUoKSk7CisgIH0KKworICAvLyBBbGxvY2F0ZSBhbmQgaW5pdGlhbGl6ZSBkZWZhdWx0IGluc3RhbmNlcy4gIFRoaXMgY2FuJ3QgYmUgZG9uZSBsYXppbHkKKyAgLy8gc2luY2UgZGVmYXVsdCBpbnN0YW5jZXMgYXJlIHJldHVybmVkIGJ5IHNpbXBsZSBhY2Nlc3NvcnMgYW5kIGFyZSB1c2VkIHdpdGgKKyAgLy8gZXh0ZW5zaW9ucy4gIFNwZWFraW5nIG9mIHdoaWNoLCB3ZSBhbHNvIHJlZ2lzdGVyIGV4dGVuc2lvbnMgYXQgdGhpcyB0aW1lLgorICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5tZXNzYWdlX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgbWVzc2FnZV9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVEZWZhdWx0SW5zdGFuY2VBbGxvY2F0b3IocHJpbnRlcik7CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+ZXh0ZW5zaW9uX2NvdW50KCk7IGkrKykgeworICAgIGV4dGVuc2lvbl9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVSZWdpc3RyYXRpb24ocHJpbnRlcik7CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+bWVzc2FnZV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIG1lc3NhZ2VfZ2VuZXJhdG9yc19baV0tPkdlbmVyYXRlRGVmYXVsdEluc3RhbmNlSW5pdGlhbGl6ZXIocHJpbnRlcik7CisgIH0KKworICBwcmludGVyLT5QcmludCgKKyAgICAiOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6T25TaHV0ZG93bigmJHNodXRkb3duZmlsZW5hbWUkKTtcbiIsCisgICAgInNodXRkb3duZmlsZW5hbWUiLCBHbG9iYWxTaHV0ZG93bkZpbGVOYW1lKGZpbGVfLT5uYW1lKCkpKTsKKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KAorICAgICJ9XG4iCisgICAgIlxuIik7CisKKyAgUHJpbnRIYW5kbGluZ09wdGlvbmFsU3RhdGljSW5pdGlhbGl6ZXJzKAorICAgIGZpbGVfLCBwcmludGVyLAorICAgIC8vIFdpdGggc3RhdGljIGluaXRpYWxpemVycy4KKyAgICAiLy8gRm9yY2UgQWRkRGVzY3JpcHRvcnMoKSB0byBiZSBjYWxsZWQgYXQgc3RhdGljIGluaXRpYWxpemF0aW9uIHRpbWUuXG4iCisgICAgInN0cnVjdCBTdGF0aWNEZXNjcmlwdG9ySW5pdGlhbGl6ZXJfJGZpbGVuYW1lJCB7XG4iCisgICAgIiAgU3RhdGljRGVzY3JpcHRvckluaXRpYWxpemVyXyRmaWxlbmFtZSQoKSB7XG4iCisgICAgIiAgICAkYWRkZGVzY3JpcHRvcnNuYW1lJCgpO1xuIgorICAgICIgIH1cbiIKKyAgICAifSBzdGF0aWNfZGVzY3JpcHRvcl9pbml0aWFsaXplcl8kZmlsZW5hbWUkXztcbiIsCisgICAgLy8gV2l0aG91dC4KKyAgICAiR09PR0xFX1BST1RPQlVGX0RFQ0xBUkVfT05DRSgkYWRkZGVzY3JpcHRvcnNuYW1lJF9vbmNlXyk7XG4iCisgICAgInZvaWQgJGFkZGRlc2NyaXB0b3JzbmFtZSQoKSB7XG4iCisgICAgIiAgOjpnb29nbGU6OnByb3RvYnVmOjpHb29nbGVPbmNlSW5pdCgmJGFkZGRlc2NyaXB0b3JzbmFtZSRfb25jZV8sXG4iCisgICAgIiAgICAgICAgICAgICAgICAgJiRhZGRkZXNjcmlwdG9yc25hbWUkX2ltcGwpO1xuIgorICAgICJ9XG4iLAorICAgIC8vIFZhcnMuCisgICAgImFkZGRlc2NyaXB0b3JzbmFtZSIsIEdsb2JhbEFkZERlc2NyaXB0b3JzTmFtZShmaWxlXy0+bmFtZSgpKSwKKyAgICAiZmlsZW5hbWUiLCBGaWxlbmFtZUlkZW50aWZpZXIoZmlsZV8tPm5hbWUoKSkpOworfQorCit2b2lkIEZpbGVHZW5lcmF0b3I6OkdlbmVyYXRlTmFtZXNwYWNlT3BlbmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBpZiAocGFja2FnZV9wYXJ0c18uc2l6ZSgpID4gMCkgcHJpbnRlci0+UHJpbnQoIlxuIik7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrYWdlX3BhcnRzXy5zaXplKCk7IGkrKykgeworICAgIHByaW50ZXItPlByaW50KCJuYW1lc3BhY2UgJHBhcnQkIHtcbiIsCisgICAgICAgICAgICAgICAgICAgInBhcnQiLCBwYWNrYWdlX3BhcnRzX1tpXSk7CisgIH0KK30KKwordm9pZCBGaWxlR2VuZXJhdG9yOjpHZW5lcmF0ZU5hbWVzcGFjZUNsb3NlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgaWYgKHBhY2thZ2VfcGFydHNfLnNpemUoKSA+IDApIHByaW50ZXItPlByaW50KCJcbiIpOworCisgIGZvciAoaW50IGkgPSBwYWNrYWdlX3BhcnRzXy5zaXplKCkgLSAxOyBpID49IDA7IGktLSkgeworICAgIHByaW50ZXItPlByaW50KCJ9ICAvLyBuYW1lc3BhY2UgJHBhcnQkXG4iLAorICAgICAgICAgICAgICAgICAgICJwYXJ0IiwgcGFja2FnZV9wYXJ0c19baV0pOworICB9Cit9CisKK3ZvaWQgRmlsZUdlbmVyYXRvcjo6R2VuZXJhdGVGb3J3YXJkRGVjbGFyYXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIEZvcndhcmREZWNsYXJhdGlvbnMgZGVjbHM7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPmRlcGVuZGVuY3lfY291bnQoKTsgaSsrKSB7CisgICAgRmlsZUdlbmVyYXRvciBkZXBlbmRlbmN5KGZpbGVfLT5kZXBlbmRlbmN5KGkpLCBvcHRpb25zXyk7CisgICAgZGVwZW5kZW5jeS5GaWxsRm9yd2FyZERlY2xhcmF0aW9ucygmZGVjbHMpOworICB9CisgIEZpbGxGb3J3YXJkRGVjbGFyYXRpb25zKCZkZWNscyk7CisgIGRlY2xzLlByaW50KHByaW50ZXIpOworfQorCit2b2lkIEZpbGVHZW5lcmF0b3I6OkZpbGxGb3J3YXJkRGVjbGFyYXRpb25zKEZvcndhcmREZWNsYXJhdGlvbnMqIGRlY2xzKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPnB1YmxpY19kZXBlbmRlbmN5X2NvdW50KCk7IGkrKykgeworICAgIEZpbGVHZW5lcmF0b3IgZGVwZW5kZW5jeShmaWxlXy0+cHVibGljX2RlcGVuZGVuY3koaSksIG9wdGlvbnNfKTsKKyAgICBkZXBlbmRlbmN5LkZpbGxGb3J3YXJkRGVjbGFyYXRpb25zKGRlY2xzKTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2thZ2VfcGFydHNfLnNpemUoKTsgaSsrKSB7CisgICAgZGVjbHMgPSBkZWNscy0+QWRkT3JHZXROYW1lc3BhY2UocGFja2FnZV9wYXJ0c19baV0pOworICB9CisgIC8vIEdlbmVyYXRlIGVudW0gZGVmaW5pdGlvbnMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBtZXNzYWdlX2dlbmVyYXRvcnNfW2ldLT5GaWxsRW51bUZvcndhcmREZWNsYXJhdGlvbnMoJmRlY2xzLT5lbnVtcygpKTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5lbnVtX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgZW51bV9nZW5lcmF0b3JzX1tpXS0+RmlsbEZvcndhcmREZWNsYXJhdGlvbigmZGVjbHMtPmVudW1zKCkpOworICB9CisgIC8vIEdlbmVyYXRlIGZvcndhcmQgZGVjbGFyYXRpb25zIG9mIGNsYXNzZXMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBtZXNzYWdlX2dlbmVyYXRvcnNfW2ldLT5GaWxsTWVzc2FnZUZvcndhcmREZWNsYXJhdGlvbnMoCisgICAgICAgICZkZWNscy0+Y2xhc3NlcygpKTsKKyAgfQorfQorCit2b2lkIEZpbGVHZW5lcmF0b3I6OkdlbmVyYXRlVG9wSGVhZGVyR3VhcmQoaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBmaWxlbmFtZV9pZGVudGlmaWVyKSB7CisgIC8vIEdlbmVyYXRlIHRvcCBvZiBoZWFkZXIuCisgIHByaW50ZXItPlByaW50KAorICAgICIvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIVxuIgorICAgICIvLyBzb3VyY2U6ICRmaWxlbmFtZSRcbiIKKyAgICAiXG4iCisgICAgIiNpZm5kZWYgUFJPVE9CVUZfJGZpbGVuYW1lX2lkZW50aWZpZXIkX19JTkNMVURFRFxuIgorICAgICIjZGVmaW5lIFBST1RPQlVGXyRmaWxlbmFtZV9pZGVudGlmaWVyJF9fSU5DTFVERURcbiIKKyAgICAiXG4iCisgICAgIiNpbmNsdWRlIDxzdHJpbmc+XG4iCisgICAgIlxuIiwKKyAgICAiZmlsZW5hbWUiLCBmaWxlXy0+bmFtZSgpLAorICAgICJmaWxlbmFtZV9pZGVudGlmaWVyIiwgZmlsZW5hbWVfaWRlbnRpZmllcik7Cit9CisKK3ZvaWQgRmlsZUdlbmVyYXRvcjo6R2VuZXJhdGVCb3R0b21IZWFkZXJHdWFyZCgKKyAgICBpbzo6UHJpbnRlciogcHJpbnRlciwgY29uc3Qgc3RyaW5nJiBmaWxlbmFtZV9pZGVudGlmaWVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgICIjZW5kaWYgIC8vIFBST1RPQlVGXyRmaWxlbmFtZV9pZGVudGlmaWVyJF9fSU5DTFVERURcbiIsCisgICAgImZpbGVuYW1lX2lkZW50aWZpZXIiLCBmaWxlbmFtZV9pZGVudGlmaWVyKTsKK30KKwordm9pZCBGaWxlR2VuZXJhdG9yOjpHZW5lcmF0ZUxpYnJhcnlJbmNsdWRlcyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworCisgIHByaW50ZXItPlByaW50KAorICAgICIjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPlxuIgorICAgICJcbiIpOworCisgIC8vIFZlcmlmeSB0aGUgcHJvdG9idWYgbGlicmFyeSBoZWFkZXIgdmVyc2lvbiBpcyBjb21wYXRpYmxlIHdpdGggdGhlIHByb3RvYworICAvLyB2ZXJzaW9uIGJlZm9yZSBnb2luZyBhbnkgZnVydGhlci4KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIiNpZiBHT09HTEVfUFJPVE9CVUZfVkVSU0lPTiA8ICRtaW5faGVhZGVyX3ZlcnNpb24kXG4iCisgICAgIiNlcnJvciBUaGlzIGZpbGUgd2FzIGdlbmVyYXRlZCBieSBhIG5ld2VyIHZlcnNpb24gb2YgcHJvdG9jIHdoaWNoIGlzXG4iCisgICAgIiNlcnJvciBpbmNvbXBhdGlibGUgd2l0aCB5b3VyIFByb3RvY29sIEJ1ZmZlciBoZWFkZXJzLiAgUGxlYXNlIHVwZGF0ZVxuIgorICAgICIjZXJyb3IgeW91ciBoZWFkZXJzLlxuIgorICAgICIjZW5kaWZcbiIKKyAgICAiI2lmICRwcm90b2NfdmVyc2lvbiQgPCBHT09HTEVfUFJPVE9CVUZfTUlOX1BST1RPQ19WRVJTSU9OXG4iCisgICAgIiNlcnJvciBUaGlzIGZpbGUgd2FzIGdlbmVyYXRlZCBieSBhbiBvbGRlciB2ZXJzaW9uIG9mIHByb3RvYyB3aGljaCBpc1xuIgorICAgICIjZXJyb3IgaW5jb21wYXRpYmxlIHdpdGggeW91ciBQcm90b2NvbCBCdWZmZXIgaGVhZGVycy4gIFBsZWFzZVxuIgorICAgICIjZXJyb3IgcmVnZW5lcmF0ZSB0aGlzIGZpbGUgd2l0aCBhIG5ld2VyIHZlcnNpb24gb2YgcHJvdG9jLlxuIgorICAgICIjZW5kaWZcbiIKKyAgICAiXG4iLAorICAgICJtaW5faGVhZGVyX3ZlcnNpb24iLAorICAgICAgU2ltcGxlSXRvYShwcm90b2J1Zjo6aW50ZXJuYWw6OmtNaW5IZWFkZXJWZXJzaW9uRm9yUHJvdG9jKSwKKyAgICAicHJvdG9jX3ZlcnNpb24iLCBTaW1wbGVJdG9hKEdPT0dMRV9QUk9UT0JVRl9WRVJTSU9OKSk7CisKKyAgLy8gT0ssIGl0J3Mgbm93IHNhZmUgdG8gI2luY2x1ZGUgb3RoZXIgZmlsZXMuCisgIHByaW50ZXItPlByaW50KAorICAgICIjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2FyZW5hLmg+XG4iCisgICAgIiNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvYXJlbmFzdHJpbmcuaD5cbiIKKyAgICAiI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfbWVzc2FnZV91dGlsLmg+XG4iKTsKKyAgaWYgKFVzZVVua25vd25GaWVsZFNldChmaWxlXykpIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICIjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21ldGFkYXRhLmg+XG4iKTsKKyAgfQorICBpZiAoZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpID4gMCkgeworICAgIGlmIChIYXNEZXNjcmlwdG9yTWV0aG9kcyhmaWxlXykpIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tZXNzYWdlLmg+XG4iKTsKKyAgICB9IGVsc2UgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICIjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21lc3NhZ2VfbGl0ZS5oPlxuIik7CisgICAgfQorICB9CisgIHByaW50ZXItPlByaW50KAorICAgICIjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3JlcGVhdGVkX2ZpZWxkLmg+XG4iCisgICAgIiNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZXh0ZW5zaW9uX3NldC5oPlxuIik7CisgIGlmIChIYXNNYXBGaWVsZHMoZmlsZV8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICIjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21hcC5oPlxuIik7CisgICAgaWYgKEhhc0Rlc2NyaXB0b3JNZXRob2RzKGZpbGVfKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgIiNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWFwX2ZpZWxkX2lubC5oPlxuIik7CisgICAgfSBlbHNlIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICIjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21hcF9maWVsZF9saXRlLmg+XG4iKTsKKyAgICB9CisgIH0KKworICBpZiAoSGFzRW51bURlZmluaXRpb25zKGZpbGVfKSkgeworICAgIGlmIChIYXNEZXNjcmlwdG9yTWV0aG9kcyhmaWxlXykpIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICIjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9lbnVtX3JlZmxlY3Rpb24uaD5cbiIpOworICAgIH0gZWxzZSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAiI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfZW51bV91dGlsLmg+XG4iKTsKKyAgICB9CisgIH0KKworICBpZiAoSGFzR2VuZXJpY1NlcnZpY2VzKGZpbGVfKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIiNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc2VydmljZS5oPlxuIik7CisgIH0KKworICBpZiAoVXNlVW5rbm93bkZpZWxkU2V0KGZpbGVfKSAmJiBmaWxlXy0+bWVzc2FnZV90eXBlX2NvdW50KCkgPiAwKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bmtub3duX2ZpZWxkX3NldC5oPlxuIik7CisgIH0KKworCisgIGlmIChJc0FueU1lc3NhZ2UoZmlsZV8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9hbnkuaD5cbiIpOworICB9Cit9CisKK3ZvaWQgRmlsZUdlbmVyYXRvcjo6R2VuZXJhdGVEZXBlbmRlbmN5SW5jbHVkZXMoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgc2V0PHN0cmluZz4gcHVibGljX2ltcG9ydF9uYW1lczsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+cHVibGljX2RlcGVuZGVuY3lfY291bnQoKTsgaSsrKSB7CisgICAgcHVibGljX2ltcG9ydF9uYW1lcy5pbnNlcnQoZmlsZV8tPnB1YmxpY19kZXBlbmRlbmN5KGkpLT5uYW1lKCkpOworICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+ZGVwZW5kZW5jeV9jb3VudCgpOyBpKyspIHsKKyAgICBib29sIHdlbGxfa25vd24gPSBJc1dlbGxLbm93bk1lc3NhZ2UoZmlsZV8tPmRlcGVuZGVuY3koaSkpOworICAgIGNvbnN0IHN0cmluZyYgbmFtZSA9IGZpbGVfLT5kZXBlbmRlbmN5KGkpLT5uYW1lKCk7CisgICAgYm9vbCBwdWJsaWNfaW1wb3J0ID0gKHB1YmxpY19pbXBvcnRfbmFtZXMuY291bnQobmFtZSkgIT0gMCk7CisKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICIjaW5jbHVkZSAkbGVmdCQkZGVwZW5kZW5jeSQucGIuaCRyaWdodCQkaXd5dSRcbiIsCisgICAgICAiZGVwZW5kZW5jeSIsIFN0cmlwUHJvdG8obmFtZSksCisgICAgICAiaXd5dSIsIChwdWJsaWNfaW1wb3J0KSA/ICIgIC8vIElXWVUgcHJhZ21hOiBleHBvcnQiIDogIiIsCisgICAgICAibGVmdCIsIHdlbGxfa25vd24gPyAiPCIgOiAiXCIiLAorICAgICAgInJpZ2h0Iiwgd2VsbF9rbm93biA/ICI+IiA6ICJcIiIpOworICB9Cit9CisKK3ZvaWQgRmlsZUdlbmVyYXRvcjo6R2VuZXJhdGVHbG9iYWxTdGF0ZUZ1bmN0aW9uRGVjbGFyYXRpb25zKAorICAgIGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIC8vIEZvcndhcmQtZGVjbGFyZSB0aGUgQWRkRGVzY3JpcHRvcnMsIEFzc2lnbkRlc2NyaXB0b3JzLCBhbmQgU2h1dGRvd25GaWxlCisgIC8vIGZ1bmN0aW9ucywgc28gdGhhdCB3ZSBjYW4gZGVjbGFyZSB0aGVtIHRvIGJlIGZyaWVuZHMgb2YgZWFjaCBjbGFzcy4KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIlxuIgorICAgICIvLyBJbnRlcm5hbCBpbXBsZW1lbnRhdGlvbiBkZXRhaWwgLS0gZG8gbm90IGNhbGwgdGhlc2UuXG4iCisgICAgInZvaWQgJGRsbGV4cG9ydF9kZWNsJCRhZGRkZXNjcmlwdG9yc25hbWUkKCk7XG4iLAorICAgICJhZGRkZXNjcmlwdG9yc25hbWUiLCBHbG9iYWxBZGREZXNjcmlwdG9yc05hbWUoZmlsZV8tPm5hbWUoKSksCisgICAgImRsbGV4cG9ydF9kZWNsIiwKKyAgICBvcHRpb25zXy5kbGxleHBvcnRfZGVjbC5lbXB0eSgpID8gIiIgOiBvcHRpb25zXy5kbGxleHBvcnRfZGVjbCArICIgIik7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgLy8gTm90ZSB0aGF0IHdlIGRvbid0IHB1dCBkbGxleHBvcnRfZGVjbCBvbiB0aGVzZSBiZWNhdXNlIHRoZXkgYXJlIG9ubHkKKyAgICAvLyBjYWxsZWQgYnkgdGhlIC5wYi5jYyBmaWxlIGluIHdoaWNoIHRoZXkgYXJlIGRlZmluZWQuCisgICAgInZvaWQgJGFzc2lnbmRlc2NyaXB0b3JzbmFtZSQoKTtcbiIKKyAgICAidm9pZCAkc2h1dGRvd25maWxlbmFtZSQoKTtcbiIKKyAgICAiXG4iLAorICAgICJhc3NpZ25kZXNjcmlwdG9yc25hbWUiLCBHbG9iYWxBc3NpZ25EZXNjcmlwdG9yc05hbWUoZmlsZV8tPm5hbWUoKSksCisgICAgInNodXRkb3duZmlsZW5hbWUiLCBHbG9iYWxTaHV0ZG93bkZpbGVOYW1lKGZpbGVfLT5uYW1lKCkpKTsKK30KKwordm9pZCBGaWxlR2VuZXJhdG9yOjpHZW5lcmF0ZU1lc3NhZ2VGb3J3YXJkRGVjbGFyYXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHNldDxzdHJpbmc+IGNsYXNzZXM7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBtZXNzYWdlX2dlbmVyYXRvcnNfW2ldLT5GaWxsTWVzc2FnZUZvcndhcmREZWNsYXJhdGlvbnMoJmNsYXNzZXMpOworICB9CisgIGZvciAoc2V0PHN0cmluZz46OmNvbnN0X2l0ZXJhdG9yIGl0ID0gY2xhc3Nlcy5iZWdpbigpLCBlbmQgPSBjbGFzc2VzLmVuZCgpOworICAgICAgIGl0ICE9IGVuZDsgKytpdCkgeworICAgIHByaW50ZXItPlByaW50KCJjbGFzcyAkY2xhc3NuYW1lJDtcbiIsICJjbGFzc25hbWUiLCBpdC0+Y19zdHIoKSk7CisgIH0KK30KKwordm9pZCBGaWxlR2VuZXJhdG9yOjpHZW5lcmF0ZU1lc3NhZ2VEZWZpbml0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICAvLyBHZW5lcmF0ZSBjbGFzcyBkZWZpbml0aW9ucy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+bWVzc2FnZV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIGlmIChpID4gMCkgeworICAgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisgICAgICBwcmludGVyLT5QcmludChrVGhpblNlcGFyYXRvcik7CisgICAgICBwcmludGVyLT5QcmludCgiXG4iKTsKKyAgICB9CisgICAgbWVzc2FnZV9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVDbGFzc0RlZmluaXRpb24ocHJpbnRlcik7CisgIH0KK30KKwordm9pZCBGaWxlR2VuZXJhdG9yOjpHZW5lcmF0ZUVudW1EZWZpbml0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICAvLyBHZW5lcmF0ZSBlbnVtIGRlZmluaXRpb25zLgorICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5tZXNzYWdlX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgbWVzc2FnZV9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVFbnVtRGVmaW5pdGlvbnMocHJpbnRlcik7CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+ZW51bV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIGVudW1fZ2VuZXJhdG9yc19baV0tPkdlbmVyYXRlRGVmaW5pdGlvbihwcmludGVyKTsKKyAgfQorfQorCit2b2lkIEZpbGVHZW5lcmF0b3I6OkdlbmVyYXRlU2VydmljZURlZmluaXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIGlmIChIYXNHZW5lcmljU2VydmljZXMoZmlsZV8pKSB7CisgICAgLy8gR2VuZXJhdGUgc2VydmljZSBkZWZpbml0aW9ucy4KKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5zZXJ2aWNlX2NvdW50KCk7IGkrKykgeworICAgICAgaWYgKGkgPiAwKSB7CisgICAgICAgIHByaW50ZXItPlByaW50KCJcbiIpOworICAgICAgICBwcmludGVyLT5QcmludChrVGhpblNlcGFyYXRvcik7CisgICAgICAgIHByaW50ZXItPlByaW50KCJcbiIpOworICAgICAgfQorICAgICAgc2VydmljZV9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVEZWNsYXJhdGlvbnMocHJpbnRlcik7CisgICAgfQorCisgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisgICAgcHJpbnRlci0+UHJpbnQoa1RoaWNrU2VwYXJhdG9yKTsKKyAgICBwcmludGVyLT5QcmludCgiXG4iKTsKKyAgfQorfQorCit2b2lkIEZpbGVHZW5lcmF0b3I6OkdlbmVyYXRlRXh0ZW5zaW9uSWRlbnRpZmllcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgLy8gRGVjbGFyZSBleHRlbnNpb24gaWRlbnRpZmllcnMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPmV4dGVuc2lvbl9jb3VudCgpOyBpKyspIHsKKyAgICBleHRlbnNpb25fZ2VuZXJhdG9yc19baV0tPkdlbmVyYXRlRGVjbGFyYXRpb24ocHJpbnRlcik7CisgIH0KK30KKwordm9pZCBGaWxlR2VuZXJhdG9yOjpHZW5lcmF0ZUlubGluZUZ1bmN0aW9uRGVmaW5pdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgLy8gQW4gYXNpZGUgYWJvdXQgaW5saW5lIGZ1bmN0aW9ucyBpbiAucHJvdG8uaCBtb2RlOgorICAvLworICAvLyBUaGUgUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTIHN5bWJvbCBjb250cm9scyBjb25kaXRpb25hbGx5CisgIC8vIG1vdmluZyBtdWNoIG9mIHRoZSBpbmxpbmUgZnVuY3Rpb25zIHRvIHRoZSAucGIuY2MgZmlsZSwgd2hpY2ggY2FuIGJlIGEKKyAgLy8gc2lnbmlmaWNhbnQgcGVyZm9ybWFuY2UgYmVuZWZpdCBmb3IgY29tcGlsYXRpb24gdGltZSwgYXQgdGhlIGV4cGVuc2UKKyAgLy8gb2Ygbm9uLWlubGluZSBmdW5jdGlvbiBjYWxscy4KKyAgLy8KKyAgLy8gSG93ZXZlciwgaW4gLnByb3RvLmggbW9kZSwgdGhlIGRlZmluaXRpb24gb2YgdGhlIGludGVybmFsIGRlcGVuZGVudAorICAvLyBiYXNlIGNsYXNzIG11c3QgcmVtYWluIGluIHRoZSBoZWFkZXIsIGFuZCBjYW4gbmV2ZXIgYmUgb3V0LWxpbmVkLiBUaGUKKyAgLy8gZGVwZW5kZW50IGJhc2UgY2xhc3MgYWxzbyBuZWVkcyBhY2Nlc3MgdG8gaGFzLWJpdCBtYW5pcHVhdGlvbgorICAvLyBmdW5jdGlvbnMsIHNvIHRoZSBoYXMtYml0IGZ1bmN0aW9ucyBtdXN0IGJlIHVuY29uZGl0aW9uYWxseSBpbmxpbmVkIGluCisgIC8vIHByb3RvX2ggbW9kZS4KKyAgLy8KKyAgLy8gVGhpcyBnaXZlcyB1cyB0aHJlZSBmbGF2b3JzIG9mIGZ1bmN0aW9uczoKKyAgLy8KKyAgLy8gIDEuIEZ1bmN0aW9ucyBvbiB0aGUgbWVzc2FnZSBub3QgdXNlZCBieSB0aGUgaW50ZXJuYWwgZGVwZW5kZW50IGJhc2UKKyAgLy8gICAgIGNsYXNzOiBpbiAucHJvdG8uaCBtb2RlLCBvbmx5IHNvbWUgZnVuY3Rpb25zIGFyZSBkZWZpbmVkIG9uIHRoZQorICAvLyAgICAgbWVzc2FnZSBjbGFzczsgb3RoZXJzIGFyZSBkZWZpbmVkIG9uIHRoZSBkZXBlbmRlbnQgYmFzZSBjbGFzcy4KKyAgLy8gICAgIFRoZXNlIGFyZSBndWFyZGVkIGFuZCBjYW4gYmUgb3V0LWxpbmVkLiBUaGVzZSBhcmUgZ2VuZXJhdGVkIGJ5CisgIC8vICAgICBHZW5lcmF0ZUlubGluZU1ldGhvZHMsIGFuZCBpbmNsdWRlIGhhc18qIGJpdCBmdW5jdGlvbnMgaW4KKyAgLy8gICAgIG5vbi1wcm90b19oIG1vZGUuCisgIC8vCisgIC8vICAyLiBGdW5jdGlvbnMgb24gdGhlIGludGVybmFsIGRlcGVuZGVudCBiYXNlIGNsYXNzOiB0aGVzZSBmdW5jdGlvbnMKKyAgLy8gICAgIGFyZSBkZXBlbmRlbnQgb24gYSB0ZW1wbGF0ZSBwYXJhbWV0ZXIsIHNvIHRoZXkgYWx3YXlzIG5lZWQgdG8KKyAgLy8gICAgIHJlbWFpbiBpbiB0aGUgaGVhZGVyLgorICAvLworICAvLyAgMy4gRnVuY3Rpb25zIG9uIHRoZSBtZXNzYWdlIHRoYXQgYXJlIHVzZWQgYnkgdGhlIGRlcGVuZGVudCBiYXNlOiB0aGUKKyAgLy8gICAgIGRlcGVuZGVudCBiYXNlIGNsYXNzIGRvd24gY2FzdHMgaXRzZWxmIHRvIHRoZSBtZXNzYWdlCisgIC8vICAgICBpbXBsZW1lbnRhdGlvbiBjbGFzcyB0byBhY2Nlc3MgdGhlc2UgZnVuY3Rpb25zICh0aGUgaGFzXyogYml0CisgIC8vICAgICBtYW5pcHVsYXRpb24gZnVuY3Rpb25zKS4gVW5saWtlICMxLCB0aGVzZSBmdW5jdGlvbnMgbXVzdAorICAvLyAgICAgdW5jb25kaXRpb25hbGx5IHJlbWFpbiBpbiB0aGUgaGVhZGVyLiBUaGVzZSBhcmUgZW1pdHRlZCBieQorICAvLyAgICAgR2VuZXJhdGVEZXBlbmRlbnRJbmxpbmVNZXRob2RzLCBldmVuIHRob3VnaCB0aGV5IGFyZSBub3QgYWN0dWFsbHkKKyAgLy8gICAgIGRlcGVuZGVudC4KKworICBwcmludGVyLT5QcmludCgiI2lmICFQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlNcbiIpOworICAvLyBHZW5lcmF0ZSBjbGFzcyBpbmxpbmUgbWV0aG9kcy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+bWVzc2FnZV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIGlmIChpID4gMCkgeworICAgICAgcHJpbnRlci0+UHJpbnQoa1RoaW5TZXBhcmF0b3IpOworICAgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisgICAgfQorICAgIG1lc3NhZ2VfZ2VuZXJhdG9yc19baV0tPkdlbmVyYXRlSW5saW5lTWV0aG9kcyhwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBpc19pbmxpbmUgPSAqLyB0cnVlKTsKKyAgfQorICBwcmludGVyLT5QcmludCgiI2VuZGlmICAvLyAhUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTXG4iKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5tZXNzYWdlX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgaWYgKGkgPiAwKSB7CisgICAgICBwcmludGVyLT5QcmludChrVGhpblNlcGFyYXRvcik7CisgICAgICBwcmludGVyLT5QcmludCgiXG4iKTsKKyAgICB9CisgICAgLy8gTWV0aG9kcyBvZiB0aGUgZGVwZW5kZW50IGJhc2UgY2xhc3MgbXVzdCBhbHdheXMgYmUgaW5saW5lIGluIHRoZSBoZWFkZXIuCisgICAgbWVzc2FnZV9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVEZXBlbmRlbnRJbmxpbmVNZXRob2RzKHByaW50ZXIpOworICB9Cit9CisKK3ZvaWQgRmlsZUdlbmVyYXRvcjo6R2VuZXJhdGVQcm90bzJOYW1lc3BhY2VFbnVtU3BlY2lhbGl6YXRpb25zKAorICAgIGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIC8vIEVtaXQgR2V0RW51bURlc2NyaXB0b3Igc3BlY2lhbGl6YXRpb25zIGludG8gZ29vZ2xlOjpwcm90b2J1ZiBuYW1lc3BhY2U6CisgIGlmIChIYXNFbnVtRGVmaW5pdGlvbnMoZmlsZV8pKSB7CisgICAgLy8gVGhlIFNXSUcgY29uZGl0aW9uYWwgaXMgdG8gYXZvaWQgYSBudWxsLXBvaW50ZXIgZGVyZWZlcmVuY2UKKyAgICAvLyAoYnVnIDE5ODQ5NjQpIGluIHN3aWctMS4zLjIxIHJlc3VsdGluZyBmcm9tIHRoZSBmb2xsb3dpbmcgc3ludGF4OgorICAgIC8vICAgbmFtZXNwYWNlIFggeyB2b2lkIFk8Wjo6Vz4oKTsgfQorICAgIC8vIHdoaWNoIGFwcGVhcnMgaW4gR2V0RW51bURlc2NyaXB0b3IoKSBzcGVjaWFsaXphdGlvbnMuCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJcbiIKKyAgICAgICAgIiNpZm5kZWYgU1dJR1xuIgorICAgICAgICAibmFtZXNwYWNlIGdvb2dsZSB7XG5uYW1lc3BhY2UgcHJvdG9idWYge1xuIgorICAgICAgICAiXG4iKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5tZXNzYWdlX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgICBtZXNzYWdlX2dlbmVyYXRvcnNfW2ldLT5HZW5lcmF0ZUdldEVudW1EZXNjcmlwdG9yU3BlY2lhbGl6YXRpb25zKHByaW50ZXIpOworICAgIH0KKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5lbnVtX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgICBlbnVtX2dlbmVyYXRvcnNfW2ldLT5HZW5lcmF0ZUdldEVudW1EZXNjcmlwdG9yU3BlY2lhbGl6YXRpb25zKHByaW50ZXIpOworICAgIH0KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIlxuIgorICAgICAgICAifSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmXG59ICAvLyBuYW1lc3BhY2UgZ29vZ2xlXG4iCisgICAgICAgICIjZW5kaWYgIC8vIFNXSUdcbiIpOworICB9Cit9CisKK30gIC8vIG5hbWVzcGFjZSBjcHAKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZmlsZS5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2ZpbGUuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yOWNkYWVhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2ZpbGUuaApAQCAtMCwwICsxLDE1NSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DUFBfRklMRV9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NQUF9GSUxFX0hfXworCisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDx2ZWN0b3I+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfb3B0aW9ucy5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisgIGNsYXNzIEZpbGVEZXNjcmlwdG9yOyAgICAgICAgLy8gZGVzY3JpcHRvci5oCisgIG5hbWVzcGFjZSBpbyB7CisgICAgY2xhc3MgUHJpbnRlcjsgICAgICAgICAgICAgLy8gcHJpbnRlci5oCisgIH0KK30KKworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgY3BwIHsKKworY2xhc3MgRW51bUdlbmVyYXRvcjsgICAgICAgICAgIC8vIGVudW0uaAorY2xhc3MgTWVzc2FnZUdlbmVyYXRvcjsgICAgICAgIC8vIG1lc3NhZ2UuaAorY2xhc3MgU2VydmljZUdlbmVyYXRvcjsgICAgICAgIC8vIHNlcnZpY2UuaAorY2xhc3MgRXh0ZW5zaW9uR2VuZXJhdG9yOyAgICAgIC8vIGV4dGVuc2lvbi5oCisKK2NsYXNzIEZpbGVHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgLy8gU2VlIGdlbmVyYXRvci5jYyBmb3IgdGhlIG1lYW5pbmcgb2YgZGxsZXhwb3J0X2RlY2wuCisgIGV4cGxpY2l0IEZpbGVHZW5lcmF0b3IoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT3B0aW9ucyYgb3B0aW9ucyk7CisgIH5GaWxlR2VuZXJhdG9yKCk7CisKKyAgdm9pZCBHZW5lcmF0ZVByb3RvSGVhZGVyKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdm9pZCBHZW5lcmF0ZVBCSGVhZGVyKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdm9pZCBHZW5lcmF0ZVNvdXJjZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyBwcml2YXRlOgorICAvLyBJbnRlcm5hbCB0eXBlIHVzZWQgYnkgR2VuZXJhdGVGb3J3YXJkRGVjbGFyYXRpb25zIChkZWZpbmVkIGluIGZpbGUuY2MpLgorICBjbGFzcyBGb3J3YXJkRGVjbGFyYXRpb25zOworCisgIC8vIEdlbmVyYXRlIHRoZSBCdWlsZERlc2NyaXB0b3JzKCkgcHJvY2VkdXJlLCB3aGljaCBidWlsZHMgYWxsIGRlc2NyaXB0b3JzCisgIC8vIGZvciB0eXBlcyBkZWZpbmVkIGluIHRoZSBmaWxlLgorICB2b2lkIEdlbmVyYXRlQnVpbGREZXNjcmlwdG9ycyhpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyAgdm9pZCBHZW5lcmF0ZU5hbWVzcGFjZU9wZW5lcnMoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2b2lkIEdlbmVyYXRlTmFtZXNwYWNlQ2xvc2Vycyhpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyAgLy8gRm9yIG90aGVyIGltcG9ydHMsIGdlbmVyYXRlcyB0aGVpciBmb3J3YXJkLWRlY2xhcmF0aW9ucy4KKyAgdm9pZCBHZW5lcmF0ZUZvcndhcmREZWNsYXJhdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIC8vIEludGVybmFsIGhlbHBlciB1c2VkIGJ5IEdlbmVyYXRlRm9yd2FyZERlY2xhcmF0aW9uczogZmlsbHMgJ2RlY2xzJworICAvLyB3aXRoIGFsbCBuZWNlc3NhcnkgZm9yd2FyZC1kZWNsYXJhdGlvbnMgZm9yIHRoaXMgZmlsZSBhbmQgaXRzCisgIC8vIHRyYW5zaWVudCBkZXBlZG5lbmNpZXMuCisgIHZvaWQgRmlsbEZvcndhcmREZWNsYXJhdGlvbnMoRm9yd2FyZERlY2xhcmF0aW9ucyogZGVjbHMpOworCisgIC8vIEdlbmVyYXRlcyB0b3Agb3IgYm90dG9tIG9mIGEgaGVhZGVyIGZpbGUuCisgIHZvaWQgR2VuZXJhdGVUb3BIZWFkZXJHdWFyZChpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgZmlsZW5hbWVfaWRlbnRpZmllcik7CisgIHZvaWQgR2VuZXJhdGVCb3R0b21IZWFkZXJHdWFyZChpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgZmlsZW5hbWVfaWRlbnRpZmllcik7CisKKyAgLy8gR2VuZXJhdGVzICNpbmNsdWRlIGRpcmVjdGl2ZXMuCisgIHZvaWQgR2VuZXJhdGVMaWJyYXJ5SW5jbHVkZXMoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2b2lkIEdlbmVyYXRlRGVwZW5kZW5jeUluY2x1ZGVzKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworICAvLyBHZW5lcmF0ZXMgYSBjb3VwbGUgb2YgZGlmZmVyZW50IHBpZWNlcyBiZWZvcmUgZGVmaW5pdGlvbnM6CisgIHZvaWQgR2VuZXJhdGVHbG9iYWxTdGF0ZUZ1bmN0aW9uRGVjbGFyYXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworICAvLyBHZW5lcmF0ZXMgdHlwZXMgZm9yIGNsYXNzZXMuCisgIHZvaWQgR2VuZXJhdGVNZXNzYWdlRGVmaW5pdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIC8vIEdlbmVyYXRlcyBmb3J3YXJkLWRlY2xhcmF0aW9ucyBmb3IganVzdCB0aGlzIGZpbGUncyBjbGFzc2VzLiBUaGlzIGlzCisgIC8vIHVzZWQgZm9yIC5wYi5oIGhlYWRlcnMsIGJ1dCBub3QgaW4gcHJvdG9faCBtb2RlLgorICB2b2lkIEdlbmVyYXRlTWVzc2FnZUZvcndhcmREZWNsYXJhdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIC8vIEZpbGxzIGluIHR5cGVzIGZvciBmb3J3YXJkIGRlY2xhcmF0aW9ucy4gVGhpcyBpcyB1c2VkIGludGVybmFsbHksIGFuZAorICAvLyBhbHNvIGJ5IG90aGVyIEZpbGVHZW5lcmF0b3JzIHRvIGRldGVybWluZSBpbXBvcnRzJyBkZWNsYXJhdGlvbnMuCisgIHZvaWQgRmlsbE1lc3NhZ2VGb3J3YXJkRGVjbGFyYXRpb25zKEZvcndhcmREZWNsYXJhdGlvbnMqIGRlY2xzKTsKKyAgdm9pZCBGaWxsTWVzc2FnZURlZmluaXRpb25zKEZvcndhcmREZWNsYXJhdGlvbnMqIGRlY2xzKTsKKworICAvLyBHZW5lcmF0ZXMgZW51bSBkZWZpbml0aW9ucy4KKyAgdm9pZCBHZW5lcmF0ZUVudW1Gb3J3YXJkRGVjbGFyYXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdm9pZCBGaWxsRW51bUZvcndhcmREZWNsYXJhdGlvbnMoRm9yd2FyZERlY2xhcmF0aW9ucyogZGVjbHMpOworICB2b2lkIEdlbmVyYXRlRW51bURlZmluaXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworICAvLyBHZW5lcmF0ZXMgZ2VuZXJpYyBzZXJ2aWNlIGRlZmluaXRpb25zLgorICB2b2lkIEdlbmVyYXRlU2VydmljZURlZmluaXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworICAvLyBHZW5lcmF0ZXMgZXh0ZW5zaW9uIGlkZW50aWZpZXJzLgorICB2b2lkIEdlbmVyYXRlRXh0ZW5zaW9uSWRlbnRpZmllcnMoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIC8vIEdlbmVyYXRlcyBpbmxpbmUgZnVuY3Rpb24gZGVmaW50aW9ucy4KKyAgdm9pZCBHZW5lcmF0ZUlubGluZUZ1bmN0aW9uRGVmaW5pdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIHZvaWQgR2VuZXJhdGVQcm90bzJOYW1lc3BhY2VFbnVtU3BlY2lhbGl6YXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZV87CisKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX2FycmF5PGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8TWVzc2FnZUdlbmVyYXRvcj4gPiBtZXNzYWdlX2dlbmVyYXRvcnNfOworICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfYXJyYXk8Z29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxFbnVtR2VuZXJhdG9yPiA+IGVudW1fZ2VuZXJhdG9yc187CisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9hcnJheTxnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPFNlcnZpY2VHZW5lcmF0b3I+ID4gc2VydmljZV9nZW5lcmF0b3JzXzsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX2FycmF5PGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8RXh0ZW5zaW9uR2VuZXJhdG9yPiA+IGV4dGVuc2lvbl9nZW5lcmF0b3JzXzsKKworICAvLyBFLmcuIGlmIHRoZSBwYWNrYWdlIGlzIGZvby5iYXIsIHBhY2thZ2VfcGFydHNfIGlzIHsiZm9vIiwgImJhciJ9LgorICB2ZWN0b3I8c3RyaW5nPiBwYWNrYWdlX3BhcnRzXzsKKyAgY29uc3QgT3B0aW9ucyBvcHRpb25zXzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoRmlsZUdlbmVyYXRvcik7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgY3BwCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DUFBfRklMRV9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9nZW5lcmF0b3IuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZ2VuZXJhdG9yLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc4MTUyNmIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZ2VuZXJhdG9yLmNjCkBAIC0wLDAgKzEsMTM2IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9nZW5lcmF0b3IuaD4KKworI2luY2x1ZGUgPHZlY3Rvcj4KKyNpbmNsdWRlIDxtZW1vcnk+CisjaWZuZGVmIF9TSEFSRURfUFRSX0gKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc2hhcmVkX3B0ci5oPgorI2VuZGlmCisjaW5jbHVkZSA8dXRpbGl0eT4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2ZpbGUuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgY3BwIHsKKworQ3BwR2VuZXJhdG9yOjpDcHBHZW5lcmF0b3IoKSB7fQorQ3BwR2VuZXJhdG9yOjp+Q3BwR2VuZXJhdG9yKCkge30KKworYm9vbCBDcHBHZW5lcmF0b3I6OkdlbmVyYXRlKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgcGFyYW1ldGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdlbmVyYXRvckNvbnRleHQqIGdlbmVyYXRvcl9jb250ZXh0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyogZXJyb3IpIGNvbnN0IHsKKyAgdmVjdG9yPHBhaXI8c3RyaW5nLCBzdHJpbmc+ID4gb3B0aW9uczsKKyAgUGFyc2VHZW5lcmF0b3JQYXJhbWV0ZXIocGFyYW1ldGVyLCAmb3B0aW9ucyk7CisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgLy8gcGFyc2UgZ2VuZXJhdG9yIG9wdGlvbnMKKworICAvLyBUT0RPKGtlbnRvbik6ICBJZiB3ZSBldmVyIGhhdmUgbW9yZSBvcHRpb25zLCB3ZSBtYXkgd2FudCB0byBjcmVhdGUgYQorICAvLyAgIGNsYXNzIHRoYXQgZW5jYXBzdWxhdGVzIHRoZW0gd2hpY2ggd2UgY2FuIHBhc3MgZG93biB0byBhbGwgdGhlCisgIC8vICAgZ2VuZXJhdG9yIGNsYXNzZXMuICBDdXJyZW50bHkgd2UgcGFzcyBkbGxleHBvcnRfZGVjbCBkb3duIHRvIGFsbCBvZgorICAvLyAgIHRoZW0gdmlhIHRoZSBjb25zdHJ1Y3RvcnMsIGJ1dCB3ZSBkb24ndCB3YW50IHRvIGhhdmUgdG8gYWRkIGFub3RoZXIKKyAgLy8gICBjb25zdHJ1Y3RvciBwYXJhbWV0ZXIgZm9yIGV2ZXJ5IG9wdGlvbi4KKworICAvLyBJZiB0aGUgZGxsZXhwb3J0X2RlY2wgb3B0aW9uIGlzIHBhc3NlZCB0byB0aGUgY29tcGlsZXIsIHdlIG5lZWQgdG8gd3JpdGUKKyAgLy8gaXQgaW4gZnJvbnQgb2YgZXZlcnkgc3ltYm9sIHRoYXQgc2hvdWxkIGJlIGV4cG9ydGVkIGlmIHRoaXMgLnByb3RvIGlzCisgIC8vIGNvbXBpbGVkIGludG8gYSBXaW5kb3dzIERMTC4gIEUuZy4sIGlmIHRoZSB1c2VyIGludm9rZXMgdGhlIHByb3RvY29sCisgIC8vIGNvbXBpbGVyIGFzOgorICAvLyAgIHByb3RvYyAtLWNwcF9vdXQ9ZGxsZXhwb3J0X2RlY2w9Rk9PX0VYUE9SVDpvdXRkaXIgZm9vLnByb3RvCisgIC8vIHRoZW4gd2UnbGwgZGVmaW5lIGNsYXNzZXMgbGlrZSB0aGlzOgorICAvLyAgIGNsYXNzIEZPT19FWFBPUlQgRm9vIHsKKyAgLy8gICAgIC4uLgorICAvLyAgIH0KKyAgLy8gRk9PX0VYUE9SVCBpcyBhIG1hY3JvIHdoaWNoIHNob3VsZCBleHBhbmQgdG8gX19kZWNsc3BlYyhkbGxleHBvcnQpIG9yCisgIC8vIF9fZGVjbHNwZWMoZGxsaW1wb3J0KSBkZXBlbmRpbmcgb24gd2hhdCBpcyBiZWluZyBjb21waWxlZC4KKyAgLy8KKyAgT3B0aW9ucyBmaWxlX29wdGlvbnM7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBvcHRpb25zLnNpemUoKTsgaSsrKSB7CisgICAgaWYgKG9wdGlvbnNbaV0uZmlyc3QgPT0gImRsbGV4cG9ydF9kZWNsIikgeworICAgICAgZmlsZV9vcHRpb25zLmRsbGV4cG9ydF9kZWNsID0gb3B0aW9uc1tpXS5zZWNvbmQ7CisgICAgfSBlbHNlIGlmIChvcHRpb25zW2ldLmZpcnN0ID09ICJzYWZlX2JvdW5kYXJ5X2NoZWNrIikgeworICAgICAgZmlsZV9vcHRpb25zLnNhZmVfYm91bmRhcnlfY2hlY2sgPSB0cnVlOworICAgIH0gZWxzZSB7CisgICAgICAqZXJyb3IgPSAiVW5rbm93biBnZW5lcmF0b3Igb3B0aW9uOiAiICsgb3B0aW9uc1tpXS5maXJzdDsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0KKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisKKyAgc3RyaW5nIGJhc2VuYW1lID0gU3RyaXBQcm90byhmaWxlLT5uYW1lKCkpOworCisgIEZpbGVHZW5lcmF0b3IgZmlsZV9nZW5lcmF0b3IoZmlsZSwgZmlsZV9vcHRpb25zKTsKKworICAvLyBHZW5lcmF0ZSBoZWFkZXIocykuCisgIGlmIChmaWxlX29wdGlvbnMucHJvdG9faCkgeworICAgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8aW86Olplcm9Db3B5T3V0cHV0U3RyZWFtPiBvdXRwdXQoCisgICAgICAgIGdlbmVyYXRvcl9jb250ZXh0LT5PcGVuKGJhc2VuYW1lICsgIi5wcm90by5oIikpOworICAgIGlvOjpQcmludGVyIHByaW50ZXIob3V0cHV0LmdldCgpLCAnJCcpOworICAgIGZpbGVfZ2VuZXJhdG9yLkdlbmVyYXRlUHJvdG9IZWFkZXIoJnByaW50ZXIpOworICB9CisKKyAgYmFzZW5hbWUuYXBwZW5kKCIucGIiKTsKKyAgeworICAgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8aW86Olplcm9Db3B5T3V0cHV0U3RyZWFtPiBvdXRwdXQoCisgICAgICAgIGdlbmVyYXRvcl9jb250ZXh0LT5PcGVuKGJhc2VuYW1lICsgIi5oIikpOworICAgIGlvOjpQcmludGVyIHByaW50ZXIob3V0cHV0LmdldCgpLCAnJCcpOworICAgIGZpbGVfZ2VuZXJhdG9yLkdlbmVyYXRlUEJIZWFkZXIoJnByaW50ZXIpOworICB9CisKKyAgLy8gR2VuZXJhdGUgY2MgZmlsZS4KKyAgeworICAgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8aW86Olplcm9Db3B5T3V0cHV0U3RyZWFtPiBvdXRwdXQoCisgICAgICAgIGdlbmVyYXRvcl9jb250ZXh0LT5PcGVuKGJhc2VuYW1lICsgIi5jYyIpKTsKKyAgICBpbzo6UHJpbnRlciBwcmludGVyKG91dHB1dC5nZXQoKSwgJyQnKTsKKyAgICBmaWxlX2dlbmVyYXRvci5HZW5lcmF0ZVNvdXJjZSgmcHJpbnRlcik7CisgIH0KKworICByZXR1cm4gdHJ1ZTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGNwcAorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9nZW5lcmF0b3IuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9nZW5lcmF0b3IuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZDUxN2NmCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2dlbmVyYXRvci5oCkBAIC0wLDAgKzEsNzIgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBHZW5lcmF0ZXMgQysrIGNvZGUgZm9yIGEgZ2l2ZW4gLnByb3RvIGZpbGUuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NQUF9HRU5FUkFUT1JfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DUFBfR0VORVJBVE9SX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jb2RlX2dlbmVyYXRvci5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGNwcCB7CisKKy8vIENvZGVHZW5lcmF0b3IgaW1wbGVtZW50YXRpb24gd2hpY2ggZ2VuZXJhdGVzIGEgQysrIHNvdXJjZSBmaWxlIGFuZAorLy8gaGVhZGVyLiAgSWYgeW91IGNyZWF0ZSB5b3VyIG93biBwcm90b2NvbCBjb21waWxlciBiaW5hcnkgYW5kIHlvdSB3YW50CisvLyBpdCB0byBzdXBwb3J0IEMrKyBvdXRwdXQsIHlvdSBjYW4gZG8gc28gYnkgcmVnaXN0ZXJpbmcgYW4gaW5zdGFuY2Ugb2YgdGhpcworLy8gQ29kZUdlbmVyYXRvciB3aXRoIHRoZSBDb21tYW5kTGluZUludGVyZmFjZSBpbiB5b3VyIG1haW4oKSBmdW5jdGlvbi4KK2NsYXNzIExJQlBST1RPQ19FWFBPUlQgQ3BwR2VuZXJhdG9yIDogcHVibGljIENvZGVHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgQ3BwR2VuZXJhdG9yKCk7CisgIH5DcHBHZW5lcmF0b3IoKTsKKworICAvLyBpbXBsZW1lbnRzIENvZGVHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICBib29sIEdlbmVyYXRlKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlLAorICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgcGFyYW1ldGVyLAorICAgICAgICAgICAgICAgIEdlbmVyYXRvckNvbnRleHQqIGdlbmVyYXRvcl9jb250ZXh0LAorICAgICAgICAgICAgICAgIHN0cmluZyogZXJyb3IpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKENwcEdlbmVyYXRvcik7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgY3BwCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DUFBfR0VORVJBVE9SX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2hlbHBlcnMuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfaGVscGVycy5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mYjQ2ZTM4Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2hlbHBlcnMuY2MKQEAgLTAsMCArMSw2OTkgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2luY2x1ZGUgPGxpbWl0cz4KKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8dmVjdG9yPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9oYXNoLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbG9nZ2luZy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdWJzdGl0dXRlLmg+CisKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBjcHAgeworCituYW1lc3BhY2UgeworCitzdGF0aWMgY29uc3QgY2hhciBrQW55TWVzc2FnZU5hbWVbXSA9ICJBbnkiOworc3RhdGljIGNvbnN0IGNoYXIga0FueVByb3RvRmlsZVtdID0gImdvb2dsZS9wcm90b2J1Zi9hbnkucHJvdG8iOworc3RhdGljIGNvbnN0IGNoYXIga0dvb2dsZVByb3RvYnVmUHJlZml4W10gPSAiZ29vZ2xlL3Byb3RvYnVmLyI7CisKK3N0cmluZyBEb3RzVG9VbmRlcnNjb3Jlcyhjb25zdCBzdHJpbmcmIG5hbWUpIHsKKyAgcmV0dXJuIFN0cmluZ1JlcGxhY2UobmFtZSwgIi4iLCAiXyIsIHRydWUpOworfQorCitzdHJpbmcgRG90c1RvQ29sb25zKGNvbnN0IHN0cmluZyYgbmFtZSkgeworICByZXR1cm4gU3RyaW5nUmVwbGFjZShuYW1lLCAiLiIsICI6OiIsIHRydWUpOworfQorCitjb25zdCBjaGFyKiBjb25zdCBrS2V5d29yZExpc3RbXSA9IHsKKyAgImFsaWduYXMiLCAiYWxpZ25vZiIsICJhbmQiLCAiYW5kX2VxIiwgImFzbSIsICJhdXRvIiwgImJpdGFuZCIsICJiaXRvciIsCisgICJib29sIiwgImJyZWFrIiwgImNhc2UiLCAiY2F0Y2giLCAiY2hhciIsICJjbGFzcyIsICJjb21wbCIsICJjb25zdCIsCisgICJjb25zdGV4cHIiLCAiY29uc3RfY2FzdCIsICJjb250aW51ZSIsICJkZWNsdHlwZSIsICJkZWZhdWx0IiwgImRlbGV0ZSIsICJkbyIsCisgICJkb3VibGUiLCAiZHluYW1pY19jYXN0IiwgImVsc2UiLCAiZW51bSIsICJleHBsaWNpdCIsICJleHRlcm4iLCAiZmFsc2UiLAorICAiZmxvYXQiLCAiZm9yIiwgImZyaWVuZCIsICJnb3RvIiwgImlmIiwgImlubGluZSIsICJpbnQiLCAibG9uZyIsICJtdXRhYmxlIiwKKyAgIm5hbWVzcGFjZSIsICJuZXciLCAibm9leGNlcHQiLCAibm90IiwgIm5vdF9lcSIsICJOVUxMIiwgIm9wZXJhdG9yIiwgIm9yIiwKKyAgIm9yX2VxIiwgInByaXZhdGUiLCAicHJvdGVjdGVkIiwgInB1YmxpYyIsICJyZWdpc3RlciIsICJyZWludGVycHJldF9jYXN0IiwKKyAgInJldHVybiIsICJzaG9ydCIsICJzaWduZWQiLCAic2l6ZW9mIiwgInN0YXRpYyIsICJzdGF0aWNfYXNzZXJ0IiwKKyAgInN0YXRpY19jYXN0IiwgInN0cnVjdCIsICJzd2l0Y2giLCAidGVtcGxhdGUiLCAidGhpcyIsICJ0aHJlYWRfbG9jYWwiLAorICAidGhyb3ciLCAidHJ1ZSIsICJ0cnkiLCAidHlwZWRlZiIsICJ0eXBlaWQiLCAidHlwZW5hbWUiLCAidW5pb24iLCAidW5zaWduZWQiLAorICAidXNpbmciLCAidmlydHVhbCIsICJ2b2lkIiwgInZvbGF0aWxlIiwgIndjaGFyX3QiLCAid2hpbGUiLCAieG9yIiwgInhvcl9lcSIKK307CisKK2hhc2hfc2V0PHN0cmluZz4gTWFrZUtleXdvcmRzTWFwKCkgeworICBoYXNoX3NldDxzdHJpbmc+IHJlc3VsdDsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBHT09HTEVfQVJSQVlTSVpFKGtLZXl3b3JkTGlzdCk7IGkrKykgeworICAgIHJlc3VsdC5pbnNlcnQoa0tleXdvcmRMaXN0W2ldKTsKKyAgfQorICByZXR1cm4gcmVzdWx0OworfQorCitoYXNoX3NldDxzdHJpbmc+IGtLZXl3b3JkcyA9IE1ha2VLZXl3b3Jkc01hcCgpOworCisvLyBSZXR1cm5zIHdoZXRoZXIgdGhlIHByb3ZpZGVkIGRlc2NyaXB0b3IgaGFzIGFuIGV4dGVuc2lvbi4gVGhpcyBpbmNsdWRlcyBpdHMKKy8vIG5lc3RlZCB0eXBlcy4KK2Jvb2wgSGFzRXh0ZW5zaW9uKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgaWYgKGRlc2NyaXB0b3ItPmV4dGVuc2lvbl9jb3VudCgpID4gMCkgeworICAgIHJldHVybiB0cnVlOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvci0+bmVzdGVkX3R5cGVfY291bnQoKTsgKytpKSB7CisgICAgaWYgKEhhc0V4dGVuc2lvbihkZXNjcmlwdG9yLT5uZXN0ZWRfdHlwZShpKSkpIHsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgfQorICByZXR1cm4gZmFsc2U7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCitzdHJpbmcgVW5kZXJzY29yZXNUb0NhbWVsQ2FzZShjb25zdCBzdHJpbmcmIGlucHV0LCBib29sIGNhcF9uZXh0X2xldHRlcikgeworICBzdHJpbmcgcmVzdWx0OworICAvLyBOb3RlOiAgSSBkaXN0cnVzdCBjdHlwZS5oIGR1ZSB0byBsb2NhbGVzLgorICBmb3IgKGludCBpID0gMDsgaSA8IGlucHV0LnNpemUoKTsgaSsrKSB7CisgICAgaWYgKCdhJyA8PSBpbnB1dFtpXSAmJiBpbnB1dFtpXSA8PSAneicpIHsKKyAgICAgIGlmIChjYXBfbmV4dF9sZXR0ZXIpIHsKKyAgICAgICAgcmVzdWx0ICs9IGlucHV0W2ldICsgKCdBJyAtICdhJyk7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXN1bHQgKz0gaW5wdXRbaV07CisgICAgICB9CisgICAgICBjYXBfbmV4dF9sZXR0ZXIgPSBmYWxzZTsKKyAgICB9IGVsc2UgaWYgKCdBJyA8PSBpbnB1dFtpXSAmJiBpbnB1dFtpXSA8PSAnWicpIHsKKyAgICAgIC8vIENhcGl0YWwgbGV0dGVycyBhcmUgbGVmdCBhcy1pcy4KKyAgICAgIHJlc3VsdCArPSBpbnB1dFtpXTsKKyAgICAgIGNhcF9uZXh0X2xldHRlciA9IGZhbHNlOworICAgIH0gZWxzZSBpZiAoJzAnIDw9IGlucHV0W2ldICYmIGlucHV0W2ldIDw9ICc5JykgeworICAgICAgcmVzdWx0ICs9IGlucHV0W2ldOworICAgICAgY2FwX25leHRfbGV0dGVyID0gdHJ1ZTsKKyAgICB9IGVsc2UgeworICAgICAgY2FwX25leHRfbGV0dGVyID0gdHJ1ZTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIHJlc3VsdDsKK30KKworY29uc3QgY2hhciBrVGhpY2tTZXBhcmF0b3JbXSA9CisgICIvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4iOworY29uc3QgY2hhciBrVGhpblNlcGFyYXRvcltdID0KKyAgIi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiI7CisKK3N0cmluZyBDbGFzc05hbWUoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwgYm9vbCBxdWFsaWZpZWQpIHsKKworICAvLyBGaW5kICJvdXRlciIsIHRoZSBkZXNjcmlwdG9yIG9mIHRoZSB0b3AtbGV2ZWwgbWVzc2FnZSBpbiB3aGljaAorICAvLyAiZGVzY3JpcHRvciIgaXMgZW1iZWRkZWQuCisgIGNvbnN0IERlc2NyaXB0b3IqIG91dGVyID0gZGVzY3JpcHRvcjsKKyAgd2hpbGUgKG91dGVyLT5jb250YWluaW5nX3R5cGUoKSAhPSBOVUxMKSBvdXRlciA9IG91dGVyLT5jb250YWluaW5nX3R5cGUoKTsKKworICBjb25zdCBzdHJpbmcmIG91dGVyX25hbWUgPSBvdXRlci0+ZnVsbF9uYW1lKCk7CisgIHN0cmluZyBpbm5lcl9uYW1lID0gZGVzY3JpcHRvci0+ZnVsbF9uYW1lKCkuc3Vic3RyKG91dGVyX25hbWUuc2l6ZSgpKTsKKworICBpZiAocXVhbGlmaWVkKSB7CisgICAgcmV0dXJuICI6OiIgKyBEb3RzVG9Db2xvbnMob3V0ZXJfbmFtZSkgKyBEb3RzVG9VbmRlcnNjb3Jlcyhpbm5lcl9uYW1lKTsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gb3V0ZXItPm5hbWUoKSArIERvdHNUb1VuZGVyc2NvcmVzKGlubmVyX25hbWUpOworICB9Cit9CisKK3N0cmluZyBDbGFzc05hbWUoY29uc3QgRW51bURlc2NyaXB0b3IqIGVudW1fZGVzY3JpcHRvciwgYm9vbCBxdWFsaWZpZWQpIHsKKyAgaWYgKGVudW1fZGVzY3JpcHRvci0+Y29udGFpbmluZ190eXBlKCkgPT0gTlVMTCkgeworICAgIGlmIChxdWFsaWZpZWQpIHsKKyAgICAgIHJldHVybiAiOjoiICsgRG90c1RvQ29sb25zKGVudW1fZGVzY3JpcHRvci0+ZnVsbF9uYW1lKCkpOworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gZW51bV9kZXNjcmlwdG9yLT5uYW1lKCk7CisgICAgfQorICB9IGVsc2UgeworICAgIHN0cmluZyByZXN1bHQgPSBDbGFzc05hbWUoZW51bV9kZXNjcmlwdG9yLT5jb250YWluaW5nX3R5cGUoKSwgcXVhbGlmaWVkKTsKKyAgICByZXN1bHQgKz0gJ18nOworICAgIHJlc3VsdCArPSBlbnVtX2Rlc2NyaXB0b3ItPm5hbWUoKTsKKyAgICByZXR1cm4gcmVzdWx0OworICB9Cit9CisKKworc3RyaW5nIERlcGVuZGVudEJhc2VDbGFzc1RlbXBsYXRlTmFtZShjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIHJldHVybiBDbGFzc05hbWUoZGVzY3JpcHRvciwgZmFsc2UpICsgIl9JbnRlcm5hbEJhc2UiOworfQorCitzdHJpbmcgU3VwZXJDbGFzc05hbWUoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICByZXR1cm4gSGFzRGVzY3JpcHRvck1ldGhvZHMoZGVzY3JpcHRvci0+ZmlsZSgpKSA/CisgICAgICAiOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlIiA6ICI6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VMaXRlIjsKK30KKworc3RyaW5nIERlcGVuZGVudEJhc2VEb3duQ2FzdCgpIHsKKyAgcmV0dXJuICJyZWludGVycHJldF9jYXN0PFQqPih0aGlzKS0+IjsKK30KKworc3RyaW5nIERlcGVuZGVudEJhc2VDb25zdERvd25DYXN0KCkgeworICByZXR1cm4gInJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgVCo+KHRoaXMpLT4iOworfQorCitzdHJpbmcgRmllbGROYW1lKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgc3RyaW5nIHJlc3VsdCA9IGZpZWxkLT5uYW1lKCk7CisgIExvd2VyU3RyaW5nKCZyZXN1bHQpOworICBpZiAoa0tleXdvcmRzLmNvdW50KHJlc3VsdCkgPiAwKSB7CisgICAgcmVzdWx0LmFwcGVuZCgiXyIpOworICB9CisgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0cmluZyBFbnVtVmFsdWVOYW1lKGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIGVudW1fdmFsdWUpIHsKKyAgc3RyaW5nIHJlc3VsdCA9IGVudW1fdmFsdWUtPm5hbWUoKTsKKyAgaWYgKGtLZXl3b3Jkcy5jb3VudChyZXN1bHQpID4gMCkgeworICAgIHJlc3VsdC5hcHBlbmQoIl8iKTsKKyAgfQorICByZXR1cm4gcmVzdWx0OworfQorCitzdHJpbmcgRmllbGRDb25zdGFudE5hbWUoY29uc3QgRmllbGREZXNjcmlwdG9yICpmaWVsZCkgeworICBzdHJpbmcgZmllbGRfbmFtZSA9IFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoZmllbGQtPm5hbWUoKSwgdHJ1ZSk7CisgIHN0cmluZyByZXN1bHQgPSAiayIgKyBmaWVsZF9uYW1lICsgIkZpZWxkTnVtYmVyIjsKKworICBpZiAoIWZpZWxkLT5pc19leHRlbnNpb24oKSAmJgorICAgICAgZmllbGQtPmNvbnRhaW5pbmdfdHlwZSgpLT5GaW5kRmllbGRCeUNhbWVsY2FzZU5hbWUoCisgICAgICAgIGZpZWxkLT5jYW1lbGNhc2VfbmFtZSgpKSAhPSBmaWVsZCkgeworICAgIC8vIFRoaXMgZmllbGQncyBjYW1lbGNhc2UgbmFtZSBpcyBub3QgdW5pcXVlLiAgQXMgYSBoYWNrLCBhZGQgdGhlIGZpZWxkCisgICAgLy8gbnVtYmVyIHRvIHRoZSBjb25zdGFudCBuYW1lLiAgVGhpcyBtYWtlcyB0aGUgY29uc3RhbnQgcmF0aGVyIHVzZWxlc3MsCisgICAgLy8gYnV0IHdoYXQgY2FuIHdlIGRvPworICAgIHJlc3VsdCArPSAiXyIgKyBTaW1wbGVJdG9hKGZpZWxkLT5udW1iZXIoKSk7CisgIH0KKworICByZXR1cm4gcmVzdWx0OworfQorCitib29sIElzRmllbGREZXBlbmRlbnQoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICBpZiAoZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSAhPSBOVUxMICYmCisgICAgICBmaWVsZC0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HKSB7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKyAgaWYgKGZpZWxkLT5pc19tYXAoKSkgeworICAgIGNvbnN0IERlc2NyaXB0b3IqIG1hcF9kZXNjcmlwdG9yID0gZmllbGQtPm1lc3NhZ2VfdHlwZSgpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWFwX2Rlc2NyaXB0b3ItPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgICAgaWYgKElzRmllbGREZXBlbmRlbnQobWFwX2Rlc2NyaXB0b3ItPmZpZWxkKGkpKSkgeworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIGlmIChmaWVsZC0+Y3BwX3R5cGUoKSAhPSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICBpZiAoZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSAhPSBOVUxMKSB7CisgICAgLy8gT25lb2YgZmllbGRzIHdpbGwgYWx3YXlzIGJlIGRlcGVuZGVudC4KKyAgICAvLworICAgIC8vIFRoaXMgaXMgYSB1bmlxdWUgY2FzZSBmb3IgZmllbGQgY29kZWdlbi4gRmllbGQgZ2VuZXJhdG9ycyBhcmUKKyAgICAvLyByZXNwb25zaWJsZSBmb3IgZ2VuZXJhdGluZyBhbGwgdGhlIGZpZWxkLXNwZWNpZmljIGFjY2Vzc29yCisgICAgLy8gZnVuY3Rpb25zLCBleGNlcHQgZm9yIHRoZSBjbGVhcl8qKCkgZnVuY3Rpb247IGluc3RlYWQsIGZpZWxkCisgICAgLy8gZ2VuZXJhdG9ycyBwcm9kdWNlIGlubGluZSBjbGVhcmluZyBjb2RlLgorICAgIC8vCisgICAgLy8gRm9yIG5vbi1vbmVvZiBmaWVsZHMsIHRoZSBNZXNzYWdlIGNsYXNzIHVzZXMgdGhlIGlubGluZSBjbGVhcmluZworICAgIC8vIGNvZGUgdG8gZGVmaW5lIHRoZSBmaWVsZCdzIGNsZWFyXyooKSBmdW5jdGlvbiwgYXMgd2VsbCBhcyBpbiB0aGUKKyAgICAvLyBkZXN0cnVjdG9yLiBGb3Igb25lb2YgZmllbGRzLCB0aGUgTWVzc2FnZSBjbGFzcyBnZW5lcmF0ZXMgYSBtdWNoCisgICAgLy8gbW9yZSBjb21wbGljYXRlZCBjbGVhcl8qKCkgZnVuY3Rpb24sIHdoaWNoIGNsZWFycyBvbmx5IHRoZSBvbmVvZgorICAgIC8vIG1lbWJlciB0aGF0IGlzIHNldCwgaW4gYWRkaXRpb24gdG8gY2xlYXJpbmcgbWV0aG9kcyBmb3IgZWFjaCBvZiB0aGUKKyAgICAvLyBvbmVvZiBtZW1iZXJzIGluZGl2aWR1YWxseS4KKyAgICAvLworICAgIC8vIFNpbmNlIG9uZW9mcyBkbyBub3QgaGF2ZSB0aGVpciBvd24gZ2VuZXJhdG9yIGNsYXNzLCB0aGUgTWVzc2FnZSBjb2RlCisgICAgLy8gZ2VuZXJhdGlvbiBsb2dpYyB3b3VsZCBiZSBzaWduaWZpY2FudGx5IGNvbXBsaWNhdGVkIGluIG9yZGVyIHRvCisgICAgLy8gc3BsaXQgZGVwZW5kZW50IGFuZCBub24tZGVwZW5kZW50IG1hbmlwdWxhdGlvbiBsb2dpYyBiYXNlZCBvbgorICAgIC8vIHdoZXRoZXIgdGhlIG9uZW9mIHRydWx5IG5lZWRzIHRvIGJlIGRlcGVuZGVudDsgc28sIGZvciBvbmVvZiBmaWVsZHMsCisgICAgLy8gd2UganVzdCBhc3N1bWUgaXQgKGFuZCBpdHMgY29uc3RpdHVlbnRzKSBzaG91bGQgYmUgbWFuaXB1bGF0ZWQgYnkgYQorICAgIC8vIGRlcGVuZGVudCBiYXNlIGNsYXNzIGZ1bmN0aW9uLgorICAgIC8vCisgICAgLy8gVGhpcyBpcyBsZXNzIHByZWNpc2UgdGhhbiBob3cgZGVwZW5kZW50IG1lc3NhZ2UtdHlwZWQgZmllbGRzIGFyZQorICAgIC8vIGhhbmRsZWQsIGJ1dCB0aGUgY29zdCBpcyBsaW1pdGVkIHRvIG9ubHkgdGhlIGdlbmVyYXRlZCBjb2RlIGZvciB0aGUKKyAgICAvLyBvbmVvZiBmaWVsZCwgd2hpY2ggc2VlbXMgbGlrZSBhbiBhY2NlcHRhYmxlIHRyYWRlb2ZmLgorICAgIHJldHVybiB0cnVlOworICB9CisgIGlmIChmaWVsZC0+ZmlsZSgpID09IGZpZWxkLT5tZXNzYWdlX3R5cGUoKS0+ZmlsZSgpKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIHJldHVybiB0cnVlOworfQorCitzdHJpbmcgRGVwZW5kZW50VHlwZU5hbWUoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICByZXR1cm4gIkludGVybmFsQmFzZV8iICsgZmllbGQtPm5hbWUoKSArICJfVCI7Cit9CisKK3N0cmluZyBGaWVsZE1lc3NhZ2VUeXBlTmFtZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIC8vIE5vdGU6ICBUaGUgR29vZ2xlLWludGVybmFsIHZlcnNpb24gb2YgUHJvdG9jb2wgQnVmZmVycyB1c2VzIHRoaXMgZnVuY3Rpb24KKyAgLy8gICBhcyBhIGhvb2sgcG9pbnQgZm9yIGhhY2tzIHRvIHN1cHBvcnQgbGVnYWN5IGNvZGUuCisgIHJldHVybiBDbGFzc05hbWUoZmllbGQtPm1lc3NhZ2VfdHlwZSgpLCB0cnVlKTsKK30KKworc3RyaW5nIFN0cmlwUHJvdG8oY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSkgeworICBpZiAoSGFzU3VmZml4U3RyaW5nKGZpbGVuYW1lLCAiLnByb3RvZGV2ZWwiKSkgeworICAgIHJldHVybiBTdHJpcFN1ZmZpeFN0cmluZyhmaWxlbmFtZSwgIi5wcm90b2RldmVsIik7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIFN0cmlwU3VmZml4U3RyaW5nKGZpbGVuYW1lLCAiLnByb3RvIik7CisgIH0KK30KKworY29uc3QgY2hhciogUHJpbWl0aXZlVHlwZU5hbWUoRmllbGREZXNjcmlwdG9yOjpDcHBUeXBlIHR5cGUpIHsKKyAgc3dpdGNoICh0eXBlKSB7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UMzIgIDogcmV0dXJuICI6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9JTlQ2NCAgOiByZXR1cm4gIjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50NjQiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1VJTlQzMiA6IHJldHVybiAiOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1VJTlQ2NCA6IHJldHVybiAiOjpnb29nbGU6OnByb3RvYnVmOjp1aW50NjQiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0RPVUJMRSA6IHJldHVybiAiZG91YmxlIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9GTE9BVCAgOiByZXR1cm4gImZsb2F0IjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9CT09MICAgOiByZXR1cm4gImJvb2wiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0VOVU0gICA6IHJldHVybiAiaW50IjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9TVFJJTkcgOiByZXR1cm4gIjo6c3RkOjpzdHJpbmciOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U6IHJldHVybiBOVUxMOworCisgICAgLy8gTm8gZGVmYXVsdCBiZWNhdXNlIHdlIHdhbnQgdGhlIGNvbXBpbGVyIHRvIGNvbXBsYWluIGlmIGFueSBuZXcKKyAgICAvLyBDcHBUeXBlcyBhcmUgYWRkZWQuCisgIH0KKworICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ2FuJ3QgZ2V0IGhlcmUuIjsKKyAgcmV0dXJuIE5VTEw7Cit9CisKK2NvbnN0IGNoYXIqIERlY2xhcmVkVHlwZU1ldGhvZE5hbWUoRmllbGREZXNjcmlwdG9yOjpUeXBlIHR5cGUpIHsKKyAgc3dpdGNoICh0eXBlKSB7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfSU5UMzIgICA6IHJldHVybiAiSW50MzIiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0lOVDY0ICAgOiByZXR1cm4gIkludDY0IjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9VSU5UMzIgIDogcmV0dXJuICJVSW50MzIiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1VJTlQ2NCAgOiByZXR1cm4gIlVJbnQ2NCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0lOVDMyICA6IHJldHVybiAiU0ludDMyIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TSU5UNjQgIDogcmV0dXJuICJTSW50NjQiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0ZJWEVEMzIgOiByZXR1cm4gIkZpeGVkMzIiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0ZJWEVENjQgOiByZXR1cm4gIkZpeGVkNjQiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NGSVhFRDMyOiByZXR1cm4gIlNGaXhlZDMyIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TRklYRUQ2NDogcmV0dXJuICJTRml4ZWQ2NCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRkxPQVQgICA6IHJldHVybiAiRmxvYXQiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0RPVUJMRSAgOiByZXR1cm4gIkRvdWJsZSI7CisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9CT09MICAgIDogcmV0dXJuICJCb29sIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9FTlVNICAgIDogcmV0dXJuICJFbnVtIjsKKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NUUklORyAgOiByZXR1cm4gIlN0cmluZyI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfQllURVMgICA6IHJldHVybiAiQnl0ZXMiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQICAgOiByZXR1cm4gIkdyb3VwIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9NRVNTQUdFIDogcmV0dXJuICJNZXNzYWdlIjsKKworICAgIC8vIE5vIGRlZmF1bHQgYmVjYXVzZSB3ZSB3YW50IHRoZSBjb21waWxlciB0byBjb21wbGFpbiBpZiBhbnkgbmV3CisgICAgLy8gdHlwZXMgYXJlIGFkZGVkLgorICB9CisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJDYW4ndCBnZXQgaGVyZS4iOworICByZXR1cm4gIiI7Cit9CisKK3N0cmluZyBJbnQzMlRvU3RyaW5nKGludCBudW1iZXIpIHsKKyAgLy8gZ2NjIHJlamVjdHMgdGhlIGRlY2ltYWwgZm9ybSBvZiBraW50MzJtaW4uCisgIGlmIChudW1iZXIgPT0ga2ludDMybWluKSB7CisgICAgR09PR0xFX0NPTVBJTEVfQVNTRVJUKGtpbnQzMm1pbiA9PSAofjB4N2ZmZmZmZmYpLCBraW50MzJtaW5fdmFsdWVfZXJyb3IpOworICAgIHJldHVybiAiKH4weDdmZmZmZmZmKSI7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIFNpbXBsZUl0b2EobnVtYmVyKTsKKyAgfQorfQorCitzdHJpbmcgSW50NjRUb1N0cmluZyhpbnQ2NCBudW1iZXIpIHsKKyAgLy8gZ2NjIHJlamVjdHMgdGhlIGRlY2ltYWwgZm9ybSBvZiBraW50NjRtaW4KKyAgaWYgKG51bWJlciA9PSBraW50NjRtaW4pIHsKKyAgICAvLyBNYWtlIHN1cmUgd2UgYXJlIGluIGEgMidzIGNvbXBsZW1lbnQgc3lzdGVtLgorICAgIEdPT0dMRV9DT01QSUxFX0FTU0VSVChraW50NjRtaW4gPT0gR09PR0xFX0xPTkdMT05HKH4weDdmZmZmZmZmZmZmZmZmZmYpLAorICAgICAgICAgICAgICAgICAgIGtpbnQ2NG1pbl92YWx1ZV9lcnJvcik7CisgICAgcmV0dXJuICJHT09HTEVfTE9OR0xPTkcofjB4N2ZmZmZmZmZmZmZmZmZmZikiOworICB9CisgIHJldHVybiAiR09PR0xFX0xPTkdMT05HKCIgKyBTaW1wbGVJdG9hKG51bWJlcikgKyAiKSI7Cit9CisKK3N0cmluZyBEZWZhdWx0VmFsdWUoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICBzd2l0Y2ggKGZpZWxkLT5jcHBfdHlwZSgpKSB7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UMzI6CisgICAgICByZXR1cm4gSW50MzJUb1N0cmluZyhmaWVsZC0+ZGVmYXVsdF92YWx1ZV9pbnQzMigpKTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9VSU5UMzI6CisgICAgICByZXR1cm4gU2ltcGxlSXRvYShmaWVsZC0+ZGVmYXVsdF92YWx1ZV91aW50MzIoKSkgKyAidSI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UNjQ6CisgICAgICByZXR1cm4gSW50NjRUb1N0cmluZyhmaWVsZC0+ZGVmYXVsdF92YWx1ZV9pbnQ2NCgpKTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9VSU5UNjQ6CisgICAgICByZXR1cm4gIkdPT0dMRV9VTE9OR0xPTkcoIiArIFNpbXBsZUl0b2EoZmllbGQtPmRlZmF1bHRfdmFsdWVfdWludDY0KCkpKyAiKSI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRE9VQkxFOiB7CisgICAgICBkb3VibGUgdmFsdWUgPSBmaWVsZC0+ZGVmYXVsdF92YWx1ZV9kb3VibGUoKTsKKyAgICAgIGlmICh2YWx1ZSA9PSBudW1lcmljX2xpbWl0czxkb3VibGU+OjppbmZpbml0eSgpKSB7CisgICAgICAgIHJldHVybiAiOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6SW5maW5pdHkoKSI7CisgICAgICB9IGVsc2UgaWYgKHZhbHVlID09IC1udW1lcmljX2xpbWl0czxkb3VibGU+OjppbmZpbml0eSgpKSB7CisgICAgICAgIHJldHVybiAiLTo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkluZmluaXR5KCkiOworICAgICAgfSBlbHNlIGlmICh2YWx1ZSAhPSB2YWx1ZSkgeworICAgICAgICByZXR1cm4gIjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6Ok5hTigpIjsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiBTaW1wbGVEdG9hKHZhbHVlKTsKKyAgICAgIH0KKyAgICB9CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRkxPQVQ6CisgICAgICB7CisgICAgICAgIGZsb2F0IHZhbHVlID0gZmllbGQtPmRlZmF1bHRfdmFsdWVfZmxvYXQoKTsKKyAgICAgICAgaWYgKHZhbHVlID09IG51bWVyaWNfbGltaXRzPGZsb2F0Pjo6aW5maW5pdHkoKSkgeworICAgICAgICAgIHJldHVybiAic3RhdGljX2Nhc3Q8ZmxvYXQ+KDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkluZmluaXR5KCkpIjsKKyAgICAgICAgfSBlbHNlIGlmICh2YWx1ZSA9PSAtbnVtZXJpY19saW1pdHM8ZmxvYXQ+OjppbmZpbml0eSgpKSB7CisgICAgICAgICAgcmV0dXJuICJzdGF0aWNfY2FzdDxmbG9hdD4oLTo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkluZmluaXR5KCkpIjsKKyAgICAgICAgfSBlbHNlIGlmICh2YWx1ZSAhPSB2YWx1ZSkgeworICAgICAgICAgIHJldHVybiAic3RhdGljX2Nhc3Q8ZmxvYXQ+KDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6Ok5hTigpKSI7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc3RyaW5nIGZsb2F0X3ZhbHVlID0gU2ltcGxlRnRvYSh2YWx1ZSk7CisgICAgICAgICAgLy8gSWYgZmxvYXRpbmcgcG9pbnQgdmFsdWUgY29udGFpbnMgYSBwZXJpb2QgKC4pIG9yIGFuIGV4cG9uZW50CisgICAgICAgICAgLy8gKGVpdGhlciBFIG9yIGUpLCB0aGVuIGFwcGVuZCBzdWZmaXggJ2YnIHRvIG1ha2UgaXQgYSBmbG9hdAorICAgICAgICAgIC8vIGxpdGVyYWwuCisgICAgICAgICAgaWYgKGZsb2F0X3ZhbHVlLmZpbmRfZmlyc3Rfb2YoIi5lRSIpICE9IHN0cmluZzo6bnBvcykgeworICAgICAgICAgICAgZmxvYXRfdmFsdWUucHVzaF9iYWNrKCdmJyk7CisgICAgICAgICAgfQorICAgICAgICAgIHJldHVybiBmbG9hdF92YWx1ZTsKKyAgICAgICAgfQorICAgICAgfQorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0JPT0w6CisgICAgICByZXR1cm4gZmllbGQtPmRlZmF1bHRfdmFsdWVfYm9vbCgpID8gInRydWUiIDogImZhbHNlIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9FTlVNOgorICAgICAgLy8gTGF6eTogIEdlbmVyYXRlIGEgc3RhdGljX2Nhc3QgYmVjYXVzZSB3ZSBkb24ndCBoYXZlIGEgaGVscGVyIGZ1bmN0aW9uCisgICAgICAvLyAgIHRoYXQgY29uc3RydWN0cyB0aGUgZnVsbCBuYW1lIG9mIGFuIGVudW0gdmFsdWUuCisgICAgICByZXR1cm4gc3RyaW5nczo6U3Vic3RpdHV0ZSgKKyAgICAgICAgICAic3RhdGljX2Nhc3Q8ICQwID4oJDEpIiwKKyAgICAgICAgICBDbGFzc05hbWUoZmllbGQtPmVudW1fdHlwZSgpLCB0cnVlKSwKKyAgICAgICAgICBJbnQzMlRvU3RyaW5nKGZpZWxkLT5kZWZhdWx0X3ZhbHVlX2VudW0oKS0+bnVtYmVyKCkpKTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9TVFJJTkc6CisgICAgICByZXR1cm4gIlwiIiArIEVzY2FwZVRyaWdyYXBocygKKyAgICAgICAgQ0VzY2FwZShmaWVsZC0+ZGVmYXVsdF92YWx1ZV9zdHJpbmcoKSkpICsKKyAgICAgICAgIlwiIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgcmV0dXJuIEZpZWxkTWVzc2FnZVR5cGVOYW1lKGZpZWxkKSArICI6OmRlZmF1bHRfaW5zdGFuY2UoKSI7CisgIH0KKyAgLy8gQ2FuJ3QgYWN0dWFsbHkgZ2V0IGhlcmU7IG1ha2UgY29tcGlsZXIgaGFwcHkuICAoV2UgY291bGQgYWRkIGEgZGVmYXVsdAorICAvLyBjYXNlIGFib3ZlIGJ1dCB0aGVuIHdlIHdvdWxkbid0IGdldCB0aGUgbmljZSBjb21waWxlciB3YXJuaW5nIHdoZW4gYQorICAvLyBuZXcgdHlwZSBpcyBhZGRlZC4pCisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJDYW4ndCBnZXQgaGVyZS4iOworICByZXR1cm4gIiI7Cit9CisKKy8vIENvbnZlcnQgYSBmaWxlIG5hbWUgaW50byBhIHZhbGlkIGlkZW50aWZpZXIuCitzdHJpbmcgRmlsZW5hbWVJZGVudGlmaWVyKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUpIHsKKyAgc3RyaW5nIHJlc3VsdDsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlbmFtZS5zaXplKCk7IGkrKykgeworICAgIGlmIChhc2NpaV9pc2FsbnVtKGZpbGVuYW1lW2ldKSkgeworICAgICAgcmVzdWx0LnB1c2hfYmFjayhmaWxlbmFtZVtpXSk7CisgICAgfSBlbHNlIHsKKyAgICAgIC8vIE5vdCBhbHBoYW51bWVyaWMuICBUbyBhdm9pZCBhbnkgcG9zc2liaWxpdHkgb2YgbmFtZSBjb25mbGljdHMgd2UKKyAgICAgIC8vIHVzZSB0aGUgaGV4IGNvZGUgZm9yIHRoZSBjaGFyYWN0ZXIuCisgICAgICBTdHJBcHBlbmQoJnJlc3VsdCwgIl8iLCBzdHJpbmdzOjpIZXgoc3RhdGljX2Nhc3Q8dWludDg+KGZpbGVuYW1lW2ldKSkpOworICAgIH0KKyAgfQorICByZXR1cm4gcmVzdWx0OworfQorCisvLyBSZXR1cm4gdGhlIG5hbWUgb2YgdGhlIEFkZERlc2NyaXB0b3JzKCkgZnVuY3Rpb24gZm9yIGEgZ2l2ZW4gZmlsZS4KK3N0cmluZyBHbG9iYWxBZGREZXNjcmlwdG9yc05hbWUoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSkgeworICByZXR1cm4gInByb3RvYnVmX0FkZERlc2NfIiArIEZpbGVuYW1lSWRlbnRpZmllcihmaWxlbmFtZSk7Cit9CisKKy8vIFJldHVybiB0aGUgbmFtZSBvZiB0aGUgQXNzaWduRGVzY3JpcHRvcnMoKSBmdW5jdGlvbiBmb3IgYSBnaXZlbiBmaWxlLgorc3RyaW5nIEdsb2JhbEFzc2lnbkRlc2NyaXB0b3JzTmFtZShjb25zdCBzdHJpbmcmIGZpbGVuYW1lKSB7CisgIHJldHVybiAicHJvdG9idWZfQXNzaWduRGVzY18iICsgRmlsZW5hbWVJZGVudGlmaWVyKGZpbGVuYW1lKTsKK30KKworLy8gUmV0dXJuIHRoZSBuYW1lIG9mIHRoZSBTaHV0ZG93bkZpbGUoKSBmdW5jdGlvbiBmb3IgYSBnaXZlbiBmaWxlLgorc3RyaW5nIEdsb2JhbFNodXRkb3duRmlsZU5hbWUoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSkgeworICByZXR1cm4gInByb3RvYnVmX1NodXRkb3duRmlsZV8iICsgRmlsZW5hbWVJZGVudGlmaWVyKGZpbGVuYW1lKTsKK30KKworLy8gUmV0dXJuIHRoZSBxdWFsaWZpZWQgQysrIG5hbWUgZm9yIGEgZmlsZSBsZXZlbCBzeW1ib2wuCitzdHJpbmcgUXVhbGlmaWVkRmlsZUxldmVsU3ltYm9sKGNvbnN0IHN0cmluZyYgcGFja2FnZSwgY29uc3Qgc3RyaW5nJiBuYW1lKSB7CisgIGlmIChwYWNrYWdlLmVtcHR5KCkpIHsKKyAgICByZXR1cm4gU3RyQ2F0KCI6OiIsIG5hbWUpOworICB9CisgIHJldHVybiBTdHJDYXQoIjo6IiwgRG90c1RvQ29sb25zKHBhY2thZ2UpLCAiOjoiLCBuYW1lKTsKK30KKworLy8gRXNjYXBlIEMrKyB0cmlncmFwaHMgYnkgZXNjYXBpbmcgcXVlc3Rpb24gbWFya3MgdG8gXD8KK3N0cmluZyBFc2NhcGVUcmlncmFwaHMoY29uc3Qgc3RyaW5nJiB0b19lc2NhcGUpIHsKKyAgcmV0dXJuIFN0cmluZ1JlcGxhY2UodG9fZXNjYXBlLCAiPyIsICJcXD8iLCB0cnVlKTsKK30KKworLy8gRXNjYXBlZCBmdW5jdGlvbiBuYW1lIHRvIGVsaW1pbmF0ZSBuYW1pbmcgY29uZmxpY3QuCitzdHJpbmcgU2FmZUZ1bmN0aW9uTmFtZShjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgcHJlZml4KSB7CisgIC8vIERvIG5vdCB1c2UgRmllbGROYW1lKCkgc2luY2UgaXQgd2lsbCBlc2NhcGUga2V5d29yZHMuCisgIHN0cmluZyBuYW1lID0gZmllbGQtPm5hbWUoKTsKKyAgTG93ZXJTdHJpbmcoJm5hbWUpOworICBzdHJpbmcgZnVuY3Rpb25fbmFtZSA9IHByZWZpeCArIG5hbWU7CisgIGlmIChkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoZnVuY3Rpb25fbmFtZSkpIHsKKyAgICAvLyBTaW5nbGUgdW5kZXJzY29yZSB3aWxsIGFsc28gbWFrZSBpdCBjb25mbGljdGluZyB3aXRoIHRoZSBwcml2YXRlIGRhdGEKKyAgICAvLyBtZW1iZXIuIFdlIHVzZSBkb3VibGUgdW5kZXJzY29yZSB0byBlc2NhcGUgZnVuY3Rpb24gbmFtZXMuCisgICAgZnVuY3Rpb25fbmFtZS5hcHBlbmQoIl9fIik7CisgIH0gZWxzZSBpZiAoa0tleXdvcmRzLmNvdW50KG5hbWUpID4gMCkgeworICAgIC8vIElmIHRoZSBmaWVsZCBuYW1lIGlzIGEga2V5d29yZCwgd2UgYXBwZW5kIHRoZSB1bmRlcnNjb3JlIGJhY2sgdG8ga2VlcCBpdAorICAgIC8vIGNvbnNpc3RlbnQgd2l0aCBvdGhlciBmdW5jdGlvbiBuYW1lcy4KKyAgICBmdW5jdGlvbl9uYW1lLmFwcGVuZCgiXyIpOworICB9CisgIHJldHVybiBmdW5jdGlvbl9uYW1lOworfQorCitib29sIFN0YXRpY0luaXRpYWxpemVyc0ZvcmNlZChjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSkgeworICBpZiAoSGFzRGVzY3JpcHRvck1ldGhvZHMoZmlsZSkgfHwgZmlsZS0+ZXh0ZW5zaW9uX2NvdW50KCkgPiAwKSB7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlLT5tZXNzYWdlX3R5cGVfY291bnQoKTsgKytpKSB7CisgICAgaWYgKEhhc0V4dGVuc2lvbihmaWxlLT5tZXNzYWdlX3R5cGUoaSkpKSB7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIGZhbHNlOworfQorCit2b2lkIFByaW50SGFuZGxpbmdPcHRpb25hbFN0YXRpY0luaXRpYWxpemVycygKKyAgICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSwgaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgY29uc3QgY2hhciogd2l0aF9zdGF0aWNfaW5pdCwgY29uc3QgY2hhciogd2l0aG91dF9zdGF0aWNfaW5pdCwKKyAgICBjb25zdCBjaGFyKiB2YXIxLCBjb25zdCBzdHJpbmcmIHZhbDEsCisgICAgY29uc3QgY2hhciogdmFyMiwgY29uc3Qgc3RyaW5nJiB2YWwyKSB7CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyczsKKyAgaWYgKHZhcjEpIHsKKyAgICB2YXJzW3ZhcjFdID0gdmFsMTsKKyAgfQorICBpZiAodmFyMikgeworICAgIHZhcnNbdmFyMl0gPSB2YWwyOworICB9CisgIFByaW50SGFuZGxpbmdPcHRpb25hbFN0YXRpY0luaXRpYWxpemVycygKKyAgICAgIHZhcnMsIGZpbGUsIHByaW50ZXIsIHdpdGhfc3RhdGljX2luaXQsIHdpdGhvdXRfc3RhdGljX2luaXQpOworfQorCit2b2lkIFByaW50SGFuZGxpbmdPcHRpb25hbFN0YXRpY0luaXRpYWxpemVycygKKyAgICBjb25zdCBtYXA8c3RyaW5nLCBzdHJpbmc+JiB2YXJzLCBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSwKKyAgICBpbzo6UHJpbnRlciogcHJpbnRlciwgY29uc3QgY2hhciogd2l0aF9zdGF0aWNfaW5pdCwKKyAgICBjb25zdCBjaGFyKiB3aXRob3V0X3N0YXRpY19pbml0KSB7CisgIGlmIChTdGF0aWNJbml0aWFsaXplcnNGb3JjZWQoZmlsZSkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLCB3aXRoX3N0YXRpY19pbml0KTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLCAoc3RyaW5nKAorICAgICAgIiNpZmRlZiBHT09HTEVfUFJPVE9CVUZfTk9fU1RBVElDX0lOSVRJQUxJWkVSXG4iKSArCisgICAgICB3aXRob3V0X3N0YXRpY19pbml0ICsKKyAgICAgICIjZWxzZVxuIiArCisgICAgICB3aXRoX3N0YXRpY19pbml0ICsKKyAgICAgICIjZW5kaWZcbiIpLmNfc3RyKCkpOworICB9Cit9CisKKworc3RhdGljIGJvb2wgSGFzTWFwRmllbGRzKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yLT5maWVsZF9jb3VudCgpOyArK2kpIHsKKyAgICBpZiAoZGVzY3JpcHRvci0+ZmllbGQoaSktPmlzX21hcCgpKSB7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yLT5uZXN0ZWRfdHlwZV9jb3VudCgpOyArK2kpIHsKKyAgICBpZiAoSGFzTWFwRmllbGRzKGRlc2NyaXB0b3ItPm5lc3RlZF90eXBlKGkpKSkgcmV0dXJuIHRydWU7CisgIH0KKyAgcmV0dXJuIGZhbHNlOworfQorCitib29sIEhhc01hcEZpZWxkcyhjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSkgeworICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGUtPm1lc3NhZ2VfdHlwZV9jb3VudCgpOyArK2kpIHsKKyAgICBpZiAoSGFzTWFwRmllbGRzKGZpbGUtPm1lc3NhZ2VfdHlwZShpKSkpIHJldHVybiB0cnVlOworICB9CisgIHJldHVybiBmYWxzZTsKK30KKworc3RhdGljIGJvb2wgSGFzRW51bURlZmluaXRpb25zKGNvbnN0IERlc2NyaXB0b3IqIG1lc3NhZ2VfdHlwZSkgeworICBpZiAobWVzc2FnZV90eXBlLT5lbnVtX3R5cGVfY291bnQoKSA+IDApIHJldHVybiB0cnVlOworICBmb3IgKGludCBpID0gMDsgaSA8IG1lc3NhZ2VfdHlwZS0+bmVzdGVkX3R5cGVfY291bnQoKTsgKytpKSB7CisgICAgaWYgKEhhc0VudW1EZWZpbml0aW9ucyhtZXNzYWdlX3R5cGUtPm5lc3RlZF90eXBlKGkpKSkgcmV0dXJuIHRydWU7CisgIH0KKyAgcmV0dXJuIGZhbHNlOworfQorCitib29sIEhhc0VudW1EZWZpbml0aW9ucyhjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSkgeworICBpZiAoZmlsZS0+ZW51bV90eXBlX2NvdW50KCkgPiAwKSByZXR1cm4gdHJ1ZTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlLT5tZXNzYWdlX3R5cGVfY291bnQoKTsgKytpKSB7CisgICAgaWYgKEhhc0VudW1EZWZpbml0aW9ucyhmaWxlLT5tZXNzYWdlX3R5cGUoaSkpKSByZXR1cm4gdHJ1ZTsKKyAgfQorICByZXR1cm4gZmFsc2U7Cit9CisKK2Jvb2wgSXNTdHJpbmdPck1lc3NhZ2UoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICBzd2l0Y2ggKGZpZWxkLT5jcHBfdHlwZSgpKSB7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UMzI6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UNjQ6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDMyOgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1VJTlQ2NDoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9ET1VCTEU6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRkxPQVQ6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfQk9PTDoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9FTlVNOgorICAgICAgcmV0dXJuIGZhbHNlOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORzoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgcmV0dXJuIHRydWU7CisgIH0KKworICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ2FuJ3QgZ2V0IGhlcmUuIjsKKyAgcmV0dXJuIGZhbHNlOworfQorCitGaWVsZE9wdGlvbnM6OkNUeXBlIEVmZmVjdGl2ZVN0cmluZ0NUeXBlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgR09PR0xFX0RDSEVDSyhmaWVsZC0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HKTsKKyAgLy8gT3Blbi1zb3VyY2UgcHJvdG9idWYgcmVsZWFzZSBvbmx5IHN1cHBvcnRzIFNUUklORyBjdHlwZS4KKyAgcmV0dXJuIEZpZWxkT3B0aW9uczo6U1RSSU5HOworCit9CisKK2Jvb2wgSXNBbnlNZXNzYWdlKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIHJldHVybiBkZXNjcmlwdG9yLT5uYW1lKCkgPT0ga0FueVByb3RvRmlsZTsKK30KKworYm9vbCBJc0FueU1lc3NhZ2UoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICByZXR1cm4gZGVzY3JpcHRvci0+bmFtZSgpID09IGtBbnlNZXNzYWdlTmFtZSAmJgorICAgICAgICAgZGVzY3JpcHRvci0+ZmlsZSgpLT5uYW1lKCkgPT0ga0FueVByb3RvRmlsZTsKK30KKworYm9vbCBJc1dlbGxLbm93bk1lc3NhZ2UoY29uc3QgRmlsZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgcmV0dXJuICFkZXNjcmlwdG9yLT5uYW1lKCkuY29tcGFyZSgwLCAxNiwga0dvb2dsZVByb3RvYnVmUHJlZml4KTsKK30KKworZW51bSBVdGY4Q2hlY2tNb2RlIHsKKyAgU1RSSUNUID0gMCwgIC8vIFBhcnNpbmcgd2lsbCBmYWlsIGlmIG5vbiBVVEYtOCBkYXRhIGlzIGluIHN0cmluZyBmaWVsZHMuCisgIFZFUklGWSA9IDEsICAvLyBPbmx5IGxvZyBhbiBlcnJvciBidXQgcGFyc2luZyB3aWxsIHN1Y2NlZWQuCisgIE5PTkUgPSAyLCAgLy8gTm8gVVRGLTggY2hlY2suCit9OworCisvLyBXaGljaCBsZXZlbCBvZiBVVEYtOCBlbmZvcmNlbWFudCBpcyBwbGFjZWQgb24gdGhpcyBmaWxlLgorc3RhdGljIFV0ZjhDaGVja01vZGUgR2V0VXRmOENoZWNrTW9kZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIGlmIChmaWVsZC0+ZmlsZSgpLT5zeW50YXgoKSA9PSBGaWxlRGVzY3JpcHRvcjo6U1lOVEFYX1BST1RPMykgeworICAgIHJldHVybiBTVFJJQ1Q7CisgIH0gZWxzZSBpZiAoZmllbGQtPmZpbGUoKS0+b3B0aW9ucygpLm9wdGltaXplX2ZvcigpICE9CisgICAgICAgICAgICAgRmlsZU9wdGlvbnM6OkxJVEVfUlVOVElNRSkgeworICAgIHJldHVybiBWRVJJRlk7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIE5PTkU7CisgIH0KK30KKworc3RhdGljIHZvaWQgR2VuZXJhdGVVdGY4Q2hlY2tDb2RlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBmb3JfcGFyc2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWFwPHN0cmluZywgc3RyaW5nPiYgdmFyaWFibGVzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIHBhcmFtZXRlcnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogc3RyaWN0X2Z1bmN0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIHZlcmlmeV9mdW5jdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBzd2l0Y2ggKEdldFV0ZjhDaGVja01vZGUoZmllbGQpKSB7CisgICAgY2FzZSBTVFJJQ1Q6IHsKKyAgICAgIGlmIChmb3JfcGFyc2UpIHsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoIkRPXygiKTsKKyAgICAgIH0KKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICI6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6JGZ1bmN0aW9uJChcbiIsCisgICAgICAgICAgImZ1bmN0aW9uIiwgc3RyaWN0X2Z1bmN0aW9uKTsKKyAgICAgIHByaW50ZXItPkluZGVudCgpOworICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLCBwYXJhbWV0ZXJzKTsKKyAgICAgIGlmIChmb3JfcGFyc2UpIHsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoIjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpQQVJTRSxcbiIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoIjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTRVJJQUxJWkUsXG4iKTsKKyAgICAgIH0KKyAgICAgIHByaW50ZXItPlByaW50KCJcIiRmdWxsX25hbWUkXCIpIiwgImZ1bGxfbmFtZSIsIGZpZWxkLT5mdWxsX25hbWUoKSk7CisgICAgICBpZiAoZm9yX3BhcnNlKSB7CisgICAgICAgIHByaW50ZXItPlByaW50KCIpIik7CisgICAgICB9CisgICAgICBwcmludGVyLT5QcmludCgiO1xuIik7CisgICAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBWRVJJRlk6IHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICI6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjokZnVuY3Rpb24kKFxuIiwKKyAgICAgICAgICAiZnVuY3Rpb24iLCB2ZXJpZnlfZnVuY3Rpb24pOworICAgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXMsIHBhcmFtZXRlcnMpOworICAgICAgaWYgKGZvcl9wYXJzZSkgeworICAgICAgICBwcmludGVyLT5QcmludCgiOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6UEFSU0UsXG4iKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHByaW50ZXItPlByaW50KCI6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsXG4iKTsKKyAgICAgIH0KKyAgICAgIHByaW50ZXItPlByaW50KCJcIiRmdWxsX25hbWUkXCIpO1xuIiwgImZ1bGxfbmFtZSIsIGZpZWxkLT5mdWxsX25hbWUoKSk7CisgICAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBOT05FOgorICAgICAgYnJlYWs7CisgIH0KK30KKwordm9pZCBHZW5lcmF0ZVV0ZjhDaGVja0NvZGVGb3JTdHJpbmcoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgZm9yX3BhcnNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWFwPHN0cmluZywgc3RyaW5nPiYgdmFyaWFibGVzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogcGFyYW1ldGVycywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIEdlbmVyYXRlVXRmOENoZWNrQ29kZShmaWVsZCwgZm9yX3BhcnNlLCB2YXJpYWJsZXMsIHBhcmFtZXRlcnMsCisgICAgICAgICAgICAgICAgICAgICAgICAiVmVyaWZ5VXRmOFN0cmluZyIsICJWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCIsCisgICAgICAgICAgICAgICAgICAgICAgICBwcmludGVyKTsKK30KKwordm9pZCBHZW5lcmF0ZVV0ZjhDaGVja0NvZGVGb3JDb3JkKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBmb3JfcGFyc2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWFwPHN0cmluZywgc3RyaW5nPiYgdmFyaWFibGVzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIHBhcmFtZXRlcnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgR2VuZXJhdGVVdGY4Q2hlY2tDb2RlKGZpZWxkLCBmb3JfcGFyc2UsIHZhcmlhYmxlcywgcGFyYW1ldGVycywKKyAgICAgICAgICAgICAgICAgICAgICAgICJWZXJpZnlVdGY4Q29yZCIsICJWZXJpZnlVVEY4Q29yZE5hbWVkRmllbGQiLAorICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnRlcik7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBjcHAKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfaGVscGVycy5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2hlbHBlcnMuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMjJkNDE0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2hlbHBlcnMuaApAQCAtMCwwICsxLDI4OSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DUFBfSEVMUEVSU19IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NQUF9IRUxQRVJTX0hfXworCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworbmFtZXNwYWNlIGlvIHsKK2NsYXNzIFByaW50ZXI7Cit9CisKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgY3BwIHsKKworLy8gQ29tbW9ubHktdXNlZCBzZXBhcmF0b3IgY29tbWVudHMuICBUaGljayBpcyBhIGxpbmUgb2YgJz0nLCB0aGluIGlzIGEgbGluZQorLy8gb2YgJy0nLgorZXh0ZXJuIGNvbnN0IGNoYXIga1RoaWNrU2VwYXJhdG9yW107CitleHRlcm4gY29uc3QgY2hhciBrVGhpblNlcGFyYXRvcltdOworCisvLyBSZXR1cm5zIHRoZSBub24tbmVzdGVkIHR5cGUgbmFtZSBmb3IgdGhlIGdpdmVuIHR5cGUuICBJZiAicXVhbGlmaWVkIiBpcworLy8gdHJ1ZSwgcHJlZml4IHRoZSB0eXBlIHdpdGggdGhlIGZ1bGwgbmFtZXNwYWNlLiAgRm9yIGV4YW1wbGUsIGlmIHlvdSBoYWQ6CisvLyAgIHBhY2thZ2UgZm9vLmJhcjsKKy8vICAgbWVzc2FnZSBCYXogeyBtZXNzYWdlIFF1eCB7fSB9CisvLyBUaGVuIHRoZSBxdWFsaWZpZWQgQ2xhc3NOYW1lIGZvciBRdXggd291bGQgYmU6CisvLyAgIDo6Zm9vOjpiYXI6OkJhel9RdXgKKy8vIFdoaWxlIHRoZSBub24tcXVhbGlmaWVkIHZlcnNpb24gd291bGQgYmU6CisvLyAgIEJhel9RdXgKK3N0cmluZyBDbGFzc05hbWUoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwgYm9vbCBxdWFsaWZpZWQpOworc3RyaW5nIENsYXNzTmFtZShjb25zdCBFbnVtRGVzY3JpcHRvciogZW51bV9kZXNjcmlwdG9yLCBib29sIHF1YWxpZmllZCk7CisKKy8vIE5hbWUgb2YgdGhlIENSVFAgY2xhc3MgdGVtcGxhdGUgKGZvciB1c2Ugd2l0aCBwcm90b19oKS4KKy8vIFRoaXMgaXMgYSBjbGFzcyBuYW1lLCBsaWtlICJQcm90b05hbWVfSW50ZXJuYWxCYXNlIi4KK3N0cmluZyBEZXBlbmRlbnRCYXNlQ2xhc3NUZW1wbGF0ZU5hbWUoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CisKKy8vIE5hbWUgb2YgdGhlIGJhc2UgY2xhc3M6IGVpdGhlciB0aGUgZGVwZW5kZW50IGJhc2UgY2xhc3MgKGZvciB1c2Ugd2l0aAorLy8gcHJvdG9faCkgb3IgZ29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZS4KK3N0cmluZyBTdXBlckNsYXNzTmFtZShjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKKworLy8gUmV0dXJucyBhIHN0cmluZyB0aGF0IGRvd24tY2FzdHMgZnJvbSB0aGUgZGVwZW5kZW50IGJhc2UgY2xhc3MgdG8gdGhlCisvLyBkZXJpdmVkIGNsYXNzLgorc3RyaW5nIERlcGVuZGVudEJhc2VEb3duQ2FzdCgpOworc3RyaW5nIERlcGVuZGVudEJhc2VDb25zdERvd25DYXN0KCk7CisKKy8vIEdldCB0aGUgKHVucXVhbGlmaWVkKSBuYW1lIHRoYXQgc2hvdWxkIGJlIHVzZWQgZm9yIHRoaXMgZmllbGQgaW4gQysrIGNvZGUuCisvLyBUaGUgbmFtZSBpcyBjb2VyY2VkIHRvIGxvd2VyLWNhc2UgdG8gZW11bGF0ZSBwcm90bzEgYmVoYXZpb3IuICBQZW9wbGUKKy8vIHNob3VsZCBiZSB1c2luZyBsb3dlcmNhc2Utd2l0aC11bmRlcnNjb3JlcyBzdHlsZSBmb3IgcHJvdG8gZmllbGQgbmFtZXMKKy8vIGFueXdheSwgc28gbm9ybWFsbHkgdGhpcyBqdXN0IHJldHVybnMgZmllbGQtPm5hbWUoKS4KK3N0cmluZyBGaWVsZE5hbWUoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCk7CisKKy8vIEdldCB0aGUgc2FuaXRpemVkIG5hbWUgdGhhdCBzaG91bGQgYmUgdXNlZCBmb3IgdGhlIGdpdmVuIGVudW0gaW4gQysrIGNvZGUuCitzdHJpbmcgRW51bVZhbHVlTmFtZShjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBlbnVtX3ZhbHVlKTsKKworLy8gR2V0IHRoZSB1bnF1YWxpZmllZCBuYW1lIHRoYXQgc2hvdWxkIGJlIHVzZWQgZm9yIGEgZmllbGQncyBmaWVsZAorLy8gbnVtYmVyIGNvbnN0YW50Lgorc3RyaW5nIEZpZWxkQ29uc3RhbnROYW1lKGNvbnN0IEZpZWxkRGVzY3JpcHRvciAqZmllbGQpOworCisvLyBSZXR1cm5zIHRoZSBzY29wZSB3aGVyZSB0aGUgZmllbGQgd2FzIGRlZmluZWQgKGZvciBleHRlbnNpb25zLCB0aGlzIGlzCisvLyBkaWZmZXJlbnQgZnJvbSB0aGUgbWVzc2FnZSB0eXBlIHRvIHdoaWNoIHRoZSBmaWVsZCBhcHBsaWVzKS4KK2lubGluZSBjb25zdCBEZXNjcmlwdG9yKiBGaWVsZFNjb3BlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgcmV0dXJuIGZpZWxkLT5pc19leHRlbnNpb24oKSA/CisgICAgZmllbGQtPmV4dGVuc2lvbl9zY29wZSgpIDogZmllbGQtPmNvbnRhaW5pbmdfdHlwZSgpOworfQorCisvLyBSZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuICdmaWVsZF9kZXNjcmlwdG9yJyBoYXMgYSBtZXNzYWdlIHR5cGUgdGhhdCBpcworLy8gYSBkZXBlbmRlbmN5IG9mIHRoZSBmaWxlIHdoZXJlIHRoZSBmaWVsZCBpcyBkZWZpbmVkIChpLmUuLCB0aGUgZmllbGQKKy8vIHR5cGUgaXMgZGVmaW5lZCBpbiBhIGRpZmZlcmVudCBmaWxlIHRoYW4gdGhlIG1lc3NhZ2UgaG9sZGluZyB0aGUgZmllbGQpLgorLy8KKy8vIFRoaXMgb25seSBhcHBsaWVzIHRvIE1lc3NhZ2UtdHlwZWQgZmllbGRzLiBFbnVtLXR5cGVkIGZpZWxkcyBtYXkgcmVmZXIKKy8vIHRvIGFuIGVudW0gaW4gYSBkZXBlbmRlbmN5OyBob3dldmVyLCBlbnVtcyBhcmUgc3BlY2lmaWVkIGFuZAorLy8gZm9yd2FyZC1kZWNsYXJlZCB3aXRoIGFuIGVudW0tYmFzZSwgc28gdGhlIGRlZmluaXRpb24gaXMgbm90IHJlcXVpcmVkIHRvCisvLyBtYW5pcHVsYXRlIHRoZSBmaWVsZCB2YWx1ZS4KK2Jvb2wgSXNGaWVsZERlcGVuZGVudChjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkX2Rlc2NyaXB0b3IpOworCisvLyBSZXR1cm5zIHRoZSBuYW1lIHRoYXQgc2hvdWxkIGJlIHVzZWQgZm9yIGZvcmNpbmcgZGVwZW5kZW50IGxvb2t1cCBmcm9tIGEKKy8vIGRlcGVuZGVudCBiYXNlIGNsYXNzLgorc3RyaW5nIERlcGVuZGVudFR5cGVOYW1lKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpOworCisvLyBSZXR1cm5zIHRoZSBmdWxseS1xdWFsaWZpZWQgdHlwZSBuYW1lIGZpZWxkLT5tZXNzYWdlX3R5cGUoKS4gIFVzdWFsbHkgdGhpcworLy8gaXMganVzdCBDbGFzc05hbWUoZmllbGQtPm1lc3NhZ2VfdHlwZSgpLCB0cnVlKTsKK3N0cmluZyBGaWVsZE1lc3NhZ2VUeXBlTmFtZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKTsKKworLy8gU3RyaXBzICIucHJvdG8iIG9yICIucHJvdG9kZXZlbCIgZnJvbSB0aGUgZW5kIG9mIGEgZmlsZW5hbWUuCitzdHJpbmcgU3RyaXBQcm90byhjb25zdCBzdHJpbmcmIGZpbGVuYW1lKTsKKworLy8gR2V0IHRoZSBDKysgdHlwZSBuYW1lIGZvciBhIHByaW1pdGl2ZSB0eXBlIChlLmcuICJkb3VibGUiLCAiOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiIsIGV0Yy4pLgorLy8gTm90ZTogIG5vbi1idWlsdC1pbiB0eXBlIG5hbWVzIHdpbGwgYmUgcXVhbGlmaWVkLCBtZWFuaW5nIHRoZXkgd2lsbCBzdGFydAorLy8gd2l0aCBhIDo6LiAgSWYgeW91IGFyZSB1c2luZyB0aGUgdHlwZSBhcyBhIHRlbXBsYXRlIHBhcmFtZXRlciwgeW91IHdpbGwKKy8vIG5lZWQgdG8gaW5zdXJlIHRoZXJlIGlzIGEgc3BhY2UgYmV0d2VlbiB0aGUgPCBhbmQgdGhlIDo6LCBiZWNhdXNlIHRoZQorLy8gcmlkaWN1bG91cyBDKysgc3RhbmRhcmQgZGVmaW5lcyAiPDoiIHRvIGJlIGEgc3lub255bSBmb3IgIlsiLgorY29uc3QgY2hhciogUHJpbWl0aXZlVHlwZU5hbWUoRmllbGREZXNjcmlwdG9yOjpDcHBUeXBlIHR5cGUpOworCisvLyBHZXQgdGhlIGRlY2xhcmVkIHR5cGUgbmFtZSBpbiBDYW1lbENhc2UgZm9ybWF0LCBhcyBpcyB1c2VkIGUuZy4gZm9yIHRoZQorLy8gbWV0aG9kcyBvZiBXaXJlRm9ybWF0LiAgRm9yIGV4YW1wbGUsIFRZUEVfSU5UMzIgYmVjb21lcyAiSW50MzIiLgorY29uc3QgY2hhciogRGVjbGFyZWRUeXBlTWV0aG9kTmFtZShGaWVsZERlc2NyaXB0b3I6OlR5cGUgdHlwZSk7CisKKy8vIFJldHVybiB0aGUgY29kZSB0aGF0IGV2YWx1YXRlcyB0byB0aGUgbnVtYmVyIHdoZW4gY29tcGlsZWQuCitzdHJpbmcgSW50MzJUb1N0cmluZyhpbnQgbnVtYmVyKTsKKworLy8gUmV0dXJuIHRoZSBjb2RlIHRoYXQgZXZhbHVhdGVzIHRvIHRoZSBudW1iZXIgd2hlbiBjb21waWxlZC4KK3N0cmluZyBJbnQ2NFRvU3RyaW5nKGludDY0IG51bWJlcik7CisKKy8vIEdldCBjb2RlIHRoYXQgZXZhbHVhdGVzIHRvIHRoZSBmaWVsZCdzIGRlZmF1bHQgdmFsdWUuCitzdHJpbmcgRGVmYXVsdFZhbHVlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpOworCisvLyBDb252ZXJ0IGEgZmlsZSBuYW1lIGludG8gYSB2YWxpZCBpZGVudGlmaWVyLgorc3RyaW5nIEZpbGVuYW1lSWRlbnRpZmllcihjb25zdCBzdHJpbmcmIGZpbGVuYW1lKTsKKworLy8gUmV0dXJuIHRoZSBuYW1lIG9mIHRoZSBBZGREZXNjcmlwdG9ycygpIGZ1bmN0aW9uIGZvciBhIGdpdmVuIGZpbGUuCitzdHJpbmcgR2xvYmFsQWRkRGVzY3JpcHRvcnNOYW1lKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUpOworCisvLyBSZXR1cm4gdGhlIG5hbWUgb2YgdGhlIEFzc2lnbkRlc2NyaXB0b3JzKCkgZnVuY3Rpb24gZm9yIGEgZ2l2ZW4gZmlsZS4KK3N0cmluZyBHbG9iYWxBc3NpZ25EZXNjcmlwdG9yc05hbWUoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSk7CisKKy8vIFJldHVybiB0aGUgcXVhbGlmaWVkIEMrKyBuYW1lIGZvciBhIGZpbGUgbGV2ZWwgc3ltYm9sLgorc3RyaW5nIFF1YWxpZmllZEZpbGVMZXZlbFN5bWJvbChjb25zdCBzdHJpbmcmIHBhY2thZ2UsIGNvbnN0IHN0cmluZyYgbmFtZSk7CisKKy8vIFJldHVybiB0aGUgbmFtZSBvZiB0aGUgU2h1dGRvd25GaWxlKCkgZnVuY3Rpb24gZm9yIGEgZ2l2ZW4gZmlsZS4KK3N0cmluZyBHbG9iYWxTaHV0ZG93bkZpbGVOYW1lKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUpOworCisvLyBFc2NhcGUgQysrIHRyaWdyYXBocyBieSBlc2NhcGluZyBxdWVzdGlvbiBtYXJrcyB0byBcPworc3RyaW5nIEVzY2FwZVRyaWdyYXBocyhjb25zdCBzdHJpbmcmIHRvX2VzY2FwZSk7CisKKy8vIEVzY2FwZWQgZnVuY3Rpb24gbmFtZSB0byBlbGltaW5hdGUgbmFtaW5nIGNvbmZsaWN0Lgorc3RyaW5nIFNhZmVGdW5jdGlvbk5hbWUoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHByZWZpeCk7CisKKy8vIFJldHVybnMgdHJ1ZSBpZiB1bmtub3duIGZpZWxkcyBhcmUgcHJlc2V2ZWQgYWZ0ZXIgcGFyc2luZy4KK2lubGluZSBib29sIFByZXNlcnZlVW5rbm93bkZpZWxkcyhjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlKSB7CisgIHJldHVybiBtZXNzYWdlLT5maWxlKCktPnN5bnRheCgpICE9IEZpbGVEZXNjcmlwdG9yOjpTWU5UQVhfUFJPVE8zOworfQorCisvLyBJZiBQcmVzZXJ2ZVVua25vd25GaWVsZHMoKSBpcyB0cnVlLCBkZXRlcm1pbmVzIHdoZXRoZXIgdW5rbm93bgorLy8gZmllbGRzIHdpbGwgYmUgc3RvcmVkIGluIGFuIFVua25vd25GaWVsZFNldCBvciBhIHN0cmluZy4KKy8vIElmIFByZXNlcnZlVW5rbm93bkZpZWxkcygpIGlzIGZhbHNlLCB0aGlzIG1ldGhvZCB3aWxsIG5vdCBiZQorLy8gdXNlZC4KK2lubGluZSBib29sIFVzZVVua25vd25GaWVsZFNldChjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSkgeworICByZXR1cm4gZmlsZS0+b3B0aW9ucygpLm9wdGltaXplX2ZvcigpICE9IEZpbGVPcHRpb25zOjpMSVRFX1JVTlRJTUU7Cit9CisKKworLy8gRG9lcyB0aGUgZmlsZSBoYXZlIGFueSBtYXAgZmllbGRzLCBuZWNlc3NpdGF0aW5nIHRoZSBmaWxlIHRvIGluY2x1ZGUKKy8vIG1hcF9maWVsZF9pbmwuaCBhbmQgbWFwLmguCitib29sIEhhc01hcEZpZWxkcyhjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSk7CisKKy8vIERvZXMgdGhpcyBmaWxlIGhhdmUgYW55IGVudW0gdHlwZSBkZWZpbml0aW9ucz8KK2Jvb2wgSGFzRW51bURlZmluaXRpb25zKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKTsKKworLy8gRG9lcyB0aGlzIGZpbGUgaGF2ZSBnZW5lcmF0ZWQgcGFyc2luZywgc2VyaWFsaXphdGlvbiwgYW5kIG90aGVyCisvLyBzdGFuZGFyZCBtZXRob2RzIGZvciB3aGljaCByZWZsZWN0aW9uLWJhc2VkIGZhbGxiYWNrIGltcGxlbWVudGF0aW9ucyBleGlzdD8KK2lubGluZSBib29sIEhhc0dlbmVyYXRlZE1ldGhvZHMoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUpIHsKKyAgcmV0dXJuIGZpbGUtPm9wdGlvbnMoKS5vcHRpbWl6ZV9mb3IoKSAhPSBGaWxlT3B0aW9uczo6Q09ERV9TSVpFOworfQorCisvLyBEbyBtZXNzYWdlIGNsYXNzZXMgaW4gdGhpcyBmaWxlIGhhdmUgZGVzY3JpcHRvciBhbmQgcmVmbGVjdGlvbiBtZXRob2RzPworaW5saW5lIGJvb2wgSGFzRGVzY3JpcHRvck1ldGhvZHMoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUpIHsKKyAgcmV0dXJuIGZpbGUtPm9wdGlvbnMoKS5vcHRpbWl6ZV9mb3IoKSAhPSBGaWxlT3B0aW9uczo6TElURV9SVU5USU1FOworfQorCisvLyBTaG91bGQgd2UgZ2VuZXJhdGUgZ2VuZXJpYyBzZXJ2aWNlcyBmb3IgdGhpcyBmaWxlPworaW5saW5lIGJvb2wgSGFzR2VuZXJpY1NlcnZpY2VzKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKSB7CisgIHJldHVybiBmaWxlLT5zZXJ2aWNlX2NvdW50KCkgPiAwICYmCisgICAgICAgICBmaWxlLT5vcHRpb25zKCkub3B0aW1pemVfZm9yKCkgIT0gRmlsZU9wdGlvbnM6OkxJVEVfUlVOVElNRSAmJgorICAgICAgICAgZmlsZS0+b3B0aW9ucygpLmNjX2dlbmVyaWNfc2VydmljZXMoKTsKK30KKworLy8gU2hvdWxkIHdlIGdlbmVyYXRlIGEgc2VwYXJhdGUsIHN1cGVyLW9wdGltaXplZCBjb2RlIHBhdGggZm9yIHNlcmlhbGl6aW5nIHRvCisvLyBmbGF0IGFycmF5cz8gIFdlIGRvbid0IGRvIHRoaXMgaW4gTGl0ZSBtb2RlIGJlY2F1c2Ugd2UnZCByYXRoZXIgcmVkdWNlIGNvZGUKKy8vIHNpemUuCitpbmxpbmUgYm9vbCBIYXNGYXN0QXJyYXlTZXJpYWxpemF0aW9uKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKSB7CisgIHJldHVybiBmaWxlLT5vcHRpb25zKCkub3B0aW1pemVfZm9yKCkgPT0gRmlsZU9wdGlvbnM6OlNQRUVEOworfQorCisvLyBSZXR1cm5zIHdoZXRoZXIgd2UgaGF2ZSB0byBnZW5lcmF0ZSBjb2RlIHdpdGggc3RhdGljIGluaXRpYWxpemVycy4KK2Jvb2wgU3RhdGljSW5pdGlhbGl6ZXJzRm9yY2VkKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKTsKKworLy8gUHJpbnRzICd3aXRoX3N0YXRpY19pbml0JyBpZiBzdGF0aWMgaW5pdGlhbGl6ZXJzIGhhdmUgdG8gYmUgdXNlZCBmb3IgdGhlCisvLyBwcm92aWRlZCBmaWxlLiBPdGhlcndpc2UgZW1pdHMgYm90aCAnd2l0aF9zdGF0aWNfaW5pdCcgYW5kCisvLyAnd2l0aG91dF9zdGF0aWNfaW5pdCcgdXNpbmcgI2lmZGVmLgordm9pZCBQcmludEhhbmRsaW5nT3B0aW9uYWxTdGF0aWNJbml0aWFsaXplcnMoCisgICAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUsIGlvOjpQcmludGVyKiBwcmludGVyLAorICAgIGNvbnN0IGNoYXIqIHdpdGhfc3RhdGljX2luaXQsIGNvbnN0IGNoYXIqIHdpdGhvdXRfc3RhdGljX2luaXQsCisgICAgY29uc3QgY2hhciogdmFyMSA9IE5VTEwsIGNvbnN0IHN0cmluZyYgdmFsMSA9ICIiLAorICAgIGNvbnN0IGNoYXIqIHZhcjIgPSBOVUxMLCBjb25zdCBzdHJpbmcmIHZhbDIgPSAiIik7CisKK3ZvaWQgUHJpbnRIYW5kbGluZ09wdGlvbmFsU3RhdGljSW5pdGlhbGl6ZXJzKAorICAgIGNvbnN0IG1hcDxzdHJpbmcsIHN0cmluZz4mIHZhcnMsIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlLAorICAgIGlvOjpQcmludGVyKiBwcmludGVyLCBjb25zdCBjaGFyKiB3aXRoX3N0YXRpY19pbml0LAorICAgIGNvbnN0IGNoYXIqIHdpdGhvdXRfc3RhdGljX2luaXQpOworCisKK2lubGluZSBib29sIElzTWFwRW50cnlNZXNzYWdlKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgcmV0dXJuIGRlc2NyaXB0b3ItPm9wdGlvbnMoKS5tYXBfZW50cnkoKTsKK30KKworLy8gUmV0dXJucyB0cnVlIGlmIHRoZSBmaWVsZCdzIENQUFRZUEUgaXMgc3RyaW5nIG9yIG1lc3NhZ2UuCitib29sIElzU3RyaW5nT3JNZXNzYWdlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpOworCisvLyBGb3IgYSBzdHJpbmcgZmllbGQsIHJldHVybnMgdGhlIGVmZmVjdGl2ZSBjdHlwZS4gIElmIHRoZSBhY3R1YWwgY3R5cGUgaXMKKy8vIG5vdCBzdXBwb3J0ZWQsIHJldHVybnMgdGhlIGRlZmF1bHQgb2YgU1RSSU5HLgorRmllbGRPcHRpb25zOjpDVHlwZSBFZmZlY3RpdmVTdHJpbmdDVHlwZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKTsKKworc3RyaW5nIFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoY29uc3Qgc3RyaW5nJiBpbnB1dCwgYm9vbCBjYXBfbmV4dF9sZXR0ZXIpOworCitpbmxpbmUgYm9vbCBIYXNGaWVsZFByZXNlbmNlKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKSB7CisgIHJldHVybiBmaWxlLT5zeW50YXgoKSAhPSBGaWxlRGVzY3JpcHRvcjo6U1lOVEFYX1BST1RPMzsKK30KKworLy8gUmV0dXJucyB0cnVlIGlmICdlbnVtJyBzZW1hbnRpY3MgYXJlIHN1Y2ggdGhhdCB1bmtub3duIHZhbHVlcyBhcmUgcHJlc2VydmVkCisvLyBpbiB0aGUgZW51bSBmaWVsZCBpdHNlbGYsIHJhdGhlciB0aGFuIGdvaW5nIHRvIHRoZSBVbmtub3duRmllbGRTZXQuCitpbmxpbmUgYm9vbCBIYXNQcmVzZXJ2aW5nVW5rbm93bkVudW1TZW1hbnRpY3MoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUpIHsKKyAgcmV0dXJuIGZpbGUtPnN5bnRheCgpID09IEZpbGVEZXNjcmlwdG9yOjpTWU5UQVhfUFJPVE8zOworfQorCitpbmxpbmUgYm9vbCBTdXBwb3J0c0FyZW5hcyhjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSkgeworICByZXR1cm4gZmlsZS0+b3B0aW9ucygpLmNjX2VuYWJsZV9hcmVuYXMoKTsKK30KKworaW5saW5lIGJvb2wgU3VwcG9ydHNBcmVuYXMoY29uc3QgRGVzY3JpcHRvciogZGVzYykgeworICByZXR1cm4gU3VwcG9ydHNBcmVuYXMoZGVzYy0+ZmlsZSgpKTsKK30KKworaW5saW5lIGJvb2wgU3VwcG9ydHNBcmVuYXMoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICByZXR1cm4gU3VwcG9ydHNBcmVuYXMoZmllbGQtPmZpbGUoKSk7Cit9CisKK2Jvb2wgSXNBbnlNZXNzYWdlKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKK2Jvb2wgSXNBbnlNZXNzYWdlKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworCitib29sIElzV2VsbEtub3duTWVzc2FnZShjb25zdCBGaWxlRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CisKK3ZvaWQgR2VuZXJhdGVVdGY4Q2hlY2tDb2RlRm9yU3RyaW5nKAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgYm9vbCBmb3JfcGFyc2UsCisgICAgY29uc3QgbWFwPHN0cmluZywgc3RyaW5nPiYgdmFyaWFibGVzLAorICAgIGNvbnN0IGNoYXIqIHBhcmFtZXRlcnMsCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIpOworCit2b2lkIEdlbmVyYXRlVXRmOENoZWNrQ29kZUZvckNvcmQoCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICBib29sIGZvcl9wYXJzZSwKKyAgICBjb25zdCBtYXA8c3RyaW5nLCBzdHJpbmc+JiB2YXJpYWJsZXMsCisgICAgY29uc3QgY2hhciogcGFyYW1ldGVycywKKyAgICBpbzo6UHJpbnRlciogcHJpbnRlcik7CisKK30gIC8vIG5hbWVzcGFjZSBjcHAKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NQUF9IRUxQRVJTX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX21hcF9maWVsZC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9tYXBfZmllbGQuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTVlMmYwNwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9tYXBfZmllbGQuY2MKQEAgLTAsMCArMSw0MTAgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfbWFwX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfaGVscGVycy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBjcHAgeworCitib29sIElzUHJvdG8zRmllbGQoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZF9kZXNjcmlwdG9yKSB7CisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlX2Rlc2NyaXB0b3IgPSBmaWVsZF9kZXNjcmlwdG9yLT5maWxlKCk7CisgIHJldHVybiBmaWxlX2Rlc2NyaXB0b3ItPnN5bnRheCgpID09IEZpbGVEZXNjcmlwdG9yOjpTWU5UQVhfUFJPVE8zOworfQorCit2b2lkIFNldE1lc3NhZ2VWYXJpYWJsZXMoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgIG1hcDxzdHJpbmcsIHN0cmluZz4qIHZhcmlhYmxlcywKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBPcHRpb25zJiBvcHRpb25zKSB7CisgIFNldENvbW1vbkZpZWxkVmFyaWFibGVzKGRlc2NyaXB0b3IsIHZhcmlhYmxlcywgb3B0aW9ucyk7CisgICgqdmFyaWFibGVzKVsidHlwZSJdID0gRmllbGRNZXNzYWdlVHlwZU5hbWUoZGVzY3JpcHRvcik7CisgICgqdmFyaWFibGVzKVsic3RyZWFtX3dyaXRlciJdID0gKCp2YXJpYWJsZXMpWyJkZWNsYXJlZF90eXBlIl0gKworICAgICAgKEhhc0Zhc3RBcnJheVNlcmlhbGl6YXRpb24oZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCktPmZpbGUoKSkgPworICAgICAgICJNYXliZVRvQXJyYXkiIDoKKyAgICAgICAiIik7CisgICgqdmFyaWFibGVzKVsiZnVsbF9uYW1lIl0gPSBkZXNjcmlwdG9yLT5mdWxsX25hbWUoKTsKKworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGtleSA9CisgICAgICBkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJrZXkiKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiB2YWwgPQorICAgICAgZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgidmFsdWUiKTsKKyAgKCp2YXJpYWJsZXMpWyJrZXlfY3BwIl0gPSBQcmltaXRpdmVUeXBlTmFtZShrZXktPmNwcF90eXBlKCkpOworICBzd2l0Y2ggKHZhbC0+Y3BwX3R5cGUoKSkgeworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U6CisgICAgICAoKnZhcmlhYmxlcylbInZhbF9jcHAiXSA9IEZpZWxkTWVzc2FnZVR5cGVOYW1lKHZhbCk7CisgICAgICAoKnZhcmlhYmxlcylbIndyYXBwZXIiXSA9ICJFbnRyeVdyYXBwZXIiOworICAgICAgYnJlYWs7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRU5VTToKKyAgICAgICgqdmFyaWFibGVzKVsidmFsX2NwcCJdID0gQ2xhc3NOYW1lKHZhbC0+ZW51bV90eXBlKCksIHRydWUpOworICAgICAgKCp2YXJpYWJsZXMpWyJ3cmFwcGVyIl0gPSAiRW51bUVudHJ5V3JhcHBlciI7CisgICAgICBicmVhazsKKyAgICBkZWZhdWx0OgorICAgICAgKCp2YXJpYWJsZXMpWyJ2YWxfY3BwIl0gPSBQcmltaXRpdmVUeXBlTmFtZSh2YWwtPmNwcF90eXBlKCkpOworICAgICAgKCp2YXJpYWJsZXMpWyJ3cmFwcGVyIl0gPSAiRW50cnlXcmFwcGVyIjsKKyAgfQorICAoKnZhcmlhYmxlcylbImtleV93aXJlX3R5cGUiXSA9CisgICAgICAiOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfIiArCisgICAgICBUb1VwcGVyKERlY2xhcmVkVHlwZU1ldGhvZE5hbWUoa2V5LT50eXBlKCkpKTsKKyAgKCp2YXJpYWJsZXMpWyJ2YWxfd2lyZV90eXBlIl0gPQorICAgICAgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFXyIgKworICAgICAgVG9VcHBlcihEZWNsYXJlZFR5cGVNZXRob2ROYW1lKHZhbC0+dHlwZSgpKSk7CisgICgqdmFyaWFibGVzKVsibWFwX2NsYXNzbmFtZSJdID0gQ2xhc3NOYW1lKGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpLCBmYWxzZSk7CisgICgqdmFyaWFibGVzKVsibnVtYmVyIl0gPSBTaW1wbGVJdG9hKGRlc2NyaXB0b3ItPm51bWJlcigpKTsKKyAgKCp2YXJpYWJsZXMpWyJ0YWciXSA9IFNpbXBsZUl0b2EoaW50ZXJuYWw6OldpcmVGb3JtYXQ6Ok1ha2VUYWcoZGVzY3JpcHRvcikpOworCisgIGlmIChIYXNEZXNjcmlwdG9yTWV0aG9kcyhkZXNjcmlwdG9yLT5maWxlKCkpKSB7CisgICAgKCp2YXJpYWJsZXMpWyJsaXRlIl0gPSAiIjsKKyAgfSBlbHNlIHsKKyAgICAoKnZhcmlhYmxlcylbImxpdGUiXSA9ICJMaXRlIjsKKyAgfQorCisgIGlmICghSXNQcm90bzNGaWVsZChkZXNjcmlwdG9yKSAmJgorICAgICAgdmFsLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX0VOVU0pIHsKKyAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBkZWZhdWx0X3ZhbHVlID0gdmFsLT5kZWZhdWx0X3ZhbHVlX2VudW0oKTsKKyAgICAoKnZhcmlhYmxlcylbImRlZmF1bHRfZW51bV92YWx1ZSJdID0gSW50MzJUb1N0cmluZyhkZWZhdWx0X3ZhbHVlLT5udW1iZXIoKSk7CisgIH0gZWxzZSB7CisgICAgKCp2YXJpYWJsZXMpWyJkZWZhdWx0X2VudW1fdmFsdWUiXSA9ICIwIjsKKyAgfQorfQorCitNYXBGaWVsZEdlbmVyYXRvcjo6CitNYXBGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICBjb25zdCBPcHRpb25zJiBvcHRpb25zKQorICAgIDogZGVzY3JpcHRvcl8oZGVzY3JpcHRvciksCisgICAgICBkZXBlbmRlbnRfZmllbGRfKG9wdGlvbnMucHJvdG9faCAmJiBJc0ZpZWxkRGVwZW5kZW50KGRlc2NyaXB0b3IpKSB7CisgIFNldE1lc3NhZ2VWYXJpYWJsZXMoZGVzY3JpcHRvciwgJnZhcmlhYmxlc18sIG9wdGlvbnMpOworfQorCitNYXBGaWVsZEdlbmVyYXRvcjo6fk1hcEZpZWxkR2VuZXJhdG9yKCkge30KKwordm9pZCBNYXBGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVByaXZhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAidHlwZWRlZiA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpNYXBFbnRyeUxpdGU8XG4iCisgICAgICAiICAgICRrZXlfY3BwJCwgJHZhbF9jcHAkLFxuIgorICAgICAgIiAgICAka2V5X3dpcmVfdHlwZSQsXG4iCisgICAgICAiICAgICR2YWxfd2lyZV90eXBlJCxcbiIKKyAgICAgICIgICAgJGRlZmF1bHRfZW51bV92YWx1ZSQgPlxuIgorICAgICAgIiAgICAkbWFwX2NsYXNzbmFtZSQ7XG4iCisgICAgICAiOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6TWFwRmllbGQkbGl0ZSQ8XG4iCisgICAgICAiICAgICRrZXlfY3BwJCwgJHZhbF9jcHAkLFxuIgorICAgICAgIiAgICAka2V5X3dpcmVfdHlwZSQsXG4iCisgICAgICAiICAgICR2YWxfd2lyZV90eXBlJCxcbiIKKyAgICAgICIgICAgJGRlZmF1bHRfZW51bV92YWx1ZSQgPiAkbmFtZSRfO1xuIik7Cit9CisKK3ZvaWQgTWFwRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVBY2Nlc3NvckRlY2xhcmF0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWFwPCAka2V5X2NwcCQsICR2YWxfY3BwJCA+JlxuIgorICAgICAgIiAgICAkbmFtZSQoKSBjb25zdCRkZXByZWNhdGlvbiQ7XG4iCisgICAgICAiOjpnb29nbGU6OnByb3RvYnVmOjpNYXA8ICRrZXlfY3BwJCwgJHZhbF9jcHAkID4qXG4iCisgICAgICAiICAgIG11dGFibGVfJG5hbWUkKCkkZGVwcmVjYXRpb24kO1xuIik7Cit9CisKK3ZvaWQgTWFwRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVJbmxpbmVBY2Nlc3NvckRlZmluaXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaXNfaW5saW5lKSBjb25zdCB7CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyaWFibGVzKHZhcmlhYmxlc18pOworICB2YXJpYWJsZXNbImlubGluZSJdID0gaXNfaW5saW5lID8gImlubGluZSIgOiAiIjsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICAgIiRpbmxpbmUkIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWFwPCAka2V5X2NwcCQsICR2YWxfY3BwJCA+JlxuIgorICAgICAgIiRjbGFzc25hbWUkOjokbmFtZSQoKSBjb25zdCB7XG4iCisgICAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbWFwOiRmdWxsX25hbWUkKVxuIgorICAgICAgIiAgcmV0dXJuICRuYW1lJF8uR2V0TWFwKCk7XG4iCisgICAgICAifVxuIgorICAgICAgIiRpbmxpbmUkIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWFwPCAka2V5X2NwcCQsICR2YWxfY3BwJCA+KlxuIgorICAgICAgIiRjbGFzc25hbWUkOjptdXRhYmxlXyRuYW1lJCgpIHtcbiIKKyAgICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX21hcDokZnVsbF9uYW1lJClcbiIKKyAgICAgICIgIHJldHVybiAkbmFtZSRfLk11dGFibGVNYXAoKTtcbiIKKyAgICAgICJ9XG4iKTsKK30KKwordm9pZCBNYXBGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUNsZWFyaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlcyh2YXJpYWJsZXNfKTsKKyAgdmFyaWFibGVzWyJ0aGlzX21lc3NhZ2UiXSA9IGRlcGVuZGVudF9maWVsZF8gPyBEZXBlbmRlbnRCYXNlRG93bkNhc3QoKSA6ICIiOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXMsICIkdGhpc19tZXNzYWdlJCRuYW1lJF8uQ2xlYXIoKTtcbiIpOworfQorCit2b2lkIE1hcEZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgIiRuYW1lJF8uTWVyZ2VGcm9tKGZyb20uJG5hbWUkXyk7XG4iKTsKK30KKwordm9pZCBNYXBGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVN3YXBwaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAiJG5hbWUkXy5Td2FwKCZvdGhlci0+JG5hbWUkXyk7XG4iKTsKK30KKwordm9pZCBNYXBGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUNvbnN0cnVjdG9yQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoSGFzRGVzY3JpcHRvck1ldGhvZHMoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAiJG5hbWUkXy5TZXRBc3NpZ25EZXNjcmlwdG9yQ2FsbGJhY2soXG4iCisgICAgICAgICIgICAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKTtcbiIKKyAgICAgICAgIiRuYW1lJF8uU2V0RW50cnlEZXNjcmlwdG9yKFxuIgorICAgICAgICAiICAgICYkdHlwZSRfZGVzY3JpcHRvcl8pO1xuIik7CisgIH0KK30KKwordm9pZCBNYXBGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lcmdlRnJvbUNvZGVkU3RyZWFtKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogdmFsdWVfZmllbGQgPQorICAgICAgZGVzY3JpcHRvcl8tPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoInZhbHVlIik7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiOjpnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPCRtYXBfY2xhc3NuYW1lJD4gZW50cnkoJG5hbWUkXy5OZXdFbnRyeSgpKTtcbiIpOworCisgIGlmIChJc1Byb3RvM0ZpZWxkKGRlc2NyaXB0b3JfKSB8fAorICAgICAgdmFsdWVfZmllbGQtPnR5cGUoKSAhPSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRU5VTSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICJET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRNZXNzYWdlTm9WaXJ0dWFsKFxuIgorICAgICAgICAiICAgIGlucHV0LCBlbnRyeS5nZXQoKSkpO1xuIik7CisgICAgc3dpdGNoICh2YWx1ZV9maWVsZC0+Y3BwX3R5cGUoKSkgeworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRToKKyAgICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgICAgICIoKm11dGFibGVfJG5hbWUkKCkpW2VudHJ5LT5rZXkoKV0uU3dhcCgiCisgICAgICAgICAgICAiZW50cnktPm11dGFibGVfdmFsdWUoKSk7XG4iKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9FTlVNOgorICAgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAgICAgIigqbXV0YWJsZV8kbmFtZSQoKSlbZW50cnktPmtleSgpXSA9XG4iCisgICAgICAgICAgICAiICAgIHN0YXRpY19jYXN0PCAkdmFsX2NwcCQgPigqZW50cnktPm11dGFibGVfdmFsdWUoKSk7XG4iKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBkZWZhdWx0OgorICAgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAgICAgIigqbXV0YWJsZV8kbmFtZSQoKSlbZW50cnktPmtleSgpXSA9ICplbnRyeS0+bXV0YWJsZV92YWx1ZSgpO1xuIik7CisgICAgICAgIGJyZWFrOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAie1xuIgorICAgICAgICAiICA6OnN0ZDo6c3RyaW5nIGRhdGE7XG4iCisgICAgICAgICIgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFN0cmluZyhpbnB1dCwgJmRhdGEpKTtcbiIKKyAgICAgICAgIiAgRE9fKGVudHJ5LT5QYXJzZUZyb21TdHJpbmcoZGF0YSkpO1xuIgorICAgICAgICAiICBpZiAoJHZhbF9jcHAkX0lzVmFsaWQoKmVudHJ5LT5tdXRhYmxlX3ZhbHVlKCkpKSB7XG4iCisgICAgICAgICIgICAgKCptdXRhYmxlXyRuYW1lJCgpKVtlbnRyeS0+a2V5KCldID1cbiIKKyAgICAgICAgIiAgICAgICAgc3RhdGljX2Nhc3Q8ICR2YWxfY3BwJCA+KCplbnRyeS0+bXV0YWJsZV92YWx1ZSgpKTtcbiIKKyAgICAgICAgIiAgfSBlbHNlIHtcbiIpOworICAgIGlmIChIYXNEZXNjcmlwdG9yTWV0aG9kcyhkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgICAiICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSIKKyAgICAgICAgICAiLT5BZGRMZW5ndGhEZWxpbWl0ZWQoJG51bWJlciQsIGRhdGEpO1xuIik7CisgICAgfSBlbHNlIHsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICAgIiAgICB1bmtub3duX2ZpZWxkc19zdHJlYW0uV3JpdGVWYXJpbnQzMigkdGFnJCk7XG4iCisgICAgICAgICAgIiAgICB1bmtub3duX2ZpZWxkc19zdHJlYW0uV3JpdGVWYXJpbnQzMihkYXRhLnNpemUoKSk7XG4iCisgICAgICAgICAgIiAgICB1bmtub3duX2ZpZWxkc19zdHJlYW0uV3JpdGVTdHJpbmcoZGF0YSk7XG4iKTsKKyAgICB9CisKKworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICIgIH1cbiIKKyAgICAgICAgIn1cbiIpOworICB9CisKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBrZXlfZmllbGQgPQorICAgICAgZGVzY3JpcHRvcl8tPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoImtleSIpOworICBpZiAoa2V5X2ZpZWxkLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX1NUUklORykgeworICAgIEdlbmVyYXRlVXRmOENoZWNrQ29kZUZvclN0cmluZygKKyAgICAgICAga2V5X2ZpZWxkLCB0cnVlLCB2YXJpYWJsZXNfLAorICAgICAgICAiZW50cnktPmtleSgpLmRhdGEoKSwgZW50cnktPmtleSgpLmxlbmd0aCgpLFxuIiwgcHJpbnRlcik7CisgIH0KKyAgaWYgKHZhbHVlX2ZpZWxkLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX1NUUklORykgeworICAgIEdlbmVyYXRlVXRmOENoZWNrQ29kZUZvclN0cmluZygKKyAgICAgICAgdmFsdWVfZmllbGQsIHRydWUsIHZhcmlhYmxlc18sCisgICAgICAgICJlbnRyeS0+bXV0YWJsZV92YWx1ZSgpLT5kYXRhKCksXG4iCisgICAgICAgICJlbnRyeS0+bXV0YWJsZV92YWx1ZSgpLT5sZW5ndGgoKSxcbiIsIHByaW50ZXIpOworICB9CisKKyAgLy8gSWYgZW50cnkgaXMgYWxsb2NhdGVkIGJ5IGFyZW5hLCBpdHMgZGVzY3RydWN0b3Igc2hvdWxkIGJlIGF2b2lkZWQuCisgIGlmIChTdXBwb3J0c0FyZW5hcyhkZXNjcmlwdG9yXykpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAiaWYgKGVudHJ5LT5HZXRBcmVuYSgpICE9IE5VTEwpIGVudHJ5LnJlbGVhc2UoKTtcbiIpOworICB9Cit9CisKK3ZvaWQgTWFwRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJ7XG4iCisgICAgICAiICA6Omdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8JG1hcF9jbGFzc25hbWUkPiBlbnRyeTtcbiIKKyAgICAgICIgIGZvciAoOjpnb29nbGU6OnByb3RvYnVmOjpNYXA8ICRrZXlfY3BwJCwgJHZhbF9jcHAkID46OmNvbnN0X2l0ZXJhdG9yXG4iCisgICAgICAiICAgICAgaXQgPSB0aGlzLT4kbmFtZSQoKS5iZWdpbigpO1xuIgorICAgICAgIiAgICAgIGl0ICE9IHRoaXMtPiRuYW1lJCgpLmVuZCgpOyArK2l0KSB7XG4iKTsKKworICAvLyBJZiBlbnRyeSBpcyBhbGxvY2F0ZWQgYnkgYXJlbmEsIGl0cyBkZXNjdHJ1Y3RvciBzaG91bGQgYmUgYXZvaWRlZC4KKyAgaWYgKFN1cHBvcnRzQXJlbmFzKGRlc2NyaXB0b3JfKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICIgICAgaWYgKGVudHJ5LmdldCgpICE9IE5VTEwgJiYgZW50cnktPkdldEFyZW5hKCkgIT0gTlVMTCkge1xuIgorICAgICAgICAiICAgICAgZW50cnkucmVsZWFzZSgpO1xuIgorICAgICAgICAiICAgIH1cbiIpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIgICAgZW50cnkucmVzZXQoJG5hbWUkXy5OZXckd3JhcHBlciQoaXQtPmZpcnN0LCBpdC0+c2Vjb25kKSk7XG4iCisgICAgICAiICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZSRzdHJlYW1fd3JpdGVyJChcbiIKKyAgICAgICIgICAgICAgICRudW1iZXIkLCAqZW50cnksIG91dHB1dCk7XG4iKTsKKworICBwcmludGVyLT5JbmRlbnQoKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBrZXlfZmllbGQgPQorICAgICAgZGVzY3JpcHRvcl8tPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoImtleSIpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHZhbHVlX2ZpZWxkID0KKyAgICAgIGRlc2NyaXB0b3JfLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJ2YWx1ZSIpOworICBpZiAoa2V5X2ZpZWxkLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX1NUUklORykgeworICAgIEdlbmVyYXRlVXRmOENoZWNrQ29kZUZvclN0cmluZygKKyAgICAgICAga2V5X2ZpZWxkLCBmYWxzZSwgdmFyaWFibGVzXywKKyAgICAgICAgIml0LT5maXJzdC5kYXRhKCksIGl0LT5maXJzdC5sZW5ndGgoKSxcbiIsIHByaW50ZXIpOworICB9CisgIGlmICh2YWx1ZV9maWVsZC0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TVFJJTkcpIHsKKyAgICBHZW5lcmF0ZVV0ZjhDaGVja0NvZGVGb3JTdHJpbmcoCisgICAgICAgIHZhbHVlX2ZpZWxkLCBmYWxzZSwgdmFyaWFibGVzXywKKyAgICAgICAgIml0LT5zZWNvbmQuZGF0YSgpLCBpdC0+c2Vjb25kLmxlbmd0aCgpLFxuIiwgcHJpbnRlcik7CisgIH0KKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPk91dGRlbnQoKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAgICIgIH1cbiIpOworCisgIC8vIElmIGVudHJ5IGlzIGFsbG9jYXRlZCBieSBhcmVuYSwgaXRzIGRlc2N0cnVjdG9yIHNob3VsZCBiZSBhdm9pZGVkLgorICBpZiAoU3VwcG9ydHNBcmVuYXMoZGVzY3JpcHRvcl8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgIiAgaWYgKGVudHJ5LmdldCgpICE9IE5VTEwgJiYgZW50cnktPkdldEFyZW5hKCkgIT0gTlVMTCkge1xuIgorICAgICAgICAiICAgIGVudHJ5LnJlbGVhc2UoKTtcbiIKKyAgICAgICAgIiAgfVxuIik7CisgIH0KKworICBwcmludGVyLT5QcmludCgifVxuIik7Cit9CisKK3ZvaWQgTWFwRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAie1xuIgorICAgICAgIiAgOjpnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPCRtYXBfY2xhc3NuYW1lJD4gZW50cnk7XG4iCisgICAgICAiICBmb3IgKDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWFwPCAka2V5X2NwcCQsICR2YWxfY3BwJCA+Ojpjb25zdF9pdGVyYXRvclxuIgorICAgICAgIiAgICAgIGl0ID0gdGhpcy0+JG5hbWUkKCkuYmVnaW4oKTtcbiIKKyAgICAgICIgICAgICBpdCAhPSB0aGlzLT4kbmFtZSQoKS5lbmQoKTsgKytpdCkge1xuIik7CisKKyAgLy8gSWYgZW50cnkgaXMgYWxsb2NhdGVkIGJ5IGFyZW5hLCBpdHMgZGVzY3RydWN0b3Igc2hvdWxkIGJlIGF2b2lkZWQuCisgIGlmIChTdXBwb3J0c0FyZW5hcyhkZXNjcmlwdG9yXykpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAiICAgIGlmIChlbnRyeS5nZXQoKSAhPSBOVUxMICYmIGVudHJ5LT5HZXRBcmVuYSgpICE9IE5VTEwpIHtcbiIKKyAgICAgICAgIiAgICAgIGVudHJ5LnJlbGVhc2UoKTtcbiIKKyAgICAgICAgIiAgICB9XG4iKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiICAgIGVudHJ5LnJlc2V0KCRuYW1lJF8uTmV3JHdyYXBwZXIkKGl0LT5maXJzdCwgaXQtPnNlY29uZCkpO1xuIgorICAgICAgIiAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6XG4iCisgICAgICAiICAgICAgICBXcml0ZSRkZWNsYXJlZF90eXBlJE5vVmlydHVhbFRvQXJyYXkoXG4iCisgICAgICAiICAgICAgICAgICAgJG51bWJlciQsICplbnRyeSwgdGFyZ2V0KTtcbiIpOworCisgIHByaW50ZXItPkluZGVudCgpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGtleV9maWVsZCA9CisgICAgICBkZXNjcmlwdG9yXy0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgia2V5Iik7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogdmFsdWVfZmllbGQgPQorICAgICAgZGVzY3JpcHRvcl8tPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoInZhbHVlIik7CisgIGlmIChrZXlfZmllbGQtPnR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU1RSSU5HKSB7CisgICAgR2VuZXJhdGVVdGY4Q2hlY2tDb2RlRm9yU3RyaW5nKAorICAgICAgICBrZXlfZmllbGQsIGZhbHNlLCB2YXJpYWJsZXNfLAorICAgICAgICAiaXQtPmZpcnN0LmRhdGEoKSwgaXQtPmZpcnN0Lmxlbmd0aCgpLFxuIiwgcHJpbnRlcik7CisgIH0KKyAgaWYgKHZhbHVlX2ZpZWxkLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX1NUUklORykgeworICAgIEdlbmVyYXRlVXRmOENoZWNrQ29kZUZvclN0cmluZygKKyAgICAgICAgdmFsdWVfZmllbGQsIGZhbHNlLCB2YXJpYWJsZXNfLAorICAgICAgICAiaXQtPnNlY29uZC5kYXRhKCksIGl0LT5zZWNvbmQubGVuZ3RoKCksXG4iLCBwcmludGVyKTsKKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAgICIgIH1cbiIpOworCisgIC8vIElmIGVudHJ5IGlzIGFsbG9jYXRlZCBieSBhcmVuYSwgaXRzIGRlc2N0cnVjdG9yIHNob3VsZCBiZSBhdm9pZGVkLgorICBpZiAoU3VwcG9ydHNBcmVuYXMoZGVzY3JpcHRvcl8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgIiAgaWYgKGVudHJ5LmdldCgpICE9IE5VTEwgJiYgZW50cnktPkdldEFyZW5hKCkgIT0gTlVMTCkge1xuIgorICAgICAgICAiICAgIGVudHJ5LnJlbGVhc2UoKTtcbiIKKyAgICAgICAgIiAgfVxuIik7CisgIH0KKworICBwcmludGVyLT5QcmludCgifVxuIik7Cit9CisKK3ZvaWQgTWFwRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVCeXRlU2l6ZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgInRvdGFsX3NpemUgKz0gJHRhZ19zaXplJCAqIHRoaXMtPiRuYW1lJF9zaXplKCk7XG4iCisgICAgICAie1xuIgorICAgICAgIiAgOjpnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPCRtYXBfY2xhc3NuYW1lJD4gZW50cnk7XG4iCisgICAgICAiICBmb3IgKDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWFwPCAka2V5X2NwcCQsICR2YWxfY3BwJCA+Ojpjb25zdF9pdGVyYXRvclxuIgorICAgICAgIiAgICAgIGl0ID0gdGhpcy0+JG5hbWUkKCkuYmVnaW4oKTtcbiIKKyAgICAgICIgICAgICBpdCAhPSB0aGlzLT4kbmFtZSQoKS5lbmQoKTsgKytpdCkge1xuIik7CisKKyAgLy8gSWYgZW50cnkgaXMgYWxsb2NhdGVkIGJ5IGFyZW5hLCBpdHMgZGVzY3RydWN0b3Igc2hvdWxkIGJlIGF2b2lkZWQuCisgIGlmIChTdXBwb3J0c0FyZW5hcyhkZXNjcmlwdG9yXykpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAiICAgIGlmIChlbnRyeS5nZXQoKSAhPSBOVUxMICYmIGVudHJ5LT5HZXRBcmVuYSgpICE9IE5VTEwpIHtcbiIKKyAgICAgICAgIiAgICAgIGVudHJ5LnJlbGVhc2UoKTtcbiIKKyAgICAgICAgIiAgICB9XG4iKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiICAgIGVudHJ5LnJlc2V0KCRuYW1lJF8uTmV3JHdyYXBwZXIkKGl0LT5maXJzdCwgaXQtPnNlY29uZCkpO1xuIgorICAgICAgIiAgICB0b3RhbF9zaXplICs9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpcbiIKKyAgICAgICIgICAgICAgICRkZWNsYXJlZF90eXBlJFNpemVOb1ZpcnR1YWwoKmVudHJ5KTtcbiIKKyAgICAgICIgIH1cbiIpOworCisgIC8vIElmIGVudHJ5IGlzIGFsbG9jYXRlZCBieSBhcmVuYSwgaXRzIGRlc2N0cnVjdG9yIHNob3VsZCBiZSBhdm9pZGVkLgorICBpZiAoU3VwcG9ydHNBcmVuYXMoZGVzY3JpcHRvcl8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgIiAgaWYgKGVudHJ5LmdldCgpICE9IE5VTEwgJiYgZW50cnktPkdldEFyZW5hKCkgIT0gTlVMTCkge1xuIgorICAgICAgICAiICAgIGVudHJ5LnJlbGVhc2UoKTtcbiIKKyAgICAgICAgIiAgfVxuIik7CisgIH0KKworICBwcmludGVyLT5QcmludCgifVxuIik7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBjcHAKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfbWFwX2ZpZWxkLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfbWFwX2ZpZWxkLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWUyMDU2MgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9tYXBfZmllbGQuaApAQCAtMCwwICsxLDc3IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1BQX01BUF9GSUVMRF9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NQUF9NQVBfRklFTERfSF9fCisKKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8c3RyaW5nPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfbWVzc2FnZV9maWVsZC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGNwcCB7CisKK2NsYXNzIE1hcEZpZWxkR2VuZXJhdG9yIDogcHVibGljIEZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IE1hcEZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT3B0aW9ucyYgb3B0aW9ucyk7CisgIH5NYXBGaWVsZEdlbmVyYXRvcigpOworCisgIC8vIGltcGxlbWVudHMgRmllbGRHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIHZvaWQgR2VuZXJhdGVQcml2YXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVBY2Nlc3NvckRlY2xhcmF0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVJbmxpbmVBY2Nlc3NvckRlZmluaXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGlzX2lubGluZSkgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVDbGVhcmluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU3dhcHBpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUNvbnN0cnVjdG9yQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnZUZyb21Db2RlZFN0cmVhbShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCeXRlU2l6ZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyBwcml2YXRlOgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworICBjb25zdCBib29sIGRlcGVuZGVudF9maWVsZF87CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyaWFibGVzXzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoTWFwRmllbGRHZW5lcmF0b3IpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGNwcAorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1BQX01BUF9GSUVMRF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9tZXNzYWdlLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX21lc3NhZ2UuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODMwNGViYgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9tZXNzYWdlLmNjCkBAIC0wLDAgKzEsMzc2NSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8YWxnb3JpdGhtPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9oYXNoLmg+CisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPG1lbW9yeT4KKyNpZm5kZWYgX1NIQVJFRF9QVFJfSAorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaGFyZWRfcHRyLmg+CisjZW5kaWYKKyNpbmNsdWRlIDx1dGlsaXR5PgorI2luY2x1ZGUgPHZlY3Rvcj4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9tZXNzYWdlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9lbnVtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZXh0ZW5zaW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfaGVscGVycy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaD4KKworCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGNwcCB7CisKK3VzaW5nIGludGVybmFsOjpXaXJlRm9ybWF0OwordXNpbmcgaW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOworCituYW1lc3BhY2UgeworCit0ZW1wbGF0ZSA8Y2xhc3MgVD4KK3ZvaWQgUHJpbnRGaWVsZENvbW1lbnQoaW86OlByaW50ZXIqIHByaW50ZXIsIGNvbnN0IFQqIGZpZWxkKSB7CisgIC8vIFByaW50IHRoZSBmaWVsZCdzIChvciBvbmVvZidzKSBwcm90by1zeW50YXggZGVmaW5pdGlvbiBhcyBhIGNvbW1lbnQuCisgIC8vIFdlIGRvbid0IHdhbnQgdG8gcHJpbnQgZ3JvdXAgYm9kaWVzIHNvIHdlIGN1dCBvZmYgYWZ0ZXIgdGhlIGZpcnN0CisgIC8vIGxpbmUuCisgIERlYnVnU3RyaW5nT3B0aW9ucyBvcHRpb25zOworICBvcHRpb25zLmVsaWRlX2dyb3VwX2JvZHkgPSB0cnVlOworICBvcHRpb25zLmVsaWRlX29uZW9mX2JvZHkgPSB0cnVlOworICBzdHJpbmcgZGVmID0gZmllbGQtPkRlYnVnU3RyaW5nV2l0aE9wdGlvbnMob3B0aW9ucyk7CisgIHByaW50ZXItPlByaW50KCIvLyAkZGVmJFxuIiwKKyAgICAiZGVmIiwgZGVmLnN1YnN0cigwLCBkZWYuZmluZF9maXJzdF9vZignXG4nKSkpOworfQorCitzdHJ1Y3QgRmllbGRPcmRlcmluZ0J5TnVtYmVyIHsKKyAgaW5saW5lIGJvb2wgb3BlcmF0b3IoKShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBiKSBjb25zdCB7CisgICAgcmV0dXJuIGEtPm51bWJlcigpIDwgYi0+bnVtYmVyKCk7CisgIH0KK307CisKKy8vIFNvcnQgdGhlIGZpZWxkcyBvZiB0aGUgZ2l2ZW4gRGVzY3JpcHRvciBieSBudW1iZXIgaW50byBhIG5ld1tdJ2QgYXJyYXkKKy8vIGFuZCByZXR1cm4gaXQuCitjb25zdCBGaWVsZERlc2NyaXB0b3IqKiBTb3J0RmllbGRzQnlOdW1iZXIoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqKiBmaWVsZHMgPQorICAgIG5ldyBjb25zdCBGaWVsZERlc2NyaXB0b3IqW2Rlc2NyaXB0b3ItPmZpZWxkX2NvdW50KCldOworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3ItPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGZpZWxkc1tpXSA9IGRlc2NyaXB0b3ItPmZpZWxkKGkpOworICB9CisgIHN0ZDo6c29ydChmaWVsZHMsIGZpZWxkcyArIGRlc2NyaXB0b3ItPmZpZWxkX2NvdW50KCksCisgICAgICAgICAgICBGaWVsZE9yZGVyaW5nQnlOdW1iZXIoKSk7CisgIHJldHVybiBmaWVsZHM7Cit9CisKKy8vIEZ1bmN0b3IgZm9yIHNvcnRpbmcgZXh0ZW5zaW9uIHJhbmdlcyBieSB0aGVpciAic3RhcnQiIGZpZWxkIG51bWJlci4KK3N0cnVjdCBFeHRlbnNpb25SYW5nZVNvcnRlciB7CisgIGJvb2wgb3BlcmF0b3IoKShjb25zdCBEZXNjcmlwdG9yOjpFeHRlbnNpb25SYW5nZSogbGVmdCwKKyAgICAgICAgICAgICAgICAgIGNvbnN0IERlc2NyaXB0b3I6OkV4dGVuc2lvblJhbmdlKiByaWdodCkgY29uc3QgeworICAgIHJldHVybiBsZWZ0LT5zdGFydCA8IHJpZ2h0LT5zdGFydDsKKyAgfQorfTsKKworLy8gUmV0dXJucyB0cnVlIGlmIHRoZSAicmVxdWlyZWQiIHJlc3RyaWN0aW9uIGNoZWNrIHNob3VsZCBiZSBpZ25vcmVkIGZvciB0aGUKKy8vIGdpdmVuIGZpZWxkLgoraW5saW5lIHN0YXRpYyBib29sIFNob3VsZElnbm9yZVJlcXVpcmVkRmllbGRDaGVjaygKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIHJldHVybiBmYWxzZTsKK30KKworLy8gUmV0dXJucyB0cnVlIGlmIHRoZSBtZXNzYWdlIHR5cGUgaGFzIGFueSByZXF1aXJlZCBmaWVsZHMuICBJZiBpdCBkb2Vzbid0LAorLy8gd2UgY2FuIG9wdGltaXplIG91dCBjYWxscyB0byBpdHMgSXNJbml0aWFsaXplZCgpIG1ldGhvZC4KKy8vCisvLyBhbHJlYWR5X3NlZW4gaXMgdXNlZCB0byBhdm9pZCBjaGVja2luZyB0aGUgc2FtZSB0eXBlIG11bHRpcGxlIHRpbWVzCisvLyAoYW5kIGFsc28gdG8gcHJvdGVjdCBhZ2FpbnN0IHJlY3Vyc2lvbikuCitzdGF0aWMgYm9vbCBIYXNSZXF1aXJlZEZpZWxkcygKKyAgICBjb25zdCBEZXNjcmlwdG9yKiB0eXBlLAorICAgIGhhc2hfc2V0PGNvbnN0IERlc2NyaXB0b3IqPiogYWxyZWFkeV9zZWVuKSB7CisgIGlmIChhbHJlYWR5X3NlZW4tPmNvdW50KHR5cGUpID4gMCkgeworICAgIC8vIFNpbmNlIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIGEgcmVxdWlyZWQgZmllbGQgY2F1c2VzIHRoZSB3aG9sZQorICAgIC8vIGZ1bmN0aW9uIHRvIHJldHVybiB0cnVlLCB3ZSBjYW4gYXNzdW1lIHRoYXQgaWYgdGhlIHR5cGUgaXMgYWxyZWFkeQorICAgIC8vIGluIHRoZSBjYWNoZSBpdCBkaWRuJ3QgaGF2ZSBhbnkgcmVxdWlyZWQgZmllbGRzLgorICAgIHJldHVybiBmYWxzZTsKKyAgfQorICBhbHJlYWR5X3NlZW4tPmluc2VydCh0eXBlKTsKKworICAvLyBJZiB0aGUgdHlwZSBoYXMgZXh0ZW5zaW9ucywgYW4gZXh0ZW5zaW9uIHdpdGggbWVzc2FnZSB0eXBlIGNvdWxkIGNvbnRhaW4KKyAgLy8gcmVxdWlyZWQgZmllbGRzLCBzbyB3ZSBoYXZlIHRvIGJlIGNvbnNlcnZhdGl2ZSBhbmQgYXNzdW1lIHN1Y2ggYW4KKyAgLy8gZXh0ZW5zaW9uIGV4aXN0cy4KKyAgaWYgKHR5cGUtPmV4dGVuc2lvbl9yYW5nZV9jb3VudCgpID4gMCkgcmV0dXJuIHRydWU7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0eXBlLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gdHlwZS0+ZmllbGQoaSk7CisgICAgaWYgKGZpZWxkLT5pc19yZXF1aXJlZCgpKSB7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgICAgaWYgKGZpZWxkLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFICYmCisgICAgICAgICFTaG91bGRJZ25vcmVSZXF1aXJlZEZpZWxkQ2hlY2soZmllbGQpKSB7CisgICAgICBpZiAoSGFzUmVxdWlyZWRGaWVsZHMoZmllbGQtPm1lc3NhZ2VfdHlwZSgpLCBhbHJlYWR5X3NlZW4pKSB7CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgfQorICAgIH0KKyAgfQorCisgIHJldHVybiBmYWxzZTsKK30KKworc3RhdGljIGJvb2wgSGFzUmVxdWlyZWRGaWVsZHMoY29uc3QgRGVzY3JpcHRvciogdHlwZSkgeworICBoYXNoX3NldDxjb25zdCBEZXNjcmlwdG9yKj4gYWxyZWFkeV9zZWVuOworICByZXR1cm4gSGFzUmVxdWlyZWRGaWVsZHModHlwZSwgJmFscmVhZHlfc2Vlbik7Cit9CisKKy8vIFRoaXMgcmV0dXJucyBhbiBlc3RpbWF0ZSBvZiB0aGUgY29tcGlsZXIncyBhbGlnbm1lbnQgZm9yIHRoZSBmaWVsZC4gIFRoaXMKKy8vIGNhbid0IGd1YXJhbnRlZSB0byBiZSBjb3JyZWN0IGJlY2F1c2UgdGhlIGdlbmVyYXRlZCBjb2RlIGNvdWxkIGJlIGNvbXBpbGVkIG9uCisvLyBkaWZmZXJlbnQgc3lzdGVtcyB3aXRoIGRpZmZlcmVudCBhbGlnbm1lbnQgcnVsZXMuICBUaGUgZXN0aW1hdGVzIGJlbG93IGFzc3VtZQorLy8gNjQtYml0IHBvaW50ZXJzLgoraW50IEVzdGltYXRlQWxpZ25tZW50U2l6ZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIGlmIChmaWVsZCA9PSBOVUxMKSByZXR1cm4gMDsKKyAgaWYgKGZpZWxkLT5pc19yZXBlYXRlZCgpKSByZXR1cm4gODsKKyAgc3dpdGNoIChmaWVsZC0+Y3BwX3R5cGUoKSkgeworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0JPT0w6CisgICAgICByZXR1cm4gMTsKKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0lOVDMyOgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1VJTlQzMjoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9FTlVNOgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0ZMT0FUOgorICAgICAgcmV0dXJuIDQ7CisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9JTlQ2NDoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9VSU5UNjQ6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRE9VQkxFOgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORzoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgcmV0dXJuIDg7CisgIH0KKyAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkNhbid0IGdldCBoZXJlLiI7CisgIHJldHVybiAtMTsgIC8vIE1ha2UgY29tcGlsZXIgaGFwcHkuCit9CisKKy8vIEZpZWxkR3JvdXAgaXMganVzdCBhIGhlbHBlciBmb3IgT3B0aW1pemVQYWRkaW5nIGJlbG93LiAgSXQgaG9sZHMgYSB2ZWN0b3Igb2YKKy8vIGZpZWxkcyB0aGF0IGFyZSBncm91cGVkIHRvZ2V0aGVyIGJlY2F1c2UgdGhleSBoYXZlIGNvbXBhdGlibGUgYWxpZ25tZW50LCBhbmQKKy8vIGEgcHJlZmVycmVkIGxvY2F0aW9uIGluIHRoZSBmaW5hbCBmaWVsZCBvcmRlcmluZy4KK2NsYXNzIEZpZWxkR3JvdXAgeworIHB1YmxpYzoKKyAgRmllbGRHcm91cCgpCisgICAgICA6IHByZWZlcnJlZF9sb2NhdGlvbl8oMCkge30KKworICAvLyBBIGdyb3VwIHdpdGggYSBzaW5nbGUgZmllbGQuCisgIEZpZWxkR3JvdXAoZmxvYXQgcHJlZmVycmVkX2xvY2F0aW9uLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKQorICAgICAgOiBwcmVmZXJyZWRfbG9jYXRpb25fKHByZWZlcnJlZF9sb2NhdGlvbiksCisgICAgICAgIGZpZWxkc18oMSwgZmllbGQpIHt9CisKKyAgLy8gQXBwZW5kIHRoZSBmaWVsZHMgaW4gJ290aGVyJyB0byB0aGlzIGdyb3VwLgorICB2b2lkIEFwcGVuZChjb25zdCBGaWVsZEdyb3VwJiBvdGhlcikgeworICAgIGlmIChvdGhlci5maWVsZHNfLmVtcHR5KCkpIHsKKyAgICAgIHJldHVybjsKKyAgICB9CisgICAgLy8gUHJlZmVycmVkIGxvY2F0aW9uIGlzIHRoZSBhdmVyYWdlIGFtb25nIGFsbCB0aGUgZmllbGRzLCBzbyB3ZSB3ZWlnaHQgYnkKKyAgICAvLyB0aGUgbnVtYmVyIG9mIGZpZWxkcyBvbiBlYWNoIEZpZWxkR3JvdXAgb2JqZWN0LgorICAgIHByZWZlcnJlZF9sb2NhdGlvbl8gPQorICAgICAgICAocHJlZmVycmVkX2xvY2F0aW9uXyAqIGZpZWxkc18uc2l6ZSgpICsKKyAgICAgICAgIChvdGhlci5wcmVmZXJyZWRfbG9jYXRpb25fICogb3RoZXIuZmllbGRzXy5zaXplKCkpKSAvCisgICAgICAgIChmaWVsZHNfLnNpemUoKSArIG90aGVyLmZpZWxkc18uc2l6ZSgpKTsKKyAgICBmaWVsZHNfLmluc2VydChmaWVsZHNfLmVuZCgpLCBvdGhlci5maWVsZHNfLmJlZ2luKCksIG90aGVyLmZpZWxkc18uZW5kKCkpOworICB9CisKKyAgdm9pZCBTZXRQcmVmZXJyZWRMb2NhdGlvbihmbG9hdCBsb2NhdGlvbikgeyBwcmVmZXJyZWRfbG9jYXRpb25fID0gbG9jYXRpb247IH0KKyAgY29uc3QgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+JiBmaWVsZHMoKSBjb25zdCB7IHJldHVybiBmaWVsZHNfOyB9CisKKyAgLy8gRmllbGRHcm91cCBvYmplY3RzIHNvcnQgYnkgdGhlaXIgcHJlZmVycmVkIGxvY2F0aW9uLgorICBib29sIG9wZXJhdG9yPChjb25zdCBGaWVsZEdyb3VwJiBvdGhlcikgY29uc3QgeworICAgIHJldHVybiBwcmVmZXJyZWRfbG9jYXRpb25fIDwgb3RoZXIucHJlZmVycmVkX2xvY2F0aW9uXzsKKyAgfQorCisgcHJpdmF0ZToKKyAgLy8gInByZWZlcnJlZF9sb2NhdGlvbl8iIGlzIGFuIGVzdGltYXRlIG9mIHdoZXJlIHRoaXMgZ3JvdXAgc2hvdWxkIGdvIGluIHRoZQorICAvLyBmaW5hbCBsaXN0IG9mIGZpZWxkcy4gIFdlIGNvbXB1dGUgdGhpcyBieSB0YWtpbmcgdGhlIGF2ZXJhZ2UgaW5kZXggb2YgZWFjaAorICAvLyBmaWVsZCBpbiB0aGlzIGdyb3VwIGluIHRoZSBvcmlnaW5hbCBvcmRlcmluZyBvZiBmaWVsZHMuICBUaGlzIGlzIHZlcnkKKyAgLy8gYXBwcm94aW1hdGUsIGJ1dCBzaG91bGQgcHV0IHRoaXMgZ3JvdXAgY2xvc2UgdG8gd2hlcmUgaXRzIG1lbWJlciBmaWVsZHMKKyAgLy8gb3JpZ2luYWxseSB3ZW50LgorICBmbG9hdCBwcmVmZXJyZWRfbG9jYXRpb25fOworICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4gZmllbGRzXzsKKyAgLy8gV2UgcmVseSBvbiB0aGUgZGVmYXVsdCBjb3B5IGNvbnN0cnVjdG9yIGFuZCBvcGVyYXRvcj0gc28gdGhpcyB0eXBlIGNhbiBiZQorICAvLyB1c2VkIGluIGEgdmVjdG9yLgorfTsKKworLy8gUmVvcmRlciAnZmllbGRzJyBzbyB0aGF0IGlmIHRoZSBmaWVsZHMgYXJlIG91dHB1dCBpbnRvIGEgYysrIGNsYXNzIGluIHRoZSBuZXcKKy8vIG9yZGVyLCB0aGUgYWxpZ25tZW50IHBhZGRpbmcgaXMgbWluaW1pemVkLiAgV2UgdHJ5IHRvIGRvIHRoaXMgd2hpbGUga2VlcGluZworLy8gZWFjaCBmaWVsZCBhcyBjbG9zZSBhcyBwb3NzaWJsZSB0byBpdHMgb3JpZ2luYWwgcG9zaXRpb24gc28gdGhhdCB3ZSBkb24ndAorLy8gcmVkdWNlIGNhY2hlIGxvY2FsaXR5IG11Y2ggZm9yIGZ1bmN0aW9uIHRoYXQgYWNjZXNzIGVhY2ggZmllbGQgaW4gb3JkZXIuCit2b2lkIE9wdGltaXplUGFkZGluZyh2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4qIGZpZWxkcykgeworICAvLyBGaXJzdCBkaXZpZGUgZmllbGRzIGludG8gdGhvc2UgdGhhdCBhbGlnbiB0byAxIGJ5dGUsIDQgYnl0ZXMgb3IgOCBieXRlcy4KKyAgdmVjdG9yPEZpZWxkR3JvdXA+IGFsaWduZWRfdG9fMSwgYWxpZ25lZF90b180LCBhbGlnbmVkX3RvXzg7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRzLT5zaXplKCk7ICsraSkgeworICAgIHN3aXRjaCAoRXN0aW1hdGVBbGlnbm1lbnRTaXplKCgqZmllbGRzKVtpXSkpIHsKKyAgICAgIGNhc2UgMTogYWxpZ25lZF90b18xLnB1c2hfYmFjayhGaWVsZEdyb3VwKGksICgqZmllbGRzKVtpXSkpOyBicmVhazsKKyAgICAgIGNhc2UgNDogYWxpZ25lZF90b180LnB1c2hfYmFjayhGaWVsZEdyb3VwKGksICgqZmllbGRzKVtpXSkpOyBicmVhazsKKyAgICAgIGNhc2UgODogYWxpZ25lZF90b184LnB1c2hfYmFjayhGaWVsZEdyb3VwKGksICgqZmllbGRzKVtpXSkpOyBicmVhazsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJVbmtub3duIGFsaWdubWVudCBzaXplLiI7CisgICAgfQorICB9CisKKyAgLy8gTm93IGdyb3VwIGZpZWxkcyBhbGlnbmVkIHRvIDEgYnl0ZSBpbnRvIHNldHMgb2YgNCwgYW5kIHRyZWF0IHRob3NlIGxpa2UgYQorICAvLyBzaW5nbGUgZmllbGQgYWxpZ25lZCB0byA0IGJ5dGVzLgorICBmb3IgKGludCBpID0gMDsgaSA8IGFsaWduZWRfdG9fMS5zaXplKCk7IGkgKz0gNCkgeworICAgIEZpZWxkR3JvdXAgZmllbGRfZ3JvdXA7CisgICAgZm9yIChpbnQgaiA9IGk7IGogPCBhbGlnbmVkX3RvXzEuc2l6ZSgpICYmIGogPCBpICsgNDsgKytqKSB7CisgICAgICBmaWVsZF9ncm91cC5BcHBlbmQoYWxpZ25lZF90b18xW2pdKTsKKyAgICB9CisgICAgYWxpZ25lZF90b180LnB1c2hfYmFjayhmaWVsZF9ncm91cCk7CisgIH0KKyAgLy8gU29ydCBieSBwcmVmZXJyZWQgbG9jYXRpb24gdG8ga2VlcCBmaWVsZHMgYXMgY2xvc2UgdG8gdGhlaXIgb3JpZ2luYWwKKyAgLy8gbG9jYXRpb24gYXMgcG9zc2libGUuICBVc2luZyBzdGFibGVfc29ydCBlbnN1cmVzIHRoYXQgdGhlIG91dHB1dCBpcworICAvLyBjb25zaXN0ZW50IGFjcm9zcyBydW5zLgorICBzdGQ6OnN0YWJsZV9zb3J0KGFsaWduZWRfdG9fNC5iZWdpbigpLCBhbGlnbmVkX3RvXzQuZW5kKCkpOworCisgIC8vIE5vdyBncm91cCBmaWVsZHMgYWxpZ25lZCB0byA0IGJ5dGVzIChvciB0aGUgNC1maWVsZCBncm91cHMgY3JlYXRlZCBhYm92ZSkKKyAgLy8gaW50byBwYWlycywgYW5kIHRyZWF0IHRob3NlIGxpa2UgYSBzaW5nbGUgZmllbGQgYWxpZ25lZCB0byA4IGJ5dGVzLgorICBmb3IgKGludCBpID0gMDsgaSA8IGFsaWduZWRfdG9fNC5zaXplKCk7IGkgKz0gMikgeworICAgIEZpZWxkR3JvdXAgZmllbGRfZ3JvdXA7CisgICAgZm9yIChpbnQgaiA9IGk7IGogPCBhbGlnbmVkX3RvXzQuc2l6ZSgpICYmIGogPCBpICsgMjsgKytqKSB7CisgICAgICBmaWVsZF9ncm91cC5BcHBlbmQoYWxpZ25lZF90b180W2pdKTsKKyAgICB9CisgICAgaWYgKGkgPT0gYWxpZ25lZF90b180LnNpemUoKSAtIDEpIHsKKyAgICAgIC8vIE1vdmUgaW5jb21wbGV0ZSA0LWJ5dGUgYmxvY2sgdG8gdGhlIGVuZC4KKyAgICAgIGZpZWxkX2dyb3VwLlNldFByZWZlcnJlZExvY2F0aW9uKGZpZWxkcy0+c2l6ZSgpICsgMSk7CisgICAgfQorICAgIGFsaWduZWRfdG9fOC5wdXNoX2JhY2soZmllbGRfZ3JvdXApOworICB9CisgIC8vIFNvcnQgYnkgcHJlZmVycmVkIGxvY2F0aW9uLgorICBzdGQ6OnN0YWJsZV9zb3J0KGFsaWduZWRfdG9fOC5iZWdpbigpLCBhbGlnbmVkX3RvXzguZW5kKCkpOworCisgIC8vIE5vdyBwdWxsIG91dCBhbGwgdGhlIEZpZWxkRGVzY3JpcHRvcnMgaW4gb3JkZXIuCisgIGZpZWxkcy0+Y2xlYXIoKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBhbGlnbmVkX3RvXzguc2l6ZSgpOyArK2kpIHsKKyAgICBmaWVsZHMtPmluc2VydChmaWVsZHMtPmVuZCgpLAorICAgICAgICAgICAgICAgICAgIGFsaWduZWRfdG9fOFtpXS5maWVsZHMoKS5iZWdpbigpLAorICAgICAgICAgICAgICAgICAgIGFsaWduZWRfdG9fOFtpXS5maWVsZHMoKS5lbmQoKSk7CisgIH0KK30KKworc3RyaW5nIE1lc3NhZ2VUeXBlUHJvdG9OYW1lKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgcmV0dXJuIGZpZWxkLT5tZXNzYWdlX3R5cGUoKS0+ZnVsbF9uYW1lKCk7Cit9CisKKy8vIEVtaXRzIGFuIGlmLXN0YXRlbWVudCB3aXRoIGEgY29uZGl0aW9uIHRoYXQgZXZhbHVhdGVzIHRvIHRydWUgaWYgfGZpZWxkfCBpcworLy8gY29uc2lkZXJlZCBub24tZGVmYXVsdCAod2lsbCBiZSBzZW50IG92ZXIgdGhlIHdpcmUpLCBmb3IgbWVzc2FnZSB0eXBlcworLy8gd2l0aG91dCB0cnVlIGZpZWxkIHByZXNlbmNlLiBTaG91bGQgb25seSBiZSBjYWxsZWQgaWYKKy8vICFIYXNGaWVsZFByZXNlbmNlKG1lc3NhZ2VfZGVzY3JpcHRvcikuCitib29sIEVtaXRGaWVsZE5vbkRlZmF1bHRDb25kaXRpb24oaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBwcmVmaXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICAvLyBNZXJnZSBhbmQgc2VyaWFsaXplIHNlbWFudGljczogcHJpbWl0aXZlIGZpZWxkcyBhcmUgbWVyZ2VkL3NlcmlhbGl6ZWQgb25seQorICAvLyBpZiBub24temVybyAobnVtZXJpYykgb3Igbm9uLWVtcHR5IChzdHJpbmcpLgorICBpZiAoIWZpZWxkLT5pc19yZXBlYXRlZCgpICYmICFmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpKSB7CisgICAgaWYgKGZpZWxkLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9TVFJJTkcpIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICJpZiAoJHByZWZpeCQkbmFtZSQoKS5zaXplKCkgPiAwKSB7XG4iLAorICAgICAgICAgICJwcmVmaXgiLCBwcmVmaXgsCisgICAgICAgICAgIm5hbWUiLCBGaWVsZE5hbWUoZmllbGQpKTsKKyAgICB9IGVsc2UgaWYgKGZpZWxkLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFKSB7CisgICAgICAvLyBNZXNzYWdlIGZpZWxkcyBzdGlsbCBoYXZlIGhhc18kbmFtZSQoKSBtZXRob2RzLgorICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgImlmICgkcHJlZml4JGhhc18kbmFtZSQoKSkge1xuIiwKKyAgICAgICAgICAicHJlZml4IiwgcHJlZml4LAorICAgICAgICAgICJuYW1lIiwgRmllbGROYW1lKGZpZWxkKSk7CisgICAgfSBlbHNlIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICJpZiAoJHByZWZpeCQkbmFtZSQoKSAhPSAwKSB7XG4iLAorICAgICAgICAgICJwcmVmaXgiLCBwcmVmaXgsCisgICAgICAgICAgIm5hbWUiLCBGaWVsZE5hbWUoZmllbGQpKTsKKyAgICB9CisgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgcmV0dXJuIHRydWU7CisgIH0gZWxzZSBpZiAoZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiaWYgKGhhc18kbmFtZSQoKSkge1xuIiwKKyAgICAgICAgIm5hbWUiLCBGaWVsZE5hbWUoZmllbGQpKTsKKyAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorICByZXR1cm4gZmFsc2U7Cit9CisKKy8vIERvZXMgdGhlIGdpdmVuIGZpZWxkIGhhdmUgYSBoYXNfJG5hbWUkKCkgbWV0aG9kPworYm9vbCBIYXNIYXNNZXRob2QoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICBpZiAoSGFzRmllbGRQcmVzZW5jZShmaWVsZC0+ZmlsZSgpKSkgeworICAgIC8vIEluIHByb3RvMS9wcm90bzIsIGV2ZXJ5IGZpZWxkIGhhcyBhIGhhc18kbmFtZSQoKSBtZXRob2QuCisgICAgcmV0dXJuIHRydWU7CisgIH0KKyAgLy8gRm9yIG1lc3NhZ2UgdHlwZXMgd2l0aG91dCB0cnVlIGZpZWxkIHByZXNlbmNlLCBvbmx5IGZpZWxkcyB3aXRoIGEgbWVzc2FnZQorICAvLyB0eXBlIGhhdmUgYSBoYXNfJG5hbWUkKCkgbWV0aG9kLgorICByZXR1cm4gZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U7Cit9CisKKy8vIENvbGxlY3RzIG1hcCBlbnRyeSBtZXNzYWdlIHR5cGUgaW5mb3JtYXRpb24uCit2b2lkIENvbGxlY3RNYXBJbmZvKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgIG1hcDxzdHJpbmcsIHN0cmluZz4qIHZhcmlhYmxlcykgeworICBHT09HTEVfQ0hFQ0soSXNNYXBFbnRyeU1lc3NhZ2UoZGVzY3JpcHRvcikpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGtleSA9IGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgia2V5Iik7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogdmFsID0gZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJ2YWx1ZSIpOworICAoKnZhcmlhYmxlcylbImtleSJdID0gUHJpbWl0aXZlVHlwZU5hbWUoa2V5LT5jcHBfdHlwZSgpKTsKKyAgc3dpdGNoICh2YWwtPmNwcF90eXBlKCkpIHsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgKCp2YXJpYWJsZXMpWyJ2YWwiXSA9IEZpZWxkTWVzc2FnZVR5cGVOYW1lKHZhbCk7CisgICAgICBicmVhazsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9FTlVNOgorICAgICAgKCp2YXJpYWJsZXMpWyJ2YWwiXSA9IENsYXNzTmFtZSh2YWwtPmVudW1fdHlwZSgpLCB0cnVlKTsKKyAgICAgIGJyZWFrOworICAgIGRlZmF1bHQ6CisgICAgICAoKnZhcmlhYmxlcylbInZhbCJdID0gUHJpbWl0aXZlVHlwZU5hbWUodmFsLT5jcHBfdHlwZSgpKTsKKyAgfQorICAoKnZhcmlhYmxlcylbImtleV93aXJlX3R5cGUiXSA9CisgICAgICAiOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfIiArCisgICAgICBUb1VwcGVyKERlY2xhcmVkVHlwZU1ldGhvZE5hbWUoa2V5LT50eXBlKCkpKTsKKyAgKCp2YXJpYWJsZXMpWyJ2YWxfd2lyZV90eXBlIl0gPQorICAgICAgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFXyIgKworICAgICAgVG9VcHBlcihEZWNsYXJlZFR5cGVNZXRob2ROYW1lKHZhbC0+dHlwZSgpKSk7Cit9CisKKy8vIERvZXMgdGhlIGdpdmVuIGZpZWxkIGhhdmUgYSBwcml2YXRlIChpbnRlcm5hbCBoZWxwZXIgb25seSkgaGFzXyRuYW1lJCgpCisvLyBtZXRob2Q/Citib29sIEhhc1ByaXZhdGVIYXNNZXRob2QoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICAvLyBPbmx5IGZvciBvbmVvZnMgaW4gbWVzc2FnZSB0eXBlcyB3aXRoIG5vIGZpZWxkIHByZXNlbmNlLiBoYXNfJG5hbWUkKCksCisgIC8vIGJhc2VkIG9uIHRoZSBvbmVvZiBjYXNlLCBpcyBzdGlsbCB1c2VmdWwgaW50ZXJuYWxseSBmb3IgZ2VuZXJhdGVkIGNvZGUuCisgIHJldHVybiAoIUhhc0ZpZWxkUHJlc2VuY2UoZmllbGQtPmZpbGUoKSkgJiYKKyAgICAgICAgICBmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpICE9IE5VTEwpOworfQorCit9ICAvLyBhbm9ueW1vdXMgbmFtZXNwYWNlCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworTWVzc2FnZUdlbmVyYXRvcjo6TWVzc2FnZUdlbmVyYXRvcihjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBPcHRpb25zJiBvcHRpb25zKQorICAgIDogZGVzY3JpcHRvcl8oZGVzY3JpcHRvciksCisgICAgICBjbGFzc25hbWVfKENsYXNzTmFtZShkZXNjcmlwdG9yLCBmYWxzZSkpLAorICAgICAgb3B0aW9uc18ob3B0aW9ucyksCisgICAgICBmaWVsZF9nZW5lcmF0b3JzXyhkZXNjcmlwdG9yLCBvcHRpb25zKSwKKyAgICAgIG5lc3RlZF9nZW5lcmF0b3JzXyhuZXcgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjwKKyAgICAgICAgICBNZXNzYWdlR2VuZXJhdG9yPltkZXNjcmlwdG9yLT5uZXN0ZWRfdHlwZV9jb3VudCgpXSksCisgICAgICBlbnVtX2dlbmVyYXRvcnNfKAorICAgICAgICAgIG5ldyBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPEVudW1HZW5lcmF0b3I+W2Rlc2NyaXB0b3ItPmVudW1fdHlwZV9jb3VudCgpXSksCisgICAgICBleHRlbnNpb25fZ2VuZXJhdG9yc18obmV3IGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8CisgICAgICAgICAgRXh0ZW5zaW9uR2VuZXJhdG9yPltkZXNjcmlwdG9yLT5leHRlbnNpb25fY291bnQoKV0pLAorICAgICAgdXNlX2RlcGVuZGVudF9iYXNlXyhmYWxzZSkgeworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvci0+bmVzdGVkX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgbmVzdGVkX2dlbmVyYXRvcnNfW2ldLnJlc2V0KAorICAgICAgbmV3IE1lc3NhZ2VHZW5lcmF0b3IoZGVzY3JpcHRvci0+bmVzdGVkX3R5cGUoaSksIG9wdGlvbnMpKTsKKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvci0+ZW51bV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIGVudW1fZ2VuZXJhdG9yc19baV0ucmVzZXQoCisgICAgICBuZXcgRW51bUdlbmVyYXRvcihkZXNjcmlwdG9yLT5lbnVtX3R5cGUoaSksIG9wdGlvbnMpKTsKKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvci0+ZXh0ZW5zaW9uX2NvdW50KCk7IGkrKykgeworICAgIGV4dGVuc2lvbl9nZW5lcmF0b3JzX1tpXS5yZXNldCgKKyAgICAgIG5ldyBFeHRlbnNpb25HZW5lcmF0b3IoZGVzY3JpcHRvci0+ZXh0ZW5zaW9uKGkpLCBvcHRpb25zKSk7CisgIH0KKworICBudW1fcmVxdWlyZWRfZmllbGRzXyA9IDA7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvci0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgaWYgKGRlc2NyaXB0b3ItPmZpZWxkKGkpLT5pc19yZXF1aXJlZCgpKSB7CisgICAgICArK251bV9yZXF1aXJlZF9maWVsZHNfOworICAgIH0KKyAgICBpZiAob3B0aW9ucy5wcm90b19oICYmIElzRmllbGREZXBlbmRlbnQoZGVzY3JpcHRvci0+ZmllbGQoaSkpKSB7CisgICAgICB1c2VfZGVwZW5kZW50X2Jhc2VfID0gdHJ1ZTsKKyAgICB9CisgIH0KKyAgaWYgKG9wdGlvbnMucHJvdG9faCAmJiBkZXNjcmlwdG9yLT5vbmVvZl9kZWNsX2NvdW50KCkgPiAwKSB7CisgICAgLy8gQWx3YXlzIG1ha2Ugb25lb2ZzIGRlcGVuZGVudC4KKyAgICB1c2VfZGVwZW5kZW50X2Jhc2VfID0gdHJ1ZTsKKyAgfQorfQorCitNZXNzYWdlR2VuZXJhdG9yOjp+TWVzc2FnZUdlbmVyYXRvcigpIHt9CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6CitGaWxsTWVzc2FnZUZvcndhcmREZWNsYXJhdGlvbnMoc2V0PHN0cmluZz4qIGNsYXNzX25hbWVzKSB7CisgIGNsYXNzX25hbWVzLT5pbnNlcnQoY2xhc3NuYW1lXyk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+bmVzdGVkX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgLy8gbWFwIGVudHJ5IG1lc3NhZ2UgZG9lc24ndCBuZWVkIGZvcndhcmQgZGVjbGFyYXRpb24uIFNpbmNlIG1hcCBlbnRyeQorICAgIC8vIG1lc3NhZ2UgY2Fubm90IGJlIGEgdG9wIGxldmVsIGNsYXNzLCB3ZSBqdXN0IG5lZWQgdG8gYXZvaWQgY2FsbGluZworICAgIC8vIEdlbmVyYXRlRm9yd2FyZERlY2xhcmF0aW9uIGhlcmUuCisgICAgaWYgKElzTWFwRW50cnlNZXNzYWdlKGRlc2NyaXB0b3JfLT5uZXN0ZWRfdHlwZShpKSkpIGNvbnRpbnVlOworICAgIG5lc3RlZF9nZW5lcmF0b3JzX1tpXS0+RmlsbE1lc3NhZ2VGb3J3YXJkRGVjbGFyYXRpb25zKGNsYXNzX25hbWVzKTsKKyAgfQorfQorCit2b2lkIE1lc3NhZ2VHZW5lcmF0b3I6OgorRmlsbEVudW1Gb3J3YXJkRGVjbGFyYXRpb25zKHNldDxzdHJpbmc+KiBlbnVtX25hbWVzKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlX2NvdW50KCk7IGkrKykgeworICAgIG5lc3RlZF9nZW5lcmF0b3JzX1tpXS0+RmlsbEVudW1Gb3J3YXJkRGVjbGFyYXRpb25zKGVudW1fbmFtZXMpOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmVudW1fdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBlbnVtX2dlbmVyYXRvcnNfW2ldLT5GaWxsRm9yd2FyZERlY2xhcmF0aW9uKGVudW1fbmFtZXMpOworICB9Cit9CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUVudW1EZWZpbml0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5uZXN0ZWRfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBuZXN0ZWRfZ2VuZXJhdG9yc19baV0tPkdlbmVyYXRlRW51bURlZmluaXRpb25zKHByaW50ZXIpOworICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZW51bV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIGVudW1fZ2VuZXJhdG9yc19baV0tPkdlbmVyYXRlRGVmaW5pdGlvbihwcmludGVyKTsKKyAgfQorfQorCit2b2lkIE1lc3NhZ2VHZW5lcmF0b3I6OgorR2VuZXJhdGVHZXRFbnVtRGVzY3JpcHRvclNwZWNpYWxpemF0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5uZXN0ZWRfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBuZXN0ZWRfZ2VuZXJhdG9yc19baV0tPkdlbmVyYXRlR2V0RW51bURlc2NyaXB0b3JTcGVjaWFsaXphdGlvbnMocHJpbnRlcik7CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZW51bV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIGVudW1fZ2VuZXJhdG9yc19baV0tPkdlbmVyYXRlR2V0RW51bURlc2NyaXB0b3JTcGVjaWFsaXphdGlvbnMocHJpbnRlcik7CisgIH0KK30KKwordm9pZCBNZXNzYWdlR2VuZXJhdG9yOjoKK0dlbmVyYXRlRGVwZW5kZW50RmllbGRBY2Nlc3NvckRlY2xhcmF0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvcl8tPmZpZWxkKGkpOworCisgICAgUHJpbnRGaWVsZENvbW1lbnQocHJpbnRlciwgZmllbGQpOworCisgICAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJzOworICAgIFNldENvbW1vbkZpZWxkVmFyaWFibGVzKGZpZWxkLCAmdmFycywgb3B0aW9uc18pOworCisgICAgaWYgKHVzZV9kZXBlbmRlbnRfYmFzZV8gJiYgSXNGaWVsZERlcGVuZGVudChmaWVsZCkpIHsKKyAgICAgIC8vIElmIHRoZSBtZXNzYWdlIGlzIGRlcGVuZGVudCwgdGhlIGlubGluZSBjbGVhcl8qKCkgbWV0aG9kIHdpbGwgbmVlZAorICAgICAgLy8gdG8gZGVsZXRlIHRoZSBtZXNzYWdlIHR5cGUsIHNvIGl0IG11c3QgYmUgaW4gdGhlIGRlcGVuZGVudCBiYXNlCisgICAgICAvLyBjbGFzcy4gKFNlZSBhbHNvIEdlbmVyYXRlRmllbGRBY2Nlc3NvckRlY2xhcmF0aW9ucy4pCisgICAgICBwcmludGVyLT5QcmludCh2YXJzLCAidm9pZCBjbGVhcl8kbmFtZSQoKSRkZXByZWNhdGlvbiQ7XG4iKTsKKyAgICB9CisgICAgLy8gR2VuZXJhdGUgdHlwZS1zcGVjaWZpYyBhY2Nlc3NvciBkZWNsYXJhdGlvbnMuCisgICAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGZpZWxkKS5HZW5lcmF0ZURlcGVuZGVudEFjY2Vzc29yRGVjbGFyYXRpb25zKHByaW50ZXIpOworICAgIHByaW50ZXItPlByaW50KCJcbiIpOworICB9Cit9CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUZpZWxkQWNjZXNzb3JEZWNsYXJhdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3JfLT5maWVsZChpKTsKKworICAgIFByaW50RmllbGRDb21tZW50KHByaW50ZXIsIGZpZWxkKTsKKworICAgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyczsKKyAgICBTZXRDb21tb25GaWVsZFZhcmlhYmxlcyhmaWVsZCwgJnZhcnMsIG9wdGlvbnNfKTsKKyAgICB2YXJzWyJjb25zdGFudF9uYW1lIl0gPSBGaWVsZENvbnN0YW50TmFtZShmaWVsZCk7CisKKyAgICBib29sIGRlcGVuZGVudF9maWVsZCA9IHVzZV9kZXBlbmRlbnRfYmFzZV8gJiYgSXNGaWVsZERlcGVuZGVudChmaWVsZCk7CisgICAgaWYgKGRlcGVuZGVudF9maWVsZCAmJgorICAgICAgICBmaWVsZC0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSAmJgorICAgICAgICAhZmllbGQtPmlzX21hcCgpKSB7CisgICAgICAvLyBJZiB0aGlzIGZpZWxkIGlzIGRlcGVuZGVudCwgdGhlIGRlcGVuZGVudCBiYXNlIGNsYXNzIGRldGVybWluZXMKKyAgICAgIC8vIHRoZSBtZXNzYWdlIHR5cGUgZnJvbSB0aGUgZGVyaXZlZCBjbGFzcyAod2hpY2ggaXMgYSB0ZW1wbGF0ZQorICAgICAgLy8gcGFyYW1ldGVyKS4gVGhpcyB0eXBlZGVmIGlzIGZvciB0aGF0OgorICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgInByaXZhdGU6XG4iCisgICAgICAgICAgInR5cGVkZWYgJGZpZWxkX3R5cGUkICRkZXBlbmRlbnRfdHlwZSQ7XG4iCisgICAgICAgICAgInB1YmxpYzpcbiIsCisgICAgICAgICAgImZpZWxkX3R5cGUiLCBGaWVsZE1lc3NhZ2VUeXBlTmFtZShmaWVsZCksCisgICAgICAgICAgImRlcGVuZGVudF90eXBlIiwgRGVwZW5kZW50VHlwZU5hbWUoZmllbGQpKTsKKyAgICB9CisKKyAgICBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkpIHsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcnMsICJpbnQgJG5hbWUkX3NpemUoKSBjb25zdCRkZXByZWNhdGlvbiQ7XG4iKTsKKyAgICB9IGVsc2UgaWYgKEhhc0hhc01ldGhvZChmaWVsZCkpIHsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcnMsICJib29sIGhhc18kbmFtZSQoKSBjb25zdCRkZXByZWNhdGlvbiQ7XG4iKTsKKyAgICB9IGVsc2UgaWYgKEhhc1ByaXZhdGVIYXNNZXRob2QoZmllbGQpKSB7CisgICAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgICAgICJwcml2YXRlOlxuIgorICAgICAgICAgICJib29sIGhhc18kbmFtZSQoKSBjb25zdCRkZXByZWNhdGlvbiQ7XG4iCisgICAgICAgICAgInB1YmxpYzpcbiIpOworICAgIH0KKworICAgIGlmICghZGVwZW5kZW50X2ZpZWxkKSB7CisgICAgICAvLyBJZiB0aGlzIGZpZWxkIGlzIGRlcGVuZGVudCwgdGhlbiBpdHMgY2xlYXJfKCkgbWV0aG9kIGlzIGluIHRoZQorICAgICAgLy8gZGVwZW5lbnQgYmFzZSBjbGFzcy4gKFNlZSBhbHNvIEdlbmVyYXRlRGVwZW5kZW50QWNjZXNzb3JEZWNsYXJhdGlvbnMuKQorICAgICAgcHJpbnRlci0+UHJpbnQodmFycywgInZvaWQgY2xlYXJfJG5hbWUkKCkkZGVwcmVjYXRpb24kO1xuIik7CisgICAgfQorICAgIHByaW50ZXItPlByaW50KHZhcnMsICJzdGF0aWMgY29uc3QgaW50ICRjb25zdGFudF9uYW1lJCA9ICRudW1iZXIkO1xuIik7CisKKyAgICAvLyBHZW5lcmF0ZSB0eXBlLXNwZWNpZmljIGFjY2Vzc29yIGRlY2xhcmF0aW9ucy4KKyAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZmllbGQpLkdlbmVyYXRlQWNjZXNzb3JEZWNsYXJhdGlvbnMocHJpbnRlcik7CisKKyAgICBwcmludGVyLT5QcmludCgiXG4iKTsKKyAgfQorCisgIGlmIChkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCkgPiAwKSB7CisgICAgLy8gR2VuZXJhdGUgYWNjZXNzb3JzIGZvciBleHRlbnNpb25zLiAgV2UganVzdCBjYWxsIGEgbWFjcm8gbG9jYXRlZCBpbgorICAgIC8vIGV4dGVuc2lvbl9zZXQuaCBzaW5jZSB0aGUgYWNjZXNzb3JzIGFib3V0IDgwIGxpbmVzIG9mIHN0YXRpYyBjb2RlLgorICAgIHByaW50ZXItPlByaW50KAorICAgICAgIkdPT0dMRV9QUk9UT0JVRl9FWFRFTlNJT05fQUNDRVNTT1JTKCRjbGFzc25hbWUkKVxuIiwKKyAgICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfKTsKKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2xfY291bnQoKTsgaSsrKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICIkY2FtZWxfb25lb2ZfbmFtZSRDYXNlICRvbmVvZl9uYW1lJF9jYXNlKCkgY29uc3Q7XG4iLAorICAgICAgICAiY2FtZWxfb25lb2ZfbmFtZSIsCisgICAgICAgIFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPm5hbWUoKSwgdHJ1ZSksCisgICAgICAgICJvbmVvZl9uYW1lIiwgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPm5hbWUoKSk7CisgIH0KK30KKwordm9pZCBNZXNzYWdlR2VuZXJhdG9yOjoKK0dlbmVyYXRlRGVwZW5kZW50RmllbGRBY2Nlc3NvckRlZmluaXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIGlmICghdXNlX2RlcGVuZGVudF9iYXNlXykgcmV0dXJuOworCisgIHByaW50ZXItPlByaW50KCIvLyAkY2xhc3NuYW1lJFxuXG4iLCAiY2xhc3NuYW1lIiwKKyAgICAgICAgICAgICAgICAgRGVwZW5kZW50QmFzZUNsYXNzVGVtcGxhdGVOYW1lKGRlc2NyaXB0b3JfKSk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3JfLT5maWVsZChpKTsKKworICAgIFByaW50RmllbGRDb21tZW50KHByaW50ZXIsIGZpZWxkKTsKKworICAgIC8vIFRoZXNlIGZ1bmN0aW9ucyBhcmUgbm90IHJlYWxseSBkZXBlbmRlbnQ6IHRoZXkgYXJlIHBhcnQgb2YgdGhlCisgICAgLy8gKG5vbi1kZXBlbmRlbnQpIGRlcml2ZWQgY2xhc3MuIEhvd2V2ZXIsIHRoZXkgbmVlZCB0byBsaXZlIG91dHNpZGUKKyAgICAvLyBhbnkgI2lmZGVmIGd1YXJkcywgc28gd2UgdHJlYXQgdGhlbSBhcyBpZiB0aGV5IHdlcmUgZGVwZW5kZW50LgorICAgIC8vCisgICAgLy8gU2VlIHRoZSBjb21tZW50IGluIEZpbGVHZW5lcmF0b3I6OkdlbmVyYXRlSW5saW5lRnVuY3Rpb25EZWZpbml0aW9ucworICAgIC8vIGZvciBhIG1vcmUgY29tcGxldGUgZXhwbGFuYXRpb24uCisgICAgaWYgKHVzZV9kZXBlbmRlbnRfYmFzZV8gJiYgSXNGaWVsZERlcGVuZGVudChmaWVsZCkpIHsKKyAgICAgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyczsKKyAgICAgIFNldENvbW1vbkZpZWxkVmFyaWFibGVzKGZpZWxkLCAmdmFycywgb3B0aW9uc18pOworICAgICAgdmFyc1siaW5saW5lIl0gPSAiaW5saW5lICI7CisgICAgICBpZiAoZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSkgeworICAgICAgICB2YXJzWyJmaWVsZF9uYW1lIl0gPSBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlKGZpZWxkLT5uYW1lKCksIHRydWUpOworICAgICAgICB2YXJzWyJvbmVvZl9uYW1lIl0gPSBmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpLT5uYW1lKCk7CisgICAgICAgIHZhcnNbIm9uZW9mX2luZGV4Il0gPSBTaW1wbGVJdG9hKGZpZWxkLT5jb250YWluaW5nX29uZW9mKCktPmluZGV4KCkpOworICAgICAgICBHZW5lcmF0ZU9uZW9mTWVtYmVySGFzQml0cyhmaWVsZCwgdmFycywgcHJpbnRlcik7CisgICAgICB9IGVsc2UgaWYgKCFmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgeworICAgICAgICAvLyBUaGVyZSB3aWxsIGJlIG5vIGhlYWRlciBndWFyZCwgc28gdGhpcyBhbHdheXMgaGFzIHRvIGJlIGlubGluZS4KKyAgICAgICAgR2VuZXJhdGVTaW5ndWxhckZpZWxkSGFzQml0cyhmaWVsZCwgdmFycywgcHJpbnRlcik7CisgICAgICB9CisgICAgICAvLyB2YXJzIG5lZWRlZCBmb3IgY2xlYXJfKCksIHdoaWNoIGlzIGluIHRoZSBkZXBlbmRlbnQgYmFzZToKKyAgICAgIC8vIChTZWUgYWxzbyBHZW5lcmF0ZURlcGVuZGVudEZpZWxkQWNjZXNzb3JEZWNsYXJhdGlvbnMuKQorICAgICAgdmFyc1sidG1wbCJdID0gInRlbXBsYXRlPGNsYXNzIFQ+XG4iOworICAgICAgdmFyc1siZGVwZW5kZW50X2NsYXNzbmFtZSJdID0KKyAgICAgICAgICBEZXBlbmRlbnRCYXNlQ2xhc3NUZW1wbGF0ZU5hbWUoZGVzY3JpcHRvcl8pICsgIjxUPiI7CisgICAgICB2YXJzWyJ0aGlzX21lc3NhZ2UiXSA9IERlcGVuZGVudEJhc2VEb3duQ2FzdCgpOworICAgICAgdmFyc1sidGhpc19jb25zdF9tZXNzYWdlIl0gPSBEZXBlbmRlbnRCYXNlQ29uc3REb3duQ2FzdCgpOworICAgICAgR2VuZXJhdGVGaWVsZENsZWFyKGZpZWxkLCB2YXJzLCBwcmludGVyKTsKKyAgICB9CisKKyAgICAvLyBHZW5lcmF0ZSB0eXBlLXNwZWNpZmljIGFjY2Vzc29ycy4KKyAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZmllbGQpCisgICAgICAgIC5HZW5lcmF0ZURlcGVuZGVudElubGluZUFjY2Vzc29yRGVmaW5pdGlvbnMocHJpbnRlcik7CisKKyAgICBwcmludGVyLT5QcmludCgiXG4iKTsKKyAgfQorCisgIC8vIEdlbmVyYXRlIGhhc18kbmFtZSQoKSBhbmQgY2xlYXJfaGFzXyRuYW1lJCgpIGZ1bmN0aW9ucyBmb3Igb25lb2ZzCisgIC8vIFNpbWlsYXIgdG8gb3RoZXIgaGFzLWJpdHMsIHRoZXNlIG11c3QgYWx3YXlzIGJlIGluIHRoZSBoZWFkZXIgaWYgd2UKKyAgLy8gYXJlIHVzaW5nIGEgZGVwZW5kZW50IGJhc2UgY2xhc3MuCisgIEdlbmVyYXRlT25lb2ZIYXNCaXRzKHByaW50ZXIsIHRydWUgLyogaXNfaW5saW5lICovKTsKK30KKwordm9pZCBNZXNzYWdlR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2luZ3VsYXJGaWVsZEhhc0JpdHMoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBpZiAoSGFzRmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIC8vIE4uQi46IHdpdGhvdXQgZmllbGQgcHJlc2VuY2UsIHdlIGRvIG5vdCB1c2UgaGFzLWJpdHMgb3IgZ2VuZXJhdGUKKyAgICAvLyBoYXNfJG5hbWUkKCkgbWV0aG9kcy4KKyAgICB2YXJzWyJoYXNfYXJyYXlfaW5kZXgiXSA9IFNpbXBsZUl0b2EoZmllbGQtPmluZGV4KCkgLyAzMik7CisgICAgdmFyc1siaGFzX21hc2siXSA9IFN0ckNhdChzdHJpbmdzOjpIZXgoMXUgPDwgKGZpZWxkLT5pbmRleCgpICUgMzIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ3M6OlpFUk9fUEFEXzgpKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgIiRpbmxpbmUkIgorICAgICAgImJvb2wgJGNsYXNzbmFtZSQ6Omhhc18kbmFtZSQoKSBjb25zdCB7XG4iCisgICAgICAiICByZXR1cm4gKF9oYXNfYml0c19bJGhhc19hcnJheV9pbmRleCRdICYgMHgkaGFzX21hc2skdSkgIT0gMDtcbiIKKyAgICAgICJ9XG4iCisgICAgICAiJGlubGluZSQiCisgICAgICAidm9pZCAkY2xhc3NuYW1lJDo6c2V0X2hhc18kbmFtZSQoKSB7XG4iCisgICAgICAiICBfaGFzX2JpdHNfWyRoYXNfYXJyYXlfaW5kZXgkXSB8PSAweCRoYXNfbWFzayR1O1xuIgorICAgICAgIn1cbiIKKyAgICAgICIkaW5saW5lJCIKKyAgICAgICJ2b2lkICRjbGFzc25hbWUkOjpjbGVhcl9oYXNfJG5hbWUkKCkge1xuIgorICAgICAgIiAgX2hhc19iaXRzX1skaGFzX2FycmF5X2luZGV4JF0gJj0gfjB4JGhhc19tYXNrJHU7XG4iCisgICAgICAifVxuIik7CisgIH0gZWxzZSB7CisgICAgLy8gTWVzc2FnZSBmaWVsZHMgaGF2ZSBhIGhhc18kbmFtZSQoKSBtZXRob2QuCisgICAgaWYgKGZpZWxkLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFKSB7CisgICAgICBib29sIGlzX2xhenkgPSBmYWxzZTsKKyAgICAgIGlmIChpc19sYXp5KSB7CisgICAgICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAgICAgIiRpbmxpbmUkIgorICAgICAgICAgICJib29sICRjbGFzc25hbWUkOjpoYXNfJG5hbWUkKCkgY29uc3Qge1xuIgorICAgICAgICAgICIgIHJldHVybiAhJG5hbWUkXy5Jc0NsZWFyZWQoKTtcbiIKKyAgICAgICAgICAifVxuIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgICAgICIkaW5saW5lJCIKKyAgICAgICAgICAiYm9vbCAkY2xhc3NuYW1lJDo6aGFzXyRuYW1lJCgpIGNvbnN0IHtcbiIKKyAgICAgICAgICAiICByZXR1cm4gIV9pc19kZWZhdWx0X2luc3RhbmNlXyAmJiAkbmFtZSRfICE9IE5VTEw7XG4iCisgICAgICAgICAgIn1cbiIpOworICAgICAgfQorICAgIH0KKyAgfQorfQorCit2b2lkIE1lc3NhZ2VHZW5lcmF0b3I6OgorR2VuZXJhdGVPbmVvZkhhc0JpdHMoaW86OlByaW50ZXIqIHByaW50ZXIsIGJvb2wgaXNfaW5saW5lKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2xfY291bnQoKTsgaSsrKSB7CisgICAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJzOworICAgIHZhcnNbIm9uZW9mX25hbWUiXSA9IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5uYW1lKCk7CisgICAgdmFyc1sib25lb2ZfaW5kZXgiXSA9IFNpbXBsZUl0b2EoZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPmluZGV4KCkpOworICAgIHZhcnNbImNhcF9vbmVvZl9uYW1lIl0gPQorICAgICAgICBUb1VwcGVyKGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5uYW1lKCkpOworICAgIHZhcnNbImNsYXNzbmFtZSJdID0gY2xhc3NuYW1lXzsKKyAgICB2YXJzWyJpbmxpbmUiXSA9IChpc19pbmxpbmUgPyAiaW5saW5lICIgOiAiIik7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgIHZhcnMsCisgICAgICAgICIkaW5saW5lJCIKKyAgICAgICAgImJvb2wgJGNsYXNzbmFtZSQ6Omhhc18kb25lb2ZfbmFtZSQoKSBjb25zdCB7XG4iCisgICAgICAgICIgIHJldHVybiAkb25lb2ZfbmFtZSRfY2FzZSgpICE9ICRjYXBfb25lb2ZfbmFtZSRfTk9UX1NFVDtcbiIKKyAgICAgICAgIn1cbiIKKyAgICAgICAgIiRpbmxpbmUkIgorICAgICAgICAidm9pZCAkY2xhc3NuYW1lJDo6Y2xlYXJfaGFzXyRvbmVvZl9uYW1lJCgpIHtcbiIKKyAgICAgICAgIiAgX29uZW9mX2Nhc2VfWyRvbmVvZl9pbmRleCRdID0gJGNhcF9vbmVvZl9uYW1lJF9OT1RfU0VUO1xuIgorICAgICAgICAifVxuIik7CisgIH0KK30KKwordm9pZCBNZXNzYWdlR2VuZXJhdG9yOjoKK0dlbmVyYXRlT25lb2ZNZW1iZXJIYXNCaXRzKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtYXA8c3RyaW5nLCBzdHJpbmc+JiB2YXJzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgLy8gU2luZ3VsYXIgZmllbGQgaW4gYSBvbmVvZgorICAvLyBOLkIuOiBXaXRob3V0IGZpZWxkIHByZXNlbmNlLCB3ZSBkbyBub3QgdXNlIGhhcy1iaXRzIG9yIGdlbmVyYXRlCisgIC8vIGhhc18kbmFtZSQoKSBtZXRob2RzLCBidXQgb25lb2ZzIHN0aWxsIGhhdmUgc2V0X2hhc18kbmFtZSQoKS4KKyAgLy8gT25lb2ZzIGFsc28gaGF2ZSBoYXNfJG5hbWUkKCkgYnV0IG9ubHkgYXMgYSBwcml2YXRlIGhlbHBlcgorICAvLyBtZXRob2QsIHNvIHRoYXQgZ2VuZXJhdGVkIGNvZGUgaXMgc2xpZ2h0bHkgY2xlYW5lciAodnMuICBjb21wYXJpbmcKKyAgLy8gX29uZW9mX2Nhc2VfW2luZGV4XSBhZ2FpbnN0IGEgY29uc3RhbnQgZXZlcnl3aGVyZSkuCisgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgIiRpbmxpbmUkIgorICAgICJib29sICRjbGFzc25hbWUkOjpoYXNfJG5hbWUkKCkgY29uc3Qge1xuIgorICAgICIgIHJldHVybiAkb25lb2ZfbmFtZSRfY2FzZSgpID09IGskZmllbGRfbmFtZSQ7XG4iCisgICAgIn1cbiIpOworICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICIkaW5saW5lJCIKKyAgICAidm9pZCAkY2xhc3NuYW1lJDo6c2V0X2hhc18kbmFtZSQoKSB7XG4iCisgICAgIiAgX29uZW9mX2Nhc2VfWyRvbmVvZl9pbmRleCRdID0gayRmaWVsZF9uYW1lJDtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUZpZWxkQ2xlYXIoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICBjb25zdCBtYXA8c3RyaW5nLCBzdHJpbmc+JiB2YXJzLAorICAgICAgICAgICAgICAgICAgIGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIC8vIEdlbmVyYXRlIGNsZWFyXyRuYW1lJCgpIChTZWUgR2VuZXJhdGVGaWVsZEFjY2Vzc29yRGVjbGFyYXRpb25zIGFuZAorICAvLyBHZW5lcmF0ZURlcGVuZGVudEZpZWxkQWNjZXNzb3JEZWNsYXJhdGlvbnMsICRkZXBlbmRlbnRfY2xhc3NuYW1lJCBpcworICAvLyBzZXQgYnkgdGhlIEdlbmVyYXRlKkRlZmluaXRpb25zIGZ1bmN0aW9ucy4pCisgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgIiR0bXBsJCIKKyAgICAiJGlubGluZSQiCisgICAgInZvaWQgJGRlcGVuZGVudF9jbGFzc25hbWUkOjpjbGVhcl8kbmFtZSQoKSB7XG4iKTsKKworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBpZiAoZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSkgeworICAgIC8vIENsZWFyIHRoaXMgZmllbGQgb25seSBpZiBpdCBpcyB0aGUgYWN0aXZlIGZpZWxkIGluIHRoaXMgb25lb2YsCisgICAgLy8gb3RoZXJ3aXNlIGlnbm9yZQorICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAiaWYgKCR0aGlzX21lc3NhZ2UkaGFzXyRuYW1lJCgpKSB7XG4iKTsKKyAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZmllbGQpCisgICAgICAgIC5HZW5lcmF0ZUNsZWFyaW5nQ29kZShwcmludGVyKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgIiR0aGlzX21lc3NhZ2UkY2xlYXJfaGFzXyRvbmVvZl9uYW1lJCgpO1xuIik7CisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIHByaW50ZXItPlByaW50KCJ9XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZmllbGQpCisgICAgICAgIC5HZW5lcmF0ZUNsZWFyaW5nQ29kZShwcmludGVyKTsKKyAgICBpZiAoSGFzRmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgICAgaWYgKCFmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgeworICAgICAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgICAgICAgICAgICAgICAgICAiJHRoaXNfbWVzc2FnZSRjbGVhcl9oYXNfJG5hbWUkKCk7XG4iKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KCJ9XG4iKTsKK30KKwordm9pZCBNZXNzYWdlR2VuZXJhdG9yOjoKK0dlbmVyYXRlRmllbGRBY2Nlc3NvckRlZmluaXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyLCBib29sIGlzX2lubGluZSkgeworICBwcmludGVyLT5QcmludCgiLy8gJGNsYXNzbmFtZSRcblxuIiwgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8pOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBkZXNjcmlwdG9yXy0+ZmllbGQoaSk7CisKKyAgICBQcmludEZpZWxkQ29tbWVudChwcmludGVyLCBmaWVsZCk7CisKKyAgICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcnM7CisgICAgU2V0Q29tbW9uRmllbGRWYXJpYWJsZXMoZmllbGQsICZ2YXJzLCBvcHRpb25zXyk7CisgICAgdmFyc1siaW5saW5lIl0gPSBpc19pbmxpbmUgPyAiaW5saW5lICIgOiAiIjsKKyAgICBpZiAodXNlX2RlcGVuZGVudF9iYXNlXyAmJiBJc0ZpZWxkRGVwZW5kZW50KGZpZWxkKSkgeworICAgICAgdmFyc1sidG1wbCJdID0gInRlbXBsYXRlPGNsYXNzIFQ+XG4iOworICAgICAgdmFyc1siZGVwZW5kZW50X2NsYXNzbmFtZSJdID0KKyAgICAgICAgICBEZXBlbmRlbnRCYXNlQ2xhc3NUZW1wbGF0ZU5hbWUoZGVzY3JpcHRvcl8pICsgIjxUPiI7CisgICAgICB2YXJzWyJ0aGlzX21lc3NhZ2UiXSA9ICJyZWludGVycHJldF9jYXN0PFQqPih0aGlzKS0+IjsKKyAgICAgIHZhcnNbInRoaXNfY29uc3RfbWVzc2FnZSJdID0gInJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgVCo+KHRoaXMpLT4iOworICAgIH0gZWxzZSB7CisgICAgICB2YXJzWyJ0bXBsIl0gPSAiIjsKKyAgICAgIHZhcnNbImRlcGVuZGVudF9jbGFzc25hbWUiXSA9IHZhcnNbImNsYXNzbmFtZSJdOworICAgICAgdmFyc1sidGhpc19tZXNzYWdlIl0gPSAiIjsKKyAgICAgIHZhcnNbInRoaXNfY29uc3RfbWVzc2FnZSJdID0gIiI7CisgICAgfQorCisgICAgLy8gR2VuZXJhdGUgaGFzXyRuYW1lJCgpIG9yICRuYW1lJF9zaXplKCkuCisgICAgaWYgKGZpZWxkLT5pc19yZXBlYXRlZCgpKSB7CisgICAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgICAiJGlubGluZSQiCisgICAgICAgICJpbnQgJGNsYXNzbmFtZSQ6OiRuYW1lJF9zaXplKCkgY29uc3Qge1xuIgorICAgICAgICAiICByZXR1cm4gJG5hbWUkXy5zaXplKCk7XG4iCisgICAgICAgICJ9XG4iKTsKKyAgICB9IGVsc2UgaWYgKGZpZWxkLT5jb250YWluaW5nX29uZW9mKCkpIHsKKyAgICAgIHZhcnNbImZpZWxkX25hbWUiXSA9IFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoZmllbGQtPm5hbWUoKSwgdHJ1ZSk7CisgICAgICB2YXJzWyJvbmVvZl9uYW1lIl0gPSBmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpLT5uYW1lKCk7CisgICAgICB2YXJzWyJvbmVvZl9pbmRleCJdID0gU2ltcGxlSXRvYShmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpLT5pbmRleCgpKTsKKyAgICAgIGlmICghdXNlX2RlcGVuZGVudF9iYXNlXyB8fCAhSXNGaWVsZERlcGVuZGVudChmaWVsZCkpIHsKKyAgICAgICAgR2VuZXJhdGVPbmVvZk1lbWJlckhhc0JpdHMoZmllbGQsIHZhcnMsIHByaW50ZXIpOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICAvLyBTaW5ndWxhciBmaWVsZC4KKyAgICAgIGlmICghdXNlX2RlcGVuZGVudF9iYXNlXyB8fCAhSXNGaWVsZERlcGVuZGVudChmaWVsZCkpIHsKKyAgICAgICAgR2VuZXJhdGVTaW5ndWxhckZpZWxkSGFzQml0cyhmaWVsZCwgdmFycywgcHJpbnRlcik7CisgICAgICB9CisgICAgfQorCisgICAgaWYgKCF1c2VfZGVwZW5kZW50X2Jhc2VfIHx8ICFJc0ZpZWxkRGVwZW5kZW50KGZpZWxkKSkgeworICAgICAgR2VuZXJhdGVGaWVsZENsZWFyKGZpZWxkLCB2YXJzLCBwcmludGVyKTsKKyAgICB9CisKKyAgICAvLyBHZW5lcmF0ZSB0eXBlLXNwZWNpZmljIGFjY2Vzc29ycy4KKyAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZmllbGQpLkdlbmVyYXRlSW5saW5lQWNjZXNzb3JEZWZpbml0aW9ucyhwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzX2lubGluZSk7CisKKyAgICBwcmludGVyLT5QcmludCgiXG4iKTsKKyAgfQorCisgIGlmICghdXNlX2RlcGVuZGVudF9iYXNlXykgeworICAgIC8vIEdlbmVyYXRlIGhhc18kbmFtZSQoKSBhbmQgY2xlYXJfaGFzXyRuYW1lJCgpIGZ1bmN0aW9ucyBmb3Igb25lb2ZzCisgICAgLy8gSWYgd2UgYXJlbid0IHVzaW5nIGEgZGVwZW5kZW50IGJhc2UsIHRoZXkgY2FuIGJlIHdpdGggdGhlIG90aGVyIGZ1bmN0aW9ucworICAgIC8vIHRoYXQgYXJlICNpZmRlZi1ndWFyZGVkLgorICAgIEdlbmVyYXRlT25lb2ZIYXNCaXRzKHByaW50ZXIsIGlzX2lubGluZSk7CisgIH0KK30KKworLy8gSGVscGVyIGZvciB0aGUgY29kZSB0aGF0IGVtaXRzIHRoZSBDbGVhcigpIG1ldGhvZC4KK3N0YXRpYyBib29sIENhbkNsZWFyQnlaZXJvaW5nKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgaWYgKGZpZWxkLT5pc19yZXBlYXRlZCgpIHx8IGZpZWxkLT5pc19leHRlbnNpb24oKSkgcmV0dXJuIGZhbHNlOworICBzd2l0Y2ggKGZpZWxkLT5jcHBfdHlwZSgpKSB7CisgICAgY2FzZSBpbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfRU5VTToKKyAgICAgIHJldHVybiBmaWVsZC0+ZGVmYXVsdF92YWx1ZV9lbnVtKCktPm51bWJlcigpID09IDA7CisgICAgY2FzZSBpbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfSU5UMzI6CisgICAgICByZXR1cm4gZmllbGQtPmRlZmF1bHRfdmFsdWVfaW50MzIoKSA9PSAwOworICAgIGNhc2UgaW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpDUFBUWVBFX0lOVDY0OgorICAgICAgcmV0dXJuIGZpZWxkLT5kZWZhdWx0X3ZhbHVlX2ludDY0KCkgPT0gMDsKKyAgICBjYXNlIGludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV9VSU5UMzI6CisgICAgICByZXR1cm4gZmllbGQtPmRlZmF1bHRfdmFsdWVfdWludDMyKCkgPT0gMDsKKyAgICBjYXNlIGludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV9VSU5UNjQ6CisgICAgICByZXR1cm4gZmllbGQtPmRlZmF1bHRfdmFsdWVfdWludDY0KCkgPT0gMDsKKyAgICBjYXNlIGludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV9GTE9BVDoKKyAgICAgIHJldHVybiBmaWVsZC0+ZGVmYXVsdF92YWx1ZV9mbG9hdCgpID09IDA7CisgICAgY2FzZSBpbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfRE9VQkxFOgorICAgICAgcmV0dXJuIGZpZWxkLT5kZWZhdWx0X3ZhbHVlX2RvdWJsZSgpID09IDA7CisgICAgY2FzZSBpbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfQk9PTDoKKyAgICAgIHJldHVybiBmaWVsZC0+ZGVmYXVsdF92YWx1ZV9ib29sKCkgPT0gZmFsc2U7CisgICAgZGVmYXVsdDoKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgfQorfQorCit2b2lkIE1lc3NhZ2VHZW5lcmF0b3I6OgorR2VuZXJhdGVEZXBlbmRlbnRCYXNlQ2xhc3NEZWZpbml0aW9uKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIGlmICghdXNlX2RlcGVuZGVudF9iYXNlXykgeworICAgIHJldHVybjsKKyAgfQorCisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyczsKKyAgdmFyc1siY2xhc3NuYW1lIl0gPSBEZXBlbmRlbnRCYXNlQ2xhc3NUZW1wbGF0ZU5hbWUoZGVzY3JpcHRvcl8pOworICB2YXJzWyJzdXBlcmNsYXNzIl0gPSBTdXBlckNsYXNzTmFtZShkZXNjcmlwdG9yXyk7CisKKyAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAidGVtcGxhdGUgPGNsYXNzIFQ+XG4iCisgICAgImNsYXNzICRjbGFzc25hbWUkIDogcHVibGljICRzdXBlcmNsYXNzJCB7XG4iCisgICAgIiBwdWJsaWM6XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAiJGNsYXNzbmFtZSQoKSB7fVxuIgorICAgICJ2aXJ0dWFsIH4kY2xhc3NuYW1lJCgpIHt9XG4iCisgICAgIlxuIik7CisKKyAgLy8gR2VuZXJhdGUgZGVwZW5kZW50IGFjY2Vzc29yIG1ldGhvZHMgZm9yIGFsbCBmaWVsZHMuCisgIEdlbmVyYXRlRGVwZW5kZW50RmllbGRBY2Nlc3NvckRlY2xhcmF0aW9ucyhwcmludGVyKTsKKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KCJ9O1xuIik7Cit9CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUNsYXNzRGVmaW5pdGlvbihpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5uZXN0ZWRfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICAvLyBtYXAgZW50cnkgbWVzc2FnZSBkb2Vzbid0IG5lZWQgY2xhc3MgZGVmaW5pdGlvbi4gU2luY2UgbWFwIGVudHJ5IG1lc3NhZ2UKKyAgICAvLyBjYW5ub3QgYmUgYSB0b3AgbGV2ZWwgY2xhc3MsIHdlIGp1c3QgbmVlZCB0byBhdm9pZCBjYWxsaW5nCisgICAgLy8gR2VuZXJhdGVDbGFzc0RlZmluaXRpb24gaGVyZS4KKyAgICBpZiAoSXNNYXBFbnRyeU1lc3NhZ2UoZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlKGkpKSkgY29udGludWU7CisgICAgbmVzdGVkX2dlbmVyYXRvcnNfW2ldLT5HZW5lcmF0ZUNsYXNzRGVmaW5pdGlvbihwcmludGVyKTsKKyAgICBwcmludGVyLT5QcmludCgiXG4iKTsKKyAgICBwcmludGVyLT5QcmludChrVGhpblNlcGFyYXRvcik7CisgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisgIH0KKworICBpZiAodXNlX2RlcGVuZGVudF9iYXNlXykgeworICAgIEdlbmVyYXRlRGVwZW5kZW50QmFzZUNsYXNzRGVmaW5pdGlvbihwcmludGVyKTsKKyAgICAgIHByaW50ZXItPlByaW50KCJcbiIpOworICB9CisKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJzOworICB2YXJzWyJjbGFzc25hbWUiXSA9IGNsYXNzbmFtZV87CisgIHZhcnNbImZpZWxkX2NvdW50Il0gPSBTaW1wbGVJdG9hKGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpKTsKKyAgdmFyc1sib25lb2ZfZGVjbF9jb3VudCJdID0gU2ltcGxlSXRvYShkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbF9jb3VudCgpKTsKKyAgaWYgKG9wdGlvbnNfLmRsbGV4cG9ydF9kZWNsLmVtcHR5KCkpIHsKKyAgICB2YXJzWyJkbGxleHBvcnQiXSA9ICIiOworICB9IGVsc2UgeworICAgIHZhcnNbImRsbGV4cG9ydCJdID0gb3B0aW9uc18uZGxsZXhwb3J0X2RlY2wgKyAiICI7CisgIH0KKyAgaWYgKHVzZV9kZXBlbmRlbnRfYmFzZV8pIHsKKyAgICB2YXJzWyJzdXBlcmNsYXNzIl0gPQorICAgICAgICBEZXBlbmRlbnRCYXNlQ2xhc3NUZW1wbGF0ZU5hbWUoZGVzY3JpcHRvcl8pICsgIjwiICsgY2xhc3NuYW1lXyArICI+IjsKKyAgfSBlbHNlIHsKKyAgICB2YXJzWyJzdXBlcmNsYXNzIl0gPSBTdXBlckNsYXNzTmFtZShkZXNjcmlwdG9yXyk7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAiY2xhc3MgJGRsbGV4cG9ydCQkY2xhc3NuYW1lJCA6IHB1YmxpYyAkc3VwZXJjbGFzcyQge1xuIik7CisgIGlmICh1c2VfZGVwZW5kZW50X2Jhc2VfKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFycywgIiAgZnJpZW5kIGNsYXNzICRzdXBlcmNsYXNzJDtcbiIpOworICB9CisgIHByaW50ZXItPlByaW50KCIgcHVibGljOlxuIik7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgIiRjbGFzc25hbWUkKCk7XG4iCisgICAgInZpcnR1YWwgfiRjbGFzc25hbWUkKCk7XG4iCisgICAgIlxuIgorICAgICIkY2xhc3NuYW1lJChjb25zdCAkY2xhc3NuYW1lJCYgZnJvbSk7XG4iCisgICAgIlxuIgorICAgICJpbmxpbmUgJGNsYXNzbmFtZSQmIG9wZXJhdG9yPShjb25zdCAkY2xhc3NuYW1lJCYgZnJvbSkge1xuIgorICAgICIgIENvcHlGcm9tKGZyb20pO1xuIgorICAgICIgIHJldHVybiAqdGhpcztcbiIKKyAgICAifVxuIgorICAgICJcbiIpOworCisgIGlmIChQcmVzZXJ2ZVVua25vd25GaWVsZHMoZGVzY3JpcHRvcl8pKSB7CisgICAgaWYgKFVzZVVua25vd25GaWVsZFNldChkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpVbmtub3duRmllbGRTZXQmIHVua25vd25fZmllbGRzKCkgY29uc3Qge1xuIgorICAgICAgICAiICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy51bmtub3duX2ZpZWxkcygpO1xuIgorICAgICAgICAifVxuIgorICAgICAgICAiXG4iCisgICAgICAgICJpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpVbmtub3duRmllbGRTZXQqIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSB7XG4iCisgICAgICAgICIgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLm11dGFibGVfdW5rbm93bl9maWVsZHMoKTtcbiIKKyAgICAgICAgIn1cbiIKKyAgICAgICAgIlxuIik7CisgICAgfSBlbHNlIHsKKyAgICAgIGlmIChTdXBwb3J0c0FyZW5hcyhkZXNjcmlwdG9yXykpIHsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgImlubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiB1bmtub3duX2ZpZWxkcygpIGNvbnN0IHtcbiIKKyAgICAgICAgICAiICByZXR1cm4gX3Vua25vd25fZmllbGRzXy5HZXQoXG4iCisgICAgICAgICAgIiAgICAgICY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7XG4iCisgICAgICAgICAgIn1cbiIKKyAgICAgICAgICAiXG4iCisgICAgICAgICAgImlubGluZSA6OnN0ZDo6c3RyaW5nKiBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkge1xuIgorICAgICAgICAgICIgIHJldHVybiBfdW5rbm93bl9maWVsZHNfLk11dGFibGUoXG4iCisgICAgICAgICAgIiAgICAgICY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSxcbiIKKyAgICAgICAgICAiICAgICAgR2V0QXJlbmFOb1ZpcnR1YWwoKSk7XG4iCisgICAgICAgICAgIn1cbiIKKyAgICAgICAgICAiXG4iKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICJpbmxpbmUgY29uc3QgOjpzdGQ6OnN0cmluZyYgdW5rbm93bl9maWVsZHMoKSBjb25zdCB7XG4iCisgICAgICAgICAgIiAgcmV0dXJuIF91bmtub3duX2ZpZWxkc18uR2V0Tm9BcmVuYShcbiIKKyAgICAgICAgICAiICAgICAgJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTtcbiIKKyAgICAgICAgICAifVxuIgorICAgICAgICAgICJcbiIKKyAgICAgICAgICAiaW5saW5lIDo6c3RkOjpzdHJpbmcqIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSB7XG4iCisgICAgICAgICAgIiAgcmV0dXJuIF91bmtub3duX2ZpZWxkc18uTXV0YWJsZU5vQXJlbmEoXG4iCisgICAgICAgICAgIiAgICAgICY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7XG4iCisgICAgICAgICAgIn1cbiIKKyAgICAgICAgICAiXG4iKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvLyBOLkIuOiBXZSBleGNsdWRlIEdldEFyZW5hKCkgd2hlbiBhcmVuYSBzdXBwb3J0IGlzIGRpc2FibGVkLCBmYWxsaW5nIGJhY2sgb24KKyAgLy8gTWVzc2FnZUxpdGUncyBpbXBsZW1lbnRhdGlvbiB3aGljaCByZXR1cm5zIE5VTEwgcmF0aGVyIHRoYW4gZ2VuZXJhdGluZyBvdXIKKyAgLy8gb3duIG1ldGhvZCB3aGljaCByZXR1cm5zIE5VTEwsIGluIG9yZGVyIHRvIHJlZHVjZSBjb2RlIHNpemUuCisgIGlmIChTdXBwb3J0c0FyZW5hcyhkZXNjcmlwdG9yXykpIHsKKyAgICAvLyB2aXJ0dWFsIG1ldGhvZCB2ZXJzaW9uIG9mIEdldEFyZW5hTm9WaXJ0dWFsKCksIHJlcXVpcmVkIGZvciBnZW5lcmljIGRpc3BhdGNoIGdpdmVuIGEKKyAgICAvLyBNZXNzYWdlTGl0ZSogKGUuZy4sIGluIFJlcGVhdGVkRmllbGQ6OkFkZEFsbG9jYXRlZCgpKS4KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgImlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYSgpIGNvbnN0IHsgcmV0dXJuIEdldEFyZW5hTm9WaXJ0dWFsKCk7IH1cbiIKKyAgICAgICAgImlubGluZSB2b2lkKiBHZXRNYXliZUFyZW5hUG9pbnRlcigpIGNvbnN0IHtcbiIKKyAgICAgICAgIiAgcmV0dXJuIE1heWJlQXJlbmFQdHIoKTtcbiIKKyAgICAgICAgIn1cbiIpOworICB9CisKKyAgLy8gT25seSBnZW5lcmF0ZSB0aGlzIG1lbWJlciBpZiBpdCdzIG5vdCBkaXNhYmxlZC4KKyAgaWYgKEhhc0Rlc2NyaXB0b3JNZXRob2RzKGRlc2NyaXB0b3JfLT5maWxlKCkpICYmCisgICAgICAhZGVzY3JpcHRvcl8tPm9wdGlvbnMoKS5ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yKCkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgInN0YXRpYyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIGRlc2NyaXB0b3IoKTtcbiIpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAic3RhdGljIGNvbnN0ICRjbGFzc25hbWUkJiBkZWZhdWx0X2luc3RhbmNlKCk7XG4iCisgICAgIlxuIik7CisKKyAgLy8gR2VuZXJhdGUgZW51bSB2YWx1ZXMgZm9yIGV2ZXJ5IGZpZWxkIGluIG9uZW9mcy4gT25lIGxpc3QgaXMgZ2VuZXJhdGVkIGZvcgorICAvLyBlYWNoIG9uZW9mIHdpdGggYW4gYWRkaXRpb25hbCAqX05PVF9TRVQgdmFsdWUuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2xfY291bnQoKTsgaSsrKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJlbnVtICRjYW1lbF9vbmVvZl9uYW1lJENhc2Uge1xuIiwKKyAgICAgICAgImNhbWVsX29uZW9mX25hbWUiLAorICAgICAgICBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlKGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5uYW1lKCksIHRydWUpKTsKKyAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICBmb3IgKGludCBqID0gMDsgaiA8IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5maWVsZF9jb3VudCgpOyBqKyspIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICJrJGZpZWxkX25hbWUkID0gJGZpZWxkX251bWJlciQsXG4iLAorICAgICAgICAgICJmaWVsZF9uYW1lIiwKKyAgICAgICAgICBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlKAorICAgICAgICAgICAgICBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKS0+ZmllbGQoaiktPm5hbWUoKSwgdHJ1ZSksCisgICAgICAgICAgImZpZWxkX251bWJlciIsCisgICAgICAgICAgU2ltcGxlSXRvYShkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKS0+ZmllbGQoaiktPm51bWJlcigpKSk7CisgICAgfQorICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiJGNhcF9vbmVvZl9uYW1lJF9OT1RfU0VUID0gMCxcbiIsCisgICAgICAgICJjYXBfb25lb2ZfbmFtZSIsCisgICAgICAgIFRvVXBwZXIoZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPm5hbWUoKSkpOworICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIn07XG4iCisgICAgICAgICJcbiIpOworICB9CisKKyAgaWYgKCFTdGF0aWNJbml0aWFsaXplcnNGb3JjZWQoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgIiNpZmRlZiBHT09HTEVfUFJPVE9CVUZfTk9fU1RBVElDX0lOSVRJQUxJWkVSXG4iCisgICAgICAiLy8gUmV0dXJucyB0aGUgaW50ZXJuYWwgZGVmYXVsdCBpbnN0YW5jZSBwb2ludGVyLiBUaGlzIGZ1bmN0aW9uIGNhblxuIgorICAgICAgIi8vIHJldHVybiBOVUxMIHRodXMgc2hvdWxkIG5vdCBiZSB1c2VkIGJ5IHRoZSB1c2VyLiBUaGlzIGlzIGludGVuZGVkXG4iCisgICAgICAiLy8gZm9yIFByb3RvYnVmIGludGVybmFsIGNvZGUuIFBsZWFzZSB1c2UgZGVmYXVsdF9pbnN0YW5jZSgpIGRlY2xhcmVkXG4iCisgICAgICAiLy8gYWJvdmUgaW5zdGVhZC5cbiIKKyAgICAgICJzdGF0aWMgaW5saW5lIGNvbnN0ICRjbGFzc25hbWUkKiBpbnRlcm5hbF9kZWZhdWx0X2luc3RhbmNlKCkge1xuIgorICAgICAgIiAgcmV0dXJuIGRlZmF1bHRfaW5zdGFuY2VfO1xuIgorICAgICAgIn1cbiIKKyAgICAgICIjZW5kaWZcbiIKKyAgICAgICJcbiIpOworICB9CisKKworICBpZiAoU3VwcG9ydHNBcmVuYXMoZGVzY3JpcHRvcl8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICJ2b2lkIFVuc2FmZUFyZW5hU3dhcCgkY2xhc3NuYW1lJCogb3RoZXIpO1xuIik7CisgIH0KKworICBpZiAoSXNBbnlNZXNzYWdlKGRlc2NyaXB0b3JfKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAiLy8gaW1wbGVtZW50cyBBbnkgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiIKKyAgICAgICJcbiIKKyAgICAgICJ2b2lkIFBhY2tGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgbWVzc2FnZSk7XG4iCisgICAgICAiYm9vbCBVbnBhY2tUbyg6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UqIG1lc3NhZ2UpIGNvbnN0O1xuIgorICAgICAgInRlbXBsYXRlPHR5cGVuYW1lIFQ+IGJvb2wgSXMoKSBjb25zdCB7XG4iCisgICAgICAiICByZXR1cm4gX2FueV9tZXRhZGF0YV8uSXM8VD4oKTtcbiIKKyAgICAgICJ9XG4iCisgICAgICAiXG4iKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgInZvaWQgU3dhcCgkY2xhc3NuYW1lJCogb3RoZXIpO1xuIgorICAgICJcbiIKKyAgICAiLy8gaW1wbGVtZW50cyBNZXNzYWdlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiIKKyAgICAiXG4iCisgICAgImlubGluZSAkY2xhc3NuYW1lJCogTmV3KCkgY29uc3QgeyByZXR1cm4gTmV3KE5VTEwpOyB9XG4iCisgICAgIlxuIgorICAgICIkY2xhc3NuYW1lJCogTmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdDtcbiIpOworCisgIGlmIChIYXNHZW5lcmF0ZWRNZXRob2RzKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgaWYgKEhhc0Rlc2NyaXB0b3JNZXRob2RzKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgICAidm9pZCBDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pO1xuIgorICAgICAgICAidm9pZCBNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTtcbiIpOworICAgIH0gZWxzZSB7CisgICAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgICAidm9pZCBDaGVja1R5cGVBbmRNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlTGl0ZSYgZnJvbSk7XG4iKTsKKyAgICB9CisKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgInZvaWQgQ29weUZyb20oY29uc3QgJGNsYXNzbmFtZSQmIGZyb20pO1xuIgorICAgICAgInZvaWQgTWVyZ2VGcm9tKGNvbnN0ICRjbGFzc25hbWUkJiBmcm9tKTtcbiIKKyAgICAgICJ2b2lkIENsZWFyKCk7XG4iCisgICAgICAiYm9vbCBJc0luaXRpYWxpemVkKCkgY29uc3Q7XG4iCisgICAgICAiXG4iCisgICAgICAiaW50IEJ5dGVTaXplKCkgY29uc3Q7XG4iCisgICAgICAiYm9vbCBNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oXG4iCisgICAgICAiICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KTtcbiIKKyAgICAgICJ2b2lkIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcyhcbiIKKyAgICAgICIgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3Q7XG4iKTsKKyAgICAvLyBEaXNjYXJkVW5rbm93bkZpZWxkcygpIGlzIGltcGxlbWVudGVkIGluIG1lc3NhZ2UuY2MgdXNpbmcgcmVmbGVjdGlvbnMuIFdlCisgICAgLy8gbmVlZCB0byBpbXBsZW1lbnQgdGhpcyBmdW5jdGlvbiBpbiBnZW5lcmF0ZWQgY29kZSBmb3IgbWVzc2FnZXMuCisgICAgaWYgKCFVc2VVbmtub3duRmllbGRTZXQoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAidm9pZCBEaXNjYXJkVW5rbm93bkZpZWxkcygpO1xuIik7CisgICAgfQorICAgIGlmIChIYXNGYXN0QXJyYXlTZXJpYWxpemF0aW9uKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogb3V0cHV0KSBjb25zdDtcbiIpOworICAgIH0KKyAgfQorCisgIC8vIENoZWNrIGFsbCBGaWVsZERlc2NyaXB0b3JzIGluY2x1ZGluZyB0aG9zZSBpbiBvbmVvZnMgdG8gZXN0aW1hdGUKKyAgLy8gd2hldGhlciA6OnN0ZDo6c3RyaW5nIGlzIGxpa2VseSB0byBiZSB1c2VkLCBhbmQgZGVwZW5kaW5nIG9uIHRoYXQKKyAgLy8gZXN0aW1hdGUsIHNldCB1c2VzX3N0cmluZ18gdG8gdHJ1ZSBvciBmYWxzZS4gIFRoYXQgY29udG9scworICAvLyB3aGV0aGVyIHRvIGZvcmNlIGluaXRpYWxpemF0aW9uIG9mIGVtcHR5X3N0cmluZ18gaW4gU2hhcmVkQ3RvcigpLgorICAvLyBJdCdzIG9mdGVuIGFkdmFudGFnZW91cyB0byBkbyBzbyB0byBrZWVwICJpcyBlbXB0eV9zdHJpbmdfCisgIC8vIGluaXRlZD8iIGNvZGUgZnJvbSBhcHBlYXJpbmcgYWxsIG92ZXIgdGhlIHBsYWNlLgorICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4gZGVzY3JpcHRvcnM7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGRlc2NyaXB0b3JzLnB1c2hfYmFjayhkZXNjcmlwdG9yXy0+ZmllbGQoaSkpOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2xfY291bnQoKTsgaSsrKSB7CisgICAgZm9yIChpbnQgaiA9IDA7IGogPCBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKS0+ZmllbGRfY291bnQoKTsgaisrKSB7CisgICAgICBkZXNjcmlwdG9ycy5wdXNoX2JhY2soZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPmZpZWxkKGopKTsKKyAgICB9CisgIH0KKyAgdXNlc19zdHJpbmdfID0gZmFsc2U7CisgIGlmIChQcmVzZXJ2ZVVua25vd25GaWVsZHMoZGVzY3JpcHRvcl8pICYmCisgICAgICAhVXNlVW5rbm93bkZpZWxkU2V0KGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgdXNlc19zdHJpbmdfID0gdHJ1ZTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JzLnNpemUoKTsgaSsrKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3JzW2ldOworICAgIGlmIChmaWVsZC0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkLT5vcHRpb25zKCkuY3R5cGUoKSkgeworICAgICAgICBkZWZhdWx0OiB1c2VzX3N0cmluZ18gPSB0cnVlOyBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICBwcmludGVyLT5QcmludCgKKyAgICAiaW50IEdldENhY2hlZFNpemUoKSBjb25zdCB7IHJldHVybiBfY2FjaGVkX3NpemVfOyB9XG4iCisgICAgInByaXZhdGU6XG4iCisgICAgInZvaWQgU2hhcmVkQ3RvcigpO1xuIgorICAgICJ2b2lkIFNoYXJlZER0b3IoKTtcbiIKKyAgICAidm9pZCBTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdDtcbiIKKyAgICAidm9pZCBJbnRlcm5hbFN3YXAoJGNsYXNzbmFtZSQqIG90aGVyKTtcbiIsCisgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8pOworICBpZiAoU3VwcG9ydHNBcmVuYXMoZGVzY3JpcHRvcl8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAicHJvdGVjdGVkOlxuIgorICAgICAgImV4cGxpY2l0ICRjbGFzc25hbWUkKDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKTtcbiIKKyAgICAgICJwcml2YXRlOlxuIgorICAgICAgInN0YXRpYyB2b2lkIEFyZW5hRHRvcih2b2lkKiBvYmplY3QpO1xuIgorICAgICAgImlubGluZSB2b2lkIFJlZ2lzdGVyQXJlbmFEdG9yKDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKTtcbiIsCisgICAgICAiY2xhc3NuYW1lIiwgY2xhc3NuYW1lXyk7CisgIH0KKworICBpZiAoVXNlVW5rbm93bkZpZWxkU2V0KGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAicHJpdmF0ZTpcbiIKKyAgICAgICJpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogR2V0QXJlbmFOb1ZpcnR1YWwoKSBjb25zdCB7XG4iCisgICAgICAiICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5hcmVuYSgpO1xuIgorICAgICAgIn1cbiIKKyAgICAgICJpbmxpbmUgdm9pZCogTWF5YmVBcmVuYVB0cigpIGNvbnN0IHtcbiIKKyAgICAgICIgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnJhd19hcmVuYV9wdHIoKTtcbiIKKyAgICAgICJ9XG4iCisgICAgICAicHVibGljOlxuIgorICAgICAgIlxuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAicHJpdmF0ZTpcbiIKKyAgICAgICJpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogR2V0QXJlbmFOb1ZpcnR1YWwoKSBjb25zdCB7XG4iCisgICAgICAiICByZXR1cm4gX2FyZW5hX3B0cl87XG4iCisgICAgICAifVxuIgorICAgICAgImlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBNYXliZUFyZW5hUHRyKCkgY29uc3Qge1xuIgorICAgICAgIiAgcmV0dXJuIF9hcmVuYV9wdHJfO1xuIgorICAgICAgIn1cbiIKKyAgICAgICJwdWJsaWM6XG4iCisgICAgICAiXG4iKTsKKyAgfQorCisgIGlmIChIYXNEZXNjcmlwdG9yTWV0aG9kcyhkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgR2V0TWV0YWRhdGEoKSBjb25zdDtcbiIKKyAgICAgICJcbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIjo6c3RkOjpzdHJpbmcgR2V0VHlwZU5hbWUoKSBjb25zdDtcbiIKKyAgICAgICJcbiIpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIi8vIG5lc3RlZCB0eXBlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4iCisgICAgIlxuIik7CisKKyAgLy8gSW1wb3J0IGFsbCBuZXN0ZWQgbWVzc2FnZSBjbGFzc2VzIGludG8gdGhpcyBjbGFzcydzIHNjb3BlIHdpdGggdHlwZWRlZnMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IERlc2NyaXB0b3IqIG5lc3RlZF90eXBlID0gZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlKGkpOworICAgIGlmICghSXNNYXBFbnRyeU1lc3NhZ2UobmVzdGVkX3R5cGUpKSB7CisgICAgICBwcmludGVyLT5QcmludCgidHlwZWRlZiAkbmVzdGVkX2Z1bGxfbmFtZSQgJG5lc3RlZF9uYW1lJDtcbiIsCisgICAgICAgICAgICAgICAgICAgICAibmVzdGVkX25hbWUiLCBuZXN0ZWRfdHlwZS0+bmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgIm5lc3RlZF9mdWxsX25hbWUiLCBDbGFzc05hbWUobmVzdGVkX3R5cGUsIGZhbHNlKSk7CisgICAgfQorICB9CisKKyAgaWYgKGRlc2NyaXB0b3JfLT5uZXN0ZWRfdHlwZV9jb3VudCgpID4gMCkgeworICAgIHByaW50ZXItPlByaW50KCJcbiIpOworICB9CisKKyAgLy8gSW1wb3J0IGFsbCBuZXN0ZWQgZW51bXMgYW5kIHRoZWlyIHZhbHVlcyBpbnRvIHRoaXMgY2xhc3MncyBzY29wZSB3aXRoCisgIC8vIHR5cGVkZWZzIGFuZCBjb25zdGFudHMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmVudW1fdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBlbnVtX2dlbmVyYXRvcnNfW2ldLT5HZW5lcmF0ZVN5bWJvbEltcG9ydHMocHJpbnRlcik7CisgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisgIH0KKworICBwcmludGVyLT5QcmludCgKKyAgICAiLy8gYWNjZXNzb3JzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiIKKyAgICAiXG4iKTsKKworICAvLyBHZW5lcmF0ZSBhY2Nlc3NvciBtZXRob2RzIGZvciBhbGwgZmllbGRzLgorICBHZW5lcmF0ZUZpZWxkQWNjZXNzb3JEZWNsYXJhdGlvbnMocHJpbnRlcik7CisKKyAgLy8gRGVjbGFyZSBleHRlbnNpb24gaWRlbnRpZmllcnMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmV4dGVuc2lvbl9jb3VudCgpOyBpKyspIHsKKyAgICBleHRlbnNpb25fZ2VuZXJhdG9yc19baV0tPkdlbmVyYXRlRGVjbGFyYXRpb24ocHJpbnRlcik7CisgIH0KKworCisgIHByaW50ZXItPlByaW50KAorICAgICIvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6JGZ1bGxfbmFtZSQpXG4iLAorICAgICJmdWxsX25hbWUiLCBkZXNjcmlwdG9yXy0+ZnVsbF9uYW1lKCkpOworCisgIC8vIEdlbmVyYXRlIHByaXZhdGUgbWVtYmVycy4KKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgiIHByaXZhdGU6XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBpZiAoIWRlc2NyaXB0b3JfLT5maWVsZChpKS0+aXNfcmVwZWF0ZWQoKSkgeworICAgICAgLy8gc2V0X2hhc18qKiooKSBnZW5lcmF0ZWQgaW4gYWxsIHByb3RvMS8yIGNvZGUgYW5kIGluIG9uZW9mcyAob25seSkgZm9yCisgICAgICAvLyBtZXNzYWdlcyB3aXRob3V0IHRydWUgZmllbGQgcHJlc2VuY2UuCisgICAgICBpZiAoSGFzRmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSB8fAorICAgICAgICAgIGRlc2NyaXB0b3JfLT5maWVsZChpKS0+Y29udGFpbmluZ19vbmVvZigpKSB7CisgICAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICJpbmxpbmUgdm9pZCBzZXRfaGFzXyRuYW1lJCgpO1xuIiwKKyAgICAgICAgICAibmFtZSIsIEZpZWxkTmFtZShkZXNjcmlwdG9yXy0+ZmllbGQoaSkpKTsKKyAgICAgIH0KKyAgICAgIC8vIGNsZWFyX2hhc18qKiooKSBnZW5lcmF0ZWQgb25seSBmb3Igbm9uLW9uZW9mIGZpZWxkcworICAgICAgLy8gaW4gcHJvdG8xLzIuCisgICAgICBpZiAoIWRlc2NyaXB0b3JfLT5maWVsZChpKS0+Y29udGFpbmluZ19vbmVvZigpICYmCisgICAgICAgICAgSGFzRmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAiaW5saW5lIHZvaWQgY2xlYXJfaGFzXyRuYW1lJCgpO1xuIiwKKyAgICAgICAgICAibmFtZSIsIEZpZWxkTmFtZShkZXNjcmlwdG9yXy0+ZmllbGQoaSkpKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKyAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisKKyAgLy8gR2VuZXJhdGUgb25lb2YgZnVuY3Rpb24gZGVjbGFyYXRpb25zCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2xfY291bnQoKTsgaSsrKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJpbmxpbmUgYm9vbCBoYXNfJG9uZW9mX25hbWUkKCkgY29uc3Q7XG4iCisgICAgICAgICJ2b2lkIGNsZWFyXyRvbmVvZl9uYW1lJCgpO1xuIgorICAgICAgICAiaW5saW5lIHZvaWQgY2xlYXJfaGFzXyRvbmVvZl9uYW1lJCgpO1xuXG4iLAorICAgICAgICAib25lb2ZfbmFtZSIsIGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5uYW1lKCkpOworICB9CisKKyAgaWYgKEhhc0dlbmVyYXRlZE1ldGhvZHMoZGVzY3JpcHRvcl8tPmZpbGUoKSkgJiYKKyAgICAgICFkZXNjcmlwdG9yXy0+b3B0aW9ucygpLm1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KCkgJiYKKyAgICAgIG51bV9yZXF1aXJlZF9maWVsZHNfID4gMSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiLy8gaGVscGVyIGZvciBCeXRlU2l6ZSgpXG4iCisgICAgICAgICJpbnQgUmVxdWlyZWRGaWVsZHNCeXRlU2l6ZUZhbGxiYWNrKCkgY29uc3Q7XG5cbiIpOworICB9CisKKyAgLy8gUHJlcGFyZSBkZWNscyBmb3IgX2NhY2hlZF9zaXplXyBhbmQgX2hhc19iaXRzXy4gIFRoZWlyIHBvc2l0aW9uIGluIHRoZQorICAvLyBvdXRwdXQgd2lsbCBiZSBkZXRlcm1pbmVkIGxhdGVyLgorCisgIGJvb2wgbmVlZF90b19lbWl0X2NhY2hlZF9zaXplID0gdHJ1ZTsKKyAgLy8gVE9ETyhrZW50b24pOiAgTWFrZSBfY2FjaGVkX3NpemVfIGFuIGF0b21pYzxpbnQ+IHdoZW4gQysrIHN1cHBvcnRzIGl0LgorICBjb25zdCBzdHJpbmcgY2FjaGVkX3NpemVfZGVjbCA9ICJtdXRhYmxlIGludCBfY2FjaGVkX3NpemVfO1xuIjsKKworICAvLyBUT0RPKGppZWx1bykgLSBPcHRpbWl6ZSBfaGFzX2JpdHNfIGZvciByZXBlYXRlZCBhbmQgb25lb2YgZmllbGRzLgorICBzaXplX3Qgc2l6ZW9mX2hhc19iaXRzID0gKGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpICsgMzEpIC8gMzIgKiA0OworICBpZiAoZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCkgPT0gMCkgeworICAgIC8vIFplcm8tc2l6ZSBhcnJheXMgYXJlbid0IHRlY2huaWNhbGx5IGFsbG93ZWQsIGFuZCBNU1ZDIGluIHBhcnRpY3VsYXIKKyAgICAvLyBkb2Vzbid0IGxpa2UgdGhlbS4gIFdlIHN0aWxsIG5lZWQgdG8gZGVjbGFyZSB0aGVzZSBhcnJheXMgdG8gbWFrZQorICAgIC8vIG90aGVyIGNvZGUgY29tcGlsZS4gIFNpbmNlIHRoaXMgaXMgYW4gdW5jb21tb24gY2FzZSwgd2UnbGwganVzdCBkZWNsYXJlCisgICAgLy8gdGhlbSB3aXRoIHNpemUgMSBhbmQgd2FzdGUgc29tZSBzcGFjZS4gIE9oIHdlbGwuCisgICAgc2l6ZW9mX2hhc19iaXRzID0gNDsKKyAgfQorICBjb25zdCBzdHJpbmcgaGFzX2JpdHNfZGVjbCA9IHNpemVvZl9oYXNfYml0cyA9PSAwID8gIiIgOgorICAgICAgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIF9oYXNfYml0c19bIiArIFNpbXBsZUl0b2Eoc2l6ZW9mX2hhc19iaXRzIC8gNCkgKyAiXTtcbiI7CisKKworICAvLyBUbyBtaW5pbWl6ZSBwYWRkaW5nLCBkYXRhIG1lbWJlcnMgYXJlIGRpdmlkZWQgaW50byB0aHJlZSBzZWN0aW9uczoKKyAgLy8gKDEpIG1lbWJlcnMgYXNzdW1lZCB0byBhbGlnbiB0byA4IGJ5dGVzCisgIC8vICgyKSBtZW1iZXJzIGNvcnJlc3BvbmRpbmcgdG8gbWVzc2FnZSBmaWVsZHMsIHJlLW9yZGVyZWQgdG8gb3B0aW1pemUKKyAgLy8gICAgIGFsaWdubWVudC4KKyAgLy8gKDMpIG1lbWJlcnMgYXNzdW1lZCB0byBhbGlnbiB0byA0IGJ5dGVzLgorCisgIC8vIE1lbWJlcnMgYXNzdW1lZCB0byBhbGlnbiB0byA4IGJ5dGVzOgorCisgIGlmIChkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCkgPiAwKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RXh0ZW5zaW9uU2V0IF9leHRlbnNpb25zXztcbiIKKyAgICAgICJcbiIpOworICB9CisKKyAgaWYgKFVzZVVua25vd25GaWVsZFNldChkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEgX2ludGVybmFsX21ldGFkYXRhXztcbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFyZW5hU3RyaW5nUHRyIF91bmtub3duX2ZpZWxkc187XG4iCisgICAgICAiOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogX2FyZW5hX3B0cl87XG4iCisgICAgICAiXG4iKTsKKyAgfQorCisgIGlmIChTdXBwb3J0c0FyZW5hcyhkZXNjcmlwdG9yXykpIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJmcmllbmQgY2xhc3MgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYTtcbiIKKyAgICAgICJ0eXBlZGVmIHZvaWQgSW50ZXJuYWxBcmVuYUNvbnN0cnVjdGFibGVfO1xuIgorICAgICAgInR5cGVkZWYgdm9pZCBEZXN0cnVjdG9yU2tpcHBhYmxlXztcbiIpOworICB9CisKKyAgaWYgKEhhc0ZpZWxkUHJlc2VuY2UoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICAvLyBfaGFzX2JpdHNfIGlzIGZyZXF1ZW50bHkgYWNjZXNzZWQsIHNvIHRvIHJlZHVjZSBjb2RlIHNpemUgYW5kIGltcHJvdmUKKyAgICAvLyBzcGVlZCwgaXQgc2hvdWxkIGJlIGNsb3NlIHRvIHRoZSBzdGFydCBvZiB0aGUgb2JqZWN0LiAgQnV0LCB0cnkgbm90IHRvCisgICAgLy8gd2FzdGUgc3BhY2U6X2hhc19iaXRzXyBieSBpdHNlbGYgYWx3YXlzIG1ha2VzIHNlbnNlIGlmIGl0cyBzaXplIGlzIGEKKyAgICAvLyBtdWx0aXBsZSBvZiA4LCBidXQsIG90aGVyd2lzZSwgbWF5YmUgX2hhc19iaXRzXyBhbmQgY2FjaGVkX3NpemVfIHRvZ2V0aGVyCisgICAgLy8gd2lsbCB3b3JrIHdlbGwuCisgICAgcHJpbnRlci0+UHJpbnQoaGFzX2JpdHNfZGVjbC5jX3N0cigpKTsKKyAgICBpZiAoKHNpemVvZl9oYXNfYml0cyAlIDgpICE9IDApIHsKKyAgICAgIHByaW50ZXItPlByaW50KGNhY2hlZF9zaXplX2RlY2wuY19zdHIoKSk7CisgICAgICBuZWVkX3RvX2VtaXRfY2FjaGVkX3NpemUgPSBmYWxzZTsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgLy8gV2l0aG91dCBmaWVsZCBwcmVzZW5jZSwgd2UgbmVlZCBhbm90aGVyIHdheSB0byBkaXNhbWJpZ3VhdGUgdGhlIGRlZmF1bHQKKyAgICAvLyBpbnN0YW5jZSwgYmVjYXVzZSB0aGUgZGVmYXVsdCBpbnN0YW5jZSdzIHN1Ym1lc3NhZ2UgZmllbGRzIChpZiBhbnkpIHN0b3JlCisgICAgLy8gcG9pbnRlcnMgdG8gdGhlIGRlZmF1bHQgaW5zdGFuY2VzIG9mIHRoZSBzdWJtZXNzYWdlcyBldmVuIHdoZW4gdGhleQorICAgIC8vIGFyZW4ndCBwcmVzZW50LiBBbHRlcm5hdGl2ZXMgdG8gdGhpcyBhcHByb2FjaCBtaWdodCBiZSB0byAoaSkgdXNlIGEKKyAgICAvLyB0YWdnZWQgcG9pbnRlciBvbiBhbGwgbWVzc2FnZSBmaWVsZHMsIHNldHRpbmcgYSB0YWcgYml0IGZvciAibm90IHJlYWxseQorICAgIC8vIHByZXNlbnQsIGp1c3QgZGVmYXVsdCBpbnN0YW5jZSI7IG9yIChpaSkgY29tcGFyaW5nIHx0aGlzfCBhZ2FpbnN0IHRoZQorICAgIC8vIHJldHVybiB2YWx1ZSBmcm9tIEdlbmVyYXRlZE1lc3NhZ2VGYWN0b3J5OjpHZXRQcm90b3R5cGUoKSBpbiBhbGwKKyAgICAvLyBoYXNfJGZpZWxkJCgpIGNhbGxzLiBIb3dldmVyLCBib3RoIG9mIHRoZXNlIG9wdGlvbnMgYXJlIG11Y2ggbW9yZQorICAgIC8vIGV4cGVuc2l2ZSAoaW4gY29kZSBzaXplIGFuZCBDUFUgb3ZlcmhlYWQpIHRoYW4ganVzdCBjaGVja2luZyBhIGZpZWxkIGluCisgICAgLy8gdGhlIG1lc3NhZ2UuIExvbmctdGVybSwgdGhlIGJlc3Qgc29sdXRpb24gd291bGQgYmUgdG8gcmVhcmNoaXRlY3QgdGhlCisgICAgLy8gZGVmYXVsdCBpbnN0YW5jZSBkZXNpZ24gbm90IHRvIHN0b3JlIHBvaW50ZXJzIHRvIHN1Ym1lc3NhZ2UgZGVmYXVsdAorICAgIC8vIGluc3RhbmNlcywgYW5kIGhhdmUgcmVmbGVjdGlvbiBnZXQgdGhvc2Ugc29tZSBvdGhlciB3YXk7IGJ1dCB0aGF0IGNoYW5nZQorICAgIC8vIHdvdWxkIGhhdmUgdG9vIG11Y2ggaW1wYWN0IG9uIHByb3RvMi4KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJib29sIF9pc19kZWZhdWx0X2luc3RhbmNlXztcbiIpOworICB9CisKKyAgLy8gRmllbGQgbWVtYmVyczoKKworICAvLyBMaXN0IGZpZWxkcyB3aGljaCBkb2Vzbid0IGJlbG9uZyB0byBhbnkgb25lb2YKKyAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+IGZpZWxkczsKKyAgaGFzaF9tYXA8c3RyaW5nLCBpbnQ+IGZpZWxkbmFtZV90b19jaHVuazsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgaWYgKCFkZXNjcmlwdG9yXy0+ZmllbGQoaSktPmNvbnRhaW5pbmdfb25lb2YoKSkgeworICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3JfLT5maWVsZChpKTsKKyAgICAgIGZpZWxkcy5wdXNoX2JhY2soZmllbGQpOworICAgICAgZmllbGRuYW1lX3RvX2NodW5rW0ZpZWxkTmFtZShmaWVsZCldID0gaSAvIDg7CisgICAgfQorICB9CisgIE9wdGltaXplUGFkZGluZygmZmllbGRzKTsKKyAgLy8gRW1pdCBzb21lIHByaXZhdGUgYW5kIHN0YXRpYyBtZW1iZXJzCisgIHJ1bnNfb2ZfZmllbGRzXyA9IHZlY3RvcjwgdmVjdG9yPHN0cmluZz4gPigxKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZHMuc2l6ZSgpOyArK2kpIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZmllbGRzW2ldOworICAgIGNvbnN0IEZpZWxkR2VuZXJhdG9yJiBnZW5lcmF0b3IgPSBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZmllbGQpOworICAgIGdlbmVyYXRvci5HZW5lcmF0ZVN0YXRpY01lbWJlcnMocHJpbnRlcik7CisgICAgZ2VuZXJhdG9yLkdlbmVyYXRlUHJpdmF0ZU1lbWJlcnMocHJpbnRlcik7CisgICAgaWYgKENhbkNsZWFyQnlaZXJvaW5nKGZpZWxkKSkgeworICAgICAgY29uc3Qgc3RyaW5nJiBmaWVsZG5hbWUgPSBGaWVsZE5hbWUoZmllbGQpOworICAgICAgaWYgKCFydW5zX29mX2ZpZWxkc18uYmFjaygpLmVtcHR5KCkgJiYKKyAgICAgICAgICAoZmllbGRuYW1lX3RvX2NodW5rW3J1bnNfb2ZfZmllbGRzXy5iYWNrKCkuYmFjaygpXSAhPQorICAgICAgICAgICBmaWVsZG5hbWVfdG9fY2h1bmtbZmllbGRuYW1lXSkpIHsKKyAgICAgICAgcnVuc19vZl9maWVsZHNfLnB1c2hfYmFjayh2ZWN0b3I8c3RyaW5nPigpKTsKKyAgICAgIH0KKyAgICAgIHJ1bnNfb2ZfZmllbGRzXy5iYWNrKCkucHVzaF9iYWNrKGZpZWxkbmFtZSk7CisgICAgfSBlbHNlIGlmICghcnVuc19vZl9maWVsZHNfLmJhY2soKS5lbXB0eSgpKSB7CisgICAgICBydW5zX29mX2ZpZWxkc18ucHVzaF9iYWNrKHZlY3RvcjxzdHJpbmc+KCkpOworICAgIH0KKyAgfQorCisgIC8vIEZvciBlYWNoIG9uZW9mIGdlbmVyYXRlIGEgdW5pb24KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbF9jb3VudCgpOyBpKyspIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgInVuaW9uICRjYW1lbF9vbmVvZl9uYW1lJFVuaW9uIHtcbiIKKyAgICAgICAgLy8gZXhwbGljaXQgZW1wdHkgY29uc3RydWN0b3IgaXMgbmVlZGVkIHdoZW4gdW5pb24gY29udGFpbnMKKyAgICAgICAgLy8gQXJlbmFTdHJpbmdQdHIgbWVtYmVycyBmb3Igc3RyaW5nIGZpZWxkcy4KKyAgICAgICAgIiAgJGNhbWVsX29uZW9mX25hbWUkVW5pb24oKSB7fVxuIiwKKyAgICAgICAgImNhbWVsX29uZW9mX25hbWUiLAorICAgICAgICBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlKGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5uYW1lKCksIHRydWUpKTsKKyAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICBmb3IgKGludCBqID0gMDsgaiA8IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5maWVsZF9jb3VudCgpOyBqKyspIHsKKyAgICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKS0+CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGQoaikpLkdlbmVyYXRlUHJpdmF0ZU1lbWJlcnMocHJpbnRlcik7CisgICAgfQorICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIn0gJG9uZW9mX25hbWUkXztcbiIsCisgICAgICAgICJvbmVvZl9uYW1lIiwgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPm5hbWUoKSk7CisgICAgZm9yIChpbnQgaiA9IDA7IGogPCBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKS0+ZmllbGRfY291bnQoKTsgaisrKSB7CisgICAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkKGopKS5HZW5lcmF0ZVN0YXRpY01lbWJlcnMocHJpbnRlcik7CisgICAgfQorICB9CisKKyAgLy8gTWVtYmVycyBhc3N1bWVkIHRvIGFsaWduIHRvIDQgYnl0ZXM6CisKKyAgaWYgKG5lZWRfdG9fZW1pdF9jYWNoZWRfc2l6ZSkgeworICAgIHByaW50ZXItPlByaW50KGNhY2hlZF9zaXplX2RlY2wuY19zdHIoKSk7CisgICAgbmVlZF90b19lbWl0X2NhY2hlZF9zaXplID0gZmFsc2U7CisgIH0KKworICAvLyBHZW5lcmF0ZSBfb25lb2ZfY2FzZV8uCisgIGlmIChkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbF9jb3VudCgpID4gMCkgeworICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAiOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgX29uZW9mX2Nhc2VfWyRvbmVvZl9kZWNsX2NvdW50JF07XG4iCisgICAgICAiXG4iKTsKKyAgfQorCisgIC8vIEdlbmVyYXRlIF9hbnlfbWV0YWRhdGFfIGZvciB0aGUgQW55IHR5cGUuCisgIGlmIChJc0FueU1lc3NhZ2UoZGVzY3JpcHRvcl8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICI6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBbnlNZXRhZGF0YSBfYW55X21ldGFkYXRhXztcbiIpOworICB9CisKKyAgLy8gRGVjbGFyZSBBZGREZXNjcmlwdG9ycygpLCBCdWlsZERlc2NyaXB0b3JzKCksIGFuZCBTaHV0ZG93bkZpbGUoKSBhcworICAvLyBmcmllbmRzIHNvIHRoYXQgdGhleSBjYW4gYWNjZXNzIHByaXZhdGUgc3RhdGljIHZhcmlhYmxlcyBsaWtlCisgIC8vIGRlZmF1bHRfaW5zdGFuY2VfIGFuZCByZWZsZWN0aW9uXy4KKyAgUHJpbnRIYW5kbGluZ09wdGlvbmFsU3RhdGljSW5pdGlhbGl6ZXJzKAorICAgIGRlc2NyaXB0b3JfLT5maWxlKCksIHByaW50ZXIsCisgICAgLy8gV2l0aCBzdGF0aWMgaW5pdGlhbGl6ZXJzLgorICAgICJmcmllbmQgdm9pZCAkZGxsZXhwb3J0X2RlY2wkICRhZGRkZXNjcmlwdG9yc25hbWUkKCk7XG4iLAorICAgIC8vIFdpdGhvdXQuCisgICAgImZyaWVuZCB2b2lkICRkbGxleHBvcnRfZGVjbCQgJGFkZGRlc2NyaXB0b3JzbmFtZSRfaW1wbCgpO1xuIiwKKyAgICAvLyBWYXJzLgorICAgICJkbGxleHBvcnRfZGVjbCIsIG9wdGlvbnNfLmRsbGV4cG9ydF9kZWNsLAorICAgICJhZGRkZXNjcmlwdG9yc25hbWUiLAorICAgIEdsb2JhbEFkZERlc2NyaXB0b3JzTmFtZShkZXNjcmlwdG9yXy0+ZmlsZSgpLT5uYW1lKCkpKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAiZnJpZW5kIHZvaWQgJGFzc2lnbmRlc2NyaXB0b3JzbmFtZSQoKTtcbiIKKyAgICAiZnJpZW5kIHZvaWQgJHNodXRkb3duZmlsZW5hbWUkKCk7XG4iCisgICAgIlxuIiwKKyAgICAiYXNzaWduZGVzY3JpcHRvcnNuYW1lIiwKKyAgICAgIEdsb2JhbEFzc2lnbkRlc2NyaXB0b3JzTmFtZShkZXNjcmlwdG9yXy0+ZmlsZSgpLT5uYW1lKCkpLAorICAgICJzaHV0ZG93bmZpbGVuYW1lIiwgR2xvYmFsU2h1dGRvd25GaWxlTmFtZShkZXNjcmlwdG9yXy0+ZmlsZSgpLT5uYW1lKCkpKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAidm9pZCBJbml0QXNEZWZhdWx0SW5zdGFuY2UoKTtcbiIKKyAgICAic3RhdGljICRjbGFzc25hbWUkKiBkZWZhdWx0X2luc3RhbmNlXztcbiIsCisgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8pOworCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQodmFycywgIn07Iik7CisgIEdPT0dMRV9EQ0hFQ0soIW5lZWRfdG9fZW1pdF9jYWNoZWRfc2l6ZSk7Cit9CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6CitHZW5lcmF0ZURlcGVuZGVudElubGluZU1ldGhvZHMoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+bmVzdGVkX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgLy8gbWFwIGVudHJ5IG1lc3NhZ2UgZG9lc24ndCBuZWVkIGlubGluZSBtZXRob2RzLiBTaW5jZSBtYXAgZW50cnkgbWVzc2FnZQorICAgIC8vIGNhbm5vdCBiZSBhIHRvcCBsZXZlbCBjbGFzcywgd2UganVzdCBuZWVkIHRvIGF2b2lkIGNhbGxpbmcKKyAgICAvLyBHZW5lcmF0ZUlubGluZU1ldGhvZHMgaGVyZS4KKyAgICBpZiAoSXNNYXBFbnRyeU1lc3NhZ2UoZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlKGkpKSkgY29udGludWU7CisgICAgbmVzdGVkX2dlbmVyYXRvcnNfW2ldLT5HZW5lcmF0ZURlcGVuZGVudElubGluZU1ldGhvZHMocHJpbnRlcik7CisgICAgcHJpbnRlci0+UHJpbnQoa1RoaW5TZXBhcmF0b3IpOworICAgIHByaW50ZXItPlByaW50KCJcbiIpOworICB9CisKKyAgR2VuZXJhdGVEZXBlbmRlbnRGaWVsZEFjY2Vzc29yRGVmaW5pdGlvbnMocHJpbnRlcik7Cit9CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUlubGluZU1ldGhvZHMoaW86OlByaW50ZXIqIHByaW50ZXIsIGJvb2wgaXNfaW5saW5lKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlX2NvdW50KCk7IGkrKykgeworICAgIC8vIG1hcCBlbnRyeSBtZXNzYWdlIGRvZXNuJ3QgbmVlZCBpbmxpbmUgbWV0aG9kcy4gU2luY2UgbWFwIGVudHJ5IG1lc3NhZ2UKKyAgICAvLyBjYW5ub3QgYmUgYSB0b3AgbGV2ZWwgY2xhc3MsIHdlIGp1c3QgbmVlZCB0byBhdm9pZCBjYWxsaW5nCisgICAgLy8gR2VuZXJhdGVJbmxpbmVNZXRob2RzIGhlcmUuCisgICAgaWYgKElzTWFwRW50cnlNZXNzYWdlKGRlc2NyaXB0b3JfLT5uZXN0ZWRfdHlwZShpKSkpIGNvbnRpbnVlOworICAgIG5lc3RlZF9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVJbmxpbmVNZXRob2RzKHByaW50ZXIsIGlzX2lubGluZSk7CisgICAgcHJpbnRlci0+UHJpbnQoa1RoaW5TZXBhcmF0b3IpOworICAgIHByaW50ZXItPlByaW50KCJcbiIpOworICB9CisKKyAgR2VuZXJhdGVGaWVsZEFjY2Vzc29yRGVmaW5pdGlvbnMocHJpbnRlciwgaXNfaW5saW5lKTsKKworICAvLyBHZW5lcmF0ZSBvbmVvZl9jYXNlKCkgZnVuY3Rpb25zLgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsX2NvdW50KCk7IGkrKykgeworICAgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyczsKKyAgICB2YXJzWyJjbGFzc19uYW1lIl0gPSBjbGFzc25hbWVfOworICAgIHZhcnNbImNhbWVsX29uZW9mX25hbWUiXSA9IFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoCisgICAgICAgIGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5uYW1lKCksIHRydWUpOworICAgIHZhcnNbIm9uZW9mX25hbWUiXSA9IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5uYW1lKCk7CisgICAgdmFyc1sib25lb2ZfaW5kZXgiXSA9IFNpbXBsZUl0b2EoZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPmluZGV4KCkpOworICAgIHZhcnNbImlubGluZSJdID0gaXNfaW5saW5lID8gImlubGluZSAiIDogIiI7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgIHZhcnMsCisgICAgICAgICIkaW5saW5lJCIKKyAgICAgICAgIiRjbGFzc19uYW1lJDo6JGNhbWVsX29uZW9mX25hbWUkQ2FzZSAkY2xhc3NfbmFtZSQ6OiIKKyAgICAgICAgIiRvbmVvZl9uYW1lJF9jYXNlKCkgY29uc3Qge1xuIgorICAgICAgICAiICByZXR1cm4gJGNsYXNzX25hbWUkOjokY2FtZWxfb25lb2ZfbmFtZSRDYXNlKCIKKyAgICAgICAgIl9vbmVvZl9jYXNlX1skb25lb2ZfaW5kZXgkXSk7XG4iCisgICAgICAgICJ9XG4iKTsKKyAgfQorfQorCit2b2lkIE1lc3NhZ2VHZW5lcmF0b3I6OgorR2VuZXJhdGVEZXNjcmlwdG9yRGVjbGFyYXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIGlmICghSXNNYXBFbnRyeU1lc3NhZ2UoZGVzY3JpcHRvcl8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiAkbmFtZSRfZGVzY3JpcHRvcl8gPSBOVUxMO1xuIgorICAgICAgImNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKlxuIgorICAgICAgIiAgJG5hbWUkX3JlZmxlY3Rpb25fID0gTlVMTDtcbiIsCisgICAgICAibmFtZSIsIGNsYXNzbmFtZV8pOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgImNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogJG5hbWUkX2Rlc2NyaXB0b3JfID0gTlVMTDtcbiIsCisgICAgICAibmFtZSIsIGNsYXNzbmFtZV8pOworICB9CisKKyAgLy8gR2VuZXJhdGUgb25lb2YgZGVmYXVsdCBpbnN0YW5jZSBmb3IgcmVmbGVjdGlvbiB1c2FnZS4KKyAgaWYgKGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsX2NvdW50KCkgPiAwKSB7CisgICAgcHJpbnRlci0+UHJpbnQoInN0cnVjdCAkbmFtZSRPbmVvZkluc3RhbmNlIHtcbiIsCisgICAgICAgICAgICAgICAgICAgIm5hbWUiLCBjbGFzc25hbWVfKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsX2NvdW50KCk7IGkrKykgeworICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKS0+ZmllbGRfY291bnQoKTsgaisrKSB7CisgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKS0+ZmllbGQoaik7CisgICAgICAgIHByaW50ZXItPlByaW50KCIgICIpOworICAgICAgICBpZiAoZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UgfHwKKyAgICAgICAgICAgIChmaWVsZC0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HICYmCisgICAgICAgICAgICAgRWZmZWN0aXZlU3RyaW5nQ1R5cGUoZmllbGQpICE9IEZpZWxkT3B0aW9uczo6U1RSSU5HKSkgeworICAgICAgICAgIHByaW50ZXItPlByaW50KCJjb25zdCAiKTsKKyAgICAgICAgfQorICAgICAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZmllbGQpLkdlbmVyYXRlUHJpdmF0ZU1lbWJlcnMocHJpbnRlcik7CisgICAgICB9CisgICAgfQorCisgICAgcHJpbnRlci0+UHJpbnQoIn0qICRuYW1lJF9kZWZhdWx0X29uZW9mX2luc3RhbmNlXyA9IE5VTEw7XG4iLAorICAgICAgICAgICAgICAgICAgICJuYW1lIiwgY2xhc3NuYW1lXyk7CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5uZXN0ZWRfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBuZXN0ZWRfZ2VuZXJhdG9yc19baV0tPkdlbmVyYXRlRGVzY3JpcHRvckRlY2xhcmF0aW9ucyhwcmludGVyKTsKKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmVudW1fdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yKiAkbmFtZSRfZGVzY3JpcHRvcl8gPSBOVUxMO1xuIiwKKyAgICAgICJuYW1lIiwgQ2xhc3NOYW1lKGRlc2NyaXB0b3JfLT5lbnVtX3R5cGUoaSksIGZhbHNlKSk7CisgIH0KK30KKwordm9pZCBNZXNzYWdlR2VuZXJhdG9yOjoKK0dlbmVyYXRlRGVzY3JpcHRvckluaXRpYWxpemVyKGlvOjpQcmludGVyKiBwcmludGVyLCBpbnQgaW5kZXgpIHsKKyAgLy8gVE9ETyhrZW50b24pOiAgUGFzc2luZyB0aGUgaW5kZXggdG8gdGhpcyBtZXRob2QgaXMgcmVkdW5kYW50OyBqdXN0IHVzZQorICAvLyAgIGRlc2NyaXB0b3JfLT5pbmRleCgpIGluc3RlYWQuCisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyczsKKyAgdmFyc1siY2xhc3NuYW1lIl0gPSBjbGFzc25hbWVfOworICB2YXJzWyJpbmRleCJdID0gU2ltcGxlSXRvYShpbmRleCk7CisKKyAgLy8gT2J0YWluIHRoZSBkZXNjcmlwdG9yIGZyb20gdGhlIHBhcmVudCdzIGRlc2NyaXB0b3IuCisgIGlmIChkZXNjcmlwdG9yXy0+Y29udGFpbmluZ190eXBlKCkgPT0gTlVMTCkgeworICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAiJGNsYXNzbmFtZSRfZGVzY3JpcHRvcl8gPSBmaWxlLT5tZXNzYWdlX3R5cGUoJGluZGV4JCk7XG4iKTsKKyAgfSBlbHNlIHsKKyAgICB2YXJzWyJwYXJlbnQiXSA9IENsYXNzTmFtZShkZXNjcmlwdG9yXy0+Y29udGFpbmluZ190eXBlKCksIGZhbHNlKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgIiRjbGFzc25hbWUkX2Rlc2NyaXB0b3JfID0gIgorICAgICAgICAiJHBhcmVudCRfZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlKCRpbmRleCQpO1xuIik7CisgIH0KKworICBpZiAoSXNNYXBFbnRyeU1lc3NhZ2UoZGVzY3JpcHRvcl8pKSByZXR1cm47CisKKyAgLy8gR2VuZXJhdGUgdGhlIG9mZnNldHMuCisgIEdlbmVyYXRlT2Zmc2V0cyhwcmludGVyKTsKKworICBjb25zdCBib29sIHBhc3NfcG9vbF9hbmRfZmFjdG9yeSA9IGZhbHNlOworICB2YXJzWyJmbiJdID0gcGFzc19wb29sX2FuZF9mYWN0b3J5ID8KKyAgICAgICJuZXcgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24iIDoKKyAgICAgICI6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbiIKKyAgICAgICI6Ok5ld0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uIjsKKyAgLy8gQ29uc3RydWN0IHRoZSByZWZsZWN0aW9uIG9iamVjdC4KKyAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAiJGNsYXNzbmFtZSRfcmVmbGVjdGlvbl8gPVxuIgorICAgICIgICRmbiQoXG4iCisgICAgIiAgICAkY2xhc3NuYW1lJF9kZXNjcmlwdG9yXyxcbiIKKyAgICAiICAgICRjbGFzc25hbWUkOjpkZWZhdWx0X2luc3RhbmNlXyxcbiIKKyAgICAiICAgICRjbGFzc25hbWUkX29mZnNldHNfLFxuIik7CisgIGlmICghSGFzRmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIC8vIElmIHdlIGRvbid0IGhhdmUgZmllbGQgcHJlc2VuY2UsIHRoZW4gX2hhc19iaXRzXyBkb2VzIG5vdCBleGlzdC4KKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICIgICAgLTEsXG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICIgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVCgkY2xhc3NuYW1lJCwgX2hhc19iaXRzX1swXSksXG4iKTsKKyAgfQorCisgIC8vIFVua25vd24gZmllbGQgb2Zmc2V0OiBlaXRoZXIgcG9pbnRzIHRvIHRoZSB1bmtub3duIGZpZWxkIHNldCBpZiBlbWJlZGRlZAorICAvLyBkaXJlY3RseSwgb3IgaW5kaWNhdGVzIHRoYXQgdGhlIHVua25vd24gZmllbGQgc2V0IGlzIHN0b3JlZCBhcyBwYXJ0IG9mIHRoZQorICAvLyBpbnRlcm5hbCBtZXRhZGF0YSBpZiBub3QuCisgIGlmIChVc2VVbmtub3duRmllbGRTZXQoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICIgICAgLTEsXG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICIgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVCgiCisgICAgICAiJGNsYXNzbmFtZSQsIF91bmtub3duX2ZpZWxkc18pLFxuIik7CisgIH0KKworICBpZiAoZGVzY3JpcHRvcl8tPmV4dGVuc2lvbl9yYW5nZV9jb3VudCgpID4gMCkgeworICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAiICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoIgorICAgICAgICAiJGNsYXNzbmFtZSQsIF9leHRlbnNpb25zXyksXG4iKTsKKyAgfSBlbHNlIHsKKyAgICAvLyBObyBleHRlbnNpb25zLgorICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAiICAgIC0xLFxuIik7CisgIH0KKworICBpZiAoZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2xfY291bnQoKSA+IDApIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICIgICAgJGNsYXNzbmFtZSRfZGVmYXVsdF9vbmVvZl9pbnN0YW5jZV8sXG4iCisgICAgIiAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKCIKKyAgICAgICIkY2xhc3NuYW1lJCwgX29uZW9mX2Nhc2VfWzBdKSxcbiIpOworICB9CisKKyAgaWYgKHBhc3NfcG9vbF9hbmRfZmFjdG9yeSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclBvb2w6OmdlbmVyYXRlZF9wb29sKCksXG4iKTsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAgICAgICAgICAgICAgICAiICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZUZhY3Rvcnk6OmdlbmVyYXRlZF9mYWN0b3J5KCksXG4iKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgIiAgICBzaXplb2YoJGNsYXNzbmFtZSQpLFxuIik7CisKKyAgLy8gQXJlbmEgb2Zmc2V0OiBlaXRoZXIgYW4gb2Zmc2V0IHRvIHRoZSBtZXRhZGF0YSBzdHJ1Y3QgdGhhdCBjb250YWlucyB0aGUKKyAgLy8gYXJlbmEgcG9pbnRlciBhbmQgdW5rbm93biBmaWVsZCBzZXQgKGluIGEgc3BhY2UtZWZmaWNpZW50IHdheSkgaWYgd2UgdXNlCisgIC8vIHRoYXQgaW1wbGVtZW50YXRpb24gc3RyYXRlZ3ksIG9yIGFuIG9mZnNldCBkaXJlY3RseSB0byB0aGUgYXJlbmEgcG9pbnRlciBpZgorICAvLyBub3QgKGJlY2F1c2UgZS5nLiB3ZSBkb24ndCBoYXZlIGFuIHVua25vd24gZmllbGQgc2V0KS4KKyAgaWYgKFVzZVVua25vd25GaWVsZFNldChkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgIiAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKCIKKyAgICAiJGNsYXNzbmFtZSQsIF9pbnRlcm5hbF9tZXRhZGF0YV8pLFxuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAiICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoIgorICAgICIkY2xhc3NuYW1lJCwgX2FyZW5hXyksXG4iKTsKKyAgfQorCisgIC8vIGlzX2RlZmF1bHRfaW5zdGFuY2VfIG9mZnNldC4KKyAgaWYgKEhhc0ZpZWxkUHJlc2VuY2UoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICIgICAgLTEpO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAiICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoIgorICAgICIkY2xhc3NuYW1lJCwgX2lzX2RlZmF1bHRfaW5zdGFuY2VfKSk7XG4iKTsKKyAgfQorCisgIC8vIEhhbmRsZSBuZXN0ZWQgdHlwZXMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlX2NvdW50KCk7IGkrKykgeworICAgIG5lc3RlZF9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVEZXNjcmlwdG9ySW5pdGlhbGl6ZXIocHJpbnRlciwgaSk7CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5lbnVtX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgZW51bV9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVEZXNjcmlwdG9ySW5pdGlhbGl6ZXIocHJpbnRlciwgaSk7CisgIH0KK30KKwordm9pZCBNZXNzYWdlR2VuZXJhdG9yOjoKK0dlbmVyYXRlVHlwZVJlZ2lzdHJhdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgLy8gUmVnaXN0ZXIgdGhpcyBtZXNzYWdlIHR5cGUgd2l0aCB0aGUgbWVzc2FnZSBmYWN0b3J5LgorICBpZiAoIUlzTWFwRW50cnlNZXNzYWdlKGRlc2NyaXB0b3JfKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZUZhY3Rvcnk6OkludGVybmFsUmVnaXN0ZXJHZW5lcmF0ZWRNZXNzYWdlKFxuIgorICAgICAgIiAgICAkY2xhc3NuYW1lJF9kZXNjcmlwdG9yXywgJiRjbGFzc25hbWUkOjpkZWZhdWx0X2luc3RhbmNlKCkpO1xuIiwKKyAgICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfKTsKKyAgfQorICBlbHNlIHsKKyAgICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcnM7CisgICAgQ29sbGVjdE1hcEluZm8oZGVzY3JpcHRvcl8sICZ2YXJzKTsKKyAgICB2YXJzWyJjbGFzc25hbWUiXSA9IGNsYXNzbmFtZV87CisKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHZhbCA9IGRlc2NyaXB0b3JfLT5GaW5kRmllbGRCeU5hbWUoInZhbHVlIik7CisgICAgaWYgKGRlc2NyaXB0b3JfLT5maWxlKCktPnN5bnRheCgpID09IEZpbGVEZXNjcmlwdG9yOjpTWU5UQVhfUFJPVE8yICYmCisgICAgICAgIHZhbC0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9FTlVNKSB7CisgICAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBkZWZhdWx0X3ZhbHVlID0gdmFsLT5kZWZhdWx0X3ZhbHVlX2VudW0oKTsKKyAgICAgIHZhcnNbImRlZmF1bHRfZW51bV92YWx1ZSJdID0gSW50MzJUb1N0cmluZyhkZWZhdWx0X3ZhbHVlLT5udW1iZXIoKSk7CisgICAgfSBlbHNlIHsKKyAgICAgIHZhcnNbImRlZmF1bHRfZW51bV92YWx1ZSJdID0gIjAiOworICAgIH0KKworICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAiOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZE1lc3NhZ2UoXG4iCisgICAgICAiICAgICAgJGNsYXNzbmFtZSRfZGVzY3JpcHRvcl8sXG4iCisgICAgICAiICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6TWFwRW50cnk8XG4iCisgICAgICAiICAgICAgICAgICRrZXkkLFxuIgorICAgICAgIiAgICAgICAgICAkdmFsJCxcbiIKKyAgICAgICIgICAgICAgICAgJGtleV93aXJlX3R5cGUkLFxuIgorICAgICAgIiAgICAgICAgICAkdmFsX3dpcmVfdHlwZSQsXG4iCisgICAgICAiICAgICAgICAgICRkZWZhdWx0X2VudW1fdmFsdWUkPjo6Q3JlYXRlRGVmYXVsdEluc3RhbmNlKFxuIgorICAgICAgIiAgICAgICAgICAgICAgJGNsYXNzbmFtZSRfZGVzY3JpcHRvcl8pKTtcbiIpOworICB9CisKKyAgLy8gSGFuZGxlIG5lc3RlZCB0eXBlcy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+bmVzdGVkX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgbmVzdGVkX2dlbmVyYXRvcnNfW2ldLT5HZW5lcmF0ZVR5cGVSZWdpc3RyYXRpb25zKHByaW50ZXIpOworICB9Cit9CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6CitHZW5lcmF0ZURlZmF1bHRJbnN0YW5jZUFsbG9jYXRvcihpbzo6UHJpbnRlciogcHJpbnRlcikgeworICAvLyBDb25zdHJ1Y3QgdGhlIGRlZmF1bHQgaW5zdGFuY2VzIG9mIGFsbCBmaWVsZHMsIGFzIHRoZXkgd2lsbCBiZSB1c2VkCisgIC8vIHdoZW4gY3JlYXRpbmcgdGhlIGRlZmF1bHQgaW5zdGFuY2Ugb2YgdGhlIGVudGlyZSBtZXNzYWdlLgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZGVzY3JpcHRvcl8tPmZpZWxkKGkpKQorICAgICAgICAgICAgICAgICAgICAgLkdlbmVyYXRlRGVmYXVsdEluc3RhbmNlQWxsb2NhdG9yKHByaW50ZXIpOworICB9CisKKyAgaWYgKElzTWFwRW50cnlNZXNzYWdlKGRlc2NyaXB0b3JfKSkgcmV0dXJuOworCisgIC8vIENvbnN0cnVjdCB0aGUgZGVmYXVsdCBpbnN0YW5jZS4gIFdlIGNhbid0IGNhbGwgSW5pdEFzRGVmYXVsdEluc3RhbmNlKCkgeWV0CisgIC8vIGJlY2F1c2Ugd2UgbmVlZCB0byBtYWtlIHN1cmUgYWxsIGRlZmF1bHQgaW5zdGFuY2VzIHRoYXQgdGhpcyBvbmUgbWlnaHQKKyAgLy8gZGVwZW5kIG9uIGFyZSBjb25zdHJ1Y3RlZCBmaXJzdC4KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIiRjbGFzc25hbWUkOjpkZWZhdWx0X2luc3RhbmNlXyA9IG5ldyAkY2xhc3NuYW1lJCgpO1xuIiwKKyAgICAiY2xhc3NuYW1lIiwgY2xhc3NuYW1lXyk7CisKKyAgaWYgKChkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbF9jb3VudCgpID4gMCkgJiYKKyAgICAgIEhhc0Rlc2NyaXB0b3JNZXRob2RzKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgIiRjbGFzc25hbWUkX2RlZmF1bHRfb25lb2ZfaW5zdGFuY2VfID0gbmV3ICRjbGFzc25hbWUkT25lb2ZJbnN0YW5jZSgpO1xuIiwKKyAgICAiY2xhc3NuYW1lIiwgY2xhc3NuYW1lXyk7CisgIH0KKworICAvLyBIYW5kbGUgbmVzdGVkIHR5cGVzLgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5uZXN0ZWRfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBuZXN0ZWRfZ2VuZXJhdG9yc19baV0tPkdlbmVyYXRlRGVmYXVsdEluc3RhbmNlQWxsb2NhdG9yKHByaW50ZXIpOworICB9CisKK30KKwordm9pZCBNZXNzYWdlR2VuZXJhdG9yOjoKK0dlbmVyYXRlRGVmYXVsdEluc3RhbmNlSW5pdGlhbGl6ZXIoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIiRjbGFzc25hbWUkOjpkZWZhdWx0X2luc3RhbmNlXy0+SW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7XG4iLAorICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfKTsKKworICAvLyBSZWdpc3RlciBleHRlbnNpb25zLgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5leHRlbnNpb25fY291bnQoKTsgaSsrKSB7CisgICAgZXh0ZW5zaW9uX2dlbmVyYXRvcnNfW2ldLT5HZW5lcmF0ZVJlZ2lzdHJhdGlvbihwcmludGVyKTsKKyAgfQorCisgIC8vIEhhbmRsZSBuZXN0ZWQgdHlwZXMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlX2NvdW50KCk7IGkrKykgeworICAgIC8vIG1hcCBlbnRyeSBtZXNzYWdlIGRvZXNuJ3QgbmVlZCB0byBpbml0aWFsaXplIGRlZmF1bHQgaW5zdGFuY2UgbWFudWFsbHkuCisgICAgLy8gU2luY2UgbWFwIGVudHJ5IG1lc3NhZ2UgY2Fubm90IGJlIGEgdG9wIGxldmVsIGNsYXNzLCB3ZSBqdXN0IG5lZWQgdG8KKyAgICAvLyBhdm9pZCBjYWxsaW5nIERlZmF1bHRJbnN0YW5jZUluaXRpYWxpemVyIGhlcmUuCisgICAgaWYgKElzTWFwRW50cnlNZXNzYWdlKGRlc2NyaXB0b3JfLT5uZXN0ZWRfdHlwZShpKSkpIGNvbnRpbnVlOworICAgIG5lc3RlZF9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVEZWZhdWx0SW5zdGFuY2VJbml0aWFsaXplcihwcmludGVyKTsKKyAgfQorfQorCit2b2lkIE1lc3NhZ2VHZW5lcmF0b3I6OgorR2VuZXJhdGVTaHV0ZG93bkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgImRlbGV0ZSAkY2xhc3NuYW1lJDo6ZGVmYXVsdF9pbnN0YW5jZV87XG4iLAorICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfKTsKKworICBpZiAoSGFzRGVzY3JpcHRvck1ldGhvZHMoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBpZiAoZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2xfY291bnQoKSA+IDApIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiZGVsZXRlICRjbGFzc25hbWUkX2RlZmF1bHRfb25lb2ZfaW5zdGFuY2VfO1xuIiwKKyAgICAgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8pOworICAgIH0KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJkZWxldGUgJGNsYXNzbmFtZSRfcmVmbGVjdGlvbl87XG4iLAorICAgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8pOworICB9CisKKyAgLy8gSGFuZGxlIGRlZmF1bHQgaW5zdGFuY2VzIG9mIGZpZWxkcy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGRlc2NyaXB0b3JfLT5maWVsZChpKSkKKyAgICAgICAgICAgICAgICAgICAgIC5HZW5lcmF0ZVNodXRkb3duQ29kZShwcmludGVyKTsKKyAgfQorCisgIC8vIEhhbmRsZSBuZXN0ZWQgdHlwZXMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlX2NvdW50KCk7IGkrKykgeworICAgIGlmIChJc01hcEVudHJ5TWVzc2FnZShkZXNjcmlwdG9yXy0+bmVzdGVkX3R5cGUoaSkpKSBjb250aW51ZTsKKyAgICBuZXN0ZWRfZ2VuZXJhdG9yc19baV0tPkdlbmVyYXRlU2h1dGRvd25Db2RlKHByaW50ZXIpOworICB9Cit9CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUNsYXNzTWV0aG9kcyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICAvLyBtdXRhYmxlX3Vua25vd25fZmllbGRzIHdyYXBwZXIgZnVuY3Rpb24gZm9yIExhenlTdHJpbmdPdXRwdXRTdHJlYW0KKyAgLy8gY2FsbGJhY2suCisgIGlmICghVXNlVW5rbm93bkZpZWxkU2V0KGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJzdGF0aWMgOjpzdGQ6OnN0cmluZyogTXV0YWJsZVVua25vd25GaWVsZHNGb3IkY2xhc3NuYW1lJChcbiIKKyAgICAgICAgIiAgICAkY2xhc3NuYW1lJCogcHRyKSB7XG4iCisgICAgICAgICIgIHJldHVybiBwdHItPm11dGFibGVfdW5rbm93bl9maWVsZHMoKTtcbiIKKyAgICAgICAgIn1cbiIKKyAgICAgICAgIlxuIiwKKyAgICAgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8pOworICB9CisgIGlmIChJc0FueU1lc3NhZ2UoZGVzY3JpcHRvcl8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAidm9pZCAkY2xhc3NuYW1lJDo6UGFja0Zyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBtZXNzYWdlKSB7XG4iCisgICAgICAiICBfYW55X21ldGFkYXRhXy5QYWNrRnJvbShtZXNzYWdlKTtcbiIKKyAgICAgICJ9XG4iCisgICAgICAiXG4iCisgICAgICAiYm9vbCAkY2xhc3NuYW1lJDo6VW5wYWNrVG8oOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKiBtZXNzYWdlKSBjb25zdCB7XG4iCisgICAgICAiICByZXR1cm4gX2FueV9tZXRhZGF0YV8uVW5wYWNrVG8obWVzc2FnZSk7XG4iCisgICAgICAifVxuIgorICAgICAgIlxuIiwKKyAgICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfKTsKKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmVudW1fdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBlbnVtX2dlbmVyYXRvcnNfW2ldLT5HZW5lcmF0ZU1ldGhvZHMocHJpbnRlcik7CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5uZXN0ZWRfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICAvLyBtYXAgZW50cnkgbWVzc2FnZSBkb2Vzbid0IG5lZWQgY2xhc3MgbWV0aG9kcy4gU2luY2UgbWFwIGVudHJ5IG1lc3NhZ2UKKyAgICAvLyBjYW5ub3QgYmUgYSB0b3AgbGV2ZWwgY2xhc3MsIHdlIGp1c3QgbmVlZCB0byBhdm9pZCBjYWxsaW5nCisgICAgLy8gR2VuZXJhdGVDbGFzc01ldGhvZHMgaGVyZS4KKyAgICBpZiAoSXNNYXBFbnRyeU1lc3NhZ2UoZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlKGkpKSkgY29udGludWU7CisgICAgbmVzdGVkX2dlbmVyYXRvcnNfW2ldLT5HZW5lcmF0ZUNsYXNzTWV0aG9kcyhwcmludGVyKTsKKyAgICBwcmludGVyLT5QcmludCgiXG4iKTsKKyAgICBwcmludGVyLT5QcmludChrVGhpblNlcGFyYXRvcik7CisgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisgIH0KKworICAvLyBHZW5lcmF0ZSBub24taW5saW5lIGZpZWxkIGRlZmluaXRpb25zLgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZGVzY3JpcHRvcl8tPmZpZWxkKGkpKQorICAgICAgICAgICAgICAgICAgICAgLkdlbmVyYXRlTm9uSW5saW5lQWNjZXNzb3JEZWZpbml0aW9ucyhwcmludGVyKTsKKyAgfQorCisgIC8vIEdlbmVyYXRlIGZpZWxkIG51bWJlciBjb25zdGFudHMuCisgIHByaW50ZXItPlByaW50KCIjaWYgIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDBcbiIpOworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IgKmZpZWxkID0gZGVzY3JpcHRvcl8tPmZpZWxkKGkpOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgImNvbnN0IGludCAkY2xhc3NuYW1lJDo6JGNvbnN0YW50X25hbWUkO1xuIiwKKyAgICAgICJjbGFzc25hbWUiLCBDbGFzc05hbWUoRmllbGRTY29wZShmaWVsZCksIGZhbHNlKSwKKyAgICAgICJjb25zdGFudF9uYW1lIiwgRmllbGRDb25zdGFudE5hbWUoZmllbGQpKTsKKyAgfQorICBwcmludGVyLT5QcmludCgKKyAgICAiI2VuZGlmICAvLyAhZGVmaW5lZChfTVNDX1ZFUikgfHwgX01TQ19WRVIgPj0gMTkwMFxuIgorICAgICJcbiIpOworCisgIC8vIERlZmluZSBleHRlbnNpb24gaWRlbnRpZmllcnMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmV4dGVuc2lvbl9jb3VudCgpOyBpKyspIHsKKyAgICBleHRlbnNpb25fZ2VuZXJhdG9yc19baV0tPkdlbmVyYXRlRGVmaW5pdGlvbihwcmludGVyKTsKKyAgfQorCisgIEdlbmVyYXRlU3RydWN0b3JzKHByaW50ZXIpOworICBwcmludGVyLT5QcmludCgiXG4iKTsKKworICBpZiAoZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2xfY291bnQoKSA+IDApIHsKKyAgICBHZW5lcmF0ZU9uZW9mQ2xlYXIocHJpbnRlcik7CisgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisgIH0KKworICBpZiAoSGFzR2VuZXJhdGVkTWV0aG9kcyhkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIEdlbmVyYXRlQ2xlYXIocHJpbnRlcik7CisgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisKKyAgICBHZW5lcmF0ZU1lcmdlRnJvbUNvZGVkU3RyZWFtKHByaW50ZXIpOworICAgIHByaW50ZXItPlByaW50KCJcbiIpOworCisgICAgR2VuZXJhdGVTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMocHJpbnRlcik7CisgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisKKyAgICBpZiAoSGFzRmFzdEFycmF5U2VyaWFsaXphdGlvbihkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgICAgR2VuZXJhdGVTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KHByaW50ZXIpOworICAgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisgICAgfQorCisgICAgR2VuZXJhdGVCeXRlU2l6ZShwcmludGVyKTsKKyAgICBwcmludGVyLT5QcmludCgiXG4iKTsKKworICAgIEdlbmVyYXRlTWVyZ2VGcm9tKHByaW50ZXIpOworICAgIHByaW50ZXItPlByaW50KCJcbiIpOworCisgICAgR2VuZXJhdGVDb3B5RnJvbShwcmludGVyKTsKKyAgICBwcmludGVyLT5QcmludCgiXG4iKTsKKworICAgIEdlbmVyYXRlSXNJbml0aWFsaXplZChwcmludGVyKTsKKyAgICBwcmludGVyLT5QcmludCgiXG4iKTsKKyAgfQorCisgIEdlbmVyYXRlU3dhcChwcmludGVyKTsKKyAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisKKyAgaWYgKEhhc0Rlc2NyaXB0b3JNZXRob2RzKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSAkY2xhc3NuYW1lJDo6R2V0TWV0YWRhdGEoKSBjb25zdCB7XG4iCisgICAgICAiICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTtcbiIKKyAgICAgICIgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgbWV0YWRhdGE7XG4iCisgICAgICAiICBtZXRhZGF0YS5kZXNjcmlwdG9yID0gJGNsYXNzbmFtZSRfZGVzY3JpcHRvcl87XG4iCisgICAgICAiICBtZXRhZGF0YS5yZWZsZWN0aW9uID0gJGNsYXNzbmFtZSRfcmVmbGVjdGlvbl87XG4iCisgICAgICAiICByZXR1cm4gbWV0YWRhdGE7XG4iCisgICAgICAifVxuIgorICAgICAgIlxuIiwKKyAgICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICI6OnN0ZDo6c3RyaW5nICRjbGFzc25hbWUkOjpHZXRUeXBlTmFtZSgpIGNvbnN0IHtcbiIKKyAgICAgICIgIHJldHVybiBcIiR0eXBlX25hbWUkXCI7XG4iCisgICAgICAifVxuIgorICAgICAgIlxuIiwKKyAgICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfLAorICAgICAgInR5cGVfbmFtZSIsIGRlc2NyaXB0b3JfLT5mdWxsX25hbWUoKSk7CisgIH0KKworfQorCit2b2lkIE1lc3NhZ2VHZW5lcmF0b3I6OgorR2VuZXJhdGVPZmZzZXRzKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgICJzdGF0aWMgY29uc3QgaW50ICRjbGFzc25hbWUkX29mZnNldHNfWyRmaWVsZF9jb3VudCRdID0ge1xuIiwKKyAgICAiY2xhc3NuYW1lIiwgY2xhc3NuYW1lXywKKyAgICAiZmllbGRfY291bnQiLCBTaW1wbGVJdG9hKG1heCgKKyAgICAgICAgMSwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCkgKyBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbF9jb3VudCgpKSkpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvcl8tPmZpZWxkKGkpOworICAgIGlmIChmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpKSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAiUFJPVE8yX0dFTkVSQVRFRF9ERUZBVUxUX09ORU9GX0ZJRUxEX09GRlNFVCgiCisgICAgICAgICAgIiRjbGFzc25hbWUkX2RlZmF1bHRfb25lb2ZfaW5zdGFuY2VfLCAkbmFtZSRfKSxcbiIsCisgICAgICAgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8sCisgICAgICAgICAgIm5hbWUiLCBGaWVsZE5hbWUoZmllbGQpKTsKKyAgICB9IGVsc2UgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgIkdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoJGNsYXNzbmFtZSQsICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJG5hbWUkXyksXG4iLAorICAgICAgICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfLAorICAgICAgICAgICJuYW1lIiwgRmllbGROYW1lKGZpZWxkKSk7CisgICAgfQorICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBPbmVvZkRlc2NyaXB0b3IqIG9uZW9mID0gZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSk7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVCgkY2xhc3NuYW1lJCwgJG5hbWUkXyksXG4iLAorICAgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8sCisgICAgICAibmFtZSIsIG9uZW9mLT5uYW1lKCkpOworICB9CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgifTtcbiIpOworfQorCit2b2lkIE1lc3NhZ2VHZW5lcmF0b3I6OgorR2VuZXJhdGVTaGFyZWRDb25zdHJ1Y3RvckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgInZvaWQgJGNsYXNzbmFtZSQ6OlNoYXJlZEN0b3IoKSB7XG4iLAorICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgaWYgKCFIYXNGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiICBfaXNfZGVmYXVsdF9pbnN0YW5jZV8gPSBmYWxzZTtcbiIpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQoU3RyQ2F0KAorICAgICAgdXNlc19zdHJpbmdfID8gIjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nKCk7XG4iIDogIiIsCisgICAgICAiX2NhY2hlZF9zaXplXyA9IDA7XG4iKS5jX3N0cigpKTsKKworICBpZiAoUHJlc2VydmVVbmtub3duRmllbGRzKGRlc2NyaXB0b3JfKSAmJgorICAgICAgIVVzZVVua25vd25GaWVsZFNldChkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiX3Vua25vd25fZmllbGRzXy5VbnNhZmVTZXREZWZhdWx0KFxuIgorICAgICAgICAiICAgICY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7XG4iKTsKKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGlmICghZGVzY3JpcHRvcl8tPmZpZWxkKGkpLT5jb250YWluaW5nX29uZW9mKCkpIHsKKyAgICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChkZXNjcmlwdG9yXy0+ZmllbGQoaSkpCisgICAgICAgICAgLkdlbmVyYXRlQ29uc3RydWN0b3JDb2RlKHByaW50ZXIpOworICAgIH0KKyAgfQorCisgIGlmIChIYXNGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiOjptZW1zZXQoX2hhc19iaXRzXywgMCwgc2l6ZW9mKF9oYXNfYml0c18pKTtcbiIpOworICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbF9jb3VudCgpOyBpKyspIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgImNsZWFyX2hhc18kb25lb2ZfbmFtZSQoKTtcbiIsCisgICAgICAgICJvbmVvZl9uYW1lIiwgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPm5hbWUoKSk7CisgIH0KKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KCJ9XG5cbiIpOworfQorCit2b2lkIE1lc3NhZ2VHZW5lcmF0b3I6OgorR2VuZXJhdGVTaGFyZWREZXN0cnVjdG9yQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICAidm9pZCAkY2xhc3NuYW1lJDo6U2hhcmVkRHRvcigpIHtcbiIsCisgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8pOworICBwcmludGVyLT5JbmRlbnQoKTsKKyAgaWYgKFN1cHBvcnRzQXJlbmFzKGRlc2NyaXB0b3JfKSkgeworICAgIC8vIERvIG5vdGhpbmcgd2hlbiB0aGUgbWVzc2FnZSBpcyBhbGxvY2F0ZWQgaW4gYW4gYXJlbmEuCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiaWYgKEdldEFyZW5hTm9WaXJ0dWFsKCkgIT0gTlVMTCkge1xuIgorICAgICAgIiAgcmV0dXJuO1xuIgorICAgICAgIn1cbiIKKyAgICAgICJcbiIpOworICB9CisKKyAgLy8gV3JpdGUgdGhlIGRlc2N0cnVjdG9yIGZvciBfdW5rbm93bl9maWVsZHNfIGluIGxpdGUgcnVudGltZS4KKyAgaWYgKFByZXNlcnZlVW5rbm93bkZpZWxkcyhkZXNjcmlwdG9yXykgJiYKKyAgICAgICFVc2VVbmtub3duRmllbGRTZXQoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBpZiAoU3VwcG9ydHNBcmVuYXMoZGVzY3JpcHRvcl8pKSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAiX3Vua25vd25fZmllbGRzXy5EZXN0cm95KFxuIgorICAgICAgICAgICIgICAgJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLFxuIgorICAgICAgICAgICIgICAgR2V0QXJlbmFOb1ZpcnR1YWwoKSk7XG4iKTsKKyAgICB9IGVsc2UgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgIl91bmtub3duX2ZpZWxkc18uRGVzdHJveU5vQXJlbmEoXG4iCisgICAgICAgICAgIiAgICAmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpO1xuIik7CisgICAgfQorICB9CisKKyAgLy8gV3JpdGUgdGhlIGRlc3RydWN0b3JzIGZvciBlYWNoIGZpZWxkIGV4Y2VwdCBvbmVvZiBtZW1iZXJzLgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBpZiAoIWRlc2NyaXB0b3JfLT5maWVsZChpKS0+Y29udGFpbmluZ19vbmVvZigpKSB7CisgICAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZGVzY3JpcHRvcl8tPmZpZWxkKGkpKQorICAgICAgICAgICAgICAgICAgICAgICAuR2VuZXJhdGVEZXN0cnVjdG9yQ29kZShwcmludGVyKTsKKyAgICB9CisgIH0KKworICAvLyBHZW5lcmF0ZSBjb2RlIHRvIGRlc3RydWN0IG9uZW9mcy4gQ2xlYXJpbmcgc2hvdWxkIGRvIHRoZSB3b3JrLgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsX2NvdW50KCk7IGkrKykgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiaWYgKGhhc18kb25lb2ZfbmFtZSQoKSkge1xuIgorICAgICAgICAiICBjbGVhcl8kb25lb2ZfbmFtZSQoKTtcbiIKKyAgICAgICAgIn1cbiIsCisgICAgICAgICJvbmVvZl9uYW1lIiwgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPm5hbWUoKSk7CisgIH0KKworICBQcmludEhhbmRsaW5nT3B0aW9uYWxTdGF0aWNJbml0aWFsaXplcnMoCisgICAgZGVzY3JpcHRvcl8tPmZpbGUoKSwgcHJpbnRlciwKKyAgICAvLyBXaXRoIHN0YXRpYyBpbml0aWFsaXplcnMuCisgICAgImlmICh0aGlzICE9IGRlZmF1bHRfaW5zdGFuY2VfKSB7XG4iLAorICAgIC8vIFdpdGhvdXQuCisgICAgImlmICh0aGlzICE9ICZkZWZhdWx0X2luc3RhbmNlKCkpIHtcbiIpOworCisgIC8vIFdlIG5lZWQgdG8gZGVsZXRlIGFsbCBlbWJlZGRlZCBtZXNzYWdlcy4KKyAgLy8gVE9ETyhrZW50b24pOiAgSWYgd2UgbWFrZSB1bnNldCBtZXNzYWdlcyBwb2ludCBhdCBkZWZhdWx0IGluc3RhbmNlcworICAvLyAgIGluc3RlYWQgb2YgTlVMTCwgdGhlbiBpdCB3b3VsZCBtYWtlIHNlbnNlIHRvIG1vdmUgdGhpcyBjb2RlIGludG8KKyAgLy8gICBNZXNzYWdlRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlRGVzdHJ1Y3RvckNvZGUoKS4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3JfLT5maWVsZChpKTsKKworICAgIGlmICghZmllbGQtPmlzX3JlcGVhdGVkKCkgJiYKKyAgICAgICAgZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UpIHsKKyAgICAgIC8vIFNraXAgb25lb2YgbWVtYmVycworICAgICAgaWYgKCFmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpKSB7CisgICAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICAgIiAgZGVsZXRlICRuYW1lJF87XG4iLAorICAgICAgICAgICAgIm5hbWUiLCBGaWVsZE5hbWUoZmllbGQpKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KAorICAgICIgIH1cbiIKKyAgICAifVxuIgorICAgICJcbiIpOworfQorCit2b2lkIE1lc3NhZ2VHZW5lcmF0b3I6OgorR2VuZXJhdGVBcmVuYURlc3RydWN0b3JDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIC8vIEdlbmVyYXRlIHRoZSBBcmVuYUR0b3IoKSBtZXRob2QuIFRyYWNrIHdoZXRoZXIgYW55IGZpZWxkcyBhY3R1YWxseSBwcm9kdWNlZAorICAvLyBjb2RlIHRoYXQgbmVlZHMgdG8gYmUgY2FsbGVkLgorICBwcmludGVyLT5QcmludCgKKyAgICAgICJ2b2lkICRjbGFzc25hbWUkOjpBcmVuYUR0b3Iodm9pZCogb2JqZWN0KSB7XG4iLAorICAgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8pOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICAvLyBUaGlzIGNvZGUgaXMgcGxhY2VkIGluc2lkZSBhIHN0YXRpYyBtZXRob2QsIHJhdGhlciB0aGFuIGFuIG9yZGluYXJ5IG9uZSwKKyAgLy8gc2luY2UgdGhhdCBzaW1wbGlmaWVzIEFyZW5hJ3MgZGVzdHJ1Y3RvciBsaXN0IChvcmRpbmFyeSBmdW5jdGlvbiBwb2ludGVycworICAvLyByYXRoZXIgdGhhbiBtZW1iZXIgZnVuY3Rpb24gcG9pbnRlcnMpLiBfdGhpcyBpcyB0aGUgb2JqZWN0IGJlaW5nCisgIC8vIGRlc3RydWN0ZWQuCisgIHByaW50ZXItPlByaW50KAorICAgICAgIiRjbGFzc25hbWUkKiBfdGhpcyA9IHJlaW50ZXJwcmV0X2Nhc3Q8ICRjbGFzc25hbWUkKiA+KG9iamVjdCk7XG4iCisgICAgICAvLyBhdm9pZCBhbiAidW51c2VkIHZhcmlhYmxlIiB3YXJuaW5nIGluIGNhc2Ugbm8gZmllbGRzIGhhdmUgZHRvciBjb2RlLgorICAgICAgIih2b2lkKV90aGlzO1xuIiwKKyAgICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfKTsKKworICBib29sIG5lZWRfcmVnaXN0cmF0aW9uID0gZmFsc2U7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGlmIChmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZGVzY3JpcHRvcl8tPmZpZWxkKGkpKQorICAgICAgICAgICAgICAgICAgICAgICAgIC5HZW5lcmF0ZUFyZW5hRGVzdHJ1Y3RvckNvZGUocHJpbnRlcikpIHsKKyAgICAgIG5lZWRfcmVnaXN0cmF0aW9uID0gdHJ1ZTsKKyAgICB9CisgIH0KKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAgICJ9XG4iKTsKKworICBpZiAobmVlZF9yZWdpc3RyYXRpb24pIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgImlubGluZSB2b2lkICRjbGFzc25hbWUkOjpSZWdpc3RlckFyZW5hRHRvcig6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkge1xuIgorICAgICAgICAiICBpZiAoYXJlbmEgIT0gTlVMTCkge1xuIgorICAgICAgICAiICAgIGFyZW5hLT5Pd25DdXN0b21EZXN0cnVjdG9yKHRoaXMsICYkY2xhc3NuYW1lJDo6QXJlbmFEdG9yKTtcbiIKKyAgICAgICAgIiAgfVxuIgorICAgICAgICAifVxuIiwKKyAgICAgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8pOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAidm9pZCAkY2xhc3NuYW1lJDo6UmVnaXN0ZXJBcmVuYUR0b3IoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIHtcbiIKKyAgICAgICAgIn1cbiIsCisgICAgICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfKTsKKyAgfQorfQorCit2b2lkIE1lc3NhZ2VHZW5lcmF0b3I6OgorR2VuZXJhdGVTdHJ1Y3RvcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgc3RyaW5nIHN1cGVyY2xhc3M7CisgIGlmICh1c2VfZGVwZW5kZW50X2Jhc2VfKSB7CisgICAgc3VwZXJjbGFzcyA9CisgICAgICAgIERlcGVuZGVudEJhc2VDbGFzc1RlbXBsYXRlTmFtZShkZXNjcmlwdG9yXykgKyAiPCIgKyBjbGFzc25hbWVfICsgIj4iOworICB9IGVsc2UgeworICAgIHN1cGVyY2xhc3MgPSBTdXBlckNsYXNzTmFtZShkZXNjcmlwdG9yXyk7CisgIH0KKyAgc3RyaW5nIGluaXRpYWxpemVyX3dpdGhfYXJlbmEgPSBzdXBlcmNsYXNzICsgIigpIjsKKworICBpZiAoZGVzY3JpcHRvcl8tPmV4dGVuc2lvbl9yYW5nZV9jb3VudCgpID4gMCkgeworICAgIGluaXRpYWxpemVyX3dpdGhfYXJlbmEgKz0gIixcbiAgX2V4dGVuc2lvbnNfKGFyZW5hKSI7CisgIH0KKworICBpZiAoVXNlVW5rbm93bkZpZWxkU2V0KGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgaW5pdGlhbGl6ZXJfd2l0aF9hcmVuYSArPSAiLFxuICBfaW50ZXJuYWxfbWV0YWRhdGFfKGFyZW5hKSI7CisgIH0gZWxzZSB7CisgICAgaW5pdGlhbGl6ZXJfd2l0aF9hcmVuYSArPSAiLFxuICBfYXJlbmFfcHRyXyhhcmVuYSkiOworICB9CisKKyAgLy8gSW5pdGlhbGl6ZSBtZW1iZXIgdmFyaWFibGVzIHdpdGggYXJlbmEgY29uc3RydWN0b3IuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGJvb2wgaGFzX2FyZW5hX2NvbnN0cnVjdG9yID0gZGVzY3JpcHRvcl8tPmZpZWxkKGkpLT5pc19yZXBlYXRlZCgpOworICAgIGlmIChoYXNfYXJlbmFfY29uc3RydWN0b3IpIHsKKyAgICAgIGluaXRpYWxpemVyX3dpdGhfYXJlbmEgKz0gc3RyaW5nKCIsXG4gICIpICsKKyAgICAgICAgICBGaWVsZE5hbWUoZGVzY3JpcHRvcl8tPmZpZWxkKGkpKSArIHN0cmluZygiXyhhcmVuYSkiKTsKKyAgICB9CisgIH0KKworICBpZiAoSXNBbnlNZXNzYWdlKGRlc2NyaXB0b3JfKSkgeworICAgIGluaXRpYWxpemVyX3dpdGhfYXJlbmEgKz0gIixcbiAgX2FueV9tZXRhZGF0YV8oJnR5cGVfdXJsLCAmdmFsdWVfKSI7CisgIH0KKworICBzdHJpbmcgaW5pdGlhbGl6ZXJfbnVsbDsKKyAgaW5pdGlhbGl6ZXJfbnVsbCA9IChVc2VVbmtub3duRmllbGRTZXQoZGVzY3JpcHRvcl8tPmZpbGUoKSkgPworICAgICIsIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkiIDogIiwgX2FyZW5hX3B0cl8oTlVMTCkiKTsKKyAgaWYgKElzQW55TWVzc2FnZShkZXNjcmlwdG9yXykpIHsKKyAgICBpbml0aWFsaXplcl9udWxsICs9ICIsIF9hbnlfbWV0YWRhdGFfKCZ0eXBlX3VybF8sICZ2YWx1ZV8pIjsKKyAgfQorCisgIHByaW50ZXItPlByaW50KAorICAgICAgIiRjbGFzc25hbWUkOjokY2xhc3NuYW1lJCgpXG4iCisgICAgICAiICA6ICRzdXBlcmNsYXNzJCgpJGluaXRpYWxpemVyJCB7XG4iCisgICAgICAiICBTaGFyZWRDdG9yKCk7XG4iCisgICAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29uc3RydWN0b3I6JGZ1bGxfbmFtZSQpXG4iCisgICAgICAifVxuIiwKKyAgICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfLAorICAgICAgInN1cGVyY2xhc3MiLCBzdXBlcmNsYXNzLAorICAgICAgImZ1bGxfbmFtZSIsIGRlc2NyaXB0b3JfLT5mdWxsX25hbWUoKSwKKyAgICAgICJpbml0aWFsaXplciIsIGluaXRpYWxpemVyX251bGwpOworCisgIGlmIChTdXBwb3J0c0FyZW5hcyhkZXNjcmlwdG9yXykpIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIlxuIgorICAgICAgICAiJGNsYXNzbmFtZSQ6OiRjbGFzc25hbWUkKDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKVxuIgorICAgICAgICAiICA6ICRpbml0aWFsaXplciQge1xuIgorICAgICAgICAiICBTaGFyZWRDdG9yKCk7XG4iCisgICAgICAgICIgIFJlZ2lzdGVyQXJlbmFEdG9yKGFyZW5hKTtcbiIKKyAgICAgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGFyZW5hX2NvbnN0cnVjdG9yOiRmdWxsX25hbWUkKVxuIgorICAgICAgICAifVxuIiwKKyAgICAgICAgImluaXRpYWxpemVyIiwgaW5pdGlhbGl6ZXJfd2l0aF9hcmVuYSwKKyAgICAgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8sCisgICAgICAgICJzdXBlcmNsYXNzIiwgc3VwZXJjbGFzcywKKyAgICAgICAgImZ1bGxfbmFtZSIsIGRlc2NyaXB0b3JfLT5mdWxsX25hbWUoKSk7CisgIH0KKworICBwcmludGVyLT5QcmludCgKKyAgICAiXG4iCisgICAgInZvaWQgJGNsYXNzbmFtZSQ6OkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpIHtcbiIsCisgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8pOworCisgIGlmICghSGFzRmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIiAgX2lzX2RlZmF1bHRfaW5zdGFuY2VfID0gdHJ1ZTtcbiIpOworICB9CisKKyAgLy8gVGhlIGRlZmF1bHQgaW5zdGFuY2UgbmVlZHMgYWxsIG9mIGl0cyBlbWJlZGRlZCBtZXNzYWdlIHBvaW50ZXJzCisgIC8vIGNyb3NzLWxpbmtlZCB0byBvdGhlciBkZWZhdWx0IGluc3RhbmNlcy4gIFdlIGNhbid0IGRvIHRoaXMgaW5pdGlhbGl6YXRpb24KKyAgLy8gaW4gdGhlIGNvbnN0cnVjdG9yIGJlY2F1c2Ugc29tZSBvdGhlciBkZWZhdWx0IGluc3RhbmNlcyBtYXkgbm90IGhhdmUgYmVlbgorICAvLyBjb25zdHJ1Y3RlZCB5ZXQgYXQgdGhhdCB0aW1lLgorICAvLyBUT0RPKGtlbnRvbik6ICBNYXliZSBhbGwgbWVzc2FnZSBmaWVsZHMgKGV2ZW4gZm9yIG5vbi1kZWZhdWx0IG1lc3NhZ2VzKQorICAvLyAgIHNob3VsZCBiZSBpbml0aWFsaXplZCB0byBwb2ludCBhdCBkZWZhdWx0IGluc3RhbmNlcyByYXRoZXIgdGhhbiBOVUxMPworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvcl8tPmZpZWxkKGkpOworCisgICAgaWYgKCFmaWVsZC0+aXNfcmVwZWF0ZWQoKSAmJgorICAgICAgICBmaWVsZC0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSAmJgorICAgICAgICAoZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSA9PSBOVUxMIHx8CisgICAgICAgICBIYXNEZXNjcmlwdG9yTWV0aG9kcyhkZXNjcmlwdG9yXy0+ZmlsZSgpKSkpIHsKKyAgICAgIHN0cmluZyBuYW1lOworICAgICAgaWYgKGZpZWxkLT5jb250YWluaW5nX29uZW9mKCkpIHsKKyAgICAgICAgbmFtZSA9IGNsYXNzbmFtZV8gKyAiX2RlZmF1bHRfb25lb2ZfaW5zdGFuY2VfLT4iOworICAgICAgfQorICAgICAgbmFtZSArPSBGaWVsZE5hbWUoZmllbGQpOworICAgICAgUHJpbnRIYW5kbGluZ09wdGlvbmFsU3RhdGljSW5pdGlhbGl6ZXJzKAorICAgICAgICBkZXNjcmlwdG9yXy0+ZmlsZSgpLCBwcmludGVyLAorICAgICAgICAvLyBXaXRoIHN0YXRpYyBpbml0aWFsaXplcnMuCisgICAgICAgICIgICRuYW1lJF8gPSBjb25zdF9jYXN0PCAkdHlwZSQqPigmJHR5cGUkOjpkZWZhdWx0X2luc3RhbmNlKCkpO1xuIiwKKyAgICAgICAgLy8gV2l0aG91dC4KKyAgICAgICAgIiAgJG5hbWUkXyA9IGNvbnN0X2Nhc3Q8ICR0eXBlJCo+KFxuIgorICAgICAgICAiICAgICAgJHR5cGUkOjppbnRlcm5hbF9kZWZhdWx0X2luc3RhbmNlKCkpO1xuIiwKKyAgICAgICAgLy8gVmFycy4KKyAgICAgICAgIm5hbWUiLCBuYW1lLAorICAgICAgICAidHlwZSIsIEZpZWxkTWVzc2FnZVR5cGVOYW1lKGZpZWxkKSk7CisgICAgfSBlbHNlIGlmIChmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpICYmCisgICAgICAgICAgICAgICBIYXNEZXNjcmlwdG9yTWV0aG9kcyhkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgICAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGRlc2NyaXB0b3JfLT5maWVsZChpKSkKKyAgICAgICAgICAuR2VuZXJhdGVDb25zdHJ1Y3RvckNvZGUocHJpbnRlcik7CisgICAgfQorICB9CisgIHByaW50ZXItPlByaW50KAorICAgICJ9XG4iCisgICAgIlxuIik7CisKKyAgLy8gR2VuZXJhdGUgdGhlIGNvcHkgY29uc3RydWN0b3IuCisgIHByaW50ZXItPlByaW50KAorICAgICIkY2xhc3NuYW1lJDo6JGNsYXNzbmFtZSQoY29uc3QgJGNsYXNzbmFtZSQmIGZyb20pXG4iCisgICAgIiAgOiAkc3VwZXJjbGFzcyQoKSIsCisgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8sCisgICAgInN1cGVyY2xhc3MiLCBzdXBlcmNsYXNzLAorICAgICJmdWxsX25hbWUiLCBkZXNjcmlwdG9yXy0+ZnVsbF9uYW1lKCkpOworICBpZiAoVXNlVW5rbm93bkZpZWxkU2V0KGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICIsXG4gICAgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSIpOworICB9IGVsc2UgaWYgKCFVc2VVbmtub3duRmllbGRTZXQoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBwcmludGVyLT5QcmludCgiLFxuICAgIF9hcmVuYV9wdHJfKE5VTEwpIik7CisgIH0KKyAgaWYgKElzQW55TWVzc2FnZShkZXNjcmlwdG9yXykpIHsKKyAgICBwcmludGVyLT5QcmludCgiLFxuICAgIF9hbnlfbWV0YWRhdGFfKCZ0eXBlX3VybF8sICZ2YWx1ZV8pIik7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQoIiB7XG4iKTsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIiAgU2hhcmVkQ3RvcigpO1xuIgorICAgICIgIE1lcmdlRnJvbShmcm9tKTtcbiIKKyAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29weV9jb25zdHJ1Y3RvcjokZnVsbF9uYW1lJClcbiIKKyAgICAifVxuIgorICAgICJcbiIsCisgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8sCisgICAgInN1cGVyY2xhc3MiLCBzdXBlcmNsYXNzLAorICAgICJmdWxsX25hbWUiLCBkZXNjcmlwdG9yXy0+ZnVsbF9uYW1lKCkpOworCisgIC8vIEdlbmVyYXRlIHRoZSBzaGFyZWQgY29uc3RydWN0b3IgY29kZS4KKyAgR2VuZXJhdGVTaGFyZWRDb25zdHJ1Y3RvckNvZGUocHJpbnRlcik7CisKKyAgLy8gR2VuZXJhdGUgdGhlIGRlc3RydWN0b3IuCisgIHByaW50ZXItPlByaW50KAorICAgICIkY2xhc3NuYW1lJDo6fiRjbGFzc25hbWUkKCkge1xuIgorICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChkZXN0cnVjdG9yOiRmdWxsX25hbWUkKVxuIgorICAgICIgIFNoYXJlZER0b3IoKTtcbiIKKyAgICAifVxuIgorICAgICJcbiIsCisgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8sCisgICAgImZ1bGxfbmFtZSIsIGRlc2NyaXB0b3JfLT5mdWxsX25hbWUoKSk7CisKKyAgLy8gR2VuZXJhdGUgdGhlIHNoYXJlZCBkZXN0cnVjdG9yIGNvZGUuCisgIEdlbmVyYXRlU2hhcmVkRGVzdHJ1Y3RvckNvZGUocHJpbnRlcik7CisKKyAgLy8gR2VuZXJhdGUgdGhlIGFyZW5hLXNwZWNpZmljIGRlc3RydWN0b3IgY29kZS4KKyAgaWYgKFN1cHBvcnRzQXJlbmFzKGRlc2NyaXB0b3JfKSkgeworICAgIEdlbmVyYXRlQXJlbmFEZXN0cnVjdG9yQ29kZShwcmludGVyKTsKKyAgfQorCisgIC8vIEdlbmVyYXRlIFNldENhY2hlZFNpemUuCisgIHByaW50ZXItPlByaW50KAorICAgICJ2b2lkICRjbGFzc25hbWUkOjpTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdCB7XG4iCisgICAgIiAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTtcbiIKKyAgICAiICBfY2FjaGVkX3NpemVfID0gc2l6ZTtcbiIKKyAgICAiICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTtcbiIKKyAgICAifVxuIiwKKyAgICAiY2xhc3NuYW1lIiwgY2xhc3NuYW1lXyk7CisKKyAgLy8gT25seSBnZW5lcmF0ZSB0aGlzIG1lbWJlciBpZiBpdCdzIG5vdCBkaXNhYmxlZC4KKyAgaWYgKEhhc0Rlc2NyaXB0b3JNZXRob2RzKGRlc2NyaXB0b3JfLT5maWxlKCkpICYmCisgICAgICAhZGVzY3JpcHRvcl8tPm9wdGlvbnMoKS5ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yKCkpIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqICRjbGFzc25hbWUkOjpkZXNjcmlwdG9yKCkge1xuIgorICAgICAgIiAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7XG4iCisgICAgICAiICByZXR1cm4gJGNsYXNzbmFtZSRfZGVzY3JpcHRvcl87XG4iCisgICAgICAifVxuIgorICAgICAgIlxuIiwKKyAgICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfLAorICAgICAgImFkZGRlc2NyaXB0b3JzbmFtZSIsCisgICAgICBHbG9iYWxBZGREZXNjcmlwdG9yc05hbWUoZGVzY3JpcHRvcl8tPmZpbGUoKS0+bmFtZSgpKSk7CisgIH0KKworICBwcmludGVyLT5QcmludCgKKyAgICAiY29uc3QgJGNsYXNzbmFtZSQmICRjbGFzc25hbWUkOjpkZWZhdWx0X2luc3RhbmNlKCkge1xuIiwKKyAgICAiY2xhc3NuYW1lIiwgY2xhc3NuYW1lXyk7CisKKyAgUHJpbnRIYW5kbGluZ09wdGlvbmFsU3RhdGljSW5pdGlhbGl6ZXJzKAorICAgIGRlc2NyaXB0b3JfLT5maWxlKCksIHByaW50ZXIsCisgICAgLy8gV2l0aCBzdGF0aWMgaW5pdGlhbGl6ZXJzLgorICAgICIgIGlmIChkZWZhdWx0X2luc3RhbmNlXyA9PSBOVUxMKSAkYWRkZGVzY3JpcHRvcnNuYW1lJCgpO1xuIiwKKyAgICAvLyBXaXRob3V0LgorICAgICIgICRhZGRkZXNjcmlwdG9yc25hbWUkKCk7XG4iLAorICAgIC8vIFZhcnMuCisgICAgImFkZGRlc2NyaXB0b3JzbmFtZSIsCisgICAgR2xvYmFsQWRkRGVzY3JpcHRvcnNOYW1lKGRlc2NyaXB0b3JfLT5maWxlKCktPm5hbWUoKSkpOworCisgIHByaW50ZXItPlByaW50KAorICAgICIgIHJldHVybiAqZGVmYXVsdF9pbnN0YW5jZV87XG4iCisgICAgIn1cbiIKKyAgICAiXG4iCisgICAgIiRjbGFzc25hbWUkKiAkY2xhc3NuYW1lJDo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBOVUxMO1xuIgorICAgICJcbiIsCisgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8pOworCisgIGlmIChTdXBwb3J0c0FyZW5hcyhkZXNjcmlwdG9yXykpIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICIkY2xhc3NuYW1lJCogJGNsYXNzbmFtZSQ6Ok5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3Qge1xuIgorICAgICAgIiAgcmV0dXJuIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmE6OkNyZWF0ZU1lc3NhZ2U8JGNsYXNzbmFtZSQ+KGFyZW5hKTtcbiIKKyAgICAgICJ9XG4iLAorICAgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8pOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIiRjbGFzc25hbWUkKiAkY2xhc3NuYW1lJDo6TmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdCB7XG4iCisgICAgICAiICAkY2xhc3NuYW1lJCogbiA9IG5ldyAkY2xhc3NuYW1lJDtcbiIKKyAgICAgICIgIGlmIChhcmVuYSAhPSBOVUxMKSB7XG4iCisgICAgICAiICAgIGFyZW5hLT5Pd24obik7XG4iCisgICAgICAiICB9XG4iCisgICAgICAiICByZXR1cm4gbjtcbiIKKyAgICAgICJ9XG4iLAorICAgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8pOworICB9CisKK30KKworLy8gUmV0dXJuIHRoZSBudW1iZXIgb2YgYml0cyBzZXQgaW4gbiwgYSBub24tbmVnYXRpdmUgaW50ZWdlci4KK3N0YXRpYyBpbnQgcG9wY250KHVpbnQzMiBuKSB7CisgIGludCByZXN1bHQgPSAwOworICB3aGlsZSAobiAhPSAwKSB7CisgICAgcmVzdWx0ICs9IChuICYgMSk7CisgICAgbiA9IG4gLyAyOworICB9CisgIHJldHVybiByZXN1bHQ7Cit9CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUNsZWFyKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KCJ2b2lkICRjbGFzc25hbWUkOjpDbGVhcigpIHtcbiIsCisgICAgICAgICAgICAgICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgLy8gU3RlcCAxOiBFeHRlbnNpb25zCisgIGlmIChkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCkgPiAwKSB7CisgICAgcHJpbnRlci0+UHJpbnQoIl9leHRlbnNpb25zXy5DbGVhcigpO1xuIik7CisgIH0KKworICAvLyBTdGVwIDI6IEV2ZXJ5dGhpbmcgYnV0IGV4dGVuc2lvbnMsIHJlcGVhdGVkcywgdW5pb25zLgorICAvLyBUaGVzZSBhcmUgaGFuZGxlZCBpbiBjaHVua3Mgb2YgOC4gIFRoZSBmaXJzdCBjaHVuayBpcworICAvLyB0aGUgbm9uLWV4dGVuc2lvbnMtbm9uLXJlcGVhdGVkcy1ub24tdW5pb25zIGluCisgIC8vICBkZXNjcmlwdG9yXy0+ZmllbGQoMCksIGRlc2NyaXB0b3JfLT5maWVsZCgxKSwgLi4uIGRlc2NyaXB0b3JfLT5maWVsZCg3KSwKKyAgLy8gYW5kIHRoZSBzZWNvbmQgY2h1bmsgaXMgdGhlIHNhbWUgZm9yCisgIC8vICBkZXNjcmlwdG9yXy0+ZmllbGQoOCksIGRlc2NyaXB0b3JfLT5maWVsZCg5KSwgLi4uIGRlc2NyaXB0b3JfLT5maWVsZCgxNSksCisgIC8vIGV0Yy4KKyAgc2V0PGludD4gc3RlcDJfaW5kaWNlczsKKyAgaGFzaF9tYXA8c3RyaW5nLCBpbnQ+IGZpZWxkbmFtZV90b19jaHVuazsKKyAgaGFzaF9tYXA8aW50LCBzdHJpbmc+IG1lbXNldHNfZm9yX2NodW5rOworICBoYXNoX21hcDxpbnQsIGludD4gbWVtc2V0X2ZpZWxkX2NvdW50X2Zvcl9jaHVuazsKKyAgaGFzaF9zZXQ8c3RyaW5nPiBoYW5kbGVkOyAgLy8gZmllbGRzIHRoYXQgYXBwZWFyIGFueXdoZXJlIGluIG1lbXNldHNfZm9yX2NodW5rCisgIGhhc2hfbWFwPGludCwgdWludDMyPiBmaWVsZHNfbWFza19mb3JfY2h1bms7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBkZXNjcmlwdG9yXy0+ZmllbGQoaSk7CisgICAgaWYgKCFmaWVsZC0+aXNfcmVwZWF0ZWQoKSAmJiAhZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSkgeworICAgICAgc3RlcDJfaW5kaWNlcy5pbnNlcnQoaSk7CisgICAgICBpbnQgY2h1bmsgPSBpIC8gODsKKyAgICAgIGZpZWxkbmFtZV90b19jaHVua1tGaWVsZE5hbWUoZmllbGQpXSA9IGNodW5rOworICAgICAgZmllbGRzX21hc2tfZm9yX2NodW5rW2NodW5rXSB8PSBzdGF0aWNfY2FzdDx1aW50MzI+KDEpIDw8IChpICUgMzIpOworICAgIH0KKyAgfQorCisgIC8vIFN0ZXAgMmE6IEdyZWVkaWx5IHNlZWsgcnVucyBvZiBmaWVsZHMgdGhhdCBjYW4gYmUgY2xlYXJlZCBieSBtZW1zZXQtdG8tMC4KKyAgLy8gVGhlIGdlbmVyYXRlZCBjb2RlIHVzZXMgdHdvIG1hY3JvcyB0byBoZWxwIGl0IGNsZWFyIHJ1bnMgb2YgZmllbGRzOgorICAvLyBaUl9IRUxQRVJfKGYxKSAtIFpSX0hFTFBFUl8oZjApIGNvbXB1dGVzIHRoZSBkaWZmZXJlbmNlLCBpbiBieXRlcywgb2YgdGhlCisgIC8vIHBvc2l0aW9ucyBvZiB0d28gZmllbGRzIGluIHRoZSBNZXNzYWdlLgorICAvLyBaUl8gemVyb2VzIGEgbm9uLWVtcHR5IHJhbmdlIG9mIGZpZWxkcyB2aWEgbWVtc2V0LgorICBjb25zdCBjaGFyKiBtYWNyb3MgPQorICAgICAgIiNkZWZpbmUgWlJfSEVMUEVSXyhmKSByZWludGVycHJldF9jYXN0PGNoYXIqPihcXFxuIgorICAgICAgIiAgJnJlaW50ZXJwcmV0X2Nhc3Q8JGNsYXNzbmFtZSQqPigxNiktPmYpXG5cbiIKKyAgICAgICIjZGVmaW5lIFpSXyhmaXJzdCwgbGFzdCkgZG8ge1xcXG4iCisgICAgICAiICA6Om1lbXNldCgmZmlyc3QsIDAsXFxcbiIKKyAgICAgICIgICAgICAgICAgIFpSX0hFTFBFUl8obGFzdCkgLSBaUl9IRUxQRVJfKGZpcnN0KSArIHNpemVvZihsYXN0KSk7XFxcbiIKKyAgICAgICJ9IHdoaWxlICgwKVxuXG4iOworICBmb3IgKGludCBpID0gMDsgaSA8IHJ1bnNfb2ZfZmllbGRzXy5zaXplKCk7IGkrKykgeworICAgIGNvbnN0IHZlY3RvcjxzdHJpbmc+JiBydW4gPSBydW5zX29mX2ZpZWxkc19baV07CisgICAgaWYgKHJ1bi5zaXplKCkgPCAyKSBjb250aW51ZTsKKyAgICBjb25zdCBzdHJpbmcmIGZpcnN0X2ZpZWxkX25hbWUgPSBydW5bMF07CisgICAgY29uc3Qgc3RyaW5nJiBsYXN0X2ZpZWxkX25hbWUgPSBydW4uYmFjaygpOworICAgIGludCBjaHVuayA9IGZpZWxkbmFtZV90b19jaHVua1tydW5bMF1dOworICAgIG1lbXNldHNfZm9yX2NodW5rW2NodW5rXS5hcHBlbmQoCisgICAgICAiWlJfKCIgKyBmaXJzdF9maWVsZF9uYW1lICsgIl8sICIgKyBsYXN0X2ZpZWxkX25hbWUgKyAiXyk7XG4iKTsKKyAgICBmb3IgKGludCBqID0gMDsgaiA8IHJ1bi5zaXplKCk7IGorKykgeworICAgICAgR09PR0xFX0RDSEVDS19FUShjaHVuaywgZmllbGRuYW1lX3RvX2NodW5rW3J1bltqXV0pOworICAgICAgaGFuZGxlZC5pbnNlcnQocnVuW2pdKTsKKyAgICB9CisgICAgbWVtc2V0X2ZpZWxkX2NvdW50X2Zvcl9jaHVua1tjaHVua10gKz0gcnVuLnNpemUoKTsKKyAgfQorICBjb25zdCBib29sIG1hY3Jvc19hcmVfbmVlZGVkID0gaGFuZGxlZC5zaXplKCkgPiAwOworICBpZiAobWFjcm9zX2FyZV9uZWVkZWQpIHsKKyAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgcHJpbnRlci0+UHJpbnQobWFjcm9zLAorICAgICAgICAgICAgICAgICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfKTsKKyAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgfQorICAvLyBTdGVwIDJiOiBGaW5pc2ggc3RlcCAyLCBpZ25vcmluZyBmaWVsZHMgaGFuZGxlZCBpbiBzdGVwIDJhLgorICBpbnQgbGFzdF9pbmRleCA9IC0xOworICBib29sIGNodW5rX2Jsb2NrX2luX3Byb2dyZXNzID0gZmFsc2U7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGlmIChzdGVwMl9pbmRpY2VzLmNvdW50KGkpID09IDApIGNvbnRpbnVlOworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBkZXNjcmlwdG9yXy0+ZmllbGQoaSk7CisgICAgY29uc3Qgc3RyaW5nIGZpZWxkbmFtZSA9IEZpZWxkTmFtZShmaWVsZCk7CisgICAgaWYgKGkgLyA4ICE9IGxhc3RfaW5kZXggLyA4IHx8IGxhc3RfaW5kZXggPCAwKSB7CisgICAgICAvLyBFbmQgcHJldmlvdXMgY2h1bmssIGlmIHRoZXJlIHdhcyBvbmUuCisgICAgICBpZiAoY2h1bmtfYmxvY2tfaW5fcHJvZ3Jlc3MpIHsKKyAgICAgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgICAgICBwcmludGVyLT5QcmludCgifVxuIik7CisgICAgICAgIGNodW5rX2Jsb2NrX2luX3Byb2dyZXNzID0gZmFsc2U7CisgICAgICB9CisgICAgICAvLyBTdGFydCBjaHVuay4KKyAgICAgIGNvbnN0IHN0cmluZyYgbWVtc2V0cyA9IG1lbXNldHNfZm9yX2NodW5rW2kgLyA4XTsKKyAgICAgIHVpbnQzMiBtYXNrID0gZmllbGRzX21hc2tfZm9yX2NodW5rW2kgLyA4XTsKKyAgICAgIGludCBjb3VudCA9IHBvcGNudChtYXNrKTsKKyAgICAgIEdPT0dMRV9EQ0hFQ0tfR0UoY291bnQsIDEpOworICAgICAgaWYgKGNvdW50ID09IDEgfHwKKyAgICAgICAgICAoY291bnQgPD0gNCAmJiBjb3VudCA9PSBtZW1zZXRfZmllbGRfY291bnRfZm9yX2NodW5rW2kgLyA4XSkpIHsKKyAgICAgICAgLy8gTm8gImlmIiBoZXJlIGJlY2F1c2UgdGhlIGNodW5rIGlzIHRyaXZpYWwuCisgICAgICB9IGVsc2UgeworICAgICAgICBpZiAoSGFzRmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgICAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICAgImlmIChfaGFzX2JpdHNfWyRpbmRleCQgLyAzMl0gJiAkbWFzayR1KSB7XG4iLAorICAgICAgICAgICAgImluZGV4IiwgU2ltcGxlSXRvYShpIC8gOCAqIDgpLAorICAgICAgICAgICAgIm1hc2siLCBTaW1wbGVJdG9hKG1hc2spKTsKKyAgICAgICAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICAgICAgICBjaHVua19ibG9ja19pbl9wcm9ncmVzcyA9IHRydWU7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIHByaW50ZXItPlByaW50KG1lbXNldHMuY19zdHIoKSk7CisgICAgfQorICAgIGxhc3RfaW5kZXggPSBpOworICAgIGlmIChoYW5kbGVkLmNvdW50KGZpZWxkbmFtZSkgPiAwKSBjb250aW51ZTsKKworICAgIC8vIEl0J3MgZmFzdGVyIHRvIGp1c3Qgb3ZlcndyaXRlIHByaW1pdGl2ZSB0eXBlcywgYnV0IHdlIHNob3VsZAorICAgIC8vIG9ubHkgY2xlYXIgc3RyaW5ncyBhbmQgbWVzc2FnZXMgaWYgdGhleSB3ZXJlIHNldC4KKyAgICAvLyBUT0RPKGtlbnRvbik6ICBMZXQgdGhlIENwcEZpZWxkR2VuZXJhdG9yIGRlY2lkZSB0aGlzIHNvbWVob3cuCisgICAgYm9vbCBzaG91bGRfY2hlY2tfYml0ID0KKyAgICAgIGZpZWxkLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFIHx8CisgICAgICBmaWVsZC0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HOworCisgICAgYm9vbCBoYXZlX2VuY2xvc2luZ19pZiA9IGZhbHNlOworICAgIGlmIChzaG91bGRfY2hlY2tfYml0ICYmCisgICAgICAgIC8vIElmIG5vIGZpZWxkIHByZXNlbmNlLCB0aGVuIGFsd2F5cyBjbGVhciBzdHJpbmdzL21lc3NhZ2VzIGFzIHdlbGwuCisgICAgICAgIEhhc0ZpZWxkUHJlc2VuY2UoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICAgIHByaW50ZXItPlByaW50KCJpZiAoaGFzXyRuYW1lJCgpKSB7XG4iLCAibmFtZSIsIGZpZWxkbmFtZSk7CisgICAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICAgIGhhdmVfZW5jbG9zaW5nX2lmID0gdHJ1ZTsKKyAgICB9CisKKyAgICBpZiAodXNlX2RlcGVuZGVudF9iYXNlXyAmJiBJc0ZpZWxkRGVwZW5kZW50KGZpZWxkKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQoImNsZWFyXyRuYW1lJCgpO1xuIiwgIm5hbWUiLCBmaWVsZG5hbWUpOworICAgIH0gZWxzZSB7CisgICAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZmllbGQpLkdlbmVyYXRlQ2xlYXJpbmdDb2RlKHByaW50ZXIpOworICAgIH0KKworICAgIGlmIChoYXZlX2VuY2xvc2luZ19pZikgeworICAgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgICAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworICAgIH0KKyAgfQorCisgIGlmIChjaHVua19ibG9ja19pbl9wcm9ncmVzcykgeworICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICBwcmludGVyLT5QcmludCgifVxuIik7CisgIH0KKyAgaWYgKG1hY3Jvc19hcmVfbmVlZGVkKSB7CisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIHByaW50ZXItPlByaW50KCJcbiN1bmRlZiBaUl9IRUxQRVJfXG4jdW5kZWYgWlJfXG5cbiIpOworICAgIHByaW50ZXItPkluZGVudCgpOworICB9CisKKyAgLy8gU3RlcCAzOiBSZXBlYXRlZCBmaWVsZHMgZG9uJ3QgdXNlIF9oYXNfYml0c187IGVtaXQgY29kZSB0byBjbGVhciB0aGVtIGhlcmUuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBkZXNjcmlwdG9yXy0+ZmllbGQoaSk7CisKKyAgICBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkpIHsKKyAgICAgIGlmICh1c2VfZGVwZW5kZW50X2Jhc2VfICYmIElzRmllbGREZXBlbmRlbnQoZmllbGQpKSB7CisgICAgICAgIHByaW50ZXItPlByaW50KCJjbGVhcl8kbmFtZSQoKTtcbiIsICJuYW1lIiwgRmllbGROYW1lKGZpZWxkKSk7CisgICAgICB9IGVsc2UgeworICAgICAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZmllbGQpLkdlbmVyYXRlQ2xlYXJpbmdDb2RlKHByaW50ZXIpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIC8vIFN0ZXAgNDogVW5pb25zLgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsX2NvdW50KCk7IGkrKykgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiY2xlYXJfJG9uZW9mX25hbWUkKCk7XG4iLAorICAgICAgICAib25lb2ZfbmFtZSIsIGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5uYW1lKCkpOworICB9CisKKyAgaWYgKEhhc0ZpZWxkUHJlc2VuY2UoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICAvLyBTdGVwIDU6IEV2ZXJ5dGhpbmcgZWxzZS4KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICI6Om1lbXNldChfaGFzX2JpdHNfLCAwLCBzaXplb2YoX2hhc19iaXRzXykpO1xuIik7CisgIH0KKworICBpZiAoUHJlc2VydmVVbmtub3duRmllbGRzKGRlc2NyaXB0b3JfKSkgeworICAgIGlmIChVc2VVbmtub3duRmllbGRTZXQoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7XG4iCisgICAgICAgICIgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+Q2xlYXIoKTtcbiIKKyAgICAgICAgIn1cbiIpOworICAgIH0gZWxzZSB7CisgICAgICBpZiAoU3VwcG9ydHNBcmVuYXMoZGVzY3JpcHRvcl8pKSB7CisgICAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICJfdW5rbm93bl9maWVsZHNfLkNsZWFyVG9FbXB0eShcbiIKKyAgICAgICAgICAiICAgICY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSxcbiIKKyAgICAgICAgICAiICAgIEdldEFyZW5hTm9WaXJ0dWFsKCkpO1xuIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAiX3Vua25vd25fZmllbGRzXy5DbGVhclRvRW1wdHlOb0FyZW5hKFxuIgorICAgICAgICAgICIgICAgJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTtcbiIpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworfQorCit2b2lkIE1lc3NhZ2VHZW5lcmF0b3I6OgorR2VuZXJhdGVPbmVvZkNsZWFyKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIC8vIEdlbmVyYXRlZCBmdW5jdGlvbiBjbGVhcnMgdGhlIGFjdGl2ZSBmaWVsZCBhbmQgdW5pb24gY2FzZSAoZS5nLiBmb29fY2FzZV8pLgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsX2NvdW50KCk7IGkrKykgeworICAgIG1hcDxzdHJpbmcsIHN0cmluZz4gb25lb2ZfdmFyczsKKyAgICBvbmVvZl92YXJzWyJjbGFzc25hbWUiXSA9IGNsYXNzbmFtZV87CisgICAgb25lb2ZfdmFyc1sib25lb2ZuYW1lIl0gPSBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKS0+bmFtZSgpOworICAgIHN0cmluZyBtZXNzYWdlX2NsYXNzOworCisgICAgcHJpbnRlci0+UHJpbnQob25lb2ZfdmFycywKKyAgICAgICAgInZvaWQgJGNsYXNzbmFtZSQ6OmNsZWFyXyRvbmVvZm5hbWUkKCkge1xuIik7CisgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgcHJpbnRlci0+UHJpbnQob25lb2ZfdmFycywKKyAgICAgICAgInN3aXRjaCgkb25lb2ZuYW1lJF9jYXNlKCkpIHtcbiIpOworICAgIHByaW50ZXItPkluZGVudCgpOworICAgIGZvciAoaW50IGogPSAwOyBqIDwgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPmZpZWxkX2NvdW50KCk7IGorKykgeworICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5maWVsZChqKTsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICJjYXNlIGskZmllbGRfbmFtZSQ6IHtcbiIsCisgICAgICAgICAgImZpZWxkX25hbWUiLCBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlKGZpZWxkLT5uYW1lKCksIHRydWUpKTsKKyAgICAgIHByaW50ZXItPkluZGVudCgpOworICAgICAgLy8gV2UgY2xlYXIgb25seSBhbGxvY2F0ZWQgb2JqZWN0cyBpbiBvbmVvZnMKKyAgICAgIGlmICghSXNTdHJpbmdPck1lc3NhZ2UoZmllbGQpKSB7CisgICAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICAgIi8vIE5vIG5lZWQgdG8gY2xlYXJcbiIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGZpZWxkKS5HZW5lcmF0ZUNsZWFyaW5nQ29kZShwcmludGVyKTsKKyAgICAgIH0KKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICJicmVhaztcbiIpOworICAgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgIn1cbiIpOworICAgIH0KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgImNhc2UgJGNhcF9vbmVvZl9uYW1lJF9OT1RfU0VUOiB7XG4iCisgICAgICAgICIgIGJyZWFrO1xuIgorICAgICAgICAifVxuIiwKKyAgICAgICAgImNhcF9vbmVvZl9uYW1lIiwKKyAgICAgICAgVG9VcHBlcihkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKS0+bmFtZSgpKSk7CisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAifVxuIgorICAgICAgICAiX29uZW9mX2Nhc2VfWyRvbmVvZl9pbmRleCRdID0gJGNhcF9vbmVvZl9uYW1lJF9OT1RfU0VUO1xuIiwKKyAgICAgICAgIm9uZW9mX2luZGV4IiwgU2ltcGxlSXRvYShpKSwKKyAgICAgICAgImNhcF9vbmVvZl9uYW1lIiwKKyAgICAgICAgVG9VcHBlcihkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKS0+bmFtZSgpKSk7CisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAifVxuIgorICAgICAgICAiXG4iKTsKKyAgfQorfQorCit2b2lkIE1lc3NhZ2VHZW5lcmF0b3I6OgorR2VuZXJhdGVTd2FwKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIGlmIChTdXBwb3J0c0FyZW5hcyhkZXNjcmlwdG9yXykpIHsKKyAgICAvLyBHZW5lcmF0ZSB0aGUgU3dhcCBtZW1iZXIgZnVuY3Rpb24uIFRoaXMgaXMgYSBsaWdodHdlaWdodCB3cmFwcGVyIGFyb3VuZAorICAgIC8vIFVuc2FmZUFyZW5hU3dhcCgpIC8gTWVyZ2VGcm9tKCkgd2l0aCB0ZW1wb3JhcmllcywgZGVwZW5kaW5nIG9uIHRoZSBtZW1vcnkKKyAgICAvLyBvd25lcnNoaXAgc2l0dWF0aW9uOiBzd2FwcGluZyBhY3Jvc3MgYXJlbmFzIG9yIGJldHdlZW4gYW4gYXJlbmEgYW5kIGEKKyAgICAvLyBoZWFwIHJlcXVpcmVzIGNvcHlpbmcuCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJ2b2lkICRjbGFzc25hbWUkOjpTd2FwKCRjbGFzc25hbWUkKiBvdGhlcikge1xuIgorICAgICAgICAiICBpZiAob3RoZXIgPT0gdGhpcykgcmV0dXJuO1xuIgorICAgICAgICAiICBpZiAoR2V0QXJlbmFOb1ZpcnR1YWwoKSA9PSBvdGhlci0+R2V0QXJlbmFOb1ZpcnR1YWwoKSkge1xuIgorICAgICAgICAiICAgIEludGVybmFsU3dhcChvdGhlcik7XG4iCisgICAgICAgICIgIH0gZWxzZSB7XG4iCisgICAgICAgICIgICAgJGNsYXNzbmFtZSQgdGVtcDtcbiIKKyAgICAgICAgIiAgICB0ZW1wLk1lcmdlRnJvbSgqdGhpcyk7XG4iCisgICAgICAgICIgICAgQ29weUZyb20oKm90aGVyKTtcbiIKKyAgICAgICAgIiAgICBvdGhlci0+Q29weUZyb20odGVtcCk7XG4iCisgICAgICAgICIgIH1cbiIKKyAgICAgICAgIn1cbiIKKyAgICAgICAgInZvaWQgJGNsYXNzbmFtZSQ6OlVuc2FmZUFyZW5hU3dhcCgkY2xhc3NuYW1lJCogb3RoZXIpIHtcbiIKKyAgICAgICAgIiAgaWYgKG90aGVyID09IHRoaXMpIHJldHVybjtcbiIKKyAgICAgICAgIiAgR09PR0xFX0RDSEVDSyhHZXRBcmVuYU5vVmlydHVhbCgpID09IG90aGVyLT5HZXRBcmVuYU5vVmlydHVhbCgpKTtcbiIKKyAgICAgICAgIiAgSW50ZXJuYWxTd2FwKG90aGVyKTtcbiIKKyAgICAgICAgIn1cbiIsCisgICAgICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgInZvaWQgJGNsYXNzbmFtZSQ6OlN3YXAoJGNsYXNzbmFtZSQqIG90aGVyKSB7XG4iCisgICAgICAgICIgIGlmIChvdGhlciA9PSB0aGlzKSByZXR1cm47XG4iCisgICAgICAgICIgIEludGVybmFsU3dhcChvdGhlcik7XG4iCisgICAgICAgICJ9XG4iLAorICAgICAgICAiY2xhc3NuYW1lIiwgY2xhc3NuYW1lXyk7CisgIH0KKworICAvLyBHZW5lcmF0ZSB0aGUgVW5zYWZlQXJlbmFTd2FwIG1lbWJlciBmdW5jdGlvbi4KKyAgcHJpbnRlci0+UHJpbnQoInZvaWQgJGNsYXNzbmFtZSQ6OkludGVybmFsU3dhcCgkY2xhc3NuYW1lJCogb3RoZXIpIHtcbiIsCisgICAgICAgICAgICAgICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgaWYgKEhhc0dlbmVyYXRlZE1ldGhvZHMoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBkZXNjcmlwdG9yXy0+ZmllbGQoaSk7CisgICAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZmllbGQpLkdlbmVyYXRlU3dhcHBpbmdDb2RlKHByaW50ZXIpOworICAgIH0KKworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2xfY291bnQoKTsgaSsrKSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgInN0ZDo6c3dhcCgkb25lb2ZfbmFtZSRfLCBvdGhlci0+JG9uZW9mX25hbWUkXyk7XG4iCisgICAgICAgICJzdGQ6OnN3YXAoX29uZW9mX2Nhc2VfWyRpJF0sIG90aGVyLT5fb25lb2ZfY2FzZV9bJGkkXSk7XG4iLAorICAgICAgICAib25lb2ZfbmFtZSIsIGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5uYW1lKCksCisgICAgICAgICJpIiwgU2ltcGxlSXRvYShpKSk7CisgICAgfQorCisgICAgaWYgKEhhc0ZpZWxkUHJlc2VuY2UoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgKGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpICsgMzEpIC8gMzI7ICsraSkgeworICAgICAgICBwcmludGVyLT5QcmludCgic3RkOjpzd2FwKF9oYXNfYml0c19bJGkkXSwgb3RoZXItPl9oYXNfYml0c19bJGkkXSk7XG4iLAorICAgICAgICAgICAgICAgICAgICAgICAiaSIsIFNpbXBsZUl0b2EoaSkpOworICAgICAgfQorICAgIH0KKworICAgIGlmIChQcmVzZXJ2ZVVua25vd25GaWVsZHMoZGVzY3JpcHRvcl8pKSB7CisgICAgICBpZiAoVXNlVW5rbm93bkZpZWxkU2V0KGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICJfaW50ZXJuYWxfbWV0YWRhdGFfLlN3YXAoJm90aGVyLT5faW50ZXJuYWxfbWV0YWRhdGFfKTtcbiIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoIl91bmtub3duX2ZpZWxkc18uU3dhcCgmb3RoZXItPl91bmtub3duX2ZpZWxkc18pO1xuIik7CisgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgIC8vIFN0aWxsIHN3YXAgaW50ZXJuYWxfbWV0YWRhdGEgYXMgaXQgbWF5IGNvbnRhaW4gbW9yZSB0aGFuIGp1c3QKKyAgICAgIC8vIHVua25vd24gZmllbGRzLgorICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJfaW50ZXJuYWxfbWV0YWRhdGFfLlN3YXAoJm90aGVyLT5faW50ZXJuYWxfbWV0YWRhdGFfKTtcbiIpOworICAgIH0KKyAgICBwcmludGVyLT5QcmludCgic3RkOjpzd2FwKF9jYWNoZWRfc2l6ZV8sIG90aGVyLT5fY2FjaGVkX3NpemVfKTtcbiIpOworICAgIGlmIChkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCkgPiAwKSB7CisgICAgICBwcmludGVyLT5QcmludCgiX2V4dGVuc2lvbnNfLlN3YXAoJm90aGVyLT5fZXh0ZW5zaW9uc18pO1xuIik7CisgICAgfQorICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KCJHZXRSZWZsZWN0aW9uKCktPlN3YXAodGhpcywgb3RoZXIpOyIpOworICB9CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgifVxuIik7Cit9CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lcmdlRnJvbShpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBpZiAoSGFzRGVzY3JpcHRvck1ldGhvZHMoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICAvLyBHZW5lcmF0ZSB0aGUgZ2VuZXJhbGl6ZWQgTWVyZ2VGcm9tIChha2EgdGhhdCB3aGljaCB0YWtlcyBpbiB0aGUgTWVzc2FnZQorICAgIC8vIGJhc2UgY2xhc3MgYXMgYSBwYXJhbWV0ZXIpLgorICAgIHByaW50ZXItPlByaW50KAorICAgICAgInZvaWQgJGNsYXNzbmFtZSQ6Ok1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHtcbiIKKyAgICAgICIgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7XG4iLAorICAgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8pOworICAgIHByaW50ZXItPkluZGVudCgpOworCisgICAgLy8gQ2FzdCB0aGUgbWVzc2FnZSB0byB0aGUgcHJvcGVyIHR5cGUuIElmIHdlIGZpbmQgdGhhdCB0aGUgbWVzc2FnZSBpcworICAgIC8vICpub3QqIG9mIHRoZSBwcm9wZXIgdHlwZSwgd2UgY2FuIHN0aWxsIGNhbGwgTWVyZ2UgdmlhIHRoZSByZWZsZWN0aW9uCisgICAgLy8gc3lzdGVtLCBhcyB0aGUgR09PR0xFX0NIRUNLIGFib3ZlIGVuc3VyZWQgdGhhdCB3ZSBoYXZlIHRoZSBzYW1lIGRlc2NyaXB0b3IKKyAgICAvLyBmb3IgZWFjaCBtZXNzYWdlLgorICAgIHByaW50ZXItPlByaW50KAorICAgICAgImNvbnN0ICRjbGFzc25hbWUkKiBzb3VyY2UgPSBcbiIKKyAgICAgICIgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RHluYW1pY0Nhc3RUb0dlbmVyYXRlZDxjb25zdCAkY2xhc3NuYW1lJD4oXG4iCisgICAgICAiICAgICAgICAmZnJvbSk7XG4iCisgICAgICAiaWYgKHNvdXJjZSA9PSBOVUxMKSB7XG4iCisgICAgICAiICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpSZWZsZWN0aW9uT3BzOjpNZXJnZShmcm9tLCB0aGlzKTtcbiIKKyAgICAgICJ9IGVsc2Uge1xuIgorICAgICAgIiAgTWVyZ2VGcm9tKCpzb3VyY2UpO1xuIgorICAgICAgIn1cbiIsCisgICAgICAiY2xhc3NuYW1lIiwgY2xhc3NuYW1lXyk7CisKKyAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgcHJpbnRlci0+UHJpbnQoIn1cblxuIik7CisgIH0gZWxzZSB7CisgICAgLy8gR2VuZXJhdGUgQ2hlY2tUeXBlQW5kTWVyZ2VGcm9tKCkuCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAidm9pZCAkY2xhc3NuYW1lJDo6Q2hlY2tUeXBlQW5kTWVyZ2VGcm9tKFxuIgorICAgICAgIiAgICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VMaXRlJiBmcm9tKSB7XG4iCisgICAgICAiICBNZXJnZUZyb20oKjo6Z29vZ2xlOjpwcm90b2J1Zjo6ZG93bl9jYXN0PGNvbnN0ICRjbGFzc25hbWUkKj4oJmZyb20pKTtcbiIKKyAgICAgICJ9XG4iCisgICAgICAiXG4iLAorICAgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8pOworICB9CisKKyAgLy8gR2VuZXJhdGUgdGhlIGNsYXNzLXNwZWNpZmljIE1lcmdlRnJvbSwgd2hpY2ggYXZvaWRzIHRoZSBHT09HTEVfQ0hFQ0sgYW5kIGNhc3QuCisgIHByaW50ZXItPlByaW50KAorICAgICJ2b2lkICRjbGFzc25hbWUkOjpNZXJnZUZyb20oY29uc3QgJGNsYXNzbmFtZSQmIGZyb20pIHtcbiIKKyAgICAiICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pO1xuIiwKKyAgICAiY2xhc3NuYW1lIiwgY2xhc3NuYW1lXyk7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIC8vIE1lcmdlIFJlcGVhdGVkIGZpZWxkcy4gVGhlc2UgZmllbGRzIGRvIG5vdCByZXF1aXJlIGEKKyAgLy8gY2hlY2sgYXMgd2UgY2FuIHNpbXBseSBpdGVyYXRlIG92ZXIgdGhlbS4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgKytpKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3JfLT5maWVsZChpKTsKKworICAgIGlmIChmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgeworICAgICAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGZpZWxkKS5HZW5lcmF0ZU1lcmdpbmdDb2RlKHByaW50ZXIpOworICAgIH0KKyAgfQorCisgIC8vIE1lcmdlIG9uZW9mIGZpZWxkcy4gT25lb2YgZmllbGQgcmVxdWlyZXMgb25lb2YgY2FzZSBjaGVjay4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbF9jb3VudCgpOyArK2kpIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgInN3aXRjaCAoZnJvbS4kb25lb2ZuYW1lJF9jYXNlKCkpIHtcbiIsCisgICAgICAgICJvbmVvZm5hbWUiLCBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKS0+bmFtZSgpKTsKKyAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICBmb3IgKGludCBqID0gMDsgaiA8IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5maWVsZF9jb3VudCgpOyBqKyspIHsKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKS0+ZmllbGQoaik7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAiY2FzZSBrJGZpZWxkX25hbWUkOiB7XG4iLAorICAgICAgICAgICJmaWVsZF9uYW1lIiwgVW5kZXJzY29yZXNUb0NhbWVsQ2FzZShmaWVsZC0+bmFtZSgpLCB0cnVlKSk7CisgICAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChmaWVsZCkuR2VuZXJhdGVNZXJnaW5nQ29kZShwcmludGVyKTsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICJicmVhaztcbiIpOworICAgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgIn1cbiIpOworICAgIH0KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgImNhc2UgJGNhcF9vbmVvZl9uYW1lJF9OT1RfU0VUOiB7XG4iCisgICAgICAgICIgIGJyZWFrO1xuIgorICAgICAgICAifVxuIiwKKyAgICAgICAgImNhcF9vbmVvZl9uYW1lIiwKKyAgICAgICAgVG9VcHBlcihkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKS0+bmFtZSgpKSk7CisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAifVxuIik7CisgIH0KKworICAvLyBNZXJnZSBPcHRpb25hbCBhbmQgUmVxdWlyZWQgZmllbGRzIChhZnRlciBhIF9oYXNfYml0IGNoZWNrKS4KKyAgaW50IGxhc3RfaW5kZXggPSAtMTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyArK2kpIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvcl8tPmZpZWxkKGkpOworCisgICAgaWYgKCFmaWVsZC0+aXNfcmVwZWF0ZWQoKSAmJiAhZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSkgeworICAgICAgaWYgKEhhc0ZpZWxkUHJlc2VuY2UoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICAgICAgLy8gU2VlIGFib3ZlIGluIEdlbmVyYXRlQ2xlYXIgZm9yIGFuIGV4cGxhbmF0aW9uIG9mIHRoaXMuCisgICAgICAgIGlmIChpIC8gOCAhPSBsYXN0X2luZGV4IC8gOCB8fCBsYXN0X2luZGV4IDwgMCkgeworICAgICAgICAgIGlmIChsYXN0X2luZGV4ID49IDApIHsKKyAgICAgICAgICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICAgICAgICAgIHByaW50ZXItPlByaW50KCJ9XG4iKTsKKyAgICAgICAgICB9CisgICAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgICAiaWYgKGZyb20uX2hhc19iaXRzX1skaW5kZXgkIC8gMzJdICYgIgorICAgICAgICAgICAgIigweGZmdSA8PCAoJGluZGV4JCAlIDMyKSkpIHtcbiIsCisgICAgICAgICAgICAiaW5kZXgiLCBTaW1wbGVJdG9hKGZpZWxkLT5pbmRleCgpKSk7CisgICAgICAgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgICAgIH0KKyAgICAgIH0KKworICAgICAgbGFzdF9pbmRleCA9IGk7CisKKyAgICAgIGJvb2wgaGF2ZV9lbmNsb3NpbmdfaWYgPSBmYWxzZTsKKyAgICAgIGlmIChIYXNGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICJpZiAoZnJvbS5oYXNfJG5hbWUkKCkpIHtcbiIsCisgICAgICAgICAgIm5hbWUiLCBGaWVsZE5hbWUoZmllbGQpKTsKKyAgICAgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgICAgIGhhdmVfZW5jbG9zaW5nX2lmID0gdHJ1ZTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIC8vIE1lcmdlIHNlbWFudGljcyB3aXRob3V0IHRydWUgZmllbGQgcHJlc2VuY2U6IHByaW1pdGl2ZSBmaWVsZHMgYXJlCisgICAgICAgIC8vIG1lcmdlZCBvbmx5IGlmIG5vbi16ZXJvIChudW1lcmljKSBvciBub24tZW1wdHkgKHN0cmluZykuCisgICAgICAgIGhhdmVfZW5jbG9zaW5nX2lmID0gRW1pdEZpZWxkTm9uRGVmYXVsdENvbmRpdGlvbigKKyAgICAgICAgICAgIHByaW50ZXIsICJmcm9tLiIsIGZpZWxkKTsKKyAgICAgIH0KKworICAgICAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGZpZWxkKS5HZW5lcmF0ZU1lcmdpbmdDb2RlKHByaW50ZXIpOworCisgICAgICBpZiAoaGF2ZV9lbmNsb3NpbmdfaWYpIHsKKyAgICAgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgICAgICBwcmludGVyLT5QcmludCgifVxuIik7CisgICAgICB9CisgICAgfQorICB9CisKKyAgaWYgKEhhc0ZpZWxkUHJlc2VuY2UoZGVzY3JpcHRvcl8tPmZpbGUoKSkgJiYKKyAgICAgIGxhc3RfaW5kZXggPj0gMCkgeworICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICBwcmludGVyLT5QcmludCgifVxuIik7CisgIH0KKworICBpZiAoZGVzY3JpcHRvcl8tPmV4dGVuc2lvbl9yYW5nZV9jb3VudCgpID4gMCkgeworICAgIHByaW50ZXItPlByaW50KCJfZXh0ZW5zaW9uc18uTWVyZ2VGcm9tKGZyb20uX2V4dGVuc2lvbnNfKTtcbiIpOworICB9CisKKyAgaWYgKFByZXNlcnZlVW5rbm93bkZpZWxkcyhkZXNjcmlwdG9yXykpIHsKKyAgICBpZiAoVXNlVW5rbm93bkZpZWxkU2V0KGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgImlmIChmcm9tLl9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7XG4iCisgICAgICAgICIgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+TWVyZ2VGcm9tKGZyb20udW5rbm93bl9maWVsZHMoKSk7XG4iCisgICAgICAgICJ9XG4iKTsKKyAgICB9IGVsc2UgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJpZiAoIWZyb20udW5rbm93bl9maWVsZHMoKS5lbXB0eSgpKSB7XG4iCisgICAgICAgICIgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+YXBwZW5kKGZyb20udW5rbm93bl9maWVsZHMoKSk7XG4iCisgICAgICAgICJ9XG4iKTsKKyAgICB9CisgIH0KKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KCJ9XG4iKTsKK30KKwordm9pZCBNZXNzYWdlR2VuZXJhdG9yOjoKK0dlbmVyYXRlQ29weUZyb20oaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgaWYgKEhhc0Rlc2NyaXB0b3JNZXRob2RzKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgLy8gR2VuZXJhdGUgdGhlIGdlbmVyYWxpemVkIENvcHlGcm9tIChha2EgdGhhdCB3aGljaCB0YWtlcyBpbiB0aGUgTWVzc2FnZQorICAgIC8vIGJhc2UgY2xhc3MgYXMgYSBwYXJhbWV0ZXIpLgorICAgIHByaW50ZXItPlByaW50KAorICAgICAgInZvaWQgJGNsYXNzbmFtZSQ6OkNvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkge1xuIiwKKyAgICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfKTsKKyAgICBwcmludGVyLT5JbmRlbnQoKTsKKworICAgIHByaW50ZXItPlByaW50KAorICAgICAgImlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47XG4iCisgICAgICAiQ2xlYXIoKTtcbiIKKyAgICAgICJNZXJnZUZyb20oZnJvbSk7XG4iKTsKKworICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICBwcmludGVyLT5QcmludCgifVxuXG4iKTsKKyAgfQorCisgIC8vIEdlbmVyYXRlIHRoZSBjbGFzcy1zcGVjaWZpYyBDb3B5RnJvbS4KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgInZvaWQgJGNsYXNzbmFtZSQ6OkNvcHlGcm9tKGNvbnN0ICRjbGFzc25hbWUkJiBmcm9tKSB7XG4iLAorICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgImlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47XG4iCisgICAgIkNsZWFyKCk7XG4iCisgICAgIk1lcmdlRnJvbShmcm9tKTtcbiIpOworCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworfQorCit2b2lkIE1lc3NhZ2VHZW5lcmF0b3I6OgorR2VuZXJhdGVNZXJnZUZyb21Db2RlZFN0cmVhbShpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBpZiAoZGVzY3JpcHRvcl8tPm9wdGlvbnMoKS5tZXNzYWdlX3NldF93aXJlX2Zvcm1hdCgpKSB7CisgICAgLy8gU3BlY2lhbC1jYXNlIE1lc3NhZ2VTZXQuCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiYm9vbCAkY2xhc3NuYW1lJDo6TWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKFxuIgorICAgICAgIiAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCkge1xuIiwKKyAgICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfKTsKKworICAgIFByaW50SGFuZGxpbmdPcHRpb25hbFN0YXRpY0luaXRpYWxpemVycygKKyAgICAgIGRlc2NyaXB0b3JfLT5maWxlKCksIHByaW50ZXIsCisgICAgICAvLyBXaXRoIHN0YXRpYyBpbml0aWFsaXplcnMuCisgICAgICAiICByZXR1cm4gX2V4dGVuc2lvbnNfLlBhcnNlTWVzc2FnZVNldChpbnB1dCwgZGVmYXVsdF9pbnN0YW5jZV8sXG4iCisgICAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkpO1xuIiwKKyAgICAgIC8vIFdpdGhvdXQuCisgICAgICAiICByZXR1cm4gX2V4dGVuc2lvbnNfLlBhcnNlTWVzc2FnZVNldChpbnB1dCwgJmRlZmF1bHRfaW5zdGFuY2UoKSxcbiIKKyAgICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSk7XG4iLAorICAgICAgLy8gVmFycy4KKyAgICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfKTsKKworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIn1cbiIpOworICAgIHJldHVybjsKKyAgfQorCisgIHByaW50ZXItPlByaW50KAorICAgICJib29sICRjbGFzc25hbWUkOjpNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oXG4iCisgICAgIiAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCkge1xuIgorICAgICIjZGVmaW5lIERPXyhFWFBSRVNTSU9OKSBpZiAoIShFWFBSRVNTSU9OKSkgZ290byBmYWlsdXJlXG4iCisgICAgIiAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgdGFnO1xuIiwKKyAgICAiY2xhc3NuYW1lIiwgY2xhc3NuYW1lXyk7CisKKyAgaWYgKCFVc2VVbmtub3duRmllbGRTZXQoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICAvLyBVc2UgTGF6eVN0cmluZ091dHB1dFN0cmluZyB0byBhdm9pZCBpbml0aWFsaXppbmcgdW5rbm93biBmaWVsZHMgc3RyaW5nCisgICAgLy8gdW5sZXNzIGl0IGlzIGFjdHVhbGx5IG5lZWRlZC4gRm9yIHRoZSBzYW1lIHJlYXNvbiwgZGlzYWJsZSBlYWdlciByZWZyZXNoCisgICAgLy8gb24gdGhlIENvZGVkT3V0cHV0U3RyZWFtLgorICAgIHByaW50ZXItPlByaW50KAorICAgICAgIiAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6TGF6eVN0cmluZ091dHB1dFN0cmVhbSB1bmtub3duX2ZpZWxkc19zdHJpbmcoXG4iCisgICAgICAiICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6TmV3UGVybWFuZW50Q2FsbGJhY2soXG4iCisgICAgICAiICAgICAgICAgICZNdXRhYmxlVW5rbm93bkZpZWxkc0ZvciRjbGFzc25hbWUkLCB0aGlzKSk7XG4iCisgICAgICAiICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSB1bmtub3duX2ZpZWxkc19zdHJlYW0oXG4iCisgICAgICAiICAgICAgJnVua25vd25fZmllbGRzX3N0cmluZywgZmFsc2UpO1xuIiwKKyAgICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KAorICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdGFydDokZnVsbF9uYW1lJClcbiIsCisgICAgImZ1bGxfbmFtZSIsIGRlc2NyaXB0b3JfLT5mdWxsX25hbWUoKSk7CisKKyAgcHJpbnRlci0+SW5kZW50KCk7CisgIHByaW50ZXItPlByaW50KCJmb3IgKDs7KSB7XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX2FycmF5PGNvbnN0IEZpZWxkRGVzY3JpcHRvciAqID4gb3JkZXJlZF9maWVsZHMoCisgICAgICBTb3J0RmllbGRzQnlOdW1iZXIoZGVzY3JpcHRvcl8pKTsKKyAgdWludDMyIG1heHRhZyA9IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpID09IDAgPyAwIDoKKyAgICAgIFdpcmVGb3JtYXQ6Ok1ha2VUYWcob3JkZXJlZF9maWVsZHNbZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCkgLSAxXSk7CisgIGNvbnN0IGludCBrQ3V0b2ZmMCA9IDEyNzsgICAgICAgICAgICAgICAvLyBmaXRzIGluIDEtYnl0ZSB2YXJpbnQKKyAgY29uc3QgaW50IGtDdXRvZmYxID0gKDEyNyA8PCA3KSArIDEyNzsgIC8vIGZpdHMgaW4gMi1ieXRlIHZhcmludAorICBwcmludGVyLT5QcmludCgiOjpzdGQ6OnBhaXI8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyLCBib29sPiBwID0gIgorICAgICAgICAgICAgICAgICAiaW5wdXQtPlJlYWRUYWdXaXRoQ3V0b2ZmKCRtYXgkKTtcbiIKKyAgICAgICAgICAgICAgICAgInRhZyA9IHAuZmlyc3Q7XG4iCisgICAgICAgICAgICAgICAgICJpZiAoIXAuc2Vjb25kKSBnb3RvIGhhbmRsZV91bnVzdWFsO1xuIiwKKyAgICAgICAgICAgICAgICAgIm1heCIsIFNpbXBsZUl0b2EobWF4dGFnIDw9IGtDdXRvZmYwID8ga0N1dG9mZjAgOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobWF4dGFnIDw9IGtDdXRvZmYxID8ga0N1dG9mZjEgOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4dGFnKSkpOworICBpZiAoZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCkgPiAwKSB7CisgICAgLy8gV2UgZG9uJ3QgZXZlbiB3YW50IHRvIHByaW50IHRoZSBzd2l0Y2goKSBpZiB3ZSBoYXZlIG5vIGZpZWxkcyBiZWNhdXNlCisgICAgLy8gTVNWQyBkaXNsaWtlcyBzd2l0Y2goKSBzdGF0ZW1lbnRzIHRoYXQgY29udGFpbiBvbmx5IGEgZGVmYXVsdCB2YWx1ZS4KKworICAgIC8vIE5vdGU6ICBJZiB3ZSBqdXN0IHN3aXRjaGVkIG9uIHRoZSB0YWcgcmF0aGVyIHRoYW4gdGhlIGZpZWxkIG51bWJlciwgd2UKKyAgICAvLyBjb3VsZCBhdm9pZCB0aGUgbmVlZCBmb3IgdGhlIGlmKCkgdG8gY2hlY2sgdGhlIHdpcmUgdHlwZSBhdCB0aGUgYmVnaW5uaW5nCisgICAgLy8gb2YgZWFjaCBjYXNlLiAgSG93ZXZlciwgdGhpcyBpcyBhY3R1YWxseSBhIGJpdCBzbG93ZXIgaW4gcHJhY3RpY2UgYXMgaXQKKyAgICAvLyBjcmVhdGVzIGEganVtcCB0YWJsZSB0aGF0IGlzIDh4IGxhcmdlciBhbmQgc3BhcnNlciwgYW5kIG1lYW53aGlsZSB0aGUKKyAgICAvLyBpZigpcyBhcmUgaGlnaGx5IHByZWRpY3RhYmxlLgorICAgIHByaW50ZXItPlByaW50KCJzd2l0Y2ggKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjoiCisgICAgICAgICAgICAgICAgICAgIkdldFRhZ0ZpZWxkTnVtYmVyKHRhZykpIHtcbiIpOworCisgICAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgICAvLyBGaW5kIHJlcGVhdGVkIG1lc3NhZ2VzIGFuZCBncm91cHMgbm93LCB0byBzaW1wbGlmeSB3aGF0IGZvbGxvd3MuCisgICAgaGFzaF9zZXQ8aW50PiBmaWVsZHNfd2l0aF9wYXJzZV9sb29wOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IG9yZGVyZWRfZmllbGRzW2ldOworICAgICAgaWYgKGZpZWxkLT5pc19yZXBlYXRlZCgpICYmCisgICAgICAgICAgKGZpZWxkLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX01FU1NBR0UgfHwKKyAgICAgICAgICAgZmllbGQtPnR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfR1JPVVApKSB7CisgICAgICAgIGZpZWxkc193aXRoX3BhcnNlX2xvb3AuaW5zZXJ0KGkpOworICAgICAgfQorICAgIH0KKworICAgIC8vIG5lZWRfbGFiZWwgaXMgdHJ1ZSBpZiB3ZSBnZW5lcmF0ZWQgImdvdG8gcGFyc2VfJG5hbWUkIiB3aGlsZSBoYW5kbGluZyB0aGUKKyAgICAvLyBwcmV2aW91cyBmaWVsZC4KKyAgICBib29sIG5lZWRfbGFiZWwgPSBmYWxzZTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBvcmRlcmVkX2ZpZWxkc1tpXTsKKyAgICAgIGNvbnN0IGJvb2wgbG9vcHMgPSBmaWVsZHNfd2l0aF9wYXJzZV9sb29wLmNvdW50KGkpID4gMDsKKyAgICAgIGNvbnN0IGJvb2wgbmV4dF9maWVsZF9sb29wcyA9IGZpZWxkc193aXRoX3BhcnNlX2xvb3AuY291bnQoaSArIDEpID4gMDsKKworICAgICAgUHJpbnRGaWVsZENvbW1lbnQocHJpbnRlciwgZmllbGQpOworCisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgImNhc2UgJG51bWJlciQ6IHtcbiIsCisgICAgICAgICJudW1iZXIiLCBTaW1wbGVJdG9hKGZpZWxkLT5udW1iZXIoKSkpOworICAgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgICBjb25zdCBGaWVsZEdlbmVyYXRvciYgZmllbGRfZ2VuZXJhdG9yID0gZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGZpZWxkKTsKKworICAgICAgLy8gRW1pdCBjb2RlIHRvIHBhcnNlIHRoZSBjb21tb24sIGV4cGVjdGVkIGNhc2UuCisgICAgICBwcmludGVyLT5QcmludCgiaWYgKHRhZyA9PSAkY29tbW9udGFnJCkge1xuIiwKKyAgICAgICAgICAgICAgICAgICAgICJjb21tb250YWciLCBTaW1wbGVJdG9hKFdpcmVGb3JtYXQ6Ok1ha2VUYWcoZmllbGQpKSk7CisKKyAgICAgIGlmIChuZWVkX2xhYmVsIHx8CisgICAgICAgICAgKGZpZWxkLT5pc19yZXBlYXRlZCgpICYmICFmaWVsZC0+aXNfcGFja2VkKCkgJiYgIWxvb3BzKSkgeworICAgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAgICIgcGFyc2VfJG5hbWUkOlxuIiwKKyAgICAgICAgICAgICJuYW1lIiwgZmllbGQtPm5hbWUoKSk7CisgICAgICB9CisgICAgICBpZiAobG9vcHMpIHsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgIiAgRE9fKGlucHV0LT5JbmNyZW1lbnRSZWN1cnNpb25EZXB0aCgpKTtcbiIKKyAgICAgICAgICAiIHBhcnNlX2xvb3BfJG5hbWUkOlxuIiwKKyAgICAgICAgICAibmFtZSIsIGZpZWxkLT5uYW1lKCkpOworICAgICAgfQorCisgICAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICAgIGlmIChmaWVsZC0+aXNfcGFja2VkKCkpIHsKKyAgICAgICAgZmllbGRfZ2VuZXJhdG9yLkdlbmVyYXRlTWVyZ2VGcm9tQ29kZWRTdHJlYW1XaXRoUGFja2luZyhwcmludGVyKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGZpZWxkX2dlbmVyYXRvci5HZW5lcmF0ZU1lcmdlRnJvbUNvZGVkU3RyZWFtKHByaW50ZXIpOworICAgICAgfQorICAgICAgcHJpbnRlci0+T3V0ZGVudCgpOworCisgICAgICAvLyBFbWl0IGNvZGUgdG8gcGFyc2UgdW5leHBlY3RlZGx5IHBhY2tlZCBvciB1bnBhY2tlZCB2YWx1ZXMuCisgICAgICBpZiAoZmllbGQtPmlzX3BhY2tlZCgpKSB7CisgICAgICAgIGludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V2lyZVR5cGUgd2lyZXR5cGUgPQorICAgICAgICAgICAgV2lyZUZvcm1hdDo6V2lyZVR5cGVGb3JGaWVsZFR5cGUoZmllbGQtPnR5cGUoKSk7CisgICAgICAgIHByaW50ZXItPlByaW50KCJ9IGVsc2UgaWYgKHRhZyA9PSAkdW5jb21tb250YWckKSB7XG4iLAorICAgICAgICAgICAgICAgICAgICAgICAidW5jb21tb250YWciLCBTaW1wbGVJdG9hKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpNYWtlVGFnKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkLT5udW1iZXIoKSwgd2lyZXR5cGUpKSk7CisgICAgICAgIHByaW50ZXItPkluZGVudCgpOworICAgICAgICBmaWVsZF9nZW5lcmF0b3IuR2VuZXJhdGVNZXJnZUZyb21Db2RlZFN0cmVhbShwcmludGVyKTsKKyAgICAgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgICAgfSBlbHNlIGlmIChmaWVsZC0+aXNfcGFja2FibGUoKSAmJiAhZmllbGQtPmlzX3BhY2tlZCgpKSB7CisgICAgICAgIGludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V2lyZVR5cGUgd2lyZXR5cGUgPQorICAgICAgICAgICAgaW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVEOworICAgICAgICBwcmludGVyLT5QcmludCgifSBlbHNlIGlmICh0YWcgPT0gJHVuY29tbW9udGFnJCkge1xuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgInVuY29tbW9udGFnIiwgU2ltcGxlSXRvYSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6TWFrZVRhZygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZC0+bnVtYmVyKCksIHdpcmV0eXBlKSkpOworICAgICAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICAgICAgZmllbGRfZ2VuZXJhdG9yLkdlbmVyYXRlTWVyZ2VGcm9tQ29kZWRTdHJlYW1XaXRoUGFja2luZyhwcmludGVyKTsKKyAgICAgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgICAgfQorCisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIn0gZWxzZSB7XG4iCisgICAgICAgICIgIGdvdG8gaGFuZGxlX3VudXN1YWw7XG4iCisgICAgICAgICJ9XG4iKTsKKworICAgICAgLy8gc3dpdGNoKCkgaXMgc2xvdyBzaW5jZSBpdCBjYW4ndCBiZSBwcmVkaWN0ZWQgd2VsbC4gIEluc2VydCBzb21lIGlmKClzCisgICAgICAvLyBoZXJlIHRoYXQgYXR0ZW1wdCB0byBwcmVkaWN0IHRoZSBuZXh0IHRhZy4KKyAgICAgIC8vIEZvciBub24tcGFja2VkIHJlcGVhdGVkIGZpZWxkcywgZXhwZWN0IHRoZSBzYW1lIHRhZyBhZ2Fpbi4KKyAgICAgIGlmIChsb29wcykgeworICAgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAiaWYgKGlucHV0LT5FeHBlY3RUYWcoJHRhZyQpKSBnb3RvIHBhcnNlX2xvb3BfJG5hbWUkO1xuIiwKKyAgICAgICAgICAidGFnIiwgU2ltcGxlSXRvYShXaXJlRm9ybWF0OjpNYWtlVGFnKGZpZWxkKSksCisgICAgICAgICAgIm5hbWUiLCBmaWVsZC0+bmFtZSgpKTsKKyAgICAgIH0gZWxzZSBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkgJiYgIWZpZWxkLT5pc19wYWNrZWQoKSkgeworICAgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAiaWYgKGlucHV0LT5FeHBlY3RUYWcoJHRhZyQpKSBnb3RvIHBhcnNlXyRuYW1lJDtcbiIsCisgICAgICAgICAgInRhZyIsIFNpbXBsZUl0b2EoV2lyZUZvcm1hdDo6TWFrZVRhZyhmaWVsZCkpLAorICAgICAgICAgICJuYW1lIiwgZmllbGQtPm5hbWUoKSk7CisgICAgICB9CisKKyAgICAgIC8vIEhhdmUgd2UgZW1pdHRlZCAiaWYgKGlucHV0LT5FeHBlY3RUYWcoJG5leHRfdGFnJCkpIC4uLiIgeWV0PworICAgICAgYm9vbCBlbWl0dGVkX2dvdG9fbmV4dF90YWcgPSBmYWxzZTsKKworICAgICAgLy8gRm9yIHJlcGVhdGVkIG1lc3NhZ2VzL2dyb3Vwcywgd2UgbmVlZCB0byBkZWNyZW1lbnQgcmVjdXJzaW9uIGRlcHRoLAorICAgICAgLy8gdW5sZXNzIHRoZSBuZXh0IHRhZyBpcyBhbHNvIGZvciBhIHJlcGVhdGVkIG1lc3NhZ2UvZ3JvdXAuCisgICAgICBpZiAobG9vcHMpIHsKKyAgICAgICAgaWYgKG5leHRfZmllbGRfbG9vcHMpIHsKKyAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIG5leHRfZmllbGQgPSBvcmRlcmVkX2ZpZWxkc1tpICsgMV07CisgICAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgICAiaWYgKGlucHV0LT5FeHBlY3RUYWcoJG5leHRfdGFnJCkpIGdvdG8gcGFyc2VfbG9vcF8kbmV4dF9uYW1lJDtcbiIsCisgICAgICAgICAgICAibmV4dF90YWciLCBTaW1wbGVJdG9hKFdpcmVGb3JtYXQ6Ok1ha2VUYWcobmV4dF9maWVsZCkpLAorICAgICAgICAgICAgIm5leHRfbmFtZSIsIG5leHRfZmllbGQtPm5hbWUoKSk7CisgICAgICAgICAgZW1pdHRlZF9nb3RvX25leHRfdGFnID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAiaW5wdXQtPlVuc2FmZURlY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCk7XG4iKTsKKyAgICAgIH0KKworICAgICAgLy8gSWYgdGhlcmUgYXJlIG1vcmUgZmllbGRzLCBleHBlY3QgdGhlIG5leHQgb25lLgorICAgICAgbmVlZF9sYWJlbCA9IGZhbHNlOworICAgICAgaWYgKCFlbWl0dGVkX2dvdG9fbmV4dF90YWcpIHsKKyAgICAgICAgaWYgKGkgKyAxID09IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpKSB7CisgICAgICAgICAgLy8gRXhwZWN0IEVPRi4KKyAgICAgICAgICAvLyBUT0RPKGtlbnRvbik6ICBFeHBlY3QgZ3JvdXAgZW5kLXRhZz8KKyAgICAgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAgICJpZiAoaW5wdXQtPkV4cGVjdEF0RW5kKCkpIGdvdG8gc3VjY2VzcztcbiIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogbmV4dF9maWVsZCA9IG9yZGVyZWRfZmllbGRzW2kgKyAxXTsKKyAgICAgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAgICJpZiAoaW5wdXQtPkV4cGVjdFRhZygkbmV4dF90YWckKSkgZ290byBwYXJzZV8kbmV4dF9uYW1lJDtcbiIsCisgICAgICAgICAgICAibmV4dF90YWciLCBTaW1wbGVJdG9hKFdpcmVGb3JtYXQ6Ok1ha2VUYWcobmV4dF9maWVsZCkpLAorICAgICAgICAgICAgIm5leHRfbmFtZSIsIG5leHRfZmllbGQtPm5hbWUoKSk7CisgICAgICAgICAgbmVlZF9sYWJlbCA9IHRydWU7CisgICAgICAgIH0KKyAgICAgIH0KKworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJicmVhaztcbiIpOworCisgICAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgICBwcmludGVyLT5QcmludCgifVxuXG4iKTsKKyAgICB9CisKKyAgICBwcmludGVyLT5QcmludCgiZGVmYXVsdDoge1xuIik7CisgICAgcHJpbnRlci0+SW5kZW50KCk7CisgIH0KKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KCJoYW5kbGVfdW51c3VhbDpcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKyAgLy8gSWYgdGFnIGlzIDAgb3IgYW4gZW5kLWdyb3VwIHRhZyB0aGVuIHRoaXMgbXVzdCBiZSB0aGUgZW5kIG9mIHRoZSBtZXNzYWdlLgorICBwcmludGVyLT5QcmludCgKKyAgICAiaWYgKHRhZyA9PSAwIHx8XG4iCisgICAgIiAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnV2lyZVR5cGUodGFnKSA9PVxuIgorICAgICIgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0VORF9HUk9VUCkge1xuIgorICAgICIgIGdvdG8gc3VjY2VzcztcbiIKKyAgICAifVxuIik7CisKKyAgLy8gSGFuZGxlIGV4dGVuc2lvbiByYW5nZXMuCisgIGlmIChkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCkgPiAwKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiaWYgKCIpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmV4dGVuc2lvbl9yYW5nZV9jb3VudCgpOyBpKyspIHsKKyAgICAgIGNvbnN0IERlc2NyaXB0b3I6OkV4dGVuc2lvblJhbmdlKiByYW5nZSA9CisgICAgICAgIGRlc2NyaXB0b3JfLT5leHRlbnNpb25fcmFuZ2UoaSk7CisgICAgICBpZiAoaSA+IDApIHByaW50ZXItPlByaW50KCIgfHxcbiAgICAiKTsKKworICAgICAgdWludDMyIHN0YXJ0X3RhZyA9IFdpcmVGb3JtYXRMaXRlOjpNYWtlVGFnKAorICAgICAgICByYW5nZS0+c3RhcnQsIHN0YXRpY19jYXN0PFdpcmVGb3JtYXRMaXRlOjpXaXJlVHlwZT4oMCkpOworICAgICAgdWludDMyIGVuZF90YWcgPSBXaXJlRm9ybWF0TGl0ZTo6TWFrZVRhZygKKyAgICAgICAgcmFuZ2UtPmVuZCwgc3RhdGljX2Nhc3Q8V2lyZUZvcm1hdExpdGU6OldpcmVUeXBlPigwKSk7CisKKyAgICAgIGlmIChyYW5nZS0+ZW5kID4gRmllbGREZXNjcmlwdG9yOjprTWF4TnVtYmVyKSB7CisgICAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICIoJHN0YXJ0JHUgPD0gdGFnKSIsCisgICAgICAgICAgInN0YXJ0IiwgU2ltcGxlSXRvYShzdGFydF90YWcpKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICIoJHN0YXJ0JHUgPD0gdGFnICYmIHRhZyA8ICRlbmQkdSkiLAorICAgICAgICAgICJzdGFydCIsIFNpbXBsZUl0b2Eoc3RhcnRfdGFnKSwKKyAgICAgICAgICAiZW5kIiwgU2ltcGxlSXRvYShlbmRfdGFnKSk7CisgICAgICB9CisgICAgfQorICAgIHByaW50ZXItPlByaW50KCIpIHtcbiIpOworICAgIGlmIChQcmVzZXJ2ZVVua25vd25GaWVsZHMoZGVzY3JpcHRvcl8pKSB7CisgICAgICBpZiAoVXNlVW5rbm93bkZpZWxkU2V0KGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgICAgIFByaW50SGFuZGxpbmdPcHRpb25hbFN0YXRpY0luaXRpYWxpemVycygKKyAgICAgICAgICBkZXNjcmlwdG9yXy0+ZmlsZSgpLCBwcmludGVyLAorICAgICAgICAgIC8vIFdpdGggc3RhdGljIGluaXRpYWxpemVycy4KKyAgICAgICAgICAiICBET18oX2V4dGVuc2lvbnNfLlBhcnNlRmllbGQodGFnLCBpbnB1dCwgZGVmYXVsdF9pbnN0YW5jZV8sXG4iCisgICAgICAgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSkpO1xuIiwKKyAgICAgICAgICAvLyBXaXRob3V0LgorICAgICAgICAgICIgIERPXyhfZXh0ZW5zaW9uc18uUGFyc2VGaWVsZCh0YWcsIGlucHV0LCAmZGVmYXVsdF9pbnN0YW5jZSgpLFxuIgorICAgICAgICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkpKTtcbiIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgUHJpbnRIYW5kbGluZ09wdGlvbmFsU3RhdGljSW5pdGlhbGl6ZXJzKAorICAgICAgICAgIGRlc2NyaXB0b3JfLT5maWxlKCksIHByaW50ZXIsCisgICAgICAgICAgLy8gV2l0aCBzdGF0aWMgaW5pdGlhbGl6ZXJzLgorICAgICAgICAgICIgIERPXyhfZXh0ZW5zaW9uc18uUGFyc2VGaWVsZCh0YWcsIGlucHV0LCBkZWZhdWx0X2luc3RhbmNlXyxcbiIKKyAgICAgICAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnVua25vd25fZmllbGRzX3N0cmVhbSkpO1xuIiwKKyAgICAgICAgICAvLyBXaXRob3V0LgorICAgICAgICAgICIgIERPXyhfZXh0ZW5zaW9uc18uUGFyc2VGaWVsZCh0YWcsIGlucHV0LCAmZGVmYXVsdF9pbnN0YW5jZSgpLFxuIgorICAgICAgICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmdW5rbm93bl9maWVsZHNfc3RyZWFtKSk7XG4iKTsKKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgUHJpbnRIYW5kbGluZ09wdGlvbmFsU3RhdGljSW5pdGlhbGl6ZXJzKAorICAgICAgICBkZXNjcmlwdG9yXy0+ZmlsZSgpLCBwcmludGVyLAorICAgICAgICAvLyBXaXRoIHN0YXRpYyBpbml0aWFsaXplcnMuCisgICAgICAgICIgIERPXyhfZXh0ZW5zaW9uc18uUGFyc2VGaWVsZCh0YWcsIGlucHV0LCBkZWZhdWx0X2luc3RhbmNlXyk7XG4iLAorICAgICAgICAvLyBXaXRob3V0LgorICAgICAgICAiICBET18oX2V4dGVuc2lvbnNfLlBhcnNlRmllbGQodGFnLCBpbnB1dCwgJmRlZmF1bHRfaW5zdGFuY2UoKSk7XG4iKTsKKyAgICB9CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiICBjb250aW51ZTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorCisgIC8vIFdlIHJlYWxseSBkb24ndCByZWNvZ25pemUgdGhpcyB0YWcuICBTa2lwIGl0LgorICBpZiAoUHJlc2VydmVVbmtub3duRmllbGRzKGRlc2NyaXB0b3JfKSkgeworICAgIGlmIChVc2VVbmtub3duRmllbGRTZXQoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNraXBGaWVsZChcbiIKKyAgICAgICAgIiAgICAgIGlucHV0LCB0YWcsIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSkpO1xuIik7CisgICAgfSBlbHNlIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTa2lwRmllbGQoXG4iCisgICAgICAgICIgICAgaW5wdXQsIHRhZywgJnVua25vd25fZmllbGRzX3N0cmVhbSkpO1xuIik7CisgICAgfQorICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIkRPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U2tpcEZpZWxkKGlucHV0LCB0YWcpKTtcbiIpOworICB9CisKKyAgaWYgKGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpID4gMCkgeworICAgIHByaW50ZXItPlByaW50KCJicmVhaztcbiIpOworICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICBwcmludGVyLT5QcmludCgifVxuIik7ICAgIC8vIGRlZmF1bHQ6CisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIHByaW50ZXItPlByaW50KCJ9XG4iKTsgICAgLy8gc3dpdGNoCisgIH0KKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIiAgfVxuIiAgICAgICAgICAgICAgICAgICAvLyBmb3IgKDs7KQorICAgICJzdWNjZXNzOlxuIgorICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdWNjZXNzOiRmdWxsX25hbWUkKVxuIgorICAgICIgIHJldHVybiB0cnVlO1xuIgorICAgICJmYWlsdXJlOlxuIgorICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9mYWlsdXJlOiRmdWxsX25hbWUkKVxuIgorICAgICIgIHJldHVybiBmYWxzZTtcbiIKKyAgICAiI3VuZGVmIERPX1xuIgorICAgICJ9XG4iLCAiZnVsbF9uYW1lIiwgZGVzY3JpcHRvcl8tPmZ1bGxfbmFtZSgpKTsKK30KKwordm9pZCBNZXNzYWdlR2VuZXJhdG9yOjpHZW5lcmF0ZVNlcmlhbGl6ZU9uZUZpZWxkKAorICAgIGlvOjpQcmludGVyKiBwcmludGVyLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBib29sIHRvX2FycmF5KSB7CisgIFByaW50RmllbGRDb21tZW50KHByaW50ZXIsIGZpZWxkKTsKKworICBib29sIGhhdmVfZW5jbG9zaW5nX2lmID0gZmFsc2U7CisgIGlmICghZmllbGQtPmlzX3JlcGVhdGVkKCkgJiYgSGFzRmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgImlmIChoYXNfJG5hbWUkKCkpIHtcbiIsCisgICAgICAibmFtZSIsIEZpZWxkTmFtZShmaWVsZCkpOworICAgIHByaW50ZXItPkluZGVudCgpOworICAgIGhhdmVfZW5jbG9zaW5nX2lmID0gdHJ1ZTsKKyAgfSBlbHNlIGlmICghSGFzRmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIGhhdmVfZW5jbG9zaW5nX2lmID0gRW1pdEZpZWxkTm9uRGVmYXVsdENvbmRpdGlvbihwcmludGVyLCAidGhpcy0+IiwgZmllbGQpOworICB9CisKKyAgaWYgKHRvX2FycmF5KSB7CisgICAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGZpZWxkKS5HZW5lcmF0ZVNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoCisgICAgICAgIHByaW50ZXIpOworICB9IGVsc2UgeworICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChmaWVsZCkuR2VuZXJhdGVTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMocHJpbnRlcik7CisgIH0KKworICBpZiAoaGF2ZV9lbmNsb3NpbmdfaWYpIHsKKyAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworICB9CisgIHByaW50ZXItPlByaW50KCJcbiIpOworfQorCit2b2lkIE1lc3NhZ2VHZW5lcmF0b3I6OkdlbmVyYXRlU2VyaWFsaXplT25lRXh0ZW5zaW9uUmFuZ2UoCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIsIGNvbnN0IERlc2NyaXB0b3I6OkV4dGVuc2lvblJhbmdlKiByYW5nZSwKKyAgICBib29sIHRvX2FycmF5KSB7CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyczsKKyAgdmFyc1sic3RhcnQiXSA9IFNpbXBsZUl0b2EocmFuZ2UtPnN0YXJ0KTsKKyAgdmFyc1siZW5kIl0gPSBTaW1wbGVJdG9hKHJhbmdlLT5lbmQpOworICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICIvLyBFeHRlbnNpb24gcmFuZ2UgWyRzdGFydCQsICRlbmQkKVxuIik7CisgIGlmICh0b19hcnJheSkgeworICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAidGFyZ2V0ID0gX2V4dGVuc2lvbnNfLlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoXG4iCisgICAgICAiICAgICRzdGFydCQsICRlbmQkLCB0YXJnZXQpO1xuXG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgIl9leHRlbnNpb25zXy5TZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoXG4iCisgICAgICAiICAgICRzdGFydCQsICRlbmQkLCBvdXRwdXQpO1xuXG4iKTsKKyAgfQorfQorCit2b2lkIE1lc3NhZ2VHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgaWYgKGRlc2NyaXB0b3JfLT5vcHRpb25zKCkubWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQoKSkgeworICAgIC8vIFNwZWNpYWwtY2FzZSBNZXNzYWdlU2V0LgorICAgIHByaW50ZXItPlByaW50KAorICAgICAgInZvaWQgJGNsYXNzbmFtZSQ6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcyhcbiIKKyAgICAgICIgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3Qge1xuIgorICAgICAgIiAgX2V4dGVuc2lvbnNfLlNlcmlhbGl6ZU1lc3NhZ2VTZXRXaXRoQ2FjaGVkU2l6ZXMob3V0cHV0KTtcbiIsCisgICAgICAiY2xhc3NuYW1lIiwgY2xhc3NuYW1lXyk7CisgICAgR09PR0xFX0NIRUNLKFVzZVVua25vd25GaWVsZFNldChkZXNjcmlwdG9yXy0+ZmlsZSgpKSk7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTZXJpYWxpemVVbmtub3duTWVzc2FnZVNldEl0ZW1zKFxuIgorICAgICAgIiAgICAgIHVua25vd25fZmllbGRzKCksIG91dHB1dCk7XG4iKTsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJ9XG4iKTsKKyAgICByZXR1cm47CisgIH0KKworICBwcmludGVyLT5QcmludCgKKyAgICAidm9pZCAkY2xhc3NuYW1lJDo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzKFxuIgorICAgICIgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3Qge1xuIiwKKyAgICAiY2xhc3NuYW1lIiwgY2xhc3NuYW1lXyk7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIHByaW50ZXItPlByaW50KAorICAgICIvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3N0YXJ0OiRmdWxsX25hbWUkKVxuIiwKKyAgICAiZnVsbF9uYW1lIiwgZGVzY3JpcHRvcl8tPmZ1bGxfbmFtZSgpKTsKKworICBHZW5lcmF0ZVNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc0JvZHkocHJpbnRlciwgZmFsc2UpOworCisgIHByaW50ZXItPlByaW50KAorICAgICIvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX2VuZDokZnVsbF9uYW1lJClcbiIsCisgICAgImZ1bGxfbmFtZSIsIGRlc2NyaXB0b3JfLT5mdWxsX25hbWUoKSk7CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgaWYgKGRlc2NyaXB0b3JfLT5vcHRpb25zKCkubWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQoKSkgeworICAgIC8vIFNwZWNpYWwtY2FzZSBNZXNzYWdlU2V0LgorICAgIHByaW50ZXItPlByaW50KAorICAgICAgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqICRjbGFzc25hbWUkOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KFxuIgorICAgICAgIiAgICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiB0YXJnZXQpIGNvbnN0IHtcbiIKKyAgICAgICIgIHRhcmdldCA9XG4iCisgICAgICAiICAgICAgX2V4dGVuc2lvbnNfLlNlcmlhbGl6ZU1lc3NhZ2VTZXRXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KHRhcmdldCk7XG4iLAorICAgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8pOworICAgIEdPT0dMRV9DSEVDSyhVc2VVbmtub3duRmllbGRTZXQoZGVzY3JpcHRvcl8tPmZpbGUoKSkpOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIiAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6XG4iCisgICAgICAiICAgICAgICAgICAgIFNlcmlhbGl6ZVVua25vd25NZXNzYWdlU2V0SXRlbXNUb0FycmF5KFxuIgorICAgICAgIiAgICAgICAgICAgICAgIHVua25vd25fZmllbGRzKCksIHRhcmdldCk7XG4iKTsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICIgIHJldHVybiB0YXJnZXQ7XG4iCisgICAgICAifVxuIik7CisgICAgcmV0dXJuOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqICRjbGFzc25hbWUkOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KFxuIgorICAgICIgICAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogdGFyZ2V0KSBjb25zdCB7XG4iLAorICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWVfKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIi8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfc3RhcnQ6JGZ1bGxfbmFtZSQpXG4iLAorICAgICJmdWxsX25hbWUiLCBkZXNjcmlwdG9yXy0+ZnVsbF9uYW1lKCkpOworCisgIEdlbmVyYXRlU2VyaWFsaXplV2l0aENhY2hlZFNpemVzQm9keShwcmludGVyLCB0cnVlKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAiLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9lbmQ6JGZ1bGxfbmFtZSQpXG4iLAorICAgICJmdWxsX25hbWUiLCBkZXNjcmlwdG9yXy0+ZnVsbF9uYW1lKCkpOworCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIiAgcmV0dXJuIHRhcmdldDtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc0JvZHkoaW86OlByaW50ZXIqIHByaW50ZXIsIGJvb2wgdG9fYXJyYXkpIHsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX2FycmF5PGNvbnN0IEZpZWxkRGVzY3JpcHRvciAqID4gb3JkZXJlZF9maWVsZHMoCisgICAgICBTb3J0RmllbGRzQnlOdW1iZXIoZGVzY3JpcHRvcl8pKTsKKworICB2ZWN0b3I8Y29uc3QgRGVzY3JpcHRvcjo6RXh0ZW5zaW9uUmFuZ2UqPiBzb3J0ZWRfZXh0ZW5zaW9uczsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCk7ICsraSkgeworICAgIHNvcnRlZF9leHRlbnNpb25zLnB1c2hfYmFjayhkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX3JhbmdlKGkpKTsKKyAgfQorICBzdGQ6OnNvcnQoc29ydGVkX2V4dGVuc2lvbnMuYmVnaW4oKSwgc29ydGVkX2V4dGVuc2lvbnMuZW5kKCksCisgICAgICAgICAgICBFeHRlbnNpb25SYW5nZVNvcnRlcigpKTsKKworICAvLyBNZXJnZSB0aGUgZmllbGRzIGFuZCB0aGUgZXh0ZW5zaW9uIHJhbmdlcywgYm90aCBzb3J0ZWQgYnkgZmllbGQgbnVtYmVyLgorICBpbnQgaSwgajsKKyAgZm9yIChpID0gMCwgaiA9IDA7CisgICAgICAgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpIHx8IGogPCBzb3J0ZWRfZXh0ZW5zaW9ucy5zaXplKCk7CisgICAgICAgKSB7CisgICAgaWYgKGkgPT0gZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCkpIHsKKyAgICAgIEdlbmVyYXRlU2VyaWFsaXplT25lRXh0ZW5zaW9uUmFuZ2UocHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc29ydGVkX2V4dGVuc2lvbnNbaisrXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9fYXJyYXkpOworICAgIH0gZWxzZSBpZiAoaiA9PSBzb3J0ZWRfZXh0ZW5zaW9ucy5zaXplKCkpIHsKKyAgICAgIEdlbmVyYXRlU2VyaWFsaXplT25lRmllbGQocHJpbnRlciwgb3JkZXJlZF9maWVsZHNbaSsrXSwgdG9fYXJyYXkpOworICAgIH0gZWxzZSBpZiAob3JkZXJlZF9maWVsZHNbaV0tPm51bWJlcigpIDwgc29ydGVkX2V4dGVuc2lvbnNbal0tPnN0YXJ0KSB7CisgICAgICBHZW5lcmF0ZVNlcmlhbGl6ZU9uZUZpZWxkKHByaW50ZXIsIG9yZGVyZWRfZmllbGRzW2krK10sIHRvX2FycmF5KTsKKyAgICB9IGVsc2UgeworICAgICAgR2VuZXJhdGVTZXJpYWxpemVPbmVFeHRlbnNpb25SYW5nZShwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzb3J0ZWRfZXh0ZW5zaW9uc1tqKytdLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b19hcnJheSk7CisgICAgfQorICB9CisKKyAgaWYgKFByZXNlcnZlVW5rbm93bkZpZWxkcyhkZXNjcmlwdG9yXykpIHsKKyAgICBpZiAoVXNlVW5rbm93bkZpZWxkU2V0KGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgICBwcmludGVyLT5QcmludCgiaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7XG4iKTsKKyAgICAgIHByaW50ZXItPkluZGVudCgpOworICAgICAgaWYgKHRvX2FycmF5KSB7CisgICAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICJ0YXJnZXQgPSAiCisgICAgICAgICAgICAgICI6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTZXJpYWxpemVVbmtub3duRmllbGRzVG9BcnJheShcbiIKKyAgICAgICAgICAiICAgIHVua25vd25fZmllbGRzKCksIHRhcmdldCk7XG4iKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICI6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTZXJpYWxpemVVbmtub3duRmllbGRzKFxuIgorICAgICAgICAgICIgICAgdW5rbm93bl9maWVsZHMoKSwgb3V0cHV0KTtcbiIpOworICAgICAgfQorICAgICAgcHJpbnRlci0+T3V0ZGVudCgpOworCisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIn1cbiIpOworICAgIH0gZWxzZSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIm91dHB1dC0+V3JpdGVSYXcodW5rbm93bl9maWVsZHMoKS5kYXRhKCksXG4iCisgICAgICAgICIgICAgICAgICAgICAgICAgIHN0YXRpY19jYXN0PGludD4odW5rbm93bl9maWVsZHMoKS5zaXplKCkpKTtcbiIpOworICAgIH0KKyAgfQorfQorCitzdGF0aWMgdmVjdG9yPHVpbnQzMj4gUmVxdWlyZWRGaWVsZHNCaXRNYXNrKGNvbnN0IERlc2NyaXB0b3IqIGRlc2MpIHsKKyAgdmVjdG9yPHVpbnQzMj4gcmVzdWx0OworICB1aW50MzIgbWFzayA9IDA7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzYy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgaWYgKGkgPiAwICYmIGkgJSAzMiA9PSAwKSB7CisgICAgICByZXN1bHQucHVzaF9iYWNrKG1hc2spOworICAgICAgbWFzayA9IDA7CisgICAgfQorICAgIGlmIChkZXNjLT5maWVsZChpKS0+aXNfcmVxdWlyZWQoKSkgeworICAgICAgbWFzayB8PSAoMSA8PCAoaSAmIDMxKSk7CisgICAgfQorICB9CisgIGlmIChtYXNrICE9IDApIHsKKyAgICByZXN1bHQucHVzaF9iYWNrKG1hc2spOworICB9CisgIHJldHVybiByZXN1bHQ7Cit9CisKKy8vIENyZWF0ZSBhbiBleHByZXNzaW9uIHRoYXQgZXZhbHVhdGVzIHRvCisvLyAgImZvciBhbGwgaSwgKF9oYXNfYml0c19baV0gJiBtYXNrc1tpXSkgPT0gbWFza3NbaV0iCisvLyBtYXNrcyBpcyBhbGxvd2VkIHRvIGJlIHNob3J0ZXIgdGhhbiBfaGFzX2JpdHNfLCBidXQgYXQgbGVhc3Qgb25lIGVsZW1lbnQgb2YKKy8vIG1hc2tzIG11c3QgYmUgbm9uLXplcm8uCitzdGF0aWMgc3RyaW5nIENvbmRpdGlvbmFsVG9DaGVja0JpdG1hc2tzKGNvbnN0IHZlY3Rvcjx1aW50MzI+JiBtYXNrcykgeworICB2ZWN0b3I8c3RyaW5nPiBwYXJ0czsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBtYXNrcy5zaXplKCk7IGkrKykgeworICAgIGlmIChtYXNrc1tpXSA9PSAwKSBjb250aW51ZTsKKyAgICBzdHJpbmcgbSA9IFN0ckNhdCgiMHgiLCBzdHJpbmdzOjpIZXgobWFza3NbaV0sIHN0cmluZ3M6OlpFUk9fUEFEXzgpKTsKKyAgICAvLyBFYWNoIHhvciBldmFsdWF0ZXMgdG8gMCBpZiB0aGUgZXhwZWN0ZWQgYml0cyBhcmUgcHJlc2VudC4KKyAgICBwYXJ0cy5wdXNoX2JhY2soU3RyQ2F0KCIoKF9oYXNfYml0c19bIiwgaSwgIl0gJiAiLCBtLCAiKSBeICIsIG0sICIpIikpOworICB9CisgIEdPT0dMRV9DSEVDSyghcGFydHMuZW1wdHkoKSk7CisgIC8vIElmIHdlIGhhdmUgbXVsdGlwbGUgcGFydHMsIGVhY2ggZXhwZWN0ZWQgdG8gYmUgMCwgdGhlbiBiaXR3aXNlLW9yIHRoZW0uCisgIHN0cmluZyByZXN1bHQgPSBwYXJ0cy5zaXplKCkgPT0gMSA/IHBhcnRzWzBdIDoKKyAgICAgIFN0ckNhdCgiKCIsIEpvaW4ocGFydHMsICJcbiAgICAgICB8ICIpLCAiKSIpOworICByZXR1cm4gcmVzdWx0ICsgIiA9PSAwIjsKK30KKwordm9pZCBNZXNzYWdlR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnl0ZVNpemUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgaWYgKGRlc2NyaXB0b3JfLT5vcHRpb25zKCkubWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQoKSkgeworICAgIC8vIFNwZWNpYWwtY2FzZSBNZXNzYWdlU2V0LgorICAgIHByaW50ZXItPlByaW50KAorICAgICAgImludCAkY2xhc3NuYW1lJDo6Qnl0ZVNpemUoKSBjb25zdCB7XG4iCisgICAgICAiICBpbnQgdG90YWxfc2l6ZSA9IF9leHRlbnNpb25zXy5NZXNzYWdlU2V0Qnl0ZVNpemUoKTtcbiIsCisgICAgICAiY2xhc3NuYW1lIiwgY2xhc3NuYW1lXyk7CisgICAgR09PR0xFX0NIRUNLKFVzZVVua25vd25GaWVsZFNldChkZXNjcmlwdG9yXy0+ZmlsZSgpKSk7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7XG4iCisgICAgICAiICB0b3RhbF9zaXplICs9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlxuIgorICAgICAgIiAgICAgIENvbXB1dGVVbmtub3duTWVzc2FnZVNldEl0ZW1zU2l6ZSh1bmtub3duX2ZpZWxkcygpKTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICIgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7XG4iCisgICAgICAiICBfY2FjaGVkX3NpemVfID0gdG90YWxfc2l6ZTtcbiIKKyAgICAgICIgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpO1xuIgorICAgICAgIiAgcmV0dXJuIHRvdGFsX3NpemU7XG4iCisgICAgICAifVxuIik7CisgICAgcmV0dXJuOworICB9CisKKyAgaWYgKG51bV9yZXF1aXJlZF9maWVsZHNfID4gMSAmJiBIYXNGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgLy8gRW1pdCBhIGZ1bmN0aW9uIChyYXJlbHkgdXNlZCwgd2UgaG9wZSkgdGhhdCBoYW5kbGVzIHRoZSByZXF1aXJlZCBmaWVsZHMKKyAgICAvLyBieSBjaGVja2luZyBmb3IgZWFjaCBvbmUgaW5kaXZpZHVhbGx5LgorICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiaW50ICRjbGFzc25hbWUkOjpSZXF1aXJlZEZpZWxkc0J5dGVTaXplRmFsbGJhY2soKSBjb25zdCB7XG4iLAorICAgICAgICAiY2xhc3NuYW1lIiwgY2xhc3NuYW1lXyk7CisgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgcHJpbnRlci0+UHJpbnQoImludCB0b3RhbF9zaXplID0gMDtcbiIpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3JfLT5maWVsZChpKTsKKyAgICAgIGlmIChmaWVsZC0+aXNfcmVxdWlyZWQoKSkgeworICAgICAgICBwcmludGVyLT5QcmludCgiXG4iCisgICAgICAgICAgICAgICAgICAgICAgICJpZiAoaGFzXyRuYW1lJCgpKSB7XG4iLAorICAgICAgICAgICAgICAgICAgICAgICAibmFtZSIsIEZpZWxkTmFtZShmaWVsZCkpOworICAgICAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICAgICAgUHJpbnRGaWVsZENvbW1lbnQocHJpbnRlciwgZmllbGQpOworICAgICAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZmllbGQpLkdlbmVyYXRlQnl0ZVNpemUocHJpbnRlcik7CisgICAgICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworICAgICAgfQorICAgIH0KKyAgICBwcmludGVyLT5QcmludCgiXG4iCisgICAgICAgICAgICAgICAgICAgInJldHVybiB0b3RhbF9zaXplO1xuIik7CisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIHByaW50ZXItPlByaW50KCJ9XG4iKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KAorICAgICJpbnQgJGNsYXNzbmFtZSQ6OkJ5dGVTaXplKCkgY29uc3Qge1xuIiwKKyAgICAiY2xhc3NuYW1lIiwgY2xhc3NuYW1lXyk7CisgIHByaW50ZXItPkluZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAiaW50IHRvdGFsX3NpemUgPSAwO1xuIgorICAgICJcbiIpOworCisgIC8vIEhhbmRsZSByZXF1aXJlZCBmaWVsZHMgKGlmIGFueSkuICBXZSBleHBlY3QgYWxsIG9mIHRoZW0gdG8gYmUKKyAgLy8gcHJlc2VudCwgc28gZW1pdCBvbmUgY29uZGl0aW9uYWwgdGhhdCBjaGVja3MgZm9yIHRoYXQuICBJZiB0aGV5IGFyZSBhbGwKKyAgLy8gcHJlc2VudCB0aGVuIHRoZSBmYXN0IHBhdGggZXhlY3V0ZXM7IG90aGVyd2lzZSB0aGUgc2xvdyBwYXRoIGV4ZWN1dGVzLgorICBpZiAobnVtX3JlcXVpcmVkX2ZpZWxkc18gPiAxICYmIEhhc0ZpZWxkUHJlc2VuY2UoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICAvLyBUaGUgZmFzdCBwYXRoIHdvcmtzIGlmIGFsbCByZXF1aXJlZCBmaWVsZHMgYXJlIHByZXNlbnQuCisgICAgdmVjdG9yPHVpbnQzMj4gbWFza3NfZm9yX2hhc19iaXRzID0gUmVxdWlyZWRGaWVsZHNCaXRNYXNrKGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCgoc3RyaW5nKCJpZiAoIikgKworICAgICAgICAgICAgICAgICAgICBDb25kaXRpb25hbFRvQ2hlY2tCaXRtYXNrcyhtYXNrc19mb3JfaGFzX2JpdHMpICsKKyAgICAgICAgICAgICAgICAgICAgIikgeyAgLy8gQWxsIHJlcXVpcmVkIGZpZWxkcyBhcmUgcHJlc2VudC5cbiIpLmNfc3RyKCkpOworICAgIHByaW50ZXItPkluZGVudCgpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3JfLT5maWVsZChpKTsKKyAgICAgIGlmICghZmllbGQtPmlzX3JlcXVpcmVkKCkpIGNvbnRpbnVlOworICAgICAgUHJpbnRGaWVsZENvbW1lbnQocHJpbnRlciwgZmllbGQpOworICAgICAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGZpZWxkKS5HZW5lcmF0ZUJ5dGVTaXplKHByaW50ZXIpOworICAgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisgICAgfQorICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICBwcmludGVyLT5QcmludCgifSBlbHNlIHtcbiIgIC8vIHRoZSBzbG93IHBhdGgKKyAgICAgICAgICAgICAgICAgICAiICB0b3RhbF9zaXplICs9IFJlcXVpcmVkRmllbGRzQnl0ZVNpemVGYWxsYmFjaygpO1xuIgorICAgICAgICAgICAgICAgICAgICJ9XG4iKTsKKyAgfSBlbHNlIHsKKyAgICAvLyBudW1fcmVxdWlyZWRfZmllbGRzXyA8PSAxOiBubyBuZWVkIHRvIGJlIHRyaWNreQorICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3JfLT5maWVsZChpKTsKKyAgICAgIGlmICghZmllbGQtPmlzX3JlcXVpcmVkKCkpIGNvbnRpbnVlOworICAgICAgUHJpbnRGaWVsZENvbW1lbnQocHJpbnRlciwgZmllbGQpOworICAgICAgcHJpbnRlci0+UHJpbnQoImlmIChoYXNfJG5hbWUkKCkpIHtcbiIsCisgICAgICAgICAgICAgICAgICAgICAibmFtZSIsIEZpZWxkTmFtZShmaWVsZCkpOworICAgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZmllbGQpLkdlbmVyYXRlQnl0ZVNpemUocHJpbnRlcik7CisgICAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgICBwcmludGVyLT5QcmludCgifVxuIik7CisgICAgfQorICB9CisKKyAgLy8gSGFuZGxlIG9wdGlvbmFsIGZpZWxkcyAod29ycnkgYmVsb3cgYWJvdXQgcmVwZWF0ZWRzLCBvbmVvZnMsIGV0Yy4pLgorICAvLyBUaGVzZSBhcmUgaGFuZGxlZCBpbiBjaHVua3Mgb2YgOC4gIFRoZSBmaXJzdCBjaHVuayBpcworICAvLyB0aGUgbm9uLXJlcXVpcmVkcy1ub24tcmVwZWF0ZWRzLW5vbi11bmlvbnMtbm9uLWV4dGVuc2lvbnMgaW4KKyAgLy8gIGRlc2NyaXB0b3JfLT5maWVsZCgwKSwgZGVzY3JpcHRvcl8tPmZpZWxkKDEpLCAuLi4gZGVzY3JpcHRvcl8tPmZpZWxkKDcpLAorICAvLyBhbmQgdGhlIHNlY29uZCBjaHVuayBpcyB0aGUgc2FtZSBmb3IKKyAgLy8gIGRlc2NyaXB0b3JfLT5maWVsZCg4KSwgZGVzY3JpcHRvcl8tPmZpZWxkKDkpLCAuLi4gZGVzY3JpcHRvcl8tPmZpZWxkKDE1KSwKKyAgLy8gZXRjLgorICBoYXNoX21hcDxpbnQsIHVpbnQzMj4gZmllbGRzX21hc2tfZm9yX2NodW5rOworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvcl8tPmZpZWxkKGkpOworICAgIGlmICghZmllbGQtPmlzX3JlcXVpcmVkKCkgJiYgIWZpZWxkLT5pc19yZXBlYXRlZCgpICYmCisgICAgICAgICFmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpKSB7CisgICAgICBmaWVsZHNfbWFza19mb3JfY2h1bmtbaSAvIDhdIHw9IHN0YXRpY19jYXN0PHVpbnQzMj4oMSkgPDwgKGkgJSAzMik7CisgICAgfQorICB9CisKKyAgaW50IGxhc3RfaW5kZXggPSAtMTsKKyAgYm9vbCBjaHVua19ibG9ja19pbl9wcm9ncmVzcyA9IGZhbHNlOworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvcl8tPmZpZWxkKGkpOworICAgIGlmICghZmllbGQtPmlzX3JlcXVpcmVkKCkgJiYgIWZpZWxkLT5pc19yZXBlYXRlZCgpICYmCisgICAgICAgICFmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpKSB7CisgICAgICAvLyBTZWUgYWJvdmUgaW4gR2VuZXJhdGVDbGVhciBmb3IgYW4gZXhwbGFuYXRpb24gb2YgdGhpcy4KKyAgICAgIC8vIFRPRE8oa2VudG9uKTogIFNoYXJlIGNvZGU/ICBVbmNsZWFyIGhvdyB0byBkbyBzbyB3aXRob3V0CisgICAgICAvLyAgIG92ZXItZW5naW5lZXJpbmcuCisgICAgICBpZiAoaSAvIDggIT0gbGFzdF9pbmRleCAvIDggfHwgbGFzdF9pbmRleCA8IDApIHsKKyAgICAgICAgLy8gRW5kIHByZXZpb3VzIGNodW5rLCBpZiB0aGVyZSB3YXMgb25lLgorICAgICAgICBpZiAoY2h1bmtfYmxvY2tfaW5fcHJvZ3Jlc3MpIHsKKyAgICAgICAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgICAgICAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworICAgICAgICAgIGNodW5rX2Jsb2NrX2luX3Byb2dyZXNzID0gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgLy8gU3RhcnQgY2h1bmsuCisgICAgICAgIHVpbnQzMiBtYXNrID0gZmllbGRzX21hc2tfZm9yX2NodW5rW2kgLyA4XTsKKyAgICAgICAgaW50IGNvdW50ID0gcG9wY250KG1hc2spOworICAgICAgICBHT09HTEVfRENIRUNLX0dFKGNvdW50LCAxKTsKKyAgICAgICAgaWYgKGNvdW50ID09IDEpIHsKKyAgICAgICAgICAvLyBObyAiaWYiIGhlcmUgYmVjYXVzZSB0aGUgY2h1bmsgaXMgdHJpdmlhbC4KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBpZiAoSGFzRmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgICAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgICAgICJpZiAoX2hhc19iaXRzX1skaW5kZXgkIC8gMzJdICYgJG1hc2skdSkge1xuIiwKKyAgICAgICAgICAgICAgImluZGV4IiwgU2ltcGxlSXRvYShpKSwKKyAgICAgICAgICAgICAgIm1hc2siLCBTaW1wbGVJdG9hKG1hc2spKTsKKyAgICAgICAgICAgIHByaW50ZXItPkluZGVudCgpOworICAgICAgICAgICAgY2h1bmtfYmxvY2tfaW5fcHJvZ3Jlc3MgPSB0cnVlOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfQorICAgICAgbGFzdF9pbmRleCA9IGk7CisKKyAgICAgIFByaW50RmllbGRDb21tZW50KHByaW50ZXIsIGZpZWxkKTsKKworICAgICAgYm9vbCBoYXZlX2VuY2xvc2luZ19pZiA9IGZhbHNlOworICAgICAgaWYgKEhhc0ZpZWxkUHJlc2VuY2UoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgImlmIChoYXNfJG5hbWUkKCkpIHtcbiIsCisgICAgICAgICAgIm5hbWUiLCBGaWVsZE5hbWUoZmllbGQpKTsKKyAgICAgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgICAgIGhhdmVfZW5jbG9zaW5nX2lmID0gdHJ1ZTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIC8vIFdpdGhvdXQgZmllbGQgcHJlc2VuY2U6IGZpZWxkIGlzIHNlcmlhbGl6ZWQgb25seSBpZiBpdCBoYXMgYQorICAgICAgICAvLyBub24tZGVmYXVsdCB2YWx1ZS4KKyAgICAgICAgaGF2ZV9lbmNsb3NpbmdfaWYgPSBFbWl0RmllbGROb25EZWZhdWx0Q29uZGl0aW9uKAorICAgICAgICAgICAgcHJpbnRlciwgInRoaXMtPiIsIGZpZWxkKTsKKyAgICAgIH0KKworICAgICAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGZpZWxkKS5HZW5lcmF0ZUJ5dGVTaXplKHByaW50ZXIpOworCisgICAgICBpZiAoaGF2ZV9lbmNsb3NpbmdfaWYpIHsKKyAgICAgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAifVxuIgorICAgICAgICAgICJcbiIpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIGlmIChjaHVua19ibG9ja19pbl9wcm9ncmVzcykgeworICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICBwcmludGVyLT5QcmludCgifVxuIik7CisgIH0KKworICAvLyBSZXBlYXRlZCBmaWVsZHMgZG9uJ3QgdXNlIF9oYXNfYml0c18gc28gd2UgY291bnQgdGhlbSBpbiBhIHNlcGFyYXRlCisgIC8vIHBhc3MuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBkZXNjcmlwdG9yXy0+ZmllbGQoaSk7CisKKyAgICBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkpIHsKKyAgICAgIFByaW50RmllbGRDb21tZW50KHByaW50ZXIsIGZpZWxkKTsKKyAgICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChmaWVsZCkuR2VuZXJhdGVCeXRlU2l6ZShwcmludGVyKTsKKyAgICAgIHByaW50ZXItPlByaW50KCJcbiIpOworICAgIH0KKyAgfQorCisgIC8vIEZpZWxkcyBpbnNpZGUgYSBvbmVvZiBkb24ndCB1c2UgX2hhc19iaXRzXyBzbyB3ZSBjb3VudCB0aGVtIGluIGEgc2VwYXJhdGUKKyAgLy8gcGFzcy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbF9jb3VudCgpOyBpKyspIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgInN3aXRjaCAoJG9uZW9mbmFtZSRfY2FzZSgpKSB7XG4iLAorICAgICAgICAib25lb2ZuYW1lIiwgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPm5hbWUoKSk7CisgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgZm9yIChpbnQgaiA9IDA7IGogPCBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKS0+ZmllbGRfY291bnQoKTsgaisrKSB7CisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPmZpZWxkKGopOworICAgICAgUHJpbnRGaWVsZENvbW1lbnQocHJpbnRlciwgZmllbGQpOworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgImNhc2UgayRmaWVsZF9uYW1lJDoge1xuIiwKKyAgICAgICAgICAiZmllbGRfbmFtZSIsIFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoZmllbGQtPm5hbWUoKSwgdHJ1ZSkpOworICAgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZmllbGQpLkdlbmVyYXRlQnl0ZVNpemUocHJpbnRlcik7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAiYnJlYWs7XG4iKTsKKyAgICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICJ9XG4iKTsKKyAgICB9CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJjYXNlICRjYXBfb25lb2ZfbmFtZSRfTk9UX1NFVDoge1xuIgorICAgICAgICAiICBicmVhaztcbiIKKyAgICAgICAgIn1cbiIsCisgICAgICAgICJjYXBfb25lb2ZfbmFtZSIsCisgICAgICAgIFRvVXBwZXIoZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPm5hbWUoKSkpOworICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIn1cbiIpOworICB9CisKKyAgaWYgKGRlc2NyaXB0b3JfLT5leHRlbnNpb25fcmFuZ2VfY291bnQoKSA+IDApIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJ0b3RhbF9zaXplICs9IF9leHRlbnNpb25zXy5CeXRlU2l6ZSgpO1xuIgorICAgICAgIlxuIik7CisgIH0KKworICBpZiAoUHJlc2VydmVVbmtub3duRmllbGRzKGRlc2NyaXB0b3JfKSkgeworICAgIGlmIChVc2VVbmtub3duRmllbGRTZXQoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7XG4iCisgICAgICAgICIgIHRvdGFsX3NpemUgKz1cbiIKKyAgICAgICAgIiAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpDb21wdXRlVW5rbm93bkZpZWxkc1NpemUoXG4iCisgICAgICAgICIgICAgICB1bmtub3duX2ZpZWxkcygpKTtcbiIKKyAgICAgICAgIn1cbiIpOworICAgIH0gZWxzZSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgInRvdGFsX3NpemUgKz0gdW5rbm93bl9maWVsZHMoKS5zaXplKCk7XG4iCisgICAgICAgICJcbiIpOworICAgIH0KKyAgfQorCisgIC8vIFdlIHVwZGF0ZSBfY2FjaGVkX3NpemVfIGV2ZW4gdGhvdWdoIHRoaXMgaXMgYSBjb25zdCBtZXRob2QuICBJbiB0aGVvcnksCisgIC8vIHRoaXMgaXMgbm90IHRocmVhZC1jb21wYXRpYmxlLCBiZWNhdXNlIGNvbmN1cnJlbnQgd3JpdGVzIGhhdmUgdW5kZWZpbmVkCisgIC8vIHJlc3VsdHMuICBJbiBwcmFjdGljZSwgc2luY2UgYW55IGNvbmN1cnJlbnQgd3JpdGVzIHdpbGwgYmUgd3JpdGluZyB0aGUKKyAgLy8gZXhhY3Qgc2FtZSB2YWx1ZSwgaXQgd29ya3Mgb24gYWxsIGNvbW1vbiBwcm9jZXNzb3JzLiAgSW4gYSBmdXR1cmUgdmVyc2lvbgorICAvLyBvZiBDKyssIF9jYWNoZWRfc2l6ZV8gc2hvdWxkIGJlIG1hZGUgaW50byBhbiBhdG9taWM8aW50Pi4KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIkdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7XG4iCisgICAgIl9jYWNoZWRfc2l6ZV8gPSB0b3RhbF9zaXplO1xuIgorICAgICJHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTtcbiIKKyAgICAicmV0dXJuIHRvdGFsX3NpemU7XG4iKTsKKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KCJ9XG4iKTsKK30KKwordm9pZCBNZXNzYWdlR2VuZXJhdG9yOjoKK0dlbmVyYXRlSXNJbml0aWFsaXplZChpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICAiYm9vbCAkY2xhc3NuYW1lJDo6SXNJbml0aWFsaXplZCgpIGNvbnN0IHtcbiIsCisgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8pOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBpZiAoSGFzRmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIC8vIENoZWNrIHRoYXQgYWxsIHJlcXVpcmVkIGZpZWxkcyBpbiB0aGlzIG1lc3NhZ2UgYXJlIHNldC4gIFdlIGNhbiBkbyB0aGlzCisgICAgLy8gbW9zdCBlZmZpY2llbnRseSBieSBjaGVja2luZyAzMiAiaGFzIGJpdHMiIGF0IGEgdGltZS4KKyAgICBpbnQgaGFzX2JpdHNfYXJyYXlfc2l6ZSA9IChkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKSArIDMxKSAvIDMyOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaGFzX2JpdHNfYXJyYXlfc2l6ZTsgaSsrKSB7CisgICAgICB1aW50MzIgbWFzayA9IDA7CisgICAgICBmb3IgKGludCBiaXQgPSAwOyBiaXQgPCAzMjsgYml0KyspIHsKKyAgICAgICAgaW50IGluZGV4ID0gaSAqIDMyICsgYml0OworICAgICAgICBpZiAoaW5kZXggPj0gZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCkpIGJyZWFrOworICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvcl8tPmZpZWxkKGluZGV4KTsKKworICAgICAgICBpZiAoZmllbGQtPmlzX3JlcXVpcmVkKCkpIHsKKyAgICAgICAgICBtYXNrIHw9IDEgPDwgYml0OworICAgICAgICB9CisgICAgICB9CisKKyAgICAgIGlmIChtYXNrICE9IDApIHsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgImlmICgoX2hhc19iaXRzX1skaSRdICYgMHgkbWFzayQpICE9IDB4JG1hc2skKSByZXR1cm4gZmFsc2U7XG4iLAorICAgICAgICAgICJpIiwgU2ltcGxlSXRvYShpKSwKKyAgICAgICAgICAibWFzayIsIFN0ckNhdChzdHJpbmdzOjpIZXgobWFzaywgc3RyaW5nczo6WkVST19QQURfOCkpKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvLyBOb3cgY2hlY2sgdGhhdCBhbGwgZW1iZWRkZWQgbWVzc2FnZXMgYXJlIGluaXRpYWxpemVkLgorICBwcmludGVyLT5QcmludCgiXG4iKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3JfLT5maWVsZChpKTsKKyAgICBpZiAoZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UgJiYKKyAgICAgICAgIVNob3VsZElnbm9yZVJlcXVpcmVkRmllbGRDaGVjayhmaWVsZCkgJiYKKyAgICAgICAgSGFzUmVxdWlyZWRGaWVsZHMoZmllbGQtPm1lc3NhZ2VfdHlwZSgpKSkgeworICAgICAgaWYgKGZpZWxkLT5pc19yZXBlYXRlZCgpKSB7CisgICAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICJpZiAoITo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFsbEFyZUluaXRpYWxpemVkKHRoaXMtPiRuYW1lJCgpKSkiCisgICAgICAgICAgIiByZXR1cm4gZmFsc2U7XG4iLAorICAgICAgICAgICJuYW1lIiwgRmllbGROYW1lKGZpZWxkKSk7CisgICAgICB9IGVsc2UgeworICAgICAgICBpZiAoZmllbGQtPm9wdGlvbnMoKS53ZWFrKCkgfHwgIWZpZWxkLT5jb250YWluaW5nX29uZW9mKCkpIHsKKyAgICAgICAgICAvLyBGb3Igd2VhayBmaWVsZHMsIHVzZSB0aGUgZGF0YSBtZW1iZXIgKDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSopIGluc3RlYWQKKyAgICAgICAgICAvLyBvZiB0aGUgZ2V0dGVyIHRvIGF2b2lkIGEgbGluayBkZXBlbmRlbmN5IG9uIHRoZSB3ZWFrIG1lc3NhZ2UgdHlwZQorICAgICAgICAgIC8vIHdoaWNoIGlzIG9ubHkgZm9yd2FyZCBkZWNsYXJlZC4KKyAgICAgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAgICAgImlmIChoYXNfJG5hbWUkKCkpIHtcbiIKKyAgICAgICAgICAgICAgIiAgaWYgKCF0aGlzLT4kbmFtZSRfLT5Jc0luaXRpYWxpemVkKCkpIHJldHVybiBmYWxzZTtcbiIKKyAgICAgICAgICAgICAgIn1cbiIsCisgICAgICAgICAgICAibmFtZSIsIEZpZWxkTmFtZShmaWVsZCkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICAgImlmIChoYXNfJG5hbWUkKCkpIHtcbiIKKyAgICAgICAgICAgICIgIGlmICghdGhpcy0+JG5hbWUkKCkuSXNJbml0aWFsaXplZCgpKSByZXR1cm4gZmFsc2U7XG4iCisgICAgICAgICAgICAifVxuIiwKKyAgICAgICAgICAgICJuYW1lIiwgRmllbGROYW1lKGZpZWxkKSk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgIH0KKworICBpZiAoZGVzY3JpcHRvcl8tPmV4dGVuc2lvbl9yYW5nZV9jb3VudCgpID4gMCkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIlxuIgorICAgICAgImlmICghX2V4dGVuc2lvbnNfLklzSW5pdGlhbGl6ZWQoKSkgcmV0dXJuIGZhbHNlOyIpOworICB9CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAiICByZXR1cm4gdHJ1ZTtcbiIKKyAgICAifVxuIik7Cit9CisKKworfSAgLy8gbmFtZXNwYWNlIGNwcAorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9tZXNzYWdlLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfbWVzc2FnZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhlMTlhM2YKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfbWVzc2FnZS5oCkBAIC0wLDAgKzEsMjA0IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NQUF9NRVNTQUdFX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1BQX01FU1NBR0VfSF9fCisKKyNpbmNsdWRlIDxtZW1vcnk+CisjaWZuZGVmIF9TSEFSRURfUFRSX0gKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc2hhcmVkX3B0ci5oPgorI2VuZGlmCisjaW5jbHVkZSA8c2V0PgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9maWVsZC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX29wdGlvbnMuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworICBuYW1lc3BhY2UgaW8geworICAgIGNsYXNzIFByaW50ZXI7ICAgICAgICAgICAgIC8vIHByaW50ZXIuaAorICB9Cit9CisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGNwcCB7CisKK2NsYXNzIEVudW1HZW5lcmF0b3I7ICAgICAgICAgICAvLyBlbnVtLmgKK2NsYXNzIEV4dGVuc2lvbkdlbmVyYXRvcjsgICAgICAvLyBleHRlbnNpb24uaAorCitjbGFzcyBNZXNzYWdlR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIC8vIFNlZSBnZW5lcmF0b3IuY2MgZm9yIHRoZSBtZWFuaW5nIG9mIGRsbGV4cG9ydF9kZWNsLgorICBNZXNzYWdlR2VuZXJhdG9yKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGNvbnN0IE9wdGlvbnMmIG9wdGlvbnMpOworICB+TWVzc2FnZUdlbmVyYXRvcigpOworCisgIC8vIEhlYWRlciBzdHVmZi4KKworICAvLyBSZXR1cm4gbmFtZXMgZm9yIGZvd2FyZCBkZWNsYXJhdGlvbnMgb2YgdGhpcyBjbGFzcyBhbmQgYWxsIGl0cyBuZXN0ZWQKKyAgLy8gdHlwZXMuCisgIHZvaWQgRmlsbE1lc3NhZ2VGb3J3YXJkRGVjbGFyYXRpb25zKHNldDxzdHJpbmc+KiBjbGFzc19uYW1lcyk7CisgIHZvaWQgRmlsbEVudW1Gb3J3YXJkRGVjbGFyYXRpb25zKHNldDxzdHJpbmc+KiBlbnVtX25hbWVzKTsKKworICAvLyBHZW5lcmF0ZSBkZWZpbml0aW9ucyBvZiBhbGwgbmVzdGVkIGVudW1zIChtdXN0IGNvbWUgYmVmb3JlIGNsYXNzCisgIC8vIGRlZmluaXRpb25zIGJlY2F1c2UgdGhvc2UgY2xhc3NlcyB1c2UgdGhlIGVudW1zIGRlZmluaXRpb25zKS4KKyAgdm9pZCBHZW5lcmF0ZUVudW1EZWZpbml0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyAgLy8gR2VuZXJhdGUgc3BlY2lhbGl6YXRpb25zIG9mIEdldEVudW1EZXNjcmlwdG9yPE15RW51bT4oKS4KKyAgLy8gUHJlY29uZGl0aW9uOiBpbiA6Omdvb2dsZTo6cHJvdG9idWYgbmFtZXNwYWNlLgorICB2b2lkIEdlbmVyYXRlR2V0RW51bURlc2NyaXB0b3JTcGVjaWFsaXphdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIC8vIEdlbmVyYXRlIGRlZmluaXRpb25zIGZvciB0aGlzIGNsYXNzIGFuZCBhbGwgaXRzIG5lc3RlZCB0eXBlcy4KKyAgdm9pZCBHZW5lcmF0ZUNsYXNzRGVmaW5pdGlvbihpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyAgLy8gR2VuZXJhdGUgZGVmaW5pdGlvbnMgb2YgaW5saW5lIG1ldGhvZHMgKHBsYWNlZCBhdCB0aGUgZW5kIG9mIHRoZSBoZWFkZXIKKyAgLy8gZmlsZSkuCisgIHZvaWQgR2VuZXJhdGVJbmxpbmVNZXRob2RzKGlvOjpQcmludGVyKiBwcmludGVyLCBib29sIGlzX2lubGluZSk7CisKKyAgLy8gRGVwZW5kZW50IG1ldGhvZHMgYXJlIGFsd2F5cyBpbmxpbmUuCisgIHZvaWQgR2VuZXJhdGVEZXBlbmRlbnRJbmxpbmVNZXRob2RzKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworICAvLyBTb3VyY2UgZmlsZSBzdHVmZi4KKworICAvLyBHZW5lcmF0ZSBjb2RlIHdoaWNoIGRlY2xhcmVzIGFsbCB0aGUgZ2xvYmFsIGRlc2NyaXB0b3IgcG9pbnRlcnMgd2hpY2gKKyAgLy8gd2lsbCBiZSBpbml0aWFsaXplZCBieSB0aGUgbWV0aG9kcyBiZWxvdy4KKyAgdm9pZCBHZW5lcmF0ZURlc2NyaXB0b3JEZWNsYXJhdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIC8vIEdlbmVyYXRlIGNvZGUgdGhhdCBpbml0aWFsaXplcyB0aGUgZ2xvYmFsIHZhcmlhYmxlIHN0b3JpbmcgdGhlIG1lc3NhZ2UncworICAvLyBkZXNjcmlwdG9yLgorICB2b2lkIEdlbmVyYXRlRGVzY3JpcHRvckluaXRpYWxpemVyKGlvOjpQcmludGVyKiBwcmludGVyLCBpbnQgaW5kZXgpOworCisgIC8vIEdlbmVyYXRlIGNvZGUgdGhhdCBjYWxscyBNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZE1lc3NhZ2UoKQorICAvLyBmb3IgYWxsIHR5cGVzLgorICB2b2lkIEdlbmVyYXRlVHlwZVJlZ2lzdHJhdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIC8vIEdlbmVyYXRlcyBjb2RlIHRoYXQgYWxsb2NhdGVzIHRoZSBtZXNzYWdlJ3MgZGVmYXVsdCBpbnN0YW5jZS4KKyAgdm9pZCBHZW5lcmF0ZURlZmF1bHRJbnN0YW5jZUFsbG9jYXRvcihpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyAgLy8gR2VuZXJhdGVzIGNvZGUgdGhhdCBpbml0aWFsaXplcyB0aGUgbWVzc2FnZSdzIGRlZmF1bHQgaW5zdGFuY2UuICBUaGlzCisgIC8vIGlzIHNlcGFyYXRlIGZyb20gYWxsb2NhdGluZyBiZWNhdXNlIGFsbCBkZWZhdWx0IGluc3RhbmNlcyBtdXN0IGJlCisgIC8vIGFsbG9jYXRlZCBiZWZvcmUgYW55IGNhbiBiZSBpbml0aWFsaXplZC4KKyAgdm9pZCBHZW5lcmF0ZURlZmF1bHRJbnN0YW5jZUluaXRpYWxpemVyKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworICAvLyBHZW5lcmF0ZXMgY29kZSB0aGF0IHNob3VsZCBiZSBydW4gd2hlbiBTaHV0ZG93blByb3RvYnVmTGlicmFyeSgpIGlzIGNhbGxlZCwKKyAgLy8gdG8gZGVsZXRlIGFsbCBkeW5hbWljYWxseS1hbGxvY2F0ZWQgb2JqZWN0cy4KKyAgdm9pZCBHZW5lcmF0ZVNodXRkb3duQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyAgLy8gR2VuZXJhdGUgYWxsIG5vbi1pbmxpbmUgbWV0aG9kcyBmb3IgdGhpcyBjbGFzcy4KKyAgdm9pZCBHZW5lcmF0ZUNsYXNzTWV0aG9kcyhpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyBwcml2YXRlOgorICAvLyBHZW5lcmF0ZSBkZWNsYXJhdGlvbnMgYW5kIGRlZmluaXRpb25zIG9mIGFjY2Vzc29ycyBmb3IgZmllbGRzLgorICB2b2lkIEdlbmVyYXRlRGVwZW5kZW50QmFzZUNsYXNzRGVmaW5pdGlvbihpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZvaWQgR2VuZXJhdGVEZXBlbmRlbnRGaWVsZEFjY2Vzc29yRGVjbGFyYXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdm9pZCBHZW5lcmF0ZUZpZWxkQWNjZXNzb3JEZWNsYXJhdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2b2lkIEdlbmVyYXRlRGVwZW5kZW50RmllbGRBY2Nlc3NvckRlZmluaXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdm9pZCBHZW5lcmF0ZUZpZWxkQWNjZXNzb3JEZWZpbml0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlciwgYm9vbCBpc19pbmxpbmUpOworCisgIC8vIEdlbmVyYXRlIHRoZSBmaWVsZCBvZmZzZXRzIGFycmF5LgorICB2b2lkIEdlbmVyYXRlT2Zmc2V0cyhpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyAgLy8gR2VuZXJhdGUgY29uc3RydWN0b3JzIGFuZCBkZXN0cnVjdG9yLgorICB2b2lkIEdlbmVyYXRlU3RydWN0b3JzKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworICAvLyBUaGUgY29tcGlsZXIgdHlwaWNhbGx5IGdlbmVyYXRlcyBtdWx0aXBsZSBjb3BpZXMgb2YgZWFjaCBjb25zdHJ1Y3RvciBhbmQKKyAgLy8gZGVzdHJ1Y3RvcjogaHR0cDovL2djYy5nbnUub3JnL2J1Z3MuaHRtbCNub25idWdzX2N4eAorICAvLyBQbGFjaW5nIGNvbW1vbiBjb2RlIGluIGEgc2VwYXJhdGUgbWV0aG9kIHJlZHVjZXMgdGhlIGdlbmVyYXRlZCBjb2RlIHNpemUuCisgIC8vCisgIC8vIEdlbmVyYXRlIHRoZSBzaGFyZWQgY29uc3RydWN0b3IgY29kZS4KKyAgdm9pZCBHZW5lcmF0ZVNoYXJlZENvbnN0cnVjdG9yQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIC8vIEdlbmVyYXRlIHRoZSBzaGFyZWQgZGVzdHJ1Y3RvciBjb2RlLgorICB2b2lkIEdlbmVyYXRlU2hhcmVkRGVzdHJ1Y3RvckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpOworICAvLyBHZW5lcmF0ZSB0aGUgYXJlbmEtc3BlY2lmaWMgZGVzdHJ1Y3RvciBjb2RlLgorICB2b2lkIEdlbmVyYXRlQXJlbmFEZXN0cnVjdG9yQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyAgLy8gR2VuZXJhdGUgc3RhbmRhcmQgTWVzc2FnZSBtZXRob2RzLgorICB2b2lkIEdlbmVyYXRlQ2xlYXIoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2b2lkIEdlbmVyYXRlT25lb2ZDbGVhcihpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZvaWQgR2VuZXJhdGVNZXJnZUZyb21Db2RlZFN0cmVhbShpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheShpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNCb2R5KGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIHRvX2FycmF5KTsKKyAgdm9pZCBHZW5lcmF0ZUJ5dGVTaXplKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdm9pZCBHZW5lcmF0ZU1lcmdlRnJvbShpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZvaWQgR2VuZXJhdGVDb3B5RnJvbShpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZvaWQgR2VuZXJhdGVTd2FwKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdm9pZCBHZW5lcmF0ZUlzSW5pdGlhbGl6ZWQoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIC8vIEhlbHBlcnMgZm9yIEdlbmVyYXRlU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKCkuCisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVPbmVGaWVsZChpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIHVuYm91bmRlZCk7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVPbmVFeHRlbnNpb25SYW5nZSgKKyAgICAgIGlvOjpQcmludGVyKiBwcmludGVyLCBjb25zdCBEZXNjcmlwdG9yOjpFeHRlbnNpb25SYW5nZSogcmFuZ2UsCisgICAgICBib29sIHVuYm91bmRlZCk7CisKKworICAvLyBHZW5lcmF0ZXMgaGFzX2ZvbygpIGZ1bmN0aW9ucyBhbmQgdmFyaWFibGVzIGZvciBzaW5ndWxhciBmaWVsZCBoYXMtYml0cy4KKyAgdm9pZCBHZW5lcmF0ZVNpbmd1bGFyRmllbGRIYXNCaXRzKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIC8vIEdlbmVyYXRlcyBoYXNfZm9vKCkgZnVuY3Rpb25zIGFuZCB2YXJpYWJsZXMgZm9yIG9uZW9mIGZpZWxkIGhhcy1iaXRzLgorICB2b2lkIEdlbmVyYXRlT25lb2ZIYXNCaXRzKGlvOjpQcmludGVyKiBwcmludGVyLCBib29sIGlzX2lubGluZSk7CisgIC8vIEdlbmVyYXRlcyBoYXNfZm9vX2JhcigpIGZ1bmN0aW9ucyBmb3Igb25lb2YgbWVtYmVycy4KKyAgdm9pZCBHZW5lcmF0ZU9uZW9mTWVtYmVySGFzQml0cyhjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1hcDxzdHJpbmcsIHN0cmluZz4mIHZhcnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OlByaW50ZXIqIHByaW50ZXIpOworICAvLyBHZW5lcmF0ZXMgdGhlIGNsZWFyX2ZvbygpIG1ldGhvZCBmb3IgYSBmaWVsZC4KKyAgdm9pZCBHZW5lcmF0ZUZpZWxkQ2xlYXIoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWFwPHN0cmluZywgc3RyaW5nPiYgdmFycywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworICBzdHJpbmcgY2xhc3NuYW1lXzsKKyAgT3B0aW9ucyBvcHRpb25zXzsKKyAgRmllbGRHZW5lcmF0b3JNYXAgZmllbGRfZ2VuZXJhdG9yc187CisgIHZlY3RvcjwgdmVjdG9yPHN0cmluZz4gPiBydW5zX29mX2ZpZWxkc187ICAvLyB0aGF0IG1pZ2h0IGJlIHRyaXZpYWxseSBjbGVhcmVkCisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9hcnJheTxnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPE1lc3NhZ2VHZW5lcmF0b3I+ID4gbmVzdGVkX2dlbmVyYXRvcnNfOworICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfYXJyYXk8Z29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxFbnVtR2VuZXJhdG9yPiA+IGVudW1fZ2VuZXJhdG9yc187CisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9hcnJheTxnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPEV4dGVuc2lvbkdlbmVyYXRvcj4gPiBleHRlbnNpb25fZ2VuZXJhdG9yc187CisgIGludCBudW1fcmVxdWlyZWRfZmllbGRzXzsKKyAgYm9vbCB1c2VzX3N0cmluZ187CisgIGJvb2wgdXNlX2RlcGVuZGVudF9iYXNlXzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoTWVzc2FnZUdlbmVyYXRvcik7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgY3BwCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DUFBfTUVTU0FHRV9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9tZXNzYWdlX2ZpZWxkLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX21lc3NhZ2VfZmllbGQuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjQ1NDU4OQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9tZXNzYWdlX2ZpZWxkLmNjCkBAIC0wLDAgKzEsMTA0NSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfbWVzc2FnZV9maWVsZC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgY3BwIHsKKworbmFtZXNwYWNlIHsKKwordm9pZCBTZXRNZXNzYWdlVmFyaWFibGVzKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICBtYXA8c3RyaW5nLCBzdHJpbmc+KiB2YXJpYWJsZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT3B0aW9ucyYgb3B0aW9ucykgeworICBTZXRDb21tb25GaWVsZFZhcmlhYmxlcyhkZXNjcmlwdG9yLCB2YXJpYWJsZXMsIG9wdGlvbnMpOworICAoKnZhcmlhYmxlcylbInR5cGUiXSA9IEZpZWxkTWVzc2FnZVR5cGVOYW1lKGRlc2NyaXB0b3IpOworICBpZiAoZGVzY3JpcHRvci0+b3B0aW9ucygpLndlYWsoKSB8fCAhZGVzY3JpcHRvci0+Y29udGFpbmluZ19vbmVvZigpKSB7CisgICAgKCp2YXJpYWJsZXMpWyJub25fbnVsbF9wdHJfdG9fbmFtZSJdID0KKyAgICAgICAgU3RyQ2F0KCJ0aGlzLT4iLCAoKnZhcmlhYmxlcylbIm5hbWUiXSwgIl8iKTsKKyAgfQorICAoKnZhcmlhYmxlcylbInN0cmVhbV93cml0ZXIiXSA9ICgqdmFyaWFibGVzKVsiZGVjbGFyZWRfdHlwZSJdICsKKyAgICAgIChIYXNGYXN0QXJyYXlTZXJpYWxpemF0aW9uKGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpLT5maWxlKCkpID8KKyAgICAgICAiTWF5YmVUb0FycmF5IiA6CisgICAgICAgIiIpOworICAvLyBOT1RFOiBFc2NhcGVkIGhlcmUgdG8gdW5ibG9jayBwcm90bzEtPnByb3RvMiBtaWdyYXRpb24uCisgIC8vIFRPRE8obGl1amlzaSk6IEV4dGVuZCB0aGlzIHRvIGFwcGx5IGZvciBvdGhlciBjb25mbGljdGluZyBtZXRob2RzLgorICAoKnZhcmlhYmxlcylbInJlbGVhc2VfbmFtZSJdID0KKyAgICAgIFNhZmVGdW5jdGlvbk5hbWUoZGVzY3JpcHRvci0+Y29udGFpbmluZ190eXBlKCksCisgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0b3IsICJyZWxlYXNlXyIpOworICAoKnZhcmlhYmxlcylbImZ1bGxfbmFtZSJdID0gZGVzY3JpcHRvci0+ZnVsbF9uYW1lKCk7CisgIGlmIChvcHRpb25zLnByb3RvX2ggJiYgSXNGaWVsZERlcGVuZGVudChkZXNjcmlwdG9yKSkgeworICAgICgqdmFyaWFibGVzKVsiZGVwZW5kZW50X3R5cGUiXSA9ICJUOjoiICsgRGVwZW5kZW50VHlwZU5hbWUoZGVzY3JpcHRvcik7CisgICAgKCp2YXJpYWJsZXMpWyJkZXBlbmRlbnRfdHlwZW5hbWUiXSA9CisgICAgICAgICJ0eXBlbmFtZSBUOjoiICsgRGVwZW5kZW50VHlwZU5hbWUoZGVzY3JpcHRvcik7CisgIH0gZWxzZSB7CisgICAgKCp2YXJpYWJsZXMpWyJkZXBlbmRlbnRfdHlwZSJdID0gRmllbGRNZXNzYWdlVHlwZU5hbWUoZGVzY3JpcHRvcik7CisgICAgKCp2YXJpYWJsZXMpWyJkZXBlbmRlbnRfdHlwZW5hbWUiXSA9IEZpZWxkTWVzc2FnZVR5cGVOYW1lKGRlc2NyaXB0b3IpOworICB9Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK01lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitNZXNzYWdlRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE9wdGlvbnMmIG9wdGlvbnMpCisgIDogZGVzY3JpcHRvcl8oZGVzY3JpcHRvciksCisgICAgZGVwZW5kZW50X2ZpZWxkXyhvcHRpb25zLnByb3RvX2ggJiYgSXNGaWVsZERlcGVuZGVudChkZXNjcmlwdG9yKSkgeworICBTZXRNZXNzYWdlVmFyaWFibGVzKGRlc2NyaXB0b3IsICZ2YXJpYWJsZXNfLCBvcHRpb25zKTsKK30KKworTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjp+TWVzc2FnZUZpZWxkR2VuZXJhdG9yKCkge30KKwordm9pZCBNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVQcml2YXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAiJHR5cGUkKiAkbmFtZSRfO1xuIik7Cit9CisKK3ZvaWQgTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlR2V0dGVyRGVjbGFyYXRpb24oaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJjb25zdCAkdHlwZSQmICRuYW1lJCgpIGNvbnN0JGRlcHJlY2F0aW9uJDtcbiIpOworfQorCit2b2lkIE1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZURlcGVuZGVudEFjY2Vzc29yRGVjbGFyYXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmICghZGVwZW5kZW50X2ZpZWxkXykgeworICAgIHJldHVybjsKKyAgfQorICAvLyBBcmVuYSBtYW5pcHVsYXRpb24gY29kZSBpcyBvdXQtb2YtbGluZSBpbiB0aGUgZGVyaXZlZCBtZXNzYWdlIGNsYXNzLgorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkdHlwZSQqIG11dGFibGVfJG5hbWUkKCkkZGVwcmVjYXRpb24kO1xuIgorICAgICIkdHlwZSQqICRyZWxlYXNlX25hbWUkKCkkZGVwcmVjYXRpb24kO1xuIgorICAgICJ2b2lkIHNldF9hbGxvY2F0ZWRfJG5hbWUkKCR0eXBlJCogJG5hbWUkKSRkZXByZWNhdGlvbiQ7XG4iKTsKK30KKwordm9pZCBNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVBY2Nlc3NvckRlY2xhcmF0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoU3VwcG9ydHNBcmVuYXMoZGVzY3JpcHRvcl8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAicHJpdmF0ZTpcbiIKKyAgICAgICAidm9pZCBfc2xvd19tdXRhYmxlXyRuYW1lJCgpJGRlcHJlY2F0aW9uJDtcbiIpOworICAgIGlmIChTdXBwb3J0c0FyZW5hcyhkZXNjcmlwdG9yXy0+bWVzc2FnZV90eXBlKCkpKSB7CisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICJ2b2lkIF9zbG93X3NldF9hbGxvY2F0ZWRfJG5hbWUkKFxuIgorICAgICAgICIgICAgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogbWVzc2FnZV9hcmVuYSwgJHR5cGUkKiogJG5hbWUkKSRkZXByZWNhdGlvbiQ7XG4iKTsKKyAgICB9CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAiJHR5cGUkKiBfc2xvd18kcmVsZWFzZV9uYW1lJCgpJGRlcHJlY2F0aW9uJDtcbiIKKyAgICAgICAicHVibGljOlxuIik7CisgIH0KKyAgR2VuZXJhdGVHZXR0ZXJEZWNsYXJhdGlvbihwcmludGVyKTsKKyAgaWYgKCFkZXBlbmRlbnRfZmllbGRfKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkdHlwZSQqIG11dGFibGVfJG5hbWUkKCkkZGVwcmVjYXRpb24kO1xuIgorICAgICAgIiR0eXBlJCogJHJlbGVhc2VfbmFtZSQoKSRkZXByZWNhdGlvbiQ7XG4iCisgICAgICAidm9pZCBzZXRfYWxsb2NhdGVkXyRuYW1lJCgkdHlwZSQqICRuYW1lJCkkZGVwcmVjYXRpb24kO1xuIik7CisgIH0KKyAgaWYgKFN1cHBvcnRzQXJlbmFzKGRlc2NyaXB0b3JfKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJHR5cGUkKiB1bnNhZmVfYXJlbmFfcmVsZWFzZV8kbmFtZSQoKSRkZXByZWNhdGlvbiQ7XG4iCisgICAgICAidm9pZCB1bnNhZmVfYXJlbmFfc2V0X2FsbG9jYXRlZF8kbmFtZSQoXG4iCisgICAgICAiICAgICR0eXBlJCogJG5hbWUkKSRkZXByZWNhdGlvbiQ7XG4iKTsKKyAgfQorfQorCit2b2lkIE1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6R2VuZXJhdGVOb25JbmxpbmVBY2Nlc3NvckRlZmluaXRpb25zKAorICAgIGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChTdXBwb3J0c0FyZW5hcyhkZXNjcmlwdG9yXykpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgInZvaWQgJGNsYXNzbmFtZSQ6Ol9zbG93X211dGFibGVfJG5hbWUkKCkge1xuIik7CisgICAgICBpZiAoU3VwcG9ydHNBcmVuYXMoZGVzY3JpcHRvcl8tPm1lc3NhZ2VfdHlwZSgpKSkgeworICAgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAgICIgICRuYW1lJF8gPSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hOjpDcmVhdGVNZXNzYWdlPCAkdHlwZSQgPihcbiIKKyAgICAgICAgICAiICAgICAgR2V0QXJlbmFOb1ZpcnR1YWwoKSk7XG4iKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICAgIiAgJG5hbWUkXyA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmE6OkNyZWF0ZTwgJHR5cGUkID4oXG4iCisgICAgICAgICAgIiAgICAgIEdldEFyZW5hTm9WaXJ0dWFsKCkpO1xuIik7CisgICAgICB9CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJ9XG4iCisgICAgICAiJHR5cGUkKiAkY2xhc3NuYW1lJDo6X3Nsb3dfJHJlbGVhc2VfbmFtZSQoKSB7XG4iCisgICAgICAiICBpZiAoJG5hbWUkXyA9PSBOVUxMKSB7XG4iCisgICAgICAiICAgIHJldHVybiBOVUxMO1xuIgorICAgICAgIiAgfSBlbHNlIHtcbiIKKyAgICAgICIgICAgJHR5cGUkKiB0ZW1wID0gbmV3ICR0eXBlJDtcbiIKKyAgICAgICIgICAgdGVtcC0+TWVyZ2VGcm9tKCokbmFtZSRfKTtcbiIKKyAgICAgICIgICAgJG5hbWUkXyA9IE5VTEw7XG4iCisgICAgICAiICAgIHJldHVybiB0ZW1wO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIn1cbiIKKyAgICAgICIkdHlwZSQqICRjbGFzc25hbWUkOjp1bnNhZmVfYXJlbmFfcmVsZWFzZV8kbmFtZSQoKSB7XG4iCisgICAgICAiICAkY2xlYXJfaGFzYml0JFxuIgorICAgICAgIiAgJHR5cGUkKiB0ZW1wID0gJG5hbWUkXztcbiIKKyAgICAgICIgICRuYW1lJF8gPSBOVUxMO1xuIgorICAgICAgIiAgcmV0dXJuIHRlbXA7XG4iCisgICAgICAifVxuIik7CisgICAgaWYgKFN1cHBvcnRzQXJlbmFzKGRlc2NyaXB0b3JfLT5tZXNzYWdlX3R5cGUoKSkpIHsKKyAgICAgIC8vIE5PVEU6IHRoZSBzYW1lIGxvZ2ljIGlzIG1pcnJvcmVkIGluIHdlYWtfbWVzc2FnZV9maWVsZC5jYy4gQW55CisgICAgICAvLyBhcmVuYS1yZWxhdGVkIHNlbWFudGljcyBjaGFuZ2VzIHNob3VsZCBiZSBtYWRlIGluIGJvdGggcGxhY2VzLgorICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgICAidm9pZCAkY2xhc3NuYW1lJDo6X3Nsb3dfc2V0X2FsbG9jYXRlZF8kbmFtZSQoXG4iCisgICAgICAgICAgIiAgICA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBtZXNzYWdlX2FyZW5hLCAkdHlwZSQqKiAkbmFtZSQpIHtcbiIKKyAgICAgICAgICAiICAgIGlmIChtZXNzYWdlX2FyZW5hICE9IE5VTEwgJiYgXG4iCisgICAgICAgICAgIiAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYTo6R2V0QXJlbmEoKiRuYW1lJCkgPT0gTlVMTCkge1xuIgorICAgICAgICAgICIgICAgICBtZXNzYWdlX2FyZW5hLT5Pd24oKiRuYW1lJCk7XG4iCisgICAgICAgICAgIiAgICB9IGVsc2UgaWYgKG1lc3NhZ2VfYXJlbmEgIT1cbiIKKyAgICAgICAgICAiICAgICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYTo6R2V0QXJlbmEoKiRuYW1lJCkpIHtcbiIKKyAgICAgICAgICAiICAgICAgJHR5cGUkKiBuZXdfJG5hbWUkID0gXG4iCisgICAgICAgICAgIiAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmE6OkNyZWF0ZU1lc3NhZ2U8ICR0eXBlJCA+KFxuIgorICAgICAgICAgICIgICAgICAgICAgICBtZXNzYWdlX2FyZW5hKTtcbiIKKyAgICAgICAgICAiICAgICAgbmV3XyRuYW1lJC0+Q29weUZyb20oKiokbmFtZSQpO1xuIgorICAgICAgICAgICIgICAgICAqJG5hbWUkID0gbmV3XyRuYW1lJDtcbiIKKyAgICAgICAgICAiICAgIH1cbiIKKyAgICAgICAgICAifVxuIik7CisgICAgfQorICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAidm9pZCAkY2xhc3NuYW1lJDo6dW5zYWZlX2FyZW5hX3NldF9hbGxvY2F0ZWRfJG5hbWUkKFxuIgorICAgICAgIiAgICAkdHlwZSQqICRuYW1lJCkge1xuIgorICAgICAgLy8gSWYgd2UncmUgbm90IG9uIGFuIGFyZW5hLCBmcmVlIHdoYXRldmVyIHdlIHdlcmUgaG9sZGluZyBiZWZvcmUuCisgICAgICAvLyAoSWYgd2UgYXJlIG9uIGFyZW5hLCB3ZSBjYW4ganVzdCBmb3JnZXQgdGhlIGVhcmxpZXIgcG9pbnRlci4pCisgICAgICAiICBpZiAoR2V0QXJlbmFOb1ZpcnR1YWwoKSA9PSBOVUxMKSB7XG4iCisgICAgICAiICAgIGRlbGV0ZSAkbmFtZSRfO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIiAgJG5hbWUkXyA9ICRuYW1lJDtcbiIKKyAgICAgICIgIGlmICgkbmFtZSQpIHtcbiIKKyAgICAgICIgICAgJHNldF9oYXNiaXQkXG4iCisgICAgICAiICB9IGVsc2Uge1xuIgorICAgICAgIiAgICAkY2xlYXJfaGFzYml0JFxuIgorICAgICAgIiAgfVxuIgorICAgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3Vuc2FmZV9hcmVuYV9zZXRfYWxsb2NhdGVkIgorICAgICAgIjokZnVsbF9uYW1lJClcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorfQorCit2b2lkIE1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZURlcGVuZGVudElubGluZUFjY2Vzc29yRGVmaW5pdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKCFkZXBlbmRlbnRfZmllbGRfKSB7CisgICAgcmV0dXJuOworICB9CisKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXModmFyaWFibGVzXyk7CisgIC8vIEZvciB0aGUgQ1JUUCBiYXNlIGNsYXNzLCBhbGwgbXV0YXRpb24gbWV0aG9kcyBhcmUgZGVwZW5kZW50LCBhbmQgc28KKyAgLy8gdGhleSBtdXN0IGJlIGluIHRoZSBoZWFkZXIuCisgIHZhcmlhYmxlc1siZGVwZW5kZW50X2NsYXNzbmFtZSJdID0KKyAgICAgIERlcGVuZGVudEJhc2VDbGFzc1RlbXBsYXRlTmFtZShkZXNjcmlwdG9yXy0+Y29udGFpbmluZ190eXBlKCkpICsgIjxUPiI7CisgIHZhcmlhYmxlc1sidGhpc19tZXNzYWdlIl0gPSBEZXBlbmRlbnRCYXNlRG93bkNhc3QoKTsKKyAgaWYgKCF2YXJpYWJsZXNbInNldF9oYXNiaXQiXS5lbXB0eSgpKSB7CisgICAgdmFyaWFibGVzWyJzZXRfaGFzYml0Il0gPQorICAgICAgICB2YXJpYWJsZXNbInRoaXNfbWVzc2FnZSJdICsgdmFyaWFibGVzWyJzZXRfaGFzYml0Il07CisgIH0KKyAgaWYgKCF2YXJpYWJsZXNbImNsZWFyX2hhc2JpdCJdLmVtcHR5KCkpIHsKKyAgICB2YXJpYWJsZXNbImNsZWFyX2hhc2JpdCJdID0KKyAgICAgICAgdmFyaWFibGVzWyJ0aGlzX21lc3NhZ2UiXSArIHZhcmlhYmxlc1siY2xlYXJfaGFzYml0Il07CisgIH0KKworICBpZiAoU3VwcG9ydHNBcmVuYXMoZGVzY3JpcHRvcl8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICAgInRlbXBsYXRlIDxjbGFzcyBUPlxuIgorICAgICAgImlubGluZSAkdHlwZSQqICRkZXBlbmRlbnRfY2xhc3NuYW1lJDo6bXV0YWJsZV8kbmFtZSQoKSB7XG4iCisgICAgICAiICAkc2V0X2hhc2JpdCRcbiIKKyAgICAgICIgICRkZXBlbmRlbnRfdHlwZW5hbWUkKiYgJG5hbWUkXyA9ICR0aGlzX21lc3NhZ2UkJG5hbWUkXztcbiIKKyAgICAgICIgIGlmICgkbmFtZSRfID09IE5VTEwpIHtcbiIKKyAgICAgICIgICAgJHRoaXNfbWVzc2FnZSRfc2xvd19tdXRhYmxlXyRuYW1lJCgpO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6JGZ1bGxfbmFtZSQpXG4iCisgICAgICAiICByZXR1cm4gJG5hbWUkXztcbiIKKyAgICAgICJ9XG4iCisgICAgICAidGVtcGxhdGUgPGNsYXNzIFQ+XG4iCisgICAgICAiaW5saW5lICR0eXBlJCogJGRlcGVuZGVudF9jbGFzc25hbWUkOjokcmVsZWFzZV9uYW1lJCgpIHtcbiIKKyAgICAgICIgICRkZXBlbmRlbnRfdHlwZW5hbWUkKiYgJG5hbWUkXyA9ICR0aGlzX21lc3NhZ2UkJG5hbWUkXztcbiIKKyAgICAgICIgICRjbGVhcl9oYXNiaXQkXG4iCisgICAgICAiICBpZiAoJHRoaXNfbWVzc2FnZSRHZXRBcmVuYU5vVmlydHVhbCgpICE9IE5VTEwpIHtcbiIKKyAgICAgICIgICAgcmV0dXJuICR0aGlzX21lc3NhZ2UkX3Nsb3dfJHJlbGVhc2VfbmFtZSQoKTtcbiIKKyAgICAgICIgIH0gZWxzZSB7XG4iCisgICAgICAiICAgICRkZXBlbmRlbnRfdHlwZW5hbWUkKiB0ZW1wID0gJG5hbWUkXztcbiIKKyAgICAgICIgICAgJG5hbWUkXyA9IE5VTEw7XG4iCisgICAgICAiICAgIHJldHVybiB0ZW1wO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIn1cbiIKKyAgICAgICJ0ZW1wbGF0ZSA8Y2xhc3MgVD5cbiIKKyAgICAgICJpbmxpbmUgdm9pZCAkZGVwZW5kZW50X2NsYXNzbmFtZSQ6OiIKKyAgICAgICJzZXRfYWxsb2NhdGVkXyRuYW1lJCgkdHlwZSQqICRuYW1lJCkge1xuIgorICAgICAgIiAgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogbWVzc2FnZV9hcmVuYSA9ICR0aGlzX21lc3NhZ2UkR2V0QXJlbmFOb1ZpcnR1YWwoKTtcbiIKKyAgICAgICIgICRkZXBlbmRlbnRfdHlwZW5hbWUkKiYgJG5hbWUkXyA9ICR0aGlzX21lc3NhZ2UkJG5hbWUkXztcbiIKKyAgICAgICIgIGlmIChtZXNzYWdlX2FyZW5hID09IE5VTEwpIHtcbiIKKyAgICAgICIgICAgZGVsZXRlICRuYW1lJF87XG4iCisgICAgICAiICB9XG4iCisgICAgICAiICBpZiAoJG5hbWUkICE9IE5VTEwpIHtcbiIpOworICAgIGlmIChTdXBwb3J0c0FyZW5hcyhkZXNjcmlwdG9yXy0+bWVzc2FnZV90eXBlKCkpKSB7CisgICAgICAvLyBJZiB3ZSdyZSBvbiBhbiBhcmVuYSBhbmQgdGhlIGluY29taW5nIG1lc3NhZ2UgaXMgbm90LCBzaW1wbHkgT3duKCkgaXQKKyAgICAgIC8vIHJhdGhlciB0aGFuIGNvcHkgdG8gdGhlIGFyZW5hIC0tIGVpdGhlciB3YXkgd2UgbmVlZCBhIGhlYXAgZGVhbGxvYywKKyAgICAgIC8vIHNvIHdlIG1pZ2h0IGFzIHdlbGwgZGVmZXIgaXQuIE90aGVyd2lzZSwgaWYgaW5jb21pbmcgbWVzc2FnZSBpcyBvbiBhCisgICAgICAvLyBkaWZmZXJlbnQgb3duZXJzaGlwIGRvbWFpbiAoc3BlY2lmaWMgYXJlbmEsIG9yIHRoZSBoZWFwKSB0aGFuIHdlIGFyZSwKKyAgICAgIC8vIGNvcHkgdG8gb3VyIGFyZW5hIChvciBoZWFwLCBhcyB0aGUgY2FzZSBtYXkgYmUpLgorICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICAgICAiICAgICR0aGlzX21lc3NhZ2UkX3Nsb3dfc2V0X2FsbG9jYXRlZF8kbmFtZSQobWVzc2FnZV9hcmVuYSwgIgorICAgICAgICAiJiRuYW1lJCk7XG4iKTsKKyAgICB9IGVsc2UgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICAgICAiICAgIGlmIChtZXNzYWdlX2FyZW5hICE9IE5VTEwpIHtcbiIKKyAgICAgICAgIiAgICAgIG1lc3NhZ2VfYXJlbmEtPk93bigkbmFtZSQpO1xuIgorICAgICAgICAiICAgIH1cbiIpOworICAgIH0KKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXMsCisgICAgICAiICB9XG4iCisgICAgICAiICAkbmFtZSRfID0gJG5hbWUkO1xuIgorICAgICAgIiAgaWYgKCRuYW1lJCkge1xuIgorICAgICAgIiAgICAkc2V0X2hhc2JpdCRcbiIKKyAgICAgICIgIH0gZWxzZSB7XG4iCisgICAgICAiICAgICRjbGVhcl9oYXNiaXQkXG4iCisgICAgICAiICB9XG4iCisgICAgICAvLyBUT0RPKGRsaik6IG1vdmUgaW5zZXJ0aW9uIHBvaW50cyB0byBtZXNzYWdlIGNsYXNzLgorICAgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6JGZ1bGxfbmFtZSQpXG4iCisgICAgICAifVxuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICAgInRlbXBsYXRlIDxjbGFzcyBUPlxuIgorICAgICAgImlubGluZSAkdHlwZSQqICRkZXBlbmRlbnRfY2xhc3NuYW1lJDo6bXV0YWJsZV8kbmFtZSQoKSB7XG4iCisgICAgICAiICAkc2V0X2hhc2JpdCRcbiIKKyAgICAgICIgICRkZXBlbmRlbnRfdHlwZW5hbWUkKiYgJG5hbWUkXyA9ICR0aGlzX21lc3NhZ2UkJG5hbWUkXztcbiIKKyAgICAgICIgIGlmICgkbmFtZSRfID09IE5VTEwpIHtcbiIKKyAgICAgICIgICAgJG5hbWUkXyA9IG5ldyAkZGVwZW5kZW50X3R5cGVuYW1lJDtcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOiRmdWxsX25hbWUkKVxuIgorICAgICAgIiAgcmV0dXJuICRuYW1lJF87XG4iCisgICAgICAifVxuIgorICAgICAgInRlbXBsYXRlIDxjbGFzcyBUPlxuIgorICAgICAgImlubGluZSAkdHlwZSQqICRkZXBlbmRlbnRfY2xhc3NuYW1lJDo6JHJlbGVhc2VfbmFtZSQoKSB7XG4iCisgICAgICAiICAkY2xlYXJfaGFzYml0JFxuIgorICAgICAgIiAgJGRlcGVuZGVudF90eXBlbmFtZSQqJiAkbmFtZSRfID0gJHRoaXNfbWVzc2FnZSQkbmFtZSRfO1xuIgorICAgICAgIiAgJGRlcGVuZGVudF90eXBlbmFtZSQqIHRlbXAgPSAkbmFtZSRfO1xuIgorICAgICAgIiAgJG5hbWUkXyA9IE5VTEw7XG4iCisgICAgICAiICByZXR1cm4gdGVtcDtcbiIKKyAgICAgICJ9XG4iCisgICAgICAidGVtcGxhdGUgPGNsYXNzIFQ+XG4iCisgICAgICAiaW5saW5lIHZvaWQgJGRlcGVuZGVudF9jbGFzc25hbWUkOjoiCisgICAgICAic2V0X2FsbG9jYXRlZF8kbmFtZSQoJHR5cGUkKiAkbmFtZSQpIHtcbiIKKyAgICAgICIgICRkZXBlbmRlbnRfdHlwZW5hbWUkKiYgJG5hbWUkXyA9ICR0aGlzX21lc3NhZ2UkJG5hbWUkXztcbiIKKyAgICAgICIgIGRlbGV0ZSAkbmFtZSRfO1xuIik7CisKKyAgICBpZiAoU3VwcG9ydHNBcmVuYXMoZGVzY3JpcHRvcl8tPm1lc3NhZ2VfdHlwZSgpKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICAgIiAgaWYgKCRuYW1lJCAhPSBOVUxMICYmIHN0YXRpY19jYXN0PCAkZGVwZW5kZW50X3R5cGVuYW1lJCogPigkbmFtZSQpIgorICAgICAgIi0+R2V0QXJlbmEoKSAhPSBOVUxMKSB7XG4iCisgICAgICAiICAgICRkZXBlbmRlbnRfdHlwZW5hbWUkKiBuZXdfJG5hbWUkID0gbmV3ICRkZXBlbmRlbnRfdHlwZW5hbWUkO1xuIgorICAgICAgIiAgICBuZXdfJG5hbWUkLT5Db3B5RnJvbSgqJG5hbWUkKTtcbiIKKyAgICAgICIgICAgJG5hbWUkID0gbmV3XyRuYW1lJDtcbiIKKyAgICAgICIgIH1cbiIpOworICAgIH0KKworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAgICIgICRuYW1lJF8gPSAkbmFtZSQ7XG4iCisgICAgICAiICBpZiAoJG5hbWUkKSB7XG4iCisgICAgICAiICAgICRzZXRfaGFzYml0JFxuIgorICAgICAgIiAgfSBlbHNlIHtcbiIKKyAgICAgICIgICAgJGNsZWFyX2hhc2JpdCRcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOiRmdWxsX25hbWUkKVxuIgorICAgICAgIn1cbiIpOworICB9Cit9CisKK3ZvaWQgTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlSW5saW5lQWNjZXNzb3JEZWZpbml0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGlzX2lubGluZSkgY29uc3QgeworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlcyh2YXJpYWJsZXNfKTsKKyAgdmFyaWFibGVzWyJpbmxpbmUiXSA9IGlzX2lubGluZSA/ICJpbmxpbmUgIiA6ICIiOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXMsCisgICAgIiRpbmxpbmUkY29uc3QgJHR5cGUkJiAkY2xhc3NuYW1lJDo6JG5hbWUkKCkgY29uc3Qge1xuIgorICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6JGZ1bGxfbmFtZSQpXG4iKTsKKworICBQcmludEhhbmRsaW5nT3B0aW9uYWxTdGF0aWNJbml0aWFsaXplcnMoCisgICAgdmFyaWFibGVzLCBkZXNjcmlwdG9yXy0+ZmlsZSgpLCBwcmludGVyLAorICAgIC8vIFdpdGggc3RhdGljIGluaXRpYWxpemVycy4KKyAgICAiICByZXR1cm4gJG5hbWUkXyAhPSBOVUxMID8gKiRuYW1lJF8gOiAqZGVmYXVsdF9pbnN0YW5jZV8tPiRuYW1lJF87XG4iLAorICAgIC8vIFdpdGhvdXQuCisgICAgIiAgcmV0dXJuICRuYW1lJF8gIT0gTlVMTCA/ICokbmFtZSRfIDogKmRlZmF1bHRfaW5zdGFuY2UoKS4kbmFtZSRfO1xuIik7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywgIn1cbiIpOworCisgIGlmIChkZXBlbmRlbnRfZmllbGRfKSB7CisgICAgcmV0dXJuOworICB9CisKKyAgaWYgKFN1cHBvcnRzQXJlbmFzKGRlc2NyaXB0b3JfKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAgICIkaW5saW5lJCIKKyAgICAgICIkdHlwZSQqICRjbGFzc25hbWUkOjptdXRhYmxlXyRuYW1lJCgpIHtcbiIKKyAgICAgICIgICRzZXRfaGFzYml0JFxuIgorICAgICAgIiAgaWYgKCRuYW1lJF8gPT0gTlVMTCkge1xuIgorICAgICAgIiAgICBfc2xvd19tdXRhYmxlXyRuYW1lJCgpO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6JGZ1bGxfbmFtZSQpXG4iCisgICAgICAiICByZXR1cm4gJG5hbWUkXztcbiIKKyAgICAgICJ9XG4iCisgICAgICAiJGlubGluZSQiCisgICAgICAiJHR5cGUkKiAkY2xhc3NuYW1lJDo6JHJlbGVhc2VfbmFtZSQoKSB7XG4iCisgICAgICAiICAkY2xlYXJfaGFzYml0JFxuIgorICAgICAgIiAgaWYgKEdldEFyZW5hTm9WaXJ0dWFsKCkgIT0gTlVMTCkge1xuIgorICAgICAgIiAgICByZXR1cm4gX3Nsb3dfJHJlbGVhc2VfbmFtZSQoKTtcbiIKKyAgICAgICIgIH0gZWxzZSB7XG4iCisgICAgICAiICAgICR0eXBlJCogdGVtcCA9ICRuYW1lJF87XG4iCisgICAgICAiICAgICRuYW1lJF8gPSBOVUxMO1xuIgorICAgICAgIiAgICByZXR1cm4gdGVtcDtcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICJ9XG4iCisgICAgICAiJGlubGluZSQgIgorICAgICAgInZvaWQgJGNsYXNzbmFtZSQ6OnNldF9hbGxvY2F0ZWRfJG5hbWUkKCR0eXBlJCogJG5hbWUkKSB7XG4iCisgICAgICAiICA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBtZXNzYWdlX2FyZW5hID0gR2V0QXJlbmFOb1ZpcnR1YWwoKTtcbiIKKyAgICAgICIgIGlmIChtZXNzYWdlX2FyZW5hID09IE5VTEwpIHtcbiIKKyAgICAgICIgICAgZGVsZXRlICRuYW1lJF87XG4iCisgICAgICAiICB9XG4iCisgICAgICAiICBpZiAoJG5hbWUkICE9IE5VTEwpIHtcbiIpOworICAgIGlmIChTdXBwb3J0c0FyZW5hcyhkZXNjcmlwdG9yXy0+bWVzc2FnZV90eXBlKCkpKSB7CisgICAgICAvLyBJZiB3ZSdyZSBvbiBhbiBhcmVuYSBhbmQgdGhlIGluY29taW5nIG1lc3NhZ2UgaXMgbm90LCBzaW1wbHkgT3duKCkgaXQKKyAgICAgIC8vIHJhdGhlciB0aGFuIGNvcHkgdG8gdGhlIGFyZW5hIC0tIGVpdGhlciB3YXkgd2UgbmVlZCBhIGhlYXAgZGVhbGxvYywKKyAgICAgIC8vIHNvIHdlIG1pZ2h0IGFzIHdlbGwgZGVmZXIgaXQuIE90aGVyd2lzZSwgaWYgaW5jb21pbmcgbWVzc2FnZSBpcyBvbiBhCisgICAgICAvLyBkaWZmZXJlbnQgb3duZXJzaGlwIGRvbWFpbiAoc3BlY2lmaWMgYXJlbmEsIG9yIHRoZSBoZWFwKSB0aGFuIHdlIGFyZSwKKyAgICAgIC8vIGNvcHkgdG8gb3VyIGFyZW5hIChvciBoZWFwLCBhcyB0aGUgY2FzZSBtYXkgYmUpLgorICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICAgICAiICAgIF9zbG93X3NldF9hbGxvY2F0ZWRfJG5hbWUkKG1lc3NhZ2VfYXJlbmEsICYkbmFtZSQpO1xuIik7CisgICAgfSBlbHNlIHsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAgICAgIiAgICBpZiAobWVzc2FnZV9hcmVuYSAhPSBOVUxMKSB7XG4iCisgICAgICAgICIgICAgICBtZXNzYWdlX2FyZW5hLT5Pd24oJG5hbWUkKTtcbiIKKyAgICAgICAgIiAgICB9XG4iKTsKKyAgICB9CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICAgIiAgfVxuIgorICAgICAgIiAgJG5hbWUkXyA9ICRuYW1lJDtcbiIKKyAgICAgICIgIGlmICgkbmFtZSQpIHtcbiIKKyAgICAgICIgICAgJHNldF9oYXNiaXQkXG4iCisgICAgICAiICB9IGVsc2Uge1xuIgorICAgICAgIiAgICAkY2xlYXJfaGFzYml0JFxuIgorICAgICAgIiAgfVxuIgorICAgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6JGZ1bGxfbmFtZSQpXG4iCisgICAgICAifVxuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICAgIiRpbmxpbmUkIgorICAgICAgIiR0eXBlJCogJGNsYXNzbmFtZSQ6Om11dGFibGVfJG5hbWUkKCkge1xuIgorICAgICAgIiAgJHNldF9oYXNiaXQkXG4iCisgICAgICAiICBpZiAoJG5hbWUkXyA9PSBOVUxMKSB7XG4iCisgICAgICAiICAgICRuYW1lJF8gPSBuZXcgJHR5cGUkO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6JGZ1bGxfbmFtZSQpXG4iCisgICAgICAiICByZXR1cm4gJG5hbWUkXztcbiIKKyAgICAgICJ9XG4iCisgICAgICAiJGlubGluZSQiCisgICAgICAiJHR5cGUkKiAkY2xhc3NuYW1lJDo6JHJlbGVhc2VfbmFtZSQoKSB7XG4iCisgICAgICAiICAkY2xlYXJfaGFzYml0JFxuIgorICAgICAgIiAgJHR5cGUkKiB0ZW1wID0gJG5hbWUkXztcbiIKKyAgICAgICIgICRuYW1lJF8gPSBOVUxMO1xuIgorICAgICAgIiAgcmV0dXJuIHRlbXA7XG4iCisgICAgICAifVxuIgorICAgICAgIiRpbmxpbmUkIgorICAgICAgInZvaWQgJGNsYXNzbmFtZSQ6OnNldF9hbGxvY2F0ZWRfJG5hbWUkKCR0eXBlJCogJG5hbWUkKSB7XG4iCisgICAgICAiICBkZWxldGUgJG5hbWUkXztcbiIpOworCisgICAgaWYgKFN1cHBvcnRzQXJlbmFzKGRlc2NyaXB0b3JfLT5tZXNzYWdlX3R5cGUoKSkpIHsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAgICIgIGlmICgkbmFtZSQgIT0gTlVMTCAmJiAkbmFtZSQtPkdldEFyZW5hKCkgIT0gTlVMTCkge1xuIgorICAgICAgIiAgICAkdHlwZSQqIG5ld18kbmFtZSQgPSBuZXcgJHR5cGUkO1xuIgorICAgICAgIiAgICBuZXdfJG5hbWUkLT5Db3B5RnJvbSgqJG5hbWUkKTtcbiIKKyAgICAgICIgICAgJG5hbWUkID0gbmV3XyRuYW1lJDtcbiIKKyAgICAgICIgIH1cbiIpOworICAgIH0KKworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAgICIgICRuYW1lJF8gPSAkbmFtZSQ7XG4iCisgICAgICAiICBpZiAoJG5hbWUkKSB7XG4iCisgICAgICAiICAgICRzZXRfaGFzYml0JFxuIgorICAgICAgIiAgfSBlbHNlIHtcbiIKKyAgICAgICIgICAgJGNsZWFyX2hhc2JpdCRcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOiRmdWxsX25hbWUkKVxuIgorICAgICAgIn1cbiIpOworICB9Cit9CisKK3ZvaWQgTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQ2xlYXJpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyaWFibGVzKHZhcmlhYmxlc18pOworICB2YXJpYWJsZXNbInRoaXNfbWVzc2FnZSJdID0gZGVwZW5kZW50X2ZpZWxkXyA/IERlcGVuZGVudEJhc2VEb3duQ2FzdCgpIDogIiI7CisgIGlmICghSGFzRmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIC8vIElmIHdlIGRvbid0IGhhdmUgaGFzLWJpdHMsIG1lc3NhZ2UgcHJlc2VuY2UgaXMgaW5kaWNhdGVkIG9ubHkgYnkgcHRyICE9CisgICAgLy8gTlVMTC4gVGh1cyBvbiBjbGVhciwgd2UgbmVlZCB0byBkZWxldGUgdGhlIG9iamVjdC4KKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXMsCisgICAgICAiaWYgKCR0aGlzX21lc3NhZ2UkR2V0QXJlbmFOb1ZpcnR1YWwoKSA9PSBOVUxMICYmICIKKyAgICAgICIkdGhpc19tZXNzYWdlJCRuYW1lJF8gIT0gTlVMTCkgZGVsZXRlICR0aGlzX21lc3NhZ2UkJG5hbWUkXztcbiIKKyAgICAgICIkdGhpc19tZXNzYWdlJCRuYW1lJF8gPSBOVUxMO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICAgImlmICgkdGhpc19tZXNzYWdlJCRuYW1lJF8gIT0gTlVMTCkgJHRoaXNfbWVzc2FnZSQkbmFtZSRfLT4iCisgICAgICAiJGRlcGVuZGVudF90eXBlJDo6Q2xlYXIoKTtcbiIpOworICB9Cit9CisKK3ZvaWQgTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAibXV0YWJsZV8kbmFtZSQoKS0+JHR5cGUkOjpNZXJnZUZyb20oZnJvbS4kbmFtZSQoKSk7XG4iKTsKK30KKwordm9pZCBNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTd2FwcGluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgInN0ZDo6c3dhcCgkbmFtZSRfLCBvdGhlci0+JG5hbWUkXyk7XG4iKTsKK30KKwordm9pZCBNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVDb25zdHJ1Y3RvckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgIiRuYW1lJF8gPSBOVUxMO1xuIik7Cit9CisKK3ZvaWQgTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2VGcm9tQ29kZWRTdHJlYW0oaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKGRlc2NyaXB0b3JfLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX01FU1NBR0UpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIkRPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZE1lc3NhZ2VOb1ZpcnR1YWwoXG4iCisgICAgICAiICAgICBpbnB1dCwgbXV0YWJsZV8kbmFtZSQoKSkpO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRHcm91cE5vVmlydHVhbChcbiIKKyAgICAgICIgICAgICAkbnVtYmVyJCwgaW5wdXQsIG11dGFibGVfJG5hbWUkKCkpKTtcbiIpOworICB9Cit9CisKK3ZvaWQgTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZSRzdHJlYW1fd3JpdGVyJChcbiIKKyAgICAiICAkbnVtYmVyJCwgKiRub25fbnVsbF9wdHJfdG9fbmFtZSQsIG91dHB1dCk7XG4iKTsKK30KKwordm9pZCBNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpcbiIKKyAgICAiICBXcml0ZSRkZWNsYXJlZF90eXBlJE5vVmlydHVhbFRvQXJyYXkoXG4iCisgICAgIiAgICAkbnVtYmVyJCwgKiRub25fbnVsbF9wdHJfdG9fbmFtZSQsIHRhcmdldCk7XG4iKTsKK30KKwordm9pZCBNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVCeXRlU2l6ZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJ0b3RhbF9zaXplICs9ICR0YWdfc2l6ZSQgK1xuIgorICAgICIgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjokZGVjbGFyZWRfdHlwZSRTaXplTm9WaXJ0dWFsKFxuIgorICAgICIgICAgKiRub25fbnVsbF9wdHJfdG9fbmFtZSQpO1xuIik7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworTWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3I6OgorTWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT3B0aW9ucyYgb3B0aW9ucykKKyAgOiBNZXNzYWdlRmllbGRHZW5lcmF0b3IoZGVzY3JpcHRvciwgb3B0aW9ucyksCisgICAgZGVwZW5kZW50X2Jhc2VfKG9wdGlvbnMucHJvdG9faCkgeworICBTZXRDb21tb25PbmVvZkZpZWxkVmFyaWFibGVzKGRlc2NyaXB0b3IsICZ2YXJpYWJsZXNfKTsKK30KKworTWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3I6On5NZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcigpIHt9CisKKwordm9pZCBNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZURlcGVuZGVudEFjY2Vzc29yRGVjbGFyYXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIE9uZW9mIGZpZWxkIGdldHRlcnMgbXVzdCBiZSBkZXBlbmRlbnQgYXMgdGhleSBjYWxsIGRlZmF1bHRfaW5zdGFuY2UoKS4KKyAgLy8gT3RoZXJ3aXNlLCB0aGUgbG9naWMgaXMgdGhlIHNhbWUgYXMgTWVzc2FnZUZpZWxkcy4KKyAgaWYgKCFkZXBlbmRlbnRfZmllbGRfKSB7CisgICAgcmV0dXJuOworICB9CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiY29uc3QgJHR5cGUkJiAkbmFtZSQoKSBjb25zdCRkZXByZWNhdGlvbiQ7XG4iKTsKKyAgTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZURlcGVuZGVudEFjY2Vzc29yRGVjbGFyYXRpb25zKHByaW50ZXIpOworfQorCit2b2lkIE1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlR2V0dGVyRGVjbGFyYXRpb24oaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gT25lb2YgZmllbGQgZ2V0dGVycyBtdXN0IGJlIGRlcGVuZGVudCBhcyB0aGV5IGNhbGwgZGVmYXVsdF9pbnN0YW5jZSgpLgorICAvLyBVbmxpa2UgTWVzc2FnZUZpZWxkLCB0aGlzIG1lYW5zIHRoZXJlIGlzIG5vIChub24tZGVwZW5kZW50KSBnZXR0ZXIgdG8KKyAgLy8gZ2VuZXJhdGUuCisgIGlmIChkZXBlbmRlbnRfZmllbGRfKSB7CisgICAgcmV0dXJuOworICB9CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiY29uc3QgJHR5cGUkJiAkbmFtZSQoKSBjb25zdCRkZXByZWNhdGlvbiQ7XG4iKTsKK30KKwordm9pZCBNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZURlcGVuZGVudElubGluZUFjY2Vzc29yRGVmaW5pdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gRm9yIHRoZSBDUlRQIGJhc2UgY2xhc3MsIGFsbCBtdXRhdGlvbiBtZXRob2RzIGFyZSBkZXBlbmRlbnQsIGFuZCBzbworICAvLyB0aGV5IG11c3QgYmUgaW4gdGhlIGhlYWRlci4KKyAgaWYgKCFkZXBlbmRlbnRfYmFzZV8pIHsKKyAgICByZXR1cm47CisgIH0KKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXModmFyaWFibGVzXyk7CisgIHZhcmlhYmxlc1siaW5saW5lIl0gPSAiaW5saW5lICI7CisgIHZhcmlhYmxlc1siZGVwZW5kZW50X2NsYXNzbmFtZSJdID0KKyAgICAgIERlcGVuZGVudEJhc2VDbGFzc1RlbXBsYXRlTmFtZShkZXNjcmlwdG9yXy0+Y29udGFpbmluZ190eXBlKCkpICsgIjxUPiI7CisgIHZhcmlhYmxlc1sidGhpc19tZXNzYWdlIl0gPSAicmVpbnRlcnByZXRfY2FzdDxUKj4odGhpcyktPiI7CisgIC8vIENvbnN0IG1lc3NhZ2UgYWNjZXNzIGlzIG5lZWRlZCBmb3IgdGhlIGRlcGVuZGVudCBnZXR0ZXIuCisgIHZhcmlhYmxlc1sidGhpc19jb25zdF9tZXNzYWdlIl0gPSAicmVpbnRlcnByZXRfY2FzdDxjb25zdCBUKj4odGhpcyktPiI7CisgIHZhcmlhYmxlc1sidG1wbCJdID0gInRlbXBsYXRlIDxjbGFzcyBUPlxuIjsKKyAgdmFyaWFibGVzWyJmaWVsZF9tZW1iZXIiXSA9IHZhcmlhYmxlc1sidGhpc19tZXNzYWdlIl0gKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyaWFibGVzWyJvbmVvZl9wcmVmaXgiXSArIHZhcmlhYmxlc1sibmFtZSJdICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJfIjsKKyAgSW50ZXJuYWxHZW5lcmF0ZUlubGluZUFjY2Vzc29yRGVmaW5pdGlvbnModmFyaWFibGVzLCBwcmludGVyKTsKK30KKwordm9pZCBNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUlubGluZUFjY2Vzc29yRGVmaW5pdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc19pbmxpbmUpIGNvbnN0IHsKKyAgaWYgKGRlcGVuZGVudF9iYXNlXykgeworICAgIHJldHVybjsKKyAgfQorICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlcyh2YXJpYWJsZXNfKTsKKyAgdmFyaWFibGVzWyJpbmxpbmUiXSA9IGlzX2lubGluZSA/ICJpbmxpbmUgIiA6ICIiOworICB2YXJpYWJsZXNbImRlcGVuZGVudF9jbGFzc25hbWUiXSA9IHZhcmlhYmxlc1siY2xhc3NuYW1lIl07CisgIHZhcmlhYmxlc1sidGhpc19tZXNzYWdlIl0gPSAiIjsKKyAgdmFyaWFibGVzWyJ0aGlzX2NvbnN0X21lc3NhZ2UiXSA9ICIiOworICB2YXJpYWJsZXNbInRtcGwiXSA9ICIiOworICB2YXJpYWJsZXNbImZpZWxkX21lbWJlciJdID0KKyAgICAgIHZhcmlhYmxlc1sib25lb2ZfcHJlZml4Il0gKyB2YXJpYWJsZXNbIm5hbWUiXSArICJfIjsKKyAgdmFyaWFibGVzWyJkZXBlbmRlbnRfdHlwZSJdID0gdmFyaWFibGVzWyJ0eXBlIl07CisgIEludGVybmFsR2VuZXJhdGVJbmxpbmVBY2Nlc3NvckRlZmluaXRpb25zKHZhcmlhYmxlcywgcHJpbnRlcik7Cit9CisKK3ZvaWQgTWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVOb25JbmxpbmVBY2Nlc3NvckRlZmluaXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyaWFibGVzKHZhcmlhYmxlc18pOworICB2YXJpYWJsZXNbImZpZWxkX21lbWJlciJdID0KKyAgICAgIHZhcmlhYmxlc1sib25lb2ZfcHJlZml4Il0gKyB2YXJpYWJsZXNbIm5hbWUiXSArICJfIjsKKworICAvL3ByaW50ZXItPlByaW50KHZhcmlhYmxlcywKK30KKwordm9pZCBNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitJbnRlcm5hbEdlbmVyYXRlSW5saW5lQWNjZXNzb3JEZWZpbml0aW9ucyhjb25zdCBtYXA8c3RyaW5nLCBzdHJpbmc+JiB2YXJpYWJsZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXMsCisgICAgIiR0bXBsJCIKKyAgICAiJGlubGluZSQgIgorICAgICJjb25zdCAkdHlwZSQmICRkZXBlbmRlbnRfY2xhc3NuYW1lJDo6JG5hbWUkKCkgY29uc3Qge1xuIgorICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6JGZ1bGxfbmFtZSQpXG4iCisgICAgIiAgcmV0dXJuICR0aGlzX2NvbnN0X21lc3NhZ2UkaGFzXyRuYW1lJCgpXG4iCisgICAgIiAgICAgID8gKiR0aGlzX2NvbnN0X21lc3NhZ2UkJG9uZW9mX3ByZWZpeCQkbmFtZSRfXG4iCisgICAgIiAgICAgIDogJGRlcGVuZGVudF90eXBlJDo6ZGVmYXVsdF9pbnN0YW5jZSgpO1xuIgorICAgICJ9XG4iKTsKKworICBpZiAoU3VwcG9ydHNBcmVuYXMoZGVzY3JpcHRvcl8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICAgIiR0bXBsJCIKKyAgICAgICIkaW5saW5lJCIKKyAgICAgICIkdHlwZSQqICRkZXBlbmRlbnRfY2xhc3NuYW1lJDo6bXV0YWJsZV8kbmFtZSQoKSB7XG4iCisgICAgICAiICBpZiAoISR0aGlzX21lc3NhZ2UkaGFzXyRuYW1lJCgpKSB7XG4iCisgICAgICAiICAgICR0aGlzX21lc3NhZ2UkY2xlYXJfJG9uZW9mX25hbWUkKCk7XG4iCisgICAgICAiICAgICR0aGlzX21lc3NhZ2Ukc2V0X2hhc18kbmFtZSQoKTtcbiIpOworICAgIGlmIChTdXBwb3J0c0FyZW5hcyhkZXNjcmlwdG9yXy0+bWVzc2FnZV90eXBlKCkpKSB7CisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXMsCisgICAgICAgICAiICAgICRmaWVsZF9tZW1iZXIkID0gXG4iCisgICAgICAgICAiICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYTo6Q3JlYXRlTWVzc2FnZTwgJGRlcGVuZGVudF90eXBlbmFtZSQgPihcbiIKKyAgICAgICAgICIgICAgICAkdGhpc19tZXNzYWdlJEdldEFyZW5hTm9WaXJ0dWFsKCkpO1xuIik7CisgICAgfSBlbHNlIHsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAgICAgICIgICAgJHRoaXNfbWVzc2FnZSQkb25lb2ZfcHJlZml4JCRuYW1lJF8gPSBcbiIKKyAgICAgICAgICIgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hOjpDcmVhdGU8ICRkZXBlbmRlbnRfdHlwZW5hbWUkID4oXG4iCisgICAgICAgICAiICAgICAgJHRoaXNfbWVzc2FnZSRHZXRBcmVuYU5vVmlydHVhbCgpKTtcbiIpOworICAgIH0KKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXMsCisgICAgICAiICB9XG4iCisgICAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTokZnVsbF9uYW1lJClcbiIKKyAgICAgICIgIHJldHVybiAkZmllbGRfbWVtYmVyJDtcbiIKKyAgICAgICJ9XG4iCisgICAgICAiJHRtcGwkIgorICAgICAgIiRpbmxpbmUkIgorICAgICAgIiR0eXBlJCogJGRlcGVuZGVudF9jbGFzc25hbWUkOjokcmVsZWFzZV9uYW1lJCgpIHtcbiIKKyAgICAgICIgIGlmICgkdGhpc19tZXNzYWdlJGhhc18kbmFtZSQoKSkge1xuIgorICAgICAgIiAgICAkdGhpc19tZXNzYWdlJGNsZWFyX2hhc18kb25lb2ZfbmFtZSQoKTtcbiIKKyAgICAgICIgICAgaWYgKCR0aGlzX21lc3NhZ2UkR2V0QXJlbmFOb1ZpcnR1YWwoKSAhPSBOVUxMKSB7XG4iCisgICAgICAvLyBOLkIuOiBzYWZlIHRvIHVzZSB0aGUgdW5kZXJseWluZyBmaWVsZCBwb2ludGVyIGhlcmUgYmVjYXVzZSB3ZSBhcmUgc3VyZQorICAgICAgLy8gdGhhdCBpdCBpcyBub24tTlVMTCAoYmVjYXVzZSBoYXNfJG5hbWUkKCkgcmV0dXJuZWQgdHJ1ZSkuCisgICAgICAiICAgICAgJGRlcGVuZGVudF90eXBlbmFtZSQqIHRlbXAgPSBuZXcgJGRlcGVuZGVudF90eXBlbmFtZSQ7XG4iCisgICAgICAiICAgICAgdGVtcC0+TWVyZ2VGcm9tKCokZmllbGRfbWVtYmVyJCk7XG4iCisgICAgICAiICAgICAgJGZpZWxkX21lbWJlciQgPSBOVUxMO1xuIgorICAgICAgIiAgICAgIHJldHVybiB0ZW1wO1xuIgorICAgICAgIiAgICB9IGVsc2Uge1xuIgorICAgICAgIiAgICAgICRkZXBlbmRlbnRfdHlwZW5hbWUkKiB0ZW1wID0gJGZpZWxkX21lbWJlciQ7XG4iCisgICAgICAiICAgICAgJGZpZWxkX21lbWJlciQgPSBOVUxMO1xuIgorICAgICAgIiAgICAgIHJldHVybiB0ZW1wO1xuIgorICAgICAgIiAgICB9XG4iCisgICAgICAiICB9IGVsc2Uge1xuIgorICAgICAgIiAgICByZXR1cm4gTlVMTDtcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICJ9XG4iCisgICAgICAiJHRtcGwkIgorICAgICAgIiRpbmxpbmUkIgorICAgICAgInZvaWQgJGRlcGVuZGVudF9jbGFzc25hbWUkOjoiCisgICAgICAic2V0X2FsbG9jYXRlZF8kbmFtZSQoJHR5cGUkKiAkbmFtZSQpIHtcbiIKKyAgICAgICIgICR0aGlzX21lc3NhZ2UkY2xlYXJfJG9uZW9mX25hbWUkKCk7XG4iCisgICAgICAiICBpZiAoJG5hbWUkKSB7XG4iKTsKKworICAgIGlmIChTdXBwb3J0c0FyZW5hcyhkZXNjcmlwdG9yXy0+bWVzc2FnZV90eXBlKCkpKSB7CisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXMsCisgICAgICAgIC8vIElmIGluY29taW5nIG1lc3NhZ2UgaXMgb24gdGhlIGhlYXAgYW5kIHdlIGFyZSBvbiBhbiBhcmVuYSwganVzdCBPd24oKQorICAgICAgICAvLyBpdCAoc2VlIGFib3ZlKS4gSWYgaXQncyBvbiBhIGRpZmZlcmVudCBhcmVuYSB0aGFuIHdlIGFyZSBvciBvbmUgb2YgdXMKKyAgICAgICAgLy8gaXMgb24gdGhlIGhlYXAsIHdlIG1ha2UgYSBjb3B5IHRvIG91ciBhcmVuYS9oZWFwLgorICAgICAgICAiICAgIGlmICgkdGhpc19tZXNzYWdlJEdldEFyZW5hTm9WaXJ0dWFsKCkgIT0gTlVMTCAmJlxuIgorICAgICAgICAiICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hOjpHZXRBcmVuYSgkbmFtZSQpID09IE5VTEwpIHtcbiIKKyAgICAgICAgIiAgICAgICR0aGlzX21lc3NhZ2UkR2V0QXJlbmFOb1ZpcnR1YWwoKS0+T3duKCRuYW1lJCk7XG4iCisgICAgICAgICIgICAgfSBlbHNlIGlmICgkdGhpc19tZXNzYWdlJEdldEFyZW5hTm9WaXJ0dWFsKCkgIT1cbiIKKyAgICAgICAgIiAgICAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmE6OkdldEFyZW5hKCRuYW1lJCkpIHtcbiIKKyAgICAgICAgIiAgICAgICRkZXBlbmRlbnRfdHlwZW5hbWUkKiBuZXdfJG5hbWUkID0gXG4iCisgICAgICAgICIgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYTo6Q3JlYXRlTWVzc2FnZTwgJGRlcGVuZGVudF90eXBlbmFtZSQgPihcbiIKKyAgICAgICAgIiAgICAgICAgICAkdGhpc19tZXNzYWdlJEdldEFyZW5hTm9WaXJ0dWFsKCkpO1xuIgorICAgICAgICAiICAgICAgbmV3XyRuYW1lJC0+Q29weUZyb20oKiRuYW1lJCk7XG4iCisgICAgICAgICIgICAgICAkbmFtZSQgPSBuZXdfJG5hbWUkO1xuIgorICAgICAgICAiICAgIH1cbiIpOworICAgIH0gZWxzZSB7CisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXMsCisgICAgICAgICIgICAgaWYgKCR0aGlzX21lc3NhZ2UkR2V0QXJlbmFOb1ZpcnR1YWwoKSAhPSBOVUxMKSB7XG4iCisgICAgICAgICIgICAgICAkdGhpc19tZXNzYWdlJEdldEFyZW5hTm9WaXJ0dWFsKCktPk93bigkbmFtZSQpO1xuIgorICAgICAgICAiICAgIH1cbiIpOworICAgIH0KKworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAgICIgICAgJHRoaXNfbWVzc2FnZSRzZXRfaGFzXyRuYW1lJCgpO1xuIgorICAgICAgIiAgICAkZmllbGRfbWVtYmVyJCA9ICRuYW1lJDtcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOiRmdWxsX25hbWUkKVxuIgorICAgICAgIn1cbiIKKyAgICAgICIkaW5saW5lJCAkdHlwZSQqICRjbGFzc25hbWUkOjp1bnNhZmVfYXJlbmFfcmVsZWFzZV8kbmFtZSQoKSB7XG4iCisgICAgICAiICBpZiAoaGFzXyRuYW1lJCgpKSB7XG4iCisgICAgICAiICAgIGNsZWFyX2hhc18kb25lb2ZfbmFtZSQoKTtcbiIKKyAgICAgICIgICAgJHR5cGUkKiB0ZW1wID0gJG9uZW9mX3ByZWZpeCQkbmFtZSRfO1xuIgorICAgICAgIiAgICAkb25lb2ZfcHJlZml4JCRuYW1lJF8gPSBOVUxMO1xuIgorICAgICAgIiAgICByZXR1cm4gdGVtcDtcbiIKKyAgICAgICIgIH0gZWxzZSB7XG4iCisgICAgICAiICAgIHJldHVybiBOVUxMO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIn1cbiIKKyAgICAgICIkaW5saW5lJCB2b2lkICRjbGFzc25hbWUkOjp1bnNhZmVfYXJlbmFfc2V0X2FsbG9jYXRlZF8kbmFtZSQiCisgICAgICAiKCR0eXBlJCogJG5hbWUkKSB7XG4iCisgICAgICAvLyBXZSByZWx5IG9uIHRoZSBvbmVvZiBjbGVhciBtZXRob2QgdG8gZnJlZSB0aGUgZWFybGllciBjb250ZW50cyBvZiB0aGlzCisgICAgICAvLyBvbmVvZi4gV2UgY2FuIGRpcmVjdGx5IHVzZSB0aGUgcG9pbnRlciB3ZSdyZSBnaXZlbiB0byBzZXQgdGhlIG5ldworICAgICAgLy8gdmFsdWUuCisgICAgICAiICBjbGVhcl8kb25lb2ZfbmFtZSQoKTtcbiIKKyAgICAgICIgIGlmICgkbmFtZSQpIHtcbiIKKyAgICAgICIgICAgc2V0X2hhc18kbmFtZSQoKTtcbiIKKyAgICAgICIgICAgJG9uZW9mX3ByZWZpeCQkbmFtZSRfID0gJG5hbWUkO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3Vuc2FmZV9hcmVuYV9zZXRfYWxsb2NhdGVkOiIKKyAgICAgICIkZnVsbF9uYW1lJClcbiIKKyAgICAgICJ9XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXMsCisgICAgICAiJHRtcGwkIgorICAgICAgIiRpbmxpbmUkIgorICAgICAgIiR0eXBlJCogJGRlcGVuZGVudF9jbGFzc25hbWUkOjptdXRhYmxlXyRuYW1lJCgpIHtcbiIKKyAgICAgICIgIGlmICghJHRoaXNfbWVzc2FnZSRoYXNfJG5hbWUkKCkpIHtcbiIKKyAgICAgICIgICAgJHRoaXNfbWVzc2FnZSRjbGVhcl8kb25lb2ZfbmFtZSQoKTtcbiIKKyAgICAgICIgICAgJHRoaXNfbWVzc2FnZSRzZXRfaGFzXyRuYW1lJCgpO1xuIgorICAgICAgIiAgICAkZmllbGRfbWVtYmVyJCA9IG5ldyAkZGVwZW5kZW50X3R5cGVuYW1lJDtcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOiRmdWxsX25hbWUkKVxuIgorICAgICAgIiAgcmV0dXJuICRmaWVsZF9tZW1iZXIkO1xuIgorICAgICAgIn1cbiIKKyAgICAgICIkdG1wbCQiCisgICAgICAiJGlubGluZSQiCisgICAgICAiJHR5cGUkKiAkZGVwZW5kZW50X2NsYXNzbmFtZSQ6OiRyZWxlYXNlX25hbWUkKCkge1xuIgorICAgICAgIiAgaWYgKCR0aGlzX21lc3NhZ2UkaGFzXyRuYW1lJCgpKSB7XG4iCisgICAgICAiICAgICR0aGlzX21lc3NhZ2UkY2xlYXJfaGFzXyRvbmVvZl9uYW1lJCgpO1xuIgorICAgICAgIiAgICAkZGVwZW5kZW50X3R5cGVuYW1lJCogdGVtcCA9ICRmaWVsZF9tZW1iZXIkO1xuIgorICAgICAgIiAgICAkZmllbGRfbWVtYmVyJCA9IE5VTEw7XG4iCisgICAgICAiICAgIHJldHVybiB0ZW1wO1xuIgorICAgICAgIiAgfSBlbHNlIHtcbiIKKyAgICAgICIgICAgcmV0dXJuIE5VTEw7XG4iCisgICAgICAiICB9XG4iCisgICAgICAifVxuIgorICAgICAgIiR0bXBsJCIKKyAgICAgICIkaW5saW5lJCIKKyAgICAgICJ2b2lkICRkZXBlbmRlbnRfY2xhc3NuYW1lJDo6IgorICAgICAgInNldF9hbGxvY2F0ZWRfJG5hbWUkKCR0eXBlJCogJG5hbWUkKSB7XG4iCisgICAgICAiICAkdGhpc19tZXNzYWdlJGNsZWFyXyRvbmVvZl9uYW1lJCgpO1xuIgorICAgICAgIiAgaWYgKCRuYW1lJCkge1xuIik7CisgICAgaWYgKFN1cHBvcnRzQXJlbmFzKGRlc2NyaXB0b3JfLT5tZXNzYWdlX3R5cGUoKSkpIHsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAgICAgIiAgICBpZiAoc3RhdGljX2Nhc3Q8ICRkZXBlbmRlbnRfdHlwZW5hbWUkKj4oJG5hbWUkKS0+IgorICAgICAgICAiR2V0QXJlbmEoKSAhPSBOVUxMKSB7XG4iCisgICAgICAgICIgICAgICAkZGVwZW5kZW50X3R5cGVuYW1lJCogbmV3XyRuYW1lJCA9IG5ldyAkZGVwZW5kZW50X3R5cGVuYW1lJDtcbiIKKyAgICAgICAgIiAgICAgIG5ld18kbmFtZSQtPkNvcHlGcm9tKCokbmFtZSQpO1xuIgorICAgICAgICAiICAgICAgJG5hbWUkID0gbmV3XyRuYW1lJDtcbiIKKyAgICAgICAgIiAgICB9XG4iKTsKKyAgICB9CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICAgIiAgICAkdGhpc19tZXNzYWdlJHNldF9oYXNfJG5hbWUkKCk7XG4iCisgICAgICAiICAgICRmaWVsZF9tZW1iZXIkID0gJG5hbWUkO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6JGZ1bGxfbmFtZSQpXG4iCisgICAgICAifVxuIik7CisgIH0KK30KKwordm9pZCBNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUNsZWFyaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlcyh2YXJpYWJsZXNfKTsKKyAgdmFyaWFibGVzWyJ0aGlzX21lc3NhZ2UiXSA9IGRlcGVuZGVudF9maWVsZF8gPyBEZXBlbmRlbnRCYXNlRG93bkNhc3QoKSA6ICIiOworICBpZiAoU3VwcG9ydHNBcmVuYXMoZGVzY3JpcHRvcl8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICAgImlmICgkdGhpc19tZXNzYWdlJEdldEFyZW5hTm9WaXJ0dWFsKCkgPT0gTlVMTCkge1xuIgorICAgICAgIiAgZGVsZXRlICR0aGlzX21lc3NhZ2UkJG9uZW9mX3ByZWZpeCQkbmFtZSRfO1xuIgorICAgICAgIn1cbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAgICJkZWxldGUgJHRoaXNfbWVzc2FnZSQkb25lb2ZfcHJlZml4JCRuYW1lJF87XG4iKTsKKyAgfQorfQorCit2b2lkIE1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU3dhcHBpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIERvbid0IHByaW50IGFueSBzd2FwcGluZyBjb2RlLiBTd2FwcGluZyB0aGUgdW5pb24gd2lsbCBzd2FwIHRoaXMgZmllbGQuCit9CisKK3ZvaWQgTWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVDb25zdHJ1Y3RvckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gRG9uJ3QgcHJpbnQgYW55IGNvbnN0cnVjdG9yIGNvZGUuIFRoZSBmaWVsZCBpcyBpbiBhIHVuaW9uLiBXZSBhbGxvY2F0ZQorICAvLyBzcGFjZSBvbmx5IHdoZW4gdGhpcyBmaWVsZCBpcyB1c2VkLgorfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK1JlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK1JlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE9wdGlvbnMmIG9wdGlvbnMpCisgIDogZGVzY3JpcHRvcl8oZGVzY3JpcHRvciksCisgICAgZGVwZW5kZW50X2ZpZWxkXyhvcHRpb25zLnByb3RvX2ggJiYgSXNGaWVsZERlcGVuZGVudChkZXNjcmlwdG9yKSksCisgICAgZGVwZW5kZW50X2dldHRlcl8oZGVwZW5kZW50X2ZpZWxkXyAmJiBvcHRpb25zLnNhZmVfYm91bmRhcnlfY2hlY2spIHsKKyAgU2V0TWVzc2FnZVZhcmlhYmxlcyhkZXNjcmlwdG9yLCAmdmFyaWFibGVzXywgb3B0aW9ucyk7Cit9CisKK1JlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjp+UmVwZWF0ZWRNZXNzYWdlRmllbGRHZW5lcmF0b3IoKSB7fQorCit2b2lkIFJlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlUHJpdmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCAkdHlwZSQgPiAkbmFtZSRfO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorSW50ZXJuYWxHZW5lcmF0ZVR5cGVEZXBlbmRlbnRBY2Nlc3NvckRlY2xhcmF0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkdHlwZSQqIG11dGFibGVfJG5hbWUkKGludCBpbmRleCkkZGVwcmVjYXRpb24kO1xuIgorICAgICIkdHlwZSQqIGFkZF8kbmFtZSQoKSRkZXByZWNhdGlvbiQ7XG4iKTsKKyAgaWYgKGRlcGVuZGVudF9nZXR0ZXJfKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8ICR0eXBlJCA+JlxuIgorICAgICAgIiAgICAkbmFtZSQoKSBjb25zdCRkZXByZWNhdGlvbiQ7XG4iKTsKKyAgfQorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICI6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8ICR0eXBlJCA+KlxuIgorICAgICIgICAgbXV0YWJsZV8kbmFtZSQoKSRkZXByZWNhdGlvbiQ7XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZE1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZURlcGVuZGVudEFjY2Vzc29yRGVjbGFyYXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChkZXBlbmRlbnRfZ2V0dGVyXykgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiY29uc3QgJHR5cGUkJiAkbmFtZSQoaW50IGluZGV4KSBjb25zdCRkZXByZWNhdGlvbiQ7XG4iKTsKKyAgfQorICBpZiAoZGVwZW5kZW50X2ZpZWxkXykgeworICAgIEludGVybmFsR2VuZXJhdGVUeXBlRGVwZW5kZW50QWNjZXNzb3JEZWNsYXJhdGlvbnMocHJpbnRlcik7CisgIH0KK30KKwordm9pZCBSZXBlYXRlZE1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUFjY2Vzc29yRGVjbGFyYXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmICghZGVwZW5kZW50X2dldHRlcl8pIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImNvbnN0ICR0eXBlJCYgJG5hbWUkKGludCBpbmRleCkgY29uc3QkZGVwcmVjYXRpb24kO1xuIik7CisgIH0KKyAgaWYgKCFkZXBlbmRlbnRfZmllbGRfKSB7CisgICAgSW50ZXJuYWxHZW5lcmF0ZVR5cGVEZXBlbmRlbnRBY2Nlc3NvckRlY2xhcmF0aW9ucyhwcmludGVyKTsKKyAgfQorICBpZiAoIWRlcGVuZGVudF9nZXR0ZXJfKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8ICR0eXBlJCA+JlxuIgorICAgICAgIiAgICAkbmFtZSQoKSBjb25zdCRkZXByZWNhdGlvbiQ7XG4iKTsKKyAgfQorfQorCit2b2lkIFJlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlRGVwZW5kZW50SW5saW5lQWNjZXNzb3JEZWZpbml0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoIWRlcGVuZGVudF9maWVsZF8pIHsKKyAgICByZXR1cm47CisgIH0KKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXModmFyaWFibGVzXyk7CisgIC8vIEZvciB0aGUgQ1JUUCBiYXNlIGNsYXNzLCBhbGwgbXV0YXRpb24gbWV0aG9kcyBhcmUgZGVwZW5kZW50LCBhbmQgc28KKyAgLy8gdGhleSBtdXN0IGJlIGluIHRoZSBoZWFkZXIuCisgIHZhcmlhYmxlc1siZGVwZW5kZW50X2NsYXNzbmFtZSJdID0KKyAgICAgIERlcGVuZGVudEJhc2VDbGFzc1RlbXBsYXRlTmFtZShkZXNjcmlwdG9yXy0+Y29udGFpbmluZ190eXBlKCkpICsgIjxUPiI7CisgIHZhcmlhYmxlc1sidGhpc19tZXNzYWdlIl0gPSBEZXBlbmRlbnRCYXNlRG93bkNhc3QoKTsKKyAgdmFyaWFibGVzWyJ0aGlzX2NvbnN0X21lc3NhZ2UiXSA9IERlcGVuZGVudEJhc2VDb25zdERvd25DYXN0KCk7CisKKyAgaWYgKGRlcGVuZGVudF9nZXR0ZXJfKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICAgInRlbXBsYXRlIDxjbGFzcyBUPlxuIgorICAgICAgImlubGluZSBjb25zdCAkdHlwZSQmICRkZXBlbmRlbnRfY2xhc3NuYW1lJDo6JG5hbWUkKGludCBpbmRleCkgY29uc3Qge1xuIgorICAgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDokZnVsbF9uYW1lJClcbiIKKyAgICAgICIgIHJldHVybiAkdGhpc19jb25zdF9tZXNzYWdlJCRuYW1lJF8uJGNwcGdldCQoaW5kZXgpO1xuIgorICAgICAgIn1cbiIpOworICB9CisKKyAgLy8gR2VuZXJhdGUgcGVyLWVsZW1lbnQgYWNjZXNzb3JzOgorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXMsCisgICAgInRlbXBsYXRlIDxjbGFzcyBUPlxuIgorICAgICJpbmxpbmUgJHR5cGUkKiAkZGVwZW5kZW50X2NsYXNzbmFtZSQ6Om11dGFibGVfJG5hbWUkKGludCBpbmRleCkge1xuIgorICAgIC8vIFRPRE8oZGxqKTogbW92ZSBpbnNlcnRpb24gcG9pbnRzCisgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6JGZ1bGxfbmFtZSQpXG4iCisgICAgIiAgcmV0dXJuICR0aGlzX21lc3NhZ2UkJG5hbWUkXy5NdXRhYmxlKGluZGV4KTtcbiIKKyAgICAifVxuIgorICAgICJ0ZW1wbGF0ZSA8Y2xhc3MgVD5cbiIKKyAgICAiaW5saW5lICR0eXBlJCogJGRlcGVuZGVudF9jbGFzc25hbWUkOjphZGRfJG5hbWUkKCkge1xuIgorICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6JGZ1bGxfbmFtZSQpXG4iCisgICAgIiAgcmV0dXJuICR0aGlzX21lc3NhZ2UkJG5hbWUkXy5BZGQoKTtcbiIKKyAgICAifVxuIik7CisKKworICBpZiAoZGVwZW5kZW50X2dldHRlcl8pIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXMsCisgICAgICAidGVtcGxhdGUgPGNsYXNzIFQ+XG4iCisgICAgICAiaW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgJHR5cGUkID4mXG4iCisgICAgICAiJGRlcGVuZGVudF9jbGFzc25hbWUkOjokbmFtZSQoKSBjb25zdCB7XG4iCisgICAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDokZnVsbF9uYW1lJClcbiIKKyAgICAgICIgIHJldHVybiAkdGhpc19jb25zdF9tZXNzYWdlJCRuYW1lJF87XG4iCisgICAgICAifVxuIik7CisgIH0KKworICAvLyBHZW5lcmF0ZSBtdXRhYmxlIGFjY2VzcyB0byB0aGUgZW50aXJlIGxpc3Q6CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAidGVtcGxhdGUgPGNsYXNzIFQ+XG4iCisgICAgImlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8ICR0eXBlJCA+KlxuIgorICAgICIkZGVwZW5kZW50X2NsYXNzbmFtZSQ6Om11dGFibGVfJG5hbWUkKCkge1xuIgorICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6JGZ1bGxfbmFtZSQpXG4iCisgICAgIiAgcmV0dXJuICYkdGhpc19tZXNzYWdlJCRuYW1lJF87XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIFJlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlSW5saW5lQWNjZXNzb3JEZWZpbml0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGlzX2lubGluZSkgY29uc3QgeworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlcyh2YXJpYWJsZXNfKTsKKyAgdmFyaWFibGVzWyJpbmxpbmUiXSA9IGlzX2lubGluZSA/ICJpbmxpbmUgIiA6ICIiOworCisgIGlmICghZGVwZW5kZW50X2dldHRlcl8pIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXMsCisgICAgICAiJGlubGluZSQiCisgICAgICAiY29uc3QgJHR5cGUkJiAkY2xhc3NuYW1lJDo6JG5hbWUkKGludCBpbmRleCkgY29uc3Qge1xuIgorICAgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDokZnVsbF9uYW1lJClcbiIKKyAgICAgICIgIHJldHVybiAkbmFtZSRfLiRjcHBnZXQkKGluZGV4KTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorCisgIGlmICghZGVwZW5kZW50X2ZpZWxkXykgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAgICIkaW5saW5lJCIKKyAgICAgICIkdHlwZSQqICRjbGFzc25hbWUkOjptdXRhYmxlXyRuYW1lJChpbnQgaW5kZXgpIHtcbiIKKyAgICAgIC8vIFRPRE8oZGxqKTogbW92ZSBpbnNlcnRpb24gcG9pbnRzCisgICAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTokZnVsbF9uYW1lJClcbiIKKyAgICAgICIgIHJldHVybiAkbmFtZSRfLk11dGFibGUoaW5kZXgpO1xuIgorICAgICAgIn1cbiIKKyAgICAgICIkaW5saW5lJCIKKyAgICAgICIkdHlwZSQqICRjbGFzc25hbWUkOjphZGRfJG5hbWUkKCkge1xuIgorICAgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDokZnVsbF9uYW1lJClcbiIKKyAgICAgICIgIHJldHVybiAkbmFtZSRfLkFkZCgpO1xuIgorICAgICAgIn1cbiIpOworICB9CisKKworICBpZiAoIWRlcGVuZGVudF9maWVsZF8pIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXMsCisgICAgICAiJGlubGluZSQiCisgICAgICAiOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCAkdHlwZSQgPipcbiIKKyAgICAgICIkY2xhc3NuYW1lJDo6bXV0YWJsZV8kbmFtZSQoKSB7XG4iCisgICAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0OiRmdWxsX25hbWUkKVxuIgorICAgICAgIiAgcmV0dXJuICYkbmFtZSRfO1xuIgorICAgICAgIn1cbiIpOworICB9CisgIGlmICghZGVwZW5kZW50X2dldHRlcl8pIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXMsCisgICAgICAiJGlubGluZSQiCisgICAgICAiY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCAkdHlwZSQgPiZcbiIKKyAgICAgICIkY2xhc3NuYW1lJDo6JG5hbWUkKCkgY29uc3Qge1xuIgorICAgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6JGZ1bGxfbmFtZSQpXG4iCisgICAgICAiICByZXR1cm4gJG5hbWUkXztcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorfQorCit2b2lkIFJlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQ2xlYXJpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyaWFibGVzKHZhcmlhYmxlc18pOworICB2YXJpYWJsZXNbInRoaXNfbWVzc2FnZSJdID0gZGVwZW5kZW50X2ZpZWxkXyA/IERlcGVuZGVudEJhc2VEb3duQ2FzdCgpIDogIiI7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywgIiR0aGlzX21lc3NhZ2UkJG5hbWUkXy5DbGVhcigpO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAiJG5hbWUkXy5NZXJnZUZyb20oZnJvbS4kbmFtZSRfKTtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU3dhcHBpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sICIkbmFtZSRfLlVuc2FmZUFyZW5hU3dhcCgmb3RoZXItPiRuYW1lJF8pO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVDb25zdHJ1Y3RvckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gTm90IG5lZWRlZCBmb3IgcmVwZWF0ZWQgZmllbGRzLgorfQorCit2b2lkIFJlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2VGcm9tQ29kZWRTdHJlYW0oaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKGRlc2NyaXB0b3JfLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX01FU1NBR0UpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIkRPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6IgorICAgICAgIlJlYWRNZXNzYWdlTm9WaXJ0dWFsTm9SZWN1cnNpb25EZXB0aChcbiIKKyAgICAgICIgICAgICBpbnB1dCwgYWRkXyRuYW1lJCgpKSk7XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIkRPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6IgorICAgICAgIlJlYWRHcm91cE5vVmlydHVhbE5vUmVjdXJzaW9uRGVwdGgoXG4iCisgICAgICAiICAgICAgJG51bWJlciQsIGlucHV0LCBhZGRfJG5hbWUkKCkpKTtcbiIpOworICB9Cit9CisKK3ZvaWQgUmVwZWF0ZWRNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT4kbmFtZSRfc2l6ZSgpOyBpIDwgbjsgaSsrKSB7XG4iCisgICAgIiAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlJHN0cmVhbV93cml0ZXIkKFxuIgorICAgICIgICAgJG51bWJlciQsIHRoaXMtPiRuYW1lJChpKSwgb3V0cHV0KTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImZvciAodW5zaWduZWQgaW50IGkgPSAwLCBuID0gdGhpcy0+JG5hbWUkX3NpemUoKTsgaSA8IG47IGkrKykge1xuIgorICAgICIgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpcbiIKKyAgICAiICAgIFdyaXRlJGRlY2xhcmVkX3R5cGUkTm9WaXJ0dWFsVG9BcnJheShcbiIKKyAgICAiICAgICAgJG51bWJlciQsIHRoaXMtPiRuYW1lJChpKSwgdGFyZ2V0KTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVCeXRlU2l6ZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJ0b3RhbF9zaXplICs9ICR0YWdfc2l6ZSQgKiB0aGlzLT4kbmFtZSRfc2l6ZSgpO1xuIgorICAgICJmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPiRuYW1lJF9zaXplKCk7IGkrKykge1xuIgorICAgICIgIHRvdGFsX3NpemUgKz1cbiIKKyAgICAiICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjokZGVjbGFyZWRfdHlwZSRTaXplTm9WaXJ0dWFsKFxuIgorICAgICIgICAgICB0aGlzLT4kbmFtZSQoaSkpO1xuIgorICAgICJ9XG4iKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGNwcAorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9tZXNzYWdlX2ZpZWxkLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfbWVzc2FnZV9maWVsZC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM1ZWZkMGYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfbWVzc2FnZV9maWVsZC5oCkBAIC0wLDAgKzEsMTUwIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NQUF9NRVNTQUdFX0ZJRUxEX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1BQX01FU1NBR0VfRklFTERfSF9fCisKKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2ZpZWxkLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgY3BwIHsKKworY2xhc3MgTWVzc2FnZUZpZWxkR2VuZXJhdG9yIDogcHVibGljIEZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IE1lc3NhZ2VGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBPcHRpb25zJiBvcHRpb25zKTsKKyAgfk1lc3NhZ2VGaWVsZEdlbmVyYXRvcigpOworCisgIC8vIGltcGxlbWVudHMgRmllbGRHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIHZvaWQgR2VuZXJhdGVQcml2YXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVEZXBlbmRlbnRBY2Nlc3NvckRlY2xhcmF0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVBY2Nlc3NvckRlY2xhcmF0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVEZXBlbmRlbnRJbmxpbmVBY2Nlc3NvckRlZmluaXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUlubGluZUFjY2Vzc29yRGVmaW5pdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaXNfaW5saW5lKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU5vbklubGluZUFjY2Vzc29yRGVmaW5pdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQ2xlYXJpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVN3YXBwaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVDb25zdHJ1Y3RvckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2VGcm9tQ29kZWRTdHJlYW0oaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnl0ZVNpemUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgcHJvdGVjdGVkOgorICB2b2lkIEdlbmVyYXRlQXJlbmFNYW5pcHVsYXRpb25Db2RlKGNvbnN0IG1hcDxzdHJpbmcsIHN0cmluZz4mIHZhcmlhYmxlcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlR2V0dGVyRGVjbGFyYXRpb24oaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcl87CisgIGNvbnN0IGJvb2wgZGVwZW5kZW50X2ZpZWxkXzsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXNfOworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKE1lc3NhZ2VGaWVsZEdlbmVyYXRvcik7Cit9OworCitjbGFzcyBNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvciA6IHB1YmxpYyBNZXNzYWdlRmllbGRHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgTWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBPcHRpb25zJiBvcHRpb25zKTsKKyAgfk1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yKCk7CisKKyAgLy8gaW1wbGVtZW50cyBGaWVsZEdlbmVyYXRvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgdm9pZCBHZW5lcmF0ZURlcGVuZGVudEFjY2Vzc29yRGVjbGFyYXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZURlcGVuZGVudElubGluZUFjY2Vzc29yRGVmaW5pdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSW5saW5lQWNjZXNzb3JEZWZpbml0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc19pbmxpbmUpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTm9uSW5saW5lQWNjZXNzb3JEZWZpbml0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVDbGVhcmluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU3dhcHBpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUNvbnN0cnVjdG9yQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyBwcm90ZWN0ZWQ6CisgIHZvaWQgR2VuZXJhdGVHZXR0ZXJEZWNsYXJhdGlvbihpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyBwcml2YXRlOgorICB2b2lkIEludGVybmFsR2VuZXJhdGVJbmxpbmVBY2Nlc3NvckRlZmluaXRpb25zKAorICAgICAgY29uc3QgbWFwPHN0cmluZywgc3RyaW5nPiYgdmFyaWFibGVzLCBpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyAgY29uc3QgYm9vbCBkZXBlbmRlbnRfYmFzZV87CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcik7Cit9OworCitjbGFzcyBSZXBlYXRlZE1lc3NhZ2VGaWVsZEdlbmVyYXRvciA6IHB1YmxpYyBGaWVsZEdlbmVyYXRvciB7CisgcHVibGljOgorICBleHBsaWNpdCBSZXBlYXRlZE1lc3NhZ2VGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE9wdGlvbnMmIG9wdGlvbnMpOworICB+UmVwZWF0ZWRNZXNzYWdlRmllbGRHZW5lcmF0b3IoKTsKKworICAvLyBpbXBsZW1lbnRzIEZpZWxkR2VuZXJhdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICB2b2lkIEdlbmVyYXRlUHJpdmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRGVwZW5kZW50QWNjZXNzb3JEZWNsYXJhdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQWNjZXNzb3JEZWNsYXJhdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRGVwZW5kZW50SW5saW5lQWNjZXNzb3JEZWZpbml0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVJbmxpbmVBY2Nlc3NvckRlZmluaXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGlzX2lubGluZSkgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVDbGVhcmluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU3dhcHBpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUNvbnN0cnVjdG9yQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnZUZyb21Db2RlZFN0cmVhbShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCeXRlU2l6ZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyBwcml2YXRlOgorICB2b2lkIEludGVybmFsR2VuZXJhdGVUeXBlRGVwZW5kZW50QWNjZXNzb3JEZWNsYXJhdGlvbnMoCisgICAgICBpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgY29uc3QgYm9vbCBkZXBlbmRlbnRfZmllbGRfOworICBjb25zdCBib29sIGRlcGVuZGVudF9nZXR0ZXJfOworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlc187CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFJlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBjcHAKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NQUF9NRVNTQUdFX0ZJRUxEX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX29wdGlvbnMuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9vcHRpb25zLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDQ2M2YyMAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9vcHRpb25zLmgKQEAgLTAsMCArMSw1OSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjogcmVubmllQGdvb2dsZS5jb20gKEplZmZyZXkgUmVubmllKQorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DUFBfT1BUSU9OU19IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NQUF9PUFRJT05TX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBjcHAgeworCisvLyBHZW5lcmF0b3Igb3B0aW9ucyAoc2VlIGdlbmVyYXRvci5jYyBmb3IgYSBkZXNjcmlwdGlvbiBvZiBlYWNoKToKK3N0cnVjdCBPcHRpb25zIHsKKyAgT3B0aW9ucygpIDogc2FmZV9ib3VuZGFyeV9jaGVjayhmYWxzZSksIHByb3RvX2goZmFsc2UpIHsKKyAgfQorICBzdHJpbmcgZGxsZXhwb3J0X2RlY2w7CisgIGJvb2wgc2FmZV9ib3VuZGFyeV9jaGVjazsKKyAgYm9vbCBwcm90b19oOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGNwcAorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DUFBfT1BUSU9OU19IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9wbHVnaW5fdW5pdHRlc3QuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfcGx1Z2luX3VuaXR0ZXN0LmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQxZWZiZmUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfcGx1Z2luX3VuaXR0ZXN0LmNjCkBAIC0wLDAgKzEsMjUxIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8KKy8vIFRPRE8oa2VudG9uKTogIFNoYXJlIGNvZGUgd2l0aCB0aGUgdmVyc2lvbnMgb2YgdGhpcyB0ZXN0IGluIG90aGVyIGxhbmd1YWdlcz8KKy8vICAgSXQgc2VlbWVkIGxpa2UgcGFyYW1ldGVyaXppbmcgaXQgd291bGQgYWRkIG1vcmUgY29tcGxleGl0eSB0aGFuIGl0IGlzCisvLyAgIHdvcnRoLgorCisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZ2VuZXJhdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvbW1hbmRfbGluZV9pbnRlcmZhY2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0Lmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9maWxlLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgY3BwIHsKK25hbWVzcGFjZSB7CisKK2NsYXNzIFRlc3RHZW5lcmF0b3IgOiBwdWJsaWMgQ29kZUdlbmVyYXRvciB7CisgcHVibGljOgorICBUZXN0R2VuZXJhdG9yKCkge30KKyAgflRlc3RHZW5lcmF0b3IoKSB7fQorCisgIHZpcnR1YWwgYm9vbCBHZW5lcmF0ZShjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgcGFyYW1ldGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgR2VuZXJhdG9yQ29udGV4dCogY29udGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyogZXJyb3IpIGNvbnN0IHsKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJpbmNsdWRlcyIsIGNvbnRleHQpOworICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgIm5hbWVzcGFjZV9zY29wZSIsIGNvbnRleHQpOworICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgImdsb2JhbF9zY29wZSIsIGNvbnRleHQpOworICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgImNsYXNzX3Njb3BlOmZvby5CYXIiLCBjb250ZXh0KTsKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJjbGFzc19zY29wZTpmb28uQmFyLkJheiIsIGNvbnRleHQpOworCisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmNjIiwgImluY2x1ZGVzIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmNjIiwgIm5hbWVzcGFjZV9zY29wZSIsIGNvbnRleHQpOworICAgIFRyeUluc2VydCgidGVzdC5wYi5jYyIsICJnbG9iYWxfc2NvcGUiLCBjb250ZXh0KTsKKworICAgIC8vIENoZWNrIGZpZWxkIGFjY2Vzc29ycyBmb3IgYW4gb3B0aW9uYWwgaW50MzI6CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfZ2V0OmZvby5CYXIub3B0SW50IiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfc2V0OmZvby5CYXIub3B0SW50IiwgY29udGV4dCk7CisKKyAgICAvLyBDaGVjayBmaWVsZCBhY2Nlc3NvcnMgZm9yIGEgcmVwZWF0ZWQgaW50MzI6CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfZ2V0OmZvby5CYXIucmVwZWF0ZWRJbnQiLCBjb250ZXh0KTsKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJmaWVsZF9zZXQ6Zm9vLkJhci5yZXBlYXRlZEludCIsIGNvbnRleHQpOworCisgICAgLy8gQ2hlY2sgZmllbGQgYWNjZXNzb3JzIGZvciBhIHJlcXVpcmVkIHN0cmluZzoKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJmaWVsZF9nZXQ6Zm9vLkJhci5yZXF1aXJlZFN0cmluZyIsIGNvbnRleHQpOworICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgImZpZWxkX3NldDpmb28uQmFyLnJlcXVpcmVkU3RyaW5nIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfc2V0X2NoYXI6Zm9vLkJhci5yZXF1aXJlZFN0cmluZyIsIGNvbnRleHQpOworICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgImZpZWxkX3NldF9wb2ludGVyOmZvby5CYXIucmVxdWlyZWRTdHJpbmciLCBjb250ZXh0KTsKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJmaWVsZF9tdXRhYmxlOmZvby5CYXIucmVxdWlyZWRTdHJpbmciLCBjb250ZXh0KTsKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJmaWVsZF9zZXRfYWxsb2NhdGVkOmZvby5CYXIucmVxdWlyZWRTdHJpbmciLAorICAgICAgICAgICAgICBjb250ZXh0KTsKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJmaWVsZF9zZXRfY2hhcjpmb28uQmFyLnJlcXVpcmVkU3RyaW5nIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfc2V0X3BvaW50ZXI6Zm9vLkJhci5yZXF1aXJlZFN0cmluZyIsIGNvbnRleHQpOworCisgICAgLy8gQ2hlY2sgZmllbGQgYWNjZXNzb3JzIGZvciBhIHJlcGVhdGVkIHN0cmluZzoKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJmaWVsZF9nZXQ6Zm9vLkJhci5yZXBlYXRlZFN0cmluZyIsIGNvbnRleHQpOworICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgImZpZWxkX3NldDpmb28uQmFyLnJlcGVhdGVkU3RyaW5nIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfc2V0X2NoYXI6Zm9vLkJhci5yZXBlYXRlZFN0cmluZyIsIGNvbnRleHQpOworICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgImZpZWxkX3NldF9wb2ludGVyOmZvby5CYXIucmVwZWF0ZWRTdHJpbmciLCBjb250ZXh0KTsKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJmaWVsZF9tdXRhYmxlOmZvby5CYXIucmVwZWF0ZWRTdHJpbmciLCBjb250ZXh0KTsKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJmaWVsZF9zZXRfY2hhcjpmb28uQmFyLnJlcGVhdGVkU3RyaW5nIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfc2V0X3BvaW50ZXI6Zm9vLkJhci5yZXBlYXRlZFN0cmluZyIsIGNvbnRleHQpOworCisgICAgLy8gQ2hlY2sgZmllbGQgYWNjZXNzb3JzIGZvciBhbiBpbnQgaW5zaWRlIG9uZW9me306CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfZ2V0OmZvby5CYXIub25lT2ZJbnQiLCBjb250ZXh0KTsKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJmaWVsZF9zZXQ6Zm9vLkJhci5vbmVPZkludCIsIGNvbnRleHQpOworCisgICAgLy8gQ2hlY2sgZmllbGQgYWNjZXNzb3JzIGZvciBhIHN0cmluZyBpbnNpZGUgb25lb2Z7fToKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJmaWVsZF9nZXQ6Zm9vLkJhci5vbmVPZlN0cmluZyIsIGNvbnRleHQpOworICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgImZpZWxkX3NldDpmb28uQmFyLm9uZU9mU3RyaW5nIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfc2V0X2NoYXI6Zm9vLkJhci5vbmVPZlN0cmluZyIsIGNvbnRleHQpOworICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgImZpZWxkX3NldF9wb2ludGVyOmZvby5CYXIub25lT2ZTdHJpbmciLCBjb250ZXh0KTsKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJmaWVsZF9tdXRhYmxlOmZvby5CYXIub25lT2ZTdHJpbmciLCBjb250ZXh0KTsKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJmaWVsZF9zZXRfYWxsb2NhdGVkOmZvby5CYXIub25lT2ZTdHJpbmciLCBjb250ZXh0KTsKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJmaWVsZF9zZXRfY2hhcjpmb28uQmFyLm9uZU9mU3RyaW5nIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfc2V0X3BvaW50ZXI6Zm9vLkJhci5vbmVPZlN0cmluZyIsIGNvbnRleHQpOworCisgICAgLy8gQ2hlY2sgZmllbGQgYWNjZXNzb3JzIGZvciBhbiBvcHRpb25hbCBtZXNzYWdlOgorICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgImZpZWxkX2dldDpmb28uQmFyLm9wdE1lc3NhZ2UiLCBjb250ZXh0KTsKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJmaWVsZF9tdXRhYmxlOmZvby5CYXIub3B0TWVzc2FnZSIsIGNvbnRleHQpOworICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgImZpZWxkX3NldF9hbGxvY2F0ZWQ6Zm9vLkJhci5vcHRNZXNzYWdlIiwgY29udGV4dCk7CisKKyAgICAvLyBDaGVjayBmaWVsZCBhY2Nlc3NvcnMgZm9yIGEgcmVwZWF0ZWQgbWVzc2FnZToKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJmaWVsZF9hZGQ6Zm9vLkJhci5yZXBlYXRlZE1lc3NhZ2UiLCBjb250ZXh0KTsKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJmaWVsZF9nZXQ6Zm9vLkJhci5yZXBlYXRlZE1lc3NhZ2UiLCBjb250ZXh0KTsKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJmaWVsZF9saXN0OmZvby5CYXIucmVwZWF0ZWRNZXNzYWdlIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfbXV0YWJsZTpmb28uQmFyLnJlcGVhdGVkTWVzc2FnZSIsIGNvbnRleHQpOworICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgImZpZWxkX211dGFibGVfbGlzdDpmb28uQmFyLnJlcGVhdGVkTWVzc2FnZSIsCisgICAgICAgICAgICAgIGNvbnRleHQpOworCisgICAgLy8gQ2hlY2sgZmllbGQgYWNjZXNzb3JzIGZvciBhIG1lc3NhZ2UgaW5zaWRlIG9uZW9me306CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfZ2V0OmZvby5CYXIub25lT2ZNZXNzYWdlIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfbXV0YWJsZTpmb28uQmFyLm9uZU9mTWVzc2FnZSIsIGNvbnRleHQpOworICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgImZpZWxkX3NldF9hbGxvY2F0ZWQ6Zm9vLkJhci5vbmVPZk1lc3NhZ2UiLCBjb250ZXh0KTsKKworICAgIC8vIENoZWNrIGZpZWxkIGFjY2Vzc29ycyBmb3IgYW4gb3B0aW9uYWwgZW51bToKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJmaWVsZF9nZXQ6Zm9vLkJhci5vcHRFbnVtIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfc2V0OmZvby5CYXIub3B0RW51bSIsIGNvbnRleHQpOworCisgICAgLy8gQ2hlY2sgZmllbGQgYWNjZXNzb3JzIGZvciBhIHJlcGVhdGVkIGVudW06CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfZ2V0OmZvby5CYXIucmVwZWF0ZWRFbnVtIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfc2V0OmZvby5CYXIucmVwZWF0ZWRFbnVtIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfYWRkOmZvby5CYXIucmVwZWF0ZWRFbnVtIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfbGlzdDpmb28uQmFyLnJlcGVhdGVkRW51bSIsIGNvbnRleHQpOworICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgImZpZWxkX211dGFibGVfbGlzdDpmb28uQmFyLnJlcGVhdGVkRW51bSIsIGNvbnRleHQpOworCisgICAgLy8gQ2hlY2sgZmllbGQgYWNjZXNzb3JzIGZvciBhbiBlbnVtIGluc2lkZSBvbmVvZnt9OgorICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgImZpZWxkX2dldDpmb28uQmFyLm9uZU9mRW51bSIsIGNvbnRleHQpOworICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgImZpZWxkX3NldDpmb28uQmFyLm9uZU9mRW51bSIsIGNvbnRleHQpOworCisgICAgLy8gQ2hlY2sgZmllbGQgYWNjZXNzb3JzIGZvciBhIHJlcXVpcmVkIGNvcmQ6CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfZ2V0OmZvby5CYXIucmVxdWlyZWRDb3JkIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfc2V0OmZvby5CYXIucmVxdWlyZWRDb3JkIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfbXV0YWJsZTpmb28uQmFyLnJlcXVpcmVkQ29yZCIsIGNvbnRleHQpOworCisgICAgLy8gQ2hlY2sgZmllbGQgYWNjZXNzb3JzIGZvciBhIHJlcGVhdGVkIGNvcmQ6CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfZ2V0OmZvby5CYXIucmVwZWF0ZWRDb3JkIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfc2V0OmZvby5CYXIucmVwZWF0ZWRDb3JkIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfYWRkOmZvby5CYXIucmVwZWF0ZWRDb3JkIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0LnBiLmgiLCAiZmllbGRfbGlzdDpmb28uQmFyLnJlcGVhdGVkQ29yZCIsIGNvbnRleHQpOworICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgImZpZWxkX211dGFibGU6Zm9vLkJhci5yZXBlYXRlZENvcmQiLCBjb250ZXh0KTsKKyAgICBUcnlJbnNlcnQoInRlc3QucGIuaCIsICJmaWVsZF9tdXRhYmxlX2xpc3Q6Zm9vLkJhci5yZXBlYXRlZENvcmQiLCBjb250ZXh0KTsKKworICAgIC8vIENoZWNrIGZpZWxkIGFjY2Vzc29ycyBmb3IgYSBjb3JkIGluc2lkZSBvbmVvZnt9OgorICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgImZpZWxkX2dldDpmb28uQmFyLm9uZU9mQ29yZCIsIGNvbnRleHQpOworICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgImZpZWxkX3NldDpmb28uQmFyLm9uZU9mQ29yZCIsIGNvbnRleHQpOworICAgIFRyeUluc2VydCgidGVzdC5wYi5oIiwgImZpZWxkX211dGFibGU6Zm9vLkJhci5vbmVPZkNvcmQiLCBjb250ZXh0KTsKKworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgdm9pZCBUcnlJbnNlcnQoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSwgY29uc3Qgc3RyaW5nJiBpbnNlcnRpb25fcG9pbnQsCisgICAgICAgICAgICAgICAgIEdlbmVyYXRvckNvbnRleHQqIGNvbnRleHQpIGNvbnN0IHsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPGlvOjpaZXJvQ29weU91dHB1dFN0cmVhbT4gb3V0cHV0KAorICAgICAgICBjb250ZXh0LT5PcGVuRm9ySW5zZXJ0KGZpbGVuYW1lLCBpbnNlcnRpb25fcG9pbnQpKTsKKyAgICBpbzo6UHJpbnRlciBwcmludGVyKG91dHB1dC5nZXQoKSwgJyQnKTsKKyAgICBwcmludGVyLlByaW50KCIvLyBpbnNlcnRlZCAkbmFtZSRcbiIsICJuYW1lIiwgaW5zZXJ0aW9uX3BvaW50KTsKKyAgfQorfTsKKworLy8gVGhpcyB0ZXN0IHZlcmlmaWVzIHRoYXQgYWxsIHRoZSBleHBlY3RlZCBpbnNlcnRpb24gcG9pbnRzIGV4aXN0LiAgSXQgZG9lcworLy8gbm90IHZlcmlmeSB0aGF0IHRoZXkgYXJlIGNvcnJlY3RseS1wbGFjZWQ7IHRoYXQgd291bGQgcmVxdWlyZSBhY3R1YWxseQorLy8gY29tcGlsaW5nIHRoZSBvdXRwdXQgd2hpY2ggaXMgYSBiaXQgbW9yZSB0aGFuIEkgY2FyZSB0byBkbyBmb3IgdGhpcyB0ZXN0LgorVEVTVChDcHBQbHVnaW5UZXN0LCBQbHVnaW5UZXN0KSB7CisgIEdPT0dMRV9DSEVDS19PSyhGaWxlOjpTZXRDb250ZW50cyhUZXN0VGVtcERpcigpICsgIi90ZXN0LnByb3RvIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwYWNrYWdlIGZvbztcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlxuIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZW51bSBUaHVkIHsgVkFMVUUgPSAwOyB9XG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm1lc3NhZ2UgQmFyIHtcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgbWVzc2FnZSBCYXoge31cbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgb3B0aW9uYWwgaW50MzIgb3B0SW50ID0gMTtcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgcmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRJbnQgPSAyO1xuIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiXG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgIHJlcXVpcmVkIHN0cmluZyByZXF1aXJlZFN0cmluZyA9IDM7XG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgIHJlcGVhdGVkIHN0cmluZyByZXBlYXRlZFN0cmluZyA9IDQ7XG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgb3B0aW9uYWwgQmF6IG9wdE1lc3NhZ2UgPSA2O1xuIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICByZXBlYXRlZCBCYXogcmVwZWF0ZWRNZXNzYWdlID0gNztcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlxuIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICBvcHRpb25hbCBUaHVkIG9wdEVudW0gPSA4O1xuIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICByZXBlYXRlZCBUaHVkIHJlcGVhdGVkRW51bSA9IDk7XG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgcmVxdWlyZWQgc3RyaW5nIHJlcXVpcmVkQ29yZCA9IDEwIFtcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgICBjdHlwZSA9IENPUkRcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgXTtcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgcmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkQ29yZCA9IDExIFtcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgICBjdHlwZSA9IENPUkRcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgXTtcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlxuIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICBvbmVvZiBRdXgge1xuIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICAgIGludDY0IG9uZU9mSW50ID0gMjA7XG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgICAgc3RyaW5nIG9uZU9mU3RyaW5nID0gMjE7XG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgICAgQmF6IG9uZU9mTWVzc2FnZSA9IDIyO1xuIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICAgIFRodWQgb25lT2ZFbnVtID0gMjM7IgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICAgIHN0cmluZyBvbmVPZkNvcmQgPSAyNCBbXG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgICAgICBjdHlwZSA9IENPUkRcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgICBdO1xuIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICB9XG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ9XG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlKSk7CisKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6Y29tcGlsZXI6OkNvbW1hbmRMaW5lSW50ZXJmYWNlIGNsaTsKKyAgY2xpLlNldElucHV0c0FyZVByb3RvUGF0aFJlbGF0aXZlKHRydWUpOworCisgIENwcEdlbmVyYXRvciBjcHBfZ2VuZXJhdG9yOworICBUZXN0R2VuZXJhdG9yIHRlc3RfZ2VuZXJhdG9yOworICBjbGkuUmVnaXN0ZXJHZW5lcmF0b3IoIi0tY3BwX291dCIsICZjcHBfZ2VuZXJhdG9yLCAiIik7CisgIGNsaS5SZWdpc3RlckdlbmVyYXRvcigiLS10ZXN0X291dCIsICZ0ZXN0X2dlbmVyYXRvciwgIiIpOworCisgIHN0cmluZyBwcm90b19wYXRoID0gIi1JIiArIFRlc3RUZW1wRGlyKCk7CisgIHN0cmluZyBjcHBfb3V0ID0gIi0tY3BwX291dD0iICsgVGVzdFRlbXBEaXIoKTsKKyAgc3RyaW5nIHRlc3Rfb3V0ID0gIi0tdGVzdF9vdXQ9IiArIFRlc3RUZW1wRGlyKCk7CisKKyAgY29uc3QgY2hhciogYXJndltdID0geworICAgICJwcm90b2MiLAorICAgIHByb3RvX3BhdGguY19zdHIoKSwKKyAgICBjcHBfb3V0LmNfc3RyKCksCisgICAgdGVzdF9vdXQuY19zdHIoKSwKKyAgICAidGVzdC5wcm90byIKKyAgfTsKKworICBFWFBFQ1RfRVEoMCwgY2xpLlJ1big1LCBhcmd2KSk7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorfSAgLy8gbmFtZXNwYWNlIGNwcAorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9wcmltaXRpdmVfZmllbGQuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfcHJpbWl0aXZlX2ZpZWxkLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlmOTI5ZDMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfcHJpbWl0aXZlX2ZpZWxkLmNjCkBAIC0wLDAgKzEsNDU5IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9wcmltaXRpdmVfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGNwcCB7CisKK3VzaW5nIGludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTsKKworbmFtZXNwYWNlIHsKKworLy8gRm9yIGVuY29kaW5ncyB3aXRoIGZpeGVkIHNpemVzLCByZXR1cm5zIHRoYXQgc2l6ZSBpbiBieXRlcy4gIE90aGVyd2lzZQorLy8gcmV0dXJucyAtMS4KK2ludCBGaXhlZFNpemUoRmllbGREZXNjcmlwdG9yOjpUeXBlIHR5cGUpIHsKKyAgc3dpdGNoICh0eXBlKSB7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfSU5UMzIgICA6IHJldHVybiAtMTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9JTlQ2NCAgIDogcmV0dXJuIC0xOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1VJTlQzMiAgOiByZXR1cm4gLTE7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfVUlOVDY0ICA6IHJldHVybiAtMTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TSU5UMzIgIDogcmV0dXJuIC0xOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NJTlQ2NCAgOiByZXR1cm4gLTE7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRklYRUQzMiA6IHJldHVybiBXaXJlRm9ybWF0TGl0ZTo6a0ZpeGVkMzJTaXplOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0ZJWEVENjQgOiByZXR1cm4gV2lyZUZvcm1hdExpdGU6OmtGaXhlZDY0U2l6ZTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TRklYRUQzMjogcmV0dXJuIFdpcmVGb3JtYXRMaXRlOjprU0ZpeGVkMzJTaXplOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NGSVhFRDY0OiByZXR1cm4gV2lyZUZvcm1hdExpdGU6OmtTRml4ZWQ2NFNpemU7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRkxPQVQgICA6IHJldHVybiBXaXJlRm9ybWF0TGl0ZTo6a0Zsb2F0U2l6ZTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9ET1VCTEUgIDogcmV0dXJuIFdpcmVGb3JtYXRMaXRlOjprRG91YmxlU2l6ZTsKKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0JPT0wgICAgOiByZXR1cm4gV2lyZUZvcm1hdExpdGU6OmtCb29sU2l6ZTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9FTlVNICAgIDogcmV0dXJuIC0xOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU1RSSU5HICA6IHJldHVybiAtMTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9CWVRFUyAgIDogcmV0dXJuIC0xOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQICAgOiByZXR1cm4gLTE7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfTUVTU0FHRSA6IHJldHVybiAtMTsKKworICAgIC8vIE5vIGRlZmF1bHQgYmVjYXVzZSB3ZSB3YW50IHRoZSBjb21waWxlciB0byBjb21wbGFpbiBpZiBhbnkgbmV3CisgICAgLy8gdHlwZXMgYXJlIGFkZGVkLgorICB9CisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJDYW4ndCBnZXQgaGVyZS4iOworICByZXR1cm4gLTE7Cit9CisKK3ZvaWQgU2V0UHJpbWl0aXZlVmFyaWFibGVzKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcDxzdHJpbmcsIHN0cmluZz4qIHZhcmlhYmxlcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE9wdGlvbnMmIG9wdGlvbnMpIHsKKyAgU2V0Q29tbW9uRmllbGRWYXJpYWJsZXMoZGVzY3JpcHRvciwgdmFyaWFibGVzLCBvcHRpb25zKTsKKyAgKCp2YXJpYWJsZXMpWyJ0eXBlIl0gPSBQcmltaXRpdmVUeXBlTmFtZShkZXNjcmlwdG9yLT5jcHBfdHlwZSgpKTsKKyAgKCp2YXJpYWJsZXMpWyJkZWZhdWx0Il0gPSBEZWZhdWx0VmFsdWUoZGVzY3JpcHRvcik7CisgICgqdmFyaWFibGVzKVsidGFnIl0gPSBTaW1wbGVJdG9hKGludGVybmFsOjpXaXJlRm9ybWF0OjpNYWtlVGFnKGRlc2NyaXB0b3IpKTsKKyAgaW50IGZpeGVkX3NpemUgPSBGaXhlZFNpemUoZGVzY3JpcHRvci0+dHlwZSgpKTsKKyAgaWYgKGZpeGVkX3NpemUgIT0gLTEpIHsKKyAgICAoKnZhcmlhYmxlcylbImZpeGVkX3NpemUiXSA9IFNpbXBsZUl0b2EoZml4ZWRfc2l6ZSk7CisgIH0KKyAgKCp2YXJpYWJsZXMpWyJ3aXJlX2Zvcm1hdF9maWVsZF90eXBlIl0gPQorICAgICAgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjoiICsgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9OYW1lKAorICAgICAgICAgIHN0YXRpY19jYXN0PEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGU+KGRlc2NyaXB0b3ItPnR5cGUoKSkpOworICAoKnZhcmlhYmxlcylbImZ1bGxfbmFtZSJdID0gZGVzY3JpcHRvci0+ZnVsbF9uYW1lKCk7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK1ByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK1ByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE9wdGlvbnMmIG9wdGlvbnMpCisgIDogZGVzY3JpcHRvcl8oZGVzY3JpcHRvcikgeworICBTZXRQcmltaXRpdmVWYXJpYWJsZXMoZGVzY3JpcHRvciwgJnZhcmlhYmxlc18sIG9wdGlvbnMpOworfQorCitQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6flByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKCkge30KKwordm9pZCBQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVByaXZhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sICIkdHlwZSQgJG5hbWUkXztcbiIpOworfQorCit2b2lkIFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQWNjZXNzb3JEZWNsYXJhdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJHR5cGUkICRuYW1lJCgpIGNvbnN0JGRlcHJlY2F0aW9uJDtcbiIKKyAgICAidm9pZCBzZXRfJG5hbWUkKCR0eXBlJCB2YWx1ZSkkZGVwcmVjYXRpb24kO1xuIik7Cit9CisKK3ZvaWQgUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVJbmxpbmVBY2Nlc3NvckRlZmluaXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyLCBib29sIGlzX2lubGluZSkgY29uc3QgeworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlcyh2YXJpYWJsZXNfKTsKKyAgdmFyaWFibGVzWyJpbmxpbmUiXSA9IGlzX2lubGluZSA/ICJpbmxpbmUiIDogIiI7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAiJGlubGluZSQgJHR5cGUkICRjbGFzc25hbWUkOjokbmFtZSQoKSBjb25zdCB7XG4iCisgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDokZnVsbF9uYW1lJClcbiIKKyAgICAiICByZXR1cm4gJG5hbWUkXztcbiIKKyAgICAifVxuIgorICAgICIkaW5saW5lJCB2b2lkICRjbGFzc25hbWUkOjpzZXRfJG5hbWUkKCR0eXBlJCB2YWx1ZSkge1xuIgorICAgICIgICRzZXRfaGFzYml0JFxuIgorICAgICIgICRuYW1lJF8gPSB2YWx1ZTtcbiIKKyAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0OiRmdWxsX25hbWUkKVxuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUNsZWFyaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAiJG5hbWUkXyA9ICRkZWZhdWx0JDtcbiIpOworfQorCit2b2lkIFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgInNldF8kbmFtZSQoZnJvbS4kbmFtZSQoKSk7XG4iKTsKK30KKwordm9pZCBQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVN3YXBwaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAic3RkOjpzd2FwKCRuYW1lJF8sIG90aGVyLT4kbmFtZSRfKTtcbiIpOworfQorCit2b2lkIFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQ29uc3RydWN0b3JDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sICIkbmFtZSRfID0gJGRlZmF1bHQkO1xuIik7Cit9CisKK3ZvaWQgUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZXJnZUZyb21Db2RlZFN0cmVhbShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPFxuIgorICAgICIgICAgICAgICAkdHlwZSQsICR3aXJlX2Zvcm1hdF9maWVsZF90eXBlJD4oXG4iCisgICAgIiAgICAgICBpbnB1dCwgJiRuYW1lJF8pKSk7XG4iCisgICAgIiRzZXRfaGFzYml0JFxuIik7Cit9CisKK3ZvaWQgUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlJGRlY2xhcmVkX3R5cGUkKCIKKyAgICAgICIkbnVtYmVyJCwgdGhpcy0+JG5hbWUkKCksIG91dHB1dCk7XG4iKTsKK30KKwordm9pZCBQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAidGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlJGRlY2xhcmVkX3R5cGUkVG9BcnJheSgiCisgICAgICAiJG51bWJlciQsIHRoaXMtPiRuYW1lJCgpLCB0YXJnZXQpO1xuIik7Cit9CisKK3ZvaWQgUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVCeXRlU2l6ZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpbnQgZml4ZWRfc2l6ZSA9IEZpeGVkU2l6ZShkZXNjcmlwdG9yXy0+dHlwZSgpKTsKKyAgaWYgKGZpeGVkX3NpemUgPT0gLTEpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgInRvdGFsX3NpemUgKz0gJHRhZ19zaXplJCArXG4iCisgICAgICAiICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6JGRlY2xhcmVkX3R5cGUkU2l6ZShcbiIKKyAgICAgICIgICAgdGhpcy0+JG5hbWUkKCkpO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJ0b3RhbF9zaXplICs9ICR0YWdfc2l6ZSQgKyAkZml4ZWRfc2l6ZSQ7XG4iKTsKKyAgfQorfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK1ByaW1pdGl2ZU9uZW9mRmllbGRHZW5lcmF0b3I6OgorUHJpbWl0aXZlT25lb2ZGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE9wdGlvbnMmIG9wdGlvbnMpCisgIDogUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IoZGVzY3JpcHRvciwgb3B0aW9ucykgeworICBTZXRDb21tb25PbmVvZkZpZWxkVmFyaWFibGVzKGRlc2NyaXB0b3IsICZ2YXJpYWJsZXNfKTsKK30KKworUHJpbWl0aXZlT25lb2ZGaWVsZEdlbmVyYXRvcjo6flByaW1pdGl2ZU9uZW9mRmllbGRHZW5lcmF0b3IoKSB7fQorCit2b2lkIFByaW1pdGl2ZU9uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVJbmxpbmVBY2Nlc3NvckRlZmluaXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyLCBib29sIGlzX2lubGluZSkgY29uc3QgeworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlcyh2YXJpYWJsZXNfKTsKKyAgdmFyaWFibGVzWyJpbmxpbmUiXSA9IGlzX2lubGluZSA/ICJpbmxpbmUiIDogIiI7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAiJGlubGluZSQgJHR5cGUkICRjbGFzc25hbWUkOjokbmFtZSQoKSBjb25zdCB7XG4iCisgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDokZnVsbF9uYW1lJClcbiIKKyAgICAiICBpZiAoaGFzXyRuYW1lJCgpKSB7XG4iCisgICAgIiAgICByZXR1cm4gJG9uZW9mX3ByZWZpeCQkbmFtZSRfO1xuIgorICAgICIgIH1cbiIKKyAgICAiICByZXR1cm4gJGRlZmF1bHQkO1xuIgorICAgICJ9XG4iCisgICAgIiRpbmxpbmUkIHZvaWQgJGNsYXNzbmFtZSQ6OnNldF8kbmFtZSQoJHR5cGUkIHZhbHVlKSB7XG4iCisgICAgIiAgaWYgKCFoYXNfJG5hbWUkKCkpIHtcbiIKKyAgICAiICAgIGNsZWFyXyRvbmVvZl9uYW1lJCgpO1xuIgorICAgICIgICAgc2V0X2hhc18kbmFtZSQoKTtcbiIKKyAgICAiICB9XG4iCisgICAgIiAgJG9uZW9mX3ByZWZpeCQkbmFtZSRfID0gdmFsdWU7XG4iCisgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDokZnVsbF9uYW1lJClcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUHJpbWl0aXZlT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUNsZWFyaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAiJG9uZW9mX3ByZWZpeCQkbmFtZSRfID0gJGRlZmF1bHQkO1xuIik7Cit9CisKK3ZvaWQgUHJpbWl0aXZlT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVN3YXBwaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBEb24ndCBwcmludCBhbnkgc3dhcHBpbmcgY29kZS4gU3dhcHBpbmcgdGhlIHVuaW9uIHdpbGwgc3dhcCB0aGlzIGZpZWxkLgorfQorCit2b2lkIFByaW1pdGl2ZU9uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVDb25zdHJ1Y3RvckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICB2YXJpYWJsZXNfLAorICAgICAgIiAgJGNsYXNzbmFtZSRfZGVmYXVsdF9vbmVvZl9pbnN0YW5jZV8tPiRuYW1lJF8gPSAkZGVmYXVsdCQ7XG4iKTsKK30KKwordm9pZCBQcmltaXRpdmVPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2VGcm9tQ29kZWRTdHJlYW0oaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiY2xlYXJfJG9uZW9mX25hbWUkKCk7XG4iCisgICAgIkRPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8XG4iCisgICAgIiAgICAgICAgICR0eXBlJCwgJHdpcmVfZm9ybWF0X2ZpZWxkX3R5cGUkPihcbiIKKyAgICAiICAgICAgIGlucHV0LCAmJG9uZW9mX3ByZWZpeCQkbmFtZSRfKSkpO1xuIgorICAgICJzZXRfaGFzXyRuYW1lJCgpO1xuIik7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworUmVwZWF0ZWRQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitSZXBlYXRlZFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT3B0aW9ucyYgb3B0aW9ucykKKyAgOiBkZXNjcmlwdG9yXyhkZXNjcmlwdG9yKSB7CisgIFNldFByaW1pdGl2ZVZhcmlhYmxlcyhkZXNjcmlwdG9yLCAmdmFyaWFibGVzXywgb3B0aW9ucyk7CisKKyAgaWYgKGRlc2NyaXB0b3ItPmlzX3BhY2tlZCgpKSB7CisgICAgdmFyaWFibGVzX1sicGFja2VkX3JlYWRlciJdID0gIlJlYWRQYWNrZWRQcmltaXRpdmUiOworICAgIHZhcmlhYmxlc19bInJlcGVhdGVkX3JlYWRlciJdID0gIlJlYWRSZXBlYXRlZFByaW1pdGl2ZU5vSW5saW5lIjsKKyAgfSBlbHNlIHsKKyAgICB2YXJpYWJsZXNfWyJwYWNrZWRfcmVhZGVyIl0gPSAiUmVhZFBhY2tlZFByaW1pdGl2ZU5vSW5saW5lIjsKKyAgICB2YXJpYWJsZXNfWyJyZXBlYXRlZF9yZWFkZXIiXSA9ICJSZWFkUmVwZWF0ZWRQcmltaXRpdmUiOworICB9Cit9CisKK1JlcGVhdGVkUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6On5SZXBlYXRlZFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKCkge30KKwordm9pZCBSZXBlYXRlZFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlUHJpdmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZEZpZWxkPCAkdHlwZSQgPiAkbmFtZSRfO1xuIik7CisgIGlmIChkZXNjcmlwdG9yXy0+aXNfcGFja2VkKCkgJiYgSGFzR2VuZXJhdGVkTWV0aG9kcyhkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAibXV0YWJsZSBpbnQgXyRuYW1lJF9jYWNoZWRfYnl0ZV9zaXplXztcbiIpOworICB9Cit9CisKK3ZvaWQgUmVwZWF0ZWRQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUFjY2Vzc29yRGVjbGFyYXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiR0eXBlJCAkbmFtZSQoaW50IGluZGV4KSBjb25zdCRkZXByZWNhdGlvbiQ7XG4iCisgICAgInZvaWQgc2V0XyRuYW1lJChpbnQgaW5kZXgsICR0eXBlJCB2YWx1ZSkkZGVwcmVjYXRpb24kO1xuIgorICAgICJ2b2lkIGFkZF8kbmFtZSQoJHR5cGUkIHZhbHVlKSRkZXByZWNhdGlvbiQ7XG4iKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZEZpZWxkPCAkdHlwZSQgPiZcbiIKKyAgICAiICAgICRuYW1lJCgpIGNvbnN0JGRlcHJlY2F0aW9uJDtcbiIKKyAgICAiOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZEZpZWxkPCAkdHlwZSQgPipcbiIKKyAgICAiICAgIG11dGFibGVfJG5hbWUkKCkkZGVwcmVjYXRpb24kO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUlubGluZUFjY2Vzc29yRGVmaW5pdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIsIGJvb2wgaXNfaW5saW5lKSBjb25zdCB7CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyaWFibGVzKHZhcmlhYmxlc18pOworICB2YXJpYWJsZXNbImlubGluZSJdID0gaXNfaW5saW5lID8gImlubGluZSIgOiAiIjsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICIkaW5saW5lJCAkdHlwZSQgJGNsYXNzbmFtZSQ6OiRuYW1lJChpbnQgaW5kZXgpIGNvbnN0IHtcbiIKKyAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0OiRmdWxsX25hbWUkKVxuIgorICAgICIgIHJldHVybiAkbmFtZSRfLkdldChpbmRleCk7XG4iCisgICAgIn1cbiIKKyAgICAiJGlubGluZSQgdm9pZCAkY2xhc3NuYW1lJDo6c2V0XyRuYW1lJChpbnQgaW5kZXgsICR0eXBlJCB2YWx1ZSkge1xuIgorICAgICIgICRuYW1lJF8uU2V0KGluZGV4LCB2YWx1ZSk7XG4iCisgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDokZnVsbF9uYW1lJClcbiIKKyAgICAifVxuIgorICAgICIkaW5saW5lJCB2b2lkICRjbGFzc25hbWUkOjphZGRfJG5hbWUkKCR0eXBlJCB2YWx1ZSkge1xuIgorICAgICIgICRuYW1lJF8uQWRkKHZhbHVlKTtcbiIKKyAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOiRmdWxsX25hbWUkKVxuIgorICAgICJ9XG4iKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICIkaW5saW5lJCBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkRmllbGQ8ICR0eXBlJCA+JlxuIgorICAgICIkY2xhc3NuYW1lJDo6JG5hbWUkKCkgY29uc3Qge1xuIgorICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0OiRmdWxsX25hbWUkKVxuIgorICAgICIgIHJldHVybiAkbmFtZSRfO1xuIgorICAgICJ9XG4iCisgICAgIiRpbmxpbmUkIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRGaWVsZDwgJHR5cGUkID4qXG4iCisgICAgIiRjbGFzc25hbWUkOjptdXRhYmxlXyRuYW1lJCgpIHtcbiIKKyAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0OiRmdWxsX25hbWUkKVxuIgorICAgICIgIHJldHVybiAmJG5hbWUkXztcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUNsZWFyaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAiJG5hbWUkXy5DbGVhcigpO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sICIkbmFtZSRfLk1lcmdlRnJvbShmcm9tLiRuYW1lJF8pO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVN3YXBwaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAiJG5hbWUkXy5VbnNhZmVBcmVuYVN3YXAoJm90aGVyLT4kbmFtZSRfKTtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVDb25zdHJ1Y3RvckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gTm90IG5lZWRlZCBmb3IgcmVwZWF0ZWQgZmllbGRzLgorfQorCit2b2lkIFJlcGVhdGVkUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZXJnZUZyb21Db2RlZFN0cmVhbShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjokcmVwZWF0ZWRfcmVhZGVyJDxcbiIKKyAgICAiICAgICAgICAgJHR5cGUkLCAkd2lyZV9mb3JtYXRfZmllbGRfdHlwZSQ+KFxuIgorICAgICIgICAgICAgJHRhZ19zaXplJCwgJHRhZyQsIGlucHV0LCB0aGlzLT5tdXRhYmxlXyRuYW1lJCgpKSkpO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lcmdlRnJvbUNvZGVkU3RyZWFtV2l0aFBhY2tpbmcoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6JHBhY2tlZF9yZWFkZXIkPFxuIgorICAgICIgICAgICAgICAkdHlwZSQsICR3aXJlX2Zvcm1hdF9maWVsZF90eXBlJD4oXG4iCisgICAgIiAgICAgICBpbnB1dCwgdGhpcy0+bXV0YWJsZV8kbmFtZSQoKSkpKTtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKGRlc2NyaXB0b3JfLT5pc19wYWNrZWQoKSkgeworICAgIC8vIFdyaXRlIHRoZSB0YWcgYW5kIHRoZSBzaXplLgorICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaWYgKHRoaXMtPiRuYW1lJF9zaXplKCkgPiAwKSB7XG4iCisgICAgICAiICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVUYWcoIgorICAgICAgICAgICIkbnVtYmVyJCwgIgorICAgICAgICAgICI6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCwgIgorICAgICAgICAgICJvdXRwdXQpO1xuIgorICAgICAgIiAgb3V0cHV0LT5Xcml0ZVZhcmludDMyKF8kbmFtZSRfY2FjaGVkX2J5dGVfc2l6ZV8pO1xuIgorICAgICAgIn1cbiIpOworICB9CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT4kbmFtZSRfc2l6ZSgpOyBpKyspIHtcbiIpOworICBpZiAoZGVzY3JpcHRvcl8tPmlzX3BhY2tlZCgpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZSRkZWNsYXJlZF90eXBlJE5vVGFnKFxuIgorICAgICAgIiAgICB0aGlzLT4kbmFtZSQoaSksIG91dHB1dCk7XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlJGRlY2xhcmVkX3R5cGUkKFxuIgorICAgICAgIiAgICAkbnVtYmVyJCwgdGhpcy0+JG5hbWUkKGkpLCBvdXRwdXQpO1xuIik7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworfQorCit2b2lkIFJlcGVhdGVkUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChkZXNjcmlwdG9yXy0+aXNfcGFja2VkKCkpIHsKKyAgICAvLyBXcml0ZSB0aGUgdGFnIGFuZCB0aGUgc2l6ZS4KKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImlmICh0aGlzLT4kbmFtZSRfc2l6ZSgpID4gMCkge1xuIgorICAgICAgIiAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlVGFnVG9BcnJheShcbiIKKyAgICAgICIgICAgJG51bWJlciQsXG4iCisgICAgICAiICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVELFxuIgorICAgICAgIiAgICB0YXJnZXQpO1xuIgorICAgICAgIiAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW06OldyaXRlVmFyaW50MzJUb0FycmF5KFxuIgorICAgICAgIiAgICBfJG5hbWUkX2NhY2hlZF9ieXRlX3NpemVfLCB0YXJnZXQpO1xuIgorICAgICAgIn1cbiIpOworICB9CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT4kbmFtZSRfc2l6ZSgpOyBpKyspIHtcbiIpOworICBpZiAoZGVzY3JpcHRvcl8tPmlzX3BhY2tlZCgpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpcbiIKKyAgICAgICIgICAgV3JpdGUkZGVjbGFyZWRfdHlwZSROb1RhZ1RvQXJyYXkodGhpcy0+JG5hbWUkKGkpLCB0YXJnZXQpO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpcbiIKKyAgICAgICIgICAgV3JpdGUkZGVjbGFyZWRfdHlwZSRUb0FycmF5KCRudW1iZXIkLCB0aGlzLT4kbmFtZSQoaSksIHRhcmdldCk7XG4iKTsKKyAgfQorICBwcmludGVyLT5QcmludCgifVxuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUJ5dGVTaXplKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIntcbiIKKyAgICAiICBpbnQgZGF0YV9zaXplID0gMDtcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKyAgaW50IGZpeGVkX3NpemUgPSBGaXhlZFNpemUoZGVzY3JpcHRvcl8tPnR5cGUoKSk7CisgIGlmIChmaXhlZF9zaXplID09IC0xKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPiRuYW1lJF9zaXplKCk7IGkrKykge1xuIgorICAgICAgIiAgZGF0YV9zaXplICs9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpcbiIKKyAgICAgICIgICAgJGRlY2xhcmVkX3R5cGUkU2l6ZSh0aGlzLT4kbmFtZSQoaSkpO1xuIgorICAgICAgIn1cbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiZGF0YV9zaXplID0gJGZpeGVkX3NpemUkICogdGhpcy0+JG5hbWUkX3NpemUoKTtcbiIpOworICB9CisKKyAgaWYgKGRlc2NyaXB0b3JfLT5pc19wYWNrZWQoKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaWYgKGRhdGFfc2l6ZSA+IDApIHtcbiIKKyAgICAgICIgIHRvdGFsX3NpemUgKz0gJHRhZ19zaXplJCArXG4iCisgICAgICAiICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpJbnQzMlNpemUoZGF0YV9zaXplKTtcbiIKKyAgICAgICJ9XG4iCisgICAgICAiR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTtcbiIKKyAgICAgICJfJG5hbWUkX2NhY2hlZF9ieXRlX3NpemVfID0gZGF0YV9zaXplO1xuIgorICAgICAgIkdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpO1xuIgorICAgICAgInRvdGFsX3NpemUgKz0gZGF0YV9zaXplO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJ0b3RhbF9zaXplICs9ICR0YWdfc2l6ZSQgKiB0aGlzLT4kbmFtZSRfc2l6ZSgpICsgZGF0YV9zaXplO1xuIik7CisgIH0KKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgifVxuIik7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBjcHAKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfcHJpbWl0aXZlX2ZpZWxkLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfcHJpbWl0aXZlX2ZpZWxkLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmNkN2Q2OAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9wcmltaXRpdmVfZmllbGQuaApAQCAtMCwwICsxLDEyNiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DUFBfUFJJTUlUSVZFX0ZJRUxEX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1BQX1BSSU1JVElWRV9GSUVMRF9IX18KKworI2luY2x1ZGUgPG1hcD4KKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZmllbGQuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBjcHAgeworCitjbGFzcyBQcmltaXRpdmVGaWVsZEdlbmVyYXRvciA6IHB1YmxpYyBGaWVsZEdlbmVyYXRvciB7CisgcHVibGljOgorICBleHBsaWNpdCBQcmltaXRpdmVGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE9wdGlvbnMmIG9wdGlvbnMpOworICB+UHJpbWl0aXZlRmllbGRHZW5lcmF0b3IoKTsKKworICAvLyBpbXBsZW1lbnRzIEZpZWxkR2VuZXJhdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICB2b2lkIEdlbmVyYXRlUHJpdmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQWNjZXNzb3JEZWNsYXJhdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSW5saW5lQWNjZXNzb3JEZWZpbml0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc19pbmxpbmUpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQ2xlYXJpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVN3YXBwaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVDb25zdHJ1Y3RvckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2VGcm9tQ29kZWRTdHJlYW0oaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnl0ZVNpemUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgcHJvdGVjdGVkOgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlc187CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IpOworfTsKKworY2xhc3MgUHJpbWl0aXZlT25lb2ZGaWVsZEdlbmVyYXRvciA6IHB1YmxpYyBQcmltaXRpdmVGaWVsZEdlbmVyYXRvciB7CisgcHVibGljOgorICBleHBsaWNpdCBQcmltaXRpdmVPbmVvZkZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBPcHRpb25zJiBvcHRpb25zKTsKKyAgflByaW1pdGl2ZU9uZW9mRmllbGRHZW5lcmF0b3IoKTsKKworICAvLyBpbXBsZW1lbnRzIEZpZWxkR2VuZXJhdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICB2b2lkIEdlbmVyYXRlSW5saW5lQWNjZXNzb3JEZWZpbml0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc19pbmxpbmUpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQ2xlYXJpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVN3YXBwaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVDb25zdHJ1Y3RvckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2VGcm9tQ29kZWRTdHJlYW0oaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFByaW1pdGl2ZU9uZW9mRmllbGRHZW5lcmF0b3IpOworfTsKKworY2xhc3MgUmVwZWF0ZWRQcmltaXRpdmVGaWVsZEdlbmVyYXRvciA6IHB1YmxpYyBGaWVsZEdlbmVyYXRvciB7CisgcHVibGljOgorICBleHBsaWNpdCBSZXBlYXRlZFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBPcHRpb25zJiBvcHRpb25zKTsKKyAgflJlcGVhdGVkUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IoKTsKKworICAvLyBpbXBsZW1lbnRzIEZpZWxkR2VuZXJhdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICB2b2lkIEdlbmVyYXRlUHJpdmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQWNjZXNzb3JEZWNsYXJhdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSW5saW5lQWNjZXNzb3JEZWZpbml0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc19pbmxpbmUpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQ2xlYXJpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVN3YXBwaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVDb25zdHJ1Y3RvckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2VGcm9tQ29kZWRTdHJlYW0oaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2VGcm9tQ29kZWRTdHJlYW1XaXRoUGFja2luZyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCeXRlU2l6ZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyBwcml2YXRlOgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlc187CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFJlcGVhdGVkUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGNwcAorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1BQX1BSSU1JVElWRV9GSUVMRF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9zZXJ2aWNlLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX3NlcnZpY2UuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjI2YzJhYQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9zZXJ2aWNlLmNjCkBAIC0wLDAgKzEsMzM0IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9zZXJ2aWNlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfaGVscGVycy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBjcHAgeworCitTZXJ2aWNlR2VuZXJhdG9yOjpTZXJ2aWNlR2VuZXJhdG9yKGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBPcHRpb25zJiBvcHRpb25zKQorICA6IGRlc2NyaXB0b3JfKGRlc2NyaXB0b3IpIHsKKyAgdmFyc19bImNsYXNzbmFtZSJdID0gZGVzY3JpcHRvcl8tPm5hbWUoKTsKKyAgdmFyc19bImZ1bGxfbmFtZSJdID0gZGVzY3JpcHRvcl8tPmZ1bGxfbmFtZSgpOworICBpZiAob3B0aW9ucy5kbGxleHBvcnRfZGVjbC5lbXB0eSgpKSB7CisgICAgdmFyc19bImRsbGV4cG9ydCJdID0gIiI7CisgIH0gZWxzZSB7CisgICAgdmFyc19bImRsbGV4cG9ydCJdID0gb3B0aW9ucy5kbGxleHBvcnRfZGVjbCArICIgIjsKKyAgfQorfQorCitTZXJ2aWNlR2VuZXJhdG9yOjp+U2VydmljZUdlbmVyYXRvcigpIHt9CisKK3ZvaWQgU2VydmljZUdlbmVyYXRvcjo6R2VuZXJhdGVEZWNsYXJhdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgLy8gRm9yd2FyZC1kZWNsYXJlIHRoZSBzdHViIHR5cGUuCisgIHByaW50ZXItPlByaW50KHZhcnNfLAorICAgICJjbGFzcyAkY2xhc3NuYW1lJF9TdHViO1xuIgorICAgICJcbiIpOworCisgIEdlbmVyYXRlSW50ZXJmYWNlKHByaW50ZXIpOworICBHZW5lcmF0ZVN0dWJEZWZpbml0aW9uKHByaW50ZXIpOworfQorCit2b2lkIFNlcnZpY2VHZW5lcmF0b3I6OkdlbmVyYXRlSW50ZXJmYWNlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KHZhcnNfLAorICAgICJjbGFzcyAkZGxsZXhwb3J0JCRjbGFzc25hbWUkIDogcHVibGljIDo6Z29vZ2xlOjpwcm90b2J1Zjo6U2VydmljZSB7XG4iCisgICAgIiBwcm90ZWN0ZWQ6XG4iCisgICAgIiAgLy8gVGhpcyBjbGFzcyBzaG91bGQgYmUgdHJlYXRlZCBhcyBhbiBhYnN0cmFjdCBpbnRlcmZhY2UuXG4iCisgICAgIiAgaW5saW5lICRjbGFzc25hbWUkKCkge307XG4iCisgICAgIiBwdWJsaWM6XG4iCisgICAgIiAgdmlydHVhbCB+JGNsYXNzbmFtZSQoKTtcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBwcmludGVyLT5QcmludCh2YXJzXywKKyAgICAiXG4iCisgICAgInR5cGVkZWYgJGNsYXNzbmFtZSRfU3R1YiBTdHViO1xuIgorICAgICJcbiIKKyAgICAic3RhdGljIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6U2VydmljZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IoKTtcbiIKKyAgICAiXG4iKTsKKworICBHZW5lcmF0ZU1ldGhvZFNpZ25hdHVyZXMoVklSVFVBTCwgcHJpbnRlcik7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIlxuIgorICAgICIvLyBpbXBsZW1lbnRzIFNlcnZpY2UgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuIgorICAgICJcbiIKKyAgICAiY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpTZXJ2aWNlRGVzY3JpcHRvciogR2V0RGVzY3JpcHRvcigpO1xuIgorICAgICJ2b2lkIENhbGxNZXRob2QoY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRob2REZXNjcmlwdG9yKiBtZXRob2QsXG4iCisgICAgIiAgICAgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OlJwY0NvbnRyb2xsZXIqIGNvbnRyb2xsZXIsXG4iCisgICAgIiAgICAgICAgICAgICAgICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UqIHJlcXVlc3QsXG4iCisgICAgIiAgICAgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UqIHJlc3BvbnNlLFxuIgorICAgICIgICAgICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjpDbG9zdXJlKiBkb25lKTtcbiIKKyAgICAiY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBHZXRSZXF1ZXN0UHJvdG90eXBlKFxuIgorICAgICIgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0aG9kRGVzY3JpcHRvciogbWV0aG9kKSBjb25zdDtcbiIKKyAgICAiY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBHZXRSZXNwb25zZVByb3RvdHlwZShcbiIKKyAgICAiICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGhvZERlc2NyaXB0b3IqIG1ldGhvZCkgY29uc3Q7XG4iKTsKKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KHZhcnNfLAorICAgICJcbiIKKyAgICAiIHByaXZhdGU6XG4iCisgICAgIiAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKCRjbGFzc25hbWUkKTtcbiIKKyAgICAifTtcbiIKKyAgICAiXG4iKTsKK30KKwordm9pZCBTZXJ2aWNlR2VuZXJhdG9yOjpHZW5lcmF0ZVN0dWJEZWZpbml0aW9uKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KHZhcnNfLAorICAgICJjbGFzcyAkZGxsZXhwb3J0JCRjbGFzc25hbWUkX1N0dWIgOiBwdWJsaWMgJGNsYXNzbmFtZSQge1xuIgorICAgICIgcHVibGljOlxuIik7CisKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgcHJpbnRlci0+UHJpbnQodmFyc18sCisgICAgIiRjbGFzc25hbWUkX1N0dWIoOjpnb29nbGU6OnByb3RvYnVmOjpScGNDaGFubmVsKiBjaGFubmVsKTtcbiIKKyAgICAiJGNsYXNzbmFtZSRfU3R1Yig6Omdvb2dsZTo6cHJvdG9idWY6OlJwY0NoYW5uZWwqIGNoYW5uZWwsXG4iCisgICAgIiAgICAgICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjpTZXJ2aWNlOjpDaGFubmVsT3duZXJzaGlwIG93bmVyc2hpcCk7XG4iCisgICAgIn4kY2xhc3NuYW1lJF9TdHViKCk7XG4iCisgICAgIlxuIgorICAgICJpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpScGNDaGFubmVsKiBjaGFubmVsKCkgeyByZXR1cm4gY2hhbm5lbF87IH1cbiIKKyAgICAiXG4iCisgICAgIi8vIGltcGxlbWVudHMgJGNsYXNzbmFtZSQgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4iCisgICAgIlxuIik7CisKKyAgR2VuZXJhdGVNZXRob2RTaWduYXR1cmVzKE5PTl9WSVJUVUFMLCBwcmludGVyKTsKKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KHZhcnNfLAorICAgICIgcHJpdmF0ZTpcbiIKKyAgICAiICA6Omdvb2dsZTo6cHJvdG9idWY6OlJwY0NoYW5uZWwqIGNoYW5uZWxfO1xuIgorICAgICIgIGJvb2wgb3duc19jaGFubmVsXztcbiIKKyAgICAiICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoJGNsYXNzbmFtZSRfU3R1Yik7XG4iCisgICAgIn07XG4iCisgICAgIlxuIik7Cit9CisKK3ZvaWQgU2VydmljZUdlbmVyYXRvcjo6R2VuZXJhdGVNZXRob2RTaWduYXR1cmVzKAorICAgIFZpcnR1YWxPck5vbiB2aXJ0dWFsX29yX25vbiwgaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+bWV0aG9kX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IE1ldGhvZERlc2NyaXB0b3IqIG1ldGhvZCA9IGRlc2NyaXB0b3JfLT5tZXRob2QoaSk7CisgICAgbWFwPHN0cmluZywgc3RyaW5nPiBzdWJfdmFyczsKKyAgICBzdWJfdmFyc1sibmFtZSJdID0gbWV0aG9kLT5uYW1lKCk7CisgICAgc3ViX3ZhcnNbImlucHV0X3R5cGUiXSA9IENsYXNzTmFtZShtZXRob2QtPmlucHV0X3R5cGUoKSwgdHJ1ZSk7CisgICAgc3ViX3ZhcnNbIm91dHB1dF90eXBlIl0gPSBDbGFzc05hbWUobWV0aG9kLT5vdXRwdXRfdHlwZSgpLCB0cnVlKTsKKyAgICBzdWJfdmFyc1sidmlydHVhbCJdID0gdmlydHVhbF9vcl9ub24gPT0gVklSVFVBTCA/ICJ2aXJ0dWFsICIgOiAiIjsKKworICAgIHByaW50ZXItPlByaW50KHN1Yl92YXJzLAorICAgICAgIiR2aXJ0dWFsJHZvaWQgJG5hbWUkKDo6Z29vZ2xlOjpwcm90b2J1Zjo6UnBjQ29udHJvbGxlciogY29udHJvbGxlcixcbiIKKyAgICAgICIgICAgICAgICAgICAgICAgICAgICBjb25zdCAkaW5wdXRfdHlwZSQqIHJlcXVlc3QsXG4iCisgICAgICAiICAgICAgICAgICAgICAgICAgICAgJG91dHB1dF90eXBlJCogcmVzcG9uc2UsXG4iCisgICAgICAiICAgICAgICAgICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjpDbG9zdXJlKiBkb25lKTtcbiIpOworICB9Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKwordm9pZCBTZXJ2aWNlR2VuZXJhdG9yOjpHZW5lcmF0ZURlc2NyaXB0b3JJbml0aWFsaXplcigKKyAgICBpbzo6UHJpbnRlciogcHJpbnRlciwgaW50IGluZGV4KSB7CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyczsKKyAgdmFyc1siY2xhc3NuYW1lIl0gPSBkZXNjcmlwdG9yXy0+bmFtZSgpOworICB2YXJzWyJpbmRleCJdID0gU2ltcGxlSXRvYShpbmRleCk7CisKKyAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAiJGNsYXNzbmFtZSRfZGVzY3JpcHRvcl8gPSBmaWxlLT5zZXJ2aWNlKCRpbmRleCQpO1xuIik7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKwordm9pZCBTZXJ2aWNlR2VuZXJhdG9yOjpHZW5lcmF0ZUltcGxlbWVudGF0aW9uKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KHZhcnNfLAorICAgICIkY2xhc3NuYW1lJDo6fiRjbGFzc25hbWUkKCkge31cbiIKKyAgICAiXG4iCisgICAgImNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6U2VydmljZURlc2NyaXB0b3IqICRjbGFzc25hbWUkOjpkZXNjcmlwdG9yKCkge1xuIgorICAgICIgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpO1xuIgorICAgICIgIHJldHVybiAkY2xhc3NuYW1lJF9kZXNjcmlwdG9yXztcbiIKKyAgICAifVxuIgorICAgICJcbiIKKyAgICAiY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpTZXJ2aWNlRGVzY3JpcHRvciogJGNsYXNzbmFtZSQ6OkdldERlc2NyaXB0b3IoKSB7XG4iCisgICAgIiAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7XG4iCisgICAgIiAgcmV0dXJuICRjbGFzc25hbWUkX2Rlc2NyaXB0b3JfO1xuIgorICAgICJ9XG4iCisgICAgIlxuIik7CisKKyAgLy8gR2VuZXJhdGUgbWV0aG9kcyBvZiB0aGUgaW50ZXJmYWNlLgorICBHZW5lcmF0ZU5vdEltcGxlbWVudGVkTWV0aG9kcyhwcmludGVyKTsKKyAgR2VuZXJhdGVDYWxsTWV0aG9kKHByaW50ZXIpOworICBHZW5lcmF0ZUdldFByb3RvdHlwZShSRVFVRVNULCBwcmludGVyKTsKKyAgR2VuZXJhdGVHZXRQcm90b3R5cGUoUkVTUE9OU0UsIHByaW50ZXIpOworCisgIC8vIEdlbmVyYXRlIHN0dWIgaW1wbGVtZW50YXRpb24uCisgIHByaW50ZXItPlByaW50KHZhcnNfLAorICAgICIkY2xhc3NuYW1lJF9TdHViOjokY2xhc3NuYW1lJF9TdHViKDo6Z29vZ2xlOjpwcm90b2J1Zjo6UnBjQ2hhbm5lbCogY2hhbm5lbClcbiIKKyAgICAiICA6IGNoYW5uZWxfKGNoYW5uZWwpLCBvd25zX2NoYW5uZWxfKGZhbHNlKSB7fVxuIgorICAgICIkY2xhc3NuYW1lJF9TdHViOjokY2xhc3NuYW1lJF9TdHViKFxuIgorICAgICIgICAgOjpnb29nbGU6OnByb3RvYnVmOjpScGNDaGFubmVsKiBjaGFubmVsLFxuIgorICAgICIgICAgOjpnb29nbGU6OnByb3RvYnVmOjpTZXJ2aWNlOjpDaGFubmVsT3duZXJzaGlwIG93bmVyc2hpcClcbiIKKyAgICAiICA6IGNoYW5uZWxfKGNoYW5uZWwpLFxuIgorICAgICIgICAgb3duc19jaGFubmVsXyhvd25lcnNoaXAgPT0gOjpnb29nbGU6OnByb3RvYnVmOjpTZXJ2aWNlOjpTVFVCX09XTlNfQ0hBTk5FTCkge31cbiIKKyAgICAiJGNsYXNzbmFtZSRfU3R1Yjo6fiRjbGFzc25hbWUkX1N0dWIoKSB7XG4iCisgICAgIiAgaWYgKG93bnNfY2hhbm5lbF8pIGRlbGV0ZSBjaGFubmVsXztcbiIKKyAgICAifVxuIgorICAgICJcbiIpOworCisgIEdlbmVyYXRlU3R1Yk1ldGhvZHMocHJpbnRlcik7Cit9CisKK3ZvaWQgU2VydmljZUdlbmVyYXRvcjo6R2VuZXJhdGVOb3RJbXBsZW1lbnRlZE1ldGhvZHMoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+bWV0aG9kX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IE1ldGhvZERlc2NyaXB0b3IqIG1ldGhvZCA9IGRlc2NyaXB0b3JfLT5tZXRob2QoaSk7CisgICAgbWFwPHN0cmluZywgc3RyaW5nPiBzdWJfdmFyczsKKyAgICBzdWJfdmFyc1siY2xhc3NuYW1lIl0gPSBkZXNjcmlwdG9yXy0+bmFtZSgpOworICAgIHN1Yl92YXJzWyJuYW1lIl0gPSBtZXRob2QtPm5hbWUoKTsKKyAgICBzdWJfdmFyc1siaW5kZXgiXSA9IFNpbXBsZUl0b2EoaSk7CisgICAgc3ViX3ZhcnNbImlucHV0X3R5cGUiXSA9IENsYXNzTmFtZShtZXRob2QtPmlucHV0X3R5cGUoKSwgdHJ1ZSk7CisgICAgc3ViX3ZhcnNbIm91dHB1dF90eXBlIl0gPSBDbGFzc05hbWUobWV0aG9kLT5vdXRwdXRfdHlwZSgpLCB0cnVlKTsKKworICAgIHByaW50ZXItPlByaW50KHN1Yl92YXJzLAorICAgICAgInZvaWQgJGNsYXNzbmFtZSQ6OiRuYW1lJCg6Omdvb2dsZTo6cHJvdG9idWY6OlJwY0NvbnRyb2xsZXIqIGNvbnRyb2xsZXIsXG4iCisgICAgICAiICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0ICRpbnB1dF90eXBlJCosXG4iCisgICAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICRvdXRwdXRfdHlwZSQqLFxuIgorICAgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OkNsb3N1cmUqIGRvbmUpIHtcbiIKKyAgICAgICIgIGNvbnRyb2xsZXItPlNldEZhaWxlZChcIk1ldGhvZCAkbmFtZSQoKSBub3QgaW1wbGVtZW50ZWQuXCIpO1xuIgorICAgICAgIiAgZG9uZS0+UnVuKCk7XG4iCisgICAgICAifVxuIgorICAgICAgIlxuIik7CisgIH0KK30KKwordm9pZCBTZXJ2aWNlR2VuZXJhdG9yOjpHZW5lcmF0ZUNhbGxNZXRob2QoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQodmFyc18sCisgICAgInZvaWQgJGNsYXNzbmFtZSQ6OkNhbGxNZXRob2QoY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRob2REZXNjcmlwdG9yKiBtZXRob2QsXG4iCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjpScGNDb250cm9sbGVyKiBjb250cm9sbGVyLFxuIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSogcmVxdWVzdCxcbiIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UqIHJlc3BvbnNlLFxuIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6Q2xvc3VyZSogZG9uZSkge1xuIgorICAgICIgIEdPT0dMRV9EQ0hFQ0tfRVEobWV0aG9kLT5zZXJ2aWNlKCksICRjbGFzc25hbWUkX2Rlc2NyaXB0b3JfKTtcbiIKKyAgICAiICBzd2l0Y2gobWV0aG9kLT5pbmRleCgpKSB7XG4iKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5tZXRob2RfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgTWV0aG9kRGVzY3JpcHRvciogbWV0aG9kID0gZGVzY3JpcHRvcl8tPm1ldGhvZChpKTsKKyAgICBtYXA8c3RyaW5nLCBzdHJpbmc+IHN1Yl92YXJzOworICAgIHN1Yl92YXJzWyJuYW1lIl0gPSBtZXRob2QtPm5hbWUoKTsKKyAgICBzdWJfdmFyc1siaW5kZXgiXSA9IFNpbXBsZUl0b2EoaSk7CisgICAgc3ViX3ZhcnNbImlucHV0X3R5cGUiXSA9IENsYXNzTmFtZShtZXRob2QtPmlucHV0X3R5cGUoKSwgdHJ1ZSk7CisgICAgc3ViX3ZhcnNbIm91dHB1dF90eXBlIl0gPSBDbGFzc05hbWUobWV0aG9kLT5vdXRwdXRfdHlwZSgpLCB0cnVlKTsKKworICAgIC8vIE5vdGU6ICBkb3duX2Nhc3QgZG9lcyBub3Qgd29yayBoZXJlIGJlY2F1c2UgaXQgb25seSB3b3JrcyBvbiBwb2ludGVycywKKyAgICAvLyAgIG5vdCByZWZlcmVuY2VzLgorICAgIHByaW50ZXItPlByaW50KHN1Yl92YXJzLAorICAgICAgIiAgICBjYXNlICRpbmRleCQ6XG4iCisgICAgICAiICAgICAgJG5hbWUkKGNvbnRyb2xsZXIsXG4iCisgICAgICAiICAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6ZG93bl9jYXN0PGNvbnN0ICRpbnB1dF90eXBlJCo+KHJlcXVlc3QpLFxuIgorICAgICAgIiAgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmRvd25fY2FzdDwgJG91dHB1dF90eXBlJCo+KHJlc3BvbnNlKSxcbiIKKyAgICAgICIgICAgICAgICAgICAgZG9uZSk7XG4iCisgICAgICAiICAgICAgYnJlYWs7XG4iKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KHZhcnNfLAorICAgICIgICAgZGVmYXVsdDpcbiIKKyAgICAiICAgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgXCJCYWQgbWV0aG9kIGluZGV4OyB0aGlzIHNob3VsZCBuZXZlciBoYXBwZW4uXCI7XG4iCisgICAgIiAgICAgIGJyZWFrO1xuIgorICAgICIgIH1cbiIKKyAgICAifVxuIgorICAgICJcbiIpOworfQorCit2b2lkIFNlcnZpY2VHZW5lcmF0b3I6OkdlbmVyYXRlR2V0UHJvdG90eXBlKFJlcXVlc3RPclJlc3BvbnNlIHdoaWNoLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBpZiAod2hpY2ggPT0gUkVRVUVTVCkgeworICAgIHByaW50ZXItPlByaW50KHZhcnNfLAorICAgICAgImNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgJGNsYXNzbmFtZSQ6OkdldFJlcXVlc3RQcm90b3R5cGUoXG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJzXywKKyAgICAgICJjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmICRjbGFzc25hbWUkOjpHZXRSZXNwb25zZVByb3RvdHlwZShcbiIpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQodmFyc18sCisgICAgIiAgICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGhvZERlc2NyaXB0b3IqIG1ldGhvZCkgY29uc3Qge1xuIgorICAgICIgIEdPT0dMRV9EQ0hFQ0tfRVEobWV0aG9kLT5zZXJ2aWNlKCksIGRlc2NyaXB0b3IoKSk7XG4iCisgICAgIiAgc3dpdGNoKG1ldGhvZC0+aW5kZXgoKSkge1xuIik7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+bWV0aG9kX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IE1ldGhvZERlc2NyaXB0b3IqIG1ldGhvZCA9IGRlc2NyaXB0b3JfLT5tZXRob2QoaSk7CisgICAgY29uc3QgRGVzY3JpcHRvciogdHlwZSA9CisgICAgICAod2hpY2ggPT0gUkVRVUVTVCkgPyBtZXRob2QtPmlucHV0X3R5cGUoKSA6IG1ldGhvZC0+b3V0cHV0X3R5cGUoKTsKKworICAgIG1hcDxzdHJpbmcsIHN0cmluZz4gc3ViX3ZhcnM7CisgICAgc3ViX3ZhcnNbImluZGV4Il0gPSBTaW1wbGVJdG9hKGkpOworICAgIHN1Yl92YXJzWyJ0eXBlIl0gPSBDbGFzc05hbWUodHlwZSwgdHJ1ZSk7CisKKyAgICBwcmludGVyLT5QcmludChzdWJfdmFycywKKyAgICAgICIgICAgY2FzZSAkaW5kZXgkOlxuIgorICAgICAgIiAgICAgIHJldHVybiAkdHlwZSQ6OmRlZmF1bHRfaW5zdGFuY2UoKTtcbiIpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQodmFyc18sCisgICAgIiAgICBkZWZhdWx0OlxuIgorICAgICIgICAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCBcIkJhZCBtZXRob2QgaW5kZXg7IHRoaXMgc2hvdWxkIG5ldmVyIGhhcHBlbi5cIjtcbiIKKyAgICAiICAgICAgcmV0dXJuICpzdGF0aWNfY2FzdDwgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKj4oTlVMTCk7XG4iCisgICAgIiAgfVxuIgorICAgICJ9XG4iCisgICAgIlxuIik7Cit9CisKK3ZvaWQgU2VydmljZUdlbmVyYXRvcjo6R2VuZXJhdGVTdHViTWV0aG9kcyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5tZXRob2RfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgTWV0aG9kRGVzY3JpcHRvciogbWV0aG9kID0gZGVzY3JpcHRvcl8tPm1ldGhvZChpKTsKKyAgICBtYXA8c3RyaW5nLCBzdHJpbmc+IHN1Yl92YXJzOworICAgIHN1Yl92YXJzWyJjbGFzc25hbWUiXSA9IGRlc2NyaXB0b3JfLT5uYW1lKCk7CisgICAgc3ViX3ZhcnNbIm5hbWUiXSA9IG1ldGhvZC0+bmFtZSgpOworICAgIHN1Yl92YXJzWyJpbmRleCJdID0gU2ltcGxlSXRvYShpKTsKKyAgICBzdWJfdmFyc1siaW5wdXRfdHlwZSJdID0gQ2xhc3NOYW1lKG1ldGhvZC0+aW5wdXRfdHlwZSgpLCB0cnVlKTsKKyAgICBzdWJfdmFyc1sib3V0cHV0X3R5cGUiXSA9IENsYXNzTmFtZShtZXRob2QtPm91dHB1dF90eXBlKCksIHRydWUpOworCisgICAgcHJpbnRlci0+UHJpbnQoc3ViX3ZhcnMsCisgICAgICAidm9pZCAkY2xhc3NuYW1lJF9TdHViOjokbmFtZSQoOjpnb29nbGU6OnByb3RvYnVmOjpScGNDb250cm9sbGVyKiBjb250cm9sbGVyLFxuIgorICAgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0ICRpbnB1dF90eXBlJCogcmVxdWVzdCxcbiIKKyAgICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkb3V0cHV0X3R5cGUkKiByZXNwb25zZSxcbiIKKyAgICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OkNsb3N1cmUqIGRvbmUpIHtcbiIKKyAgICAgICIgIGNoYW5uZWxfLT5DYWxsTWV0aG9kKGRlc2NyaXB0b3IoKS0+bWV0aG9kKCRpbmRleCQpLFxuIgorICAgICAgIiAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbGxlciwgcmVxdWVzdCwgcmVzcG9uc2UsIGRvbmUpO1xuIgorICAgICAgIn1cbiIpOworICB9Cit9CisKK30gIC8vIG5hbWVzcGFjZSBjcHAKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfc2VydmljZS5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX3NlcnZpY2UuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lZGUyZmQ4Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX3NlcnZpY2UuaApAQCAtMCwwICsxLDExOCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DUFBfU0VSVklDRV9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NQUF9TRVJWSUNFX0hfXworCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9vcHRpb25zLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworICBuYW1lc3BhY2UgaW8geworICAgIGNsYXNzIFByaW50ZXI7ICAgICAgICAgICAgIC8vIHByaW50ZXIuaAorICB9Cit9CisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGNwcCB7CisKK2NsYXNzIFNlcnZpY2VHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgLy8gU2VlIGdlbmVyYXRvci5jYyBmb3IgdGhlIG1lYW5pbmcgb2YgZGxsZXhwb3J0X2RlY2wuCisgIGV4cGxpY2l0IFNlcnZpY2VHZW5lcmF0b3IoY29uc3QgU2VydmljZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT3B0aW9ucyYgb3B0aW9ucyk7CisgIH5TZXJ2aWNlR2VuZXJhdG9yKCk7CisKKyAgLy8gSGVhZGVyIHN0dWZmLgorCisgIC8vIEdlbmVyYXRlIHRoZSBjbGFzcyBkZWZpbml0aW9ucyBmb3IgdGhlIHNlcnZpY2UncyBpbnRlcmZhY2UgYW5kIHRoZQorICAvLyBzdHViIGltcGxlbWVudGF0aW9uLgorICB2b2lkIEdlbmVyYXRlRGVjbGFyYXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworICAvLyBTb3VyY2UgZmlsZSBzdHVmZi4KKworICAvLyBHZW5lcmF0ZSBjb2RlIHRoYXQgaW5pdGlhbGl6ZXMgdGhlIGdsb2JhbCB2YXJpYWJsZSBzdG9yaW5nIHRoZSBzZXJ2aWNlJ3MKKyAgLy8gZGVzY3JpcHRvci4KKyAgdm9pZCBHZW5lcmF0ZURlc2NyaXB0b3JJbml0aWFsaXplcihpbzo6UHJpbnRlciogcHJpbnRlciwgaW50IGluZGV4KTsKKworICAvLyBHZW5lcmF0ZSBpbXBsZW1lbnRhdGlvbnMgb2YgZXZlcnl0aGluZyBkZWNsYXJlZCBieSBHZW5lcmF0ZURlY2xhcmF0aW9ucygpLgorICB2b2lkIEdlbmVyYXRlSW1wbGVtZW50YXRpb24oaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgcHJpdmF0ZToKKyAgZW51bSBSZXF1ZXN0T3JSZXNwb25zZSB7IFJFUVVFU1QsIFJFU1BPTlNFIH07CisgIGVudW0gVmlydHVhbE9yTm9uIHsgVklSVFVBTCwgTk9OX1ZJUlRVQUwgfTsKKworICAvLyBIZWFkZXIgc3R1ZmYuCisKKyAgLy8gR2VuZXJhdGUgdGhlIHNlcnZpY2UgYWJzdHJhY3QgaW50ZXJmYWNlLgorICB2b2lkIEdlbmVyYXRlSW50ZXJmYWNlKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworICAvLyBHZW5lcmF0ZSB0aGUgc3R1YiBjbGFzcyBkZWZpbml0aW9uLgorICB2b2lkIEdlbmVyYXRlU3R1YkRlZmluaXRpb24oaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIC8vIFByaW50cyBzaWduYXR1cmVzIGZvciBhbGwgbWV0aG9kcyBpbiB0aGUKKyAgdm9pZCBHZW5lcmF0ZU1ldGhvZFNpZ25hdHVyZXMoVmlydHVhbE9yTm9uIHZpcnR1YWxfb3Jfbm9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyAgLy8gU291cmNlIGZpbGUgc3R1ZmYuCisKKyAgLy8gR2VuZXJhdGUgdGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb25zIG9mIHRoZSBzZXJ2aWNlIG1ldGhvZHMsIHdoaWNoCisgIC8vIHByb2R1Y2UgYSAibm90IGltcGxlbWVudGVkIiBlcnJvci4KKyAgdm9pZCBHZW5lcmF0ZU5vdEltcGxlbWVudGVkTWV0aG9kcyhpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyAgLy8gR2VuZXJhdGUgdGhlIENhbGxNZXRob2QoKSBtZXRob2Qgb2YgdGhlIHNlcnZpY2UuCisgIHZvaWQgR2VuZXJhdGVDYWxsTWV0aG9kKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworICAvLyBHZW5lcmF0ZSB0aGUgR2V0e1JlcXVlc3QsUmVzcG9uc2V9UHJvdG90eXBlKCkgbWV0aG9kcy4KKyAgdm9pZCBHZW5lcmF0ZUdldFByb3RvdHlwZShSZXF1ZXN0T3JSZXNwb25zZSB3aGljaCwgaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIC8vIEdlbmVyYXRlIHRoZSBzdHViJ3MgaW1wbGVtZW50YXRpb25zIG9mIHRoZSBzZXJ2aWNlIG1ldGhvZHMuCisgIHZvaWQgR2VuZXJhdGVTdHViTWV0aG9kcyhpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyAgY29uc3QgU2VydmljZURlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcnNfOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhTZXJ2aWNlR2VuZXJhdG9yKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBjcHAKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NQUF9TRVJWSUNFX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX3N0cmluZ19maWVsZC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9zdHJpbmdfZmllbGQuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmIwODIxYQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9zdHJpbmdfZmllbGQuY2MKQEAgLTAsMCArMSw4NjQgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX3N0cmluZ19maWVsZC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBjcHAgeworCituYW1lc3BhY2UgeworCit2b2lkIFNldFN0cmluZ1ZhcmlhYmxlcyhjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICBtYXA8c3RyaW5nLCBzdHJpbmc+KiB2YXJpYWJsZXMsCisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBPcHRpb25zJiBvcHRpb25zKSB7CisgIFNldENvbW1vbkZpZWxkVmFyaWFibGVzKGRlc2NyaXB0b3IsIHZhcmlhYmxlcywgb3B0aW9ucyk7CisgICgqdmFyaWFibGVzKVsiZGVmYXVsdCJdID0gRGVmYXVsdFZhbHVlKGRlc2NyaXB0b3IpOworICAoKnZhcmlhYmxlcylbImRlZmF1bHRfbGVuZ3RoIl0gPQorICAgICAgU2ltcGxlSXRvYShkZXNjcmlwdG9yLT5kZWZhdWx0X3ZhbHVlX3N0cmluZygpLmxlbmd0aCgpKTsKKyAgc3RyaW5nIGRlZmF1bHRfdmFyaWFibGVfc3RyaW5nID0KKyAgICAgIGRlc2NyaXB0b3ItPmRlZmF1bHRfdmFsdWVfc3RyaW5nKCkuZW1wdHkoKQorICAgICAgICAgID8gIiY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSIKKyAgICAgICAgICA6ICJfZGVmYXVsdF8iICsgRmllbGROYW1lKGRlc2NyaXB0b3IpICsgIl8iOworICAoKnZhcmlhYmxlcylbImRlZmF1bHRfdmFyaWFibGUiXSA9IGRlZmF1bHRfdmFyaWFibGVfc3RyaW5nOworICAoKnZhcmlhYmxlcylbImRlZmF1bHRfdmFsdWVfaW5pdCJdID0KKyAgICAgIGRlc2NyaXB0b3ItPmRlZmF1bHRfdmFsdWVfc3RyaW5nKCkuZW1wdHkoKQorICAgICAgPyAiIiA6ICIqIiArIGRlZmF1bHRfdmFyaWFibGVfc3RyaW5nOworICAoKnZhcmlhYmxlcylbInBvaW50ZXJfdHlwZSJdID0KKyAgICAgIGRlc2NyaXB0b3ItPnR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfQllURVMgPyAidm9pZCIgOiAiY2hhciI7CisgIC8vIE5PVEU6IEVzY2FwZWQgaGVyZSB0byB1bmJsb2NrIHByb3RvMS0+cHJvdG8yIG1pZ3JhdGlvbi4KKyAgLy8gVE9ETyhsaXVqaXNpKTogRXh0ZW5kIHRoaXMgdG8gYXBwbHkgZm9yIG90aGVyIGNvbmZsaWN0aW5nIG1ldGhvZHMuCisgICgqdmFyaWFibGVzKVsicmVsZWFzZV9uYW1lIl0gPQorICAgICAgU2FmZUZ1bmN0aW9uTmFtZShkZXNjcmlwdG9yLT5jb250YWluaW5nX3R5cGUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRvciwgInJlbGVhc2VfIik7CisgICgqdmFyaWFibGVzKVsiZnVsbF9uYW1lIl0gPSBkZXNjcmlwdG9yLT5mdWxsX25hbWUoKTsKKworICAoKnZhcmlhYmxlcylbInN0cmluZ19waWVjZSJdID0gIjo6c3RkOjpzdHJpbmciOworfQorCit9ICAvLyBuYW1lc3BhY2UKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitTdHJpbmdGaWVsZEdlbmVyYXRvcjo6CitTdHJpbmdGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICBjb25zdCBPcHRpb25zJiBvcHRpb25zKQorICA6IGRlc2NyaXB0b3JfKGRlc2NyaXB0b3IpIHsKKyAgU2V0U3RyaW5nVmFyaWFibGVzKGRlc2NyaXB0b3IsICZ2YXJpYWJsZXNfLCBvcHRpb25zKTsKK30KKworU3RyaW5nRmllbGRHZW5lcmF0b3I6On5TdHJpbmdGaWVsZEdlbmVyYXRvcigpIHt9CisKK3ZvaWQgU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVQcml2YXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBOLkIuIHRoYXQgd2UgY29udGludWUgdG8gdXNlIHxBcmVuYVN0cmluZ1B0cnwgaW5zdGVhZCBvZiB8c3RyaW5nKnwgZm9yCisgIC8vIHN0cmluZyBmaWVsZHMsIGV2ZW4gd2hlbiBTdXBwb3J0QXJlbmFzKGRlc2NyaXB0b3JfKSA9PSBmYWxzZS4gV2h5PworICAvLyBUaGUgc2ltcGxlIGFuc3dlciBpcyB0byBhdm9pZCB1bm1haW50YWluYWJsZSBjb21wbGV4aXR5LiBUaGUgcmVmbGVjdGlvbgorICAvLyBjb2RlIGFzc3VtZXMgQXJlbmFTdHJpbmdQdHJzLiBUaGVzZSBhcmUgKmFsbW9zdCogaW4tbWVtb3J5LWNvbXBhdGlibGUgd2l0aAorICAvLyBzdHJpbmcqLCBleGNlcHQgZm9yIHRoZSBwb2ludGVyIHRhZ3MgYW5kIHJlbGF0ZWQgb3duZXJzaGlwIHNlbWFudGljcy4gV2UKKyAgLy8gY291bGQgbW9kaWZ5IHRoZSBydW50aW1lIGNvZGUgdG8gdXNlIHN0cmluZyogZm9yIHRoZSBub3Qtc3VwcG9ydGluZy1hcmVuYXMKKyAgLy8gY2FzZSwgYnV0IHRoaXMgd291bGQgcmVxdWlyZSBhIHdheSB0byBkZXRlY3Qgd2hpY2ggdHlwZSBvZiBjbGFzcyB3YXMKKyAgLy8gZ2VuZXJhdGVkIChhZGRpbmcgb3ZlcmhlYWQgYW5kIGNvbXBsZXhpdHkgdG8gR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24pCisgIC8vIGFuZCBsaXR0ZXJpbmcgdGhlIHJ1bnRpbWUgY29kZSBwYXRocyB3aXRoIGNvbmRpdGlvbmFscy4gSXQncyBzaW1wbGVyIHRvCisgIC8vIHN0aWNrIHdpdGggdGhpcyBidXQgdXNlIGxpZ2h0d2VpZ2h0IGFjY2Vzc29ycyB0aGF0IGFzc3VtZSBhcmVuYSA9PSBOVUxMLgorICAvLyBUaGVyZSBzaG91bGQgYmUgdmVyeSBsaXR0bGUgb3ZlcmhlYWQgYW55d2F5IGJlY2F1c2UgaXQncyBqdXN0IGEgdGFnZ2VkCisgIC8vIHBvaW50ZXIgaW4tbWVtb3J5LgorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAiOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QXJlbmFTdHJpbmdQdHIgJG5hbWUkXztcbiIpOworfQorCit2b2lkIFN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU3RhdGljTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoIWRlc2NyaXB0b3JfLT5kZWZhdWx0X3ZhbHVlX3N0cmluZygpLmVtcHR5KCkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAic3RhdGljIDo6c3RkOjpzdHJpbmcqICRkZWZhdWx0X3ZhcmlhYmxlJDtcbiIpOworICB9Cit9CisKK3ZvaWQgU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVBY2Nlc3NvckRlY2xhcmF0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBJZiB3ZSdyZSB1c2luZyBTdHJpbmdGaWVsZEdlbmVyYXRvciBmb3IgYSBmaWVsZCB3aXRoIGEgY3R5cGUsIGl0J3MKKyAgLy8gYmVjYXVzZSB0aGF0IGN0eXBlIGlzbid0IGFjdHVhbGx5IGltcGxlbWVudGVkLiAgSW4gcGFydGljdWxhciwgdGhpcyBpcworICAvLyB0cnVlIG9mIGN0eXBlPUNPUkQgYW5kIGN0eXBlPVNUUklOR19QSUVDRSBpbiB0aGUgb3BlbiBzb3VyY2UgcmVsZWFzZS4KKyAgLy8gV2UgYXJlbid0IHJlbGVhc2luZyBDb3JkIGJlY2F1c2UgaXQgaGFzIHRvbyBtYW55IEdvb2dsZS1zcGVjaWZpYworICAvLyBkZXBlbmRlbmNpZXMgYW5kIHdlIGFyZW4ndCByZWxlYXNpbmcgU3RyaW5nUGllY2UgYmVjYXVzZSBpdCdzIGhhcmRseQorICAvLyB1c2VmdWwgb3V0c2lkZSBvZiBHb29nbGUgYW5kIGJlY2F1c2UgaXQgd291bGQgZ2V0IGNvbmZ1c2luZyB0byBoYXZlCisgIC8vIG11bHRpcGxlIGluc3RhbmNlcyBvZiB0aGUgU3RyaW5nUGllY2UgY2xhc3MgaW4gZGlmZmVyZW50IGxpYnJhcmllcyAoUENSRQorICAvLyBhbHJlYWR5IGluY2x1ZGVzIGl0IGZvciB0aGVpciBDKysgYmluZGluZ3MsIHdoaWNoIGNhbWUgZnJvbSBHb29nbGUpLgorICAvLworICAvLyBJbiBhbnkgY2FzZSwgd2UgbWFrZSBhbGwgdGhlIGFjY2Vzc29ycyBwcml2YXRlIHdoaWxlIHN0aWxsIGFjdHVhbGx5CisgIC8vIHVzaW5nIGEgc3RyaW5nIHRvIHJlcHJlc2VudCB0aGUgZmllbGQgaW50ZXJuYWxseS4gIFRoaXMgd2F5LCB3ZSBjYW4KKyAgLy8gZ3VhcmFudGVlIHRoYXQgaWYgd2UgZG8gZXZlciBpbXBsZW1lbnQgdGhlIGN0eXBlLCBpdCB3b24ndCBicmVhayBhbnkKKyAgLy8gZXhpc3RpbmcgdXNlcnMgd2hvIG1pZ2h0IGJlIC0tIGZvciB3aGF0ZXZlciByZWFzb24gLS0gYWxyZWFkeSB1c2luZyAucHJvdG8KKyAgLy8gZmlsZXMgdGhhdCBhcHBsaWVkIHRoZSBjdHlwZS4gIFRoZSBmaWVsZCBjYW4gc3RpbGwgYmUgYWNjZXNzZWQgdmlhIHRoZQorICAvLyByZWZsZWN0aW9uIGludGVyZmFjZSBzaW5jZSB0aGUgcmVmbGVjdGlvbiBpbnRlcmZhY2UgaXMgaW5kZXBlbmRlbnQgb2YKKyAgLy8gdGhlIHN0cmluZydzIHVuZGVybHlpbmcgcmVwcmVzZW50YXRpb24uCisKKyAgYm9vbCB1bmtub3duX2N0eXBlID0KKyAgICAgIGRlc2NyaXB0b3JfLT5vcHRpb25zKCkuY3R5cGUoKSAhPSBFZmZlY3RpdmVTdHJpbmdDVHlwZShkZXNjcmlwdG9yXyk7CisKKyAgaWYgKHVua25vd25fY3R5cGUpIHsKKyAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiIHByaXZhdGU6XG4iCisgICAgICAiICAvLyBIaWRkZW4gZHVlIHRvIHVua25vd24gY3R5cGUgb3B0aW9uLlxuIik7CisgICAgcHJpbnRlci0+SW5kZW50KCk7CisgIH0KKworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJjb25zdCA6OnN0ZDo6c3RyaW5nJiAkbmFtZSQoKSBjb25zdCRkZXByZWNhdGlvbiQ7XG4iCisgICAgInZvaWQgc2V0XyRuYW1lJChjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkkZGVwcmVjYXRpb24kO1xuIgorICAgICJ2b2lkIHNldF8kbmFtZSQoY29uc3QgY2hhciogdmFsdWUpJGRlcHJlY2F0aW9uJDtcbiIKKyAgICAidm9pZCBzZXRfJG5hbWUkKGNvbnN0ICRwb2ludGVyX3R5cGUkKiB2YWx1ZSwgc2l6ZV90IHNpemUpIgorICAgICAgICAgICAgICAgICAiJGRlcHJlY2F0aW9uJDtcbiIKKyAgICAiOjpzdGQ6OnN0cmluZyogbXV0YWJsZV8kbmFtZSQoKSRkZXByZWNhdGlvbiQ7XG4iCisgICAgIjo6c3RkOjpzdHJpbmcqICRyZWxlYXNlX25hbWUkKCkkZGVwcmVjYXRpb24kO1xuIgorICAgICJ2b2lkIHNldF9hbGxvY2F0ZWRfJG5hbWUkKDo6c3RkOjpzdHJpbmcqICRuYW1lJCkkZGVwcmVjYXRpb24kO1xuIik7CisgIGlmIChTdXBwb3J0c0FyZW5hcyhkZXNjcmlwdG9yXykpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIjo6c3RkOjpzdHJpbmcqIHVuc2FmZV9hcmVuYV9yZWxlYXNlXyRuYW1lJCgpJGRlcHJlY2F0aW9uJDtcbiIKKyAgICAgICJ2b2lkIHVuc2FmZV9hcmVuYV9zZXRfYWxsb2NhdGVkXyRuYW1lJChcbiIKKyAgICAgICIgICAgOjpzdGQ6OnN0cmluZyogJG5hbWUkKSRkZXByZWNhdGlvbiQ7XG4iKTsKKyAgfQorCisKKyAgaWYgKHVua25vd25fY3R5cGUpIHsKKyAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgcHJpbnRlci0+UHJpbnQoIiBwdWJsaWM6XG4iKTsKKyAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgfQorfQorCit2b2lkIFN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlSW5saW5lQWNjZXNzb3JEZWZpbml0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGlzX2lubGluZSkgY29uc3QgeworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlcyh2YXJpYWJsZXNfKTsKKyAgdmFyaWFibGVzWyJpbmxpbmUiXSA9IGlzX2lubGluZSA/ICJpbmxpbmUiIDogIiI7CisgIGlmIChTdXBwb3J0c0FyZW5hcyhkZXNjcmlwdG9yXykpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXMsCisgICAgICAiJGlubGluZSQgY29uc3QgOjpzdGQ6OnN0cmluZyYgJGNsYXNzbmFtZSQ6OiRuYW1lJCgpIGNvbnN0IHtcbiIKKyAgICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6JGZ1bGxfbmFtZSQpXG4iCisgICAgICAiICByZXR1cm4gJG5hbWUkXy5HZXQoJGRlZmF1bHRfdmFyaWFibGUkKTtcbiIKKyAgICAgICJ9XG4iCisgICAgICAiJGlubGluZSQgdm9pZCAkY2xhc3NuYW1lJDo6c2V0XyRuYW1lJChjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkge1xuIgorICAgICAgIiAgJHNldF9oYXNiaXQkXG4iCisgICAgICAiICAkbmFtZSRfLlNldCgkZGVmYXVsdF92YXJpYWJsZSQsIHZhbHVlLCBHZXRBcmVuYU5vVmlydHVhbCgpKTtcbiIKKyAgICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6JGZ1bGxfbmFtZSQpXG4iCisgICAgICAifVxuIgorICAgICAgIiRpbmxpbmUkIHZvaWQgJGNsYXNzbmFtZSQ6OnNldF8kbmFtZSQoY29uc3QgY2hhciogdmFsdWUpIHtcbiIKKyAgICAgICIgICRzZXRfaGFzYml0JFxuIgorICAgICAgIiAgJG5hbWUkXy5TZXQoJGRlZmF1bHRfdmFyaWFibGUkLCAkc3RyaW5nX3BpZWNlJCh2YWx1ZSksXG4iCisgICAgICAiICAgICAgICAgICAgICBHZXRBcmVuYU5vVmlydHVhbCgpKTtcbiIKKyAgICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjokZnVsbF9uYW1lJClcbiIKKyAgICAgICJ9XG4iCisgICAgICAiJGlubGluZSQgIgorICAgICAgInZvaWQgJGNsYXNzbmFtZSQ6OnNldF8kbmFtZSQoY29uc3QgJHBvaW50ZXJfdHlwZSQqIHZhbHVlLFxuIgorICAgICAgIiAgICBzaXplX3Qgc2l6ZSkge1xuIgorICAgICAgIiAgJHNldF9oYXNiaXQkXG4iCisgICAgICAiICAkbmFtZSRfLlNldCgkZGVmYXVsdF92YXJpYWJsZSQsICRzdHJpbmdfcGllY2UkKFxuIgorICAgICAgIiAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSksIEdldEFyZW5hTm9WaXJ0dWFsKCkpO1xuIgorICAgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOiRmdWxsX25hbWUkKVxuIgorICAgICAgIn1cbiIKKyAgICAgICIkaW5saW5lJCA6OnN0ZDo6c3RyaW5nKiAkY2xhc3NuYW1lJDo6bXV0YWJsZV8kbmFtZSQoKSB7XG4iCisgICAgICAiICAkc2V0X2hhc2JpdCRcbiIKKyAgICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOiRmdWxsX25hbWUkKVxuIgorICAgICAgIiAgcmV0dXJuICRuYW1lJF8uTXV0YWJsZSgkZGVmYXVsdF92YXJpYWJsZSQsIEdldEFyZW5hTm9WaXJ0dWFsKCkpO1xuIgorICAgICAgIn1cbiIKKyAgICAgICIkaW5saW5lJCA6OnN0ZDo6c3RyaW5nKiAkY2xhc3NuYW1lJDo6JHJlbGVhc2VfbmFtZSQoKSB7XG4iCisgICAgICAiICAkY2xlYXJfaGFzYml0JFxuIgorICAgICAgIiAgcmV0dXJuICRuYW1lJF8uUmVsZWFzZSgkZGVmYXVsdF92YXJpYWJsZSQsIEdldEFyZW5hTm9WaXJ0dWFsKCkpO1xuIgorICAgICAgIn1cbiIKKyAgICAgICIkaW5saW5lJCA6OnN0ZDo6c3RyaW5nKiAkY2xhc3NuYW1lJDo6dW5zYWZlX2FyZW5hX3JlbGVhc2VfJG5hbWUkKCkge1xuIgorICAgICAgIiAgR09PR0xFX0RDSEVDSyhHZXRBcmVuYU5vVmlydHVhbCgpICE9IE5VTEwpO1xuIgorICAgICAgIiAgJGNsZWFyX2hhc2JpdCRcbiIKKyAgICAgICIgIHJldHVybiAkbmFtZSRfLlVuc2FmZUFyZW5hUmVsZWFzZSgkZGVmYXVsdF92YXJpYWJsZSQsXG4iCisgICAgICAiICAgICAgR2V0QXJlbmFOb1ZpcnR1YWwoKSk7XG4iCisgICAgICAifVxuIgorICAgICAgIiRpbmxpbmUkIHZvaWQgJGNsYXNzbmFtZSQ6OnNldF9hbGxvY2F0ZWRfJG5hbWUkKDo6c3RkOjpzdHJpbmcqICRuYW1lJCkge1xuIgorICAgICAgIiAgaWYgKCRuYW1lJCAhPSBOVUxMKSB7XG4iCisgICAgICAiICAgICRzZXRfaGFzYml0JFxuIgorICAgICAgIiAgfSBlbHNlIHtcbiIKKyAgICAgICIgICAgJGNsZWFyX2hhc2JpdCRcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICIgICRuYW1lJF8uU2V0QWxsb2NhdGVkKCRkZWZhdWx0X3ZhcmlhYmxlJCwgJG5hbWUkLFxuIgorICAgICAgIiAgICAgIEdldEFyZW5hTm9WaXJ0dWFsKCkpO1xuIgorICAgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6JGZ1bGxfbmFtZSQpXG4iCisgICAgICAifVxuIgorICAgICAgIiRpbmxpbmUkIHZvaWQgJGNsYXNzbmFtZSQ6OnVuc2FmZV9hcmVuYV9zZXRfYWxsb2NhdGVkXyRuYW1lJChcbiIKKyAgICAgICIgICAgOjpzdGQ6OnN0cmluZyogJG5hbWUkKSB7XG4iCisgICAgICAiICBHT09HTEVfRENIRUNLKEdldEFyZW5hTm9WaXJ0dWFsKCkgIT0gTlVMTCk7XG4iCisgICAgICAiICBpZiAoJG5hbWUkICE9IE5VTEwpIHtcbiIKKyAgICAgICIgICAgJHNldF9oYXNiaXQkXG4iCisgICAgICAiICB9IGVsc2Uge1xuIgorICAgICAgIiAgICAkY2xlYXJfaGFzYml0JFxuIgorICAgICAgIiAgfVxuIgorICAgICAgIiAgJG5hbWUkXy5VbnNhZmVBcmVuYVNldEFsbG9jYXRlZCgkZGVmYXVsdF92YXJpYWJsZSQsXG4iCisgICAgICAiICAgICAgJG5hbWUkLCBHZXRBcmVuYU5vVmlydHVhbCgpKTtcbiIKKyAgICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOiRmdWxsX25hbWUkKVxuIgorICAgICAgIn1cbiIpOworICB9IGVsc2UgeworICAgIC8vIE5vLWFyZW5hIGNhc2UuCisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICAgIiRpbmxpbmUkIGNvbnN0IDo6c3RkOjpzdHJpbmcmICRjbGFzc25hbWUkOjokbmFtZSQoKSBjb25zdCB7XG4iCisgICAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0OiRmdWxsX25hbWUkKVxuIgorICAgICAgIiAgcmV0dXJuICRuYW1lJF8uR2V0Tm9BcmVuYSgkZGVmYXVsdF92YXJpYWJsZSQpO1xuIgorICAgICAgIn1cbiIKKyAgICAgICIkaW5saW5lJCB2b2lkICRjbGFzc25hbWUkOjpzZXRfJG5hbWUkKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7XG4iCisgICAgICAiICAkc2V0X2hhc2JpdCRcbiIKKyAgICAgICIgICRuYW1lJF8uU2V0Tm9BcmVuYSgkZGVmYXVsdF92YXJpYWJsZSQsIHZhbHVlKTtcbiIKKyAgICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6JGZ1bGxfbmFtZSQpXG4iCisgICAgICAifVxuIgorICAgICAgIiRpbmxpbmUkIHZvaWQgJGNsYXNzbmFtZSQ6OnNldF8kbmFtZSQoY29uc3QgY2hhciogdmFsdWUpIHtcbiIKKyAgICAgICIgICRzZXRfaGFzYml0JFxuIgorICAgICAgIiAgJG5hbWUkXy5TZXROb0FyZW5hKCRkZWZhdWx0X3ZhcmlhYmxlJCwgJHN0cmluZ19waWVjZSQodmFsdWUpKTtcbiIKKyAgICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjokZnVsbF9uYW1lJClcbiIKKyAgICAgICJ9XG4iCisgICAgICAiJGlubGluZSQgIgorICAgICAgInZvaWQgJGNsYXNzbmFtZSQ6OnNldF8kbmFtZSQoY29uc3QgJHBvaW50ZXJfdHlwZSQqIHZhbHVlLCAiCisgICAgICAic2l6ZV90IHNpemUpIHtcbiIKKyAgICAgICIgICRzZXRfaGFzYml0JFxuIgorICAgICAgIiAgJG5hbWUkXy5TZXROb0FyZW5hKCRkZWZhdWx0X3ZhcmlhYmxlJCxcbiIKKyAgICAgICIgICAgICAkc3RyaW5nX3BpZWNlJChyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTtcbiIKKyAgICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjokZnVsbF9uYW1lJClcbiIKKyAgICAgICJ9XG4iCisgICAgICAiJGlubGluZSQgOjpzdGQ6OnN0cmluZyogJGNsYXNzbmFtZSQ6Om11dGFibGVfJG5hbWUkKCkge1xuIgorICAgICAgIiAgJHNldF9oYXNiaXQkXG4iCisgICAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTokZnVsbF9uYW1lJClcbiIKKyAgICAgICIgIHJldHVybiAkbmFtZSRfLk11dGFibGVOb0FyZW5hKCRkZWZhdWx0X3ZhcmlhYmxlJCk7XG4iCisgICAgICAifVxuIgorICAgICAgIiRpbmxpbmUkIDo6c3RkOjpzdHJpbmcqICRjbGFzc25hbWUkOjokcmVsZWFzZV9uYW1lJCgpIHtcbiIKKyAgICAgICIgICRjbGVhcl9oYXNiaXQkXG4iCisgICAgICAiICByZXR1cm4gJG5hbWUkXy5SZWxlYXNlTm9BcmVuYSgkZGVmYXVsdF92YXJpYWJsZSQpO1xuIgorICAgICAgIn1cbiIKKyAgICAgICIkaW5saW5lJCB2b2lkICRjbGFzc25hbWUkOjpzZXRfYWxsb2NhdGVkXyRuYW1lJCg6OnN0ZDo6c3RyaW5nKiAkbmFtZSQpIHtcbiIKKyAgICAgICIgIGlmICgkbmFtZSQgIT0gTlVMTCkge1xuIgorICAgICAgIiAgICAkc2V0X2hhc2JpdCRcbiIKKyAgICAgICIgIH0gZWxzZSB7XG4iCisgICAgICAiICAgICRjbGVhcl9oYXNiaXQkXG4iCisgICAgICAiICB9XG4iCisgICAgICAiICAkbmFtZSRfLlNldEFsbG9jYXRlZE5vQXJlbmEoJGRlZmF1bHRfdmFyaWFibGUkLCAkbmFtZSQpO1xuIgorICAgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6JGZ1bGxfbmFtZSQpXG4iCisgICAgICAifVxuIik7CisgIH0KK30KKwordm9pZCBTdHJpbmdGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU5vbklubGluZUFjY2Vzc29yRGVmaW5pdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKCFkZXNjcmlwdG9yXy0+ZGVmYXVsdF92YWx1ZV9zdHJpbmcoKS5lbXB0eSgpKSB7CisgICAgLy8gSW5pdGlhbGl6ZWQgaW4gR2VuZXJhdGVEZWZhdWx0SW5zdGFuY2VBbGxvY2F0b3IuCisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICI6OnN0ZDo6c3RyaW5nKiAkY2xhc3NuYW1lJDo6JGRlZmF1bHRfdmFyaWFibGUkID0gTlVMTDtcbiIpOworICB9Cit9CisKK3ZvaWQgU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVDbGVhcmluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gVHdvLWRpbWVuc2lvbiBzcGVjaWFsaXphdGlvbiBoZXJlOiBzdXBwb3J0aW5nIGFyZW5hcyBvciBub3QsIGFuZCBkZWZhdWx0CisgIC8vIHZhbHVlIGlzIHRoZSBlbXB0eSBzdHJpbmcgb3Igbm90LiBDb21wbGV4aXR5IGhlcmUgZW5zdXJlcyB0aGUgbWluaW1hbAorICAvLyBudW1iZXIgb2YgYnJhbmNoZXMgLyBhbW91bnQgb2YgZXh0cmFuZW91cyBjb2RlIGF0IHJ1bnRpbWUgKGdpdmVuIHRoYXQgdGhlCisgIC8vIGJlbG93IG1ldGhvZHMgYXJlIGlubGluZWQgb25lLWxpbmVycykhCisgIGlmIChTdXBwb3J0c0FyZW5hcyhkZXNjcmlwdG9yXykpIHsKKyAgICBpZiAoZGVzY3JpcHRvcl8tPmRlZmF1bHRfdmFsdWVfc3RyaW5nKCkuZW1wdHkoKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgIiRuYW1lJF8uQ2xlYXJUb0VtcHR5KCRkZWZhdWx0X3ZhcmlhYmxlJCwgR2V0QXJlbmFOb1ZpcnR1YWwoKSk7XG4iKTsKKyAgICB9IGVsc2UgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgIiRuYW1lJF8uQ2xlYXJUb0RlZmF1bHQoJGRlZmF1bHRfdmFyaWFibGUkLCBHZXRBcmVuYU5vVmlydHVhbCgpKTtcbiIpOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICBpZiAoZGVzY3JpcHRvcl8tPmRlZmF1bHRfdmFsdWVfc3RyaW5nKCkuZW1wdHkoKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgIiRuYW1lJF8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgkZGVmYXVsdF92YXJpYWJsZSQpO1xuIik7CisgICAgfSBlbHNlIHsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICIkbmFtZSRfLkNsZWFyVG9EZWZhdWx0Tm9BcmVuYSgkZGVmYXVsdF92YXJpYWJsZSQpO1xuIik7CisgICAgfQorICB9Cit9CisKK3ZvaWQgU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoU3VwcG9ydHNBcmVuYXMoZGVzY3JpcHRvcl8pIHx8IGRlc2NyaXB0b3JfLT5jb250YWluaW5nX29uZW9mKCkgIT0gTlVMTCkgeworICAgIC8vIFRPRE8oZ3Bpa2UpOiBpbXByb3ZlIHRoaXMKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAic2V0XyRuYW1lJChmcm9tLiRuYW1lJCgpKTtcbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJHNldF9oYXNiaXQkXG4iCisgICAgICAiJG5hbWUkXy5Bc3NpZ25XaXRoRGVmYXVsdCgkZGVmYXVsdF92YXJpYWJsZSQsIGZyb20uJG5hbWUkXyk7XG4iKTsKKyAgfQorfQorCit2b2lkIFN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU3dhcHBpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sICIkbmFtZSRfLlN3YXAoJm90aGVyLT4kbmFtZSRfKTtcbiIpOworfQorCit2b2lkIFN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQ29uc3RydWN0b3JDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJG5hbWUkXy5VbnNhZmVTZXREZWZhdWx0KCRkZWZhdWx0X3ZhcmlhYmxlJCk7XG4iKTsKK30KKwordm9pZCBTdHJpbmdGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZURlc3RydWN0b3JDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChTdXBwb3J0c0FyZW5hcyhkZXNjcmlwdG9yXykpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRuYW1lJF8uRGVzdHJveSgkZGVmYXVsdF92YXJpYWJsZSQsIEdldEFyZW5hTm9WaXJ0dWFsKCkpO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkbmFtZSRfLkRlc3Ryb3lOb0FyZW5hKCRkZWZhdWx0X3ZhcmlhYmxlJCk7XG4iKTsKKyAgfQorfQorCit2b2lkIFN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlRGVmYXVsdEluc3RhbmNlQWxsb2NhdG9yKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmICghZGVzY3JpcHRvcl8tPmRlZmF1bHRfdmFsdWVfc3RyaW5nKCkuZW1wdHkoKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJGNsYXNzbmFtZSQ6OiRkZWZhdWx0X3ZhcmlhYmxlJCA9XG4iCisgICAgICAiICAgIG5ldyA6OnN0ZDo6c3RyaW5nKCRkZWZhdWx0JCwgJGRlZmF1bHRfbGVuZ3RoJCk7XG4iKTsKKyAgfQorfQorCit2b2lkIFN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2h1dGRvd25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmICghZGVzY3JpcHRvcl8tPmRlZmF1bHRfdmFsdWVfc3RyaW5nKCkuZW1wdHkoKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiZGVsZXRlICRjbGFzc25hbWUkOjokZGVmYXVsdF92YXJpYWJsZSQ7XG4iKTsKKyAgfQorfQorCit2b2lkIFN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2VGcm9tQ29kZWRTdHJlYW0oaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkJGRlY2xhcmVkX3R5cGUkKFxuIgorICAgICIgICAgICBpbnB1dCwgdGhpcy0+bXV0YWJsZV8kbmFtZSQoKSkpO1xuIik7CisKKyAgaWYgKGRlc2NyaXB0b3JfLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX1NUUklORykgeworICAgIEdlbmVyYXRlVXRmOENoZWNrQ29kZUZvclN0cmluZygKKyAgICAgICAgZGVzY3JpcHRvcl8sIHRydWUsIHZhcmlhYmxlc18sCisgICAgICAgICJ0aGlzLT4kbmFtZSQoKS5kYXRhKCksIHRoaXMtPiRuYW1lJCgpLmxlbmd0aCgpLFxuIiwgcHJpbnRlcik7CisgIH0KK30KKwordm9pZCBTdHJpbmdGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoZGVzY3JpcHRvcl8tPnR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU1RSSU5HKSB7CisgICAgR2VuZXJhdGVVdGY4Q2hlY2tDb2RlRm9yU3RyaW5nKAorICAgICAgICBkZXNjcmlwdG9yXywgZmFsc2UsIHZhcmlhYmxlc18sCisgICAgICAgICJ0aGlzLT4kbmFtZSQoKS5kYXRhKCksIHRoaXMtPiRuYW1lJCgpLmxlbmd0aCgpLFxuIiwgcHJpbnRlcik7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlJGRlY2xhcmVkX3R5cGUkTWF5YmVBbGlhc2VkKFxuIgorICAgICIgICRudW1iZXIkLCB0aGlzLT4kbmFtZSQoKSwgb3V0cHV0KTtcbiIpOworfQorCit2b2lkIFN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoZGVzY3JpcHRvcl8tPnR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU1RSSU5HKSB7CisgICAgR2VuZXJhdGVVdGY4Q2hlY2tDb2RlRm9yU3RyaW5nKAorICAgICAgICBkZXNjcmlwdG9yXywgZmFsc2UsIHZhcmlhYmxlc18sCisgICAgICAgICJ0aGlzLT4kbmFtZSQoKS5kYXRhKCksIHRoaXMtPiRuYW1lJCgpLmxlbmd0aCgpLFxuIiwgcHJpbnRlcik7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAidGFyZ2V0ID1cbiIKKyAgICAiICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGUkZGVjbGFyZWRfdHlwZSRUb0FycmF5KFxuIgorICAgICIgICAgJG51bWJlciQsIHRoaXMtPiRuYW1lJCgpLCB0YXJnZXQpO1xuIik7Cit9CisKK3ZvaWQgU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVCeXRlU2l6ZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJ0b3RhbF9zaXplICs9ICR0YWdfc2l6ZSQgK1xuIgorICAgICIgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjokZGVjbGFyZWRfdHlwZSRTaXplKFxuIgorICAgICIgICAgdGhpcy0+JG5hbWUkKCkpO1xuIik7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworU3RyaW5nT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitTdHJpbmdPbmVvZkZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT3B0aW9ucyYgb3B0aW9ucykKKyAgICA6IFN0cmluZ0ZpZWxkR2VuZXJhdG9yKGRlc2NyaXB0b3IsIG9wdGlvbnMpLAorICAgICAgZGVwZW5kZW50X2ZpZWxkXyhvcHRpb25zLnByb3RvX2gpIHsKKyAgU2V0Q29tbW9uT25lb2ZGaWVsZFZhcmlhYmxlcyhkZXNjcmlwdG9yLCAmdmFyaWFibGVzXyk7Cit9CisKK1N0cmluZ09uZW9mRmllbGRHZW5lcmF0b3I6On5TdHJpbmdPbmVvZkZpZWxkR2VuZXJhdG9yKCkge30KKwordm9pZCBTdHJpbmdPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlSW5saW5lQWNjZXNzb3JEZWZpbml0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGlzX2lubGluZSkgY29uc3QgeworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlcyh2YXJpYWJsZXNfKTsKKyAgdmFyaWFibGVzWyJpbmxpbmUiXSA9IGlzX2lubGluZSA/ICJpbmxpbmUiIDogIiI7CisgIGlmIChTdXBwb3J0c0FyZW5hcyhkZXNjcmlwdG9yXykpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXMsCisgICAgICAiJGlubGluZSQgY29uc3QgOjpzdGQ6OnN0cmluZyYgJGNsYXNzbmFtZSQ6OiRuYW1lJCgpIGNvbnN0IHtcbiIKKyAgICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6JGZ1bGxfbmFtZSQpXG4iCisgICAgICAiICBpZiAoaGFzXyRuYW1lJCgpKSB7XG4iCisgICAgICAiICAgIHJldHVybiAkb25lb2ZfcHJlZml4JCRuYW1lJF8uR2V0KCRkZWZhdWx0X3ZhcmlhYmxlJCk7XG4iCisgICAgICAiICB9XG4iCisgICAgICAiICByZXR1cm4gKiRkZWZhdWx0X3ZhcmlhYmxlJDtcbiIKKyAgICAgICJ9XG4iCisgICAgICAiJGlubGluZSQgdm9pZCAkY2xhc3NuYW1lJDo6c2V0XyRuYW1lJChjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkge1xuIgorICAgICAgIiAgaWYgKCFoYXNfJG5hbWUkKCkpIHtcbiIKKyAgICAgICIgICAgY2xlYXJfJG9uZW9mX25hbWUkKCk7XG4iCisgICAgICAiICAgIHNldF9oYXNfJG5hbWUkKCk7XG4iCisgICAgICAiICAgICRvbmVvZl9wcmVmaXgkJG5hbWUkXy5VbnNhZmVTZXREZWZhdWx0KCRkZWZhdWx0X3ZhcmlhYmxlJCk7XG4iCisgICAgICAiICB9XG4iCisgICAgICAiICAkb25lb2ZfcHJlZml4JCRuYW1lJF8uU2V0KCRkZWZhdWx0X3ZhcmlhYmxlJCwgdmFsdWUsXG4iCisgICAgICAiICAgICAgR2V0QXJlbmFOb1ZpcnR1YWwoKSk7XG4iCisgICAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0OiRmdWxsX25hbWUkKVxuIgorICAgICAgIn1cbiIKKyAgICAgICIkaW5saW5lJCB2b2lkICRjbGFzc25hbWUkOjpzZXRfJG5hbWUkKGNvbnN0IGNoYXIqIHZhbHVlKSB7XG4iCisgICAgICAiICBpZiAoIWhhc18kbmFtZSQoKSkge1xuIgorICAgICAgIiAgICBjbGVhcl8kb25lb2ZfbmFtZSQoKTtcbiIKKyAgICAgICIgICAgc2V0X2hhc18kbmFtZSQoKTtcbiIKKyAgICAgICIgICAgJG9uZW9mX3ByZWZpeCQkbmFtZSRfLlVuc2FmZVNldERlZmF1bHQoJGRlZmF1bHRfdmFyaWFibGUkKTtcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICIgICRvbmVvZl9wcmVmaXgkJG5hbWUkXy5TZXQoJGRlZmF1bHRfdmFyaWFibGUkLFxuIgorICAgICAgIiAgICAgICRzdHJpbmdfcGllY2UkKHZhbHVlKSwgR2V0QXJlbmFOb1ZpcnR1YWwoKSk7XG4iCisgICAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6JGZ1bGxfbmFtZSQpXG4iCisgICAgICAifVxuIgorICAgICAgIiRpbmxpbmUkICIKKyAgICAgICJ2b2lkICRjbGFzc25hbWUkOjpzZXRfJG5hbWUkKGNvbnN0ICRwb2ludGVyX3R5cGUkKiB2YWx1ZSxcbiIKKyAgICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCBzaXplKSB7XG4iCisgICAgICAiICBpZiAoIWhhc18kbmFtZSQoKSkge1xuIgorICAgICAgIiAgICBjbGVhcl8kb25lb2ZfbmFtZSQoKTtcbiIKKyAgICAgICIgICAgc2V0X2hhc18kbmFtZSQoKTtcbiIKKyAgICAgICIgICAgJG9uZW9mX3ByZWZpeCQkbmFtZSRfLlVuc2FmZVNldERlZmF1bHQoJGRlZmF1bHRfdmFyaWFibGUkKTtcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICIgICRvbmVvZl9wcmVmaXgkJG5hbWUkXy5TZXQoJGRlZmF1bHRfdmFyaWFibGUkLCAkc3RyaW5nX3BpZWNlJChcbiIKKyAgICAgICIgICAgICByZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpLFxuIgorICAgICAgIiAgICAgIEdldEFyZW5hTm9WaXJ0dWFsKCkpO1xuIgorICAgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOiRmdWxsX25hbWUkKVxuIgorICAgICAgIn1cbiIKKyAgICAgICIkaW5saW5lJCA6OnN0ZDo6c3RyaW5nKiAkY2xhc3NuYW1lJDo6bXV0YWJsZV8kbmFtZSQoKSB7XG4iCisgICAgICAiICBpZiAoIWhhc18kbmFtZSQoKSkge1xuIgorICAgICAgIiAgICBjbGVhcl8kb25lb2ZfbmFtZSQoKTtcbiIKKyAgICAgICIgICAgc2V0X2hhc18kbmFtZSQoKTtcbiIKKyAgICAgICIgICAgJG9uZW9mX3ByZWZpeCQkbmFtZSRfLlVuc2FmZVNldERlZmF1bHQoJGRlZmF1bHRfdmFyaWFibGUkKTtcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICIgIHJldHVybiAkb25lb2ZfcHJlZml4JCRuYW1lJF8uTXV0YWJsZSgkZGVmYXVsdF92YXJpYWJsZSQsXG4iCisgICAgICAiICAgICAgR2V0QXJlbmFOb1ZpcnR1YWwoKSk7XG4iCisgICAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTokZnVsbF9uYW1lJClcbiIKKyAgICAgICJ9XG4iCisgICAgICAiJGlubGluZSQgOjpzdGQ6OnN0cmluZyogJGNsYXNzbmFtZSQ6OiRyZWxlYXNlX25hbWUkKCkge1xuIgorICAgICAgIiAgaWYgKGhhc18kbmFtZSQoKSkge1xuIgorICAgICAgIiAgICBjbGVhcl9oYXNfJG9uZW9mX25hbWUkKCk7XG4iCisgICAgICAiICAgIHJldHVybiAkb25lb2ZfcHJlZml4JCRuYW1lJF8uUmVsZWFzZSgkZGVmYXVsdF92YXJpYWJsZSQsXG4iCisgICAgICAiICAgICAgICBHZXRBcmVuYU5vVmlydHVhbCgpKTtcbiIKKyAgICAgICIgIH0gZWxzZSB7XG4iCisgICAgICAiICAgIHJldHVybiBOVUxMO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIn1cbiIKKyAgICAgICIkaW5saW5lJCA6OnN0ZDo6c3RyaW5nKiAkY2xhc3NuYW1lJDo6dW5zYWZlX2FyZW5hX3JlbGVhc2VfJG5hbWUkKCkge1xuIgorICAgICAgIiAgR09PR0xFX0RDSEVDSyhHZXRBcmVuYU5vVmlydHVhbCgpICE9IE5VTEwpO1xuIgorICAgICAgIiAgaWYgKGhhc18kbmFtZSQoKSkge1xuIgorICAgICAgIiAgICBjbGVhcl9oYXNfJG9uZW9mX25hbWUkKCk7XG4iCisgICAgICAiICAgIHJldHVybiAkb25lb2ZfcHJlZml4JCRuYW1lJF8uVW5zYWZlQXJlbmFSZWxlYXNlKFxuIgorICAgICAgIiAgICAgICAgJGRlZmF1bHRfdmFyaWFibGUkLCBHZXRBcmVuYU5vVmlydHVhbCgpKTtcbiIKKyAgICAgICIgIH0gZWxzZSB7XG4iCisgICAgICAiICAgIHJldHVybiBOVUxMO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIn1cbiIKKyAgICAgICIkaW5saW5lJCB2b2lkICRjbGFzc25hbWUkOjpzZXRfYWxsb2NhdGVkXyRuYW1lJCg6OnN0ZDo6c3RyaW5nKiAkbmFtZSQpIHtcbiIKKyAgICAgICIgIGlmICghaGFzXyRuYW1lJCgpKSB7XG4iCisgICAgICAiICAgICRvbmVvZl9wcmVmaXgkJG5hbWUkXy5VbnNhZmVTZXREZWZhdWx0KCRkZWZhdWx0X3ZhcmlhYmxlJCk7XG4iCisgICAgICAiICB9XG4iCisgICAgICAiICBjbGVhcl8kb25lb2ZfbmFtZSQoKTtcbiIKKyAgICAgICIgIGlmICgkbmFtZSQgIT0gTlVMTCkge1xuIgorICAgICAgIiAgICBzZXRfaGFzXyRuYW1lJCgpO1xuIgorICAgICAgIiAgICAkb25lb2ZfcHJlZml4JCRuYW1lJF8uU2V0QWxsb2NhdGVkKCRkZWZhdWx0X3ZhcmlhYmxlJCwgJG5hbWUkLFxuIgorICAgICAgIiAgICAgICAgR2V0QXJlbmFOb1ZpcnR1YWwoKSk7XG4iCisgICAgICAiICB9XG4iCisgICAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDokZnVsbF9uYW1lJClcbiIKKyAgICAgICJ9XG4iCisgICAgICAiJGlubGluZSQgdm9pZCAkY2xhc3NuYW1lJDo6dW5zYWZlX2FyZW5hX3NldF9hbGxvY2F0ZWRfJG5hbWUkKCIKKyAgICAgICI6OnN0ZDo6c3RyaW5nKiAkbmFtZSQpIHtcbiIKKyAgICAgICIgIEdPT0dMRV9EQ0hFQ0soR2V0QXJlbmFOb1ZpcnR1YWwoKSAhPSBOVUxMKTtcbiIKKyAgICAgICIgIGlmICghaGFzXyRuYW1lJCgpKSB7XG4iCisgICAgICAiICAgICRvbmVvZl9wcmVmaXgkJG5hbWUkXy5VbnNhZmVTZXREZWZhdWx0KCRkZWZhdWx0X3ZhcmlhYmxlJCk7XG4iCisgICAgICAiICB9XG4iCisgICAgICAiICBjbGVhcl8kb25lb2ZfbmFtZSQoKTtcbiIKKyAgICAgICIgIGlmICgkbmFtZSQpIHtcbiIKKyAgICAgICIgICAgc2V0X2hhc18kbmFtZSQoKTtcbiIKKyAgICAgICIgICAgJG9uZW9mX3ByZWZpeCQkbmFtZSRfLlVuc2FmZUFyZW5hU2V0QWxsb2NhdGVkKCRkZWZhdWx0X3ZhcmlhYmxlJCwgIgorICAgICAgIiRuYW1lJCwgR2V0QXJlbmFOb1ZpcnR1YWwoKSk7XG4iCisgICAgICAiICB9XG4iCisgICAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDokZnVsbF9uYW1lJClcbiIKKyAgICAgICJ9XG4iKTsKKyAgfSBlbHNlIHsKKyAgICAvLyBOby1hcmVuYSBjYXNlLgorICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAgICIkaW5saW5lJCBjb25zdCA6OnN0ZDo6c3RyaW5nJiAkY2xhc3NuYW1lJDo6JG5hbWUkKCkgY29uc3Qge1xuIgorICAgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDokZnVsbF9uYW1lJClcbiIKKyAgICAgICIgIGlmIChoYXNfJG5hbWUkKCkpIHtcbiIKKyAgICAgICIgICAgcmV0dXJuICRvbmVvZl9wcmVmaXgkJG5hbWUkXy5HZXROb0FyZW5hKCRkZWZhdWx0X3ZhcmlhYmxlJCk7XG4iCisgICAgICAiICB9XG4iCisgICAgICAiICByZXR1cm4gKiRkZWZhdWx0X3ZhcmlhYmxlJDtcbiIKKyAgICAgICJ9XG4iCisgICAgICAiJGlubGluZSQgdm9pZCAkY2xhc3NuYW1lJDo6c2V0XyRuYW1lJChjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkge1xuIgorICAgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDokZnVsbF9uYW1lJClcbiIKKyAgICAgICIgIGlmICghaGFzXyRuYW1lJCgpKSB7XG4iCisgICAgICAiICAgIGNsZWFyXyRvbmVvZl9uYW1lJCgpO1xuIgorICAgICAgIiAgICBzZXRfaGFzXyRuYW1lJCgpO1xuIgorICAgICAgIiAgICAkb25lb2ZfcHJlZml4JCRuYW1lJF8uVW5zYWZlU2V0RGVmYXVsdCgkZGVmYXVsdF92YXJpYWJsZSQpO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIiAgJG9uZW9mX3ByZWZpeCQkbmFtZSRfLlNldE5vQXJlbmEoJGRlZmF1bHRfdmFyaWFibGUkLCB2YWx1ZSk7XG4iCisgICAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0OiRmdWxsX25hbWUkKVxuIgorICAgICAgIn1cbiIKKyAgICAgICIkaW5saW5lJCB2b2lkICRjbGFzc25hbWUkOjpzZXRfJG5hbWUkKGNvbnN0IGNoYXIqIHZhbHVlKSB7XG4iCisgICAgICAiICBpZiAoIWhhc18kbmFtZSQoKSkge1xuIgorICAgICAgIiAgICBjbGVhcl8kb25lb2ZfbmFtZSQoKTtcbiIKKyAgICAgICIgICAgc2V0X2hhc18kbmFtZSQoKTtcbiIKKyAgICAgICIgICAgJG9uZW9mX3ByZWZpeCQkbmFtZSRfLlVuc2FmZVNldERlZmF1bHQoJGRlZmF1bHRfdmFyaWFibGUkKTtcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICIgICRvbmVvZl9wcmVmaXgkJG5hbWUkXy5TZXROb0FyZW5hKCRkZWZhdWx0X3ZhcmlhYmxlJCxcbiIKKyAgICAgICIgICAgICAkc3RyaW5nX3BpZWNlJCh2YWx1ZSkpO1xuIgorICAgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOiRmdWxsX25hbWUkKVxuIgorICAgICAgIn1cbiIKKyAgICAgICIkaW5saW5lJCAiCisgICAgICAidm9pZCAkY2xhc3NuYW1lJDo6c2V0XyRuYW1lJChjb25zdCAkcG9pbnRlcl90eXBlJCogdmFsdWUsIHNpemVfdCBzaXplKSB7XG4iCisgICAgICAiICBpZiAoIWhhc18kbmFtZSQoKSkge1xuIgorICAgICAgIiAgICBjbGVhcl8kb25lb2ZfbmFtZSQoKTtcbiIKKyAgICAgICIgICAgc2V0X2hhc18kbmFtZSQoKTtcbiIKKyAgICAgICIgICAgJG9uZW9mX3ByZWZpeCQkbmFtZSRfLlVuc2FmZVNldERlZmF1bHQoJGRlZmF1bHRfdmFyaWFibGUkKTtcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICIgICRvbmVvZl9wcmVmaXgkJG5hbWUkXy5TZXROb0FyZW5hKCRkZWZhdWx0X3ZhcmlhYmxlJCwgJHN0cmluZ19waWVjZSQoXG4iCisgICAgICAiICAgICAgcmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7XG4iCisgICAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6JGZ1bGxfbmFtZSQpXG4iCisgICAgICAifVxuIgorICAgICAgIiRpbmxpbmUkIDo6c3RkOjpzdHJpbmcqICRjbGFzc25hbWUkOjptdXRhYmxlXyRuYW1lJCgpIHtcbiIKKyAgICAgICIgIGlmICghaGFzXyRuYW1lJCgpKSB7XG4iCisgICAgICAiICAgIGNsZWFyXyRvbmVvZl9uYW1lJCgpO1xuIgorICAgICAgIiAgICBzZXRfaGFzXyRuYW1lJCgpO1xuIgorICAgICAgIiAgICAkb25lb2ZfcHJlZml4JCRuYW1lJF8uVW5zYWZlU2V0RGVmYXVsdCgkZGVmYXVsdF92YXJpYWJsZSQpO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6JGZ1bGxfbmFtZSQpXG4iCisgICAgICAiICByZXR1cm4gJG9uZW9mX3ByZWZpeCQkbmFtZSRfLk11dGFibGVOb0FyZW5hKCRkZWZhdWx0X3ZhcmlhYmxlJCk7XG4iCisgICAgICAifVxuIgorICAgICAgIiRpbmxpbmUkIDo6c3RkOjpzdHJpbmcqICRjbGFzc25hbWUkOjokcmVsZWFzZV9uYW1lJCgpIHtcbiIKKyAgICAgICIgIGlmIChoYXNfJG5hbWUkKCkpIHtcbiIKKyAgICAgICIgICAgY2xlYXJfaGFzXyRvbmVvZl9uYW1lJCgpO1xuIgorICAgICAgIiAgICByZXR1cm4gJG9uZW9mX3ByZWZpeCQkbmFtZSRfLlJlbGVhc2VOb0FyZW5hKCRkZWZhdWx0X3ZhcmlhYmxlJCk7XG4iCisgICAgICAiICB9IGVsc2Uge1xuIgorICAgICAgIiAgICByZXR1cm4gTlVMTDtcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICJ9XG4iCisgICAgICAiJGlubGluZSQgdm9pZCAkY2xhc3NuYW1lJDo6c2V0X2FsbG9jYXRlZF8kbmFtZSQoOjpzdGQ6OnN0cmluZyogJG5hbWUkKSB7XG4iCisgICAgICAiICBpZiAoIWhhc18kbmFtZSQoKSkge1xuIgorICAgICAgIiAgICAkb25lb2ZfcHJlZml4JCRuYW1lJF8uVW5zYWZlU2V0RGVmYXVsdCgkZGVmYXVsdF92YXJpYWJsZSQpO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIiAgY2xlYXJfJG9uZW9mX25hbWUkKCk7XG4iCisgICAgICAiICBpZiAoJG5hbWUkICE9IE5VTEwpIHtcbiIKKyAgICAgICIgICAgc2V0X2hhc18kbmFtZSQoKTtcbiIKKyAgICAgICIgICAgJG9uZW9mX3ByZWZpeCQkbmFtZSRfLlNldEFsbG9jYXRlZE5vQXJlbmEoJGRlZmF1bHRfdmFyaWFibGUkLFxuIgorICAgICAgIiAgICAgICAgJG5hbWUkKTtcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOiRmdWxsX25hbWUkKVxuIgorICAgICAgIn1cbiIpOworICB9Cit9CisKK3ZvaWQgU3RyaW5nT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUNsZWFyaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlcyh2YXJpYWJsZXNfKTsKKyAgaWYgKGRlcGVuZGVudF9maWVsZF8pIHsKKyAgICB2YXJpYWJsZXNbInRoaXNfbWVzc2FnZSJdID0gRGVwZW5kZW50QmFzZURvd25DYXN0KCk7CisgICAgLy8gVGhpcyBjbGVhcmluZyBjb2RlIG1heSBiZSBpbiB0aGUgZGVwZW5kZW50IGJhc2UgY2xhc3MuIElmIHRoZSBkZWZhdWx0CisgICAgLy8gdmFsdWUgaXMgYW4gZW1wdHkgc3RyaW5nLCB0aGVuIHRoZSAkZGVmYXVsdF92YXJpYWJsZSQgaXMgYSBnbG9iYWwKKyAgICAvLyBzaW5nbGV0b24uIElmIHRoZSBkZWZhdWx0IGlzIG5vdCBlbXB0eSwgd2UgbmVlZCB0byBkb3duLWNhc3QgdG8gZ2V0IHRoZQorICAgIC8vIGRlZmF1bHQgdmFsdWUncyBnbG9iYWwgc2luZ2xldG9uIGluc3RhbmNlLiBTZWUgU2V0U3RyaW5nVmFyaWFibGVzKCkgZm9yCisgICAgLy8gcG9zc2libGUgdmFsdWVzIG9mIGRlZmF1bHRfdmFyaWFibGUuCisgICAgaWYgKCFkZXNjcmlwdG9yXy0+ZGVmYXVsdF92YWx1ZV9zdHJpbmcoKS5lbXB0eSgpKSB7CisgICAgICB2YXJpYWJsZXNbImRlZmF1bHRfdmFyaWFibGUiXSA9CisgICAgICAgICAgRGVwZW5kZW50QmFzZURvd25DYXN0KCkgKyB2YXJpYWJsZXNbImRlZmF1bHRfdmFyaWFibGUiXTsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgdmFyaWFibGVzWyJ0aGlzX21lc3NhZ2UiXSA9ICIiOworICB9CisgIGlmIChTdXBwb3J0c0FyZW5hcyhkZXNjcmlwdG9yXykpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXMsCisgICAgICAiJHRoaXNfbWVzc2FnZSQkb25lb2ZfcHJlZml4JCRuYW1lJF8uRGVzdHJveSgkZGVmYXVsdF92YXJpYWJsZSQsXG4iCisgICAgICAiICAgICR0aGlzX21lc3NhZ2UkR2V0QXJlbmFOb1ZpcnR1YWwoKSk7XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXMsCisgICAgICAiJHRoaXNfbWVzc2FnZSQkb25lb2ZfcHJlZml4JCRuYW1lJF8uIgorICAgICAgIkRlc3Ryb3lOb0FyZW5hKCRkZWZhdWx0X3ZhcmlhYmxlJCk7XG4iKTsKKyAgfQorfQorCit2b2lkIFN0cmluZ09uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTd2FwcGluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gRG9uJ3QgcHJpbnQgYW55IHN3YXBwaW5nIGNvZGUuIFN3YXBwaW5nIHRoZSB1bmlvbiB3aWxsIHN3YXAgdGhpcyBmaWVsZC4KK30KKwordm9pZCBTdHJpbmdPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQ29uc3RydWN0b3JDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiAgJGNsYXNzbmFtZSRfZGVmYXVsdF9vbmVvZl9pbnN0YW5jZV8tPiRuYW1lJF8uVW5zYWZlU2V0RGVmYXVsdCgiCisgICAgIiRkZWZhdWx0X3ZhcmlhYmxlJCk7XG4iKTsKK30KKwordm9pZCBTdHJpbmdPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlRGVzdHJ1Y3RvckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKFN1cHBvcnRzQXJlbmFzKGRlc2NyaXB0b3JfKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaWYgKGhhc18kbmFtZSQoKSkge1xuIgorICAgICAgIiAgJG9uZW9mX3ByZWZpeCQkbmFtZSRfLkRlc3Ryb3koJGRlZmF1bHRfdmFyaWFibGUkLFxuIgorICAgICAgIiAgICAgIEdldEFyZW5hTm9WaXJ0dWFsKCkpO1xuIgorICAgICAgIn1cbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaWYgKGhhc18kbmFtZSQoKSkge1xuIgorICAgICAgIiAgJG9uZW9mX3ByZWZpeCQkbmFtZSRfLkRlc3Ryb3lOb0FyZW5hKCRkZWZhdWx0X3ZhcmlhYmxlJCk7XG4iCisgICAgICAifVxuIik7CisgIH0KK30KKwordm9pZCBTdHJpbmdPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2VGcm9tQ29kZWRTdHJlYW0oaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIkRPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZCRkZWNsYXJlZF90eXBlJChcbiIKKyAgICAgICIgICAgICBpbnB1dCwgdGhpcy0+bXV0YWJsZV8kbmFtZSQoKSkpO1xuIik7CisKKyAgaWYgKGRlc2NyaXB0b3JfLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX1NUUklORykgeworICAgIEdlbmVyYXRlVXRmOENoZWNrQ29kZUZvclN0cmluZygKKyAgICAgICAgZGVzY3JpcHRvcl8sIHRydWUsIHZhcmlhYmxlc18sCisgICAgICAgICJ0aGlzLT4kbmFtZSQoKS5kYXRhKCksIHRoaXMtPiRuYW1lJCgpLmxlbmd0aCgpLFxuIiwgcHJpbnRlcik7CisgIH0KK30KKworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK1JlcGVhdGVkU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorUmVwZWF0ZWRTdHJpbmdGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE9wdGlvbnMmIG9wdGlvbnMpCisgICAgOiBkZXNjcmlwdG9yXyhkZXNjcmlwdG9yKSB7CisgIFNldFN0cmluZ1ZhcmlhYmxlcyhkZXNjcmlwdG9yLCAmdmFyaWFibGVzXywgb3B0aW9ucyk7Cit9CisKK1JlcGVhdGVkU3RyaW5nRmllbGRHZW5lcmF0b3I6On5SZXBlYXRlZFN0cmluZ0ZpZWxkR2VuZXJhdG9yKCkge30KKwordm9pZCBSZXBlYXRlZFN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlUHJpdmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6OnN0ZDo6c3RyaW5nPiAkbmFtZSRfO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRTdHJpbmdGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUFjY2Vzc29yRGVjbGFyYXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIFNlZSBjb21tZW50IGFib3ZlIGFib3V0IHVua25vd24gY3R5cGVzLgorICBib29sIHVua25vd25fY3R5cGUgPQorICAgICAgZGVzY3JpcHRvcl8tPm9wdGlvbnMoKS5jdHlwZSgpICE9IEVmZmVjdGl2ZVN0cmluZ0NUeXBlKGRlc2NyaXB0b3JfKTsKKworICBpZiAodW5rbm93bl9jdHlwZSkgeworICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICIgcHJpdmF0ZTpcbiIKKyAgICAgICIgIC8vIEhpZGRlbiBkdWUgdG8gdW5rbm93biBjdHlwZSBvcHRpb24uXG4iKTsKKyAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImNvbnN0IDo6c3RkOjpzdHJpbmcmICRuYW1lJChpbnQgaW5kZXgpIGNvbnN0JGRlcHJlY2F0aW9uJDtcbiIKKyAgICAiOjpzdGQ6OnN0cmluZyogbXV0YWJsZV8kbmFtZSQoaW50IGluZGV4KSRkZXByZWNhdGlvbiQ7XG4iCisgICAgInZvaWQgc2V0XyRuYW1lJChpbnQgaW5kZXgsIGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSRkZXByZWNhdGlvbiQ7XG4iCisgICAgInZvaWQgc2V0XyRuYW1lJChpbnQgaW5kZXgsIGNvbnN0IGNoYXIqIHZhbHVlKSRkZXByZWNhdGlvbiQ7XG4iCisgICAgIiIKKyAgICAidm9pZCBzZXRfJG5hbWUkKGludCBpbmRleCwgY29uc3QgJHBvaW50ZXJfdHlwZSQqIHZhbHVlLCBzaXplX3Qgc2l6ZSkiCisgICAgICAgICAgICAgICAgICIkZGVwcmVjYXRpb24kO1xuIgorICAgICI6OnN0ZDo6c3RyaW5nKiBhZGRfJG5hbWUkKCkkZGVwcmVjYXRpb24kO1xuIgorICAgICJ2b2lkIGFkZF8kbmFtZSQoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpJGRlcHJlY2F0aW9uJDtcbiIKKyAgICAidm9pZCBhZGRfJG5hbWUkKGNvbnN0IGNoYXIqIHZhbHVlKSRkZXByZWNhdGlvbiQ7XG4iCisgICAgInZvaWQgYWRkXyRuYW1lJChjb25zdCAkcG9pbnRlcl90eXBlJCogdmFsdWUsIHNpemVfdCBzaXplKSIKKyAgICAgICAgICAgICAgICAgIiRkZXByZWNhdGlvbiQ7XG4iKTsKKworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6c3RkOjpzdHJpbmc+JiAkbmFtZSQoKSBjb25zdCIKKyAgICAgICAgICAgICAgICAgIiRkZXByZWNhdGlvbiQ7XG4iCisgICAgIjo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpzdGQ6OnN0cmluZz4qIG11dGFibGVfJG5hbWUkKCkiCisgICAgICAgICAgICAgICAgICIkZGVwcmVjYXRpb24kO1xuIik7CisKKyAgaWYgKHVua25vd25fY3R5cGUpIHsKKyAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgcHJpbnRlci0+UHJpbnQoIiBwdWJsaWM6XG4iKTsKKyAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgfQorfQorCit2b2lkIFJlcGVhdGVkU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVJbmxpbmVBY2Nlc3NvckRlZmluaXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaXNfaW5saW5lKSBjb25zdCB7CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyaWFibGVzKHZhcmlhYmxlc18pOworICB2YXJpYWJsZXNbImlubGluZSJdID0gaXNfaW5saW5lID8gImlubGluZSIgOiAiIjsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICIkaW5saW5lJCBjb25zdCA6OnN0ZDo6c3RyaW5nJiAkY2xhc3NuYW1lJDo6JG5hbWUkKGludCBpbmRleCkgY29uc3Qge1xuIgorICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6JGZ1bGxfbmFtZSQpXG4iCisgICAgIiAgcmV0dXJuICRuYW1lJF8uJGNwcGdldCQoaW5kZXgpO1xuIgorICAgICJ9XG4iCisgICAgIiRpbmxpbmUkIDo6c3RkOjpzdHJpbmcqICRjbGFzc25hbWUkOjptdXRhYmxlXyRuYW1lJChpbnQgaW5kZXgpIHtcbiIKKyAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTokZnVsbF9uYW1lJClcbiIKKyAgICAiICByZXR1cm4gJG5hbWUkXy5NdXRhYmxlKGluZGV4KTtcbiIKKyAgICAifVxuIgorICAgICIkaW5saW5lJCB2b2lkICRjbGFzc25hbWUkOjpzZXRfJG5hbWUkKGludCBpbmRleCwgY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHtcbiIKKyAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0OiRmdWxsX25hbWUkKVxuIgorICAgICIgICRuYW1lJF8uTXV0YWJsZShpbmRleCktPmFzc2lnbih2YWx1ZSk7XG4iCisgICAgIn1cbiIKKyAgICAiJGlubGluZSQgdm9pZCAkY2xhc3NuYW1lJDo6c2V0XyRuYW1lJChpbnQgaW5kZXgsIGNvbnN0IGNoYXIqIHZhbHVlKSB7XG4iCisgICAgIiAgJG5hbWUkXy5NdXRhYmxlKGluZGV4KS0+YXNzaWduKHZhbHVlKTtcbiIKKyAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6JGZ1bGxfbmFtZSQpXG4iCisgICAgIn1cbiIKKyAgICAiJGlubGluZSQgdm9pZCAiCisgICAgIiRjbGFzc25hbWUkOjpzZXRfJG5hbWUkIgorICAgICIoaW50IGluZGV4LCBjb25zdCAkcG9pbnRlcl90eXBlJCogdmFsdWUsIHNpemVfdCBzaXplKSB7XG4iCisgICAgIiAgJG5hbWUkXy5NdXRhYmxlKGluZGV4KS0+YXNzaWduKFxuIgorICAgICIgICAgcmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKTtcbiIKKyAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6JGZ1bGxfbmFtZSQpXG4iCisgICAgIn1cbiIKKyAgICAiJGlubGluZSQgOjpzdGQ6OnN0cmluZyogJGNsYXNzbmFtZSQ6OmFkZF8kbmFtZSQoKSB7XG4iCisgICAgIiAgcmV0dXJuICRuYW1lJF8uQWRkKCk7XG4iCisgICAgIn1cbiIKKyAgICAiJGlubGluZSQgdm9pZCAkY2xhc3NuYW1lJDo6YWRkXyRuYW1lJChjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkge1xuIgorICAgICIgICRuYW1lJF8uQWRkKCktPmFzc2lnbih2YWx1ZSk7XG4iCisgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDokZnVsbF9uYW1lJClcbiIKKyAgICAifVxuIgorICAgICIkaW5saW5lJCB2b2lkICRjbGFzc25hbWUkOjphZGRfJG5hbWUkKGNvbnN0IGNoYXIqIHZhbHVlKSB7XG4iCisgICAgIiAgJG5hbWUkXy5BZGQoKS0+YXNzaWduKHZhbHVlKTtcbiIKKyAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkX2NoYXI6JGZ1bGxfbmFtZSQpXG4iCisgICAgIn1cbiIKKyAgICAiJGlubGluZSQgdm9pZCAiCisgICAgIiRjbGFzc25hbWUkOjphZGRfJG5hbWUkKGNvbnN0ICRwb2ludGVyX3R5cGUkKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHtcbiIKKyAgICAiICAkbmFtZSRfLkFkZCgpLT5hc3NpZ24ocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKTtcbiIKKyAgICAiICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkX3BvaW50ZXI6JGZ1bGxfbmFtZSQpXG4iCisgICAgIn1cbiIpOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXMsCisgICAgIiRpbmxpbmUkIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpzdGQ6OnN0cmluZz4mXG4iCisgICAgIiRjbGFzc25hbWUkOjokbmFtZSQoKSBjb25zdCB7XG4iCisgICAgIiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6JGZ1bGxfbmFtZSQpXG4iCisgICAgIiAgcmV0dXJuICRuYW1lJF87XG4iCisgICAgIn1cbiIKKyAgICAiJGlubGluZSQgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6OnN0ZDo6c3RyaW5nPipcbiIKKyAgICAiJGNsYXNzbmFtZSQ6Om11dGFibGVfJG5hbWUkKCkge1xuIgorICAgICIgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6JGZ1bGxfbmFtZSQpXG4iCisgICAgIiAgcmV0dXJuICYkbmFtZSRfO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZFN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQ2xlYXJpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sICIkbmFtZSRfLkNsZWFyKCk7XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZFN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgIiRuYW1lJF8uTWVyZ2VGcm9tKGZyb20uJG5hbWUkXyk7XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZFN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU3dhcHBpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sICIkbmFtZSRfLlVuc2FmZUFyZW5hU3dhcCgmb3RoZXItPiRuYW1lJF8pO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRTdHJpbmdGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUNvbnN0cnVjdG9yQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBOb3QgbmVlZGVkIGZvciByZXBlYXRlZCBmaWVsZHMuCit9CisKK3ZvaWQgUmVwZWF0ZWRTdHJpbmdGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lcmdlRnJvbUNvZGVkU3RyZWFtKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIkRPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZCRkZWNsYXJlZF90eXBlJChcbiIKKyAgICAiICAgICAgaW5wdXQsIHRoaXMtPmFkZF8kbmFtZSQoKSkpO1xuIik7CisgIGlmIChkZXNjcmlwdG9yXy0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TVFJJTkcpIHsKKyAgICBHZW5lcmF0ZVV0ZjhDaGVja0NvZGVGb3JTdHJpbmcoCisgICAgICAgIGRlc2NyaXB0b3JfLCB0cnVlLCB2YXJpYWJsZXNfLAorICAgICAgICAidGhpcy0+JG5hbWUkKHRoaXMtPiRuYW1lJF9zaXplKCkgLSAxKS5kYXRhKCksXG4iCisgICAgICAgICJ0aGlzLT4kbmFtZSQodGhpcy0+JG5hbWUkX3NpemUoKSAtIDEpLmxlbmd0aCgpLFxuIiwKKyAgICAgICAgcHJpbnRlcik7CisgIH0KK30KKwordm9pZCBSZXBlYXRlZFN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+JG5hbWUkX3NpemUoKTsgaSsrKSB7XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisgIGlmIChkZXNjcmlwdG9yXy0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TVFJJTkcpIHsKKyAgICBHZW5lcmF0ZVV0ZjhDaGVja0NvZGVGb3JTdHJpbmcoCisgICAgICAgIGRlc2NyaXB0b3JfLCBmYWxzZSwgdmFyaWFibGVzXywKKyAgICAgICAgInRoaXMtPiRuYW1lJChpKS5kYXRhKCksIHRoaXMtPiRuYW1lJChpKS5sZW5ndGgoKSxcbiIsIHByaW50ZXIpOworICB9CisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGUkZGVjbGFyZWRfdHlwZSQoXG4iCisgICAgIiAgICAkbnVtYmVyJCwgdGhpcy0+JG5hbWUkKGkpLCBvdXRwdXQpO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZFN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPiRuYW1lJF9zaXplKCk7IGkrKykge1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworICBpZiAoZGVzY3JpcHRvcl8tPnR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU1RSSU5HKSB7CisgICAgR2VuZXJhdGVVdGY4Q2hlY2tDb2RlRm9yU3RyaW5nKAorICAgICAgICBkZXNjcmlwdG9yXywgZmFsc2UsIHZhcmlhYmxlc18sCisgICAgICAgICJ0aGlzLT4kbmFtZSQoaSkuZGF0YSgpLCB0aGlzLT4kbmFtZSQoaSkubGVuZ3RoKCksXG4iLCBwcmludGVyKTsKKyAgfQorICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlxuIgorICAgICIgICAgV3JpdGUkZGVjbGFyZWRfdHlwZSRUb0FycmF5KCRudW1iZXIkLCB0aGlzLT4kbmFtZSQoaSksIHRhcmdldCk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIFJlcGVhdGVkU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVCeXRlU2l6ZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJ0b3RhbF9zaXplICs9ICR0YWdfc2l6ZSQgKiB0aGlzLT4kbmFtZSRfc2l6ZSgpO1xuIgorICAgICJmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPiRuYW1lJF9zaXplKCk7IGkrKykge1xuIgorICAgICIgIHRvdGFsX3NpemUgKz0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OiRkZWNsYXJlZF90eXBlJFNpemUoXG4iCisgICAgIiAgICB0aGlzLT4kbmFtZSQoaSkpO1xuIgorICAgICJ9XG4iKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGNwcAorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9zdHJpbmdfZmllbGQuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9zdHJpbmdfZmllbGQuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42MTZlMjA2Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX3N0cmluZ19maWVsZC5oCkBAIC0wLDAgKzEsMTMyIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NQUF9TVFJJTkdfRklFTERfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DUFBfU1RSSU5HX0ZJRUxEX0hfXworCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9maWVsZC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGNwcCB7CisKK2NsYXNzIFN0cmluZ0ZpZWxkR2VuZXJhdG9yIDogcHVibGljIEZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IFN0cmluZ0ZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT3B0aW9ucyYgb3B0aW9ucyk7CisgIH5TdHJpbmdGaWVsZEdlbmVyYXRvcigpOworCisgIC8vIGltcGxlbWVudHMgRmllbGRHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIHZvaWQgR2VuZXJhdGVQcml2YXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTdGF0aWNNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUFjY2Vzc29yRGVjbGFyYXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUlubGluZUFjY2Vzc29yRGVmaW5pdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaXNfaW5saW5lKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU5vbklubGluZUFjY2Vzc29yRGVmaW5pdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQ2xlYXJpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVN3YXBwaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVDb25zdHJ1Y3RvckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRGVzdHJ1Y3RvckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRGVmYXVsdEluc3RhbmNlQWxsb2NhdG9yKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNodXRkb3duQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnZUZyb21Db2RlZFN0cmVhbShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCeXRlU2l6ZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyBwcm90ZWN0ZWQ6CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcl87CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyaWFibGVzXzsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhTdHJpbmdGaWVsZEdlbmVyYXRvcik7Cit9OworCitjbGFzcyBTdHJpbmdPbmVvZkZpZWxkR2VuZXJhdG9yIDogcHVibGljIFN0cmluZ0ZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IFN0cmluZ09uZW9mRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE9wdGlvbnMmIG9wdGlvbnMpOworICB+U3RyaW5nT25lb2ZGaWVsZEdlbmVyYXRvcigpOworCisgIC8vIGltcGxlbWVudHMgRmllbGRHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIHZvaWQgR2VuZXJhdGVJbmxpbmVBY2Nlc3NvckRlZmluaXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGlzX2lubGluZSkgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVDbGVhcmluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU3dhcHBpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUNvbnN0cnVjdG9yQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVEZXN0cnVjdG9yQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnZUZyb21Db2RlZFN0cmVhbShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyBwcml2YXRlOgorICBjb25zdCBib29sIGRlcGVuZGVudF9maWVsZF87CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhTdHJpbmdPbmVvZkZpZWxkR2VuZXJhdG9yKTsKK307CisKK2NsYXNzIFJlcGVhdGVkU3RyaW5nRmllbGRHZW5lcmF0b3IgOiBwdWJsaWMgRmllbGRHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgUmVwZWF0ZWRTdHJpbmdGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT3B0aW9ucyYgb3B0aW9ucyk7CisgIH5SZXBlYXRlZFN0cmluZ0ZpZWxkR2VuZXJhdG9yKCk7CisKKyAgLy8gaW1wbGVtZW50cyBGaWVsZEdlbmVyYXRvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgdm9pZCBHZW5lcmF0ZVByaXZhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUFjY2Vzc29yRGVjbGFyYXRpb25zKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUlubGluZUFjY2Vzc29yRGVmaW5pdGlvbnMoaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaXNfaW5saW5lKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUNsZWFyaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTd2FwcGluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQ29uc3RydWN0b3JDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU1lcmdlRnJvbUNvZGVkU3RyZWFtKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUJ5dGVTaXplKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKworIHByaXZhdGU6CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcl87CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyaWFibGVzXzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoUmVwZWF0ZWRTdHJpbmdGaWVsZEdlbmVyYXRvcik7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgY3BwCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DUFBfU1RSSU5HX0ZJRUxEX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX3Rlc3RfYmFkX2lkZW50aWZpZXJzLnByb3RvIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX3Rlc3RfYmFkX2lkZW50aWZpZXJzLnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRlMjViMmUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfdGVzdF9iYWRfaWRlbnRpZmllcnMucHJvdG8KQEAgLTAsMCArMSwxNTYgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBUaGlzIGZpbGUgdGVzdHMgdGhhdCB2YXJpb3VzIGlkZW50aWZpZXJzIHdvcmsgYXMgZmllbGQgYW5kIHR5cGUgbmFtZXMgZXZlbgorLy8gdGhvdWdoIHRoZSBzYW1lIGlkZW50aWZpZXJzIGFyZSB1c2VkIGludGVybmFsbHkgYnkgdGhlIEMrKyBjb2RlIGdlbmVyYXRvci4KKworc3ludGF4ID0gInByb3RvMiI7CisKKy8vIFNvbWUgZ2VuZXJpY19zZXJ2aWNlcyBvcHRpb24ocykgYWRkZWQgYXV0b21hdGljYWxseS4KKy8vIFNlZTogIGh0dHA6Ly9nby9wcm90bzItZ2VuZXJpYy1zZXJ2aWNlcy1kZWZhdWx0CitvcHRpb24gY2NfZ2VuZXJpY19zZXJ2aWNlcyA9IHRydWU7ICAgICAvLyBhdXRvLWFkZGVkCisKKy8vIFdlIGRvbid0IHB1dCB0aGlzIGluIGEgcGFja2FnZSB3aXRoaW4gcHJvdG8yIGJlY2F1c2Ugd2UgbmVlZCB0byBtYWtlIHN1cmUKKy8vIHRoYXQgdGhlIGdlbmVyYXRlZCBjb2RlIGRvZXNuJ3QgZGVwZW5kIG9uIGJlaW5nIGluIHRoZSBwcm90bzIgbmFtZXNwYWNlLgorcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdDsKKworLy8gVGVzdCB0aGF0IGZpZWxkcyBjYW4gaGF2ZSBuYW1lcyBsaWtlICJpbnB1dCIgYW5kICJpIiB3aGljaCBhcmUgYWxzbyB1c2VkCisvLyBpbnRlcm5hbGx5IGJ5IHRoZSBjb2RlIGdlbmVyYXRvciBmb3IgbG9jYWwgdmFyaWFibGVzLgorbWVzc2FnZSBUZXN0Q29uZmxpY3RpbmdTeW1ib2xOYW1lcyB7CisgIG1lc3NhZ2UgQnVpbGREZXNjcmlwdG9ycyB7fQorICBtZXNzYWdlIFR5cGVUcmFpdHMge30KKworICBvcHRpb25hbCBpbnQzMiBpbnB1dCA9IDE7CisgIG9wdGlvbmFsIGludDMyIG91dHB1dCA9IDI7CisgIG9wdGlvbmFsIHN0cmluZyBsZW5ndGggPSAzOworICByZXBlYXRlZCBpbnQzMiBpID0gNDsKKyAgcmVwZWF0ZWQgc3RyaW5nIG5ld19lbGVtZW50ID0gNSBbY3R5cGU9U1RSSU5HX1BJRUNFXTsKKyAgb3B0aW9uYWwgaW50MzIgdG90YWxfc2l6ZSA9IDY7CisgIG9wdGlvbmFsIGludDMyIHRhZyA9IDc7CisKKyAgZW51bSBUZXN0RW51bSB7IEZPTyA9IDA7IH0KKyAgbWVzc2FnZSBEYXRhMSB7IHJlcGVhdGVkIGludDMyIGRhdGEgPSAxOyB9CisgIG1lc3NhZ2UgRGF0YTIgeyByZXBlYXRlZCBUZXN0RW51bSBkYXRhID0gMTsgfQorICBtZXNzYWdlIERhdGEzIHsgcmVwZWF0ZWQgc3RyaW5nIGRhdGEgPSAxOyB9CisgIG1lc3NhZ2UgRGF0YTQgeyByZXBlYXRlZCBEYXRhNCBkYXRhID0gMTsgfQorICBtZXNzYWdlIERhdGE1IHsgcmVwZWF0ZWQgc3RyaW5nIGRhdGEgPSAxIFtjdHlwZT1TVFJJTkdfUElFQ0VdOyB9CisgIG1lc3NhZ2UgRGF0YTYgeyByZXBlYXRlZCBzdHJpbmcgZGF0YSA9IDEgW2N0eXBlPUNPUkRdOyB9CisKKyAgb3B0aW9uYWwgaW50MzIgc291cmNlID0gODsKKyAgb3B0aW9uYWwgaW50MzIgdmFsdWUgPSA5OworICBvcHRpb25hbCBpbnQzMiBmaWxlID0gMTA7CisgIG9wdGlvbmFsIGludDMyIGZyb20gPSAxMTsKKyAgb3B0aW9uYWwgaW50MzIgaGFuZGxlX3VuaW50ZXJwcmV0ZWQgPSAxMjsKKyAgcmVwZWF0ZWQgaW50MzIgaW5kZXggPSAxMzsKKyAgb3B0aW9uYWwgaW50MzIgY29udHJvbGxlciA9IDE0OworICBvcHRpb25hbCBpbnQzMiBhbHJlYWR5X2hlcmUgPSAxNTsKKworICBvcHRpb25hbCB1aW50MzIgdWludDMyID0gMTY7CisgIG9wdGlvbmFsIHVpbnQ2NCB1aW50NjQgPSAxNzsKKyAgb3B0aW9uYWwgc3RyaW5nIHN0cmluZyA9IDE4OworICBvcHRpb25hbCBpbnQzMiBtZW1zZXQgPSAxOTsKKyAgb3B0aW9uYWwgaW50MzIgaW50MzIgPSAyMDsKKyAgb3B0aW9uYWwgaW50NjQgaW50NjQgPSAyMTsKKworICBvcHRpb25hbCB1aW50MzIgY2FjaGVkX3NpemUgPSAyMjsKKyAgb3B0aW9uYWwgdWludDMyIGV4dGVuc2lvbnMgPSAyMzsKKyAgb3B0aW9uYWwgdWludDMyIGJpdCA9IDI0OworICBvcHRpb25hbCB1aW50MzIgYml0cyA9IDI1OworICBvcHRpb25hbCB1aW50MzIgb2Zmc2V0cyA9IDI2OworICBvcHRpb25hbCB1aW50MzIgcmVmbGVjdGlvbiA9IDI3OworCisgIG1lc3NhZ2UgQ29yZCB7fQorICBvcHRpb25hbCBzdHJpbmcgc29tZV9jb3JkID0gMjggW2N0eXBlPUNPUkRdOworCisgIG1lc3NhZ2UgU3RyaW5nUGllY2Uge30KKyAgb3B0aW9uYWwgc3RyaW5nIHNvbWVfc3RyaW5nX3BpZWNlID0gMjkgW2N0eXBlPVNUUklOR19QSUVDRV07CisKKyAgLy8gU29tZSBrZXl3b3Jkcy4KKyAgb3B0aW9uYWwgdWludDMyIGludCA9IDMwOworICBvcHRpb25hbCB1aW50MzIgZnJpZW5kID0gMzE7CisgIG9wdGlvbmFsIHVpbnQzMiBjbGFzcyA9IDM3OworICBvcHRpb25hbCB1aW50MzIgdHlwZWRlY2wgPSAzOTsKKyAgb3B0aW9uYWwgdWludDMyIGF1dG8gPSA0MDsKKworICAvLyBUaGUgZ2VuZXJhdG9yIHVzZWQgdG8gI2RlZmluZSBhIG1hY3JvIGNhbGxlZCAiRE8iIGluc2lkZSB0aGUgLmNjIGZpbGUuCisgIG1lc3NhZ2UgRE8ge30KKyAgb3B0aW9uYWwgRE8gZG8gPSAzMjsKKworICAvLyBTb21lIHRlbXBsYXRlIHBhcmFtZXRlciBuYW1lcyBmb3IgZXh0ZW5zaW9ucy4KKyAgb3B0aW9uYWwgaW50MzIgZmllbGRfdHlwZSA9IDMzOworICBvcHRpb25hbCBib29sIGlzX3BhY2tlZCA9IDM0OworCisgIC8vIHRlc3QgY29uZmxpY3RpbmcgcmVsZWFzZV8kbmFtZSQuICJsZW5ndGgiIGFuZCAiZG8iIGZpZWxkIGluIHRoaXMgbWVzc2FnZQorICAvLyBtdXN0IHJlbWFpbiBzdHJpbmcgb3IgbWVzc2FnZSBmaWVsZHMgdG8gbWFrZSB0aGUgdGVzdCB2YWxpZC4KKyAgb3B0aW9uYWwgc3RyaW5nIHJlbGVhc2VfbGVuZ3RoID0gMzU7CisgIC8vIEEgbW9yZSBleHRyZW1lIGNhc2UsIHRoZSBmaWVsZCBuYW1lICJkbyIgaGVyZSBpcyBhIGtleXdvcmQsIHdoaWNoIHdpbGwgYmUKKyAgLy8gZXNjYXBlZCB0byAiZG9fIiBhbHJlYWR5LiBUZXN0IHRoZXJlIGlzIG5vIGNvbmZsaWN0IGV2ZW4gd2l0aCBlc2NhcGVkIGZpZWxkCisgIC8vIG5hbWVzLgorICBvcHRpb25hbCBETyByZWxlYXNlX2RvID0gMzY7CisKKyAgLy8gRm9yIGNsYXNoaW5nIGxvY2FsIHZhcmlhYmxlcyBpbiBTZXJpYWxpemUgYW5kIEJ5dGVTaXplIGNhbGN1bGF0aW9uLgorICBvcHRpb25hbCBzdHJpbmcgdGFyZ2V0ID0gMzg7CisKKyAgZXh0ZW5zaW9ucyAxMDAwIHRvIG1heDsgIC8vIE5PX1BST1RPMworfQorCittZXNzYWdlIFRlc3RDb25mbGljdGluZ1N5bWJvbE5hbWVzRXh0ZW5zaW9uIHsgICAgICAgICAgICAgICAgICAgIC8vIE5PX1BST1RPMworICBleHRlbmQgVGVzdENvbmZsaWN0aW5nU3ltYm9sTmFtZXMgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBOT19QUk9UTzMKKyAgICByZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMl9leHQgPSAyMDQyMzYzOCBbcGFja2VkPXRydWVdOyAgLy8gTk9fUFJPVE8zCisgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5PX1BST1RPMworfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBOT19QUk9UTzMKKworbWVzc2FnZSBUZXN0Q29uZmxpY3RpbmdFbnVtTmFtZXMgeyAgLy8gTk9fUFJPVE8zCisgIGVudW0gTmVzdGVkQ29uZmxpY3RpbmdFbnVtIHsgICAgICAvLyBOT19QUk9UTzMKKyAgICBhbmQgPSAxOyAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5PX1BST1RPMworICAgIGNsYXNzID0gMjsgICAgICAgICAgICAgICAgICAgICAgLy8gTk9fUFJPVE8zCisgICAgaW50ID0gMzsgICAgICAgICAgICAgICAgICAgICAgICAvLyBOT19QUk9UTzMKKyAgICB0eXBlZGVmID0gNDsgICAgICAgICAgICAgICAgICAgIC8vIE5PX1BST1RPMworICAgIFhPUiA9IDU7ICAgICAgICAgICAgICAgICAgICAgICAgLy8gTk9fUFJPVE8zCisgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBOT19QUk9UTzMKKworICBvcHRpb25hbCBOZXN0ZWRDb25mbGljdGluZ0VudW0gY29uZmxpY3RpbmdfZW51bSA9IDE7ICAvLyBOT19QUk9UTzMKK30gIC8vIE5PX1BST1RPMworCitlbnVtIENvbmZsaWN0aW5nRW51bSB7ICAvLyBOT19QUk9UTzMKKyAgTk9UX0VRID0gMTsgICAgICAgICAgIC8vIE5PX1BST1RPMworICB2b2xhdGlsZSA9IDI7ICAgICAgICAgLy8gTk9fUFJPVE8zCisgIHJldHVybiA9IDM7ICAgICAgICAgICAvLyBOT19QUk9UTzMKK30gIC8vIE5PX1BST1RPMworCittZXNzYWdlIER1bW15TWVzc2FnZSB7fQorCitzZXJ2aWNlIFRlc3RDb25mbGljdGluZ01ldGhvZE5hbWVzIHsKKyAgcnBjIENsb3N1cmUoRHVtbXlNZXNzYWdlKSByZXR1cm5zIChEdW1teU1lc3NhZ2UpOworfQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX3Rlc3RfbGFyZ2VfZW51bV92YWx1ZS5wcm90byBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF90ZXN0X2xhcmdlX2VudW1fdmFsdWUucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2I2Y2ExYgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF90ZXN0X2xhcmdlX2VudW1fdmFsdWUucHJvdG8KQEAgLTAsMCArMSw0MyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIFRlc3QgdGhhdCBwcm90bzIgY29tcGlsZXIgY2FuIGdlbmVyYXRlIHZhbGlkIGNvZGUgd2hlbiB0aGUgZW51bSB2YWx1ZQorLy8gaXMgSU5UX01BWC4gTm90ZSB0aGF0IHRoaXMgaXMgYSBjb21waWxlLW9ubHkgdGVzdCBhbmQgdGhpcyBwcm90byBpcyBub3QKKy8vIHJlZmVyZW5jZWQgaW4gYW55IEMrKyBjb2RlLgorc3ludGF4ID0gInByb3RvMiI7CisKK3BhY2thZ2UgcHJvdG9idWZfdW5pdHRlc3Q7CisKK21lc3NhZ2UgVGVzdExhcmdlRW51bVZhbHVlIHsKKyAgZW51bSBFbnVtV2l0aExhcmdlVmFsdWUgeworICAgIFZBTFVFXzEgPSAxOworICAgIFZBTFVFX01BWCA9IDB4N2ZmZmZmZmY7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF91bml0dGVzdC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF91bml0dGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45OTQyYTM0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX3VuaXR0ZXN0LmNjCkBAIC0wLDAgKzEsMjE0MCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorLy8KKy8vIFRvIHRlc3QgdGhlIGNvZGUgZ2VuZXJhdG9yLCB3ZSBhY3R1YWxseSB1c2UgaXQgdG8gZ2VuZXJhdGUgY29kZSBmb3IKKy8vIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wcm90bywgdGhlbiB0ZXN0IHRoYXQuICBUaGlzIG1lYW5zIHRoYXQgd2UKKy8vIGFyZSBhY3R1YWxseSB0ZXN0aW5nIHRoZSBwYXJzZXIgYW5kIG90aGVyIHBhcnRzIG9mIHRoZSBzeXN0ZW0gYXQgdGhlIHNhbWUKKy8vIHRpbWUsIGFuZCB0aGF0IHByb2JsZW1zIGluIHRoZSBnZW5lcmF0b3IgbWF5IHNob3cgdXAgYXMgY29tcGlsZS10aW1lIGVycm9ycworLy8gcmF0aGVyIHRoYW4gdW5pdHRlc3QgZmFpbHVyZXMsIHdoaWNoIG1heSBiZSBzdXJwcmlzaW5nLiAgSG93ZXZlciwgdGVzdGluZworLy8gdGhlIG91dHB1dCBvZiB0aGUgQysrIGdlbmVyYXRvciBkaXJlY3RseSB3b3VsZCBiZSB2ZXJ5IGhhcmQuICBXZSBjYW4ndCB2ZXJ5CisvLyB3ZWxsIGp1c3QgY2hlY2sgaXQgYWdhaW5zdCBnb2xkZW4gZmlsZXMgc2luY2UgdGhvc2UgZmlsZXMgd291bGQgaGF2ZSB0byBiZQorLy8gdXBkYXRlZCBmb3IgYW55IHNtYWxsIGNoYW5nZTsgc3VjaCBhIHRlc3Qgd291bGQgYmUgdmVyeSBicml0dGxlIGFuZCBwcm9iYWJseQorLy8gbm90IHZlcnkgaGVscGZ1bC4gIFdoYXQgd2UgcmVhbGx5IHdhbnQgdG8gdGVzdCBpcyB0aGF0IHRoZSBjb2RlIGNvbXBpbGVzCisvLyBjb3JyZWN0bHkgYW5kIHByb2R1Y2VzIHRoZSBpbnRlcmZhY2VzIHdlIGV4cGVjdCwgd2hpY2ggaXMgd2h5IHRoaXMgdGVzdAorLy8gaXMgd3JpdHRlbiB0aGlzIHdheS4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX3VuaXR0ZXN0Lmg+CisKKyNpbmNsdWRlIDxtZW1vcnk+CisjaWZuZGVmIF9TSEFSRURfUFRSX0gKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc2hhcmVkX3B0ci5oPgorI2VuZGlmCisjaW5jbHVkZSA8dmVjdG9yPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X29wdGltaXplX2Zvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9lbWJlZF9vcHRpbWl6ZV9mb3IucGIuaD4KKyNpZiAhZGVmaW5lZChHT09HTEVfUFJPVE9CVUZfQ01BS0VfQlVJTEQpICYmICFkZWZpbmVkKF9NU0NfVkVSKQorLy8gV2UgZXhjbHVkZSB0aGlzIGxhcmdlIHByb3RvIGZyb20gY21ha2UgYnVpbGQgYmVjYXVzZSBpdCdzIHRvbyBsYXJnZSBmb3IKKy8vIHZpc3VhbCBzdHVkaW8gdG8gY29tcGlsZSAocmVwb3J0IGludGVybmFsIGVycm9ycykuCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2Vub3Jtb3VzX2Rlc2NyaXB0b3IucGIuaD4KKyNlbmRpZgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9ub19nZW5lcmljX3NlcnZpY2VzLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RfdXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF90ZXN0X2JhZF9pZGVudGlmaWVycy5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9pbXBvcnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbV9pbXBsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9keW5hbWljX21lc3NhZ2UuaD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jYWxsYmFjay5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbG9nZ2luZy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N1YnN0aXR1dGUuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0Lmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RsX3V0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgewordXNpbmcgaW50ZXJuYWw6Ok5ld1Blcm1hbmVudENhbGxiYWNrOworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBjcHAgeworCisvLyBDYW4ndCB1c2UgYW4gYW5vbnltb3VzIG5hbWVzcGFjZSBoZXJlIGR1ZSB0byBicm9rZW5uZXNzIG9mIFRydTY0IGNvbXBpbGVyLgorbmFtZXNwYWNlIGNwcF91bml0dGVzdCB7CisKK25hbWVzcGFjZSBwcm90b2J1Zl91bml0dGVzdCA9IDo6cHJvdG9idWZfdW5pdHRlc3Q7CisKKworY2xhc3MgTW9ja0Vycm9yQ29sbGVjdG9yIDogcHVibGljIE11bHRpRmlsZUVycm9yQ29sbGVjdG9yIHsKKyBwdWJsaWM6CisgIE1vY2tFcnJvckNvbGxlY3RvcigpIHt9CisgIH5Nb2NrRXJyb3JDb2xsZWN0b3IoKSB7fQorCisgIHN0cmluZyB0ZXh0XzsKKworICAvLyBpbXBsZW1lbnRzIEVycm9yQ29sbGVjdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICB2b2lkIEFkZEVycm9yKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUsIGludCBsaW5lLCBpbnQgY29sdW1uLAorICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgbWVzc2FnZSkgeworICAgIHN0cmluZ3M6OlN1YnN0aXR1dGVBbmRBcHBlbmQoJnRleHRfLCAiJDA6JDE6JDI6ICQzXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZW5hbWUsIGxpbmUsIGNvbHVtbiwgbWVzc2FnZSk7CisgIH0KK307CisKKyNpZm5kZWYgUFJPVE9CVUZfVEVTVF9OT19ERVNDUklQVE9SUworCisvLyBUZXN0IHRoYXQgZ2VuZXJhdGVkIGNvZGUgaGFzIHByb3BlciBkZXNjcmlwdG9yczoKKy8vIFBhcnNlIGEgZGVzY3JpcHRvciBkaXJlY3RseSAodXNpbmcgZ29vZ2xlOjpwcm90b2J1Zjo6Y29tcGlsZXI6OkltcG9ydGVyKSBhbmQKKy8vIGNvbXBhcmUgaXQgdG8gdGhlIG9uZSB0aGF0IHdhcyBwcm9kdWNlZCBieSBnZW5lcmF0ZWQgY29kZS4KK1RFU1QoR2VuZXJhdGVkRGVzY3JpcHRvclRlc3QsIElkZW50aWNhbERlc2NyaXB0b3JzKSB7CisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBnZW5lcmF0ZWRfZGVzY3JpcHRvciA9CisgICAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6ZGVzY3JpcHRvcigpLT5maWxlKCk7CisKKyAgLy8gU2V0IHVwIHRoZSBJbXBvcnRlci4KKyAgTW9ja0Vycm9yQ29sbGVjdG9yIGVycm9yX2NvbGxlY3RvcjsKKyAgRGlza1NvdXJjZVRyZWUgc291cmNlX3RyZWU7CisgIHNvdXJjZV90cmVlLk1hcFBhdGgoIiIsIFRlc3RTb3VyY2VEaXIoKSk7CisgIEltcG9ydGVyIGltcG9ydGVyKCZzb3VyY2VfdHJlZSwgJmVycm9yX2NvbGxlY3Rvcik7CisKKyAgLy8gSW1wb3J0IChwYXJzZSkgdW5pdHRlc3QucHJvdG8uCisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBwYXJzZWRfZGVzY3JpcHRvciA9CisgICAgaW1wb3J0ZXIuSW1wb3J0KCJnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucHJvdG8iKTsKKyAgRVhQRUNUX0VRKCIiLCBlcnJvcl9jb2xsZWN0b3IudGV4dF8pOworICBBU1NFUlRfVFJVRShwYXJzZWRfZGVzY3JpcHRvciAhPSBOVUxMKTsKKworICAvLyBUZXN0IHRoYXQgZGVzY3JpcHRvcnMgYXJlIGdlbmVyYXRlZCBjb3JyZWN0bHkgYnkgY29udmVydGluZyB0aGVtIHRvCisgIC8vIEZpbGVEZXNjcmlwdG9yUHJvdG9zIGFuZCBjb21wYXJpbmcuCisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZ2VuZXJhdGVkX2RlY3NyaXB0b3JfcHJvdG8sIHBhcnNlZF9kZXNjcmlwdG9yX3Byb3RvOworICBnZW5lcmF0ZWRfZGVzY3JpcHRvci0+Q29weVRvKCZnZW5lcmF0ZWRfZGVjc3JpcHRvcl9wcm90byk7CisgIHBhcnNlZF9kZXNjcmlwdG9yLT5Db3B5VG8oJnBhcnNlZF9kZXNjcmlwdG9yX3Byb3RvKTsKKworICBFWFBFQ1RfRVEocGFyc2VkX2Rlc2NyaXB0b3JfcHJvdG8uRGVidWdTdHJpbmcoKSwKKyAgICAgICAgICAgIGdlbmVyYXRlZF9kZWNzcmlwdG9yX3Byb3RvLkRlYnVnU3RyaW5nKCkpOworfQorCisjaWYgIWRlZmluZWQoR09PR0xFX1BST1RPQlVGX0NNQUtFX0JVSUxEKSAmJiAhZGVmaW5lZChfTVNDX1ZFUikKKy8vIFRlc3QgdGhhdCBnZW5lcmF0ZWQgY29kZSBoYXMgcHJvcGVyIGRlc2NyaXB0b3JzOgorLy8gVG91Y2ggYSBkZXNjcmlwdG9yIGdlbmVyYXRlZCBmcm9tIGFuIGVub3Jtb3VzIG1lc3NhZ2UgdG8gdmFsaWRhdGUgc3BlY2lhbAorLy8gaGFuZGxpbmcgZm9yIGRlc2NyaXB0b3JzIGV4Y2VlZGluZyB0aGUgQysrIHN0YW5kYXJkJ3MgcmVjb21tZW5kZWQgbWluaW11bQorLy8gbGltaXQgZm9yIHN0cmluZyBsaXRlcmFsIHNpemUKK1RFU1QoR2VuZXJhdGVkRGVzY3JpcHRvclRlc3QsIEVub3Jtb3VzRGVzY3JpcHRvcikgeworICBjb25zdCBEZXNjcmlwdG9yKiBnZW5lcmF0ZWRfZGVzY3JpcHRvciA9CisgICAgVGVzdEVub3Jtb3VzRGVzY3JpcHRvcjo6ZGVzY3JpcHRvcigpOworCisgIEVYUEVDVF9UUlVFKGdlbmVyYXRlZF9kZXNjcmlwdG9yICE9IE5VTEwpOworfQorI2VuZGlmCisKKyNlbmRpZiAgLy8gIVBST1RPQlVGX1RFU1RfTk9fREVTQ1JJUFRPUlMKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VUZXN0LCBEZWZhdWx0cykgeworICAvLyBDaGVjayB0aGF0IGFsbCBkZWZhdWx0IHZhbHVlcyBhcmUgc2V0IGNvcnJlY3RseSBpbiB0aGUgaW5pdGlhbCBtZXNzYWdlLgorICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisKKyAgVGVzdFV0aWw6OkV4cGVjdENsZWFyKG1lc3NhZ2UpOworCisgIC8vIE1lc3NhZ2VzIHNob3VsZCByZXR1cm4gcG9pbnRlcnMgdG8gZGVmYXVsdCBpbnN0YW5jZXMgdW50aWwgZmlyc3QgdXNlLgorICAvLyAoVGhpcyBpcyBub3QgY2hlY2tlZCBieSBFeHBlY3RDbGVhcigpIHNpbmNlIGl0IGlzIG5vdCBhY3R1YWxseSB0cnVlIGFmdGVyCisgIC8vIHRoZSBmaWVsZHMgaGF2ZSBiZWVuIHNldCBhbmQgdGhlbiBjbGVhcmVkLikKKyAgRVhQRUNUX0VRKCZ1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpPcHRpb25hbEdyb3VwOjpkZWZhdWx0X2luc3RhbmNlKCksCisgICAgICAgICAgICAmbWVzc2FnZS5vcHRpb25hbGdyb3VwKCkpOworICBFWFBFQ1RfRVEoJnVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2U6OmRlZmF1bHRfaW5zdGFuY2UoKSwKKyAgICAgICAgICAgICZtZXNzYWdlLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCkpOworICBFWFBFQ1RfRVEoJnVuaXR0ZXN0OjpGb3JlaWduTWVzc2FnZTo6ZGVmYXVsdF9pbnN0YW5jZSgpLAorICAgICAgICAgICAgJm1lc3NhZ2Uub3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlKCkpOworICBFWFBFQ1RfRVEoJnVuaXR0ZXN0X2ltcG9ydDo6SW1wb3J0TWVzc2FnZTo6ZGVmYXVsdF9pbnN0YW5jZSgpLAorICAgICAgICAgICAgJm1lc3NhZ2Uub3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UoKSk7Cit9CisKKyNpZm5kZWYgUFJPVE9CVUZfVVNFX0RMTFMKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVRlc3QsIEludDMyU3RyaW5nQ29udmVyc2lvbikgeworICBFWFBFQ1RfRVEoIjk3MSIsIEludDMyVG9TdHJpbmcoOTcxKSk7CisgIEVYUEVDVF9FUSgiKH4weDdmZmZmZmZmKSIsIEludDMyVG9TdHJpbmcoa2ludDMybWluKSk7CisgIEVYUEVDVF9FUSgiMjE0NzQ4MzY0NyIsIEludDMyVG9TdHJpbmcoa2ludDMybWF4KSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVRlc3QsIEludDY0U3RyaW5nQ29udmVyc2lvbikgeworICBFWFBFQ1RfRVEoIkdPT0dMRV9MT05HTE9ORyg5NzEpIiwgSW50NjRUb1N0cmluZyg5NzEpKTsKKyAgRVhQRUNUX0VRKCJHT09HTEVfTE9OR0xPTkcoLTIxNDc0ODM2NDgpIiwgSW50NjRUb1N0cmluZyhraW50MzJtaW4pKTsKKyAgRVhQRUNUX0VRKCJHT09HTEVfTE9OR0xPTkcofjB4N2ZmZmZmZmZmZmZmZmZmZikiLCBJbnQ2NFRvU3RyaW5nKGtpbnQ2NG1pbikpOworICBFWFBFQ1RfRVEoIkdPT0dMRV9MT05HTE9ORyg5MjIzMzcyMDM2ODU0Nzc1ODA3KSIsIEludDY0VG9TdHJpbmcoa2ludDY0bWF4KSk7Cit9CisjZW5kaWYgIC8vICFQUk9UT0JVRl9VU0VfRExMUworCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VUZXN0LCBGbG9hdGluZ1BvaW50RGVmYXVsdHMpIHsKKyAgY29uc3QgdW5pdHRlc3Q6OlRlc3RFeHRyZW1lRGVmYXVsdFZhbHVlcyYgZXh0cmVtZV9kZWZhdWx0ID0KKyAgICAgIHVuaXR0ZXN0OjpUZXN0RXh0cmVtZURlZmF1bHRWYWx1ZXM6OmRlZmF1bHRfaW5zdGFuY2UoKTsKKworICBFWFBFQ1RfRVEoMC4wZiwgZXh0cmVtZV9kZWZhdWx0Lnplcm9fZmxvYXQoKSk7CisgIEVYUEVDVF9FUSgxLjBmLCBleHRyZW1lX2RlZmF1bHQub25lX2Zsb2F0KCkpOworICBFWFBFQ1RfRVEoMS41ZiwgZXh0cmVtZV9kZWZhdWx0LnNtYWxsX2Zsb2F0KCkpOworICBFWFBFQ1RfRVEoLTEuMGYsIGV4dHJlbWVfZGVmYXVsdC5uZWdhdGl2ZV9vbmVfZmxvYXQoKSk7CisgIEVYUEVDVF9FUSgtMS41ZiwgZXh0cmVtZV9kZWZhdWx0Lm5lZ2F0aXZlX2Zsb2F0KCkpOworICBFWFBFQ1RfRVEoMi4wZThmLCBleHRyZW1lX2RlZmF1bHQubGFyZ2VfZmxvYXQoKSk7CisgIEVYUEVDVF9FUSgtOGUtMjhmLCBleHRyZW1lX2RlZmF1bHQuc21hbGxfbmVnYXRpdmVfZmxvYXQoKSk7CisgIEVYUEVDVF9FUShudW1lcmljX2xpbWl0czxkb3VibGU+OjppbmZpbml0eSgpLAorICAgICAgICAgICAgZXh0cmVtZV9kZWZhdWx0LmluZl9kb3VibGUoKSk7CisgIEVYUEVDVF9FUSgtbnVtZXJpY19saW1pdHM8ZG91YmxlPjo6aW5maW5pdHkoKSwKKyAgICAgICAgICAgIGV4dHJlbWVfZGVmYXVsdC5uZWdfaW5mX2RvdWJsZSgpKTsKKyAgRVhQRUNUX1RSVUUoZXh0cmVtZV9kZWZhdWx0Lm5hbl9kb3VibGUoKSAhPSBleHRyZW1lX2RlZmF1bHQubmFuX2RvdWJsZSgpKTsKKyAgRVhQRUNUX0VRKG51bWVyaWNfbGltaXRzPGZsb2F0Pjo6aW5maW5pdHkoKSwKKyAgICAgICAgICAgIGV4dHJlbWVfZGVmYXVsdC5pbmZfZmxvYXQoKSk7CisgIEVYUEVDVF9FUSgtbnVtZXJpY19saW1pdHM8ZmxvYXQ+OjppbmZpbml0eSgpLAorICAgICAgICAgICAgZXh0cmVtZV9kZWZhdWx0Lm5lZ19pbmZfZmxvYXQoKSk7CisgIEVYUEVDVF9UUlVFKGV4dHJlbWVfZGVmYXVsdC5uYW5fZmxvYXQoKSAhPSBleHRyZW1lX2RlZmF1bHQubmFuX2Zsb2F0KCkpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VUZXN0LCBUcmlncmFwaCkgeworICBjb25zdCB1bml0dGVzdDo6VGVzdEV4dHJlbWVEZWZhdWx0VmFsdWVzJiBleHRyZW1lX2RlZmF1bHQgPQorICAgICAgdW5pdHRlc3Q6OlRlc3RFeHRyZW1lRGVmYXVsdFZhbHVlczo6ZGVmYXVsdF9pbnN0YW5jZSgpOworCisgIEVYUEVDVF9FUSgiPyA/ID8/ID8/ID8/PyA/XD8vID9cPy0iLCBleHRyZW1lX2RlZmF1bHQuY3BwX3RyaWdyYXBoKCkpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VUZXN0LCBFeHRyZW1lU21hbGxJbnRlZ2VyRGVmYXVsdCkgeworICBjb25zdCB1bml0dGVzdDo6VGVzdEV4dHJlbWVEZWZhdWx0VmFsdWVzJiBleHRyZW1lX2RlZmF1bHQgPQorICAgICAgdW5pdHRlc3Q6OlRlc3RFeHRyZW1lRGVmYXVsdFZhbHVlczo6ZGVmYXVsdF9pbnN0YW5jZSgpOworICBFWFBFQ1RfRVEofjB4N2ZmZmZmZmYsIGtpbnQzMm1pbik7CisgIEVYUEVDVF9FUShHT09HTEVfTE9OR0xPTkcofjB4N2ZmZmZmZmZmZmZmZmZmZiksIGtpbnQ2NG1pbik7CisgIEVYUEVDVF9FUShraW50MzJtaW4sIGV4dHJlbWVfZGVmYXVsdC5yZWFsbHlfc21hbGxfaW50MzIoKSk7CisgIEVYUEVDVF9FUShraW50NjRtaW4sIGV4dHJlbWVfZGVmYXVsdC5yZWFsbHlfc21hbGxfaW50NjQoKSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVRlc3QsIEFjY2Vzc29ycykgeworICAvLyBTZXQgZXZlcnkgZmllbGQgdG8gYSB1bmlxdWUgdmFsdWUgdGhlbiBnbyBiYWNrIGFuZCBjaGVjayBhbGwgdGhvc2UKKyAgLy8gdmFsdWVzLgorICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbWVzc2FnZSk7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxGaWVsZHNTZXQobWVzc2FnZSk7CisKKyAgVGVzdFV0aWw6Ok1vZGlmeVJlcGVhdGVkRmllbGRzKCZtZXNzYWdlKTsKKyAgVGVzdFV0aWw6OkV4cGVjdFJlcGVhdGVkRmllbGRzTW9kaWZpZWQobWVzc2FnZSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVRlc3QsIE11dGFibGVTdHJpbmdEZWZhdWx0KSB7CisgIC8vIG11dGFibGVfZm9vKCkgZm9yIGEgc3RyaW5nIHNob3VsZCByZXR1cm4gYSBzdHJpbmcgaW5pdGlhbGl6ZWQgdG8gaXRzCisgIC8vIGRlZmF1bHQgdmFsdWUuCisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKworICBFWFBFQ1RfRVEoImhlbGxvIiwgKm1lc3NhZ2UubXV0YWJsZV9kZWZhdWx0X3N0cmluZygpKTsKKworICAvLyBOb3RlIHRoYXQgdGhlIGZpcnN0IHRpbWUgd2UgY2FsbCBtdXRhYmxlX2ZvbygpLCB3ZSBnZXQgYSBuZXdseS1hbGxvY2F0ZWQKKyAgLy8gc3RyaW5nLCBidXQgaWYgd2UgY2xlYXIgaXQgYW5kIGNhbGwgaXQgYWdhaW4sIHdlIGdldCB0aGUgc2FtZSBvYmplY3QgYWdhaW4uCisgIC8vIFdlIHNob3VsZCB2ZXJpZnkgdGhhdCBpdCBoYXMgaXRzIGRlZmF1bHQgdmFsdWUgaW4gYm90aCBjYXNlcy4KKyAgbWVzc2FnZS5zZXRfZGVmYXVsdF9zdHJpbmcoImJsYWgiKTsKKyAgbWVzc2FnZS5DbGVhcigpOworCisgIEVYUEVDVF9FUSgiaGVsbG8iLCAqbWVzc2FnZS5tdXRhYmxlX2RlZmF1bHRfc3RyaW5nKCkpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VUZXN0LCBTdHJpbmdEZWZhdWx0cykgeworICB1bml0dGVzdDo6VGVzdEV4dHJlbWVEZWZhdWx0VmFsdWVzIG1lc3NhZ2U7CisgIC8vIENoZWNrIGlmICdcMDAwJyBjYW4gYmUgdXNlZCBpbiBkZWZhdWx0IHN0cmluZyB2YWx1ZS4KKyAgRVhQRUNUX0VRKHN0cmluZygiaGVsXDAwMGxvIiwgNiksIG1lc3NhZ2Uuc3RyaW5nX3dpdGhfemVybygpKTsKKyAgRVhQRUNUX0VRKHN0cmluZygid29yXDAwMGxkIiwgNiksIG1lc3NhZ2UuYnl0ZXNfd2l0aF96ZXJvKCkpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VUZXN0LCBSZWxlYXNlU3RyaW5nKSB7CisgIC8vIENoZWNrIHRoYXQgcmVsZWFzZV9mb28oKSBzdGFydHMgb3V0IE5VTEwsIGFuZCBnaXZlcyB1cyBhIHZhbHVlCisgIC8vIHRoYXQgd2UgY2FuIGRlbGV0ZSBhZnRlciBpdCdzIGJlZW4gc2V0LgorICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisKKyAgRVhQRUNUX0VRKE5VTEwsIG1lc3NhZ2UucmVsZWFzZV9kZWZhdWx0X3N0cmluZygpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfc3RyaW5nKCkpOworICBFWFBFQ1RfRVEoImhlbGxvIiwgbWVzc2FnZS5kZWZhdWx0X3N0cmluZygpKTsKKworICBtZXNzYWdlLnNldF9kZWZhdWx0X3N0cmluZygiYmxhaCIpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X3N0cmluZygpKTsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxzdHJpbmc+IHN0cihtZXNzYWdlLnJlbGVhc2VfZGVmYXVsdF9zdHJpbmcoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19kZWZhdWx0X3N0cmluZygpKTsKKyAgQVNTRVJUX1RSVUUoc3RyICE9IE5VTEwpOworICBFWFBFQ1RfRVEoImJsYWgiLCAqc3RyKTsKKworICBFWFBFQ1RfRVEoTlVMTCwgbWVzc2FnZS5yZWxlYXNlX2RlZmF1bHRfc3RyaW5nKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZGVmYXVsdF9zdHJpbmcoKSk7CisgIEVYUEVDVF9FUSgiaGVsbG8iLCBtZXNzYWdlLmRlZmF1bHRfc3RyaW5nKCkpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VUZXN0LCBSZWxlYXNlTWVzc2FnZSkgeworICAvLyBDaGVjayB0aGF0IHJlbGVhc2VfZm9vKCkgc3RhcnRzIG91dCBOVUxMLCBhbmQgZ2l2ZXMgdXMgYSB2YWx1ZQorICAvLyB0aGF0IHdlIGNhbiBkZWxldGUgYWZ0ZXIgaXQncyBiZWVuIHNldC4KKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlOworCisgIEVYUEVDVF9FUShOVUxMLCBtZXNzYWdlLnJlbGVhc2Vfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpKTsKKworICBtZXNzYWdlLm11dGFibGVfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKS0+c2V0X2JiKDEpOworICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2U+IG5lc3QoCisgICAgICBtZXNzYWdlLnJlbGVhc2Vfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpKTsKKyAgQVNTRVJUX1RSVUUobmVzdCAhPSBOVUxMKTsKKyAgRVhQRUNUX0VRKDEsIG5lc3QtPmJiKCkpOworCisgIEVYUEVDVF9FUShOVUxMLCBtZXNzYWdlLnJlbGVhc2Vfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpKTsKK30KKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlVGVzdCwgU2V0QWxsb2NhdGVkU3RyaW5nKSB7CisgIC8vIENoZWNrIHRoYXQgc2V0X2FsbG9jYXRlZF9mb28oKSB3b3JrcyBmb3Igc3RyaW5ncy4KKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlOworCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9zdHJpbmcoKSk7CisgIGNvbnN0IHN0cmluZyBrSGVsbG8oImhlbGxvIik7CisgIG1lc3NhZ2Uuc2V0X29wdGlvbmFsX3N0cmluZyhrSGVsbG8pOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vcHRpb25hbF9zdHJpbmcoKSk7CisKKyAgbWVzc2FnZS5zZXRfYWxsb2NhdGVkX29wdGlvbmFsX3N0cmluZyhOVUxMKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX3N0cmluZygpKTsKKyAgRVhQRUNUX0VRKCIiLCBtZXNzYWdlLm9wdGlvbmFsX3N0cmluZygpKTsKKworICBtZXNzYWdlLnNldF9hbGxvY2F0ZWRfb3B0aW9uYWxfc3RyaW5nKG5ldyBzdHJpbmcoa0hlbGxvKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX3N0cmluZygpKTsKKyAgRVhQRUNUX0VRKGtIZWxsbywgbWVzc2FnZS5vcHRpb25hbF9zdHJpbmcoKSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVRlc3QsIFNldEFsbG9jYXRlZE1lc3NhZ2UpIHsKKyAgLy8gQ2hlY2sgdGhhdCBzZXRfYWxsb2NhdGVkX2ZvbygpIGNhbiBiZSBjYWxsZWQgaW4gYWxsIGNhc2VzLgorICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCkpOworCisgIG1lc3NhZ2UubXV0YWJsZV9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpLT5zZXRfYmIoMSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCkpOworCisgIG1lc3NhZ2Uuc2V0X2FsbG9jYXRlZF9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZShOVUxMKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCkpOworICBFWFBFQ1RfRVEoJnVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2U6OmRlZmF1bHRfaW5zdGFuY2UoKSwKKyAgICAgICAgICAgICZtZXNzYWdlLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCkpOworCisgIG1lc3NhZ2UubXV0YWJsZV9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpLT5zZXRfYmIoMSk7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2UqIG5lc3QgPQorICAgICAgbWVzc2FnZS5yZWxlYXNlX29wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCk7CisgIEFTU0VSVF9UUlVFKG5lc3QgIT0gTlVMTCk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpKTsKKworICBtZXNzYWdlLnNldF9hbGxvY2F0ZWRfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UobmVzdCk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpLmJiKCkpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VUZXN0LCBDbGVhcikgeworICAvLyBTZXQgZXZlcnkgZmllbGQgdG8gYSB1bmlxdWUgdmFsdWUsIGNsZWFyIHRoZSBtZXNzYWdlLCB0aGVuIGNoZWNrIHRoYXQKKyAgLy8gaXQgaXMgY2xlYXJlZC4KKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlOworCisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1lc3NhZ2UpOworICBtZXNzYWdlLkNsZWFyKCk7CisgIFRlc3RVdGlsOjpFeHBlY3RDbGVhcihtZXNzYWdlKTsKKworICAvLyBVbmxpa2Ugd2l0aCB0aGUgZGVmYXVsdHMgdGVzdCwgd2UgZG8gTk9UIGV4cGVjdCB0aGF0IHJlcXVlc3RpbmcgZW1iZWRkZWQKKyAgLy8gbWVzc2FnZXMgd2lsbCByZXR1cm4gYSBwb2ludGVyIHRvIHRoZSBkZWZhdWx0IGluc3RhbmNlLiAgSW5zdGVhZCwgdGhleQorICAvLyBzaG91bGQgcmV0dXJuIHRoZSBvYmplY3RzIHRoYXQgd2VyZSBjcmVhdGVkIHdoZW4gbXV0YWJsZV9ibGFoKCkgd2FzCisgIC8vIGNhbGxlZC4KKyAgRVhQRUNUX05FKCZ1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpPcHRpb25hbEdyb3VwOjpkZWZhdWx0X2luc3RhbmNlKCksCisgICAgICAgICAgICAmbWVzc2FnZS5vcHRpb25hbGdyb3VwKCkpOworICBFWFBFQ1RfTkUoJnVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2U6OmRlZmF1bHRfaW5zdGFuY2UoKSwKKyAgICAgICAgICAgICZtZXNzYWdlLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCkpOworICBFWFBFQ1RfTkUoJnVuaXR0ZXN0OjpGb3JlaWduTWVzc2FnZTo6ZGVmYXVsdF9pbnN0YW5jZSgpLAorICAgICAgICAgICAgJm1lc3NhZ2Uub3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlKCkpOworICBFWFBFQ1RfTkUoJnVuaXR0ZXN0X2ltcG9ydDo6SW1wb3J0TWVzc2FnZTo6ZGVmYXVsdF9pbnN0YW5jZSgpLAorICAgICAgICAgICAgJm1lc3NhZ2Uub3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UoKSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVRlc3QsIEVtYmVkZGVkTnVsbHNJbkJ5dGVzQ2hhclN0YXIpIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlOworCisgIGNvbnN0IGNoYXIqIHZhbHVlID0gIlwwbGFsYWxhXDBcMCI7CisgIG1lc3NhZ2Uuc2V0X29wdGlvbmFsX2J5dGVzKHZhbHVlLCA5KTsKKyAgQVNTRVJUX0VRKDksIG1lc3NhZ2Uub3B0aW9uYWxfYnl0ZXMoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbWVtY21wKHZhbHVlLCBtZXNzYWdlLm9wdGlvbmFsX2J5dGVzKCkuZGF0YSgpLCA5KSk7CisKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfYnl0ZXModmFsdWUsIDkpOworICBBU1NFUlRfRVEoOSwgbWVzc2FnZS5yZXBlYXRlZF9ieXRlcygwKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbWVtY21wKHZhbHVlLCBtZXNzYWdlLnJlcGVhdGVkX2J5dGVzKDApLmRhdGEoKSwgOSkpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VUZXN0LCBDbGVhck9uZUZpZWxkKSB7CisgIC8vIFNldCBldmVyeSBmaWVsZCB0byBhIHVuaXF1ZSB2YWx1ZSwgdGhlbiBjbGVhciBvbmUgdmFsdWUgYW5kIGluc3VyZSB0aGF0CisgIC8vIG9ubHkgdGhhdCBvbmUgdmFsdWUgaXMgY2xlYXJlZC4KKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlOworCisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1lc3NhZ2UpOworICBpbnQ2NCBvcmlnaW5hbF92YWx1ZSA9IG1lc3NhZ2Uub3B0aW9uYWxfaW50NjQoKTsKKworICAvLyBDbGVhciB0aGUgZmllbGQgYW5kIG1ha2Ugc3VyZSBpdCBzaG93cyB1cCBhcyBjbGVhcmVkLgorICBtZXNzYWdlLmNsZWFyX29wdGlvbmFsX2ludDY0KCk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9pbnQ2NCgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2Uub3B0aW9uYWxfaW50NjQoKSk7CisKKyAgLy8gT3RoZXIgYWRqYWNlbnQgZmllbGRzIHNob3VsZCBub3QgYmUgY2xlYXJlZC4KKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfb3B0aW9uYWxfaW50MzIoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX3VpbnQzMigpKTsKKworICAvLyBNYWtlIHN1cmUgaWYgd2Ugc2V0IGl0IGFnYWluLCB0aGVuIGFsbCBmaWVsZHMgYXJlIHNldC4KKyAgbWVzc2FnZS5zZXRfb3B0aW9uYWxfaW50NjQob3JpZ2luYWxfdmFsdWUpOworICBUZXN0VXRpbDo6RXhwZWN0QWxsRmllbGRzU2V0KG1lc3NhZ2UpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VUZXN0LCBTdHJpbmdDaGFyU3Rhckxlbmd0aCkgeworICAvLyBWZXJpZnkgdGhhdCB3ZSBjYW4gdXNlIGEgY2hhciosbGVuZ3RoIHRvIHNldCBvbmUgb2YgdGhlIHN0cmluZyBmaWVsZHMuCisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKyAgbWVzc2FnZS5zZXRfb3B0aW9uYWxfc3RyaW5nKCJhYmNkZWYiLCAzKTsKKyAgRVhQRUNUX0VRKCJhYmMiLCBtZXNzYWdlLm9wdGlvbmFsX3N0cmluZygpKTsKKworICAvLyBWZXJpZnkgdGhhdCB3ZSBjYW4gdXNlIGEgY2hhciosbGVuZ3RoIHRvIGFkZCB0byBhIHJlcGVhdGVkIHN0cmluZyBmaWVsZC4KKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfc3RyaW5nKCJhYmNkZWYiLCAzKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nX3NpemUoKSk7CisgIEVYUEVDVF9FUSgiYWJjIiwgbWVzc2FnZS5yZXBlYXRlZF9zdHJpbmcoMCkpOworCisgIC8vIFZlcmlmeSB0aGF0IHdlIGNhbiB1c2UgYSBjaGFyKixsZW5ndGggdG8gc2V0IGEgcmVwZWF0ZWQgc3RyaW5nIGZpZWxkLgorICBtZXNzYWdlLnNldF9yZXBlYXRlZF9zdHJpbmcoMCwgInd4eXoiLCAyKTsKKyAgRVhQRUNUX0VRKCJ3eCIsIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nKDApKTsKK30KKworCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VUZXN0LCBDb3B5RnJvbSkgeworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2UxLCBtZXNzYWdlMjsKKworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZtZXNzYWdlMSk7CisgIG1lc3NhZ2UyLkNvcHlGcm9tKG1lc3NhZ2UxKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEZpZWxkc1NldChtZXNzYWdlMik7CisKKyAgLy8gQ29weWluZyBmcm9tIHNlbGYgc2hvdWxkIGJlIGEgbm8tb3AuCisgIG1lc3NhZ2UyLkNvcHlGcm9tKG1lc3NhZ2UyKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEZpZWxkc1NldChtZXNzYWdlMik7Cit9CisKKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlVGVzdCwgU3dhcFdpdGhFbXB0eSkgeworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2UxLCBtZXNzYWdlMjsKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbWVzc2FnZTEpOworCisgIFRlc3RVdGlsOjpFeHBlY3RBbGxGaWVsZHNTZXQobWVzc2FnZTEpOworICBUZXN0VXRpbDo6RXhwZWN0Q2xlYXIobWVzc2FnZTIpOworICBtZXNzYWdlMS5Td2FwKCZtZXNzYWdlMik7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxGaWVsZHNTZXQobWVzc2FnZTIpOworICBUZXN0VXRpbDo6RXhwZWN0Q2xlYXIobWVzc2FnZTEpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VUZXN0LCBTd2FwV2l0aFNlbGYpIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlOworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZtZXNzYWdlKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEZpZWxkc1NldChtZXNzYWdlKTsKKyAgbWVzc2FnZS5Td2FwKCZtZXNzYWdlKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEZpZWxkc1NldChtZXNzYWdlKTsKK30KKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlVGVzdCwgU3dhcFdpdGhPdGhlcikgeworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2UxLCBtZXNzYWdlMjsKKworICBtZXNzYWdlMS5zZXRfb3B0aW9uYWxfaW50MzIoMTIzKTsKKyAgbWVzc2FnZTEuc2V0X29wdGlvbmFsX3N0cmluZygiYWJjIik7CisgIG1lc3NhZ2UxLm11dGFibGVfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKS0+c2V0X2JiKDEpOworICBtZXNzYWdlMS5zZXRfb3B0aW9uYWxfbmVzdGVkX2VudW0odW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6Rk9PKTsKKyAgbWVzc2FnZTEuYWRkX3JlcGVhdGVkX2ludDMyKDEpOworICBtZXNzYWdlMS5hZGRfcmVwZWF0ZWRfaW50MzIoMik7CisgIG1lc3NhZ2UxLmFkZF9yZXBlYXRlZF9zdHJpbmcoImEiKTsKKyAgbWVzc2FnZTEuYWRkX3JlcGVhdGVkX3N0cmluZygiYiIpOworICBtZXNzYWdlMS5hZGRfcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UoKS0+c2V0X2JiKDcpOworICBtZXNzYWdlMS5hZGRfcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UoKS0+c2V0X2JiKDgpOworICBtZXNzYWdlMS5hZGRfcmVwZWF0ZWRfbmVzdGVkX2VudW0odW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6Rk9PKTsKKyAgbWVzc2FnZTEuYWRkX3JlcGVhdGVkX25lc3RlZF9lbnVtKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkJBUik7CisKKyAgbWVzc2FnZTIuc2V0X29wdGlvbmFsX2ludDMyKDQ1Nik7CisgIG1lc3NhZ2UyLnNldF9vcHRpb25hbF9zdHJpbmcoImRlZiIpOworICBtZXNzYWdlMi5tdXRhYmxlX29wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCktPnNldF9iYigyKTsKKyAgbWVzc2FnZTIuc2V0X29wdGlvbmFsX25lc3RlZF9lbnVtKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkJBUik7CisgIG1lc3NhZ2UyLmFkZF9yZXBlYXRlZF9pbnQzMigzKTsKKyAgbWVzc2FnZTIuYWRkX3JlcGVhdGVkX3N0cmluZygiYyIpOworICBtZXNzYWdlMi5hZGRfcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UoKS0+c2V0X2JiKDkpOworICBtZXNzYWdlMi5hZGRfcmVwZWF0ZWRfbmVzdGVkX2VudW0odW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6QkFaKTsKKworICBtZXNzYWdlMS5Td2FwKCZtZXNzYWdlMik7CisKKyAgRVhQRUNUX0VRKDQ1NiwgbWVzc2FnZTEub3B0aW9uYWxfaW50MzIoKSk7CisgIEVYUEVDVF9FUSgiZGVmIiwgbWVzc2FnZTEub3B0aW9uYWxfc3RyaW5nKCkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZTEub3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKS5iYigpKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkJBUiwgbWVzc2FnZTEub3B0aW9uYWxfbmVzdGVkX2VudW0oKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlMS5yZXBlYXRlZF9pbnQzMl9zaXplKCkpOworICBFWFBFQ1RfRVEoMywgbWVzc2FnZTEucmVwZWF0ZWRfaW50MzIoMCkpOworICBBU1NFUlRfRVEoMSwgbWVzc2FnZTEucmVwZWF0ZWRfc3RyaW5nX3NpemUoKSk7CisgIEVYUEVDVF9FUSgiYyIsIG1lc3NhZ2UxLnJlcGVhdGVkX3N0cmluZygwKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlMS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9zaXplKCkpOworICBFWFBFQ1RfRVEoOSwgbWVzc2FnZTEucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UoMCkuYmIoKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlMS5yZXBlYXRlZF9uZXN0ZWRfZW51bV9zaXplKCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6QkFaLCBtZXNzYWdlMS5yZXBlYXRlZF9uZXN0ZWRfZW51bSgwKSk7CisKKyAgRVhQRUNUX0VRKDEyMywgbWVzc2FnZTIub3B0aW9uYWxfaW50MzIoKSk7CisgIEVYUEVDVF9FUSgiYWJjIiwgbWVzc2FnZTIub3B0aW9uYWxfc3RyaW5nKCkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZTIub3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKS5iYigpKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkZPTywgbWVzc2FnZTIub3B0aW9uYWxfbmVzdGVkX2VudW0oKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlMi5yZXBlYXRlZF9pbnQzMl9zaXplKCkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZTIucmVwZWF0ZWRfaW50MzIoMCkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZTIucmVwZWF0ZWRfaW50MzIoMSkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZTIucmVwZWF0ZWRfc3RyaW5nX3NpemUoKSk7CisgIEVYUEVDVF9FUSgiYSIsIG1lc3NhZ2UyLnJlcGVhdGVkX3N0cmluZygwKSk7CisgIEVYUEVDVF9FUSgiYiIsIG1lc3NhZ2UyLnJlcGVhdGVkX3N0cmluZygxKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlMi5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9zaXplKCkpOworICBFWFBFQ1RfRVEoNywgbWVzc2FnZTIucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UoMCkuYmIoKSk7CisgIEVYUEVDVF9FUSg4LCBtZXNzYWdlMi5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSgxKS5iYigpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UyLnJlcGVhdGVkX25lc3RlZF9lbnVtX3NpemUoKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpGT08sIG1lc3NhZ2UyLnJlcGVhdGVkX25lc3RlZF9lbnVtKDApKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkJBUiwgbWVzc2FnZTIucmVwZWF0ZWRfbmVzdGVkX2VudW0oMSkpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VUZXN0LCBDb3B5Q29uc3RydWN0b3IpIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlMTsKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbWVzc2FnZTEpOworCisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTIobWVzc2FnZTEpOworICBUZXN0VXRpbDo6RXhwZWN0QWxsRmllbGRzU2V0KG1lc3NhZ2UyKTsKK30KKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlVGVzdCwgQ29weUFzc2lnbm1lbnRPcGVyYXRvcikgeworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2UxOworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZtZXNzYWdlMSk7CisKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlMjsKKyAgbWVzc2FnZTIgPSBtZXNzYWdlMTsKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEZpZWxkc1NldChtZXNzYWdlMik7CisKKyAgLy8gTWFrZSBzdXJlIHRoYXQgc2VsZi1hc3NpZ25tZW50IGRvZXMgc29tZXRoaW5nIHNhbmUuCisgIG1lc3NhZ2UyLm9wZXJhdG9yPShtZXNzYWdlMik7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxGaWVsZHNTZXQobWVzc2FnZTIpOworfQorCisjaWYgIWRlZmluZWQoUFJPVE9CVUZfVEVTVF9OT19ERVNDUklQVE9SUykgfHwgXAorICAgICFkZWZpbmVkKEdPT0dMRV9QUk9UT0JVRl9OT19SVFRJKQorVEVTVChHZW5lcmF0ZWRNZXNzYWdlVGVzdCwgVXBjYXN0Q29weUZyb20pIHsKKyAgLy8gVGVzdCB0aGUgQ29weUZyb20gbWV0aG9kIHRoYXQgdGFrZXMgaW4gdGhlIGdlbmVyaWMgY29uc3QgTWVzc2FnZSYKKyAgLy8gcGFyYW1ldGVyLgorICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2UxLCBtZXNzYWdlMjsKKworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZtZXNzYWdlMSk7CisKKyAgY29uc3QgTWVzc2FnZSogc291cmNlID0gaW1wbGljaXRfY2FzdDxjb25zdCBNZXNzYWdlKj4oJm1lc3NhZ2UxKTsKKyAgbWVzc2FnZTIuQ29weUZyb20oKnNvdXJjZSk7CisKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEZpZWxkc1NldChtZXNzYWdlMik7Cit9CisjZW5kaWYKKworI2lmbmRlZiBQUk9UT0JVRl9URVNUX05PX0RFU0NSSVBUT1JTCisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVRlc3QsIER5bmFtaWNNZXNzYWdlQ29weUZyb20pIHsKKyAgLy8gVGVzdCBjb3B5aW5nIGZyb20gYSBEeW5hbWljTWVzc2FnZSwgd2hpY2ggbXVzdCBmYWxsIGJhY2sgdG8gdXNpbmcKKyAgLy8gcmVmbGVjdGlvbi4KKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlMjsKKworICAvLyBDb25zdHJ1Y3QgYSBuZXcgdmVyc2lvbiBvZiB0aGUgZHluYW1pYyBtZXNzYWdlIHZpYSB0aGUgZmFjdG9yeS4KKyAgRHluYW1pY01lc3NhZ2VGYWN0b3J5IGZhY3Rvcnk7CisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8TWVzc2FnZT4gbWVzc2FnZTE7CisgIG1lc3NhZ2UxLnJlc2V0KGZhY3RvcnkuR2V0UHJvdG90eXBlKAorICAgICAgICAgICAgICAgICAgICAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6ZGVzY3JpcHRvcigpKS0+TmV3KCkpOworCisgIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyIHJlZmxlY3Rpb25fdGVzdGVyKAorICAgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OmRlc2NyaXB0b3IoKSk7CisgIHJlZmxlY3Rpb25fdGVzdGVyLlNldEFsbEZpZWxkc1ZpYVJlZmxlY3Rpb24obWVzc2FnZTEuZ2V0KCkpOworCisgIG1lc3NhZ2UyLkNvcHlGcm9tKCptZXNzYWdlMSk7CisKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEZpZWxkc1NldChtZXNzYWdlMik7Cit9CisKKyNlbmRpZiAgLy8gIVBST1RPQlVGX1RFU1RfTk9fREVTQ1JJUFRPUlMKKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlVGVzdCwgTm9uRW1wdHlNZXJnZUZyb20pIHsKKyAgLy8gVGVzdCBtZXJnaW5nIHdpdGggYSBub24tZW1wdHkgbWVzc2FnZS4gQ29kZSBpcyBhIG1vZGlmaWVkIGZvcm0KKyAgLy8gb2YgdGhhdCBmb3VuZCBpbiBnb29nbGUvcHJvdG9idWYvcmVmbGVjdGlvbl9vcHNfdW5pdHRlc3QuY2MuCisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTEsIG1lc3NhZ2UyOworCisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1lc3NhZ2UxKTsKKworICAvLyBUaGlzIGZpZWxkIHdpbGwgdGVzdCBtZXJnaW5nIGludG8gYW4gZW1wdHkgc3BvdC4KKyAgbWVzc2FnZTIuc2V0X29wdGlvbmFsX2ludDMyKG1lc3NhZ2UxLm9wdGlvbmFsX2ludDMyKCkpOworICBtZXNzYWdlMS5jbGVhcl9vcHRpb25hbF9pbnQzMigpOworCisgIC8vIFRoaXMgdGVzdHMgb3ZlcndyaXRpbmcuCisgIG1lc3NhZ2UyLnNldF9vcHRpb25hbF9zdHJpbmcobWVzc2FnZTEub3B0aW9uYWxfc3RyaW5nKCkpOworICBtZXNzYWdlMS5zZXRfb3B0aW9uYWxfc3RyaW5nKCJzb21ldGhpbmcgZWxzZSIpOworCisgIC8vIFRoaXMgdGVzdHMgY29uY2F0ZW5hdGluZy4KKyAgbWVzc2FnZTIuYWRkX3JlcGVhdGVkX2ludDMyKG1lc3NhZ2UxLnJlcGVhdGVkX2ludDMyKDEpKTsKKyAgaW50MzIgaSA9IG1lc3NhZ2UxLnJlcGVhdGVkX2ludDMyKDApOworICBtZXNzYWdlMS5jbGVhcl9yZXBlYXRlZF9pbnQzMigpOworICBtZXNzYWdlMS5hZGRfcmVwZWF0ZWRfaW50MzIoaSk7CisKKyAgbWVzc2FnZTEuTWVyZ2VGcm9tKG1lc3NhZ2UyKTsKKworICBUZXN0VXRpbDo6RXhwZWN0QWxsRmllbGRzU2V0KG1lc3NhZ2UxKTsKK30KKworI2lmICFkZWZpbmVkKFBST1RPQlVGX1RFU1RfTk9fREVTQ1JJUFRPUlMpIHx8IFwKKyAgICAhZGVmaW5lZChHT09HTEVfUFJPVE9CVUZfTk9fUlRUSSkKKyNpZmRlZiBQUk9UT0JVRl9IQVNfREVBVEhfVEVTVAorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VUZXN0LCBNZXJnZUZyb21TZWxmKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKyAgRVhQRUNUX0RFQVRIKG1lc3NhZ2UuTWVyZ2VGcm9tKG1lc3NhZ2UpLCAiQ2hlY2sgZmFpbGVkOi4qcGJbLl1jYyIpOworICBFWFBFQ1RfREVBVEgobWVzc2FnZS5NZXJnZUZyb20oaW1wbGljaXRfY2FzdDxjb25zdCBNZXNzYWdlJj4obWVzc2FnZSkpLAorICAgICAgICAgICAgICAgIkNoZWNrIGZhaWxlZDouKnBiWy5dY2MiKTsKK30KKworI2VuZGlmICAvLyBQUk9UT0JVRl9IQVNfREVBVEhfVEVTVAorI2VuZGlmICAvLyAhUFJPVE9CVUZfVEVTVF9OT19ERVNDUklQVE9SUyB8fCAhR09PR0xFX1BST1RPQlVGX05PX1JUVEkKKworLy8gVGVzdCB0aGUgZ2VuZXJhdGVkIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoKSwKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVRlc3QsIFNlcmlhbGl6YXRpb25Ub0FycmF5KSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTEsIG1lc3NhZ2UyOworICBzdHJpbmcgZGF0YTsKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbWVzc2FnZTEpOworICBpbnQgc2l6ZSA9IG1lc3NhZ2UxLkJ5dGVTaXplKCk7CisgIGRhdGEucmVzaXplKHNpemUpOworICB1aW50OCogc3RhcnQgPSByZWludGVycHJldF9jYXN0PHVpbnQ4Kj4oc3RyaW5nX2FzX2FycmF5KCZkYXRhKSk7CisgIHVpbnQ4KiBlbmQgPSBtZXNzYWdlMS5TZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KHN0YXJ0KTsKKyAgRVhQRUNUX0VRKHNpemUsIGVuZCAtIHN0YXJ0KTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZTIuUGFyc2VGcm9tU3RyaW5nKGRhdGEpKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEZpZWxkc1NldChtZXNzYWdlMik7CisKK30KKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlVGVzdCwgUGFja2VkRmllbGRzU2VyaWFsaXphdGlvblRvQXJyYXkpIHsKKyAgdW5pdHRlc3Q6OlRlc3RQYWNrZWRUeXBlcyBwYWNrZWRfbWVzc2FnZTEsIHBhY2tlZF9tZXNzYWdlMjsKKyAgc3RyaW5nIHBhY2tlZF9kYXRhOworICBUZXN0VXRpbDo6U2V0UGFja2VkRmllbGRzKCZwYWNrZWRfbWVzc2FnZTEpOworICBpbnQgcGFja2VkX3NpemUgPSBwYWNrZWRfbWVzc2FnZTEuQnl0ZVNpemUoKTsKKyAgcGFja2VkX2RhdGEucmVzaXplKHBhY2tlZF9zaXplKTsKKyAgdWludDgqIHN0YXJ0ID0gcmVpbnRlcnByZXRfY2FzdDx1aW50OCo+KHN0cmluZ19hc19hcnJheSgmcGFja2VkX2RhdGEpKTsKKyAgdWludDgqIGVuZCA9IHBhY2tlZF9tZXNzYWdlMS5TZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KHN0YXJ0KTsKKyAgRVhQRUNUX0VRKHBhY2tlZF9zaXplLCBlbmQgLSBzdGFydCk7CisgIEVYUEVDVF9UUlVFKHBhY2tlZF9tZXNzYWdlMi5QYXJzZUZyb21TdHJpbmcocGFja2VkX2RhdGEpKTsKKyAgVGVzdFV0aWw6OkV4cGVjdFBhY2tlZEZpZWxkc1NldChwYWNrZWRfbWVzc2FnZTIpOworfQorCisvLyBUZXN0IHRoZSBnZW5lcmF0ZWQgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKCkgYnkgZm9yY2luZyB0aGUgYnVmZmVyIHRvIHdyaXRlCisvLyBvbmUgYnl0ZSBhdCBhIHRpbWUuCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VUZXN0LCBTZXJpYWxpemF0aW9uVG9TdHJlYW0pIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlMSwgbWVzc2FnZTI7CisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1lc3NhZ2UxKTsKKyAgaW50IHNpemUgPSBtZXNzYWdlMS5CeXRlU2l6ZSgpOworICBzdHJpbmcgZGF0YTsKKyAgZGF0YS5yZXNpemUoc2l6ZSk7CisgIHsKKyAgICAvLyBBbGxvdyB0aGUgb3V0cHV0IHN0cmVhbSB0byBidWZmZXIgb25seSBvbmUgYnl0ZSBhdCBhIHRpbWUuCisgICAgaW86OkFycmF5T3V0cHV0U3RyZWFtIGFycmF5X3N0cmVhbShzdHJpbmdfYXNfYXJyYXkoJmRhdGEpLCBzaXplLCAxKTsKKyAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0X3N0cmVhbSgmYXJyYXlfc3RyZWFtKTsKKyAgICBtZXNzYWdlMS5TZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoJm91dHB1dF9zdHJlYW0pOworICAgIEVYUEVDVF9GQUxTRShvdXRwdXRfc3RyZWFtLkhhZEVycm9yKCkpOworICAgIEVYUEVDVF9FUShzaXplLCBvdXRwdXRfc3RyZWFtLkJ5dGVDb3VudCgpKTsKKyAgfQorICBFWFBFQ1RfVFJVRShtZXNzYWdlMi5QYXJzZUZyb21TdHJpbmcoZGF0YSkpOworICBUZXN0VXRpbDo6RXhwZWN0QWxsRmllbGRzU2V0KG1lc3NhZ2UyKTsKKworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VUZXN0LCBQYWNrZWRGaWVsZHNTZXJpYWxpemF0aW9uVG9TdHJlYW0pIHsKKyAgdW5pdHRlc3Q6OlRlc3RQYWNrZWRUeXBlcyBtZXNzYWdlMSwgbWVzc2FnZTI7CisgIFRlc3RVdGlsOjpTZXRQYWNrZWRGaWVsZHMoJm1lc3NhZ2UxKTsKKyAgaW50IHNpemUgPSBtZXNzYWdlMS5CeXRlU2l6ZSgpOworICBzdHJpbmcgZGF0YTsKKyAgZGF0YS5yZXNpemUoc2l6ZSk7CisgIHsKKyAgICAvLyBBbGxvdyB0aGUgb3V0cHV0IHN0cmVhbSB0byBidWZmZXIgb25seSBvbmUgYnl0ZSBhdCBhIHRpbWUuCisgICAgaW86OkFycmF5T3V0cHV0U3RyZWFtIGFycmF5X3N0cmVhbShzdHJpbmdfYXNfYXJyYXkoJmRhdGEpLCBzaXplLCAxKTsKKyAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0X3N0cmVhbSgmYXJyYXlfc3RyZWFtKTsKKyAgICBtZXNzYWdlMS5TZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoJm91dHB1dF9zdHJlYW0pOworICAgIEVYUEVDVF9GQUxTRShvdXRwdXRfc3RyZWFtLkhhZEVycm9yKCkpOworICAgIEVYUEVDVF9FUShzaXplLCBvdXRwdXRfc3RyZWFtLkJ5dGVDb3VudCgpKTsKKyAgfQorICBFWFBFQ1RfVFJVRShtZXNzYWdlMi5QYXJzZUZyb21TdHJpbmcoZGF0YSkpOworICBUZXN0VXRpbDo6RXhwZWN0UGFja2VkRmllbGRzU2V0KG1lc3NhZ2UyKTsKK30KKworCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VUZXN0LCBSZXF1aXJlZCkgeworICAvLyBUZXN0IHRoYXQgSXNJbml0aWFsaXplZCgpIHJldHVybnMgZmFsc2UgaWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nLgorICB1bml0dGVzdDo6VGVzdFJlcXVpcmVkIG1lc3NhZ2U7CisKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSXNJbml0aWFsaXplZCgpKTsKKyAgbWVzc2FnZS5zZXRfYSgxKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSXNJbml0aWFsaXplZCgpKTsKKyAgbWVzc2FnZS5zZXRfYigyKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSXNJbml0aWFsaXplZCgpKTsKKyAgbWVzc2FnZS5zZXRfYygzKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5Jc0luaXRpYWxpemVkKCkpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VUZXN0LCBSZXF1aXJlZEZvcmVpZ24pIHsKKyAgLy8gVGVzdCB0aGF0IElzSW5pdGlhbGl6ZWQoKSByZXR1cm5zIGZhbHNlIGlmIHJlcXVpcmVkIGZpZWxkcyBpbiBuZXN0ZWQKKyAgLy8gbWVzc2FnZXMgYXJlIG1pc3NpbmcuCisgIHVuaXR0ZXN0OjpUZXN0UmVxdWlyZWRGb3JlaWduIG1lc3NhZ2U7CisKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5Jc0luaXRpYWxpemVkKCkpOworCisgIG1lc3NhZ2UubXV0YWJsZV9vcHRpb25hbF9tZXNzYWdlKCk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLklzSW5pdGlhbGl6ZWQoKSk7CisKKyAgbWVzc2FnZS5tdXRhYmxlX29wdGlvbmFsX21lc3NhZ2UoKS0+c2V0X2EoMSk7CisgIG1lc3NhZ2UubXV0YWJsZV9vcHRpb25hbF9tZXNzYWdlKCktPnNldF9iKDIpOworICBtZXNzYWdlLm11dGFibGVfb3B0aW9uYWxfbWVzc2FnZSgpLT5zZXRfYygzKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5Jc0luaXRpYWxpemVkKCkpOworCisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX21lc3NhZ2UoKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSXNJbml0aWFsaXplZCgpKTsKKworICBtZXNzYWdlLm11dGFibGVfcmVwZWF0ZWRfbWVzc2FnZSgwKS0+c2V0X2EoMSk7CisgIG1lc3NhZ2UubXV0YWJsZV9yZXBlYXRlZF9tZXNzYWdlKDApLT5zZXRfYigyKTsKKyAgbWVzc2FnZS5tdXRhYmxlX3JlcGVhdGVkX21lc3NhZ2UoMCktPnNldF9jKDMpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLklzSW5pdGlhbGl6ZWQoKSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVRlc3QsIEZvcmVpZ25OZXN0ZWQpIHsKKyAgLy8gVGVzdCB0aGF0IFRlc3RBbGxUeXBlczo6TmVzdGVkTWVzc2FnZSBjYW4gYmUgZW1iZWRkZWQgZGlyZWN0bHkgaW50bworICAvLyBhbm90aGVyIG1lc3NhZ2UuCisgIHVuaXR0ZXN0OjpUZXN0Rm9yZWlnbk5lc3RlZCBtZXNzYWdlOworCisgIC8vIElmIHRoaXMgY29tcGlsZXMgYW5kIHJ1bnMgd2l0aG91dCBjcmFzaGluZywgaXQgbXVzdCB3b3JrLiAgV2UgaGF2ZQorICAvLyBub3RoaW5nIG1vcmUgdG8gdGVzdC4KKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6TmVzdGVkTWVzc2FnZSogbmVzdGVkID0KKyAgICBtZXNzYWdlLm11dGFibGVfZm9yZWlnbl9uZXN0ZWQoKTsKKyAgbmVzdGVkLT5zZXRfYmIoMSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVRlc3QsIFJlYWxseUxhcmdlVGFnTnVtYmVyKSB7CisgIC8vIFRlc3QgdGhhdCByZWFsbHkgbGFyZ2UgdGFnIG51bWJlcnMgZG9uJ3QgYnJlYWsgYW55dGhpbmcuCisgIHVuaXR0ZXN0OjpUZXN0UmVhbGx5TGFyZ2VUYWdOdW1iZXIgbWVzc2FnZTEsIG1lc3NhZ2UyOworICBzdHJpbmcgZGF0YTsKKworICAvLyBGb3IgdGhlIG1vc3QgcGFydCwgaWYgdGhpcyBjb21waWxlcyBhbmQgcnVucyB0aGVuIHdlJ3JlIHByb2JhYmx5IGdvb2QuCisgIC8vIChUaGUgbW9zdCBsaWtlbHkgY2F1c2UgZm9yIGZhaWx1cmUgd291bGQgYmUgaWYgc29tZXRoaW5nIHdlcmUgYXR0ZW1wdGluZworICAvLyB0byBhbGxvY2F0ZSBhIGxvb2t1cCB0YWJsZSBvZiBzb21lIHNvcnQgdXNpbmcgdGFnIG51bWJlcnMgYXMgdGhlIGluZGV4LikKKyAgLy8gV2UnbGwgdHJ5IHNlcmlhbGl6aW5nIGp1c3QgZm9yIGZ1bi4KKyAgbWVzc2FnZTEuc2V0X2EoMTIzNCk7CisgIG1lc3NhZ2UxLnNldF9iYig1Njc4KTsKKyAgbWVzc2FnZTEuU2VyaWFsaXplVG9TdHJpbmcoJmRhdGEpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlMi5QYXJzZUZyb21TdHJpbmcoZGF0YSkpOworICBFWFBFQ1RfRVEoMTIzNCwgbWVzc2FnZTIuYSgpKTsKKyAgRVhQRUNUX0VRKDU2NzgsIG1lc3NhZ2UyLmJiKCkpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VUZXN0LCBNdXR1YWxSZWN1cnNpb24pIHsKKyAgLy8gVGVzdCB0aGF0IG11dHVhbGx5LXJlY3Vyc2l2ZSBtZXNzYWdlIHR5cGVzIHdvcmsuCisgIHVuaXR0ZXN0OjpUZXN0TXV0dWFsUmVjdXJzaW9uQSBtZXNzYWdlOworICB1bml0dGVzdDo6VGVzdE11dHVhbFJlY3Vyc2lvbkEqIG5lc3RlZCA9IG1lc3NhZ2UubXV0YWJsZV9iYigpLT5tdXRhYmxlX2EoKTsKKyAgdW5pdHRlc3Q6OlRlc3RNdXR1YWxSZWN1cnNpb25BKiBuZXN0ZWQyID0gbmVzdGVkLT5tdXRhYmxlX2JiKCktPm11dGFibGVfYSgpOworCisgIC8vIEFnYWluLCBpZiB0aGUgYWJvdmUgY29tcGlsZXMgYW5kIHJ1bnMsIHRoYXQncyBhbGwgd2UgcmVhbGx5IGhhdmUgdG8KKyAgLy8gdGVzdCwgYnV0IGp1c3QgZm9yIHJ1biB3ZSdsbCBjaGVjayB0aGF0IHRoZSBzeXN0ZW0gZGlkbid0IHNvbWVob3cgY29tZQorICAvLyB1cCB3aXRoIGEgcG9pbnRlciBsb29wLi4uCisgIEVYUEVDVF9ORSgmbWVzc2FnZSwgbmVzdGVkKTsKKyAgRVhQRUNUX05FKCZtZXNzYWdlLCBuZXN0ZWQyKTsKKyAgRVhQRUNUX05FKG5lc3RlZCwgbmVzdGVkMik7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVRlc3QsIENhbWVsQ2FzZUZpZWxkTmFtZXMpIHsKKyAgLy8gVGhpcyB0ZXN0IGlzIG1haW5seSBjaGVja2luZyB0aGF0IHRoZSBmb2xsb3dpbmcgY29tcGlsZXMsIHdoaWNoIHZlcmlmaWVzCisgIC8vIHRoYXQgdGhlIGZpZWxkIG5hbWVzIHdlcmUgY29lcmNlZCB0byBsb3dlci1jYXNlLgorICAvLworICAvLyBQcm90b2NvbCBidWZmZXJzIHN0YW5kYXJkIHN0eWxlIGlzIHRvIHVzZSBsb3dlcmNhc2Utd2l0aC11bmRlcnNjb3JlcyBmb3IKKyAgLy8gZmllbGQgbmFtZXMuICBTb21lIG9sZCBwcm90bzEgLnByb3RvcyB1bmZvcnR1bmF0ZWx5IHVzZWQgY2FtZWwtY2FzZSBmaWVsZAorICAvLyBuYW1lcy4gIEluIHByb3RvMSwgdGhlc2UgbmFtZXMgd2VyZSBmb3JjZWQgdG8gbG93ZXItY2FzZS4gIFNvLCB3ZSBkbyB0aGUKKyAgLy8gc2FtZSB0aGluZyBpbiBwcm90bzIuCisKKyAgdW5pdHRlc3Q6OlRlc3RDYW1lbENhc2VGaWVsZE5hbWVzIG1lc3NhZ2U7CisKKyAgbWVzc2FnZS5zZXRfcHJpbWl0aXZlZmllbGQoMik7CisgIG1lc3NhZ2Uuc2V0X3N0cmluZ2ZpZWxkKCJmb28iKTsKKyAgbWVzc2FnZS5zZXRfZW51bWZpZWxkKHVuaXR0ZXN0OjpGT1JFSUdOX0ZPTyk7CisgIG1lc3NhZ2UubXV0YWJsZV9tZXNzYWdlZmllbGQoKS0+c2V0X2MoNik7CisKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRwcmltaXRpdmVmaWVsZCg4KTsKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRzdHJpbmdmaWVsZCgicXV4Iik7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkZW51bWZpZWxkKHVuaXR0ZXN0OjpGT1JFSUdOX0JBUik7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkbWVzc2FnZWZpZWxkKCktPnNldF9jKDE1KTsKKworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5wcmltaXRpdmVmaWVsZCgpKTsKKyAgRVhQRUNUX0VRKCJmb28iLCBtZXNzYWdlLnN0cmluZ2ZpZWxkKCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fRk9PLCBtZXNzYWdlLmVudW1maWVsZCgpKTsKKyAgRVhQRUNUX0VRKDYsIG1lc3NhZ2UubWVzc2FnZWZpZWxkKCkuYygpKTsKKworICBFWFBFQ1RfRVEoOCwgbWVzc2FnZS5yZXBlYXRlZHByaW1pdGl2ZWZpZWxkKDApKTsKKyAgRVhQRUNUX0VRKCJxdXgiLCBtZXNzYWdlLnJlcGVhdGVkc3RyaW5nZmllbGQoMCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fQkFSLCBtZXNzYWdlLnJlcGVhdGVkZW51bWZpZWxkKDApKTsKKyAgRVhQRUNUX0VRKDE1LCBtZXNzYWdlLnJlcGVhdGVkbWVzc2FnZWZpZWxkKDApLmMoKSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVRlc3QsIFRlc3RDb25mbGljdGluZ1N5bWJvbE5hbWVzKSB7CisgIC8vIHRlc3RfYmFkX2lkZW50aWZpZXJzLnByb3RvIHN1Y2Nlc3NmdWxseSBjb21waWxlZCwgdGhlbiBpdCB3b3Jrcy4gIFRoZQorICAvLyBmb2xsb3dpbmcgaXMganVzdCBhIHRva2VuIHVzYWdlIHRvIGluc3VyZSB0aGF0IHRoZSBjb2RlIGlzLCBpbiBmYWN0LAorICAvLyBiZWluZyBjb21waWxlZCBhbmQgbGlua2VkLgorCisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0Q29uZmxpY3RpbmdTeW1ib2xOYW1lcyBtZXNzYWdlOworICBtZXNzYWdlLnNldF91aW50MzIoMSk7CisgIEVYUEVDVF9FUSgzLCBtZXNzYWdlLkJ5dGVTaXplKCkpOworCisgIG1lc3NhZ2Uuc2V0X2ZyaWVuZF8oNSk7CisgIEVYUEVDVF9FUSg1LCBtZXNzYWdlLmZyaWVuZF8oKSk7CisKKyAgbWVzc2FnZS5zZXRfY2xhc3NfKDYpOworICBFWFBFQ1RfRVEoNiwgbWVzc2FnZS5jbGFzc18oKSk7CisKKyAgLy8gSW5zdGFudGlhdGUgZXh0ZW5zaW9uIHRlbXBsYXRlIGZ1bmN0aW9ucyB0byB0ZXN0IGNvbmZsaWN0aW5nIHRlbXBsYXRlCisgIC8vIHBhcmFtZXRlciBuYW1lcy4KKyAgdHlwZWRlZiBwcm90b2J1Zl91bml0dGVzdDo6VGVzdENvbmZsaWN0aW5nU3ltYm9sTmFtZXNFeHRlbnNpb24gRXh0ZW5zaW9uTWVzc2FnZTsKKyAgbWVzc2FnZS5BZGRFeHRlbnNpb24oRXh0ZW5zaW9uTWVzc2FnZTo6cmVwZWF0ZWRfaW50MzJfZXh0LCAxMjMpOworICBFWFBFQ1RfRVEoMTIzLAorICAgICAgICAgICAgbWVzc2FnZS5HZXRFeHRlbnNpb24oRXh0ZW5zaW9uTWVzc2FnZTo6cmVwZWF0ZWRfaW50MzJfZXh0LCAwKSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVRlc3QsIFRlc3RDb25mbGljdGluZ0VudW1OYW1lcykgeworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdENvbmZsaWN0aW5nRW51bU5hbWVzIG1lc3NhZ2U7CisgIG1lc3NhZ2Uuc2V0X2NvbmZsaWN0aW5nX2VudW0ocHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RDb25mbGljdGluZ0VudW1OYW1lc19OZXN0ZWRDb25mbGljdGluZ0VudW1fYW5kXyk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLmNvbmZsaWN0aW5nX2VudW0oKSk7CisgIG1lc3NhZ2Uuc2V0X2NvbmZsaWN0aW5nX2VudW0ocHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RDb25mbGljdGluZ0VudW1OYW1lc19OZXN0ZWRDb25mbGljdGluZ0VudW1fWE9SKTsKKyAgRVhQRUNUX0VRKDUsIG1lc3NhZ2UuY29uZmxpY3RpbmdfZW51bSgpKTsKKworCisgIHByb3RvYnVmX3VuaXR0ZXN0OjpDb25mbGljdGluZ0VudW0gY29uZmxpY3RpbmdfZW51bTsKKyAgY29uZmxpY3RpbmdfZW51bSA9IHByb3RvYnVmX3VuaXR0ZXN0OjpOT1RfRVE7CisgIEVYUEVDVF9FUSgxLCBjb25mbGljdGluZ19lbnVtKTsKKyAgY29uZmxpY3RpbmdfZW51bSA9IHByb3RvYnVmX3VuaXR0ZXN0OjpyZXR1cm5fOworICBFWFBFQ1RfRVEoMywgY29uZmxpY3RpbmdfZW51bSk7Cit9CisKKyNpZm5kZWYgUFJPVE9CVUZfVEVTVF9OT19ERVNDUklQVE9SUworCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VUZXN0LCBUZXN0T3B0aW1pemVkRm9yU2l6ZSkgeworICAvLyBXZSByZWx5IG9uIHRoZSB0ZXN0cyBpbiByZWZsZWN0aW9uX29wc191bml0dGVzdCBhbmQgd2lyZV9mb3JtYXRfdW5pdHRlc3QKKyAgLy8gdG8gcmVhbGx5IHRlc3QgdGhhdCByZWZsZWN0aW9uLWJhc2VkIG1ldGhvZHMgd29yay4gIEhlcmUgd2UgYXJlIG1vc3RseQorICAvLyBqdXN0IG1ha2luZyBzdXJlIHRoYXQgVGVzdE9wdGltaXplZEZvclNpemUgYWN0dWFsbHkgYnVpbGRzIGFuZCBzZWVtcyB0bworICAvLyBmdW5jdGlvbi4KKworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdE9wdGltaXplZEZvclNpemUgbWVzc2FnZSwgbWVzc2FnZTI7CisgIG1lc3NhZ2Uuc2V0X2koMSk7CisgIG1lc3NhZ2UubXV0YWJsZV9tc2coKS0+c2V0X2MoMik7CisgIG1lc3NhZ2UyLkNvcHlGcm9tKG1lc3NhZ2UpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZTIuaSgpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UyLm1zZygpLmMoKSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVRlc3QsIFRlc3RFbWJlZE9wdGltaXplZEZvclNpemUpIHsKKyAgLy8gVmVyaWZpZXMgdGhhdCBzb21ldGhpbmcgb3B0aW1pemVkIGZvciBzcGVlZCBjYW4gY29udGFpbiBzb21ldGhpbmcgb3B0aW1pemVkCisgIC8vIGZvciBzaXplLgorCisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0RW1iZWRPcHRpbWl6ZWRGb3JTaXplIG1lc3NhZ2UsIG1lc3NhZ2UyOworICBtZXNzYWdlLm11dGFibGVfb3B0aW9uYWxfbWVzc2FnZSgpLT5zZXRfaSgxKTsKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfbWVzc2FnZSgpLT5tdXRhYmxlX21zZygpLT5zZXRfYygyKTsKKyAgc3RyaW5nIGRhdGE7CisgIG1lc3NhZ2UuU2VyaWFsaXplVG9TdHJpbmcoJmRhdGEpOworICBBU1NFUlRfVFJVRShtZXNzYWdlMi5QYXJzZUZyb21TdHJpbmcoZGF0YSkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZTIub3B0aW9uYWxfbWVzc2FnZSgpLmkoKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlMi5yZXBlYXRlZF9tZXNzYWdlKDApLm1zZygpLmMoKSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVRlc3QsIFRlc3RTcGFjZVVzZWQpIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlMTsKKyAgLy8gc2l6ZW9mIHByb3ZpZGVzIGEgbG93ZXIgYm91bmQgb24gU3BhY2VVc2VkKCkuCisgIEVYUEVDVF9MRShzaXplb2YodW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyksIG1lc3NhZ2UxLlNwYWNlVXNlZCgpKTsKKyAgY29uc3QgaW50IGVtcHR5X21lc3NhZ2Vfc2l6ZSA9IG1lc3NhZ2UxLlNwYWNlVXNlZCgpOworCisgIC8vIFNldHRpbmcgcHJpbWl0aXZlIHR5cGVzIHNob3VsZG4ndCBhZmZlY3QgdGhlIHNwYWNlIHVzZWQuCisgIG1lc3NhZ2UxLnNldF9vcHRpb25hbF9pbnQzMigxMjMpOworICBtZXNzYWdlMS5zZXRfb3B0aW9uYWxfaW50NjQoMTIzNDUpOworICBtZXNzYWdlMS5zZXRfb3B0aW9uYWxfdWludDMyKDEyMyk7CisgIG1lc3NhZ2UxLnNldF9vcHRpb25hbF91aW50NjQoMTIzNDUpOworICBFWFBFQ1RfRVEoZW1wdHlfbWVzc2FnZV9zaXplLCBtZXNzYWdlMS5TcGFjZVVzZWQoKSk7CisKKyAgLy8gT24gc29tZSBTVEwgaW1wbGVtZW50YXRpb25zLCBzZXR0aW5nIHRoZSBzdHJpbmcgdG8gYSBzbWFsbCB2YWx1ZSBzaG91bGQKKyAgLy8gb25seSBpbmNyZWFzZSBTcGFjZVVzZWQoKSBieSB0aGUgc2l6ZSBvZiBhIHN0cmluZyBvYmplY3QsIHRob3VnaCB0aGlzIGlzCisgIC8vIG5vdCB0cnVlIGV2ZXJ5d2hlcmUuCisgIG1lc3NhZ2UxLnNldF9vcHRpb25hbF9zdHJpbmcoImFiYyIpOworICBFWFBFQ1RfTEUoZW1wdHlfbWVzc2FnZV9zaXplICsgc2l6ZW9mKHN0cmluZyksIG1lc3NhZ2UxLlNwYWNlVXNlZCgpKTsKKworICAvLyBTZXR0aW5nIGEgc3RyaW5nIHRvIGEgdmFsdWUgbGFyZ2VyIHRoYW4gdGhlIHN0cmluZyBvYmplY3QgaXRzZWxmIHNob3VsZAorICAvLyBpbmNyZWFzZSBTcGFjZVVzZWQoKSwgYmVjYXVzZSBpdCBjYW5ub3Qgc3RvcmUgdGhlIHZhbHVlIGludGVybmFsbHkuCisgIG1lc3NhZ2UxLnNldF9vcHRpb25hbF9zdHJpbmcoc3RyaW5nKHNpemVvZihzdHJpbmcpICsgMSwgJ3gnKSk7CisgIGludCBtaW5fZXhwZWN0ZWRfaW5jcmVhc2UgPSBtZXNzYWdlMS5vcHRpb25hbF9zdHJpbmcoKS5jYXBhY2l0eSgpICsKKyAgICAgIHNpemVvZihzdHJpbmcpOworICBFWFBFQ1RfTEUoZW1wdHlfbWVzc2FnZV9zaXplICsgbWluX2V4cGVjdGVkX2luY3JlYXNlLAorICAgICAgICAgICAgbWVzc2FnZTEuU3BhY2VVc2VkKCkpOworCisgIGludCBwcmV2aW91c19zaXplID0gbWVzc2FnZTEuU3BhY2VVc2VkKCk7CisgIC8vIEFkZGluZyBhbiBvcHRpb25hbCBtZXNzYWdlIHNob3VsZCBpbmNyZWFzZSB0aGUgc2l6ZSBieSB0aGUgc2l6ZSBvZiB0aGUKKyAgLy8gbmVzdGVkIG1lc3NhZ2UgdHlwZS4gTmVzdGVkTWVzc2FnZSBpcyBzaW1wbGUgZW5vdWdoICgxIGludCBmaWVsZCkgdGhhdCBpdAorICAvLyBpcyBlcXVhbCB0byBzaXplb2YoTmVzdGVkTWVzc2FnZSkKKyAgbWVzc2FnZTEubXV0YWJsZV9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpOworICBBU1NFUlRfRVEoc2l6ZW9mKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2UpLAorICAgICAgICAgICAgbWVzc2FnZTEub3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKS5TcGFjZVVzZWQoKSk7CisgIEVYUEVDVF9FUShwcmV2aW91c19zaXplICsKKyAgICAgICAgICAgIHNpemVvZih1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlKSwKKyAgICAgICAgICAgIG1lc3NhZ2UxLlNwYWNlVXNlZCgpKTsKK30KKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlVGVzdCwgVGVzdE9uZW9mU3BhY2VVc2VkKSB7CisgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIG1lc3NhZ2UxOworICBFWFBFQ1RfTEUoc2l6ZW9mKHVuaXR0ZXN0OjpUZXN0T25lb2YyKSwgbWVzc2FnZTEuU3BhY2VVc2VkKCkpOworCisgIGNvbnN0IGludCBlbXB0eV9tZXNzYWdlX3NpemUgPSBtZXNzYWdlMS5TcGFjZVVzZWQoKTsKKyAgLy8gU2V0dGluZyBwcmltaXRpdmUgdHlwZXMgc2hvdWxkbid0IGFmZmVjdCB0aGUgc3BhY2UgdXNlZC4KKyAgbWVzc2FnZTEuc2V0X2Zvb19pbnQoMTIzKTsKKyAgbWVzc2FnZTEuc2V0X2Jhcl9pbnQoMTIzNDUpOworICBFWFBFQ1RfRVEoZW1wdHlfbWVzc2FnZV9zaXplLCBtZXNzYWdlMS5TcGFjZVVzZWQoKSk7CisKKyAgLy8gU2V0dGluZyBhIHN0cmluZyBpbiBvbmVvZiB0byBhIHNtYWxsIHZhbHVlIHNob3VsZCBvbmx5IGluY3JlYXNlIFNwYWNlVXNlZCgpCisgIC8vIGJ5IHRoZSBzaXplIG9mIGEgc3RyaW5nIG9iamVjdC4KKyAgbWVzc2FnZTEuc2V0X2Zvb19zdHJpbmcoImFiYyIpOworICBFWFBFQ1RfTEUoZW1wdHlfbWVzc2FnZV9zaXplICsgc2l6ZW9mKHN0cmluZyksIG1lc3NhZ2UxLlNwYWNlVXNlZCgpKTsKKworICAvLyBTZXR0aW5nIGEgc3RyaW5nIGluIG9uZW9mIHRvIGEgdmFsdWUgbGFyZ2VyIHRoYW4gdGhlIHN0cmluZyBvYmplY3QgaXRzZWxmCisgIC8vIHNob3VsZCBpbmNyZWFzZSBTcGFjZVVzZWQoKSwgYmVjYXVzZSBpdCBjYW5ub3Qgc3RvcmUgdGhlIHZhbHVlIGludGVybmFsbHkuCisgIG1lc3NhZ2UxLnNldF9mb29fc3RyaW5nKHN0cmluZyhzaXplb2Yoc3RyaW5nKSArIDEsICd4JykpOworICBpbnQgbWluX2V4cGVjdGVkX2luY3JlYXNlID0gbWVzc2FnZTEuZm9vX3N0cmluZygpLmNhcGFjaXR5KCkgKworICAgICAgc2l6ZW9mKHN0cmluZyk7CisgIEVYUEVDVF9MRShlbXB0eV9tZXNzYWdlX3NpemUgKyBtaW5fZXhwZWN0ZWRfaW5jcmVhc2UsCisgICAgICAgICAgICBtZXNzYWdlMS5TcGFjZVVzZWQoKSk7CisKKyAgLy8gU2V0dGluZyBhIG1lc3NhZ2UgaW4gb25lb2Ygc2hvdWxkIGRlbGV0ZSB0aGUgb3RoZXIgZmllbGRzIGFuZCBpbmNyZWFzZSB0aGUKKyAgLy8gc2l6ZSBieSB0aGUgc2l6ZSBvZiB0aGUgbmVzdGVkIG1lc3NhZ2UgdHlwZS4gTmVzdGVkTWVzc2FnZSBpcyBzaW1wbGUgZW5vdWdoCisgIC8vIHRoYXQgaXQgaXMgZXF1YWwgdG8gc2l6ZW9mKE5lc3RlZE1lc3NhZ2UpCisgIG1lc3NhZ2UxLm11dGFibGVfZm9vX21lc3NhZ2UoKTsKKyAgQVNTRVJUX0VRKHNpemVvZih1bml0dGVzdDo6VGVzdE9uZW9mMjo6TmVzdGVkTWVzc2FnZSksCisgICAgICAgICAgICBtZXNzYWdlMS5mb29fbWVzc2FnZSgpLlNwYWNlVXNlZCgpKTsKKyAgRVhQRUNUX0VRKGVtcHR5X21lc3NhZ2Vfc2l6ZSArCisgICAgICAgICAgICBzaXplb2YodW5pdHRlc3Q6OlRlc3RPbmVvZjI6Ok5lc3RlZE1lc3NhZ2UpLAorICAgICAgICAgICAgbWVzc2FnZTEuU3BhY2VVc2VkKCkpOworfQorCisjZW5kaWYgIC8vICFQUk9UT0JVRl9URVNUX05PX0RFU0NSSVBUT1JTCisKKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlVGVzdCwgRmllbGRDb25zdGFudFZhbHVlcykgeworICB1bml0dGVzdDo6VGVzdFJlcXVpcmVkIG1lc3NhZ2U7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzX05lc3RlZE1lc3NhZ2U6OmtCYkZpZWxkTnVtYmVyLCAxKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OmtPcHRpb25hbEludDMyRmllbGROdW1iZXIsIDEpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6a09wdGlvbmFsZ3JvdXBGaWVsZE51bWJlciwgMTYpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6a09wdGlvbmFsTmVzdGVkTWVzc2FnZUZpZWxkTnVtYmVyLCAxOCk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjprT3B0aW9uYWxOZXN0ZWRFbnVtRmllbGROdW1iZXIsIDIxKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OmtSZXBlYXRlZEludDMyRmllbGROdW1iZXIsIDMxKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OmtSZXBlYXRlZGdyb3VwRmllbGROdW1iZXIsIDQ2KTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OmtSZXBlYXRlZE5lc3RlZE1lc3NhZ2VGaWVsZE51bWJlciwgNDgpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6a1JlcGVhdGVkTmVzdGVkRW51bUZpZWxkTnVtYmVyLCA1MSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVRlc3QsIEV4dGVuc2lvbkNvbnN0YW50VmFsdWVzKSB7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdFJlcXVpcmVkOjprU2luZ2xlRmllbGROdW1iZXIsIDEwMDApOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RSZXF1aXJlZDo6a011bHRpRmllbGROdW1iZXIsIDEwMDEpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OmtPcHRpb25hbEludDMyRXh0ZW5zaW9uRmllbGROdW1iZXIsIDEpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OmtPcHRpb25hbGdyb3VwRXh0ZW5zaW9uRmllbGROdW1iZXIsIDE2KTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjprT3B0aW9uYWxOZXN0ZWRNZXNzYWdlRXh0ZW5zaW9uRmllbGROdW1iZXIsIDE4KTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjprT3B0aW9uYWxOZXN0ZWRFbnVtRXh0ZW5zaW9uRmllbGROdW1iZXIsIDIxKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjprUmVwZWF0ZWRJbnQzMkV4dGVuc2lvbkZpZWxkTnVtYmVyLCAzMSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6a1JlcGVhdGVkZ3JvdXBFeHRlbnNpb25GaWVsZE51bWJlciwgNDYpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OmtSZXBlYXRlZE5lc3RlZE1lc3NhZ2VFeHRlbnNpb25GaWVsZE51bWJlciwgNDgpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OmtSZXBlYXRlZE5lc3RlZEVudW1FeHRlbnNpb25GaWVsZE51bWJlciwgNTEpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VUZXN0LCBQYXJzZUZyb21UcnVuY2F0ZWQpIHsKKyAgY29uc3Qgc3RyaW5nIGxvbmdfc3RyaW5nID0gc3RyaW5nKDEyOCwgJ3EnKTsKKyAgRmlsZURlc2NyaXB0b3JQcm90byBwOworICBwLmFkZF9leHRlbnNpb24oKS0+c2V0X25hbWUobG9uZ19zdHJpbmcpOworICBjb25zdCBzdHJpbmcgbXNnID0gcC5TZXJpYWxpemVBc1N0cmluZygpOworICBpbnQgc3VjY2Vzc2Z1bF9jb3VudCA9IDA7CisgIGZvciAoaW50IGkgPSAwOyBpIDw9IG1zZy5zaXplKCk7IGkrKykgeworICAgIGlmIChwLlBhcnNlRnJvbUFycmF5KG1zZy5jX3N0cigpLCBpKSkgeworICAgICAgKytzdWNjZXNzZnVsX2NvdW50OworICAgIH0KKyAgfQorICAvLyBXZSBkb24ndCByZWFsbHkgY2FyZSBhYm91dCBob3cgb2Z0ZW4gd2Ugc3VjY2VlZGVkLgorICAvLyBBcyBsb25nIGFzIHdlIGRpZG4ndCBjcmFzaCwgd2UncmUgaGFwcHkuCisgIEVYUEVDVF9HRShzdWNjZXNzZnVsX2NvdW50LCAxKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitURVNUKEdlbmVyYXRlZEVudW1UZXN0LCBFbnVtVmFsdWVzQXNTd2l0Y2hDYXNlcykgeworICAvLyBUZXN0IHRoYXQgb3VyIG5lc3RlZCBlbnVtIHZhbHVlcyBjYW4gYmUgdXNlZCBhcyBzd2l0Y2ggY2FzZXMuICBUaGlzIHRlc3QKKyAgLy8gZG9lc24ndCBhY3R1YWxseSBkbyBhbnl0aGluZywgdGhlIHByb29mIHRoYXQgaXQgd29ya3MgaXMgdGhhdCBpdAorICAvLyBjb21waWxlcy4KKyAgaW50IGkgPTA7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5lc3RlZEVudW0gYSA9IHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkJBUjsKKyAgc3dpdGNoIChhKSB7CisgICAgY2FzZSB1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpGT086CisgICAgICBpID0gMTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6QkFSOgorICAgICAgaSA9IDI7CisgICAgICBicmVhazsKKyAgICBjYXNlIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkJBWjoKKyAgICAgIGkgPSAzOworICAgICAgYnJlYWs7CisgICAgY2FzZSB1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpORUc6CisgICAgICBpID0gLTE7CisgICAgICBicmVhazsKKyAgICAvLyBubyBkZWZhdWx0IGNhc2U6ICBXZSB3YW50IHRvIG1ha2Ugc3VyZSB0aGUgY29tcGlsZXIgcmVjb2duaXplcyB0aGF0CisgICAgLy8gICBhbGwgY2FzZXMgYXJlIGNvdmVyZWQuICAoR0NDIHdhcm5zIGlmIHlvdSBkbyBub3QgY292ZXIgYWxsIGNhc2VzIG9mCisgICAgLy8gICBhbiBlbnVtIGluIGEgc3dpdGNoLikKKyAgfQorCisgIC8vIFRva2VuIGNoZWNrIGp1c3QgZm9yIGZ1bi4KKyAgRVhQRUNUX0VRKDIsIGkpOworfQorCitURVNUKEdlbmVyYXRlZEVudW1UZXN0LCBJc1ZhbGlkVmFsdWUpIHsKKyAgLy8gVGVzdCBlbnVtIElzVmFsaWRWYWx1ZS4KKyAgRVhQRUNUX1RSVUUodW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6TmVzdGVkRW51bV9Jc1ZhbGlkKDEpKTsKKyAgRVhQRUNUX1RSVUUodW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6TmVzdGVkRW51bV9Jc1ZhbGlkKDIpKTsKKyAgRVhQRUNUX1RSVUUodW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6TmVzdGVkRW51bV9Jc1ZhbGlkKDMpKTsKKworICBFWFBFQ1RfRkFMU0UodW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6TmVzdGVkRW51bV9Jc1ZhbGlkKDApKTsKKyAgRVhQRUNUX0ZBTFNFKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5lc3RlZEVudW1fSXNWYWxpZCg0KSk7CisKKyAgLy8gTWFrZSBzdXJlIGl0IGFsc28gd29ya3Mgd2hlbiB0aGVyZSBhcmUgZHVwcy4KKyAgRVhQRUNUX1RSVUUodW5pdHRlc3Q6OlRlc3RFbnVtV2l0aER1cFZhbHVlX0lzVmFsaWQoMSkpOworICBFWFBFQ1RfVFJVRSh1bml0dGVzdDo6VGVzdEVudW1XaXRoRHVwVmFsdWVfSXNWYWxpZCgyKSk7CisgIEVYUEVDVF9UUlVFKHVuaXR0ZXN0OjpUZXN0RW51bVdpdGhEdXBWYWx1ZV9Jc1ZhbGlkKDMpKTsKKworICBFWFBFQ1RfRkFMU0UodW5pdHRlc3Q6OlRlc3RFbnVtV2l0aER1cFZhbHVlX0lzVmFsaWQoMCkpOworICBFWFBFQ1RfRkFMU0UodW5pdHRlc3Q6OlRlc3RFbnVtV2l0aER1cFZhbHVlX0lzVmFsaWQoNCkpOworfQorCitURVNUKEdlbmVyYXRlZEVudW1UZXN0LCBNaW5BbmRNYXgpIHsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5FRywKKyAgICAgICAgICAgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5lc3RlZEVudW1fTUlOKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkJBWiwKKyAgICAgICAgICAgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5lc3RlZEVudW1fTUFYKTsKKyAgRVhQRUNUX0VRKDQsIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5lc3RlZEVudW1fQVJSQVlTSVpFKTsKKworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fRk9PLCB1bml0dGVzdDo6Rm9yZWlnbkVudW1fTUlOKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0JBWiwgdW5pdHRlc3Q6OkZvcmVpZ25FbnVtX01BWCk7CisgIEVYUEVDVF9FUSg3LCB1bml0dGVzdDo6Rm9yZWlnbkVudW1fQVJSQVlTSVpFKTsKKworICBFWFBFQ1RfRVEoMSwgdW5pdHRlc3Q6OlRlc3RFbnVtV2l0aER1cFZhbHVlX01JTik7CisgIEVYUEVDVF9FUSgzLCB1bml0dGVzdDo6VGVzdEVudW1XaXRoRHVwVmFsdWVfTUFYKTsKKyAgRVhQRUNUX0VRKDQsIHVuaXR0ZXN0OjpUZXN0RW51bVdpdGhEdXBWYWx1ZV9BUlJBWVNJWkUpOworCisgIEVYUEVDVF9FUSh1bml0dGVzdDo6U1BBUlNFX0UsIHVuaXR0ZXN0OjpUZXN0U3BhcnNlRW51bV9NSU4pOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlNQQVJTRV9DLCB1bml0dGVzdDo6VGVzdFNwYXJzZUVudW1fTUFYKTsKKyAgRVhQRUNUX0VRKDEyNTg5MjM1LCB1bml0dGVzdDo6VGVzdFNwYXJzZUVudW1fQVJSQVlTSVpFKTsKKworICAvLyBNYWtlIHN1cmUgd2UgY2FuIHRha2UgdGhlIGFkZHJlc3Mgb2YgX01JTiwgX01BWCBhbmQgX0FSUkFZU0laRS4KKyAgdm9pZCogbnVsbF9wb2ludGVyID0gMDsgIC8vIE5VTEwgbWF5IGJlIGludGVnZXItdHlwZSwgbm90IHBvaW50ZXItdHlwZS4KKyAgRVhQRUNUX05FKG51bGxfcG9pbnRlciwgJnVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5lc3RlZEVudW1fTUlOKTsKKyAgRVhQRUNUX05FKG51bGxfcG9pbnRlciwgJnVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5lc3RlZEVudW1fTUFYKTsKKyAgRVhQRUNUX05FKG51bGxfcG9pbnRlciwgJnVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5lc3RlZEVudW1fQVJSQVlTSVpFKTsKKworICBFWFBFQ1RfTkUobnVsbF9wb2ludGVyLCAmdW5pdHRlc3Q6OkZvcmVpZ25FbnVtX01JTik7CisgIEVYUEVDVF9ORShudWxsX3BvaW50ZXIsICZ1bml0dGVzdDo6Rm9yZWlnbkVudW1fTUFYKTsKKyAgRVhQRUNUX05FKG51bGxfcG9pbnRlciwgJnVuaXR0ZXN0OjpGb3JlaWduRW51bV9BUlJBWVNJWkUpOworCisgIC8vIE1ha2Ugc3VyZSB3ZSBjYW4gdXNlIF9NSU4gYW5kIF9NQVggYXMgc3dpdGNoIGNhc2VzLgorICBzd2l0Y2ggKHVuaXR0ZXN0OjpTUEFSU0VfQSkgeworICAgIGNhc2UgdW5pdHRlc3Q6OlRlc3RTcGFyc2VFbnVtX01JTjoKKyAgICBjYXNlIHVuaXR0ZXN0OjpUZXN0U3BhcnNlRW51bV9NQVg6CisgICAgICBicmVhazsKKyAgICBkZWZhdWx0OgorICAgICAgYnJlYWs7CisgIH0KK30KKworI2lmbmRlZiBQUk9UT0JVRl9URVNUX05PX0RFU0NSSVBUT1JTCisKK1RFU1QoR2VuZXJhdGVkRW51bVRlc3QsIE5hbWUpIHsKKyAgLy8gIk5hbWVzIiBpbiB0aGUgcHJlc2VuY2Ugb2YgZHVwIHZhbHVlcyBhcmUgYSBiaXQgYXJiaXRyYXJ5LgorICBFWFBFQ1RfRVEoIkZPTzEiLCB1bml0dGVzdDo6VGVzdEVudW1XaXRoRHVwVmFsdWVfTmFtZSh1bml0dGVzdDo6Rk9PMSkpOworICBFWFBFQ1RfRVEoIkZPTzEiLCB1bml0dGVzdDo6VGVzdEVudW1XaXRoRHVwVmFsdWVfTmFtZSh1bml0dGVzdDo6Rk9PMikpOworCisgIEVYUEVDVF9FUSgiU1BBUlNFX0EiLCB1bml0dGVzdDo6VGVzdFNwYXJzZUVudW1fTmFtZSh1bml0dGVzdDo6U1BBUlNFX0EpKTsKKyAgRVhQRUNUX0VRKCJTUEFSU0VfQiIsIHVuaXR0ZXN0OjpUZXN0U3BhcnNlRW51bV9OYW1lKHVuaXR0ZXN0OjpTUEFSU0VfQikpOworICBFWFBFQ1RfRVEoIlNQQVJTRV9DIiwgdW5pdHRlc3Q6OlRlc3RTcGFyc2VFbnVtX05hbWUodW5pdHRlc3Q6OlNQQVJTRV9DKSk7CisgIEVYUEVDVF9FUSgiU1BBUlNFX0QiLCB1bml0dGVzdDo6VGVzdFNwYXJzZUVudW1fTmFtZSh1bml0dGVzdDo6U1BBUlNFX0QpKTsKKyAgRVhQRUNUX0VRKCJTUEFSU0VfRSIsIHVuaXR0ZXN0OjpUZXN0U3BhcnNlRW51bV9OYW1lKHVuaXR0ZXN0OjpTUEFSU0VfRSkpOworICBFWFBFQ1RfRVEoIlNQQVJTRV9GIiwgdW5pdHRlc3Q6OlRlc3RTcGFyc2VFbnVtX05hbWUodW5pdHRlc3Q6OlNQQVJTRV9GKSk7CisgIEVYUEVDVF9FUSgiU1BBUlNFX0ciLCB1bml0dGVzdDo6VGVzdFNwYXJzZUVudW1fTmFtZSh1bml0dGVzdDo6U1BBUlNFX0cpKTsKK30KKworVEVTVChHZW5lcmF0ZWRFbnVtVGVzdCwgUGFyc2UpIHsKKyAgdW5pdHRlc3Q6OlRlc3RFbnVtV2l0aER1cFZhbHVlIGR1cF92YWx1ZSA9IHVuaXR0ZXN0OjpGT08xOworICBFWFBFQ1RfVFJVRSh1bml0dGVzdDo6VGVzdEVudW1XaXRoRHVwVmFsdWVfUGFyc2UoIkZPTzEiLCAmZHVwX3ZhbHVlKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9PMSwgZHVwX3ZhbHVlKTsKKyAgRVhQRUNUX1RSVUUodW5pdHRlc3Q6OlRlc3RFbnVtV2l0aER1cFZhbHVlX1BhcnNlKCJGT08yIiwgJmR1cF92YWx1ZSkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPTzIsIGR1cF92YWx1ZSk7CisgIEVYUEVDVF9GQUxTRSh1bml0dGVzdDo6VGVzdEVudW1XaXRoRHVwVmFsdWVfUGFyc2UoIkZPTyIsICZkdXBfdmFsdWUpKTsKK30KKworVEVTVChHZW5lcmF0ZWRFbnVtVGVzdCwgR2V0RW51bURlc2NyaXB0b3IpIHsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5lc3RlZEVudW1fZGVzY3JpcHRvcigpLAorICAgICAgICAgICAgR2V0RW51bURlc2NyaXB0b3I8dW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6TmVzdGVkRW51bT4oKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rm9yZWlnbkVudW1fZGVzY3JpcHRvcigpLAorICAgICAgICAgICAgR2V0RW51bURlc2NyaXB0b3I8dW5pdHRlc3Q6OkZvcmVpZ25FbnVtPigpKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0RW51bVdpdGhEdXBWYWx1ZV9kZXNjcmlwdG9yKCksCisgICAgICAgICAgICBHZXRFbnVtRGVzY3JpcHRvcjx1bml0dGVzdDo6VGVzdEVudW1XaXRoRHVwVmFsdWU+KCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RTcGFyc2VFbnVtX2Rlc2NyaXB0b3IoKSwKKyAgICAgICAgICAgIEdldEVudW1EZXNjcmlwdG9yPHVuaXR0ZXN0OjpUZXN0U3BhcnNlRW51bT4oKSk7Cit9CisKK2VudW0gTm9uUHJvdG9FbnVtIHsKKyAga0ZvbyA9IDEsCit9OworCitURVNUKEdlbmVyYXRlZEVudW1UZXN0LCBJc1Byb3RvRW51bVR5cGVUcmFpdCkgeworICBFWFBFQ1RfVFJVRShpc19wcm90b19lbnVtPHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5lc3RlZEVudW0+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGlzX3Byb3RvX2VudW08dW5pdHRlc3Q6OkZvcmVpZ25FbnVtPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShpc19wcm90b19lbnVtPHVuaXR0ZXN0OjpUZXN0RW51bVdpdGhEdXBWYWx1ZT46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfcHJvdG9fZW51bTx1bml0dGVzdDo6VGVzdFNwYXJzZUVudW0+Ojp2YWx1ZSk7CisKKyAgRVhQRUNUX0ZBTFNFKGlzX3Byb3RvX2VudW08aW50Pjo6dmFsdWUpOworICBFWFBFQ1RfRkFMU0UoaXNfcHJvdG9fZW51bTxOb25Qcm90b0VudW0+Ojp2YWx1ZSk7Cit9CisKKyNlbmRpZiAgLy8gUFJPVE9CVUZfVEVTVF9OT19ERVNDUklQVE9SUworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKyNpZm5kZWYgUFJPVE9CVUZfVEVTVF9OT19ERVNDUklQVE9SUworCisvLyBTdXBwb3J0IGNvZGUgZm9yIHRlc3Rpbmcgc2VydmljZXMuCitjbGFzcyBHZW5lcmF0ZWRTZXJ2aWNlVGVzdCA6IHB1YmxpYyB0ZXN0aW5nOjpUZXN0IHsKKyBwcm90ZWN0ZWQ6CisgIGNsYXNzIE1vY2tUZXN0U2VydmljZSA6IHB1YmxpYyB1bml0dGVzdDo6VGVzdFNlcnZpY2UgeworICAgcHVibGljOgorICAgIE1vY2tUZXN0U2VydmljZSgpCisgICAgICA6IGNhbGxlZF8oZmFsc2UpLAorICAgICAgICBtZXRob2RfKCIiKSwKKyAgICAgICAgY29udHJvbGxlcl8oTlVMTCksCisgICAgICAgIHJlcXVlc3RfKE5VTEwpLAorICAgICAgICByZXNwb25zZV8oTlVMTCksCisgICAgICAgIGRvbmVfKE5VTEwpIHt9CisKKyAgICB+TW9ja1Rlc3RTZXJ2aWNlKCkge30KKworICAgIHZvaWQgUmVzZXQoKSB7IGNhbGxlZF8gPSBmYWxzZTsgfQorCisgICAgLy8gaW1wbGVtZW50cyBUZXN0U2VydmljZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgICB2b2lkIEZvbyhScGNDb250cm9sbGVyKiBjb250cm9sbGVyLAorICAgICAgICAgICAgIGNvbnN0IHVuaXR0ZXN0OjpGb29SZXF1ZXN0KiByZXF1ZXN0LAorICAgICAgICAgICAgIHVuaXR0ZXN0OjpGb29SZXNwb25zZSogcmVzcG9uc2UsCisgICAgICAgICAgICAgQ2xvc3VyZSogZG9uZSkgeworICAgICAgQVNTRVJUX0ZBTFNFKGNhbGxlZF8pOworICAgICAgY2FsbGVkXyA9IHRydWU7CisgICAgICBtZXRob2RfID0gIkZvbyI7CisgICAgICBjb250cm9sbGVyXyA9IGNvbnRyb2xsZXI7CisgICAgICByZXF1ZXN0XyA9IHJlcXVlc3Q7CisgICAgICByZXNwb25zZV8gPSByZXNwb25zZTsKKyAgICAgIGRvbmVfID0gZG9uZTsKKyAgICB9CisKKyAgICB2b2lkIEJhcihScGNDb250cm9sbGVyKiBjb250cm9sbGVyLAorICAgICAgICAgICAgIGNvbnN0IHVuaXR0ZXN0OjpCYXJSZXF1ZXN0KiByZXF1ZXN0LAorICAgICAgICAgICAgIHVuaXR0ZXN0OjpCYXJSZXNwb25zZSogcmVzcG9uc2UsCisgICAgICAgICAgICAgQ2xvc3VyZSogZG9uZSkgeworICAgICAgQVNTRVJUX0ZBTFNFKGNhbGxlZF8pOworICAgICAgY2FsbGVkXyA9IHRydWU7CisgICAgICBtZXRob2RfID0gIkJhciI7CisgICAgICBjb250cm9sbGVyXyA9IGNvbnRyb2xsZXI7CisgICAgICByZXF1ZXN0XyA9IHJlcXVlc3Q7CisgICAgICByZXNwb25zZV8gPSByZXNwb25zZTsKKyAgICAgIGRvbmVfID0gZG9uZTsKKyAgICB9CisKKyAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgIGJvb2wgY2FsbGVkXzsKKyAgICBzdHJpbmcgbWV0aG9kXzsKKyAgICBScGNDb250cm9sbGVyKiBjb250cm9sbGVyXzsKKyAgICBjb25zdCBNZXNzYWdlKiByZXF1ZXN0XzsKKyAgICBNZXNzYWdlKiByZXNwb25zZV87CisgICAgQ2xvc3VyZSogZG9uZV87CisgIH07CisKKyAgY2xhc3MgTW9ja1JwY0NoYW5uZWwgOiBwdWJsaWMgUnBjQ2hhbm5lbCB7CisgICBwdWJsaWM6CisgICAgTW9ja1JwY0NoYW5uZWwoKQorICAgICAgOiBjYWxsZWRfKGZhbHNlKSwKKyAgICAgICAgbWV0aG9kXyhOVUxMKSwKKyAgICAgICAgY29udHJvbGxlcl8oTlVMTCksCisgICAgICAgIHJlcXVlc3RfKE5VTEwpLAorICAgICAgICByZXNwb25zZV8oTlVMTCksCisgICAgICAgIGRvbmVfKE5VTEwpLAorICAgICAgICBkZXN0cm95ZWRfKE5VTEwpIHt9CisKKyAgICB+TW9ja1JwY0NoYW5uZWwoKSB7CisgICAgICBpZiAoZGVzdHJveWVkXyAhPSBOVUxMKSAqZGVzdHJveWVkXyA9IHRydWU7CisgICAgfQorCisgICAgdm9pZCBSZXNldCgpIHsgY2FsbGVkXyA9IGZhbHNlOyB9CisKKyAgICAvLyBpbXBsZW1lbnRzIFRlc3RTZXJ2aWNlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgIHZvaWQgQ2FsbE1ldGhvZChjb25zdCBNZXRob2REZXNjcmlwdG9yKiBtZXRob2QsCisgICAgICAgICAgICAgICAgICAgIFJwY0NvbnRyb2xsZXIqIGNvbnRyb2xsZXIsCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2UqIHJlcXVlc3QsCisgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UqIHJlc3BvbnNlLAorICAgICAgICAgICAgICAgICAgICBDbG9zdXJlKiBkb25lKSB7CisgICAgICBBU1NFUlRfRkFMU0UoY2FsbGVkXyk7CisgICAgICBjYWxsZWRfID0gdHJ1ZTsKKyAgICAgIG1ldGhvZF8gPSBtZXRob2Q7CisgICAgICBjb250cm9sbGVyXyA9IGNvbnRyb2xsZXI7CisgICAgICByZXF1ZXN0XyA9IHJlcXVlc3Q7CisgICAgICByZXNwb25zZV8gPSByZXNwb25zZTsKKyAgICAgIGRvbmVfID0gZG9uZTsKKyAgICB9CisKKyAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgIGJvb2wgY2FsbGVkXzsKKyAgICBjb25zdCBNZXRob2REZXNjcmlwdG9yKiBtZXRob2RfOworICAgIFJwY0NvbnRyb2xsZXIqIGNvbnRyb2xsZXJfOworICAgIGNvbnN0IE1lc3NhZ2UqIHJlcXVlc3RfOworICAgIE1lc3NhZ2UqIHJlc3BvbnNlXzsKKyAgICBDbG9zdXJlKiBkb25lXzsKKyAgICBib29sKiBkZXN0cm95ZWRfOworICB9OworCisgIGNsYXNzIE1vY2tDb250cm9sbGVyIDogcHVibGljIFJwY0NvbnRyb2xsZXIgeworICAgcHVibGljOgorICAgIHZvaWQgUmVzZXQoKSB7CisgICAgICBBRERfRkFJTFVSRSgpIDw8ICJSZXNldCgpIG5vdCBleHBlY3RlZCBkdXJpbmcgdGhpcyB0ZXN0LiI7CisgICAgfQorICAgIGJvb2wgRmFpbGVkKCkgY29uc3QgeworICAgICAgQUREX0ZBSUxVUkUoKSA8PCAiRmFpbGVkKCkgbm90IGV4cGVjdGVkIGR1cmluZyB0aGlzIHRlc3QuIjsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgc3RyaW5nIEVycm9yVGV4dCgpIGNvbnN0IHsKKyAgICAgIEFERF9GQUlMVVJFKCkgPDwgIkVycm9yVGV4dCgpIG5vdCBleHBlY3RlZCBkdXJpbmcgdGhpcyB0ZXN0LiI7CisgICAgICByZXR1cm4gIiI7CisgICAgfQorICAgIHZvaWQgU3RhcnRDYW5jZWwoKSB7CisgICAgICBBRERfRkFJTFVSRSgpIDw8ICJTdGFydENhbmNlbCgpIG5vdCBleHBlY3RlZCBkdXJpbmcgdGhpcyB0ZXN0LiI7CisgICAgfQorICAgIHZvaWQgU2V0RmFpbGVkKGNvbnN0IHN0cmluZyYgcmVhc29uKSB7CisgICAgICBBRERfRkFJTFVSRSgpIDw8ICJTZXRGYWlsZWQoKSBub3QgZXhwZWN0ZWQgZHVyaW5nIHRoaXMgdGVzdC4iOworICAgIH0KKyAgICBib29sIElzQ2FuY2VsZWQoKSBjb25zdCB7CisgICAgICBBRERfRkFJTFVSRSgpIDw8ICJJc0NhbmNlbGVkKCkgbm90IGV4cGVjdGVkIGR1cmluZyB0aGlzIHRlc3QuIjsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgdm9pZCBOb3RpZnlPbkNhbmNlbChDbG9zdXJlKiBjYWxsYmFjaykgeworICAgICAgQUREX0ZBSUxVUkUoKSA8PCAiTm90aWZ5T25DYW5jZWwoKSBub3QgZXhwZWN0ZWQgZHVyaW5nIHRoaXMgdGVzdC4iOworICAgIH0KKyAgfTsKKworICBHZW5lcmF0ZWRTZXJ2aWNlVGVzdCgpCisgICAgOiBkZXNjcmlwdG9yXyh1bml0dGVzdDo6VGVzdFNlcnZpY2U6OmRlc2NyaXB0b3IoKSksCisgICAgICBmb29fKGRlc2NyaXB0b3JfLT5GaW5kTWV0aG9kQnlOYW1lKCJGb28iKSksCisgICAgICBiYXJfKGRlc2NyaXB0b3JfLT5GaW5kTWV0aG9kQnlOYW1lKCJCYXIiKSksCisgICAgICBzdHViXygmbW9ja19jaGFubmVsXyksCisgICAgICBkb25lXyhOZXdQZXJtYW5lbnRDYWxsYmFjaygmRG9Ob3RoaW5nKSkge30KKworICB2aXJ0dWFsIHZvaWQgU2V0VXAoKSB7CisgICAgQVNTRVJUX1RSVUUoZm9vXyAhPSBOVUxMKTsKKyAgICBBU1NFUlRfVFJVRShiYXJfICE9IE5VTEwpOworICB9CisKKyAgY29uc3QgU2VydmljZURlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworICBjb25zdCBNZXRob2REZXNjcmlwdG9yKiBmb29fOworICBjb25zdCBNZXRob2REZXNjcmlwdG9yKiBiYXJfOworCisgIE1vY2tUZXN0U2VydmljZSBtb2NrX3NlcnZpY2VfOworICBNb2NrQ29udHJvbGxlciBtb2NrX2NvbnRyb2xsZXJfOworCisgIE1vY2tScGNDaGFubmVsIG1vY2tfY2hhbm5lbF87CisgIHVuaXR0ZXN0OjpUZXN0U2VydmljZTo6U3R1YiBzdHViXzsKKworICAvLyBKdXN0IHNvIHdlIGRvbid0IGhhdmUgdG8gcmUtZGVmaW5lIHRoZXNlIHdpdGggZXZlcnkgdGVzdC4KKyAgdW5pdHRlc3Q6OkZvb1JlcXVlc3QgZm9vX3JlcXVlc3RfOworICB1bml0dGVzdDo6Rm9vUmVzcG9uc2UgZm9vX3Jlc3BvbnNlXzsKKyAgdW5pdHRlc3Q6OkJhclJlcXVlc3QgYmFyX3JlcXVlc3RfOworICB1bml0dGVzdDo6QmFyUmVzcG9uc2UgYmFyX3Jlc3BvbnNlXzsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxDbG9zdXJlPiBkb25lXzsKK307CisKK1RFU1RfRihHZW5lcmF0ZWRTZXJ2aWNlVGVzdCwgR2V0RGVzY3JpcHRvcikgeworICAvLyBUZXN0IHRoYXQgR2V0RGVzY3JpcHRvcigpIHdvcmtzLgorCisgIEVYUEVDVF9FUShkZXNjcmlwdG9yXywgbW9ja19zZXJ2aWNlXy5HZXREZXNjcmlwdG9yKCkpOworfQorCitURVNUX0YoR2VuZXJhdGVkU2VydmljZVRlc3QsIEdldENoYW5uZWwpIHsKKyAgRVhQRUNUX0VRKCZtb2NrX2NoYW5uZWxfLCBzdHViXy5jaGFubmVsKCkpOworfQorCitURVNUX0YoR2VuZXJhdGVkU2VydmljZVRlc3QsIE93bnNDaGFubmVsKSB7CisgIE1vY2tScGNDaGFubmVsKiBjaGFubmVsID0gbmV3IE1vY2tScGNDaGFubmVsOworICBib29sIGRlc3Ryb3llZCA9IGZhbHNlOworICBjaGFubmVsLT5kZXN0cm95ZWRfID0gJmRlc3Ryb3llZDsKKworICB7CisgICAgdW5pdHRlc3Q6OlRlc3RTZXJ2aWNlOjpTdHViIG93bmluZ19zdHViKGNoYW5uZWwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNlcnZpY2U6OlNUVUJfT1dOU19DSEFOTkVMKTsKKyAgICBFWFBFQ1RfRkFMU0UoZGVzdHJveWVkKTsKKyAgfQorCisgIEVYUEVDVF9UUlVFKGRlc3Ryb3llZCk7Cit9CisKK1RFU1RfRihHZW5lcmF0ZWRTZXJ2aWNlVGVzdCwgQ2FsbE1ldGhvZCkgeworICAvLyBUZXN0IHRoYXQgQ2FsbE1ldGhvZCgpIHdvcmtzLgorCisgIC8vIENhbGwgRm9vKCkgdmlhIENhbGxNZXRob2QoKS4KKyAgbW9ja19zZXJ2aWNlXy5DYWxsTWV0aG9kKGZvb18sICZtb2NrX2NvbnRyb2xsZXJfLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgJmZvb19yZXF1ZXN0XywgJmZvb19yZXNwb25zZV8sIGRvbmVfLmdldCgpKTsKKworICBBU1NFUlRfVFJVRShtb2NrX3NlcnZpY2VfLmNhbGxlZF8pOworCisgIEVYUEVDVF9FUSgiRm9vIiAgICAgICAgICAgICwgbW9ja19zZXJ2aWNlXy5tZXRob2RfICAgICk7CisgIEVYUEVDVF9FUSgmbW9ja19jb250cm9sbGVyXywgbW9ja19zZXJ2aWNlXy5jb250cm9sbGVyXyk7CisgIEVYUEVDVF9FUSgmZm9vX3JlcXVlc3RfICAgICwgbW9ja19zZXJ2aWNlXy5yZXF1ZXN0XyAgICk7CisgIEVYUEVDVF9FUSgmZm9vX3Jlc3BvbnNlXyAgICwgbW9ja19zZXJ2aWNlXy5yZXNwb25zZV8gICk7CisgIEVYUEVDVF9FUShkb25lXy5nZXQoKSAgICAgICwgbW9ja19zZXJ2aWNlXy5kb25lXyAgICAgICk7CisKKyAgLy8gVHJ5IGFnYWluLCBidXQgY2FsbCBCYXIoKSBpbnN0ZWFkLgorICBtb2NrX3NlcnZpY2VfLlJlc2V0KCk7CisgIG1vY2tfc2VydmljZV8uQ2FsbE1ldGhvZChiYXJfLCAmbW9ja19jb250cm9sbGVyXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICZiYXJfcmVxdWVzdF8sICZiYXJfcmVzcG9uc2VfLCBkb25lXy5nZXQoKSk7CisKKyAgQVNTRVJUX1RSVUUobW9ja19zZXJ2aWNlXy5jYWxsZWRfKTsKKyAgRVhQRUNUX0VRKCJCYXIiLCBtb2NrX3NlcnZpY2VfLm1ldGhvZF8pOworfQorCitURVNUX0YoR2VuZXJhdGVkU2VydmljZVRlc3QsIENhbGxNZXRob2RUeXBlRmFpbHVyZSkgeworICAvLyBWZXJpZnkgZGVhdGggaWYgd2UgY2FsbCBGb28oKSB3aXRoIEJhcidzIG1lc3NhZ2UgdHlwZXMuCisKKyNpZmRlZiBQUk9UT0JVRl9IQVNfREVBVEhfVEVTVCAgLy8gZGVhdGggdGVzdHMgZG8gbm90IHdvcmsgb24gV2luZG93cyB5ZXQKKyAgRVhQRUNUX0RFQlVHX0RFQVRIKAorICAgIG1vY2tfc2VydmljZV8uQ2FsbE1ldGhvZChmb29fLCAmbW9ja19jb250cm9sbGVyXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmZvb19yZXF1ZXN0XywgJmJhcl9yZXNwb25zZV8sIGRvbmVfLmdldCgpKSwKKyAgICAiZHluYW1pY19jYXN0Iik7CisKKyAgbW9ja19zZXJ2aWNlXy5SZXNldCgpOworICBFWFBFQ1RfREVCVUdfREVBVEgoCisgICAgbW9ja19zZXJ2aWNlXy5DYWxsTWV0aG9kKGZvb18sICZtb2NrX2NvbnRyb2xsZXJfLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmYmFyX3JlcXVlc3RfLCAmZm9vX3Jlc3BvbnNlXywgZG9uZV8uZ2V0KCkpLAorICAgICJkeW5hbWljX2Nhc3QiKTsKKyNlbmRpZiAgLy8gUFJPVE9CVUZfSEFTX0RFQVRIX1RFU1QKK30KKworVEVTVF9GKEdlbmVyYXRlZFNlcnZpY2VUZXN0LCBHZXRQcm90b3R5cGVzKSB7CisgIC8vIFRlc3QgR2V0e1JlcXVlc3QsUmVzcG9uc2V9UHJvdG90eXBlKCkgbWV0aG9kcy4KKworICBFWFBFQ1RfRVEoJnVuaXR0ZXN0OjpGb29SZXF1ZXN0OjpkZWZhdWx0X2luc3RhbmNlKCksCisgICAgICAgICAgICAmbW9ja19zZXJ2aWNlXy5HZXRSZXF1ZXN0UHJvdG90eXBlKGZvb18pKTsKKyAgRVhQRUNUX0VRKCZ1bml0dGVzdDo6QmFyUmVxdWVzdDo6ZGVmYXVsdF9pbnN0YW5jZSgpLAorICAgICAgICAgICAgJm1vY2tfc2VydmljZV8uR2V0UmVxdWVzdFByb3RvdHlwZShiYXJfKSk7CisKKyAgRVhQRUNUX0VRKCZ1bml0dGVzdDo6Rm9vUmVzcG9uc2U6OmRlZmF1bHRfaW5zdGFuY2UoKSwKKyAgICAgICAgICAgICZtb2NrX3NlcnZpY2VfLkdldFJlc3BvbnNlUHJvdG90eXBlKGZvb18pKTsKKyAgRVhQRUNUX0VRKCZ1bml0dGVzdDo6QmFyUmVzcG9uc2U6OmRlZmF1bHRfaW5zdGFuY2UoKSwKKyAgICAgICAgICAgICZtb2NrX3NlcnZpY2VfLkdldFJlc3BvbnNlUHJvdG90eXBlKGJhcl8pKTsKK30KKworVEVTVF9GKEdlbmVyYXRlZFNlcnZpY2VUZXN0LCBTdHViKSB7CisgIC8vIFRlc3QgdGhhdCB0aGUgc3R1YiBjbGFzcyB3b3Jrcy4KKworICAvLyBDYWxsIEZvbygpIHZpYSB0aGUgc3R1Yi4KKyAgc3R1Yl8uRm9vKCZtb2NrX2NvbnRyb2xsZXJfLCAmZm9vX3JlcXVlc3RfLCAmZm9vX3Jlc3BvbnNlXywgZG9uZV8uZ2V0KCkpOworCisgIEFTU0VSVF9UUlVFKG1vY2tfY2hhbm5lbF8uY2FsbGVkXyk7CisKKyAgRVhQRUNUX0VRKGZvb18gICAgICAgICAgICAgLCBtb2NrX2NoYW5uZWxfLm1ldGhvZF8gICAgKTsKKyAgRVhQRUNUX0VRKCZtb2NrX2NvbnRyb2xsZXJfLCBtb2NrX2NoYW5uZWxfLmNvbnRyb2xsZXJfKTsKKyAgRVhQRUNUX0VRKCZmb29fcmVxdWVzdF8gICAgLCBtb2NrX2NoYW5uZWxfLnJlcXVlc3RfICAgKTsKKyAgRVhQRUNUX0VRKCZmb29fcmVzcG9uc2VfICAgLCBtb2NrX2NoYW5uZWxfLnJlc3BvbnNlXyAgKTsKKyAgRVhQRUNUX0VRKGRvbmVfLmdldCgpICAgICAgLCBtb2NrX2NoYW5uZWxfLmRvbmVfICAgICAgKTsKKworICAvLyBDYWxsIEJhcigpIHZpYSB0aGUgc3R1Yi4KKyAgbW9ja19jaGFubmVsXy5SZXNldCgpOworICBzdHViXy5CYXIoJm1vY2tfY29udHJvbGxlcl8sICZiYXJfcmVxdWVzdF8sICZiYXJfcmVzcG9uc2VfLCBkb25lXy5nZXQoKSk7CisKKyAgQVNTRVJUX1RSVUUobW9ja19jaGFubmVsXy5jYWxsZWRfKTsKKyAgRVhQRUNUX0VRKGJhcl8sIG1vY2tfY2hhbm5lbF8ubWV0aG9kXyk7Cit9CisKK1RFU1RfRihHZW5lcmF0ZWRTZXJ2aWNlVGVzdCwgTm90SW1wbGVtZW50ZWQpIHsKKyAgLy8gVGVzdCB0aGF0IGZhaWxpbmcgdG8gaW1wbGVtZW50IGEgbWV0aG9kIG9mIGEgc2VydmljZSBjYXVzZXMgaXQgdG8gZmFpbAorICAvLyB3aXRoIGEgIm5vdCBpbXBsZW1lbnRlZCIgZXJyb3IgbWVzc2FnZS4KKworICAvLyBBIHNlcnZpY2Ugd2hpY2ggZG9lc24ndCBpbXBsZW1lbnQgYW55IG1ldGhvZHMuCisgIGNsYXNzIFVuaW1wbGVtZW50ZWRTZXJ2aWNlIDogcHVibGljIHVuaXR0ZXN0OjpUZXN0U2VydmljZSB7CisgICBwdWJsaWM6CisgICAgVW5pbXBsZW1lbnRlZFNlcnZpY2UoKSB7fQorICB9OworCisgIFVuaW1wbGVtZW50ZWRTZXJ2aWNlIHVuaW1wbGVtZW50ZWRfc2VydmljZTsKKworICAvLyBBbmQgYSBjb250cm9sbGVyIHdoaWNoIGV4cGVjdHMgdG8gZ2V0IGEgIm5vdCBpbXBsZW1lbnRlZCIgZXJyb3IuCisgIGNsYXNzIEV4cGVjdFVuaW1wbGVtZW50ZWRDb250cm9sbGVyIDogcHVibGljIE1vY2tDb250cm9sbGVyIHsKKyAgIHB1YmxpYzoKKyAgICBFeHBlY3RVbmltcGxlbWVudGVkQ29udHJvbGxlcigpIDogY2FsbGVkXyhmYWxzZSkge30KKworICAgIHZvaWQgU2V0RmFpbGVkKGNvbnN0IHN0cmluZyYgcmVhc29uKSB7CisgICAgICBFWFBFQ1RfRkFMU0UoY2FsbGVkXyk7CisgICAgICBjYWxsZWRfID0gdHJ1ZTsKKyAgICAgIEVYUEVDVF9FUSgiTWV0aG9kIEZvbygpIG5vdCBpbXBsZW1lbnRlZC4iLCByZWFzb24pOworICAgIH0KKworICAgIGJvb2wgY2FsbGVkXzsKKyAgfTsKKworICBFeHBlY3RVbmltcGxlbWVudGVkQ29udHJvbGxlciBjb250cm9sbGVyOworCisgIC8vIENhbGwgRm9vLgorICB1bmltcGxlbWVudGVkX3NlcnZpY2UuRm9vKCZjb250cm9sbGVyLCAmZm9vX3JlcXVlc3RfLCAmZm9vX3Jlc3BvbnNlXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb25lXy5nZXQoKSk7CisKKyAgRVhQRUNUX1RSVUUoY29udHJvbGxlci5jYWxsZWRfKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitjbGFzcyBPbmVvZlRlc3QgOiBwdWJsaWMgdGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICB2aXJ0dWFsIHZvaWQgU2V0VXAoKSB7CisgIH0KKworICB2b2lkIEV4cGVjdEVudW1DYXNlc1dvcmsoY29uc3QgdW5pdHRlc3Q6OlRlc3RPbmVvZjIgJm1lc3NhZ2UpIHsKKyAgICBzd2l0Y2ggKG1lc3NhZ2UuZm9vX2Nhc2UoKSkgeworICAgICAgY2FzZSB1bml0dGVzdDo6VGVzdE9uZW9mMjo6a0Zvb0ludDoKKyAgICAgICAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfZm9vX2ludCgpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIHVuaXR0ZXN0OjpUZXN0T25lb2YyOjprRm9vU3RyaW5nOgorICAgICAgICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19mb29fc3RyaW5nKCkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgdW5pdHRlc3Q6OlRlc3RPbmVvZjI6OmtGb29Db3JkOgorICAgICAgICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19mb29fY29yZCgpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIHVuaXR0ZXN0OjpUZXN0T25lb2YyOjprRm9vU3RyaW5nUGllY2U6CisgICAgICAgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2Zvb19zdHJpbmdfcGllY2UoKSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSB1bml0dGVzdDo6VGVzdE9uZW9mMjo6a0Zvb0J5dGVzOgorICAgICAgICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19mb29fYnl0ZXMoKSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSB1bml0dGVzdDo6VGVzdE9uZW9mMjo6a0Zvb0VudW06CisgICAgICAgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2Zvb19lbnVtKCkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgdW5pdHRlc3Q6OlRlc3RPbmVvZjI6OmtGb29NZXNzYWdlOgorICAgICAgICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19mb29fbWVzc2FnZSgpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIHVuaXR0ZXN0OjpUZXN0T25lb2YyOjprRm9vZ3JvdXA6CisgICAgICAgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2Zvb2dyb3VwKCkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgdW5pdHRlc3Q6OlRlc3RPbmVvZjI6OmtGb29MYXp5TWVzc2FnZToKKyAgICAgICAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfZm9vX2xhenlfbWVzc2FnZSgpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIHVuaXR0ZXN0OjpUZXN0T25lb2YyOjpGT09fTk9UX1NFVDoKKyAgICAgICAgYnJlYWs7CisgICAgfQorICB9Cit9OworCitURVNUX0YoT25lb2ZUZXN0LCBTZXR0aW5nT25lRmllbGRDbGVhcnNPdGhlcnMpIHsKKyAgdW5pdHRlc3Q6OlRlc3RPbmVvZjIgbWVzc2FnZTsKKworICBtZXNzYWdlLnNldF9mb29faW50KDEyMyk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2Zvb19pbnQoKSk7CisgIFRlc3RVdGlsOjpFeHBlY3RBdE1vc3RPbmVGaWVsZFNldEluT25lb2YobWVzc2FnZSk7CisKKyAgbWVzc2FnZS5zZXRfZm9vX3N0cmluZygiZm9vIik7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2Zvb19zdHJpbmcoKSk7CisgIFRlc3RVdGlsOjpFeHBlY3RBdE1vc3RPbmVGaWVsZFNldEluT25lb2YobWVzc2FnZSk7CisKKworICBtZXNzYWdlLnNldF9mb29fYnl0ZXMoInF1eCIpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19mb29fYnl0ZXMoKSk7CisgIFRlc3RVdGlsOjpFeHBlY3RBdE1vc3RPbmVGaWVsZFNldEluT25lb2YobWVzc2FnZSk7CisKKyAgbWVzc2FnZS5zZXRfZm9vX2VudW0odW5pdHRlc3Q6OlRlc3RPbmVvZjI6OkZPTyk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2Zvb19lbnVtKCkpOworICBUZXN0VXRpbDo6RXhwZWN0QXRNb3N0T25lRmllbGRTZXRJbk9uZW9mKG1lc3NhZ2UpOworCisgIG1lc3NhZ2UubXV0YWJsZV9mb29fbWVzc2FnZSgpLT5zZXRfcXV4X2ludCgyMzQpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19mb29fbWVzc2FnZSgpKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEF0TW9zdE9uZUZpZWxkU2V0SW5PbmVvZihtZXNzYWdlKTsKKworICBtZXNzYWdlLm11dGFibGVfZm9vZ3JvdXAoKS0+c2V0X2EoMzQ1KTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfZm9vZ3JvdXAoKSk7CisgIFRlc3RVdGlsOjpFeHBlY3RBdE1vc3RPbmVGaWVsZFNldEluT25lb2YobWVzc2FnZSk7CisKKworICAvLyB3ZSByZXBlYXQgdGhpcyBiZWNhdXNlIHdlIGRpZG4ndCB0ZXN0IGlmIHRoaXMgcHJvcGVybHkgY2xlYXJzIG90aGVyIGZpZWxkcworICAvLyBhdCB0aGUgYmVnaW5uaW5nLgorICBtZXNzYWdlLnNldF9mb29faW50KDEyMyk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2Zvb19pbnQoKSk7CisgIFRlc3RVdGlsOjpFeHBlY3RBdE1vc3RPbmVGaWVsZFNldEluT25lb2YobWVzc2FnZSk7Cit9CisKK1RFU1RfRihPbmVvZlRlc3QsIEVudW1DYXNlcykgeworICB1bml0dGVzdDo6VGVzdE9uZW9mMiBtZXNzYWdlOworCisgIG1lc3NhZ2Uuc2V0X2Zvb19pbnQoMTIzKTsKKyAgRXhwZWN0RW51bUNhc2VzV29yayhtZXNzYWdlKTsKKyAgbWVzc2FnZS5zZXRfZm9vX3N0cmluZygiZm9vIik7CisgIEV4cGVjdEVudW1DYXNlc1dvcmsobWVzc2FnZSk7CisgIG1lc3NhZ2Uuc2V0X2Zvb19ieXRlcygicXV4Iik7CisgIEV4cGVjdEVudW1DYXNlc1dvcmsobWVzc2FnZSk7CisgIG1lc3NhZ2Uuc2V0X2Zvb19lbnVtKHVuaXR0ZXN0OjpUZXN0T25lb2YyOjpGT08pOworICBFeHBlY3RFbnVtQ2FzZXNXb3JrKG1lc3NhZ2UpOworICBtZXNzYWdlLm11dGFibGVfZm9vX21lc3NhZ2UoKS0+c2V0X3F1eF9pbnQoMjM0KTsKKyAgRXhwZWN0RW51bUNhc2VzV29yayhtZXNzYWdlKTsKKyAgbWVzc2FnZS5tdXRhYmxlX2Zvb2dyb3VwKCktPnNldF9hKDM0NSk7CisgIEV4cGVjdEVudW1DYXNlc1dvcmsobWVzc2FnZSk7Cit9CisKK1RFU1RfRihPbmVvZlRlc3QsIFByaW1pdGl2ZVR5cGUpIHsKKyAgdW5pdHRlc3Q6OlRlc3RPbmVvZjIgbWVzc2FnZTsKKyAgLy8gVW5zZXQgZmllbGQgcmV0dXJucyBkZWZhdWx0IHZhbHVlCisgIEVYUEVDVF9FUShtZXNzYWdlLmZvb19pbnQoKSwgMCk7CisKKyAgbWVzc2FnZS5zZXRfZm9vX2ludCgxMjMpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19mb29faW50KCkpOworICBFWFBFQ1RfRVEobWVzc2FnZS5mb29faW50KCksIDEyMyk7CisgIG1lc3NhZ2UuY2xlYXJfZm9vX2ludCgpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZm9vX2ludCgpKTsKK30KKworVEVTVF9GKE9uZW9mVGVzdCwgRW51bVR5cGUpIHsKKyAgdW5pdHRlc3Q6OlRlc3RPbmVvZjIgbWVzc2FnZTsKKyAgLy8gVW5zZXQgZmllbGQgcmV0dXJucyBkZWZhdWx0IHZhbHVlCisgIEVYUEVDVF9FUShtZXNzYWdlLmZvb19lbnVtKCksIDEpOworCisgIG1lc3NhZ2Uuc2V0X2Zvb19lbnVtKHVuaXR0ZXN0OjpUZXN0T25lb2YyOjpGT08pOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19mb29fZW51bSgpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UuZm9vX2VudW0oKSwgdW5pdHRlc3Q6OlRlc3RPbmVvZjI6OkZPTyk7CisgIG1lc3NhZ2UuY2xlYXJfZm9vX2VudW0oKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2Zvb19lbnVtKCkpOworfQorCitURVNUX0YoT25lb2ZUZXN0LCBTZXRTdHJpbmcpIHsKKyAgLy8gQ2hlY2sgdGhhdCBzZXR0aW5nIGEgc3RyaW5nIGZpZWxkIGluIHZhcmlvdXMgd2F5cyB3b3JrcworICB1bml0dGVzdDo6VGVzdE9uZW9mMiBtZXNzYWdlOworCisgIC8vIFVuc2V0IGZpZWxkIHJldHVybnMgZGVmYXVsdCB2YWx1ZQorICBFWFBFQ1RfRVEobWVzc2FnZS5mb29fc3RyaW5nKCksICIiKTsKKworICBtZXNzYWdlLnNldF9mb29fc3RyaW5nKCJmb28iKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfZm9vX3N0cmluZygpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UuZm9vX3N0cmluZygpLCAiZm9vIik7CisgIG1lc3NhZ2UuY2xlYXJfZm9vX3N0cmluZygpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZm9vX3N0cmluZygpKTsKKworICBtZXNzYWdlLnNldF9mb29fc3RyaW5nKHN0cmluZygiYmFyIikpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19mb29fc3RyaW5nKCkpOworICBFWFBFQ1RfRVEobWVzc2FnZS5mb29fc3RyaW5nKCksICJiYXIiKTsKKyAgbWVzc2FnZS5jbGVhcl9mb29fc3RyaW5nKCk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19mb29fc3RyaW5nKCkpOworCisKKyAgbWVzc2FnZS5zZXRfZm9vX3N0cmluZygicXV4IiwgMyk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2Zvb19zdHJpbmcoKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlLmZvb19zdHJpbmcoKSwgInF1eCIpOworICBtZXNzYWdlLmNsZWFyX2Zvb19zdHJpbmcoKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2Zvb19zdHJpbmcoKSk7CisKKyAgbWVzc2FnZS5tdXRhYmxlX2Zvb19zdHJpbmcoKS0+YXNzaWduKCJxdXV4Iik7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2Zvb19zdHJpbmcoKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlLmZvb19zdHJpbmcoKSwgInF1dXgiKTsKKyAgbWVzc2FnZS5jbGVhcl9mb29fc3RyaW5nKCk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19mb29fc3RyaW5nKCkpOworCisgIG1lc3NhZ2Uuc2V0X2Zvb19zdHJpbmcoImNvcmdlIik7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2Zvb19zdHJpbmcoKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlLmZvb19zdHJpbmcoKSwgImNvcmdlIik7CisgIG1lc3NhZ2UuY2xlYXJfZm9vX3N0cmluZygpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZm9vX3N0cmluZygpKTsKK30KKworVEVTVF9GKE9uZW9mVGVzdCwgUmVsZWFzZVN0cmluZykgeworICAvLyBDaGVjayB0aGF0IHJlbGVhc2VfZm9vKCkgc3RhcnRzIG91dCBOVUxMLCBhbmQgZ2l2ZXMgdXMgYSB2YWx1ZQorICAvLyB0aGF0IHdlIGNhbiBkZWxldGUgYWZ0ZXIgaXQncyBiZWVuIHNldC4KKyAgdW5pdHRlc3Q6OlRlc3RPbmVvZjIgbWVzc2FnZTsKKworICBFWFBFQ1RfRVEoTlVMTCwgbWVzc2FnZS5yZWxlYXNlX2Zvb19zdHJpbmcoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19mb29fc3RyaW5nKCkpOworCisgIG1lc3NhZ2Uuc2V0X2Zvb19zdHJpbmcoImJsYWgiKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfZm9vX3N0cmluZygpKTsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxzdHJpbmc+IHN0cihtZXNzYWdlLnJlbGVhc2VfZm9vX3N0cmluZygpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2Zvb19zdHJpbmcoKSk7CisgIEFTU0VSVF9UUlVFKHN0ciAhPSBOVUxMKTsKKyAgRVhQRUNUX0VRKCJibGFoIiwgKnN0cik7CisKKyAgRVhQRUNUX0VRKE5VTEwsIG1lc3NhZ2UucmVsZWFzZV9mb29fc3RyaW5nKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZm9vX3N0cmluZygpKTsKK30KKworVEVTVF9GKE9uZW9mVGVzdCwgU2V0QWxsb2NhdGVkU3RyaW5nKSB7CisgIC8vIENoZWNrIHRoYXQgc2V0X2FsbG9jYXRlZF9mb28oKSB3b3JrcyBmb3Igc3RyaW5ncy4KKyAgdW5pdHRlc3Q6OlRlc3RPbmVvZjIgbWVzc2FnZTsKKworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZm9vX3N0cmluZygpKTsKKyAgY29uc3Qgc3RyaW5nIGtIZWxsbygiaGVsbG8iKTsKKyAgbWVzc2FnZS5zZXRfZm9vX3N0cmluZyhrSGVsbG8pOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19mb29fc3RyaW5nKCkpOworCisgIG1lc3NhZ2Uuc2V0X2FsbG9jYXRlZF9mb29fc3RyaW5nKE5VTEwpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZm9vX3N0cmluZygpKTsKKyAgRVhQRUNUX0VRKCIiLCBtZXNzYWdlLmZvb19zdHJpbmcoKSk7CisKKyAgbWVzc2FnZS5zZXRfYWxsb2NhdGVkX2Zvb19zdHJpbmcobmV3IHN0cmluZyhrSGVsbG8pKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfZm9vX3N0cmluZygpKTsKKyAgRVhQRUNUX0VRKGtIZWxsbywgbWVzc2FnZS5mb29fc3RyaW5nKCkpOworfQorCisKK1RFU1RfRihPbmVvZlRlc3QsIFNldE1lc3NhZ2UpIHsKKyAgLy8gQ2hlY2sgdGhhdCBzZXR0aW5nIGEgbWVzc2FnZSBmaWVsZCB3b3JrcworICB1bml0dGVzdDo6VGVzdE9uZW9mMiBtZXNzYWdlOworCisgIC8vIFVuc2V0IGZpZWxkIHJldHVybnMgZGVmYXVsdCBpbnN0YW5jZQorICBFWFBFQ1RfRVEoJm1lc3NhZ2UuZm9vX21lc3NhZ2UoKSwKKyAgICAgICAgICAgICZ1bml0dGVzdDo6VGVzdE9uZW9mMl9OZXN0ZWRNZXNzYWdlOjpkZWZhdWx0X2luc3RhbmNlKCkpOworICBFWFBFQ1RfRVEobWVzc2FnZS5mb29fbWVzc2FnZSgpLnF1eF9pbnQoKSwgMCk7CisKKyAgbWVzc2FnZS5tdXRhYmxlX2Zvb19tZXNzYWdlKCktPnNldF9xdXhfaW50KDIzNCk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2Zvb19tZXNzYWdlKCkpOworICBFWFBFQ1RfRVEobWVzc2FnZS5mb29fbWVzc2FnZSgpLnF1eF9pbnQoKSwgMjM0KTsKKyAgbWVzc2FnZS5jbGVhcl9mb29fbWVzc2FnZSgpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZm9vX21lc3NhZ2UoKSk7Cit9CisKK1RFU1RfRihPbmVvZlRlc3QsIFJlbGVhc2VNZXNzYWdlKSB7CisgIC8vIENoZWNrIHRoYXQgcmVsZWFzZV9mb28oKSBzdGFydHMgb3V0IE5VTEwsIGFuZCBnaXZlcyB1cyBhIHZhbHVlCisgIC8vIHRoYXQgd2UgY2FuIGRlbGV0ZSBhZnRlciBpdCdzIGJlZW4gc2V0LgorICB1bml0dGVzdDo6VGVzdE9uZW9mMiBtZXNzYWdlOworCisgIEVYUEVDVF9FUShOVUxMLCBtZXNzYWdlLnJlbGVhc2VfZm9vX21lc3NhZ2UoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19mb29fbWVzc2FnZSgpKTsKKworICBtZXNzYWdlLm11dGFibGVfZm9vX21lc3NhZ2UoKS0+c2V0X3F1eF9pbnQoMSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2Zvb19tZXNzYWdlKCkpOworICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPHVuaXR0ZXN0OjpUZXN0T25lb2YyX05lc3RlZE1lc3NhZ2U+IG1lcygKKyAgICAgIG1lc3NhZ2UucmVsZWFzZV9mb29fbWVzc2FnZSgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2Zvb19tZXNzYWdlKCkpOworICBBU1NFUlRfVFJVRShtZXMgIT0gTlVMTCk7CisgIEVYUEVDVF9FUSgxLCBtZXMtPnF1eF9pbnQoKSk7CisKKyAgRVhQRUNUX0VRKE5VTEwsIG1lc3NhZ2UucmVsZWFzZV9mb29fbWVzc2FnZSgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2Zvb19tZXNzYWdlKCkpOworfQorCitURVNUX0YoT25lb2ZUZXN0LCBTZXRBbGxvY2F0ZWRNZXNzYWdlKSB7CisgIC8vIENoZWNrIHRoYXQgc2V0X2FsbG9jYXRlZF9mb28oKSB3b3JrcyBmb3IgbWVzc2FnZXMuCisgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIG1lc3NhZ2U7CisKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2Zvb19tZXNzYWdlKCkpOworCisgIG1lc3NhZ2UubXV0YWJsZV9mb29fbWVzc2FnZSgpLT5zZXRfcXV4X2ludCgxKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfZm9vX21lc3NhZ2UoKSk7CisKKyAgbWVzc2FnZS5zZXRfYWxsb2NhdGVkX2Zvb19tZXNzYWdlKE5VTEwpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZm9vX21lc3NhZ2UoKSk7CisgIEVYUEVDVF9FUSgmbWVzc2FnZS5mb29fbWVzc2FnZSgpLAorICAgICAgICAgICAgJnVuaXR0ZXN0OjpUZXN0T25lb2YyX05lc3RlZE1lc3NhZ2U6OmRlZmF1bHRfaW5zdGFuY2UoKSk7CisKKyAgbWVzc2FnZS5tdXRhYmxlX2Zvb19tZXNzYWdlKCktPnNldF9xdXhfaW50KDEpOworICB1bml0dGVzdDo6VGVzdE9uZW9mMl9OZXN0ZWRNZXNzYWdlKiBtZXMgPSBtZXNzYWdlLnJlbGVhc2VfZm9vX21lc3NhZ2UoKTsKKyAgQVNTRVJUX1RSVUUobWVzICE9IE5VTEwpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZm9vX21lc3NhZ2UoKSk7CisKKyAgbWVzc2FnZS5zZXRfYWxsb2NhdGVkX2Zvb19tZXNzYWdlKG1lcyk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2Zvb19tZXNzYWdlKCkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5mb29fbWVzc2FnZSgpLnF1eF9pbnQoKSk7Cit9CisKKworVEVTVF9GKE9uZW9mVGVzdCwgQ2xlYXIpIHsKKyAgdW5pdHRlc3Q6OlRlc3RPbmVvZjIgbWVzc2FnZTsKKworICBtZXNzYWdlLnNldF9mb29faW50KDEpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19mb29faW50KCkpOworICBtZXNzYWdlLmNsZWFyX2Zvb19pbnQoKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2Zvb19pbnQoKSk7Cit9CisKK1RFU1RfRihPbmVvZlRlc3QsIERlZmF1bHRzKSB7CisgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIG1lc3NhZ2U7CisKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2Zvb19pbnQoKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlLmZvb19pbnQoKSwgMCk7CisKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2Zvb19zdHJpbmcoKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlLmZvb19zdHJpbmcoKSwgIiIpOworCisKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2Zvb19ieXRlcygpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UuZm9vX2J5dGVzKCksICIiKTsKKworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZm9vX2VudW0oKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlLmZvb19lbnVtKCksIDEpOworCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19mb29fbWVzc2FnZSgpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UuZm9vX21lc3NhZ2UoKS5xdXhfaW50KCksIDApOworCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19mb29ncm91cCgpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UuZm9vZ3JvdXAoKS5hKCksIDApOworCisKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2Jhcl9pbnQoKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlLmJhcl9pbnQoKSwgNSk7CisKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2Jhcl9zdHJpbmcoKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlLmJhcl9zdHJpbmcoKSwgIlNUUklORyIpOworCisKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2Jhcl9ieXRlcygpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UuYmFyX2J5dGVzKCksICJCWVRFUyIpOworCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19iYXJfZW51bSgpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UuYmFyX2VudW0oKSwgMik7Cit9CisKK1RFU1RfRihPbmVvZlRlc3QsIFN3YXBXaXRoRW1wdHkpIHsKKyAgdW5pdHRlc3Q6OlRlc3RPbmVvZjIgbWVzc2FnZTEsIG1lc3NhZ2UyOworICBtZXNzYWdlMS5zZXRfZm9vX3N0cmluZygiRk9PIik7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UxLmhhc19mb29fc3RyaW5nKCkpOworICBtZXNzYWdlMS5Td2FwKCZtZXNzYWdlMik7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlMS5oYXNfZm9vX3N0cmluZygpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZTIuaGFzX2Zvb19zdHJpbmcoKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlMi5mb29fc3RyaW5nKCksICJGT08iKTsKK30KKworVEVTVF9GKE9uZW9mVGVzdCwgU3dhcFdpdGhTZWxmKSB7CisgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIG1lc3NhZ2U7CisgIG1lc3NhZ2Uuc2V0X2Zvb19zdHJpbmcoIkZPTyIpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19mb29fc3RyaW5nKCkpOworICBtZXNzYWdlLlN3YXAoJm1lc3NhZ2UpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19mb29fc3RyaW5nKCkpOworICBFWFBFQ1RfRVEobWVzc2FnZS5mb29fc3RyaW5nKCksICJGT08iKTsKK30KKworVEVTVF9GKE9uZW9mVGVzdCwgU3dhcEJvdGhIYXNGaWVsZHMpIHsKKyAgdW5pdHRlc3Q6OlRlc3RPbmVvZjIgbWVzc2FnZTEsIG1lc3NhZ2UyOworCisgIG1lc3NhZ2UxLnNldF9mb29fc3RyaW5nKCJGT08iKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZTEuaGFzX2Zvb19zdHJpbmcoKSk7CisgIG1lc3NhZ2UyLm11dGFibGVfZm9vX21lc3NhZ2UoKS0+c2V0X3F1eF9pbnQoMSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UyLmhhc19mb29fbWVzc2FnZSgpKTsKKworICBtZXNzYWdlMS5Td2FwKCZtZXNzYWdlMik7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlMS5oYXNfZm9vX3N0cmluZygpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UyLmhhc19mb29fbWVzc2FnZSgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZTEuaGFzX2Zvb19tZXNzYWdlKCkpOworICBFWFBFQ1RfRVEobWVzc2FnZTEuZm9vX21lc3NhZ2UoKS5xdXhfaW50KCksIDEpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlMi5oYXNfZm9vX3N0cmluZygpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UyLmZvb19zdHJpbmcoKSwgIkZPTyIpOworfQorCitURVNUX0YoT25lb2ZUZXN0LCBDb3B5Q29uc3RydWN0b3IpIHsKKyAgdW5pdHRlc3Q6OlRlc3RPbmVvZjIgbWVzc2FnZTE7CisgIG1lc3NhZ2UxLnNldF9mb29fYnl0ZXMoIkZPTyIpOworCisgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIG1lc3NhZ2UyKG1lc3NhZ2UxKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZTIuaGFzX2Zvb19ieXRlcygpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UyLmZvb19ieXRlcygpLCAiRk9PIik7Cit9CisKK1RFU1RfRihPbmVvZlRlc3QsIENvcHlGcm9tKSB7CisgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIG1lc3NhZ2UxLCBtZXNzYWdlMjsKKyAgbWVzc2FnZTEuc2V0X2Zvb19lbnVtKHVuaXR0ZXN0OjpUZXN0T25lb2YyOjpCQVIpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlMS5oYXNfZm9vX2VudW0oKSk7CisKKyAgbWVzc2FnZTIuQ29weUZyb20obWVzc2FnZTEpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlMi5oYXNfZm9vX2VudW0oKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlMi5mb29fZW51bSgpLCB1bml0dGVzdDo6VGVzdE9uZW9mMjo6QkFSKTsKKworICAvLyBDb3B5aW5nIGZyb20gc2VsZiBzaG91bGQgYmUgYSBuby1vcC4KKyAgbWVzc2FnZTIuQ29weUZyb20obWVzc2FnZTIpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlMi5oYXNfZm9vX2VudW0oKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlMi5mb29fZW51bSgpLCB1bml0dGVzdDo6VGVzdE9uZW9mMjo6QkFSKTsKK30KKworVEVTVF9GKE9uZW9mVGVzdCwgQ29weUFzc2lnbm1lbnRPcGVyYXRvcikgeworICB1bml0dGVzdDo6VGVzdE9uZW9mMiBtZXNzYWdlMTsKKyAgbWVzc2FnZTEubXV0YWJsZV9mb29fbWVzc2FnZSgpLT5zZXRfcXV4X2ludCgxMjMpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlMS5oYXNfZm9vX21lc3NhZ2UoKSk7CisKKyAgdW5pdHRlc3Q6OlRlc3RPbmVvZjIgbWVzc2FnZTI7CisgIG1lc3NhZ2UyID0gbWVzc2FnZTE7CisgIEVYUEVDVF9FUShtZXNzYWdlMi5mb29fbWVzc2FnZSgpLnF1eF9pbnQoKSwgMTIzKTsKKworICAvLyBNYWtlIHN1cmUgdGhhdCBzZWxmLWFzc2lnbm1lbnQgZG9lcyBzb21ldGhpbmcgc2FuZS4KKyAgbWVzc2FnZTIgPSBtZXNzYWdlMjsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UyLmZvb19tZXNzYWdlKCkucXV4X2ludCgpLCAxMjMpOworfQorCitURVNUX0YoT25lb2ZUZXN0LCBVcGNhc3RDb3B5RnJvbSkgeworICAvLyBUZXN0IHRoZSBDb3B5RnJvbSBtZXRob2QgdGhhdCB0YWtlcyBpbiB0aGUgZ2VuZXJpYyBjb25zdCBNZXNzYWdlJgorICAvLyBwYXJhbWV0ZXIuCisgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIG1lc3NhZ2UxLCBtZXNzYWdlMjsKKyAgbWVzc2FnZTEubXV0YWJsZV9mb29ncm91cCgpLT5zZXRfYSgxMjMpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlMS5oYXNfZm9vZ3JvdXAoKSk7CisKKyAgY29uc3QgTWVzc2FnZSogc291cmNlID0gaW1wbGljaXRfY2FzdDxjb25zdCBNZXNzYWdlKj4oJm1lc3NhZ2UxKTsKKyAgbWVzc2FnZTIuQ29weUZyb20oKnNvdXJjZSk7CisKKyAgRVhQRUNUX1RSVUUobWVzc2FnZTIuaGFzX2Zvb2dyb3VwKCkpOworICBFWFBFQ1RfRVEobWVzc2FnZTIuZm9vZ3JvdXAoKS5hKCksIDEyMyk7Cit9CisKKy8vIFRlc3QgdGhlIGdlbmVyYXRlZCBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KCksCisvLyBUaGlzIGluZGlyZWN0bHkgdGVzdHMgTWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKCkKKy8vIFdlIGhhdmUgdG8gdGVzdCBlYWNoIGZpZWxkIHR5cGUgc2VwYXJhdGVseSBiZWNhdXNlIHdlIGNhbm5vdCBzZXQgdGhlbSBhdCB0aGUKKy8vIHNhbWUgdGltZQorVEVTVF9GKE9uZW9mVGVzdCwgU2VyaWFsaXphdGlvblRvQXJyYXkpIHsKKyAgLy8gUHJpbWl0aXZlIHR5cGUKKyAgeworICAgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIG1lc3NhZ2UxLCBtZXNzYWdlMjsKKyAgICBzdHJpbmcgZGF0YTsKKyAgICBtZXNzYWdlMS5zZXRfZm9vX2ludCgxMjMpOworICAgIGludCBzaXplID0gbWVzc2FnZTEuQnl0ZVNpemUoKTsKKyAgICBkYXRhLnJlc2l6ZShzaXplKTsKKyAgICB1aW50OCogc3RhcnQgPSByZWludGVycHJldF9jYXN0PHVpbnQ4Kj4oc3RyaW5nX2FzX2FycmF5KCZkYXRhKSk7CisgICAgdWludDgqIGVuZCA9IG1lc3NhZ2UxLlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoc3RhcnQpOworICAgIEVYUEVDVF9FUShzaXplLCBlbmQgLSBzdGFydCk7CisgICAgRVhQRUNUX1RSVUUobWVzc2FnZTIuUGFyc2VGcm9tU3RyaW5nKGRhdGEpKTsKKyAgICBFWFBFQ1RfRVEobWVzc2FnZTIuZm9vX2ludCgpLCAxMjMpOworICB9CisKKyAgLy8gU3RyaW5nCisgIHsKKyAgICB1bml0dGVzdDo6VGVzdE9uZW9mMiBtZXNzYWdlMSwgbWVzc2FnZTI7CisgICAgc3RyaW5nIGRhdGE7CisgICAgbWVzc2FnZTEuc2V0X2Zvb19zdHJpbmcoImZvbyIpOworICAgIGludCBzaXplID0gbWVzc2FnZTEuQnl0ZVNpemUoKTsKKyAgICBkYXRhLnJlc2l6ZShzaXplKTsKKyAgICB1aW50OCogc3RhcnQgPSByZWludGVycHJldF9jYXN0PHVpbnQ4Kj4oc3RyaW5nX2FzX2FycmF5KCZkYXRhKSk7CisgICAgdWludDgqIGVuZCA9IG1lc3NhZ2UxLlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoc3RhcnQpOworICAgIEVYUEVDVF9FUShzaXplLCBlbmQgLSBzdGFydCk7CisgICAgRVhQRUNUX1RSVUUobWVzc2FnZTIuUGFyc2VGcm9tU3RyaW5nKGRhdGEpKTsKKyAgICBFWFBFQ1RfRVEobWVzc2FnZTIuZm9vX3N0cmluZygpLCAiZm9vIik7CisgIH0KKworCisgIC8vIEJ5dGVzCisgIHsKKyAgICB1bml0dGVzdDo6VGVzdE9uZW9mMiBtZXNzYWdlMSwgbWVzc2FnZTI7CisgICAgc3RyaW5nIGRhdGE7CisgICAgbWVzc2FnZTEuc2V0X2Zvb19ieXRlcygicXV4Iik7CisgICAgaW50IHNpemUgPSBtZXNzYWdlMS5CeXRlU2l6ZSgpOworICAgIGRhdGEucmVzaXplKHNpemUpOworICAgIHVpbnQ4KiBzdGFydCA9IHJlaW50ZXJwcmV0X2Nhc3Q8dWludDgqPihzdHJpbmdfYXNfYXJyYXkoJmRhdGEpKTsKKyAgICB1aW50OCogZW5kID0gbWVzc2FnZTEuU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheShzdGFydCk7CisgICAgRVhQRUNUX0VRKHNpemUsIGVuZCAtIHN0YXJ0KTsKKyAgICBFWFBFQ1RfVFJVRShtZXNzYWdlMi5QYXJzZUZyb21TdHJpbmcoZGF0YSkpOworICAgIEVYUEVDVF9FUShtZXNzYWdlMi5mb29fYnl0ZXMoKSwgInF1eCIpOworICB9CisKKyAgLy8gRW51bQorICB7CisgICAgdW5pdHRlc3Q6OlRlc3RPbmVvZjIgbWVzc2FnZTEsIG1lc3NhZ2UyOworICAgIHN0cmluZyBkYXRhOworICAgIG1lc3NhZ2UxLnNldF9mb29fZW51bSh1bml0dGVzdDo6VGVzdE9uZW9mMjo6Rk9PKTsKKyAgICBpbnQgc2l6ZSA9IG1lc3NhZ2UxLkJ5dGVTaXplKCk7CisgICAgZGF0YS5yZXNpemUoc2l6ZSk7CisgICAgdWludDgqIHN0YXJ0ID0gcmVpbnRlcnByZXRfY2FzdDx1aW50OCo+KHN0cmluZ19hc19hcnJheSgmZGF0YSkpOworICAgIHVpbnQ4KiBlbmQgPSBtZXNzYWdlMS5TZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KHN0YXJ0KTsKKyAgICBFWFBFQ1RfRVEoc2l6ZSwgZW5kIC0gc3RhcnQpOworICAgIEVYUEVDVF9UUlVFKG1lc3NhZ2UyLlBhcnNlRnJvbVN0cmluZyhkYXRhKSk7CisgICAgRVhQRUNUX0VRKG1lc3NhZ2UyLmZvb19lbnVtKCksIHVuaXR0ZXN0OjpUZXN0T25lb2YyOjpGT08pOworICB9CisKKyAgLy8gTWVzc2FnZQorICB7CisgICAgdW5pdHRlc3Q6OlRlc3RPbmVvZjIgbWVzc2FnZTEsIG1lc3NhZ2UyOworICAgIHN0cmluZyBkYXRhOworICAgIG1lc3NhZ2UxLm11dGFibGVfZm9vX21lc3NhZ2UoKS0+c2V0X3F1eF9pbnQoMjM0KTsKKyAgICBpbnQgc2l6ZSA9IG1lc3NhZ2UxLkJ5dGVTaXplKCk7CisgICAgZGF0YS5yZXNpemUoc2l6ZSk7CisgICAgdWludDgqIHN0YXJ0ID0gcmVpbnRlcnByZXRfY2FzdDx1aW50OCo+KHN0cmluZ19hc19hcnJheSgmZGF0YSkpOworICAgIHVpbnQ4KiBlbmQgPSBtZXNzYWdlMS5TZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KHN0YXJ0KTsKKyAgICBFWFBFQ1RfRVEoc2l6ZSwgZW5kIC0gc3RhcnQpOworICAgIEVYUEVDVF9UUlVFKG1lc3NhZ2UyLlBhcnNlRnJvbVN0cmluZyhkYXRhKSk7CisgICAgRVhQRUNUX0VRKG1lc3NhZ2UyLmZvb19tZXNzYWdlKCkucXV4X2ludCgpLCAyMzQpOworICB9CisKKyAgLy8gR3JvdXAKKyAgeworICAgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIG1lc3NhZ2UxLCBtZXNzYWdlMjsKKyAgICBzdHJpbmcgZGF0YTsKKyAgICBtZXNzYWdlMS5tdXRhYmxlX2Zvb2dyb3VwKCktPnNldF9hKDM0NSk7CisgICAgaW50IHNpemUgPSBtZXNzYWdlMS5CeXRlU2l6ZSgpOworICAgIGRhdGEucmVzaXplKHNpemUpOworICAgIHVpbnQ4KiBzdGFydCA9IHJlaW50ZXJwcmV0X2Nhc3Q8dWludDgqPihzdHJpbmdfYXNfYXJyYXkoJmRhdGEpKTsKKyAgICB1aW50OCogZW5kID0gbWVzc2FnZTEuU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheShzdGFydCk7CisgICAgRVhQRUNUX0VRKHNpemUsIGVuZCAtIHN0YXJ0KTsKKyAgICBFWFBFQ1RfVFJVRShtZXNzYWdlMi5QYXJzZUZyb21TdHJpbmcoZGF0YSkpOworICAgIEVYUEVDVF9FUShtZXNzYWdlMi5mb29ncm91cCgpLmEoKSwgMzQ1KTsKKyAgfQorCit9CisKKy8vIFRlc3QgdGhlIGdlbmVyYXRlZCBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoKSBieSBmb3JjaW5nIHRoZSBidWZmZXIgdG8gd3JpdGUKKy8vIG9uZSBieXRlIGF0IGEgdGltZS4KKy8vIFRoaXMgaW5kaXJlY3RseSB0ZXN0cyBNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oKQorLy8gV2UgaGF2ZSB0byB0ZXN0IGVhY2ggZmllbGQgdHlwZSBzZXBhcmF0ZWx5IGJlY2F1c2Ugd2UgY2Fubm90IHNldCB0aGVtIGF0IHRoZQorLy8gc2FtZSB0aW1lCitURVNUX0YoT25lb2ZUZXN0LCBTZXJpYWxpemF0aW9uVG9TdHJlYW0pIHsKKyAgLy8gUHJpbWl0aXZlIHR5cGUKKyAgeworICAgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIG1lc3NhZ2UxLCBtZXNzYWdlMjsKKyAgICBzdHJpbmcgZGF0YTsKKyAgICBtZXNzYWdlMS5zZXRfZm9vX2ludCgxMjMpOworICAgIGludCBzaXplID0gbWVzc2FnZTEuQnl0ZVNpemUoKTsKKyAgICBkYXRhLnJlc2l6ZShzaXplKTsKKworICAgIHsKKyAgICAgIC8vIEFsbG93IHRoZSBvdXRwdXQgc3RyZWFtIHRvIGJ1ZmZlciBvbmx5IG9uZSBieXRlIGF0IGEgdGltZS4KKyAgICAgIGlvOjpBcnJheU91dHB1dFN0cmVhbSBhcnJheV9zdHJlYW0oc3RyaW5nX2FzX2FycmF5KCZkYXRhKSwgc2l6ZSwgMSk7CisgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0X3N0cmVhbSgmYXJyYXlfc3RyZWFtKTsKKyAgICAgIG1lc3NhZ2UxLlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygmb3V0cHV0X3N0cmVhbSk7CisgICAgICBFWFBFQ1RfRkFMU0Uob3V0cHV0X3N0cmVhbS5IYWRFcnJvcigpKTsKKyAgICAgIEVYUEVDVF9FUShzaXplLCBvdXRwdXRfc3RyZWFtLkJ5dGVDb3VudCgpKTsKKyAgICB9CisKKyAgICBFWFBFQ1RfVFJVRShtZXNzYWdlMi5QYXJzZUZyb21TdHJpbmcoZGF0YSkpOworICAgIEVYUEVDVF9FUShtZXNzYWdlMi5mb29faW50KCksIDEyMyk7CisgIH0KKworICAvLyBTdHJpbmcKKyAgeworICAgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIG1lc3NhZ2UxLCBtZXNzYWdlMjsKKyAgICBzdHJpbmcgZGF0YTsKKyAgICBtZXNzYWdlMS5zZXRfZm9vX3N0cmluZygiZm9vIik7CisgICAgaW50IHNpemUgPSBtZXNzYWdlMS5CeXRlU2l6ZSgpOworICAgIGRhdGEucmVzaXplKHNpemUpOworCisgICAgeworICAgICAgLy8gQWxsb3cgdGhlIG91dHB1dCBzdHJlYW0gdG8gYnVmZmVyIG9ubHkgb25lIGJ5dGUgYXQgYSB0aW1lLgorICAgICAgaW86OkFycmF5T3V0cHV0U3RyZWFtIGFycmF5X3N0cmVhbShzdHJpbmdfYXNfYXJyYXkoJmRhdGEpLCBzaXplLCAxKTsKKyAgICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSBvdXRwdXRfc3RyZWFtKCZhcnJheV9zdHJlYW0pOworICAgICAgbWVzc2FnZTEuU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKCZvdXRwdXRfc3RyZWFtKTsKKyAgICAgIEVYUEVDVF9GQUxTRShvdXRwdXRfc3RyZWFtLkhhZEVycm9yKCkpOworICAgICAgRVhQRUNUX0VRKHNpemUsIG91dHB1dF9zdHJlYW0uQnl0ZUNvdW50KCkpOworICAgIH0KKworICAgIEVYUEVDVF9UUlVFKG1lc3NhZ2UyLlBhcnNlRnJvbVN0cmluZyhkYXRhKSk7CisgICAgRVhQRUNUX0VRKG1lc3NhZ2UyLmZvb19zdHJpbmcoKSwgImZvbyIpOworICB9CisKKworICAvLyBCeXRlcworICB7CisgICAgdW5pdHRlc3Q6OlRlc3RPbmVvZjIgbWVzc2FnZTEsIG1lc3NhZ2UyOworICAgIHN0cmluZyBkYXRhOworICAgIG1lc3NhZ2UxLnNldF9mb29fYnl0ZXMoInF1eCIpOworICAgIGludCBzaXplID0gbWVzc2FnZTEuQnl0ZVNpemUoKTsKKyAgICBkYXRhLnJlc2l6ZShzaXplKTsKKworICAgIHsKKyAgICAgIC8vIEFsbG93IHRoZSBvdXRwdXQgc3RyZWFtIHRvIGJ1ZmZlciBvbmx5IG9uZSBieXRlIGF0IGEgdGltZS4KKyAgICAgIGlvOjpBcnJheU91dHB1dFN0cmVhbSBhcnJheV9zdHJlYW0oc3RyaW5nX2FzX2FycmF5KCZkYXRhKSwgc2l6ZSwgMSk7CisgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0X3N0cmVhbSgmYXJyYXlfc3RyZWFtKTsKKyAgICAgIG1lc3NhZ2UxLlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygmb3V0cHV0X3N0cmVhbSk7CisgICAgICBFWFBFQ1RfRkFMU0Uob3V0cHV0X3N0cmVhbS5IYWRFcnJvcigpKTsKKyAgICAgIEVYUEVDVF9FUShzaXplLCBvdXRwdXRfc3RyZWFtLkJ5dGVDb3VudCgpKTsKKyAgICB9CisKKyAgICBFWFBFQ1RfVFJVRShtZXNzYWdlMi5QYXJzZUZyb21TdHJpbmcoZGF0YSkpOworICAgIEVYUEVDVF9FUShtZXNzYWdlMi5mb29fYnl0ZXMoKSwgInF1eCIpOworICB9CisKKyAgLy8gRW51bQorICB7CisgICAgdW5pdHRlc3Q6OlRlc3RPbmVvZjIgbWVzc2FnZTEsIG1lc3NhZ2UyOworICAgIHN0cmluZyBkYXRhOworICAgIG1lc3NhZ2UxLnNldF9mb29fZW51bSh1bml0dGVzdDo6VGVzdE9uZW9mMjo6Rk9PKTsKKyAgICBpbnQgc2l6ZSA9IG1lc3NhZ2UxLkJ5dGVTaXplKCk7CisgICAgZGF0YS5yZXNpemUoc2l6ZSk7CisKKyAgICB7CisgICAgICAvLyBBbGxvdyB0aGUgb3V0cHV0IHN0cmVhbSB0byBidWZmZXIgb25seSBvbmUgYnl0ZSBhdCBhIHRpbWUuCisgICAgICBpbzo6QXJyYXlPdXRwdXRTdHJlYW0gYXJyYXlfc3RyZWFtKHN0cmluZ19hc19hcnJheSgmZGF0YSksIHNpemUsIDEpOworICAgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dF9zdHJlYW0oJmFycmF5X3N0cmVhbSk7CisgICAgICBtZXNzYWdlMS5TZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoJm91dHB1dF9zdHJlYW0pOworICAgICAgRVhQRUNUX0ZBTFNFKG91dHB1dF9zdHJlYW0uSGFkRXJyb3IoKSk7CisgICAgICBFWFBFQ1RfRVEoc2l6ZSwgb3V0cHV0X3N0cmVhbS5CeXRlQ291bnQoKSk7CisgICAgfQorCisgICAgRVhQRUNUX1RSVUUobWVzc2FnZTIuUGFyc2VGcm9tU3RyaW5nKGRhdGEpKTsKKyAgICBFWFBFQ1RfRVEobWVzc2FnZTIuZm9vX2VudW0oKSwgdW5pdHRlc3Q6OlRlc3RPbmVvZjI6OkZPTyk7CisgIH0KKworICAvLyBNZXNzYWdlCisgIHsKKyAgICB1bml0dGVzdDo6VGVzdE9uZW9mMiBtZXNzYWdlMSwgbWVzc2FnZTI7CisgICAgc3RyaW5nIGRhdGE7CisgICAgbWVzc2FnZTEubXV0YWJsZV9mb29fbWVzc2FnZSgpLT5zZXRfcXV4X2ludCgyMzQpOworICAgIGludCBzaXplID0gbWVzc2FnZTEuQnl0ZVNpemUoKTsKKyAgICBkYXRhLnJlc2l6ZShzaXplKTsKKworICAgIHsKKyAgICAgIC8vIEFsbG93IHRoZSBvdXRwdXQgc3RyZWFtIHRvIGJ1ZmZlciBvbmx5IG9uZSBieXRlIGF0IGEgdGltZS4KKyAgICAgIGlvOjpBcnJheU91dHB1dFN0cmVhbSBhcnJheV9zdHJlYW0oc3RyaW5nX2FzX2FycmF5KCZkYXRhKSwgc2l6ZSwgMSk7CisgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0X3N0cmVhbSgmYXJyYXlfc3RyZWFtKTsKKyAgICAgIG1lc3NhZ2UxLlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygmb3V0cHV0X3N0cmVhbSk7CisgICAgICBFWFBFQ1RfRkFMU0Uob3V0cHV0X3N0cmVhbS5IYWRFcnJvcigpKTsKKyAgICAgIEVYUEVDVF9FUShzaXplLCBvdXRwdXRfc3RyZWFtLkJ5dGVDb3VudCgpKTsKKyAgICB9CisKKyAgICBFWFBFQ1RfVFJVRShtZXNzYWdlMi5QYXJzZUZyb21TdHJpbmcoZGF0YSkpOworICAgIEVYUEVDVF9FUShtZXNzYWdlMi5mb29fbWVzc2FnZSgpLnF1eF9pbnQoKSwgMjM0KTsKKyAgfQorCisgIC8vIEdyb3VwCisgIHsKKyAgICB1bml0dGVzdDo6VGVzdE9uZW9mMiBtZXNzYWdlMSwgbWVzc2FnZTI7CisgICAgc3RyaW5nIGRhdGE7CisgICAgbWVzc2FnZTEubXV0YWJsZV9mb29ncm91cCgpLT5zZXRfYSgzNDUpOworICAgIGludCBzaXplID0gbWVzc2FnZTEuQnl0ZVNpemUoKTsKKyAgICBkYXRhLnJlc2l6ZShzaXplKTsKKworICAgIHsKKyAgICAgIC8vIEFsbG93IHRoZSBvdXRwdXQgc3RyZWFtIHRvIGJ1ZmZlciBvbmx5IG9uZSBieXRlIGF0IGEgdGltZS4KKyAgICAgIGlvOjpBcnJheU91dHB1dFN0cmVhbSBhcnJheV9zdHJlYW0oc3RyaW5nX2FzX2FycmF5KCZkYXRhKSwgc2l6ZSwgMSk7CisgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0X3N0cmVhbSgmYXJyYXlfc3RyZWFtKTsKKyAgICAgIG1lc3NhZ2UxLlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygmb3V0cHV0X3N0cmVhbSk7CisgICAgICBFWFBFQ1RfRkFMU0Uob3V0cHV0X3N0cmVhbS5IYWRFcnJvcigpKTsKKyAgICAgIEVYUEVDVF9FUShzaXplLCBvdXRwdXRfc3RyZWFtLkJ5dGVDb3VudCgpKTsKKyAgICB9CisKKyAgICBFWFBFQ1RfVFJVRShtZXNzYWdlMi5QYXJzZUZyb21TdHJpbmcoZGF0YSkpOworICAgIEVYUEVDVF9FUShtZXNzYWdlMi5mb29ncm91cCgpLmEoKSwgMzQ1KTsKKyAgfQorCit9CisKK1RFU1RfRihPbmVvZlRlc3QsIE1lcmdlRnJvbSkgeworICB1bml0dGVzdDo6VGVzdE9uZW9mMiBtZXNzYWdlMSwgbWVzc2FnZTI7CisKKyAgbWVzc2FnZTEuc2V0X2Zvb19pbnQoMTIzKTsKKyAgbWVzc2FnZTIuTWVyZ2VGcm9tKG1lc3NhZ2UxKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEF0TW9zdE9uZUZpZWxkU2V0SW5PbmVvZihtZXNzYWdlMik7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UyLmhhc19mb29faW50KCkpOworICBFWFBFQ1RfRVEobWVzc2FnZTIuZm9vX2ludCgpLCAxMjMpOworCisgIG1lc3NhZ2UxLnNldF9mb29fc3RyaW5nKCJmb28iKTsKKyAgbWVzc2FnZTIuTWVyZ2VGcm9tKG1lc3NhZ2UxKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEF0TW9zdE9uZUZpZWxkU2V0SW5PbmVvZihtZXNzYWdlMik7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UyLmhhc19mb29fc3RyaW5nKCkpOworICBFWFBFQ1RfRVEobWVzc2FnZTIuZm9vX3N0cmluZygpLCAiZm9vIik7CisKKworICBtZXNzYWdlMS5zZXRfZm9vX2J5dGVzKCJxdXgiKTsKKyAgbWVzc2FnZTIuTWVyZ2VGcm9tKG1lc3NhZ2UxKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEF0TW9zdE9uZUZpZWxkU2V0SW5PbmVvZihtZXNzYWdlMik7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UyLmhhc19mb29fYnl0ZXMoKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlMi5mb29fYnl0ZXMoKSwgInF1eCIpOworCisgIG1lc3NhZ2UxLnNldF9mb29fZW51bSh1bml0dGVzdDo6VGVzdE9uZW9mMjo6Rk9PKTsKKyAgbWVzc2FnZTIuTWVyZ2VGcm9tKG1lc3NhZ2UxKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEF0TW9zdE9uZUZpZWxkU2V0SW5PbmVvZihtZXNzYWdlMik7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UyLmhhc19mb29fZW51bSgpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UyLmZvb19lbnVtKCksIHVuaXR0ZXN0OjpUZXN0T25lb2YyOjpGT08pOworCisgIG1lc3NhZ2UxLm11dGFibGVfZm9vX21lc3NhZ2UoKS0+c2V0X3F1eF9pbnQoMjM0KTsKKyAgbWVzc2FnZTIuTWVyZ2VGcm9tKG1lc3NhZ2UxKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEF0TW9zdE9uZUZpZWxkU2V0SW5PbmVvZihtZXNzYWdlMik7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UyLmhhc19mb29fbWVzc2FnZSgpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UyLmZvb19tZXNzYWdlKCkucXV4X2ludCgpLCAyMzQpOworCisgIG1lc3NhZ2UxLm11dGFibGVfZm9vZ3JvdXAoKS0+c2V0X2EoMzQ1KTsKKyAgbWVzc2FnZTIuTWVyZ2VGcm9tKG1lc3NhZ2UxKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEF0TW9zdE9uZUZpZWxkU2V0SW5PbmVvZihtZXNzYWdlMik7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UyLmhhc19mb29ncm91cCgpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UyLmZvb2dyb3VwKCkuYSgpLCAzNDUpOworCit9CisKK30gIC8vIG5hbWVzcGFjZSBjcHBfdW5pdHRlc3QKK30gIC8vIG5hbWVzcGFjZSBjcHAKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorCituYW1lc3BhY2Ugbm9fZ2VuZXJpY19zZXJ2aWNlc190ZXN0IHsKKyAgLy8gVmVyaWZ5IHRoYXQgbm8gY2xhc3MgY2FsbGVkICJUZXN0U2VydmljZSIgd2FzIGRlZmluZWQgaW4KKyAgLy8gdW5pdHRlc3Rfbm9fZ2VuZXJpY19zZXJ2aWNlcy5wYi5oIGJ5IGRlZmluaW5nIGEgZGlmZmVyZW50IHR5cGUgYnkgdGhlIHNhbWUKKyAgLy8gbmFtZS4gIElmIHN1Y2ggYSBzZXJ2aWNlIHdhcyBnZW5lcmF0ZWQsIHRoaXMgd2lsbCBub3QgY29tcGlsZS4KKyAgc3RydWN0IFRlc3RTZXJ2aWNlIHsKKyAgICBpbnQgaTsKKyAgfTsKK30KKworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBjcHAgeworbmFtZXNwYWNlIGNwcF91bml0dGVzdCB7CisKK1RFU1RfRihHZW5lcmF0ZWRTZXJ2aWNlVGVzdCwgTm9HZW5lcmljU2VydmljZXMpIHsKKyAgLy8gVmVyaWZ5IHRoYXQgbm9uLXNlcnZpY2VzIGluIHVuaXR0ZXN0X25vX2dlbmVyaWNfc2VydmljZXMucHJvdG8gd2VyZQorICAvLyBnZW5lcmF0ZWQuCisgIG5vX2dlbmVyaWNfc2VydmljZXNfdGVzdDo6VGVzdE1lc3NhZ2UgbWVzc2FnZTsKKyAgbWVzc2FnZS5zZXRfYSgxKTsKKyAgbWVzc2FnZS5TZXRFeHRlbnNpb24obm9fZ2VuZXJpY19zZXJ2aWNlc190ZXN0Ojp0ZXN0X2V4dGVuc2lvbiwgMTIzKTsKKyAgbm9fZ2VuZXJpY19zZXJ2aWNlc190ZXN0OjpUZXN0RW51bSBlID0gbm9fZ2VuZXJpY19zZXJ2aWNlc190ZXN0OjpGT087CisgIEVYUEVDVF9FUShlLCAxKTsKKworICAvLyBWZXJpZnkgdGhhdCBhIFNlcnZpY2VEZXNjcmlwdG9yIGlzIGdlbmVyYXRlZCBmb3IgdGhlIHNlcnZpY2UgZXZlbiBpZiB0aGUKKyAgLy8gY2xhc3MgaXRzZWxmIGlzIG5vdC4KKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUgPQorICAgICAgbm9fZ2VuZXJpY19zZXJ2aWNlc190ZXN0OjpUZXN0TWVzc2FnZTo6ZGVzY3JpcHRvcigpLT5maWxlKCk7CisKKyAgQVNTRVJUX0VRKDEsIGZpbGUtPnNlcnZpY2VfY291bnQoKSk7CisgIEVYUEVDVF9FUSgiVGVzdFNlcnZpY2UiLCBmaWxlLT5zZXJ2aWNlKDApLT5uYW1lKCkpOworICBBU1NFUlRfRVEoMSwgZmlsZS0+c2VydmljZSgwKS0+bWV0aG9kX2NvdW50KCkpOworICBFWFBFQ1RfRVEoIkZvbyIsIGZpbGUtPnNlcnZpY2UoMCktPm1ldGhvZCgwKS0+bmFtZSgpKTsKK30KKworI2VuZGlmICAvLyAhUFJPVE9CVUZfVEVTVF9OT19ERVNDUklQVE9SUworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKy8vIFRoaXMgdGVzdCBtdXN0IHJ1biBsYXN0LiAgSXQgdmVyaWZpZXMgdGhhdCBkZXNjcmlwdG9ycyB3ZXJlIG9yIHdlcmUgbm90CisvLyBpbml0aWFsaXplZCBkZXBlbmRpbmcgb24gd2hldGhlciBQUk9UT0JVRl9URVNUX05PX0RFU0NSSVBUT1JTIHdhcyBkZWZpbmVkLgorLy8gV2hlbiB0aGlzIGlzIGRlZmluZWQsIHdlIHNraXAgYWxsIHRlc3RzIHdoaWNoIGFyZSBleHBlY3RlZCB0byB0cmlnZ2VyCisvLyBkZXNjcmlwdG9yIGluaXRpYWxpemF0aW9uLiAgVGhpcyB2ZXJpZmllcyB0aGF0IGV2ZXJ5dGhpbmcgZWxzZSBzdGlsbCB3b3JrcworLy8gaWYgZGVzY3JpcHRvcnMgYXJlIG5vdCBpbml0aWFsaXplZC4KK1RFU1QoRGVzY3JpcHRvckluaXRpYWxpemF0aW9uVGVzdCwgSW5pdGlhbGl6ZWQpIHsKKyNpZmRlZiBQUk9UT0JVRl9URVNUX05PX0RFU0NSSVBUT1JTCisgIGJvb2wgc2hvdWxkX2hhdmVfZGVzY3JpcHRvcnMgPSBmYWxzZTsKKyNlbHNlCisgIGJvb2wgc2hvdWxkX2hhdmVfZGVzY3JpcHRvcnMgPSB0cnVlOworI2VuZGlmCisKKyAgRVhQRUNUX0VRKHNob3VsZF9oYXZlX2Rlc2NyaXB0b3JzLAorICAgIERlc2NyaXB0b3JQb29sOjpnZW5lcmF0ZWRfcG9vbCgpLT5JbnRlcm5hbElzRmlsZUxvYWRlZCgKKyAgICAgICJnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucHJvdG8iKSk7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBjcHBfdW5pdHRlc3QKKworfSAgLy8gbmFtZXNwYWNlIGNwcAorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF91bml0dGVzdC5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX3VuaXR0ZXN0LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjljOGY0NAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF91bml0dGVzdC5oCkBAIC0wLDAgKzEsNTEgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBUaGlzIGhlYWRlciBkZWNsYXJlcyB0aGUgbmFtZXNwYWNlIGdvb2dsZTo6cHJvdG9idWY6OnByb3RvYnVmX3VuaXR0ZXN0IGluIG9yZGVyIHRvIGV4cG9zZQorLy8gYW55IHByb2JsZW1zIHdpdGggdGhlIGdlbmVyYXRlZCBjbGFzcyBuYW1lcy4gV2UgdXNlIHRoaXMgaGVhZGVyIHRvIGVuc3VyZQorLy8gdW5pdHRlc3QuY2Mgd2lsbCBkZWNsYXJlIHRoZSBuYW1lc3BhY2UgcHJpb3IgdG8gb3RoZXIgaW5jbHVkZXMsIHdoaWxlIG9iZXlpbmcKKy8vIG5vcm1hbCBpbmNsdWRlIG9yZGVyaW5nLgorLy8KKy8vIFdoZW4gZ2VuZXJhdGluZyBhIGNsYXNzIG5hbWUgb2YgImZvby5CYXIiIHdlIG11c3QgZW5zdXJlIHdlIHByZWZpeCB0aGUgY2xhc3MKKy8vIG5hbWUgd2l0aCAiOjoiLCBpbiBjYXNlIHRoZSBuYW1lc3BhY2UgZ29vZ2xlOjpwcm90b2J1Zjo6Zm9vIGV4aXN0cy4gV2UgaW50ZW50aW9uYWxseQorLy8gdHJpZ2dlciB0aGF0IGNhc2UgaGVyZSBieSBkZWNsYXJpbmcgZ29vZ2xlOjpwcm90b2J1Zjo6cHJvdG9idWZfdW5pdHRlc3QuCisvLworLy8gU2VlIENsYXNzTmFtZSBpbiBoZWxwZXJzLmggZm9yIG1vcmUgZGV0YWlscy4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1BQX1VOSVRURVNUX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1BQX1VOSVRURVNUX0hfXworCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgcHJvdG9idWZfdW5pdHRlc3Qge30KK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DUFBfVU5JVFRFU1RfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9tZXRhZGF0YV90ZXN0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvbWV0YWRhdGFfdGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40MjJlYjczCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvbWV0YWRhdGFfdGVzdC5jYwpAQCAtMCwwICsxLDU4IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2luY2x1ZGUgPG1lbW9yeT4KKyNpZm5kZWYgX1NIQVJFRF9QVFJfSAorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaGFyZWRfcHRyLmg+CisjZW5kaWYKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvY3BwX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3BwL2NwcF9nZW5lcmF0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY29tbWFuZF9saW5lX2ludGVyZmFjZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbF9saXRlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZ29vZ2xldGVzdC5oPgorI2luY2x1ZGUgPGd0ZXN0L2d0ZXN0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZmlsZS5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGNwcCB7CituYW1lc3BhY2UgeworCit9ICAvLyBuYW1lc3BhY2UKK30gIC8vIG5hbWVzcGFjZSBjcHAKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfZG9jX2NvbW1lbnQuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfZG9jX2NvbW1lbnQuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTg3ZTAyMgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9kb2NfY29tbWVudC5jYwpAQCAtMCwwICsxLDExNCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX2RvY19jb21tZW50Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgY3NoYXJwIHsKKworLy8gRnVuY3Rpb25zIHRvIGNyZWF0ZSBDIyBYTUwgZG9jdW1lbnRhdGlvbiBjb21tZW50cy4KKy8vIEN1cnJlbnRseSB0aGlzIG9ubHkgaW5jbHVkZXMgZG9jdW1lbnRhdGlvbiBjb21tZW50cyBjb250YWluaW5nIHRleHQgc3BlY2lmaWVkIGFzIGNvbW1lbnRzCisvLyBpbiB0aGUgLnByb3RvIGZpbGU7IGRvY3VtZW50YXRpb24gY29tbWVudHMgZ2VuZXJhdGVkIGp1c3QgZnJvbSBmaWVsZC9tZXNzYWdlL2VudW0vcHJvdG8gbmFtZXMKKy8vIGlzIGlubGluZWQgaW4gdGhlIHJlbGV2YW50IGNvZGUuIElmIG1vcmUgY29udHJvbCBpcyByZXF1aXJlZCwgdGhhdCBjb2RlIGNhbiBiZSBtb3ZlZCBoZXJlLgorCit2b2lkIFdyaXRlRG9jQ29tbWVudEJvZHlJbXBsKGlvOjpQcmludGVyKiBwcmludGVyLCBTb3VyY2VMb2NhdGlvbiBsb2NhdGlvbikgeworICAgIHN0cmluZyBjb21tZW50cyA9IGxvY2F0aW9uLmxlYWRpbmdfY29tbWVudHMuZW1wdHkoKSA/CisgICAgICAgIGxvY2F0aW9uLnRyYWlsaW5nX2NvbW1lbnRzIDogbG9jYXRpb24ubGVhZGluZ19jb21tZW50czsKKyAgICBpZiAoY29tbWVudHMuZW1wdHkoKSkgeworICAgICAgICByZXR1cm47CisgICAgfQorICAgIC8vIFhNTCBlc2NhcGluZy4uLiBubyBuZWVkIGZvciBhcG9zdHJvcGhlcyBldGMgYXMgdGhlIHdob2xlIHRleHQgaXMgZ29pbmcgdG8gYmUgYSBjaGlsZAorICAgIC8vIG5vZGUgb2YgYSBzdW1tYXJ5IGVsZW1lbnQsIG5vdCBwYXJ0IG9mIGFuIGF0dHJpYnV0ZS4KKyAgICBjb21tZW50cyA9IFN0cmluZ1JlcGxhY2UoY29tbWVudHMsICImIiwgIiZhbXA7IiwgdHJ1ZSk7CisgICAgY29tbWVudHMgPSBTdHJpbmdSZXBsYWNlKGNvbW1lbnRzLCAiPCIsICImbHQ7IiwgdHJ1ZSk7CisgICAgdmVjdG9yPHN0cmluZz4gbGluZXMgPSBTcGxpdChjb21tZW50cywgIlxuIiwgZmFsc2UgLyogc2tpcF9lbXB0eSAqLyk7CisgICAgLy8gVE9ETzogV2UgcmVhbGx5IHNob3VsZCB3b3JrIG91dCB3aGljaCBwYXJ0IHRvIHB1dCBpbiB0aGUgc3VtbWFyeSBhbmQgd2hpY2ggdG8gcHV0IGluIHRoZSByZW1hcmtzLi4uCisgICAgLy8gYnV0IHRoYXQgbmVlZHMgdG8gYmUgcGFydCBvZiBhIGJpZ2dlciBlZmZvcnQgdG8gdW5kZXJzdGFuZCB0aGUgbWFya2Rvd24gYmV0dGVyIGFueXdheS4KKyAgICBwcmludGVyLT5QcmludCgiLy8vIDxzdW1tYXJ5PlxuIik7CisgICAgYm9vbCBsYXN0X3dhc19lbXB0eSA9IGZhbHNlOworICAgIC8vIFdlIHNxdWFzaCBtdWx0aXBsZSBibGFuayBsaW5lcyBkb3duIHRvIG9uZSwgYW5kIHJlbW92ZSBhbnkgdHJhaWxpbmcgYmxhbmsgbGluZXMuIFdlIG5lZWQKKyAgICAvLyB0byBwcmVzZXJ2ZSB0aGUgYmxhbmsgbGluZXMgdGhlbXNlbHZlcywgYXMgdGhpcyBpcyByZWxldmFudCBpbiB0aGUgbWFya2Rvd24uCisgICAgLy8gTm90ZSB0aGF0IHdlIGNhbid0IHJlbW92ZSBsZWFkaW5nIG9yIHRyYWlsaW5nIHdoaXRlc3BhY2UgYXMgKnRoYXQncyogcmVsZXZhbnQgaW4gbWFya2Rvd24gdG9vLgorICAgIC8vIChXZSBkb24ndCBza2lwICJqdXN0IHdoaXRlc3BhY2UiIGxpbmVzLCBlaXRoZXIuKQorICAgIGZvciAoc3RkOjp2ZWN0b3I8c3RyaW5nPjo6aXRlcmF0b3IgaXQgPSBsaW5lcy5iZWdpbigpOyBpdCAhPSBsaW5lcy5lbmQoKTsgKytpdCkgeworICAgICAgICBzdHJpbmcgbGluZSA9ICppdDsKKyAgICAgICAgaWYgKGxpbmUuZW1wdHkoKSkgeworICAgICAgICAgICAgbGFzdF93YXNfZW1wdHkgPSB0cnVlOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaWYgKGxhc3Rfd2FzX2VtcHR5KSB7CisgICAgICAgICAgICAgICAgcHJpbnRlci0+UHJpbnQoIi8vL1xuIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBsYXN0X3dhc19lbXB0eSA9IGZhbHNlOworICAgICAgICAgICAgcHJpbnRlci0+UHJpbnQoIi8vLyAkbGluZSRcbiIsICJsaW5lIiwgKml0KTsKKyAgICAgICAgfQorICAgIH0KKyAgICBwcmludGVyLT5QcmludCgiLy8vIDwvc3VtbWFyeT5cbiIpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRGVzY3JpcHRvclR5cGU+CitzdGF0aWMgdm9pZCBXcml0ZURvY0NvbW1lbnRCb2R5KAorICAgIGlvOjpQcmludGVyKiBwcmludGVyLCBjb25zdCBEZXNjcmlwdG9yVHlwZSogZGVzY3JpcHRvcikgeworICAgIFNvdXJjZUxvY2F0aW9uIGxvY2F0aW9uOworICAgIGlmIChkZXNjcmlwdG9yLT5HZXRTb3VyY2VMb2NhdGlvbigmbG9jYXRpb24pKSB7CisgICAgICAgIFdyaXRlRG9jQ29tbWVudEJvZHlJbXBsKHByaW50ZXIsIGxvY2F0aW9uKTsKKyAgICB9Cit9CisKK3ZvaWQgV3JpdGVNZXNzYWdlRG9jQ29tbWVudChpbzo6UHJpbnRlciogcHJpbnRlciwgY29uc3QgRGVzY3JpcHRvciogbWVzc2FnZSkgeworICAgIFdyaXRlRG9jQ29tbWVudEJvZHkocHJpbnRlciwgbWVzc2FnZSk7Cit9CisKK3ZvaWQgV3JpdGVQcm9wZXJ0eURvY0NvbW1lbnQoaW86OlByaW50ZXIqIHByaW50ZXIsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgICBXcml0ZURvY0NvbW1lbnRCb2R5KHByaW50ZXIsIGZpZWxkKTsKK30KKwordm9pZCBXcml0ZUVudW1Eb2NDb21tZW50KGlvOjpQcmludGVyKiBwcmludGVyLCBjb25zdCBFbnVtRGVzY3JpcHRvciogZW51bURlc2NyaXB0b3IpIHsKKyAgICBXcml0ZURvY0NvbW1lbnRCb2R5KHByaW50ZXIsIGVudW1EZXNjcmlwdG9yKTsKK30KK3ZvaWQgV3JpdGVFbnVtVmFsdWVEb2NDb21tZW50KGlvOjpQcmludGVyKiBwcmludGVyLCBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiB2YWx1ZSkgeworICAgIFdyaXRlRG9jQ29tbWVudEJvZHkocHJpbnRlciwgdmFsdWUpOworfQorCit2b2lkIFdyaXRlTWV0aG9kRG9jQ29tbWVudChpbzo6UHJpbnRlciogcHJpbnRlciwgY29uc3QgTWV0aG9kRGVzY3JpcHRvciogbWV0aG9kKSB7CisgICAgV3JpdGVEb2NDb21tZW50Qm9keShwcmludGVyLCBtZXRob2QpOworfQorCit9ICAvLyBuYW1lc3BhY2UgY3NoYXJwCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX2RvY19jb21tZW50LmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfZG9jX2NvbW1lbnQuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NWViMGVhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX2RvY19jb21tZW50LmgKQEAgLTAsMCArMSw1MSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1NIQVJQX0RPQ19DT01NRU5UX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1NIQVJQX0RPQ19DT01NRU5UX0hfXworCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGNzaGFycCB7CisgICAgdm9pZCBXcml0ZU1lc3NhZ2VEb2NDb21tZW50KGlvOjpQcmludGVyKiBwcmludGVyLCBjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlKTsKKyAgICB2b2lkIFdyaXRlUHJvcGVydHlEb2NDb21tZW50KGlvOjpQcmludGVyKiBwcmludGVyLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKTsKKyAgICB2b2lkIFdyaXRlRW51bURvY0NvbW1lbnQoaW86OlByaW50ZXIqIHByaW50ZXIsIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBlbnVtRGVzY3JpcHRvcik7CisgICAgdm9pZCBXcml0ZUVudW1WYWx1ZURvY0NvbW1lbnQoaW86OlByaW50ZXIqIHByaW50ZXIsIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIHZhbHVlKTsKKyAgICB2b2lkIFdyaXRlTWV0aG9kRG9jQ29tbWVudChpbzo6UHJpbnRlciogcHJpbnRlciwgY29uc3QgTWV0aG9kRGVzY3JpcHRvciogbWV0aG9kKTsKK30gIC8vIG5hbWVzcGFjZSBjc2hhcnAKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DU0hBUlBfRE9DX0NPTU1FTlRfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfZW51bS5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9lbnVtLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU2NjgxOTgKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfZW51bS5jYwpAQCAtMCwwICsxLDgxIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2luY2x1ZGUgPHNzdHJlYW0+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY29kZV9nZW5lcmF0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfZG9jX2NvbW1lbnQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9lbnVtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfaGVscGVycy5oPgorCit1c2luZyBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6c2NvcGVkX3B0cjsKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBjc2hhcnAgeworCitFbnVtR2VuZXJhdG9yOjpFbnVtR2VuZXJhdG9yKGNvbnN0IEVudW1EZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSA6CisgICAgU291cmNlR2VuZXJhdG9yQmFzZShkZXNjcmlwdG9yLT5maWxlKCkpLAorICAgIGRlc2NyaXB0b3JfKGRlc2NyaXB0b3IpIHsKK30KKworRW51bUdlbmVyYXRvcjo6fkVudW1HZW5lcmF0b3IoKSB7Cit9CisKK3ZvaWQgRW51bUdlbmVyYXRvcjo6R2VuZXJhdGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgV3JpdGVFbnVtRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIFdyaXRlR2VuZXJhdGVkQ29kZUF0dHJpYnV0ZXMocHJpbnRlcik7CisgIHByaW50ZXItPlByaW50KCIkYWNjZXNzX2xldmVsJCBlbnVtICRuYW1lJCB7XG4iLAorICAgICAgICAgICAgICAgICAiYWNjZXNzX2xldmVsIiwgY2xhc3NfYWNjZXNzX2xldmVsKCksCisgICAgICAgICAgICAgICAgICJuYW1lIiwgZGVzY3JpcHRvcl8tPm5hbWUoKSk7CisgIHByaW50ZXItPkluZGVudCgpOworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT52YWx1ZV9jb3VudCgpOyBpKyspIHsKKyAgICAgIFdyaXRlRW51bVZhbHVlRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXy0+dmFsdWUoaSkpOworICAgICAgcHJpbnRlci0+UHJpbnQoIiRuYW1lJCA9ICRudW1iZXIkLFxuIiwKKyAgICAgICAgICAgICAgICAgICAibmFtZSIsIGRlc2NyaXB0b3JfLT52YWx1ZShpKS0+bmFtZSgpLAorICAgICAgICAgICAgICAgICAgICJudW1iZXIiLCBTaW1wbGVJdG9hKGRlc2NyaXB0b3JfLT52YWx1ZShpKS0+bnVtYmVyKCkpKTsKKyAgfQorICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KCJ9XG4iKTsKKyAgcHJpbnRlci0+UHJpbnQoIlxuIik7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBjc2hhcnAKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfZW51bS5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX2VudW0uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yY2YyZmFkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX2VudW0uaApAQCAtMCwwICsxLDYzIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1NIQVJQX0VOVU1fSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DU0hBUlBfRU5VTV9IX18KKworI2luY2x1ZGUgPHN0cmluZz4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jb2RlX2dlbmVyYXRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX3NvdXJjZV9nZW5lcmF0b3JfYmFzZS5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGNzaGFycCB7CisKK2NsYXNzIEVudW1HZW5lcmF0b3IgOiBwdWJsaWMgU291cmNlR2VuZXJhdG9yQmFzZSB7CisgcHVibGljOgorICBFbnVtR2VuZXJhdG9yKGNvbnN0IEVudW1EZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKKyAgfkVudW1HZW5lcmF0b3IoKTsKKworICB2b2lkIEdlbmVyYXRlKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworIHByaXZhdGU6CisgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoRW51bUdlbmVyYXRvcik7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgY3NoYXJwCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DU0hBUlBfRU5VTV9IX18KKwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX2VudW1fZmllbGQuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfZW51bV9maWVsZC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kMzhmYjFlCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX2VudW1fZmllbGQuY2MKQEAgLTAsMCArMSwxMTkgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaW5jbHVkZSA8c3N0cmVhbT4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jb2RlX2dlbmVyYXRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wbHVnaW4uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbS5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfaGVscGVycy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX2VudW1fZmllbGQuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBjc2hhcnAgeworCitFbnVtRmllbGRHZW5lcmF0b3I6OkVudW1GaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZmllbGRPcmRpbmFsKQorICAgIDogUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IoZGVzY3JpcHRvciwgZmllbGRPcmRpbmFsKSB7Cit9CisKK0VudW1GaWVsZEdlbmVyYXRvcjo6fkVudW1GaWVsZEdlbmVyYXRvcigpIHsKK30KKwordm9pZCBFbnVtRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJG5hbWUkXyA9ICgkdHlwZV9uYW1lJCkgaW5wdXQuUmVhZEVudW0oKTtcbiIpOworfQorCit2b2lkIEVudW1GaWVsZEdlbmVyYXRvcjo6R2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoJGhhc19wcm9wZXJ0eV9jaGVjayQpIHtcbiIKKyAgICAiICBvdXRwdXQuV3JpdGVSYXdUYWcoJHRhZ19ieXRlcyQpO1xuIgorICAgICIgIG91dHB1dC5Xcml0ZUVudW0oKGludCkgJHByb3BlcnR5X25hbWUkKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgRW51bUZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICB2YXJpYWJsZXNfLAorICAgICJpZiAoJGhhc19wcm9wZXJ0eV9jaGVjayQpIHtcbiIKKyAgICAgICIgIHNpemUgKz0gJHRhZ19zaXplJCArIHBiOjpDb2RlZE91dHB1dFN0cmVhbS5Db21wdXRlRW51bVNpemUoKGludCkgJHByb3BlcnR5X25hbWUkKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgRW51bUZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZUNvZGVjQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICB2YXJpYWJsZXNfLAorICAgICAgICAicGI6OkZpZWxkQ29kZWMuRm9yRW51bSgkdGFnJCwgeCA9PiAoaW50KSB4LCB4ID0+ICgkdHlwZV9uYW1lJCkgeCkiKTsKK30KKworRW51bU9uZW9mRmllbGRHZW5lcmF0b3I6OkVudW1PbmVvZkZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKwkJCQkJCSBpbnQgZmllbGRPcmRpbmFsKQorICA6IFByaW1pdGl2ZU9uZW9mRmllbGRHZW5lcmF0b3IoZGVzY3JpcHRvciwgZmllbGRPcmRpbmFsKSB7Cit9CisKK0VudW1PbmVvZkZpZWxkR2VuZXJhdG9yOjp+RW51bU9uZW9mRmllbGRHZW5lcmF0b3IoKSB7Cit9CisKK3ZvaWQgRW51bU9uZW9mRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgLy8gVE9ETyhqb25za2VldCk6IFdoYXQgYWJvdXQgaWYgd2UgcmVhZCB0aGUgZGVmYXVsdCB2YWx1ZT8KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgdmFyaWFibGVzXywKKyAgICAiJG9uZW9mX25hbWUkXyA9IGlucHV0LlJlYWRFbnVtKCk7XG4iCisgICAgIiRvbmVvZl9uYW1lJENhc2VfID0gJG9uZW9mX3Byb3BlcnR5X25hbWUkT25lb2ZDYXNlLiRwcm9wZXJ0eV9uYW1lJDtcbiIpOworfQorCit2b2lkIEVudW1PbmVvZkZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgIHZhcmlhYmxlc18sCisgICAgImlmICgkaGFzX3Byb3BlcnR5X2NoZWNrJCkge1xuIgorICAgICIgIG91dHB1dC5Xcml0ZVJhd1RhZygkdGFnX2J5dGVzJCk7XG4iCisgICAgIiAgb3V0cHV0LldyaXRlRW51bSgoaW50KSAkcHJvcGVydHlfbmFtZSQpO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBFbnVtT25lb2ZGaWVsZEdlbmVyYXRvcjo6R2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgdmFyaWFibGVzXywKKyAgICAiaWYgKCRoYXNfcHJvcGVydHlfY2hlY2skKSB7XG4iCisgICAgIiAgc2l6ZSArPSAkdGFnX3NpemUkICsgcGI6OkNvZGVkT3V0cHV0U3RyZWFtLkNvbXB1dGVFbnVtU2l6ZSgoaW50KSAkcHJvcGVydHlfbmFtZSQpO1xuIgorICAgICJ9XG4iKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGNzaGFycAorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9lbnVtX2ZpZWxkLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfZW51bV9maWVsZC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA4MzY0MTUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfZW51bV9maWVsZC5oCkBAIC0wLDAgKzEsNzcgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DU0hBUlBfRU5VTV9GSUVMRF9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NTSEFSUF9FTlVNX0ZJRUxEX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvZGVfZ2VuZXJhdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfcHJpbWl0aXZlX2ZpZWxkLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgY3NoYXJwIHsKKworY2xhc3MgRW51bUZpZWxkR2VuZXJhdG9yIDogcHVibGljIFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIEVudW1GaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGludCBmaWVsZE9yZGluYWwpOworICB+RW51bUZpZWxkR2VuZXJhdG9yKCk7CisKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlQ29kZWNDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoRW51bUZpZWxkR2VuZXJhdG9yKTsKK307CisKK2NsYXNzIEVudW1PbmVvZkZpZWxkR2VuZXJhdG9yIDogcHVibGljIFByaW1pdGl2ZU9uZW9mRmllbGRHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgRW51bU9uZW9mRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBpbnQgZmllbGRPcmRpbmFsKTsKKyAgfkVudW1PbmVvZkZpZWxkR2VuZXJhdG9yKCk7CisKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoRW51bU9uZW9mRmllbGRHZW5lcmF0b3IpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGNzaGFycAorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1NIQVJQX0VOVU1fRklFTERfSF9fCisKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9maWVsZF9iYXNlLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX2ZpZWxkX2Jhc2UuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWRmNDNkMwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9maWVsZF9iYXNlLmNjCkBAIC0wLDAgKzEsNDI1IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2luY2x1ZGUgPGxpbWl0cz4KKyNpbmNsdWRlIDxzc3RyZWFtPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvZGVfZ2VuZXJhdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BsdWdpbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9tYXRobGltaXRzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuaD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX2ZpZWxkX2Jhc2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfbmFtZXMuaD4KKwordXNpbmcgZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OnNjb3BlZF9wdHI7CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgY3NoYXJwIHsKKwordm9pZCBGaWVsZEdlbmVyYXRvckJhc2U6OlNldENvbW1vbkZpZWxkVmFyaWFibGVzKAorICAgIG1hcDxzdHJpbmcsIHN0cmluZz4qIHZhcmlhYmxlcykgeworICAvLyBOb3RlOiB0aGlzIHdpbGwgYmUgdmFsaWQgZXZlbiB0aG91Z2ggdGhlIHRhZyBlbWl0dGVkIGZvciBwYWNrZWQgYW5kIHVucGFja2VkIHZlcnNpb25zIG9mCisgIC8vIHJlcGVhdGVkIGZpZWxkcyB2YXJpZXMgYnkgd2lyZSBmb3JtYXQuIFRoZSB3aXJlIGZvcm1hdCBpcyBlbmNvZGVkIGluIHRoZSBib3R0b20gMyBiaXRzLCB3aGljaAorICAvLyBuZXZlciBlZmZlY3RzIHRoZSB0YWcgc2l6ZS4KKyAgaW50IHRhZ19zaXplID0gaW50ZXJuYWw6OldpcmVGb3JtYXQ6OlRhZ1NpemUoZGVzY3JpcHRvcl8tPm51bWJlcigpLCBkZXNjcmlwdG9yXy0+dHlwZSgpKTsKKyAgdWludCB0YWcgPSBpbnRlcm5hbDo6V2lyZUZvcm1hdDo6TWFrZVRhZyhkZXNjcmlwdG9yXyk7CisgIHVpbnQ4IHRhZ19hcnJheVs1XTsKKyAgaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZVRhZ1RvQXJyYXkodGFnLCB0YWdfYXJyYXkpOworICBzdHJpbmcgdGFnX2J5dGVzID0gU2ltcGxlSXRvYSh0YWdfYXJyYXlbMF0pOworICBmb3IgKGludCBpID0gMTsgaSA8IHRhZ19zaXplOyBpKyspIHsKKyAgICB0YWdfYnl0ZXMgKz0gIiwgIiArIFNpbXBsZUl0b2EodGFnX2FycmF5W2ldKTsKKyAgfQorCisgICgqdmFyaWFibGVzKVsiYWNjZXNzX2xldmVsIl0gPSAicHVibGljIjsKKyAgKCp2YXJpYWJsZXMpWyJ0YWciXSA9IFNpbXBsZUl0b2EodGFnKTsKKyAgKCp2YXJpYWJsZXMpWyJ0YWdfc2l6ZSJdID0gU2ltcGxlSXRvYSh0YWdfc2l6ZSk7CisgICgqdmFyaWFibGVzKVsidGFnX2J5dGVzIl0gPSB0YWdfYnl0ZXM7CisKKyAgKCp2YXJpYWJsZXMpWyJwcm9wZXJ0eV9uYW1lIl0gPSBwcm9wZXJ0eV9uYW1lKCk7CisgICgqdmFyaWFibGVzKVsidHlwZV9uYW1lIl0gPSB0eXBlX25hbWUoKTsKKyAgKCp2YXJpYWJsZXMpWyJuYW1lIl0gPSBuYW1lKCk7CisgICgqdmFyaWFibGVzKVsiZGVzY3JpcHRvcl9uYW1lIl0gPSBkZXNjcmlwdG9yXy0+bmFtZSgpOworICAoKnZhcmlhYmxlcylbImRlZmF1bHRfdmFsdWUiXSA9IGRlZmF1bHRfdmFsdWUoKTsKKyAgaWYgKGhhc19kZWZhdWx0X3ZhbHVlKCkpIHsKKyAgICAoKnZhcmlhYmxlcylbIm5hbWVfZGVmX21lc3NhZ2UiXSA9CisgICAgICAoKnZhcmlhYmxlcylbIm5hbWUiXSArICJfID0gIiArICgqdmFyaWFibGVzKVsiZGVmYXVsdF92YWx1ZSJdOworICB9IGVsc2UgeworICAgICgqdmFyaWFibGVzKVsibmFtZV9kZWZfbWVzc2FnZSJdID0gKCp2YXJpYWJsZXMpWyJuYW1lIl0gKyAiXyI7CisgIH0KKyAgKCp2YXJpYWJsZXMpWyJjYXBpdGFsaXplZF90eXBlX25hbWUiXSA9IGNhcGl0YWxpemVkX3R5cGVfbmFtZSgpOworICAoKnZhcmlhYmxlcylbIm51bWJlciJdID0gbnVtYmVyKCk7CisgICgqdmFyaWFibGVzKVsiaGFzX3Byb3BlcnR5X2NoZWNrIl0gPQorICAgICgqdmFyaWFibGVzKVsicHJvcGVydHlfbmFtZSJdICsgIiAhPSAiICsgKCp2YXJpYWJsZXMpWyJkZWZhdWx0X3ZhbHVlIl07CisgICgqdmFyaWFibGVzKVsib3RoZXJfaGFzX3Byb3BlcnR5X2NoZWNrIl0gPSAib3RoZXIuIiArCisgICAgKCp2YXJpYWJsZXMpWyJwcm9wZXJ0eV9uYW1lIl0gKyAiICE9ICIgKyAoKnZhcmlhYmxlcylbImRlZmF1bHRfdmFsdWUiXTsKK30KKwordm9pZCBGaWVsZEdlbmVyYXRvckJhc2U6OlNldENvbW1vbk9uZW9mRmllbGRWYXJpYWJsZXMoCisgICAgbWFwPHN0cmluZywgc3RyaW5nPiogdmFyaWFibGVzKSB7CisgICgqdmFyaWFibGVzKVsib25lb2ZfbmFtZSJdID0gb25lb2ZfbmFtZSgpOworICAoKnZhcmlhYmxlcylbImhhc19wcm9wZXJ0eV9jaGVjayJdID0gb25lb2ZfbmFtZSgpICsgIkNhc2VfID09ICIgKyBvbmVvZl9wcm9wZXJ0eV9uYW1lKCkgKworICAgICJPbmVvZkNhc2UuIiArIHByb3BlcnR5X25hbWUoKTsKKyAgKCp2YXJpYWJsZXMpWyJvbmVvZl9wcm9wZXJ0eV9uYW1lIl0gPSBvbmVvZl9wcm9wZXJ0eV9uYW1lKCk7Cit9CisKK0ZpZWxkR2VuZXJhdG9yQmFzZTo6RmllbGRHZW5lcmF0b3JCYXNlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBmaWVsZE9yZGluYWwpCisgICAgOiBTb3VyY2VHZW5lcmF0b3JCYXNlKGRlc2NyaXB0b3ItPmZpbGUoKSksCisgICAgICBkZXNjcmlwdG9yXyhkZXNjcmlwdG9yKSwKKyAgICAgIGZpZWxkT3JkaW5hbF8oZmllbGRPcmRpbmFsKSB7CisgIFNldENvbW1vbkZpZWxkVmFyaWFibGVzKCZ2YXJpYWJsZXNfKTsKK30KKworRmllbGRHZW5lcmF0b3JCYXNlOjp+RmllbGRHZW5lcmF0b3JCYXNlKCkgeworfQorCit2b2lkIEZpZWxkR2VuZXJhdG9yQmFzZTo6R2VuZXJhdGVGcmVlemluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgLy8gTm8tb3A6IG9ubHkgbWVzc2FnZSBmaWVsZHMgYW5kIHJlcGVhdGVkIGZpZWxkcyBuZWVkCisgIC8vIHNwZWNpYWwgaGFuZGxpbmcgZm9yIGZyZWV6aW5nLCBzbyBkZWZhdWx0IHRvIG5vdCBnZW5lcmF0aW5nIGFueSBjb2RlLgorfQorCit2b2lkIEZpZWxkR2VuZXJhdG9yQmFzZTo6R2VuZXJhdGVDb2RlY0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgICAvLyBOby1vcDogZXhwZWN0IHRoaXMgdG8gYmUgb3ZlcnJpZGRlbiBieSBhcHByb3ByaWF0ZSB0eXBlcy4KKyAgICAvLyBDb3VsZCBmYWlsIGlmIHdlIGdldCBjYWxsZWQgaGVyZSB0aG91Z2guLi4KK30KKwordm9pZCBGaWVsZEdlbmVyYXRvckJhc2U6OkFkZERlcHJlY2F0ZWRGbGFnKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIGlmIChkZXNjcmlwdG9yXy0+b3B0aW9ucygpLmRlcHJlY2F0ZWQoKSkKKyAgeworICAgIHByaW50ZXItPlByaW50KCJbZ2xvYmFsOjpTeXN0ZW0uT2Jzb2xldGVBdHRyaWJ1dGUoKV1cbiIpOworICB9Cit9CisKK3ZvaWQgRmllbGRHZW5lcmF0b3JCYXNlOjpBZGRQdWJsaWNNZW1iZXJBdHRyaWJ1dGVzKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIEFkZERlcHJlY2F0ZWRGbGFnKHByaW50ZXIpOworfQorCitzdGQ6OnN0cmluZyBGaWVsZEdlbmVyYXRvckJhc2U6Om9uZW9mX3Byb3BlcnR5X25hbWUoKSB7CisgIHJldHVybiBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlKGRlc2NyaXB0b3JfLT5jb250YWluaW5nX29uZW9mKCktPm5hbWUoKSwgdHJ1ZSk7Cit9CisKK3N0ZDo6c3RyaW5nIEZpZWxkR2VuZXJhdG9yQmFzZTo6b25lb2ZfbmFtZSgpIHsKKyAgcmV0dXJuIFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoZGVzY3JpcHRvcl8tPmNvbnRhaW5pbmdfb25lb2YoKS0+bmFtZSgpLCBmYWxzZSk7Cit9CisKK3N0ZDo6c3RyaW5nIEZpZWxkR2VuZXJhdG9yQmFzZTo6cHJvcGVydHlfbmFtZSgpIHsKKyAgcmV0dXJuIEdldFByb3BlcnR5TmFtZShkZXNjcmlwdG9yXyk7Cit9CisKK3N0ZDo6c3RyaW5nIEZpZWxkR2VuZXJhdG9yQmFzZTo6bmFtZSgpIHsKKyAgcmV0dXJuIFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoR2V0RmllbGROYW1lKGRlc2NyaXB0b3JfKSwgZmFsc2UpOworfQorCitzdGQ6OnN0cmluZyBGaWVsZEdlbmVyYXRvckJhc2U6OnR5cGVfbmFtZSgpIHsKKyAgcmV0dXJuIHR5cGVfbmFtZShkZXNjcmlwdG9yXyk7Cit9CisKK3N0ZDo6c3RyaW5nIEZpZWxkR2VuZXJhdG9yQmFzZTo6dHlwZV9uYW1lKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBzd2l0Y2ggKGRlc2NyaXB0b3ItPnR5cGUoKSkgeworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0VOVU06CisgICAgICByZXR1cm4gR2V0Q2xhc3NOYW1lKGRlc2NyaXB0b3ItPmVudW1fdHlwZSgpKTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9NRVNTQUdFOgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQOgorICAgICAgaWYgKElzV3JhcHBlclR5cGUoZGVzY3JpcHRvcikpIHsKKyAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiB3cmFwcGVkX2ZpZWxkID0gZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCktPmZpZWxkKDApOworICAgICAgICBzdHJpbmcgd3JhcHBlZF9maWVsZF90eXBlX25hbWUgPSB0eXBlX25hbWUod3JhcHBlZF9maWVsZCk7CisgICAgICAgIC8vIFN0cmluZyBhbmQgQnl0ZVN0cmluZyBnbyB0byB0aGUgc2FtZSB0eXBlOyBvdGhlciB3cmFwcGVkIHR5cGVzIGdvIHRvIHRoZQorICAgICAgICAvLyBudWxsYWJsZSBlcXVpdmFsZW50LgorICAgICAgICBpZiAod3JhcHBlZF9maWVsZC0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TVFJJTkcgfHwKKyAgICAgICAgICAgIHdyYXBwZWRfZmllbGQtPnR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfQllURVMpIHsKKyAgICAgICAgICByZXR1cm4gd3JhcHBlZF9maWVsZF90eXBlX25hbWU7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgcmV0dXJuIHdyYXBwZWRfZmllbGRfdHlwZV9uYW1lICsgIj8iOworICAgICAgICB9CisgICAgICB9CisgICAgICByZXR1cm4gR2V0Q2xhc3NOYW1lKGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpKTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9ET1VCTEU6CisgICAgICByZXR1cm4gImRvdWJsZSI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRkxPQVQ6CisgICAgICByZXR1cm4gImZsb2F0IjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9JTlQ2NDoKKyAgICAgIHJldHVybiAibG9uZyI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfVUlOVDY0OgorICAgICAgcmV0dXJuICJ1bG9uZyI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfSU5UMzI6CisgICAgICByZXR1cm4gImludCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRklYRUQ2NDoKKyAgICAgIHJldHVybiAidWxvbmciOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0ZJWEVEMzI6CisgICAgICByZXR1cm4gInVpbnQiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0JPT0w6CisgICAgICByZXR1cm4gImJvb2wiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NUUklORzoKKyAgICAgIHJldHVybiAic3RyaW5nIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9CWVRFUzoKKyAgICAgIHJldHVybiAicGI6OkJ5dGVTdHJpbmciOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1VJTlQzMjoKKyAgICAgIHJldHVybiAidWludCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0ZJWEVEMzI6CisgICAgICByZXR1cm4gImludCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0ZJWEVENjQ6CisgICAgICByZXR1cm4gImxvbmciOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NJTlQzMjoKKyAgICAgIHJldHVybiAiaW50IjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TSU5UNjQ6CisgICAgICByZXR1cm4gImxvbmciOworICAgIGRlZmF1bHQ6CisgICAgICBHT09HTEVfTE9HKEZBVEFMKTw8ICJVbmtub3duIGZpZWxkIHR5cGUuIjsKKyAgICAgIHJldHVybiAiIjsKKyAgfQorfQorCitib29sIEZpZWxkR2VuZXJhdG9yQmFzZTo6aGFzX2RlZmF1bHRfdmFsdWUoKSB7CisgIHN3aXRjaCAoZGVzY3JpcHRvcl8tPnR5cGUoKSkgeworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0VOVU06CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfTUVTU0FHRToKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9HUk9VUDoKKyAgICAgIHJldHVybiB0cnVlOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0RPVUJMRToKKyAgICAgIHJldHVybiBkZXNjcmlwdG9yXy0+ZGVmYXVsdF92YWx1ZV9kb3VibGUoKSAhPSAwLjA7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRkxPQVQ6CisgICAgICByZXR1cm4gZGVzY3JpcHRvcl8tPmRlZmF1bHRfdmFsdWVfZmxvYXQoKSAhPSAwLjA7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfSU5UNjQ6CisgICAgICByZXR1cm4gZGVzY3JpcHRvcl8tPmRlZmF1bHRfdmFsdWVfaW50NjQoKSAhPSAwTDsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9VSU5UNjQ6CisgICAgICByZXR1cm4gZGVzY3JpcHRvcl8tPmRlZmF1bHRfdmFsdWVfdWludDY0KCkgIT0gMEw7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfSU5UMzI6CisgICAgICByZXR1cm4gZGVzY3JpcHRvcl8tPmRlZmF1bHRfdmFsdWVfaW50MzIoKSAhPSAwOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0ZJWEVENjQ6CisgICAgICByZXR1cm4gZGVzY3JpcHRvcl8tPmRlZmF1bHRfdmFsdWVfdWludDY0KCkgIT0gMEw7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRklYRUQzMjoKKyAgICAgIHJldHVybiBkZXNjcmlwdG9yXy0+ZGVmYXVsdF92YWx1ZV91aW50MzIoKSAhPSAwOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0JPT0w6CisgICAgICByZXR1cm4gZGVzY3JpcHRvcl8tPmRlZmF1bHRfdmFsdWVfYm9vbCgpOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NUUklORzoKKyAgICAgIHJldHVybiB0cnVlOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0JZVEVTOgorICAgICAgcmV0dXJuIHRydWU7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfVUlOVDMyOgorICAgICAgcmV0dXJuIGRlc2NyaXB0b3JfLT5kZWZhdWx0X3ZhbHVlX3VpbnQzMigpICE9IDA7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0ZJWEVEMzI6CisgICAgICByZXR1cm4gZGVzY3JpcHRvcl8tPmRlZmF1bHRfdmFsdWVfaW50MzIoKSAhPSAwOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NGSVhFRDY0OgorICAgICAgcmV0dXJuIGRlc2NyaXB0b3JfLT5kZWZhdWx0X3ZhbHVlX2ludDY0KCkgIT0gMEw7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0lOVDMyOgorICAgICAgcmV0dXJuIGRlc2NyaXB0b3JfLT5kZWZhdWx0X3ZhbHVlX2ludDMyKCkgIT0gMDsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TSU5UNjQ6CisgICAgICByZXR1cm4gZGVzY3JpcHRvcl8tPmRlZmF1bHRfdmFsdWVfaW50NjQoKSAhPSAwTDsKKyAgICBkZWZhdWx0OgorICAgICAgR09PR0xFX0xPRyhGQVRBTCk8PCAiVW5rbm93biBmaWVsZCB0eXBlLiI7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgfQorfQorCitib29sIEZpZWxkR2VuZXJhdG9yQmFzZTo6aXNfbnVsbGFibGVfdHlwZSgpIHsKKyAgc3dpdGNoIChkZXNjcmlwdG9yXy0+dHlwZSgpKSB7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRU5VTToKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9ET1VCTEU6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRkxPQVQ6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfSU5UNjQ6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfVUlOVDY0OgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0lOVDMyOgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0ZJWEVENjQ6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRklYRUQzMjoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9CT09MOgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1VJTlQzMjoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TRklYRUQzMjoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TRklYRUQ2NDoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TSU5UMzI6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0lOVDY0OgorICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfTUVTU0FHRToKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9HUk9VUDoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TVFJJTkc6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfQllURVM6CisgICAgICByZXR1cm4gdHJ1ZTsKKworICAgIGRlZmF1bHQ6CisgICAgICBHT09HTEVfTE9HKEZBVEFMKTw8ICJVbmtub3duIGZpZWxkIHR5cGUuIjsKKyAgICAgIHJldHVybiB0cnVlOworICB9Cit9CisKK2Jvb2wgQWxsUHJpbnRhYmxlQXNjaWkoY29uc3Qgc3RkOjpzdHJpbmcmIHRleHQpIHsKKyAgZm9yKGludCBpID0gMDsgaSA8IHRleHQuc2l6ZSgpOyBpKyspIHsKKyAgICBpZiAodGV4dFtpXSA8IDB4MjAgfHwgdGV4dFtpXSA+IDB4N2UpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKK3N0ZDo6c3RyaW5nIEZpZWxkR2VuZXJhdG9yQmFzZTo6R2V0U3RyaW5nRGVmYXVsdFZhbHVlSW50ZXJuYWwoKSB7CisgIC8vIE5vIG90aGVyIGRlZmF1bHQgdmFsdWVzIG5lZWRlZCBmb3IgcHJvdG8zLi4uCisgIHJldHVybiAiXCJcIiI7Cit9CisKK3N0ZDo6c3RyaW5nIEZpZWxkR2VuZXJhdG9yQmFzZTo6R2V0Qnl0ZXNEZWZhdWx0VmFsdWVJbnRlcm5hbCgpIHsKKyAgLy8gTm8gb3RoZXIgZGVmYXVsdCB2YWx1ZXMgbmVlZGVkIGZvciBwcm90bzMuLi4KKyAgcmV0dXJuICJwYjo6Qnl0ZVN0cmluZy5FbXB0eSI7Cit9CisKK3N0ZDo6c3RyaW5nIEZpZWxkR2VuZXJhdG9yQmFzZTo6ZGVmYXVsdF92YWx1ZSgpIHsKKyAgICByZXR1cm4gZGVmYXVsdF92YWx1ZShkZXNjcmlwdG9yXyk7Cit9CisKK3N0ZDo6c3RyaW5nIEZpZWxkR2VuZXJhdG9yQmFzZTo6ZGVmYXVsdF92YWx1ZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgc3dpdGNoIChkZXNjcmlwdG9yLT50eXBlKCkpIHsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9FTlVNOgorICAgICAgcmV0dXJuIHR5cGVfbmFtZSgpICsgIi4iICsgZGVzY3JpcHRvci0+ZGVmYXVsdF92YWx1ZV9lbnVtKCktPm5hbWUoKTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9NRVNTQUdFOgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQOgorICAgICAgaWYgKElzV3JhcHBlclR5cGUoZGVzY3JpcHRvcikpIHsKKyAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiB3cmFwcGVkX2ZpZWxkID0gZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCktPmZpZWxkKDApOworICAgICAgICByZXR1cm4gZGVmYXVsdF92YWx1ZSh3cmFwcGVkX2ZpZWxkKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiAibnVsbCI7CisgICAgICB9CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRE9VQkxFOiB7CisgICAgICBkb3VibGUgdmFsdWUgPSBkZXNjcmlwdG9yLT5kZWZhdWx0X3ZhbHVlX2RvdWJsZSgpOworICAgICAgaWYgKHZhbHVlID09IG51bWVyaWNfbGltaXRzPGRvdWJsZT46OmluZmluaXR5KCkpIHsKKyAgICAgICAgcmV0dXJuICJkb3VibGUuUG9zaXRpdmVJbmZpbml0eSI7CisgICAgICB9IGVsc2UgaWYgKHZhbHVlID09IC1udW1lcmljX2xpbWl0czxkb3VibGU+OjppbmZpbml0eSgpKSB7CisgICAgICAgIHJldHVybiAiZG91YmxlLk5lZ2F0aXZlSW5maW5pdHkiOworICAgICAgfSBlbHNlIGlmIChNYXRoTGltaXRzPGRvdWJsZT46OklzTmFOKHZhbHVlKSkgeworICAgICAgICByZXR1cm4gImRvdWJsZS5OYU4iOworICAgICAgfQorICAgICAgcmV0dXJuIFNpbXBsZUR0b2EodmFsdWUpICsgIkQiOworICAgIH0KKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9GTE9BVDogeworICAgICAgZmxvYXQgdmFsdWUgPSBkZXNjcmlwdG9yLT5kZWZhdWx0X3ZhbHVlX2Zsb2F0KCk7CisgICAgICBpZiAodmFsdWUgPT0gbnVtZXJpY19saW1pdHM8ZmxvYXQ+OjppbmZpbml0eSgpKSB7CisgICAgICAgIHJldHVybiAiZmxvYXQuUG9zaXRpdmVJbmZpbml0eSI7CisgICAgICB9IGVsc2UgaWYgKHZhbHVlID09IC1udW1lcmljX2xpbWl0czxmbG9hdD46OmluZmluaXR5KCkpIHsKKyAgICAgICAgcmV0dXJuICJmbG9hdC5OZWdhdGl2ZUluZmluaXR5IjsKKyAgICAgIH0gZWxzZSBpZiAoTWF0aExpbWl0czxmbG9hdD46OklzTmFOKHZhbHVlKSkgeworICAgICAgICByZXR1cm4gImZsb2F0Lk5hTiI7CisgICAgICB9CisgICAgICByZXR1cm4gU2ltcGxlRnRvYSh2YWx1ZSkgKyAiRiI7CisgICAgfQorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0lOVDY0OgorICAgICAgcmV0dXJuIFNpbXBsZUl0b2EoZGVzY3JpcHRvci0+ZGVmYXVsdF92YWx1ZV9pbnQ2NCgpKSArICJMIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9VSU5UNjQ6CisgICAgICByZXR1cm4gU2ltcGxlSXRvYShkZXNjcmlwdG9yLT5kZWZhdWx0X3ZhbHVlX3VpbnQ2NCgpKSArICJVTCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfSU5UMzI6CisgICAgICByZXR1cm4gU2ltcGxlSXRvYShkZXNjcmlwdG9yLT5kZWZhdWx0X3ZhbHVlX2ludDMyKCkpOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0ZJWEVENjQ6CisgICAgICByZXR1cm4gU2ltcGxlSXRvYShkZXNjcmlwdG9yLT5kZWZhdWx0X3ZhbHVlX3VpbnQ2NCgpKSArICJVTCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRklYRUQzMjoKKyAgICAgIHJldHVybiBTaW1wbGVJdG9hKGRlc2NyaXB0b3ItPmRlZmF1bHRfdmFsdWVfdWludDMyKCkpOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0JPT0w6CisgICAgICBpZiAoZGVzY3JpcHRvci0+ZGVmYXVsdF92YWx1ZV9ib29sKCkpIHsKKyAgICAgICAgcmV0dXJuICJ0cnVlIjsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiAiZmFsc2UiOworICAgICAgfQorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NUUklORzoKKyAgICAgIHJldHVybiBHZXRTdHJpbmdEZWZhdWx0VmFsdWVJbnRlcm5hbCgpOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0JZVEVTOgorICAgICAgcmV0dXJuIEdldEJ5dGVzRGVmYXVsdFZhbHVlSW50ZXJuYWwoKTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9VSU5UMzI6CisgICAgICByZXR1cm4gU2ltcGxlSXRvYShkZXNjcmlwdG9yLT5kZWZhdWx0X3ZhbHVlX3VpbnQzMigpKTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TRklYRUQzMjoKKyAgICAgIHJldHVybiBTaW1wbGVJdG9hKGRlc2NyaXB0b3ItPmRlZmF1bHRfdmFsdWVfaW50MzIoKSk7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0ZJWEVENjQ6CisgICAgICByZXR1cm4gU2ltcGxlSXRvYShkZXNjcmlwdG9yLT5kZWZhdWx0X3ZhbHVlX2ludDY0KCkpICsgIkwiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NJTlQzMjoKKyAgICAgIHJldHVybiBTaW1wbGVJdG9hKGRlc2NyaXB0b3ItPmRlZmF1bHRfdmFsdWVfaW50MzIoKSk7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0lOVDY0OgorICAgICAgcmV0dXJuIFNpbXBsZUl0b2EoZGVzY3JpcHRvci0+ZGVmYXVsdF92YWx1ZV9pbnQ2NCgpKSArICJMIjsKKyAgICBkZWZhdWx0OgorICAgICAgR09PR0xFX0xPRyhGQVRBTCk8PCAiVW5rbm93biBmaWVsZCB0eXBlLiI7CisgICAgICByZXR1cm4gIiI7CisgIH0KK30KKworc3RkOjpzdHJpbmcgRmllbGRHZW5lcmF0b3JCYXNlOjpudW1iZXIoKSB7CisgIHJldHVybiBTaW1wbGVJdG9hKGRlc2NyaXB0b3JfLT5udW1iZXIoKSk7Cit9CisKK3N0ZDo6c3RyaW5nIEZpZWxkR2VuZXJhdG9yQmFzZTo6Y2FwaXRhbGl6ZWRfdHlwZV9uYW1lKCkgeworICBzd2l0Y2ggKGRlc2NyaXB0b3JfLT50eXBlKCkpIHsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9FTlVNOgorICAgICAgcmV0dXJuICJFbnVtIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9NRVNTQUdFOgorICAgICAgcmV0dXJuICJNZXNzYWdlIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9HUk9VUDoKKyAgICAgIHJldHVybiAiR3JvdXAiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0RPVUJMRToKKyAgICAgIHJldHVybiAiRG91YmxlIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9GTE9BVDoKKyAgICAgIHJldHVybiAiRmxvYXQiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0lOVDY0OgorICAgICAgcmV0dXJuICJJbnQ2NCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfVUlOVDY0OgorICAgICAgcmV0dXJuICJVSW50NjQiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0lOVDMyOgorICAgICAgcmV0dXJuICJJbnQzMiI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRklYRUQ2NDoKKyAgICAgIHJldHVybiAiRml4ZWQ2NCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRklYRUQzMjoKKyAgICAgIHJldHVybiAiRml4ZWQzMiI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfQk9PTDoKKyAgICAgIHJldHVybiAiQm9vbCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU1RSSU5HOgorICAgICAgcmV0dXJuICJTdHJpbmciOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0JZVEVTOgorICAgICAgcmV0dXJuICJCeXRlcyI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfVUlOVDMyOgorICAgICAgcmV0dXJuICJVSW50MzIiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NGSVhFRDMyOgorICAgICAgcmV0dXJuICJTRml4ZWQzMiI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0ZJWEVENjQ6CisgICAgICByZXR1cm4gIlNGaXhlZDY0IjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TSU5UMzI6CisgICAgICByZXR1cm4gIlNJbnQzMiI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0lOVDY0OgorICAgICAgcmV0dXJuICJTSW50NjQiOworICAgIGRlZmF1bHQ6CisgICAgICBHT09HTEVfTE9HKEZBVEFMKTw8ICJVbmtub3duIGZpZWxkIHR5cGUuIjsKKyAgICAgIHJldHVybiAiIjsKKyAgfQorfQorCit9ICAvLyBuYW1lc3BhY2UgY3NoYXJwCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX2ZpZWxkX2Jhc2UuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9maWVsZF9iYXNlLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDgzNTQzYgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9maWVsZF9iYXNlLmgKQEAgLTAsMCArMSwxMDMgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DU0hBUlBfRklFTERfQkFTRV9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NTSEFSUF9GSUVMRF9CQVNFX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY29kZV9nZW5lcmF0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9zb3VyY2VfZ2VuZXJhdG9yX2Jhc2UuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBjc2hhcnAgeworCitjbGFzcyBGaWVsZEdlbmVyYXRvckJhc2UgOiBwdWJsaWMgU291cmNlR2VuZXJhdG9yQmFzZSB7CisgcHVibGljOgorICBGaWVsZEdlbmVyYXRvckJhc2UoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBpbnQgZmllbGRPcmRpbmFsKTsKKyAgfkZpZWxkR2VuZXJhdG9yQmFzZSgpOworCisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZUNsb25pbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSA9IDA7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZUZyZWV6aW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZUNvZGVjQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpID0gMDsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpID0gMDsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpID0gMDsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpID0gMDsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSA9IDA7CisKKyAgdmlydHVhbCB2b2lkIFdyaXRlSGFzaChpbzo6UHJpbnRlciogcHJpbnRlcikgPSAwOworICB2aXJ0dWFsIHZvaWQgV3JpdGVFcXVhbHMoaW86OlByaW50ZXIqIHByaW50ZXIpID0gMDsKKyAgLy8gQ3VycmVudGx5IHVudXNlZCwgYXMgd2UgdXNlIHJlZmxlY3Rpb24gdG8gZ2VuZXJhdGUgSlNPTgorICB2aXJ0dWFsIHZvaWQgV3JpdGVUb1N0cmluZyhpbzo6UHJpbnRlciogcHJpbnRlcikgPSAwOworCisgcHJvdGVjdGVkOgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworICBjb25zdCBpbnQgZmllbGRPcmRpbmFsXzsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXNfOworCisgIHZvaWQgQWRkRGVwcmVjYXRlZEZsYWcoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2b2lkIEFkZE51bGxDaGVjayhpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZvaWQgQWRkTnVsbENoZWNrKGlvOjpQcmludGVyKiBwcmludGVyLCBjb25zdCBzdGQ6OnN0cmluZyYgbmFtZSk7CisKKyAgdm9pZCBBZGRQdWJsaWNNZW1iZXJBdHRyaWJ1dGVzKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdm9pZCBTZXRDb21tb25PbmVvZkZpZWxkVmFyaWFibGVzKG1hcDxzdHJpbmcsIHN0cmluZz4qIHZhcmlhYmxlcyk7CisKKyAgc3RkOjpzdHJpbmcgb25lb2ZfcHJvcGVydHlfbmFtZSgpOworICBzdGQ6OnN0cmluZyBvbmVvZl9uYW1lKCk7CisgIHN0ZDo6c3RyaW5nIHByb3BlcnR5X25hbWUoKTsKKyAgc3RkOjpzdHJpbmcgbmFtZSgpOworICBzdGQ6OnN0cmluZyB0eXBlX25hbWUoKTsKKyAgc3RkOjpzdHJpbmcgdHlwZV9uYW1lKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CisgIGJvb2wgaGFzX2RlZmF1bHRfdmFsdWUoKTsKKyAgYm9vbCBpc19udWxsYWJsZV90eXBlKCk7CisgIHN0ZDo6c3RyaW5nIGRlZmF1bHRfdmFsdWUoKTsKKyAgc3RkOjpzdHJpbmcgZGVmYXVsdF92YWx1ZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworICBzdGQ6OnN0cmluZyBudW1iZXIoKTsKKyAgc3RkOjpzdHJpbmcgY2FwaXRhbGl6ZWRfdHlwZV9uYW1lKCk7CisKKyBwcml2YXRlOgorICB2b2lkIFNldENvbW1vbkZpZWxkVmFyaWFibGVzKG1hcDxzdHJpbmcsIHN0cmluZz4qIHZhcmlhYmxlcyk7CisgIHN0ZDo6c3RyaW5nIEdldFN0cmluZ0RlZmF1bHRWYWx1ZUludGVybmFsKCk7CisgIHN0ZDo6c3RyaW5nIEdldEJ5dGVzRGVmYXVsdFZhbHVlSW50ZXJuYWwoKTsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoRmllbGRHZW5lcmF0b3JCYXNlKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBjc2hhcnAKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NTSEFSUF9GSUVMRF9CQVNFX0hfXworCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfZ2VuZXJhdG9yLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX2dlbmVyYXRvci5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MjVkZTU0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX2dlbmVyYXRvci5jYwpAQCAtMCwwICsxLDEwNyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlIDxzc3RyZWFtPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvZGVfZ2VuZXJhdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BsdWdpbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX2dlbmVyYXRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9uYW1lcy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX3JlZmxlY3Rpb25fY2xhc3MuaD4KKwordXNpbmcgZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OnNjb3BlZF9wdHI7CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgY3NoYXJwIHsKKwordm9pZCBHZW5lcmF0ZUZpbGUoY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmlsZURlc2NyaXB0b3IqIGZpbGUsCisgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBSZWZsZWN0aW9uQ2xhc3NHZW5lcmF0b3IgcmVmbGVjdGlvbkNsYXNzR2VuZXJhdG9yKGZpbGUpOworICByZWZsZWN0aW9uQ2xhc3NHZW5lcmF0b3IuR2VuZXJhdGUocHJpbnRlcik7Cit9CisKK2Jvb2wgR2VuZXJhdG9yOjpHZW5lcmF0ZSgKKyAgICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSwKKyAgICBjb25zdCBzdHJpbmcmIHBhcmFtZXRlciwKKyAgICBHZW5lcmF0b3JDb250ZXh0KiBnZW5lcmF0b3JfY29udGV4dCwKKyAgICBzdHJpbmcqIGVycm9yKSBjb25zdCB7CisKKyAgdmVjdG9yPHBhaXI8c3RyaW5nLCBzdHJpbmc+ID4gb3B0aW9uczsKKyAgUGFyc2VHZW5lcmF0b3JQYXJhbWV0ZXIocGFyYW1ldGVyLCAmb3B0aW9ucyk7CisKKyAgLy8gV2Ugb25seSBzdXBwb3J0IHByb3RvMyAtIGJ1dCB3ZSBtYWtlIGFuIGV4Y2VwdGlvbiBmb3IgZGVzY3JpcHRvci5wcm90by4KKyAgaWYgKGZpbGUtPnN5bnRheCgpICE9IEZpbGVEZXNjcmlwdG9yOjpTWU5UQVhfUFJPVE8zICYmICFJc0Rlc2NyaXB0b3JQcm90byhmaWxlKSkgeworICAgICplcnJvciA9ICJDIyBjb2RlIGdlbmVyYXRpb24gb25seSBzdXBwb3J0cyBwcm90bzMgc3ludGF4IjsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBzdGQ6OnN0cmluZyBmaWxlX2V4dGVuc2lvbiA9ICIuY3MiOworICBzdGQ6OnN0cmluZyBiYXNlX25hbWVzcGFjZSA9ICIiOworICBib29sIGdlbmVyYXRlX2RpcmVjdG9yaWVzID0gZmFsc2U7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgb3B0aW9ucy5zaXplKCk7IGkrKykgeworICAgIGlmIChvcHRpb25zW2ldLmZpcnN0ID09ICJmaWxlX2V4dGVuc2lvbiIpIHsKKyAgICAgIGZpbGVfZXh0ZW5zaW9uID0gb3B0aW9uc1tpXS5zZWNvbmQ7CisgICAgfSBlbHNlIGlmIChvcHRpb25zW2ldLmZpcnN0ID09ICJiYXNlX25hbWVzcGFjZSIpIHsKKyAgICAgIGJhc2VfbmFtZXNwYWNlID0gb3B0aW9uc1tpXS5zZWNvbmQ7CisgICAgICBnZW5lcmF0ZV9kaXJlY3RvcmllcyA9IHRydWU7CisgICAgfSBlbHNlIHsKKyAgICAgICplcnJvciA9ICJVbmtub3duIGdlbmVyYXRvciBvcHRpb246ICIgKyBvcHRpb25zW2ldLmZpcnN0OworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgfQorCisgIHN0cmluZyBmaWxlbmFtZV9lcnJvciA9ICIiOworICBzdGQ6OnN0cmluZyBmaWxlbmFtZSA9IEdldE91dHB1dEZpbGUoZmlsZSwgZmlsZV9leHRlbnNpb24sIGdlbmVyYXRlX2RpcmVjdG9yaWVzLCBiYXNlX25hbWVzcGFjZSwgJmZpbGVuYW1lX2Vycm9yKTsKKyAgaWYgKGZpbGVuYW1lLmVtcHR5KCkpIHsKKyAgICAqZXJyb3IgPSBmaWxlbmFtZV9lcnJvcjsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgc2NvcGVkX3B0cjxpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0+IG91dHB1dCgKKyAgICAgIGdlbmVyYXRvcl9jb250ZXh0LT5PcGVuKGZpbGVuYW1lKSk7CisgIGlvOjpQcmludGVyIHByaW50ZXIob3V0cHV0LmdldCgpLCAnJCcpOworCisgIEdlbmVyYXRlRmlsZShmaWxlLCAmcHJpbnRlcik7CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBjc2hhcnAKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfZ2VuZXJhdG9yLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfZ2VuZXJhdG9yLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWI1NGU5MQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9nZW5lcmF0b3IuaApAQCAtMCwwICsxLDU4IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1NIQVJQX0dFTkVSQVRPUl9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NTSEFSUF9HRU5FUkFUT1JfSF9fCisKKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY29kZV9nZW5lcmF0b3IuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBjc2hhcnAgeworCitjbGFzcyBMSUJQUk9UT0NfRVhQT1JUIEdlbmVyYXRvcgorICAgIDogcHVibGljIGdvb2dsZTo6cHJvdG9idWY6OmNvbXBpbGVyOjpDb2RlR2VuZXJhdG9yIHsKKyAgdmlydHVhbCBib29sIEdlbmVyYXRlKAorICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUsCisgICAgICBjb25zdCBzdHJpbmcmIHBhcmFtZXRlciwKKyAgICAgIEdlbmVyYXRvckNvbnRleHQqIGdlbmVyYXRvcl9jb250ZXh0LAorICAgICAgc3RyaW5nKiBlcnJvcikgY29uc3Q7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgY3NoYXJwCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DU0hBUlBfR0VORVJBVE9SX0hfXworCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfZ2VuZXJhdG9yX3VuaXR0ZXN0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX2dlbmVyYXRvcl91bml0dGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ZWY3ZGY0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX2dlbmVyYXRvcl91bml0dGVzdC5jYwpAQCAtMCwwICsxLDU0IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDE0IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2luY2x1ZGUgPG1lbW9yeT4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9ydWJ5L3J1YnlfZ2VuZXJhdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvbW1hbmRfbGluZV9pbnRlcmZhY2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0Lmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9maWxlLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgY3NoYXJwIHsKK25hbWVzcGFjZSB7CisKKy8vIFRPRE8oanRhdHRlcm11c2NoKTogYWRkIHNvbWUgdGVzdHMuCisKK30gIC8vIG5hbWVzcGFjZQorfSAgLy8gbmFtZXNwYWNlIGNzaGFycAorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9oZWxwZXJzLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX2hlbHBlcnMuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzUxZmU0NAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9oZWxwZXJzLmNjCkBAIC0wLDAgKzEsNDA1IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxhbGdvcml0aG0+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2hhc2guaD4KKyNpbmNsdWRlIDxsaW1pdHM+CisjaW5jbHVkZSA8dmVjdG9yPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfaGVscGVycy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdWJzdGl0dXRlLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9maWVsZF9iYXNlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfZW51bV9maWVsZC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX21hcF9maWVsZC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX21lc3NhZ2VfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9wcmltaXRpdmVfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9yZXBlYXRlZF9lbnVtX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfcmVwZWF0ZWRfbWVzc2FnZV9maWVsZC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX3JlcGVhdGVkX3ByaW1pdGl2ZV9maWVsZC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX3dyYXBwZXJfZmllbGQuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBjc2hhcnAgeworCitDU2hhcnBUeXBlIEdldENTaGFycFR5cGUoRmllbGREZXNjcmlwdG9yOjpUeXBlIHR5cGUpIHsKKyAgc3dpdGNoICh0eXBlKSB7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfSU5UMzI6CisgICAgICByZXR1cm4gQ1NIQVJQVFlQRV9JTlQzMjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9JTlQ2NDoKKyAgICAgIHJldHVybiBDU0hBUlBUWVBFX0lOVDY0OworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1VJTlQzMjoKKyAgICAgIHJldHVybiBDU0hBUlBUWVBFX1VJTlQzMjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9VSU5UNjQ6CisgICAgICByZXR1cm4gQ1NIQVJQVFlQRV9VSU5UMzI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0lOVDMyOgorICAgICAgcmV0dXJuIENTSEFSUFRZUEVfSU5UMzI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0lOVDY0OgorICAgICAgcmV0dXJuIENTSEFSUFRZUEVfSU5UNjQ7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRklYRUQzMjoKKyAgICAgIHJldHVybiBDU0hBUlBUWVBFX1VJTlQzMjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9GSVhFRDY0OgorICAgICAgcmV0dXJuIENTSEFSUFRZUEVfVUlOVDY0OworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NGSVhFRDMyOgorICAgICAgcmV0dXJuIENTSEFSUFRZUEVfSU5UMzI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0ZJWEVENjQ6CisgICAgICByZXR1cm4gQ1NIQVJQVFlQRV9JTlQ2NDsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9GTE9BVDoKKyAgICAgIHJldHVybiBDU0hBUlBUWVBFX0ZMT0FUOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0RPVUJMRToKKyAgICAgIHJldHVybiBDU0hBUlBUWVBFX0RPVUJMRTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9CT09MOgorICAgICAgcmV0dXJuIENTSEFSUFRZUEVfQk9PTDsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9FTlVNOgorICAgICAgcmV0dXJuIENTSEFSUFRZUEVfRU5VTTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TVFJJTkc6CisgICAgICByZXR1cm4gQ1NIQVJQVFlQRV9TVFJJTkc7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfQllURVM6CisgICAgICByZXR1cm4gQ1NIQVJQVFlQRV9CWVRFU1RSSU5HOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQOgorICAgICAgcmV0dXJuIENTSEFSUFRZUEVfTUVTU0FHRTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9NRVNTQUdFOgorICAgICAgcmV0dXJuIENTSEFSUFRZUEVfTUVTU0FHRTsKKworICAgICAgLy8gTm8gZGVmYXVsdCBiZWNhdXNlIHdlIHdhbnQgdGhlIGNvbXBpbGVyIHRvIGNvbXBsYWluIGlmIGFueSBuZXcKKyAgICAgIC8vIHR5cGVzIGFyZSBhZGRlZC4KKyAgfQorICBHT09HTEVfTE9HKEZBVEFMKTw8ICJDYW4ndCBnZXQgaGVyZS4iOworICByZXR1cm4gKENTaGFycFR5cGUpIC0xOworfQorCitzdGQ6OnN0cmluZyBTdHJpcERvdFByb3RvKGNvbnN0IHN0ZDo6c3RyaW5nJiBwcm90b19maWxlKSB7CisgIGludCBsYXN0aW5kZXggPSBwcm90b19maWxlLmZpbmRfbGFzdF9vZigiLiIpOworICByZXR1cm4gcHJvdG9fZmlsZS5zdWJzdHIoMCwgbGFzdGluZGV4KTsKK30KKworc3RkOjpzdHJpbmcgR2V0RmlsZU5hbWVzcGFjZShjb25zdCBGaWxlRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBpZiAoZGVzY3JpcHRvci0+b3B0aW9ucygpLmhhc19jc2hhcnBfbmFtZXNwYWNlKCkpIHsKKyAgICByZXR1cm4gZGVzY3JpcHRvci0+b3B0aW9ucygpLmNzaGFycF9uYW1lc3BhY2UoKTsKKyAgfQorICByZXR1cm4gVW5kZXJzY29yZXNUb0NhbWVsQ2FzZShkZXNjcmlwdG9yLT5wYWNrYWdlKCksIHRydWUsIHRydWUpOworfQorCisvLyBSZXR1cm5zIHRoZSBQYXNjYWwtY2FzZWQgbGFzdCBwYXJ0IG9mIHRoZSBwcm90byBmaWxlLiBGb3IgZXhhbXBsZSwKKy8vIGlucHV0IG9mICJnb29nbGUvcHJvdG9idWYvZm9vX2Jhci5wcm90byIgd291bGQgcmVzdWx0IGluICJGb29CYXIiLgorc3RkOjpzdHJpbmcgR2V0RmlsZU5hbWVCYXNlKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgICAgc3RkOjpzdHJpbmcgcHJvdG9fZmlsZSA9IGRlc2NyaXB0b3ItPm5hbWUoKTsKKyAgICBpbnQgbGFzdHNsYXNoID0gcHJvdG9fZmlsZS5maW5kX2xhc3Rfb2YoIi8iKTsKKyAgICBzdGQ6OnN0cmluZyBiYXNlID0gcHJvdG9fZmlsZS5zdWJzdHIobGFzdHNsYXNoICsgMSk7CisgICAgcmV0dXJuIFVuZGVyc2NvcmVzVG9QYXNjYWxDYXNlKFN0cmlwRG90UHJvdG8oYmFzZSkpOworfQorCitzdGQ6OnN0cmluZyBHZXRSZWZsZWN0aW9uQ2xhc3NVbnF1YWxpZmllZE5hbWUoY29uc3QgRmlsZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgLy8gVE9ETzogRGV0ZWN0IGNvbGxpc2lvbnMgd2l0aCBleGlzdGluZyBtZXNzYWdlcywgYW5kIGFwcGVuZCBhbiB1bmRlcnNjb3JlIGlmIG5lY2Vzc2FyeS4KKyAgcmV0dXJuIEdldEZpbGVOYW1lQmFzZShkZXNjcmlwdG9yKSArICJSZWZsZWN0aW9uIjsKK30KKworLy8gVE9ETyhqdGF0dGVybXVzY2gpOiBjYW4gd2UgcmV1c2UgYSB1dGlsaXR5IGZ1bmN0aW9uPworc3RkOjpzdHJpbmcgVW5kZXJzY29yZXNUb0NhbWVsQ2FzZShjb25zdCBzdGQ6OnN0cmluZyYgaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgY2FwX25leHRfbGV0dGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIHByZXNlcnZlX3BlcmlvZCkgeworICBzdHJpbmcgcmVzdWx0OworICAvLyBOb3RlOiAgSSBkaXN0cnVzdCBjdHlwZS5oIGR1ZSB0byBsb2NhbGVzLgorICBmb3IgKGludCBpID0gMDsgaSA8IGlucHV0LnNpemUoKTsgaSsrKSB7CisgICAgaWYgKCdhJyA8PSBpbnB1dFtpXSAmJiBpbnB1dFtpXSA8PSAneicpIHsKKyAgICAgIGlmIChjYXBfbmV4dF9sZXR0ZXIpIHsKKyAgICAgICAgcmVzdWx0ICs9IGlucHV0W2ldICsgKCdBJyAtICdhJyk7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXN1bHQgKz0gaW5wdXRbaV07CisgICAgICB9CisgICAgICBjYXBfbmV4dF9sZXR0ZXIgPSBmYWxzZTsKKyAgICB9IGVsc2UgaWYgKCdBJyA8PSBpbnB1dFtpXSAmJiBpbnB1dFtpXSA8PSAnWicpIHsKKyAgICAgIGlmIChpID09IDAgJiYgIWNhcF9uZXh0X2xldHRlcikgeworICAgICAgICAvLyBGb3JjZSBmaXJzdCBsZXR0ZXIgdG8gbG93ZXItY2FzZSB1bmxlc3MgZXhwbGljaXRseSB0b2xkIHRvCisgICAgICAgIC8vIGNhcGl0YWxpemUgaXQuCisgICAgICAgIHJlc3VsdCArPSBpbnB1dFtpXSArICgnYScgLSAnQScpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgLy8gQ2FwaXRhbCBsZXR0ZXJzIGFmdGVyIHRoZSBmaXJzdCBhcmUgbGVmdCBhcy1pcy4KKyAgICAgICAgcmVzdWx0ICs9IGlucHV0W2ldOworICAgICAgfQorICAgICAgY2FwX25leHRfbGV0dGVyID0gZmFsc2U7CisgICAgfSBlbHNlIGlmICgnMCcgPD0gaW5wdXRbaV0gJiYgaW5wdXRbaV0gPD0gJzknKSB7CisgICAgICByZXN1bHQgKz0gaW5wdXRbaV07CisgICAgICBjYXBfbmV4dF9sZXR0ZXIgPSB0cnVlOworICAgIH0gZWxzZSB7CisgICAgICBjYXBfbmV4dF9sZXR0ZXIgPSB0cnVlOworICAgICAgaWYgKGlucHV0W2ldID09ICcuJyAmJiBwcmVzZXJ2ZV9wZXJpb2QpIHsKKyAgICAgICAgcmVzdWx0ICs9ICcuJzsKKyAgICAgIH0KKyAgICB9CisgIH0KKyAgLy8gQWRkIGEgdHJhaWxpbmcgIl8iIGlmIHRoZSBuYW1lIHNob3VsZCBiZSBhbHRlcmVkLgorICBpZiAoaW5wdXRbaW5wdXQuc2l6ZSgpIC0gMV0gPT0gJyMnKSB7CisgICAgcmVzdWx0ICs9ICdfJzsKKyAgfQorICByZXR1cm4gcmVzdWx0OworfQorCitzdGQ6OnN0cmluZyBVbmRlcnNjb3Jlc1RvUGFzY2FsQ2FzZShjb25zdCBzdGQ6OnN0cmluZyYgaW5wdXQpIHsKKyAgcmV0dXJuIFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoaW5wdXQsIHRydWUpOworfQorCitzdGQ6OnN0cmluZyBUb0NTaGFycE5hbWUoY29uc3Qgc3RkOjpzdHJpbmcmIG5hbWUsIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKSB7CisgIHN0ZDo6c3RyaW5nIHJlc3VsdCA9IEdldEZpbGVOYW1lc3BhY2UoZmlsZSk7CisgIGlmIChyZXN1bHQgIT0gIiIpIHsKKyAgICByZXN1bHQgKz0gJy4nOworICB9CisgIHN0cmluZyBjbGFzc25hbWU7CisgIGlmIChmaWxlLT5wYWNrYWdlKCkuZW1wdHkoKSkgeworICAgIGNsYXNzbmFtZSA9IG5hbWU7CisgIH0gZWxzZSB7CisgICAgLy8gU3RyaXAgdGhlIHByb3RvIHBhY2thZ2UgZnJvbSBmdWxsX25hbWUgc2luY2Ugd2UndmUgcmVwbGFjZWQgaXQgd2l0aAorICAgIC8vIHRoZSBDIyBuYW1lc3BhY2UuCisgICAgY2xhc3NuYW1lID0gbmFtZS5zdWJzdHIoZmlsZS0+cGFja2FnZSgpLnNpemUoKSArIDEpOworICB9CisgIHJlc3VsdCArPSBTdHJpbmdSZXBsYWNlKGNsYXNzbmFtZSwgIi4iLCAiLlR5cGVzLiIsIHRydWUpOworICByZXR1cm4gImdsb2JhbDo6IiArIHJlc3VsdDsKK30KKworc3RkOjpzdHJpbmcgR2V0UmVmbGVjdGlvbkNsYXNzTmFtZShjb25zdCBGaWxlRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBzdGQ6OnN0cmluZyByZXN1bHQgPSBHZXRGaWxlTmFtZXNwYWNlKGRlc2NyaXB0b3IpOworICBpZiAoIXJlc3VsdC5lbXB0eSgpKSB7CisgICAgcmVzdWx0ICs9ICcuJzsKKyAgfQorICByZXN1bHQgKz0gR2V0UmVmbGVjdGlvbkNsYXNzVW5xdWFsaWZpZWROYW1lKGRlc2NyaXB0b3IpOworICByZXR1cm4gImdsb2JhbDo6IiArIHJlc3VsdDsKK30KKworc3RkOjpzdHJpbmcgR2V0Q2xhc3NOYW1lKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgcmV0dXJuIFRvQ1NoYXJwTmFtZShkZXNjcmlwdG9yLT5mdWxsX25hbWUoKSwgZGVzY3JpcHRvci0+ZmlsZSgpKTsKK30KKworc3RkOjpzdHJpbmcgR2V0Q2xhc3NOYW1lKGNvbnN0IEVudW1EZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIHJldHVybiBUb0NTaGFycE5hbWUoZGVzY3JpcHRvci0+ZnVsbF9uYW1lKCksIGRlc2NyaXB0b3ItPmZpbGUoKSk7Cit9CisKKy8vIEdyb3VwcyBhcmUgaGFja3k6ICBUaGUgbmFtZSBvZiB0aGUgZmllbGQgaXMganVzdCB0aGUgbG93ZXItY2FzZWQgbmFtZQorLy8gb2YgdGhlIGdyb3VwIHR5cGUuICBJbiBDIywgdGhvdWdoLCB3ZSB3b3VsZCBsaWtlIHRvIHJldGFpbiB0aGUgb3JpZ2luYWwKKy8vIGNhcGl0YWxpemF0aW9uIG9mIHRoZSB0eXBlIG5hbWUuCitzdGQ6OnN0cmluZyBHZXRGaWVsZE5hbWUoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIGlmIChkZXNjcmlwdG9yLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQKSB7CisgICAgcmV0dXJuIGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpLT5uYW1lKCk7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIGRlc2NyaXB0b3ItPm5hbWUoKTsKKyAgfQorfQorCitzdGQ6OnN0cmluZyBHZXRGaWVsZENvbnN0YW50TmFtZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIHJldHVybiBHZXRQcm9wZXJ0eU5hbWUoZmllbGQpICsgIkZpZWxkTnVtYmVyIjsKK30KKworc3RkOjpzdHJpbmcgR2V0UHJvcGVydHlOYW1lKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICAvLyBUT0RPKGp0YXR0ZXJtdXNjaCk6IGNvbnNpZGVyIGludHJvZHVjaW5nIGNzaGFycF9wcm9wZXJ0eV9uYW1lIGZpZWxkIG9wdGlvbgorICBzdGQ6OnN0cmluZyBwcm9wZXJ0eV9uYW1lID0gVW5kZXJzY29yZXNUb1Bhc2NhbENhc2UoR2V0RmllbGROYW1lKGRlc2NyaXB0b3IpKTsKKyAgLy8gQXZvaWQgZWl0aGVyIG91ciBvd24gdHlwZSBuYW1lIG9yIHJlc2VydmVkIG5hbWVzLiBOb3RlIHRoYXQgbm90IGFsbCBuYW1lcworICAvLyBhcmUgcmVzZXJ2ZWQgLSBhIGZpZWxkIGNhbGxlZCB0b19zdHJpbmcsIHdyaXRlX3RvIGV0YyB3b3VsZCBzdGlsbCBjYXVzZSBhIHByb2JsZW0uCisgIC8vIFRoZXJlIGFyZSB2YXJpb3VzIHdheXMgb2YgZW5kaW5nIHVwIHdpdGggbmFtaW5nIGNvbGxpc2lvbnMsIGJ1dCB3ZSB0cnkgdG8gYXZvaWQgb2J2aW91cworICAvLyBvbmVzLgorICBpZiAocHJvcGVydHlfbmFtZSA9PSBkZXNjcmlwdG9yLT5jb250YWluaW5nX3R5cGUoKS0+bmFtZSgpCisgICAgICB8fCBwcm9wZXJ0eV9uYW1lID09ICJUeXBlcyIKKyAgICAgIHx8IHByb3BlcnR5X25hbWUgPT0gIkRlc2NyaXB0b3IiKSB7CisgICAgcHJvcGVydHlfbmFtZSArPSAiXyI7CisgIH0KKyAgcmV0dXJuIHByb3BlcnR5X25hbWU7Cit9CisKK3N0ZDo6c3RyaW5nIEdldE91dHB1dEZpbGUoCisgICAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmlsZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgY29uc3Qgc3RkOjpzdHJpbmcgZmlsZV9leHRlbnNpb24sCisgICAgY29uc3QgYm9vbCBnZW5lcmF0ZV9kaXJlY3RvcmllcywKKyAgICBjb25zdCBzdGQ6OnN0cmluZyBiYXNlX25hbWVzcGFjZSwKKyAgICBzdHJpbmcqIGVycm9yKSB7CisgIHN0cmluZyByZWxhdGl2ZV9maWxlbmFtZSA9IEdldEZpbGVOYW1lQmFzZShkZXNjcmlwdG9yKSArIGZpbGVfZXh0ZW5zaW9uOworICBpZiAoIWdlbmVyYXRlX2RpcmVjdG9yaWVzKSB7CisgICAgcmV0dXJuIHJlbGF0aXZlX2ZpbGVuYW1lOworICB9CisgIHN0cmluZyBucyA9IEdldEZpbGVOYW1lc3BhY2UoZGVzY3JpcHRvcik7CisgIHN0cmluZyBuYW1lc3BhY2Vfc3VmZml4ID0gbnM7CisgIGlmICghYmFzZV9uYW1lc3BhY2UuZW1wdHkoKSkgeworICAgIC8vIENoZWNrIHRoYXQgdGhlIGJhc2VfbmFtZXNwYWNlIGlzIGVpdGhlciBlcXVhbCB0byBvciBhIGxlYWRpbmcgcGFydCBvZgorICAgIC8vIHRoZSBmaWxlIG5hbWVzcGFjZS4gVGhpcyBpc24ndCBqdXN0IGEgc2ltcGxlIHByZWZpeDsgIkZvby5CIiBzaG91bGRuJ3QKKyAgICAvLyBiZSByZWdhcmRlZCBhcyBhIHByZWZpeCBvZiAiRm9vLkJhciIuIFRoZSBzaW1wbGVzdCBvcHRpb24gaXMgdG8gYWRkICIuIgorICAgIC8vIHRvIGJvdGguCisgICAgc3RyaW5nIGV4dGVuZGVkX25zID0gbnMgKyAiLiI7CisgICAgaWYgKGV4dGVuZGVkX25zLmZpbmQoYmFzZV9uYW1lc3BhY2UgKyAiLiIpICE9IDApIHsKKyAgICAgICplcnJvciA9ICJOYW1lc3BhY2UgIiArIG5zICsgIiBpcyBub3QgYSBwcmVmaXggbmFtZXNwYWNlIG9mIGJhc2UgbmFtZXNwYWNlICIgKyBiYXNlX25hbWVzcGFjZTsKKyAgICAgIHJldHVybiAiIjsgLy8gVGhpcyB3aWxsIGJlIGlnbm9yZWQsIGJlY2F1c2Ugd2UndmUgc2V0IGFuIGVycm9yLgorICAgIH0KKyAgICBuYW1lc3BhY2Vfc3VmZml4ID0gbnMuc3Vic3RyKGJhc2VfbmFtZXNwYWNlLmxlbmd0aCgpKTsKKyAgICBpZiAobmFtZXNwYWNlX3N1ZmZpeC5maW5kKCIuIikgPT0gMCkgeworICAgICAgbmFtZXNwYWNlX3N1ZmZpeCA9IG5hbWVzcGFjZV9zdWZmaXguc3Vic3RyKDEpOworICAgIH0KKyAgfQorCisgIHN0cmluZyBuYW1lc3BhY2VfZGlyID0gU3RyaW5nUmVwbGFjZShuYW1lc3BhY2Vfc3VmZml4LCAiLiIsICIvIiwgdHJ1ZSk7CisgIGlmICghbmFtZXNwYWNlX2Rpci5lbXB0eSgpKSB7CisgICAgbmFtZXNwYWNlX2RpciArPSAiLyI7CisgIH0KKyAgcmV0dXJuIG5hbWVzcGFjZV9kaXIgKyByZWxhdGl2ZV9maWxlbmFtZTsKK30KKworLy8gVE9ETzogYyZwIGZyb20gSmF2YSBwcm90b2MgcGx1Z2luCisvLyBGb3IgZW5jb2RpbmdzIHdpdGggZml4ZWQgc2l6ZXMsIHJldHVybnMgdGhhdCBzaXplIGluIGJ5dGVzLiAgT3RoZXJ3aXNlCisvLyByZXR1cm5zIC0xLgoraW50IEdldEZpeGVkU2l6ZShGaWVsZERlc2NyaXB0b3I6OlR5cGUgdHlwZSkgeworICBzd2l0Y2ggKHR5cGUpIHsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9JTlQzMiAgIDogcmV0dXJuIC0xOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0lOVDY0ICAgOiByZXR1cm4gLTE7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfVUlOVDMyICA6IHJldHVybiAtMTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9VSU5UNjQgIDogcmV0dXJuIC0xOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NJTlQzMiAgOiByZXR1cm4gLTE7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0lOVDY0ICA6IHJldHVybiAtMTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9GSVhFRDMyIDogcmV0dXJuIGludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6a0ZpeGVkMzJTaXplOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0ZJWEVENjQgOiByZXR1cm4gaW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjprRml4ZWQ2NFNpemU7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0ZJWEVEMzI6IHJldHVybiBpbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OmtTRml4ZWQzMlNpemU7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0ZJWEVENjQ6IHJldHVybiBpbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OmtTRml4ZWQ2NFNpemU7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRkxPQVQgICA6IHJldHVybiBpbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OmtGbG9hdFNpemU7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRE9VQkxFICA6IHJldHVybiBpbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OmtEb3VibGVTaXplOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfQk9PTCAgICA6IHJldHVybiBpbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OmtCb29sU2l6ZTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9FTlVNICAgIDogcmV0dXJuIC0xOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU1RSSU5HICA6IHJldHVybiAtMTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9CWVRFUyAgIDogcmV0dXJuIC0xOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQICAgOiByZXR1cm4gLTE7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfTUVTU0FHRSA6IHJldHVybiAtMTsKKworICAgIC8vIE5vIGRlZmF1bHQgYmVjYXVzZSB3ZSB3YW50IHRoZSBjb21waWxlciB0byBjb21wbGFpbiBpZiBhbnkgbmV3CisgICAgLy8gdHlwZXMgYXJlIGFkZGVkLgorICB9CisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJDYW4ndCBnZXQgaGVyZS4iOworICByZXR1cm4gLTE7Cit9CisKK3N0YXRpYyBjb25zdCBjaGFyIGJhc2U2NF9jaGFyc1tdID0KKyAgICAiQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLyI7CisKK3N0ZDo6c3RyaW5nIFN0cmluZ1RvQmFzZTY0KGNvbnN0IHN0ZDo6c3RyaW5nJiBpbnB1dCkgeworICBzdGQ6OnN0cmluZyByZXN1bHQ7CisgIHNpemVfdCByZW1haW5pbmcgPSBpbnB1dC5zaXplKCk7CisgIGNvbnN0IHVuc2lnbmVkIGNoYXIgKnNyYyA9IChjb25zdCB1bnNpZ25lZCBjaGFyKikgaW5wdXQuY19zdHIoKTsKKyAgd2hpbGUgKHJlbWFpbmluZyA+IDIpIHsKKyAgICByZXN1bHQgKz0gYmFzZTY0X2NoYXJzW3NyY1swXSA+PiAyXTsKKyAgICByZXN1bHQgKz0gYmFzZTY0X2NoYXJzWygoc3JjWzBdICYgMHgzKSA8PCA0KSB8IChzcmNbMV0gPj4gNCldOworICAgIHJlc3VsdCArPSBiYXNlNjRfY2hhcnNbKChzcmNbMV0gJiAweGYpIDw8IDIpIHwgKHNyY1syXSA+PiA2KV07CisgICAgcmVzdWx0ICs9IGJhc2U2NF9jaGFyc1tzcmNbMl0gJiAweDNmXTsKKyAgICByZW1haW5pbmcgLT0gMzsKKyAgICBzcmMgKz0gMzsKKyAgfQorICBzd2l0Y2ggKHJlbWFpbmluZykgeworICAgIGNhc2UgMjoKKyAgICAgIHJlc3VsdCArPSBiYXNlNjRfY2hhcnNbc3JjWzBdID4+IDJdOworICAgICAgcmVzdWx0ICs9IGJhc2U2NF9jaGFyc1soKHNyY1swXSAmIDB4MykgPDwgNCkgfCAoc3JjWzFdID4+IDQpXTsKKyAgICAgIHJlc3VsdCArPSBiYXNlNjRfY2hhcnNbKHNyY1sxXSAmIDB4ZikgPDwgMl07CisgICAgICByZXN1bHQgKz0gJz0nOworICAgICAgc3JjICs9IDI7CisgICAgICBicmVhazsKKyAgICBjYXNlIDE6CisgICAgICByZXN1bHQgKz0gYmFzZTY0X2NoYXJzW3NyY1swXSA+PiAyXTsKKyAgICAgIHJlc3VsdCArPSBiYXNlNjRfY2hhcnNbKChzcmNbMF0gJiAweDMpIDw8IDQpXTsKKyAgICAgIHJlc3VsdCArPSAnPSc7CisgICAgICByZXN1bHQgKz0gJz0nOworICAgICAgc3JjICs9IDE7CisgICAgICBicmVhazsKKyAgfQorICByZXR1cm4gcmVzdWx0OworfQorCitzdGQ6OnN0cmluZyBGaWxlRGVzY3JpcHRvclRvQmFzZTY0KGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIHN0ZDo6c3RyaW5nIGZkcF9ieXRlczsKKyAgRmlsZURlc2NyaXB0b3JQcm90byBmZHA7CisgIGRlc2NyaXB0b3ItPkNvcHlUbygmZmRwKTsKKyAgZmRwLlNlcmlhbGl6ZVRvU3RyaW5nKCZmZHBfYnl0ZXMpOworICByZXR1cm4gU3RyaW5nVG9CYXNlNjQoZmRwX2J5dGVzKTsKK30KKworRmllbGRHZW5lcmF0b3JCYXNlKiBDcmVhdGVGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBmaWVsZE9yZGluYWwpIHsKKyAgc3dpdGNoIChkZXNjcmlwdG9yLT50eXBlKCkpIHsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9HUk9VUDoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9NRVNTQUdFOgorICAgICAgaWYgKGRlc2NyaXB0b3ItPmlzX3JlcGVhdGVkKCkpIHsKKyAgICAgICAgaWYgKGRlc2NyaXB0b3ItPmlzX21hcCgpKSB7CisgICAgICAgICAgcmV0dXJuIG5ldyBNYXBGaWVsZEdlbmVyYXRvcihkZXNjcmlwdG9yLCBmaWVsZE9yZGluYWwpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHJldHVybiBuZXcgUmVwZWF0ZWRNZXNzYWdlRmllbGRHZW5lcmF0b3IoZGVzY3JpcHRvciwgZmllbGRPcmRpbmFsKTsKKyAgICAgICAgfQorICAgICAgfSBlbHNlIHsKKyAgICAgICAgaWYgKElzV3JhcHBlclR5cGUoZGVzY3JpcHRvcikpIHsKKyAgICAgICAgICBpZiAoZGVzY3JpcHRvci0+Y29udGFpbmluZ19vbmVvZigpKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IFdyYXBwZXJPbmVvZkZpZWxkR2VuZXJhdG9yKGRlc2NyaXB0b3IsIGZpZWxkT3JkaW5hbCk7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgV3JhcHBlckZpZWxkR2VuZXJhdG9yKGRlc2NyaXB0b3IsIGZpZWxkT3JkaW5hbCk7CisgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGlmIChkZXNjcmlwdG9yLT5jb250YWluaW5nX29uZW9mKCkpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgTWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3IoZGVzY3JpcHRvciwgZmllbGRPcmRpbmFsKTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBNZXNzYWdlRmllbGRHZW5lcmF0b3IoZGVzY3JpcHRvciwgZmllbGRPcmRpbmFsKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0KKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9FTlVNOgorICAgICAgaWYgKGRlc2NyaXB0b3ItPmlzX3JlcGVhdGVkKCkpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBSZXBlYXRlZEVudW1GaWVsZEdlbmVyYXRvcihkZXNjcmlwdG9yLCBmaWVsZE9yZGluYWwpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgaWYgKGRlc2NyaXB0b3ItPmNvbnRhaW5pbmdfb25lb2YoKSkgeworICAgICAgICAgIHJldHVybiBuZXcgRW51bU9uZW9mRmllbGRHZW5lcmF0b3IoZGVzY3JpcHRvciwgZmllbGRPcmRpbmFsKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICByZXR1cm4gbmV3IEVudW1GaWVsZEdlbmVyYXRvcihkZXNjcmlwdG9yLCBmaWVsZE9yZGluYWwpOworICAgICAgICB9CisgICAgICB9CisgICAgZGVmYXVsdDoKKyAgICAgIGlmIChkZXNjcmlwdG9yLT5pc19yZXBlYXRlZCgpKSB7CisgICAgICAgIHJldHVybiBuZXcgUmVwZWF0ZWRQcmltaXRpdmVGaWVsZEdlbmVyYXRvcihkZXNjcmlwdG9yLCBmaWVsZE9yZGluYWwpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgaWYgKGRlc2NyaXB0b3ItPmNvbnRhaW5pbmdfb25lb2YoKSkgeworICAgICAgICAgIHJldHVybiBuZXcgUHJpbWl0aXZlT25lb2ZGaWVsZEdlbmVyYXRvcihkZXNjcmlwdG9yLCBmaWVsZE9yZGluYWwpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHJldHVybiBuZXcgUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IoZGVzY3JpcHRvciwgZmllbGRPcmRpbmFsKTsKKyAgICAgICAgfQorICAgICAgfQorICB9Cit9CisKK30gIC8vIG5hbWVzcGFjZSBjc2hhcnAKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfaGVscGVycy5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX2hlbHBlcnMuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lOTZlNzkzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX2hlbHBlcnMuaApAQCAtMCwwICsxLDEyMiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DU0hBUlBfSEVMUEVSU19IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NTSEFSUF9IRUxQRVJTX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY29kZV9nZW5lcmF0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGNzaGFycCB7CisKK2NsYXNzIEZpZWxkR2VuZXJhdG9yQmFzZTsKKworLy8gVE9ETzogc3RhcnQgdXNpbmcgdGhpcyBlbnVtLgorZW51bSBDU2hhcnBUeXBlIHsKKyAgQ1NIQVJQVFlQRV9JTlQzMiA9IDEsCisgIENTSEFSUFRZUEVfSU5UNjQgPSAyLAorICBDU0hBUlBUWVBFX1VJTlQzMiA9IDMsCisgIENTSEFSUFRZUEVfVUlOVDY0ID0gNCwKKyAgQ1NIQVJQVFlQRV9GTE9BVCA9IDUsCisgIENTSEFSUFRZUEVfRE9VQkxFID0gNiwKKyAgQ1NIQVJQVFlQRV9CT09MID0gNywKKyAgQ1NIQVJQVFlQRV9TVFJJTkcgPSA4LAorICBDU0hBUlBUWVBFX0JZVEVTVFJJTkcgPSA5LAorICBDU0hBUlBUWVBFX01FU1NBR0UgPSAxMCwKKyAgQ1NIQVJQVFlQRV9FTlVNID0gMTEsCisgIE1BWF9DU0hBUlBUWVBFID0gMTEKK307CisKKy8vIENvbnZlcnRzIGZpZWxkIHR5cGUgdG8gY29ycmVzcG9uZGluZyBDIyB0eXBlLgorQ1NoYXJwVHlwZSBHZXRDU2hhcnBUeXBlKEZpZWxkRGVzY3JpcHRvcjo6VHlwZSB0eXBlKTsKKworc3RkOjpzdHJpbmcgU3RyaXBEb3RQcm90byhjb25zdCBzdGQ6OnN0cmluZyYgcHJvdG9fZmlsZSk7CisKKy8vIEdldHMgdW5xdWFsaWZpZWQgbmFtZSBvZiB0aGUgcmVmbGVjdGlvbiBjbGFzcworc3RkOjpzdHJpbmcgR2V0UmVmbGVjdGlvbkNsYXNzVW5xdWFsaWZpZWROYW1lKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKKworc3RkOjpzdHJpbmcgR2V0Q2xhc3NOYW1lKGNvbnN0IEVudW1EZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKKworc3RkOjpzdHJpbmcgR2V0RmllbGROYW1lKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CisKK3N0ZDo6c3RyaW5nIEdldEZpZWxkQ29uc3RhbnROYW1lKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpOworCitzdGQ6OnN0cmluZyBHZXRQcm9wZXJ0eU5hbWUoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKKworaW50IEdldEZpeGVkU2l6ZShGaWVsZERlc2NyaXB0b3I6OlR5cGUgdHlwZSk7CisKK3N0ZDo6c3RyaW5nIFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoY29uc3Qgc3RkOjpzdHJpbmcmIGlucHV0LCBib29sIGNhcF9uZXh0X2xldHRlciwgYm9vbCBwcmVzZXJ2ZV9wZXJpb2QpOworCitpbmxpbmUgc3RkOjpzdHJpbmcgVW5kZXJzY29yZXNUb0NhbWVsQ2FzZShjb25zdCBzdGQ6OnN0cmluZyYgaW5wdXQsIGJvb2wgY2FwX25leHRfbGV0dGVyKSB7CisgIHJldHVybiBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlKGlucHV0LCBjYXBfbmV4dF9sZXR0ZXIsIGZhbHNlKTsKK30KKworc3RkOjpzdHJpbmcgVW5kZXJzY29yZXNUb1Bhc2NhbENhc2UoY29uc3Qgc3RkOjpzdHJpbmcmIGlucHV0KTsKKworLy8gVE9ETyhqdGF0dGVybXVzY2gpOiBwZXJoYXBzIHdlIGNvdWxkIG1vdmUgdGhpcyB0byBzdHJ1dGlsCitzdGQ6OnN0cmluZyBTdHJpbmdUb0Jhc2U2NChjb25zdCBzdGQ6OnN0cmluZyYgaW5wdXQpOworCitzdGQ6OnN0cmluZyBGaWxlRGVzY3JpcHRvclRvQmFzZTY0KGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKKworRmllbGRHZW5lcmF0b3JCYXNlKiBDcmVhdGVGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGludCBmaWVsZE9yZGluYWwpOworCisvLyBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIGdpdmVuIG1lc3NhZ2UgaXMgYSBtYXAgZW50cnkgbWVzc2FnZSwgaS5lLiBvbmUgaW1wbGljaXRseSBjcmVhdGVkCisvLyBieSBwcm90b2MgZHVlIHRvIGEgbWFwPGtleSwgdmFsdWU+IGZpZWxkLgoraW5saW5lIGJvb2wgSXNNYXBFbnRyeU1lc3NhZ2UoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICByZXR1cm4gZGVzY3JpcHRvci0+b3B0aW9ucygpLm1hcF9lbnRyeSgpOworfQorCisvLyBEZXRlcm1pbmVzIHdoZXRoZXIgd2UncmUgZ2VuZXJhdGluZyBjb2RlIGZvciB0aGUgcHJvdG8gcmVwcmVzZW50YXRpb24gb2YgZGVzY3JpcHRvcnMgZXRjLAorLy8gZm9yIHVzZSBpbiB0aGUgcnVudGltZS4gVGhpcyBpcyB0aGUgb25seSB0eXBlIHdoaWNoIGlzIGFsbG93ZWQgdG8gdXNlIHByb3RvMiBzeW50YXgsCisvLyBhbmQgaXQgZ2VuZXJhdGVzIGludGVybmFsIGNsYXNzZXMuCitpbmxpbmUgYm9vbCBJc0Rlc2NyaXB0b3JQcm90byhjb25zdCBGaWxlRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICByZXR1cm4gZGVzY3JpcHRvci0+bmFtZSgpID09ICJnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90byI7Cit9CisKK2lubGluZSBib29sIElzV3JhcHBlclR5cGUoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIHJldHVybiBkZXNjcmlwdG9yLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX01FU1NBR0UgJiYKKyAgICAgIGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpLT5maWxlKCktPm5hbWUoKSA9PSAiZ29vZ2xlL3Byb3RvYnVmL3dyYXBwZXJzLnByb3RvIjsKK30KKworfSAgLy8gbmFtZXNwYWNlIGNzaGFycAorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NTSEFSUF9IRUxQRVJTX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX21hcF9maWVsZC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9tYXBfZmllbGQuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTVjNjhiMwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9tYXBfZmllbGQuY2MKQEAgLTAsMCArMSwxMzggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMTUgR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaW5jbHVkZSA8c3N0cmVhbT4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jb2RlX2dlbmVyYXRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wbHVnaW4uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9kb2NfY29tbWVudC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9tYXBfZmllbGQuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBjc2hhcnAgeworCitNYXBGaWVsZEdlbmVyYXRvcjo6TWFwRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGZpZWxkT3JkaW5hbCkKKyAgICA6IEZpZWxkR2VuZXJhdG9yQmFzZShkZXNjcmlwdG9yLCBmaWVsZE9yZGluYWwpIHsKK30KKworTWFwRmllbGRHZW5lcmF0b3I6On5NYXBGaWVsZEdlbmVyYXRvcigpIHsKK30KKwordm9pZCBNYXBGaWVsZEdlbmVyYXRvcjo6R2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSB7ICAgCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvcioga2V5X2Rlc2NyaXB0b3IgPQorICAgICAgZGVzY3JpcHRvcl8tPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoImtleSIpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHZhbHVlX2Rlc2NyaXB0b3IgPQorICAgICAgZGVzY3JpcHRvcl8tPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoInZhbHVlIik7CisgIHZhcmlhYmxlc19bImtleV90eXBlX25hbWUiXSA9IHR5cGVfbmFtZShrZXlfZGVzY3JpcHRvcik7CisgIHZhcmlhYmxlc19bInZhbHVlX3R5cGVfbmFtZSJdID0gdHlwZV9uYW1lKHZhbHVlX2Rlc2NyaXB0b3IpOworICBzY29wZWRfcHRyPEZpZWxkR2VuZXJhdG9yQmFzZT4ga2V5X2dlbmVyYXRvcihDcmVhdGVGaWVsZEdlbmVyYXRvcihrZXlfZGVzY3JpcHRvciwgMSkpOyAgCisgIHNjb3BlZF9wdHI8RmllbGRHZW5lcmF0b3JCYXNlPiB2YWx1ZV9nZW5lcmF0b3IoQ3JlYXRlRmllbGRHZW5lcmF0b3IodmFsdWVfZGVzY3JpcHRvciwgMikpOworCisgIHByaW50ZXItPlByaW50KAorICAgIHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgc3RhdGljIHJlYWRvbmx5IHBiYzo6TWFwRmllbGQ8JGtleV90eXBlX25hbWUkLCAkdmFsdWVfdHlwZV9uYW1lJD4uQ29kZWMgX21hcF8kbmFtZSRfY29kZWNcbiIKKyAgICAiICAgID0gbmV3IHBiYzo6TWFwRmllbGQ8JGtleV90eXBlX25hbWUkLCAkdmFsdWVfdHlwZV9uYW1lJD4uQ29kZWMoIik7CisgIGtleV9nZW5lcmF0b3ItPkdlbmVyYXRlQ29kZWNDb2RlKHByaW50ZXIpOworICBwcmludGVyLT5QcmludCgiLCAiKTsKKyAgdmFsdWVfZ2VuZXJhdG9yLT5HZW5lcmF0ZUNvZGVjQ29kZShwcmludGVyKTsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgdmFyaWFibGVzXywKKyAgICAiLCAkdGFnJCk7XG4iCisgICAgInByaXZhdGUgcmVhZG9ubHkgcGJjOjpNYXBGaWVsZDwka2V5X3R5cGVfbmFtZSQsICR2YWx1ZV90eXBlX25hbWUkPiAkbmFtZSRfID0gbmV3IHBiYzo6TWFwRmllbGQ8JGtleV90eXBlX25hbWUkLCAkdmFsdWVfdHlwZV9uYW1lJD4oKTtcbiIpOworICBXcml0ZVByb3BlcnR5RG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIEFkZERlcHJlY2F0ZWRGbGFnKHByaW50ZXIpOworICBwcmludGVyLT5QcmludCgKKyAgICB2YXJpYWJsZXNfLAorICAgICIkYWNjZXNzX2xldmVsJCBwYmM6Ok1hcEZpZWxkPCRrZXlfdHlwZV9uYW1lJCwgJHZhbHVlX3R5cGVfbmFtZSQ+ICRwcm9wZXJ0eV9uYW1lJCB7XG4iCisgICAgIiAgZ2V0IHsgcmV0dXJuICRuYW1lJF87IH1cbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgTWFwRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICB2YXJpYWJsZXNfLAorICAgICAgIiRuYW1lJF8uQWRkKG90aGVyLiRuYW1lJF8pO1xuIik7Cit9CisKK3ZvaWQgTWFwRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgdmFyaWFibGVzXywKKyAgICAiJG5hbWUkXy5BZGRFbnRyaWVzRnJvbShpbnB1dCwgX21hcF8kbmFtZSRfY29kZWMpO1xuIik7Cit9CisKK3ZvaWQgTWFwRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgdmFyaWFibGVzXywKKyAgICAiJG5hbWUkXy5Xcml0ZVRvKG91dHB1dCwgX21hcF8kbmFtZSRfY29kZWMpO1xuIik7Cit9CisKK3ZvaWQgTWFwRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgIHZhcmlhYmxlc18sCisgICAgInNpemUgKz0gJG5hbWUkXy5DYWxjdWxhdGVTaXplKF9tYXBfJG5hbWUkX2NvZGVjKTtcbiIpOworfQorCit2b2lkIE1hcEZpZWxkR2VuZXJhdG9yOjpXcml0ZUhhc2goaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgdmFyaWFibGVzXywKKyAgICAiaGFzaCBePSAkcHJvcGVydHlfbmFtZSQuR2V0SGFzaENvZGUoKTtcbiIpOworfQordm9pZCBNYXBGaWVsZEdlbmVyYXRvcjo6V3JpdGVFcXVhbHMoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgdmFyaWFibGVzXywKKyAgICAiaWYgKCEkcHJvcGVydHlfbmFtZSQuRXF1YWxzKG90aGVyLiRwcm9wZXJ0eV9uYW1lJCkpIHJldHVybiBmYWxzZTtcbiIpOworfQorCit2b2lkIE1hcEZpZWxkR2VuZXJhdG9yOjpXcml0ZVRvU3RyaW5nKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgICAgLy8gVE9ETzogSWYgd2UgZXZlciBhY3R1YWxseSB1c2UgVG9TdHJpbmcsIHdlJ2xsIG5lZWQgdG8gaW1wbGVtZSB0aGlzLi4uCit9CisKK3ZvaWQgTWFwRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlQ2xvbmluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJG5hbWUkXyA9IG90aGVyLiRuYW1lJF8uQ2xvbmUoKTtcbiIpOworfQorCit2b2lkIE1hcEZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZUZyZWV6aW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgeworfQorCit9ICAvLyBuYW1lc3BhY2UgY3NoYXJwCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX21hcF9maWVsZC5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX21hcF9maWVsZC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYzM2ZlMWMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfbWFwX2ZpZWxkLmgKQEAgLTAsMCArMSw3MSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NTSEFSUF9NQVBfRklFTERfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DU0hBUlBfTUFQX0ZJRUxEX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvZGVfZ2VuZXJhdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfZmllbGRfYmFzZS5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGNzaGFycCB7CisKK2NsYXNzIE1hcEZpZWxkR2VuZXJhdG9yIDogcHVibGljIEZpZWxkR2VuZXJhdG9yQmFzZSB7CisgcHVibGljOgorICBNYXBGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGludCBmaWVsZE9yZGluYWwpOworICB+TWFwRmllbGRHZW5lcmF0b3IoKTsKKworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVDbG9uaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZUZyZWV6aW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZVBhcnNpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIHZpcnR1YWwgdm9pZCBXcml0ZUhhc2goaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2aXJ0dWFsIHZvaWQgV3JpdGVFcXVhbHMoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2aXJ0dWFsIHZvaWQgV3JpdGVUb1N0cmluZyhpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoTWFwRmllbGRHZW5lcmF0b3IpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGNzaGFycAorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1NIQVJQX01BUF9GSUVMRF9IX18KKwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX21lc3NhZ2UuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfbWVzc2FnZS5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMDIzMGEyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX21lc3NhZ2UuY2MKQEAgLTAsMCArMSw0OTkgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaW5jbHVkZSA8c3N0cmVhbT4KKyNpbmNsdWRlIDxhbGdvcml0aG0+CisjaW5jbHVkZSA8bWFwPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvZGVfZ2VuZXJhdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BsdWdpbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZS5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfZG9jX2NvbW1lbnQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9lbnVtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfZmllbGRfYmFzZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9tZXNzYWdlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfbmFtZXMuaD4KKwordXNpbmcgZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OnNjb3BlZF9wdHI7CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgY3NoYXJwIHsKKworYm9vbCBDb21wYXJlRmllbGROdW1iZXJzKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZDEsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZDIpIHsKKyAgcmV0dXJuIGQxLT5udW1iZXIoKSA8IGQyLT5udW1iZXIoKTsKK30KKworTWVzc2FnZUdlbmVyYXRvcjo6TWVzc2FnZUdlbmVyYXRvcihjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKQorICAgIDogU291cmNlR2VuZXJhdG9yQmFzZShkZXNjcmlwdG9yLT5maWxlKCkpLAorICAgICAgZGVzY3JpcHRvcl8oZGVzY3JpcHRvcikgeworCisgIC8vIHNvcnRlZCBmaWVsZCBuYW1lcworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBmaWVsZF9uYW1lc18ucHVzaF9iYWNrKGRlc2NyaXB0b3JfLT5maWVsZChpKS0+bmFtZSgpKTsKKyAgfQorICBzdGQ6OnNvcnQoZmllbGRfbmFtZXNfLmJlZ2luKCksIGZpZWxkX25hbWVzXy5lbmQoKSk7CisKKyAgLy8gZmllbGRzIGJ5IG51bWJlcgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBmaWVsZHNfYnlfbnVtYmVyXy5wdXNoX2JhY2soZGVzY3JpcHRvcl8tPmZpZWxkKGkpKTsKKyAgfQorICBzdGQ6OnNvcnQoZmllbGRzX2J5X251bWJlcl8uYmVnaW4oKSwgZmllbGRzX2J5X251bWJlcl8uZW5kKCksCisgICAgICAgICAgICBDb21wYXJlRmllbGROdW1iZXJzKTsKK30KKworTWVzc2FnZUdlbmVyYXRvcjo6fk1lc3NhZ2VHZW5lcmF0b3IoKSB7Cit9CisKK3N0ZDo6c3RyaW5nIE1lc3NhZ2VHZW5lcmF0b3I6OmNsYXNzX25hbWUoKSB7CisgIHJldHVybiBkZXNjcmlwdG9yXy0+bmFtZSgpOworfQorCitzdGQ6OnN0cmluZyBNZXNzYWdlR2VuZXJhdG9yOjpmdWxsX2NsYXNzX25hbWUoKSB7CisgIHJldHVybiBHZXRDbGFzc05hbWUoZGVzY3JpcHRvcl8pOworfQorCitjb25zdCBzdGQ6OnZlY3RvcjxzdGQ6OnN0cmluZz4mIE1lc3NhZ2VHZW5lcmF0b3I6OmZpZWxkX25hbWVzKCkgeworICByZXR1cm4gZmllbGRfbmFtZXNfOworfQorCitjb25zdCBzdGQ6OnZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiYgTWVzc2FnZUdlbmVyYXRvcjo6ZmllbGRzX2J5X251bWJlcigpIHsKKyAgcmV0dXJuIGZpZWxkc19ieV9udW1iZXJfOworfQorCit2b2lkIE1lc3NhZ2VHZW5lcmF0b3I6OkdlbmVyYXRlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyczsKKyAgdmFyc1siY2xhc3NfbmFtZSJdID0gY2xhc3NfbmFtZSgpOworICB2YXJzWyJhY2Nlc3NfbGV2ZWwiXSA9IGNsYXNzX2FjY2Vzc19sZXZlbCgpOworCisgIFdyaXRlTWVzc2FnZURvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCgKKyAgICAiW2dsb2JhbDo6U3lzdGVtLkRpYWdub3N0aWNzLkRlYnVnZ2VyTm9uVXNlckNvZGVBdHRyaWJ1dGUoKV1cbiIpOworICBXcml0ZUdlbmVyYXRlZENvZGVBdHRyaWJ1dGVzKHByaW50ZXIpOworICBwcmludGVyLT5QcmludCgKKyAgICB2YXJzLAorICAgICIkYWNjZXNzX2xldmVsJCBzZWFsZWQgcGFydGlhbCBjbGFzcyAkY2xhc3NfbmFtZSQgOiBwYjo6SU1lc3NhZ2U8JGNsYXNzX25hbWUkPiB7XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgLy8gQWxsIHN0YXRpYyBmaWVsZHMgYW5kIHByb3BlcnRpZXMKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICB2YXJzLAorICAgICAgInByaXZhdGUgc3RhdGljIHJlYWRvbmx5IHBiOjpNZXNzYWdlUGFyc2VyPCRjbGFzc19uYW1lJD4gX3BhcnNlciA9IG5ldyBwYjo6TWVzc2FnZVBhcnNlcjwkY2xhc3NfbmFtZSQ+KCgpID0+IG5ldyAkY2xhc3NfbmFtZSQoKSk7XG4iCisgICAgICAicHVibGljIHN0YXRpYyBwYjo6TWVzc2FnZVBhcnNlcjwkY2xhc3NfbmFtZSQ+IFBhcnNlciB7IGdldCB7IHJldHVybiBfcGFyc2VyOyB9IH1cblxuIik7CisKKyAgLy8gQWNjZXNzIHRoZSBtZXNzYWdlIGRlc2NyaXB0b3IgdmlhIHRoZSByZWxldmFudCBmaWxlIGRlc2NyaXB0b3Igb3IgY29udGFpbmluZyBtZXNzYWdlIGRlc2NyaXB0b3IuCisgIGlmICghZGVzY3JpcHRvcl8tPmNvbnRhaW5pbmdfdHlwZSgpKSB7CisgICAgdmFyc1siZGVzY3JpcHRvcl9hY2Nlc3NvciJdID0gR2V0UmVmbGVjdGlvbkNsYXNzTmFtZShkZXNjcmlwdG9yXy0+ZmlsZSgpKQorICAgICAgICArICIuRGVzY3JpcHRvci5NZXNzYWdlVHlwZXNbIiArIFNpbXBsZUl0b2EoZGVzY3JpcHRvcl8tPmluZGV4KCkpICsgIl0iOworICB9IGVsc2UgeworICAgIHZhcnNbImRlc2NyaXB0b3JfYWNjZXNzb3IiXSA9IEdldENsYXNzTmFtZShkZXNjcmlwdG9yXy0+Y29udGFpbmluZ190eXBlKCkpCisgICAgICAgICsgIi5EZXNjcmlwdG9yLk5lc3RlZFR5cGVzWyIgKyBTaW1wbGVJdG9hKGRlc2NyaXB0b3JfLT5pbmRleCgpKSArICJdIjsKKyAgfQorCisgIHByaW50ZXItPlByaW50KAorICAgIHZhcnMsCisgICAgInB1YmxpYyBzdGF0aWMgcGJyOjpNZXNzYWdlRGVzY3JpcHRvciBEZXNjcmlwdG9yIHtcbiIKKyAgICAiICBnZXQgeyByZXR1cm4gJGRlc2NyaXB0b3JfYWNjZXNzb3IkOyB9XG4iCisgICAgIn1cbiIKKyAgICAiXG4iCisgICAgInBicjo6TWVzc2FnZURlc2NyaXB0b3IgcGI6OklNZXNzYWdlLkRlc2NyaXB0b3Ige1xuIgorICAgICIgIGdldCB7IHJldHVybiBEZXNjcmlwdG9yOyB9XG4iCisgICAgIn1cbiIKKyAgICAiXG4iKTsKKworICAvLyBQYXJhbWV0ZXJsZXNzIGNvbnN0cnVjdG9yIGFuZCBwYXJ0aWFsIE9uQ29uc3RydWN0aW9uIG1ldGhvZC4KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgdmFycywKKyAgICAicHVibGljICRjbGFzc19uYW1lJCgpIHtcbiIKKyAgICAiICBPbkNvbnN0cnVjdGlvbigpO1xuIgorICAgICJ9XG5cbiIKKyAgICAicGFydGlhbCB2b2lkIE9uQ29uc3RydWN0aW9uKCk7XG5cbiIpOworCisgIEdlbmVyYXRlQ2xvbmluZ0NvZGUocHJpbnRlcik7CisgIEdlbmVyYXRlRnJlZXppbmdDb2RlKHByaW50ZXIpOworCisgIC8vIEZpZWxkcy9wcm9wZXJ0aWVzCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGREZXNjcmlwdG9yID0gZGVzY3JpcHRvcl8tPmZpZWxkKGkpOworCisgICAgLy8gUmF0czogd2UgbG9zZSB0aGUgZGVidWcgY29tbWVudCBoZXJlIDooCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiLy8vIDxzdW1tYXJ5PkZpZWxkIG51bWJlciBmb3IgdGhlIFwiJGZpZWxkX25hbWUkXCIgZmllbGQuPC9zdW1tYXJ5PlxuIgorICAgICAgInB1YmxpYyBjb25zdCBpbnQgJGZpZWxkX2NvbnN0YW50X25hbWUkID0gJGluZGV4JDtcbiIsCisgICAgICAiZmllbGRfbmFtZSIsIGZpZWxkRGVzY3JpcHRvci0+bmFtZSgpLAorICAgICAgImZpZWxkX2NvbnN0YW50X25hbWUiLCBHZXRGaWVsZENvbnN0YW50TmFtZShmaWVsZERlc2NyaXB0b3IpLAorICAgICAgImluZGV4IiwgU2ltcGxlSXRvYShmaWVsZERlc2NyaXB0b3ItPm51bWJlcigpKSk7CisgICAgc2NvcGVkX3B0cjxGaWVsZEdlbmVyYXRvckJhc2U+IGdlbmVyYXRvcigKKyAgICAgICAgQ3JlYXRlRmllbGRHZW5lcmF0b3JJbnRlcm5hbChmaWVsZERlc2NyaXB0b3IpKTsKKyAgICBnZW5lcmF0b3ItPkdlbmVyYXRlTWVtYmVycyhwcmludGVyKTsKKyAgICBwcmludGVyLT5QcmludCgiXG4iKTsKKyAgfQorCisgIC8vIG9uZW9mIHByb3BlcnRpZXMKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbF9jb3VudCgpOyBpKyspIHsKKyAgICB2YXJzWyJuYW1lIl0gPSBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlKGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5uYW1lKCksIGZhbHNlKTsKKyAgICB2YXJzWyJwcm9wZXJ0eV9uYW1lIl0gPSBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlKGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5uYW1lKCksIHRydWUpOworICAgIHZhcnNbIm9yaWdpbmFsX25hbWUiXSA9IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5uYW1lKCk7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICB2YXJzLAorICAgICAgInByaXZhdGUgb2JqZWN0ICRuYW1lJF87XG4iCisgICAgICAiLy8vIDxzdW1tYXJ5PkVudW0gb2YgcG9zc2libGUgY2FzZXMgZm9yIHRoZSBcIiRvcmlnaW5hbF9uYW1lJFwiIG9uZW9mLjwvc3VtbWFyeT5cbiIKKyAgICAgICJwdWJsaWMgZW51bSAkcHJvcGVydHlfbmFtZSRPbmVvZkNhc2Uge1xuIik7CisgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgcHJpbnRlci0+UHJpbnQoIk5vbmUgPSAwLFxuIik7CisgICAgZm9yIChpbnQgaiA9IDA7IGogPCBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKS0+ZmllbGRfY291bnQoKTsgaisrKSB7CisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPmZpZWxkKGopOworICAgICAgcHJpbnRlci0+UHJpbnQoIiRmaWVsZF9wcm9wZXJ0eV9uYW1lJCA9ICRpbmRleCQsXG4iLAorICAgICAgICAgICAgICAgICAgICAgImZpZWxkX3Byb3BlcnR5X25hbWUiLCBHZXRQcm9wZXJ0eU5hbWUoZmllbGQpLAorICAgICAgICAgICAgICAgICAgICAgImluZGV4IiwgU2ltcGxlSXRvYShmaWVsZC0+bnVtYmVyKCkpKTsKKyAgICB9CisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIHByaW50ZXItPlByaW50KCJ9XG4iKTsKKyAgICAvLyBUT0RPOiBTaG91bGQgd2UgcHV0IHRoZSBvbmVvZiAucHJvdG8gY29tbWVudHMgaGVyZT8gSXQncyB1bmNsZWFyIGV4YWN0bHkgd2hlcmUgdGhleSBzaG91bGQgZ28uCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICB2YXJzLAorICAgICAgInByaXZhdGUgJHByb3BlcnR5X25hbWUkT25lb2ZDYXNlICRuYW1lJENhc2VfID0gJHByb3BlcnR5X25hbWUkT25lb2ZDYXNlLk5vbmU7XG4iCisgICAgICAicHVibGljICRwcm9wZXJ0eV9uYW1lJE9uZW9mQ2FzZSAkcHJvcGVydHlfbmFtZSRDYXNlIHtcbiIKKyAgICAgICIgIGdldCB7IHJldHVybiAkbmFtZSRDYXNlXzsgfVxuIgorICAgICAgIn1cblxuIgorICAgICAgInB1YmxpYyB2b2lkIENsZWFyJHByb3BlcnR5X25hbWUkKCkge1xuIgorICAgICAgIiAgJG5hbWUkQ2FzZV8gPSAkcHJvcGVydHlfbmFtZSRPbmVvZkNhc2UuTm9uZTtcbiIKKyAgICAgICIgICRuYW1lJF8gPSBudWxsO1xuIgorICAgICAgIn1cblxuIik7CisgIH0KKworICAvLyBTdGFuZGFyZCBtZXRob2RzCisgIEdlbmVyYXRlRnJhbWV3b3JrTWV0aG9kcyhwcmludGVyKTsKKyAgR2VuZXJhdGVNZXNzYWdlU2VyaWFsaXphdGlvbk1ldGhvZHMocHJpbnRlcik7CisgIEdlbmVyYXRlTWVyZ2luZ01ldGhvZHMocHJpbnRlcik7CisKKyAgLy8gTmVzdGVkIG1lc3NhZ2VzIGFuZCBlbnVtcworICBpZiAoSGFzTmVzdGVkR2VuZXJhdGVkVHlwZXMoKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgdmFycywKKyAgICAgICIjcmVnaW9uIE5lc3RlZCB0eXBlc1xuIgorICAgICAgIi8vLyA8c3VtbWFyeT5Db250YWluZXIgZm9yIG5lc3RlZCB0eXBlcyBkZWNsYXJlZCBpbiB0aGUgJGNsYXNzX25hbWUkIG1lc3NhZ2UgdHlwZS48L3N1bW1hcnk+XG4iCisgICAgICAiW2dsb2JhbDo6U3lzdGVtLkRpYWdub3N0aWNzLkRlYnVnZ2VyTm9uVXNlckNvZGVBdHRyaWJ1dGUoKV1cbiIpOworICAgIFdyaXRlR2VuZXJhdGVkQ29kZUF0dHJpYnV0ZXMocHJpbnRlcik7CisgICAgcHJpbnRlci0+UHJpbnQoInB1YmxpYyBzdGF0aWMgcGFydGlhbCBjbGFzcyBUeXBlcyB7XG4iKTsKKyAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5lbnVtX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgICBFbnVtR2VuZXJhdG9yIGVudW1HZW5lcmF0b3IoZGVzY3JpcHRvcl8tPmVudW1fdHlwZShpKSk7CisgICAgICBlbnVtR2VuZXJhdG9yLkdlbmVyYXRlKHByaW50ZXIpOworICAgIH0KKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5uZXN0ZWRfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICAgIC8vIERvbid0IGdlbmVyYXRlIG5lc3RlZCB0eXBlcyBmb3IgbWFwcy4uLgorICAgICAgaWYgKCFJc01hcEVudHJ5TWVzc2FnZShkZXNjcmlwdG9yXy0+bmVzdGVkX3R5cGUoaSkpKSB7CisgICAgICAgIE1lc3NhZ2VHZW5lcmF0b3IgbWVzc2FnZUdlbmVyYXRvcihkZXNjcmlwdG9yXy0+bmVzdGVkX3R5cGUoaSkpOworICAgICAgICBtZXNzYWdlR2VuZXJhdG9yLkdlbmVyYXRlKHByaW50ZXIpOworICAgICAgfQorICAgIH0KKyAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgcHJpbnRlci0+UHJpbnQoIn1cbiIKKyAgICAgICAgICAgICAgICAgICAiI2VuZHJlZ2lvblxuIgorICAgICAgICAgICAgICAgICAgICJcbiIpOworICB9CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgifVxuIik7CisgIHByaW50ZXItPlByaW50KCJcbiIpOworfQorCisvLyBIZWxwZXIgdG8gd29yayBvdXQgd2hldGhlciB3ZSBuZWVkIHRvIGdlbmVyYXRlIGEgY2xhc3MgdG8gaG9sZCBuZXN0ZWQgdHlwZXMvZW51bXMuCisvLyBPbmx5IHRyaWNreSBiZWNhdXNlIHdlIGRvbid0IHdhbnQgdG8gZ2VuZXJhdGUgbWFwIGVudHJ5IHR5cGVzLgorYm9vbCBNZXNzYWdlR2VuZXJhdG9yOjpIYXNOZXN0ZWRHZW5lcmF0ZWRUeXBlcygpCit7CisgIGlmIChkZXNjcmlwdG9yXy0+ZW51bV90eXBlX2NvdW50KCkgPiAwKSB7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+bmVzdGVkX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgaWYgKCFJc01hcEVudHJ5TWVzc2FnZShkZXNjcmlwdG9yXy0+bmVzdGVkX3R5cGUoaSkpKSB7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIGZhbHNlOworfQorCit2b2lkIE1lc3NhZ2VHZW5lcmF0b3I6OkdlbmVyYXRlQ2xvbmluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJzOworICB2YXJzWyJjbGFzc19uYW1lIl0gPSBjbGFzc19uYW1lKCk7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgdmFycywKKyAgICAicHVibGljICRjbGFzc19uYW1lJCgkY2xhc3NfbmFtZSQgb3RoZXIpIDogdGhpcygpIHtcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKyAgLy8gQ2xvbmUgbm9uLW9uZW9mIGZpZWxkcyBmaXJzdAorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBpZiAoIWRlc2NyaXB0b3JfLT5maWVsZChpKS0+Y29udGFpbmluZ19vbmVvZigpKSB7CisgICAgICBzY29wZWRfcHRyPEZpZWxkR2VuZXJhdG9yQmFzZT4gZ2VuZXJhdG9yKAorICAgICAgICBDcmVhdGVGaWVsZEdlbmVyYXRvckludGVybmFsKGRlc2NyaXB0b3JfLT5maWVsZChpKSkpOworICAgICAgZ2VuZXJhdG9yLT5HZW5lcmF0ZUNsb25pbmdDb2RlKHByaW50ZXIpOworICAgIH0KKyAgfQorICAvLyBDbG9uZSBqdXN0IHRoZSByaWdodCBmaWVsZCBmb3IgZWFjaCBvbmVvZgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsX2NvdW50KCk7ICsraSkgeworICAgIHZhcnNbIm5hbWUiXSA9IFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPm5hbWUoKSwgZmFsc2UpOworICAgIHZhcnNbInByb3BlcnR5X25hbWUiXSA9IFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPm5hbWUoKSwgdHJ1ZSk7CisgICAgcHJpbnRlci0+UHJpbnQodmFycywgInN3aXRjaCAob3RoZXIuJHByb3BlcnR5X25hbWUkQ2FzZSkge1xuIik7CisgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgZm9yIChpbnQgaiA9IDA7IGogPCBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKS0+ZmllbGRfY291bnQoKTsgaisrKSB7CisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPmZpZWxkKGopOworICAgICAgc2NvcGVkX3B0cjxGaWVsZEdlbmVyYXRvckJhc2U+IGdlbmVyYXRvcihDcmVhdGVGaWVsZEdlbmVyYXRvckludGVybmFsKGZpZWxkKSk7CisgICAgICB2YXJzWyJmaWVsZF9wcm9wZXJ0eV9uYW1lIl0gPSBHZXRQcm9wZXJ0eU5hbWUoZmllbGQpOworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgdmFycywKKyAgICAgICAgICAiY2FzZSAkcHJvcGVydHlfbmFtZSRPbmVvZkNhc2UuJGZpZWxkX3Byb3BlcnR5X25hbWUkOlxuIik7CisgICAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICAgIGdlbmVyYXRvci0+R2VuZXJhdGVDbG9uaW5nQ29kZShwcmludGVyKTsKKyAgICAgIHByaW50ZXItPlByaW50KCJicmVhaztcbiIpOworICAgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIH0KKyAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgcHJpbnRlci0+UHJpbnQoIn1cblxuIik7CisgIH0KKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KCJ9XG5cbiIpOworCisgIHByaW50ZXItPlByaW50KAorICAgIHZhcnMsCisgICAgInB1YmxpYyAkY2xhc3NfbmFtZSQgQ2xvbmUoKSB7XG4iCisgICAgIiAgcmV0dXJuIG5ldyAkY2xhc3NfbmFtZSQodGhpcyk7XG4iCisgICAgIn1cblxuIik7Cit9CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6R2VuZXJhdGVGcmVlemluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKK30KKwordm9pZCBNZXNzYWdlR2VuZXJhdG9yOjpHZW5lcmF0ZUZyYW1ld29ya01ldGhvZHMoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcnM7CisgICAgdmFyc1siY2xhc3NfbmFtZSJdID0gY2xhc3NfbmFtZSgpOworCisgICAgLy8gRXF1YWxpdHkKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgdmFycywKKyAgICAgICAgInB1YmxpYyBvdmVycmlkZSBib29sIEVxdWFscyhvYmplY3Qgb3RoZXIpIHtcbiIKKyAgICAgICAgIiAgcmV0dXJuIEVxdWFscyhvdGhlciBhcyAkY2xhc3NfbmFtZSQpO1xuIgorICAgICAgICAifVxuXG4iCisgICAgICAgICJwdWJsaWMgYm9vbCBFcXVhbHMoJGNsYXNzX25hbWUkIG90aGVyKSB7XG4iCisgICAgICAgICIgIGlmIChSZWZlcmVuY2VFcXVhbHMob3RoZXIsIG51bGwpKSB7XG4iCisgICAgICAgICIgICAgcmV0dXJuIGZhbHNlO1xuIgorICAgICAgICAiICB9XG4iCisgICAgICAgICIgIGlmIChSZWZlcmVuY2VFcXVhbHMob3RoZXIsIHRoaXMpKSB7XG4iCisgICAgICAgICIgICAgcmV0dXJuIHRydWU7XG4iCisgICAgICAgICIgIH1cbiIpOworICAgIHByaW50ZXItPkluZGVudCgpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgICAgICBzY29wZWRfcHRyPEZpZWxkR2VuZXJhdG9yQmFzZT4gZ2VuZXJhdG9yKAorICAgICAgICAgICAgQ3JlYXRlRmllbGRHZW5lcmF0b3JJbnRlcm5hbChkZXNjcmlwdG9yXy0+ZmllbGQoaSkpKTsKKyAgICAgICAgZ2VuZXJhdG9yLT5Xcml0ZUVxdWFscyhwcmludGVyKTsKKyAgICB9CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbF9jb3VudCgpOyBpKyspIHsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoImlmICgkcHJvcGVydHlfbmFtZSRDYXNlICE9IG90aGVyLiRwcm9wZXJ0eV9uYW1lJENhc2UpIHJldHVybiBmYWxzZTtcbiIsCisgICAgICAgICAgICAicHJvcGVydHlfbmFtZSIsIFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPm5hbWUoKSwgdHJ1ZSkpOworICAgIH0KKyAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICIgIHJldHVybiB0cnVlO1xuIgorICAgICAgICAifVxuXG4iKTsKKworICAgIC8vIEdldEhhc2hDb2RlCisgICAgLy8gU3RhcnQgd2l0aCBhIG5vbi16ZXJvIHZhbHVlIHRvIGVhc2lseSBkaXN0aW5ndWlzaCBiZXR3ZWVuIG51bGwgYW5kICJlbXB0eSIgbWVzc2FnZXMuCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJwdWJsaWMgb3ZlcnJpZGUgaW50IEdldEhhc2hDb2RlKCkge1xuIgorICAgICAgICAiICBpbnQgaGFzaCA9IDE7XG4iKTsKKyAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICAgICAgc2NvcGVkX3B0cjxGaWVsZEdlbmVyYXRvckJhc2U+IGdlbmVyYXRvcigKKyAgICAgICAgICAgIENyZWF0ZUZpZWxkR2VuZXJhdG9ySW50ZXJuYWwoZGVzY3JpcHRvcl8tPmZpZWxkKGkpKSk7CisgICAgICAgIGdlbmVyYXRvci0+V3JpdGVIYXNoKHByaW50ZXIpOworICAgIH0KKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsX2NvdW50KCk7IGkrKykgeworICAgICAgICBwcmludGVyLT5QcmludCgiaGFzaCBePSAoaW50KSAkbmFtZSRDYXNlXztcbiIsCisgICAgICAgICAgICAibmFtZSIsIFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPm5hbWUoKSwgZmFsc2UpKTsKKyAgICB9CisgICAgcHJpbnRlci0+UHJpbnQoInJldHVybiBoYXNoO1xuIik7CisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIHByaW50ZXItPlByaW50KCJ9XG5cbiIpOworCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJwdWJsaWMgb3ZlcnJpZGUgc3RyaW5nIFRvU3RyaW5nKCkge1xuIgorICAgICAgICAiICByZXR1cm4gcGI6Okpzb25Gb3JtYXR0ZXIuVG9EaWFnbm9zdGljU3RyaW5nKHRoaXMpO1xuIgorICAgICAgICAifVxuXG4iKTsKK30KKwordm9pZCBNZXNzYWdlR2VuZXJhdG9yOjpHZW5lcmF0ZU1lc3NhZ2VTZXJpYWxpemF0aW9uTWV0aG9kcyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICAgICJwdWJsaWMgdm9pZCBXcml0ZVRvKHBiOjpDb2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpIHtcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICAvLyBTZXJpYWxpemUgYWxsIHRoZSBmaWVsZHMKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZHNfYnlfbnVtYmVyKCkuc2l6ZSgpOyBpKyspIHsKKyAgICBzY29wZWRfcHRyPEZpZWxkR2VuZXJhdG9yQmFzZT4gZ2VuZXJhdG9yKAorICAgICAgQ3JlYXRlRmllbGRHZW5lcmF0b3JJbnRlcm5hbChmaWVsZHNfYnlfbnVtYmVyKClbaV0pKTsKKyAgICBnZW5lcmF0b3ItPkdlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUocHJpbnRlcik7CisgIH0KKworICAvLyBUT0RPKGpvbnNrZWV0KTogTWVtb2l6ZSBzaXplIG9mIGZyb3plbiBtZXNzYWdlcz8KKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAifVxuIgorICAgICJcbiIKKyAgICAicHVibGljIGludCBDYWxjdWxhdGVTaXplKCkge1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworICBwcmludGVyLT5QcmludCgiaW50IHNpemUgPSAwO1xuIik7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIHNjb3BlZF9wdHI8RmllbGRHZW5lcmF0b3JCYXNlPiBnZW5lcmF0b3IoCisgICAgICAgIENyZWF0ZUZpZWxkR2VuZXJhdG9ySW50ZXJuYWwoZGVzY3JpcHRvcl8tPmZpZWxkKGkpKSk7CisgICAgZ2VuZXJhdG9yLT5HZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShwcmludGVyKTsKKyAgfQorICBwcmludGVyLT5QcmludCgicmV0dXJuIHNpemU7XG4iKTsKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgifVxuXG4iKTsKK30KKwordm9pZCBNZXNzYWdlR2VuZXJhdG9yOjpHZW5lcmF0ZU1lcmdpbmdNZXRob2RzKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIC8vIE5vdGU6ICBUaGVzZSBhcmUgc2VwYXJhdGUgZnJvbSBHZW5lcmF0ZU1lc3NhZ2VTZXJpYWxpemF0aW9uTWV0aG9kcygpCisgIC8vICAgYmVjYXVzZSB0aGV5IG5lZWQgdG8gYmUgZ2VuZXJhdGVkIGV2ZW4gZm9yIG1lc3NhZ2VzIHRoYXQgYXJlIG9wdGltaXplZAorICAvLyAgIGZvciBjb2RlIHNpemUuCisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyczsKKyAgdmFyc1siY2xhc3NfbmFtZSJdID0gY2xhc3NfbmFtZSgpOworCisgIHByaW50ZXItPlByaW50KAorICAgIHZhcnMsCisgICAgInB1YmxpYyB2b2lkIE1lcmdlRnJvbSgkY2xhc3NfbmFtZSQgb3RoZXIpIHtcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgImlmIChvdGhlciA9PSBudWxsKSB7XG4iCisgICAgIiAgcmV0dXJuO1xuIgorICAgICJ9XG4iKTsKKyAgLy8gTWVyZ2Ugbm9uLW9uZW9mIGZpZWxkcworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBpZiAoIWRlc2NyaXB0b3JfLT5maWVsZChpKS0+Y29udGFpbmluZ19vbmVvZigpKSB7ICAgICAgCisgICAgICBzY29wZWRfcHRyPEZpZWxkR2VuZXJhdG9yQmFzZT4gZ2VuZXJhdG9yKAorICAgICAgICAgIENyZWF0ZUZpZWxkR2VuZXJhdG9ySW50ZXJuYWwoZGVzY3JpcHRvcl8tPmZpZWxkKGkpKSk7CisgICAgICBnZW5lcmF0b3ItPkdlbmVyYXRlTWVyZ2luZ0NvZGUocHJpbnRlcik7CisgICAgfQorICB9CisgIC8vIE1lcmdlIG9uZW9mIGZpZWxkcworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsX2NvdW50KCk7ICsraSkgeworICAgIHZhcnNbIm5hbWUiXSA9IFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPm5hbWUoKSwgZmFsc2UpOworICAgIHZhcnNbInByb3BlcnR5X25hbWUiXSA9IFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPm5hbWUoKSwgdHJ1ZSk7CisgICAgcHJpbnRlci0+UHJpbnQodmFycywgInN3aXRjaCAob3RoZXIuJHByb3BlcnR5X25hbWUkQ2FzZSkge1xuIik7CisgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgZm9yIChpbnQgaiA9IDA7IGogPCBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKS0+ZmllbGRfY291bnQoKTsgaisrKSB7CisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPmZpZWxkKGopOworICAgICAgdmFyc1siZmllbGRfcHJvcGVydHlfbmFtZSJdID0gR2V0UHJvcGVydHlOYW1lKGZpZWxkKTsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICB2YXJzLAorICAgICAgICAiY2FzZSAkcHJvcGVydHlfbmFtZSRPbmVvZkNhc2UuJGZpZWxkX3Byb3BlcnR5X25hbWUkOlxuIgorICAgICAgICAiICAkZmllbGRfcHJvcGVydHlfbmFtZSQgPSBvdGhlci4kZmllbGRfcHJvcGVydHlfbmFtZSQ7XG4iCisgICAgICAgICIgIGJyZWFrO1xuIik7CisgICAgfQorICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICBwcmludGVyLT5QcmludCgifVxuXG4iKTsKKyAgfQorICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KCJ9XG5cbiIpOworICBwcmludGVyLT5QcmludCgicHVibGljIHZvaWQgTWVyZ2VGcm9tKHBiOjpDb2RlZElucHV0U3RyZWFtIGlucHV0KSB7XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisgIHByaW50ZXItPlByaW50KAorICAgICJ1aW50IHRhZztcbiIKKyAgICAid2hpbGUgKCh0YWcgPSBpbnB1dC5SZWFkVGFnKCkpICE9IDApIHtcbiIKKyAgICAiICBzd2l0Y2godGFnKSB7XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisgIHByaW50ZXItPkluZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAiZGVmYXVsdDpcbiIKKyAgICAiICBpbnB1dC5Ta2lwTGFzdEZpZWxkKCk7XG4iIC8vIFdlJ3JlIG5vdCBzdG9yaW5nIHRoZSBkYXRhLCBidXQgd2Ugc3RpbGwgbmVlZCB0byBjb25zdW1lIGl0LgorICAgICIgIGJyZWFrO1xuIik7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRzX2J5X251bWJlcigpLnNpemUoKTsgaSsrKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGZpZWxkc19ieV9udW1iZXIoKVtpXTsKKyAgICBpbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldpcmVUeXBlIHd0ID0KKyAgICAgICAgaW50ZXJuYWw6OldpcmVGb3JtYXQ6OldpcmVUeXBlRm9yRmllbGRUeXBlKGZpZWxkLT50eXBlKCkpOworICAgIHVpbnQzMiB0YWcgPSBpbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1ha2VUYWcoZmllbGQtPm51bWJlcigpLCB3dCk7CisgICAgLy8gSGFuZGxlIGJvdGggcGFja2VkIGFuZCB1bnBhY2tlZCByZXBlYXRlZCBmaWVsZHMgd2l0aCB0aGUgc2FtZSBSZWFkKkFycmF5IGNhbGw7CisgICAgLy8gdGhlIHR3byBnZW5lcmF0ZWQgY2FzZXMgYXJlIHRoZSBwYWNrZWQgYW5kIHVucGFja2VkIHRhZ3MuCisgICAgLy8gVE9ETyhqb25za2VldCk6IENoZWNrIHRoYXQgaXNfcGFja2FibGUgaXMgZXF1aXZhbGVudCB0byBpc19yZXBlYXRlZCAmJiB3dCBpbiB7IFZBUklOVCwgRklYRUQzMiwgRklYRUQ2NCB9LgorICAgIC8vIEl0IGxvb2tzIGxpa2UgaXQgaXMuLi4KKyAgICBpZiAoZmllbGQtPmlzX3BhY2thYmxlKCkpIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiY2FzZSAkcGFja2VkX3RhZyQ6XG4iLAorICAgICAgICAicGFja2VkX3RhZyIsCisgICAgICAgIFNpbXBsZUl0b2EoCisgICAgICAgICAgICBpbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1ha2VUYWcoCisgICAgICAgICAgICAgICAgZmllbGQtPm51bWJlcigpLAorICAgICAgICAgICAgICAgIGludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCkpKTsKKyAgICB9CisKKyAgICBwcmludGVyLT5QcmludCgiY2FzZSAkdGFnJDoge1xuIiwgInRhZyIsIFNpbXBsZUl0b2EodGFnKSk7CisgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgc2NvcGVkX3B0cjxGaWVsZEdlbmVyYXRvckJhc2U+IGdlbmVyYXRvcigKKyAgICAgICAgQ3JlYXRlRmllbGRHZW5lcmF0b3JJbnRlcm5hbChmaWVsZCkpOworICAgIGdlbmVyYXRvci0+R2VuZXJhdGVQYXJzaW5nQ29kZShwcmludGVyKTsKKyAgICBwcmludGVyLT5QcmludCgiYnJlYWs7XG4iKTsKKyAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworICB9CisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOyAvLyBzd2l0Y2gKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgifVxuIik7IC8vIHdoaWxlCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoIn1cblxuIik7IC8vIG1ldGhvZAorfQorCitpbnQgTWVzc2FnZUdlbmVyYXRvcjo6R2V0RmllbGRPcmRpbmFsKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkX25hbWVzKCkuc2l6ZSgpOyBpKyspIHsKKyAgICBpZiAoZmllbGRfbmFtZXMoKVtpXSA9PSBkZXNjcmlwdG9yLT5uYW1lKCkpIHsKKyAgICAgIHJldHVybiBpOworICAgIH0KKyAgfQorICBHT09HTEVfTE9HKERGQVRBTCk8PCAiQ291bGQgbm90IGZpbmQgb3JkaW5hbCBmb3IgZmllbGQgIiA8PCBkZXNjcmlwdG9yLT5uYW1lKCk7CisgIHJldHVybiAtMTsKK30KKworRmllbGRHZW5lcmF0b3JCYXNlKiBNZXNzYWdlR2VuZXJhdG9yOjpDcmVhdGVGaWVsZEdlbmVyYXRvckludGVybmFsKAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICByZXR1cm4gQ3JlYXRlRmllbGRHZW5lcmF0b3IoZGVzY3JpcHRvciwgR2V0RmllbGRPcmRpbmFsKGRlc2NyaXB0b3IpKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGNzaGFycAorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9tZXNzYWdlLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfbWVzc2FnZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYwYzQ5YWMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfbWVzc2FnZS5oCkBAIC0wLDAgKzEsODkgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DU0hBUlBfTUVTU0FHRV9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NTSEFSUF9NRVNTQUdFX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPHZlY3Rvcj4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jb2RlX2dlbmVyYXRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX3NvdXJjZV9nZW5lcmF0b3JfYmFzZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX2hlbHBlcnMuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBjc2hhcnAgeworCitjbGFzcyBGaWVsZEdlbmVyYXRvckJhc2U7CisKK2NsYXNzIE1lc3NhZ2VHZW5lcmF0b3IgOiBwdWJsaWMgU291cmNlR2VuZXJhdG9yQmFzZSB7CisgcHVibGljOgorICBNZXNzYWdlR2VuZXJhdG9yKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworICB+TWVzc2FnZUdlbmVyYXRvcigpOworCisgIHZvaWQgR2VuZXJhdGVDbG9uaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZvaWQgR2VuZXJhdGVGcmVlemluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2b2lkIEdlbmVyYXRlRnJhbWV3b3JrTWV0aG9kcyhpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZvaWQgR2VuZXJhdGUoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgcHJpdmF0ZToKKyAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcl87CisgIHN0ZDo6dmVjdG9yPHN0ZDo6c3RyaW5nPiBmaWVsZF9uYW1lc187CisgIHN0ZDo6dmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+IGZpZWxkc19ieV9udW1iZXJfOworCisgIHZvaWQgR2VuZXJhdGVNZXNzYWdlU2VyaWFsaXphdGlvbk1ldGhvZHMoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2b2lkIEdlbmVyYXRlTWVyZ2luZ01ldGhvZHMoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIGludCBHZXRGaWVsZE9yZGluYWwoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKKyAgRmllbGRHZW5lcmF0b3JCYXNlKiBDcmVhdGVGaWVsZEdlbmVyYXRvckludGVybmFsKAorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKKworICBib29sIEhhc05lc3RlZEdlbmVyYXRlZFR5cGVzKCk7CisKKyAgc3RkOjpzdHJpbmcgY2xhc3NfbmFtZSgpOworICBzdGQ6OnN0cmluZyBmdWxsX2NsYXNzX25hbWUoKTsKKworICAvLyBmaWVsZCBuYW1lcyBzb3J0ZWQgYWxwaGFiZXRpY2FsbHkKKyAgY29uc3Qgc3RkOjp2ZWN0b3I8c3RkOjpzdHJpbmc+JiBmaWVsZF9uYW1lcygpOworCisgIC8vIGZpZWxkIGRlc2NyaXB0b3JzIHNvcnRlZCBieSBudW1iZXIKKyAgY29uc3Qgc3RkOjp2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4mIGZpZWxkc19ieV9udW1iZXIoKTsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoTWVzc2FnZUdlbmVyYXRvcik7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgY3NoYXJwCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DU0hBUlBfTUVTU0FHRV9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9tZXNzYWdlX2ZpZWxkLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX21lc3NhZ2VfZmllbGQuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjgxZjc2OQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9tZXNzYWdlX2ZpZWxkLmNjCkBAIC0wLDAgKzEsMTk2IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2luY2x1ZGUgPHNzdHJlYW0+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY29kZV9nZW5lcmF0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfZG9jX2NvbW1lbnQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfbWVzc2FnZV9maWVsZC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGNzaGFycCB7CisKK01lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6TWVzc2FnZUZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBmaWVsZE9yZGluYWwpCisgICAgOiBGaWVsZEdlbmVyYXRvckJhc2UoZGVzY3JpcHRvciwgZmllbGRPcmRpbmFsKSB7CisgIHZhcmlhYmxlc19bImhhc19wcm9wZXJ0eV9jaGVjayJdID0gbmFtZSgpICsgIl8gIT0gbnVsbCI7CisgIHZhcmlhYmxlc19bImhhc19ub3RfcHJvcGVydHlfY2hlY2siXSA9IG5hbWUoKSArICJfID09IG51bGwiOworfQorCitNZXNzYWdlRmllbGRHZW5lcmF0b3I6On5NZXNzYWdlRmllbGRHZW5lcmF0b3IoKSB7CisKK30KKwordm9pZCBNZXNzYWdlRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICB2YXJpYWJsZXNfLAorICAgICJwcml2YXRlICR0eXBlX25hbWUkICRuYW1lJF87XG4iKTsKKyAgV3JpdGVQcm9wZXJ0eURvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBBZGREZXByZWNhdGVkRmxhZyhwcmludGVyKTsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgdmFyaWFibGVzXywKKyAgICAiJGFjY2Vzc19sZXZlbCQgJHR5cGVfbmFtZSQgJHByb3BlcnR5X25hbWUkIHtcbiIKKyAgICAiICBnZXQgeyByZXR1cm4gJG5hbWUkXzsgfVxuIgorICAgICIgIHNldCB7XG4iCisgICAgIiAgICAkbmFtZSRfID0gdmFsdWU7XG4iCisgICAgIiAgfVxuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBNZXNzYWdlRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgdmFyaWFibGVzXywKKyAgICAiaWYgKG90aGVyLiRoYXNfcHJvcGVydHlfY2hlY2skKSB7XG4iCisgICAgIiAgaWYgKCRoYXNfbm90X3Byb3BlcnR5X2NoZWNrJCkge1xuIgorICAgICIgICAgJG5hbWUkXyA9IG5ldyAkdHlwZV9uYW1lJCgpO1xuIgorICAgICIgIH1cbiIKKyAgICAiICAkcHJvcGVydHlfbmFtZSQuTWVyZ2VGcm9tKG90aGVyLiRwcm9wZXJ0eV9uYW1lJCk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIE1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6R2VuZXJhdGVQYXJzaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICB2YXJpYWJsZXNfLAorICAgICJpZiAoJGhhc19ub3RfcHJvcGVydHlfY2hlY2skKSB7XG4iCisgICAgIiAgJG5hbWUkXyA9IG5ldyAkdHlwZV9uYW1lJCgpO1xuIgorICAgICJ9XG4iCisgICAgLy8gVE9ETyhqb25za2VldCk6IERvIHdlIHJlYWxseSBuZWVkIG1lcmdpbmcgYmVoYXZpb3VyIGxpa2UgdGhpcz8KKyAgICAiaW5wdXQuUmVhZE1lc3NhZ2UoJG5hbWUkXyk7XG4iKTsgLy8gTm8gbmVlZCB0byBzdXBwb3J0IFRZUEVfR1JPVVAuLi4KK30KKwordm9pZCBNZXNzYWdlRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgdmFyaWFibGVzXywKKyAgICAiaWYgKCRoYXNfcHJvcGVydHlfY2hlY2skKSB7XG4iCisgICAgIiAgb3V0cHV0LldyaXRlUmF3VGFnKCR0YWdfYnl0ZXMkKTtcbiIKKyAgICAiICBvdXRwdXQuV3JpdGVNZXNzYWdlKCRwcm9wZXJ0eV9uYW1lJCk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIE1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6R2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgdmFyaWFibGVzXywKKyAgICAiaWYgKCRoYXNfcHJvcGVydHlfY2hlY2skKSB7XG4iCisgICAgIiAgc2l6ZSArPSAkdGFnX3NpemUkICsgcGI6OkNvZGVkT3V0cHV0U3RyZWFtLkNvbXB1dGVNZXNzYWdlU2l6ZSgkcHJvcGVydHlfbmFtZSQpO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBNZXNzYWdlRmllbGRHZW5lcmF0b3I6OldyaXRlSGFzaChpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICB2YXJpYWJsZXNfLAorICAgICJpZiAoJGhhc19wcm9wZXJ0eV9jaGVjayQpIGhhc2ggXj0gJHByb3BlcnR5X25hbWUkLkdldEhhc2hDb2RlKCk7XG4iKTsKK30KK3ZvaWQgTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjpXcml0ZUVxdWFscyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICB2YXJpYWJsZXNfLAorICAgICJpZiAoIW9iamVjdC5FcXVhbHMoJHByb3BlcnR5X25hbWUkLCBvdGhlci4kcHJvcGVydHlfbmFtZSQpKSByZXR1cm4gZmFsc2U7XG4iKTsKK30KK3ZvaWQgTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjpXcml0ZVRvU3RyaW5nKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHZhcmlhYmxlc19bImZpZWxkX25hbWUiXSA9IEdldEZpZWxkTmFtZShkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KAorICAgIHZhcmlhYmxlc18sCisgICAgIlByaW50RmllbGQoXCIkZmllbGRfbmFtZSRcIiwgaGFzJHByb3BlcnR5X25hbWUkLCAkbmFtZSRfLCB3cml0ZXIpO1xuIik7Cit9CisKK3ZvaWQgTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZUNsb25pbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRwcm9wZXJ0eV9uYW1lJCA9IG90aGVyLiRoYXNfcHJvcGVydHlfY2hlY2skID8gb3RoZXIuJHByb3BlcnR5X25hbWUkLkNsb25lKCkgOiBudWxsO1xuIik7Cit9CisKK3ZvaWQgTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZUZyZWV6aW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgeworfQorCit2b2lkIE1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6R2VuZXJhdGVDb2RlY0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgdmFyaWFibGVzXywKKyAgICAicGI6OkZpZWxkQ29kZWMuRm9yTWVzc2FnZSgkdGFnJCwgJHR5cGVfbmFtZSQuUGFyc2VyKSIpOworfQorCitNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcjo6TWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorCQkJCQkJICAgICAgIGludCBmaWVsZE9yZGluYWwpCisgICAgOiBNZXNzYWdlRmllbGRHZW5lcmF0b3IoZGVzY3JpcHRvciwgZmllbGRPcmRpbmFsKSB7CisgIFNldENvbW1vbk9uZW9mRmllbGRWYXJpYWJsZXMoJnZhcmlhYmxlc18pOworfQorCitNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcjo6fk1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yKCkgeworCit9CisKK3ZvaWQgTWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBXcml0ZVByb3BlcnR5RG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIEFkZERlcHJlY2F0ZWRGbGFnKHByaW50ZXIpOworICBwcmludGVyLT5QcmludCgKKyAgICB2YXJpYWJsZXNfLAorICAgICIkYWNjZXNzX2xldmVsJCAkdHlwZV9uYW1lJCAkcHJvcGVydHlfbmFtZSQge1xuIgorICAgICIgIGdldCB7IHJldHVybiAkaGFzX3Byb3BlcnR5X2NoZWNrJCA/ICgkdHlwZV9uYW1lJCkgJG9uZW9mX25hbWUkXyA6IG51bGw7IH1cbiIKKyAgICAiICBzZXQge1xuIgorICAgICIgICAgJG9uZW9mX25hbWUkXyA9IHZhbHVlO1xuIgorICAgICIgICAgJG9uZW9mX25hbWUkQ2FzZV8gPSB2YWx1ZSA9PSBudWxsID8gJG9uZW9mX3Byb3BlcnR5X25hbWUkT25lb2ZDYXNlLk5vbmUgOiAkb25lb2ZfcHJvcGVydHlfbmFtZSRPbmVvZkNhc2UuJHByb3BlcnR5X25hbWUkO1xuIgorICAgICIgIH1cbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgTWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgLy8gVE9ETyhqb25za2VldCk6IFdlIG1heSBiZSBhYmxlIHRvIGRvIGJldHRlciB0aGFuIHRoaXMKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgdmFyaWFibGVzXywKKyAgICAiJHR5cGVfbmFtZSQgc3ViQnVpbGRlciA9IG5ldyAkdHlwZV9uYW1lJCgpO1xuIgorICAgICJpZiAoJGhhc19wcm9wZXJ0eV9jaGVjayQpIHtcbiIKKyAgICAiICBzdWJCdWlsZGVyLk1lcmdlRnJvbSgkcHJvcGVydHlfbmFtZSQpO1xuIgorICAgICJ9XG4iCisgICAgImlucHV0LlJlYWRNZXNzYWdlKHN1YkJ1aWxkZXIpO1xuIiAvLyBObyBzdXBwb3J0IG9mIFRZUEVfR1JPVVAKKyAgICAiJHByb3BlcnR5X25hbWUkID0gc3ViQnVpbGRlcjtcbiIpOworfQorCit2b2lkIE1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yOjpXcml0ZVRvU3RyaW5nKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgIHZhcmlhYmxlc18sCisgICAgIlByaW50RmllbGQoXCIkZGVzY3JpcHRvcl9uYW1lJFwiLCAkaGFzX3Byb3BlcnR5X2NoZWNrJCwgJG9uZW9mX25hbWUkXywgd3JpdGVyKTtcbiIpOworfQorCit2b2lkIE1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZUNsb25pbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRwcm9wZXJ0eV9uYW1lJCA9IG90aGVyLiRwcm9wZXJ0eV9uYW1lJC5DbG9uZSgpO1xuIik7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBjc2hhcnAKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfbWVzc2FnZV9maWVsZC5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX21lc3NhZ2VfZmllbGQuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kYzZlNGRjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX21lc3NhZ2VfZmllbGQuaApAQCAtMCwwICsxLDg2IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1NIQVJQX01FU1NBR0VfRklFTERfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DU0hBUlBfTUVTU0FHRV9GSUVMRF9IX18KKworI2luY2x1ZGUgPHN0cmluZz4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jb2RlX2dlbmVyYXRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX2ZpZWxkX2Jhc2UuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBjc2hhcnAgeworCitjbGFzcyBNZXNzYWdlRmllbGRHZW5lcmF0b3IgOiBwdWJsaWMgRmllbGRHZW5lcmF0b3JCYXNlIHsKKyBwdWJsaWM6CisgIE1lc3NhZ2VGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGludCBmaWVsZE9yZGluYWwpOworICB+TWVzc2FnZUZpZWxkR2VuZXJhdG9yKCk7CisKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlQ29kZWNDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlQ2xvbmluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVGcmVlemluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVQYXJzaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworICB2aXJ0dWFsIHZvaWQgV3JpdGVIYXNoKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdmlydHVhbCB2b2lkIFdyaXRlRXF1YWxzKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdmlydHVhbCB2b2lkIFdyaXRlVG9TdHJpbmcoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKE1lc3NhZ2VGaWVsZEdlbmVyYXRvcik7Cit9OworCitjbGFzcyBNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvciA6IHB1YmxpYyBNZXNzYWdlRmllbGRHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgTWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBpbnQgZmllbGRPcmRpbmFsKTsKKyAgfk1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yKCk7CisKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlQ2xvbmluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdmlydHVhbCB2b2lkIFdyaXRlVG9TdHJpbmcoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVQYXJzaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoTWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3IpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGNzaGFycAorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1NIQVJQX01FU1NBR0VfRklFTERfSF9fCisKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9uYW1lcy5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX25hbWVzLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzA4MDUxOAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9uYW1lcy5oCkBAIC0wLDAgKzEsMTAzIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisvLworLy8gUHJvdmlkZXMgYSBtZWNoYW5pc20gZm9yIG1hcHBpbmcgYSBkZXNjcmlwdG9yIHRvIHRoZQorLy8gZnVsbHktcXVhbGlmaWVkIG5hbWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgQyMgY2xhc3MuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NTSEFSUF9OQU1FU19IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NTSEFSUF9OQU1FU19IX18KKworI2luY2x1ZGUgPHN0cmluZz4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCitjbGFzcyBEZXNjcmlwdG9yOworY2xhc3MgRW51bURlc2NyaXB0b3I7CitjbGFzcyBGaWxlRGVzY3JpcHRvcjsKK2NsYXNzIFNlcnZpY2VEZXNjcmlwdG9yOworCituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGNzaGFycCB7CisKKy8vIFJlcXVpcmVzOgorLy8gICBkZXNjcmlwdG9yICE9IE5VTEwKKy8vCisvLyBSZXR1cm5zOgorLy8gICBUaGUgbmFtZXNwYWNlIHRvIHVzZSBmb3IgZ2l2ZW4gZmlsZSBkZXNjcmlwdG9yLgorc3RyaW5nIEdldEZpbGVOYW1lc3BhY2UoY29uc3QgRmlsZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworCisvLyBSZXF1aXJlczoKKy8vICAgZGVzY3JpcHRvciAhPSBOVUxMCisvLworLy8gUmV0dXJuczoKKy8vICAgVGhlIGZ1bGx5LXF1YWxpZmllZCBDIyBjbGFzcyBuYW1lLgorc3RyaW5nIEdldENsYXNzTmFtZShjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKKworLy8gUmVxdWlyZXM6CisvLyAgIGRlc2NyaXB0b3IgIT0gTlVMTAorLy8KKy8vIFJldHVybnM6CisvLyAgIFRoZSBmdWxseS1xdWFsaWZpZWQgbmFtZSBvZiB0aGUgQyMgY2xhc3MgdGhhdCBwcm92aWRlcworLy8gICBhY2Nlc3MgdG8gdGhlIGZpbGUgZGVzY3JpcHRvci4gUHJvdG8gY29tcGlsZXIgZ2VuZXJhdGVzCisvLyAgIHN1Y2ggY2xhc3MgZm9yIGVhY2ggLnByb3RvIGZpbGUgcHJvY2Vzc2VkLgorc3RyaW5nIEdldFJlZmxlY3Rpb25DbGFzc05hbWUoY29uc3QgRmlsZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworCisvLyBHZW5lcmF0ZXMgb3V0cHV0IGZpbGUgbmFtZSBmb3IgZ2l2ZW4gZmlsZSBkZXNjcmlwdG9yLiBJZiBnZW5lcmF0ZV9kaXJlY3RvcmllcworLy8gaXMgdHJ1ZSwgdGhlIG91dHB1dCBmaWxlIHdpbGwgYmUgcHV0IHVuZGVyIGRpcmVjdG9yeSBjb3JyZXNwb25kaW5nIHRvIGZpbGUncworLy8gbmFtZXNwYWNlLiBiYXNlX25hbWVzcGFjZSBjYW4gYmUgdXNlZCB0byBzdHJpcCBzb21lIG9mIHRoZSB0b3AgbGV2ZWwKKy8vIGRpcmVjdG9yaWVzLiBFLmcuIGZvciBmaWxlIHdpdGggbmFtZXNwYWNlICJCYXIuRm9vIiBhbmQgYmFzZV9uYW1lc3BhY2U9IkJhciIsCisvLyB0aGUgcmVzdWx0aW5nIGZpbGUgd2lsbCBiZSBwdXQgdW5kZXIgZGlyZWN0b3J5ICJGb28iIChhbmQgbm90ICJCYXIvRm9vIikuCisvLworLy8gUmVxdWlyZXM6CisvLyAgIGRlc2NyaXB0b3IgIT0gTlVMTAorLy8gICBlcnJvciAhPSBOVUxMCisvLworLy8gIFJldHVybnM6CisvLyAgICBUaGUgZmlsZSBuYW1lIHRvIHVzZSBhcyBvdXRwdXQgZmlsZSBmb3IgZ2l2ZW4gZmlsZSBkZXNjcmlwdG9yLiBJbiBjYXNlCisvLyAgICBvZiBmYWlsdXJlLCB0aGlzIGZ1bmN0aW9uIHdpbGwgcmV0dXJuIGVtcHR5IHN0cmluZyBhbmQgZXJyb3IgcGFyYW1ldGVyCisvLyAgICB3aWxsIGNvbnRhaW4gdGhlIGVycm9yIG1lc3NhZ2UuCitzdHJpbmcgR2V0T3V0cHV0RmlsZSgKKyAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWxlRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICBjb25zdCBzdHJpbmcgZmlsZV9leHRlbnNpb24sCisgICAgY29uc3QgYm9vbCBnZW5lcmF0ZV9kaXJlY3RvcmllcywKKyAgICBjb25zdCBzdHJpbmcgYmFzZV9uYW1lc3BhY2UsCisgICAgc3RyaW5nKiBlcnJvcik7CisKK30gIC8vIG5hbWVzcGFjZSBjc2hhcnAKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NTSEFSUF9OQU1FU19IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9wcmltaXRpdmVfZmllbGQuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfcHJpbWl0aXZlX2ZpZWxkLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYwYWZkODkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfcHJpbWl0aXZlX2ZpZWxkLmNjCkBAIC0wLDAgKzEsMjE3IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2luY2x1ZGUgPHNzdHJlYW0+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY29kZV9nZW5lcmF0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfZG9jX2NvbW1lbnQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfcHJpbWl0aXZlX2ZpZWxkLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgY3NoYXJwIHsKKworUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OlByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwgaW50IGZpZWxkT3JkaW5hbCkKKyAgICA6IEZpZWxkR2VuZXJhdG9yQmFzZShkZXNjcmlwdG9yLCBmaWVsZE9yZGluYWwpIHsKKyAgLy8gVE9ETyhqb25za2VldCk6IE1ha2UgdGhpcyBjbGVhbmVyLi4uCisgIGlzX3ZhbHVlX3R5cGUgPSBkZXNjcmlwdG9yLT50eXBlKCkgIT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX1NUUklORworICAgICAgJiYgZGVzY3JpcHRvci0+dHlwZSgpICE9IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9CWVRFUzsKKyAgaWYgKCFpc192YWx1ZV90eXBlKSB7CisgICAgdmFyaWFibGVzX1siaGFzX3Byb3BlcnR5X2NoZWNrIl0gPSB2YXJpYWJsZXNfWyJwcm9wZXJ0eV9uYW1lIl0gKyAiLkxlbmd0aCAhPSAwIjsKKyAgICB2YXJpYWJsZXNfWyJvdGhlcl9oYXNfcHJvcGVydHlfY2hlY2siXSA9ICJvdGhlci4iICsgdmFyaWFibGVzX1sicHJvcGVydHlfbmFtZSJdICsgIi5MZW5ndGggIT0gMCI7CisgIH0KK30KKworUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6On5QcmltaXRpdmVGaWVsZEdlbmVyYXRvcigpIHsKK30KKwordm9pZCBQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6R2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIC8vIFRPRE8oam9uc2tlZXQpOiBXb3JrIG91dCB3aGV0aGVyIHdlIHdhbnQgdG8gcHJldmVudCB0aGUgZmllbGRzIGZyb20gZXZlciBiZWluZworICAvLyBudWxsLCBvciB3aGV0aGVyIHdlIGp1c3QgaGFuZGxlIGl0LCBpbiB0aGUgY2FzZXMgb2YgYnl0ZXMgYW5kIHN0cmluZy4KKyAgLy8gKEJhc2ljYWxseSwgc2hvdWxkIG51bGwtaGFuZGxpbmcgY29kZSBiZSBpbiB0aGUgZ2V0dGVyIG9yIHRoZSBzZXR0ZXI/KQorICBwcmludGVyLT5QcmludCgKKyAgICB2YXJpYWJsZXNfLAorICAgICJwcml2YXRlICR0eXBlX25hbWUkICRuYW1lX2RlZl9tZXNzYWdlJDtcbiIpOworICBXcml0ZVByb3BlcnR5RG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIEFkZERlcHJlY2F0ZWRGbGFnKHByaW50ZXIpOworICBwcmludGVyLT5QcmludCgKKyAgICB2YXJpYWJsZXNfLAorICAgICIkYWNjZXNzX2xldmVsJCAkdHlwZV9uYW1lJCAkcHJvcGVydHlfbmFtZSQge1xuIgorICAgICIgIGdldCB7IHJldHVybiAkbmFtZSRfOyB9XG4iCisgICAgIiAgc2V0IHtcbiIpOworICBpZiAoaXNfdmFsdWVfdHlwZSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgdmFyaWFibGVzXywKKyAgICAgICIgICAgJG5hbWUkXyA9IHZhbHVlO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICB2YXJpYWJsZXNfLAorICAgICAgIiAgICAkbmFtZSRfID0gcGI6OlByb3RvUHJlY29uZGl0aW9ucy5DaGVja05vdE51bGwodmFsdWUsIFwidmFsdWVcIik7XG4iKTsKKyAgfQorICBwcmludGVyLT5QcmludCgKKyAgICAiICB9XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgIHZhcmlhYmxlc18sCisgICAgImlmICgkb3RoZXJfaGFzX3Byb3BlcnR5X2NoZWNrJCkge1xuIgorICAgICIgICRwcm9wZXJ0eV9uYW1lJCA9IG90aGVyLiRwcm9wZXJ0eV9uYW1lJDtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgLy8gTm90ZTogaW52b2tlIHRoZSBwcm9wZXJ0eSBzZXR0ZXIgcmF0aGVyIHRoYW4gd3JpdGluZyBzdHJhaWdodCB0byB0aGUgZmllbGQsCisgIC8vIHNvIHRoYXQgd2UgY2FuIG5vcm1hbGl6ZSAibnVsbCB0byBlbXB0eSIgZm9yIHN0cmluZ3MgYW5kIGJ5dGVzLgorICBwcmludGVyLT5QcmludCgKKyAgICB2YXJpYWJsZXNfLAorICAgICIkcHJvcGVydHlfbmFtZSQgPSBpbnB1dC5SZWFkJGNhcGl0YWxpemVkX3R5cGVfbmFtZSQoKTtcbiIpOworfQorCit2b2lkIFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgIHZhcmlhYmxlc18sCisgICAgImlmICgkaGFzX3Byb3BlcnR5X2NoZWNrJCkge1xuIgorICAgICIgIG91dHB1dC5Xcml0ZVJhd1RhZygkdGFnX2J5dGVzJCk7XG4iCisgICAgIiAgb3V0cHV0LldyaXRlJGNhcGl0YWxpemVkX3R5cGVfbmFtZSQoJHByb3BlcnR5X25hbWUkKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgIHZhcmlhYmxlc18sCisgICAgImlmICgkaGFzX3Byb3BlcnR5X2NoZWNrJCkge1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworICBpbnQgZml4ZWRTaXplID0gR2V0Rml4ZWRTaXplKGRlc2NyaXB0b3JfLT50eXBlKCkpOworICBpZiAoZml4ZWRTaXplID09IC0xKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICB2YXJpYWJsZXNfLAorICAgICAgInNpemUgKz0gJHRhZ19zaXplJCArIHBiOjpDb2RlZE91dHB1dFN0cmVhbS5Db21wdXRlJGNhcGl0YWxpemVkX3R5cGVfbmFtZSRTaXplKCRwcm9wZXJ0eV9uYW1lJCk7XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJzaXplICs9ICR0YWdfc2l6ZSQgKyAkZml4ZWRfc2l6ZSQ7XG4iLAorICAgICAgImZpeGVkX3NpemUiLCBTaW1wbGVJdG9hKGZpeGVkU2l6ZSksCisgICAgICAidGFnX3NpemUiLCB2YXJpYWJsZXNfWyJ0YWdfc2l6ZSJdKTsKKyAgfQorICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KCJ9XG4iKTsKK30KKwordm9pZCBQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6V3JpdGVIYXNoKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgIHZhcmlhYmxlc18sCisgICAgImlmICgkaGFzX3Byb3BlcnR5X2NoZWNrJCkgaGFzaCBePSAkcHJvcGVydHlfbmFtZSQuR2V0SGFzaENvZGUoKTtcbiIpOworfQordm9pZCBQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6V3JpdGVFcXVhbHMoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgdmFyaWFibGVzXywKKyAgICAiaWYgKCRwcm9wZXJ0eV9uYW1lJCAhPSBvdGhlci4kcHJvcGVydHlfbmFtZSQpIHJldHVybiBmYWxzZTtcbiIpOworfQordm9pZCBQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6V3JpdGVUb1N0cmluZyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICB2YXJpYWJsZXNfLAorICAgICJQcmludEZpZWxkKFwiJGRlc2NyaXB0b3JfbmFtZSRcIiwgJGhhc19wcm9wZXJ0eV9jaGVjayQsICRwcm9wZXJ0eV9uYW1lJCwgd3JpdGVyKTtcbiIpOworfQorCit2b2lkIFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZUNsb25pbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRuYW1lJF8gPSBvdGhlci4kbmFtZSRfO1xuIik7Cit9CisKK3ZvaWQgUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlQ29kZWNDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgIHZhcmlhYmxlc18sCisgICAgInBiOjpGaWVsZENvZGVjLkZvciRjYXBpdGFsaXplZF90eXBlX25hbWUkKCR0YWckKSIpOworfQorCitQcmltaXRpdmVPbmVvZkZpZWxkR2VuZXJhdG9yOjpQcmltaXRpdmVPbmVvZkZpZWxkR2VuZXJhdG9yKAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwgaW50IGZpZWxkT3JkaW5hbCkKKyAgICA6IFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKGRlc2NyaXB0b3IsIGZpZWxkT3JkaW5hbCkgeworICBTZXRDb21tb25PbmVvZkZpZWxkVmFyaWFibGVzKCZ2YXJpYWJsZXNfKTsKK30KKworUHJpbWl0aXZlT25lb2ZGaWVsZEdlbmVyYXRvcjo6flByaW1pdGl2ZU9uZW9mRmllbGRHZW5lcmF0b3IoKSB7Cit9CisKK3ZvaWQgUHJpbWl0aXZlT25lb2ZGaWVsZEdlbmVyYXRvcjo6R2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIFdyaXRlUHJvcGVydHlEb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgQWRkRGVwcmVjYXRlZEZsYWcocHJpbnRlcik7CisgIHByaW50ZXItPlByaW50KAorICAgIHZhcmlhYmxlc18sCisgICAgIiRhY2Nlc3NfbGV2ZWwkICR0eXBlX25hbWUkICRwcm9wZXJ0eV9uYW1lJCB7XG4iCisgICAgIiAgZ2V0IHsgcmV0dXJuICRoYXNfcHJvcGVydHlfY2hlY2skID8gKCR0eXBlX25hbWUkKSAkb25lb2ZfbmFtZSRfIDogJGRlZmF1bHRfdmFsdWUkOyB9XG4iCisgICAgIiAgc2V0IHtcbiIpOworICAgIGlmIChpc192YWx1ZV90eXBlKSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgdmFyaWFibGVzXywKKyAgICAgICAgIiAgICAkb25lb2ZfbmFtZSRfID0gdmFsdWU7XG4iKTsKKyAgICB9IGVsc2UgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgIHZhcmlhYmxlc18sCisgICAgICAgICIgICAgJG9uZW9mX25hbWUkXyA9IHBiOjpQcm90b1ByZWNvbmRpdGlvbnMuQ2hlY2tOb3ROdWxsKHZhbHVlLCBcInZhbHVlXCIpO1xuIik7CisgICAgfQorICAgIHByaW50ZXItPlByaW50KAorICAgICAgdmFyaWFibGVzXywKKyAgICAgICIgICAgJG9uZW9mX25hbWUkQ2FzZV8gPSAkb25lb2ZfcHJvcGVydHlfbmFtZSRPbmVvZkNhc2UuJHByb3BlcnR5X25hbWUkO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIn1cbiIpOworfQorCit2b2lkIFByaW1pdGl2ZU9uZW9mRmllbGRHZW5lcmF0b3I6OldyaXRlVG9TdHJpbmcoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiUHJpbnRGaWVsZChcIiRkZXNjcmlwdG9yX25hbWUkXCIsICRoYXNfcHJvcGVydHlfY2hlY2skLCAkb25lb2ZfbmFtZSRfLCB3cml0ZXIpO1xuIik7Cit9CisKK3ZvaWQgUHJpbWl0aXZlT25lb2ZGaWVsZEdlbmVyYXRvcjo6R2VuZXJhdGVQYXJzaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgdmFyaWFibGVzXywKKyAgICAgICIkcHJvcGVydHlfbmFtZSQgPSBpbnB1dC5SZWFkJGNhcGl0YWxpemVkX3R5cGVfbmFtZSQoKTtcbiIpOworfQorCit2b2lkIFByaW1pdGl2ZU9uZW9mRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlQ2xvbmluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJHByb3BlcnR5X25hbWUkID0gb3RoZXIuJHByb3BlcnR5X25hbWUkO1xuIik7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBjc2hhcnAKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfcHJpbWl0aXZlX2ZpZWxkLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfcHJpbWl0aXZlX2ZpZWxkLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGI4N2ViYwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9wcmltaXRpdmVfZmllbGQuaApAQCAtMCwwICsxLDg4IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1NIQVJQX1BSSU1JVElWRV9GSUVMRF9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NTSEFSUF9QUklNSVRJVkVfRklFTERfSF9fCisKKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY29kZV9nZW5lcmF0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9maWVsZF9iYXNlLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgY3NoYXJwIHsKKworY2xhc3MgUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IgOiBwdWJsaWMgRmllbGRHZW5lcmF0b3JCYXNlIHsKKyBwdWJsaWM6CisgIFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwgaW50IGZpZWxkT3JkaW5hbCk7CisgIH5QcmltaXRpdmVGaWVsZEdlbmVyYXRvcigpOworCisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZUNvZGVjQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZUNsb25pbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyAgdmlydHVhbCB2b2lkIFdyaXRlSGFzaChpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZpcnR1YWwgdm9pZCBXcml0ZUVxdWFscyhpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZpcnR1YWwgdm9pZCBXcml0ZVRvU3RyaW5nKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworIHByb3RlY3RlZDoKKyAgYm9vbCBpc192YWx1ZV90eXBlOworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKTsKK307CisKK2NsYXNzIFByaW1pdGl2ZU9uZW9mRmllbGRHZW5lcmF0b3IgOiBwdWJsaWMgUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgUHJpbWl0aXZlT25lb2ZGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGludCBmaWVsZE9yZGluYWwpOworICB+UHJpbWl0aXZlT25lb2ZGaWVsZEdlbmVyYXRvcigpOworCisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZUNsb25pbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZpcnR1YWwgdm9pZCBXcml0ZVRvU3RyaW5nKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFByaW1pdGl2ZU9uZW9mRmllbGRHZW5lcmF0b3IpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGNzaGFycAorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1NIQVJQX1BSSU1JVElWRV9GSUVMRF9IX18KKwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX3JlZmxlY3Rpb25fY2xhc3MuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfcmVmbGVjdGlvbl9jbGFzcy5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMmRhZTQzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX3JlZmxlY3Rpb25fY2xhc3MuY2MKQEAgLTAsMCArMSwyOTEgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaW5jbHVkZSA8c3N0cmVhbT4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jb2RlX2dlbmVyYXRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wbHVnaW4uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX2VudW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfbWVzc2FnZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX25hbWVzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfcmVmbGVjdGlvbl9jbGFzcy5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGNzaGFycCB7CisKK1JlZmxlY3Rpb25DbGFzc0dlbmVyYXRvcjo6UmVmbGVjdGlvbkNsYXNzR2VuZXJhdG9yKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKQorICAgIDogU291cmNlR2VuZXJhdG9yQmFzZShmaWxlKSwKKyAgICAgIGZpbGVfKGZpbGUpIHsKKyAgbmFtZXNwYWNlXyA9IEdldEZpbGVOYW1lc3BhY2UoZmlsZSk7CisgIHJlZmxlY3Rpb25DbGFzc25hbWVfID0gR2V0UmVmbGVjdGlvbkNsYXNzVW5xdWFsaWZpZWROYW1lKGZpbGUpOworfQorCitSZWZsZWN0aW9uQ2xhc3NHZW5lcmF0b3I6On5SZWZsZWN0aW9uQ2xhc3NHZW5lcmF0b3IoKSB7Cit9CisKK3ZvaWQgUmVmbGVjdGlvbkNsYXNzR2VuZXJhdG9yOjpHZW5lcmF0ZShpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBXcml0ZUludHJvZHVjdGlvbihwcmludGVyKTsKKworICBXcml0ZURlc2NyaXB0b3IocHJpbnRlcik7CisgIC8vIENsb3NlIHRoZSBjbGFzcyBkZWNsYXJhdGlvbi4KKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgifVxuIik7CisKKyAgLy8gd3JpdGUgY2hpbGRyZW46IEVudW1zCisgIGlmIChmaWxlXy0+ZW51bV90eXBlX2NvdW50KCkgPiAwKSB7CisgICAgcHJpbnRlci0+UHJpbnQoIiNyZWdpb24gRW51bXNcbiIpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPmVudW1fdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICAgIEVudW1HZW5lcmF0b3IgZW51bUdlbmVyYXRvcihmaWxlXy0+ZW51bV90eXBlKGkpKTsKKyAgICAgIGVudW1HZW5lcmF0b3IuR2VuZXJhdGUocHJpbnRlcik7CisgICAgfQorICAgIHByaW50ZXItPlByaW50KCIjZW5kcmVnaW9uXG4iKTsKKyAgICBwcmludGVyLT5QcmludCgiXG4iKTsKKyAgfQorCisgIC8vIHdyaXRlIGNoaWxkcmVuOiBNZXNzYWdlcworICBpZiAoZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpID4gMCkgeworICAgIHByaW50ZXItPlByaW50KCIjcmVnaW9uIE1lc3NhZ2VzXG4iKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5tZXNzYWdlX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgICBNZXNzYWdlR2VuZXJhdG9yIG1lc3NhZ2VHZW5lcmF0b3IoZmlsZV8tPm1lc3NhZ2VfdHlwZShpKSk7CisgICAgICBtZXNzYWdlR2VuZXJhdG9yLkdlbmVyYXRlKHByaW50ZXIpOworICAgIH0KKyAgICBwcmludGVyLT5QcmludCgiI2VuZHJlZ2lvblxuIik7CisgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisgIH0KKworICAvLyBUT0RPKGp0YXR0ZXJtdXNjaCk6IGFkZCBpbnNlcnRpb24gcG9pbnQgZm9yIHNlcnZpY2VzLgorCisgIGlmICghbmFtZXNwYWNlXy5lbXB0eSgpKSB7CisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIHByaW50ZXItPlByaW50KCJ9XG4iKTsKKyAgfQorICBwcmludGVyLT5QcmludCgiXG4iKTsKKyAgcHJpbnRlci0+UHJpbnQoIiNlbmRyZWdpb24gRGVzaWduZXIgZ2VuZXJhdGVkIGNvZGVcbiIpOworfQorCit2b2lkIFJlZmxlY3Rpb25DbGFzc0dlbmVyYXRvcjo6V3JpdGVJbnRyb2R1Y3Rpb24oaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIi8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhXG4iCisgICAgIi8vIHNvdXJjZTogJGZpbGVfbmFtZSRcbiIKKyAgICAiI3ByYWdtYSB3YXJuaW5nIGRpc2FibGUgMTU5MSwgMDYxMiwgMzAyMVxuIgorICAgICIjcmVnaW9uIERlc2lnbmVyIGdlbmVyYXRlZCBjb2RlXG4iCisgICAgIlxuIgorICAgICJ1c2luZyBwYiA9IGdsb2JhbDo6R29vZ2xlLlByb3RvYnVmO1xuIgorICAgICJ1c2luZyBwYmMgPSBnbG9iYWw6Okdvb2dsZS5Qcm90b2J1Zi5Db2xsZWN0aW9ucztcbiIKKyAgICAidXNpbmcgcGJyID0gZ2xvYmFsOjpHb29nbGUuUHJvdG9idWYuUmVmbGVjdGlvbjtcbiIKKyAgICAidXNpbmcgc2NnID0gZ2xvYmFsOjpTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYztcbiIsCisgICAgImZpbGVfbmFtZSIsIGZpbGVfLT5uYW1lKCkpOworCisgIGlmICghbmFtZXNwYWNlXy5lbXB0eSgpKSB7CisgICAgcHJpbnRlci0+UHJpbnQoIm5hbWVzcGFjZSAkbmFtZXNwYWNlJCB7XG4iLCAibmFtZXNwYWNlIiwgbmFtZXNwYWNlXyk7CisgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisgIH0KKworICBwcmludGVyLT5QcmludCgKKyAgICAiLy8vIDxzdW1tYXJ5PkhvbGRlciBmb3IgcmVmbGVjdGlvbiBpbmZvcm1hdGlvbiBnZW5lcmF0ZWQgZnJvbSAkZmlsZV9uYW1lJDwvc3VtbWFyeT5cbiIKKyAgICAiW2dsb2JhbDo6U3lzdGVtLkRpYWdub3N0aWNzLkRlYnVnZ2VyTm9uVXNlckNvZGVBdHRyaWJ1dGUoKV1cbiIsCisgICAgImZpbGVfbmFtZSIsIGZpbGVfLT5uYW1lKCkpOworICBXcml0ZUdlbmVyYXRlZENvZGVBdHRyaWJ1dGVzKHByaW50ZXIpOworICBwcmludGVyLT5QcmludCgKKyAgICAiJGFjY2Vzc19sZXZlbCQgc3RhdGljIHBhcnRpYWwgY2xhc3MgJHJlZmxlY3Rpb25fY2xhc3NfbmFtZSQge1xuIgorICAgICJcbiIsCisgICAgImFjY2Vzc19sZXZlbCIsIGNsYXNzX2FjY2Vzc19sZXZlbCgpLAorICAgICJyZWZsZWN0aW9uX2NsYXNzX25hbWUiLCByZWZsZWN0aW9uQ2xhc3NuYW1lXyk7CisgIHByaW50ZXItPkluZGVudCgpOworfQorCit2b2lkIFJlZmxlY3Rpb25DbGFzc0dlbmVyYXRvcjo6V3JpdGVEZXNjcmlwdG9yKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgICIjcmVnaW9uIERlc2NyaXB0b3JcbiIKKyAgICAiLy8vIDxzdW1tYXJ5PkZpbGUgZGVzY3JpcHRvciBmb3IgJGZpbGVfbmFtZSQ8L3N1bW1hcnk+XG4iCisgICAgInB1YmxpYyBzdGF0aWMgcGJyOjpGaWxlRGVzY3JpcHRvciBEZXNjcmlwdG9yIHtcbiIKKyAgICAiICBnZXQgeyByZXR1cm4gZGVzY3JpcHRvcjsgfVxuIgorICAgICJ9XG4iCisgICAgInByaXZhdGUgc3RhdGljIHBicjo6RmlsZURlc2NyaXB0b3IgZGVzY3JpcHRvcjtcbiIKKyAgICAiXG4iCisgICAgInN0YXRpYyAkcmVmbGVjdGlvbl9jbGFzc19uYW1lJCgpIHtcbiIsCisgICAgImZpbGVfbmFtZSIsIGZpbGVfLT5uYW1lKCksCisgICAgInJlZmxlY3Rpb25fY2xhc3NfbmFtZSIsIHJlZmxlY3Rpb25DbGFzc25hbWVfKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisgIHByaW50ZXItPlByaW50KAorICAgICJieXRlW10gZGVzY3JpcHRvckRhdGEgPSBnbG9iYWw6OlN5c3RlbS5Db252ZXJ0LkZyb21CYXNlNjRTdHJpbmcoXG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisgIHByaW50ZXItPkluZGVudCgpOworICBwcmludGVyLT5QcmludCgic3RyaW5nLkNvbmNhdChcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICAvLyBUT0RPKGpvbnNrZWV0KTogQ29uc2lkZXIgYSBDIy1lc2NhcGluZyBmb3JtYXQgaGVyZSBpbnN0ZWFkIG9mIGp1c3QgQmFzZTY0LgorICBzdGQ6OnN0cmluZyBiYXNlNjQgPSBGaWxlRGVzY3JpcHRvclRvQmFzZTY0KGZpbGVfKTsKKyAgd2hpbGUgKGJhc2U2NC5zaXplKCkgPiA2MCkgeworICAgIHByaW50ZXItPlByaW50KCJcIiRiYXNlNjQkXCIsXG4iLCAiYmFzZTY0IiwgYmFzZTY0LnN1YnN0cigwLCA2MCkpOworICAgIGJhc2U2NCA9IGJhc2U2NC5zdWJzdHIoNjApOworICB9CisgIHByaW50ZXItPlByaW50KCJcIiRiYXNlNjQkXCIpKTtcbiIsICJiYXNlNjQiLCBiYXNlNjQpOworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8vIEludm9rZSBJbnRlcm5hbEJ1aWxkR2VuZXJhdGVkRmlsZUZyb20oKSB0byBidWlsZCB0aGUgZmlsZS4KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiZGVzY3JpcHRvciA9IHBicjo6RmlsZURlc2NyaXB0b3IuRnJvbUdlbmVyYXRlZENvZGUoZGVzY3JpcHRvckRhdGEsXG4iKTsKKyAgcHJpbnRlci0+UHJpbnQoIiAgICBuZXcgcGJyOjpGaWxlRGVzY3JpcHRvcltdIHsgIik7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPmRlcGVuZGVuY3lfY291bnQoKTsgaSsrKSB7CisgICAgLy8gZGVzY3JpcHRvci5wcm90byBpcyBzcGVjaWFsOiB3ZSBkb24ndCBhbGxvdyBhY2Nlc3MgdG8gdGhlIGdlbmVyYXRlZCBjb2RlLCBidXQgdGhlcmUncworICAgIC8vIGEgc2VwYXJhdGVseS1leHBvc2VkIHByb3BlcnR5IHRvIGdldCBhdCB0aGUgZmlsZSBkZXNjcmlwdG9yLCBzcGVjaWZpY2FsbHkgdG8gYWxsb3cgdGhpcworICAgIC8vIGtpbmQgb2YgZGVwZW5kZW5jeS4KKyAgICBpZiAoSXNEZXNjcmlwdG9yUHJvdG8oZmlsZV8tPmRlcGVuZGVuY3koaSkpKSB7CisgICAgICBwcmludGVyLT5QcmludCgicGJyOjpGaWxlRGVzY3JpcHRvci5EZXNjcmlwdG9yUHJvdG9GaWxlRGVzY3JpcHRvciwgIik7CisgICAgfSBlbHNlIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgIiRmdWxsX3JlZmxlY3Rpb25fY2xhc3NfbmFtZSQuRGVzY3JpcHRvciwgIiwKKyAgICAgICJmdWxsX3JlZmxlY3Rpb25fY2xhc3NfbmFtZSIsCisgICAgICBHZXRSZWZsZWN0aW9uQ2xhc3NOYW1lKGZpbGVfLT5kZXBlbmRlbmN5KGkpKSk7CisgICAgfQorICB9CisgIHByaW50ZXItPlByaW50KCJ9LFxuIgorICAgICAgIiAgICBuZXcgcGJyOjpHZW5lcmF0ZWRDbHJUeXBlSW5mbygiKTsKKyAgLy8gU3BlY2lmeSBhbGwgdGhlIGdlbmVyYXRlZCBjb2RlIGluZm9ybWF0aW9uLCByZWN1cnNpdmVseS4KKyAgaWYgKGZpbGVfLT5lbnVtX3R5cGVfY291bnQoKSA+IDApIHsKKyAgICAgIHByaW50ZXItPlByaW50KCJuZXdbXSB7Iik7CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5lbnVtX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgICAgICAgcHJpbnRlci0+UHJpbnQoInR5cGVvZigkdHlwZV9uYW1lJCksICIsICJ0eXBlX25hbWUiLCBHZXRDbGFzc05hbWUoZmlsZV8tPmVudW1fdHlwZShpKSkpOworICAgICAgfQorICAgICAgcHJpbnRlci0+UHJpbnQoIn0sICIpOworICB9CisgIGVsc2UgeworICAgICAgcHJpbnRlci0+UHJpbnQoIm51bGwsICIpOworICB9CisgIGlmIChmaWxlXy0+bWVzc2FnZV90eXBlX2NvdW50KCkgPiAwKSB7CisgICAgICBwcmludGVyLT5QcmludCgibmV3IHBicjo6R2VuZXJhdGVkQ2xyVHlwZUluZm9bXSB7XG4iKTsKKyAgICAgIHByaW50ZXItPkluZGVudCgpOworICAgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICAgICAgICBXcml0ZUdlbmVyYXRlZENvZGVJbmZvKGZpbGVfLT5tZXNzYWdlX3R5cGUoaSksIHByaW50ZXIsIGkgPT0gZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpIC0gMSk7CisgICAgICB9CisgICAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgICBwcmludGVyLT5QcmludCgiXG59KSk7XG4iKTsKKyAgICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgfQorICBlbHNlIHsKKyAgICAgIHByaW50ZXItPlByaW50KCJudWxsKSk7XG4iKTsKKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworICBwcmludGVyLT5QcmludCgiI2VuZHJlZ2lvblxuXG4iKTsKK30KKworLy8gV3JpdGUgb3V0IHRoZSBnZW5lcmF0ZWQgY29kZSBmb3IgYSBwYXJ0aWN1bGFyIG1lc3NhZ2UuIFRoaXMgY29uc2lzdHMgb2YgdGhlIENMUiB0eXBlLCBwcm9wZXJ0eSBuYW1lcworLy8gY29ycmVzcG9uZGluZyB0byBmaWVsZHMsIG5hbWVzIGNvcnJlc3BvbmRpbmcgdG8gb25lb2ZzLCBuZXN0ZWQgZW51bXMsIGFuZCBuZXN0ZWQgdHlwZXMuIEVhY2ggYXJyYXkgcGFydAorLy8gY2FuIGJlIHNwZWNpZmllZCBhcyBudWxsIGlmIGl0IHdvdWxkIGJlIGVtcHR5LCB0byBtYWtlIHRoZSBnZW5lcmF0ZWQgY29kZSBzb21ld2hhdCBzaW1wbGVyIHRvIHJlYWQuCisvLyBXZSB3cml0ZSBhIGxpbmUgYnJlYWsgYXQgdGhlIGVuZCBvZiBlYWNoIGdlbmVyYXRlZCBjb2RlIGluZm8sIHNvIHRoYXQgaW4gdGhlIGZpbmFsIGZpbGUgd2UnbGwgc2VlIGFsbAorLy8gdGhlIHR5cGVzLCBwcmUtb3JkZXJlZCBkZXB0aCBmaXJzdCwgb25lIHBlciBsaW5lLiBUaGUgaW5kZW50YXRpb24gd2lsbCBiZSBzbGlnaHRseSB1bnVzdWFsLAorLy8gaW4gdGhhdCBpdCB3aWxsIGxvb2sgbGlrZSBhIHNpbmdsZSBhcnJheSB3aGVuIGl0J3MgYWN0dWFsbHkgY29uc3RydWN0aW5nIGEgdHJlZSwgYnV0IGl0J2xsIGJlIGVhc3kgdG8KKy8vIHJlYWQgZXZlbiB3aXRoIG11bHRpcGxlIGxldmVscyBvZiBuZXN0aW5nLgorLy8gVGhlICJsYXN0IiBwYXJhbWV0ZXIgaW5kaWNhdGVzIHdoZXRoZXIgdGhpcyBtZXNzYWdlIGRlc2NyaXB0b3IgaXMgdGhlIGxhc3Qgb25lIGJlaW5nIHByaW50ZWQgaW4gdGhpcyBpbW1lZGlhdGUKKy8vIGNvbnRleHQuIEl0IGdvdmVybnMgd2hldGhlciBvciBub3QgYSB0cmFpbGluZyBjb21tYSBhbmQgbmV3bGluZSBpcyB3cml0dGVuIGFmdGVyIHRoZSBjb25zdHJ1Y3RvciwgZWZmZWN0aXZlbHkKKy8vIGp1c3QgY29udHJvbGxpbmcgdGhlIGZvcm1hdHRpbmcgaW4gdGhlIGdlbmVyYXRlZCBjb2RlLgordm9pZCBSZWZsZWN0aW9uQ2xhc3NHZW5lcmF0b3I6OldyaXRlR2VuZXJhdGVkQ29kZUluZm8oY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwgaW86OlByaW50ZXIqIHByaW50ZXIsIGJvb2wgbGFzdCkgeworICBpZiAoSXNNYXBFbnRyeU1lc3NhZ2UoZGVzY3JpcHRvcikpIHsKKyAgICBwcmludGVyLT5QcmludCgibnVsbCwgIik7CisgICAgcmV0dXJuOworICB9CisgIC8vIEdlbmVyYXRlZCBtZXNzYWdlIHR5cGUKKyAgcHJpbnRlci0+UHJpbnQoIm5ldyBwYnI6OkdlbmVyYXRlZENsclR5cGVJbmZvKHR5cGVvZigkdHlwZV9uYW1lJCksICR0eXBlX25hbWUkLlBhcnNlciwgIiwgInR5cGVfbmFtZSIsIEdldENsYXNzTmFtZShkZXNjcmlwdG9yKSk7CisgIAorICAvLyBGaWVsZHMKKyAgaWYgKGRlc2NyaXB0b3ItPmZpZWxkX2NvdW50KCkgPiAwKSB7CisgICAgICBzdGQ6OnZlY3RvcjxzdGQ6OnN0cmluZz4gZmllbGRzOworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICAgICAgICBmaWVsZHMucHVzaF9iYWNrKEdldFByb3BlcnR5TmFtZShkZXNjcmlwdG9yLT5maWVsZChpKSkpOworICAgICAgfQorICAgICAgcHJpbnRlci0+UHJpbnQoIm5ld1tdeyBcIiRmaWVsZHMkXCIgfSwgIiwgImZpZWxkcyIsIEpvaW5TdHJpbmdzKGZpZWxkcywgIlwiLCBcIiIpKTsKKyAgfQorICBlbHNlIHsKKyAgICAgIHByaW50ZXItPlByaW50KCJudWxsLCAiKTsKKyAgfQorCisgIC8vIE9uZW9mcworICBpZiAoZGVzY3JpcHRvci0+b25lb2ZfZGVjbF9jb3VudCgpID4gMCkgeworICAgICAgc3RkOjp2ZWN0b3I8c3RkOjpzdHJpbmc+IG9uZW9mczsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvci0+b25lb2ZfZGVjbF9jb3VudCgpOyBpKyspIHsKKyAgICAgICAgICBvbmVvZnMucHVzaF9iYWNrKFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoZGVzY3JpcHRvci0+b25lb2ZfZGVjbChpKS0+bmFtZSgpLCB0cnVlKSk7CisgICAgICB9CisgICAgICBwcmludGVyLT5QcmludCgibmV3W117IFwiJG9uZW9mcyRcIiB9LCAiLCAib25lb2ZzIiwgSm9pblN0cmluZ3Mob25lb2ZzLCAiXCIsIFwiIikpOworICB9CisgIGVsc2UgeworICAgICAgcHJpbnRlci0+UHJpbnQoIm51bGwsICIpOworICB9CisKKyAgLy8gTmVzdGVkIGVudW1zCisgIGlmIChkZXNjcmlwdG9yLT5lbnVtX3R5cGVfY291bnQoKSA+IDApIHsKKyAgICAgIHN0ZDo6dmVjdG9yPHN0ZDo6c3RyaW5nPiBlbnVtczsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvci0+ZW51bV90eXBlX2NvdW50KCk7IGkrKykgeworICAgICAgICAgIGVudW1zLnB1c2hfYmFjayhHZXRDbGFzc05hbWUoZGVzY3JpcHRvci0+ZW51bV90eXBlKGkpKSk7CisgICAgICB9CisgICAgICBwcmludGVyLT5QcmludCgibmV3W117IHR5cGVvZigkZW51bXMkKSB9LCAiLCAiZW51bXMiLCBKb2luU3RyaW5ncyhlbnVtcywgIiksIHR5cGVvZigiKSk7CisgIH0KKyAgZWxzZSB7CisgICAgICBwcmludGVyLT5QcmludCgibnVsbCwgIik7CisgIH0KKworICAvLyBOZXN0ZWQgdHlwZXMKKyAgaWYgKGRlc2NyaXB0b3ItPm5lc3RlZF90eXBlX2NvdW50KCkgPiAwKSB7CisgICAgICAvLyBOZWVkIHRvIHNwZWNpZnkgYXJyYXkgdHlwZSBleHBsaWNpdGx5IGhlcmUsIGFzIGFsbCBlbGVtZW50cyBtYXkgYmUgbnVsbC4gCisgICAgICBwcmludGVyLT5QcmludCgibmV3IHBicjo6R2VuZXJhdGVkQ2xyVHlwZUluZm9bXSB7ICIpOworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yLT5uZXN0ZWRfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICAgICAgICBXcml0ZUdlbmVyYXRlZENvZGVJbmZvKGRlc2NyaXB0b3ItPm5lc3RlZF90eXBlKGkpLCBwcmludGVyLCBpID09IGRlc2NyaXB0b3ItPm5lc3RlZF90eXBlX2NvdW50KCkgLSAxKTsKKyAgICAgIH0KKyAgICAgIHByaW50ZXItPlByaW50KCJ9Iik7CisgIH0KKyAgZWxzZSB7CisgICAgICBwcmludGVyLT5QcmludCgibnVsbCIpOworICB9CisgIHByaW50ZXItPlByaW50KGxhc3QgPyAiKSIgOiAiKSxcbiIpOworfQorCit9ICAvLyBuYW1lc3BhY2UgY3NoYXJwCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX3JlZmxlY3Rpb25fY2xhc3MuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9yZWZsZWN0aW9uX2NsYXNzLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGE1YjhlZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9yZWZsZWN0aW9uX2NsYXNzLmgKQEAgLTAsMCArMSw2OSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NTSEFSUF9SRUZMRUNUSU9OX0NMQVNTX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1NIQVJQX1JFRkxFQ1RJT05fQ0xBU1NfSF9fCisKKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY29kZV9nZW5lcmF0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9zb3VyY2VfZ2VuZXJhdG9yX2Jhc2UuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBjc2hhcnAgeworCitjbGFzcyBSZWZsZWN0aW9uQ2xhc3NHZW5lcmF0b3IgOiBwdWJsaWMgU291cmNlR2VuZXJhdG9yQmFzZSB7CisgcHVibGljOgorICBSZWZsZWN0aW9uQ2xhc3NHZW5lcmF0b3IoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUpOworICB+UmVmbGVjdGlvbkNsYXNzR2VuZXJhdG9yKCk7CisKKyAgdm9pZCBHZW5lcmF0ZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyBwcml2YXRlOgorICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZV87CisKKyAgc3RkOjpzdHJpbmcgbmFtZXNwYWNlXzsKKyAgc3RkOjpzdHJpbmcgcmVmbGVjdGlvbkNsYXNzbmFtZV87CisKKyAgdm9pZCBXcml0ZUludHJvZHVjdGlvbihpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZvaWQgV3JpdGVEZXNjcmlwdG9yKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdm9pZCBXcml0ZUdlbmVyYXRlZENvZGVJbmZvKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGlvOjpQcmludGVyKiBwcmludGVyLCBib29sIGxhc3QpOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhSZWZsZWN0aW9uQ2xhc3NHZW5lcmF0b3IpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGNzaGFycAorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1NIQVJQX1JFRkxFQ1RJT05fQ0xBU1NfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfcmVwZWF0ZWRfZW51bV9maWVsZC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9yZXBlYXRlZF9lbnVtX2ZpZWxkLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNhMTFiNzUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfcmVwZWF0ZWRfZW51bV9maWVsZC5jYwpAQCAtMCwwICsxLDEyNyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlIDxzc3RyZWFtPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvZGVfZ2VuZXJhdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BsdWdpbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0Lmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9kb2NfY29tbWVudC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9yZXBlYXRlZF9lbnVtX2ZpZWxkLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgY3NoYXJwIHsKKworUmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3I6OlJlcGVhdGVkRW51bUZpZWxkR2VuZXJhdG9yKAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwgaW50IGZpZWxkT3JkaW5hbCkKKyAgICA6IEZpZWxkR2VuZXJhdG9yQmFzZShkZXNjcmlwdG9yLCBmaWVsZE9yZGluYWwpIHsKK30KKworUmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3I6On5SZXBlYXRlZEVudW1GaWVsZEdlbmVyYXRvcigpIHsKKworfQorCit2b2lkIFJlcGVhdGVkRW51bUZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgdmFyaWFibGVzXywKKyAgICAicHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgcGI6OkZpZWxkQ29kZWM8JHR5cGVfbmFtZSQ+IF9yZXBlYXRlZF8kbmFtZSRfY29kZWNcbiIKKyAgICAiICAgID0gcGI6OkZpZWxkQ29kZWMuRm9yRW51bSgkdGFnJCwgeCA9PiAoaW50KSB4LCB4ID0+ICgkdHlwZV9uYW1lJCkgeCk7XG4iKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHJpdmF0ZSByZWFkb25seSBwYmM6OlJlcGVhdGVkRmllbGQ8JHR5cGVfbmFtZSQ+ICRuYW1lJF8gPSBuZXcgcGJjOjpSZXBlYXRlZEZpZWxkPCR0eXBlX25hbWUkPigpO1xuIik7CisgIFdyaXRlUHJvcGVydHlEb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgQWRkRGVwcmVjYXRlZEZsYWcocHJpbnRlcik7CisgIHByaW50ZXItPlByaW50KAorICAgIHZhcmlhYmxlc18sCisgICAgIiRhY2Nlc3NfbGV2ZWwkIHBiYzo6UmVwZWF0ZWRGaWVsZDwkdHlwZV9uYW1lJD4gJHByb3BlcnR5X25hbWUkIHtcbiIKKyAgICAiICBnZXQgeyByZXR1cm4gJG5hbWUkXzsgfVxuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEVudW1GaWVsZEdlbmVyYXRvcjo6R2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICB2YXJpYWJsZXNfLAorICAgICIkbmFtZSRfLkFkZChvdGhlci4kbmFtZSRfKTtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkRW51bUZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZVBhcnNpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgIHZhcmlhYmxlc18sCisgICAgIiRuYW1lJF8uQWRkRW50cmllc0Zyb20oaW5wdXQsIF9yZXBlYXRlZF8kbmFtZSRfY29kZWMpO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgdmFyaWFibGVzXywKKyAgICAiJG5hbWUkXy5Xcml0ZVRvKG91dHB1dCwgX3JlcGVhdGVkXyRuYW1lJF9jb2RlYyk7XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEVudW1GaWVsZEdlbmVyYXRvcjo6R2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsgIAorICBwcmludGVyLT5QcmludCgKKyAgICB2YXJpYWJsZXNfLAorICAgICJzaXplICs9ICRuYW1lJF8uQ2FsY3VsYXRlU2l6ZShfcmVwZWF0ZWRfJG5hbWUkX2NvZGVjKTtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkRW51bUZpZWxkR2VuZXJhdG9yOjpXcml0ZUhhc2goaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgdmFyaWFibGVzXywKKyAgICAiaGFzaCBePSAkbmFtZSRfLkdldEhhc2hDb2RlKCk7XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEVudW1GaWVsZEdlbmVyYXRvcjo6V3JpdGVFcXVhbHMoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgdmFyaWFibGVzXywKKyAgICAiaWYoISRuYW1lJF8uRXF1YWxzKG90aGVyLiRuYW1lJF8pKSByZXR1cm4gZmFsc2U7XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEVudW1GaWVsZEdlbmVyYXRvcjo6V3JpdGVUb1N0cmluZyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJQcmludEZpZWxkKFwiJGRlc2NyaXB0b3JfbmFtZSRcIiwgJG5hbWUkXywgd3JpdGVyKTtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkRW51bUZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZUNsb25pbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRuYW1lJF8gPSBvdGhlci4kbmFtZSRfLkNsb25lKCk7XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEVudW1GaWVsZEdlbmVyYXRvcjo6R2VuZXJhdGVGcmVlemluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKK30KKworfSAgLy8gbmFtZXNwYWNlIGNzaGFycAorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9yZXBlYXRlZF9lbnVtX2ZpZWxkLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfcmVwZWF0ZWRfZW51bV9maWVsZC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVlNTBlZWYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfcmVwZWF0ZWRfZW51bV9maWVsZC5oCkBAIC0wLDAgKzEsNzMgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DU0hBUlBfUkVQRUFURURfRU5VTV9GSUVMRF9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NTSEFSUF9SRVBFQVRFRF9FTlVNX0ZJRUxEX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvZGVfZ2VuZXJhdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfZmllbGRfYmFzZS5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGNzaGFycCB7CisKKy8vIFRPRE8oam9uc2tlZXQpOiBSZWZhY3RvciByZXBlYXRlZCBmaWVsZCBzdXBwb3J0OyBhbGwgdGhlIGltcGxlbWVudGF0aW9ucyBhcmUgKnJlYWxseSogc2ltaWxhci4gV2UKKy8vIHNob3VsZCBwcm9iYWJseSBoYXZlIGEgUmVwZWF0ZWRGaWVsZEdlbmVyYXRvckJhc2UuCitjbGFzcyBSZXBlYXRlZEVudW1GaWVsZEdlbmVyYXRvciA6IHB1YmxpYyBGaWVsZEdlbmVyYXRvckJhc2UgeworIHB1YmxpYzoKKyAgUmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBpbnQgZmllbGRPcmRpbmFsKTsKKyAgflJlcGVhdGVkRW51bUZpZWxkR2VuZXJhdG9yKCk7CisKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlQ2xvbmluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVGcmVlemluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVQYXJzaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworICB2aXJ0dWFsIHZvaWQgV3JpdGVIYXNoKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdmlydHVhbCB2b2lkIFdyaXRlRXF1YWxzKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdmlydHVhbCB2b2lkIFdyaXRlVG9TdHJpbmcoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFJlcGVhdGVkRW51bUZpZWxkR2VuZXJhdG9yKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBjc2hhcnAKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NTSEFSUF9SRVBFQVRFRF9FTlVNX0ZJRUxEX0hfXworCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfcmVwZWF0ZWRfbWVzc2FnZV9maWVsZC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9yZXBlYXRlZF9tZXNzYWdlX2ZpZWxkLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZjMTJmYWUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfcmVwZWF0ZWRfbWVzc2FnZV9maWVsZC5jYwpAQCAtMCwwICsxLDE0MiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlIDxzc3RyZWFtPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvZGVfZ2VuZXJhdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BsdWdpbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9kb2NfY29tbWVudC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9yZXBlYXRlZF9tZXNzYWdlX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfbWVzc2FnZV9maWVsZC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX3dyYXBwZXJfZmllbGQuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBjc2hhcnAgeworCitSZXBlYXRlZE1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6UmVwZWF0ZWRNZXNzYWdlRmllbGRHZW5lcmF0b3IoCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBpbnQgZmllbGRPcmRpbmFsKQorICAgIDogRmllbGRHZW5lcmF0b3JCYXNlKGRlc2NyaXB0b3IsIGZpZWxkT3JkaW5hbCkgeworfQorCitSZXBlYXRlZE1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6flJlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yKCkgeworCit9CisKK3ZvaWQgUmVwZWF0ZWRNZXNzYWdlRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICB2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIHN0YXRpYyByZWFkb25seSBwYjo6RmllbGRDb2RlYzwkdHlwZV9uYW1lJD4gX3JlcGVhdGVkXyRuYW1lJF9jb2RlY1xuIgorICAgICIgICAgPSAiKTsKKyAgLy8gRG9uJ3Qgd2FudCB0byBkdXBsaWNhdGUgdGhlIGNvZGVjIGNvZGUgaGVyZS4uLiBtYXliZSB3ZSBzaG91bGQgaGF2ZSBhCisgIC8vICJjcmVhdGUgc2luZ2xlIGZpZWxkIGdlbmVyYXRvciBmb3IgdGhpcyByZXBlYXRlZCBmaWVsZCIKKyAgLy8gZnVuY3Rpb24sIGJ1dCBpdCBkb2Vzbid0IHNlZW0gd29ydGggaXQgZm9yIGp1c3QgdGhpcy4KKyAgaWYgKElzV3JhcHBlclR5cGUoZGVzY3JpcHRvcl8pKSB7CisgICAgc2NvcGVkX3B0cjxGaWVsZEdlbmVyYXRvckJhc2U+IHNpbmdsZV9nZW5lcmF0b3IobmV3IFdyYXBwZXJGaWVsZEdlbmVyYXRvcihkZXNjcmlwdG9yXywgZmllbGRPcmRpbmFsXykpOworICAgIHNpbmdsZV9nZW5lcmF0b3ItPkdlbmVyYXRlQ29kZWNDb2RlKHByaW50ZXIpOworICB9IGVsc2UgeworICAgIHNjb3BlZF9wdHI8RmllbGRHZW5lcmF0b3JCYXNlPiBzaW5nbGVfZ2VuZXJhdG9yKG5ldyBNZXNzYWdlRmllbGRHZW5lcmF0b3IoZGVzY3JpcHRvcl8sIGZpZWxkT3JkaW5hbF8pKTsKKyAgICBzaW5nbGVfZ2VuZXJhdG9yLT5HZW5lcmF0ZUNvZGVjQ29kZShwcmludGVyKTsKKyAgfQorICBwcmludGVyLT5QcmludCgiO1xuIik7CisgIHByaW50ZXItPlByaW50KAorICAgIHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgcmVhZG9ubHkgcGJjOjpSZXBlYXRlZEZpZWxkPCR0eXBlX25hbWUkPiAkbmFtZSRfID0gbmV3IHBiYzo6UmVwZWF0ZWRGaWVsZDwkdHlwZV9uYW1lJD4oKTtcbiIpOworICBXcml0ZVByb3BlcnR5RG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIEFkZERlcHJlY2F0ZWRGbGFnKHByaW50ZXIpOworICBwcmludGVyLT5QcmludCgKKyAgICB2YXJpYWJsZXNfLAorICAgICIkYWNjZXNzX2xldmVsJCBwYmM6OlJlcGVhdGVkRmllbGQ8JHR5cGVfbmFtZSQ+ICRwcm9wZXJ0eV9uYW1lJCB7XG4iCisgICAgIiAgZ2V0IHsgcmV0dXJuICRuYW1lJF87IH1cbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRNZXNzYWdlRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgdmFyaWFibGVzXywKKyAgICAiJG5hbWUkXy5BZGQob3RoZXIuJG5hbWUkXyk7XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZE1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6R2VuZXJhdGVQYXJzaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICB2YXJpYWJsZXNfLAorICAgICIkbmFtZSRfLkFkZEVudHJpZXNGcm9tKGlucHV0LCBfcmVwZWF0ZWRfJG5hbWUkX2NvZGVjKTtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgIHZhcmlhYmxlc18sCisgICAgIiRuYW1lJF8uV3JpdGVUbyhvdXRwdXQsIF9yZXBlYXRlZF8kbmFtZSRfY29kZWMpO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRNZXNzYWdlRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgIHZhcmlhYmxlc18sCisgICAgInNpemUgKz0gJG5hbWUkXy5DYWxjdWxhdGVTaXplKF9yZXBlYXRlZF8kbmFtZSRfY29kZWMpO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRNZXNzYWdlRmllbGRHZW5lcmF0b3I6OldyaXRlSGFzaChpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICB2YXJpYWJsZXNfLAorICAgICJoYXNoIF49ICRuYW1lJF8uR2V0SGFzaENvZGUoKTtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjpXcml0ZUVxdWFscyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICB2YXJpYWJsZXNfLAorICAgICJpZighJG5hbWUkXy5FcXVhbHMob3RoZXIuJG5hbWUkXykpIHJldHVybiBmYWxzZTtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjpXcml0ZVRvU3RyaW5nKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHZhcmlhYmxlc19bImZpZWxkX25hbWUiXSA9IEdldEZpZWxkTmFtZShkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KAorICAgIHZhcmlhYmxlc18sCisgICAgIlByaW50RmllbGQoXCIkZmllbGRfbmFtZSRcIiwgJG5hbWUkXywgd3JpdGVyKTtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZUNsb25pbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRuYW1lJF8gPSBvdGhlci4kbmFtZSRfLkNsb25lKCk7XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZE1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6R2VuZXJhdGVGcmVlemluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKK30KKworfSAgLy8gbmFtZXNwYWNlIGNzaGFycAorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9yZXBlYXRlZF9tZXNzYWdlX2ZpZWxkLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfcmVwZWF0ZWRfbWVzc2FnZV9maWVsZC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNmNjAxYzcKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfcmVwZWF0ZWRfbWVzc2FnZV9maWVsZC5oCkBAIC0wLDAgKzEsNzEgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DU0hBUlBfUkVQRUFURURfTUVTU0FHRV9GSUVMRF9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NTSEFSUF9SRVBFQVRFRF9NRVNTQUdFX0ZJRUxEX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvZGVfZ2VuZXJhdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfZmllbGRfYmFzZS5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGNzaGFycCB7CisKK2NsYXNzIFJlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yIDogcHVibGljIEZpZWxkR2VuZXJhdG9yQmFzZSB7CisgcHVibGljOgorICBSZXBlYXRlZE1lc3NhZ2VGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGludCBmaWVsZE9yZGluYWwpOworICB+UmVwZWF0ZWRNZXNzYWdlRmllbGRHZW5lcmF0b3IoKTsKKworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVDbG9uaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZUZyZWV6aW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZVBhcnNpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIHZpcnR1YWwgdm9pZCBXcml0ZUhhc2goaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2aXJ0dWFsIHZvaWQgV3JpdGVFcXVhbHMoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2aXJ0dWFsIHZvaWQgV3JpdGVUb1N0cmluZyhpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoUmVwZWF0ZWRNZXNzYWdlRmllbGRHZW5lcmF0b3IpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGNzaGFycAorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1NIQVJQX1JFUEVBVEVEX01FU1NBR0VfRklFTERfSF9fCisKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9yZXBlYXRlZF9wcmltaXRpdmVfZmllbGQuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfcmVwZWF0ZWRfcHJpbWl0aXZlX2ZpZWxkLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVmZTBiMjAKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfcmVwZWF0ZWRfcHJpbWl0aXZlX2ZpZWxkLmNjCkBAIC0wLDAgKzEsMTI1IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2luY2x1ZGUgPHNzdHJlYW0+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY29kZV9nZW5lcmF0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuaD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX2RvY19jb21tZW50Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfaGVscGVycy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX3JlcGVhdGVkX3ByaW1pdGl2ZV9maWVsZC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGNzaGFycCB7CisKK1JlcGVhdGVkUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OlJlcGVhdGVkUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IoCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBpbnQgZmllbGRPcmRpbmFsKQorICAgIDogRmllbGRHZW5lcmF0b3JCYXNlKGRlc2NyaXB0b3IsIGZpZWxkT3JkaW5hbCkgeworfQorCitSZXBlYXRlZFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjp+UmVwZWF0ZWRQcmltaXRpdmVGaWVsZEdlbmVyYXRvcigpIHsKKworfQorCit2b2lkIFJlcGVhdGVkUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICB2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIHN0YXRpYyByZWFkb25seSBwYjo6RmllbGRDb2RlYzwkdHlwZV9uYW1lJD4gX3JlcGVhdGVkXyRuYW1lJF9jb2RlY1xuIgorICAgICIgICAgPSBwYjo6RmllbGRDb2RlYy5Gb3IkY2FwaXRhbGl6ZWRfdHlwZV9uYW1lJCgkdGFnJCk7XG4iKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHJpdmF0ZSByZWFkb25seSBwYmM6OlJlcGVhdGVkRmllbGQ8JHR5cGVfbmFtZSQ+ICRuYW1lJF8gPSBuZXcgcGJjOjpSZXBlYXRlZEZpZWxkPCR0eXBlX25hbWUkPigpO1xuIik7CisgIFdyaXRlUHJvcGVydHlEb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgQWRkRGVwcmVjYXRlZEZsYWcocHJpbnRlcik7CisgIHByaW50ZXItPlByaW50KAorICAgIHZhcmlhYmxlc18sCisgICAgIiRhY2Nlc3NfbGV2ZWwkIHBiYzo6UmVwZWF0ZWRGaWVsZDwkdHlwZV9uYW1lJD4gJHByb3BlcnR5X25hbWUkIHtcbiIKKyAgICAiICBnZXQgeyByZXR1cm4gJG5hbWUkXzsgfVxuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgIHZhcmlhYmxlc18sCisgICAgIiRuYW1lJF8uQWRkKG90aGVyLiRuYW1lJF8pO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6R2VuZXJhdGVQYXJzaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICB2YXJpYWJsZXNfLAorICAgICIkbmFtZSRfLkFkZEVudHJpZXNGcm9tKGlucHV0LCBfcmVwZWF0ZWRfJG5hbWUkX2NvZGVjKTtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgdmFyaWFibGVzXywKKyAgICAiJG5hbWUkXy5Xcml0ZVRvKG91dHB1dCwgX3JlcGVhdGVkXyRuYW1lJF9jb2RlYyk7XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICB2YXJpYWJsZXNfLAorICAgICJzaXplICs9ICRuYW1lJF8uQ2FsY3VsYXRlU2l6ZShfcmVwZWF0ZWRfJG5hbWUkX2NvZGVjKTtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OldyaXRlSGFzaChpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICB2YXJpYWJsZXNfLAorICAgICJoYXNoIF49ICRuYW1lJF8uR2V0SGFzaENvZGUoKTtcbiIpOworfQordm9pZCBSZXBlYXRlZFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjpXcml0ZUVxdWFscyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICB2YXJpYWJsZXNfLAorICAgICJpZighJG5hbWUkXy5FcXVhbHMob3RoZXIuJG5hbWUkXykpIHJldHVybiBmYWxzZTtcbiIpOworfQordm9pZCBSZXBlYXRlZFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjpXcml0ZVRvU3RyaW5nKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIlByaW50RmllbGQoXCIkZGVzY3JpcHRvcl9uYW1lJFwiLCAkbmFtZSRfLCB3cml0ZXIpO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6R2VuZXJhdGVDbG9uaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkbmFtZSRfID0gb3RoZXIuJG5hbWUkXy5DbG9uZSgpO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6R2VuZXJhdGVGcmVlemluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKK30KKworfSAgLy8gbmFtZXNwYWNlIGNzaGFycAorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9yZXBlYXRlZF9wcmltaXRpdmVfZmllbGQuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9yZXBlYXRlZF9wcmltaXRpdmVfZmllbGQuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMWNlZWI1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX3JlcGVhdGVkX3ByaW1pdGl2ZV9maWVsZC5oCkBAIC0wLDAgKzEsNzEgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DU0hBUlBfUkVQRUFURURfUFJJTUlUSVZFX0ZJRUxEX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1NIQVJQX1JFUEVBVEVEX1BSSU1JVElWRV9GSUVMRF9IX18KKworI2luY2x1ZGUgPHN0cmluZz4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jb2RlX2dlbmVyYXRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX2ZpZWxkX2Jhc2UuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBjc2hhcnAgeworCitjbGFzcyBSZXBlYXRlZFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yIDogcHVibGljIEZpZWxkR2VuZXJhdG9yQmFzZSB7CisgcHVibGljOgorICBSZXBlYXRlZFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwgaW50IGZpZWxkT3JkaW5hbCk7CisgIH5SZXBlYXRlZFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKCk7CisKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlQ2xvbmluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVGcmVlemluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVQYXJzaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworICB2aXJ0dWFsIHZvaWQgV3JpdGVIYXNoKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdmlydHVhbCB2b2lkIFdyaXRlRXF1YWxzKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdmlydHVhbCB2b2lkIFdyaXRlVG9TdHJpbmcoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFJlcGVhdGVkUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGNzaGFycAorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1NIQVJQX1JFUEVBVEVEX1BSSU1JVElWRV9GSUVMRF9IX18KKwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX3NvdXJjZV9nZW5lcmF0b3JfYmFzZS5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9zb3VyY2VfZ2VuZXJhdG9yX2Jhc2UuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzM1ZDE2NAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9zb3VyY2VfZ2VuZXJhdG9yX2Jhc2UuY2MKQEAgLTAsMCArMSw2NiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlIDxzc3RyZWFtPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvZGVfZ2VuZXJhdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BsdWdpbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9zb3VyY2VfZ2VuZXJhdG9yX2Jhc2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9oZWxwZXJzLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgY3NoYXJwIHsKKworU291cmNlR2VuZXJhdG9yQmFzZTo6U291cmNlR2VuZXJhdG9yQmFzZShjb25zdCBGaWxlRGVzY3JpcHRvciogZGVzY3JpcHRvcikKKyAgICA6IGRlc2NyaXB0b3JfKGRlc2NyaXB0b3IpIHsKK30KKworU291cmNlR2VuZXJhdG9yQmFzZTo6flNvdXJjZUdlbmVyYXRvckJhc2UoKSB7Cit9CisKK3ZvaWQgU291cmNlR2VuZXJhdG9yQmFzZTo6V3JpdGVHZW5lcmF0ZWRDb2RlQXR0cmlidXRlcyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICAvLyBUaGlzIGhvb2sgY2FuIGJlIHVzZWQgdG8gcmVpbnRyb2R1Y2UgZ2VuZXJhdGVkIGNvZGUgYXR0cmlidXRlcyBpbiB0aGUgZnV0dXJlLgorfQorCitzdGQ6OnN0cmluZyBTb3VyY2VHZW5lcmF0b3JCYXNlOjpjbGFzc19hY2Nlc3NfbGV2ZWwoKSB7CisgIHJldHVybiBJc0Rlc2NyaXB0b3JQcm90byhkZXNjcmlwdG9yXykgPyAiaW50ZXJuYWwiIDogInB1YmxpYyI7ICAvLyBwdWJsaWNfY2xhc3NlcyBpcyBhbHdheXMgb24uCit9CisKK30gIC8vIG5hbWVzcGFjZSBjc2hhcnAKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfc291cmNlX2dlbmVyYXRvcl9iYXNlLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfc291cmNlX2dlbmVyYXRvcl9iYXNlLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmNhZWYxNwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9zb3VyY2VfZ2VuZXJhdG9yX2Jhc2UuaApAQCAtMCwwICsxLDY0IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1NIQVJQX1NPVVJDRV9HRU5FUkFUT1JfQkFTRV9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NTSEFSUF9TT1VSQ0VfR0VORVJBVE9SX0JBU0VfSF9fCisKKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY29kZV9nZW5lcmF0b3IuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBjc2hhcnAgeworCitjbGFzcyBTb3VyY2VHZW5lcmF0b3JCYXNlIHsKKyBwcm90ZWN0ZWQ6CisgIFNvdXJjZUdlbmVyYXRvckJhc2UoY29uc3QgRmlsZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworICB2aXJ0dWFsIH5Tb3VyY2VHZW5lcmF0b3JCYXNlKCk7CisKKyAgc3RkOjpzdHJpbmcgY2xhc3NfYWNjZXNzX2xldmVsKCk7CisKKyAgdm9pZCBXcml0ZUdlbmVyYXRlZENvZGVBdHRyaWJ1dGVzKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworIHByaXZhdGU6CisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoU291cmNlR2VuZXJhdG9yQmFzZSk7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgY3NoYXJwCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9DU0hBUlBfU09VUkNFX0dFTkVSQVRPUl9CQVNFX0hfXworCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfd3JhcHBlcl9maWVsZC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF93cmFwcGVyX2ZpZWxkLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZhMzc1MGUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NzaGFycC9jc2hhcnBfd3JhcHBlcl9maWVsZC5jYwpAQCAtMCwwICsxLDIxMCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlIDxzc3RyZWFtPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvZGVfZ2VuZXJhdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BsdWdpbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9kb2NfY29tbWVudC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF93cmFwcGVyX2ZpZWxkLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgY3NoYXJwIHsKKworV3JhcHBlckZpZWxkR2VuZXJhdG9yOjpXcmFwcGVyRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGZpZWxkT3JkaW5hbCkKKyAgICA6IEZpZWxkR2VuZXJhdG9yQmFzZShkZXNjcmlwdG9yLCBmaWVsZE9yZGluYWwpIHsKKyAgdmFyaWFibGVzX1siaGFzX3Byb3BlcnR5X2NoZWNrIl0gPSBuYW1lKCkgKyAiXyAhPSBudWxsIjsKKyAgdmFyaWFibGVzX1siaGFzX25vdF9wcm9wZXJ0eV9jaGVjayJdID0gbmFtZSgpICsgIl8gPT0gbnVsbCI7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogd3JhcHBlZF9maWVsZCA9IGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpLT5maWVsZCgwKTsKKyAgaXNfdmFsdWVfdHlwZSA9IHdyYXBwZWRfZmllbGQtPnR5cGUoKSAhPSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU1RSSU5HICYmCisgICAgICB3cmFwcGVkX2ZpZWxkLT50eXBlKCkgIT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX0JZVEVTOworICBpZiAoaXNfdmFsdWVfdHlwZSkgeworICAgIHZhcmlhYmxlc19bIm5vbm51bGxhYmxlX3R5cGVfbmFtZSJdID0gdHlwZV9uYW1lKHdyYXBwZWRfZmllbGQpOworICB9Cit9CisKK1dyYXBwZXJGaWVsZEdlbmVyYXRvcjo6fldyYXBwZXJGaWVsZEdlbmVyYXRvcigpIHsKK30KKwordm9pZCBXcmFwcGVyRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICAgICAgdmFyaWFibGVzXywKKyAgICAgICAgInByaXZhdGUgc3RhdGljIHJlYWRvbmx5IHBiOjpGaWVsZENvZGVjPCR0eXBlX25hbWUkPiBfc2luZ2xlXyRuYW1lJF9jb2RlYyA9ICIpOworICBHZW5lcmF0ZUNvZGVjQ29kZShwcmludGVyKTsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgdmFyaWFibGVzXywKKyAgICAiO1xuIgorICAgICJwcml2YXRlICR0eXBlX25hbWUkICRuYW1lJF87XG4iKTsKKyAgV3JpdGVQcm9wZXJ0eURvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBBZGREZXByZWNhdGVkRmxhZyhwcmludGVyKTsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgdmFyaWFibGVzXywKKyAgICAiJGFjY2Vzc19sZXZlbCQgJHR5cGVfbmFtZSQgJHByb3BlcnR5X25hbWUkIHtcbiIKKyAgICAiICBnZXQgeyByZXR1cm4gJG5hbWUkXzsgfVxuIgorICAgICIgIHNldCB7XG4iCisgICAgIiAgICAkbmFtZSRfID0gdmFsdWU7XG4iCisgICAgIiAgfVxuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBXcmFwcGVyRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgdmFyaWFibGVzXywKKyAgICAiaWYgKG90aGVyLiRoYXNfcHJvcGVydHlfY2hlY2skKSB7XG4iCisgICAgIiAgaWYgKCRoYXNfbm90X3Byb3BlcnR5X2NoZWNrJCB8fCBvdGhlci4kcHJvcGVydHlfbmFtZSQgIT0gJGRlZmF1bHRfdmFsdWUkKSB7XG4iCisgICAgIiAgICAkcHJvcGVydHlfbmFtZSQgPSBvdGhlci4kcHJvcGVydHlfbmFtZSQ7XG4iCisgICAgIiAgfVxuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBXcmFwcGVyRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgdmFyaWFibGVzXywKKyAgICAiJHR5cGVfbmFtZSQgdmFsdWUgPSBfc2luZ2xlXyRuYW1lJF9jb2RlYy5SZWFkKGlucHV0KTtcbiIKKyAgICAiaWYgKCRoYXNfbm90X3Byb3BlcnR5X2NoZWNrJCB8fCB2YWx1ZSAhPSAkZGVmYXVsdF92YWx1ZSQpIHtcbiIKKyAgICAiICAkcHJvcGVydHlfbmFtZSQgPSB2YWx1ZTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgV3JhcHBlckZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgIHZhcmlhYmxlc18sCisgICAgImlmICgkaGFzX3Byb3BlcnR5X2NoZWNrJCkge1xuIgorICAgICIgIF9zaW5nbGVfJG5hbWUkX2NvZGVjLldyaXRlVGFnQW5kVmFsdWUob3V0cHV0LCAkcHJvcGVydHlfbmFtZSQpO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBXcmFwcGVyRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgIHZhcmlhYmxlc18sCisgICAgImlmICgkaGFzX3Byb3BlcnR5X2NoZWNrJCkge1xuIgorICAgICIgIHNpemUgKz0gX3NpbmdsZV8kbmFtZSRfY29kZWMuQ2FsY3VsYXRlU2l6ZVdpdGhUYWcoJHByb3BlcnR5X25hbWUkKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgV3JhcHBlckZpZWxkR2VuZXJhdG9yOjpXcml0ZUhhc2goaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgdmFyaWFibGVzXywKKyAgICAiaWYgKCRoYXNfcHJvcGVydHlfY2hlY2skKSBoYXNoIF49ICRwcm9wZXJ0eV9uYW1lJC5HZXRIYXNoQ29kZSgpO1xuIik7Cit9CisKK3ZvaWQgV3JhcHBlckZpZWxkR2VuZXJhdG9yOjpXcml0ZUVxdWFscyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICB2YXJpYWJsZXNfLAorICAgICJpZiAoJHByb3BlcnR5X25hbWUkICE9IG90aGVyLiRwcm9wZXJ0eV9uYW1lJCkgcmV0dXJuIGZhbHNlO1xuIik7Cit9CisKK3ZvaWQgV3JhcHBlckZpZWxkR2VuZXJhdG9yOjpXcml0ZVRvU3RyaW5nKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIC8vIFRPRE86IEltcGxlbWVudCBpZiB3ZSBldmVyIGFjdHVhbGx5IG5lZWQgaXQuLi4KK30KKwordm9pZCBXcmFwcGVyRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlQ2xvbmluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJHByb3BlcnR5X25hbWUkID0gb3RoZXIuJHByb3BlcnR5X25hbWUkO1xuIik7Cit9CisKK3ZvaWQgV3JhcHBlckZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZUNvZGVjQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBpZiAoaXNfdmFsdWVfdHlwZSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgdmFyaWFibGVzXywKKyAgICAgICJwYjo6RmllbGRDb2RlYy5Gb3JTdHJ1Y3RXcmFwcGVyPCRub25udWxsYWJsZV90eXBlX25hbWUkPigkdGFnJCkiKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgIHZhcmlhYmxlc18sCisgICAgICAicGI6OkZpZWxkQ29kZWMuRm9yQ2xhc3NXcmFwcGVyPCR0eXBlX25hbWUkPigkdGFnJCkiKTsKKyAgfQorfQorCitXcmFwcGVyT25lb2ZGaWVsZEdlbmVyYXRvcjo6V3JhcHBlck9uZW9mRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgIGludCBmaWVsZE9yZGluYWwpCisgICAgOiBXcmFwcGVyRmllbGRHZW5lcmF0b3IoZGVzY3JpcHRvciwgZmllbGRPcmRpbmFsKSB7CisgICAgU2V0Q29tbW9uT25lb2ZGaWVsZFZhcmlhYmxlcygmdmFyaWFibGVzXyk7Cit9CisKK1dyYXBwZXJPbmVvZkZpZWxkR2VuZXJhdG9yOjp+V3JhcHBlck9uZW9mRmllbGRHZW5lcmF0b3IoKSB7Cit9CisKK3ZvaWQgV3JhcHBlck9uZW9mRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICAvLyBOb3RlOiBkZWxpYmVyYXRlbHkgX29uZW9mXyRuYW1lJF9jb2RlYywgbm90IF8kb25lb2ZfbmFtZSRfY29kZWMuLi4gd2UgaGF2ZSBvbmUgY29kZWMgcGVyIGZpZWxkLgorICBwcmludGVyLT5QcmludCgKKyAgICAgICAgdmFyaWFibGVzXywKKyAgICAgICAgInByaXZhdGUgc3RhdGljIHJlYWRvbmx5IHBiOjpGaWVsZENvZGVjPCR0eXBlX25hbWUkPiBfb25lb2ZfJG5hbWUkX2NvZGVjID0gIik7CisgIEdlbmVyYXRlQ29kZWNDb2RlKHByaW50ZXIpOworICBwcmludGVyLT5QcmludCgiO1xuIik7CisgIFdyaXRlUHJvcGVydHlEb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgQWRkRGVwcmVjYXRlZEZsYWcocHJpbnRlcik7CisgIHByaW50ZXItPlByaW50KAorICAgIHZhcmlhYmxlc18sCisgICAgIiRhY2Nlc3NfbGV2ZWwkICR0eXBlX25hbWUkICRwcm9wZXJ0eV9uYW1lJCB7XG4iCisgICAgIiAgZ2V0IHsgcmV0dXJuICRoYXNfcHJvcGVydHlfY2hlY2skID8gKCR0eXBlX25hbWUkKSAkb25lb2ZfbmFtZSRfIDogKCR0eXBlX25hbWUkKSBudWxsOyB9XG4iCisgICAgIiAgc2V0IHtcbiIKKyAgICAiICAgICRvbmVvZl9uYW1lJF8gPSB2YWx1ZTtcbiIKKyAgICAiICAgICRvbmVvZl9uYW1lJENhc2VfID0gdmFsdWUgPT0gbnVsbCA/ICRvbmVvZl9wcm9wZXJ0eV9uYW1lJE9uZW9mQ2FzZS5Ob25lIDogJG9uZW9mX3Byb3BlcnR5X25hbWUkT25lb2ZDYXNlLiRwcm9wZXJ0eV9uYW1lJDtcbiIKKyAgICAiICB9XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIFdyYXBwZXJPbmVvZkZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZVBhcnNpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgIHZhcmlhYmxlc18sCisgICAgIiRwcm9wZXJ0eV9uYW1lJCA9IF9vbmVvZl8kbmFtZSRfY29kZWMuUmVhZChpbnB1dCk7XG4iKTsKK30KKwordm9pZCBXcmFwcGVyT25lb2ZGaWVsZEdlbmVyYXRvcjo6R2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgeworICAvLyBUT0RPOiBJIHN1c3BlY3QgdGhpcyBpcyB3cm9uZy4uLgorICBwcmludGVyLT5QcmludCgKKyAgICB2YXJpYWJsZXNfLAorICAgICJpZiAoJGhhc19wcm9wZXJ0eV9jaGVjayQpIHtcbiIKKyAgICAiICBfb25lb2ZfJG5hbWUkX2NvZGVjLldyaXRlVGFnQW5kVmFsdWUob3V0cHV0LCAoJHR5cGVfbmFtZSQpICRvbmVvZl9uYW1lJF8pO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBXcmFwcGVyT25lb2ZGaWVsZEdlbmVyYXRvcjo6R2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgLy8gVE9ETzogSSBzdXNwZWN0IHRoaXMgaXMgd3JvbmcuLi4KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgdmFyaWFibGVzXywKKyAgICAiaWYgKCRoYXNfcHJvcGVydHlfY2hlY2skKSB7XG4iCisgICAgIiAgc2l6ZSArPSBfb25lb2ZfJG5hbWUkX2NvZGVjLkNhbGN1bGF0ZVNpemVXaXRoVGFnKCRwcm9wZXJ0eV9uYW1lJCk7XG4iCisgICAgIn1cbiIpOworfQorCit9ICAvLyBuYW1lc3BhY2UgY3NoYXJwCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jc2hhcnAvY3NoYXJwX3dyYXBwZXJfZmllbGQuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF93cmFwcGVyX2ZpZWxkLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmUyNDE0YQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF93cmFwcGVyX2ZpZWxkLmgKQEAgLTAsMCArMSw4NSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0NTSEFSUF9XUkFQUEVSX0ZJRUxEX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1NIQVJQX1dSQVBQRVJfRklFTERfSF9fCisKKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY29kZV9nZW5lcmF0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9maWVsZF9iYXNlLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgY3NoYXJwIHsKKworY2xhc3MgV3JhcHBlckZpZWxkR2VuZXJhdG9yIDogcHVibGljIEZpZWxkR2VuZXJhdG9yQmFzZSB7CisgcHVibGljOgorICBXcmFwcGVyRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBpbnQgZmllbGRPcmRpbmFsKTsKKyAgfldyYXBwZXJGaWVsZEdlbmVyYXRvcigpOworCisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZUNvZGVjQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZUNsb25pbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyAgdmlydHVhbCB2b2lkIFdyaXRlSGFzaChpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZpcnR1YWwgdm9pZCBXcml0ZUVxdWFscyhpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZpcnR1YWwgdm9pZCBXcml0ZVRvU3RyaW5nKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworIHByaXZhdGU6CisgIGJvb2wgaXNfdmFsdWVfdHlwZTsgLy8gVHJ1ZSBmb3IgaW50MzIgZXRjOyBmYWxzZSBmb3IgYnl0ZXMgYW5kIHN0cmluZworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoV3JhcHBlckZpZWxkR2VuZXJhdG9yKTsKK307CisKK2NsYXNzIFdyYXBwZXJPbmVvZkZpZWxkR2VuZXJhdG9yIDogcHVibGljIFdyYXBwZXJGaWVsZEdlbmVyYXRvciB7CisgcHVibGljOgorICBXcmFwcGVyT25lb2ZGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGludCBmaWVsZE9yZGluYWwpOworICB+V3JhcHBlck9uZW9mRmllbGRHZW5lcmF0b3IoKTsKKworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoV3JhcHBlck9uZW9mRmllbGRHZW5lcmF0b3IpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGNzaGFycAorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfQ1NIQVJQX1dSQVBQRVJfRklFTERfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2ltcG9ydGVyLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9pbXBvcnRlci5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wZDkwOTNjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9pbXBvcnRlci5jYwpAQCAtMCwwICsxLDQ5NiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaWZkZWYgX01TQ19WRVIKKyNpbmNsdWRlIDxpby5oPgorI2Vsc2UKKyNpbmNsdWRlIDx1bmlzdGQuaD4KKyNlbmRpZgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CisjaW5jbHVkZSA8ZmNudGwuaD4KKyNpbmNsdWRlIDxlcnJuby5oPgorCisjaW5jbHVkZSA8YWxnb3JpdGhtPgorI2luY2x1ZGUgPG1lbW9yeT4KKyNpZm5kZWYgX1NIQVJFRF9QVFJfSAorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaGFyZWRfcHRyLmg+CisjZW5kaWYKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9pbXBvcnRlci5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BhcnNlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby90b2tlbml6ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbV9pbXBsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKKworI2lmZGVmIF9XSU4zMgorI2lmbmRlZiBGX09LCisjZGVmaW5lIEZfT0sgMDAgIC8vIG5vdCBkZWZpbmVkIGJ5IE1TVkMgZm9yIHdoYXRldmVyIHJlYXNvbgorI2VuZGlmCisjaW5jbHVkZSA8Y3R5cGUuaD4KKyNlbmRpZgorCisvLyBSZXR1cm5zIHRydWUgaWYgdGhlIHRleHQgbG9va3MgbGlrZSBhIFdpbmRvd3Mtc3R5bGUgYWJzb2x1dGUgcGF0aCwgc3RhcnRpbmcKKy8vIHdpdGggYSBkcml2ZSBsZXR0ZXIuICBFeGFtcGxlOiAgIkM6XGZvbyIuICBUT0RPKGtlbnRvbik6ICBTaGFyZSB0aGlzIHdpdGgKKy8vIGNvcHkgaW4gY29tbWFuZF9saW5lX2ludGVyZmFjZS5jYz8KK3N0YXRpYyBib29sIElzV2luZG93c0Fic29sdXRlUGF0aChjb25zdCBzdHJpbmcmIHRleHQpIHsKKyNpZiBkZWZpbmVkKF9XSU4zMikgfHwgZGVmaW5lZChfX0NZR1dJTl9fKQorICByZXR1cm4gdGV4dC5zaXplKCkgPj0gMyAmJiB0ZXh0WzFdID09ICc6JyAmJgorICAgICAgICAgaXNhbHBoYSh0ZXh0WzBdKSAmJgorICAgICAgICAgKHRleHRbMl0gPT0gJy8nIHx8IHRleHRbMl0gPT0gJ1xcJykgJiYKKyAgICAgICAgIHRleHQuZmluZF9sYXN0X29mKCc6JykgPT0gMTsKKyNlbHNlCisgIHJldHVybiBmYWxzZTsKKyNlbmRpZgorfQorCitNdWx0aUZpbGVFcnJvckNvbGxlY3Rvcjo6fk11bHRpRmlsZUVycm9yQ29sbGVjdG9yKCkge30KKworLy8gVGhpcyBjbGFzcyBzZXJ2ZXMgdHdvIHB1cnBvc2VzOgorLy8gLSBJdCBpbXBsZW1lbnRzIHRoZSBFcnJvckNvbGxlY3RvciBpbnRlcmZhY2UgKHVzZWQgYnkgVG9rZW5pemVyIGFuZCBQYXJzZXIpCisvLyAgIGluIHRlcm1zIG9mIE11bHRpRmlsZUVycm9yQ29sbGVjdG9yLCB1c2luZyBhIHBhcnRpY3VsYXIgZmlsZW5hbWUuCisvLyAtIEl0IGxldHMgdXMgY2hlY2sgaWYgYW55IGVycm9ycyBoYXZlIG9jY3VycmVkLgorY2xhc3MgU291cmNlVHJlZURlc2NyaXB0b3JEYXRhYmFzZTo6U2luZ2xlRmlsZUVycm9yQ29sbGVjdG9yCisgICAgOiBwdWJsaWMgaW86OkVycm9yQ29sbGVjdG9yIHsKKyBwdWJsaWM6CisgIFNpbmdsZUZpbGVFcnJvckNvbGxlY3Rvcihjb25zdCBzdHJpbmcmIGZpbGVuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgTXVsdGlGaWxlRXJyb3JDb2xsZWN0b3IqIG11bHRpX2ZpbGVfZXJyb3JfY29sbGVjdG9yKQorICAgIDogZmlsZW5hbWVfKGZpbGVuYW1lKSwKKyAgICAgIG11bHRpX2ZpbGVfZXJyb3JfY29sbGVjdG9yXyhtdWx0aV9maWxlX2Vycm9yX2NvbGxlY3RvciksCisgICAgICBoYWRfZXJyb3JzXyhmYWxzZSkge30KKyAgflNpbmdsZUZpbGVFcnJvckNvbGxlY3RvcigpIHt9CisKKyAgYm9vbCBoYWRfZXJyb3JzKCkgeyByZXR1cm4gaGFkX2Vycm9yc187IH0KKworICAvLyBpbXBsZW1lbnRzIEVycm9yQ29sbGVjdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICB2b2lkIEFkZEVycm9yKGludCBsaW5lLCBpbnQgY29sdW1uLCBjb25zdCBzdHJpbmcmIG1lc3NhZ2UpIHsKKyAgICBpZiAobXVsdGlfZmlsZV9lcnJvcl9jb2xsZWN0b3JfICE9IE5VTEwpIHsKKyAgICAgIG11bHRpX2ZpbGVfZXJyb3JfY29sbGVjdG9yXy0+QWRkRXJyb3IoZmlsZW5hbWVfLCBsaW5lLCBjb2x1bW4sIG1lc3NhZ2UpOworICAgIH0KKyAgICBoYWRfZXJyb3JzXyA9IHRydWU7CisgIH0KKworIHByaXZhdGU6CisgIHN0cmluZyBmaWxlbmFtZV87CisgIE11bHRpRmlsZUVycm9yQ29sbGVjdG9yKiBtdWx0aV9maWxlX2Vycm9yX2NvbGxlY3Rvcl87CisgIGJvb2wgaGFkX2Vycm9yc187Cit9OworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK1NvdXJjZVRyZWVEZXNjcmlwdG9yRGF0YWJhc2U6OlNvdXJjZVRyZWVEZXNjcmlwdG9yRGF0YWJhc2UoCisgICAgU291cmNlVHJlZSogc291cmNlX3RyZWUpCisgIDogc291cmNlX3RyZWVfKHNvdXJjZV90cmVlKSwKKyAgICBlcnJvcl9jb2xsZWN0b3JfKE5VTEwpLAorICAgIHVzaW5nX3ZhbGlkYXRpb25fZXJyb3JfY29sbGVjdG9yXyhmYWxzZSksCisgICAgdmFsaWRhdGlvbl9lcnJvcl9jb2xsZWN0b3JfKHRoaXMpIHt9CisKK1NvdXJjZVRyZWVEZXNjcmlwdG9yRGF0YWJhc2U6On5Tb3VyY2VUcmVlRGVzY3JpcHRvckRhdGFiYXNlKCkge30KKworYm9vbCBTb3VyY2VUcmVlRGVzY3JpcHRvckRhdGFiYXNlOjpGaW5kRmlsZUJ5TmFtZSgKKyAgICBjb25zdCBzdHJpbmcmIGZpbGVuYW1lLCBGaWxlRGVzY3JpcHRvclByb3RvKiBvdXRwdXQpIHsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxpbzo6WmVyb0NvcHlJbnB1dFN0cmVhbT4gaW5wdXQoc291cmNlX3RyZWVfLT5PcGVuKGZpbGVuYW1lKSk7CisgIGlmIChpbnB1dCA9PSBOVUxMKSB7CisgICAgaWYgKGVycm9yX2NvbGxlY3Rvcl8gIT0gTlVMTCkgeworICAgICAgZXJyb3JfY29sbGVjdG9yXy0+QWRkRXJyb3IoZmlsZW5hbWUsIC0xLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlX3RyZWVfLT5HZXRMYXN0RXJyb3JNZXNzYWdlKCkpOworICAgIH0KKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLyBTZXQgdXAgdGhlIHRva2VuaXplciBhbmQgcGFyc2VyLgorICBTaW5nbGVGaWxlRXJyb3JDb2xsZWN0b3IgZmlsZV9lcnJvcl9jb2xsZWN0b3IoZmlsZW5hbWUsIGVycm9yX2NvbGxlY3Rvcl8pOworICBpbzo6VG9rZW5pemVyIHRva2VuaXplcihpbnB1dC5nZXQoKSwgJmZpbGVfZXJyb3JfY29sbGVjdG9yKTsKKworICBQYXJzZXIgcGFyc2VyOworICBpZiAoZXJyb3JfY29sbGVjdG9yXyAhPSBOVUxMKSB7CisgICAgcGFyc2VyLlJlY29yZEVycm9yc1RvKCZmaWxlX2Vycm9yX2NvbGxlY3Rvcik7CisgIH0KKyAgaWYgKHVzaW5nX3ZhbGlkYXRpb25fZXJyb3JfY29sbGVjdG9yXykgeworICAgIHBhcnNlci5SZWNvcmRTb3VyY2VMb2NhdGlvbnNUbygmc291cmNlX2xvY2F0aW9uc18pOworICB9CisKKyAgLy8gUGFyc2UgaXQuCisgIG91dHB1dC0+c2V0X25hbWUoZmlsZW5hbWUpOworICByZXR1cm4gcGFyc2VyLlBhcnNlKCZ0b2tlbml6ZXIsIG91dHB1dCkgJiYKKyAgICAgICAgICFmaWxlX2Vycm9yX2NvbGxlY3Rvci5oYWRfZXJyb3JzKCk7Cit9CisKK2Jvb2wgU291cmNlVHJlZURlc2NyaXB0b3JEYXRhYmFzZTo6RmluZEZpbGVDb250YWluaW5nU3ltYm9sKAorICAgIGNvbnN0IHN0cmluZyYgc3ltYm9sX25hbWUsIEZpbGVEZXNjcmlwdG9yUHJvdG8qIG91dHB1dCkgeworICByZXR1cm4gZmFsc2U7Cit9CisKK2Jvb2wgU291cmNlVHJlZURlc2NyaXB0b3JEYXRhYmFzZTo6RmluZEZpbGVDb250YWluaW5nRXh0ZW5zaW9uKAorICAgIGNvbnN0IHN0cmluZyYgY29udGFpbmluZ190eXBlLCBpbnQgZmllbGRfbnVtYmVyLAorICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8qIG91dHB1dCkgeworICByZXR1cm4gZmFsc2U7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworU291cmNlVHJlZURlc2NyaXB0b3JEYXRhYmFzZTo6VmFsaWRhdGlvbkVycm9yQ29sbGVjdG9yOjoKK1ZhbGlkYXRpb25FcnJvckNvbGxlY3RvcihTb3VyY2VUcmVlRGVzY3JpcHRvckRhdGFiYXNlKiBvd25lcikKKyAgOiBvd25lcl8ob3duZXIpIHt9CisKK1NvdXJjZVRyZWVEZXNjcmlwdG9yRGF0YWJhc2U6OlZhbGlkYXRpb25FcnJvckNvbGxlY3Rvcjo6Cit+VmFsaWRhdGlvbkVycm9yQ29sbGVjdG9yKCkge30KKwordm9pZCBTb3VyY2VUcmVlRGVzY3JpcHRvckRhdGFiYXNlOjpWYWxpZGF0aW9uRXJyb3JDb2xsZWN0b3I6OkFkZEVycm9yKAorICAgIGNvbnN0IHN0cmluZyYgZmlsZW5hbWUsCisgICAgY29uc3Qgc3RyaW5nJiBlbGVtZW50X25hbWUsCisgICAgY29uc3QgTWVzc2FnZSogZGVzY3JpcHRvciwKKyAgICBFcnJvckxvY2F0aW9uIGxvY2F0aW9uLAorICAgIGNvbnN0IHN0cmluZyYgbWVzc2FnZSkgeworICBpZiAob3duZXJfLT5lcnJvcl9jb2xsZWN0b3JfID09IE5VTEwpIHJldHVybjsKKworICBpbnQgbGluZSwgY29sdW1uOworICBvd25lcl8tPnNvdXJjZV9sb2NhdGlvbnNfLkZpbmQoZGVzY3JpcHRvciwgbG9jYXRpb24sICZsaW5lLCAmY29sdW1uKTsKKyAgb3duZXJfLT5lcnJvcl9jb2xsZWN0b3JfLT5BZGRFcnJvcihmaWxlbmFtZSwgbGluZSwgY29sdW1uLCBtZXNzYWdlKTsKK30KKwordm9pZCBTb3VyY2VUcmVlRGVzY3JpcHRvckRhdGFiYXNlOjpWYWxpZGF0aW9uRXJyb3JDb2xsZWN0b3I6OkFkZFdhcm5pbmcoCisgICAgY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSwKKyAgICBjb25zdCBzdHJpbmcmIGVsZW1lbnRfbmFtZSwKKyAgICBjb25zdCBNZXNzYWdlKiBkZXNjcmlwdG9yLAorICAgIEVycm9yTG9jYXRpb24gbG9jYXRpb24sCisgICAgY29uc3Qgc3RyaW5nJiBtZXNzYWdlKSB7CisgIGlmIChvd25lcl8tPmVycm9yX2NvbGxlY3Rvcl8gPT0gTlVMTCkgcmV0dXJuOworCisgIGludCBsaW5lLCBjb2x1bW47CisgIG93bmVyXy0+c291cmNlX2xvY2F0aW9uc18uRmluZChkZXNjcmlwdG9yLCBsb2NhdGlvbiwgJmxpbmUsICZjb2x1bW4pOworICBvd25lcl8tPmVycm9yX2NvbGxlY3Rvcl8tPkFkZFdhcm5pbmcoZmlsZW5hbWUsIGxpbmUsIGNvbHVtbiwgbWVzc2FnZSk7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworSW1wb3J0ZXI6OkltcG9ydGVyKFNvdXJjZVRyZWUqIHNvdXJjZV90cmVlLAorICAgICAgICAgICAgICAgICAgIE11bHRpRmlsZUVycm9yQ29sbGVjdG9yKiBlcnJvcl9jb2xsZWN0b3IpCisgIDogZGF0YWJhc2VfKHNvdXJjZV90cmVlKSwKKyAgICBwb29sXygmZGF0YWJhc2VfLCBkYXRhYmFzZV8uR2V0VmFsaWRhdGlvbkVycm9yQ29sbGVjdG9yKCkpIHsKKyAgcG9vbF8uRW5mb3JjZVdlYWtEZXBlbmRlbmNpZXModHJ1ZSk7CisgIGRhdGFiYXNlXy5SZWNvcmRFcnJvcnNUbyhlcnJvcl9jb2xsZWN0b3IpOworfQorCitJbXBvcnRlcjo6fkltcG9ydGVyKCkge30KKworY29uc3QgRmlsZURlc2NyaXB0b3IqIEltcG9ydGVyOjpJbXBvcnQoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSkgeworICByZXR1cm4gcG9vbF8uRmluZEZpbGVCeU5hbWUoZmlsZW5hbWUpOworfQorCit2b2lkIEltcG9ydGVyOjpBZGRVbnVzZWRJbXBvcnRUcmFja0ZpbGUoY29uc3Qgc3RyaW5nJiBmaWxlX25hbWUpIHsKKyAgcG9vbF8uQWRkVW51c2VkSW1wb3J0VHJhY2tGaWxlKGZpbGVfbmFtZSk7Cit9CisKK3ZvaWQgSW1wb3J0ZXI6OkNsZWFyVW51c2VkSW1wb3J0VHJhY2tGaWxlcygpIHsKKyAgcG9vbF8uQ2xlYXJVbnVzZWRJbXBvcnRUcmFja0ZpbGVzKCk7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworU291cmNlVHJlZTo6flNvdXJjZVRyZWUoKSB7fQorCitzdHJpbmcgU291cmNlVHJlZTo6R2V0TGFzdEVycm9yTWVzc2FnZSgpIHsKKyAgcmV0dXJuICJGaWxlIG5vdCBmb3VuZC4iOworfQorCitEaXNrU291cmNlVHJlZTo6RGlza1NvdXJjZVRyZWUoKSB7fQorCitEaXNrU291cmNlVHJlZTo6fkRpc2tTb3VyY2VUcmVlKCkge30KKworc3RhdGljIGlubGluZSBjaGFyIExhc3RDaGFyKGNvbnN0IHN0cmluZyYgc3RyKSB7CisgIHJldHVybiBzdHJbc3RyLnNpemUoKSAtIDFdOworfQorCisvLyBHaXZlbiBhIHBhdGgsIHJldHVybnMgYW4gZXF1aXZhbGVudCBwYXRoIHdpdGggdGhlc2UgY2hhbmdlczoKKy8vIC0gT24gV2luZG93cywgYW55IGJhY2tzbGFzaGVzIGFyZSByZXBsYWNlZCB3aXRoIGZvcndhcmQgc2xhc2hlcy4KKy8vIC0gQW55IGluc3RhbmNlcyBvZiB0aGUgZGlyZWN0b3J5ICIuIiBhcmUgcmVtb3ZlZC4KKy8vIC0gQW55IGNvbnNlY3V0aXZlICcvJ3MgYXJlIGNvbGxhcHNlZCBpbnRvIGEgc2luZ2xlIHNsYXNoLgorLy8gTm90ZSB0aGF0IHRoZSByZXN1bHRpbmcgc3RyaW5nIG1heSBiZSBlbXB0eS4KKy8vCisvLyBUT0RPKGtlbnRvbik6ICBJdCB3b3VsZCBiZSBuaWNlIHRvIGhhbmRsZSAiLi4iLCBlLmcuIHNvIHRoYXQgd2UgY2FuIGZpZ3VyZQorLy8gICBvdXQgdGhhdCAiZm9vL2Jhci5wcm90byIgaXMgaW5zaWRlICJiYXovLi4vZm9vIi4gIEhvd2V2ZXIsIGlmIGJheiBpcyBhCisvLyAgIHN5bWxpbmsgb3IgZG9lc24ndCBleGlzdCwgdGhlbiB0aGluZ3MgZ2V0IGNvbXBsaWNhdGVkLCBhbmQgd2UgY2FuJ3QKKy8vICAgYWN0dWFsbHkgZGV0ZXJtaW5lIHRoaXMgd2l0aG91dCBpbnZlc3RpZ2F0aW5nIHRoZSBmaWxlc3lzdGVtLCBwcm9iYWJseQorLy8gICBpbiBub24tcG9ydGFibGUgd2F5cy4gIFNvLCB3ZSBwdW50LgorLy8KKy8vIFRPRE8oa2VudG9uKTogIEl0IHdvdWxkIGJlIG5pY2UgdG8gdXNlIHJlYWxwYXRoKCkgaGVyZSBleGNlcHQgdGhhdCBpdAorLy8gICByZXNvbHZlcyBzeW1ib2xpYyBsaW5rcy4gIFRoaXMgY291bGQgY2F1c2UgcHJvYmxlbXMgaWYgcGVvcGxlIHBsYWNlCisvLyAgIHN5bWJvbGljIGxpbmtzIGluIHRoZWlyIHNvdXJjZSB0cmVlLiAgRm9yIGV4YW1wbGUsIGlmIHlvdSBleGVjdXRlZDoKKy8vICAgICBwcm90b2MgLS1wcm90b19wYXRoPWZvbyBmb28vYmFyL2Jhei5wcm90bworLy8gICB0aGVuIGlmIGZvby9iYXIgaXMgYSBzeW1ib2xpYyBsaW5rLCBmb28vYmFyL2Jhei5wcm90byB3aWxsIGNhbm9uaWNhbGl6ZQorLy8gICB0byBhIHBhdGggd2hpY2ggZG9lcyBub3QgYXBwZWFyIHRvIGJlIHVuZGVyIGZvbywgYW5kIHRodXMgdGhlIGNvbXBpbGVyCisvLyAgIHdpbGwgY29tcGxhaW4gdGhhdCBiYXoucHJvdG8gaXMgbm90IGluc2lkZSB0aGUgLS1wcm90b19wYXRoLgorc3RhdGljIHN0cmluZyBDYW5vbmljYWxpemVQYXRoKHN0cmluZyBwYXRoKSB7CisjaWZkZWYgX1dJTjMyCisgIC8vIFRoZSBXaW4zMiBBUEkgYWNjZXB0cyBmb3J3YXJkIHNsYXNoZXMgYXMgYSBwYXRoIGRlbGltaXRlciBldmVuIHRob3VnaAorICAvLyBiYWNrc2xhc2hlcyBhcmUgc3RhbmRhcmQuICBMZXQncyBhdm9pZCBjb25mdXNpb24gYW5kIHVzZSBvbmx5IGZvcndhcmQKKyAgLy8gc2xhc2hlcy4KKyAgaWYgKEhhc1ByZWZpeFN0cmluZyhwYXRoLCAiXFxcXCIpKSB7CisgICAgLy8gQXZvaWQgY29udmVydGluZyB0d28gbGVhZGluZyBiYWNrc2xhc2hlcy4KKyAgICBwYXRoID0gIlxcXFwiICsgU3RyaW5nUmVwbGFjZShwYXRoLnN1YnN0cigyKSwgIlxcIiwgIi8iLCB0cnVlKTsKKyAgfSBlbHNlIHsKKyAgICBwYXRoID0gU3RyaW5nUmVwbGFjZShwYXRoLCAiXFwiLCAiLyIsIHRydWUpOworICB9CisjZW5kaWYKKworICB2ZWN0b3I8c3RyaW5nPiBjYW5vbmljYWxfcGFydHM7CisgIHZlY3RvcjxzdHJpbmc+IHBhcnRzID0gU3BsaXQoCisgICAgICBwYXRoLCAiLyIsIHRydWUpOyAgLy8gTm90ZTogIFJlbW92ZXMgZW1wdHkgcGFydHMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFydHMuc2l6ZSgpOyBpKyspIHsKKyAgICBpZiAocGFydHNbaV0gPT0gIi4iKSB7CisgICAgICAvLyBJZ25vcmUuCisgICAgfSBlbHNlIHsKKyAgICAgIGNhbm9uaWNhbF9wYXJ0cy5wdXNoX2JhY2socGFydHNbaV0pOworICAgIH0KKyAgfQorICBzdHJpbmcgcmVzdWx0ID0gSm9pbihjYW5vbmljYWxfcGFydHMsICIvIik7CisgIGlmICghcGF0aC5lbXB0eSgpICYmIHBhdGhbMF0gPT0gJy8nKSB7CisgICAgLy8gUmVzdG9yZSBsZWFkaW5nIHNsYXNoLgorICAgIHJlc3VsdCA9ICcvJyArIHJlc3VsdDsKKyAgfQorICBpZiAoIXBhdGguZW1wdHkoKSAmJiBMYXN0Q2hhcihwYXRoKSA9PSAnLycgJiYKKyAgICAgICFyZXN1bHQuZW1wdHkoKSAmJiBMYXN0Q2hhcihyZXN1bHQpICE9ICcvJykgeworICAgIC8vIFJlc3RvcmUgdHJhaWxpbmcgc2xhc2guCisgICAgcmVzdWx0ICs9ICcvJzsKKyAgfQorICByZXR1cm4gcmVzdWx0OworfQorCitzdGF0aWMgaW5saW5lIGJvb2wgQ29udGFpbnNQYXJlbnRSZWZlcmVuY2UoY29uc3Qgc3RyaW5nJiBwYXRoKSB7CisgIHJldHVybiBwYXRoID09ICIuLiIgfHwKKyAgICAgICAgIEhhc1ByZWZpeFN0cmluZyhwYXRoLCAiLi4vIikgfHwKKyAgICAgICAgIEhhc1N1ZmZpeFN0cmluZyhwYXRoLCAiLy4uIikgfHwKKyAgICAgICAgIHBhdGguZmluZCgiLy4uLyIpICE9IHN0cmluZzo6bnBvczsKK30KKworLy8gTWFwcyBhIGZpbGUgZnJvbSBhbiBvbGQgbG9jYXRpb24gdG8gYSBuZXcgb25lLiAgVHlwaWNhbGx5LCBvbGRfcHJlZml4IGlzCisvLyBhIHZpcnR1YWwgcGF0aCBhbmQgbmV3X3ByZWZpeCBpcyBpdHMgY29ycmVzcG9uZGluZyBkaXNrIHBhdGguICBSZXR1cm5zCisvLyBmYWxzZSBpZiB0aGUgZmlsZW5hbWUgZGlkIG5vdCBzdGFydCB3aXRoIG9sZF9wcmVmaXgsIG90aGVyd2lzZSByZXBsYWNlcworLy8gb2xkX3ByZWZpeCB3aXRoIG5ld19wcmVmaXggYW5kIHN0b3JlcyB0aGUgcmVzdWx0IGluICpyZXN1bHQuICBFeGFtcGxlczoKKy8vICAgc3RyaW5nIHJlc3VsdDsKKy8vICAgYXNzZXJ0KEFwcGx5TWFwcGluZygiZm9vL2JhciIsICIiLCAiYmF6IiwgJnJlc3VsdCkpOworLy8gICBhc3NlcnQocmVzdWx0ID09ICJiYXovZm9vL2JhciIpOworLy8KKy8vICAgYXNzZXJ0KEFwcGx5TWFwcGluZygiZm9vL2JhciIsICJmb28iLCAiYmF6IiwgJnJlc3VsdCkpOworLy8gICBhc3NlcnQocmVzdWx0ID09ICJiYXovYmFyIik7CisvLworLy8gICBhc3NlcnQoQXBwbHlNYXBwaW5nKCJmb28iLCAiZm9vIiwgImJhciIsICZyZXN1bHQpKTsKKy8vICAgYXNzZXJ0KHJlc3VsdCA9PSAiYmFyIik7CisvLworLy8gICBhc3NlcnQoIUFwcGx5TWFwcGluZygiZm9vL2JhciIsICJiYXoiLCAicXV4IiwgJnJlc3VsdCkpOworLy8gICBhc3NlcnQoIUFwcGx5TWFwcGluZygiZm9vL2JhciIsICJiYXoiLCAicXV4IiwgJnJlc3VsdCkpOworLy8gICBhc3NlcnQoIUFwcGx5TWFwcGluZygiZm9vYmFyIiwgImZvbyIsICJiYXoiLCAmcmVzdWx0KSk7CitzdGF0aWMgYm9vbCBBcHBseU1hcHBpbmcoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIG9sZF9wcmVmaXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBuZXdfcHJlZml4LAorICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyogcmVzdWx0KSB7CisgIGlmIChvbGRfcHJlZml4LmVtcHR5KCkpIHsKKyAgICAvLyBvbGRfcHJlZml4IG1hdGNoZXMgYW55IHJlbGF0aXZlIHBhdGguCisgICAgaWYgKENvbnRhaW5zUGFyZW50UmVmZXJlbmNlKGZpbGVuYW1lKSkgeworICAgICAgLy8gV2UgZG8gbm90IGFsbG93IHRoZSBmaWxlIG5hbWUgdG8gdXNlICIuLiIuCisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIGlmIChIYXNQcmVmaXhTdHJpbmcoZmlsZW5hbWUsICIvIikgfHwKKyAgICAgICAgSXNXaW5kb3dzQWJzb2x1dGVQYXRoKGZpbGVuYW1lKSkgeworICAgICAgLy8gVGhpcyBpcyBhbiBhYnNvbHV0ZSBwYXRoLCBzbyBpdCBpc24ndCBtYXRjaGVkIGJ5IHRoZSBlbXB0eSBzdHJpbmcuCisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIHJlc3VsdC0+YXNzaWduKG5ld19wcmVmaXgpOworICAgIGlmICghcmVzdWx0LT5lbXB0eSgpKSByZXN1bHQtPnB1c2hfYmFjaygnLycpOworICAgIHJlc3VsdC0+YXBwZW5kKGZpbGVuYW1lKTsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfSBlbHNlIGlmIChIYXNQcmVmaXhTdHJpbmcoZmlsZW5hbWUsIG9sZF9wcmVmaXgpKSB7CisgICAgLy8gb2xkX3ByZWZpeCBpcyBhIHByZWZpeCBvZiB0aGUgZmlsZW5hbWUuICBJcyBpdCB0aGUgd2hvbGUgZmlsZW5hbWU/CisgICAgaWYgKGZpbGVuYW1lLnNpemUoKSA9PSBvbGRfcHJlZml4LnNpemUoKSkgeworICAgICAgLy8gWWVwLCBpdCdzIGFuIGV4YWN0IG1hdGNoLgorICAgICAgKnJlc3VsdCA9IG5ld19wcmVmaXg7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9IGVsc2UgeworICAgICAgLy8gTm90IGFuIGV4YWN0IG1hdGNoLiAgSXMgdGhlIG5leHQgY2hhcmFjdGVyIGEgJy8nPyAgT3RoZXJ3aXNlLAorICAgICAgLy8gdGhpcyBpc24ndCBhY3R1YWxseSBhIG1hdGNoIGF0IGFsbC4gIEUuZy4gdGhlIHByZWZpeCAiZm9vL2JhciIKKyAgICAgIC8vIGRvZXMgbm90IG1hdGNoIHRoZSBmaWxlbmFtZSAiZm9vL2JhcmJheiIuCisgICAgICBpbnQgYWZ0ZXJfcHJlZml4X3N0YXJ0ID0gLTE7CisgICAgICBpZiAoZmlsZW5hbWVbb2xkX3ByZWZpeC5zaXplKCldID09ICcvJykgeworICAgICAgICBhZnRlcl9wcmVmaXhfc3RhcnQgPSBvbGRfcHJlZml4LnNpemUoKSArIDE7CisgICAgICB9IGVsc2UgaWYgKGZpbGVuYW1lW29sZF9wcmVmaXguc2l6ZSgpIC0gMV0gPT0gJy8nKSB7CisgICAgICAgIC8vIG9sZF9wcmVmaXggaXMgbmV2ZXIgZW1wdHksIGFuZCBjYW5vbmljYWxpemVkIHBhdGhzIG5ldmVyIGhhdmUKKyAgICAgICAgLy8gY29uc2VjdXRpdmUgJy8nIGNoYXJhY3RlcnMuCisgICAgICAgIGFmdGVyX3ByZWZpeF9zdGFydCA9IG9sZF9wcmVmaXguc2l6ZSgpOworICAgICAgfQorICAgICAgaWYgKGFmdGVyX3ByZWZpeF9zdGFydCAhPSAtMSkgeworICAgICAgICAvLyBZZXAuICBTbyB0aGUgcHJlZml4ZXMgYXJlIGRpcmVjdG9yaWVzIGFuZCB0aGUgZmlsZW5hbWUgaXMgYSBmaWxlCisgICAgICAgIC8vIGluc2lkZSB0aGVtLgorICAgICAgICBzdHJpbmcgYWZ0ZXJfcHJlZml4ID0gZmlsZW5hbWUuc3Vic3RyKGFmdGVyX3ByZWZpeF9zdGFydCk7CisgICAgICAgIGlmIChDb250YWluc1BhcmVudFJlZmVyZW5jZShhZnRlcl9wcmVmaXgpKSB7CisgICAgICAgICAgLy8gV2UgZG8gbm90IGFsbG93IHRoZSBmaWxlIG5hbWUgdG8gdXNlICIuLiIuCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIHJlc3VsdC0+YXNzaWduKG5ld19wcmVmaXgpOworICAgICAgICBpZiAoIXJlc3VsdC0+ZW1wdHkoKSkgcmVzdWx0LT5wdXNoX2JhY2soJy8nKTsKKyAgICAgICAgcmVzdWx0LT5hcHBlbmQoYWZ0ZXJfcHJlZml4KTsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICB9CisgICAgfQorICB9CisKKyAgcmV0dXJuIGZhbHNlOworfQorCit2b2lkIERpc2tTb3VyY2VUcmVlOjpNYXBQYXRoKGNvbnN0IHN0cmluZyYgdmlydHVhbF9wYXRoLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIGRpc2tfcGF0aCkgeworICBtYXBwaW5nc18ucHVzaF9iYWNrKE1hcHBpbmcodmlydHVhbF9wYXRoLCBDYW5vbmljYWxpemVQYXRoKGRpc2tfcGF0aCkpKTsKK30KKworRGlza1NvdXJjZVRyZWU6OkRpc2tGaWxlVG9WaXJ0dWFsRmlsZVJlc3VsdAorRGlza1NvdXJjZVRyZWU6OkRpc2tGaWxlVG9WaXJ0dWFsRmlsZSgKKyAgICBjb25zdCBzdHJpbmcmIGRpc2tfZmlsZSwKKyAgICBzdHJpbmcqIHZpcnR1YWxfZmlsZSwKKyAgICBzdHJpbmcqIHNoYWRvd2luZ19kaXNrX2ZpbGUpIHsKKyAgaW50IG1hcHBpbmdfaW5kZXggPSAtMTsKKyAgc3RyaW5nIGNhbm9uaWNhbF9kaXNrX2ZpbGUgPSBDYW5vbmljYWxpemVQYXRoKGRpc2tfZmlsZSk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBtYXBwaW5nc18uc2l6ZSgpOyBpKyspIHsKKyAgICAvLyBBcHBseSB0aGUgbWFwcGluZyBpbiByZXZlcnNlLgorICAgIGlmIChBcHBseU1hcHBpbmcoY2Fub25pY2FsX2Rpc2tfZmlsZSwgbWFwcGluZ3NfW2ldLmRpc2tfcGF0aCwKKyAgICAgICAgICAgICAgICAgICAgIG1hcHBpbmdzX1tpXS52aXJ0dWFsX3BhdGgsIHZpcnR1YWxfZmlsZSkpIHsKKyAgICAgIC8vIFN1Y2Nlc3MuCisgICAgICBtYXBwaW5nX2luZGV4ID0gaTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgfQorCisgIGlmIChtYXBwaW5nX2luZGV4ID09IC0xKSB7CisgICAgcmV0dXJuIE5PX01BUFBJTkc7CisgIH0KKworICAvLyBJdGVyYXRlIHRocm91Z2ggYWxsIG1hcHBpbmdzIHdpdGggaGlnaGVyIHByZWNlZGVuY2UgYW5kIHZlcmlmeSB0aGF0IG5vbmUKKyAgLy8gb2YgdGhlbSBtYXAgdGhpcyBmaWxlIHRvIHNvbWUgb3RoZXIgZXhpc3RpbmcgZmlsZS4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBtYXBwaW5nX2luZGV4OyBpKyspIHsKKyAgICBpZiAoQXBwbHlNYXBwaW5nKCp2aXJ0dWFsX2ZpbGUsIG1hcHBpbmdzX1tpXS52aXJ0dWFsX3BhdGgsCisgICAgICAgICAgICAgICAgICAgICBtYXBwaW5nc19baV0uZGlza19wYXRoLCBzaGFkb3dpbmdfZGlza19maWxlKSkgeworICAgICAgaWYgKGFjY2VzcyhzaGFkb3dpbmdfZGlza19maWxlLT5jX3N0cigpLCBGX09LKSA+PSAwKSB7CisgICAgICAgIC8vIEZpbGUgZXhpc3RzLgorICAgICAgICByZXR1cm4gU0hBRE9XRUQ7CisgICAgICB9CisgICAgfQorICB9CisgIHNoYWRvd2luZ19kaXNrX2ZpbGUtPmNsZWFyKCk7CisKKyAgLy8gVmVyaWZ5IHRoYXQgd2UgY2FuIG9wZW4gdGhlIGZpbGUuICBOb3RlIHRoYXQgdGhpcyBhbHNvIGhhcyB0aGUgc2lkZS1lZmZlY3QKKyAgLy8gb2YgdmVyaWZ5aW5nIHRoYXQgd2UgYXJlIG5vdCBjYW5vbmljYWxpemluZyBhd2F5IGFueSBub24tZXhpc3RlbnQKKyAgLy8gZGlyZWN0b3JpZXMuCisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8aW86Olplcm9Db3B5SW5wdXRTdHJlYW0+IHN0cmVhbShPcGVuRGlza0ZpbGUoZGlza19maWxlKSk7CisgIGlmIChzdHJlYW0gPT0gTlVMTCkgeworICAgIHJldHVybiBDQU5OT1RfT1BFTjsKKyAgfQorCisgIHJldHVybiBTVUNDRVNTOworfQorCitib29sIERpc2tTb3VyY2VUcmVlOjpWaXJ0dWFsRmlsZVRvRGlza0ZpbGUoY29uc3Qgc3RyaW5nJiB2aXJ0dWFsX2ZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nKiBkaXNrX2ZpbGUpIHsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxpbzo6WmVyb0NvcHlJbnB1dFN0cmVhbT4gc3RyZWFtKAorICAgICAgT3BlblZpcnR1YWxGaWxlKHZpcnR1YWxfZmlsZSwgZGlza19maWxlKSk7CisgIHJldHVybiBzdHJlYW0gIT0gTlVMTDsKK30KKworaW86Olplcm9Db3B5SW5wdXRTdHJlYW0qIERpc2tTb3VyY2VUcmVlOjpPcGVuKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUpIHsKKyAgcmV0dXJuIE9wZW5WaXJ0dWFsRmlsZShmaWxlbmFtZSwgTlVMTCk7Cit9CisKK3N0cmluZyBEaXNrU291cmNlVHJlZTo6R2V0TGFzdEVycm9yTWVzc2FnZSgpIHsKKyAgcmV0dXJuIGxhc3RfZXJyb3JfbWVzc2FnZV87Cit9CisKK2lvOjpaZXJvQ29weUlucHV0U3RyZWFtKiBEaXNrU291cmNlVHJlZTo6T3BlblZpcnR1YWxGaWxlKAorICAgIGNvbnN0IHN0cmluZyYgdmlydHVhbF9maWxlLAorICAgIHN0cmluZyogZGlza19maWxlKSB7CisgIGlmICh2aXJ0dWFsX2ZpbGUgIT0gQ2Fub25pY2FsaXplUGF0aCh2aXJ0dWFsX2ZpbGUpIHx8CisgICAgICBDb250YWluc1BhcmVudFJlZmVyZW5jZSh2aXJ0dWFsX2ZpbGUpKSB7CisgICAgLy8gV2UgZG8gbm90IGFsbG93IGltcG9ydGluZyBvZiBwYXRocyBjb250YWluaW5nIHRoaW5ncyBsaWtlICIuLiIgb3IKKyAgICAvLyBjb25zZWN1dGl2ZSBzbGFzaGVzIHNpbmNlIHRoZSBjb21waWxlciBleHBlY3RzIGZpbGVzIHRvIGJlIHVuaXF1ZWx5CisgICAgLy8gaWRlbnRpZmllZCBieSBmaWxlIG5hbWUuCisgICAgbGFzdF9lcnJvcl9tZXNzYWdlXyA9ICJCYWNrc2xhc2hlcywgY29uc2VjdXRpdmUgc2xhc2hlcywgXCIuXCIsIG9yIFwiLi5cIiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICJhcmUgbm90IGFsbG93ZWQgaW4gdGhlIHZpcnR1YWwgcGF0aCI7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IG1hcHBpbmdzXy5zaXplKCk7IGkrKykgeworICAgIHN0cmluZyB0ZW1wX2Rpc2tfZmlsZTsKKyAgICBpZiAoQXBwbHlNYXBwaW5nKHZpcnR1YWxfZmlsZSwgbWFwcGluZ3NfW2ldLnZpcnR1YWxfcGF0aCwKKyAgICAgICAgICAgICAgICAgICAgIG1hcHBpbmdzX1tpXS5kaXNrX3BhdGgsICZ0ZW1wX2Rpc2tfZmlsZSkpIHsKKyAgICAgIGlvOjpaZXJvQ29weUlucHV0U3RyZWFtKiBzdHJlYW0gPSBPcGVuRGlza0ZpbGUodGVtcF9kaXNrX2ZpbGUpOworICAgICAgaWYgKHN0cmVhbSAhPSBOVUxMKSB7CisgICAgICAgIGlmIChkaXNrX2ZpbGUgIT0gTlVMTCkgeworICAgICAgICAgICpkaXNrX2ZpbGUgPSB0ZW1wX2Rpc2tfZmlsZTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gc3RyZWFtOworICAgICAgfQorCisgICAgICBpZiAoZXJybm8gPT0gRUFDQ0VTKSB7CisgICAgICAgIC8vIFRoZSBmaWxlIGV4aXN0cyBidXQgaXMgbm90IHJlYWRhYmxlLgorICAgICAgICBsYXN0X2Vycm9yX21lc3NhZ2VfID0gIlJlYWQgYWNjZXNzIGlzIGRlbmllZCBmb3IgZmlsZTogIiArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wX2Rpc2tfZmlsZTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICB9CisgICAgfQorICB9CisgIGxhc3RfZXJyb3JfbWVzc2FnZV8gPSAiRmlsZSBub3QgZm91bmQuIjsKKyAgcmV0dXJuIE5VTEw7Cit9CisKK2lvOjpaZXJvQ29weUlucHV0U3RyZWFtKiBEaXNrU291cmNlVHJlZTo6T3BlbkRpc2tGaWxlKAorICAgIGNvbnN0IHN0cmluZyYgZmlsZW5hbWUpIHsKKyAgaW50IGZpbGVfZGVzY3JpcHRvcjsKKyAgZG8geworICAgIGZpbGVfZGVzY3JpcHRvciA9IG9wZW4oZmlsZW5hbWUuY19zdHIoKSwgT19SRE9OTFkpOworICB9IHdoaWxlIChmaWxlX2Rlc2NyaXB0b3IgPCAwICYmIGVycm5vID09IEVJTlRSKTsKKyAgaWYgKGZpbGVfZGVzY3JpcHRvciA+PSAwKSB7CisgICAgaW86OkZpbGVJbnB1dFN0cmVhbSogcmVzdWx0ID0gbmV3IGlvOjpGaWxlSW5wdXRTdHJlYW0oZmlsZV9kZXNjcmlwdG9yKTsKKyAgICByZXN1bHQtPlNldENsb3NlT25EZWxldGUodHJ1ZSk7CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorfQorCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9pbXBvcnRlci5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9pbXBvcnRlci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNjOGZjYzMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2ltcG9ydGVyLmgKQEAgLTAsMCArMSwzMjYgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBUaGlzIGZpbGUgaXMgdGhlIHB1YmxpYyBpbnRlcmZhY2UgdG8gdGhlIC5wcm90byBmaWxlIHBhcnNlci4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSU1QT1JURVJfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9JTVBPUlRFUl9IX18KKworI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDx2ZWN0b3I+CisjaW5jbHVkZSA8c2V0PgorI2luY2x1ZGUgPHV0aWxpdHk+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvcl9kYXRhYmFzZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wYXJzZXIuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCituYW1lc3BhY2UgaW8geyBjbGFzcyBaZXJvQ29weUlucHV0U3RyZWFtOyB9CisKK25hbWVzcGFjZSBjb21waWxlciB7CisKKy8vIERlZmluZWQgaW4gdGhpcyBmaWxlLgorY2xhc3MgSW1wb3J0ZXI7CitjbGFzcyBNdWx0aUZpbGVFcnJvckNvbGxlY3RvcjsKK2NsYXNzIFNvdXJjZVRyZWU7CitjbGFzcyBEaXNrU291cmNlVHJlZTsKKworLy8gVE9ETyhrZW50b24pOiAgTW92ZSBhbGwgU291cmNlVHJlZSBzdHVmZiB0byBhIHNlcGFyYXRlIGZpbGU/CisKKy8vIEFuIGltcGxlbWVudGF0aW9uIG9mIERlc2NyaXB0b3JEYXRhYmFzZSB3aGljaCBsb2FkcyBmaWxlcyBmcm9tIGEgU291cmNlVHJlZQorLy8gYW5kIHBhcnNlcyB0aGVtLgorLy8KKy8vIE5vdGU6ICBUaGlzIGNsYXNzIGlzIG5vdCB0aHJlYWQtc2FmZSBzaW5jZSBpdCBtYWludGFpbnMgYSB0YWJsZSBvZiBzb3VyY2UKKy8vICAgY29kZSBsb2NhdGlvbnMgZm9yIGVycm9yIHJlcG9ydGluZy4gIEhvd2V2ZXIsIHdoZW4gYSBEZXNjcmlwdG9yUG9vbCB3cmFwcworLy8gICBhIERlc2NyaXB0b3JEYXRhYmFzZSwgaXQgdXNlcyBtdXRleCBsb2NraW5nIHRvIG1ha2Ugc3VyZSBvbmx5IG9uZSBtZXRob2QKKy8vICAgb2YgdGhlIGRhdGFiYXNlIGlzIGNhbGxlZCBhdCBhIHRpbWUsIGV2ZW4gaWYgdGhlIERlc2NyaXB0b3JQb29sIGlzIHVzZWQKKy8vICAgZnJvbSBtdWx0aXBsZSB0aHJlYWRzLiAgVGhlcmVmb3JlLCB0aGVyZSBpcyBvbmx5IGEgcHJvYmxlbSBpZiB5b3UgY3JlYXRlCisvLyAgIG11bHRpcGxlIERlc2NyaXB0b3JQb29scyB3cmFwcGluZyB0aGUgc2FtZSBTb3VyY2VUcmVlRGVzY3JpcHRvckRhdGFiYXNlCisvLyAgIGFuZCB1c2UgdGhlbSBmcm9tIG11bHRpcGxlIHRocmVhZHMuCisvLworLy8gTm90ZTogIFRoaXMgY2xhc3MgZG9lcyBub3QgaW1wbGVtZW50IEZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbCgpIG9yCisvLyAgIEZpbmRGaWxlQ29udGFpbmluZ0V4dGVuc2lvbigpOyB0aGVzZSB3aWxsIGFsd2F5cyByZXR1cm4gZmFsc2UuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgU291cmNlVHJlZURlc2NyaXB0b3JEYXRhYmFzZSA6IHB1YmxpYyBEZXNjcmlwdG9yRGF0YWJhc2UgeworIHB1YmxpYzoKKyAgU291cmNlVHJlZURlc2NyaXB0b3JEYXRhYmFzZShTb3VyY2VUcmVlKiBzb3VyY2VfdHJlZSk7CisgIH5Tb3VyY2VUcmVlRGVzY3JpcHRvckRhdGFiYXNlKCk7CisKKyAgLy8gSW5zdHJ1Y3RzIHRoZSBTb3VyY2VUcmVlRGVzY3JpcHRvckRhdGFiYXNlIHRvIHJlcG9ydCBhbnkgcGFyc2UgZXJyb3JzCisgIC8vIHRvIHRoZSBnaXZlbiBNdWx0aUZpbGVFcnJvckNvbGxlY3Rvci4gIFRoaXMgc2hvdWxkIGJlIGNhbGxlZCBiZWZvcmUKKyAgLy8gcGFyc2luZy4gIGVycm9yX2NvbGxlY3RvciBtdXN0IHJlbWFpbiB2YWxpZCB1bnRpbCBlaXRoZXIgdGhpcyBtZXRob2QKKyAgLy8gaXMgY2FsbGVkIGFnYWluIG9yIHRoZSBTb3VyY2VUcmVlRGVzY3JpcHRvckRhdGFiYXNlIGlzIGRlc3Ryb3llZC4KKyAgdm9pZCBSZWNvcmRFcnJvcnNUbyhNdWx0aUZpbGVFcnJvckNvbGxlY3RvciogZXJyb3JfY29sbGVjdG9yKSB7CisgICAgZXJyb3JfY29sbGVjdG9yXyA9IGVycm9yX2NvbGxlY3RvcjsKKyAgfQorCisgIC8vIEdldHMgYSBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3Igd2hpY2ggcmVjb3JkcyBlcnJvcnMgdG8gdGhlCisgIC8vIE11bHRpRmlsZUVycm9yQ29sbGVjdG9yIHNwZWNpZmllZCB3aXRoIFJlY29yZEVycm9yc1RvKCkuICBUaGlzIGNvbGxlY3RvcgorICAvLyBoYXMgdGhlIGFiaWxpdHkgdG8gZGV0ZXJtaW5lIGV4YWN0IGxpbmUgYW5kIGNvbHVtbiBudW1iZXJzIG9mIGVycm9ycworICAvLyBmcm9tIHRoZSBpbmZvcm1hdGlvbiBnaXZlbiB0byBpdCBieSB0aGUgRGVzY3JpcHRvclBvb2wuCisgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3RvciogR2V0VmFsaWRhdGlvbkVycm9yQ29sbGVjdG9yKCkgeworICAgIHVzaW5nX3ZhbGlkYXRpb25fZXJyb3JfY29sbGVjdG9yXyA9IHRydWU7CisgICAgcmV0dXJuICZ2YWxpZGF0aW9uX2Vycm9yX2NvbGxlY3Rvcl87CisgIH0KKworICAvLyBpbXBsZW1lbnRzIERlc2NyaXB0b3JEYXRhYmFzZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICBib29sIEZpbmRGaWxlQnlOYW1lKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUsIEZpbGVEZXNjcmlwdG9yUHJvdG8qIG91dHB1dCk7CisgIGJvb2wgRmluZEZpbGVDb250YWluaW5nU3ltYm9sKGNvbnN0IHN0cmluZyYgc3ltYm9sX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8qIG91dHB1dCk7CisgIGJvb2wgRmluZEZpbGVDb250YWluaW5nRXh0ZW5zaW9uKGNvbnN0IHN0cmluZyYgY29udGFpbmluZ190eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZmllbGRfbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlRGVzY3JpcHRvclByb3RvKiBvdXRwdXQpOworCisgcHJpdmF0ZToKKyAgY2xhc3MgU2luZ2xlRmlsZUVycm9yQ29sbGVjdG9yOworCisgIFNvdXJjZVRyZWUqIHNvdXJjZV90cmVlXzsKKyAgTXVsdGlGaWxlRXJyb3JDb2xsZWN0b3IqIGVycm9yX2NvbGxlY3Rvcl87CisKKyAgY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFZhbGlkYXRpb25FcnJvckNvbGxlY3RvciA6IHB1YmxpYyBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3IgeworICAgcHVibGljOgorICAgIFZhbGlkYXRpb25FcnJvckNvbGxlY3RvcihTb3VyY2VUcmVlRGVzY3JpcHRvckRhdGFiYXNlKiBvd25lcik7CisgICAgflZhbGlkYXRpb25FcnJvckNvbGxlY3RvcigpOworCisgICAgLy8gaW1wbGVtZW50cyBFcnJvckNvbGxlY3RvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICB2b2lkIEFkZEVycm9yKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUsCisgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIGVsZW1lbnRfbmFtZSwKKyAgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2UqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICBFcnJvckxvY2F0aW9uIGxvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBtZXNzYWdlKTsKKworICAgIHZpcnR1YWwgdm9pZCBBZGRXYXJuaW5nKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBlbGVtZW50X25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZSogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBFcnJvckxvY2F0aW9uIGxvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgbWVzc2FnZSk7CisKKyAgIHByaXZhdGU6CisgICAgU291cmNlVHJlZURlc2NyaXB0b3JEYXRhYmFzZSogb3duZXJfOworICB9OworICBmcmllbmQgY2xhc3MgVmFsaWRhdGlvbkVycm9yQ29sbGVjdG9yOworCisgIGJvb2wgdXNpbmdfdmFsaWRhdGlvbl9lcnJvcl9jb2xsZWN0b3JfOworICBTb3VyY2VMb2NhdGlvblRhYmxlIHNvdXJjZV9sb2NhdGlvbnNfOworICBWYWxpZGF0aW9uRXJyb3JDb2xsZWN0b3IgdmFsaWRhdGlvbl9lcnJvcl9jb2xsZWN0b3JfOworfTsKKworLy8gU2ltcGxlIGludGVyZmFjZSBmb3IgcGFyc2luZyAucHJvdG8gZmlsZXMuICBUaGlzIHdyYXBzIHRoZSBwcm9jZXNzCisvLyBvZiBvcGVuaW5nIHRoZSBmaWxlLCBwYXJzaW5nIGl0IHdpdGggYSBQYXJzZXIsIHJlY3Vyc2l2ZWx5IHBhcnNpbmcgYWxsIGl0cworLy8gaW1wb3J0cywgYW5kIHRoZW4gY3Jvc3MtbGlua2luZyB0aGUgcmVzdWx0cyB0byBwcm9kdWNlIGEgRmlsZURlc2NyaXB0b3IuCisvLworLy8gVGhpcyBpcyByZWFsbHkganVzdCBhIHRoaW4gd3JhcHBlciBhcm91bmQgU291cmNlVHJlZURlc2NyaXB0b3JEYXRhYmFzZS4KKy8vIFlvdSBtYXkgZmluZCB0aGF0IFNvdXJjZVRyZWVEZXNjcmlwdG9yRGF0YWJhc2UgaXMgbW9yZSBmbGV4aWJsZS4KKy8vCisvLyBUT0RPKGtlbnRvbik6ICBJIGZlZWwgbGlrZSB0aGlzIGNsYXNzIGlzIG5vdCB3ZWxsLW5hbWVkLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEltcG9ydGVyIHsKKyBwdWJsaWM6CisgIEltcG9ydGVyKFNvdXJjZVRyZWUqIHNvdXJjZV90cmVlLAorICAgICAgICAgICBNdWx0aUZpbGVFcnJvckNvbGxlY3RvciogZXJyb3JfY29sbGVjdG9yKTsKKyAgfkltcG9ydGVyKCk7CisKKyAgLy8gSW1wb3J0IHRoZSBnaXZlbiBmaWxlIGFuZCBidWlsZCBhIEZpbGVEZXNjcmlwdG9yIHJlcHJlc2VudGluZyBpdC4gIElmCisgIC8vIHRoZSBmaWxlIGlzIGFscmVhZHkgaW4gdGhlIERlc2NyaXB0b3JQb29sLCB0aGUgZXhpc3RpbmcgRmlsZURlc2NyaXB0b3IKKyAgLy8gd2lsbCBiZSByZXR1cm5lZC4gIFRoZSBGaWxlRGVzY3JpcHRvciBpcyBwcm9wZXJ0eSBvZiB0aGUgRGVzY3JpcHRvclBvb2wsCisgIC8vIGFuZCB3aWxsIHJlbWFpbiB2YWxpZCB1bnRpbCBpdCBpcyBkZXN0cm95ZWQuICBJZiBhbnkgZXJyb3JzIG9jY3VyLCB0aGV5CisgIC8vIHdpbGwgYmUgcmVwb3J0ZWQgdXNpbmcgdGhlIGVycm9yIGNvbGxlY3RvciBhbmQgSW1wb3J0KCkgd2lsbCByZXR1cm4gTlVMTC4KKyAgLy8KKyAgLy8gQSBwYXJ0aWN1bGFyIEltcG9ydGVyIG9iamVjdCB3aWxsIG9ubHkgcmVwb3J0IGVycm9ycyBmb3IgYSBwYXJ0aWN1bGFyCisgIC8vIGZpbGUgb25jZS4gIEFsbCBmdXR1cmUgYXR0ZW1wdHMgdG8gaW1wb3J0IHRoZSBzYW1lIGZpbGUgd2lsbCByZXR1cm4gTlVMTAorICAvLyB3aXRob3V0IHJlcG9ydGluZyBhbnkgZXJyb3JzLiAgVGhlIGlkZWEgaXMgdGhhdCB5b3UgbWlnaHQgd2FudCB0byBpbXBvcnQKKyAgLy8gYSBsb3Qgb2YgZmlsZXMgd2l0aG91dCBzZWVpbmcgdGhlIHNhbWUgZXJyb3JzIG92ZXIgYW5kIG92ZXIgYWdhaW4uICBJZgorICAvLyB5b3Ugd2FudCB0byBzZWUgZXJyb3JzIGZvciB0aGUgc2FtZSBmaWxlcyByZXBlYXRlZGx5LCB5b3UgY2FuIHVzZSBhCisgIC8vIHNlcGFyYXRlIEltcG9ydGVyIG9iamVjdCB0byBpbXBvcnQgZWFjaCBvbmUgKGJ1dCB1c2UgdGhlIHNhbWUKKyAgLy8gRGVzY3JpcHRvclBvb2wgc28gdGhhdCB0aGV5IGNhbiBiZSBjcm9zcy1saW5rZWQpLgorICBjb25zdCBGaWxlRGVzY3JpcHRvciogSW1wb3J0KGNvbnN0IHN0cmluZyYgZmlsZW5hbWUpOworCisgIC8vIFRoZSBEZXNjcmlwdG9yUG9vbCBpbiB3aGljaCBhbGwgaW1wb3J0ZWQgRmlsZURlc2NyaXB0b3JzIGFuZCB0aGVpcgorICAvLyBjb250ZW50cyBhcmUgc3RvcmVkLgorICBpbmxpbmUgY29uc3QgRGVzY3JpcHRvclBvb2wqIHBvb2woKSBjb25zdCB7CisgICAgcmV0dXJuICZwb29sXzsKKyAgfQorCisgIHZvaWQgQWRkVW51c2VkSW1wb3J0VHJhY2tGaWxlKGNvbnN0IHN0cmluZyYgZmlsZV9uYW1lKTsKKyAgdm9pZCBDbGVhclVudXNlZEltcG9ydFRyYWNrRmlsZXMoKTsKKworIHByaXZhdGU6CisgIFNvdXJjZVRyZWVEZXNjcmlwdG9yRGF0YWJhc2UgZGF0YWJhc2VfOworICBEZXNjcmlwdG9yUG9vbCBwb29sXzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoSW1wb3J0ZXIpOworfTsKKworLy8gSWYgdGhlIGltcG9ydGVyIGVuY291bnRlcnMgcHJvYmxlbXMgd2hpbGUgdHJ5aW5nIHRvIGltcG9ydCB0aGUgcHJvdG8gZmlsZXMsCisvLyBpdCByZXBvcnRzIHRoZW0gdG8gYSBNdWx0aUZpbGVFcnJvckNvbGxlY3Rvci4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBNdWx0aUZpbGVFcnJvckNvbGxlY3RvciB7CisgcHVibGljOgorICBpbmxpbmUgTXVsdGlGaWxlRXJyb3JDb2xsZWN0b3IoKSB7fQorICB2aXJ0dWFsIH5NdWx0aUZpbGVFcnJvckNvbGxlY3RvcigpOworCisgIC8vIExpbmUgYW5kIGNvbHVtbiBudW1iZXJzIGFyZSB6ZXJvLWJhc2VkLiAgQSBsaW5lIG51bWJlciBvZiAtMSBpbmRpY2F0ZXMKKyAgLy8gYW4gZXJyb3Igd2l0aCB0aGUgZW50aXJlIGZpbGUgKGUuZy4gIm5vdCBmb3VuZCIpLgorICB2aXJ0dWFsIHZvaWQgQWRkRXJyb3IoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSwgaW50IGxpbmUsIGludCBjb2x1bW4sCisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIG1lc3NhZ2UpID0gMDsKKworICB2aXJ0dWFsIHZvaWQgQWRkV2FybmluZyhjb25zdCBzdHJpbmcmIGZpbGVuYW1lLCBpbnQgbGluZSwgaW50IGNvbHVtbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBtZXNzYWdlKSB7fQorCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKE11bHRpRmlsZUVycm9yQ29sbGVjdG9yKTsKK307CisKKy8vIEFic3RyYWN0IGludGVyZmFjZSB3aGljaCByZXByZXNlbnRzIGEgZGlyZWN0b3J5IHRyZWUgY29udGFpbmluZyBwcm90byBmaWxlcy4KKy8vIFVzZWQgYnkgdGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gb2YgSW1wb3J0ZXIgdG8gcmVzb2x2ZSBpbXBvcnQgc3RhdGVtZW50cworLy8gTW9zdCB1c2VycyB3aWxsIHByb2JhYmx5IHdhbnQgdG8gdXNlIHRoZSBEaXNrU291cmNlVHJlZSBpbXBsZW1lbnRhdGlvbiwKKy8vIGJlbG93LgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFNvdXJjZVRyZWUgeworIHB1YmxpYzoKKyAgaW5saW5lIFNvdXJjZVRyZWUoKSB7fQorICB2aXJ0dWFsIH5Tb3VyY2VUcmVlKCk7CisKKyAgLy8gT3BlbiB0aGUgZ2l2ZW4gZmlsZSBhbmQgcmV0dXJuIGEgc3RyZWFtIHRoYXQgcmVhZHMgaXQsIG9yIE5VTEwgaWYgbm90CisgIC8vIGZvdW5kLiAgVGhlIGNhbGxlciB0YWtlcyBvd25lcnNoaXAgb2YgdGhlIHJldHVybmVkIG9iamVjdC4gIFRoZSBmaWxlbmFtZQorICAvLyBtdXN0IGJlIGEgcGF0aCByZWxhdGl2ZSB0byB0aGUgcm9vdCBvZiB0aGUgc291cmNlIHRyZWUgYW5kIG11c3Qgbm90CisgIC8vIGNvbnRhaW4gIi4iIG9yICIuLiIgY29tcG9uZW50cy4KKyAgdmlydHVhbCBpbzo6WmVyb0NvcHlJbnB1dFN0cmVhbSogT3Blbihjb25zdCBzdHJpbmcmIGZpbGVuYW1lKSA9IDA7CisKKyAgLy8gSWYgT3BlbigpIHJldHVybnMgTlVMTCwgY2FsbGluZyB0aGlzIG1ldGhvZCBpbW1lZGlhdGVseSB3aWxsIHJldHVybiBhbgorICAvLyBkZXNjcmlwdGlvbiBvZiB0aGUgZXJyb3IuCisgIC8vIFN1YmNsYXNzZXMgc2hvdWxkIGltcGxlbWVudCB0aGlzIG1ldGhvZCBhbmQgcmV0dXJuIGEgbWVhbmluZ2Z1bCB2YWx1ZSBmb3IKKyAgLy8gYmV0dGVyIGVycm9yIHJlcG9ydGluZy4KKyAgLy8gVE9ETyh4aWFvZmVuZyk6IGNoYW5nZSB0aGlzIHRvIGEgcHVyZSB2aXJ0dWFsIGZ1bmN0aW9uLgorICB2aXJ0dWFsIHN0cmluZyBHZXRMYXN0RXJyb3JNZXNzYWdlKCk7CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoU291cmNlVHJlZSk7Cit9OworCisvLyBBbiBpbXBsZW1lbnRhdGlvbiBvZiBTb3VyY2VUcmVlIHdoaWNoIGxvYWRzIGZpbGVzIGZyb20gbG9jYXRpb25zIG9uIGRpc2suCisvLyBNdWx0aXBsZSBtYXBwaW5ncyBjYW4gYmUgc2V0IHVwIHRvIG1hcCBsb2NhdGlvbnMgaW4gdGhlIERpc2tTb3VyY2VUcmVlIHRvCisvLyBsb2NhdGlvbnMgaW4gdGhlIHBoeXNpY2FsIGZpbGVzeXN0ZW0uCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgRGlza1NvdXJjZVRyZWUgOiBwdWJsaWMgU291cmNlVHJlZSB7CisgcHVibGljOgorICBEaXNrU291cmNlVHJlZSgpOworICB+RGlza1NvdXJjZVRyZWUoKTsKKworICAvLyBNYXAgYSBwYXRoIG9uIGRpc2sgdG8gYSBsb2NhdGlvbiBpbiB0aGUgU291cmNlVHJlZS4gIFRoZSBwYXRoIG1heSBiZQorICAvLyBlaXRoZXIgYSBmaWxlIG9yIGEgZGlyZWN0b3J5LiAgSWYgaXQgaXMgYSBkaXJlY3RvcnksIHRoZSBlbnRpcmUgdHJlZQorICAvLyB1bmRlciBpdCB3aWxsIGJlIG1hcHBlZCB0byB0aGUgZ2l2ZW4gdmlydHVhbCBsb2NhdGlvbi4gIFRvIG1hcCBhIGRpcmVjdG9yeQorICAvLyB0byB0aGUgcm9vdCBvZiB0aGUgc291cmNlIHRyZWUsIHBhc3MgYW4gZW1wdHkgc3RyaW5nIGZvciB2aXJ0dWFsX3BhdGguCisgIC8vCisgIC8vIElmIG11bHRpcGxlIG1hcHBlZCBwYXRocyBhcHBseSB3aGVuIG9wZW5pbmcgYSBmaWxlLCB0aGV5IHdpbGwgYmUgc2VhcmNoZWQKKyAgLy8gaW4gb3JkZXIuICBGb3IgZXhhbXBsZSwgaWYgeW91IGRvOgorICAvLyAgIE1hcFBhdGgoImJhciIsICJmb28vYmFyIik7CisgIC8vICAgTWFwUGF0aCgiIiwgImJheiIpOworICAvLyBhbmQgdGhlbiB5b3UgZG86CisgIC8vICAgT3BlbigiYmFyL3F1eCIpOworICAvLyB0aGUgRGlza1NvdXJjZVRyZWUgd2lsbCBmaXJzdCB0cnkgdG8gb3BlbiBmb28vYmFyL3F1eCwgdGhlbiBiYXovYmFyL3F1eCwKKyAgLy8gcmV0dXJuaW5nIHRoZSBmaXJzdCBvbmUgdGhhdCBvcGVucyBzdWNjZXNzZnVseS4KKyAgLy8KKyAgLy8gZGlza19wYXRoIG1heSBiZSBhbiBhYnNvbHV0ZSBwYXRoIG9yIHJlbGF0aXZlIHRvIHRoZSBjdXJyZW50IGRpcmVjdG9yeSwKKyAgLy8ganVzdCBsaWtlIGEgcGF0aCB5b3UnZCBwYXNzIHRvIG9wZW4oKS4KKyAgdm9pZCBNYXBQYXRoKGNvbnN0IHN0cmluZyYgdmlydHVhbF9wYXRoLCBjb25zdCBzdHJpbmcmIGRpc2tfcGF0aCk7CisKKyAgLy8gUmV0dXJuIHR5cGUgZm9yIERpc2tGaWxlVG9WaXJ0dWFsRmlsZSgpLgorICBlbnVtIERpc2tGaWxlVG9WaXJ0dWFsRmlsZVJlc3VsdCB7CisgICAgU1VDQ0VTUywKKyAgICBTSEFET1dFRCwKKyAgICBDQU5OT1RfT1BFTiwKKyAgICBOT19NQVBQSU5HCisgIH07CisKKyAgLy8gR2l2ZW4gYSBwYXRoIHRvIGEgZmlsZSBvbiBkaXNrLCBmaW5kIGEgdmlydHVhbCBwYXRoIG1hcHBpbmcgdG8gdGhhdAorICAvLyBmaWxlLiAgVGhlIGZpcnN0IG1hcHBpbmcgY3JlYXRlZCB3aXRoIE1hcFBhdGgoKSB3aG9zZSBkaXNrX3BhdGggY29udGFpbnMKKyAgLy8gdGhlIGZpbGVuYW1lIGlzIHVzZWQuICBIb3dldmVyLCB0aGF0IHZpcnR1YWwgcGF0aCBtYXkgbm90IGFjdHVhbGx5IGJlCisgIC8vIHVzYWJsZSB0byBvcGVuIHRoZSBnaXZlbiBmaWxlLiAgUG9zc2libGUgcmV0dXJuIHZhbHVlcyBhcmU6CisgIC8vICogU1VDQ0VTUzogVGhlIG1hcHBpbmcgd2FzIGZvdW5kLiAgKnZpcnR1YWxfZmlsZSBpcyBmaWxsZWQgaW4gc28gdGhhdAorICAvLyAgIGNhbGxpbmcgT3BlbigqdmlydHVhbF9maWxlKSB3aWxsIG9wZW4gdGhlIGZpbGUgbmFtZWQgYnkgZGlza19maWxlLgorICAvLyAqIFNIQURPV0VEOiBBIG1hcHBpbmcgd2FzIGZvdW5kLCBidXQgdXNpbmcgT3BlbigpIHRvIG9wZW4gdGhpcyB2aXJ0dWFsCisgIC8vICAgcGF0aCB3aWxsIGVuZCB1cCByZXR1cm5pbmcgc29tZSBkaWZmZXJlbnQgZmlsZS4gIFRoaXMgaXMgYmVjYXVzZSBzb21lCisgIC8vICAgb3RoZXIgbWFwcGluZyB3aXRoIGEgaGlnaGVyIHByZWNlZGVuY2UgYWxzbyBtYXRjaGVzIHRoaXMgdmlydHVhbCBwYXRoCisgIC8vICAgYW5kIG1hcHMgaXQgdG8gYSBkaWZmZXJlbnQgZmlsZSB0aGF0IGV4aXN0cyBvbiBkaXNrLiAgKnZpcnR1YWxfZmlsZQorICAvLyAgIGlzIGZpbGxlZCBpbiBhcyBpdCB3b3VsZCBiZSBpbiB0aGUgU1VDQ0VTUyBjYXNlLiAgKnNoYWRvd2luZ19kaXNrX2ZpbGUKKyAgLy8gICBpcyBmaWxsZWQgaW4gd2l0aCB0aGUgZGlzayBwYXRoIG9mIHRoZSBmaWxlIHdoaWNoIHdvdWxkIGJlIG9wZW5lZCBpZgorICAvLyAgIHlvdSB3ZXJlIHRvIGNhbGwgT3BlbigqdmlydHVhbF9maWxlKS4KKyAgLy8gKiBDQU5OT1RfT1BFTjogVGhlIG1hcHBpbmcgd2FzIGZvdW5kIGFuZCB3YXMgbm90IHNoYWRvd2VkLCBidXQgdGhlCisgIC8vICAgZmlsZSBzcGVjaWZpZWQgY2Fubm90IGJlIG9wZW5lZC4gIFdoZW4gdGhpcyB2YWx1ZSBpcyByZXR1cm5lZCwKKyAgLy8gICBlcnJubyB3aWxsIGluZGljYXRlIHRoZSByZWFzb24gdGhlIGZpbGUgY2Fubm90IGJlIG9wZW5lZC4gICp2aXJ0dWFsX2ZpbGUKKyAgLy8gICB3aWxsIGJlIHNldCB0byB0aGUgdmlydHVhbCBwYXRoIGFzIGluIHRoZSBTVUNDRVNTIGNhc2UsIGV2ZW4gdGhvdWdoCisgIC8vICAgaXQgaXMgbm90IHVzZWZ1bC4KKyAgLy8gKiBOT19NQVBQSU5HOiBJbmRpY2F0ZXMgdGhhdCBubyBtYXBwaW5nIHdhcyBmb3VuZCB3aGljaCBjb250YWlucyB0aGlzCisgIC8vICAgZmlsZS4KKyAgRGlza0ZpbGVUb1ZpcnR1YWxGaWxlUmVzdWx0CisgICAgRGlza0ZpbGVUb1ZpcnR1YWxGaWxlKGNvbnN0IHN0cmluZyYgZGlza19maWxlLAorICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcqIHZpcnR1YWxfZmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nKiBzaGFkb3dpbmdfZGlza19maWxlKTsKKworICAvLyBHaXZlbiBhIHZpcnR1YWwgcGF0aCwgZmluZCB0aGUgcGF0aCB0byB0aGUgZmlsZSBvbiBkaXNrLgorICAvLyBSZXR1cm4gdHJ1ZSBhbmQgdXBkYXRlIGRpc2tfZmlsZSB3aXRoIHRoZSBvbi1kaXNrIHBhdGggaWYgdGhlIGZpbGUgZXhpc3RzLgorICAvLyBSZXR1cm4gZmFsc2UgYW5kIGxlYXZlIGRpc2tfZmlsZSB1bnRvdWNoZWQgaWYgdGhlIGZpbGUgZG9lc24ndCBleGlzdC4KKyAgYm9vbCBWaXJ0dWFsRmlsZVRvRGlza0ZpbGUoY29uc3Qgc3RyaW5nJiB2aXJ0dWFsX2ZpbGUsIHN0cmluZyogZGlza19maWxlKTsKKworICAvLyBpbXBsZW1lbnRzIFNvdXJjZVRyZWUgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICB2aXJ0dWFsIGlvOjpaZXJvQ29weUlucHV0U3RyZWFtKiBPcGVuKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUpOworCisgIHZpcnR1YWwgc3RyaW5nIEdldExhc3RFcnJvck1lc3NhZ2UoKTsKKworIHByaXZhdGU6CisgIHN0cnVjdCBNYXBwaW5nIHsKKyAgICBzdHJpbmcgdmlydHVhbF9wYXRoOworICAgIHN0cmluZyBkaXNrX3BhdGg7CisKKyAgICBpbmxpbmUgTWFwcGluZyhjb25zdCBzdHJpbmcmIHZpcnR1YWxfcGF0aF9wYXJhbSwKKyAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIGRpc2tfcGF0aF9wYXJhbSkKKyAgICAgIDogdmlydHVhbF9wYXRoKHZpcnR1YWxfcGF0aF9wYXJhbSksIGRpc2tfcGF0aChkaXNrX3BhdGhfcGFyYW0pIHt9CisgIH07CisgIHZlY3RvcjxNYXBwaW5nPiBtYXBwaW5nc187CisgIHN0cmluZyBsYXN0X2Vycm9yX21lc3NhZ2VfOworCisgIC8vIExpa2UgT3BlbigpLCBidXQgcmV0dXJucyB0aGUgb24tZGlzayBwYXRoIGluIGRpc2tfZmlsZSBpZiBkaXNrX2ZpbGUgaXMKKyAgLy8gbm9uLU5VTEwgYW5kIHRoZSBmaWxlIGNvdWxkIGJlIHN1Y2Nlc3NmdWxseSBvcGVuZWQuCisgIGlvOjpaZXJvQ29weUlucHV0U3RyZWFtKiBPcGVuVmlydHVhbEZpbGUoY29uc3Qgc3RyaW5nJiB2aXJ0dWFsX2ZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nKiBkaXNrX2ZpbGUpOworCisgIC8vIExpa2UgT3BlbigpIGJ1dCBnaXZlbiB0aGUgYWN0dWFsIG9uLWRpc2sgcGF0aC4KKyAgaW86Olplcm9Db3B5SW5wdXRTdHJlYW0qIE9wZW5EaXNrRmlsZShjb25zdCBzdHJpbmcmIGZpbGVuYW1lKTsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoRGlza1NvdXJjZVRyZWUpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSU1QT1JURVJfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2ltcG9ydGVyX3VuaXR0ZXN0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9pbXBvcnRlcl91bml0dGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iZTE5YWEyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9pbXBvcnRlcl91bml0dGVzdC5jYwpAQCAtMCwwICsxLDUyMiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2hhc2guaD4KKyNpbmNsdWRlIDxtZW1vcnk+CisjaWZuZGVmIF9TSEFSRURfUFRSX0gKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc2hhcmVkX3B0ci5oPgorI2VuZGlmCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvaW1wb3J0ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2ZpbGUuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbV9pbXBsLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbWFwX3V0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbG9nZ2luZy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9maWxlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3Vic3RpdHV0ZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2dvb2dsZXRlc3QuaD4KKyNpbmNsdWRlIDxndGVzdC9ndGVzdC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworCituYW1lc3BhY2UgeworCitib29sIEZpbGVFeGlzdHMoY29uc3Qgc3RyaW5nJiBwYXRoKSB7CisgIHJldHVybiBGaWxlOjpFeGlzdHMocGF0aCk7Cit9CisKKyNkZWZpbmUgRVhQRUNUX1NVQlNUUklORyhuZWVkbGUsIGhheXN0YWNrKSBcCisgIEVYUEVDVF9QUkVEX0ZPUk1BVDIodGVzdGluZzo6SXNTdWJzdHJpbmcsIChuZWVkbGUpLCAoaGF5c3RhY2spKQorCitjbGFzcyBNb2NrRXJyb3JDb2xsZWN0b3IgOiBwdWJsaWMgTXVsdGlGaWxlRXJyb3JDb2xsZWN0b3IgeworIHB1YmxpYzoKKyAgTW9ja0Vycm9yQ29sbGVjdG9yKCkge30KKyAgfk1vY2tFcnJvckNvbGxlY3RvcigpIHt9CisKKyAgc3RyaW5nIHRleHRfOworICBzdHJpbmcgd2FybmluZ190ZXh0XzsKKworICAvLyBpbXBsZW1lbnRzIEVycm9yQ29sbGVjdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICB2b2lkIEFkZEVycm9yKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUsIGludCBsaW5lLCBpbnQgY29sdW1uLAorICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgbWVzc2FnZSkgeworICAgIHN0cmluZ3M6OlN1YnN0aXR1dGVBbmRBcHBlbmQoJnRleHRfLCAiJDA6JDE6JDI6ICQzXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZW5hbWUsIGxpbmUsIGNvbHVtbiwgbWVzc2FnZSk7CisgIH0KKworICB2b2lkIEFkZFdhcm5pbmcoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSwgaW50IGxpbmUsIGludCBjb2x1bW4sCisgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIG1lc3NhZ2UpIHsKKyAgICBzdHJpbmdzOjpTdWJzdGl0dXRlQW5kQXBwZW5kKCZ3YXJuaW5nX3RleHRfLCAiJDA6JDE6JDI6ICQzXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZW5hbWUsIGxpbmUsIGNvbHVtbiwgbWVzc2FnZSk7CisgIH0KK307CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gQSBkdW1teSBpbXBsZW1lbnRhdGlvbiBvZiBTb3VyY2VUcmVlIGJhY2tlZCBieSBhIHNpbXBsZSBtYXAuCitjbGFzcyBNb2NrU291cmNlVHJlZSA6IHB1YmxpYyBTb3VyY2VUcmVlIHsKKyBwdWJsaWM6CisgIE1vY2tTb3VyY2VUcmVlKCkge30KKyAgfk1vY2tTb3VyY2VUcmVlKCkge30KKworICB2b2lkIEFkZEZpbGUoY29uc3Qgc3RyaW5nJiBuYW1lLCBjb25zdCBjaGFyKiBjb250ZW50cykgeworICAgIGZpbGVzX1tuYW1lXSA9IGNvbnRlbnRzOworICB9CisKKyAgLy8gaW1wbGVtZW50cyBTb3VyY2VUcmVlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgaW86Olplcm9Db3B5SW5wdXRTdHJlYW0qIE9wZW4oY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSkgeworICAgIGNvbnN0IGNoYXIqIGNvbnRlbnRzID0gRmluZFB0ck9yTnVsbChmaWxlc18sIGZpbGVuYW1lKTsKKyAgICBpZiAoY29udGVudHMgPT0gTlVMTCkgeworICAgICAgcmV0dXJuIE5VTEw7CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiBuZXcgaW86OkFycmF5SW5wdXRTdHJlYW0oY29udGVudHMsIHN0cmxlbihjb250ZW50cykpOworICAgIH0KKyAgfQorCisgIHN0cmluZyBHZXRMYXN0RXJyb3JNZXNzYWdlKCkgeworICAgIHJldHVybiAiRmlsZSBub3QgZm91bmQuIjsKKyAgfQorCisgcHJpdmF0ZToKKyAgaGFzaF9tYXA8c3RyaW5nLCBjb25zdCBjaGFyKj4gZmlsZXNfOworfTsKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitjbGFzcyBJbXBvcnRlclRlc3QgOiBwdWJsaWMgdGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICBJbXBvcnRlclRlc3QoKQorICAgIDogaW1wb3J0ZXJfKCZzb3VyY2VfdHJlZV8sICZlcnJvcl9jb2xsZWN0b3JfKSB7fQorCisgIHZvaWQgQWRkRmlsZShjb25zdCBzdHJpbmcmIGZpbGVuYW1lLCBjb25zdCBjaGFyKiB0ZXh0KSB7CisgICAgc291cmNlX3RyZWVfLkFkZEZpbGUoZmlsZW5hbWUsIHRleHQpOworICB9CisKKyAgLy8gUmV0dXJuIHRoZSBjb2xsZWN0ZWQgZXJyb3IgdGV4dAorICBzdHJpbmcgZXJyb3IoKSBjb25zdCB7IHJldHVybiBlcnJvcl9jb2xsZWN0b3JfLnRleHRfOyB9CisgIHN0cmluZyB3YXJuaW5nKCkgY29uc3QgeyByZXR1cm4gZXJyb3JfY29sbGVjdG9yXy53YXJuaW5nX3RleHRfOyB9CisKKyAgTW9ja0Vycm9yQ29sbGVjdG9yIGVycm9yX2NvbGxlY3Rvcl87CisgIE1vY2tTb3VyY2VUcmVlIHNvdXJjZV90cmVlXzsKKyAgSW1wb3J0ZXIgaW1wb3J0ZXJfOworfTsKKworVEVTVF9GKEltcG9ydGVyVGVzdCwgSW1wb3J0KSB7CisgIC8vIFRlc3Qgbm9ybWFsIGltcG9ydGluZy4KKyAgQWRkRmlsZSgiZm9vLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAibWVzc2FnZSBGb28ge31cbiIpOworCisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlID0gaW1wb3J0ZXJfLkltcG9ydCgiZm9vLnByb3RvIik7CisgIEVYUEVDVF9FUSgiIiwgZXJyb3JfY29sbGVjdG9yXy50ZXh0Xyk7CisgIEFTU0VSVF9UUlVFKGZpbGUgIT0gTlVMTCk7CisKKyAgQVNTRVJUX0VRKDEsIGZpbGUtPm1lc3NhZ2VfdHlwZV9jb3VudCgpKTsKKyAgRVhQRUNUX0VRKCJGb28iLCBmaWxlLT5tZXNzYWdlX3R5cGUoMCktPm5hbWUoKSk7CisKKyAgLy8gSW1wb3J0aW5nIGFnYWluIHNob3VsZCByZXR1cm4gc2FtZSBvYmplY3QuCisgIEVYUEVDVF9FUShmaWxlLCBpbXBvcnRlcl8uSW1wb3J0KCJmb28ucHJvdG8iKSk7Cit9CisKK1RFU1RfRihJbXBvcnRlclRlc3QsIEltcG9ydE5lc3RlZCkgeworICAvLyBUZXN0IHRoYXQgaW1wb3J0aW5nIGEgZmlsZSB3aGljaCBpbXBvcnRzIGFub3RoZXIgZmlsZSB3b3Jrcy4KKyAgQWRkRmlsZSgiZm9vLnByb3RvIiwKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAiaW1wb3J0IFwiYmFyLnByb3RvXCI7XG4iCisgICAgIm1lc3NhZ2UgRm9vIHtcbiIKKyAgICAiICBvcHRpb25hbCBCYXIgYmFyID0gMTtcbiIKKyAgICAifVxuIik7CisgIEFkZEZpbGUoImJhci5wcm90byIsCisgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgIm1lc3NhZ2UgQmFyIHt9XG4iKTsKKworICAvLyBOb3RlIHRoYXQgYm90aCBmaWxlcyBhcmUgYWN0dWFsbHkgcGFyc2VkIGJ5IHRoZSBmaXJzdCBjYWxsIHRvIEltcG9ydCgpCisgIC8vIGhlcmUsIHNpbmNlIGZvby5wcm90byBpbXBvcnRzIGJhci5wcm90by4gIFRoZSBzZWNvbmQgY2FsbCBqdXN0IHJldHVybnMKKyAgLy8gdGhlIHNhbWUgUHJvdG9GaWxlIGZvciBiYXIucHJvdG8gd2hpY2ggd2FzIGNvbnN0cnVjdGVkIHdoaWxlIGltcG9ydGluZworICAvLyBmb28ucHJvdG8uICBXZSB0ZXN0IHRoYXQgdGhpcyBpcyB0aGUgY2FzZSBiZWxvdyBieSBjaGVja2luZyB0aGF0IGJhcgorICAvLyBpcyBhbW9uZyBmb28ncyBkZXBlbmRlbmNpZXMgKGJ5IHBvaW50ZXIpLgorICBjb25zdCBGaWxlRGVzY3JpcHRvciogZm9vID0gaW1wb3J0ZXJfLkltcG9ydCgiZm9vLnByb3RvIik7CisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBiYXIgPSBpbXBvcnRlcl8uSW1wb3J0KCJiYXIucHJvdG8iKTsKKyAgRVhQRUNUX0VRKCIiLCBlcnJvcl9jb2xsZWN0b3JfLnRleHRfKTsKKyAgQVNTRVJUX1RSVUUoZm9vICE9IE5VTEwpOworICBBU1NFUlRfVFJVRShiYXIgIT0gTlVMTCk7CisKKyAgLy8gQ2hlY2sgdGhhdCBmb28ncyBkZXBlbmRlbmN5IGlzIHRoZSBzYW1lIG9iamVjdCBhcyBiYXIuCisgIEFTU0VSVF9FUSgxLCBmb28tPmRlcGVuZGVuY3lfY291bnQoKSk7CisgIEVYUEVDVF9FUShiYXIsIGZvby0+ZGVwZW5kZW5jeSgwKSk7CisKKyAgLy8gQ2hlY2sgdGhhdCBmb28gcHJvcGVybHkgY3Jvc3MtbGlua3MgYmFyLgorICBBU1NFUlRfRVEoMSwgZm9vLT5tZXNzYWdlX3R5cGVfY291bnQoKSk7CisgIEFTU0VSVF9FUSgxLCBiYXItPm1lc3NhZ2VfdHlwZV9jb3VudCgpKTsKKyAgQVNTRVJUX0VRKDEsIGZvby0+bWVzc2FnZV90eXBlKDApLT5maWVsZF9jb3VudCgpKTsKKyAgQVNTRVJUX0VRKEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9NRVNTQUdFLAorICAgICAgICAgICAgZm9vLT5tZXNzYWdlX3R5cGUoMCktPmZpZWxkKDApLT50eXBlKCkpOworICBFWFBFQ1RfRVEoYmFyLT5tZXNzYWdlX3R5cGUoMCksCisgICAgICAgICAgICBmb28tPm1lc3NhZ2VfdHlwZSgwKS0+ZmllbGQoMCktPm1lc3NhZ2VfdHlwZSgpKTsKK30KKworVEVTVF9GKEltcG9ydGVyVGVzdCwgRmlsZU5vdEZvdW5kKSB7CisgIC8vIEVycm9yOiAgUGFyc2luZyBhIGZpbGUgdGhhdCBkb2Vzbid0IGV4aXN0LgorICBFWFBFQ1RfVFJVRShpbXBvcnRlcl8uSW1wb3J0KCJmb28ucHJvdG8iKSA9PSBOVUxMKTsKKyAgRVhQRUNUX0VRKAorICAgICJmb28ucHJvdG86LTE6MDogRmlsZSBub3QgZm91bmQuXG4iLAorICAgIGVycm9yX2NvbGxlY3Rvcl8udGV4dF8pOworfQorCitURVNUX0YoSW1wb3J0ZXJUZXN0LCBJbXBvcnROb3RGb3VuZCkgeworICAvLyBFcnJvcjogIEltcG9ydGluZyBhIGZpbGUgdGhhdCBkb2Vzbid0IGV4aXN0LgorICBBZGRGaWxlKCJmb28ucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJpbXBvcnQgXCJiYXIucHJvdG9cIjtcbiIpOworCisgIEVYUEVDVF9UUlVFKGltcG9ydGVyXy5JbXBvcnQoImZvby5wcm90byIpID09IE5VTEwpOworICBFWFBFQ1RfRVEoCisgICAgImJhci5wcm90bzotMTowOiBGaWxlIG5vdCBmb3VuZC5cbiIKKyAgICAiZm9vLnByb3RvOi0xOjA6IEltcG9ydCBcImJhci5wcm90b1wiIHdhcyBub3QgZm91bmQgb3IgaGFkIGVycm9ycy5cbiIsCisgICAgZXJyb3JfY29sbGVjdG9yXy50ZXh0Xyk7Cit9CisKK1RFU1RfRihJbXBvcnRlclRlc3QsIFJlY3Vyc2l2ZUltcG9ydCkgeworICAvLyBFcnJvcjogIFJlY3Vyc2l2ZSBpbXBvcnQuCisgIEFkZEZpbGUoInJlY3Vyc2l2ZTEucHJvdG8iLAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICJpbXBvcnQgXCJyZWN1cnNpdmUyLnByb3RvXCI7XG4iKTsKKyAgQWRkRmlsZSgicmVjdXJzaXZlMi5wcm90byIsCisgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgImltcG9ydCBcInJlY3Vyc2l2ZTEucHJvdG9cIjtcbiIpOworCisgIEVYUEVDVF9UUlVFKGltcG9ydGVyXy5JbXBvcnQoInJlY3Vyc2l2ZTEucHJvdG8iKSA9PSBOVUxMKTsKKyAgRVhQRUNUX0VRKAorICAgICJyZWN1cnNpdmUxLnByb3RvOi0xOjA6IEZpbGUgcmVjdXJzaXZlbHkgaW1wb3J0cyBpdHNlbGY6IHJlY3Vyc2l2ZTEucHJvdG8gIgorICAgICAgIi0+IHJlY3Vyc2l2ZTIucHJvdG8gLT4gcmVjdXJzaXZlMS5wcm90b1xuIgorICAgICJyZWN1cnNpdmUyLnByb3RvOi0xOjA6IEltcG9ydCBcInJlY3Vyc2l2ZTEucHJvdG9cIiB3YXMgbm90IGZvdW5kICIKKyAgICAgICJvciBoYWQgZXJyb3JzLlxuIgorICAgICJyZWN1cnNpdmUxLnByb3RvOi0xOjA6IEltcG9ydCBcInJlY3Vyc2l2ZTIucHJvdG9cIiB3YXMgbm90IGZvdW5kICIKKyAgICAgICJvciBoYWQgZXJyb3JzLlxuIiwKKyAgICBlcnJvcl9jb2xsZWN0b3JfLnRleHRfKTsKK30KKworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK2NsYXNzIERpc2tTb3VyY2VUcmVlVGVzdCA6IHB1YmxpYyB0ZXN0aW5nOjpUZXN0IHsKKyBwcm90ZWN0ZWQ6CisgIHZpcnR1YWwgdm9pZCBTZXRVcCgpIHsKKyAgICBkaXJuYW1lc18ucHVzaF9iYWNrKFRlc3RUZW1wRGlyKCkgKyAiL3Rlc3RfcHJvdG8yX2ltcG9ydF9wYXRoXzEiKTsKKyAgICBkaXJuYW1lc18ucHVzaF9iYWNrKFRlc3RUZW1wRGlyKCkgKyAiL3Rlc3RfcHJvdG8yX2ltcG9ydF9wYXRoXzIiKTsKKworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGlybmFtZXNfLnNpemUoKTsgaSsrKSB7CisgICAgICBpZiAoRmlsZUV4aXN0cyhkaXJuYW1lc19baV0pKSB7CisgICAgICAgIEZpbGU6OkRlbGV0ZVJlY3Vyc2l2ZWx5KGRpcm5hbWVzX1tpXSwgTlVMTCwgTlVMTCk7CisgICAgICB9CisgICAgICBHT09HTEVfQ0hFQ0tfT0soRmlsZTo6Q3JlYXRlRGlyKGRpcm5hbWVzX1tpXSwgMDc3NykpOworICAgIH0KKyAgfQorCisgIHZpcnR1YWwgdm9pZCBUZWFyRG93bigpIHsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGRpcm5hbWVzXy5zaXplKCk7IGkrKykgeworICAgICAgaWYgKEZpbGVFeGlzdHMoZGlybmFtZXNfW2ldKSkgeworICAgICAgICBGaWxlOjpEZWxldGVSZWN1cnNpdmVseShkaXJuYW1lc19baV0sIE5VTEwsIE5VTEwpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIHZvaWQgQWRkRmlsZShjb25zdCBzdHJpbmcmIGZpbGVuYW1lLCBjb25zdCBjaGFyKiBjb250ZW50cykgeworICAgIEdPT0dMRV9DSEVDS19PSyhGaWxlOjpTZXRDb250ZW50cyhmaWxlbmFtZSwgY29udGVudHMsIHRydWUpKTsKKyAgfQorCisgIHZvaWQgQWRkU3ViZGlyKGNvbnN0IHN0cmluZyYgZGlybmFtZSkgeworICAgIEdPT0dMRV9DSEVDS19PSyhGaWxlOjpDcmVhdGVEaXIoZGlybmFtZSwgMDc3NykpOworICB9CisKKyAgdm9pZCBFeHBlY3RGaWxlQ29udGVudHMoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogZXhwZWN0ZWRfY29udGVudHMpIHsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPGlvOjpaZXJvQ29weUlucHV0U3RyZWFtPiBpbnB1dChzb3VyY2VfdHJlZV8uT3BlbihmaWxlbmFtZSkpOworCisgICAgQVNTRVJUX0ZBTFNFKGlucHV0ID09IE5VTEwpOworCisgICAgLy8gUmVhZCBhbGwgdGhlIGRhdGEgZnJvbSB0aGUgZmlsZS4KKyAgICBzdHJpbmcgZmlsZV9jb250ZW50czsKKyAgICBjb25zdCB2b2lkKiBkYXRhOworICAgIGludCBzaXplOworICAgIHdoaWxlIChpbnB1dC0+TmV4dCgmZGF0YSwgJnNpemUpKSB7CisgICAgICBmaWxlX2NvbnRlbnRzLmFwcGVuZChyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPihkYXRhKSwgc2l6ZSk7CisgICAgfQorCisgICAgRVhQRUNUX0VRKGV4cGVjdGVkX2NvbnRlbnRzLCBmaWxlX2NvbnRlbnRzKTsKKyAgfQorCisgIHZvaWQgRXhwZWN0Q2Fubm90T3BlbkZpbGUoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIGVycm9yX21lc3NhZ2UpIHsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPGlvOjpaZXJvQ29weUlucHV0U3RyZWFtPiBpbnB1dChzb3VyY2VfdHJlZV8uT3BlbihmaWxlbmFtZSkpOworICAgIEVYUEVDVF9UUlVFKGlucHV0ID09IE5VTEwpOworICAgIEVYUEVDVF9FUShlcnJvcl9tZXNzYWdlLCBzb3VyY2VfdHJlZV8uR2V0TGFzdEVycm9yTWVzc2FnZSgpKTsKKyAgfQorCisgIERpc2tTb3VyY2VUcmVlIHNvdXJjZV90cmVlXzsKKworICAvLyBQYXRocyBvZiB0d28gb24tZGlzayBkaXJlY3RvcmllcyB0byB1c2UgZHVyaW5nIHRoZSB0ZXN0LgorICB2ZWN0b3I8c3RyaW5nPiBkaXJuYW1lc187Cit9OworCitURVNUX0YoRGlza1NvdXJjZVRyZWVUZXN0LCBNYXBSb290KSB7CisgIC8vIFRlc3Qgb3BlbmluZyBhIGZpbGUgaW4gYSBkaXJlY3RvcnkgdGhhdCBpcyBtYXBwZWQgdG8gdGhlIHJvb3Qgb2YgdGhlCisgIC8vIHNvdXJjZSB0cmVlLgorICBBZGRGaWxlKGRpcm5hbWVzX1swXSArICIvZm9vIiwgIkhlbGxvIFdvcmxkISIpOworICBzb3VyY2VfdHJlZV8uTWFwUGF0aCgiIiwgZGlybmFtZXNfWzBdKTsKKworICBFeHBlY3RGaWxlQ29udGVudHMoImZvbyIsICJIZWxsbyBXb3JsZCEiKTsKKyAgRXhwZWN0Q2Fubm90T3BlbkZpbGUoImJhciIsICJGaWxlIG5vdCBmb3VuZC4iKTsKK30KKworVEVTVF9GKERpc2tTb3VyY2VUcmVlVGVzdCwgTWFwRGlyZWN0b3J5KSB7CisgIC8vIFRlc3Qgb3BlbmluZyBhIGZpbGUgaW4gYSBkaXJlY3RvcnkgdGhhdCBpcyBtYXBwZWQgdG8gc29tZXdoZXJlIG90aGVyCisgIC8vIHRoYW4gdGhlIHJvb3Qgb2YgdGhlIHNvdXJjZSB0cmVlLgorCisgIEFkZEZpbGUoZGlybmFtZXNfWzBdICsgIi9mb28iLCAiSGVsbG8gV29ybGQhIik7CisgIHNvdXJjZV90cmVlXy5NYXBQYXRoKCJiYXoiLCBkaXJuYW1lc19bMF0pOworCisgIEV4cGVjdEZpbGVDb250ZW50cygiYmF6L2ZvbyIsICJIZWxsbyBXb3JsZCEiKTsKKyAgRXhwZWN0Q2Fubm90T3BlbkZpbGUoImJhei9iYXIiLCAiRmlsZSBub3QgZm91bmQuIik7CisgIEV4cGVjdENhbm5vdE9wZW5GaWxlKCJmb28iLCAiRmlsZSBub3QgZm91bmQuIik7CisgIEV4cGVjdENhbm5vdE9wZW5GaWxlKCJiYXIiLCAiRmlsZSBub3QgZm91bmQuIik7CisKKyAgLy8gTm9uLWNhbm9uaWNhbCBmaWxlIG5hbWVzIHNob3VsZCBub3Qgd29yay4KKyAgRXhwZWN0Q2Fubm90T3BlbkZpbGUoImJhei8vZm9vIiwKKyAgICAgICAgICAgICAgICAgICAgICAgIkJhY2tzbGFzaGVzLCBjb25zZWN1dGl2ZSBzbGFzaGVzLCBcIi5cIiwgb3IgXCIuLlwiIGFyZSAiCisgICAgICAgICAgICAgICAgICAgICAgICJub3QgYWxsb3dlZCBpbiB0aGUgdmlydHVhbCBwYXRoIik7CisgIEV4cGVjdENhbm5vdE9wZW5GaWxlKCJiYXovLi4vYmF6L2ZvbyIsCisgICAgICAgICAgICAgICAgICAgICAgICJCYWNrc2xhc2hlcywgY29uc2VjdXRpdmUgc2xhc2hlcywgXCIuXCIsIG9yIFwiLi5cIiBhcmUgIgorICAgICAgICAgICAgICAgICAgICAgICAibm90IGFsbG93ZWQgaW4gdGhlIHZpcnR1YWwgcGF0aCIpOworICBFeHBlY3RDYW5ub3RPcGVuRmlsZSgiYmF6Ly4vZm9vIiwKKyAgICAgICAgICAgICAgICAgICAgICAgIkJhY2tzbGFzaGVzLCBjb25zZWN1dGl2ZSBzbGFzaGVzLCBcIi5cIiwgb3IgXCIuLlwiIGFyZSAiCisgICAgICAgICAgICAgICAgICAgICAgICJub3QgYWxsb3dlZCBpbiB0aGUgdmlydHVhbCBwYXRoIik7CisgIEV4cGVjdENhbm5vdE9wZW5GaWxlKCJiYXovZm9vLyIsICJGaWxlIG5vdCBmb3VuZC4iKTsKK30KKworVEVTVF9GKERpc2tTb3VyY2VUcmVlVGVzdCwgTm9QYXJlbnQpIHsKKyAgLy8gVGVzdCB0aGF0IHdlIGNhbm5vdCBvcGVuIGZpbGVzIGluIGEgcGFyZW50IG9mIGEgbWFwcGVkIGRpcmVjdG9yeS4KKworICBBZGRGaWxlKGRpcm5hbWVzX1swXSArICIvZm9vIiwgIkhlbGxvIFdvcmxkISIpOworICBBZGRTdWJkaXIoZGlybmFtZXNfWzBdICsgIi9iYXIiKTsKKyAgQWRkRmlsZShkaXJuYW1lc19bMF0gKyAiL2Jhci9iYXoiLCAiQmxhaC4iKTsKKyAgc291cmNlX3RyZWVfLk1hcFBhdGgoIiIsIGRpcm5hbWVzX1swXSArICIvYmFyIik7CisKKyAgRXhwZWN0RmlsZUNvbnRlbnRzKCJiYXoiLCAiQmxhaC4iKTsKKyAgRXhwZWN0Q2Fubm90T3BlbkZpbGUoIi4uL2ZvbyIsCisgICAgICAgICAgICAgICAgICAgICAgICJCYWNrc2xhc2hlcywgY29uc2VjdXRpdmUgc2xhc2hlcywgXCIuXCIsIG9yIFwiLi5cIiBhcmUgIgorICAgICAgICAgICAgICAgICAgICAgICAibm90IGFsbG93ZWQgaW4gdGhlIHZpcnR1YWwgcGF0aCIpOworICBFeHBlY3RDYW5ub3RPcGVuRmlsZSgiLi4vYmFyL2JheiIsCisgICAgICAgICAgICAgICAgICAgICAgICJCYWNrc2xhc2hlcywgY29uc2VjdXRpdmUgc2xhc2hlcywgXCIuXCIsIG9yIFwiLi5cIiBhcmUgIgorICAgICAgICAgICAgICAgICAgICAgICAibm90IGFsbG93ZWQgaW4gdGhlIHZpcnR1YWwgcGF0aCIpOworfQorCitURVNUX0YoRGlza1NvdXJjZVRyZWVUZXN0LCBNYXBGaWxlKSB7CisgIC8vIFRlc3Qgb3BlbmluZyBhIGZpbGUgdGhhdCBpcyBtYXBwZWQgZGlyZWN0bHkgaW50byB0aGUgc291cmNlIHRyZWUuCisKKyAgQWRkRmlsZShkaXJuYW1lc19bMF0gKyAiL2ZvbyIsICJIZWxsbyBXb3JsZCEiKTsKKyAgc291cmNlX3RyZWVfLk1hcFBhdGgoImZvbyIsIGRpcm5hbWVzX1swXSArICIvZm9vIik7CisKKyAgRXhwZWN0RmlsZUNvbnRlbnRzKCJmb28iLCAiSGVsbG8gV29ybGQhIik7CisgIEV4cGVjdENhbm5vdE9wZW5GaWxlKCJiYXIiLCAiRmlsZSBub3QgZm91bmQuIik7Cit9CisKK1RFU1RfRihEaXNrU291cmNlVHJlZVRlc3QsIFNlYXJjaE11bHRpcGxlRGlyZWN0b3JpZXMpIHsKKyAgLy8gVGVzdCBtYXBwaW5nIGFuZCBzZWFyY2hpbmcgbXVsdGlwbGUgZGlyZWN0b3JpZXMuCisKKyAgQWRkRmlsZShkaXJuYW1lc19bMF0gKyAiL2ZvbyIsICJIZWxsbyBXb3JsZCEiKTsKKyAgQWRkRmlsZShkaXJuYW1lc19bMV0gKyAiL2ZvbyIsICJUaGlzIGZpbGUgc2hvdWxkIGJlIGhpZGRlbi4iKTsKKyAgQWRkRmlsZShkaXJuYW1lc19bMV0gKyAiL2JhciIsICJHb29kYnllIFdvcmxkISIpOworICBzb3VyY2VfdHJlZV8uTWFwUGF0aCgiIiwgZGlybmFtZXNfWzBdKTsKKyAgc291cmNlX3RyZWVfLk1hcFBhdGgoIiIsIGRpcm5hbWVzX1sxXSk7CisKKyAgRXhwZWN0RmlsZUNvbnRlbnRzKCJmb28iLCAiSGVsbG8gV29ybGQhIik7CisgIEV4cGVjdEZpbGVDb250ZW50cygiYmFyIiwgIkdvb2RieWUgV29ybGQhIik7CisgIEV4cGVjdENhbm5vdE9wZW5GaWxlKCJiYXoiLCAiRmlsZSBub3QgZm91bmQuIik7Cit9CisKK1RFU1RfRihEaXNrU291cmNlVHJlZVRlc3QsIE9yZGVyaW5nVHJ1bXBzU3BlY2lmaWNpdHkpIHsKKyAgLy8gVGVzdCB0aGF0IGRpcmVjdG9yaWVzIGFyZSBhbHdheXMgc2VhcmNoZWQgaW4gb3JkZXIsIGV2ZW4gd2hlbiBhIGxhdHRlcgorICAvLyBkaXJlY3RvcnkgaXMgbW9yZS1zcGVjaWZpYyB0aGFuIGEgZm9ybWVyIG9uZS4KKworICAvLyBDcmVhdGUgdGhlICJiYXIiIGRpcmVjdG9yeSBzbyB3ZSBjYW4gcHV0IGEgZmlsZSBpbiBpdC4KKyAgR09PR0xFX0NIRUNLX09LKEZpbGU6OkNyZWF0ZURpcihkaXJuYW1lc19bMF0gKyAiL2JhciIsIDA3NzcpKTsKKworICAvLyBBZGQgZmlsZXMgYW5kIG1hcCBwYXRocy4KKyAgQWRkRmlsZShkaXJuYW1lc19bMF0gKyAiL2Jhci9mb28iLCAiSGVsbG8gV29ybGQhIik7CisgIEFkZEZpbGUoZGlybmFtZXNfWzFdICsgIi9mb28iLCAiVGhpcyBmaWxlIHNob3VsZCBiZSBoaWRkZW4uIik7CisgIHNvdXJjZV90cmVlXy5NYXBQYXRoKCIiLCBkaXJuYW1lc19bMF0pOworICBzb3VyY2VfdHJlZV8uTWFwUGF0aCgiYmFyIiwgZGlybmFtZXNfWzFdKTsKKworICAvLyBDaGVjay4KKyAgRXhwZWN0RmlsZUNvbnRlbnRzKCJiYXIvZm9vIiwgIkhlbGxvIFdvcmxkISIpOworfQorCitURVNUX0YoRGlza1NvdXJjZVRyZWVUZXN0LCBEaXNrRmlsZVRvVmlydHVhbEZpbGUpIHsKKyAgLy8gVGVzdCBEaXNrRmlsZVRvVmlydHVhbEZpbGUuCisKKyAgQWRkRmlsZShkaXJuYW1lc19bMF0gKyAiL2ZvbyIsICJIZWxsbyBXb3JsZCEiKTsKKyAgQWRkRmlsZShkaXJuYW1lc19bMV0gKyAiL2ZvbyIsICJUaGlzIGZpbGUgc2hvdWxkIGJlIGhpZGRlbi4iKTsKKyAgc291cmNlX3RyZWVfLk1hcFBhdGgoImJhciIsIGRpcm5hbWVzX1swXSk7CisgIHNvdXJjZV90cmVlXy5NYXBQYXRoKCJiYXIiLCBkaXJuYW1lc19bMV0pOworCisgIHN0cmluZyB2aXJ0dWFsX2ZpbGU7CisgIHN0cmluZyBzaGFkb3dpbmdfZGlza19maWxlOworCisgIEVYUEVDVF9FUShEaXNrU291cmNlVHJlZTo6Tk9fTUFQUElORywKKyAgICBzb3VyY2VfdHJlZV8uRGlza0ZpbGVUb1ZpcnR1YWxGaWxlKAorICAgICAgIi9mb28iLCAmdmlydHVhbF9maWxlLCAmc2hhZG93aW5nX2Rpc2tfZmlsZSkpOworCisgIEVYUEVDVF9FUShEaXNrU291cmNlVHJlZTo6U0hBRE9XRUQsCisgICAgc291cmNlX3RyZWVfLkRpc2tGaWxlVG9WaXJ0dWFsRmlsZSgKKyAgICAgIGRpcm5hbWVzX1sxXSArICIvZm9vIiwgJnZpcnR1YWxfZmlsZSwgJnNoYWRvd2luZ19kaXNrX2ZpbGUpKTsKKyAgRVhQRUNUX0VRKCJiYXIvZm9vIiwgdmlydHVhbF9maWxlKTsKKyAgRVhQRUNUX0VRKGRpcm5hbWVzX1swXSArICIvZm9vIiwgc2hhZG93aW5nX2Rpc2tfZmlsZSk7CisKKyAgRVhQRUNUX0VRKERpc2tTb3VyY2VUcmVlOjpDQU5OT1RfT1BFTiwKKyAgICBzb3VyY2VfdHJlZV8uRGlza0ZpbGVUb1ZpcnR1YWxGaWxlKAorICAgICAgZGlybmFtZXNfWzFdICsgIi9iYXoiLCAmdmlydHVhbF9maWxlLCAmc2hhZG93aW5nX2Rpc2tfZmlsZSkpOworICBFWFBFQ1RfRVEoImJhci9iYXoiLCB2aXJ0dWFsX2ZpbGUpOworCisgIEVYUEVDVF9FUShEaXNrU291cmNlVHJlZTo6U1VDQ0VTUywKKyAgICBzb3VyY2VfdHJlZV8uRGlza0ZpbGVUb1ZpcnR1YWxGaWxlKAorICAgICAgZGlybmFtZXNfWzBdICsgIi9mb28iLCAmdmlydHVhbF9maWxlLCAmc2hhZG93aW5nX2Rpc2tfZmlsZSkpOworICBFWFBFQ1RfRVEoImJhci9mb28iLCB2aXJ0dWFsX2ZpbGUpOworfQorCitURVNUX0YoRGlza1NvdXJjZVRyZWVUZXN0LCBEaXNrRmlsZVRvVmlydHVhbEZpbGVDYW5vbmljYWxpemF0aW9uKSB7CisgIC8vIFRlc3QgaGFuZGxpbmcgb2YgIi4uIiwgIi4iLCBldGMuIGluIERpc2tGaWxlVG9WaXJ0dWFsRmlsZSgpLgorCisgIHNvdXJjZV90cmVlXy5NYXBQYXRoKCJkaXIxIiwgIi4uIik7CisgIHNvdXJjZV90cmVlXy5NYXBQYXRoKCJkaXIyIiwgIi4uLy4uL2ZvbyIpOworICBzb3VyY2VfdHJlZV8uTWFwUGF0aCgiZGlyMyIsICIuL2Zvby9iYXIvLiIpOworICBzb3VyY2VfdHJlZV8uTWFwUGF0aCgiZGlyNCIsICIuIik7CisgIHNvdXJjZV90cmVlXy5NYXBQYXRoKCIiLCAiL3F1eCIpOworICBzb3VyY2VfdHJlZV8uTWFwUGF0aCgiZGlyNSIsICIvcXV1eC8iKTsKKworICBzdHJpbmcgdmlydHVhbF9maWxlOworICBzdHJpbmcgc2hhZG93aW5nX2Rpc2tfZmlsZTsKKworICAvLyAiLi4vLi4iIHNob3VsZCBub3QgYmUgY29uc2lkZXJlZCB0byBiZSB1bmRlciAiLi4iLgorICBFWFBFQ1RfRVEoRGlza1NvdXJjZVRyZWU6Ok5PX01BUFBJTkcsCisgICAgc291cmNlX3RyZWVfLkRpc2tGaWxlVG9WaXJ0dWFsRmlsZSgKKyAgICAgICIuLi8uLi9iYXoiLCAmdmlydHVhbF9maWxlLCAmc2hhZG93aW5nX2Rpc2tfZmlsZSkpOworCisgIC8vICIvZm9vIiBpcyBub3QgbWFwcGVkIChpdCBzaG91bGQgbm90IGJlIG1pc2ludGVwcmV0ZWQgYXMgYmVpbmcgdW5kZXIgIi4iKS4KKyAgRVhQRUNUX0VRKERpc2tTb3VyY2VUcmVlOjpOT19NQVBQSU5HLAorICAgIHNvdXJjZV90cmVlXy5EaXNrRmlsZVRvVmlydHVhbEZpbGUoCisgICAgICAiL2ZvbyIsICZ2aXJ0dWFsX2ZpbGUsICZzaGFkb3dpbmdfZGlza19maWxlKSk7CisKKyNpZmRlZiBXSU4zMgorICAvLyAiQzpcZm9vIiBpcyBub3QgbWFwcGVkIChpdCBzaG91bGQgbm90IGJlIG1pc2ludGVwcmV0ZWQgYXMgYmVpbmcgdW5kZXIgIi4iKS4KKyAgRVhQRUNUX0VRKERpc2tTb3VyY2VUcmVlOjpOT19NQVBQSU5HLAorICAgIHNvdXJjZV90cmVlXy5EaXNrRmlsZVRvVmlydHVhbEZpbGUoCisgICAgICAiQzpcXGZvbyIsICZ2aXJ0dWFsX2ZpbGUsICZzaGFkb3dpbmdfZGlza19maWxlKSk7CisjZW5kaWYgIC8vIFdJTjMyCisKKyAgLy8gQnV0ICIuLi9iYXoiIHNob3VsZCBiZS4KKyAgRVhQRUNUX0VRKERpc2tTb3VyY2VUcmVlOjpDQU5OT1RfT1BFTiwKKyAgICBzb3VyY2VfdHJlZV8uRGlza0ZpbGVUb1ZpcnR1YWxGaWxlKAorICAgICAgIi4uL2JheiIsICZ2aXJ0dWFsX2ZpbGUsICZzaGFkb3dpbmdfZGlza19maWxlKSk7CisgIEVYUEVDVF9FUSgiZGlyMS9iYXoiLCB2aXJ0dWFsX2ZpbGUpOworCisgIC8vICIuLi8uLi9mb28vYmF6IiBpcyB1bmRlciAiLi4vLi4vZm9vIi4KKyAgRVhQRUNUX0VRKERpc2tTb3VyY2VUcmVlOjpDQU5OT1RfT1BFTiwKKyAgICBzb3VyY2VfdHJlZV8uRGlza0ZpbGVUb1ZpcnR1YWxGaWxlKAorICAgICAgIi4uLy4uL2Zvby9iYXoiLCAmdmlydHVhbF9maWxlLCAmc2hhZG93aW5nX2Rpc2tfZmlsZSkpOworICBFWFBFQ1RfRVEoImRpcjIvYmF6IiwgdmlydHVhbF9maWxlKTsKKworICAvLyAiZm9vLy4vYmFyL2JheiIgaXMgdW5kZXIgIi4vZm9vL2Jhci8uIi4KKyAgRVhQRUNUX0VRKERpc2tTb3VyY2VUcmVlOjpDQU5OT1RfT1BFTiwKKyAgICBzb3VyY2VfdHJlZV8uRGlza0ZpbGVUb1ZpcnR1YWxGaWxlKAorICAgICAgImZvby9iYXIvYmF6IiwgJnZpcnR1YWxfZmlsZSwgJnNoYWRvd2luZ19kaXNrX2ZpbGUpKTsKKyAgRVhQRUNUX0VRKCJkaXIzL2JheiIsIHZpcnR1YWxfZmlsZSk7CisKKyAgLy8gImJhciIgaXMgdW5kZXIgIi4iLgorICBFWFBFQ1RfRVEoRGlza1NvdXJjZVRyZWU6OkNBTk5PVF9PUEVOLAorICAgIHNvdXJjZV90cmVlXy5EaXNrRmlsZVRvVmlydHVhbEZpbGUoCisgICAgICAiYmFyIiwgJnZpcnR1YWxfZmlsZSwgJnNoYWRvd2luZ19kaXNrX2ZpbGUpKTsKKyAgRVhQRUNUX0VRKCJkaXI0L2JhciIsIHZpcnR1YWxfZmlsZSk7CisKKyAgLy8gIi9xdXgvYmF6IiBpcyB1bmRlciAiL3F1eCIuCisgIEVYUEVDVF9FUShEaXNrU291cmNlVHJlZTo6Q0FOTk9UX09QRU4sCisgICAgc291cmNlX3RyZWVfLkRpc2tGaWxlVG9WaXJ0dWFsRmlsZSgKKyAgICAgICIvcXV4L2JheiIsICZ2aXJ0dWFsX2ZpbGUsICZzaGFkb3dpbmdfZGlza19maWxlKSk7CisgIEVYUEVDVF9FUSgiYmF6IiwgdmlydHVhbF9maWxlKTsKKworICAvLyAiL3F1dXgvYmFyIiBpcyB1bmRlciAiL3F1dXgiLgorICBFWFBFQ1RfRVEoRGlza1NvdXJjZVRyZWU6OkNBTk5PVF9PUEVOLAorICAgIHNvdXJjZV90cmVlXy5EaXNrRmlsZVRvVmlydHVhbEZpbGUoCisgICAgICAiL3F1dXgvYmFyIiwgJnZpcnR1YWxfZmlsZSwgJnNoYWRvd2luZ19kaXNrX2ZpbGUpKTsKKyAgRVhQRUNUX0VRKCJkaXI1L2JhciIsIHZpcnR1YWxfZmlsZSk7Cit9CisKK1RFU1RfRihEaXNrU291cmNlVHJlZVRlc3QsIFZpcnR1YWxGaWxlVG9EaXNrRmlsZSkgeworICAvLyBUZXN0IFZpcnR1YWxGaWxlVG9EaXNrRmlsZS4KKworICBBZGRGaWxlKGRpcm5hbWVzX1swXSArICIvZm9vIiwgIkhlbGxvIFdvcmxkISIpOworICBBZGRGaWxlKGRpcm5hbWVzX1sxXSArICIvZm9vIiwgIlRoaXMgZmlsZSBzaG91bGQgYmUgaGlkZGVuLiIpOworICBBZGRGaWxlKGRpcm5hbWVzX1sxXSArICIvcXV1eCIsICJUaGlzIGZpbGUgc2hvdWxkIG5vdCBiZSBoaWRkZW4uIik7CisgIHNvdXJjZV90cmVlXy5NYXBQYXRoKCJiYXIiLCBkaXJuYW1lc19bMF0pOworICBzb3VyY2VfdHJlZV8uTWFwUGF0aCgiYmFyIiwgZGlybmFtZXNfWzFdKTsKKworICAvLyBFeGlzdGVudCBmaWxlcywgc2hhZG93ZWQgYW5kIG5vbi1zaGFkb3dlZCBjYXNlLgorICBzdHJpbmcgZGlza19maWxlOworICBFWFBFQ1RfVFJVRShzb3VyY2VfdHJlZV8uVmlydHVhbEZpbGVUb0Rpc2tGaWxlKCJiYXIvZm9vIiwgJmRpc2tfZmlsZSkpOworICBFWFBFQ1RfRVEoZGlybmFtZXNfWzBdICsgIi9mb28iLCBkaXNrX2ZpbGUpOworICBFWFBFQ1RfVFJVRShzb3VyY2VfdHJlZV8uVmlydHVhbEZpbGVUb0Rpc2tGaWxlKCJiYXIvcXV1eCIsICZkaXNrX2ZpbGUpKTsKKyAgRVhQRUNUX0VRKGRpcm5hbWVzX1sxXSArICIvcXV1eCIsIGRpc2tfZmlsZSk7CisKKyAgLy8gTm9uZXhpc3RlbnQgZmlsZSBpbiBleGlzdGVudCBkaXJlY3RvcnkgYW5kIHZpY2UgdmVyc2EuCisgIHN0cmluZyBub3RfdG91Y2hlZCA9ICJub3QgdG91Y2hlZCI7CisgIEVYUEVDVF9GQUxTRShzb3VyY2VfdHJlZV8uVmlydHVhbEZpbGVUb0Rpc2tGaWxlKCJiYXIvYmF6IiwgJm5vdF90b3VjaGVkKSk7CisgIEVYUEVDVF9FUSgibm90IHRvdWNoZWQiLCBub3RfdG91Y2hlZCk7CisgIEVYUEVDVF9GQUxTRShzb3VyY2VfdHJlZV8uVmlydHVhbEZpbGVUb0Rpc2tGaWxlKCJiYXovZm9vIiwgJm5vdF90b3VjaGVkKSk7CisgIEVYUEVDVF9FUSgibm90IHRvdWNoZWQiLCBub3RfdG91Y2hlZCk7CisKKyAgLy8gQWNjZXB0IE5VTEwgYXMgb3V0cHV0IHBhcmFtZXRlci4KKyAgRVhQRUNUX1RSVUUoc291cmNlX3RyZWVfLlZpcnR1YWxGaWxlVG9EaXNrRmlsZSgiYmFyL2ZvbyIsIE5VTEwpKTsKKyAgRVhQRUNUX0ZBTFNFKHNvdXJjZV90cmVlXy5WaXJ0dWFsRmlsZVRvRGlza0ZpbGUoImJhei9mb28iLCBOVUxMKSk7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfY29udGV4dC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2NvbnRleHQuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2QyMWZlNgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2NvbnRleHQuY2MKQEAgLTAsMCArMSwxOTUgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9jb250ZXh0Lmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9uYW1lX3Jlc29sdmVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9tYXBfdXRpbC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmEgeworCitDb250ZXh0OjpDb250ZXh0KGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKQorICAgIDogbmFtZV9yZXNvbHZlcl8obmV3IENsYXNzTmFtZVJlc29sdmVyKSB7CisgIEluaXRpYWxpemVGaWVsZEdlbmVyYXRvckluZm8oZmlsZSk7Cit9CisKK0NvbnRleHQ6On5Db250ZXh0KCkgeworfQorCitDbGFzc05hbWVSZXNvbHZlciogQ29udGV4dDo6R2V0TmFtZVJlc29sdmVyKCkgeworICByZXR1cm4gbmFtZV9yZXNvbHZlcl8uZ2V0KCk7Cit9CisKK25hbWVzcGFjZSB7CisvLyBXaGV0aGVyIHR3byBmaWVsZHMgaGF2ZSBjb25mbGljdGluZyBhY2Nlc3NvcnMgKGFzc3VtaW5nIG5hbWUxIGFuZCBuYW1lMgorLy8gYXJlIGRpZmZlcmVudCkuIG5hbWUxIGFuZCBuYW1lMiBhcmUgZmllbGQxIGFuZCBmaWVsZDIncyBjYW1lbC1jYXNlIG5hbWUKKy8vIHJlc3BlY3RpdmVseS4KK2Jvb2wgSXNDb25mbGljdGluZyhjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkMSwgY29uc3Qgc3RyaW5nJiBuYW1lMSwKKyAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkMiwgY29uc3Qgc3RyaW5nJiBuYW1lMiwKKyAgICAgICAgICAgICAgICAgICBzdHJpbmcqIGluZm8pIHsKKyAgaWYgKGZpZWxkMS0+aXNfcmVwZWF0ZWQoKSkgeworICAgIGlmIChmaWVsZDItPmlzX3JlcGVhdGVkKCkpIHsKKyAgICAgIC8vIEJvdGggZmllbGRzIGFyZSByZXBlYXRlZC4KKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9IGVsc2UgeworICAgICAgLy8gZmllbGQxIGlzIHJlcGVhdGVkLCBhbmQgZmllbGQyIGlzIG5vdC4KKyAgICAgIGlmIChuYW1lMSArICJDb3VudCIgPT0gbmFtZTIpIHsKKyAgICAgICAgKmluZm8gPSAiYm90aCByZXBlYXRlZCBmaWVsZCBcIiIgKyBmaWVsZDEtPm5hbWUoKSArICJcIiBhbmQgc2luZ3VsYXIgIiArCisgICAgICAgICAgICAiZmllbGQgXCIiICsgZmllbGQyLT5uYW1lKCkgKyAiXCIgZ2VuZXJhdGVzIHRoZSBtZXRob2QgXCIiICsKKyAgICAgICAgICAgICJnZXQiICsgbmFtZTEgKyAiQ291bnQoKVwiIjsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICB9CisgICAgICBpZiAobmFtZTEgKyAiTGlzdCIgPT0gbmFtZTIpIHsKKyAgICAgICAgKmluZm8gPSAiYm90aCByZXBlYXRlZCBmaWVsZCBcIiIgKyBmaWVsZDEtPm5hbWUoKSArICJcIiBhbmQgc2luZ3VsYXIgIiArCisgICAgICAgICAgICAiZmllbGQgXCIiICsgZmllbGQyLT5uYW1lKCkgKyAiXCIgZ2VuZXJhdGVzIHRoZSBtZXRob2QgXCIiICsKKyAgICAgICAgICAgICJnZXQiICsgbmFtZTEgKyAiTGlzdCgpXCIiOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0KKyAgICAgIC8vIFdlbGwsIHRoZXJlIGFyZSBvYnZpb3VzbHkgbWFueSBtb3JlIGNvbmZsaWN0aW5nIGNhc2VzLCBidXQgaXQgcHJvYmFibHkKKyAgICAgIC8vIGRvZXNuJ3Qgd29ydGggdGhlIGVmZm9ydCB0byBleGhhdXN0IGFsbCBvZiB0aGVtIGJlY2F1c2UgdGhleSByYXJlbHkKKyAgICAgIC8vIGhhcHBlbiBhbmQgYXMgd2UgYXJlIGNvbnRpbnVpbmcgYWRkaW5nIG5ldyBtZXRob2RzL2NoYW5naW5nIGV4aXN0aW5nCisgICAgICAvLyBtZXRob2RzIHRoZSBudW1iZXIgb2YgZGlmZmVyZW50IGNvbmZsaWN0aW5nIGNhc2VzIHdpbGwga2VlcCBncm93aW5nLgorICAgICAgLy8gV2UgY2FuIGp1c3QgYWRkIG1vcmUgY2FzZXMgaGVyZSB3aGVuIHRoZXkgYXJlIGZvdW5kIGluIHRoZSByZWFsIHdvcmxkLgorICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICBpZiAoZmllbGQyLT5pc19yZXBlYXRlZCgpKSB7CisgICAgICByZXR1cm4gSXNDb25mbGljdGluZyhmaWVsZDIsIG5hbWUyLCBmaWVsZDEsIG5hbWUxLCBpbmZvKTsKKyAgICB9IGVsc2UgeworICAgICAgLy8gTm9uZSBvZiB0aGUgdHdvIGZpZWxkcyBhcmUgcmVwZWF0ZWQuCisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICB9Cit9Cit9ICAvLyBuYW1lc3BhY2UKKwordm9pZCBDb250ZXh0OjpJbml0aWFsaXplRmllbGRHZW5lcmF0b3JJbmZvKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZS0+bWVzc2FnZV90eXBlX2NvdW50KCk7ICsraSkgeworICAgIEluaXRpYWxpemVGaWVsZEdlbmVyYXRvckluZm9Gb3JNZXNzYWdlKGZpbGUtPm1lc3NhZ2VfdHlwZShpKSk7CisgIH0KK30KKwordm9pZCBDb250ZXh0OjpJbml0aWFsaXplRmllbGRHZW5lcmF0b3JJbmZvRm9yTWVzc2FnZSgKKyAgICBjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZS0+bmVzdGVkX3R5cGVfY291bnQoKTsgKytpKSB7CisgICAgSW5pdGlhbGl6ZUZpZWxkR2VuZXJhdG9ySW5mb0Zvck1lc3NhZ2UobWVzc2FnZS0+bmVzdGVkX3R5cGUoaSkpOworICB9CisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBmaWVsZHM7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZS0+ZmllbGRfY291bnQoKTsgKytpKSB7CisgICAgZmllbGRzLnB1c2hfYmFjayhtZXNzYWdlLT5maWVsZChpKSk7CisgIH0KKyAgSW5pdGlhbGl6ZUZpZWxkR2VuZXJhdG9ySW5mb0ZvckZpZWxkcyhmaWVsZHMpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZS0+b25lb2ZfZGVjbF9jb3VudCgpOyArK2kpIHsKKyAgICBjb25zdCBPbmVvZkRlc2NyaXB0b3IqIG9uZW9mID0gbWVzc2FnZS0+b25lb2ZfZGVjbChpKTsKKyAgICBPbmVvZkdlbmVyYXRvckluZm8gaW5mbzsKKyAgICBpbmZvLm5hbWUgPSBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlKG9uZW9mLT5uYW1lKCksIGZhbHNlKTsKKyAgICBpbmZvLmNhcGl0YWxpemVkX25hbWUgPSBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlKG9uZW9mLT5uYW1lKCksIHRydWUpOworICAgIG9uZW9mX2dlbmVyYXRvcl9pbmZvX21hcF9bb25lb2ZdID0gaW5mbzsKKyAgfQorfQorCit2b2lkIENvbnRleHQ6OkluaXRpYWxpemVGaWVsZEdlbmVyYXRvckluZm9Gb3JGaWVsZHMoCisgICAgY29uc3QgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+JiBmaWVsZHMpIHsKKyAgLy8gRmluZCBvdXQgYWxsIGZpZWxkcyB0aGF0IGNvbmZsaWN0IHdpdGggc29tZSBvdGhlciBmaWVsZCBpbiB0aGUgc2FtZQorICAvLyBtZXNzYWdlLgorICB2ZWN0b3I8Ym9vbD4gaXNfY29uZmxpY3QoZmllbGRzLnNpemUoKSk7CisgIHZlY3RvcjxzdHJpbmc+IGNvbmZsaWN0X3JlYXNvbihmaWVsZHMuc2l6ZSgpKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZHMuc2l6ZSgpOyArK2kpIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZmllbGRzW2ldOworICAgIGNvbnN0IHN0cmluZyYgbmFtZSA9IFVuZGVyc2NvcmVzVG9DYXBpdGFsaXplZENhbWVsQ2FzZShmaWVsZCk7CisgICAgZm9yIChpbnQgaiA9IGkgKyAxOyBqIDwgZmllbGRzLnNpemUoKTsgKytqKSB7CisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIG90aGVyID0gZmllbGRzW2pdOworICAgICAgY29uc3Qgc3RyaW5nJiBvdGhlcl9uYW1lID0gVW5kZXJzY29yZXNUb0NhcGl0YWxpemVkQ2FtZWxDYXNlKG90aGVyKTsKKyAgICAgIGlmIChuYW1lID09IG90aGVyX25hbWUpIHsKKyAgICAgICAgaXNfY29uZmxpY3RbaV0gPSBpc19jb25mbGljdFtqXSA9IHRydWU7CisgICAgICAgIGNvbmZsaWN0X3JlYXNvbltpXSA9IGNvbmZsaWN0X3JlYXNvbltqXSA9CisgICAgICAgICAgICAiY2FwaXRhbGl6ZWQgbmFtZSBvZiBmaWVsZCBcIiIgKyBmaWVsZC0+bmFtZSgpICsKKyAgICAgICAgICAgICJcIiBjb25mbGljdHMgd2l0aCBmaWVsZCBcIiIgKyBvdGhlci0+bmFtZSgpICsgIlwiIjsKKyAgICAgIH0gZWxzZSBpZiAoSXNDb25mbGljdGluZyhmaWVsZCwgbmFtZSwgb3RoZXIsIG90aGVyX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmNvbmZsaWN0X3JlYXNvbltqXSkpIHsKKyAgICAgICAgaXNfY29uZmxpY3RbaV0gPSBpc19jb25mbGljdFtqXSA9IHRydWU7CisgICAgICAgIGNvbmZsaWN0X3JlYXNvbltpXSA9IGNvbmZsaWN0X3JlYXNvbltqXTsKKyAgICAgIH0KKyAgICB9CisgICAgaWYgKGlzX2NvbmZsaWN0W2ldKSB7CisgICAgICBHT09HTEVfTE9HKFdBUk5JTkcpIDw8ICJmaWVsZCBcIiIgPDwgZmllbGQtPmZ1bGxfbmFtZSgpIDw8ICJcIiBpcyBjb25mbGljdGluZyAiCisgICAgICAgICAgICAgICAgICAgPDwgIndpdGggYW5vdGhlciBmaWVsZDogIiA8PCBjb25mbGljdF9yZWFzb25baV07CisgICAgfQorICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRzLnNpemUoKTsgKytpKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGZpZWxkc1tpXTsKKyAgICBGaWVsZEdlbmVyYXRvckluZm8gaW5mbzsKKyAgICBpbmZvLm5hbWUgPSBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlKGZpZWxkKTsKKyAgICBpbmZvLmNhcGl0YWxpemVkX25hbWUgPSBVbmRlcnNjb3Jlc1RvQ2FwaXRhbGl6ZWRDYW1lbENhc2UoZmllbGQpOworICAgIC8vIEZvciBmaWVsZHMgY29uZmxpY3Rpbmcgd2l0aCBzb21lIG90aGVyIGZpZWxkcywgd2UgYXBwZW5kIHRoZSBmaWVsZAorICAgIC8vIG51bWJlciB0byB0aGVpciBmaWVsZCBuYW1lcyBpbiBnZW5lcmF0ZWQgY29kZSB0byBhdm9pZCBjb25mbGljdHMuCisgICAgaWYgKGlzX2NvbmZsaWN0W2ldKSB7CisgICAgICBpbmZvLm5hbWUgKz0gU2ltcGxlSXRvYShmaWVsZC0+bnVtYmVyKCkpOworICAgICAgaW5mby5jYXBpdGFsaXplZF9uYW1lICs9IFNpbXBsZUl0b2EoZmllbGQtPm51bWJlcigpKTsKKyAgICAgIGluZm8uZGlzYW1iaWd1YXRlZF9yZWFzb24gPSBjb25mbGljdF9yZWFzb25baV07CisgICAgfQorICAgIGZpZWxkX2dlbmVyYXRvcl9pbmZvX21hcF9bZmllbGRdID0gaW5mbzsKKyAgfQorfQorCitjb25zdCBGaWVsZEdlbmVyYXRvckluZm8qIENvbnRleHQ6OkdldEZpZWxkR2VuZXJhdG9ySW5mbygKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7CisgIGNvbnN0IEZpZWxkR2VuZXJhdG9ySW5mbyogcmVzdWx0ID0KKyAgICAgIEZpbmRPck51bGwoZmllbGRfZ2VuZXJhdG9yX2luZm9fbWFwXywgZmllbGQpOworICBpZiAocmVzdWx0ID09IE5VTEwpIHsKKyAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ2FuIG5vdCBmaW5kIEZpZWxkR2VuZXJhdG9ySW5mbyBmb3IgZmllbGQ6ICIKKyAgICAgICAgICAgICAgIDw8IGZpZWxkLT5mdWxsX25hbWUoKTsKKyAgfQorICByZXR1cm4gcmVzdWx0OworfQorCitjb25zdCBPbmVvZkdlbmVyYXRvckluZm8qIENvbnRleHQ6OkdldE9uZW9mR2VuZXJhdG9ySW5mbygKKyAgICBjb25zdCBPbmVvZkRlc2NyaXB0b3IqIG9uZW9mKSBjb25zdCB7CisgIGNvbnN0IE9uZW9mR2VuZXJhdG9ySW5mbyogcmVzdWx0ID0KKyAgICAgIEZpbmRPck51bGwob25lb2ZfZ2VuZXJhdG9yX2luZm9fbWFwXywgb25lb2YpOworICBpZiAocmVzdWx0ID09IE5VTEwpIHsKKyAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ2FuIG5vdCBmaW5kIE9uZW9mR2VuZXJhdG9ySW5mbyBmb3Igb25lb2Y6ICIKKyAgICAgICAgICAgICAgIDw8IG9uZW9mLT5uYW1lKCk7CisgIH0KKyAgcmV0dXJuIHJlc3VsdDsKK30KKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9jb250ZXh0LmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9jb250ZXh0LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWI1OTVkMAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2NvbnRleHQuaApAQCAtMCwwICsxLDk4IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9DT05URVhUX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9DT05URVhUX0hfXworCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPG1lbW9yeT4KKyNpZm5kZWYgX1NIQVJFRF9QVFJfSAorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaGFyZWRfcHRyLmg+CisjZW5kaWYKKyNpbmNsdWRlIDx2ZWN0b3I+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKyAgY2xhc3MgRmlsZURlc2NyaXB0b3I7CisgIGNsYXNzIEZpZWxkRGVzY3JpcHRvcjsKKyAgY2xhc3MgT25lb2ZEZXNjcmlwdG9yOworICBjbGFzcyBEZXNjcmlwdG9yOworICBuYW1lc3BhY2UgY29tcGlsZXIgeworICAgIG5hbWVzcGFjZSBqYXZhIHsKKyAgICAgIGNsYXNzIENsYXNzTmFtZVJlc29sdmVyOyAgLy8gbmFtZV9yZXNvbHZlci5oCisgICAgfQorICB9Cit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YSB7CisKK3N0cnVjdCBGaWVsZEdlbmVyYXRvckluZm87CitzdHJ1Y3QgT25lb2ZHZW5lcmF0b3JJbmZvOworLy8gQSBjb250ZXh0IG9iamVjdCBob2xkcyB0aGUgaW5mb3JtYXRpb24gdGhhdCBpcyBzaGFyZWQgYW1vbmcgYWxsIGNvZGUKKy8vIGdlbmVyYXRvcnMuCitjbGFzcyBDb250ZXh0IHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IENvbnRleHQoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUpOworICB+Q29udGV4dCgpOworCisgIC8vIEdldCB0aGUgbmFtZSByZXNvbHZlciBhc3NvY2lhdGVkIHdpdGggdGhpcyBjb250ZXh0LiBUaGUgcmVzb2x2ZXIKKyAgLy8gY2FuIGJlIHVzZWQgdG8gbWFwIGRlc2NyaXB0b3JzIHRvIEphdmEgY2xhc3MgbmFtZXMuCisgIENsYXNzTmFtZVJlc29sdmVyKiBHZXROYW1lUmVzb2x2ZXIoKTsKKworICAvLyBHZXQgdGhlIEZpZWxkR2VuZXJhdG9ySW5mbyBmb3IgYSBnaXZlbiBmaWVsZC4KKyAgY29uc3QgRmllbGRHZW5lcmF0b3JJbmZvKiBHZXRGaWVsZEdlbmVyYXRvckluZm8oCisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdDsKKworICAvLyBHZXQgdGhlIE9uZW9mR2VuZXJhdG9ySW5mbyBmb3IgYSBnaXZlbiBvbmVvZi4KKyAgY29uc3QgT25lb2ZHZW5lcmF0b3JJbmZvKiBHZXRPbmVvZkdlbmVyYXRvckluZm8oCisgICAgICBjb25zdCBPbmVvZkRlc2NyaXB0b3IqIG9uZW9mKSBjb25zdDsKKworIHByaXZhdGU6CisgIHZvaWQgSW5pdGlhbGl6ZUZpZWxkR2VuZXJhdG9ySW5mbyhjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSk7CisgIHZvaWQgSW5pdGlhbGl6ZUZpZWxkR2VuZXJhdG9ySW5mb0Zvck1lc3NhZ2UoY29uc3QgRGVzY3JpcHRvciogbWVzc2FnZSk7CisgIHZvaWQgSW5pdGlhbGl6ZUZpZWxkR2VuZXJhdG9ySW5mb0ZvckZpZWxkcygKKyAgICAgIGNvbnN0IHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiYgZmllbGRzKTsKKworICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPENsYXNzTmFtZVJlc29sdmVyPiBuYW1lX3Jlc29sdmVyXzsKKyAgbWFwPGNvbnN0IEZpZWxkRGVzY3JpcHRvciosIEZpZWxkR2VuZXJhdG9ySW5mbz4gZmllbGRfZ2VuZXJhdG9yX2luZm9fbWFwXzsKKyAgbWFwPGNvbnN0IE9uZW9mRGVzY3JpcHRvciosIE9uZW9mR2VuZXJhdG9ySW5mbz4gb25lb2ZfZ2VuZXJhdG9yX2luZm9fbWFwXzsKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKENvbnRleHQpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfQ09OVEVYVF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2RvY19jb21tZW50LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZG9jX2NvbW1lbnQuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjYzZjBjOQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2RvY19jb21tZW50LmNjCkBAIC0wLDAgKzEsMjMzIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2RvY19jb21tZW50Lmg+CisKKyNpbmNsdWRlIDx2ZWN0b3I+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YSB7CisKK3N0cmluZyBFc2NhcGVKYXZhZG9jKGNvbnN0IHN0cmluZyYgaW5wdXQpIHsKKyAgc3RyaW5nIHJlc3VsdDsKKyAgcmVzdWx0LnJlc2VydmUoaW5wdXQuc2l6ZSgpICogMik7CisKKyAgY2hhciBwcmV2ID0gJyonOworCisgIGZvciAoc3RyaW5nOjpzaXplX3R5cGUgaSA9IDA7IGkgPCBpbnB1dC5zaXplKCk7IGkrKykgeworICAgIGNoYXIgYyA9IGlucHV0W2ldOworICAgIHN3aXRjaCAoYykgeworICAgICAgY2FzZSAnKic6CisgICAgICAgIC8vIEF2b2lkICIvKiIuCisgICAgICAgIGlmIChwcmV2ID09ICcvJykgeworICAgICAgICAgIHJlc3VsdC5hcHBlbmQoIiYjNDI7Iik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgcmVzdWx0LnB1c2hfYmFjayhjKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgJy8nOgorICAgICAgICAvLyBBdm9pZCAiKi8iLgorICAgICAgICBpZiAocHJldiA9PSAnKicpIHsKKyAgICAgICAgICByZXN1bHQuYXBwZW5kKCImIzQ3OyIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHJlc3VsdC5wdXNoX2JhY2soYyk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlICdAJzoKKyAgICAgICAgLy8gJ0AnIHN0YXJ0cyBqYXZhZG9jIHRhZ3MgaW5jbHVkaW5nIHRoZSBAZGVwcmVjYXRlZCB0YWcsIHdoaWNoIHdpbGwKKyAgICAgICAgLy8gY2F1c2UgYSBjb21waWxlLXRpbWUgZXJyb3IgaWYgaW5zZXJ0ZWQgYmVmb3JlIGEgZGVjbGFyYXRpb24gdGhhdAorICAgICAgICAvLyBkb2VzIG5vdCBoYXZlIGEgY29ycmVzcG9uZGluZyBARGVwcmVjYXRlZCBhbm5vdGF0aW9uLgorICAgICAgICByZXN1bHQuYXBwZW5kKCImIzY0OyIpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgJzwnOgorICAgICAgICAvLyBBdm9pZCBpbnRlcnByZXRhdGlvbiBhcyBIVE1MLgorICAgICAgICByZXN1bHQuYXBwZW5kKCImbHQ7Iik7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSAnPic6CisgICAgICAgIC8vIEF2b2lkIGludGVycHJldGF0aW9uIGFzIEhUTUwuCisgICAgICAgIHJlc3VsdC5hcHBlbmQoIiZndDsiKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlICcmJzoKKyAgICAgICAgLy8gQXZvaWQgaW50ZXJwcmV0YXRpb24gYXMgSFRNTC4KKyAgICAgICAgcmVzdWx0LmFwcGVuZCgiJmFtcDsiKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlICdcXCc6CisgICAgICAgIC8vIEphdmEgaW50ZXJwcmV0cyBVbmljb2RlIGVzY2FwZSBzZXF1ZW5jZXMgYW55d2hlcmUhCisgICAgICAgIHJlc3VsdC5hcHBlbmQoIiYjOTI7Iik7CisgICAgICAgIGJyZWFrOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgcmVzdWx0LnB1c2hfYmFjayhjKTsKKyAgICAgICAgYnJlYWs7CisgICAgfQorCisgICAgcHJldiA9IGM7CisgIH0KKworICByZXR1cm4gcmVzdWx0OworfQorCitzdGF0aWMgdm9pZCBXcml0ZURvY0NvbW1lbnRCb2R5Rm9yTG9jYXRpb24oCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIsIGNvbnN0IFNvdXJjZUxvY2F0aW9uJiBsb2NhdGlvbikgeworICBzdHJpbmcgY29tbWVudHMgPSBsb2NhdGlvbi5sZWFkaW5nX2NvbW1lbnRzLmVtcHR5KCkgPworICAgICAgbG9jYXRpb24udHJhaWxpbmdfY29tbWVudHMgOiBsb2NhdGlvbi5sZWFkaW5nX2NvbW1lbnRzOworICBpZiAoIWNvbW1lbnRzLmVtcHR5KCkpIHsKKyAgICAvLyBUT0RPKGtlbnRvbik6ICBJZGVhbGx5IHdlIHNob3VsZCBwYXJzZSB0aGUgY29tbWVudCB0ZXh0IGFzIE1hcmtkb3duIGFuZAorICAgIC8vICAgd3JpdGUgaXQgYmFjayBhcyBIVE1MLCBidXQgdGhpcyByZXF1aXJlcyBhIE1hcmtkb3duIHBhcnNlci4gIEZvciBub3cKKyAgICAvLyAgIHdlIGp1c3QgdXNlIDxwcmU+IHRvIGdldCBmaXhlZC13aWR0aCB0ZXh0IGZvcm1hdHRpbmcuCisKKyAgICAvLyBJZiB0aGUgY29tbWVudCBpdHNlbGYgY29udGFpbnMgYmxvY2sgY29tbWVudCBzdGFydCBvciBlbmQgbWFya2VycywKKyAgICAvLyBIVE1MLWVzY2FwZSB0aGVtIHNvIHRoYXQgdGhleSBkb24ndCBhY2NpZGVudGFsbHkgY2xvc2UgdGhlIGRvYyBjb21tZW50LgorICAgIGNvbW1lbnRzID0gRXNjYXBlSmF2YWRvYyhjb21tZW50cyk7CisKKyAgICB2ZWN0b3I8c3RyaW5nPiBsaW5lcyA9IFNwbGl0KGNvbW1lbnRzLCAiXG4iKTsKKyAgICB3aGlsZSAoIWxpbmVzLmVtcHR5KCkgJiYgbGluZXMuYmFjaygpLmVtcHR5KCkpIHsKKyAgICAgIGxpbmVzLnBvcF9iYWNrKCk7CisgICAgfQorCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICIgKlxuIgorICAgICAgICAiICogPHByZT5cbiIpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGluZXMuc2l6ZSgpOyBpKyspIHsKKyAgICAgIC8vIE1vc3QgbGluZXMgc2hvdWxkIHN0YXJ0IHdpdGggYSBzcGFjZS4gIFdhdGNoIG91dCBmb3IgbGluZXMgdGhhdCBzdGFydAorICAgICAgLy8gd2l0aCBhIC8sIHNpbmNlIHB1dHRpbmcgdGhhdCByaWdodCBhZnRlciB0aGUgbGVhZGluZyBhc3RlcmlzayB3aWxsCisgICAgICAvLyBjbG9zZSB0aGUgY29tbWVudC4KKyAgICAgIGlmICghbGluZXNbaV0uZW1wdHkoKSAmJiBsaW5lc1tpXVswXSA9PSAnLycpIHsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoIiAqICRsaW5lJFxuIiwgImxpbmUiLCBsaW5lc1tpXSk7CisgICAgICB9IGVsc2UgeworICAgICAgICBwcmludGVyLT5QcmludCgiICokbGluZSRcbiIsICJsaW5lIiwgbGluZXNbaV0pOworICAgICAgfQorICAgIH0KKyAgICBwcmludGVyLT5QcmludCgiICogPC9wcmU+XG4iKTsKKyAgfQorfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRGVzY3JpcHRvclR5cGU+CitzdGF0aWMgdm9pZCBXcml0ZURvY0NvbW1lbnRCb2R5KAorICAgIGlvOjpQcmludGVyKiBwcmludGVyLCBjb25zdCBEZXNjcmlwdG9yVHlwZSogZGVzY3JpcHRvcikgeworICBTb3VyY2VMb2NhdGlvbiBsb2NhdGlvbjsKKyAgaWYgKGRlc2NyaXB0b3ItPkdldFNvdXJjZUxvY2F0aW9uKCZsb2NhdGlvbikpIHsKKyAgICBXcml0ZURvY0NvbW1lbnRCb2R5Rm9yTG9jYXRpb24ocHJpbnRlciwgbG9jYXRpb24pOworICB9Cit9CisKK3N0YXRpYyBzdHJpbmcgRmlyc3RMaW5lT2YoY29uc3Qgc3RyaW5nJiB2YWx1ZSkgeworICBzdHJpbmcgcmVzdWx0ID0gdmFsdWU7CisKKyAgc3RyaW5nOjpzaXplX3R5cGUgcG9zID0gcmVzdWx0LmZpbmRfZmlyc3Rfb2YoJ1xuJyk7CisgIGlmIChwb3MgIT0gc3RyaW5nOjpucG9zKSB7CisgICAgcmVzdWx0LmVyYXNlKHBvcyk7CisgIH0KKworICAvLyBJZiBsaW5lIGVuZHMgaW4gYW4gb3BlbmluZyBicmFjZSwgbWFrZSBpdCAieyAuLi4gfSIgc28gaXQgbG9va3MgbmljZS4KKyAgaWYgKCFyZXN1bHQuZW1wdHkoKSAmJiByZXN1bHRbcmVzdWx0LnNpemUoKSAtIDFdID09ICd7JykgeworICAgIHJlc3VsdC5hcHBlbmQoIiAuLi4gfSIpOworICB9CisKKyAgcmV0dXJuIHJlc3VsdDsKK30KKwordm9pZCBXcml0ZU1lc3NhZ2VEb2NDb21tZW50KGlvOjpQcmludGVyKiBwcmludGVyLCBjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlKSB7CisgIHByaW50ZXItPlByaW50KAorICAgICIvKipcbiIKKyAgICAiICogUHJvdG9idWYgdHlwZSB7QGNvZGUgJGZ1bGxuYW1lJH1cbiIsCisgICAgImZ1bGxuYW1lIiwgRXNjYXBlSmF2YWRvYyhtZXNzYWdlLT5mdWxsX25hbWUoKSkpOworICBXcml0ZURvY0NvbW1lbnRCb2R5KHByaW50ZXIsIG1lc3NhZ2UpOworICBwcmludGVyLT5QcmludCgiICovXG4iKTsKK30KKwordm9pZCBXcml0ZUZpZWxkRG9jQ29tbWVudChpbzo6UHJpbnRlciogcHJpbnRlciwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICAvLyBJbiB0aGVvcnkgd2Ugc2hvdWxkIGhhdmUgc2xpZ2h0bHkgZGlmZmVyZW50IGNvbW1lbnRzIGZvciBzZXR0ZXJzLCBnZXR0ZXJzLAorICAvLyBldGMuLCBidXQgaW4gcHJhY3RpY2UgZXZlcnlvbmUgYWxyZWFkeSBrbm93cyB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZXNlCisgIC8vIHNvIGl0J3MgcmVkdW5kYW50IGluZm9ybWF0aW9uLgorCisgIC8vIFdlIHVzZSB0aGUgZmllbGQgZGVjbGFyYXRpb24gYXMgdGhlIGZpcnN0IGxpbmUgb2YgdGhlIGNvbW1lbnQsIGUuZy46CisgIC8vICAgb3B0aW9uYWwgc3RyaW5nIGZvbyA9IDU7CisgIC8vIFRoaXMgY29tbXVuaWNhdGVzIGEgbG90IG9mIGluZm9ybWF0aW9uIGFib3V0IHRoZSBmaWVsZCBpbiBhIHNtYWxsIHNwYWNlLgorICAvLyBJZiB0aGUgZmllbGQgaXMgYSBncm91cCwgdGhlIGRlYnVnIHN0cmluZyBtaWdodCBlbmQgd2l0aCB7LgorICBwcmludGVyLT5QcmludCgKKyAgICAiLyoqXG4iCisgICAgIiAqIDxjb2RlPiRkZWYkPC9jb2RlPlxuIiwKKyAgICAiZGVmIiwgRXNjYXBlSmF2YWRvYyhGaXJzdExpbmVPZihmaWVsZC0+RGVidWdTdHJpbmcoKSkpKTsKKyAgV3JpdGVEb2NDb21tZW50Qm9keShwcmludGVyLCBmaWVsZCk7CisgIHByaW50ZXItPlByaW50KCIgKi9cbiIpOworfQorCit2b2lkIFdyaXRlRW51bURvY0NvbW1lbnQoaW86OlByaW50ZXIqIHByaW50ZXIsIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBlbnVtXykgeworICBwcmludGVyLT5QcmludCgKKyAgICAiLyoqXG4iCisgICAgIiAqIFByb3RvYnVmIGVudW0ge0Bjb2RlICRmdWxsbmFtZSR9XG4iLAorICAgICJmdWxsbmFtZSIsIEVzY2FwZUphdmFkb2MoZW51bV8tPmZ1bGxfbmFtZSgpKSk7CisgIFdyaXRlRG9jQ29tbWVudEJvZHkocHJpbnRlciwgZW51bV8pOworICBwcmludGVyLT5QcmludCgiICovXG4iKTsKK30KKwordm9pZCBXcml0ZUVudW1WYWx1ZURvY0NvbW1lbnQoaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiB2YWx1ZSkgeworICBwcmludGVyLT5QcmludCgKKyAgICAiLyoqXG4iCisgICAgIiAqIDxjb2RlPiRkZWYkPC9jb2RlPlxuIiwKKyAgICAiZGVmIiwgRXNjYXBlSmF2YWRvYyhGaXJzdExpbmVPZih2YWx1ZS0+RGVidWdTdHJpbmcoKSkpKTsKKyAgV3JpdGVEb2NDb21tZW50Qm9keShwcmludGVyLCB2YWx1ZSk7CisgIHByaW50ZXItPlByaW50KCIgKi9cbiIpOworfQorCit2b2lkIFdyaXRlU2VydmljZURvY0NvbW1lbnQoaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgU2VydmljZURlc2NyaXB0b3IqIHNlcnZpY2UpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIi8qKlxuIgorICAgICIgKiBQcm90b2J1ZiBzZXJ2aWNlIHtAY29kZSAkZnVsbG5hbWUkfVxuIiwKKyAgICAiZnVsbG5hbWUiLCBFc2NhcGVKYXZhZG9jKHNlcnZpY2UtPmZ1bGxfbmFtZSgpKSk7CisgIFdyaXRlRG9jQ29tbWVudEJvZHkocHJpbnRlciwgc2VydmljZSk7CisgIHByaW50ZXItPlByaW50KCIgKi9cbiIpOworfQorCit2b2lkIFdyaXRlTWV0aG9kRG9jQ29tbWVudChpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1ldGhvZERlc2NyaXB0b3IqIG1ldGhvZCkgeworICBwcmludGVyLT5QcmludCgKKyAgICAiLyoqXG4iCisgICAgIiAqIDxjb2RlPiRkZWYkPC9jb2RlPlxuIiwKKyAgICAiZGVmIiwgRXNjYXBlSmF2YWRvYyhGaXJzdExpbmVPZihtZXRob2QtPkRlYnVnU3RyaW5nKCkpKSk7CisgIFdyaXRlRG9jQ29tbWVudEJvZHkocHJpbnRlciwgbWV0aG9kKTsKKyAgcHJpbnRlci0+UHJpbnQoIiAqL1xuIik7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZG9jX2NvbW1lbnQuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2RvY19jb21tZW50LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2Q5NTM1YwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2RvY19jb21tZW50LmgKQEAgLTAsMCArMSw2OSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX0RPQ19DT01NRU5UX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9ET0NfQ09NTUVOVF9IX18KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKyAgbmFtZXNwYWNlIGlvIHsKKyAgICBjbGFzcyBQcmludGVyOyAgICAgICAgICAgICAvLyBwcmludGVyLmgKKyAgfQorfQorCituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhIHsKKwordm9pZCBXcml0ZU1lc3NhZ2VEb2NDb21tZW50KGlvOjpQcmludGVyKiBwcmludGVyLCBjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlKTsKK3ZvaWQgV3JpdGVGaWVsZERvY0NvbW1lbnQoaW86OlByaW50ZXIqIHByaW50ZXIsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpOwordm9pZCBXcml0ZUVudW1Eb2NDb21tZW50KGlvOjpQcmludGVyKiBwcmludGVyLCBjb25zdCBFbnVtRGVzY3JpcHRvciogZW51bV8pOwordm9pZCBXcml0ZUVudW1WYWx1ZURvY0NvbW1lbnQoaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiB2YWx1ZSk7Cit2b2lkIFdyaXRlU2VydmljZURvY0NvbW1lbnQoaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgU2VydmljZURlc2NyaXB0b3IqIHNlcnZpY2UpOwordm9pZCBXcml0ZU1ldGhvZERvY0NvbW1lbnQoaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNZXRob2REZXNjcmlwdG9yKiBtZXRob2QpOworCisvLyBFeHBvc2VkIGZvciB0ZXN0aW5nIG9ubHkuCitMSUJQUk9UT0NfRVhQT1JUIHN0cmluZyBFc2NhcGVKYXZhZG9jKGNvbnN0IHN0cmluZyYgaW5wdXQpOworCit9ICAvLyBuYW1lc3BhY2UgamF2YQorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9ET0NfQ09NTUVOVF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2RvY19jb21tZW50X3VuaXR0ZXN0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZG9jX2NvbW1lbnRfdW5pdHRlc3QuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWU1ODJlYQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2RvY19jb21tZW50X3VuaXR0ZXN0LmNjCkBAIC0wLDAgKzEsNjcgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2RvY19jb21tZW50Lmg+CisKKyNpbmNsdWRlIDxndGVzdC9ndGVzdC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmEgeworbmFtZXNwYWNlIHsKKworVEVTVChKYXZhRG9jQ29tbWVudFRlc3QsIEVzY2FwaW5nKSB7CisgIEVYUEVDVF9FUSgiZm9vIC8mIzQyOyBiYXIgKiYjNDc7IGJheiIsIEVzY2FwZUphdmFkb2MoImZvbyAvKiBiYXIgKi8gYmF6IikpOworICBFWFBFQ1RfRVEoImZvbyAvJiM0MjsmIzQ3OyBiYXoiLCBFc2NhcGVKYXZhZG9jKCJmb28gLyovIGJheiIpKTsKKyAgRVhQRUNUX0VRKCJ7JiM2NDtmb299IiwgRXNjYXBlSmF2YWRvYygie0Bmb299IikpOworICBFWFBFQ1RfRVEoIiZsdDtpJmd0OyZhbXA7Jmx0Oy9pJmd0OyIsIEVzY2FwZUphdmFkb2MoIjxpPiY8L2k+IikpOworICBFWFBFQ1RfRVEoImZvbyYjOTI7dTEyMzRiYXIiLCBFc2NhcGVKYXZhZG9jKCJmb29cXHUxMjM0YmFyIikpOworICBFWFBFQ1RfRVEoIiYjNjQ7ZGVwcmVjYXRlZCIsIEVzY2FwZUphdmFkb2MoIkBkZXByZWNhdGVkIikpOworfQorCisvLyBUT0RPKGtlbnRvbik6ICBJdCdzIGhhcmQgdG8gd3JpdGUgYSByb2J1c3QgdGVzdCBvZiB0aGUgZG9jIGNvbW1lbnRzIC0tIHdlCisvLyAgIGNhbiBvbmx5IHJlYWxseSBjb21wYXJlIHRoZSBvdXRwdXQgYWdhaW5zdCBhIGdvbGRlbiB2YWx1ZSwgd2hpY2ggaXMgYQorLy8gICBmYWlybHkgdGVkaW91cyBhbmQgZnJhZ2lsZSB0ZXN0aW5nIHN0cmF0ZWd5LiAgSWYgd2Ugd2FudCB0byBnbyB0aGF0IHJvdXRlLAorLy8gICBpdCBwcm9iYWJseSBtYWtlcyBzZW5zZSB0byBiaXRlIHRoZSBidWxsZXQgYW5kIHdyaXRlIGEgdGVzdCB0aGF0IGNvbXBhcmVzCisvLyAgIHRoZSB3aG9sZSBnZW5lcmF0ZWQgb3V0cHV0IGZvciB1bml0dGVzdC5wcm90byBhZ2FpbnN0IGEgZ29sZGVuIHZhbHVlLCB3aXRoCisvLyAgIGEgdmVyeSBzaW1wbGUgc2NyaXB0IHRoYXQgY2FuIGJlIHJ1biB0byByZWdlbmVyYXRlIGl0IHdpdGggdGhlIGxhdGVzdCBjb2RlLgorLy8gICBUaGlzIHdvdWxkIG1lYW4gdGhhdCB1cGRhdGVzIHRvIHRoZSBnb2xkZW4gZmlsZSB3b3VsZCBoYXZlIHRvIGJlIGluY2x1ZGVkCisvLyAgIGluIGFueSBjaGFuZ2UgdG8gdGhlIGNvZGUgZ2VuZXJhdG9yLCB3aGljaCB3b3VsZCBhY3R1YWxseSBiZSBmYWlybHkgdXNlZnVsCisvLyAgIGFzIGl0IGFsbG93cyB0aGUgcmV2aWV3ZXIgdG8gc2VlIGNsZWFybHkgaG93IHRoZSBnZW5lcmF0ZWQgY29kZSBpcworLy8gICBjaGFuZ2luZy4KKworfSAgLy8gbmFtZXNwYWNlCit9ICAvLyBuYW1lc3BhY2UgamF2YQorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2VudW0uY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9lbnVtLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVmYzliMDAKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9lbnVtLmNjCkBAIC0wLDAgKzEsMzQ3IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8c3RyaW5nPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9jb250ZXh0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9lbnVtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9kb2NfY29tbWVudC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfaGVscGVycy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbmFtZV9yZXNvbHZlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmEgeworCituYW1lc3BhY2UgeworYm9vbCBFbnVtSGFzQ3VzdG9tT3B0aW9ucyhjb25zdCBFbnVtRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBpZiAoZGVzY3JpcHRvci0+b3B0aW9ucygpLnVua25vd25fZmllbGRzKCkuZmllbGRfY291bnQoKSA+IDApIHJldHVybiB0cnVlOworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3ItPnZhbHVlX2NvdW50KCk7ICsraSkgeworICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIHZhbHVlID0gZGVzY3JpcHRvci0+dmFsdWUoaSk7CisgICAgaWYgKHZhbHVlLT5vcHRpb25zKCkudW5rbm93bl9maWVsZHMoKS5maWVsZF9jb3VudCgpID4gMCkgcmV0dXJuIHRydWU7CisgIH0KKyAgcmV0dXJuIGZhbHNlOworfQorfSAgLy8gbmFtZXNwYWNlCisKK0VudW1HZW5lcmF0b3I6OkVudW1HZW5lcmF0b3IoY29uc3QgRW51bURlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaW1tdXRhYmxlX2FwaSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29udGV4dCogY29udGV4dCkKKyAgOiBkZXNjcmlwdG9yXyhkZXNjcmlwdG9yKSwgaW1tdXRhYmxlX2FwaV8oaW1tdXRhYmxlX2FwaSksCisgICAgbmFtZV9yZXNvbHZlcl8oY29udGV4dC0+R2V0TmFtZVJlc29sdmVyKCkpICB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPnZhbHVlX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIHZhbHVlID0gZGVzY3JpcHRvcl8tPnZhbHVlKGkpOworICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIGNhbm9uaWNhbF92YWx1ZSA9CisgICAgICBkZXNjcmlwdG9yXy0+RmluZFZhbHVlQnlOdW1iZXIodmFsdWUtPm51bWJlcigpKTsKKworICAgIGlmICh2YWx1ZSA9PSBjYW5vbmljYWxfdmFsdWUpIHsKKyAgICAgIGNhbm9uaWNhbF92YWx1ZXNfLnB1c2hfYmFjayh2YWx1ZSk7CisgICAgfSBlbHNlIHsKKyAgICAgIEFsaWFzIGFsaWFzOworICAgICAgYWxpYXMudmFsdWUgPSB2YWx1ZTsKKyAgICAgIGFsaWFzLmNhbm9uaWNhbF92YWx1ZSA9IGNhbm9uaWNhbF92YWx1ZTsKKyAgICAgIGFsaWFzZXNfLnB1c2hfYmFjayhhbGlhcyk7CisgICAgfQorICB9Cit9CisKK0VudW1HZW5lcmF0b3I6On5FbnVtR2VuZXJhdG9yKCkge30KKwordm9pZCBFbnVtR2VuZXJhdG9yOjpHZW5lcmF0ZShpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBXcml0ZUVudW1Eb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgInB1YmxpYyBlbnVtICRjbGFzc25hbWUkXG4iCisgICAgIiAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xNZXNzYWdlRW51bSB7XG4iLAorICAgICJjbGFzc25hbWUiLCBkZXNjcmlwdG9yXy0+bmFtZSgpKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBjYW5vbmljYWxfdmFsdWVzXy5zaXplKCk7IGkrKykgeworICAgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyczsKKyAgICB2YXJzWyJuYW1lIl0gPSBjYW5vbmljYWxfdmFsdWVzX1tpXS0+bmFtZSgpOworICAgIHZhcnNbImluZGV4Il0gPSBTaW1wbGVJdG9hKGNhbm9uaWNhbF92YWx1ZXNfW2ldLT5pbmRleCgpKTsKKyAgICB2YXJzWyJudW1iZXIiXSA9IFNpbXBsZUl0b2EoY2Fub25pY2FsX3ZhbHVlc19baV0tPm51bWJlcigpKTsKKyAgICBXcml0ZUVudW1WYWx1ZURvY0NvbW1lbnQocHJpbnRlciwgY2Fub25pY2FsX3ZhbHVlc19baV0pOworICAgIGlmIChjYW5vbmljYWxfdmFsdWVzX1tpXS0+b3B0aW9ucygpLmRlcHJlY2F0ZWQoKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQoIkBqYXZhLmxhbmcuRGVwcmVjYXRlZFxuIik7CisgICAgfQorICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAiJG5hbWUkKCRpbmRleCQsICRudW1iZXIkKSxcbiIpOworICB9CisKKyAgaWYgKFN1cHBvcnRVbmtub3duRW51bVZhbHVlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgcHJpbnRlci0+UHJpbnQoIlVOUkVDT0dOSVpFRCgtMSwgLTEpLFxuIik7CisgIH0KKworICBwcmludGVyLT5QcmludCgKKyAgICAiO1xuIgorICAgICJcbiIpOworCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBhbGlhc2VzXy5zaXplKCk7IGkrKykgeworICAgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyczsKKyAgICB2YXJzWyJjbGFzc25hbWUiXSA9IGRlc2NyaXB0b3JfLT5uYW1lKCk7CisgICAgdmFyc1sibmFtZSJdID0gYWxpYXNlc19baV0udmFsdWUtPm5hbWUoKTsKKyAgICB2YXJzWyJjYW5vbmljYWxfbmFtZSJdID0gYWxpYXNlc19baV0uY2Fub25pY2FsX3ZhbHVlLT5uYW1lKCk7CisgICAgV3JpdGVFbnVtVmFsdWVEb2NDb21tZW50KHByaW50ZXIsIGFsaWFzZXNfW2ldLnZhbHVlKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgInB1YmxpYyBzdGF0aWMgZmluYWwgJGNsYXNzbmFtZSQgJG5hbWUkID0gJGNhbm9uaWNhbF9uYW1lJDtcbiIpOworICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+dmFsdWVfY291bnQoKTsgaSsrKSB7CisgICAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJzOworICAgIHZhcnNbIm5hbWUiXSA9IGRlc2NyaXB0b3JfLT52YWx1ZShpKS0+bmFtZSgpOworICAgIHZhcnNbIm51bWJlciJdID0gU2ltcGxlSXRvYShkZXNjcmlwdG9yXy0+dmFsdWUoaSktPm51bWJlcigpKTsKKyAgICBXcml0ZUVudW1WYWx1ZURvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8tPnZhbHVlKGkpKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgInB1YmxpYyBzdGF0aWMgZmluYWwgaW50ICRuYW1lJF9WQUxVRSA9ICRudW1iZXIkO1xuIik7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBwcmludGVyLT5QcmludCgKKyAgICAiXG4iCisgICAgInB1YmxpYyBmaW5hbCBpbnQgZ2V0TnVtYmVyKCkge1xuIik7CisgIGlmIChTdXBwb3J0VW5rbm93bkVudW1WYWx1ZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIiAgaWYgKGluZGV4ID09IC0xKSB7XG4iCisgICAgICAiICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKFxuIgorICAgICAgIiAgICAgICAgXCJDYW4ndCBnZXQgdGhlIG51bWJlciBvZiBhbiB1bmtub3duIGVudW0gdmFsdWUuXCIpO1xuIgorICAgICAgIiAgfVxuIik7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIiAgcmV0dXJuIHZhbHVlO1xuIgorICAgICJ9XG4iCisgICAgIlxuIgorICAgICJwdWJsaWMgc3RhdGljICRjbGFzc25hbWUkIHZhbHVlT2YoaW50IHZhbHVlKSB7XG4iCisgICAgIiAgc3dpdGNoICh2YWx1ZSkge1xuIiwKKyAgICAiY2xhc3NuYW1lIiwgZGVzY3JpcHRvcl8tPm5hbWUoKSk7CisgIHByaW50ZXItPkluZGVudCgpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGNhbm9uaWNhbF92YWx1ZXNfLnNpemUoKTsgaSsrKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiY2FzZSAkbnVtYmVyJDogcmV0dXJuICRuYW1lJDtcbiIsCisgICAgICAibmFtZSIsIGNhbm9uaWNhbF92YWx1ZXNfW2ldLT5uYW1lKCksCisgICAgICAibnVtYmVyIiwgU2ltcGxlSXRvYShjYW5vbmljYWxfdmFsdWVzX1tpXS0+bnVtYmVyKCkpKTsKKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAiICAgIGRlZmF1bHQ6IHJldHVybiBudWxsO1xuIgorICAgICIgIH1cbiIKKyAgICAifVxuIgorICAgICJcbiIKKyAgICAicHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPCRjbGFzc25hbWUkPlxuIgorICAgICIgICAgaW50ZXJuYWxHZXRWYWx1ZU1hcCgpIHtcbiIKKyAgICAiICByZXR1cm4gaW50ZXJuYWxWYWx1ZU1hcDtcbiIKKyAgICAifVxuIgorICAgICJwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPFxuIgorICAgICIgICAgJGNsYXNzbmFtZSQ+IGludGVybmFsVmFsdWVNYXAgPVxuIgorICAgICIgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDwkY2xhc3NuYW1lJD4oKSB7XG4iCisgICAgIiAgICAgICAgcHVibGljICRjbGFzc25hbWUkIGZpbmRWYWx1ZUJ5TnVtYmVyKGludCBudW1iZXIpIHtcbiIKKyAgICAiICAgICAgICAgIHJldHVybiAkY2xhc3NuYW1lJC52YWx1ZU9mKG51bWJlcik7XG4iCisgICAgIiAgICAgICAgfVxuIgorICAgICIgICAgICB9O1xuIgorICAgICJcbiIsCisgICAgImNsYXNzbmFtZSIsIGRlc2NyaXB0b3JfLT5uYW1lKCkpOworCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8vIFJlZmxlY3Rpb24KKworICBpZiAoSGFzRGVzY3JpcHRvck1ldGhvZHMoZGVzY3JpcHRvcl8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAicHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvclxuIgorICAgICAgIiAgICBnZXRWYWx1ZURlc2NyaXB0b3IoKSB7XG4iCisgICAgICAiICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpLmdldFZhbHVlcygpLmdldChpbmRleCk7XG4iCisgICAgICAifVxuIgorICAgICAgInB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yXG4iCisgICAgICAiICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkge1xuIgorICAgICAgIiAgcmV0dXJuIGdldERlc2NyaXB0b3IoKTtcbiIKKyAgICAgICJ9XG4iCisgICAgICAicHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yXG4iCisgICAgICAiICAgIGdldERlc2NyaXB0b3IoKSB7XG4iKTsKKworICAgIC8vIFRPRE8oa2VudG9uKTogIENhY2hlIHN0YXRpY2FsbHk/ICBOb3RlIHRoYXQgd2UgY2FuJ3QgYWNjZXNzIGRlc2NyaXB0b3JzCisgICAgLy8gICBhdCBtb2R1bGUgaW5pdCB0aW1lIGJlY2F1c2UgaXQgd291bGRuJ3Qgd29yayB3aXRoIGRlc2NyaXB0b3IucHJvdG8sIGJ1dAorICAgIC8vICAgd2UgY2FuIGNhY2hlIHRoZSB2YWx1ZSB0aGUgZmlyc3QgdGltZSBnZXREZXNjcmlwdG9yKCkgaXMgY2FsbGVkLgorICAgIGlmIChkZXNjcmlwdG9yXy0+Y29udGFpbmluZ190eXBlKCkgPT0gTlVMTCkgeworICAgICAgaWYgKCFNdWx0aXBsZUphdmFGaWxlcyhkZXNjcmlwdG9yXy0+ZmlsZSgpLCBpbW11dGFibGVfYXBpXykpIHsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgIiAgcmV0dXJuICRmaWxlJC5nZXREZXNjcmlwdG9yKCkuZ2V0RW51bVR5cGVzKCkuZ2V0KCRpbmRleCQpO1xuIiwKKyAgICAgICAgICAiZmlsZSIsIG5hbWVfcmVzb2x2ZXJfLT5HZXRDbGFzc05hbWUoZGVzY3JpcHRvcl8tPmZpbGUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1tdXRhYmxlX2FwaV8pLAorICAgICAgICAgICJpbmRleCIsIFNpbXBsZUl0b2EoZGVzY3JpcHRvcl8tPmluZGV4KCkpKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHByaW50ZXItPkluZGVudCgpOworICAgICAgICBpZiAoRW51bUhhc0N1c3RvbU9wdGlvbnMoZGVzY3JpcHRvcl8pKSB7CisgICAgICAgICAgLy8gV2UgbmVlZCB0byBsb2FkIHRoZSBpbW11dGFibGUgY2xhc3NlcyBpbiBvcmRlciB0byBwYXJzZSBjdXN0b20KKyAgICAgICAgICAvLyBvcHRpb25zLiBIb3dldmVyLCBzaW5jZSBmaWxlIGxldmVsIGVudW1zIChubyBvdXRlciBjbGFzcykgYXJlCisgICAgICAgICAgLy8gc2hhcmVkIGJ5IGltbXV0YWJsZSBjb2RlIGFuZCBtdXRhYmxlIGNvZGUsIHRoZSBpbW11dGFibGUgY2xhc3NlcworICAgICAgICAgIC8vIG1heSBub3QgZXhpc3QuIFNvIHdlIHRyeSB0byB1c2UgSmF2YSByZWZsZWN0aW9uIHRvIHJldHJpZXZlIHRoZQorICAgICAgICAgIC8vIGRlc2NyaXB0b3IgZnJvbSBpbW11dGFibGUgY2xhc3Nlcy4KKyAgICAgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAgICJ0cnkge1xuIgorICAgICAgICAgICAgIiAgamF2YS5sYW5nLkNsYXNzIGltbXV0YWJsZUZpbGVDbGFzcyA9XG4iCisgICAgICAgICAgICAiICAgICAgamF2YS5sYW5nLkNsYXNzLmZvck5hbWUoXCIkaW1tdXRhYmxlX2ZpbGVfY2xhc3NfbmFtZSRcIik7XG4iCisgICAgICAgICAgICAiICBAamF2YS5sYW5nLlN1cHByZXNzV2FybmluZ3MoXCJ1bmNoZWNrZWRcIilcbiIKKyAgICAgICAgICAgICIgIGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZCBtID1cbiIKKyAgICAgICAgICAgICIgICAgICBpbW11dGFibGVGaWxlQ2xhc3MuZ2V0TWV0aG9kKFwiZ2V0RGVzY3JpcHRvclwiKTtcbiIKKyAgICAgICAgICAgICIgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IgZmlsZSA9XG4iCisgICAgICAgICAgICAiICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IpXG4iCisgICAgICAgICAgICAiICAgICAgICAgIG0uaW52b2tlKGltbXV0YWJsZUZpbGVDbGFzcyk7XG4iCisgICAgICAgICAgICAiICByZXR1cm4gZmlsZS5nZXRFbnVtVHlwZXMoKS5nZXQoJGluZGV4JCk7XG4iCisgICAgICAgICAgICAifSBjYXRjaCAoRXhjZXB0aW9uIGUpIHtcbiIKKyAgICAgICAgICAgIC8vIEltbXV0YWJsZSBjbGFzc2VzIGNhbm5vdCBiZSBmb3VuZC4gUHJvY2VlZCBhcyBpZiBjdXN0b20gb3B0aW9ucworICAgICAgICAgICAgLy8gZG9uJ3QgZXhpc3QuCisgICAgICAgICAgICAifVxuIiwKKyAgICAgICAgICAgICJpbW11dGFibGVfZmlsZV9jbGFzc19uYW1lIiwKKyAgICAgICAgICAgIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcl8tPmZpbGUoKSksCisgICAgICAgICAgICAiaW5kZXgiLCBTaW1wbGVJdG9hKGRlc2NyaXB0b3JfLT5pbmRleCgpKSk7CisgICAgICAgIH0KKyAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgInJldHVybiAkaW1tdXRhYmxlX3BhY2thZ2UkLiRkZXNjcmlwdG9yX2NsYXNzJC4kZGVzY3JpcHRvciRcbiIKKyAgICAgICAgICAiICAgIC5nZXRFbnVtVHlwZXMoKS5nZXQoJGluZGV4JCk7XG4iLAorICAgICAgICAgICJpbW11dGFibGVfcGFja2FnZSIsIEZpbGVKYXZhUGFja2FnZShkZXNjcmlwdG9yXy0+ZmlsZSgpLCB0cnVlKSwKKyAgICAgICAgICAiZGVzY3JpcHRvcl9jbGFzcyIsCisgICAgICAgICAgbmFtZV9yZXNvbHZlcl8tPkdldERlc2NyaXB0b3JDbGFzc05hbWUoZGVzY3JpcHRvcl8tPmZpbGUoKSksCisgICAgICAgICAgImRlc2NyaXB0b3IiLCAiZ2V0RGVzY3JpcHRvcigpIiwKKyAgICAgICAgICAiaW5kZXgiLCBTaW1wbGVJdG9hKGRlc2NyaXB0b3JfLT5pbmRleCgpKSk7CisgICAgICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgIiAgcmV0dXJuICRwYXJlbnQkLiRkZXNjcmlwdG9yJC5nZXRFbnVtVHlwZXMoKS5nZXQoJGluZGV4JCk7XG4iLAorICAgICAgICAgICJwYXJlbnQiLCBuYW1lX3Jlc29sdmVyXy0+R2V0Q2xhc3NOYW1lKGRlc2NyaXB0b3JfLT5jb250YWluaW5nX3R5cGUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbW11dGFibGVfYXBpXyksCisgICAgICAgICAgImRlc2NyaXB0b3IiLCBkZXNjcmlwdG9yXy0+Y29udGFpbmluZ190eXBlKCktPm9wdGlvbnMoKQorICAgICAgICAgICAgICAgICAgICAgICAgLm5vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3IoKQorICAgICAgICAgICAgICAgICAgICAgICAgPyAiZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0RGVzY3JpcHRvckZvclR5cGUoKSIKKyAgICAgICAgICAgICAgICAgICAgICAgIDogImdldERlc2NyaXB0b3IoKSIsCisgICAgICAgICAgImluZGV4IiwgU2ltcGxlSXRvYShkZXNjcmlwdG9yXy0+aW5kZXgoKSkpOworICAgIH0KKworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIn1cbiIKKyAgICAgICJcbiIKKyAgICAgICJwcml2YXRlIHN0YXRpYyBmaW5hbCAkY2xhc3NuYW1lJFtdIFZBTFVFUyA9ICIsCisgICAgICAiY2xhc3NuYW1lIiwgZGVzY3JpcHRvcl8tPm5hbWUoKSk7CisKKyAgICBpZiAoQ2FuVXNlRW51bVZhbHVlcygpKSB7CisgICAgICAvLyBJZiB0aGUgY29uc3RhbnRzIHdlIGFyZSBnb2luZyB0byBvdXRwdXQgYXJlIGV4YWN0bHkgdGhlIG9uZXMgd2UKKyAgICAgIC8vIGhhdmUgZGVjbGFyZWQgaW4gdGhlIEphdmEgZW51bSBpbiB0aGUgc2FtZSBvcmRlciwgdGhlbiB3ZSBjYW4gdXNlCisgICAgICAvLyB0aGUgdmFsdWVzKCkgbWV0aG9kIHRoYXQgdGhlIEphdmEgY29tcGlsZXIgYXV0b21hdGljYWxseSBnZW5lcmF0ZXMKKyAgICAgIC8vIGZvciBldmVyeSBlbnVtLgorICAgICAgcHJpbnRlci0+UHJpbnQoInZhbHVlcygpO1xuIik7CisgICAgfSBlbHNlIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAie1xuIgorICAgICAgICAiICAiKTsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPnZhbHVlX2NvdW50KCk7IGkrKykgeworICAgICAgICBwcmludGVyLT5QcmludCgiJG5hbWUkLCAiLAorICAgICAgICAgICJuYW1lIiwgZGVzY3JpcHRvcl8tPnZhbHVlKGkpLT5uYW1lKCkpOworICAgICAgfQorICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgIlxuIgorICAgICAgICAgICJ9O1xuIik7CisgICAgfQorCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiXG4iCisgICAgICAicHVibGljIHN0YXRpYyAkY2xhc3NuYW1lJCB2YWx1ZU9mKFxuIgorICAgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IgZGVzYykge1xuIgorICAgICAgIiAgaWYgKGRlc2MuZ2V0VHlwZSgpICE9IGdldERlc2NyaXB0b3IoKSkge1xuIgorICAgICAgIiAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihcbiIKKyAgICAgICIgICAgICBcIkVudW1WYWx1ZURlc2NyaXB0b3IgaXMgbm90IGZvciB0aGlzIHR5cGUuXCIpO1xuIgorICAgICAgIiAgfVxuIiwKKyAgICAgICJjbGFzc25hbWUiLCBkZXNjcmlwdG9yXy0+bmFtZSgpKTsKKyAgICBpZiAoU3VwcG9ydFVua25vd25FbnVtVmFsdWUoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiICBpZiAoZGVzYy5nZXRJbmRleCgpID09IC0xKSB7XG4iCisgICAgICAgICIgICAgcmV0dXJuIFVOUkVDT0dOSVpFRDtcbiIKKyAgICAgICAgIiAgfVxuIik7CisgICAgfQorICAgIHByaW50ZXItPlByaW50KAorICAgICAgIiAgcmV0dXJuIFZBTFVFU1tkZXNjLmdldEluZGV4KCldO1xuIgorICAgICAgIn1cbiIKKyAgICAgICJcbiIpOworCisgICAgcHJpbnRlci0+UHJpbnQoInByaXZhdGUgZmluYWwgaW50IGluZGV4O1xuIik7CisgIH0KKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIHByaW50ZXItPlByaW50KAorICAgICJwcml2YXRlIGZpbmFsIGludCB2YWx1ZTtcblxuIgorICAgICJwcml2YXRlICRjbGFzc25hbWUkKGludCBpbmRleCwgaW50IHZhbHVlKSB7XG4iLAorICAgICJjbGFzc25hbWUiLCBkZXNjcmlwdG9yXy0+bmFtZSgpKTsKKyAgaWYgKEhhc0Rlc2NyaXB0b3JNZXRob2RzKGRlc2NyaXB0b3JfKSkgeworICAgIHByaW50ZXItPlByaW50KCIgIHRoaXMuaW5kZXggPSBpbmRleDtcbiIpOworICB9CisgIHByaW50ZXItPlByaW50KAorICAgICIgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiIKKyAgICAifVxuIik7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIlxuIgorICAgICIvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZW51bV9zY29wZTokZnVsbF9uYW1lJClcbiIsCisgICAgImZ1bGxfbmFtZSIsIGRlc2NyaXB0b3JfLT5mdWxsX25hbWUoKSk7CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgifVxuXG4iKTsKK30KKworYm9vbCBFbnVtR2VuZXJhdG9yOjpDYW5Vc2VFbnVtVmFsdWVzKCkgeworICBpZiAoY2Fub25pY2FsX3ZhbHVlc18uc2l6ZSgpICE9IGRlc2NyaXB0b3JfLT52YWx1ZV9jb3VudCgpKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPnZhbHVlX2NvdW50KCk7IGkrKykgeworICAgIGlmIChkZXNjcmlwdG9yXy0+dmFsdWUoaSktPm5hbWUoKSAhPSBjYW5vbmljYWxfdmFsdWVzX1tpXS0+bmFtZSgpKSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICB9CisgIHJldHVybiB0cnVlOworfQorCit9ICAvLyBuYW1lc3BhY2UgamF2YQorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2VudW0uaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2VudW0uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMGQ5MWY1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZW51bS5oCkBAIC0wLDAgKzEsOTkgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9FTlVNX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9FTlVNX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPHZlY3Rvcj4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisgIG5hbWVzcGFjZSBjb21waWxlciB7CisgICAgbmFtZXNwYWNlIGphdmEgeworICAgICAgY2xhc3MgQ29udGV4dDsgICAgICAgICAgIC8vIGNvbnRleHQuaAorICAgICAgY2xhc3MgQ2xhc3NOYW1lUmVzb2x2ZXI7IC8vIG5hbWVfcmVzb2x2ZXIuaAorICAgIH0KKyAgfQorICBuYW1lc3BhY2UgaW8geworICAgIGNsYXNzIFByaW50ZXI7ICAgICAgICAgICAgIC8vIHByaW50ZXIuaAorICB9Cit9CisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmEgeworCitjbGFzcyBFbnVtR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IEVudW1HZW5lcmF0b3IoY29uc3QgRW51bURlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpbW11dGFibGVfYXBpLAorICAgICAgICAgICAgICAgICAgICAgICAgIENvbnRleHQqIGNvbnRleHQpOworICB+RW51bUdlbmVyYXRvcigpOworCisgIHZvaWQgR2VuZXJhdGUoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgcHJpdmF0ZToKKyAgY29uc3QgRW51bURlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworCisgIC8vIFRoZSBwcm90byBsYW5ndWFnZSBhbGxvd3MgbXVsdGlwbGUgZW51bSBjb25zdGFudHMgdG8gaGF2ZSB0aGUgc2FtZSBudW1lcmljCisgIC8vIHZhbHVlLiAgSmF2YSwgaG93ZXZlciwgZG9lcyBub3QgYWxsb3cgbXVsdGlwbGUgZW51bSBjb25zdGFudHMgdG8gYmUKKyAgLy8gY29uc2lkZXJlZCBlcXVpdmFsZW50LiAgV2UgdHJlYXQgdGhlIGZpcnN0IGRlZmluZWQgY29uc3RhbnQgZm9yIGFueQorICAvLyBnaXZlbiBudW1lcmljIHZhbHVlIGFzICJjYW5vbmljYWwiIGFuZCB0aGUgcmVzdCBhcyBhbGlhc2VzIG9mIHRoYXQKKyAgLy8gY2Fub25pY2FsIHZhbHVlLgorICB2ZWN0b3I8Y29uc3QgRW51bVZhbHVlRGVzY3JpcHRvcio+IGNhbm9uaWNhbF92YWx1ZXNfOworCisgIHN0cnVjdCBBbGlhcyB7CisgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogdmFsdWU7CisgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogY2Fub25pY2FsX3ZhbHVlOworICB9OworICB2ZWN0b3I8QWxpYXM+IGFsaWFzZXNfOworCisgIGJvb2wgaW1tdXRhYmxlX2FwaV87CisKKyAgQ29udGV4dCogY29udGV4dF87CisgIENsYXNzTmFtZVJlc29sdmVyKiBuYW1lX3Jlc29sdmVyXzsKKworICBib29sIENhblVzZUVudW1WYWx1ZXMoKTsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoRW51bUdlbmVyYXRvcik7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgamF2YQorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9FTlVNX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZW51bV9maWVsZC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2VudW1fZmllbGQuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTU4ZGE5NgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2VudW1fZmllbGQuY2MKQEAgLTAsMCArMSw5NjkgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2luY2x1ZGUgPG1hcD4KKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbG9nZ2luZy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2NvbnRleHQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2RvY19jb21tZW50Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9lbnVtX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9uYW1lX3Jlc29sdmVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmEgeworCituYW1lc3BhY2UgeworCit2b2lkIFNldEVudW1WYXJpYWJsZXMoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgIGludCBtZXNzYWdlQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZEdlbmVyYXRvckluZm8qIGluZm8sCisgICAgICAgICAgICAgICAgICAgICAgQ2xhc3NOYW1lUmVzb2x2ZXIqIG5hbWVfcmVzb2x2ZXIsCisgICAgICAgICAgICAgICAgICAgICAgbWFwPHN0cmluZywgc3RyaW5nPiogdmFyaWFibGVzKSB7CisgIFNldENvbW1vbkZpZWxkVmFyaWFibGVzKGRlc2NyaXB0b3IsIGluZm8sIHZhcmlhYmxlcyk7CisKKyAgKCp2YXJpYWJsZXMpWyJ0eXBlIl0gPQorICAgICAgbmFtZV9yZXNvbHZlci0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3ItPmVudW1fdHlwZSgpKTsKKyAgKCp2YXJpYWJsZXMpWyJtdXRhYmxlX3R5cGUiXSA9CisgICAgICBuYW1lX3Jlc29sdmVyLT5HZXRNdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3ItPmVudW1fdHlwZSgpKTsKKyAgKCp2YXJpYWJsZXMpWyJkZWZhdWx0Il0gPSBJbW11dGFibGVEZWZhdWx0VmFsdWUoZGVzY3JpcHRvciwgbmFtZV9yZXNvbHZlcik7CisgICgqdmFyaWFibGVzKVsiZGVmYXVsdF9udW1iZXIiXSA9IFNpbXBsZUl0b2EoCisgICAgICBkZXNjcmlwdG9yLT5kZWZhdWx0X3ZhbHVlX2VudW0oKS0+bnVtYmVyKCkpOworICBpZiAoZGVzY3JpcHRvci0+aXNfcGFja2VkKCkpIHsKKyAgICAoKnZhcmlhYmxlcylbInRhZyJdID0gU2ltcGxlSXRvYShpbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1ha2VUYWcoCisgICAgICAgIGRlc2NyaXB0b3ItPm51bWJlcigpLAorICAgICAgICBpbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQpKTsKKyAgfSBlbHNlIHsKKyAgICAoKnZhcmlhYmxlcylbInRhZyJdID0gU2ltcGxlSXRvYShpbnRlcm5hbDo6V2lyZUZvcm1hdDo6TWFrZVRhZyhkZXNjcmlwdG9yKSk7CisgIH0KKyAgKCp2YXJpYWJsZXMpWyJ0YWdfc2l6ZSJdID0gU2ltcGxlSXRvYSgKKyAgICAgIGludGVybmFsOjpXaXJlRm9ybWF0OjpUYWdTaXplKGRlc2NyaXB0b3ItPm51bWJlcigpLCBHZXRUeXBlKGRlc2NyaXB0b3IpKSk7CisgIC8vIFRPRE8oYmlyZG8pOiBBZGQgQGRlcHJlY2F0ZWQgamF2YWRvYyB3aGVuIGdlbmVyYXRpbmcgamF2YWRvYyBpcyBzdXBwb3J0ZWQKKyAgLy8gYnkgdGhlIHByb3RvIGNvbXBpbGVyCisgICgqdmFyaWFibGVzKVsiZGVwcmVjYXRpb24iXSA9IGRlc2NyaXB0b3ItPm9wdGlvbnMoKS5kZXByZWNhdGVkKCkKKyAgICAgID8gIkBqYXZhLmxhbmcuRGVwcmVjYXRlZCAiIDogIiI7CisgICgqdmFyaWFibGVzKVsib25fY2hhbmdlZCJdID0KKyAgICAgIEhhc0Rlc2NyaXB0b3JNZXRob2RzKGRlc2NyaXB0b3ItPmNvbnRhaW5pbmdfdHlwZSgpKSA/ICJvbkNoYW5nZWQoKTsiIDogIiI7CisKKyAgaWYgKFN1cHBvcnRGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3ItPmZpbGUoKSkpIHsKKyAgICAvLyBGb3Igc2luZ3VsYXIgbWVzc2FnZXMgYW5kIGJ1aWxkZXJzLCBvbmUgYml0IGlzIHVzZWQgZm9yIHRoZSBoYXNGaWVsZCBiaXQuCisgICAgKCp2YXJpYWJsZXMpWyJnZXRfaGFzX2ZpZWxkX2JpdF9tZXNzYWdlIl0gPSBHZW5lcmF0ZUdldEJpdChtZXNzYWdlQml0SW5kZXgpOworICAgICgqdmFyaWFibGVzKVsiZ2V0X2hhc19maWVsZF9iaXRfYnVpbGRlciJdID0gR2VuZXJhdGVHZXRCaXQoYnVpbGRlckJpdEluZGV4KTsKKworICAgIC8vIE5vdGUgdGhhdCB0aGVzZSBoYXZlIGEgdHJhaWxpbmcgIjsiLgorICAgICgqdmFyaWFibGVzKVsic2V0X2hhc19maWVsZF9iaXRfbWVzc2FnZSJdID0KKyAgICAgICAgR2VuZXJhdGVTZXRCaXQobWVzc2FnZUJpdEluZGV4KSArICI7IjsKKyAgICAoKnZhcmlhYmxlcylbInNldF9oYXNfZmllbGRfYml0X2J1aWxkZXIiXSA9CisgICAgICAgIEdlbmVyYXRlU2V0Qml0KGJ1aWxkZXJCaXRJbmRleCkgKyAiOyI7CisgICAgKCp2YXJpYWJsZXMpWyJjbGVhcl9oYXNfZmllbGRfYml0X2J1aWxkZXIiXSA9CisgICAgICAgIEdlbmVyYXRlQ2xlYXJCaXQoYnVpbGRlckJpdEluZGV4KSArICI7IjsKKworICAgICgqdmFyaWFibGVzKVsiaXNfZmllbGRfcHJlc2VudF9tZXNzYWdlIl0gPSBHZW5lcmF0ZUdldEJpdChtZXNzYWdlQml0SW5kZXgpOworICB9IGVsc2UgeworICAgICgqdmFyaWFibGVzKVsic2V0X2hhc19maWVsZF9iaXRfbWVzc2FnZSJdID0gIiI7CisgICAgKCp2YXJpYWJsZXMpWyJzZXRfaGFzX2ZpZWxkX2JpdF9idWlsZGVyIl0gPSAiIjsKKyAgICAoKnZhcmlhYmxlcylbImNsZWFyX2hhc19maWVsZF9iaXRfYnVpbGRlciJdID0gIiI7CisKKyAgICAoKnZhcmlhYmxlcylbImlzX2ZpZWxkX3ByZXNlbnRfbWVzc2FnZSJdID0KKyAgICAgICAgKCp2YXJpYWJsZXMpWyJuYW1lIl0gKyAiXyAhPSAiICsKKyAgICAgICAgKCp2YXJpYWJsZXMpWyJkZWZhdWx0Il0gKyAiLmdldE51bWJlcigpIjsKKyAgfQorCisgIC8vIEZvciByZXBhdGVkIGJ1aWxkZXJzLCBvbmUgYml0IGlzIHVzZWQgZm9yIHdoZXRoZXIgdGhlIGFycmF5IGlzIGltbXV0YWJsZS4KKyAgKCp2YXJpYWJsZXMpWyJnZXRfbXV0YWJsZV9iaXRfYnVpbGRlciJdID0gR2VuZXJhdGVHZXRCaXQoYnVpbGRlckJpdEluZGV4KTsKKyAgKCp2YXJpYWJsZXMpWyJzZXRfbXV0YWJsZV9iaXRfYnVpbGRlciJdID0gR2VuZXJhdGVTZXRCaXQoYnVpbGRlckJpdEluZGV4KTsKKyAgKCp2YXJpYWJsZXMpWyJjbGVhcl9tdXRhYmxlX2JpdF9idWlsZGVyIl0gPSBHZW5lcmF0ZUNsZWFyQml0KGJ1aWxkZXJCaXRJbmRleCk7CisKKyAgLy8gRm9yIHJlcGVhdGVkIGZpZWxkcywgb25lIGJpdCBpcyB1c2VkIGZvciB3aGV0aGVyIHRoZSBhcnJheSBpcyBpbW11dGFibGUKKyAgLy8gaW4gdGhlIHBhcnNpbmcgY29uc3RydWN0b3IuCisgICgqdmFyaWFibGVzKVsiZ2V0X211dGFibGVfYml0X3BhcnNlciJdID0KKyAgICAgIEdlbmVyYXRlR2V0Qml0TXV0YWJsZUxvY2FsKGJ1aWxkZXJCaXRJbmRleCk7CisgICgqdmFyaWFibGVzKVsic2V0X211dGFibGVfYml0X3BhcnNlciJdID0KKyAgICAgIEdlbmVyYXRlU2V0Qml0TXV0YWJsZUxvY2FsKGJ1aWxkZXJCaXRJbmRleCk7CisKKyAgKCp2YXJpYWJsZXMpWyJnZXRfaGFzX2ZpZWxkX2JpdF9mcm9tX2xvY2FsIl0gPQorICAgICAgR2VuZXJhdGVHZXRCaXRGcm9tTG9jYWwoYnVpbGRlckJpdEluZGV4KTsKKyAgKCp2YXJpYWJsZXMpWyJzZXRfaGFzX2ZpZWxkX2JpdF90b19sb2NhbCJdID0KKyAgICAgIEdlbmVyYXRlU2V0Qml0VG9Mb2NhbChtZXNzYWdlQml0SW5kZXgpOworCisgIGlmIChTdXBwb3J0VW5rbm93bkVudW1WYWx1ZShkZXNjcmlwdG9yLT5maWxlKCkpKSB7CisgICAgKCp2YXJpYWJsZXMpWyJ1bmtub3duIl0gPSAoKnZhcmlhYmxlcylbInR5cGUiXSArICIuVU5SRUNPR05JWkVEIjsKKyAgfSBlbHNlIHsKKyAgICAoKnZhcmlhYmxlcylbInVua25vd24iXSA9ICgqdmFyaWFibGVzKVsiZGVmYXVsdCJdOworICB9Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK0ltbXV0YWJsZUVudW1GaWVsZEdlbmVyYXRvcjo6CitJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBtZXNzYWdlQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb250ZXh0KiBjb250ZXh0KQorICA6IGRlc2NyaXB0b3JfKGRlc2NyaXB0b3IpLCBtZXNzYWdlQml0SW5kZXhfKG1lc3NhZ2VCaXRJbmRleCksCisgICAgYnVpbGRlckJpdEluZGV4XyhidWlsZGVyQml0SW5kZXgpLAorICAgIG5hbWVfcmVzb2x2ZXJfKGNvbnRleHQtPkdldE5hbWVSZXNvbHZlcigpKSB7CisgIFNldEVudW1WYXJpYWJsZXMoZGVzY3JpcHRvciwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgY29udGV4dC0+R2V0RmllbGRHZW5lcmF0b3JJbmZvKGRlc2NyaXB0b3IpLAorICAgICAgICAgICAgICAgICAgIG5hbWVfcmVzb2x2ZXJfLCAmdmFyaWFibGVzXyk7Cit9CisKK0ltbXV0YWJsZUVudW1GaWVsZEdlbmVyYXRvcjo6fkltbXV0YWJsZUVudW1GaWVsZEdlbmVyYXRvcigpIHt9CisKK2ludCBJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3I6OkdldE51bUJpdHNGb3JNZXNzYWdlKCkgY29uc3QgeworICByZXR1cm4gMTsKK30KKworaW50IEltbXV0YWJsZUVudW1GaWVsZEdlbmVyYXRvcjo6R2V0TnVtQml0c0ZvckJ1aWxkZXIoKSBjb25zdCB7CisgIHJldHVybiAxOworfQorCit2b2lkIEltbXV0YWJsZUVudW1GaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUludGVyZmFjZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKFN1cHBvcnRGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJGRlcHJlY2F0aW9uJGJvb2xlYW4gaGFzJGNhcGl0YWxpemVkX25hbWUkKCk7XG4iKTsKKyAgfQorICBpZiAoU3VwcG9ydFVua25vd25FbnVtVmFsdWUoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kaW50IGdldCRjYXBpdGFsaXplZF9uYW1lJFZhbHVlKCk7XG4iKTsKKyAgfQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiQkdHlwZSQgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCk7XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgaW50ICRuYW1lJF87XG4iKTsKKyAgUHJpbnRFeHRyYUZpZWxkSW5mbyh2YXJpYWJsZXNfLCBwcmludGVyKTsKKyAgaWYgKFN1cHBvcnRGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBib29sZWFuIGhhcyRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAgICIgIHJldHVybiAkZ2V0X2hhc19maWVsZF9iaXRfbWVzc2FnZSQ7XG4iCisgICAgICAifVxuIik7CisgIH0KKyAgaWYgKFN1cHBvcnRVbmtub3duRW51bVZhbHVlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBpbnQgZ2V0JGNhcGl0YWxpemVkX25hbWUkVmFsdWUoKSB7XG4iCisgICAgICAiICByZXR1cm4gJG5hbWUkXztcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAiICAkdHlwZSQgcmVzdWx0ID0gJHR5cGUkLnZhbHVlT2YoJG5hbWUkXyk7XG4iCisgICAgIiAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gJHVua25vd24kIDogcmVzdWx0O1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIGludCAkbmFtZSRfID0gJGRlZmF1bHRfbnVtYmVyJDtcbiIpOworICBpZiAoU3VwcG9ydEZpZWxkUHJlc2VuY2UoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljIGJvb2xlYW4gaGFzJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICAgIiAgcmV0dXJuICRnZXRfaGFzX2ZpZWxkX2JpdF9idWlsZGVyJDtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorICBpZiAoU3VwcG9ydFVua25vd25FbnVtVmFsdWUoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljIGludCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRWYWx1ZSgpIHtcbiIKKyAgICAgICIgIHJldHVybiAkbmFtZSRfO1xuIgorICAgICAgIn1cbiIpOworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBzZXQkY2FwaXRhbGl6ZWRfbmFtZSRWYWx1ZShpbnQgdmFsdWUpIHtcbiIKKyAgICAgICIgICRuYW1lJF8gPSB2YWx1ZTtcbiIKKyAgICAgICIgICRvbl9jaGFuZ2VkJFxuIgorICAgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgICAifVxuIik7CisgIH0KKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljICR0eXBlJCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgJHR5cGUkIHJlc3VsdCA9ICR0eXBlJC52YWx1ZU9mKCRuYW1lJF8pO1xuIgorICAgICIgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/ICR1bmtub3duJCA6IHJlc3VsdDtcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIHNldCRjYXBpdGFsaXplZF9uYW1lJCgkdHlwZSQgdmFsdWUpIHtcbiIKKyAgICAiICBpZiAodmFsdWUgPT0gbnVsbCkge1xuIgorICAgICIgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7XG4iCisgICAgIiAgfVxuIgorICAgICIgICRzZXRfaGFzX2ZpZWxkX2JpdF9idWlsZGVyJFxuIgorICAgICIgICRuYW1lJF8gPSB2YWx1ZS5nZXROdW1iZXIoKTtcbiIKKyAgICAiICAkb25fY2hhbmdlZCRcbiIKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGNsZWFyJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgICRjbGVhcl9oYXNfZmllbGRfYml0X2J1aWxkZXIkXG4iCisgICAgIiAgJG5hbWUkXyA9ICRkZWZhdWx0X251bWJlciQ7XG4iCisgICAgIiAgJG9uX2NoYW5nZWQkXG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZUVudW1GaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUZpZWxkQnVpbGRlckluaXRpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgIGNvbnN0IHsKKyAgLy8gbm9vcCBmb3IgZW51bXMKK30KKwordm9pZCBJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgIiRuYW1lJF8gPSAkZGVmYXVsdF9udW1iZXIkO1xuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRlckNsZWFyQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkbmFtZSRfID0gJGRlZmF1bHRfbnVtYmVyJDtcbiIKKyAgICAiJGNsZWFyX2hhc19maWVsZF9iaXRfYnVpbGRlciRcbiIpOworfQorCit2b2lkIEltbXV0YWJsZUVudW1GaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaWYgKG90aGVyLmhhcyRjYXBpdGFsaXplZF9uYW1lJCgpKSB7XG4iCisgICAgICAiICBzZXQkY2FwaXRhbGl6ZWRfbmFtZSQob3RoZXIuZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkpO1xuIgorICAgICAgIn1cbiIpOworICB9IGVsc2UgaWYgKFN1cHBvcnRVbmtub3duRW51bVZhbHVlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJpZiAob3RoZXIuJG5hbWUkXyAhPSAkZGVmYXVsdF9udW1iZXIkKSB7XG4iCisgICAgICAiICBzZXQkY2FwaXRhbGl6ZWRfbmFtZSRWYWx1ZShvdGhlci5nZXQkY2FwaXRhbGl6ZWRfbmFtZSRWYWx1ZSgpKTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ2FuJ3QgcmVhY2ggaGVyZS4iOworICB9Cit9CisKK3ZvaWQgSW1tdXRhYmxlRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaWYgKCRnZXRfaGFzX2ZpZWxkX2JpdF9mcm9tX2xvY2FsJCkge1xuIgorICAgICAgIiAgJHNldF9oYXNfZmllbGRfYml0X3RvX2xvY2FsJDtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJyZXN1bHQuJG5hbWUkXyA9ICRuYW1lJF87XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVQYXJzaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoU3VwcG9ydFVua25vd25FbnVtVmFsdWUoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImludCByYXdWYWx1ZSA9IGlucHV0LnJlYWRFbnVtKCk7XG4iCisgICAgICAiJHNldF9oYXNfZmllbGRfYml0X21lc3NhZ2UkXG4iCisgICAgICAiJG5hbWUkXyA9IHJhd1ZhbHVlO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJpbnQgcmF3VmFsdWUgPSBpbnB1dC5yZWFkRW51bSgpO1xuIgorICAgICAgIiR0eXBlJCB2YWx1ZSA9ICR0eXBlJC52YWx1ZU9mKHJhd1ZhbHVlKTtcbiIKKyAgICAgICJpZiAodmFsdWUgPT0gbnVsbCkge1xuIik7CisgICAgaWYgKFByZXNlcnZlVW5rbm93bkZpZWxkcyhkZXNjcmlwdG9yXy0+Y29udGFpbmluZ190eXBlKCkpKSB7CisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAiICB1bmtub3duRmllbGRzLm1lcmdlVmFyaW50RmllbGQoJG51bWJlciQsIHJhd1ZhbHVlKTtcbiIpOworICAgIH0KKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIn0gZWxzZSB7XG4iCisgICAgICAiICAkc2V0X2hhc19maWVsZF9iaXRfbWVzc2FnZSRcbiIKKyAgICAgICIgICRuYW1lJF8gPSByYXdWYWx1ZTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorfQorCit2b2lkIEltbXV0YWJsZUVudW1GaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVBhcnNpbmdEb25lQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBub29wIGZvciBlbnVtcworfQorCit2b2lkIEltbXV0YWJsZUVudW1GaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkaXNfZmllbGRfcHJlc2VudF9tZXNzYWdlJCkge1xuIgorICAgICIgIG91dHB1dC53cml0ZUVudW0oJG51bWJlciQsICRuYW1lJF8pO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCRpc19maWVsZF9wcmVzZW50X21lc3NhZ2UkKSB7XG4iCisgICAgIiAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtXG4iCisgICAgIiAgICAuY29tcHV0ZUVudW1TaXplKCRudW1iZXIkLCAkbmFtZSRfKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJyZXN1bHQgPSByZXN1bHQgJiYgJG5hbWUkXyA9PSBvdGhlci4kbmFtZSRfO1xuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlSGFzaENvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaGFzaCA9ICgzNyAqIGhhc2gpICsgJGNvbnN0YW50X25hbWUkO1xuIgorICAgICJoYXNoID0gKDUzICogaGFzaCkgKyAkbmFtZSRfO1xuIik7Cit9CisKK3N0cmluZyBJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3I6OkdldEJveGVkVHlwZSgpIGNvbnN0IHsKKyAgcmV0dXJuIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcl8tPmVudW1fdHlwZSgpKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitJbW11dGFibGVFbnVtT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitJbW11dGFibGVFbnVtT25lb2ZGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnRleHQqIGNvbnRleHQpCisgICAgOiBJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3IoCisgICAgICAgICAgZGVzY3JpcHRvciwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsIGNvbnRleHQpIHsKKyAgY29uc3QgT25lb2ZHZW5lcmF0b3JJbmZvKiBpbmZvID0KKyAgICAgIGNvbnRleHQtPkdldE9uZW9mR2VuZXJhdG9ySW5mbyhkZXNjcmlwdG9yLT5jb250YWluaW5nX29uZW9mKCkpOworICBTZXRDb21tb25PbmVvZlZhcmlhYmxlcyhkZXNjcmlwdG9yLCBpbmZvLCAmdmFyaWFibGVzXyk7Cit9CisKK0ltbXV0YWJsZUVudW1PbmVvZkZpZWxkR2VuZXJhdG9yOjoKK35JbW11dGFibGVFbnVtT25lb2ZGaWVsZEdlbmVyYXRvcigpIHt9CisKK3ZvaWQgSW1tdXRhYmxlRW51bU9uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIFByaW50RXh0cmFGaWVsZEluZm8odmFyaWFibGVzXywgcHJpbnRlcik7CisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgYm9vbGVhbiBoYXMkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgICAiICByZXR1cm4gJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkO1xuIgorICAgICAgIn1cbiIpOworICB9CisgIGlmIChTdXBwb3J0VW5rbm93bkVudW1WYWx1ZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgaW50IGdldCRjYXBpdGFsaXplZF9uYW1lJFZhbHVlKCkge1xuIgorICAgICAgIiAgaWYgKCRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJCkge1xuIgorICAgICAgIiAgICByZXR1cm4gKGphdmEubGFuZy5JbnRlZ2VyKSAkb25lb2ZfbmFtZSRfO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIiAgcmV0dXJuICRkZWZhdWx0X251bWJlciQ7XG4iCisgICAgICAifVxuIik7CisgIH0KKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljICR0eXBlJCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgaWYgKCRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJCkge1xuIgorICAgICIgICAgJHR5cGUkIHJlc3VsdCA9ICAkdHlwZSQudmFsdWVPZigoamF2YS5sYW5nLkludGVnZXIpICRvbmVvZl9uYW1lJF8pO1xuIgorICAgICIgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gJHVua25vd24kIDogcmVzdWx0O1xuIgorICAgICIgIH1cbiIKKyAgICAiICByZXR1cm4gJGRlZmF1bHQkO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVFbnVtT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUJ1aWxkZXJNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgYm9vbGVhbiBoYXMkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgICAiICByZXR1cm4gJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkO1xuIgorICAgICAgIn1cbiIpOworICB9CisgIGlmIChTdXBwb3J0VW5rbm93bkVudW1WYWx1ZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgaW50IGdldCRjYXBpdGFsaXplZF9uYW1lJFZhbHVlKCkge1xuIgorICAgICAgIiAgaWYgKCRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJCkge1xuIgorICAgICAgIiAgICByZXR1cm4gKChqYXZhLmxhbmcuSW50ZWdlcikgJG9uZW9mX25hbWUkXykuaW50VmFsdWUoKTtcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICIgIHJldHVybiAkZGVmYXVsdF9udW1iZXIkO1xuIgorICAgICAgIn1cbiIpOworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBzZXQkY2FwaXRhbGl6ZWRfbmFtZSRWYWx1ZShpbnQgdmFsdWUpIHtcbiIKKyAgICAgICIgICRzZXRfb25lb2ZfY2FzZV9tZXNzYWdlJDtcbiIKKyAgICAgICIgICRvbmVvZl9uYW1lJF8gPSB2YWx1ZTtcbiIKKyAgICAgICIgICRvbl9jaGFuZ2VkJFxuIgorICAgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgICAifVxuIik7CisgIH0KKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljICR0eXBlJCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgaWYgKCRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJCkge1xuIgorICAgICIgICAgJHR5cGUkIHJlc3VsdCA9ICAkdHlwZSQudmFsdWVPZigoamF2YS5sYW5nLkludGVnZXIpICRvbmVvZl9uYW1lJF8pO1xuIgorICAgICIgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gJHVua25vd24kIDogcmVzdWx0O1xuIgorICAgICIgIH1cbiIKKyAgICAiICByZXR1cm4gJGRlZmF1bHQkO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgc2V0JGNhcGl0YWxpemVkX25hbWUkKCR0eXBlJCB2YWx1ZSkge1xuIgorICAgICIgIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4iCisgICAgIiAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTtcbiIKKyAgICAiICB9XG4iCisgICAgIiAgJHNldF9vbmVvZl9jYXNlX21lc3NhZ2UkO1xuIgorICAgICIgICRvbmVvZl9uYW1lJF8gPSB2YWx1ZS5nZXROdW1iZXIoKTtcbiIKKyAgICAiICAkb25fY2hhbmdlZCRcbiIKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGNsZWFyJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgIGlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIKKyAgICAiICAgICRjbGVhcl9vbmVvZl9jYXNlX21lc3NhZ2UkO1xuIgorICAgICIgICAgJG9uZW9mX25hbWUkXyA9IG51bGw7XG4iCisgICAgIiAgICAkb25fY2hhbmdlZCRcbiIKKyAgICAiICB9XG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZUVudW1PbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIKKyAgICAiICByZXN1bHQuJG9uZW9mX25hbWUkXyA9ICRvbmVvZl9uYW1lJF87XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZUVudW1PbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKFN1cHBvcnRVbmtub3duRW51bVZhbHVlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJzZXQkY2FwaXRhbGl6ZWRfbmFtZSRWYWx1ZShvdGhlci5nZXQkY2FwaXRhbGl6ZWRfbmFtZSRWYWx1ZSgpKTtcbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAic2V0JGNhcGl0YWxpemVkX25hbWUkKG90aGVyLmdldCRjYXBpdGFsaXplZF9uYW1lJCgpKTtcbiIpOworICB9Cit9CisKK3ZvaWQgSW1tdXRhYmxlRW51bU9uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVQYXJzaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoU3VwcG9ydFVua25vd25FbnVtVmFsdWUoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImludCByYXdWYWx1ZSA9IGlucHV0LnJlYWRFbnVtKCk7XG4iCisgICAgICAiJHNldF9vbmVvZl9jYXNlX21lc3NhZ2UkO1xuIgorICAgICAgIiRvbmVvZl9uYW1lJF8gPSByYXdWYWx1ZTtcbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaW50IHJhd1ZhbHVlID0gaW5wdXQucmVhZEVudW0oKTtcbiIKKyAgICAgICIkdHlwZSQgdmFsdWUgPSAkdHlwZSQudmFsdWVPZihyYXdWYWx1ZSk7XG4iCisgICAgICAiaWYgKHZhbHVlID09IG51bGwpIHtcbiIpOworICAgIGlmIChQcmVzZXJ2ZVVua25vd25GaWVsZHMoZGVzY3JpcHRvcl8tPmNvbnRhaW5pbmdfdHlwZSgpKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgIiAgdW5rbm93bkZpZWxkcy5tZXJnZVZhcmludEZpZWxkKCRudW1iZXIkLCByYXdWYWx1ZSk7XG4iKTsKKyAgICB9CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJ9IGVsc2Uge1xuIgorICAgICAgIiAgJHNldF9vbmVvZl9jYXNlX21lc3NhZ2UkO1xuIgorICAgICAgIiAgJG9uZW9mX25hbWUkXyA9IHJhd1ZhbHVlO1xuIgorICAgICAgIn1cbiIpOworICB9Cit9CisKK3ZvaWQgSW1tdXRhYmxlRW51bU9uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iCisgICAgIiAgb3V0cHV0LndyaXRlRW51bSgkbnVtYmVyJCwgKChqYXZhLmxhbmcuSW50ZWdlcikgJG9uZW9mX25hbWUkXykpO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVFbnVtT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iCisgICAgIiAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtXG4iCisgICAgIiAgICAuY29tcHV0ZUVudW1TaXplKCRudW1iZXIkLCAoKGphdmEubGFuZy5JbnRlZ2VyKSAkb25lb2ZfbmFtZSRfKSk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZUVudW1PbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoU3VwcG9ydFVua25vd25FbnVtVmFsdWUoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgInJlc3VsdCA9IHJlc3VsdCAmJiBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRWYWx1ZSgpXG4iCisgICAgICAiICAgID09IG90aGVyLmdldCRjYXBpdGFsaXplZF9uYW1lJFZhbHVlKCk7XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgInJlc3VsdCA9IHJlc3VsdCAmJiBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKVxuIgorICAgICAgIiAgICAuZXF1YWxzKG90aGVyLmdldCRjYXBpdGFsaXplZF9uYW1lJCgpKTtcbiIpOworICB9Cit9CisKK3ZvaWQgSW1tdXRhYmxlRW51bU9uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVIYXNoQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoU3VwcG9ydFVua25vd25FbnVtVmFsdWUoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImhhc2ggPSAoMzcgKiBoYXNoKSArICRjb25zdGFudF9uYW1lJDtcbiIKKyAgICAgICJoYXNoID0gKDUzICogaGFzaCkgKyBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRWYWx1ZSgpO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJoYXNoID0gKDM3ICogaGFzaCkgKyAkY29uc3RhbnRfbmFtZSQ7XG4iCisgICAgICAiaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkuZ2V0TnVtYmVyKCk7XG4iKTsKKyAgfQorfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK1JlcGVhdGVkSW1tdXRhYmxlRW51bUZpZWxkR2VuZXJhdG9yOjoKK1JlcGVhdGVkSW1tdXRhYmxlRW51bUZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBtZXNzYWdlQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYnVpbGRlckJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29udGV4dCogY29udGV4dCkKKyAgOiBkZXNjcmlwdG9yXyhkZXNjcmlwdG9yKSwgbWVzc2FnZUJpdEluZGV4XyhtZXNzYWdlQml0SW5kZXgpLAorICAgIGJ1aWxkZXJCaXRJbmRleF8oYnVpbGRlckJpdEluZGV4KSwgY29udGV4dF8oY29udGV4dCksCisgICAgbmFtZV9yZXNvbHZlcl8oY29udGV4dC0+R2V0TmFtZVJlc29sdmVyKCkpIHsKKyAgU2V0RW51bVZhcmlhYmxlcyhkZXNjcmlwdG9yLCBtZXNzYWdlQml0SW5kZXgsIGJ1aWxkZXJCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICBjb250ZXh0LT5HZXRGaWVsZEdlbmVyYXRvckluZm8oZGVzY3JpcHRvciksCisgICAgICAgICAgICAgICAgICAgbmFtZV9yZXNvbHZlcl8sICZ2YXJpYWJsZXNfKTsKK30KKworUmVwZWF0ZWRJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3I6On5SZXBlYXRlZEltbXV0YWJsZUVudW1GaWVsZEdlbmVyYXRvcigpIHt9CisKK2ludCBSZXBlYXRlZEltbXV0YWJsZUVudW1GaWVsZEdlbmVyYXRvcjo6R2V0TnVtQml0c0Zvck1lc3NhZ2UoKSBjb25zdCB7CisgIHJldHVybiAwOworfQorCitpbnQgUmVwZWF0ZWRJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3I6OkdldE51bUJpdHNGb3JCdWlsZGVyKCkgY29uc3QgeworICByZXR1cm4gMTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZUVudW1GaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUludGVyZmFjZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kamF2YS51dGlsLkxpc3Q8JHR5cGUkPiBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRMaXN0KCk7XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kaW50IGdldCRjYXBpdGFsaXplZF9uYW1lJENvdW50KCk7XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kJHR5cGUkIGdldCRjYXBpdGFsaXplZF9uYW1lJChpbnQgaW5kZXgpO1xuIik7CisgIGlmIChTdXBwb3J0VW5rbm93bkVudW1WYWx1ZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj5cbiIKKyAgICAgICJnZXQkY2FwaXRhbGl6ZWRfbmFtZSRWYWx1ZUxpc3QoKTtcbiIpOworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRpbnQgZ2V0JGNhcGl0YWxpemVkX25hbWUkVmFsdWUoaW50IGluZGV4KTtcbiIpOworICB9Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+ICRuYW1lJF87XG4iCisgICAgInByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPFxuIgorICAgICIgICAgamF2YS5sYW5nLkludGVnZXIsICR0eXBlJD4gJG5hbWUkX2NvbnZlcnRlcl8gPVxuIgorICAgICIgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjxcbiIKKyAgICAiICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsICR0eXBlJD4oKSB7XG4iCisgICAgIiAgICAgICAgICBwdWJsaWMgJHR5cGUkIGNvbnZlcnQoamF2YS5sYW5nLkludGVnZXIgZnJvbSkge1xuIgorICAgICIgICAgICAgICAgICAkdHlwZSQgcmVzdWx0ID0gJHR5cGUkLnZhbHVlT2YoZnJvbSk7XG4iCisgICAgIiAgICAgICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/ICR1bmtub3duJCA6IHJlc3VsdDtcbiIKKyAgICAiICAgICAgICAgIH1cbiIKKyAgICAiICAgICAgICB9O1xuIik7CisgIFByaW50RXh0cmFGaWVsZEluZm8odmFyaWFibGVzXywgcHJpbnRlcik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBqYXZhLnV0aWwuTGlzdDwkdHlwZSQ+IGdldCRjYXBpdGFsaXplZF9uYW1lJExpc3QoKSB7XG4iCisgICAgIiAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPFxuIgorICAgICIgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgJHR5cGUkPigkbmFtZSRfLCAkbmFtZSRfY29udmVydGVyXyk7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgaW50IGdldCRjYXBpdGFsaXplZF9uYW1lJENvdW50KCkge1xuIgorICAgICIgIHJldHVybiAkbmFtZSRfLnNpemUoKTtcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSQgZ2V0JGNhcGl0YWxpemVkX25hbWUkKGludCBpbmRleCkge1xuIgorICAgICIgIHJldHVybiAkbmFtZSRfY29udmVydGVyXy5jb252ZXJ0KCRuYW1lJF8uZ2V0KGluZGV4KSk7XG4iCisgICAgIn1cbiIpOworICBpZiAoU3VwcG9ydFVua25vd25FbnVtVmFsdWUoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPlxuIgorICAgICAgImdldCRjYXBpdGFsaXplZF9uYW1lJFZhbHVlTGlzdCgpIHtcbiIKKyAgICAgICIgIHJldHVybiAkbmFtZSRfO1xuIgorICAgICAgIn1cbiIpOworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgaW50IGdldCRjYXBpdGFsaXplZF9uYW1lJFZhbHVlKGludCBpbmRleCkge1xuIgorICAgICAgIiAgcmV0dXJuICRuYW1lJF8uZ2V0KGluZGV4KTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorCisgIGlmIChkZXNjcmlwdG9yXy0+aXNfcGFja2VkKCkgJiYKKyAgICAgIEhhc0dlbmVyYXRlZE1ldGhvZHMoZGVzY3JpcHRvcl8tPmNvbnRhaW5pbmdfdHlwZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAicHJpdmF0ZSBpbnQgJG5hbWUkTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZTtcbiIpOworICB9Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgIC8vIE9uZSBmaWVsZCBpcyB0aGUgbGlzdCBhbmQgdGhlIG90aGVyIGZpZWxkIGtlZXBzIHRyYWNrIG9mIHdoZXRoZXIgdGhlCisgICAgLy8gbGlzdCBpcyBpbW11dGFibGUuIElmIGl0J3MgaW1tdXRhYmxlLCB0aGUgaW52YXJpYW50IGlzIHRoYXQgaXQgbXVzdAorICAgIC8vIGVpdGhlciBhbiBpbnN0YW5jZSBvZiBDb2xsZWN0aW9ucy5lbXB0eUxpc3QoKSBvciBpdCdzIGFuIEFycmF5TGlzdAorICAgIC8vIHdyYXBwZWQgaW4gYSBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KCkgd3JhcHBlciBhbmQgbm9ib2R5IGVsc2UgaGFzCisgICAgLy8gYSByZWZlcmVyZW5jZSB0byB0aGUgdW5kZXJseWluZyBBcnJheUxpc3QuIFRoaXMgaW52YXJpYW50IGFsbG93cyB1cyB0bworICAgIC8vIHNoYXJlIGluc3RhbmNlcyBvZiBsaXN0cyBiZXR3ZWVuIHByb3RvY29sIGJ1ZmZlcnMgYXZvaWRpbmcgZXhwZW5zaXZlCisgICAgLy8gbWVtb3J5IGFsbG9jYXRpb25zLiBOb3RlLCBpbW11dGFibGUgaXMgYSBzdHJvbmcgZ3VhcmFudGVlIGhlcmUgLS0gbm90CisgICAgLy8ganVzdCB0aGF0IHRoZSBsaXN0IGNhbm5vdCBiZSBtb2RpZmllZCB2aWEgdGhlIHJlZmVyZW5jZSBidXQgdGhhdCB0aGUKKyAgICAvLyBsaXN0IGNhbiBuZXZlciBiZSBtb2RpZmllZC4KKyAgICAicHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gJG5hbWUkXyA9XG4iCisgICAgIiAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpO1xuIgorCisgICAgInByaXZhdGUgdm9pZCBlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKSB7XG4iCisgICAgIiAgaWYgKCEkZ2V0X211dGFibGVfYml0X2J1aWxkZXIkKSB7XG4iCisgICAgIiAgICAkbmFtZSRfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8amF2YS5sYW5nLkludGVnZXI+KCRuYW1lJF8pO1xuIgorICAgICIgICAgJHNldF9tdXRhYmxlX2JpdF9idWlsZGVyJDtcbiIKKyAgICAiICB9XG4iCisgICAgIn1cbiIpOworCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAvLyBOb3RlOiAgV2UgcmV0dXJuIGFuIHVubW9kaWZpYWJsZSBsaXN0IGJlY2F1c2Ugb3RoZXJ3aXNlIHRoZSBjYWxsZXIKKyAgICAvLyAgIGNvdWxkIGhvbGQgb24gdG8gdGhlIHJldHVybmVkIGxpc3QgYW5kIG1vZGlmeSBpdCBhZnRlciB0aGUgbWVzc2FnZQorICAgIC8vICAgaGFzIGJlZW4gYnVpbHQsIHRodXMgbXV0YXRpbmcgdGhlIG1lc3NhZ2Ugd2hpY2ggaXMgc3VwcG9zZWQgdG8gYmUKKyAgICAvLyAgIGltbXV0YWJsZS4KKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBqYXZhLnV0aWwuTGlzdDwkdHlwZSQ+IGdldCRjYXBpdGFsaXplZF9uYW1lJExpc3QoKSB7XG4iCisgICAgIiAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPFxuIgorICAgICIgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgJHR5cGUkPigkbmFtZSRfLCAkbmFtZSRfY29udmVydGVyXyk7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgaW50IGdldCRjYXBpdGFsaXplZF9uYW1lJENvdW50KCkge1xuIgorICAgICIgIHJldHVybiAkbmFtZSRfLnNpemUoKTtcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSQgZ2V0JGNhcGl0YWxpemVkX25hbWUkKGludCBpbmRleCkge1xuIgorICAgICIgIHJldHVybiAkbmFtZSRfY29udmVydGVyXy5jb252ZXJ0KCRuYW1lJF8uZ2V0KGluZGV4KSk7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBzZXQkY2FwaXRhbGl6ZWRfbmFtZSQoXG4iCisgICAgIiAgICBpbnQgaW5kZXgsICR0eXBlJCB2YWx1ZSkge1xuIgorICAgICIgIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4iCisgICAgIiAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTtcbiIKKyAgICAiICB9XG4iCisgICAgIiAgZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCk7XG4iCisgICAgIiAgJG5hbWUkXy5zZXQoaW5kZXgsIHZhbHVlLmdldE51bWJlcigpKTtcbiIKKyAgICAiICAkb25fY2hhbmdlZCRcbiIKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGFkZCRjYXBpdGFsaXplZF9uYW1lJCgkdHlwZSQgdmFsdWUpIHtcbiIKKyAgICAiICBpZiAodmFsdWUgPT0gbnVsbCkge1xuIgorICAgICIgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7XG4iCisgICAgIiAgfVxuIgorICAgICIgIGVuc3VyZSRjYXBpdGFsaXplZF9uYW1lJElzTXV0YWJsZSgpO1xuIgorICAgICIgICRuYW1lJF8uYWRkKHZhbHVlLmdldE51bWJlcigpKTtcbiIKKyAgICAiICAkb25fY2hhbmdlZCRcbiIKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGFkZEFsbCRjYXBpdGFsaXplZF9uYW1lJChcbiIKKyAgICAiICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgJHR5cGUkPiB2YWx1ZXMpIHtcbiIKKyAgICAiICBlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKTtcbiIKKyAgICAiICBmb3IgKCR0eXBlJCB2YWx1ZSA6IHZhbHVlcykge1xuIgorICAgICIgICAgJG5hbWUkXy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpO1xuIgorICAgICIgIH1cbiIKKyAgICAiICAkb25fY2hhbmdlZCRcbiIKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGNsZWFyJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgICRuYW1lJF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7XG4iCisgICAgIiAgJGNsZWFyX211dGFibGVfYml0X2J1aWxkZXIkO1xuIgorICAgICIgICRvbl9jaGFuZ2VkJFxuIgorICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICJ9XG4iKTsKKworICBpZiAoU3VwcG9ydFVua25vd25FbnVtVmFsdWUoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPlxuIgorICAgICAgImdldCRjYXBpdGFsaXplZF9uYW1lJFZhbHVlTGlzdCgpIHtcbiIKKyAgICAgICIgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdCgkbmFtZSRfKTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljIGludCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRWYWx1ZShpbnQgaW5kZXgpIHtcbiIKKyAgICAgICIgIHJldHVybiAkbmFtZSRfLmdldChpbmRleCk7XG4iCisgICAgICAifVxuIik7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIHNldCRjYXBpdGFsaXplZF9uYW1lJFZhbHVlKFxuIgorICAgICAgIiAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkge1xuIgorICAgICAgIiAgZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCk7XG4iCisgICAgICAiICAkbmFtZSRfLnNldChpbmRleCwgdmFsdWUpO1xuIgorICAgICAgIiAgJG9uX2NoYW5nZWQkXG4iCisgICAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAgICJ9XG4iKTsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgYWRkJGNhcGl0YWxpemVkX25hbWUkVmFsdWUoaW50IHZhbHVlKSB7XG4iCisgICAgICAiICBlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKTtcbiIKKyAgICAgICIgICRuYW1lJF8uYWRkKHZhbHVlKTtcbiIKKyAgICAgICIgICRvbl9jaGFuZ2VkJFxuIgorICAgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgICAifVxuIik7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGFkZEFsbCRjYXBpdGFsaXplZF9uYW1lJFZhbHVlKFxuIgorICAgICAgIiAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykge1xuIgorICAgICAgIiAgZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCk7XG4iCisgICAgICAiICBmb3IgKGludCB2YWx1ZSA6IHZhbHVlcykge1xuIgorICAgICAgIiAgICAkbmFtZSRfLmFkZCh2YWx1ZSk7XG4iCisgICAgICAiICB9XG4iCisgICAgICAiICAkb25fY2hhbmdlZCRcbiIKKyAgICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICAgIn1cbiIpOworICB9Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVGaWVsZEJ1aWxkZXJJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpICBjb25zdCB7CisgIC8vIG5vb3AgZm9yIGVudW1zCit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgIiRuYW1lJF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZUVudW1GaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUJ1aWxkZXJDbGVhckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJG5hbWUkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTtcbiIKKyAgICAiJGNsZWFyX211dGFibGVfYml0X2J1aWxkZXIkO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBUaGUgY29kZSBiZWxvdyBkb2VzIHR3byBvcHRpbWl6YXRpb25zOgorICAvLyAgIDEuIElmIHRoZSBvdGhlciBsaXN0IGlzIGVtcHR5LCB0aGVyZSdzIG5vdGhpbmcgdG8gZG8uIFRoaXMgZW5zdXJlcyB3ZQorICAvLyAgICAgIGRvbid0IGFsbG9jYXRlIGEgbmV3IGFycmF5IGlmIHdlIGFscmVhZHkgaGF2ZSBhbiBpbW11dGFibGUgb25lLgorICAvLyAgIDIuIElmIHRoZSBvdGhlciBsaXN0IGlzIG5vbi1lbXB0eSBhbmQgb3VyIGN1cnJlbnQgbGlzdCBpcyBlbXB0eSwgd2UgY2FuCisgIC8vICAgICAgcmV1c2UgdGhlIG90aGVyIGxpc3Qgd2hpY2ggaXMgZ3VhcmFudGVlZCB0byBiZSBpbW11dGFibGUuCisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICghb3RoZXIuJG5hbWUkXy5pc0VtcHR5KCkpIHtcbiIKKyAgICAiICBpZiAoJG5hbWUkXy5pc0VtcHR5KCkpIHtcbiIKKyAgICAiICAgICRuYW1lJF8gPSBvdGhlci4kbmFtZSRfO1xuIgorICAgICIgICAgJGNsZWFyX211dGFibGVfYml0X2J1aWxkZXIkO1xuIgorICAgICIgIH0gZWxzZSB7XG4iCisgICAgIiAgICBlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKTtcbiIKKyAgICAiICAgICRuYW1lJF8uYWRkQWxsKG90aGVyLiRuYW1lJF8pO1xuIgorICAgICIgIH1cbiIKKyAgICAiICAkb25fY2hhbmdlZCRcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVCdWlsZGluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gVGhlIGNvZGUgYmVsb3cgZW5zdXJlcyB0aGF0IHRoZSByZXN1bHQgaGFzIGFuIGltbXV0YWJsZSBsaXN0LiBJZiBvdXIKKyAgLy8gbGlzdCBpcyBpbW11dGFibGUsIHdlIGNhbiBqdXN0IHJldXNlIGl0LiBJZiBub3QsIHdlIG1ha2UgaXQgaW1tdXRhYmxlLgorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoJGdldF9tdXRhYmxlX2JpdF9idWlsZGVyJCkge1xuIgorICAgICIgICRuYW1lJF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdCgkbmFtZSRfKTtcbiIKKyAgICAiICAkY2xlYXJfbXV0YWJsZV9iaXRfYnVpbGRlciQ7XG4iCisgICAgIn1cbiIKKyAgICAicmVzdWx0LiRuYW1lJF8gPSAkbmFtZSRfO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVQYXJzaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBSZWFkIGFuZCBzdG9yZSB0aGUgZW51bQorICBpZiAoU3VwcG9ydFVua25vd25FbnVtVmFsdWUoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImludCByYXdWYWx1ZSA9IGlucHV0LnJlYWRFbnVtKCk7XG4iCisgICAgICAiaWYgKCEkZ2V0X211dGFibGVfYml0X3BhcnNlciQpIHtcbiIKKyAgICAgICIgICRuYW1lJF8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4oKTtcbiIKKyAgICAgICIgICRzZXRfbXV0YWJsZV9iaXRfcGFyc2VyJDtcbiIKKyAgICAgICJ9XG4iCisgICAgICAiJG5hbWUkXy5hZGQocmF3VmFsdWUpO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJpbnQgcmF3VmFsdWUgPSBpbnB1dC5yZWFkRW51bSgpO1xuIgorICAgICAgIiR0eXBlJCB2YWx1ZSA9ICR0eXBlJC52YWx1ZU9mKHJhd1ZhbHVlKTtcbiIKKyAgICAgICAgImlmICh2YWx1ZSA9PSBudWxsKSB7XG4iKTsKKyAgICBpZiAoUHJlc2VydmVVbmtub3duRmllbGRzKGRlc2NyaXB0b3JfLT5jb250YWluaW5nX3R5cGUoKSkpIHsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICIgIHVua25vd25GaWVsZHMubWVyZ2VWYXJpbnRGaWVsZCgkbnVtYmVyJCwgcmF3VmFsdWUpO1xuIik7CisgICAgfQorICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAifSBlbHNlIHtcbiIKKyAgICAgICIgIGlmICghJGdldF9tdXRhYmxlX2JpdF9wYXJzZXIkKSB7XG4iCisgICAgICAiICAgICRuYW1lJF8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4oKTtcbiIKKyAgICAgICIgICAgJHNldF9tdXRhYmxlX2JpdF9wYXJzZXIkO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIiAgJG5hbWUkXy5hZGQocmF3VmFsdWUpO1xuIgorICAgICAgIn1cbiIpOworICB9Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVQYXJzaW5nQ29kZUZyb21QYWNrZWQoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gV3JhcCBHZW5lcmF0ZVBhcnNpbmdDb2RlJ3MgY29udGVudHMgd2l0aCBhIHdoaWxlIGxvb3AuCisKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpO1xuIgorICAgICJpbnQgb2xkTGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTtcbiIKKyAgICAid2hpbGUoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgR2VuZXJhdGVQYXJzaW5nQ29kZShwcmludGVyKTsKKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIn1cbiIKKyAgICAiaW5wdXQucG9wTGltaXQob2xkTGltaXQpO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVQYXJzaW5nRG9uZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCRnZXRfbXV0YWJsZV9iaXRfcGFyc2VyJCkge1xuIgorICAgICIgICRuYW1lJF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdCgkbmFtZSRfKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoZGVzY3JpcHRvcl8tPmlzX3BhY2tlZCgpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJpZiAoZ2V0JGNhcGl0YWxpemVkX25hbWUkTGlzdCgpLnNpemUoKSA+IDApIHtcbiIKKyAgICAgICIgIG91dHB1dC53cml0ZVJhd1ZhcmludDMyKCR0YWckKTtcbiIKKyAgICAgICIgIG91dHB1dC53cml0ZVJhd1ZhcmludDMyKCRuYW1lJE1lbW9pemVkU2VyaWFsaXplZFNpemUpO1xuIgorICAgICAgIn1cbiIKKyAgICAgICJmb3IgKGludCBpID0gMDsgaSA8ICRuYW1lJF8uc2l6ZSgpOyBpKyspIHtcbiIKKyAgICAgICIgIG91dHB1dC53cml0ZUVudW1Ob1RhZygkbmFtZSRfLmdldChpKSk7XG4iCisgICAgICAifVxuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJmb3IgKGludCBpID0gMDsgaSA8ICRuYW1lJF8uc2l6ZSgpOyBpKyspIHtcbiIKKyAgICAgICIgIG91dHB1dC53cml0ZUVudW0oJG51bWJlciQsICRuYW1lJF8uZ2V0KGkpKTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIntcbiIKKyAgICAiICBpbnQgZGF0YVNpemUgPSAwO1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImZvciAoaW50IGkgPSAwOyBpIDwgJG5hbWUkXy5zaXplKCk7IGkrKykge1xuIgorICAgICIgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW1cbiIKKyAgICAiICAgIC5jb21wdXRlRW51bVNpemVOb1RhZygkbmFtZSRfLmdldChpKSk7XG4iCisgICAgIn1cbiIpOworICBwcmludGVyLT5QcmludCgKKyAgICAic2l6ZSArPSBkYXRhU2l6ZTtcbiIpOworICBpZiAoZGVzY3JpcHRvcl8tPmlzX3BhY2tlZCgpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJpZiAoIWdldCRjYXBpdGFsaXplZF9uYW1lJExpc3QoKS5pc0VtcHR5KCkpIHsiCisgICAgICAiICBzaXplICs9ICR0YWdfc2l6ZSQ7XG4iCisgICAgICAiICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW1cbiIKKyAgICAgICIgICAgLmNvbXB1dGVSYXdWYXJpbnQzMlNpemUoZGF0YVNpemUpO1xuIgorICAgICAgIn0iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgInNpemUgKz0gJHRhZ19zaXplJCAqICRuYW1lJF8uc2l6ZSgpO1xuIik7CisgIH0KKworICAvLyBjYWNoZSB0aGUgZGF0YSBzaXplIGZvciBwYWNrZWQgZmllbGRzLgorICBpZiAoZGVzY3JpcHRvcl8tPmlzX3BhY2tlZCgpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkbmFtZSRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7XG4iKTsKKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJyZXN1bHQgPSByZXN1bHQgJiYgJG5hbWUkXy5lcXVhbHMob3RoZXIuJG5hbWUkXyk7XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZUVudW1GaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUhhc2hDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmIChnZXQkY2FwaXRhbGl6ZWRfbmFtZSRDb3VudCgpID4gMCkge1xuIgorICAgICIgIGhhc2ggPSAoMzcgKiBoYXNoKSArICRjb25zdGFudF9uYW1lJDtcbiIKKyAgICAiICBoYXNoID0gKDUzICogaGFzaCkgKyAkbmFtZSRfLmhhc2hDb2RlKCk7XG4iCisgICAgIn1cbiIpOworfQorCitzdHJpbmcgUmVwZWF0ZWRJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3I6OkdldEJveGVkVHlwZSgpIGNvbnN0IHsKKyAgcmV0dXJuIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcl8tPmVudW1fdHlwZSgpKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9lbnVtX2ZpZWxkLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9lbnVtX2ZpZWxkLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjhmZjczNAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2VudW1fZmllbGQuaApAQCAtMCwwICsxLDE2MCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX0VOVU1fRklFTERfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX0VOVU1fRklFTERfSF9fCisKKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZmllbGQuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworICBuYW1lc3BhY2UgY29tcGlsZXIgeworICAgIG5hbWVzcGFjZSBqYXZhIHsKKyAgICAgIGNsYXNzIENvbnRleHQ7ICAgICAgICAgICAgLy8gY29udGV4dC5oCisgICAgICBjbGFzcyBDbGFzc05hbWVSZXNvbHZlcjsgIC8vIG5hbWVfcmVzb2x2ZXIuaAorICAgIH0KKyAgfQorfQorCituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhIHsKKworY2xhc3MgSW1tdXRhYmxlRW51bUZpZWxkR2VuZXJhdG9yIDogcHVibGljIEltbXV0YWJsZUZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IEltbXV0YWJsZUVudW1GaWVsZEdlbmVyYXRvcigKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwgaW50IG1lc3NhZ2VCaXRJbmRleCwKKyAgICAgIGludCBidWlsZGVyQml0SW5kZXgsIENvbnRleHQqIGNvbnRleHQpOworICB+SW1tdXRhYmxlRW51bUZpZWxkR2VuZXJhdG9yKCk7CisKKyAgLy8gaW1wbGVtZW50cyBJbW11dGFibGVGaWVsZEdlbmVyYXRvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgaW50IEdldE51bUJpdHNGb3JNZXNzYWdlKCkgY29uc3Q7CisgIGludCBHZXROdW1CaXRzRm9yQnVpbGRlcigpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSW50ZXJmYWNlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUJ1aWxkZXJNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUluaXRpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCdWlsZGVyQ2xlYXJDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUJ1aWxkaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVQYXJzaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVQYXJzaW5nRG9uZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUZpZWxkQnVpbGRlckluaXRpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVFcXVhbHNDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUhhc2hDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKworICBzdHJpbmcgR2V0Qm94ZWRUeXBlKCkgY29uc3Q7CisKKyBwcm90ZWN0ZWQ6CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcl87CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyaWFibGVzXzsKKyAgY29uc3QgaW50IG1lc3NhZ2VCaXRJbmRleF87CisgIGNvbnN0IGludCBidWlsZGVyQml0SW5kZXhfOworICBDb250ZXh0KiBjb250ZXh0XzsKKyAgQ2xhc3NOYW1lUmVzb2x2ZXIqIG5hbWVfcmVzb2x2ZXJfOworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEltbXV0YWJsZUVudW1GaWVsZEdlbmVyYXRvcik7Cit9OworCitjbGFzcyBJbW11dGFibGVFbnVtT25lb2ZGaWVsZEdlbmVyYXRvciA6IHB1YmxpYyBJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgSW1tdXRhYmxlRW51bU9uZW9mRmllbGRHZW5lcmF0b3IoCisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGludCBtZXNzYWdlQml0SW5kZXgsCisgICAgICBpbnQgYnVpbGRlckJpdEluZGV4LCBDb250ZXh0KiBjb250ZXh0KTsKKyAgfkltbXV0YWJsZUVudW1PbmVvZkZpZWxkR2VuZXJhdG9yKCk7CisKKyAgdm9pZCBHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnVpbGRlck1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnVpbGRpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVBhcnNpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVFcXVhbHNDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUhhc2hDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhJbW11dGFibGVFbnVtT25lb2ZGaWVsZEdlbmVyYXRvcik7Cit9OworCitjbGFzcyBSZXBlYXRlZEltbXV0YWJsZUVudW1GaWVsZEdlbmVyYXRvciA6IHB1YmxpYyBJbW11dGFibGVGaWVsZEdlbmVyYXRvciB7CisgcHVibGljOgorICBleHBsaWNpdCBSZXBlYXRlZEltbXV0YWJsZUVudW1GaWVsZEdlbmVyYXRvcigKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwgaW50IG1lc3NhZ2VCaXRJbmRleCwKKyAgICAgIGludCBidWlsZGVyQml0SW5kZXgsIENvbnRleHQqIGNvbnRleHQpOworICB+UmVwZWF0ZWRJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3IoKTsKKworICAvLyBpbXBsZW1lbnRzIEltbXV0YWJsZUZpZWxkR2VuZXJhdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICBpbnQgR2V0TnVtQml0c0Zvck1lc3NhZ2UoKSBjb25zdDsKKyAgaW50IEdldE51bUJpdHNGb3JCdWlsZGVyKCkgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVJbnRlcmZhY2VNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnVpbGRlck1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUJ1aWxkZXJDbGVhckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnVpbGRpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVBhcnNpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVBhcnNpbmdDb2RlRnJvbVBhY2tlZChpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVQYXJzaW5nRG9uZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUZpZWxkQnVpbGRlckluaXRpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVFcXVhbHNDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUhhc2hDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKworICBzdHJpbmcgR2V0Qm94ZWRUeXBlKCkgY29uc3Q7CisKKyBwcml2YXRlOgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlc187CisgIGNvbnN0IGludCBtZXNzYWdlQml0SW5kZXhfOworICBjb25zdCBpbnQgYnVpbGRlckJpdEluZGV4XzsKKyAgQ29udGV4dCogY29udGV4dF87CisgIENsYXNzTmFtZVJlc29sdmVyKiBuYW1lX3Jlc29sdmVyXzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoUmVwZWF0ZWRJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3IpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfRU5VTV9GSUVMRF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2VudW1fZmllbGRfbGl0ZS5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2VudW1fZmllbGRfbGl0ZS5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lM2U4N2M1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZW51bV9maWVsZF9saXRlLmNjCkBAIC0wLDAgKzEsOTY2IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8c3RyaW5nPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2xvZ2dpbmcuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9jb250ZXh0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9kb2NfY29tbWVudC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZW51bV9maWVsZF9saXRlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9uYW1lX3Jlc29sdmVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmEgeworCituYW1lc3BhY2UgeworCit2b2lkIFNldEVudW1WYXJpYWJsZXMoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgIGludCBtZXNzYWdlQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZEdlbmVyYXRvckluZm8qIGluZm8sCisgICAgICAgICAgICAgICAgICAgICAgQ2xhc3NOYW1lUmVzb2x2ZXIqIG5hbWVfcmVzb2x2ZXIsCisgICAgICAgICAgICAgICAgICAgICAgbWFwPHN0cmluZywgc3RyaW5nPiogdmFyaWFibGVzKSB7CisgIFNldENvbW1vbkZpZWxkVmFyaWFibGVzKGRlc2NyaXB0b3IsIGluZm8sIHZhcmlhYmxlcyk7CisKKyAgKCp2YXJpYWJsZXMpWyJ0eXBlIl0gPQorICAgICAgbmFtZV9yZXNvbHZlci0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3ItPmVudW1fdHlwZSgpKTsKKyAgKCp2YXJpYWJsZXMpWyJtdXRhYmxlX3R5cGUiXSA9CisgICAgICBuYW1lX3Jlc29sdmVyLT5HZXRNdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3ItPmVudW1fdHlwZSgpKTsKKyAgKCp2YXJpYWJsZXMpWyJkZWZhdWx0Il0gPSBJbW11dGFibGVEZWZhdWx0VmFsdWUoZGVzY3JpcHRvciwgbmFtZV9yZXNvbHZlcik7CisgICgqdmFyaWFibGVzKVsiZGVmYXVsdF9udW1iZXIiXSA9IFNpbXBsZUl0b2EoCisgICAgICBkZXNjcmlwdG9yLT5kZWZhdWx0X3ZhbHVlX2VudW0oKS0+bnVtYmVyKCkpOworICAoKnZhcmlhYmxlcylbInRhZyJdID0gU2ltcGxlSXRvYShpbnRlcm5hbDo6V2lyZUZvcm1hdDo6TWFrZVRhZyhkZXNjcmlwdG9yKSk7CisgICgqdmFyaWFibGVzKVsidGFnX3NpemUiXSA9IFNpbXBsZUl0b2EoCisgICAgICBpbnRlcm5hbDo6V2lyZUZvcm1hdDo6VGFnU2l6ZShkZXNjcmlwdG9yLT5udW1iZXIoKSwgR2V0VHlwZShkZXNjcmlwdG9yKSkpOworICAvLyBUT0RPKGJpcmRvKTogQWRkIEBkZXByZWNhdGVkIGphdmFkb2Mgd2hlbiBnZW5lcmF0aW5nIGphdmFkb2MgaXMgc3VwcG9ydGVkCisgIC8vIGJ5IHRoZSBwcm90byBjb21waWxlcgorICAoKnZhcmlhYmxlcylbImRlcHJlY2F0aW9uIl0gPSBkZXNjcmlwdG9yLT5vcHRpb25zKCkuZGVwcmVjYXRlZCgpCisgICAgICA/ICJAamF2YS5sYW5nLkRlcHJlY2F0ZWQgIiA6ICIiOworICAoKnZhcmlhYmxlcylbIm9uX2NoYW5nZWQiXSA9CisgICAgICBIYXNEZXNjcmlwdG9yTWV0aG9kcyhkZXNjcmlwdG9yLT5jb250YWluaW5nX3R5cGUoKSkgPyAib25DaGFuZ2VkKCk7IiA6ICIiOworCisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yLT5maWxlKCkpKSB7CisgICAgLy8gRm9yIHNpbmd1bGFyIG1lc3NhZ2VzIGFuZCBidWlsZGVycywgb25lIGJpdCBpcyB1c2VkIGZvciB0aGUgaGFzRmllbGQgYml0LgorICAgICgqdmFyaWFibGVzKVsiZ2V0X2hhc19maWVsZF9iaXRfbWVzc2FnZSJdID0gR2VuZXJhdGVHZXRCaXQobWVzc2FnZUJpdEluZGV4KTsKKworICAgIC8vIE5vdGUgdGhhdCB0aGVzZSBoYXZlIGEgdHJhaWxpbmcgIjsiLgorICAgICgqdmFyaWFibGVzKVsic2V0X2hhc19maWVsZF9iaXRfbWVzc2FnZSJdID0KKyAgICAgICAgR2VuZXJhdGVTZXRCaXQobWVzc2FnZUJpdEluZGV4KSArICI7IjsKKyAgICAoKnZhcmlhYmxlcylbImNsZWFyX2hhc19maWVsZF9iaXRfbWVzc2FnZSJdID0KKyAgICAgICAgR2VuZXJhdGVDbGVhckJpdChtZXNzYWdlQml0SW5kZXgpICsgIjsiOworCisgICAgKCp2YXJpYWJsZXMpWyJpc19maWVsZF9wcmVzZW50X21lc3NhZ2UiXSA9IEdlbmVyYXRlR2V0Qml0KG1lc3NhZ2VCaXRJbmRleCk7CisgIH0gZWxzZSB7CisgICAgKCp2YXJpYWJsZXMpWyJzZXRfaGFzX2ZpZWxkX2JpdF9tZXNzYWdlIl0gPSAiIjsKKyAgICAoKnZhcmlhYmxlcylbImNsZWFyX2hhc19maWVsZF9iaXRfbWVzc2FnZSJdID0gIiI7CisKKyAgICAoKnZhcmlhYmxlcylbImlzX2ZpZWxkX3ByZXNlbnRfbWVzc2FnZSJdID0KKyAgICAgICAgKCp2YXJpYWJsZXMpWyJuYW1lIl0gKyAiXyAhPSAiICsKKyAgICAgICAgKCp2YXJpYWJsZXMpWyJkZWZhdWx0Il0gKyAiLmdldE51bWJlcigpIjsKKyAgfQorCisgIC8vIEZvciByZXBlYXRlZCBidWlsZGVycywgdGhlIHVuZGVybHlpbmcgbGlzdCB0cmFja3MgbXV0YWJpbGl0eSBzdGF0ZS4KKyAgKCp2YXJpYWJsZXMpWyJpc19tdXRhYmxlIl0gPSAoKnZhcmlhYmxlcylbIm5hbWUiXSArICJfLmlzTW9kaWZpYWJsZSgpIjsKKworICAoKnZhcmlhYmxlcylbImdldF9oYXNfZmllbGRfYml0X2Zyb21fbG9jYWwiXSA9CisgICAgICBHZW5lcmF0ZUdldEJpdEZyb21Mb2NhbChidWlsZGVyQml0SW5kZXgpOworICAoKnZhcmlhYmxlcylbInNldF9oYXNfZmllbGRfYml0X3RvX2xvY2FsIl0gPQorICAgICAgR2VuZXJhdGVTZXRCaXRUb0xvY2FsKG1lc3NhZ2VCaXRJbmRleCk7CisKKyAgaWYgKFN1cHBvcnRVbmtub3duRW51bVZhbHVlKGRlc2NyaXB0b3ItPmZpbGUoKSkpIHsKKyAgICAoKnZhcmlhYmxlcylbInVua25vd24iXSA9ICgqdmFyaWFibGVzKVsidHlwZSJdICsgIi5VTlJFQ09HTklaRUQiOworICB9IGVsc2UgeworICAgICgqdmFyaWFibGVzKVsidW5rbm93biJdID0gKCp2YXJpYWJsZXMpWyJkZWZhdWx0Il07CisgIH0KK30KKworfSAgLy8gbmFtZXNwYWNlCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworSW1tdXRhYmxlRW51bUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitJbW11dGFibGVFbnVtRmllbGRMaXRlR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBidWlsZGVyQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29udGV4dCogY29udGV4dCkKKyAgOiBkZXNjcmlwdG9yXyhkZXNjcmlwdG9yKSwgbWVzc2FnZUJpdEluZGV4XyhtZXNzYWdlQml0SW5kZXgpLAorICAgIGJ1aWxkZXJCaXRJbmRleF8oYnVpbGRlckJpdEluZGV4KSwKKyAgICBuYW1lX3Jlc29sdmVyXyhjb250ZXh0LT5HZXROYW1lUmVzb2x2ZXIoKSkgeworICBTZXRFbnVtVmFyaWFibGVzKGRlc2NyaXB0b3IsIG1lc3NhZ2VCaXRJbmRleCwgYnVpbGRlckJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgIGNvbnRleHQtPkdldEZpZWxkR2VuZXJhdG9ySW5mbyhkZXNjcmlwdG9yKSwKKyAgICAgICAgICAgICAgICAgICBuYW1lX3Jlc29sdmVyXywgJnZhcmlhYmxlc18pOworfQorCitJbW11dGFibGVFbnVtRmllbGRMaXRlR2VuZXJhdG9yOjp+SW1tdXRhYmxlRW51bUZpZWxkTGl0ZUdlbmVyYXRvcigpIHt9CisKK2ludCBJbW11dGFibGVFbnVtRmllbGRMaXRlR2VuZXJhdG9yOjpHZXROdW1CaXRzRm9yTWVzc2FnZSgpIGNvbnN0IHsKKyAgcmV0dXJuIDE7Cit9CisKK2ludCBJbW11dGFibGVFbnVtRmllbGRMaXRlR2VuZXJhdG9yOjpHZXROdW1CaXRzRm9yQnVpbGRlcigpIGNvbnN0IHsKKyAgcmV0dXJuIDA7Cit9CisKK3ZvaWQgSW1tdXRhYmxlRW51bUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUludGVyZmFjZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKFN1cHBvcnRGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJGRlcHJlY2F0aW9uJGJvb2xlYW4gaGFzJGNhcGl0YWxpemVkX25hbWUkKCk7XG4iKTsKKyAgfQorICBpZiAoU3VwcG9ydFVua25vd25FbnVtVmFsdWUoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kaW50IGdldCRjYXBpdGFsaXplZF9uYW1lJFZhbHVlKCk7XG4iKTsKKyAgfQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiQkdHlwZSQgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCk7XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVFbnVtRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIGludCAkbmFtZSRfO1xuIik7CisgIFByaW50RXh0cmFGaWVsZEluZm8odmFyaWFibGVzXywgcHJpbnRlcik7CisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgYm9vbGVhbiBoYXMkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgICAiICByZXR1cm4gJGdldF9oYXNfZmllbGRfYml0X21lc3NhZ2UkO1xuIgorICAgICAgIn1cbiIpOworICB9CisgIGlmIChTdXBwb3J0VW5rbm93bkVudW1WYWx1ZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgaW50IGdldCRjYXBpdGFsaXplZF9uYW1lJFZhbHVlKCkge1xuIgorICAgICAgIiAgcmV0dXJuICRuYW1lJF87XG4iCisgICAgICAifVxuIik7CisgIH0KKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljICR0eXBlJCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgJHR5cGUkIHJlc3VsdCA9ICR0eXBlJC52YWx1ZU9mKCRuYW1lJF8pO1xuIgorICAgICIgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/ICR1bmtub3duJCA6IHJlc3VsdDtcbiIKKyAgICAifVxuIik7CisKKyAgLy8gR2VuZXJhdGUgcHJpdmF0ZSBzZXR0ZXJzIGZvciB0aGUgYnVpbGRlciB0byBwcm94eSBpbnRvLgorICBpZiAoU3VwcG9ydFVua25vd25FbnVtVmFsdWUoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJwcml2YXRlIHZvaWQgc2V0JGNhcGl0YWxpemVkX25hbWUkVmFsdWUoaW50IHZhbHVlKSB7XG4iCisgICAgICAiICAkc2V0X2hhc19maWVsZF9iaXRfbWVzc2FnZSQiCisgICAgICAiICAkbmFtZSRfID0gdmFsdWU7XG4iCisgICAgICAifVxuIik7CisgIH0KKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIHZvaWQgc2V0JGNhcGl0YWxpemVkX25hbWUkKCR0eXBlJCB2YWx1ZSkge1xuIgorICAgICIgIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4iCisgICAgIiAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTtcbiIKKyAgICAiICB9XG4iCisgICAgIiAgJHNldF9oYXNfZmllbGRfYml0X21lc3NhZ2UkXG4iCisgICAgIiAgJG5hbWUkXyA9IHZhbHVlLmdldE51bWJlcigpO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIHZvaWQgY2xlYXIkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgJGNsZWFyX2hhc19maWVsZF9iaXRfbWVzc2FnZSRcbiIKKyAgICAiICAkbmFtZSRfID0gJGRlZmF1bHRfbnVtYmVyJDtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlRW51bUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUJ1aWxkZXJNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgYm9vbGVhbiBoYXMkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgICAiICByZXR1cm4gaW5zdGFuY2UuaGFzJGNhcGl0YWxpemVkX25hbWUkKCk7XG4iCisgICAgICAifVxuIik7CisgIH0KKyAgaWYgKFN1cHBvcnRVbmtub3duRW51bVZhbHVlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBpbnQgZ2V0JGNhcGl0YWxpemVkX25hbWUkVmFsdWUoKSB7XG4iCisgICAgICAiICByZXR1cm4gaW5zdGFuY2UuZ2V0JGNhcGl0YWxpemVkX25hbWUkVmFsdWUoKTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgc2V0JGNhcGl0YWxpemVkX25hbWUkVmFsdWUoaW50IHZhbHVlKSB7XG4iCisgICAgICAiICBjb3B5T25Xcml0ZSgpO1xuIgorICAgICAgIiAgaW5zdGFuY2Uuc2V0JGNhcGl0YWxpemVkX25hbWUkVmFsdWUoaW50IHZhbHVlKTtcbiIKKyAgICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICAgIn1cbiIpOworICB9CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSQgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgIHJldHVybiBpbnN0YW5jZS5nZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKTtcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIHNldCRjYXBpdGFsaXplZF9uYW1lJCgkdHlwZSQgdmFsdWUpIHtcbiIKKyAgICAiICBjb3B5T25Xcml0ZSgpO1xuIgorICAgICIgIGluc3RhbmNlLnNldCRjYXBpdGFsaXplZF9uYW1lJCh2YWx1ZSk7XG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBjbGVhciRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAiICBjb3B5T25Xcml0ZSgpO1xuIgorICAgICIgIGluc3RhbmNlLmNsZWFyJGNhcGl0YWxpemVkX25hbWUkKCk7XG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZUVudW1GaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVGaWVsZEJ1aWxkZXJJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpICBjb25zdCB7CisgIC8vIG5vb3AgZm9yIGVudW1zCit9CisKK3ZvaWQgSW1tdXRhYmxlRW51bUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUluaXRpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAiJG5hbWUkXyA9ICRkZWZhdWx0X251bWJlciQ7XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVFbnVtRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKFN1cHBvcnRGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJpZiAob3RoZXIuaGFzJGNhcGl0YWxpemVkX25hbWUkKCkpIHtcbiIKKyAgICAgICIgIHNldCRjYXBpdGFsaXplZF9uYW1lJChvdGhlci5nZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSk7XG4iCisgICAgICAifVxuIik7CisgIH0gZWxzZSBpZiAoU3VwcG9ydFVua25vd25FbnVtVmFsdWUoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImlmIChvdGhlci4kbmFtZSRfICE9ICRkZWZhdWx0X251bWJlciQpIHtcbiIKKyAgICAgICIgIHNldCRjYXBpdGFsaXplZF9uYW1lJFZhbHVlKG90aGVyLmdldCRjYXBpdGFsaXplZF9uYW1lJFZhbHVlKCkpO1xuIgorICAgICAgIn1cbiIpOworICB9IGVsc2UgeworICAgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJDYW4ndCByZWFjaCBoZXJlLiI7CisgIH0KK30KKwordm9pZCBJbW11dGFibGVFbnVtRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlRHluYW1pY01ldGhvZE1ha2VJbW11dGFibGVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIG5vb3AgZm9yIHNjYWxhcnMKK30KKwordm9pZCBJbW11dGFibGVFbnVtRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKFN1cHBvcnRVbmtub3duRW51bVZhbHVlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJpbnQgcmF3VmFsdWUgPSBpbnB1dC5yZWFkRW51bSgpO1xuIgorICAgICAgIiRzZXRfaGFzX2ZpZWxkX2JpdF9tZXNzYWdlJFxuIgorICAgICAgIiRuYW1lJF8gPSByYXdWYWx1ZTtcbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaW50IHJhd1ZhbHVlID0gaW5wdXQucmVhZEVudW0oKTtcbiIKKyAgICAgICIkdHlwZSQgdmFsdWUgPSAkdHlwZSQudmFsdWVPZihyYXdWYWx1ZSk7XG4iCisgICAgICAiaWYgKHZhbHVlID09IG51bGwpIHtcbiIpOworICAgIGlmIChQcmVzZXJ2ZVVua25vd25GaWVsZHMoZGVzY3JpcHRvcl8tPmNvbnRhaW5pbmdfdHlwZSgpKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgIiAgc3VwZXIubWVyZ2VWYXJpbnRGaWVsZCgkbnVtYmVyJCwgcmF3VmFsdWUpO1xuIik7CisgICAgfQorICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAifSBlbHNlIHtcbiIKKyAgICAgICIgICRzZXRfaGFzX2ZpZWxkX2JpdF9tZXNzYWdlJFxuIgorICAgICAgIiAgJG5hbWUkXyA9IHJhd1ZhbHVlO1xuIgorICAgICAgIn1cbiIpOworICB9Cit9CisKK3ZvaWQgSW1tdXRhYmxlRW51bUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZVBhcnNpbmdEb25lQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBub29wIGZvciBlbnVtcworfQorCit2b2lkIEltbXV0YWJsZUVudW1GaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoJGlzX2ZpZWxkX3ByZXNlbnRfbWVzc2FnZSQpIHtcbiIKKyAgICAiICBvdXRwdXQud3JpdGVFbnVtKCRudW1iZXIkLCAkbmFtZSRfKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlRW51bUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoJGlzX2ZpZWxkX3ByZXNlbnRfbWVzc2FnZSQpIHtcbiIKKyAgICAiICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW1cbiIKKyAgICAiICAgIC5jb21wdXRlRW51bVNpemUoJG51bWJlciQsICRuYW1lJF8pO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVFbnVtRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJyZXN1bHQgPSByZXN1bHQgJiYgJG5hbWUkXyA9PSBvdGhlci4kbmFtZSRfO1xuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlRW51bUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUhhc2hDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImhhc2ggPSAoMzcgKiBoYXNoKSArICRjb25zdGFudF9uYW1lJDtcbiIKKyAgICAiaGFzaCA9ICg1MyAqIGhhc2gpICsgJG5hbWUkXztcbiIpOworfQorCitzdHJpbmcgSW1tdXRhYmxlRW51bUZpZWxkTGl0ZUdlbmVyYXRvcjo6R2V0Qm94ZWRUeXBlKCkgY29uc3QgeworICByZXR1cm4gbmFtZV9yZXNvbHZlcl8tPkdldEltbXV0YWJsZUNsYXNzTmFtZShkZXNjcmlwdG9yXy0+ZW51bV90eXBlKCkpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK0ltbXV0YWJsZUVudW1PbmVvZkZpZWxkTGl0ZUdlbmVyYXRvcjo6CitJbW11dGFibGVFbnVtT25lb2ZGaWVsZExpdGVHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG1lc3NhZ2VCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBidWlsZGVyQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb250ZXh0KiBjb250ZXh0KQorICAgIDogSW1tdXRhYmxlRW51bUZpZWxkTGl0ZUdlbmVyYXRvcigKKyAgICAgICAgICBkZXNjcmlwdG9yLCBtZXNzYWdlQml0SW5kZXgsIGJ1aWxkZXJCaXRJbmRleCwgY29udGV4dCkgeworICBjb25zdCBPbmVvZkdlbmVyYXRvckluZm8qIGluZm8gPQorICAgICAgY29udGV4dC0+R2V0T25lb2ZHZW5lcmF0b3JJbmZvKGRlc2NyaXB0b3ItPmNvbnRhaW5pbmdfb25lb2YoKSk7CisgIFNldENvbW1vbk9uZW9mVmFyaWFibGVzKGRlc2NyaXB0b3IsIGluZm8sICZ2YXJpYWJsZXNfKTsKK30KKworSW1tdXRhYmxlRW51bU9uZW9mRmllbGRMaXRlR2VuZXJhdG9yOjoKK35JbW11dGFibGVFbnVtT25lb2ZGaWVsZExpdGVHZW5lcmF0b3IoKSB7fQorCit2b2lkIEltbXV0YWJsZUVudW1PbmVvZkZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgUHJpbnRFeHRyYUZpZWxkSW5mbyh2YXJpYWJsZXNfLCBwcmludGVyKTsKKyAgaWYgKFN1cHBvcnRGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBib29sZWFuIGhhcyRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAgICIgIHJldHVybiAkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQ7XG4iCisgICAgICAifVxuIik7CisgIH0KKyAgaWYgKFN1cHBvcnRVbmtub3duRW51bVZhbHVlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBpbnQgZ2V0JGNhcGl0YWxpemVkX25hbWUkVmFsdWUoKSB7XG4iCisgICAgICAiICBpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iCisgICAgICAiICAgIHJldHVybiAoamF2YS5sYW5nLkludGVnZXIpICRvbmVvZl9uYW1lJF87XG4iCisgICAgICAiICB9XG4iCisgICAgICAiICByZXR1cm4gJGRlZmF1bHRfbnVtYmVyJDtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAiICBpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iCisgICAgIiAgICAkdHlwZSQgcmVzdWx0ID0gICR0eXBlJC52YWx1ZU9mKChqYXZhLmxhbmcuSW50ZWdlcikgJG9uZW9mX25hbWUkXyk7XG4iCisgICAgIiAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyAkdW5rbm93biQgOiByZXN1bHQ7XG4iCisgICAgIiAgfVxuIgorICAgICIgIHJldHVybiAkZGVmYXVsdCQ7XG4iCisgICAgIn1cbiIpOworCisgIC8vIEdlbmVyYXRlIHByaXZhdGUgc2V0dGVycyBmb3IgdGhlIGJ1aWxkZXIgdG8gcHJveHkgaW50by4KKyAgaWYgKFN1cHBvcnRVbmtub3duRW51bVZhbHVlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAicHJpdmF0ZSB2b2lkIHNldCRjYXBpdGFsaXplZF9uYW1lJFZhbHVlKGludCB2YWx1ZSkge1xuIgorICAgICAgIiAgJHNldF9vbmVvZl9jYXNlX21lc3NhZ2UkO1xuIgorICAgICAgIiAgJG9uZW9mX25hbWUkXyA9IHZhbHVlO1xuIgorICAgICAgIn1cbiIpOworICB9CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHJpdmF0ZSB2b2lkIHNldCRjYXBpdGFsaXplZF9uYW1lJCgkdHlwZSQgdmFsdWUpIHtcbiIKKyAgICAiICBpZiAodmFsdWUgPT0gbnVsbCkge1xuIgorICAgICIgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7XG4iCisgICAgIiAgfVxuIgorICAgICIgICRzZXRfb25lb2ZfY2FzZV9tZXNzYWdlJDtcbiIKKyAgICAiICAkb25lb2ZfbmFtZSRfID0gdmFsdWUuZ2V0TnVtYmVyKCk7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgdm9pZCBjbGVhciRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAiICBpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iCisgICAgIiAgICAkY2xlYXJfb25lb2ZfY2FzZV9tZXNzYWdlJDtcbiIKKyAgICAiICAgICRvbmVvZl9uYW1lJF8gPSBudWxsO1xuIgorICAgICIgIH1cbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlRW51bU9uZW9mRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRlck1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKFN1cHBvcnRGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBib29sZWFuIGhhcyRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAgICIgIHJldHVybiBpbnN0YW5jZS5oYXMkY2FwaXRhbGl6ZWRfbmFtZSQoKTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorICBpZiAoU3VwcG9ydFVua25vd25FbnVtVmFsdWUoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljIGludCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRWYWx1ZSgpIHtcbiIKKyAgICAgICIgIHJldHVybiBpbnN0YW5jZS5nZXQkY2FwaXRhbGl6ZWRfbmFtZSRWYWx1ZSgpO1xuIgorICAgICAgIn1cbiIpOworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBzZXQkY2FwaXRhbGl6ZWRfbmFtZSRWYWx1ZShpbnQgdmFsdWUpIHtcbiIKKyAgICAgICIgIGNvcHlPbldyaXRlKCk7XG4iCisgICAgICAiICBpbnN0YW5jZS5zZXQkY2FwaXRhbGl6ZWRfbmFtZSRWYWx1ZSh2YWx1ZSk7XG4iCisgICAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAiICByZXR1cm4gaW5zdGFuY2UuZ2V0JGNhcGl0YWxpemVkX25hbWUkKCk7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBzZXQkY2FwaXRhbGl6ZWRfbmFtZSQoJHR5cGUkIHZhbHVlKSB7XG4iCisgICAgIiAgY29weU9uV3JpdGUoKTtcbiIKKyAgICAiICBpbnN0YW5jZS5zZXQkY2FwaXRhbGl6ZWRfbmFtZSQodmFsdWUpO1xuIgorICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgY2xlYXIkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgY29weU9uV3JpdGUoKTtcbiIKKyAgICAiICBpbnN0YW5jZS5jbGVhciRjYXBpdGFsaXplZF9uYW1lJCgpO1xuIgorICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVFbnVtT25lb2ZGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoU3VwcG9ydFVua25vd25FbnVtVmFsdWUoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgInNldCRjYXBpdGFsaXplZF9uYW1lJFZhbHVlKG90aGVyLmdldCRjYXBpdGFsaXplZF9uYW1lJFZhbHVlKCkpO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJzZXQkY2FwaXRhbGl6ZWRfbmFtZSQob3RoZXIuZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkpO1xuIik7CisgIH0KK30KKwordm9pZCBJbW11dGFibGVFbnVtT25lb2ZGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVQYXJzaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoU3VwcG9ydFVua25vd25FbnVtVmFsdWUoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImludCByYXdWYWx1ZSA9IGlucHV0LnJlYWRFbnVtKCk7XG4iCisgICAgICAiJHNldF9vbmVvZl9jYXNlX21lc3NhZ2UkO1xuIgorICAgICAgIiRvbmVvZl9uYW1lJF8gPSByYXdWYWx1ZTtcbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaW50IHJhd1ZhbHVlID0gaW5wdXQucmVhZEVudW0oKTtcbiIKKyAgICAgICIkdHlwZSQgdmFsdWUgPSAkdHlwZSQudmFsdWVPZihyYXdWYWx1ZSk7XG4iCisgICAgICAiaWYgKHZhbHVlID09IG51bGwpIHtcbiIpOworICAgIGlmIChQcmVzZXJ2ZVVua25vd25GaWVsZHMoZGVzY3JpcHRvcl8tPmNvbnRhaW5pbmdfdHlwZSgpKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgIiAgc3VwZXIubWVyZ2VWYXJpbnRGaWVsZCgkbnVtYmVyJCwgcmF3VmFsdWUpO1xuIik7CisgICAgfQorICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAifSBlbHNlIHtcbiIKKyAgICAgICIgICRzZXRfb25lb2ZfY2FzZV9tZXNzYWdlJDtcbiIKKyAgICAgICIgICRvbmVvZl9uYW1lJF8gPSByYXdWYWx1ZTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorfQorCit2b2lkIEltbXV0YWJsZUVudW1PbmVvZkZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIKKyAgICAiICBvdXRwdXQud3JpdGVFbnVtKCRudW1iZXIkLCAoKGphdmEubGFuZy5JbnRlZ2VyKSAkb25lb2ZfbmFtZSRfKSk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZUVudW1PbmVvZkZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iCisgICAgIiAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtXG4iCisgICAgIiAgICAuY29tcHV0ZUVudW1TaXplKCRudW1iZXIkLCAoKGphdmEubGFuZy5JbnRlZ2VyKSAkb25lb2ZfbmFtZSRfKSk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZUVudW1PbmVvZkZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUVxdWFsc0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKFN1cHBvcnRVbmtub3duRW51bVZhbHVlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJyZXN1bHQgPSByZXN1bHQgJiYgZ2V0JGNhcGl0YWxpemVkX25hbWUkVmFsdWUoKVxuIgorICAgICAgIiAgICA9PSBvdGhlci5nZXQkY2FwaXRhbGl6ZWRfbmFtZSRWYWx1ZSgpO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJyZXN1bHQgPSByZXN1bHQgJiYgZ2V0JGNhcGl0YWxpemVkX25hbWUkKClcbiIKKyAgICAgICIgICAgLmVxdWFscyhvdGhlci5nZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSk7XG4iKTsKKyAgfQorfQorCit2b2lkIEltbXV0YWJsZUVudW1PbmVvZkZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUhhc2hDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChTdXBwb3J0VW5rbm93bkVudW1WYWx1ZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaGFzaCA9ICgzNyAqIGhhc2gpICsgJGNvbnN0YW50X25hbWUkO1xuIgorICAgICAgImhhc2ggPSAoNTMgKiBoYXNoKSArIGdldCRjYXBpdGFsaXplZF9uYW1lJFZhbHVlKCk7XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImhhc2ggPSAoMzcgKiBoYXNoKSArICRjb25zdGFudF9uYW1lJDtcbiIKKyAgICAgICJoYXNoID0gKDUzICogaGFzaCkgKyBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKS5nZXROdW1iZXIoKTtcbiIpOworICB9Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworUmVwZWF0ZWRJbW11dGFibGVFbnVtRmllbGRMaXRlR2VuZXJhdG9yOjoKK1JlcGVhdGVkSW1tdXRhYmxlRW51bUZpZWxkTGl0ZUdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnRleHQqIGNvbnRleHQpCisgIDogZGVzY3JpcHRvcl8oZGVzY3JpcHRvciksIG1lc3NhZ2VCaXRJbmRleF8obWVzc2FnZUJpdEluZGV4KSwKKyAgICBidWlsZGVyQml0SW5kZXhfKGJ1aWxkZXJCaXRJbmRleCksIGNvbnRleHRfKGNvbnRleHQpLAorICAgIG5hbWVfcmVzb2x2ZXJfKGNvbnRleHQtPkdldE5hbWVSZXNvbHZlcigpKSB7CisgIFNldEVudW1WYXJpYWJsZXMoZGVzY3JpcHRvciwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgY29udGV4dC0+R2V0RmllbGRHZW5lcmF0b3JJbmZvKGRlc2NyaXB0b3IpLAorICAgICAgICAgICAgICAgICAgIG5hbWVfcmVzb2x2ZXJfLCAmdmFyaWFibGVzXyk7Cit9CisKK1JlcGVhdGVkSW1tdXRhYmxlRW51bUZpZWxkTGl0ZUdlbmVyYXRvcjo6Cit+UmVwZWF0ZWRJbW11dGFibGVFbnVtRmllbGRMaXRlR2VuZXJhdG9yKCkge30KKworaW50IFJlcGVhdGVkSW1tdXRhYmxlRW51bUZpZWxkTGl0ZUdlbmVyYXRvcjo6R2V0TnVtQml0c0Zvck1lc3NhZ2UoKSBjb25zdCB7CisgIHJldHVybiAwOworfQorCitpbnQgUmVwZWF0ZWRJbW11dGFibGVFbnVtRmllbGRMaXRlR2VuZXJhdG9yOjpHZXROdW1CaXRzRm9yQnVpbGRlcigpIGNvbnN0IHsKKyAgcmV0dXJuIDA7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVFbnVtRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlSW50ZXJmYWNlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRqYXZhLnV0aWwuTGlzdDwkdHlwZSQ+IGdldCRjYXBpdGFsaXplZF9uYW1lJExpc3QoKTtcbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRpbnQgZ2V0JGNhcGl0YWxpemVkX25hbWUkQ291bnQoKTtcbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiQkdHlwZSQgZ2V0JGNhcGl0YWxpemVkX25hbWUkKGludCBpbmRleCk7XG4iKTsKKyAgaWYgKFN1cHBvcnRVbmtub3duRW51bVZhbHVlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJGRlcHJlY2F0aW9uJGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPlxuIgorICAgICAgImdldCRjYXBpdGFsaXplZF9uYW1lJFZhbHVlTGlzdCgpO1xuIik7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJGRlcHJlY2F0aW9uJGludCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRWYWx1ZShpbnQgaW5kZXgpO1xuIik7CisgIH0KK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZUVudW1GaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0ICRuYW1lJF87XG4iCisgICAgInByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPFxuIgorICAgICIgICAgamF2YS5sYW5nLkludGVnZXIsICR0eXBlJD4gJG5hbWUkX2NvbnZlcnRlcl8gPVxuIgorICAgICIgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjxcbiIKKyAgICAiICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsICR0eXBlJD4oKSB7XG4iCisgICAgIiAgICAgICAgICBwdWJsaWMgJHR5cGUkIGNvbnZlcnQoamF2YS5sYW5nLkludGVnZXIgZnJvbSkge1xuIgorICAgICIgICAgICAgICAgICAkdHlwZSQgcmVzdWx0ID0gJHR5cGUkLnZhbHVlT2YoZnJvbSk7XG4iCisgICAgIiAgICAgICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/ICR1bmtub3duJCA6IHJlc3VsdDtcbiIKKyAgICAiICAgICAgICAgIH1cbiIKKyAgICAiICAgICAgICB9O1xuIik7CisgIFByaW50RXh0cmFGaWVsZEluZm8odmFyaWFibGVzXywgcHJpbnRlcik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBqYXZhLnV0aWwuTGlzdDwkdHlwZSQ+IGdldCRjYXBpdGFsaXplZF9uYW1lJExpc3QoKSB7XG4iCisgICAgIiAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPFxuIgorICAgICIgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgJHR5cGUkPigkbmFtZSRfLCAkbmFtZSRfY29udmVydGVyXyk7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgaW50IGdldCRjYXBpdGFsaXplZF9uYW1lJENvdW50KCkge1xuIgorICAgICIgIHJldHVybiAkbmFtZSRfLnNpemUoKTtcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSQgZ2V0JGNhcGl0YWxpemVkX25hbWUkKGludCBpbmRleCkge1xuIgorICAgICIgIHJldHVybiAkbmFtZSRfY29udmVydGVyXy5jb252ZXJ0KCRuYW1lJF8uZ2V0SW50KGluZGV4KSk7XG4iCisgICAgIn1cbiIpOworICBpZiAoU3VwcG9ydFVua25vd25FbnVtVmFsdWUoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPlxuIgorICAgICAgImdldCRjYXBpdGFsaXplZF9uYW1lJFZhbHVlTGlzdCgpIHtcbiIKKyAgICAgICIgIHJldHVybiAkbmFtZSRfO1xuIgorICAgICAgIn1cbiIpOworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgaW50IGdldCRjYXBpdGFsaXplZF9uYW1lJFZhbHVlKGludCBpbmRleCkge1xuIgorICAgICAgIiAgcmV0dXJuICRuYW1lJF8uZ2V0SW50KGluZGV4KTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorCisgIGlmIChkZXNjcmlwdG9yXy0+b3B0aW9ucygpLnBhY2tlZCgpICYmCisgICAgICBIYXNHZW5lcmF0ZWRNZXRob2RzKGRlc2NyaXB0b3JfLT5jb250YWluaW5nX3R5cGUoKSkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgInByaXZhdGUgaW50ICRuYW1lJE1lbW9pemVkU2VyaWFsaXplZFNpemU7XG4iKTsKKyAgfQorCisgIC8vIEdlbmVyYXRlIHByaXZhdGUgc2V0dGVycyBmb3IgdGhlIGJ1aWxkZXIgdG8gcHJveHkgaW50by4KKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHJpdmF0ZSB2b2lkIGVuc3VyZSRjYXBpdGFsaXplZF9uYW1lJElzTXV0YWJsZSgpIHtcbiIKKyAgICAiICBpZiAoISRpc19tdXRhYmxlJCkge1xuIgorICAgICIgICAgJG5hbWUkXyA9IG5ld0ludExpc3QoJG5hbWUkXyk7XG4iCisgICAgIiAgfVxuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIHZvaWQgc2V0JGNhcGl0YWxpemVkX25hbWUkKFxuIgorICAgICIgICAgaW50IGluZGV4LCAkdHlwZSQgdmFsdWUpIHtcbiIKKyAgICAiICBpZiAodmFsdWUgPT0gbnVsbCkge1xuIgorICAgICIgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7XG4iCisgICAgIiAgfVxuIgorICAgICIgIGVuc3VyZSRjYXBpdGFsaXplZF9uYW1lJElzTXV0YWJsZSgpO1xuIgorICAgICIgICRuYW1lJF8uc2V0SW50KGluZGV4LCB2YWx1ZS5nZXROdW1iZXIoKSk7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgdm9pZCBhZGQkY2FwaXRhbGl6ZWRfbmFtZSQoJHR5cGUkIHZhbHVlKSB7XG4iCisgICAgIiAgaWYgKHZhbHVlID09IG51bGwpIHtcbiIKKyAgICAiICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpO1xuIgorICAgICIgIH1cbiIKKyAgICAiICBlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKTtcbiIKKyAgICAiICAkbmFtZSRfLmFkZEludCh2YWx1ZS5nZXROdW1iZXIoKSk7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgdm9pZCBhZGRBbGwkY2FwaXRhbGl6ZWRfbmFtZSQoXG4iCisgICAgIiAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzICR0eXBlJD4gdmFsdWVzKSB7XG4iCisgICAgIiAgZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCk7XG4iCisgICAgIiAgZm9yICgkdHlwZSQgdmFsdWUgOiB2YWx1ZXMpIHtcbiIKKyAgICAiICAgICRuYW1lJF8uYWRkSW50KHZhbHVlLmdldE51bWJlcigpKTtcbiIKKyAgICAiICB9XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgdm9pZCBjbGVhciRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAiICAkbmFtZSRfID0gZW1wdHlJbnRMaXN0KCk7XG4iCisgICAgIn1cbiIpOworCisgIGlmIChTdXBwb3J0VW5rbm93bkVudW1WYWx1ZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgInByaXZhdGUgdm9pZCBzZXQkY2FwaXRhbGl6ZWRfbmFtZSRWYWx1ZShcbiIKKyAgICAgICIgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHtcbiIKKyAgICAgICIgIGVuc3VyZSRjYXBpdGFsaXplZF9uYW1lJElzTXV0YWJsZSgpO1xuIgorICAgICAgIiAgJG5hbWUkXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJwcml2YXRlIHZvaWQgYWRkJGNhcGl0YWxpemVkX25hbWUkVmFsdWUoaW50IHZhbHVlKSB7XG4iCisgICAgICAiICBlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKTtcbiIKKyAgICAgICIgICRuYW1lJF8uYWRkSW50KHZhbHVlKTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJwcml2YXRlIHZvaWQgYWRkQWxsJGNhcGl0YWxpemVkX25hbWUkVmFsdWUoXG4iCisgICAgICAiICAgIGphdmEubGFuZy5JdGVyYWJsZTxqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7XG4iCisgICAgICAiICBlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKTtcbiIKKyAgICAgICIgIGZvciAoaW50IHZhbHVlIDogdmFsdWVzKSB7XG4iCisgICAgICAiICAgICRuYW1lJF8uYWRkSW50KHZhbHVlKTtcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlRW51bUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUJ1aWxkZXJNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBqYXZhLnV0aWwuTGlzdDwkdHlwZSQ+IGdldCRjYXBpdGFsaXplZF9uYW1lJExpc3QoKSB7XG4iCisgICAgIiAgcmV0dXJuIGluc3RhbmNlLmdldCRjYXBpdGFsaXplZF9uYW1lJExpc3QoKTtcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBpbnQgZ2V0JGNhcGl0YWxpemVkX25hbWUkQ291bnQoKSB7XG4iCisgICAgIiAgcmV0dXJuIGluc3RhbmNlLmdldCRjYXBpdGFsaXplZF9uYW1lJENvdW50KCk7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkIGdldCRjYXBpdGFsaXplZF9uYW1lJChpbnQgaW5kZXgpIHtcbiIKKyAgICAiICByZXR1cm4gaW5zdGFuY2UuZ2V0JGNhcGl0YWxpemVkX25hbWUkKGluZGV4KTtcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIHNldCRjYXBpdGFsaXplZF9uYW1lJChcbiIKKyAgICAiICAgIGludCBpbmRleCwgJHR5cGUkIHZhbHVlKSB7XG4iCisgICAgIiAgY29weU9uV3JpdGUoKTtcbiIKKyAgICAiICBpbnN0YW5jZS5zZXQkY2FwaXRhbGl6ZWRfbmFtZSQoaW5kZXgsIHZhbHVlKTtcbiIKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGFkZCRjYXBpdGFsaXplZF9uYW1lJCgkdHlwZSQgdmFsdWUpIHtcbiIKKyAgICAiICBjb3B5T25Xcml0ZSgpO1xuIgorICAgICIgIGluc3RhbmNlLmFkZCRjYXBpdGFsaXplZF9uYW1lJCh2YWx1ZSk7XG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBhZGRBbGwkY2FwaXRhbGl6ZWRfbmFtZSQoXG4iCisgICAgIiAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzICR0eXBlJD4gdmFsdWVzKSB7XG4iCisgICAgIiAgY29weU9uV3JpdGUoKTtcbiIKKyAgICAiICBpbnN0YW5jZS5hZGRBbGwkY2FwaXRhbGl6ZWRfbmFtZSQodmFsdWVzKTsiCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBjbGVhciRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAiICBjb3B5T25Xcml0ZSgpO1xuIgorICAgICIgIGluc3RhbmNlLmNsZWFyJGNhcGl0YWxpemVkX25hbWUkKCk7XG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworCisgIGlmIChTdXBwb3J0VW5rbm93bkVudW1WYWx1ZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+XG4iCisgICAgICAiZ2V0JGNhcGl0YWxpemVkX25hbWUkVmFsdWVMaXN0KCkge1xuIgorICAgICAgIiAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KFxuIgorICAgICAgIiAgICAgIGluc3RhbmNlLmdldCRjYXBpdGFsaXplZF9uYW1lJFZhbHVlTGlzdCgpKTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljIGludCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRWYWx1ZShpbnQgaW5kZXgpIHtcbiIKKyAgICAgICIgIHJldHVybiBpbnN0YW5jZS5nZXQkY2FwaXRhbGl6ZWRfbmFtZSRWYWx1ZShpbmRleCk7XG4iCisgICAgICAifVxuIik7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIHNldCRjYXBpdGFsaXplZF9uYW1lJFZhbHVlKFxuIgorICAgICAgIiAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkge1xuIgorICAgICAgIiAgY29weU9uV3JpdGUoKTtcbiIKKyAgICAgICIgIGluc3RhbmNlLnNldCRjYXBpdGFsaXplZF9uYW1lJFZhbHVlKGluZGV4LCB2YWx1ZSk7XG4iCisgICAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAgICJ9XG4iKTsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgYWRkJGNhcGl0YWxpemVkX25hbWUkVmFsdWUoaW50IHZhbHVlKSB7XG4iCisgICAgICAiICBpbnN0YW5jZS5hZGQkY2FwaXRhbGl6ZWRfbmFtZSRWYWx1ZSh2YWx1ZSk7XG4iCisgICAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAgICJ9XG4iKTsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgYWRkQWxsJGNhcGl0YWxpemVkX25hbWUkVmFsdWUoXG4iCisgICAgICAiICAgIGphdmEubGFuZy5JdGVyYWJsZTxqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7XG4iCisgICAgICAiICBjb3B5T25Xcml0ZSgpO1xuIgorICAgICAgIiAgaW5zdGFuY2UuYWRkQWxsJGNhcGl0YWxpemVkX25hbWUkVmFsdWUodmFsdWVzKTtcbiIKKyAgICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICAgIn1cbiIpOworICB9Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVFbnVtRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlRmllbGRCdWlsZGVySW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSAgY29uc3QgeworICAvLyBub29wIGZvciBlbnVtcworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlRW51bUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUluaXRpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAiJG5hbWUkXyA9IGVtcHR5SW50TGlzdCgpO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVFbnVtRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gVGhlIGNvZGUgYmVsb3cgZG9lcyB0d28gb3B0aW1pemF0aW9uczoKKyAgLy8gICAxLiBJZiB0aGUgb3RoZXIgbGlzdCBpcyBlbXB0eSwgdGhlcmUncyBub3RoaW5nIHRvIGRvLiBUaGlzIGVuc3VyZXMgd2UKKyAgLy8gICAgICBkb24ndCBhbGxvY2F0ZSBhIG5ldyBhcnJheSBpZiB3ZSBhbHJlYWR5IGhhdmUgYW4gaW1tdXRhYmxlIG9uZS4KKyAgLy8gICAyLiBJZiB0aGUgb3RoZXIgbGlzdCBpcyBub24tZW1wdHkgYW5kIG91ciBjdXJyZW50IGxpc3QgaXMgZW1wdHksIHdlIGNhbgorICAvLyAgICAgIHJldXNlIHRoZSBvdGhlciBsaXN0IHdoaWNoIGlzIGd1YXJhbnRlZWQgdG8gYmUgaW1tdXRhYmxlLgorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoIW90aGVyLiRuYW1lJF8uaXNFbXB0eSgpKSB7XG4iCisgICAgIiAgaWYgKCRuYW1lJF8uaXNFbXB0eSgpKSB7XG4iCisgICAgIiAgICAkbmFtZSRfID0gb3RoZXIuJG5hbWUkXztcbiIKKyAgICAiICB9IGVsc2Uge1xuIgorICAgICIgICAgZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCk7XG4iCisgICAgIiAgICAkbmFtZSRfLmFkZEFsbChvdGhlci4kbmFtZSRfKTtcbiIKKyAgICAiICB9XG4iCisgICAgIiAgJG9uX2NoYW5nZWQkXG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlRW51bUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUR5bmFtaWNNZXRob2RNYWtlSW1tdXRhYmxlQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkbmFtZSRfLm1ha2VJbW11dGFibGUoKTtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlRW51bUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZVBhcnNpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIFJlYWQgYW5kIHN0b3JlIHRoZSBlbnVtCisgIGlmIChTdXBwb3J0VW5rbm93bkVudW1WYWx1ZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaW50IHJhd1ZhbHVlID0gaW5wdXQucmVhZEVudW0oKTtcbiIKKyAgICAgICJpZiAoISRpc19tdXRhYmxlJCkge1xuIgorICAgICAgIiAgJG5hbWUkXyA9IG5ld0ludExpc3QoKTtcbiIKKyAgICAgICJ9XG4iCisgICAgICAiJG5hbWUkXy5hZGRJbnQocmF3VmFsdWUpO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJpbnQgcmF3VmFsdWUgPSBpbnB1dC5yZWFkRW51bSgpO1xuIgorICAgICAgIiR0eXBlJCB2YWx1ZSA9ICR0eXBlJC52YWx1ZU9mKHJhd1ZhbHVlKTtcbiIKKyAgICAgICAgImlmICh2YWx1ZSA9PSBudWxsKSB7XG4iKTsKKyAgICBpZiAoUHJlc2VydmVVbmtub3duRmllbGRzKGRlc2NyaXB0b3JfLT5jb250YWluaW5nX3R5cGUoKSkpIHsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICIgIHN1cGVyLm1lcmdlVmFyaW50RmllbGQoJG51bWJlciQsIHJhd1ZhbHVlKTtcbiIpOworICAgIH0KKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIn0gZWxzZSB7XG4iCisgICAgICAiICBpZiAoISRpc19tdXRhYmxlJCkge1xuIgorICAgICAgIiAgICAkbmFtZSRfID0gbmV3SW50TGlzdCgpO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIiAgJG5hbWUkXy5hZGRJbnQocmF3VmFsdWUpO1xuIgorICAgICAgIn1cbiIpOworICB9Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVFbnVtRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlUGFyc2luZ0NvZGVGcm9tUGFja2VkKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIFdyYXAgR2VuZXJhdGVQYXJzaW5nQ29kZSdzIGNvbnRlbnRzIHdpdGggYSB3aGlsZSBsb29wLgorCisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTtcbiIKKyAgICAiaW50IG9sZExpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7XG4iCisgICAgIndoaWxlKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkge1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIEdlbmVyYXRlUGFyc2luZ0NvZGUocHJpbnRlcik7CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJ9XG4iCisgICAgImlucHV0LnBvcExpbWl0KG9sZExpbWl0KTtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlRW51bUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZVBhcnNpbmdEb25lQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoJGlzX211dGFibGUkKSB7XG4iCisgICAgIiAgJG5hbWUkXy5tYWtlSW1tdXRhYmxlKCk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlRW51bUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChkZXNjcmlwdG9yXy0+b3B0aW9ucygpLnBhY2tlZCgpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJpZiAoZ2V0JGNhcGl0YWxpemVkX25hbWUkTGlzdCgpLnNpemUoKSA+IDApIHtcbiIKKyAgICAgICIgIG91dHB1dC53cml0ZVJhd1ZhcmludDMyKCR0YWckKTtcbiIKKyAgICAgICIgIG91dHB1dC53cml0ZVJhd1ZhcmludDMyKCRuYW1lJE1lbW9pemVkU2VyaWFsaXplZFNpemUpO1xuIgorICAgICAgIn1cbiIKKyAgICAgICJmb3IgKGludCBpID0gMDsgaSA8ICRuYW1lJF8uc2l6ZSgpOyBpKyspIHtcbiIKKyAgICAgICIgIG91dHB1dC53cml0ZUVudW1Ob1RhZygkbmFtZSRfLmdldEludChpKSk7XG4iCisgICAgICAifVxuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJmb3IgKGludCBpID0gMDsgaSA8ICRuYW1lJF8uc2l6ZSgpOyBpKyspIHtcbiIKKyAgICAgICIgIG91dHB1dC53cml0ZUVudW0oJG51bWJlciQsICRuYW1lJF8uZ2V0SW50KGkpKTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlRW51bUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJ7XG4iCisgICAgIiAgaW50IGRhdGFTaXplID0gMDtcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJmb3IgKGludCBpID0gMDsgaSA8ICRuYW1lJF8uc2l6ZSgpOyBpKyspIHtcbiIKKyAgICAiICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtXG4iCisgICAgIiAgICAuY29tcHV0ZUVudW1TaXplTm9UYWcoJG5hbWUkXy5nZXRJbnQoaSkpO1xuIgorICAgICJ9XG4iKTsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgInNpemUgKz0gZGF0YVNpemU7XG4iKTsKKyAgaWYgKGRlc2NyaXB0b3JfLT5vcHRpb25zKCkucGFja2VkKCkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImlmICghZ2V0JGNhcGl0YWxpemVkX25hbWUkTGlzdCgpLmlzRW1wdHkoKSkgeyIKKyAgICAgICIgIHNpemUgKz0gJHRhZ19zaXplJDtcbiIKKyAgICAgICIgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbVxuIgorICAgICAgIiAgICAuY29tcHV0ZVJhd1ZhcmludDMyU2l6ZShkYXRhU2l6ZSk7XG4iCisgICAgICAifSIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAic2l6ZSArPSAkdGFnX3NpemUkICogJG5hbWUkXy5zaXplKCk7XG4iKTsKKyAgfQorCisgIC8vIGNhY2hlIHRoZSBkYXRhIHNpemUgZm9yIHBhY2tlZCBmaWVsZHMuCisgIGlmIChkZXNjcmlwdG9yXy0+b3B0aW9ucygpLnBhY2tlZCgpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkbmFtZSRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7XG4iKTsKKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlRW51bUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUVxdWFsc0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicmVzdWx0ID0gcmVzdWx0ICYmICRuYW1lJF8uZXF1YWxzKG90aGVyLiRuYW1lJF8pO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVFbnVtRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlSGFzaENvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKGdldCRjYXBpdGFsaXplZF9uYW1lJENvdW50KCkgPiAwKSB7XG4iCisgICAgIiAgaGFzaCA9ICgzNyAqIGhhc2gpICsgJGNvbnN0YW50X25hbWUkO1xuIgorICAgICIgIGhhc2ggPSAoNTMgKiBoYXNoKSArICRuYW1lJF8uaGFzaENvZGUoKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3N0cmluZyBSZXBlYXRlZEltbXV0YWJsZUVudW1GaWVsZExpdGVHZW5lcmF0b3I6OkdldEJveGVkVHlwZSgpIGNvbnN0IHsKKyAgcmV0dXJuIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcl8tPmVudW1fdHlwZSgpKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9lbnVtX2ZpZWxkX2xpdGUuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2VudW1fZmllbGRfbGl0ZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJjNDFjM2UKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9lbnVtX2ZpZWxkX2xpdGUuaApAQCAtMCwwICsxLDE1OSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX0VOVU1fRklFTERfTElURV9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfRU5VTV9GSUVMRF9MSVRFX0hfXworCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2ZpZWxkLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKyAgbmFtZXNwYWNlIGNvbXBpbGVyIHsKKyAgICBuYW1lc3BhY2UgamF2YSB7CisgICAgICBjbGFzcyBDb250ZXh0OyAgICAgICAgICAgIC8vIGNvbnRleHQuaAorICAgICAgY2xhc3MgQ2xhc3NOYW1lUmVzb2x2ZXI7ICAvLyBuYW1lX3Jlc29sdmVyLmgKKyAgICB9CisgIH0KK30KKworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YSB7CisKK2NsYXNzIEltbXV0YWJsZUVudW1GaWVsZExpdGVHZW5lcmF0b3IgOiBwdWJsaWMgSW1tdXRhYmxlRmllbGRMaXRlR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IEltbXV0YWJsZUVudW1GaWVsZExpdGVHZW5lcmF0b3IoCisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGludCBtZXNzYWdlQml0SW5kZXgsCisgICAgICBpbnQgYnVpbGRlckJpdEluZGV4LCBDb250ZXh0KiBjb250ZXh0KTsKKyAgfkltbXV0YWJsZUVudW1GaWVsZExpdGVHZW5lcmF0b3IoKTsKKworICAvLyBpbXBsZW1lbnRzIEltbXV0YWJsZUZpZWxkTGl0ZUdlbmVyYXRvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgaW50IEdldE51bUJpdHNGb3JNZXNzYWdlKCkgY29uc3Q7CisgIGludCBHZXROdW1CaXRzRm9yQnVpbGRlcigpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSW50ZXJmYWNlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUJ1aWxkZXJNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUluaXRpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVEeW5hbWljTWV0aG9kTWFrZUltbXV0YWJsZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlUGFyc2luZ0RvbmVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVGaWVsZEJ1aWxkZXJJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVIYXNoQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyAgc3RyaW5nIEdldEJveGVkVHlwZSgpIGNvbnN0OworCisgcHJvdGVjdGVkOgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlc187CisgIGNvbnN0IGludCBtZXNzYWdlQml0SW5kZXhfOworICBjb25zdCBpbnQgYnVpbGRlckJpdEluZGV4XzsKKyAgQ29udGV4dCogY29udGV4dF87CisgIENsYXNzTmFtZVJlc29sdmVyKiBuYW1lX3Jlc29sdmVyXzsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhJbW11dGFibGVFbnVtRmllbGRMaXRlR2VuZXJhdG9yKTsKK307CisKK2NsYXNzIEltbXV0YWJsZUVudW1PbmVvZkZpZWxkTGl0ZUdlbmVyYXRvcgorICAgIDogcHVibGljIEltbXV0YWJsZUVudW1GaWVsZExpdGVHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgSW1tdXRhYmxlRW51bU9uZW9mRmllbGRMaXRlR2VuZXJhdG9yKAorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwgQ29udGV4dCogY29udGV4dCk7CisgIH5JbW11dGFibGVFbnVtT25lb2ZGaWVsZExpdGVHZW5lcmF0b3IoKTsKKworICB2b2lkIEdlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVQYXJzaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVIYXNoQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoSW1tdXRhYmxlRW51bU9uZW9mRmllbGRMaXRlR2VuZXJhdG9yKTsKK307CisKK2NsYXNzIFJlcGVhdGVkSW1tdXRhYmxlRW51bUZpZWxkTGl0ZUdlbmVyYXRvcgorICAgIDogcHVibGljIEltbXV0YWJsZUZpZWxkTGl0ZUdlbmVyYXRvciB7CisgcHVibGljOgorICBleHBsaWNpdCBSZXBlYXRlZEltbXV0YWJsZUVudW1GaWVsZExpdGVHZW5lcmF0b3IoCisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGludCBtZXNzYWdlQml0SW5kZXgsCisgICAgICBpbnQgYnVpbGRlckJpdEluZGV4LCBDb250ZXh0KiBjb250ZXh0KTsKKyAgflJlcGVhdGVkSW1tdXRhYmxlRW51bUZpZWxkTGl0ZUdlbmVyYXRvcigpOworCisgIC8vIGltcGxlbWVudHMgSW1tdXRhYmxlRmllbGRMaXRlR2VuZXJhdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICBpbnQgR2V0TnVtQml0c0Zvck1lc3NhZ2UoKSBjb25zdDsKKyAgaW50IEdldE51bUJpdHNGb3JCdWlsZGVyKCkgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVJbnRlcmZhY2VNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnVpbGRlck1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUR5bmFtaWNNZXRob2RNYWtlSW1tdXRhYmxlQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVQYXJzaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVQYXJzaW5nQ29kZUZyb21QYWNrZWQoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlUGFyc2luZ0RvbmVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVGaWVsZEJ1aWxkZXJJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVIYXNoQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyAgc3RyaW5nIEdldEJveGVkVHlwZSgpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXNfOworICBjb25zdCBpbnQgbWVzc2FnZUJpdEluZGV4XzsKKyAgY29uc3QgaW50IGJ1aWxkZXJCaXRJbmRleF87CisgIENvbnRleHQqIGNvbnRleHRfOworICBDbGFzc05hbWVSZXNvbHZlciogbmFtZV9yZXNvbHZlcl87CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFJlcGVhdGVkSW1tdXRhYmxlRW51bUZpZWxkTGl0ZUdlbmVyYXRvcik7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgamF2YQorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9FTlVNX0ZJRUxEX0xJVEVfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9lbnVtX2xpdGUuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9lbnVtX2xpdGUuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWQ0MTVlZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2VudW1fbGl0ZS5jYwpAQCAtMCwwICsxLDIxMCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHN0cmluZz4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfY29udGV4dC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZW51bV9saXRlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9kb2NfY29tbWVudC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfaGVscGVycy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbmFtZV9yZXNvbHZlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmEgeworCituYW1lc3BhY2UgeworYm9vbCBFbnVtSGFzQ3VzdG9tT3B0aW9ucyhjb25zdCBFbnVtRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBpZiAoZGVzY3JpcHRvci0+b3B0aW9ucygpLnVua25vd25fZmllbGRzKCkuZmllbGRfY291bnQoKSA+IDApIHJldHVybiB0cnVlOworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3ItPnZhbHVlX2NvdW50KCk7ICsraSkgeworICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIHZhbHVlID0gZGVzY3JpcHRvci0+dmFsdWUoaSk7CisgICAgaWYgKHZhbHVlLT5vcHRpb25zKCkudW5rbm93bl9maWVsZHMoKS5maWVsZF9jb3VudCgpID4gMCkgcmV0dXJuIHRydWU7CisgIH0KKyAgcmV0dXJuIGZhbHNlOworfQorfSAgLy8gbmFtZXNwYWNlCisKK0VudW1MaXRlR2VuZXJhdG9yOjpFbnVtTGl0ZUdlbmVyYXRvcihjb25zdCBFbnVtRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpbW11dGFibGVfYXBpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb250ZXh0KiBjb250ZXh0KQorICA6IGRlc2NyaXB0b3JfKGRlc2NyaXB0b3IpLCBpbW11dGFibGVfYXBpXyhpbW11dGFibGVfYXBpKSwKKyAgICBuYW1lX3Jlc29sdmVyXyhjb250ZXh0LT5HZXROYW1lUmVzb2x2ZXIoKSkgIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+dmFsdWVfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogdmFsdWUgPSBkZXNjcmlwdG9yXy0+dmFsdWUoaSk7CisgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogY2Fub25pY2FsX3ZhbHVlID0KKyAgICAgIGRlc2NyaXB0b3JfLT5GaW5kVmFsdWVCeU51bWJlcih2YWx1ZS0+bnVtYmVyKCkpOworCisgICAgaWYgKHZhbHVlID09IGNhbm9uaWNhbF92YWx1ZSkgeworICAgICAgY2Fub25pY2FsX3ZhbHVlc18ucHVzaF9iYWNrKHZhbHVlKTsKKyAgICB9IGVsc2UgeworICAgICAgQWxpYXMgYWxpYXM7CisgICAgICBhbGlhcy52YWx1ZSA9IHZhbHVlOworICAgICAgYWxpYXMuY2Fub25pY2FsX3ZhbHVlID0gY2Fub25pY2FsX3ZhbHVlOworICAgICAgYWxpYXNlc18ucHVzaF9iYWNrKGFsaWFzKTsKKyAgICB9CisgIH0KK30KKworRW51bUxpdGVHZW5lcmF0b3I6On5FbnVtTGl0ZUdlbmVyYXRvcigpIHt9CisKK3ZvaWQgRW51bUxpdGVHZW5lcmF0b3I6OkdlbmVyYXRlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIFdyaXRlRW51bURvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCgKKyAgICAicHVibGljIGVudW0gJGNsYXNzbmFtZSRcbiIKKyAgICAiICAgIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZSB7XG4iLAorICAgICJjbGFzc25hbWUiLCBkZXNjcmlwdG9yXy0+bmFtZSgpKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBjYW5vbmljYWxfdmFsdWVzXy5zaXplKCk7IGkrKykgeworICAgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyczsKKyAgICB2YXJzWyJuYW1lIl0gPSBjYW5vbmljYWxfdmFsdWVzX1tpXS0+bmFtZSgpOworICAgIHZhcnNbIm51bWJlciJdID0gU2ltcGxlSXRvYShjYW5vbmljYWxfdmFsdWVzX1tpXS0+bnVtYmVyKCkpOworICAgIFdyaXRlRW51bVZhbHVlRG9jQ29tbWVudChwcmludGVyLCBjYW5vbmljYWxfdmFsdWVzX1tpXSk7CisgICAgaWYgKGNhbm9uaWNhbF92YWx1ZXNfW2ldLT5vcHRpb25zKCkuZGVwcmVjYXRlZCgpKSB7CisgICAgICBwcmludGVyLT5QcmludCgiQGphdmEubGFuZy5EZXByZWNhdGVkXG4iKTsKKyAgICB9CisgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICIkbmFtZSQoJG51bWJlciQpLFxuIik7CisgIH0KKworICBpZiAoU3VwcG9ydFVua25vd25FbnVtVmFsdWUoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBwcmludGVyLT5QcmludCgiVU5SRUNPR05JWkVEKC0xKSxcbiIpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIjtcbiIKKyAgICAiXG4iKTsKKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgYWxpYXNlc18uc2l6ZSgpOyBpKyspIHsKKyAgICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcnM7CisgICAgdmFyc1siY2xhc3NuYW1lIl0gPSBkZXNjcmlwdG9yXy0+bmFtZSgpOworICAgIHZhcnNbIm5hbWUiXSA9IGFsaWFzZXNfW2ldLnZhbHVlLT5uYW1lKCk7CisgICAgdmFyc1siY2Fub25pY2FsX25hbWUiXSA9IGFsaWFzZXNfW2ldLmNhbm9uaWNhbF92YWx1ZS0+bmFtZSgpOworICAgIFdyaXRlRW51bVZhbHVlRG9jQ29tbWVudChwcmludGVyLCBhbGlhc2VzX1tpXS52YWx1ZSk7CisgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICJwdWJsaWMgc3RhdGljIGZpbmFsICRjbGFzc25hbWUkICRuYW1lJCA9ICRjYW5vbmljYWxfbmFtZSQ7XG4iKTsKKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPnZhbHVlX2NvdW50KCk7IGkrKykgeworICAgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyczsKKyAgICB2YXJzWyJuYW1lIl0gPSBkZXNjcmlwdG9yXy0+dmFsdWUoaSktPm5hbWUoKTsKKyAgICB2YXJzWyJudW1iZXIiXSA9IFNpbXBsZUl0b2EoZGVzY3JpcHRvcl8tPnZhbHVlKGkpLT5udW1iZXIoKSk7CisgICAgV3JpdGVFbnVtVmFsdWVEb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfLT52YWx1ZShpKSk7CisgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICJwdWJsaWMgc3RhdGljIGZpbmFsIGludCAkbmFtZSRfVkFMVUUgPSAkbnVtYmVyJDtcbiIpOworICB9CisgIHByaW50ZXItPlByaW50KCJcbiIpOworCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIlxuIgorICAgICJwdWJsaWMgZmluYWwgaW50IGdldE51bWJlcigpIHtcbiIKKyAgICAiICByZXR1cm4gdmFsdWU7XG4iCisgICAgIn1cbiIKKyAgICAiXG4iCisgICAgInB1YmxpYyBzdGF0aWMgJGNsYXNzbmFtZSQgdmFsdWVPZihpbnQgdmFsdWUpIHtcbiIKKyAgICAiICBzd2l0Y2ggKHZhbHVlKSB7XG4iLAorICAgICJjbGFzc25hbWUiLCBkZXNjcmlwdG9yXy0+bmFtZSgpKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgY2Fub25pY2FsX3ZhbHVlc18uc2l6ZSgpOyBpKyspIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJjYXNlICRudW1iZXIkOiByZXR1cm4gJG5hbWUkO1xuIiwKKyAgICAgICJuYW1lIiwgY2Fub25pY2FsX3ZhbHVlc19baV0tPm5hbWUoKSwKKyAgICAgICJudW1iZXIiLCBTaW1wbGVJdG9hKGNhbm9uaWNhbF92YWx1ZXNfW2ldLT5udW1iZXIoKSkpOworICB9CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KAorICAgICIgICAgZGVmYXVsdDogcmV0dXJuIG51bGw7XG4iCisgICAgIiAgfVxuIgorICAgICJ9XG4iCisgICAgIlxuIgorICAgICJwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8JGNsYXNzbmFtZSQ+XG4iCisgICAgIiAgICBpbnRlcm5hbEdldFZhbHVlTWFwKCkge1xuIgorICAgICIgIHJldHVybiBpbnRlcm5hbFZhbHVlTWFwO1xuIgorICAgICJ9XG4iCisgICAgInByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8XG4iCisgICAgIiAgICAkY2xhc3NuYW1lJD4gaW50ZXJuYWxWYWx1ZU1hcCA9XG4iCisgICAgIiAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPCRjbGFzc25hbWUkPigpIHtcbiIKKyAgICAiICAgICAgICBwdWJsaWMgJGNsYXNzbmFtZSQgZmluZFZhbHVlQnlOdW1iZXIoaW50IG51bWJlcikge1xuIgorICAgICIgICAgICAgICAgcmV0dXJuICRjbGFzc25hbWUkLnZhbHVlT2YobnVtYmVyKTtcbiIKKyAgICAiICAgICAgICB9XG4iCisgICAgIiAgICAgIH07XG4iCisgICAgIlxuIiwKKyAgICAiY2xhc3NuYW1lIiwgZGVzY3JpcHRvcl8tPm5hbWUoKSk7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgInByaXZhdGUgZmluYWwgaW50IHZhbHVlO1xuXG4iCisgICAgInByaXZhdGUgJGNsYXNzbmFtZSQoaW50IHZhbHVlKSB7XG4iLAorICAgICJjbGFzc25hbWUiLCBkZXNjcmlwdG9yXy0+bmFtZSgpKTsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIiAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuIgorICAgICJ9XG4iKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAiXG4iCisgICAgIi8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChlbnVtX3Njb3BlOiRmdWxsX25hbWUkKVxuIiwKKyAgICAiZnVsbF9uYW1lIiwgZGVzY3JpcHRvcl8tPmZ1bGxfbmFtZSgpKTsKKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KCJ9XG5cbiIpOworfQorCitib29sIEVudW1MaXRlR2VuZXJhdG9yOjpDYW5Vc2VFbnVtVmFsdWVzKCkgeworICBpZiAoY2Fub25pY2FsX3ZhbHVlc18uc2l6ZSgpICE9IGRlc2NyaXB0b3JfLT52YWx1ZV9jb3VudCgpKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPnZhbHVlX2NvdW50KCk7IGkrKykgeworICAgIGlmIChkZXNjcmlwdG9yXy0+dmFsdWUoaSktPm5hbWUoKSAhPSBjYW5vbmljYWxfdmFsdWVzX1tpXS0+bmFtZSgpKSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICB9CisgIHJldHVybiB0cnVlOworfQorCit9ICAvLyBuYW1lc3BhY2UgamF2YQorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2VudW1fbGl0ZS5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZW51bV9saXRlLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWUyZjVmNwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2VudW1fbGl0ZS5oCkBAIC0wLDAgKzEsOTkgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9FTlVNX0xJVEVfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX0VOVU1fTElURV9IX18KKworI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDx2ZWN0b3I+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworICBuYW1lc3BhY2UgY29tcGlsZXIgeworICAgIG5hbWVzcGFjZSBqYXZhIHsKKyAgICAgIGNsYXNzIENvbnRleHQ7ICAgICAgICAgICAvLyBjb250ZXh0LmgKKyAgICAgIGNsYXNzIENsYXNzTmFtZVJlc29sdmVyOyAvLyBuYW1lX3Jlc29sdmVyLmgKKyAgICB9CisgIH0KKyAgbmFtZXNwYWNlIGlvIHsKKyAgICBjbGFzcyBQcmludGVyOyAgICAgICAgICAgICAvLyBwcmludGVyLmgKKyAgfQorfQorCituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhIHsKKworY2xhc3MgRW51bUxpdGVHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgRW51bUxpdGVHZW5lcmF0b3IoY29uc3QgRW51bURlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpbW11dGFibGVfYXBpLAorICAgICAgICAgICAgICAgICAgICAgICAgIENvbnRleHQqIGNvbnRleHQpOworICB+RW51bUxpdGVHZW5lcmF0b3IoKTsKKworICB2b2lkIEdlbmVyYXRlKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworIHByaXZhdGU6CisgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKworICAvLyBUaGUgcHJvdG8gbGFuZ3VhZ2UgYWxsb3dzIG11bHRpcGxlIGVudW0gY29uc3RhbnRzIHRvIGhhdmUgdGhlIHNhbWUgbnVtZXJpYworICAvLyB2YWx1ZS4gIEphdmEsIGhvd2V2ZXIsIGRvZXMgbm90IGFsbG93IG11bHRpcGxlIGVudW0gY29uc3RhbnRzIHRvIGJlCisgIC8vIGNvbnNpZGVyZWQgZXF1aXZhbGVudC4gIFdlIHRyZWF0IHRoZSBmaXJzdCBkZWZpbmVkIGNvbnN0YW50IGZvciBhbnkKKyAgLy8gZ2l2ZW4gbnVtZXJpYyB2YWx1ZSBhcyAiY2Fub25pY2FsIiBhbmQgdGhlIHJlc3QgYXMgYWxpYXNlcyBvZiB0aGF0CisgIC8vIGNhbm9uaWNhbCB2YWx1ZS4KKyAgdmVjdG9yPGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqPiBjYW5vbmljYWxfdmFsdWVzXzsKKworICBzdHJ1Y3QgQWxpYXMgeworICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIHZhbHVlOworICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIGNhbm9uaWNhbF92YWx1ZTsKKyAgfTsKKyAgdmVjdG9yPEFsaWFzPiBhbGlhc2VzXzsKKworICBib29sIGltbXV0YWJsZV9hcGlfOworCisgIENvbnRleHQqIGNvbnRleHRfOworICBDbGFzc05hbWVSZXNvbHZlciogbmFtZV9yZXNvbHZlcl87CisKKyAgYm9vbCBDYW5Vc2VFbnVtVmFsdWVzKCk7CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEVudW1MaXRlR2VuZXJhdG9yKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX0VOVU1fTElURV9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2V4dGVuc2lvbi5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2V4dGVuc2lvbi5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ZGI3MDg1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZXh0ZW5zaW9uLmNjCkBAIC0wLDAgKzEsMjExIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2V4dGVuc2lvbi5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9jb250ZXh0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9kb2NfY29tbWVudC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfaGVscGVycy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbmFtZV9yZXNvbHZlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhIHsKKworSW1tdXRhYmxlRXh0ZW5zaW9uR2VuZXJhdG9yOjpJbW11dGFibGVFeHRlbnNpb25HZW5lcmF0b3IoCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBDb250ZXh0KiBjb250ZXh0KQorICA6IGRlc2NyaXB0b3JfKGRlc2NyaXB0b3IpLCBjb250ZXh0Xyhjb250ZXh0KSwKKyAgICBuYW1lX3Jlc29sdmVyXyhjb250ZXh0LT5HZXROYW1lUmVzb2x2ZXIoKSkgeworICBpZiAoZGVzY3JpcHRvcl8tPmV4dGVuc2lvbl9zY29wZSgpICE9IE5VTEwpIHsKKyAgICBzY29wZV8gPSBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKAorICAgICAgICBkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX3Njb3BlKCkpOworICB9IGVsc2UgeworICAgIHNjb3BlXyA9IG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcl8tPmZpbGUoKSk7CisgIH0KK30KKworSW1tdXRhYmxlRXh0ZW5zaW9uR2VuZXJhdG9yOjp+SW1tdXRhYmxlRXh0ZW5zaW9uR2VuZXJhdG9yKCkge30KKworLy8gSW5pdGlhbGl6ZXMgdGhlIHZhcnMgcmVmZXJlbmNlZCBpbiB0aGUgZ2VuZXJhdGVkIGNvZGUgdGVtcGxhdGVzLgordm9pZCBFeHRlbnNpb25HZW5lcmF0b3I6OkluaXRUZW1wbGF0ZVZhcnMoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBzY29wZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaW1tdXRhYmxlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3NOYW1lUmVzb2x2ZXIqIG5hbWVfcmVzb2x2ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXA8c3RyaW5nLCBzdHJpbmc+KiB2YXJzX3BvaW50ZXIpIHsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiAmdmFycyA9ICp2YXJzX3BvaW50ZXI7CisgIHZhcnNbInNjb3BlIl0gPSBzY29wZTsKKyAgdmFyc1sibmFtZSJdID0gVW5kZXJzY29yZXNUb0NhbWVsQ2FzZShkZXNjcmlwdG9yKTsKKyAgdmFyc1siY29udGFpbmluZ190eXBlIl0gPQorICAgICAgbmFtZV9yZXNvbHZlci0+R2V0Q2xhc3NOYW1lKGRlc2NyaXB0b3ItPmNvbnRhaW5pbmdfdHlwZSgpLCBpbW11dGFibGUpOworICB2YXJzWyJudW1iZXIiXSA9IFNpbXBsZUl0b2EoZGVzY3JpcHRvci0+bnVtYmVyKCkpOworICB2YXJzWyJjb25zdGFudF9uYW1lIl0gPSBGaWVsZENvbnN0YW50TmFtZShkZXNjcmlwdG9yKTsKKyAgdmFyc1siaW5kZXgiXSA9IFNpbXBsZUl0b2EoZGVzY3JpcHRvci0+aW5kZXgoKSk7CisgIHZhcnNbImRlZmF1bHQiXSA9IGRlc2NyaXB0b3ItPmlzX3JlcGVhdGVkKCkgPworICAgICAgIiIgOiBEZWZhdWx0VmFsdWUoZGVzY3JpcHRvciwgaW1tdXRhYmxlLCBuYW1lX3Jlc29sdmVyKTsKKyAgdmFyc1sidHlwZV9jb25zdGFudCJdID0gRmllbGRUeXBlTmFtZShHZXRUeXBlKGRlc2NyaXB0b3IpKTsKKyAgdmFyc1sicGFja2VkIl0gPSBkZXNjcmlwdG9yLT5vcHRpb25zKCkucGFja2VkKCkgPyAidHJ1ZSIgOiAiZmFsc2UiOworICB2YXJzWyJlbnVtX21hcCJdID0gIm51bGwiOworICB2YXJzWyJwcm90b3R5cGUiXSA9ICJudWxsIjsKKworICBKYXZhVHlwZSBqYXZhX3R5cGUgPSBHZXRKYXZhVHlwZShkZXNjcmlwdG9yKTsKKyAgc3RyaW5nIHNpbmd1bGFyX3R5cGU7CisgIHN3aXRjaCAoamF2YV90eXBlKSB7CisgICAgY2FzZSBKQVZBVFlQRV9NRVNTQUdFOgorICAgICAgc2luZ3VsYXJfdHlwZSA9IG5hbWVfcmVzb2x2ZXItPkdldENsYXNzTmFtZShkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGltbXV0YWJsZSk7CisgICAgICB2YXJzWyJwcm90b3R5cGUiXSA9IHNpbmd1bGFyX3R5cGUgKyAiLmdldERlZmF1bHRJbnN0YW5jZSgpIjsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgSkFWQVRZUEVfRU5VTToKKyAgICAgIHNpbmd1bGFyX3R5cGUgPSBuYW1lX3Jlc29sdmVyLT5HZXRDbGFzc05hbWUoZGVzY3JpcHRvci0+ZW51bV90eXBlKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbW11dGFibGUpOworICAgICAgdmFyc1siZW51bV9tYXAiXSA9IHNpbmd1bGFyX3R5cGUgKyAiLmludGVybmFsR2V0VmFsdWVNYXAoKSI7CisgICAgICBicmVhazsKKyAgICBjYXNlIEpBVkFUWVBFX1NUUklORzoKKyAgICAgIHNpbmd1bGFyX3R5cGUgPSAiamF2YS5sYW5nLlN0cmluZyI7CisgICAgICBicmVhazsKKyAgICBjYXNlIEpBVkFUWVBFX0JZVEVTOgorICAgICAgc2luZ3VsYXJfdHlwZSA9IGltbXV0YWJsZSA/ICJjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmciIDogImJ5dGVbXSI7CisgICAgICBicmVhazsKKyAgICBkZWZhdWx0OgorICAgICAgc2luZ3VsYXJfdHlwZSA9IEJveGVkUHJpbWl0aXZlVHlwZU5hbWUoamF2YV90eXBlKTsKKyAgICAgIGJyZWFrOworICB9CisgIHZhcnNbInR5cGUiXSA9IGRlc2NyaXB0b3ItPmlzX3JlcGVhdGVkKCkgPworICAgICAgImphdmEudXRpbC5MaXN0PCIgKyBzaW5ndWxhcl90eXBlICsgIj4iIDogc2luZ3VsYXJfdHlwZTsKKyAgdmFyc1sic2luZ3VsYXJfdHlwZSJdID0gc2luZ3VsYXJfdHlwZTsKK30KKwordm9pZCBJbW11dGFibGVFeHRlbnNpb25HZW5lcmF0b3I6OkdlbmVyYXRlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyczsKKyAgY29uc3QgYm9vbCBrVXNlSW1tdXRhYmxlTmFtZXMgPSB0cnVlOworICBJbml0VGVtcGxhdGVWYXJzKGRlc2NyaXB0b3JfLCBzY29wZV8sIGtVc2VJbW11dGFibGVOYW1lcywgbmFtZV9yZXNvbHZlcl8sCisgICAgICAgICAgICAgICAgICAgJnZhcnMpOworICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgInB1YmxpYyBzdGF0aWMgZmluYWwgaW50ICRjb25zdGFudF9uYW1lJCA9ICRudW1iZXIkO1xuIik7CisKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBpZiAoSGFzRGVzY3JpcHRvck1ldGhvZHMoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICAvLyBOb24tbGl0ZSBleHRlbnNpb25zCisgICAgaWYgKGRlc2NyaXB0b3JfLT5leHRlbnNpb25fc2NvcGUoKSA9PSBOVUxMKSB7CisgICAgICAvLyBOb24tbmVzdGVkCisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICB2YXJzLAorICAgICAgICAgICJwdWJsaWMgc3RhdGljIGZpbmFsXG4iCisgICAgICAgICAgIiAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjxcbiIKKyAgICAgICAgICAiICAgICRjb250YWluaW5nX3R5cGUkLFxuIgorICAgICAgICAgICIgICAgJHR5cGUkPiAkbmFtZSQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VcbiIKKyAgICAgICAgICAiICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbihcbiIKKyAgICAgICAgICAiICAgICAgJHNpbmd1bGFyX3R5cGUkLmNsYXNzLFxuIgorICAgICAgICAgICIgICAgICAkcHJvdG90eXBlJCk7XG4iKTsKKyAgICB9IGVsc2UgeworICAgICAgLy8gTmVzdGVkCisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICB2YXJzLAorICAgICAgICAgICJwdWJsaWMgc3RhdGljIGZpbmFsXG4iCisgICAgICAgICAgIiAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjxcbiIKKyAgICAgICAgICAiICAgICRjb250YWluaW5nX3R5cGUkLFxuIgorICAgICAgICAgICIgICAgJHR5cGUkPiAkbmFtZSQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VcbiIKKyAgICAgICAgICAiICAgICAgICAubmV3TWVzc2FnZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbihcbiIKKyAgICAgICAgICAiICAgICAgJHNjb3BlJC5nZXREZWZhdWx0SW5zdGFuY2UoKSxcbiIKKyAgICAgICAgICAiICAgICAgJGluZGV4JCxcbiIKKyAgICAgICAgICAiICAgICAgJHNpbmd1bGFyX3R5cGUkLmNsYXNzLFxuIgorICAgICAgICAgICIgICAgICAkcHJvdG90eXBlJCk7XG4iKTsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgLy8gTGl0ZSBleHRlbnNpb25zCisgICAgaWYgKGRlc2NyaXB0b3JfLT5pc19yZXBlYXRlZCgpKSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICB2YXJzLAorICAgICAgICAgICJwdWJsaWMgc3RhdGljIGZpbmFsXG4iCisgICAgICAgICAgIiAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlTGl0ZS5HZW5lcmF0ZWRFeHRlbnNpb248XG4iCisgICAgICAgICAgIiAgICAkY29udGFpbmluZ190eXBlJCxcbiIKKyAgICAgICAgICAiICAgICR0eXBlJD4gJG5hbWUkID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlTGl0ZVxuIgorICAgICAgICAgICIgICAgICAgIC5uZXdSZXBlYXRlZEdlbmVyYXRlZEV4dGVuc2lvbihcbiIKKyAgICAgICAgICAiICAgICAgJGNvbnRhaW5pbmdfdHlwZSQuZ2V0RGVmYXVsdEluc3RhbmNlKCksXG4iCisgICAgICAgICAgIiAgICAgICRwcm90b3R5cGUkLFxuIgorICAgICAgICAgICIgICAgICAkZW51bV9tYXAkLFxuIgorICAgICAgICAgICIgICAgICAkbnVtYmVyJCxcbiIKKyAgICAgICAgICAiICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS4kdHlwZV9jb25zdGFudCQsXG4iCisgICAgICAgICAgIiAgICAgICRwYWNrZWQkLFxuIgorICAgICAgICAgICIgICAgICAkc2luZ3VsYXJfdHlwZSQuY2xhc3MpO1xuIik7CisgICAgfSBlbHNlIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgIHZhcnMsCisgICAgICAgICAgInB1YmxpYyBzdGF0aWMgZmluYWxcbiIKKyAgICAgICAgICAiICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VMaXRlLkdlbmVyYXRlZEV4dGVuc2lvbjxcbiIKKyAgICAgICAgICAiICAgICRjb250YWluaW5nX3R5cGUkLFxuIgorICAgICAgICAgICIgICAgJHR5cGUkPiAkbmFtZSQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VMaXRlXG4iCisgICAgICAgICAgIiAgICAgICAgLm5ld1Npbmd1bGFyR2VuZXJhdGVkRXh0ZW5zaW9uKFxuIgorICAgICAgICAgICIgICAgICAkY29udGFpbmluZ190eXBlJC5nZXREZWZhdWx0SW5zdGFuY2UoKSxcbiIKKyAgICAgICAgICAiICAgICAgJGRlZmF1bHQkLFxuIgorICAgICAgICAgICIgICAgICAkcHJvdG90eXBlJCxcbiIKKyAgICAgICAgICAiICAgICAgJGVudW1fbWFwJCxcbiIKKyAgICAgICAgICAiICAgICAgJG51bWJlciQsXG4iCisgICAgICAgICAgIiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuJHR5cGVfY29uc3RhbnQkLFxuIgorICAgICAgICAgICIgICAgICAkc2luZ3VsYXJfdHlwZSQuY2xhc3MpO1xuIik7CisgICAgfQorICB9Cit9CisKK2ludCBJbW11dGFibGVFeHRlbnNpb25HZW5lcmF0b3I6OkdlbmVyYXRlTm9uTmVzdGVkSW5pdGlhbGl6YXRpb25Db2RlKAorICAgIGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIGludCBieXRlY29kZV9lc3RpbWF0ZSA9IDA7CisgIGlmIChkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX3Njb3BlKCkgPT0gTlVMTCAmJgorICAgICAgSGFzRGVzY3JpcHRvck1ldGhvZHMoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICAvLyBPbmx5IGFwcGxpZXMgdG8gbm9uLW5lc3RlZCwgbm9uLWxpdGUgZXh0ZW5zaW9ucy4KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIiRuYW1lJC5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KCRpbmRleCQpKTtcbiIsCisgICAgICAgICJuYW1lIiwgVW5kZXJzY29yZXNUb0NhbWVsQ2FzZShkZXNjcmlwdG9yXyksCisgICAgICAgICJpbmRleCIsIFNpbXBsZUl0b2EoZGVzY3JpcHRvcl8tPmluZGV4KCkpKTsKKyAgICBieXRlY29kZV9lc3RpbWF0ZSArPSAyMTsKKyAgfQorICByZXR1cm4gYnl0ZWNvZGVfZXN0aW1hdGU7Cit9CisKK2ludCBJbW11dGFibGVFeHRlbnNpb25HZW5lcmF0b3I6OkdlbmVyYXRlUmVnaXN0cmF0aW9uQ29kZSgKKyAgICBpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICAicmVnaXN0cnkuYWRkKCRzY29wZSQuJG5hbWUkKTtcbiIsCisgICAgInNjb3BlIiwgc2NvcGVfLAorICAgICJuYW1lIiwgVW5kZXJzY29yZXNUb0NhbWVsQ2FzZShkZXNjcmlwdG9yXykpOworICByZXR1cm4gNzsKK30KKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9leHRlbnNpb24uaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2V4dGVuc2lvbi5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJkZDQyMjYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9leHRlbnNpb24uaApAQCAtMCwwICsxLDExMyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX0VYVEVOU0lPTl9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfRVhURU5TSU9OX0hfXworCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHN0cmluZz4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworICBjbGFzcyBGaWVsZERlc2NyaXB0b3I7ICAgICAgIC8vIGRlc2NyaXB0b3IuaAorICBuYW1lc3BhY2UgY29tcGlsZXIgeworICAgIG5hbWVzcGFjZSBqYXZhIHsKKyAgICAgIGNsYXNzIENvbnRleHQ7ICAgICAgICAgICAvLyBjb250ZXh0LmgKKyAgICAgIGNsYXNzIENsYXNzTmFtZVJlc29sdmVyOyAvLyBuYW1lX3Jlc29sdmVyLmgKKyAgICB9CisgIH0KKyAgbmFtZXNwYWNlIGlvIHsKKyAgICBjbGFzcyBQcmludGVyOyAgICAgICAgICAgICAvLyBwcmludGVyLmgKKyAgfQorfQorCituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhIHsKKworLy8gR2VuZXJhdGVzIGNvZGUgZm9yIGFuIGV4dGVuc2lvbiwgd2hpY2ggbWF5IGJlIHdpdGhpbiB0aGUgc2NvcGUgb2Ygc29tZQorLy8gbWVzc2FnZSBvciBtYXkgYmUgYXQgZmlsZSBzY29wZS4gIFRoaXMgaXMgbXVjaCBzaW1wbGVyIHRoYW4gRmllbGRHZW5lcmF0b3IKKy8vIHNpbmNlIGV4dGVuc2lvbnMgYXJlIGp1c3Qgc2ltcGxlIGlkZW50aWZpZXJzIHdpdGggaW50ZXJlc3RpbmcgdHlwZXMuCitjbGFzcyBFeHRlbnNpb25HZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgRXh0ZW5zaW9uR2VuZXJhdG9yKCkge30KKyAgdmlydHVhbCB+RXh0ZW5zaW9uR2VuZXJhdG9yKCkge30KKworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGUoaW86OlByaW50ZXIqIHByaW50ZXIpID0gMDsKKworICAvLyBSZXR1cm5zIGFuIGVzdGltYXRlIG9mIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhlIHByaW50ZWQgY29kZSB3aWxsIGNvbXBpbGUgdG8KKyAgdmlydHVhbCBpbnQgR2VuZXJhdGVOb25OZXN0ZWRJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpID0gMDsKKworICAvLyBSZXR1cm5zIGFuIGVzdGltYXRlIG9mIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhlIHByaW50ZWQgY29kZSB3aWxsIGNvbXBpbGUgdG8KKyAgdmlydHVhbCBpbnQgR2VuZXJhdGVSZWdpc3RyYXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSA9IDA7CisKKyBwcm90ZWN0ZWQ6CisgIHN0YXRpYyB2b2lkIEluaXRUZW1wbGF0ZVZhcnMoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgc2NvcGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpbW11dGFibGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3NOYW1lUmVzb2x2ZXIqIG5hbWVfcmVzb2x2ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwPHN0cmluZywgc3RyaW5nPiogdmFyc19wb2ludGVyKTsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhFeHRlbnNpb25HZW5lcmF0b3IpOworfTsKKworY2xhc3MgSW1tdXRhYmxlRXh0ZW5zaW9uR2VuZXJhdG9yIDogcHVibGljIEV4dGVuc2lvbkdlbmVyYXRvciB7CisgcHVibGljOgorICBleHBsaWNpdCBJbW11dGFibGVFeHRlbnNpb25HZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29udGV4dCogY29udGV4dCk7CisgIHZpcnR1YWwgfkltbXV0YWJsZUV4dGVuc2lvbkdlbmVyYXRvcigpOworCisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZpcnR1YWwgaW50IEdlbmVyYXRlTm9uTmVzdGVkSW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdmlydHVhbCBpbnQgR2VuZXJhdGVSZWdpc3RyYXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworIHByb3RlY3RlZDoKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgQ29udGV4dCogY29udGV4dF87CisgIENsYXNzTmFtZVJlc29sdmVyKiBuYW1lX3Jlc29sdmVyXzsKKyAgc3RyaW5nIHNjb3BlXzsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhJbW11dGFibGVFeHRlbnNpb25HZW5lcmF0b3IpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfRVhURU5TSU9OX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZXh0ZW5zaW9uX2xpdGUuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9leHRlbnNpb25fbGl0ZS5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNjlkZTI5Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZXh0ZW5zaW9uX2xpdGUuY2MKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2V4dGVuc2lvbl9saXRlLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9leHRlbnNpb25fbGl0ZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU2OWRlMjkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9leHRlbnNpb25fbGl0ZS5oCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9maWVsZC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2ZpZWxkLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM1NDM0NzYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9maWVsZC5jYwpAQCAtMCwwICsxLDMzMiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9maWVsZC5oPgorCisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2xvZ2dpbmcuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9jb250ZXh0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9lbnVtX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9lbnVtX2ZpZWxkX2xpdGUuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2xhenlfbWVzc2FnZV9maWVsZC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbGF6eV9tZXNzYWdlX2ZpZWxkX2xpdGUuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21hcF9maWVsZC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbWFwX2ZpZWxkX2xpdGUuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21lc3NhZ2VfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21lc3NhZ2VfZmllbGRfbGl0ZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfcHJpbWl0aXZlX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9wcmltaXRpdmVfZmllbGRfbGl0ZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfc3RyaW5nX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9zdHJpbmdfZmllbGRfbGl0ZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3Vic3RpdHV0ZS5oPgorCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YSB7CisKK25hbWVzcGFjZSB7CisKK0ltbXV0YWJsZUZpZWxkR2VuZXJhdG9yKiBNYWtlSW1tdXRhYmxlR2VuZXJhdG9yKAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGludCBtZXNzYWdlQml0SW5kZXgsIGludCBidWlsZGVyQml0SW5kZXgsCisgICAgQ29udGV4dCogY29udGV4dCkgeworICBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkpIHsKKyAgICBzd2l0Y2ggKEdldEphdmFUeXBlKGZpZWxkKSkgeworICAgICAgY2FzZSBKQVZBVFlQRV9NRVNTQUdFOgorICAgICAgICBpZiAoSXNNYXBFbnRyeShmaWVsZC0+bWVzc2FnZV90eXBlKCkpKSB7CisgICAgICAgICAgcmV0dXJuIG5ldyBJbW11dGFibGVNYXBGaWVsZEdlbmVyYXRvcigKKyAgICAgICAgICAgICAgZmllbGQsIG1lc3NhZ2VCaXRJbmRleCwgYnVpbGRlckJpdEluZGV4LCBjb250ZXh0KTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBpZiAoSXNMYXp5KGZpZWxkKSkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBSZXBlYXRlZEltbXV0YWJsZUxhenlNZXNzYWdlRmllbGRHZW5lcmF0b3IoCisgICAgICAgICAgICAgICAgZmllbGQsIG1lc3NhZ2VCaXRJbmRleCwgYnVpbGRlckJpdEluZGV4LCBjb250ZXh0KTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBSZXBlYXRlZEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcigKKyAgICAgICAgICAgICAgICBmaWVsZCwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsIGNvbnRleHQpOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgY2FzZSBKQVZBVFlQRV9FTlVNOgorICAgICAgICByZXR1cm4gbmV3IFJlcGVhdGVkSW1tdXRhYmxlRW51bUZpZWxkR2VuZXJhdG9yKAorICAgICAgICAgICAgZmllbGQsIG1lc3NhZ2VCaXRJbmRleCwgYnVpbGRlckJpdEluZGV4LCBjb250ZXh0KTsKKyAgICAgIGNhc2UgSkFWQVRZUEVfU1RSSU5HOgorICAgICAgICByZXR1cm4gbmV3IFJlcGVhdGVkSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3IoCisgICAgICAgICAgICBmaWVsZCwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsIGNvbnRleHQpOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgcmV0dXJuIG5ldyBSZXBlYXRlZEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKAorICAgICAgICAgICAgZmllbGQsIG1lc3NhZ2VCaXRJbmRleCwgYnVpbGRlckJpdEluZGV4LCBjb250ZXh0KTsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgaWYgKGZpZWxkLT5jb250YWluaW5nX29uZW9mKCkpIHsKKyAgICAgIHN3aXRjaCAoR2V0SmF2YVR5cGUoZmllbGQpKSB7CisgICAgICAgIGNhc2UgSkFWQVRZUEVfTUVTU0FHRToKKyAgICAgICAgICBpZiAoSXNMYXp5KGZpZWxkKSkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBJbW11dGFibGVMYXp5TWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3IoCisgICAgICAgICAgICAgICAgZmllbGQsIG1lc3NhZ2VCaXRJbmRleCwgYnVpbGRlckJpdEluZGV4LCBjb250ZXh0KTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBJbW11dGFibGVNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcigKKyAgICAgICAgICAgICAgICBmaWVsZCwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsIGNvbnRleHQpOworICAgICAgICAgIH0KKyAgICAgICAgY2FzZSBKQVZBVFlQRV9FTlVNOgorICAgICAgICAgIHJldHVybiBuZXcgSW1tdXRhYmxlRW51bU9uZW9mRmllbGRHZW5lcmF0b3IoCisgICAgICAgICAgICAgIGZpZWxkLCBtZXNzYWdlQml0SW5kZXgsIGJ1aWxkZXJCaXRJbmRleCwgY29udGV4dCk7CisgICAgICAgIGNhc2UgSkFWQVRZUEVfU1RSSU5HOgorICAgICAgICAgIHJldHVybiBuZXcgSW1tdXRhYmxlU3RyaW5nT25lb2ZGaWVsZEdlbmVyYXRvcigKKyAgICAgICAgICAgICAgZmllbGQsIG1lc3NhZ2VCaXRJbmRleCwgYnVpbGRlckJpdEluZGV4LCBjb250ZXh0KTsKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICByZXR1cm4gbmV3IEltbXV0YWJsZVByaW1pdGl2ZU9uZW9mRmllbGRHZW5lcmF0b3IoCisgICAgICAgICAgICAgIGZpZWxkLCBtZXNzYWdlQml0SW5kZXgsIGJ1aWxkZXJCaXRJbmRleCwgY29udGV4dCk7CisgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgIHN3aXRjaCAoR2V0SmF2YVR5cGUoZmllbGQpKSB7CisgICAgICAgIGNhc2UgSkFWQVRZUEVfTUVTU0FHRToKKyAgICAgICAgICBpZiAoSXNMYXp5KGZpZWxkKSkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBJbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkR2VuZXJhdG9yKAorICAgICAgICAgICAgICAgIGZpZWxkLCBtZXNzYWdlQml0SW5kZXgsIGJ1aWxkZXJCaXRJbmRleCwgY29udGV4dCk7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgSW1tdXRhYmxlTWVzc2FnZUZpZWxkR2VuZXJhdG9yKAorICAgICAgICAgICAgICAgIGZpZWxkLCBtZXNzYWdlQml0SW5kZXgsIGJ1aWxkZXJCaXRJbmRleCwgY29udGV4dCk7CisgICAgICAgICAgfQorICAgICAgICBjYXNlIEpBVkFUWVBFX0VOVU06CisgICAgICAgICAgcmV0dXJuIG5ldyBJbW11dGFibGVFbnVtRmllbGRHZW5lcmF0b3IoCisgICAgICAgICAgICAgIGZpZWxkLCBtZXNzYWdlQml0SW5kZXgsIGJ1aWxkZXJCaXRJbmRleCwgY29udGV4dCk7CisgICAgICAgIGNhc2UgSkFWQVRZUEVfU1RSSU5HOgorICAgICAgICAgIHJldHVybiBuZXcgSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3IoCisgICAgICAgICAgICAgIGZpZWxkLCBtZXNzYWdlQml0SW5kZXgsIGJ1aWxkZXJCaXRJbmRleCwgY29udGV4dCk7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgcmV0dXJuIG5ldyBJbW11dGFibGVQcmltaXRpdmVGaWVsZEdlbmVyYXRvcigKKyAgICAgICAgICAgICAgZmllbGQsIG1lc3NhZ2VCaXRJbmRleCwgYnVpbGRlckJpdEluZGV4LCBjb250ZXh0KTsKKyAgICAgIH0KKyAgICB9CisgIH0KK30KKworSW1tdXRhYmxlRmllbGRMaXRlR2VuZXJhdG9yKiBNYWtlSW1tdXRhYmxlTGl0ZUdlbmVyYXRvcigKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBpbnQgbWVzc2FnZUJpdEluZGV4LCBpbnQgYnVpbGRlckJpdEluZGV4LAorICAgIENvbnRleHQqIGNvbnRleHQpIHsKKyAgaWYgKGZpZWxkLT5pc19yZXBlYXRlZCgpKSB7CisgICAgc3dpdGNoIChHZXRKYXZhVHlwZShmaWVsZCkpIHsKKyAgICAgIGNhc2UgSkFWQVRZUEVfTUVTU0FHRToKKyAgICAgICAgaWYgKElzTWFwRW50cnkoZmllbGQtPm1lc3NhZ2VfdHlwZSgpKSkgeworICAgICAgICAgIHJldHVybiBuZXcgSW1tdXRhYmxlTWFwRmllbGRMaXRlR2VuZXJhdG9yKAorICAgICAgICAgICAgICBmaWVsZCwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsIGNvbnRleHQpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGlmIChJc0xhenkoZmllbGQpKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IFJlcGVhdGVkSW1tdXRhYmxlTGF6eU1lc3NhZ2VGaWVsZExpdGVHZW5lcmF0b3IoCisgICAgICAgICAgICAgICAgZmllbGQsIG1lc3NhZ2VCaXRJbmRleCwgYnVpbGRlckJpdEluZGV4LCBjb250ZXh0KTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBSZXBlYXRlZEltbXV0YWJsZU1lc3NhZ2VGaWVsZExpdGVHZW5lcmF0b3IoCisgICAgICAgICAgICAgICAgZmllbGQsIG1lc3NhZ2VCaXRJbmRleCwgYnVpbGRlckJpdEluZGV4LCBjb250ZXh0KTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIGNhc2UgSkFWQVRZUEVfRU5VTToKKyAgICAgICAgcmV0dXJuIG5ldyBSZXBlYXRlZEltbXV0YWJsZUVudW1GaWVsZExpdGVHZW5lcmF0b3IoCisgICAgICAgICAgICBmaWVsZCwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsIGNvbnRleHQpOworICAgICAgY2FzZSBKQVZBVFlQRV9TVFJJTkc6CisgICAgICAgIHJldHVybiBuZXcgUmVwZWF0ZWRJbW11dGFibGVTdHJpbmdGaWVsZExpdGVHZW5lcmF0b3IoCisgICAgICAgICAgICBmaWVsZCwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsIGNvbnRleHQpOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgcmV0dXJuIG5ldyBSZXBlYXRlZEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkTGl0ZUdlbmVyYXRvcigKKyAgICAgICAgICAgIGZpZWxkLCBtZXNzYWdlQml0SW5kZXgsIGJ1aWxkZXJCaXRJbmRleCwgY29udGV4dCk7CisgICAgfQorICB9IGVsc2UgeworICAgIGlmIChmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpKSB7CisgICAgICBzd2l0Y2ggKEdldEphdmFUeXBlKGZpZWxkKSkgeworICAgICAgICBjYXNlIEpBVkFUWVBFX01FU1NBR0U6CisgICAgICAgICAgaWYgKElzTGF6eShmaWVsZCkpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgSW1tdXRhYmxlTGF6eU1lc3NhZ2VPbmVvZkZpZWxkTGl0ZUdlbmVyYXRvcigKKyAgICAgICAgICAgICAgICBmaWVsZCwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsIGNvbnRleHQpOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IEltbXV0YWJsZU1lc3NhZ2VPbmVvZkZpZWxkTGl0ZUdlbmVyYXRvcigKKyAgICAgICAgICAgICAgICBmaWVsZCwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsIGNvbnRleHQpOworICAgICAgICAgIH0KKyAgICAgICAgY2FzZSBKQVZBVFlQRV9FTlVNOgorICAgICAgICAgIHJldHVybiBuZXcgSW1tdXRhYmxlRW51bU9uZW9mRmllbGRMaXRlR2VuZXJhdG9yKAorICAgICAgICAgICAgICBmaWVsZCwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsIGNvbnRleHQpOworICAgICAgICBjYXNlIEpBVkFUWVBFX1NUUklORzoKKyAgICAgICAgICByZXR1cm4gbmV3IEltbXV0YWJsZVN0cmluZ09uZW9mRmllbGRMaXRlR2VuZXJhdG9yKAorICAgICAgICAgICAgICBmaWVsZCwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsIGNvbnRleHQpOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgIHJldHVybiBuZXcgSW1tdXRhYmxlUHJpbWl0aXZlT25lb2ZGaWVsZExpdGVHZW5lcmF0b3IoCisgICAgICAgICAgICAgIGZpZWxkLCBtZXNzYWdlQml0SW5kZXgsIGJ1aWxkZXJCaXRJbmRleCwgY29udGV4dCk7CisgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgIHN3aXRjaCAoR2V0SmF2YVR5cGUoZmllbGQpKSB7CisgICAgICAgIGNhc2UgSkFWQVRZUEVfTUVTU0FHRToKKyAgICAgICAgICBpZiAoSXNMYXp5KGZpZWxkKSkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBJbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkTGl0ZUdlbmVyYXRvcigKKyAgICAgICAgICAgICAgICBmaWVsZCwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsIGNvbnRleHQpOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IEltbXV0YWJsZU1lc3NhZ2VGaWVsZExpdGVHZW5lcmF0b3IoCisgICAgICAgICAgICAgICAgZmllbGQsIG1lc3NhZ2VCaXRJbmRleCwgYnVpbGRlckJpdEluZGV4LCBjb250ZXh0KTsKKyAgICAgICAgICB9CisgICAgICAgIGNhc2UgSkFWQVRZUEVfRU5VTToKKyAgICAgICAgICByZXR1cm4gbmV3IEltbXV0YWJsZUVudW1GaWVsZExpdGVHZW5lcmF0b3IoCisgICAgICAgICAgICAgIGZpZWxkLCBtZXNzYWdlQml0SW5kZXgsIGJ1aWxkZXJCaXRJbmRleCwgY29udGV4dCk7CisgICAgICAgIGNhc2UgSkFWQVRZUEVfU1RSSU5HOgorICAgICAgICAgIHJldHVybiBuZXcgSW1tdXRhYmxlU3RyaW5nRmllbGRMaXRlR2VuZXJhdG9yKAorICAgICAgICAgICAgICBmaWVsZCwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsIGNvbnRleHQpOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgIHJldHVybiBuZXcgSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRMaXRlR2VuZXJhdG9yKAorICAgICAgICAgICAgICBmaWVsZCwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsIGNvbnRleHQpOworICAgICAgfQorICAgIH0KKyAgfQorfQorCisKK3N0YXRpYyBpbmxpbmUgdm9pZCBSZXBvcnRVbmV4cGVjdGVkUGFja2VkRmllbGRzQ2FsbChpbzo6UHJpbnRlciogcHJpbnRlcikgeworICAvLyBSZWFjaGluZyBoZXJlIGluZGljYXRlcyBhIGJ1Zy4gQ2FzZXMgYXJlOgorICAvLyAgIC0gVGhpcyBGaWVsZEdlbmVyYXRvciBzaG91bGQgc3VwcG9ydCBwYWNraW5nLAorICAvLyAgICAgYnV0IHRoaXMgbWV0aG9kIHNob3VsZCBiZSBvdmVycmlkZGVuLgorICAvLyAgIC0gVGhpcyBGaWVsZEdlbmVyYXRvciBkb2Vzbid0IHN1cHBvcnQgcGFja2luZywgYW5kIHRoaXMgbWV0aG9kCisgIC8vICAgICBzaG91bGQgbmV2ZXIgaGF2ZSBiZWVuIGNhbGxlZC4KKyAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkdlbmVyYXRlUGFyc2luZ0NvZGVGcm9tUGFja2VkKCkgIgorICAgICAgICAgICAgIDw8ICJjYWxsZWQgb24gZmllbGQgZ2VuZXJhdG9yIHRoYXQgZG9lcyBub3Qgc3VwcG9ydCBwYWNraW5nLiI7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCitJbW11dGFibGVGaWVsZEdlbmVyYXRvcjo6fkltbXV0YWJsZUZpZWxkR2VuZXJhdG9yKCkge30KKwordm9pZCBJbW11dGFibGVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVBhcnNpbmdDb2RlRnJvbVBhY2tlZChpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBSZXBvcnRVbmV4cGVjdGVkUGFja2VkRmllbGRzQ2FsbChwcmludGVyKTsKK30KKworSW1tdXRhYmxlRmllbGRMaXRlR2VuZXJhdG9yOjp+SW1tdXRhYmxlRmllbGRMaXRlR2VuZXJhdG9yKCkge30KKwordm9pZCBJbW11dGFibGVGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVQYXJzaW5nQ29kZUZyb21QYWNrZWQoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgUmVwb3J0VW5leHBlY3RlZFBhY2tlZEZpZWxkc0NhbGwocHJpbnRlcik7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKwordGVtcGxhdGUgPD4KK0ZpZWxkR2VuZXJhdG9yTWFwPEltbXV0YWJsZUZpZWxkR2VuZXJhdG9yPjo6RmllbGRHZW5lcmF0b3JNYXAoCisgICAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwgQ29udGV4dCogY29udGV4dCkKKyAgICA6IGRlc2NyaXB0b3JfKGRlc2NyaXB0b3IpLAorICAgICAgZmllbGRfZ2VuZXJhdG9yc18obmV3IGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8CisgICAgICAgICAgSW1tdXRhYmxlRmllbGRHZW5lcmF0b3I+W2Rlc2NyaXB0b3ItPmZpZWxkX2NvdW50KCldKSB7CisKKyAgLy8gQ29uc3RydWN0IGFsbCB0aGUgRmllbGRHZW5lcmF0b3JzIGFuZCBhc3NpZ24gdGhlbSBiaXQgaW5kaWNlcyBmb3IgdGhlaXIKKyAgLy8gYml0IGZpZWxkcy4KKyAgaW50IG1lc3NhZ2VCaXRJbmRleCA9IDA7CisgIGludCBidWlsZGVyQml0SW5kZXggPSAwOworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3ItPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIEltbXV0YWJsZUZpZWxkR2VuZXJhdG9yKiBnZW5lcmF0b3IgPSBNYWtlSW1tdXRhYmxlR2VuZXJhdG9yKAorICAgICAgICBkZXNjcmlwdG9yLT5maWVsZChpKSwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsIGNvbnRleHQpOworICAgIGZpZWxkX2dlbmVyYXRvcnNfW2ldLnJlc2V0KGdlbmVyYXRvcik7CisgICAgbWVzc2FnZUJpdEluZGV4ICs9IGdlbmVyYXRvci0+R2V0TnVtQml0c0Zvck1lc3NhZ2UoKTsKKyAgICBidWlsZGVyQml0SW5kZXggKz0gZ2VuZXJhdG9yLT5HZXROdW1CaXRzRm9yQnVpbGRlcigpOworICB9Cit9CisKK3RlbXBsYXRlPD4KK0ZpZWxkR2VuZXJhdG9yTWFwPEltbXV0YWJsZUZpZWxkR2VuZXJhdG9yPjo6fkZpZWxkR2VuZXJhdG9yTWFwKCkge30KKwordGVtcGxhdGUgPD4KK0ZpZWxkR2VuZXJhdG9yTWFwPEltbXV0YWJsZUZpZWxkTGl0ZUdlbmVyYXRvcj46OkZpZWxkR2VuZXJhdG9yTWFwKAorICAgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIENvbnRleHQqIGNvbnRleHQpCisgICAgOiBkZXNjcmlwdG9yXyhkZXNjcmlwdG9yKSwKKyAgICAgIGZpZWxkX2dlbmVyYXRvcnNfKG5ldyBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPAorICAgICAgICAgIEltbXV0YWJsZUZpZWxkTGl0ZUdlbmVyYXRvcj5bZGVzY3JpcHRvci0+ZmllbGRfY291bnQoKV0pIHsKKyAgLy8gQ29uc3RydWN0IGFsbCB0aGUgRmllbGRHZW5lcmF0b3JzIGFuZCBhc3NpZ24gdGhlbSBiaXQgaW5kaWNlcyBmb3IgdGhlaXIKKyAgLy8gYml0IGZpZWxkcy4KKyAgaW50IG1lc3NhZ2VCaXRJbmRleCA9IDA7CisgIGludCBidWlsZGVyQml0SW5kZXggPSAwOworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3ItPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIEltbXV0YWJsZUZpZWxkTGl0ZUdlbmVyYXRvciogZ2VuZXJhdG9yID0gTWFrZUltbXV0YWJsZUxpdGVHZW5lcmF0b3IoCisgICAgICAgIGRlc2NyaXB0b3ItPmZpZWxkKGkpLCBtZXNzYWdlQml0SW5kZXgsIGJ1aWxkZXJCaXRJbmRleCwgY29udGV4dCk7CisgICAgZmllbGRfZ2VuZXJhdG9yc19baV0ucmVzZXQoZ2VuZXJhdG9yKTsKKyAgICBtZXNzYWdlQml0SW5kZXggKz0gZ2VuZXJhdG9yLT5HZXROdW1CaXRzRm9yTWVzc2FnZSgpOworICAgIGJ1aWxkZXJCaXRJbmRleCArPSBnZW5lcmF0b3ItPkdldE51bUJpdHNGb3JCdWlsZGVyKCk7CisgIH0KK30KKwordGVtcGxhdGU8PgorRmllbGRHZW5lcmF0b3JNYXA8SW1tdXRhYmxlRmllbGRMaXRlR2VuZXJhdG9yPjo6fkZpZWxkR2VuZXJhdG9yTWFwKCkge30KKworCit2b2lkIFNldENvbW1vbkZpZWxkVmFyaWFibGVzKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGRHZW5lcmF0b3JJbmZvKiBpbmZvLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXA8c3RyaW5nLCBzdHJpbmc+KiB2YXJpYWJsZXMpIHsKKyAgKCp2YXJpYWJsZXMpWyJmaWVsZF9uYW1lIl0gPSBkZXNjcmlwdG9yLT5uYW1lKCk7CisgICgqdmFyaWFibGVzKVsibmFtZSJdID0gaW5mby0+bmFtZTsKKyAgKCp2YXJpYWJsZXMpWyJjYXBpdGFsaXplZF9uYW1lIl0gPSBpbmZvLT5jYXBpdGFsaXplZF9uYW1lOworICAoKnZhcmlhYmxlcylbImRpc2FtYmlndWF0ZWRfcmVhc29uIl0gPSBpbmZvLT5kaXNhbWJpZ3VhdGVkX3JlYXNvbjsKKyAgKCp2YXJpYWJsZXMpWyJjb25zdGFudF9uYW1lIl0gPSBGaWVsZENvbnN0YW50TmFtZShkZXNjcmlwdG9yKTsKKyAgKCp2YXJpYWJsZXMpWyJudW1iZXIiXSA9IFNpbXBsZUl0b2EoZGVzY3JpcHRvci0+bnVtYmVyKCkpOworfQorCit2b2lkIFNldENvbW1vbk9uZW9mVmFyaWFibGVzKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT25lb2ZHZW5lcmF0b3JJbmZvKiBpbmZvLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXA8c3RyaW5nLCBzdHJpbmc+KiB2YXJpYWJsZXMpIHsKKyAgKCp2YXJpYWJsZXMpWyJvbmVvZl9uYW1lIl0gPSBpbmZvLT5uYW1lOworICAoKnZhcmlhYmxlcylbIm9uZW9mX2NhcGl0YWxpemVkX25hbWUiXSA9IGluZm8tPmNhcGl0YWxpemVkX25hbWU7CisgICgqdmFyaWFibGVzKVsib25lb2ZfaW5kZXgiXSA9CisgICAgICBTaW1wbGVJdG9hKGRlc2NyaXB0b3ItPmNvbnRhaW5pbmdfb25lb2YoKS0+aW5kZXgoKSk7CisgICgqdmFyaWFibGVzKVsic2V0X29uZW9mX2Nhc2VfbWVzc2FnZSJdID0gaW5mby0+bmFtZSArCisgICAgICAiQ2FzZV8gPSAiICsgU2ltcGxlSXRvYShkZXNjcmlwdG9yLT5udW1iZXIoKSk7CisgICgqdmFyaWFibGVzKVsiY2xlYXJfb25lb2ZfY2FzZV9tZXNzYWdlIl0gPSBpbmZvLT5uYW1lICsKKyAgICAgICJDYXNlXyA9IDAiOworICAoKnZhcmlhYmxlcylbImhhc19vbmVvZl9jYXNlX21lc3NhZ2UiXSA9IGluZm8tPm5hbWUgKworICAgICAgIkNhc2VfID09ICIgKyBTaW1wbGVJdG9hKGRlc2NyaXB0b3ItPm51bWJlcigpKTsKK30KKwordm9pZCBQcmludEV4dHJhRmllbGRJbmZvKGNvbnN0IG1hcDxzdHJpbmcsIHN0cmluZz4mIHZhcmlhYmxlcywKKyAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBjb25zdCBtYXA8c3RyaW5nLCBzdHJpbmc+Ojpjb25zdF9pdGVyYXRvciBpdCA9CisgICAgICB2YXJpYWJsZXMuZmluZCgiZGlzYW1iaWd1YXRlZF9yZWFzb24iKTsKKyAgaWYgKGl0ICE9IHZhcmlhYmxlcy5lbmQoKSAmJiAhaXQtPnNlY29uZC5lbXB0eSgpKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgIHZhcmlhYmxlcywKKyAgICAgICAgIi8vIEFuIGFsdGVybmF0aXZlIG5hbWUgaXMgdXNlZCBmb3IgZmllbGQgXCIkZmllbGRfbmFtZSRcIiBiZWNhdXNlOlxuIgorICAgICAgICAiLy8gICAgICRkaXNhbWJpZ3VhdGVkX3JlYXNvbiRcbiIpOworICB9Cit9CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZmllbGQuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2ZpZWxkLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGUyNGRhMgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2ZpZWxkLmgKQEAgLTAsMCArMSwxOTcgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9GSUVMRF9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfRklFTERfSF9fCisKKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorI2luY2x1ZGUgPHN0cmluZz4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9sb2dnaW5nLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKyAgbmFtZXNwYWNlIGNvbXBpbGVyIHsKKyAgICBuYW1lc3BhY2UgamF2YSB7CisgICAgICBjbGFzcyBDb250ZXh0OyAgICAgICAgICAgICAgICAvLyBjb250ZXh0LmgKKyAgICAgIGNsYXNzIENsYXNzTmFtZVJlc29sdmVyOyAgICAgIC8vIG5hbWVfcmVzb2x2ZXIuaAorICAgIH0KKyAgfQorICBuYW1lc3BhY2UgaW8geworICAgIGNsYXNzIFByaW50ZXI7ICAgICAgICAgICAgICAgICAgLy8gcHJpbnRlci5oCisgIH0KK30KKworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YSB7CisKK2NsYXNzIEltbXV0YWJsZUZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIEltbXV0YWJsZUZpZWxkR2VuZXJhdG9yKCkge30KKyAgdmlydHVhbCB+SW1tdXRhYmxlRmllbGRHZW5lcmF0b3IoKTsKKworICB2aXJ0dWFsIGludCBHZXROdW1CaXRzRm9yTWVzc2FnZSgpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCBpbnQgR2V0TnVtQml0c0ZvckJ1aWxkZXIoKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZUludGVyZmFjZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgPSAwOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgPSAwOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlQnVpbGRlckNsZWFyQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgPSAwOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgPSAwOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVCdWlsZGluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlUGFyc2luZ0NvZGVGcm9tUGFja2VkKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlUGFyc2luZ0RvbmVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgPSAwOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVGaWVsZEJ1aWxkZXJJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpCisgICAgICBjb25zdCA9IDA7CisKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgPSAwOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVIYXNoQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgPSAwOworCisgIHZpcnR1YWwgc3RyaW5nIEdldEJveGVkVHlwZSgpIGNvbnN0ID0gMDsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhJbW11dGFibGVGaWVsZEdlbmVyYXRvcik7Cit9OworCitjbGFzcyBJbW11dGFibGVGaWVsZExpdGVHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgSW1tdXRhYmxlRmllbGRMaXRlR2VuZXJhdG9yKCkge30KKyAgdmlydHVhbCB+SW1tdXRhYmxlRmllbGRMaXRlR2VuZXJhdG9yKCk7CisKKyAgdmlydHVhbCBpbnQgR2V0TnVtQml0c0Zvck1lc3NhZ2UoKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgaW50IEdldE51bUJpdHNGb3JCdWlsZGVyKCkgY29uc3QgPSAwOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVJbnRlcmZhY2VNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlQnVpbGRlck1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlSW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZUR5bmFtaWNNZXRob2RNYWtlSW1tdXRhYmxlQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikKKyAgICAgIGNvbnN0ID0gMDsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlUGFyc2luZ0NvZGVGcm9tUGFja2VkKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlUGFyc2luZ0RvbmVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgPSAwOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVGaWVsZEJ1aWxkZXJJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpCisgICAgICBjb25zdCA9IDA7CisKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgPSAwOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVIYXNoQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgPSAwOworCisgIHZpcnR1YWwgc3RyaW5nIEdldEJveGVkVHlwZSgpIGNvbnN0ID0gMDsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhJbW11dGFibGVGaWVsZExpdGVHZW5lcmF0b3IpOworfTsKKworCisvLyBDb252ZW5pZW5jZSBjbGFzcyB3aGljaCBjb25zdHJ1Y3RzIEZpZWxkR2VuZXJhdG9ycyBmb3IgYSBEZXNjcmlwdG9yLgordGVtcGxhdGU8dHlwZW5hbWUgRmllbGRHZW5lcmF0b3JUeXBlPgorY2xhc3MgRmllbGRHZW5lcmF0b3JNYXAgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgRmllbGRHZW5lcmF0b3JNYXAoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29udGV4dCogY29udGV4dCk7CisgIH5GaWVsZEdlbmVyYXRvck1hcCgpOworCisgIGNvbnN0IEZpZWxkR2VuZXJhdG9yVHlwZSYgZ2V0KGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcl87CisgIENvbnRleHQqIGNvbnRleHRfOworICBDbGFzc05hbWVSZXNvbHZlciogbmFtZV9yZXNvbHZlcl87CisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9hcnJheTxnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPEZpZWxkR2VuZXJhdG9yVHlwZT4gPiBmaWVsZF9nZW5lcmF0b3JzXzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoRmllbGRHZW5lcmF0b3JNYXApOworfTsKKwordGVtcGxhdGU8dHlwZW5hbWUgRmllbGRHZW5lcmF0b3JUeXBlPgoraW5saW5lIGNvbnN0IEZpZWxkR2VuZXJhdG9yVHlwZSYKK0ZpZWxkR2VuZXJhdG9yTWFwPEZpZWxkR2VuZXJhdG9yVHlwZT46OmdldChjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7CisgIEdPT0dMRV9DSEVDS19FUShmaWVsZC0+Y29udGFpbmluZ190eXBlKCksIGRlc2NyaXB0b3JfKTsKKyAgcmV0dXJuICpmaWVsZF9nZW5lcmF0b3JzX1tmaWVsZC0+aW5kZXgoKV07Cit9CisKKy8vIEluc3RhbnRpYXRlIHRlbXBsYXRlIGZvciBtdXRhYmxlIGFuZCBpbW11dGFibGUgbWFwcy4KK3RlbXBsYXRlPD4KK0ZpZWxkR2VuZXJhdG9yTWFwPEltbXV0YWJsZUZpZWxkR2VuZXJhdG9yPjo6CitGaWVsZEdlbmVyYXRvck1hcChjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgQ29udGV4dCogY29udGV4dCk7CisKK3RlbXBsYXRlPD4KK0ZpZWxkR2VuZXJhdG9yTWFwPEltbXV0YWJsZUZpZWxkR2VuZXJhdG9yPjo6fkZpZWxkR2VuZXJhdG9yTWFwKCk7CisKKworLy8gRmllbGQgaW5mb3JtYXRpb24gdXNlZCBpbiBGaWVsZEdlbmVhcnRvcnMuCitzdHJ1Y3QgRmllbGRHZW5lcmF0b3JJbmZvIHsKKyAgc3RyaW5nIG5hbWU7CisgIHN0cmluZyBjYXBpdGFsaXplZF9uYW1lOworICBzdHJpbmcgZGlzYW1iaWd1YXRlZF9yZWFzb247Cit9OworCisvLyBPbmVvZiBpbmZvcm1hdGlvbiB1c2VkIGluIE9uZW9mRmllbGRHZW5lYXJ0b3JzLgorc3RydWN0IE9uZW9mR2VuZXJhdG9ySW5mbyB7CisgIHN0cmluZyBuYW1lOworICBzdHJpbmcgY2FwaXRhbGl6ZWRfbmFtZTsKK307CisKKy8vIFNldCBzb21lIGNvbW1vbiB2YXJpYWJsZXMgdXNlZCBpbiB2YXJpYWJsZSBGaWVsZEdlbmVyYXRvcnMuCit2b2lkIFNldENvbW1vbkZpZWxkVmFyaWFibGVzKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGRHZW5lcmF0b3JJbmZvKiBpbmZvLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXA8c3RyaW5nLCBzdHJpbmc+KiB2YXJpYWJsZXMpOworCisvLyBTZXQgc29tZSBjb21tb24gb25lb2YgdmFyaWFibGVzIHVzZWQgaW4gT25lb2ZGaWVsZEdlbmVyYXRvcnMuCit2b2lkIFNldENvbW1vbk9uZW9mVmFyaWFibGVzKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT25lb2ZHZW5lcmF0b3JJbmZvKiBpbmZvLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXA8c3RyaW5nLCBzdHJpbmc+KiB2YXJpYWJsZXMpOworCisvLyBQcmludCB1c2VmdWwgY29tbWVudHMgYmVmb3JlIGEgZmllbGQncyBhY2Nlc3NvcnMuCit2b2lkIFByaW50RXh0cmFGaWVsZEluZm8oY29uc3QgbWFwPHN0cmluZywgc3RyaW5nPiYgdmFyaWFibGVzLAorICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpQcmludGVyKiBwcmludGVyKTsKKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfRklFTERfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9maWxlLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZmlsZS5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jODE3MjMzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZmlsZS5jYwpAQCAtMCwwICsxLDYwNyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9maWxlLmg+CisKKyNpbmNsdWRlIDxtZW1vcnk+CisjaWZuZGVmIF9TSEFSRURfUFRSX0gKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc2hhcmVkX3B0ci5oPgorI2VuZGlmCisjaW5jbHVkZSA8c2V0PgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9jb250ZXh0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9lbnVtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9lbnVtX2xpdGUuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2V4dGVuc2lvbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZ2VuZXJhdG9yX2ZhY3RvcnkuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21lc3NhZ2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX25hbWVfcmVzb2x2ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX3NlcnZpY2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX3NoYXJlZF9jb2RlX2dlbmVyYXRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jb2RlX2dlbmVyYXRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9keW5hbWljX21lc3NhZ2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmEgeworCituYW1lc3BhY2UgeworCitzdHJ1Y3QgRmllbGREZXNjcmlwdG9yQ29tcGFyZSB7CisgIGJvb2wgb3BlcmF0b3IgKCkoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmMSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmMikgeworICAgIGlmKGYxID09IE5VTEwpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgaWYoZjIgPT0gTlVMTCkgeworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICAgIHJldHVybiBmMS0+ZnVsbF9uYW1lKCkgPCBmMi0+ZnVsbF9uYW1lKCk7CisgIH0KK307CisKK3R5cGVkZWYgc3RkOjpzZXQ8Y29uc3QgRmllbGREZXNjcmlwdG9yKiwgRmllbGREZXNjcmlwdG9yQ29tcGFyZT4gRmllbGREZXNjcmlwdG9yU2V0OworCisvLyBSZWN1cnNpdmVseSBzZWFyY2hlcyB0aGUgZ2l2ZW4gbWVzc2FnZSB0byBjb2xsZWN0IGV4dGVuc2lvbnMuCisvLyBSZXR1cm5zIHRydWUgaWYgYWxsIHRoZSBleHRlbnNpb25zIGNhbiBiZSByZWNvZ25pemVkLiBUaGUgZXh0ZW5zaW9ucyB3aWxsIGJlCisvLyBhcHBlbmRlZCBpbiB0byB0aGUgZXh0ZW5zaW9ucyBwYXJhbWV0ZXIuCisvLyBSZXR1cm5zIGZhbHNlIHdoZW4gdGhlcmUgYXJlIHVua25vd24gZmllbGRzLCBpbiB3aGljaCBjYXNlIHRoZSBkYXRhIGluIHRoZQorLy8gZXh0ZW5zaW9ucyBvdXRwdXQgcGFyYW1ldGVyIGlzIG5vdCByZWxpYWJsZSBhbmQgc2hvdWxkIGJlIGRpc2NhcmRlZC4KK2Jvb2wgQ29sbGVjdEV4dGVuc2lvbnMoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yU2V0KiBleHRlbnNpb25zKSB7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKTsKKworICAvLyBUaGVyZSBhcmUgdW5rbm93biBmaWVsZHMgdGhhdCBjb3VsZCBiZSBleHRlbnNpb25zLCB0aHVzIHRoaXMgY2FsbCBmYWlscy4KKyAgaWYgKHJlZmxlY3Rpb24tPkdldFVua25vd25GaWVsZHMobWVzc2FnZSkuZmllbGRfY291bnQoKSA+IDApIHJldHVybiBmYWxzZTsKKworICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4gZmllbGRzOworICByZWZsZWN0aW9uLT5MaXN0RmllbGRzKG1lc3NhZ2UsICZmaWVsZHMpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRzLnNpemUoKTsgaSsrKSB7CisgICAgaWYgKGZpZWxkc1tpXS0+aXNfZXh0ZW5zaW9uKCkpIGV4dGVuc2lvbnMtPmluc2VydChmaWVsZHNbaV0pOworCisgICAgaWYgKEdldEphdmFUeXBlKGZpZWxkc1tpXSkgPT0gSkFWQVRZUEVfTUVTU0FHRSkgeworICAgICAgaWYgKGZpZWxkc1tpXS0+aXNfcmVwZWF0ZWQoKSkgeworICAgICAgICBpbnQgc2l6ZSA9IHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBmaWVsZHNbaV0pOworICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IHNpemU7IGorKykgeworICAgICAgICAgIGNvbnN0IE1lc3NhZ2UmIHN1Yl9tZXNzYWdlID0KKyAgICAgICAgICAgIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkTWVzc2FnZShtZXNzYWdlLCBmaWVsZHNbaV0sIGopOworICAgICAgICAgIGlmICghQ29sbGVjdEV4dGVuc2lvbnMoc3ViX21lc3NhZ2UsIGV4dGVuc2lvbnMpKSByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGNvbnN0IE1lc3NhZ2UmIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+R2V0TWVzc2FnZShtZXNzYWdlLCBmaWVsZHNbaV0pOworICAgICAgICBpZiAoIUNvbGxlY3RFeHRlbnNpb25zKHN1Yl9tZXNzYWdlLCBleHRlbnNpb25zKSkgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgIH0KKyAgfQorCisgIHJldHVybiB0cnVlOworfQorCisvLyBGaW5kcyBhbGwgZXh0ZW5zaW9ucyBpbiB0aGUgZ2l2ZW4gbWVzc2FnZSBhbmQgaXRzIHN1Yi1tZXNzYWdlcy4gIElmIHRoZQorLy8gbWVzc2FnZSBjb250YWlucyB1bmtub3duIGZpZWxkcyAod2hpY2ggY291bGQgYmUgZXh0ZW5zaW9ucyksIHRoZW4gdGhvc2UKKy8vIGV4dGVuc2lvbnMgYXJlIGRlZmluZWQgaW4gYWx0ZXJuYXRlX3Bvb2wuCisvLyBUaGUgbWVzc2FnZSB3aWxsIGJlIGNvbnZlcnRlZCB0byBhIER5bmFtaWNNZXNzYWdlIGJhY2tlZCBieSBhbHRlcm5hdGVfcG9vbAorLy8gaW4gb3JkZXIgdG8gaGFuZGxlIHRoaXMgY2FzZS4KK3ZvaWQgQ29sbGVjdEV4dGVuc2lvbnMoY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byYgZmlsZV9wcm90bywKKyAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVzY3JpcHRvclBvb2wmIGFsdGVybmF0ZV9wb29sLAorICAgICAgICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JTZXQqIGV4dGVuc2lvbnMsCisgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgZmlsZV9kYXRhKSB7CisgIGlmICghQ29sbGVjdEV4dGVuc2lvbnMoZmlsZV9wcm90bywgZXh0ZW5zaW9ucykpIHsKKyAgICAvLyBUaGVyZSBhcmUgdW5rbm93biBmaWVsZHMgaW4gdGhlIGZpbGVfcHJvdG8sIHdoaWNoIGFyZSBwcm9iYWJseQorICAgIC8vIGV4dGVuc2lvbnMuIFdlIG5lZWQgdG8gcGFyc2UgdGhlIGRhdGEgaW50byBhIGR5bmFtaWMgbWVzc2FnZSBiYXNlZCBvbiB0aGUKKyAgICAvLyBidWlsZGVyLXBvb2wgdG8gZmluZCBvdXQgYWxsIGV4dGVuc2lvbnMuCisgICAgY29uc3QgRGVzY3JpcHRvciogZmlsZV9wcm90b19kZXNjID0gYWx0ZXJuYXRlX3Bvb2wuRmluZE1lc3NhZ2VUeXBlQnlOYW1lKAorICAgICAgICBmaWxlX3Byb3RvLkdldERlc2NyaXB0b3IoKS0+ZnVsbF9uYW1lKCkpOworICAgIEdPT0dMRV9DSEVDSyhmaWxlX3Byb3RvX2Rlc2MpCisgICAgICAgIDw8ICJGaW5kIHVua25vd24gZmllbGRzIGluIEZpbGVEZXNjcmlwdG9yUHJvdG8gd2hlbiBidWlsZGluZyAiCisgICAgICAgIDw8IGZpbGVfcHJvdG8ubmFtZSgpCisgICAgICAgIDw8ICIuIEl0J3MgbGlrZWx5IHRoYXQgdGhvc2UgZmllbGRzIGFyZSBjdXN0b20gb3B0aW9ucywgaG93ZXZlciwgIgorICAgICAgICAgICAiZGVzY3JpcHRvci5wcm90byBpcyBub3QgaW4gdGhlIHRyYW5zaXRpdmUgZGVwZW5kZW5jaWVzLiAiCisgICAgICAgICAgICJUaGlzIG5vcm1hbGx5IHNob3VsZCBub3QgaGFwcGVuLiBQbGVhc2UgcmVwb3J0IGEgYnVnLiI7CisgICAgRHluYW1pY01lc3NhZ2VGYWN0b3J5IGZhY3Rvcnk7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxNZXNzYWdlPiBkeW5hbWljX2ZpbGVfcHJvdG8oCisgICAgICAgIGZhY3RvcnkuR2V0UHJvdG90eXBlKGZpbGVfcHJvdG9fZGVzYyktPk5ldygpKTsKKyAgICBHT09HTEVfQ0hFQ0soZHluYW1pY19maWxlX3Byb3RvLmdldCgpICE9IE5VTEwpOworICAgIEdPT0dMRV9DSEVDSyhkeW5hbWljX2ZpbGVfcHJvdG8tPlBhcnNlRnJvbVN0cmluZyhmaWxlX2RhdGEpKTsKKworICAgIC8vIENvbGxlY3QgdGhlIGV4dGVuc2lvbnMgYWdhaW4gZnJvbSB0aGUgZHluYW1pYyBtZXNzYWdlLiBUaGVyZSBzaG91bGQgYmUgbm8KKyAgICAvLyBtb3JlIHVua25vd24gZmllbGRzIHRoaXMgdGltZSwgaS5lLiBhbGwgdGhlIGN1c3RvbSBvcHRpb25zIHNob3VsZCBiZQorICAgIC8vIHBhcnNlZCBhcyBleHRlbnNpb25zIG5vdy4KKyAgICBleHRlbnNpb25zLT5jbGVhcigpOworICAgIEdPT0dMRV9DSEVDSyhDb2xsZWN0RXh0ZW5zaW9ucygqZHluYW1pY19maWxlX3Byb3RvLCBleHRlbnNpb25zKSkKKyAgICAgICAgPDwgIkZpbmQgdW5rbm93biBmaWVsZHMgaW4gRmlsZURlc2NyaXB0b3JQcm90byB3aGVuIGJ1aWxkaW5nICIKKyAgICAgICAgPDwgZmlsZV9wcm90by5uYW1lKCkKKyAgICAgICAgPDwgIi4gSXQncyBsaWtlbHkgdGhhdCB0aG9zZSBmaWVsZHMgYXJlIGN1c3RvbSBvcHRpb25zLCBob3dldmVyLCAiCisgICAgICAgICAgICJ0aG9zZSBvcHRpb25zIGNhbm5vdCBiZSByZWNvZ25pemVkIGluIHRoZSBidWlsZGVyIHBvb2wuICIKKyAgICAgICAgICAgIlRoaXMgbm9ybWFsbHkgc2hvdWxkIG5vdCBoYXBwZW4uIFBsZWFzZSByZXBvcnQgYSBidWcuIjsKKyAgfQorfQorCisvLyBDb21wYXJlIHR3byBmaWVsZCBkZXNjcmlwdG9ycywgcmV0dXJuaW5nIHRydWUgaWYgdGhlIGZpcnN0IHNob3VsZCBjb21lCisvLyBiZWZvcmUgdGhlIHNlY29uZC4KK2Jvb2wgQ29tcGFyZUZpZWxkc0J5TmFtZShjb25zdCBGaWVsZERlc2NyaXB0b3IgKmEsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciAqYikgeworICByZXR1cm4gYS0+ZnVsbF9uYW1lKCkgPCBiLT5mdWxsX25hbWUoKTsKK30KKworLy8gT3VyIHN0YXRpYyBpbml0aWFsaXphdGlvbiBtZXRob2RzIGNhbiBiZWNvbWUgdmVyeSwgdmVyeSBsYXJnZS4KKy8vIFNvIGxhcmdlIHRoYXQgaWYgd2UgYXJlbid0IGNhcmVmdWwgd2UgZW5kIHVwIGJsb3dpbmcgdGhlIEpWTSdzCisvLyA2NEsgYnl0ZXMgb2YgYnl0ZWNvZGUvbWV0aG9kLiBGb3J0dW5hdGVseSwgc2luY2UgdGhlc2Ugc3RhdGljCisvLyBtZXRob2RzIGFyZSBleGVjdXRlZCBvbmx5IG9uY2UgbmVhciB0aGUgYmVnaW5uaW5nIG9mIGEgcHJvZ3JhbSwKKy8vIHRoZXJlJ3MgdXN1YWxseSBwbGVudHkgb2Ygc3RhY2sgc3BhY2UgYXZhaWxhYmxlIGFuZCB3ZSBjYW4KKy8vIGV4dGVuZCBvdXIgbWV0aG9kcyBieSBzaW1wbHkgY2hhaW5pbmcgdGhlbSB0byBhbm90aGVyIG1ldGhvZAorLy8gd2l0aCBhIHRhaWwgY2FsbC4gVGhpcyBpbnNlcnRzIHRoZSBzZXF1ZW5jZSBjYWxsLW5leHQtbWV0aG9kLAorLy8gZW5kIHRoaXMgb25lLCBiZWdpbi1uZXh0LW1ldGhvZCBhcyBuZWVkZWQuCit2b2lkIE1heWJlUmVzdGFydEphdmFNZXRob2QoaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ICpieXRlY29kZV9lc3RpbWF0ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgKm1ldGhvZF9udW0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqY2hhaW5fc3RhdGVtZW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKm1ldGhvZF9kZWNsKSB7CisgIC8vIFRoZSBnb2FsIGhlcmUgaXMgdG8gc3RheSB1bmRlciA2NEsgYnl0ZXMgb2YganZtIGJ5dGVjb2RlL21ldGhvZCwKKyAgLy8gc2luY2Ugb3RoZXJ3aXNlIHdlIGhpdCBhIGhhcmRjb2RlZCBsaW1pdCBpbiB0aGUganZtIGFuZCBqYXZhYyB3aWxsCisgIC8vIHRoZW4gZmFpbCB3aXRoIHRoZSBlcnJvciAiY29kZSB0b28gbGFyZ2UiLiBUaGlzIGxpbWl0IGxldHMgb3VyCisgIC8vIGVzdGltYXRlcyBiZSBvZmYgYnkgYSBmYWN0b3Igb2YgdHdvIGFuZCBzdGlsbCB3ZSdyZSBva2F5LgorICBzdGF0aWMgY29uc3QgaW50IGJ5dGVzUGVyTWV0aG9kID0gMTw8MTU7ICAvLyBha2EgMzJLCisKKyAgaWYgKCgqYnl0ZWNvZGVfZXN0aW1hdGUpID4gYnl0ZXNQZXJNZXRob2QpIHsKKyAgICArKygqbWV0aG9kX251bSk7CisgICAgcHJpbnRlci0+UHJpbnQoY2hhaW5fc3RhdGVtZW50LCAibWV0aG9kX251bSIsIFNpbXBsZUl0b2EoKm1ldGhvZF9udW0pKTsKKyAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworICAgIHByaW50ZXItPlByaW50KG1ldGhvZF9kZWNsLCAibWV0aG9kX251bSIsIFNpbXBsZUl0b2EoKm1ldGhvZF9udW0pKTsKKyAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICAqYnl0ZWNvZGVfZXN0aW1hdGUgPSAwOworICB9Cit9CisKKworfSAgLy8gbmFtZXNwYWNlCisKK0ZpbGVHZW5lcmF0b3I6OkZpbGVHZW5lcmF0b3IoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUsIGJvb2wgaW1tdXRhYmxlX2FwaSkKKyAgICA6IGZpbGVfKGZpbGUpLAorICAgICAgamF2YV9wYWNrYWdlXyhGaWxlSmF2YVBhY2thZ2UoZmlsZSwgaW1tdXRhYmxlX2FwaSkpLAorICAgICAgbWVzc2FnZV9nZW5lcmF0b3JzXygKKyAgICAgICAgICBuZXcgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxNZXNzYWdlR2VuZXJhdG9yPltmaWxlLT5tZXNzYWdlX3R5cGVfY291bnQoKV0pLAorICAgICAgZXh0ZW5zaW9uX2dlbmVyYXRvcnNfKAorICAgICAgICAgIG5ldyBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPEV4dGVuc2lvbkdlbmVyYXRvcj5bZmlsZS0+ZXh0ZW5zaW9uX2NvdW50KCldKSwKKyAgICAgIGNvbnRleHRfKG5ldyBDb250ZXh0KGZpbGUpKSwKKyAgICAgIG5hbWVfcmVzb2x2ZXJfKGNvbnRleHRfLT5HZXROYW1lUmVzb2x2ZXIoKSksCisgICAgICBpbW11dGFibGVfYXBpXyhpbW11dGFibGVfYXBpKSB7CisgIGNsYXNzbmFtZV8gPSBuYW1lX3Jlc29sdmVyXy0+R2V0RmlsZUNsYXNzTmFtZShmaWxlLCBpbW11dGFibGVfYXBpKTsKKyAgZ2VuZXJhdG9yX2ZhY3RvcnlfLnJlc2V0KAorICAgICAgbmV3IEltbXV0YWJsZUdlbmVyYXRvckZhY3RvcnkoY29udGV4dF8uZ2V0KCkpKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+bWVzc2FnZV90eXBlX2NvdW50KCk7ICsraSkgeworICAgIG1lc3NhZ2VfZ2VuZXJhdG9yc19baV0ucmVzZXQoCisgICAgICAgIGdlbmVyYXRvcl9mYWN0b3J5Xy0+TmV3TWVzc2FnZUdlbmVyYXRvcihmaWxlXy0+bWVzc2FnZV90eXBlKGkpKSk7CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+ZXh0ZW5zaW9uX2NvdW50KCk7ICsraSkgeworICAgIGV4dGVuc2lvbl9nZW5lcmF0b3JzX1tpXS5yZXNldCgKKyAgICAgICAgZ2VuZXJhdG9yX2ZhY3RvcnlfLT5OZXdFeHRlbnNpb25HZW5lcmF0b3IoZmlsZV8tPmV4dGVuc2lvbihpKSkpOworICB9Cit9CisKK0ZpbGVHZW5lcmF0b3I6On5GaWxlR2VuZXJhdG9yKCkge30KKworYm9vbCBGaWxlR2VuZXJhdG9yOjpWYWxpZGF0ZShzdHJpbmcqIGVycm9yKSB7CisgIC8vIENoZWNrIHRoYXQgbm8gY2xhc3MgbmFtZSBtYXRjaGVzIHRoZSBmaWxlJ3MgY2xhc3MgbmFtZS4gIFRoaXMgaXMgYSBjb21tb24KKyAgLy8gcHJvYmxlbSB0aGF0IGxlYWRzIHRvIEphdmEgY29tcGlsZSBlcnJvcnMgdGhhdCBjYW4gYmUgaGFyZCB0byB1bmRlcnN0YW5kLgorICAvLyBJdCdzIGVzcGVjaWFsbHkgYmFkIHdoZW4gdXNpbmcgdGhlIGphdmFfbXVsdGlwbGVfZmlsZXMsIHNpbmNlIHdlIHdvdWxkCisgIC8vIGVuZCB1cCBvdmVyd3JpdGluZyB0aGUgb3V0ZXIgY2xhc3Mgd2l0aCBvbmUgb2YgdGhlIGlubmVyIG9uZXMuCisgIGlmIChuYW1lX3Jlc29sdmVyXy0+SGFzQ29uZmxpY3RpbmdDbGFzc05hbWUoZmlsZV8sIGNsYXNzbmFtZV8pKSB7CisgICAgZXJyb3ItPmFzc2lnbihmaWxlXy0+bmFtZSgpKTsKKyAgICBlcnJvci0+YXBwZW5kKAorICAgICAgIjogQ2Fubm90IGdlbmVyYXRlIEphdmEgb3V0cHV0IGJlY2F1c2UgdGhlIGZpbGUncyBvdXRlciBjbGFzcyBuYW1lLCBcIiIpOworICAgIGVycm9yLT5hcHBlbmQoY2xhc3NuYW1lXyk7CisgICAgZXJyb3ItPmFwcGVuZCgKKyAgICAgICJcIiwgbWF0Y2hlcyB0aGUgbmFtZSBvZiBvbmUgb2YgdGhlIHR5cGVzIGRlY2xhcmVkIGluc2lkZSBpdC4gICIKKyAgICAgICJQbGVhc2UgZWl0aGVyIHJlbmFtZSB0aGUgdHlwZSBvciB1c2UgdGhlIGphdmFfb3V0ZXJfY2xhc3NuYW1lICIKKyAgICAgICJvcHRpb24gdG8gc3BlY2lmeSBhIGRpZmZlcmVudCBvdXRlciBjbGFzcyBuYW1lIGZvciB0aGUgLnByb3RvIGZpbGUuIik7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIHJldHVybiB0cnVlOworfQorCit2b2lkIEZpbGVHZW5lcmF0b3I6OkdlbmVyYXRlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIC8vIFdlIGRvbid0IGltcG9ydCBhbnl0aGluZyBiZWNhdXNlIHdlIHJlZmVyIHRvIGFsbCBjbGFzc2VzIGJ5IHRoZWlyCisgIC8vIGZ1bGx5LXF1YWxpZmllZCBuYW1lcyBpbiB0aGUgZ2VuZXJhdGVkIHNvdXJjZS4KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIi8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhXG4iCisgICAgIi8vIHNvdXJjZTogJGZpbGVuYW1lJFxuIgorICAgICJcbiIsCisgICAgImZpbGVuYW1lIiwgZmlsZV8tPm5hbWUoKSk7CisgIGlmICghamF2YV9wYWNrYWdlXy5lbXB0eSgpKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAicGFja2FnZSAkcGFja2FnZSQ7XG4iCisgICAgICAiXG4iLAorICAgICAgInBhY2thZ2UiLCBqYXZhX3BhY2thZ2VfKTsKKyAgfQorICBwcmludGVyLT5QcmludCgKKyAgICAicHVibGljIGZpbmFsIGNsYXNzICRjbGFzc25hbWUkIHtcbiIKKyAgICAiICBwcml2YXRlICRjbGFzc25hbWUkKCkge31cbiIsCisgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8pOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIHByaW50ZXItPlByaW50KAorICAgICJwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKFxuIgorICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeSRsaXRlJCByZWdpc3RyeSkge1xuIiwKKyAgICAibGl0ZSIsIEhhc0Rlc2NyaXB0b3JNZXRob2RzKGZpbGVfKSA/ICIiIDogIkxpdGUiKTsKKworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5leHRlbnNpb25fY291bnQoKTsgaSsrKSB7CisgICAgZXh0ZW5zaW9uX2dlbmVyYXRvcnNfW2ldLT5HZW5lcmF0ZVJlZ2lzdHJhdGlvbkNvZGUocHJpbnRlcik7CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5tZXNzYWdlX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgbWVzc2FnZV9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVFeHRlbnNpb25SZWdpc3RyYXRpb25Db2RlKHByaW50ZXIpOworICB9CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAifVxuIik7CisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBpZiAoIU11bHRpcGxlSmF2YUZpbGVzKGZpbGVfLCBpbW11dGFibGVfYXBpXykpIHsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5lbnVtX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgICBpZiAoSGFzRGVzY3JpcHRvck1ldGhvZHMoZmlsZV8pKSB7CisgICAgICAgIEVudW1HZW5lcmF0b3IoZmlsZV8tPmVudW1fdHlwZShpKSwgaW1tdXRhYmxlX2FwaV8sIGNvbnRleHRfLmdldCgpKQorICAgICAgICAgICAgLkdlbmVyYXRlKHByaW50ZXIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgRW51bUxpdGVHZW5lcmF0b3IoZmlsZV8tPmVudW1fdHlwZShpKSwgaW1tdXRhYmxlX2FwaV8sIGNvbnRleHRfLmdldCgpKQorICAgICAgICAgICAgLkdlbmVyYXRlKHByaW50ZXIpOworICAgICAgfQorICAgIH0KKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5tZXNzYWdlX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgICBtZXNzYWdlX2dlbmVyYXRvcnNfW2ldLT5HZW5lcmF0ZUludGVyZmFjZShwcmludGVyKTsKKyAgICAgIG1lc3NhZ2VfZ2VuZXJhdG9yc19baV0tPkdlbmVyYXRlKHByaW50ZXIpOworICAgIH0KKyAgICBpZiAoSGFzR2VuZXJpY1NlcnZpY2VzKGZpbGVfKSkgeworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+c2VydmljZV9jb3VudCgpOyBpKyspIHsKKyAgICAgICAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxTZXJ2aWNlR2VuZXJhdG9yPiBnZW5lcmF0b3IoCisgICAgICAgICAgICBnZW5lcmF0b3JfZmFjdG9yeV8tPk5ld1NlcnZpY2VHZW5lcmF0b3IoZmlsZV8tPnNlcnZpY2UoaSkpKTsKKyAgICAgICAgZ2VuZXJhdG9yLT5HZW5lcmF0ZShwcmludGVyKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvLyBFeHRlbnNpb25zIG11c3QgYmUgZ2VuZXJhdGVkIGluIHRoZSBvdXRlciBjbGFzcyBzaW5jZSB0aGV5IGFyZSB2YWx1ZXMsCisgIC8vIG5vdCBjbGFzc2VzLgorICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5leHRlbnNpb25fY291bnQoKTsgaSsrKSB7CisgICAgZXh0ZW5zaW9uX2dlbmVyYXRvcnNfW2ldLT5HZW5lcmF0ZShwcmludGVyKTsKKyAgfQorCisgIC8vIFN0YXRpYyB2YXJpYWJsZXMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBtZXNzYWdlX2dlbmVyYXRvcnNfW2ldLT5HZW5lcmF0ZVN0YXRpY1ZhcmlhYmxlcyhwcmludGVyKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KCJcbiIpOworCisgIGlmIChIYXNEZXNjcmlwdG9yTWV0aG9kcyhmaWxlXykpIHsKKyAgICBpZiAoaW1tdXRhYmxlX2FwaV8pIHsKKyAgICAgIEdlbmVyYXRlRGVzY3JpcHRvckluaXRpYWxpemF0aW9uQ29kZUZvckltbXV0YWJsZShwcmludGVyKTsKKyAgICB9IGVsc2UgeworICAgICAgR2VuZXJhdGVEZXNjcmlwdG9ySW5pdGlhbGl6YXRpb25Db2RlRm9yTXV0YWJsZShwcmludGVyKTsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAic3RhdGljIHtcbiIpOworICAgIHByaW50ZXItPkluZGVudCgpOworICAgIGludCBieXRlY29kZV9lc3RpbWF0ZSA9IDA7CisgICAgaW50IG1ldGhvZF9udW0gPSAwOworCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+bWVzc2FnZV90eXBlX2NvdW50KCk7IGkrKykgeworICAgICAgYnl0ZWNvZGVfZXN0aW1hdGUgKz0gbWVzc2FnZV9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVTdGF0aWNWYXJpYWJsZUluaXRpYWxpemVycyhwcmludGVyKTsKKyAgICAgIE1heWJlUmVzdGFydEphdmFNZXRob2QoCisgICAgICAgIHByaW50ZXIsCisgICAgICAgICZieXRlY29kZV9lc3RpbWF0ZSwgJm1ldGhvZF9udW0sCisgICAgICAgICJfY2xpbml0X2F1dG9zcGxpdF8kbWV0aG9kX251bSQoKTtcbiIsCisgICAgICAgICJwcml2YXRlIHN0YXRpYyB2b2lkIF9jbGluaXRfYXV0b3NwbGl0XyRtZXRob2RfbnVtJCgpIHtcbiIpOworICAgIH0KKworICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJ9XG4iKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KAorICAgICJcbiIKKyAgICAiLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG91dGVyX2NsYXNzX3Njb3BlKVxuIik7CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgifVxuIik7Cit9CisKK3ZvaWQgRmlsZUdlbmVyYXRvcjo6R2VuZXJhdGVEZXNjcmlwdG9ySW5pdGlhbGl6YXRpb25Db2RlRm9ySW1tdXRhYmxlKAorICAgIGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgICJwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3JcbiIKKyAgICAiICAgIGdldERlc2NyaXB0b3IoKSB7XG4iCisgICAgIiAgcmV0dXJuIGRlc2NyaXB0b3I7XG4iCisgICAgIn1cbiIKKyAgICAicHJpdmF0ZSBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvclxuIgorICAgICIgICAgZGVzY3JpcHRvcjtcbiIKKyAgICAic3RhdGljIHtcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBTaGFyZWRDb2RlR2VuZXJhdG9yIHNoYXJlZF9jb2RlX2dlbmVyYXRvcihmaWxlXyk7CisgIHNoYXJlZF9jb2RlX2dlbmVyYXRvci5HZW5lcmF0ZURlc2NyaXB0b3JzKHByaW50ZXIpOworCisgIGludCBieXRlY29kZV9lc3RpbWF0ZSA9IDA7CisgIGludCBtZXRob2RfbnVtID0gMDsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5tZXNzYWdlX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgYnl0ZWNvZGVfZXN0aW1hdGUgKz0gbWVzc2FnZV9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVTdGF0aWNWYXJpYWJsZUluaXRpYWxpemVycyhwcmludGVyKTsKKyAgICBNYXliZVJlc3RhcnRKYXZhTWV0aG9kKAorICAgICAgcHJpbnRlciwKKyAgICAgICZieXRlY29kZV9lc3RpbWF0ZSwgJm1ldGhvZF9udW0sCisgICAgICAiX2NsaW5pdF9hdXRvc3BsaXRfZGluaXRfJG1ldGhvZF9udW0kKCk7XG4iLAorICAgICAgInByaXZhdGUgc3RhdGljIHZvaWQgX2NsaW5pdF9hdXRvc3BsaXRfZGluaXRfJG1ldGhvZF9udW0kKCkge1xuIik7CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+ZXh0ZW5zaW9uX2NvdW50KCk7IGkrKykgeworICAgIGJ5dGVjb2RlX2VzdGltYXRlICs9IGV4dGVuc2lvbl9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVOb25OZXN0ZWRJbml0aWFsaXphdGlvbkNvZGUocHJpbnRlcik7CisgICAgTWF5YmVSZXN0YXJ0SmF2YU1ldGhvZCgKKyAgICAgIHByaW50ZXIsCisgICAgICAmYnl0ZWNvZGVfZXN0aW1hdGUsICZtZXRob2RfbnVtLAorICAgICAgIl9jbGluaXRfYXV0b3NwbGl0X2Rpbml0XyRtZXRob2RfbnVtJCgpO1xuIiwKKyAgICAgICJwcml2YXRlIHN0YXRpYyB2b2lkIF9jbGluaXRfYXV0b3NwbGl0X2Rpbml0XyRtZXRob2RfbnVtJCgpIHtcbiIpOworICB9CisKKyAgLy8gUHJvdG8gY29tcGlsZXIgYnVpbGRzIGEgRGVzY3JpcHRvclBvb2wsIHdoaWNoIGhvbGRzIGFsbCB0aGUgZGVzY3JpcHRvcnMgdG8KKyAgLy8gZ2VuZXJhdGUsIHdoZW4gcHJvY2Vzc2luZyB0aGUgIi5wcm90byIgZmlsZXMuIFdlIGNhbGwgdGhpcyBEZXNjcmlwdG9yUG9vbAorICAvLyB0aGUgcGFyc2VkIHBvb2wgKGEuay5hLiBmaWxlXy0+cG9vbCgpKS4KKyAgLy8KKyAgLy8gTm90ZSB0aGF0IHdoZW4gdXNlcnMgdHJ5IHRvIGV4dGVuZCB0aGUgKC4qKURlc2NyaXB0b3JQcm90byBpbiB0aGVpcgorICAvLyAiLnByb3RvIiBmaWxlcywgaXQgZG9lcyBub3QgYWZmZWN0IHRoZSBwcmUtYnVpbHQgRmlsZURlc2NyaXB0b3JQcm90byBjbGFzcworICAvLyBpbiBwcm90byBjb21waWxlci4gV2hlbiB3ZSBwdXQgdGhlIGRlc2NyaXB0b3IgZGF0YSBpbiB0aGUgZmlsZV9wcm90bywgdGhvc2UKKyAgLy8gZXh0ZW5zaW9ucyBiZWNvbWUgdW5rbm93biBmaWVsZHMuCisgIC8vCisgIC8vIE5vdyB3ZSBuZWVkIHRvIGZpbmQgb3V0IGFsbCB0aGUgZXh0ZW5zaW9uIHZhbHVlIHRvIHRoZSAoLiopRGVzY3JpcHRvclByb3RvCisgIC8vIGluIHRoZSBmaWxlX3Byb3RvIG1lc3NhZ2UsIGFuZCBwcmVwYXJlIGFuIEV4dGVuc2lvblJlZ2lzdHJ5IHRvIHJldHVybi4KKyAgLy8KKyAgLy8gVG8gZmluZCB0aG9zZSBleHRlbnNpb25zLCB3ZSBuZWVkIHRvIHBhcnNlIHRoZSBkYXRhIGludG8gYSBkeW5hbWljIG1lc3NhZ2UKKyAgLy8gb2YgdGhlIEZpbGVEZXNjcmlwdG9yIGJhc2VkIG9uIHRoZSBidWlsZGVyLXBvb2wsIHRoZW4gd2UgY2FuIHVzZQorICAvLyByZWZsZWN0aW9ucyB0byBmaW5kIGFsbCBleHRlbnNpb24gZmllbGRzCisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZV9wcm90bzsKKyAgZmlsZV8tPkNvcHlUbygmZmlsZV9wcm90byk7CisgIHN0cmluZyBmaWxlX2RhdGE7CisgIGZpbGVfcHJvdG8uU2VyaWFsaXplVG9TdHJpbmcoJmZpbGVfZGF0YSk7CisgIEZpZWxkRGVzY3JpcHRvclNldCBleHRlbnNpb25zOworICBDb2xsZWN0RXh0ZW5zaW9ucyhmaWxlX3Byb3RvLCAqZmlsZV8tPnBvb2woKSwgJmV4dGVuc2lvbnMsIGZpbGVfZGF0YSk7CisKKyAgaWYgKGV4dGVuc2lvbnMuc2l6ZSgpID4gMCkgeworICAgIC8vIE11c3QgY29uc3RydWN0IGFuIEV4dGVuc2lvblJlZ2lzdHJ5IGNvbnRhaW5pbmcgYWxsIGV4aXN0aW5nIGV4dGVuc2lvbnMKKyAgICAvLyBhbmQgdXNlIGl0IHRvIHBhcnNlIHRoZSBkZXNjcmlwdG9yIGRhdGEgYWdhaW4gdG8gcmVjb2duaXplIGV4dGVuc2lvbnMuCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSA9XG4iCisgICAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnkubmV3SW5zdGFuY2UoKTtcbiIpOworICAgIEZpZWxkRGVzY3JpcHRvclNldDo6aXRlcmF0b3IgaXQ7CisgICAgZm9yIChpdCA9IGV4dGVuc2lvbnMuYmVnaW4oKTsgaXQgIT0gZXh0ZW5zaW9ucy5lbmQoKTsgaXQrKykgeworICAgICAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxFeHRlbnNpb25HZW5lcmF0b3I+IGdlbmVyYXRvcigKKyAgICAgICAgICBnZW5lcmF0b3JfZmFjdG9yeV8tPk5ld0V4dGVuc2lvbkdlbmVyYXRvcigqaXQpKTsKKyAgICAgIGJ5dGVjb2RlX2VzdGltYXRlICs9IGdlbmVyYXRvci0+R2VuZXJhdGVSZWdpc3RyYXRpb25Db2RlKHByaW50ZXIpOworICAgICAgTWF5YmVSZXN0YXJ0SmF2YU1ldGhvZCgKKyAgICAgICAgcHJpbnRlciwKKyAgICAgICAgJmJ5dGVjb2RlX2VzdGltYXRlLCAmbWV0aG9kX251bSwKKyAgICAgICAgIl9jbGluaXRfYXV0b3NwbGl0X2Rpbml0XyRtZXRob2RfbnVtJChyZWdpc3RyeSk7XG4iLAorICAgICAgICAicHJpdmF0ZSBzdGF0aWMgdm9pZCBfY2xpbml0X2F1dG9zcGxpdF9kaW5pdF8kbWV0aG9kX251bSQoXG4iCisgICAgICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSkge1xuIik7CisgICAgfQorICAgIHByaW50ZXItPlByaW50KAorICAgICAgImNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3JcbiIKKyAgICAgICIgICAgLmludGVybmFsVXBkYXRlRmlsZURlc2NyaXB0b3IoZGVzY3JpcHRvciwgcmVnaXN0cnkpO1xuIik7CisgIH0KKworICAvLyBGb3JjZSBkZXNjcmlwdG9yIGluaXRpYWxpemF0aW9uIG9mIGFsbCBkZXBlbmRlbmNpZXMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPmRlcGVuZGVuY3lfY291bnQoKTsgaSsrKSB7CisgICAgaWYgKFNob3VsZEluY2x1ZGVEZXBlbmRlbmN5KGZpbGVfLT5kZXBlbmRlbmN5KGkpLCB0cnVlKSkgeworICAgICAgc3RyaW5nIGRlcGVuZGVuY3kgPQorICAgICAgICAgIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZmlsZV8tPmRlcGVuZGVuY3koaSkpOworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICIkZGVwZW5kZW5jeSQuZ2V0RGVzY3JpcHRvcigpO1xuIiwKKyAgICAgICAgImRlcGVuZGVuY3kiLCBkZXBlbmRlbmN5KTsKKyAgICB9CisgIH0KKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KAorICAgICJ9XG4iKTsKK30KKwordm9pZCBGaWxlR2VuZXJhdG9yOjpHZW5lcmF0ZURlc2NyaXB0b3JJbml0aWFsaXphdGlvbkNvZGVGb3JNdXRhYmxlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgICJwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3JcbiIKKyAgICAiICAgIGdldERlc2NyaXB0b3IoKSB7XG4iCisgICAgIiAgcmV0dXJuIGRlc2NyaXB0b3I7XG4iCisgICAgIn1cbiIKKyAgICAicHJpdmF0ZSBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvclxuIgorICAgICIgICAgZGVzY3JpcHRvcjtcbiIKKyAgICAic3RhdGljIHtcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAiZGVzY3JpcHRvciA9ICRpbW11dGFibGVfcGFja2FnZSQuJGRlc2NyaXB0b3JfY2xhc3NuYW1lJC5kZXNjcmlwdG9yO1xuIiwKKyAgICAiaW1tdXRhYmxlX3BhY2thZ2UiLCBGaWxlSmF2YVBhY2thZ2UoZmlsZV8sIHRydWUpLAorICAgICJkZXNjcmlwdG9yX2NsYXNzbmFtZSIsIG5hbWVfcmVzb2x2ZXJfLT5HZXREZXNjcmlwdG9yQ2xhc3NOYW1lKGZpbGVfKSk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+bWVzc2FnZV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIG1lc3NhZ2VfZ2VuZXJhdG9yc19baV0tPkdlbmVyYXRlU3RhdGljVmFyaWFibGVJbml0aWFsaXplcnMocHJpbnRlcik7CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+ZXh0ZW5zaW9uX2NvdW50KCk7IGkrKykgeworICAgIGV4dGVuc2lvbl9nZW5lcmF0b3JzX1tpXS0+R2VuZXJhdGVOb25OZXN0ZWRJbml0aWFsaXphdGlvbkNvZGUocHJpbnRlcik7CisgIH0KKworICAvLyBDaGVjayBpZiBjdXN0b20gb3B0aW9ucyBleGlzdC4gSWYgYW55LCB0cnkgdG8gbG9hZCBpbW11dGFibGUgY2xhc3NlcyBzaW5jZQorICAvLyBjdXN0b20gb3B0aW9ucyBhcmUgb25seSByZXByZXNlbnRlZCB3aXRoIGltbXV0YWJsZSBtZXNzYWdlcy4KKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICBmaWxlXy0+Q29weVRvKCZmaWxlX3Byb3RvKTsKKyAgc3RyaW5nIGZpbGVfZGF0YTsKKyAgZmlsZV9wcm90by5TZXJpYWxpemVUb1N0cmluZygmZmlsZV9kYXRhKTsKKyAgRmllbGREZXNjcmlwdG9yU2V0IGV4dGVuc2lvbnM7CisgIENvbGxlY3RFeHRlbnNpb25zKGZpbGVfcHJvdG8sICpmaWxlXy0+cG9vbCgpLCAmZXh0ZW5zaW9ucywgZmlsZV9kYXRhKTsKKworICBpZiAoZXh0ZW5zaW9ucy5zaXplKCkgPiAwKSB7CisgICAgLy8gVHJ5IHRvIGxvYWQgaW1tdXRhYmxlIG1lc3NhZ2VzJyBvdXRlciBjbGFzcy4gSXRzIGluaXRpYWxpemF0aW9uIGNvZGUKKyAgICAvLyB3aWxsIHRha2UgY2FyZSBvZiBpbnRlcnByZXRpbmcgY3VzdG9tIG9wdGlvbnMuCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAidHJ5IHtcbiIKKyAgICAgIC8vIE5vdGUgdGhhdCB3ZSBoYXZlIHRvIGxvYWQgdGhlIGltbXV0YWJsZSBjbGFzcyBkeW5hbWljYWxseSBoZXJlIGFzCisgICAgICAvLyB3ZSB3YW50IHRoZSBtdXRhYmxlIGNvZGUgdG8gYmUgaW5kZXBlbmRlbnQgZnJvbSB0aGUgaW1tdXRhYmxlIGNvZGUKKyAgICAgIC8vIGF0IGNvbXBpbGUgdGltZS4gSXQgaXMgcmVxdWlyZWQgdG8gaW1wbGVtZW50IGR1YWwtY29tcGlsZSBmb3IKKyAgICAgIC8vIG11dGFibGUgYW5kIGltbXV0YWJsZSBBUEkgaW4gYmxhemUuCisgICAgICAiICBqYXZhLmxhbmcuQ2xhc3MgaW1tdXRhYmxlQ2xhc3MgPSBqYXZhLmxhbmcuQ2xhc3MuZm9yTmFtZShcbiIKKyAgICAgICIgICAgICBcIiRpbW11dGFibGVfY2xhc3NuYW1lJFwiKTtcbiIKKyAgICAgICJ9IGNhdGNoIChqYXZhLmxhbmcuQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7XG4iCisgICAgICAvLyBUaGUgaW1tdXRhYmxlIGNsYXNzIGNhbiBub3QgYmUgZm91bmQuIEN1c3RvbSBvcHRpb25zIGFyZSBsZWZ0CisgICAgICAvLyBhcyB1bmtub3duIGZpZWxkcy4KKyAgICAgIC8vIFRPRE8oeGlhb2ZlbmcpOiBpbmZvcm0gdGhlIHVzZXIgd2l0aCBhIHdhcm5pbmc/CisgICAgICAifVxuIiwKKyAgICAgICJpbW11dGFibGVfY2xhc3NuYW1lIiwgbmFtZV9yZXNvbHZlcl8tPkdldEltbXV0YWJsZUNsYXNzTmFtZShmaWxlXykpOworICB9CisKKyAgLy8gRm9yY2UgZGVzY3JpcHRvciBpbml0aWFsaXphdGlvbiBvZiBhbGwgZGVwZW5kZW5jaWVzLgorICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5kZXBlbmRlbmN5X2NvdW50KCk7IGkrKykgeworICAgIGlmIChTaG91bGRJbmNsdWRlRGVwZW5kZW5jeShmaWxlXy0+ZGVwZW5kZW5jeShpKSwgZmFsc2UpKSB7CisgICAgICBzdHJpbmcgZGVwZW5kZW5jeSA9IG5hbWVfcmVzb2x2ZXJfLT5HZXRNdXRhYmxlQ2xhc3NOYW1lKAorICAgICAgICAgIGZpbGVfLT5kZXBlbmRlbmN5KGkpKTsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiJGRlcGVuZGVuY3kkLmdldERlc2NyaXB0b3IoKTtcbiIsCisgICAgICAgICJkZXBlbmRlbmN5IiwgZGVwZW5kZW5jeSk7CisgICAgfQorICB9CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAifVxuIik7Cit9CisKK3RlbXBsYXRlPHR5cGVuYW1lIEdlbmVyYXRvckNsYXNzLCB0eXBlbmFtZSBEZXNjcmlwdG9yQ2xhc3M+CitzdGF0aWMgdm9pZCBHZW5lcmF0ZVNpYmxpbmcoY29uc3Qgc3RyaW5nJiBwYWNrYWdlX2RpciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIGphdmFfcGFja2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEZXNjcmlwdG9yQ2xhc3MqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2VuZXJhdG9yQ29udGV4dCogY29udGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWN0b3I8c3RyaW5nPiogZmlsZV9saXN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgbmFtZV9zdWZmaXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2VuZXJhdG9yQ2xhc3MqIGdlbmVyYXRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkIChHZW5lcmF0b3JDbGFzczo6KnBmbikoaW86OlByaW50ZXIqIHByaW50ZXIpKSB7CisgIHN0cmluZyBmaWxlbmFtZSA9IHBhY2thZ2VfZGlyICsgZGVzY3JpcHRvci0+bmFtZSgpICsgbmFtZV9zdWZmaXggKyAiLmphdmEiOworICBmaWxlX2xpc3QtPnB1c2hfYmFjayhmaWxlbmFtZSk7CisKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0+IG91dHB1dChjb250ZXh0LT5PcGVuKGZpbGVuYW1lKSk7CisgIGlvOjpQcmludGVyIHByaW50ZXIob3V0cHV0LmdldCgpLCAnJCcpOworCisgIHByaW50ZXIuUHJpbnQoCisgICAgIi8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhXG4iCisgICAgIi8vIHNvdXJjZTogJGZpbGVuYW1lJFxuIgorICAgICJcbiIsCisgICAgImZpbGVuYW1lIiwgZGVzY3JpcHRvci0+ZmlsZSgpLT5uYW1lKCkpOworICBpZiAoIWphdmFfcGFja2FnZS5lbXB0eSgpKSB7CisgICAgcHJpbnRlci5QcmludCgKKyAgICAgICJwYWNrYWdlICRwYWNrYWdlJDtcbiIKKyAgICAgICJcbiIsCisgICAgICAicGFja2FnZSIsIGphdmFfcGFja2FnZSk7CisgIH0KKworICAoZ2VuZXJhdG9yLT4qcGZuKSgmcHJpbnRlcik7Cit9CisKK3ZvaWQgRmlsZUdlbmVyYXRvcjo6R2VuZXJhdGVTaWJsaW5ncyhjb25zdCBzdHJpbmcmIHBhY2thZ2VfZGlyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdlbmVyYXRvckNvbnRleHQqIGNvbnRleHQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjdG9yPHN0cmluZz4qIGZpbGVfbGlzdCkgeworICBpZiAoTXVsdGlwbGVKYXZhRmlsZXMoZmlsZV8sIGltbXV0YWJsZV9hcGlfKSkgeworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPmVudW1fdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICAgIGlmIChIYXNEZXNjcmlwdG9yTWV0aG9kcyhmaWxlXykpIHsKKyAgICAgICAgRW51bUdlbmVyYXRvciBnZW5lcmF0b3IoZmlsZV8tPmVudW1fdHlwZShpKSwgaW1tdXRhYmxlX2FwaV8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHRfLmdldCgpKTsKKyAgICAgICAgR2VuZXJhdGVTaWJsaW5nPEVudW1HZW5lcmF0b3I+KHBhY2thZ2VfZGlyLCBqYXZhX3BhY2thZ2VfLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZV8tPmVudW1fdHlwZShpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQsIGZpbGVfbGlzdCwgIiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZ2VuZXJhdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJkVudW1HZW5lcmF0b3I6OkdlbmVyYXRlKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIEVudW1MaXRlR2VuZXJhdG9yIGdlbmVyYXRvcihmaWxlXy0+ZW51bV90eXBlKGkpLCBpbW11dGFibGVfYXBpXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHRfLmdldCgpKTsKKyAgICAgICAgR2VuZXJhdGVTaWJsaW5nPEVudW1MaXRlR2VuZXJhdG9yPihwYWNrYWdlX2RpciwgamF2YV9wYWNrYWdlXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlXy0+ZW51bV90eXBlKGkpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQsIGZpbGVfbGlzdCwgIiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmdlbmVyYXRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmRW51bUxpdGVHZW5lcmF0b3I6OkdlbmVyYXRlKTsKKyAgICAgIH0KKyAgICB9CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+bWVzc2FnZV90eXBlX2NvdW50KCk7IGkrKykgeworICAgICAgaWYgKGltbXV0YWJsZV9hcGlfKSB7CisgICAgICAgIEdlbmVyYXRlU2libGluZzxNZXNzYWdlR2VuZXJhdG9yPihwYWNrYWdlX2RpciwgamF2YV9wYWNrYWdlXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVfLT5tZXNzYWdlX3R5cGUoaSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LCBmaWxlX2xpc3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiT3JCdWlsZGVyIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2VfZ2VuZXJhdG9yc19baV0uZ2V0KCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmTWVzc2FnZUdlbmVyYXRvcjo6R2VuZXJhdGVJbnRlcmZhY2UpOworICAgICAgfQorICAgICAgR2VuZXJhdGVTaWJsaW5nPE1lc3NhZ2VHZW5lcmF0b3I+KHBhY2thZ2VfZGlyLCBqYXZhX3BhY2thZ2VfLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVfLT5tZXNzYWdlX3R5cGUoaSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dCwgZmlsZV9saXN0LCAiIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlX2dlbmVyYXRvcnNfW2ldLmdldCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZNZXNzYWdlR2VuZXJhdG9yOjpHZW5lcmF0ZSk7CisgICAgfQorICAgIGlmIChIYXNHZW5lcmljU2VydmljZXMoZmlsZV8pKSB7CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5zZXJ2aWNlX2NvdW50KCk7IGkrKykgeworICAgICAgICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPFNlcnZpY2VHZW5lcmF0b3I+IGdlbmVyYXRvcigKKyAgICAgICAgICAgIGdlbmVyYXRvcl9mYWN0b3J5Xy0+TmV3U2VydmljZUdlbmVyYXRvcihmaWxlXy0+c2VydmljZShpKSkpOworICAgICAgICBHZW5lcmF0ZVNpYmxpbmc8U2VydmljZUdlbmVyYXRvcj4ocGFja2FnZV9kaXIsIGphdmFfcGFja2FnZV8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlXy0+c2VydmljZShpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQsIGZpbGVfbGlzdCwgIiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW5lcmF0b3IuZ2V0KCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmU2VydmljZUdlbmVyYXRvcjo6R2VuZXJhdGUpOworICAgICAgfQorICAgIH0KKyAgfQorfQorCitib29sIEZpbGVHZW5lcmF0b3I6OlNob3VsZEluY2x1ZGVEZXBlbmRlbmN5KAorICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBib29sIGltbXV0YWJsZV9hcGkpIHsKKyAgcmV0dXJuIHRydWU7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZmlsZS5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZmlsZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA4MGIzNDIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9maWxlLmgKQEAgLTAsMCArMSwxMTggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9GSUxFX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9GSUxFX0hfXworCisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDx2ZWN0b3I+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisgIGNsYXNzIEZpbGVEZXNjcmlwdG9yOyAgICAgICAgICAvLyBkZXNjcmlwdG9yLmgKKyAgbmFtZXNwYWNlIGlvIHsKKyAgICBjbGFzcyBQcmludGVyOyAgICAgICAgICAgICAgIC8vIHByaW50ZXIuaAorICB9CisgIG5hbWVzcGFjZSBjb21waWxlciB7CisgICAgY2xhc3MgR2VuZXJhdG9yQ29udGV4dDsgICAgICAvLyBjb2RlX2dlbmVyYXRvci5oCisgICAgbmFtZXNwYWNlIGphdmEgeworICAgICAgY2xhc3MgQ29udGV4dDsgICAgICAgICAgICAgLy8gY29udGV4dC5oCisgICAgICBjbGFzcyBNZXNzYWdlR2VuZXJhdG9yOyAgICAvLyBtZXNzYWdlLmgKKyAgICAgIGNsYXNzIEdlbmVyYXRvckZhY3Rvcnk7ICAgIC8vIGdlbmVyYXRvcl9mYWN0b3J5LmgKKyAgICAgIGNsYXNzIEV4dGVuc2lvbkdlbmVyYXRvcjsgIC8vIGV4dGVuc2lvbi5oCisgICAgICBjbGFzcyBDbGFzc05hbWVSZXNvbHZlcjsgICAvLyBuYW1lX3Jlc29sdmVyLmgKKyAgICB9CisgIH0KK30KKworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YSB7CisKK2NsYXNzIEZpbGVHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgRmlsZUdlbmVyYXRvcihjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSwgYm9vbCBpbW11dGFibGVfYXBpID0gdHJ1ZSk7CisgIH5GaWxlR2VuZXJhdG9yKCk7CisKKyAgLy8gQ2hlY2tzIGZvciBwcm9ibGVtcyB0aGF0IHdvdWxkIG90aGVyd2lzZSBsZWFkIHRvIGNyeXB0aWMgY29tcGlsZSBlcnJvcnMuCisgIC8vIFJldHVybnMgdHJ1ZSBpZiB0aGVyZSBhcmUgbm8gcHJvYmxlbXMsIG9yIHdyaXRlcyBhbiBlcnJvciBkZXNjcmlwdGlvbiB0bworICAvLyB0aGUgZ2l2ZW4gc3RyaW5nIGFuZCByZXR1cm5zIGZhbHNlIG90aGVyd2lzZS4KKyAgYm9vbCBWYWxpZGF0ZShzdHJpbmcqIGVycm9yKTsKKworICB2b2lkIEdlbmVyYXRlKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworICAvLyBJZiB3ZSBhcmVuJ3QgcHV0dGluZyBldmVyeXRoaW5nIGludG8gb25lIGZpbGUsIHRoaXMgd2lsbCB3cml0ZSBhbGwgdGhlCisgIC8vIGZpbGVzIG90aGVyIHRoYW4gdGhlIG91dGVyIGZpbGUgKGkuZS4gb25lIGZvciBlYWNoIG1lc3NhZ2UsIGVudW0sIGFuZAorICAvLyBzZXJ2aWNlIHR5cGUpLgorICB2b2lkIEdlbmVyYXRlU2libGluZ3MoY29uc3Qgc3RyaW5nJiBwYWNrYWdlX2RpciwKKyAgICAgICAgICAgICAgICAgICAgICAgIEdlbmVyYXRvckNvbnRleHQqIGdlbmVyYXRvcl9jb250ZXh0LAorICAgICAgICAgICAgICAgICAgICAgICAgdmVjdG9yPHN0cmluZz4qIGZpbGVfbGlzdCk7CisKKyAgY29uc3Qgc3RyaW5nJiBqYXZhX3BhY2thZ2UoKSB7IHJldHVybiBqYXZhX3BhY2thZ2VfOyB9CisgIGNvbnN0IHN0cmluZyYgY2xhc3NuYW1lKCkgICAgeyByZXR1cm4gY2xhc3NuYW1lXzsgICAgfQorCisKKyBwcml2YXRlOgorICB2b2lkIEdlbmVyYXRlRGVzY3JpcHRvckluaXRpYWxpemF0aW9uQ29kZUZvckltbXV0YWJsZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZvaWQgR2VuZXJhdGVEZXNjcmlwdG9ySW5pdGlhbGl6YXRpb25Db2RlRm9yTXV0YWJsZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyAgYm9vbCBTaG91bGRJbmNsdWRlRGVwZW5kZW5jeShjb25zdCBGaWxlRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGltbXV0YWJsZV9hcGlfKTsKKworICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZV87CisgIHN0cmluZyBqYXZhX3BhY2thZ2VfOworICBzdHJpbmcgY2xhc3NuYW1lXzsKKworICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfYXJyYXk8Z29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxNZXNzYWdlR2VuZXJhdG9yPiA+IG1lc3NhZ2VfZ2VuZXJhdG9yc187CisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9hcnJheTxnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPEV4dGVuc2lvbkdlbmVyYXRvcj4gPiBleHRlbnNpb25fZ2VuZXJhdG9yc187CisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8R2VuZXJhdG9yRmFjdG9yeT4gZ2VuZXJhdG9yX2ZhY3RvcnlfOworICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPENvbnRleHQ+IGNvbnRleHRfOworICBDbGFzc05hbWVSZXNvbHZlciogbmFtZV9yZXNvbHZlcl87CisgIGJvb2wgaW1tdXRhYmxlX2FwaV87CisKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoRmlsZUdlbmVyYXRvcik7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgamF2YQorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9GSUxFX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZ2VuZXJhdG9yLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZ2VuZXJhdG9yLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZjNmY3MjgKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9nZW5lcmF0b3IuY2MKQEAgLTAsMCArMSwxNjUgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZ2VuZXJhdG9yLmg+CisKKyNpbmNsdWRlIDxtZW1vcnk+CisjaWZuZGVmIF9TSEFSRURfUFRSX0gKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc2hhcmVkX3B0ci5oPgorI2VuZGlmCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2ZpbGUuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2dlbmVyYXRvcl9mYWN0b3J5Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9zaGFyZWRfY29kZV9nZW5lcmF0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmEgeworCisKK0phdmFHZW5lcmF0b3I6OkphdmFHZW5lcmF0b3IoKSB7fQorSmF2YUdlbmVyYXRvcjo6fkphdmFHZW5lcmF0b3IoKSB7fQorCitib29sIEphdmFHZW5lcmF0b3I6OkdlbmVyYXRlKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHBhcmFtZXRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2VuZXJhdG9yQ29udGV4dCogY29udGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nKiBlcnJvcikgY29uc3QgeworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAvLyBwYXJzZSBnZW5lcmF0b3Igb3B0aW9ucworCisgIC8vIE5hbWUgYSBmaWxlIHdoZXJlIHdlIHdpbGwgd3JpdGUgYSBsaXN0IG9mIGdlbmVyYXRlZCBmaWxlIG5hbWVzLCBvbmUKKyAgLy8gcGVyIGxpbmUuCisgIHN0cmluZyBvdXRwdXRfbGlzdF9maWxlOworCisKKyAgdmVjdG9yPHBhaXI8c3RyaW5nLCBzdHJpbmc+ID4gb3B0aW9uczsKKyAgUGFyc2VHZW5lcmF0b3JQYXJhbWV0ZXIocGFyYW1ldGVyLCAmb3B0aW9ucyk7CisKKyAgYm9vbCBnZW5lcmF0ZV9pbW11dGFibGVfY29kZSA9IGZhbHNlOworICBib29sIGdlbmVyYXRlX211dGFibGVfY29kZSA9IGZhbHNlOworICBib29sIGdlbmVyYXRlX3NoYXJlZF9jb2RlID0gZmFsc2U7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgb3B0aW9ucy5zaXplKCk7IGkrKykgeworICAgIGlmIChvcHRpb25zW2ldLmZpcnN0ID09ICJvdXRwdXRfbGlzdF9maWxlIikgeworICAgICAgb3V0cHV0X2xpc3RfZmlsZSA9IG9wdGlvbnNbaV0uc2Vjb25kOworICAgIH0gZWxzZSBpZiAob3B0aW9uc1tpXS5maXJzdCA9PSAiaW1tdXRhYmxlIikgeworICAgICAgZ2VuZXJhdGVfaW1tdXRhYmxlX2NvZGUgPSB0cnVlOworICAgIH0gZWxzZSBpZiAob3B0aW9uc1tpXS5maXJzdCA9PSAibXV0YWJsZSIpIHsKKyAgICAgIGdlbmVyYXRlX211dGFibGVfY29kZSA9IHRydWU7CisgICAgfSBlbHNlIGlmIChvcHRpb25zW2ldLmZpcnN0ID09ICJzaGFyZWQiKSB7CisgICAgICBnZW5lcmF0ZV9zaGFyZWRfY29kZSA9IHRydWU7CisgICAgfSBlbHNlIHsKKyAgICAgICplcnJvciA9ICJVbmtub3duIGdlbmVyYXRvciBvcHRpb246ICIgKyBvcHRpb25zW2ldLmZpcnN0OworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgfQorCisgIC8vIEJ5IGRlZmF1bHQgd2UgZ2VuZXJhdGUgaW1tdXRhYmxlIGNvZGUgYW5kIHNoYXJlZCBjb2RlIGZvciBpbW11dGFibGUgQVBJLgorICBpZiAoIWdlbmVyYXRlX2ltbXV0YWJsZV9jb2RlICYmICFnZW5lcmF0ZV9tdXRhYmxlX2NvZGUgJiYKKyAgICAgICFnZW5lcmF0ZV9zaGFyZWRfY29kZSkgeworICAgIGdlbmVyYXRlX2ltbXV0YWJsZV9jb2RlID0gdHJ1ZTsKKyAgICBnZW5lcmF0ZV9zaGFyZWRfY29kZSA9IHRydWU7CisgIH0KKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisKKyAgdmVjdG9yPHN0cmluZz4gYWxsX2ZpbGVzOworCisKKyAgdmVjdG9yPEZpbGVHZW5lcmF0b3IqPiBmaWxlX2dlbmVyYXRvcnM7CisgIGlmIChnZW5lcmF0ZV9pbW11dGFibGVfY29kZSkgeworICAgIGZpbGVfZ2VuZXJhdG9ycy5wdXNoX2JhY2sobmV3IEZpbGVHZW5lcmF0b3IoZmlsZSwgLyogaW1tdXRhYmxlID0gKi8gdHJ1ZSkpOworICB9CisgIGlmIChnZW5lcmF0ZV9tdXRhYmxlX2NvZGUpIHsKKyAgICBmaWxlX2dlbmVyYXRvcnMucHVzaF9iYWNrKG5ldyBGaWxlR2VuZXJhdG9yKGZpbGUsIC8qIG11dGFibGUgPSAqLyBmYWxzZSkpOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV9nZW5lcmF0b3JzLnNpemUoKTsgKytpKSB7CisgICAgaWYgKCFmaWxlX2dlbmVyYXRvcnNbaV0tPlZhbGlkYXRlKGVycm9yKSkgeworICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBmaWxlX2dlbmVyYXRvcnMuc2l6ZSgpOyArK2opIHsKKyAgICAgICAgZGVsZXRlIGZpbGVfZ2VuZXJhdG9yc1tqXTsKKyAgICAgIH0KKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfZ2VuZXJhdG9ycy5zaXplKCk7ICsraSkgeworICAgIEZpbGVHZW5lcmF0b3IqIGZpbGVfZ2VuZXJhdG9yID0gZmlsZV9nZW5lcmF0b3JzW2ldOworCisgICAgc3RyaW5nIHBhY2thZ2VfZGlyID0gSmF2YVBhY2thZ2VUb0RpcihmaWxlX2dlbmVyYXRvci0+amF2YV9wYWNrYWdlKCkpOworCisgICAgc3RyaW5nIGphdmFfZmlsZW5hbWUgPSBwYWNrYWdlX2RpcjsKKyAgICBqYXZhX2ZpbGVuYW1lICs9IGZpbGVfZ2VuZXJhdG9yLT5jbGFzc25hbWUoKTsKKyAgICBqYXZhX2ZpbGVuYW1lICs9ICIuamF2YSI7CisgICAgYWxsX2ZpbGVzLnB1c2hfYmFjayhqYXZhX2ZpbGVuYW1lKTsKKworICAgIC8vIEdlbmVyYXRlIG1haW4gamF2YSBmaWxlLgorICAgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8aW86Olplcm9Db3B5T3V0cHV0U3RyZWFtPiBvdXRwdXQoCisgICAgICAgIGNvbnRleHQtPk9wZW4oamF2YV9maWxlbmFtZSkpOworICAgIGlvOjpQcmludGVyIHByaW50ZXIob3V0cHV0LmdldCgpLCAnJCcpOworICAgIGZpbGVfZ2VuZXJhdG9yLT5HZW5lcmF0ZSgmcHJpbnRlcik7CisKKyAgICAvLyBHZW5lcmF0ZSBzaWJsaW5nIGZpbGVzLgorICAgIGZpbGVfZ2VuZXJhdG9yLT5HZW5lcmF0ZVNpYmxpbmdzKHBhY2thZ2VfZGlyLCBjb250ZXh0LCAmYWxsX2ZpbGVzKTsKKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV9nZW5lcmF0b3JzLnNpemUoKTsgKytpKSB7CisgICAgZGVsZXRlIGZpbGVfZ2VuZXJhdG9yc1tpXTsKKyAgfQorICBmaWxlX2dlbmVyYXRvcnMuY2xlYXIoKTsKKworICAvLyBHZW5lcmF0ZSBvdXRwdXQgbGlzdCBpZiByZXF1ZXN0ZWQuCisgIGlmICghb3V0cHV0X2xpc3RfZmlsZS5lbXB0eSgpKSB7CisgICAgLy8gR2VuZXJhdGUgb3V0cHV0IGxpc3QuICBUaGlzIGlzIGp1c3QgYSBzaW1wbGUgdGV4dCBmaWxlIHBsYWNlZCBpbiBhCisgICAgLy8gZGV0ZXJtaW5pc3RpYyBsb2NhdGlvbiB3aGljaCBsaXN0cyB0aGUgLmphdmEgZmlsZXMgYmVpbmcgZ2VuZXJhdGVkLgorICAgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8aW86Olplcm9Db3B5T3V0cHV0U3RyZWFtPiBzcmNsaXN0X3Jhd19vdXRwdXQoCisgICAgICAgIGNvbnRleHQtPk9wZW4ob3V0cHV0X2xpc3RfZmlsZSkpOworICAgIGlvOjpQcmludGVyIHNyY2xpc3RfcHJpbnRlcihzcmNsaXN0X3Jhd19vdXRwdXQuZ2V0KCksICckJyk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhbGxfZmlsZXMuc2l6ZSgpOyBpKyspIHsKKyAgICAgIHNyY2xpc3RfcHJpbnRlci5QcmludCgiJGZpbGVuYW1lJFxuIiwgImZpbGVuYW1lIiwgYWxsX2ZpbGVzW2ldKTsKKyAgICB9CisgIH0KKworICByZXR1cm4gdHJ1ZTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9nZW5lcmF0b3IuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2dlbmVyYXRvci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ3Zjc2YmUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9nZW5lcmF0b3IuaApAQCAtMCwwICsxLDcyIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisvLworLy8gR2VuZXJhdGVzIEphdmEgY29kZSBmb3IgYSBnaXZlbiAucHJvdG8gZmlsZS4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9HRU5FUkFUT1JfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX0dFTkVSQVRPUl9IX18KKworI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY29kZV9nZW5lcmF0b3IuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhIHsKKworLy8gQ29kZUdlbmVyYXRvciBpbXBsZW1lbnRhdGlvbiB3aGljaCBnZW5lcmF0ZXMgSmF2YSBjb2RlLiAgSWYgeW91IGNyZWF0ZSB5b3VyCisvLyBvd24gcHJvdG9jb2wgY29tcGlsZXIgYmluYXJ5IGFuZCB5b3Ugd2FudCBpdCB0byBzdXBwb3J0IEphdmEgb3V0cHV0LCB5b3UKKy8vIGNhbiBkbyBzbyBieSByZWdpc3RlcmluZyBhbiBpbnN0YW5jZSBvZiB0aGlzIENvZGVHZW5lcmF0b3Igd2l0aCB0aGUKKy8vIENvbW1hbmRMaW5lSW50ZXJmYWNlIGluIHlvdXIgbWFpbigpIGZ1bmN0aW9uLgorY2xhc3MgTElCUFJPVE9DX0VYUE9SVCBKYXZhR2VuZXJhdG9yIDogcHVibGljIENvZGVHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgSmF2YUdlbmVyYXRvcigpOworICB+SmF2YUdlbmVyYXRvcigpOworCisgIC8vIGltcGxlbWVudHMgQ29kZUdlbmVyYXRvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIGJvb2wgR2VuZXJhdGUoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUsCisgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBwYXJhbWV0ZXIsCisgICAgICAgICAgICAgICAgR2VuZXJhdG9yQ29udGV4dCogY29udGV4dCwKKyAgICAgICAgICAgICAgICBzdHJpbmcqIGVycm9yKSBjb25zdDsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhKYXZhR2VuZXJhdG9yKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX0dFTkVSQVRPUl9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2dlbmVyYXRvcl9mYWN0b3J5LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZ2VuZXJhdG9yX2ZhY3RvcnkuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTJlZjg1MQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2dlbmVyYXRvcl9mYWN0b3J5LmNjCkBAIC0wLDAgKzEsODMgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGxpdWppc2lAZ29vZ2xlLmNvbSAoUGhlcmwgTGl1KQorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9nZW5lcmF0b3JfZmFjdG9yeS5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9jb250ZXh0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9lbnVtX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9leHRlbnNpb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tZXNzYWdlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tZXNzYWdlX2xpdGUuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX3NlcnZpY2UuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhIHsKKworR2VuZXJhdG9yRmFjdG9yeTo6R2VuZXJhdG9yRmFjdG9yeSgpIHt9CitHZW5lcmF0b3JGYWN0b3J5Ojp+R2VuZXJhdG9yRmFjdG9yeSgpIHt9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworSW1tdXRhYmxlR2VuZXJhdG9yRmFjdG9yeTo6SW1tdXRhYmxlR2VuZXJhdG9yRmFjdG9yeSgKKyAgICBDb250ZXh0KiBjb250ZXh0KSA6IGNvbnRleHRfKGNvbnRleHQpIHsKK30KK0ltbXV0YWJsZUdlbmVyYXRvckZhY3Rvcnk6On5JbW11dGFibGVHZW5lcmF0b3JGYWN0b3J5KCkge30KKworTWVzc2FnZUdlbmVyYXRvciogSW1tdXRhYmxlR2VuZXJhdG9yRmFjdG9yeTo6TmV3TWVzc2FnZUdlbmVyYXRvcigKKyAgICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSBjb25zdCB7CisgIGlmIChkZXNjcmlwdG9yLT5maWxlKCktPm9wdGlvbnMoKS5vcHRpbWl6ZV9mb3IoKSA9PQorICAgICAgRmlsZU9wdGlvbnM6OkxJVEVfUlVOVElNRSkgeworICAgIHJldHVybiBuZXcgSW1tdXRhYmxlTWVzc2FnZUxpdGVHZW5lcmF0b3IoZGVzY3JpcHRvciwgY29udGV4dF8pOworICB9IGVsc2UgeworICAgIHJldHVybiBuZXcgSW1tdXRhYmxlTWVzc2FnZUdlbmVyYXRvcihkZXNjcmlwdG9yLCBjb250ZXh0Xyk7CisgIH0KK30KKworRXh0ZW5zaW9uR2VuZXJhdG9yKiBJbW11dGFibGVHZW5lcmF0b3JGYWN0b3J5OjpOZXdFeHRlbnNpb25HZW5lcmF0b3IoCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSBjb25zdCB7CisgIHJldHVybiBuZXcgSW1tdXRhYmxlRXh0ZW5zaW9uR2VuZXJhdG9yKGRlc2NyaXB0b3IsIGNvbnRleHRfKTsKK30KKworU2VydmljZUdlbmVyYXRvciogSW1tdXRhYmxlR2VuZXJhdG9yRmFjdG9yeTo6TmV3U2VydmljZUdlbmVyYXRvcigKKyAgICBjb25zdCBTZXJ2aWNlRGVzY3JpcHRvciogZGVzY3JpcHRvcikgY29uc3QgeworICByZXR1cm4gbmV3IEltbXV0YWJsZVNlcnZpY2VHZW5lcmF0b3IoZGVzY3JpcHRvciwgY29udGV4dF8pOworfQorCisKK30gIC8vIG5hbWVzcGFjZSBqYXZhCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZ2VuZXJhdG9yX2ZhY3RvcnkuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2dlbmVyYXRvcl9mYWN0b3J5LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTUzNjVhOQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2dlbmVyYXRvcl9mYWN0b3J5LmgKQEAgLTAsMCArMSwxMDEgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGxpdWppc2lAZ29vZ2xlLmNvbSAoUGhlcmwgTGl1KQorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX0dFTkVSQVRPUl9GQUNUT1JZX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9HRU5FUkFUT1JfRkFDVE9SWV9IX18KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworICBjbGFzcyBGaWVsZERlc2NyaXB0b3I7ICAgICAgICAgLy8gZGVzY3JpcHRvci5oCisgIGNsYXNzIERlc2NyaXB0b3I7ICAgICAgICAgICAgICAvLyBkZXNjcmlwdG9yLmgKKyAgY2xhc3MgU2VydmljZURlc2NyaXB0b3I7ICAgICAgIC8vIGRlc2NyaXB0b3IuaAorICBuYW1lc3BhY2UgY29tcGlsZXIgeworICAgIG5hbWVzcGFjZSBqYXZhIHsKKyAgICAgIGNsYXNzIE1lc3NhZ2VHZW5lcmF0b3I7ICAgIC8vIG1lc3NhZ2UuaAorICAgICAgY2xhc3MgRXh0ZW5zaW9uR2VuZXJhdG9yOyAgLy8gZXh0ZW5zaW9uLmgKKyAgICAgIGNsYXNzIFNlcnZpY2VHZW5lcmF0b3I7ICAgIC8vIHNlcnZpY2UuaAorICAgICAgY2xhc3MgQ29udGV4dDsgICAgICAgICAgICAgLy8gY29udGV4dC5oCisgICAgfQorICB9Cit9CisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmEgeworCitjbGFzcyBHZW5lcmF0b3JGYWN0b3J5IHsKKyBwdWJsaWM6CisgIEdlbmVyYXRvckZhY3RvcnkoKTsKKyAgdmlydHVhbCB+R2VuZXJhdG9yRmFjdG9yeSgpOworCisgIHZpcnR1YWwgTWVzc2FnZUdlbmVyYXRvciogTmV3TWVzc2FnZUdlbmVyYXRvcigKKyAgICAgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIGNvbnN0ID0gMDsKKworICB2aXJ0dWFsIEV4dGVuc2lvbkdlbmVyYXRvciogTmV3RXh0ZW5zaW9uR2VuZXJhdG9yKAorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSBjb25zdCA9IDA7CisKKyAgdmlydHVhbCBTZXJ2aWNlR2VuZXJhdG9yKiBOZXdTZXJ2aWNlR2VuZXJhdG9yKAorICAgICAgY29uc3QgU2VydmljZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIGNvbnN0ID0gMDsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhHZW5lcmF0b3JGYWN0b3J5KTsKK307CisKKy8vIEZhY3RvcnkgdGhhdCBjcmVhdGVzIGdlbmVyYXRvcnMgZm9yIGltbXV0YWJsZS1kZWZhdWx0IG1lc3NhZ2VzLgorY2xhc3MgSW1tdXRhYmxlR2VuZXJhdG9yRmFjdG9yeSA6IHB1YmxpYyBHZW5lcmF0b3JGYWN0b3J5IHsKKyBwdWJsaWM6CisgIEltbXV0YWJsZUdlbmVyYXRvckZhY3RvcnkoQ29udGV4dCogY29udGV4dCk7CisgIHZpcnR1YWwgfkltbXV0YWJsZUdlbmVyYXRvckZhY3RvcnkoKTsKKworICB2aXJ0dWFsIE1lc3NhZ2VHZW5lcmF0b3IqIE5ld01lc3NhZ2VHZW5lcmF0b3IoCisgICAgICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSBjb25zdDsKKworICB2aXJ0dWFsIEV4dGVuc2lvbkdlbmVyYXRvciogTmV3RXh0ZW5zaW9uR2VuZXJhdG9yKAorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSBjb25zdDsKKworICB2aXJ0dWFsIFNlcnZpY2VHZW5lcmF0b3IqIE5ld1NlcnZpY2VHZW5lcmF0b3IoCisgICAgICBjb25zdCBTZXJ2aWNlRGVzY3JpcHRvciogZGVzY3JpcHRvcikgY29uc3Q7CisKKyBwcml2YXRlOgorICBDb250ZXh0KiBjb250ZXh0XzsKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEltbXV0YWJsZUdlbmVyYXRvckZhY3RvcnkpOworfTsKKworCit9ICAvLyBuYW1lc3BhY2UgamF2YQorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9HRU5FUkFUT1JfRkFDVE9SWV9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2hlbHBlcnMuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9oZWxwZXJzLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUyNDg5NGIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9oZWxwZXJzLmNjCkBAIC0wLDAgKzEsNzU3IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxhbGdvcml0aG0+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2hhc2guaD4KKyNpbmNsdWRlIDxsaW1pdHM+CisjaW5jbHVkZSA8dmVjdG9yPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9uYW1lX3Jlc29sdmVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdWJzdGl0dXRlLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YSB7CisKK3VzaW5nIGludGVybmFsOjpXaXJlRm9ybWF0OwordXNpbmcgaW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOworCitjb25zdCBjaGFyIGtUaGlja1NlcGFyYXRvcltdID0KKyAgIi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiI7Citjb25zdCBjaGFyIGtUaGluU2VwYXJhdG9yW10gPQorICAiLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuIjsKKworbmFtZXNwYWNlIHsKKworY29uc3QgY2hhcioga0RlZmF1bHRQYWNrYWdlID0gIiI7CisKKy8vIE5hbWVzIHRoYXQgc2hvdWxkIGJlIGF2b2lkZWQgYXMgZmllbGQgbmFtZXMuCisvLyBVc2luZyB0aGVtIHdpbGwgY2F1c2UgdGhlIGNvbXBpbGVyIHRvIGdlbmVyYXRlIGFjY2Vzc29ycyB3aG9zZSBuYW1lcyBhcmUKKy8vIGNvbGxpZGluZyB3aXRoIG1ldGhvZHMgZGVmaW5lZCBpbiBiYXNlIGNsYXNzZXMuCitjb25zdCBjaGFyKiBrRm9yYmlkZGVuV29yZExpc3RbXSA9IHsKKyAgLy8gbWVzc2FnZSBiYXNlIGNsYXNzOgorICAiY2FjaGVkX3NpemUiLCAic2VyaWFsaXplZF9zaXplIiwKKyAgLy8gamF2YS5sYW5nLk9iamVjdDoKKyAgImNsYXNzIiwKK307CisKK2Jvb2wgSXNGb3JiaWRkZW4oY29uc3Qgc3RyaW5nJiBmaWVsZF9uYW1lKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgR09PR0xFX0FSUkFZU0laRShrRm9yYmlkZGVuV29yZExpc3QpOyArK2kpIHsKKyAgICBpZiAoZmllbGRfbmFtZSA9PSBrRm9yYmlkZGVuV29yZExpc3RbaV0pIHsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgfQorICByZXR1cm4gZmFsc2U7Cit9CisKK3N0cmluZyBGaWVsZE5hbWUoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICBzdHJpbmcgZmllbGRfbmFtZTsKKyAgLy8gR3JvdXBzIGFyZSBoYWNreTogIFRoZSBuYW1lIG9mIHRoZSBmaWVsZCBpcyBqdXN0IHRoZSBsb3dlci1jYXNlZCBuYW1lCisgIC8vIG9mIHRoZSBncm91cCB0eXBlLiAgSW4gSmF2YSwgdGhvdWdoLCB3ZSB3b3VsZCBsaWtlIHRvIHJldGFpbiB0aGUgb3JpZ2luYWwKKyAgLy8gY2FwaXRhbGl6YXRpb24gb2YgdGhlIHR5cGUgbmFtZS4KKyAgaWYgKEdldFR5cGUoZmllbGQpID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9HUk9VUCkgeworICAgIGZpZWxkX25hbWUgPSBmaWVsZC0+bWVzc2FnZV90eXBlKCktPm5hbWUoKTsKKyAgfSBlbHNlIHsKKyAgICBmaWVsZF9uYW1lID0gZmllbGQtPm5hbWUoKTsKKyAgfQorICBpZiAoSXNGb3JiaWRkZW4oZmllbGRfbmFtZSkpIHsKKyAgICAvLyBBcHBlbmQgYSB0cmFpbGluZyAiIyIgdG8gaW5kaWNhdGUgdGhhdCB0aGUgbmFtZSBzaG91bGQgYmUgZGVjb3JhdGVkIHRvCisgICAgLy8gYXZvaWQgY29sbGlzaW9uIHdpdGggb3RoZXIgbmFtZXMuCisgICAgZmllbGRfbmFtZSArPSAiIyI7CisgIH0KKyAgcmV0dXJuIGZpZWxkX25hbWU7Cit9CisKKworfSAgLy8gbmFtZXNwYWNlCisKK3N0cmluZyBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlKGNvbnN0IHN0cmluZyYgaW5wdXQsIGJvb2wgY2FwX25leHRfbGV0dGVyKSB7CisgIHN0cmluZyByZXN1bHQ7CisgIC8vIE5vdGU6ICBJIGRpc3RydXN0IGN0eXBlLmggZHVlIHRvIGxvY2FsZXMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgaW5wdXQuc2l6ZSgpOyBpKyspIHsKKyAgICBpZiAoJ2EnIDw9IGlucHV0W2ldICYmIGlucHV0W2ldIDw9ICd6JykgeworICAgICAgaWYgKGNhcF9uZXh0X2xldHRlcikgeworICAgICAgICByZXN1bHQgKz0gaW5wdXRbaV0gKyAoJ0EnIC0gJ2EnKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJlc3VsdCArPSBpbnB1dFtpXTsKKyAgICAgIH0KKyAgICAgIGNhcF9uZXh0X2xldHRlciA9IGZhbHNlOworICAgIH0gZWxzZSBpZiAoJ0EnIDw9IGlucHV0W2ldICYmIGlucHV0W2ldIDw9ICdaJykgeworICAgICAgaWYgKGkgPT0gMCAmJiAhY2FwX25leHRfbGV0dGVyKSB7CisgICAgICAgIC8vIEZvcmNlIGZpcnN0IGxldHRlciB0byBsb3dlci1jYXNlIHVubGVzcyBleHBsaWNpdGx5IHRvbGQgdG8KKyAgICAgICAgLy8gY2FwaXRhbGl6ZSBpdC4KKyAgICAgICAgcmVzdWx0ICs9IGlucHV0W2ldICsgKCdhJyAtICdBJyk7CisgICAgICB9IGVsc2UgeworICAgICAgICAvLyBDYXBpdGFsIGxldHRlcnMgYWZ0ZXIgdGhlIGZpcnN0IGFyZSBsZWZ0IGFzLWlzLgorICAgICAgICByZXN1bHQgKz0gaW5wdXRbaV07CisgICAgICB9CisgICAgICBjYXBfbmV4dF9sZXR0ZXIgPSBmYWxzZTsKKyAgICB9IGVsc2UgaWYgKCcwJyA8PSBpbnB1dFtpXSAmJiBpbnB1dFtpXSA8PSAnOScpIHsKKyAgICAgIHJlc3VsdCArPSBpbnB1dFtpXTsKKyAgICAgIGNhcF9uZXh0X2xldHRlciA9IHRydWU7CisgICAgfSBlbHNlIHsKKyAgICAgIGNhcF9uZXh0X2xldHRlciA9IHRydWU7CisgICAgfQorICB9CisgIC8vIEFkZCBhIHRyYWlsaW5nICJfIiBpZiB0aGUgbmFtZSBzaG91bGQgYmUgYWx0ZXJlZC4KKyAgaWYgKGlucHV0W2lucHV0LnNpemUoKSAtIDFdID09ICcjJykgeworICAgIHJlc3VsdCArPSAnXyc7CisgIH0KKyAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RyaW5nIFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICByZXR1cm4gVW5kZXJzY29yZXNUb0NhbWVsQ2FzZShGaWVsZE5hbWUoZmllbGQpLCBmYWxzZSk7Cit9CisKK3N0cmluZyBVbmRlcnNjb3Jlc1RvQ2FwaXRhbGl6ZWRDYW1lbENhc2UoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICByZXR1cm4gVW5kZXJzY29yZXNUb0NhbWVsQ2FzZShGaWVsZE5hbWUoZmllbGQpLCB0cnVlKTsKK30KKworc3RyaW5nIFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoY29uc3QgTWV0aG9kRGVzY3JpcHRvciogbWV0aG9kKSB7CisgIHJldHVybiBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlKG1ldGhvZC0+bmFtZSgpLCBmYWxzZSk7Cit9CisKK3N0cmluZyBVbmlxdWVGaWxlU2NvcGVJZGVudGlmaWVyKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgcmV0dXJuICJzdGF0aWNfIiArIFN0cmluZ1JlcGxhY2UoZGVzY3JpcHRvci0+ZnVsbF9uYW1lKCksICIuIiwgIl8iLCB0cnVlKTsKK30KKworc3RyaW5nIFN0cmlwUHJvdG8oY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSkgeworICBpZiAoSGFzU3VmZml4U3RyaW5nKGZpbGVuYW1lLCAiLnByb3RvZGV2ZWwiKSkgeworICAgIHJldHVybiBTdHJpcFN1ZmZpeFN0cmluZyhmaWxlbmFtZSwgIi5wcm90b2RldmVsIik7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIFN0cmlwU3VmZml4U3RyaW5nKGZpbGVuYW1lLCAiLnByb3RvIik7CisgIH0KK30KKworc3RyaW5nIEZpbGVDbGFzc05hbWUoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUsIGJvb2wgaW1tdXRhYmxlKSB7CisgIENsYXNzTmFtZVJlc29sdmVyIG5hbWVfcmVzb2x2ZXI7CisgIHJldHVybiBuYW1lX3Jlc29sdmVyLkdldEZpbGVDbGFzc05hbWUoZmlsZSwgaW1tdXRhYmxlKTsKK30KKworc3RyaW5nIEZpbGVKYXZhUGFja2FnZShjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSwgYm9vbCBpbW11dGFibGUpIHsKKyAgc3RyaW5nIHJlc3VsdDsKKworICBpZiAoZmlsZS0+b3B0aW9ucygpLmhhc19qYXZhX3BhY2thZ2UoKSkgeworICAgIHJlc3VsdCA9IGZpbGUtPm9wdGlvbnMoKS5qYXZhX3BhY2thZ2UoKTsKKyAgfSBlbHNlIHsKKyAgICByZXN1bHQgPSBrRGVmYXVsdFBhY2thZ2U7CisgICAgaWYgKCFmaWxlLT5wYWNrYWdlKCkuZW1wdHkoKSkgeworICAgICAgaWYgKCFyZXN1bHQuZW1wdHkoKSkgcmVzdWx0ICs9ICcuJzsKKyAgICAgIHJlc3VsdCArPSBmaWxlLT5wYWNrYWdlKCk7CisgICAgfQorICB9CisKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RyaW5nIEphdmFQYWNrYWdlVG9EaXIoc3RyaW5nIHBhY2thZ2VfbmFtZSkgeworICBzdHJpbmcgcGFja2FnZV9kaXIgPQorICAgIFN0cmluZ1JlcGxhY2UocGFja2FnZV9uYW1lLCAiLiIsICIvIiwgdHJ1ZSk7CisgIGlmICghcGFja2FnZV9kaXIuZW1wdHkoKSkgcGFja2FnZV9kaXIgKz0gIi8iOworICByZXR1cm4gcGFja2FnZV9kaXI7Cit9CisKKy8vIFRPRE8oeGlhb2ZlbmcpOiBUaGlzIGZ1bmN0aW9uIGlzIG9ubHkga2VwdCBmb3IgaXQncyBwdWJsaWNseSByZWZlcmVuY2VkLgorLy8gSXQgc2hvdWxkIGJlIHJlbW92ZWQgYWZ0ZXIgbXV0YWJsZSBBUEkgdXAtaW50ZWdyYXRpb24uCitzdHJpbmcgVG9KYXZhTmFtZShjb25zdCBzdHJpbmcmIGZ1bGxfbmFtZSwKKyAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKSB7CisgIHN0cmluZyByZXN1bHQ7CisgIGlmIChmaWxlLT5vcHRpb25zKCkuamF2YV9tdWx0aXBsZV9maWxlcygpKSB7CisgICAgcmVzdWx0ID0gRmlsZUphdmFQYWNrYWdlKGZpbGUpOworICB9IGVsc2UgeworICAgIHJlc3VsdCA9IENsYXNzTmFtZShmaWxlKTsKKyAgfQorICBpZiAoIXJlc3VsdC5lbXB0eSgpKSB7CisgICAgcmVzdWx0ICs9ICcuJzsKKyAgfQorICBpZiAoZmlsZS0+cGFja2FnZSgpLmVtcHR5KCkpIHsKKyAgICByZXN1bHQgKz0gZnVsbF9uYW1lOworICB9IGVsc2UgeworICAgIC8vIFN0cmlwIHRoZSBwcm90byBwYWNrYWdlIGZyb20gZnVsbF9uYW1lIHNpbmNlIHdlJ3ZlIHJlcGxhY2VkIGl0IHdpdGgKKyAgICAvLyB0aGUgSmF2YSBwYWNrYWdlLgorICAgIHJlc3VsdCArPSBmdWxsX25hbWUuc3Vic3RyKGZpbGUtPnBhY2thZ2UoKS5zaXplKCkgKyAxKTsKKyAgfQorICByZXR1cm4gcmVzdWx0OworfQorCitzdHJpbmcgQ2xhc3NOYW1lKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgQ2xhc3NOYW1lUmVzb2x2ZXIgbmFtZV9yZXNvbHZlcjsKKyAgcmV0dXJuIG5hbWVfcmVzb2x2ZXIuR2V0Q2xhc3NOYW1lKGRlc2NyaXB0b3IsIHRydWUpOworfQorCitzdHJpbmcgQ2xhc3NOYW1lKGNvbnN0IEVudW1EZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIENsYXNzTmFtZVJlc29sdmVyIG5hbWVfcmVzb2x2ZXI7CisgIHJldHVybiBuYW1lX3Jlc29sdmVyLkdldENsYXNzTmFtZShkZXNjcmlwdG9yLCB0cnVlKTsKK30KKworc3RyaW5nIENsYXNzTmFtZShjb25zdCBTZXJ2aWNlRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBDbGFzc05hbWVSZXNvbHZlciBuYW1lX3Jlc29sdmVyOworICByZXR1cm4gbmFtZV9yZXNvbHZlci5HZXRDbGFzc05hbWUoZGVzY3JpcHRvciwgdHJ1ZSk7Cit9CisKK3N0cmluZyBDbGFzc05hbWUoY29uc3QgRmlsZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgQ2xhc3NOYW1lUmVzb2x2ZXIgbmFtZV9yZXNvbHZlcjsKKyAgcmV0dXJuIG5hbWVfcmVzb2x2ZXIuR2V0Q2xhc3NOYW1lKGRlc2NyaXB0b3IsIHRydWUpOworfQorCitzdHJpbmcgRXh0cmFNZXNzYWdlSW50ZXJmYWNlcyhjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIHN0cmluZyBpbnRlcmZhY2VzID0gIi8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6IgorICAgICAgKyBkZXNjcmlwdG9yLT5mdWxsX25hbWUoKSArICIpIjsKKyAgcmV0dXJuIGludGVyZmFjZXM7Cit9CisKKworc3RyaW5nIEV4dHJhQnVpbGRlckludGVyZmFjZXMoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBzdHJpbmcgaW50ZXJmYWNlcyA9ICIvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOiIKKyAgICAgICsgZGVzY3JpcHRvci0+ZnVsbF9uYW1lKCkgKyAiKSI7CisgIHJldHVybiBpbnRlcmZhY2VzOworfQorCitzdHJpbmcgRXh0cmFNZXNzYWdlT3JCdWlsZGVySW50ZXJmYWNlcyhjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIHN0cmluZyBpbnRlcmZhY2VzID0gIi8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczoiCisgICAgICArIGRlc2NyaXB0b3ItPmZ1bGxfbmFtZSgpICsgIikiOworICByZXR1cm4gaW50ZXJmYWNlczsKK30KKworc3RyaW5nIEZpZWxkQ29uc3RhbnROYW1lKGNvbnN0IEZpZWxkRGVzY3JpcHRvciAqZmllbGQpIHsKKyAgc3RyaW5nIG5hbWUgPSBmaWVsZC0+bmFtZSgpICsgIl9GSUVMRF9OVU1CRVIiOworICBVcHBlclN0cmluZygmbmFtZSk7CisgIHJldHVybiBuYW1lOworfQorCitGaWVsZERlc2NyaXB0b3I6OlR5cGUgR2V0VHlwZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIHJldHVybiBmaWVsZC0+dHlwZSgpOworfQorCitKYXZhVHlwZSBHZXRKYXZhVHlwZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIHN3aXRjaCAoR2V0VHlwZShmaWVsZCkpIHsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9JTlQzMjoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9VSU5UMzI6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0lOVDMyOgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0ZJWEVEMzI6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0ZJWEVEMzI6CisgICAgICByZXR1cm4gSkFWQVRZUEVfSU5UOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfSU5UNjQ6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfVUlOVDY0OgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NJTlQ2NDoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9GSVhFRDY0OgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NGSVhFRDY0OgorICAgICAgcmV0dXJuIEpBVkFUWVBFX0xPTkc7CisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9GTE9BVDoKKyAgICAgIHJldHVybiBKQVZBVFlQRV9GTE9BVDsKKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0RPVUJMRToKKyAgICAgIHJldHVybiBKQVZBVFlQRV9ET1VCTEU7CisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9CT09MOgorICAgICAgcmV0dXJuIEpBVkFUWVBFX0JPT0xFQU47CisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TVFJJTkc6CisgICAgICByZXR1cm4gSkFWQVRZUEVfU1RSSU5HOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfQllURVM6CisgICAgICByZXR1cm4gSkFWQVRZUEVfQllURVM7CisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9FTlVNOgorICAgICAgcmV0dXJuIEpBVkFUWVBFX0VOVU07CisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9HUk9VUDoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9NRVNTQUdFOgorICAgICAgcmV0dXJuIEpBVkFUWVBFX01FU1NBR0U7CisKKyAgICAvLyBObyBkZWZhdWx0IGJlY2F1c2Ugd2Ugd2FudCB0aGUgY29tcGlsZXIgdG8gY29tcGxhaW4gaWYgYW55IG5ldworICAgIC8vIHR5cGVzIGFyZSBhZGRlZC4KKyAgfQorCisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJDYW4ndCBnZXQgaGVyZS4iOworICByZXR1cm4gSkFWQVRZUEVfSU5UOworfQorCitjb25zdCBjaGFyKiBQcmltaXRpdmVUeXBlTmFtZShKYXZhVHlwZSB0eXBlKSB7CisgIHN3aXRjaCAodHlwZSkgeworICAgIGNhc2UgSkFWQVRZUEVfSU5UICAgIDogcmV0dXJuICJpbnQiOworICAgIGNhc2UgSkFWQVRZUEVfTE9ORyAgIDogcmV0dXJuICJsb25nIjsKKyAgICBjYXNlIEpBVkFUWVBFX0ZMT0FUICA6IHJldHVybiAiZmxvYXQiOworICAgIGNhc2UgSkFWQVRZUEVfRE9VQkxFIDogcmV0dXJuICJkb3VibGUiOworICAgIGNhc2UgSkFWQVRZUEVfQk9PTEVBTjogcmV0dXJuICJib29sZWFuIjsKKyAgICBjYXNlIEpBVkFUWVBFX1NUUklORyA6IHJldHVybiAiamF2YS5sYW5nLlN0cmluZyI7CisgICAgY2FzZSBKQVZBVFlQRV9CWVRFUyAgOiByZXR1cm4gImNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyI7CisgICAgY2FzZSBKQVZBVFlQRV9FTlVNICAgOiByZXR1cm4gTlVMTDsKKyAgICBjYXNlIEpBVkFUWVBFX01FU1NBR0U6IHJldHVybiBOVUxMOworCisgICAgLy8gTm8gZGVmYXVsdCBiZWNhdXNlIHdlIHdhbnQgdGhlIGNvbXBpbGVyIHRvIGNvbXBsYWluIGlmIGFueSBuZXcKKyAgICAvLyBKYXZhVHlwZXMgYXJlIGFkZGVkLgorICB9CisKKyAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkNhbid0IGdldCBoZXJlLiI7CisgIHJldHVybiBOVUxMOworfQorCitjb25zdCBjaGFyKiBCb3hlZFByaW1pdGl2ZVR5cGVOYW1lKEphdmFUeXBlIHR5cGUpIHsKKyAgc3dpdGNoICh0eXBlKSB7CisgICAgY2FzZSBKQVZBVFlQRV9JTlQgICAgOiByZXR1cm4gImphdmEubGFuZy5JbnRlZ2VyIjsKKyAgICBjYXNlIEpBVkFUWVBFX0xPTkcgICA6IHJldHVybiAiamF2YS5sYW5nLkxvbmciOworICAgIGNhc2UgSkFWQVRZUEVfRkxPQVQgIDogcmV0dXJuICJqYXZhLmxhbmcuRmxvYXQiOworICAgIGNhc2UgSkFWQVRZUEVfRE9VQkxFIDogcmV0dXJuICJqYXZhLmxhbmcuRG91YmxlIjsKKyAgICBjYXNlIEpBVkFUWVBFX0JPT0xFQU46IHJldHVybiAiamF2YS5sYW5nLkJvb2xlYW4iOworICAgIGNhc2UgSkFWQVRZUEVfU1RSSU5HIDogcmV0dXJuICJqYXZhLmxhbmcuU3RyaW5nIjsKKyAgICBjYXNlIEpBVkFUWVBFX0JZVEVTICA6IHJldHVybiAiY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIjsKKyAgICBjYXNlIEpBVkFUWVBFX0VOVU0gICA6IHJldHVybiBOVUxMOworICAgIGNhc2UgSkFWQVRZUEVfTUVTU0FHRTogcmV0dXJuIE5VTEw7CisKKyAgICAvLyBObyBkZWZhdWx0IGJlY2F1c2Ugd2Ugd2FudCB0aGUgY29tcGlsZXIgdG8gY29tcGxhaW4gaWYgYW55IG5ldworICAgIC8vIEphdmFUeXBlcyBhcmUgYWRkZWQuCisgIH0KKworICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ2FuJ3QgZ2V0IGhlcmUuIjsKKyAgcmV0dXJuIE5VTEw7Cit9CisKK2NvbnN0IGNoYXIqIEZpZWxkVHlwZU5hbWUoRmllbGREZXNjcmlwdG9yOjpUeXBlIGZpZWxkX3R5cGUpIHsKKyAgc3dpdGNoIChmaWVsZF90eXBlKSB7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfSU5UMzIgICA6IHJldHVybiAiSU5UMzIiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1VJTlQzMiAgOiByZXR1cm4gIlVJTlQzMiI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0lOVDMyICA6IHJldHVybiAiU0lOVDMyIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9GSVhFRDMyIDogcmV0dXJuICJGSVhFRDMyIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TRklYRUQzMjogcmV0dXJuICJTRklYRUQzMiI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfSU5UNjQgICA6IHJldHVybiAiSU5UNjQiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1VJTlQ2NCAgOiByZXR1cm4gIlVJTlQ2NCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0lOVDY0ICA6IHJldHVybiAiU0lOVDY0IjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9GSVhFRDY0IDogcmV0dXJuICJGSVhFRDY0IjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TRklYRUQ2NDogcmV0dXJuICJTRklYRUQ2NCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRkxPQVQgICA6IHJldHVybiAiRkxPQVQiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0RPVUJMRSAgOiByZXR1cm4gIkRPVUJMRSI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfQk9PTCAgICA6IHJldHVybiAiQk9PTCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU1RSSU5HICA6IHJldHVybiAiU1RSSU5HIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9CWVRFUyAgIDogcmV0dXJuICJCWVRFUyI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRU5VTSAgICA6IHJldHVybiAiRU5VTSI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfR1JPVVAgICA6IHJldHVybiAiR1JPVVAiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX01FU1NBR0UgOiByZXR1cm4gIk1FU1NBR0UiOworCisgICAgLy8gTm8gZGVmYXVsdCBiZWNhdXNlIHdlIHdhbnQgdGhlIGNvbXBpbGVyIHRvIGNvbXBsYWluIGlmIGFueSBuZXcKKyAgICAvLyB0eXBlcyBhcmUgYWRkZWQuCisgIH0KKworICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ2FuJ3QgZ2V0IGhlcmUuIjsKKyAgcmV0dXJuIE5VTEw7Cit9CisKK2Jvb2wgQWxsQXNjaWkoY29uc3Qgc3RyaW5nJiB0ZXh0KSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGV4dC5zaXplKCk7IGkrKykgeworICAgIGlmICgodGV4dFtpXSAmIDB4ODApICE9IDApIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKK3N0cmluZyBEZWZhdWx0VmFsdWUoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgYm9vbCBpbW11dGFibGUsCisgICAgICAgICAgICAgICAgICAgIENsYXNzTmFtZVJlc29sdmVyKiBuYW1lX3Jlc29sdmVyKSB7CisgIC8vIFN3aXRjaCBvbiBDcHBUeXBlIHNpbmNlIHdlIG5lZWQgdG8ga25vdyB3aGljaCBkZWZhdWx0X3ZhbHVlXyogbWV0aG9kCisgIC8vIG9mIEZpZWxkRGVzY3JpcHRvciB0byBjYWxsLgorICBzd2l0Y2ggKGZpZWxkLT5jcHBfdHlwZSgpKSB7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UMzI6CisgICAgICByZXR1cm4gU2ltcGxlSXRvYShmaWVsZC0+ZGVmYXVsdF92YWx1ZV9pbnQzMigpKTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9VSU5UMzI6CisgICAgICAvLyBOZWVkIHRvIHByaW50IGFzIGEgc2lnbmVkIGludCBzaW5jZSBKYXZhIGhhcyBubyB1bnNpZ25lZC4KKyAgICAgIHJldHVybiBTaW1wbGVJdG9hKHN0YXRpY19jYXN0PGludDMyPihmaWVsZC0+ZGVmYXVsdF92YWx1ZV91aW50MzIoKSkpOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0lOVDY0OgorICAgICAgcmV0dXJuIFNpbXBsZUl0b2EoZmllbGQtPmRlZmF1bHRfdmFsdWVfaW50NjQoKSkgKyAiTCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDY0OgorICAgICAgcmV0dXJuIFNpbXBsZUl0b2Eoc3RhdGljX2Nhc3Q8aW50NjQ+KGZpZWxkLT5kZWZhdWx0X3ZhbHVlX3VpbnQ2NCgpKSkgKworICAgICAgICAgICAgICJMIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9ET1VCTEU6IHsKKyAgICAgIGRvdWJsZSB2YWx1ZSA9IGZpZWxkLT5kZWZhdWx0X3ZhbHVlX2RvdWJsZSgpOworICAgICAgaWYgKHZhbHVlID09IG51bWVyaWNfbGltaXRzPGRvdWJsZT46OmluZmluaXR5KCkpIHsKKyAgICAgICAgcmV0dXJuICJEb3VibGUuUE9TSVRJVkVfSU5GSU5JVFkiOworICAgICAgfSBlbHNlIGlmICh2YWx1ZSA9PSAtbnVtZXJpY19saW1pdHM8ZG91YmxlPjo6aW5maW5pdHkoKSkgeworICAgICAgICByZXR1cm4gIkRvdWJsZS5ORUdBVElWRV9JTkZJTklUWSI7CisgICAgICB9IGVsc2UgaWYgKHZhbHVlICE9IHZhbHVlKSB7CisgICAgICAgIHJldHVybiAiRG91YmxlLk5hTiI7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gU2ltcGxlRHRvYSh2YWx1ZSkgKyAiRCI7CisgICAgICB9CisgICAgfQorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0ZMT0FUOiB7CisgICAgICBmbG9hdCB2YWx1ZSA9IGZpZWxkLT5kZWZhdWx0X3ZhbHVlX2Zsb2F0KCk7CisgICAgICBpZiAodmFsdWUgPT0gbnVtZXJpY19saW1pdHM8ZmxvYXQ+OjppbmZpbml0eSgpKSB7CisgICAgICAgIHJldHVybiAiRmxvYXQuUE9TSVRJVkVfSU5GSU5JVFkiOworICAgICAgfSBlbHNlIGlmICh2YWx1ZSA9PSAtbnVtZXJpY19saW1pdHM8ZmxvYXQ+OjppbmZpbml0eSgpKSB7CisgICAgICAgIHJldHVybiAiRmxvYXQuTkVHQVRJVkVfSU5GSU5JVFkiOworICAgICAgfSBlbHNlIGlmICh2YWx1ZSAhPSB2YWx1ZSkgeworICAgICAgICByZXR1cm4gIkZsb2F0Lk5hTiI7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gU2ltcGxlRnRvYSh2YWx1ZSkgKyAiRiI7CisgICAgICB9CisgICAgfQorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0JPT0w6CisgICAgICByZXR1cm4gZmllbGQtPmRlZmF1bHRfdmFsdWVfYm9vbCgpID8gInRydWUiIDogImZhbHNlIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9TVFJJTkc6CisgICAgICBpZiAoR2V0VHlwZShmaWVsZCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX0JZVEVTKSB7CisgICAgICAgIGlmIChmaWVsZC0+aGFzX2RlZmF1bHRfdmFsdWUoKSkgeworICAgICAgICAgIC8vIFNlZSBjb21tZW50cyBpbiBJbnRlcm5hbC5qYXZhIGZvciBnb3J5IGRldGFpbHMuCisgICAgICAgICAgcmV0dXJuIHN0cmluZ3M6OlN1YnN0aXR1dGUoCisgICAgICAgICAgICAiY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5ieXRlc0RlZmF1bHRWYWx1ZShcIiQwXCIpIiwKKyAgICAgICAgICAgIENFc2NhcGUoZmllbGQtPmRlZmF1bHRfdmFsdWVfc3RyaW5nKCkpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICByZXR1cm4gImNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWSI7CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGlmIChBbGxBc2NpaShmaWVsZC0+ZGVmYXVsdF92YWx1ZV9zdHJpbmcoKSkpIHsKKyAgICAgICAgICAvLyBBbGwgY2hhcnMgYXJlIEFTQ0lJLiAgSW4gdGhpcyBjYXNlIENFc2NhcGUoKSB3b3JrcyBmaW5lLgorICAgICAgICAgIHJldHVybiAiXCIiICsgQ0VzY2FwZShmaWVsZC0+ZGVmYXVsdF92YWx1ZV9zdHJpbmcoKSkgKyAiXCIiOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIC8vIFNlZSBjb21tZW50cyBpbiBJbnRlcm5hbC5qYXZhIGZvciBnb3J5IGRldGFpbHMuCisgICAgICAgICAgcmV0dXJuIHN0cmluZ3M6OlN1YnN0aXR1dGUoCisgICAgICAgICAgICAgICJjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLnN0cmluZ0RlZmF1bHRWYWx1ZShcIiQwXCIpIiwKKyAgICAgICAgICAgICAgQ0VzY2FwZShmaWVsZC0+ZGVmYXVsdF92YWx1ZV9zdHJpbmcoKSkpOworICAgICAgICB9CisgICAgICB9CisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9FTlVNOgorICAgICAgcmV0dXJuIG5hbWVfcmVzb2x2ZXItPkdldENsYXNzTmFtZShmaWVsZC0+ZW51bV90eXBlKCksIGltbXV0YWJsZSkgKyAiLiIgKworICAgICAgICAgIGZpZWxkLT5kZWZhdWx0X3ZhbHVlX2VudW0oKS0+bmFtZSgpOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRToKKyAgICAgIHJldHVybiBuYW1lX3Jlc29sdmVyLT5HZXRDbGFzc05hbWUoZmllbGQtPm1lc3NhZ2VfdHlwZSgpLCBpbW11dGFibGUpICsKKyAgICAgICAgICAiLmdldERlZmF1bHRJbnN0YW5jZSgpIjsKKworICAgIC8vIE5vIGRlZmF1bHQgYmVjYXVzZSB3ZSB3YW50IHRoZSBjb21waWxlciB0byBjb21wbGFpbiBpZiBhbnkgbmV3CisgICAgLy8gdHlwZXMgYXJlIGFkZGVkLgorICB9CisKKyAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkNhbid0IGdldCBoZXJlLiI7CisgIHJldHVybiAiIjsKK30KKworYm9vbCBJc0RlZmF1bHRWYWx1ZUphdmFEZWZhdWx0KGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgLy8gU3dpdGNoIG9uIENwcFR5cGUgc2luY2Ugd2UgbmVlZCB0byBrbm93IHdoaWNoIGRlZmF1bHRfdmFsdWVfKiBtZXRob2QKKyAgLy8gb2YgRmllbGREZXNjcmlwdG9yIHRvIGNhbGwuCisgIHN3aXRjaCAoZmllbGQtPmNwcF90eXBlKCkpIHsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9JTlQzMjoKKyAgICAgIHJldHVybiBmaWVsZC0+ZGVmYXVsdF92YWx1ZV9pbnQzMigpID09IDA7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDMyOgorICAgICAgcmV0dXJuIGZpZWxkLT5kZWZhdWx0X3ZhbHVlX3VpbnQzMigpID09IDA7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UNjQ6CisgICAgICByZXR1cm4gZmllbGQtPmRlZmF1bHRfdmFsdWVfaW50NjQoKSA9PSAwTDsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9VSU5UNjQ6CisgICAgICByZXR1cm4gZmllbGQtPmRlZmF1bHRfdmFsdWVfdWludDY0KCkgPT0gMEw7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRE9VQkxFOgorICAgICAgcmV0dXJuIGZpZWxkLT5kZWZhdWx0X3ZhbHVlX2RvdWJsZSgpID09IDAuMDsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9GTE9BVDoKKyAgICAgIHJldHVybiBmaWVsZC0+ZGVmYXVsdF92YWx1ZV9mbG9hdCgpID09IDAuMDsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9CT09MOgorICAgICAgcmV0dXJuIGZpZWxkLT5kZWZhdWx0X3ZhbHVlX2Jvb2woKSA9PSBmYWxzZTsKKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORzoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9FTlVNOgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U6CisgICAgICByZXR1cm4gZmFsc2U7CisKKyAgICAvLyBObyBkZWZhdWx0IGJlY2F1c2Ugd2Ugd2FudCB0aGUgY29tcGlsZXIgdG8gY29tcGxhaW4gaWYgYW55IG5ldworICAgIC8vIHR5cGVzIGFyZSBhZGRlZC4KKyAgfQorCisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJDYW4ndCBnZXQgaGVyZS4iOworICByZXR1cm4gZmFsc2U7Cit9CisKK2NvbnN0IGNoYXIqIGJpdF9tYXNrc1tdID0geworICAiMHgwMDAwMDAwMSIsCisgICIweDAwMDAwMDAyIiwKKyAgIjB4MDAwMDAwMDQiLAorICAiMHgwMDAwMDAwOCIsCisgICIweDAwMDAwMDEwIiwKKyAgIjB4MDAwMDAwMjAiLAorICAiMHgwMDAwMDA0MCIsCisgICIweDAwMDAwMDgwIiwKKworICAiMHgwMDAwMDEwMCIsCisgICIweDAwMDAwMjAwIiwKKyAgIjB4MDAwMDA0MDAiLAorICAiMHgwMDAwMDgwMCIsCisgICIweDAwMDAxMDAwIiwKKyAgIjB4MDAwMDIwMDAiLAorICAiMHgwMDAwNDAwMCIsCisgICIweDAwMDA4MDAwIiwKKworICAiMHgwMDAxMDAwMCIsCisgICIweDAwMDIwMDAwIiwKKyAgIjB4MDAwNDAwMDAiLAorICAiMHgwMDA4MDAwMCIsCisgICIweDAwMTAwMDAwIiwKKyAgIjB4MDAyMDAwMDAiLAorICAiMHgwMDQwMDAwMCIsCisgICIweDAwODAwMDAwIiwKKworICAiMHgwMTAwMDAwMCIsCisgICIweDAyMDAwMDAwIiwKKyAgIjB4MDQwMDAwMDAiLAorICAiMHgwODAwMDAwMCIsCisgICIweDEwMDAwMDAwIiwKKyAgIjB4MjAwMDAwMDAiLAorICAiMHg0MDAwMDAwMCIsCisgICIweDgwMDAwMDAwIiwKK307CisKK3N0cmluZyBHZXRCaXRGaWVsZE5hbWUoaW50IGluZGV4KSB7CisgIHN0cmluZyB2YXJOYW1lID0gImJpdEZpZWxkIjsKKyAgdmFyTmFtZSArPSBTaW1wbGVJdG9hKGluZGV4KTsKKyAgdmFyTmFtZSArPSAiXyI7CisgIHJldHVybiB2YXJOYW1lOworfQorCitzdHJpbmcgR2V0Qml0RmllbGROYW1lRm9yQml0KGludCBiaXRJbmRleCkgeworICByZXR1cm4gR2V0Qml0RmllbGROYW1lKGJpdEluZGV4IC8gMzIpOworfQorCituYW1lc3BhY2UgeworCitzdHJpbmcgR2VuZXJhdGVHZXRCaXRJbnRlcm5hbChjb25zdCBzdHJpbmcmIHByZWZpeCwgaW50IGJpdEluZGV4KSB7CisgIHN0cmluZyB2YXJOYW1lID0gcHJlZml4ICsgR2V0Qml0RmllbGROYW1lRm9yQml0KGJpdEluZGV4KTsKKyAgaW50IGJpdEluVmFySW5kZXggPSBiaXRJbmRleCAlIDMyOworCisgIHN0cmluZyBtYXNrID0gYml0X21hc2tzW2JpdEluVmFySW5kZXhdOworICBzdHJpbmcgcmVzdWx0ID0gIigoIiArIHZhck5hbWUgKyAiICYgIiArIG1hc2sgKyAiKSA9PSAiICsgbWFzayArICIpIjsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RyaW5nIEdlbmVyYXRlU2V0Qml0SW50ZXJuYWwoY29uc3Qgc3RyaW5nJiBwcmVmaXgsIGludCBiaXRJbmRleCkgeworICBzdHJpbmcgdmFyTmFtZSA9IHByZWZpeCArIEdldEJpdEZpZWxkTmFtZUZvckJpdChiaXRJbmRleCk7CisgIGludCBiaXRJblZhckluZGV4ID0gYml0SW5kZXggJSAzMjsKKworICBzdHJpbmcgbWFzayA9IGJpdF9tYXNrc1tiaXRJblZhckluZGV4XTsKKyAgc3RyaW5nIHJlc3VsdCA9IHZhck5hbWUgKyAiIHw9ICIgKyBtYXNrOworICByZXR1cm4gcmVzdWx0OworfQorCit9ICAvLyBuYW1lc3BhY2UKKworc3RyaW5nIEdlbmVyYXRlR2V0Qml0KGludCBiaXRJbmRleCkgeworICByZXR1cm4gR2VuZXJhdGVHZXRCaXRJbnRlcm5hbCgiIiwgYml0SW5kZXgpOworfQorCitzdHJpbmcgR2VuZXJhdGVTZXRCaXQoaW50IGJpdEluZGV4KSB7CisgIHJldHVybiBHZW5lcmF0ZVNldEJpdEludGVybmFsKCIiLCBiaXRJbmRleCk7Cit9CisKK3N0cmluZyBHZW5lcmF0ZUNsZWFyQml0KGludCBiaXRJbmRleCkgeworICBzdHJpbmcgdmFyTmFtZSA9IEdldEJpdEZpZWxkTmFtZUZvckJpdChiaXRJbmRleCk7CisgIGludCBiaXRJblZhckluZGV4ID0gYml0SW5kZXggJSAzMjsKKworICBzdHJpbmcgbWFzayA9IGJpdF9tYXNrc1tiaXRJblZhckluZGV4XTsKKyAgc3RyaW5nIHJlc3VsdCA9IHZhck5hbWUgKyAiID0gKCIgKyB2YXJOYW1lICsgIiAmIH4iICsgbWFzayArICIpIjsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RyaW5nIEdlbmVyYXRlR2V0Qml0RnJvbUxvY2FsKGludCBiaXRJbmRleCkgeworICByZXR1cm4gR2VuZXJhdGVHZXRCaXRJbnRlcm5hbCgiZnJvbV8iLCBiaXRJbmRleCk7Cit9CisKK3N0cmluZyBHZW5lcmF0ZVNldEJpdFRvTG9jYWwoaW50IGJpdEluZGV4KSB7CisgIHJldHVybiBHZW5lcmF0ZVNldEJpdEludGVybmFsKCJ0b18iLCBiaXRJbmRleCk7Cit9CisKK3N0cmluZyBHZW5lcmF0ZUdldEJpdE11dGFibGVMb2NhbChpbnQgYml0SW5kZXgpIHsKKyAgcmV0dXJuIEdlbmVyYXRlR2V0Qml0SW50ZXJuYWwoIm11dGFibGVfIiwgYml0SW5kZXgpOworfQorCitzdHJpbmcgR2VuZXJhdGVTZXRCaXRNdXRhYmxlTG9jYWwoaW50IGJpdEluZGV4KSB7CisgIHJldHVybiBHZW5lcmF0ZVNldEJpdEludGVybmFsKCJtdXRhYmxlXyIsIGJpdEluZGV4KTsKK30KKworYm9vbCBJc1JlZmVyZW5jZVR5cGUoSmF2YVR5cGUgdHlwZSkgeworICBzd2l0Y2ggKHR5cGUpIHsKKyAgICBjYXNlIEpBVkFUWVBFX0lOVCAgICA6IHJldHVybiBmYWxzZTsKKyAgICBjYXNlIEpBVkFUWVBFX0xPTkcgICA6IHJldHVybiBmYWxzZTsKKyAgICBjYXNlIEpBVkFUWVBFX0ZMT0FUICA6IHJldHVybiBmYWxzZTsKKyAgICBjYXNlIEpBVkFUWVBFX0RPVUJMRSA6IHJldHVybiBmYWxzZTsKKyAgICBjYXNlIEpBVkFUWVBFX0JPT0xFQU46IHJldHVybiBmYWxzZTsKKyAgICBjYXNlIEpBVkFUWVBFX1NUUklORyA6IHJldHVybiB0cnVlOworICAgIGNhc2UgSkFWQVRZUEVfQllURVMgIDogcmV0dXJuIHRydWU7CisgICAgY2FzZSBKQVZBVFlQRV9FTlVNICAgOiByZXR1cm4gdHJ1ZTsKKyAgICBjYXNlIEpBVkFUWVBFX01FU1NBR0U6IHJldHVybiB0cnVlOworCisgICAgLy8gTm8gZGVmYXVsdCBiZWNhdXNlIHdlIHdhbnQgdGhlIGNvbXBpbGVyIHRvIGNvbXBsYWluIGlmIGFueSBuZXcKKyAgICAvLyBKYXZhVHlwZXMgYXJlIGFkZGVkLgorICB9CisKKyAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkNhbid0IGdldCBoZXJlLiI7CisgIHJldHVybiBmYWxzZTsKK30KKworY29uc3QgY2hhciogR2V0Q2FwaXRhbGl6ZWRUeXBlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGJvb2wgaW1tdXRhYmxlKSB7CisgIHN3aXRjaCAoR2V0VHlwZShmaWVsZCkpIHsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9JTlQzMiAgIDogcmV0dXJuICJJbnQzMiI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfVUlOVDMyICA6IHJldHVybiAiVUludDMyIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TSU5UMzIgIDogcmV0dXJuICJTSW50MzIiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0ZJWEVEMzIgOiByZXR1cm4gIkZpeGVkMzIiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NGSVhFRDMyOiByZXR1cm4gIlNGaXhlZDMyIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9JTlQ2NCAgIDogcmV0dXJuICJJbnQ2NCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfVUlOVDY0ICA6IHJldHVybiAiVUludDY0IjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TSU5UNjQgIDogcmV0dXJuICJTSW50NjQiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0ZJWEVENjQgOiByZXR1cm4gIkZpeGVkNjQiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NGSVhFRDY0OiByZXR1cm4gIlNGaXhlZDY0IjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9GTE9BVCAgIDogcmV0dXJuICJGbG9hdCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRE9VQkxFICA6IHJldHVybiAiRG91YmxlIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9CT09MICAgIDogcmV0dXJuICJCb29sIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TVFJJTkcgIDogcmV0dXJuICJTdHJpbmciOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0JZVEVTICAgOiB7CisgICAgICByZXR1cm4gIkJ5dGVzIjsKKyAgICB9CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRU5VTSAgICA6IHJldHVybiAiRW51bSI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfR1JPVVAgICA6IHJldHVybiAiR3JvdXAiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX01FU1NBR0UgOiByZXR1cm4gIk1lc3NhZ2UiOworCisgICAgLy8gTm8gZGVmYXVsdCBiZWNhdXNlIHdlIHdhbnQgdGhlIGNvbXBpbGVyIHRvIGNvbXBsYWluIGlmIGFueSBuZXcKKyAgICAvLyB0eXBlcyBhcmUgYWRkZWQuCisgIH0KKworICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ2FuJ3QgZ2V0IGhlcmUuIjsKKyAgcmV0dXJuIE5VTEw7Cit9CisKKy8vIEZvciBlbmNvZGluZ3Mgd2l0aCBmaXhlZCBzaXplcywgcmV0dXJucyB0aGF0IHNpemUgaW4gYnl0ZXMuICBPdGhlcndpc2UKKy8vIHJldHVybnMgLTEuCitpbnQgRml4ZWRTaXplKEZpZWxkRGVzY3JpcHRvcjo6VHlwZSB0eXBlKSB7CisgIHN3aXRjaCAodHlwZSkgeworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0lOVDMyICAgOiByZXR1cm4gLTE7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfSU5UNjQgICA6IHJldHVybiAtMTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9VSU5UMzIgIDogcmV0dXJuIC0xOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1VJTlQ2NCAgOiByZXR1cm4gLTE7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0lOVDMyICA6IHJldHVybiAtMTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TSU5UNjQgIDogcmV0dXJuIC0xOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0ZJWEVEMzIgOiByZXR1cm4gV2lyZUZvcm1hdExpdGU6OmtGaXhlZDMyU2l6ZTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9GSVhFRDY0IDogcmV0dXJuIFdpcmVGb3JtYXRMaXRlOjprRml4ZWQ2NFNpemU7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0ZJWEVEMzI6IHJldHVybiBXaXJlRm9ybWF0TGl0ZTo6a1NGaXhlZDMyU2l6ZTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TRklYRUQ2NDogcmV0dXJuIFdpcmVGb3JtYXRMaXRlOjprU0ZpeGVkNjRTaXplOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0ZMT0FUICAgOiByZXR1cm4gV2lyZUZvcm1hdExpdGU6OmtGbG9hdFNpemU7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRE9VQkxFICA6IHJldHVybiBXaXJlRm9ybWF0TGl0ZTo6a0RvdWJsZVNpemU7CisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9CT09MICAgIDogcmV0dXJuIFdpcmVGb3JtYXRMaXRlOjprQm9vbFNpemU7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRU5VTSAgICA6IHJldHVybiAtMTsKKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NUUklORyAgOiByZXR1cm4gLTE7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfQllURVMgICA6IHJldHVybiAtMTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9HUk9VUCAgIDogcmV0dXJuIC0xOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX01FU1NBR0UgOiByZXR1cm4gLTE7CisKKyAgICAvLyBObyBkZWZhdWx0IGJlY2F1c2Ugd2Ugd2FudCB0aGUgY29tcGlsZXIgdG8gY29tcGxhaW4gaWYgYW55IG5ldworICAgIC8vIHR5cGVzIGFyZSBhZGRlZC4KKyAgfQorICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ2FuJ3QgZ2V0IGhlcmUuIjsKKyAgcmV0dXJuIC0xOworfQorCisvLyBTb3J0IHRoZSBmaWVsZHMgb2YgdGhlIGdpdmVuIERlc2NyaXB0b3IgYnkgbnVtYmVyIGludG8gYSBuZXdbXSdkIGFycmF5CisvLyBhbmQgcmV0dXJuIGl0LiBUaGUgY2FsbGVyIHNob3VsZCBkZWxldGUgdGhlIHJldHVybmVkIGFycmF5LgorY29uc3QgRmllbGREZXNjcmlwdG9yKiogU29ydEZpZWxkc0J5TnVtYmVyKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiogZmllbGRzID0KKyAgICBuZXcgY29uc3QgRmllbGREZXNjcmlwdG9yKltkZXNjcmlwdG9yLT5maWVsZF9jb3VudCgpXTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBmaWVsZHNbaV0gPSBkZXNjcmlwdG9yLT5maWVsZChpKTsKKyAgfQorICBzdGQ6OnNvcnQoZmllbGRzLCBmaWVsZHMgKyBkZXNjcmlwdG9yLT5maWVsZF9jb3VudCgpLAorICAgICAgICAgICAgRmllbGRPcmRlcmluZ0J5TnVtYmVyKCkpOworICByZXR1cm4gZmllbGRzOworfQorCisvLyBSZXR1cm5zIHRydWUgaWYgdGhlIG1lc3NhZ2UgdHlwZSBoYXMgYW55IHJlcXVpcmVkIGZpZWxkcy4gIElmIGl0IGRvZXNuJ3QsCisvLyB3ZSBjYW4gb3B0aW1pemUgb3V0IGNhbGxzIHRvIGl0cyBpc0luaXRpYWxpemVkKCkgbWV0aG9kLgorLy8KKy8vIGFscmVhZHlfc2VlbiBpcyB1c2VkIHRvIGF2b2lkIGNoZWNraW5nIHRoZSBzYW1lIHR5cGUgbXVsdGlwbGUgdGltZXMKKy8vIChhbmQgYWxzbyB0byBwcm90ZWN0IGFnYWluc3QgcmVjdXJzaW9uKS4KK2Jvb2wgSGFzUmVxdWlyZWRGaWVsZHMoCisgICAgY29uc3QgRGVzY3JpcHRvciogdHlwZSwKKyAgICBoYXNoX3NldDxjb25zdCBEZXNjcmlwdG9yKj4qIGFscmVhZHlfc2VlbikgeworICBpZiAoYWxyZWFkeV9zZWVuLT5jb3VudCh0eXBlKSA+IDApIHsKKyAgICAvLyBUaGUgdHlwZSBpcyBhbHJlYWR5IGluIGNhY2hlLiAgVGhpcyBtZWFucyB0aGF0IGVpdGhlcjoKKyAgICAvLyBhLiBUaGUgdHlwZSBoYXMgbm8gcmVxdWlyZWQgZmllbGRzLgorICAgIC8vIGIuIFdlIGFyZSBpbiB0aGUgbWlkc3Qgb2YgY2hlY2tpbmcgaWYgdGhlIHR5cGUgaGFzIHJlcXVpcmVkIGZpZWxkcywKKyAgICAvLyAgICBzb21ld2hlcmUgdXAgdGhlIHN0YWNrLiAgSW4gdGhpcyBjYXNlLCB3ZSBrbm93IHRoYXQgaWYgdGhlIHR5cGUKKyAgICAvLyAgICBoYXMgYW55IHJlcXVpcmVkIGZpZWxkcywgdGhleSdsbCBiZSBmb3VuZCB3aGVuIHdlIHJldHVybiB0byBpdCwKKyAgICAvLyAgICBhbmQgdGhlIHdob2xlIGNhbGwgdG8gSGFzUmVxdWlyZWRGaWVsZHMoKSB3aWxsIHJldHVybiB0cnVlLgorICAgIC8vICAgIFRoZXJlZm9yZSwgd2UgZG9uJ3QgaGF2ZSB0byBjaGVjayBpZiB0aGlzIHR5cGUgaGFzIHJlcXVpcmVkIGZpZWxkcworICAgIC8vICAgIGhlcmUuCisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIGFscmVhZHlfc2Vlbi0+aW5zZXJ0KHR5cGUpOworCisgIC8vIElmIHRoZSB0eXBlIGhhcyBleHRlbnNpb25zLCBhbiBleHRlbnNpb24gd2l0aCBtZXNzYWdlIHR5cGUgY291bGQgY29udGFpbgorICAvLyByZXF1aXJlZCBmaWVsZHMsIHNvIHdlIGhhdmUgdG8gYmUgY29uc2VydmF0aXZlIGFuZCBhc3N1bWUgc3VjaCBhbgorICAvLyBleHRlbnNpb24gZXhpc3RzLgorICBpZiAodHlwZS0+ZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCkgPiAwKSByZXR1cm4gdHJ1ZTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IHR5cGUtPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSB0eXBlLT5maWVsZChpKTsKKyAgICBpZiAoZmllbGQtPmlzX3JlcXVpcmVkKCkpIHsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgICBpZiAoR2V0SmF2YVR5cGUoZmllbGQpID09IEpBVkFUWVBFX01FU1NBR0UpIHsKKyAgICAgIGlmIChIYXNSZXF1aXJlZEZpZWxkcyhmaWVsZC0+bWVzc2FnZV90eXBlKCksIGFscmVhZHlfc2VlbikpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICB9CisgICAgfQorICB9CisKKyAgcmV0dXJuIGZhbHNlOworfQorCitib29sIEhhc1JlcXVpcmVkRmllbGRzKGNvbnN0IERlc2NyaXB0b3IqIHR5cGUpIHsKKyAgaGFzaF9zZXQ8Y29uc3QgRGVzY3JpcHRvcio+IGFscmVhZHlfc2VlbjsKKyAgcmV0dXJuIEhhc1JlcXVpcmVkRmllbGRzKHR5cGUsICZhbHJlYWR5X3NlZW4pOworfQorCitib29sIEhhc1JlcGVhdGVkRmllbGRzKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yLT5maWVsZF9jb3VudCgpOyArK2kpIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvci0+ZmllbGQoaSk7CisgICAgaWYgKGZpZWxkLT5pc19yZXBlYXRlZCgpKSB7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIGZhbHNlOworfQorCit9ICAvLyBuYW1lc3BhY2UgamF2YQorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2hlbHBlcnMuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2hlbHBlcnMuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MzkyZDZkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfaGVscGVycy5oCkBAIC0wLDAgKzEsMzU1IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfSEVMUEVSU19IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfSEVMUEVSU19IX18KKworI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YSB7CisKKy8vIENvbW1vbmx5LXVzZWQgc2VwYXJhdG9yIGNvbW1lbnRzLiAgVGhpY2sgaXMgYSBsaW5lIG9mICc9JywgdGhpbiBpcyBhIGxpbmUKKy8vIG9mICctJy4KK2V4dGVybiBjb25zdCBjaGFyIGtUaGlja1NlcGFyYXRvcltdOworZXh0ZXJuIGNvbnN0IGNoYXIga1RoaW5TZXBhcmF0b3JbXTsKKworLy8gQ29udmVydHMgYSBuYW1lIHRvIGNhbWVsLWNhc2UuIElmIGNhcF9maXJzdF9sZXR0ZXIgaXMgdHJ1ZSwgY2FwaXRhbGl6ZSB0aGUKKy8vIGZpcnN0IGxldHRlci4KK3N0cmluZyBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlKGNvbnN0IHN0cmluZyYgbmFtZSwgYm9vbCBjYXBfZmlyc3RfbGV0dGVyKTsKKy8vIENvbnZlcnRzIHRoZSBmaWVsZCdzIG5hbWUgdG8gY2FtZWwtY2FzZSwgZS5nLiAiZm9vX2Jhcl9iYXoiIGJlY29tZXMKKy8vICJmb29CYXJCYXoiIG9yICJGb29CYXJCYXoiLCByZXNwZWN0aXZlbHkuCitzdHJpbmcgVW5kZXJzY29yZXNUb0NhbWVsQ2FzZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKTsKK3N0cmluZyBVbmRlcnNjb3Jlc1RvQ2FwaXRhbGl6ZWRDYW1lbENhc2UoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCk7CisKKy8vIFNpbWlsYXIsIGJ1dCBmb3IgbWV0aG9kIG5hbWVzLiAgKFR5cGljYWxseSwgdGhpcyBtZXJlbHkgaGFzIHRoZSBlZmZlY3QKKy8vIG9mIGxvd2VyLWNhc2luZyB0aGUgZmlyc3QgbGV0dGVyIG9mIHRoZSBuYW1lLikKK3N0cmluZyBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlKGNvbnN0IE1ldGhvZERlc2NyaXB0b3IqIG1ldGhvZCk7CisKKy8vIEdldCBhbiBpZGVudGlmaWVyIHRoYXQgdW5pcXVlbHkgaWRlbnRpZmllcyB0aGlzIHR5cGUgd2l0aGluIHRoZSBmaWxlLgorLy8gVGhpcyBpcyB1c2VkIHRvIGRlY2xhcmUgc3RhdGljIHZhcmlhYmxlcyByZWxhdGVkIHRvIHRoaXMgdHlwZSBhdCB0aGUKKy8vIG91dGVybW9zdCBmaWxlIHNjb3BlLgorc3RyaW5nIFVuaXF1ZUZpbGVTY29wZUlkZW50aWZpZXIoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CisKKy8vIFN0cmlwcyAiLnByb3RvIiBvciAiLnByb3RvZGV2ZWwiIGZyb20gdGhlIGVuZCBvZiBhIGZpbGVuYW1lLgorc3RyaW5nIFN0cmlwUHJvdG8oY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSk7CisKKy8vIEdldHMgdGhlIHVucXVhbGlmaWVkIGNsYXNzIG5hbWUgZm9yIHRoZSBmaWxlLiAgRm9yIGVhY2ggLnByb3RvIGZpbGUsIHRoZXJlCisvLyB3aWxsIGJlIG9uZSBKYXZhIGNsYXNzIGNvbnRhaW5pbmcgYWxsIHRoZSBpbW11dGFibGUgbWVzc2FnZXMgYW5kIGFub3RoZXIKKy8vIEphdmEgY2xhc3MgY29udGFpbmluZyBhbGwgdGhlIG11dGFibGUgbWVzc2FnZXMuCisvLyBUT0RPKHhpYW9mZW5nKTogcmVtb3ZlIHRoZSBkZWZhdWx0IHZhbHVlIGFmdGVyIHVwZGF0aW5nIGNsaWVudCBjb2RlLgorc3RyaW5nIEZpbGVDbGFzc05hbWUoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUsIGJvb2wgaW1tdXRhYmxlID0gdHJ1ZSk7CisKKy8vIFJldHVybnMgdGhlIGZpbGUncyBKYXZhIHBhY2thZ2UgbmFtZS4KK3N0cmluZyBGaWxlSmF2YVBhY2thZ2UoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUsIGJvb2wgaW1tdXRhYmxlID0gdHJ1ZSk7CisKKy8vIFJldHVybnMgb3V0cHV0IGRpcmVjdG9yeSBmb3IgdGhlIGdpdmVuIHBhY2thZ2UgbmFtZS4KK3N0cmluZyBKYXZhUGFja2FnZVRvRGlyKHN0cmluZyBwYWNrYWdlX25hbWUpOworCisvLyBDb252ZXJ0cyB0aGUgZ2l2ZW4gZnVsbHktcXVhbGlmaWVkIG5hbWUgaW4gdGhlIHByb3RvIG5hbWVzcGFjZSB0byBpdHMKKy8vIGZ1bGx5LXF1YWxpZmllZCBuYW1lIGluIHRoZSBKYXZhIG5hbWVzcGFjZSwgZ2l2ZW4gdGhhdCBpdCBpcyBpbiB0aGUgZ2l2ZW4KKy8vIGZpbGUuCisvLyBUT0RPKHhpYW9mZW5nKTogdGhpcyBtZXRob2QgaXMgZGVwcmVjYXRlZCBhbmQgc2hvdWxkIGJlIHJlbW92ZWQgaW4gdGhlCisvLyBmdXR1cmUuCitzdHJpbmcgVG9KYXZhTmFtZShjb25zdCBzdHJpbmcmIGZ1bGxfbmFtZSwKKyAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKTsKKworLy8gVE9ETyh4aWFvZmVuZyk6IHRoZSBmb2xsb3dpbmcgbWV0aG9kcyBhcmUga2VwdCBmb3IgdGhleSBhcmUgZXhwb3NlZAorLy8gcHVibGljbHkgaW4gLy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9uYW1lcy5oLiBUaGV5IHJldHVybgorLy8gaW1tdXRhYmxlIG5hbWVzIG9ubHkgYW5kIHNob3VsZCBiZSByZW1vdmVkIGFmdGVyIG11dGFibGUgQVBJIGlzCisvLyBpbnRlZ3JhdGVkIGludG8gZ29vZ2xlMy4KK3N0cmluZyBDbGFzc05hbWUoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CitzdHJpbmcgQ2xhc3NOYW1lKGNvbnN0IEVudW1EZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKK3N0cmluZyBDbGFzc05hbWUoY29uc3QgU2VydmljZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworc3RyaW5nIENsYXNzTmFtZShjb25zdCBGaWxlRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CisKKy8vIENvbW1hLXNlcGFyYXRlIGxpc3Qgb2Ygb3B0aW9uLXNwZWNpZmllZCBpbnRlcmZhY2VzIGltcGxlbWVudGVkIGJ5IHRoZQorLy8gTWVzc2FnZSwgdG8gZm9sbG93IHRoZSAiaW1wbGVtZW50cyIgZGVjbGFyYXRpb24gb2YgdGhlIE1lc3NhZ2UgZGVmaW5pdGlvbi4KK3N0cmluZyBFeHRyYU1lc3NhZ2VJbnRlcmZhY2VzKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworLy8gQ29tbWEtc2VwYXJhdGUgbGlzdCBvZiBvcHRpb24tc3BlY2lmaWVkIGludGVyZmFjZXMgaW1wbGVtZW50ZWQgYnkgdGhlCisvLyBNdXRhYmxlTWVzc2FnZSwgdG8gZm9sbG93IHRoZSAiaW1wbGVtZW50cyIgZGVjbGFyYXRpb24gb2YgdGhlIE11dGFibGVNZXNzYWdlCisvLyBkZWZpbml0aW9uLgorc3RyaW5nIEV4dHJhTXV0YWJsZU1lc3NhZ2VJbnRlcmZhY2VzKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworLy8gQ29tbWEtc2VwYXJhdGUgbGlzdCBvZiBvcHRpb24tc3BlY2lmaWVkIGludGVyZmFjZXMgaW1wbGVtZW50ZWQgYnkgdGhlCisvLyBCdWlsZGVyLCB0byBmb2xsb3cgdGhlICJpbXBsZW1lbnRzIiBkZWNsYXJhdGlvbiBvZiB0aGUgQnVpbGRlciBkZWZpbml0aW9uLgorc3RyaW5nIEV4dHJhQnVpbGRlckludGVyZmFjZXMoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CisvLyBDb21tYS1zZXBhcmF0ZSBsaXN0IG9mIG9wdGlvbi1zcGVjaWZpZWQgaW50ZXJmYWNlcyBleHRlbmRlZCBieSB0aGUKKy8vIE1lc3NhZ2VPckJ1aWxkZXIsIHRvIGZvbGxvdyB0aGUgImV4dGVuZHMiIGRlY2xhcmF0aW9uIG9mIHRoZQorLy8gTWVzc2FnZU9yQnVpbGRlciBkZWZpbml0aW9uLgorc3RyaW5nIEV4dHJhTWVzc2FnZU9yQnVpbGRlckludGVyZmFjZXMoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CisKKy8vIEdldCB0aGUgdW5xdWFsaWZpZWQgSmF2YSBjbGFzcyBuYW1lIGZvciBtdXRhYmxlIG1lc3NhZ2VzLiBpLmUuIHdpdGhvdXQKKy8vIHBhY2thZ2Ugb3Igb3V0ZXIgY2xhc3NuYW1lcy4KK2lubGluZSBzdHJpbmcgU2hvcnRNdXRhYmxlSmF2YUNsYXNzTmFtZShjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIHJldHVybiBkZXNjcmlwdG9yLT5uYW1lKCk7Cit9CisKKworLy8gV2hldGhlciB3ZSBzaG91bGQgZ2VuZXJhdGUgbXVsdGlwbGUgamF2YSBmaWxlcyBmb3IgbWVzc2FnZXMuCitpbmxpbmUgYm9vbCBNdWx0aXBsZUphdmFGaWxlcygKKyAgICBjb25zdCBGaWxlRGVzY3JpcHRvciogZGVzY3JpcHRvciwgYm9vbCBpbW11dGFibGUpIHsKKyAgcmV0dXJuIGRlc2NyaXB0b3ItPm9wdGlvbnMoKS5qYXZhX211bHRpcGxlX2ZpbGVzKCk7Cit9CisKKy8vIEdldCB0aGUgdW5xdWFsaWZpZWQgbmFtZSB0aGF0IHNob3VsZCBiZSB1c2VkIGZvciBhIGZpZWxkJ3MgZmllbGQKKy8vIG51bWJlciBjb25zdGFudC4KK3N0cmluZyBGaWVsZENvbnN0YW50TmFtZShjb25zdCBGaWVsZERlc2NyaXB0b3IgKmZpZWxkKTsKKworLy8gUmV0dXJucyB0aGUgdHlwZSBvZiB0aGUgRmllbGREZXNjcmlwdG9yLgorLy8gVGhpcyBkb2VzIG5vdGhpbmcgaW50ZXJlc3RpbmcgZm9yIHRoZSBvcGVuIHNvdXJjZSByZWxlYXNlLCBidXQgaXMgdXNlZCBmb3IKKy8vIGhhY2tzIHRoYXQgaW1wcm92ZSBjb21wYXRpYmlsaXR5IHdpdGggdmVyc2lvbiAxIHByb3RvY29sIGJ1ZmZlcnMgYXQgR29vZ2xlLgorRmllbGREZXNjcmlwdG9yOjpUeXBlIEdldFR5cGUoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCk7CisKK2VudW0gSmF2YVR5cGUgeworICBKQVZBVFlQRV9JTlQsCisgIEpBVkFUWVBFX0xPTkcsCisgIEpBVkFUWVBFX0ZMT0FULAorICBKQVZBVFlQRV9ET1VCTEUsCisgIEpBVkFUWVBFX0JPT0xFQU4sCisgIEpBVkFUWVBFX1NUUklORywKKyAgSkFWQVRZUEVfQllURVMsCisgIEpBVkFUWVBFX0VOVU0sCisgIEpBVkFUWVBFX01FU1NBR0UKK307CisKK0phdmFUeXBlIEdldEphdmFUeXBlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpOworCitjb25zdCBjaGFyKiBQcmltaXRpdmVUeXBlTmFtZShKYXZhVHlwZSB0eXBlKTsKKworLy8gR2V0IHRoZSBmdWxseS1xdWFsaWZpZWQgY2xhc3MgbmFtZSBmb3IgYSBib3hlZCBwcmltaXRpdmUgdHlwZSwgZS5nLgorLy8gImphdmEubGFuZy5JbnRlZ2VyIiBmb3IgSkFWQVRZUEVfSU5ULiAgUmV0dXJucyBOVUxMIGZvciBlbnVtIGFuZCBtZXNzYWdlCisvLyB0eXBlcy4KK2NvbnN0IGNoYXIqIEJveGVkUHJpbWl0aXZlVHlwZU5hbWUoSmF2YVR5cGUgdHlwZSk7CisKKy8vIEdldCB0aGUgbmFtZSBvZiB0aGUgamF2YSBlbnVtIGNvbnN0YW50IHJlcHJlc2VudGluZyB0aGlzIHR5cGUuIEUuZy4sCisvLyAiSU5UMzIiIGZvciBGaWVsZERlc2NyaXB0b3I6OlRZUEVfSU5UMzIuIFRoZSBlbnVtIGNvbnN0YW50J3MgZnVsbAorLy8gbmFtZSBpcyAiY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiIuCitjb25zdCBjaGFyKiBGaWVsZFR5cGVOYW1lKGNvbnN0IEZpZWxkRGVzY3JpcHRvcjo6VHlwZSBmaWVsZF90eXBlKTsKKworY2xhc3MgQ2xhc3NOYW1lUmVzb2x2ZXI7CitzdHJpbmcgRGVmYXVsdFZhbHVlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGJvb2wgaW1tdXRhYmxlLAorICAgICAgICAgICAgICAgICAgICBDbGFzc05hbWVSZXNvbHZlciogbmFtZV9yZXNvbHZlcik7CitpbmxpbmUgc3RyaW5nIEltbXV0YWJsZURlZmF1bHRWYWx1ZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3NOYW1lUmVzb2x2ZXIqIG5hbWVfcmVzb2x2ZXIpIHsKKyAgcmV0dXJuIERlZmF1bHRWYWx1ZShmaWVsZCwgdHJ1ZSwgbmFtZV9yZXNvbHZlcik7Cit9Citib29sIElzRGVmYXVsdFZhbHVlSmF2YURlZmF1bHQoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCk7CisKKy8vIERvZXMgdGhpcyBtZXNzYWdlIGNsYXNzIGhhdmUgZ2VuZXJhdGVkIHBhcnNpbmcsIHNlcmlhbGl6YXRpb24sIGFuZCBvdGhlcgorLy8gc3RhbmRhcmQgbWV0aG9kcyBmb3Igd2hpY2ggcmVmbGVjdGlvbi1iYXNlZCBmYWxsYmFjayBpbXBsZW1lbnRhdGlvbnMgZXhpc3Q/CitpbmxpbmUgYm9vbCBIYXNHZW5lcmF0ZWRNZXRob2RzKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgcmV0dXJuIGRlc2NyaXB0b3ItPmZpbGUoKS0+b3B0aW9ucygpLm9wdGltaXplX2ZvcigpICE9CisgICAgICAgICAgIEZpbGVPcHRpb25zOjpDT0RFX1NJWkU7Cit9CisKKy8vIERvZXMgdGhpcyBtZXNzYWdlIGhhdmUgc3BlY2lhbGl6ZWQgZXF1YWxzKCkgYW5kIGhhc2hDb2RlKCkgbWV0aG9kcz8KK2lubGluZSBib29sIEhhc0VxdWFsc0FuZEhhc2hDb2RlKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgcmV0dXJuIGRlc2NyaXB0b3ItPmZpbGUoKS0+b3B0aW9ucygpLmphdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoKCk7Cit9CisKKy8vIERvZXMgdGhpcyBtZXNzYWdlIGNsYXNzIGhhdmUgZGVzY3JpcHRvciBhbmQgcmVmbGVjdGlvbiBtZXRob2RzPworaW5saW5lIGJvb2wgSGFzRGVzY3JpcHRvck1ldGhvZHMoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICByZXR1cm4gZGVzY3JpcHRvci0+ZmlsZSgpLT5vcHRpb25zKCkub3B0aW1pemVfZm9yKCkgIT0KKyAgICAgICAgICAgRmlsZU9wdGlvbnM6OkxJVEVfUlVOVElNRTsKK30KK2lubGluZSBib29sIEhhc0Rlc2NyaXB0b3JNZXRob2RzKGNvbnN0IEVudW1EZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIHJldHVybiBkZXNjcmlwdG9yLT5maWxlKCktPm9wdGlvbnMoKS5vcHRpbWl6ZV9mb3IoKSAhPQorICAgICAgICAgICBGaWxlT3B0aW9uczo6TElURV9SVU5USU1FOworfQoraW5saW5lIGJvb2wgSGFzRGVzY3JpcHRvck1ldGhvZHMoY29uc3QgRmlsZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgcmV0dXJuIGRlc2NyaXB0b3ItPm9wdGlvbnMoKS5vcHRpbWl6ZV9mb3IoKSAhPQorICAgICAgICAgICBGaWxlT3B0aW9uczo6TElURV9SVU5USU1FOworfQorCisvLyBTaG91bGQgd2UgZ2VuZXJhdGUgZ2VuZXJpYyBzZXJ2aWNlcyBmb3IgdGhpcyBmaWxlPworaW5saW5lIGJvb2wgSGFzR2VuZXJpY1NlcnZpY2VzKGNvbnN0IEZpbGVEZXNjcmlwdG9yICpmaWxlKSB7CisgIHJldHVybiBmaWxlLT5zZXJ2aWNlX2NvdW50KCkgPiAwICYmCisgICAgICAgICBmaWxlLT5vcHRpb25zKCkub3B0aW1pemVfZm9yKCkgIT0gRmlsZU9wdGlvbnM6OkxJVEVfUlVOVElNRSAmJgorICAgICAgICAgZmlsZS0+b3B0aW9ucygpLmphdmFfZ2VuZXJpY19zZXJ2aWNlcygpOworfQorCitpbmxpbmUgYm9vbCBJc0xhenkoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIC8vIEN1cnJlbnRseSwgdGhlIHByb3RvLWxpdGUgdmVyc2lvbiBzdXBvcnRzIGxhenkgZmllbGQuCisgIC8vIFRPRE8obml3YXNha2kpOiBTdXBwb3J0IGxhenkgZmllbGRzIGFsc28gZm9yIG90aGVyIHByb3RvIHJ1bnRpbWVzLgorICBpZiAoZGVzY3JpcHRvci0+ZmlsZSgpLT5vcHRpb25zKCkub3B0aW1pemVfZm9yKCkgIT0KKyAgICAgIEZpbGVPcHRpb25zOjpMSVRFX1JVTlRJTUUpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgcmV0dXJuIGRlc2NyaXB0b3ItPm9wdGlvbnMoKS5sYXp5KCk7Cit9CisKKy8vIE1ldGhvZHMgZm9yIHNoYXJlZCBiaXRmaWVsZHMuCisKKy8vIEdldHMgdGhlIG5hbWUgb2YgdGhlIHNoYXJlZCBiaXRmaWVsZCBmb3IgdGhlIGdpdmVuIGluZGV4Lgorc3RyaW5nIEdldEJpdEZpZWxkTmFtZShpbnQgaW5kZXgpOworCisvLyBHZXRzIHRoZSBuYW1lIG9mIHRoZSBzaGFyZWQgYml0ZmllbGQgZm9yIHRoZSBnaXZlbiBiaXQgaW5kZXguCisvLyBFZmZlY3RpdmVseSwgR2V0Qml0RmllbGROYW1lKGJpdEluZGV4IC8gMzIpCitzdHJpbmcgR2V0Qml0RmllbGROYW1lRm9yQml0KGludCBiaXRJbmRleCk7CisKKy8vIEdlbmVyYXRlcyB0aGUgamF2YSBjb2RlIGZvciB0aGUgZXhwcmVzc2lvbiB0aGF0IHJldHVybnMgdGhlIGJvb2xlYW4gdmFsdWUKKy8vIG9mIHRoZSBiaXQgb2YgdGhlIHNoYXJlZCBiaXRmaWVsZHMgZm9yIHRoZSBnaXZlbiBiaXQgaW5kZXguCisvLyBFeGFtcGxlOiAiKChiaXRGaWVsZDFfICYgMHgwNCkgPT0gMHgwNCkiCitzdHJpbmcgR2VuZXJhdGVHZXRCaXQoaW50IGJpdEluZGV4KTsKKworLy8gR2VuZXJhdGVzIHRoZSBqYXZhIGNvZGUgZm9yIHRoZSBleHByZXNzaW9uIHRoYXQgc2V0cyB0aGUgYml0IG9mIHRoZSBzaGFyZWQKKy8vIGJpdGZpZWxkcyBmb3IgdGhlIGdpdmVuIGJpdCBpbmRleC4KKy8vIEV4YW1wbGU6ICJiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gfCAweDA0KSIKK3N0cmluZyBHZW5lcmF0ZVNldEJpdChpbnQgYml0SW5kZXgpOworCisvLyBHZW5lcmF0ZXMgdGhlIGphdmEgY29kZSBmb3IgdGhlIGV4cHJlc3Npb24gdGhhdCBjbGVhcnMgdGhlIGJpdCBvZiB0aGUgc2hhcmVkCisvLyBiaXRmaWVsZHMgZm9yIHRoZSBnaXZlbiBiaXQgaW5kZXguCisvLyBFeGFtcGxlOiAiYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDQpIgorc3RyaW5nIEdlbmVyYXRlQ2xlYXJCaXQoaW50IGJpdEluZGV4KTsKKworLy8gRG9lcyB0aGUgc2FtZSBhcyBHZW5lcmF0ZUdldEJpdCBidXQgb3BlcmF0ZXMgb24gdGhlIGJpdCBmaWVsZCBvbiBhIGxvY2FsCisvLyB2YXJpYWJsZS4gVGhpcyBpcyB1c2VkIGJ5IHRoZSBidWlsZGVyIHRvIGNvcHkgdGhlIHZhbHVlIGluIHRoZSBidWlsZGVyIHRvCisvLyB0aGUgbWVzc2FnZS4KKy8vIEV4YW1wbGU6ICIoKGZyb21fYml0RmllbGQxXyAmIDB4MDQpID09IDB4MDQpIgorc3RyaW5nIEdlbmVyYXRlR2V0Qml0RnJvbUxvY2FsKGludCBiaXRJbmRleCk7CisKKy8vIERvZXMgdGhlIHNhbWUgYXMgR2VuZXJhdGVTZXRCaXQgYnV0IG9wZXJhdGVzIG9uIHRoZSBiaXQgZmllbGQgb24gYSBsb2NhbAorLy8gdmFyaWFibGUuIFRoaXMgaXMgdXNlZCBieSB0aGUgYnVpbGRlciB0byBjb3B5IHRoZSB2YWx1ZSBpbiB0aGUgYnVpbGRlciB0bworLy8gdGhlIG1lc3NhZ2UuCisvLyBFeGFtcGxlOiAidG9fYml0RmllbGQxXyA9ICh0b19iaXRGaWVsZDFfIHwgMHgwNCkiCitzdHJpbmcgR2VuZXJhdGVTZXRCaXRUb0xvY2FsKGludCBiaXRJbmRleCk7CisKKy8vIERvZXMgdGhlIHNhbWUgYXMgR2VuZXJhdGVHZXRCaXQgYnV0IG9wZXJhdGVzIG9uIHRoZSBiaXQgZmllbGQgb24gYSBsb2NhbAorLy8gdmFyaWFibGUuIFRoaXMgaXMgdXNlZCBieSB0aGUgcGFyc2luZyBjb25zdHJ1Y3RvciB0byByZWNvcmQgaWYgYSByZXBlYXRlZAorLy8gZmllbGQgaXMgbXV0YWJsZS4KKy8vIEV4YW1wbGU6ICIoKG11dGFibGVfYml0RmllbGQxXyAmIDB4MDQpID09IDB4MDQpIgorc3RyaW5nIEdlbmVyYXRlR2V0Qml0TXV0YWJsZUxvY2FsKGludCBiaXRJbmRleCk7CisKKy8vIERvZXMgdGhlIHNhbWUgYXMgR2VuZXJhdGVTZXRCaXQgYnV0IG9wZXJhdGVzIG9uIHRoZSBiaXQgZmllbGQgb24gYSBsb2NhbAorLy8gdmFyaWFibGUuIFRoaXMgaXMgdXNlZCBieSB0aGUgcGFyc2luZyBjb25zdHJ1Y3RvciB0byByZWNvcmQgaWYgYSByZXBlYXRlZAorLy8gZmllbGQgaXMgbXV0YWJsZS4KKy8vIEV4YW1wbGU6ICJtdXRhYmxlX2JpdEZpZWxkMV8gPSAobXV0YWJsZV9iaXRGaWVsZDFfIHwgMHgwNCkiCitzdHJpbmcgR2VuZXJhdGVTZXRCaXRNdXRhYmxlTG9jYWwoaW50IGJpdEluZGV4KTsKKworLy8gUmV0dXJucyB3aGV0aGVyIHRoZSBKYXZhVHlwZSBpcyBhIHJlZmVyZW5jZSB0eXBlLgorYm9vbCBJc1JlZmVyZW5jZVR5cGUoSmF2YVR5cGUgdHlwZSk7CisKKy8vIFJldHVybnMgdGhlIGNhcGl0YWxpemVkIG5hbWUgZm9yIGNhbGxpbmcgcmVsYXRpdmUgZnVuY3Rpb25zIGluCisvLyBDb2RlZElucHV0U3RyZWFtCitjb25zdCBjaGFyKiBHZXRDYXBpdGFsaXplZFR5cGUoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgYm9vbCBpbW11dGFibGUpOworCisvLyBGb3IgZW5jb2RpbmdzIHdpdGggZml4ZWQgc2l6ZXMsIHJldHVybnMgdGhhdCBzaXplIGluIGJ5dGVzLiAgT3RoZXJ3aXNlCisvLyByZXR1cm5zIC0xLgoraW50IEZpeGVkU2l6ZShGaWVsZERlc2NyaXB0b3I6OlR5cGUgdHlwZSk7CisKKy8vIENvbXBhcmF0b3JzIHVzZWQgdG8gc29ydCBmaWVsZHMgaW4gTWVzc2FnZUdlbmVyYXRvcgorc3RydWN0IEZpZWxkT3JkZXJpbmdCeU51bWJlciB7CisgIGlubGluZSBib29sIG9wZXJhdG9yKCkoY29uc3QgRmllbGREZXNjcmlwdG9yKiBhLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogYikgY29uc3QgeworICAgIHJldHVybiBhLT5udW1iZXIoKSA8IGItPm51bWJlcigpOworICB9Cit9OworCitzdHJ1Y3QgRXh0ZW5zaW9uUmFuZ2VPcmRlcmluZyB7CisgIGJvb2wgb3BlcmF0b3IoKShjb25zdCBEZXNjcmlwdG9yOjpFeHRlbnNpb25SYW5nZSogYSwKKyAgICAgICAgICAgICAgICAgIGNvbnN0IERlc2NyaXB0b3I6OkV4dGVuc2lvblJhbmdlKiBiKSBjb25zdCB7CisgICAgcmV0dXJuIGEtPnN0YXJ0IDwgYi0+c3RhcnQ7CisgIH0KK307CisKKy8vIFNvcnQgdGhlIGZpZWxkcyBvZiB0aGUgZ2l2ZW4gRGVzY3JpcHRvciBieSBudW1iZXIgaW50byBhIG5ld1tdJ2QgYXJyYXkKKy8vIGFuZCByZXR1cm4gaXQuIFRoZSBjYWxsZXIgc2hvdWxkIGRlbGV0ZSB0aGUgcmV0dXJuZWQgYXJyYXkuCitjb25zdCBGaWVsZERlc2NyaXB0b3IqKiBTb3J0RmllbGRzQnlOdW1iZXIoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CisKKy8vIERvZXMgdGhpcyBtZXNzYWdlIGNsYXNzIGhhdmUgYW55IHBhY2tlZCBmaWVsZHM/CitpbmxpbmUgYm9vbCBIYXNQYWNrZWRGaWVsZHMoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3ItPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGlmIChkZXNjcmlwdG9yLT5maWVsZChpKS0+aXNfcGFja2VkKCkpIHsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgfQorICByZXR1cm4gZmFsc2U7Cit9CisKKy8vIENoZWNrIGEgbWVzc2FnZSB0eXBlIGFuZCBpdHMgc3ViLW1lc3NhZ2UgdHlwZXMgcmVjdXJzaXZlbHkgdG8gc2VlIGlmIGFueSBvZgorLy8gdGhlbSBoYXMgYSByZXF1aXJlZCBmaWVsZC4gUmV0dXJuIHRydWUgaWYgYSByZXF1aXJlZCBmaWVsZCBpcyBmb3VuZC4KK2Jvb2wgSGFzUmVxdWlyZWRGaWVsZHMoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CisKKy8vIFdoZXRoZXIgYSAucHJvdG8gZmlsZSBzdXBwb3J0cyBmaWVsZCBwcmVzZW5jZSB0ZXN0IGZvciBub24tbWVzc2FnZSB0eXBlcy4KK2lubGluZSBib29sIFN1cHBvcnRGaWVsZFByZXNlbmNlKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIHJldHVybiBkZXNjcmlwdG9yLT5zeW50YXgoKSAhPSBGaWxlRGVzY3JpcHRvcjo6U1lOVEFYX1BST1RPMzsKK30KKworLy8gV2hldGhlciBnZW5lcmF0ZSBjbGFzc2VzIGV4cG9zZSBwdWJsaWMgUEFSU0VSIGluc3RhbmNlcy4KK2lubGluZSBib29sIEV4cG9zZVB1YmxpY1BhcnNlcihjb25zdCBGaWxlRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICAvLyBUT0RPKGxpdWppc2kpOiBNYXJrIHRoZSBQQVJTRVIgcHJpdmF0ZSBpbiAzLjEueCByZWxlYXNlcy4KKyAgcmV0dXJuIGRlc2NyaXB0b3ItPnN5bnRheCgpID09IEZpbGVEZXNjcmlwdG9yOjpTWU5UQVhfUFJPVE8yOworfQorCisvLyBXaGV0aGVyIHVua25vd24gZW51bSB2YWx1ZXMgYXJlIGtlcHQgKGkuZS4sIG5vdCBzdG9yZWQgaW4gVW5rbm93bkZpZWxkU2V0CisvLyBidXQgaW4gdGhlIG1lc3NhZ2UgYW5kIGNhbiBiZSBxdWVyaWVkIHVzaW5nIGFkZGl0aW9uYWwgZ2V0dGVycyB0aGF0IHJldHVybgorLy8gaW50cy4KK2lubGluZSBib29sIFN1cHBvcnRVbmtub3duRW51bVZhbHVlKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIHJldHVybiBkZXNjcmlwdG9yLT5zeW50YXgoKSA9PSBGaWxlRGVzY3JpcHRvcjo6U1lOVEFYX1BST1RPMzsKK30KKworLy8gQ2hlY2sgd2hldGhlciBhIG1lc2FzZ2UgaGFzIHJlcGVhdGVkIGZpZWxkcy4KK2Jvb2wgSGFzUmVwZWF0ZWRGaWVsZHMoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CisKK2lubGluZSBib29sIElzTWFwRW50cnkoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICByZXR1cm4gZGVzY3JpcHRvci0+b3B0aW9ucygpLm1hcF9lbnRyeSgpOworfQorCitpbmxpbmUgYm9vbCBJc01hcEZpZWxkKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICByZXR1cm4gZGVzY3JpcHRvci0+aXNfbWFwKCk7Cit9CisKK2lubGluZSBib29sIFByZXNlcnZlVW5rbm93bkZpZWxkcyhjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIHJldHVybiBkZXNjcmlwdG9yLT5maWxlKCktPnN5bnRheCgpICE9IEZpbGVEZXNjcmlwdG9yOjpTWU5UQVhfUFJPVE8zOworfQorCitpbmxpbmUgYm9vbCBJc0FueU1lc3NhZ2UoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICByZXR1cm4gZGVzY3JpcHRvci0+ZnVsbF9uYW1lKCkgPT0gImdvb2dsZS5wcm90b2J1Zi5BbnkiOworfQorCitpbmxpbmUgYm9vbCBDaGVja1V0ZjgoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIHJldHVybiBkZXNjcmlwdG9yLT5maWxlKCktPnN5bnRheCgpID09IEZpbGVEZXNjcmlwdG9yOjpTWU5UQVhfUFJPVE8zIHx8CisgICAgICBkZXNjcmlwdG9yLT5maWxlKCktPm9wdGlvbnMoKS5qYXZhX3N0cmluZ19jaGVja191dGY4KCk7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX0hFTFBFUlNfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9sYXp5X21lc3NhZ2VfZmllbGQuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9sYXp5X21lc3NhZ2VfZmllbGQuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGRlOGNiZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2xhenlfbWVzc2FnZV9maWVsZC5jYwpAQCAtMCwwICsxLDgxNCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjogbml3YXNha2lAZ29vZ2xlLmNvbSAoTmFva2kgSXdhc2FraSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9jb250ZXh0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9sYXp5X21lc3NhZ2VfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2RvY19jb21tZW50Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhIHsKKworSW1tdXRhYmxlTGF6eU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitJbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkR2VuZXJhdG9yKAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgIGludCBidWlsZGVyQml0SW5kZXgsCisgICAgQ29udGV4dCogY29udGV4dCkKKyAgICA6IEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcigKKyAgICAgICAgICBkZXNjcmlwdG9yLCBtZXNzYWdlQml0SW5kZXgsIGJ1aWxkZXJCaXRJbmRleCwgY29udGV4dCkgeworfQorCitJbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkR2VuZXJhdG9yOjp+SW1tdXRhYmxlTGF6eU1lc3NhZ2VGaWVsZEdlbmVyYXRvcigpIHt9CisKK3ZvaWQgSW1tdXRhYmxlTGF6eU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlGaWVsZExpdGUgJG5hbWUkXyA9XG4iCisgICAgIiAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5RmllbGRMaXRlKCk7XG4iKTsKKworICBQcmludEV4dHJhRmllbGRJbmZvKHZhcmlhYmxlc18sIHByaW50ZXIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgYm9vbGVhbiBoYXMkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgcmV0dXJuICRnZXRfaGFzX2ZpZWxkX2JpdF9tZXNzYWdlJDtcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljICR0eXBlJCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgcmV0dXJuICgkdHlwZSQpICRuYW1lJF8uZ2V0VmFsdWUoJHR5cGUkLmdldERlZmF1bHRJbnN0YW5jZSgpKTtcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSRPckJ1aWxkZXIgZ2V0JGNhcGl0YWxpemVkX25hbWUkT3JCdWlsZGVyKCkge1xuIgorICAgICIgIHJldHVybiAkbmFtZSRfO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRlck1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gV2hlbiB1c2luZyBuZXN0ZWQtYnVpbGRlcnMsIHRoZSBjb2RlIGluaXRpYWxseSB3b3JrcyBqdXN0IGxpa2UgdGhlCisgIC8vIG5vbi1uZXN0ZWQgYnVpbGRlciBjYXNlLiBJdCBvbmx5IGNyZWF0ZXMgYSBuZXN0ZWQgYnVpbGRlciBsYXppbHkgb24KKyAgLy8gZGVtYW5kIGFuZCB0aGVuIGZvcmV2ZXIgZGVsZWdhdGVzIHRvIGl0IGFmdGVyIGNyZWF0aW9uLgorCisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5RmllbGRMaXRlICRuYW1lJF8gPVxuIgorICAgICIgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTGF6eUZpZWxkTGl0ZSgpO1xuIik7CisKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAvLyBJZiB0aGlzIGJ1aWxkZXIgaXMgbm9uLW51bGwsIGl0IGlzIHVzZWQgYW5kIHRoZSBvdGhlciBmaWVsZHMgYXJlCisgICAgLy8gaWdub3JlZC4KKyAgICAicHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlcjxcbiIKKyAgICAiICAgICR0eXBlJCwgJHR5cGUkLkJ1aWxkZXIsICR0eXBlJE9yQnVpbGRlcj4gJG5hbWUkQnVpbGRlcl87IgorICAgICJcbiIpOworCisgIC8vIFRoZSBjb21tZW50cyBhYm92ZSB0aGUgbWV0aG9kcyBiZWxvdyBhcmUgYmFzZWQgb24gYSBoeXBvdGhldGljYWwKKyAgLy8gZmllbGQgb2YgdHlwZSAiRmllbGQiIGNhbGxlZCAiRmllbGQiLgorCisgIC8vIGJvb2xlYW4gaGFzRmllbGQoKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgYm9vbGVhbiBoYXMkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgcmV0dXJuICRnZXRfaGFzX2ZpZWxkX2JpdF9idWlsZGVyJDtcbiIKKyAgICAifVxuIik7CisKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAgICIgIHJldHVybiAoJHR5cGUkKSAkbmFtZSRfLmdldFZhbHVlKCR0eXBlJC5nZXREZWZhdWx0SW5zdGFuY2UoKSk7XG4iCisgICAgICAifVxuIik7CisKKyAgLy8gRmllbGQuQnVpbGRlciBzZXRGaWVsZChGaWVsZCB2YWx1ZSkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBQcmludE5lc3RlZEJ1aWxkZXJGdW5jdGlvbihwcmludGVyLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgc2V0JGNhcGl0YWxpemVkX25hbWUkKCR0eXBlJCB2YWx1ZSkiLAorCisgICAgImlmICh2YWx1ZSA9PSBudWxsKSB7XG4iCisgICAgIiAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7XG4iCisgICAgIn1cbiIKKyAgICAiJG5hbWUkXy5zZXRWYWx1ZSh2YWx1ZSk7XG4iCisgICAgIiRvbl9jaGFuZ2VkJFxuIiwKKworICAgICBOVUxMLCAgLy8gTGF6eSBmaWVsZHMgYXJlIHN1cHBvcnRlZCBvbmx5IGZvciBsaXRlLXJ1bnRpbWUuCisKKyAgICAiJHNldF9oYXNfZmllbGRfYml0X2J1aWxkZXIkO1xuIgorICAgICJyZXR1cm4gdGhpcztcbiIpOworCisgIC8vIEZpZWxkLkJ1aWxkZXIgc2V0RmllbGQoRmllbGQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgUHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24ocHJpbnRlciwKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIHNldCRjYXBpdGFsaXplZF9uYW1lJChcbiIKKyAgICAiICAgICR0eXBlJC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkiLAorCisgICAgIiRuYW1lJF8uc2V0VmFsdWUoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpO1xuIgorICAgICIkb25fY2hhbmdlZCRcbiIsCisKKyAgICBOVUxMLAorCisgICAgIiRzZXRfaGFzX2ZpZWxkX2JpdF9idWlsZGVyJDtcbiIKKyAgICAicmV0dXJuIHRoaXM7XG4iKTsKKworICAvLyBGaWVsZC5CdWlsZGVyIG1lcmdlRmllbGQoRmllbGQgdmFsdWUpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgUHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24ocHJpbnRlciwKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIG1lcmdlJGNhcGl0YWxpemVkX25hbWUkKCR0eXBlJCB2YWx1ZSkiLAorCisgICAgImlmICgkZ2V0X2hhc19maWVsZF9iaXRfYnVpbGRlciQgJiZcbiIKKyAgICAiICAgICEkbmFtZSRfLmNvbnRhaW5zRGVmYXVsdEluc3RhbmNlKCkpIHtcbiIKKyAgICAiICAkbmFtZSRfLnNldFZhbHVlKFxuIgorICAgICIgICAgJHR5cGUkLm5ld0J1aWxkZXIoXG4iCisgICAgIiAgICAgICAgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkpLm1lcmdlRnJvbSh2YWx1ZSkuYnVpbGRQYXJ0aWFsKCkpO1xuIgorICAgICJ9IGVsc2Uge1xuIgorICAgICIgICRuYW1lJF8uc2V0VmFsdWUodmFsdWUpO1xuIgorICAgICJ9XG4iCisgICAgIiRvbl9jaGFuZ2VkJFxuIiwKKworICAgIE5VTEwsCisKKyAgICAiJHNldF9oYXNfZmllbGRfYml0X2J1aWxkZXIkO1xuIgorICAgICJyZXR1cm4gdGhpcztcbiIpOworCisgIC8vIEZpZWxkLkJ1aWxkZXIgY2xlYXJGaWVsZCgpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgUHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24ocHJpbnRlciwKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGNsZWFyJGNhcGl0YWxpemVkX25hbWUkKCkiLAorCisgICAgIiRuYW1lJF8uY2xlYXIoKTtcbiIKKyAgICAiJG9uX2NoYW5nZWQkXG4iLAorCisgICAgTlVMTCwKKworICAgICIkY2xlYXJfaGFzX2ZpZWxkX2JpdF9idWlsZGVyJDtcbiIKKyAgICAicmV0dXJuIHRoaXM7XG4iKTsKKworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkLkJ1aWxkZXIgZ2V0JGNhcGl0YWxpemVkX25hbWUkQnVpbGRlcigpIHtcbiIKKyAgICAiICAkc2V0X2hhc19maWVsZF9iaXRfYnVpbGRlciQ7XG4iCisgICAgIiAgJG9uX2NoYW5nZWQkXG4iCisgICAgIiAgcmV0dXJuIGdldCRjYXBpdGFsaXplZF9uYW1lJEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTtcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSRPckJ1aWxkZXIgZ2V0JGNhcGl0YWxpemVkX25hbWUkT3JCdWlsZGVyKCkge1xuIgorICAgICIgIGlmICgkbmFtZSRCdWlsZGVyXyAhPSBudWxsKSB7XG4iCisgICAgIiAgICByZXR1cm4gJG5hbWUkQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpO1xuIgorICAgICIgIH0gZWxzZSB7XG4iCisgICAgIiAgICByZXR1cm4gJG5hbWUkXztcbiIKKyAgICAiICB9XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXI8XG4iCisgICAgIiAgICAkdHlwZSQsICR0eXBlJC5CdWlsZGVyLCAkdHlwZSRPckJ1aWxkZXI+IFxuIgorICAgICIgICAgZ2V0JGNhcGl0YWxpemVkX25hbWUkRmllbGRCdWlsZGVyKCkge1xuIgorICAgICIgIGlmICgkbmFtZSRCdWlsZGVyXyA9PSBudWxsKSB7XG4iCisgICAgIiAgICAkbmFtZSRCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlcjxcbiIKKyAgICAiICAgICAgICAkdHlwZSQsICR0eXBlJC5CdWlsZGVyLCAkdHlwZSRPckJ1aWxkZXI+KFxuIgorICAgICIgICAgICAgICAgICAkbmFtZSRfLFxuIgorICAgICIgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLFxuIgorICAgICIgICAgICAgICAgICBpc0NsZWFuKCkpO1xuIgorICAgICIgICAgJG5hbWUkXyA9IG51bGw7XG4iCisgICAgIiAgfVxuIgorICAgICIgIHJldHVybiAkbmFtZSRCdWlsZGVyXztcbiIKKyAgICAifVxuIik7Cit9CisKKwordm9pZCBJbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlSW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sICIkbmFtZSRfLmNsZWFyKCk7XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRlckNsZWFyQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAiJG5hbWUkXy5jbGVhcigpO1xuIik7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sICIkY2xlYXJfaGFzX2ZpZWxkX2JpdF9idWlsZGVyJDtcbiIpOworfQorCit2b2lkIEltbXV0YWJsZUxhenlNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAob3RoZXIuaGFzJGNhcGl0YWxpemVkX25hbWUkKCkpIHtcbiIKKyAgICAiICAkbmFtZSRfLm1lcmdlKG90aGVyLiRuYW1lJF8pO1xuIgorICAgICIgICRzZXRfaGFzX2ZpZWxkX2JpdF9idWlsZGVyJDtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlTGF6eU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUJ1aWxkaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImlmICgkZ2V0X2hhc19maWVsZF9iaXRfZnJvbV9sb2NhbCQpIHtcbiIKKyAgICAgICIgICRzZXRfaGFzX2ZpZWxkX2JpdF90b19sb2NhbCQ7XG4iCisgICAgICAifVxuIik7CisKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJyZXN1bHQuJG5hbWUkXy5zZXQoXG4iCisgICAgICAiICAgICRuYW1lJF8pO1xuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlTGF6eU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVBhcnNpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRuYW1lJF8uc2V0Qnl0ZVN0cmluZyhpbnB1dC5yZWFkQnl0ZXMoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpO1xuIik7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRzZXRfaGFzX2ZpZWxkX2JpdF9tZXNzYWdlJDtcbiIpOworfQorCit2b2lkIEltbXV0YWJsZUxhenlNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBEbyBub3QgZGUtc2VyaWFsaXplIGxhenkgZmllbGRzLgorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoJGdldF9oYXNfZmllbGRfYml0X21lc3NhZ2UkKSB7XG4iCisgICAgIiAgb3V0cHV0LndyaXRlQnl0ZXMoJG51bWJlciQsICRuYW1lJF8udG9CeXRlU3RyaW5nKCkpO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkZ2V0X2hhc19maWVsZF9iaXRfbWVzc2FnZSQpIHtcbiIKKyAgICAiICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW1cbiIKKyAgICAiICAgIC5jb21wdXRlTGF6eUZpZWxkU2l6ZSgkbnVtYmVyJCwgJG5hbWUkXyk7XG4iCisgICAgIn1cbiIpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK0ltbXV0YWJsZUxhenlNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitJbW11dGFibGVMYXp5TWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBtZXNzYWdlQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb250ZXh0KiBjb250ZXh0KQorICAgIDogSW1tdXRhYmxlTGF6eU1lc3NhZ2VGaWVsZEdlbmVyYXRvcigKKyAgICAgICAgICBkZXNjcmlwdG9yLCBtZXNzYWdlQml0SW5kZXgsIGJ1aWxkZXJCaXRJbmRleCwgY29udGV4dCkgeworICBjb25zdCBPbmVvZkdlbmVyYXRvckluZm8qIGluZm8gPQorICAgICAgY29udGV4dC0+R2V0T25lb2ZHZW5lcmF0b3JJbmZvKGRlc2NyaXB0b3ItPmNvbnRhaW5pbmdfb25lb2YoKSk7CisgIFNldENvbW1vbk9uZW9mVmFyaWFibGVzKGRlc2NyaXB0b3IsIGluZm8sICZ2YXJpYWJsZXNfKTsKKyAgdmFyaWFibGVzX1sibGF6eV90eXBlIl0gPSAiY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5RmllbGRMaXRlIjsKK30KKworSW1tdXRhYmxlTGF6eU1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK35JbW11dGFibGVMYXp5TWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3IoKSB7fQorCit2b2lkIEltbXV0YWJsZUxhenlNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgUHJpbnRFeHRyYUZpZWxkSW5mbyh2YXJpYWJsZXNfLCBwcmludGVyKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworCisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgYm9vbGVhbiBoYXMkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgcmV0dXJuICRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJDtcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljICR0eXBlJCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgaWYgKCRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJCkge1xuIgorICAgICIgICAgcmV0dXJuICgkdHlwZSQpICgoJGxhenlfdHlwZSQpICRvbmVvZl9uYW1lJF8pLmdldFZhbHVlKFxuIgorICAgICIgICAgICAgICR0eXBlJC5nZXREZWZhdWx0SW5zdGFuY2UoKSk7XG4iCisgICAgIiAgfVxuIgorICAgICIgIHJldHVybiAkdHlwZSQuZ2V0RGVmYXVsdEluc3RhbmNlKCk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZUxhenlNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUJ1aWxkZXJNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIGJvb2xlYW4gaGFzRmllbGQoKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgYm9vbGVhbiBoYXMkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgcmV0dXJuICRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJDtcbiIKKyAgICAifVxuIik7CisKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSQgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgIGlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIKKyAgICAiICAgIHJldHVybiAoJHR5cGUkKSAoKCRsYXp5X3R5cGUkKSAkb25lb2ZfbmFtZSRfKS5nZXRWYWx1ZShcbiIKKyAgICAiICAgICAgICAkdHlwZSQuZ2V0RGVmYXVsdEluc3RhbmNlKCkpO1xuIgorICAgICIgIH1cbiIKKyAgICAiICByZXR1cm4gJHR5cGUkLmdldERlZmF1bHRJbnN0YW5jZSgpO1xuIgorICAgICJ9XG4iKTsKKworICAvLyBGaWVsZC5CdWlsZGVyIHNldEZpZWxkKEZpZWxkIHZhbHVlKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIFByaW50TmVzdGVkQnVpbGRlckZ1bmN0aW9uKHByaW50ZXIsCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBzZXQkY2FwaXRhbGl6ZWRfbmFtZSQoJHR5cGUkIHZhbHVlKSIsCisKKyAgICAiaWYgKHZhbHVlID09IG51bGwpIHtcbiIKKyAgICAiICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTtcbiIKKyAgICAifVxuIgorICAgICJpZiAoISgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpKSB7XG4iCisgICAgIiAgJG9uZW9mX25hbWUkXyA9IG5ldyAkbGF6eV90eXBlJCgpO1xuIgorICAgICIgICRzZXRfb25lb2ZfY2FzZV9tZXNzYWdlJDtcbiIKKyAgICAifVxuIgorICAgICIoKCRsYXp5X3R5cGUkKSAkb25lb2ZfbmFtZSRfKS5zZXRWYWx1ZSh2YWx1ZSk7XG4iCisgICAgIiRvbl9jaGFuZ2VkJFxuIiwKKworICAgICBOVUxMLCAgLy8gTGF6eSBmaWVsZHMgYXJlIHN1cHBvcnRlZCBvbmx5IGZvciBsaXRlLXJ1bnRpbWUuCisKKyAgICAicmV0dXJuIHRoaXM7XG4iKTsKKworICAvLyBGaWVsZC5CdWlsZGVyIHNldEZpZWxkKEZpZWxkLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIFByaW50TmVzdGVkQnVpbGRlckZ1bmN0aW9uKHByaW50ZXIsCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBzZXQkY2FwaXRhbGl6ZWRfbmFtZSQoXG4iCisgICAgIiAgICAkdHlwZSQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIiwKKworICAgICJpZiAoISgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpKSB7XG4iCisgICAgIiAgJG9uZW9mX25hbWUkXyA9IG5ldyAkbGF6eV90eXBlJCgpO1xuIgorICAgICIgICRzZXRfb25lb2ZfY2FzZV9tZXNzYWdlJDtcbiIKKyAgICAifVxuIgorICAgICIoKCRsYXp5X3R5cGUkKSAkb25lb2ZfbmFtZSRfKS5zZXRWYWx1ZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7XG4iCisgICAgIiRvbl9jaGFuZ2VkJFxuIiwKKworICAgIE5VTEwsCisKKyAgICAicmV0dXJuIHRoaXM7XG4iKTsKKworICAvLyBGaWVsZC5CdWlsZGVyIG1lcmdlRmllbGQoRmllbGQgdmFsdWUpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgUHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24ocHJpbnRlciwKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIG1lcmdlJGNhcGl0YWxpemVkX25hbWUkKCR0eXBlJCB2YWx1ZSkiLAorCisgICAgImlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQgJiZcbiIKKyAgICAiICAgICEoKCRsYXp5X3R5cGUkKSAkb25lb2ZfbmFtZSRfKS5jb250YWluc0RlZmF1bHRJbnN0YW5jZSgpKSB7XG4iCisgICAgIiAgKCgkbGF6eV90eXBlJCkgJG9uZW9mX25hbWUkXykuc2V0VmFsdWUoXG4iCisgICAgIiAgICAkdHlwZSQubmV3QnVpbGRlcihcbiIKKyAgICAiICAgICAgICBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSkubWVyZ2VGcm9tKHZhbHVlKS5idWlsZFBhcnRpYWwoKSk7XG4iCisgICAgIn0gZWxzZSB7XG4iCisgICAgIiAgaWYgKCEoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSkge1xuIgorICAgICIgICAgJG9uZW9mX25hbWUkXyA9IG5ldyAkbGF6eV90eXBlJCgpO1xuIgorICAgICIgICAgJHNldF9vbmVvZl9jYXNlX21lc3NhZ2UkO1xuIgorICAgICIgIH1cbiIKKyAgICAiICAoKCRsYXp5X3R5cGUkKSAkb25lb2ZfbmFtZSRfKS5zZXRWYWx1ZSh2YWx1ZSk7XG4iCisgICAgIn1cbiIKKyAgICAiJG9uX2NoYW5nZWQkXG4iLAorCisgICAgTlVMTCwKKworICAgICJyZXR1cm4gdGhpcztcbiIpOworCisgIC8vIEZpZWxkLkJ1aWxkZXIgY2xlYXJGaWVsZCgpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgUHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24ocHJpbnRlciwKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGNsZWFyJGNhcGl0YWxpemVkX25hbWUkKCkiLAorCisgICAgImlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIKKyAgICAiICAkY2xlYXJfb25lb2ZfY2FzZV9tZXNzYWdlJDtcbiIKKyAgICAiICAkb25lb2ZfbmFtZSRfID0gbnVsbDtcbiIKKyAgICAiICAkb25fY2hhbmdlZCRcbiIKKyAgICAifVxuIiwKKworICAgIE5VTEwsCisKKyAgICAicmV0dXJuIHRoaXM7XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVMYXp5TWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoISgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpKSB7XG4iCisgICAgIiAgJG9uZW9mX25hbWUkXyA9IG5ldyAkbGF6eV90eXBlJCgpO1xuIgorICAgICJ9XG4iCisgICAgIigoJGxhenlfdHlwZSQpICRvbmVvZl9uYW1lJF8pLm1lcmdlKFxuIgorICAgICIgICAgKCRsYXp5X3R5cGUkKSBvdGhlci4kb25lb2ZfbmFtZSRfKTtcbiIKKyAgICAiJHNldF9vbmVvZl9jYXNlX21lc3NhZ2UkO1xuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlTGF6eU1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICAgICAgICAgICJpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJyZXN1bHQuJG9uZW9mX25hbWUkXyA9IG5ldyAkbGF6eV90eXBlJCgpO1xuIgorICAgICAgIigoJGxhenlfdHlwZSQpIHJlc3VsdC4kb25lb2ZfbmFtZSRfKS5zZXQoXG4iCisgICAgICAiICAgICgoJGxhenlfdHlwZSQpICRvbmVvZl9uYW1lJF8pKTtcbiIpOworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KCJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVMYXp5TWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVQYXJzaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoISgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpKSB7XG4iCisgICAgIiAgJG9uZW9mX25hbWUkXyA9IG5ldyAkbGF6eV90eXBlJCgpO1xuIgorICAgICJ9XG4iCisgICAgIigoJGxhenlfdHlwZSQpICRvbmVvZl9uYW1lJF8pLnNldEJ5dGVTdHJpbmcoXG4iCisgICAgIiAgICBpbnB1dC5yZWFkQnl0ZXMoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpO1xuIgorICAgICIkc2V0X29uZW9mX2Nhc2VfbWVzc2FnZSQ7XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVMYXp5TWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBEbyBub3QgZGUtc2VyaWFsaXplIGxhenkgZmllbGRzLgorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iCisgICAgIiAgb3V0cHV0LndyaXRlQnl0ZXMoXG4iCisgICAgIiAgICAgICRudW1iZXIkLCAoKCRsYXp5X3R5cGUkKSAkb25lb2ZfbmFtZSRfKS50b0J5dGVTdHJpbmcoKSk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZUxhenlNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iCisgICAgIiAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtXG4iCisgICAgIiAgICAuY29tcHV0ZUxhenlGaWVsZFNpemUoJG51bWJlciQsICgkbGF6eV90eXBlJCkgJG9uZW9mX25hbWUkXyk7XG4iCisgICAgIn1cbiIpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK1JlcGVhdGVkSW1tdXRhYmxlTGF6eU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitSZXBlYXRlZEltbXV0YWJsZUxhenlNZXNzYWdlRmllbGRHZW5lcmF0b3IoCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgIGludCBtZXNzYWdlQml0SW5kZXgsCisgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwKKyAgICBDb250ZXh0KiBjb250ZXh0KQorICAgIDogUmVwZWF0ZWRJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3IoCisgICAgICAgICAgZGVzY3JpcHRvciwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsIGNvbnRleHQpIHsKK30KKworCitSZXBlYXRlZEltbXV0YWJsZUxhenlNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorflJlcGVhdGVkSW1tdXRhYmxlTGF6eU1lc3NhZ2VGaWVsZEdlbmVyYXRvcigpIHt9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuTGF6eUZpZWxkTGl0ZT4gJG5hbWUkXztcbiIpOworICBQcmludEV4dHJhRmllbGRJbmZvKHZhcmlhYmxlc18sIHByaW50ZXIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgamF2YS51dGlsLkxpc3Q8JHR5cGUkPlxuIgorICAgICIgICAgZ2V0JGNhcGl0YWxpemVkX25hbWUkTGlzdCgpIHtcbiIKKyAgICAiICBqYXZhLnV0aWwuTGlzdDwkdHlwZSQ+IGxpc3QgPVxuIgorICAgICIgICAgICBuZXcgamF2YS51dGlsLkFycmF5TGlzdDwkdHlwZSQ+KCRuYW1lJF8uc2l6ZSgpKTtcbiIKKyAgICAiICBmb3IgKGNvbS5nb29nbGUucHJvdG9idWYuTGF6eUZpZWxkTGl0ZSBsZiA6ICRuYW1lJF8pIHtcbiIKKyAgICAiICAgIGxpc3QuYWRkKCgkdHlwZSQpIGxmLmdldFZhbHVlKCR0eXBlJC5nZXREZWZhdWx0SW5zdGFuY2UoKSkpO1xuIgorICAgICIgIH1cbiIKKyAgICAiICByZXR1cm4gbGlzdDtcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgJHR5cGUkT3JCdWlsZGVyPlxuIgorICAgICIgICAgZ2V0JGNhcGl0YWxpemVkX25hbWUkT3JCdWlsZGVyTGlzdCgpIHtcbiIKKyAgICAiICByZXR1cm4gZ2V0JGNhcGl0YWxpemVkX25hbWUkTGlzdCgpO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIGludCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRDb3VudCgpIHtcbiIKKyAgICAiICByZXR1cm4gJG5hbWUkXy5zaXplKCk7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkIGdldCRjYXBpdGFsaXplZF9uYW1lJChpbnQgaW5kZXgpIHtcbiIKKyAgICAiICByZXR1cm4gKCR0eXBlJClcbiIKKyAgICAiICAgICAgJG5hbWUkXy5nZXQoaW5kZXgpLmdldFZhbHVlKCR0eXBlJC5nZXREZWZhdWx0SW5zdGFuY2UoKSk7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkT3JCdWlsZGVyIGdldCRjYXBpdGFsaXplZF9uYW1lJE9yQnVpbGRlcihcbiIKKyAgICAiICAgIGludCBpbmRleCkge1xuIgorICAgICIgIHJldHVybiAoJHR5cGUkT3JCdWlsZGVyKVxuIgorICAgICIgICAgICAkbmFtZSRfLmdldChpbmRleCkuZ2V0VmFsdWUoJHR5cGUkLmdldERlZmF1bHRJbnN0YW5jZSgpKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRlck1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gV2hlbiB1c2luZyBuZXN0ZWQtYnVpbGRlcnMsIHRoZSBjb2RlIGluaXRpYWxseSB3b3JrcyBqdXN0IGxpa2UgdGhlCisgIC8vIG5vbi1uZXN0ZWQgYnVpbGRlciBjYXNlLiBJdCBvbmx5IGNyZWF0ZXMgYSBuZXN0ZWQgYnVpbGRlciBsYXppbHkgb24KKyAgLy8gZGVtYW5kIGFuZCB0aGVuIGZvcmV2ZXIgZGVsZWdhdGVzIHRvIGl0IGFmdGVyIGNyZWF0aW9uLgorCisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5RmllbGRMaXRlPiAkbmFtZSRfID1cbiIKKyAgICAiICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7XG4iCisKKyAgICAicHJpdmF0ZSB2b2lkIGVuc3VyZSRjYXBpdGFsaXplZF9uYW1lJElzTXV0YWJsZSgpIHtcbiIKKyAgICAiICBpZiAoISRnZXRfbXV0YWJsZV9iaXRfYnVpbGRlciQpIHtcbiIKKyAgICAiICAgICRuYW1lJF8gPVxuIgorICAgICIgICAgICAgIG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGNvbS5nb29nbGUucHJvdG9idWYuTGF6eUZpZWxkTGl0ZT4oXG4iCisgICAgIiAgICAgICAgICAgICRuYW1lJF8pO1xuIgorICAgICIgICAgJHNldF9tdXRhYmxlX2JpdF9idWlsZGVyJDtcbiIKKyAgICAiICAgfVxuIgorICAgICJ9XG4iCisgICAgIlxuIik7CisKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAvLyBJZiB0aGlzIGJ1aWxkZXIgaXMgbm9uLW51bGwsIGl0IGlzIHVzZWQgYW5kIHRoZSBvdGhlciBmaWVsZHMgYXJlCisgICAgLy8gaWdub3JlZC4KKyAgICAicHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyPFxuIgorICAgICIgICAgJHR5cGUkLCAkdHlwZSQuQnVpbGRlciwgJHR5cGUkT3JCdWlsZGVyPiAkbmFtZSRCdWlsZGVyXztcbiIKKyAgICAiXG4iKTsKKworICAvLyBUaGUgY29tbWVudHMgYWJvdmUgdGhlIG1ldGhvZHMgYmVsb3cgYXJlIGJhc2VkIG9uIGEgaHlwb3RoZXRpY2FsCisgIC8vIHJlcGVhdGVkIGZpZWxkIG9mIHR5cGUgIkZpZWxkIiBjYWxsZWQgIlJlcGVhdGVkRmllbGQiLgorCisgIC8vIExpc3Q8RmllbGQ+IGdldFJlcGVhdGVkRmllbGRMaXN0KCkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBQcmludE5lc3RlZEJ1aWxkZXJGdW5jdGlvbihwcmludGVyLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIGphdmEudXRpbC5MaXN0PCR0eXBlJD4gZ2V0JGNhcGl0YWxpemVkX25hbWUkTGlzdCgpIiwKKworICAgICJqYXZhLnV0aWwuTGlzdDwkdHlwZSQ+IGxpc3QgPVxuIgorICAgICIgICAgbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8JHR5cGUkPigkbmFtZSRfLnNpemUoKSk7XG4iCisgICAgImZvciAoY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5RmllbGRMaXRlIGxmIDogJG5hbWUkXykge1xuIgorICAgICIgIGxpc3QuYWRkKCgkdHlwZSQpIGxmLmdldFZhbHVlKCR0eXBlJC5nZXREZWZhdWx0SW5zdGFuY2UoKSkpO1xuIgorICAgICJ9XG4iCisgICAgInJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChsaXN0KTtcbiIsCisKKyAgICAicmV0dXJuICRuYW1lJEJ1aWxkZXJfLmdldE1lc3NhZ2VMaXN0KCk7XG4iLAorCisgICAgTlVMTCk7CisKKyAgLy8gaW50IGdldFJlcGVhdGVkRmllbGRDb3VudCgpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgUHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24ocHJpbnRlciwKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBpbnQgZ2V0JGNhcGl0YWxpemVkX25hbWUkQ291bnQoKSIsCisKKyAgICAicmV0dXJuICRuYW1lJF8uc2l6ZSgpO1xuIiwKKyAgICAicmV0dXJuICRuYW1lJEJ1aWxkZXJfLmdldENvdW50KCk7XG4iLAorCisgICAgTlVMTCk7CisKKyAgLy8gRmllbGQgZ2V0UmVwZWF0ZWRGaWVsZChpbnQgaW5kZXgpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgUHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24ocHJpbnRlciwKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSQgZ2V0JGNhcGl0YWxpemVkX25hbWUkKGludCBpbmRleCkiLAorCisgICAgInJldHVybiAoJHR5cGUkKSAkbmFtZSRfLmdldChpbmRleCkuZ2V0VmFsdWUoXG4iCisgICAgIiAgICAkdHlwZSQuZ2V0RGVmYXVsdEluc3RhbmNlKCkpO1xuIiwKKworICAgICJyZXR1cm4gJG5hbWUkQnVpbGRlcl8uZ2V0TWVzc2FnZShpbmRleCk7XG4iLAorCisgICAgTlVMTCk7CisKKyAgLy8gQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKGludCBpbmRleCwgRmllbGQgdmFsdWUpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgUHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24ocHJpbnRlciwKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIHNldCRjYXBpdGFsaXplZF9uYW1lJChcbiIKKyAgICAiICAgIGludCBpbmRleCwgJHR5cGUkIHZhbHVlKSIsCisgICAgImlmICh2YWx1ZSA9PSBudWxsKSB7XG4iCisgICAgIiAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7XG4iCisgICAgIn1cbiIKKyAgICAiZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCk7XG4iCisgICAgIiRuYW1lJF8uc2V0KGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlGaWVsZExpdGUuZnJvbVZhbHVlKHZhbHVlKSk7XG4iCisgICAgIiRvbl9jaGFuZ2VkJFxuIiwKKyAgICAiJG5hbWUkQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgdmFsdWUpO1xuIiwKKyAgICAicmV0dXJuIHRoaXM7XG4iKTsKKworICAvLyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoaW50IGluZGV4LCBGaWVsZC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBQcmludE5lc3RlZEJ1aWxkZXJGdW5jdGlvbihwcmludGVyLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgc2V0JGNhcGl0YWxpemVkX25hbWUkKFxuIgorICAgICIgICAgaW50IGluZGV4LCAkdHlwZSQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIiwKKworICAgICJlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKTtcbiIKKyAgICAiJG5hbWUkXy5zZXQoaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eUZpZWxkTGl0ZS5mcm9tVmFsdWUoXG4iCisgICAgIiAgICBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSkpO1xuIgorICAgICIkb25fY2hhbmdlZCRcbiIsCisKKyAgICAiJG5hbWUkQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpO1xuIiwKKworICAgICJyZXR1cm4gdGhpcztcbiIpOworCisgIC8vIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZChGaWVsZCB2YWx1ZSkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBQcmludE5lc3RlZEJ1aWxkZXJGdW5jdGlvbihwcmludGVyLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgYWRkJGNhcGl0YWxpemVkX25hbWUkKCR0eXBlJCB2YWx1ZSkiLAorCisgICAgImlmICh2YWx1ZSA9PSBudWxsKSB7XG4iCisgICAgIiAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7XG4iCisgICAgIn1cbiIKKyAgICAiZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCk7XG4iCisgICAgIiRuYW1lJF8uYWRkKGNvbS5nb29nbGUucHJvdG9idWYuTGF6eUZpZWxkTGl0ZS5mcm9tVmFsdWUodmFsdWUpKTtcbiIKKworICAgICIkb25fY2hhbmdlZCRcbiIsCisKKyAgICAiJG5hbWUkQnVpbGRlcl8uYWRkTWVzc2FnZSh2YWx1ZSk7XG4iLAorCisgICAgInJldHVybiB0aGlzO1xuIik7CisKKyAgLy8gQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKGludCBpbmRleCwgRmllbGQgdmFsdWUpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgUHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24ocHJpbnRlciwKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGFkZCRjYXBpdGFsaXplZF9uYW1lJChcbiIKKyAgICAiICAgIGludCBpbmRleCwgJHR5cGUkIHZhbHVlKSIsCisKKyAgICAiaWYgKHZhbHVlID09IG51bGwpIHtcbiIKKyAgICAiICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTtcbiIKKyAgICAifVxuIgorICAgICJlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKTtcbiIKKyAgICAiJG5hbWUkXy5hZGQoaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eUZpZWxkTGl0ZS5mcm9tVmFsdWUodmFsdWUpKTtcbiIKKyAgICAiJG9uX2NoYW5nZWQkXG4iLAorCisgICAgIiRuYW1lJEJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTtcbiIsCisKKyAgICAicmV0dXJuIHRoaXM7XG4iKTsKKworICAvLyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoRmllbGQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgUHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24ocHJpbnRlciwKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGFkZCRjYXBpdGFsaXplZF9uYW1lJChcbiIKKyAgICAiICAgICR0eXBlJC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkiLAorCisgICAgImVuc3VyZSRjYXBpdGFsaXplZF9uYW1lJElzTXV0YWJsZSgpO1xuIgorICAgICIkbmFtZSRfLmFkZChjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlGaWVsZExpdGUuZnJvbVZhbHVlKFxuIgorICAgICIgICAgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpKTtcbiIKKyAgICAiJG9uX2NoYW5nZWQkXG4iLAorCisgICAgIiRuYW1lJEJ1aWxkZXJfLmFkZE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpO1xuIiwKKworICAgICJyZXR1cm4gdGhpcztcbiIpOworCisgIC8vIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZChpbnQgaW5kZXgsIEZpZWxkLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIFByaW50TmVzdGVkQnVpbGRlckZ1bmN0aW9uKHByaW50ZXIsCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBhZGQkY2FwaXRhbGl6ZWRfbmFtZSQoXG4iCisgICAgIiAgICBpbnQgaW5kZXgsICR0eXBlJC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkiLAorCisgICAgImVuc3VyZSRjYXBpdGFsaXplZF9uYW1lJElzTXV0YWJsZSgpO1xuIgorICAgICIkbmFtZSRfLmFkZChpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5RmllbGRMaXRlLmZyb21WYWx1ZShcbiIKKyAgICAiICAgIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKSk7XG4iCisgICAgIiRvbl9jaGFuZ2VkJFxuIiwKKworICAgICIkbmFtZSRCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7XG4iLAorCisgICAgInJldHVybiB0aGlzO1xuIik7CisKKyAgLy8gQnVpbGRlciBhZGRBbGxSZXBlYXRlZEZpZWxkKEl0ZXJhYmxlPEZpZWxkPiB2YWx1ZXMpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgUHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24ocHJpbnRlciwKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGFkZEFsbCRjYXBpdGFsaXplZF9uYW1lJChcbiIKKyAgICAiICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgJHR5cGUkPiB2YWx1ZXMpIiwKKworICAgICJlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKTtcbiIKKyAgICAiZm9yIChjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VMaXRlIHYgOiB2YWx1ZXMpIHtcbiIKKyAgICAiICAkbmFtZSRfLmFkZChjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlGaWVsZExpdGUuZnJvbVZhbHVlKHYpKTtcbiIKKyAgICAifVxuIgorICAgICIkb25fY2hhbmdlZCRcbiIsCisKKyAgICAiJG5hbWUkQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXModmFsdWVzKTtcbiIsCisKKyAgICAicmV0dXJuIHRoaXM7XG4iKTsKKworICAvLyBCdWlsZGVyIGNsZWFyQWxsUmVwZWF0ZWRGaWVsZCgpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgUHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24ocHJpbnRlciwKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGNsZWFyJGNhcGl0YWxpemVkX25hbWUkKCkiLAorCisgICAgIiRuYW1lJF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7XG4iCisgICAgIiRjbGVhcl9tdXRhYmxlX2JpdF9idWlsZGVyJDtcbiIKKyAgICAiJG9uX2NoYW5nZWQkXG4iLAorCisgICAgIiRuYW1lJEJ1aWxkZXJfLmNsZWFyKCk7XG4iLAorCisgICAgInJldHVybiB0aGlzO1xuIik7CisKKyAgLy8gQnVpbGRlciByZW1vdmVSZXBlYXRlZEZpZWxkKGludCBpbmRleCkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBQcmludE5lc3RlZEJ1aWxkZXJGdW5jdGlvbihwcmludGVyLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgcmVtb3ZlJGNhcGl0YWxpemVkX25hbWUkKGludCBpbmRleCkiLAorCisgICAgImVuc3VyZSRjYXBpdGFsaXplZF9uYW1lJElzTXV0YWJsZSgpO1xuIgorICAgICIkbmFtZSRfLnJlbW92ZShpbmRleCk7XG4iCisgICAgIiRvbl9jaGFuZ2VkJFxuIiwKKworICAgICIkbmFtZSRCdWlsZGVyXy5yZW1vdmUoaW5kZXgpO1xuIiwKKworICAgICJyZXR1cm4gdGhpcztcbiIpOworCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSQuQnVpbGRlciBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRCdWlsZGVyKFxuIgorICAgICIgICAgaW50IGluZGV4KSB7XG4iCisgICAgIiAgcmV0dXJuIGdldCRjYXBpdGFsaXplZF9uYW1lJEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoaW5kZXgpO1xuIgorICAgICJ9XG4iKTsKKworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljICR0eXBlJE9yQnVpbGRlciBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRPckJ1aWxkZXIoXG4iCisgICAgIiAgICBpbnQgaW5kZXgpIHtcbiIKKyAgICAiICBpZiAoJG5hbWUkQnVpbGRlcl8gPT0gbnVsbCkge1xuIgorICAgICIgICAgcmV0dXJuICRuYW1lJF8uZ2V0KGluZGV4KTsiCisgICAgIiAgfSBlbHNlIHtcbiIKKyAgICAiICAgIHJldHVybiAkbmFtZSRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKGluZGV4KTtcbiIKKyAgICAiICB9XG4iCisgICAgIn1cbiIpOworCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzICR0eXBlJE9yQnVpbGRlcj4gXG4iCisgICAgIiAgICAgZ2V0JGNhcGl0YWxpemVkX25hbWUkT3JCdWlsZGVyTGlzdCgpIHtcbiIKKyAgICAiICBpZiAoJG5hbWUkQnVpbGRlcl8gIT0gbnVsbCkge1xuIgorICAgICIgICAgcmV0dXJuICRuYW1lJEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXJMaXN0KCk7XG4iCisgICAgIiAgfSBlbHNlIHtcbiIKKyAgICAiICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdCgkbmFtZSRfKTtcbiIKKyAgICAiICB9XG4iCisgICAgIn1cbiIpOworCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkLkJ1aWxkZXIgYWRkJGNhcGl0YWxpemVkX25hbWUkQnVpbGRlcigpIHtcbiIKKyAgICAiICByZXR1cm4gZ2V0JGNhcGl0YWxpemVkX25hbWUkRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcihcbiIKKyAgICAiICAgICAgJHR5cGUkLmdldERlZmF1bHRJbnN0YW5jZSgpKTtcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkLkJ1aWxkZXIgYWRkJGNhcGl0YWxpemVkX25hbWUkQnVpbGRlcihcbiIKKyAgICAiICAgIGludCBpbmRleCkge1xuIgorICAgICIgIHJldHVybiBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKFxuIgorICAgICIgICAgICBpbmRleCwgJHR5cGUkLmdldERlZmF1bHRJbnN0YW5jZSgpKTtcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgamF2YS51dGlsLkxpc3Q8JHR5cGUkLkJ1aWxkZXI+IFxuIgorICAgICIgICAgIGdldCRjYXBpdGFsaXplZF9uYW1lJEJ1aWxkZXJMaXN0KCkge1xuIgorICAgICIgIHJldHVybiBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyTGlzdCgpO1xuIgorICAgICJ9XG4iCisgICAgInByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlcjxcbiIKKyAgICAiICAgICR0eXBlJCwgJHR5cGUkLkJ1aWxkZXIsICR0eXBlJE9yQnVpbGRlcj4gXG4iCisgICAgIiAgICBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRGaWVsZEJ1aWxkZXIoKSB7XG4iCisgICAgIiAgaWYgKCRuYW1lJEJ1aWxkZXJfID09IG51bGwpIHtcbiIKKyAgICAiICAgICRuYW1lJEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXI8XG4iCisgICAgIiAgICAgICAgJHR5cGUkLCAkdHlwZSQuQnVpbGRlciwgJHR5cGUkT3JCdWlsZGVyPihcbiIKKyAgICAiICAgICAgICAgICAgJG5hbWUkXyxcbiIKKyAgICAiICAgICAgICAgICAgJGdldF9tdXRhYmxlX2JpdF9idWlsZGVyJCxcbiIKKyAgICAiICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSxcbiIKKyAgICAiICAgICAgICAgICAgaXNDbGVhbigpKTtcbiIKKyAgICAiICAgICRuYW1lJF8gPSBudWxsO1xuIgorICAgICIgIH1cbiIKKyAgICAiICByZXR1cm4gJG5hbWUkQnVpbGRlcl87XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlTGF6eU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVBhcnNpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICghJGdldF9tdXRhYmxlX2JpdF9wYXJzZXIkKSB7XG4iCisgICAgIiAgJG5hbWUkXyA9XG4iCisgICAgIiAgICAgIG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGNvbS5nb29nbGUucHJvdG9idWYuTGF6eUZpZWxkTGl0ZT4oKTtcbiIKKyAgICAiICAkc2V0X211dGFibGVfYml0X3BhcnNlciQ7XG4iCisgICAgIn1cbiIKKyAgICAiJG5hbWUkXy5hZGQobmV3IGNvbS5nb29nbGUucHJvdG9idWYuTGF6eUZpZWxkTGl0ZShcbiIKKyAgICAiICAgIGV4dGVuc2lvblJlZ2lzdHJ5LCBpbnB1dC5yZWFkQnl0ZXMoKSkpO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiZm9yIChpbnQgaSA9IDA7IGkgPCAkbmFtZSRfLnNpemUoKTsgaSsrKSB7XG4iCisgICAgIiAgb3V0cHV0LndyaXRlQnl0ZXMoJG51bWJlciQsICRuYW1lJF8uZ2V0KGkpLnRvQnl0ZVN0cmluZygpKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImZvciAoaW50IGkgPSAwOyBpIDwgJG5hbWUkXy5zaXplKCk7IGkrKykge1xuIgorICAgICIgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbVxuIgorICAgICIgICAgLmNvbXB1dGVMYXp5RmllbGRTaXplKCRudW1iZXIkLCAkbmFtZSRfLmdldChpKSk7XG4iCisgICAgIn1cbiIpOworfQorCit9ICAvLyBuYW1lc3BhY2UgamF2YQorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2xhenlfbWVzc2FnZV9maWVsZC5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbGF6eV9tZXNzYWdlX2ZpZWxkLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjFiN2YyOAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2xhenlfbWVzc2FnZV9maWVsZC5oCkBAIC0wLDAgKzEsMTIxIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBuaXdhc2FraUBnb29nbGUuY29tIChOYW9raSBJd2FzYWtpKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfTEFaWV9NRVNTQUdFX0ZJRUxEX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9MQVpZX01FU1NBR0VfRklFTERfSF9fCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tZXNzYWdlX2ZpZWxkLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKyAgbmFtZXNwYWNlIGNvbXBpbGVyIHsKKyAgICBuYW1lc3BhY2UgamF2YSB7CisgICAgICBjbGFzcyBDb250ZXh0OyAgLy8gY29udGV4dC5oCisgICAgfQorICB9Cit9CisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmEgeworCitjbGFzcyBJbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkR2VuZXJhdG9yCisgICAgOiBwdWJsaWMgSW1tdXRhYmxlTWVzc2FnZUZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IEltbXV0YWJsZUxhenlNZXNzYWdlRmllbGRHZW5lcmF0b3IoCisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGludCBtZXNzYWdlQml0SW5kZXgsCisgICAgICBpbnQgYnVpbGRlckJpdEluZGV4LCBDb250ZXh0KiBjb250ZXh0KTsKKyAgfkltbXV0YWJsZUxhenlNZXNzYWdlRmllbGRHZW5lcmF0b3IoKTsKKworICAvLyBvdmVycm9hZHMgSW1tdXRhYmxlTWVzc2FnZUZpZWxkR2VuZXJhdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICB2b2lkIEdlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnVpbGRlckNsZWFyQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCdWlsZGluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhJbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkR2VuZXJhdG9yKTsKK307CisKK2NsYXNzIEltbXV0YWJsZUxhenlNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcgorICAgIDogcHVibGljIEltbXV0YWJsZUxhenlNZXNzYWdlRmllbGRHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgSW1tdXRhYmxlTGF6eU1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yKAorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwgQ29udGV4dCogY29udGV4dCk7CisgIH5JbW11dGFibGVMYXp5TWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3IoKTsKKworICB2b2lkIEdlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCdWlsZGluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhJbW11dGFibGVMYXp5TWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3IpOworfTsKKworY2xhc3MgUmVwZWF0ZWRJbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkR2VuZXJhdG9yCisgICAgOiBwdWJsaWMgUmVwZWF0ZWRJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgUmVwZWF0ZWRJbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkR2VuZXJhdG9yKAorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwgQ29udGV4dCogY29udGV4dCk7CisgIH5SZXBlYXRlZEltbXV0YWJsZUxhenlNZXNzYWdlRmllbGRHZW5lcmF0b3IoKTsKKworICAvLyBvdmVycm9hZHMgUmVwZWF0ZWRJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICB2b2lkIEdlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVQYXJzaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFJlcGVhdGVkSW1tdXRhYmxlTGF6eU1lc3NhZ2VGaWVsZEdlbmVyYXRvcik7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgamF2YQorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9MQVpZX01FU1NBR0VfRklFTERfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9sYXp5X21lc3NhZ2VfZmllbGRfbGl0ZS5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2xhenlfbWVzc2FnZV9maWVsZF9saXRlLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI4M2JhMWQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9sYXp5X21lc3NhZ2VfZmllbGRfbGl0ZS5jYwpAQCAtMCwwICsxLDcwOCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjogbml3YXNha2lAZ29vZ2xlLmNvbSAoTmFva2kgSXdhc2FraSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9jb250ZXh0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9sYXp5X21lc3NhZ2VfZmllbGRfbGl0ZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZG9jX2NvbW1lbnQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmEgeworCitJbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitJbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkTGl0ZUdlbmVyYXRvcigKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgaW50IG1lc3NhZ2VCaXRJbmRleCwKKyAgICBpbnQgYnVpbGRlckJpdEluZGV4LAorICAgIENvbnRleHQqIGNvbnRleHQpCisgICAgOiBJbW11dGFibGVNZXNzYWdlRmllbGRMaXRlR2VuZXJhdG9yKAorICAgICAgICAgIGRlc2NyaXB0b3IsIG1lc3NhZ2VCaXRJbmRleCwgYnVpbGRlckJpdEluZGV4LCBjb250ZXh0KSB7Cit9CisKK0ltbXV0YWJsZUxhenlNZXNzYWdlRmllbGRMaXRlR2VuZXJhdG9yOjoKK35JbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkTGl0ZUdlbmVyYXRvcigpIHt9CisKK3ZvaWQgSW1tdXRhYmxlTGF6eU1lc3NhZ2VGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5RmllbGRMaXRlICRuYW1lJF8gPVxuIgorICAgICIgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTGF6eUZpZWxkTGl0ZSgpO1xuIik7CisKKyAgUHJpbnRFeHRyYUZpZWxkSW5mbyh2YXJpYWJsZXNfLCBwcmludGVyKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIGJvb2xlYW4gaGFzJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgIHJldHVybiAkZ2V0X2hhc19maWVsZF9iaXRfbWVzc2FnZSQ7XG4iCisgICAgIn1cbiIpOworCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSQgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgIHJldHVybiAoJHR5cGUkKSAkbmFtZSRfLmdldFZhbHVlKCR0eXBlJC5nZXREZWZhdWx0SW5zdGFuY2UoKSk7XG4iCisgICAifVxuIik7CisKKyAgLy8gRmllbGQuQnVpbGRlciBzZXRGaWVsZChGaWVsZCB2YWx1ZSkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIHZvaWQgc2V0JGNhcGl0YWxpemVkX25hbWUkKCR0eXBlJCB2YWx1ZSkge1xuIgorICAgICIgIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4iCisgICAgIiAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTtcbiIKKyAgICAiICB9XG4iCisgICAgIiAgJG5hbWUkXy5zZXRWYWx1ZSh2YWx1ZSk7XG4iCisgICAgIiAgJHNldF9oYXNfZmllbGRfYml0X21lc3NhZ2UkO1xuIgorICAgICJ9XG4iKTsKKworICAvLyBGaWVsZC5CdWlsZGVyIHNldEZpZWxkKEZpZWxkLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgdm9pZCBzZXQkY2FwaXRhbGl6ZWRfbmFtZSQoXG4iCisgICAgIiAgICAkdHlwZSQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHtcbiIKKyAgICAiICAkbmFtZSRfLnNldFZhbHVlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTtcbiIKKyAgICAiICAkc2V0X2hhc19maWVsZF9iaXRfbWVzc2FnZSQ7XG4iCisgICAgIn1cbiIpOworCisgIC8vIEZpZWxkLkJ1aWxkZXIgbWVyZ2VGaWVsZChGaWVsZCB2YWx1ZSkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIHZvaWQgbWVyZ2UkY2FwaXRhbGl6ZWRfbmFtZSQoJHR5cGUkIHZhbHVlKSB7XG4iCisgICAgIiAgaWYgKCRnZXRfaGFzX2ZpZWxkX2JpdF9tZXNzYWdlJCAmJlxuIgorICAgICIgICAgICAhJG5hbWUkXy5jb250YWluc0RlZmF1bHRJbnN0YW5jZSgpKSB7XG4iCisgICAgIiAgICAkbmFtZSRfLnNldFZhbHVlKFxuIgorICAgICIgICAgICAkdHlwZSQubmV3QnVpbGRlcihcbiIKKyAgICAiICAgICAgICAgIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpKS5tZXJnZUZyb20odmFsdWUpLmJ1aWxkUGFydGlhbCgpKTtcbiIKKyAgICAiICB9IGVsc2Uge1xuIgorICAgICIgICAgJG5hbWUkXy5zZXRWYWx1ZSh2YWx1ZSk7XG4iCisgICAgIiAgfVxuIgorICAgICIgICRzZXRfaGFzX2ZpZWxkX2JpdF9tZXNzYWdlJDtcbiIKKyAgICAifVxuIik7CisKKyAgLy8gRmllbGQuQnVpbGRlciBjbGVhckZpZWxkKCkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIHZvaWQgY2xlYXIkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgJG5hbWUkXy5jbGVhcigpO1xuIgorICAgICIgICRjbGVhcl9oYXNfZmllbGRfYml0X21lc3NhZ2UkO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUJ1aWxkZXJNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIFRoZSBjb21tZW50cyBhYm92ZSB0aGUgbWV0aG9kcyBiZWxvdyBhcmUgYmFzZWQgb24gYSBoeXBvdGhldGljYWwKKyAgLy8gZmllbGQgb2YgdHlwZSAiRmllbGQiIGNhbGxlZCAiRmllbGQiLgorCisgIC8vIGJvb2xlYW4gaGFzRmllbGQoKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgYm9vbGVhbiBoYXMkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgcmV0dXJuIGluc3RhbmNlLmhhcyRjYXBpdGFsaXplZF9uYW1lJCgpO1xuIgorICAgICJ9XG4iKTsKKworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAiICByZXR1cm4gaW5zdGFuY2UuZ2V0JGNhcGl0YWxpemVkX25hbWUkKCk7XG4iCisgICAgIn1cbiIpOworCisgIC8vIEZpZWxkLkJ1aWxkZXIgc2V0RmllbGQoRmllbGQgdmFsdWUpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIHNldCRjYXBpdGFsaXplZF9uYW1lJCgkdHlwZSQgdmFsdWUpIHtcbiIKKyAgICAiICBjb3B5T25Xcml0ZSgpO1xuIgorICAgICIgIGluc3RhbmNlLnNldCRjYXBpdGFsaXplZF9uYW1lJCh2YWx1ZSk7XG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworCisgIC8vIEZpZWxkLkJ1aWxkZXIgc2V0RmllbGQoRmllbGQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIHNldCRjYXBpdGFsaXplZF9uYW1lJChcbiIKKyAgICAiICAgICR0eXBlJC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkge1xuIgorICAgICIgIGNvcHlPbldyaXRlKCk7XG4iCisgICAgIiAgaW5zdGFuY2Uuc2V0JGNhcGl0YWxpemVkX25hbWUkKGJ1aWxkZXJGb3JWYWx1ZSk7XG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworCisgIC8vIEZpZWxkLkJ1aWxkZXIgbWVyZ2VGaWVsZChGaWVsZCB2YWx1ZSkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgbWVyZ2UkY2FwaXRhbGl6ZWRfbmFtZSQoJHR5cGUkIHZhbHVlKSB7XG4iCisgICAgIiAgY29weU9uV3JpdGUoKTtcbiIKKyAgICAiICBpbnN0YW5jZS5tZXJnZSRjYXBpdGFsaXplZF9uYW1lJCh2YWx1ZSk7XG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworCisgIC8vIEZpZWxkLkJ1aWxkZXIgY2xlYXJGaWVsZCgpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGNsZWFyJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgIGNvcHlPbldyaXRlKCk7XG4iCisgICAgIiAgaW5zdGFuY2UuY2xlYXIkY2FwaXRhbGl6ZWRfbmFtZSQoKTtcbiIKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIik7Cit9CisKKwordm9pZCBJbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUluaXRpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAiJG5hbWUkXy5jbGVhcigpO1xuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlTGF6eU1lc3NhZ2VGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAob3RoZXIuaGFzJGNhcGl0YWxpemVkX25hbWUkKCkpIHtcbiIKKyAgICAiICAkbmFtZSRfLm1lcmdlKG90aGVyLiRuYW1lJF8pO1xuIgorICAgICIgICRzZXRfaGFzX2ZpZWxkX2JpdF9tZXNzYWdlJDtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlTGF6eU1lc3NhZ2VGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVQYXJzaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkbmFtZSRfLnNldEJ5dGVTdHJpbmcoaW5wdXQucmVhZEJ5dGVzKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTtcbiIpOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkc2V0X2hhc19maWVsZF9iaXRfbWVzc2FnZSQ7XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIERvIG5vdCBkZS1zZXJpYWxpemUgbGF6eSBmaWVsZHMuCisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkZ2V0X2hhc19maWVsZF9iaXRfbWVzc2FnZSQpIHtcbiIKKyAgICAiICBvdXRwdXQud3JpdGVCeXRlcygkbnVtYmVyJCwgJG5hbWUkXy50b0J5dGVTdHJpbmcoKSk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZUxhenlNZXNzYWdlRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkZ2V0X2hhc19maWVsZF9iaXRfbWVzc2FnZSQpIHtcbiIKKyAgICAiICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW1cbiIKKyAgICAiICAgIC5jb21wdXRlTGF6eUZpZWxkU2l6ZSgkbnVtYmVyJCwgJG5hbWUkXyk7XG4iCisgICAgIn1cbiIpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK0ltbXV0YWJsZUxhenlNZXNzYWdlT25lb2ZGaWVsZExpdGVHZW5lcmF0b3I6OgorSW1tdXRhYmxlTGF6eU1lc3NhZ2VPbmVvZkZpZWxkTGl0ZUdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBtZXNzYWdlQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBidWlsZGVyQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnRleHQqIGNvbnRleHQpCisgICAgOiBJbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkTGl0ZUdlbmVyYXRvcigKKyAgICAgICAgICBkZXNjcmlwdG9yLCBtZXNzYWdlQml0SW5kZXgsIGJ1aWxkZXJCaXRJbmRleCwgY29udGV4dCkgeworICBjb25zdCBPbmVvZkdlbmVyYXRvckluZm8qIGluZm8gPQorICAgICAgY29udGV4dC0+R2V0T25lb2ZHZW5lcmF0b3JJbmZvKGRlc2NyaXB0b3ItPmNvbnRhaW5pbmdfb25lb2YoKSk7CisgIFNldENvbW1vbk9uZW9mVmFyaWFibGVzKGRlc2NyaXB0b3IsIGluZm8sICZ2YXJpYWJsZXNfKTsKKyAgdmFyaWFibGVzX1sibGF6eV90eXBlIl0gPSAiY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5RmllbGRMaXRlIjsKK30KKworSW1tdXRhYmxlTGF6eU1lc3NhZ2VPbmVvZkZpZWxkTGl0ZUdlbmVyYXRvcjo6Cit+SW1tdXRhYmxlTGF6eU1lc3NhZ2VPbmVvZkZpZWxkTGl0ZUdlbmVyYXRvcigpIHt9CisKK3ZvaWQgSW1tdXRhYmxlTGF6eU1lc3NhZ2VPbmVvZkZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgUHJpbnRFeHRyYUZpZWxkSW5mbyh2YXJpYWJsZXNfLCBwcmludGVyKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworCisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgYm9vbGVhbiBoYXMkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgcmV0dXJuICRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJDtcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljICR0eXBlJCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgaWYgKCRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJCkge1xuIgorICAgICIgICAgcmV0dXJuICgkdHlwZSQpICgoJGxhenlfdHlwZSQpICRvbmVvZl9uYW1lJF8pLmdldFZhbHVlKFxuIgorICAgICIgICAgICAgICR0eXBlJC5nZXREZWZhdWx0SW5zdGFuY2UoKSk7XG4iCisgICAgIiAgfVxuIgorICAgICIgIHJldHVybiAkdHlwZSQuZ2V0RGVmYXVsdEluc3RhbmNlKCk7XG4iCisgICAgIn1cbiIpOworCisgIC8vIEZpZWxkLkJ1aWxkZXIgc2V0RmllbGQoRmllbGQgdmFsdWUpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHJpdmF0ZSB2b2lkIHNldCRjYXBpdGFsaXplZF9uYW1lJCgkdHlwZSQgdmFsdWUpIHtcbiIKKyAgICAiICBpZiAodmFsdWUgPT0gbnVsbCkge1xuIgorICAgICIgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7XG4iCisgICAgIiAgfVxuIgorICAgICIgIGlmICghKCRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJCkpIHtcbiIKKyAgICAiICAgICRvbmVvZl9uYW1lJF8gPSBuZXcgJGxhenlfdHlwZSQoKTtcbiIKKyAgICAiICAgICRzZXRfb25lb2ZfY2FzZV9tZXNzYWdlJDtcbiIKKyAgICAiICB9XG4iCisgICAgIiAgKCgkbGF6eV90eXBlJCkgJG9uZW9mX25hbWUkXykuc2V0VmFsdWUodmFsdWUpO1xuIgorICAgICJ9XG4iKTsKKworICAvLyBGaWVsZC5CdWlsZGVyIHNldEZpZWxkKEZpZWxkLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgdm9pZCBzZXQkY2FwaXRhbGl6ZWRfbmFtZSQoXG4iCisgICAgIiAgICAkdHlwZSQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHtcbiIKKyAgICAiICBpZiAoISgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpKSB7XG4iCisgICAgIiAgICAkb25lb2ZfbmFtZSRfID0gbmV3ICRsYXp5X3R5cGUkKCk7XG4iCisgICAgIiAgICAkc2V0X29uZW9mX2Nhc2VfbWVzc2FnZSQ7XG4iCisgICAgIiAgfVxuIgorICAgICIgICgoJGxhenlfdHlwZSQpICRvbmVvZl9uYW1lJF8pLnNldFZhbHVlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTtcbiIKKyAgICAifVxuIik7CisKKyAgLy8gRmllbGQuQnVpbGRlciBtZXJnZUZpZWxkKEZpZWxkIHZhbHVlKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgdm9pZCBtZXJnZSRjYXBpdGFsaXplZF9uYW1lJCgkdHlwZSQgdmFsdWUpIHtcbiIKKyAgICAiICBpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkICYmXG4iCisgICAgIiAgICAgICEoKCRsYXp5X3R5cGUkKSAkb25lb2ZfbmFtZSRfKS5jb250YWluc0RlZmF1bHRJbnN0YW5jZSgpKSB7XG4iCisgICAgIiAgICAoKCRsYXp5X3R5cGUkKSAkb25lb2ZfbmFtZSRfKS5zZXRWYWx1ZShcbiIKKyAgICAiICAgICAgICR0eXBlJC5uZXdCdWlsZGVyKFxuIgorICAgICIgICAgICAgICAgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkpLm1lcmdlRnJvbSh2YWx1ZSkuYnVpbGRQYXJ0aWFsKCkpO1xuIgorICAgICIgIH0gZWxzZSB7XG4iCisgICAgIiAgICBpZiAoISgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpKSB7XG4iCisgICAgIiAgICAgICRvbmVvZl9uYW1lJF8gPSBuZXcgJGxhenlfdHlwZSQoKTtcbiIKKyAgICAiICAgICAgJHNldF9vbmVvZl9jYXNlX21lc3NhZ2UkO1xuIgorICAgICIgICAgfVxuIgorICAgICIgICAgKCgkbGF6eV90eXBlJCkgJG9uZW9mX25hbWUkXykuc2V0VmFsdWUodmFsdWUpO1xuIgorICAgICIgIH1cbiIKKyAgICAifVxuIik7CisKKyAgLy8gRmllbGQuQnVpbGRlciBjbGVhckZpZWxkKCkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIHZvaWQgY2xlYXIkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgaWYgKCRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJCkge1xuIgorICAgICIgICAgJGNsZWFyX29uZW9mX2Nhc2VfbWVzc2FnZSQ7XG4iCisgICAgIiAgICAkb25lb2ZfbmFtZSRfID0gbnVsbDtcbiIKKyAgICAiICB9XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZUxhenlNZXNzYWdlT25lb2ZGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBib29sZWFuIGhhc0ZpZWxkKCkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIGJvb2xlYW4gaGFzJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgIHJldHVybiBpbnN0YW5jZS5oYXMkY2FwaXRhbGl6ZWRfbmFtZSQoKTtcbiIKKyAgICAifVxuIik7CisKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSQgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgIHJldHVybiBpbnN0YW5jZS5nZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKTtcbiIKKyAgICAifVxuIik7CisKKyAgLy8gRmllbGQuQnVpbGRlciBzZXRGaWVsZChGaWVsZCB2YWx1ZSkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgc2V0JGNhcGl0YWxpemVkX25hbWUkKCR0eXBlJCB2YWx1ZSkge1xuIgorICAgICIgIGNvcHlPbldyaXRlKCk7XG4iCisgICAgIiAgaW5zdGFuY2Uuc2V0JGNhcGl0YWxpemVkX25hbWUkKHZhbHVlKTtcbiIKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIik7CisKKyAgLy8gRmllbGQuQnVpbGRlciBzZXRGaWVsZChGaWVsZC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgc2V0JGNhcGl0YWxpemVkX25hbWUkKFxuIgorICAgICIgICAgJHR5cGUkLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7XG4iCisgICAgIiAgY29weU9uV3JpdGUoKTtcbiIKKyAgICAiICBpbnN0YW5jZS5zZXQkY2FwaXRhbGl6ZWRfbmFtZSQoYnVpbGRlckZvclZhbHVlKTtcbiIKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIik7CisKKyAgLy8gRmllbGQuQnVpbGRlciBtZXJnZUZpZWxkKEZpZWxkIHZhbHVlKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBtZXJnZSRjYXBpdGFsaXplZF9uYW1lJCgkdHlwZSQgdmFsdWUpIHtcbiIKKyAgICAiICBjb3B5T25Xcml0ZSgpO1xuIgorICAgICIgIGluc3RhbmNlLm1lcmdlJGNhcGl0YWxpemVkX25hbWUkKHZhbHVlKTtcbiIKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIik7CisKKyAgLy8gRmllbGQuQnVpbGRlciBjbGVhckZpZWxkKCkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgY2xlYXIkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgY29weU9uV3JpdGUoKTtcbiIKKyAgICAiICBpbnN0YW5jZS5jbGVhciRjYXBpdGFsaXplZF9uYW1lJCgpO1xuIgorICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVMYXp5TWVzc2FnZU9uZW9mRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCEoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSkge1xuIgorICAgICIgICRvbmVvZl9uYW1lJF8gPSBuZXcgJGxhenlfdHlwZSQoKTtcbiIKKyAgICAifVxuIgorICAgICIoKCRsYXp5X3R5cGUkKSAkb25lb2ZfbmFtZSRfKS5tZXJnZShcbiIKKyAgICAiICAgICgkbGF6eV90eXBlJCkgb3RoZXIuJG9uZW9mX25hbWUkXyk7XG4iCisgICAgIiRzZXRfb25lb2ZfY2FzZV9tZXNzYWdlJDtcbiIpOworfQorCit2b2lkIEltbXV0YWJsZUxhenlNZXNzYWdlT25lb2ZGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVQYXJzaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoISgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpKSB7XG4iCisgICAgIiAgJG9uZW9mX25hbWUkXyA9IG5ldyAkbGF6eV90eXBlJCgpO1xuIgorICAgICJ9XG4iCisgICAgIigoJGxhenlfdHlwZSQpICRvbmVvZl9uYW1lJF8pLnNldEJ5dGVTdHJpbmcoXG4iCisgICAgIiAgICBpbnB1dC5yZWFkQnl0ZXMoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpO1xuIgorICAgICIkc2V0X29uZW9mX2Nhc2VfbWVzc2FnZSQ7XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVMYXp5TWVzc2FnZU9uZW9mRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gRG8gbm90IGRlLXNlcmlhbGl6ZSBsYXp5IGZpZWxkcy4KKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJCkge1xuIgorICAgICIgIG91dHB1dC53cml0ZUJ5dGVzKFxuIgorICAgICIgICAgICAkbnVtYmVyJCwgKCgkbGF6eV90eXBlJCkgJG9uZW9mX25hbWUkXykudG9CeXRlU3RyaW5nKCkpO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVMYXp5TWVzc2FnZU9uZW9mRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIKKyAgICAiICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW1cbiIKKyAgICAiICAgIC5jb21wdXRlTGF6eUZpZWxkU2l6ZSgkbnVtYmVyJCwgKCRsYXp5X3R5cGUkKSAkb25lb2ZfbmFtZSRfKTtcbiIKKyAgICAifVxuIik7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworUmVwZWF0ZWRJbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitSZXBlYXRlZEltbXV0YWJsZUxhenlNZXNzYWdlRmllbGRMaXRlR2VuZXJhdG9yKAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgIGludCBidWlsZGVyQml0SW5kZXgsCisgICAgQ29udGV4dCogY29udGV4dCkKKyAgICA6IFJlcGVhdGVkSW1tdXRhYmxlTWVzc2FnZUZpZWxkTGl0ZUdlbmVyYXRvcigKKyAgICAgICAgICBkZXNjcmlwdG9yLCBtZXNzYWdlQml0SW5kZXgsIGJ1aWxkZXJCaXRJbmRleCwgY29udGV4dCkgeworfQorCisKK1JlcGVhdGVkSW1tdXRhYmxlTGF6eU1lc3NhZ2VGaWVsZExpdGVHZW5lcmF0b3I6OgorflJlcGVhdGVkSW1tdXRhYmxlTGF6eU1lc3NhZ2VGaWVsZExpdGVHZW5lcmF0b3IoKSB7fQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlTGF6eU1lc3NhZ2VGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Qcm90b2J1Zkxpc3Q8XG4iCisgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlGaWVsZExpdGU+ICRuYW1lJF87XG4iKTsKKyAgUHJpbnRFeHRyYUZpZWxkSW5mbyh2YXJpYWJsZXNfLCBwcmludGVyKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIGphdmEudXRpbC5MaXN0PCR0eXBlJD5cbiIKKyAgICAiICAgIGdldCRjYXBpdGFsaXplZF9uYW1lJExpc3QoKSB7XG4iCisgICAgIiAgamF2YS51dGlsLkxpc3Q8JHR5cGUkPiBsaXN0ID1cbiIKKyAgICAiICAgICAgbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8JHR5cGUkPigkbmFtZSRfLnNpemUoKSk7XG4iCisgICAgIiAgZm9yIChjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlGaWVsZExpdGUgbGYgOiAkbmFtZSRfKSB7XG4iCisgICAgIiAgICBsaXN0LmFkZCgoJHR5cGUkKSBsZi5nZXRWYWx1ZSgkdHlwZSQuZ2V0RGVmYXVsdEluc3RhbmNlKCkpKTtcbiIKKyAgICAiICB9XG4iCisgICAgLy8gVE9ETyhkd2Vpcyk6IE1ha2UgdGhpcyBsaXN0IGltbXV0YWJsZT8KKyAgICAiICByZXR1cm4gbGlzdDtcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgJHR5cGUkT3JCdWlsZGVyPlxuIgorICAgICIgICAgZ2V0JGNhcGl0YWxpemVkX25hbWUkT3JCdWlsZGVyTGlzdCgpIHtcbiIKKyAgICAiICByZXR1cm4gZ2V0JGNhcGl0YWxpemVkX25hbWUkTGlzdCgpO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIGludCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRDb3VudCgpIHtcbiIKKyAgICAiICByZXR1cm4gJG5hbWUkXy5zaXplKCk7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkIGdldCRjYXBpdGFsaXplZF9uYW1lJChpbnQgaW5kZXgpIHtcbiIKKyAgICAiICByZXR1cm4gKCR0eXBlJClcbiIKKyAgICAiICAgICAgJG5hbWUkXy5nZXQoaW5kZXgpLmdldFZhbHVlKCR0eXBlJC5nZXREZWZhdWx0SW5zdGFuY2UoKSk7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkT3JCdWlsZGVyIGdldCRjYXBpdGFsaXplZF9uYW1lJE9yQnVpbGRlcihcbiIKKyAgICAiICAgIGludCBpbmRleCkge1xuIgorICAgICIgIHJldHVybiAoJHR5cGUkT3JCdWlsZGVyKVxuIgorICAgICIgICAgICAkbmFtZSRfLmdldChpbmRleCkuZ2V0VmFsdWUoJHR5cGUkLmdldERlZmF1bHRJbnN0YW5jZSgpKTtcbiIKKyAgICAifVxuIik7CisKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHJpdmF0ZSB2b2lkIGVuc3VyZSRjYXBpdGFsaXplZF9uYW1lJElzTXV0YWJsZSgpIHtcbiIKKyAgICAiICBpZiAoISRpc19tdXRhYmxlJCkge1xuIgorICAgICIgICAgJG5hbWUkXyA9IG5ld1Byb3RvYnVmTGlzdCgkbmFtZSRfKTtcbiIKKyAgICAiICAgfVxuIgorICAgICJ9XG4iCisgICAgIlxuIik7CisKKyAgLy8gQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKGludCBpbmRleCwgRmllbGQgdmFsdWUpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHJpdmF0ZSB2b2lkIHNldCRjYXBpdGFsaXplZF9uYW1lJChcbiIKKyAgICAiICAgIGludCBpbmRleCwgJHR5cGUkIHZhbHVlKSB7XG4iCisgICAgIiAgaWYgKHZhbHVlID09IG51bGwpIHtcbiIKKyAgICAiICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpO1xuIgorICAgICIgIH1cbiIKKyAgICAiICBlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKTtcbiIKKyAgICAiICAkbmFtZSRfLnNldChcbiIKKyAgICAiICAgICAgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eUZpZWxkTGl0ZS5mcm9tVmFsdWUodmFsdWUpKTtcbiIKKyAgICAifVxuIik7CisKKyAgLy8gQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKGludCBpbmRleCwgRmllbGQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHJpdmF0ZSB2b2lkIHNldCRjYXBpdGFsaXplZF9uYW1lJChcbiIKKyAgICAiICAgIGludCBpbmRleCwgJHR5cGUkLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7XG4iCisgICAgIiAgZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCk7XG4iCisgICAgIiAgJG5hbWUkXy5zZXQoaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eUZpZWxkTGl0ZS5mcm9tVmFsdWUoXG4iCisgICAgIiAgICAgIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKSk7XG4iCisgICAgIn1cbiIpOworCisgIC8vIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZChGaWVsZCB2YWx1ZSkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIHZvaWQgYWRkJGNhcGl0YWxpemVkX25hbWUkKCR0eXBlJCB2YWx1ZSkge1xuIgorICAgICIgIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4iCisgICAgIiAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTtcbiIKKyAgICAiICB9XG4iCisgICAgIiAgZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCk7XG4iCisgICAgIiAgJG5hbWUkXy5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5RmllbGRMaXRlLmZyb21WYWx1ZSh2YWx1ZSkpO1xuIgorICAgICJ9XG4iKTsKKworICAvLyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoaW50IGluZGV4LCBGaWVsZCB2YWx1ZSkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIHZvaWQgYWRkJGNhcGl0YWxpemVkX25hbWUkKFxuIgorICAgICIgICAgaW50IGluZGV4LCAkdHlwZSQgdmFsdWUpIHtcbiIKKyAgICAiICBpZiAodmFsdWUgPT0gbnVsbCkge1xuIgorICAgICIgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7XG4iCisgICAgIiAgfVxuIgorICAgICIgIGVuc3VyZSRjYXBpdGFsaXplZF9uYW1lJElzTXV0YWJsZSgpO1xuIgorICAgICIgICRuYW1lJF8uYWRkKFxuIgorICAgICIgICAgICBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5RmllbGRMaXRlLmZyb21WYWx1ZSh2YWx1ZSkpO1xuIgorICAgICJ9XG4iKTsKKworICAvLyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoRmllbGQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHJpdmF0ZSB2b2lkIGFkZCRjYXBpdGFsaXplZF9uYW1lJChcbiIKKyAgICAiICAgICR0eXBlJC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkge1xuIgorICAgICIgIGVuc3VyZSRjYXBpdGFsaXplZF9uYW1lJElzTXV0YWJsZSgpO1xuIgorICAgICIgICRuYW1lJF8uYWRkKGNvbS5nb29nbGUucHJvdG9idWYuTGF6eUZpZWxkTGl0ZS5mcm9tVmFsdWUoXG4iCisgICAgIiAgICAgIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKSk7XG4iCisgICAgIn1cbiIpOworCisgIC8vIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZChpbnQgaW5kZXgsIEZpZWxkLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgdm9pZCBhZGQkY2FwaXRhbGl6ZWRfbmFtZSQoXG4iCisgICAgIiAgICBpbnQgaW5kZXgsICR0eXBlJC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkge1xuIgorICAgICIgIGVuc3VyZSRjYXBpdGFsaXplZF9uYW1lJElzTXV0YWJsZSgpO1xuIgorICAgICIgICRuYW1lJF8uYWRkKGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlGaWVsZExpdGUuZnJvbVZhbHVlKFxuIgorICAgICIgICAgICBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSkpO1xuIgorICAgICJ9XG4iKTsKKworICAvLyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkRmllbGQoSXRlcmFibGU8RmllbGQ+IHZhbHVlcykKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIHZvaWQgYWRkQWxsJGNhcGl0YWxpemVkX25hbWUkKFxuIgorICAgICIgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyAkdHlwZSQ+IHZhbHVlcykge1xuIgorICAgICIgIGVuc3VyZSRjYXBpdGFsaXplZF9uYW1lJElzTXV0YWJsZSgpO1xuIgorICAgICIgIGZvciAoY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlTGl0ZSB2IDogdmFsdWVzKSB7XG4iCisgICAgIiAgICAkbmFtZSRfLmFkZChjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlGaWVsZExpdGUuZnJvbVZhbHVlKHYpKTtcbiIKKyAgICAiICB9XG4iCisgICAgIn1cbiIpOworCisgIC8vIEJ1aWxkZXIgY2xlYXJBbGxSZXBlYXRlZEZpZWxkKCkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIHZvaWQgY2xlYXIkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgJG5hbWUkXyA9IGVtcHR5UHJvdG9idWZMaXN0KCk7XG4iCisgICAgIn1cbiIpOworCisgIC8vIEJ1aWxkZXIgcmVtb3ZlUmVwZWF0ZWRGaWVsZChpbnQgaW5kZXgpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHJpdmF0ZSB2b2lkIHJlbW92ZSRjYXBpdGFsaXplZF9uYW1lJChpbnQgaW5kZXgpIHtcbiIKKyAgICAiICBlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKTtcbiIKKyAgICAiICAkbmFtZSRfLnJlbW92ZShpbmRleCk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlTGF6eU1lc3NhZ2VGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBMaXN0PEZpZWxkPiBnZXRSZXBlYXRlZEZpZWxkTGlzdCgpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBqYXZhLnV0aWwuTGlzdDwkdHlwZSQ+IGdldCRjYXBpdGFsaXplZF9uYW1lJExpc3QoKSB7XG4iCisgICAgIiAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KFxuIgorICAgICIgICAgICBpbnN0YW5jZS5nZXQkY2FwaXRhbGl6ZWRfbmFtZSRMaXN0KCkpO1xuIgorICAgICJ9XG4iKTsKKworICAvLyBpbnQgZ2V0UmVwZWF0ZWRGaWVsZENvdW50KCkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIGludCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRDb3VudCgpIHtcbiIKKyAgICAiICByZXR1cm4gaW5zdGFuY2UuZ2V0JGNhcGl0YWxpemVkX25hbWUkQ291bnQoKTtcbiIKKyAgICAifVxuIik7CisKKyAgLy8gRmllbGQgZ2V0UmVwZWF0ZWRGaWVsZChpbnQgaW5kZXgpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSQgZ2V0JGNhcGl0YWxpemVkX25hbWUkKGludCBpbmRleCkge1xuIgorICAgICIgIHJldHVybiBpbnN0YW5jZS5nZXQkY2FwaXRhbGl6ZWRfbmFtZSQoaW5kZXgpO1xuIgorICAgICJ9XG4iKTsKKworICAvLyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoaW50IGluZGV4LCBGaWVsZCB2YWx1ZSkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgc2V0JGNhcGl0YWxpemVkX25hbWUkKFxuIgorICAgICIgICAgaW50IGluZGV4LCAkdHlwZSQgdmFsdWUpIHtcbiIKKyAgICAiICBjb3B5T25Xcml0ZSgpO1xuIgorICAgICIgIGluc3RhbmNlLnNldCRjYXBpdGFsaXplZF9uYW1lJChpbmRleCwgdmFsdWUpO1xuIgorICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICJ9XG4iKTsKKworICAvLyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoaW50IGluZGV4LCBGaWVsZC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgc2V0JGNhcGl0YWxpemVkX25hbWUkKFxuIgorICAgICIgICAgaW50IGluZGV4LCAkdHlwZSQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHtcbiIKKyAgICAiICBjb3B5T25Xcml0ZSgpO1xuIgorICAgICIgIGluc3RhbmNlLnNldCRjYXBpdGFsaXplZF9uYW1lJChpbmRleCwgYnVpbGRlckZvclZhbHVlKTtcbiIKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIik7CisKKyAgLy8gQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKEZpZWxkIHZhbHVlKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBhZGQkY2FwaXRhbGl6ZWRfbmFtZSQoJHR5cGUkIHZhbHVlKSB7XG4iCisgICAgIiAgY29weU9uV3JpdGUoKTtcbiIKKyAgICAiICBpbnN0YW5jZS5hZGQkY2FwaXRhbGl6ZWRfbmFtZSQodmFsdWUpO1xuIgorICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICJ9XG4iKTsKKworICAvLyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoaW50IGluZGV4LCBGaWVsZCB2YWx1ZSkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgYWRkJGNhcGl0YWxpemVkX25hbWUkKFxuIgorICAgICIgICAgaW50IGluZGV4LCAkdHlwZSQgdmFsdWUpIHtcbiIKKyAgICAiICBjb3B5T25Xcml0ZSgpO1xuIgorICAgICIgIGluc3RhbmNlLmFkZCRjYXBpdGFsaXplZF9uYW1lJChpbmRleCwgdmFsdWUpO1xuIgorICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICJ9XG4iKTsKKworICAvLyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoRmllbGQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGFkZCRjYXBpdGFsaXplZF9uYW1lJChcbiIKKyAgICAiICAgICR0eXBlJC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkge1xuIgorICAgICIgIGNvcHlPbldyaXRlKCk7XG4iCisgICAgIiAgaW5zdGFuY2UuYWRkJGNhcGl0YWxpemVkX25hbWUkKGJ1aWxkZXJGb3JWYWx1ZSk7XG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworCisgIC8vIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZChpbnQgaW5kZXgsIEZpZWxkLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBhZGQkY2FwaXRhbGl6ZWRfbmFtZSQoXG4iCisgICAgIiAgICBpbnQgaW5kZXgsICR0eXBlJC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkge1xuIgorICAgICIgIGNvcHlPbldyaXRlKCk7XG4iCisgICAgIiAgaW5zdGFuY2UuYWRkJGNhcGl0YWxpemVkX25hbWUkKGluZGV4LCBidWlsZGVyRm9yVmFsdWUpO1xuIgorICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICJ9XG4iKTsKKworICAvLyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkRmllbGQoSXRlcmFibGU8RmllbGQ+IHZhbHVlcykKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgYWRkQWxsJGNhcGl0YWxpemVkX25hbWUkKFxuIgorICAgICIgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyAkdHlwZSQ+IHZhbHVlcykge1xuIgorICAgICIgIGNvcHlPbldyaXRlKCk7XG4iCisgICAgIiAgaW5zdGFuY2UuYWRkQWxsJGNhcGl0YWxpemVkX25hbWUkKHZhbHVlcyk7XG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworCisgIC8vIEJ1aWxkZXIgY2xlYXJBbGxSZXBlYXRlZEZpZWxkKCkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgY2xlYXIkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgY29weU9uV3JpdGUoKTtcbiIKKyAgICAiICBpbnN0YW5jZS5jbGVhciRjYXBpdGFsaXplZF9uYW1lJCgpO1xuIgorICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICJ9XG4iKTsKKworICAvLyBCdWlsZGVyIHJlbW92ZVJlcGVhdGVkRmllbGQoaW50IGluZGV4KQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciByZW1vdmUkY2FwaXRhbGl6ZWRfbmFtZSQoaW50IGluZGV4KSB7XG4iCisgICAgIiAgY29weU9uV3JpdGUoKTtcbiIKKyAgICAiICBpbnN0YW5jZS5yZW1vdmUkY2FwaXRhbGl6ZWRfbmFtZSQoaW5kZXgpO1xuIgorICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZUxhenlNZXNzYWdlRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCEkaXNfbXV0YWJsZSQpIHtcbiIKKyAgICAiICAkbmFtZSRfID0gbmV3UHJvdG9idWZMaXN0KCk7XG4iCisgICAgIn1cbiIKKyAgICAiJG5hbWUkXy5hZGQobmV3IGNvbS5nb29nbGUucHJvdG9idWYuTGF6eUZpZWxkTGl0ZShcbiIKKyAgICAiICAgIGV4dGVuc2lvblJlZ2lzdHJ5LCBpbnB1dC5yZWFkQnl0ZXMoKSkpO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImZvciAoaW50IGkgPSAwOyBpIDwgJG5hbWUkXy5zaXplKCk7IGkrKykge1xuIgorICAgICIgIG91dHB1dC53cml0ZUJ5dGVzKCRudW1iZXIkLCAkbmFtZSRfLmdldChpKS50b0J5dGVTdHJpbmcoKSk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlTGF6eU1lc3NhZ2VGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiZm9yIChpbnQgaSA9IDA7IGkgPCAkbmFtZSRfLnNpemUoKTsgaSsrKSB7XG4iCisgICAgIiAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtXG4iCisgICAgIiAgICAuY29tcHV0ZUxhenlGaWVsZFNpemUoJG51bWJlciQsICRuYW1lJF8uZ2V0KGkpKTtcbiIKKyAgICAifVxuIik7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbGF6eV9tZXNzYWdlX2ZpZWxkX2xpdGUuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2xhenlfbWVzc2FnZV9maWVsZF9saXRlLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTg1ZWMwZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2xhenlfbWVzc2FnZV9maWVsZF9saXRlLmgKQEAgLTAsMCArMSwxMTggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IG5pd2FzYWtpQGdvb2dsZS5jb20gKE5hb2tpIEl3YXNha2kpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9MQVpZX01FU1NBR0VfRklFTERfTElURV9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfTEFaWV9NRVNTQUdFX0ZJRUxEX0xJVEVfSF9fCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tZXNzYWdlX2ZpZWxkX2xpdGUuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworICBuYW1lc3BhY2UgY29tcGlsZXIgeworICAgIG5hbWVzcGFjZSBqYXZhIHsKKyAgICAgIGNsYXNzIENvbnRleHQ7ICAvLyBjb250ZXh0LmgKKyAgICB9CisgIH0KK30KKworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YSB7CisKK2NsYXNzIEltbXV0YWJsZUxhenlNZXNzYWdlRmllbGRMaXRlR2VuZXJhdG9yCisgICAgOiBwdWJsaWMgSW1tdXRhYmxlTWVzc2FnZUZpZWxkTGl0ZUdlbmVyYXRvciB7CisgcHVibGljOgorICBleHBsaWNpdCBJbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkTGl0ZUdlbmVyYXRvcigKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwgaW50IG1lc3NhZ2VCaXRJbmRleCwKKyAgICAgIGludCBidWlsZGVyQml0SW5kZXgsIENvbnRleHQqIGNvbnRleHQpOworICB+SW1tdXRhYmxlTGF6eU1lc3NhZ2VGaWVsZExpdGVHZW5lcmF0b3IoKTsKKworICAvLyBvdmVycm9hZHMgSW1tdXRhYmxlTWVzc2FnZUZpZWxkTGl0ZUdlbmVyYXRvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgdm9pZCBHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnVpbGRlck1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVBhcnNpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoSW1tdXRhYmxlTGF6eU1lc3NhZ2VGaWVsZExpdGVHZW5lcmF0b3IpOworfTsKKworY2xhc3MgSW1tdXRhYmxlTGF6eU1lc3NhZ2VPbmVvZkZpZWxkTGl0ZUdlbmVyYXRvcgorICAgIDogcHVibGljIEltbXV0YWJsZUxhenlNZXNzYWdlRmllbGRMaXRlR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIEltbXV0YWJsZUxhenlNZXNzYWdlT25lb2ZGaWVsZExpdGVHZW5lcmF0b3IoCisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGludCBtZXNzYWdlQml0SW5kZXgsCisgICAgICBpbnQgYnVpbGRlckJpdEluZGV4LCBDb250ZXh0KiBjb250ZXh0KTsKKyAgfkltbXV0YWJsZUxhenlNZXNzYWdlT25lb2ZGaWVsZExpdGVHZW5lcmF0b3IoKTsKKworICB2b2lkIEdlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVQYXJzaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEltbXV0YWJsZUxhenlNZXNzYWdlT25lb2ZGaWVsZExpdGVHZW5lcmF0b3IpOworfTsKKworY2xhc3MgUmVwZWF0ZWRJbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkTGl0ZUdlbmVyYXRvcgorICAgIDogcHVibGljIFJlcGVhdGVkSW1tdXRhYmxlTWVzc2FnZUZpZWxkTGl0ZUdlbmVyYXRvciB7CisgcHVibGljOgorICBleHBsaWNpdCBSZXBlYXRlZEltbXV0YWJsZUxhenlNZXNzYWdlRmllbGRMaXRlR2VuZXJhdG9yKAorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwgQ29udGV4dCogY29udGV4dCk7CisgIH5SZXBlYXRlZEltbXV0YWJsZUxhenlNZXNzYWdlRmllbGRMaXRlR2VuZXJhdG9yKCk7CisKKyAgLy8gb3ZlcnJvYWRzIFJlcGVhdGVkSW1tdXRhYmxlTWVzc2FnZUZpZWxkTGl0ZUdlbmVyYXRvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIHZvaWQgR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUJ1aWxkZXJNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVBhcnNpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoUmVwZWF0ZWRJbW11dGFibGVMYXp5TWVzc2FnZUZpZWxkTGl0ZUdlbmVyYXRvcik7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgamF2YQorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9MQVpZX01FU1NBR0VfRklFTERfTElURV9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21hcF9maWVsZC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21hcF9maWVsZC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZTAzNWM4Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbWFwX2ZpZWxkLmNjCkBAIC0wLDAgKzEsNTAzIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbWFwX2ZpZWxkLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2NvbnRleHQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2RvY19jb21tZW50Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9uYW1lX3Jlc29sdmVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhIHsKKworbmFtZXNwYWNlIHsKKworY29uc3QgRmllbGREZXNjcmlwdG9yKiBLZXlGaWVsZChjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgR09PR0xFX0NIRUNLX0VRKEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9NRVNTQUdFLCBkZXNjcmlwdG9yLT50eXBlKCkpOworICBjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlID0gZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCk7CisgIEdPT0dMRV9DSEVDSyhtZXNzYWdlLT5vcHRpb25zKCkubWFwX2VudHJ5KCkpOworICByZXR1cm4gbWVzc2FnZS0+RmluZEZpZWxkQnlOYW1lKCJrZXkiKTsKK30KKworY29uc3QgRmllbGREZXNjcmlwdG9yKiBWYWx1ZUZpZWxkKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBHT09HTEVfQ0hFQ0tfRVEoRmllbGREZXNjcmlwdG9yOjpUWVBFX01FU1NBR0UsIGRlc2NyaXB0b3ItPnR5cGUoKSk7CisgIGNvbnN0IERlc2NyaXB0b3IqIG1lc3NhZ2UgPSBkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKTsKKyAgR09PR0xFX0NIRUNLKG1lc3NhZ2UtPm9wdGlvbnMoKS5tYXBfZW50cnkoKSk7CisgIHJldHVybiBtZXNzYWdlLT5GaW5kRmllbGRCeU5hbWUoInZhbHVlIik7Cit9CisKK3N0cmluZyBUeXBlTmFtZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgIENsYXNzTmFtZVJlc29sdmVyKiBuYW1lX3Jlc29sdmVyLAorICAgICAgICAgICAgICAgIGJvb2wgYm94ZWQpIHsKKyAgaWYgKEdldEphdmFUeXBlKGZpZWxkKSA9PSBKQVZBVFlQRV9NRVNTQUdFKSB7CisgICAgcmV0dXJuIG5hbWVfcmVzb2x2ZXItPkdldEltbXV0YWJsZUNsYXNzTmFtZShmaWVsZC0+bWVzc2FnZV90eXBlKCkpOworICB9IGVsc2UgaWYgKEdldEphdmFUeXBlKGZpZWxkKSA9PSBKQVZBVFlQRV9FTlVNKSB7CisgICAgcmV0dXJuIG5hbWVfcmVzb2x2ZXItPkdldEltbXV0YWJsZUNsYXNzTmFtZShmaWVsZC0+ZW51bV90eXBlKCkpOworICB9IGVsc2UgeworICAgIHJldHVybiBib3hlZCA/IEJveGVkUHJpbWl0aXZlVHlwZU5hbWUoR2V0SmF2YVR5cGUoZmllbGQpKQorICAgICAgICAgICAgICAgICA6IFByaW1pdGl2ZVR5cGVOYW1lKEdldEphdmFUeXBlKGZpZWxkKSk7CisgIH0KK30KKworc3RyaW5nIFdpcmVUeXBlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgcmV0dXJuICJjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLiIgKworICAgICAgc3RyaW5nKEZpZWxkVHlwZU5hbWUoZmllbGQtPnR5cGUoKSkpOworfQorCit2b2lkIFNldE1lc3NhZ2VWYXJpYWJsZXMoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgIGludCBtZXNzYWdlQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZEdlbmVyYXRvckluZm8qIGluZm8sCisgICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3NOYW1lUmVzb2x2ZXIqIG5hbWVfcmVzb2x2ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgbWFwPHN0cmluZywgc3RyaW5nPiogdmFyaWFibGVzKSB7CisgIFNldENvbW1vbkZpZWxkVmFyaWFibGVzKGRlc2NyaXB0b3IsIGluZm8sIHZhcmlhYmxlcyk7CisKKyAgKCp2YXJpYWJsZXMpWyJ0eXBlIl0gPQorICAgICAgbmFtZV9yZXNvbHZlci0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBrZXkgPSBLZXlGaWVsZChkZXNjcmlwdG9yKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiB2YWx1ZSA9IFZhbHVlRmllbGQoZGVzY3JpcHRvcik7CisgICgqdmFyaWFibGVzKVsia2V5X3R5cGUiXSA9IFR5cGVOYW1lKGtleSwgbmFtZV9yZXNvbHZlciwgZmFsc2UpOworICAoKnZhcmlhYmxlcylbImJveGVkX2tleV90eXBlIl0gPSBUeXBlTmFtZShrZXksIG5hbWVfcmVzb2x2ZXIsIHRydWUpOworICAoKnZhcmlhYmxlcylbImtleV93aXJlX3R5cGUiXSA9IFdpcmVUeXBlKGtleSk7CisgICgqdmFyaWFibGVzKVsia2V5X2RlZmF1bHRfdmFsdWUiXSA9IERlZmF1bHRWYWx1ZShrZXksIHRydWUsIG5hbWVfcmVzb2x2ZXIpOworICBpZiAoR2V0SmF2YVR5cGUodmFsdWUpID09IEpBVkFUWVBFX0VOVU0pIHsKKyAgICAvLyBXZSBzdG9yZSBlbnVtcyBhcyBJbnRlZ2VycyBpbnRlcm5hbGx5LgorICAgICgqdmFyaWFibGVzKVsidmFsdWVfdHlwZSJdID0gImludCI7CisgICAgKCp2YXJpYWJsZXMpWyJib3hlZF92YWx1ZV90eXBlIl0gPSAiamF2YS5sYW5nLkludGVnZXIiOworICAgICgqdmFyaWFibGVzKVsidmFsdWVfd2lyZV90eXBlIl0gPSBXaXJlVHlwZSh2YWx1ZSk7CisgICAgKCp2YXJpYWJsZXMpWyJ2YWx1ZV9kZWZhdWx0X3ZhbHVlIl0gPQorICAgICAgICBEZWZhdWx0VmFsdWUodmFsdWUsIHRydWUsIG5hbWVfcmVzb2x2ZXIpICsgIi5nZXROdW1iZXIoKSI7CisKKyAgICAoKnZhcmlhYmxlcylbInZhbHVlX2VudW1fdHlwZSJdID0gVHlwZU5hbWUodmFsdWUsIG5hbWVfcmVzb2x2ZXIsIGZhbHNlKTsKKworICAgIGlmIChTdXBwb3J0VW5rbm93bkVudW1WYWx1ZShkZXNjcmlwdG9yLT5maWxlKCkpKSB7CisgICAgICAvLyBNYXAgdW5rbm93biB2YWx1ZXMgdG8gYSBzcGVjaWFsIFVOUkVDT0dOSVpFRCB2YWx1ZSBpZiBzdXBwb3J0ZWQuCisgICAgICAoKnZhcmlhYmxlcylbInVucmVjb2duaXplZF92YWx1ZSJdID0KKyAgICAgICAgICAoKnZhcmlhYmxlcylbInZhbHVlX2VudW1fdHlwZSJdICsgIi5VTlJFQ09HTklaRUQiOworICAgIH0gZWxzZSB7CisgICAgICAvLyBNYXAgdW5rbm93biB2YWx1ZXMgdG8gdGhlIGRlZmF1bHQgdmFsdWUgaWYgd2UgZG9uJ3QgaGF2ZSBVTlJFQ09HTklaRUQuCisgICAgICAoKnZhcmlhYmxlcylbInVucmVjb2duaXplZF92YWx1ZSJdID0KKyAgICAgICAgICBEZWZhdWx0VmFsdWUodmFsdWUsIHRydWUsIG5hbWVfcmVzb2x2ZXIpOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICAoKnZhcmlhYmxlcylbInZhbHVlX3R5cGUiXSA9IFR5cGVOYW1lKHZhbHVlLCBuYW1lX3Jlc29sdmVyLCBmYWxzZSk7CisgICAgKCp2YXJpYWJsZXMpWyJib3hlZF92YWx1ZV90eXBlIl0gPSBUeXBlTmFtZSh2YWx1ZSwgbmFtZV9yZXNvbHZlciwgdHJ1ZSk7CisgICAgKCp2YXJpYWJsZXMpWyJ2YWx1ZV93aXJlX3R5cGUiXSA9IFdpcmVUeXBlKHZhbHVlKTsKKyAgICAoKnZhcmlhYmxlcylbInZhbHVlX2RlZmF1bHRfdmFsdWUiXSA9CisgICAgICAgIERlZmF1bHRWYWx1ZSh2YWx1ZSwgdHJ1ZSwgbmFtZV9yZXNvbHZlcik7CisgIH0KKyAgKCp2YXJpYWJsZXMpWyJ0eXBlX3BhcmFtZXRlcnMiXSA9CisgICAgICAoKnZhcmlhYmxlcylbImJveGVkX2tleV90eXBlIl0gKyAiLCAiICsgKCp2YXJpYWJsZXMpWyJib3hlZF92YWx1ZV90eXBlIl07CisgIC8vIFRPRE8oYmlyZG8pOiBBZGQgQGRlcHJlY2F0ZWQgamF2YWRvYyB3aGVuIGdlbmVyYXRpbmcgamF2YWRvYyBpcyBzdXBwb3J0ZWQKKyAgLy8gYnkgdGhlIHByb3RvIGNvbXBpbGVyCisgICgqdmFyaWFibGVzKVsiZGVwcmVjYXRpb24iXSA9IGRlc2NyaXB0b3ItPm9wdGlvbnMoKS5kZXByZWNhdGVkKCkKKyAgICAgID8gIkBqYXZhLmxhbmcuRGVwcmVjYXRlZCAiIDogIiI7CisgICgqdmFyaWFibGVzKVsib25fY2hhbmdlZCJdID0KKyAgICAgIEhhc0Rlc2NyaXB0b3JNZXRob2RzKGRlc2NyaXB0b3ItPmNvbnRhaW5pbmdfdHlwZSgpKSA/ICJvbkNoYW5nZWQoKTsiIDogIiI7CisKKyAgLy8gRm9yIHJlcGVhdGVkIGZpZWxkcywgb25lIGJpdCBpcyB1c2VkIGZvciB3aGV0aGVyIHRoZSBhcnJheSBpcyBpbW11dGFibGUKKyAgLy8gaW4gdGhlIHBhcnNpbmcgY29uc3RydWN0b3IuCisgICgqdmFyaWFibGVzKVsiZ2V0X211dGFibGVfYml0X3BhcnNlciJdID0KKyAgICAgIEdlbmVyYXRlR2V0Qml0TXV0YWJsZUxvY2FsKGJ1aWxkZXJCaXRJbmRleCk7CisgICgqdmFyaWFibGVzKVsic2V0X211dGFibGVfYml0X3BhcnNlciJdID0KKyAgICAgIEdlbmVyYXRlU2V0Qml0TXV0YWJsZUxvY2FsKGJ1aWxkZXJCaXRJbmRleCk7CisKKyAgKCp2YXJpYWJsZXMpWyJkZWZhdWx0X2VudHJ5Il0gPSAoKnZhcmlhYmxlcylbImNhcGl0YWxpemVkX25hbWUiXSArCisgICAgICAiRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSI7CisgIGlmIChIYXNEZXNjcmlwdG9yTWV0aG9kcyhkZXNjcmlwdG9yLT5maWxlKCkpKSB7CisgICAgKCp2YXJpYWJsZXMpWyJsaXRlIl0gPSAiIjsKKyAgICAoKnZhcmlhYmxlcylbIm1hcF9maWVsZF9wYXJhbWV0ZXIiXSA9ICgqdmFyaWFibGVzKVsiZGVmYXVsdF9lbnRyeSJdOworICAgICgqdmFyaWFibGVzKVsiZGVzY3JpcHRvciJdID0KKyAgICAgICAgbmFtZV9yZXNvbHZlci0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3ItPmZpbGUoKSkgKworICAgICAgICAiLmludGVybmFsXyIgKyBVbmlxdWVGaWxlU2NvcGVJZGVudGlmaWVyKGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpKSArCisgICAgICAgICJfZGVzY3JpcHRvciwgIjsKKyAgfSBlbHNlIHsKKyAgICAoKnZhcmlhYmxlcylbImxpdGUiXSA9ICJMaXRlIjsKKyAgICAoKnZhcmlhYmxlcylbIm1hcF9maWVsZF9wYXJhbWV0ZXIiXSA9ICIiOworICAgICgqdmFyaWFibGVzKVsiZGVzY3JpcHRvciJdID0gIiI7CisgIH0KK30KKworfSAgLy8gbmFtZXNwYWNlCisKK0ltbXV0YWJsZU1hcEZpZWxkR2VuZXJhdG9yOjoKK0ltbXV0YWJsZU1hcEZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBtZXNzYWdlQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYnVpbGRlckJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29udGV4dCogY29udGV4dCkKKyAgOiBkZXNjcmlwdG9yXyhkZXNjcmlwdG9yKSwgbmFtZV9yZXNvbHZlcl8oY29udGV4dC0+R2V0TmFtZVJlc29sdmVyKCkpICB7CisgIFNldE1lc3NhZ2VWYXJpYWJsZXMoZGVzY3JpcHRvciwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgY29udGV4dC0+R2V0RmllbGRHZW5lcmF0b3JJbmZvKGRlc2NyaXB0b3IpLAorICAgICAgICAgICAgICAgICAgICAgIG5hbWVfcmVzb2x2ZXJfLCAmdmFyaWFibGVzXyk7Cit9CisKK0ltbXV0YWJsZU1hcEZpZWxkR2VuZXJhdG9yOjoKK35JbW11dGFibGVNYXBGaWVsZEdlbmVyYXRvcigpIHt9CisKK2ludCBJbW11dGFibGVNYXBGaWVsZEdlbmVyYXRvcjo6R2V0TnVtQml0c0Zvck1lc3NhZ2UoKSBjb25zdCB7CisgIHJldHVybiAwOworfQorCitpbnQgSW1tdXRhYmxlTWFwRmllbGRHZW5lcmF0b3I6OkdldE51bUJpdHNGb3JCdWlsZGVyKCkgY29uc3QgeworICByZXR1cm4gMTsKK30KKwordm9pZCBJbW11dGFibGVNYXBGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUludGVyZmFjZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKEdldEphdmFUeXBlKFZhbHVlRmllbGQoZGVzY3JpcHRvcl8pKSA9PSBKQVZBVFlQRV9FTlVNKSB7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICB2YXJpYWJsZXNfLAorICAgICAgICAiJGRlcHJlY2F0aW9uJGphdmEudXRpbC5NYXA8JGJveGVkX2tleV90eXBlJCwgJHZhbHVlX2VudW1fdHlwZSQ+XG4iCisgICAgICAgICJnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKTtcbiIpOworICAgIGlmIChTdXBwb3J0VW5rbm93bkVudW1WYWx1ZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgdmFyaWFibGVzXywKKyAgICAgICAgICAiJGRlcHJlY2F0aW9uJGphdmEudXRpbC5NYXA8JHR5cGVfcGFyYW1ldGVycyQ+XG4iCisgICAgICAgICAgImdldCRjYXBpdGFsaXplZF9uYW1lJFZhbHVlKCk7XG4iKTsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICB2YXJpYWJsZXNfLAorICAgICAgICAiJGRlcHJlY2F0aW9uJGphdmEudXRpbC5NYXA8JHR5cGVfcGFyYW1ldGVycyQ+XG4iCisgICAgICAgICJnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKTtcbiIpOworICB9Cit9CisKK3ZvaWQgSW1tdXRhYmxlTWFwRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KAorICAgICAgdmFyaWFibGVzXywKKyAgICAgICJwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyAkY2FwaXRhbGl6ZWRfbmFtZSREZWZhdWx0RW50cnlIb2xkZXIge1xuIgorICAgICAgIiAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkkbGl0ZSQ8XG4iCisgICAgICAiICAgICAgJHR5cGVfcGFyYW1ldGVycyQ+IGRlZmF1bHRFbnRyeSA9XG4iCisgICAgICAiICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkkbGl0ZSRcbiIKKyAgICAgICIgICAgICAgICAgLjwkdHlwZV9wYXJhbWV0ZXJzJD5uZXdEZWZhdWx0SW5zdGFuY2UoXG4iCisgICAgICAiICAgICAgICAgICAgICAkZGVzY3JpcHRvciRcbiIKKyAgICAgICIgICAgICAgICAgICAgICRrZXlfd2lyZV90eXBlJCxcbiIKKyAgICAgICIgICAgICAgICAgICAgICRrZXlfZGVmYXVsdF92YWx1ZSQsXG4iCisgICAgICAiICAgICAgICAgICAgICAkdmFsdWVfd2lyZV90eXBlJCxcbiIKKyAgICAgICIgICAgICAgICAgICAgICR2YWx1ZV9kZWZhdWx0X3ZhbHVlJCk7XG4iCisgICAgICAifVxuIik7CisgIHByaW50ZXItPlByaW50KAorICAgICAgdmFyaWFibGVzXywKKyAgICAgICJwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQkbGl0ZSQ8XG4iCisgICAgICAiICAgICR0eXBlX3BhcmFtZXRlcnMkPiAkbmFtZSRfO1xuIgorICAgICAgInByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZCRsaXRlJDwkdHlwZV9wYXJhbWV0ZXJzJD5cbiIKKyAgICAgICJpbnRlcm5hbEdldCRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAgICIgIGlmICgkbmFtZSRfID09IG51bGwpIHtcbiIKKyAgICAgICIgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQkbGl0ZSQuZW1wdHlNYXBGaWVsZChcbiIKKyAgICAgICIgICAgICAgICRtYXBfZmllbGRfcGFyYW1ldGVyJCk7XG4iCisgICAgICAiIH1cbiIKKyAgICAgICIgIHJldHVybiAkbmFtZSRfO1xuIgorICAgICAgIn1cbiIpOworICBpZiAoR2V0SmF2YVR5cGUoVmFsdWVGaWVsZChkZXNjcmlwdG9yXykpID09IEpBVkFUWVBFX0VOVU0pIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgdmFyaWFibGVzXywKKyAgICAgICAgInByaXZhdGUgc3RhdGljIGZpbmFsXG4iCisgICAgICAgICJjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPFxuIgorICAgICAgICAiICAgIGphdmEubGFuZy5JbnRlZ2VyLCAkdmFsdWVfZW51bV90eXBlJD4gJG5hbWUkVmFsdWVDb252ZXJ0ZXIgPVxuIgorICAgICAgICAiICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcihcbiIKKyAgICAgICAgIiAgICAgICAgICAgICR2YWx1ZV9lbnVtX3R5cGUkLmludGVybmFsR2V0VmFsdWVNYXAoKSxcbiIKKyAgICAgICAgIiAgICAgICAgICAgICR1bnJlY29nbml6ZWRfdmFsdWUkKTtcbiIpOworICAgIGlmIChTdXBwb3J0VW5rbm93bkVudW1WYWx1ZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgdmFyaWFibGVzXywKKyAgICAgICAgICAiJGRlcHJlY2F0aW9uJFxuIgorICAgICAgICAgICJwdWJsaWMgamF2YS51dGlsLk1hcDwkYm94ZWRfa2V5X3R5cGUkLCAkYm94ZWRfdmFsdWVfdHlwZSQ+XG4iCisgICAgICAgICAgImdldCRjYXBpdGFsaXplZF9uYW1lJFZhbHVlKCkge1xuIgorICAgICAgICAgICIgIHJldHVybiBpbnRlcm5hbEdldCRjYXBpdGFsaXplZF9uYW1lJCgpLmdldE1hcCgpO1xuIgorICAgICAgICAgICJ9XG4iKTsKKyAgICB9CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICB2YXJpYWJsZXNfLAorICAgICAgICAiJGRlcHJlY2F0aW9uJFxuIgorICAgICAgICAicHVibGljIGphdmEudXRpbC5NYXA8JGJveGVkX2tleV90eXBlJCwgJHZhbHVlX2VudW1fdHlwZSQ+XG4iCisgICAgICAgICJnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgICAgICIgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyPFxuIgorICAgICAgICAiICAgICAgJGJveGVkX2tleV90eXBlJCwgJHZhbHVlX2VudW1fdHlwZSQsIGphdmEubGFuZy5JbnRlZ2VyPihcbiIKKyAgICAgICAgIiAgICAgICAgICBpbnRlcm5hbEdldCRjYXBpdGFsaXplZF9uYW1lJCgpLmdldE1hcCgpLFxuIgorICAgICAgICAiICAgICAgICAgICRuYW1lJFZhbHVlQ29udmVydGVyKTtcbiIKKyAgICAgICAgIn1cbiIpOworICB9IGVsc2UgeworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgdmFyaWFibGVzXywKKyAgICAgICAgIiRkZXByZWNhdGlvbiRcbiIKKyAgICAgICAgInB1YmxpYyBqYXZhLnV0aWwuTWFwPCR0eXBlX3BhcmFtZXRlcnMkPiBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgICAgICIgIHJldHVybiBpbnRlcm5hbEdldCRjYXBpdGFsaXplZF9uYW1lJCgpLmdldE1hcCgpO1xuIgorICAgICAgICAifVxuIik7CisgIH0KK30KKwordm9pZCBJbW11dGFibGVNYXBGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUJ1aWxkZXJNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KAorICAgICAgdmFyaWFibGVzXywKKyAgICAgICJwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQkbGl0ZSQ8XG4iCisgICAgICAiICAgICR0eXBlX3BhcmFtZXRlcnMkPiAkbmFtZSRfO1xuIgorICAgICAgInByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZCRsaXRlJDwkdHlwZV9wYXJhbWV0ZXJzJD5cbiIKKyAgICAgICJpbnRlcm5hbEdldCRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAgICIgIGlmICgkbmFtZSRfID09IG51bGwpIHtcbiIKKyAgICAgICIgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQkbGl0ZSQuZW1wdHlNYXBGaWVsZChcbiIKKyAgICAgICIgICAgICAgICRtYXBfZmllbGRfcGFyYW1ldGVyJCk7XG4iCisgICAgICAiIH1cbiIKKyAgICAgICIgIHJldHVybiAkbmFtZSRfO1xuIgorICAgICAgIn1cbiIKKyAgICAgICJwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQkbGl0ZSQ8JHR5cGVfcGFyYW1ldGVycyQ+XG4iCisgICAgICAiaW50ZXJuYWxHZXRNdXRhYmxlJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICAgIiAgJG9uX2NoYW5nZWQkO1xuIgorICAgICAgIiAgaWYgKCRuYW1lJF8gPT0gbnVsbCkge1xuIgorICAgICAgIiAgICAkbmFtZSRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZCRsaXRlJC5uZXdNYXBGaWVsZChcbiIKKyAgICAgICIgICAgICAgICRtYXBfZmllbGRfcGFyYW1ldGVyJCk7XG4iCisgICAgICAiICB9XG4iCisgICAgICAiICBpZiAoISRuYW1lJF8uaXNNdXRhYmxlKCkpIHtcbiIKKyAgICAgICIgICAgJG5hbWUkXyA9ICRuYW1lJF8uY29weSgpO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIiAgcmV0dXJuICRuYW1lJF87XG4iCisgICAgICAifVxuIik7CisgIGlmIChHZXRKYXZhVHlwZShWYWx1ZUZpZWxkKGRlc2NyaXB0b3JfKSkgPT0gSkFWQVRZUEVfRU5VTSkgeworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgdmFyaWFibGVzXywKKyAgICAgICAgIiRkZXByZWNhdGlvbiRcbiIKKyAgICAgICAgInB1YmxpYyBqYXZhLnV0aWwuTWFwPCRib3hlZF9rZXlfdHlwZSQsICR2YWx1ZV9lbnVtX3R5cGUkPlxuIgorICAgICAgICAiZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICAgICAiICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjxcbiIKKyAgICAgICAgIiAgICAgICRib3hlZF9rZXlfdHlwZSQsICR2YWx1ZV9lbnVtX3R5cGUkLCBqYXZhLmxhbmcuSW50ZWdlcj4oXG4iCisgICAgICAgICIgICAgICAgICAgaW50ZXJuYWxHZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKS5nZXRNYXAoKSxcbiIKKyAgICAgICAgIiAgICAgICAgICAkbmFtZSRWYWx1ZUNvbnZlcnRlcik7XG4iCisgICAgICAgICJ9XG4iKTsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgIHZhcmlhYmxlc18sCisgICAgICAgICIkZGVwcmVjYXRpb24kXG4iCisgICAgICAgICJwdWJsaWMgamF2YS51dGlsLk1hcDwkYm94ZWRfa2V5X3R5cGUkLCAkdmFsdWVfZW51bV90eXBlJD5cbiIKKyAgICAgICAgImdldE11dGFibGUkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgICAgICIgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyPFxuIgorICAgICAgICAiICAgICAgJGJveGVkX2tleV90eXBlJCwgJHZhbHVlX2VudW1fdHlwZSQsIGphdmEubGFuZy5JbnRlZ2VyPihcbiIKKyAgICAgICAgIiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGUkY2FwaXRhbGl6ZWRfbmFtZSQoKS5nZXRNdXRhYmxlTWFwKCksXG4iCisgICAgICAgICIgICAgICAgICAgJG5hbWUkVmFsdWVDb252ZXJ0ZXIpO1xuIgorICAgICAgICAifVxuIik7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICB2YXJpYWJsZXNfLAorICAgICAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIHB1dEFsbCRjYXBpdGFsaXplZF9uYW1lJChcbiIKKyAgICAgICAgIiAgICBqYXZhLnV0aWwuTWFwPCRib3hlZF9rZXlfdHlwZSQsICR2YWx1ZV9lbnVtX3R5cGUkPiB2YWx1ZXMpIHtcbiIKKyAgICAgICAgIiAgZ2V0TXV0YWJsZSRjYXBpdGFsaXplZF9uYW1lJCgpLnB1dEFsbCh2YWx1ZXMpO1xuIgorICAgICAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAgICAgIn1cbiIpOworICAgIGlmIChTdXBwb3J0VW5rbm93bkVudW1WYWx1ZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgdmFyaWFibGVzXywKKyAgICAgICAgICAiJGRlcHJlY2F0aW9uJFxuIgorICAgICAgICAgICJwdWJsaWMgamF2YS51dGlsLk1hcDwkYm94ZWRfa2V5X3R5cGUkLCAkYm94ZWRfdmFsdWVfdHlwZSQ+XG4iCisgICAgICAgICAgImdldCRjYXBpdGFsaXplZF9uYW1lJFZhbHVlKCkge1xuIgorICAgICAgICAgICIgIHJldHVybiBpbnRlcm5hbEdldCRjYXBpdGFsaXplZF9uYW1lJCgpLmdldE1hcCgpO1xuIgorICAgICAgICAgICJ9XG4iKTsKKyAgICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgIHZhcmlhYmxlc18sCisgICAgICAgICAgIiRkZXByZWNhdGlvbiRcbiIKKyAgICAgICAgICAicHVibGljIGphdmEudXRpbC5NYXA8JGJveGVkX2tleV90eXBlJCwgJGJveGVkX3ZhbHVlX3R5cGUkPlxuIgorICAgICAgICAgICJnZXRNdXRhYmxlJGNhcGl0YWxpemVkX25hbWUkVmFsdWUoKSB7XG4iCisgICAgICAgICAgIiAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZSRjYXBpdGFsaXplZF9uYW1lJCgpLmdldE11dGFibGVNYXAoKTtcbiIKKyAgICAgICAgICAifVxuIik7CisgICAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICB2YXJpYWJsZXNfLAorICAgICAgICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgcHV0QWxsJGNhcGl0YWxpemVkX25hbWUkVmFsdWUoXG4iCisgICAgICAgICAgIiAgICBqYXZhLnV0aWwuTWFwPCRib3hlZF9rZXlfdHlwZSQsICRib3hlZF92YWx1ZV90eXBlJD4gdmFsdWVzKSB7XG4iCisgICAgICAgICAgIiAgZ2V0TXV0YWJsZSRjYXBpdGFsaXplZF9uYW1lJFZhbHVlKCkucHV0QWxsKHZhbHVlcyk7XG4iCisgICAgICAgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgICAgICAgIn1cbiIpOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgIHZhcmlhYmxlc18sCisgICAgICAgICJwdWJsaWMgamF2YS51dGlsLk1hcDwkdHlwZV9wYXJhbWV0ZXJzJD4gZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICAgICAiICByZXR1cm4gaW50ZXJuYWxHZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKS5nZXRNYXAoKTtcbiIKKyAgICAgICAgIn1cbiIpOworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgdmFyaWFibGVzXywKKyAgICAgICAgInB1YmxpYyBqYXZhLnV0aWwuTWFwPCR0eXBlX3BhcmFtZXRlcnMkPlxuIgorICAgICAgICAiZ2V0TXV0YWJsZSRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAgICAgIiAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZSRjYXBpdGFsaXplZF9uYW1lJCgpLmdldE11dGFibGVNYXAoKTtcbiIKKyAgICAgICAgIn1cbiIpOworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgdmFyaWFibGVzXywKKyAgICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBwdXRBbGwkY2FwaXRhbGl6ZWRfbmFtZSQoXG4iCisgICAgICAgICIgICAgamF2YS51dGlsLk1hcDwkdHlwZV9wYXJhbWV0ZXJzJD4gdmFsdWVzKSB7XG4iCisgICAgICAgICIgIGdldE11dGFibGUkY2FwaXRhbGl6ZWRfbmFtZSQoKS5wdXRBbGwodmFsdWVzKTtcbiIKKyAgICAgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgICAgICJ9XG4iKTsKKyAgfQorfQorCit2b2lkIEltbXV0YWJsZU1hcEZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlRmllbGRCdWlsZGVySW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSAgY29uc3QgeworICAvLyBOb3RoaW5nIHRvIGluaXRpYWxpemUuCit9CisKK3ZvaWQgSW1tdXRhYmxlTWFwRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gTm90aGluZyB0byBpbml0aWFsaXplLgorfQorCit2b2lkIEltbXV0YWJsZU1hcEZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRlckNsZWFyQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCgKKyAgICAgIHZhcmlhYmxlc18sCisgICAgICAiaW50ZXJuYWxHZXRNdXRhYmxlJGNhcGl0YWxpemVkX25hbWUkKCkuY2xlYXIoKTtcbiIpOworfQorCit2b2lkIEltbXV0YWJsZU1hcEZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICB2YXJpYWJsZXNfLAorICAgICAgImludGVybmFsR2V0TXV0YWJsZSRjYXBpdGFsaXplZF9uYW1lJCgpLm1lcmdlRnJvbShcbiIKKyAgICAgICIgICAgb3RoZXIuaW50ZXJuYWxHZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSk7XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVNYXBGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUJ1aWxkaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCgKKyAgICAgIHZhcmlhYmxlc18sCisgICAgICAicmVzdWx0LiRuYW1lJF8gPSBpbnRlcm5hbEdldCRjYXBpdGFsaXplZF9uYW1lJCgpO1xuIgorICAgICAgInJlc3VsdC4kbmFtZSRfLm1ha2VJbW11dGFibGUoKTtcbiIpOworfQorCit2b2lkIEltbXV0YWJsZU1hcEZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICB2YXJpYWJsZXNfLAorICAgICAgImlmICghJGdldF9tdXRhYmxlX2JpdF9wYXJzZXIkKSB7XG4iCisgICAgICAiICAkbmFtZSRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZCRsaXRlJC5uZXdNYXBGaWVsZChcbiIKKyAgICAgICIgICAgICAkbWFwX2ZpZWxkX3BhcmFtZXRlciQpO1xuIgorICAgICAgIiAgJHNldF9tdXRhYmxlX2JpdF9wYXJzZXIkO1xuIgorICAgICAgIn1cbiIpOworICBpZiAoIVN1cHBvcnRVbmtub3duRW51bVZhbHVlKGRlc2NyaXB0b3JfLT5maWxlKCkpICYmCisgICAgICBHZXRKYXZhVHlwZShWYWx1ZUZpZWxkKGRlc2NyaXB0b3JfKSkgPT0gSkFWQVRZUEVfRU5VTSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICB2YXJpYWJsZXNfLAorICAgICAgICAiY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJ5dGVzID0gaW5wdXQucmVhZEJ5dGVzKCk7XG4iCisgICAgICAgICJjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5JGxpdGUkPCR0eXBlX3BhcmFtZXRlcnMkPlxuIgorICAgICAgICAiJG5hbWUkID0gJGRlZmF1bHRfZW50cnkkLmdldFBhcnNlckZvclR5cGUoKS5wYXJzZUZyb20oYnl0ZXMpO1xuIik7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgIHZhcmlhYmxlc18sCisgICAgICAgICJpZiAoJHZhbHVlX2VudW1fdHlwZSQudmFsdWVPZigkbmFtZSQuZ2V0VmFsdWUoKSkgPT0gbnVsbCkge1xuIgorICAgICAgICAiICB1bmtub3duRmllbGRzLm1lcmdlTGVuZ3RoRGVsaW1pdGVkRmllbGQoJG51bWJlciQsIGJ5dGVzKTtcbiIKKyAgICAgICAgIn0gZWxzZSB7XG4iCisgICAgICAgICIgICRuYW1lJF8uZ2V0TXV0YWJsZU1hcCgpLnB1dCgkbmFtZSQuZ2V0S2V5KCksICRuYW1lJC5nZXRWYWx1ZSgpKTtcbiIKKyAgICAgICAgIn1cbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICB2YXJpYWJsZXNfLAorICAgICAgICAiY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeSRsaXRlJDwkdHlwZV9wYXJhbWV0ZXJzJD5cbiIKKyAgICAgICAgIiRuYW1lJCA9IGlucHV0LnJlYWRNZXNzYWdlKFxuIgorICAgICAgICAiICAgICRkZWZhdWx0X2VudHJ5JC5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTtcbiIKKyAgICAgICAgIiRuYW1lJF8uZ2V0TXV0YWJsZU1hcCgpLnB1dCgkbmFtZSQuZ2V0S2V5KCksICRuYW1lJC5nZXRWYWx1ZSgpKTtcbiIpOworICB9Cit9CisKK3ZvaWQgSW1tdXRhYmxlTWFwRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVQYXJzaW5nRG9uZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gTm90aGluZyB0byBkbyBoZXJlLgorfQorCit2b2lkIEltbXV0YWJsZU1hcEZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICB2YXJpYWJsZXNfLAorICAgICAgImZvciAoamF2YS51dGlsLk1hcC5FbnRyeTwkdHlwZV9wYXJhbWV0ZXJzJD4gZW50cnlcbiIKKyAgICAgICIgICAgIDogaW50ZXJuYWxHZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7XG4iCisgICAgICAiICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5JGxpdGUkPCR0eXBlX3BhcmFtZXRlcnMkPlxuIgorICAgICAgIiAgJG5hbWUkID0gJGRlZmF1bHRfZW50cnkkLm5ld0J1aWxkZXJGb3JUeXBlKClcbiIKKyAgICAgICIgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKVxuIgorICAgICAgIiAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKVxuIgorICAgICAgIiAgICAgIC5idWlsZCgpO1xuIgorICAgICAgIiAgb3V0cHV0LndyaXRlTWVzc2FnZSgkbnVtYmVyJCwgJG5hbWUkKTtcbiIKKyAgICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVNYXBGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCgKKyAgICAgIHZhcmlhYmxlc18sCisgICAgICAiZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PCR0eXBlX3BhcmFtZXRlcnMkPiBlbnRyeVxuIgorICAgICAgIiAgICAgOiBpbnRlcm5hbEdldCRjYXBpdGFsaXplZF9uYW1lJCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHtcbiIKKyAgICAgICIgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkkbGl0ZSQ8JHR5cGVfcGFyYW1ldGVycyQ+XG4iCisgICAgICAiICAkbmFtZSQgPSAkZGVmYXVsdF9lbnRyeSQubmV3QnVpbGRlckZvclR5cGUoKVxuIgorICAgICAgIiAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpXG4iCisgICAgICAiICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpXG4iCisgICAgICAiICAgICAgLmJ1aWxkKCk7XG4iCisgICAgICAiICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW1cbiIKKyAgICAgICIgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKCRudW1iZXIkLCAkbmFtZSQpO1xuIgorICAgICAgIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZU1hcEZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCgKKyAgICAgIHZhcmlhYmxlc18sCisgICAgICAicmVzdWx0ID0gcmVzdWx0ICYmIGludGVybmFsR2V0JGNhcGl0YWxpemVkX25hbWUkKCkuZXF1YWxzKFxuIgorICAgICAgIiAgICBvdGhlci5pbnRlcm5hbEdldCRjYXBpdGFsaXplZF9uYW1lJCgpKTtcbiIpOworfQorCit2b2lkIEltbXV0YWJsZU1hcEZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlSGFzaENvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICB2YXJpYWJsZXNfLAorICAgICAgImlmICghaW50ZXJuYWxHZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHtcbiIKKyAgICAgICIgIGhhc2ggPSAoMzcgKiBoYXNoKSArICRjb25zdGFudF9uYW1lJDtcbiIKKyAgICAgICIgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0JGNhcGl0YWxpemVkX25hbWUkKCkuaGFzaENvZGUoKTtcbiIKKyAgICAgICJ9XG4iKTsKK30KKworc3RyaW5nIEltbXV0YWJsZU1hcEZpZWxkR2VuZXJhdG9yOjpHZXRCb3hlZFR5cGUoKSBjb25zdCB7CisgIHJldHVybiBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3JfLT5tZXNzYWdlX3R5cGUoKSk7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbWFwX2ZpZWxkLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tYXBfZmllbGQuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMjc2OGYzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbWFwX2ZpZWxkLmgKQEAgLTAsMCArMSw3OSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfTUFQX0ZJRUxEX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9NQVBfRklFTERfSF9fCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2ZpZWxkLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YSB7CisKK2NsYXNzIEltbXV0YWJsZU1hcEZpZWxkR2VuZXJhdG9yIDogcHVibGljIEltbXV0YWJsZUZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IEltbXV0YWJsZU1hcEZpZWxkR2VuZXJhdG9yKAorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwgQ29udGV4dCogY29udGV4dCk7CisgIH5JbW11dGFibGVNYXBGaWVsZEdlbmVyYXRvcigpOworCisgIC8vIGltcGxlbWVudHMgSW1tdXRhYmxlRmllbGRHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIGludCBHZXROdW1CaXRzRm9yTWVzc2FnZSgpIGNvbnN0OworICBpbnQgR2V0TnVtQml0c0ZvckJ1aWxkZXIoKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUludGVyZmFjZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnVpbGRlckNsZWFyQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCdWlsZGluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlUGFyc2luZ0RvbmVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVGaWVsZEJ1aWxkZXJJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVIYXNoQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyAgc3RyaW5nIEdldEJveGVkVHlwZSgpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXNfOworICBDbGFzc05hbWVSZXNvbHZlciogbmFtZV9yZXNvbHZlcl87Cit9OworCit9ICAvLyBuYW1lc3BhY2UgamF2YQorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9NQVBfRklFTERfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tYXBfZmllbGRfbGl0ZS5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21hcF9maWVsZF9saXRlLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQyMDM5NDAKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tYXBfZmllbGRfbGl0ZS5jYwpAQCAtMCwwICsxLDQ4MyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21hcF9maWVsZF9saXRlLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2NvbnRleHQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2RvY19jb21tZW50Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9uYW1lX3Jlc29sdmVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhIHsKKworbmFtZXNwYWNlIHsKKworY29uc3QgRmllbGREZXNjcmlwdG9yKiBLZXlGaWVsZChjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgR09PR0xFX0NIRUNLX0VRKEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9NRVNTQUdFLCBkZXNjcmlwdG9yLT50eXBlKCkpOworICBjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlID0gZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCk7CisgIEdPT0dMRV9DSEVDSyhtZXNzYWdlLT5vcHRpb25zKCkubWFwX2VudHJ5KCkpOworICByZXR1cm4gbWVzc2FnZS0+RmluZEZpZWxkQnlOYW1lKCJrZXkiKTsKK30KKworY29uc3QgRmllbGREZXNjcmlwdG9yKiBWYWx1ZUZpZWxkKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBHT09HTEVfQ0hFQ0tfRVEoRmllbGREZXNjcmlwdG9yOjpUWVBFX01FU1NBR0UsIGRlc2NyaXB0b3ItPnR5cGUoKSk7CisgIGNvbnN0IERlc2NyaXB0b3IqIG1lc3NhZ2UgPSBkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKTsKKyAgR09PR0xFX0NIRUNLKG1lc3NhZ2UtPm9wdGlvbnMoKS5tYXBfZW50cnkoKSk7CisgIHJldHVybiBtZXNzYWdlLT5GaW5kRmllbGRCeU5hbWUoInZhbHVlIik7Cit9CisKK3N0cmluZyBUeXBlTmFtZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgIENsYXNzTmFtZVJlc29sdmVyKiBuYW1lX3Jlc29sdmVyLAorICAgICAgICAgICAgICAgIGJvb2wgYm94ZWQpIHsKKyAgaWYgKEdldEphdmFUeXBlKGZpZWxkKSA9PSBKQVZBVFlQRV9NRVNTQUdFKSB7CisgICAgcmV0dXJuIG5hbWVfcmVzb2x2ZXItPkdldEltbXV0YWJsZUNsYXNzTmFtZShmaWVsZC0+bWVzc2FnZV90eXBlKCkpOworICB9IGVsc2UgaWYgKEdldEphdmFUeXBlKGZpZWxkKSA9PSBKQVZBVFlQRV9FTlVNKSB7CisgICAgcmV0dXJuIG5hbWVfcmVzb2x2ZXItPkdldEltbXV0YWJsZUNsYXNzTmFtZShmaWVsZC0+ZW51bV90eXBlKCkpOworICB9IGVsc2UgeworICAgIHJldHVybiBib3hlZCA/IEJveGVkUHJpbWl0aXZlVHlwZU5hbWUoR2V0SmF2YVR5cGUoZmllbGQpKQorICAgICAgICAgICAgICAgICA6IFByaW1pdGl2ZVR5cGVOYW1lKEdldEphdmFUeXBlKGZpZWxkKSk7CisgIH0KK30KKworc3RyaW5nIFdpcmVUeXBlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgcmV0dXJuICJjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLiIgKworICAgICAgc3RyaW5nKEZpZWxkVHlwZU5hbWUoZmllbGQtPnR5cGUoKSkpOworfQorCit2b2lkIFNldE1lc3NhZ2VWYXJpYWJsZXMoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgIGludCBtZXNzYWdlQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZEdlbmVyYXRvckluZm8qIGluZm8sCisgICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3NOYW1lUmVzb2x2ZXIqIG5hbWVfcmVzb2x2ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgbWFwPHN0cmluZywgc3RyaW5nPiogdmFyaWFibGVzKSB7CisgIFNldENvbW1vbkZpZWxkVmFyaWFibGVzKGRlc2NyaXB0b3IsIGluZm8sIHZhcmlhYmxlcyk7CisKKyAgKCp2YXJpYWJsZXMpWyJ0eXBlIl0gPQorICAgICAgbmFtZV9yZXNvbHZlci0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBrZXkgPSBLZXlGaWVsZChkZXNjcmlwdG9yKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiB2YWx1ZSA9IFZhbHVlRmllbGQoZGVzY3JpcHRvcik7CisgICgqdmFyaWFibGVzKVsia2V5X3R5cGUiXSA9IFR5cGVOYW1lKGtleSwgbmFtZV9yZXNvbHZlciwgZmFsc2UpOworICAoKnZhcmlhYmxlcylbImJveGVkX2tleV90eXBlIl0gPSBUeXBlTmFtZShrZXksIG5hbWVfcmVzb2x2ZXIsIHRydWUpOworICAoKnZhcmlhYmxlcylbImtleV93aXJlX3R5cGUiXSA9IFdpcmVUeXBlKGtleSk7CisgICgqdmFyaWFibGVzKVsia2V5X2RlZmF1bHRfdmFsdWUiXSA9IERlZmF1bHRWYWx1ZShrZXksIHRydWUsIG5hbWVfcmVzb2x2ZXIpOworICBpZiAoR2V0SmF2YVR5cGUodmFsdWUpID09IEpBVkFUWVBFX0VOVU0pIHsKKyAgICAvLyBXZSBzdG9yZSBlbnVtcyBhcyBJbnRlZ2VycyBpbnRlcm5hbGx5LgorICAgICgqdmFyaWFibGVzKVsidmFsdWVfdHlwZSJdID0gImludCI7CisgICAgKCp2YXJpYWJsZXMpWyJib3hlZF92YWx1ZV90eXBlIl0gPSAiamF2YS5sYW5nLkludGVnZXIiOworICAgICgqdmFyaWFibGVzKVsidmFsdWVfd2lyZV90eXBlIl0gPSBXaXJlVHlwZSh2YWx1ZSk7CisgICAgKCp2YXJpYWJsZXMpWyJ2YWx1ZV9kZWZhdWx0X3ZhbHVlIl0gPQorICAgICAgICBEZWZhdWx0VmFsdWUodmFsdWUsIHRydWUsIG5hbWVfcmVzb2x2ZXIpICsgIi5nZXROdW1iZXIoKSI7CisKKyAgICAoKnZhcmlhYmxlcylbInZhbHVlX2VudW1fdHlwZSJdID0gVHlwZU5hbWUodmFsdWUsIG5hbWVfcmVzb2x2ZXIsIGZhbHNlKTsKKworICAgIGlmIChTdXBwb3J0VW5rbm93bkVudW1WYWx1ZShkZXNjcmlwdG9yLT5maWxlKCkpKSB7CisgICAgICAvLyBNYXAgdW5rbm93biB2YWx1ZXMgdG8gYSBzcGVjaWFsIFVOUkVDT0dOSVpFRCB2YWx1ZSBpZiBzdXBwb3J0ZWQuCisgICAgICAoKnZhcmlhYmxlcylbInVucmVjb2duaXplZF92YWx1ZSJdID0KKyAgICAgICAgICAoKnZhcmlhYmxlcylbInZhbHVlX2VudW1fdHlwZSJdICsgIi5VTlJFQ09HTklaRUQiOworICAgIH0gZWxzZSB7CisgICAgICAvLyBNYXAgdW5rbm93biB2YWx1ZXMgdG8gdGhlIGRlZmF1bHQgdmFsdWUgaWYgd2UgZG9uJ3QgaGF2ZSBVTlJFQ09HTklaRUQuCisgICAgICAoKnZhcmlhYmxlcylbInVucmVjb2duaXplZF92YWx1ZSJdID0KKyAgICAgICAgICBEZWZhdWx0VmFsdWUodmFsdWUsIHRydWUsIG5hbWVfcmVzb2x2ZXIpOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICAoKnZhcmlhYmxlcylbInZhbHVlX3R5cGUiXSA9IFR5cGVOYW1lKHZhbHVlLCBuYW1lX3Jlc29sdmVyLCBmYWxzZSk7CisgICAgKCp2YXJpYWJsZXMpWyJib3hlZF92YWx1ZV90eXBlIl0gPSBUeXBlTmFtZSh2YWx1ZSwgbmFtZV9yZXNvbHZlciwgdHJ1ZSk7CisgICAgKCp2YXJpYWJsZXMpWyJ2YWx1ZV93aXJlX3R5cGUiXSA9IFdpcmVUeXBlKHZhbHVlKTsKKyAgICAoKnZhcmlhYmxlcylbInZhbHVlX2RlZmF1bHRfdmFsdWUiXSA9CisgICAgICAgIERlZmF1bHRWYWx1ZSh2YWx1ZSwgdHJ1ZSwgbmFtZV9yZXNvbHZlcik7CisgIH0KKyAgKCp2YXJpYWJsZXMpWyJ0eXBlX3BhcmFtZXRlcnMiXSA9CisgICAgICAoKnZhcmlhYmxlcylbImJveGVkX2tleV90eXBlIl0gKyAiLCAiICsgKCp2YXJpYWJsZXMpWyJib3hlZF92YWx1ZV90eXBlIl07CisgIC8vIFRPRE8oYmlyZG8pOiBBZGQgQGRlcHJlY2F0ZWQgamF2YWRvYyB3aGVuIGdlbmVyYXRpbmcgamF2YWRvYyBpcyBzdXBwb3J0ZWQKKyAgLy8gYnkgdGhlIHByb3RvIGNvbXBpbGVyCisgICgqdmFyaWFibGVzKVsiZGVwcmVjYXRpb24iXSA9IGRlc2NyaXB0b3ItPm9wdGlvbnMoKS5kZXByZWNhdGVkKCkKKyAgICAgID8gIkBqYXZhLmxhbmcuRGVwcmVjYXRlZCAiIDogIiI7CisgICgqdmFyaWFibGVzKVsib25fY2hhbmdlZCJdID0KKyAgICAgIEhhc0Rlc2NyaXB0b3JNZXRob2RzKGRlc2NyaXB0b3ItPmNvbnRhaW5pbmdfdHlwZSgpKSA/ICJvbkNoYW5nZWQoKTsiIDogIiI7CisKKyAgKCp2YXJpYWJsZXMpWyJkZWZhdWx0X2VudHJ5Il0gPSAoKnZhcmlhYmxlcylbImNhcGl0YWxpemVkX25hbWUiXSArCisgICAgICAiRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSI7CisgICgqdmFyaWFibGVzKVsibGl0ZSJdID0gIkxpdGUiOworICAoKnZhcmlhYmxlcylbImRlc2NyaXB0b3IiXSA9ICIiOworfQorCit9ICAvLyBuYW1lc3BhY2UKKworSW1tdXRhYmxlTWFwRmllbGRMaXRlR2VuZXJhdG9yOjoKK0ltbXV0YWJsZU1hcEZpZWxkTGl0ZUdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnRleHQqIGNvbnRleHQpCisgIDogZGVzY3JpcHRvcl8oZGVzY3JpcHRvciksIG5hbWVfcmVzb2x2ZXJfKGNvbnRleHQtPkdldE5hbWVSZXNvbHZlcigpKSAgeworICBTZXRNZXNzYWdlVmFyaWFibGVzKGRlc2NyaXB0b3IsIG1lc3NhZ2VCaXRJbmRleCwgYnVpbGRlckJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQtPkdldEZpZWxkR2VuZXJhdG9ySW5mbyhkZXNjcmlwdG9yKSwKKyAgICAgICAgICAgICAgICAgICAgICBuYW1lX3Jlc29sdmVyXywgJnZhcmlhYmxlc18pOworfQorCitJbW11dGFibGVNYXBGaWVsZExpdGVHZW5lcmF0b3I6OgorfkltbXV0YWJsZU1hcEZpZWxkTGl0ZUdlbmVyYXRvcigpIHt9CisKK2ludCBJbW11dGFibGVNYXBGaWVsZExpdGVHZW5lcmF0b3I6OkdldE51bUJpdHNGb3JNZXNzYWdlKCkgY29uc3QgeworICByZXR1cm4gMDsKK30KKworaW50IEltbXV0YWJsZU1hcEZpZWxkTGl0ZUdlbmVyYXRvcjo6R2V0TnVtQml0c0ZvckJ1aWxkZXIoKSBjb25zdCB7CisgIHJldHVybiAwOworfQorCit2b2lkIEltbXV0YWJsZU1hcEZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUludGVyZmFjZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKEdldEphdmFUeXBlKFZhbHVlRmllbGQoZGVzY3JpcHRvcl8pKSA9PSBKQVZBVFlQRV9FTlVNKSB7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICB2YXJpYWJsZXNfLAorICAgICAgICAiJGRlcHJlY2F0aW9uJGphdmEudXRpbC5NYXA8JGJveGVkX2tleV90eXBlJCwgJHZhbHVlX2VudW1fdHlwZSQ+XG4iCisgICAgICAgICJnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKTtcbiIpOworICAgIGlmIChTdXBwb3J0VW5rbm93bkVudW1WYWx1ZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgdmFyaWFibGVzXywKKyAgICAgICAgICAiJGRlcHJlY2F0aW9uJGphdmEudXRpbC5NYXA8JHR5cGVfcGFyYW1ldGVycyQ+XG4iCisgICAgICAgICAgImdldCRjYXBpdGFsaXplZF9uYW1lJFZhbHVlKCk7XG4iKTsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICB2YXJpYWJsZXNfLAorICAgICAgICAiJGRlcHJlY2F0aW9uJGphdmEudXRpbC5NYXA8JHR5cGVfcGFyYW1ldGVycyQ+XG4iCisgICAgICAgICJnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKTtcbiIpOworICB9Cit9CisKK3ZvaWQgSW1tdXRhYmxlTWFwRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCgKKyAgICAgIHZhcmlhYmxlc18sCisgICAgICAicHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgJGNhcGl0YWxpemVkX25hbWUkRGVmYXVsdEVudHJ5SG9sZGVyIHtcbiIKKyAgICAgICIgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5JGxpdGUkPFxuIgorICAgICAgIiAgICAgICR0eXBlX3BhcmFtZXRlcnMkPiBkZWZhdWx0RW50cnkgPVxuIgorICAgICAgIiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5JGxpdGUkXG4iCisgICAgICAiICAgICAgICAgIC48JHR5cGVfcGFyYW1ldGVycyQ+bmV3RGVmYXVsdEluc3RhbmNlKFxuIgorICAgICAgIiAgICAgICAgICAgICAgJGRlc2NyaXB0b3IkXG4iCisgICAgICAiICAgICAgICAgICAgICAka2V5X3dpcmVfdHlwZSQsXG4iCisgICAgICAiICAgICAgICAgICAgICAka2V5X2RlZmF1bHRfdmFsdWUkLFxuIgorICAgICAgIiAgICAgICAgICAgICAgJHZhbHVlX3dpcmVfdHlwZSQsXG4iCisgICAgICAiICAgICAgICAgICAgICAkdmFsdWVfZGVmYXVsdF92YWx1ZSQpO1xuIgorICAgICAgIn1cbiIpOworICBwcmludGVyLT5QcmludCgKKyAgICAgIHZhcmlhYmxlc18sCisgICAgICAicHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkJGxpdGUkPFxuIgorICAgICAgIiAgICAkdHlwZV9wYXJhbWV0ZXJzJD4gJG5hbWUkXyA9XG4iCisgICAgICAiICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkJGxpdGUkLmVtcHR5TWFwRmllbGQoKTtcbiIKKyAgICAgICJwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQkbGl0ZSQ8JHR5cGVfcGFyYW1ldGVycyQ+XG4iCisgICAgICAiaW50ZXJuYWxHZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgICAiICByZXR1cm4gJG5hbWUkXztcbiIKKyAgICAgICJ9XG4iCisgICAgICAicHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkJGxpdGUkPCR0eXBlX3BhcmFtZXRlcnMkPlxuIgorICAgICAgImludGVybmFsR2V0TXV0YWJsZSRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAgICIgIGlmICghJG5hbWUkXy5pc011dGFibGUoKSkge1xuIgorICAgICAgIiAgICAkbmFtZSRfID0gJG5hbWUkXy5jb3B5KCk7XG4iCisgICAgICAiICB9XG4iCisgICAgICAiICByZXR1cm4gJG5hbWUkXztcbiIKKyAgICAgICJ9XG4iKTsKKyAgaWYgKEdldEphdmFUeXBlKFZhbHVlRmllbGQoZGVzY3JpcHRvcl8pKSA9PSBKQVZBVFlQRV9FTlVNKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgIHZhcmlhYmxlc18sCisgICAgICAgICJwcml2YXRlIHN0YXRpYyBmaW5hbFxuIgorICAgICAgICAiY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjxcbiIKKyAgICAgICAgIiAgICBqYXZhLmxhbmcuSW50ZWdlciwgJHZhbHVlX2VudW1fdHlwZSQ+ICRuYW1lJFZhbHVlQ29udmVydGVyID1cbiIKKyAgICAgICAgIiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoXG4iCisgICAgICAgICIgICAgICAgICAgICAkdmFsdWVfZW51bV90eXBlJC5pbnRlcm5hbEdldFZhbHVlTWFwKCksXG4iCisgICAgICAgICIgICAgICAgICAgICAkdW5yZWNvZ25pemVkX3ZhbHVlJCk7XG4iKTsKKyAgICBpZiAoU3VwcG9ydFVua25vd25FbnVtVmFsdWUoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgIHZhcmlhYmxlc18sCisgICAgICAgICAgIiRkZXByZWNhdGlvbiRcbiIKKyAgICAgICAgICAicHVibGljIGphdmEudXRpbC5NYXA8JGJveGVkX2tleV90eXBlJCwgJGJveGVkX3ZhbHVlX3R5cGUkPlxuIgorICAgICAgICAgICJnZXQkY2FwaXRhbGl6ZWRfbmFtZSRWYWx1ZSgpIHtcbiIKKyAgICAgICAgICAiICByZXR1cm4gaW50ZXJuYWxHZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKS5nZXRNYXAoKTtcbiIKKyAgICAgICAgICAifVxuIik7CisgICAgfQorICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgdmFyaWFibGVzXywKKyAgICAgICAgIiRkZXByZWNhdGlvbiRcbiIKKyAgICAgICAgInB1YmxpYyBqYXZhLnV0aWwuTWFwPCRib3hlZF9rZXlfdHlwZSQsICR2YWx1ZV9lbnVtX3R5cGUkPlxuIgorICAgICAgICAiZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICAgICAiICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjxcbiIKKyAgICAgICAgIiAgICAgICRib3hlZF9rZXlfdHlwZSQsICR2YWx1ZV9lbnVtX3R5cGUkLCBqYXZhLmxhbmcuSW50ZWdlcj4oXG4iCisgICAgICAgICIgICAgICAgICAgaW50ZXJuYWxHZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKS5nZXRNYXAoKSxcbiIKKyAgICAgICAgIiAgICAgICAgICAkbmFtZSRWYWx1ZUNvbnZlcnRlcik7XG4iCisgICAgICAgICJ9XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgIHZhcmlhYmxlc18sCisgICAgICAgICIkZGVwcmVjYXRpb24kXG4iCisgICAgICAgICJwdWJsaWMgamF2YS51dGlsLk1hcDwkdHlwZV9wYXJhbWV0ZXJzJD4gZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICAgICAiICByZXR1cm4gaW50ZXJuYWxHZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKS5nZXRNYXAoKTtcbiIKKyAgICAgICAgIn1cbiIpOworICB9CisKKyAgLy8gR2VuZXJhdGUgcHJpdmF0ZSBzZXR0ZXJzIGZvciB0aGUgYnVpbGRlciB0byBwcm94eSBpbnRvLgorICBpZiAoR2V0SmF2YVR5cGUoVmFsdWVGaWVsZChkZXNjcmlwdG9yXykpID09IEpBVkFUWVBFX0VOVU0pIHsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgIHZhcmlhYmxlc18sCisgICAgICAgICJwcml2YXRlIGphdmEudXRpbC5NYXA8JGJveGVkX2tleV90eXBlJCwgJHZhbHVlX2VudW1fdHlwZSQ+XG4iCisgICAgICAgICJnZXRNdXRhYmxlJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICAgICAiICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjxcbiIKKyAgICAgICAgIiAgICAgICRib3hlZF9rZXlfdHlwZSQsICR2YWx1ZV9lbnVtX3R5cGUkLCBqYXZhLmxhbmcuSW50ZWdlcj4oXG4iCisgICAgICAgICIgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlJGNhcGl0YWxpemVkX25hbWUkKCkuZ2V0TXV0YWJsZU1hcCgpLFxuIgorICAgICAgICAiICAgICAgICAgICRuYW1lJFZhbHVlQ29udmVydGVyKTtcbiIKKyAgICAgICAgIn1cbiIpOworICAgIGlmIChTdXBwb3J0VW5rbm93bkVudW1WYWx1ZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgdmFyaWFibGVzXywKKyAgICAgICAgICAicHJpdmF0ZSBqYXZhLnV0aWwuTWFwPCRib3hlZF9rZXlfdHlwZSQsICRib3hlZF92YWx1ZV90eXBlJD5cbiIKKyAgICAgICAgICAiZ2V0TXV0YWJsZSRjYXBpdGFsaXplZF9uYW1lJFZhbHVlKCkge1xuIgorICAgICAgICAgICIgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGUkY2FwaXRhbGl6ZWRfbmFtZSQoKS5nZXRNdXRhYmxlTWFwKCk7XG4iCisgICAgICAgICAgIn1cbiIpOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgIHZhcmlhYmxlc18sCisgICAgICAgICJwcml2YXRlIGphdmEudXRpbC5NYXA8JHR5cGVfcGFyYW1ldGVycyQ+XG4iCisgICAgICAgICJnZXRNdXRhYmxlJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICAgICAiICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlJGNhcGl0YWxpemVkX25hbWUkKCkuZ2V0TXV0YWJsZU1hcCgpO1xuIgorICAgICAgICAifVxuIik7CisgIH0KK30KKwordm9pZCBJbW11dGFibGVNYXBGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoR2V0SmF2YVR5cGUoVmFsdWVGaWVsZChkZXNjcmlwdG9yXykpID09IEpBVkFUWVBFX0VOVU0pIHsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgIHZhcmlhYmxlc18sCisgICAgICAgICIkZGVwcmVjYXRpb24kXG4iCisgICAgICAgICJwdWJsaWMgamF2YS51dGlsLk1hcDwkYm94ZWRfa2V5X3R5cGUkLCAkdmFsdWVfZW51bV90eXBlJD5cbiIKKyAgICAgICAgImdldCRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAgICAgIiAgcmV0dXJuIGluc3RhbmNlLmdldCRjYXBpdGFsaXplZF9uYW1lJCgpO1xuIgorICAgICAgICAifVxuIik7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICB2YXJpYWJsZXNfLAorICAgICAgICAiJGRlcHJlY2F0aW9uJFxuIgorICAgICAgICAicHVibGljIGphdmEudXRpbC5NYXA8JGJveGVkX2tleV90eXBlJCwgJHZhbHVlX2VudW1fdHlwZSQ+XG4iCisgICAgICAgICJnZXRNdXRhYmxlJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICAgICAiICBjb3B5T25Xcml0ZSgpO1xuIgorICAgICAgICAiICByZXR1cm4gaW5zdGFuY2UuZ2V0TXV0YWJsZSRjYXBpdGFsaXplZF9uYW1lJCgpO1xuIgorICAgICAgICAifVxuIik7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICB2YXJpYWJsZXNfLAorICAgICAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIHB1dEFsbCRjYXBpdGFsaXplZF9uYW1lJChcbiIKKyAgICAgICAgIiAgICBqYXZhLnV0aWwuTWFwPCRib3hlZF9rZXlfdHlwZSQsICR2YWx1ZV9lbnVtX3R5cGUkPiB2YWx1ZXMpIHtcbiIKKyAgICAgICAgIiAgZ2V0TXV0YWJsZSRjYXBpdGFsaXplZF9uYW1lJCgpLnB1dEFsbCh2YWx1ZXMpO1xuIgorICAgICAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAgICAgIn1cbiIpOworICAgIGlmIChTdXBwb3J0VW5rbm93bkVudW1WYWx1ZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgdmFyaWFibGVzXywKKyAgICAgICAgICAiJGRlcHJlY2F0aW9uJFxuIgorICAgICAgICAgICJwdWJsaWMgamF2YS51dGlsLk1hcDwkYm94ZWRfa2V5X3R5cGUkLCAkYm94ZWRfdmFsdWVfdHlwZSQ+XG4iCisgICAgICAgICAgImdldCRjYXBpdGFsaXplZF9uYW1lJFZhbHVlKCkge1xuIgorICAgICAgICAgICIgIHJldHVybiBpbnN0YW5jZS5nZXQkY2FwaXRhbGl6ZWRfbmFtZSRWYWx1ZSgpO1xuIgorICAgICAgICAgICJ9XG4iKTsKKyAgICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgIHZhcmlhYmxlc18sCisgICAgICAgICAgIiRkZXByZWNhdGlvbiRcbiIKKyAgICAgICAgICAicHVibGljIGphdmEudXRpbC5NYXA8JGJveGVkX2tleV90eXBlJCwgJGJveGVkX3ZhbHVlX3R5cGUkPlxuIgorICAgICAgICAgICJnZXRNdXRhYmxlJGNhcGl0YWxpemVkX25hbWUkVmFsdWUoKSB7XG4iCisgICAgICAgICAgIiAgY29weU9uV3JpdGUoKTtcbiIKKyAgICAgICAgICAiICByZXR1cm4gaW5zdGFuY2UuZ2V0TXV0YWJsZSRjYXBpdGFsaXplZF9uYW1lJFZhbHVlKCk7XG4iCisgICAgICAgICAgIn1cbiIpOworICAgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgdmFyaWFibGVzXywKKyAgICAgICAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIHB1dEFsbCRjYXBpdGFsaXplZF9uYW1lJFZhbHVlKFxuIgorICAgICAgICAgICIgICAgamF2YS51dGlsLk1hcDwkYm94ZWRfa2V5X3R5cGUkLCAkYm94ZWRfdmFsdWVfdHlwZSQ+IHZhbHVlcykge1xuIgorICAgICAgICAgICIgIGdldE11dGFibGUkY2FwaXRhbGl6ZWRfbmFtZSRWYWx1ZSgpLnB1dEFsbCh2YWx1ZXMpO1xuIgorICAgICAgICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICAgICAgICJ9XG4iKTsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICB2YXJpYWJsZXNfLAorICAgICAgICAicHVibGljIGphdmEudXRpbC5NYXA8JHR5cGVfcGFyYW1ldGVycyQ+IGdldCRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAgICAgIiAgcmV0dXJuIGluc3RhbmNlLmdldCRjYXBpdGFsaXplZF9uYW1lJCgpO1xuIgorICAgICAgICAifVxuIik7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICB2YXJpYWJsZXNfLAorICAgICAgICAicHVibGljIGphdmEudXRpbC5NYXA8JHR5cGVfcGFyYW1ldGVycyQ+XG4iCisgICAgICAgICJnZXRNdXRhYmxlJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICAgICAiICBjb3B5T25Xcml0ZSgpO1xuIgorICAgICAgICAiICByZXR1cm4gaW5zdGFuY2UuZ2V0TXV0YWJsZSRjYXBpdGFsaXplZF9uYW1lJCgpO1xuIgorICAgICAgICAifVxuIik7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICB2YXJpYWJsZXNfLAorICAgICAgICAicHVibGljIEJ1aWxkZXIgcHV0QWxsJGNhcGl0YWxpemVkX25hbWUkKFxuIgorICAgICAgICAiICAgIGphdmEudXRpbC5NYXA8JHR5cGVfcGFyYW1ldGVycyQ+IHZhbHVlcykge1xuIgorICAgICAgICAiICBnZXRNdXRhYmxlJGNhcGl0YWxpemVkX25hbWUkKCkucHV0QWxsKHZhbHVlcyk7XG4iCisgICAgICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICAgICAifVxuIik7CisgIH0KK30KKwordm9pZCBJbW11dGFibGVNYXBGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVGaWVsZEJ1aWxkZXJJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpICBjb25zdCB7CisgIC8vIE5vdGhpbmcgdG8gaW5pdGlhbGl6ZS4KK30KKwordm9pZCBJbW11dGFibGVNYXBGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gTm90aGluZyB0byBpbml0aWFsaXplLgorfQorCit2b2lkIEltbXV0YWJsZU1hcEZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KAorICAgICAgdmFyaWFibGVzXywKKyAgICAgICJpbnRlcm5hbEdldE11dGFibGUkY2FwaXRhbGl6ZWRfbmFtZSQoKS5tZXJnZUZyb20oXG4iCisgICAgICAiICAgIG90aGVyLmludGVybmFsR2V0JGNhcGl0YWxpemVkX25hbWUkKCkpO1xuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlTWFwRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlRHluYW1pY01ldGhvZE1ha2VJbW11dGFibGVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRuYW1lJF8ubWFrZUltbXV0YWJsZSgpO1xuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlTWFwRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICB2YXJpYWJsZXNfLAorICAgICAgImlmICghJG5hbWUkXy5pc011dGFibGUoKSkge1xuIgorICAgICAgIiAgJG5hbWUkXyA9ICRuYW1lJF8uY29weSgpO1xuIgorICAgICAgIn1cbiIpOworICBpZiAoIVN1cHBvcnRVbmtub3duRW51bVZhbHVlKGRlc2NyaXB0b3JfLT5maWxlKCkpICYmCisgICAgICBHZXRKYXZhVHlwZShWYWx1ZUZpZWxkKGRlc2NyaXB0b3JfKSkgPT0gSkFWQVRZUEVfRU5VTSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICB2YXJpYWJsZXNfLAorICAgICAgICAiY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJ5dGVzID0gaW5wdXQucmVhZEJ5dGVzKCk7XG4iCisgICAgICAgICJjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5JGxpdGUkPCR0eXBlX3BhcmFtZXRlcnMkPlxuIgorICAgICAgICAiJG5hbWUkID0gJGRlZmF1bHRfZW50cnkkLmdldFBhcnNlckZvclR5cGUoKS5wYXJzZUZyb20oYnl0ZXMpO1xuIik7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgIHZhcmlhYmxlc18sCisgICAgICAgICJpZiAoJHZhbHVlX2VudW1fdHlwZSQudmFsdWVPZigkbmFtZSQuZ2V0VmFsdWUoKSkgPT0gbnVsbCkge1xuIgorICAgICAgICAiICBzdXBlci5tZXJnZUxlbmd0aERlbGltaXRlZEZpZWxkKCRudW1iZXIkLCBieXRlcyk7XG4iCisgICAgICAgICJ9IGVsc2Uge1xuIgorICAgICAgICAiICAkbmFtZSRfLmdldE11dGFibGVNYXAoKS5wdXQoJG5hbWUkLmdldEtleSgpLCAkbmFtZSQuZ2V0VmFsdWUoKSk7XG4iCisgICAgICAgICJ9XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgdmFyaWFibGVzXywKKyAgICAgICAgImNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkkbGl0ZSQ8JHR5cGVfcGFyYW1ldGVycyQ+XG4iCisgICAgICAgICIkbmFtZSQgPSBpbnB1dC5yZWFkTWVzc2FnZShcbiIKKyAgICAgICAgIiAgICAkZGVmYXVsdF9lbnRyeSQuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7XG4iCisgICAgICAgICIkbmFtZSRfLmdldE11dGFibGVNYXAoKS5wdXQoJG5hbWUkLmdldEtleSgpLCAkbmFtZSQuZ2V0VmFsdWUoKSk7XG4iKTsKKyAgfQorfQorCit2b2lkIEltbXV0YWJsZU1hcEZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZVBhcnNpbmdEb25lQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBOb3RoaW5nIHRvIGRvIGhlcmUuCit9CisKK3ZvaWQgSW1tdXRhYmxlTWFwRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICB2YXJpYWJsZXNfLAorICAgICAgImZvciAoamF2YS51dGlsLk1hcC5FbnRyeTwkdHlwZV9wYXJhbWV0ZXJzJD4gZW50cnlcbiIKKyAgICAgICIgICAgIDogaW50ZXJuYWxHZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7XG4iCisgICAgICAiICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5JGxpdGUkPCR0eXBlX3BhcmFtZXRlcnMkPlxuIgorICAgICAgIiAgJG5hbWUkID0gJGRlZmF1bHRfZW50cnkkLm5ld0J1aWxkZXJGb3JUeXBlKClcbiIKKyAgICAgICIgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKVxuIgorICAgICAgIiAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKVxuIgorICAgICAgIiAgICAgIC5idWlsZCgpO1xuIgorICAgICAgIiAgb3V0cHV0LndyaXRlTWVzc2FnZSgkbnVtYmVyJCwgJG5hbWUkKTtcbiIKKyAgICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVNYXBGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICB2YXJpYWJsZXNfLAorICAgICAgImZvciAoamF2YS51dGlsLk1hcC5FbnRyeTwkdHlwZV9wYXJhbWV0ZXJzJD4gZW50cnlcbiIKKyAgICAgICIgICAgIDogaW50ZXJuYWxHZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7XG4iCisgICAgICAiICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5JGxpdGUkPCR0eXBlX3BhcmFtZXRlcnMkPlxuIgorICAgICAgIiAgJG5hbWUkID0gJGRlZmF1bHRfZW50cnkkLm5ld0J1aWxkZXJGb3JUeXBlKClcbiIKKyAgICAgICIgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKVxuIgorICAgICAgIiAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKVxuIgorICAgICAgIiAgICAgIC5idWlsZCgpO1xuIgorICAgICAgIiAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtXG4iCisgICAgICAiICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgkbnVtYmVyJCwgJG5hbWUkKTtcbiIKKyAgICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVNYXBGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVFcXVhbHNDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KAorICAgICAgdmFyaWFibGVzXywKKyAgICAgICJyZXN1bHQgPSByZXN1bHQgJiYgaW50ZXJuYWxHZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKS5lcXVhbHMoXG4iCisgICAgICAiICAgIG90aGVyLmludGVybmFsR2V0JGNhcGl0YWxpemVkX25hbWUkKCkpO1xuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlTWFwRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlSGFzaENvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICB2YXJpYWJsZXNfLAorICAgICAgImlmICghaW50ZXJuYWxHZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHtcbiIKKyAgICAgICIgIGhhc2ggPSAoMzcgKiBoYXNoKSArICRjb25zdGFudF9uYW1lJDtcbiIKKyAgICAgICIgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0JGNhcGl0YWxpemVkX25hbWUkKCkuaGFzaENvZGUoKTtcbiIKKyAgICAgICJ9XG4iKTsKK30KKworc3RyaW5nIEltbXV0YWJsZU1hcEZpZWxkTGl0ZUdlbmVyYXRvcjo6R2V0Qm94ZWRUeXBlKCkgY29uc3QgeworICByZXR1cm4gbmFtZV9yZXNvbHZlcl8tPkdldEltbXV0YWJsZUNsYXNzTmFtZShkZXNjcmlwdG9yXy0+bWVzc2FnZV90eXBlKCkpOworfQorCit9ICAvLyBuYW1lc3BhY2UgamF2YQorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21hcF9maWVsZF9saXRlLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tYXBfZmllbGRfbGl0ZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmEwOWNkNTMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tYXBfZmllbGRfbGl0ZS5oCkBAIC0wLDAgKzEsNzggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX01BUF9GSUVMRF9MSVRFX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9NQVBfRklFTERfTElURV9IX18KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZmllbGQuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhIHsKKworY2xhc3MgSW1tdXRhYmxlTWFwRmllbGRMaXRlR2VuZXJhdG9yIDogcHVibGljIEltbXV0YWJsZUZpZWxkTGl0ZUdlbmVyYXRvciB7CisgcHVibGljOgorICBleHBsaWNpdCBJbW11dGFibGVNYXBGaWVsZExpdGVHZW5lcmF0b3IoCisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGludCBtZXNzYWdlQml0SW5kZXgsCisgICAgICBpbnQgYnVpbGRlckJpdEluZGV4LCBDb250ZXh0KiBjb250ZXh0KTsKKyAgfkltbXV0YWJsZU1hcEZpZWxkTGl0ZUdlbmVyYXRvcigpOworCisgIC8vIGltcGxlbWVudHMgSW1tdXRhYmxlRmllbGRMaXRlR2VuZXJhdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICBpbnQgR2V0TnVtQml0c0Zvck1lc3NhZ2UoKSBjb25zdDsKKyAgaW50IEdldE51bUJpdHNGb3JCdWlsZGVyKCkgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVJbnRlcmZhY2VNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnVpbGRlck1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUR5bmFtaWNNZXRob2RNYWtlSW1tdXRhYmxlQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVQYXJzaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVQYXJzaW5nRG9uZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUZpZWxkQnVpbGRlckluaXRpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVFcXVhbHNDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUhhc2hDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKworICBzdHJpbmcgR2V0Qm94ZWRUeXBlKCkgY29uc3Q7CisKKyBwcml2YXRlOgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlc187CisgIENsYXNzTmFtZVJlc29sdmVyKiBuYW1lX3Jlc29sdmVyXzsKK307CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX01BUF9GSUVMRF9MSVRFX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbWVzc2FnZS5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21lc3NhZ2UuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjJhNzBjMwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21lc3NhZ2UuY2MKQEAgLTAsMCArMSwxMzc1IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21lc3NhZ2UuaD4KKworI2luY2x1ZGUgPGFsZ29yaXRobT4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvaGFzaC5oPgorI2luY2x1ZGUgPG1hcD4KKyNpbmNsdWRlIDxtZW1vcnk+CisjaWZuZGVmIF9TSEFSRURfUFRSX0gKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc2hhcmVkX3B0ci5oPgorI2VuZGlmCisjaW5jbHVkZSA8dmVjdG9yPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9jb250ZXh0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9kb2NfY29tbWVudC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZW51bS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZXh0ZW5zaW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9nZW5lcmF0b3JfZmFjdG9yeS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfaGVscGVycy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbWVzc2FnZV9idWlsZGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tZXNzYWdlX2J1aWxkZXJfbGl0ZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbmFtZV9yZXNvbHZlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3Vic3RpdHV0ZS5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmEgeworCit1c2luZyBpbnRlcm5hbDo6V2lyZUZvcm1hdDsKK3VzaW5nIGludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTsKKworbmFtZXNwYWNlIHsKK2Jvb2wgR2VuZXJhdGVIYXNCaXRzKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgcmV0dXJuIFN1cHBvcnRGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3ItPmZpbGUoKSkgfHwKKyAgICAgIEhhc1JlcGVhdGVkRmllbGRzKGRlc2NyaXB0b3IpOworfQorCitzdHJpbmcgTWFwVmFsdWVJbW11dGFibGVDbGFzc2ROYW1lKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzTmFtZVJlc29sdmVyKiBuYW1lX3Jlc29sdmVyKSB7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogdmFsdWVfZmllbGQgPSBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoInZhbHVlIik7CisgIEdPT0dMRV9DSEVDS19FUShGaWVsZERlc2NyaXB0b3I6OlRZUEVfTUVTU0FHRSwgdmFsdWVfZmllbGQtPnR5cGUoKSk7CisgIHJldHVybiBuYW1lX3Jlc29sdmVyLT5HZXRJbW11dGFibGVDbGFzc05hbWUodmFsdWVfZmllbGQtPm1lc3NhZ2VfdHlwZSgpKTsKK30KK30gIC8vIG5hbWVzcGFjZQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK01lc3NhZ2VHZW5lcmF0b3I6Ok1lc3NhZ2VHZW5lcmF0b3IoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcikKKyAgOiBkZXNjcmlwdG9yXyhkZXNjcmlwdG9yKSB7fQorCitNZXNzYWdlR2VuZXJhdG9yOjp+TWVzc2FnZUdlbmVyYXRvcigpIHt9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKy8vIFRPRE8oYXBpKTogTW92ZSB0aGlzIGNsYXNzIHRvIGEgc2VwYXJhdGUgaW1tdXRhYmxlX21lc3NhZ2UuY2MgZmlsZS4KK0ltbXV0YWJsZU1lc3NhZ2VHZW5lcmF0b3I6OkltbXV0YWJsZU1lc3NhZ2VHZW5lcmF0b3IoCisgICAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwgQ29udGV4dCogY29udGV4dCkKKyAgOiBNZXNzYWdlR2VuZXJhdG9yKGRlc2NyaXB0b3IpLCBjb250ZXh0Xyhjb250ZXh0KSwKKyAgICBuYW1lX3Jlc29sdmVyXyhjb250ZXh0LT5HZXROYW1lUmVzb2x2ZXIoKSksCisgICAgZmllbGRfZ2VuZXJhdG9yc18oZGVzY3JpcHRvciwgY29udGV4dF8pIHsKKyAgR09PR0xFX0NIRUNLX05FKAorICAgICAgRmlsZU9wdGlvbnM6OkxJVEVfUlVOVElNRSwgZGVzY3JpcHRvci0+ZmlsZSgpLT5vcHRpb25zKCkub3B0aW1pemVfZm9yKCkpOworfQorCitJbW11dGFibGVNZXNzYWdlR2VuZXJhdG9yOjp+SW1tdXRhYmxlTWVzc2FnZUdlbmVyYXRvcigpIHt9CisKK3ZvaWQgSW1tdXRhYmxlTWVzc2FnZUdlbmVyYXRvcjo6R2VuZXJhdGVTdGF0aWNWYXJpYWJsZXMoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgLy8gQmVjYXVzZSBkZXNjcmlwdG9yLnByb3RvIChjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b3MpIGlzCisgIC8vIHVzZWQgaW4gdGhlIGNvbnN0cnVjdGlvbiBvZiBkZXNjcmlwdG9ycywgd2UgaGF2ZSBhIHRyaWNreSBib290c3RyYXBwaW5nCisgIC8vIHByb2JsZW0uICBUbyBoZWxwIGNvbnRyb2wgc3RhdGljIGluaXRpYWxpemF0aW9uIG9yZGVyLCB3ZSBtYWtlIHN1cmUgYWxsCisgIC8vIGRlc2NyaXB0b3JzIGFuZCBvdGhlciBzdGF0aWMgZGF0YSB0aGF0IGRlcGVuZHMgb24gdGhlbSBhcmUgbWVtYmVycyBvZgorICAvLyB0aGUgb3V0ZXJtb3N0IGNsYXNzIGluIHRoZSBmaWxlLiAgVGhpcyB3YXksIHRoZXkgd2lsbCBiZSBpbml0aWFsaXplZCBpbgorICAvLyBhIGRldGVybWluaXN0aWMgb3JkZXIuCisKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJzOworICB2YXJzWyJpZGVudGlmaWVyIl0gPSBVbmlxdWVGaWxlU2NvcGVJZGVudGlmaWVyKGRlc2NyaXB0b3JfKTsKKyAgdmFyc1siaW5kZXgiXSA9IFNpbXBsZUl0b2EoZGVzY3JpcHRvcl8tPmluZGV4KCkpOworICB2YXJzWyJjbGFzc25hbWUiXSA9IG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcl8pOworICBpZiAoZGVzY3JpcHRvcl8tPmNvbnRhaW5pbmdfdHlwZSgpICE9IE5VTEwpIHsKKyAgICB2YXJzWyJwYXJlbnQiXSA9IFVuaXF1ZUZpbGVTY29wZUlkZW50aWZpZXIoCisgICAgICAgIGRlc2NyaXB0b3JfLT5jb250YWluaW5nX3R5cGUoKSk7CisgIH0KKyAgaWYgKE11bHRpcGxlSmF2YUZpbGVzKGRlc2NyaXB0b3JfLT5maWxlKCksIC8qIGltbXV0YWJsZSA9ICovIHRydWUpKSB7CisgICAgLy8gV2UgY2FuIG9ubHkgbWFrZSB0aGVzZSBwYWNrYWdlLXByaXZhdGUgc2luY2UgdGhlIGNsYXNzZXMgdGhhdCB1c2UgdGhlbQorICAgIC8vIGFyZSBpbiBzZXBhcmF0ZSBmaWxlcy4KKyAgICB2YXJzWyJwcml2YXRlIl0gPSAiIjsKKyAgfSBlbHNlIHsKKyAgICB2YXJzWyJwcml2YXRlIl0gPSAicHJpdmF0ZSAiOworICB9CisKKyAgLy8gVGhlIGRlc2NyaXB0b3IgZm9yIHRoaXMgdHlwZS4KKyAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAvLyBUT0RPKHRlYm9yaW5nKTogZmluYWwgbmVlZHMgdG8gYmUgYWRkZWQgYmFjay4gVGhlIHdheSB0byBmaXggaXQgaXMgdG8KKyAgICAvLyBnZW5lcmF0ZSBtZXRob2RzIHRoYXQgY2FuIGNvbnN0cnVjdCB0aGUgdHlwZXMsIGFuZCB0aGVuIHN0aWxsIGRlY2xhcmUgdGhlCisgICAgLy8gdHlwZXMsIGFuZCB0aGVuIGluaXQgdGhlbSBpbiBjbGluaXQgd2l0aCB0aGUgbmV3IG1ldGhvZCBjYWxscy4KKyAgICAiJHByaXZhdGUkc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvclxuIgorICAgICIgIGludGVybmFsXyRpZGVudGlmaWVyJF9kZXNjcmlwdG9yO1xuIik7CisKKyAgLy8gQW5kIHRoZSBGaWVsZEFjY2Vzc29yVGFibGUuCisgIEdlbmVyYXRlRmllbGRBY2Nlc3NvclRhYmxlKHByaW50ZXIpOworCisgIC8vIEdlbmVyYXRlIHN0YXRpYyBtZW1iZXJzIGZvciBhbGwgbmVzdGVkIHR5cGVzLgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5uZXN0ZWRfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICAvLyBUT0RPKGtlbnRvbik6ICBSZXVzZSBNZXNzYWdlR2VuZXJhdG9yIG9iamVjdHM/CisgICAgSW1tdXRhYmxlTWVzc2FnZUdlbmVyYXRvcihkZXNjcmlwdG9yXy0+bmVzdGVkX3R5cGUoaSksIGNvbnRleHRfKQorICAgICAgLkdlbmVyYXRlU3RhdGljVmFyaWFibGVzKHByaW50ZXIpOworICB9Cit9CisKK2ludCBJbW11dGFibGVNZXNzYWdlR2VuZXJhdG9yOjpHZW5lcmF0ZVN0YXRpY1ZhcmlhYmxlSW5pdGlhbGl6ZXJzKAorICAgIGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIGludCBieXRlY29kZV9lc3RpbWF0ZSA9IDA7CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyczsKKyAgdmFyc1siaWRlbnRpZmllciJdID0gVW5pcXVlRmlsZVNjb3BlSWRlbnRpZmllcihkZXNjcmlwdG9yXyk7CisgIHZhcnNbImluZGV4Il0gPSBTaW1wbGVJdG9hKGRlc2NyaXB0b3JfLT5pbmRleCgpKTsKKyAgdmFyc1siY2xhc3NuYW1lIl0gPSBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3JfKTsKKyAgaWYgKGRlc2NyaXB0b3JfLT5jb250YWluaW5nX3R5cGUoKSAhPSBOVUxMKSB7CisgICAgdmFyc1sicGFyZW50Il0gPSBVbmlxdWVGaWxlU2NvcGVJZGVudGlmaWVyKAorICAgICAgICBkZXNjcmlwdG9yXy0+Y29udGFpbmluZ190eXBlKCkpOworICB9CisKKyAgLy8gVGhlIGRlc2NyaXB0b3IgZm9yIHRoaXMgdHlwZS4KKyAgaWYgKGRlc2NyaXB0b3JfLT5jb250YWluaW5nX3R5cGUoKSA9PSBOVUxMKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICJpbnRlcm5hbF8kaWRlbnRpZmllciRfZGVzY3JpcHRvciA9XG4iCisgICAgICAiICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KCRpbmRleCQpO1xuIik7CisgICAgYnl0ZWNvZGVfZXN0aW1hdGUgKz0gMzA7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICJpbnRlcm5hbF8kaWRlbnRpZmllciRfZGVzY3JpcHRvciA9XG4iCisgICAgICAiICBpbnRlcm5hbF8kcGFyZW50JF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KCRpbmRleCQpO1xuIik7CisgICAgYnl0ZWNvZGVfZXN0aW1hdGUgKz0gMzA7CisgIH0KKworICAvLyBBbmQgdGhlIEZpZWxkQWNjZXNzb3JUYWJsZS4KKyAgYnl0ZWNvZGVfZXN0aW1hdGUgKz0gR2VuZXJhdGVGaWVsZEFjY2Vzc29yVGFibGVJbml0aWFsaXplcihwcmludGVyKTsKKworICAvLyBHZW5lcmF0ZSBzdGF0aWMgbWVtYmVyIGluaXRpYWxpemVycyBmb3IgYWxsIG5lc3RlZCB0eXBlcy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+bmVzdGVkX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgLy8gVE9ETyhrZW50b24pOiAgUmV1c2UgTWVzc2FnZUdlbmVyYXRvciBvYmplY3RzPworICAgIGJ5dGVjb2RlX2VzdGltYXRlICs9CisgICAgICAgIEltbXV0YWJsZU1lc3NhZ2VHZW5lcmF0b3IoZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlKGkpLCBjb250ZXh0XykKKyAgICAgICAgICAgIC5HZW5lcmF0ZVN0YXRpY1ZhcmlhYmxlSW5pdGlhbGl6ZXJzKHByaW50ZXIpOworICB9CisgIHJldHVybiBieXRlY29kZV9lc3RpbWF0ZTsKK30KKwordm9pZCBJbW11dGFibGVNZXNzYWdlR2VuZXJhdG9yOjoKK0dlbmVyYXRlRmllbGRBY2Nlc3NvclRhYmxlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyczsKKyAgdmFyc1siaWRlbnRpZmllciJdID0gVW5pcXVlRmlsZVNjb3BlSWRlbnRpZmllcihkZXNjcmlwdG9yXyk7CisgIGlmIChNdWx0aXBsZUphdmFGaWxlcyhkZXNjcmlwdG9yXy0+ZmlsZSgpLCAvKiBpbW11dGFibGUgPSAqLyB0cnVlKSkgeworICAgIC8vIFdlIGNhbiBvbmx5IG1ha2UgdGhlc2UgcGFja2FnZS1wcml2YXRlIHNpbmNlIHRoZSBjbGFzc2VzIHRoYXQgdXNlIHRoZW0KKyAgICAvLyBhcmUgaW4gc2VwYXJhdGUgZmlsZXMuCisgICAgdmFyc1sicHJpdmF0ZSJdID0gIiI7CisgIH0gZWxzZSB7CisgICAgdmFyc1sicHJpdmF0ZSJdID0gInByaXZhdGUgIjsKKyAgfQorICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICIkcHJpdmF0ZSRzdGF0aWNcbiIKKyAgICAiICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuRmllbGRBY2Nlc3NvclRhYmxlXG4iCisgICAgIiAgICBpbnRlcm5hbF8kaWRlbnRpZmllciRfZmllbGRBY2Nlc3NvclRhYmxlO1xuIik7Cit9CisKK2ludCBJbW11dGFibGVNZXNzYWdlR2VuZXJhdG9yOjoKK0dlbmVyYXRlRmllbGRBY2Nlc3NvclRhYmxlSW5pdGlhbGl6ZXIoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgaW50IGJ5dGVjb2RlX2VzdGltYXRlID0gMTA7CisgIHByaW50ZXItPlByaW50KAorICAgICJpbnRlcm5hbF8kaWRlbnRpZmllciRfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3XG4iCisgICAgIiAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkZpZWxkQWNjZXNzb3JUYWJsZShcbiIKKyAgICAiICAgIGludGVybmFsXyRpZGVudGlmaWVyJF9kZXNjcmlwdG9yLFxuIgorICAgICIgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICIsCisgICAgImlkZW50aWZpZXIiLAorICAgIFVuaXF1ZUZpbGVTY29wZUlkZW50aWZpZXIoZGVzY3JpcHRvcl8pKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3JfLT5maWVsZChpKTsKKyAgICBjb25zdCBGaWVsZEdlbmVyYXRvckluZm8qIGluZm8gPSBjb250ZXh0Xy0+R2V0RmllbGRHZW5lcmF0b3JJbmZvKGZpZWxkKTsKKyAgICBieXRlY29kZV9lc3RpbWF0ZSArPSA2OworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIlwiJGZpZWxkX25hbWUkXCIsICIsCisgICAgICAiZmllbGRfbmFtZSIsIGluZm8tPmNhcGl0YWxpemVkX25hbWUpOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2xfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBvbmVvZiA9IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpOworICAgIGNvbnN0IE9uZW9mR2VuZXJhdG9ySW5mbyogaW5mbyA9IGNvbnRleHRfLT5HZXRPbmVvZkdlbmVyYXRvckluZm8ob25lb2YpOworICAgIGJ5dGVjb2RlX2VzdGltYXRlICs9IDY7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiXCIkb25lb2ZfbmFtZSRcIiwgIiwKKyAgICAgICJvbmVvZl9uYW1lIiwgaW5mby0+Y2FwaXRhbGl6ZWRfbmFtZSk7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQoIn0pO1xuIik7CisgIHJldHVybiBieXRlY29kZV9lc3RpbWF0ZTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCit2b2lkIEltbXV0YWJsZU1lc3NhZ2VHZW5lcmF0b3I6OkdlbmVyYXRlSW50ZXJmYWNlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIGlmIChkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCkgPiAwKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAicHVibGljIGludGVyZmFjZSAkY2xhc3NuYW1lJE9yQnVpbGRlciBleHRlbmRzXG4iCisgICAgICAiICAgICRleHRyYV9pbnRlcmZhY2VzJFxuIgorICAgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuXG4iCisgICAgICAiICAgICAgICBFeHRlbmRhYmxlTWVzc2FnZU9yQnVpbGRlcjwkY2xhc3NuYW1lJD4ge1xuIiwKKyAgICAgICJleHRyYV9pbnRlcmZhY2VzIiwgRXh0cmFNZXNzYWdlT3JCdWlsZGVySW50ZXJmYWNlcyhkZXNjcmlwdG9yXyksCisgICAgICAiY2xhc3NuYW1lIiwgZGVzY3JpcHRvcl8tPm5hbWUoKSk7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAicHVibGljIGludGVyZmFjZSAkY2xhc3NuYW1lJE9yQnVpbGRlciBleHRlbmRzXG4iCisgICAgICAiICAgICRleHRyYV9pbnRlcmZhY2VzJFxuIgorICAgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIge1xuIiwKKyAgICAgICJleHRyYV9pbnRlcmZhY2VzIiwgRXh0cmFNZXNzYWdlT3JCdWlsZGVySW50ZXJmYWNlcyhkZXNjcmlwdG9yXyksCisgICAgICAiY2xhc3NuYW1lIiwgZGVzY3JpcHRvcl8tPm5hbWUoKSk7CisgIH0KKworICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICAgIHByaW50ZXItPlByaW50KCJcbiIpOworICAgICAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGRlc2NyaXB0b3JfLT5maWVsZChpKSkKKyAgICAgICAgICAgICAgICAgICAgICAgLkdlbmVyYXRlSW50ZXJmYWNlTWVtYmVycyhwcmludGVyKTsKKyAgICB9CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbF9jb3VudCgpOyBpKyspIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICJcbiIKKyAgICAgICAgICAicHVibGljICRjbGFzc25hbWUkLiRvbmVvZl9jYXBpdGFsaXplZF9uYW1lJENhc2UgIgorICAgICAgICAgICJnZXQkb25lb2ZfY2FwaXRhbGl6ZWRfbmFtZSRDYXNlKCk7XG4iLAorICAgICAgICAgICJvbmVvZl9jYXBpdGFsaXplZF9uYW1lIiwKKyAgICAgICAgICBjb250ZXh0Xy0+R2V0T25lb2ZHZW5lcmF0b3JJbmZvKAorICAgICAgICAgICAgICBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKSktPmNhcGl0YWxpemVkX25hbWUsCisgICAgICAgICAgImNsYXNzbmFtZSIsCisgICAgICAgICAgY29udGV4dF8tPkdldE5hbWVSZXNvbHZlcigpLT5HZXRJbW11dGFibGVDbGFzc05hbWUoCisgICAgICAgICAgICAgIGRlc2NyaXB0b3JfKSk7CisgICAgfQorICBwcmludGVyLT5PdXRkZW50KCk7CisKKyAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK3ZvaWQgSW1tdXRhYmxlTWVzc2FnZUdlbmVyYXRvcjo6R2VuZXJhdGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgYm9vbCBpc19vd25fZmlsZSA9CisgICAgZGVzY3JpcHRvcl8tPmNvbnRhaW5pbmdfdHlwZSgpID09IE5VTEwgJiYKKyAgICBNdWx0aXBsZUphdmFGaWxlcyhkZXNjcmlwdG9yXy0+ZmlsZSgpLCAvKiBpbW11dGFibGUgPSAqLyB0cnVlKTsKKworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlczsKKyAgdmFyaWFibGVzWyJzdGF0aWMiXSA9IGlzX293bl9maWxlID8gIiAiIDogIiBzdGF0aWMgIjsKKyAgdmFyaWFibGVzWyJjbGFzc25hbWUiXSA9IGRlc2NyaXB0b3JfLT5uYW1lKCk7CisgIHZhcmlhYmxlc1siZXh0cmFfaW50ZXJmYWNlcyJdID0gRXh0cmFNZXNzYWdlSW50ZXJmYWNlcyhkZXNjcmlwdG9yXyk7CisKKyAgV3JpdGVNZXNzYWdlRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisKKyAgLy8gVGhlIGJ1aWxkZXJfdHlwZSBzdG9yZXMgdGhlIHN1cGVyIHR5cGUgbmFtZSBvZiB0aGUgbmVzdGVkIEJ1aWxkZXIgY2xhc3MuCisgIHN0cmluZyBidWlsZGVyX3R5cGU7CisgIGlmIChkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCkgPiAwKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICAgInB1YmxpYyAkc3RhdGljJGZpbmFsIGNsYXNzICRjbGFzc25hbWUkIGV4dGVuZHNcbiIKKyAgICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkV4dGVuZGFibGVNZXNzYWdlPFxuIgorICAgICAgIiAgICAgICRjbGFzc25hbWUkPiBpbXBsZW1lbnRzXG4iCisgICAgICAiICAgICRleHRyYV9pbnRlcmZhY2VzJFxuIgorICAgICAgIiAgICAkY2xhc3NuYW1lJE9yQnVpbGRlciB7XG4iKTsKKyAgICBidWlsZGVyX3R5cGUgPSBzdHJpbmdzOjpTdWJzdGl0dXRlKAorICAgICAgICAgICAgICJjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuRXh0ZW5kYWJsZUJ1aWxkZXI8JDAsID8+IiwKKyAgICAgICAgICAgICBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3JfKSk7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICAgInB1YmxpYyAkc3RhdGljJGZpbmFsIGNsYXNzICRjbGFzc25hbWUkIGV4dGVuZHNcbiIKKyAgICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlIGltcGxlbWVudHNcbiIKKyAgICAgICIgICAgJGV4dHJhX2ludGVyZmFjZXMkXG4iCisgICAgICAiICAgICRjbGFzc25hbWUkT3JCdWlsZGVyIHtcbiIpOworICAgIGJ1aWxkZXJfdHlwZSA9ICJjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuQnVpbGRlcjw/PiI7CisgIH0KKyAgcHJpbnRlci0+SW5kZW50KCk7CisgIC8vIFVzaW5nIGJ1aWxkZXJfdHlwZSwgaW5zdGVhZCBvZiBCdWlsZGVyLCBwcmV2ZW50cyB0aGUgQnVpbGRlciBjbGFzcyBmcm9tCisgIC8vIGJlaW5nIGxvYWRlZCBpbnRvIFBlcm1HZW4gc3BhY2Ugd2hlbiB0aGUgZGVmYXVsdCBpbnN0YW5jZSBpcyBjcmVhdGVkLgorICAvLyBUaGlzIG9wdGltaXplcyB0aGUgUGVybUdlbiBzcGFjZSB1c2FnZSBmb3IgY2xpZW50cyB0aGF0IGRvIG5vdCBtb2RpZnkKKyAgLy8gbWVzc2FnZXMuCisgIHByaW50ZXItPlByaW50KAorICAgICIvLyBVc2UgJGNsYXNzbmFtZSQubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC5cbiIKKyAgICAicHJpdmF0ZSAkY2xhc3NuYW1lJCgkYnVpbGRlcnR5cGUkIGJ1aWxkZXIpIHtcbiIKKyAgICAiICBzdXBlcihidWlsZGVyKTtcbiIKKyAgICAifVxuIiwKKyAgICAiY2xhc3NuYW1lIiwgZGVzY3JpcHRvcl8tPm5hbWUoKSwKKyAgICAiYnVpbGRlcnR5cGUiLCBidWlsZGVyX3R5cGUpOworICBwcmludGVyLT5QcmludCgKKyAgICAicHJpdmF0ZSAkY2xhc3NuYW1lJCgpIHtcbiIsCisgICAgImNsYXNzbmFtZSIsIGRlc2NyaXB0b3JfLT5uYW1lKCkpOworICBwcmludGVyLT5JbmRlbnQoKTsKKyAgR2VuZXJhdGVJbml0aWFsaXplcnMocHJpbnRlcik7CisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIn1cbiIKKyAgICAiXG4iKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAiQGphdmEubGFuZy5PdmVycmlkZVxuIgorICAgICJwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXRcbiIKKyAgICAiZ2V0VW5rbm93bkZpZWxkcygpIHtcbiIpOworICBpZiAoUHJlc2VydmVVbmtub3duRmllbGRzKGRlc2NyaXB0b3JfKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIiAgcmV0dXJuIHRoaXMudW5rbm93bkZpZWxkcztcbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIiAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0LmdldERlZmF1bHRJbnN0YW5jZSgpO1xuIik7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIn1cbiIpOworCisgIGlmIChIYXNHZW5lcmF0ZWRNZXRob2RzKGRlc2NyaXB0b3JfKSkgeworICAgIEdlbmVyYXRlUGFyc2luZ0NvbnN0cnVjdG9yKHByaW50ZXIpOworICB9CisKKyAgR2VuZXJhdGVEZXNjcmlwdG9yTWV0aG9kcyhwcmludGVyKTsKKworICAvLyBOZXN0ZWQgdHlwZXMKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZW51bV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIEVudW1HZW5lcmF0b3IoZGVzY3JpcHRvcl8tPmVudW1fdHlwZShpKSwgdHJ1ZSwgY29udGV4dF8pCisgICAgICAgIC5HZW5lcmF0ZShwcmludGVyKTsKKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlX2NvdW50KCk7IGkrKykgeworICAgIC8vIERvbid0IGdlbmVyYXRlIEphdmEgY2xhc3NlcyBmb3IgbWFwIGVudHJ5IG1lc3NhZ2VzLgorICAgIGlmIChJc01hcEVudHJ5KGRlc2NyaXB0b3JfLT5uZXN0ZWRfdHlwZShpKSkpIGNvbnRpbnVlOworICAgIEltbXV0YWJsZU1lc3NhZ2VHZW5lcmF0b3IgbWVzc2FnZUdlbmVyYXRvcigKKyAgICAgICAgZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlKGkpLCBjb250ZXh0Xyk7CisgICAgbWVzc2FnZUdlbmVyYXRvci5HZW5lcmF0ZUludGVyZmFjZShwcmludGVyKTsKKyAgICBtZXNzYWdlR2VuZXJhdG9yLkdlbmVyYXRlKHByaW50ZXIpOworICB9CisKKyAgaWYgKEdlbmVyYXRlSGFzQml0cyhkZXNjcmlwdG9yXykpIHsKKyAgICAvLyBJbnRlZ2VycyBmb3IgYml0IGZpZWxkcy4KKyAgICBpbnQgdG90YWxCaXRzID0gMDsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICAgIHRvdGFsQml0cyArPSBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZGVzY3JpcHRvcl8tPmZpZWxkKGkpKQorICAgICAgICAgIC5HZXROdW1CaXRzRm9yTWVzc2FnZSgpOworICAgIH0KKyAgICBpbnQgdG90YWxJbnRzID0gKHRvdGFsQml0cyArIDMxKSAvIDMyOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdG90YWxJbnRzOyBpKyspIHsKKyAgICAgIHByaW50ZXItPlByaW50KCJwcml2YXRlIGludCAkYml0X2ZpZWxkX25hbWUkO1xuIiwKKyAgICAgICAgImJpdF9maWVsZF9uYW1lIiwgR2V0Qml0RmllbGROYW1lKGkpKTsKKyAgICB9CisgIH0KKworICAvLyBvbmVvZgorICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcnM7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2xfY291bnQoKTsgaSsrKSB7CisgICAgdmFyc1sib25lb2ZfbmFtZSJdID0gY29udGV4dF8tPkdldE9uZW9mR2VuZXJhdG9ySW5mbygKKyAgICAgICAgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSkpLT5uYW1lOworICAgIHZhcnNbIm9uZW9mX2NhcGl0YWxpemVkX25hbWUiXSA9IGNvbnRleHRfLT5HZXRPbmVvZkdlbmVyYXRvckluZm8oCisgICAgICAgIGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpKS0+Y2FwaXRhbGl6ZWRfbmFtZTsKKyAgICB2YXJzWyJvbmVvZl9pbmRleCJdID0gU2ltcGxlSXRvYShkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKS0+aW5kZXgoKSk7CisgICAgLy8gb25lb2ZDYXNlXyBhbmQgb25lb2ZfCisgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICJwcml2YXRlIGludCAkb25lb2ZfbmFtZSRDYXNlXyA9IDA7XG4iCisgICAgICAicHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0ICRvbmVvZl9uYW1lJF87XG4iKTsKKyAgICAvLyBPbmVvZkNhc2UgZW51bQorICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAicHVibGljIGVudW0gJG9uZW9mX2NhcGl0YWxpemVkX25hbWUkQ2FzZVxuIgorICAgICAgIiAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGUge1xuIik7CisgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgZm9yIChpbnQgaiA9IDA7IGogPCBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKS0+ZmllbGRfY291bnQoKTsgaisrKSB7CisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPmZpZWxkKGopOworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICIkZmllbGRfbmFtZSQoJGZpZWxkX251bWJlciQpLFxuIiwKKyAgICAgICAgImZpZWxkX25hbWUiLAorICAgICAgICBUb1VwcGVyKGZpZWxkLT5uYW1lKCkpLAorICAgICAgICAiZmllbGRfbnVtYmVyIiwKKyAgICAgICAgU2ltcGxlSXRvYShmaWVsZC0+bnVtYmVyKCkpKTsKKyAgICB9CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiJGNhcF9vbmVvZl9uYW1lJF9OT1RfU0VUKDApO1xuIiwKKyAgICAgICJjYXBfb25lb2ZfbmFtZSIsCisgICAgICBUb1VwcGVyKHZhcnNbIm9uZW9mX25hbWUiXSkpOworICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAicHJpdmF0ZSBpbnQgdmFsdWUgPSAwO1xuIgorICAgICAgInByaXZhdGUgJG9uZW9mX2NhcGl0YWxpemVkX25hbWUkQ2FzZShpbnQgdmFsdWUpIHtcbiIKKyAgICAgICIgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgInB1YmxpYyBzdGF0aWMgJG9uZW9mX2NhcGl0YWxpemVkX25hbWUkQ2FzZSB2YWx1ZU9mKGludCB2YWx1ZSkge1xuIgorICAgICAgIiAgc3dpdGNoICh2YWx1ZSkge1xuIik7CisgICAgZm9yIChpbnQgaiA9IDA7IGogPCBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKS0+ZmllbGRfY291bnQoKTsgaisrKSB7CisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPmZpZWxkKGopOworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICIgICAgY2FzZSAkZmllbGRfbnVtYmVyJDogcmV0dXJuICRmaWVsZF9uYW1lJDtcbiIsCisgICAgICAgICJmaWVsZF9udW1iZXIiLAorICAgICAgICBTaW1wbGVJdG9hKGZpZWxkLT5udW1iZXIoKSksCisgICAgICAgICJmaWVsZF9uYW1lIiwKKyAgICAgICAgVG9VcHBlcihmaWVsZC0+bmFtZSgpKSk7CisgICAgfQorICAgIHByaW50ZXItPlByaW50KAorICAgICAgIiAgICBjYXNlIDA6IHJldHVybiAkY2FwX29uZW9mX25hbWUkX05PVF9TRVQ7XG4iCisgICAgICAiICAgIGRlZmF1bHQ6IHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKFxuIgorICAgICAgIiAgICAgIFwiVmFsdWUgaXMgdW5kZWZpbmVkIGZvciB0aGlzIG9uZW9mIGVudW0uXCIpO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIn1cbiIKKyAgICAgICJwdWJsaWMgaW50IGdldE51bWJlcigpIHtcbiIKKyAgICAgICIgIHJldHVybiB0aGlzLnZhbHVlO1xuIgorICAgICAgIn1cbiIsCisgICAgICAiY2FwX29uZW9mX25hbWUiLCBUb1VwcGVyKHZhcnNbIm9uZW9mX25hbWUiXSkpOworICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICBwcmludGVyLT5QcmludCgifTtcblxuIik7CisgICAgLy8gb25lb2ZDYXNlKCkKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgInB1YmxpYyAkb25lb2ZfY2FwaXRhbGl6ZWRfbmFtZSRDYXNlXG4iCisgICAgICAiZ2V0JG9uZW9mX2NhcGl0YWxpemVkX25hbWUkQ2FzZSgpIHtcbiIKKyAgICAgICIgIHJldHVybiAkb25lb2ZfY2FwaXRhbGl6ZWRfbmFtZSRDYXNlLnZhbHVlT2YoXG4iCisgICAgICAiICAgICAgJG9uZW9mX25hbWUkQ2FzZV8pO1xuIgorICAgICAgIn1cbiIKKyAgICAgICJcbiIpOworICB9CisKKyAgaWYgKElzQW55TWVzc2FnZShkZXNjcmlwdG9yXykpIHsKKyAgICBHZW5lcmF0ZUFueU1ldGhvZHMocHJpbnRlcik7CisgIH0KKworICAvLyBGaWVsZHMKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgcHJpbnRlci0+UHJpbnQoInB1YmxpYyBzdGF0aWMgZmluYWwgaW50ICRjb25zdGFudF9uYW1lJCA9ICRudW1iZXIkO1xuIiwKKyAgICAgICJjb25zdGFudF9uYW1lIiwgRmllbGRDb25zdGFudE5hbWUoZGVzY3JpcHRvcl8tPmZpZWxkKGkpKSwKKyAgICAgICJudW1iZXIiLCBTaW1wbGVJdG9hKGRlc2NyaXB0b3JfLT5maWVsZChpKS0+bnVtYmVyKCkpKTsKKyAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZGVzY3JpcHRvcl8tPmZpZWxkKGkpKS5HZW5lcmF0ZU1lbWJlcnMocHJpbnRlcik7CisgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisgIH0KKworICBpZiAoSGFzR2VuZXJhdGVkTWV0aG9kcyhkZXNjcmlwdG9yXykpIHsKKyAgICBHZW5lcmF0ZUlzSW5pdGlhbGl6ZWQocHJpbnRlcik7CisgICAgR2VuZXJhdGVNZXNzYWdlU2VyaWFsaXphdGlvbk1ldGhvZHMocHJpbnRlcik7CisgIH0KKworICBpZiAoSGFzRXF1YWxzQW5kSGFzaENvZGUoZGVzY3JpcHRvcl8pKSB7CisgICAgR2VuZXJhdGVFcXVhbHNBbmRIYXNoQ29kZShwcmludGVyKTsKKyAgfQorCisKKyAgR2VuZXJhdGVQYXJzZUZyb21NZXRob2RzKHByaW50ZXIpOworICBHZW5lcmF0ZUJ1aWxkZXIocHJpbnRlcik7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIlxuIgorICAgICIvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6JGZ1bGxfbmFtZSQpXG4iLAorICAgICJmdWxsX25hbWUiLCBkZXNjcmlwdG9yXy0+ZnVsbF9uYW1lKCkpOworCisKKyAgLy8gQ2FyZWZ1bGx5IGluaXRpYWxpemUgdGhlIGRlZmF1bHQgaW5zdGFuY2UgaW4gc3VjaCBhIHdheSB0aGF0IGl0IGRvZXNuJ3QKKyAgLy8gY29uZmxpY3Qgd2l0aCBvdGhlciBpbml0aWFsaXphdGlvbi4KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgInByaXZhdGUgc3RhdGljIGZpbmFsICRjbGFzc25hbWUkIERFRkFVTFRfSU5TVEFOQ0U7XG4iLAorICAgICJjbGFzc25hbWUiLCBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3JfKSk7CisgIHByaW50ZXItPlByaW50KAorICAgICJzdGF0aWMge1xuIgorICAgICIgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgJGNsYXNzbmFtZSQoKTtcbiIKKyAgICAifVxuIgorICAgICJcbiIsCisgICAgImNsYXNzbmFtZSIsIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcl8pKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAgICJwdWJsaWMgc3RhdGljICRjbGFzc25hbWUkIGdldERlZmF1bHRJbnN0YW5jZSgpIHtcbiIKKyAgICAgICIgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFO1xuIgorICAgICAgIn1cbiIKKyAgICAgICJcbiIsCisgICAgICAiY2xhc3NuYW1lIiwgbmFtZV9yZXNvbHZlcl8tPkdldEltbXV0YWJsZUNsYXNzTmFtZShkZXNjcmlwdG9yXykpOworCisgIEdlbmVyYXRlUGFyc2VyKHByaW50ZXIpOworCisgIHByaW50ZXItPlByaW50KAorICAgICJwdWJsaWMgJGNsYXNzbmFtZSQgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHtcbiIKKyAgICAiICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTtcbiIKKyAgICAifVxuIgorICAgICJcbiIsCisgICAgImNsYXNzbmFtZSIsIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcl8pKTsKKworICAvLyBFeHRlbnNpb25zIG11c3QgYmUgZGVjbGFyZWQgYWZ0ZXIgdGhlIERFRkFVTFRfSU5TVEFOQ0UgaXMgaW5pdGlhbGl6ZWQKKyAgLy8gYmVjYXVzZSB0aGUgREVGQVVMVF9JTlNUQU5DRSBpcyB1c2VkIGJ5IHRoZSBleHRlbnNpb24gdG8gbGF6aWx5IHJldHJpZXZlCisgIC8vIHRoZSBvdXRlciBjbGFzcydzIEZpbGVEZXNjcmlwdG9yLgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5leHRlbnNpb25fY291bnQoKTsgaSsrKSB7CisgICAgSW1tdXRhYmxlRXh0ZW5zaW9uR2VuZXJhdG9yKGRlc2NyaXB0b3JfLT5leHRlbnNpb24oaSksIGNvbnRleHRfKQorICAgICAgICAuR2VuZXJhdGUocHJpbnRlcik7CisgIH0KKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KCJ9XG5cbiIpOworfQorCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKwordm9pZCBJbW11dGFibGVNZXNzYWdlR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVzc2FnZVNlcmlhbGl6YXRpb25NZXRob2RzKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9hcnJheTxjb25zdCBGaWVsZERlc2NyaXB0b3IgKiA+IHNvcnRlZF9maWVsZHMoCisgICAgICBTb3J0RmllbGRzQnlOdW1iZXIoZGVzY3JpcHRvcl8pKTsKKworICB2ZWN0b3I8Y29uc3QgRGVzY3JpcHRvcjo6RXh0ZW5zaW9uUmFuZ2UqPiBzb3J0ZWRfZXh0ZW5zaW9uczsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCk7ICsraSkgeworICAgIHNvcnRlZF9leHRlbnNpb25zLnB1c2hfYmFjayhkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX3JhbmdlKGkpKTsKKyAgfQorICBzdGQ6OnNvcnQoc29ydGVkX2V4dGVuc2lvbnMuYmVnaW4oKSwgc29ydGVkX2V4dGVuc2lvbnMuZW5kKCksCisgICAgICAgICAgICBFeHRlbnNpb25SYW5nZU9yZGVyaW5nKCkpOworCisgIHByaW50ZXItPlByaW50KAorICAgICJwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KVxuIgorICAgICIgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHtcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKyAgaWYgKEhhc1BhY2tlZEZpZWxkcyhkZXNjcmlwdG9yXykpIHsKKyAgICAvLyB3cml0ZVRvKENvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkgbWlnaHQgYmUgaW52b2tlZCB3aXRob3V0CisgICAgLy8gZ2V0U2VyaWFsaXplZFNpemUoKSBldmVyIGJlaW5nIGNhbGxlZCwgYnV0IHdlIG5lZWQgdGhlIG1lbW9pemVkCisgICAgLy8gc2l6ZXMgaW4gY2FzZSB0aGlzIG1lc3NhZ2UgaGFzIHBhY2tlZCBmaWVsZHMuIFJhdGhlciB0aGFuIGVtaXQgY2hlY2tzIGZvcgorICAgIC8vIGVhY2ggcGFja2VkIGZpZWxkLCBqdXN0IGNhbGwgZ2V0U2VyaWFsaXplZFNpemUoKSB1cCBmcm9udC4KKyAgICAvLyBJbiBtb3N0IGNhc2VzLCBnZXRTZXJpYWxpemVkU2l6ZSgpIHdpbGwgaGF2ZSBhbHJlYWR5IGJlZW4gY2FsbGVkIGFueXdheQorICAgIC8vIGJ5IG9uZSBvZiB0aGUgd3JhcHBlciB3cml0ZVRvKCkgbWV0aG9kcywgbWFraW5nIHRoaXMgY2FsbCBjaGVhcC4KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJnZXRTZXJpYWxpemVkU2l6ZSgpO1xuIik7CisgIH0KKworICBpZiAoZGVzY3JpcHRvcl8tPmV4dGVuc2lvbl9yYW5nZV9jb3VudCgpID4gMCkgeworICAgIGlmIChkZXNjcmlwdG9yXy0+b3B0aW9ucygpLm1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KCkpIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlXG4iCisgICAgICAgICIgIC5FeHRlbmRhYmxlTWVzc2FnZTwkY2xhc3NuYW1lJD4uRXh0ZW5zaW9uV3JpdGVyXG4iCisgICAgICAgICIgICAgZXh0ZW5zaW9uV3JpdGVyID0gbmV3TWVzc2FnZVNldEV4dGVuc2lvbldyaXRlcigpO1xuIiwKKyAgICAgICAgImNsYXNzbmFtZSIsIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcl8pKTsKKyAgICB9IGVsc2UgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VcbiIKKyAgICAgICAgIiAgLkV4dGVuZGFibGVNZXNzYWdlPCRjbGFzc25hbWUkPi5FeHRlbnNpb25Xcml0ZXJcbiIKKyAgICAgICAgIiAgICBleHRlbnNpb25Xcml0ZXIgPSBuZXdFeHRlbnNpb25Xcml0ZXIoKTtcbiIsCisgICAgICAgICJjbGFzc25hbWUiLCBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3JfKSk7CisgICAgfQorICB9CisKKyAgLy8gTWVyZ2UgdGhlIGZpZWxkcyBhbmQgdGhlIGV4dGVuc2lvbiByYW5nZXMsIGJvdGggc29ydGVkIGJ5IGZpZWxkIG51bWJlci4KKyAgZm9yIChpbnQgaSA9IDAsIGogPSAwOworICAgICAgIGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKSB8fCBqIDwgc29ydGVkX2V4dGVuc2lvbnMuc2l6ZSgpOworICAgICAgICkgeworICAgIGlmIChpID09IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpKSB7CisgICAgICBHZW5lcmF0ZVNlcmlhbGl6ZU9uZUV4dGVuc2lvblJhbmdlKHByaW50ZXIsIHNvcnRlZF9leHRlbnNpb25zW2orK10pOworICAgIH0gZWxzZSBpZiAoaiA9PSBzb3J0ZWRfZXh0ZW5zaW9ucy5zaXplKCkpIHsKKyAgICAgIEdlbmVyYXRlU2VyaWFsaXplT25lRmllbGQocHJpbnRlciwgc29ydGVkX2ZpZWxkc1tpKytdKTsKKyAgICB9IGVsc2UgaWYgKHNvcnRlZF9maWVsZHNbaV0tPm51bWJlcigpIDwgc29ydGVkX2V4dGVuc2lvbnNbal0tPnN0YXJ0KSB7CisgICAgICBHZW5lcmF0ZVNlcmlhbGl6ZU9uZUZpZWxkKHByaW50ZXIsIHNvcnRlZF9maWVsZHNbaSsrXSk7CisgICAgfSBlbHNlIHsKKyAgICAgIEdlbmVyYXRlU2VyaWFsaXplT25lRXh0ZW5zaW9uUmFuZ2UocHJpbnRlciwgc29ydGVkX2V4dGVuc2lvbnNbaisrXSk7CisgICAgfQorICB9CisKKyAgaWYgKFByZXNlcnZlVW5rbm93bkZpZWxkcyhkZXNjcmlwdG9yXykpIHsKKyAgICBpZiAoZGVzY3JpcHRvcl8tPm9wdGlvbnMoKS5tZXNzYWdlX3NldF93aXJlX2Zvcm1hdCgpKSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgInVua25vd25GaWVsZHMud3JpdGVBc01lc3NhZ2VTZXRUbyhvdXRwdXQpO1xuIik7CisgICAgfSBlbHNlIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAidW5rbm93bkZpZWxkcy53cml0ZVRvKG91dHB1dCk7XG4iKTsKKyAgICB9CisgIH0KKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KAorICAgICJ9XG4iCisgICAgIlxuIgorICAgICJwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkge1xuIgorICAgICIgIGludCBzaXplID0gbWVtb2l6ZWRTaXplO1xuIgorICAgICIgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTtcbiIKKyAgICAiXG4iCisgICAgIiAgc2l6ZSA9IDA7XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KHNvcnRlZF9maWVsZHNbaV0pLkdlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKHByaW50ZXIpOworICB9CisKKyAgaWYgKGRlc2NyaXB0b3JfLT5leHRlbnNpb25fcmFuZ2VfY291bnQoKSA+IDApIHsKKyAgICBpZiAoZGVzY3JpcHRvcl8tPm9wdGlvbnMoKS5tZXNzYWdlX3NldF93aXJlX2Zvcm1hdCgpKSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgInNpemUgKz0gZXh0ZW5zaW9uc1NlcmlhbGl6ZWRTaXplQXNNZXNzYWdlU2V0KCk7XG4iKTsKKyAgICB9IGVsc2UgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJzaXplICs9IGV4dGVuc2lvbnNTZXJpYWxpemVkU2l6ZSgpO1xuIik7CisgICAgfQorICB9CisKKyAgaWYgKFByZXNlcnZlVW5rbm93bkZpZWxkcyhkZXNjcmlwdG9yXykpIHsKKyAgICBpZiAoZGVzY3JpcHRvcl8tPm9wdGlvbnMoKS5tZXNzYWdlX3NldF93aXJlX2Zvcm1hdCgpKSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgInNpemUgKz0gdW5rbm93bkZpZWxkcy5nZXRTZXJpYWxpemVkU2l6ZUFzTWVzc2FnZVNldCgpO1xuIik7CisgICAgfSBlbHNlIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAic2l6ZSArPSB1bmtub3duRmllbGRzLmdldFNlcmlhbGl6ZWRTaXplKCk7XG4iKTsKKyAgICB9CisgIH0KKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KAorICAgICIgIG1lbW9pemVkU2l6ZSA9IHNpemU7XG4iCisgICAgIiAgcmV0dXJuIHNpemU7XG4iCisgICAgIn1cbiIKKyAgICAiXG4iKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAicHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVNZXNzYWdlR2VuZXJhdG9yOjoKK0dlbmVyYXRlUGFyc2VGcm9tTWV0aG9kcyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICAvLyBOb3RlOiAgVGhlc2UgYXJlIHNlcGFyYXRlIGZyb20gR2VuZXJhdGVNZXNzYWdlU2VyaWFsaXphdGlvbk1ldGhvZHMoKQorICAvLyAgIGJlY2F1c2UgdGhleSBuZWVkIHRvIGJlIGdlbmVyYXRlZCBldmVuIGZvciBtZXNzYWdlcyB0aGF0IGFyZSBvcHRpbWl6ZWQKKyAgLy8gICBmb3IgY29kZSBzaXplLgorICBwcmludGVyLT5QcmludCgKKyAgICAicHVibGljIHN0YXRpYyAkY2xhc3NuYW1lJCBwYXJzZUZyb20oXG4iCisgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSlcbiIKKyAgICAiICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7XG4iCisgICAgIiAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7XG4iCisgICAgIn1cbiIKKyAgICAicHVibGljIHN0YXRpYyAkY2xhc3NuYW1lJCBwYXJzZUZyb20oXG4iCisgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSxcbiIKKyAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KVxuIgorICAgICIgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHtcbiIKKyAgICAiICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7XG4iCisgICAgIn1cbiIKKyAgICAicHVibGljIHN0YXRpYyAkY2xhc3NuYW1lJCBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpXG4iCisgICAgIiAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24ge1xuIgorICAgICIgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpO1xuIgorICAgICJ9XG4iCisgICAgInB1YmxpYyBzdGF0aWMgJGNsYXNzbmFtZSQgcGFyc2VGcm9tKFxuIgorICAgICIgICAgYnl0ZVtdIGRhdGEsXG4iCisgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSlcbiIKKyAgICAiICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7XG4iCisgICAgIiAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpO1xuIgorICAgICJ9XG4iCisgICAgInB1YmxpYyBzdGF0aWMgJGNsYXNzbmFtZSQgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpXG4iCisgICAgIiAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7XG4iCisgICAgIiAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsiCisgICAgIn1cbiIKKyAgICAicHVibGljIHN0YXRpYyAkY2xhc3NuYW1lJCBwYXJzZUZyb20oXG4iCisgICAgIiAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LFxuIgorICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpXG4iCisgICAgIiAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7XG4iCisgICAgIiAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7IgorICAgICJ9XG4iCisgICAgInB1YmxpYyBzdGF0aWMgJGNsYXNzbmFtZSQgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpXG4iCisgICAgIiAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7XG4iCisgICAgIiAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsiCisgICAgIn1cbiIKKyAgICAicHVibGljIHN0YXRpYyAkY2xhc3NuYW1lJCBwYXJzZURlbGltaXRlZEZyb20oXG4iCisgICAgIiAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LFxuIgorICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpXG4iCisgICAgIiAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7XG4iCisgICAgIiAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7IgorICAgICJ9XG4iCisgICAgInB1YmxpYyBzdGF0aWMgJGNsYXNzbmFtZSQgcGFyc2VGcm9tKFxuIgorICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KVxuIgorICAgICIgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24ge1xuIgorICAgICIgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7IgorICAgICJ9XG4iCisgICAgInB1YmxpYyBzdGF0aWMgJGNsYXNzbmFtZSQgcGFyc2VGcm9tKFxuIgorICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LFxuIgorICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpXG4iCisgICAgIiAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7XG4iCisgICAgIiAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7IgorICAgICJ9XG4iCisgICAgIlxuIiwKKyAgICAiY2xhc3NuYW1lIiwgbmFtZV9yZXNvbHZlcl8tPkdldEltbXV0YWJsZUNsYXNzTmFtZShkZXNjcmlwdG9yXykpOworfQorCit2b2lkIEltbXV0YWJsZU1lc3NhZ2VHZW5lcmF0b3I6OkdlbmVyYXRlU2VyaWFsaXplT25lRmllbGQoCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGZpZWxkKS5HZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKHByaW50ZXIpOworfQorCit2b2lkIEltbXV0YWJsZU1lc3NhZ2VHZW5lcmF0b3I6OkdlbmVyYXRlU2VyaWFsaXplT25lRXh0ZW5zaW9uUmFuZ2UoCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIsIGNvbnN0IERlc2NyaXB0b3I6OkV4dGVuc2lvblJhbmdlKiByYW5nZSkgeworICBwcmludGVyLT5QcmludCgKKyAgICAiZXh0ZW5zaW9uV3JpdGVyLndyaXRlVW50aWwoJGVuZCQsIG91dHB1dCk7XG4iLAorICAgICJlbmQiLCBTaW1wbGVJdG9hKHJhbmdlLT5lbmQpKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCit2b2lkIEltbXV0YWJsZU1lc3NhZ2VHZW5lcmF0b3I6OkdlbmVyYXRlQnVpbGRlcihpbzo6UHJpbnRlciogcHJpbnRlcikgeworICAvLyBMSVRFX1JVTlRJTUUgaW1wbGVtZW50cyB0aGlzIGF0IHRoZSBHZW5lcmF0ZWRNZXNzYWdlTGl0ZSBsZXZlbC4KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgInB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9XG4iKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAicHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7XG4iCisgICAgIiAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7XG4iCisgICAgIn1cbiIKKyAgICAicHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoJGNsYXNzbmFtZSQgcHJvdG90eXBlKSB7XG4iCisgICAgIiAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7XG4iCisgICAgIn1cbiIKKyAgICAicHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkge1xuIgorICAgICIgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0VcbiIKKyAgICAiICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7XG4iCisgICAgIn1cbiIKKyAgICAiXG4iLAorICAgICJjbGFzc25hbWUiLCBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3JfKSk7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIkBqYXZhLmxhbmcuT3ZlcnJpZGVcbiIKKyAgICAicHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoXG4iCisgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuQnVpbGRlclBhcmVudCBwYXJlbnQpIHtcbiIKKyAgICAiICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpO1xuIgorICAgICIgIHJldHVybiBidWlsZGVyO1xuIgorICAgICJ9XG4iKTsKKworICBNZXNzYWdlQnVpbGRlckdlbmVyYXRvciBidWlsZGVyR2VuZXJhdG9yKGRlc2NyaXB0b3JfLCBjb250ZXh0Xyk7CisgIGJ1aWxkZXJHZW5lcmF0b3IuR2VuZXJhdGUocHJpbnRlcik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlTWVzc2FnZUdlbmVyYXRvcjo6CitHZW5lcmF0ZURlc2NyaXB0b3JNZXRob2RzKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIGlmICghZGVzY3JpcHRvcl8tPm9wdGlvbnMoKS5ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yKCkpIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvclxuIgorICAgICAgIiAgICBnZXREZXNjcmlwdG9yKCkge1xuIgorICAgICAgIiAgcmV0dXJuICRmaWxlY2xhc3MkLmludGVybmFsXyRpZGVudGlmaWVyJF9kZXNjcmlwdG9yO1xuIgorICAgICAgIn1cbiIKKyAgICAgICJcbiIsCisgICAgICAiZmlsZWNsYXNzIiwgbmFtZV9yZXNvbHZlcl8tPkdldEltbXV0YWJsZUNsYXNzTmFtZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSwKKyAgICAgICJpZGVudGlmaWVyIiwgVW5pcXVlRmlsZVNjb3BlSWRlbnRpZmllcihkZXNjcmlwdG9yXykpOworICB9CisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBtYXBfZmllbGRzOworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvcl8tPmZpZWxkKGkpOworICAgIGlmIChHZXRKYXZhVHlwZShmaWVsZCkgPT0gSkFWQVRZUEVfTUVTU0FHRSAmJgorICAgICAgICBJc01hcEVudHJ5KGZpZWxkLT5tZXNzYWdlX3R5cGUoKSkpIHsKKyAgICAgIG1hcF9maWVsZHMucHVzaF9iYWNrKGZpZWxkKTsKKyAgICB9CisgIH0KKyAgaWYgKCFtYXBfZmllbGRzLmVtcHR5KCkpIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJAU3VwcHJlc3NXYXJuaW5ncyh7XCJyYXd0eXBlc1wifSlcbiIKKyAgICAgICJwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZCBpbnRlcm5hbEdldE1hcEZpZWxkKFxuIgorICAgICAgIiAgICBpbnQgbnVtYmVyKSB7XG4iCisgICAgICAiICBzd2l0Y2ggKG51bWJlcikge1xuIik7CisgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtYXBfZmllbGRzLnNpemUoKTsgKytpKSB7CisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gbWFwX2ZpZWxkc1tpXTsKKyAgICAgIGNvbnN0IEZpZWxkR2VuZXJhdG9ySW5mbyogaW5mbyA9IGNvbnRleHRfLT5HZXRGaWVsZEdlbmVyYXRvckluZm8oZmllbGQpOworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJjYXNlICRudW1iZXIkOlxuIgorICAgICAgICAiICByZXR1cm4gaW50ZXJuYWxHZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKTtcbiIsCisgICAgICAgICJudW1iZXIiLCBTaW1wbGVJdG9hKGZpZWxkLT5udW1iZXIoKSksCisgICAgICAgICJjYXBpdGFsaXplZF9uYW1lIiwgaW5mby0+Y2FwaXRhbGl6ZWRfbmFtZSk7CisgICAgfQorICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiZGVmYXVsdDpcbiIKKyAgICAgICAgIiAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oXG4iCisgICAgICAgICIgICAgICBcIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogXCIgKyBudW1iZXIpO1xuIik7CisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIiAgfVxuIgorICAgICAgICAifVxuIik7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgInByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuRmllbGRBY2Nlc3NvclRhYmxlXG4iCisgICAgIiAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHtcbiIKKyAgICAiICByZXR1cm4gJGZpbGVjbGFzcyQuaW50ZXJuYWxfJGlkZW50aWZpZXIkX2ZpZWxkQWNjZXNzb3JUYWJsZVxuIgorICAgICIgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZChcbiIKKyAgICAiICAgICAgICAgICRjbGFzc25hbWUkLmNsYXNzLCAkY2xhc3NuYW1lJC5CdWlsZGVyLmNsYXNzKTtcbiIKKyAgICAifVxuIgorICAgICJcbiIsCisgICAgImNsYXNzbmFtZSIsIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcl8pLAorICAgICJmaWxlY2xhc3MiLCBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3JfLT5maWxlKCkpLAorICAgICJpZGVudGlmaWVyIiwgVW5pcXVlRmlsZVNjb3BlSWRlbnRpZmllcihkZXNjcmlwdG9yXykpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK3ZvaWQgSW1tdXRhYmxlTWVzc2FnZUdlbmVyYXRvcjo6R2VuZXJhdGVJc0luaXRpYWxpemVkKAorICAgIGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIC8vIE1lbW9pemVzIHdoZXRoZXIgdGhlIHByb3RvY29sIGJ1ZmZlciBpcyBmdWxseSBpbml0aWFsaXplZCAoaGFzIGFsbAorICAvLyByZXF1aXJlZCBmaWVsZHMpLiAtMSBtZWFucyBub3QgeWV0IGNvbXB1dGVkLiAwIG1lYW5zIGZhbHNlIGFuZCAxIG1lYW5zCisgIC8vIHRydWUuCisgIHByaW50ZXItPlByaW50KAorICAgICJwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7XG4iKTsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgInB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgLy8gRG9uJ3QgZGlyZWN0bHkgY29tcGFyZSB0byAtMSB0byBhdm9pZCBhbiBBbmRyb2lkIHg4NiBKSVQgYnVnLgorICBwcmludGVyLT5QcmludCgKKyAgICAiYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkO1xuIgorICAgICJpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTtcbiIKKyAgICAiaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlO1xuIgorICAgICJcbiIpOworCisgIC8vIENoZWNrIHRoYXQgYWxsIHJlcXVpcmVkIGZpZWxkcyBpbiB0aGlzIG1lc3NhZ2UgYXJlIHNldC4KKyAgLy8gVE9ETyhrZW50b24pOiAgV2UgY2FuIG9wdGltaXplIHRoaXMgd2hlbiB3ZSBzd2l0Y2ggdG8gcHV0dGluZyBhbGwgdGhlCisgIC8vICAgImhhcyIgZmllbGRzIGludG8gYSBzaW5nbGUgYml0ZmllbGQuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBkZXNjcmlwdG9yXy0+ZmllbGQoaSk7CisgICAgY29uc3QgRmllbGRHZW5lcmF0b3JJbmZvKiBpbmZvID0gY29udGV4dF8tPkdldEZpZWxkR2VuZXJhdG9ySW5mbyhmaWVsZCk7CisKKyAgICBpZiAoZmllbGQtPmlzX3JlcXVpcmVkKCkpIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiaWYgKCFoYXMkbmFtZSQoKSkge1xuIgorICAgICAgICAiICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwO1xuIgorICAgICAgICAiICByZXR1cm4gZmFsc2U7XG4iCisgICAgICAgICJ9XG4iLAorICAgICAgICAibmFtZSIsIGluZm8tPmNhcGl0YWxpemVkX25hbWUpOworICAgIH0KKyAgfQorCisgIC8vIE5vdyBjaGVjayB0aGF0IGFsbCBlbWJlZGRlZCBtZXNzYWdlcyBhcmUgaW5pdGlhbGl6ZWQuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBkZXNjcmlwdG9yXy0+ZmllbGQoaSk7CisgICAgY29uc3QgRmllbGRHZW5lcmF0b3JJbmZvKiBpbmZvID0gY29udGV4dF8tPkdldEZpZWxkR2VuZXJhdG9ySW5mbyhmaWVsZCk7CisgICAgaWYgKEdldEphdmFUeXBlKGZpZWxkKSA9PSBKQVZBVFlQRV9NRVNTQUdFICYmCisgICAgICAgIEhhc1JlcXVpcmVkRmllbGRzKGZpZWxkLT5tZXNzYWdlX3R5cGUoKSkpIHsKKyAgICAgIHN3aXRjaCAoZmllbGQtPmxhYmVsKCkpIHsKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkxBQkVMX1JFUVVJUkVEOgorICAgICAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICAgImlmICghZ2V0JG5hbWUkKCkuaXNJbml0aWFsaXplZCgpKSB7XG4iCisgICAgICAgICAgICAgIiAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDtcbiIKKyAgICAgICAgICAgICAiICByZXR1cm4gZmFsc2U7XG4iCisgICAgICAgICAgICAgIn1cbiIsCisgICAgICAgICAgICAidHlwZSIsIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoCisgICAgICAgICAgICAgICAgZmllbGQtPm1lc3NhZ2VfdHlwZSgpKSwKKyAgICAgICAgICAgICJuYW1lIiwgaW5mby0+Y2FwaXRhbGl6ZWRfbmFtZSk7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpMQUJFTF9PUFRJT05BTDoKKyAgICAgICAgICBpZiAoIVN1cHBvcnRGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3JfLT5maWxlKCkpICYmCisgICAgICAgICAgICAgIGZpZWxkLT5jb250YWluaW5nX29uZW9mKCkgIT0gTlVMTCkgeworICAgICAgICAgICAgY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBvbmVvZiA9IGZpZWxkLT5jb250YWluaW5nX29uZW9mKCk7CisgICAgICAgICAgICBjb25zdCBPbmVvZkdlbmVyYXRvckluZm8qIG9uZW9mX2luZm8gPQorICAgICAgICAgICAgICAgIGNvbnRleHRfLT5HZXRPbmVvZkdlbmVyYXRvckluZm8ob25lb2YpOworICAgICAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgICAgICJpZiAoJG9uZW9mX25hbWUkQ2FzZV8gPT0gJGZpZWxkX251bWJlciQpIHtcbiIsCisgICAgICAgICAgICAgICJvbmVvZl9uYW1lIiwgb25lb2ZfaW5mby0+bmFtZSwKKyAgICAgICAgICAgICAgImZpZWxkX251bWJlciIsIFNpbXBsZUl0b2EoZmllbGQtPm51bWJlcigpKSk7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICAgICAiaWYgKGhhcyRuYW1lJCgpKSB7XG4iLAorICAgICAgICAgICAgICAibmFtZSIsIGluZm8tPmNhcGl0YWxpemVkX25hbWUpOworICAgICAgICAgIH0KKyAgICAgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAgICIgIGlmICghZ2V0JG5hbWUkKCkuaXNJbml0aWFsaXplZCgpKSB7XG4iCisgICAgICAgICAgICAiICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7XG4iCisgICAgICAgICAgICAiICAgIHJldHVybiBmYWxzZTtcbiIKKyAgICAgICAgICAgICIgIH1cbiIKKyAgICAgICAgICAgICJ9XG4iLAorICAgICAgICAgICAgIm5hbWUiLCBpbmZvLT5jYXBpdGFsaXplZF9uYW1lKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkxBQkVMX1JFUEVBVEVEOgorICAgICAgICAgIGlmIChJc01hcEVudHJ5KGZpZWxkLT5tZXNzYWdlX3R5cGUoKSkpIHsKKyAgICAgICAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICAgICAiZm9yICgkdHlwZSQgaXRlbSA6IGdldCRuYW1lJCgpLnZhbHVlcygpKSB7XG4iCisgICAgICAgICAgICAgICIgIGlmICghaXRlbS5pc0luaXRpYWxpemVkKCkpIHtcbiIKKyAgICAgICAgICAgICAgIiAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwO1xuIgorICAgICAgICAgICAgICAiICAgIHJldHVybiBmYWxzZTtcbiIKKyAgICAgICAgICAgICAgIiAgfVxuIgorICAgICAgICAgICAgICAifVxuIiwKKyAgICAgICAgICAgICAgInR5cGUiLCBNYXBWYWx1ZUltbXV0YWJsZUNsYXNzZE5hbWUoZmllbGQtPm1lc3NhZ2VfdHlwZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lX3Jlc29sdmVyXyksCisgICAgICAgICAgICAgICJuYW1lIiwgaW5mby0+Y2FwaXRhbGl6ZWRfbmFtZSk7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICAgICAiZm9yIChpbnQgaSA9IDA7IGkgPCBnZXQkbmFtZSRDb3VudCgpOyBpKyspIHtcbiIKKyAgICAgICAgICAgICAgIiAgaWYgKCFnZXQkbmFtZSQoaSkuaXNJbml0aWFsaXplZCgpKSB7XG4iCisgICAgICAgICAgICAgICIgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDtcbiIKKyAgICAgICAgICAgICAgIiAgICByZXR1cm4gZmFsc2U7XG4iCisgICAgICAgICAgICAgICIgIH1cbiIKKyAgICAgICAgICAgICAgIn1cbiIsCisgICAgICAgICAgICAgICJ0eXBlIiwgbmFtZV9yZXNvbHZlcl8tPkdldEltbXV0YWJsZUNsYXNzTmFtZSgKKyAgICAgICAgICAgICAgICAgIGZpZWxkLT5tZXNzYWdlX3R5cGUoKSksCisgICAgICAgICAgICAgICJuYW1lIiwgaW5mby0+Y2FwaXRhbGl6ZWRfbmFtZSk7CisgICAgICAgICAgfQorICAgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgfQorCisgIGlmIChkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCkgPiAwKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiaWYgKCFleHRlbnNpb25zQXJlSW5pdGlhbGl6ZWQoKSkge1xuIgorICAgICAgIiAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDtcbiIKKyAgICAgICIgIHJldHVybiBmYWxzZTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAiICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxO1xuIik7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIiAgcmV0dXJuIHRydWU7XG4iCisgICAgIn1cbiIKKyAgICAiXG4iKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCituYW1lc3BhY2UgeworYm9vbCBDaGVja0hhc0JpdHNGb3JFcXVhbHNBbmRIYXNoQ29kZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIGlmIChmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICBpZiAoU3VwcG9ydEZpZWxkUHJlc2VuY2UoZmllbGQtPmZpbGUoKSkpIHsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorICByZXR1cm4gR2V0SmF2YVR5cGUoZmllbGQpID09IEpBVkFUWVBFX01FU1NBR0UgJiYKKyAgICAgIGZpZWxkLT5jb250YWluaW5nX29uZW9mKCkgPT0gTlVMTDsKK30KK30gIC8vIG5hbWVzcGFjZQorCit2b2lkIEltbXV0YWJsZU1lc3NhZ2VHZW5lcmF0b3I6OgorR2VuZXJhdGVFcXVhbHNBbmRIYXNoQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICAiQGphdmEubGFuZy5PdmVycmlkZVxuIgorICAgICJwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHtcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgImlmIChvYmogPT0gdGhpcykge1xuIgorICAgICIgcmV0dXJuIHRydWU7XG4iCisgICAgIn1cbiIKKyAgICAiaWYgKCEob2JqIGluc3RhbmNlb2YgJGNsYXNzbmFtZSQpKSB7XG4iCisgICAgIiAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopO1xuIgorICAgICJ9XG4iCisgICAgIiRjbGFzc25hbWUkIG90aGVyID0gKCRjbGFzc25hbWUkKSBvYmo7XG4iCisgICAgIlxuIiwKKyAgICAiY2xhc3NuYW1lIiwgbmFtZV9yZXNvbHZlcl8tPkdldEltbXV0YWJsZUNsYXNzTmFtZShkZXNjcmlwdG9yXykpOworCisgIHByaW50ZXItPlByaW50KCJib29sZWFuIHJlc3VsdCA9IHRydWU7XG4iKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3JfLT5maWVsZChpKTsKKyAgICBpZiAoZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSA9PSBOVUxMKSB7CisgICAgICBjb25zdCBGaWVsZEdlbmVyYXRvckluZm8qIGluZm8gPSBjb250ZXh0Xy0+R2V0RmllbGRHZW5lcmF0b3JJbmZvKGZpZWxkKTsKKyAgICAgIGJvb2wgY2hlY2tfaGFzX2JpdHMgPSBDaGVja0hhc0JpdHNGb3JFcXVhbHNBbmRIYXNoQ29kZShmaWVsZCk7CisgICAgICBpZiAoY2hlY2tfaGFzX2JpdHMpIHsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgInJlc3VsdCA9IHJlc3VsdCAmJiAoaGFzJG5hbWUkKCkgPT0gb3RoZXIuaGFzJG5hbWUkKCkpO1xuIgorICAgICAgICAgICJpZiAoaGFzJG5hbWUkKCkpIHtcbiIsCisgICAgICAgICAgIm5hbWUiLCBpbmZvLT5jYXBpdGFsaXplZF9uYW1lKTsKKyAgICAgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgICB9CisgICAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZmllbGQpLkdlbmVyYXRlRXF1YWxzQ29kZShwcmludGVyKTsKKyAgICAgIGlmIChjaGVja19oYXNfYml0cykgeworICAgICAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICJ9XG4iKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvLyBDb21wYXJlIG9uZW9mcy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbF9jb3VudCgpOyBpKyspIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJyZXN1bHQgPSByZXN1bHQgJiYgZ2V0JG9uZW9mX2NhcGl0YWxpemVkX25hbWUkQ2FzZSgpLmVxdWFscyhcbiIKKyAgICAgICIgICAgb3RoZXIuZ2V0JG9uZW9mX2NhcGl0YWxpemVkX25hbWUkQ2FzZSgpKTtcbiIsCisgICAgICAib25lb2ZfY2FwaXRhbGl6ZWRfbmFtZSIsCisgICAgICBjb250ZXh0Xy0+R2V0T25lb2ZHZW5lcmF0b3JJbmZvKAorICAgICAgICAgIGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpKS0+Y2FwaXRhbGl6ZWRfbmFtZSk7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiaWYgKCFyZXN1bHQpIHJldHVybiBmYWxzZTtcbiIKKyAgICAgICJzd2l0Y2ggKCRvbmVvZl9uYW1lJENhc2VfKSB7XG4iLAorICAgICAgIm9uZW9mX25hbWUiLAorICAgICAgY29udGV4dF8tPkdldE9uZW9mR2VuZXJhdG9ySW5mbygKKyAgICAgICAgICBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKSktPm5hbWUpOworICAgIHByaW50ZXItPkluZGVudCgpOworICAgIGZvciAoaW50IGogPSAwOyBqIDwgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPmZpZWxkX2NvdW50KCk7IGorKykgeworICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5maWVsZChqKTsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiY2FzZSAkZmllbGRfbnVtYmVyJDpcbiIsCisgICAgICAgICJmaWVsZF9udW1iZXIiLAorICAgICAgICBTaW1wbGVJdG9hKGZpZWxkLT5udW1iZXIoKSkpOworICAgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZmllbGQpLkdlbmVyYXRlRXF1YWxzQ29kZShwcmludGVyKTsKKyAgICAgIHByaW50ZXItPlByaW50KCJicmVhaztcbiIpOworICAgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIH0KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJjYXNlIDA6XG4iCisgICAgICAiZGVmYXVsdDpcbiIpOworICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICBwcmludGVyLT5QcmludCgifVxuIik7CisgIH0KKworICBpZiAoUHJlc2VydmVVbmtub3duRmllbGRzKGRlc2NyaXB0b3JfKSkgeworICAgIC8vIEFsd2F5cyBjb25zaWRlciB1bmtub3duIGZpZWxkcyBmb3IgZXF1YWxpdHkuIFRoaXMgd2lsbCBzb21ldGltZXMgcmV0dXJuCisgICAgLy8gZmFsc2UgZm9yIG5vbi1jYW5vbmljYWwgb3JkZXJpbmcgd2hlbiBydW5uaW5nIGluIExJVEVfUlVOVElNRSBidXQgaXQncworICAgIC8vIHRoZSBiZXN0IHdlIGNhbiBkby4KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJyZXN1bHQgPSByZXN1bHQgJiYgdW5rbm93bkZpZWxkcy5lcXVhbHMob3RoZXIudW5rbm93bkZpZWxkcyk7XG4iKTsKKyAgfQorICBpZiAoZGVzY3JpcHRvcl8tPmV4dGVuc2lvbl9yYW5nZV9jb3VudCgpID4gMCkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgInJlc3VsdCA9IHJlc3VsdCAmJlxuIgorICAgICAgIiAgICBnZXRFeHRlbnNpb25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0RXh0ZW5zaW9uRmllbGRzKCkpO1xuIik7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgInJldHVybiByZXN1bHQ7XG4iKTsKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAifVxuIgorICAgICJcbiIpOworCisgIHByaW50ZXItPlByaW50KAorICAgICJAamF2YS5sYW5nLk92ZXJyaWRlXG4iCisgICAgInB1YmxpYyBpbnQgaGFzaENvZGUoKSB7XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisgIHByaW50ZXItPlByaW50KAorICAgICJpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisgIHByaW50ZXItPlByaW50KAorICAgICJyZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTtcbiIpOworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KAorICAgICJ9XG4iCisgICAgImludCBoYXNoID0gNDE7XG4iKTsKKworICBwcmludGVyLT5QcmludCgiaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvckZvclR5cGUoKS5oYXNoQ29kZSgpO1xuIik7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3JfLT5maWVsZChpKTsKKyAgICBjb25zdCBGaWVsZEdlbmVyYXRvckluZm8qIGluZm8gPSBjb250ZXh0Xy0+R2V0RmllbGRHZW5lcmF0b3JJbmZvKGZpZWxkKTsKKyAgICBib29sIGNoZWNrX2hhc19iaXRzID0gQ2hlY2tIYXNCaXRzRm9yRXF1YWxzQW5kSGFzaENvZGUoZmllbGQpOworICAgIGlmIChjaGVja19oYXNfYml0cykgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJpZiAoaGFzJG5hbWUkKCkpIHtcbiIsCisgICAgICAgICJuYW1lIiwgaW5mby0+Y2FwaXRhbGl6ZWRfbmFtZSk7CisgICAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICB9CisgICAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGZpZWxkKS5HZW5lcmF0ZUhhc2hDb2RlKHByaW50ZXIpOworICAgIGlmIChjaGVja19oYXNfYml0cykgeworICAgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgICAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworICAgIH0KKyAgfQorICBpZiAoZGVzY3JpcHRvcl8tPmV4dGVuc2lvbl9yYW5nZV9jb3VudCgpID4gMCkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgImhhc2ggPSBoYXNoRmllbGRzKGhhc2gsIGdldEV4dGVuc2lvbkZpZWxkcygpKTtcbiIpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgImhhc2ggPSAoMjkgKiBoYXNoKSArIHVua25vd25GaWVsZHMuaGFzaENvZGUoKTtcbiIpOworICBwcmludGVyLT5QcmludCgKKyAgICAibWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7XG4iCisgICAgInJldHVybiBoYXNoO1xuIik7CisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIn1cbiIKKyAgICAiXG4iKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCit2b2lkIEltbXV0YWJsZU1lc3NhZ2VHZW5lcmF0b3I6OgorR2VuZXJhdGVFeHRlbnNpb25SZWdpc3RyYXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmV4dGVuc2lvbl9jb3VudCgpOyBpKyspIHsKKyAgICBJbW11dGFibGVFeHRlbnNpb25HZW5lcmF0b3IoZGVzY3JpcHRvcl8tPmV4dGVuc2lvbihpKSwgY29udGV4dF8pCisgICAgICAuR2VuZXJhdGVSZWdpc3RyYXRpb25Db2RlKHByaW50ZXIpOworICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+bmVzdGVkX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgSW1tdXRhYmxlTWVzc2FnZUdlbmVyYXRvcihkZXNjcmlwdG9yXy0+bmVzdGVkX3R5cGUoaSksIGNvbnRleHRfKQorICAgICAgLkdlbmVyYXRlRXh0ZW5zaW9uUmVnaXN0cmF0aW9uQ29kZShwcmludGVyKTsKKyAgfQorfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Cit2b2lkIEltbXV0YWJsZU1lc3NhZ2VHZW5lcmF0b3I6OgorR2VuZXJhdGVQYXJzaW5nQ29uc3RydWN0b3IoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX2FycmF5PGNvbnN0IEZpZWxkRGVzY3JpcHRvciAqID4gc29ydGVkX2ZpZWxkcygKKyAgICAgIFNvcnRGaWVsZHNCeU51bWJlcihkZXNjcmlwdG9yXykpOworCisgIHByaW50ZXItPlByaW50KAorICAgICAgInByaXZhdGUgJGNsYXNzbmFtZSQoXG4iCisgICAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCxcbiIKKyAgICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpIHtcbiIsCisgICAgICAiY2xhc3NuYW1lIiwgZGVzY3JpcHRvcl8tPm5hbWUoKSk7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIC8vIEluaXRpYWxpemUgYWxsIGZpZWxkcyB0byBkZWZhdWx0LgorICBwcmludGVyLT5QcmludCgKKyAgICAgICJ0aGlzKCk7XG4iKTsKKworICAvLyBVc2UgYnVpbGRlciBiaXRzIHRvIHRyYWNrIG11dGFibGUgcmVwZWF0ZWQgZmllbGRzLgorICBpbnQgdG90YWxCdWlsZGVyQml0cyA9IDA7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IEltbXV0YWJsZUZpZWxkR2VuZXJhdG9yJiBmaWVsZCA9CisgICAgICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChkZXNjcmlwdG9yXy0+ZmllbGQoaSkpOworICAgIHRvdGFsQnVpbGRlckJpdHMgKz0gZmllbGQuR2V0TnVtQml0c0ZvckJ1aWxkZXIoKTsKKyAgfQorICBpbnQgdG90YWxCdWlsZGVySW50cyA9ICh0b3RhbEJ1aWxkZXJCaXRzICsgMzEpIC8gMzI7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdG90YWxCdWlsZGVySW50czsgaSsrKSB7CisgICAgcHJpbnRlci0+UHJpbnQoImludCBtdXRhYmxlXyRiaXRfZmllbGRfbmFtZSQgPSAwO1xuIiwKKyAgICAgICJiaXRfZmllbGRfbmFtZSIsIEdldEJpdEZpZWxkTmFtZShpKSk7CisgIH0KKworICBpZiAoUHJlc2VydmVVbmtub3duRmllbGRzKGRlc2NyaXB0b3JfKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgImNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0LkJ1aWxkZXIgdW5rbm93bkZpZWxkcyA9XG4iCisgICAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0Lm5ld0J1aWxkZXIoKTtcbiIpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICAidHJ5IHtcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAiYm9vbGVhbiBkb25lID0gZmFsc2U7XG4iCisgICAgIndoaWxlICghZG9uZSkge1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIHByaW50ZXItPlByaW50KAorICAgICJpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpO1xuIgorICAgICJzd2l0Y2ggKHRhZykge1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIHByaW50ZXItPlByaW50KAorICAgICJjYXNlIDA6XG4iICAgICAgICAgIC8vIHplcm8gc2lnbmFscyBFT0YgLyBsaW1pdCByZWFjaGVkCisgICAgIiAgZG9uZSA9IHRydWU7XG4iCisgICAgIiAgYnJlYWs7XG4iKTsKKworICBpZiAoUHJlc2VydmVVbmtub3duRmllbGRzKGRlc2NyaXB0b3JfKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgImRlZmF1bHQ6IHtcbiIKKyAgICAgICIgIGlmICghcGFyc2VVbmtub3duRmllbGQoaW5wdXQsIHVua25vd25GaWVsZHMsXG4iCisgICAgICAiICAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7XG4iCisgICAgICAiICAgIGRvbmUgPSB0cnVlO1xuIiAgLy8gaXQncyBhbiBlbmRncm91cCB0YWcKKyAgICAgICIgIH1cbiIKKyAgICAgICIgIGJyZWFrO1xuIgorICAgICAgIn1cbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgImRlZmF1bHQ6IHtcbiIKKyAgICAgICIgIGlmICghaW5wdXQuc2tpcEZpZWxkKHRhZykpIHtcbiIKKyAgICAgICIgICAgZG9uZSA9IHRydWU7XG4iICAvLyBpdCdzIGFuIGVuZGdyb3VwIHRhZworICAgICAgIiAgfVxuIgorICAgICAgIiAgYnJlYWs7XG4iCisgICAgICAifVxuIik7CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gc29ydGVkX2ZpZWxkc1tpXTsKKyAgICB1aW50MzIgdGFnID0gV2lyZUZvcm1hdExpdGU6Ok1ha2VUYWcoZmllbGQtPm51bWJlcigpLAorICAgICAgV2lyZUZvcm1hdDo6V2lyZVR5cGVGb3JGaWVsZFR5cGUoZmllbGQtPnR5cGUoKSkpOworCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiY2FzZSAkdGFnJDoge1xuIiwKKyAgICAgICJ0YWciLCBTaW1wbGVJdG9hKHRhZykpOworICAgIHByaW50ZXItPkluZGVudCgpOworCisgICAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGZpZWxkKS5HZW5lcmF0ZVBhcnNpbmdDb2RlKHByaW50ZXIpOworCisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIiAgYnJlYWs7XG4iCisgICAgICAifVxuIik7CisKKyAgICBpZiAoZmllbGQtPmlzX3BhY2thYmxlKCkpIHsKKyAgICAgIC8vIFRvIG1ha2UgcGFja2VkID0gdHJ1ZSB3aXJlIGNvbXBhdGlibGUsIHdlIGdlbmVyYXRlIHBhcnNpbmcgY29kZSBmcm9tIGEKKyAgICAgIC8vIHBhY2tlZCB2ZXJzaW9uIG9mIHRoaXMgZmllbGQgcmVnYXJkbGVzcyBvZiBmaWVsZC0+b3B0aW9ucygpLnBhY2tlZCgpLgorICAgICAgdWludDMyIHBhY2tlZF90YWcgPSBXaXJlRm9ybWF0TGl0ZTo6TWFrZVRhZyhmaWVsZC0+bnVtYmVyKCksCisgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVEKTsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiY2FzZSAkdGFnJDoge1xuIiwKKyAgICAgICAgInRhZyIsIFNpbXBsZUl0b2EocGFja2VkX3RhZykpOworICAgICAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChmaWVsZCkuR2VuZXJhdGVQYXJzaW5nQ29kZUZyb21QYWNrZWQocHJpbnRlcik7CisKKyAgICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiICBicmVhaztcbiIKKyAgICAgICAgIn1cbiIpOworICAgIH0KKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAgICIgIH1cbiIgICAgIC8vIHN3aXRjaCAodGFnKQorICAgICAgIn1cbiIpOyAgICAgLy8gd2hpbGUgKCFkb25lKQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICAifSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkge1xuIgorICAgICAgIiAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZS5zZXRVbmZpbmlzaGVkTWVzc2FnZSh0aGlzKSk7XG4iCisgICAgICAifSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7XG4iCisgICAgICAiICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSlcbiIKKyAgICAgICIgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UodGhpcykpO1xuIgorICAgICAgIn0gZmluYWxseSB7XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgLy8gTWFrZSByZXBlYXRlZCBmaWVsZCBsaXN0IGltbXV0YWJsZS4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IHNvcnRlZF9maWVsZHNbaV07CisgICAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGZpZWxkKS5HZW5lcmF0ZVBhcnNpbmdEb25lQ29kZShwcmludGVyKTsKKyAgfQorCisgIGlmIChQcmVzZXJ2ZVVua25vd25GaWVsZHMoZGVzY3JpcHRvcl8pKSB7CisgICAgLy8gTWFrZSB1bmtub3duIGZpZWxkcyBpbW11dGFibGUuCisgICAgcHJpbnRlci0+UHJpbnQoInRoaXMudW5rbm93bkZpZWxkcyA9IHVua25vd25GaWVsZHMuYnVpbGQoKTtcbiIpOworICB9CisKKyAgLy8gTWFrZSBleHRlbnNpb25zIGltbXV0YWJsZS4KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICAibWFrZUV4dGVuc2lvbnNJbW11dGFibGUoKTtcbiIpOworCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAgICIgIH1cbiIgICAgIC8vIGZpbmFsbHkKKyAgICAgICJ9XG4iKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQordm9pZCBJbW11dGFibGVNZXNzYWdlR2VuZXJhdG9yOjpHZW5lcmF0ZVBhcnNlcihpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICAgICIkdmlzaWJpbGl0eSQgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPCRjbGFzc25hbWUkPlxuIgorICAgICAgIiAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjwkY2xhc3NuYW1lJD4oKSB7XG4iLAorICAgICAgInZpc2liaWxpdHkiLAorICAgICAgRXhwb3NlUHVibGljUGFyc2VyKGRlc2NyaXB0b3JfLT5maWxlKCkpID8gIkBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAicHJpdmF0ZSIsCisgICAgICAiY2xhc3NuYW1lIiwgZGVzY3JpcHRvcl8tPm5hbWUoKSk7CisgIHByaW50ZXItPkluZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAgICJwdWJsaWMgJGNsYXNzbmFtZSQgcGFyc2VQYXJ0aWFsRnJvbShcbiIKKyAgICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LFxuIgorICAgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSlcbiIKKyAgICAgICIgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHtcbiIsCisgICAgICAiY2xhc3NuYW1lIiwgZGVzY3JpcHRvcl8tPm5hbWUoKSk7CisgIGlmIChIYXNHZW5lcmF0ZWRNZXRob2RzKGRlc2NyaXB0b3JfKSkgeworICAgIC8vIFRoZSBwYXJzaW5nIGNvbnN0cnVjdG9yIHRocm93cyBhbiBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gdmlhIGEKKyAgICAvLyBSdW50aW1lRXhjZXB0aW9uIHRvIGFpZCBpbiBtZXRob2QgcHJ1bmluZy4gV2UgdW53cmFwIGl0IGhlcmUuCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICIgIHRyeSB7XG4iCisgICAgICAgICIgICAgcmV0dXJuIG5ldyAkY2xhc3NuYW1lJChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpO1xuIgorICAgICAgICAiICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGUpIHtcbiIKKyAgICAgICAgIiAgICBpZiAoZS5nZXRDYXVzZSgpIGluc3RhbmNlb2ZcbiIKKyAgICAgICAgIiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24pIHtcbiIKKyAgICAgICAgIiAgICAgIHRocm93IChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbilcbiIKKyAgICAgICAgIiAgICAgICAgICBlLmdldENhdXNlKCk7XG4iCisgICAgICAgICIgICAgfVxuIgorICAgICAgICAiICAgIHRocm93IGU7XG4iCisgICAgICAgICIgIH1cbiIsCisgICAgICAgICJjbGFzc25hbWUiLCBkZXNjcmlwdG9yXy0+bmFtZSgpKTsKKyAgfSBlbHNlIHsKKyAgICAvLyBXaGVuIHBhcnNpbmcgY29uc3RydWN0b3IgaXNuJ3QgZ2VuZXJhdGVkLCB1c2UgYnVpbGRlciB0byBwYXJzZQorICAgIC8vIG1lc3NhZ2VzLiBOb3RlLCB3aWxsIGZhbGxiYWNrIHRvIHVzZSByZWZsZWN0aW9uIGJhc2VkIG1lcmdlRmllbGRGcm9tKCkKKyAgICAvLyBpbiBBYnN0cmFjdE1lc3NhZ2UuQnVpbGRlci4KKyAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIkJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTtcbiIKKyAgICAgICAgInRyeSB7XG4iCisgICAgICAgICIgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7XG4iCisgICAgICAgICJ9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7XG4iCisgICAgICAgICIgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7XG4iCisgICAgICAgICJ9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHtcbiIKKyAgICAgICAgIiAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKFxuIgorICAgICAgICAiICAgICAgZS5nZXRNZXNzYWdlKCkpLnNldFVuZmluaXNoZWRNZXNzYWdlKFxuIgorICAgICAgICAiICAgICAgICAgIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpO1xuIgorICAgICAgICAifVxuIgorICAgICAgICAicmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7XG4iKTsKKyAgICBwcmludGVyLT5PdXRkZW50KCk7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJ9XG4iKTsKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAgICJ9O1xuIgorICAgICAgIlxuIik7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICAicHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjwkY2xhc3NuYW1lJD4gcGFyc2VyKCkge1xuIgorICAgICAgIiAgcmV0dXJuIFBBUlNFUjtcbiIKKyAgICAgICJ9XG4iCisgICAgICAiXG4iCisgICAgICAiQGphdmEubGFuZy5PdmVycmlkZVxuIgorICAgICAgInB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjwkY2xhc3NuYW1lJD4gZ2V0UGFyc2VyRm9yVHlwZSgpIHtcbiIKKyAgICAgICIgIHJldHVybiBQQVJTRVI7XG4iCisgICAgICAifVxuIgorICAgICAgIlxuIiwKKyAgICAgICJjbGFzc25hbWUiLCBkZXNjcmlwdG9yXy0+bmFtZSgpKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQordm9pZCBJbW11dGFibGVNZXNzYWdlR2VuZXJhdG9yOjpHZW5lcmF0ZUluaXRpYWxpemVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBpZiAoIWRlc2NyaXB0b3JfLT5maWVsZChpKS0+Y29udGFpbmluZ19vbmVvZigpKSB7CisgICAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZGVzY3JpcHRvcl8tPmZpZWxkKGkpKQorICAgICAgICAgIC5HZW5lcmF0ZUluaXRpYWxpemF0aW9uQ29kZShwcmludGVyKTsKKyAgICB9CisgIH0KK30KKworCit2b2lkIEltbXV0YWJsZU1lc3NhZ2VHZW5lcmF0b3I6OkdlbmVyYXRlQW55TWV0aG9kcyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICAicHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGdldFR5cGVVcmwoXG4iCisgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IgZGVzY3JpcHRvcikge1xuIgorICAgICIgIHJldHVybiBcInR5cGUuZ29vZ2xlYXBpcy5jb20vXCIgKyBkZXNjcmlwdG9yLmdldEZ1bGxOYW1lKCk7XG4iCisgICAgIn1cbiIKKyAgICAiXG4iCisgICAgInB1YmxpYyBzdGF0aWMgPFQgZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2U+IEFueSBwYWNrKFxuIgorICAgICIgICAgVCBtZXNzYWdlKSB7XG4iCisgICAgIiAgcmV0dXJuIEFueS5uZXdCdWlsZGVyKClcbiIKKyAgICAiICAgICAgLnNldFR5cGVVcmwoZ2V0VHlwZVVybChtZXNzYWdlLmdldERlc2NyaXB0b3JGb3JUeXBlKCkpKVxuIgorICAgICIgICAgICAuc2V0VmFsdWUobWVzc2FnZS50b0J5dGVTdHJpbmcoKSlcbiIKKyAgICAiICAgICAgLmJ1aWxkKCk7XG4iCisgICAgIn1cbiIKKyAgICAiXG4iCisgICAgInB1YmxpYyA8VCBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZT4gYm9vbGVhbiBpcyhcbiIKKyAgICAiICAgIGphdmEubGFuZy5DbGFzczxUPiBjbGF6eikge1xuIgorICAgICIgIFQgZGVmYXVsdEluc3RhbmNlID1cbiIKKyAgICAiICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5nZXREZWZhdWx0SW5zdGFuY2UoY2xhenopO1xuIgorICAgICIgIHJldHVybiBnZXRUeXBlVXJsKCkuZXF1YWxzKFxuIgorICAgICIgICAgICBnZXRUeXBlVXJsKGRlZmF1bHRJbnN0YW5jZS5nZXREZXNjcmlwdG9yRm9yVHlwZSgpKSk7XG4iCisgICAgIn1cbiIKKyAgICAiXG4iCisgICAgInByaXZhdGUgdm9sYXRpbGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIGNhY2hlZFVucGFja1ZhbHVlO1xuIgorICAgICJcbiIKKyAgICAicHVibGljIDxUIGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlPiBUIHVucGFjayhcbiIKKyAgICAiICAgIGphdmEubGFuZy5DbGFzczxUPiBjbGF6eilcbiIKKyAgICAiICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7XG4iCisgICAgIiAgaWYgKCFpcyhjbGF6eikpIHtcbiIKKyAgICAiICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihcbiIKKyAgICAiICAgICAgICBcIlR5cGUgb2YgdGhlIEFueSBtZXNzYWdlIGRvZXMgbm90IG1hdGNoIHRoZSBnaXZlbiBjbGFzcy5cIik7XG4iCisgICAgIiAgfVxuIgorICAgICIgIGlmIChjYWNoZWRVbnBhY2tWYWx1ZSAhPSBudWxsKSB7XG4iCisgICAgIiAgICByZXR1cm4gKFQpIGNhY2hlZFVucGFja1ZhbHVlO1xuIgorICAgICIgIH1cbiIKKyAgICAiICBUIGRlZmF1bHRJbnN0YW5jZSA9XG4iCisgICAgIiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuZ2V0RGVmYXVsdEluc3RhbmNlKGNsYXp6KTtcbiIKKyAgICAiICBUIHJlc3VsdCA9IChUKSBkZWZhdWx0SW5zdGFuY2UuZ2V0UGFyc2VyRm9yVHlwZSgpXG4iCisgICAgIiAgICAgIC5wYXJzZUZyb20oZ2V0VmFsdWUoKSk7XG4iCisgICAgIiAgY2FjaGVkVW5wYWNrVmFsdWUgPSByZXN1bHQ7XG4iCisgICAgIiAgcmV0dXJuIHJlc3VsdDtcbiIKKyAgICAifVxuIik7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbWVzc2FnZS5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbWVzc2FnZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJlNWJmYjAKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tZXNzYWdlLmgKQEAgLTAsMCArMSwxMzkgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9NRVNTQUdFX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9NRVNTQUdFX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPG1hcD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2ZpZWxkLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKyAgbmFtZXNwYWNlIGNvbXBpbGVyIHsKKyAgICBuYW1lc3BhY2UgamF2YSB7CisgICAgICBjbGFzcyBDb250ZXh0OyAgICAgICAgICAgLy8gY29udGV4dC5oCisgICAgICBjbGFzcyBDbGFzc05hbWVSZXNvbHZlcjsgLy8gbmFtZV9yZXNvbHZlci5oCisgICAgfQorICB9CisgIG5hbWVzcGFjZSBpbyB7CisgICAgY2xhc3MgUHJpbnRlcjsgICAgICAgICAgICAgLy8gcHJpbnRlci5oCisgIH0KK30KKworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YSB7CisKK2NsYXNzIE1lc3NhZ2VHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgTWVzc2FnZUdlbmVyYXRvcihjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKKyAgdmlydHVhbCB+TWVzc2FnZUdlbmVyYXRvcigpOworCisgIC8vIEFsbCBzdGF0aWMgdmFyaWFibGVzIGhhdmUgdG8gYmUgZGVjbGFyZWQgYXQgdGhlIHRvcC1sZXZlbCBvZiB0aGUgZmlsZQorICAvLyBzbyB0aGF0IHdlIGNhbiBjb250cm9sIGluaXRpYWxpemF0aW9uIG9yZGVyLCB3aGljaCBpcyBpbXBvcnRhbnQgZm9yCisgIC8vIERlc2NyaXB0b3JQcm90byBib290c3RyYXBwaW5nIHRvIHdvcmsuCisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZVN0YXRpY1ZhcmlhYmxlcyhpbzo6UHJpbnRlciogcHJpbnRlcikgPSAwOworCisgIC8vIE91dHB1dCBjb2RlIHdoaWNoIGluaXRpYWxpemVzIHRoZSBzdGF0aWMgdmFyaWFibGVzIGdlbmVyYXRlZCBieQorICAvLyBHZW5lcmF0ZVN0YXRpY1ZhcmlhYmxlcygpLiBSZXR1cm5zIGFuIGVzdGltYXRlIG9mIGJ5dGVjb2RlIHNpemUuCisgIHZpcnR1YWwgaW50IEdlbmVyYXRlU3RhdGljVmFyaWFibGVJbml0aWFsaXplcnMoaW86OlByaW50ZXIqIHByaW50ZXIpID0gMDsKKworICAvLyBHZW5lcmF0ZSB0aGUgY2xhc3MgaXRzZWxmLgorICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGUoaW86OlByaW50ZXIqIHByaW50ZXIpID0gMDsKKworICAvLyBHZW5lcmF0ZXMgdGhlIGJhc2UgaW50ZXJmYWNlIHRoYXQgYm90aCB0aGUgY2xhc3MgYW5kIGl0cyBidWlsZGVyIGltcGxlbWVudAorICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVJbnRlcmZhY2UoaW86OlByaW50ZXIqIHByaW50ZXIpID0gMDsKKworICAvLyBHZW5lcmF0ZSBjb2RlIHRvIHJlZ2lzdGVyIGFsbCBjb250YWluZWQgZXh0ZW5zaW9ucyB3aXRoIGFuCisgIC8vIEV4dGVuc2lvblJlZ2lzdHJ5LgorICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVFeHRlbnNpb25SZWdpc3RyYXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSA9IDA7CisKKyBwcm90ZWN0ZWQ6CisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKE1lc3NhZ2VHZW5lcmF0b3IpOworfTsKKworY2xhc3MgSW1tdXRhYmxlTWVzc2FnZUdlbmVyYXRvciA6IHB1YmxpYyBNZXNzYWdlR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IEltbXV0YWJsZU1lc3NhZ2VHZW5lcmF0b3IoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb250ZXh0KiBjb250ZXh0KTsKKyAgdmlydHVhbCB+SW1tdXRhYmxlTWVzc2FnZUdlbmVyYXRvcigpOworCisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZUludGVyZmFjZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZUV4dGVuc2lvblJlZ2lzdHJhdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVTdGF0aWNWYXJpYWJsZXMoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIC8vIFJldHVybnMgYW4gZXN0aW1hdGUgb2YgdGhlIG51bWJlciBvZiBieXRlcyB0aGUgcHJpbnRlZCBjb2RlIHdpbGwgY29tcGlsZSB0bworICB2aXJ0dWFsIGludCBHZW5lcmF0ZVN0YXRpY1ZhcmlhYmxlSW5pdGlhbGl6ZXJzKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworIHByaXZhdGU6CisKKyAgdm9pZCBHZW5lcmF0ZUZpZWxkQWNjZXNzb3JUYWJsZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyAgLy8gUmV0dXJucyBhbiBlc3RpbWF0ZSBvZiB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRoZSBwcmludGVkIGNvZGUgd2lsbCBjb21waWxlIHRvCisgIGludCBHZW5lcmF0ZUZpZWxkQWNjZXNzb3JUYWJsZUluaXRpYWxpemVyKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworICB2b2lkIEdlbmVyYXRlTWVzc2FnZVNlcmlhbGl6YXRpb25NZXRob2RzKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdm9pZCBHZW5lcmF0ZVBhcnNlRnJvbU1ldGhvZHMoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXplT25lRmllbGQoaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKTsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZU9uZUV4dGVuc2lvblJhbmdlKAorICAgICAgaW86OlByaW50ZXIqIHByaW50ZXIsIGNvbnN0IERlc2NyaXB0b3I6OkV4dGVuc2lvblJhbmdlKiByYW5nZSk7CisKKyAgdm9pZCBHZW5lcmF0ZUJ1aWxkZXIoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2b2lkIEdlbmVyYXRlSXNJbml0aWFsaXplZChpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZvaWQgR2VuZXJhdGVEZXNjcmlwdG9yTWV0aG9kcyhpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZvaWQgR2VuZXJhdGVJbml0aWFsaXplcnMoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2b2lkIEdlbmVyYXRlRXF1YWxzQW5kSGFzaENvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2b2lkIEdlbmVyYXRlUGFyc2VyKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdm9pZCBHZW5lcmF0ZVBhcnNpbmdDb25zdHJ1Y3Rvcihpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZvaWQgR2VuZXJhdGVBbnlNZXRob2RzKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworICBDb250ZXh0KiBjb250ZXh0XzsKKyAgQ2xhc3NOYW1lUmVzb2x2ZXIqIG5hbWVfcmVzb2x2ZXJfOworICBGaWVsZEdlbmVyYXRvck1hcDxJbW11dGFibGVGaWVsZEdlbmVyYXRvcj4gZmllbGRfZ2VuZXJhdG9yc187CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEltbXV0YWJsZU1lc3NhZ2VHZW5lcmF0b3IpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfTUVTU0FHRV9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21lc3NhZ2VfYnVpbGRlci5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21lc3NhZ2VfYnVpbGRlci5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ZDUzNTAzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbWVzc2FnZV9idWlsZGVyLmNjCkBAIC0wLDAgKzEsNjYxIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBkd2Vpc0Bnb29nbGUuY29tIChEYW5pZWwgV2VpcykKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tZXNzYWdlX2J1aWxkZXIuaD4KKworI2luY2x1ZGUgPGFsZ29yaXRobT4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvaGFzaC5oPgorI2luY2x1ZGUgPG1hcD4KKyNpbmNsdWRlIDxtZW1vcnk+CisjaWZuZGVmIF9TSEFSRURfUFRSX0gKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc2hhcmVkX3B0ci5oPgorI2VuZGlmCisjaW5jbHVkZSA8dmVjdG9yPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9jb250ZXh0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9kb2NfY29tbWVudC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZW51bS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZXh0ZW5zaW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9nZW5lcmF0b3JfZmFjdG9yeS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfaGVscGVycy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbmFtZV9yZXNvbHZlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3Vic3RpdHV0ZS5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmEgeworCituYW1lc3BhY2UgeworYm9vbCBHZW5lcmF0ZUhhc0JpdHMoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICByZXR1cm4gU3VwcG9ydEZpZWxkUHJlc2VuY2UoZGVzY3JpcHRvci0+ZmlsZSgpKSB8fAorICAgICAgSGFzUmVwZWF0ZWRGaWVsZHMoZGVzY3JpcHRvcik7Cit9CisKK3N0cmluZyBNYXBWYWx1ZUltbXV0YWJsZUNsYXNzZE5hbWUoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3NOYW1lUmVzb2x2ZXIqIG5hbWVfcmVzb2x2ZXIpIHsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiB2YWx1ZV9maWVsZCA9IGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgidmFsdWUiKTsKKyAgR09PR0xFX0NIRUNLX0VRKEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9NRVNTQUdFLCB2YWx1ZV9maWVsZC0+dHlwZSgpKTsKKyAgcmV0dXJuIG5hbWVfcmVzb2x2ZXItPkdldEltbXV0YWJsZUNsYXNzTmFtZSh2YWx1ZV9maWVsZC0+bWVzc2FnZV90eXBlKCkpOworfQorfSAgLy8gbmFtZXNwYWNlCisKK01lc3NhZ2VCdWlsZGVyR2VuZXJhdG9yOjpNZXNzYWdlQnVpbGRlckdlbmVyYXRvcigKKyAgICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBDb250ZXh0KiBjb250ZXh0KQorICA6IGRlc2NyaXB0b3JfKGRlc2NyaXB0b3IpLCBjb250ZXh0Xyhjb250ZXh0KSwKKyAgICBuYW1lX3Jlc29sdmVyXyhjb250ZXh0LT5HZXROYW1lUmVzb2x2ZXIoKSksCisgICAgZmllbGRfZ2VuZXJhdG9yc18oZGVzY3JpcHRvciwgY29udGV4dF8pIHsKKyAgR09PR0xFX0NIRUNLX05FKAorICAgICAgRmlsZU9wdGlvbnM6OkxJVEVfUlVOVElNRSwgZGVzY3JpcHRvci0+ZmlsZSgpLT5vcHRpb25zKCkub3B0aW1pemVfZm9yKCkpOworfQorCitNZXNzYWdlQnVpbGRlckdlbmVyYXRvcjo6fk1lc3NhZ2VCdWlsZGVyR2VuZXJhdG9yKCkge30KKwordm9pZCBNZXNzYWdlQnVpbGRlckdlbmVyYXRvcjo6CitHZW5lcmF0ZShpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBXcml0ZU1lc3NhZ2VEb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgaWYgKGRlc2NyaXB0b3JfLT5leHRlbnNpb25fcmFuZ2VfY291bnQoKSA+IDApIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kc1xuIgorICAgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuRXh0ZW5kYWJsZUJ1aWxkZXI8XG4iCisgICAgICAiICAgICAgJGNsYXNzbmFtZSQsIEJ1aWxkZXI+IGltcGxlbWVudHNcbiIKKyAgICAgICIgICAgJGV4dHJhX2ludGVyZmFjZXMkXG4iCisgICAgICAiICAgICRjbGFzc25hbWUkT3JCdWlsZGVyIHtcbiIsCisgICAgICAiY2xhc3NuYW1lIiwgbmFtZV9yZXNvbHZlcl8tPkdldEltbXV0YWJsZUNsYXNzTmFtZShkZXNjcmlwdG9yXyksCisgICAgICAiZXh0cmFfaW50ZXJmYWNlcyIsIEV4dHJhQnVpbGRlckludGVyZmFjZXMoZGVzY3JpcHRvcl8pKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kc1xuIgorICAgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzXG4iCisgICAgICAiICAgICRleHRyYV9pbnRlcmZhY2VzJFxuIgorICAgICAgIiAgICAkY2xhc3NuYW1lJE9yQnVpbGRlciB7XG4iLAorICAgICAgImNsYXNzbmFtZSIsIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcl8pLAorICAgICAgImV4dHJhX2ludGVyZmFjZXMiLCBFeHRyYUJ1aWxkZXJJbnRlcmZhY2VzKGRlc2NyaXB0b3JfKSk7CisgIH0KKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgR2VuZXJhdGVEZXNjcmlwdG9yTWV0aG9kcyhwcmludGVyKTsKKyAgR2VuZXJhdGVDb21tb25CdWlsZGVyTWV0aG9kcyhwcmludGVyKTsKKworICBpZiAoSGFzR2VuZXJhdGVkTWV0aG9kcyhkZXNjcmlwdG9yXykpIHsKKyAgICBHZW5lcmF0ZUlzSW5pdGlhbGl6ZWQocHJpbnRlcik7CisgICAgR2VuZXJhdGVCdWlsZGVyUGFyc2luZ01ldGhvZHMocHJpbnRlcik7CisgIH0KKworICAvLyBvbmVvZgorICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcnM7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2xfY291bnQoKTsgaSsrKSB7CisgICAgdmFyc1sib25lb2ZfbmFtZSJdID0gY29udGV4dF8tPkdldE9uZW9mR2VuZXJhdG9ySW5mbygKKyAgICAgICAgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSkpLT5uYW1lOworICAgIHZhcnNbIm9uZW9mX2NhcGl0YWxpemVkX25hbWUiXSA9IGNvbnRleHRfLT5HZXRPbmVvZkdlbmVyYXRvckluZm8oCisgICAgICAgIGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpKS0+Y2FwaXRhbGl6ZWRfbmFtZTsKKyAgICB2YXJzWyJvbmVvZl9pbmRleCJdID0gU2ltcGxlSXRvYShkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKS0+aW5kZXgoKSk7CisgICAgLy8gb25lb2ZDYXNlXyBhbmQgb25lb2ZfCisgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICJwcml2YXRlIGludCAkb25lb2ZfbmFtZSRDYXNlXyA9IDA7XG4iCisgICAgICAicHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0ICRvbmVvZl9uYW1lJF87XG4iKTsKKyAgICAvLyBvbmVvZkNhc2UoKSBhbmQgY2xlYXJPbmVvZigpCisgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICJwdWJsaWMgJG9uZW9mX2NhcGl0YWxpemVkX25hbWUkQ2FzZVxuIgorICAgICAgIiAgICBnZXQkb25lb2ZfY2FwaXRhbGl6ZWRfbmFtZSRDYXNlKCkge1xuIgorICAgICAgIiAgcmV0dXJuICRvbmVvZl9jYXBpdGFsaXplZF9uYW1lJENhc2UudmFsdWVPZihcbiIKKyAgICAgICIgICAgICAkb25lb2ZfbmFtZSRDYXNlXyk7XG4iCisgICAgICAifVxuIgorICAgICAgIlxuIgorICAgICAgInB1YmxpYyBCdWlsZGVyIGNsZWFyJG9uZW9mX2NhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICAgIiAgJG9uZW9mX25hbWUkQ2FzZV8gPSAwO1xuIgorICAgICAgIiAgJG9uZW9mX25hbWUkXyA9IG51bGw7XG4iKTsKKyAgICBwcmludGVyLT5QcmludCgiICBvbkNoYW5nZWQoKTtcbiIpOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgICAifVxuIgorICAgICAgIlxuIik7CisgIH0KKworICBpZiAoR2VuZXJhdGVIYXNCaXRzKGRlc2NyaXB0b3JfKSkgeworICAgIC8vIEludGVnZXJzIGZvciBiaXQgZmllbGRzLgorICAgIGludCB0b3RhbEJpdHMgPSAwOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgICAgdG90YWxCaXRzICs9IGZpZWxkX2dlbmVyYXRvcnNfLmdldChkZXNjcmlwdG9yXy0+ZmllbGQoaSkpCisgICAgICAgICAgLkdldE51bUJpdHNGb3JCdWlsZGVyKCk7CisgICAgfQorICAgIGludCB0b3RhbEludHMgPSAodG90YWxCaXRzICsgMzEpIC8gMzI7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0b3RhbEludHM7IGkrKykgeworICAgICAgcHJpbnRlci0+UHJpbnQoInByaXZhdGUgaW50ICRiaXRfZmllbGRfbmFtZSQ7XG4iLAorICAgICAgICAiYml0X2ZpZWxkX25hbWUiLCBHZXRCaXRGaWVsZE5hbWUoaSkpOworICAgIH0KKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIHByaW50ZXItPlByaW50KCJcbiIpOworICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChkZXNjcmlwdG9yXy0+ZmllbGQoaSkpCisgICAgICAgICAgICAgICAgICAgICAuR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhwcmludGVyKTsKKyAgfQorCisgIGlmICghUHJlc2VydmVVbmtub3duRmllbGRzKGRlc2NyaXB0b3JfKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgInB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoXG4iCisgICAgICAiICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHtcbiIKKyAgICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICAgIn1cbiIKKyAgICAgICJcbiIKKyAgICAgICJwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoXG4iCisgICAgICAiICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHtcbiIKKyAgICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICAgIn1cbiIKKyAgICAgICJcbiIpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIlxuIgorICAgICIvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTokZnVsbF9uYW1lJClcbiIsCisgICAgImZ1bGxfbmFtZSIsIGRlc2NyaXB0b3JfLT5mdWxsX25hbWUoKSk7CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgifVxuIik7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKwordm9pZCBNZXNzYWdlQnVpbGRlckdlbmVyYXRvcjo6CitHZW5lcmF0ZURlc2NyaXB0b3JNZXRob2RzKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIGlmICghZGVzY3JpcHRvcl8tPm9wdGlvbnMoKS5ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yKCkpIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvclxuIgorICAgICAgIiAgICBnZXREZXNjcmlwdG9yKCkge1xuIgorICAgICAgIiAgcmV0dXJuICRmaWxlY2xhc3MkLmludGVybmFsXyRpZGVudGlmaWVyJF9kZXNjcmlwdG9yO1xuIgorICAgICAgIn1cbiIKKyAgICAgICJcbiIsCisgICAgICAiZmlsZWNsYXNzIiwgbmFtZV9yZXNvbHZlcl8tPkdldEltbXV0YWJsZUNsYXNzTmFtZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSwKKyAgICAgICJpZGVudGlmaWVyIiwgVW5pcXVlRmlsZVNjb3BlSWRlbnRpZmllcihkZXNjcmlwdG9yXykpOworICB9CisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBtYXBfZmllbGRzOworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvcl8tPmZpZWxkKGkpOworICAgIGlmIChHZXRKYXZhVHlwZShmaWVsZCkgPT0gSkFWQVRZUEVfTUVTU0FHRSAmJgorICAgICAgICBJc01hcEVudHJ5KGZpZWxkLT5tZXNzYWdlX3R5cGUoKSkpIHsKKyAgICAgIG1hcF9maWVsZHMucHVzaF9iYWNrKGZpZWxkKTsKKyAgICB9CisgIH0KKyAgaWYgKCFtYXBfZmllbGRzLmVtcHR5KCkpIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJAU3VwcHJlc3NXYXJuaW5ncyh7XCJyYXd0eXBlc1wifSlcbiIKKyAgICAgICJwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZCBpbnRlcm5hbEdldE1hcEZpZWxkKFxuIgorICAgICAgIiAgICBpbnQgbnVtYmVyKSB7XG4iCisgICAgICAiICBzd2l0Y2ggKG51bWJlcikge1xuIik7CisgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtYXBfZmllbGRzLnNpemUoKTsgKytpKSB7CisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gbWFwX2ZpZWxkc1tpXTsKKyAgICAgIGNvbnN0IEZpZWxkR2VuZXJhdG9ySW5mbyogaW5mbyA9IGNvbnRleHRfLT5HZXRGaWVsZEdlbmVyYXRvckluZm8oZmllbGQpOworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJjYXNlICRudW1iZXIkOlxuIgorICAgICAgICAiICByZXR1cm4gaW50ZXJuYWxHZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKTtcbiIsCisgICAgICAgICJudW1iZXIiLCBTaW1wbGVJdG9hKGZpZWxkLT5udW1iZXIoKSksCisgICAgICAgICJjYXBpdGFsaXplZF9uYW1lIiwgaW5mby0+Y2FwaXRhbGl6ZWRfbmFtZSk7CisgICAgfQorICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiZGVmYXVsdDpcbiIKKyAgICAgICAgIiAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oXG4iCisgICAgICAgICIgICAgICBcIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogXCIgKyBudW1iZXIpO1xuIik7CisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIiAgfVxuIgorICAgICAgICAifVxuIik7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiQFN1cHByZXNzV2FybmluZ3Moe1wicmF3dHlwZXNcIn0pXG4iCisgICAgICAicHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRmllbGQoXG4iCisgICAgICAiICAgIGludCBudW1iZXIpIHtcbiIKKyAgICAgICIgIHN3aXRjaCAobnVtYmVyKSB7XG4iKTsKKyAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IG1hcF9maWVsZHMuc2l6ZSgpOyArK2kpIHsKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBtYXBfZmllbGRzW2ldOworICAgICAgY29uc3QgRmllbGRHZW5lcmF0b3JJbmZvKiBpbmZvID0KKyAgICAgICAgICBjb250ZXh0Xy0+R2V0RmllbGRHZW5lcmF0b3JJbmZvKGZpZWxkKTsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiY2FzZSAkbnVtYmVyJDpcbiIKKyAgICAgICAgIiAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZSRjYXBpdGFsaXplZF9uYW1lJCgpO1xuIiwKKyAgICAgICAgIm51bWJlciIsIFNpbXBsZUl0b2EoZmllbGQtPm51bWJlcigpKSwKKyAgICAgICAgImNhcGl0YWxpemVkX25hbWUiLCBpbmZvLT5jYXBpdGFsaXplZF9uYW1lKTsKKyAgICB9CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJkZWZhdWx0OlxuIgorICAgICAgICAiICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihcbiIKKyAgICAgICAgIiAgICAgIFwiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiBcIiArIG51bWJlcik7XG4iKTsKKyAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiICB9XG4iCisgICAgICAgICJ9XG4iKTsKKyAgfQorICBwcmludGVyLT5QcmludCgKKyAgICAicHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5GaWVsZEFjY2Vzc29yVGFibGVcbiIKKyAgICAiICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkge1xuIgorICAgICIgIHJldHVybiAkZmlsZWNsYXNzJC5pbnRlcm5hbF8kaWRlbnRpZmllciRfZmllbGRBY2Nlc3NvclRhYmxlXG4iCisgICAgIiAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKFxuIgorICAgICIgICAgICAgICAgJGNsYXNzbmFtZSQuY2xhc3MsICRjbGFzc25hbWUkLkJ1aWxkZXIuY2xhc3MpO1xuIgorICAgICJ9XG4iCisgICAgIlxuIiwKKyAgICAiY2xhc3NuYW1lIiwgbmFtZV9yZXNvbHZlcl8tPkdldEltbXV0YWJsZUNsYXNzTmFtZShkZXNjcmlwdG9yXyksCisgICAgImZpbGVjbGFzcyIsIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcl8tPmZpbGUoKSksCisgICAgImlkZW50aWZpZXIiLCBVbmlxdWVGaWxlU2NvcGVJZGVudGlmaWVyKGRlc2NyaXB0b3JfKSk7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKwordm9pZCBNZXNzYWdlQnVpbGRlckdlbmVyYXRvcjo6CitHZW5lcmF0ZUNvbW1vbkJ1aWxkZXJNZXRob2RzKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgICAgIi8vIENvbnN0cnVjdCB1c2luZyAkY2xhc3NuYW1lJC5uZXdCdWlsZGVyKClcbiIKKyAgICAgICJwcml2YXRlIEJ1aWxkZXIoKSB7XG4iCisgICAgICAiICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7XG4iCisgICAgICAifVxuIgorICAgICAgIlxuIiwKKyAgICAgICJjbGFzc25hbWUiLCBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3JfKSk7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgInByaXZhdGUgQnVpbGRlcihcbiIKKyAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5CdWlsZGVyUGFyZW50IHBhcmVudCkge1xuIgorICAgICIgIHN1cGVyKHBhcmVudCk7XG4iCisgICAgIiAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpO1xuIgorICAgICJ9XG4iLAorICAgICJjbGFzc25hbWUiLCBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3JfKSk7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgInByaXZhdGUgdm9pZCBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCkge1xuIgorICAgICIgIGlmIChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuYWx3YXlzVXNlRmllbGRCdWlsZGVycykge1xuIik7CisKKyAgcHJpbnRlci0+SW5kZW50KCk7CisgIHByaW50ZXItPkluZGVudCgpOworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBpZiAoIWRlc2NyaXB0b3JfLT5maWVsZChpKS0+Y29udGFpbmluZ19vbmVvZigpKSB7CisgICAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZGVzY3JpcHRvcl8tPmZpZWxkKGkpKQorICAgICAgICAgIC5HZW5lcmF0ZUZpZWxkQnVpbGRlckluaXRpYWxpemF0aW9uQ29kZShwcmludGVyKTsKKyAgICB9CisgIH0KKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5PdXRkZW50KCk7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIiAgfVxuIgorICAgICJ9XG4iKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAicHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7XG4iCisgICAgIiAgc3VwZXIuY2xlYXIoKTtcbiIpOworCisgIHByaW50ZXItPkluZGVudCgpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGlmICghZGVzY3JpcHRvcl8tPmZpZWxkKGkpLT5jb250YWluaW5nX29uZW9mKCkpIHsKKyAgICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChkZXNjcmlwdG9yXy0+ZmllbGQoaSkpCisgICAgICAgICAgLkdlbmVyYXRlQnVpbGRlckNsZWFyQ29kZShwcmludGVyKTsKKyAgICB9CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsX2NvdW50KCk7IGkrKykgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIiRvbmVvZl9uYW1lJENhc2VfID0gMDtcbiIKKyAgICAgICIkb25lb2ZfbmFtZSRfID0gbnVsbDtcbiIsCisgICAgICAib25lb2ZfbmFtZSIsIGNvbnRleHRfLT5HZXRPbmVvZkdlbmVyYXRvckluZm8oCisgICAgICAgICAgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSkpLT5uYW1lKTsKKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIgorICAgICJcbiIpOworCisgIHByaW50ZXItPlByaW50KAorICAgICJwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yXG4iCisgICAgIiAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHtcbiIKKyAgICAiICByZXR1cm4gJGZpbGVjbGFzcyQuaW50ZXJuYWxfJGlkZW50aWZpZXIkX2Rlc2NyaXB0b3I7XG4iCisgICAgIn1cbiIKKyAgICAiXG4iLAorICAgICJmaWxlY2xhc3MiLCBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3JfLT5maWxlKCkpLAorICAgICJpZGVudGlmaWVyIiwgVW5pcXVlRmlsZVNjb3BlSWRlbnRpZmllcihkZXNjcmlwdG9yXykpOworCisgIC8vIExJVEUgcnVudGltZSBpbXBsZW1lbnRzIHRoaXMgaW4gR2VuZXJhdGVkTWVzc2FnZUxpdGUuCisgIHByaW50ZXItPlByaW50KAorICAgICJwdWJsaWMgJGNsYXNzbmFtZSQgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHtcbiIKKyAgICAiICByZXR1cm4gJGNsYXNzbmFtZSQuZ2V0RGVmYXVsdEluc3RhbmNlKCk7XG4iCisgICAgIn1cbiIKKyAgICAiXG4iLAorICAgICJjbGFzc25hbWUiLCBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3JfKSk7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgInB1YmxpYyAkY2xhc3NuYW1lJCBidWlsZCgpIHtcbiIKKyAgICAiICAkY2xhc3NuYW1lJCByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTtcbiIKKyAgICAiICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHtcbiIKKyAgICAiICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7XG4iCisgICAgIiAgfVxuIgorICAgICIgIHJldHVybiByZXN1bHQ7XG4iCisgICAgIn1cbiIKKyAgICAiXG4iLAorICAgICJjbGFzc25hbWUiLCBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3JfKSk7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgInB1YmxpYyAkY2xhc3NuYW1lJCBidWlsZFBhcnRpYWwoKSB7XG4iCisgICAgIiAgJGNsYXNzbmFtZSQgcmVzdWx0ID0gbmV3ICRjbGFzc25hbWUkKHRoaXMpO1xuIiwKKyAgICAiY2xhc3NuYW1lIiwgbmFtZV9yZXNvbHZlcl8tPkdldEltbXV0YWJsZUNsYXNzTmFtZShkZXNjcmlwdG9yXykpOworCisgIHByaW50ZXItPkluZGVudCgpOworCisgIGludCB0b3RhbEJ1aWxkZXJCaXRzID0gMDsKKyAgaW50IHRvdGFsTWVzc2FnZUJpdHMgPSAwOworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBJbW11dGFibGVGaWVsZEdlbmVyYXRvciYgZmllbGQgPQorICAgICAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZGVzY3JpcHRvcl8tPmZpZWxkKGkpKTsKKyAgICB0b3RhbEJ1aWxkZXJCaXRzICs9IGZpZWxkLkdldE51bUJpdHNGb3JCdWlsZGVyKCk7CisgICAgdG90YWxNZXNzYWdlQml0cyArPSBmaWVsZC5HZXROdW1CaXRzRm9yTWVzc2FnZSgpOworICB9CisgIGludCB0b3RhbEJ1aWxkZXJJbnRzID0gKHRvdGFsQnVpbGRlckJpdHMgKyAzMSkgLyAzMjsKKyAgaW50IHRvdGFsTWVzc2FnZUludHMgPSAodG90YWxNZXNzYWdlQml0cyArIDMxKSAvIDMyOworCisgIGlmIChHZW5lcmF0ZUhhc0JpdHMoZGVzY3JpcHRvcl8pKSB7CisgICAgLy8gTG9jYWwgdmFycyBmb3IgZnJvbSBhbmQgdG8gYml0IGZpZWxkcyB0byBhdm9pZCBhY2Nlc3NpbmcgdGhlIGJ1aWxkZXIgYW5kCisgICAgLy8gbWVzc2FnZSBvdmVyIGFuZCBvdmVyIGZvciB0aGVzZSBmaWVsZHMuIFNlZW1zIHRvIHByb3ZpZGUgYSBzbGlnaHQKKyAgICAvLyBwZXJmb3JhbWFuY2UgaW1wcm92ZW1lbnQgaW4gbWljcm8gYmVuY2htYXJrIGFuZCB0aGlzIGlzIGFsc28gd2hhdCBwcm90bzEKKyAgICAvLyBjb2RlIGRvZXMuCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0b3RhbEJ1aWxkZXJJbnRzOyBpKyspIHsKKyAgICAgIHByaW50ZXItPlByaW50KCJpbnQgZnJvbV8kYml0X2ZpZWxkX25hbWUkID0gJGJpdF9maWVsZF9uYW1lJDtcbiIsCisgICAgICAgICJiaXRfZmllbGRfbmFtZSIsIEdldEJpdEZpZWxkTmFtZShpKSk7CisgICAgfQorICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdG90YWxNZXNzYWdlSW50czsgaSsrKSB7CisgICAgICBwcmludGVyLT5QcmludCgiaW50IHRvXyRiaXRfZmllbGRfbmFtZSQgPSAwO1xuIiwKKyAgICAgICAgImJpdF9maWVsZF9uYW1lIiwgR2V0Qml0RmllbGROYW1lKGkpKTsKKyAgICB9CisgIH0KKworICAvLyBPdXRwdXQgZ2VuZXJhdGlvbiBjb2RlIGZvciBlYWNoIGZpZWxkLgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZGVzY3JpcHRvcl8tPmZpZWxkKGkpKS5HZW5lcmF0ZUJ1aWxkaW5nQ29kZShwcmludGVyKTsKKyAgfQorCisgIGlmIChHZW5lcmF0ZUhhc0JpdHMoZGVzY3JpcHRvcl8pKSB7CisgICAgLy8gQ29weSB0aGUgYml0IGZpZWxkIHJlc3VsdHMgdG8gdGhlIGdlbmVyYXRlZCBtZXNzYWdlCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0b3RhbE1lc3NhZ2VJbnRzOyBpKyspIHsKKyAgICAgIHByaW50ZXItPlByaW50KCJyZXN1bHQuJGJpdF9maWVsZF9uYW1lJCA9IHRvXyRiaXRfZmllbGRfbmFtZSQ7XG4iLAorICAgICAgICAiYml0X2ZpZWxkX25hbWUiLCBHZXRCaXRGaWVsZE5hbWUoaSkpOworICAgIH0KKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2xfY291bnQoKTsgaSsrKSB7CisgICAgcHJpbnRlci0+UHJpbnQoInJlc3VsdC4kb25lb2ZfbmFtZSRDYXNlXyA9ICRvbmVvZl9uYW1lJENhc2VfO1xuIiwKKyAgICAgICAgICAgICAgICAgICAib25lb2ZfbmFtZSIsIGNvbnRleHRfLT5HZXRPbmVvZkdlbmVyYXRvckluZm8oCisgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpKS0+bmFtZSk7CisgIH0KKworICBwcmludGVyLT5PdXRkZW50KCk7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIiAgb25CdWlsdCgpO1xuIik7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIiAgcmV0dXJuIHJlc3VsdDtcbiIKKyAgICAifVxuIgorICAgICJcbiIsCisgICAgImNsYXNzbmFtZSIsIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcl8pKTsKKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIGlmIChIYXNHZW5lcmF0ZWRNZXRob2RzKGRlc2NyaXB0b3JfKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgInB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHtcbiIKKyAgICAgICIgIGlmIChvdGhlciBpbnN0YW5jZW9mICRjbGFzc25hbWUkKSB7XG4iCisgICAgICAiICAgIHJldHVybiBtZXJnZUZyb20oKCRjbGFzc25hbWUkKW90aGVyKTtcbiIKKyAgICAgICIgIH0gZWxzZSB7XG4iCisgICAgICAiICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7XG4iCisgICAgICAiICAgIHJldHVybiB0aGlzO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIn1cbiIKKyAgICAgICJcbiIsCisgICAgICAiY2xhc3NuYW1lIiwgbmFtZV9yZXNvbHZlcl8tPkdldEltbXV0YWJsZUNsYXNzTmFtZShkZXNjcmlwdG9yXykpOworCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAicHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKCRjbGFzc25hbWUkIG90aGVyKSB7XG4iCisgICAgICAvLyBPcHRpbWl6YXRpb246ICBJZiBvdGhlciBpcyB0aGUgZGVmYXVsdCBpbnN0YW5jZSwgd2Uga25vdyBub25lIG9mIGl0cworICAgICAgLy8gICBmaWVsZHMgYXJlIHNldCBzbyB3ZSBjYW4gc2tpcCB0aGUgbWVyZ2UuCisgICAgICAiICBpZiAob3RoZXIgPT0gJGNsYXNzbmFtZSQuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzO1xuIiwKKyAgICAgICJjbGFzc25hbWUiLCBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3JfKSk7CisgICAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICAgIGlmICghZGVzY3JpcHRvcl8tPmZpZWxkKGkpLT5jb250YWluaW5nX29uZW9mKCkpIHsKKyAgICAgICAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KAorICAgICAgICAgICAgZGVzY3JpcHRvcl8tPmZpZWxkKGkpKS5HZW5lcmF0ZU1lcmdpbmdDb2RlKHByaW50ZXIpOworICAgICAgfQorICAgIH0KKworICAgIC8vIE1lcmdlIG9uZW9mIGZpZWxkcy4KKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsX2NvdW50KCk7ICsraSkgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJzd2l0Y2ggKG90aGVyLmdldCRvbmVvZl9jYXBpdGFsaXplZF9uYW1lJENhc2UoKSkge1xuIiwKKyAgICAgICAgIm9uZW9mX2NhcGl0YWxpemVkX25hbWUiLAorICAgICAgICBjb250ZXh0Xy0+R2V0T25lb2ZHZW5lcmF0b3JJbmZvKAorICAgICAgICAgICAgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSkpLT5jYXBpdGFsaXplZF9uYW1lKTsKKyAgICAgIHByaW50ZXItPkluZGVudCgpOworICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKS0+ZmllbGRfY291bnQoKTsgaisrKSB7CisgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKS0+ZmllbGQoaik7CisgICAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICJjYXNlICRmaWVsZF9uYW1lJDoge1xuIiwKKyAgICAgICAgICAiZmllbGRfbmFtZSIsCisgICAgICAgICAgVG9VcHBlcihmaWVsZC0+bmFtZSgpKSk7CisgICAgICAgIHByaW50ZXItPkluZGVudCgpOworICAgICAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZmllbGQpLkdlbmVyYXRlTWVyZ2luZ0NvZGUocHJpbnRlcik7CisgICAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICAgImJyZWFrO1xuIik7CisgICAgICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgICAifVxuIik7CisgICAgICB9CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgImNhc2UgJGNhcF9vbmVvZl9uYW1lJF9OT1RfU0VUOiB7XG4iCisgICAgICAgICIgIGJyZWFrO1xuIgorICAgICAgICAifVxuIiwKKyAgICAgICAgImNhcF9vbmVvZl9uYW1lIiwKKyAgICAgICAgVG9VcHBlcihjb250ZXh0Xy0+R2V0T25lb2ZHZW5lcmF0b3JJbmZvKAorICAgICAgICAgICAgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSkpLT5uYW1lKSk7CisgICAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAifVxuIik7CisgICAgfQorCisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworCisgICAgLy8gaWYgbWVzc2FnZSB0eXBlIGhhcyBleHRlbnNpb25zCisgICAgaWYgKGRlc2NyaXB0b3JfLT5leHRlbnNpb25fcmFuZ2VfY291bnQoKSA+IDApIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiICB0aGlzLm1lcmdlRXh0ZW5zaW9uRmllbGRzKG90aGVyKTtcbiIpOworICAgIH0KKworICAgIGlmIChQcmVzZXJ2ZVVua25vd25GaWVsZHMoZGVzY3JpcHRvcl8pKSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIiAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIudW5rbm93bkZpZWxkcyk7XG4iKTsKKyAgICB9CisKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICIgIG9uQ2hhbmdlZCgpO1xuIik7CisKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICAgIn1cbiIKKyAgICAgICJcbiIpOworICB9Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKwordm9pZCBNZXNzYWdlQnVpbGRlckdlbmVyYXRvcjo6CitHZW5lcmF0ZUJ1aWxkZXJQYXJzaW5nTWV0aG9kcyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICAicHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKFxuIgorICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LFxuIgorICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpXG4iCisgICAgIiAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7XG4iCisgICAgIiAgJGNsYXNzbmFtZSQgcGFyc2VkTWVzc2FnZSA9IG51bGw7XG4iCisgICAgIiAgdHJ5IHtcbiIKKyAgICAiICAgIHBhcnNlZE1lc3NhZ2UgPSBQQVJTRVIucGFyc2VQYXJ0aWFsRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpO1xuIgorICAgICIgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHtcbiIKKyAgICAiICAgIHBhcnNlZE1lc3NhZ2UgPSAoJGNsYXNzbmFtZSQpIGUuZ2V0VW5maW5pc2hlZE1lc3NhZ2UoKTtcbiIKKyAgICAiICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTtcbiIKKyAgICAiICB9IGZpbmFsbHkge1xuIgorICAgICIgICAgaWYgKHBhcnNlZE1lc3NhZ2UgIT0gbnVsbCkge1xuIgorICAgICIgICAgICBtZXJnZUZyb20ocGFyc2VkTWVzc2FnZSk7XG4iCisgICAgIiAgICB9XG4iCisgICAgIiAgfVxuIgorICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICJ9XG4iLAorICAgICJjbGFzc25hbWUiLCBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3JfKSk7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKwordm9pZCBNZXNzYWdlQnVpbGRlckdlbmVyYXRvcjo6R2VuZXJhdGVJc0luaXRpYWxpemVkKAorICAgIGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgICJwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkge1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIC8vIENoZWNrIHRoYXQgYWxsIHJlcXVpcmVkIGZpZWxkcyBpbiB0aGlzIG1lc3NhZ2UgYXJlIHNldC4KKyAgLy8gVE9ETyhrZW50b24pOiAgV2UgY2FuIG9wdGltaXplIHRoaXMgd2hlbiB3ZSBzd2l0Y2ggdG8gcHV0dGluZyBhbGwgdGhlCisgIC8vICAgImhhcyIgZmllbGRzIGludG8gYSBzaW5nbGUgYml0ZmllbGQuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBkZXNjcmlwdG9yXy0+ZmllbGQoaSk7CisgICAgY29uc3QgRmllbGRHZW5lcmF0b3JJbmZvKiBpbmZvID0gY29udGV4dF8tPkdldEZpZWxkR2VuZXJhdG9ySW5mbyhmaWVsZCk7CisKKyAgICBpZiAoZmllbGQtPmlzX3JlcXVpcmVkKCkpIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiaWYgKCFoYXMkbmFtZSQoKSkge1xuIgorICAgICAgICAiICByZXR1cm4gZmFsc2U7XG4iCisgICAgICAgICJ9XG4iLAorICAgICAgICAibmFtZSIsIGluZm8tPmNhcGl0YWxpemVkX25hbWUpOworICAgIH0KKyAgfQorCisgIC8vIE5vdyBjaGVjayB0aGF0IGFsbCBlbWJlZGRlZCBtZXNzYWdlcyBhcmUgaW5pdGlhbGl6ZWQuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBkZXNjcmlwdG9yXy0+ZmllbGQoaSk7CisgICAgY29uc3QgRmllbGRHZW5lcmF0b3JJbmZvKiBpbmZvID0gY29udGV4dF8tPkdldEZpZWxkR2VuZXJhdG9ySW5mbyhmaWVsZCk7CisgICAgaWYgKEdldEphdmFUeXBlKGZpZWxkKSA9PSBKQVZBVFlQRV9NRVNTQUdFICYmCisgICAgICAgIEhhc1JlcXVpcmVkRmllbGRzKGZpZWxkLT5tZXNzYWdlX3R5cGUoKSkpIHsKKyAgICAgIHN3aXRjaCAoZmllbGQtPmxhYmVsKCkpIHsKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkxBQkVMX1JFUVVJUkVEOgorICAgICAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICAgImlmICghZ2V0JG5hbWUkKCkuaXNJbml0aWFsaXplZCgpKSB7XG4iCisgICAgICAgICAgICAgIiAgcmV0dXJuIGZhbHNlO1xuIgorICAgICAgICAgICAgICJ9XG4iLAorICAgICAgICAgICAgInR5cGUiLCBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKAorICAgICAgICAgICAgICAgIGZpZWxkLT5tZXNzYWdlX3R5cGUoKSksCisgICAgICAgICAgICAibmFtZSIsIGluZm8tPmNhcGl0YWxpemVkX25hbWUpOworICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6TEFCRUxfT1BUSU9OQUw6CisgICAgICAgICAgaWYgKCFTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSAmJgorICAgICAgICAgICAgICBmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpICE9IE5VTEwpIHsKKyAgICAgICAgICAgIGNvbnN0IE9uZW9mRGVzY3JpcHRvciogb25lb2YgPSBmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpOworICAgICAgICAgICAgY29uc3QgT25lb2ZHZW5lcmF0b3JJbmZvKiBvbmVvZl9pbmZvID0KKyAgICAgICAgICAgICAgICBjb250ZXh0Xy0+R2V0T25lb2ZHZW5lcmF0b3JJbmZvKG9uZW9mKTsKKyAgICAgICAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICAgICAiaWYgKCRvbmVvZl9uYW1lJENhc2VfID09ICRmaWVsZF9udW1iZXIkKSB7XG4iLAorICAgICAgICAgICAgICAib25lb2ZfbmFtZSIsIG9uZW9mX2luZm8tPm5hbWUsCisgICAgICAgICAgICAgICJmaWVsZF9udW1iZXIiLCBTaW1wbGVJdG9hKGZpZWxkLT5udW1iZXIoKSkpOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAgICAgImlmIChoYXMkbmFtZSQoKSkge1xuIiwKKyAgICAgICAgICAgICAgIm5hbWUiLCBpbmZvLT5jYXBpdGFsaXplZF9uYW1lKTsKKyAgICAgICAgICB9CisgICAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgICAiICBpZiAoIWdldCRuYW1lJCgpLmlzSW5pdGlhbGl6ZWQoKSkge1xuIgorICAgICAgICAgICAgIiAgICByZXR1cm4gZmFsc2U7XG4iCisgICAgICAgICAgICAiICB9XG4iCisgICAgICAgICAgICAifVxuIiwKKyAgICAgICAgICAgICJuYW1lIiwgaW5mby0+Y2FwaXRhbGl6ZWRfbmFtZSk7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpMQUJFTF9SRVBFQVRFRDoKKyAgICAgICAgICBpZiAoSXNNYXBFbnRyeShmaWVsZC0+bWVzc2FnZV90eXBlKCkpKSB7CisgICAgICAgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAgICAgImZvciAoJHR5cGUkIGl0ZW0gOiBnZXQkbmFtZSQoKS52YWx1ZXMoKSkge1xuIgorICAgICAgICAgICAgICAiICBpZiAoIWl0ZW0uaXNJbml0aWFsaXplZCgpKSB7XG4iCisgICAgICAgICAgICAgICIgICAgcmV0dXJuIGZhbHNlO1xuIgorICAgICAgICAgICAgICAiICB9XG4iCisgICAgICAgICAgICAgICJ9XG4iLAorICAgICAgICAgICAgICAidHlwZSIsIE1hcFZhbHVlSW1tdXRhYmxlQ2xhc3NkTmFtZShmaWVsZC0+bWVzc2FnZV90eXBlKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVfcmVzb2x2ZXJfKSwKKyAgICAgICAgICAgICAgIm5hbWUiLCBpbmZvLT5jYXBpdGFsaXplZF9uYW1lKTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgICAgICJmb3IgKGludCBpID0gMDsgaSA8IGdldCRuYW1lJENvdW50KCk7IGkrKykge1xuIgorICAgICAgICAgICAgICAiICBpZiAoIWdldCRuYW1lJChpKS5pc0luaXRpYWxpemVkKCkpIHtcbiIKKyAgICAgICAgICAgICAgIiAgICByZXR1cm4gZmFsc2U7XG4iCisgICAgICAgICAgICAgICIgIH1cbiIKKyAgICAgICAgICAgICAgIn1cbiIsCisgICAgICAgICAgICAgICJ0eXBlIiwgbmFtZV9yZXNvbHZlcl8tPkdldEltbXV0YWJsZUNsYXNzTmFtZSgKKyAgICAgICAgICAgICAgICAgIGZpZWxkLT5tZXNzYWdlX3R5cGUoKSksCisgICAgICAgICAgICAgICJuYW1lIiwgaW5mby0+Y2FwaXRhbGl6ZWRfbmFtZSk7CisgICAgICAgICAgfQorICAgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgfQorCisgIGlmIChkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCkgPiAwKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiaWYgKCFleHRlbnNpb25zQXJlSW5pdGlhbGl6ZWQoKSkge1xuIgorICAgICAgIiAgcmV0dXJuIGZhbHNlO1xuIgorICAgICAgIn1cbiIpOworICB9CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworCisgIHByaW50ZXItPlByaW50KAorICAgICIgIHJldHVybiB0cnVlO1xuIgorICAgICJ9XG4iCisgICAgIlxuIik7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tZXNzYWdlX2J1aWxkZXIuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21lc3NhZ2VfYnVpbGRlci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAxNWVhMDYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tZXNzYWdlX2J1aWxkZXIuaApAQCAtMCwwICsxLDg2IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBkd2Vpc0Bnb29nbGUuY29tIChEYW5pZWwgV2VpcykKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX01FU1NBR0VfQlVJTERFUl9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfTUVTU0FHRV9CVUlMREVSX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPG1hcD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2ZpZWxkLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKyAgbmFtZXNwYWNlIGNvbXBpbGVyIHsKKyAgICBuYW1lc3BhY2UgamF2YSB7CisgICAgICBjbGFzcyBDb250ZXh0OyAgICAgICAgICAgLy8gY29udGV4dC5oCisgICAgICBjbGFzcyBDbGFzc05hbWVSZXNvbHZlcjsgLy8gbmFtZV9yZXNvbHZlci5oCisgICAgfQorICB9CisgIG5hbWVzcGFjZSBpbyB7CisgICAgY2xhc3MgUHJpbnRlcjsgICAgICAgICAgICAgLy8gcHJpbnRlci5oCisgIH0KK30KKworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YSB7CisKK2NsYXNzIE1lc3NhZ2VCdWlsZGVyR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IE1lc3NhZ2VCdWlsZGVyR2VuZXJhdG9yKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnRleHQqIGNvbnRleHQpOworICB2aXJ0dWFsIH5NZXNzYWdlQnVpbGRlckdlbmVyYXRvcigpOworCisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyBwcml2YXRlOgorICB2b2lkIEdlbmVyYXRlQ29tbW9uQnVpbGRlck1ldGhvZHMoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2b2lkIEdlbmVyYXRlRGVzY3JpcHRvck1ldGhvZHMoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2b2lkIEdlbmVyYXRlQnVpbGRlclBhcnNpbmdNZXRob2RzKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdm9pZCBHZW5lcmF0ZUlzSW5pdGlhbGl6ZWQoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworICBDb250ZXh0KiBjb250ZXh0XzsKKyAgQ2xhc3NOYW1lUmVzb2x2ZXIqIG5hbWVfcmVzb2x2ZXJfOworICBGaWVsZEdlbmVyYXRvck1hcDxJbW11dGFibGVGaWVsZEdlbmVyYXRvcj4gZmllbGRfZ2VuZXJhdG9yc187CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKE1lc3NhZ2VCdWlsZGVyR2VuZXJhdG9yKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX01FU1NBR0VfQlVJTERFUl9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21lc3NhZ2VfYnVpbGRlcl9saXRlLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbWVzc2FnZV9idWlsZGVyX2xpdGUuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODcxOWQwMAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21lc3NhZ2VfYnVpbGRlcl9saXRlLmNjCkBAIC0wLDAgKzEsMTkyIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBkd2Vpc0Bnb29nbGUuY29tIChEYW5pZWwgV2VpcykKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tZXNzYWdlX2J1aWxkZXJfbGl0ZS5oPgorCisjaW5jbHVkZSA8YWxnb3JpdGhtPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9oYXNoLmg+CisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPG1lbW9yeT4KKyNpZm5kZWYgX1NIQVJFRF9QVFJfSAorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaGFyZWRfcHRyLmg+CisjZW5kaWYKKyNpbmNsdWRlIDx2ZWN0b3I+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2NvbnRleHQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2RvY19jb21tZW50Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9lbnVtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9leHRlbnNpb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2dlbmVyYXRvcl9mYWN0b3J5Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9uYW1lX3Jlc29sdmVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdWJzdGl0dXRlLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YSB7CisKK25hbWVzcGFjZSB7Citib29sIEdlbmVyYXRlSGFzQml0cyhjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIHJldHVybiBTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yLT5maWxlKCkpIHx8CisgICAgICBIYXNSZXBlYXRlZEZpZWxkcyhkZXNjcmlwdG9yKTsKK30KKworc3RyaW5nIE1hcFZhbHVlSW1tdXRhYmxlQ2xhc3NkTmFtZShjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDbGFzc05hbWVSZXNvbHZlciogbmFtZV9yZXNvbHZlcikgeworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHZhbHVlX2ZpZWxkID0gZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJ2YWx1ZSIpOworICBHT09HTEVfQ0hFQ0tfRVEoRmllbGREZXNjcmlwdG9yOjpUWVBFX01FU1NBR0UsIHZhbHVlX2ZpZWxkLT50eXBlKCkpOworICByZXR1cm4gbmFtZV9yZXNvbHZlci0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKHZhbHVlX2ZpZWxkLT5tZXNzYWdlX3R5cGUoKSk7Cit9Cit9ICAvLyBuYW1lc3BhY2UKKworTWVzc2FnZUJ1aWxkZXJMaXRlR2VuZXJhdG9yOjpNZXNzYWdlQnVpbGRlckxpdGVHZW5lcmF0b3IoCisgICAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwgQ29udGV4dCogY29udGV4dCkKKyAgOiBkZXNjcmlwdG9yXyhkZXNjcmlwdG9yKSwgY29udGV4dF8oY29udGV4dCksCisgICAgbmFtZV9yZXNvbHZlcl8oY29udGV4dC0+R2V0TmFtZVJlc29sdmVyKCkpLAorICAgIGZpZWxkX2dlbmVyYXRvcnNfKGRlc2NyaXB0b3IsIGNvbnRleHRfKSB7CisgIEdPT0dMRV9DSEVDS19FUSgKKyAgICAgIEZpbGVPcHRpb25zOjpMSVRFX1JVTlRJTUUsIGRlc2NyaXB0b3ItPmZpbGUoKS0+b3B0aW9ucygpLm9wdGltaXplX2ZvcigpKTsKK30KKworTWVzc2FnZUJ1aWxkZXJMaXRlR2VuZXJhdG9yOjp+TWVzc2FnZUJ1aWxkZXJMaXRlR2VuZXJhdG9yKCkge30KKwordm9pZCBNZXNzYWdlQnVpbGRlckxpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgV3JpdGVNZXNzYWdlRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KAorICAgICJwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kc1xuIgorICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlTGl0ZS4kZXh0ZW5kaWJsZSRCdWlsZGVyPFxuIgorICAgICIgICAgICAkY2xhc3NuYW1lJCwgQnVpbGRlcj4gaW1wbGVtZW50c1xuIgorICAgICIgICAgJGV4dHJhX2ludGVyZmFjZXMkXG4iCisgICAgIiAgICAkY2xhc3NuYW1lJE9yQnVpbGRlciB7XG4iLAorICAgICJjbGFzc25hbWUiLCBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3JfKSwKKyAgICAiZXh0cmFfaW50ZXJmYWNlcyIsIEV4dHJhQnVpbGRlckludGVyZmFjZXMoZGVzY3JpcHRvcl8pLAorICAgICJleHRlbmRpYmxlIiwKKyAgICBkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCkgPiAwID8gIkV4dGVuZGFibGUiIDogIiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBHZW5lcmF0ZUNvbW1vbkJ1aWxkZXJNZXRob2RzKHByaW50ZXIpOworCisgIC8vIG9uZW9mCisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyczsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbF9jb3VudCgpOyBpKyspIHsKKyAgICB2YXJzWyJvbmVvZl9uYW1lIl0gPSBjb250ZXh0Xy0+R2V0T25lb2ZHZW5lcmF0b3JJbmZvKAorICAgICAgICBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKSktPm5hbWU7CisgICAgdmFyc1sib25lb2ZfY2FwaXRhbGl6ZWRfbmFtZSJdID0gY29udGV4dF8tPkdldE9uZW9mR2VuZXJhdG9ySW5mbygKKyAgICAgICAgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSkpLT5jYXBpdGFsaXplZF9uYW1lOworICAgIHZhcnNbIm9uZW9mX2luZGV4Il0gPSBTaW1wbGVJdG9hKGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5pbmRleCgpKTsKKworICAgIC8vIG9uZW9mQ2FzZSgpIGFuZCBjbGVhck9uZW9mKCkKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgInB1YmxpYyAkb25lb2ZfY2FwaXRhbGl6ZWRfbmFtZSRDYXNlXG4iCisgICAgICAiICAgIGdldCRvbmVvZl9jYXBpdGFsaXplZF9uYW1lJENhc2UoKSB7XG4iCisgICAgICAiICByZXR1cm4gaW5zdGFuY2UuZ2V0JG9uZW9mX2NhcGl0YWxpemVkX25hbWUkQ2FzZSgpO1xuIgorICAgICAgIn1cbiIKKyAgICAgICJcbiIKKyAgICAgICJwdWJsaWMgQnVpbGRlciBjbGVhciRvbmVvZl9jYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAgICIgIGNvcHlPbldyaXRlKCk7XG4iCisgICAgICAiICBpbnN0YW5jZS5jbGVhciRvbmVvZl9jYXBpdGFsaXplZF9uYW1lJCgpO1xuIgorICAgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgICAifVxuIgorICAgICAgIlxuIik7CisgIH0KKworICBpZiAoR2VuZXJhdGVIYXNCaXRzKGRlc2NyaXB0b3JfKSkgeworICAgIC8vIEludGVnZXJzIGZvciBiaXQgZmllbGRzLgorICAgIGludCB0b3RhbEJpdHMgPSAwOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgICAgdG90YWxCaXRzICs9IGZpZWxkX2dlbmVyYXRvcnNfLmdldChkZXNjcmlwdG9yXy0+ZmllbGQoaSkpCisgICAgICAgICAgLkdldE51bUJpdHNGb3JCdWlsZGVyKCk7CisgICAgfQorICAgIGludCB0b3RhbEludHMgPSAodG90YWxCaXRzICsgMzEpIC8gMzI7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0b3RhbEludHM7IGkrKykgeworICAgICAgcHJpbnRlci0+UHJpbnQoInByaXZhdGUgaW50ICRiaXRfZmllbGRfbmFtZSQ7XG4iLAorICAgICAgICAiYml0X2ZpZWxkX25hbWUiLCBHZXRCaXRGaWVsZE5hbWUoaSkpOworICAgIH0KKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIHByaW50ZXItPlByaW50KCJcbiIpOworICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChkZXNjcmlwdG9yXy0+ZmllbGQoaSkpCisgICAgICAgICAgICAgICAgICAgICAuR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhwcmludGVyKTsKKyAgfQorCisgIGlmICghUHJlc2VydmVVbmtub3duRmllbGRzKGRlc2NyaXB0b3JfKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgInB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoXG4iCisgICAgICAiICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHtcbiIKKyAgICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICAgIn1cbiIKKyAgICAgICJcbiIKKyAgICAgICJwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoXG4iCisgICAgICAiICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHtcbiIKKyAgICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICAgIn1cbiIKKyAgICAgICJcbiIpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIlxuIgorICAgICIvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTokZnVsbF9uYW1lJClcbiIsCisgICAgImZ1bGxfbmFtZSIsIGRlc2NyaXB0b3JfLT5mdWxsX25hbWUoKSk7CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgifVxuIik7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKwordm9pZCBNZXNzYWdlQnVpbGRlckxpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVDb21tb25CdWlsZGVyTWV0aG9kcyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICAiLy8gQ29uc3RydWN0IHVzaW5nICRjbGFzc25hbWUkLm5ld0J1aWxkZXIoKVxuIgorICAgICJwcml2YXRlIEJ1aWxkZXIoKSB7XG4iCisgICAgIiAgc3VwZXIoREVGQVVMVF9JTlNUQU5DRSk7XG4iCisgICAgIn1cbiIKKyAgICAiXG4iLAorICAgICJjbGFzc25hbWUiLCBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3JfKSk7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tZXNzYWdlX2J1aWxkZXJfbGl0ZS5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbWVzc2FnZV9idWlsZGVyX2xpdGUuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NTk3YjJlCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbWVzc2FnZV9idWlsZGVyX2xpdGUuaApAQCAtMCwwICsxLDgzIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBkd2Vpc0Bnb29nbGUuY29tIChEYW5pZWwgV2VpcykKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX01FU1NBR0VfQlVJTERFUl9MSVRFX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9NRVNTQUdFX0JVSUxERVJfTElURV9IX18KKworI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9maWVsZC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisgIG5hbWVzcGFjZSBjb21waWxlciB7CisgICAgbmFtZXNwYWNlIGphdmEgeworICAgICAgY2xhc3MgQ29udGV4dDsgICAgICAgICAgIC8vIGNvbnRleHQuaAorICAgICAgY2xhc3MgQ2xhc3NOYW1lUmVzb2x2ZXI7IC8vIG5hbWVfcmVzb2x2ZXIuaAorICAgIH0KKyAgfQorICBuYW1lc3BhY2UgaW8geworICAgIGNsYXNzIFByaW50ZXI7ICAgICAgICAgICAgIC8vIHByaW50ZXIuaAorICB9Cit9CisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmEgeworCitjbGFzcyBNZXNzYWdlQnVpbGRlckxpdGVHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgTWVzc2FnZUJ1aWxkZXJMaXRlR2VuZXJhdG9yKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnRleHQqIGNvbnRleHQpOworICB2aXJ0dWFsIH5NZXNzYWdlQnVpbGRlckxpdGVHZW5lcmF0b3IoKTsKKworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGUoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgcHJpdmF0ZToKKyAgdm9pZCBHZW5lcmF0ZUNvbW1vbkJ1aWxkZXJNZXRob2RzKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgQ29udGV4dCogY29udGV4dF87CisgIENsYXNzTmFtZVJlc29sdmVyKiBuYW1lX3Jlc29sdmVyXzsKKyAgRmllbGRHZW5lcmF0b3JNYXA8SW1tdXRhYmxlRmllbGRMaXRlR2VuZXJhdG9yPiBmaWVsZF9nZW5lcmF0b3JzXzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoTWVzc2FnZUJ1aWxkZXJMaXRlR2VuZXJhdG9yKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX01FU1NBR0VfQlVJTERFUl9MSVRFX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbWVzc2FnZV9maWVsZC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21lc3NhZ2VfZmllbGQuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjVmOGU2MgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21lc3NhZ2VfZmllbGQuY2MKQEAgLTAsMCArMSwxMjkyIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8c3RyaW5nPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9jb250ZXh0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tZXNzYWdlX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9kb2NfY29tbWVudC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfaGVscGVycy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbmFtZV9yZXNvbHZlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhIHsKKworbmFtZXNwYWNlIHsKKwordm9pZCBTZXRNZXNzYWdlVmFyaWFibGVzKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgIGludCBidWlsZGVyQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGRHZW5lcmF0b3JJbmZvKiBpbmZvLAorICAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzTmFtZVJlc29sdmVyKiBuYW1lX3Jlc29sdmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgIG1hcDxzdHJpbmcsIHN0cmluZz4qIHZhcmlhYmxlcykgeworICBTZXRDb21tb25GaWVsZFZhcmlhYmxlcyhkZXNjcmlwdG9yLCBpbmZvLCB2YXJpYWJsZXMpOworCisgICgqdmFyaWFibGVzKVsidHlwZSJdID0KKyAgICAgIG5hbWVfcmVzb2x2ZXItPkdldEltbXV0YWJsZUNsYXNzTmFtZShkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKSk7CisgICgqdmFyaWFibGVzKVsibXV0YWJsZV90eXBlIl0gPQorICAgICAgbmFtZV9yZXNvbHZlci0+R2V0TXV0YWJsZUNsYXNzTmFtZShkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKSk7CisgICgqdmFyaWFibGVzKVsiZ3JvdXBfb3JfbWVzc2FnZSJdID0KKyAgICAoR2V0VHlwZShkZXNjcmlwdG9yKSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfR1JPVVApID8KKyAgICAiR3JvdXAiIDogIk1lc3NhZ2UiOworICAvLyBUT0RPKGJpcmRvKTogQWRkIEBkZXByZWNhdGVkIGphdmFkb2Mgd2hlbiBnZW5lcmF0aW5nIGphdmFkb2MgaXMgc3VwcG9ydGVkCisgIC8vIGJ5IHRoZSBwcm90byBjb21waWxlcgorICAoKnZhcmlhYmxlcylbImRlcHJlY2F0aW9uIl0gPSBkZXNjcmlwdG9yLT5vcHRpb25zKCkuZGVwcmVjYXRlZCgpCisgICAgICA/ICJAamF2YS5sYW5nLkRlcHJlY2F0ZWQgIiA6ICIiOworICAoKnZhcmlhYmxlcylbIm9uX2NoYW5nZWQiXSA9CisgICAgICBIYXNEZXNjcmlwdG9yTWV0aG9kcyhkZXNjcmlwdG9yLT5jb250YWluaW5nX3R5cGUoKSkgPyAib25DaGFuZ2VkKCk7IiA6ICIiOworCisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yLT5maWxlKCkpKSB7CisgICAgLy8gRm9yIHNpbmd1bGFyIG1lc3NhZ2VzIGFuZCBidWlsZGVycywgb25lIGJpdCBpcyB1c2VkIGZvciB0aGUgaGFzRmllbGQgYml0LgorICAgICgqdmFyaWFibGVzKVsiZ2V0X2hhc19maWVsZF9iaXRfbWVzc2FnZSJdID0gR2VuZXJhdGVHZXRCaXQobWVzc2FnZUJpdEluZGV4KTsKKyAgICAoKnZhcmlhYmxlcylbImdldF9oYXNfZmllbGRfYml0X2J1aWxkZXIiXSA9IEdlbmVyYXRlR2V0Qml0KGJ1aWxkZXJCaXRJbmRleCk7CisKKyAgICAvLyBOb3RlIHRoYXQgdGhlc2UgaGF2ZSBhIHRyYWlsaW5nICI7Ii4KKyAgICAoKnZhcmlhYmxlcylbInNldF9oYXNfZmllbGRfYml0X21lc3NhZ2UiXSA9CisgICAgICAgIEdlbmVyYXRlU2V0Qml0KG1lc3NhZ2VCaXRJbmRleCkgKyAiOyI7CisgICAgKCp2YXJpYWJsZXMpWyJzZXRfaGFzX2ZpZWxkX2JpdF9idWlsZGVyIl0gPQorICAgICAgICBHZW5lcmF0ZVNldEJpdChidWlsZGVyQml0SW5kZXgpICsgIjsiOworICAgICgqdmFyaWFibGVzKVsiY2xlYXJfaGFzX2ZpZWxkX2JpdF9idWlsZGVyIl0gPQorICAgICAgICBHZW5lcmF0ZUNsZWFyQml0KGJ1aWxkZXJCaXRJbmRleCkgKyAiOyI7CisKKyAgICAoKnZhcmlhYmxlcylbImlzX2ZpZWxkX3ByZXNlbnRfbWVzc2FnZSJdID0gR2VuZXJhdGVHZXRCaXQobWVzc2FnZUJpdEluZGV4KTsKKyAgfSBlbHNlIHsKKyAgICAoKnZhcmlhYmxlcylbInNldF9oYXNfZmllbGRfYml0X21lc3NhZ2UiXSA9ICIiOworICAgICgqdmFyaWFibGVzKVsic2V0X2hhc19maWVsZF9iaXRfYnVpbGRlciJdID0gIiI7CisgICAgKCp2YXJpYWJsZXMpWyJjbGVhcl9oYXNfZmllbGRfYml0X2J1aWxkZXIiXSA9ICIiOworCisgICAgKCp2YXJpYWJsZXMpWyJpc19maWVsZF9wcmVzZW50X21lc3NhZ2UiXSA9CisgICAgICAgICgqdmFyaWFibGVzKVsibmFtZSJdICsgIl8gIT0gbnVsbCI7CisgIH0KKworICAvLyBGb3IgcmVwYXRlZCBidWlsZGVycywgb25lIGJpdCBpcyB1c2VkIGZvciB3aGV0aGVyIHRoZSBhcnJheSBpcyBpbW11dGFibGUuCisgICgqdmFyaWFibGVzKVsiZ2V0X211dGFibGVfYml0X2J1aWxkZXIiXSA9IEdlbmVyYXRlR2V0Qml0KGJ1aWxkZXJCaXRJbmRleCk7CisgICgqdmFyaWFibGVzKVsic2V0X211dGFibGVfYml0X2J1aWxkZXIiXSA9IEdlbmVyYXRlU2V0Qml0KGJ1aWxkZXJCaXRJbmRleCk7CisgICgqdmFyaWFibGVzKVsiY2xlYXJfbXV0YWJsZV9iaXRfYnVpbGRlciJdID0gR2VuZXJhdGVDbGVhckJpdChidWlsZGVyQml0SW5kZXgpOworCisgIC8vIEZvciByZXBlYXRlZCBmaWVsZHMsIG9uZSBiaXQgaXMgdXNlZCBmb3Igd2hldGhlciB0aGUgYXJyYXkgaXMgaW1tdXRhYmxlCisgIC8vIGluIHRoZSBwYXJzaW5nIGNvbnN0cnVjdG9yLgorICAoKnZhcmlhYmxlcylbImdldF9tdXRhYmxlX2JpdF9wYXJzZXIiXSA9CisgICAgICBHZW5lcmF0ZUdldEJpdE11dGFibGVMb2NhbChidWlsZGVyQml0SW5kZXgpOworICAoKnZhcmlhYmxlcylbInNldF9tdXRhYmxlX2JpdF9wYXJzZXIiXSA9CisgICAgICBHZW5lcmF0ZVNldEJpdE11dGFibGVMb2NhbChidWlsZGVyQml0SW5kZXgpOworCisgICgqdmFyaWFibGVzKVsiZ2V0X2hhc19maWVsZF9iaXRfZnJvbV9sb2NhbCJdID0KKyAgICAgIEdlbmVyYXRlR2V0Qml0RnJvbUxvY2FsKGJ1aWxkZXJCaXRJbmRleCk7CisgICgqdmFyaWFibGVzKVsic2V0X2hhc19maWVsZF9iaXRfdG9fbG9jYWwiXSA9CisgICAgICBHZW5lcmF0ZVNldEJpdFRvTG9jYWwobWVzc2FnZUJpdEluZGV4KTsKK30KKworfSAgLy8gbmFtZXNwYWNlCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworSW1tdXRhYmxlTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0ltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgaW50IG1lc3NhZ2VCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICBpbnQgYnVpbGRlckJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgIENvbnRleHQqIGNvbnRleHQpCisgIDogZGVzY3JpcHRvcl8oZGVzY3JpcHRvciksIG1lc3NhZ2VCaXRJbmRleF8obWVzc2FnZUJpdEluZGV4KSwKKyAgICBidWlsZGVyQml0SW5kZXhfKGJ1aWxkZXJCaXRJbmRleCksIGNvbnRleHRfKGNvbnRleHQpLAorICAgIG5hbWVfcmVzb2x2ZXJfKGNvbnRleHQtPkdldE5hbWVSZXNvbHZlcigpKSB7CisgICAgU2V0TWVzc2FnZVZhcmlhYmxlcyhkZXNjcmlwdG9yLCBtZXNzYWdlQml0SW5kZXgsIGJ1aWxkZXJCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQtPkdldEZpZWxkR2VuZXJhdG9ySW5mbyhkZXNjcmlwdG9yKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVfcmVzb2x2ZXJfLCAmdmFyaWFibGVzXyk7Cit9CisKK0ltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6fkltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcigpIHt9CisKK2ludCBJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3I6OkdldE51bUJpdHNGb3JNZXNzYWdlKCkgY29uc3QgeworICByZXR1cm4gMTsKK30KKworaW50IEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6R2V0TnVtQml0c0ZvckJ1aWxkZXIoKSBjb25zdCB7CisgIHJldHVybiAxOworfQorCit2b2lkIEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUludGVyZmFjZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gVE9ETyhqb25wKTogSW4gdGhlIGZ1dHVyZSwgY29uc2lkZXIgaGF2aW5nIGEgbWV0aG9kIHNwZWNpZmljIHRvIHRoZQorICAvLyBpbnRlcmZhY2Ugc28gdGhhdCBidWlsZGVycyBjYW4gY2hvb3NlIGR5bmFtaWNhbGx5IHRvIGVpdGhlciByZXR1cm4gYQorICAvLyBtZXNzYWdlIG9yIGEgbmVzdGVkIGJ1aWxkZXIsIHNvIHRoYXQgYXNraW5nIGZvciB0aGUgaW50ZXJmYWNlIGRvZXNuJ3QKKyAgLy8gY2F1c2UgYSBtZXNzYWdlIHRvIGV2ZXIgYmUgYnVpbHQuCisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSB8fAorICAgICAgZGVzY3JpcHRvcl8tPmNvbnRhaW5pbmdfb25lb2YoKSA9PSBOVUxMKSB7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJGRlcHJlY2F0aW9uJGJvb2xlYW4gaGFzJGNhcGl0YWxpemVkX25hbWUkKCk7XG4iKTsKKyAgfQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiQkdHlwZSQgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCk7XG4iKTsKKworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiQkdHlwZSRPckJ1aWxkZXIgZ2V0JGNhcGl0YWxpemVkX25hbWUkT3JCdWlsZGVyKCk7XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgJHR5cGUkICRuYW1lJF87XG4iKTsKKyAgUHJpbnRFeHRyYUZpZWxkSW5mbyh2YXJpYWJsZXNfLCBwcmludGVyKTsKKworICBpZiAoU3VwcG9ydEZpZWxkUHJlc2VuY2UoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljIGJvb2xlYW4gaGFzJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICAgIiAgcmV0dXJuICRnZXRfaGFzX2ZpZWxkX2JpdF9tZXNzYWdlJDtcbiIKKyAgICAgICJ9XG4iKTsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljICR0eXBlJCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgICAiICByZXR1cm4gJG5hbWUkXyA9PSBudWxsID8gJHR5cGUkLmdldERlZmF1bHRJbnN0YW5jZSgpIDogJG5hbWUkXztcbiIKKyAgICAgICJ9XG4iKTsKKworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkT3JCdWlsZGVyICIKKyAgICAgICJnZXQkY2FwaXRhbGl6ZWRfbmFtZSRPckJ1aWxkZXIoKSB7XG4iCisgICAgICAiICByZXR1cm4gJG5hbWUkXyA9PSBudWxsID8gJHR5cGUkLmdldERlZmF1bHRJbnN0YW5jZSgpIDogJG5hbWUkXztcbiIKKyAgICAgICJ9XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljIGJvb2xlYW4gaGFzJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICAgIiAgcmV0dXJuICRuYW1lJF8gIT0gbnVsbDtcbiIKKyAgICAgICJ9XG4iKTsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljICR0eXBlJCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgICAiICByZXR1cm4gJG5hbWUkXyA9PSBudWxsID8gJHR5cGUkLmdldERlZmF1bHRJbnN0YW5jZSgpIDogJG5hbWUkXztcbiIKKyAgICAgICJ9XG4iKTsKKworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkT3JCdWlsZGVyICIKKyAgICAgICJnZXQkY2FwaXRhbGl6ZWRfbmFtZSRPckJ1aWxkZXIoKSB7XG4iCisgICAgICAiICByZXR1cm4gZ2V0JGNhcGl0YWxpemVkX25hbWUkKCk7XG4iCisgICAgICAifVxuIik7CisgIH0KK30KKwordm9pZCBJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3I6OlByaW50TmVzdGVkQnVpbGRlckNvbmRpdGlvbigKKyAgICBpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICBjb25zdCBjaGFyKiByZWd1bGFyX2Nhc2UsCisgICAgY29uc3QgY2hhciogbmVzdGVkX2J1aWxkZXJfY2FzZSkgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAiaWYgKCRuYW1lJEJ1aWxkZXJfID09IG51bGwpIHtcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgcmVndWxhcl9jYXNlKTsKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgifSBlbHNlIHtcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgbmVzdGVkX2J1aWxkZXJfY2FzZSk7CisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6UHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24oCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgY29uc3QgY2hhciogbWV0aG9kX3Byb3RvdHlwZSwKKyAgICBjb25zdCBjaGFyKiByZWd1bGFyX2Nhc2UsCisgICAgY29uc3QgY2hhciogbmVzdGVkX2J1aWxkZXJfY2FzZSwKKyAgICBjb25zdCBjaGFyKiB0cmFpbGluZ19jb2RlKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sIG1ldGhvZF9wcm90b3R5cGUpOworICBwcmludGVyLT5QcmludCgiIHtcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKyAgUHJpbnROZXN0ZWRCdWlsZGVyQ29uZGl0aW9uKHByaW50ZXIsIHJlZ3VsYXJfY2FzZSwgbmVzdGVkX2J1aWxkZXJfY2FzZSk7CisgIGlmICh0cmFpbGluZ19jb2RlICE9IE5VTEwpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCB0cmFpbGluZ19jb2RlKTsKKyAgfQorICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KCJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBXaGVuIHVzaW5nIG5lc3RlZC1idWlsZGVycywgdGhlIGNvZGUgaW5pdGlhbGx5IHdvcmtzIGp1c3QgbGlrZSB0aGUKKyAgLy8gbm9uLW5lc3RlZCBidWlsZGVyIGNhc2UuIEl0IG9ubHkgY3JlYXRlcyBhIG5lc3RlZCBidWlsZGVyIGxhemlseSBvbgorICAvLyBkZW1hbmQgYW5kIHRoZW4gZm9yZXZlciBkZWxlZ2F0ZXMgdG8gaXQgYWZ0ZXIgY3JlYXRpb24uCisKKyAgYm9vbCBzdXBwb3J0X2ZpZWxkX3ByZXNlbmNlID0gU3VwcG9ydEZpZWxkUHJlc2VuY2UoZGVzY3JpcHRvcl8tPmZpbGUoKSk7CisKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHJpdmF0ZSAkdHlwZSQgJG5hbWUkXyA9IG51bGw7XG4iKTsKKworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgLy8gSWYgdGhpcyBidWlsZGVyIGlzIG5vbi1udWxsLCBpdCBpcyB1c2VkIGFuZCB0aGUgb3RoZXIgZmllbGRzIGFyZQorICAgICAgLy8gaWdub3JlZC4KKyAgICAgICJwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyPFxuIgorICAgICAgIiAgICAkdHlwZSQsICR0eXBlJC5CdWlsZGVyLCAkdHlwZSRPckJ1aWxkZXI+ICRuYW1lJEJ1aWxkZXJfOyIKKyAgICAgICJcbiIpOworCisgIC8vIFRoZSBjb21tZW50cyBhYm92ZSB0aGUgbWV0aG9kcyBiZWxvdyBhcmUgYmFzZWQgb24gYSBoeXBvdGhldGljYWwKKyAgLy8gZmllbGQgb2YgdHlwZSAiRmllbGQiIGNhbGxlZCAiRmllbGQiLgorCisgIC8vIGJvb2xlYW4gaGFzRmllbGQoKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIGlmIChzdXBwb3J0X2ZpZWxkX3ByZXNlbmNlKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljIGJvb2xlYW4gaGFzJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICAgIiAgcmV0dXJuICRnZXRfaGFzX2ZpZWxkX2JpdF9idWlsZGVyJDtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgYm9vbGVhbiBoYXMkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgICAiICByZXR1cm4gJG5hbWUkQnVpbGRlcl8gIT0gbnVsbCB8fCAkbmFtZSRfICE9IG51bGw7XG4iCisgICAgICAifVxuIik7CisgIH0KKworICAvLyBGaWVsZCBnZXRGaWVsZCgpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgUHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24ocHJpbnRlciwKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSQgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkiLAorICAgICJyZXR1cm4gJG5hbWUkXyA9PSBudWxsID8gJHR5cGUkLmdldERlZmF1bHRJbnN0YW5jZSgpIDogJG5hbWUkXztcbiIsCisgICAgInJldHVybiAkbmFtZSRCdWlsZGVyXy5nZXRNZXNzYWdlKCk7XG4iLAorICAgIE5VTEwpOworCisgIC8vIEZpZWxkLkJ1aWxkZXIgc2V0RmllbGQoRmllbGQgdmFsdWUpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgUHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24ocHJpbnRlciwKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIHNldCRjYXBpdGFsaXplZF9uYW1lJCgkdHlwZSQgdmFsdWUpIiwKKworICAgICJpZiAodmFsdWUgPT0gbnVsbCkge1xuIgorICAgICIgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpO1xuIgorICAgICJ9XG4iCisgICAgIiRuYW1lJF8gPSB2YWx1ZTtcbiIKKyAgICAiJG9uX2NoYW5nZWQkXG4iLAorCisgICAgIiRuYW1lJEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpO1xuIiwKKworICAgICIkc2V0X2hhc19maWVsZF9iaXRfYnVpbGRlciRcbiIKKyAgICAicmV0dXJuIHRoaXM7XG4iKTsKKworICAvLyBGaWVsZC5CdWlsZGVyIHNldEZpZWxkKEZpZWxkLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIFByaW50TmVzdGVkQnVpbGRlckZ1bmN0aW9uKHByaW50ZXIsCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBzZXQkY2FwaXRhbGl6ZWRfbmFtZSQoXG4iCisgICAgIiAgICAkdHlwZSQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIiwKKworICAgICIkbmFtZSRfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7XG4iCisgICAgIiRvbl9jaGFuZ2VkJFxuIiwKKworICAgICIkbmFtZSRCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTtcbiIsCisKKyAgICAiJHNldF9oYXNfZmllbGRfYml0X2J1aWxkZXIkXG4iCisgICAgInJldHVybiB0aGlzO1xuIik7CisKKyAgLy8gRmllbGQuQnVpbGRlciBtZXJnZUZpZWxkKEZpZWxkIHZhbHVlKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIFByaW50TmVzdGVkQnVpbGRlckZ1bmN0aW9uKHByaW50ZXIsCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBtZXJnZSRjYXBpdGFsaXplZF9uYW1lJCgkdHlwZSQgdmFsdWUpIiwKKworICAgIHN1cHBvcnRfZmllbGRfcHJlc2VuY2UKKyAgICAgICAgPyAiaWYgKCRnZXRfaGFzX2ZpZWxkX2JpdF9idWlsZGVyJCAmJlxuIgorICAgICAgICAgICIgICAgJG5hbWUkXyAhPSBudWxsICYmXG4iCisgICAgICAgICAgIiAgICAkbmFtZSRfICE9ICR0eXBlJC5nZXREZWZhdWx0SW5zdGFuY2UoKSkge1xuIgorICAgICAgICAgICIgICRuYW1lJF8gPVxuIgorICAgICAgICAgICIgICAgJHR5cGUkLm5ld0J1aWxkZXIoJG5hbWUkXykubWVyZ2VGcm9tKHZhbHVlKS5idWlsZFBhcnRpYWwoKTtcbiIKKyAgICAgICAgICAifSBlbHNlIHtcbiIKKyAgICAgICAgICAiICAkbmFtZSRfID0gdmFsdWU7XG4iCisgICAgICAgICAgIn1cbiIKKyAgICAgICAgICAiJG9uX2NoYW5nZWQkXG4iCisgICAgICAgIDogImlmICgkbmFtZSRfICE9IG51bGwpIHtcbiIKKyAgICAgICAgICAiICAkbmFtZSRfID1cbiIKKyAgICAgICAgICAiICAgICR0eXBlJC5uZXdCdWlsZGVyKCRuYW1lJF8pLm1lcmdlRnJvbSh2YWx1ZSkuYnVpbGRQYXJ0aWFsKCk7XG4iCisgICAgICAgICAgIn0gZWxzZSB7XG4iCisgICAgICAgICAgIiAgJG5hbWUkXyA9IHZhbHVlO1xuIgorICAgICAgICAgICJ9XG4iCisgICAgICAgICAgIiRvbl9jaGFuZ2VkJFxuIiwKKworICAgICIkbmFtZSRCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpO1xuIiwKKworICAgICIkc2V0X2hhc19maWVsZF9iaXRfYnVpbGRlciRcbiIKKyAgICAicmV0dXJuIHRoaXM7XG4iKTsKKworICAvLyBGaWVsZC5CdWlsZGVyIGNsZWFyRmllbGQoKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIFByaW50TmVzdGVkQnVpbGRlckZ1bmN0aW9uKHByaW50ZXIsCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBjbGVhciRjYXBpdGFsaXplZF9uYW1lJCgpIiwKKworICAgICIkbmFtZSRfID0gbnVsbDtcbiIKKyAgICAiJG9uX2NoYW5nZWQkXG4iLAorCisgICAgc3VwcG9ydF9maWVsZF9wcmVzZW5jZQorICAgICAgICA/ICIkbmFtZSRCdWlsZGVyXy5jbGVhcigpO1xuIgorICAgICAgICA6ICIkbmFtZSRfID0gbnVsbDtcbiIKKyAgICAgICAgICAiJG5hbWUkQnVpbGRlcl8gPSBudWxsO1xuIiwKKworICAgICIkY2xlYXJfaGFzX2ZpZWxkX2JpdF9idWlsZGVyJFxuIgorICAgICJyZXR1cm4gdGhpcztcbiIpOworCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSQuQnVpbGRlciBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRCdWlsZGVyKCkge1xuIgorICAgICIgICRzZXRfaGFzX2ZpZWxkX2JpdF9idWlsZGVyJFxuIgorICAgICIgICRvbl9jaGFuZ2VkJFxuIgorICAgICIgIHJldHVybiBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkT3JCdWlsZGVyIGdldCRjYXBpdGFsaXplZF9uYW1lJE9yQnVpbGRlcigpIHtcbiIKKyAgICAiICBpZiAoJG5hbWUkQnVpbGRlcl8gIT0gbnVsbCkge1xuIgorICAgICIgICAgcmV0dXJuICRuYW1lJEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTtcbiIKKyAgICAiICB9IGVsc2Uge1xuIgorICAgICIgICAgcmV0dXJuICRuYW1lJF8gPT0gbnVsbCA/XG4iCisgICAgIiAgICAgICAgJHR5cGUkLmdldERlZmF1bHRJbnN0YW5jZSgpIDogJG5hbWUkXztcbiIKKyAgICAiICB9XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXI8XG4iCisgICAgIiAgICAkdHlwZSQsICR0eXBlJC5CdWlsZGVyLCAkdHlwZSRPckJ1aWxkZXI+IFxuIgorICAgICIgICAgZ2V0JGNhcGl0YWxpemVkX25hbWUkRmllbGRCdWlsZGVyKCkge1xuIgorICAgICIgIGlmICgkbmFtZSRCdWlsZGVyXyA9PSBudWxsKSB7XG4iCisgICAgIiAgICAkbmFtZSRCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlcjxcbiIKKyAgICAiICAgICAgICAkdHlwZSQsICR0eXBlJC5CdWlsZGVyLCAkdHlwZSRPckJ1aWxkZXI+KFxuIgorICAgICIgICAgICAgICAgICBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSxcbiIKKyAgICAiICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSxcbiIKKyAgICAiICAgICAgICAgICAgaXNDbGVhbigpKTtcbiIKKyAgICAiICAgICRuYW1lJF8gPSBudWxsO1xuIgorICAgICIgIH1cbiIKKyAgICAiICByZXR1cm4gJG5hbWUkQnVpbGRlcl87XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUZpZWxkQnVpbGRlckluaXRpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgIGNvbnN0IHsKKyAgaWYgKFN1cHBvcnRGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJnZXQkY2FwaXRhbGl6ZWRfbmFtZSRGaWVsZEJ1aWxkZXIoKTtcbiIpOworICB9Cit9CisKKwordm9pZCBJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHt9CisKK3ZvaWQgSW1tdXRhYmxlTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRlckNsZWFyQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoU3VwcG9ydEZpZWxkUHJlc2VuY2UoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBQcmludE5lc3RlZEJ1aWxkZXJDb25kaXRpb24ocHJpbnRlciwKKyAgICAgICIkbmFtZSRfID0gbnVsbDtcbiIsCisKKyAgICAgICIkbmFtZSRCdWlsZGVyXy5jbGVhcigpO1xuIik7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgIiRjbGVhcl9oYXNfZmllbGRfYml0X2J1aWxkZXIkXG4iKTsKKyAgfSBlbHNlIHsKKyAgICBQcmludE5lc3RlZEJ1aWxkZXJDb25kaXRpb24ocHJpbnRlciwKKyAgICAgICIkbmFtZSRfID0gbnVsbDtcbiIsCisKKyAgICAgICIkbmFtZSRfID0gbnVsbDtcbiIKKyAgICAgICIkbmFtZSRCdWlsZGVyXyA9IG51bGw7XG4iKTsKKyAgfQorfQorCit2b2lkIEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmIChvdGhlci5oYXMkY2FwaXRhbGl6ZWRfbmFtZSQoKSkge1xuIgorICAgICIgIG1lcmdlJGNhcGl0YWxpemVkX25hbWUkKG90aGVyLmdldCRjYXBpdGFsaXplZF9uYW1lJCgpKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICJpZiAoJGdldF9oYXNfZmllbGRfYml0X2Zyb21fbG9jYWwkKSB7XG4iCisgICAgICAgICIgICRzZXRfaGFzX2ZpZWxkX2JpdF90b19sb2NhbCQ7XG4iCisgICAgICAgICJ9XG4iKTsKKyAgfQorCisgIFByaW50TmVzdGVkQnVpbGRlckNvbmRpdGlvbihwcmludGVyLAorICAgICJyZXN1bHQuJG5hbWUkXyA9ICRuYW1lJF87XG4iLAorCisgICAgInJlc3VsdC4kbmFtZSRfID0gJG5hbWUkQnVpbGRlcl8uYnVpbGQoKTtcbiIpOworfQorCit2b2lkIEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVBhcnNpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiR0eXBlJC5CdWlsZGVyIHN1YkJ1aWxkZXIgPSBudWxsO1xuIgorICAgICJpZiAoJGlzX2ZpZWxkX3ByZXNlbnRfbWVzc2FnZSQpIHtcbiIKKyAgICAiICBzdWJCdWlsZGVyID0gJG5hbWUkXy50b0J1aWxkZXIoKTtcbiIKKyAgICAifVxuIik7CisKKyAgaWYgKEdldFR5cGUoZGVzY3JpcHRvcl8pID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9HUk9VUCkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJG5hbWUkXyA9IGlucHV0LnJlYWRHcm91cCgkbnVtYmVyJCwgJHR5cGUkLnBhcnNlcigpLFxuIgorICAgICAgIiAgICBleHRlbnNpb25SZWdpc3RyeSk7XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRuYW1lJF8gPSBpbnB1dC5yZWFkTWVzc2FnZSgkdHlwZSQucGFyc2VyKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTtcbiIpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKHN1YkJ1aWxkZXIgIT0gbnVsbCkge1xuIgorICAgICIgIHN1YkJ1aWxkZXIubWVyZ2VGcm9tKCRuYW1lJF8pO1xuIgorICAgICIgICRuYW1lJF8gPSBzdWJCdWlsZGVyLmJ1aWxkUGFydGlhbCgpO1xuIgorICAgICJ9XG4iCisgICAgIiRzZXRfaGFzX2ZpZWxkX2JpdF9tZXNzYWdlJFxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlUGFyc2luZ0RvbmVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIG5vb3AgZm9yIG1lc3NhZ2VzLgorfQorCit2b2lkIEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkaXNfZmllbGRfcHJlc2VudF9tZXNzYWdlJCkge1xuIgorICAgICIgIG91dHB1dC53cml0ZSRncm91cF9vcl9tZXNzYWdlJCgkbnVtYmVyJCwgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkpO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCRpc19maWVsZF9wcmVzZW50X21lc3NhZ2UkKSB7XG4iCisgICAgIiAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtXG4iCisgICAgIiAgICAuY29tcHV0ZSRncm91cF9vcl9tZXNzYWdlJFNpemUoJG51bWJlciQsIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJyZXN1bHQgPSByZXN1bHQgJiYgZ2V0JGNhcGl0YWxpemVkX25hbWUkKClcbiIKKyAgICAiICAgIC5lcXVhbHMob3RoZXIuZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkpO1xuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlSGFzaENvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaGFzaCA9ICgzNyAqIGhhc2gpICsgJGNvbnN0YW50X25hbWUkO1xuIgorICAgICJoYXNoID0gKDUzICogaGFzaCkgKyBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKS5oYXNoQ29kZSgpO1xuIik7Cit9CisKK3N0cmluZyBJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3I6OkdldEJveGVkVHlwZSgpIGNvbnN0IHsKKyAgcmV0dXJuIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcl8tPm1lc3NhZ2VfdHlwZSgpKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitJbW11dGFibGVNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitJbW11dGFibGVNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnRleHQqIGNvbnRleHQpCisgICAgOiBJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3IoCisgICAgICAgICAgZGVzY3JpcHRvciwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsIGNvbnRleHQpIHsKKyAgY29uc3QgT25lb2ZHZW5lcmF0b3JJbmZvKiBpbmZvID0KKyAgICAgIGNvbnRleHQtPkdldE9uZW9mR2VuZXJhdG9ySW5mbyhkZXNjcmlwdG9yLT5jb250YWluaW5nX29uZW9mKCkpOworICBTZXRDb21tb25PbmVvZlZhcmlhYmxlcyhkZXNjcmlwdG9yLCBpbmZvLCAmdmFyaWFibGVzXyk7Cit9CisKK0ltbXV0YWJsZU1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK35JbW11dGFibGVNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcigpIHt9CisKK3ZvaWQgSW1tdXRhYmxlTWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIFByaW50RXh0cmFGaWVsZEluZm8odmFyaWFibGVzXywgcHJpbnRlcik7CisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgYm9vbGVhbiBoYXMkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgICAiICByZXR1cm4gJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkO1xuIgorICAgICAgIn1cbiIpOworICB9CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSQgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgIGlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIKKyAgICAiICAgICByZXR1cm4gKCR0eXBlJCkgJG9uZW9mX25hbWUkXztcbiIKKyAgICAiICB9XG4iCisgICAgIiAgcmV0dXJuICR0eXBlJC5nZXREZWZhdWx0SW5zdGFuY2UoKTtcbiIKKyAgICAifVxuIik7CisKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljICR0eXBlJE9yQnVpbGRlciBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRPckJ1aWxkZXIoKSB7XG4iCisgICAgIiAgaWYgKCRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJCkge1xuIgorICAgICIgICAgIHJldHVybiAoJHR5cGUkKSAkb25lb2ZfbmFtZSRfO1xuIgorICAgICIgIH1cbiIKKyAgICAiICByZXR1cm4gJHR5cGUkLmdldERlZmF1bHRJbnN0YW5jZSgpO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUJ1aWxkZXJNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIFdoZW4gdXNpbmcgbmVzdGVkLWJ1aWxkZXJzLCB0aGUgY29kZSBpbml0aWFsbHkgd29ya3MganVzdCBsaWtlIHRoZQorICAvLyBub24tbmVzdGVkIGJ1aWxkZXIgY2FzZS4gSXQgb25seSBjcmVhdGVzIGEgbmVzdGVkIGJ1aWxkZXIgbGF6aWx5IG9uCisgIC8vIGRlbWFuZCBhbmQgdGhlbiBmb3JldmVyIGRlbGVnYXRlcyB0byBpdCBhZnRlciBjcmVhdGlvbi4KKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAvLyBJZiB0aGlzIGJ1aWxkZXIgaXMgbm9uLW51bGwsIGl0IGlzIHVzZWQgYW5kIHRoZSBvdGhlciBmaWVsZHMgYXJlCisgICAgLy8gaWdub3JlZC4KKyAgICAicHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlcjxcbiIKKyAgICAiICAgICR0eXBlJCwgJHR5cGUkLkJ1aWxkZXIsICR0eXBlJE9yQnVpbGRlcj4gJG5hbWUkQnVpbGRlcl87IgorICAgICJcbiIpOworCisgIC8vIFRoZSBjb21tZW50cyBhYm92ZSB0aGUgbWV0aG9kcyBiZWxvdyBhcmUgYmFzZWQgb24gYSBoeXBvdGhldGljYWwKKyAgLy8gZmllbGQgb2YgdHlwZSAiRmllbGQiIGNhbGxlZCAiRmllbGQiLgorCisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIC8vIGJvb2xlYW4gaGFzRmllbGQoKQorICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgYm9vbGVhbiBoYXMkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgICAiICByZXR1cm4gJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkO1xuIgorICAgICAgIn1cbiIpOworICB9CisKKyAgLy8gRmllbGQgZ2V0RmllbGQoKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIFByaW50TmVzdGVkQnVpbGRlckZ1bmN0aW9uKHByaW50ZXIsCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpIiwKKworICAgICJpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iCisgICAgIiAgcmV0dXJuICgkdHlwZSQpICRvbmVvZl9uYW1lJF87XG4iCisgICAgIn1cbiIKKyAgICAicmV0dXJuICR0eXBlJC5nZXREZWZhdWx0SW5zdGFuY2UoKTtcbiIsCisKKyAgICAiaWYgKCRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJCkge1xuIgorICAgICIgIHJldHVybiAkbmFtZSRCdWlsZGVyXy5nZXRNZXNzYWdlKCk7XG4iCisgICAgIn1cbiIKKyAgICAicmV0dXJuICR0eXBlJC5nZXREZWZhdWx0SW5zdGFuY2UoKTtcbiIsCisKKyAgICBOVUxMKTsKKworICAvLyBGaWVsZC5CdWlsZGVyIHNldEZpZWxkKEZpZWxkIHZhbHVlKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIFByaW50TmVzdGVkQnVpbGRlckZ1bmN0aW9uKHByaW50ZXIsCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBzZXQkY2FwaXRhbGl6ZWRfbmFtZSQoJHR5cGUkIHZhbHVlKSIsCisKKyAgICAiaWYgKHZhbHVlID09IG51bGwpIHtcbiIKKyAgICAiICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTtcbiIKKyAgICAifVxuIgorICAgICIkb25lb2ZfbmFtZSRfID0gdmFsdWU7XG4iCisgICAgIiRvbl9jaGFuZ2VkJFxuIiwKKworICAgICIkbmFtZSRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTtcbiIsCisKKyAgICAiJHNldF9vbmVvZl9jYXNlX21lc3NhZ2UkO1xuIgorICAgICJyZXR1cm4gdGhpcztcbiIpOworCisgIC8vIEZpZWxkLkJ1aWxkZXIgc2V0RmllbGQoRmllbGQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgUHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24ocHJpbnRlciwKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIHNldCRjYXBpdGFsaXplZF9uYW1lJChcbiIKKyAgICAiICAgICR0eXBlJC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkiLAorCisgICAgIiRvbmVvZl9uYW1lJF8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTtcbiIKKyAgICAiJG9uX2NoYW5nZWQkXG4iLAorCisgICAgIiRuYW1lJEJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpO1xuIiwKKworICAgICIkc2V0X29uZW9mX2Nhc2VfbWVzc2FnZSQ7XG4iCisgICAgInJldHVybiB0aGlzO1xuIik7CisKKyAgLy8gRmllbGQuQnVpbGRlciBtZXJnZUZpZWxkKEZpZWxkIHZhbHVlKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIFByaW50TmVzdGVkQnVpbGRlckZ1bmN0aW9uKHByaW50ZXIsCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBtZXJnZSRjYXBpdGFsaXplZF9uYW1lJCgkdHlwZSQgdmFsdWUpIiwKKworICAgICJpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkICYmXG4iCisgICAgIiAgICAkb25lb2ZfbmFtZSRfICE9ICR0eXBlJC5nZXREZWZhdWx0SW5zdGFuY2UoKSkge1xuIgorICAgICIgICRvbmVvZl9uYW1lJF8gPSAkdHlwZSQubmV3QnVpbGRlcigoJHR5cGUkKSAkb25lb2ZfbmFtZSRfKVxuIgorICAgICIgICAgICAubWVyZ2VGcm9tKHZhbHVlKS5idWlsZFBhcnRpYWwoKTtcbiIKKyAgICAifSBlbHNlIHtcbiIKKyAgICAiICAkb25lb2ZfbmFtZSRfID0gdmFsdWU7XG4iCisgICAgIn1cbiIKKyAgICAiJG9uX2NoYW5nZWQkXG4iLAorCisgICAgImlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIKKyAgICAiICAkbmFtZSRCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpO1xuIgorICAgICJ9XG4iCisgICAgIiRuYW1lJEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpO1xuIiwKKworICAgICIkc2V0X29uZW9mX2Nhc2VfbWVzc2FnZSQ7XG4iCisgICAgInJldHVybiB0aGlzO1xuIik7CisKKyAgLy8gRmllbGQuQnVpbGRlciBjbGVhckZpZWxkKCkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBQcmludE5lc3RlZEJ1aWxkZXJGdW5jdGlvbihwcmludGVyLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgY2xlYXIkY2FwaXRhbGl6ZWRfbmFtZSQoKSIsCisKKyAgICAiaWYgKCRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJCkge1xuIgorICAgICIgICRjbGVhcl9vbmVvZl9jYXNlX21lc3NhZ2UkO1xuIgorICAgICIgICRvbmVvZl9uYW1lJF8gPSBudWxsO1xuIgorICAgICIgICRvbl9jaGFuZ2VkJFxuIgorICAgICJ9XG4iLAorCisgICAgImlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIKKyAgICAiICAkY2xlYXJfb25lb2ZfY2FzZV9tZXNzYWdlJDtcbiIKKyAgICAiICAkb25lb2ZfbmFtZSRfID0gbnVsbDtcbiIKKyAgICAifVxuIgorICAgICIkbmFtZSRCdWlsZGVyXy5jbGVhcigpO1xuIiwKKworICAgICJyZXR1cm4gdGhpcztcbiIpOworCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSQuQnVpbGRlciBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRCdWlsZGVyKCkge1xuIgorICAgICIgIHJldHVybiBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkT3JCdWlsZGVyIGdldCRjYXBpdGFsaXplZF9uYW1lJE9yQnVpbGRlcigpIHtcbiIKKyAgICAiICBpZiAoKCRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJCkgJiYgKCRuYW1lJEJ1aWxkZXJfICE9IG51bGwpKSB7XG4iCisgICAgIiAgICByZXR1cm4gJG5hbWUkQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpO1xuIgorICAgICIgIH0gZWxzZSB7XG4iCisgICAgIiAgICBpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iCisgICAgIiAgICAgIHJldHVybiAoJHR5cGUkKSAkb25lb2ZfbmFtZSRfO1xuIgorICAgICIgICAgfVxuIgorICAgICIgICAgcmV0dXJuICR0eXBlJC5nZXREZWZhdWx0SW5zdGFuY2UoKTtcbiIKKyAgICAiICB9XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXI8XG4iCisgICAgIiAgICAkdHlwZSQsICR0eXBlJC5CdWlsZGVyLCAkdHlwZSRPckJ1aWxkZXI+IFxuIgorICAgICIgICAgZ2V0JGNhcGl0YWxpemVkX25hbWUkRmllbGRCdWlsZGVyKCkge1xuIgorICAgICIgIGlmICgkbmFtZSRCdWlsZGVyXyA9PSBudWxsKSB7XG4iCisgICAgIiAgICBpZiAoISgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpKSB7XG4iCisgICAgIiAgICAgICRvbmVvZl9uYW1lJF8gPSAkdHlwZSQuZ2V0RGVmYXVsdEluc3RhbmNlKCk7XG4iCisgICAgIiAgICB9XG4iCisgICAgIiAgICAkbmFtZSRCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlcjxcbiIKKyAgICAiICAgICAgICAkdHlwZSQsICR0eXBlJC5CdWlsZGVyLCAkdHlwZSRPckJ1aWxkZXI+KFxuIgorICAgICIgICAgICAgICAgICAoJHR5cGUkKSAkb25lb2ZfbmFtZSRfLFxuIgorICAgICIgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLFxuIgorICAgICIgICAgICAgICAgICBpc0NsZWFuKCkpO1xuIgorICAgICIgICAgJG9uZW9mX25hbWUkXyA9IG51bGw7XG4iCisgICAgIiAgfVxuIgorICAgICIgICRzZXRfb25lb2ZfY2FzZV9tZXNzYWdlJDtcbiIKKyAgICAiICAkb25fY2hhbmdlZCQ7XG4iCisgICAgIiAgcmV0dXJuICRuYW1lJEJ1aWxkZXJfO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUJ1aWxkaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworCisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICAgICAgICAgICJpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgUHJpbnROZXN0ZWRCdWlsZGVyQ29uZGl0aW9uKHByaW50ZXIsCisgICAgInJlc3VsdC4kb25lb2ZfbmFtZSRfID0gJG9uZW9mX25hbWUkXztcbiIsCisKKyAgICAicmVzdWx0LiRvbmVvZl9uYW1lJF8gPSAkbmFtZSRCdWlsZGVyXy5idWlsZCgpO1xuIik7CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgifVxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlTWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJtZXJnZSRjYXBpdGFsaXplZF9uYW1lJChvdGhlci5nZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSk7XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVBhcnNpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiR0eXBlJC5CdWlsZGVyIHN1YkJ1aWxkZXIgPSBudWxsO1xuIgorICAgICJpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iCisgICAgIiAgc3ViQnVpbGRlciA9ICgoJHR5cGUkKSAkb25lb2ZfbmFtZSRfKS50b0J1aWxkZXIoKTtcbiIKKyAgICAifVxuIik7CisKKyAgaWYgKEdldFR5cGUoZGVzY3JpcHRvcl8pID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9HUk9VUCkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJG9uZW9mX25hbWUkXyA9IGlucHV0LnJlYWRHcm91cCgkbnVtYmVyJCwgJHR5cGUkLnBhcnNlcigpLFxuIgorICAgICAgIiAgICBleHRlbnNpb25SZWdpc3RyeSk7XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRvbmVvZl9uYW1lJF8gPVxuIgorICAgICAgIiAgICBpbnB1dC5yZWFkTWVzc2FnZSgkdHlwZSQucGFyc2VyKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTtcbiIpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKHN1YkJ1aWxkZXIgIT0gbnVsbCkge1xuIgorICAgICIgIHN1YkJ1aWxkZXIubWVyZ2VGcm9tKCgkdHlwZSQpICRvbmVvZl9uYW1lJF8pO1xuIgorICAgICIgICRvbmVvZl9uYW1lJF8gPSBzdWJCdWlsZGVyLmJ1aWxkUGFydGlhbCgpO1xuIgorICAgICJ9XG4iKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJHNldF9vbmVvZl9jYXNlX21lc3NhZ2UkO1xuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlTWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iCisgICAgIiAgb3V0cHV0LndyaXRlJGdyb3VwX29yX21lc3NhZ2UkKCRudW1iZXIkLCAoJHR5cGUkKSAkb25lb2ZfbmFtZSRfKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlTWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJCkge1xuIgorICAgICIgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbVxuIgorICAgICIgICAgLmNvbXB1dGUkZ3JvdXBfb3JfbWVzc2FnZSRTaXplKCRudW1iZXIkLCAoJHR5cGUkKSAkb25lb2ZfbmFtZSRfKTtcbiIKKyAgICAifVxuIik7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworUmVwZWF0ZWRJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorUmVwZWF0ZWRJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG1lc3NhZ2VCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBidWlsZGVyQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb250ZXh0KiBjb250ZXh0KQorICA6IGRlc2NyaXB0b3JfKGRlc2NyaXB0b3IpLCBtZXNzYWdlQml0SW5kZXhfKG1lc3NhZ2VCaXRJbmRleCksCisgICAgYnVpbGRlckJpdEluZGV4XyhidWlsZGVyQml0SW5kZXgpLCBjb250ZXh0Xyhjb250ZXh0KSwKKyAgICBuYW1lX3Jlc29sdmVyXyhjb250ZXh0LT5HZXROYW1lUmVzb2x2ZXIoKSkgIHsKKyAgU2V0TWVzc2FnZVZhcmlhYmxlcyhkZXNjcmlwdG9yLCBtZXNzYWdlQml0SW5kZXgsIGJ1aWxkZXJCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LT5HZXRGaWVsZEdlbmVyYXRvckluZm8oZGVzY3JpcHRvciksCisgICAgICAgICAgICAgICAgICAgICAgbmFtZV9yZXNvbHZlcl8sICZ2YXJpYWJsZXNfKTsKK30KKworUmVwZWF0ZWRJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorflJlcGVhdGVkSW1tdXRhYmxlTWVzc2FnZUZpZWxkR2VuZXJhdG9yKCkge30KKworaW50IFJlcGVhdGVkSW1tdXRhYmxlTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjpHZXROdW1CaXRzRm9yTWVzc2FnZSgpIGNvbnN0IHsKKyAgcmV0dXJuIDA7Cit9CisKK2ludCBSZXBlYXRlZEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6R2V0TnVtQml0c0ZvckJ1aWxkZXIoKSBjb25zdCB7CisgIHJldHVybiAxOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlSW50ZXJmYWNlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBUT0RPKGpvbnApOiBJbiB0aGUgZnV0dXJlLCBjb25zaWRlciBoYXZpbmcgbWV0aG9kcyBzcGVjaWZpYyB0byB0aGUKKyAgLy8gaW50ZXJmYWNlIHNvIHRoYXQgYnVpbGRlcnMgY2FuIGNob29zZSBkeW5hbWljYWxseSB0byBlaXRoZXIgcmV0dXJuIGEKKyAgLy8gbWVzc2FnZSBvciBhIG5lc3RlZCBidWlsZGVyLCBzbyB0aGF0IGFza2luZyBmb3IgdGhlIGludGVyZmFjZSBkb2Vzbid0CisgIC8vIGNhdXNlIGEgbWVzc2FnZSB0byBldmVyIGJlIGJ1aWx0LgorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRqYXZhLnV0aWwuTGlzdDwkdHlwZSQ+IFxuIgorICAgICIgICAgZ2V0JGNhcGl0YWxpemVkX25hbWUkTGlzdCgpO1xuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJCR0eXBlJCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoaW50IGluZGV4KTtcbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRpbnQgZ2V0JGNhcGl0YWxpemVkX25hbWUkQ291bnQoKTtcbiIpOworCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyAkdHlwZSRPckJ1aWxkZXI+IFxuIgorICAgICIgICAgZ2V0JGNhcGl0YWxpemVkX25hbWUkT3JCdWlsZGVyTGlzdCgpO1xuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJCR0eXBlJE9yQnVpbGRlciBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRPckJ1aWxkZXIoXG4iCisgICAgIiAgICBpbnQgaW5kZXgpO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgamF2YS51dGlsLkxpc3Q8JHR5cGUkPiAkbmFtZSRfO1xuIik7CisgIFByaW50RXh0cmFGaWVsZEluZm8odmFyaWFibGVzXywgcHJpbnRlcik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBqYXZhLnV0aWwuTGlzdDwkdHlwZSQ+IGdldCRjYXBpdGFsaXplZF9uYW1lJExpc3QoKSB7XG4iCisgICAgIiAgcmV0dXJuICRuYW1lJF87XG4iICAgLy8gbm90ZTogIHVubW9kaWZpYWJsZSBsaXN0CisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzICR0eXBlJE9yQnVpbGRlcj4gXG4iCisgICAgIiAgICBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRPckJ1aWxkZXJMaXN0KCkge1xuIgorICAgICIgIHJldHVybiAkbmFtZSRfO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIGludCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRDb3VudCgpIHtcbiIKKyAgICAiICByZXR1cm4gJG5hbWUkXy5zaXplKCk7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkIGdldCRjYXBpdGFsaXplZF9uYW1lJChpbnQgaW5kZXgpIHtcbiIKKyAgICAiICByZXR1cm4gJG5hbWUkXy5nZXQoaW5kZXgpO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljICR0eXBlJE9yQnVpbGRlciBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRPckJ1aWxkZXIoXG4iCisgICAgIiAgICBpbnQgaW5kZXgpIHtcbiIKKyAgICAiICByZXR1cm4gJG5hbWUkXy5nZXQoaW5kZXgpO1xuIgorICAgICJ9XG4iKTsKKworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjpQcmludE5lc3RlZEJ1aWxkZXJDb25kaXRpb24oCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgY29uc3QgY2hhciogcmVndWxhcl9jYXNlLAorICAgIGNvbnN0IGNoYXIqIG5lc3RlZF9idWlsZGVyX2Nhc2UpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgImlmICgkbmFtZSRCdWlsZGVyXyA9PSBudWxsKSB7XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sIHJlZ3VsYXJfY2FzZSk7CisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoIn0gZWxzZSB7XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sIG5lc3RlZF9idWlsZGVyX2Nhc2UpOworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KCJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6UHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24oCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgY29uc3QgY2hhciogbWV0aG9kX3Byb3RvdHlwZSwKKyAgICBjb25zdCBjaGFyKiByZWd1bGFyX2Nhc2UsCisgICAgY29uc3QgY2hhciogbmVzdGVkX2J1aWxkZXJfY2FzZSwKKyAgICBjb25zdCBjaGFyKiB0cmFpbGluZ19jb2RlKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sIG1ldGhvZF9wcm90b3R5cGUpOworICBwcmludGVyLT5QcmludCgiIHtcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKyAgUHJpbnROZXN0ZWRCdWlsZGVyQ29uZGl0aW9uKHByaW50ZXIsIHJlZ3VsYXJfY2FzZSwgbmVzdGVkX2J1aWxkZXJfY2FzZSk7CisgIGlmICh0cmFpbGluZ19jb2RlICE9IE5VTEwpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCB0cmFpbGluZ19jb2RlKTsKKyAgfQorICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KCJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUJ1aWxkZXJNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIFdoZW4gdXNpbmcgbmVzdGVkLWJ1aWxkZXJzLCB0aGUgY29kZSBpbml0aWFsbHkgd29ya3MganVzdCBsaWtlIHRoZQorICAvLyBub24tbmVzdGVkIGJ1aWxkZXIgY2FzZS4gSXQgb25seSBjcmVhdGVzIGEgbmVzdGVkIGJ1aWxkZXIgbGF6aWx5IG9uCisgIC8vIGRlbWFuZCBhbmQgdGhlbiBmb3JldmVyIGRlbGVnYXRlcyB0byBpdCBhZnRlciBjcmVhdGlvbi4KKworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgIC8vIFVzZWQgd2hlbiB0aGUgYnVpbGRlciBpcyBudWxsLgorICAgIC8vIE9uZSBmaWVsZCBpcyB0aGUgbGlzdCBhbmQgdGhlIG90aGVyIGZpZWxkIGtlZXBzIHRyYWNrIG9mIHdoZXRoZXIgdGhlCisgICAgLy8gbGlzdCBpcyBpbW11dGFibGUuIElmIGl0J3MgaW1tdXRhYmxlLCB0aGUgaW52YXJpYW50IGlzIHRoYXQgaXQgbXVzdAorICAgIC8vIGVpdGhlciBhbiBpbnN0YW5jZSBvZiBDb2xsZWN0aW9ucy5lbXB0eUxpc3QoKSBvciBpdCdzIGFuIEFycmF5TGlzdAorICAgIC8vIHdyYXBwZWQgaW4gYSBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KCkgd3JhcHBlciBhbmQgbm9ib2R5IGVsc2UgaGFzCisgICAgLy8gYSByZWZlcmVyZW5jZSB0byB0aGUgdW5kZXJseWluZyBBcnJheUxpc3QuIFRoaXMgaW52YXJpYW50IGFsbG93cyB1cyB0bworICAgIC8vIHNoYXJlIGluc3RhbmNlcyBvZiBsaXN0cyBiZXR3ZWVuIHByb3RvY29sIGJ1ZmZlcnMgYXZvaWRpbmcgZXhwZW5zaXZlCisgICAgLy8gbWVtb3J5IGFsbG9jYXRpb25zLiBOb3RlLCBpbW11dGFibGUgaXMgYSBzdHJvbmcgZ3VhcmFudGVlIGhlcmUgLS0gbm90CisgICAgLy8ganVzdCB0aGF0IHRoZSBsaXN0IGNhbm5vdCBiZSBtb2RpZmllZCB2aWEgdGhlIHJlZmVyZW5jZSBidXQgdGhhdCB0aGUKKyAgICAvLyBsaXN0IGNhbiBuZXZlciBiZSBtb2RpZmllZC4KKyAgICAicHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDwkdHlwZSQ+ICRuYW1lJF8gPVxuIgorICAgICIgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTtcbiIKKworICAgICJwcml2YXRlIHZvaWQgZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCkge1xuIgorICAgICIgIGlmICghJGdldF9tdXRhYmxlX2JpdF9idWlsZGVyJCkge1xuIgorICAgICIgICAgJG5hbWUkXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PCR0eXBlJD4oJG5hbWUkXyk7XG4iCisgICAgIiAgICAkc2V0X211dGFibGVfYml0X2J1aWxkZXIkO1xuIgorICAgICIgICB9XG4iCisgICAgIn1cbiIKKyAgICAiXG4iKTsKKworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgIC8vIElmIHRoaXMgYnVpbGRlciBpcyBub24tbnVsbCwgaXQgaXMgdXNlZCBhbmQgdGhlIG90aGVyIGZpZWxkcyBhcmUKKyAgICAvLyBpZ25vcmVkLgorICAgICJwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXI8XG4iCisgICAgIiAgICAkdHlwZSQsICR0eXBlJC5CdWlsZGVyLCAkdHlwZSRPckJ1aWxkZXI+ICRuYW1lJEJ1aWxkZXJfO1xuIgorICAgICJcbiIpOworCisgIC8vIFRoZSBjb21tZW50cyBhYm92ZSB0aGUgbWV0aG9kcyBiZWxvdyBhcmUgYmFzZWQgb24gYSBoeXBvdGhldGljYWwKKyAgLy8gcmVwZWF0ZWQgZmllbGQgb2YgdHlwZSAiRmllbGQiIGNhbGxlZCAiUmVwZWF0ZWRGaWVsZCIuCisKKyAgLy8gTGlzdDxGaWVsZD4gZ2V0UmVwZWF0ZWRGaWVsZExpc3QoKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIFByaW50TmVzdGVkQnVpbGRlckZ1bmN0aW9uKHByaW50ZXIsCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgamF2YS51dGlsLkxpc3Q8JHR5cGUkPiBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRMaXN0KCkiLAorCisgICAgInJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdCgkbmFtZSRfKTtcbiIsCisgICAgInJldHVybiAkbmFtZSRCdWlsZGVyXy5nZXRNZXNzYWdlTGlzdCgpO1xuIiwKKworICAgIE5VTEwpOworCisgIC8vIGludCBnZXRSZXBlYXRlZEZpZWxkQ291bnQoKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIFByaW50TmVzdGVkQnVpbGRlckZ1bmN0aW9uKHByaW50ZXIsCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgaW50IGdldCRjYXBpdGFsaXplZF9uYW1lJENvdW50KCkiLAorCisgICAgInJldHVybiAkbmFtZSRfLnNpemUoKTtcbiIsCisgICAgInJldHVybiAkbmFtZSRCdWlsZGVyXy5nZXRDb3VudCgpO1xuIiwKKworICAgIE5VTEwpOworCisgIC8vIEZpZWxkIGdldFJlcGVhdGVkRmllbGQoaW50IGluZGV4KQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIFByaW50TmVzdGVkQnVpbGRlckZ1bmN0aW9uKHByaW50ZXIsCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkIGdldCRjYXBpdGFsaXplZF9uYW1lJChpbnQgaW5kZXgpIiwKKworICAgICJyZXR1cm4gJG5hbWUkXy5nZXQoaW5kZXgpO1xuIiwKKworICAgICJyZXR1cm4gJG5hbWUkQnVpbGRlcl8uZ2V0TWVzc2FnZShpbmRleCk7XG4iLAorCisgICAgTlVMTCk7CisKKyAgLy8gQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKGludCBpbmRleCwgRmllbGQgdmFsdWUpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgUHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24ocHJpbnRlciwKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIHNldCRjYXBpdGFsaXplZF9uYW1lJChcbiIKKyAgICAiICAgIGludCBpbmRleCwgJHR5cGUkIHZhbHVlKSIsCisgICAgImlmICh2YWx1ZSA9PSBudWxsKSB7XG4iCisgICAgIiAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7XG4iCisgICAgIn1cbiIKKyAgICAiZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCk7XG4iCisgICAgIiRuYW1lJF8uc2V0KGluZGV4LCB2YWx1ZSk7XG4iCisgICAgIiRvbl9jaGFuZ2VkJFxuIiwKKyAgICAiJG5hbWUkQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgdmFsdWUpO1xuIiwKKyAgICAicmV0dXJuIHRoaXM7XG4iKTsKKworICAvLyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoaW50IGluZGV4LCBGaWVsZC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBQcmludE5lc3RlZEJ1aWxkZXJGdW5jdGlvbihwcmludGVyLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgc2V0JGNhcGl0YWxpemVkX25hbWUkKFxuIgorICAgICIgICAgaW50IGluZGV4LCAkdHlwZSQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIiwKKworICAgICJlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKTtcbiIKKyAgICAiJG5hbWUkXy5zZXQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTtcbiIKKyAgICAiJG9uX2NoYW5nZWQkXG4iLAorCisgICAgIiRuYW1lJEJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTtcbiIsCisKKyAgICAicmV0dXJuIHRoaXM7XG4iKTsKKworICAvLyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoRmllbGQgdmFsdWUpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgUHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24ocHJpbnRlciwKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGFkZCRjYXBpdGFsaXplZF9uYW1lJCgkdHlwZSQgdmFsdWUpIiwKKworICAgICJpZiAodmFsdWUgPT0gbnVsbCkge1xuIgorICAgICIgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpO1xuIgorICAgICJ9XG4iCisgICAgImVuc3VyZSRjYXBpdGFsaXplZF9uYW1lJElzTXV0YWJsZSgpO1xuIgorICAgICIkbmFtZSRfLmFkZCh2YWx1ZSk7XG4iCisKKyAgICAiJG9uX2NoYW5nZWQkXG4iLAorCisgICAgIiRuYW1lJEJ1aWxkZXJfLmFkZE1lc3NhZ2UodmFsdWUpO1xuIiwKKworICAgICJyZXR1cm4gdGhpcztcbiIpOworCisgIC8vIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZChpbnQgaW5kZXgsIEZpZWxkIHZhbHVlKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIFByaW50TmVzdGVkQnVpbGRlckZ1bmN0aW9uKHByaW50ZXIsCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBhZGQkY2FwaXRhbGl6ZWRfbmFtZSQoXG4iCisgICAgIiAgICBpbnQgaW5kZXgsICR0eXBlJCB2YWx1ZSkiLAorCisgICAgImlmICh2YWx1ZSA9PSBudWxsKSB7XG4iCisgICAgIiAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7XG4iCisgICAgIn1cbiIKKyAgICAiZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCk7XG4iCisgICAgIiRuYW1lJF8uYWRkKGluZGV4LCB2YWx1ZSk7XG4iCisgICAgIiRvbl9jaGFuZ2VkJFxuIiwKKworICAgICIkbmFtZSRCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7XG4iLAorCisgICAgInJldHVybiB0aGlzO1xuIik7CisKKyAgLy8gQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKEZpZWxkLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIFByaW50TmVzdGVkQnVpbGRlckZ1bmN0aW9uKHByaW50ZXIsCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBhZGQkY2FwaXRhbGl6ZWRfbmFtZSQoXG4iCisgICAgIiAgICAkdHlwZSQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIiwKKworICAgICJlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKTtcbiIKKyAgICAiJG5hbWUkXy5hZGQoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpO1xuIgorICAgICIkb25fY2hhbmdlZCRcbiIsCisKKyAgICAiJG5hbWUkQnVpbGRlcl8uYWRkTWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7XG4iLAorCisgICAgInJldHVybiB0aGlzO1xuIik7CisKKyAgLy8gQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKGludCBpbmRleCwgRmllbGQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgUHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24ocHJpbnRlciwKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGFkZCRjYXBpdGFsaXplZF9uYW1lJChcbiIKKyAgICAiICAgIGludCBpbmRleCwgJHR5cGUkLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSIsCisKKyAgICAiZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCk7XG4iCisgICAgIiRuYW1lJF8uYWRkKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7XG4iCisgICAgIiRvbl9jaGFuZ2VkJFxuIiwKKworICAgICIkbmFtZSRCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7XG4iLAorCisgICAgInJldHVybiB0aGlzO1xuIik7CisKKyAgLy8gQnVpbGRlciBhZGRBbGxSZXBlYXRlZEZpZWxkKEl0ZXJhYmxlPEZpZWxkPiB2YWx1ZXMpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgUHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24ocHJpbnRlciwKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGFkZEFsbCRjYXBpdGFsaXplZF9uYW1lJChcbiIKKyAgICAiICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgJHR5cGUkPiB2YWx1ZXMpIiwKKworICAgICJlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKTtcbiIKKyAgICAiY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKFxuIgorICAgICIgICAgdmFsdWVzLCAkbmFtZSRfKTtcbiIKKyAgICAiJG9uX2NoYW5nZWQkXG4iLAorCisgICAgIiRuYW1lJEJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKHZhbHVlcyk7XG4iLAorCisgICAgInJldHVybiB0aGlzO1xuIik7CisKKyAgLy8gQnVpbGRlciBjbGVhckFsbFJlcGVhdGVkRmllbGQoKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIFByaW50TmVzdGVkQnVpbGRlckZ1bmN0aW9uKHByaW50ZXIsCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBjbGVhciRjYXBpdGFsaXplZF9uYW1lJCgpIiwKKworICAgICIkbmFtZSRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpO1xuIgorICAgICIkY2xlYXJfbXV0YWJsZV9iaXRfYnVpbGRlciQ7XG4iCisgICAgIiRvbl9jaGFuZ2VkJFxuIiwKKworICAgICIkbmFtZSRCdWlsZGVyXy5jbGVhcigpO1xuIiwKKworICAgICJyZXR1cm4gdGhpcztcbiIpOworCisgIC8vIEJ1aWxkZXIgcmVtb3ZlUmVwZWF0ZWRGaWVsZChpbnQgaW5kZXgpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgUHJpbnROZXN0ZWRCdWlsZGVyRnVuY3Rpb24ocHJpbnRlciwKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIHJlbW92ZSRjYXBpdGFsaXplZF9uYW1lJChpbnQgaW5kZXgpIiwKKworICAgICJlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKTtcbiIKKyAgICAiJG5hbWUkXy5yZW1vdmUoaW5kZXgpO1xuIgorICAgICIkb25fY2hhbmdlZCRcbiIsCisKKyAgICAiJG5hbWUkQnVpbGRlcl8ucmVtb3ZlKGluZGV4KTtcbiIsCisKKyAgICAicmV0dXJuIHRoaXM7XG4iKTsKKworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkLkJ1aWxkZXIgZ2V0JGNhcGl0YWxpemVkX25hbWUkQnVpbGRlcihcbiIKKyAgICAiICAgIGludCBpbmRleCkge1xuIgorICAgICIgIHJldHVybiBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKGluZGV4KTtcbiIKKyAgICAifVxuIik7CisKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSRPckJ1aWxkZXIgZ2V0JGNhcGl0YWxpemVkX25hbWUkT3JCdWlsZGVyKFxuIgorICAgICIgICAgaW50IGluZGV4KSB7XG4iCisgICAgIiAgaWYgKCRuYW1lJEJ1aWxkZXJfID09IG51bGwpIHtcbiIKKyAgICAiICAgIHJldHVybiAkbmFtZSRfLmdldChpbmRleCk7IgorICAgICIgIH0gZWxzZSB7XG4iCisgICAgIiAgICByZXR1cm4gJG5hbWUkQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcihpbmRleCk7XG4iCisgICAgIiAgfVxuIgorICAgICJ9XG4iKTsKKworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyAkdHlwZSRPckJ1aWxkZXI+IFxuIgorICAgICIgICAgIGdldCRjYXBpdGFsaXplZF9uYW1lJE9yQnVpbGRlckxpc3QoKSB7XG4iCisgICAgIiAgaWYgKCRuYW1lJEJ1aWxkZXJfICE9IG51bGwpIHtcbiIKKyAgICAiICAgIHJldHVybiAkbmFtZSRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpO1xuIgorICAgICIgIH0gZWxzZSB7XG4iCisgICAgIiAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoJG5hbWUkXyk7XG4iCisgICAgIiAgfVxuIgorICAgICJ9XG4iKTsKKworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljICR0eXBlJC5CdWlsZGVyIGFkZCRjYXBpdGFsaXplZF9uYW1lJEJ1aWxkZXIoKSB7XG4iCisgICAgIiAgcmV0dXJuIGdldCRjYXBpdGFsaXplZF9uYW1lJEZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoXG4iCisgICAgIiAgICAgICR0eXBlJC5nZXREZWZhdWx0SW5zdGFuY2UoKSk7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljICR0eXBlJC5CdWlsZGVyIGFkZCRjYXBpdGFsaXplZF9uYW1lJEJ1aWxkZXIoXG4iCisgICAgIiAgICBpbnQgaW5kZXgpIHtcbiIKKyAgICAiICByZXR1cm4gZ2V0JGNhcGl0YWxpemVkX25hbWUkRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcihcbiIKKyAgICAiICAgICAgaW5kZXgsICR0eXBlJC5nZXREZWZhdWx0SW5zdGFuY2UoKSk7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIGphdmEudXRpbC5MaXN0PCR0eXBlJC5CdWlsZGVyPiBcbiIKKyAgICAiICAgICBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRCdWlsZGVyTGlzdCgpIHtcbiIKKyAgICAiICByZXR1cm4gZ2V0JGNhcGl0YWxpemVkX25hbWUkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlckxpc3QoKTtcbiIKKyAgICAifVxuIgorICAgICJwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXI8XG4iCisgICAgIiAgICAkdHlwZSQsICR0eXBlJC5CdWlsZGVyLCAkdHlwZSRPckJ1aWxkZXI+IFxuIgorICAgICIgICAgZ2V0JGNhcGl0YWxpemVkX25hbWUkRmllbGRCdWlsZGVyKCkge1xuIgorICAgICIgIGlmICgkbmFtZSRCdWlsZGVyXyA9PSBudWxsKSB7XG4iCisgICAgIiAgICAkbmFtZSRCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyPFxuIgorICAgICIgICAgICAgICR0eXBlJCwgJHR5cGUkLkJ1aWxkZXIsICR0eXBlJE9yQnVpbGRlcj4oXG4iCisgICAgIiAgICAgICAgICAgICRuYW1lJF8sXG4iCisgICAgIiAgICAgICAgICAgICRnZXRfbXV0YWJsZV9iaXRfYnVpbGRlciQsXG4iCisgICAgIiAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksXG4iCisgICAgIiAgICAgICAgICAgIGlzQ2xlYW4oKSk7XG4iCisgICAgIiAgICAkbmFtZSRfID0gbnVsbDtcbiIKKyAgICAiICB9XG4iCisgICAgIiAgcmV0dXJuICRuYW1lJEJ1aWxkZXJfO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUZpZWxkQnVpbGRlckluaXRpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiZ2V0JGNhcGl0YWxpemVkX25hbWUkRmllbGRCdWlsZGVyKCk7XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUluaXRpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAiJG5hbWUkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRlckNsZWFyQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBQcmludE5lc3RlZEJ1aWxkZXJDb25kaXRpb24ocHJpbnRlciwKKyAgICAiJG5hbWUkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTtcbiIKKyAgICAiJGNsZWFyX211dGFibGVfYml0X2J1aWxkZXIkO1xuIiwKKworICAgICIkbmFtZSRCdWlsZGVyXy5jbGVhcigpO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBUaGUgY29kZSBiZWxvdyBkb2VzIHR3byBvcHRpbWl6YXRpb25zIChub24tbmVzdGVkIGJ1aWxkZXIgY2FzZSk6CisgIC8vICAgMS4gSWYgdGhlIG90aGVyIGxpc3QgaXMgZW1wdHksIHRoZXJlJ3Mgbm90aGluZyB0byBkby4gVGhpcyBlbnN1cmVzIHdlCisgIC8vICAgICAgZG9uJ3QgYWxsb2NhdGUgYSBuZXcgYXJyYXkgaWYgd2UgYWxyZWFkeSBoYXZlIGFuIGltbXV0YWJsZSBvbmUuCisgIC8vICAgMi4gSWYgdGhlIG90aGVyIGxpc3QgaXMgbm9uLWVtcHR5IGFuZCBvdXIgY3VycmVudCBsaXN0IGlzIGVtcHR5LCB3ZSBjYW4KKyAgLy8gICAgICByZXVzZSB0aGUgb3RoZXIgbGlzdCB3aGljaCBpcyBndWFyYW50ZWVkIHRvIGJlIGltbXV0YWJsZS4KKyAgUHJpbnROZXN0ZWRCdWlsZGVyQ29uZGl0aW9uKHByaW50ZXIsCisgICAgImlmICghb3RoZXIuJG5hbWUkXy5pc0VtcHR5KCkpIHtcbiIKKyAgICAiICBpZiAoJG5hbWUkXy5pc0VtcHR5KCkpIHtcbiIKKyAgICAiICAgICRuYW1lJF8gPSBvdGhlci4kbmFtZSRfO1xuIgorICAgICIgICAgJGNsZWFyX211dGFibGVfYml0X2J1aWxkZXIkO1xuIgorICAgICIgIH0gZWxzZSB7XG4iCisgICAgIiAgICBlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKTtcbiIKKyAgICAiICAgICRuYW1lJF8uYWRkQWxsKG90aGVyLiRuYW1lJF8pO1xuIgorICAgICIgIH1cbiIKKyAgICAiICAkb25fY2hhbmdlZCRcbiIKKyAgICAifVxuIiwKKworICAgICJpZiAoIW90aGVyLiRuYW1lJF8uaXNFbXB0eSgpKSB7XG4iCisgICAgIiAgaWYgKCRuYW1lJEJ1aWxkZXJfLmlzRW1wdHkoKSkge1xuIgorICAgICIgICAgJG5hbWUkQnVpbGRlcl8uZGlzcG9zZSgpO1xuIgorICAgICIgICAgJG5hbWUkQnVpbGRlcl8gPSBudWxsO1xuIgorICAgICIgICAgJG5hbWUkXyA9IG90aGVyLiRuYW1lJF87XG4iCisgICAgIiAgICAkY2xlYXJfbXV0YWJsZV9iaXRfYnVpbGRlciQ7XG4iCisgICAgIiAgICAkbmFtZSRCdWlsZGVyXyA9IFxuIgorICAgICIgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuYWx3YXlzVXNlRmllbGRCdWlsZGVycyA/XG4iCisgICAgIiAgICAgICAgIGdldCRjYXBpdGFsaXplZF9uYW1lJEZpZWxkQnVpbGRlcigpIDogbnVsbDtcbiIKKyAgICAiICB9IGVsc2Uge1xuIgorICAgICIgICAgJG5hbWUkQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXMob3RoZXIuJG5hbWUkXyk7XG4iCisgICAgIiAgfVxuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUJ1aWxkaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBUaGUgY29kZSBiZWxvdyAobm9uLW5lc3RlZCBidWlsZGVyIGNhc2UpIGVuc3VyZXMgdGhhdCB0aGUgcmVzdWx0IGhhcyBhbgorICAvLyBpbW11dGFibGUgbGlzdC4gSWYgb3VyIGxpc3QgaXMgaW1tdXRhYmxlLCB3ZSBjYW4ganVzdCByZXVzZSBpdC4gSWYgbm90LAorICAvLyB3ZSBtYWtlIGl0IGltbXV0YWJsZS4KKyAgUHJpbnROZXN0ZWRCdWlsZGVyQ29uZGl0aW9uKHByaW50ZXIsCisgICAgImlmICgkZ2V0X211dGFibGVfYml0X2J1aWxkZXIkKSB7XG4iCisgICAgIiAgJG5hbWUkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KCRuYW1lJF8pO1xuIgorICAgICIgICRjbGVhcl9tdXRhYmxlX2JpdF9idWlsZGVyJDtcbiIKKyAgICAifVxuIgorICAgICJyZXN1bHQuJG5hbWUkXyA9ICRuYW1lJF87XG4iLAorCisgICAgInJlc3VsdC4kbmFtZSRfID0gJG5hbWUkQnVpbGRlcl8uYnVpbGQoKTtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCEkZ2V0X211dGFibGVfYml0X3BhcnNlciQpIHtcbiIKKyAgICAiICAkbmFtZSRfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8JHR5cGUkPigpO1xuIgorICAgICIgICRzZXRfbXV0YWJsZV9iaXRfcGFyc2VyJDtcbiIKKyAgICAifVxuIik7CisKKyAgaWYgKEdldFR5cGUoZGVzY3JpcHRvcl8pID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9HUk9VUCkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJG5hbWUkXy5hZGQoaW5wdXQucmVhZEdyb3VwKCRudW1iZXIkLCAkdHlwZSQucGFyc2VyKCksXG4iCisgICAgICAiICAgIGV4dGVuc2lvblJlZ2lzdHJ5KSk7XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRuYW1lJF8uYWRkKGlucHV0LnJlYWRNZXNzYWdlKCR0eXBlJC5wYXJzZXIoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpKTtcbiIpOworICB9Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVQYXJzaW5nRG9uZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCRnZXRfbXV0YWJsZV9iaXRfcGFyc2VyJCkge1xuIgorICAgICIgICRuYW1lJF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdCgkbmFtZSRfKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJmb3IgKGludCBpID0gMDsgaSA8ICRuYW1lJF8uc2l6ZSgpOyBpKyspIHtcbiIKKyAgICAiICBvdXRwdXQud3JpdGUkZ3JvdXBfb3JfbWVzc2FnZSQoJG51bWJlciQsICRuYW1lJF8uZ2V0KGkpKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiZm9yIChpbnQgaSA9IDA7IGkgPCAkbmFtZSRfLnNpemUoKTsgaSsrKSB7XG4iCisgICAgIiAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtXG4iCisgICAgIiAgICAuY29tcHV0ZSRncm91cF9vcl9tZXNzYWdlJFNpemUoJG51bWJlciQsICRuYW1lJF8uZ2V0KGkpKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVFcXVhbHNDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInJlc3VsdCA9IHJlc3VsdCAmJiBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRMaXN0KClcbiIKKyAgICAiICAgIC5lcXVhbHMob3RoZXIuZ2V0JGNhcGl0YWxpemVkX25hbWUkTGlzdCgpKTtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlSGFzaENvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKGdldCRjYXBpdGFsaXplZF9uYW1lJENvdW50KCkgPiAwKSB7XG4iCisgICAgIiAgaGFzaCA9ICgzNyAqIGhhc2gpICsgJGNvbnN0YW50X25hbWUkO1xuIgorICAgICIgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldCRjYXBpdGFsaXplZF9uYW1lJExpc3QoKS5oYXNoQ29kZSgpO1xuIgorICAgICJ9XG4iKTsKK30KKworc3RyaW5nIFJlcGVhdGVkSW1tdXRhYmxlTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjpHZXRCb3hlZFR5cGUoKSBjb25zdCB7CisgIHJldHVybiBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3JfLT5tZXNzYWdlX3R5cGUoKSk7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbWVzc2FnZV9maWVsZC5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbWVzc2FnZV9maWVsZC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVhODIyNWEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tZXNzYWdlX2ZpZWxkLmgKQEAgLTAsMCArMSwxNzMgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9NRVNTQUdFX0ZJRUxEX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9NRVNTQUdFX0ZJRUxEX0hfXworCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2ZpZWxkLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKyAgbmFtZXNwYWNlIGNvbXBpbGVyIHsKKyAgICBuYW1lc3BhY2UgamF2YSB7CisgICAgICBjbGFzcyBDb250ZXh0OyAgICAgICAgICAgLy8gY29udGV4dC5oCisgICAgICBjbGFzcyBDbGFzc05hbWVSZXNvbHZlcjsgLy8gbmFtZV9yZXNvbHZlci5oCisgICAgfQorICB9Cit9CisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmEgeworCitjbGFzcyBJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3IgOiBwdWJsaWMgSW1tdXRhYmxlRmllbGRHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgSW1tdXRhYmxlTWVzc2FnZUZpZWxkR2VuZXJhdG9yKAorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwgQ29udGV4dCogY29udGV4dCk7CisgIH5JbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3IoKTsKKworICAvLyBpbXBsZW1lbnRzIEltbXV0YWJsZUZpZWxkR2VuZXJhdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICBpbnQgR2V0TnVtQml0c0Zvck1lc3NhZ2UoKSBjb25zdDsKKyAgaW50IEdldE51bUJpdHNGb3JCdWlsZGVyKCkgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVJbnRlcmZhY2VNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnVpbGRlck1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUJ1aWxkZXJDbGVhckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnVpbGRpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVBhcnNpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVBhcnNpbmdEb25lQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRmllbGRCdWlsZGVySW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUVxdWFsc0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSGFzaENvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgIHN0cmluZyBHZXRCb3hlZFR5cGUoKSBjb25zdDsKKworIHByb3RlY3RlZDoKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXNfOworICBjb25zdCBpbnQgbWVzc2FnZUJpdEluZGV4XzsKKyAgY29uc3QgaW50IGJ1aWxkZXJCaXRJbmRleF87CisgIENvbnRleHQqIGNvbnRleHRfOworICBDbGFzc05hbWVSZXNvbHZlciogbmFtZV9yZXNvbHZlcl87CisKKyAgdm9pZCBQcmludE5lc3RlZEJ1aWxkZXJDb25kaXRpb24oaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICBjb25zdCBjaGFyKiByZWd1bGFyX2Nhc2UsIGNvbnN0IGNoYXIqIG5lc3RlZF9idWlsZGVyX2Nhc2UpIGNvbnN0OworICB2b2lkIFByaW50TmVzdGVkQnVpbGRlckZ1bmN0aW9uKGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgY29uc3QgY2hhciogbWV0aG9kX3Byb3RvdHlwZSwgY29uc3QgY2hhciogcmVndWxhcl9jYXNlLAorICAgICAgY29uc3QgY2hhciogbmVzdGVkX2J1aWxkZXJfY2FzZSwKKyAgICAgIGNvbnN0IGNoYXIqIHRyYWlsaW5nX2NvZGUpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcik7Cit9OworCitjbGFzcyBJbW11dGFibGVNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcgorICAgIDogcHVibGljIEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvciB7CisgcHVibGljOgorICBJbW11dGFibGVNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcigKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwgaW50IG1lc3NhZ2VCaXRJbmRleCwKKyAgICAgIGludCBidWlsZGVyQml0SW5kZXgsIENvbnRleHQqIGNvbnRleHQpOworICB+SW1tdXRhYmxlTWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3IoKTsKKworICB2b2lkIEdlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCdWlsZGluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhJbW11dGFibGVNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcik7Cit9OworCitjbGFzcyBSZXBlYXRlZEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvciA6IHB1YmxpYyBJbW11dGFibGVGaWVsZEdlbmVyYXRvciB7CisgcHVibGljOgorICBleHBsaWNpdCBSZXBlYXRlZEltbXV0YWJsZU1lc3NhZ2VGaWVsZEdlbmVyYXRvcigKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwgaW50IG1lc3NhZ2VCaXRJbmRleCwKKyAgICAgIGludCBidWlsZGVyQml0SW5kZXgsIENvbnRleHQqIGNvbnRleHQpOworICB+UmVwZWF0ZWRJbW11dGFibGVNZXNzYWdlRmllbGRHZW5lcmF0b3IoKTsKKworICAvLyBpbXBsZW1lbnRzIEltbXV0YWJsZUZpZWxkR2VuZXJhdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICBpbnQgR2V0TnVtQml0c0Zvck1lc3NhZ2UoKSBjb25zdDsKKyAgaW50IEdldE51bUJpdHNGb3JCdWlsZGVyKCkgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVJbnRlcmZhY2VNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnVpbGRlck1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUJ1aWxkZXJDbGVhckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnVpbGRpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVBhcnNpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVBhcnNpbmdEb25lQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRmllbGRCdWlsZGVySW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUVxdWFsc0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSGFzaENvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgIHN0cmluZyBHZXRCb3hlZFR5cGUoKSBjb25zdDsKKworIHByb3RlY3RlZDoKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXNfOworICBjb25zdCBpbnQgbWVzc2FnZUJpdEluZGV4XzsKKyAgY29uc3QgaW50IGJ1aWxkZXJCaXRJbmRleF87CisgIENvbnRleHQqIGNvbnRleHRfOworICBDbGFzc05hbWVSZXNvbHZlciogbmFtZV9yZXNvbHZlcl87CisKKyAgdm9pZCBQcmludE5lc3RlZEJ1aWxkZXJDb25kaXRpb24oaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICBjb25zdCBjaGFyKiByZWd1bGFyX2Nhc2UsIGNvbnN0IGNoYXIqIG5lc3RlZF9idWlsZGVyX2Nhc2UpIGNvbnN0OworICB2b2lkIFByaW50TmVzdGVkQnVpbGRlckZ1bmN0aW9uKGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgY29uc3QgY2hhciogbWV0aG9kX3Byb3RvdHlwZSwgY29uc3QgY2hhciogcmVndWxhcl9jYXNlLAorICAgICAgY29uc3QgY2hhciogbmVzdGVkX2J1aWxkZXJfY2FzZSwKKyAgICAgIGNvbnN0IGNoYXIqIHRyYWlsaW5nX2NvZGUpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFJlcGVhdGVkSW1tdXRhYmxlTWVzc2FnZUZpZWxkR2VuZXJhdG9yKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX01FU1NBR0VfRklFTERfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tZXNzYWdlX2ZpZWxkX2xpdGUuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tZXNzYWdlX2ZpZWxkX2xpdGUuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzU2NTIwZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21lc3NhZ2VfZmllbGRfbGl0ZS5jYwpAQCAtMCwwICsxLDk0NiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHN0cmluZz4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfY29udGV4dC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbWVzc2FnZV9maWVsZF9saXRlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9kb2NfY29tbWVudC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfaGVscGVycy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbmFtZV9yZXNvbHZlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhIHsKKworbmFtZXNwYWNlIHsKKwordm9pZCBTZXRNZXNzYWdlVmFyaWFibGVzKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgIGludCBidWlsZGVyQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGRHZW5lcmF0b3JJbmZvKiBpbmZvLAorICAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzTmFtZVJlc29sdmVyKiBuYW1lX3Jlc29sdmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgIG1hcDxzdHJpbmcsIHN0cmluZz4qIHZhcmlhYmxlcykgeworICBTZXRDb21tb25GaWVsZFZhcmlhYmxlcyhkZXNjcmlwdG9yLCBpbmZvLCB2YXJpYWJsZXMpOworCisgICgqdmFyaWFibGVzKVsidHlwZSJdID0KKyAgICAgIG5hbWVfcmVzb2x2ZXItPkdldEltbXV0YWJsZUNsYXNzTmFtZShkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKSk7CisgICgqdmFyaWFibGVzKVsibXV0YWJsZV90eXBlIl0gPQorICAgICAgbmFtZV9yZXNvbHZlci0+R2V0TXV0YWJsZUNsYXNzTmFtZShkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKSk7CisgICgqdmFyaWFibGVzKVsiZ3JvdXBfb3JfbWVzc2FnZSJdID0KKyAgICAoR2V0VHlwZShkZXNjcmlwdG9yKSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfR1JPVVApID8KKyAgICAiR3JvdXAiIDogIk1lc3NhZ2UiOworICAvLyBUT0RPKGJpcmRvKTogQWRkIEBkZXByZWNhdGVkIGphdmFkb2Mgd2hlbiBnZW5lcmF0aW5nIGphdmFkb2MgaXMgc3VwcG9ydGVkCisgIC8vIGJ5IHRoZSBwcm90byBjb21waWxlcgorICAoKnZhcmlhYmxlcylbImRlcHJlY2F0aW9uIl0gPSBkZXNjcmlwdG9yLT5vcHRpb25zKCkuZGVwcmVjYXRlZCgpCisgICAgICA/ICJAamF2YS5sYW5nLkRlcHJlY2F0ZWQgIiA6ICIiOworICAoKnZhcmlhYmxlcylbIm9uX2NoYW5nZWQiXSA9CisgICAgICBIYXNEZXNjcmlwdG9yTWV0aG9kcyhkZXNjcmlwdG9yLT5jb250YWluaW5nX3R5cGUoKSkgPyAib25DaGFuZ2VkKCk7IiA6ICIiOworCisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yLT5maWxlKCkpKSB7CisgICAgLy8gRm9yIHNpbmd1bGFyIG1lc3NhZ2VzIGFuZCBidWlsZGVycywgb25lIGJpdCBpcyB1c2VkIGZvciB0aGUgaGFzRmllbGQgYml0LgorICAgICgqdmFyaWFibGVzKVsiZ2V0X2hhc19maWVsZF9iaXRfbWVzc2FnZSJdID0gR2VuZXJhdGVHZXRCaXQobWVzc2FnZUJpdEluZGV4KTsKKworICAgIC8vIE5vdGUgdGhhdCB0aGVzZSBoYXZlIGEgdHJhaWxpbmcgIjsiLgorICAgICgqdmFyaWFibGVzKVsic2V0X2hhc19maWVsZF9iaXRfbWVzc2FnZSJdID0KKyAgICAgICAgR2VuZXJhdGVTZXRCaXQobWVzc2FnZUJpdEluZGV4KSArICI7IjsKKyAgICAoKnZhcmlhYmxlcylbImNsZWFyX2hhc19maWVsZF9iaXRfbWVzc2FnZSJdID0KKyAgICAgICAgR2VuZXJhdGVDbGVhckJpdChtZXNzYWdlQml0SW5kZXgpICsgIjsiOworCisgICAgKCp2YXJpYWJsZXMpWyJpc19maWVsZF9wcmVzZW50X21lc3NhZ2UiXSA9IEdlbmVyYXRlR2V0Qml0KG1lc3NhZ2VCaXRJbmRleCk7CisgIH0gZWxzZSB7CisgICAgKCp2YXJpYWJsZXMpWyJzZXRfaGFzX2ZpZWxkX2JpdF9tZXNzYWdlIl0gPSAiIjsKKyAgICAoKnZhcmlhYmxlcylbImNsZWFyX2hhc19maWVsZF9iaXRfbWVzc2FnZSJdID0gIiI7CisKKyAgICAoKnZhcmlhYmxlcylbImlzX2ZpZWxkX3ByZXNlbnRfbWVzc2FnZSJdID0KKyAgICAgICAgKCp2YXJpYWJsZXMpWyJuYW1lIl0gKyAiXyAhPSBudWxsIjsKKyAgfQorCisgIC8vIEZvciByZXBlYXRlZCBidWlsZGVycywgdGhlIHVuZGVybHlpbmcgbGlzdCB0cmFja3MgbXV0YWJpbGl0eSBzdGF0ZS4KKyAgKCp2YXJpYWJsZXMpWyJpc19tdXRhYmxlIl0gPSAoKnZhcmlhYmxlcylbIm5hbWUiXSArICJfLmlzTW9kaWZpYWJsZSgpIjsKKworICAoKnZhcmlhYmxlcylbImdldF9oYXNfZmllbGRfYml0X2Zyb21fbG9jYWwiXSA9CisgICAgICBHZW5lcmF0ZUdldEJpdEZyb21Mb2NhbChidWlsZGVyQml0SW5kZXgpOworICAoKnZhcmlhYmxlcylbInNldF9oYXNfZmllbGRfYml0X3RvX2xvY2FsIl0gPQorICAgICAgR2VuZXJhdGVTZXRCaXRUb0xvY2FsKG1lc3NhZ2VCaXRJbmRleCk7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK0ltbXV0YWJsZU1lc3NhZ2VGaWVsZExpdGVHZW5lcmF0b3I6OgorSW1tdXRhYmxlTWVzc2FnZUZpZWxkTGl0ZUdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgaW50IG1lc3NhZ2VCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICBpbnQgYnVpbGRlckJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgIENvbnRleHQqIGNvbnRleHQpCisgIDogZGVzY3JpcHRvcl8oZGVzY3JpcHRvciksIG1lc3NhZ2VCaXRJbmRleF8obWVzc2FnZUJpdEluZGV4KSwKKyAgICBidWlsZGVyQml0SW5kZXhfKGJ1aWxkZXJCaXRJbmRleCksIGNvbnRleHRfKGNvbnRleHQpLAorICAgIG5hbWVfcmVzb2x2ZXJfKGNvbnRleHQtPkdldE5hbWVSZXNvbHZlcigpKSB7CisgICAgU2V0TWVzc2FnZVZhcmlhYmxlcyhkZXNjcmlwdG9yLCBtZXNzYWdlQml0SW5kZXgsIGJ1aWxkZXJCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQtPkdldEZpZWxkR2VuZXJhdG9ySW5mbyhkZXNjcmlwdG9yKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVfcmVzb2x2ZXJfLCAmdmFyaWFibGVzXyk7Cit9CisKK0ltbXV0YWJsZU1lc3NhZ2VGaWVsZExpdGVHZW5lcmF0b3I6On5JbW11dGFibGVNZXNzYWdlRmllbGRMaXRlR2VuZXJhdG9yKCkge30KKworaW50IEltbXV0YWJsZU1lc3NhZ2VGaWVsZExpdGVHZW5lcmF0b3I6OkdldE51bUJpdHNGb3JNZXNzYWdlKCkgY29uc3QgeworICByZXR1cm4gMTsKK30KKworaW50IEltbXV0YWJsZU1lc3NhZ2VGaWVsZExpdGVHZW5lcmF0b3I6OkdldE51bUJpdHNGb3JCdWlsZGVyKCkgY29uc3QgeworICByZXR1cm4gMDsKK30KKwordm9pZCBJbW11dGFibGVNZXNzYWdlRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlSW50ZXJmYWNlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBUT0RPKGpvbnApOiBJbiB0aGUgZnV0dXJlLCBjb25zaWRlciBoYXZpbmcgYSBtZXRob2Qgc3BlY2lmaWMgdG8gdGhlCisgIC8vIGludGVyZmFjZSBzbyB0aGF0IGJ1aWxkZXJzIGNhbiBjaG9vc2UgZHluYW1pY2FsbHkgdG8gZWl0aGVyIHJldHVybiBhCisgIC8vIG1lc3NhZ2Ugb3IgYSBuZXN0ZWQgYnVpbGRlciwgc28gdGhhdCBhc2tpbmcgZm9yIHRoZSBpbnRlcmZhY2UgZG9lc24ndAorICAvLyBjYXVzZSBhIG1lc3NhZ2UgdG8gZXZlciBiZSBidWlsdC4KKyAgaWYgKFN1cHBvcnRGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3JfLT5maWxlKCkpIHx8CisgICAgICBkZXNjcmlwdG9yXy0+Y29udGFpbmluZ19vbmVvZigpID09IE5VTEwpIHsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kYm9vbGVhbiBoYXMkY2FwaXRhbGl6ZWRfbmFtZSQoKTtcbiIpOworICB9CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJCR0eXBlJCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKTtcbiIpOworfQorCit2b2lkIEltbXV0YWJsZU1lc3NhZ2VGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgJHR5cGUkICRuYW1lJF87XG4iKTsKKyAgUHJpbnRFeHRyYUZpZWxkSW5mbyh2YXJpYWJsZXNfLCBwcmludGVyKTsKKworICBpZiAoU3VwcG9ydEZpZWxkUHJlc2VuY2UoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljIGJvb2xlYW4gaGFzJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICAgIiAgcmV0dXJuICRnZXRfaGFzX2ZpZWxkX2JpdF9tZXNzYWdlJDtcbiIKKyAgICAgICJ9XG4iKTsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljICR0eXBlJCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgICAiICByZXR1cm4gJG5hbWUkXyA9PSBudWxsID8gJHR5cGUkLmdldERlZmF1bHRJbnN0YW5jZSgpIDogJG5hbWUkXztcbiIKKyAgICAgICJ9XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljIGJvb2xlYW4gaGFzJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICAgIiAgcmV0dXJuICRuYW1lJF8gIT0gbnVsbDtcbiIKKyAgICAgICJ9XG4iKTsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljICR0eXBlJCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgICAiICByZXR1cm4gJG5hbWUkXyA9PSBudWxsID8gJHR5cGUkLmdldERlZmF1bHRJbnN0YW5jZSgpIDogJG5hbWUkXztcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorCisgIC8vIEZpZWxkLkJ1aWxkZXIgc2V0RmllbGQoRmllbGQgdmFsdWUpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHJpdmF0ZSB2b2lkIHNldCRjYXBpdGFsaXplZF9uYW1lJCgkdHlwZSQgdmFsdWUpIHtcbiIKKyAgICAiICBpZiAodmFsdWUgPT0gbnVsbCkge1xuIgorICAgICIgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7XG4iCisgICAgIiAgfVxuIgorICAgICIgICRuYW1lJF8gPSB2YWx1ZTtcbiIKKyAgICAiICAkc2V0X2hhc19maWVsZF9iaXRfbWVzc2FnZSRcbiIKKyAgICAiICB9XG4iKTsKKworICAvLyBGaWVsZC5CdWlsZGVyIHNldEZpZWxkKEZpZWxkLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgdm9pZCBzZXQkY2FwaXRhbGl6ZWRfbmFtZSQoXG4iCisgICAgIiAgICAkdHlwZSQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHtcbiIKKyAgICAiICAkbmFtZSRfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7XG4iCisgICAgIiAgJHNldF9oYXNfZmllbGRfYml0X21lc3NhZ2UkXG4iCisgICAgIn1cbiIpOworCisgIC8vIEZpZWxkLkJ1aWxkZXIgbWVyZ2VGaWVsZChGaWVsZCB2YWx1ZSkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIHZvaWQgbWVyZ2UkY2FwaXRhbGl6ZWRfbmFtZSQoJHR5cGUkIHZhbHVlKSB7XG4iCisgICAgIiAgaWYgKCRuYW1lJF8gIT0gbnVsbCAmJlxuIgorICAgICIgICAgICAkbmFtZSRfICE9ICR0eXBlJC5nZXREZWZhdWx0SW5zdGFuY2UoKSkge1xuIgorICAgICIgICAgJG5hbWUkXyA9XG4iCisgICAgIiAgICAgICR0eXBlJC5uZXdCdWlsZGVyKCRuYW1lJF8pLm1lcmdlRnJvbSh2YWx1ZSkuYnVpbGRQYXJ0aWFsKCk7XG4iCisgICAgIiAgfSBlbHNlIHtcbiIKKyAgICAiICAgICRuYW1lJF8gPSB2YWx1ZTtcbiIKKyAgICAiICB9XG4iCisgICAgIiAgJHNldF9oYXNfZmllbGRfYml0X21lc3NhZ2UkXG4iCisgICAgIn1cbiIpOworCisgIC8vIEZpZWxkLkJ1aWxkZXIgY2xlYXJGaWVsZCgpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHJpdmF0ZSB2b2lkIGNsZWFyJGNhcGl0YWxpemVkX25hbWUkKCkgeyIKKyAgICAiICAkbmFtZSRfID0gbnVsbDtcbiIKKyAgICAiICAkY2xlYXJfaGFzX2ZpZWxkX2JpdF9tZXNzYWdlJFxuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVNZXNzYWdlRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRlck1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gVGhlIGNvbW1lbnRzIGFib3ZlIHRoZSBtZXRob2RzIGJlbG93IGFyZSBiYXNlZCBvbiBhIGh5cG90aGV0aWNhbAorICAvLyBmaWVsZCBvZiB0eXBlICJGaWVsZCIgY2FsbGVkICJGaWVsZCIuCisKKyAgLy8gYm9vbGVhbiBoYXNGaWVsZCgpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBib29sZWFuIGhhcyRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAiICByZXR1cm4gaW5zdGFuY2UuaGFzJGNhcGl0YWxpemVkX25hbWUkKCk7XG4iCisgICAgIn1cbiIpOworCisgIC8vIEZpZWxkIGdldEZpZWxkKCkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljICR0eXBlJCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgcmV0dXJuIGluc3RhbmNlLmdldCRjYXBpdGFsaXplZF9uYW1lJCgpO1xuIgorICAgICJ9XG4iKTsKKworICAvLyBGaWVsZC5CdWlsZGVyIHNldEZpZWxkKEZpZWxkIHZhbHVlKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBzZXQkY2FwaXRhbGl6ZWRfbmFtZSQoJHR5cGUkIHZhbHVlKSB7XG4iCisgICAgIiAgY29weU9uV3JpdGUoKTtcbiIKKyAgICAiICBpbnN0YW5jZS5zZXQkY2FwaXRhbGl6ZWRfbmFtZSQodmFsdWUpO1xuIgorICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICIgIH1cbiIpOworCisgIC8vIEZpZWxkLkJ1aWxkZXIgc2V0RmllbGQoRmllbGQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIHNldCRjYXBpdGFsaXplZF9uYW1lJChcbiIKKyAgICAiICAgICR0eXBlJC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkge1xuIgorICAgICIgIGNvcHlPbldyaXRlKCk7XG4iCisgICAgIiAgaW5zdGFuY2Uuc2V0JGNhcGl0YWxpemVkX25hbWUkKGJ1aWxkZXJGb3JWYWx1ZSk7XG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworCisgIC8vIEZpZWxkLkJ1aWxkZXIgbWVyZ2VGaWVsZChGaWVsZCB2YWx1ZSkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgbWVyZ2UkY2FwaXRhbGl6ZWRfbmFtZSQoJHR5cGUkIHZhbHVlKSB7XG4iCisgICAgIiAgY29weU9uV3JpdGUoKTtcbiIKKyAgICAiICBpbnN0YW5jZS5tZXJnZSRjYXBpdGFsaXplZF9uYW1lJCh2YWx1ZSk7XG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworCisgIC8vIEZpZWxkLkJ1aWxkZXIgY2xlYXJGaWVsZCgpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGNsZWFyJGNhcGl0YWxpemVkX25hbWUkKCkgeyIKKyAgICAiICBjb3B5T25Xcml0ZSgpO1xuIgorICAgICIgIGluc3RhbmNlLmNsZWFyJGNhcGl0YWxpemVkX25hbWUkKCk7XG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZU1lc3NhZ2VGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVGaWVsZEJ1aWxkZXJJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpICBjb25zdCB7CisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiZ2V0JGNhcGl0YWxpemVkX25hbWUkRmllbGRCdWlsZGVyKCk7XG4iKTsKKyAgfQorfQorCisKK3ZvaWQgSW1tdXRhYmxlTWVzc2FnZUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUluaXRpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Qge30KKwordm9pZCBJbW11dGFibGVNZXNzYWdlRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKG90aGVyLmhhcyRjYXBpdGFsaXplZF9uYW1lJCgpKSB7XG4iCisgICAgIiAgbWVyZ2UkY2FwaXRhbGl6ZWRfbmFtZSQob3RoZXIuZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkpO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVNZXNzYWdlRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlRHluYW1pY01ldGhvZE1ha2VJbW11dGFibGVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIG5vb3AgZm9yIHNjYWxhcnMKK30KKwordm9pZCBJbW11dGFibGVNZXNzYWdlRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJHR5cGUkLkJ1aWxkZXIgc3ViQnVpbGRlciA9IG51bGw7XG4iCisgICAgImlmICgkaXNfZmllbGRfcHJlc2VudF9tZXNzYWdlJCkge1xuIgorICAgICIgIHN1YkJ1aWxkZXIgPSAkbmFtZSRfLnRvQnVpbGRlcigpO1xuIgorICAgICJ9XG4iKTsKKworICAgIGlmIChHZXRUeXBlKGRlc2NyaXB0b3JfKSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfR1JPVVApIHsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICIkbmFtZSRfID0gaW5wdXQucmVhZEdyb3VwKCRudW1iZXIkLCAkdHlwZSQucGFyc2VyKCksXG4iCisgICAgICAgICIgICAgZXh0ZW5zaW9uUmVnaXN0cnkpO1xuIik7CisgICAgfSBlbHNlIHsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICIkbmFtZSRfID0gaW5wdXQucmVhZE1lc3NhZ2UoJHR5cGUkLnBhcnNlcigpLCBleHRlbnNpb25SZWdpc3RyeSk7XG4iKTsKKyAgICB9CisKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKHN1YkJ1aWxkZXIgIT0gbnVsbCkge1xuIgorICAgICIgIHN1YkJ1aWxkZXIubWVyZ2VGcm9tKCRuYW1lJF8pO1xuIgorICAgICIgICRuYW1lJF8gPSBzdWJCdWlsZGVyLmJ1aWxkUGFydGlhbCgpO1xuIgorICAgICJ9XG4iCisgICAgIiRzZXRfaGFzX2ZpZWxkX2JpdF9tZXNzYWdlJFxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlTWVzc2FnZUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZVBhcnNpbmdEb25lQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBub29wIGZvciBtZXNzYWdlcy4KK30KKwordm9pZCBJbW11dGFibGVNZXNzYWdlRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCRpc19maWVsZF9wcmVzZW50X21lc3NhZ2UkKSB7XG4iCisgICAgIiAgb3V0cHV0LndyaXRlJGdyb3VwX29yX21lc3NhZ2UkKCRudW1iZXIkLCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZU1lc3NhZ2VGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCRpc19maWVsZF9wcmVzZW50X21lc3NhZ2UkKSB7XG4iCisgICAgIiAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtXG4iCisgICAgIiAgICAuY29tcHV0ZSRncm91cF9vcl9tZXNzYWdlJFNpemUoJG51bWJlciQsIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlTWVzc2FnZUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUVxdWFsc0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicmVzdWx0ID0gcmVzdWx0ICYmIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpXG4iCisgICAgIiAgICAuZXF1YWxzKG90aGVyLmdldCRjYXBpdGFsaXplZF9uYW1lJCgpKTtcbiIpOworfQorCit2b2lkIEltbXV0YWJsZU1lc3NhZ2VGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVIYXNoQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJoYXNoID0gKDM3ICogaGFzaCkgKyAkY29uc3RhbnRfbmFtZSQ7XG4iCisgICAgImhhc2ggPSAoNTMgKiBoYXNoKSArIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpLmhhc2hDb2RlKCk7XG4iKTsKK30KKworc3RyaW5nIEltbXV0YWJsZU1lc3NhZ2VGaWVsZExpdGVHZW5lcmF0b3I6OkdldEJveGVkVHlwZSgpIGNvbnN0IHsKKyAgcmV0dXJuIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcl8tPm1lc3NhZ2VfdHlwZSgpKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitJbW11dGFibGVNZXNzYWdlT25lb2ZGaWVsZExpdGVHZW5lcmF0b3I6OgorSW1tdXRhYmxlTWVzc2FnZU9uZW9mRmllbGRMaXRlR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBtZXNzYWdlQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYnVpbGRlckJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29udGV4dCogY29udGV4dCkKKyAgICA6IEltbXV0YWJsZU1lc3NhZ2VGaWVsZExpdGVHZW5lcmF0b3IoCisgICAgICAgICAgZGVzY3JpcHRvciwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsIGNvbnRleHQpIHsKKyAgY29uc3QgT25lb2ZHZW5lcmF0b3JJbmZvKiBpbmZvID0KKyAgICAgIGNvbnRleHQtPkdldE9uZW9mR2VuZXJhdG9ySW5mbyhkZXNjcmlwdG9yLT5jb250YWluaW5nX29uZW9mKCkpOworICBTZXRDb21tb25PbmVvZlZhcmlhYmxlcyhkZXNjcmlwdG9yLCBpbmZvLCAmdmFyaWFibGVzXyk7Cit9CisKK0ltbXV0YWJsZU1lc3NhZ2VPbmVvZkZpZWxkTGl0ZUdlbmVyYXRvcjo6Cit+SW1tdXRhYmxlTWVzc2FnZU9uZW9mRmllbGRMaXRlR2VuZXJhdG9yKCkge30KKwordm9pZCBJbW11dGFibGVNZXNzYWdlT25lb2ZGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIFByaW50RXh0cmFGaWVsZEluZm8odmFyaWFibGVzXywgcHJpbnRlcik7CisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgYm9vbGVhbiBoYXMkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgICAiICByZXR1cm4gJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkO1xuIgorICAgICAgIn1cbiIpOworICB9CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSQgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgIGlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIKKyAgICAiICAgICByZXR1cm4gKCR0eXBlJCkgJG9uZW9mX25hbWUkXztcbiIKKyAgICAiICB9XG4iCisgICAgIiAgcmV0dXJuICR0eXBlJC5nZXREZWZhdWx0SW5zdGFuY2UoKTtcbiIKKyAgICAifVxuIik7CisKKyAgLy8gRmllbGQuQnVpbGRlciBzZXRGaWVsZChGaWVsZCB2YWx1ZSkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIHZvaWQgc2V0JGNhcGl0YWxpemVkX25hbWUkKCR0eXBlJCB2YWx1ZSkge1xuIgorICAgICIgIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4iCisgICAgIiAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTtcbiIKKyAgICAiICB9XG4iCisgICAgIiAgJG9uZW9mX25hbWUkXyA9IHZhbHVlO1xuIgorICAgICIgICRzZXRfb25lb2ZfY2FzZV9tZXNzYWdlJDtcbiIKKyAgICAifVxuIik7CisKKyAgLy8gRmllbGQuQnVpbGRlciBzZXRGaWVsZChGaWVsZC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIHZvaWQgc2V0JGNhcGl0YWxpemVkX25hbWUkKFxuIgorICAgICIgICAgJHR5cGUkLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7XG4iCisgICAgIiAgJG9uZW9mX25hbWUkXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpO1xuIgorICAgICIgICRzZXRfb25lb2ZfY2FzZV9tZXNzYWdlJDtcbiIKKyAgICAifVxuIik7CisKKyAgLy8gRmllbGQuQnVpbGRlciBtZXJnZUZpZWxkKEZpZWxkIHZhbHVlKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgdm9pZCBtZXJnZSRjYXBpdGFsaXplZF9uYW1lJCgkdHlwZSQgdmFsdWUpIHtcbiIKKyAgICAiICBpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkICYmXG4iCisgICAgIiAgICAgICRvbmVvZl9uYW1lJF8gIT0gJHR5cGUkLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7XG4iCisgICAgIiAgICAkb25lb2ZfbmFtZSRfID0gJHR5cGUkLm5ld0J1aWxkZXIoKCR0eXBlJCkgJG9uZW9mX25hbWUkXylcbiIKKyAgICAiICAgICAgICAubWVyZ2VGcm9tKHZhbHVlKS5idWlsZFBhcnRpYWwoKTtcbiIKKyAgICAiICB9IGVsc2Uge1xuIgorICAgICIgICAgJG9uZW9mX25hbWUkXyA9IHZhbHVlO1xuIgorICAgICIgIH1cbiIKKyAgICAiICAkc2V0X29uZW9mX2Nhc2VfbWVzc2FnZSQ7XG4iCisgICAgIn1cbiIpOworCisgIC8vIEZpZWxkLkJ1aWxkZXIgY2xlYXJGaWVsZCgpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHJpdmF0ZSB2b2lkIGNsZWFyJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgIGlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIKKyAgICAiICAgICRjbGVhcl9vbmVvZl9jYXNlX21lc3NhZ2UkO1xuIgorICAgICIgICAgJG9uZW9mX25hbWUkXyA9IG51bGw7XG4iCisgICAgIiAgfVxuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVNZXNzYWdlT25lb2ZGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBUaGUgY29tbWVudHMgYWJvdmUgdGhlIG1ldGhvZHMgYmVsb3cgYXJlIGJhc2VkIG9uIGEgaHlwb3RoZXRpY2FsCisgIC8vIGZpZWxkIG9mIHR5cGUgIkZpZWxkIiBjYWxsZWQgIkZpZWxkIi4KKworICBpZiAoU3VwcG9ydEZpZWxkUHJlc2VuY2UoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICAvLyBib29sZWFuIGhhc0ZpZWxkKCkKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljIGJvb2xlYW4gaGFzJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICAgIiAgcmV0dXJuIGluc3RhbmNlLmhhcyRjYXBpdGFsaXplZF9uYW1lJCgpO1xuIgorICAgICAgIn1cbiIpOworICB9CisKKyAgLy8gRmllbGQgZ2V0RmllbGQoKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAiICByZXR1cm4gaW5zdGFuY2UuZ2V0JGNhcGl0YWxpemVkX25hbWUkKCk7XG4iCisgICAgIn1cbiIpOworCisgIC8vIEZpZWxkLkJ1aWxkZXIgc2V0RmllbGQoRmllbGQgdmFsdWUpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIHNldCRjYXBpdGFsaXplZF9uYW1lJCgkdHlwZSQgdmFsdWUpIHtcbiIKKyAgICAiICBjb3B5T25Xcml0ZSgpO1xuIgorICAgICIgIGluc3RhbmNlLnNldCRjYXBpdGFsaXplZF9uYW1lJCh2YWx1ZSk7XG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworCisgIC8vIEZpZWxkLkJ1aWxkZXIgc2V0RmllbGQoRmllbGQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIHNldCRjYXBpdGFsaXplZF9uYW1lJChcbiIKKyAgICAiICAgICR0eXBlJC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkge1xuIgorICAgICIgIGNvcHlPbldyaXRlKCk7XG4iCisgICAgIiAgaW5zdGFuY2Uuc2V0JGNhcGl0YWxpemVkX25hbWUkKGJ1aWxkZXJGb3JWYWx1ZSk7XG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworCisgIC8vIEZpZWxkLkJ1aWxkZXIgbWVyZ2VGaWVsZChGaWVsZCB2YWx1ZSkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgbWVyZ2UkY2FwaXRhbGl6ZWRfbmFtZSQoJHR5cGUkIHZhbHVlKSB7XG4iCisgICAgIiAgY29weU9uV3JpdGUoKTtcbiIKKyAgICAiICBpbnN0YW5jZS5tZXJnZSRjYXBpdGFsaXplZF9uYW1lJCh2YWx1ZSk7XG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworCisgIC8vIEZpZWxkLkJ1aWxkZXIgY2xlYXJGaWVsZCgpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGNsZWFyJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgIGNvcHlPbldyaXRlKCk7XG4iCisgICAgIiAgaW5zdGFuY2UuY2xlYXIkY2FwaXRhbGl6ZWRfbmFtZSQoKTtcbiIKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlTWVzc2FnZU9uZW9mRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAibWVyZ2UkY2FwaXRhbGl6ZWRfbmFtZSQob3RoZXIuZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkpO1xuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlTWVzc2FnZU9uZW9mRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJHR5cGUkLkJ1aWxkZXIgc3ViQnVpbGRlciA9IG51bGw7XG4iCisgICAgImlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIKKyAgICAiICBzdWJCdWlsZGVyID0gKCgkdHlwZSQpICRvbmVvZl9uYW1lJF8pLnRvQnVpbGRlcigpO1xuIgorICAgICJ9XG4iKTsKKworICAgIGlmIChHZXRUeXBlKGRlc2NyaXB0b3JfKSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfR1JPVVApIHsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICIkb25lb2ZfbmFtZSRfID0gaW5wdXQucmVhZEdyb3VwKCRudW1iZXIkLCAkdHlwZSQucGFyc2VyKCksXG4iCisgICAgICAgICIgICAgZXh0ZW5zaW9uUmVnaXN0cnkpO1xuIik7CisgICAgfSBlbHNlIHsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICIkb25lb2ZfbmFtZSRfID1cbiIKKyAgICAgICAgIiAgICAgaW5wdXQucmVhZE1lc3NhZ2UoJHR5cGUkLnBhcnNlcigpLCBleHRlbnNpb25SZWdpc3RyeSk7XG4iKTsKKyAgICB9CisKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKHN1YkJ1aWxkZXIgIT0gbnVsbCkge1xuIgorICAgICIgIHN1YkJ1aWxkZXIubWVyZ2VGcm9tKCgkdHlwZSQpICRvbmVvZl9uYW1lJF8pO1xuIgorICAgICIgICRvbmVvZl9uYW1lJF8gPSBzdWJCdWlsZGVyLmJ1aWxkUGFydGlhbCgpO1xuIgorICAgICJ9XG4iKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJHNldF9vbmVvZl9jYXNlX21lc3NhZ2UkO1xuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlTWVzc2FnZU9uZW9mRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJCkge1xuIgorICAgICIgIG91dHB1dC53cml0ZSRncm91cF9vcl9tZXNzYWdlJCgkbnVtYmVyJCwgKCR0eXBlJCkgJG9uZW9mX25hbWUkXyk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZU1lc3NhZ2VPbmVvZkZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iCisgICAgIiAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtXG4iCisgICAgIiAgICAuY29tcHV0ZSRncm91cF9vcl9tZXNzYWdlJFNpemUoJG51bWJlciQsICgkdHlwZSQpICRvbmVvZl9uYW1lJF8pO1xuIgorICAgICJ9XG4iKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitSZXBlYXRlZEltbXV0YWJsZU1lc3NhZ2VGaWVsZExpdGVHZW5lcmF0b3I6OgorUmVwZWF0ZWRJbW11dGFibGVNZXNzYWdlRmllbGRMaXRlR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBtZXNzYWdlQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYnVpbGRlckJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29udGV4dCogY29udGV4dCkKKyAgOiBkZXNjcmlwdG9yXyhkZXNjcmlwdG9yKSwgbWVzc2FnZUJpdEluZGV4XyhtZXNzYWdlQml0SW5kZXgpLAorICAgIGJ1aWxkZXJCaXRJbmRleF8oYnVpbGRlckJpdEluZGV4KSwgY29udGV4dF8oY29udGV4dCksCisgICAgbmFtZV9yZXNvbHZlcl8oY29udGV4dC0+R2V0TmFtZVJlc29sdmVyKCkpICB7CisgIFNldE1lc3NhZ2VWYXJpYWJsZXMoZGVzY3JpcHRvciwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgY29udGV4dC0+R2V0RmllbGRHZW5lcmF0b3JJbmZvKGRlc2NyaXB0b3IpLAorICAgICAgICAgICAgICAgICAgICAgIG5hbWVfcmVzb2x2ZXJfLCAmdmFyaWFibGVzXyk7Cit9CisKK1JlcGVhdGVkSW1tdXRhYmxlTWVzc2FnZUZpZWxkTGl0ZUdlbmVyYXRvcjo6Cit+UmVwZWF0ZWRJbW11dGFibGVNZXNzYWdlRmllbGRMaXRlR2VuZXJhdG9yKCkge30KKworaW50IFJlcGVhdGVkSW1tdXRhYmxlTWVzc2FnZUZpZWxkTGl0ZUdlbmVyYXRvcjo6R2V0TnVtQml0c0Zvck1lc3NhZ2UoKSBjb25zdCB7CisgIHJldHVybiAwOworfQorCitpbnQgUmVwZWF0ZWRJbW11dGFibGVNZXNzYWdlRmllbGRMaXRlR2VuZXJhdG9yOjpHZXROdW1CaXRzRm9yQnVpbGRlcigpIGNvbnN0IHsKKyAgcmV0dXJuIDA7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVNZXNzYWdlRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlSW50ZXJmYWNlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBUT0RPKGpvbnApOiBJbiB0aGUgZnV0dXJlLCBjb25zaWRlciBoYXZpbmcgbWV0aG9kcyBzcGVjaWZpYyB0byB0aGUKKyAgLy8gaW50ZXJmYWNlIHNvIHRoYXQgYnVpbGRlcnMgY2FuIGNob29zZSBkeW5hbWljYWxseSB0byBlaXRoZXIgcmV0dXJuIGEKKyAgLy8gbWVzc2FnZSBvciBhIG5lc3RlZCBidWlsZGVyLCBzbyB0aGF0IGFza2luZyBmb3IgdGhlIGludGVyZmFjZSBkb2Vzbid0CisgIC8vIGNhdXNlIGEgbWVzc2FnZSB0byBldmVyIGJlIGJ1aWx0LgorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRqYXZhLnV0aWwuTGlzdDwkdHlwZSQ+IFxuIgorICAgICIgICAgZ2V0JGNhcGl0YWxpemVkX25hbWUkTGlzdCgpO1xuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJCR0eXBlJCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoaW50IGluZGV4KTtcbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRpbnQgZ2V0JGNhcGl0YWxpemVkX25hbWUkQ291bnQoKTtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlTWVzc2FnZUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLlByb3RvYnVmTGlzdDwkdHlwZSQ+ICRuYW1lJF87XG4iKTsKKyAgUHJpbnRFeHRyYUZpZWxkSW5mbyh2YXJpYWJsZXNfLCBwcmludGVyKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIGphdmEudXRpbC5MaXN0PCR0eXBlJD4gZ2V0JGNhcGl0YWxpemVkX25hbWUkTGlzdCgpIHtcbiIKKyAgICAiICByZXR1cm4gJG5hbWUkXztcbiIgICAvLyBub3RlOiAgdW5tb2RpZmlhYmxlIGxpc3QKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgJHR5cGUkT3JCdWlsZGVyPiBcbiIKKyAgICAiICAgIGdldCRjYXBpdGFsaXplZF9uYW1lJE9yQnVpbGRlckxpc3QoKSB7XG4iCisgICAgIiAgcmV0dXJuICRuYW1lJF87XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgaW50IGdldCRjYXBpdGFsaXplZF9uYW1lJENvdW50KCkge1xuIgorICAgICIgIHJldHVybiAkbmFtZSRfLnNpemUoKTtcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSQgZ2V0JGNhcGl0YWxpemVkX25hbWUkKGludCBpbmRleCkge1xuIgorICAgICIgIHJldHVybiAkbmFtZSRfLmdldChpbmRleCk7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkT3JCdWlsZGVyIGdldCRjYXBpdGFsaXplZF9uYW1lJE9yQnVpbGRlcihcbiIKKyAgICAiICAgIGludCBpbmRleCkge1xuIgorICAgICIgIHJldHVybiAkbmFtZSRfLmdldChpbmRleCk7XG4iCisgICAgIn1cbiIpOworCisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgdm9pZCBlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKSB7XG4iCisgICAgIiAgaWYgKCEkaXNfbXV0YWJsZSQpIHtcbiIKKyAgICAiICAgICRuYW1lJF8gPSBuZXdQcm90b2J1Zkxpc3QoJG5hbWUkXyk7XG4iCisgICAgIiAgIH1cbiIKKyAgICAifVxuIgorICAgICJcbiIpOworCisgIC8vIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZChpbnQgaW5kZXgsIEZpZWxkIHZhbHVlKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgdm9pZCBzZXQkY2FwaXRhbGl6ZWRfbmFtZSQoXG4iCisgICAgIiAgICBpbnQgaW5kZXgsICR0eXBlJCB2YWx1ZSkge1xuIgorICAgICIgIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4iCisgICAgIiAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTtcbiIKKyAgICAiICB9XG4iCisgICAgIiAgZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCk7XG4iCisgICAgIiAgJG5hbWUkXy5zZXQoaW5kZXgsIHZhbHVlKTtcbiIKKyAgICAifVxuIik7CisKKyAgLy8gQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKGludCBpbmRleCwgRmllbGQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHJpdmF0ZSB2b2lkIHNldCRjYXBpdGFsaXplZF9uYW1lJChcbiIKKyAgICAiICAgIGludCBpbmRleCwgJHR5cGUkLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7XG4iCisgICAgIiAgZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCk7XG4iCisgICAgIiAgJG5hbWUkXy5zZXQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTtcbiIKKyAgICAifVxuIik7CisKKyAgLy8gQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKEZpZWxkIHZhbHVlKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgdm9pZCBhZGQkY2FwaXRhbGl6ZWRfbmFtZSQoJHR5cGUkIHZhbHVlKSB7XG4iCisgICAgIiAgaWYgKHZhbHVlID09IG51bGwpIHtcbiIKKyAgICAiICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpO1xuIgorICAgICIgIH1cbiIKKyAgICAiICBlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKTtcbiIKKyAgICAiICAkbmFtZSRfLmFkZCh2YWx1ZSk7XG4iCisgICAgIn1cbiIpOworCisgIC8vIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZChpbnQgaW5kZXgsIEZpZWxkIHZhbHVlKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgdm9pZCBhZGQkY2FwaXRhbGl6ZWRfbmFtZSQoXG4iCisgICAgIiAgICBpbnQgaW5kZXgsICR0eXBlJCB2YWx1ZSkge1xuIgorICAgICIgIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4iCisgICAgIiAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTtcbiIKKyAgICAiICB9XG4iCisgICAgIiAgZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCk7XG4iCisgICAgIiAgJG5hbWUkXy5hZGQoaW5kZXgsIHZhbHVlKTtcbiIKKyAgICAifVxuIik7CisgIC8vIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZChGaWVsZC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIHZvaWQgYWRkJGNhcGl0YWxpemVkX25hbWUkKFxuIgorICAgICIgICAgJHR5cGUkLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7XG4iCisgICAgIiAgZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCk7XG4iCisgICAgIiAgJG5hbWUkXy5hZGQoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpO1xuIgorICAgICJ9XG4iKTsKKworICAvLyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoaW50IGluZGV4LCBGaWVsZC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIHZvaWQgYWRkJGNhcGl0YWxpemVkX25hbWUkKFxuIgorICAgICIgICAgaW50IGluZGV4LCAkdHlwZSQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHtcbiIKKyAgICAiICBlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKTtcbiIKKyAgICAiICAkbmFtZSRfLmFkZChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpO1xuIgorICAgICJ9XG4iKTsKKworICAvLyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkRmllbGQoSXRlcmFibGU8RmllbGQ+IHZhbHVlcykKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIHZvaWQgYWRkQWxsJGNhcGl0YWxpemVkX25hbWUkKFxuIgorICAgICIgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyAkdHlwZSQ+IHZhbHVlcykge1xuIgorICAgICIgIGVuc3VyZSRjYXBpdGFsaXplZF9uYW1lJElzTXV0YWJsZSgpO1xuIgorICAgICIgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5hZGRBbGwoXG4iCisgICAgIiAgICAgIHZhbHVlcywgJG5hbWUkXyk7XG4iCisgICAgIn1cbiIpOworCisgIC8vIEJ1aWxkZXIgY2xlYXJBbGxSZXBlYXRlZEZpZWxkKCkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIHZvaWQgY2xlYXIkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgJG5hbWUkXyA9IGVtcHR5UHJvdG9idWZMaXN0KCk7XG4iCisgICAgIn1cbiIpOworCisgIC8vIEJ1aWxkZXIgcmVtb3ZlUmVwZWF0ZWRGaWVsZChpbnQgaW5kZXgpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHJpdmF0ZSB2b2lkIHJlbW92ZSRjYXBpdGFsaXplZF9uYW1lJChpbnQgaW5kZXgpIHtcbiIKKyAgICAiICBlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKTtcbiIKKyAgICAiICAkbmFtZSRfLnJlbW92ZShpbmRleCk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlTWVzc2FnZUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUJ1aWxkZXJNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIFRoZSBjb21tZW50cyBhYm92ZSB0aGUgbWV0aG9kcyBiZWxvdyBhcmUgYmFzZWQgb24gYSBoeXBvdGhldGljYWwKKyAgLy8gcmVwZWF0ZWQgZmllbGQgb2YgdHlwZSAiRmllbGQiIGNhbGxlZCAiUmVwZWF0ZWRGaWVsZCIuCisKKyAgLy8gTGlzdDxGaWVsZD4gZ2V0UmVwZWF0ZWRGaWVsZExpc3QoKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgamF2YS51dGlsLkxpc3Q8JHR5cGUkPiBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRMaXN0KCkge1xuIgorICAgICIgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChcbiIKKyAgICAiICAgICAgaW5zdGFuY2UuZ2V0JGNhcGl0YWxpemVkX25hbWUkTGlzdCgpKTtcbiIKKyAgICAifVxuIik7CisKKyAgLy8gaW50IGdldFJlcGVhdGVkRmllbGRDb3VudCgpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBpbnQgZ2V0JGNhcGl0YWxpemVkX25hbWUkQ291bnQoKSB7XG4iCisgICAgIiAgcmV0dXJuIGluc3RhbmNlLmdldCRjYXBpdGFsaXplZF9uYW1lJENvdW50KCk7XG4iCisgICAgIn0iKTsKKworICAvLyBGaWVsZCBnZXRSZXBlYXRlZEZpZWxkKGludCBpbmRleCkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljICR0eXBlJCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoaW50IGluZGV4KSB7XG4iCisgICAgIiAgcmV0dXJuIGluc3RhbmNlLmdldCRjYXBpdGFsaXplZF9uYW1lJChpbmRleCk7XG4iCisgICAgIn1cbiIpOworCisgIC8vIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZChpbnQgaW5kZXgsIEZpZWxkIHZhbHVlKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBzZXQkY2FwaXRhbGl6ZWRfbmFtZSQoXG4iCisgICAgIiAgICBpbnQgaW5kZXgsICR0eXBlJCB2YWx1ZSkge1xuIgorICAgICIgIGNvcHlPbldyaXRlKCk7XG4iCisgICAgIiAgaW5zdGFuY2Uuc2V0JGNhcGl0YWxpemVkX25hbWUkKGluZGV4LCB2YWx1ZSk7XG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworCisgIC8vIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZChpbnQgaW5kZXgsIEZpZWxkLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBzZXQkY2FwaXRhbGl6ZWRfbmFtZSQoXG4iCisgICAgIiAgICBpbnQgaW5kZXgsICR0eXBlJC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkge1xuIgorICAgICIgIGNvcHlPbldyaXRlKCk7XG4iCisgICAgIiAgaW5zdGFuY2Uuc2V0JGNhcGl0YWxpemVkX25hbWUkKGluZGV4LCBidWlsZGVyRm9yVmFsdWUpO1xuIgorICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICJ9XG4iKTsKKworICAvLyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoRmllbGQgdmFsdWUpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGFkZCRjYXBpdGFsaXplZF9uYW1lJCgkdHlwZSQgdmFsdWUpIHtcbiIKKyAgICAiICBjb3B5T25Xcml0ZSgpO1xuIgorICAgICIgIGluc3RhbmNlLmFkZCRjYXBpdGFsaXplZF9uYW1lJCh2YWx1ZSk7XG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworCisgIC8vIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZChpbnQgaW5kZXgsIEZpZWxkIHZhbHVlKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBhZGQkY2FwaXRhbGl6ZWRfbmFtZSQoXG4iCisgICAgIiAgICBpbnQgaW5kZXgsICR0eXBlJCB2YWx1ZSkge1xuIgorICAgICIgIGNvcHlPbldyaXRlKCk7XG4iCisgICAgIiAgaW5zdGFuY2UuYWRkJGNhcGl0YWxpemVkX25hbWUkKGluZGV4LCB2YWx1ZSk7XG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworICAvLyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoRmllbGQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGFkZCRjYXBpdGFsaXplZF9uYW1lJChcbiIKKyAgICAiICAgICR0eXBlJC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkge1xuIgorICAgICIgIGNvcHlPbldyaXRlKCk7XG4iCisgICAgIiAgaW5zdGFuY2UuYWRkJGNhcGl0YWxpemVkX25hbWUkKGJ1aWxkZXJGb3JWYWx1ZSk7XG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworCisgIC8vIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZChpbnQgaW5kZXgsIEZpZWxkLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBhZGQkY2FwaXRhbGl6ZWRfbmFtZSQoXG4iCisgICAgIiAgICBpbnQgaW5kZXgsICR0eXBlJC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkge1xuIgorICAgICIgIGNvcHlPbldyaXRlKCk7XG4iCisgICAgIiAgaW5zdGFuY2UuYWRkJGNhcGl0YWxpemVkX25hbWUkKGluZGV4LCBidWlsZGVyRm9yVmFsdWUpO1xuIgorICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICJ9XG4iKTsKKworICAvLyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkRmllbGQoSXRlcmFibGU8RmllbGQ+IHZhbHVlcykKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgYWRkQWxsJGNhcGl0YWxpemVkX25hbWUkKFxuIgorICAgICIgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyAkdHlwZSQ+IHZhbHVlcykge1xuIgorICAgICIgIGNvcHlPbldyaXRlKCk7XG4iCisgICAgIiAgaW5zdGFuY2UuYWRkQWxsJGNhcGl0YWxpemVkX25hbWUkKHZhbHVlcyk7XG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworCisgIC8vIEJ1aWxkZXIgY2xlYXJBbGxSZXBlYXRlZEZpZWxkKCkKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgY2xlYXIkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgY29weU9uV3JpdGUoKTtcbiIKKyAgICAiICBpbnN0YW5jZS5jbGVhciRjYXBpdGFsaXplZF9uYW1lJCgpO1xuIgorICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICJ9XG4iKTsKKworICAvLyBCdWlsZGVyIHJlbW92ZVJlcGVhdGVkRmllbGQoaW50IGluZGV4KQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciByZW1vdmUkY2FwaXRhbGl6ZWRfbmFtZSQoaW50IGluZGV4KSB7XG4iCisgICAgIiAgY29weU9uV3JpdGUoKTtcbiIKKyAgICAiICBpbnN0YW5jZS5yZW1vdmUkY2FwaXRhbGl6ZWRfbmFtZSQoaW5kZXgpO1xuIgorICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZU1lc3NhZ2VGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVGaWVsZEJ1aWxkZXJJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpICBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImdldCRjYXBpdGFsaXplZF9uYW1lJEZpZWxkQnVpbGRlcigpO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVNZXNzYWdlRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlSW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sICIkbmFtZSRfID0gZW1wdHlQcm90b2J1Zkxpc3QoKTtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlTWVzc2FnZUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIFRoZSBjb2RlIGJlbG93IGRvZXMgdHdvIG9wdGltaXphdGlvbnMgKG5vbi1uZXN0ZWQgYnVpbGRlciBjYXNlKToKKyAgLy8gICAxLiBJZiB0aGUgb3RoZXIgbGlzdCBpcyBlbXB0eSwgdGhlcmUncyBub3RoaW5nIHRvIGRvLiBUaGlzIGVuc3VyZXMgd2UKKyAgLy8gICAgICBkb24ndCBhbGxvY2F0ZSBhIG5ldyBhcnJheSBpZiB3ZSBhbHJlYWR5IGhhdmUgYW4gaW1tdXRhYmxlIG9uZS4KKyAgLy8gICAyLiBJZiB0aGUgb3RoZXIgbGlzdCBpcyBub24tZW1wdHkgYW5kIG91ciBjdXJyZW50IGxpc3QgaXMgZW1wdHksIHdlIGNhbgorICAvLyAgICAgIHJldXNlIHRoZSBvdGhlciBsaXN0IHdoaWNoIGlzIGd1YXJhbnRlZWQgdG8gYmUgaW1tdXRhYmxlLgorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoIW90aGVyLiRuYW1lJF8uaXNFbXB0eSgpKSB7XG4iCisgICAgIiAgaWYgKCRuYW1lJF8uaXNFbXB0eSgpKSB7XG4iCisgICAgIiAgICAkbmFtZSRfID0gb3RoZXIuJG5hbWUkXztcbiIKKyAgICAiICB9IGVsc2Uge1xuIgorICAgICIgICAgZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCk7XG4iCisgICAgIiAgICAkbmFtZSRfLmFkZEFsbChvdGhlci4kbmFtZSRfKTtcbiIKKyAgICAiICB9XG4iCisgICAgIiAgJG9uX2NoYW5nZWQkXG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlTWVzc2FnZUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUR5bmFtaWNNZXRob2RNYWtlSW1tdXRhYmxlQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkbmFtZSRfLm1ha2VJbW11dGFibGUoKTtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlTWVzc2FnZUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZVBhcnNpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICghJGlzX211dGFibGUkKSB7XG4iCisgICAgIiAgJG5hbWUkXyA9IG5ld1Byb3RvYnVmTGlzdCgpO1xuIgorICAgICJ9XG4iKTsKKworICAgIGlmIChHZXRUeXBlKGRlc2NyaXB0b3JfKSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfR1JPVVApIHsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICIkbmFtZSRfLmFkZChpbnB1dC5yZWFkR3JvdXAoJG51bWJlciQsICR0eXBlJC5wYXJzZXIoKSxcbiIKKyAgICAgICAgIiAgICBleHRlbnNpb25SZWdpc3RyeSkpO1xuIik7CisgICAgfSBlbHNlIHsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICIkbmFtZSRfLmFkZChcbiIKKyAgICAgICAgIiAgICBpbnB1dC5yZWFkTWVzc2FnZSgkdHlwZSQucGFyc2VyKCksIGV4dGVuc2lvblJlZ2lzdHJ5KSk7XG4iKTsKKyAgICB9Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVNZXNzYWdlRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlUGFyc2luZ0RvbmVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkaXNfbXV0YWJsZSQpIHtcbiIKKyAgICAiICAkbmFtZSRfLm1ha2VJbW11dGFibGUoKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVNZXNzYWdlRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiZm9yIChpbnQgaSA9IDA7IGkgPCAkbmFtZSRfLnNpemUoKTsgaSsrKSB7XG4iCisgICAgIiAgb3V0cHV0LndyaXRlJGdyb3VwX29yX21lc3NhZ2UkKCRudW1iZXIkLCAkbmFtZSRfLmdldChpKSk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlTWVzc2FnZUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJmb3IgKGludCBpID0gMDsgaSA8ICRuYW1lJF8uc2l6ZSgpOyBpKyspIHtcbiIKKyAgICAiICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW1cbiIKKyAgICAiICAgIC5jb21wdXRlJGdyb3VwX29yX21lc3NhZ2UkU2l6ZSgkbnVtYmVyJCwgJG5hbWUkXy5nZXQoaSkpO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZU1lc3NhZ2VGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVFcXVhbHNDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInJlc3VsdCA9IHJlc3VsdCAmJiBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRMaXN0KClcbiIKKyAgICAiICAgIC5lcXVhbHMob3RoZXIuZ2V0JGNhcGl0YWxpemVkX25hbWUkTGlzdCgpKTtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlTWVzc2FnZUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUhhc2hDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmIChnZXQkY2FwaXRhbGl6ZWRfbmFtZSRDb3VudCgpID4gMCkge1xuIgorICAgICIgIGhhc2ggPSAoMzcgKiBoYXNoKSArICRjb25zdGFudF9uYW1lJDtcbiIKKyAgICAiICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRMaXN0KCkuaGFzaENvZGUoKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3N0cmluZyBSZXBlYXRlZEltbXV0YWJsZU1lc3NhZ2VGaWVsZExpdGVHZW5lcmF0b3I6OkdldEJveGVkVHlwZSgpIGNvbnN0IHsKKyAgcmV0dXJuIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcl8tPm1lc3NhZ2VfdHlwZSgpKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tZXNzYWdlX2ZpZWxkX2xpdGUuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21lc3NhZ2VfZmllbGRfbGl0ZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFlMjZjMDYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tZXNzYWdlX2ZpZWxkX2xpdGUuaApAQCAtMCwwICsxLDE1NyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX01FU1NBR0VfRklFTERfTElURV9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfTUVTU0FHRV9GSUVMRF9MSVRFX0hfXworCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2ZpZWxkLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKyAgbmFtZXNwYWNlIGNvbXBpbGVyIHsKKyAgICBuYW1lc3BhY2UgamF2YSB7CisgICAgICBjbGFzcyBDb250ZXh0OyAgICAgICAgICAgLy8gY29udGV4dC5oCisgICAgICBjbGFzcyBDbGFzc05hbWVSZXNvbHZlcjsgLy8gbmFtZV9yZXNvbHZlci5oCisgICAgfQorICB9Cit9CisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmEgeworCitjbGFzcyBJbW11dGFibGVNZXNzYWdlRmllbGRMaXRlR2VuZXJhdG9yIDogcHVibGljIEltbXV0YWJsZUZpZWxkTGl0ZUdlbmVyYXRvciB7CisgcHVibGljOgorICBleHBsaWNpdCBJbW11dGFibGVNZXNzYWdlRmllbGRMaXRlR2VuZXJhdG9yKAorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwgQ29udGV4dCogY29udGV4dCk7CisgIH5JbW11dGFibGVNZXNzYWdlRmllbGRMaXRlR2VuZXJhdG9yKCk7CisKKyAgLy8gaW1wbGVtZW50cyBJbW11dGFibGVGaWVsZExpdGVHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIGludCBHZXROdW1CaXRzRm9yTWVzc2FnZSgpIGNvbnN0OworICBpbnQgR2V0TnVtQml0c0ZvckJ1aWxkZXIoKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUludGVyZmFjZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRHluYW1pY01ldGhvZE1ha2VJbW11dGFibGVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVBhcnNpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVBhcnNpbmdEb25lQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRmllbGRCdWlsZGVySW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUVxdWFsc0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSGFzaENvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgIHN0cmluZyBHZXRCb3hlZFR5cGUoKSBjb25zdDsKKworIHByb3RlY3RlZDoKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXNfOworICBjb25zdCBpbnQgbWVzc2FnZUJpdEluZGV4XzsKKyAgY29uc3QgaW50IGJ1aWxkZXJCaXRJbmRleF87CisgIENvbnRleHQqIGNvbnRleHRfOworICBDbGFzc05hbWVSZXNvbHZlciogbmFtZV9yZXNvbHZlcl87CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoSW1tdXRhYmxlTWVzc2FnZUZpZWxkTGl0ZUdlbmVyYXRvcik7Cit9OworCitjbGFzcyBJbW11dGFibGVNZXNzYWdlT25lb2ZGaWVsZExpdGVHZW5lcmF0b3IKKyAgICA6IHB1YmxpYyBJbW11dGFibGVNZXNzYWdlRmllbGRMaXRlR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIEltbXV0YWJsZU1lc3NhZ2VPbmVvZkZpZWxkTGl0ZUdlbmVyYXRvcigKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwgaW50IG1lc3NhZ2VCaXRJbmRleCwKKyAgICAgIGludCBidWlsZGVyQml0SW5kZXgsIENvbnRleHQqIGNvbnRleHQpOworICB+SW1tdXRhYmxlTWVzc2FnZU9uZW9mRmllbGRMaXRlR2VuZXJhdG9yKCk7CisKKyAgdm9pZCBHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnVpbGRlck1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhJbW11dGFibGVNZXNzYWdlT25lb2ZGaWVsZExpdGVHZW5lcmF0b3IpOworfTsKKworY2xhc3MgUmVwZWF0ZWRJbW11dGFibGVNZXNzYWdlRmllbGRMaXRlR2VuZXJhdG9yCisgICAgOiBwdWJsaWMgSW1tdXRhYmxlRmllbGRMaXRlR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IFJlcGVhdGVkSW1tdXRhYmxlTWVzc2FnZUZpZWxkTGl0ZUdlbmVyYXRvcigKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwgaW50IG1lc3NhZ2VCaXRJbmRleCwKKyAgICAgIGludCBidWlsZGVyQml0SW5kZXgsIENvbnRleHQqIGNvbnRleHQpOworICB+UmVwZWF0ZWRJbW11dGFibGVNZXNzYWdlRmllbGRMaXRlR2VuZXJhdG9yKCk7CisKKyAgLy8gaW1wbGVtZW50cyBJbW11dGFibGVGaWVsZExpdGVHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIGludCBHZXROdW1CaXRzRm9yTWVzc2FnZSgpIGNvbnN0OworICBpbnQgR2V0TnVtQml0c0ZvckJ1aWxkZXIoKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUludGVyZmFjZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRHluYW1pY01ldGhvZE1ha2VJbW11dGFibGVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVBhcnNpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVBhcnNpbmdEb25lQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRmllbGRCdWlsZGVySW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUVxdWFsc0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSGFzaENvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgIHN0cmluZyBHZXRCb3hlZFR5cGUoKSBjb25zdDsKKworIHByb3RlY3RlZDoKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXNfOworICBjb25zdCBpbnQgbWVzc2FnZUJpdEluZGV4XzsKKyAgY29uc3QgaW50IGJ1aWxkZXJCaXRJbmRleF87CisgIENvbnRleHQqIGNvbnRleHRfOworICBDbGFzc05hbWVSZXNvbHZlciogbmFtZV9yZXNvbHZlcl87CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoUmVwZWF0ZWRJbW11dGFibGVNZXNzYWdlRmllbGRMaXRlR2VuZXJhdG9yKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX01FU1NBR0VfRklFTERfTElURV9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21lc3NhZ2VfbGl0ZS5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21lc3NhZ2VfbGl0ZS5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NGVkMmMzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbWVzc2FnZV9saXRlLmNjCkBAIC0wLDAgKzEsMTE3NCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjogZHdlaXNAZ29vZ2xlLmNvbSAoRGFuaWVsIFdlaXMpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbWVzc2FnZV9saXRlLmg+CisKKyNpbmNsdWRlIDxhbGdvcml0aG0+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2hhc2guaD4KKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorI2luY2x1ZGUgPHZlY3Rvcj4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfY29udGV4dC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZG9jX2NvbW1lbnQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2VudW1fbGl0ZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZXh0ZW5zaW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9nZW5lcmF0b3JfZmFjdG9yeS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfaGVscGVycy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbWVzc2FnZV9idWlsZGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tZXNzYWdlX2J1aWxkZXJfbGl0ZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbmFtZV9yZXNvbHZlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3Vic3RpdHV0ZS5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmEgeworCit1c2luZyBpbnRlcm5hbDo6V2lyZUZvcm1hdDsKK3VzaW5nIGludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTsKKworbmFtZXNwYWNlIHsKK2Jvb2wgR2VuZXJhdGVIYXNCaXRzKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgcmV0dXJuIFN1cHBvcnRGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3ItPmZpbGUoKSkgfHwKKyAgICAgIEhhc1JlcGVhdGVkRmllbGRzKGRlc2NyaXB0b3IpOworfQorCitzdHJpbmcgTWFwVmFsdWVJbW11dGFibGVDbGFzc2ROYW1lKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzTmFtZVJlc29sdmVyKiBuYW1lX3Jlc29sdmVyKSB7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogdmFsdWVfZmllbGQgPSBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoInZhbHVlIik7CisgIEdPT0dMRV9DSEVDS19FUShGaWVsZERlc2NyaXB0b3I6OlRZUEVfTUVTU0FHRSwgdmFsdWVfZmllbGQtPnR5cGUoKSk7CisgIHJldHVybiBuYW1lX3Jlc29sdmVyLT5HZXRJbW11dGFibGVDbGFzc05hbWUodmFsdWVfZmllbGQtPm1lc3NhZ2VfdHlwZSgpKTsKK30KK30gIC8vIG5hbWVzcGFjZQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CitJbW11dGFibGVNZXNzYWdlTGl0ZUdlbmVyYXRvcjo6SW1tdXRhYmxlTWVzc2FnZUxpdGVHZW5lcmF0b3IoCisgICAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwgQ29udGV4dCogY29udGV4dCkKKyAgOiBNZXNzYWdlR2VuZXJhdG9yKGRlc2NyaXB0b3IpLCBjb250ZXh0Xyhjb250ZXh0KSwKKyAgICBuYW1lX3Jlc29sdmVyXyhjb250ZXh0LT5HZXROYW1lUmVzb2x2ZXIoKSksCisgICAgZmllbGRfZ2VuZXJhdG9yc18oZGVzY3JpcHRvciwgY29udGV4dF8pIHsKKyAgR09PR0xFX0NIRUNLX0VRKAorICAgICAgRmlsZU9wdGlvbnM6OkxJVEVfUlVOVElNRSwgZGVzY3JpcHRvci0+ZmlsZSgpLT5vcHRpb25zKCkub3B0aW1pemVfZm9yKCkpOworfQorCitJbW11dGFibGVNZXNzYWdlTGl0ZUdlbmVyYXRvcjo6fkltbXV0YWJsZU1lc3NhZ2VMaXRlR2VuZXJhdG9yKCkge30KKwordm9pZCBJbW11dGFibGVNZXNzYWdlTGl0ZUdlbmVyYXRvcjo6R2VuZXJhdGVTdGF0aWNWYXJpYWJsZXMoCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgLy8gR2VuZXJhdGUgc3RhdGljIG1lbWJlcnMgZm9yIGFsbCBuZXN0ZWQgdHlwZXMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlX2NvdW50KCk7IGkrKykgeworICAgIC8vIFRPRE8oa2VudG9uKTogIFJldXNlIE1lc3NhZ2VHZW5lcmF0b3Igb2JqZWN0cz8KKyAgICBJbW11dGFibGVNZXNzYWdlTGl0ZUdlbmVyYXRvcihkZXNjcmlwdG9yXy0+bmVzdGVkX3R5cGUoaSksIGNvbnRleHRfKQorICAgICAgLkdlbmVyYXRlU3RhdGljVmFyaWFibGVzKHByaW50ZXIpOworICB9Cit9CisKK2ludCBJbW11dGFibGVNZXNzYWdlTGl0ZUdlbmVyYXRvcjo6R2VuZXJhdGVTdGF0aWNWYXJpYWJsZUluaXRpYWxpemVycygKKyAgICBpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBpbnQgYnl0ZWNvZGVfZXN0aW1hdGUgPSAwOworICAvLyBHZW5lcmF0ZSBzdGF0aWMgbWVtYmVyIGluaXRpYWxpemVycyBmb3IgYWxsIG5lc3RlZCB0eXBlcy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+bmVzdGVkX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgLy8gVE9ETyhrZW50b24pOiAgUmV1c2UgTWVzc2FnZUdlbmVyYXRvciBvYmplY3RzPworICAgIGJ5dGVjb2RlX2VzdGltYXRlICs9CisgICAgICAgIEltbXV0YWJsZU1lc3NhZ2VMaXRlR2VuZXJhdG9yKGRlc2NyaXB0b3JfLT5uZXN0ZWRfdHlwZShpKSwgY29udGV4dF8pCisgICAgICAgICAgICAuR2VuZXJhdGVTdGF0aWNWYXJpYWJsZUluaXRpYWxpemVycyhwcmludGVyKTsKKyAgfQorICByZXR1cm4gYnl0ZWNvZGVfZXN0aW1hdGU7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKwordm9pZCBJbW11dGFibGVNZXNzYWdlTGl0ZUdlbmVyYXRvcjo6R2VuZXJhdGVJbnRlcmZhY2UoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgaWYgKGRlc2NyaXB0b3JfLT5leHRlbnNpb25fcmFuZ2VfY291bnQoKSA+IDApIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJwdWJsaWMgaW50ZXJmYWNlICRjbGFzc25hbWUkT3JCdWlsZGVyIGV4dGVuZHMgXG4iCisgICAgICAiICAgICRleHRyYV9pbnRlcmZhY2VzJFxuIgorICAgICAgIiAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlTGl0ZS5cbiIKKyAgICAgICIgICAgICAgICAgRXh0ZW5kYWJsZU1lc3NhZ2VPckJ1aWxkZXI8XG4iCisgICAgICAiICAgICAgICAgICAgICAkY2xhc3NuYW1lJCwgJGNsYXNzbmFtZSQuQnVpbGRlcj4ge1xuIiwKKyAgICAgICJleHRyYV9pbnRlcmZhY2VzIiwgRXh0cmFNZXNzYWdlT3JCdWlsZGVySW50ZXJmYWNlcyhkZXNjcmlwdG9yXyksCisgICAgICAiY2xhc3NuYW1lIiwgZGVzY3JpcHRvcl8tPm5hbWUoKSk7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAicHVibGljIGludGVyZmFjZSAkY2xhc3NuYW1lJE9yQnVpbGRlciBleHRlbmRzXG4iCisgICAgICAiICAgICRleHRyYV9pbnRlcmZhY2VzJFxuIgorICAgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VMaXRlT3JCdWlsZGVyIHtcbiIsCisgICAgICAiZXh0cmFfaW50ZXJmYWNlcyIsIEV4dHJhTWVzc2FnZU9yQnVpbGRlckludGVyZmFjZXMoZGVzY3JpcHRvcl8pLAorICAgICAgImNsYXNzbmFtZSIsIGRlc2NyaXB0b3JfLT5uYW1lKCkpOworICB9CisKKyAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgICBwcmludGVyLT5QcmludCgiXG4iKTsKKyAgICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChkZXNjcmlwdG9yXy0+ZmllbGQoaSkpCisgICAgICAgICAgICAgICAgICAgICAgIC5HZW5lcmF0ZUludGVyZmFjZU1lbWJlcnMocHJpbnRlcik7CisgICAgfQorICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2xfY291bnQoKTsgaSsrKSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAiXG4iCisgICAgICAgICAgInB1YmxpYyAkY2xhc3NuYW1lJC4kb25lb2ZfY2FwaXRhbGl6ZWRfbmFtZSRDYXNlICIKKyAgICAgICAgICAiZ2V0JG9uZW9mX2NhcGl0YWxpemVkX25hbWUkQ2FzZSgpO1xuIiwKKyAgICAgICAgICAib25lb2ZfY2FwaXRhbGl6ZWRfbmFtZSIsCisgICAgICAgICAgY29udGV4dF8tPkdldE9uZW9mR2VuZXJhdG9ySW5mbygKKyAgICAgICAgICAgICAgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSkpLT5jYXBpdGFsaXplZF9uYW1lLAorICAgICAgICAgICJjbGFzc25hbWUiLAorICAgICAgICAgIGNvbnRleHRfLT5HZXROYW1lUmVzb2x2ZXIoKS0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3JfKSk7CisgICAgfQorICBwcmludGVyLT5PdXRkZW50KCk7CisKKyAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK3ZvaWQgSW1tdXRhYmxlTWVzc2FnZUxpdGVHZW5lcmF0b3I6OkdlbmVyYXRlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIGJvb2wgaXNfb3duX2ZpbGUgPQorICAgIGRlc2NyaXB0b3JfLT5jb250YWluaW5nX3R5cGUoKSA9PSBOVUxMICYmCisgICAgTXVsdGlwbGVKYXZhRmlsZXMoZGVzY3JpcHRvcl8tPmZpbGUoKSwgLyogaW1tdXRhYmxlID0gKi8gdHJ1ZSk7CisKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXM7CisgIHZhcmlhYmxlc1sic3RhdGljIl0gPSBpc19vd25fZmlsZSA/ICIgIiA6ICIgc3RhdGljICI7CisgIHZhcmlhYmxlc1siY2xhc3NuYW1lIl0gPSBkZXNjcmlwdG9yXy0+bmFtZSgpOworICB2YXJpYWJsZXNbImV4dHJhX2ludGVyZmFjZXMiXSA9IEV4dHJhTWVzc2FnZUludGVyZmFjZXMoZGVzY3JpcHRvcl8pOworCisgIFdyaXRlTWVzc2FnZURvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworCisgIC8vIFRoZSBidWlsZGVyX3R5cGUgc3RvcmVzIHRoZSBzdXBlciB0eXBlIG5hbWUgb2YgdGhlIG5lc3RlZCBCdWlsZGVyIGNsYXNzLgorICBzdHJpbmcgYnVpbGRlcl90eXBlOworICBpZiAoZGVzY3JpcHRvcl8tPmV4dGVuc2lvbl9yYW5nZV9jb3VudCgpID4gMCkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAgICJwdWJsaWMgJHN0YXRpYyRmaW5hbCBjbGFzcyAkY2xhc3NuYW1lJCBleHRlbmRzXG4iCisgICAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZUxpdGUuRXh0ZW5kYWJsZU1lc3NhZ2U8XG4iCisgICAgICAiICAgICAgJGNsYXNzbmFtZSQsICRjbGFzc25hbWUkLkJ1aWxkZXI+IGltcGxlbWVudHNcbiIKKyAgICAgICIgICAgJGV4dHJhX2ludGVyZmFjZXMkXG4iCisgICAgICAiICAgICRjbGFzc25hbWUkT3JCdWlsZGVyIHtcbiIpOworICAgIGJ1aWxkZXJfdHlwZSA9IHN0cmluZ3M6OlN1YnN0aXR1dGUoCisgICAgICAgICJjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VMaXRlLkV4dGVuZGFibGVCdWlsZGVyPCQwLCA/PiIsCisgICAgICAgIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcl8pKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXMsCisgICAgICAgICJwdWJsaWMgJHN0YXRpYyRmaW5hbCBjbGFzcyAkY2xhc3NuYW1lJCBleHRlbmRzXG4iCisgICAgICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlTGl0ZTxcbiIKKyAgICAgICAgIiAgICAgICAgJGNsYXNzbmFtZSQsICRjbGFzc25hbWUkLkJ1aWxkZXI+IGltcGxlbWVudHNcbiIKKyAgICAgICAgIiAgICAkZXh0cmFfaW50ZXJmYWNlcyRcbiIKKyAgICAgICAgIiAgICAkY2xhc3NuYW1lJE9yQnVpbGRlciB7XG4iKTsKKworICAgIGJ1aWxkZXJfdHlwZSA9ICJjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VMaXRlLkJ1aWxkZXIiOworICB9CisgIHByaW50ZXItPkluZGVudCgpOworCisgIEdlbmVyYXRlUGFyc2luZ0NvbnN0cnVjdG9yKHByaW50ZXIpOworCisgIC8vIE5lc3RlZCB0eXBlcworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5lbnVtX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgRW51bUxpdGVHZW5lcmF0b3IoZGVzY3JpcHRvcl8tPmVudW1fdHlwZShpKSwgdHJ1ZSwgY29udGV4dF8pCisgICAgICAgIC5HZW5lcmF0ZShwcmludGVyKTsKKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlX2NvdW50KCk7IGkrKykgeworICAgIC8vIERvbid0IGdlbmVyYXRlIEphdmEgY2xhc3NlcyBmb3IgbWFwIGVudHJ5IG1lc3NhZ2VzLgorICAgIGlmIChJc01hcEVudHJ5KGRlc2NyaXB0b3JfLT5uZXN0ZWRfdHlwZShpKSkpIGNvbnRpbnVlOworICAgIEltbXV0YWJsZU1lc3NhZ2VMaXRlR2VuZXJhdG9yIG1lc3NhZ2VHZW5lcmF0b3IoCisgICAgICAgIGRlc2NyaXB0b3JfLT5uZXN0ZWRfdHlwZShpKSwgY29udGV4dF8pOworICAgIG1lc3NhZ2VHZW5lcmF0b3IuR2VuZXJhdGVJbnRlcmZhY2UocHJpbnRlcik7CisgICAgbWVzc2FnZUdlbmVyYXRvci5HZW5lcmF0ZShwcmludGVyKTsKKyAgfQorCisgIGlmIChHZW5lcmF0ZUhhc0JpdHMoZGVzY3JpcHRvcl8pKSB7CisgICAgLy8gSW50ZWdlcnMgZm9yIGJpdCBmaWVsZHMuCisgICAgaW50IHRvdGFsQml0cyA9IDA7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgICB0b3RhbEJpdHMgKz0gZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGRlc2NyaXB0b3JfLT5maWVsZChpKSkKKyAgICAgICAgICAuR2V0TnVtQml0c0Zvck1lc3NhZ2UoKTsKKyAgICB9CisgICAgaW50IHRvdGFsSW50cyA9ICh0b3RhbEJpdHMgKyAzMSkgLyAzMjsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHRvdGFsSW50czsgaSsrKSB7CisgICAgICBwcmludGVyLT5QcmludCgicHJpdmF0ZSBpbnQgJGJpdF9maWVsZF9uYW1lJDtcbiIsCisgICAgICAgICJiaXRfZmllbGRfbmFtZSIsIEdldEJpdEZpZWxkTmFtZShpKSk7CisgICAgfQorICB9CisKKyAgLy8gb25lb2YKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJzOworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsX2NvdW50KCk7IGkrKykgeworICAgIHZhcnNbIm9uZW9mX25hbWUiXSA9IGNvbnRleHRfLT5HZXRPbmVvZkdlbmVyYXRvckluZm8oCisgICAgICAgIGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpKS0+bmFtZTsKKyAgICB2YXJzWyJvbmVvZl9jYXBpdGFsaXplZF9uYW1lIl0gPSBjb250ZXh0Xy0+R2V0T25lb2ZHZW5lcmF0b3JJbmZvKAorICAgICAgICBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKSktPmNhcGl0YWxpemVkX25hbWU7CisgICAgdmFyc1sib25lb2ZfaW5kZXgiXSA9IFNpbXBsZUl0b2EoZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPmluZGV4KCkpOworICAgIC8vIG9uZW9mQ2FzZV8gYW5kIG9uZW9mXworICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAicHJpdmF0ZSBpbnQgJG9uZW9mX25hbWUkQ2FzZV8gPSAwO1xuIgorICAgICAgInByaXZhdGUgamF2YS5sYW5nLk9iamVjdCAkb25lb2ZfbmFtZSRfO1xuIik7CisgICAgLy8gT25lb2ZDYXNlIGVudW0KKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgInB1YmxpYyBlbnVtICRvbmVvZl9jYXBpdGFsaXplZF9uYW1lJENhc2VcbiIKKyAgICAgICIgICAgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlIHtcbiIpOworICAgIHByaW50ZXItPkluZGVudCgpOworICAgIGZvciAoaW50IGogPSAwOyBqIDwgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPmZpZWxkX2NvdW50KCk7IGorKykgeworICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5maWVsZChqKTsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiJGZpZWxkX25hbWUkKCRmaWVsZF9udW1iZXIkKSxcbiIsCisgICAgICAgICJmaWVsZF9uYW1lIiwKKyAgICAgICAgVG9VcHBlcihmaWVsZC0+bmFtZSgpKSwKKyAgICAgICAgImZpZWxkX251bWJlciIsCisgICAgICAgIFNpbXBsZUl0b2EoZmllbGQtPm51bWJlcigpKSk7CisgICAgfQorICAgIHByaW50ZXItPlByaW50KAorICAgICAgIiRjYXBfb25lb2ZfbmFtZSRfTk9UX1NFVCgwKTtcbiIsCisgICAgICAiY2FwX29uZW9mX25hbWUiLAorICAgICAgVG9VcHBlcih2YXJzWyJvbmVvZl9uYW1lIl0pKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICAgInByaXZhdGUgaW50IHZhbHVlID0gMDtcbiIKKyAgICAgICJwcml2YXRlICRvbmVvZl9jYXBpdGFsaXplZF9uYW1lJENhc2UoaW50IHZhbHVlKSB7XG4iCisgICAgICAiICB0aGlzLnZhbHVlID0gdmFsdWU7XG4iCisgICAgICAifVxuIik7CisgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICJwdWJsaWMgc3RhdGljICRvbmVvZl9jYXBpdGFsaXplZF9uYW1lJENhc2UgdmFsdWVPZihpbnQgdmFsdWUpIHtcbiIKKyAgICAgICIgIHN3aXRjaCAodmFsdWUpIHtcbiIpOworICAgIGZvciAoaW50IGogPSAwOyBqIDwgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPmZpZWxkX2NvdW50KCk7IGorKykgeworICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5maWVsZChqKTsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiICAgIGNhc2UgJGZpZWxkX251bWJlciQ6IHJldHVybiAkZmllbGRfbmFtZSQ7XG4iLAorICAgICAgICAiZmllbGRfbnVtYmVyIiwKKyAgICAgICAgU2ltcGxlSXRvYShmaWVsZC0+bnVtYmVyKCkpLAorICAgICAgICAiZmllbGRfbmFtZSIsCisgICAgICAgIFRvVXBwZXIoZmllbGQtPm5hbWUoKSkpOworICAgIH0KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICIgICAgY2FzZSAwOiByZXR1cm4gJGNhcF9vbmVvZl9uYW1lJF9OT1RfU0VUO1xuIgorICAgICAgIiAgICBkZWZhdWx0OiB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihcbiIKKyAgICAgICIgICAgICBcIlZhbHVlIGlzIHVuZGVmaW5lZCBmb3IgdGhpcyBvbmVvZiBlbnVtLlwiKTtcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICJ9XG4iCisgICAgICAicHVibGljIGludCBnZXROdW1iZXIoKSB7XG4iCisgICAgICAiICByZXR1cm4gdGhpcy52YWx1ZTtcbiIKKyAgICAgICJ9XG4iLAorICAgICAgImNhcF9vbmVvZl9uYW1lIiwgVG9VcHBlcih2YXJzWyJvbmVvZl9uYW1lIl0pKTsKKyAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgcHJpbnRlci0+UHJpbnQoIn07XG5cbiIpOworICAgIC8vIG9uZW9mQ2FzZSgpCisgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICJwdWJsaWMgJG9uZW9mX2NhcGl0YWxpemVkX25hbWUkQ2FzZVxuIgorICAgICAgImdldCRvbmVvZl9jYXBpdGFsaXplZF9uYW1lJENhc2UoKSB7XG4iCisgICAgICAiICByZXR1cm4gJG9uZW9mX2NhcGl0YWxpemVkX25hbWUkQ2FzZS52YWx1ZU9mKFxuIgorICAgICAgIiAgICAgICRvbmVvZl9uYW1lJENhc2VfKTtcbiIKKyAgICAgICJ9XG4iCisgICAgICAiXG4iCisgICAgICAicHJpdmF0ZSB2b2lkIGNsZWFyJG9uZW9mX2NhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICAgIiAgJG9uZW9mX25hbWUkQ2FzZV8gPSAwO1xuIgorICAgICAgIiAgJG9uZW9mX25hbWUkXyA9IG51bGw7XG4iCisgICAgICAifVxuIgorICAgICAgIlxuIik7CisgIH0KKworICAvLyBGaWVsZHMKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgcHJpbnRlci0+UHJpbnQoInB1YmxpYyBzdGF0aWMgZmluYWwgaW50ICRjb25zdGFudF9uYW1lJCA9ICRudW1iZXIkO1xuIiwKKyAgICAgICJjb25zdGFudF9uYW1lIiwgRmllbGRDb25zdGFudE5hbWUoZGVzY3JpcHRvcl8tPmZpZWxkKGkpKSwKKyAgICAgICJudW1iZXIiLCBTaW1wbGVJdG9hKGRlc2NyaXB0b3JfLT5maWVsZChpKS0+bnVtYmVyKCkpKTsKKyAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZGVzY3JpcHRvcl8tPmZpZWxkKGkpKS5HZW5lcmF0ZU1lbWJlcnMocHJpbnRlcik7CisgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisgIH0KKworICBHZW5lcmF0ZU1lc3NhZ2VTZXJpYWxpemF0aW9uTWV0aG9kcyhwcmludGVyKTsKKworICBpZiAoSGFzRXF1YWxzQW5kSGFzaENvZGUoZGVzY3JpcHRvcl8pKSB7CisgICAgR2VuZXJhdGVFcXVhbHNBbmRIYXNoQ29kZShwcmludGVyKTsKKyAgfQorCisKKyAgR2VuZXJhdGVQYXJzZUZyb21NZXRob2RzKHByaW50ZXIpOworICBHZW5lcmF0ZUJ1aWxkZXIocHJpbnRlcik7CisKKyAgaWYgKEhhc1JlcXVpcmVkRmllbGRzKGRlc2NyaXB0b3JfKSkgeworICAgIC8vIE1lbW9pemVzIHdoZXRoZXIgdGhlIHByb3RvY29sIGJ1ZmZlciBpcyBmdWxseSBpbml0aWFsaXplZCAoaGFzIGFsbAorICAgIC8vIHJlcXVpcmVkIGZpZWxkcykuIC0xIG1lYW5zIG5vdCB5ZXQgY29tcHV0ZWQuIDAgbWVhbnMgZmFsc2UgYW5kIDEgbWVhbnMKKyAgICAvLyB0cnVlLgorICAgIHByaW50ZXItPlByaW50KAorICAgICAgInByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTtcbiIpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgInByb3RlY3RlZCBmaW5hbCBPYmplY3QgZHluYW1pY01ldGhvZChcbiIKKyAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZUxpdGUuTWV0aG9kVG9JbnZva2UgbWV0aG9kLFxuIgorICAgICIgICAgT2JqZWN0IGFyZzAsIE9iamVjdCBhcmcxKSB7XG4iCisgICAgIiAgc3dpdGNoIChtZXRob2QpIHtcbiIKKyAgICAiICAgIGNhc2UgUEFSU0VfUEFSVElBTF9GUk9NOiB7XG4iCisgICAgIiAgICAgIHJldHVybiBuZXcgJGNsYXNzbmFtZSQoIgorICAgICIgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSkgYXJnMCxcbiIKKyAgICAiICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSkgYXJnMSk7XG4iCisgICAgIiAgICB9XG4iCisgICAgIiAgICBjYXNlIE5FV19JTlNUQU5DRToge1xuIgorICAgICIgICAgICByZXR1cm4gbmV3ICRjbGFzc25hbWUkKFxuIgorICAgICIgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FTVBUWV9DT0RFRF9JTlBVVF9TVFJFQU0sXG4iCisgICAgIiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZVxuIgorICAgICIgICAgICAgICAgICAgIC5nZXRFbXB0eVJlZ2lzdHJ5KCkpO1xuIgorICAgICIgICAgfVxuIiwKKyAgICAiY2xhc3NuYW1lIiwgbmFtZV9yZXNvbHZlcl8tPkdldEltbXV0YWJsZUNsYXNzTmFtZShkZXNjcmlwdG9yXykpOworCisgIHByaW50ZXItPkluZGVudCgpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAiY2FzZSBJU19JTklUSUFMSVpFRDoge1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworICBHZW5lcmF0ZUR5bmFtaWNNZXRob2RJc0luaXRpYWxpemVkKHByaW50ZXIpOworICBwcmludGVyLT5PdXRkZW50KCk7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIn1cbiIKKyAgICAiY2FzZSBNQUtFX0lNTVVUQUJMRToge1xuIik7CisKKyAgcHJpbnRlci0+SW5kZW50KCk7CisgIEdlbmVyYXRlRHluYW1pY01ldGhvZE1ha2VJbW11dGFibGUocHJpbnRlcik7CisgIHByaW50ZXItPk91dGRlbnQoKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAifVxuIgorICAgICJjYXNlIE5FV19CVUlMREVSOiB7XG4iKTsKKworICBwcmludGVyLT5JbmRlbnQoKTsKKyAgR2VuZXJhdGVEeW5hbWljTWV0aG9kTmV3QnVpbGRlcihwcmludGVyKTsKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworCisgIHByaW50ZXItPlByaW50KAorICAgICJ9XG4iCisgICAgImNhc2UgTUVSR0VfRlJPTToge1xuIik7CisKKyAgcHJpbnRlci0+SW5kZW50KCk7CisgIEdlbmVyYXRlRHluYW1pY01ldGhvZE1lcmdlRnJvbShwcmludGVyKTsKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworCisgIHByaW50ZXItPlByaW50KAorICAgICJ9XG4iCisgICAgImNhc2UgR0VUX0RFRkFVTFRfSU5TVEFOQ0U6IHtcbiIKKyAgICAiICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTtcbiIKKyAgICAifVxuIgorICAgICJjYXNlIEdFVF9QQVJTRVI6IHtcbiIKKyAgICAvLyBHZW5lcmFsbHkgb25lIHdvdWxkIHVzZSB0aGUgbGF6eSBpbml0aWFsaXphdGlvbiBob2xkZXIgcGF0dGVybiBmb3IKKyAgICAvLyBtYW5pcHVsYXRpbmcgc3RhdGljIGZpZWxkcyBidXQgdGhhdCBoYXMgZXhjZXB0aW9uYWwgY29zdCBvbiBBbmRyb2lkIGFzCisgICAgLy8gaXQgd2lsbCBnZW5lcmF0ZSBhbiBleHRyYSBjbGFzcyBmb3IgZXZlcnkgbWVzc2FnZS4gSW5zdGVhZCwgdXNlIHRoZQorICAgIC8vIGRvdWJsZS1jaGVjayBsb2NraW5nIHBhdHRlcm4gd2hpY2ggd29ya3MganVzdCBhcyB3ZWxsLgorICAgICIgIGlmIChQQVJTRVIgPT0gbnVsbCkgeyIKKyAgICAiICAgIHN5bmNocm9uaXplZCAoJGNsYXNzbmFtZSQuY2xhc3MpIHtcbiIKKyAgICAiICAgICAgaWYgKFBBUlNFUiA9PSBudWxsKSB7XG4iCisgICAgIiAgICAgICAgUEFSU0VSID0gbmV3IERlZmF1bHRJbnN0YW5jZUJhc2VkUGFyc2VyKERFRkFVTFRfSU5TVEFOQ0UpO1xuIgorICAgICIgICAgICB9XG4iCisgICAgIiAgICB9XG4iCisgICAgIiAgfVxuIgorICAgICIgIHJldHVybiBQQVJTRVI7XG4iCisgICAgIn1cbiIsCisgICAgImNsYXNzbmFtZSIsIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcl8pKTsKKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPk91dGRlbnQoKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAiICB9XG4iCisgICAgIiAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7XG4iCisgICAgIn1cbiIKKyAgICAiXG4iLAorICAgICJjbGFzc25hbWUiLCBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3JfKSk7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIlxuIgorICAgICIvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6JGZ1bGxfbmFtZSQpXG4iLAorICAgICJmdWxsX25hbWUiLCBkZXNjcmlwdG9yXy0+ZnVsbF9uYW1lKCkpOworCisKKyAgLy8gQ2FyZWZ1bGx5IGluaXRpYWxpemUgdGhlIGRlZmF1bHQgaW5zdGFuY2UgaW4gc3VjaCBhIHdheSB0aGF0IGl0IGRvZXNuJ3QKKyAgLy8gY29uZmxpY3Qgd2l0aCBvdGhlciBpbml0aWFsaXphdGlvbi4KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgInByaXZhdGUgc3RhdGljIGZpbmFsICRjbGFzc25hbWUkIERFRkFVTFRfSU5TVEFOQ0U7XG4iLAorICAgICJjbGFzc25hbWUiLCBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3JfKSk7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgInN0YXRpYyB7XG4iCisgICAgIiAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyAkY2xhc3NuYW1lJChcbiIKKyAgICAiICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbFxuIgorICAgICIgICAgICAgICAgLkVNUFRZX0NPREVEX0lOUFVUX1NUUkVBTSxcbiIKKyAgICAiICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGVcbiIKKyAgICAiICAgICAgICAgIC5nZXRFbXB0eVJlZ2lzdHJ5KCkpO1xuIgorICAgICJ9XG4iCisgICAgIlxuIiwKKyAgICAiY2xhc3NuYW1lIiwgZGVzY3JpcHRvcl8tPm5hbWUoKSk7CisgIHByaW50ZXItPlByaW50KAorICAgICAgInB1YmxpYyBzdGF0aWMgJGNsYXNzbmFtZSQgZ2V0RGVmYXVsdEluc3RhbmNlKCkge1xuIgorICAgICAgIiAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7XG4iCisgICAgICAifVxuIgorICAgICAgIlxuIiwKKyAgICAgICJjbGFzc25hbWUiLCBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3JfKSk7CisKKyAgR2VuZXJhdGVQYXJzZXIocHJpbnRlcik7CisKKyAgLy8gRXh0ZW5zaW9ucyBtdXN0IGJlIGRlY2xhcmVkIGFmdGVyIHRoZSBERUZBVUxUX0lOU1RBTkNFIGlzIGluaXRpYWxpemVkCisgIC8vIGJlY2F1c2UgdGhlIERFRkFVTFRfSU5TVEFOQ0UgaXMgdXNlZCBieSB0aGUgZXh0ZW5zaW9uIHRvIGxhemlseSByZXRyaWV2ZQorICAvLyB0aGUgb3V0ZXIgY2xhc3MncyBGaWxlRGVzY3JpcHRvci4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX2NvdW50KCk7IGkrKykgeworICAgIEltbXV0YWJsZUV4dGVuc2lvbkdlbmVyYXRvcihkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uKGkpLCBjb250ZXh0XykKKyAgICAgICAgLkdlbmVyYXRlKHByaW50ZXIpOworICB9CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgifVxuXG4iKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCit2b2lkIEltbXV0YWJsZU1lc3NhZ2VMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVzc2FnZVNlcmlhbGl6YXRpb25NZXRob2RzKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9hcnJheTxjb25zdCBGaWVsZERlc2NyaXB0b3IgKiA+IHNvcnRlZF9maWVsZHMoCisgICAgICBTb3J0RmllbGRzQnlOdW1iZXIoZGVzY3JpcHRvcl8pKTsKKworICB2ZWN0b3I8Y29uc3QgRGVzY3JpcHRvcjo6RXh0ZW5zaW9uUmFuZ2UqPiBzb3J0ZWRfZXh0ZW5zaW9uczsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCk7ICsraSkgeworICAgIHNvcnRlZF9leHRlbnNpb25zLnB1c2hfYmFjayhkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX3JhbmdlKGkpKTsKKyAgfQorICBzdGQ6OnNvcnQoc29ydGVkX2V4dGVuc2lvbnMuYmVnaW4oKSwgc29ydGVkX2V4dGVuc2lvbnMuZW5kKCksCisgICAgICAgICAgICBFeHRlbnNpb25SYW5nZU9yZGVyaW5nKCkpOworCisgIHByaW50ZXItPlByaW50KAorICAgICJwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KVxuIgorICAgICIgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHtcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKyAgaWYgKEhhc1BhY2tlZEZpZWxkcyhkZXNjcmlwdG9yXykpIHsKKyAgICAvLyB3cml0ZVRvKENvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkgbWlnaHQgYmUgaW52b2tlZCB3aXRob3V0CisgICAgLy8gZ2V0U2VyaWFsaXplZFNpemUoKSBldmVyIGJlaW5nIGNhbGxlZCwgYnV0IHdlIG5lZWQgdGhlIG1lbW9pemVkCisgICAgLy8gc2l6ZXMgaW4gY2FzZSB0aGlzIG1lc3NhZ2UgaGFzIHBhY2tlZCBmaWVsZHMuIFJhdGhlciB0aGFuIGVtaXQgY2hlY2tzIGZvcgorICAgIC8vIGVhY2ggcGFja2VkIGZpZWxkLCBqdXN0IGNhbGwgZ2V0U2VyaWFsaXplZFNpemUoKSB1cCBmcm9udC4KKyAgICAvLyBJbiBtb3N0IGNhc2VzLCBnZXRTZXJpYWxpemVkU2l6ZSgpIHdpbGwgaGF2ZSBhbHJlYWR5IGJlZW4gY2FsbGVkIGFueXdheQorICAgIC8vIGJ5IG9uZSBvZiB0aGUgd3JhcHBlciB3cml0ZVRvKCkgbWV0aG9kcywgbWFraW5nIHRoaXMgY2FsbCBjaGVhcC4KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJnZXRTZXJpYWxpemVkU2l6ZSgpO1xuIik7CisgIH0KKworICBpZiAoZGVzY3JpcHRvcl8tPmV4dGVuc2lvbl9yYW5nZV9jb3VudCgpID4gMCkgeworICAgIGlmIChkZXNjcmlwdG9yXy0+b3B0aW9ucygpLm1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KCkpIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlTGl0ZVxuIgorICAgICAgICAiICAuRXh0ZW5kYWJsZU1lc3NhZ2U8JGNsYXNzbmFtZSQsICRjbGFzc25hbWUkLkJ1aWxkZXI+XG4iCisgICAgICAgICIgICAgLkV4dGVuc2lvbldyaXRlciBleHRlbnNpb25Xcml0ZXIgPVxuIgorICAgICAgICAiICAgICAgbmV3TWVzc2FnZVNldEV4dGVuc2lvbldyaXRlcigpO1xuIiwKKyAgICAgICAgImNsYXNzbmFtZSIsIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcl8pKTsKKyAgICB9IGVsc2UgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VMaXRlXG4iCisgICAgICAgICIgIC5FeHRlbmRhYmxlTWVzc2FnZTwkY2xhc3NuYW1lJCwgJGNsYXNzbmFtZSQuQnVpbGRlcj5cbiIKKyAgICAgICAgIiAgICAuRXh0ZW5zaW9uV3JpdGVyIGV4dGVuc2lvbldyaXRlciA9XG4iCisgICAgICAgICIgICAgICBuZXdFeHRlbnNpb25Xcml0ZXIoKTtcbiIsCisgICAgICAgICJjbGFzc25hbWUiLCBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3JfKSk7CisgICAgfQorICB9CisKKyAgLy8gTWVyZ2UgdGhlIGZpZWxkcyBhbmQgdGhlIGV4dGVuc2lvbiByYW5nZXMsIGJvdGggc29ydGVkIGJ5IGZpZWxkIG51bWJlci4KKyAgZm9yIChpbnQgaSA9IDAsIGogPSAwOworICAgICAgIGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKSB8fCBqIDwgc29ydGVkX2V4dGVuc2lvbnMuc2l6ZSgpOworICAgICAgICkgeworICAgIGlmIChpID09IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpKSB7CisgICAgICBHZW5lcmF0ZVNlcmlhbGl6ZU9uZUV4dGVuc2lvblJhbmdlKHByaW50ZXIsIHNvcnRlZF9leHRlbnNpb25zW2orK10pOworICAgIH0gZWxzZSBpZiAoaiA9PSBzb3J0ZWRfZXh0ZW5zaW9ucy5zaXplKCkpIHsKKyAgICAgIEdlbmVyYXRlU2VyaWFsaXplT25lRmllbGQocHJpbnRlciwgc29ydGVkX2ZpZWxkc1tpKytdKTsKKyAgICB9IGVsc2UgaWYgKHNvcnRlZF9maWVsZHNbaV0tPm51bWJlcigpIDwgc29ydGVkX2V4dGVuc2lvbnNbal0tPnN0YXJ0KSB7CisgICAgICBHZW5lcmF0ZVNlcmlhbGl6ZU9uZUZpZWxkKHByaW50ZXIsIHNvcnRlZF9maWVsZHNbaSsrXSk7CisgICAgfSBlbHNlIHsKKyAgICAgIEdlbmVyYXRlU2VyaWFsaXplT25lRXh0ZW5zaW9uUmFuZ2UocHJpbnRlciwgc29ydGVkX2V4dGVuc2lvbnNbaisrXSk7CisgICAgfQorICB9CisKKyAgaWYgKFByZXNlcnZlVW5rbm93bkZpZWxkcyhkZXNjcmlwdG9yXykpIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJ1bmtub3duRmllbGRzLndyaXRlVG8ob3V0cHV0KTtcbiIpOworICB9CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAifVxuIgorICAgICJcbiIKKyAgICAicHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHtcbiIKKyAgICAiICBpbnQgc2l6ZSA9IG1lbW9pemVkU2VyaWFsaXplZFNpemU7XG4iCisgICAgIiAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplO1xuIgorICAgICJcbiIKKyAgICAiICBzaXplID0gMDtcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoc29ydGVkX2ZpZWxkc1tpXSkuR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUocHJpbnRlcik7CisgIH0KKworICBpZiAoZGVzY3JpcHRvcl8tPmV4dGVuc2lvbl9yYW5nZV9jb3VudCgpID4gMCkgeworICAgIGlmIChkZXNjcmlwdG9yXy0+b3B0aW9ucygpLm1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KCkpIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAic2l6ZSArPSBleHRlbnNpb25zU2VyaWFsaXplZFNpemVBc01lc3NhZ2VTZXQoKTtcbiIpOworICAgIH0gZWxzZSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgInNpemUgKz0gZXh0ZW5zaW9uc1NlcmlhbGl6ZWRTaXplKCk7XG4iKTsKKyAgICB9CisgIH0KKworICBpZiAoUHJlc2VydmVVbmtub3duRmllbGRzKGRlc2NyaXB0b3JfKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgInNpemUgKz0gdW5rbm93bkZpZWxkcy5nZXRTZXJpYWxpemVkU2l6ZSgpO1xuIik7CisgIH0KKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KAorICAgICIgIG1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBzaXplO1xuIgorICAgICIgIHJldHVybiBzaXplO1xuIgorICAgICJ9XG4iCisgICAgIlxuIik7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgInByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMO1xuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlTWVzc2FnZUxpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVQYXJzZUZyb21NZXRob2RzKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIC8vIE5vdGU6ICBUaGVzZSBhcmUgc2VwYXJhdGUgZnJvbSBHZW5lcmF0ZU1lc3NhZ2VTZXJpYWxpemF0aW9uTWV0aG9kcygpCisgIC8vICAgYmVjYXVzZSB0aGV5IG5lZWQgdG8gYmUgZ2VuZXJhdGVkIGV2ZW4gZm9yIG1lc3NhZ2VzIHRoYXQgYXJlIG9wdGltaXplZAorICAvLyAgIGZvciBjb2RlIHNpemUuCisgIHByaW50ZXItPlByaW50KAorICAgICJwdWJsaWMgc3RhdGljICRjbGFzc25hbWUkIHBhcnNlRnJvbShcbiIKKyAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKVxuIgorICAgICIgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHtcbiIKKyAgICAiICByZXR1cm4gcGFyc2VyKCkucGFyc2VGcm9tKGRhdGEpO1xuIgorICAgICJ9XG4iCisgICAgInB1YmxpYyBzdGF0aWMgJGNsYXNzbmFtZSQgcGFyc2VGcm9tKFxuIgorICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsXG4iCisgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSlcbiIKKyAgICAiICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7XG4iCisgICAgIiAgcmV0dXJuIHBhcnNlcigpLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7XG4iCisgICAgIn1cbiIKKyAgICAicHVibGljIHN0YXRpYyAkY2xhc3NuYW1lJCBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpXG4iCisgICAgIiAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24ge1xuIgorICAgICIgIHJldHVybiBwYXJzZXIoKS5wYXJzZUZyb20oZGF0YSk7XG4iCisgICAgIn1cbiIKKyAgICAicHVibGljIHN0YXRpYyAkY2xhc3NuYW1lJCBwYXJzZUZyb20oXG4iCisgICAgIiAgICBieXRlW10gZGF0YSxcbiIKKyAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KVxuIgorICAgICIgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHtcbiIKKyAgICAiICByZXR1cm4gcGFyc2VyKCkucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTtcbiIKKyAgICAifVxuIgorICAgICJwdWJsaWMgc3RhdGljICRjbGFzc25hbWUkIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KVxuIgorICAgICIgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24ge1xuIgorICAgICIgIHJldHVybiBwYXJzZXIoKS5wYXJzZUZyb20oaW5wdXQpO1xuIgorICAgICJ9XG4iCisgICAgInB1YmxpYyBzdGF0aWMgJGNsYXNzbmFtZSQgcGFyc2VGcm9tKFxuIgorICAgICIgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCxcbiIKKyAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KVxuIgorICAgICIgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24ge1xuIgorICAgICIgIHJldHVybiBwYXJzZXIoKS5wYXJzZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTtcbiIKKyAgICAifVxuIgorICAgICJwdWJsaWMgc3RhdGljICRjbGFzc25hbWUkIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KVxuIgorICAgICIgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24ge1xuIgorICAgICIgIHJldHVybiBwYXJzZXIoKS5wYXJzZURlbGltaXRlZEZyb20oaW5wdXQpO1xuIgorICAgICJ9XG4iCisgICAgInB1YmxpYyBzdGF0aWMgJGNsYXNzbmFtZSQgcGFyc2VEZWxpbWl0ZWRGcm9tKFxuIgorICAgICIgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCxcbiIKKyAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KVxuIgorICAgICIgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24ge1xuIgorICAgICIgIHJldHVybiBwYXJzZXIoKS5wYXJzZURlbGltaXRlZEZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTtcbiIKKyAgICAifVxuIgorICAgICJwdWJsaWMgc3RhdGljICRjbGFzc25hbWUkIHBhcnNlRnJvbShcbiIKKyAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dClcbiIKKyAgICAiICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHtcbiIKKyAgICAiICByZXR1cm4gcGFyc2VyKCkucGFyc2VGcm9tKGlucHV0KTtcbiIKKyAgICAifVxuIgorICAgICJwdWJsaWMgc3RhdGljICRjbGFzc25hbWUkIHBhcnNlRnJvbShcbiIKKyAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCxcbiIKKyAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KVxuIgorICAgICIgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24ge1xuIgorICAgICIgIHJldHVybiBwYXJzZXIoKS5wYXJzZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTtcbiIKKyAgICAifVxuIgorICAgICJcbiIsCisgICAgImNsYXNzbmFtZSIsIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcl8pKTsKK30KKwordm9pZCBJbW11dGFibGVNZXNzYWdlTGl0ZUdlbmVyYXRvcjo6R2VuZXJhdGVTZXJpYWxpemVPbmVGaWVsZCgKKyAgICBpbzo6UHJpbnRlciogcHJpbnRlciwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZmllbGQpLkdlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUocHJpbnRlcik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlTWVzc2FnZUxpdGVHZW5lcmF0b3I6OkdlbmVyYXRlU2VyaWFsaXplT25lRXh0ZW5zaW9uUmFuZ2UoCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIsIGNvbnN0IERlc2NyaXB0b3I6OkV4dGVuc2lvblJhbmdlKiByYW5nZSkgeworICBwcmludGVyLT5QcmludCgKKyAgICAiZXh0ZW5zaW9uV3JpdGVyLndyaXRlVW50aWwoJGVuZCQsIG91dHB1dCk7XG4iLAorICAgICJlbmQiLCBTaW1wbGVJdG9hKHJhbmdlLT5lbmQpKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCit2b2lkIEltbXV0YWJsZU1lc3NhZ2VMaXRlR2VuZXJhdG9yOjpHZW5lcmF0ZUJ1aWxkZXIoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgInB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkge1xuIgorICAgICIgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpO1xuIgorICAgICJ9XG4iCisgICAgInB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCRjbGFzc25hbWUkIHByb3RvdHlwZSkge1xuIgorICAgICIgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpO1xuIgorICAgICJ9XG4iCisgICAgIlxuIiwKKyAgICAiY2xhc3NuYW1lIiwgbmFtZV9yZXNvbHZlcl8tPkdldEltbXV0YWJsZUNsYXNzTmFtZShkZXNjcmlwdG9yXykpOworCisgIE1lc3NhZ2VCdWlsZGVyTGl0ZUdlbmVyYXRvciBidWlsZGVyR2VuZXJhdG9yKGRlc2NyaXB0b3JfLCBjb250ZXh0Xyk7CisgIGJ1aWxkZXJHZW5lcmF0b3IuR2VuZXJhdGUocHJpbnRlcik7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKwordm9pZCBJbW11dGFibGVNZXNzYWdlTGl0ZUdlbmVyYXRvcjo6R2VuZXJhdGVEeW5hbWljTWV0aG9kSXNJbml0aWFsaXplZCgKKyAgICBpbzo6UHJpbnRlciogcHJpbnRlcikgeworICAvLyBSZXR1cm5zIG51bGwgZm9yIGZhbHNlLCBERUZBVUxUX0lOU1RBTkNFIGZvciB0cnVlLgorICBpZiAoIUhhc1JlcXVpcmVkRmllbGRzKGRlc2NyaXB0b3JfKSkgeworICAgIHByaW50ZXItPlByaW50KCJyZXR1cm4gREVGQVVMVF9JTlNUQU5DRTtcbiIpOworICAgIHJldHVybjsKKyAgfQorCisgIC8vIERvbid0IGRpcmVjdGx5IGNvbXBhcmUgdG8gLTEgdG8gYXZvaWQgYW4gQW5kcm9pZCB4ODYgSklUIGJ1Zy4KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgImJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDtcbiIKKyAgICAiaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7XG4iCisgICAgImlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBudWxsO1xuIgorICAgICJcbiIKKyAgICAiYm9vbGVhbiBzaG91bGRNZW1vaXplID0gKChCb29sZWFuKSBhcmcwKS5ib29sZWFuVmFsdWUoKTtcbiIpOworCisgIC8vIENoZWNrIHRoYXQgYWxsIHJlcXVpcmVkIGZpZWxkcyBpbiB0aGlzIG1lc3NhZ2UgYXJlIHNldC4KKyAgLy8gVE9ETyhrZW50b24pOiAgV2UgY2FuIG9wdGltaXplIHRoaXMgd2hlbiB3ZSBzd2l0Y2ggdG8gcHV0dGluZyBhbGwgdGhlCisgIC8vICAgImhhcyIgZmllbGRzIGludG8gYSBzaW5nbGUgYml0ZmllbGQuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBkZXNjcmlwdG9yXy0+ZmllbGQoaSk7CisgICAgY29uc3QgRmllbGRHZW5lcmF0b3JJbmZvKiBpbmZvID0gY29udGV4dF8tPkdldEZpZWxkR2VuZXJhdG9ySW5mbyhmaWVsZCk7CisKKyAgICBpZiAoZmllbGQtPmlzX3JlcXVpcmVkKCkpIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiaWYgKCFoYXMkbmFtZSQoKSkge1xuIgorICAgICAgICAiICBpZiAoc2hvdWxkTWVtb2l6ZSkge1xuIgorICAgICAgICAiICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7XG4iCisgICAgICAgICIgIH1cbiIKKyAgICAgICAgIiAgcmV0dXJuIG51bGw7XG4iCisgICAgICAgICJ9XG4iLAorICAgICAgICAibmFtZSIsIGluZm8tPmNhcGl0YWxpemVkX25hbWUpOworICAgIH0KKyAgfQorCisgIC8vIE5vdyBjaGVjayB0aGF0IGFsbCBlbWJlZGRlZCBtZXNzYWdlcyBhcmUgaW5pdGlhbGl6ZWQuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBkZXNjcmlwdG9yXy0+ZmllbGQoaSk7CisgICAgY29uc3QgRmllbGRHZW5lcmF0b3JJbmZvKiBpbmZvID0gY29udGV4dF8tPkdldEZpZWxkR2VuZXJhdG9ySW5mbyhmaWVsZCk7CisgICAgaWYgKEdldEphdmFUeXBlKGZpZWxkKSA9PSBKQVZBVFlQRV9NRVNTQUdFICYmCisgICAgICAgIEhhc1JlcXVpcmVkRmllbGRzKGZpZWxkLT5tZXNzYWdlX3R5cGUoKSkpIHsKKyAgICAgIHN3aXRjaCAoZmllbGQtPmxhYmVsKCkpIHsKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkxBQkVMX1JFUVVJUkVEOgorICAgICAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICAgImlmICghZ2V0JG5hbWUkKCkuaXNJbml0aWFsaXplZCgpKSB7XG4iCisgICAgICAgICAgICAiICBpZiAoc2hvdWxkTWVtb2l6ZSkge1xuIgorICAgICAgICAgICAgIiAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwO1xuIgorICAgICAgICAgICAgIiAgfVxuIgorICAgICAgICAgICAgIiAgcmV0dXJuIG51bGw7XG4iCisgICAgICAgICAgICAifVxuIiwKKyAgICAgICAgICAgICJ0eXBlIiwgbmFtZV9yZXNvbHZlcl8tPkdldEltbXV0YWJsZUNsYXNzTmFtZSgKKyAgICAgICAgICAgICAgICBmaWVsZC0+bWVzc2FnZV90eXBlKCkpLAorICAgICAgICAgICAgIm5hbWUiLCBpbmZvLT5jYXBpdGFsaXplZF9uYW1lKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkxBQkVMX09QVElPTkFMOgorICAgICAgICAgIGlmICghU3VwcG9ydEZpZWxkUHJlc2VuY2UoZGVzY3JpcHRvcl8tPmZpbGUoKSkgJiYKKyAgICAgICAgICAgICAgZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSAhPSBOVUxMKSB7CisgICAgICAgICAgICBjb25zdCBPbmVvZkRlc2NyaXB0b3IqIG9uZW9mID0gZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKTsKKyAgICAgICAgICAgIGNvbnN0IE9uZW9mR2VuZXJhdG9ySW5mbyogb25lb2ZfaW5mbyA9CisgICAgICAgICAgICAgICAgY29udGV4dF8tPkdldE9uZW9mR2VuZXJhdG9ySW5mbyhvbmVvZik7CisgICAgICAgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAgICAgImlmICgkb25lb2ZfbmFtZSRDYXNlXyA9PSAkZmllbGRfbnVtYmVyJCkge1xuIiwKKyAgICAgICAgICAgICAgIm9uZW9mX25hbWUiLCBvbmVvZl9pbmZvLT5uYW1lLAorICAgICAgICAgICAgICAiZmllbGRfbnVtYmVyIiwgU2ltcGxlSXRvYShmaWVsZC0+bnVtYmVyKCkpKTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgICAgICJpZiAoaGFzJG5hbWUkKCkpIHtcbiIsCisgICAgICAgICAgICAgICJuYW1lIiwgaW5mby0+Y2FwaXRhbGl6ZWRfbmFtZSk7CisgICAgICAgICAgfQorICAgICAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICAgIiAgaWYgKCFnZXQkbmFtZSQoKS5pc0luaXRpYWxpemVkKCkpIHtcbiIKKyAgICAgICAgICAgICIgICAgaWYgKHNob3VsZE1lbW9pemUpIHtcbiIKKyAgICAgICAgICAgICIgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwO1xuIgorICAgICAgICAgICAgIiAgICB9XG4iCisgICAgICAgICAgICAiICAgIHJldHVybiBudWxsO1xuIgorICAgICAgICAgICAgIiAgfVxuIgorICAgICAgICAgICAgIn1cbiIsCisgICAgICAgICAgICAibmFtZSIsIGluZm8tPmNhcGl0YWxpemVkX25hbWUpOworICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6TEFCRUxfUkVQRUFURUQ6CisgICAgICAgICAgaWYgKElzTWFwRW50cnkoZmllbGQtPm1lc3NhZ2VfdHlwZSgpKSkgeworICAgICAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgICAgICJmb3IgKCR0eXBlJCBpdGVtIDogZ2V0JG5hbWUkKCkudmFsdWVzKCkpIHtcbiIKKyAgICAgICAgICAgICAgIiAgaWYgKCFpdGVtLmlzSW5pdGlhbGl6ZWQoKSkge1xuIgorICAgICAgICAgICAgICAiICAgIGlmIChzaG91bGRNZW1vaXplKSB7XG4iCisgICAgICAgICAgICAgICIgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwO1xuIgorICAgICAgICAgICAgICAiICAgIH1cbiIKKyAgICAgICAgICAgICAgIiAgICByZXR1cm4gbnVsbDtcbiIKKyAgICAgICAgICAgICAgIiAgfVxuIgorICAgICAgICAgICAgICAifVxuIiwKKyAgICAgICAgICAgICAgInR5cGUiLCBNYXBWYWx1ZUltbXV0YWJsZUNsYXNzZE5hbWUoZmllbGQtPm1lc3NhZ2VfdHlwZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lX3Jlc29sdmVyXyksCisgICAgICAgICAgICAgICJuYW1lIiwgaW5mby0+Y2FwaXRhbGl6ZWRfbmFtZSk7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICAgICAiZm9yIChpbnQgaSA9IDA7IGkgPCBnZXQkbmFtZSRDb3VudCgpOyBpKyspIHtcbiIKKyAgICAgICAgICAgICAgIiAgaWYgKCFnZXQkbmFtZSQoaSkuaXNJbml0aWFsaXplZCgpKSB7XG4iCisgICAgICAgICAgICAgICIgICAgaWYgKHNob3VsZE1lbW9pemUpIHtcbiIKKyAgICAgICAgICAgICAgIiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7XG4iCisgICAgICAgICAgICAgICIgICAgfVxuIgorICAgICAgICAgICAgICAiICAgIHJldHVybiBudWxsO1xuIgorICAgICAgICAgICAgICAiICB9XG4iCisgICAgICAgICAgICAgICJ9XG4iLAorICAgICAgICAgICAgICAidHlwZSIsIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoCisgICAgICAgICAgICAgICAgICBmaWVsZC0+bWVzc2FnZV90eXBlKCkpLAorICAgICAgICAgICAgICAibmFtZSIsIGluZm8tPmNhcGl0YWxpemVkX25hbWUpOworICAgICAgICAgIH0KKyAgICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICBpZiAoZGVzY3JpcHRvcl8tPmV4dGVuc2lvbl9yYW5nZV9jb3VudCgpID4gMCkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgImlmICghZXh0ZW5zaW9uc0FyZUluaXRpYWxpemVkKCkpIHtcbiIKKyAgICAgICIgIGlmIChzaG91bGRNZW1vaXplKSB7XG4iCisgICAgICAiICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7XG4iCisgICAgICAiICB9XG4iCisgICAgICAiICByZXR1cm4gbnVsbDtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KAorICAgICJpZiAoc2hvdWxkTWVtb2l6ZSkgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTtcbiIpOworCisgIHByaW50ZXItPlByaW50KAorICAgICJyZXR1cm4gREVGQVVMVF9JTlNUQU5DRTtcbiIKKyAgICAiXG4iKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCit2b2lkIEltbXV0YWJsZU1lc3NhZ2VMaXRlR2VuZXJhdG9yOjpHZW5lcmF0ZUR5bmFtaWNNZXRob2RNYWtlSW1tdXRhYmxlKAorICAgIGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIC8vIE91dHB1dCBnZW5lcmF0aW9uIGNvZGUgZm9yIGVhY2ggZmllbGQuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChkZXNjcmlwdG9yXy0+ZmllbGQoaSkpCisgICAgICAgIC5HZW5lcmF0ZUR5bmFtaWNNZXRob2RNYWtlSW1tdXRhYmxlQ29kZShwcmludGVyKTsKKyAgfQorICBwcmludGVyLT5QcmludCgKKyAgICAicmV0dXJuIG51bGw7XG4iKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCit2b2lkIEltbXV0YWJsZU1lc3NhZ2VMaXRlR2VuZXJhdG9yOjpHZW5lcmF0ZUR5bmFtaWNNZXRob2ROZXdCdWlsZGVyKAorICAgIGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgICJyZXR1cm4gbmV3IEJ1aWxkZXIoKTtcbiIpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK3ZvaWQgSW1tdXRhYmxlTWVzc2FnZUxpdGVHZW5lcmF0b3I6OkdlbmVyYXRlRHluYW1pY01ldGhvZE1lcmdlRnJvbSgKKyAgICBpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICAvLyBPcHRpbWl6YXRpb246ICBJZiBvdGhlciBpcyB0aGUgZGVmYXVsdCBpbnN0YW5jZSwgd2Uga25vdyBub25lIG9mIGl0cworICAgIC8vICAgZmllbGRzIGFyZSBzZXQgc28gd2UgY2FuIHNraXAgdGhlIG1lcmdlLgorICAgICJpZiAoYXJnMCA9PSAkY2xhc3NuYW1lJC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7XG4iCisgICAgIiRjbGFzc25hbWUkIG90aGVyID0gKCRjbGFzc25hbWUkKSBhcmcwO1xuIiwKKyAgICAiY2xhc3NuYW1lIiwgbmFtZV9yZXNvbHZlcl8tPkdldEltbXV0YWJsZUNsYXNzTmFtZShkZXNjcmlwdG9yXykpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGlmICghZGVzY3JpcHRvcl8tPmZpZWxkKGkpLT5jb250YWluaW5nX29uZW9mKCkpIHsKKyAgICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldCgKKyAgICAgICAgICBkZXNjcmlwdG9yXy0+ZmllbGQoaSkpLkdlbmVyYXRlTWVyZ2luZ0NvZGUocHJpbnRlcik7CisgICAgfQorICB9CisKKyAgLy8gTWVyZ2Ugb25lb2YgZmllbGRzLgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsX2NvdW50KCk7ICsraSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgInN3aXRjaCAob3RoZXIuZ2V0JG9uZW9mX2NhcGl0YWxpemVkX25hbWUkQ2FzZSgpKSB7XG4iLAorICAgICAgIm9uZW9mX2NhcGl0YWxpemVkX25hbWUiLAorICAgICAgY29udGV4dF8tPkdldE9uZW9mR2VuZXJhdG9ySW5mbygKKyAgICAgICAgICBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKSktPmNhcGl0YWxpemVkX25hbWUpOworICAgIHByaW50ZXItPkluZGVudCgpOworICAgIGZvciAoaW50IGogPSAwOyBqIDwgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSktPmZpZWxkX2NvdW50KCk7IGorKykgeworICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpLT5maWVsZChqKTsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiY2FzZSAkZmllbGRfbmFtZSQ6IHtcbiIsCisgICAgICAgICJmaWVsZF9uYW1lIiwKKyAgICAgICAgVG9VcHBlcihmaWVsZC0+bmFtZSgpKSk7CisgICAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChmaWVsZCkuR2VuZXJhdGVNZXJnaW5nQ29kZShwcmludGVyKTsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICJicmVhaztcbiIpOworICAgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgIn1cbiIpOworICAgIH0KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJjYXNlICRjYXBfb25lb2ZfbmFtZSRfTk9UX1NFVDoge1xuIgorICAgICAgIiAgYnJlYWs7XG4iCisgICAgICAifVxuIiwKKyAgICAgICJjYXBfb25lb2ZfbmFtZSIsCisgICAgICBUb1VwcGVyKGNvbnRleHRfLT5HZXRPbmVvZkdlbmVyYXRvckluZm8oCisgICAgICAgICAgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSkpLT5uYW1lKSk7CisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIn1cbiIpOworICB9CisKKyAgLy8gaWYgbWVzc2FnZSB0eXBlIGhhcyBleHRlbnNpb25zCisgIGlmIChkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCkgPiAwKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAidGhpcy5tZXJnZUV4dGVuc2lvbkZpZWxkcyhvdGhlcik7XG4iKTsKKyAgfQorCisgIGlmIChQcmVzZXJ2ZVVua25vd25GaWVsZHMoZGVzY3JpcHRvcl8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAidGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIudW5rbm93bkZpZWxkcyk7XG4iKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KAorICAgICJyZXR1cm4gdGhpcztcbiIpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK25hbWVzcGFjZSB7Citib29sIENoZWNrSGFzQml0c0ZvckVxdWFsc0FuZEhhc2hDb2RlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgaWYgKGZpZWxkLT5pc19yZXBlYXRlZCgpKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShmaWVsZC0+ZmlsZSgpKSkgeworICAgIHJldHVybiB0cnVlOworICB9CisgIHJldHVybiBHZXRKYXZhVHlwZShmaWVsZCkgPT0gSkFWQVRZUEVfTUVTU0FHRSAmJgorICAgICAgZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSA9PSBOVUxMOworfQorfSAgLy8gbmFtZXNwYWNlCisKK3ZvaWQgSW1tdXRhYmxlTWVzc2FnZUxpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVFcXVhbHNBbmRIYXNoQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICAiQGphdmEubGFuZy5PdmVycmlkZVxuIgorICAgICJwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHtcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgImlmIChvYmogPT0gdGhpcykge1xuIgorICAgICIgcmV0dXJuIHRydWU7XG4iCisgICAgIn1cbiIKKyAgICAiaWYgKCEob2JqIGluc3RhbmNlb2YgJGNsYXNzbmFtZSQpKSB7XG4iCisgICAgIiAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopO1xuIgorICAgICJ9XG4iCisgICAgIiRjbGFzc25hbWUkIG90aGVyID0gKCRjbGFzc25hbWUkKSBvYmo7XG4iCisgICAgIlxuIiwKKyAgICAiY2xhc3NuYW1lIiwgbmFtZV9yZXNvbHZlcl8tPkdldEltbXV0YWJsZUNsYXNzTmFtZShkZXNjcmlwdG9yXykpOworCisgIHByaW50ZXItPlByaW50KCJib29sZWFuIHJlc3VsdCA9IHRydWU7XG4iKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3JfLT5maWVsZChpKTsKKyAgICBjb25zdCBGaWVsZEdlbmVyYXRvckluZm8qIGluZm8gPSBjb250ZXh0Xy0+R2V0RmllbGRHZW5lcmF0b3JJbmZvKGZpZWxkKTsKKyAgICBib29sIGNoZWNrX2hhc19iaXRzID0gQ2hlY2tIYXNCaXRzRm9yRXF1YWxzQW5kSGFzaENvZGUoZmllbGQpOworICAgIGlmIChjaGVja19oYXNfYml0cykgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJyZXN1bHQgPSByZXN1bHQgJiYgKGhhcyRuYW1lJCgpID09IG90aGVyLmhhcyRuYW1lJCgpKTtcbiIKKyAgICAgICAgImlmIChoYXMkbmFtZSQoKSkge1xuIiwKKyAgICAgICAgIm5hbWUiLCBpbmZvLT5jYXBpdGFsaXplZF9uYW1lKTsKKyAgICAgIHByaW50ZXItPkluZGVudCgpOworICAgIH0KKyAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZmllbGQpLkdlbmVyYXRlRXF1YWxzQ29kZShwcmludGVyKTsKKyAgICBpZiAoY2hlY2tfaGFzX2JpdHMpIHsKKyAgICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAifVxuIik7CisgICAgfQorICB9CisgIGlmIChQcmVzZXJ2ZVVua25vd25GaWVsZHMoZGVzY3JpcHRvcl8pKSB7CisgICAgLy8gQWx3YXlzIGNvbnNpZGVyIHVua25vd24gZmllbGRzIGZvciBlcXVhbGl0eS4gVGhpcyB3aWxsIHNvbWV0aW1lcyByZXR1cm4KKyAgICAvLyBmYWxzZSBmb3Igbm9uLWNhbm9uaWNhbCBvcmRlcmluZyB3aGVuIHJ1bm5pbmcgaW4gTElURV9SVU5USU1FIGJ1dCBpdCdzCisgICAgLy8gdGhlIGJlc3Qgd2UgY2FuIGRvLgorICAgIHByaW50ZXItPlByaW50KAorICAgICAgInJlc3VsdCA9IHJlc3VsdCAmJiB1bmtub3duRmllbGRzLmVxdWFscyhvdGhlci51bmtub3duRmllbGRzKTtcbiIpOworICB9CisgIHByaW50ZXItPlByaW50KAorICAgICJyZXR1cm4gcmVzdWx0O1xuIik7CisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIn1cbiIKKyAgICAiXG4iKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAiQGphdmEubGFuZy5PdmVycmlkZVxuIgorICAgICJwdWJsaWMgaW50IGhhc2hDb2RlKCkge1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAiaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkge1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAicmV0dXJuIG1lbW9pemVkSGFzaENvZGU7XG4iKTsKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAifVxuIgorICAgICJpbnQgaGFzaCA9IDQxO1xuIik7CisKKyAgLy8gSW5jbHVkZSB0aGUgaGFzaCBvZiB0aGUgY2xhc3Mgc28gdGhhdCB0d28gb2JqZWN0cyB3aXRoIGRpZmZlcmVudCB0eXBlcworICAvLyBidXQgdGhlIHNhbWUgZmllbGQgdmFsdWVzIHdpbGwgcHJvYmFibHkgaGF2ZSBkaWZmZXJlbnQgaGFzaGVzLgorICBwcmludGVyLT5QcmludCgiaGFzaCA9ICgxOSAqIGhhc2gpICsgJGNsYXNzbmFtZSQuY2xhc3MuaGFzaENvZGUoKTtcbiIsCisgICAgImNsYXNzbmFtZSIsIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcl8pKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvcl8tPmZpZWxkKGkpOworICAgIGNvbnN0IEZpZWxkR2VuZXJhdG9ySW5mbyogaW5mbyA9IGNvbnRleHRfLT5HZXRGaWVsZEdlbmVyYXRvckluZm8oZmllbGQpOworICAgIGJvb2wgY2hlY2tfaGFzX2JpdHMgPSBDaGVja0hhc0JpdHNGb3JFcXVhbHNBbmRIYXNoQ29kZShmaWVsZCk7CisgICAgaWYgKGNoZWNrX2hhc19iaXRzKSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgImlmIChoYXMkbmFtZSQoKSkge1xuIiwKKyAgICAgICAgIm5hbWUiLCBpbmZvLT5jYXBpdGFsaXplZF9uYW1lKTsKKyAgICAgIHByaW50ZXItPkluZGVudCgpOworICAgIH0KKyAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZmllbGQpLkdlbmVyYXRlSGFzaENvZGUocHJpbnRlcik7CisgICAgaWYgKGNoZWNrX2hhc19iaXRzKSB7CisgICAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgICBwcmludGVyLT5QcmludCgifVxuIik7CisgICAgfQorICB9CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgImhhc2ggPSAoMjkgKiBoYXNoKSArIHVua25vd25GaWVsZHMuaGFzaENvZGUoKTtcbiIpOworICBwcmludGVyLT5QcmludCgKKyAgICAibWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7XG4iCisgICAgInJldHVybiBoYXNoO1xuIik7CisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIn1cbiIKKyAgICAiXG4iKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCit2b2lkIEltbXV0YWJsZU1lc3NhZ2VMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlRXh0ZW5zaW9uUmVnaXN0cmF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5leHRlbnNpb25fY291bnQoKTsgaSsrKSB7CisgICAgSW1tdXRhYmxlRXh0ZW5zaW9uR2VuZXJhdG9yKGRlc2NyaXB0b3JfLT5leHRlbnNpb24oaSksIGNvbnRleHRfKQorICAgICAgLkdlbmVyYXRlUmVnaXN0cmF0aW9uQ29kZShwcmludGVyKTsKKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlX2NvdW50KCk7IGkrKykgeworICAgIEltbXV0YWJsZU1lc3NhZ2VMaXRlR2VuZXJhdG9yKGRlc2NyaXB0b3JfLT5uZXN0ZWRfdHlwZShpKSwgY29udGV4dF8pCisgICAgICAuR2VuZXJhdGVFeHRlbnNpb25SZWdpc3RyYXRpb25Db2RlKHByaW50ZXIpOworICB9Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KK3ZvaWQgSW1tdXRhYmxlTWVzc2FnZUxpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVQYXJzaW5nQ29uc3RydWN0b3IoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX2FycmF5PGNvbnN0IEZpZWxkRGVzY3JpcHRvciAqID4gc29ydGVkX2ZpZWxkcygKKyAgICAgIFNvcnRGaWVsZHNCeU51bWJlcihkZXNjcmlwdG9yXykpOworCisgIHByaW50ZXItPlByaW50KAorICAgICAgInByaXZhdGUgJGNsYXNzbmFtZSQoXG4iCisgICAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCxcbiIKKyAgICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpIHtcbiIsCisgICAgICAiY2xhc3NuYW1lIiwgZGVzY3JpcHRvcl8tPm5hbWUoKSk7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIC8vIEluaXRpYWxpemUgYWxsIGZpZWxkcyB0byBkZWZhdWx0LgorICBHZW5lcmF0ZUluaXRpYWxpemVycyhwcmludGVyKTsKKworICAvLyBVc2UgYnVpbGRlciBiaXRzIHRvIHRyYWNrIG11dGFibGUgcmVwZWF0ZWQgZmllbGRzLgorICBpbnQgdG90YWxCdWlsZGVyQml0cyA9IDA7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IEltbXV0YWJsZUZpZWxkTGl0ZUdlbmVyYXRvciYgZmllbGQgPQorICAgICAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZGVzY3JpcHRvcl8tPmZpZWxkKGkpKTsKKyAgICB0b3RhbEJ1aWxkZXJCaXRzICs9IGZpZWxkLkdldE51bUJpdHNGb3JCdWlsZGVyKCk7CisgIH0KKyAgaW50IHRvdGFsQnVpbGRlckludHMgPSAodG90YWxCdWlsZGVyQml0cyArIDMxKSAvIDMyOworICBmb3IgKGludCBpID0gMDsgaSA8IHRvdGFsQnVpbGRlckludHM7IGkrKykgeworICAgIHByaW50ZXItPlByaW50KCJpbnQgbXV0YWJsZV8kYml0X2ZpZWxkX25hbWUkID0gMDtcbiIsCisgICAgICAiYml0X2ZpZWxkX25hbWUiLCBHZXRCaXRGaWVsZE5hbWUoaSkpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICAidHJ5IHtcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAiYm9vbGVhbiBkb25lID0gZmFsc2U7XG4iCisgICAgIndoaWxlICghZG9uZSkge1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIHByaW50ZXItPlByaW50KAorICAgICJpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpO1xuIgorICAgICJzd2l0Y2ggKHRhZykge1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIHByaW50ZXItPlByaW50KAorICAgICJjYXNlIDA6XG4iICAgICAgICAgIC8vIHplcm8gc2lnbmFscyBFT0YgLyBsaW1pdCByZWFjaGVkCisgICAgIiAgZG9uZSA9IHRydWU7XG4iCisgICAgIiAgYnJlYWs7XG4iKTsKKworICBpZiAoUHJlc2VydmVVbmtub3duRmllbGRzKGRlc2NyaXB0b3JfKSkgeworICAgIGlmIChkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCkgPiAwKSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgImRlZmF1bHQ6IHtcbiIKKyAgICAgICAgIiAgaWYgKCFwYXJzZVVua25vd25GaWVsZChnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCksXG4iCisgICAgICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7XG4iCisgICAgICAgICIgICAgZG9uZSA9IHRydWU7XG4iICAvLyBpdCdzIGFuIGVuZGdyb3VwIHRhZworICAgICAgICAiICB9XG4iCisgICAgICAgICIgIGJyZWFrO1xuIgorICAgICAgICAifVxuIik7CisgICAgfSBlbHNlIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiZGVmYXVsdDoge1xuIgorICAgICAgICAiICBpZiAoIXBhcnNlVW5rbm93bkZpZWxkKHRhZywgaW5wdXQpKSB7XG4iCisgICAgICAgICIgICAgZG9uZSA9IHRydWU7XG4iICAvLyBpdCdzIGFuIGVuZGdyb3VwIHRhZworICAgICAgICAiICB9XG4iCisgICAgICAgICIgIGJyZWFrO1xuIgorICAgICAgICAifVxuIik7CisgICAgfQorICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgImRlZmF1bHQ6IHtcbiIKKyAgICAgICIgIGlmICghaW5wdXQuc2tpcEZpZWxkKHRhZykpIHtcbiIKKyAgICAgICIgICAgZG9uZSA9IHRydWU7XG4iICAvLyBpdCdzIGFuIGVuZGdyb3VwIHRhZworICAgICAgIiAgfVxuIgorICAgICAgIiAgYnJlYWs7XG4iCisgICAgICAifVxuIik7CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gc29ydGVkX2ZpZWxkc1tpXTsKKyAgICB1aW50MzIgdGFnID0gV2lyZUZvcm1hdExpdGU6Ok1ha2VUYWcoZmllbGQtPm51bWJlcigpLAorICAgICAgV2lyZUZvcm1hdDo6V2lyZVR5cGVGb3JGaWVsZFR5cGUoZmllbGQtPnR5cGUoKSkpOworCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiY2FzZSAkdGFnJDoge1xuIiwKKyAgICAgICJ0YWciLCBTaW1wbGVJdG9hKHRhZykpOworICAgIHByaW50ZXItPkluZGVudCgpOworCisgICAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGZpZWxkKS5HZW5lcmF0ZVBhcnNpbmdDb2RlKHByaW50ZXIpOworCisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIiAgYnJlYWs7XG4iCisgICAgICAifVxuIik7CisKKyAgICBpZiAoZmllbGQtPmlzX3BhY2thYmxlKCkpIHsKKyAgICAgIC8vIFRvIG1ha2UgcGFja2VkID0gdHJ1ZSB3aXJlIGNvbXBhdGlibGUsIHdlIGdlbmVyYXRlIHBhcnNpbmcgY29kZSBmcm9tIGEKKyAgICAgIC8vIHBhY2tlZCB2ZXJzaW9uIG9mIHRoaXMgZmllbGQgcmVnYXJkbGVzcyBvZiBmaWVsZC0+b3B0aW9ucygpLnBhY2tlZCgpLgorICAgICAgdWludDMyIHBhY2tlZF90YWcgPSBXaXJlRm9ybWF0TGl0ZTo6TWFrZVRhZyhmaWVsZC0+bnVtYmVyKCksCisgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVEKTsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiY2FzZSAkdGFnJDoge1xuIiwKKyAgICAgICAgInRhZyIsIFNpbXBsZUl0b2EocGFja2VkX3RhZykpOworICAgICAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChmaWVsZCkuR2VuZXJhdGVQYXJzaW5nQ29kZUZyb21QYWNrZWQocHJpbnRlcik7CisKKyAgICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiICBicmVhaztcbiIKKyAgICAgICAgIn1cbiIpOworICAgIH0KKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAgICIgIH1cbiIgICAgIC8vIHN3aXRjaCAodGFnKQorICAgICAgIn1cbiIpOyAgICAgLy8gd2hpbGUgKCFkb25lKQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICAifSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkge1xuIgorICAgICAgIiAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZS5zZXRVbmZpbmlzaGVkTWVzc2FnZSh0aGlzKSk7XG4iCisgICAgICAifSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7XG4iCisgICAgICAiICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihcbiIKKyAgICAgICIgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oXG4iCisgICAgICAiICAgICAgICAgIGUuZ2V0TWVzc2FnZSgpKS5zZXRVbmZpbmlzaGVkTWVzc2FnZSh0aGlzKSk7XG4iCisgICAgICAifSBmaW5hbGx5IHtcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICAvLyBNYWtlIHJlcGVhdGVkIGZpZWxkIGxpc3QgaW1tdXRhYmxlLgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gc29ydGVkX2ZpZWxkc1tpXTsKKyAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZmllbGQpLkdlbmVyYXRlUGFyc2luZ0RvbmVDb2RlKHByaW50ZXIpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiZG9uZVBhcnNpbmcoKTtcbiIpOworCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAgICIgIH1cbiIgICAgIC8vIGZpbmFsbHkKKyAgICAgICJ9XG4iKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQordm9pZCBJbW11dGFibGVNZXNzYWdlTGl0ZUdlbmVyYXRvcjo6R2VuZXJhdGVQYXJzZXIoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICAicHJpdmF0ZSBzdGF0aWMgdm9sYXRpbGUgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8JGNsYXNzbmFtZSQ+IFBBUlNFUjtcbiIKKyAgICAgICJcbiIKKyAgICAgICJwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPCRjbGFzc25hbWUkPiBwYXJzZXIoKSB7XG4iCisgICAgICAiICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS5nZXRQYXJzZXJGb3JUeXBlKCk7XG4iCisgICAgICAifVxuIiwKKyAgICAgICJjbGFzc25hbWUiLCBkZXNjcmlwdG9yXy0+bmFtZSgpKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQordm9pZCBJbW11dGFibGVNZXNzYWdlTGl0ZUdlbmVyYXRvcjo6R2VuZXJhdGVJbml0aWFsaXplcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgaWYgKCFkZXNjcmlwdG9yXy0+ZmllbGQoaSktPmNvbnRhaW5pbmdfb25lb2YoKSkgeworICAgICAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGRlc2NyaXB0b3JfLT5maWVsZChpKSkKKyAgICAgICAgICAuR2VuZXJhdGVJbml0aWFsaXphdGlvbkNvZGUocHJpbnRlcik7CisgICAgfQorICB9Cit9CisKKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tZXNzYWdlX2xpdGUuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX21lc3NhZ2VfbGl0ZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJiZDNjZGQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tZXNzYWdlX2xpdGUuaApAQCAtMCwwICsxLDkxIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBkd2Vpc0Bnb29nbGUuY29tIChEYW5pZWwgV2VpcykKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX01FU1NBR0VfTElURV9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfTUVTU0FHRV9MSVRFX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPG1hcD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9tZXNzYWdlLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YSB7CisKK2NsYXNzIEltbXV0YWJsZU1lc3NhZ2VMaXRlR2VuZXJhdG9yIDogcHVibGljIE1lc3NhZ2VHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgSW1tdXRhYmxlTWVzc2FnZUxpdGVHZW5lcmF0b3IoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb250ZXh0KiBjb250ZXh0KTsKKyAgdmlydHVhbCB+SW1tdXRhYmxlTWVzc2FnZUxpdGVHZW5lcmF0b3IoKTsKKworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGUoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVJbnRlcmZhY2UoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVFeHRlbnNpb25SZWdpc3RyYXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlU3RhdGljVmFyaWFibGVzKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdmlydHVhbCBpbnQgR2VuZXJhdGVTdGF0aWNWYXJpYWJsZUluaXRpYWxpemVycyhpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyBwcml2YXRlOgorCisgIHZvaWQgR2VuZXJhdGVNZXNzYWdlU2VyaWFsaXphdGlvbk1ldGhvZHMoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2b2lkIEdlbmVyYXRlUGFyc2VGcm9tTWV0aG9kcyhpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVPbmVGaWVsZChpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpOworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXplT25lRXh0ZW5zaW9uUmFuZ2UoCisgICAgICBpbzo6UHJpbnRlciogcHJpbnRlciwgY29uc3QgRGVzY3JpcHRvcjo6RXh0ZW5zaW9uUmFuZ2UqIHJhbmdlKTsKKworICB2b2lkIEdlbmVyYXRlQnVpbGRlcihpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZvaWQgR2VuZXJhdGVEeW5hbWljTWV0aG9kSXNJbml0aWFsaXplZChpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZvaWQgR2VuZXJhdGVEeW5hbWljTWV0aG9kTWFrZUltbXV0YWJsZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZvaWQgR2VuZXJhdGVEeW5hbWljTWV0aG9kTWVyZ2VGcm9tKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdm9pZCBHZW5lcmF0ZUR5bmFtaWNNZXRob2ROZXdCdWlsZGVyKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdm9pZCBHZW5lcmF0ZUluaXRpYWxpemVycyhpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZvaWQgR2VuZXJhdGVFcXVhbHNBbmRIYXNoQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZvaWQgR2VuZXJhdGVQYXJzZXIoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2b2lkIEdlbmVyYXRlUGFyc2luZ0NvbnN0cnVjdG9yKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworICBDb250ZXh0KiBjb250ZXh0XzsKKyAgQ2xhc3NOYW1lUmVzb2x2ZXIqIG5hbWVfcmVzb2x2ZXJfOworICBGaWVsZEdlbmVyYXRvck1hcDxJbW11dGFibGVGaWVsZExpdGVHZW5lcmF0b3I+IGZpZWxkX2dlbmVyYXRvcnNfOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhJbW11dGFibGVNZXNzYWdlTGl0ZUdlbmVyYXRvcik7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgamF2YQorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9NRVNTQUdFX0xJVEVfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9uYW1lX3Jlc29sdmVyLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbmFtZV9yZXNvbHZlci5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wYzM2M2Y5Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbmFtZV9yZXNvbHZlci5jYwpAQCAtMCwwICsxLDI2NiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX25hbWVfcmVzb2x2ZXIuaD4KKworI2luY2x1ZGUgPG1hcD4KKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3Vic3RpdHV0ZS5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmEgeworCituYW1lc3BhY2UgeworLy8gQSBzdWZmaXggdGhhdCB3aWxsIGJlIGFwcGVuZGVkIHRvIHRoZSBmaWxlJ3Mgb3V0ZXIgY2xhc3MgbmFtZSBpZiB0aGUgbmFtZQorLy8gY29uZmxpY3RzIHdpdGggc29tZSBvdGhlciB0eXBlcyBkZWZpbmVkIGluIHRoZSBmaWxlLgorY29uc3QgY2hhcioga091dGVyQ2xhc3NOYW1lU3VmZml4ID0gIk91dGVyQ2xhc3MiOworCisvLyBTdHJpcCBwYWNrYWdlIG5hbWUgZnJvbSBhIGRlc2NyaXB0b3IncyBmdWxsIG5hbWUuCisvLyBGb3IgZXhhbXBsZToKKy8vICAgRnVsbCBuYW1lICAgOiBmb28uQmFyLkJhegorLy8gICBQYWNrYWdlIG5hbWU6IGZvbworLy8gICBBZnRlciBzdHJpcCA6IEJhci5CYXoKK3N0cmluZyBTdHJpcFBhY2thZ2VOYW1lKGNvbnN0IHN0cmluZyYgZnVsbF9uYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUpIHsKKyAgaWYgKGZpbGUtPnBhY2thZ2UoKS5lbXB0eSgpKSB7CisgICAgcmV0dXJuIGZ1bGxfbmFtZTsKKyAgfSBlbHNlIHsKKyAgICAvLyBTdHJpcCBwYWNrYWdlIG5hbWUKKyAgICByZXR1cm4gZnVsbF9uYW1lLnN1YnN0cihmaWxlLT5wYWNrYWdlKCkuc2l6ZSgpICsgMSk7CisgIH0KK30KKworLy8gR2V0IHRoZSBuYW1lIG9mIGEgbWVzc2FnZSdzIEphdmEgY2xhc3Mgd2l0aG91dCBwYWNrYWdlIG5hbWUgcHJlZml4Lgorc3RyaW5nIENsYXNzTmFtZVdpdGhvdXRQYWNrYWdlKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpbW11dGFibGUpIHsKKyAgcmV0dXJuIFN0cmlwUGFja2FnZU5hbWUoZGVzY3JpcHRvci0+ZnVsbF9uYW1lKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0b3ItPmZpbGUoKSk7Cit9CisKKy8vIEdldCB0aGUgbmFtZSBvZiBhbiBlbnVtJ3MgSmF2YSBjbGFzcyB3aXRob3V0IHBhY2thZ2UgbmFtZSBwcmVmaXguCitzdHJpbmcgQ2xhc3NOYW1lV2l0aG91dFBhY2thZ2UoY29uc3QgRW51bURlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpbW11dGFibGUpIHsKKyAgLy8gRG9lc24ndCBhcHBlbmQgIk11dGFibGUiIGZvciBlbnVtIHR5cGUncyBuYW1lLgorICBjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlX2Rlc2NyaXB0b3IgPSBkZXNjcmlwdG9yLT5jb250YWluaW5nX3R5cGUoKTsKKyAgaWYgKG1lc3NhZ2VfZGVzY3JpcHRvciA9PSBOVUxMKSB7CisgICAgcmV0dXJuIGRlc2NyaXB0b3ItPm5hbWUoKTsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gQ2xhc3NOYW1lV2l0aG91dFBhY2thZ2UobWVzc2FnZV9kZXNjcmlwdG9yLCBpbW11dGFibGUpICsKKyAgICAgICAgICAgIi4iICsgZGVzY3JpcHRvci0+bmFtZSgpOworICB9Cit9CisKKy8vIEdldCB0aGUgbmFtZSBvZiBhIHNlcnZpY2UncyBKYXZhIGNsYXNzIHdpdGhvdXQgcGFja2FnZSBuYW1lIHByZWZpeC4KK3N0cmluZyBDbGFzc05hbWVXaXRob3V0UGFja2FnZShjb25zdCBTZXJ2aWNlRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGltbXV0YWJsZSkgeworICBzdHJpbmcgZnVsbF9uYW1lID0gU3RyaXBQYWNrYWdlTmFtZShkZXNjcmlwdG9yLT5mdWxsX25hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRvci0+ZmlsZSgpKTsKKyAgLy8gV2UgZG9uJ3QgYWxsb3cgbmVzdGVkIHNlcnZpY2UgZGVmaW5pdGlvbnMuCisgIEdPT0dMRV9DSEVDSyhmdWxsX25hbWUuZmluZCgnLicpID09IHN0cmluZzo6bnBvcyk7CisgIHJldHVybiBmdWxsX25hbWU7Cit9CisKKy8vIENoZWNrIHdoZXRoZXIgYSBnaXZlbiBtZXNzYWdlIG9yIGl0cyBuZXN0ZWQgdHlwZXMgaGFzIHRoZSBnaXZlbiBjbGFzcyBuYW1lLgorYm9vbCBNZXNzYWdlSGFzQ29uZmxpY3RpbmdDbGFzc05hbWUoY29uc3QgRGVzY3JpcHRvciogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgY2xhc3NuYW1lKSB7CisgIGlmIChtZXNzYWdlLT5uYW1lKCkgPT0gY2xhc3NuYW1lKSByZXR1cm4gdHJ1ZTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZXNzYWdlLT5uZXN0ZWRfdHlwZV9jb3VudCgpOyArK2kpIHsKKyAgICBpZiAoTWVzc2FnZUhhc0NvbmZsaWN0aW5nQ2xhc3NOYW1lKG1lc3NhZ2UtPm5lc3RlZF90eXBlKGkpLCBjbGFzc25hbWUpKSB7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZXNzYWdlLT5lbnVtX3R5cGVfY291bnQoKTsgKytpKSB7CisgICAgaWYgKG1lc3NhZ2UtPmVudW1fdHlwZShpKS0+bmFtZSgpID09IGNsYXNzbmFtZSkgeworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICB9CisgIHJldHVybiBmYWxzZTsKK30KKworfSAgLy8gbmFtZXNwYWNlCisKK0NsYXNzTmFtZVJlc29sdmVyOjpDbGFzc05hbWVSZXNvbHZlcigpIHsKK30KKworQ2xhc3NOYW1lUmVzb2x2ZXI6On5DbGFzc05hbWVSZXNvbHZlcigpIHsKK30KKworc3RyaW5nIENsYXNzTmFtZVJlc29sdmVyOjpHZXRGaWxlRGVmYXVsdEltbXV0YWJsZUNsYXNzTmFtZSgKKyAgICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSkgeworICBzdHJpbmcgYmFzZW5hbWU7CisgIHN0cmluZzo6c2l6ZV90eXBlIGxhc3Rfc2xhc2ggPSBmaWxlLT5uYW1lKCkuZmluZF9sYXN0X29mKCcvJyk7CisgIGlmIChsYXN0X3NsYXNoID09IHN0cmluZzo6bnBvcykgeworICAgIGJhc2VuYW1lID0gZmlsZS0+bmFtZSgpOworICB9IGVsc2UgeworICAgIGJhc2VuYW1lID0gZmlsZS0+bmFtZSgpLnN1YnN0cihsYXN0X3NsYXNoICsgMSk7CisgIH0KKyAgcmV0dXJuIFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoU3RyaXBQcm90byhiYXNlbmFtZSksIHRydWUpOworfQorCitzdHJpbmcgQ2xhc3NOYW1lUmVzb2x2ZXI6OkdldEZpbGVJbW11dGFibGVDbGFzc05hbWUoCisgICAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUpIHsKKyAgc3RyaW5nJiBjbGFzc19uYW1lID0gZmlsZV9pbW11dGFibGVfb3V0ZXJfY2xhc3NfbmFtZXNfW2ZpbGVdOworICBpZiAoY2xhc3NfbmFtZS5lbXB0eSgpKSB7CisgICAgaWYgKGZpbGUtPm9wdGlvbnMoKS5oYXNfamF2YV9vdXRlcl9jbGFzc25hbWUoKSkgeworICAgICAgY2xhc3NfbmFtZSA9IGZpbGUtPm9wdGlvbnMoKS5qYXZhX291dGVyX2NsYXNzbmFtZSgpOworICAgIH0gZWxzZSB7CisgICAgICBjbGFzc19uYW1lID0gR2V0RmlsZURlZmF1bHRJbW11dGFibGVDbGFzc05hbWUoZmlsZSk7CisgICAgICBpZiAoSGFzQ29uZmxpY3RpbmdDbGFzc05hbWUoZmlsZSwgY2xhc3NfbmFtZSkpIHsKKyAgICAgICAgY2xhc3NfbmFtZSArPSBrT3V0ZXJDbGFzc05hbWVTdWZmaXg7CisgICAgICB9CisgICAgfQorICB9CisgIHJldHVybiBjbGFzc19uYW1lOworfQorCitzdHJpbmcgQ2xhc3NOYW1lUmVzb2x2ZXI6OkdldEZpbGVDbGFzc05hbWUoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpbW11dGFibGUpIHsKKyAgaWYgKGltbXV0YWJsZSkgeworICAgIHJldHVybiBHZXRGaWxlSW1tdXRhYmxlQ2xhc3NOYW1lKGZpbGUpOworICB9IGVsc2UgeworICAgIHJldHVybiAiTXV0YWJsZSIgKyBHZXRGaWxlSW1tdXRhYmxlQ2xhc3NOYW1lKGZpbGUpOworICB9Cit9CisKKy8vIENoZWNrIHdoZXRoZXIgdGhlcmUgaXMgYW55IHR5cGUgZGVmaW5lZCBpbiB0aGUgcHJvdG8gZmlsZSB0aGF0IGhhcworLy8gdGhlIGdpdmVuIGNsYXNzIG5hbWUuCitib29sIENsYXNzTmFtZVJlc29sdmVyOjpIYXNDb25mbGljdGluZ0NsYXNzTmFtZSgKKyAgICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSwgY29uc3Qgc3RyaW5nJiBjbGFzc25hbWUpIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlLT5lbnVtX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgaWYgKGZpbGUtPmVudW1fdHlwZShpKS0+bmFtZSgpID09IGNsYXNzbmFtZSkgeworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZS0+c2VydmljZV9jb3VudCgpOyBpKyspIHsKKyAgICBpZiAoZmlsZS0+c2VydmljZShpKS0+bmFtZSgpID09IGNsYXNzbmFtZSkgeworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZS0+bWVzc2FnZV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIGlmIChNZXNzYWdlSGFzQ29uZmxpY3RpbmdDbGFzc05hbWUoZmlsZS0+bWVzc2FnZV90eXBlKGkpLCBjbGFzc25hbWUpKSB7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIGZhbHNlOworfQorCitzdHJpbmcgQ2xhc3NOYW1lUmVzb2x2ZXI6OkdldERlc2NyaXB0b3JDbGFzc05hbWUoCisgICAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgcmV0dXJuIEdldEZpbGVJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcik7Cit9CisKK3N0cmluZyBDbGFzc05hbWVSZXNvbHZlcjo6R2V0Q2xhc3NOYW1lKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpbW11dGFibGUpIHsKKyAgc3RyaW5nIHJlc3VsdCA9IEZpbGVKYXZhUGFja2FnZShkZXNjcmlwdG9yLCBpbW11dGFibGUpOworICBpZiAoIXJlc3VsdC5lbXB0eSgpKSByZXN1bHQgKz0gJy4nOworICByZXN1bHQgKz0gR2V0RmlsZUNsYXNzTmFtZShkZXNjcmlwdG9yLCBpbW11dGFibGUpOworICByZXR1cm4gcmVzdWx0OworfQorCisvLyBHZXQgdGhlIGZ1bGwgbmFtZSBvZiBhIEphdmEgY2xhc3MgYnkgcHJlcGVuZGluZyB0aGUgSmF2YSBwYWNrYWdlIG5hbWUKKy8vIG9yIG91dGVyIGNsYXNzIG5hbWUuCitzdHJpbmcgQ2xhc3NOYW1lUmVzb2x2ZXI6OkdldENsYXNzRnVsbE5hbWUoY29uc3Qgc3RyaW5nJiBuYW1lX3dpdGhvdXRfcGFja2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGltbXV0YWJsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIG11bHRpcGxlX2ZpbGVzKSB7CisgIHN0cmluZyByZXN1bHQ7CisgIGlmIChtdWx0aXBsZV9maWxlcykgeworICAgIHJlc3VsdCA9IEZpbGVKYXZhUGFja2FnZShmaWxlLCBpbW11dGFibGUpOworICB9IGVsc2UgeworICAgIHJlc3VsdCA9IEdldENsYXNzTmFtZShmaWxlLCBpbW11dGFibGUpOworICB9CisgIGlmICghcmVzdWx0LmVtcHR5KCkpIHsKKyAgICByZXN1bHQgKz0gJy4nOworICB9CisgIHJlc3VsdCArPSBuYW1lX3dpdGhvdXRfcGFja2FnZTsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RyaW5nIENsYXNzTmFtZVJlc29sdmVyOjpHZXRDbGFzc05hbWUoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaW1tdXRhYmxlKSB7CisgIHJldHVybiBHZXRDbGFzc0Z1bGxOYW1lKENsYXNzTmFtZVdpdGhvdXRQYWNrYWdlKGRlc2NyaXB0b3IsIGltbXV0YWJsZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0b3ItPmZpbGUoKSwgaW1tdXRhYmxlLAorICAgICAgICAgICAgICAgICAgICAgICAgICBNdWx0aXBsZUphdmFGaWxlcyhkZXNjcmlwdG9yLT5maWxlKCksIGltbXV0YWJsZSkpOworfQorCitzdHJpbmcgQ2xhc3NOYW1lUmVzb2x2ZXI6OkdldENsYXNzTmFtZShjb25zdCBFbnVtRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaW1tdXRhYmxlKSB7CisgIHJldHVybiBHZXRDbGFzc0Z1bGxOYW1lKENsYXNzTmFtZVdpdGhvdXRQYWNrYWdlKGRlc2NyaXB0b3IsIGltbXV0YWJsZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0b3ItPmZpbGUoKSwgaW1tdXRhYmxlLAorICAgICAgICAgICAgICAgICAgICAgICAgICBNdWx0aXBsZUphdmFGaWxlcyhkZXNjcmlwdG9yLT5maWxlKCksIGltbXV0YWJsZSkpOworfQorCitzdHJpbmcgQ2xhc3NOYW1lUmVzb2x2ZXI6OkdldENsYXNzTmFtZShjb25zdCBTZXJ2aWNlRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaW1tdXRhYmxlKSB7CisgIHJldHVybiBHZXRDbGFzc0Z1bGxOYW1lKENsYXNzTmFtZVdpdGhvdXRQYWNrYWdlKGRlc2NyaXB0b3IsIGltbXV0YWJsZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0b3ItPmZpbGUoKSwgaW1tdXRhYmxlLAorICAgICAgICAgICAgICAgICAgICAgICAgICBNdWx0aXBsZUphdmFGaWxlcyhkZXNjcmlwdG9yLT5maWxlKCksIGltbXV0YWJsZSkpOworfQorCisvLyBHZXQgdGhlIEphdmEgQ2xhc3Mgc3R5bGUgZnVsbCBuYW1lIG9mIGEgbWVzc2FnZS4KK3N0cmluZyBDbGFzc05hbWVSZXNvbHZlcjo6R2V0SmF2YUNsYXNzRnVsbE5hbWUoCisgICAgY29uc3Qgc3RyaW5nJiBuYW1lX3dpdGhvdXRfcGFja2FnZSwKKyAgICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSwKKyAgICBib29sIGltbXV0YWJsZSkgeworICBzdHJpbmcgcmVzdWx0OworICBpZiAoTXVsdGlwbGVKYXZhRmlsZXMoZmlsZSwgaW1tdXRhYmxlKSkgeworICAgIHJlc3VsdCA9IEZpbGVKYXZhUGFja2FnZShmaWxlLCBpbW11dGFibGUpOworICAgIGlmICghcmVzdWx0LmVtcHR5KCkpIHJlc3VsdCArPSAnLic7CisgIH0gZWxzZSB7CisgICAgcmVzdWx0ID0gR2V0Q2xhc3NOYW1lKGZpbGUsIGltbXV0YWJsZSk7CisgICAgaWYgKCFyZXN1bHQuZW1wdHkoKSkgcmVzdWx0ICs9ICckJzsKKyAgfQorICByZXN1bHQgKz0gU3RyaW5nUmVwbGFjZShuYW1lX3dpdGhvdXRfcGFja2FnZSwgIi4iLCAiJCIsIHRydWUpOworICByZXR1cm4gcmVzdWx0OworfQorCitzdHJpbmcgQ2xhc3NOYW1lUmVzb2x2ZXI6OkdldEV4dGVuc2lvbklkZW50aWZpZXJOYW1lKAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwgYm9vbCBpbW11dGFibGUpIHsKKyAgcmV0dXJuIEdldENsYXNzTmFtZShkZXNjcmlwdG9yLT5jb250YWluaW5nX3R5cGUoKSwgaW1tdXRhYmxlKSArICIuIiArCisgICAgICAgICBkZXNjcmlwdG9yLT5uYW1lKCk7Cit9CisKKworc3RyaW5nIENsYXNzTmFtZVJlc29sdmVyOjpHZXRKYXZhSW1tdXRhYmxlQ2xhc3NOYW1lKAorICAgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgcmV0dXJuIEdldEphdmFDbGFzc0Z1bGxOYW1lKAorICAgICAgQ2xhc3NOYW1lV2l0aG91dFBhY2thZ2UoZGVzY3JpcHRvciwgdHJ1ZSksCisgICAgICBkZXNjcmlwdG9yLT5maWxlKCksIHRydWUpOworfQorCisKK30gIC8vIG5hbWVzcGFjZSBqYXZhCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbmFtZV9yZXNvbHZlci5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbmFtZV9yZXNvbHZlci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFiNjBiMGEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9uYW1lX3Jlc29sdmVyLmgKQEAgLTAsMCArMSwxMjQgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX05BTUVfUkVTT0xWRVJfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX05BTUVfUkVTT0xWRVJfSF9fCisKKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8c3RyaW5nPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CitjbGFzcyBEZXNjcmlwdG9yOworY2xhc3MgRW51bURlc2NyaXB0b3I7CitjbGFzcyBGaWVsZERlc2NyaXB0b3I7CitjbGFzcyBGaWxlRGVzY3JpcHRvcjsKK2NsYXNzIFNlcnZpY2VEZXNjcmlwdG9yOworCituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmEgeworCisvLyBVc2VkIHRvIGdldCB0aGUgSmF2YSBjbGFzcyByZWxhdGVkIG5hbWVzIGZvciBhIGdpdmVuIGRlc2NyaXB0b3IuIEl0IGNhY2hlcworLy8gdGhlIHJlc3VsdHMgdG8gYXZvaWQgcmVkdW5kYW50IGNhbGN1bGF0aW9uIGFjcm9zcyBtdWx0aXBsZSBuYW1lIHF1ZXJpZXMuCisvLyBUaHJlYWQtc2FmZXR5IG5vdGU6IFRoaXMgY2xhc3MgaXMgKm5vdCogdGhyZWFkLXNhZmUuCitjbGFzcyBDbGFzc05hbWVSZXNvbHZlciB7CisgcHVibGljOgorICBDbGFzc05hbWVSZXNvbHZlcigpOworICB+Q2xhc3NOYW1lUmVzb2x2ZXIoKTsKKworICAvLyBHZXRzIHRoZSB1bnF1YWxpZmllZCBvdXRlciBjbGFzcyBuYW1lIGZvciB0aGUgZmlsZS4KKyAgc3RyaW5nIEdldEZpbGVDbGFzc05hbWUoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUsIGJvb2wgaW1tdXRhYmxlKTsKKyAgLy8gR2V0cyB0aGUgdW5xdWFsaWZpZWQgaW1tdXRhYmxlIG91dGVyIGNsYXNzIG5hbWUgb2YgYSBmaWxlLgorICBzdHJpbmcgR2V0RmlsZUltbXV0YWJsZUNsYXNzTmFtZShjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSk7CisgIC8vIEdldHMgdGhlIHVucXVhbGlmaWVkIGRlZmF1bHQgaW1tdXRhYmxlIG91dGVyIGNsYXNzIG5hbWUgb2YgYSBmaWxlCisgIC8vIChjb252ZXJ0ZWQgZnJvbSB0aGUgcHJvdG8gZmlsZSdzIG5hbWUpLgorICBzdHJpbmcgR2V0RmlsZURlZmF1bHRJbW11dGFibGVDbGFzc05hbWUoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUpOworCisgIC8vIENoZWNrIHdoZXRoZXIgdGhlcmUgaXMgYW55IHR5cGUgZGVmaW5lZCBpbiB0aGUgcHJvdG8gZmlsZSB0aGF0IGhhcworICAvLyB0aGUgZ2l2ZW4gY2xhc3MgbmFtZS4KKyAgYm9vbCBIYXNDb25mbGljdGluZ0NsYXNzTmFtZShjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIGNsYXNzbmFtZSk7CisKKyAgLy8gR2V0cyB0aGUgbmFtZSBvZiB0aGUgb3V0ZXIgY2xhc3MgdGhhdCBob2xkcyBkZXNjcmlwdG9yIGluZm9ybWF0aW9uLgorICAvLyBEZXNjcmlwdG9ycyBhcmUgc2hhcmVkIGJldHdlZW4gaW1tdXRhYmxlIG1lc3NhZ2VzIGFuZCBtdXRhYmxlIG1lc3NhZ2VzLgorICAvLyBTaW5jZSBib3RoIG9mIHRoZW0gYXJlIGdlbmVyYXRlZCBvcHRpb25hbGx5LCB0aGUgZGVzY3JpcHRvcnMgbmVlZCB0byBiZQorICAvLyBwdXQgaW4gYW5vdGhlciBjb21tb24gcGxhY2UuCisgIHN0cmluZyBHZXREZXNjcmlwdG9yQ2xhc3NOYW1lKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKTsKKworICAvLyBHZXRzIHRoZSBmdWxseS1xdWFsaWZpZWQgY2xhc3MgbmFtZSBjb3JyZXNwb25kaW5nIHRvIHRoZSBnaXZlbiBkZXNjcmlwdG9yLgorICBzdHJpbmcgR2V0Q2xhc3NOYW1lKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGJvb2wgaW1tdXRhYmxlKTsKKyAgc3RyaW5nIEdldENsYXNzTmFtZShjb25zdCBFbnVtRGVzY3JpcHRvciogZGVzY3JpcHRvciwgYm9vbCBpbW11dGFibGUpOworICBzdHJpbmcgR2V0Q2xhc3NOYW1lKGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBib29sIGltbXV0YWJsZSk7CisgIHN0cmluZyBHZXRDbGFzc05hbWUoY29uc3QgRmlsZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGJvb2wgaW1tdXRhYmxlKTsKKworICB0ZW1wbGF0ZTxjbGFzcyBEZXNjcmlwdG9yVHlwZT4KKyAgc3RyaW5nIEdldEltbXV0YWJsZUNsYXNzTmFtZShjb25zdCBEZXNjcmlwdG9yVHlwZSogZGVzY3JpcHRvcikgeworICAgIHJldHVybiBHZXRDbGFzc05hbWUoZGVzY3JpcHRvciwgdHJ1ZSk7CisgIH0KKyAgdGVtcGxhdGU8Y2xhc3MgRGVzY3JpcHRvclR5cGU+CisgIHN0cmluZyBHZXRNdXRhYmxlQ2xhc3NOYW1lKGNvbnN0IERlc2NyaXB0b3JUeXBlKiBkZXNjcmlwdG9yKSB7CisgICAgcmV0dXJuIEdldENsYXNzTmFtZShkZXNjcmlwdG9yLCBmYWxzZSk7CisgIH0KKworICAvLyBHZXRzIHRoZSBmdWxseSBxdWFsaWZpZWQgbmFtZSBvZiBhbiBleHRlbnNpb24gaWRlbnRpZmllci4KKyAgc3RyaW5nIEdldEV4dGVuc2lvbklkZW50aWZpZXJOYW1lKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaW1tdXRhYmxlKTsKKworICAvLyBHZXRzIHRoZSBmdWxseSBxdWFsaWZpZWQgbmFtZSBmb3IgZ2VuZXJhdGVkIGNsYXNzZXMgaW4gSmF2YSBjb252ZW50aW9uLgorICAvLyBOZXN0ZWQgY2xhc3NlcyB3aWxsIGJlIHNlcGFyYXRlZCB1c2luZyAnJCcgaW5zdGVhZCBvZiAnLicKKyAgLy8gRm9yIGV4YW1wbGU6CisgIC8vICAgY29tLnBhY2thZ2UuT3V0ZXJDbGFzcyRPdXRlck1lc3NhZ2UkSW5uZXJNZXNzYWdlCisgIHN0cmluZyBHZXRKYXZhSW1tdXRhYmxlQ2xhc3NOYW1lKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworIHByaXZhdGU6CisgIC8vIEdldCB0aGUgZnVsbCBuYW1lIG9mIGEgSmF2YSBjbGFzcyBieSBwcmVwZW5kaW5nIHRoZSBKYXZhIHBhY2thZ2UgbmFtZQorICAvLyBvciBvdXRlciBjbGFzcyBuYW1lLgorICBzdHJpbmcgR2V0Q2xhc3NGdWxsTmFtZShjb25zdCBzdHJpbmcmIG5hbWVfd2l0aG91dF9wYWNrYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpbW11dGFibGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgbXVsdGlwbGVfZmlsZXMpOworICAvLyBHZXQgdGhlIEphdmEgQ2xhc3Mgc3R5bGUgZnVsbCBuYW1lIG9mIGEgbWVzc2FnZS4KKyAgc3RyaW5nIEdldEphdmFDbGFzc0Z1bGxOYW1lKAorICAgICAgY29uc3Qgc3RyaW5nJiBuYW1lX3dpdGhvdXRfcGFja2FnZSwKKyAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlLAorICAgICAgYm9vbCBpbW11dGFibGUpOworICAvLyBDYWNoZXMgdGhlIHJlc3VsdCB0byBwcm92aWRlIGJldHRlciBwZXJmb3JtYW5jZS4KKyAgbWFwPGNvbnN0IEZpbGVEZXNjcmlwdG9yKiwgc3RyaW5nPiBmaWxlX2ltbXV0YWJsZV9vdXRlcl9jbGFzc19uYW1lc187CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKENsYXNzTmFtZVJlc29sdmVyKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX05BTUVfUkVTT0xWRVJfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9uYW1lcy5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbmFtZXMuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wZDYxNDMzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbmFtZXMuaApAQCAtMCwwICsxLDg3IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisvLworLy8gUHJvdmlkZXMgYSBtZWNoYW5pc20gZm9yIG1hcHBpbmcgYSBkZXNjcmlwdG9yIHRvIHRoZQorLy8gZnVsbHktcXVhbGlmaWVkIG5hbWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgSmF2YSBjbGFzcy4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9OQU1FU19IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfTkFNRVNfSF9fCisKKyNpbmNsdWRlIDxzdHJpbmc+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworY2xhc3MgRGVzY3JpcHRvcjsKK2NsYXNzIEVudW1EZXNjcmlwdG9yOworY2xhc3MgRmlsZURlc2NyaXB0b3I7CitjbGFzcyBTZXJ2aWNlRGVzY3JpcHRvcjsKKworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhIHsKKworLy8gUmVxdWlyZXM6CisvLyAgIGRlc2NyaXB0b3IgIT0gTlVMTAorLy8KKy8vIFJldHVybnM6CisvLyAgIFRoZSBmdWxseS1xdWFsaWZpZWQgSmF2YSBjbGFzcyBuYW1lLgorc3RyaW5nIENsYXNzTmFtZShjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKKworLy8gUmVxdWlyZXM6CisvLyAgIGRlc2NyaXB0b3IgIT0gTlVMTAorLy8KKy8vIFJldHVybnM6CisvLyAgIFRoZSBmdWxseS1xdWFsaWZpZWQgSmF2YSBjbGFzcyBuYW1lLgorc3RyaW5nIENsYXNzTmFtZShjb25zdCBFbnVtRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CisKKy8vIFJlcXVpcmVzOgorLy8gICBkZXNjcmlwdG9yICE9IE5VTEwKKy8vCisvLyBSZXR1cm5zOgorLy8gICBUaGUgZnVsbHktcXVhbGlmaWVkIEphdmEgY2xhc3MgbmFtZS4KK3N0cmluZyBDbGFzc05hbWUoY29uc3QgRmlsZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworCisvLyBSZXF1aXJlczoKKy8vICAgZGVzY3JpcHRvciAhPSBOVUxMCisvLworLy8gUmV0dXJuczoKKy8vICAgVGhlIGZ1bGx5LXF1YWxpZmllZCBKYXZhIGNsYXNzIG5hbWUuCitzdHJpbmcgQ2xhc3NOYW1lKGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfTkFNRVNfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9wbHVnaW5fdW5pdHRlc3QuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9wbHVnaW5fdW5pdHRlc3QuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmU1Mjc2MgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX3BsdWdpbl91bml0dGVzdC5jYwpAQCAtMCwwICsxLDEyNyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vCisvLyBUT0RPKGtlbnRvbik6ICBTaGFyZSBjb2RlIHdpdGggdGhlIHZlcnNpb25zIG9mIHRoaXMgdGVzdCBpbiBvdGhlciBsYW5ndWFnZXM/CisvLyAgIEl0IHNlZW1lZCBsaWtlIHBhcmFtZXRlcml6aW5nIGl0IHdvdWxkIGFkZCBtb3JlIGNvbXBsZXhpdHkgdGhhbiBpdCBpcworLy8gICB3b3J0aC4KKworI2luY2x1ZGUgPG1lbW9yeT4KKyNpZm5kZWYgX1NIQVJFRF9QVFJfSAorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaGFyZWRfcHRyLmg+CisjZW5kaWYKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZ2VuZXJhdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvbW1hbmRfbGluZV9pbnRlcmZhY2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0Lmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9maWxlLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YSB7CituYW1lc3BhY2UgeworCitjbGFzcyBUZXN0R2VuZXJhdG9yIDogcHVibGljIENvZGVHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgVGVzdEdlbmVyYXRvcigpIHt9CisgIH5UZXN0R2VuZXJhdG9yKCkge30KKworICB2aXJ0dWFsIGJvb2wgR2VuZXJhdGUoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHBhcmFtZXRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgIEdlbmVyYXRvckNvbnRleHQqIGNvbnRleHQsCisgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcqIGVycm9yKSBjb25zdCB7CisgICAgc3RyaW5nIGZpbGVuYW1lID0gIlRlc3QuamF2YSI7CisgICAgVHJ5SW5zZXJ0KGZpbGVuYW1lLCAib3V0ZXJfY2xhc3Nfc2NvcGUiLCBjb250ZXh0KTsKKyAgICBUcnlJbnNlcnQoZmlsZW5hbWUsICJjbGFzc19zY29wZTpmb28uQmFyIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KGZpbGVuYW1lLCAiY2xhc3Nfc2NvcGU6Zm9vLkJhci5CYXoiLCBjb250ZXh0KTsKKyAgICBUcnlJbnNlcnQoZmlsZW5hbWUsICJidWlsZGVyX3Njb3BlOmZvby5CYXIiLCBjb250ZXh0KTsKKyAgICBUcnlJbnNlcnQoZmlsZW5hbWUsICJidWlsZGVyX3Njb3BlOmZvby5CYXIuQmF6IiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KGZpbGVuYW1lLCAiZW51bV9zY29wZTpmb28uUXV4IiwgY29udGV4dCk7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICB2b2lkIFRyeUluc2VydChjb25zdCBzdHJpbmcmIGZpbGVuYW1lLCBjb25zdCBzdHJpbmcmIGluc2VydGlvbl9wb2ludCwKKyAgICAgICAgICAgICAgICAgR2VuZXJhdG9yQ29udGV4dCogY29udGV4dCkgY29uc3QgeworICAgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8aW86Olplcm9Db3B5T3V0cHV0U3RyZWFtPiBvdXRwdXQoCisgICAgICAgIGNvbnRleHQtPk9wZW5Gb3JJbnNlcnQoZmlsZW5hbWUsIGluc2VydGlvbl9wb2ludCkpOworICAgIGlvOjpQcmludGVyIHByaW50ZXIob3V0cHV0LmdldCgpLCAnJCcpOworICAgIHByaW50ZXIuUHJpbnQoIi8vIGluc2VydGVkICRuYW1lJFxuIiwgIm5hbWUiLCBpbnNlcnRpb25fcG9pbnQpOworICB9Cit9OworCisvLyBUaGlzIHRlc3QgdmVyaWZpZXMgdGhhdCBhbGwgdGhlIGV4cGVjdGVkIGluc2VydGlvbiBwb2ludHMgZXhpc3QuICBJdCBkb2VzCisvLyBub3QgdmVyaWZ5IHRoYXQgdGhleSBhcmUgY29ycmVjdGx5LXBsYWNlZDsgdGhhdCB3b3VsZCByZXF1aXJlIGFjdHVhbGx5CisvLyBjb21waWxpbmcgdGhlIG91dHB1dCB3aGljaCBpcyBhIGJpdCBtb3JlIHRoYW4gSSBjYXJlIHRvIGRvIGZvciB0aGlzIHRlc3QuCitURVNUKEphdmFQbHVnaW5UZXN0LCBQbHVnaW5UZXN0KSB7CisgIEdPT0dMRV9DSEVDS19PSyhGaWxlOjpTZXRDb250ZW50cyhUZXN0VGVtcERpcigpICsgIi90ZXN0LnByb3RvIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwYWNrYWdlIGZvbztcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm9wdGlvbiBqYXZhX3BhY2thZ2UgPSBcIlwiO1xuIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib3B0aW9uIGphdmFfb3V0ZXJfY2xhc3NuYW1lID0gXCJUZXN0XCI7XG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJtZXNzYWdlIEJhciB7XG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgIG1lc3NhZ2UgQmF6IHt9XG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ9XG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJlbnVtIFF1eCB7IEJMQUggPSAxOyB9XG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlKSk7CisKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6Y29tcGlsZXI6OkNvbW1hbmRMaW5lSW50ZXJmYWNlIGNsaTsKKyAgY2xpLlNldElucHV0c0FyZVByb3RvUGF0aFJlbGF0aXZlKHRydWUpOworCisgIEphdmFHZW5lcmF0b3IgamF2YV9nZW5lcmF0b3I7CisgIFRlc3RHZW5lcmF0b3IgdGVzdF9nZW5lcmF0b3I7CisgIGNsaS5SZWdpc3RlckdlbmVyYXRvcigiLS1qYXZhX291dCIsICZqYXZhX2dlbmVyYXRvciwgIiIpOworICBjbGkuUmVnaXN0ZXJHZW5lcmF0b3IoIi0tdGVzdF9vdXQiLCAmdGVzdF9nZW5lcmF0b3IsICIiKTsKKworICBzdHJpbmcgcHJvdG9fcGF0aCA9ICItSSIgKyBUZXN0VGVtcERpcigpOworICBzdHJpbmcgamF2YV9vdXQgPSAiLS1qYXZhX291dD0iICsgVGVzdFRlbXBEaXIoKTsKKyAgc3RyaW5nIHRlc3Rfb3V0ID0gIi0tdGVzdF9vdXQ9IiArIFRlc3RUZW1wRGlyKCk7CisKKyAgY29uc3QgY2hhciogYXJndltdID0geworICAgICJwcm90b2MiLAorICAgIHByb3RvX3BhdGguY19zdHIoKSwKKyAgICBqYXZhX291dC5jX3N0cigpLAorICAgIHRlc3Rfb3V0LmNfc3RyKCksCisgICAgInRlc3QucHJvdG8iCisgIH07CisKKyAgRVhQRUNUX0VRKDAsIGNsaS5SdW4oNSwgYXJndikpOworfQorCit9ICAvLyBuYW1lc3BhY2UKK30gIC8vIG5hbWVzcGFjZSBqYXZhCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfcHJpbWl0aXZlX2ZpZWxkLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfcHJpbWl0aXZlX2ZpZWxkLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE3OGJiZTEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9wcmltaXRpdmVfZmllbGQuY2MKQEAgLTAsMCArMSw4NjYgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2luY2x1ZGUgPG1hcD4KKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbG9nZ2luZy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2NvbnRleHQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2RvY19jb21tZW50Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9uYW1lX3Jlc29sdmVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9wcmltaXRpdmVfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YSB7CisKK3VzaW5nIGludGVybmFsOjpXaXJlRm9ybWF0OwordXNpbmcgaW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOworCituYW1lc3BhY2UgeworCit2b2lkIFNldFByaW1pdGl2ZVZhcmlhYmxlcyhjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkR2VuZXJhdG9ySW5mbyogaW5mbywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzTmFtZVJlc29sdmVyKiBuYW1lX3Jlc29sdmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwPHN0cmluZywgc3RyaW5nPiogdmFyaWFibGVzKSB7CisgIFNldENvbW1vbkZpZWxkVmFyaWFibGVzKGRlc2NyaXB0b3IsIGluZm8sIHZhcmlhYmxlcyk7CisKKyAgKCp2YXJpYWJsZXMpWyJ0eXBlIl0gPSBQcmltaXRpdmVUeXBlTmFtZShHZXRKYXZhVHlwZShkZXNjcmlwdG9yKSk7CisgICgqdmFyaWFibGVzKVsiYm94ZWRfdHlwZSJdID0gQm94ZWRQcmltaXRpdmVUeXBlTmFtZShHZXRKYXZhVHlwZShkZXNjcmlwdG9yKSk7CisgICgqdmFyaWFibGVzKVsiZmllbGRfdHlwZSJdID0gKCp2YXJpYWJsZXMpWyJ0eXBlIl07CisgICgqdmFyaWFibGVzKVsiZmllbGRfbGlzdF90eXBlIl0gPSAiamF2YS51dGlsLkxpc3Q8IiArCisgICAgICAoKnZhcmlhYmxlcylbImJveGVkX3R5cGUiXSArICI+IjsKKyAgKCp2YXJpYWJsZXMpWyJlbXB0eV9saXN0Il0gPSAiamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpIjsKKyAgKCp2YXJpYWJsZXMpWyJkZWZhdWx0Il0gPSBJbW11dGFibGVEZWZhdWx0VmFsdWUoZGVzY3JpcHRvciwgbmFtZV9yZXNvbHZlcik7CisgICgqdmFyaWFibGVzKVsiZGVmYXVsdF9pbml0Il0gPSBJc0RlZmF1bHRWYWx1ZUphdmFEZWZhdWx0KGRlc2NyaXB0b3IpID8KKyAgICAgICIiIDogKCI9ICIgKyBJbW11dGFibGVEZWZhdWx0VmFsdWUoZGVzY3JpcHRvciwgbmFtZV9yZXNvbHZlcikpOworICAoKnZhcmlhYmxlcylbImNhcGl0YWxpemVkX3R5cGUiXSA9CisgICAgICBHZXRDYXBpdGFsaXplZFR5cGUoZGVzY3JpcHRvciwgLyogaW1tdXRhYmxlID0gKi8gdHJ1ZSk7CisgIGlmIChkZXNjcmlwdG9yLT5pc19wYWNrZWQoKSkgeworICAgICgqdmFyaWFibGVzKVsidGFnIl0gPSBTaW1wbGVJdG9hKFdpcmVGb3JtYXRMaXRlOjpNYWtlVGFnKAorICAgICAgICBkZXNjcmlwdG9yLT5udW1iZXIoKSwgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQpKTsKKyAgfSBlbHNlIHsKKyAgICAoKnZhcmlhYmxlcylbInRhZyJdID0gU2ltcGxlSXRvYShXaXJlRm9ybWF0OjpNYWtlVGFnKGRlc2NyaXB0b3IpKTsKKyAgfQorICAoKnZhcmlhYmxlcylbInRhZ19zaXplIl0gPSBTaW1wbGVJdG9hKAorICAgICAgV2lyZUZvcm1hdDo6VGFnU2l6ZShkZXNjcmlwdG9yLT5udW1iZXIoKSwgR2V0VHlwZShkZXNjcmlwdG9yKSkpOworICBpZiAoSXNSZWZlcmVuY2VUeXBlKEdldEphdmFUeXBlKGRlc2NyaXB0b3IpKSkgeworICAgICgqdmFyaWFibGVzKVsibnVsbF9jaGVjayJdID0KKyAgICAgICAgIiAgaWYgKHZhbHVlID09IG51bGwpIHtcbiIKKyAgICAgICAgIiAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTtcbiIKKyAgICAgICAgIiAgfVxuIjsKKyAgfSBlbHNlIHsKKyAgICAoKnZhcmlhYmxlcylbIm51bGxfY2hlY2siXSA9ICIiOworICB9CisgIC8vIFRPRE8oYmlyZG8pOiBBZGQgQGRlcHJlY2F0ZWQgamF2YWRvYyB3aGVuIGdlbmVyYXRpbmcgamF2YWRvYyBpcyBzdXBwb3J0ZWQKKyAgLy8gYnkgdGhlIHByb3RvIGNvbXBpbGVyCisgICgqdmFyaWFibGVzKVsiZGVwcmVjYXRpb24iXSA9IGRlc2NyaXB0b3ItPm9wdGlvbnMoKS5kZXByZWNhdGVkKCkKKyAgICAgID8gIkBqYXZhLmxhbmcuRGVwcmVjYXRlZCAiIDogIiI7CisgIGludCBmaXhlZF9zaXplID0gRml4ZWRTaXplKEdldFR5cGUoZGVzY3JpcHRvcikpOworICBpZiAoZml4ZWRfc2l6ZSAhPSAtMSkgeworICAgICgqdmFyaWFibGVzKVsiZml4ZWRfc2l6ZSJdID0gU2ltcGxlSXRvYShmaXhlZF9zaXplKTsKKyAgfQorICAoKnZhcmlhYmxlcylbIm9uX2NoYW5nZWQiXSA9CisgICAgICBIYXNEZXNjcmlwdG9yTWV0aG9kcyhkZXNjcmlwdG9yLT5jb250YWluaW5nX3R5cGUoKSkgPyAib25DaGFuZ2VkKCk7IiA6ICIiOworCisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yLT5maWxlKCkpKSB7CisgICAgLy8gRm9yIHNpbmd1bGFyIG1lc3NhZ2VzIGFuZCBidWlsZGVycywgb25lIGJpdCBpcyB1c2VkIGZvciB0aGUgaGFzRmllbGQgYml0LgorICAgICgqdmFyaWFibGVzKVsiZ2V0X2hhc19maWVsZF9iaXRfbWVzc2FnZSJdID0gR2VuZXJhdGVHZXRCaXQobWVzc2FnZUJpdEluZGV4KTsKKyAgICAoKnZhcmlhYmxlcylbImdldF9oYXNfZmllbGRfYml0X2J1aWxkZXIiXSA9IEdlbmVyYXRlR2V0Qml0KGJ1aWxkZXJCaXRJbmRleCk7CisKKyAgICAvLyBOb3RlIHRoYXQgdGhlc2UgaGF2ZSBhIHRyYWlsaW5nICI7Ii4KKyAgICAoKnZhcmlhYmxlcylbInNldF9oYXNfZmllbGRfYml0X21lc3NhZ2UiXSA9CisgICAgICAgIEdlbmVyYXRlU2V0Qml0KG1lc3NhZ2VCaXRJbmRleCkgKyAiOyI7CisgICAgKCp2YXJpYWJsZXMpWyJzZXRfaGFzX2ZpZWxkX2JpdF9idWlsZGVyIl0gPQorICAgICAgICBHZW5lcmF0ZVNldEJpdChidWlsZGVyQml0SW5kZXgpICsgIjsiOworICAgICgqdmFyaWFibGVzKVsiY2xlYXJfaGFzX2ZpZWxkX2JpdF9idWlsZGVyIl0gPQorICAgICAgICBHZW5lcmF0ZUNsZWFyQml0KGJ1aWxkZXJCaXRJbmRleCkgKyAiOyI7CisKKyAgICAoKnZhcmlhYmxlcylbImlzX2ZpZWxkX3ByZXNlbnRfbWVzc2FnZSJdID0gR2VuZXJhdGVHZXRCaXQobWVzc2FnZUJpdEluZGV4KTsKKyAgfSBlbHNlIHsKKyAgICAoKnZhcmlhYmxlcylbInNldF9oYXNfZmllbGRfYml0X21lc3NhZ2UiXSA9ICIiOworICAgICgqdmFyaWFibGVzKVsic2V0X2hhc19maWVsZF9iaXRfYnVpbGRlciJdID0gIiI7CisgICAgKCp2YXJpYWJsZXMpWyJjbGVhcl9oYXNfZmllbGRfYml0X2J1aWxkZXIiXSA9ICIiOworCisgICAgaWYgKGRlc2NyaXB0b3ItPnR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfQllURVMpIHsKKyAgICAgICgqdmFyaWFibGVzKVsiaXNfZmllbGRfcHJlc2VudF9tZXNzYWdlIl0gPQorICAgICAgICAgICIhIiArICgqdmFyaWFibGVzKVsibmFtZSJdICsgIl8uaXNFbXB0eSgpIjsKKyAgICB9IGVsc2UgeworICAgICAgKCp2YXJpYWJsZXMpWyJpc19maWVsZF9wcmVzZW50X21lc3NhZ2UiXSA9CisgICAgICAgICAgKCp2YXJpYWJsZXMpWyJuYW1lIl0gKyAiXyAhPSAiICsgKCp2YXJpYWJsZXMpWyJkZWZhdWx0Il07CisgICAgfQorICB9CisKKyAgLy8gRm9yIHJlcGF0ZWQgYnVpbGRlcnMsIG9uZSBiaXQgaXMgdXNlZCBmb3Igd2hldGhlciB0aGUgYXJyYXkgaXMgaW1tdXRhYmxlLgorICAoKnZhcmlhYmxlcylbImdldF9tdXRhYmxlX2JpdF9idWlsZGVyIl0gPSBHZW5lcmF0ZUdldEJpdChidWlsZGVyQml0SW5kZXgpOworICAoKnZhcmlhYmxlcylbInNldF9tdXRhYmxlX2JpdF9idWlsZGVyIl0gPSBHZW5lcmF0ZVNldEJpdChidWlsZGVyQml0SW5kZXgpOworICAoKnZhcmlhYmxlcylbImNsZWFyX211dGFibGVfYml0X2J1aWxkZXIiXSA9IEdlbmVyYXRlQ2xlYXJCaXQoYnVpbGRlckJpdEluZGV4KTsKKworICAvLyBGb3IgcmVwZWF0ZWQgZmllbGRzLCBvbmUgYml0IGlzIHVzZWQgZm9yIHdoZXRoZXIgdGhlIGFycmF5IGlzIGltbXV0YWJsZQorICAvLyBpbiB0aGUgcGFyc2luZyBjb25zdHJ1Y3Rvci4KKyAgKCp2YXJpYWJsZXMpWyJnZXRfbXV0YWJsZV9iaXRfcGFyc2VyIl0gPQorICAgICAgR2VuZXJhdGVHZXRCaXRNdXRhYmxlTG9jYWwoYnVpbGRlckJpdEluZGV4KTsKKyAgKCp2YXJpYWJsZXMpWyJzZXRfbXV0YWJsZV9iaXRfcGFyc2VyIl0gPQorICAgICAgR2VuZXJhdGVTZXRCaXRNdXRhYmxlTG9jYWwoYnVpbGRlckJpdEluZGV4KTsKKworICAoKnZhcmlhYmxlcylbImdldF9oYXNfZmllbGRfYml0X2Zyb21fbG9jYWwiXSA9CisgICAgICBHZW5lcmF0ZUdldEJpdEZyb21Mb2NhbChidWlsZGVyQml0SW5kZXgpOworICAoKnZhcmlhYmxlcylbInNldF9oYXNfZmllbGRfYml0X3RvX2xvY2FsIl0gPQorICAgICAgR2VuZXJhdGVTZXRCaXRUb0xvY2FsKG1lc3NhZ2VCaXRJbmRleCk7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK0ltbXV0YWJsZVByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0ltbXV0YWJsZVByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBtZXNzYWdlQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYnVpbGRlckJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29udGV4dCogY29udGV4dCkKKyAgOiBkZXNjcmlwdG9yXyhkZXNjcmlwdG9yKSwgbWVzc2FnZUJpdEluZGV4XyhtZXNzYWdlQml0SW5kZXgpLAorICAgIGJ1aWxkZXJCaXRJbmRleF8oYnVpbGRlckJpdEluZGV4KSwgY29udGV4dF8oY29udGV4dCksCisgICAgbmFtZV9yZXNvbHZlcl8oY29udGV4dC0+R2V0TmFtZVJlc29sdmVyKCkpIHsKKyAgU2V0UHJpbWl0aXZlVmFyaWFibGVzKGRlc2NyaXB0b3IsIG1lc3NhZ2VCaXRJbmRleCwgYnVpbGRlckJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dC0+R2V0RmllbGRHZW5lcmF0b3JJbmZvKGRlc2NyaXB0b3IpLAorICAgICAgICAgICAgICAgICAgICAgICAgbmFtZV9yZXNvbHZlcl8sICZ2YXJpYWJsZXNfKTsKK30KKworSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6On5JbW11dGFibGVQcmltaXRpdmVGaWVsZEdlbmVyYXRvcigpIHt9CisKK2ludCBJbW11dGFibGVQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6R2V0TnVtQml0c0Zvck1lc3NhZ2UoKSBjb25zdCB7CisgIHJldHVybiAxOworfQorCitpbnQgSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OkdldE51bUJpdHNGb3JCdWlsZGVyKCkgY29uc3QgeworICByZXR1cm4gMTsKK30KKwordm9pZCBJbW11dGFibGVQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUludGVyZmFjZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKFN1cHBvcnRGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJGRlcHJlY2F0aW9uJGJvb2xlYW4gaGFzJGNhcGl0YWxpemVkX25hbWUkKCk7XG4iKTsKKyAgfQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiQkdHlwZSQgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCk7XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHJpdmF0ZSAkZmllbGRfdHlwZSQgJG5hbWUkXztcbiIpOworICBQcmludEV4dHJhRmllbGRJbmZvKHZhcmlhYmxlc18sIHByaW50ZXIpOworICBpZiAoU3VwcG9ydEZpZWxkUHJlc2VuY2UoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljIGJvb2xlYW4gaGFzJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICAgIiAgcmV0dXJuICRnZXRfaGFzX2ZpZWxkX2JpdF9tZXNzYWdlJDtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSQgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgIHJldHVybiAkbmFtZSRfO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUJ1aWxkZXJNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgJGZpZWxkX3R5cGUkICRuYW1lJF8gJGRlZmF1bHRfaW5pdCQ7XG4iKTsKKworICBpZiAoU3VwcG9ydEZpZWxkUHJlc2VuY2UoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljIGJvb2xlYW4gaGFzJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICAgIiAgcmV0dXJuICRnZXRfaGFzX2ZpZWxkX2JpdF9idWlsZGVyJDtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSQgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgIHJldHVybiAkbmFtZSRfO1xuIgorICAgICJ9XG4iKTsKKworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBzZXQkY2FwaXRhbGl6ZWRfbmFtZSQoJHR5cGUkIHZhbHVlKSB7XG4iCisgICAgIiRudWxsX2NoZWNrJCIKKyAgICAiICAkc2V0X2hhc19maWVsZF9iaXRfYnVpbGRlciRcbiIKKyAgICAiICAkbmFtZSRfID0gdmFsdWU7XG4iCisgICAgIiAgJG9uX2NoYW5nZWQkXG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGNsZWFyJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgICRjbGVhcl9oYXNfZmllbGRfYml0X2J1aWxkZXIkXG4iKTsKKyAgSmF2YVR5cGUgdHlwZSA9IEdldEphdmFUeXBlKGRlc2NyaXB0b3JfKTsKKyAgaWYgKHR5cGUgPT0gSkFWQVRZUEVfU1RSSU5HIHx8IHR5cGUgPT0gSkFWQVRZUEVfQllURVMpIHsKKyAgICAvLyBUaGUgZGVmYXVsdCB2YWx1ZSBpcyBub3QgYSBzaW1wbGUgbGl0ZXJhbCBzbyB3ZSB3YW50IHRvIGF2b2lkIGV4ZWN1dGluZworICAgIC8vIGl0IG11bHRpcGxlIHRpbWVzLiAgSW5zdGVhZCwgZ2V0IHRoZSBkZWZhdWx0IG91dCBvZiB0aGUgZGVmYXVsdCBpbnN0YW5jZS4KKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiAgJG5hbWUkXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldCRjYXBpdGFsaXplZF9uYW1lJCgpO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIgICRuYW1lJF8gPSAkZGVmYXVsdCQ7XG4iKTsKKyAgfQorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIgICRvbl9jaGFuZ2VkJFxuIgorICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUZpZWxkQnVpbGRlckluaXRpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgIGNvbnN0IHsKKyAgLy8gbm9vcCBmb3IgcHJpbWl0aXZlcworfQorCit2b2lkIEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlSW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sICIkbmFtZSRfID0gJGRlZmF1bHQkO1xuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVCdWlsZGVyQ2xlYXJDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRuYW1lJF8gPSAkZGVmYXVsdCQ7XG4iCisgICAgIiRjbGVhcl9oYXNfZmllbGRfYml0X2J1aWxkZXIkXG4iKTsKK30KKwordm9pZCBJbW11dGFibGVQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaWYgKG90aGVyLmhhcyRjYXBpdGFsaXplZF9uYW1lJCgpKSB7XG4iCisgICAgICAiICBzZXQkY2FwaXRhbGl6ZWRfbmFtZSQob3RoZXIuZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkpO1xuIgorICAgICAgIn1cbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaWYgKG90aGVyLmdldCRjYXBpdGFsaXplZF9uYW1lJCgpICE9ICRkZWZhdWx0JCkge1xuIgorICAgICAgIiAgc2V0JGNhcGl0YWxpemVkX25hbWUkKG90aGVyLmdldCRjYXBpdGFsaXplZF9uYW1lJCgpKTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorfQorCit2b2lkIEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaWYgKCRnZXRfaGFzX2ZpZWxkX2JpdF9mcm9tX2xvY2FsJCkge1xuIgorICAgICAgIiAgJHNldF9oYXNfZmllbGRfYml0X3RvX2xvY2FsJDtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJyZXN1bHQuJG5hbWUkXyA9ICRuYW1lJF87XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVBhcnNpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRzZXRfaGFzX2ZpZWxkX2JpdF9tZXNzYWdlJFxuIgorICAgICIkbmFtZSRfID0gaW5wdXQucmVhZCRjYXBpdGFsaXplZF90eXBlJCgpO1xuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVQYXJzaW5nRG9uZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gbm9vcCBmb3IgcHJpbWl0aXZlcy4KK30KKwordm9pZCBJbW11dGFibGVQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkaXNfZmllbGRfcHJlc2VudF9tZXNzYWdlJCkge1xuIgorICAgICIgIG91dHB1dC53cml0ZSRjYXBpdGFsaXplZF90eXBlJCgkbnVtYmVyJCwgJG5hbWUkXyk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkaXNfZmllbGRfcHJlc2VudF9tZXNzYWdlJCkge1xuIgorICAgICIgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbVxuIgorICAgICIgICAgLmNvbXB1dGUkY2FwaXRhbGl6ZWRfdHlwZSRTaXplKCRudW1iZXIkLCAkbmFtZSRfKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVFcXVhbHNDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHN3aXRjaCAoR2V0SmF2YVR5cGUoZGVzY3JpcHRvcl8pKSB7CisgICAgY2FzZSBKQVZBVFlQRV9JTlQ6CisgICAgY2FzZSBKQVZBVFlQRV9MT05HOgorICAgIGNhc2UgSkFWQVRZUEVfQk9PTEVBTjoKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICJyZXN1bHQgPSByZXN1bHQgJiYgKGdldCRjYXBpdGFsaXplZF9uYW1lJCgpXG4iCisgICAgICAgICIgICAgPT0gb3RoZXIuZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkpO1xuIik7CisgICAgICBicmVhazsKKworICAgIGNhc2UgSkFWQVRZUEVfRkxPQVQ6CisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAicmVzdWx0ID0gcmVzdWx0ICYmIChcbiIKKyAgICAgICAgIiAgICBqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkpXG4iCisgICAgICAgICIgICAgPT0gamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKFxuIgorICAgICAgICAiICAgICAgICBvdGhlci5nZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSkpO1xuIik7CisgICAgICBicmVhazsKKworICAgIGNhc2UgSkFWQVRZUEVfRE9VQkxFOgorICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgInJlc3VsdCA9IHJlc3VsdCAmJiAoXG4iCisgICAgICAgICIgICAgamF2YS5sYW5nLkRvdWJsZS5kb3VibGVUb0xvbmdCaXRzKGdldCRjYXBpdGFsaXplZF9uYW1lJCgpKVxuIgorICAgICAgICAiICAgID09IGphdmEubGFuZy5Eb3VibGUuZG91YmxlVG9Mb25nQml0cyhcbiIKKyAgICAgICAgIiAgICAgICAgb3RoZXIuZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkpKTtcbiIpOworICAgICAgYnJlYWs7CisKKyAgICBjYXNlIEpBVkFUWVBFX1NUUklORzoKKyAgICBjYXNlIEpBVkFUWVBFX0JZVEVTOgorICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgInJlc3VsdCA9IHJlc3VsdCAmJiBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKVxuIgorICAgICAgICAiICAgIC5lcXVhbHMob3RoZXIuZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkpO1xuIik7CisgICAgICBicmVhazsKKworICAgIGNhc2UgSkFWQVRZUEVfRU5VTToKKyAgICBjYXNlIEpBVkFUWVBFX01FU1NBR0U6CisgICAgZGVmYXVsdDoKKyAgICAgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJDYW4ndCBnZXQgaGVyZS4iOworICAgICAgYnJlYWs7CisgIH0KK30KKwordm9pZCBJbW11dGFibGVQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUhhc2hDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImhhc2ggPSAoMzcgKiBoYXNoKSArICRjb25zdGFudF9uYW1lJDtcbiIpOworICBzd2l0Y2ggKEdldEphdmFUeXBlKGRlc2NyaXB0b3JfKSkgeworICAgIGNhc2UgSkFWQVRZUEVfSU5UOgorICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgImhhc2ggPSAoNTMgKiBoYXNoKSArIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpO1xuIik7CisgICAgICBicmVhazsKKworICAgIGNhc2UgSkFWQVRZUEVfTE9ORzoKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICJoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKFxuIgorICAgICAgICAiICAgIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpKTtcbiIpOworICAgICAgYnJlYWs7CisKKyAgICBjYXNlIEpBVkFUWVBFX0JPT0xFQU46CisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAiaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoQm9vbGVhbihcbiIKKyAgICAgICAgIiAgICBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSk7XG4iKTsKKyAgICAgIGJyZWFrOworCisgICAgY2FzZSBKQVZBVFlQRV9GTE9BVDoKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICJoYXNoID0gKDUzICogaGFzaCkgKyBqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoXG4iCisgICAgICAgICIgICAgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkpO1xuIik7CisgICAgICBicmVhazsKKworICAgIGNhc2UgSkFWQVRZUEVfRE9VQkxFOgorICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgImhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoXG4iCisgICAgICAgICIgICAgamF2YS5sYW5nLkRvdWJsZS5kb3VibGVUb0xvbmdCaXRzKGdldCRjYXBpdGFsaXplZF9uYW1lJCgpKSk7XG4iKTsKKyAgICAgIGJyZWFrOworCisgICAgY2FzZSBKQVZBVFlQRV9TVFJJTkc6CisgICAgY2FzZSBKQVZBVFlQRV9CWVRFUzoKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICJoYXNoID0gKDUzICogaGFzaCkgKyBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKS5oYXNoQ29kZSgpO1xuIik7CisgICAgICBicmVhazsKKworICAgIGNhc2UgSkFWQVRZUEVfRU5VTToKKyAgICBjYXNlIEpBVkFUWVBFX01FU1NBR0U6CisgICAgZGVmYXVsdDoKKyAgICAgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJDYW4ndCBnZXQgaGVyZS4iOworICAgICAgYnJlYWs7CisgIH0KK30KKworc3RyaW5nIEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjpHZXRCb3hlZFR5cGUoKSBjb25zdCB7CisgIHJldHVybiBCb3hlZFByaW1pdGl2ZVR5cGVOYW1lKEdldEphdmFUeXBlKGRlc2NyaXB0b3JfKSk7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworSW1tdXRhYmxlUHJpbWl0aXZlT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitJbW11dGFibGVQcmltaXRpdmVPbmVvZkZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBtZXNzYWdlQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYnVpbGRlckJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29udGV4dCogY29udGV4dCkKKyAgICA6IEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKAorICAgICAgICAgIGRlc2NyaXB0b3IsIG1lc3NhZ2VCaXRJbmRleCwgYnVpbGRlckJpdEluZGV4LCBjb250ZXh0KSB7CisgIGNvbnN0IE9uZW9mR2VuZXJhdG9ySW5mbyogaW5mbyA9CisgICAgICBjb250ZXh0LT5HZXRPbmVvZkdlbmVyYXRvckluZm8oZGVzY3JpcHRvci0+Y29udGFpbmluZ19vbmVvZigpKTsKKyAgU2V0Q29tbW9uT25lb2ZWYXJpYWJsZXMoZGVzY3JpcHRvciwgaW5mbywgJnZhcmlhYmxlc18pOworfQorCitJbW11dGFibGVQcmltaXRpdmVPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK35JbW11dGFibGVQcmltaXRpdmVPbmVvZkZpZWxkR2VuZXJhdG9yKCkge30KKwordm9pZCBJbW11dGFibGVQcmltaXRpdmVPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBQcmludEV4dHJhRmllbGRJbmZvKHZhcmlhYmxlc18sIHByaW50ZXIpOworICBpZiAoU3VwcG9ydEZpZWxkUHJlc2VuY2UoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljIGJvb2xlYW4gaGFzJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICAgIiAgcmV0dXJuICRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJDtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSQgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgIGlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIKKyAgICAiICAgIHJldHVybiAoJGJveGVkX3R5cGUkKSAkb25lb2ZfbmFtZSRfO1xuIgorICAgICIgIH1cbiIKKyAgICAiICByZXR1cm4gJGRlZmF1bHQkO1xuIgorICAgICJ9XG4iKTsKK30KKworCit2b2lkIEltbXV0YWJsZVByaW1pdGl2ZU9uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoU3VwcG9ydEZpZWxkUHJlc2VuY2UoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljIGJvb2xlYW4gaGFzJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICAgIiAgcmV0dXJuICRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJDtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSQgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgIGlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIKKyAgICAiICAgIHJldHVybiAoJGJveGVkX3R5cGUkKSAkb25lb2ZfbmFtZSRfO1xuIgorICAgICIgIH1cbiIKKyAgICAiICByZXR1cm4gJGRlZmF1bHQkO1xuIgorICAgICJ9XG4iKTsKKworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBzZXQkY2FwaXRhbGl6ZWRfbmFtZSQoJHR5cGUkIHZhbHVlKSB7XG4iCisgICAgIiRudWxsX2NoZWNrJCIKKyAgICAiICAkc2V0X29uZW9mX2Nhc2VfbWVzc2FnZSQ7XG4iCisgICAgIiAgJG9uZW9mX25hbWUkXyA9IHZhbHVlO1xuIgorICAgICIgICRvbl9jaGFuZ2VkJFxuIgorICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICJ9XG4iKTsKKworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBjbGVhciRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAiICBpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iCisgICAgIiAgICAkY2xlYXJfb25lb2ZfY2FzZV9tZXNzYWdlJDtcbiIKKyAgICAiICAgICRvbmVvZl9uYW1lJF8gPSBudWxsO1xuIgorICAgICIgICAgJG9uX2NoYW5nZWQkXG4iCisgICAgIiAgfVxuIgorICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVQcmltaXRpdmVPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIKKyAgICAiICByZXN1bHQuJG9uZW9mX25hbWUkXyA9ICRvbmVvZl9uYW1lJF87XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZVByaW1pdGl2ZU9uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJzZXQkY2FwaXRhbGl6ZWRfbmFtZSQob3RoZXIuZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkpO1xuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlUHJpbWl0aXZlT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVBhcnNpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRzZXRfb25lb2ZfY2FzZV9tZXNzYWdlJDtcbiIKKyAgICAiJG9uZW9mX25hbWUkXyA9IGlucHV0LnJlYWQkY2FwaXRhbGl6ZWRfdHlwZSQoKTtcbiIpOworfQorCit2b2lkIEltbXV0YWJsZVByaW1pdGl2ZU9uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iCisgICAgIiAgb3V0cHV0LndyaXRlJGNhcGl0YWxpemVkX3R5cGUkKFxuIgorICAgICIgICAgICAkbnVtYmVyJCwgKCR0eXBlJCkoKCRib3hlZF90eXBlJCkgJG9uZW9mX25hbWUkXykpO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVQcmltaXRpdmVPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIKKyAgICAiICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW1cbiIKKyAgICAiICAgIC5jb21wdXRlJGNhcGl0YWxpemVkX3R5cGUkU2l6ZShcbiIKKyAgICAiICAgICAgICAkbnVtYmVyJCwgKCR0eXBlJCkoKCRib3hlZF90eXBlJCkgJG9uZW9mX25hbWUkXykpO1xuIgorICAgICJ9XG4iKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitSZXBlYXRlZEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK1JlcGVhdGVkSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYnVpbGRlckJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb250ZXh0KiBjb250ZXh0KQorICA6IGRlc2NyaXB0b3JfKGRlc2NyaXB0b3IpLCBtZXNzYWdlQml0SW5kZXhfKG1lc3NhZ2VCaXRJbmRleCksCisgICAgYnVpbGRlckJpdEluZGV4XyhidWlsZGVyQml0SW5kZXgpLCBjb250ZXh0Xyhjb250ZXh0KSwKKyAgICBuYW1lX3Jlc29sdmVyXyhjb250ZXh0LT5HZXROYW1lUmVzb2x2ZXIoKSkgeworICBTZXRQcmltaXRpdmVWYXJpYWJsZXMoZGVzY3JpcHRvciwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LT5HZXRGaWVsZEdlbmVyYXRvckluZm8oZGVzY3JpcHRvciksCisgICAgICAgICAgICAgICAgICAgICAgICBuYW1lX3Jlc29sdmVyXywgJnZhcmlhYmxlc18pOworfQorCitSZXBlYXRlZEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK35SZXBlYXRlZEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKCkge30KKworaW50IFJlcGVhdGVkSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OkdldE51bUJpdHNGb3JNZXNzYWdlKCkgY29uc3QgeworICByZXR1cm4gMDsKK30KKworaW50IFJlcGVhdGVkSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OkdldE51bUJpdHNGb3JCdWlsZGVyKCkgY29uc3QgeworICByZXR1cm4gMTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlSW50ZXJmYWNlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRqYXZhLnV0aWwuTGlzdDwkYm94ZWRfdHlwZSQ+IGdldCRjYXBpdGFsaXplZF9uYW1lJExpc3QoKTtcbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRpbnQgZ2V0JGNhcGl0YWxpemVkX25hbWUkQ291bnQoKTtcbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiQkdHlwZSQgZ2V0JGNhcGl0YWxpemVkX25hbWUkKGludCBpbmRleCk7XG4iKTsKK30KKworCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgJGZpZWxkX2xpc3RfdHlwZSQgJG5hbWUkXztcbiIpOworICBQcmludEV4dHJhRmllbGRJbmZvKHZhcmlhYmxlc18sIHByaW50ZXIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgamF2YS51dGlsLkxpc3Q8JGJveGVkX3R5cGUkPlxuIgorICAgICIgICAgZ2V0JGNhcGl0YWxpemVkX25hbWUkTGlzdCgpIHtcbiIKKyAgICAiICByZXR1cm4gJG5hbWUkXztcbiIgICAvLyBub3RlOiAgdW5tb2RpZmlhYmxlIGxpc3QKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBpbnQgZ2V0JGNhcGl0YWxpemVkX25hbWUkQ291bnQoKSB7XG4iCisgICAgIiAgcmV0dXJuICRuYW1lJF8uc2l6ZSgpO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljICR0eXBlJCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoaW50IGluZGV4KSB7XG4iCisgICAgIiAgcmV0dXJuICRuYW1lJF8uZ2V0KGluZGV4KTtcbiIKKyAgICAifVxuIik7CisKKyAgaWYgKGRlc2NyaXB0b3JfLT5pc19wYWNrZWQoKSAmJgorICAgICAgSGFzR2VuZXJhdGVkTWV0aG9kcyhkZXNjcmlwdG9yXy0+Y29udGFpbmluZ190eXBlKCkpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJwcml2YXRlIGludCAkbmFtZSRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7XG4iKTsKKyAgfQorfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBPbmUgZmllbGQgaXMgdGhlIGxpc3QgYW5kIHRoZSBiaXQgZmllbGQga2VlcHMgdHJhY2sgb2Ygd2hldGhlciB0aGUKKyAgLy8gbGlzdCBpcyBpbW11dGFibGUuIElmIGl0J3MgaW1tdXRhYmxlLCB0aGUgaW52YXJpYW50IGlzIHRoYXQgaXQgbXVzdAorICAvLyBlaXRoZXIgYW4gaW5zdGFuY2Ugb2YgQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCkgb3IgaXQncyBhbiBBcnJheUxpc3QKKyAgLy8gd3JhcHBlZCBpbiBhIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoKSB3cmFwcGVyIGFuZCBub2JvZHkgZWxzZSBoYXMKKyAgLy8gYSByZWZlcmVyZW5jZSB0byB0aGUgdW5kZXJseWluZyBBcnJheUxpc3QuIFRoaXMgaW52YXJpYW50IGFsbG93cyB1cyB0bworICAvLyBzaGFyZSBpbnN0YW5jZXMgb2YgbGlzdHMgYmV0d2VlbiBwcm90b2NvbCBidWZmZXJzIGF2b2lkaW5nIGV4cGVuc2l2ZQorICAvLyBtZW1vcnkgYWxsb2NhdGlvbnMuIE5vdGUsIGltbXV0YWJsZSBpcyBhIHN0cm9uZyBndWFyYW50ZWUgaGVyZSAtLSBub3QKKyAgLy8ganVzdCB0aGF0IHRoZSBsaXN0IGNhbm5vdCBiZSBtb2RpZmllZCB2aWEgdGhlIHJlZmVyZW5jZSBidXQgdGhhdCB0aGUKKyAgLy8gbGlzdCBjYW4gbmV2ZXIgYmUgbW9kaWZpZWQuCisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgJGZpZWxkX2xpc3RfdHlwZSQgJG5hbWUkXyA9ICRlbXB0eV9saXN0JDtcbiIpOworCisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgdm9pZCBlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKSB7XG4iCisgICAgIiAgaWYgKCEkZ2V0X211dGFibGVfYml0X2J1aWxkZXIkKSB7XG4iCisgICAgIiAgICAkbmFtZSRfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8JGJveGVkX3R5cGUkPigkbmFtZSRfKTtcbiIKKyAgICAiICAgICRzZXRfbXV0YWJsZV9iaXRfYnVpbGRlciQ7XG4iCisgICAgIiAgIH1cbiIKKyAgICAifVxuIik7CisKKyAgICAvLyBOb3RlOiAgV2UgcmV0dXJuIGFuIHVubW9kaWZpYWJsZSBsaXN0IGJlY2F1c2Ugb3RoZXJ3aXNlIHRoZSBjYWxsZXIKKyAgICAvLyAgIGNvdWxkIGhvbGQgb24gdG8gdGhlIHJldHVybmVkIGxpc3QgYW5kIG1vZGlmeSBpdCBhZnRlciB0aGUgbWVzc2FnZQorICAgIC8vICAgaGFzIGJlZW4gYnVpbHQsIHRodXMgbXV0YXRpbmcgdGhlIG1lc3NhZ2Ugd2hpY2ggaXMgc3VwcG9zZWQgdG8gYmUKKyAgICAvLyAgIGltbXV0YWJsZS4KKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIGphdmEudXRpbC5MaXN0PCRib3hlZF90eXBlJD5cbiIKKyAgICAiICAgIGdldCRjYXBpdGFsaXplZF9uYW1lJExpc3QoKSB7XG4iCisgICAgIiAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KCRuYW1lJF8pO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIGludCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRDb3VudCgpIHtcbiIKKyAgICAiICByZXR1cm4gJG5hbWUkXy5zaXplKCk7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkIGdldCRjYXBpdGFsaXplZF9uYW1lJChpbnQgaW5kZXgpIHtcbiIKKyAgICAiICByZXR1cm4gJG5hbWUkXy5nZXQoaW5kZXgpO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgc2V0JGNhcGl0YWxpemVkX25hbWUkKFxuIgorICAgICIgICAgaW50IGluZGV4LCAkdHlwZSQgdmFsdWUpIHtcbiIKKyAgICAiJG51bGxfY2hlY2skIgorICAgICIgIGVuc3VyZSRjYXBpdGFsaXplZF9uYW1lJElzTXV0YWJsZSgpO1xuIgorICAgICIgICRuYW1lJF8uc2V0KGluZGV4LCB2YWx1ZSk7XG4iCisgICAgIiAgJG9uX2NoYW5nZWQkXG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBhZGQkY2FwaXRhbGl6ZWRfbmFtZSQoJHR5cGUkIHZhbHVlKSB7XG4iCisgICAgIiRudWxsX2NoZWNrJCIKKyAgICAiICBlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKTtcbiIKKyAgICAiICAkbmFtZSRfLmFkZCh2YWx1ZSk7XG4iCisgICAgIiAgJG9uX2NoYW5nZWQkXG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBhZGRBbGwkY2FwaXRhbGl6ZWRfbmFtZSQoXG4iCisgICAgIiAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzICRib3hlZF90eXBlJD4gdmFsdWVzKSB7XG4iCisgICAgIiAgZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCk7XG4iCisgICAgIiAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKFxuIgorICAgICIgICAgICB2YWx1ZXMsICRuYW1lJF8pO1xuIgorICAgICIgICRvbl9jaGFuZ2VkJFxuIgorICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgY2xlYXIkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgJG5hbWUkXyA9ICRlbXB0eV9saXN0JDtcbiIKKyAgICAiICAkY2xlYXJfbXV0YWJsZV9iaXRfYnVpbGRlciQ7XG4iCisgICAgIiAgJG9uX2NoYW5nZWQkXG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVGaWVsZEJ1aWxkZXJJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpICBjb25zdCB7CisgIC8vIG5vb3AgZm9yIHByaW1pdGl2ZXMKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlSW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sICIkbmFtZSRfID0gJGVtcHR5X2xpc3QkO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUJ1aWxkZXJDbGVhckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJG5hbWUkXyA9ICRlbXB0eV9saXN0JDtcbiIKKyAgICAiJGNsZWFyX211dGFibGVfYml0X2J1aWxkZXIkO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIFRoZSBjb2RlIGJlbG93IGRvZXMgdHdvIG9wdGltaXphdGlvbnM6CisgIC8vICAgMS4gSWYgdGhlIG90aGVyIGxpc3QgaXMgZW1wdHksIHRoZXJlJ3Mgbm90aGluZyB0byBkby4gVGhpcyBlbnN1cmVzIHdlCisgIC8vICAgICAgZG9uJ3QgYWxsb2NhdGUgYSBuZXcgYXJyYXkgaWYgd2UgYWxyZWFkeSBoYXZlIGFuIGltbXV0YWJsZSBvbmUuCisgIC8vICAgMi4gSWYgdGhlIG90aGVyIGxpc3QgaXMgbm9uLWVtcHR5IGFuZCBvdXIgY3VycmVudCBsaXN0IGlzIGVtcHR5LCB3ZSBjYW4KKyAgLy8gICAgICByZXVzZSB0aGUgb3RoZXIgbGlzdCB3aGljaCBpcyBndWFyYW50ZWVkIHRvIGJlIGltbXV0YWJsZS4KKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCFvdGhlci4kbmFtZSRfLmlzRW1wdHkoKSkge1xuIgorICAgICIgIGlmICgkbmFtZSRfLmlzRW1wdHkoKSkge1xuIgorICAgICIgICAgJG5hbWUkXyA9IG90aGVyLiRuYW1lJF87XG4iCisgICAgIiAgICAkY2xlYXJfbXV0YWJsZV9iaXRfYnVpbGRlciQ7XG4iCisgICAgIiAgfSBlbHNlIHtcbiIKKyAgICAiICAgIGVuc3VyZSRjYXBpdGFsaXplZF9uYW1lJElzTXV0YWJsZSgpO1xuIgorICAgICIgICAgJG5hbWUkXy5hZGRBbGwob3RoZXIuJG5hbWUkXyk7XG4iCisgICAgIiAgfVxuIgorICAgICIgICRvbl9jaGFuZ2VkJFxuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIFRoZSBjb2RlIGJlbG93IGVuc3VyZXMgdGhhdCB0aGUgcmVzdWx0IGhhcyBhbiBpbW11dGFibGUgbGlzdC4gSWYgb3VyCisgIC8vIGxpc3QgaXMgaW1tdXRhYmxlLCB3ZSBjYW4ganVzdCByZXVzZSBpdC4gSWYgbm90LCB3ZSBtYWtlIGl0IGltbXV0YWJsZS4KKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCRnZXRfbXV0YWJsZV9iaXRfYnVpbGRlciQpIHtcbiIKKyAgICAiICAkbmFtZSRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoJG5hbWUkXyk7XG4iCisgICAgIiAgJGNsZWFyX211dGFibGVfYml0X2J1aWxkZXIkO1xuIgorICAgICJ9XG4iCisgICAgInJlc3VsdC4kbmFtZSRfID0gJG5hbWUkXztcbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVQYXJzaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoISRnZXRfbXV0YWJsZV9iaXRfcGFyc2VyJCkge1xuIgorICAgICIgICRuYW1lJF8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDwkYm94ZWRfdHlwZSQ+KCk7XG4iCisgICAgIiAgJHNldF9tdXRhYmxlX2JpdF9wYXJzZXIkO1xuIgorICAgICJ9XG4iCisgICAgIiRuYW1lJF8uYWRkKGlucHV0LnJlYWQkY2FwaXRhbGl6ZWRfdHlwZSQoKSk7XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlUGFyc2luZ0NvZGVGcm9tUGFja2VkKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTtcbiIKKyAgICAiaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7XG4iCisgICAgImlmICghJGdldF9tdXRhYmxlX2JpdF9wYXJzZXIkICYmIGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkge1xuIgorICAgICIgICRuYW1lJF8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDwkYm94ZWRfdHlwZSQ+KCk7XG4iCisgICAgIiAgJHNldF9tdXRhYmxlX2JpdF9wYXJzZXIkO1xuIgorICAgICJ9XG4iCisgICAgIndoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHtcbiIKKyAgICAiICAkbmFtZSRfLmFkZChpbnB1dC5yZWFkJGNhcGl0YWxpemVkX3R5cGUkKCkpO1xuIgorICAgICJ9XG4iCisgICAgImlucHV0LnBvcExpbWl0KGxpbWl0KTtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVQYXJzaW5nRG9uZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCRnZXRfbXV0YWJsZV9iaXRfcGFyc2VyJCkge1xuIgorICAgICIgICRuYW1lJF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdCgkbmFtZSRfKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChkZXNjcmlwdG9yXy0+aXNfcGFja2VkKCkpIHsKKyAgICAvLyBXZSBpbnZva2UgZ2V0U2VyaWFsaXplZFNpemUgaW4gd3JpdGVUbyBmb3IgbWVzc2FnZXMgdGhhdCBoYXZlIHBhY2tlZAorICAgIC8vIGZpZWxkcyBpbiBJbW11dGFibGVNZXNzYWdlR2VuZXJhdG9yOjpHZW5lcmF0ZU1lc3NhZ2VTZXJpYWxpemF0aW9uTWV0aG9kcy4KKyAgICAvLyBUaGF0IG1ha2VzIGl0IHNhZmUgdG8gcmVseSBvbiB0aGUgbWVtb2l6ZWQgc2l6ZSBoZXJlLgorICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaWYgKGdldCRjYXBpdGFsaXplZF9uYW1lJExpc3QoKS5zaXplKCkgPiAwKSB7XG4iCisgICAgICAiICBvdXRwdXQud3JpdGVSYXdWYXJpbnQzMigkdGFnJCk7XG4iCisgICAgICAiICBvdXRwdXQud3JpdGVSYXdWYXJpbnQzMigkbmFtZSRNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTtcbiIKKyAgICAgICJ9XG4iCisgICAgICAiZm9yIChpbnQgaSA9IDA7IGkgPCAkbmFtZSRfLnNpemUoKTsgaSsrKSB7XG4iCisgICAgICAiICBvdXRwdXQud3JpdGUkY2FwaXRhbGl6ZWRfdHlwZSROb1RhZygkbmFtZSRfLmdldChpKSk7XG4iCisgICAgICAifVxuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJmb3IgKGludCBpID0gMDsgaSA8ICRuYW1lJF8uc2l6ZSgpOyBpKyspIHtcbiIKKyAgICAgICIgIG91dHB1dC53cml0ZSRjYXBpdGFsaXplZF90eXBlJCgkbnVtYmVyJCwgJG5hbWUkXy5nZXQoaSkpO1xuIgorICAgICAgIn1cbiIpOworICB9Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJ7XG4iCisgICAgIiAgaW50IGRhdGFTaXplID0gMDtcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBpZiAoRml4ZWRTaXplKEdldFR5cGUoZGVzY3JpcHRvcl8pKSA9PSAtMSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiZm9yIChpbnQgaSA9IDA7IGkgPCAkbmFtZSRfLnNpemUoKTsgaSsrKSB7XG4iCisgICAgICAiICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtXG4iCisgICAgICAiICAgIC5jb21wdXRlJGNhcGl0YWxpemVkX3R5cGUkU2l6ZU5vVGFnKCRuYW1lJF8uZ2V0KGkpKTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImRhdGFTaXplID0gJGZpeGVkX3NpemUkICogZ2V0JGNhcGl0YWxpemVkX25hbWUkTGlzdCgpLnNpemUoKTtcbiIpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICAic2l6ZSArPSBkYXRhU2l6ZTtcbiIpOworCisgIGlmIChkZXNjcmlwdG9yXy0+aXNfcGFja2VkKCkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImlmICghZ2V0JGNhcGl0YWxpemVkX25hbWUkTGlzdCgpLmlzRW1wdHkoKSkge1xuIgorICAgICAgIiAgc2l6ZSArPSAkdGFnX3NpemUkO1xuIgorICAgICAgIiAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtXG4iCisgICAgICAiICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7XG4iCisgICAgICAifVxuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJzaXplICs9ICR0YWdfc2l6ZSQgKiBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRMaXN0KCkuc2l6ZSgpO1xuIik7CisgIH0KKworICAvLyBjYWNoZSB0aGUgZGF0YSBzaXplIGZvciBwYWNrZWQgZmllbGRzLgorICBpZiAoZGVzY3JpcHRvcl8tPmlzX3BhY2tlZCgpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkbmFtZSRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7XG4iKTsKKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVFcXVhbHNDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInJlc3VsdCA9IHJlc3VsdCAmJiBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRMaXN0KClcbiIKKyAgICAiICAgIC5lcXVhbHMob3RoZXIuZ2V0JGNhcGl0YWxpemVkX25hbWUkTGlzdCgpKTtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVIYXNoQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoZ2V0JGNhcGl0YWxpemVkX25hbWUkQ291bnQoKSA+IDApIHtcbiIKKyAgICAiICBoYXNoID0gKDM3ICogaGFzaCkgKyAkY29uc3RhbnRfbmFtZSQ7XG4iCisgICAgIiAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0JGNhcGl0YWxpemVkX25hbWUkTGlzdCgpLmhhc2hDb2RlKCk7XG4iCisgICAgIn1cbiIpOworfQorCitzdHJpbmcgUmVwZWF0ZWRJbW11dGFibGVQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6R2V0Qm94ZWRUeXBlKCkgY29uc3QgeworICByZXR1cm4gQm94ZWRQcmltaXRpdmVUeXBlTmFtZShHZXRKYXZhVHlwZShkZXNjcmlwdG9yXykpOworfQorCit9ICAvLyBuYW1lc3BhY2UgamF2YQorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX3ByaW1pdGl2ZV9maWVsZC5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfcHJpbWl0aXZlX2ZpZWxkLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDBjZDEyZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX3ByaW1pdGl2ZV9maWVsZC5oCkBAIC0wLDAgKzEsMTYwIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfUFJJTUlUSVZFX0ZJRUxEX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9QUklNSVRJVkVfRklFTERfSF9fCisKKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZmllbGQuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworICBuYW1lc3BhY2UgY29tcGlsZXIgeworICAgIG5hbWVzcGFjZSBqYXZhIHsKKyAgICAgIGNsYXNzIENvbnRleHQ7ICAgICAgICAgICAvLyBjb250ZXh0LmgKKyAgICAgIGNsYXNzIENsYXNzTmFtZVJlc29sdmVyOyAvLyBuYW1lX3Jlc29sdmVyLmgKKyAgICB9CisgIH0KK30KKworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YSB7CisKK2NsYXNzIEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yIDogcHVibGljIEltbXV0YWJsZUZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKAorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwgQ29udGV4dCogY29udGV4dCk7CisgIH5JbW11dGFibGVQcmltaXRpdmVGaWVsZEdlbmVyYXRvcigpOworCisgIC8vIGltcGxlbWVudHMgSW1tdXRhYmxlRmllbGRHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIGludCBHZXROdW1CaXRzRm9yTWVzc2FnZSgpIGNvbnN0OworICBpbnQgR2V0TnVtQml0c0ZvckJ1aWxkZXIoKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUludGVyZmFjZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnVpbGRlckNsZWFyQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCdWlsZGluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlUGFyc2luZ0RvbmVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVGaWVsZEJ1aWxkZXJJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVIYXNoQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyAgc3RyaW5nIEdldEJveGVkVHlwZSgpIGNvbnN0OworCisgcHJvdGVjdGVkOgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlc187CisgIGNvbnN0IGludCBtZXNzYWdlQml0SW5kZXhfOworICBjb25zdCBpbnQgYnVpbGRlckJpdEluZGV4XzsKKyAgQ29udGV4dCogY29udGV4dF87CisgIENsYXNzTmFtZVJlc29sdmVyKiBuYW1lX3Jlc29sdmVyXzsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhJbW11dGFibGVQcmltaXRpdmVGaWVsZEdlbmVyYXRvcik7Cit9OworCitjbGFzcyBJbW11dGFibGVQcmltaXRpdmVPbmVvZkZpZWxkR2VuZXJhdG9yCisgICAgOiBwdWJsaWMgSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgSW1tdXRhYmxlUHJpbWl0aXZlT25lb2ZGaWVsZEdlbmVyYXRvcigKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwgaW50IG1lc3NhZ2VCaXRJbmRleCwKKyAgICAgIGludCBidWlsZGVyQml0SW5kZXgsIENvbnRleHQqIGNvbnRleHQpOworICB+SW1tdXRhYmxlUHJpbWl0aXZlT25lb2ZGaWVsZEdlbmVyYXRvcigpOworCisgIHZvaWQgR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUJ1aWxkZXJNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUJ1aWxkaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVQYXJzaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEltbXV0YWJsZVByaW1pdGl2ZU9uZW9mRmllbGRHZW5lcmF0b3IpOworfTsKKworY2xhc3MgUmVwZWF0ZWRJbW11dGFibGVQcmltaXRpdmVGaWVsZEdlbmVyYXRvcgorICAgIDogcHVibGljIEltbXV0YWJsZUZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IFJlcGVhdGVkSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IoCisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGludCBtZXNzYWdlQml0SW5kZXgsCisgICAgICBpbnQgYnVpbGRlckJpdEluZGV4LCBDb250ZXh0KiBjb250ZXh0KTsKKyAgdmlydHVhbCB+UmVwZWF0ZWRJbW11dGFibGVQcmltaXRpdmVGaWVsZEdlbmVyYXRvcigpOworCisgIC8vIGltcGxlbWVudHMgSW1tdXRhYmxlRmllbGRHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIGludCBHZXROdW1CaXRzRm9yTWVzc2FnZSgpIGNvbnN0OworICBpbnQgR2V0TnVtQml0c0ZvckJ1aWxkZXIoKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUludGVyZmFjZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnVpbGRlckNsZWFyQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCdWlsZGluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlUGFyc2luZ0NvZGVGcm9tUGFja2VkKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVBhcnNpbmdEb25lQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRmllbGRCdWlsZGVySW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUVxdWFsc0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSGFzaENvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgIHN0cmluZyBHZXRCb3hlZFR5cGUoKSBjb25zdDsKKworIHByaXZhdGU6CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcl87CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyaWFibGVzXzsKKyAgY29uc3QgaW50IG1lc3NhZ2VCaXRJbmRleF87CisgIGNvbnN0IGludCBidWlsZGVyQml0SW5kZXhfOworICBDb250ZXh0KiBjb250ZXh0XzsKKyAgQ2xhc3NOYW1lUmVzb2x2ZXIqIG5hbWVfcmVzb2x2ZXJfOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhSZXBlYXRlZEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX1BSSU1JVElWRV9GSUVMRF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX3ByaW1pdGl2ZV9maWVsZF9saXRlLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfcHJpbWl0aXZlX2ZpZWxkX2xpdGUuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWE3YmY4MgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX3ByaW1pdGl2ZV9maWVsZF9saXRlLmNjCkBAIC0wLDAgKzEsOTExIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8c3RyaW5nPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2xvZ2dpbmcuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9jb250ZXh0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9kb2NfY29tbWVudC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfaGVscGVycy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbmFtZV9yZXNvbHZlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfcHJpbWl0aXZlX2ZpZWxkX2xpdGUuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YSB7CisKK3VzaW5nIGludGVybmFsOjpXaXJlRm9ybWF0OwordXNpbmcgaW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOworCituYW1lc3BhY2UgeworCit2b2lkIFNldFByaW1pdGl2ZVZhcmlhYmxlcyhjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkR2VuZXJhdG9ySW5mbyogaW5mbywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzTmFtZVJlc29sdmVyKiBuYW1lX3Jlc29sdmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwPHN0cmluZywgc3RyaW5nPiogdmFyaWFibGVzKSB7CisgIFNldENvbW1vbkZpZWxkVmFyaWFibGVzKGRlc2NyaXB0b3IsIGluZm8sIHZhcmlhYmxlcyk7CisKKyAgKCp2YXJpYWJsZXMpWyJ0eXBlIl0gPSBQcmltaXRpdmVUeXBlTmFtZShHZXRKYXZhVHlwZShkZXNjcmlwdG9yKSk7CisgICgqdmFyaWFibGVzKVsiYm94ZWRfdHlwZSJdID0gQm94ZWRQcmltaXRpdmVUeXBlTmFtZShHZXRKYXZhVHlwZShkZXNjcmlwdG9yKSk7CisgICgqdmFyaWFibGVzKVsiZmllbGRfdHlwZSJdID0gKCp2YXJpYWJsZXMpWyJ0eXBlIl07CisgICgqdmFyaWFibGVzKVsiZGVmYXVsdCJdID0gSW1tdXRhYmxlRGVmYXVsdFZhbHVlKGRlc2NyaXB0b3IsIG5hbWVfcmVzb2x2ZXIpOworICAoKnZhcmlhYmxlcylbImRlZmF1bHRfaW5pdCJdID0gSXNEZWZhdWx0VmFsdWVKYXZhRGVmYXVsdChkZXNjcmlwdG9yKSA/CisgICAgICAiIiA6ICgiPSAiICsgSW1tdXRhYmxlRGVmYXVsdFZhbHVlKGRlc2NyaXB0b3IsIG5hbWVfcmVzb2x2ZXIpKTsKKyAgKCp2YXJpYWJsZXMpWyJjYXBpdGFsaXplZF90eXBlIl0gPQorICAgICAgR2V0Q2FwaXRhbGl6ZWRUeXBlKGRlc2NyaXB0b3IsIC8qIGltbXV0YWJsZSA9ICovIHRydWUpOworICAoKnZhcmlhYmxlcylbInRhZyJdID0gU2ltcGxlSXRvYShXaXJlRm9ybWF0OjpNYWtlVGFnKGRlc2NyaXB0b3IpKTsKKyAgKCp2YXJpYWJsZXMpWyJ0YWdfc2l6ZSJdID0gU2ltcGxlSXRvYSgKKyAgICAgIFdpcmVGb3JtYXQ6OlRhZ1NpemUoZGVzY3JpcHRvci0+bnVtYmVyKCksIEdldFR5cGUoZGVzY3JpcHRvcikpKTsKKworICBzdHJpbmcgY2FwaXRhbGl6ZWRfdHlwZSA9IFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoUHJpbWl0aXZlVHlwZU5hbWUoCisgICAgICAgIEdldEphdmFUeXBlKGRlc2NyaXB0b3IpKSwgdHJ1ZSAvKiBjYXBfbmV4dF9sZXR0ZXIgKi8pOworICBzd2l0Y2ggKEdldEphdmFUeXBlKGRlc2NyaXB0b3IpKSB7CisgICAgY2FzZSBKQVZBVFlQRV9JTlQ6CisgICAgY2FzZSBKQVZBVFlQRV9MT05HOgorICAgIGNhc2UgSkFWQVRZUEVfRkxPQVQ6CisgICAgY2FzZSBKQVZBVFlQRV9ET1VCTEU6CisgICAgY2FzZSBKQVZBVFlQRV9CT09MRUFOOgorICAgICAgKCp2YXJpYWJsZXMpWyJmaWVsZF9saXN0X3R5cGUiXSA9CisgICAgICAgICAgImNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuIiArIGNhcGl0YWxpemVkX3R5cGUgKyAiTGlzdCI7CisgICAgICAoKnZhcmlhYmxlcylbIm5ld19saXN0Il0gPSAibmV3IiArIGNhcGl0YWxpemVkX3R5cGUgKyAiTGlzdCI7CisgICAgICAoKnZhcmlhYmxlcylbIm5ld19saXN0X3dpdGhfY2FwYWNpdHkiXSA9CisgICAgICAgICAgIm5ldyIgKyBjYXBpdGFsaXplZF90eXBlICsgIkxpc3RXaXRoQ2FwYWNpdHkiOworICAgICAgKCp2YXJpYWJsZXMpWyJlbXB0eV9saXN0Il0gPSAiZW1wdHkiICsgY2FwaXRhbGl6ZWRfdHlwZSArICJMaXN0KCkiOworICAgICAgKCp2YXJpYWJsZXMpWyJtYWtlX25hbWVfdW5tb2RpZmlhYmxlIl0gPQorICAgICAgICAgICgqdmFyaWFibGVzKVsibmFtZSJdICsgIl8ubWFrZUltbXV0YWJsZSgpIjsKKyAgICAgICgqdmFyaWFibGVzKVsicmVwZWF0ZWRfZ2V0Il0gPQorICAgICAgICAgICgqdmFyaWFibGVzKVsibmFtZSJdICsgIl8uZ2V0IiArIGNhcGl0YWxpemVkX3R5cGU7CisgICAgICAoKnZhcmlhYmxlcylbInJlcGVhdGVkX2FkZCJdID0KKyAgICAgICAgICAoKnZhcmlhYmxlcylbIm5hbWUiXSArICJfLmFkZCIgKyBjYXBpdGFsaXplZF90eXBlOworICAgICAgKCp2YXJpYWJsZXMpWyJyZXBlYXRlZF9zZXQiXSA9CisgICAgICAgICAgKCp2YXJpYWJsZXMpWyJuYW1lIl0gKyAiXy5zZXQiICsgY2FwaXRhbGl6ZWRfdHlwZTsKKyAgICAgIGJyZWFrOworICAgIGRlZmF1bHQ6CisgICAgICAoKnZhcmlhYmxlcylbImZpZWxkX2xpc3RfdHlwZSJdID0KKyAgICAgICAgICAiY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Qcm90b2J1Zkxpc3Q8IiArCisgICAgICAgICAgKCp2YXJpYWJsZXMpWyJib3hlZF90eXBlIl0gKyAiPiI7CisgICAgICAoKnZhcmlhYmxlcylbIm5ld19saXN0Il0gPSAibmV3UHJvdG9idWZMaXN0IjsKKyAgICAgICgqdmFyaWFibGVzKVsibmV3X2xpc3Rfd2l0aF9jYXBhY2l0eSJdID0gIm5ld1Byb3RvYnVmTGlzdFdpdGhDYXBhY2l0eSI7CisgICAgICAoKnZhcmlhYmxlcylbImVtcHR5X2xpc3QiXSA9ICJlbXB0eVByb3RvYnVmTGlzdCgpIjsKKyAgICAgICgqdmFyaWFibGVzKVsibWFrZV9uYW1lX3VubW9kaWZpYWJsZSJdID0KKyAgICAgICAgICAoKnZhcmlhYmxlcylbIm5hbWUiXSArICJfLm1ha2VJbW11dGFibGUoKSI7CisgICAgICAoKnZhcmlhYmxlcylbInJlcGVhdGVkX2dldCJdID0gKCp2YXJpYWJsZXMpWyJuYW1lIl0gKyAiXy5nZXQiOworICAgICAgKCp2YXJpYWJsZXMpWyJyZXBlYXRlZF9hZGQiXSA9ICgqdmFyaWFibGVzKVsibmFtZSJdICsgIl8uYWRkIjsKKyAgICAgICgqdmFyaWFibGVzKVsicmVwZWF0ZWRfc2V0Il0gPSAoKnZhcmlhYmxlcylbIm5hbWUiXSArICJfLnNldCI7CisgIH0KKworICBpZiAoSXNSZWZlcmVuY2VUeXBlKEdldEphdmFUeXBlKGRlc2NyaXB0b3IpKSkgeworICAgICgqdmFyaWFibGVzKVsibnVsbF9jaGVjayJdID0KKyAgICAgICAgIiAgaWYgKHZhbHVlID09IG51bGwpIHtcbiIKKyAgICAgICAgIiAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTtcbiIKKyAgICAgICAgIiAgfVxuIjsKKyAgfSBlbHNlIHsKKyAgICAoKnZhcmlhYmxlcylbIm51bGxfY2hlY2siXSA9ICIiOworICB9CisgIC8vIFRPRE8oYmlyZG8pOiBBZGQgQGRlcHJlY2F0ZWQgamF2YWRvYyB3aGVuIGdlbmVyYXRpbmcgamF2YWRvYyBpcyBzdXBwb3J0ZWQKKyAgLy8gYnkgdGhlIHByb3RvIGNvbXBpbGVyCisgICgqdmFyaWFibGVzKVsiZGVwcmVjYXRpb24iXSA9IGRlc2NyaXB0b3ItPm9wdGlvbnMoKS5kZXByZWNhdGVkKCkKKyAgICAgID8gIkBqYXZhLmxhbmcuRGVwcmVjYXRlZCAiIDogIiI7CisgIGludCBmaXhlZF9zaXplID0gRml4ZWRTaXplKEdldFR5cGUoZGVzY3JpcHRvcikpOworICBpZiAoZml4ZWRfc2l6ZSAhPSAtMSkgeworICAgICgqdmFyaWFibGVzKVsiZml4ZWRfc2l6ZSJdID0gU2ltcGxlSXRvYShmaXhlZF9zaXplKTsKKyAgfQorICAoKnZhcmlhYmxlcylbIm9uX2NoYW5nZWQiXSA9CisgICAgICBIYXNEZXNjcmlwdG9yTWV0aG9kcyhkZXNjcmlwdG9yLT5jb250YWluaW5nX3R5cGUoKSkgPyAib25DaGFuZ2VkKCk7IiA6ICIiOworCisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yLT5maWxlKCkpKSB7CisgICAgLy8gRm9yIHNpbmd1bGFyIG1lc3NhZ2VzIGFuZCBidWlsZGVycywgb25lIGJpdCBpcyB1c2VkIGZvciB0aGUgaGFzRmllbGQgYml0LgorICAgICgqdmFyaWFibGVzKVsiZ2V0X2hhc19maWVsZF9iaXRfbWVzc2FnZSJdID0gR2VuZXJhdGVHZXRCaXQobWVzc2FnZUJpdEluZGV4KTsKKworICAgIC8vIE5vdGUgdGhhdCB0aGVzZSBoYXZlIGEgdHJhaWxpbmcgIjsiLgorICAgICgqdmFyaWFibGVzKVsic2V0X2hhc19maWVsZF9iaXRfbWVzc2FnZSJdID0KKyAgICAgICAgR2VuZXJhdGVTZXRCaXQobWVzc2FnZUJpdEluZGV4KSArICI7IjsKKyAgICAoKnZhcmlhYmxlcylbImNsZWFyX2hhc19maWVsZF9iaXRfbWVzc2FnZSJdID0KKyAgICAgICAgR2VuZXJhdGVDbGVhckJpdChtZXNzYWdlQml0SW5kZXgpICsgIjsiOworCisgICAgKCp2YXJpYWJsZXMpWyJpc19maWVsZF9wcmVzZW50X21lc3NhZ2UiXSA9IEdlbmVyYXRlR2V0Qml0KG1lc3NhZ2VCaXRJbmRleCk7CisgIH0gZWxzZSB7CisgICAgKCp2YXJpYWJsZXMpWyJzZXRfaGFzX2ZpZWxkX2JpdF9tZXNzYWdlIl0gPSAiIjsKKyAgICAoKnZhcmlhYmxlcylbInNldF9oYXNfZmllbGRfYml0X21lc3NhZ2UiXSA9ICIiOworICAgICgqdmFyaWFibGVzKVsiY2xlYXJfaGFzX2ZpZWxkX2JpdF9tZXNzYWdlIl0gPSAiIjsKKworICAgIGlmIChkZXNjcmlwdG9yLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX0JZVEVTKSB7CisgICAgICAoKnZhcmlhYmxlcylbImlzX2ZpZWxkX3ByZXNlbnRfbWVzc2FnZSJdID0KKyAgICAgICAgICAiISIgKyAoKnZhcmlhYmxlcylbIm5hbWUiXSArICJfLmlzRW1wdHkoKSI7CisgICAgfSBlbHNlIHsKKyAgICAgICgqdmFyaWFibGVzKVsiaXNfZmllbGRfcHJlc2VudF9tZXNzYWdlIl0gPQorICAgICAgICAgICgqdmFyaWFibGVzKVsibmFtZSJdICsgIl8gIT0gIiArICgqdmFyaWFibGVzKVsiZGVmYXVsdCJdOworICAgIH0KKyAgfQorCisgIC8vIEZvciByZXBlYXRlZCBidWlsZGVycywgdGhlIHVuZGVybHlpbmcgbGlzdCB0cmFja3MgbXV0YWJpbGl0eSBzdGF0ZS4KKyAgKCp2YXJpYWJsZXMpWyJpc19tdXRhYmxlIl0gPSAoKnZhcmlhYmxlcylbIm5hbWUiXSArICJfLmlzTW9kaWZpYWJsZSgpIjsKKworICAoKnZhcmlhYmxlcylbImdldF9oYXNfZmllbGRfYml0X2Zyb21fbG9jYWwiXSA9CisgICAgICBHZW5lcmF0ZUdldEJpdEZyb21Mb2NhbChidWlsZGVyQml0SW5kZXgpOworICAoKnZhcmlhYmxlcylbInNldF9oYXNfZmllbGRfYml0X3RvX2xvY2FsIl0gPQorICAgICAgR2VuZXJhdGVTZXRCaXRUb0xvY2FsKG1lc3NhZ2VCaXRJbmRleCk7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK0ltbXV0YWJsZVByaW1pdGl2ZUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitJbW11dGFibGVQcmltaXRpdmVGaWVsZExpdGVHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG1lc3NhZ2VCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBidWlsZGVyQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb250ZXh0KiBjb250ZXh0KQorICA6IGRlc2NyaXB0b3JfKGRlc2NyaXB0b3IpLCBtZXNzYWdlQml0SW5kZXhfKG1lc3NhZ2VCaXRJbmRleCksCisgICAgYnVpbGRlckJpdEluZGV4XyhidWlsZGVyQml0SW5kZXgpLCBjb250ZXh0Xyhjb250ZXh0KSwKKyAgICBuYW1lX3Jlc29sdmVyXyhjb250ZXh0LT5HZXROYW1lUmVzb2x2ZXIoKSkgeworICBTZXRQcmltaXRpdmVWYXJpYWJsZXMoZGVzY3JpcHRvciwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LT5HZXRGaWVsZEdlbmVyYXRvckluZm8oZGVzY3JpcHRvciksCisgICAgICAgICAgICAgICAgICAgICAgICBuYW1lX3Jlc29sdmVyXywgJnZhcmlhYmxlc18pOworfQorCitJbW11dGFibGVQcmltaXRpdmVGaWVsZExpdGVHZW5lcmF0b3I6On5JbW11dGFibGVQcmltaXRpdmVGaWVsZExpdGVHZW5lcmF0b3IoKSB7fQorCitpbnQgSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRMaXRlR2VuZXJhdG9yOjpHZXROdW1CaXRzRm9yTWVzc2FnZSgpIGNvbnN0IHsKKyAgcmV0dXJuIDE7Cit9CisKK2ludCBJbW11dGFibGVQcmltaXRpdmVGaWVsZExpdGVHZW5lcmF0b3I6OkdldE51bUJpdHNGb3JCdWlsZGVyKCkgY29uc3QgeworICByZXR1cm4gMDsKK30KKwordm9pZCBJbW11dGFibGVQcmltaXRpdmVGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVJbnRlcmZhY2VNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRib29sZWFuIGhhcyRjYXBpdGFsaXplZF9uYW1lJCgpO1xuIik7CisgIH0KKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kJHR5cGUkIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpO1xuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlICRmaWVsZF90eXBlJCAkbmFtZSRfO1xuIik7CisgIFByaW50RXh0cmFGaWVsZEluZm8odmFyaWFibGVzXywgcHJpbnRlcik7CisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgYm9vbGVhbiBoYXMkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgICAiICByZXR1cm4gJGdldF9oYXNfZmllbGRfYml0X21lc3NhZ2UkO1xuIgorICAgICAgIn1cbiIpOworICB9CisKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljICR0eXBlJCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgcmV0dXJuICRuYW1lJF87XG4iCisgICAgIn1cbiIpOworCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHJpdmF0ZSB2b2lkIHNldCRjYXBpdGFsaXplZF9uYW1lJCgkdHlwZSQgdmFsdWUpIHtcbiIKKyAgICAiJG51bGxfY2hlY2skIgorICAgICIgICRzZXRfaGFzX2ZpZWxkX2JpdF9tZXNzYWdlJFxuIgorICAgICIgICRuYW1lJF8gPSB2YWx1ZTtcbiIKKyAgICAifVxuIik7CisKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIHZvaWQgY2xlYXIkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgJGNsZWFyX2hhc19maWVsZF9iaXRfbWVzc2FnZSRcbiIpOworICBKYXZhVHlwZSB0eXBlID0gR2V0SmF2YVR5cGUoZGVzY3JpcHRvcl8pOworICBpZiAodHlwZSA9PSBKQVZBVFlQRV9TVFJJTkcgfHwgdHlwZSA9PSBKQVZBVFlQRV9CWVRFUykgeworICAgIC8vIFRoZSBkZWZhdWx0IHZhbHVlIGlzIG5vdCBhIHNpbXBsZSBsaXRlcmFsIHNvIHdlIHdhbnQgdG8gYXZvaWQgZXhlY3V0aW5nCisgICAgLy8gaXQgbXVsdGlwbGUgdGltZXMuICBJbnN0ZWFkLCBnZXQgdGhlIGRlZmF1bHQgb3V0IG9mIHRoZSBkZWZhdWx0IGluc3RhbmNlLgorICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiICAkbmFtZSRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0JGNhcGl0YWxpemVkX25hbWUkKCk7XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiAgJG5hbWUkXyA9ICRkZWZhdWx0JDtcbiIpOworICB9CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUJ1aWxkZXJNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgYm9vbGVhbiBoYXMkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgICAiICByZXR1cm4gaW5zdGFuY2UuaGFzJGNhcGl0YWxpemVkX25hbWUkKCk7XG4iCisgICAgICAifVxuIik7CisgIH0KKworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAiICByZXR1cm4gaW5zdGFuY2UuZ2V0JGNhcGl0YWxpemVkX25hbWUkKCk7XG4iCisgICAgIn1cbiIpOworCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIHNldCRjYXBpdGFsaXplZF9uYW1lJCgkdHlwZSQgdmFsdWUpIHtcbiIKKyAgICAiICBjb3B5T25Xcml0ZSgpO1xuIgorICAgICIgIGluc3RhbmNlLnNldCRjYXBpdGFsaXplZF9uYW1lJCh2YWx1ZSk7XG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGNsZWFyJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgIGNvcHlPbldyaXRlKCk7XG4iCisgICAgIiAgaW5zdGFuY2UuY2xlYXIkY2FwaXRhbGl6ZWRfbmFtZSQoKTtcbiIKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlRmllbGRCdWlsZGVySW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSAgY29uc3QgeworICAvLyBub29wIGZvciBwcmltaXRpdmVzCit9CisKK3ZvaWQgSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlSW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sICIkbmFtZSRfID0gJGRlZmF1bHQkO1xuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRlckNsZWFyQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBub29wIGZvciBwcmltaXRpdmVzCit9CisKK3ZvaWQgSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKFN1cHBvcnRGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJpZiAob3RoZXIuaGFzJGNhcGl0YWxpemVkX25hbWUkKCkpIHtcbiIKKyAgICAgICIgIHNldCRjYXBpdGFsaXplZF9uYW1lJChvdGhlci5nZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSk7XG4iCisgICAgICAifVxuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJpZiAob3RoZXIuZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkgIT0gJGRlZmF1bHQkKSB7XG4iCisgICAgICAiICBzZXQkY2FwaXRhbGl6ZWRfbmFtZSQob3RoZXIuZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkpO1xuIgorICAgICAgIn1cbiIpOworICB9Cit9CisKK3ZvaWQgSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIG5vb3AgZm9yIHByaW1pdGl2ZXMKK30KKwordm9pZCBJbW11dGFibGVQcmltaXRpdmVGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVEeW5hbWljTWV0aG9kTWFrZUltbXV0YWJsZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gbm9vcCBmb3Igc2NhbGFycworfQorCit2b2lkIEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZVBhcnNpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRzZXRfaGFzX2ZpZWxkX2JpdF9tZXNzYWdlJFxuIgorICAgICIkbmFtZSRfID0gaW5wdXQucmVhZCRjYXBpdGFsaXplZF90eXBlJCgpO1xuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlUGFyc2luZ0RvbmVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIG5vb3AgZm9yIHByaW1pdGl2ZXMuCit9CisKK3ZvaWQgSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCRpc19maWVsZF9wcmVzZW50X21lc3NhZ2UkKSB7XG4iCisgICAgIiAgb3V0cHV0LndyaXRlJGNhcGl0YWxpemVkX3R5cGUkKCRudW1iZXIkLCAkbmFtZSRfKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkaXNfZmllbGRfcHJlc2VudF9tZXNzYWdlJCkge1xuIgorICAgICIgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbVxuIgorICAgICIgICAgLmNvbXB1dGUkY2FwaXRhbGl6ZWRfdHlwZSRTaXplKCRudW1iZXIkLCAkbmFtZSRfKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBzd2l0Y2ggKEdldEphdmFUeXBlKGRlc2NyaXB0b3JfKSkgeworICAgIGNhc2UgSkFWQVRZUEVfSU5UOgorICAgIGNhc2UgSkFWQVRZUEVfTE9ORzoKKyAgICBjYXNlIEpBVkFUWVBFX0JPT0xFQU46CisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAicmVzdWx0ID0gcmVzdWx0ICYmIChnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKVxuIgorICAgICAgICAiICAgID09IG90aGVyLmdldCRjYXBpdGFsaXplZF9uYW1lJCgpKTtcbiIpOworICAgICAgYnJlYWs7CisKKyAgICBjYXNlIEpBVkFUWVBFX0ZMT0FUOgorICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgInJlc3VsdCA9IHJlc3VsdCAmJiAoXG4iCisgICAgICAgICIgICAgamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKGdldCRjYXBpdGFsaXplZF9uYW1lJCgpKVxuIgorICAgICAgICAiICAgID09IGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cyhcbiIKKyAgICAgICAgIiAgICAgICAgb3RoZXIuZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkpKTtcbiIpOworICAgICAgYnJlYWs7CisKKyAgICBjYXNlIEpBVkFUWVBFX0RPVUJMRToKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICJyZXN1bHQgPSByZXN1bHQgJiYgKFxuIgorICAgICAgICAiICAgIGphdmEubGFuZy5Eb3VibGUuZG91YmxlVG9Mb25nQml0cyhnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSlcbiIKKyAgICAgICAgIiAgICA9PSBqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoXG4iCisgICAgICAgICIgICAgICAgIG90aGVyLmdldCRjYXBpdGFsaXplZF9uYW1lJCgpKSk7XG4iKTsKKyAgICAgIGJyZWFrOworCisgICAgY2FzZSBKQVZBVFlQRV9TVFJJTkc6CisgICAgY2FzZSBKQVZBVFlQRV9CWVRFUzoKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICJyZXN1bHQgPSByZXN1bHQgJiYgZ2V0JGNhcGl0YWxpemVkX25hbWUkKClcbiIKKyAgICAgICAgIiAgICAuZXF1YWxzKG90aGVyLmdldCRjYXBpdGFsaXplZF9uYW1lJCgpKTtcbiIpOworICAgICAgYnJlYWs7CisKKyAgICBjYXNlIEpBVkFUWVBFX0VOVU06CisgICAgY2FzZSBKQVZBVFlQRV9NRVNTQUdFOgorICAgIGRlZmF1bHQ6CisgICAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ2FuJ3QgZ2V0IGhlcmUuIjsKKyAgICAgIGJyZWFrOworICB9Cit9CisKK3ZvaWQgSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlSGFzaENvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaGFzaCA9ICgzNyAqIGhhc2gpICsgJGNvbnN0YW50X25hbWUkO1xuIik7CisgIHN3aXRjaCAoR2V0SmF2YVR5cGUoZGVzY3JpcHRvcl8pKSB7CisgICAgY2FzZSBKQVZBVFlQRV9JTlQ6CisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAiaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCk7XG4iKTsKKyAgICAgIGJyZWFrOworCisgICAgY2FzZSBKQVZBVFlQRV9MT05HOgorICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgImhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoXG4iCisgICAgICAgICIgICAgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkpO1xuIik7CisgICAgICBicmVhazsKKworICAgIGNhc2UgSkFWQVRZUEVfQk9PTEVBTjoKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICJoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hCb29sZWFuKFxuIgorICAgICAgICAiICAgIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpKTtcbiIpOworICAgICAgYnJlYWs7CisKKyAgICBjYXNlIEpBVkFUWVBFX0ZMT0FUOgorICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgImhhc2ggPSAoNTMgKiBoYXNoKSArIGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cyhcbiIKKyAgICAgICAgIiAgICBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSk7XG4iKTsKKyAgICAgIGJyZWFrOworCisgICAgY2FzZSBKQVZBVFlQRV9ET1VCTEU6CisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAiaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoTG9uZyhcbiIKKyAgICAgICAgIiAgICBqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkpKTtcbiIpOworICAgICAgYnJlYWs7CisKKyAgICBjYXNlIEpBVkFUWVBFX1NUUklORzoKKyAgICBjYXNlIEpBVkFUWVBFX0JZVEVTOgorICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgImhhc2ggPSAoNTMgKiBoYXNoKSArIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpLmhhc2hDb2RlKCk7XG4iKTsKKyAgICAgIGJyZWFrOworCisgICAgY2FzZSBKQVZBVFlQRV9FTlVNOgorICAgIGNhc2UgSkFWQVRZUEVfTUVTU0FHRToKKyAgICBkZWZhdWx0OgorICAgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkNhbid0IGdldCBoZXJlLiI7CisgICAgICBicmVhazsKKyAgfQorfQorCitzdHJpbmcgSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRMaXRlR2VuZXJhdG9yOjpHZXRCb3hlZFR5cGUoKSBjb25zdCB7CisgIHJldHVybiBCb3hlZFByaW1pdGl2ZVR5cGVOYW1lKEdldEphdmFUeXBlKGRlc2NyaXB0b3JfKSk7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworSW1tdXRhYmxlUHJpbWl0aXZlT25lb2ZGaWVsZExpdGVHZW5lcmF0b3I6OgorSW1tdXRhYmxlUHJpbWl0aXZlT25lb2ZGaWVsZExpdGVHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG1lc3NhZ2VCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBidWlsZGVyQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb250ZXh0KiBjb250ZXh0KQorICAgIDogSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRMaXRlR2VuZXJhdG9yKAorICAgICAgICAgIGRlc2NyaXB0b3IsIG1lc3NhZ2VCaXRJbmRleCwgYnVpbGRlckJpdEluZGV4LCBjb250ZXh0KSB7CisgIGNvbnN0IE9uZW9mR2VuZXJhdG9ySW5mbyogaW5mbyA9CisgICAgICBjb250ZXh0LT5HZXRPbmVvZkdlbmVyYXRvckluZm8oZGVzY3JpcHRvci0+Y29udGFpbmluZ19vbmVvZigpKTsKKyAgU2V0Q29tbW9uT25lb2ZWYXJpYWJsZXMoZGVzY3JpcHRvciwgaW5mbywgJnZhcmlhYmxlc18pOworfQorCitJbW11dGFibGVQcmltaXRpdmVPbmVvZkZpZWxkTGl0ZUdlbmVyYXRvcjo6Cit+SW1tdXRhYmxlUHJpbWl0aXZlT25lb2ZGaWVsZExpdGVHZW5lcmF0b3IoKSB7fQorCit2b2lkIEltbXV0YWJsZVByaW1pdGl2ZU9uZW9mRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBQcmludEV4dHJhRmllbGRJbmZvKHZhcmlhYmxlc18sIHByaW50ZXIpOworICBpZiAoU3VwcG9ydEZpZWxkUHJlc2VuY2UoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljIGJvb2xlYW4gaGFzJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICAgIiAgcmV0dXJuICRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJDtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyAkdHlwZSQgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgIGlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIKKyAgICAiICAgIHJldHVybiAoJGJveGVkX3R5cGUkKSAkb25lb2ZfbmFtZSRfO1xuIgorICAgICIgIH1cbiIKKyAgICAiICByZXR1cm4gJGRlZmF1bHQkO1xuIgorICAgICJ9XG4iKTsKKworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgdm9pZCBzZXQkY2FwaXRhbGl6ZWRfbmFtZSQoJHR5cGUkIHZhbHVlKSB7XG4iCisgICAgIiRudWxsX2NoZWNrJCIKKyAgICAiICAkc2V0X29uZW9mX2Nhc2VfbWVzc2FnZSQ7XG4iCisgICAgIiAgJG9uZW9mX25hbWUkXyA9IHZhbHVlO1xuIgorICAgICJ9XG4iKTsKKworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgdm9pZCBjbGVhciRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAiICBpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iCisgICAgIiAgICAkY2xlYXJfb25lb2ZfY2FzZV9tZXNzYWdlJDtcbiIKKyAgICAiICAgICRvbmVvZl9uYW1lJF8gPSBudWxsO1xuIgorICAgICIgIH1cbiIKKyAgICAifVxuIik7Cit9CisKKwordm9pZCBJbW11dGFibGVQcmltaXRpdmVPbmVvZkZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUJ1aWxkZXJNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgYm9vbGVhbiBoYXMkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgICAiICByZXR1cm4gaW5zdGFuY2UuaGFzJGNhcGl0YWxpemVkX25hbWUkKCk7XG4iCisgICAgICAifVxuIik7CisgIH0KKworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgJHR5cGUkIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAiICByZXR1cm4gaW5zdGFuY2UuZ2V0JGNhcGl0YWxpemVkX25hbWUkKCk7XG4iCisgICAgIn1cbiIpOworCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIHNldCRjYXBpdGFsaXplZF9uYW1lJCgkdHlwZSQgdmFsdWUpIHtcbiIKKyAgICAiICBjb3B5T25Xcml0ZSgpO1xuIgorICAgICIgIGluc3RhbmNlLnNldCRjYXBpdGFsaXplZF9uYW1lJCh2YWx1ZSk7XG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGNsZWFyJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgIGNvcHlPbldyaXRlKCk7XG4iCisgICAgIiAgaW5zdGFuY2UuY2xlYXIkY2FwaXRhbGl6ZWRfbmFtZSQoKTtcbiIKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlUHJpbWl0aXZlT25lb2ZGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVCdWlsZGluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gbm9vcCBmb3IgcHJpbWl0aXZlcworfQorCit2b2lkIEltbXV0YWJsZVByaW1pdGl2ZU9uZW9mRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAic2V0JGNhcGl0YWxpemVkX25hbWUkKG90aGVyLmdldCRjYXBpdGFsaXplZF9uYW1lJCgpKTtcbiIpOworfQorCit2b2lkIEltbXV0YWJsZVByaW1pdGl2ZU9uZW9mRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJHNldF9vbmVvZl9jYXNlX21lc3NhZ2UkO1xuIgorICAgICIkb25lb2ZfbmFtZSRfID0gaW5wdXQucmVhZCRjYXBpdGFsaXplZF90eXBlJCgpO1xuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlUHJpbWl0aXZlT25lb2ZGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iCisgICAgIiAgb3V0cHV0LndyaXRlJGNhcGl0YWxpemVkX3R5cGUkKFxuIgorICAgICIgICAgICAkbnVtYmVyJCwgKCR0eXBlJCkoKCRib3hlZF90eXBlJCkgJG9uZW9mX25hbWUkXykpO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVQcmltaXRpdmVPbmVvZkZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iCisgICAgIiAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtXG4iCisgICAgIiAgICAuY29tcHV0ZSRjYXBpdGFsaXplZF90eXBlJFNpemUoXG4iCisgICAgIiAgICAgICAgJG51bWJlciQsICgkdHlwZSQpKCgkYm94ZWRfdHlwZSQpICRvbmVvZl9uYW1lJF8pKTtcbiIKKyAgICAifVxuIik7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworUmVwZWF0ZWRJbW11dGFibGVQcmltaXRpdmVGaWVsZExpdGVHZW5lcmF0b3I6OgorUmVwZWF0ZWRJbW11dGFibGVQcmltaXRpdmVGaWVsZExpdGVHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYnVpbGRlckJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb250ZXh0KiBjb250ZXh0KQorICA6IGRlc2NyaXB0b3JfKGRlc2NyaXB0b3IpLCBtZXNzYWdlQml0SW5kZXhfKG1lc3NhZ2VCaXRJbmRleCksCisgICAgYnVpbGRlckJpdEluZGV4XyhidWlsZGVyQml0SW5kZXgpLCBjb250ZXh0Xyhjb250ZXh0KSwKKyAgICBuYW1lX3Jlc29sdmVyXyhjb250ZXh0LT5HZXROYW1lUmVzb2x2ZXIoKSkgeworICBTZXRQcmltaXRpdmVWYXJpYWJsZXMoZGVzY3JpcHRvciwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LT5HZXRGaWVsZEdlbmVyYXRvckluZm8oZGVzY3JpcHRvciksCisgICAgICAgICAgICAgICAgICAgICAgICBuYW1lX3Jlc29sdmVyXywgJnZhcmlhYmxlc18pOworfQorCitSZXBlYXRlZEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkTGl0ZUdlbmVyYXRvcjo6Cit+UmVwZWF0ZWRJbW11dGFibGVQcmltaXRpdmVGaWVsZExpdGVHZW5lcmF0b3IoKSB7fQorCitpbnQgUmVwZWF0ZWRJbW11dGFibGVQcmltaXRpdmVGaWVsZExpdGVHZW5lcmF0b3I6OkdldE51bUJpdHNGb3JNZXNzYWdlKCkgY29uc3QgeworICByZXR1cm4gMDsKK30KKworaW50IFJlcGVhdGVkSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRMaXRlR2VuZXJhdG9yOjpHZXROdW1CaXRzRm9yQnVpbGRlcigpIGNvbnN0IHsKKyAgcmV0dXJuIDA7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVQcmltaXRpdmVGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVJbnRlcmZhY2VNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJGphdmEudXRpbC5MaXN0PCRib3hlZF90eXBlJD4gZ2V0JGNhcGl0YWxpemVkX25hbWUkTGlzdCgpO1xuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJGludCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRDb3VudCgpO1xuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJCR0eXBlJCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoaW50IGluZGV4KTtcbiIpOworfQorCisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVQcmltaXRpdmVGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgJGZpZWxkX2xpc3RfdHlwZSQgJG5hbWUkXztcbiIpOworICBQcmludEV4dHJhRmllbGRJbmZvKHZhcmlhYmxlc18sIHByaW50ZXIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgamF2YS51dGlsLkxpc3Q8JGJveGVkX3R5cGUkPlxuIgorICAgICIgICAgZ2V0JGNhcGl0YWxpemVkX25hbWUkTGlzdCgpIHtcbiIKKyAgICAiICByZXR1cm4gJG5hbWUkXztcbiIgICAvLyBub3RlOiAgdW5tb2RpZmlhYmxlIGxpc3QKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBpbnQgZ2V0JGNhcGl0YWxpemVkX25hbWUkQ291bnQoKSB7XG4iCisgICAgIiAgcmV0dXJuICRuYW1lJF8uc2l6ZSgpO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljICR0eXBlJCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoaW50IGluZGV4KSB7XG4iCisgICAgIiAgcmV0dXJuICRyZXBlYXRlZF9nZXQkKGluZGV4KTtcbiIKKyAgICAifVxuIik7CisKKyAgaWYgKGRlc2NyaXB0b3JfLT5vcHRpb25zKCkucGFja2VkKCkgJiYKKyAgICAgIEhhc0dlbmVyYXRlZE1ldGhvZHMoZGVzY3JpcHRvcl8tPmNvbnRhaW5pbmdfdHlwZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAicHJpdmF0ZSBpbnQgJG5hbWUkTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xO1xuIik7CisgIH0KKworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIHZvaWQgZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCkge1xuIgorICAgICIgIGlmICghJGlzX211dGFibGUkKSB7XG4iCisgICAgIiAgICAkbmFtZSRfID0gJG5ld19saXN0JCgkbmFtZSRfKTtcbiIKKyAgICAiICAgfVxuIgorICAgICJ9XG4iKTsKKworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgdm9pZCBzZXQkY2FwaXRhbGl6ZWRfbmFtZSQoXG4iCisgICAgIiAgICBpbnQgaW5kZXgsICR0eXBlJCB2YWx1ZSkge1xuIgorICAgICIkbnVsbF9jaGVjayQiCisgICAgIiAgZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCk7XG4iCisgICAgIiAgJHJlcGVhdGVkX3NldCQoaW5kZXgsIHZhbHVlKTtcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHJpdmF0ZSB2b2lkIGFkZCRjYXBpdGFsaXplZF9uYW1lJCgkdHlwZSQgdmFsdWUpIHtcbiIKKyAgICAiJG51bGxfY2hlY2skIgorICAgICIgIGVuc3VyZSRjYXBpdGFsaXplZF9uYW1lJElzTXV0YWJsZSgpO1xuIgorICAgICIgICRyZXBlYXRlZF9hZGQkKHZhbHVlKTtcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHJpdmF0ZSB2b2lkIGFkZEFsbCRjYXBpdGFsaXplZF9uYW1lJChcbiIKKyAgICAiICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgJGJveGVkX3R5cGUkPiB2YWx1ZXMpIHtcbiIKKyAgICAiICBlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKTtcbiIKKyAgICAiICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuYWRkQWxsKFxuIgorICAgICIgICAgICB2YWx1ZXMsICRuYW1lJF8pO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIHZvaWQgY2xlYXIkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgJG5hbWUkXyA9ICRlbXB0eV9saXN0JDtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVQcmltaXRpdmVGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgamF2YS51dGlsLkxpc3Q8JGJveGVkX3R5cGUkPlxuIgorICAgICIgICAgZ2V0JGNhcGl0YWxpemVkX25hbWUkTGlzdCgpIHtcbiIKKyAgICAiICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoXG4iCisgICAgIiAgICAgIGluc3RhbmNlLmdldCRjYXBpdGFsaXplZF9uYW1lJExpc3QoKSk7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgaW50IGdldCRjYXBpdGFsaXplZF9uYW1lJENvdW50KCkge1xuIgorICAgICIgIHJldHVybiBpbnN0YW5jZS5nZXQkY2FwaXRhbGl6ZWRfbmFtZSRDb3VudCgpO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljICR0eXBlJCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoaW50IGluZGV4KSB7XG4iCisgICAgIiAgcmV0dXJuIGluc3RhbmNlLmdldCRjYXBpdGFsaXplZF9uYW1lJChpbmRleCk7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBzZXQkY2FwaXRhbGl6ZWRfbmFtZSQoXG4iCisgICAgIiAgICBpbnQgaW5kZXgsICR0eXBlJCB2YWx1ZSkge1xuIgorICAgICIgIGNvcHlPbldyaXRlKCk7XG4iCisgICAgIiAgaW5zdGFuY2Uuc2V0JGNhcGl0YWxpemVkX25hbWUkKGluZGV4LCB2YWx1ZSk7XG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBhZGQkY2FwaXRhbGl6ZWRfbmFtZSQoJHR5cGUkIHZhbHVlKSB7XG4iCisgICAgIiAgY29weU9uV3JpdGUoKTtcbiIKKyAgICAiICBpbnN0YW5jZS5hZGQkY2FwaXRhbGl6ZWRfbmFtZSQodmFsdWUpO1xuIgorICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgYWRkQWxsJGNhcGl0YWxpemVkX25hbWUkKFxuIgorICAgICIgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyAkYm94ZWRfdHlwZSQ+IHZhbHVlcykge1xuIgorICAgICIgIGNvcHlPbldyaXRlKCk7XG4iCisgICAgIiAgaW5zdGFuY2UuYWRkQWxsJGNhcGl0YWxpemVkX25hbWUkKHZhbHVlcyk7XG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBjbGVhciRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAiICBjb3B5T25Xcml0ZSgpO1xuIgorICAgICIgIGluc3RhbmNlLmNsZWFyJGNhcGl0YWxpemVkX25hbWUkKCk7XG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlRmllbGRCdWlsZGVySW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSAgY29uc3QgeworICAvLyBub29wIGZvciBwcmltaXRpdmVzCit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVQcmltaXRpdmVGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgIiRuYW1lJF8gPSAkZW1wdHlfbGlzdCQ7XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUJ1aWxkZXJDbGVhckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gbm9vcCBmb3IgcHJpbWl0aXZlcworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gVGhlIGNvZGUgYmVsb3cgZG9lcyB0d28gb3B0aW1pemF0aW9uczoKKyAgLy8gICAxLiBJZiB0aGUgb3RoZXIgbGlzdCBpcyBlbXB0eSwgdGhlcmUncyBub3RoaW5nIHRvIGRvLiBUaGlzIGVuc3VyZXMgd2UKKyAgLy8gICAgICBkb24ndCBhbGxvY2F0ZSBhIG5ldyBhcnJheSBpZiB3ZSBhbHJlYWR5IGhhdmUgYW4gaW1tdXRhYmxlIG9uZS4KKyAgLy8gICAyLiBJZiB0aGUgb3RoZXIgbGlzdCBpcyBub24tZW1wdHkgYW5kIG91ciBjdXJyZW50IGxpc3QgaXMgZW1wdHksIHdlIGNhbgorICAvLyAgICAgIHJldXNlIHRoZSBvdGhlciBsaXN0IHdoaWNoIGlzIGd1YXJhbnRlZWQgdG8gYmUgaW1tdXRhYmxlLgorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoIW90aGVyLiRuYW1lJF8uaXNFbXB0eSgpKSB7XG4iCisgICAgIiAgaWYgKCRuYW1lJF8uaXNFbXB0eSgpKSB7XG4iCisgICAgIiAgICAkbmFtZSRfID0gb3RoZXIuJG5hbWUkXztcbiIKKyAgICAiICB9IGVsc2Uge1xuIgorICAgICIgICAgZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCk7XG4iCisgICAgIiAgICAkbmFtZSRfLmFkZEFsbChvdGhlci4kbmFtZSRfKTtcbiIKKyAgICAiICB9XG4iCisgICAgIiAgJG9uX2NoYW5nZWQkXG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIG5vb3AgZm9yIHByaW1pdGl2ZXMKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUR5bmFtaWNNZXRob2RNYWtlSW1tdXRhYmxlQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkbmFtZSRfLm1ha2VJbW11dGFibGUoKTtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gVE9ETyhkd2Vpcyk6IFNjYW4gdGhlIGlucHV0IGJ1ZmZlciB0byBjb3VudCwgdGhlbiBpbml0aWFsaXplCisgIC8vIGFwcHJvcHJpYXRlbHkuCisgIC8vIFRPRE8oZHdlaXMpOiBTY2FuIHRoZSBpbnB1dCBidWZmZXIgdG8gY291bnQgYW5kIGVuc3VyZSBjYXBhY2l0eS4KKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCEkaXNfbXV0YWJsZSQpIHtcbiIKKyAgICAiICAkbmFtZSRfID0gJG5ld19saXN0JCgpO1xuIgorICAgICJ9XG4iCisgICAgIiRyZXBlYXRlZF9hZGQkKGlucHV0LnJlYWQkY2FwaXRhbGl6ZWRfdHlwZSQoKSk7XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZVBhcnNpbmdDb2RlRnJvbVBhY2tlZChpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7XG4iCisgICAgImludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpO1xuIgorICAgICJpZiAoISRpc19tdXRhYmxlJCAmJiBpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHtcbiIpOworCisgIGludCBmaXhlZF9zaXplID0gRml4ZWRTaXplKEdldFR5cGUoZGVzY3JpcHRvcl8pKTsKKyAgaWYgKGZpeGVkX3NpemUgPT0gLTEpIHsKKyAgICAvLyBUT0RPKGR3ZWlzKTogU2NhbiB0aGUgaW5wdXQgYnVmZmVyIHRvIGNvdW50LCB0aGVuIGluaXRpYWxpemUKKyAgICAvLyBhcHByb3ByaWF0ZWx5LgorICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiICAkbmFtZSRfID0gJG5ld19saXN0JCgpO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIgICRuYW1lJF8gPSAkbmV3X2xpc3Rfd2l0aF9jYXBhY2l0eSQobGVuZ3RoLyRmaXhlZF9zaXplJCk7XG4iKTsKKyAgfQorCisgIC8vIFRPRE8oZHdlaXMpOiBTY2FuIHRoZSBpbnB1dCBidWZmZXIgdG8gY291bnQgYW5kIGVuc3VyZSBjYXBhY2l0eS4KKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAifVxuIgorICAgICJ3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7XG4iCisgICAgIiAgJHJlcGVhdGVkX2FkZCQoaW5wdXQucmVhZCRjYXBpdGFsaXplZF90eXBlJCgpKTtcbiIKKyAgICAifVxuIgorICAgICJpbnB1dC5wb3BMaW1pdChsaW1pdCk7XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZVBhcnNpbmdEb25lQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoJGlzX211dGFibGUkKSB7XG4iCisgICAgIiAgJG1ha2VfbmFtZV91bm1vZGlmaWFibGUkO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChkZXNjcmlwdG9yXy0+b3B0aW9ucygpLnBhY2tlZCgpKSB7CisgICAgLy8gV2UgaW52b2tlIGdldFNlcmlhbGl6ZWRTaXplIGluIHdyaXRlVG8gZm9yIG1lc3NhZ2VzIHRoYXQgaGF2ZSBwYWNrZWQKKyAgICAvLyBmaWVsZHMgaW4gSW1tdXRhYmxlTWVzc2FnZUdlbmVyYXRvcjo6R2VuZXJhdGVNZXNzYWdlU2VyaWFsaXphdGlvbk1ldGhvZHMuCisgICAgLy8gVGhhdCBtYWtlcyBpdCBzYWZlIHRvIHJlbHkgb24gdGhlIG1lbW9pemVkIHNpemUgaGVyZS4KKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImlmIChnZXQkY2FwaXRhbGl6ZWRfbmFtZSRMaXN0KCkuc2l6ZSgpID4gMCkge1xuIgorICAgICAgIiAgb3V0cHV0LndyaXRlUmF3VmFyaW50MzIoJHRhZyQpO1xuIgorICAgICAgIiAgb3V0cHV0LndyaXRlUmF3VmFyaW50MzIoJG5hbWUkTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7XG4iCisgICAgICAifVxuIgorICAgICAgImZvciAoaW50IGkgPSAwOyBpIDwgJG5hbWUkXy5zaXplKCk7IGkrKykge1xuIgorICAgICAgIiAgb3V0cHV0LndyaXRlJGNhcGl0YWxpemVkX3R5cGUkTm9UYWcoJHJlcGVhdGVkX2dldCQoaSkpO1xuIgorICAgICAgIn1cbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiZm9yIChpbnQgaSA9IDA7IGkgPCAkbmFtZSRfLnNpemUoKTsgaSsrKSB7XG4iCisgICAgICAiICBvdXRwdXQud3JpdGUkY2FwaXRhbGl6ZWRfdHlwZSQoJG51bWJlciQsICRyZXBlYXRlZF9nZXQkKGkpKTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIntcbiIKKyAgICAiICBpbnQgZGF0YVNpemUgPSAwO1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIGlmIChGaXhlZFNpemUoR2V0VHlwZShkZXNjcmlwdG9yXykpID09IC0xKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJmb3IgKGludCBpID0gMDsgaSA8ICRuYW1lJF8uc2l6ZSgpOyBpKyspIHtcbiIKKyAgICAgICIgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW1cbiIKKyAgICAgICIgICAgLmNvbXB1dGUkY2FwaXRhbGl6ZWRfdHlwZSRTaXplTm9UYWcoJHJlcGVhdGVkX2dldCQoaSkpO1xuIgorICAgICAgIn1cbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiZGF0YVNpemUgPSAkZml4ZWRfc2l6ZSQgKiBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRMaXN0KCkuc2l6ZSgpO1xuIik7CisgIH0KKworICBwcmludGVyLT5QcmludCgKKyAgICAgICJzaXplICs9IGRhdGFTaXplO1xuIik7CisKKyAgaWYgKGRlc2NyaXB0b3JfLT5vcHRpb25zKCkucGFja2VkKCkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImlmICghZ2V0JGNhcGl0YWxpemVkX25hbWUkTGlzdCgpLmlzRW1wdHkoKSkge1xuIgorICAgICAgIiAgc2l6ZSArPSAkdGFnX3NpemUkO1xuIgorICAgICAgIiAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtXG4iCisgICAgICAiICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7XG4iCisgICAgICAifVxuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJzaXplICs9ICR0YWdfc2l6ZSQgKiBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRMaXN0KCkuc2l6ZSgpO1xuIik7CisgIH0KKworICAvLyBjYWNoZSB0aGUgZGF0YSBzaXplIGZvciBwYWNrZWQgZmllbGRzLgorICBpZiAoZGVzY3JpcHRvcl8tPm9wdGlvbnMoKS5wYWNrZWQoKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJG5hbWUkTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplO1xuIik7CisgIH0KKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KCJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUVxdWFsc0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicmVzdWx0ID0gcmVzdWx0ICYmIGdldCRjYXBpdGFsaXplZF9uYW1lJExpc3QoKVxuIgorICAgICIgICAgLmVxdWFscyhvdGhlci5nZXQkY2FwaXRhbGl6ZWRfbmFtZSRMaXN0KCkpO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVQcmltaXRpdmVGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVIYXNoQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoZ2V0JGNhcGl0YWxpemVkX25hbWUkQ291bnQoKSA+IDApIHtcbiIKKyAgICAiICBoYXNoID0gKDM3ICogaGFzaCkgKyAkY29uc3RhbnRfbmFtZSQ7XG4iCisgICAgIiAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0JGNhcGl0YWxpemVkX25hbWUkTGlzdCgpLmhhc2hDb2RlKCk7XG4iCisgICAgIn1cbiIpOworfQorCitzdHJpbmcgUmVwZWF0ZWRJbW11dGFibGVQcmltaXRpdmVGaWVsZExpdGVHZW5lcmF0b3I6OkdldEJveGVkVHlwZSgpIGNvbnN0IHsKKyAgcmV0dXJuIEJveGVkUHJpbWl0aXZlVHlwZU5hbWUoR2V0SmF2YVR5cGUoZGVzY3JpcHRvcl8pKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9wcmltaXRpdmVfZmllbGRfbGl0ZS5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfcHJpbWl0aXZlX2ZpZWxkX2xpdGUuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hZDYwM2MyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfcHJpbWl0aXZlX2ZpZWxkX2xpdGUuaApAQCAtMCwwICsxLDE2MyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX1BSSU1JVElWRV9GSUVMRF9MSVRFX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9QUklNSVRJVkVfRklFTERfTElURV9IX18KKworI2luY2x1ZGUgPG1hcD4KKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9maWVsZC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisgIG5hbWVzcGFjZSBjb21waWxlciB7CisgICAgbmFtZXNwYWNlIGphdmEgeworICAgICAgY2xhc3MgQ29udGV4dDsgICAgICAgICAgIC8vIGNvbnRleHQuaAorICAgICAgY2xhc3MgQ2xhc3NOYW1lUmVzb2x2ZXI7IC8vIG5hbWVfcmVzb2x2ZXIuaAorICAgIH0KKyAgfQorfQorCituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhIHsKKworY2xhc3MgSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRMaXRlR2VuZXJhdG9yCisgICAgOiBwdWJsaWMgSW1tdXRhYmxlRmllbGRMaXRlR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IEltbXV0YWJsZVByaW1pdGl2ZUZpZWxkTGl0ZUdlbmVyYXRvcigKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwgaW50IG1lc3NhZ2VCaXRJbmRleCwKKyAgICAgIGludCBidWlsZGVyQml0SW5kZXgsIENvbnRleHQqIGNvbnRleHQpOworICB+SW1tdXRhYmxlUHJpbWl0aXZlRmllbGRMaXRlR2VuZXJhdG9yKCk7CisKKyAgLy8gaW1wbGVtZW50cyBJbW11dGFibGVGaWVsZExpdGVHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIGludCBHZXROdW1CaXRzRm9yTWVzc2FnZSgpIGNvbnN0OworICBpbnQgR2V0TnVtQml0c0ZvckJ1aWxkZXIoKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUludGVyZmFjZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnVpbGRlckNsZWFyQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCdWlsZGluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRHluYW1pY01ldGhvZE1ha2VJbW11dGFibGVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVBhcnNpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVBhcnNpbmdEb25lQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRmllbGRCdWlsZGVySW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUVxdWFsc0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSGFzaENvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgIHN0cmluZyBHZXRCb3hlZFR5cGUoKSBjb25zdDsKKworIHByb3RlY3RlZDoKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXNfOworICBjb25zdCBpbnQgbWVzc2FnZUJpdEluZGV4XzsKKyAgY29uc3QgaW50IGJ1aWxkZXJCaXRJbmRleF87CisgIENvbnRleHQqIGNvbnRleHRfOworICBDbGFzc05hbWVSZXNvbHZlciogbmFtZV9yZXNvbHZlcl87CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRMaXRlR2VuZXJhdG9yKTsKK307CisKK2NsYXNzIEltbXV0YWJsZVByaW1pdGl2ZU9uZW9mRmllbGRMaXRlR2VuZXJhdG9yCisgICAgOiBwdWJsaWMgSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRMaXRlR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIEltbXV0YWJsZVByaW1pdGl2ZU9uZW9mRmllbGRMaXRlR2VuZXJhdG9yKAorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwgQ29udGV4dCogY29udGV4dCk7CisgIH5JbW11dGFibGVQcmltaXRpdmVPbmVvZkZpZWxkTGl0ZUdlbmVyYXRvcigpOworCisgIHZvaWQgR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUJ1aWxkZXJNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUJ1aWxkaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVQYXJzaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEltbXV0YWJsZVByaW1pdGl2ZU9uZW9mRmllbGRMaXRlR2VuZXJhdG9yKTsKK307CisKK2NsYXNzIFJlcGVhdGVkSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRMaXRlR2VuZXJhdG9yCisgICAgOiBwdWJsaWMgSW1tdXRhYmxlRmllbGRMaXRlR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IFJlcGVhdGVkSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRMaXRlR2VuZXJhdG9yKAorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwgQ29udGV4dCogY29udGV4dCk7CisgIHZpcnR1YWwgflJlcGVhdGVkSW1tdXRhYmxlUHJpbWl0aXZlRmllbGRMaXRlR2VuZXJhdG9yKCk7CisKKyAgLy8gaW1wbGVtZW50cyBJbW11dGFibGVGaWVsZExpdGVHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIGludCBHZXROdW1CaXRzRm9yTWVzc2FnZSgpIGNvbnN0OworICBpbnQgR2V0TnVtQml0c0ZvckJ1aWxkZXIoKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUludGVyZmFjZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnVpbGRlckNsZWFyQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCdWlsZGluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRHluYW1pY01ldGhvZE1ha2VJbW11dGFibGVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVBhcnNpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVBhcnNpbmdDb2RlRnJvbVBhY2tlZChpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVQYXJzaW5nRG9uZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUZpZWxkQnVpbGRlckluaXRpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVFcXVhbHNDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUhhc2hDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKworICBzdHJpbmcgR2V0Qm94ZWRUeXBlKCkgY29uc3Q7CisKKyBwcml2YXRlOgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlc187CisgIGNvbnN0IGludCBtZXNzYWdlQml0SW5kZXhfOworICBjb25zdCBpbnQgYnVpbGRlckJpdEluZGV4XzsKKyAgQ29udGV4dCogY29udGV4dF87CisgIENsYXNzTmFtZVJlc29sdmVyKiBuYW1lX3Jlc29sdmVyXzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoUmVwZWF0ZWRJbW11dGFibGVQcmltaXRpdmVGaWVsZExpdGVHZW5lcmF0b3IpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfUFJJTUlUSVZFX0ZJRUxEX0xJVEVfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9zZXJ2aWNlLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfc2VydmljZS5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMWJmYzEyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfc2VydmljZS5jYwpAQCAtMCwwICsxLDQ3MiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9zZXJ2aWNlLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2NvbnRleHQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2RvY19jb21tZW50Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9uYW1lX3Jlc29sdmVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmEgeworCitTZXJ2aWNlR2VuZXJhdG9yOjpTZXJ2aWNlR2VuZXJhdG9yKGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKQorICA6IGRlc2NyaXB0b3JfKGRlc2NyaXB0b3IpIHt9CisKK1NlcnZpY2VHZW5lcmF0b3I6On5TZXJ2aWNlR2VuZXJhdG9yKCkge30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorSW1tdXRhYmxlU2VydmljZUdlbmVyYXRvcjo6SW1tdXRhYmxlU2VydmljZUdlbmVyYXRvcigKKyAgICBjb25zdCBTZXJ2aWNlRGVzY3JpcHRvciogZGVzY3JpcHRvciwgQ29udGV4dCogY29udGV4dCkKKyAgICA6IFNlcnZpY2VHZW5lcmF0b3IoZGVzY3JpcHRvciksIGNvbnRleHRfKGNvbnRleHQpLAorICAgIG5hbWVfcmVzb2x2ZXJfKGNvbnRleHQtPkdldE5hbWVSZXNvbHZlcigpKSB7fQorCitJbW11dGFibGVTZXJ2aWNlR2VuZXJhdG9yOjp+SW1tdXRhYmxlU2VydmljZUdlbmVyYXRvcigpIHt9CisKK3ZvaWQgSW1tdXRhYmxlU2VydmljZUdlbmVyYXRvcjo6R2VuZXJhdGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgYm9vbCBpc19vd25fZmlsZSA9CisgICAgTXVsdGlwbGVKYXZhRmlsZXMoZGVzY3JpcHRvcl8tPmZpbGUoKSwgLyogaW1tdXRhYmxlID0gKi8gdHJ1ZSk7CisgIFdyaXRlU2VydmljZURvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCgKKyAgICAicHVibGljICRzdGF0aWMkIGFic3RyYWN0IGNsYXNzICRjbGFzc25hbWUkXG4iCisgICAgIiAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuU2VydmljZSB7XG4iLAorICAgICJzdGF0aWMiLCBpc19vd25fZmlsZSA/ICIiIDogInN0YXRpYyIsCisgICAgImNsYXNzbmFtZSIsIGRlc2NyaXB0b3JfLT5uYW1lKCkpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAicHJvdGVjdGVkICRjbGFzc25hbWUkKCkge31cblxuIiwKKyAgICAiY2xhc3NuYW1lIiwgZGVzY3JpcHRvcl8tPm5hbWUoKSk7CisKKyAgR2VuZXJhdGVJbnRlcmZhY2UocHJpbnRlcik7CisKKyAgR2VuZXJhdGVOZXdSZWZsZWN0aXZlU2VydmljZU1ldGhvZChwcmludGVyKTsKKyAgR2VuZXJhdGVOZXdSZWZsZWN0aXZlQmxvY2tpbmdTZXJ2aWNlTWV0aG9kKHByaW50ZXIpOworCisgIEdlbmVyYXRlQWJzdHJhY3RNZXRob2RzKHByaW50ZXIpOworCisgIC8vIEdlbmVyYXRlIGdldERlc2NyaXB0b3IoKSBhbmQgZ2V0RGVzY3JpcHRvckZvclR5cGUoKS4KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgInB1YmxpYyBzdGF0aWMgZmluYWxcbiIKKyAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuU2VydmljZURlc2NyaXB0b3JcbiIKKyAgICAiICAgIGdldERlc2NyaXB0b3IoKSB7XG4iCisgICAgIiAgcmV0dXJuICRmaWxlJC5nZXREZXNjcmlwdG9yKCkuZ2V0U2VydmljZXMoKS5nZXQoJGluZGV4JCk7XG4iCisgICAgIn1cbiIsCisgICAgImZpbGUiLCBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKGRlc2NyaXB0b3JfLT5maWxlKCkpLAorICAgICJpbmRleCIsIFNpbXBsZUl0b2EoZGVzY3JpcHRvcl8tPmluZGV4KCkpKTsKKyAgR2VuZXJhdGVHZXREZXNjcmlwdG9yRm9yVHlwZShwcmludGVyKTsKKworICAvLyBHZW5lcmF0ZSBtb3JlIHN0dWZmLgorICBHZW5lcmF0ZUNhbGxNZXRob2QocHJpbnRlcik7CisgIEdlbmVyYXRlR2V0UHJvdG90eXBlKFJFUVVFU1QsIHByaW50ZXIpOworICBHZW5lcmF0ZUdldFByb3RvdHlwZShSRVNQT05TRSwgcHJpbnRlcik7CisgIEdlbmVyYXRlU3R1YihwcmludGVyKTsKKyAgR2VuZXJhdGVCbG9ja2luZ1N0dWIocHJpbnRlcik7CisKKyAgLy8gQWRkIGFuIGluc2VydGlvbiBwb2ludC4KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIlxuIgorICAgICIvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6JGZ1bGxfbmFtZSQpXG4iLAorICAgICJmdWxsX25hbWUiLCBkZXNjcmlwdG9yXy0+ZnVsbF9uYW1lKCkpOworCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoIn1cblxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlU2VydmljZUdlbmVyYXRvcjo6R2VuZXJhdGVHZXREZXNjcmlwdG9yRm9yVHlwZSgKKyAgICBpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICAicHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuU2VydmljZURlc2NyaXB0b3JcbiIKKyAgICAiICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkge1xuIgorICAgICIgIHJldHVybiBnZXREZXNjcmlwdG9yKCk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZVNlcnZpY2VHZW5lcmF0b3I6OkdlbmVyYXRlSW50ZXJmYWNlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KCJwdWJsaWMgaW50ZXJmYWNlIEludGVyZmFjZSB7XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisgIEdlbmVyYXRlQWJzdHJhY3RNZXRob2RzKHByaW50ZXIpOworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KCJ9XG5cbiIpOworfQorCit2b2lkIEltbXV0YWJsZVNlcnZpY2VHZW5lcmF0b3I6OkdlbmVyYXRlTmV3UmVmbGVjdGl2ZVNlcnZpY2VNZXRob2QoCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgInB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlIG5ld1JlZmxlY3RpdmVTZXJ2aWNlKFxuIgorICAgICIgICAgZmluYWwgSW50ZXJmYWNlIGltcGwpIHtcbiIKKyAgICAiICByZXR1cm4gbmV3ICRjbGFzc25hbWUkKCkge1xuIiwKKyAgICAiY2xhc3NuYW1lIiwgZGVzY3JpcHRvcl8tPm5hbWUoKSk7CisgIHByaW50ZXItPkluZGVudCgpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5tZXRob2RfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgTWV0aG9kRGVzY3JpcHRvciogbWV0aG9kID0gZGVzY3JpcHRvcl8tPm1ldGhvZChpKTsKKyAgICBwcmludGVyLT5QcmludCgiQGphdmEubGFuZy5PdmVycmlkZVxuIik7CisgICAgR2VuZXJhdGVNZXRob2RTaWduYXR1cmUocHJpbnRlciwgbWV0aG9kLCBJU19DT05DUkVURSk7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiIHtcbiIKKyAgICAgICIgIGltcGwuJG1ldGhvZCQoY29udHJvbGxlciwgcmVxdWVzdCwgZG9uZSk7XG4iCisgICAgICAifVxuXG4iLAorICAgICAgIm1ldGhvZCIsIFVuZGVyc2NvcmVzVG9DYW1lbENhc2UobWV0aG9kKSk7CisgIH0KKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KCJ9O1xuIik7CisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoIn1cblxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlU2VydmljZUdlbmVyYXRvcjo6R2VuZXJhdGVOZXdSZWZsZWN0aXZlQmxvY2tpbmdTZXJ2aWNlTWV0aG9kKAorICAgIGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgICJwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuQmxvY2tpbmdTZXJ2aWNlXG4iCisgICAgIiAgICBuZXdSZWZsZWN0aXZlQmxvY2tpbmdTZXJ2aWNlKGZpbmFsIEJsb2NraW5nSW50ZXJmYWNlIGltcGwpIHtcbiIKKyAgICAiICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQmxvY2tpbmdTZXJ2aWNlKCkge1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBHZW5lcmF0ZUdldERlc2NyaXB0b3JGb3JUeXBlKHByaW50ZXIpOworCisgIEdlbmVyYXRlQ2FsbEJsb2NraW5nTWV0aG9kKHByaW50ZXIpOworICBHZW5lcmF0ZUdldFByb3RvdHlwZShSRVFVRVNULCBwcmludGVyKTsKKyAgR2VuZXJhdGVHZXRQcm90b3R5cGUoUkVTUE9OU0UsIHByaW50ZXIpOworCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoIn07XG4iKTsKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgifVxuXG4iKTsKK30KKwordm9pZCBJbW11dGFibGVTZXJ2aWNlR2VuZXJhdG9yOjpHZW5lcmF0ZUFic3RyYWN0TWV0aG9kcyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5tZXRob2RfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgTWV0aG9kRGVzY3JpcHRvciogbWV0aG9kID0gZGVzY3JpcHRvcl8tPm1ldGhvZChpKTsKKyAgICBXcml0ZU1ldGhvZERvY0NvbW1lbnQocHJpbnRlciwgbWV0aG9kKTsKKyAgICBHZW5lcmF0ZU1ldGhvZFNpZ25hdHVyZShwcmludGVyLCBtZXRob2QsIElTX0FCU1RSQUNUKTsKKyAgICBwcmludGVyLT5QcmludCgiO1xuXG4iKTsKKyAgfQorfQorCit2b2lkIEltbXV0YWJsZVNlcnZpY2VHZW5lcmF0b3I6OkdlbmVyYXRlQ2FsbE1ldGhvZChpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICAiXG4iCisgICAgInB1YmxpYyBmaW5hbCB2b2lkIGNhbGxNZXRob2QoXG4iCisgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk1ldGhvZERlc2NyaXB0b3IgbWV0aG9kLFxuIgorICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNDb250cm9sbGVyIGNvbnRyb2xsZXIsXG4iCisgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2UgcmVxdWVzdCxcbiIKKyAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuUnBjQ2FsbGJhY2s8XG4iCisgICAgIiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZT4gZG9uZSkge1xuIgorICAgICIgIGlmIChtZXRob2QuZ2V0U2VydmljZSgpICE9IGdldERlc2NyaXB0b3IoKSkge1xuIgorICAgICIgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oXG4iCisgICAgIiAgICAgIFwiU2VydmljZS5jYWxsTWV0aG9kKCkgZ2l2ZW4gbWV0aG9kIGRlc2NyaXB0b3IgZm9yIHdyb25nIFwiICtcbiIKKyAgICAiICAgICAgXCJzZXJ2aWNlIHR5cGUuXCIpO1xuIgorICAgICIgIH1cbiIKKyAgICAiICBzd2l0Y2gobWV0aG9kLmdldEluZGV4KCkpIHtcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+bWV0aG9kX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IE1ldGhvZERlc2NyaXB0b3IqIG1ldGhvZCA9IGRlc2NyaXB0b3JfLT5tZXRob2QoaSk7CisgICAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJzOworICAgIHZhcnNbImluZGV4Il0gPSBTaW1wbGVJdG9hKGkpOworICAgIHZhcnNbIm1ldGhvZCJdID0gVW5kZXJzY29yZXNUb0NhbWVsQ2FzZShtZXRob2QpOworICAgIHZhcnNbImlucHV0Il0gPSBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKAorICAgICAgICBtZXRob2QtPmlucHV0X3R5cGUoKSk7CisgICAgdmFyc1sib3V0cHV0Il0gPSBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKAorICAgICAgICBtZXRob2QtPm91dHB1dF90eXBlKCkpOworICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAiY2FzZSAkaW5kZXgkOlxuIgorICAgICAgIiAgdGhpcy4kbWV0aG9kJChjb250cm9sbGVyLCAoJGlucHV0JClyZXF1ZXN0LFxuIgorICAgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY1V0aWwuPCRvdXRwdXQkPnNwZWNpYWxpemVDYWxsYmFjayhcbiIKKyAgICAgICIgICAgICBkb25lKSk7XG4iCisgICAgICAiICByZXR1cm47XG4iKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KAorICAgICJkZWZhdWx0OlxuIgorICAgICIgIHRocm93IG5ldyBqYXZhLmxhbmcuQXNzZXJ0aW9uRXJyb3IoXCJDYW4ndCBnZXQgaGVyZS5cIik7XG4iKTsKKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPk91dGRlbnQoKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAiICB9XG4iCisgICAgIn1cbiIKKyAgICAiXG4iKTsKK30KKwordm9pZCBJbW11dGFibGVTZXJ2aWNlR2VuZXJhdG9yOjpHZW5lcmF0ZUNhbGxCbG9ja2luZ01ldGhvZCgKKyAgICBpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICAiXG4iCisgICAgInB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2UgY2FsbEJsb2NraW5nTWV0aG9kKFxuIgorICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5NZXRob2REZXNjcmlwdG9yIG1ldGhvZCxcbiIKKyAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuUnBjQ29udHJvbGxlciBjb250cm9sbGVyLFxuIgorICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIHJlcXVlc3QpXG4iCisgICAgIiAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRXhjZXB0aW9uIHtcbiIKKyAgICAiICBpZiAobWV0aG9kLmdldFNlcnZpY2UoKSAhPSBnZXREZXNjcmlwdG9yKCkpIHtcbiIKKyAgICAiICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKFxuIgorICAgICIgICAgICBcIlNlcnZpY2UuY2FsbEJsb2NraW5nTWV0aG9kKCkgZ2l2ZW4gbWV0aG9kIGRlc2NyaXB0b3IgZm9yIFwiICtcbiIKKyAgICAiICAgICAgXCJ3cm9uZyBzZXJ2aWNlIHR5cGUuXCIpO1xuIgorICAgICIgIH1cbiIKKyAgICAiICBzd2l0Y2gobWV0aG9kLmdldEluZGV4KCkpIHtcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+bWV0aG9kX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IE1ldGhvZERlc2NyaXB0b3IqIG1ldGhvZCA9IGRlc2NyaXB0b3JfLT5tZXRob2QoaSk7CisgICAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJzOworICAgIHZhcnNbImluZGV4Il0gPSBTaW1wbGVJdG9hKGkpOworICAgIHZhcnNbIm1ldGhvZCJdID0gVW5kZXJzY29yZXNUb0NhbWVsQ2FzZShtZXRob2QpOworICAgIHZhcnNbImlucHV0Il0gPSBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKAorICAgICAgICBtZXRob2QtPmlucHV0X3R5cGUoKSk7CisgICAgdmFyc1sib3V0cHV0Il0gPSBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKAorICAgICAgICBtZXRob2QtPm91dHB1dF90eXBlKCkpOworICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAiY2FzZSAkaW5kZXgkOlxuIgorICAgICAgIiAgcmV0dXJuIGltcGwuJG1ldGhvZCQoY29udHJvbGxlciwgKCRpbnB1dCQpcmVxdWVzdCk7XG4iKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KAorICAgICJkZWZhdWx0OlxuIgorICAgICIgIHRocm93IG5ldyBqYXZhLmxhbmcuQXNzZXJ0aW9uRXJyb3IoXCJDYW4ndCBnZXQgaGVyZS5cIik7XG4iKTsKKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPk91dGRlbnQoKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAiICB9XG4iCisgICAgIn1cbiIKKyAgICAiXG4iKTsKK30KKwordm9pZCBJbW11dGFibGVTZXJ2aWNlR2VuZXJhdG9yOjpHZW5lcmF0ZUdldFByb3RvdHlwZShSZXF1ZXN0T3JSZXNwb25zZSB3aGljaCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgLyoKKyAgICogVE9ETyhjcG92aXJrKTogVGhlIGV4Y2VwdGlvbiBtZXNzYWdlIHNheXMgIlNlcnZpY2UuZm9vIiB3aGVuIGl0IG1heSBiZQorICAgKiAiQmxvY2tpbmdTZXJ2aWNlLmZvby4iICBDb25zaWRlciBmaXhpbmcuCisgICAqLworICBwcmludGVyLT5QcmludCgKKyAgICAicHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZVxuIgorICAgICIgICAgZ2V0JHJlcXVlc3Rfb3JfcmVzcG9uc2UkUHJvdG90eXBlKFxuIgorICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5NZXRob2REZXNjcmlwdG9yIG1ldGhvZCkge1xuIgorICAgICIgIGlmIChtZXRob2QuZ2V0U2VydmljZSgpICE9IGdldERlc2NyaXB0b3IoKSkge1xuIgorICAgICIgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oXG4iCisgICAgIiAgICAgIFwiU2VydmljZS5nZXQkcmVxdWVzdF9vcl9yZXNwb25zZSRQcm90b3R5cGUoKSBnaXZlbiBtZXRob2QgXCIgK1xuIgorICAgICIgICAgICBcImRlc2NyaXB0b3IgZm9yIHdyb25nIHNlcnZpY2UgdHlwZS5cIik7XG4iCisgICAgIiAgfVxuIgorICAgICIgIHN3aXRjaChtZXRob2QuZ2V0SW5kZXgoKSkge1xuIiwKKyAgICAicmVxdWVzdF9vcl9yZXNwb25zZSIsICh3aGljaCA9PSBSRVFVRVNUKSA/ICJSZXF1ZXN0IiA6ICJSZXNwb25zZSIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+bWV0aG9kX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IE1ldGhvZERlc2NyaXB0b3IqIG1ldGhvZCA9IGRlc2NyaXB0b3JfLT5tZXRob2QoaSk7CisgICAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJzOworICAgIHZhcnNbImluZGV4Il0gPSBTaW1wbGVJdG9hKGkpOworICAgIHZhcnNbInR5cGUiXSA9IG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoCisgICAgICAod2hpY2ggPT0gUkVRVUVTVCkgPyBtZXRob2QtPmlucHV0X3R5cGUoKSA6IG1ldGhvZC0+b3V0cHV0X3R5cGUoKSk7CisgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICJjYXNlICRpbmRleCQ6XG4iCisgICAgICAiICByZXR1cm4gJHR5cGUkLmdldERlZmF1bHRJbnN0YW5jZSgpO1xuIik7CisgIH0KKworICBwcmludGVyLT5QcmludCgKKyAgICAiZGVmYXVsdDpcbiIKKyAgICAiICB0aHJvdyBuZXcgamF2YS5sYW5nLkFzc2VydGlvbkVycm9yKFwiQ2FuJ3QgZ2V0IGhlcmUuXCIpO1xuIik7CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5PdXRkZW50KCk7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIiAgfVxuIgorICAgICJ9XG4iCisgICAgIlxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlU2VydmljZUdlbmVyYXRvcjo6R2VuZXJhdGVTdHViKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgICJwdWJsaWMgc3RhdGljIFN0dWIgbmV3U3R1YihcbiIKKyAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuUnBjQ2hhbm5lbCBjaGFubmVsKSB7XG4iCisgICAgIiAgcmV0dXJuIG5ldyBTdHViKGNoYW5uZWwpO1xuIgorICAgICJ9XG4iCisgICAgIlxuIgorICAgICJwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFN0dWIgZXh0ZW5kcyAkY2xhc3NuYW1lJCBpbXBsZW1lbnRzIEludGVyZmFjZSB7IgorICAgICJcbiIsCisgICAgImNsYXNzbmFtZSIsIG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoZGVzY3JpcHRvcl8pKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgInByaXZhdGUgU3R1Yihjb20uZ29vZ2xlLnByb3RvYnVmLlJwY0NoYW5uZWwgY2hhbm5lbCkge1xuIgorICAgICIgIHRoaXMuY2hhbm5lbCA9IGNoYW5uZWw7XG4iCisgICAgIn1cbiIKKyAgICAiXG4iCisgICAgInByaXZhdGUgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNDaGFubmVsIGNoYW5uZWw7XG4iCisgICAgIlxuIgorICAgICJwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNDaGFubmVsIGdldENoYW5uZWwoKSB7XG4iCisgICAgIiAgcmV0dXJuIGNoYW5uZWw7XG4iCisgICAgIn1cbiIpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPm1ldGhvZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBNZXRob2REZXNjcmlwdG9yKiBtZXRob2QgPSBkZXNjcmlwdG9yXy0+bWV0aG9kKGkpOworICAgIHByaW50ZXItPlByaW50KCJcbiIpOworICAgIEdlbmVyYXRlTWV0aG9kU2lnbmF0dXJlKHByaW50ZXIsIG1ldGhvZCwgSVNfQ09OQ1JFVEUpOworICAgIHByaW50ZXItPlByaW50KCIge1xuIik7CisgICAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcnM7CisgICAgdmFyc1siaW5kZXgiXSA9IFNpbXBsZUl0b2EoaSk7CisgICAgdmFyc1sib3V0cHV0Il0gPSBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKAorICAgICAgICBtZXRob2QtPm91dHB1dF90eXBlKCkpOworICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAiY2hhbm5lbC5jYWxsTWV0aG9kKFxuIgorICAgICAgIiAgZ2V0RGVzY3JpcHRvcigpLmdldE1ldGhvZHMoKS5nZXQoJGluZGV4JCksXG4iCisgICAgICAiICBjb250cm9sbGVyLFxuIgorICAgICAgIiAgcmVxdWVzdCxcbiIKKyAgICAgICIgICRvdXRwdXQkLmdldERlZmF1bHRJbnN0YW5jZSgpLFxuIgorICAgICAgIiAgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNVdGlsLmdlbmVyYWxpemVDYWxsYmFjayhcbiIKKyAgICAgICIgICAgZG9uZSxcbiIKKyAgICAgICIgICAgJG91dHB1dCQuY2xhc3MsXG4iCisgICAgICAiICAgICRvdXRwdXQkLmdldERlZmF1bHRJbnN0YW5jZSgpKSk7XG4iKTsKKworICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICBwcmludGVyLT5QcmludCgifVxuIik7CisgIH0KKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KAorICAgICJ9XG4iCisgICAgIlxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlU2VydmljZUdlbmVyYXRvcjo6R2VuZXJhdGVCbG9ja2luZ1N0dWIoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgInB1YmxpYyBzdGF0aWMgQmxvY2tpbmdJbnRlcmZhY2UgbmV3QmxvY2tpbmdTdHViKFxuIgorICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CbG9ja2luZ1JwY0NoYW5uZWwgY2hhbm5lbCkge1xuIgorICAgICIgIHJldHVybiBuZXcgQmxvY2tpbmdTdHViKGNoYW5uZWwpO1xuIgorICAgICJ9XG4iCisgICAgIlxuIik7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgInB1YmxpYyBpbnRlcmZhY2UgQmxvY2tpbmdJbnRlcmZhY2UgeyIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5tZXRob2RfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgTWV0aG9kRGVzY3JpcHRvciogbWV0aG9kID0gZGVzY3JpcHRvcl8tPm1ldGhvZChpKTsKKyAgICBHZW5lcmF0ZUJsb2NraW5nTWV0aG9kU2lnbmF0dXJlKHByaW50ZXIsIG1ldGhvZCk7CisgICAgcHJpbnRlci0+UHJpbnQoIjtcbiIpOworICB9CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAifVxuIgorICAgICJcbiIpOworCisgIHByaW50ZXItPlByaW50KAorICAgICJwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBCbG9ja2luZ1N0dWIgaW1wbGVtZW50cyBCbG9ja2luZ0ludGVyZmFjZSB7XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgInByaXZhdGUgQmxvY2tpbmdTdHViKGNvbS5nb29nbGUucHJvdG9idWYuQmxvY2tpbmdScGNDaGFubmVsIGNoYW5uZWwpIHtcbiIKKyAgICAiICB0aGlzLmNoYW5uZWwgPSBjaGFubmVsO1xuIgorICAgICJ9XG4iCisgICAgIlxuIgorICAgICJwcml2YXRlIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuQmxvY2tpbmdScGNDaGFubmVsIGNoYW5uZWw7XG4iKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5tZXRob2RfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgTWV0aG9kRGVzY3JpcHRvciogbWV0aG9kID0gZGVzY3JpcHRvcl8tPm1ldGhvZChpKTsKKyAgICBHZW5lcmF0ZUJsb2NraW5nTWV0aG9kU2lnbmF0dXJlKHByaW50ZXIsIG1ldGhvZCk7CisgICAgcHJpbnRlci0+UHJpbnQoIiB7XG4iKTsKKyAgICBwcmludGVyLT5JbmRlbnQoKTsKKworICAgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyczsKKyAgICB2YXJzWyJpbmRleCJdID0gU2ltcGxlSXRvYShpKTsKKyAgICB2YXJzWyJvdXRwdXQiXSA9IG5hbWVfcmVzb2x2ZXJfLT5HZXRJbW11dGFibGVDbGFzc05hbWUoCisgICAgICAgIG1ldGhvZC0+b3V0cHV0X3R5cGUoKSk7CisgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICJyZXR1cm4gKCRvdXRwdXQkKSBjaGFubmVsLmNhbGxCbG9ja2luZ01ldGhvZChcbiIKKyAgICAgICIgIGdldERlc2NyaXB0b3IoKS5nZXRNZXRob2RzKCkuZ2V0KCRpbmRleCQpLFxuIgorICAgICAgIiAgY29udHJvbGxlcixcbiIKKyAgICAgICIgIHJlcXVlc3QsXG4iCisgICAgICAiICAkb3V0cHV0JC5nZXREZWZhdWx0SW5zdGFuY2UoKSk7XG4iKTsKKworICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJ9XG4iCisgICAgICAiXG4iKTsKKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZVNlcnZpY2VHZW5lcmF0b3I6OkdlbmVyYXRlTWV0aG9kU2lnbmF0dXJlKGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNZXRob2REZXNjcmlwdG9yKiBtZXRob2QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElzQWJzdHJhY3QgaXNfYWJzdHJhY3QpIHsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJzOworICB2YXJzWyJuYW1lIl0gPSBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlKG1ldGhvZCk7CisgIHZhcnNbImlucHV0Il0gPSBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKG1ldGhvZC0+aW5wdXRfdHlwZSgpKTsKKyAgdmFyc1sib3V0cHV0Il0gPSBuYW1lX3Jlc29sdmVyXy0+R2V0SW1tdXRhYmxlQ2xhc3NOYW1lKG1ldGhvZC0+b3V0cHV0X3R5cGUoKSk7CisgIHZhcnNbImFic3RyYWN0Il0gPSAoaXNfYWJzdHJhY3QgPT0gSVNfQUJTVFJBQ1QpID8gImFic3RyYWN0IiA6ICIiOworICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICJwdWJsaWMgJGFic3RyYWN0JCB2b2lkICRuYW1lJChcbiIKKyAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuUnBjQ29udHJvbGxlciBjb250cm9sbGVyLFxuIgorICAgICIgICAgJGlucHV0JCByZXF1ZXN0LFxuIgorICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNDYWxsYmFjazwkb3V0cHV0JD4gZG9uZSkiKTsKK30KKwordm9pZCBJbW11dGFibGVTZXJ2aWNlR2VuZXJhdG9yOjpHZW5lcmF0ZUJsb2NraW5nTWV0aG9kU2lnbmF0dXJlKAorICAgIGlvOjpQcmludGVyKiBwcmludGVyLAorICAgIGNvbnN0IE1ldGhvZERlc2NyaXB0b3IqIG1ldGhvZCkgeworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcnM7CisgIHZhcnNbIm1ldGhvZCJdID0gVW5kZXJzY29yZXNUb0NhbWVsQ2FzZShtZXRob2QpOworICB2YXJzWyJpbnB1dCJdID0gbmFtZV9yZXNvbHZlcl8tPkdldEltbXV0YWJsZUNsYXNzTmFtZShtZXRob2QtPmlucHV0X3R5cGUoKSk7CisgIHZhcnNbIm91dHB1dCJdID0gbmFtZV9yZXNvbHZlcl8tPkdldEltbXV0YWJsZUNsYXNzTmFtZShtZXRob2QtPm91dHB1dF90eXBlKCkpOworICBwcmludGVyLT5QcmludCh2YXJzLAorICAgICJcbiIKKyAgICAicHVibGljICRvdXRwdXQkICRtZXRob2QkKFxuIgorICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNDb250cm9sbGVyIGNvbnRyb2xsZXIsXG4iCisgICAgIiAgICAkaW5wdXQkIHJlcXVlc3QpXG4iCisgICAgIiAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRXhjZXB0aW9uIik7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfc2VydmljZS5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfc2VydmljZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY3MDdlODIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9zZXJ2aWNlLmgKQEAgLTAsMCArMSwxMzUgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9TRVJWSUNFX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9TRVJWSUNFX0hfXworCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKyAgbmFtZXNwYWNlIGNvbXBpbGVyIHsKKyAgICBuYW1lc3BhY2UgamF2YSB7CisgICAgICBjbGFzcyBDb250ZXh0OyAgICAgICAgICAgIC8vIGNvbnRleHQuaAorICAgICAgY2xhc3MgQ2xhc3NOYW1lUmVzb2x2ZXI7ICAvLyBuYW1lX3Jlc29sdmVyLmgKKyAgICB9CisgIH0KKyAgbmFtZXNwYWNlIGlvIHsKKyAgICBjbGFzcyBQcmludGVyOyAgICAgICAgICAgICAgLy8gcHJpbnRlci5oCisgIH0KK30KKworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YSB7CisKK2NsYXNzIFNlcnZpY2VHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgU2VydmljZUdlbmVyYXRvcihjb25zdCBTZXJ2aWNlRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CisgIHZpcnR1YWwgflNlcnZpY2VHZW5lcmF0b3IoKTsKKworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGUoaW86OlByaW50ZXIqIHByaW50ZXIpID0gMDsKKworICBlbnVtIFJlcXVlc3RPclJlc3BvbnNlIHsgUkVRVUVTVCwgUkVTUE9OU0UgfTsKKyAgZW51bSBJc0Fic3RyYWN0IHsgSVNfQUJTVFJBQ1QsIElTX0NPTkNSRVRFIH07CisKKyBwcm90ZWN0ZWQ6CisgIGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhTZXJ2aWNlR2VuZXJhdG9yKTsKK307CisKK2NsYXNzIEltbXV0YWJsZVNlcnZpY2VHZW5lcmF0b3IgOiBwdWJsaWMgU2VydmljZUdlbmVyYXRvciB7CisgcHVibGljOgorICBleHBsaWNpdCBJbW11dGFibGVTZXJ2aWNlR2VuZXJhdG9yKGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnRleHQqIGNvbnRleHQpOworICB2aXJ0dWFsIH5JbW11dGFibGVTZXJ2aWNlR2VuZXJhdG9yKCk7CisKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworIHByaXZhdGU6CisKKyAgLy8gR2VuZXJhdGUgdGhlIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgbWV0aG9kLgorICB2b2lkIEdlbmVyYXRlR2V0RGVzY3JpcHRvckZvclR5cGUoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIC8vIEdlbmVyYXRlIGEgSmF2YSBpbnRlcmZhY2UgZm9yIHRoZSBzZXJ2aWNlLgorICB2b2lkIEdlbmVyYXRlSW50ZXJmYWNlKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworICAvLyBHZW5lcmF0ZSBuZXdSZWZsZWN0aXZlU2VydmljZSgpIG1ldGhvZC4KKyAgdm9pZCBHZW5lcmF0ZU5ld1JlZmxlY3RpdmVTZXJ2aWNlTWV0aG9kKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworICAvLyBHZW5lcmF0ZSBuZXdSZWZsZWN0aXZlQmxvY2tpbmdTZXJ2aWNlKCkgbWV0aG9kLgorICB2b2lkIEdlbmVyYXRlTmV3UmVmbGVjdGl2ZUJsb2NraW5nU2VydmljZU1ldGhvZChpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyAgLy8gR2VuZXJhdGUgYWJzdHJhY3QgbWV0aG9kIGRlY2xhcmF0aW9ucyBmb3IgYWxsIG1ldGhvZHMuCisgIHZvaWQgR2VuZXJhdGVBYnN0cmFjdE1ldGhvZHMoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIC8vIEdlbmVyYXRlIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiBTZXJ2aWNlLmNhbGxNZXRob2QoKS4KKyAgdm9pZCBHZW5lcmF0ZUNhbGxNZXRob2QoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIC8vIEdlbmVyYXRlIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiBCbG9ja2luZ1NlcnZpY2UuY2FsbEJsb2NraW5nTWV0aG9kKCkuCisgIHZvaWQgR2VuZXJhdGVDYWxsQmxvY2tpbmdNZXRob2QoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIC8vIEdlbmVyYXRlIHRoZSBpbXBsZW1lbnRhdGlvbnMgb2YgU2VydmljZS5nZXR7UmVxdWVzdCxSZXNwb25zZX1Qcm90b3R5cGUoKS4KKyAgdm9pZCBHZW5lcmF0ZUdldFByb3RvdHlwZShSZXF1ZXN0T3JSZXNwb25zZSB3aGljaCwgaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIC8vIEdlbmVyYXRlIGEgc3R1YiBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgc2VydmljZS4KKyAgdm9pZCBHZW5lcmF0ZVN0dWIoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIC8vIEdlbmVyYXRlIGEgbWV0aG9kIHNpZ25hdHVyZSwgcG9zc2libHkgYWJzdHJhY3QsIHdpdGhvdXQgYm9keSBvciB0cmFpbGluZworICAvLyBzZW1pY29sb24uCisgIHZvaWQgR2VuZXJhdGVNZXRob2RTaWduYXR1cmUoaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWV0aG9kRGVzY3JpcHRvciogbWV0aG9kLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElzQWJzdHJhY3QgaXNfYWJzdHJhY3QpOworCisgIC8vIEdlbmVyYXRlIGEgYmxvY2tpbmcgc3R1YiBpbnRlcmZhY2UgYW5kIGltcGxlbWVudGF0aW9uIG9mIHRoZSBzZXJ2aWNlLgorICB2b2lkIEdlbmVyYXRlQmxvY2tpbmdTdHViKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworICAvLyBHZW5lcmF0ZSB0aGUgbWV0aG9kIHNpZ25hdHVyZSBmb3Igb25lIG1ldGhvZCBvZiBhIGJsb2NraW5nIHN0dWIuCisgIHZvaWQgR2VuZXJhdGVCbG9ja2luZ01ldGhvZFNpZ25hdHVyZShpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1ldGhvZERlc2NyaXB0b3IqIG1ldGhvZCk7CisKKyAgQ29udGV4dCogY29udGV4dF87CisgIENsYXNzTmFtZVJlc29sdmVyKiBuYW1lX3Jlc29sdmVyXzsKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEltbXV0YWJsZVNlcnZpY2VHZW5lcmF0b3IpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKKyNlbmRpZiAgLy8gTkVUX1BST1RPMl9DT01QSUxFUl9KQVZBX1NFUlZJQ0VfSF9fCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9zaGFyZWRfY29kZV9nZW5lcmF0b3IuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9zaGFyZWRfY29kZV9nZW5lcmF0b3IuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzAxNzczNgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX3NoYXJlZF9jb2RlX2dlbmVyYXRvci5jYwpAQCAtMCwwICsxLDIwNSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjogeGlhb2ZlbmdAZ29vZ2xlLmNvbSAoRmVuZyBYaWFvKQorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9zaGFyZWRfY29kZV9nZW5lcmF0b3IuaD4KKworI2luY2x1ZGUgPG1lbW9yeT4KKyNpZm5kZWYgX1NIQVJFRF9QVFJfSAorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaGFyZWRfcHRyLmg+CisjZW5kaWYKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfaGVscGVycy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfbmFtZV9yZXNvbHZlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jb2RlX2dlbmVyYXRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhIHsKKworU2hhcmVkQ29kZUdlbmVyYXRvcjo6U2hhcmVkQ29kZUdlbmVyYXRvcihjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSkKKyAgOiBuYW1lX3Jlc29sdmVyXyhuZXcgQ2xhc3NOYW1lUmVzb2x2ZXIpLCBmaWxlXyhmaWxlKSB7Cit9CisKK1NoYXJlZENvZGVHZW5lcmF0b3I6On5TaGFyZWRDb2RlR2VuZXJhdG9yKCkgeworfQorCit2b2lkIFNoYXJlZENvZGVHZW5lcmF0b3I6OkdlbmVyYXRlKEdlbmVyYXRvckNvbnRleHQqIGNvbnRleHQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlY3RvcjxzdHJpbmc+KiBmaWxlX2xpc3QpIHsKKyAgc3RyaW5nIGphdmFfcGFja2FnZSA9IEZpbGVKYXZhUGFja2FnZShmaWxlXyk7CisgIHN0cmluZyBwYWNrYWdlX2RpciA9IEphdmFQYWNrYWdlVG9EaXIoamF2YV9wYWNrYWdlKTsKKworICBpZiAoSGFzRGVzY3JpcHRvck1ldGhvZHMoZmlsZV8pKSB7CisgICAgLy8gR2VuZXJhdGUgZGVzY3JpcHRvcnMuCisgICAgc3RyaW5nIGNsYXNzbmFtZSA9IG5hbWVfcmVzb2x2ZXJfLT5HZXREZXNjcmlwdG9yQ2xhc3NOYW1lKGZpbGVfKTsKKyAgICBzdHJpbmcgZmlsZW5hbWUgPSBwYWNrYWdlX2RpciArIGNsYXNzbmFtZSArICIuamF2YSI7CisgICAgZmlsZV9saXN0LT5wdXNoX2JhY2soZmlsZW5hbWUpOworICAgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8aW86Olplcm9Db3B5T3V0cHV0U3RyZWFtPiBvdXRwdXQoY29udGV4dC0+T3BlbihmaWxlbmFtZSkpOworICAgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8aW86OlByaW50ZXI+IHByaW50ZXIobmV3IGlvOjpQcmludGVyKG91dHB1dC5nZXQoKSwgJyQnKSk7CisKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICIvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIVxuIgorICAgICAgIi8vIHNvdXJjZTogJGZpbGVuYW1lJFxuIgorICAgICAgIlxuIiwKKyAgICAgICJmaWxlbmFtZSIsIGZpbGVfLT5uYW1lKCkpOworICAgIGlmICghamF2YV9wYWNrYWdlLmVtcHR5KCkpIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAicGFja2FnZSAkcGFja2FnZSQ7XG4iCisgICAgICAgICJcbiIsCisgICAgICAgICJwYWNrYWdlIiwgamF2YV9wYWNrYWdlKTsKKyAgICB9CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAicHVibGljIGZpbmFsIGNsYXNzICRjbGFzc25hbWUkIHtcbiIKKyAgICAgICIgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvclxuIgorICAgICAgIiAgICAgIGRlc2NyaXB0b3I7XG4iCisgICAgICAiICBzdGF0aWMge1xuIiwKKyAgICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWUpOworICAgIHByaW50ZXItPkluZGVudCgpOworICAgIHByaW50ZXItPkluZGVudCgpOworICAgIEdlbmVyYXRlRGVzY3JpcHRvcnMocHJpbnRlci5nZXQoKSk7CisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICIgIH1cbiIKKyAgICAgICJ9XG4iKTsKKworICAgIHByaW50ZXIucmVzZXQoKTsKKyAgICBvdXRwdXQucmVzZXQoKTsKKyAgfQorfQorCisKK3ZvaWQgU2hhcmVkQ29kZUdlbmVyYXRvcjo6R2VuZXJhdGVEZXNjcmlwdG9ycyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICAvLyBFbWJlZCB0aGUgZGVzY3JpcHRvci4gIFdlIHNpbXBseSBzZXJpYWxpemUgdGhlIGVudGlyZSBGaWxlRGVzY3JpcHRvclByb3RvCisgIC8vIGFuZCBlbWJlZCBpdCBhcyBhIHN0cmluZyBsaXRlcmFsLCB3aGljaCBpcyBwYXJzZWQgYW5kIGJ1aWx0IGludG8gcmVhbAorICAvLyBkZXNjcmlwdG9ycyBhdCBpbml0aWFsaXphdGlvbiB0aW1lLiAgV2UgdW5mb3J0dW5hdGVseSBoYXZlIHRvIHB1dCBpdCBpbgorICAvLyBhIHN0cmluZyBsaXRlcmFsLCBub3QgYSBieXRlIGFycmF5LCBiZWNhdXNlIGFwcGFyZW50bHkgdXNpbmcgYSBsaXRlcmFsCisgIC8vIGJ5dGUgYXJyYXkgY2F1c2VzIHRoZSBKYXZhIGNvbXBpbGVyIHRvIGdlbmVyYXRlICppbnN0cnVjdGlvbnMqIHRvCisgIC8vIGluaXRpYWxpemUgZWFjaCBhbmQgZXZlcnkgYnl0ZSBvZiB0aGUgYXJyYXksIGUuZy4gYXMgaWYgeW91IHR5cGVkOgorICAvLyAgIGJbMF0gPSAxMjM7IGJbMV0gPSA0NTY7IGJbMl0gPSA3ODk7CisgIC8vIFRoaXMgbWFrZXMgaHVnZSBieXRlY29kZSBmaWxlcyBhbmQgY2FuIGVhc2lseSBoaXQgdGhlIGNvbXBpbGVyJ3MgaW50ZXJuYWwKKyAgLy8gY29kZSBzaXplIGxpbWl0cyAoZXJyb3IgImNvZGUgdG8gbGFyZ2UiKS4gIFN0cmluZyBsaXRlcmFscyBhcmUgYXBwYXJlbnRseQorICAvLyBlbWJlZGRlZCByYXcsIHdoaWNoIGlzIHdoYXQgd2Ugd2FudC4KKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICBmaWxlXy0+Q29weVRvKCZmaWxlX3Byb3RvKTsKKworCisgIHN0cmluZyBmaWxlX2RhdGE7CisgIGZpbGVfcHJvdG8uU2VyaWFsaXplVG9TdHJpbmcoJmZpbGVfZGF0YSk7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgImphdmEubGFuZy5TdHJpbmdbXSBkZXNjcmlwdG9yRGF0YSA9IHtcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICAvLyBPbmx5IHdyaXRlIDQwIGJ5dGVzIHBlciBsaW5lLgorICBzdGF0aWMgY29uc3QgaW50IGtCeXRlc1BlckxpbmUgPSA0MDsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlX2RhdGEuc2l6ZSgpOyBpICs9IGtCeXRlc1BlckxpbmUpIHsKKyAgICBpZiAoaSA+IDApIHsKKyAgICAgIC8vIEV2ZXJ5IDQwMCBsaW5lcywgc3RhcnQgYSBuZXcgc3RyaW5nIGxpdGVyYWwsIGluIG9yZGVyIHRvIGF2b2lkIHRoZQorICAgICAgLy8gNjRrIGxlbmd0aCBsaW1pdC4KKyAgICAgIGlmIChpICUgNDAwID09IDApIHsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoIixcbiIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoIiArXG4iKTsKKyAgICAgIH0KKyAgICB9CisgICAgcHJpbnRlci0+UHJpbnQoIlwiJGRhdGEkXCIiLAorICAgICAgImRhdGEiLCBDRXNjYXBlKGZpbGVfZGF0YS5zdWJzdHIoaSwga0J5dGVzUGVyTGluZSkpKTsKKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoIlxufTtcbiIpOworCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8vIENyZWF0ZSB0aGUgSW50ZXJuYWxEZXNjcmlwdG9yQXNzaWduZXIuCisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgImNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IuIgorICAgICJJbnRlcm5hbERlc2NyaXB0b3JBc3NpZ25lciBhc3NpZ25lciA9XG4iCisgICAgIiAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvci4iCisgICAgIiAgICBJbnRlcm5hbERlc2NyaXB0b3JBc3NpZ25lcigpIHtcbiIKKyAgICAiICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnkgYXNzaWduRGVzY3JpcHRvcnMoXG4iCisgICAgIiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yIHJvb3QpIHtcbiIKKyAgICAiICAgICAgICBkZXNjcmlwdG9yID0gcm9vdDtcbiIKKyAgICAvLyBDdXN0b20gb3B0aW9ucyB3aWxsIGJlIGhhbmRsZWQgd2hlbiBpbW11dGFibGUgbWVzc2FnZXMnIG91dGVyIGNsYXNzIGlzCisgICAgLy8gbG9hZGVkLiBIZXJlIHdlIGp1c3QgcmV0dXJuIG51bGwgYW5kIGxldCBjdXN0b20gb3B0aW9ucyBiZSB1bmtub3duCisgICAgLy8gZmllbGRzLgorICAgICIgICAgICAgIHJldHVybiBudWxsO1xuIgorICAgICIgICAgICB9XG4iCisgICAgIiAgICB9O1xuIik7CisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgLy8gRmluZCBvdXQgYWxsIGRlcGVuZGVuY2llcy4KKyAgdmVjdG9yPHBhaXI8c3RyaW5nLCBzdHJpbmc+ID4gZGVwZW5kZW5jaWVzOworICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5kZXBlbmRlbmN5X2NvdW50KCk7IGkrKykgeworICAgIGlmIChTaG91bGRJbmNsdWRlRGVwZW5kZW5jeShmaWxlXy0+ZGVwZW5kZW5jeShpKSkpIHsKKyAgICAgIHN0cmluZyBmaWxlbmFtZSA9IGZpbGVfLT5kZXBlbmRlbmN5KGkpLT5uYW1lKCk7CisgICAgICBzdHJpbmcgY2xhc3NuYW1lID0gRmlsZUphdmFQYWNrYWdlKGZpbGVfLT5kZXBlbmRlbmN5KGkpKSArICIuIiArCisgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZV9yZXNvbHZlcl8tPkdldERlc2NyaXB0b3JDbGFzc05hbWUoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVfLT5kZXBlbmRlbmN5KGkpKTsKKyAgICAgIGRlcGVuZGVuY2llcy5wdXNoX2JhY2soc3RkOjptYWtlX3BhaXIoZmlsZW5hbWUsIGNsYXNzbmFtZSkpOworICAgIH0KKyAgfQorCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8vIEludm9rZSBpbnRlcm5hbEJ1aWxkR2VuZXJhdGVkRmlsZUZyb20oKSB0byBidWlsZCB0aGUgZmlsZS4KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgImNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3JcbiIKKyAgICAiICAuaW50ZXJuYWxCdWlsZEdlbmVyYXRlZEZpbGVGcm9tKGRlc2NyaXB0b3JEYXRhLFxuIik7CisgIHByaW50ZXItPlByaW50KAorICAgICIgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3JbXSB7XG4iKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlcGVuZGVuY2llcy5zaXplKCk7IGkrKykgeworICAgIGNvbnN0IHN0cmluZyYgZGVwZW5kZW5jeSA9IGRlcGVuZGVuY2llc1tpXS5zZWNvbmQ7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICIgICAgICAkZGVwZW5kZW5jeSQuZ2V0RGVzY3JpcHRvcigpLFxuIiwKKyAgICAgICAgImRlcGVuZGVuY3kiLCBkZXBlbmRlbmN5KTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KAorICAgICIgICAgfSwgYXNzaWduZXIpO1xuIik7Cit9CisKK2Jvb2wgU2hhcmVkQ29kZUdlbmVyYXRvcjo6U2hvdWxkSW5jbHVkZURlcGVuZGVuY3koCisgICAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgcmV0dXJuIHRydWU7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfc2hhcmVkX2NvZGVfZ2VuZXJhdG9yLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9zaGFyZWRfY29kZV9nZW5lcmF0b3IuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zOGEzMmZjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfc2hhcmVkX2NvZGVfZ2VuZXJhdG9yLmgKQEAgLTAsMCArMSw5NCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjogeGlhb2ZlbmdAZ29vZ2xlLmNvbSAoRmVuZyBYaWFvKQorLy8KKy8vIEdlbmVyYXRvcnMgdGhhdCBnZW5lcmF0ZSBzaGFyZWQgY29kZSBiZXR3ZWVuIGltbXV0YWJsZSBBUEkgYW5kIG11dGFibGUgQVBJLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX1NIQVJFRF9DT0RFX0dFTkVSQVRPUl9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfU0hBUkVEX0NPREVfR0VORVJBVE9SX0hfXworCisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDx2ZWN0b3I+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKyAgY2xhc3MgRmlsZURlc2NyaXB0b3I7ICAgICAgICAvLyBkZXNjcmlwdG9yLmgKKyAgbmFtZXNwYWNlIGNvbXBpbGVyIHsKKyAgICBjbGFzcyBHZW5lcmF0b3JDb250ZXh0OyAgICAvLyBjb2RlX2dlbmVyYXRvci5oCisgICAgbmFtZXNwYWNlIGphdmEgeworICAgICAgY2xhc3MgQ2xhc3NOYW1lUmVzb2x2ZXI7ICAgICAgIC8vIG5hbWVfcmVzb2x2ZXIuaAorICAgIH0KKyAgfQorICBuYW1lc3BhY2UgaW8geworICAgIGNsYXNzIFByaW50ZXI7ICAgICAgICAgICAgIC8vIHByaW50ZXIuaAorICB9Cit9CisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmEgeworCisvLyBBIGdlbmVyYXRvciB0aGF0IGdlbmVyYXRlcyBjb2RlIHRoYXQgYXJlIHNoYXJlZCBiZXR3ZWVuIGltbXV0YWJsZSBBUEkKKy8vIGFuZCBtdXRhYmxlIEFQSS4gQ3VycmVudGx5IG9ubHkgZGVzY3JpcHRvcnMgYXJlIHNoYXJlZC4KK2NsYXNzIFNoYXJlZENvZGVHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgU2hhcmVkQ29kZUdlbmVyYXRvcihjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSk7CisgIH5TaGFyZWRDb2RlR2VuZXJhdG9yKCk7CisKKyAgdm9pZCBHZW5lcmF0ZShHZW5lcmF0b3JDb250ZXh0KiBnZW5lcmF0b3JfY29udGV4dCwKKyAgICAgICAgICAgICAgICB2ZWN0b3I8c3RyaW5nPiogZmlsZV9saXN0KTsKKworICB2b2lkIEdlbmVyYXRlRGVzY3JpcHRvcnMoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgcHJpdmF0ZToKKyAgLy8gUmV0dXJucyB3aGV0aGVyIHRoZSBkZXBlbmRlbmN5IHNob3VsZCBiZSBpbmNsdWRlZCBpbiB0aGUgb3V0cHV0IGZpbGUuCisgIC8vIEFsd2F5cyByZXR1cm5zIHRydWUgZm9yIG9wZW5zb3VyY2UsIGJ1dCB1c2VkIGludGVybmFsbHkgYXQgR29vZ2xlIHRvIGhlbHAKKyAgLy8gaW1wcm92ZSBjb21wYXRpYmlsaXR5IHdpdGggdmVyc2lvbiAxIG9mIHByb3RvY29sIGJ1ZmZlcnMuCisgIGJvb2wgU2hvdWxkSW5jbHVkZURlcGVuZGVuY3koY29uc3QgRmlsZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworCisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8Q2xhc3NOYW1lUmVzb2x2ZXI+IG5hbWVfcmVzb2x2ZXJfOworICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZV87CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhTaGFyZWRDb2RlR2VuZXJhdG9yKTsKK307CisKKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfU0hBUkVEX0NPREVfR0VORVJBVE9SX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfc3RyaW5nX2ZpZWxkLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfc3RyaW5nX2ZpZWxkLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdmNzU3ZTQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9zdHJpbmdfZmllbGQuY2MKQEAgLTAsMCArMSwxMDIzIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gQXV0aG9yOiBqb25wQGdvb2dsZS5jb20gKEpvbiBQZXJsb3cpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2luY2x1ZGUgPG1hcD4KKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbG9nZ2luZy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2NvbnRleHQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2RvY19jb21tZW50Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9uYW1lX3Jlc29sdmVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9zdHJpbmdfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YSB7CisKK3VzaW5nIGludGVybmFsOjpXaXJlRm9ybWF0OwordXNpbmcgaW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOworCituYW1lc3BhY2UgeworCit2b2lkIFNldFByaW1pdGl2ZVZhcmlhYmxlcyhjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkR2VuZXJhdG9ySW5mbyogaW5mbywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzTmFtZVJlc29sdmVyKiBuYW1lX3Jlc29sdmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwPHN0cmluZywgc3RyaW5nPiogdmFyaWFibGVzKSB7CisgIFNldENvbW1vbkZpZWxkVmFyaWFibGVzKGRlc2NyaXB0b3IsIGluZm8sIHZhcmlhYmxlcyk7CisKKyAgKCp2YXJpYWJsZXMpWyJlbXB0eV9saXN0Il0gPSAiY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LkVNUFRZIjsKKworICAoKnZhcmlhYmxlcylbImRlZmF1bHQiXSA9IEltbXV0YWJsZURlZmF1bHRWYWx1ZShkZXNjcmlwdG9yLCBuYW1lX3Jlc29sdmVyKTsKKyAgKCp2YXJpYWJsZXMpWyJkZWZhdWx0X2luaXQiXSA9CisgICAgICAiPSAiICsgSW1tdXRhYmxlRGVmYXVsdFZhbHVlKGRlc2NyaXB0b3IsIG5hbWVfcmVzb2x2ZXIpOworICAoKnZhcmlhYmxlcylbImNhcGl0YWxpemVkX3R5cGUiXSA9ICJTdHJpbmciOworICAoKnZhcmlhYmxlcylbInRhZyJdID0gU2ltcGxlSXRvYShXaXJlRm9ybWF0OjpNYWtlVGFnKGRlc2NyaXB0b3IpKTsKKyAgKCp2YXJpYWJsZXMpWyJ0YWdfc2l6ZSJdID0gU2ltcGxlSXRvYSgKKyAgICAgIFdpcmVGb3JtYXQ6OlRhZ1NpemUoZGVzY3JpcHRvci0+bnVtYmVyKCksIEdldFR5cGUoZGVzY3JpcHRvcikpKTsKKyAgKCp2YXJpYWJsZXMpWyJudWxsX2NoZWNrIl0gPQorICAgICAgIiAgaWYgKHZhbHVlID09IG51bGwpIHtcbiIKKyAgICAgICIgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7XG4iCisgICAgICAiICB9XG4iOworICAoKnZhcmlhYmxlcylbIndyaXRlU3RyaW5nIl0gPQorICAgICAgImNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS53cml0ZVN0cmluZyI7CisgICgqdmFyaWFibGVzKVsiY29tcHV0ZVN0cmluZ1NpemUiXSA9CisgICAgICAiY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLmNvbXB1dGVTdHJpbmdTaXplIjsKKworICAvLyBUT0RPKGJpcmRvKTogQWRkIEBkZXByZWNhdGVkIGphdmFkb2Mgd2hlbiBnZW5lcmF0aW5nIGphdmFkb2MgaXMgc3VwcG9ydGVkCisgIC8vIGJ5IHRoZSBwcm90byBjb21waWxlcgorICAoKnZhcmlhYmxlcylbImRlcHJlY2F0aW9uIl0gPSBkZXNjcmlwdG9yLT5vcHRpb25zKCkuZGVwcmVjYXRlZCgpCisgICAgICA/ICJAamF2YS5sYW5nLkRlcHJlY2F0ZWQgIiA6ICIiOworICAoKnZhcmlhYmxlcylbIm9uX2NoYW5nZWQiXSA9CisgICAgICBIYXNEZXNjcmlwdG9yTWV0aG9kcyhkZXNjcmlwdG9yLT5jb250YWluaW5nX3R5cGUoKSkgPyAib25DaGFuZ2VkKCk7IiA6ICIiOworCisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yLT5maWxlKCkpKSB7CisgICAgLy8gRm9yIHNpbmd1bGFyIG1lc3NhZ2VzIGFuZCBidWlsZGVycywgb25lIGJpdCBpcyB1c2VkIGZvciB0aGUgaGFzRmllbGQgYml0LgorICAgICgqdmFyaWFibGVzKVsiZ2V0X2hhc19maWVsZF9iaXRfbWVzc2FnZSJdID0gR2VuZXJhdGVHZXRCaXQobWVzc2FnZUJpdEluZGV4KTsKKyAgICAoKnZhcmlhYmxlcylbImdldF9oYXNfZmllbGRfYml0X2J1aWxkZXIiXSA9IEdlbmVyYXRlR2V0Qml0KGJ1aWxkZXJCaXRJbmRleCk7CisKKyAgICAvLyBOb3RlIHRoYXQgdGhlc2UgaGF2ZSBhIHRyYWlsaW5nICI7Ii4KKyAgICAoKnZhcmlhYmxlcylbInNldF9oYXNfZmllbGRfYml0X21lc3NhZ2UiXSA9CisgICAgICAgIEdlbmVyYXRlU2V0Qml0KG1lc3NhZ2VCaXRJbmRleCkgKyAiOyI7CisgICAgKCp2YXJpYWJsZXMpWyJzZXRfaGFzX2ZpZWxkX2JpdF9idWlsZGVyIl0gPQorICAgICAgICBHZW5lcmF0ZVNldEJpdChidWlsZGVyQml0SW5kZXgpICsgIjsiOworICAgICgqdmFyaWFibGVzKVsiY2xlYXJfaGFzX2ZpZWxkX2JpdF9idWlsZGVyIl0gPQorICAgICAgICBHZW5lcmF0ZUNsZWFyQml0KGJ1aWxkZXJCaXRJbmRleCkgKyAiOyI7CisKKyAgICAoKnZhcmlhYmxlcylbImlzX2ZpZWxkX3ByZXNlbnRfbWVzc2FnZSJdID0gR2VuZXJhdGVHZXRCaXQobWVzc2FnZUJpdEluZGV4KTsKKyAgfSBlbHNlIHsKKyAgICAoKnZhcmlhYmxlcylbInNldF9oYXNfZmllbGRfYml0X21lc3NhZ2UiXSA9ICIiOworICAgICgqdmFyaWFibGVzKVsic2V0X2hhc19maWVsZF9iaXRfYnVpbGRlciJdID0gIiI7CisgICAgKCp2YXJpYWJsZXMpWyJjbGVhcl9oYXNfZmllbGRfYml0X2J1aWxkZXIiXSA9ICIiOworCisgICAgKCp2YXJpYWJsZXMpWyJpc19maWVsZF9wcmVzZW50X21lc3NhZ2UiXSA9CisgICAgICAgICIhZ2V0IiArICgqdmFyaWFibGVzKVsiY2FwaXRhbGl6ZWRfbmFtZSJdICsgIkJ5dGVzKCkuaXNFbXB0eSgpIjsKKyAgfQorCisgIC8vIEZvciByZXBlYXRlZCBidWlsZGVycywgb25lIGJpdCBpcyB1c2VkIGZvciB3aGV0aGVyIHRoZSBhcnJheSBpcyBpbW11dGFibGUuCisgICgqdmFyaWFibGVzKVsiZ2V0X211dGFibGVfYml0X2J1aWxkZXIiXSA9IEdlbmVyYXRlR2V0Qml0KGJ1aWxkZXJCaXRJbmRleCk7CisgICgqdmFyaWFibGVzKVsic2V0X211dGFibGVfYml0X2J1aWxkZXIiXSA9IEdlbmVyYXRlU2V0Qml0KGJ1aWxkZXJCaXRJbmRleCk7CisgICgqdmFyaWFibGVzKVsiY2xlYXJfbXV0YWJsZV9iaXRfYnVpbGRlciJdID0gR2VuZXJhdGVDbGVhckJpdChidWlsZGVyQml0SW5kZXgpOworCisgIC8vIEZvciByZXBlYXRlZCBmaWVsZHMsIG9uZSBiaXQgaXMgdXNlZCBmb3Igd2hldGhlciB0aGUgYXJyYXkgaXMgaW1tdXRhYmxlCisgIC8vIGluIHRoZSBwYXJzaW5nIGNvbnN0cnVjdG9yLgorICAoKnZhcmlhYmxlcylbImdldF9tdXRhYmxlX2JpdF9wYXJzZXIiXSA9CisgICAgICBHZW5lcmF0ZUdldEJpdE11dGFibGVMb2NhbChidWlsZGVyQml0SW5kZXgpOworICAoKnZhcmlhYmxlcylbInNldF9tdXRhYmxlX2JpdF9wYXJzZXIiXSA9CisgICAgICBHZW5lcmF0ZVNldEJpdE11dGFibGVMb2NhbChidWlsZGVyQml0SW5kZXgpOworCisgICgqdmFyaWFibGVzKVsiZ2V0X2hhc19maWVsZF9iaXRfZnJvbV9sb2NhbCJdID0KKyAgICAgIEdlbmVyYXRlR2V0Qml0RnJvbUxvY2FsKGJ1aWxkZXJCaXRJbmRleCk7CisgICgqdmFyaWFibGVzKVsic2V0X2hhc19maWVsZF9iaXRfdG9fbG9jYWwiXSA9CisgICAgICBHZW5lcmF0ZVNldEJpdFRvTG9jYWwobWVzc2FnZUJpdEluZGV4KTsKK30KKworfSAgLy8gbmFtZXNwYWNlCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG1lc3NhZ2VCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBidWlsZGVyQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb250ZXh0KiBjb250ZXh0KQorICA6IGRlc2NyaXB0b3JfKGRlc2NyaXB0b3IpLCBtZXNzYWdlQml0SW5kZXhfKG1lc3NhZ2VCaXRJbmRleCksCisgICAgYnVpbGRlckJpdEluZGV4XyhidWlsZGVyQml0SW5kZXgpLCBjb250ZXh0Xyhjb250ZXh0KSwKKyAgICBuYW1lX3Jlc29sdmVyXyhjb250ZXh0LT5HZXROYW1lUmVzb2x2ZXIoKSkgeworICBTZXRQcmltaXRpdmVWYXJpYWJsZXMoZGVzY3JpcHRvciwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LT5HZXRGaWVsZEdlbmVyYXRvckluZm8oZGVzY3JpcHRvciksCisgICAgICAgICAgICAgICAgICAgICAgICBuYW1lX3Jlc29sdmVyXywgJnZhcmlhYmxlc18pOworfQorCitJbW11dGFibGVTdHJpbmdGaWVsZEdlbmVyYXRvcjo6fkltbXV0YWJsZVN0cmluZ0ZpZWxkR2VuZXJhdG9yKCkge30KKworaW50IEltbXV0YWJsZVN0cmluZ0ZpZWxkR2VuZXJhdG9yOjpHZXROdW1CaXRzRm9yTWVzc2FnZSgpIGNvbnN0IHsKKyAgcmV0dXJuIDE7Cit9CisKK2ludCBJbW11dGFibGVTdHJpbmdGaWVsZEdlbmVyYXRvcjo6R2V0TnVtQml0c0ZvckJ1aWxkZXIoKSBjb25zdCB7CisgIHJldHVybiAxOworfQorCisvLyBBIG5vdGUgYWJvdXQgaG93IHN0cmluZ3MgYXJlIGhhbmRsZWQuIFRoaXMgY29kZSB1c2VkIHRvIGp1c3Qgc3RvcmUgYSBTdHJpbmcKKy8vIGluIHRoZSBNZXNzYWdlLiBUaGlzIGhhZCB0d28gaXNzdWVzOgorLy8KKy8vICAxLiBJdCB3b3VsZG4ndCByb3VuZHRyaXAgYnl0ZSBhcnJheXMgdGhhdCB3ZXJlIG5vdCB2YWlkIFVURi04IGVuY29kZWQKKy8vICAgICBzdHJpbmdzLCBidXQgcmF0aGVyIGZpZWxkcyB0aGF0IHdlcmUgcmF3IGJ5dGVzIGluY29ycmVjdGx5IG1hcmtlZAorLy8gICAgIGFzIHN0cmluZ3MgaW4gdGhlIHByb3RvIGZpbGUuIFRoaXMgaXMgY29tbW9uIGJlY2F1c2UgaW4gdGhlIHByb3RvMQorLy8gICAgIHN5bnRheCwgc3RyaW5nIHdhcyB0aGUgd2F5IHRvIGluZGljYXRlIGJ5dGVzIGFuZCBDKysgZW5naW5lZXJzIGNhbgorLy8gICAgIGVhc2lseSBtYWtlIHRoaXMgbWlzdGFrZSB3aXRob3V0IGFmZmVjdGluZyB0aGUgQysrIEFQSS4gQnkgY29udmVydGluZyB0bworLy8gICAgIHN0cmluZ3MgaW1tZWRpYXRlbHksIHNvbWUgamF2YSBjb2RlIG1pZ2h0IGNvcnJ1cHQgdGhlc2UgYnl0ZSBhcnJheXMgYXMKKy8vICAgICBpdCBwYXNzZXMgdGhyb3VnaCBhIGphdmEgc2VydmVyIGV2ZW4gaWYgdGhlIGZpZWxkIHdhcyBuZXZlciBhY2Nlc3NlZCBieQorLy8gICAgIGFwcGxpY2F0aW9uIGNvZGUuCisvLworLy8gIDIuIFRoZXJlJ3MgYSBwZXJmb3JtYW5jZSBoaXQgdG8gY29udmVydGluZyBiZXR3ZWVuIGJ5dGVzIGFuZCBzdHJpbmdzIGFuZAorLy8gICAgIGl0IG1hbnkgY2FzZXMsIHRoZSBmaWVsZCBpcyBuZXZlciBldmVuIHJlYWQgYnkgdGhlIGFwcGxpY2F0aW9uIGNvZGUuIFRoaXMKKy8vICAgICBhdm9pZHMgdW5uZWNlc3NhcnkgY29udmVyc2lvbnMgaW4gdGhlIGNvbW1vbiB1c2UgY2FzZXMuCisvLworLy8gU28gbm93LCB0aGUgZmllbGQgZm9yIFN0cmluZyBpcyBtYWludGFpbmVkIGFzIGFuIE9iamVjdCByZWZlcmVuY2Ugd2hpY2ggY2FuCisvLyBlaXRoZXIgc3RvcmUgYSBTdHJpbmcgb3IgYSBCeXRlU3RyaW5nLiBUaGUgY29kZSB1c2VzIGFuIGluc3RhbmNlb2YgY2hlY2sKKy8vIHRvIHNlZSB3aGljaCBvbmUgaXQgaGFzIGFuZCBjb252ZXJ0cyB0byB0aGUgb3RoZXIgb25lIGlmIG5lZWRlZC4gSXQgcmVtZW1iZXJzCisvLyB0aGUgbGFzdCB2YWx1ZSByZXF1ZXN0ZWQgKGluIGEgdGhyZWFkIHNhZmUgbWFubmVyKSBhcyB0aGlzIGlzIG1vc3QgbGlrZWx5CisvLyB0aGUgb25lIG5lZWRlZCBuZXh0LiBUaGUgdGhyZWFkIHNhZmV0eSBpcyBzdWNoIHRoYXQgaWYgdHdvIHRocmVhZHMgYm90aAorLy8gY29udmVydCB0aGUgZmllbGQgYmVjYXVzZSB0aGUgY2hhbmdlcyBtYWRlIGJ5IGVhY2ggdGhyZWFkIHdlcmUgbm90IHZpc2libGUgdG8KKy8vIHRoZSBvdGhlciwgdGhleSBtYXkgY2F1c2UgYSBjb252ZXJzaW9uIHRvIGhhcHBlbiBtb3JlIHRpbWVzIHRoYW4gd291bGQKKy8vIG90aGVyd2lzZSBiZSBuZWNlc3NhcnkuIFRoaXMgd2FzIGRlZW1lZCBiZXR0ZXIgdGhhbiBhZGRpbmcgc3luY2hyb25pemF0aW9uCisvLyBvdmVyaGVhZC4gSXQgd2lsbCBub3QgY2F1c2UgYW55IGNvcnJ1cHRpb24gaXNzdWVzIG9yIGFmZmVjdCB0aGUgYmVoYXZpb3Igb2YKKy8vIHRoZSBBUEkuIFRoZSBpbnN0YW5jZW9mIGNoZWNrIGlzIGFsc28gaGlnaGx5IG9wdGltaXplZCBpbiB0aGUgSlZNIGFuZCB3ZQorLy8gZGVjaWRlZCBpdCB3YXMgYmV0dGVyIHRvIHJlZHVjZSB0aGUgbWVtb3J5IG92ZXJoZWFkIGJ5IG5vdCBoYXZpbmcgdHdvCisvLyBzZXBhcmF0ZSBmaWVsZHMgYnV0IHJhdGhlciB1c2UgZHluYW1pYyB0eXBlIGNoZWNraW5nLgorLy8KKy8vIEZvciBzaW5nbGUgZmllbGRzLCB0aGUgbG9naWMgZm9yIHRoaXMgaXMgZG9uZSBpbnNpZGUgdGhlIGdlbmVyYXRlZCBjb2RlLiBGb3IKKy8vIHJlcGVhdGVkIGZpZWxkcywgdGhlIGxvZ2ljIGlzIGRvbmUgaW4gTGF6eVN0cmluZ0FycmF5TGlzdCBhbmQKKy8vIFVubW9kaWZpYWJsZUxhenlTdHJpbmdMaXN0Lgordm9pZCBJbW11dGFibGVTdHJpbmdGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUludGVyZmFjZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKFN1cHBvcnRGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJGRlcHJlY2F0aW9uJGJvb2xlYW4gaGFzJGNhcGl0YWxpemVkX25hbWUkKCk7XG4iKTsKKyAgfQorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRqYXZhLmxhbmcuU3RyaW5nIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpO1xuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZ1xuIgorICAgICIgICAgZ2V0JGNhcGl0YWxpemVkX25hbWUkQnl0ZXMoKTtcbiIpOworfQorCit2b2lkIEltbXV0YWJsZVN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgJG5hbWUkXztcbiIpOworICBQcmludEV4dHJhRmllbGRJbmZvKHZhcmlhYmxlc18sIHByaW50ZXIpOworCisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgYm9vbGVhbiBoYXMkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgICAiICByZXR1cm4gJGdldF9oYXNfZmllbGRfYml0X21lc3NhZ2UkO1xuIgorICAgICAgIn1cbiIpOworICB9CisKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgIGphdmEubGFuZy5PYmplY3QgcmVmID0gJG5hbWUkXztcbiIKKyAgICAiICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykge1xuIgorICAgICIgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7XG4iCisgICAgIiAgfSBlbHNlIHtcbiIKKyAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IFxuIgorICAgICIgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjtcbiIKKyAgICAgICIgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7XG4iKTsKKyAgaWYgKENoZWNrVXRmOChkZXNjcmlwdG9yXykpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiAgICAkbmFtZSRfID0gcztcbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7XG4iCisgICAgICAiICAgICAgJG5hbWUkXyA9IHM7XG4iCisgICAgICAiICAgIH1cbiIpOworICB9CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiAgICByZXR1cm4gcztcbiIKKyAgICAiICB9XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nXG4iCisgICAgIiAgICBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRCeXRlcygpIHtcbiIKKyAgICAiICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9ICRuYW1lJF87XG4iCisgICAgIiAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHtcbiIKKyAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gXG4iCisgICAgIiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOChcbiIKKyAgICAiICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7XG4iCisgICAgIiAgICAkbmFtZSRfID0gYjtcbiIKKyAgICAiICAgIHJldHVybiBiO1xuIgorICAgICIgIH0gZWxzZSB7XG4iCisgICAgIiAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmO1xuIgorICAgICIgIH1cbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIGphdmEubGFuZy5PYmplY3QgJG5hbWUkXyAkZGVmYXVsdF9pbml0JDtcbiIpOworICBpZiAoU3VwcG9ydEZpZWxkUHJlc2VuY2UoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljIGJvb2xlYW4gaGFzJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICAgIiAgcmV0dXJuICRnZXRfaGFzX2ZpZWxkX2JpdF9idWlsZGVyJDtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAiICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9ICRuYW1lJF87XG4iCisgICAgIiAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHtcbiIKKyAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9XG4iCisgICAgIiAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmO1xuIgorICAgICIgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7XG4iKTsKKyAgaWYgKENoZWNrVXRmOChkZXNjcmlwdG9yXykpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiAgICAkbmFtZSRfID0gcztcbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7XG4iCisgICAgICAiICAgICAgJG5hbWUkXyA9IHM7XG4iCisgICAgICAiICAgIH1cbiIpOworICB9CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiAgICByZXR1cm4gcztcbiIKKyAgICAiICB9IGVsc2Uge1xuIgorICAgICIgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7XG4iCisgICAgIiAgfVxuIgorICAgICJ9XG4iKTsKKworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nXG4iCisgICAgIiAgICBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRCeXRlcygpIHtcbiIKKyAgICAiICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9ICRuYW1lJF87XG4iCisgICAgIiAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykge1xuIgorICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSBcbiIKKyAgICAiICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KFxuIgorICAgICIgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTtcbiIKKyAgICAiICAgICRuYW1lJF8gPSBiO1xuIgorICAgICIgICAgcmV0dXJuIGI7XG4iCisgICAgIiAgfSBlbHNlIHtcbiIKKyAgICAiICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7XG4iCisgICAgIiAgfVxuIgorICAgICJ9XG4iKTsKKworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBzZXQkY2FwaXRhbGl6ZWRfbmFtZSQoXG4iCisgICAgIiAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7XG4iCisgICAgIiRudWxsX2NoZWNrJCIKKyAgICAiICAkc2V0X2hhc19maWVsZF9iaXRfYnVpbGRlciRcbiIKKyAgICAiICAkbmFtZSRfID0gdmFsdWU7XG4iCisgICAgIiAgJG9uX2NoYW5nZWQkXG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBjbGVhciRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAiICAkY2xlYXJfaGFzX2ZpZWxkX2JpdF9idWlsZGVyJFxuIik7CisgIC8vIFRoZSBkZWZhdWx0IHZhbHVlIGlzIG5vdCBhIHNpbXBsZSBsaXRlcmFsIHNvIHdlIHdhbnQgdG8gYXZvaWQgZXhlY3V0aW5nCisgIC8vIGl0IG11bHRpcGxlIHRpbWVzLiAgSW5zdGVhZCwgZ2V0IHRoZSBkZWZhdWx0IG91dCBvZiB0aGUgZGVmYXVsdCBpbnN0YW5jZS4KKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiICAkbmFtZSRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0JGNhcGl0YWxpemVkX25hbWUkKCk7XG4iKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiICAkb25fY2hhbmdlZCRcbiIKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIik7CisKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgc2V0JGNhcGl0YWxpemVkX25hbWUkQnl0ZXMoXG4iCisgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHtcbiIKKyAgICAiJG51bGxfY2hlY2skIik7CisgIGlmIChDaGVja1V0ZjgoZGVzY3JpcHRvcl8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIgIGNoZWNrQnl0ZVN0cmluZ0lzVXRmOCh2YWx1ZSk7XG4iKTsKKyAgfQorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIgICRzZXRfaGFzX2ZpZWxkX2JpdF9idWlsZGVyJFxuIgorICAgICIgICRuYW1lJF8gPSB2YWx1ZTtcbiIKKyAgICAiICAkb25fY2hhbmdlZCRcbiIKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVGaWVsZEJ1aWxkZXJJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpICBjb25zdCB7CisgIC8vIG5vb3AgZm9yIHByaW1pdGl2ZXMKK30KKwordm9pZCBJbW11dGFibGVTdHJpbmdGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUluaXRpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAiJG5hbWUkXyA9ICRkZWZhdWx0JDtcbiIpOworfQorCit2b2lkIEltbXV0YWJsZVN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRlckNsZWFyQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkbmFtZSRfID0gJGRlZmF1bHQkO1xuIgorICAgICIkY2xlYXJfaGFzX2ZpZWxkX2JpdF9idWlsZGVyJFxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoU3VwcG9ydEZpZWxkUHJlc2VuY2UoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICAvLyBBbGxvdyBhIHNsaWdodCBicmVhY2ggb2YgYWJzdHJhY3Rpb24gaGVyZSBpbiBvcmRlciB0byBhdm9pZCBmb3JjaW5nCisgICAgLy8gYWxsIHN0cmluZyBmaWVsZHMgdG8gU3RyaW5ncyB3aGVuIGNvcHlpbmcgZmllbGRzIGZyb20gYSBNZXNzYWdlLgorICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaWYgKG90aGVyLmhhcyRjYXBpdGFsaXplZF9uYW1lJCgpKSB7XG4iCisgICAgICAiICAkc2V0X2hhc19maWVsZF9iaXRfYnVpbGRlciRcbiIKKyAgICAgICIgICRuYW1lJF8gPSBvdGhlci4kbmFtZSRfO1xuIgorICAgICAgIiAgJG9uX2NoYW5nZWQkXG4iCisgICAgICAifVxuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJpZiAoIW90aGVyLmdldCRjYXBpdGFsaXplZF9uYW1lJCgpLmlzRW1wdHkoKSkge1xuIgorICAgICAgIiAgJG5hbWUkXyA9IG90aGVyLiRuYW1lJF87XG4iCisgICAgICAiICAkb25fY2hhbmdlZCRcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorfQorCit2b2lkIEltbXV0YWJsZVN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQnVpbGRpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaWYgKCRnZXRfaGFzX2ZpZWxkX2JpdF9mcm9tX2xvY2FsJCkge1xuIgorICAgICAgIiAgJHNldF9oYXNfZmllbGRfYml0X3RvX2xvY2FsJDtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJyZXN1bHQuJG5hbWUkXyA9ICRuYW1lJF87XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVTdHJpbmdGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVBhcnNpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChDaGVja1V0ZjgoZGVzY3JpcHRvcl8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJqYXZhLmxhbmcuU3RyaW5nIHMgPSBpbnB1dC5yZWFkU3RyaW5nUmVxdWlyZVV0ZjgoKTtcbiIKKyAgICAgICIkc2V0X2hhc19maWVsZF9iaXRfbWVzc2FnZSRcbiIKKyAgICAgICIkbmFtZSRfID0gcztcbiIpOworICB9IGVsc2UgaWYgKCFIYXNEZXNjcmlwdG9yTWV0aG9kcyhkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIC8vIExpdGUgcnVudGltZSBzaG91bGQgYXR0ZW1wdCB0byByZWR1Y2UgYWxsb2NhdGlvbnMgYnkgYXR0ZW1wdGluZyB0bworICAgIC8vIGNvbnN0cnVjdCB0aGUgc3RyaW5nIGRpcmVjdGx5IGZyb20gdGhlIGlucHV0IHN0cmVhbSBidWZmZXIuIFRoaXMgYXZvaWRzCisgICAgLy8gc3B1cmlvdXMgaW50ZXJtZWRpYXJ5IEJ5dGVTdHJpbmcgYWxsb2NhdGlvbnMsIGN1dHRpbmcgb3ZlcmFsbCBhbGxvY2F0aW9ucworICAgIC8vIGluIGhhbGYuCisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJqYXZhLmxhbmcuU3RyaW5nIHMgPSBpbnB1dC5yZWFkU3RyaW5nKCk7XG4iCisgICAgICAiJHNldF9oYXNfZmllbGRfYml0X21lc3NhZ2UkXG4iCisgICAgICAiJG5hbWUkXyA9IHM7XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IGlucHV0LnJlYWRCeXRlcygpO1xuIgorICAgICAgIiRzZXRfaGFzX2ZpZWxkX2JpdF9tZXNzYWdlJFxuIgorICAgICAgIiRuYW1lJF8gPSBicztcbiIpOworICB9Cit9CisKK3ZvaWQgSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVQYXJzaW5nRG9uZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gbm9vcCBmb3Igc3RyaW5ncy4KK30KKwordm9pZCBJbW11dGFibGVTdHJpbmdGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkaXNfZmllbGRfcHJlc2VudF9tZXNzYWdlJCkge1xuIgorICAgICIgICR3cml0ZVN0cmluZyQob3V0cHV0LCAkbnVtYmVyJCwgJG5hbWUkXyk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZVN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkaXNfZmllbGRfcHJlc2VudF9tZXNzYWdlJCkge1xuIgorICAgICIgIHNpemUgKz0gJGNvbXB1dGVTdHJpbmdTaXplJCgkbnVtYmVyJCwgJG5hbWUkXyk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZVN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJyZXN1bHQgPSByZXN1bHQgJiYgZ2V0JGNhcGl0YWxpemVkX25hbWUkKClcbiIKKyAgICAiICAgIC5lcXVhbHMob3RoZXIuZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkpO1xuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVIYXNoQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJoYXNoID0gKDM3ICogaGFzaCkgKyAkY29uc3RhbnRfbmFtZSQ7XG4iKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkuaGFzaENvZGUoKTtcbiIpOworfQorCitzdHJpbmcgSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3I6OkdldEJveGVkVHlwZSgpIGNvbnN0IHsKKyAgcmV0dXJuICJqYXZhLmxhbmcuU3RyaW5nIjsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitJbW11dGFibGVTdHJpbmdPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0ltbXV0YWJsZVN0cmluZ09uZW9mRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYnVpbGRlckJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb250ZXh0KiBjb250ZXh0KQorICAgIDogSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3IoCisgICAgICAgICAgZGVzY3JpcHRvciwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsIGNvbnRleHQpIHsKKyAgY29uc3QgT25lb2ZHZW5lcmF0b3JJbmZvKiBpbmZvID0KKyAgICAgIGNvbnRleHQtPkdldE9uZW9mR2VuZXJhdG9ySW5mbyhkZXNjcmlwdG9yLT5jb250YWluaW5nX29uZW9mKCkpOworICBTZXRDb21tb25PbmVvZlZhcmlhYmxlcyhkZXNjcmlwdG9yLCBpbmZvLCAmdmFyaWFibGVzXyk7Cit9CisKK0ltbXV0YWJsZVN0cmluZ09uZW9mRmllbGRHZW5lcmF0b3I6OgorfkltbXV0YWJsZVN0cmluZ09uZW9mRmllbGRHZW5lcmF0b3IoKSB7fQorCit2b2lkIEltbXV0YWJsZVN0cmluZ09uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIFByaW50RXh0cmFGaWVsZEluZm8odmFyaWFibGVzXywgcHJpbnRlcik7CisKKyAgaWYgKFN1cHBvcnRGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBib29sZWFuIGhhcyRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAiICByZXR1cm4gJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkO1xuIgorICAgICJ9XG4iKTsKKyAgfQorCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAiICBqYXZhLmxhbmcuT2JqZWN0IHJlZiAkZGVmYXVsdF9pbml0JDtcbiIKKyAgICAiICBpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iCisgICAgIiAgICByZWYgPSAkb25lb2ZfbmFtZSRfO1xuIgorICAgICIgIH1cbiIKKyAgICAiICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykge1xuIgorICAgICIgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7XG4iCisgICAgIiAgfSBlbHNlIHtcbiIKKyAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IFxuIgorICAgICIgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjtcbiIKKyAgICAiICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpO1xuIik7CisgIGlmIChDaGVja1V0ZjgoZGVzY3JpcHRvcl8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiICAgIGlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIKKyAgICAiICAgICAgJG9uZW9mX25hbWUkXyA9IHM7XG4iCisgICAgIiAgICB9XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkgJiYgKCRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJCkpIHtcbiIKKyAgICAiICAgICAgJG9uZW9mX25hbWUkXyA9IHM7XG4iCisgICAgIiAgICB9XG4iKTsKKyAgfQorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIgICAgcmV0dXJuIHM7XG4iCisgICAgIiAgfVxuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworCisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nXG4iCisgICAgIiAgICBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRCeXRlcygpIHtcbiIKKyAgICAiICBqYXZhLmxhbmcuT2JqZWN0IHJlZiAkZGVmYXVsdF9pbml0JDtcbiIKKyAgICAiICBpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iCisgICAgIiAgICByZWYgPSAkb25lb2ZfbmFtZSRfO1xuIgorICAgICIgIH1cbiIKKyAgICAiICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykge1xuIgorICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSBcbiIKKyAgICAiICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KFxuIgorICAgICIgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTtcbiIKKyAgICAiICAgIGlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIKKyAgICAiICAgICAgJG9uZW9mX25hbWUkXyA9IGI7XG4iCisgICAgIiAgICB9XG4iCisgICAgIiAgICByZXR1cm4gYjtcbiIKKyAgICAiICB9IGVsc2Uge1xuIgorICAgICIgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjtcbiIKKyAgICAiICB9XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZVN0cmluZ09uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoU3VwcG9ydEZpZWxkUHJlc2VuY2UoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVwcmVjYXRpb24kcHVibGljIGJvb2xlYW4gaGFzJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICAgIiAgcmV0dXJuICRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJDtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAiICBqYXZhLmxhbmcuT2JqZWN0IHJlZiAkZGVmYXVsdF9pbml0JDtcbiIKKyAgICAiICBpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iCisgICAgIiAgICByZWYgPSAkb25lb2ZfbmFtZSRfO1xuIgorICAgICIgIH1cbiIKKyAgICAiICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkge1xuIgorICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID1cbiIKKyAgICAiICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7XG4iCisgICAgIiAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTtcbiIKKyAgICAiICAgIGlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIpOworICBpZiAoQ2hlY2tVdGY4KGRlc2NyaXB0b3JfKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiICAgICAgJG9uZW9mX25hbWUkXyA9IHM7XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7XG4iCisgICAgICAiICAgICAgICAkb25lb2ZfbmFtZSRfID0gcztcbiIKKyAgICAgICIgICAgICB9XG4iKTsKKyAgfQorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIgICAgfVxuIgorICAgICIgICAgcmV0dXJuIHM7XG4iCisgICAgIiAgfSBlbHNlIHtcbiIKKyAgICAiICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmO1xuIgorICAgICIgIH1cbiIKKyAgICAifVxuIik7CisKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZ1xuIgorICAgICIgICAgZ2V0JGNhcGl0YWxpemVkX25hbWUkQnl0ZXMoKSB7XG4iCisgICAgIiAgamF2YS5sYW5nLk9iamVjdCByZWYgJGRlZmF1bHRfaW5pdCQ7XG4iCisgICAgIiAgaWYgKCRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJCkge1xuIgorICAgICIgICAgcmVmID0gJG9uZW9mX25hbWUkXztcbiIKKyAgICAiICB9XG4iCisgICAgIiAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykge1xuIgorICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSBcbiIKKyAgICAiICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KFxuIgorICAgICIgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTtcbiIKKyAgICAiICAgIGlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIKKyAgICAiICAgICAgJG9uZW9mX25hbWUkXyA9IGI7XG4iCisgICAgIiAgICB9XG4iCisgICAgIiAgICByZXR1cm4gYjtcbiIKKyAgICAiICB9IGVsc2Uge1xuIgorICAgICIgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjtcbiIKKyAgICAiICB9XG4iCisgICAgIn1cbiIpOworCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIHNldCRjYXBpdGFsaXplZF9uYW1lJChcbiIKKyAgICAiICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHtcbiIKKyAgICAiJG51bGxfY2hlY2skIgorICAgICIgICRzZXRfb25lb2ZfY2FzZV9tZXNzYWdlJDtcbiIKKyAgICAiICAkb25lb2ZfbmFtZSRfID0gdmFsdWU7XG4iCisgICAgIiAgJG9uX2NoYW5nZWQkXG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBjbGVhciRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAiICBpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iCisgICAgIiAgICAkY2xlYXJfb25lb2ZfY2FzZV9tZXNzYWdlJDtcbiIKKyAgICAiICAgICRvbmVvZl9uYW1lJF8gPSBudWxsO1xuIgorICAgICIgICAgJG9uX2NoYW5nZWQkXG4iCisgICAgIiAgfVxuIgorICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICJ9XG4iKTsKKworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBzZXQkY2FwaXRhbGl6ZWRfbmFtZSRCeXRlcyhcbiIKKyAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkge1xuIgorICAgICIkbnVsbF9jaGVjayQiKTsKKyAgaWYgKENoZWNrVXRmOChkZXNjcmlwdG9yXykpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiAgY2hlY2tCeXRlU3RyaW5nSXNVdGY4KHZhbHVlKTtcbiIpOworICB9CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiAgJHNldF9vbmVvZl9jYXNlX21lc3NhZ2UkO1xuIgorICAgICIgICRvbmVvZl9uYW1lJF8gPSB2YWx1ZTtcbiIKKyAgICAiICAkb25fY2hhbmdlZCRcbiIKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlU3RyaW5nT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIEFsbG93IGEgc2xpZ2h0IGJyZWFjaCBvZiBhYnN0cmFjdGlvbiBoZXJlIGluIG9yZGVyIHRvIGF2b2lkIGZvcmNpbmcKKyAgLy8gYWxsIHN0cmluZyBmaWVsZHMgdG8gU3RyaW5ncyB3aGVuIGNvcHlpbmcgZmllbGRzIGZyb20gYSBNZXNzYWdlLgorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkc2V0X29uZW9mX2Nhc2VfbWVzc2FnZSQ7XG4iCisgICAgIiRvbmVvZl9uYW1lJF8gPSBvdGhlci4kb25lb2ZfbmFtZSRfO1xuIgorICAgICIkb25fY2hhbmdlZCRcbiIpOworfQorCit2b2lkIEltbXV0YWJsZVN0cmluZ09uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVCdWlsZGluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJCkge1xuIgorICAgICIgIHJlc3VsdC4kb25lb2ZfbmFtZSRfID0gJG9uZW9mX25hbWUkXztcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlU3RyaW5nT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVBhcnNpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChDaGVja1V0ZjgoZGVzY3JpcHRvcl8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJqYXZhLmxhbmcuU3RyaW5nIHMgPSBpbnB1dC5yZWFkU3RyaW5nUmVxdWlyZVV0ZjgoKTtcbiIKKyAgICAgICIkc2V0X29uZW9mX2Nhc2VfbWVzc2FnZSQ7XG4iCisgICAgICAiJG9uZW9mX25hbWUkXyA9IHM7XG4iKTsKKyAgfSBlbHNlIGlmICghSGFzRGVzY3JpcHRvck1ldGhvZHMoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICAvLyBMaXRlIHJ1bnRpbWUgc2hvdWxkIGF0dGVtcHQgdG8gcmVkdWNlIGFsbG9jYXRpb25zIGJ5IGF0dGVtcHRpbmcgdG8KKyAgICAvLyBjb25zdHJ1Y3QgdGhlIHN0cmluZyBkaXJlY3RseSBmcm9tIHRoZSBpbnB1dCBzdHJlYW0gYnVmZmVyLiBUaGlzIGF2b2lkcworICAgIC8vIHNwdXJpb3VzIGludGVybWVkaWFyeSBCeXRlU3RyaW5nIGFsbG9jYXRpb25zLCBjdXR0aW5nIG92ZXJhbGwgYWxsb2NhdGlvbnMKKyAgICAvLyBpbiBoYWxmLgorICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiamF2YS5sYW5nLlN0cmluZyBzID0gaW5wdXQucmVhZFN0cmluZygpO1xuIgorICAgICAgIiRzZXRfb25lb2ZfY2FzZV9tZXNzYWdlJDtcbiIKKyAgICAgICIkb25lb2ZfbmFtZSRfID0gcztcbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gaW5wdXQucmVhZEJ5dGVzKCk7XG4iCisgICAgICAiJHNldF9vbmVvZl9jYXNlX21lc3NhZ2UkO1xuIgorICAgICAgIiRvbmVvZl9uYW1lJF8gPSBicztcbiIpOworICB9Cit9CisKK3ZvaWQgSW1tdXRhYmxlU3RyaW5nT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIKKyAgICAiICAkd3JpdGVTdHJpbmckKG91dHB1dCwgJG51bWJlciQsICRvbmVvZl9uYW1lJF8pO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVTdHJpbmdPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIKKyAgICAiICBzaXplICs9ICRjb21wdXRlU3RyaW5nU2l6ZSQoJG51bWJlciQsICRvbmVvZl9uYW1lJF8pO1xuIgorICAgICJ9XG4iKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitSZXBlYXRlZEltbXV0YWJsZVN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK1JlcGVhdGVkSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYnVpbGRlckJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb250ZXh0KiBjb250ZXh0KQorICA6IGRlc2NyaXB0b3JfKGRlc2NyaXB0b3IpLCBtZXNzYWdlQml0SW5kZXhfKG1lc3NhZ2VCaXRJbmRleCksCisgICAgYnVpbGRlckJpdEluZGV4XyhidWlsZGVyQml0SW5kZXgpLCBjb250ZXh0Xyhjb250ZXh0KSwKKyAgICBuYW1lX3Jlc29sdmVyXyhjb250ZXh0LT5HZXROYW1lUmVzb2x2ZXIoKSkgeworICBTZXRQcmltaXRpdmVWYXJpYWJsZXMoZGVzY3JpcHRvciwgbWVzc2FnZUJpdEluZGV4LCBidWlsZGVyQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LT5HZXRGaWVsZEdlbmVyYXRvckluZm8oZGVzY3JpcHRvciksCisgICAgICAgICAgICAgICAgICAgICAgICBuYW1lX3Jlc29sdmVyXywgJnZhcmlhYmxlc18pOworfQorCitSZXBlYXRlZEltbXV0YWJsZVN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK35SZXBlYXRlZEltbXV0YWJsZVN0cmluZ0ZpZWxkR2VuZXJhdG9yKCkge30KKworaW50IFJlcGVhdGVkSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3I6OkdldE51bUJpdHNGb3JNZXNzYWdlKCkgY29uc3QgeworICByZXR1cm4gMDsKK30KKworaW50IFJlcGVhdGVkSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3I6OkdldE51bUJpdHNGb3JCdWlsZGVyKCkgY29uc3QgeworICByZXR1cm4gMTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZVN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlSW50ZXJmYWNlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sU3RyaW5nTGlzdFxuIgorICAgICIgICAgZ2V0JGNhcGl0YWxpemVkX25hbWUkTGlzdCgpO1xuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJGludCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRDb3VudCgpO1xuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJGphdmEubGFuZy5TdHJpbmcgZ2V0JGNhcGl0YWxpemVkX25hbWUkKGludCBpbmRleCk7XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nXG4iCisgICAgIiAgICBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRCeXRlcyhpbnQgaW5kZXgpO1xuIik7Cit9CisKKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZVN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0xpc3QgJG5hbWUkXztcbiIpOworICBQcmludEV4dHJhRmllbGRJbmZvKHZhcmlhYmxlc18sIHByaW50ZXIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3RcbiIKKyAgICAiICAgIGdldCRjYXBpdGFsaXplZF9uYW1lJExpc3QoKSB7XG4iCisgICAgIiAgcmV0dXJuICRuYW1lJF87XG4iICAgLy8gbm90ZTogIHVubW9kaWZpYWJsZSBsaXN0CisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgaW50IGdldCRjYXBpdGFsaXplZF9uYW1lJENvdW50KCkge1xuIgorICAgICIgIHJldHVybiAkbmFtZSRfLnNpemUoKTtcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldCRjYXBpdGFsaXplZF9uYW1lJChpbnQgaW5kZXgpIHtcbiIKKyAgICAiICByZXR1cm4gJG5hbWUkXy5nZXQoaW5kZXgpO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZ1xuIgorICAgICIgICAgZ2V0JGNhcGl0YWxpemVkX25hbWUkQnl0ZXMoaW50IGluZGV4KSB7XG4iCisgICAgIiAgcmV0dXJuICRuYW1lJF8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBPbmUgZmllbGQgaXMgdGhlIGxpc3QgYW5kIHRoZSBiaXQgZmllbGQga2VlcHMgdHJhY2sgb2Ygd2hldGhlciB0aGUKKyAgLy8gbGlzdCBpcyBpbW11dGFibGUuIElmIGl0J3MgaW1tdXRhYmxlLCB0aGUgaW52YXJpYW50IGlzIHRoYXQgaXQgbXVzdAorICAvLyBlaXRoZXIgYW4gaW5zdGFuY2Ugb2YgQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCkgb3IgaXQncyBhbiBBcnJheUxpc3QKKyAgLy8gd3JhcHBlZCBpbiBhIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoKSB3cmFwcGVyIGFuZCBub2JvZHkgZWxzZSBoYXMKKyAgLy8gYSByZWZlcmVyZW5jZSB0byB0aGUgdW5kZXJseWluZyBBcnJheUxpc3QuIFRoaXMgaW52YXJpYW50IGFsbG93cyB1cyB0bworICAvLyBzaGFyZSBpbnN0YW5jZXMgb2YgbGlzdHMgYmV0d2VlbiBwcm90b2NvbCBidWZmZXJzIGF2b2lkaW5nIGV4cGVuc2l2ZQorICAvLyBtZW1vcnkgYWxsb2NhdGlvbnMuIE5vdGUsIGltbXV0YWJsZSBpcyBhIHN0cm9uZyBndWFyYW50ZWUgaGVyZSAtLSBub3QKKyAgLy8ganVzdCB0aGF0IHRoZSBsaXN0IGNhbm5vdCBiZSBtb2RpZmllZCB2aWEgdGhlIHJlZmVyZW5jZSBidXQgdGhhdCB0aGUKKyAgLy8gbGlzdCBjYW4gbmV2ZXIgYmUgbW9kaWZpZWQuCisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nTGlzdCAkbmFtZSRfID0gJGVtcHR5X2xpc3QkO1xuIik7CisKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHJpdmF0ZSB2b2lkIGVuc3VyZSRjYXBpdGFsaXplZF9uYW1lJElzTXV0YWJsZSgpIHtcbiIKKyAgICAiICBpZiAoISRnZXRfbXV0YWJsZV9iaXRfYnVpbGRlciQpIHtcbiIKKyAgICAiICAgICRuYW1lJF8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0KCRuYW1lJF8pO1xuIgorICAgICIgICAgJHNldF9tdXRhYmxlX2JpdF9idWlsZGVyJDtcbiIKKyAgICAiICAgfVxuIgorICAgICJ9XG4iKTsKKworICAgIC8vIE5vdGU6ICBXZSByZXR1cm4gYW4gdW5tb2RpZmlhYmxlIGxpc3QgYmVjYXVzZSBvdGhlcndpc2UgdGhlIGNhbGxlcgorICAgIC8vICAgY291bGQgaG9sZCBvbiB0byB0aGUgcmV0dXJuZWQgbGlzdCBhbmQgbW9kaWZ5IGl0IGFmdGVyIHRoZSBtZXNzYWdlCisgICAgLy8gICBoYXMgYmVlbiBidWlsdCwgdGh1cyBtdXRhdGluZyB0aGUgbWVzc2FnZSB3aGljaCBpcyBzdXBwb3NlZCB0byBiZQorICAgIC8vICAgaW1tdXRhYmxlLgorICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3RcbiIKKyAgICAiICAgIGdldCRjYXBpdGFsaXplZF9uYW1lJExpc3QoKSB7XG4iCisgICAgIiAgcmV0dXJuICRuYW1lJF8uZ2V0VW5tb2RpZmlhYmxlVmlldygpO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIGludCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRDb3VudCgpIHtcbiIKKyAgICAiICByZXR1cm4gJG5hbWUkXy5zaXplKCk7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoaW50IGluZGV4KSB7XG4iCisgICAgIiAgcmV0dXJuICRuYW1lJF8uZ2V0KGluZGV4KTtcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmdcbiIKKyAgICAiICAgIGdldCRjYXBpdGFsaXplZF9uYW1lJEJ5dGVzKGludCBpbmRleCkge1xuIgorICAgICIgIHJldHVybiAkbmFtZSRfLmdldEJ5dGVTdHJpbmcoaW5kZXgpO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgc2V0JGNhcGl0YWxpemVkX25hbWUkKFxuIgorICAgICIgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7XG4iCisgICAgIiRudWxsX2NoZWNrJCIKKyAgICAiICBlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKTtcbiIKKyAgICAiICAkbmFtZSRfLnNldChpbmRleCwgdmFsdWUpO1xuIgorICAgICIgICRvbl9jaGFuZ2VkJFxuIgorICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgYWRkJGNhcGl0YWxpemVkX25hbWUkKFxuIgorICAgICIgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkge1xuIgorICAgICIkbnVsbF9jaGVjayQiCisgICAgIiAgZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCk7XG4iCisgICAgIiAgJG5hbWUkXy5hZGQodmFsdWUpO1xuIgorICAgICIgICRvbl9jaGFuZ2VkJFxuIgorICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgYWRkQWxsJGNhcGl0YWxpemVkX25hbWUkKFxuIgorICAgICIgICAgamF2YS5sYW5nLkl0ZXJhYmxlPGphdmEubGFuZy5TdHJpbmc+IHZhbHVlcykge1xuIgorICAgICIgIGVuc3VyZSRjYXBpdGFsaXplZF9uYW1lJElzTXV0YWJsZSgpO1xuIgorICAgICIgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbChcbiIKKyAgICAiICAgICAgdmFsdWVzLCAkbmFtZSRfKTtcbiIKKyAgICAiICAkb25fY2hhbmdlZCRcbiIKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGNsZWFyJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgICRuYW1lJF8gPSAkZW1wdHlfbGlzdCQ7XG4iCisgICAgIiAgJGNsZWFyX211dGFibGVfYml0X2J1aWxkZXIkO1xuIgorICAgICIgICRvbl9jaGFuZ2VkJFxuIgorICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICJ9XG4iKTsKKworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBhZGQkY2FwaXRhbGl6ZWRfbmFtZSRCeXRlcyhcbiIKKyAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkge1xuIgorICAgICIkbnVsbF9jaGVjayQiKTsKKyAgaWYgKENoZWNrVXRmOChkZXNjcmlwdG9yXykpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiAgY2hlY2tCeXRlU3RyaW5nSXNVdGY4KHZhbHVlKTtcbiIpOworICB9CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiAgZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCk7XG4iCisgICAgIiAgJG5hbWUkXy5hZGQodmFsdWUpO1xuIgorICAgICIgICRvbl9jaGFuZ2VkJFxuIgorICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZVN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlRmllbGRCdWlsZGVySW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSAgY29uc3QgeworICAvLyBub29wIGZvciBwcmltaXRpdmVzCit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVTdHJpbmdGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUluaXRpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAiJG5hbWUkXyA9ICRlbXB0eV9saXN0JDtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVCdWlsZGVyQ2xlYXJDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRuYW1lJF8gPSAkZW1wdHlfbGlzdCQ7XG4iCisgICAgIiRjbGVhcl9tdXRhYmxlX2JpdF9idWlsZGVyJDtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBUaGUgY29kZSBiZWxvdyBkb2VzIHR3byBvcHRpbWl6YXRpb25zOgorICAvLyAgIDEuIElmIHRoZSBvdGhlciBsaXN0IGlzIGVtcHR5LCB0aGVyZSdzIG5vdGhpbmcgdG8gZG8uIFRoaXMgZW5zdXJlcyB3ZQorICAvLyAgICAgIGRvbid0IGFsbG9jYXRlIGEgbmV3IGFycmF5IGlmIHdlIGFscmVhZHkgaGF2ZSBhbiBpbW11dGFibGUgb25lLgorICAvLyAgIDIuIElmIHRoZSBvdGhlciBsaXN0IGlzIG5vbi1lbXB0eSBhbmQgb3VyIGN1cnJlbnQgbGlzdCBpcyBlbXB0eSwgd2UgY2FuCisgIC8vICAgICAgcmV1c2UgdGhlIG90aGVyIGxpc3Qgd2hpY2ggaXMgZ3VhcmFudGVlZCB0byBiZSBpbW11dGFibGUuCisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICghb3RoZXIuJG5hbWUkXy5pc0VtcHR5KCkpIHtcbiIKKyAgICAiICBpZiAoJG5hbWUkXy5pc0VtcHR5KCkpIHtcbiIKKyAgICAiICAgICRuYW1lJF8gPSBvdGhlci4kbmFtZSRfO1xuIgorICAgICIgICAgJGNsZWFyX211dGFibGVfYml0X2J1aWxkZXIkO1xuIgorICAgICIgIH0gZWxzZSB7XG4iCisgICAgIiAgICBlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKTtcbiIKKyAgICAiICAgICRuYW1lJF8uYWRkQWxsKG90aGVyLiRuYW1lJF8pO1xuIgorICAgICIgIH1cbiIKKyAgICAiICAkb25fY2hhbmdlZCRcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVTdHJpbmdGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUJ1aWxkaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBUaGUgY29kZSBiZWxvdyBlbnN1cmVzIHRoYXQgdGhlIHJlc3VsdCBoYXMgYW4gaW1tdXRhYmxlIGxpc3QuIElmIG91cgorICAvLyBsaXN0IGlzIGltbXV0YWJsZSwgd2UgY2FuIGp1c3QgcmV1c2UgaXQuIElmIG5vdCwgd2UgbWFrZSBpdCBpbW11dGFibGUuCisKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCRnZXRfbXV0YWJsZV9iaXRfYnVpbGRlciQpIHtcbiIKKyAgICAiICAkbmFtZSRfID0gJG5hbWUkXy5nZXRVbm1vZGlmaWFibGVWaWV3KCk7XG4iCisgICAgIiAgJGNsZWFyX211dGFibGVfYml0X2J1aWxkZXIkO1xuIgorICAgICJ9XG4iCisgICAgInJlc3VsdC4kbmFtZSRfID0gJG5hbWUkXztcbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVQYXJzaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoQ2hlY2tVdGY4KGRlc2NyaXB0b3JfKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImphdmEubGFuZy5TdHJpbmcgcyA9IGlucHV0LnJlYWRTdHJpbmdSZXF1aXJlVXRmOCgpO1xuIik7CisgIH0gZWxzZSBpZiAoIUhhc0Rlc2NyaXB0b3JNZXRob2RzKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgLy8gTGl0ZSBydW50aW1lIHNob3VsZCBhdHRlbXB0IHRvIHJlZHVjZSBhbGxvY2F0aW9ucyBieSBhdHRlbXB0aW5nIHRvCisgICAgLy8gY29uc3RydWN0IHRoZSBzdHJpbmcgZGlyZWN0bHkgZnJvbSB0aGUgaW5wdXQgc3RyZWFtIGJ1ZmZlci4gVGhpcyBhdm9pZHMKKyAgICAvLyBzcHVyaW91cyBpbnRlcm1lZGlhcnkgQnl0ZVN0cmluZyBhbGxvY2F0aW9ucywgY3V0dGluZyBvdmVyYWxsIGFsbG9jYXRpb25zCisgICAgLy8gaW4gaGFsZi4KKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJqYXZhLmxhbmcuU3RyaW5nIHMgPSBpbnB1dC5yZWFkU3RyaW5nKCk7XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSBpbnB1dC5yZWFkQnl0ZXMoKTtcbiIpOworICB9CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICghJGdldF9tdXRhYmxlX2JpdF9wYXJzZXIkKSB7XG4iCisgICAgIiAgJG5hbWUkXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QoKTtcbiIKKyAgICAiICAkc2V0X211dGFibGVfYml0X3BhcnNlciQ7XG4iCisgICAgIn1cbiIpOworICBpZiAoQ2hlY2tVdGY4KGRlc2NyaXB0b3JfKSB8fCAhSGFzRGVzY3JpcHRvck1ldGhvZHMoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRuYW1lJF8uYWRkKHMpO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkbmFtZSRfLmFkZChicyk7XG4iKTsKKyAgfQorfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVQYXJzaW5nRG9uZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCRnZXRfbXV0YWJsZV9iaXRfcGFyc2VyJCkge1xuIgorICAgICIgICRuYW1lJF8gPSAkbmFtZSRfLmdldFVubW9kaWZpYWJsZVZpZXcoKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVTdHJpbmdGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImZvciAoaW50IGkgPSAwOyBpIDwgJG5hbWUkXy5zaXplKCk7IGkrKykge1xuIgorICAgICIgICR3cml0ZVN0cmluZyQob3V0cHV0LCAkbnVtYmVyJCwgJG5hbWUkXy5nZXRSYXcoaSkpO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZVN0cmluZ0ZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIntcbiIKKyAgICAiICBpbnQgZGF0YVNpemUgPSAwO1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImZvciAoaW50IGkgPSAwOyBpIDwgJG5hbWUkXy5zaXplKCk7IGkrKykge1xuIgorICAgICIgIGRhdGFTaXplICs9IGNvbXB1dGVTdHJpbmdTaXplTm9UYWcoJG5hbWUkXy5nZXRSYXcoaSkpO1xuIgorICAgICJ9XG4iKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAgICJzaXplICs9IGRhdGFTaXplO1xuIik7CisKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAic2l6ZSArPSAkdGFnX3NpemUkICogZ2V0JGNhcGl0YWxpemVkX25hbWUkTGlzdCgpLnNpemUoKTtcbiIpOworCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVFcXVhbHNDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInJlc3VsdCA9IHJlc3VsdCAmJiBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRMaXN0KClcbiIKKyAgICAiICAgIC5lcXVhbHMob3RoZXIuZ2V0JGNhcGl0YWxpemVkX25hbWUkTGlzdCgpKTtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVIYXNoQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoZ2V0JGNhcGl0YWxpemVkX25hbWUkQ291bnQoKSA+IDApIHtcbiIKKyAgICAiICBoYXNoID0gKDM3ICogaGFzaCkgKyAkY29uc3RhbnRfbmFtZSQ7XG4iCisgICAgIiAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0JGNhcGl0YWxpemVkX25hbWUkTGlzdCgpLmhhc2hDb2RlKCk7XG4iCisgICAgIn1cbiIpOworfQorCitzdHJpbmcgUmVwZWF0ZWRJbW11dGFibGVTdHJpbmdGaWVsZEdlbmVyYXRvcjo6R2V0Qm94ZWRUeXBlKCkgY29uc3QgeworICByZXR1cm4gIlN0cmluZyI7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfc3RyaW5nX2ZpZWxkLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9zdHJpbmdfZmllbGQuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hM2I1NzM1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfc3RyaW5nX2ZpZWxkLmgKQEAgLTAsMCArMSwxNTkgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyBBdXRob3I6IGpvbnBAZ29vZ2xlLmNvbSAoSm9uIFBlcmxvdykKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX1NUUklOR19GSUVMRF9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfU1RSSU5HX0ZJRUxEX0hfXworCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2ZpZWxkLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKyAgbmFtZXNwYWNlIGNvbXBpbGVyIHsKKyAgICBuYW1lc3BhY2UgamF2YSB7CisgICAgICBjbGFzcyBDb250ZXh0OyAgICAgICAgICAgLy8gY29udGV4dC5oCisgICAgICBjbGFzcyBDbGFzc05hbWVSZXNvbHZlcjsgLy8gbmFtZV9yZXNvbHZlci5oCisgICAgfQorICB9Cit9CisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmEgeworCitjbGFzcyBJbW11dGFibGVTdHJpbmdGaWVsZEdlbmVyYXRvciA6IHB1YmxpYyBJbW11dGFibGVGaWVsZEdlbmVyYXRvciB7CisgcHVibGljOgorICBleHBsaWNpdCBJbW11dGFibGVTdHJpbmdGaWVsZEdlbmVyYXRvcigKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwgaW50IG1lc3NhZ2VCaXRJbmRleCwKKyAgICAgIGludCBidWlsZGVyQml0SW5kZXgsIENvbnRleHQqIGNvbnRleHQpOworICB+SW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3IoKTsKKworICAvLyBpbXBsZW1lbnRzIEltbXV0YWJsZUZpZWxkR2VuZXJhdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICBpbnQgR2V0TnVtQml0c0Zvck1lc3NhZ2UoKSBjb25zdDsKKyAgaW50IEdldE51bUJpdHNGb3JCdWlsZGVyKCkgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVJbnRlcmZhY2VNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnVpbGRlck1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUJ1aWxkZXJDbGVhckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnVpbGRpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVBhcnNpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVBhcnNpbmdEb25lQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRmllbGRCdWlsZGVySW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUVxdWFsc0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSGFzaENvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgIHN0cmluZyBHZXRCb3hlZFR5cGUoKSBjb25zdDsKKworIHByb3RlY3RlZDoKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXNfOworICBjb25zdCBpbnQgbWVzc2FnZUJpdEluZGV4XzsKKyAgY29uc3QgaW50IGJ1aWxkZXJCaXRJbmRleF87CisgIENvbnRleHQqIGNvbnRleHRfOworICBDbGFzc05hbWVSZXNvbHZlciogbmFtZV9yZXNvbHZlcl87CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3IpOworfTsKKworY2xhc3MgSW1tdXRhYmxlU3RyaW5nT25lb2ZGaWVsZEdlbmVyYXRvcgorICAgIDogcHVibGljIEltbXV0YWJsZVN0cmluZ0ZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIEltbXV0YWJsZVN0cmluZ09uZW9mRmllbGRHZW5lcmF0b3IoCisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGludCBtZXNzYWdlQml0SW5kZXgsCisgICAgICBpbnQgYnVpbGRlckJpdEluZGV4LCBDb250ZXh0KiBjb250ZXh0KTsKKyAgfkltbXV0YWJsZVN0cmluZ09uZW9mRmllbGRHZW5lcmF0b3IoKTsKKworIHByaXZhdGU6CisgIHZvaWQgR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUJ1aWxkZXJNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUJ1aWxkaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVQYXJzaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhJbW11dGFibGVTdHJpbmdPbmVvZkZpZWxkR2VuZXJhdG9yKTsKK307CisKK2NsYXNzIFJlcGVhdGVkSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3IgOiBwdWJsaWMgSW1tdXRhYmxlRmllbGRHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgUmVwZWF0ZWRJbW11dGFibGVTdHJpbmdGaWVsZEdlbmVyYXRvcigKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwgaW50IG1lc3NhZ2VCaXRJbmRleCwKKyAgICAgIGludCBidWlsZGVyQml0SW5kZXgsIENvbnRleHQqIGNvbnRleHQpOworICB+UmVwZWF0ZWRJbW11dGFibGVTdHJpbmdGaWVsZEdlbmVyYXRvcigpOworCisgIC8vIGltcGxlbWVudHMgSW1tdXRhYmxlRmllbGRHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIGludCBHZXROdW1CaXRzRm9yTWVzc2FnZSgpIGNvbnN0OworICBpbnQgR2V0TnVtQml0c0ZvckJ1aWxkZXIoKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUludGVyZmFjZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQnVpbGRlckNsZWFyQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCdWlsZGluZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlUGFyc2luZ0RvbmVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVGaWVsZEJ1aWxkZXJJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVIYXNoQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyAgc3RyaW5nIEdldEJveGVkVHlwZSgpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXNfOworICBjb25zdCBpbnQgbWVzc2FnZUJpdEluZGV4XzsKKyAgY29uc3QgaW50IGJ1aWxkZXJCaXRJbmRleF87CisgIENvbnRleHQqIGNvbnRleHRfOworICBDbGFzc05hbWVSZXNvbHZlciogbmFtZV9yZXNvbHZlcl87CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFJlcGVhdGVkSW1tdXRhYmxlU3RyaW5nRmllbGRHZW5lcmF0b3IpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfU1RSSU5HX0ZJRUxEX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfc3RyaW5nX2ZpZWxkX2xpdGUuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9zdHJpbmdfZmllbGRfbGl0ZS5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lYjU5NjRiCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfc3RyaW5nX2ZpZWxkX2xpdGUuY2MKQEAgLTAsMCArMSw5MDAgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyBBdXRob3I6IGpvbnBAZ29vZ2xlLmNvbSAoSm9uIFBlcmxvdykKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHN0cmluZz4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9sb2dnaW5nLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfY29udGV4dC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZG9jX2NvbW1lbnQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX25hbWVfcmVzb2x2ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX3N0cmluZ19maWVsZF9saXRlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmEgeworCit1c2luZyBpbnRlcm5hbDo6V2lyZUZvcm1hdDsKK3VzaW5nIGludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTsKKworbmFtZXNwYWNlIHsKKwordm9pZCBTZXRQcmltaXRpdmVWYXJpYWJsZXMoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG1lc3NhZ2VCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBidWlsZGVyQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZEdlbmVyYXRvckluZm8qIGluZm8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICBDbGFzc05hbWVSZXNvbHZlciogbmFtZV9yZXNvbHZlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcDxzdHJpbmcsIHN0cmluZz4qIHZhcmlhYmxlcykgeworICBTZXRDb21tb25GaWVsZFZhcmlhYmxlcyhkZXNjcmlwdG9yLCBpbmZvLCB2YXJpYWJsZXMpOworCisgICgqdmFyaWFibGVzKVsiZW1wdHlfbGlzdCJdID0KKyAgICAgICJjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VMaXRlLmVtcHR5UHJvdG9idWZMaXN0KCkiOworCisgICgqdmFyaWFibGVzKVsiZGVmYXVsdCJdID0gSW1tdXRhYmxlRGVmYXVsdFZhbHVlKGRlc2NyaXB0b3IsIG5hbWVfcmVzb2x2ZXIpOworICAoKnZhcmlhYmxlcylbImRlZmF1bHRfaW5pdCJdID0KKyAgICAgICI9ICIgKyBJbW11dGFibGVEZWZhdWx0VmFsdWUoZGVzY3JpcHRvciwgbmFtZV9yZXNvbHZlcik7CisgICgqdmFyaWFibGVzKVsiY2FwaXRhbGl6ZWRfdHlwZSJdID0gIlN0cmluZyI7CisgICgqdmFyaWFibGVzKVsidGFnIl0gPSBTaW1wbGVJdG9hKFdpcmVGb3JtYXQ6Ok1ha2VUYWcoZGVzY3JpcHRvcikpOworICAoKnZhcmlhYmxlcylbInRhZ19zaXplIl0gPSBTaW1wbGVJdG9hKAorICAgICAgV2lyZUZvcm1hdDo6VGFnU2l6ZShkZXNjcmlwdG9yLT5udW1iZXIoKSwgR2V0VHlwZShkZXNjcmlwdG9yKSkpOworICAoKnZhcmlhYmxlcylbIm51bGxfY2hlY2siXSA9CisgICAgICAiICBpZiAodmFsdWUgPT0gbnVsbCkge1xuIgorICAgICAgIiAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTtcbiIKKyAgICAgICIgIH1cbiI7CisKKyAgLy8gVE9ETyhiaXJkbyk6IEFkZCBAZGVwcmVjYXRlZCBqYXZhZG9jIHdoZW4gZ2VuZXJhdGluZyBqYXZhZG9jIGlzIHN1cHBvcnRlZAorICAvLyBieSB0aGUgcHJvdG8gY29tcGlsZXIKKyAgKCp2YXJpYWJsZXMpWyJkZXByZWNhdGlvbiJdID0gZGVzY3JpcHRvci0+b3B0aW9ucygpLmRlcHJlY2F0ZWQoKQorICAgICAgPyAiQGphdmEubGFuZy5EZXByZWNhdGVkICIgOiAiIjsKKyAgKCp2YXJpYWJsZXMpWyJvbl9jaGFuZ2VkIl0gPQorICAgICAgSGFzRGVzY3JpcHRvck1ldGhvZHMoZGVzY3JpcHRvci0+Y29udGFpbmluZ190eXBlKCkpID8gIm9uQ2hhbmdlZCgpOyIgOiAiIjsKKworICBpZiAoU3VwcG9ydEZpZWxkUHJlc2VuY2UoZGVzY3JpcHRvci0+ZmlsZSgpKSkgeworICAgIC8vIEZvciBzaW5ndWxhciBtZXNzYWdlcyBhbmQgYnVpbGRlcnMsIG9uZSBiaXQgaXMgdXNlZCBmb3IgdGhlIGhhc0ZpZWxkIGJpdC4KKyAgICAoKnZhcmlhYmxlcylbImdldF9oYXNfZmllbGRfYml0X21lc3NhZ2UiXSA9IEdlbmVyYXRlR2V0Qml0KG1lc3NhZ2VCaXRJbmRleCk7CisKKyAgICAvLyBOb3RlIHRoYXQgdGhlc2UgaGF2ZSBhIHRyYWlsaW5nICI7Ii4KKyAgICAoKnZhcmlhYmxlcylbInNldF9oYXNfZmllbGRfYml0X21lc3NhZ2UiXSA9CisgICAgICAgIEdlbmVyYXRlU2V0Qml0KG1lc3NhZ2VCaXRJbmRleCkgKyAiOyI7CisgICAgKCp2YXJpYWJsZXMpWyJjbGVhcl9oYXNfZmllbGRfYml0X21lc3NhZ2UiXSA9CisgICAgICAgIEdlbmVyYXRlQ2xlYXJCaXQobWVzc2FnZUJpdEluZGV4KSArICI7IjsKKworICAgICgqdmFyaWFibGVzKVsiaXNfZmllbGRfcHJlc2VudF9tZXNzYWdlIl0gPSBHZW5lcmF0ZUdldEJpdChtZXNzYWdlQml0SW5kZXgpOworICB9IGVsc2UgeworICAgICgqdmFyaWFibGVzKVsic2V0X2hhc19maWVsZF9iaXRfbWVzc2FnZSJdID0gIiI7CisgICAgKCp2YXJpYWJsZXMpWyJjbGVhcl9oYXNfZmllbGRfYml0X21lc3NhZ2UiXSA9ICIiOworCisgICAgKCp2YXJpYWJsZXMpWyJpc19maWVsZF9wcmVzZW50X21lc3NhZ2UiXSA9CisgICAgICAgICIhZ2V0IiArICgqdmFyaWFibGVzKVsiY2FwaXRhbGl6ZWRfbmFtZSJdICsgIi5pc0VtcHR5KCkiOworICB9CisKKyAgLy8gRm9yIHJlcGVhdGVkIGJ1aWxkZXJzLCB0aGUgdW5kZXJseWluZyBsaXN0IHRyYWNrcyBtdXRhYmlsaXR5IHN0YXRlLgorICAoKnZhcmlhYmxlcylbImlzX211dGFibGUiXSA9ICgqdmFyaWFibGVzKVsibmFtZSJdICsgIl8uaXNNb2RpZmlhYmxlKCkiOworCisgICgqdmFyaWFibGVzKVsiZ2V0X2hhc19maWVsZF9iaXRfZnJvbV9sb2NhbCJdID0KKyAgICAgIEdlbmVyYXRlR2V0Qml0RnJvbUxvY2FsKGJ1aWxkZXJCaXRJbmRleCk7CisgICgqdmFyaWFibGVzKVsic2V0X2hhc19maWVsZF9iaXRfdG9fbG9jYWwiXSA9CisgICAgICBHZW5lcmF0ZVNldEJpdFRvTG9jYWwobWVzc2FnZUJpdEluZGV4KTsKK30KKworfSAgLy8gbmFtZXNwYWNlCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworSW1tdXRhYmxlU3RyaW5nRmllbGRMaXRlR2VuZXJhdG9yOjoKK0ltbXV0YWJsZVN0cmluZ0ZpZWxkTGl0ZUdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnRleHQqIGNvbnRleHQpCisgIDogZGVzY3JpcHRvcl8oZGVzY3JpcHRvciksIG1lc3NhZ2VCaXRJbmRleF8obWVzc2FnZUJpdEluZGV4KSwKKyAgICBidWlsZGVyQml0SW5kZXhfKGJ1aWxkZXJCaXRJbmRleCksIGNvbnRleHRfKGNvbnRleHQpLAorICAgIG5hbWVfcmVzb2x2ZXJfKGNvbnRleHQtPkdldE5hbWVSZXNvbHZlcigpKSB7CisgIFNldFByaW1pdGl2ZVZhcmlhYmxlcyhkZXNjcmlwdG9yLCBtZXNzYWdlQml0SW5kZXgsIGJ1aWxkZXJCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQtPkdldEZpZWxkR2VuZXJhdG9ySW5mbyhkZXNjcmlwdG9yKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVfcmVzb2x2ZXJfLCAmdmFyaWFibGVzXyk7Cit9CisKK0ltbXV0YWJsZVN0cmluZ0ZpZWxkTGl0ZUdlbmVyYXRvcjo6fkltbXV0YWJsZVN0cmluZ0ZpZWxkTGl0ZUdlbmVyYXRvcigpIHt9CisKK2ludCBJbW11dGFibGVTdHJpbmdGaWVsZExpdGVHZW5lcmF0b3I6OkdldE51bUJpdHNGb3JNZXNzYWdlKCkgY29uc3QgeworICByZXR1cm4gMTsKK30KKworaW50IEltbXV0YWJsZVN0cmluZ0ZpZWxkTGl0ZUdlbmVyYXRvcjo6R2V0TnVtQml0c0ZvckJ1aWxkZXIoKSBjb25zdCB7CisgIHJldHVybiAwOworfQorCisvLyBBIG5vdGUgYWJvdXQgaG93IHN0cmluZ3MgYXJlIGhhbmRsZWQuIEluIHRoZSBTUEVFRCBhbmQgQ09ERV9TSVpFIHJ1bnRpbWVzLAorLy8gc3RyaW5ncyBhcmUgbm90IHN0b3JlZCBhcyBqYXZhLmxhbmcuU3RyaW5nIGluIHRoZSBNZXNzYWdlIGJlY2F1c2Ugb2YgdHdvCisvLyBpc3N1ZXM6CisvLworLy8gIDEuIEl0IHdvdWxkbid0IHJvdW5kdHJpcCBieXRlIGFycmF5cyB0aGF0IHdlcmUgbm90IHZhaWQgVVRGLTggZW5jb2RlZAorLy8gICAgIHN0cmluZ3MsIGJ1dCByYXRoZXIgZmllbGRzIHRoYXQgd2VyZSByYXcgYnl0ZXMgaW5jb3JyZWN0bHkgbWFya2VkCisvLyAgICAgYXMgc3RyaW5ncyBpbiB0aGUgcHJvdG8gZmlsZS4gVGhpcyBpcyBjb21tb24gYmVjYXVzZSBpbiB0aGUgcHJvdG8xCisvLyAgICAgc3ludGF4LCBzdHJpbmcgd2FzIHRoZSB3YXkgdG8gaW5kaWNhdGUgYnl0ZXMgYW5kIEMrKyBlbmdpbmVlcnMgY2FuCisvLyAgICAgZWFzaWx5IG1ha2UgdGhpcyBtaXN0YWtlIHdpdGhvdXQgYWZmZWN0aW5nIHRoZSBDKysgQVBJLiBCeSBjb252ZXJ0aW5nIHRvCisvLyAgICAgc3RyaW5ncyBpbW1lZGlhdGVseSwgc29tZSBqYXZhIGNvZGUgbWlnaHQgY29ycnVwdCB0aGVzZSBieXRlIGFycmF5cyBhcworLy8gICAgIGl0IHBhc3NlcyB0aHJvdWdoIGEgamF2YSBzZXJ2ZXIgZXZlbiBpZiB0aGUgZmllbGQgd2FzIG5ldmVyIGFjY2Vzc2VkIGJ5CisvLyAgICAgYXBwbGljYXRpb24gY29kZS4KKy8vCisvLyAgMi4gVGhlcmUncyBhIHBlcmZvcm1hbmNlIGhpdCB0byBjb252ZXJ0aW5nIGJldHdlZW4gYnl0ZXMgYW5kIHN0cmluZ3MgYW5kCisvLyAgICAgaXQgbWFueSBjYXNlcywgdGhlIGZpZWxkIGlzIG5ldmVyIGV2ZW4gcmVhZCBieSB0aGUgYXBwbGljYXRpb24gY29kZS4gVGhpcworLy8gICAgIGF2b2lkcyB1bm5lY2Vzc2FyeSBjb252ZXJzaW9ucyBpbiB0aGUgY29tbW9uIHVzZSBjYXNlcy4KKy8vCisvLyBJbiB0aGUgTElURV9SVU5USU1FLCB3ZSBzdG9yZSBzdHJpbmdzIGFzIGphdmEubGFuZy5TdHJpbmcgYmVjYXVzZSB3ZSBhc3N1bWUKKy8vIHRoYXQgdGhlIHVzZXJzIG9mIHRoaXMgcnVudGltZSBhcmUgbm90IHN1YmplY3QgdG8gcHJvdG8xIGNvbnN0cmFpbnRzIGFuZCBhcmUKKy8vIHJ1bm5pbmcgY29kZSBvbiBkZXZpY2VzIHRoYXQgYXJlIHVzZXIgZmFjaW5nLiBUaGF0IGlzLCB0aGUgZGV2ZWxvcGVycyBhcmUKKy8vIHByb3Blcmx5IGluY2VudGl2aXplZCB0byBvbmx5IGZldGNoIHRoZSBkYXRhIHRoZXkgbmVlZCB0byByZWFkIGFuZCB3aXNoIHRvCisvLyByZWR1Y2UgdGhlIG51bWJlciBvZiBhbGxvY2F0aW9ucyBpbmN1cnJlZCB3aGVuIHJ1bm5pbmcgb24gYSB1c2VyJ3MgZGV2aWNlLgorCisvLyBUT0RPKGR3ZWlzKTogQ29uc2lkZXIgZHJvcHBpbmcgYWxsIG9mIHRoZSAqQnl0ZXMoKSBtZXRob2RzLiBUaGV5IHJlYWxseQorLy8gICAgIHNob3VsZG4ndCBiZSBuZWNlc3Nhcnkgb3IgdXNlZCBvbiBkZXZpY2VzLgordm9pZCBJbW11dGFibGVTdHJpbmdGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVJbnRlcmZhY2VNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRib29sZWFuIGhhcyRjYXBpdGFsaXplZF9uYW1lJCgpO1xuIik7CisgIH0KKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kamF2YS5sYW5nLlN0cmluZyBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKTtcbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmdcbiIKKyAgICAiICAgIGdldCRjYXBpdGFsaXplZF9uYW1lJEJ5dGVzKCk7XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVTdHJpbmdGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgamF2YS5sYW5nLlN0cmluZyAkbmFtZSRfO1xuIik7CisgIFByaW50RXh0cmFGaWVsZEluZm8odmFyaWFibGVzXywgcHJpbnRlcik7CisKKyAgaWYgKFN1cHBvcnRGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBib29sZWFuIGhhcyRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAgICIgIHJldHVybiAkZ2V0X2hhc19maWVsZF9iaXRfbWVzc2FnZSQ7XG4iCisgICAgICAifVxuIik7CisgIH0KKworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgcmV0dXJuICRuYW1lJF87XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nXG4iCisgICAgIiAgICBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRCeXRlcygpIHtcbiIKKyAgICAiICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgkbmFtZSRfKTtcbiIKKyAgICAifVxuIik7CisKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIHZvaWQgc2V0JGNhcGl0YWxpemVkX25hbWUkKFxuIgorICAgICIgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkge1xuIgorICAgICIkbnVsbF9jaGVjayQiCisgICAgIiAgJHNldF9oYXNfZmllbGRfYml0X21lc3NhZ2UkXG4iCisgICAgIiAgJG5hbWUkXyA9IHZhbHVlO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIHZvaWQgY2xlYXIkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgJGNsZWFyX2hhc19maWVsZF9iaXRfbWVzc2FnZSRcbiIKKyAgICAvLyBUaGUgZGVmYXVsdCB2YWx1ZSBpcyBub3QgYSBzaW1wbGUgbGl0ZXJhbCBzbyB3ZSB3YW50IHRvIGF2b2lkIGV4ZWN1dGluZworICAgIC8vIGl0IG11bHRpcGxlIHRpbWVzLiAgSW5zdGVhZCwgZ2V0IHRoZSBkZWZhdWx0IG91dCBvZiB0aGUgZGVmYXVsdCBpbnN0YW5jZS4KKyAgICAiICAkbmFtZSRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0JGNhcGl0YWxpemVkX25hbWUkKCk7XG4iCisgICAgIn1cbiIpOworCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHJpdmF0ZSB2b2lkIHNldCRjYXBpdGFsaXplZF9uYW1lJEJ5dGVzKFxuIgorICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7XG4iCisgICAgIiRudWxsX2NoZWNrJCIpOworICBpZiAoQ2hlY2tVdGY4KGRlc2NyaXB0b3JfKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiICBjaGVja0J5dGVTdHJpbmdJc1V0ZjgodmFsdWUpO1xuIik7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiICAkc2V0X2hhc19maWVsZF9iaXRfbWVzc2FnZSRcbiIKKyAgICAiICAkbmFtZSRfID0gdmFsdWUudG9TdHJpbmdVdGY4KCk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZVN0cmluZ0ZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUJ1aWxkZXJNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgYm9vbGVhbiBoYXMkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgICAiICByZXR1cm4gaW5zdGFuY2UuaGFzJGNhcGl0YWxpemVkX25hbWUkKCk7XG4iCisgICAgICAifVxuIik7CisgIH0KKworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgcmV0dXJuIGluc3RhbmNlLmdldCRjYXBpdGFsaXplZF9uYW1lJCgpO1xuIgorICAgICJ9XG4iKTsKKworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nXG4iCisgICAgIiAgICBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRCeXRlcygpIHtcbiIKKyAgICAiICByZXR1cm4gaW5zdGFuY2UuZ2V0JGNhcGl0YWxpemVkX25hbWUkQnl0ZXMoKTtcbiIKKyAgICAifVxuIik7CisKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgc2V0JGNhcGl0YWxpemVkX25hbWUkKFxuIgorICAgICIgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkge1xuIgorICAgICIgIGNvcHlPbldyaXRlKCk7XG4iCisgICAgIiAgaW5zdGFuY2Uuc2V0JGNhcGl0YWxpemVkX25hbWUkKHZhbHVlKTtcbiIKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGNsZWFyJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgIGNvcHlPbldyaXRlKCk7XG4iCisgICAgIiAgaW5zdGFuY2UuY2xlYXIkY2FwaXRhbGl6ZWRfbmFtZSQoKTtcbiIKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIik7CisKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgc2V0JGNhcGl0YWxpemVkX25hbWUkQnl0ZXMoXG4iCisgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHtcbiIKKyAgICAiICBjb3B5T25Xcml0ZSgpO1xuIgorICAgICIgIGluc3RhbmNlLnNldCRjYXBpdGFsaXplZF9uYW1lJEJ5dGVzKHZhbHVlKTtcbiIKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlU3RyaW5nRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlRmllbGRCdWlsZGVySW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSAgY29uc3QgeworICAvLyBub29wIGZvciBzdHJpbmdzCit9CisKK3ZvaWQgSW1tdXRhYmxlU3RyaW5nRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlSW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sICIkbmFtZSRfID0gJGRlZmF1bHQkO1xuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlU3RyaW5nRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKFN1cHBvcnRGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgLy8gQWxsb3cgYSBzbGlnaHQgYnJlYWNoIG9mIGFic3RyYWN0aW9uIGhlcmUgaW4gb3JkZXIgdG8gYXZvaWQgZm9yY2luZworICAgIC8vIGFsbCBzdHJpbmcgZmllbGRzIHRvIFN0cmluZ3Mgd2hlbiBjb3B5aW5nIGZpZWxkcyBmcm9tIGEgTWVzc2FnZS4KKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImlmIChvdGhlci5oYXMkY2FwaXRhbGl6ZWRfbmFtZSQoKSkge1xuIgorICAgICAgIiAgJHNldF9oYXNfZmllbGRfYml0X21lc3NhZ2UkXG4iCisgICAgICAiICAkbmFtZSRfID0gb3RoZXIuJG5hbWUkXztcbiIKKyAgICAgICIgICRvbl9jaGFuZ2VkJFxuIgorICAgICAgIn1cbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaWYgKCFvdGhlci5nZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKS5pc0VtcHR5KCkpIHtcbiIKKyAgICAgICIgICRuYW1lJF8gPSBvdGhlci4kbmFtZSRfO1xuIgorICAgICAgIiAgJG9uX2NoYW5nZWQkXG4iCisgICAgICAifVxuIik7CisgIH0KK30KKwordm9pZCBJbW11dGFibGVTdHJpbmdGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVEeW5hbWljTWV0aG9kTWFrZUltbXV0YWJsZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gbm9vcCBmb3Igc2NhbGFycworfQorCit2b2lkIEltbXV0YWJsZVN0cmluZ0ZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZVBhcnNpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChDaGVja1V0ZjgoZGVzY3JpcHRvcl8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJTdHJpbmcgcyA9IGlucHV0LnJlYWRTdHJpbmdSZXF1aXJlVXRmOCgpO1xuIgorICAgICAgIiRzZXRfaGFzX2ZpZWxkX2JpdF9tZXNzYWdlJFxuIgorICAgICAgIiRuYW1lJF8gPSBzO1xuIik7CisgIH0gZWxzZSB7CisgICAgLy8gTGl0ZSBydW50aW1lIHNob3VsZCBhdHRlbXB0IHRvIHJlZHVjZSBhbGxvY2F0aW9ucyBieSBhdHRlbXB0aW5nIHRvCisgICAgLy8gY29uc3RydWN0IHRoZSBzdHJpbmcgZGlyZWN0bHkgZnJvbSB0aGUgaW5wdXQgc3RyZWFtIGJ1ZmZlci4gVGhpcyBhdm9pZHMKKyAgICAvLyBzcHVyaW91cyBpbnRlcm1lZGlhcnkgQnl0ZVN0cmluZyBhbGxvY2F0aW9ucywgY3V0dGluZyBvdmVyYWxsIGFsbG9jYXRpb25zCisgICAgLy8gaW4gaGFsZi4KKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIlN0cmluZyBzID0gaW5wdXQucmVhZFN0cmluZygpO1xuIgorICAgICAgIiRzZXRfaGFzX2ZpZWxkX2JpdF9tZXNzYWdlJFxuIgorICAgICAgIiRuYW1lJF8gPSBzO1xuIik7CisgIH0KK30KKwordm9pZCBJbW11dGFibGVTdHJpbmdGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVQYXJzaW5nRG9uZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gbm9vcCBmb3Igc3RyaW5ncworfQorCit2b2lkIEltbXV0YWJsZVN0cmluZ0ZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIExpdGUgcnVudGltZSBzaG91bGQgcmVkdWNlIGFsbG9jYXRpb25zIGJ5IHNlcmlhbGl6aW5nIHRoZSBzdHJpbmcgZGlyZWN0bHkuCisgIC8vIFRoaXMgYXZvaWRzIHNwdXJpb3VzIGludGVybWVkaWFyeSBCeXRlU3RyaW5nIGFsbG9jYXRpb25zLCBjdXR0aW5nIG92ZXJhbGwKKyAgLy8gYWxsb2NhdGlvbnMgaW4gaGFsZi4KKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCRpc19maWVsZF9wcmVzZW50X21lc3NhZ2UkKSB7XG4iCisgICAgIiAgb3V0cHV0LndyaXRlU3RyaW5nKCRudW1iZXIkLCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZVN0cmluZ0ZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBMaXRlIHJ1bnRpbWUgc2hvdWxkIHJlZHVjZSBhbGxvY2F0aW9ucyBieSBjb21wdXRpbmcgb24gdGhlIHN0cmluZyBkaXJlY3RseS4KKyAgLy8gVGhpcyBhdm9pZHMgc3B1cmlvdXMgaW50ZXJtZWRpYXJ5IEJ5dGVTdHJpbmcgYWxsb2NhdGlvbnMsIGN1dHRpbmcgb3ZlcmFsbAorICAvLyBhbGxvY2F0aW9ucyBpbiBoYWxmLgorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoJGlzX2ZpZWxkX3ByZXNlbnRfbWVzc2FnZSQpIHtcbiIKKyAgICAiICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW1cbiIKKyAgICAiICAgIC5jb21wdXRlU3RyaW5nU2l6ZSgkbnVtYmVyJCwgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkpO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVTdHJpbmdGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVFcXVhbHNDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInJlc3VsdCA9IHJlc3VsdCAmJiBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKVxuIgorICAgICIgICAgLmVxdWFscyhvdGhlci5nZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSk7XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVTdHJpbmdGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVIYXNoQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJoYXNoID0gKDM3ICogaGFzaCkgKyAkY29uc3RhbnRfbmFtZSQ7XG4iKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkuaGFzaENvZGUoKTtcbiIpOworfQorCitzdHJpbmcgSW1tdXRhYmxlU3RyaW5nRmllbGRMaXRlR2VuZXJhdG9yOjpHZXRCb3hlZFR5cGUoKSBjb25zdCB7CisgIHJldHVybiAiamF2YS5sYW5nLlN0cmluZyI7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworSW1tdXRhYmxlU3RyaW5nT25lb2ZGaWVsZExpdGVHZW5lcmF0b3I6OgorSW1tdXRhYmxlU3RyaW5nT25lb2ZGaWVsZExpdGVHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYnVpbGRlckJpdEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb250ZXh0KiBjb250ZXh0KQorICAgIDogSW1tdXRhYmxlU3RyaW5nRmllbGRMaXRlR2VuZXJhdG9yKAorICAgICAgICAgIGRlc2NyaXB0b3IsIG1lc3NhZ2VCaXRJbmRleCwgYnVpbGRlckJpdEluZGV4LCBjb250ZXh0KSB7CisgIGNvbnN0IE9uZW9mR2VuZXJhdG9ySW5mbyogaW5mbyA9CisgICAgICBjb250ZXh0LT5HZXRPbmVvZkdlbmVyYXRvckluZm8oZGVzY3JpcHRvci0+Y29udGFpbmluZ19vbmVvZigpKTsKKyAgU2V0Q29tbW9uT25lb2ZWYXJpYWJsZXMoZGVzY3JpcHRvciwgaW5mbywgJnZhcmlhYmxlc18pOworfQorCitJbW11dGFibGVTdHJpbmdPbmVvZkZpZWxkTGl0ZUdlbmVyYXRvcjo6Cit+SW1tdXRhYmxlU3RyaW5nT25lb2ZGaWVsZExpdGVHZW5lcmF0b3IoKSB7fQorCit2b2lkIEltbXV0YWJsZVN0cmluZ09uZW9mRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBQcmludEV4dHJhRmllbGRJbmZvKHZhcmlhYmxlc18sIHByaW50ZXIpOworCisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgYm9vbGVhbiBoYXMkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgcmV0dXJuICRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJDtcbiIKKyAgICAifVxuIik7CisgIH0KKworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgamF2YS5sYW5nLlN0cmluZyByZWYgJGRlZmF1bHRfaW5pdCQ7XG4iCisgICAgIiAgaWYgKCRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJCkge1xuIgorICAgICIgICAgcmVmID0gKGphdmEubGFuZy5TdHJpbmcpICRvbmVvZl9uYW1lJF87XG4iCisgICAgIiAgfVxuIgorICAgICIgIHJldHVybiByZWY7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmdcbiIKKyAgICAiICAgIGdldCRjYXBpdGFsaXplZF9uYW1lJEJ5dGVzKCkge1xuIgorICAgICIgIGphdmEubGFuZy5TdHJpbmcgcmVmICRkZWZhdWx0X2luaXQkO1xuIgorICAgICIgIGlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIKKyAgICAiICAgIHJlZiA9IChqYXZhLmxhbmcuU3RyaW5nKSAkb25lb2ZfbmFtZSRfO1xuIgorICAgICIgIH1cbiIKKyAgICAiICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOChyZWYpO1xuIgorICAgICJ9XG4iKTsKKworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInByaXZhdGUgdm9pZCBzZXQkY2FwaXRhbGl6ZWRfbmFtZSQoXG4iCisgICAgIiAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7XG4iCisgICAgIiRudWxsX2NoZWNrJCIKKyAgICAiICAkc2V0X29uZW9mX2Nhc2VfbWVzc2FnZSQ7XG4iCisgICAgIiAgJG9uZW9mX25hbWUkXyA9IHZhbHVlO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIHZvaWQgY2xlYXIkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgaWYgKCRoYXNfb25lb2ZfY2FzZV9tZXNzYWdlJCkge1xuIgorICAgICIgICAgJGNsZWFyX29uZW9mX2Nhc2VfbWVzc2FnZSQ7XG4iCisgICAgIiAgICAkb25lb2ZfbmFtZSRfID0gbnVsbDtcbiIKKyAgICAiICB9XG4iCisgICAgIn1cbiIpOworCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHJpdmF0ZSB2b2lkIHNldCRjYXBpdGFsaXplZF9uYW1lJEJ5dGVzKFxuIgorICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7XG4iCisgICAgIiRudWxsX2NoZWNrJCIpOworICBpZiAoQ2hlY2tVdGY4KGRlc2NyaXB0b3JfKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiICBjaGVja0J5dGVTdHJpbmdJc1V0ZjgodmFsdWUpO1xuIik7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiICAkc2V0X29uZW9mX2Nhc2VfbWVzc2FnZSQ7XG4iCisgICAgIiAgJG9uZW9mX25hbWUkXyA9IHZhbHVlLnRvU3RyaW5nVXRmOCgpO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBJbW11dGFibGVTdHJpbmdPbmVvZkZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUJ1aWxkZXJNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChTdXBwb3J0RmllbGRQcmVzZW5jZShkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgYm9vbGVhbiBoYXMkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgICAiICByZXR1cm4gaW5zdGFuY2UuaGFzJGNhcGl0YWxpemVkX25hbWUkKCk7XG4iCisgICAgICAifVxuIik7CisgIH0KKworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgcmV0dXJuIGluc3RhbmNlLmdldCRjYXBpdGFsaXplZF9uYW1lJCgpO1xuIgorICAgICJ9XG4iKTsKKworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nXG4iCisgICAgIiAgICBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRCeXRlcygpIHtcbiIKKyAgICAiICByZXR1cm4gaW5zdGFuY2UuZ2V0JGNhcGl0YWxpemVkX25hbWUkQnl0ZXMoKTtcbiIKKyAgICAifVxuIik7CisKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgc2V0JGNhcGl0YWxpemVkX25hbWUkKFxuIgorICAgICIgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkge1xuIgorICAgICIgIGNvcHlPbldyaXRlKCk7XG4iCisgICAgIiAgaW5zdGFuY2Uuc2V0JGNhcGl0YWxpemVkX25hbWUkKHZhbHVlKTtcbiIKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGNsZWFyJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgIGNvcHlPbldyaXRlKCk7XG4iCisgICAgIiAgaW5zdGFuY2UuY2xlYXIkY2FwaXRhbGl6ZWRfbmFtZSQoKTtcbiIKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIik7CisKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgc2V0JGNhcGl0YWxpemVkX25hbWUkQnl0ZXMoXG4iCisgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHtcbiIKKyAgICAiICBjb3B5T25Xcml0ZSgpO1xuIgorICAgICIgIGluc3RhbmNlLnNldCRjYXBpdGFsaXplZF9uYW1lJEJ5dGVzKHZhbHVlKTtcbiIKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgSW1tdXRhYmxlU3RyaW5nT25lb2ZGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBBbGxvdyBhIHNsaWdodCBicmVhY2ggb2YgYWJzdHJhY3Rpb24gaGVyZSBpbiBvcmRlciB0byBhdm9pZCBmb3JjaW5nCisgIC8vIGFsbCBzdHJpbmcgZmllbGRzIHRvIFN0cmluZ3Mgd2hlbiBjb3B5aW5nIGZpZWxkcyBmcm9tIGEgTWVzc2FnZS4KKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJHNldF9vbmVvZl9jYXNlX21lc3NhZ2UkO1xuIgorICAgICIkb25lb2ZfbmFtZSRfID0gb3RoZXIuJG9uZW9mX25hbWUkXztcbiIKKyAgICAiJG9uX2NoYW5nZWQkXG4iKTsKK30KKwordm9pZCBJbW11dGFibGVTdHJpbmdPbmVvZkZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZVBhcnNpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChDaGVja1V0ZjgoZGVzY3JpcHRvcl8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJTdHJpbmcgcyA9IGlucHV0LnJlYWRTdHJpbmdSZXF1aXJlVXRmOCgpO1xuIgorICAgICAgIiRzZXRfb25lb2ZfY2FzZV9tZXNzYWdlJDtcbiIKKyAgICAgICIkb25lb2ZfbmFtZSRfID0gcztcbiIpOworICB9IGVsc2UgeworICAgIC8vIExpdGUgcnVudGltZSBzaG91bGQgYXR0ZW1wdCB0byByZWR1Y2UgYWxsb2NhdGlvbnMgYnkgYXR0ZW1wdGluZyB0bworICAgIC8vIGNvbnN0cnVjdCB0aGUgc3RyaW5nIGRpcmVjdGx5IGZyb20gdGhlIGlucHV0IHN0cmVhbSBidWZmZXIuIFRoaXMgYXZvaWRzCisgICAgLy8gc3B1cmlvdXMgaW50ZXJtZWRpYXJ5IEJ5dGVTdHJpbmcgYWxsb2NhdGlvbnMsIGN1dHRpbmcgb3ZlcmFsbCBhbGxvY2F0aW9ucworICAgIC8vIGluIGhhbGYuCisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJTdHJpbmcgcyA9IGlucHV0LnJlYWRTdHJpbmcoKTtcbiIKKyAgICAgICIkc2V0X29uZW9mX2Nhc2VfbWVzc2FnZSQ7XG4iCisgICAgICAiJG9uZW9mX25hbWUkXyA9IHM7XG4iKTsKKyAgfQorfQorCit2b2lkIEltbXV0YWJsZVN0cmluZ09uZW9mRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gTGl0ZSBydW50aW1lIHNob3VsZCByZWR1Y2UgYWxsb2NhdGlvbnMgYnkgc2VyaWFsaXppbmcgdGhlIHN0cmluZyBkaXJlY3RseS4KKyAgLy8gVGhpcyBhdm9pZHMgc3B1cmlvdXMgaW50ZXJtZWRpYXJ5IEJ5dGVTdHJpbmcgYWxsb2NhdGlvbnMsIGN1dHRpbmcgb3ZlcmFsbAorICAvLyBhbGxvY2F0aW9ucyBpbiBoYWxmLgorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoJGhhc19vbmVvZl9jYXNlX21lc3NhZ2UkKSB7XG4iCisgICAgIiAgb3V0cHV0LndyaXRlU3RyaW5nKCRudW1iZXIkLCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEltbXV0YWJsZVN0cmluZ09uZW9mRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIExpdGUgcnVudGltZSBzaG91bGQgcmVkdWNlIGFsbG9jYXRpb25zIGJ5IGNvbXB1dGluZyBvbiB0aGUgc3RyaW5nIGRpcmVjdGx5LgorICAvLyBUaGlzIGF2b2lkcyBzcHVyaW91cyBpbnRlcm1lZGlhcnkgQnl0ZVN0cmluZyBhbGxvY2F0aW9ucywgY3V0dGluZyBvdmVyYWxsCisgIC8vIGFsbG9jYXRpb25zIGluIGhhbGYuCisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkaGFzX29uZW9mX2Nhc2VfbWVzc2FnZSQpIHtcbiIKKyAgICAiICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW1cbiIKKyAgICAiICAgIC5jb21wdXRlU3RyaW5nU2l6ZSgkbnVtYmVyJCwgZ2V0JGNhcGl0YWxpemVkX25hbWUkKCkpO1xuIgorICAgICJ9XG4iKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitSZXBlYXRlZEltbXV0YWJsZVN0cmluZ0ZpZWxkTGl0ZUdlbmVyYXRvcjo6CitSZXBlYXRlZEltbXV0YWJsZVN0cmluZ0ZpZWxkTGl0ZUdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBtZXNzYWdlQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBidWlsZGVyQml0SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnRleHQqIGNvbnRleHQpCisgIDogZGVzY3JpcHRvcl8oZGVzY3JpcHRvciksIG1lc3NhZ2VCaXRJbmRleF8obWVzc2FnZUJpdEluZGV4KSwKKyAgICBidWlsZGVyQml0SW5kZXhfKGJ1aWxkZXJCaXRJbmRleCksIGNvbnRleHRfKGNvbnRleHQpLAorICAgIG5hbWVfcmVzb2x2ZXJfKGNvbnRleHQtPkdldE5hbWVSZXNvbHZlcigpKSB7CisgIFNldFByaW1pdGl2ZVZhcmlhYmxlcyhkZXNjcmlwdG9yLCBtZXNzYWdlQml0SW5kZXgsIGJ1aWxkZXJCaXRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQtPkdldEZpZWxkR2VuZXJhdG9ySW5mbyhkZXNjcmlwdG9yKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVfcmVzb2x2ZXJfLCAmdmFyaWFibGVzXyk7Cit9CisKK1JlcGVhdGVkSW1tdXRhYmxlU3RyaW5nRmllbGRMaXRlR2VuZXJhdG9yOjoKK35SZXBlYXRlZEltbXV0YWJsZVN0cmluZ0ZpZWxkTGl0ZUdlbmVyYXRvcigpIHt9CisKK2ludCBSZXBlYXRlZEltbXV0YWJsZVN0cmluZ0ZpZWxkTGl0ZUdlbmVyYXRvcjo6R2V0TnVtQml0c0Zvck1lc3NhZ2UoKSBjb25zdCB7CisgIHJldHVybiAwOworfQorCitpbnQgUmVwZWF0ZWRJbW11dGFibGVTdHJpbmdGaWVsZExpdGVHZW5lcmF0b3I6OkdldE51bUJpdHNGb3JCdWlsZGVyKCkgY29uc3QgeworICByZXR1cm4gMDsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZVN0cmluZ0ZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUludGVyZmFjZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kamF2YS51dGlsLkxpc3Q8U3RyaW5nPlxuIgorICAgICIgICAgZ2V0JGNhcGl0YWxpemVkX25hbWUkTGlzdCgpO1xuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJGludCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRDb3VudCgpO1xuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJGphdmEubGFuZy5TdHJpbmcgZ2V0JGNhcGl0YWxpemVkX25hbWUkKGludCBpbmRleCk7XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nXG4iCisgICAgIiAgICBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRCeXRlcyhpbnQgaW5kZXgpO1xuIik7Cit9CisKKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZVN0cmluZ0ZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLlByb3RvYnVmTGlzdDxTdHJpbmc+ICRuYW1lJF87XG4iKTsKKyAgUHJpbnRFeHRyYUZpZWxkSW5mbyh2YXJpYWJsZXNfLCBwcmludGVyKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIGphdmEudXRpbC5MaXN0PFN0cmluZz4gZ2V0JGNhcGl0YWxpemVkX25hbWUkTGlzdCgpIHtcbiIKKyAgICAiICByZXR1cm4gJG5hbWUkXztcbiIgICAvLyBub3RlOiAgdW5tb2RpZmlhYmxlIGxpc3QKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBpbnQgZ2V0JGNhcGl0YWxpemVkX25hbWUkQ291bnQoKSB7XG4iCisgICAgIiAgcmV0dXJuICRuYW1lJF8uc2l6ZSgpO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0JGNhcGl0YWxpemVkX25hbWUkKGludCBpbmRleCkge1xuIgorICAgICIgIHJldHVybiAkbmFtZSRfLmdldChpbmRleCk7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nXG4iCisgICAgIiAgICBnZXQkY2FwaXRhbGl6ZWRfbmFtZSRCeXRlcyhpbnQgaW5kZXgpIHtcbiIKKyAgICAiICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOChcbiIKKyAgICAiICAgICAgJG5hbWUkXy5nZXQoaW5kZXgpKTtcbiIKKyAgICAifVxuIik7CisKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHJpdmF0ZSB2b2lkIGVuc3VyZSRjYXBpdGFsaXplZF9uYW1lJElzTXV0YWJsZSgpIHtcbiIKKyAgICAiICBpZiAoISRpc19tdXRhYmxlJCkge1xuIgorICAgICIgICAgJG5hbWUkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZUxpdGUubmV3UHJvdG9idWZMaXN0KFxuIgorICAgICIgICAgICAgICRuYW1lJF8pO1xuIgorICAgICIgICB9XG4iCisgICAgIn1cbiIpOworCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHJpdmF0ZSB2b2lkIHNldCRjYXBpdGFsaXplZF9uYW1lJChcbiIKKyAgICAiICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkge1xuIgorICAgICIkbnVsbF9jaGVjayQiCisgICAgIiAgZW5zdXJlJGNhcGl0YWxpemVkX25hbWUkSXNNdXRhYmxlKCk7XG4iCisgICAgIiAgJG5hbWUkXy5zZXQoaW5kZXgsIHZhbHVlKTtcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHJpdmF0ZSB2b2lkIGFkZCRjYXBpdGFsaXplZF9uYW1lJChcbiIKKyAgICAiICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHtcbiIKKyAgICAiJG51bGxfY2hlY2skIgorICAgICIgIGVuc3VyZSRjYXBpdGFsaXplZF9uYW1lJElzTXV0YWJsZSgpO1xuIgorICAgICIgICRuYW1lJF8uYWRkKHZhbHVlKTtcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHJpdmF0ZSB2b2lkIGFkZEFsbCRjYXBpdGFsaXplZF9uYW1lJChcbiIKKyAgICAiICAgIGphdmEubGFuZy5JdGVyYWJsZTxqYXZhLmxhbmcuU3RyaW5nPiB2YWx1ZXMpIHtcbiIKKyAgICAiICBlbnN1cmUkY2FwaXRhbGl6ZWRfbmFtZSRJc011dGFibGUoKTtcbiIKKyAgICAiICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuYWRkQWxsKFxuIgorICAgICIgICAgICB2YWx1ZXMsICRuYW1lJF8pO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIHZvaWQgY2xlYXIkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgJG5hbWUkXyA9ICRlbXB0eV9saXN0JDtcbiIKKyAgICAifVxuIik7CisKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwcml2YXRlIHZvaWQgYWRkJGNhcGl0YWxpemVkX25hbWUkQnl0ZXMoXG4iCisgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHtcbiIKKyAgICAiJG51bGxfY2hlY2skIik7CisgIGlmIChDaGVja1V0ZjgoZGVzY3JpcHRvcl8pKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIgIGNoZWNrQnl0ZVN0cmluZ0lzVXRmOCh2YWx1ZSk7XG4iKTsKKyAgfQorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIgIGVuc3VyZSRjYXBpdGFsaXplZF9uYW1lJElzTXV0YWJsZSgpO1xuIgorICAgICIgICRuYW1lJF8uYWRkKHZhbHVlLnRvU3RyaW5nVXRmOCgpKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVTdHJpbmdGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgamF2YS51dGlsLkxpc3Q8U3RyaW5nPlxuIgorICAgICIgICAgZ2V0JGNhcGl0YWxpemVkX25hbWUkTGlzdCgpIHtcbiIKKyAgICAiICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoXG4iCisgICAgIiAgICAgIGluc3RhbmNlLmdldCRjYXBpdGFsaXplZF9uYW1lJExpc3QoKSk7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgaW50IGdldCRjYXBpdGFsaXplZF9uYW1lJENvdW50KCkge1xuIgorICAgICIgIHJldHVybiBpbnN0YW5jZS5nZXQkY2FwaXRhbGl6ZWRfbmFtZSRDb3VudCgpO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0JGNhcGl0YWxpemVkX25hbWUkKGludCBpbmRleCkge1xuIgorICAgICIgIHJldHVybiBpbnN0YW5jZS5nZXQkY2FwaXRhbGl6ZWRfbmFtZSQoaW5kZXgpO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZ1xuIgorICAgICIgICAgZ2V0JGNhcGl0YWxpemVkX25hbWUkQnl0ZXMoaW50IGluZGV4KSB7XG4iCisgICAgIiAgcmV0dXJuIGluc3RhbmNlLmdldCRjYXBpdGFsaXplZF9uYW1lJEJ5dGVzKGluZGV4KTtcbiIKKyAgICAifVxuIik7CisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIHNldCRjYXBpdGFsaXplZF9uYW1lJChcbiIKKyAgICAiICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkge1xuIgorICAgICIgIGNvcHlPbldyaXRlKCk7XG4iCisgICAgIiAgaW5zdGFuY2Uuc2V0JGNhcGl0YWxpemVkX25hbWUkKGluZGV4LCB2YWx1ZSk7XG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBhZGQkY2FwaXRhbGl6ZWRfbmFtZSQoXG4iCisgICAgIiAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7XG4iCisgICAgIiAgY29weU9uV3JpdGUoKTtcbiIKKyAgICAiICBpbnN0YW5jZS5hZGQkY2FwaXRhbGl6ZWRfbmFtZSQodmFsdWUpO1xuIgorICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICJ9XG4iKTsKKyAgV3JpdGVGaWVsZERvY0NvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8pOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkZGVwcmVjYXRpb24kcHVibGljIEJ1aWxkZXIgYWRkQWxsJGNhcGl0YWxpemVkX25hbWUkKFxuIgorICAgICIgICAgamF2YS5sYW5nLkl0ZXJhYmxlPGphdmEubGFuZy5TdHJpbmc+IHZhbHVlcykge1xuIgorICAgICIgIGNvcHlPbldyaXRlKCk7XG4iCisgICAgIiAgaW5zdGFuY2UuYWRkQWxsJGNhcGl0YWxpemVkX25hbWUkKHZhbHVlcyk7XG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworICBXcml0ZUZpZWxkRG9jQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRkZXByZWNhdGlvbiRwdWJsaWMgQnVpbGRlciBjbGVhciRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAiICBjb3B5T25Xcml0ZSgpO1xuIgorICAgICIgIGluc3RhbmNlLmNsZWFyJGNhcGl0YWxpemVkX25hbWUkKCk7XG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworCisgIFdyaXRlRmllbGREb2NDb21tZW50KHByaW50ZXIsIGRlc2NyaXB0b3JfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJGRlcHJlY2F0aW9uJHB1YmxpYyBCdWlsZGVyIGFkZCRjYXBpdGFsaXplZF9uYW1lJEJ5dGVzKFxuIgorICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7XG4iCisgICAgIiAgY29weU9uV3JpdGUoKTtcbiIKKyAgICAiICBpbnN0YW5jZS5hZGQkY2FwaXRhbGl6ZWRfbmFtZSRCeXRlcyh2YWx1ZSk7XG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlU3RyaW5nRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlRmllbGRCdWlsZGVySW5pdGlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSAgY29uc3QgeworICAvLyBub29wIGZvciBzdHJpbmdzCit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVTdHJpbmdGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgIiRuYW1lJF8gPSAkZW1wdHlfbGlzdCQ7XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZVN0cmluZ0ZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIFRoZSBjb2RlIGJlbG93IGRvZXMgdHdvIG9wdGltaXphdGlvbnM6CisgIC8vICAgMS4gSWYgdGhlIG90aGVyIGxpc3QgaXMgZW1wdHksIHRoZXJlJ3Mgbm90aGluZyB0byBkby4gVGhpcyBlbnN1cmVzIHdlCisgIC8vICAgICAgZG9uJ3QgYWxsb2NhdGUgYSBuZXcgYXJyYXkgaWYgd2UgYWxyZWFkeSBoYXZlIGFuIGltbXV0YWJsZSBvbmUuCisgIC8vICAgMi4gSWYgdGhlIG90aGVyIGxpc3QgaXMgbm9uLWVtcHR5IGFuZCBvdXIgY3VycmVudCBsaXN0IGlzIGVtcHR5LCB3ZSBjYW4KKyAgLy8gICAgICByZXVzZSB0aGUgb3RoZXIgbGlzdCB3aGljaCBpcyBndWFyYW50ZWVkIHRvIGJlIGltbXV0YWJsZS4KKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCFvdGhlci4kbmFtZSRfLmlzRW1wdHkoKSkge1xuIgorICAgICIgIGlmICgkbmFtZSRfLmlzRW1wdHkoKSkge1xuIgorICAgICIgICAgJG5hbWUkXyA9IG90aGVyLiRuYW1lJF87XG4iCisgICAgIiAgfSBlbHNlIHtcbiIKKyAgICAiICAgIGVuc3VyZSRjYXBpdGFsaXplZF9uYW1lJElzTXV0YWJsZSgpO1xuIgorICAgICIgICAgJG5hbWUkXy5hZGRBbGwob3RoZXIuJG5hbWUkXyk7XG4iCisgICAgIiAgfVxuIgorICAgICIgICRvbl9jaGFuZ2VkJFxuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZVN0cmluZ0ZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUR5bmFtaWNNZXRob2RNYWtlSW1tdXRhYmxlQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkbmFtZSRfLm1ha2VJbW11dGFibGUoKTtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlU3RyaW5nRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKENoZWNrVXRmOChkZXNjcmlwdG9yXykpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJTdHJpbmcgcyA9IGlucHV0LnJlYWRTdHJpbmdSZXF1aXJlVXRmOCgpO1xuIik7CisgIH0gZWxzZSB7CisgICAgLy8gTGl0ZSBydW50aW1lIHNob3VsZCBhdHRlbXB0IHRvIHJlZHVjZSBhbGxvY2F0aW9ucyBieSBhdHRlbXB0aW5nIHRvCisgICAgLy8gY29uc3RydWN0IHRoZSBzdHJpbmcgZGlyZWN0bHkgZnJvbSB0aGUgaW5wdXQgc3RyZWFtIGJ1ZmZlci4gVGhpcyBhdm9pZHMKKyAgICAvLyBzcHVyaW91cyBpbnRlcm1lZGlhcnkgQnl0ZVN0cmluZyBhbGxvY2F0aW9ucywgY3V0dGluZyBvdmVyYWxsIGFsbG9jYXRpb25zCisgICAgLy8gaW4gaGFsZi4KKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJTdHJpbmcgcyA9IGlucHV0LnJlYWRTdHJpbmcoKTtcbiIpOworICB9CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICghJGlzX211dGFibGUkKSB7XG4iCisgICAgIiAgJG5hbWUkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZUxpdGUubmV3UHJvdG9idWZMaXN0KCk7XG4iCisgICAgIn1cbiIpOworICBpZiAoQ2hlY2tVdGY4KGRlc2NyaXB0b3JfKSB8fCAhSGFzRGVzY3JpcHRvck1ldGhvZHMoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRuYW1lJF8uYWRkKHMpO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkbmFtZSRfLmFkZChicyk7XG4iKTsKKyAgfQorfQorCit2b2lkIFJlcGVhdGVkSW1tdXRhYmxlU3RyaW5nRmllbGRMaXRlR2VuZXJhdG9yOjoKK0dlbmVyYXRlUGFyc2luZ0RvbmVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkaXNfbXV0YWJsZSQpIHtcbiIKKyAgICAiICAkbmFtZSRfLm1ha2VJbW11dGFibGUoKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVTdHJpbmdGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBMaXRlIHJ1bnRpbWUgc2hvdWxkIHJlZHVjZSBhbGxvY2F0aW9ucyBieSBzZXJpYWxpemluZyB0aGUgc3RyaW5nIGRpcmVjdGx5LgorICAvLyBUaGlzIGF2b2lkcyBzcHVyaW91cyBpbnRlcm1lZGlhcnkgQnl0ZVN0cmluZyBhbGxvY2F0aW9ucywgY3V0dGluZyBvdmVyYWxsCisgIC8vIGFsbG9jYXRpb25zIGluIGhhbGYuCisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImZvciAoaW50IGkgPSAwOyBpIDwgJG5hbWUkXy5zaXplKCk7IGkrKykge1xuIgorICAgICIgIG91dHB1dC53cml0ZVN0cmluZygkbnVtYmVyJCwgJG5hbWUkXy5nZXQoaSkpO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZVN0cmluZ0ZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBMaXRlIHJ1bnRpbWUgc2hvdWxkIHJlZHVjZSBhbGxvY2F0aW9ucyBieSBjb21wdXRpbmcgb24gdGhlIHN0cmluZyBkaXJlY3RseS4KKyAgLy8gVGhpcyBhdm9pZHMgc3B1cmlvdXMgaW50ZXJtZWRpYXJ5IEJ5dGVTdHJpbmcgYWxsb2NhdGlvbnMsIGN1dHRpbmcgb3ZlcmFsbAorICAvLyBhbGxvY2F0aW9ucyBpbiBoYWxmLgorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJ7XG4iCisgICAgIiAgaW50IGRhdGFTaXplID0gMDtcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJmb3IgKGludCBpID0gMDsgaSA8ICRuYW1lJF8uc2l6ZSgpOyBpKyspIHtcbiIKKyAgICAiICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtXG4iCisgICAgIiAgICAuY29tcHV0ZVN0cmluZ1NpemVOb1RhZygkbmFtZSRfLmdldChpKSk7XG4iCisgICAgIn1cbiIpOworCisgIHByaW50ZXItPlByaW50KAorICAgICAgInNpemUgKz0gZGF0YVNpemU7XG4iKTsKKworCisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInNpemUgKz0gJHRhZ19zaXplJCAqIGdldCRjYXBpdGFsaXplZF9uYW1lJExpc3QoKS5zaXplKCk7XG4iKTsKKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KCJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEltbXV0YWJsZVN0cmluZ0ZpZWxkTGl0ZUdlbmVyYXRvcjo6CitHZW5lcmF0ZUVxdWFsc0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicmVzdWx0ID0gcmVzdWx0ICYmIGdldCRjYXBpdGFsaXplZF9uYW1lJExpc3QoKVxuIgorICAgICIgICAgLmVxdWFscyhvdGhlci5nZXQkY2FwaXRhbGl6ZWRfbmFtZSRMaXN0KCkpO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRJbW11dGFibGVTdHJpbmdGaWVsZExpdGVHZW5lcmF0b3I6OgorR2VuZXJhdGVIYXNoQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoZ2V0JGNhcGl0YWxpemVkX25hbWUkQ291bnQoKSA+IDApIHtcbiIKKyAgICAiICBoYXNoID0gKDM3ICogaGFzaCkgKyAkY29uc3RhbnRfbmFtZSQ7XG4iCisgICAgIiAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0JGNhcGl0YWxpemVkX25hbWUkTGlzdCgpLmhhc2hDb2RlKCk7XG4iCisgICAgIn1cbiIpOworfQorCitzdHJpbmcgUmVwZWF0ZWRJbW11dGFibGVTdHJpbmdGaWVsZExpdGVHZW5lcmF0b3I6OkdldEJveGVkVHlwZSgpIGNvbnN0IHsKKyAgcmV0dXJuICJTdHJpbmciOworfQorCit9ICAvLyBuYW1lc3BhY2UgamF2YQorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YS9qYXZhX3N0cmluZ19maWVsZF9saXRlLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9zdHJpbmdfZmllbGRfbGl0ZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRkOWI0YmQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9zdHJpbmdfZmllbGRfbGl0ZS5oCkBAIC0wLDAgKzEsMTU3IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gQXV0aG9yOiBqb25wQGdvb2dsZS5jb20gKEpvbiBQZXJsb3cpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQV9TVFJJTkdfRklFTERfTElURV9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFfU1RSSU5HX0ZJRUxEX0xJVEVfSF9fCisKKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhL2phdmFfZmllbGQuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworICBuYW1lc3BhY2UgY29tcGlsZXIgeworICAgIG5hbWVzcGFjZSBqYXZhIHsKKyAgICAgIGNsYXNzIENvbnRleHQ7ICAgICAgICAgICAvLyBjb250ZXh0LmgKKyAgICAgIGNsYXNzIENsYXNzTmFtZVJlc29sdmVyOyAvLyBuYW1lX3Jlc29sdmVyLmgKKyAgICB9CisgIH0KK30KKworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YSB7CisKK2NsYXNzIEltbXV0YWJsZVN0cmluZ0ZpZWxkTGl0ZUdlbmVyYXRvciA6IHB1YmxpYyBJbW11dGFibGVGaWVsZExpdGVHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgSW1tdXRhYmxlU3RyaW5nRmllbGRMaXRlR2VuZXJhdG9yKAorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBpbnQgbWVzc2FnZUJpdEluZGV4LAorICAgICAgaW50IGJ1aWxkZXJCaXRJbmRleCwgQ29udGV4dCogY29udGV4dCk7CisgIH5JbW11dGFibGVTdHJpbmdGaWVsZExpdGVHZW5lcmF0b3IoKTsKKworICAvLyBpbXBsZW1lbnRzIEltbXV0YWJsZUZpZWxkTGl0ZUdlbmVyYXRvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgaW50IEdldE51bUJpdHNGb3JNZXNzYWdlKCkgY29uc3Q7CisgIGludCBHZXROdW1CaXRzRm9yQnVpbGRlcigpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSW50ZXJmYWNlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUJ1aWxkZXJNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUluaXRpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVEeW5hbWljTWV0aG9kTWFrZUltbXV0YWJsZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlUGFyc2luZ0RvbmVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVGaWVsZEJ1aWxkZXJJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVIYXNoQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyAgc3RyaW5nIEdldEJveGVkVHlwZSgpIGNvbnN0OworCisgcHJvdGVjdGVkOgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlc187CisgIGNvbnN0IGludCBtZXNzYWdlQml0SW5kZXhfOworICBjb25zdCBpbnQgYnVpbGRlckJpdEluZGV4XzsKKyAgQ29udGV4dCogY29udGV4dF87CisgIENsYXNzTmFtZVJlc29sdmVyKiBuYW1lX3Jlc29sdmVyXzsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhJbW11dGFibGVTdHJpbmdGaWVsZExpdGVHZW5lcmF0b3IpOworfTsKKworY2xhc3MgSW1tdXRhYmxlU3RyaW5nT25lb2ZGaWVsZExpdGVHZW5lcmF0b3IKKyAgICA6IHB1YmxpYyBJbW11dGFibGVTdHJpbmdGaWVsZExpdGVHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgSW1tdXRhYmxlU3RyaW5nT25lb2ZGaWVsZExpdGVHZW5lcmF0b3IoCisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGludCBtZXNzYWdlQml0SW5kZXgsCisgICAgICBpbnQgYnVpbGRlckJpdEluZGV4LCBDb250ZXh0KiBjb250ZXh0KTsKKyAgfkltbXV0YWJsZVN0cmluZ09uZW9mRmllbGRMaXRlR2VuZXJhdG9yKCk7CisKKyBwcml2YXRlOgorICB2b2lkIEdlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVCdWlsZGVyTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVQYXJzaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhJbW11dGFibGVTdHJpbmdPbmVvZkZpZWxkTGl0ZUdlbmVyYXRvcik7Cit9OworCitjbGFzcyBSZXBlYXRlZEltbXV0YWJsZVN0cmluZ0ZpZWxkTGl0ZUdlbmVyYXRvcgorICAgIDogcHVibGljIEltbXV0YWJsZUZpZWxkTGl0ZUdlbmVyYXRvciB7CisgcHVibGljOgorICBleHBsaWNpdCBSZXBlYXRlZEltbXV0YWJsZVN0cmluZ0ZpZWxkTGl0ZUdlbmVyYXRvcigKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwgaW50IG1lc3NhZ2VCaXRJbmRleCwKKyAgICAgIGludCBidWlsZGVyQml0SW5kZXgsIENvbnRleHQqIGNvbnRleHQpOworICB+UmVwZWF0ZWRJbW11dGFibGVTdHJpbmdGaWVsZExpdGVHZW5lcmF0b3IoKTsKKworICAvLyBpbXBsZW1lbnRzIEltbXV0YWJsZUZpZWxkTGl0ZUdlbmVyYXRvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgaW50IEdldE51bUJpdHNGb3JNZXNzYWdlKCkgY29uc3Q7CisgIGludCBHZXROdW1CaXRzRm9yQnVpbGRlcigpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSW50ZXJmYWNlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUJ1aWxkZXJNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUluaXRpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVEeW5hbWljTWV0aG9kTWFrZUltbXV0YWJsZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlUGFyc2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlUGFyc2luZ0RvbmVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVGaWVsZEJ1aWxkZXJJbml0aWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVIYXNoQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyAgc3RyaW5nIEdldEJveGVkVHlwZSgpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXNfOworICBjb25zdCBpbnQgbWVzc2FnZUJpdEluZGV4XzsKKyAgY29uc3QgaW50IGJ1aWxkZXJCaXRJbmRleF87CisgIENvbnRleHQqIGNvbnRleHRfOworICBDbGFzc05hbWVSZXNvbHZlciogbmFtZV9yZXNvbHZlcl87CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFJlcGVhdGVkSW1tdXRhYmxlU3RyaW5nRmllbGRMaXRlR2VuZXJhdG9yKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBX1NUUklOR19GSUVMRF9MSVRFX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19lbnVtLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19lbnVtLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM2ZThkZmUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2VudW0uY2MKQEAgLTAsMCArMSwxNDMgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvcHJvdG9idWYvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHN0cmluZz4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19wYXJhbXMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZW51bS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YW5hbm8geworCitFbnVtR2VuZXJhdG9yOjpFbnVtR2VuZXJhdG9yKGNvbnN0IEVudW1EZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBjb25zdCBQYXJhbXMmIHBhcmFtcykKKyAgOiBwYXJhbXNfKHBhcmFtcyksIGRlc2NyaXB0b3JfKGRlc2NyaXB0b3IpIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+dmFsdWVfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogdmFsdWUgPSBkZXNjcmlwdG9yXy0+dmFsdWUoaSk7CisgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogY2Fub25pY2FsX3ZhbHVlID0KKyAgICAgIGRlc2NyaXB0b3JfLT5GaW5kVmFsdWVCeU51bWJlcih2YWx1ZS0+bnVtYmVyKCkpOworCisgICAgaWYgKHZhbHVlID09IGNhbm9uaWNhbF92YWx1ZSkgeworICAgICAgY2Fub25pY2FsX3ZhbHVlc18ucHVzaF9iYWNrKHZhbHVlKTsKKyAgICB9IGVsc2UgeworICAgICAgQWxpYXMgYWxpYXM7CisgICAgICBhbGlhcy52YWx1ZSA9IHZhbHVlOworICAgICAgYWxpYXMuY2Fub25pY2FsX3ZhbHVlID0gY2Fub25pY2FsX3ZhbHVlOworICAgICAgYWxpYXNlc18ucHVzaF9iYWNrKGFsaWFzKTsKKyAgICB9CisgIH0KK30KKworRW51bUdlbmVyYXRvcjo6fkVudW1HZW5lcmF0b3IoKSB7fQorCit2b2lkIEVudW1HZW5lcmF0b3I6OkdlbmVyYXRlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgICAgIlxuIgorICAgICAgIi8vIGVudW0gJGNsYXNzbmFtZSRcbiIsCisgICAgICAiY2xhc3NuYW1lIiwgZGVzY3JpcHRvcl8tPm5hbWUoKSk7CisKKyAgY29uc3Qgc3RyaW5nIGNsYXNzbmFtZSA9IFJlbmFtZUphdmFLZXl3b3JkcyhkZXNjcmlwdG9yXy0+bmFtZSgpKTsKKworICAvLyBTdGFydCBvZiBjb250YWluZXIgaW50ZXJmYWNlCisgIC8vIElmIGdlbmVyYXRpbmcgaW50ZGVmcywgd2UgdXNlIHRoZSBjb250YWluZXIgaW50ZXJmYWNlIGFzIHRoZSBpbnRkZWYgaWYKKyAgLy8gcHJlc2VudC4gT3RoZXJ3aXNlLCB3ZSBqdXN0IG1ha2UgYW4gZW1wdHkgQGludGVyZmFjZSBwYXJhbGxlbCB0byB0aGUKKyAgLy8gY29uc3RhbnRzLgorICBib29sIHVzZV9pbnRkZWYgPSBwYXJhbXNfLmdlbmVyYXRlX2ludGRlZnMoKTsKKyAgYm9vbCB1c2Vfc2hlbGxfY2xhc3MgPSBwYXJhbXNfLmphdmFfZW51bV9zdHlsZSgpOworICBpZiAodXNlX2ludGRlZikgeworICAgIC8vIEBJbnREZWYgYW5ub3RhdGlvbiBzbyB0b29scyBjYW4gZW5mb3JjZSBjb3JyZWN0bmVzcworICAgIC8vIEFubm90YXRpb25zIHdpbGwgYmUgZGlzY2FyZGVkIGJ5IHRoZSBjb21waWxlcgorICAgIHByaW50ZXItPlByaW50KCJAamF2YS5sYW5nLmFubm90YXRpb24uUmV0ZW50aW9uKCIKKyAgICAgICJqYXZhLmxhbmcuYW5ub3RhdGlvbi5SZXRlbnRpb25Qb2xpY3kuU09VUkNFKVxuIgorICAgICAgIkBhbmRyb2lkLnN1cHBvcnQuYW5ub3RhdGlvbi5JbnREZWYoe1xuIik7CisgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjYW5vbmljYWxfdmFsdWVzXy5zaXplKCk7IGkrKykgeworICAgICAgY29uc3Qgc3RyaW5nIGNvbnN0YW50X25hbWUgPQorICAgICAgICAgIFJlbmFtZUphdmFLZXl3b3JkcyhjYW5vbmljYWxfdmFsdWVzX1tpXS0+bmFtZSgpKTsKKyAgICAgIGlmICh1c2Vfc2hlbGxfY2xhc3MpIHsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoIiRjbGFzc25hbWUkLiRuYW1lJCxcbiIsCisgICAgICAgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZSwKKyAgICAgICAgICAibmFtZSIsIGNvbnN0YW50X25hbWUpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoIiRuYW1lJCxcbiIsICJuYW1lIiwgY29uc3RhbnRfbmFtZSk7CisgICAgICB9CisgICAgfQorICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICBwcmludGVyLT5QcmludCgifSlcbiIpOworICB9CisgIGlmICh1c2Vfc2hlbGxfY2xhc3MgfHwgdXNlX2ludGRlZikgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgInB1YmxpYyAkYXRfZm9yX2ludGRlZiRpbnRlcmZhY2UgJGNsYXNzbmFtZSQge1xuIiwKKyAgICAgICJjbGFzc25hbWUiLCBjbGFzc25hbWUsCisgICAgICAiYXRfZm9yX2ludGRlZiIsIHVzZV9pbnRkZWYgPyAiQCIgOiAiIik7CisgICAgaWYgKHVzZV9zaGVsbF9jbGFzcykgeworICAgICAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICB9IGVsc2UgeworICAgICAgICBwcmludGVyLT5QcmludCgifVxuXG4iKTsKKyAgICB9CisgIH0KKworICAvLyBDYW5vbmljYWwgdmFsdWVzCisgIGZvciAoaW50IGkgPSAwOyBpIDwgY2Fub25pY2FsX3ZhbHVlc18uc2l6ZSgpOyBpKyspIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJwdWJsaWMgc3RhdGljIGZpbmFsIGludCAkbmFtZSQgPSAkY2Fub25pY2FsX3ZhbHVlJDtcbiIsCisgICAgICAibmFtZSIsIFJlbmFtZUphdmFLZXl3b3JkcyhjYW5vbmljYWxfdmFsdWVzX1tpXS0+bmFtZSgpKSwKKyAgICAgICJjYW5vbmljYWxfdmFsdWUiLCBTaW1wbGVJdG9hKGNhbm9uaWNhbF92YWx1ZXNfW2ldLT5udW1iZXIoKSkpOworICB9CisKKyAgLy8gQWxpYXNlcworICBmb3IgKGludCBpID0gMDsgaSA8IGFsaWFzZXNfLnNpemUoKTsgaSsrKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAicHVibGljIHN0YXRpYyBmaW5hbCBpbnQgJG5hbWUkID0gJGNhbm9uaWNhbF9uYW1lJDtcbiIsCisgICAgICAibmFtZSIsIFJlbmFtZUphdmFLZXl3b3JkcyhhbGlhc2VzX1tpXS52YWx1ZS0+bmFtZSgpKSwKKyAgICAgICJjYW5vbmljYWxfbmFtZSIsIFJlbmFtZUphdmFLZXl3b3JkcyhhbGlhc2VzX1tpXS5jYW5vbmljYWxfdmFsdWUtPm5hbWUoKSkpOworICB9CisKKyAgLy8gRW5kIG9mIGNvbnRhaW5lciBpbnRlcmZhY2UKKyAgaWYgKHVzZV9zaGVsbF9jbGFzcykgeworICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICBwcmludGVyLT5QcmludCgifVxuIik7CisgIH0KK30KKworfSAgLy8gbmFtZXNwYWNlIGphdmFuYW5vCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19lbnVtLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2VudW0uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMGRkMzY0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19lbnVtLmgKQEAgLTAsMCArMSw4NyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9wcm90b2J1Zi8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFOQU5PX0VOVU1fSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBTkFOT19FTlVNX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPHZlY3Rvcj4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19wYXJhbXMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisgIG5hbWVzcGFjZSBpbyB7CisgICAgY2xhc3MgUHJpbnRlcjsgICAgICAgICAgICAgLy8gcHJpbnRlci5oCisgIH0KK30KKworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YW5hbm8geworCitjbGFzcyBFbnVtR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IEVudW1HZW5lcmF0b3IoY29uc3QgRW51bURlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGNvbnN0IFBhcmFtcyYgcGFyYW1zKTsKKyAgfkVudW1HZW5lcmF0b3IoKTsKKworICB2b2lkIEdlbmVyYXRlKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworIHByaXZhdGU6CisgIGNvbnN0IFBhcmFtcyYgcGFyYW1zXzsKKyAgY29uc3QgRW51bURlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworCisgIC8vIFRoZSBwcm90byBsYW5ndWFnZSBhbGxvd3MgbXVsdGlwbGUgZW51bSBjb25zdGFudHMgdG8gaGF2ZSB0aGUgc2FtZSBudW1lcmljCisgIC8vIHZhbHVlLiAgSmF2YSwgaG93ZXZlciwgZG9lcyBub3QgYWxsb3cgbXVsdGlwbGUgZW51bSBjb25zdGFudHMgdG8gYmUKKyAgLy8gY29uc2lkZXJlZCBlcXVpdmFsZW50LiAgV2UgdHJlYXQgdGhlIGZpcnN0IGRlZmluZWQgY29uc3RhbnQgZm9yIGFueQorICAvLyBnaXZlbiBudW1lcmljIHZhbHVlIGFzICJjYW5vbmljYWwiIGFuZCB0aGUgcmVzdCBhcyBhbGlhc2VzIG9mIHRoYXQKKyAgLy8gY2Fub25pY2FsIHZhbHVlLgorICB2ZWN0b3I8Y29uc3QgRW51bVZhbHVlRGVzY3JpcHRvcio+IGNhbm9uaWNhbF92YWx1ZXNfOworCisgIHN0cnVjdCBBbGlhcyB7CisgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogdmFsdWU7CisgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogY2Fub25pY2FsX3ZhbHVlOworICB9OworICB2ZWN0b3I8QWxpYXM+IGFsaWFzZXNfOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhFbnVtR2VuZXJhdG9yKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhbmFubworfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQU5BTk9fRU5VTV9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZW51bV9maWVsZC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZW51bV9maWVsZC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NjY2ZGIzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19lbnVtX2ZpZWxkLmNjCkBAIC0wLDAgKzEsNTQ0IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL3Byb3RvYnVmLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2luY2x1ZGUgPG1hcD4KKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZW51bV9maWVsZC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9faGVscGVycy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhbmFubyB7CisKK25hbWVzcGFjZSB7CisKKy8vIFRPRE8oa2VudG9uKTogIEZhY3RvciBvdXQgYSAiU2V0Q29tbW9uRmllbGRWYXJpYWJsZXMoKSIgdG8gZ2V0IHJpZCBvZgorLy8gICByZXBlYXQgY29kZSBiZXR3ZWVuIHRoaXMgYW5kIHRoZSBvdGhlciBmaWVsZCB0eXBlcy4KK3ZvaWQgU2V0RW51bVZhcmlhYmxlcyhjb25zdCBQYXJhbXMmIHBhcmFtcywKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIG1hcDxzdHJpbmcsIHN0cmluZz4qIHZhcmlhYmxlcykgeworICAoKnZhcmlhYmxlcylbIm5hbWUiXSA9CisgICAgUmVuYW1lSmF2YUtleXdvcmRzKFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoZGVzY3JpcHRvcikpOworICAoKnZhcmlhYmxlcylbImNhcGl0YWxpemVkX25hbWUiXSA9CisgICAgUmVuYW1lSmF2YUtleXdvcmRzKFVuZGVyc2NvcmVzVG9DYXBpdGFsaXplZENhbWVsQ2FzZShkZXNjcmlwdG9yKSk7CisgICgqdmFyaWFibGVzKVsibnVtYmVyIl0gPSBTaW1wbGVJdG9hKGRlc2NyaXB0b3ItPm51bWJlcigpKTsKKyAgaWYgKHBhcmFtcy51c2VfcmVmZXJlbmNlX3R5cGVzX2Zvcl9wcmltaXRpdmVzKCkKKyAgICAgICYmICFwYXJhbXMucmVmdHlwZXNfcHJpbWl0aXZlX2VudW1zKCkKKyAgICAgICYmICFkZXNjcmlwdG9yLT5pc19yZXBlYXRlZCgpKSB7CisgICAgKCp2YXJpYWJsZXMpWyJ0eXBlIl0gPSAiamF2YS5sYW5nLkludGVnZXIiOworICAgICgqdmFyaWFibGVzKVsiZGVmYXVsdCJdID0gIm51bGwiOworICB9IGVsc2UgeworICAgICgqdmFyaWFibGVzKVsidHlwZSJdID0gImludCI7CisgICAgKCp2YXJpYWJsZXMpWyJkZWZhdWx0Il0gPSBEZWZhdWx0VmFsdWUocGFyYW1zLCBkZXNjcmlwdG9yKTsKKyAgfQorICAoKnZhcmlhYmxlcylbInJlcGVhdGVkX2RlZmF1bHQiXSA9CisgICAgICAiY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLldpcmVGb3JtYXROYW5vLkVNUFRZX0lOVF9BUlJBWSI7CisgICgqdmFyaWFibGVzKVsidGFnIl0gPSBTaW1wbGVJdG9hKGludGVybmFsOjpXaXJlRm9ybWF0OjpNYWtlVGFnKGRlc2NyaXB0b3IpKTsKKyAgKCp2YXJpYWJsZXMpWyJ0YWdfc2l6ZSJdID0gU2ltcGxlSXRvYSgKKyAgICAgIGludGVybmFsOjpXaXJlRm9ybWF0OjpUYWdTaXplKGRlc2NyaXB0b3ItPm51bWJlcigpLCBkZXNjcmlwdG9yLT50eXBlKCkpKTsKKyAgKCp2YXJpYWJsZXMpWyJub25fcGFja2VkX3RhZyJdID0gU2ltcGxlSXRvYSgKKyAgICAgIGludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6TWFrZVRhZyhkZXNjcmlwdG9yLT5udW1iZXIoKSwKKyAgICAgICAgICBpbnRlcm5hbDo6V2lyZUZvcm1hdDo6V2lyZVR5cGVGb3JGaWVsZFR5cGUoZGVzY3JpcHRvci0+dHlwZSgpKSkpOworICAoKnZhcmlhYmxlcylbIm1lc3NhZ2VfbmFtZSJdID0gZGVzY3JpcHRvci0+Y29udGFpbmluZ190eXBlKCktPm5hbWUoKTsKKyAgY29uc3QgRW51bURlc2NyaXB0b3IqIGVudW1fdHlwZSA9IGRlc2NyaXB0b3ItPmVudW1fdHlwZSgpOworICAoKnZhcmlhYmxlcylbIm1lc3NhZ2VfdHlwZV9pbnRkZWYiXSA9ICJAIgorICAgICAgKyBUb0phdmFOYW1lKHBhcmFtcywgZW51bV90eXBlLT5uYW1lKCksIHRydWUsCisgICAgICAgICAgZW51bV90eXBlLT5jb250YWluaW5nX3R5cGUoKSwgZW51bV90eXBlLT5maWxlKCkpOworfQorCit2b2lkIExvYWRFbnVtVmFsdWVzKGNvbnN0IFBhcmFtcyYgcGFyYW1zLAorICAgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBlbnVtX2Rlc2NyaXB0b3IsIHZlY3RvcjxzdHJpbmc+KiBjYW5vbmljYWxfdmFsdWVzKSB7CisgIHN0cmluZyBlbnVtX2NsYXNzX25hbWUgPSBDbGFzc05hbWUocGFyYW1zLCBlbnVtX2Rlc2NyaXB0b3IpOworICBmb3IgKGludCBpID0gMDsgaSA8IGVudW1fZGVzY3JpcHRvci0+dmFsdWVfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogdmFsdWUgPSBlbnVtX2Rlc2NyaXB0b3ItPnZhbHVlKGkpOworICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIGNhbm9uaWNhbF92YWx1ZSA9CisgICAgICAgIGVudW1fZGVzY3JpcHRvci0+RmluZFZhbHVlQnlOdW1iZXIodmFsdWUtPm51bWJlcigpKTsKKyAgICBpZiAodmFsdWUgPT0gY2Fub25pY2FsX3ZhbHVlKSB7CisgICAgICBjYW5vbmljYWxfdmFsdWVzLT5wdXNoX2JhY2soCisgICAgICAgICAgZW51bV9jbGFzc19uYW1lICsgIi4iICsgUmVuYW1lSmF2YUtleXdvcmRzKHZhbHVlLT5uYW1lKCkpKTsKKyAgICB9CisgIH0KK30KKwordm9pZCBQcmludENhc2VMYWJlbHMoCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIsIGNvbnN0IHZlY3RvcjxzdHJpbmc+JiBjYW5vbmljYWxfdmFsdWVzKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgY2Fub25pY2FsX3ZhbHVlcy5zaXplKCk7IGkrKykgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIiAgY2FzZSAkdmFsdWUkOlxuIiwKKyAgICAgICJ2YWx1ZSIsIGNhbm9uaWNhbF92YWx1ZXNbaV0pOworICB9Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK0VudW1GaWVsZEdlbmVyYXRvcjo6CitFbnVtRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBjb25zdCBQYXJhbXMmIHBhcmFtcykKKyAgOiBGaWVsZEdlbmVyYXRvcihwYXJhbXMpLCBkZXNjcmlwdG9yXyhkZXNjcmlwdG9yKSB7CisgIFNldEVudW1WYXJpYWJsZXMocGFyYW1zLCBkZXNjcmlwdG9yLCAmdmFyaWFibGVzXyk7CisgIExvYWRFbnVtVmFsdWVzKHBhcmFtcywgZGVzY3JpcHRvci0+ZW51bV90eXBlKCksICZjYW5vbmljYWxfdmFsdWVzXyk7Cit9CisKK0VudW1GaWVsZEdlbmVyYXRvcjo6fkVudW1GaWVsZEdlbmVyYXRvcigpIHt9CisKK3ZvaWQgRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlciwgYm9vbCAvKiB1bnVzZWQgbGF6eV9pbml0ICovKSBjb25zdCB7CisgIGlmIChwYXJhbXNfLmdlbmVyYXRlX2ludGRlZnMoKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sICIkbWVzc2FnZV90eXBlX2ludGRlZiRcbiIpOworICB9CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sICJwdWJsaWMgJHR5cGUkICRuYW1lJDtcbiIpOworCisgIGlmIChwYXJhbXNfLmdlbmVyYXRlX2hhcygpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJwdWJsaWMgYm9vbGVhbiBoYXMkY2FwaXRhbGl6ZWRfbmFtZSQ7XG4iKTsKKyAgfQorfQorCit2b2lkIEVudW1GaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUNsZWFyQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkbmFtZSQgPSAkZGVmYXVsdCQ7XG4iKTsKKworICBpZiAocGFyYW1zXy5nZW5lcmF0ZV9oYXMoKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaGFzJGNhcGl0YWxpemVkX25hbWUkID0gZmFsc2U7XG4iKTsKKyAgfQorfQorCit2b2lkIEVudW1GaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImludCB2YWx1ZSA9IGlucHV0LnJlYWRJbnQzMigpO1xuIgorICAgICJzd2l0Y2ggKHZhbHVlKSB7XG4iKTsKKyAgUHJpbnRDYXNlTGFiZWxzKHByaW50ZXIsIGNhbm9uaWNhbF92YWx1ZXNfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiICAgIHRoaXMuJG5hbWUkID0gdmFsdWU7XG4iKTsKKyAgaWYgKHBhcmFtc18uZ2VuZXJhdGVfaGFzKCkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiAgICBoYXMkY2FwaXRhbGl6ZWRfbmFtZSQgPSB0cnVlO1xuIik7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIiAgICBicmVhaztcbiIKKyAgICAifVxuIik7CisgIC8vIE5vIGRlZmF1bHQgY2FzZTogaW4gY2FzZSBvZiBpbnZhbGlkIHZhbHVlIGZyb20gdGhlIHdpcmUsIHByZXNlcnZlIG9sZAorICAvLyBmaWVsZCB2YWx1ZS4gQWxzbyB3ZSBhcmUgbm90IHN0b3JpbmcgdGhlIGludmFsaWQgdmFsdWUgaW50byB0aGUgdW5rbm93bgorICAvLyBmaWVsZHMsIGJlY2F1c2UgdGhlcmUgaXMgbm8gd2F5IHRvIGdldCB0aGUgdmFsdWUgb3V0LgorfQorCit2b2lkIEVudW1GaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChkZXNjcmlwdG9yXy0+aXNfcmVxdWlyZWQoKSAmJiAhcGFyYW1zXy5nZW5lcmF0ZV9oYXMoKSkgeworICAgIC8vIEFsd2F5cyBzZXJpYWxpemUgYSByZXF1aXJlZCBmaWVsZCBpZiB3ZSBkb24ndCBoYXZlIHRoZSAnaGFzJyBzaWduYWwuCisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJvdXRwdXQud3JpdGVJbnQzMigkbnVtYmVyJCwgdGhpcy4kbmFtZSQpO1xuIik7CisgIH0gZWxzZSB7CisgICAgaWYgKHBhcmFtc18uZ2VuZXJhdGVfaGFzKCkpIHsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICJpZiAodGhpcy4kbmFtZSQgIT0gJGRlZmF1bHQkIHx8IGhhcyRjYXBpdGFsaXplZF9uYW1lJCkge1xuIik7CisgICAgfSBlbHNlIHsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICJpZiAodGhpcy4kbmFtZSQgIT0gJGRlZmF1bHQkKSB7XG4iKTsKKyAgICB9CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIgIG91dHB1dC53cml0ZUludDMyKCRudW1iZXIkLCB0aGlzLiRuYW1lJCk7XG4iCisgICAgICAifVxuIik7CisgIH0KK30KKwordm9pZCBFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKGRlc2NyaXB0b3JfLT5pc19yZXF1aXJlZCgpICYmICFwYXJhbXNfLmdlbmVyYXRlX2hhcygpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYubmFuby5Db2RlZE91dHB1dEJ5dGVCdWZmZXJOYW5vXG4iCisgICAgICAiICAuY29tcHV0ZUludDMyU2l6ZSgkbnVtYmVyJCwgdGhpcy4kbmFtZSQpO1xuIik7CisgIH0gZWxzZSB7CisgICAgaWYgKHBhcmFtc18uZ2VuZXJhdGVfaGFzKCkpIHsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICJpZiAodGhpcy4kbmFtZSQgIT0gJGRlZmF1bHQkIHx8IGhhcyRjYXBpdGFsaXplZF9uYW1lJCkge1xuIik7CisgICAgfSBlbHNlIHsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICJpZiAodGhpcy4kbmFtZSQgIT0gJGRlZmF1bHQkKSB7XG4iKTsKKyAgICB9CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLkNvZGVkT3V0cHV0Qnl0ZUJ1ZmZlck5hbm9cbiIKKyAgICAgICIgICAgLmNvbXB1dGVJbnQzMlNpemUoJG51bWJlciQsIHRoaXMuJG5hbWUkKTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorfQorCit2b2lkIEVudW1GaWVsZEdlbmVyYXRvcjo6R2VuZXJhdGVFcXVhbHNDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChwYXJhbXNfLnVzZV9yZWZlcmVuY2VfdHlwZXNfZm9yX3ByaW1pdGl2ZXMoKQorICAgICAgICAmJiAhcGFyYW1zXy5yZWZ0eXBlc19wcmltaXRpdmVfZW51bXMoKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaWYgKHRoaXMuJG5hbWUkID09IG51bGwpIHtcbiIKKyAgICAgICIgIGlmIChvdGhlci4kbmFtZSQgIT0gbnVsbCkge1xuIgorICAgICAgIiAgICByZXR1cm4gZmFsc2U7XG4iCisgICAgICAiICB9XG4iCisgICAgICAifSBlbHNlIGlmICghdGhpcy4kbmFtZSQuZXF1YWxzKG90aGVyLiRuYW1lJCkpIHtcbiIKKyAgICAgICIgIHJldHVybiBmYWxzZTsiCisgICAgICAifVxuIik7CisgIH0gZWxzZSB7CisgICAgLy8gV2UgZGVmaW5lIGVxdWFsaXR5IGFzIHNlcmlhbGl6ZWQgZm9ybSBlcXVhbGl0eS4gSWYgZ2VuZXJhdGVfaGFzKCksCisgICAgLy8gdGhlbiBpZiB0aGUgZmllbGQgdmFsdWUgZXF1YWxzIHRoZSBkZWZhdWx0IHZhbHVlIGluIGJvdGggbWVzc2FnZXMsCisgICAgLy8gYnV0IG9uZSdzICdoYXMnIGZpZWxkIGlzIHNldCBhbmQgdGhlIG90aGVyJ3MgaXMgbm90LCB0aGUgc2VyaWFsaXplZAorICAgIC8vIGZvcm1zIGFyZSBkaWZmZXJlbnQgYW5kIHdlIHNob3VsZCByZXR1cm4gZmFsc2UuCisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJpZiAodGhpcy4kbmFtZSQgIT0gb3RoZXIuJG5hbWUkIik7CisgICAgaWYgKHBhcmFtc18uZ2VuZXJhdGVfaGFzKCkpIHsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICJcbiIKKyAgICAgICAgIiAgICB8fCAodGhpcy4kbmFtZSQgPT0gJGRlZmF1bHQkXG4iCisgICAgICAgICIgICAgICAgICYmIHRoaXMuaGFzJGNhcGl0YWxpemVkX25hbWUkICE9IG90aGVyLmhhcyRjYXBpdGFsaXplZF9uYW1lJCkiKTsKKyAgICB9CisgICAgcHJpbnRlci0+UHJpbnQoIikge1xuIgorICAgICAgIiAgcmV0dXJuIGZhbHNlO1xuIgorICAgICAgIn1cbiIpOworICB9Cit9CisKK3ZvaWQgRW51bUZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZUhhc2hDb2RlQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCgKKyAgICAicmVzdWx0ID0gMzEgKiByZXN1bHQgKyAiKTsKKyAgaWYgKHBhcmFtc18udXNlX3JlZmVyZW5jZV90eXBlc19mb3JfcHJpbWl0aXZlcygpCisgICAgICAgICYmICFwYXJhbXNfLnJlZnR5cGVzX3ByaW1pdGl2ZV9lbnVtcygpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIodGhpcy4kbmFtZSQgPT0gbnVsbCA/IDAgOiB0aGlzLiRuYW1lJCkiKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgInRoaXMuJG5hbWUkIik7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQoIjtcbiIpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK0FjY2Vzc29yRW51bUZpZWxkR2VuZXJhdG9yOjoKK0FjY2Vzc29yRW51bUZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICBjb25zdCBQYXJhbXMmIHBhcmFtcywgaW50IGhhc19iaXRfaW5kZXgpCisgIDogRmllbGRHZW5lcmF0b3IocGFyYW1zKSwgZGVzY3JpcHRvcl8oZGVzY3JpcHRvcikgeworICBTZXRFbnVtVmFyaWFibGVzKHBhcmFtcywgZGVzY3JpcHRvciwgJnZhcmlhYmxlc18pOworICBMb2FkRW51bVZhbHVlcyhwYXJhbXMsIGRlc2NyaXB0b3ItPmVudW1fdHlwZSgpLCAmY2Fub25pY2FsX3ZhbHVlc18pOworICBTZXRCaXRPcGVyYXRpb25WYXJpYWJsZXMoImhhcyIsIGhhc19iaXRfaW5kZXgsICZ2YXJpYWJsZXNfKTsKK30KKworQWNjZXNzb3JFbnVtRmllbGRHZW5lcmF0b3I6On5BY2Nlc3NvckVudW1GaWVsZEdlbmVyYXRvcigpIHt9CisKK3ZvaWQgQWNjZXNzb3JFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyLCBib29sIC8qIHVudXNlZCBsYXp5X2luaXQgKi8pIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgInByaXZhdGUgaW50ICRuYW1lJF87XG4iKTsKKyAgaWYgKHBhcmFtc18uZ2VuZXJhdGVfaW50ZGVmcygpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgIiRtZXNzYWdlX3R5cGVfaW50ZGVmJFxuIik7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHVibGljIGludCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgcmV0dXJuICRuYW1lJF87XG4iCisgICAgIn1cbiIKKyAgICAicHVibGljICRtZXNzYWdlX25hbWUkIHNldCRjYXBpdGFsaXplZF9uYW1lJCgiKTsKKyAgaWYgKHBhcmFtc18uZ2VuZXJhdGVfaW50ZGVmcygpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJcbiIKKyAgICAgICIgICAgJG1lc3NhZ2VfdHlwZV9pbnRkZWYkICIpOworICB9CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImludCB2YWx1ZSkge1xuIgorICAgICIgICRuYW1lJF8gPSB2YWx1ZTtcbiIKKyAgICAiICAkc2V0X2hhcyQ7XG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIKKyAgICAicHVibGljIGJvb2xlYW4gaGFzJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgIHJldHVybiAkZ2V0X2hhcyQ7XG4iCisgICAgIn1cbiIKKyAgICAicHVibGljICRtZXNzYWdlX25hbWUkIGNsZWFyJGNhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICIgICRuYW1lJF8gPSAkZGVmYXVsdCQ7XG4iCisgICAgIiAgJGNsZWFyX2hhcyQ7XG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEFjY2Vzc29yRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQ2xlYXJDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRuYW1lJF8gPSAkZGVmYXVsdCQ7XG4iKTsKK30KKwordm9pZCBBY2Nlc3NvckVudW1GaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImludCB2YWx1ZSA9IGlucHV0LnJlYWRJbnQzMigpO1xuIgorICAgICJzd2l0Y2ggKHZhbHVlKSB7XG4iKTsKKyAgUHJpbnRDYXNlTGFiZWxzKHByaW50ZXIsIGNhbm9uaWNhbF92YWx1ZXNfKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiICAgICRuYW1lJF8gPSB2YWx1ZTtcbiIKKyAgICAiICAgICRzZXRfaGFzJDtcbiIKKyAgICAiICAgIGJyZWFrO1xuIgorICAgICJ9XG4iKTsKKyAgLy8gTm8gZGVmYXVsdCBjYXNlOiBpbiBjYXNlIG9mIGludmFsaWQgdmFsdWUgZnJvbSB0aGUgd2lyZSwgcHJlc2VydmUgb2xkCisgIC8vIGZpZWxkIHZhbHVlLiBBbHNvIHdlIGFyZSBub3Qgc3RvcmluZyB0aGUgaW52YWxpZCB2YWx1ZSBpbnRvIHRoZSB1bmtub3duCisgIC8vIGZpZWxkcywgYmVjYXVzZSB0aGVyZSBpcyBubyB3YXkgdG8gZ2V0IHRoZSB2YWx1ZSBvdXQuCit9CisKK3ZvaWQgQWNjZXNzb3JFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoJGdldF9oYXMkKSB7XG4iCisgICAgIiAgb3V0cHV0LndyaXRlSW50MzIoJG51bWJlciQsICRuYW1lJF8pO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBBY2Nlc3NvckVudW1GaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoJGdldF9oYXMkKSB7XG4iCisgICAgIiAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFub1xuIgorICAgICIgICAgLmNvbXB1dGVJbnQzMlNpemUoJG51bWJlciQsICRuYW1lJF8pO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBBY2Nlc3NvckVudW1GaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUVxdWFsc0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCRkaWZmZXJlbnRfaGFzJFxuIgorICAgICIgICAgfHwgJG5hbWUkXyAhPSBvdGhlci4kbmFtZSRfKSB7XG4iCisgICAgIiAgcmV0dXJuIGZhbHNlO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBBY2Nlc3NvckVudW1GaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUhhc2hDb2RlQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJyZXN1bHQgPSAzMSAqIHJlc3VsdCArICRuYW1lJF87XG4iKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitSZXBlYXRlZEVudW1GaWVsZEdlbmVyYXRvcjo6CitSZXBlYXRlZEVudW1GaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGNvbnN0IFBhcmFtcyYgcGFyYW1zKQorICA6IEZpZWxkR2VuZXJhdG9yKHBhcmFtcyksIGRlc2NyaXB0b3JfKGRlc2NyaXB0b3IpIHsKKyAgU2V0RW51bVZhcmlhYmxlcyhwYXJhbXMsIGRlc2NyaXB0b3IsICZ2YXJpYWJsZXNfKTsKKyAgTG9hZEVudW1WYWx1ZXMocGFyYW1zLCBkZXNjcmlwdG9yLT5lbnVtX3R5cGUoKSwgJmNhbm9uaWNhbF92YWx1ZXNfKTsKK30KKworUmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3I6On5SZXBlYXRlZEVudW1GaWVsZEdlbmVyYXRvcigpIHt9CisKK3ZvaWQgUmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyLCBib29sIC8qIHVudXNlZCBsYXp5X2luaXQgKi8pIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHVibGljICR0eXBlJFtdICRuYW1lJDtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQ2xlYXJDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRuYW1lJCA9ICRyZXBlYXRlZF9kZWZhdWx0JDtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gRmlyc3QsIGZpZ3VyZSBvdXQgdGhlIG1heGltdW0gbGVuZ3RoIG9mIHRoZSBhcnJheSwgdGhlbiBwYXJzZSwKKyAgLy8gYW5kIGZpbmFsbHkgY29weSB0aGUgdmFsaWQgdmFsdWVzIHRvIHRoZSBmaWVsZC4KKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaW50IGxlbmd0aCA9IGNvbS5nb29nbGUucHJvdG9idWYubmFuby5XaXJlRm9ybWF0TmFub1xuIgorICAgICIgICAgLmdldFJlcGVhdGVkRmllbGRBcnJheUxlbmd0aChpbnB1dCwgJG5vbl9wYWNrZWRfdGFnJCk7XG4iCisgICAgImludFtdIHZhbGlkVmFsdWVzID0gbmV3IGludFtsZW5ndGhdO1xuIgorICAgICJpbnQgdmFsaWRDb3VudCA9IDA7XG4iCisgICAgImZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiIKKyAgICAiICBpZiAoaSAhPSAwKSB7IC8vIHRhZyBmb3IgZmlyc3QgdmFsdWUgYWxyZWFkeSBjb25zdW1lZC5cbiIKKyAgICAiICAgIGlucHV0LnJlYWRUYWcoKTtcbiIKKyAgICAiICB9XG4iCisgICAgIiAgaW50IHZhbHVlID0gaW5wdXQucmVhZEludDMyKCk7XG4iCisgICAgIiAgc3dpdGNoICh2YWx1ZSkge1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworICBQcmludENhc2VMYWJlbHMocHJpbnRlciwgY2Fub25pY2FsX3ZhbHVlc18pOworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiAgICAgIHZhbGlkVmFsdWVzW3ZhbGlkQ291bnQrK10gPSB2YWx1ZTtcbiIKKyAgICAiICAgICAgYnJlYWs7XG4iCisgICAgIiAgfVxuIgorICAgICJ9XG4iCisgICAgImlmICh2YWxpZENvdW50ICE9IDApIHtcbiIKKyAgICAiICBpbnQgaSA9IHRoaXMuJG5hbWUkID09IG51bGwgPyAwIDogdGhpcy4kbmFtZSQubGVuZ3RoO1xuIgorICAgICIgIGlmIChpID09IDAgJiYgdmFsaWRDb3VudCA9PSB2YWxpZFZhbHVlcy5sZW5ndGgpIHtcbiIKKyAgICAiICAgIHRoaXMuJG5hbWUkID0gdmFsaWRWYWx1ZXM7XG4iCisgICAgIiAgfSBlbHNlIHtcbiIKKyAgICAiICAgIGludFtdIG5ld0FycmF5ID0gbmV3IGludFtpICsgdmFsaWRDb3VudF07XG4iCisgICAgIiAgICBpZiAoaSAhPSAwKSB7XG4iCisgICAgIiAgICAgIGphdmEubGFuZy5TeXN0ZW0uYXJyYXljb3B5KHRoaXMuJG5hbWUkLCAwLCBuZXdBcnJheSwgMCwgaSk7XG4iCisgICAgIiAgICB9XG4iCisgICAgIiAgICBqYXZhLmxhbmcuU3lzdGVtLmFycmF5Y29weSh2YWxpZFZhbHVlcywgMCwgbmV3QXJyYXksIGksIHZhbGlkQ291bnQpO1xuIgorICAgICIgICAgdGhpcy4kbmFtZSQgPSBuZXdBcnJheTtcbiIKKyAgICAiICB9XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIFJlcGVhdGVkRW51bUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2luZ0NvZGVGcm9tUGFja2VkKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImludCBieXRlcyA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpO1xuIgorICAgICJpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQoYnl0ZXMpO1xuIgorICAgICIvLyBGaXJzdCBwYXNzIHRvIGNvbXB1dGUgYXJyYXkgbGVuZ3RoLlxuIgorICAgICJpbnQgYXJyYXlMZW5ndGggPSAwO1xuIgorICAgICJpbnQgc3RhcnRQb3MgPSBpbnB1dC5nZXRQb3NpdGlvbigpO1xuIgorICAgICJ3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7XG4iCisgICAgIiAgc3dpdGNoIChpbnB1dC5yZWFkSW50MzIoKSkge1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworICBQcmludENhc2VMYWJlbHMocHJpbnRlciwgY2Fub25pY2FsX3ZhbHVlc18pOworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiAgICAgIGFycmF5TGVuZ3RoKys7XG4iCisgICAgIiAgICAgIGJyZWFrO1xuIgorICAgICIgIH1cbiIKKyAgICAifVxuIgorICAgICJpZiAoYXJyYXlMZW5ndGggIT0gMCkge1xuIgorICAgICIgIGlucHV0LnJld2luZFRvUG9zaXRpb24oc3RhcnRQb3MpO1xuIgorICAgICIgIGludCBpID0gdGhpcy4kbmFtZSQgPT0gbnVsbCA/IDAgOiB0aGlzLiRuYW1lJC5sZW5ndGg7XG4iCisgICAgIiAgaW50W10gbmV3QXJyYXkgPSBuZXcgaW50W2kgKyBhcnJheUxlbmd0aF07XG4iCisgICAgIiAgaWYgKGkgIT0gMCkge1xuIgorICAgICIgICAgamF2YS5sYW5nLlN5c3RlbS5hcnJheWNvcHkodGhpcy4kbmFtZSQsIDAsIG5ld0FycmF5LCAwLCBpKTtcbiIKKyAgICAiICB9XG4iCisgICAgIiAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkge1xuIgorICAgICIgICAgaW50IHZhbHVlID0gaW5wdXQucmVhZEludDMyKCk7XG4iCisgICAgIiAgICBzd2l0Y2ggKHZhbHVlKSB7XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisgIHByaW50ZXItPkluZGVudCgpOworICBQcmludENhc2VMYWJlbHMocHJpbnRlciwgY2Fub25pY2FsX3ZhbHVlc18pOworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiICAgICAgICBuZXdBcnJheVtpKytdID0gdmFsdWU7XG4iCisgICAgIiAgICAgICAgYnJlYWs7XG4iCisgICAgIiAgICB9XG4iCisgICAgIiAgfVxuIgorICAgICIgIHRoaXMuJG5hbWUkID0gbmV3QXJyYXk7XG4iCisgICAgIn1cbiIKKyAgICAiaW5wdXQucG9wTGltaXQobGltaXQpO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVSZXBlYXRlZERhdGFTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBDcmVhdGVzIGEgdmFyaWFibGUgZGF0YVNpemUgYW5kIHB1dHMgdGhlIHNlcmlhbGl6ZWQgc2l6ZSBpbiB0aGVyZS4KKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaW50IGRhdGFTaXplID0gMDtcbiIKKyAgICAiZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLiRuYW1lJC5sZW5ndGg7IGkrKykge1xuIgorICAgICIgIGludCBlbGVtZW50ID0gdGhpcy4kbmFtZSRbaV07XG4iCisgICAgIiAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLkNvZGVkT3V0cHV0Qnl0ZUJ1ZmZlck5hbm9cbiIKKyAgICAiICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhlbGVtZW50KTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAodGhpcy4kbmFtZSQgIT0gbnVsbCAmJiB0aGlzLiRuYW1lJC5sZW5ndGggPiAwKSB7XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgaWYgKGRlc2NyaXB0b3JfLT5vcHRpb25zKCkucGFja2VkKCkpIHsKKyAgICBHZW5lcmF0ZVJlcGVhdGVkRGF0YVNpemVDb2RlKHByaW50ZXIpOworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAib3V0cHV0LndyaXRlUmF3VmFyaW50MzIoJHRhZyQpO1xuIgorICAgICAgIm91dHB1dC53cml0ZVJhd1ZhcmludDMyKGRhdGFTaXplKTtcbiIKKyAgICAgICJmb3IgKGludCBpID0gMDsgaSA8IHRoaXMuJG5hbWUkLmxlbmd0aDsgaSsrKSB7XG4iCisgICAgICAiICBvdXRwdXQud3JpdGVSYXdWYXJpbnQzMih0aGlzLiRuYW1lJFtpXSk7XG4iCisgICAgICAifVxuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJmb3IgKGludCBpID0gMDsgaSA8IHRoaXMuJG5hbWUkLmxlbmd0aDsgaSsrKSB7XG4iCisgICAgICAiICBvdXRwdXQud3JpdGVJbnQzMigkbnVtYmVyJCwgdGhpcy4kbmFtZSRbaV0pO1xuIgorICAgICAgIn1cbiIpOworICB9CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEVudW1GaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAodGhpcy4kbmFtZSQgIT0gbnVsbCAmJiB0aGlzLiRuYW1lJC5sZW5ndGggPiAwKSB7XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgR2VuZXJhdGVSZXBlYXRlZERhdGFTaXplQ29kZShwcmludGVyKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAic2l6ZSArPSBkYXRhU2l6ZTtcbiIpOworICBpZiAoZGVzY3JpcHRvcl8tPm9wdGlvbnMoKS5wYWNrZWQoKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAic2l6ZSArPSAkdGFnX3NpemUkO1xuIgorICAgICAgInNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLkNvZGVkT3V0cHV0Qnl0ZUJ1ZmZlck5hbm9cbiIKKyAgICAgICIgICAgLmNvbXB1dGVSYXdWYXJpbnQzMlNpemUoZGF0YVNpemUpO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJzaXplICs9ICR0YWdfc2l6ZSQgKiB0aGlzLiRuYW1lJC5sZW5ndGg7XG4iKTsKKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVGaXhDbG9uZWRDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICh0aGlzLiRuYW1lJCAhPSBudWxsICYmIHRoaXMuJG5hbWUkLmxlbmd0aCA+IDApIHtcbiIKKyAgICAiICBjbG9uZWQuJG5hbWUkID0gdGhpcy4kbmFtZSQuY2xvbmUoKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVFcXVhbHNDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICghY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLkludGVybmFsTmFuby5lcXVhbHMoXG4iCisgICAgIiAgICB0aGlzLiRuYW1lJCwgb3RoZXIuJG5hbWUkKSkge1xuIgorICAgICIgIHJldHVybiBmYWxzZTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVIYXNoQ29kZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicmVzdWx0ID0gMzEgKiByZXN1bHRcbiIKKyAgICAiICAgICsgY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLkludGVybmFsTmFuby5oYXNoQ29kZSh0aGlzLiRuYW1lJCk7XG4iKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGphdmFuYW5vCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19lbnVtX2ZpZWxkLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2VudW1fZmllbGQuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iOTQ3OTBkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19lbnVtX2ZpZWxkLmgKQEAgLTAsMCArMSwxMjYgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvcHJvdG9idWYvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBTkFOT19FTlVNX0ZJRUxEX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQU5BTk9fRU5VTV9GSUVMRF9IX18KKworI2luY2x1ZGUgPG1hcD4KKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8dmVjdG9yPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19maWVsZC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmFuYW5vIHsKKworY2xhc3MgRW51bUZpZWxkR2VuZXJhdG9yIDogcHVibGljIEZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IEVudW1GaWVsZEdlbmVyYXRvcigKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwgY29uc3QgUGFyYW1zJiBwYXJhbXMpOworICB+RW51bUZpZWxkR2VuZXJhdG9yKCk7CisKKyAgLy8gaW1wbGVtZW50cyBGaWVsZEdlbmVyYXRvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgdm9pZCBHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIsIGJvb2wgbGF6eV9pbml0KSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUNsZWFyQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVIYXNoQ29kZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXNfOworICB2ZWN0b3I8c3RyaW5nPiBjYW5vbmljYWxfdmFsdWVzXzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoRW51bUZpZWxkR2VuZXJhdG9yKTsKK307CisKK2NsYXNzIEFjY2Vzc29yRW51bUZpZWxkR2VuZXJhdG9yIDogcHVibGljIEZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IEFjY2Vzc29yRW51bUZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgIGNvbnN0IFBhcmFtcyYgcGFyYW1zLCBpbnQgaGFzX2JpdF9pbmRleCk7CisgIH5BY2Nlc3NvckVudW1GaWVsZEdlbmVyYXRvcigpOworCisgIC8vIGltcGxlbWVudHMgRmllbGRHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIHZvaWQgR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyLCBib29sIGxhenlfaW5pdCkgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVDbGVhckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUVxdWFsc0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSGFzaENvZGVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKworIHByaXZhdGU6CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcl87CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyaWFibGVzXzsKKyAgdmVjdG9yPHN0cmluZz4gY2Fub25pY2FsX3ZhbHVlc187CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEFjY2Vzc29yRW51bUZpZWxkR2VuZXJhdG9yKTsKK307CisKK2NsYXNzIFJlcGVhdGVkRW51bUZpZWxkR2VuZXJhdG9yIDogcHVibGljIEZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IFJlcGVhdGVkRW51bUZpZWxkR2VuZXJhdG9yKAorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBjb25zdCBQYXJhbXMmIHBhcmFtcyk7CisgIH5SZXBlYXRlZEVudW1GaWVsZEdlbmVyYXRvcigpOworCisgIC8vIGltcGxlbWVudHMgRmllbGRHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIHZvaWQgR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyLCBib29sIGxhenlfaW5pdCkgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVDbGVhckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2luZ0NvZGVGcm9tUGFja2VkKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVFcXVhbHNDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUhhc2hDb2RlQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVGaXhDbG9uZWRDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKworIHByaXZhdGU6CisgIHZvaWQgR2VuZXJhdGVSZXBlYXRlZERhdGFTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXNfOworICB2ZWN0b3I8c3RyaW5nPiBjYW5vbmljYWxfdmFsdWVzXzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoUmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3IpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGphdmFuYW5vCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBTkFOT19FTlVNX0ZJRUxEX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19leHRlbnNpb24uY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2V4dGVuc2lvbi5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wYjlkMWQ4Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19leHRlbnNpb24uY2MKQEAgLTAsMCArMSwxNTAgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvcHJvdG9idWYvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjogYmR1ZmZAZ29vZ2xlLmNvbSAoQnJpYW4gRHVmZikKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19leHRlbnNpb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9faGVscGVycy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhbmFubyB7CisKK3VzaW5nIGludGVybmFsOjpXaXJlRm9ybWF0OwordXNpbmcgaW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOworCituYW1lc3BhY2UgeworCitjb25zdCBjaGFyKiBHZXRUeXBlQ29uc3RhbnROYW1lKGNvbnN0IEZpZWxkRGVzY3JpcHRvcjo6VHlwZSB0eXBlKSB7CisgIHN3aXRjaCAodHlwZSkgeworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0lOVDMyICAgOiByZXR1cm4gIlRZUEVfSU5UMzIiICAgOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1VJTlQzMiAgOiByZXR1cm4gIlRZUEVfVUlOVDMyIiAgOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NJTlQzMiAgOiByZXR1cm4gIlRZUEVfU0lOVDMyIiAgOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0ZJWEVEMzIgOiByZXR1cm4gIlRZUEVfRklYRUQzMiIgOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NGSVhFRDMyOiByZXR1cm4gIlRZUEVfU0ZJWEVEMzIiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0lOVDY0ICAgOiByZXR1cm4gIlRZUEVfSU5UNjQiICAgOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1VJTlQ2NCAgOiByZXR1cm4gIlRZUEVfVUlOVDY0IiAgOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NJTlQ2NCAgOiByZXR1cm4gIlRZUEVfU0lOVDY0IiAgOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0ZJWEVENjQgOiByZXR1cm4gIlRZUEVfRklYRUQ2NCIgOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NGSVhFRDY0OiByZXR1cm4gIlRZUEVfU0ZJWEVENjQiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0ZMT0FUICAgOiByZXR1cm4gIlRZUEVfRkxPQVQiICAgOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0RPVUJMRSAgOiByZXR1cm4gIlRZUEVfRE9VQkxFIiAgOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0JPT0wgICAgOiByZXR1cm4gIlRZUEVfQk9PTCIgICAgOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NUUklORyAgOiByZXR1cm4gIlRZUEVfU1RSSU5HIiAgOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0JZVEVTICAgOiByZXR1cm4gIlRZUEVfQllURVMiICAgOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0VOVU0gICAgOiByZXR1cm4gIlRZUEVfRU5VTSIgICAgOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQICAgOiByZXR1cm4gIlRZUEVfR1JPVVAiICAgOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX01FU1NBR0UgOiByZXR1cm4gIlRZUEVfTUVTU0FHRSIgOworCisgICAgLy8gTm8gZGVmYXVsdCBiZWNhdXNlIHdlIHdhbnQgdGhlIGNvbXBpbGVyIHRvIGNvbXBsYWluIGlmIGFueSBuZXcKKyAgICAvLyB0eXBlcyBhcmUgYWRkZWQuCisgIH0KKworICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ2FuJ3QgZ2V0IGhlcmUuIjsKKyAgcmV0dXJuIE5VTEw7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCit2b2lkIFNldFZhcmlhYmxlcyhjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGNvbnN0IFBhcmFtcyBwYXJhbXMsCisgICAgICAgICAgICAgICAgICBtYXA8c3RyaW5nLCBzdHJpbmc+KiB2YXJpYWJsZXMpIHsKKyAgKCp2YXJpYWJsZXMpWyJleHRlbmRzIl0gPSBDbGFzc05hbWUocGFyYW1zLCBkZXNjcmlwdG9yLT5jb250YWluaW5nX3R5cGUoKSk7CisgICgqdmFyaWFibGVzKVsibmFtZSJdID0gUmVuYW1lSmF2YUtleXdvcmRzKFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoZGVzY3JpcHRvcikpOworICBib29sIHJlcGVhdGVkID0gZGVzY3JpcHRvci0+aXNfcmVwZWF0ZWQoKTsKKyAgKCp2YXJpYWJsZXMpWyJyZXBlYXRlZCJdID0gcmVwZWF0ZWQgPyAiUmVwZWF0ZWQiIDogIiI7CisgICgqdmFyaWFibGVzKVsidHlwZSJdID0gR2V0VHlwZUNvbnN0YW50TmFtZShkZXNjcmlwdG9yLT50eXBlKCkpOworICBKYXZhVHlwZSBqYXZhX3R5cGUgPSBHZXRKYXZhVHlwZShkZXNjcmlwdG9yLT50eXBlKCkpOworICBzdHJpbmcgdGFnID0gU2ltcGxlSXRvYShXaXJlRm9ybWF0OjpNYWtlVGFnKGRlc2NyaXB0b3IpKTsKKyAgaWYgKGphdmFfdHlwZSA9PSBKQVZBVFlQRV9NRVNTQUdFKSB7CisgICAgKCp2YXJpYWJsZXMpWyJleHRfdHlwZSJdID0gIk1lc3NhZ2VUeXBlZCI7CisgICAgc3RyaW5nIG1lc3NhZ2VfdHlwZSA9IENsYXNzTmFtZShwYXJhbXMsIGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpKTsKKyAgICBpZiAocmVwZWF0ZWQpIHsKKyAgICAgIG1lc3NhZ2VfdHlwZSArPSAiW10iOworICAgIH0KKyAgICAoKnZhcmlhYmxlcylbImNsYXNzIl0gPSBtZXNzYWdlX3R5cGU7CisgICAgLy8gRm9yIG1lc3NhZ2UgdHlwZWQgZXh0ZW5zaW9ucywgdGFnc19wYXJhbXMgY29udGFpbnMgYSBzaW5nbGUgdGFnCisgICAgLy8gZm9yIGJvdGggc2luZ3VsYXIgYW5kIHJlcGVhdGVkIGNhc2VzLgorICAgICgqdmFyaWFibGVzKVsidGFnX3BhcmFtcyJdID0gdGFnOworICB9IGVsc2UgeworICAgICgqdmFyaWFibGVzKVsiZXh0X3R5cGUiXSA9ICJQcmltaXRpdmVUeXBlZCI7CisgICAgaWYgKCFyZXBlYXRlZCkgeworICAgICAgKCp2YXJpYWJsZXMpWyJjbGFzcyJdID0gQm94ZWRQcmltaXRpdmVUeXBlTmFtZShqYXZhX3R5cGUpOworICAgICAgKCp2YXJpYWJsZXMpWyJ0YWdfcGFyYW1zIl0gPSB0YWc7CisgICAgfSBlbHNlIHsKKyAgICAgICgqdmFyaWFibGVzKVsiY2xhc3MiXSA9IFByaW1pdGl2ZVR5cGVOYW1lKGphdmFfdHlwZSkgKyAiW10iOworICAgICAgaWYgKCFkZXNjcmlwdG9yLT5pc19wYWNrYWJsZSgpKSB7CisgICAgICAgIC8vIE5vbi1wYWNrYWJsZTogbm9uUGFja2VkVGFnID09IHRhZywgcGFja2VkVGFnID09IDAKKyAgICAgICAgKCp2YXJpYWJsZXMpWyJ0YWdfcGFyYW1zIl0gPSB0YWcgKyAiLCAiICsgdGFnICsgIiwgMCI7CisgICAgICB9IGVsc2UgaWYgKGRlc2NyaXB0b3ItPm9wdGlvbnMoKS5wYWNrZWQoKSkgeworICAgICAgICAvLyBQYWNrYWJsZSBhbmQgcGFja2VkOiB0YWcgPT0gcGFja2VkVGFnCisgICAgICAgIHN0cmluZyBub25fcGFja2VkX3RhZyA9IFNpbXBsZUl0b2EoV2lyZUZvcm1hdExpdGU6Ok1ha2VUYWcoCisgICAgICAgICAgICBkZXNjcmlwdG9yLT5udW1iZXIoKSwKKyAgICAgICAgICAgIFdpcmVGb3JtYXQ6OldpcmVUeXBlRm9yRmllbGRUeXBlKGRlc2NyaXB0b3ItPnR5cGUoKSkpKTsKKyAgICAgICAgKCp2YXJpYWJsZXMpWyJ0YWdfcGFyYW1zIl0gPSB0YWcgKyAiLCAiICsgbm9uX3BhY2tlZF90YWcgKyAiLCAiICsgdGFnOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgLy8gUGFja2FibGUgYW5kIG5vdCBwYWNrZWQ6IHRhZyA9PSBub25QYWNrZWRUYWcKKyAgICAgICAgc3RyaW5nIHBhY2tlZF90YWcgPSBTaW1wbGVJdG9hKFdpcmVGb3JtYXRMaXRlOjpNYWtlVGFnKAorICAgICAgICAgICAgZGVzY3JpcHRvci0+bnVtYmVyKCksIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVEKSk7CisgICAgICAgICgqdmFyaWFibGVzKVsidGFnX3BhcmFtcyJdID0gdGFnICsgIiwgIiArIHRhZyArICIsICIgKyBwYWNrZWRfdGFnOworICAgICAgfQorICAgIH0KKyAgfQorfQorCitFeHRlbnNpb25HZW5lcmF0b3I6OgorRXh0ZW5zaW9uR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwgY29uc3QgUGFyYW1zJiBwYXJhbXMpCisgIDogcGFyYW1zXyhwYXJhbXMpLCBkZXNjcmlwdG9yXyhkZXNjcmlwdG9yKSB7CisgIFNldFZhcmlhYmxlcyhkZXNjcmlwdG9yLCBwYXJhbXMsICZ2YXJpYWJsZXNfKTsKK30KKworRXh0ZW5zaW9uR2VuZXJhdG9yOjp+RXh0ZW5zaW9uR2VuZXJhdG9yKCkge30KKwordm9pZCBFeHRlbnNpb25HZW5lcmF0b3I6OkdlbmVyYXRlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KCJcbiIpOworICBQcmludEZpZWxkQ29tbWVudChwcmludGVyLCBkZXNjcmlwdG9yXyk7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLkV4dGVuc2lvbjxcbiIKKyAgICAiICAgICRleHRlbmRzJCxcbiIKKyAgICAiICAgICRjbGFzcyQ+ICRuYW1lJCA9XG4iCisgICAgIiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLkV4dGVuc2lvbi5jcmVhdGUkcmVwZWF0ZWQkJGV4dF90eXBlJChcbiIKKyAgICAiICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLkV4dGVuc2lvbi4kdHlwZSQsXG4iCisgICAgIiAgICAgICAgICAgICRjbGFzcyQuY2xhc3MsXG4iCisgICAgIiAgICAgICAgICAgICR0YWdfcGFyYW1zJEwpO1xuIik7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhbmFubworfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19leHRlbnNpb24uaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZXh0ZW5zaW9uLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDg0M2UyOQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZXh0ZW5zaW9uLmgKQEAgLTAsMCArMSw3NCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9wcm90b2J1Zi8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBiZHVmZkBnb29nbGUuY29tIChCcmlhbiBEdWZmKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFOQU5PX0VYVEVOU0lPTl9IXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQU5BTk9fRVhURU5TSU9OX0hfCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX3BhcmFtcy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworICBuYW1lc3BhY2UgaW8geworICAgIGNsYXNzIFByaW50ZXI7ICAgICAgICAgICAgIC8vIHByaW50ZXIuaAorICB9Cit9CisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmFuYW5vIHsKKworY2xhc3MgRXh0ZW5zaW9uR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IEV4dGVuc2lvbkdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGNvbnN0IFBhcmFtcyYgcGFyYW1zKTsKKyAgfkV4dGVuc2lvbkdlbmVyYXRvcigpOworCisgIHZvaWQgR2VuZXJhdGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgY29uc3QgUGFyYW1zJiBwYXJhbXNfOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlc187CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEV4dGVuc2lvbkdlbmVyYXRvcik7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgamF2YW5hbm8KK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFOQU5PX0VYVEVOU0lPTl9IXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19maWVsZC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZmllbGQuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODUyNTdmMwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZmllbGQuY2MKQEAgLTAsMCArMSwyMDkgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvcHJvdG9idWYvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fcHJpbWl0aXZlX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2VudW1fZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fbWFwX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX21lc3NhZ2VfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YW5hbm8geworCitGaWVsZEdlbmVyYXRvcjo6fkZpZWxkR2VuZXJhdG9yKCkge30KKworYm9vbCBGaWVsZEdlbmVyYXRvcjo6U2F2ZWREZWZhdWx0TmVlZGVkKCkgY29uc3QgeworICAvLyBObyBzYXZlZCBkZWZhdWx0IGZvciB0aGlzIGZpZWxkIGJ5IGRlZmF1bHQuCisgIC8vIFN1YmNsYXNzZXMgd2hvc2UgaW5zdGFuY2VzIG1heSBuZWVkIHNhdmVkIGRlZmF1bHRzIHdpbGwgb3ZlcnJpZGUgdGhpcworICAvLyBhbmQgcmV0dXJuIHRoZSBhcHByb3ByaWF0ZSB2YWx1ZS4KKyAgcmV0dXJuIGZhbHNlOworfQorCit2b2lkIEZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZUluaXRTYXZlZERlZmF1bHRDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIE5vIHNhdmVkIGRlZmF1bHQgZm9yIHRoaXMgZmllbGQgYnkgZGVmYXVsdC4KKyAgLy8gU3ViY2xhc3NlcyB3aG9zZSBpbnN0YW5jZXMgbWF5IG5lZWQgc2F2ZWQgZGVmYXVsdHMgd2lsbCBvdmVycmlkZSB0aGlzCisgIC8vIGFuZCBnZW5lcmF0ZSB0aGUgYXBwcm9wcmlhdGUgaW5pdCBjb2RlIHRvIHRoZSBwcmludGVyLgorfQorCit2b2lkIEZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZU1lcmdpbmdDb2RlRnJvbVBhY2tlZChpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBSZWFjaGluZyBoZXJlIGluZGljYXRlcyBhIGJ1Zy4gQ2FzZXMgYXJlOgorICAvLyAgIC0gVGhpcyBGaWVsZEdlbmVyYXRvciBzaG91bGQgc3VwcG9ydCBwYWNraW5nLCBidXQgdGhpcyBtZXRob2Qgc2hvdWxkIGJlCisgIC8vICAgICBvdmVycmlkZGVuLgorICAvLyAgIC0gVGhpcyBGaWVsZEdlbmVyYXRvciBkb2Vzbid0IHN1cHBvcnQgcGFja2luZywgYW5kIHRoaXMgbWV0aG9kIHNob3VsZAorICAvLyAgICAgbmV2ZXIgaGF2ZSBiZWVuIGNhbGxlZC4KKyAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkdlbmVyYXRlUGFyc2luZ0NvZGVGcm9tUGFja2VkKCkgIgorICAgICAgICAgICAgIDw8ICJjYWxsZWQgb24gZmllbGQgZ2VuZXJhdG9yIHRoYXQgZG9lcyBub3Qgc3VwcG9ydCBwYWNraW5nLiI7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitGaWVsZEdlbmVyYXRvck1hcDo6RmllbGRHZW5lcmF0b3JNYXAoCisgICAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwgY29uc3QgUGFyYW1zICZwYXJhbXMpCisgIDogZGVzY3JpcHRvcl8oZGVzY3JpcHRvciksCisgICAgZmllbGRfZ2VuZXJhdG9yc18oCisgICAgICBuZXcgc2NvcGVkX3B0cjxGaWVsZEdlbmVyYXRvcj5bZGVzY3JpcHRvci0+ZmllbGRfY291bnQoKV0pIHsKKworICBpbnQgbmV4dF9oYXNfYml0X2luZGV4ID0gMDsKKyAgYm9vbCBzYXZlZF9kZWZhdWx0c19uZWVkZWQgPSBmYWxzZTsKKyAgLy8gQ29uc3RydWN0IGFsbCB0aGUgRmllbGRHZW5lcmF0b3JzLgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3ItPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIEZpZWxkR2VuZXJhdG9yKiBmaWVsZF9nZW5lcmF0b3IgPSBNYWtlR2VuZXJhdG9yKAorICAgICAgICBkZXNjcmlwdG9yLT5maWVsZChpKSwgcGFyYW1zLCAmbmV4dF9oYXNfYml0X2luZGV4KTsKKyAgICBzYXZlZF9kZWZhdWx0c19uZWVkZWQgPSBzYXZlZF9kZWZhdWx0c19uZWVkZWQKKyAgICAgICAgfHwgZmllbGRfZ2VuZXJhdG9yLT5TYXZlZERlZmF1bHROZWVkZWQoKTsKKyAgICBmaWVsZF9nZW5lcmF0b3JzX1tpXS5yZXNldChmaWVsZF9nZW5lcmF0b3IpOworICB9CisgIHRvdGFsX2JpdHNfID0gbmV4dF9oYXNfYml0X2luZGV4OworICBzYXZlZF9kZWZhdWx0c19uZWVkZWRfID0gc2F2ZWRfZGVmYXVsdHNfbmVlZGVkOworfQorCitGaWVsZEdlbmVyYXRvciogRmllbGRHZW5lcmF0b3JNYXA6Ok1ha2VHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICBjb25zdCBQYXJhbXMgJnBhcmFtcywgaW50KiBuZXh0X2hhc19iaXRfaW5kZXgpIHsKKyAgSmF2YVR5cGUgamF2YV90eXBlID0gR2V0SmF2YVR5cGUoZmllbGQpOworICBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkpIHsKKyAgICBzd2l0Y2ggKGphdmFfdHlwZSkgeworICAgICAgY2FzZSBKQVZBVFlQRV9NRVNTQUdFOgorICAgICAgICBpZiAoSXNNYXBFbnRyeShmaWVsZC0+bWVzc2FnZV90eXBlKCkpKSB7CisgICAgICAgICAgcmV0dXJuIG5ldyBNYXBGaWVsZEdlbmVyYXRvcihmaWVsZCwgcGFyYW1zKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICByZXR1cm4gbmV3IFJlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yKGZpZWxkLCBwYXJhbXMpOworICAgICAgICB9CisgICAgICBjYXNlIEpBVkFUWVBFX0VOVU06CisgICAgICAgIHJldHVybiBuZXcgUmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3IoZmllbGQsIHBhcmFtcyk7CisgICAgICBkZWZhdWx0OgorICAgICAgICByZXR1cm4gbmV3IFJlcGVhdGVkUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IoZmllbGQsIHBhcmFtcyk7CisgICAgfQorICB9IGVsc2UgaWYgKGZpZWxkLT5jb250YWluaW5nX29uZW9mKCkpIHsKKyAgICBzd2l0Y2ggKGphdmFfdHlwZSkgeworICAgICAgY2FzZSBKQVZBVFlQRV9NRVNTQUdFOgorICAgICAgICByZXR1cm4gbmV3IE1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yKGZpZWxkLCBwYXJhbXMpOworICAgICAgY2FzZSBKQVZBVFlQRV9FTlVNOgorICAgICAgZGVmYXVsdDoKKyAgICAgICAgcmV0dXJuIG5ldyBQcmltaXRpdmVPbmVvZkZpZWxkR2VuZXJhdG9yKGZpZWxkLCBwYXJhbXMpOworICAgIH0KKyAgfSBlbHNlIGlmIChwYXJhbXMub3B0aW9uYWxfZmllbGRfYWNjZXNzb3JzKCkgJiYgZmllbGQtPmlzX29wdGlvbmFsKCkKKyAgICAgICYmIGphdmFfdHlwZSAhPSBKQVZBVFlQRV9NRVNTQUdFKSB7CisgICAgLy8gV2UgbmVlZCBhIGhhcy1iaXQgZm9yIGVhY2ggcHJpbWl0aXZlL2VudW0gZmllbGQgYmVjYXVzZSB0aGVpciBkZWZhdWx0CisgICAgLy8gdmFsdWVzIGNvdWxkIGJlIHNhbWUgYXMgZXhwbGljaXRseSBzZXQgdmFsdWVzLiBCdXQgd2UgZG9uJ3QgbmVlZCBpdAorICAgIC8vIGZvciBhIG1lc3NhZ2UgZmllbGQgYmVjYXVzZSB0aGV5IGhhdmUgbm8gZGVmYXVsdHMgYW5kIE5hbm8gdXNlcyAnbnVsbCcKKyAgICAvLyBmb3IgdW5zZXQgbWVzc2FnZXMsIHdoaWNoIGNhbm5vdCBiZSBzZXQgZXhwbGljaXRseS4KKyAgICBzd2l0Y2ggKGphdmFfdHlwZSkgeworICAgICAgY2FzZSBKQVZBVFlQRV9FTlVNOgorICAgICAgICByZXR1cm4gbmV3IEFjY2Vzc29yRW51bUZpZWxkR2VuZXJhdG9yKAorICAgICAgICAgICAgZmllbGQsIHBhcmFtcywgKCpuZXh0X2hhc19iaXRfaW5kZXgpKyspOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgcmV0dXJuIG5ldyBBY2Nlc3NvclByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKAorICAgICAgICAgICAgZmllbGQsIHBhcmFtcywgKCpuZXh0X2hhc19iaXRfaW5kZXgpKyspOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICBzd2l0Y2ggKGphdmFfdHlwZSkgeworICAgICAgY2FzZSBKQVZBVFlQRV9NRVNTQUdFOgorICAgICAgICByZXR1cm4gbmV3IE1lc3NhZ2VGaWVsZEdlbmVyYXRvcihmaWVsZCwgcGFyYW1zKTsKKyAgICAgIGNhc2UgSkFWQVRZUEVfRU5VTToKKyAgICAgICAgcmV0dXJuIG5ldyBFbnVtRmllbGRHZW5lcmF0b3IoZmllbGQsIHBhcmFtcyk7CisgICAgICBkZWZhdWx0OgorICAgICAgICByZXR1cm4gbmV3IFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKGZpZWxkLCBwYXJhbXMpOworICAgIH0KKyAgfQorfQorCitGaWVsZEdlbmVyYXRvck1hcDo6fkZpZWxkR2VuZXJhdG9yTWFwKCkge30KKworY29uc3QgRmllbGRHZW5lcmF0b3ImIEZpZWxkR2VuZXJhdG9yTWFwOjpnZXQoCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3QgeworICBHT09HTEVfQ0hFQ0tfRVEoZmllbGQtPmNvbnRhaW5pbmdfdHlwZSgpLCBkZXNjcmlwdG9yXyk7CisgIHJldHVybiAqZmllbGRfZ2VuZXJhdG9yc19bZmllbGQtPmluZGV4KCldOworfQorCit2b2lkIFNldENvbW1vbk9uZW9mVmFyaWFibGVzKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwPHN0cmluZywgc3RyaW5nPiogdmFyaWFibGVzKSB7CisgICgqdmFyaWFibGVzKVsib25lb2ZfbmFtZSJdID0KKyAgICAgIFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoZGVzY3JpcHRvci0+Y29udGFpbmluZ19vbmVvZigpKTsKKyAgKCp2YXJpYWJsZXMpWyJvbmVvZl9jYXBpdGFsaXplZF9uYW1lIl0gPQorICAgICAgVW5kZXJzY29yZXNUb0NhcGl0YWxpemVkQ2FtZWxDYXNlKGRlc2NyaXB0b3ItPmNvbnRhaW5pbmdfb25lb2YoKSk7CisgICgqdmFyaWFibGVzKVsib25lb2ZfaW5kZXgiXSA9CisgICAgICBTaW1wbGVJdG9hKGRlc2NyaXB0b3ItPmNvbnRhaW5pbmdfb25lb2YoKS0+aW5kZXgoKSk7CisgICgqdmFyaWFibGVzKVsic2V0X29uZW9mX2Nhc2UiXSA9CisgICAgICAidGhpcy4iICsgKCp2YXJpYWJsZXMpWyJvbmVvZl9uYW1lIl0gKworICAgICAgIkNhc2VfID0gIiArIFNpbXBsZUl0b2EoZGVzY3JpcHRvci0+bnVtYmVyKCkpOworICAoKnZhcmlhYmxlcylbImNsZWFyX29uZW9mX2Nhc2UiXSA9CisgICAgICAidGhpcy4iICsgKCp2YXJpYWJsZXMpWyJvbmVvZl9uYW1lIl0gKyAiQ2FzZV8gPSAwIjsKKyAgKCp2YXJpYWJsZXMpWyJoYXNfb25lb2ZfY2FzZSJdID0KKyAgICAgICJ0aGlzLiIgKyAoKnZhcmlhYmxlcylbIm9uZW9mX25hbWUiXSArICJDYXNlXyA9PSAiICsKKyAgICAgIFNpbXBsZUl0b2EoZGVzY3JpcHRvci0+bnVtYmVyKCkpOworfQorCit2b2lkIEdlbmVyYXRlT25lb2ZGaWVsZEVxdWFscyhjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtYXA8c3RyaW5nLCBzdHJpbmc+JiB2YXJpYWJsZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBpZiAoR2V0SmF2YVR5cGUoZGVzY3JpcHRvcikgPT0gSkFWQVRZUEVfQllURVMpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXMsCisgICAgICAiaWYgKHRoaXMuaGFzJGNhcGl0YWxpemVkX25hbWUkKCkpIHtcbiIKKyAgICAgICIgIGlmICghamF2YS51dGlsLkFycmF5cy5lcXVhbHMoKGJ5dGVbXSkgdGhpcy4kb25lb2ZfbmFtZSRfLFxuIgorICAgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZVtdKSBvdGhlci4kb25lb2ZfbmFtZSRfKSkge1xuIgorICAgICAgIiAgICByZXR1cm4gZmFsc2U7XG4iCisgICAgICAiICB9XG4iCisgICAgICAifVxuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzLAorICAgICAgImlmICh0aGlzLmhhcyRjYXBpdGFsaXplZF9uYW1lJCgpKSB7XG4iCisgICAgICAiICBpZiAoIXRoaXMuJG9uZW9mX25hbWUkXy5lcXVhbHMob3RoZXIuJG9uZW9mX25hbWUkXykpIHtcbiIKKyAgICAgICIgICAgcmV0dXJuIGZhbHNlO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIn1cbiIpOworICB9Cit9CisKK3ZvaWQgR2VuZXJhdGVPbmVvZkZpZWxkSGFzaENvZGUoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtYXA8c3RyaW5nLCBzdHJpbmc+JiB2YXJpYWJsZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIGlmIChHZXRKYXZhVHlwZShkZXNjcmlwdG9yKSA9PSBKQVZBVFlQRV9CWVRFUykgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAgICJyZXN1bHQgPSAzMSAqIHJlc3VsdCArICgkaGFzX29uZW9mX2Nhc2UkXG4iCisgICAgICAiICAgPyBqYXZhLnV0aWwuQXJyYXlzLmhhc2hDb2RlKChieXRlW10pIHRoaXMuJG9uZW9mX25hbWUkXykgOiAwKTtcbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlcywKKyAgICAgICJyZXN1bHQgPSAzMSAqIHJlc3VsdCArXG4iCisgICAgICAiICAoJGhhc19vbmVvZl9jYXNlJCA/IHRoaXMuJG9uZW9mX25hbWUkXy5oYXNoQ29kZSgpIDogMCk7XG4iKTsKKyAgfQorfQorCit9ICAvLyBuYW1lc3BhY2UgamF2YW5hbm8KK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2ZpZWxkLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2ZpZWxkLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTdjMjIxZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZmllbGQuaApAQCAtMCwwICsxLDEzMCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9wcm90b2J1Zi8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFOQU5PX0ZJRUxEX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQU5BTk9fRklFTERfSF9fCisKKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19wYXJhbXMuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworICBuYW1lc3BhY2UgaW8geworICAgIGNsYXNzIFByaW50ZXI7ICAgICAgICAgICAgIC8vIHByaW50ZXIuaAorICB9Cit9CisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmFuYW5vIHsKKworY2xhc3MgRmllbGRHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgRmllbGRHZW5lcmF0b3IoY29uc3QgUGFyYW1zJiBwYXJhbXMpIDogcGFyYW1zXyhwYXJhbXMpIHt9CisgIHZpcnR1YWwgfkZpZWxkR2VuZXJhdG9yKCk7CisKKyAgdmlydHVhbCBib29sIFNhdmVkRGVmYXVsdE5lZWRlZCgpIGNvbnN0OworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVJbml0U2F2ZWREZWZhdWx0Q29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyAgLy8gR2VuZXJhdGVzIGNvZGUgZm9yIEphdmEgZmllbGRzIGFuZCBtZXRob2RzIHN1cHBvcnRpbmcgdGhpcyBmaWVsZC4KKyAgLy8gSWYgdGhpcyBmaWVsZCBuZWVkcyBhIHNhdmVkIGRlZmF1bHQgKFNhdmVkRGVmYXVsdE5lZWRlZCgpIGlzIHRydWUpLAorICAvLyB0aGVuIEBsYXp5X2luaXQgY29udHJvbHMgaG93IHRoZSBzdGF0aWMgZmllbGQgZm9yIHRoYXQgZGVmYXVsdCB2YWx1ZQorICAvLyBhbmQgaXRzIGluaXRpYWxpemF0aW9uIGNvZGUgc2hvdWxkIGJlIGdlbmVyYXRlZC4gSWYgQGxhenlfaW5pdCBpcworICAvLyB0cnVlLCB0aGUgc3RhdGljIGZpZWxkIGlzIG5vdCBkZWNsYXJlZCBmaW5hbCBhbmQgdGhlIGluaXRpYWxpemF0aW9uCisgIC8vIGNvZGUgaXMgZ2VuZXJhdGVkIG9ubHkgd2hlbiBHZW5lcmF0ZUluaXRTYXZlZERlZmF1bHRDb2RlIGlzIGNhbGxlZDsKKyAgLy8gb3RoZXJ3aXNlLCB0aGUgc3RhdGljIGZpZWxkIGlzIGRlY2xhcmVkIGZpbmFsIGFuZCBpbml0aWFsaXplZCBpbmxpbmUuCisgIC8vIEdlbmVyYXRlSW5pdFNhdmVkRGVmYXVsdENvZGUgd2lsbCBub3QgYmUgY2FsbGVkIGluIHRoZSBsYXR0ZXIgY2FzZS4KKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlTWVtYmVycygKKyAgICAgIGlvOjpQcmludGVyKiBwcmludGVyLCBib29sIGxhenlfaW5pdCkgY29uc3QgPSAwOworCisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZUNsZWFyQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgPSAwOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgPSAwOworCisgIC8vIEdlbmVyYXRlcyBjb2RlIHRvIG1lcmdlIGZyb20gcGFja2VkIHNlcmlhbGl6ZWQgZm9ybS4gVGhlIGRlZmF1bHQKKyAgLy8gaW1wbGVtZW50YXRpb24gd2lsbCBmYWlsOyBzdWJjbGFzc2VzIHdoaWNoIGNhbiBoYW5kbGUgcGFja2VkIHNlcmlhbGl6ZWQKKyAgLy8gZm9ybXMgd2lsbCBvdmVycmlkZSB0aGlzIGFuZCBwcmludCBhcHByb3ByaWF0ZSBjb2RlIHRvIHRoZSBwcmludGVyLgorICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZUZyb21QYWNrZWQoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgPSAwOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVFcXVhbHNDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZUhhc2hDb2RlQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgPSAwOworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVGaXhDbG9uZWRDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7fQorCisgcHJvdGVjdGVkOgorICBjb25zdCBQYXJhbXMmIHBhcmFtc187CisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEZpZWxkR2VuZXJhdG9yKTsKK307CisKKy8vIENvbnZlbmllbmNlIGNsYXNzIHdoaWNoIGNvbnN0cnVjdHMgRmllbGRHZW5lcmF0b3JzIGZvciBhIERlc2NyaXB0b3IuCitjbGFzcyBGaWVsZEdlbmVyYXRvck1hcCB7CisgcHVibGljOgorICBleHBsaWNpdCBGaWVsZEdlbmVyYXRvck1hcChjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBjb25zdCBQYXJhbXMgJnBhcmFtcyk7CisgIH5GaWVsZEdlbmVyYXRvck1hcCgpOworCisgIGNvbnN0IEZpZWxkR2VuZXJhdG9yJiBnZXQoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3Q7CisgIGludCB0b3RhbF9iaXRzKCkgY29uc3QgeyByZXR1cm4gdG90YWxfYml0c187IH0KKyAgYm9vbCBzYXZlZF9kZWZhdWx0c19uZWVkZWQoKSBjb25zdCB7IHJldHVybiBzYXZlZF9kZWZhdWx0c19uZWVkZWRfOyB9CisKKyBwcml2YXRlOgorICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgc2NvcGVkX2FycmF5PHNjb3BlZF9wdHI8RmllbGRHZW5lcmF0b3I+ID4gZmllbGRfZ2VuZXJhdG9yc187CisgIGludCB0b3RhbF9iaXRzXzsKKyAgYm9vbCBzYXZlZF9kZWZhdWx0c19uZWVkZWRfOworCisgIHN0YXRpYyBGaWVsZEdlbmVyYXRvciogTWFrZUdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgY29uc3QgUGFyYW1zICZwYXJhbXMsIGludCogbmV4dF9oYXNfYml0X2luZGV4KTsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoRmllbGRHZW5lcmF0b3JNYXApOworfTsKKwordm9pZCBTZXRDb21tb25PbmVvZlZhcmlhYmxlcyhjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcDxzdHJpbmcsIHN0cmluZz4qIHZhcmlhYmxlcyk7Cit2b2lkIEdlbmVyYXRlT25lb2ZGaWVsZEVxdWFscyhjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtYXA8c3RyaW5nLCBzdHJpbmc+JiB2YXJpYWJsZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlcik7Cit2b2lkIEdlbmVyYXRlT25lb2ZGaWVsZEhhc2hDb2RlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWFwPHN0cmluZywgc3RyaW5nPiYgdmFyaWFibGVzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlcik7CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhbmFubworfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQU5BTk9fRklFTERfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2ZpbGUuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2ZpbGUuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzY3NmFiOQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZmlsZS5jYwpAQCAtMCwwICsxLDI2MyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9wcm90b2J1Zi8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxpb3N0cmVhbT4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19maWxlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2VudW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZXh0ZW5zaW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fbWVzc2FnZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jb2RlX2dlbmVyYXRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YW5hbm8geworCituYW1lc3BhY2UgeworCisvLyBSZWN1cnNpdmVseSBzZWFyY2hlcyB0aGUgZ2l2ZW4gbWVzc2FnZSB0byBzZWUgaWYgaXQgY29udGFpbnMgYW55IGV4dGVuc2lvbnMuCitib29sIFVzZXNFeHRlbnNpb25zKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UpIHsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpOworCisgIC8vIFdlIGNvbnNlcnZhdGl2ZWx5IGFzc3VtZSB0aGF0IHVua25vd24gZmllbGRzIGFyZSBleHRlbnNpb25zLgorICBpZiAocmVmbGVjdGlvbi0+R2V0VW5rbm93bkZpZWxkcyhtZXNzYWdlKS5maWVsZF9jb3VudCgpID4gMCkgcmV0dXJuIHRydWU7CisKKyAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+IGZpZWxkczsKKyAgcmVmbGVjdGlvbi0+TGlzdEZpZWxkcyhtZXNzYWdlLCAmZmllbGRzKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkcy5zaXplKCk7IGkrKykgeworICAgIGlmIChmaWVsZHNbaV0tPmlzX2V4dGVuc2lvbigpKSByZXR1cm4gdHJ1ZTsKKworICAgIGlmIChmaWVsZHNbaV0tPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UpIHsKKyAgICAgIGlmIChmaWVsZHNbaV0tPmlzX3JlcGVhdGVkKCkpIHsKKyAgICAgICAgaW50IHNpemUgPSByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgZmllbGRzW2ldKTsKKyAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBzaXplOyBqKyspIHsKKyAgICAgICAgICBjb25zdCBNZXNzYWdlJiBzdWJfbWVzc2FnZSA9CisgICAgICAgICAgICByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZE1lc3NhZ2UobWVzc2FnZSwgZmllbGRzW2ldLCBqKTsKKyAgICAgICAgICBpZiAoVXNlc0V4dGVuc2lvbnMoc3ViX21lc3NhZ2UpKSByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgfSBlbHNlIHsKKyAgICAgICAgY29uc3QgTWVzc2FnZSYgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5HZXRNZXNzYWdlKG1lc3NhZ2UsIGZpZWxkc1tpXSk7CisgICAgICAgIGlmIChVc2VzRXh0ZW5zaW9ucyhzdWJfbWVzc2FnZSkpIHJldHVybiB0cnVlOworICAgICAgfQorICAgIH0KKyAgfQorCisgIHJldHVybiBmYWxzZTsKK30KKworfSAgLy8gbmFtZXNwYWNlCisKK0ZpbGVHZW5lcmF0b3I6OkZpbGVHZW5lcmF0b3IoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUsIGNvbnN0IFBhcmFtcyYgcGFyYW1zKQorICA6IGZpbGVfKGZpbGUpLAorICAgIHBhcmFtc18ocGFyYW1zKSwKKyAgICBqYXZhX3BhY2thZ2VfKEZpbGVKYXZhUGFja2FnZShwYXJhbXMsIGZpbGUpKSwKKyAgICBjbGFzc25hbWVfKEZpbGVDbGFzc05hbWUocGFyYW1zLCBmaWxlKSkge30KKworRmlsZUdlbmVyYXRvcjo6fkZpbGVHZW5lcmF0b3IoKSB7fQorCitib29sIEZpbGVHZW5lcmF0b3I6OlZhbGlkYXRlKHN0cmluZyogZXJyb3IpIHsKKyAgLy8gQ2hlY2sgZm9yIGV4dGVuc2lvbnMKKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICBmaWxlXy0+Q29weVRvKCZmaWxlX3Byb3RvKTsKKyAgaWYgKFVzZXNFeHRlbnNpb25zKGZpbGVfcHJvdG8pICYmICFwYXJhbXNfLnN0b3JlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICBlcnJvci0+YXNzaWduKGZpbGVfLT5uYW1lKCkpOworICAgIGVycm9yLT5hcHBlbmQoCisgICAgICAgICI6IEphdmEgTkFOT19SVU5USU1FIG9ubHkgc3VwcG9ydHMgZXh0ZW5zaW9ucyB3aGVuIHRoZSAiCisgICAgICAgICInc3RvcmVfdW5rbm93bl9maWVsZHMnIGdlbmVyYXRvciBvcHRpb24gaXMgJ3RydWUnLiIpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIGlmIChmaWxlXy0+c2VydmljZV9jb3VudCgpICE9IDAgJiYgIXBhcmFtc18uaWdub3JlX3NlcnZpY2VzKCkpIHsKKyAgICBlcnJvci0+YXNzaWduKGZpbGVfLT5uYW1lKCkpOworICAgIGVycm9yLT5hcHBlbmQoCisgICAgICAiOiBKYXZhIE5BTk9fUlVOVElNRSBkb2VzIG5vdCBzdXBwb3J0IHNlcnZpY2VzXCIiKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBpZiAoIUlzT3V0ZXJDbGFzc05lZWRlZChwYXJhbXNfLCBmaWxlXykpIHsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIC8vIENoZWNrIHdoZXRoZXIgbGVnYWN5IGphdmFuYW5vIGdlbmVyYXRvciB3b3VsZCBvbWl0IHRoZSBvdXRlciBjbGFzcy4KKyAgaWYgKCFwYXJhbXNfLmhhc19qYXZhX291dGVyX2NsYXNzbmFtZShmaWxlXy0+bmFtZSgpKQorICAgICAgJiYgZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpID09IDEKKyAgICAgICYmIGZpbGVfLT5lbnVtX3R5cGVfY291bnQoKSA9PSAwICYmIGZpbGVfLT5leHRlbnNpb25fY291bnQoKSA9PSAwKSB7CisgICAgY291dCA8PCAiSU5GTzogIiA8PCBmaWxlXy0+bmFtZSgpIDw8ICI6IiA8PCBlbmRsOworICAgIGNvdXQgPDwgIkphdmFuYW5vIGdlbmVyYXRvciBoYXMgY2hhbmdlZCB0byBhbGlnbiB3aXRoIGphdmEgZ2VuZXJhdG9yLiAiCisgICAgICAgICJBbiBvdXRlciBjbGFzcyB3aWxsIGJlIGNyZWF0ZWQgZm9yIHRoaXMgZmlsZSBhbmQgdGhlIHNpbmdsZSBtZXNzYWdlICIKKyAgICAgICAgImluIHRoZSBmaWxlIHdpbGwgYmVjb21lIGEgbmVzdGVkIGNsYXNzLiBVc2UgamF2YV9tdWx0aXBsZV9maWxlcyB0byAiCisgICAgICAgICJza2lwIGdlbmVyYXRpbmcgdGhlIG91dGVyIGNsYXNzLCBvciBzZXQgYW4gZXhwbGljaXQgIgorICAgICAgICAiamF2YV9vdXRlcl9jbGFzc25hbWUgdG8gc3VwcHJlc3MgdGhpcyBtZXNzYWdlLiIgPDwgZW5kbDsKKyAgfQorCisgIC8vIENoZWNrIHRoYXQgbm8gY2xhc3MgbmFtZSBtYXRjaGVzIHRoZSBmaWxlJ3MgY2xhc3MgbmFtZS4gIFRoaXMgaXMgYSBjb21tb24KKyAgLy8gcHJvYmxlbSB0aGF0IGxlYWRzIHRvIEphdmEgY29tcGlsZSBlcnJvcnMgdGhhdCBjYW4gYmUgaGFyZCB0byB1bmRlcnN0YW5kLgorICAvLyBJdCdzIGVzcGVjaWFsbHkgYmFkIHdoZW4gdXNpbmcgdGhlIGphdmFfbXVsdGlwbGVfZmlsZXMsIHNpbmNlIHdlIHdvdWxkCisgIC8vIGVuZCB1cCBvdmVyd3JpdGluZyB0aGUgb3V0ZXIgY2xhc3Mgd2l0aCBvbmUgb2YgdGhlIGlubmVyIG9uZXMuCisgIGJvb2wgZm91bmRfY29uZmxpY3QgPSBmYWxzZTsKKyAgZm9yIChpbnQgaSA9IDA7ICFmb3VuZF9jb25mbGljdCAmJiBpIDwgZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBpZiAoZmlsZV8tPm1lc3NhZ2VfdHlwZShpKS0+bmFtZSgpID09IGNsYXNzbmFtZV8pIHsKKyAgICAgIGZvdW5kX2NvbmZsaWN0ID0gdHJ1ZTsKKyAgICB9CisgIH0KKyAgaWYgKHBhcmFtc18uamF2YV9lbnVtX3N0eWxlKCkpIHsKKyAgICBmb3IgKGludCBpID0gMDsgIWZvdW5kX2NvbmZsaWN0ICYmIGkgPCBmaWxlXy0+ZW51bV90eXBlX2NvdW50KCk7IGkrKykgeworICAgICAgaWYgKGZpbGVfLT5lbnVtX3R5cGUoaSktPm5hbWUoKSA9PSBjbGFzc25hbWVfKSB7CisgICAgICAgIGZvdW5kX2NvbmZsaWN0ID0gdHJ1ZTsKKyAgICAgIH0KKyAgICB9CisgIH0KKyAgaWYgKGZvdW5kX2NvbmZsaWN0KSB7CisgICAgZXJyb3ItPmFzc2lnbihmaWxlXy0+bmFtZSgpKTsKKyAgICBlcnJvci0+YXBwZW5kKAorICAgICAgIjogQ2Fubm90IGdlbmVyYXRlIEphdmEgb3V0cHV0IGJlY2F1c2UgdGhlIGZpbGUncyBvdXRlciBjbGFzcyBuYW1lLCBcIiIpOworICAgIGVycm9yLT5hcHBlbmQoY2xhc3NuYW1lXyk7CisgICAgZXJyb3ItPmFwcGVuZCgKKyAgICAgICJcIiwgbWF0Y2hlcyB0aGUgbmFtZSBvZiBvbmUgb2YgdGhlIHR5cGVzIGRlY2xhcmVkIGluc2lkZSBpdC4gICIKKyAgICAgICJQbGVhc2UgZWl0aGVyIHJlbmFtZSB0aGUgdHlwZSBvciB1c2UgdGhlIGphdmFfb3V0ZXJfY2xhc3NuYW1lICIKKyAgICAgICJvcHRpb24gdG8gc3BlY2lmeSBhIGRpZmZlcmVudCBvdXRlciBjbGFzcyBuYW1lIGZvciB0aGUgLnByb3RvIGZpbGUuIik7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIHJldHVybiB0cnVlOworfQorCit2b2lkIEZpbGVHZW5lcmF0b3I6OkdlbmVyYXRlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIC8vIFdlIGRvbid0IGltcG9ydCBhbnl0aGluZyBiZWNhdXNlIHdlIHJlZmVyIHRvIGFsbCBjbGFzc2VzIGJ5IHRoZWlyCisgIC8vIGZ1bGx5LXF1YWxpZmllZCBuYW1lcyBpbiB0aGUgZ2VuZXJhdGVkIHNvdXJjZS4KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIi8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhXG4iKTsKKyAgaWYgKCFqYXZhX3BhY2thZ2VfLmVtcHR5KCkpIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJcbiIKKyAgICAgICJwYWNrYWdlICRwYWNrYWdlJDtcbiIsCisgICAgICAicGFja2FnZSIsIGphdmFfcGFja2FnZV8pOworICB9CisKKyAgLy8gTm90ZTogY29uc3RhbnRzIChmcm9tIGVudW1zLCBlbWl0dGVkIGluIHRoZSBsb29wIGJlbG93KSBtYXkgaGF2ZSB0aGUgc2FtZSBuYW1lcyBhcyBjb25zdGFudHMKKyAgLy8gaW4gdGhlIG5lc3RlZCBjbGFzc2VzLiBUaGlzIGNhdXNlcyBKYXZhIHdhcm5pbmdzLCBidXQgaXMgbm90IGZhdGFsLCBzbyB3ZSBzdXBwcmVzcyB0aG9zZQorICAvLyB3YXJuaW5ncyBoZXJlIGluIHRoZSB0b3AtbW9zdCBjbGFzcyBkZWNsYXJhdGlvbi4KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIlxuIgorICAgICJAU3VwcHJlc3NXYXJuaW5ncyhcImhpZGluZ1wiKVxuIgorICAgICJwdWJsaWMgaW50ZXJmYWNlICRjbGFzc25hbWUkIHtcbiIsCisgICAgImNsYXNzbmFtZSIsIGNsYXNzbmFtZV8pOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIEV4dGVuc2lvbnMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPmV4dGVuc2lvbl9jb3VudCgpOyBpKyspIHsKKyAgICBFeHRlbnNpb25HZW5lcmF0b3IoZmlsZV8tPmV4dGVuc2lvbihpKSwgcGFyYW1zXykuR2VuZXJhdGUocHJpbnRlcik7CisgIH0KKworICAvLyBFbnVtcy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+ZW51bV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIEVudW1HZW5lcmF0b3IoZmlsZV8tPmVudW1fdHlwZShpKSwgcGFyYW1zXykuR2VuZXJhdGUocHJpbnRlcik7CisgIH0KKworICAvLyBNZXNzYWdlcy4KKyAgaWYgKCFwYXJhbXNfLmphdmFfbXVsdGlwbGVfZmlsZXMoZmlsZV8tPm5hbWUoKSkpIHsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5tZXNzYWdlX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgICBNZXNzYWdlR2VuZXJhdG9yKGZpbGVfLT5tZXNzYWdlX3R5cGUoaSksIHBhcmFtc18pLkdlbmVyYXRlKHByaW50ZXIpOworICAgIH0KKyAgfQorCisgIC8vIFN0YXRpYyB2YXJpYWJsZXMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICAvLyBUT0RPKGtlbnRvbik6ICBSZXVzZSBNZXNzYWdlR2VuZXJhdG9yIG9iamVjdHM/CisgICAgTWVzc2FnZUdlbmVyYXRvcihmaWxlXy0+bWVzc2FnZV90eXBlKGkpLCBwYXJhbXNfKS5HZW5lcmF0ZVN0YXRpY1ZhcmlhYmxlcyhwcmludGVyKTsKKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIn1cbiIpOworfQorCit0ZW1wbGF0ZTx0eXBlbmFtZSBHZW5lcmF0b3JDbGFzcywgdHlwZW5hbWUgRGVzY3JpcHRvckNsYXNzPgorc3RhdGljIHZvaWQgR2VuZXJhdGVTaWJsaW5nKGNvbnN0IHN0cmluZyYgcGFja2FnZV9kaXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBqYXZhX3BhY2thZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVzY3JpcHRvckNsYXNzKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdlbmVyYXRvckNvbnRleHQqIG91dHB1dF9kaXJlY3RvcnksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjdG9yPHN0cmluZz4qIGZpbGVfbGlzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBQYXJhbXMmIHBhcmFtcykgeworICBzdHJpbmcgZmlsZW5hbWUgPSBwYWNrYWdlX2RpciArIGRlc2NyaXB0b3ItPm5hbWUoKSArICIuamF2YSI7CisgIGZpbGVfbGlzdC0+cHVzaF9iYWNrKGZpbGVuYW1lKTsKKworICBzY29wZWRfcHRyPGlvOjpaZXJvQ29weU91dHB1dFN0cmVhbT4gb3V0cHV0KAorICAgIG91dHB1dF9kaXJlY3RvcnktPk9wZW4oZmlsZW5hbWUpKTsKKyAgaW86OlByaW50ZXIgcHJpbnRlcihvdXRwdXQuZ2V0KCksICckJyk7CisKKyAgcHJpbnRlci5QcmludCgKKyAgICAiLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCFcbiIpOworICBpZiAoIWphdmFfcGFja2FnZS5lbXB0eSgpKSB7CisgICAgcHJpbnRlci5QcmludCgKKyAgICAgICJcbiIKKyAgICAgICJwYWNrYWdlICRwYWNrYWdlJDtcbiIsCisgICAgICAicGFja2FnZSIsIGphdmFfcGFja2FnZSk7CisgIH0KKworICBHZW5lcmF0b3JDbGFzcyhkZXNjcmlwdG9yLCBwYXJhbXMpLkdlbmVyYXRlKCZwcmludGVyKTsKK30KKwordm9pZCBGaWxlR2VuZXJhdG9yOjpHZW5lcmF0ZVNpYmxpbmdzKGNvbnN0IHN0cmluZyYgcGFja2FnZV9kaXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2VuZXJhdG9yQ29udGV4dCogb3V0cHV0X2RpcmVjdG9yeSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWN0b3I8c3RyaW5nPiogZmlsZV9saXN0KSB7CisgIGlmIChwYXJhbXNfLmphdmFfbXVsdGlwbGVfZmlsZXMoZmlsZV8tPm5hbWUoKSkpIHsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5tZXNzYWdlX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgICBHZW5lcmF0ZVNpYmxpbmc8TWVzc2FnZUdlbmVyYXRvcj4ocGFja2FnZV9kaXIsIGphdmFfcGFja2FnZV8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZV8tPm1lc3NhZ2VfdHlwZShpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXRfZGlyZWN0b3J5LCBmaWxlX2xpc3QsIHBhcmFtc18pOworICAgIH0KKworICAgIGlmIChwYXJhbXNfLmphdmFfZW51bV9zdHlsZSgpKSB7CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5lbnVtX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgICAgIEdlbmVyYXRlU2libGluZzxFbnVtR2VuZXJhdG9yPihwYWNrYWdlX2RpciwgamF2YV9wYWNrYWdlXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVfLT5lbnVtX3R5cGUoaSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXRfZGlyZWN0b3J5LCBmaWxlX2xpc3QsIHBhcmFtc18pOworICAgICAgfQorICAgIH0KKyAgfQorfQorCit9ICAvLyBuYW1lc3BhY2UgamF2YW5hbm8KK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2ZpbGUuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZmlsZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIxN2VhZmUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2ZpbGUuaApAQCAtMCwwICsxLDk0IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL3Byb3RvYnVmLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQU5BTk9fRklMRV9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFOQU5PX0ZJTEVfSF9fCisKKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8dmVjdG9yPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fcGFyYW1zLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKyAgY2xhc3MgRmlsZURlc2NyaXB0b3I7ICAgICAgICAvLyBkZXNjcmlwdG9yLmgKKyAgbmFtZXNwYWNlIGlvIHsKKyAgICBjbGFzcyBQcmludGVyOyAgICAgICAgICAgICAvLyBwcmludGVyLmgKKyAgfQorICBuYW1lc3BhY2UgY29tcGlsZXIgeworICAgIGNsYXNzIEdlbmVyYXRvckNvbnRleHQ7ICAgICAvLyBjb2RlX2dlbmVyYXRvci5oCisgIH0KK30KKworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YW5hbm8geworCitjbGFzcyBGaWxlR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IEZpbGVHZW5lcmF0b3IoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUsIGNvbnN0IFBhcmFtcyYgcGFyYW1zKTsKKyAgfkZpbGVHZW5lcmF0b3IoKTsKKworICAvLyBDaGVja3MgZm9yIHByb2JsZW1zIHRoYXQgd291bGQgb3RoZXJ3aXNlIGxlYWQgdG8gY3J5cHRpYyBjb21waWxlIGVycm9ycy4KKyAgLy8gUmV0dXJucyB0cnVlIGlmIHRoZXJlIGFyZSBubyBwcm9ibGVtcywgb3Igd3JpdGVzIGFuIGVycm9yIGRlc2NyaXB0aW9uIHRvCisgIC8vIHRoZSBnaXZlbiBzdHJpbmcgYW5kIHJldHVybnMgZmFsc2Ugb3RoZXJ3aXNlLgorICBib29sIFZhbGlkYXRlKHN0cmluZyogZXJyb3IpOworCisgIHZvaWQgR2VuZXJhdGUoaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgIC8vIElmIHdlIGFyZW4ndCBwdXR0aW5nIGV2ZXJ5dGhpbmcgaW50byBvbmUgZmlsZSwgdGhpcyB3aWxsIHdyaXRlIGFsbCB0aGUKKyAgLy8gZmlsZXMgb3RoZXIgdGhhbiB0aGUgb3V0ZXIgZmlsZSAoaS5lLiBvbmUgZm9yIGVhY2ggbWVzc2FnZSwgZW51bSwgYW5kCisgIC8vIHNlcnZpY2UgdHlwZSkuCisgIHZvaWQgR2VuZXJhdGVTaWJsaW5ncyhjb25zdCBzdHJpbmcmIHBhY2thZ2VfZGlyLAorICAgICAgICAgICAgICAgICAgICAgICAgR2VuZXJhdG9yQ29udGV4dCogb3V0cHV0X2RpcmVjdG9yeSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHZlY3RvcjxzdHJpbmc+KiBmaWxlX2xpc3QpOworCisgIGNvbnN0IHN0cmluZyYgamF2YV9wYWNrYWdlKCkgeyByZXR1cm4gamF2YV9wYWNrYWdlXzsgfQorICBjb25zdCBzdHJpbmcmIGNsYXNzbmFtZSgpICAgIHsgcmV0dXJuIGNsYXNzbmFtZV87ICAgIH0KKworIHByaXZhdGU6CisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlXzsKKyAgY29uc3QgUGFyYW1zJiBwYXJhbXNfOworICBzdHJpbmcgamF2YV9wYWNrYWdlXzsKKyAgc3RyaW5nIGNsYXNzbmFtZV87CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEZpbGVHZW5lcmF0b3IpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGphdmFuYW5vCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBTkFOT19GSUxFX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19nZW5lcmF0b3IuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2dlbmVyYXRvci5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMzNlYmExCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19nZW5lcmF0b3IuY2MKQEAgLTAsMCArMSwyMzIgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvcHJvdG9idWYvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX3BhcmFtcy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19nZW5lcmF0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZmlsZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhbmFubyB7CisKK25hbWVzcGFjZSB7CisKK3N0cmluZyBUcmltU3RyaW5nKGNvbnN0IHN0cmluZyYgcykgeworICBzdHJpbmc6OnNpemVfdHlwZSBzdGFydCA9IHMuZmluZF9maXJzdF9ub3Rfb2YoIiBcblxyXHQiKTsKKyAgaWYgKHN0YXJ0ID09IHN0cmluZzo6bnBvcykgeworICAgIHJldHVybiAiIjsKKyAgfQorICBzdHJpbmc6OnNpemVfdHlwZSBlbmQgPSBzLmZpbmRfbGFzdF9ub3Rfb2YoIiBcblxyXHQiKSArIDE7CisgIHJldHVybiBzLnN1YnN0cihzdGFydCwgZW5kIC0gc3RhcnQpOworfQorCit9IC8vIG5hbWVzcGFjZQorCit2b2lkIFVwZGF0ZVBhcmFtc1JlY3Vyc2l2ZWx5KFBhcmFtcyYgcGFyYW1zLAorICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKSB7CisgIC8vIEFkZCBhbnkgcGFyYW1ldGVycyBmb3IgdGhpcyBmaWxlCisgIGlmIChmaWxlLT5vcHRpb25zKCkuaGFzX2phdmFfb3V0ZXJfY2xhc3NuYW1lKCkpIHsKKyAgICBwYXJhbXMuc2V0X2phdmFfb3V0ZXJfY2xhc3NuYW1lKAorICAgICAgZmlsZS0+bmFtZSgpLCBmaWxlLT5vcHRpb25zKCkuamF2YV9vdXRlcl9jbGFzc25hbWUoKSk7CisgIH0KKyAgaWYgKGZpbGUtPm9wdGlvbnMoKS5oYXNfamF2YV9wYWNrYWdlKCkpIHsKKyAgICBzdHJpbmcgcmVzdWx0ID0gZmlsZS0+b3B0aW9ucygpLmphdmFfcGFja2FnZSgpOworICAgIGlmICghZmlsZS0+b3B0aW9ucygpLmphdmFuYW5vX3VzZV9kZXByZWNhdGVkX3BhY2thZ2UoKSkgeworICAgICAgaWYgKCFyZXN1bHQuZW1wdHkoKSkgeworICAgICAgICByZXN1bHQgKz0gIi4iOworICAgICAgfQorICAgICAgcmVzdWx0ICs9ICJuYW5vIjsKKyAgICB9CisgICAgcGFyYW1zLnNldF9qYXZhX3BhY2thZ2UoCisgICAgICBmaWxlLT5uYW1lKCksIHJlc3VsdCk7CisgIH0KKyAgaWYgKGZpbGUtPm9wdGlvbnMoKS5oYXNfamF2YV9tdWx0aXBsZV9maWxlcygpKSB7CisgICAgcGFyYW1zLnNldF9qYXZhX211bHRpcGxlX2ZpbGVzKAorICAgICAgZmlsZS0+bmFtZSgpLCBmaWxlLT5vcHRpb25zKCkuamF2YV9tdWx0aXBsZV9maWxlcygpKTsKKyAgfQorCisgIC8vIExvb3AgdGhyb3VnaCBhbGwgZGVwZW5kZW50IGZpbGVzIHJlY3Vyc2l2ZWx5CisgIC8vIGFkZGluZyBkZXAKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlLT5kZXBlbmRlbmN5X2NvdW50KCk7IGkrKykgeworICAgIFVwZGF0ZVBhcmFtc1JlY3Vyc2l2ZWx5KHBhcmFtcywgZmlsZS0+ZGVwZW5kZW5jeShpKSk7CisgIH0KK30KKworSmF2YU5hbm9HZW5lcmF0b3I6OkphdmFOYW5vR2VuZXJhdG9yKCkge30KK0phdmFOYW5vR2VuZXJhdG9yOjp+SmF2YU5hbm9HZW5lcmF0b3IoKSB7fQorCitib29sIEphdmFOYW5vR2VuZXJhdG9yOjpHZW5lcmF0ZShjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBwYXJhbWV0ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdlbmVyYXRvckNvbnRleHQqIG91dHB1dF9kaXJlY3RvcnksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyogZXJyb3IpIGNvbnN0IHsKKyAgdmVjdG9yPHBhaXI8c3RyaW5nLCBzdHJpbmc+ID4gb3B0aW9uczsKKworICBQYXJzZUdlbmVyYXRvclBhcmFtZXRlcihwYXJhbWV0ZXIsICZvcHRpb25zKTsKKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAvLyBwYXJzZSBnZW5lcmF0b3Igb3B0aW9ucworCisgIC8vIE5hbWUgYSBmaWxlIHdoZXJlIHdlIHdpbGwgd3JpdGUgYSBsaXN0IG9mIGdlbmVyYXRlZCBmaWxlIG5hbWVzLCBvbmUKKyAgLy8gcGVyIGxpbmUuCisgIHN0cmluZyBvdXRwdXRfbGlzdF9maWxlOworICBQYXJhbXMgcGFyYW1zKGZpbGUtPm5hbWUoKSk7CisKKyAgLy8gVXBkYXRlIHBlciBmaWxlIHBhcmFtcworICBVcGRhdGVQYXJhbXNSZWN1cnNpdmVseShwYXJhbXMsIGZpbGUpOworCisgIC8vIFJlcGxhY2UgYW55IGV4aXN0aW5nIG9wdGlvbnMgd2l0aCBvbmVzIGZyb20gY29tbWFuZCBsaW5lCisgIGZvciAoaW50IGkgPSAwOyBpIDwgb3B0aW9ucy5zaXplKCk7IGkrKykgeworICAgIHN0cmluZyBvcHRpb25fbmFtZSA9IFRyaW1TdHJpbmcob3B0aW9uc1tpXS5maXJzdCk7CisgICAgc3RyaW5nIG9wdGlvbl92YWx1ZSA9IFRyaW1TdHJpbmcob3B0aW9uc1tpXS5zZWNvbmQpOworICAgIGlmIChvcHRpb25fbmFtZSA9PSAib3V0cHV0X2xpc3RfZmlsZSIpIHsKKyAgICAgIG91dHB1dF9saXN0X2ZpbGUgPSBvcHRpb25fdmFsdWU7CisgICAgfSBlbHNlIGlmIChvcHRpb25fbmFtZSA9PSAiamF2YV9wYWNrYWdlIikgeworICAgICAgICB2ZWN0b3I8c3RyaW5nPiBwYXJ0czsKKyAgICAgICAgU3BsaXRTdHJpbmdVc2luZyhvcHRpb25fdmFsdWUsICJ8IiwgJnBhcnRzKTsKKyAgICAgICAgaWYgKHBhcnRzLnNpemUoKSAhPSAyKSB7CisgICAgICAgICAgKmVycm9yID0gIkJhZCBqYXZhX3BhY2thZ2UsIGV4cGVjdGluZyBmaWxlbmFtZXxQYWNrYWdlTmFtZSBmb3VuZCAnIgorICAgICAgICAgICAgKyBvcHRpb25fdmFsdWUgKyAiJyI7CisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICAgIHBhcmFtcy5zZXRfamF2YV9wYWNrYWdlKHBhcnRzWzBdLCBwYXJ0c1sxXSk7CisgICAgfSBlbHNlIGlmIChvcHRpb25fbmFtZSA9PSAiamF2YV9vdXRlcl9jbGFzc25hbWUiKSB7CisgICAgICAgIHZlY3RvcjxzdHJpbmc+IHBhcnRzOworICAgICAgICBTcGxpdFN0cmluZ1VzaW5nKG9wdGlvbl92YWx1ZSwgInwiLCAmcGFydHMpOworICAgICAgICBpZiAocGFydHMuc2l6ZSgpICE9IDIpIHsKKyAgICAgICAgICAqZXJyb3IgPSAiQmFkIGphdmFfb3V0ZXJfY2xhc3NuYW1lLCAiCisgICAgICAgICAgICAgICAgICAgImV4cGVjdGluZyBmaWxlbmFtZXxDbGFzc05hbWUgZm91bmQgJyIKKyAgICAgICAgICAgICAgICAgICArIG9wdGlvbl92YWx1ZSArICInIjsKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgcGFyYW1zLnNldF9qYXZhX291dGVyX2NsYXNzbmFtZShwYXJ0c1swXSwgcGFydHNbMV0pOworICAgIH0gZWxzZSBpZiAob3B0aW9uX25hbWUgPT0gInN0b3JlX3Vua25vd25fZmllbGRzIikgeworICAgICAgcGFyYW1zLnNldF9zdG9yZV91bmtub3duX2ZpZWxkcyhvcHRpb25fdmFsdWUgPT0gInRydWUiKTsKKyAgICB9IGVsc2UgaWYgKG9wdGlvbl9uYW1lID09ICJqYXZhX211bHRpcGxlX2ZpbGVzIikgeworICAgICAgcGFyYW1zLnNldF9vdmVycmlkZV9qYXZhX211bHRpcGxlX2ZpbGVzKG9wdGlvbl92YWx1ZSA9PSAidHJ1ZSIpOworICAgIH0gZWxzZSBpZiAob3B0aW9uX25hbWUgPT0gImphdmFfbmFub19nZW5lcmF0ZV9oYXMiKSB7CisgICAgICBwYXJhbXMuc2V0X2dlbmVyYXRlX2hhcyhvcHRpb25fdmFsdWUgPT0gInRydWUiKTsKKyAgICB9IGVsc2UgaWYgKG9wdGlvbl9uYW1lID09ICJlbnVtX3N0eWxlIikgeworICAgICAgcGFyYW1zLnNldF9qYXZhX2VudW1fc3R5bGUob3B0aW9uX3ZhbHVlID09ICJqYXZhIik7CisgICAgfSBlbHNlIGlmIChvcHRpb25fbmFtZSA9PSAib3B0aW9uYWxfZmllbGRfc3R5bGUiKSB7CisgICAgICBwYXJhbXMuc2V0X29wdGlvbmFsX2ZpZWxkX2FjY2Vzc29ycyhvcHRpb25fdmFsdWUgPT0gImFjY2Vzc29ycyIpOworICAgICAgcGFyYW1zLnNldF91c2VfcmVmZXJlbmNlX3R5cGVzX2Zvcl9wcmltaXRpdmVzKG9wdGlvbl92YWx1ZSA9PSAicmVmdHlwZXMiCisgICAgICAgICAgfHwgb3B0aW9uX3ZhbHVlID09ICJyZWZ0eXBlc19jb21wYXRfbW9kZSIpOworICAgICAgcGFyYW1zLnNldF9yZWZ0eXBlc19wcmltaXRpdmVfZW51bXMoCisgICAgICAgICAgb3B0aW9uX3ZhbHVlID09ICJyZWZ0eXBlc19jb21wYXRfbW9kZSIpOworICAgICAgaWYgKG9wdGlvbl92YWx1ZSA9PSAicmVmdHlwZXNfY29tcGF0X21vZGUiKSB7CisgICAgICAgIHBhcmFtcy5zZXRfZ2VuZXJhdGVfY2xlYXIoZmFsc2UpOworICAgICAgfQorICAgIH0gZWxzZSBpZiAob3B0aW9uX25hbWUgPT0gImdlbmVyYXRlX2VxdWFscyIpIHsKKyAgICAgIHBhcmFtcy5zZXRfZ2VuZXJhdGVfZXF1YWxzKG9wdGlvbl92YWx1ZSA9PSAidHJ1ZSIpOworICAgIH0gZWxzZSBpZiAob3B0aW9uX25hbWUgPT0gImlnbm9yZV9zZXJ2aWNlcyIpIHsKKyAgICAgIHBhcmFtcy5zZXRfaWdub3JlX3NlcnZpY2VzKG9wdGlvbl92YWx1ZSA9PSAidHJ1ZSIpOworICAgIH0gZWxzZSBpZiAob3B0aW9uX25hbWUgPT0gInBhcmNlbGFibGVfbWVzc2FnZXMiKSB7CisgICAgICBwYXJhbXMuc2V0X3BhcmNlbGFibGVfbWVzc2FnZXMob3B0aW9uX3ZhbHVlID09ICJ0cnVlIik7CisgICAgfSBlbHNlIGlmIChvcHRpb25fbmFtZSA9PSAiZ2VuZXJhdGVfY2xvbmUiKSB7CisgICAgICBwYXJhbXMuc2V0X2dlbmVyYXRlX2Nsb25lKG9wdGlvbl92YWx1ZSA9PSAidHJ1ZSIpOworICAgIH0gZWxzZSBpZiAob3B0aW9uX25hbWUgPT0gImdlbmVyYXRlX2ludGRlZnMiKSB7CisgICAgICBwYXJhbXMuc2V0X2dlbmVyYXRlX2ludGRlZnMob3B0aW9uX3ZhbHVlID09ICJ0cnVlIik7CisgICAgfSBlbHNlIGlmIChvcHRpb25fbmFtZSA9PSAiZ2VuZXJhdGVfY2xlYXIiKSB7CisgICAgICBwYXJhbXMuc2V0X2dlbmVyYXRlX2NsZWFyKG9wdGlvbl92YWx1ZSA9PSAidHJ1ZSIpOworICAgIH0gZWxzZSB7CisgICAgICAqZXJyb3IgPSAiSWdub3JlIHVua25vd24gamF2YW5hbm8gZ2VuZXJhdG9yIG9wdGlvbjogIiArIG9wdGlvbl9uYW1lOworICAgIH0KKyAgfQorCisgIC8vIENoZWNrIGlsbGVnYWwgcGFyYW1ldGVyIGNvbWJpbmF0aW9ucworICAvLyBOb3RlOiB0aGUgZW51bS1saWtlIG9wdGlvbmFsX2ZpZWxkX3N0eWxlIGdlbmVyYXRvciBwYXJhbSBlbnN1cmVzCisgIC8vIHRoYXQgd2UgY2FuIG5ldmVyIGhhdmUgaWxsZWdhbCBjb21iaW5hdGlvbnMgb2YgZmllbGQgc3R5bGVzCisgIC8vIChlLmcuIHJlZnR5cGVzIGFuZCBhY2Nlc3NvcnMgY2FuJ3QgYmUgb24gYXQgdGhlIHNhbWUgdGltZSkuCisgIGlmIChwYXJhbXMuZ2VuZXJhdGVfaGFzKCkKKyAgICAgICYmIChwYXJhbXMub3B0aW9uYWxfZmllbGRfYWNjZXNzb3JzKCkKKyAgICAgICAgICB8fCBwYXJhbXMudXNlX3JlZmVyZW5jZV90eXBlc19mb3JfcHJpbWl0aXZlcygpKSkgeworICAgIGVycm9yLT5hc3NpZ24oImphdmFfbmFub19nZW5lcmF0ZV9oYXM9dHJ1ZSBjYW5ub3QgYmUgdXNlZCBpbiBjb25qdW5jdGlvbiIKKyAgICAgICAgIiB3aXRoIG9wdGlvbmFsX2ZpZWxkX3N0eWxlPWFjY2Vzc29ycyBvciBvcHRpb25hbF9maWVsZF9zdHlsZT1yZWZ0eXBlcyIpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgRmlsZUdlbmVyYXRvciBmaWxlX2dlbmVyYXRvcihmaWxlLCBwYXJhbXMpOworICBpZiAoIWZpbGVfZ2VuZXJhdG9yLlZhbGlkYXRlKGVycm9yKSkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIHN0cmluZyBwYWNrYWdlX2RpciA9CisgICAgU3RyaW5nUmVwbGFjZShmaWxlX2dlbmVyYXRvci5qYXZhX3BhY2thZ2UoKSwgIi4iLCAiLyIsIHRydWUpOworICBpZiAoIXBhY2thZ2VfZGlyLmVtcHR5KCkpIHBhY2thZ2VfZGlyICs9ICIvIjsKKworICB2ZWN0b3I8c3RyaW5nPiBhbGxfZmlsZXM7CisKKyAgaWYgKElzT3V0ZXJDbGFzc05lZWRlZChwYXJhbXMsIGZpbGUpKSB7CisgICAgc3RyaW5nIGphdmFfZmlsZW5hbWUgPSBwYWNrYWdlX2RpcjsKKyAgICBqYXZhX2ZpbGVuYW1lICs9IGZpbGVfZ2VuZXJhdG9yLmNsYXNzbmFtZSgpOworICAgIGphdmFfZmlsZW5hbWUgKz0gIi5qYXZhIjsKKyAgICBhbGxfZmlsZXMucHVzaF9iYWNrKGphdmFfZmlsZW5hbWUpOworCisgICAgLy8gR2VuZXJhdGUgbWFpbiBqYXZhIGZpbGUuCisgICAgc2NvcGVkX3B0cjxpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0+IG91dHB1dCgKKyAgICAgIG91dHB1dF9kaXJlY3RvcnktPk9wZW4oamF2YV9maWxlbmFtZSkpOworICAgIGlvOjpQcmludGVyIHByaW50ZXIob3V0cHV0LmdldCgpLCAnJCcpOworICAgIGZpbGVfZ2VuZXJhdG9yLkdlbmVyYXRlKCZwcmludGVyKTsKKyAgfQorCisgIC8vIEdlbmVyYXRlIHNpYmxpbmcgZmlsZXMuCisgIGZpbGVfZ2VuZXJhdG9yLkdlbmVyYXRlU2libGluZ3MocGFja2FnZV9kaXIsIG91dHB1dF9kaXJlY3RvcnksICZhbGxfZmlsZXMpOworCisgIC8vIEdlbmVyYXRlIG91dHB1dCBsaXN0IGlmIHJlcXVlc3RlZC4KKyAgaWYgKCFvdXRwdXRfbGlzdF9maWxlLmVtcHR5KCkpIHsKKyAgICAvLyBHZW5lcmF0ZSBvdXRwdXQgbGlzdC4gIFRoaXMgaXMganVzdCBhIHNpbXBsZSB0ZXh0IGZpbGUgcGxhY2VkIGluIGEKKyAgICAvLyBkZXRlcm1pbmlzdGljIGxvY2F0aW9uIHdoaWNoIGxpc3RzIHRoZSAuamF2YSBmaWxlcyBiZWluZyBnZW5lcmF0ZWQuCisgICAgc2NvcGVkX3B0cjxpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0+IHNyY2xpc3RfcmF3X291dHB1dCgKKyAgICAgIG91dHB1dF9kaXJlY3RvcnktPk9wZW4ob3V0cHV0X2xpc3RfZmlsZSkpOworICAgIGlvOjpQcmludGVyIHNyY2xpc3RfcHJpbnRlcihzcmNsaXN0X3Jhd19vdXRwdXQuZ2V0KCksICckJyk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhbGxfZmlsZXMuc2l6ZSgpOyBpKyspIHsKKyAgICAgIHNyY2xpc3RfcHJpbnRlci5QcmludCgiJGZpbGVuYW1lJFxuIiwgImZpbGVuYW1lIiwgYWxsX2ZpbGVzW2ldKTsKKyAgICB9CisgIH0KKworICByZXR1cm4gdHJ1ZTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGphdmEKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2dlbmVyYXRvci5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19nZW5lcmF0b3IuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42ZjlmN2YyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19nZW5lcmF0b3IuaApAQCAtMCwwICsxLDcyIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL3Byb3RvYnVmLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBHZW5lcmF0ZXMgSmF2YSBuYW5vIGNvZGUgZm9yIGEgZ2l2ZW4gLnByb3RvIGZpbGUuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFOQU5PX05BTk9fR0VORVJBVE9SX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQU5BTk9fTkFOT19HRU5FUkFUT1JfSF9fCisKKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NvZGVfZ2VuZXJhdG9yLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YW5hbm8geworCisvLyBDb2RlR2VuZXJhdG9yIGltcGxlbWVudGF0aW9uIHdoaWNoIGdlbmVyYXRlcyBKYXZhIG5hbm8gY29kZS4gIElmIHlvdSBjcmVhdGUgeW91cgorLy8gb3duIHByb3RvY29sIGNvbXBpbGVyIGJpbmFyeSBhbmQgeW91IHdhbnQgaXQgdG8gc3VwcG9ydCBKYXZhIG91dHB1dCBmb3IgdGhlCisvLyBuYW5vIHJ1bnRpbWUsIHlvdSBjYW4gZG8gc28gYnkgcmVnaXN0ZXJpbmcgYW4gaW5zdGFuY2Ugb2YgdGhpcyBDb2RlR2VuZXJhdG9yIHdpdGgKKy8vIHRoZSBDb21tYW5kTGluZUludGVyZmFjZSBpbiB5b3VyIG1haW4oKSBmdW5jdGlvbi4KK2NsYXNzIExJQlBST1RPQ19FWFBPUlQgSmF2YU5hbm9HZW5lcmF0b3IgOiBwdWJsaWMgQ29kZUdlbmVyYXRvciB7CisgcHVibGljOgorICBKYXZhTmFub0dlbmVyYXRvcigpOworICB+SmF2YU5hbm9HZW5lcmF0b3IoKTsKKworICAvLyBpbXBsZW1lbnRzIENvZGVHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICBib29sIEdlbmVyYXRlKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlLAorICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgcGFyYW1ldGVyLAorICAgICAgICAgICAgICAgIEdlbmVyYXRvckNvbnRleHQqIG91dHB1dF9kaXJlY3RvcnksCisgICAgICAgICAgICAgICAgc3RyaW5nKiBlcnJvcikgY29uc3Q7CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoSmF2YU5hbm9HZW5lcmF0b3IpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGphdmFuYW5vCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBTkFOT19OQU5PX0dFTkVSQVRPUl9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9faGVscGVycy5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9faGVscGVycy5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NDY1NjU1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19oZWxwZXJzLmNjCkBAIC0wLDAgKzEsNTkzIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL3Byb3RvYnVmLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2luY2x1ZGUgPGxpbWl0cz4KKyNpbmNsdWRlIDx2ZWN0b3I+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9faGVscGVycy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19wYXJhbXMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9oYXNoLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3Vic3RpdHV0ZS5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmFuYW5vIHsKKworY29uc3QgY2hhciBrVGhpY2tTZXBhcmF0b3JbXSA9CisgICIvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4iOworY29uc3QgY2hhciBrVGhpblNlcGFyYXRvcltdID0KKyAgIi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiI7CisKK2NsYXNzIFJlbmFtZUtleXdvcmRzIHsKKyBwcml2YXRlOgorICBoYXNoX3NldDxzdHJpbmc+IGphdmFfa2V5d29yZHNfc2V0XzsKKworIHB1YmxpYzoKKyAgUmVuYW1lS2V5d29yZHMoKSB7CisgICAgc3RhdGljIGNvbnN0IGNoYXIqIGtKYXZhS2V5d29yZHNMaXN0W10gPSB7CisgICAgICAvLyBSZXNlcnZlZCBKYXZhIEtleXdvcmRzCisgICAgICAiYWJzdHJhY3QiLCAiYXNzZXJ0IiwgImJvb2xlYW4iLCAiYnJlYWsiLCAiYnl0ZSIsICJjYXNlIiwgImNhdGNoIiwKKyAgICAgICJjaGFyIiwgImNsYXNzIiwgImNvbnN0IiwgImNvbnRpbnVlIiwgImRlZmF1bHQiLCAiZG8iLCAiZG91YmxlIiwgImVsc2UiLAorICAgICAgImVudW0iLCAiZXh0ZW5kcyIsICJmaW5hbCIsICJmaW5hbGx5IiwgImZsb2F0IiwgImZvciIsICJnb3RvIiwgImlmIiwKKyAgICAgICJpbXBsZW1lbnRzIiwgImltcG9ydCIsICJpbnN0YW5jZW9mIiwgImludCIsICJpbnRlcmZhY2UiLCAibG9uZyIsCisgICAgICAibmF0aXZlIiwgIm5ldyIsICJwYWNrYWdlIiwgInByaXZhdGUiLCAicHJvdGVjdGVkIiwgInB1YmxpYyIsICJyZXR1cm4iLAorICAgICAgInNob3J0IiwgInN0YXRpYyIsICJzdHJpY3RmcCIsICJzdXBlciIsICJzd2l0Y2giLCAic3luY2hyb25pemVkIiwKKyAgICAgICJ0aGlzIiwgInRocm93IiwgInRocm93cyIsICJ0cmFuc2llbnQiLCAidHJ5IiwgInZvaWQiLCAidm9sYXRpbGUiLCAid2hpbGUiLAorCisgICAgICAvLyBSZXNlcnZlZCBLZXl3b3JkcyBmb3IgTGl0ZXJhbHMKKyAgICAgICJmYWxzZSIsICJudWxsIiwgInRydWUiCisgICAgfTsKKworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgR09PR0xFX0FSUkFZU0laRShrSmF2YUtleXdvcmRzTGlzdCk7IGkrKykgeworICAgICAgamF2YV9rZXl3b3Jkc19zZXRfLmluc2VydChrSmF2YUtleXdvcmRzTGlzdFtpXSk7CisgICAgfQorICB9CisKKyAgLy8gVXNlZCB0byByZW5hbWUgdGhlIGEgZmllbGQgbmFtZSBpZiBpdCdzIGEgamF2YSBrZXl3b3JkLiAgU3BlY2lmaWNhbGx5CisgIC8vIHRoaXMgaXMgdXNlZCB0byByZW5hbWUgdGhlIFsibmFtZSJdIG9yIFsiY2FwaXRhbGl6ZWRfbmFtZSJdIGZpZWxkIHBhcmFtcy4KKyAgLy8gKGh0dHA6Ly9kb2NzLm9yYWNsZS5jb20vamF2YXNlL3R1dG9yaWFsL2phdmEvbnV0c2FuZGJvbHRzL19rZXl3b3Jkcy5odG1sKQorICBzdHJpbmcgUmVuYW1lSmF2YUtleXdvcmRzSW1wbChjb25zdCBzdHJpbmcmIGlucHV0KSB7CisgICAgc3RyaW5nIHJlc3VsdCA9IGlucHV0OworCisgICAgaWYgKGphdmFfa2V5d29yZHNfc2V0Xy5maW5kKHJlc3VsdCkgIT0gamF2YV9rZXl3b3Jkc19zZXRfLmVuZCgpKSB7CisgICAgICByZXN1bHQgKz0gIl8iOworICAgIH0KKworICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworfTsKKworc3RhdGljIFJlbmFtZUtleXdvcmRzIHNSZW5hbWVLZXl3b3JkczsKKworbmFtZXNwYWNlIHsKKworY29uc3QgY2hhcioga0RlZmF1bHRQYWNrYWdlID0gIiI7CisKK2NvbnN0IHN0cmluZyYgRmllbGROYW1lKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgLy8gR3JvdXBzIGFyZSBoYWNreTogIFRoZSBuYW1lIG9mIHRoZSBmaWVsZCBpcyBqdXN0IHRoZSBsb3dlci1jYXNlZCBuYW1lCisgIC8vIG9mIHRoZSBncm91cCB0eXBlLiAgSW4gSmF2YSwgdGhvdWdoLCB3ZSB3b3VsZCBsaWtlIHRvIHJldGFpbiB0aGUgb3JpZ2luYWwKKyAgLy8gY2FwaXRhbGl6YXRpb24gb2YgdGhlIHR5cGUgbmFtZS4KKyAgaWYgKGZpZWxkLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQKSB7CisgICAgcmV0dXJuIGZpZWxkLT5tZXNzYWdlX3R5cGUoKS0+bmFtZSgpOworICB9IGVsc2UgeworICAgIHJldHVybiBmaWVsZC0+bmFtZSgpOworICB9Cit9CisKK3N0cmluZyBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlSW1wbChjb25zdCBzdHJpbmcmIGlucHV0LCBib29sIGNhcF9uZXh0X2xldHRlcikgeworICBzdHJpbmcgcmVzdWx0OworICAvLyBOb3RlOiAgSSBkaXN0cnVzdCBjdHlwZS5oIGR1ZSB0byBsb2NhbGVzLgorICBmb3IgKGludCBpID0gMDsgaSA8IGlucHV0LnNpemUoKTsgaSsrKSB7CisgICAgaWYgKCdhJyA8PSBpbnB1dFtpXSAmJiBpbnB1dFtpXSA8PSAneicpIHsKKyAgICAgIGlmIChjYXBfbmV4dF9sZXR0ZXIpIHsKKyAgICAgICAgcmVzdWx0ICs9IGlucHV0W2ldICsgKCdBJyAtICdhJyk7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXN1bHQgKz0gaW5wdXRbaV07CisgICAgICB9CisgICAgICBjYXBfbmV4dF9sZXR0ZXIgPSBmYWxzZTsKKyAgICB9IGVsc2UgaWYgKCdBJyA8PSBpbnB1dFtpXSAmJiBpbnB1dFtpXSA8PSAnWicpIHsKKyAgICAgIGlmIChpID09IDAgJiYgIWNhcF9uZXh0X2xldHRlcikgeworICAgICAgICAvLyBGb3JjZSBmaXJzdCBsZXR0ZXIgdG8gbG93ZXItY2FzZSB1bmxlc3MgZXhwbGljaXRseSB0b2xkIHRvCisgICAgICAgIC8vIGNhcGl0YWxpemUgaXQuCisgICAgICAgIHJlc3VsdCArPSBpbnB1dFtpXSArICgnYScgLSAnQScpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgLy8gQ2FwaXRhbCBsZXR0ZXJzIGFmdGVyIHRoZSBmaXJzdCBhcmUgbGVmdCBhcy1pcy4KKyAgICAgICAgcmVzdWx0ICs9IGlucHV0W2ldOworICAgICAgfQorICAgICAgY2FwX25leHRfbGV0dGVyID0gZmFsc2U7CisgICAgfSBlbHNlIGlmICgnMCcgPD0gaW5wdXRbaV0gJiYgaW5wdXRbaV0gPD0gJzknKSB7CisgICAgICByZXN1bHQgKz0gaW5wdXRbaV07CisgICAgICBjYXBfbmV4dF9sZXR0ZXIgPSB0cnVlOworICAgIH0gZWxzZSB7CisgICAgICBjYXBfbmV4dF9sZXR0ZXIgPSB0cnVlOworICAgIH0KKyAgfQorICByZXR1cm4gcmVzdWx0OworfQorCit9ICAvLyBuYW1lc3BhY2UKKworc3RyaW5nIFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICByZXR1cm4gVW5kZXJzY29yZXNUb0NhbWVsQ2FzZUltcGwoRmllbGROYW1lKGZpZWxkKSwgZmFsc2UpOworfQorCitzdHJpbmcgVW5kZXJzY29yZXNUb0NhcGl0YWxpemVkQ2FtZWxDYXNlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgcmV0dXJuIFVuZGVyc2NvcmVzVG9DYW1lbENhc2VJbXBsKEZpZWxkTmFtZShmaWVsZCksIHRydWUpOworfQorCitzdHJpbmcgVW5kZXJzY29yZXNUb0NhbWVsQ2FzZShjb25zdCBNZXRob2REZXNjcmlwdG9yKiBtZXRob2QpIHsKKyAgcmV0dXJuIFVuZGVyc2NvcmVzVG9DYW1lbENhc2VJbXBsKG1ldGhvZC0+bmFtZSgpLCBmYWxzZSk7Cit9CisKK3N0cmluZyBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlKGNvbnN0IE9uZW9mRGVzY3JpcHRvciogb25lb2YpIHsKKyAgcmV0dXJuIFVuZGVyc2NvcmVzVG9DYW1lbENhc2VJbXBsKG9uZW9mLT5uYW1lKCksIGZhbHNlKTsKK30KKworc3RyaW5nIFVuZGVyc2NvcmVzVG9DYXBpdGFsaXplZENhbWVsQ2FzZShjb25zdCBPbmVvZkRlc2NyaXB0b3IqIG9uZW9mKSB7CisgIHJldHVybiBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlSW1wbChvbmVvZi0+bmFtZSgpLCB0cnVlKTsKK30KKworc3RyaW5nIFJlbmFtZUphdmFLZXl3b3Jkcyhjb25zdCBzdHJpbmcmIGlucHV0KSB7CisgIHJldHVybiBzUmVuYW1lS2V5d29yZHMuUmVuYW1lSmF2YUtleXdvcmRzSW1wbChpbnB1dCk7Cit9CisKK3N0cmluZyBTdHJpcFByb3RvKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUpIHsKKyAgaWYgKEhhc1N1ZmZpeFN0cmluZyhmaWxlbmFtZSwgIi5wcm90b2RldmVsIikpIHsKKyAgICByZXR1cm4gU3RyaXBTdWZmaXhTdHJpbmcoZmlsZW5hbWUsICIucHJvdG9kZXZlbCIpOworICB9IGVsc2UgeworICAgIHJldHVybiBTdHJpcFN1ZmZpeFN0cmluZyhmaWxlbmFtZSwgIi5wcm90byIpOworICB9Cit9CisKK3N0cmluZyBGaWxlQ2xhc3NOYW1lKGNvbnN0IFBhcmFtcyYgcGFyYW1zLCBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSkgeworICBpZiAocGFyYW1zLmhhc19qYXZhX291dGVyX2NsYXNzbmFtZShmaWxlLT5uYW1lKCkpKSB7CisgICAgcmV0dXJuIHBhcmFtcy5qYXZhX291dGVyX2NsYXNzbmFtZShmaWxlLT5uYW1lKCkpOworICB9IGVsc2UgeworICAgIC8vIFVzZSB0aGUgZmlsZW5hbWUgaXRzZWxmIHdpdGggdW5kZXJzY29yZXMgcmVtb3ZlZAorICAgIC8vIGFuZCBhIENhbWVsQ2FzZSBzdHlsZSBuYW1lLgorICAgIHN0cmluZyBiYXNlbmFtZTsKKyAgICBzdHJpbmc6OnNpemVfdHlwZSBsYXN0X3NsYXNoID0gZmlsZS0+bmFtZSgpLmZpbmRfbGFzdF9vZignLycpOworICAgIGlmIChsYXN0X3NsYXNoID09IHN0cmluZzo6bnBvcykgeworICAgICAgYmFzZW5hbWUgPSBmaWxlLT5uYW1lKCk7CisgICAgfSBlbHNlIHsKKyAgICAgIGJhc2VuYW1lID0gZmlsZS0+bmFtZSgpLnN1YnN0cihsYXN0X3NsYXNoICsgMSk7CisgICAgfQorICAgIHJldHVybiBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlSW1wbChTdHJpcFByb3RvKGJhc2VuYW1lKSwgdHJ1ZSk7CisgIH0KK30KKworc3RyaW5nIEZpbGVKYXZhUGFja2FnZShjb25zdCBQYXJhbXMmIHBhcmFtcywgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUpIHsKKyAgaWYgKHBhcmFtcy5oYXNfamF2YV9wYWNrYWdlKGZpbGUtPm5hbWUoKSkpIHsKKyAgICByZXR1cm4gcGFyYW1zLmphdmFfcGFja2FnZShmaWxlLT5uYW1lKCkpOworICB9IGVsc2UgeworICAgIHN0cmluZyByZXN1bHQgPSBrRGVmYXVsdFBhY2thZ2U7CisgICAgaWYgKCFmaWxlLT5wYWNrYWdlKCkuZW1wdHkoKSkgeworICAgICAgaWYgKCFyZXN1bHQuZW1wdHkoKSkgcmVzdWx0ICs9ICcuJzsKKyAgICAgIHJlc3VsdCArPSBmaWxlLT5wYWNrYWdlKCk7CisgICAgfQorCisgICAgaWYgKCFmaWxlLT5vcHRpb25zKCkuamF2YW5hbm9fdXNlX2RlcHJlY2F0ZWRfcGFja2FnZSgpKSB7CisgICAgICBpZiAoIXJlc3VsdC5lbXB0eSgpKSB7CisgICAgICAgIHJlc3VsdCArPSAiLiI7CisgICAgICB9CisgICAgICByZXN1bHQgKz0gIm5hbm8iOworICAgIH0KKworICAgIHJldHVybiByZXN1bHQ7CisgIH0KK30KKworYm9vbCBJc091dGVyQ2xhc3NOZWVkZWQoY29uc3QgUGFyYW1zJiBwYXJhbXMsIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKSB7CisgIC8vIElmIGphdmFfbXVsdGlwbGVfZmlsZXMgaXMgZmFsc2UsIHRoZSBvdXRlciBjbGFzcyBpcyBhbHdheXMgbmVlZGVkLgorICBpZiAoIXBhcmFtcy5qYXZhX211bHRpcGxlX2ZpbGVzKGZpbGUtPm5hbWUoKSkpIHsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIC8vIEZpbGUtc2NvcGUgZXh0ZW5zaW9ucyBuZWVkIHRoZSBvdXRlciBjbGFzcyBhcyB0aGUgc2NvcGUuCisgIGlmIChmaWxlLT5leHRlbnNpb25fY291bnQoKSAhPSAwKSB7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICAvLyBJZiBjb250YWluZXIgaW50ZXJmYWNlcyBhcmUgbm90IGdlbmVyYXRlZCwgZmlsZS1zY29wZSBlbnVtcyBuZWVkIHRoZQorICAvLyBvdXRlciBjbGFzcyBhcyB0aGUgc2NvcGUuCisgIGlmIChmaWxlLT5lbnVtX3R5cGVfY291bnQoKSAhPSAwICYmICFwYXJhbXMuamF2YV9lbnVtX3N0eWxlKCkpIHsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIHJldHVybiBmYWxzZTsKK30KKworc3RyaW5nIFRvSmF2YU5hbWUoY29uc3QgUGFyYW1zJiBwYXJhbXMsIGNvbnN0IHN0cmluZyYgbmFtZSwgYm9vbCBpc19jbGFzcywKKyAgICBjb25zdCBEZXNjcmlwdG9yKiBwYXJlbnQsIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKSB7CisgIHN0cmluZyByZXN1bHQ7CisgIGlmIChwYXJlbnQgIT0gTlVMTCkgeworICAgIHJlc3VsdC5hcHBlbmQoQ2xhc3NOYW1lKHBhcmFtcywgcGFyZW50KSk7CisgIH0gZWxzZSBpZiAoaXNfY2xhc3MgJiYgcGFyYW1zLmphdmFfbXVsdGlwbGVfZmlsZXMoZmlsZS0+bmFtZSgpKSkgeworICAgIHJlc3VsdC5hcHBlbmQoRmlsZUphdmFQYWNrYWdlKHBhcmFtcywgZmlsZSkpOworICB9IGVsc2UgeworICAgIHJlc3VsdC5hcHBlbmQoQ2xhc3NOYW1lKHBhcmFtcywgZmlsZSkpOworICB9CisgIGlmICghcmVzdWx0LmVtcHR5KCkpIHJlc3VsdC5hcHBlbmQoMSwgJy4nKTsKKyAgcmVzdWx0LmFwcGVuZChSZW5hbWVKYXZhS2V5d29yZHMobmFtZSkpOworICByZXR1cm4gcmVzdWx0OworfQorCitzdHJpbmcgQ2xhc3NOYW1lKGNvbnN0IFBhcmFtcyYgcGFyYW1zLCBjb25zdCBGaWxlRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBzdHJpbmcgcmVzdWx0ID0gRmlsZUphdmFQYWNrYWdlKHBhcmFtcywgZGVzY3JpcHRvcik7CisgIGlmICghcmVzdWx0LmVtcHR5KCkpIHJlc3VsdCArPSAnLic7CisgIHJlc3VsdCArPSBGaWxlQ2xhc3NOYW1lKHBhcmFtcywgZGVzY3JpcHRvcik7CisgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0cmluZyBDbGFzc05hbWUoY29uc3QgUGFyYW1zJiBwYXJhbXMsIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIGNvbnN0IERlc2NyaXB0b3IqIHBhcmVudCA9IGRlc2NyaXB0b3ItPmNvbnRhaW5pbmdfdHlwZSgpOworICAvLyBXaGVuIHVzaW5nIEphdmEgZW51bSBzdHlsZSwgYW4gZW51bSdzIGNsYXNzIG5hbWUgY29udGFpbnMgdGhlIGVudW0gbmFtZS4KKyAgLy8gVXNlIHRoZSBzdGFuZGFyZCBUb0phdmFOYW1lIHRyYW5zbGF0aW9uLgorICBpZiAocGFyYW1zLmphdmFfZW51bV9zdHlsZSgpKSB7CisgICAgcmV0dXJuIFRvSmF2YU5hbWUocGFyYW1zLCBkZXNjcmlwdG9yLT5uYW1lKCksIHRydWUsIHBhcmVudCwKKyAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdG9yLT5maWxlKCkpOworICB9CisgIC8vIE90aGVyd2lzZSB0aGUgZW51bSBtZW1iZXJzIGFyZSBhY2Nlc3NlZCBmcm9tIHRoZSBlbmNsb3NpbmcgY2xhc3MuCisgIGlmIChwYXJlbnQgIT0gTlVMTCkgeworICAgIHJldHVybiBDbGFzc05hbWUocGFyYW1zLCBwYXJlbnQpOworICB9IGVsc2UgeworICAgIHJldHVybiBDbGFzc05hbWUocGFyYW1zLCBkZXNjcmlwdG9yLT5maWxlKCkpOworICB9Cit9CisKK3N0cmluZyBGaWVsZENvbnN0YW50TmFtZShjb25zdCBGaWVsZERlc2NyaXB0b3IgKmZpZWxkKSB7CisgIHN0cmluZyBuYW1lID0gZmllbGQtPm5hbWUoKSArICJfRklFTERfTlVNQkVSIjsKKyAgVXBwZXJTdHJpbmcoJm5hbWUpOworICByZXR1cm4gbmFtZTsKK30KKworc3RyaW5nIEZpZWxkRGVmYXVsdENvbnN0YW50TmFtZShjb25zdCBGaWVsZERlc2NyaXB0b3IgKmZpZWxkKSB7CisgIHJldHVybiAiXyIgKyBSZW5hbWVKYXZhS2V5d29yZHMoVW5kZXJzY29yZXNUb0NhbWVsQ2FzZShmaWVsZCkpICsgIkRlZmF1bHQiOworfQorCit2b2lkIFByaW50RmllbGRDb21tZW50KGlvOjpQcmludGVyKiBwcmludGVyLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIC8vIFdlIGRvbid0IHdhbnQgdG8gcHJpbnQgZ3JvdXAgYm9kaWVzIHNvIHdlIGN1dCBvZmYgYWZ0ZXIgdGhlIGZpcnN0IGxpbmUKKyAgLy8gKHRoZSBzZWNvbmQgbGluZSBmb3IgZXh0ZW5zaW9ucykuCisgIHN0cmluZyBkZWYgPSBmaWVsZC0+RGVidWdTdHJpbmcoKTsKKyAgc3RyaW5nOjpzaXplX3R5cGUgZmlyc3RfbGluZV9lbmQgPSBkZWYuZmluZF9maXJzdF9vZignXG4nKTsKKyAgcHJpbnRlci0+UHJpbnQoIi8vICRkZWYkXG4iLAorICAgICJkZWYiLCBkZWYuc3Vic3RyKDAsIGZpcnN0X2xpbmVfZW5kKSk7CisgIGlmIChmaWVsZC0+aXNfZXh0ZW5zaW9uKCkpIHsKKyAgICBzdHJpbmc6OnNpemVfdHlwZSBzZWNvbmRfbGluZV9zdGFydCA9IGZpcnN0X2xpbmVfZW5kICsgMTsKKyAgICBzdHJpbmc6OnNpemVfdHlwZSBzZWNvbmRfbGluZV9sZW5ndGggPQorICAgICAgICBkZWYuZmluZCgnXG4nLCBzZWNvbmRfbGluZV9zdGFydCkgLSBzZWNvbmRfbGluZV9zdGFydDsKKyAgICBwcmludGVyLT5QcmludCgiLy8gJGRlZiRcbiIsCisgICAgICAiZGVmIiwgZGVmLnN1YnN0cihzZWNvbmRfbGluZV9zdGFydCwgc2Vjb25kX2xpbmVfbGVuZ3RoKSk7CisgIH0KK30KKworSmF2YVR5cGUgR2V0SmF2YVR5cGUoRmllbGREZXNjcmlwdG9yOjpUeXBlIGZpZWxkX3R5cGUpIHsKKyAgc3dpdGNoIChmaWVsZF90eXBlKSB7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfSU5UMzI6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfVUlOVDMyOgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NJTlQzMjoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9GSVhFRDMyOgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NGSVhFRDMyOgorICAgICAgcmV0dXJuIEpBVkFUWVBFX0lOVDsKKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0lOVDY0OgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1VJTlQ2NDoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TSU5UNjQ6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRklYRUQ2NDoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TRklYRUQ2NDoKKyAgICAgIHJldHVybiBKQVZBVFlQRV9MT05HOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRkxPQVQ6CisgICAgICByZXR1cm4gSkFWQVRZUEVfRkxPQVQ7CisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9ET1VCTEU6CisgICAgICByZXR1cm4gSkFWQVRZUEVfRE9VQkxFOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfQk9PTDoKKyAgICAgIHJldHVybiBKQVZBVFlQRV9CT09MRUFOOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU1RSSU5HOgorICAgICAgcmV0dXJuIEpBVkFUWVBFX1NUUklORzsKKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0JZVEVTOgorICAgICAgcmV0dXJuIEpBVkFUWVBFX0JZVEVTOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRU5VTToKKyAgICAgIHJldHVybiBKQVZBVFlQRV9FTlVNOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfR1JPVVA6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfTUVTU0FHRToKKyAgICAgIHJldHVybiBKQVZBVFlQRV9NRVNTQUdFOworCisgICAgLy8gTm8gZGVmYXVsdCBiZWNhdXNlIHdlIHdhbnQgdGhlIGNvbXBpbGVyIHRvIGNvbXBsYWluIGlmIGFueSBuZXcKKyAgICAvLyB0eXBlcyBhcmUgYWRkZWQuCisgIH0KKworICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ2FuJ3QgZ2V0IGhlcmUuIjsKKyAgcmV0dXJuIEpBVkFUWVBFX0lOVDsKK30KKworc3RyaW5nIFByaW1pdGl2ZVR5cGVOYW1lKEphdmFUeXBlIHR5cGUpIHsKKyAgc3dpdGNoICh0eXBlKSB7CisgICAgY2FzZSBKQVZBVFlQRV9JTlQgICAgOiByZXR1cm4gImludCI7CisgICAgY2FzZSBKQVZBVFlQRV9MT05HICAgOiByZXR1cm4gImxvbmciOworICAgIGNhc2UgSkFWQVRZUEVfRkxPQVQgIDogcmV0dXJuICJmbG9hdCI7CisgICAgY2FzZSBKQVZBVFlQRV9ET1VCTEUgOiByZXR1cm4gImRvdWJsZSI7CisgICAgY2FzZSBKQVZBVFlQRV9CT09MRUFOOiByZXR1cm4gImJvb2xlYW4iOworICAgIGNhc2UgSkFWQVRZUEVfU1RSSU5HIDogcmV0dXJuICJqYXZhLmxhbmcuU3RyaW5nIjsKKyAgICBjYXNlIEpBVkFUWVBFX0JZVEVTICA6IHJldHVybiAiYnl0ZVtdIjsKKyAgICBjYXNlIEpBVkFUWVBFX0VOVU0gICA6IHJldHVybiAiaW50IjsKKyAgICBjYXNlIEpBVkFUWVBFX01FU1NBR0U6IHJldHVybiAiIjsKKworICAgIC8vIE5vIGRlZmF1bHQgYmVjYXVzZSB3ZSB3YW50IHRoZSBjb21waWxlciB0byBjb21wbGFpbiBpZiBhbnkgbmV3CisgICAgLy8gSmF2YVR5cGVzIGFyZSBhZGRlZC4KKyAgfQorCisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJDYW4ndCBnZXQgaGVyZS4iOworICByZXR1cm4gIiI7Cit9CisKK3N0cmluZyBCb3hlZFByaW1pdGl2ZVR5cGVOYW1lKEphdmFUeXBlIHR5cGUpIHsKKyAgc3dpdGNoICh0eXBlKSB7CisgICAgY2FzZSBKQVZBVFlQRV9JTlQgICAgOiByZXR1cm4gImphdmEubGFuZy5JbnRlZ2VyIjsKKyAgICBjYXNlIEpBVkFUWVBFX0xPTkcgICA6IHJldHVybiAiamF2YS5sYW5nLkxvbmciOworICAgIGNhc2UgSkFWQVRZUEVfRkxPQVQgIDogcmV0dXJuICJqYXZhLmxhbmcuRmxvYXQiOworICAgIGNhc2UgSkFWQVRZUEVfRE9VQkxFIDogcmV0dXJuICJqYXZhLmxhbmcuRG91YmxlIjsKKyAgICBjYXNlIEpBVkFUWVBFX0JPT0xFQU46IHJldHVybiAiamF2YS5sYW5nLkJvb2xlYW4iOworICAgIGNhc2UgSkFWQVRZUEVfU1RSSU5HIDogcmV0dXJuICJqYXZhLmxhbmcuU3RyaW5nIjsKKyAgICBjYXNlIEpBVkFUWVBFX0JZVEVTICA6IHJldHVybiAiYnl0ZVtdIjsKKyAgICBjYXNlIEpBVkFUWVBFX0VOVU0gICA6IHJldHVybiAiamF2YS5sYW5nLkludGVnZXIiOworICAgIGNhc2UgSkFWQVRZUEVfTUVTU0FHRTogcmV0dXJuICIiOworCisgICAgLy8gTm8gZGVmYXVsdCBiZWNhdXNlIHdlIHdhbnQgdGhlIGNvbXBpbGVyIHRvIGNvbXBsYWluIGlmIGFueSBuZXcKKyAgICAvLyBKYXZhVHlwZXMgYXJlIGFkZGVkLgorICB9CisKKyAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkNhbid0IGdldCBoZXJlLiI7CisgIHJldHVybiAiIjsKK30KKworc3RyaW5nIEVtcHR5QXJyYXlOYW1lKGNvbnN0IFBhcmFtcyYgcGFyYW1zLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIHN3aXRjaCAoR2V0SmF2YVR5cGUoZmllbGQpKSB7CisgICAgY2FzZSBKQVZBVFlQRV9JTlQgICAgOiByZXR1cm4gImNvbS5nb29nbGUucHJvdG9idWYubmFuby5XaXJlRm9ybWF0TmFuby5FTVBUWV9JTlRfQVJSQVkiOworICAgIGNhc2UgSkFWQVRZUEVfTE9ORyAgIDogcmV0dXJuICJjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uV2lyZUZvcm1hdE5hbm8uRU1QVFlfTE9OR19BUlJBWSI7CisgICAgY2FzZSBKQVZBVFlQRV9GTE9BVCAgOiByZXR1cm4gImNvbS5nb29nbGUucHJvdG9idWYubmFuby5XaXJlRm9ybWF0TmFuby5FTVBUWV9GTE9BVF9BUlJBWSI7CisgICAgY2FzZSBKQVZBVFlQRV9ET1VCTEUgOiByZXR1cm4gImNvbS5nb29nbGUucHJvdG9idWYubmFuby5XaXJlRm9ybWF0TmFuby5FTVBUWV9ET1VCTEVfQVJSQVkiOworICAgIGNhc2UgSkFWQVRZUEVfQk9PTEVBTjogcmV0dXJuICJjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uV2lyZUZvcm1hdE5hbm8uRU1QVFlfQk9PTEVBTl9BUlJBWSI7CisgICAgY2FzZSBKQVZBVFlQRV9TVFJJTkcgOiByZXR1cm4gImNvbS5nb29nbGUucHJvdG9idWYubmFuby5XaXJlRm9ybWF0TmFuby5FTVBUWV9TVFJJTkdfQVJSQVkiOworICAgIGNhc2UgSkFWQVRZUEVfQllURVMgIDogcmV0dXJuICJjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uV2lyZUZvcm1hdE5hbm8uRU1QVFlfQllURVNfQVJSQVkiOworICAgIGNhc2UgSkFWQVRZUEVfRU5VTSAgIDogcmV0dXJuICJjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uV2lyZUZvcm1hdE5hbm8uRU1QVFlfSU5UX0FSUkFZIjsKKyAgICBjYXNlIEpBVkFUWVBFX01FU1NBR0U6IHJldHVybiBDbGFzc05hbWUocGFyYW1zLCBmaWVsZC0+bWVzc2FnZV90eXBlKCkpICsgIi5FTVBUWV9BUlJBWSI7CisKKyAgICAvLyBObyBkZWZhdWx0IGJlY2F1c2Ugd2Ugd2FudCB0aGUgY29tcGlsZXIgdG8gY29tcGxhaW4gaWYgYW55IG5ldworICAgIC8vIEphdmFUeXBlcyBhcmUgYWRkZWQuCisgIH0KKworICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ2FuJ3QgZ2V0IGhlcmUuIjsKKyAgcmV0dXJuICIiOworfQorCitzdHJpbmcgRGVmYXVsdFZhbHVlKGNvbnN0IFBhcmFtcyYgcGFyYW1zLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIGlmIChmaWVsZC0+bGFiZWwoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkxBQkVMX1JFUEVBVEVEKSB7CisgICAgcmV0dXJuIEVtcHR5QXJyYXlOYW1lKHBhcmFtcywgZmllbGQpOworICB9CisKKyAgaWYgKHBhcmFtcy51c2VfcmVmZXJlbmNlX3R5cGVzX2Zvcl9wcmltaXRpdmVzKCkpIHsKKyAgICBpZiAocGFyYW1zLnJlZnR5cGVzX3ByaW1pdGl2ZV9lbnVtcygpCisgICAgICAgICAgJiYgZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0VOVU0pIHsKKyAgICAgIHJldHVybiAiSW50ZWdlci5NSU5fVkFMVUUiOworICAgIH0KKyAgICByZXR1cm4gIm51bGwiOworICB9CisKKyAgLy8gU3dpdGNoIG9uIGNwcF90eXBlIHNpbmNlIHdlIG5lZWQgdG8ga25vdyB3aGljaCBkZWZhdWx0X3ZhbHVlXyogbWV0aG9kCisgIC8vIG9mIEZpZWxkRGVzY3JpcHRvciB0byBjYWxsLgorICBzd2l0Y2ggKGZpZWxkLT5jcHBfdHlwZSgpKSB7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UMzI6CisgICAgICByZXR1cm4gU2ltcGxlSXRvYShmaWVsZC0+ZGVmYXVsdF92YWx1ZV9pbnQzMigpKTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9VSU5UMzI6CisgICAgICAvLyBOZWVkIHRvIHByaW50IGFzIGEgc2lnbmVkIGludCBzaW5jZSBKYXZhIGhhcyBubyB1bnNpZ25lZC4KKyAgICAgIHJldHVybiBTaW1wbGVJdG9hKHN0YXRpY19jYXN0PGludDMyPihmaWVsZC0+ZGVmYXVsdF92YWx1ZV91aW50MzIoKSkpOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0lOVDY0OgorICAgICAgcmV0dXJuIFNpbXBsZUl0b2EoZmllbGQtPmRlZmF1bHRfdmFsdWVfaW50NjQoKSkgKyAiTCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDY0OgorICAgICAgcmV0dXJuIFNpbXBsZUl0b2Eoc3RhdGljX2Nhc3Q8aW50NjQ+KGZpZWxkLT5kZWZhdWx0X3ZhbHVlX3VpbnQ2NCgpKSkgKworICAgICAgICAgICAgICJMIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9ET1VCTEU6IHsKKyAgICAgIGRvdWJsZSB2YWx1ZSA9IGZpZWxkLT5kZWZhdWx0X3ZhbHVlX2RvdWJsZSgpOworICAgICAgaWYgKHZhbHVlID09IG51bWVyaWNfbGltaXRzPGRvdWJsZT46OmluZmluaXR5KCkpIHsKKyAgICAgICAgcmV0dXJuICJEb3VibGUuUE9TSVRJVkVfSU5GSU5JVFkiOworICAgICAgfSBlbHNlIGlmICh2YWx1ZSA9PSAtbnVtZXJpY19saW1pdHM8ZG91YmxlPjo6aW5maW5pdHkoKSkgeworICAgICAgICByZXR1cm4gIkRvdWJsZS5ORUdBVElWRV9JTkZJTklUWSI7CisgICAgICB9IGVsc2UgaWYgKHZhbHVlICE9IHZhbHVlKSB7CisgICAgICAgIHJldHVybiAiRG91YmxlLk5hTiI7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gU2ltcGxlRHRvYSh2YWx1ZSkgKyAiRCI7CisgICAgICB9CisgICAgfQorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0ZMT0FUOiB7CisgICAgICBmbG9hdCB2YWx1ZSA9IGZpZWxkLT5kZWZhdWx0X3ZhbHVlX2Zsb2F0KCk7CisgICAgICBpZiAodmFsdWUgPT0gbnVtZXJpY19saW1pdHM8ZmxvYXQ+OjppbmZpbml0eSgpKSB7CisgICAgICAgIHJldHVybiAiRmxvYXQuUE9TSVRJVkVfSU5GSU5JVFkiOworICAgICAgfSBlbHNlIGlmICh2YWx1ZSA9PSAtbnVtZXJpY19saW1pdHM8ZmxvYXQ+OjppbmZpbml0eSgpKSB7CisgICAgICAgIHJldHVybiAiRmxvYXQuTkVHQVRJVkVfSU5GSU5JVFkiOworICAgICAgfSBlbHNlIGlmICh2YWx1ZSAhPSB2YWx1ZSkgeworICAgICAgICByZXR1cm4gIkZsb2F0Lk5hTiI7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gU2ltcGxlRnRvYSh2YWx1ZSkgKyAiRiI7CisgICAgICB9CisgICAgfQorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0JPT0w6CisgICAgICByZXR1cm4gZmllbGQtPmRlZmF1bHRfdmFsdWVfYm9vbCgpID8gInRydWUiIDogImZhbHNlIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9TVFJJTkc6CisgICAgICBpZiAoIWZpZWxkLT5kZWZhdWx0X3ZhbHVlX3N0cmluZygpLmVtcHR5KCkpIHsKKyAgICAgICAgLy8gUG9pbnQgaXQgdG8gdGhlIHN0YXRpYyBmaW5hbCBpbiB0aGUgZ2VuZXJhdGVkIGNvZGUuCisgICAgICAgIHJldHVybiBGaWVsZERlZmF1bHRDb25zdGFudE5hbWUoZmllbGQpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgaWYgKGZpZWxkLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX0JZVEVTKSB7CisgICAgICAgICAgcmV0dXJuICJjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uV2lyZUZvcm1hdE5hbm8uRU1QVFlfQllURVMiOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHJldHVybiAiXCJcIiI7CisgICAgICAgIH0KKyAgICAgIH0KKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0VOVU06CisgICAgICByZXR1cm4gQ2xhc3NOYW1lKHBhcmFtcywgZmllbGQtPmVudW1fdHlwZSgpKSArICIuIiArCisgICAgICAgICAgICAgUmVuYW1lSmF2YUtleXdvcmRzKGZpZWxkLT5kZWZhdWx0X3ZhbHVlX2VudW0oKS0+bmFtZSgpKTsKKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U6CisgICAgICByZXR1cm4gIm51bGwiOworCisgICAgLy8gTm8gZGVmYXVsdCBiZWNhdXNlIHdlIHdhbnQgdGhlIGNvbXBpbGVyIHRvIGNvbXBsYWluIGlmIGFueSBuZXcKKyAgICAvLyB0eXBlcyBhcmUgYWRkZWQuCisgIH0KKworICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ2FuJ3QgZ2V0IGhlcmUuIjsKKyAgcmV0dXJuICIiOworfQorCisKK3N0YXRpYyBjb25zdCBjaGFyKiBrQml0TWFza3NbXSA9IHsKKyAgIjB4MDAwMDAwMDEiLAorICAiMHgwMDAwMDAwMiIsCisgICIweDAwMDAwMDA0IiwKKyAgIjB4MDAwMDAwMDgiLAorICAiMHgwMDAwMDAxMCIsCisgICIweDAwMDAwMDIwIiwKKyAgIjB4MDAwMDAwNDAiLAorICAiMHgwMDAwMDA4MCIsCisKKyAgIjB4MDAwMDAxMDAiLAorICAiMHgwMDAwMDIwMCIsCisgICIweDAwMDAwNDAwIiwKKyAgIjB4MDAwMDA4MDAiLAorICAiMHgwMDAwMTAwMCIsCisgICIweDAwMDAyMDAwIiwKKyAgIjB4MDAwMDQwMDAiLAorICAiMHgwMDAwODAwMCIsCisKKyAgIjB4MDAwMTAwMDAiLAorICAiMHgwMDAyMDAwMCIsCisgICIweDAwMDQwMDAwIiwKKyAgIjB4MDAwODAwMDAiLAorICAiMHgwMDEwMDAwMCIsCisgICIweDAwMjAwMDAwIiwKKyAgIjB4MDA0MDAwMDAiLAorICAiMHgwMDgwMDAwMCIsCisKKyAgIjB4MDEwMDAwMDAiLAorICAiMHgwMjAwMDAwMCIsCisgICIweDA0MDAwMDAwIiwKKyAgIjB4MDgwMDAwMDAiLAorICAiMHgxMDAwMDAwMCIsCisgICIweDIwMDAwMDAwIiwKKyAgIjB4NDAwMDAwMDAiLAorICAiMHg4MDAwMDAwMCIsCit9OworCitzdHJpbmcgR2V0Qml0RmllbGROYW1lKGludCBpbmRleCkgeworICBzdHJpbmcgdmFyX25hbWUgPSAiYml0RmllbGQiOworICB2YXJfbmFtZSArPSBTaW1wbGVJdG9hKGluZGV4KTsKKyAgdmFyX25hbWUgKz0gIl8iOworICByZXR1cm4gdmFyX25hbWU7Cit9CisKK3N0cmluZyBHZXRCaXRGaWVsZE5hbWVGb3JCaXQoaW50IGJpdF9pbmRleCkgeworICByZXR1cm4gR2V0Qml0RmllbGROYW1lKGJpdF9pbmRleCAvIDMyKTsKK30KKworc3RyaW5nIEdlbmVyYXRlR2V0Qml0KGludCBiaXRfaW5kZXgpIHsKKyAgc3RyaW5nIHZhcl9uYW1lID0gR2V0Qml0RmllbGROYW1lRm9yQml0KGJpdF9pbmRleCk7CisgIGludCBiaXRfaW5fdmFyX2luZGV4ID0gYml0X2luZGV4ICUgMzI7CisKKyAgc3RyaW5nIG1hc2sgPSBrQml0TWFza3NbYml0X2luX3Zhcl9pbmRleF07CisgIHN0cmluZyByZXN1bHQgPSAiKCgiICsgdmFyX25hbWUgKyAiICYgIiArIG1hc2sgKyAiKSAhPSAwKSI7CisgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0cmluZyBHZW5lcmF0ZVNldEJpdChpbnQgYml0X2luZGV4KSB7CisgIHN0cmluZyB2YXJfbmFtZSA9IEdldEJpdEZpZWxkTmFtZUZvckJpdChiaXRfaW5kZXgpOworICBpbnQgYml0X2luX3Zhcl9pbmRleCA9IGJpdF9pbmRleCAlIDMyOworCisgIHN0cmluZyBtYXNrID0ga0JpdE1hc2tzW2JpdF9pbl92YXJfaW5kZXhdOworICBzdHJpbmcgcmVzdWx0ID0gdmFyX25hbWUgKyAiIHw9ICIgKyBtYXNrOworICByZXR1cm4gcmVzdWx0OworfQorCitzdHJpbmcgR2VuZXJhdGVDbGVhckJpdChpbnQgYml0X2luZGV4KSB7CisgIHN0cmluZyB2YXJfbmFtZSA9IEdldEJpdEZpZWxkTmFtZUZvckJpdChiaXRfaW5kZXgpOworICBpbnQgYml0X2luX3Zhcl9pbmRleCA9IGJpdF9pbmRleCAlIDMyOworCisgIHN0cmluZyBtYXNrID0ga0JpdE1hc2tzW2JpdF9pbl92YXJfaW5kZXhdOworICBzdHJpbmcgcmVzdWx0ID0gdmFyX25hbWUgKyAiID0gKCIgKyB2YXJfbmFtZSArICIgJiB+IiArIG1hc2sgKyAiKSI7CisgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0cmluZyBHZW5lcmF0ZURpZmZlcmVudEJpdChpbnQgYml0X2luZGV4KSB7CisgIHN0cmluZyB2YXJfbmFtZSA9IEdldEJpdEZpZWxkTmFtZUZvckJpdChiaXRfaW5kZXgpOworICBpbnQgYml0X2luX3Zhcl9pbmRleCA9IGJpdF9pbmRleCAlIDMyOworCisgIHN0cmluZyBtYXNrID0ga0JpdE1hc2tzW2JpdF9pbl92YXJfaW5kZXhdOworICBzdHJpbmcgcmVzdWx0ID0gIigoIiArIHZhcl9uYW1lICsgIiAmICIgKyBtYXNrCisgICAgICArICIpICE9IChvdGhlci4iICsgdmFyX25hbWUgKyAiICYgIiArIG1hc2sgKyAiKSkiOworICByZXR1cm4gcmVzdWx0OworfQorCit2b2lkIFNldEJpdE9wZXJhdGlvblZhcmlhYmxlcyhjb25zdCBzdHJpbmcgbmFtZSwKKyAgICBpbnQgYml0SW5kZXgsIG1hcDxzdHJpbmcsIHN0cmluZz4qIHZhcmlhYmxlcykgeworICAoKnZhcmlhYmxlcylbImdldF8iICsgbmFtZV0gPSBHZW5lcmF0ZUdldEJpdChiaXRJbmRleCk7CisgICgqdmFyaWFibGVzKVsic2V0XyIgKyBuYW1lXSA9IEdlbmVyYXRlU2V0Qml0KGJpdEluZGV4KTsKKyAgKCp2YXJpYWJsZXMpWyJjbGVhcl8iICsgbmFtZV0gPSBHZW5lcmF0ZUNsZWFyQml0KGJpdEluZGV4KTsKKyAgKCp2YXJpYWJsZXMpWyJkaWZmZXJlbnRfIiArIG5hbWVdID0gR2VuZXJhdGVEaWZmZXJlbnRCaXQoYml0SW5kZXgpOworfQorCitib29sIEhhc01hcEZpZWxkKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yLT5maWVsZF9jb3VudCgpOyArK2kpIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvci0+ZmllbGQoaSk7CisgICAgaWYgKGZpZWxkLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX01FU1NBR0UgJiYKKyAgICAgICAgSXNNYXBFbnRyeShmaWVsZC0+bWVzc2FnZV90eXBlKCkpKSB7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIGZhbHNlOworfQorCit9ICAvLyBuYW1lc3BhY2UgamF2YW5hbm8KK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2hlbHBlcnMuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9faGVscGVycy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAxNGM4NWEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2hlbHBlcnMuaApAQCAtMCwwICsxLDE5OSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9wcm90b2J1Zi8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFOQU5PX0hFTFBFUlNfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBTkFOT19IRUxQRVJTX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19wYXJhbXMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhbmFubyB7CisKKy8vIENvbW1vbmx5LXVzZWQgc2VwYXJhdG9yIGNvbW1lbnRzLiAgVGhpY2sgaXMgYSBsaW5lIG9mICc9JywgdGhpbiBpcyBhIGxpbmUKKy8vIG9mICctJy4KK2V4dGVybiBjb25zdCBjaGFyIGtUaGlja1NlcGFyYXRvcltdOworZXh0ZXJuIGNvbnN0IGNoYXIga1RoaW5TZXBhcmF0b3JbXTsKKworLy8gQ29udmVydHMgdGhlIGZpZWxkJ3MgbmFtZSB0byBjYW1lbC1jYXNlLCBlLmcuICJmb29fYmFyX2JheiIgYmVjb21lcworLy8gImZvb0JhckJheiIgb3IgIkZvb0JhckJheiIsIHJlc3BlY3RpdmVseS4KK3N0cmluZyBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpOworc3RyaW5nIFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBvbmVvZik7CitzdHJpbmcgVW5kZXJzY29yZXNUb0NhcGl0YWxpemVkQ2FtZWxDYXNlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpOworc3RyaW5nIFVuZGVyc2NvcmVzVG9DYXBpdGFsaXplZENhbWVsQ2FzZShjb25zdCBPbmVvZkRlc2NyaXB0b3IqIG9uZW9mKTsKKworLy8gQXBwZW5kcyBhbiAiXyIgdG8gdGhlIGVuZCBvZiBhIGZpZWxkIHdoZXJlIHRoZSBuYW1lIGlzIGEgcmVzZXJ2ZWQgamF2YQorLy8ga2V5d29yZC4gIEZvciBleGFtcGxlIGludDMyIHB1YmxpYyA9IDEgd2lsbCBnZW5lcmF0ZSBpbnQgcHVibGljXy4KK3N0cmluZyBSZW5hbWVKYXZhS2V5d29yZHMoY29uc3Qgc3RyaW5nJiBpbnB1dCk7CisKKy8vIFNpbWlsYXIsIGJ1dCBmb3IgbWV0aG9kIG5hbWVzLiAgKFR5cGljYWxseSwgdGhpcyBtZXJlbHkgaGFzIHRoZSBlZmZlY3QKKy8vIG9mIGxvd2VyLWNhc2luZyB0aGUgZmlyc3QgbGV0dGVyIG9mIHRoZSBuYW1lLikKK3N0cmluZyBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlKGNvbnN0IE1ldGhvZERlc2NyaXB0b3IqIG1ldGhvZCk7CisKKy8vIFN0cmlwcyAiLnByb3RvIiBvciAiLnByb3RvZGV2ZWwiIGZyb20gdGhlIGVuZCBvZiBhIGZpbGVuYW1lLgorc3RyaW5nIFN0cmlwUHJvdG8oY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSk7CisKKy8vIEdldHMgdGhlIHVucXVhbGlmaWVkIGNsYXNzIG5hbWUgZm9yIHRoZSBmaWxlLiAgRWFjaCAucHJvdG8gZmlsZSBiZWNvbWVzIGEKKy8vIHNpbmdsZSBKYXZhIGNsYXNzLCB3aXRoIGFsbCBpdHMgY29udGVudHMgbmVzdGVkIGluIHRoYXQgY2xhc3MuCitzdHJpbmcgRmlsZUNsYXNzTmFtZShjb25zdCBQYXJhbXMmIHBhcmFtcywgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUpOworCisvLyBSZXR1cm5zIHRoZSBmaWxlJ3MgSmF2YSBwYWNrYWdlIG5hbWUuCitzdHJpbmcgRmlsZUphdmFQYWNrYWdlKGNvbnN0IFBhcmFtcyYgcGFyYW1zLCBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSk7CisKKy8vIFJldHVybnMgd2hldGhlciB0aGUgSmF2YSBvdXRlciBjbGFzcyBpcyBuZWVkZWQsIGkuZS4gd2hldGhlciB0aGUgb3B0aW9uCisvLyBqYXZhX211bHRpcGxlX2ZpbGVzIGlzIGZhbHNlLCBvciB0aGUgcHJvdG8gZmlsZSBjb250YWlucyBhbnkgZmlsZS1zY29wZQorLy8gZW51bXMvZXh0ZW5zaW9ucy4KK2Jvb2wgSXNPdXRlckNsYXNzTmVlZGVkKGNvbnN0IFBhcmFtcyYgcGFyYW1zLCBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSk7CisKKy8vIENvbnZlcnRzIHRoZSBnaXZlbiBzaW1wbGUgbmFtZSBvZiBhIHByb3RvIGVudGl0eSB0byBpdHMgZnVsbHktcXVhbGlmaWVkIG5hbWUKKy8vIGluIHRoZSBKYXZhIG5hbWVzcGFjZSwgZ2l2ZW4gdGhhdCBpdCBpcyBpbiB0aGUgZ2l2ZW4gZmlsZSBlbmNsb3NlZCBpbiB0aGUKKy8vIGdpdmVuIHBhcmVudCBtZXNzYWdlIChvciBOVUxMIGZvciBmaWxlLXNjb3BlIGVudGl0aWVzKS4gV2hldGhlciB0aGUgZmlsZSdzCisvLyBvdXRlciBjbGFzcyBuYW1lIHNob3VsZCBiZSBpbmNsdWRlZCBpbiB0aGUgcmV0dXJuIHZhbHVlIGRlcGVuZHMgb24gZmFjdG9ycworLy8gaW5mZXJyYWJsZSBmcm9tIHRoZSBnaXZlbiBhcmd1bWVudHMsIGluY2x1ZGluZyBpc19jbGFzcyB3aGljaCBpbmRpY2F0ZXMKKy8vIHdoZXRoZXIgdGhlIGVudGl0eSB0cmFuc2xhdGVzIHRvIGEgSmF2YSBjbGFzcy4KK3N0cmluZyBUb0phdmFOYW1lKGNvbnN0IFBhcmFtcyYgcGFyYW1zLCBjb25zdCBzdHJpbmcmIG5hbWUsIGJvb2wgaXNfY2xhc3MsCisgICAgY29uc3QgRGVzY3JpcHRvciogcGFyZW50LCBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSk7CisKKy8vIFRoZXNlIHJldHVybiB0aGUgZnVsbHktcXVhbGlmaWVkIGNsYXNzIG5hbWUgY29ycmVzcG9uZGluZyB0byB0aGUgZ2l2ZW4KKy8vIGRlc2NyaXB0b3IuCitpbmxpbmUgc3RyaW5nIENsYXNzTmFtZShjb25zdCBQYXJhbXMmIHBhcmFtcywgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICByZXR1cm4gVG9KYXZhTmFtZShwYXJhbXMsIGRlc2NyaXB0b3ItPm5hbWUoKSwgdHJ1ZSwKKyAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRvci0+Y29udGFpbmluZ190eXBlKCksIGRlc2NyaXB0b3ItPmZpbGUoKSk7Cit9CitzdHJpbmcgQ2xhc3NOYW1lKGNvbnN0IFBhcmFtcyYgcGFyYW1zLCBjb25zdCBFbnVtRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CitpbmxpbmUgc3RyaW5nIENsYXNzTmFtZShjb25zdCBQYXJhbXMmIHBhcmFtcywKKyAgICBjb25zdCBTZXJ2aWNlRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICByZXR1cm4gVG9KYXZhTmFtZShwYXJhbXMsIGRlc2NyaXB0b3ItPm5hbWUoKSwgdHJ1ZSwgTlVMTCwgZGVzY3JpcHRvci0+ZmlsZSgpKTsKK30KK2lubGluZSBzdHJpbmcgRXh0ZW5zaW9uSWRlbnRpZmllck5hbWUoY29uc3QgUGFyYW1zJiBwYXJhbXMsCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIHJldHVybiBUb0phdmFOYW1lKHBhcmFtcywgZGVzY3JpcHRvci0+bmFtZSgpLCBmYWxzZSwKKyAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRvci0+ZXh0ZW5zaW9uX3Njb3BlKCksIGRlc2NyaXB0b3ItPmZpbGUoKSk7Cit9CitzdHJpbmcgQ2xhc3NOYW1lKGNvbnN0IFBhcmFtcyYgcGFyYW1zLCBjb25zdCBGaWxlRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CisKKy8vIEdldCB0aGUgdW5xdWFsaWZpZWQgbmFtZSB0aGF0IHNob3VsZCBiZSB1c2VkIGZvciBhIGZpZWxkJ3MgZmllbGQKKy8vIG51bWJlciBjb25zdGFudC4KK3N0cmluZyBGaWVsZENvbnN0YW50TmFtZShjb25zdCBGaWVsZERlc2NyaXB0b3IgKmZpZWxkKTsKKworc3RyaW5nIEZpZWxkRGVmYXVsdENvbnN0YW50TmFtZShjb25zdCBGaWVsZERlc2NyaXB0b3IgKmZpZWxkKTsKKworLy8gUHJpbnQgdGhlIGZpZWxkJ3MgcHJvdG8tc3ludGF4IGRlZmluaXRpb24gYXMgYSBjb21tZW50Lgordm9pZCBQcmludEZpZWxkQ29tbWVudChpbzo6UHJpbnRlciogcHJpbnRlciwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCk7CisKK2VudW0gSmF2YVR5cGUgeworICBKQVZBVFlQRV9JTlQsCisgIEpBVkFUWVBFX0xPTkcsCisgIEpBVkFUWVBFX0ZMT0FULAorICBKQVZBVFlQRV9ET1VCTEUsCisgIEpBVkFUWVBFX0JPT0xFQU4sCisgIEpBVkFUWVBFX1NUUklORywKKyAgSkFWQVRZUEVfQllURVMsCisgIEpBVkFUWVBFX0VOVU0sCisgIEpBVkFUWVBFX01FU1NBR0UKK307CisKK0phdmFUeXBlIEdldEphdmFUeXBlKEZpZWxkRGVzY3JpcHRvcjo6VHlwZSBmaWVsZF90eXBlKTsKKworaW5saW5lIEphdmFUeXBlIEdldEphdmFUeXBlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgcmV0dXJuIEdldEphdmFUeXBlKGZpZWxkLT50eXBlKCkpOworfQorCitzdHJpbmcgUHJpbWl0aXZlVHlwZU5hbWUoSmF2YVR5cGUgdHlwZSk7CisKKy8vIEdldCB0aGUgZnVsbHktcXVhbGlmaWVkIGNsYXNzIG5hbWUgZm9yIGEgYm94ZWQgcHJpbWl0aXZlIHR5cGUsIGUuZy4KKy8vICJqYXZhLmxhbmcuSW50ZWdlciIgZm9yIEpBVkFUWVBFX0lOVC4gIFJldHVybnMgTlVMTCBmb3IgZW51bSBhbmQgbWVzc2FnZQorLy8gdHlwZXMuCitzdHJpbmcgQm94ZWRQcmltaXRpdmVUeXBlTmFtZShKYXZhVHlwZSB0eXBlKTsKKworc3RyaW5nIEVtcHR5QXJyYXlOYW1lKGNvbnN0IFBhcmFtcyYgcGFyYW1zLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKTsKKworc3RyaW5nIERlZmF1bHRWYWx1ZShjb25zdCBQYXJhbXMmIHBhcmFtcywgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCk7CisKKworLy8gTWV0aG9kcyBmb3Igc2hhcmVkIGJpdGZpZWxkcy4KKworLy8gR2V0cyB0aGUgbmFtZSBvZiB0aGUgc2hhcmVkIGJpdGZpZWxkIGZvciB0aGUgZ2l2ZW4gZmllbGQgaW5kZXguCitzdHJpbmcgR2V0Qml0RmllbGROYW1lKGludCBpbmRleCk7CisKKy8vIEdldHMgdGhlIG5hbWUgb2YgdGhlIHNoYXJlZCBiaXRmaWVsZCBmb3IgdGhlIGdpdmVuIGJpdCBpbmRleC4KKy8vIEVmZmVjdGl2ZWx5LCBHZXRCaXRGaWVsZE5hbWUoYml0X2luZGV4IC8gMzIpCitzdHJpbmcgR2V0Qml0RmllbGROYW1lRm9yQml0KGludCBiaXRfaW5kZXgpOworCisvLyBHZW5lcmF0ZXMgdGhlIGphdmEgY29kZSBmb3IgdGhlIGV4cHJlc3Npb24gdGhhdCByZXR1cm5zIHdoZXRoZXIgdGhlIGJpdCBhdAorLy8gdGhlIGdpdmVuIGJpdCBpbmRleCBpcyBzZXQuCisvLyBFeGFtcGxlOiAiKChiaXRGaWVsZDFfICYgMHgwNDAwMDAwMCkgIT0gMCkiCitzdHJpbmcgR2VuZXJhdGVHZXRCaXQoaW50IGJpdF9pbmRleCk7CisKKy8vIEdlbmVyYXRlcyB0aGUgamF2YSBjb2RlIGZvciB0aGUgZXhwcmVzc2lvbiB0aGF0IHNldHMgdGhlIGJpdCBhdCB0aGUgZ2l2ZW4KKy8vIGJpdCBpbmRleC4KKy8vIEV4YW1wbGU6ICJiaXRGaWVsZDFfIHw9IDB4MDQwMDAwMDAiCitzdHJpbmcgR2VuZXJhdGVTZXRCaXQoaW50IGJpdF9pbmRleCk7CisKKy8vIEdlbmVyYXRlcyB0aGUgamF2YSBjb2RlIGZvciB0aGUgZXhwcmVzc2lvbiB0aGF0IGNsZWFycyB0aGUgYml0IGF0IHRoZSBnaXZlbgorLy8gYml0IGluZGV4LgorLy8gRXhhbXBsZTogImJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDA0MDAwMDAwKSIKK3N0cmluZyBHZW5lcmF0ZUNsZWFyQml0KGludCBiaXRfaW5kZXgpOworCisvLyBHZW5lcmF0ZXMgdGhlIGphdmEgY29kZSBmb3IgdGhlIGV4cHJlc3Npb24gdGhhdCByZXR1cm5zIHdoZXRoZXIgdGhlIGJpdCBhdAorLy8gdGhlIGdpdmVuIGJpdCBpbmRleCBjb250YWlucyBkaWZmZXJlbnQgdmFsdWVzIGluIHRoZSBjdXJyZW50IG9iamVjdCBhbmQKKy8vIGFub3RoZXIgb2JqZWN0IGFjY2Vzc2libGUgdmlhIHRoZSB2YXJpYWJsZSAnb3RoZXInLgorLy8gRXhhbXBsZTogIigoYml0RmllbGQxXyAmIDB4MDQwMDAwMDApICE9IChvdGhlci5iaXRGaWVsZDFfICYgMHgwNDAwMDAwMCkpIgorc3RyaW5nIEdlbmVyYXRlRGlmZmVyZW50Qml0KGludCBiaXRfaW5kZXgpOworCisvLyBTZXRzIHRoZSAnZ2V0XyonLCAnc2V0XyonLCAnY2xlYXJfKicgYW5kICdkaWZmZXJlbnRfKicgdmFyaWFibGVzLCB3aGVyZSAqIGlzCisvLyB0aGUgZ2l2ZW4gbmFtZSBvZiB0aGUgYml0LCB0byB0aGUgYXBwcm9wcmlhdGUgSmF2YSBleHByZXNzaW9ucyBmb3IgdGhlIGdpdmVuCisvLyBiaXQgaW5kZXguCit2b2lkIFNldEJpdE9wZXJhdGlvblZhcmlhYmxlcyhjb25zdCBzdHJpbmcgbmFtZSwKKyAgICBpbnQgYml0SW5kZXgsIG1hcDxzdHJpbmcsIHN0cmluZz4qIHZhcmlhYmxlcyk7CisKK2lubGluZSBib29sIElzTWFwRW50cnkoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICAvLyBUT0RPKGxpdWppc2kpOiBBZGQgYW4gb3B0aW9uIHRvIHR1cm4gb24gbWFwcyBmb3IgcHJvdG8yIHN5bnRheCBhcyB3ZWxsLgorICByZXR1cm4gZGVzY3JpcHRvci0+b3B0aW9ucygpLm1hcF9lbnRyeSgpICYmCisgICAgICBkZXNjcmlwdG9yLT5maWxlKCktPnN5bnRheCgpID09IEZpbGVEZXNjcmlwdG9yOjpTWU5UQVhfUFJPVE8zOworfQorCitib29sIEhhc01hcEZpZWxkKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworCit9ICAvLyBuYW1lc3BhY2UgamF2YW5hbm8KK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFOQU5PX0hFTFBFUlNfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX21hcF9maWVsZC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fbWFwX2ZpZWxkLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgzYjJiMGMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX21hcF9maWVsZC5jYwpAQCAtMCwwICsxLDE4NiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9wcm90b2J1Zi8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19tYXBfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9faGVscGVycy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YW5hbm8geworCituYW1lc3BhY2UgeworCitzdHJpbmcgVHlwZU5hbWUoY29uc3QgUGFyYW1zJiBwYXJhbXMsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgYm9vbCBib3hlZCkgeworICBKYXZhVHlwZSBqYXZhX3R5cGUgPSBHZXRKYXZhVHlwZShmaWVsZCk7CisgIHN3aXRjaCAoamF2YV90eXBlKSB7CisgICAgY2FzZSBKQVZBVFlQRV9NRVNTQUdFOgorICAgICAgcmV0dXJuIENsYXNzTmFtZShwYXJhbXMsIGZpZWxkLT5tZXNzYWdlX3R5cGUoKSk7CisgICAgY2FzZSBKQVZBVFlQRV9JTlQ6CisgICAgY2FzZSBKQVZBVFlQRV9MT05HOgorICAgIGNhc2UgSkFWQVRZUEVfRkxPQVQ6CisgICAgY2FzZSBKQVZBVFlQRV9ET1VCTEU6CisgICAgY2FzZSBKQVZBVFlQRV9CT09MRUFOOgorICAgIGNhc2UgSkFWQVRZUEVfU1RSSU5HOgorICAgIGNhc2UgSkFWQVRZUEVfQllURVM6CisgICAgY2FzZSBKQVZBVFlQRV9FTlVNOgorICAgICAgaWYgKGJveGVkKSB7CisgICAgICAgIHJldHVybiBCb3hlZFByaW1pdGl2ZVR5cGVOYW1lKGphdmFfdHlwZSk7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gUHJpbWl0aXZlVHlwZU5hbWUoamF2YV90eXBlKTsKKyAgICAgIH0KKyAgICAvLyBObyBkZWZhdWx0IGJlY2F1c2Ugd2Ugd2FudCB0aGUgY29tcGlsZXIgdG8gY29tcGxhaW4gaWYgYW55IG5ldyBKYXZhVHlwZXMKKyAgICAvLyBhcmUgYWRkZWQuLgorICB9CisKKyAgR09PR0xFX0xPRyhGQVRBTCkgPDwgInNob3VsZCBub3QgcmVhY2ggaGVyZS4iOworICByZXR1cm4gIiI7Cit9CisKK2NvbnN0IEZpZWxkRGVzY3JpcHRvciogS2V5RmllbGQoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIEdPT0dMRV9DSEVDS19FUShGaWVsZERlc2NyaXB0b3I6OlRZUEVfTUVTU0FHRSwgZGVzY3JpcHRvci0+dHlwZSgpKTsKKyAgY29uc3QgRGVzY3JpcHRvciogbWVzc2FnZSA9IGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpOworICBHT09HTEVfQ0hFQ0sobWVzc2FnZS0+b3B0aW9ucygpLm1hcF9lbnRyeSgpKTsKKyAgcmV0dXJuIG1lc3NhZ2UtPkZpbmRGaWVsZEJ5TmFtZSgia2V5Iik7Cit9CisKK2NvbnN0IEZpZWxkRGVzY3JpcHRvciogVmFsdWVGaWVsZChjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgR09PR0xFX0NIRUNLX0VRKEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9NRVNTQUdFLCBkZXNjcmlwdG9yLT50eXBlKCkpOworICBjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlID0gZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCk7CisgIEdPT0dMRV9DSEVDSyhtZXNzYWdlLT5vcHRpb25zKCkubWFwX2VudHJ5KCkpOworICByZXR1cm4gbWVzc2FnZS0+RmluZEZpZWxkQnlOYW1lKCJ2YWx1ZSIpOworfQorCit2b2lkIFNldE1hcFZhcmlhYmxlcyhjb25zdCBQYXJhbXMmIHBhcmFtcywKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIG1hcDxzdHJpbmcsIHN0cmluZz4qIHZhcmlhYmxlcykgeworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGtleSA9IEtleUZpZWxkKGRlc2NyaXB0b3IpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHZhbHVlID0gVmFsdWVGaWVsZChkZXNjcmlwdG9yKTsKKyAgKCp2YXJpYWJsZXMpWyJuYW1lIl0gPQorICAgIFJlbmFtZUphdmFLZXl3b3JkcyhVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlKGRlc2NyaXB0b3IpKTsKKyAgKCp2YXJpYWJsZXMpWyJudW1iZXIiXSA9IFNpbXBsZUl0b2EoZGVzY3JpcHRvci0+bnVtYmVyKCkpOworICAoKnZhcmlhYmxlcylbImtleV90eXBlIl0gPSBUeXBlTmFtZShwYXJhbXMsIGtleSwgZmFsc2UpOworICAoKnZhcmlhYmxlcylbImJveGVkX2tleV90eXBlIl0gPSBUeXBlTmFtZShwYXJhbXMsa2V5LCB0cnVlKTsKKyAgKCp2YXJpYWJsZXMpWyJrZXlfZGVzY190eXBlIl0gPQorICAgICAgIlRZUEVfIiArIFRvVXBwZXIoRmllbGREZXNjcmlwdG9yOjpUeXBlTmFtZShrZXktPnR5cGUoKSkpOworICAoKnZhcmlhYmxlcylbImtleV90YWciXSA9IFNpbXBsZUl0b2EoaW50ZXJuYWw6OldpcmVGb3JtYXQ6Ok1ha2VUYWcoa2V5KSk7CisgICgqdmFyaWFibGVzKVsidmFsdWVfdHlwZSJdID0gVHlwZU5hbWUocGFyYW1zLCB2YWx1ZSwgZmFsc2UpOworICAoKnZhcmlhYmxlcylbImJveGVkX3ZhbHVlX3R5cGUiXSA9IFR5cGVOYW1lKHBhcmFtcywgdmFsdWUsIHRydWUpOworICAoKnZhcmlhYmxlcylbInZhbHVlX2Rlc2NfdHlwZSJdID0KKyAgICAgICJUWVBFXyIgKyBUb1VwcGVyKEZpZWxkRGVzY3JpcHRvcjo6VHlwZU5hbWUodmFsdWUtPnR5cGUoKSkpOworICAoKnZhcmlhYmxlcylbInZhbHVlX3RhZyJdID0gU2ltcGxlSXRvYShpbnRlcm5hbDo6V2lyZUZvcm1hdDo6TWFrZVRhZyh2YWx1ZSkpOworICAoKnZhcmlhYmxlcylbInR5cGVfcGFyYW1ldGVycyJdID0KKyAgICAgICgqdmFyaWFibGVzKVsiYm94ZWRfa2V5X3R5cGUiXSArICIsICIgKyAoKnZhcmlhYmxlcylbImJveGVkX3ZhbHVlX3R5cGUiXTsKKyAgKCp2YXJpYWJsZXMpWyJ2YWx1ZV9kZWZhdWx0Il0gPQorICAgICAgdmFsdWUtPnR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfTUVTU0FHRQorICAgICAgICAgID8gIm5ldyAiICsgKCp2YXJpYWJsZXMpWyJ2YWx1ZV90eXBlIl0gKyAiKCkiCisgICAgICAgICAgOiAibnVsbCI7Cit9Cit9ICAvLyBuYW1lc3BhY2UKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorTWFwRmllbGRHZW5lcmF0b3I6Ok1hcEZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBQYXJhbXMmIHBhcmFtcykKKyAgICA6IEZpZWxkR2VuZXJhdG9yKHBhcmFtcyksIGRlc2NyaXB0b3JfKGRlc2NyaXB0b3IpIHsKKyAgU2V0TWFwVmFyaWFibGVzKHBhcmFtcywgZGVzY3JpcHRvciwgJnZhcmlhYmxlc18pOworfQorCitNYXBGaWVsZEdlbmVyYXRvcjo6fk1hcEZpZWxkR2VuZXJhdG9yKCkge30KKwordm9pZCBNYXBGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIsIGJvb2wgLyogdW51c2VkIGxhenlfaW5pdCAqLykgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwdWJsaWMgamF2YS51dGlsLk1hcDwkdHlwZV9wYXJhbWV0ZXJzJD4gJG5hbWUkO1xuIik7Cit9CisKK3ZvaWQgTWFwRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVDbGVhckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJG5hbWUkID0gbnVsbDtcbiIpOworfQorCit2b2lkIE1hcEZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAidGhpcy4kbmFtZSQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uSW50ZXJuYWxOYW5vLm1lcmdlTWFwRW50cnkoXG4iCisgICAgIiAgaW5wdXQsIHRoaXMuJG5hbWUkLCBtYXBGYWN0b3J5LFxuIgorICAgICIgIGNvbS5nb29nbGUucHJvdG9idWYubmFuby5JbnRlcm5hbE5hbm8uJGtleV9kZXNjX3R5cGUkLFxuIgorICAgICIgIGNvbS5nb29nbGUucHJvdG9idWYubmFuby5JbnRlcm5hbE5hbm8uJHZhbHVlX2Rlc2NfdHlwZSQsXG4iCisgICAgIiAgJHZhbHVlX2RlZmF1bHQkLFxuIgorICAgICIgICRrZXlfdGFnJCwgJHZhbHVlX3RhZyQpO1xuIgorICAgICJcbiIpOworfQorCit2b2lkIE1hcEZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKHRoaXMuJG5hbWUkICE9IG51bGwpIHtcbiIKKyAgICAiICBjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uSW50ZXJuYWxOYW5vLnNlcmlhbGl6ZU1hcEZpZWxkKFxuIgorICAgICIgICAgb3V0cHV0LCB0aGlzLiRuYW1lJCwgJG51bWJlciQsXG4iCisgICAgIiAgY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLkludGVybmFsTmFuby4ka2V5X2Rlc2NfdHlwZSQsXG4iCisgICAgIiAgY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLkludGVybmFsTmFuby4kdmFsdWVfZGVzY190eXBlJCk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIE1hcEZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICh0aGlzLiRuYW1lJCAhPSBudWxsKSB7XG4iCisgICAgIiAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uSW50ZXJuYWxOYW5vLmNvbXB1dGVNYXBGaWVsZFNpemUoXG4iCisgICAgIiAgICB0aGlzLiRuYW1lJCwgJG51bWJlciQsXG4iCisgICAgIiAgY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLkludGVybmFsTmFuby4ka2V5X2Rlc2NfdHlwZSQsXG4iCisgICAgIiAgY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLkludGVybmFsTmFuby4kdmFsdWVfZGVzY190eXBlJCk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIE1hcEZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoIWNvbS5nb29nbGUucHJvdG9idWYubmFuby5JbnRlcm5hbE5hbm8uZXF1YWxzKFxuIgorICAgICIgIHRoaXMuJG5hbWUkLCBvdGhlci4kbmFtZSQpKSB7XG4iCisgICAgIiAgcmV0dXJuIGZhbHNlO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBNYXBGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUhhc2hDb2RlQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJyZXN1bHQgPSAzMSAqIHJlc3VsdCArXG4iCisgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uSW50ZXJuYWxOYW5vLmhhc2hDb2RlKHRoaXMuJG5hbWUkKTtcbiIpOworfQorCit9ICAvLyBuYW1lc3BhY2UgamF2YW5hbm8KK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX21hcF9maWVsZC5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19tYXBfZmllbGQuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMDFiZGUzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19tYXBfZmllbGQuaApAQCAtMCwwICsxLDcwIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL3Byb3RvYnVmLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBTkFOT19NQVBfRklFTERfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBTkFOT19NQVBfRklFTERfSF9fCisKKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPHZlY3Rvcj4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZmllbGQuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhbmFubyB7CisKK2NsYXNzIE1hcEZpZWxkR2VuZXJhdG9yIDogcHVibGljIEZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IE1hcEZpZWxkR2VuZXJhdG9yKAorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBjb25zdCBQYXJhbXMmIHBhcmFtcyk7CisgIH5NYXBGaWVsZEdlbmVyYXRvcigpOworCisgIC8vIGltcGxlbWVudHMgRmllbGRHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIHZvaWQgR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyLCBib29sIGxhenlfaW5pdCkgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVDbGVhckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUVxdWFsc0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSGFzaENvZGVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKworIHByaXZhdGU6CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcl87CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyaWFibGVzXzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoTWFwRmllbGRHZW5lcmF0b3IpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGphdmFuYW5vCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQU5BTk9fTUFQX0ZJRUxEX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19tZXNzYWdlLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19tZXNzYWdlLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE0MWRhNWEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX21lc3NhZ2UuY2MKQEAgLTAsMCArMSw2NzYgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvcHJvdG9idWYvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8YWxnb3JpdGhtPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9oYXNoLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX21lc3NhZ2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZW51bS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19leHRlbnNpb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9faGVscGVycy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhbmFubyB7CisKK3VzaW5nIGludGVybmFsOjpXaXJlRm9ybWF0OwordXNpbmcgaW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOworCituYW1lc3BhY2UgeworCitzdHJ1Y3QgRmllbGRPcmRlcmluZ0J5TnVtYmVyIHsKKyAgaW5saW5lIGJvb2wgb3BlcmF0b3IoKShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBiKSBjb25zdCB7CisgICAgcmV0dXJuIGEtPm51bWJlcigpIDwgYi0+bnVtYmVyKCk7CisgIH0KK307CisKKy8vIFNvcnQgdGhlIGZpZWxkcyBvZiB0aGUgZ2l2ZW4gRGVzY3JpcHRvciBieSBudW1iZXIgaW50byBhIG5ld1tdJ2QgYXJyYXkKKy8vIGFuZCByZXR1cm4gaXQuCitjb25zdCBGaWVsZERlc2NyaXB0b3IqKiBTb3J0RmllbGRzQnlOdW1iZXIoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqKiBmaWVsZHMgPQorICAgIG5ldyBjb25zdCBGaWVsZERlc2NyaXB0b3IqW2Rlc2NyaXB0b3ItPmZpZWxkX2NvdW50KCldOworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3ItPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGZpZWxkc1tpXSA9IGRlc2NyaXB0b3ItPmZpZWxkKGkpOworICB9CisgIHNvcnQoZmllbGRzLCBmaWVsZHMgKyBkZXNjcmlwdG9yLT5maWVsZF9jb3VudCgpLAorICAgICAgIEZpZWxkT3JkZXJpbmdCeU51bWJlcigpKTsKKyAgcmV0dXJuIGZpZWxkczsKK30KKworfSAgLy8gbmFtZXNwYWNlCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworTWVzc2FnZUdlbmVyYXRvcjo6TWVzc2FnZUdlbmVyYXRvcihjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBjb25zdCBQYXJhbXMmIHBhcmFtcykKKyAgOiBwYXJhbXNfKHBhcmFtcyksCisgICAgZGVzY3JpcHRvcl8oZGVzY3JpcHRvciksCisgICAgZmllbGRfZ2VuZXJhdG9yc18oZGVzY3JpcHRvciwgcGFyYW1zKSB7Cit9CisKK01lc3NhZ2VHZW5lcmF0b3I6On5NZXNzYWdlR2VuZXJhdG9yKCkge30KKwordm9pZCBNZXNzYWdlR2VuZXJhdG9yOjpHZW5lcmF0ZVN0YXRpY1ZhcmlhYmxlcyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICAvLyBHZW5lcmF0ZSBzdGF0aWMgbWVtYmVycyBmb3IgYWxsIG5lc3RlZCB0eXBlcy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+bmVzdGVkX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgLy8gVE9ETyhrZW50b24pOiAgUmV1c2UgTWVzc2FnZUdlbmVyYXRvciBvYmplY3RzPworICAgIGlmIChJc01hcEVudHJ5KGRlc2NyaXB0b3JfLT5uZXN0ZWRfdHlwZShpKSkpIGNvbnRpbnVlOworICAgIE1lc3NhZ2VHZW5lcmF0b3IoZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlKGkpLCBwYXJhbXNfKQorICAgICAgLkdlbmVyYXRlU3RhdGljVmFyaWFibGVzKHByaW50ZXIpOworICB9Cit9CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6R2VuZXJhdGVTdGF0aWNWYXJpYWJsZUluaXRpYWxpemVycygKKyAgICBpbzo6UHJpbnRlciogcHJpbnRlcikgeworICAvLyBHZW5lcmF0ZSBzdGF0aWMgbWVtYmVyIGluaXRpYWxpemVycyBmb3IgYWxsIG5lc3RlZCB0eXBlcy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+bmVzdGVkX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAvLyBUT0RPKGtlbnRvbik6ICBSZXVzZSBNZXNzYWdlR2VuZXJhdG9yIG9iamVjdHM/CisgICAgaWYgKElzTWFwRW50cnkoZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlKGkpKSkgY29udGludWU7CisgICAgTWVzc2FnZUdlbmVyYXRvcihkZXNjcmlwdG9yXy0+bmVzdGVkX3R5cGUoaSksIHBhcmFtc18pCisgICAgICAuR2VuZXJhdGVTdGF0aWNWYXJpYWJsZUluaXRpYWxpemVycyhwcmludGVyKTsKKyAgfQorfQorCit2b2lkIE1lc3NhZ2VHZW5lcmF0b3I6OkdlbmVyYXRlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIGlmICghcGFyYW1zXy5zdG9yZV91bmtub3duX2ZpZWxkcygpICYmCisgICAgICAoZGVzY3JpcHRvcl8tPmV4dGVuc2lvbl9jb3VudCgpICE9IDAgfHwgZGVzY3JpcHRvcl8tPmV4dGVuc2lvbl9yYW5nZV9jb3VudCgpICE9IDApKSB7CisgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkV4dGVuc2lvbnMgYXJlIG9ubHkgc3VwcG9ydGVkIGluIE5BTk9fUlVOVElNRSBpZiB0aGUgIgorICAgICAgICAiJ3N0b3JlX3Vua25vd25fZmllbGRzJyBnZW5lcmF0b3Igb3B0aW9uIGlzICd0cnVlJ1xuIjsKKyAgfQorCisgIGNvbnN0IHN0cmluZyYgZmlsZV9uYW1lID0gZGVzY3JpcHRvcl8tPmZpbGUoKS0+bmFtZSgpOworICBib29sIGlzX293bl9maWxlID0KKyAgICBwYXJhbXNfLmphdmFfbXVsdGlwbGVfZmlsZXMoZmlsZV9uYW1lKQorICAgICAgJiYgZGVzY3JpcHRvcl8tPmNvbnRhaW5pbmdfdHlwZSgpID09IE5VTEw7CisKKyAgaWYgKGlzX293bl9maWxlKSB7CisgICAgLy8gTm90ZTogY29uc3RhbnRzIChmcm9tIGVudW1zIGFuZCBmaWVsZHMgcmVxdWlyaW5nIHN0b3JlZCBkZWZhdWx0cywgZW1pdHRlZCBpbiB0aGUgbG9vcCBiZWxvdykKKyAgICAvLyBtYXkgaGF2ZSB0aGUgc2FtZSBuYW1lcyBhcyBjb25zdGFudHMgaW4gdGhlIG5lc3RlZCBjbGFzc2VzLiBUaGlzIGNhdXNlcyBKYXZhIHdhcm5pbmdzLCBidXQKKyAgICAvLyBpcyBub3QgZmF0YWwsIHNvIHdlIHN1cHByZXNzIHRob3NlIHdhcm5pbmdzIGhlcmUgaW4gdGhlIHRvcC1tb3N0IGNsYXNzIGRlY2xhcmF0aW9uLgorICAgIHByaW50ZXItPlByaW50KAorICAgICAgIlxuIgorICAgICAgIkBTdXBwcmVzc1dhcm5pbmdzKFwiaGlkaW5nXCIpXG4iCisgICAgICAicHVibGljIGZpbmFsIGNsYXNzICRjbGFzc25hbWUkIGV4dGVuZHNcbiIsCisgICAgICAiY2xhc3NuYW1lIiwgZGVzY3JpcHRvcl8tPm5hbWUoKSk7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiXG4iCisgICAgICAicHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyAkY2xhc3NuYW1lJCBleHRlbmRzXG4iLAorICAgICAgImNsYXNzbmFtZSIsIGRlc2NyaXB0b3JfLT5uYW1lKCkpOworICB9CisgIGlmIChwYXJhbXNfLnN0b3JlX3Vua25vd25fZmllbGRzKCkgJiYgcGFyYW1zXy5wYXJjZWxhYmxlX21lc3NhZ2VzKCkpIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLmFuZHJvaWQuUGFyY2VsYWJsZUV4dGVuZGFibGVNZXNzYWdlTmFubzwkY2xhc3NuYW1lJD4iLAorICAgICAgImNsYXNzbmFtZSIsIGRlc2NyaXB0b3JfLT5uYW1lKCkpOworICB9IGVsc2UgaWYgKHBhcmFtc18uc3RvcmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uRXh0ZW5kYWJsZU1lc3NhZ2VOYW5vPCRjbGFzc25hbWUkPiIsCisgICAgICAiY2xhc3NuYW1lIiwgZGVzY3JpcHRvcl8tPm5hbWUoKSk7CisgIH0gZWxzZSBpZiAocGFyYW1zXy5wYXJjZWxhYmxlX21lc3NhZ2VzKCkpIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICIgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLmFuZHJvaWQuUGFyY2VsYWJsZU1lc3NhZ2VOYW5vIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiICAgIGNvbS5nb29nbGUucHJvdG9idWYubmFuby5NZXNzYWdlTmFubyIpOworICB9CisgIGlmIChwYXJhbXNfLmdlbmVyYXRlX2Nsb25lKCkpIHsKKyAgICBwcmludGVyLT5QcmludCgiIGltcGxlbWVudHMgamF2YS5sYW5nLkNsb25lYWJsZSB7XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCgiIHtcbiIpOworICB9CisgIHByaW50ZXItPkluZGVudCgpOworCisgIGlmIChwYXJhbXNfLnBhcmNlbGFibGVfbWVzc2FnZXMoKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIlxuIgorICAgICAgIi8vIFVzZWQgYnkgUGFyY2VsYWJsZVxuIgorICAgICAgIkBTdXBwcmVzc1dhcm5pbmdzKHtcInVudXNlZFwifSlcbiIKKyAgICAgICJwdWJsaWMgc3RhdGljIGZpbmFsIGFuZHJvaWQub3MuUGFyY2VsYWJsZS5DcmVhdG9yPCRjbGFzc25hbWUkPiBDUkVBVE9SID1cbiIKKyAgICAgICIgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYubmFuby5hbmRyb2lkLlBhcmNlbGFibGVNZXNzYWdlTmFub0NyZWF0b3I8XG4iCisgICAgICAiICAgICAgICAkY2xhc3NuYW1lJD4oJGNsYXNzbmFtZSQuY2xhc3MpO1xuIiwKKyAgICAgICJjbGFzc25hbWUiLCBkZXNjcmlwdG9yXy0+bmFtZSgpKTsKKyAgfQorCisgIC8vIE5lc3RlZCB0eXBlcyBhbmQgZXh0ZW5zaW9ucworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5leHRlbnNpb25fY291bnQoKTsgaSsrKSB7CisgICAgRXh0ZW5zaW9uR2VuZXJhdG9yKGRlc2NyaXB0b3JfLT5leHRlbnNpb24oaSksIHBhcmFtc18pLkdlbmVyYXRlKHByaW50ZXIpOworICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZW51bV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIEVudW1HZW5lcmF0b3IoZGVzY3JpcHRvcl8tPmVudW1fdHlwZShpKSwgcGFyYW1zXykuR2VuZXJhdGUocHJpbnRlcik7CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5uZXN0ZWRfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBpZiAoSXNNYXBFbnRyeShkZXNjcmlwdG9yXy0+bmVzdGVkX3R5cGUoaSkpKSBjb250aW51ZTsKKyAgICBNZXNzYWdlR2VuZXJhdG9yKGRlc2NyaXB0b3JfLT5uZXN0ZWRfdHlwZShpKSwgcGFyYW1zXykuR2VuZXJhdGUocHJpbnRlcik7CisgIH0KKworICAvLyBvbmVvZgorICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcnM7CisgIHZhcnNbIm1lc3NhZ2VfbmFtZSJdID0gZGVzY3JpcHRvcl8tPm5hbWUoKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBPbmVvZkRlc2NyaXB0b3IqIG9uZW9mX2Rlc2MgPSBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbChpKTsKKyAgICB2YXJzWyJvbmVvZl9uYW1lIl0gPSBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlKG9uZW9mX2Rlc2MpOworICAgIHZhcnNbIm9uZW9mX2NhcGl0YWxpemVkX25hbWUiXSA9CisgICAgICAgIFVuZGVyc2NvcmVzVG9DYXBpdGFsaXplZENhbWVsQ2FzZShvbmVvZl9kZXNjKTsKKyAgICB2YXJzWyJvbmVvZl9pbmRleCJdID0gU2ltcGxlSXRvYShvbmVvZl9kZXNjLT5pbmRleCgpKTsKKyAgICAvLyBPbmVvZiBDb25zdGFudHMKKyAgICBmb3IgKGludCBqID0gMDsgaiA8IG9uZW9mX2Rlc2MtPmZpZWxkX2NvdW50KCk7IGorKykgeworICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IG9uZW9mX2Rlc2MtPmZpZWxkKGopOworICAgICAgdmFyc1sibnVtYmVyIl0gPSBTaW1wbGVJdG9hKGZpZWxkLT5udW1iZXIoKSk7CisgICAgICB2YXJzWyJjYXBfZmllbGRfbmFtZSJdID0gVG9VcHBlcihmaWVsZC0+bmFtZSgpKTsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAgICJwdWJsaWMgc3RhdGljIGZpbmFsIGludCAkY2FwX2ZpZWxkX25hbWUkX0ZJRUxEX05VTUJFUiA9ICRudW1iZXIkO1xuIik7CisgICAgfQorICAgIC8vIG9uZW9mQ2FzZV8gYW5kIG9uZW9mXworICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAicHJpdmF0ZSBpbnQgJG9uZW9mX25hbWUkQ2FzZV8gPSAwO1xuIgorICAgICAgInByaXZhdGUgamF2YS5sYW5nLk9iamVjdCAkb25lb2ZfbmFtZSRfO1xuIik7CisgICAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICJwdWJsaWMgaW50IGdldCRvbmVvZl9jYXBpdGFsaXplZF9uYW1lJENhc2UoKSB7XG4iCisgICAgICAiICByZXR1cm4gdGhpcy4kb25lb2ZfbmFtZSRDYXNlXztcbiIKKyAgICAgICJ9XG4iKTsKKyAgICAvLyBPbmVvZiBjbGVhcgorICAgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAicHVibGljICRtZXNzYWdlX25hbWUkIGNsZWFyJG9uZW9mX2NhcGl0YWxpemVkX25hbWUkKCkge1xuIgorICAgICAgIiAgdGhpcy4kb25lb2ZfbmFtZSRDYXNlXyA9IDA7XG4iCisgICAgICAiICB0aGlzLiRvbmVvZl9uYW1lJF8gPSBudWxsO1xuIgorICAgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgICAifVxuIik7CisgIH0KKworICAvLyBMYXp5IGluaXRpYWxpemF0aW9uIG9mIG90aGVyd2lzZSBzdGF0aWMgZmluYWwgZmllbGRzIGNhbiBoZWxwIHByZXZlbnQgdGhlCisgIC8vIGNsYXNzIGluaXRpYWxpemVyIGZyb20gYmVpbmcgZ2VuZXJhdGVkLiBXZSB3YW50IHRvIHByZXZlbnQgaXQgYmVjYXVzZSBpdAorICAvLyBzdG9wcyBQcm9HdWFyZCBmcm9tIGlubGluaW5nIGFueSBtZXRob2RzIGluIHRoaXMgY2xhc3MgaW50byBjYWxsIHNpdGVzIGFuZAorICAvLyB0aGVyZWZvcmUgcmVkdWNpbmcgdGhlIG1ldGhvZCBjb3VudC4gSG93ZXZlciwgZXh0ZW5zaW9ucyBhcmUgYmVzdCBrZXB0IGFzCisgIC8vIHB1YmxpYyBzdGF0aWMgZmluYWwgZmllbGRzIHdpdGggaW5pdGlhbGl6ZXJzLCBzbyB3aXRoIHRoZWlyIGV4aXN0ZW5jZSB3ZQorICAvLyB3b24ndCBib3RoZXIgd2l0aCBsYXp5IGluaXRpYWxpemF0aW9uLgorICBib29sIGxhenlfaW5pdCA9IGRlc2NyaXB0b3JfLT5leHRlbnNpb25fY291bnQoKSA9PSAwOworCisgIC8vIEVtcHR5IGFycmF5CisgIGlmIChsYXp5X2luaXQpIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJcbiIKKyAgICAgICJwcml2YXRlIHN0YXRpYyB2b2xhdGlsZSAkY2xhc3NuYW1lJFtdIF9lbXB0eUFycmF5O1xuIgorICAgICAgInB1YmxpYyBzdGF0aWMgJGNsYXNzbmFtZSRbXSBlbXB0eUFycmF5KCkge1xuIgorICAgICAgIiAgLy8gTGF6aWx5IGluaXRpYWxpemVzIHRoZSBlbXB0eSBhcnJheVxuIgorICAgICAgIiAgaWYgKF9lbXB0eUFycmF5ID09IG51bGwpIHtcbiIKKyAgICAgICIgICAgc3luY2hyb25pemVkIChcbiIKKyAgICAgICIgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYubmFuby5JbnRlcm5hbE5hbm8uTEFaWV9JTklUX0xPQ0spIHtcbiIKKyAgICAgICIgICAgICBpZiAoX2VtcHR5QXJyYXkgPT0gbnVsbCkge1xuIgorICAgICAgIiAgICAgICAgX2VtcHR5QXJyYXkgPSBuZXcgJGNsYXNzbmFtZSRbMF07XG4iCisgICAgICAiICAgICAgfVxuIgorICAgICAgIiAgICB9XG4iCisgICAgICAiICB9XG4iCisgICAgICAiICByZXR1cm4gX2VtcHR5QXJyYXk7XG4iCisgICAgICAifVxuIiwKKyAgICAgICJjbGFzc25hbWUiLCBkZXNjcmlwdG9yXy0+bmFtZSgpKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJcbiIKKyAgICAgICJwcml2YXRlIHN0YXRpYyBmaW5hbCAkY2xhc3NuYW1lJFtdIEVNUFRZX0FSUkFZID0ge307XG4iCisgICAgICAicHVibGljIHN0YXRpYyAkY2xhc3NuYW1lJFtdIGVtcHR5QXJyYXkoKSB7XG4iCisgICAgICAiICByZXR1cm4gRU1QVFlfQVJSQVk7XG4iCisgICAgICAifVxuIiwKKyAgICAgICJjbGFzc25hbWUiLCBkZXNjcmlwdG9yXy0+bmFtZSgpKTsKKyAgfQorCisgIC8vIEludGVnZXJzIGZvciBiaXQgZmllbGRzCisgIGludCB0b3RhbEludHMgPSAoZmllbGRfZ2VuZXJhdG9yc18udG90YWxfYml0cygpICsgMzEpIC8gMzI7CisgIGlmICh0b3RhbEludHMgPiAwKSB7CisgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0b3RhbEludHM7IGkrKykgeworICAgICAgcHJpbnRlci0+UHJpbnQoInByaXZhdGUgaW50ICRiaXRfZmllbGRfbmFtZSQ7XG4iLAorICAgICAgICAiYml0X2ZpZWxkX25hbWUiLCBHZXRCaXRGaWVsZE5hbWUoaSkpOworICAgIH0KKyAgfQorCisgIC8vIEZpZWxkcyBhbmQgbWF5YmUgdGhlaXIgZGVmYXVsdCB2YWx1ZXMKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisgICAgUHJpbnRGaWVsZENvbW1lbnQocHJpbnRlciwgZGVzY3JpcHRvcl8tPmZpZWxkKGkpKTsKKyAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZGVzY3JpcHRvcl8tPmZpZWxkKGkpKS5HZW5lcmF0ZU1lbWJlcnMoCisgICAgICAgIHByaW50ZXIsIGxhenlfaW5pdCk7CisgIH0KKworICAvLyBDb25zdHJ1Y3Rvciwgd2l0aCBsYXp5IGluaXQgY29kZSBpZiBuZWVkZWQKKyAgaWYgKGxhenlfaW5pdCAmJiBmaWVsZF9nZW5lcmF0b3JzXy5zYXZlZF9kZWZhdWx0c19uZWVkZWQoKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIlxuIgorICAgICAgInByaXZhdGUgc3RhdGljIHZvbGF0aWxlIGJvb2xlYW4gX2NsYXNzSW5pdGlhbGl6ZWQ7XG4iCisgICAgICAiXG4iCisgICAgICAicHVibGljICRjbGFzc25hbWUkKCkge1xuIgorICAgICAgIiAgLy8gTGF6aWx5IGluaXRpYWxpemVzIHRoZSBmaWVsZCBkZWZhdWx0c1xuIgorICAgICAgIiAgaWYgKCFfY2xhc3NJbml0aWFsaXplZCkge1xuIgorICAgICAgIiAgICBzeW5jaHJvbml6ZWQgKFxuIgorICAgICAgIiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLkludGVybmFsTmFuby5MQVpZX0lOSVRfTE9DSykge1xuIgorICAgICAgIiAgICAgIGlmICghX2NsYXNzSW5pdGlhbGl6ZWQpIHtcbiIsCisgICAgICAiY2xhc3NuYW1lIiwgZGVzY3JpcHRvcl8tPm5hbWUoKSk7CisgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZGVzY3JpcHRvcl8tPmZpZWxkKGkpKQorICAgICAgICAgIC5HZW5lcmF0ZUluaXRTYXZlZERlZmF1bHRDb2RlKHByaW50ZXIpOworICAgIH0KKyAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiICAgICAgICBfY2xhc3NJbml0aWFsaXplZCA9IHRydWU7XG4iCisgICAgICAiICAgICAgfVxuIgorICAgICAgIiAgICB9XG4iCisgICAgICAiICB9XG4iKTsKKyAgICBpZiAocGFyYW1zXy5nZW5lcmF0ZV9jbGVhcigpKSB7CisgICAgICBwcmludGVyLT5QcmludCgiICBjbGVhcigpO1xuIik7CisgICAgfQorICAgIHByaW50ZXItPlByaW50KCJ9XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJcbiIKKyAgICAgICJwdWJsaWMgJGNsYXNzbmFtZSQoKSB7XG4iLAorICAgICAgImNsYXNzbmFtZSIsIGRlc2NyaXB0b3JfLT5uYW1lKCkpOworICAgIGlmIChwYXJhbXNfLmdlbmVyYXRlX2NsZWFyKCkpIHsKKyAgICAgIHByaW50ZXItPlByaW50KCIgIGNsZWFyKCk7XG4iKTsKKyAgICB9IGVsc2UgeworICAgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgICBHZW5lcmF0ZUZpZWxkSW5pdGlhbGl6ZXJzKHByaW50ZXIpOworICAgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIH0KKyAgICBwcmludGVyLT5QcmludCgifVxuIik7CisgIH0KKworICAvLyBPdGhlciBtZXRob2RzIGluIHRoaXMgY2xhc3MKKworICBHZW5lcmF0ZUNsZWFyKHByaW50ZXIpOworCisgIGlmIChwYXJhbXNfLmdlbmVyYXRlX2Nsb25lKCkpIHsKKyAgICBHZW5lcmF0ZUNsb25lKHByaW50ZXIpOworICB9CisKKyAgaWYgKHBhcmFtc18uZ2VuZXJhdGVfZXF1YWxzKCkpIHsKKyAgICBHZW5lcmF0ZUVxdWFscyhwcmludGVyKTsKKyAgICBHZW5lcmF0ZUhhc2hDb2RlKHByaW50ZXIpOworICB9CisKKyAgR2VuZXJhdGVNZXNzYWdlU2VyaWFsaXphdGlvbk1ldGhvZHMocHJpbnRlcik7CisgIEdlbmVyYXRlTWVyZ2VGcm9tTWV0aG9kcyhwcmludGVyKTsKKyAgR2VuZXJhdGVQYXJzZUZyb21NZXRob2RzKHByaW50ZXIpOworCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lc3NhZ2VTZXJpYWxpemF0aW9uTWV0aG9kcyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICAvLyBSZWx5IG9uIHRoZSBwYXJlbnQgaW1wbGVtZW50YXRpb25zIG9mIHdyaXRlVG8oKSBhbmQgZ2V0U2VyaWFsaXplZFNpemUoKQorICAvLyBpZiB0aGVyZSBhcmUgbm8gZmllbGRzIHRvIHNlcmlhbGl6ZSBpbiB0aGlzIG1lc3NhZ2UuCisgIGlmIChkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKSA9PSAwKSB7CisgICAgcmV0dXJuOworICB9CisKKyAgc2NvcGVkX2FycmF5PGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+IHNvcnRlZF9maWVsZHMoCisgICAgU29ydEZpZWxkc0J5TnVtYmVyKGRlc2NyaXB0b3JfKSk7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIlxuIgorICAgICJAT3ZlcnJpZGVcbiIKKyAgICAicHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFubyBvdXRwdXQpXG4iCisgICAgIiAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgLy8gT3V0cHV0IHRoZSBmaWVsZHMgaW4gc29ydGVkIG9yZGVyCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIEdlbmVyYXRlU2VyaWFsaXplT25lRmllbGQocHJpbnRlciwgc29ydGVkX2ZpZWxkc1tpXSk7CisgIH0KKworICAvLyBUaGUgcGFyZW50IGltcGxlbWVudGF0aW9uIHdpbGwgd3JpdGUgYW55IHVua25vd24gZmllbGRzIGlmIG5lY2Vzc2FyeS4KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgInN1cGVyLndyaXRlVG8ob3V0cHV0KTtcbiIpOworCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworCisgIC8vIFRoZSBwYXJlbnQgaW1wbGVtZW50YXRpb24gd2lsbCBnZXQgdGhlIHNlcmlhbGl6ZWQgc2l6ZSBmb3IgdW5rbm93bgorICAvLyBmaWVsZHMgaWYgbmVjZXNzYXJ5LgorICBwcmludGVyLT5QcmludCgKKyAgICAiXG4iCisgICAgIkBPdmVycmlkZVxuIgorICAgICJwcm90ZWN0ZWQgaW50IGNvbXB1dGVTZXJpYWxpemVkU2l6ZSgpIHtcbiIKKyAgICAiICBpbnQgc2l6ZSA9IHN1cGVyLmNvbXB1dGVTZXJpYWxpemVkU2l6ZSgpO1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChzb3J0ZWRfZmllbGRzW2ldKS5HZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShwcmludGVyKTsKKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIiAgcmV0dXJuIHNpemU7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIE1lc3NhZ2VHZW5lcmF0b3I6OkdlbmVyYXRlTWVyZ2VGcm9tTWV0aG9kcyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBzY29wZWRfYXJyYXk8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4gc29ydGVkX2ZpZWxkcygKKyAgICBTb3J0RmllbGRzQnlOdW1iZXIoZGVzY3JpcHRvcl8pKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAiXG4iCisgICAgIkBPdmVycmlkZVxuIgorICAgICJwdWJsaWMgJGNsYXNzbmFtZSQgbWVyZ2VGcm9tKFxuIgorICAgICIgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYubmFuby5Db2RlZElucHV0Qnl0ZUJ1ZmZlck5hbm8gaW5wdXQpXG4iCisgICAgIiAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7XG4iLAorICAgICJjbGFzc25hbWUiLCBkZXNjcmlwdG9yXy0+bmFtZSgpKTsKKworICBwcmludGVyLT5JbmRlbnQoKTsKKyAgaWYgKEhhc01hcEZpZWxkKGRlc2NyaXB0b3JfKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgImNvbS5nb29nbGUucHJvdG9idWYubmFuby5NYXBGYWN0b3JpZXMuTWFwRmFjdG9yeSBtYXBGYWN0b3J5ID1cbiIKKyAgICAgICIgIGNvbS5nb29nbGUucHJvdG9idWYubmFuby5NYXBGYWN0b3JpZXMuZ2V0TWFwRmFjdG9yeSgpO1xuIik7CisgIH0KKworICBwcmludGVyLT5QcmludCgKKyAgICAid2hpbGUgKHRydWUpIHtcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAiaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTtcbiIKKyAgICAic3dpdGNoICh0YWcpIHtcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAiY2FzZSAwOlxuIiAgICAgICAgICAvLyB6ZXJvIHNpZ25hbHMgRU9GIC8gbGltaXQgcmVhY2hlZAorICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICJkZWZhdWx0OiB7XG4iKTsKKworICBwcmludGVyLT5JbmRlbnQoKTsKKyAgaWYgKHBhcmFtc18uc3RvcmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiaWYgKCFzdG9yZVVua25vd25GaWVsZChpbnB1dCwgdGFnKSkge1xuIgorICAgICAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAgICAgIn1cbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiaWYgKCFjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uV2lyZUZvcm1hdE5hbm8ucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIHRhZykpIHtcbiIKKyAgICAgICAgIiAgcmV0dXJuIHRoaXM7XG4iICAgLy8gaXQncyBhbiBlbmRncm91cCB0YWcKKyAgICAgICAgIn1cbiIpOworICB9CisgIHByaW50ZXItPlByaW50KCJicmVhaztcbiIpOworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KCJ9XG4iKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gc29ydGVkX2ZpZWxkc1tpXTsKKyAgICB1aW50MzIgdGFnID0gV2lyZUZvcm1hdExpdGU6Ok1ha2VUYWcoZmllbGQtPm51bWJlcigpLAorICAgICAgV2lyZUZvcm1hdDo6V2lyZVR5cGVGb3JGaWVsZFR5cGUoZmllbGQtPnR5cGUoKSkpOworCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiY2FzZSAkdGFnJDoge1xuIiwKKyAgICAgICJ0YWciLCBTaW1wbGVJdG9hKHRhZykpOworICAgIHByaW50ZXItPkluZGVudCgpOworCisgICAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGZpZWxkKS5HZW5lcmF0ZU1lcmdpbmdDb2RlKHByaW50ZXIpOworCisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIiAgYnJlYWs7XG4iCisgICAgICAifVxuIik7CisKKyAgICBpZiAoZmllbGQtPmlzX3BhY2thYmxlKCkpIHsKKyAgICAgIC8vIFRvIG1ha2UgcGFja2VkID0gdHJ1ZSB3aXJlIGNvbXBhdGlibGUsIHdlIGdlbmVyYXRlIHBhcnNpbmcgY29kZSBmcm9tIGEKKyAgICAgIC8vIHBhY2tlZCB2ZXJzaW9uIG9mIHRoaXMgZmllbGQgcmVnYXJkbGVzcyBvZiBmaWVsZC0+b3B0aW9ucygpLnBhY2tlZCgpLgorICAgICAgdWludDMyIHBhY2tlZF90YWcgPSBXaXJlRm9ybWF0TGl0ZTo6TWFrZVRhZyhmaWVsZC0+bnVtYmVyKCksCisgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVEKTsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiY2FzZSAkdGFnJDoge1xuIiwKKyAgICAgICAgInRhZyIsIFNpbXBsZUl0b2EocGFja2VkX3RhZykpOworICAgICAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChmaWVsZCkuR2VuZXJhdGVNZXJnaW5nQ29kZUZyb21QYWNrZWQocHJpbnRlcik7CisKKyAgICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiICBicmVhaztcbiIKKyAgICAgICAgIn1cbiIpOworICAgIH0KKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KAorICAgICIgICAgfVxuIiAgICAgLy8gc3dpdGNoICh0YWcpCisgICAgIiAgfVxuIiAgICAgICAvLyB3aGlsZSAodHJ1ZSkKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6CitHZW5lcmF0ZVBhcnNlRnJvbU1ldGhvZHMoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgLy8gTm90ZTogIFRoZXNlIGFyZSBzZXBhcmF0ZSBmcm9tIEdlbmVyYXRlTWVzc2FnZVNlcmlhbGl6YXRpb25NZXRob2RzKCkKKyAgLy8gICBiZWNhdXNlIHRoZXkgbmVlZCB0byBiZSBnZW5lcmF0ZWQgZXZlbiBmb3IgbWVzc2FnZXMgdGhhdCBhcmUgb3B0aW1pemVkCisgIC8vICAgZm9yIGNvZGUgc2l6ZS4KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIlxuIgorICAgICJwdWJsaWMgc3RhdGljICRjbGFzc25hbWUkIHBhcnNlRnJvbShieXRlW10gZGF0YSlcbiIKKyAgICAiICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uSW52YWxpZFByb3RvY29sQnVmZmVyTmFub0V4Y2VwdGlvbiB7XG4iCisgICAgIiAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYubmFuby5NZXNzYWdlTmFuby5tZXJnZUZyb20obmV3ICRjbGFzc25hbWUkKCksIGRhdGEpO1xuIgorICAgICJ9XG4iCisgICAgIlxuIgorICAgICJwdWJsaWMgc3RhdGljICRjbGFzc25hbWUkIHBhcnNlRnJvbShcbiIKKyAgICAiICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uQ29kZWRJbnB1dEJ5dGVCdWZmZXJOYW5vIGlucHV0KVxuIgorICAgICIgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24ge1xuIgorICAgICIgIHJldHVybiBuZXcgJGNsYXNzbmFtZSQoKS5tZXJnZUZyb20oaW5wdXQpO1xuIgorICAgICJ9XG4iLAorICAgICJjbGFzc25hbWUiLCBkZXNjcmlwdG9yXy0+bmFtZSgpKTsKK30KKwordm9pZCBNZXNzYWdlR2VuZXJhdG9yOjpHZW5lcmF0ZVNlcmlhbGl6ZU9uZUZpZWxkKAorICAgIGlvOjpQcmludGVyKiBwcmludGVyLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChmaWVsZCkuR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShwcmludGVyKTsKK30KKwordm9pZCBNZXNzYWdlR2VuZXJhdG9yOjpHZW5lcmF0ZUNsZWFyKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIGlmICghcGFyYW1zXy5nZW5lcmF0ZV9jbGVhcigpKSB7CisgICAgcmV0dXJuOworICB9CisgIHByaW50ZXItPlByaW50KAorICAgICJcbiIKKyAgICAicHVibGljICRjbGFzc25hbWUkIGNsZWFyKCkge1xuIiwKKyAgICAiY2xhc3NuYW1lIiwgZGVzY3JpcHRvcl8tPm5hbWUoKSk7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIEdlbmVyYXRlRmllbGRJbml0aWFsaXplcnMocHJpbnRlcik7CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAiICByZXR1cm4gdGhpcztcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6R2VuZXJhdGVGaWVsZEluaXRpYWxpemVycyhpbzo6UHJpbnRlciogcHJpbnRlcikgeworICAvLyBDbGVhciBiaXQgZmllbGRzLgorICBpbnQgdG90YWxJbnRzID0gKGZpZWxkX2dlbmVyYXRvcnNfLnRvdGFsX2JpdHMoKSArIDMxKSAvIDMyOworICBmb3IgKGludCBpID0gMDsgaSA8IHRvdGFsSW50czsgaSsrKSB7CisgICAgcHJpbnRlci0+UHJpbnQoIiRiaXRfZmllbGRfbmFtZSQgPSAwO1xuIiwKKyAgICAgICJiaXRfZmllbGRfbmFtZSIsIEdldEJpdEZpZWxkTmFtZShpKSk7CisgIH0KKworICAvLyBDYWxsIGNsZWFyIGZvciBhbGwgb2YgdGhlIGZpZWxkcy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3JfLT5maWVsZChpKTsKKyAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZmllbGQpLkdlbmVyYXRlQ2xlYXJDb2RlKHByaW50ZXIpOworICB9CisKKyAgLy8gQ2xlYXIgb25lb2ZzLgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsX2NvdW50KCk7IGkrKykgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgImNsZWFyJG9uZW9mX2NhcGl0YWxpemVkX25hbWUkKCk7XG4iLAorICAgICAgIm9uZW9mX2NhcGl0YWxpemVkX25hbWUiLCBVbmRlcnNjb3Jlc1RvQ2FwaXRhbGl6ZWRDYW1lbENhc2UoCisgICAgICAgICAgZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2woaSkpKTsKKyAgfQorCisgIC8vIENsZWFyIHVua25vd24gZmllbGRzLgorICBpZiAocGFyYW1zXy5zdG9yZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgcHJpbnRlci0+UHJpbnQoInVua25vd25GaWVsZERhdGEgPSBudWxsO1xuIik7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQoImNhY2hlZFNpemUgPSAtMTtcbiIpOworfQorCit2b2lkIE1lc3NhZ2VHZW5lcmF0b3I6OkdlbmVyYXRlQ2xvbmUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIkBPdmVycmlkZVxuIgorICAgICJwdWJsaWMgJGNsYXNzbmFtZSQgY2xvbmUoKSB7XG4iLAorICAgICJjbGFzc25hbWUiLCBkZXNjcmlwdG9yXy0+bmFtZSgpKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIiRjbGFzc25hbWUkIGNsb25lZDtcbiIKKyAgICAidHJ5IHtcbiIKKyAgICAiICBjbG9uZWQgPSAoJGNsYXNzbmFtZSQpIHN1cGVyLmNsb25lKCk7XG4iCisgICAgIn0gY2F0Y2ggKGphdmEubGFuZy5DbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7XG4iCisgICAgIiAgdGhyb3cgbmV3IGphdmEubGFuZy5Bc3NlcnRpb25FcnJvcihlKTtcbiIKKyAgICAifVxuIiwKKyAgICAiY2xhc3NuYW1lIiwgZGVzY3JpcHRvcl8tPm5hbWUoKSk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGRlc2NyaXB0b3JfLT5maWVsZChpKSkuR2VuZXJhdGVGaXhDbG9uZWRDb2RlKHByaW50ZXIpOworICB9CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAiICByZXR1cm4gY2xvbmVkO1xuIgorICAgICJ9XG4iCisgICAgIlxuIik7Cit9CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6R2VuZXJhdGVFcXVhbHMoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgLy8gRG9uJ3Qgb3ZlcnJpZGUgaWYgdGhlcmUgYXJlIG5vIGZpZWxkcy4gV2UgY291bGQgZ2VuZXJhdGUgYW4KKyAgLy8gZXF1YWxzIG1ldGhvZCB0aGF0IGNvbXBhcmVzIHR5cGVzLCBidXQgb2Z0ZW4gZW1wdHkgbWVzc2FnZXMKKyAgLy8gYXJlIHVzZWQgYXMgbmFtZXNwYWNlcy4KKyAgaWYgKGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpID09IDAgJiYgIXBhcmFtc18uc3RvcmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHJldHVybjsKKyAgfQorCisgIHByaW50ZXItPlByaW50KAorICAgICJcbiIKKyAgICAiQE92ZXJyaWRlXG4iCisgICAgInB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgbykge1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAiaWYgKG8gPT0gdGhpcykge1xuIgorICAgICIgIHJldHVybiB0cnVlO1xuIgorICAgICJ9XG4iCisgICAgImlmICghKG8gaW5zdGFuY2VvZiAkY2xhc3NuYW1lJCkpIHtcbiIKKyAgICAiICByZXR1cm4gZmFsc2U7XG4iCisgICAgIn1cbiIKKyAgICAiJGNsYXNzbmFtZSQgb3RoZXIgPSAoJGNsYXNzbmFtZSQpIG87XG4iLAorICAgICJjbGFzc25hbWUiLCBkZXNjcmlwdG9yXy0+bmFtZSgpKTsKKworICAvLyBDaGVja2luZyBvbmVvZiBjYXNlIGJlZm9yZSBjaGVja2luZyBlYWNoIG9uZW9mIGZpZWxkLgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IE9uZW9mRGVzY3JpcHRvciogb25lb2ZfZGVzYyA9IGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgImlmICh0aGlzLiRvbmVvZl9uYW1lJENhc2VfICE9IG90aGVyLiRvbmVvZl9uYW1lJENhc2VfKSB7XG4iCisgICAgICAiICByZXR1cm4gZmFsc2U7XG4iCisgICAgICAifVxuIiwKKyAgICAgICJvbmVvZl9uYW1lIiwgVW5kZXJzY29yZXNUb0NhbWVsQ2FzZShvbmVvZl9kZXNjKSk7CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvcl8tPmZpZWxkKGkpOworICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChmaWVsZCkuR2VuZXJhdGVFcXVhbHNDb2RlKHByaW50ZXIpOworICB9CisKKyAgaWYgKHBhcmFtc18uc3RvcmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgImlmICh1bmtub3duRmllbGREYXRhID09IG51bGwgfHwgdW5rbm93bkZpZWxkRGF0YS5pc0VtcHR5KCkpIHtcbiIKKyAgICAgICIgIHJldHVybiBvdGhlci51bmtub3duRmllbGREYXRhID09IG51bGwgfHwgb3RoZXIudW5rbm93bkZpZWxkRGF0YS5pc0VtcHR5KCk7XG4iCisgICAgICAifSBlbHNlIHtcbiIKKyAgICAgICIgIHJldHVybiB1bmtub3duRmllbGREYXRhLmVxdWFscyhvdGhlci51bmtub3duRmllbGREYXRhKTtcbiIKKyAgICAgICJ9Iik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAicmV0dXJuIHRydWU7XG4iKTsKKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoIn1cbiIpOworfQorCit2b2lkIE1lc3NhZ2VHZW5lcmF0b3I6OkdlbmVyYXRlSGFzaENvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgaWYgKGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpID09IDAgJiYgIXBhcmFtc18uc3RvcmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHJldHVybjsKKyAgfQorCisgIHByaW50ZXItPlByaW50KAorICAgICJcbiIKKyAgICAiQE92ZXJyaWRlXG4iCisgICAgInB1YmxpYyBpbnQgaGFzaENvZGUoKSB7XG4iKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgcHJpbnRlci0+UHJpbnQoImludCByZXN1bHQgPSAxNztcbiIpOworICBwcmludGVyLT5QcmludCgicmVzdWx0ID0gMzEgKiByZXN1bHQgKyBnZXRDbGFzcygpLmdldE5hbWUoKS5oYXNoQ29kZSgpO1xuIik7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBkZXNjcmlwdG9yXy0+ZmllbGQoaSk7CisgICAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGZpZWxkKS5HZW5lcmF0ZUhhc2hDb2RlQ29kZShwcmludGVyKTsKKyAgfQorCisgIGlmIChwYXJhbXNfLnN0b3JlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJyZXN1bHQgPSAzMSAqIHJlc3VsdCArIFxuIgorICAgICAgIiAgKHVua25vd25GaWVsZERhdGEgPT0gbnVsbCB8fCB1bmtub3duRmllbGREYXRhLmlzRW1wdHkoKSA/IDAgOiBcbiIKKyAgICAgICIgIHVua25vd25GaWVsZERhdGEuaGFzaENvZGUoKSk7XG4iKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KCJyZXR1cm4gcmVzdWx0O1xuIik7CisKKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgifVxuIik7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworfSAgLy8gbmFtZXNwYWNlIGphdmFuYW5vCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19tZXNzYWdlLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX21lc3NhZ2UuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yODFlYzY0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19tZXNzYWdlLmgKQEAgLTAsMCArMSw5NyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9wcm90b2J1Zi8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFOQU5PX01FU1NBR0VfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBTkFOT19NRVNTQUdFX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX3BhcmFtcy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworICBuYW1lc3BhY2UgaW8geworICAgIGNsYXNzIFByaW50ZXI7ICAgICAgICAgICAgIC8vIHByaW50ZXIuaAorICB9Cit9CisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGphdmFuYW5vIHsKKworY2xhc3MgTWVzc2FnZUdlbmVyYXRvciB7CisgcHVibGljOgorICBleHBsaWNpdCBNZXNzYWdlR2VuZXJhdG9yKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGNvbnN0IFBhcmFtcyYgcGFyYW1zKTsKKyAgfk1lc3NhZ2VHZW5lcmF0b3IoKTsKKworICAvLyBBbGwgc3RhdGljIHZhcmlhYmxlcyBoYXZlIHRvIGJlIGRlY2xhcmVkIGF0IHRoZSB0b3AtbGV2ZWwgb2YgdGhlIGZpbGUKKyAgLy8gc28gdGhhdCB3ZSBjYW4gY29udHJvbCBpbml0aWFsaXphdGlvbiBvcmRlciwgd2hpY2ggaXMgaW1wb3J0YW50IGZvcgorICAvLyBEZXNjcmlwdG9yUHJvdG8gYm9vdHN0cmFwcGluZyB0byB3b3JrLgorICB2b2lkIEdlbmVyYXRlU3RhdGljVmFyaWFibGVzKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworICAvLyBPdXRwdXQgY29kZSB3aGljaCBpbml0aWFsaXplcyB0aGUgc3RhdGljIHZhcmlhYmxlcyBnZW5lcmF0ZWQgYnkKKyAgLy8gR2VuZXJhdGVTdGF0aWNWYXJpYWJsZXMoKS4KKyAgdm9pZCBHZW5lcmF0ZVN0YXRpY1ZhcmlhYmxlSW5pdGlhbGl6ZXJzKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworICAvLyBHZW5lcmF0ZSB0aGUgY2xhc3MgaXRzZWxmLgorICB2b2lkIEdlbmVyYXRlKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworIHByaXZhdGU6CisgIHZvaWQgR2VuZXJhdGVNZXNzYWdlU2VyaWFsaXphdGlvbk1ldGhvZHMoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2b2lkIEdlbmVyYXRlTWVyZ2VGcm9tTWV0aG9kcyhpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZvaWQgR2VuZXJhdGVQYXJzZUZyb21NZXRob2RzKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZU9uZUZpZWxkKGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCk7CisKKyAgdm9pZCBHZW5lcmF0ZUNsZWFyKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdm9pZCBHZW5lcmF0ZUZpZWxkSW5pdGlhbGl6ZXJzKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdm9pZCBHZW5lcmF0ZUVxdWFscyhpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZvaWQgR2VuZXJhdGVIYXNoQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZvaWQgR2VuZXJhdGVDbG9uZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyAgY29uc3QgUGFyYW1zJiBwYXJhbXNfOworICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgRmllbGRHZW5lcmF0b3JNYXAgZmllbGRfZ2VuZXJhdG9yc187CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKE1lc3NhZ2VHZW5lcmF0b3IpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGphdmFuYW5vCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBTkFOT19NRVNTQUdFX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19tZXNzYWdlX2ZpZWxkLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19tZXNzYWdlX2ZpZWxkLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQxZDA0YjUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX21lc3NhZ2VfZmllbGQuY2MKQEAgLTAsMCArMSwzNjMgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvcHJvdG9idWYvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHN0cmluZz4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19tZXNzYWdlX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgamF2YW5hbm8geworCit1c2luZyBpbnRlcm5hbDo6V2lyZUZvcm1hdDsKK3VzaW5nIGludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTsKKworbmFtZXNwYWNlIHsKKworLy8gVE9ETyhrZW50b24pOiAgRmFjdG9yIG91dCBhICJTZXRDb21tb25GaWVsZFZhcmlhYmxlcygpIiB0byBnZXQgcmlkIG9mCisvLyAgIHJlcGVhdCBjb2RlIGJldHdlZW4gdGhpcyBhbmQgdGhlIG90aGVyIGZpZWxkIHR5cGVzLgordm9pZCBTZXRNZXNzYWdlVmFyaWFibGVzKGNvbnN0IFBhcmFtcyYgcGFyYW1zLAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwgbWFwPHN0cmluZywgc3RyaW5nPiogdmFyaWFibGVzKSB7CisgICgqdmFyaWFibGVzKVsibmFtZSJdID0KKyAgICBSZW5hbWVKYXZhS2V5d29yZHMoVW5kZXJzY29yZXNUb0NhbWVsQ2FzZShkZXNjcmlwdG9yKSk7CisgICgqdmFyaWFibGVzKVsiY2FwaXRhbGl6ZWRfbmFtZSJdID0KKyAgICBSZW5hbWVKYXZhS2V5d29yZHMoVW5kZXJzY29yZXNUb0NhcGl0YWxpemVkQ2FtZWxDYXNlKGRlc2NyaXB0b3IpKTsKKyAgKCp2YXJpYWJsZXMpWyJudW1iZXIiXSA9IFNpbXBsZUl0b2EoZGVzY3JpcHRvci0+bnVtYmVyKCkpOworICAoKnZhcmlhYmxlcylbInR5cGUiXSA9IENsYXNzTmFtZShwYXJhbXMsIGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpKTsKKyAgKCp2YXJpYWJsZXMpWyJncm91cF9vcl9tZXNzYWdlIl0gPQorICAgIChkZXNjcmlwdG9yLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQKSA/CisgICAgIkdyb3VwIiA6ICJNZXNzYWdlIjsKKyAgKCp2YXJpYWJsZXMpWyJtZXNzYWdlX25hbWUiXSA9IGRlc2NyaXB0b3ItPmNvbnRhaW5pbmdfdHlwZSgpLT5uYW1lKCk7CisgIC8vKCp2YXJpYWJsZXMpWyJtZXNzYWdlX3R5cGUiXSA9IGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpLT5uYW1lKCk7CisgICgqdmFyaWFibGVzKVsidGFnIl0gPSBTaW1wbGVJdG9hKFdpcmVGb3JtYXQ6Ok1ha2VUYWcoZGVzY3JpcHRvcikpOworfQorCit9ICAvLyBuYW1lc3BhY2UKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorTWVzc2FnZUZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwgY29uc3QgUGFyYW1zJiBwYXJhbXMpCisgIDogRmllbGRHZW5lcmF0b3IocGFyYW1zKSwgZGVzY3JpcHRvcl8oZGVzY3JpcHRvcikgeworICBTZXRNZXNzYWdlVmFyaWFibGVzKHBhcmFtcywgZGVzY3JpcHRvciwgJnZhcmlhYmxlc18pOworfQorCitNZXNzYWdlRmllbGRHZW5lcmF0b3I6On5NZXNzYWdlRmllbGRHZW5lcmF0b3IoKSB7fQorCit2b2lkIE1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIsIGJvb2wgLyogdW51c2VkIGxhenlfaW5pdCAqLykgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwdWJsaWMgJHR5cGUkICRuYW1lJDtcbiIpOworfQorCit2b2lkIE1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUNsZWFyQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkbmFtZSQgPSBudWxsO1xuIik7Cit9CisKK3ZvaWQgTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKHRoaXMuJG5hbWUkID09IG51bGwpIHtcbiIKKyAgICAiICB0aGlzLiRuYW1lJCA9IG5ldyAkdHlwZSQoKTtcbiIKKyAgICAifVxuIik7CisKKyAgaWYgKGRlc2NyaXB0b3JfLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJpbnB1dC5yZWFkR3JvdXAodGhpcy4kbmFtZSQsICRudW1iZXIkKTtcbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaW5wdXQucmVhZE1lc3NhZ2UodGhpcy4kbmFtZSQpO1xuIik7CisgIH0KK30KKwordm9pZCBNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAodGhpcy4kbmFtZSQgIT0gbnVsbCkge1xuIgorICAgICIgIG91dHB1dC53cml0ZSRncm91cF9vcl9tZXNzYWdlJCgkbnVtYmVyJCwgdGhpcy4kbmFtZSQpO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKHRoaXMuJG5hbWUkICE9IG51bGwpIHtcbiIKKyAgICAiICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYubmFuby5Db2RlZE91dHB1dEJ5dGVCdWZmZXJOYW5vXG4iCisgICAgIiAgICAuY29tcHV0ZSRncm91cF9vcl9tZXNzYWdlJFNpemUoJG51bWJlciQsIHRoaXMuJG5hbWUkKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlRml4Q2xvbmVkQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAodGhpcy4kbmFtZSQgIT0gbnVsbCkge1xuIgorICAgICIgIGNsb25lZC4kbmFtZSQgPSB0aGlzLiRuYW1lJC5jbG9uZSgpO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVFcXVhbHNDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICh0aGlzLiRuYW1lJCA9PSBudWxsKSB7IFxuIgorICAgICIgIGlmIChvdGhlci4kbmFtZSQgIT0gbnVsbCkge1xuIgorICAgICIgICAgcmV0dXJuIGZhbHNlO1xuIgorICAgICIgIH1cbiIKKyAgICAifSBlbHNlIHtcbiIKKyAgICAiICBpZiAoIXRoaXMuJG5hbWUkLmVxdWFscyhvdGhlci4kbmFtZSQpKSB7XG4iCisgICAgIiAgICByZXR1cm4gZmFsc2U7XG4iCisgICAgIiAgfVxuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVIYXNoQ29kZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicmVzdWx0ID0gMzEgKiByZXN1bHQgK1xuIgorICAgICIgICAgKHRoaXMuJG5hbWUkID09IG51bGwgPyAwIDogdGhpcy4kbmFtZSQuaGFzaENvZGUoKSk7XG4iKTsKK30KKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworTWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3I6Ok1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yKAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwgY29uc3QgUGFyYW1zJiBwYXJhbXMpCisgICAgOiBGaWVsZEdlbmVyYXRvcihwYXJhbXMpLCBkZXNjcmlwdG9yXyhkZXNjcmlwdG9yKSB7CisgICAgU2V0TWVzc2FnZVZhcmlhYmxlcyhwYXJhbXMsIGRlc2NyaXB0b3IsICZ2YXJpYWJsZXNfKTsKKyAgICBTZXRDb21tb25PbmVvZlZhcmlhYmxlcyhkZXNjcmlwdG9yLCAmdmFyaWFibGVzXyk7Cit9CisKK01lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yOjp+TWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3IoKSB7fQorCit2b2lkIE1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlciwgYm9vbCAvKiB1bnVzZWQgbGF6eV9pbml0ICovKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInB1YmxpYyBib29sZWFuIGhhcyRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAiICByZXR1cm4gJGhhc19vbmVvZl9jYXNlJDtcbiIKKyAgICAifVxuIgorICAgICJwdWJsaWMgJHR5cGUkIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAiICBpZiAoJGhhc19vbmVvZl9jYXNlJCkge1xuIgorICAgICIgICAgcmV0dXJuICgkdHlwZSQpIHRoaXMuJG9uZW9mX25hbWUkXztcbiIKKyAgICAiICB9XG4iCisgICAgIiAgcmV0dXJuIG51bGw7XG4iCisgICAgIn1cbiIKKyAgICAicHVibGljICRtZXNzYWdlX25hbWUkIHNldCRjYXBpdGFsaXplZF9uYW1lJCgkdHlwZSQgdmFsdWUpIHtcbiIKKyAgICAiICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH1cbiIKKyAgICAiICAkc2V0X29uZW9mX2Nhc2UkO1xuIgorICAgICIgIHRoaXMuJG9uZW9mX25hbWUkXyA9IHZhbHVlO1xuIgorICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUNsZWFyQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICAvLyBObyBjbGVhciBtZXRob2QgZm9yIG9uZW9mIGZpZWxkcy4KK30KKwordm9pZCBNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICghKCRoYXNfb25lb2ZfY2FzZSQpKSB7XG4iCisgICAgIiAgdGhpcy4kb25lb2ZfbmFtZSRfID0gbmV3ICR0eXBlJCgpO1xuIgorICAgICJ9XG4iCisgICAgImlucHV0LnJlYWRNZXNzYWdlKFxuIgorICAgICIgICAgKGNvbS5nb29nbGUucHJvdG9idWYubmFuby5NZXNzYWdlTmFubykgdGhpcy4kb25lb2ZfbmFtZSRfKTtcbiIKKyAgICAiJHNldF9vbmVvZl9jYXNlJDtcbiIpOworfQorCit2b2lkIE1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCRoYXNfb25lb2ZfY2FzZSQpIHtcbiIKKyAgICAiICBvdXRwdXQud3JpdGVNZXNzYWdlKCRudW1iZXIkLFxuIgorICAgICIgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLk1lc3NhZ2VOYW5vKSB0aGlzLiRvbmVvZl9uYW1lJF8pO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoJGhhc19vbmVvZl9jYXNlJCkge1xuIgorICAgICIgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLkNvZGVkT3V0cHV0Qnl0ZUJ1ZmZlck5hbm9cbiIKKyAgICAiICAgIC5jb21wdXRlTWVzc2FnZVNpemUoJG51bWJlciQsXG4iCisgICAgIiAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYubmFuby5NZXNzYWdlTmFubykgdGhpcy4kb25lb2ZfbmFtZSRfKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgTWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVGaXhDbG9uZWRDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICh0aGlzLiRvbmVvZl9uYW1lJCAhPSBudWxsKSB7XG4iCisgICAgIiAgY2xvbmVkLiRvbmVvZl9uYW1lJCA9IHRoaXMuJG9uZW9mX25hbWUkLmNsb25lKCk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIE1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBHZW5lcmF0ZU9uZW9mRmllbGRFcXVhbHMoZGVzY3JpcHRvcl8sIHZhcmlhYmxlc18sIHByaW50ZXIpOworfQorCit2b2lkIE1lc3NhZ2VPbmVvZkZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlSGFzaENvZGVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIEdlbmVyYXRlT25lb2ZGaWVsZEhhc2hDb2RlKGRlc2NyaXB0b3JfLCB2YXJpYWJsZXNfLCBwcmludGVyKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitSZXBlYXRlZE1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6UmVwZWF0ZWRNZXNzYWdlRmllbGRHZW5lcmF0b3IoCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBjb25zdCBQYXJhbXMmIHBhcmFtcykKKyAgICA6IEZpZWxkR2VuZXJhdG9yKHBhcmFtcyksIGRlc2NyaXB0b3JfKGRlc2NyaXB0b3IpIHsKKyAgU2V0TWVzc2FnZVZhcmlhYmxlcyhwYXJhbXMsIGRlc2NyaXB0b3IsICZ2YXJpYWJsZXNfKTsKK30KKworUmVwZWF0ZWRNZXNzYWdlRmllbGRHZW5lcmF0b3I6On5SZXBlYXRlZE1lc3NhZ2VGaWVsZEdlbmVyYXRvcigpIHt9CisKK3ZvaWQgUmVwZWF0ZWRNZXNzYWdlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyLCBib29sIC8qIHVudXNlZCBsYXp5X2luaXQgKi8pIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHVibGljICR0eXBlJFtdICRuYW1lJDtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQ2xlYXJDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRuYW1lJCA9ICR0eXBlJC5lbXB0eUFycmF5KCk7XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZE1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIEZpcnN0LCBmaWd1cmUgb3V0IHRoZSBsZW5ndGggb2YgdGhlIGFycmF5LCB0aGVuIHBhcnNlLgorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpbnQgYXJyYXlMZW5ndGggPSBjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uV2lyZUZvcm1hdE5hbm9cbiIKKyAgICAiICAgIC5nZXRSZXBlYXRlZEZpZWxkQXJyYXlMZW5ndGgoaW5wdXQsICR0YWckKTtcbiIKKyAgICAiaW50IGkgPSB0aGlzLiRuYW1lJCA9PSBudWxsID8gMCA6IHRoaXMuJG5hbWUkLmxlbmd0aDtcbiIKKyAgICAiJHR5cGUkW10gbmV3QXJyYXkgPVxuIgorICAgICIgICAgbmV3ICR0eXBlJFtpICsgYXJyYXlMZW5ndGhdO1xuIgorICAgICJpZiAoaSAhPSAwKSB7XG4iCisgICAgIiAgamF2YS5sYW5nLlN5c3RlbS5hcnJheWNvcHkodGhpcy4kbmFtZSQsIDAsIG5ld0FycmF5LCAwLCBpKTtcbiIKKyAgICAifVxuIgorICAgICJmb3IgKDsgaSA8IG5ld0FycmF5Lmxlbmd0aCAtIDE7IGkrKykge1xuIgorICAgICIgIG5ld0FycmF5W2ldID0gbmV3ICR0eXBlJCgpO1xuIik7CisKKyAgaWYgKGRlc2NyaXB0b3JfLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIgIGlucHV0LnJlYWRHcm91cChuZXdBcnJheVtpXSwgJG51bWJlciQpO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIgIGlucHV0LnJlYWRNZXNzYWdlKG5ld0FycmF5W2ldKTtcbiIpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiICBpbnB1dC5yZWFkVGFnKCk7XG4iCisgICAgIn1cbiIKKyAgICAiLy8gTGFzdCBvbmUgd2l0aG91dCByZWFkVGFnLlxuIgorICAgICJuZXdBcnJheVtpXSA9IG5ldyAkdHlwZSQoKTtcbiIpOworCisgIGlmIChkZXNjcmlwdG9yXy0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9HUk9VUCkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaW5wdXQucmVhZEdyb3VwKG5ld0FycmF5W2ldLCAkbnVtYmVyJCk7XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImlucHV0LnJlYWRNZXNzYWdlKG5ld0FycmF5W2ldKTtcbiIpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAidGhpcy4kbmFtZSQgPSBuZXdBcnJheTtcbiIpOworfQorCit2b2lkIFJlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKHRoaXMuJG5hbWUkICE9IG51bGwgJiYgdGhpcy4kbmFtZSQubGVuZ3RoID4gMCkge1xuIgorICAgICIgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy4kbmFtZSQubGVuZ3RoOyBpKyspIHtcbiIKKyAgICAiICAgICR0eXBlJCBlbGVtZW50ID0gdGhpcy4kbmFtZSRbaV07XG4iCisgICAgIiAgICBpZiAoZWxlbWVudCAhPSBudWxsKSB7XG4iCisgICAgIiAgICAgIG91dHB1dC53cml0ZSRncm91cF9vcl9tZXNzYWdlJCgkbnVtYmVyJCwgZWxlbWVudCk7XG4iCisgICAgIiAgICB9XG4iCisgICAgIiAgfVxuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZE1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6ZWRTaXplQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAodGhpcy4kbmFtZSQgIT0gbnVsbCAmJiB0aGlzLiRuYW1lJC5sZW5ndGggPiAwKSB7XG4iCisgICAgIiAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLiRuYW1lJC5sZW5ndGg7IGkrKykge1xuIgorICAgICIgICAgJHR5cGUkIGVsZW1lbnQgPSB0aGlzLiRuYW1lJFtpXTtcbiIKKyAgICAiICAgIGlmIChlbGVtZW50ICE9IG51bGwpIHtcbiIKKyAgICAiICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFub1xuIgorICAgICIgICAgICAgIC5jb21wdXRlJGdyb3VwX29yX21lc3NhZ2UkU2l6ZSgkbnVtYmVyJCwgZWxlbWVudCk7XG4iCisgICAgIiAgICB9XG4iCisgICAgIiAgfVxuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZE1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUZpeENsb25lZENvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKHRoaXMuJG5hbWUkICE9IG51bGwgJiYgdGhpcy4kbmFtZSQubGVuZ3RoID4gMCkge1xuIgorICAgICIgIGNsb25lZC4kbmFtZSQgPSBuZXcgJHR5cGUkW3RoaXMuJG5hbWUkLmxlbmd0aF07XG4iCisgICAgIiAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLiRuYW1lJC5sZW5ndGg7IGkrKykge1xuIgorICAgICIgICAgaWYgKHRoaXMuJG5hbWUkW2ldICE9IG51bGwpIHtcbiIKKyAgICAiICAgICAgY2xvbmVkLiRuYW1lJFtpXSA9IHRoaXMuJG5hbWUkW2ldLmNsb25lKCk7XG4iCisgICAgIiAgICB9XG4iCisgICAgIiAgfVxuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZE1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUVxdWFsc0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCFjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uSW50ZXJuYWxOYW5vLmVxdWFscyhcbiIKKyAgICAiICAgIHRoaXMuJG5hbWUkLCBvdGhlci4kbmFtZSQpKSB7XG4iCisgICAgIiAgcmV0dXJuIGZhbHNlO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZE1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUhhc2hDb2RlQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJyZXN1bHQgPSAzMSAqIHJlc3VsdFxuIgorICAgICIgICAgKyBjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uSW50ZXJuYWxOYW5vLmhhc2hDb2RlKHRoaXMuJG5hbWUkKTtcbiIpOworfQorCit9ICAvLyBuYW1lc3BhY2UgamF2YW5hbm8KK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX21lc3NhZ2VfZmllbGQuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fbWVzc2FnZV9maWVsZC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUwNzQ3MzUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX21lc3NhZ2VfZmllbGQuaApAQCAtMCwwICsxLDEyMSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9wcm90b2J1Zi8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFOQU5PX01FU1NBR0VfRklFTERfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9KQVZBTkFOT19NRVNTQUdFX0ZJRUxEX0hfXworCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZmllbGQuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhbmFubyB7CisKK2NsYXNzIE1lc3NhZ2VGaWVsZEdlbmVyYXRvciA6IHB1YmxpYyBGaWVsZEdlbmVyYXRvciB7CisgcHVibGljOgorICBleHBsaWNpdCBNZXNzYWdlRmllbGRHZW5lcmF0b3IoCisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGNvbnN0IFBhcmFtcyYgcGFyYW1zKTsKKyAgfk1lc3NhZ2VGaWVsZEdlbmVyYXRvcigpOworCisgIC8vIGltcGxlbWVudHMgRmllbGRHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIHZvaWQgR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyLCBib29sIGxhenlfaW5pdCkgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVDbGVhckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUVxdWFsc0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSGFzaENvZGVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUZpeENsb25lZENvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXNfOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhNZXNzYWdlRmllbGRHZW5lcmF0b3IpOworfTsKKworY2xhc3MgTWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3IgOiBwdWJsaWMgRmllbGRHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgTWVzc2FnZU9uZW9mRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBQYXJhbXMmIHBhcmFtcyk7CisgIH5NZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcigpOworCisgIC8vIGltcGxlbWVudHMgRmllbGRHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIHZvaWQgR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyLCBib29sIGxhenlfaW5pdCkgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVDbGVhckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUVxdWFsc0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSGFzaENvZGVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUZpeENsb25lZENvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXNfOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhNZXNzYWdlT25lb2ZGaWVsZEdlbmVyYXRvcik7Cit9OworCitjbGFzcyBSZXBlYXRlZE1lc3NhZ2VGaWVsZEdlbmVyYXRvciA6IHB1YmxpYyBGaWVsZEdlbmVyYXRvciB7CisgcHVibGljOgorICBleHBsaWNpdCBSZXBlYXRlZE1lc3NhZ2VGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgIGNvbnN0IFBhcmFtcyYgcGFyYW1zKTsKKyAgflJlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yKCk7CisKKyAgLy8gaW1wbGVtZW50cyBGaWVsZEdlbmVyYXRvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgdm9pZCBHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIsIGJvb2wgbGF6eV9pbml0KSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUNsZWFyQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVIYXNoQ29kZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRml4Q2xvbmVkQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyBwcml2YXRlOgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlc187CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFJlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhbmFubworfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQU5BTk9fTUVTU0FHRV9GSUVMRF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fcGFyYW1zLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX3BhcmFtcy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUzYjRiYjkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX3BhcmFtcy5oCkBAIC0wLDAgKzEsMjU4IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDEwIEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL3Byb3RvYnVmLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IHdpbmtAZ29vZ2xlLmNvbSAoV2luayBTYXZpbGxlKQorCisjaWZuZGVmIFBST1RPQlVGX0NPTVBJTEVSX0pBVkFOQU5PX0pBVkFOQU5PX1BBUkFNU19IXworI2RlZmluZSBQUk9UT0JVRl9DT01QSUxFUl9KQVZBTkFOT19KQVZBTkFOT19QQVJBTVNfSF8KKworI2luY2x1ZGUgPG1hcD4KKyNpbmNsdWRlIDxzZXQ+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhbmFubyB7CisKK2VudW0gZU11bHRpcGxlRmlsZXMgeyBKQVZBTkFOT19NVUxfVU5TRVQsIEpBVkFOQU5PX01VTF9GQUxTRSwgSkFWQU5BTk9fTVVMX1RSVUUgfTsKKworLy8gUGFyYW1ldGVycyBmb3IgdXNlZCBieSB0aGUgZ2VuZXJhdG9ycworY2xhc3MgUGFyYW1zIHsKKyBwdWJsaWM6CisgIHR5cGVkZWYgbWFwPHN0cmluZywgc3RyaW5nPiBOYW1lTWFwOworICB0eXBlZGVmIHNldDxzdHJpbmc+IE5hbWVTZXQ7CisgcHJpdmF0ZToKKyAgc3RyaW5nIGVtcHR5XzsKKyAgc3RyaW5nIGJhc2VfbmFtZV87CisgIGVNdWx0aXBsZUZpbGVzIG92ZXJyaWRlX2phdmFfbXVsdGlwbGVfZmlsZXNfOworICBib29sIHN0b3JlX3Vua25vd25fZmllbGRzXzsKKyAgTmFtZU1hcCBqYXZhX3BhY2thZ2VzXzsKKyAgTmFtZU1hcCBqYXZhX291dGVyX2NsYXNzbmFtZXNfOworICBOYW1lU2V0IGphdmFfbXVsdGlwbGVfZmlsZXNfOworICBib29sIGdlbmVyYXRlX2hhc187CisgIGJvb2wgamF2YV9lbnVtX3N0eWxlXzsKKyAgYm9vbCBvcHRpb25hbF9maWVsZF9hY2Nlc3NvcnNfOworICBib29sIHVzZV9yZWZlcmVuY2VfdHlwZXNfZm9yX3ByaW1pdGl2ZXNfOworICBib29sIGdlbmVyYXRlX2VxdWFsc187CisgIGJvb2wgaWdub3JlX3NlcnZpY2VzXzsKKyAgYm9vbCBwYXJjZWxhYmxlX21lc3NhZ2VzXzsKKyAgYm9vbCByZWZ0eXBlc19wcmltaXRpdmVfZW51bXNfOworICBib29sIGdlbmVyYXRlX2NsZWFyXzsKKyAgYm9vbCBnZW5lcmF0ZV9jbG9uZV87CisgIGJvb2wgZ2VuZXJhdGVfaW50ZGVmc187CisKKyBwdWJsaWM6CisgIFBhcmFtcyhjb25zdCBzdHJpbmcgJiBiYXNlX25hbWUpIDoKKyAgICBlbXB0eV8oIiIpLAorICAgIGJhc2VfbmFtZV8oYmFzZV9uYW1lKSwKKyAgICBvdmVycmlkZV9qYXZhX211bHRpcGxlX2ZpbGVzXyhKQVZBTkFOT19NVUxfVU5TRVQpLAorICAgIHN0b3JlX3Vua25vd25fZmllbGRzXyhmYWxzZSksCisgICAgZ2VuZXJhdGVfaGFzXyhmYWxzZSksCisgICAgamF2YV9lbnVtX3N0eWxlXyhmYWxzZSksCisgICAgb3B0aW9uYWxfZmllbGRfYWNjZXNzb3JzXyhmYWxzZSksCisgICAgdXNlX3JlZmVyZW5jZV90eXBlc19mb3JfcHJpbWl0aXZlc18oZmFsc2UpLAorICAgIGdlbmVyYXRlX2VxdWFsc18oZmFsc2UpLAorICAgIGlnbm9yZV9zZXJ2aWNlc18oZmFsc2UpLAorICAgIHBhcmNlbGFibGVfbWVzc2FnZXNfKGZhbHNlKSwKKyAgICByZWZ0eXBlc19wcmltaXRpdmVfZW51bXNfKGZhbHNlKSwKKyAgICBnZW5lcmF0ZV9jbGVhcl8odHJ1ZSksCisgICAgZ2VuZXJhdGVfY2xvbmVfKGZhbHNlKSwKKyAgICBnZW5lcmF0ZV9pbnRkZWZzXyhmYWxzZSkgeworICB9CisKKyAgY29uc3Qgc3RyaW5nJiBiYXNlX25hbWUoKSBjb25zdCB7CisgICAgcmV0dXJuIGJhc2VfbmFtZV87CisgIH0KKworICBib29sIGhhc19qYXZhX3BhY2thZ2UoY29uc3Qgc3RyaW5nJiBmaWxlX25hbWUpIGNvbnN0IHsKKyAgICByZXR1cm4gamF2YV9wYWNrYWdlc18uZmluZChmaWxlX25hbWUpCisgICAgICAgICAgICAgICAgICAgICAgICAhPSBqYXZhX3BhY2thZ2VzXy5lbmQoKTsKKyAgfQorICB2b2lkIHNldF9qYXZhX3BhY2thZ2UoY29uc3Qgc3RyaW5nJiBmaWxlX25hbWUsCisgICAgICBjb25zdCBzdHJpbmcmIGphdmFfcGFja2FnZSkgeworICAgIGphdmFfcGFja2FnZXNfW2ZpbGVfbmFtZV0gPSBqYXZhX3BhY2thZ2U7CisgIH0KKyAgY29uc3Qgc3RyaW5nJiBqYXZhX3BhY2thZ2UoY29uc3Qgc3RyaW5nJiBmaWxlX25hbWUpIGNvbnN0IHsKKyAgICBOYW1lTWFwOjpjb25zdF9pdGVyYXRvciBpdHI7CisKKyAgICBpdHIgPSBqYXZhX3BhY2thZ2VzXy5maW5kKGZpbGVfbmFtZSk7CisgICAgaWYgIChpdHIgPT0gamF2YV9wYWNrYWdlc18uZW5kKCkpIHsKKyAgICAgIHJldHVybiBlbXB0eV87CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiBpdHItPnNlY29uZDsKKyAgICB9CisgIH0KKyAgY29uc3QgTmFtZU1hcCYgamF2YV9wYWNrYWdlcygpIHsKKyAgICByZXR1cm4gamF2YV9wYWNrYWdlc187CisgIH0KKworICBib29sIGhhc19qYXZhX291dGVyX2NsYXNzbmFtZShjb25zdCBzdHJpbmcmIGZpbGVfbmFtZSkgY29uc3QgeworICAgIHJldHVybiBqYXZhX291dGVyX2NsYXNzbmFtZXNfLmZpbmQoZmlsZV9uYW1lKQorICAgICAgICAgICAgICAgICAgICAgICAgIT0gamF2YV9vdXRlcl9jbGFzc25hbWVzXy5lbmQoKTsKKyAgfQorICB2b2lkIHNldF9qYXZhX291dGVyX2NsYXNzbmFtZShjb25zdCBzdHJpbmcmIGZpbGVfbmFtZSwKKyAgICAgIGNvbnN0IHN0cmluZyYgamF2YV9vdXRlcl9jbGFzc25hbWUpIHsKKyAgICBqYXZhX291dGVyX2NsYXNzbmFtZXNfW2ZpbGVfbmFtZV0gPSBqYXZhX291dGVyX2NsYXNzbmFtZTsKKyAgfQorICBjb25zdCBzdHJpbmcmIGphdmFfb3V0ZXJfY2xhc3NuYW1lKGNvbnN0IHN0cmluZyYgZmlsZV9uYW1lKSBjb25zdCB7CisgICAgTmFtZU1hcDo6Y29uc3RfaXRlcmF0b3IgaXRyOworCisgICAgaXRyID0gamF2YV9vdXRlcl9jbGFzc25hbWVzXy5maW5kKGZpbGVfbmFtZSk7CisgICAgaWYgIChpdHIgPT0gamF2YV9vdXRlcl9jbGFzc25hbWVzXy5lbmQoKSkgeworICAgICAgcmV0dXJuIGVtcHR5XzsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIGl0ci0+c2Vjb25kOworICAgIH0KKyAgfQorICBjb25zdCBOYW1lTWFwJiBqYXZhX291dGVyX2NsYXNzbmFtZXMoKSB7CisgICAgcmV0dXJuIGphdmFfb3V0ZXJfY2xhc3NuYW1lc187CisgIH0KKworICB2b2lkIHNldF9vdmVycmlkZV9qYXZhX211bHRpcGxlX2ZpbGVzKGJvb2wgamF2YV9tdWx0aXBsZV9maWxlcykgeworICAgIGlmIChqYXZhX211bHRpcGxlX2ZpbGVzKSB7CisgICAgICBvdmVycmlkZV9qYXZhX211bHRpcGxlX2ZpbGVzXyA9IEpBVkFOQU5PX01VTF9UUlVFOworICAgIH0gZWxzZSB7CisgICAgICBvdmVycmlkZV9qYXZhX211bHRpcGxlX2ZpbGVzXyA9IEpBVkFOQU5PX01VTF9GQUxTRTsKKyAgICB9CisgIH0KKyAgdm9pZCBjbGVhcl9vdmVycmlkZV9qYXZhX211bHRpcGxlX2ZpbGVzKCkgeworICAgIG92ZXJyaWRlX2phdmFfbXVsdGlwbGVfZmlsZXNfID0gSkFWQU5BTk9fTVVMX1VOU0VUOworICB9CisKKyAgdm9pZCBzZXRfamF2YV9tdWx0aXBsZV9maWxlcyhjb25zdCBzdHJpbmcmIGZpbGVfbmFtZSwgYm9vbCB2YWx1ZSkgeworICAgIGlmICh2YWx1ZSkgeworICAgICAgamF2YV9tdWx0aXBsZV9maWxlc18uaW5zZXJ0KGZpbGVfbmFtZSk7CisgICAgfSBlbHNlIHsKKyAgICAgIGphdmFfbXVsdGlwbGVfZmlsZXNfLmVyYXNlKGZpbGVfbmFtZSk7CisgICAgfQorICB9CisgIGJvb2wgamF2YV9tdWx0aXBsZV9maWxlcyhjb25zdCBzdHJpbmcmIGZpbGVfbmFtZSkgY29uc3QgeworICAgIHN3aXRjaCAob3ZlcnJpZGVfamF2YV9tdWx0aXBsZV9maWxlc18pIHsKKyAgICAgIGNhc2UgSkFWQU5BTk9fTVVMX0ZBTFNFOgorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBjYXNlIEpBVkFOQU5PX01VTF9UUlVFOgorICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHJldHVybiBqYXZhX211bHRpcGxlX2ZpbGVzXy5maW5kKGZpbGVfbmFtZSkKKyAgICAgICAgICAgICAgICAhPSBqYXZhX211bHRpcGxlX2ZpbGVzXy5lbmQoKTsKKyAgICB9CisgIH0KKworICB2b2lkIHNldF9zdG9yZV91bmtub3duX2ZpZWxkcyhib29sIHZhbHVlKSB7CisgICAgc3RvcmVfdW5rbm93bl9maWVsZHNfID0gdmFsdWU7CisgIH0KKyAgYm9vbCBzdG9yZV91bmtub3duX2ZpZWxkcygpIGNvbnN0IHsKKyAgICByZXR1cm4gc3RvcmVfdW5rbm93bl9maWVsZHNfOworICB9CisKKyAgdm9pZCBzZXRfZ2VuZXJhdGVfaGFzKGJvb2wgdmFsdWUpIHsKKyAgICBnZW5lcmF0ZV9oYXNfID0gdmFsdWU7CisgIH0KKyAgYm9vbCBnZW5lcmF0ZV9oYXMoKSBjb25zdCB7CisgICAgcmV0dXJuIGdlbmVyYXRlX2hhc187CisgIH0KKworICB2b2lkIHNldF9qYXZhX2VudW1fc3R5bGUoYm9vbCB2YWx1ZSkgeworICAgIGphdmFfZW51bV9zdHlsZV8gPSB2YWx1ZTsKKyAgfQorICBib29sIGphdmFfZW51bV9zdHlsZSgpIGNvbnN0IHsKKyAgICByZXR1cm4gamF2YV9lbnVtX3N0eWxlXzsKKyAgfQorCisgIHZvaWQgc2V0X29wdGlvbmFsX2ZpZWxkX2FjY2Vzc29ycyhib29sIHZhbHVlKSB7CisgICAgb3B0aW9uYWxfZmllbGRfYWNjZXNzb3JzXyA9IHZhbHVlOworICB9CisgIGJvb2wgb3B0aW9uYWxfZmllbGRfYWNjZXNzb3JzKCkgY29uc3QgeworICAgIHJldHVybiBvcHRpb25hbF9maWVsZF9hY2Nlc3NvcnNfOworICB9CisKKyAgdm9pZCBzZXRfdXNlX3JlZmVyZW5jZV90eXBlc19mb3JfcHJpbWl0aXZlcyhib29sIHZhbHVlKSB7CisgICAgdXNlX3JlZmVyZW5jZV90eXBlc19mb3JfcHJpbWl0aXZlc18gPSB2YWx1ZTsKKyAgfQorICBib29sIHVzZV9yZWZlcmVuY2VfdHlwZXNfZm9yX3ByaW1pdGl2ZXMoKSBjb25zdCB7CisgICAgcmV0dXJuIHVzZV9yZWZlcmVuY2VfdHlwZXNfZm9yX3ByaW1pdGl2ZXNfOworICB9CisKKyAgdm9pZCBzZXRfZ2VuZXJhdGVfZXF1YWxzKGJvb2wgdmFsdWUpIHsKKyAgICBnZW5lcmF0ZV9lcXVhbHNfID0gdmFsdWU7CisgIH0KKyAgYm9vbCBnZW5lcmF0ZV9lcXVhbHMoKSBjb25zdCB7CisgICAgcmV0dXJuIGdlbmVyYXRlX2VxdWFsc187CisgIH0KKworICB2b2lkIHNldF9pZ25vcmVfc2VydmljZXMoYm9vbCB2YWx1ZSkgeworICAgIGlnbm9yZV9zZXJ2aWNlc18gPSB2YWx1ZTsKKyAgfQorICBib29sIGlnbm9yZV9zZXJ2aWNlcygpIGNvbnN0IHsKKyAgICByZXR1cm4gaWdub3JlX3NlcnZpY2VzXzsKKyAgfQorCisgIHZvaWQgc2V0X3BhcmNlbGFibGVfbWVzc2FnZXMoYm9vbCB2YWx1ZSkgeworICAgIHBhcmNlbGFibGVfbWVzc2FnZXNfID0gdmFsdWU7CisgIH0KKyAgYm9vbCBwYXJjZWxhYmxlX21lc3NhZ2VzKCkgY29uc3QgeworICAgIHJldHVybiBwYXJjZWxhYmxlX21lc3NhZ2VzXzsKKyAgfQorCisgIHZvaWQgc2V0X3JlZnR5cGVzX3ByaW1pdGl2ZV9lbnVtcyhib29sIHZhbHVlKSB7CisgICAgcmVmdHlwZXNfcHJpbWl0aXZlX2VudW1zXyA9IHZhbHVlOworICB9CisgIGJvb2wgcmVmdHlwZXNfcHJpbWl0aXZlX2VudW1zKCkgY29uc3QgeworICAgIHJldHVybiByZWZ0eXBlc19wcmltaXRpdmVfZW51bXNfOworICB9CisKKyAgdm9pZCBzZXRfZ2VuZXJhdGVfY2xlYXIoYm9vbCB2YWx1ZSkgeworICAgIGdlbmVyYXRlX2NsZWFyXyA9IHZhbHVlOworICB9CisgIGJvb2wgZ2VuZXJhdGVfY2xlYXIoKSBjb25zdCB7CisgICAgcmV0dXJuIGdlbmVyYXRlX2NsZWFyXzsKKyAgfQorCisgIHZvaWQgc2V0X2dlbmVyYXRlX2Nsb25lKGJvb2wgdmFsdWUpIHsKKyAgICBnZW5lcmF0ZV9jbG9uZV8gPSB2YWx1ZTsKKyAgfQorICBib29sIGdlbmVyYXRlX2Nsb25lKCkgY29uc3QgeworICAgIHJldHVybiBnZW5lcmF0ZV9jbG9uZV87CisgIH0KKworICB2b2lkIHNldF9nZW5lcmF0ZV9pbnRkZWZzKGJvb2wgdmFsdWUpIHsKKyAgICBnZW5lcmF0ZV9pbnRkZWZzXyA9IHZhbHVlOworICB9CisgIGJvb2wgZ2VuZXJhdGVfaW50ZGVmcygpIGNvbnN0IHsKKyAgICByZXR1cm4gZ2VuZXJhdGVfaW50ZGVmc187CisgIH0KK307CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhbmFubworfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gUFJPVE9CVUZfQ09NUElMRVJfSkFWQU5BTk9fSkFWQU5BTk9fUEFSQU1TX0hfCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX3ByaW1pdGl2ZV9maWVsZC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fcHJpbWl0aXZlX2ZpZWxkLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk3OGFiZjIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX3ByaW1pdGl2ZV9maWVsZC5jYwpAQCAtMCwwICsxLDk2OCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9wcm90b2J1Zi8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8bWF0aC5oPgorI2luY2x1ZGUgPHN0cmluZz4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qYXZhbmFuby9qYXZhbmFub19wcmltaXRpdmVfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N1YnN0aXR1dGUuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhbmFubyB7CisKK3VzaW5nIGludGVybmFsOjpXaXJlRm9ybWF0OwordXNpbmcgaW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOworCituYW1lc3BhY2UgeworCitib29sIElzUmVmZXJlbmNlVHlwZShKYXZhVHlwZSB0eXBlKSB7CisgIHN3aXRjaCAodHlwZSkgeworICAgIGNhc2UgSkFWQVRZUEVfSU5UICAgIDogcmV0dXJuIGZhbHNlOworICAgIGNhc2UgSkFWQVRZUEVfTE9ORyAgIDogcmV0dXJuIGZhbHNlOworICAgIGNhc2UgSkFWQVRZUEVfRkxPQVQgIDogcmV0dXJuIGZhbHNlOworICAgIGNhc2UgSkFWQVRZUEVfRE9VQkxFIDogcmV0dXJuIGZhbHNlOworICAgIGNhc2UgSkFWQVRZUEVfQk9PTEVBTjogcmV0dXJuIGZhbHNlOworICAgIGNhc2UgSkFWQVRZUEVfU1RSSU5HIDogcmV0dXJuIHRydWU7CisgICAgY2FzZSBKQVZBVFlQRV9CWVRFUyAgOiByZXR1cm4gdHJ1ZTsKKyAgICBjYXNlIEpBVkFUWVBFX0VOVU0gICA6IHJldHVybiBmYWxzZTsKKyAgICBjYXNlIEpBVkFUWVBFX01FU1NBR0U6IHJldHVybiB0cnVlOworCisgICAgLy8gTm8gZGVmYXVsdCBiZWNhdXNlIHdlIHdhbnQgdGhlIGNvbXBpbGVyIHRvIGNvbXBsYWluIGlmIGFueSBuZXcKKyAgICAvLyBKYXZhVHlwZXMgYXJlIGFkZGVkLgorICB9CisKKyAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkNhbid0IGdldCBoZXJlLiI7CisgIHJldHVybiBmYWxzZTsKK30KKworYm9vbCBJc0FycmF5VHlwZShKYXZhVHlwZSB0eXBlKSB7CisgIHN3aXRjaCAodHlwZSkgeworICAgIGNhc2UgSkFWQVRZUEVfSU5UICAgIDogcmV0dXJuIGZhbHNlOworICAgIGNhc2UgSkFWQVRZUEVfTE9ORyAgIDogcmV0dXJuIGZhbHNlOworICAgIGNhc2UgSkFWQVRZUEVfRkxPQVQgIDogcmV0dXJuIGZhbHNlOworICAgIGNhc2UgSkFWQVRZUEVfRE9VQkxFIDogcmV0dXJuIGZhbHNlOworICAgIGNhc2UgSkFWQVRZUEVfQk9PTEVBTjogcmV0dXJuIGZhbHNlOworICAgIGNhc2UgSkFWQVRZUEVfU1RSSU5HIDogcmV0dXJuIGZhbHNlOworICAgIGNhc2UgSkFWQVRZUEVfQllURVMgIDogcmV0dXJuIHRydWU7CisgICAgY2FzZSBKQVZBVFlQRV9FTlVNICAgOiByZXR1cm4gZmFsc2U7CisgICAgY2FzZSBKQVZBVFlQRV9NRVNTQUdFOiByZXR1cm4gZmFsc2U7CisKKyAgICAvLyBObyBkZWZhdWx0IGJlY2F1c2Ugd2Ugd2FudCB0aGUgY29tcGlsZXIgdG8gY29tcGxhaW4gaWYgYW55IG5ldworICAgIC8vIEphdmFUeXBlcyBhcmUgYWRkZWQuCisgIH0KKworICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ2FuJ3QgZ2V0IGhlcmUuIjsKKyAgcmV0dXJuIGZhbHNlOworfQorCitjb25zdCBjaGFyKiBHZXRDYXBpdGFsaXplZFR5cGUoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICBzd2l0Y2ggKGZpZWxkLT50eXBlKCkpIHsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9JTlQzMiAgIDogcmV0dXJuICJJbnQzMiIgICA7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfVUlOVDMyICA6IHJldHVybiAiVUludDMyIiAgOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NJTlQzMiAgOiByZXR1cm4gIlNJbnQzMiIgIDsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9GSVhFRDMyIDogcmV0dXJuICJGaXhlZDMyIiA7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0ZJWEVEMzI6IHJldHVybiAiU0ZpeGVkMzIiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0lOVDY0ICAgOiByZXR1cm4gIkludDY0IiAgIDsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9VSU5UNjQgIDogcmV0dXJuICJVSW50NjQiICA7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0lOVDY0ICA6IHJldHVybiAiU0ludDY0IiAgOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0ZJWEVENjQgOiByZXR1cm4gIkZpeGVkNjQiIDsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TRklYRUQ2NDogcmV0dXJuICJTRml4ZWQ2NCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRkxPQVQgICA6IHJldHVybiAiRmxvYXQiICAgOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0RPVUJMRSAgOiByZXR1cm4gIkRvdWJsZSIgIDsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9CT09MICAgIDogcmV0dXJuICJCb29sIiAgICA7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU1RSSU5HICA6IHJldHVybiAiU3RyaW5nIiAgOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0JZVEVTICAgOiByZXR1cm4gIkJ5dGVzIiAgIDsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9FTlVNICAgIDogcmV0dXJuICJFbnVtIiAgICA7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfR1JPVVAgICA6IHJldHVybiAiR3JvdXAiICAgOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX01FU1NBR0UgOiByZXR1cm4gIk1lc3NhZ2UiIDsKKworICAgIC8vIE5vIGRlZmF1bHQgYmVjYXVzZSB3ZSB3YW50IHRoZSBjb21waWxlciB0byBjb21wbGFpbiBpZiBhbnkgbmV3CisgICAgLy8gdHlwZXMgYXJlIGFkZGVkLgorICB9CisKKyAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkNhbid0IGdldCBoZXJlLiI7CisgIHJldHVybiBOVUxMOworfQorCisvLyBGb3IgZW5jb2RpbmdzIHdpdGggZml4ZWQgc2l6ZXMsIHJldHVybnMgdGhhdCBzaXplIGluIGJ5dGVzLiAgT3RoZXJ3aXNlCisvLyByZXR1cm5zIC0xLgoraW50IEZpeGVkU2l6ZShGaWVsZERlc2NyaXB0b3I6OlR5cGUgdHlwZSkgeworICBzd2l0Y2ggKHR5cGUpIHsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9JTlQzMiAgIDogcmV0dXJuIC0xOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0lOVDY0ICAgOiByZXR1cm4gLTE7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfVUlOVDMyICA6IHJldHVybiAtMTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9VSU5UNjQgIDogcmV0dXJuIC0xOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NJTlQzMiAgOiByZXR1cm4gLTE7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0lOVDY0ICA6IHJldHVybiAtMTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9GSVhFRDMyIDogcmV0dXJuIFdpcmVGb3JtYXRMaXRlOjprRml4ZWQzMlNpemU7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRklYRUQ2NCA6IHJldHVybiBXaXJlRm9ybWF0TGl0ZTo6a0ZpeGVkNjRTaXplOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NGSVhFRDMyOiByZXR1cm4gV2lyZUZvcm1hdExpdGU6OmtTRml4ZWQzMlNpemU7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0ZJWEVENjQ6IHJldHVybiBXaXJlRm9ybWF0TGl0ZTo6a1NGaXhlZDY0U2l6ZTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9GTE9BVCAgIDogcmV0dXJuIFdpcmVGb3JtYXRMaXRlOjprRmxvYXRTaXplOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0RPVUJMRSAgOiByZXR1cm4gV2lyZUZvcm1hdExpdGU6OmtEb3VibGVTaXplOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfQk9PTCAgICA6IHJldHVybiBXaXJlRm9ybWF0TGl0ZTo6a0Jvb2xTaXplOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0VOVU0gICAgOiByZXR1cm4gLTE7CisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TVFJJTkcgIDogcmV0dXJuIC0xOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0JZVEVTICAgOiByZXR1cm4gLTE7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfR1JPVVAgICA6IHJldHVybiAtMTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9NRVNTQUdFIDogcmV0dXJuIC0xOworCisgICAgLy8gTm8gZGVmYXVsdCBiZWNhdXNlIHdlIHdhbnQgdGhlIGNvbXBpbGVyIHRvIGNvbXBsYWluIGlmIGFueSBuZXcKKyAgICAvLyB0eXBlcyBhcmUgYWRkZWQuCisgIH0KKyAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkNhbid0IGdldCBoZXJlLiI7CisgIHJldHVybiAtMTsKK30KKworYm9vbCBBbGxBc2NpaShjb25zdCBzdHJpbmcmIHRleHQpIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0ZXh0LnNpemUoKTsgaSsrKSB7CisgICAgaWYgKCh0ZXh0W2ldICYgMHg4MCkgIT0gMCkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgfQorICByZXR1cm4gdHJ1ZTsKK30KKworCit2b2lkIFNldFByaW1pdGl2ZVZhcmlhYmxlcyhjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGNvbnN0IFBhcmFtcyBwYXJhbXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXA8c3RyaW5nLCBzdHJpbmc+KiB2YXJpYWJsZXMpIHsKKyAgKCp2YXJpYWJsZXMpWyJuYW1lIl0gPQorICAgIFJlbmFtZUphdmFLZXl3b3JkcyhVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlKGRlc2NyaXB0b3IpKTsKKyAgKCp2YXJpYWJsZXMpWyJjYXBpdGFsaXplZF9uYW1lIl0gPQorICAgIFJlbmFtZUphdmFLZXl3b3JkcyhVbmRlcnNjb3Jlc1RvQ2FwaXRhbGl6ZWRDYW1lbENhc2UoZGVzY3JpcHRvcikpOworICAoKnZhcmlhYmxlcylbIm51bWJlciJdID0gU2ltcGxlSXRvYShkZXNjcmlwdG9yLT5udW1iZXIoKSk7CisgIGlmIChwYXJhbXMudXNlX3JlZmVyZW5jZV90eXBlc19mb3JfcHJpbWl0aXZlcygpCisgICAgICAmJiAhZGVzY3JpcHRvci0+aXNfcmVwZWF0ZWQoKSkgeworICAgICgqdmFyaWFibGVzKVsidHlwZSJdID0gQm94ZWRQcmltaXRpdmVUeXBlTmFtZShHZXRKYXZhVHlwZShkZXNjcmlwdG9yKSk7CisgIH0gZWxzZSB7CisgICAgKCp2YXJpYWJsZXMpWyJ0eXBlIl0gPSBQcmltaXRpdmVUeXBlTmFtZShHZXRKYXZhVHlwZShkZXNjcmlwdG9yKSk7CisgIH0KKyAgLy8gRGVhbHMgd2l0aCBkZWZhdWx0cy4gRm9yIEMrKy1zdHJpbmcgdHlwZXMgKHN0cmluZyBhbmQgYnl0ZXMpLAorICAvLyB3ZSBtaWdodCBuZWVkIHRvIGhhdmUgdGhlIGdlbmVyYXRlZCBjb2RlIGRvIHRoZSB1bmljb2RlIGRlY29kaW5nCisgIC8vIChzZWUgY29tbWVudHMgaW4gSW50ZXJuYWxOYW5vLmphdmEgZm9yIGdvcnkgZGV0YWlscy4pLiBXZSB3b3VsZAorICAvLyBsaWtlIHRvIGRvIHRoaXMgb25jZSBpbnRvIGEgc3RhdGljIGZpZWxkIGFuZCByZS11c2UgdGhhdCBmcm9tCisgIC8vIHRoZW4gb24uCisgIGlmIChkZXNjcmlwdG9yLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9TVFJJTkcgJiYKKyAgICAgICFkZXNjcmlwdG9yLT5kZWZhdWx0X3ZhbHVlX3N0cmluZygpLmVtcHR5KCkgJiYKKyAgICAgICFwYXJhbXMudXNlX3JlZmVyZW5jZV90eXBlc19mb3JfcHJpbWl0aXZlcygpKSB7CisgICAgaWYgKGRlc2NyaXB0b3ItPnR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfQllURVMpIHsKKyAgICAgICgqdmFyaWFibGVzKVsiZGVmYXVsdCJdID0gRGVmYXVsdFZhbHVlKHBhcmFtcywgZGVzY3JpcHRvcik7CisgICAgICAoKnZhcmlhYmxlcylbImRlZmF1bHRfY29uc3RhbnQiXSA9IEZpZWxkRGVmYXVsdENvbnN0YW50TmFtZShkZXNjcmlwdG9yKTsKKyAgICAgICgqdmFyaWFibGVzKVsiZGVmYXVsdF9jb25zdGFudF92YWx1ZSJdID0gc3RyaW5nczo6U3Vic3RpdHV0ZSgKKyAgICAgICAgICAiY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLkludGVybmFsTmFuby5ieXRlc0RlZmF1bHRWYWx1ZShcIiQwXCIpIiwKKyAgICAgICAgICBDRXNjYXBlKGRlc2NyaXB0b3ItPmRlZmF1bHRfdmFsdWVfc3RyaW5nKCkpKTsKKyAgICAgICgqdmFyaWFibGVzKVsiZGVmYXVsdF9jb3B5X2lmX25lZWRlZCJdID0KKyAgICAgICAgICAoKnZhcmlhYmxlcylbImRlZmF1bHQiXSArICIuY2xvbmUoKSI7CisgICAgfSBlbHNlIGlmIChBbGxBc2NpaShkZXNjcmlwdG9yLT5kZWZhdWx0X3ZhbHVlX3N0cmluZygpKSkgeworICAgICAgLy8gQWxsIGNoYXJzIGFyZSBBU0NJSS4gIEluIHRoaXMgY2FzZSBkaXJlY3RseSByZWZlcmVuY2luZyBhCisgICAgICAvLyBDRXNjYXBlKCknZCBzdHJpbmcgbGl0ZXJhbCB3b3JrcyBmaW5lLgorICAgICAgKCp2YXJpYWJsZXMpWyJkZWZhdWx0Il0gPQorICAgICAgICAgICJcIiIgKyBDRXNjYXBlKGRlc2NyaXB0b3ItPmRlZmF1bHRfdmFsdWVfc3RyaW5nKCkpICsgIlwiIjsKKyAgICAgICgqdmFyaWFibGVzKVsiZGVmYXVsdF9jb3B5X2lmX25lZWRlZCJdID0gKCp2YXJpYWJsZXMpWyJkZWZhdWx0Il07CisgICAgfSBlbHNlIHsKKyAgICAgIC8vIFN0cmluZ3Mgd2hlcmUgc29tZSBjaGFycyBhcmUgbm9uLUFTQ0lJLiBXZSBuZWVkIHRvIHNhdmUgdGhlCisgICAgICAvLyBkZWZhdWx0IHZhbHVlLgorICAgICAgKCp2YXJpYWJsZXMpWyJkZWZhdWx0Il0gPSBEZWZhdWx0VmFsdWUocGFyYW1zLCBkZXNjcmlwdG9yKTsKKyAgICAgICgqdmFyaWFibGVzKVsiZGVmYXVsdF9jb25zdGFudCJdID0gRmllbGREZWZhdWx0Q29uc3RhbnROYW1lKGRlc2NyaXB0b3IpOworICAgICAgKCp2YXJpYWJsZXMpWyJkZWZhdWx0X2NvbnN0YW50X3ZhbHVlIl0gPSBzdHJpbmdzOjpTdWJzdGl0dXRlKAorICAgICAgICAgICJjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uSW50ZXJuYWxOYW5vLnN0cmluZ0RlZmF1bHRWYWx1ZShcIiQwXCIpIiwKKyAgICAgICAgICBDRXNjYXBlKGRlc2NyaXB0b3ItPmRlZmF1bHRfdmFsdWVfc3RyaW5nKCkpKTsKKyAgICAgICgqdmFyaWFibGVzKVsiZGVmYXVsdF9jb3B5X2lmX25lZWRlZCJdID0gKCp2YXJpYWJsZXMpWyJkZWZhdWx0Il07CisgICAgfQorICB9IGVsc2UgeworICAgIC8vIE5vbi1zdHJpbmcsIG5vbi1ieXRlcyBmaWVsZC4gRGVmYXVsdHMgYXJlIGxpdGVyYWxzLgorICAgICgqdmFyaWFibGVzKVsiZGVmYXVsdCJdID0gRGVmYXVsdFZhbHVlKHBhcmFtcywgZGVzY3JpcHRvcik7CisgICAgKCp2YXJpYWJsZXMpWyJkZWZhdWx0X2NvcHlfaWZfbmVlZGVkIl0gPSAoKnZhcmlhYmxlcylbImRlZmF1bHQiXTsKKyAgfQorICAoKnZhcmlhYmxlcylbImJveGVkX3R5cGUiXSA9IEJveGVkUHJpbWl0aXZlVHlwZU5hbWUoR2V0SmF2YVR5cGUoZGVzY3JpcHRvcikpOworICAoKnZhcmlhYmxlcylbImNhcGl0YWxpemVkX3R5cGUiXSA9IEdldENhcGl0YWxpemVkVHlwZShkZXNjcmlwdG9yKTsKKyAgKCp2YXJpYWJsZXMpWyJ0YWciXSA9IFNpbXBsZUl0b2EoV2lyZUZvcm1hdDo6TWFrZVRhZyhkZXNjcmlwdG9yKSk7CisgICgqdmFyaWFibGVzKVsidGFnX3NpemUiXSA9IFNpbXBsZUl0b2EoCisgICAgICBXaXJlRm9ybWF0OjpUYWdTaXplKGRlc2NyaXB0b3ItPm51bWJlcigpLCBkZXNjcmlwdG9yLT50eXBlKCkpKTsKKyAgKCp2YXJpYWJsZXMpWyJub25fcGFja2VkX3RhZyJdID0gU2ltcGxlSXRvYSgKKyAgICAgIGludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6TWFrZVRhZyhkZXNjcmlwdG9yLT5udW1iZXIoKSwKKyAgICAgICAgICBpbnRlcm5hbDo6V2lyZUZvcm1hdDo6V2lyZVR5cGVGb3JGaWVsZFR5cGUoZGVzY3JpcHRvci0+dHlwZSgpKSkpOworICBpbnQgZml4ZWRfc2l6ZSA9IEZpeGVkU2l6ZShkZXNjcmlwdG9yLT50eXBlKCkpOworICBpZiAoZml4ZWRfc2l6ZSAhPSAtMSkgeworICAgICgqdmFyaWFibGVzKVsiZml4ZWRfc2l6ZSJdID0gU2ltcGxlSXRvYShmaXhlZF9zaXplKTsKKyAgfQorICAoKnZhcmlhYmxlcylbIm1lc3NhZ2VfbmFtZSJdID0gZGVzY3JpcHRvci0+Y29udGFpbmluZ190eXBlKCktPm5hbWUoKTsKKyAgKCp2YXJpYWJsZXMpWyJlbXB0eV9hcnJheV9uYW1lIl0gPSBFbXB0eUFycmF5TmFtZShwYXJhbXMsIGRlc2NyaXB0b3IpOworfQorfSAgLy8gbmFtZXNwYWNlCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBjb25zdCBQYXJhbXMmIHBhcmFtcykKKyAgOiBGaWVsZEdlbmVyYXRvcihwYXJhbXMpLCBkZXNjcmlwdG9yXyhkZXNjcmlwdG9yKSB7CisgIFNldFByaW1pdGl2ZVZhcmlhYmxlcyhkZXNjcmlwdG9yLCBwYXJhbXMsICZ2YXJpYWJsZXNfKTsKK30KKworUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6On5QcmltaXRpdmVGaWVsZEdlbmVyYXRvcigpIHt9CisKK2Jvb2wgUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OlNhdmVkRGVmYXVsdE5lZWRlZCgpIGNvbnN0IHsKKyAgcmV0dXJuIHZhcmlhYmxlc18uZmluZCgiZGVmYXVsdF9jb25zdGFudCIpICE9IHZhcmlhYmxlc18uZW5kKCk7Cit9CisKK3ZvaWQgUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlSW5pdFNhdmVkRGVmYXVsdENvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKHZhcmlhYmxlc18uZmluZCgiZGVmYXVsdF9jb25zdGFudCIpICE9IHZhcmlhYmxlc18uZW5kKCkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiRkZWZhdWx0X2NvbnN0YW50JCA9ICRkZWZhdWx0X2NvbnN0YW50X3ZhbHVlJDtcbiIpOworICB9Cit9CisKK3ZvaWQgUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyLCBib29sIGxhenlfaW5pdCkgY29uc3QgeworICBpZiAodmFyaWFibGVzXy5maW5kKCJkZWZhdWx0X2NvbnN0YW50IikgIT0gdmFyaWFibGVzXy5lbmQoKSkgeworICAgIC8vIFRob3NlIHByaW1pdGl2ZSB0eXBlcyB0aGF0IG5lZWQgYSBzYXZlZCBkZWZhdWx0LgorICAgIGlmIChsYXp5X2luaXQpIHsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICJwcml2YXRlIHN0YXRpYyAkdHlwZSQgJGRlZmF1bHRfY29uc3RhbnQkO1xuIik7CisgICAgfSBlbHNlIHsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICJwcml2YXRlIHN0YXRpYyBmaW5hbCAkdHlwZSQgJGRlZmF1bHRfY29uc3RhbnQkID1cbiIKKyAgICAgICAgIiAgICAkZGVmYXVsdF9jb25zdGFudF92YWx1ZSQ7XG4iKTsKKyAgICB9CisgIH0KKworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwdWJsaWMgJHR5cGUkICRuYW1lJDtcbiIpOworCisgIGlmIChwYXJhbXNfLmdlbmVyYXRlX2hhcygpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJwdWJsaWMgYm9vbGVhbiBoYXMkY2FwaXRhbGl6ZWRfbmFtZSQ7XG4iKTsKKyAgfQorfQorCit2b2lkIFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQ2xlYXJDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRuYW1lJCA9ICRkZWZhdWx0X2NvcHlfaWZfbmVlZGVkJDtcbiIpOworCisgIGlmIChwYXJhbXNfLmdlbmVyYXRlX2hhcygpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJoYXMkY2FwaXRhbGl6ZWRfbmFtZSQgPSBmYWxzZTtcbiIpOworICB9Cit9CisKK3ZvaWQgUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJ0aGlzLiRuYW1lJCA9IGlucHV0LnJlYWQkY2FwaXRhbGl6ZWRfdHlwZSQoKTtcbiIpOworCisgIGlmIChwYXJhbXNfLmdlbmVyYXRlX2hhcygpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJoYXMkY2FwaXRhbGl6ZWRfbmFtZSQgPSB0cnVlO1xuIik7CisgIH0KK30KKwordm9pZCBQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db25kaXRpb25hbChpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAocGFyYW1zXy51c2VfcmVmZXJlbmNlX3R5cGVzX2Zvcl9wcmltaXRpdmVzKCkpIHsKKyAgICAvLyBGb3IgcmVmZXJlbmNlIHR5cGUgbW9kZSwgc2VyaWFsaXplIGJhc2VkIG9uIGVxdWFsaXR5CisgICAgLy8gdG8gbnVsbC4KKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImlmICh0aGlzLiRuYW1lJCAhPSBudWxsKSB7XG4iKTsKKyAgICByZXR1cm47CisgIH0KKyAgaWYgKHBhcmFtc18uZ2VuZXJhdGVfaGFzKCkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImlmIChoYXMkY2FwaXRhbGl6ZWRfbmFtZSQgfHwgIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJpZiAoIik7CisgIH0KKyAgSmF2YVR5cGUgamF2YV90eXBlID0gR2V0SmF2YVR5cGUoZGVzY3JpcHRvcl8pOworICBpZiAoSXNBcnJheVR5cGUoamF2YV90eXBlKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiIWphdmEudXRpbC5BcnJheXMuZXF1YWxzKHRoaXMuJG5hbWUkLCAkZGVmYXVsdCQpKSB7XG4iKTsKKyAgfSBlbHNlIGlmIChJc1JlZmVyZW5jZVR5cGUoamF2YV90eXBlKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiIXRoaXMuJG5hbWUkLmVxdWFscygkZGVmYXVsdCQpKSB7XG4iKTsKKyAgfSBlbHNlIGlmIChqYXZhX3R5cGUgPT0gSkFWQVRZUEVfRkxPQVQpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cyh0aGlzLiRuYW1lJClcbiIKKyAgICAgICIgICAgIT0gamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKCRkZWZhdWx0JCkpIHtcbiIpOworICB9IGVsc2UgaWYgKGphdmFfdHlwZSA9PSBKQVZBVFlQRV9ET1VCTEUpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImphdmEubGFuZy5Eb3VibGUuZG91YmxlVG9Mb25nQml0cyh0aGlzLiRuYW1lJClcbiIKKyAgICAgICIgICAgIT0gamF2YS5sYW5nLkRvdWJsZS5kb3VibGVUb0xvbmdCaXRzKCRkZWZhdWx0JCkpIHtcbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAidGhpcy4kbmFtZSQgIT0gJGRlZmF1bHQkKSB7XG4iKTsKKyAgfQorfQorCit2b2lkIFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKGRlc2NyaXB0b3JfLT5pc19yZXF1aXJlZCgpICYmICFwYXJhbXNfLmdlbmVyYXRlX2hhcygpKSB7CisgICAgLy8gQWx3YXlzIHNlcmlhbGl6ZSBhIHJlcXVpcmVkIGZpZWxkIGlmIHdlIGRvbid0IGhhdmUgdGhlICdoYXMnIHNpZ25hbC4KKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIm91dHB1dC53cml0ZSRjYXBpdGFsaXplZF90eXBlJCgkbnVtYmVyJCwgdGhpcy4kbmFtZSQpO1xuIik7CisgIH0gZWxzZSB7CisgICAgR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29uZGl0aW9uYWwocHJpbnRlcik7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIgIG91dHB1dC53cml0ZSRjYXBpdGFsaXplZF90eXBlJCgkbnVtYmVyJCwgdGhpcy4kbmFtZSQpO1xuIgorICAgICAgIn1cbiIpOworICB9Cit9CisKK3ZvaWQgUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKGRlc2NyaXB0b3JfLT5pc19yZXF1aXJlZCgpICYmICFwYXJhbXNfLmdlbmVyYXRlX2hhcygpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYubmFuby5Db2RlZE91dHB1dEJ5dGVCdWZmZXJOYW5vXG4iCisgICAgICAiICAgIC5jb21wdXRlJGNhcGl0YWxpemVkX3R5cGUkU2l6ZSgkbnVtYmVyJCwgdGhpcy4kbmFtZSQpO1xuIik7CisgIH0gZWxzZSB7CisgICAgR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29uZGl0aW9uYWwocHJpbnRlcik7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5uYW5vLkNvZGVkT3V0cHV0Qnl0ZUJ1ZmZlck5hbm9cbiIKKyAgICAgICIgICAgICAuY29tcHV0ZSRjYXBpdGFsaXplZF90eXBlJFNpemUoJG51bWJlciQsIHRoaXMuJG5hbWUkKTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorfQorCit2b2lkIFJlcGVhdGVkUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVGaXhDbG9uZWRDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICh0aGlzLiRuYW1lJCAhPSBudWxsICYmIHRoaXMuJG5hbWUkLmxlbmd0aCA+IDApIHtcbiIKKyAgICAiICBjbG9uZWQuJG5hbWUkID0gdGhpcy4kbmFtZSQuY2xvbmUoKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVFcXVhbHNDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIFdlIGRlZmluZSBlcXVhbGl0eSBhcyBzZXJpYWxpemVkIGZvcm0gZXF1YWxpdHkuIElmIGdlbmVyYXRlX2hhcygpLAorICAvLyB0aGVuIGlmIHRoZSBmaWVsZCB2YWx1ZSBlcXVhbHMgdGhlIGRlZmF1bHQgdmFsdWUgaW4gYm90aCBtZXNzYWdlcywKKyAgLy8gYnV0IG9uZSdzICdoYXMnIGZpZWxkIGlzIHNldCBhbmQgdGhlIG90aGVyJ3MgaXMgbm90LCB0aGUgc2VyaWFsaXplZAorICAvLyBmb3JtcyBhcmUgZGlmZmVyZW50IGFuZCB3ZSBzaG91bGQgcmV0dXJuIGZhbHNlLgorICBKYXZhVHlwZSBqYXZhX3R5cGUgPSBHZXRKYXZhVHlwZShkZXNjcmlwdG9yXyk7CisgIGlmIChqYXZhX3R5cGUgPT0gSkFWQVRZUEVfQllURVMpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgImlmICghamF2YS51dGlsLkFycmF5cy5lcXVhbHModGhpcy4kbmFtZSQsIG90aGVyLiRuYW1lJCkiKTsKKyAgICBpZiAocGFyYW1zXy5nZW5lcmF0ZV9oYXMoKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgIlxuIgorICAgICAgICAiICAgIHx8IChqYXZhLnV0aWwuQXJyYXlzLmVxdWFscyh0aGlzLiRuYW1lJCwgJGRlZmF1bHQkKVxuIgorICAgICAgICAiICAgICAgICAmJiB0aGlzLmhhcyRjYXBpdGFsaXplZF9uYW1lJCAhPSBvdGhlci5oYXMkY2FwaXRhbGl6ZWRfbmFtZSQpIik7CisgICAgfQorICAgIHByaW50ZXItPlByaW50KCIpIHtcbiIKKyAgICAgICIgIHJldHVybiBmYWxzZTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfSBlbHNlIGlmIChqYXZhX3R5cGUgPT0gSkFWQVRZUEVfU1RSSU5HCisgICAgICB8fCBwYXJhbXNfLnVzZV9yZWZlcmVuY2VfdHlwZXNfZm9yX3ByaW1pdGl2ZXMoKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaWYgKHRoaXMuJG5hbWUkID09IG51bGwpIHtcbiIKKyAgICAgICIgIGlmIChvdGhlci4kbmFtZSQgIT0gbnVsbCkge1xuIgorICAgICAgIiAgICByZXR1cm4gZmFsc2U7XG4iCisgICAgICAiICB9XG4iCisgICAgICAifSBlbHNlIGlmICghdGhpcy4kbmFtZSQuZXF1YWxzKG90aGVyLiRuYW1lJCkiKTsKKyAgICBpZiAocGFyYW1zXy5nZW5lcmF0ZV9oYXMoKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgIlxuIgorICAgICAgICAiICAgIHx8ICh0aGlzLiRuYW1lJC5lcXVhbHMoJGRlZmF1bHQkKVxuIgorICAgICAgICAiICAgICAgICAmJiB0aGlzLmhhcyRjYXBpdGFsaXplZF9uYW1lJCAhPSBvdGhlci5oYXMkY2FwaXRhbGl6ZWRfbmFtZSQpIik7CisgICAgfQorICAgIHByaW50ZXItPlByaW50KCIpIHtcbiIKKyAgICAgICIgIHJldHVybiBmYWxzZTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfSBlbHNlIGlmIChqYXZhX3R5cGUgPT0gSkFWQVRZUEVfRkxPQVQpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIntcbiIKKyAgICAgICIgIGludCBiaXRzID0gamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKHRoaXMuJG5hbWUkKTtcbiIKKyAgICAgICIgIGlmIChiaXRzICE9IGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cyhvdGhlci4kbmFtZSQpIik7CisgICAgaWYgKHBhcmFtc18uZ2VuZXJhdGVfaGFzKCkpIHsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICJcbiIKKyAgICAgICAgIiAgICAgIHx8IChiaXRzID09IGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cygkZGVmYXVsdCQpXG4iCisgICAgICAgICIgICAgICAgICAgJiYgdGhpcy5oYXMkY2FwaXRhbGl6ZWRfbmFtZSQgIT0gb3RoZXIuaGFzJGNhcGl0YWxpemVkX25hbWUkKSIpOworICAgIH0KKyAgICBwcmludGVyLT5QcmludCgiKSB7XG4iCisgICAgICAiICAgIHJldHVybiBmYWxzZTtcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICJ9XG4iKTsKKyAgfSBlbHNlIGlmIChqYXZhX3R5cGUgPT0gSkFWQVRZUEVfRE9VQkxFKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJ7XG4iCisgICAgICAiICBsb25nIGJpdHMgPSBqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHModGhpcy4kbmFtZSQpO1xuIgorICAgICAgIiAgaWYgKGJpdHMgIT0gamF2YS5sYW5nLkRvdWJsZS5kb3VibGVUb0xvbmdCaXRzKG90aGVyLiRuYW1lJCkiKTsKKyAgICBpZiAocGFyYW1zXy5nZW5lcmF0ZV9oYXMoKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgIlxuIgorICAgICAgICAiICAgICAgfHwgKGJpdHMgPT0gamF2YS5sYW5nLkRvdWJsZS5kb3VibGVUb0xvbmdCaXRzKCRkZWZhdWx0JClcbiIKKyAgICAgICAgIiAgICAgICAgICAmJiB0aGlzLmhhcyRjYXBpdGFsaXplZF9uYW1lJCAhPSBvdGhlci5oYXMkY2FwaXRhbGl6ZWRfbmFtZSQpIik7CisgICAgfQorICAgIHByaW50ZXItPlByaW50KCIpIHtcbiIKKyAgICAgICIgICAgcmV0dXJuIGZhbHNlO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIn1cbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaWYgKHRoaXMuJG5hbWUkICE9IG90aGVyLiRuYW1lJCIpOworICAgIGlmIChwYXJhbXNfLmdlbmVyYXRlX2hhcygpKSB7CisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAiXG4iCisgICAgICAgICIgICAgfHwgKHRoaXMuJG5hbWUkID09ICRkZWZhdWx0JFxuIgorICAgICAgICAiICAgICAgICAmJiB0aGlzLmhhcyRjYXBpdGFsaXplZF9uYW1lJCAhPSBvdGhlci5oYXMkY2FwaXRhbGl6ZWRfbmFtZSQpIik7CisgICAgfQorICAgIHByaW50ZXItPlByaW50KCIpIHtcbiIKKyAgICAgICIgIHJldHVybiBmYWxzZTtcbiIKKyAgICAgICJ9XG4iKTsKKyAgfQorfQorCit2b2lkIFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlSGFzaENvZGVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIEphdmFUeXBlIGphdmFfdHlwZSA9IEdldEphdmFUeXBlKGRlc2NyaXB0b3JfKTsKKyAgaWYgKGphdmFfdHlwZSA9PSBKQVZBVFlQRV9CWVRFUykgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAicmVzdWx0ID0gMzEgKiByZXN1bHQgKyBqYXZhLnV0aWwuQXJyYXlzLmhhc2hDb2RlKHRoaXMuJG5hbWUkKTtcbiIpOworICB9IGVsc2UgaWYgKGphdmFfdHlwZSA9PSBKQVZBVFlQRV9TVFJJTkcKKyAgICAgIHx8IHBhcmFtc18udXNlX3JlZmVyZW5jZV90eXBlc19mb3JfcHJpbWl0aXZlcygpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJyZXN1bHQgPSAzMSAqIHJlc3VsdFxuIgorICAgICAgIiAgICArICh0aGlzLiRuYW1lJCA9PSBudWxsID8gMCA6IHRoaXMuJG5hbWUkLmhhc2hDb2RlKCkpO1xuIik7CisgIH0gZWxzZSB7CisgICAgc3dpdGNoIChqYXZhX3R5cGUpIHsKKyAgICAgIC8vIEZvciBhbGwgSmF2YSBwcmltaXRpdmUgdHlwZXMgYmVsb3csIHRoZSBoYXNoIGNvZGVzIG1hdGNoIHRoZQorICAgICAgLy8gcmVzdWx0cyBvZiBCb3hlZFR5cGUudmFsdWVPZihwcmltaXRpdmVWYWx1ZSkuaGFzaENvZGUoKS4KKyAgICAgIGNhc2UgSkFWQVRZUEVfSU5UOgorICAgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAgICJyZXN1bHQgPSAzMSAqIHJlc3VsdCArIHRoaXMuJG5hbWUkO1xuIik7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBKQVZBVFlQRV9MT05HOgorICAgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAgICJyZXN1bHQgPSAzMSAqIHJlc3VsdFxuIgorICAgICAgICAgICIgICAgKyAoaW50KSAodGhpcy4kbmFtZSQgXiAodGhpcy4kbmFtZSQgPj4+IDMyKSk7XG4iKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIEpBVkFUWVBFX0ZMT0FUOgorICAgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAgICJyZXN1bHQgPSAzMSAqIHJlc3VsdFxuIgorICAgICAgICAgICIgICAgKyBqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHModGhpcy4kbmFtZSQpO1xuIik7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBKQVZBVFlQRV9ET1VCTEU6CisgICAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICAgIntcbiIKKyAgICAgICAgICAiICBsb25nIHYgPSBqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHModGhpcy4kbmFtZSQpO1xuIgorICAgICAgICAgICIgIHJlc3VsdCA9IDMxICogcmVzdWx0ICsgKGludCkgKHYgXiAodiA+Pj4gMzIpKTtcbiIKKyAgICAgICAgICAifVxuIik7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBKQVZBVFlQRV9CT09MRUFOOgorICAgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAgICJyZXN1bHQgPSAzMSAqIHJlc3VsdCArICh0aGlzLiRuYW1lJCA/IDEyMzEgOiAxMjM3KTtcbiIpOworICAgICAgICBicmVhazsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIEdPT0dMRV9MT0coRVJST1IpIDw8ICJ1bmtub3duIGphdmEgdHlwZSBmb3IgcHJpbWl0aXZlIGZpZWxkIjsKKyAgICAgICAgYnJlYWs7CisgICAgfQorICB9Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworQWNjZXNzb3JQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitBY2Nlc3NvclByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgY29uc3QgUGFyYW1zJiBwYXJhbXMsIGludCBoYXNfYml0X2luZGV4KQorICA6IEZpZWxkR2VuZXJhdG9yKHBhcmFtcyksIGRlc2NyaXB0b3JfKGRlc2NyaXB0b3IpIHsKKyAgU2V0UHJpbWl0aXZlVmFyaWFibGVzKGRlc2NyaXB0b3IsIHBhcmFtcywgJnZhcmlhYmxlc18pOworICBTZXRCaXRPcGVyYXRpb25WYXJpYWJsZXMoImhhcyIsIGhhc19iaXRfaW5kZXgsICZ2YXJpYWJsZXNfKTsKK30KKworQWNjZXNzb3JQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6fkFjY2Vzc29yUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IoKSB7fQorCitib29sIEFjY2Vzc29yUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OlNhdmVkRGVmYXVsdE5lZWRlZCgpIGNvbnN0IHsKKyAgcmV0dXJuIHZhcmlhYmxlc18uZmluZCgiZGVmYXVsdF9jb25zdGFudCIpICE9IHZhcmlhYmxlc18uZW5kKCk7Cit9CisKK3ZvaWQgQWNjZXNzb3JQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUluaXRTYXZlZERlZmF1bHRDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmICh2YXJpYWJsZXNfLmZpbmQoImRlZmF1bHRfY29uc3RhbnQiKSAhPSB2YXJpYWJsZXNfLmVuZCgpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICIkZGVmYXVsdF9jb25zdGFudCQgPSAkZGVmYXVsdF9jb25zdGFudF92YWx1ZSQ7XG4iKTsKKyAgfQorfQorCit2b2lkIEFjY2Vzc29yUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyLCBib29sIGxhenlfaW5pdCkgY29uc3QgeworICBpZiAodmFyaWFibGVzXy5maW5kKCJkZWZhdWx0X2NvbnN0YW50IikgIT0gdmFyaWFibGVzXy5lbmQoKSkgeworICAgIC8vIFRob3NlIHByaW1pdGl2ZSB0eXBlcyB0aGF0IG5lZWQgYSBzYXZlZCBkZWZhdWx0LgorICAgIGlmIChsYXp5X2luaXQpIHsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICJwcml2YXRlIHN0YXRpYyAkdHlwZSQgJGRlZmF1bHRfY29uc3RhbnQkO1xuIik7CisgICAgfSBlbHNlIHsKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICJwcml2YXRlIHN0YXRpYyBmaW5hbCAkdHlwZSQgJGRlZmF1bHRfY29uc3RhbnQkID1cbiIKKyAgICAgICAgIiAgICAkZGVmYXVsdF9jb25zdGFudF92YWx1ZSQ7XG4iKTsKKyAgICB9CisgIH0KKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAicHJpdmF0ZSAkdHlwZSQgJG5hbWUkXztcbiIKKyAgICAicHVibGljICR0eXBlJCBnZXQkY2FwaXRhbGl6ZWRfbmFtZSQoKSB7XG4iCisgICAgIiAgcmV0dXJuICRuYW1lJF87XG4iCisgICAgIn1cbiIKKyAgICAicHVibGljICRtZXNzYWdlX25hbWUkIHNldCRjYXBpdGFsaXplZF9uYW1lJCgkdHlwZSQgdmFsdWUpIHtcbiIpOworICBpZiAoSXNSZWZlcmVuY2VUeXBlKEdldEphdmFUeXBlKGRlc2NyaXB0b3JfKSkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIiAgaWYgKHZhbHVlID09IG51bGwpIHtcbiIKKyAgICAgICIgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpO1xuIgorICAgICAgIiAgfVxuIik7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiICAkbmFtZSRfID0gdmFsdWU7XG4iCisgICAgIiAgJHNldF9oYXMkO1xuIgorICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICJ9XG4iCisgICAgInB1YmxpYyBib29sZWFuIGhhcyRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAiICByZXR1cm4gJGdldF9oYXMkO1xuIgorICAgICJ9XG4iCisgICAgInB1YmxpYyAkbWVzc2FnZV9uYW1lJCBjbGVhciRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAiICAkbmFtZSRfID0gJGRlZmF1bHRfY29weV9pZl9uZWVkZWQkO1xuIgorICAgICIgICRjbGVhcl9oYXMkO1xuIgorICAgICIgIHJldHVybiB0aGlzO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBBY2Nlc3NvclByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlQ2xlYXJDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgIiRuYW1lJF8gPSAkZGVmYXVsdF9jb3B5X2lmX25lZWRlZCQ7XG4iKTsKK30KKwordm9pZCBBY2Nlc3NvclByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiJG5hbWUkXyA9IGlucHV0LnJlYWQkY2FwaXRhbGl6ZWRfdHlwZSQoKTtcbiIKKyAgICAiJHNldF9oYXMkO1xuIik7Cit9CisKK3ZvaWQgQWNjZXNzb3JQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVNlcmlhbGl6YXRpb25Db2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkZ2V0X2hhcyQpIHtcbiIKKyAgICAiICBvdXRwdXQud3JpdGUkY2FwaXRhbGl6ZWRfdHlwZSQoJG51bWJlciQsICRuYW1lJF8pO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBBY2Nlc3NvclByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkZ2V0X2hhcyQpIHtcbiIKKyAgICAiICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYubmFuby5Db2RlZE91dHB1dEJ5dGVCdWZmZXJOYW5vXG4iCisgICAgIiAgICAgIC5jb21wdXRlJGNhcGl0YWxpemVkX3R5cGUkU2l6ZSgkbnVtYmVyJCwgJG5hbWUkXyk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIEFjY2Vzc29yUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVFcXVhbHNDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHN3aXRjaCAoR2V0SmF2YVR5cGUoZGVzY3JpcHRvcl8pKSB7CisgICAgLy8gRm9yIGFsbCBKYXZhIHByaW1pdGl2ZSB0eXBlcyBiZWxvdywgdGhlIGVxdWFsaXR5IGNoZWNrcyBtYXRjaCB0aGUKKyAgICAvLyByZXN1bHRzIG9mIEJveGVkVHlwZS52YWx1ZU9mKHByaW1pdGl2ZVZhbHVlKS5lcXVhbHMob3RoZXJWYWx1ZSkuCisgICAgY2FzZSBKQVZBVFlQRV9GTE9BVDoKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICJpZiAoJGRpZmZlcmVudF9oYXMkXG4iCisgICAgICAgICIgICAgfHwgamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKCRuYW1lJF8pXG4iCisgICAgICAgICIgICAgICAgICE9IGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cyhvdGhlci4kbmFtZSRfKSkge1xuIgorICAgICAgICAiICByZXR1cm4gZmFsc2U7XG4iCisgICAgICAgICJ9XG4iKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgSkFWQVRZUEVfRE9VQkxFOgorICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgImlmICgkZGlmZmVyZW50X2hhcyRcbiIKKyAgICAgICAgIiAgICB8fCBqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoJG5hbWUkXylcbiIKKyAgICAgICAgIiAgICAgICAgIT0gamF2YS5sYW5nLkRvdWJsZS5kb3VibGVUb0xvbmdCaXRzKG90aGVyLiRuYW1lJF8pKSB7XG4iCisgICAgICAgICIgIHJldHVybiBmYWxzZTtcbiIKKyAgICAgICAgIn1cbiIpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBKQVZBVFlQRV9JTlQ6CisgICAgY2FzZSBKQVZBVFlQRV9MT05HOgorICAgIGNhc2UgSkFWQVRZUEVfQk9PTEVBTjoKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICJpZiAoJGRpZmZlcmVudF9oYXMkXG4iCisgICAgICAgICIgICAgfHwgJG5hbWUkXyAhPSBvdGhlci4kbmFtZSRfKSB7XG4iCisgICAgICAgICIgIHJldHVybiBmYWxzZTtcbiIKKyAgICAgICAgIn1cbiIpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBKQVZBVFlQRV9TVFJJTkc6CisgICAgICAvLyBBY2Nlc3NvciBzdHlsZSB3b3VsZCBndWFyYW50ZWUgJG5hbWUkXyBub24tbnVsbAorICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgImlmICgkZGlmZmVyZW50X2hhcyRcbiIKKyAgICAgICAgIiAgICB8fCAhJG5hbWUkXy5lcXVhbHMob3RoZXIuJG5hbWUkXykpIHtcbiIKKyAgICAgICAgIiAgcmV0dXJuIGZhbHNlO1xuIgorICAgICAgICAifVxuIik7CisgICAgICBicmVhazsKKyAgICBjYXNlIEpBVkFUWVBFX0JZVEVTOgorICAgICAgLy8gQWNjZXNzb3Igc3R5bGUgd291bGQgZ3VhcmFudGVlICRuYW1lJF8gbm9uLW51bGwKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICJpZiAoJGRpZmZlcmVudF9oYXMkXG4iCisgICAgICAgICIgICAgfHwgIWphdmEudXRpbC5BcnJheXMuZXF1YWxzKCRuYW1lJF8sIG90aGVyLiRuYW1lJF8pKSB7XG4iCisgICAgICAgICIgIHJldHVybiBmYWxzZTtcbiIKKyAgICAgICAgIn1cbiIpOworICAgICAgYnJlYWs7CisgICAgZGVmYXVsdDoKKyAgICAgIEdPT0dMRV9MT0coRVJST1IpIDw8ICJ1bmtub3duIGphdmEgdHlwZSBmb3IgcHJpbWl0aXZlIGZpZWxkIjsKKyAgICAgIGJyZWFrOworICB9Cit9CisKK3ZvaWQgQWNjZXNzb3JQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUhhc2hDb2RlQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBzd2l0Y2ggKEdldEphdmFUeXBlKGRlc2NyaXB0b3JfKSkgeworICAgIC8vIEZvciBhbGwgSmF2YSBwcmltaXRpdmUgdHlwZXMgYmVsb3csIHRoZSBoYXNoIGNvZGVzIG1hdGNoIHRoZQorICAgIC8vIHJlc3VsdHMgb2YgQm94ZWRUeXBlLnZhbHVlT2YocHJpbWl0aXZlVmFsdWUpLmhhc2hDb2RlKCkuCisgICAgY2FzZSBKQVZBVFlQRV9JTlQ6CisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAicmVzdWx0ID0gMzEgKiByZXN1bHQgKyAkbmFtZSRfO1xuIik7CisgICAgICBicmVhazsKKyAgICBjYXNlIEpBVkFUWVBFX0xPTkc6CisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAicmVzdWx0ID0gMzEgKiByZXN1bHQgKyAoaW50KSAoJG5hbWUkXyBeICgkbmFtZSRfID4+PiAzMikpO1xuIik7CisgICAgICBicmVhazsKKyAgICBjYXNlIEpBVkFUWVBFX0ZMT0FUOgorICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgInJlc3VsdCA9IDMxICogcmVzdWx0ICtcbiIKKyAgICAgICAgIiAgICBqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoJG5hbWUkXyk7XG4iKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgSkFWQVRZUEVfRE9VQkxFOgorICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgIntcbiIKKyAgICAgICAgIiAgbG9uZyB2ID0gamF2YS5sYW5nLkRvdWJsZS5kb3VibGVUb0xvbmdCaXRzKCRuYW1lJF8pO1xuIgorICAgICAgICAiICByZXN1bHQgPSAzMSAqIHJlc3VsdCArIChpbnQpICh2IF4gKHYgPj4+IDMyKSk7XG4iCisgICAgICAgICJ9XG4iKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgSkFWQVRZUEVfQk9PTEVBTjoKKyAgICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICJyZXN1bHQgPSAzMSAqIHJlc3VsdCArICgkbmFtZSRfID8gMTIzMSA6IDEyMzcpO1xuIik7CisgICAgICBicmVhazsKKyAgICBjYXNlIEpBVkFUWVBFX1NUUklORzoKKyAgICAgIC8vIEFjY2Vzc29yIHN0eWxlIHdvdWxkIGd1YXJhbnRlZSAkbmFtZSRfIG5vbi1udWxsCisgICAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAicmVzdWx0ID0gMzEgKiByZXN1bHQgKyAkbmFtZSRfLmhhc2hDb2RlKCk7XG4iKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgSkFWQVRZUEVfQllURVM6CisgICAgICAvLyBBY2Nlc3NvciBzdHlsZSB3b3VsZCBndWFyYW50ZWUgJG5hbWUkXyBub24tbnVsbAorICAgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICAgInJlc3VsdCA9IDMxICogcmVzdWx0ICsgamF2YS51dGlsLkFycmF5cy5oYXNoQ29kZSgkbmFtZSRfKTtcbiIpOworICAgICAgYnJlYWs7CisgICAgZGVmYXVsdDoKKyAgICAgIEdPT0dMRV9MT0coRVJST1IpIDw8ICJ1bmtub3duIGphdmEgdHlwZSBmb3IgcHJpbWl0aXZlIGZpZWxkIjsKKyAgICAgIGJyZWFrOworICB9Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworUHJpbWl0aXZlT25lb2ZGaWVsZEdlbmVyYXRvcjo6UHJpbWl0aXZlT25lb2ZGaWVsZEdlbmVyYXRvcigKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGNvbnN0IFBhcmFtcyYgcGFyYW1zKQorICA6IEZpZWxkR2VuZXJhdG9yKHBhcmFtcyksIGRlc2NyaXB0b3JfKGRlc2NyaXB0b3IpIHsKKyAgICBTZXRQcmltaXRpdmVWYXJpYWJsZXMoZGVzY3JpcHRvciwgcGFyYW1zLCAmdmFyaWFibGVzXyk7CisgICAgU2V0Q29tbW9uT25lb2ZWYXJpYWJsZXMoZGVzY3JpcHRvciwgJnZhcmlhYmxlc18pOworfQorCitQcmltaXRpdmVPbmVvZkZpZWxkR2VuZXJhdG9yOjp+UHJpbWl0aXZlT25lb2ZGaWVsZEdlbmVyYXRvcigpIHt9CisKK3ZvaWQgUHJpbWl0aXZlT25lb2ZGaWVsZEdlbmVyYXRvcjo6R2VuZXJhdGVNZW1iZXJzKAorICAgIGlvOjpQcmludGVyKiBwcmludGVyLCBib29sIC8qdW51c2VkIGxhenlfaW5pdCovKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInB1YmxpYyBib29sZWFuIGhhcyRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAiICByZXR1cm4gJGhhc19vbmVvZl9jYXNlJDtcbiIKKyAgICAifVxuIgorICAgICJwdWJsaWMgJHR5cGUkIGdldCRjYXBpdGFsaXplZF9uYW1lJCgpIHtcbiIKKyAgICAiICBpZiAoJGhhc19vbmVvZl9jYXNlJCkge1xuIgorICAgICIgICAgcmV0dXJuICgkdHlwZSQpICgkYm94ZWRfdHlwZSQpIHRoaXMuJG9uZW9mX25hbWUkXztcbiIKKyAgICAiICB9XG4iCisgICAgIiAgcmV0dXJuICRkZWZhdWx0JDtcbiIKKyAgICAifVxuIgorICAgICJwdWJsaWMgJG1lc3NhZ2VfbmFtZSQgc2V0JGNhcGl0YWxpemVkX25hbWUkKCR0eXBlJCB2YWx1ZSkge1xuIgorICAgICIgICRzZXRfb25lb2ZfY2FzZSQ7XG4iCisgICAgIiAgdGhpcy4kb25lb2ZfbmFtZSRfID0gdmFsdWU7XG4iCisgICAgIiAgcmV0dXJuIHRoaXM7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIFByaW1pdGl2ZU9uZW9mRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlQ2xlYXJDb2RlKAorICAgIGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIE5vIGNsZWFyIG1ldGhvZCBmb3Igb25lb2YgZmllbGRzLgorfQorCit2b2lkIFByaW1pdGl2ZU9uZW9mRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlTWVyZ2luZ0NvZGUoCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAidGhpcy4kb25lb2ZfbmFtZSRfID0gaW5wdXQucmVhZCRjYXBpdGFsaXplZF90eXBlJCgpO1xuIgorICAgICIkc2V0X29uZW9mX2Nhc2UkO1xuIik7Cit9CisKK3ZvaWQgUHJpbWl0aXZlT25lb2ZGaWVsZEdlbmVyYXRvcjo6R2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZSgKKyAgICBpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoJGhhc19vbmVvZl9jYXNlJCkge1xuIgorICAgICIgIG91dHB1dC53cml0ZSRjYXBpdGFsaXplZF90eXBlJChcbiIKKyAgICAiICAgICAgJG51bWJlciQsICgkYm94ZWRfdHlwZSQpIHRoaXMuJG9uZW9mX25hbWUkXyk7XG4iCisgICAgIn1cbiIpOworfQorCit2b2lkIFByaW1pdGl2ZU9uZW9mRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKAorICAgIGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICgkaGFzX29uZW9mX2Nhc2UkKSB7XG4iCisgICAgIiAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFub1xuIgorICAgICIgICAgICAuY29tcHV0ZSRjYXBpdGFsaXplZF90eXBlJFNpemUoXG4iCisgICAgIiAgICAgICAgICAkbnVtYmVyJCwgKCRib3hlZF90eXBlJCkgdGhpcy4kb25lb2ZfbmFtZSRfKTtcbiIKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUHJpbWl0aXZlT25lb2ZGaWVsZEdlbmVyYXRvcjo6R2VuZXJhdGVFcXVhbHNDb2RlKAorICAgIGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIEdlbmVyYXRlT25lb2ZGaWVsZEVxdWFscyhkZXNjcmlwdG9yXywgdmFyaWFibGVzXywgcHJpbnRlcik7Cit9CisKK3ZvaWQgUHJpbWl0aXZlT25lb2ZGaWVsZEdlbmVyYXRvcjo6R2VuZXJhdGVIYXNoQ29kZUNvZGUoCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgR2VuZXJhdGVPbmVvZkZpZWxkSGFzaENvZGUoZGVzY3JpcHRvcl8sIHZhcmlhYmxlc18sIHByaW50ZXIpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK1JlcGVhdGVkUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OlJlcGVhdGVkUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IoCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBjb25zdCBQYXJhbXMmIHBhcmFtcykKKyAgOiBGaWVsZEdlbmVyYXRvcihwYXJhbXMpLCBkZXNjcmlwdG9yXyhkZXNjcmlwdG9yKSB7CisgIFNldFByaW1pdGl2ZVZhcmlhYmxlcyhkZXNjcmlwdG9yLCBwYXJhbXMsICZ2YXJpYWJsZXNfKTsKK30KKworUmVwZWF0ZWRQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6flJlcGVhdGVkUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IoKSB7fQorCit2b2lkIFJlcGVhdGVkUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6OgorR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyLCBib29sIC8qdW51c2VkIGluaXRfZGVmYXVsdHMqLykgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJwdWJsaWMgJHR5cGUkW10gJG5hbWUkO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUNsZWFyQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICIkbmFtZSQgPSAkZGVmYXVsdCQ7XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gRmlyc3QsIGZpZ3VyZSBvdXQgdGhlIGxlbmd0aCBvZiB0aGUgYXJyYXksIHRoZW4gcGFyc2UuCisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImludCBhcnJheUxlbmd0aCA9IGNvbS5nb29nbGUucHJvdG9idWYubmFuby5XaXJlRm9ybWF0TmFub1xuIgorICAgICIgICAgLmdldFJlcGVhdGVkRmllbGRBcnJheUxlbmd0aChpbnB1dCwgJG5vbl9wYWNrZWRfdGFnJCk7XG4iCisgICAgImludCBpID0gdGhpcy4kbmFtZSQgPT0gbnVsbCA/IDAgOiB0aGlzLiRuYW1lJC5sZW5ndGg7XG4iKTsKKworICBpZiAoR2V0SmF2YVR5cGUoZGVzY3JpcHRvcl8pID09IEpBVkFUWVBFX0JZVEVTKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJieXRlW11bXSBuZXdBcnJheSA9IG5ldyBieXRlW2kgKyBhcnJheUxlbmd0aF1bXTtcbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiJHR5cGUkW10gbmV3QXJyYXkgPSBuZXcgJHR5cGUkW2kgKyBhcnJheUxlbmd0aF07XG4iKTsKKyAgfQorICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICJpZiAoaSAhPSAwKSB7XG4iCisgICAgIiAgamF2YS5sYW5nLlN5c3RlbS5hcnJheWNvcHkodGhpcy4kbmFtZSQsIDAsIG5ld0FycmF5LCAwLCBpKTtcbiIKKyAgICAifVxuIgorICAgICJmb3IgKDsgaSA8IG5ld0FycmF5Lmxlbmd0aCAtIDE7IGkrKykge1xuIgorICAgICIgIG5ld0FycmF5W2ldID0gaW5wdXQucmVhZCRjYXBpdGFsaXplZF90eXBlJCgpO1xuIgorICAgICIgIGlucHV0LnJlYWRUYWcoKTtcbiIKKyAgICAifVxuIgorICAgICIvLyBMYXN0IG9uZSB3aXRob3V0IHJlYWRUYWcuXG4iCisgICAgIm5ld0FycmF5W2ldID0gaW5wdXQucmVhZCRjYXBpdGFsaXplZF90eXBlJCgpO1xuIgorICAgICJ0aGlzLiRuYW1lJCA9IG5ld0FycmF5O1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZU1lcmdpbmdDb2RlRnJvbVBhY2tlZChpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCgKKyAgICAiaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpO1xuIgorICAgICJpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTtcbiIpOworCisgIC8vIElmIHdlIGtub3cgdGhlIGVsZW1lbnRzIHdpbGwgYWxsIGJlIG9mIHRoZSBzYW1lIHNpemUsIHRoZSBhcnJheUxlbmd0aAorICAvLyBjYW4gYmUgY2FsY3VsYXRlZCBtdWNoIG1vcmUgZWFzaWx5LiBIb3dldmVyLCBGaXhlZFNpemUoKSByZXR1cm5zIDEgZm9yCisgIC8vIHJlcGVhdGVkIGJvb2wgZmllbGRzLCB3aGljaCBhcmUgZ3VhcmFudGVlZCB0byBoYXZlIHRoZSBmaXhlZCBzaXplIG9mCisgIC8vIDEgYnl0ZSBwZXIgdmFsdWUgb25seSBpZiB3ZSBjb250cm9sIHRoZSBvdXRwdXQuIE9uIHRoZSB3aXJlIHRoZXkgY2FuCisgIC8vIGxlZ2FsbHkgYXBwZWFyIGFzIHZhcmlhYmxlLXNpemUgaW50ZWdlcnMsIHNvIHdlIG5lZWQgdG8gdXNlIHRoZSBzbG93CisgIC8vIHdheSBmb3IgcmVwZWF0ZWQgYm9vbCBmaWVsZHMuCisgIGlmIChkZXNjcmlwdG9yXy0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9CT09MCisgICAgICB8fCBGaXhlZFNpemUoZGVzY3JpcHRvcl8tPnR5cGUoKSkgPT0gLTEpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIi8vIEZpcnN0IHBhc3MgdG8gY29tcHV0ZSBhcnJheSBsZW5ndGguXG4iCisgICAgICAiaW50IGFycmF5TGVuZ3RoID0gMDtcbiIKKyAgICAgICJpbnQgc3RhcnRQb3MgPSBpbnB1dC5nZXRQb3NpdGlvbigpO1xuIgorICAgICAgIndoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHtcbiIKKyAgICAgICIgIGlucHV0LnJlYWQkY2FwaXRhbGl6ZWRfdHlwZSQoKTtcbiIKKyAgICAgICIgIGFycmF5TGVuZ3RoKys7XG4iCisgICAgICAifVxuIgorICAgICAgImlucHV0LnJld2luZFRvUG9zaXRpb24oc3RhcnRQb3MpO1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJpbnQgYXJyYXlMZW5ndGggPSBsZW5ndGggLyAkZml4ZWRfc2l6ZSQ7XG4iKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImludCBpID0gdGhpcy4kbmFtZSQgPT0gbnVsbCA/IDAgOiB0aGlzLiRuYW1lJC5sZW5ndGg7XG4iCisgICAgIiR0eXBlJFtdIG5ld0FycmF5ID0gbmV3ICR0eXBlJFtpICsgYXJyYXlMZW5ndGhdO1xuIgorICAgICJpZiAoaSAhPSAwKSB7XG4iCisgICAgIiAgamF2YS5sYW5nLlN5c3RlbS5hcnJheWNvcHkodGhpcy4kbmFtZSQsIDAsIG5ld0FycmF5LCAwLCBpKTtcbiIKKyAgICAifVxuIgorICAgICJmb3IgKDsgaSA8IG5ld0FycmF5Lmxlbmd0aDsgaSsrKSB7XG4iCisgICAgIiAgbmV3QXJyYXlbaV0gPSBpbnB1dC5yZWFkJGNhcGl0YWxpemVkX3R5cGUkKCk7XG4iCisgICAgIn1cbiIKKyAgICAidGhpcy4kbmFtZSQgPSBuZXdBcnJheTtcbiIKKyAgICAiaW5wdXQucG9wTGltaXQobGltaXQpO1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZVJlcGVhdGVkRGF0YVNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIENyZWF0ZXMgYSB2YXJpYWJsZSBkYXRhU2l6ZSBhbmQgcHV0cyB0aGUgc2VyaWFsaXplZCBzaXplIGluIHRoZXJlLgorICAvLyBJZiB0aGUgZWxlbWVudCB0eXBlIGlzIGEgSmF2YSByZWZlcmVuY2UgdHlwZSwgYWxzbyBnZW5lcmF0ZXMKKyAgLy8gZGF0YUNvdW50IHdoaWNoIHN0b3JlcyB0aGUgbnVtYmVyIG9mIG5vbi1udWxsIGVsZW1lbnRzIGluIHRoZSBmaWVsZC4KKyAgaWYgKElzUmVmZXJlbmNlVHlwZShHZXRKYXZhVHlwZShkZXNjcmlwdG9yXykpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJpbnQgZGF0YUNvdW50ID0gMDtcbiIKKyAgICAgICJpbnQgZGF0YVNpemUgPSAwO1xuIgorICAgICAgImZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy4kbmFtZSQubGVuZ3RoOyBpKyspIHtcbiIKKyAgICAgICIgICR0eXBlJCBlbGVtZW50ID0gdGhpcy4kbmFtZSRbaV07XG4iCisgICAgICAiICBpZiAoZWxlbWVudCAhPSBudWxsKSB7XG4iCisgICAgICAiICAgIGRhdGFDb3VudCsrO1xuIgorICAgICAgIiAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFub1xuIgorICAgICAgIiAgICAgICAgLmNvbXB1dGUkY2FwaXRhbGl6ZWRfdHlwZSRTaXplTm9UYWcoZWxlbWVudCk7XG4iCisgICAgICAiICB9XG4iCisgICAgICAifVxuIik7CisgIH0gZWxzZSBpZiAoRml4ZWRTaXplKGRlc2NyaXB0b3JfLT50eXBlKCkpID09IC0xKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJpbnQgZGF0YVNpemUgPSAwO1xuIgorICAgICAgImZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy4kbmFtZSQubGVuZ3RoOyBpKyspIHtcbiIKKyAgICAgICIgICR0eXBlJCBlbGVtZW50ID0gdGhpcy4kbmFtZSRbaV07XG4iCisgICAgICAiICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFub1xuIgorICAgICAgIiAgICAgIC5jb21wdXRlJGNhcGl0YWxpemVkX3R5cGUkU2l6ZU5vVGFnKGVsZW1lbnQpO1xuIgorICAgICAgIn1cbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiaW50IGRhdGFTaXplID0gJGZpeGVkX3NpemUkICogdGhpcy4kbmFtZSQubGVuZ3RoO1xuIik7CisgIH0KK30KKwordm9pZCBSZXBlYXRlZFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKHRoaXMuJG5hbWUkICE9IG51bGwgJiYgdGhpcy4kbmFtZSQubGVuZ3RoID4gMCkge1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIGlmIChkZXNjcmlwdG9yXy0+aXNfcGFja2FibGUoKSAmJiBkZXNjcmlwdG9yXy0+b3B0aW9ucygpLnBhY2tlZCgpKSB7CisgICAgR2VuZXJhdGVSZXBlYXRlZERhdGFTaXplQ29kZShwcmludGVyKTsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgIm91dHB1dC53cml0ZVJhd1ZhcmludDMyKCR0YWckKTtcbiIKKyAgICAgICJvdXRwdXQud3JpdGVSYXdWYXJpbnQzMihkYXRhU2l6ZSk7XG4iCisgICAgICAiZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLiRuYW1lJC5sZW5ndGg7IGkrKykge1xuIgorICAgICAgIiAgb3V0cHV0LndyaXRlJGNhcGl0YWxpemVkX3R5cGUkTm9UYWcodGhpcy4kbmFtZSRbaV0pO1xuIgorICAgICAgIn1cbiIpOworICB9IGVsc2UgaWYgKElzUmVmZXJlbmNlVHlwZShHZXRKYXZhVHlwZShkZXNjcmlwdG9yXykpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJmb3IgKGludCBpID0gMDsgaSA8IHRoaXMuJG5hbWUkLmxlbmd0aDsgaSsrKSB7XG4iCisgICAgICAiICAkdHlwZSQgZWxlbWVudCA9IHRoaXMuJG5hbWUkW2ldO1xuIgorICAgICAgIiAgaWYgKGVsZW1lbnQgIT0gbnVsbCkge1xuIgorICAgICAgIiAgICBvdXRwdXQud3JpdGUkY2FwaXRhbGl6ZWRfdHlwZSQoJG51bWJlciQsIGVsZW1lbnQpO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIn1cbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAiZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLiRuYW1lJC5sZW5ndGg7IGkrKykge1xuIgorICAgICAgIiAgb3V0cHV0LndyaXRlJGNhcGl0YWxpemVkX3R5cGUkKCRudW1iZXIkLCB0aGlzLiRuYW1lJFtpXSk7XG4iCisgICAgICAifVxuIik7CisgIH0KKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KCJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgImlmICh0aGlzLiRuYW1lJCAhPSBudWxsICYmIHRoaXMuJG5hbWUkLmxlbmd0aCA+IDApIHtcbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBHZW5lcmF0ZVJlcGVhdGVkRGF0YVNpemVDb2RlKHByaW50ZXIpOworCisgIHByaW50ZXItPlByaW50KAorICAgICJzaXplICs9IGRhdGFTaXplO1xuIik7CisgIGlmIChkZXNjcmlwdG9yXy0+aXNfcGFja2FibGUoKSAmJiBkZXNjcmlwdG9yXy0+b3B0aW9ucygpLnBhY2tlZCgpKSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJzaXplICs9ICR0YWdfc2l6ZSQ7XG4iCisgICAgICAic2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uQ29kZWRPdXRwdXRCeXRlQnVmZmVyTmFub1xuIgorICAgICAgIiAgICAuY29tcHV0ZVJhd1ZhcmludDMyU2l6ZShkYXRhU2l6ZSk7XG4iKTsKKyAgfSBlbHNlIGlmIChJc1JlZmVyZW5jZVR5cGUoR2V0SmF2YVR5cGUoZGVzY3JpcHRvcl8pKSkgeworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAic2l6ZSArPSAkdGFnX3NpemUkICogZGF0YUNvdW50O1xuIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAgICJzaXplICs9ICR0YWdfc2l6ZSQgKiB0aGlzLiRuYW1lJC5sZW5ndGg7XG4iKTsKKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKworICBwcmludGVyLT5QcmludCgKKyAgICAifVxuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6CitHZW5lcmF0ZUVxdWFsc0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywKKyAgICAiaWYgKCFjb20uZ29vZ2xlLnByb3RvYnVmLm5hbm8uSW50ZXJuYWxOYW5vLmVxdWFscyhcbiIKKyAgICAiICAgIHRoaXMuJG5hbWUkLCBvdGhlci4kbmFtZSQpKSB7XG4iCisgICAgIiAgcmV0dXJuIGZhbHNlO1xuIgorICAgICJ9XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjoKK0dlbmVyYXRlSGFzaENvZGVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgInJlc3VsdCA9IDMxICogcmVzdWx0XG4iCisgICAgIiAgICArIGNvbS5nb29nbGUucHJvdG9idWYubmFuby5JbnRlcm5hbE5hbm8uaGFzaENvZGUodGhpcy4kbmFtZSQpO1xuIik7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBqYXZhbmFubworfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fcHJpbWl0aXZlX2ZpZWxkLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX3ByaW1pdGl2ZV9maWVsZC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmEwMTk4MWQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmFuYW5vL2phdmFuYW5vX3ByaW1pdGl2ZV9maWVsZC5oCkBAIC0wLDAgKzEsMTUwIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL3Byb3RvYnVmLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQU5BTk9fUFJJTUlUSVZFX0ZJRUxEX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSkFWQU5BTk9fUFJJTUlUSVZFX0ZJRUxEX0hfXworCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZmllbGQuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqYXZhbmFubyB7CisKK2NsYXNzIFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yIDogcHVibGljIEZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKAorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBjb25zdCBQYXJhbXMmIHBhcmFtcyk7CisgIH5QcmltaXRpdmVGaWVsZEdlbmVyYXRvcigpOworCisgIC8vIGltcGxlbWVudHMgRmllbGRHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIGJvb2wgU2F2ZWREZWZhdWx0TmVlZGVkKCkgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVJbml0U2F2ZWREZWZhdWx0Q29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyLCBib29sIGxhenlfaW5pdCkgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVDbGVhckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUVxdWFsc0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSGFzaENvZGVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKworIHByaXZhdGU6CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29uZGl0aW9uYWwoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcl87CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyaWFibGVzXzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IpOworfTsKKworY2xhc3MgQWNjZXNzb3JQcmltaXRpdmVGaWVsZEdlbmVyYXRvciA6IHB1YmxpYyBGaWVsZEdlbmVyYXRvciB7CisgcHVibGljOgorICBleHBsaWNpdCBBY2Nlc3NvclByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgIGNvbnN0IFBhcmFtcyAmcGFyYW1zLCBpbnQgaGFzX2JpdF9pbmRleCk7CisgIH5BY2Nlc3NvclByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKCk7CisKKyAgLy8gaW1wbGVtZW50cyBGaWVsZEdlbmVyYXRvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgYm9vbCBTYXZlZERlZmF1bHROZWVkZWQoKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUluaXRTYXZlZERlZmF1bHRDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU1lbWJlcnMoaW86OlByaW50ZXIqIHByaW50ZXIsIGJvb2wgbGF6eV9pbml0KSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUNsZWFyQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVNZXJnaW5nQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVIYXNoQ29kZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXNfOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhBY2Nlc3NvclByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKTsKK307CisKK2NsYXNzIFByaW1pdGl2ZU9uZW9mRmllbGRHZW5lcmF0b3IgOiBwdWJsaWMgRmllbGRHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgUHJpbWl0aXZlT25lb2ZGaWVsZEdlbmVyYXRvcigKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwgY29uc3QgUGFyYW1zJiBwYXJhbXMpOworICB+UHJpbWl0aXZlT25lb2ZGaWVsZEdlbmVyYXRvcigpOworCisgIC8vIGltcGxlbWVudHMgRmllbGRHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIHZvaWQgR2VuZXJhdGVNZW1iZXJzKGlvOjpQcmludGVyKiBwcmludGVyLCBib29sIGxhenlfaW5pdCkgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVDbGVhckNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlTWVyZ2luZ0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXphdGlvbkNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlU2VyaWFsaXplZFNpemVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUVxdWFsc0NvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlSGFzaENvZGVDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKworIHByaXZhdGU6CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcl87CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyaWFibGVzXzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoUHJpbWl0aXZlT25lb2ZGaWVsZEdlbmVyYXRvcik7Cit9OworCitjbGFzcyBSZXBlYXRlZFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yIDogcHVibGljIEZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IFJlcGVhdGVkUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFBhcmFtcyYgcGFyYW1zKTsKKyAgflJlcGVhdGVkUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IoKTsKKworICAvLyBpbXBsZW1lbnRzIEZpZWxkR2VuZXJhdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICB2b2lkIEdlbmVyYXRlTWVtYmVycyhpbzo6UHJpbnRlciogcHJpbnRlciwgYm9vbCBsYXp5X2luaXQpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQ2xlYXJDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU1lcmdpbmdDb2RlKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZU1lcmdpbmdDb2RlRnJvbVBhY2tlZChpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemF0aW9uQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVkU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRXF1YWxzQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVIYXNoQ29kZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlRml4Q2xvbmVkQ29kZShpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyBwcml2YXRlOgorICB2b2lkIEdlbmVyYXRlUmVwZWF0ZWREYXRhU2l6ZUNvZGUoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcl87CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyaWFibGVzXzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoUmVwZWF0ZWRQcmltaXRpdmVGaWVsZEdlbmVyYXRvcik7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgamF2YW5hbm8KK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pBVkFOQU5PX1BSSU1JVElWRV9GSUVMRF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvanMvanNfZ2VuZXJhdG9yLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qcy9qc19nZW5lcmF0b3IuY2MKbmV3IGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMDAwMDAwMC4uZTZjM2IzNgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvanMvanNfZ2VuZXJhdG9yLmNjCkBAIC0wLDAgKzEsMjYyMiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvanMvanNfZ2VuZXJhdG9yLmg+CisKKyNpbmNsdWRlIDxhc3NlcnQuaD4KKyNpbmNsdWRlIDxhbGdvcml0aG0+CisjaW5jbHVkZSA8bGltaXRzPgorI2luY2x1ZGUgPG1hcD4KKyNpbmNsdWRlIDxtZW1vcnk+CisjaWZuZGVmIF9TSEFSRURfUFRSX0gKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc2hhcmVkX3B0ci5oPgorI2VuZGlmCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPHV0aWxpdHk+CisjaW5jbHVkZSA8dmVjdG9yPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2xvZ2dpbmcuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cmluZ3ByaW50Zi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBqcyB7CisKKy8vIFNvcnRlZCBsaXN0IG9mIEphdmFTY3JpcHQga2V5d29yZHMuIFRoZXNlIGNhbm5vdCBiZSB1c2VkIGFzIG5hbWVzLiBJZiB0aGV5CisvLyBhcHBlYXIsIHdlIHByZWZpeCB0aGVtIHdpdGggInBiXyIuCitjb25zdCBjaGFyKiBrS2V5d29yZFtdID0geworICAiYWJzdHJhY3QiLAorICAiYm9vbGVhbiIsCisgICJicmVhayIsCisgICJieXRlIiwKKyAgImNhc2UiLAorICAiY2F0Y2giLAorICAiY2hhciIsCisgICJjbGFzcyIsCisgICJjb25zdCIsCisgICJjb250aW51ZSIsCisgICJkZWJ1Z2dlciIsCisgICJkZWZhdWx0IiwKKyAgImRlbGV0ZSIsCisgICJkbyIsCisgICJkb3VibGUiLAorICAiZWxzZSIsCisgICJlbnVtIiwKKyAgImV4cG9ydCIsCisgICJleHRlbmRzIiwKKyAgImZhbHNlIiwKKyAgImZpbmFsIiwKKyAgImZpbmFsbHkiLAorICAiZmxvYXQiLAorICAiZm9yIiwKKyAgImZ1bmN0aW9uIiwKKyAgImdvdG8iLAorICAiaWYiLAorICAiaW1wbGVtZW50cyIsCisgICJpbXBvcnQiLAorICAiaW4iLAorICAiaW5zdGFuY2VvZiIsCisgICJpbnQiLAorICAiaW50ZXJmYWNlIiwKKyAgImxvbmciLAorICAibmF0aXZlIiwKKyAgIm5ldyIsCisgICJudWxsIiwKKyAgInBhY2thZ2UiLAorICAicHJpdmF0ZSIsCisgICJwcm90ZWN0ZWQiLAorICAicHVibGljIiwKKyAgInJldHVybiIsCisgICJzaG9ydCIsCisgICJzdGF0aWMiLAorICAic3VwZXIiLAorICAic3dpdGNoIiwKKyAgInN5bmNocm9uaXplZCIsCisgICJ0aGlzIiwKKyAgInRocm93IiwKKyAgInRocm93cyIsCisgICJ0cmFuc2llbnQiLAorICAidHJ5IiwKKyAgInR5cGVvZiIsCisgICJ2YXIiLAorICAidm9pZCIsCisgICJ2b2xhdGlsZSIsCisgICJ3aGlsZSIsCisgICJ3aXRoIiwKK307CisKK3N0YXRpYyBjb25zdCBpbnQga051bUtleXdvcmQgPSBzaXplb2Yoa0tleXdvcmQpIC8gc2l6ZW9mKGNoYXIqKTsKKworbmFtZXNwYWNlIHsKKworYm9vbCBJc1Jlc2VydmVkKGNvbnN0IHN0cmluZyYgaWRlbnQpIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBrTnVtS2V5d29yZDsgaSsrKSB7CisgICAgaWYgKGlkZW50ID09IGtLZXl3b3JkW2ldKSB7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIGZhbHNlOworfQorCisvLyBSZXR1cm5zIGEgY29weSBvZiB8ZmlsZW5hbWV8IHdpdGggYW55IHRyYWlsaW5nICIucHJvdG9kZXZlbCIgb3IgIi5wcm90bworLy8gc3VmZml4IHN0cmlwcGVkLgorc3RyaW5nIFN0cmlwUHJvdG8oY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSkgeworICBjb25zdCBjaGFyKiBzdWZmaXggPSBIYXNTdWZmaXhTdHJpbmcoZmlsZW5hbWUsICIucHJvdG9kZXZlbCIpCisgICAgICA/ICIucHJvdG9kZXZlbCIgOiAiLnByb3RvIjsKKyAgcmV0dXJuIFN0cmlwU3VmZml4U3RyaW5nKGZpbGVuYW1lLCBzdWZmaXgpOworfQorCisvLyBSZXR1cm5zIHRoZSBmdWxseSBub3JtYWxpemVkIEphdmFTY3JpcHQgcGF0aCBmb3IgdGhlIGdpdmVuCisvLyBmaWxlIGRlc2NyaXB0b3IncyBwYWNrYWdlLgorc3RyaW5nIEdldFBhdGgoY29uc3QgR2VuZXJhdG9yT3B0aW9ucyYgb3B0aW9ucywKKyAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKSB7CisgIGlmICghb3B0aW9ucy5uYW1lc3BhY2VfcHJlZml4LmVtcHR5KCkpIHsKKyAgICByZXR1cm4gb3B0aW9ucy5uYW1lc3BhY2VfcHJlZml4OworICB9IGVsc2UgaWYgKCFmaWxlLT5wYWNrYWdlKCkuZW1wdHkoKSkgeworICAgIHJldHVybiAicHJvdG8uIiArIGZpbGUtPnBhY2thZ2UoKTsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gInByb3RvIjsKKyAgfQorfQorCisvLyBGb3J3YXJkIGRlY2xhcmUsIHNvIHRoYXQgR2V0UHJlZml4IGNhbiBjYWxsIHRoaXMgbWV0aG9kLAorLy8gd2hpY2ggaW4gdHVybiwgY2FsbHMgR2V0UHJlZml4Lgorc3RyaW5nIEdldFBhdGgoY29uc3QgR2VuZXJhdG9yT3B0aW9ucyYgb3B0aW9ucywKKyAgICAgICAgICAgICAgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworCisvLyBSZXR1cm5zIHRoZSBwYXRoIHByZWZpeCBmb3IgYSBtZXNzYWdlIG9yIGVudW1lcmF0aW9uIHRoYXQKKy8vIGxpdmVzIHVuZGVyIHRoZSBnaXZlbiBmaWxlIGFuZCBjb250YWluaW5nIHR5cGUuCitzdHJpbmcgR2V0UHJlZml4KGNvbnN0IEdlbmVyYXRvck9wdGlvbnMmIG9wdGlvbnMsCisgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlX2Rlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgIGNvbnN0IERlc2NyaXB0b3IqIGNvbnRhaW5pbmdfdHlwZSkgeworICBzdHJpbmcgcHJlZml4ID0gIiI7CisKKyAgaWYgKGNvbnRhaW5pbmdfdHlwZSA9PSBOVUxMKSB7CisgICAgcHJlZml4ID0gR2V0UGF0aChvcHRpb25zLCBmaWxlX2Rlc2NyaXB0b3IpOworICB9IGVsc2UgeworICAgIHByZWZpeCA9IEdldFBhdGgob3B0aW9ucywgY29udGFpbmluZ190eXBlKTsKKyAgfQorCisgIGlmICghcHJlZml4LmVtcHR5KCkpIHsKKyAgICBwcmVmaXggKz0gIi4iOworICB9CisKKyAgcmV0dXJuIHByZWZpeDsKK30KKworCisvLyBSZXR1cm5zIHRoZSBmdWxseSBub3JtYWxpemVkIEphdmFTY3JpcHQgcGF0aCBmb3IgdGhlIGdpdmVuCisvLyBtZXNzYWdlIGRlc2NyaXB0b3IuCitzdHJpbmcgR2V0UGF0aChjb25zdCBHZW5lcmF0b3JPcHRpb25zJiBvcHRpb25zLAorICAgICAgICAgICAgICAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICByZXR1cm4gR2V0UHJlZml4KAorICAgICAgb3B0aW9ucywgZGVzY3JpcHRvci0+ZmlsZSgpLAorICAgICAgZGVzY3JpcHRvci0+Y29udGFpbmluZ190eXBlKCkpICsgZGVzY3JpcHRvci0+bmFtZSgpOworfQorCisKKy8vIFJldHVybnMgdGhlIGZ1bGx5IG5vcm1hbGl6ZWQgSmF2YVNjcmlwdCBwYXRoIGZvciB0aGUgZ2l2ZW4KKy8vIGZpZWxkJ3MgY29udGFpbmluZyBtZXNzYWdlIGRlc2NyaXB0b3IuCitzdHJpbmcgR2V0UGF0aChjb25zdCBHZW5lcmF0b3JPcHRpb25zJiBvcHRpb25zLAorICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIHJldHVybiBHZXRQYXRoKG9wdGlvbnMsIGRlc2NyaXB0b3ItPmNvbnRhaW5pbmdfdHlwZSgpKTsKK30KKworLy8gUmV0dXJucyB0aGUgZnVsbHkgbm9ybWFsaXplZCBKYXZhU2NyaXB0IHBhdGggZm9yIHRoZSBnaXZlbgorLy8gZW51bWVyYXRpb24gZGVzY3JpcHRvci4KK3N0cmluZyBHZXRQYXRoKGNvbnN0IEdlbmVyYXRvck9wdGlvbnMmIG9wdGlvbnMsCisgICAgICAgICAgICAgICBjb25zdCBFbnVtRGVzY3JpcHRvciogZW51bV9kZXNjcmlwdG9yKSB7CisgIHJldHVybiBHZXRQcmVmaXgoCisgICAgICBvcHRpb25zLCBlbnVtX2Rlc2NyaXB0b3ItPmZpbGUoKSwKKyAgICAgIGVudW1fZGVzY3JpcHRvci0+Y29udGFpbmluZ190eXBlKCkpICsgZW51bV9kZXNjcmlwdG9yLT5uYW1lKCk7Cit9CisKKworLy8gUmV0dXJucyB0aGUgZnVsbHkgbm9ybWFsaXplZCBKYXZhU2NyaXB0IHBhdGggZm9yIHRoZSBnaXZlbgorLy8gZW51bWVyYXRpb24gdmFsdWUgZGVzY3JpcHRvci4KK3N0cmluZyBHZXRQYXRoKGNvbnN0IEdlbmVyYXRvck9wdGlvbnMmIG9wdGlvbnMsCisgICAgICAgICAgICAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiB2YWx1ZV9kZXNjcmlwdG9yKSB7CisgIHJldHVybiBHZXRQYXRoKAorICAgICAgb3B0aW9ucywKKyAgICAgIHZhbHVlX2Rlc2NyaXB0b3ItPnR5cGUoKSkgKyAiLiIgKyB2YWx1ZV9kZXNjcmlwdG9yLT5uYW1lKCk7Cit9CisKKy8vIC0gT2JqZWN0IGZpZWxkIG5hbWU6IExPV0VSX1VOREVSU0NPUkUgLT4gTE9XRVJfQ0FNRUwsIGV4Y2VwdCBmb3IgZ3JvdXAgZmllbGRzCisvLyAoVVBQRVJfQ0FNRUwgLT4gTE9XRVJfQ0FNRUwpLCB3aXRoICJMaXN0IiAob3IgIk1hcCIpIGFwcGVuZGVkIGlmIGFwcHJvcHJpYXRlLAorLy8gYW5kIHdpdGggcmVzZXJ2ZWQgd29yZHMgdHJpZ2dlcmluZyBhICJwYl8iIHByZWZpeC4KKy8vIC0gR2V0dGVycy9zZXR0ZXJzOiBMT1dFUl9VTkRFUlNDT1JFIC0+IFVQUEVSX0NBTUVMLCBleGNlcHQgZm9yIGdyb3VwIGZpZWxkcworLy8gKHVzZSB0aGUgbmFtZSBkaXJlY3RseSksIHRoZW4gYXBwZW5kICJMaXN0IiBpZiBhcHByb3ByaWF0ZSwgdGhlbiBhcHBlbmQgIiQiCisvLyBpZiByZXN1bHRpbmcgbmFtZSBpcyBlcXVhbCB0byBhIHJlc2VydmVkIHdvcmQuCisvLyAtIEVudW1zOiBqdXN0IHVwcGVyY2FzZS4KKworLy8gTG9jYWxlLWluZGVwZW5kZW50IHZlcnNpb24gb2YgVG9Mb3dlciB0aGF0IGRlYWxzIG9ubHkgd2l0aCBBU0NJSSBBLVouCitjaGFyIFRvTG93ZXJBU0NJSShjaGFyIGMpIHsKKyAgaWYgKGMgPj0gJ0EnICYmIGMgPD0gJ1onKSB7CisgICAgcmV0dXJuIChjIC0gJ0EnKSArICdhJzsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gYzsKKyAgfQorfQorCit2ZWN0b3I8c3RyaW5nPiBQYXJzZUxvd2VyVW5kZXJzY29yZShjb25zdCBzdHJpbmcmIGlucHV0KSB7CisgIHZlY3RvcjxzdHJpbmc+IHdvcmRzOworICBzdHJpbmcgcnVubmluZyA9ICIiOworICBmb3IgKGludCBpID0gMDsgaSA8IGlucHV0LnNpemUoKTsgaSsrKSB7CisgICAgaWYgKGlucHV0W2ldID09ICdfJykgeworICAgICAgaWYgKCFydW5uaW5nLmVtcHR5KCkpIHsKKyAgICAgICAgd29yZHMucHVzaF9iYWNrKHJ1bm5pbmcpOworICAgICAgICBydW5uaW5nLmNsZWFyKCk7CisgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgIHJ1bm5pbmcgKz0gVG9Mb3dlckFTQ0lJKGlucHV0W2ldKTsKKyAgICB9CisgIH0KKyAgaWYgKCFydW5uaW5nLmVtcHR5KCkpIHsKKyAgICB3b3Jkcy5wdXNoX2JhY2socnVubmluZyk7CisgIH0KKyAgcmV0dXJuIHdvcmRzOworfQorCit2ZWN0b3I8c3RyaW5nPiBQYXJzZVVwcGVyQ2FtZWwoY29uc3Qgc3RyaW5nJiBpbnB1dCkgeworICB2ZWN0b3I8c3RyaW5nPiB3b3JkczsKKyAgc3RyaW5nIHJ1bm5pbmcgPSAiIjsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbnB1dC5zaXplKCk7IGkrKykgeworICAgIGlmIChpbnB1dFtpXSA+PSAnQScgJiYgaW5wdXRbaV0gPD0gJ1onICYmICFydW5uaW5nLmVtcHR5KCkpIHsKKyAgICAgIHdvcmRzLnB1c2hfYmFjayhydW5uaW5nKTsKKyAgICAgIHJ1bm5pbmcuY2xlYXIoKTsKKyAgICB9CisgICAgcnVubmluZyArPSBUb0xvd2VyQVNDSUkoaW5wdXRbaV0pOworICB9CisgIGlmICghcnVubmluZy5lbXB0eSgpKSB7CisgICAgd29yZHMucHVzaF9iYWNrKHJ1bm5pbmcpOworICB9CisgIHJldHVybiB3b3JkczsKK30KKworc3RyaW5nIFRvTG93ZXJDYW1lbChjb25zdCB2ZWN0b3I8c3RyaW5nPiYgd29yZHMpIHsKKyAgc3RyaW5nIHJlc3VsdDsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB3b3Jkcy5zaXplKCk7IGkrKykgeworICAgIHN0cmluZyB3b3JkID0gd29yZHNbaV07CisgICAgaWYgKGkgPT0gMCAmJiAod29yZFswXSA+PSAnQScgJiYgd29yZFswXSA8PSAnWicpKSB7CisgICAgICB3b3JkWzBdID0gKHdvcmRbMF0gLSAnQScpICsgJ2EnOworICAgIH0gZWxzZSBpZiAoaSAhPSAwICYmICh3b3JkWzBdID49ICdhJyAmJiB3b3JkWzBdIDw9ICd6JykpIHsKKyAgICAgIHdvcmRbMF0gPSAod29yZFswXSAtICdhJykgKyAnQSc7CisgICAgfQorICAgIHJlc3VsdCArPSB3b3JkOworICB9CisgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0cmluZyBUb1VwcGVyQ2FtZWwoY29uc3QgdmVjdG9yPHN0cmluZz4mIHdvcmRzKSB7CisgIHN0cmluZyByZXN1bHQ7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgd29yZHMuc2l6ZSgpOyBpKyspIHsKKyAgICBzdHJpbmcgd29yZCA9IHdvcmRzW2ldOworICAgIGlmICh3b3JkWzBdID49ICdhJyAmJiB3b3JkWzBdIDw9ICd6JykgeworICAgICAgd29yZFswXSA9ICh3b3JkWzBdIC0gJ2EnKSArICdBJzsKKyAgICB9CisgICAgcmVzdWx0ICs9IHdvcmQ7CisgIH0KKyAgcmV0dXJuIHJlc3VsdDsKK30KKworLy8gQmFzZWQgb24gY29kZSBmcm9tIGRlc2NyaXB0b3IuY2MgKFRoYW5rcyBLZW50b24hKQorLy8gVXBwZXJjYXNlcyB0aGUgZW50aXJlIHN0cmluZywgdHVybmluZyBWYWx1ZU5hbWUgaW50bworLy8gVkFMVUVOQU1FLgorc3RyaW5nIFRvRW51bUNhc2UoY29uc3Qgc3RyaW5nJiBpbnB1dCkgeworICBzdHJpbmcgcmVzdWx0OworICByZXN1bHQucmVzZXJ2ZShpbnB1dC5zaXplKCkpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgaW5wdXQuc2l6ZSgpOyBpKyspIHsKKyAgICBpZiAoJ2EnIDw9IGlucHV0W2ldICYmIGlucHV0W2ldIDw9ICd6JykgeworICAgICAgcmVzdWx0LnB1c2hfYmFjayhpbnB1dFtpXSAtICdhJyArICdBJyk7CisgICAgfSBlbHNlIHsKKyAgICAgIHJlc3VsdC5wdXNoX2JhY2soaW5wdXRbaV0pOworICAgIH0KKyAgfQorCisgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0cmluZyBUb0ZpbGVOYW1lKGNvbnN0IHN0cmluZyYgaW5wdXQpIHsKKyAgc3RyaW5nIHJlc3VsdDsKKyAgcmVzdWx0LnJlc2VydmUoaW5wdXQuc2l6ZSgpKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGlucHV0LnNpemUoKTsgaSsrKSB7CisgICAgaWYgKCdBJyA8PSBpbnB1dFtpXSAmJiBpbnB1dFtpXSA8PSAnWicpIHsKKyAgICAgIHJlc3VsdC5wdXNoX2JhY2soaW5wdXRbaV0gLSAnQScgKyAnYScpOworICAgIH0gZWxzZSB7CisgICAgICByZXN1bHQucHVzaF9iYWNrKGlucHV0W2ldKTsKKyAgICB9CisgIH0KKworICByZXR1cm4gcmVzdWx0OworfQorCisvLyBSZXR1cm5zIHRoZSBtZXNzYWdlL3Jlc3BvbnNlIElELCBpZiBzZXQuCitzdHJpbmcgR2V0TWVzc2FnZUlkKGNvbnN0IERlc2NyaXB0b3IqIGRlc2MpIHsKKyAgcmV0dXJuIHN0cmluZygpOworfQorCisKKy8vIFVzZWQgaW5zaWRlIEdvb2dsZSBvbmx5IC0tIGRvIG5vdCByZW1vdmUuCitib29sIElzUmVzcG9uc2UoY29uc3QgRGVzY3JpcHRvciogZGVzYykgeyByZXR1cm4gZmFsc2U7IH0KK2Jvb2wgSWdub3JlRmllbGQoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeyByZXR1cm4gZmFsc2U7IH0KKworCisvLyBEb2VzIEpTUEIgaWdub3JlIHRoaXMgZW50aXJlIG9uZW9mPyBUcnVlIG9ubHkgaWYgYWxsIGZpZWxkcyBhcmUgaWdub3JlZC4KK2Jvb2wgSWdub3JlT25lb2YoY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBvbmVvZikgeworICBmb3IgKGludCBpID0gMDsgaSA8IG9uZW9mLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBpZiAoIUlnbm9yZUZpZWxkKG9uZW9mLT5maWVsZChpKSkpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKK3N0cmluZyBKU0lkZW50KGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICBib29sIGlzX3VwcGVyX2NhbWVsLAorICAgICAgICAgICAgICAgYm9vbCBpc19tYXApIHsKKyAgc3RyaW5nIHJlc3VsdDsKKyAgaWYgKGZpZWxkLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQKSB7CisgICAgcmVzdWx0ID0gaXNfdXBwZXJfY2FtZWwgPworICAgICAgICBUb1VwcGVyQ2FtZWwoUGFyc2VVcHBlckNhbWVsKGZpZWxkLT5tZXNzYWdlX3R5cGUoKS0+bmFtZSgpKSkgOgorICAgICAgICBUb0xvd2VyQ2FtZWwoUGFyc2VVcHBlckNhbWVsKGZpZWxkLT5tZXNzYWdlX3R5cGUoKS0+bmFtZSgpKSk7CisgIH0gZWxzZSB7CisgICAgcmVzdWx0ID0gaXNfdXBwZXJfY2FtZWwgPworICAgICAgICBUb1VwcGVyQ2FtZWwoUGFyc2VMb3dlclVuZGVyc2NvcmUoZmllbGQtPm5hbWUoKSkpIDoKKyAgICAgICAgVG9Mb3dlckNhbWVsKFBhcnNlTG93ZXJVbmRlcnNjb3JlKGZpZWxkLT5uYW1lKCkpKTsKKyAgfQorICBpZiAoaXNfbWFwKSB7CisgICAgcmVzdWx0ICs9ICJNYXAiOworICB9IGVsc2UgaWYgKGZpZWxkLT5pc19yZXBlYXRlZCgpKSB7CisgICAgcmVzdWx0ICs9ICJMaXN0IjsKKyAgfQorICByZXR1cm4gcmVzdWx0OworfQorCitzdHJpbmcgSlNPYmplY3RGaWVsZE5hbWUoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICBzdHJpbmcgbmFtZSA9IEpTSWRlbnQoCisgICAgICBmaWVsZCwKKyAgICAgIC8qIGlzX3VwcGVyX2NhbWVsID0gKi8gZmFsc2UsCisgICAgICAvKiBpc19tYXAgPSAqLyBmYWxzZSk7CisgIGlmIChJc1Jlc2VydmVkKG5hbWUpKSB7CisgICAgbmFtZSA9ICJwYl8iICsgbmFtZTsKKyAgfQorICByZXR1cm4gbmFtZTsKK30KKworLy8gUmV0dXJucyB0aGUgZmllbGQgbmFtZSBhcyBhIGNhcGl0YWxpemVkIHBvcnRpb24gb2YgYSBnZXR0ZXIvc2V0dGVyIG1ldGhvZAorLy8gbmFtZSwgZS5nLiBNeUZpZWxkIGZvciAuZ2V0TXlGaWVsZCgpLgorc3RyaW5nIEpTR2V0dGVyTmFtZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIHN0cmluZyBuYW1lID0gSlNJZGVudChmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgIC8qIGlzX3VwcGVyX2NhbWVsID0gKi8gdHJ1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIC8qIGlzX21hcCA9ICovIGZhbHNlKTsKKyAgaWYgKG5hbWUgPT0gIkV4dGVuc2lvbiIgfHwgbmFtZSA9PSAiSnNQYk1lc3NhZ2VJZCIpIHsKKyAgICAvLyBBdm9pZCBjb25mbGljdHMgd2l0aCBiYXNlLWNsYXNzIG5hbWVzLgorICAgIG5hbWUgKz0gIiQiOworICB9CisgIHJldHVybiBuYW1lOworfQorCitzdHJpbmcgSlNNYXBHZXR0ZXJOYW1lKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgcmV0dXJuIEpTSWRlbnQoZmllbGQsCisgICAgICAgICAgICAgICAgIC8qIGlzX3VwcGVyX2NhbWVsID0gKi8gdHJ1ZSwKKyAgICAgICAgICAgICAgICAgLyogaXNfbWFwID0gKi8gdHJ1ZSk7Cit9CisKKworCitzdHJpbmcgSlNPbmVvZk5hbWUoY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBvbmVvZikgeworICByZXR1cm4gVG9VcHBlckNhbWVsKFBhcnNlTG93ZXJVbmRlcnNjb3JlKG9uZW9mLT5uYW1lKCkpKTsKK30KKworLy8gUmV0dXJucyB0aGUgaW5kZXggY29ycmVzcG9uZGluZyB0byB0aGlzIGZpZWxkIGluIHRoZSBKU1BCIGFycmF5ICh1bmRlcmx5aW5nCisvLyBkYXRhIHN0b3JhZ2UgYXJyYXkpLgorc3RyaW5nIEpTRmllbGRJbmRleChjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIC8vIERldGVybWluZSB3aGV0aGVyIHRoaXMgZmllbGQgaXMgYSBtZW1iZXIgb2YgYSBncm91cC4gR3JvdXAgZmllbGRzIGFyZSBhIGJpdAorICAvLyB3b25reTogdGhlaXIgImNvbnRhaW5pbmcgdHlwZSIgaXMgYSBtZXNzYWdlIHR5cGUgY3JlYXRlZCBqdXN0IGZvciB0aGUKKyAgLy8gZ3JvdXAsIGFuZCB0aGF0IHR5cGUncyBwYXJlbnQgdHlwZSBoYXMgYSBmaWVsZCB3aXRoIHRoZSBncm91cC1tZXNzYWdlIHR5cGUKKyAgLy8gYXMgaXRzIG1lc3NhZ2UgdHlwZSBhbmQgVFlQRV9HUk9VUCBhcyBpdHMgZmllbGQgdHlwZS4gRm9yIHN1Y2ggZmllbGRzLCB0aGUKKyAgLy8gaW5kZXggd2UgdXNlIGlzIHJlbGF0aXZlIHRvIHRoZSBmaWVsZCBudW1iZXIgb2YgdGhlIGdyb3VwIHN1Ym1lc3NhZ2UgZmllbGQuCisgIC8vIEZvciBhbGwgb3RoZXIgZmllbGRzLCB3ZSBqdXN0IHVzZSB0aGUgZmllbGQgbnVtYmVyLgorICBjb25zdCBEZXNjcmlwdG9yKiBjb250YWluaW5nX3R5cGUgPSBmaWVsZC0+Y29udGFpbmluZ190eXBlKCk7CisgIGNvbnN0IERlc2NyaXB0b3IqIHBhcmVudF90eXBlID0gY29udGFpbmluZ190eXBlLT5jb250YWluaW5nX3R5cGUoKTsKKyAgaWYgKHBhcmVudF90eXBlICE9IE5VTEwpIHsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhcmVudF90eXBlLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICAgIGlmIChwYXJlbnRfdHlwZS0+ZmllbGQoaSktPnR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfR1JPVVAgJiYKKyAgICAgICAgICBwYXJlbnRfdHlwZS0+ZmllbGQoaSktPm1lc3NhZ2VfdHlwZSgpID09IGNvbnRhaW5pbmdfdHlwZSkgeworICAgICAgICByZXR1cm4gU2ltcGxlSXRvYShmaWVsZC0+bnVtYmVyKCkgLSBwYXJlbnRfdHlwZS0+ZmllbGQoaSktPm51bWJlcigpKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKyAgcmV0dXJuIFNpbXBsZUl0b2EoZmllbGQtPm51bWJlcigpKTsKK30KKworc3RyaW5nIEpTT25lb2ZJbmRleChjb25zdCBPbmVvZkRlc2NyaXB0b3IqIG9uZW9mKSB7CisgIGludCBpbmRleCA9IC0xOworICBmb3IgKGludCBpID0gMDsgaSA8IG9uZW9mLT5jb250YWluaW5nX3R5cGUoKS0+b25lb2ZfZGVjbF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBPbmVvZkRlc2NyaXB0b3IqIG8gPSBvbmVvZi0+Y29udGFpbmluZ190eXBlKCktPm9uZW9mX2RlY2woaSk7CisgICAgLy8gSWYgYXQgbGVhc3Qgb25lIGZpZWxkIGluIHRoaXMgb25lb2YgaXMgbm90IEpTUEItaWdub3JlZCwgY291bnQgdGhlIG9uZW9mLgorICAgIGZvciAoaW50IGogPSAwOyBqIDwgby0+ZmllbGRfY291bnQoKTsgaisrKSB7CisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGYgPSBvLT5maWVsZChqKTsKKyAgICAgIGlmICghSWdub3JlRmllbGQoZikpIHsKKyAgICAgICAgaW5kZXgrKzsKKyAgICAgICAgYnJlYWs7ICAvLyBpbm5lciBsb29wCisgICAgICB9CisgICAgfQorICAgIGlmIChvID09IG9uZW9mKSB7CisgICAgICBicmVhazsKKyAgICB9CisgIH0KKyAgcmV0dXJuIFNpbXBsZUl0b2EoaW5kZXgpOworfQorCisvLyBEZWNvZGVzIGEgY29kZXBvaW50IGluIFx4MDAwMCAtLSBceEZGRkYuIFNpbmNlIEpTIHN0cmluZ3MgYXJlIFVURi0xNiwgd2Ugb25seQorLy8gbmVlZCB0byBoYW5kbGUgdGhlIEJNUCAoMTYtYml0IHJhbmdlKSBoZXJlLgordWludDE2IERlY29kZVVURjhDb2RlcG9pbnQodWludDgqIGJ5dGVzLCBzaXplX3QqIGxlbmd0aCkgeworICBpZiAoKmxlbmd0aCA9PSAwKSB7CisgICAgcmV0dXJuIDA7CisgIH0KKyAgc2l6ZV90IGV4cGVjdGVkID0gMDsKKyAgaWYgKCgqYnl0ZXMgJiAweDgwKSA9PSAwKSB7CisgICAgZXhwZWN0ZWQgPSAxOworICB9IGVsc2UgaWYgKCgqYnl0ZXMgJiAweGUwKSA9PSAweGMwKSB7CisgICAgZXhwZWN0ZWQgPSAyOworICB9IGVsc2UgaWYgKCgqYnl0ZXMgJiAweGYwKSA9PSAweGUwKSB7CisgICAgZXhwZWN0ZWQgPSAzOworICB9IGVsc2UgeworICAgIC8vIFRvbyBsb25nIC0tIGRvbid0IGFjY2VwdC4KKyAgICAqbGVuZ3RoID0gMDsKKyAgICByZXR1cm4gMDsKKyAgfQorCisgIGlmICgqbGVuZ3RoIDwgZXhwZWN0ZWQpIHsKKyAgICAvLyBOb3QgZW5vdWdoIGJ5dGVzIC0tIGRvbid0IGFjY2VwdC4KKyAgICAqbGVuZ3RoID0gMDsKKyAgICByZXR1cm4gMDsKKyAgfQorCisgICpsZW5ndGggPSBleHBlY3RlZDsKKyAgc3dpdGNoIChleHBlY3RlZCkgeworICAgIGNhc2UgMTogcmV0dXJuIGJ5dGVzWzBdOworICAgIGNhc2UgMjogcmV0dXJuICgoYnl0ZXNbMF0gJiAweDFGKSA8PCA2KSAgfAorICAgICAgICAgICAgICAgICAgICgoYnl0ZXNbMV0gJiAweDNGKSA8PCAwKTsKKyAgICBjYXNlIDM6IHJldHVybiAoKGJ5dGVzWzBdICYgMHgwRikgPDwgMTIpIHwKKyAgICAgICAgICAgICAgICAgICAoKGJ5dGVzWzFdICYgMHgzRikgPDwgNikgIHwKKyAgICAgICAgICAgICAgICAgICAoKGJ5dGVzWzJdICYgMHgzRikgPDwgMCk7CisgICAgZGVmYXVsdDogcmV0dXJuIDA7CisgIH0KK30KKworLy8gRXNjYXBlcyB0aGUgY29udGVudHMgb2YgYSBzdHJpbmcgdG8gYmUgaW5jbHVkZWQgd2l0aGluIGRvdWJsZS1xdW90ZXMgKCIiKSBpbgorLy8gSmF2YVNjcmlwdC4gfGlzX3V0Zjh8IGRldGVybWluZXMgd2hldGhlciB0aGUgaW5wdXQgZGF0YSAoaW4gYSBDKysgc3RyaW5nIG9mCisvLyBjaGFycykgaXMgVVRGLTggZW5jb2RlZCAoaW4gd2hpY2ggY2FzZSBjb2RlcG9pbnRzIGJlY29tZSBKYXZhU2NyaXB0IHN0cmluZworLy8gY2hhcmFjdGVycywgZXNjYXBlZCB3aXRoIDE2LWJpdCBoZXggZXNjYXBlcyB3aGVyZSBuZWNlc3NhcnkpIG9yIHJhdyBiaW5hcnkKKy8vIChpbiB3aGljaCBjYXNlIGJ5dGVzIGJlY29tZSBKYXZhU2NyaXB0IHN0cmluZyBjaGFyYWN0ZXJzIDAgLS0gMjU1KS4KK3N0cmluZyBFc2NhcGVKU1N0cmluZyhjb25zdCBzdHJpbmcmIGluLCBib29sIGlzX3V0ZjgpIHsKKyAgc3RyaW5nIHJlc3VsdDsKKyAgc2l6ZV90IGRlY29kZWQgPSAwOworICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IGluLnNpemUoKTsgaSArPSBkZWNvZGVkKSB7CisgICAgdWludDE2IGNvZGVwb2ludCA9IDA7CisgICAgaWYgKGlzX3V0ZjgpIHsKKyAgICAgIC8vIERlY29kZSB0aGUgbmV4dCBVVEYtOCBjb2RlcG9pbnQuCisgICAgICBzaXplX3QgaGF2ZV9ieXRlcyA9IGluLnNpemUoKSAtIGk7CisgICAgICB1aW50OCBieXRlc1szXSA9IHsKKyAgICAgICAgc3RhdGljX2Nhc3Q8dWludDg+KGluW2ldKSwKKyAgICAgICAgc3RhdGljX2Nhc3Q8dWludDg+KCgoaSArIDEpIDwgaW4uc2l6ZSgpKSA/IGluW2kgKyAxXSA6IDApLAorICAgICAgICBzdGF0aWNfY2FzdDx1aW50OD4oKChpICsgMikgPCBpbi5zaXplKCkpID8gaW5baSArIDJdIDogMCksCisgICAgICB9OworICAgICAgY29kZXBvaW50ID0gRGVjb2RlVVRGOENvZGVwb2ludChieXRlcywgJmhhdmVfYnl0ZXMpOworICAgICAgaWYgKGhhdmVfYnl0ZXMgPT0gMCkgeworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICAgIGRlY29kZWQgPSBoYXZlX2J5dGVzOworICAgIH0gZWxzZSB7CisgICAgICBjb2RlcG9pbnQgPSBzdGF0aWNfY2FzdDx1aW50MTY+KHN0YXRpY19jYXN0PHVpbnQ4PihpbltpXSkpOworICAgICAgZGVjb2RlZCA9IDE7CisgICAgfQorCisgICAgLy8gTmV4dCBieXRlIC0tIHVzZWQgZm9yIG1pbmltYWwgb2N0YWwgZXNjYXBlcyBiZWxvdy4KKyAgICBjaGFyIG5leHRfYnl0ZSA9IChpICsgZGVjb2RlZCkgPCBpbi5zaXplKCkgPworICAgICAgICBpbltpICsgZGVjb2RlZF0gOiAwOworICAgIGJvb2wgcGFkX29jdGFsID0gKG5leHRfYnl0ZSA+PSAnMCcgJiYgbmV4dF9ieXRlIDw9ICc3Jyk7CisKKyAgICBzd2l0Y2ggKGNvZGVwb2ludCkgeworICAgICAgY2FzZSAnXDAnOiByZXN1bHQgKz0gcGFkX29jdGFsID8gIlxcMDAwIiA6ICJcXDAiOyAgIGJyZWFrOworICAgICAgY2FzZSAnXGInOiByZXN1bHQgKz0gIlxcXGIiOyAgYnJlYWs7CisgICAgICBjYXNlICdcdCc6IHJlc3VsdCArPSAiXFxcdCI7ICBicmVhazsKKyAgICAgIGNhc2UgJ1xuJzogcmVzdWx0ICs9ICJcXFxuIjsgIGJyZWFrOworICAgICAgY2FzZSAnXHInOiByZXN1bHQgKz0gIlxcXHIiOyAgYnJlYWs7CisgICAgICBjYXNlICdcZic6IHJlc3VsdCArPSAiXFxcZiI7ICBicmVhazsKKyAgICAgIGNhc2UgJ1xcJzogcmVzdWx0ICs9ICJcXFxcIjsgIGJyZWFrOworICAgICAgY2FzZSAnIic6ICByZXN1bHQgKz0gcGFkX29jdGFsID8gIlxcMDQyIiA6ICJcXDQyIjsgYnJlYWs7CisgICAgICBjYXNlICcmJzogIHJlc3VsdCArPSBwYWRfb2N0YWwgPyAiXFwwNDYiIDogIlxcNDYiOyBicmVhazsKKyAgICAgIGNhc2UgJ1wnJzogcmVzdWx0ICs9IHBhZF9vY3RhbCA/ICJcXDA0NyIgOiAiXFw0NyI7IGJyZWFrOworICAgICAgY2FzZSAnPCc6ICByZXN1bHQgKz0gcGFkX29jdGFsID8gIlxcMDc0IiA6ICJcXDc0IjsgYnJlYWs7CisgICAgICBjYXNlICc9JzogIHJlc3VsdCArPSBwYWRfb2N0YWwgPyAiXFwwNzUiIDogIlxcNzUiOyBicmVhazsKKyAgICAgIGNhc2UgJz4nOiAgcmVzdWx0ICs9IHBhZF9vY3RhbCA/ICJcXDA3NiIgOiAiXFw3NiI7IGJyZWFrOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgLy8gQWxsIG90aGVyIG5vbi1BU0NJSSBjb2RlcG9pbnRzIGFyZSBlc2NhcGVkLgorICAgICAgICAvLyBPcmlnaW5hbCBjb2RlZ2VuIHVzZXMgaGV4IGZvciA+PSAweDEwMCBhbmQgb2N0YWwgZm9yIG90aGVycy4KKyAgICAgICAgaWYgKGNvZGVwb2ludCA+PSAweDIwICYmIGNvZGVwb2ludCA8PSAweDdlKSB7CisgICAgICAgICAgcmVzdWx0ICs9IHN0YXRpY19jYXN0PGNoYXI+KGNvZGVwb2ludCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgaWYgKGNvZGVwb2ludCA+PSAweDEwMCkgeworICAgICAgICAgICAgcmVzdWx0ICs9IFN0cmluZ1ByaW50ZigiXFx1JTA0eCIsIGNvZGVwb2ludCk7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGlmIChwYWRfb2N0YWwgfHwgY29kZXBvaW50ID49IDAxMDApIHsKKyAgICAgICAgICAgICAgcmVzdWx0ICs9ICJcXCI7CisgICAgICAgICAgICAgIHJlc3VsdCArPSAoJzAnICsgKChjb2RlcG9pbnQgPj4gNikgJiAwNykpOworICAgICAgICAgICAgICByZXN1bHQgKz0gKCcwJyArICgoY29kZXBvaW50ID4+IDMpICYgMDcpKTsKKyAgICAgICAgICAgICAgcmVzdWx0ICs9ICgnMCcgKyAoKGNvZGVwb2ludCA+PiAwKSAmIDA3KSk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGNvZGVwb2ludCA+PSAwMTApIHsKKyAgICAgICAgICAgICAgcmVzdWx0ICs9ICJcXCI7CisgICAgICAgICAgICAgIHJlc3VsdCArPSAoJzAnICsgKChjb2RlcG9pbnQgPj4gMykgJiAwNykpOworICAgICAgICAgICAgICByZXN1bHQgKz0gKCcwJyArICgoY29kZXBvaW50ID4+IDApICYgMDcpKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgIHJlc3VsdCArPSAiXFwiOworICAgICAgICAgICAgICByZXN1bHQgKz0gKCcwJyArICgoY29kZXBvaW50ID4+IDApICYgMDcpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgfQorICB9CisgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0cmluZyBFc2NhcGVCYXNlNjQoY29uc3Qgc3RyaW5nJiBpbikgeworICBzdGF0aWMgY29uc3QgY2hhcioga0FscGhhYmV0ID0KKyAgICAgICJBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvIjsKKyAgc3RyaW5nIHJlc3VsdDsKKworICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IGluLnNpemUoKTsgaSArPSAzKSB7CisgICAgaW50IHZhbHVlID0gKGluW2ldIDw8IDE2KSB8CisgICAgICAgICgoKGkgKyAxKSA8IGluLnNpemUoKSkgPyAoaW5baSArIDFdIDw8IDgpIDogMCkgfAorICAgICAgICAoKChpICsgMikgPCBpbi5zaXplKCkpID8gKGluW2kgKyAyXSA8PCAwKSA6IDApOworICAgIHJlc3VsdCArPSBrQWxwaGFiZXRbKHZhbHVlID4+IDE4KSAmIDB4M2ZdOworICAgIHJlc3VsdCArPSBrQWxwaGFiZXRbKHZhbHVlID4+IDEyKSAmIDB4M2ZdOworICAgIGlmICgoaSArIDEpIDwgaW4uc2l6ZSgpKSB7CisgICAgICByZXN1bHQgKz0ga0FscGhhYmV0Wyh2YWx1ZSA+PiAgNikgJiAweDNmXTsKKyAgICB9IGVsc2UgeworICAgICAgcmVzdWx0ICs9ICc9JzsKKyAgICB9CisgICAgaWYgKChpICsgMikgPCBpbi5zaXplKCkpIHsKKyAgICAgIHJlc3VsdCArPSBrQWxwaGFiZXRbKHZhbHVlID4+ICAwKSAmIDB4M2ZdOworICAgIH0gZWxzZSB7CisgICAgICByZXN1bHQgKz0gJz0nOworICAgIH0KKyAgfQorCisgIHJldHVybiByZXN1bHQ7Cit9CisKKy8vIFBvc3QtcHJvY2VzcyB0aGUgcmVzdWx0IG9mIFNpbXBsZUZ0b2EvU2ltcGxlRHRvYSB0byAqZXhhY3RseSogbWF0Y2ggdGhlCisvLyBvcmlnaW5hbCBjb2RlZ2VuJ3MgZm9ybWF0dGluZyAod2hpY2ggaXMganVzdCAudG9TdHJpbmcoKSBvbiBqYXZhLmxhbmcuRG91YmxlCisvLyBvciBqYXZhLmxhbmcuRmxvYXQpLgorc3RyaW5nIFBvc3RQcm9jZXNzRmxvYXQoc3RyaW5nIHJlc3VsdCkgeworICAvLyBJZiBpbmYsIC1pbmYgb3IgbmFuLCByZXBsYWNlIHdpdGggK0luZmluaXR5LCAtSW5maW5pdHkgb3IgTmFOLgorICBpZiAocmVzdWx0ID09ICJpbmYiKSB7CisgICAgcmV0dXJuICJJbmZpbml0eSI7CisgIH0gZWxzZSBpZiAocmVzdWx0ID09ICItaW5mIikgeworICAgIHJldHVybiAiLUluZmluaXR5IjsKKyAgfSBlbHNlIGlmIChyZXN1bHQgPT0gIm5hbiIpIHsKKyAgICByZXR1cm4gIk5hTiI7CisgIH0KKworICAvLyBJZiBzY2llbnRpZmljIG5vdGF0aW9uIChlLmcuLCAiMWUxMCIpLCAoaSkgY2FwaXRhbGl6ZSB0aGUgImUiLCAoaWkpCisgIC8vIGVuc3VyZSB0aGF0IHRoZSBtYW50aXNzYSAocG9ydGlvbiBwcmlvciB0byB0aGUgImUiKSBoYXMgYXQgbGVhc3Qgb25lCisgIC8vIGZyYWN0aW9uYWwgZGlnaXQgKGFmdGVyIHRoZSBkZWNpbWFsIHBvaW50KSwgYW5kIChpaWkpIHN0cmlwIGFueSB1bm5lY2Vzc2FyeQorICAvLyBsZWFkaW5nIHplcm9lcyBhbmQvb3IgJysnIHNpZ25zIGZyb20gdGhlIGV4cG9uZW50LgorICBzdHJpbmc6OnNpemVfdHlwZSBleHBfcG9zID0gcmVzdWx0LmZpbmQoJ2UnKTsKKyAgaWYgKGV4cF9wb3MgIT0gc3RyaW5nOjpucG9zKSB7CisgICAgc3RyaW5nIG1hbnRpc3NhID0gcmVzdWx0LnN1YnN0cigwLCBleHBfcG9zKTsKKyAgICBzdHJpbmcgZXhwb25lbnQgPSByZXN1bHQuc3Vic3RyKGV4cF9wb3MgKyAxKTsKKworICAgIC8vIEFkZCAiLjAiIHRvIG1hbnRpc3NhIGlmIG5vIGZyYWN0aW9uYWwgcGFydCBleGlzdHMuCisgICAgaWYgKG1hbnRpc3NhLmZpbmQoJy4nKSA9PSBzdHJpbmc6Om5wb3MpIHsKKyAgICAgIG1hbnRpc3NhICs9ICIuMCI7CisgICAgfQorCisgICAgLy8gU3RyaXAgdGhlIHNpZ24gb2ZmIHRoZSBleHBvbmVudCBhbmQgc3RvcmUgYXMgfGV4cF9uZWd8LgorICAgIGJvb2wgZXhwX25lZyA9IGZhbHNlOworICAgIGlmICghZXhwb25lbnQuZW1wdHkoKSAmJiBleHBvbmVudFswXSA9PSAnKycpIHsKKyAgICAgIGV4cG9uZW50ID0gZXhwb25lbnQuc3Vic3RyKDEpOworICAgIH0gZWxzZSBpZiAoIWV4cG9uZW50LmVtcHR5KCkgJiYgZXhwb25lbnRbMF0gPT0gJy0nKSB7CisgICAgICBleHBfbmVnID0gdHJ1ZTsKKyAgICAgIGV4cG9uZW50ID0gZXhwb25lbnQuc3Vic3RyKDEpOworICAgIH0KKworICAgIC8vIFN0cmlwIGFueSBsZWFkaW5nIHplcm9lcyBvZmYgdGhlIGV4cG9uZW50LgorICAgIHdoaWxlIChleHBvbmVudC5zaXplKCkgPiAxICYmIGV4cG9uZW50WzBdID09ICcwJykgeworICAgICAgZXhwb25lbnQgPSBleHBvbmVudC5zdWJzdHIoMSk7CisgICAgfQorCisgICAgcmV0dXJuIG1hbnRpc3NhICsgIkUiICsgc3RyaW5nKGV4cF9uZWcgPyAiLSIgOiAiIikgKyBleHBvbmVudDsKKyAgfQorCisgIC8vIE90aGVyd2lzZSwgdGhpcyBpcyBhbiBvcmRpbmFyeSBkZWNpbWFsIG51bWJlci4gQXBwZW5kICIuMCIgaWYgcmVzdWx0IGhhcyBubworICAvLyBkZWNpbWFsL2ZyYWN0aW9uYWwgcGFydCBpbiBvcmRlciB0byBtYXRjaCBvdXRwdXQgb2Ygb3JpZ2luYWwgY29kZWdlbi4KKyAgaWYgKHJlc3VsdC5maW5kKCcuJykgPT0gc3RyaW5nOjpucG9zKSB7CisgICAgcmVzdWx0ICs9ICIuMCI7CisgIH0KKworICByZXR1cm4gcmVzdWx0OworfQorCitzdHJpbmcgRmxvYXRUb1N0cmluZyhmbG9hdCB2YWx1ZSkgeworICBzdHJpbmcgcmVzdWx0ID0gU2ltcGxlRnRvYSh2YWx1ZSk7CisgIHJldHVybiBQb3N0UHJvY2Vzc0Zsb2F0KHJlc3VsdCk7Cit9CisKK3N0cmluZyBEb3VibGVUb1N0cmluZyhkb3VibGUgdmFsdWUpIHsKKyAgc3RyaW5nIHJlc3VsdCA9IFNpbXBsZUR0b2EodmFsdWUpOworICByZXR1cm4gUG9zdFByb2Nlc3NGbG9hdChyZXN1bHQpOworfQorCitzdHJpbmcgTWF5YmVOdW1iZXJTdHJpbmcoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgY29uc3Qgc3RyaW5nJiBvcmlnKSB7CisgIHJldHVybiBvcmlnOworfQorCitzdHJpbmcgSlNGaWVsZERlZmF1bHQoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICBhc3NlcnQoZmllbGQtPmhhc19kZWZhdWx0X3ZhbHVlKCkpOworICBzd2l0Y2ggKGZpZWxkLT5jcHBfdHlwZSgpKSB7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UMzI6CisgICAgICByZXR1cm4gTWF5YmVOdW1iZXJTdHJpbmcoCisgICAgICAgICAgZmllbGQsIFNpbXBsZUl0b2EoZmllbGQtPmRlZmF1bHRfdmFsdWVfaW50MzIoKSkpOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1VJTlQzMjoKKyAgICAgIC8vIFRoZSBvcmlnaW5hbCBjb2RlZ2VuIGlzIGluIEphdmEsIGFuZCBKYXZhIHByb3RvYnVmcyBzdG9yZSB1bnNpZ25lZAorICAgICAgLy8gaW50ZWdlciB2YWx1ZXMgYXMgc2lnbmVkIGludGVnZXIgdmFsdWVzLiBJbiBvcmRlciB0byBleGFjdGx5IG1hdGNoIHRoZQorICAgICAgLy8gb3V0cHV0LCB3ZSBuZWVkIHRvIHJlaW50ZXJwcmV0IGFzIGJhc2UtMiBzaWduZWQuIFVnaC4KKyAgICAgIHJldHVybiBNYXliZU51bWJlclN0cmluZygKKyAgICAgICAgICBmaWVsZCwgU2ltcGxlSXRvYShzdGF0aWNfY2FzdDxpbnQzMj4oZmllbGQtPmRlZmF1bHRfdmFsdWVfdWludDMyKCkpKSk7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UNjQ6CisgICAgICByZXR1cm4gTWF5YmVOdW1iZXJTdHJpbmcoCisgICAgICAgICAgZmllbGQsIFNpbXBsZUl0b2EoZmllbGQtPmRlZmF1bHRfdmFsdWVfaW50NjQoKSkpOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1VJTlQ2NDoKKyAgICAgIC8vIFNlZSBhYm92ZSBub3RlIGZvciB1aW50MzIgLS0gcmVpbnRlcnByZXRpbmcgYXMgc2lnbmVkLgorICAgICAgcmV0dXJuIE1heWJlTnVtYmVyU3RyaW5nKAorICAgICAgICAgIGZpZWxkLCBTaW1wbGVJdG9hKHN0YXRpY19jYXN0PGludDY0PihmaWVsZC0+ZGVmYXVsdF92YWx1ZV91aW50NjQoKSkpKTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9FTlVNOgorICAgICAgcmV0dXJuIFNpbXBsZUl0b2EoZmllbGQtPmRlZmF1bHRfdmFsdWVfZW51bSgpLT5udW1iZXIoKSk7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfQk9PTDoKKyAgICAgIHJldHVybiBmaWVsZC0+ZGVmYXVsdF92YWx1ZV9ib29sKCkgPyAidHJ1ZSIgOiAiZmFsc2UiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0ZMT0FUOgorICAgICAgcmV0dXJuIEZsb2F0VG9TdHJpbmcoZmllbGQtPmRlZmF1bHRfdmFsdWVfZmxvYXQoKSk7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRE9VQkxFOgorICAgICAgcmV0dXJuIERvdWJsZVRvU3RyaW5nKGZpZWxkLT5kZWZhdWx0X3ZhbHVlX2RvdWJsZSgpKTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9TVFJJTkc6CisgICAgICBpZiAoZmllbGQtPnR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU1RSSU5HKSB7CisgICAgICAgIHJldHVybiAiXCIiICsgRXNjYXBlSlNTdHJpbmcoZmllbGQtPmRlZmF1bHRfdmFsdWVfc3RyaW5nKCksIHRydWUpICsKKyAgICAgICAgICAgICAgICJcIiI7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gIlwiIiArIEVzY2FwZUJhc2U2NChmaWVsZC0+ZGVmYXVsdF92YWx1ZV9zdHJpbmcoKSkgKworICAgICAgICAgICAgICAgIlwiIjsKKyAgICAgIH0KKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgcmV0dXJuICJudWxsIjsKKyAgfQorICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiU2hvdWxkbid0IHJlYWNoIGhlcmUuIjsKKyAgcmV0dXJuICIiOworfQorCitzdHJpbmcgUHJvdG9UeXBlTmFtZShjb25zdCBHZW5lcmF0b3JPcHRpb25zJiBvcHRpb25zLAorICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICBzd2l0Y2ggKGZpZWxkLT50eXBlKCkpIHsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9CT09MOgorICAgICAgcmV0dXJuICJib29sIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9JTlQzMjoKKyAgICAgIHJldHVybiAiaW50MzIiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1VJTlQzMjoKKyAgICAgIHJldHVybiAidWludDMyIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TSU5UMzI6CisgICAgICByZXR1cm4gInNpbnQzMiI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRklYRUQzMjoKKyAgICAgIHJldHVybiAiZml4ZWQzMiI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0ZJWEVEMzI6CisgICAgICByZXR1cm4gInNmaXhlZDMyIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9JTlQ2NDoKKyAgICAgIHJldHVybiAiaW50NjQiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1VJTlQ2NDoKKyAgICAgIHJldHVybiAidWludDY0IjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TSU5UNjQ6CisgICAgICByZXR1cm4gInNpbnQ2NCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRklYRUQ2NDoKKyAgICAgIHJldHVybiAiZml4ZWQ2NCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0ZJWEVENjQ6CisgICAgICByZXR1cm4gInNmaXhlZDY0IjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9GTE9BVDoKKyAgICAgIHJldHVybiAiZmxvYXQiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0RPVUJMRToKKyAgICAgIHJldHVybiAiZG91YmxlIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TVFJJTkc6CisgICAgICByZXR1cm4gInN0cmluZyI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfQllURVM6CisgICAgICByZXR1cm4gImJ5dGVzIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9HUk9VUDoKKyAgICAgIHJldHVybiBHZXRQYXRoKG9wdGlvbnMsIGZpZWxkLT5tZXNzYWdlX3R5cGUoKSk7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRU5VTToKKyAgICAgIHJldHVybiBHZXRQYXRoKG9wdGlvbnMsIGZpZWxkLT5lbnVtX3R5cGUoKSk7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfTUVTU0FHRToKKyAgICAgIHJldHVybiBHZXRQYXRoKG9wdGlvbnMsIGZpZWxkLT5tZXNzYWdlX3R5cGUoKSk7CisgICAgZGVmYXVsdDoKKyAgICAgIHJldHVybiAiIjsKKyAgfQorfQorCitzdHJpbmcgSlNJbnRlZ2VyVHlwZU5hbWUoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICByZXR1cm4gIm51bWJlciI7Cit9CisKK3N0cmluZyBKU1R5cGVOYW1lKGNvbnN0IEdlbmVyYXRvck9wdGlvbnMmIG9wdGlvbnMsCisgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIHN3aXRjaCAoZmllbGQtPmNwcF90eXBlKCkpIHsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9CT09MOgorICAgICAgcmV0dXJuICJib29sZWFuIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9JTlQzMjoKKyAgICAgIHJldHVybiBKU0ludGVnZXJUeXBlTmFtZShmaWVsZCk7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UNjQ6CisgICAgICByZXR1cm4gSlNJbnRlZ2VyVHlwZU5hbWUoZmllbGQpOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1VJTlQzMjoKKyAgICAgIHJldHVybiBKU0ludGVnZXJUeXBlTmFtZShmaWVsZCk7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDY0OgorICAgICAgcmV0dXJuIEpTSW50ZWdlclR5cGVOYW1lKGZpZWxkKTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9GTE9BVDoKKyAgICAgIHJldHVybiAibnVtYmVyIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9ET1VCTEU6CisgICAgICByZXR1cm4gIm51bWJlciI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HOgorICAgICAgcmV0dXJuICJzdHJpbmciOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0VOVU06CisgICAgICByZXR1cm4gR2V0UGF0aChvcHRpb25zLCBmaWVsZC0+ZW51bV90eXBlKCkpOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U6CisgICAgICByZXR1cm4gR2V0UGF0aChvcHRpb25zLCBmaWVsZC0+bWVzc2FnZV90eXBlKCkpOworICAgIGRlZmF1bHQ6CisgICAgICByZXR1cm4gIiI7CisgIH0KK30KKworYm9vbCBIYXNGaWVsZFByZXNlbmNlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpOworCitzdHJpbmcgSlNGaWVsZFR5cGVBbm5vdGF0aW9uKGNvbnN0IEdlbmVyYXRvck9wdGlvbnMmIG9wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgZm9yY2Vfb3B0aW9uYWwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgZm9yY2VfcHJlc2VudCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBzaW5ndWxhcl9pZl9ub3RfcGFja2VkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGFsd2F5c19zaW5ndWxhcikgeworICBib29sIGlzX3ByaW1pdGl2ZSA9CisgICAgICAoZmllbGQtPmNwcF90eXBlKCkgIT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0VOVU0gJiYKKyAgICAgICBmaWVsZC0+Y3BwX3R5cGUoKSAhPSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSk7CisKKyAgc3RyaW5nIGpzdHlwZSA9IEpTVHlwZU5hbWUob3B0aW9ucywgZmllbGQpOworCisgIGlmIChmaWVsZC0+aXNfcmVwZWF0ZWQoKSAmJgorICAgICAgIWFsd2F5c19zaW5ndWxhciAmJgorICAgICAgKGZpZWxkLT5pc19wYWNrZWQoKSB8fCAhc2luZ3VsYXJfaWZfbm90X3BhY2tlZCkpIHsKKyAgICBpZiAoIWlzX3ByaW1pdGl2ZSkgeworICAgICAganN0eXBlID0gIiEiICsganN0eXBlOworICAgIH0KKyAgICBqc3R5cGUgPSAiQXJyYXkuPCIgKyBqc3R5cGUgKyAiPiI7CisgICAgaWYgKCFmb3JjZV9vcHRpb25hbCkgeworICAgICAganN0eXBlID0gIiEiICsganN0eXBlOworICAgIH0KKyAgfQorCisgIGlmIChmaWVsZC0+aXNfb3B0aW9uYWwoKSAmJiBpc19wcmltaXRpdmUgJiYKKyAgICAgICghZmllbGQtPmhhc19kZWZhdWx0X3ZhbHVlKCkgfHwgZm9yY2Vfb3B0aW9uYWwpICYmICFmb3JjZV9wcmVzZW50KSB7CisgICAganN0eXBlICs9ICI/IjsKKyAgfSBlbHNlIGlmIChmaWVsZC0+aXNfcmVxdWlyZWQoKSAmJiAhaXNfcHJpbWl0aXZlICYmICFmb3JjZV9vcHRpb25hbCkgeworICAgIGpzdHlwZSA9ICIhIiArIGpzdHlwZTsKKyAgfQorCisgIGlmIChmb3JjZV9vcHRpb25hbCAmJiBIYXNGaWVsZFByZXNlbmNlKGZpZWxkKSkgeworICAgIGpzdHlwZSArPSAifHVuZGVmaW5lZCI7CisgIH0KKyAgaWYgKGZvcmNlX3ByZXNlbnQgJiYganN0eXBlWzBdICE9ICchJyAmJiAhaXNfcHJpbWl0aXZlKSB7CisgICAganN0eXBlID0gIiEiICsganN0eXBlOworICB9CisKKyAgcmV0dXJuIGpzdHlwZTsKK30KKworc3RyaW5nIEpTQmluYXJ5UmVhZGVyTWV0aG9kVHlwZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIHN0cmluZyBuYW1lID0gZmllbGQtPnR5cGVfbmFtZSgpOworICBpZiAobmFtZVswXSA+PSAnYScgJiYgbmFtZVswXSA8PSAneicpIHsKKyAgICBuYW1lWzBdID0gKG5hbWVbMF0gLSAnYScpICsgJ0EnOworICB9CisKKyAgcmV0dXJuIG5hbWU7Cit9CisKK3N0cmluZyBKU0JpbmFyeVJlYWRXcml0ZU1ldGhvZE5hbWUoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc193cml0ZXIpIHsKKyAgc3RyaW5nIG5hbWUgPSBKU0JpbmFyeVJlYWRlck1ldGhvZFR5cGUoZmllbGQpOworICBpZiAoaXNfd3JpdGVyICYmIGZpZWxkLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX0JZVEVTKSB7CisgICAgLy8gT3ZlcnJpZGUgZm9yIGBieXRlc2AgZmllbGRzOiB0cmVhdCBzdHJpbmcgYXMgcmF3IGJ5dGVzLCBub3QgYmFzZTY0LgorICAgIG5hbWUgPSAiQnl0ZXNSYXdTdHJpbmciOworICB9CisgIGlmIChmaWVsZC0+aXNfcGFja2VkKCkpIHsKKyAgICBuYW1lID0gIlBhY2tlZCIgKyBuYW1lOworICB9IGVsc2UgaWYgKGlzX3dyaXRlciAmJiBmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgeworICAgIG5hbWUgPSAiUmVwZWF0ZWQiICsgbmFtZTsKKyAgfQorICByZXR1cm4gbmFtZTsKK30KKworc3RyaW5nIEpTQmluYXJ5UmVhZGVyTWV0aG9kTmFtZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIHJldHVybiAicmVhZCIgKyBKU0JpbmFyeVJlYWRXcml0ZU1ldGhvZE5hbWUoZmllbGQsIC8qIGlzX3dyaXRlciA9ICovIGZhbHNlKTsKK30KKworc3RyaW5nIEpTQmluYXJ5V3JpdGVyTWV0aG9kTmFtZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIHJldHVybiAid3JpdGUiICsgSlNCaW5hcnlSZWFkV3JpdGVNZXRob2ROYW1lKGZpZWxkLCAvKiBpc193cml0ZXIgPSAqLyB0cnVlKTsKK30KKworc3RyaW5nIEpTUmV0dXJuQ2xhdXNlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzYykgeworICByZXR1cm4gIiI7Cit9CisKK3N0cmluZyBKU1JldHVybkRvYyhjb25zdCBHZW5lcmF0b3JPcHRpb25zJiBvcHRpb25zLAorICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzYykgeworICByZXR1cm4gIiI7Cit9CisKK2Jvb2wgSGFzUmVwZWF0ZWRGaWVsZHMoY29uc3QgRGVzY3JpcHRvciogZGVzYykgeworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2MtPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGlmIChkZXNjLT5maWVsZChpKS0+aXNfcmVwZWF0ZWQoKSkgeworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICB9CisgIHJldHVybiBmYWxzZTsKK30KKworc3RhdGljIGNvbnN0IGNoYXIqIGtSZXBlYXRlZEZpZWxkQXJyYXlOYW1lID0gIi5yZXBlYXRlZEZpZWxkc18iOworCitzdHJpbmcgUmVwZWF0ZWRGaWVsZHNBcnJheU5hbWUoY29uc3QgR2VuZXJhdG9yT3B0aW9ucyYgb3B0aW9ucywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjKSB7CisgIHJldHVybiBIYXNSZXBlYXRlZEZpZWxkcyhkZXNjKSA/CisgICAgICAoR2V0UGF0aChvcHRpb25zLCBkZXNjKSArIGtSZXBlYXRlZEZpZWxkQXJyYXlOYW1lKSA6ICJudWxsIjsKK30KKworYm9vbCBIYXNPbmVvZkZpZWxkcyhjb25zdCBEZXNjcmlwdG9yKiBkZXNjKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzYy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgaWYgKGRlc2MtPmZpZWxkKGkpLT5jb250YWluaW5nX29uZW9mKCkpIHsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgfQorICByZXR1cm4gZmFsc2U7Cit9CisKK3N0YXRpYyBjb25zdCBjaGFyKiBrT25lb2ZHcm91cEFycmF5TmFtZSA9ICIub25lb2ZHcm91cHNfIjsKKworc3RyaW5nIE9uZW9mRmllbGRzQXJyYXlOYW1lKGNvbnN0IEdlbmVyYXRvck9wdGlvbnMmIG9wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVzY3JpcHRvciogZGVzYykgeworICByZXR1cm4gSGFzT25lb2ZGaWVsZHMoZGVzYykgPworICAgICAgKEdldFBhdGgob3B0aW9ucywgZGVzYykgKyBrT25lb2ZHcm91cEFycmF5TmFtZSkgOiAibnVsbCI7Cit9CisKK3N0cmluZyBSZXBlYXRlZEZpZWxkTnVtYmVyTGlzdChjb25zdCBEZXNjcmlwdG9yKiBkZXNjKSB7CisgIHN0ZDo6dmVjdG9yPHN0cmluZz4gbnVtYmVyczsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBpZiAoZGVzYy0+ZmllbGQoaSktPmlzX3JlcGVhdGVkKCkpIHsKKyAgICAgIG51bWJlcnMucHVzaF9iYWNrKEpTRmllbGRJbmRleChkZXNjLT5maWVsZChpKSkpOworICAgIH0KKyAgfQorICByZXR1cm4gIlsiICsgSm9pbihudW1iZXJzLCAiLCIpICsgIl0iOworfQorCitzdHJpbmcgT25lb2ZHcm91cExpc3QoY29uc3QgRGVzY3JpcHRvciogZGVzYykgeworICAvLyBMaXN0IG9mIGFycmF5cyAob25lIHBlciBvbmVvZiksIGVhY2ggb2Ygd2hpY2ggaXMgYSBsaXN0IG9mIGZpZWxkIGluZGljZXMKKyAgc3RkOjp2ZWN0b3I8c3RyaW5nPiBvbmVvZl9lbnRyaWVzOworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2MtPm9uZW9mX2RlY2xfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBvbmVvZiA9IGRlc2MtPm9uZW9mX2RlY2woaSk7CisgICAgaWYgKElnbm9yZU9uZW9mKG9uZW9mKSkgeworICAgICAgY29udGludWU7CisgICAgfQorCisgICAgc3RkOjp2ZWN0b3I8c3RyaW5nPiBvbmVvZl9maWVsZHM7CisgICAgZm9yIChpbnQgaiA9IDA7IGogPCBvbmVvZi0+ZmllbGRfY291bnQoKTsgaisrKSB7CisgICAgICBpZiAoSWdub3JlRmllbGQob25lb2YtPmZpZWxkKGopKSkgeworICAgICAgICBjb250aW51ZTsKKyAgICAgIH0KKyAgICAgIG9uZW9mX2ZpZWxkcy5wdXNoX2JhY2soSlNGaWVsZEluZGV4KG9uZW9mLT5maWVsZChqKSkpOworICAgIH0KKyAgICBvbmVvZl9lbnRyaWVzLnB1c2hfYmFjaygiWyIgKyBKb2luKG9uZW9mX2ZpZWxkcywgIiwiKSArICJdIik7CisgIH0KKyAgcmV0dXJuICJbIiArIEpvaW4ob25lb2ZfZW50cmllcywgIiwiKSArICJdIjsKK30KKworc3RyaW5nIEpTT25lb2ZBcnJheShjb25zdCBHZW5lcmF0b3JPcHRpb25zJiBvcHRpb25zLAorICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIHJldHVybiBPbmVvZkZpZWxkc0FycmF5TmFtZShvcHRpb25zLCBmaWVsZC0+Y29udGFpbmluZ190eXBlKCkpICsgIlsiICsKKyAgICAgIEpTT25lb2ZJbmRleChmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpKSArICJdIjsKK30KKworc3RyaW5nIFJlbGF0aXZlVHlwZU5hbWUoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICBhc3NlcnQoZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0VOVU0gfHwKKyAgICAgICAgIGZpZWxkLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFKTsKKyAgLy8gRm9yIGEgZmllbGQgd2l0aCBhbiBlbnVtIG9yIG1lc3NhZ2UgdHlwZSwgY29tcHV0ZSBhIG5hbWUgcmVsYXRpdmUgdG8gdGhlCisgIC8vIHBhdGggbmFtZSBvZiB0aGUgbWVzc2FnZSB0eXBlIGNvbnRhaW5pbmcgdGhpcyBmaWVsZC4KKyAgc3RyaW5nIHBhY2thZ2UgPSBmaWVsZC0+ZmlsZSgpLT5wYWNrYWdlKCk7CisgIHN0cmluZyBjb250YWluaW5nX3R5cGUgPSBmaWVsZC0+Y29udGFpbmluZ190eXBlKCktPmZ1bGxfbmFtZSgpICsgIi4iOworICBzdHJpbmcgdHlwZSA9IChmaWVsZC0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRU5VTSkgPworICAgICAgZmllbGQtPmVudW1fdHlwZSgpLT5mdWxsX25hbWUoKSA6IGZpZWxkLT5tZXNzYWdlX3R5cGUoKS0+ZnVsbF9uYW1lKCk7CisKKyAgLy8gfHByZWZpeHwgaXMgYWR2YW5jZWQgYXMgd2UgZmluZCBzZXBhcmF0b3JzICcuJyBwYXN0IHRoZSBjb21tb24gcGFja2FnZQorICAvLyBwcmVmaXggdGhhdCB5aWVsZCBjb21tb24gcHJlZml4ZXMgaW4gdGhlIGNvbnRhaW5pbmcgdHlwZSdzIG5hbWUgYW5kIHRoaXMKKyAgLy8gdHlwZSdzIG5hbWUuCisgIGludCBwcmVmaXggPSAwOworICBmb3IgKGludCBpID0gMDsgaSA8IHR5cGUuc2l6ZSgpICYmIGkgPCBjb250YWluaW5nX3R5cGUuc2l6ZSgpOyBpKyspIHsKKyAgICBpZiAodHlwZVtpXSAhPSBjb250YWluaW5nX3R5cGVbaV0pIHsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBpZiAodHlwZVtpXSA9PSAnLicgJiYgaSA+PSBwYWNrYWdlLnNpemUoKSkgeworICAgICAgcHJlZml4ID0gaSArIDE7CisgICAgfQorICB9CisKKyAgcmV0dXJuIHR5cGUuc3Vic3RyKHByZWZpeCk7Cit9CisKK3N0cmluZyBKU0V4dGVuc2lvbnNPYmplY3ROYW1lKGNvbnN0IEdlbmVyYXRvck9wdGlvbnMmIG9wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjKSB7CisgIGlmIChkZXNjLT5mdWxsX25hbWUoKSA9PSAiZ29vZ2xlLnByb3RvYnVmLmJyaWRnZS5NZXNzYWdlU2V0IikgeworICAgIHJldHVybiAianNwYi5NZXNzYWdlLm1lc3NhZ2VTZXRFeHRlbnNpb25zIjsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gR2V0UGF0aChvcHRpb25zLCBkZXNjKSArICIuZXh0ZW5zaW9ucyI7CisgIH0KK30KKworc3RyaW5nIEZpZWxkRGVmaW5pdGlvbihjb25zdCBHZW5lcmF0b3JPcHRpb25zJiBvcHRpb25zLAorICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIHN0cmluZyBxdWFsaWZpZXIgPSBmaWVsZC0+aXNfcmVwZWF0ZWQoKSA/ICJyZXBlYXRlZCIgOgorICAgICAgKGZpZWxkLT5pc19vcHRpb25hbCgpID8gIm9wdGlvbmFsIiA6ICJyZXF1aXJlZCIpOworICBzdHJpbmcgdHlwZSwgbmFtZTsKKyAgaWYgKGZpZWxkLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX0VOVU0gfHwKKyAgICAgIGZpZWxkLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX01FU1NBR0UpIHsKKyAgICB0eXBlID0gUmVsYXRpdmVUeXBlTmFtZShmaWVsZCk7CisgICAgbmFtZSA9IGZpZWxkLT5uYW1lKCk7CisgIH0gZWxzZSBpZiAoZmllbGQtPnR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfR1JPVVApIHsKKyAgICB0eXBlID0gImdyb3VwIjsKKyAgICBuYW1lID0gZmllbGQtPm1lc3NhZ2VfdHlwZSgpLT5uYW1lKCk7CisgIH0gZWxzZSB7CisgICAgdHlwZSA9IFByb3RvVHlwZU5hbWUob3B0aW9ucywgZmllbGQpOworICAgIG5hbWUgPSBmaWVsZC0+bmFtZSgpOworICB9CisgIHJldHVybiBTdHJpbmdQcmludGYoIiVzICVzICVzID0gJWQ7IiwKKyAgICAgICAgICAgICAgICAgICAgICBxdWFsaWZpZXIuY19zdHIoKSwKKyAgICAgICAgICAgICAgICAgICAgICB0eXBlLmNfc3RyKCksCisgICAgICAgICAgICAgICAgICAgICAgbmFtZS5jX3N0cigpLAorICAgICAgICAgICAgICAgICAgICAgIGZpZWxkLT5udW1iZXIoKSk7Cit9CisKK3N0cmluZyBGaWVsZENvbW1lbnRzKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgc3RyaW5nIGNvbW1lbnRzOworICBpZiAoZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0JPT0wpIHsKKyAgICBjb21tZW50cyArPQorICAgICAgICAiICogTm90ZSB0aGF0IEJvb2xlYW4gZmllbGRzIG1heSBiZSBzZXQgdG8gMC8xIHdoZW4gc2VyaWFsaXplZCBmcm9tICIKKyAgICAgICAgImEgSmF2YSBzZXJ2ZXIuXG4iCisgICAgICAgICIgKiBZb3Ugc2hvdWxkIGF2b2lkIGNvbXBhcmlzb25zIGxpa2Uge0Bjb2RlIHZhbCA9PT0gdHJ1ZS9mYWxzZX0gaW4gIgorICAgICAgICAidGhvc2UgY2FzZXMuXG4iOworICB9CisgIGlmIChmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgeworICAgIGNvbW1lbnRzICs9CisgICAgICAgICIgKiBJZiB5b3UgY2hhbmdlIHRoaXMgYXJyYXkgYnkgYWRkaW5nLCByZW1vdmluZyBvciByZXBsYWNpbmcgIgorICAgICAgICAiZWxlbWVudHMsIG9yIGlmIHlvdVxuIgorICAgICAgICAiICogcmVwbGFjZSB0aGUgYXJyYXkgaXRzZWxmLCB0aGVuIHlvdSBtdXN0IGNhbGwgdGhlIHNldHRlciB0byAiCisgICAgICAgICJ1cGRhdGUgaXQuXG4iOworICB9CisgIHJldHVybiBjb21tZW50czsKK30KKworYm9vbCBTaG91bGRHZW5lcmF0ZUV4dGVuc2lvbihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIHJldHVybgorICAgICAgZmllbGQtPmlzX2V4dGVuc2lvbigpICYmCisgICAgICAhSWdub3JlRmllbGQoZmllbGQpOworfQorCitib29sIEhhc0V4dGVuc2lvbnMoY29uc3QgRGVzY3JpcHRvciogZGVzYykgeworICBpZiAoZGVzYy0+ZXh0ZW5zaW9uX2NvdW50KCkgPiAwKSB7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjLT5uZXN0ZWRfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBpZiAoSGFzRXh0ZW5zaW9ucyhkZXNjLT5uZXN0ZWRfdHlwZShpKSkpIHsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgfQorICByZXR1cm4gZmFsc2U7Cit9CisKK2Jvb2wgSGFzRXh0ZW5zaW9ucyhjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSkgeworICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGUtPmV4dGVuc2lvbl9jb3VudCgpOyBpKyspIHsKKyAgICBpZiAoU2hvdWxkR2VuZXJhdGVFeHRlbnNpb24oZmlsZS0+ZXh0ZW5zaW9uKGkpKSkgeworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZS0+bWVzc2FnZV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIGlmIChIYXNFeHRlbnNpb25zKGZpbGUtPm1lc3NhZ2VfdHlwZShpKSkpIHsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgfQorICByZXR1cm4gZmFsc2U7Cit9CisKK2Jvb2wgSXNFeHRlbmRhYmxlKGNvbnN0IERlc2NyaXB0b3IqIGRlc2MpIHsKKyAgcmV0dXJuIGRlc2MtPmV4dGVuc2lvbl9yYW5nZV9jb3VudCgpID4gMDsKK30KKworLy8gUmV0dXJucyB0aGUgbWF4IGluZGV4IGluIHRoZSB1bmRlcmx5aW5nIGRhdGEgc3RvcmFnZSBhcnJheSBiZXlvbmQgd2hpY2ggdGhlCisvLyBleHRlbnNpb24gb2JqZWN0IGlzIHVzZWQuCitzdHJpbmcgR2V0UGl2b3QoY29uc3QgRGVzY3JpcHRvciogZGVzYykgeworICBzdGF0aWMgY29uc3QgaW50IGtEZWZhdWx0UGl2b3QgPSAoMSA8PCAyOSk7ICAvLyBtYXggZmllbGQgbnVtYmVyICgyOSBiaXRzKQorCisgIC8vIEZpbmQgdGhlIG1heCBmaWVsZCBudW1iZXIKKyAgaW50IG1heF9maWVsZF9udW1iZXIgPSAwOworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2MtPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGlmICghSWdub3JlRmllbGQoZGVzYy0+ZmllbGQoaSkpICYmCisgICAgICAgIGRlc2MtPmZpZWxkKGkpLT5udW1iZXIoKSA+IG1heF9maWVsZF9udW1iZXIpIHsKKyAgICAgIG1heF9maWVsZF9udW1iZXIgPSBkZXNjLT5maWVsZChpKS0+bnVtYmVyKCk7CisgICAgfQorICB9CisKKyAgaW50IHBpdm90ID0gLTE7CisgIGlmIChJc0V4dGVuZGFibGUoZGVzYykpIHsKKyAgICBwaXZvdCA9ICgobWF4X2ZpZWxkX251bWJlciArIDEpIDwga0RlZmF1bHRQaXZvdCkgPworICAgICAgICAobWF4X2ZpZWxkX251bWJlciArIDEpIDoga0RlZmF1bHRQaXZvdDsKKyAgfQorCisgIHJldHVybiBTaW1wbGVJdG9hKHBpdm90KTsKK30KKworLy8gUmV0dXJucyB0cnVlIGZvciBmaWVsZHMgdGhhdCByZXByZXNlbnQgIm51bGwiIGFzIGRpc3RpbmN0IGZyb20gdGhlIGRlZmF1bHQKKy8vIHZhbHVlLiBTZWUgaHR0cHM6Ly9nby9wcm90bzMjaGVhZGluZz1oLmtvemV3cXFjcWh1eiBmb3IgbW9yZSBpbmZvcm1hdGlvbi4KK2Jvb2wgSGFzRmllbGRQcmVzZW5jZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIHJldHVybgorICAgICAgKGZpZWxkLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFKSB8fAorICAgICAgKGZpZWxkLT5jb250YWluaW5nX29uZW9mKCkgIT0gTlVMTCkgfHwKKyAgICAgIChmaWVsZC0+ZmlsZSgpLT5zeW50YXgoKSAhPSBGaWxlRGVzY3JpcHRvcjo6U1lOVEFYX1BST1RPMyk7Cit9CisKKy8vIEZvciBwcm90bzMgZmllbGRzIHdpdGhvdXQgcHJlc2VuY2UsIHJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBkZWZhdWx0CisvLyB2YWx1ZSBpbiBKYXZhU2NyaXB0LiBTZWUgaHR0cHM6Ly9nby9wcm90bzMjaGVhZGluZz1oLmtvemV3cXFjcWh1eiBmb3IgbW9yZQorLy8gaW5mb3JtYXRpb24uCitzdHJpbmcgUHJvdG8zUHJpbWl0aXZlRmllbGREZWZhdWx0KGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgc3dpdGNoIChmaWVsZC0+Y3BwX3R5cGUoKSkgeworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0lOVDMyOgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0lOVDY0OgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1VJTlQzMjoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9VSU5UNjQ6IHsKKyAgICAgIHJldHVybiAiMCI7CisgICAgfQorCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRU5VTToKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9GTE9BVDoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9ET1VCTEU6CisgICAgICByZXR1cm4gIjAiOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfQk9PTDoKKyAgICAgIHJldHVybiAiZmFsc2UiOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HOgorICAgICAgcmV0dXJuICJcIlwiIjsKKworICAgIGRlZmF1bHQ6CisgICAgICAvLyBCWVRFUyBhbmQgTUVTU0FHRSBhcmUgaGFuZGxlZCBzZXBhcmF0ZWx5LgorICAgICAgYXNzZXJ0KGZhbHNlKTsKKyAgICAgIHJldHVybiAiIjsKKyAgfQorfQorCit9ICAvLyBhbm9ueW1vdXMgbmFtZXNwYWNlCisKK3ZvaWQgR2VuZXJhdG9yOjpHZW5lcmF0ZUhlYWRlcihjb25zdCBHZW5lcmF0b3JPcHRpb25zJiBvcHRpb25zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KCIvKipcbiIKKyAgICAgICAgICAgICAgICAgIiAqIEBmaWxlb3ZlcnZpZXdcbiIKKyAgICAgICAgICAgICAgICAgIiAqIEBlbmhhbmNlYWJsZVxuIgorICAgICAgICAgICAgICAgICAiICogQHB1YmxpY1xuIgorICAgICAgICAgICAgICAgICAiICovXG4iCisgICAgICAgICAgICAgICAgICIvLyBHRU5FUkFURUQgQ09ERSAtLSBETyBOT1QgRURJVCFcbiIKKyAgICAgICAgICAgICAgICAgIlxuIik7Cit9CisKK3ZvaWQgR2VuZXJhdG9yOjpGaW5kUHJvdmlkZXMoY29uc3QgR2VuZXJhdG9yT3B0aW9ucyYgb3B0aW9ucywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZlY3Rvcjxjb25zdCBGaWxlRGVzY3JpcHRvcio+JiBmaWxlcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjpzZXQ8c3RyaW5nPiogcHJvdmlkZWQpIGNvbnN0IHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlcy5zaXplKCk7IGkrKykgeworICAgIGZvciAoaW50IGogPSAwOyBqIDwgZmlsZXNbaV0tPm1lc3NhZ2VfdHlwZV9jb3VudCgpOyBqKyspIHsKKyAgICAgIEZpbmRQcm92aWRlc0Zvck1lc3NhZ2Uob3B0aW9ucywgcHJpbnRlciwgZmlsZXNbaV0tPm1lc3NhZ2VfdHlwZShqKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3ZpZGVkKTsKKyAgICB9CisgICAgZm9yIChpbnQgaiA9IDA7IGogPCBmaWxlc1tpXS0+ZW51bV90eXBlX2NvdW50KCk7IGorKykgeworICAgICAgRmluZFByb3ZpZGVzRm9yRW51bShvcHRpb25zLCBwcmludGVyLCBmaWxlc1tpXS0+ZW51bV90eXBlKGopLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdmlkZWQpOworICAgIH0KKyAgfQorCisgIHByaW50ZXItPlByaW50KCJcbiIpOworfQorCit2b2lkIEdlbmVyYXRvcjo6RmluZFByb3ZpZGVzRm9yTWVzc2FnZSgKKyAgICBjb25zdCBHZW5lcmF0b3JPcHRpb25zJiBvcHRpb25zLAorICAgIGlvOjpQcmludGVyKiBwcmludGVyLAorICAgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2MsCisgICAgc3RkOjpzZXQ8c3RyaW5nPiogcHJvdmlkZWQpIGNvbnN0IHsKKyAgc3RyaW5nIG5hbWUgPSBHZXRQYXRoKG9wdGlvbnMsIGRlc2MpOworICBwcm92aWRlZC0+aW5zZXJ0KG5hbWUpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzYy0+ZW51bV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIEZpbmRQcm92aWRlc0ZvckVudW0ob3B0aW9ucywgcHJpbnRlciwgZGVzYy0+ZW51bV90eXBlKGkpLAorICAgICAgICAgICAgICAgICAgICAgICAgcHJvdmlkZWQpOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzYy0+bmVzdGVkX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgRmluZFByb3ZpZGVzRm9yTWVzc2FnZShvcHRpb25zLCBwcmludGVyLCBkZXNjLT5uZXN0ZWRfdHlwZShpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3ZpZGVkKTsKKyAgfQorfQorCit2b2lkIEdlbmVyYXRvcjo6RmluZFByb3ZpZGVzRm9yRW51bShjb25zdCBHZW5lcmF0b3JPcHRpb25zJiBvcHRpb25zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBFbnVtRGVzY3JpcHRvciogZW51bWRlc2MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OnNldDxzdHJpbmc+KiBwcm92aWRlZCkgY29uc3QgeworICBzdHJpbmcgbmFtZSA9IEdldFBhdGgob3B0aW9ucywgZW51bWRlc2MpOworICBwcm92aWRlZC0+aW5zZXJ0KG5hbWUpOworfQorCit2b2lkIEdlbmVyYXRvcjo6RmluZFByb3ZpZGVzRm9yRmllbGRzKAorICAgIGNvbnN0IEdlbmVyYXRvck9wdGlvbnMmIG9wdGlvbnMsCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgY29uc3QgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+JiBmaWVsZHMsCisgICAgc3RkOjpzZXQ8c3RyaW5nPiogcHJvdmlkZWQpIGNvbnN0IHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZHMuc2l6ZSgpOyBpKyspIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZmllbGRzW2ldOworCisgICAgaWYgKElnbm9yZUZpZWxkKGZpZWxkKSkgeworICAgICAgY29udGludWU7CisgICAgfQorCisgICAgc3RyaW5nIG5hbWUgPQorICAgICAgICBHZXRQYXRoKG9wdGlvbnMsIGZpZWxkLT5maWxlKCkpICsgIi4iICsgSlNPYmplY3RGaWVsZE5hbWUoZmllbGQpOworICAgIHByb3ZpZGVkLT5pbnNlcnQobmFtZSk7CisgIH0KK30KKwordm9pZCBHZW5lcmF0b3I6OkdlbmVyYXRlUHJvdmlkZXMoY29uc3QgR2VuZXJhdG9yT3B0aW9ucyYgb3B0aW9ucywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjpzZXQ8c3RyaW5nPiogcHJvdmlkZWQpIGNvbnN0IHsKKyAgZm9yIChzdGQ6OnNldDxzdHJpbmc+OjppdGVyYXRvciBpdCA9IHByb3ZpZGVkLT5iZWdpbigpOworICAgICAgIGl0ICE9IHByb3ZpZGVkLT5lbmQoKTsgKytpdCkgeworICAgIHByaW50ZXItPlByaW50KCJnb29nLnByb3ZpZGUoJyRuYW1lJCcpO1xuIiwKKyAgICAgICAgICAgICAgICAgICAibmFtZSIsICppdCk7CisgIH0KK30KKwordm9pZCBHZW5lcmF0b3I6OkdlbmVyYXRlUmVxdWlyZXMoY29uc3QgR2VuZXJhdG9yT3B0aW9ucyYgb3B0aW9ucywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVzY3JpcHRvciogZGVzYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6c2V0PHN0cmluZz4qIHByb3ZpZGVkKSBjb25zdCB7CisgIHN0ZDo6c2V0PHN0cmluZz4gcmVxdWlyZWQ7CisgIHN0ZDo6c2V0PHN0cmluZz4gZm9yd2FyZHM7CisgIGJvb2wgaGF2ZV9tZXNzYWdlID0gZmFsc2U7CisgIEZpbmRSZXF1aXJlc0Zvck1lc3NhZ2Uob3B0aW9ucywgZGVzYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAmcmVxdWlyZWQsICZmb3J3YXJkcywgJmhhdmVfbWVzc2FnZSk7CisKKyAgR2VuZXJhdGVSZXF1aXJlc0ltcGwob3B0aW9ucywgcHJpbnRlciwgJnJlcXVpcmVkLCAmZm9yd2FyZHMsIHByb3ZpZGVkLAorICAgICAgICAgICAgICAgICAgICAgICAvKiByZXF1aXJlX2pzcGIgPSAqLyBoYXZlX21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgIC8qIHJlcXVpcmVfZXh0ZW5zaW9uID0gKi8gSGFzRXh0ZW5zaW9ucyhkZXNjKSk7Cit9CisKK3ZvaWQgR2VuZXJhdG9yOjpHZW5lcmF0ZVJlcXVpcmVzKGNvbnN0IEdlbmVyYXRvck9wdGlvbnMmIG9wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZlY3Rvcjxjb25zdCBGaWxlRGVzY3JpcHRvcio+JiBmaWxlcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6c2V0PHN0cmluZz4qIHByb3ZpZGVkKSBjb25zdCB7CisgIHN0ZDo6c2V0PHN0cmluZz4gcmVxdWlyZWQ7CisgIHN0ZDo6c2V0PHN0cmluZz4gZm9yd2FyZHM7CisgIGJvb2wgaGF2ZV9leHRlbnNpb25zID0gZmFsc2U7CisgIGJvb2wgaGF2ZV9tZXNzYWdlID0gZmFsc2U7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlcy5zaXplKCk7IGkrKykgeworICAgIGZvciAoaW50IGogPSAwOyBqIDwgZmlsZXNbaV0tPm1lc3NhZ2VfdHlwZV9jb3VudCgpOyBqKyspIHsKKyAgICAgIEZpbmRSZXF1aXJlc0Zvck1lc3NhZ2Uob3B0aW9ucywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZXNbaV0tPm1lc3NhZ2VfdHlwZShqKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnJlcXVpcmVkLCAmZm9yd2FyZHMsICZoYXZlX21lc3NhZ2UpOworICAgIH0KKyAgICBpZiAoIWhhdmVfZXh0ZW5zaW9ucyAmJiBIYXNFeHRlbnNpb25zKGZpbGVzW2ldKSkgeworICAgICAgaGF2ZV9leHRlbnNpb25zID0gdHJ1ZTsKKyAgICB9CisKKyAgICBmb3IgKGludCBqID0gMDsgaiA8IGZpbGVzW2ldLT5leHRlbnNpb25fY291bnQoKTsgaisrKSB7CisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGV4dGVuc2lvbiA9IGZpbGVzW2ldLT5leHRlbnNpb24oaik7CisgICAgICBpZiAoSWdub3JlRmllbGQoZXh0ZW5zaW9uKSkgeworICAgICAgICBjb250aW51ZTsKKyAgICAgIH0KKyAgICAgIGlmIChleHRlbnNpb24tPmNvbnRhaW5pbmdfdHlwZSgpLT5mdWxsX25hbWUoKSAhPQorICAgICAgICAgICJnb29nbGUucHJvdG9idWYuYnJpZGdlLk1lc3NhZ2VTZXQiKSB7CisgICAgICAgIHJlcXVpcmVkLmluc2VydChHZXRQYXRoKG9wdGlvbnMsIGV4dGVuc2lvbi0+Y29udGFpbmluZ190eXBlKCkpKTsKKyAgICAgIH0KKyAgICAgIEZpbmRSZXF1aXJlc0ZvckZpZWxkKG9wdGlvbnMsIGV4dGVuc2lvbiwgJnJlcXVpcmVkLCAmZm9yd2FyZHMpOworICAgICAgaGF2ZV9leHRlbnNpb25zID0gdHJ1ZTsKKyAgICB9CisgIH0KKworICBHZW5lcmF0ZVJlcXVpcmVzSW1wbChvcHRpb25zLCBwcmludGVyLCAmcmVxdWlyZWQsICZmb3J3YXJkcywgcHJvdmlkZWQsCisgICAgICAgICAgICAgICAgICAgICAgIC8qIHJlcXVpcmVfanNwYiA9ICovIGhhdmVfbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgLyogcmVxdWlyZV9leHRlbnNpb24gPSAqLyBoYXZlX2V4dGVuc2lvbnMpOworfQorCit2b2lkIEdlbmVyYXRvcjo6R2VuZXJhdGVSZXF1aXJlcyhjb25zdCBHZW5lcmF0b3JPcHRpb25zJiBvcHRpb25zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4mIGZpZWxkcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6c2V0PHN0cmluZz4qIHByb3ZpZGVkKSBjb25zdCB7CisgIHN0ZDo6c2V0PHN0cmluZz4gcmVxdWlyZWQ7CisgIHN0ZDo6c2V0PHN0cmluZz4gZm9yd2FyZHM7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRzLnNpemUoKTsgaSsrKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGZpZWxkc1tpXTsKKyAgICBpZiAoSWdub3JlRmllbGQoZmllbGQpKSB7CisgICAgICBjb250aW51ZTsKKyAgICB9CisgICAgRmluZFJlcXVpcmVzRm9yRXh0ZW5zaW9uKG9wdGlvbnMsIGZpZWxkLCAmcmVxdWlyZWQsICZmb3J3YXJkcyk7CisgIH0KKworICBHZW5lcmF0ZVJlcXVpcmVzSW1wbChvcHRpb25zLCBwcmludGVyLCAmcmVxdWlyZWQsICZmb3J3YXJkcywgcHJvdmlkZWQsCisgICAgICAgICAgICAgICAgICAgICAgIC8qIHJlcXVpcmVfanNwYiA9ICovIGZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgICAvKiByZXF1aXJlX2V4dGVuc2lvbiA9ICovIGZpZWxkcy5zaXplKCkgPiAwKTsKK30KKwordm9pZCBHZW5lcmF0b3I6OkdlbmVyYXRlUmVxdWlyZXNJbXBsKGNvbnN0IEdlbmVyYXRvck9wdGlvbnMmIG9wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjpzZXQ8c3RyaW5nPiogcmVxdWlyZWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjpzZXQ8c3RyaW5nPiogZm9yd2FyZHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjpzZXQ8c3RyaW5nPiogcHJvdmlkZWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCByZXF1aXJlX2pzcGIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCByZXF1aXJlX2V4dGVuc2lvbikgY29uc3QgeworICBpZiAocmVxdWlyZV9qc3BiKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJnb29nLnJlcXVpcmUoJ2pzcGIuTWVzc2FnZScpO1xuIik7CisgICAgaWYgKG9wdGlvbnMuYmluYXJ5KSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAiZ29vZy5yZXF1aXJlKCdqc3BiLkJpbmFyeVJlYWRlcicpO1xuIgorICAgICAgICAgICJnb29nLnJlcXVpcmUoJ2pzcGIuQmluYXJ5V3JpdGVyJyk7XG4iKTsKKyAgICB9CisgIH0KKyAgaWYgKHJlcXVpcmVfZXh0ZW5zaW9uKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICJnb29nLnJlcXVpcmUoJ2pzcGIuRXh0ZW5zaW9uRmllbGRJbmZvJyk7XG4iKTsKKyAgfQorCisgIHN0ZDo6c2V0PHN0cmluZz46Oml0ZXJhdG9yIGl0OworICBmb3IgKGl0ID0gcmVxdWlyZWQtPmJlZ2luKCk7IGl0ICE9IHJlcXVpcmVkLT5lbmQoKTsgKytpdCkgeworICAgIGlmIChwcm92aWRlZC0+ZmluZCgqaXQpICE9IHByb3ZpZGVkLT5lbmQoKSkgeworICAgICAgY29udGludWU7CisgICAgfQorICAgIHByaW50ZXItPlByaW50KCJnb29nLnJlcXVpcmUoJyRuYW1lJCcpO1xuIiwKKyAgICAgICAgICAgICAgICAgICAibmFtZSIsICppdCk7CisgIH0KKworICBwcmludGVyLT5QcmludCgiXG4iKTsKKworICBmb3IgKGl0ID0gZm9yd2FyZHMtPmJlZ2luKCk7IGl0ICE9IGZvcndhcmRzLT5lbmQoKTsgKytpdCkgeworICAgIGlmIChwcm92aWRlZC0+ZmluZCgqaXQpICE9IHByb3ZpZGVkLT5lbmQoKSkgeworICAgICAgY29udGludWU7CisgICAgfQorICAgIHByaW50ZXItPlByaW50KCJnb29nLmZvcndhcmREZWNsYXJlKCckbmFtZSQnKTtcbiIsCisgICAgICAgICAgICAgICAgICAgIm5hbWUiLCAqaXQpOworICB9Cit9CisKK2Jvb2wgTmFtZXNwYWNlT25seShjb25zdCBEZXNjcmlwdG9yKiBkZXNjKSB7CisgIHJldHVybiBmYWxzZTsKK30KKwordm9pZCBHZW5lcmF0b3I6OkZpbmRSZXF1aXJlc0Zvck1lc3NhZ2UoCisgICAgY29uc3QgR2VuZXJhdG9yT3B0aW9ucyYgb3B0aW9ucywKKyAgICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjLAorICAgIHN0ZDo6c2V0PHN0cmluZz4qIHJlcXVpcmVkLAorICAgIHN0ZDo6c2V0PHN0cmluZz4qIGZvcndhcmRzLAorICAgIGJvb2wqIGhhdmVfbWVzc2FnZSkgY29uc3QgeworCisKKyAgaWYgKCFOYW1lc3BhY2VPbmx5KGRlc2MpKSB7CisgICAgKmhhdmVfbWVzc2FnZSA9IHRydWU7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBkZXNjLT5maWVsZChpKTsKKyAgICAgIGlmIChJZ25vcmVGaWVsZChmaWVsZCkpIHsKKyAgICAgICAgY29udGludWU7CisgICAgICB9CisgICAgICBGaW5kUmVxdWlyZXNGb3JGaWVsZChvcHRpb25zLCBmaWVsZCwgcmVxdWlyZWQsIGZvcndhcmRzKTsKKyAgICB9CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2MtPmV4dGVuc2lvbl9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzYy0+ZXh0ZW5zaW9uKGkpOworICAgIGlmIChJZ25vcmVGaWVsZChmaWVsZCkpIHsKKyAgICAgIGNvbnRpbnVlOworICAgIH0KKyAgICBGaW5kUmVxdWlyZXNGb3JFeHRlbnNpb24ob3B0aW9ucywgZmllbGQsIHJlcXVpcmVkLCBmb3J3YXJkcyk7CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2MtPm5lc3RlZF90eXBlX2NvdW50KCk7IGkrKykgeworICAgIEZpbmRSZXF1aXJlc0Zvck1lc3NhZ2Uob3B0aW9ucywgZGVzYy0+bmVzdGVkX3R5cGUoaSksIHJlcXVpcmVkLCBmb3J3YXJkcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhdmVfbWVzc2FnZSk7CisgIH0KK30KKwordm9pZCBHZW5lcmF0b3I6OkZpbmRSZXF1aXJlc0ZvckZpZWxkKGNvbnN0IEdlbmVyYXRvck9wdGlvbnMmIG9wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OnNldDxzdHJpbmc+KiByZXF1aXJlZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OnNldDxzdHJpbmc+KiBmb3J3YXJkcykgY29uc3QgeworICAgIGlmIChmaWVsZC0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRU5VTSAmJgorICAgICAgICAvLyBOLkIuOiBmaWxlLWxldmVsIGV4dGVuc2lvbnMgd2l0aCBlbnVtIHR5cGUgZG8gKm5vdCogY3JlYXRlCisgICAgICAgIC8vIGRlcGVuZGVuY2llcywgYXMgcGVyIG9yaWdpbmFsIGNvZGVnZW4uCisgICAgICAgICEoZmllbGQtPmlzX2V4dGVuc2lvbigpICYmIGZpZWxkLT5leHRlbnNpb25fc2NvcGUoKSA9PSBOVUxMKSkgeworICAgICAgaWYgKG9wdGlvbnMuYWRkX3JlcXVpcmVfZm9yX2VudW1zKSB7CisgICAgICAgIHJlcXVpcmVkLT5pbnNlcnQoR2V0UGF0aChvcHRpb25zLCBmaWVsZC0+ZW51bV90eXBlKCkpKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGZvcndhcmRzLT5pbnNlcnQoR2V0UGF0aChvcHRpb25zLCBmaWVsZC0+ZW51bV90eXBlKCkpKTsKKyAgICAgIH0KKyAgICB9IGVsc2UgaWYgKGZpZWxkLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFKSB7CisgICAgICByZXF1aXJlZC0+aW5zZXJ0KEdldFBhdGgob3B0aW9ucywgZmllbGQtPm1lc3NhZ2VfdHlwZSgpKSk7CisgICAgfQorfQorCit2b2lkIEdlbmVyYXRvcjo6RmluZFJlcXVpcmVzRm9yRXh0ZW5zaW9uKGNvbnN0IEdlbmVyYXRvck9wdGlvbnMmIG9wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6c2V0PHN0cmluZz4qIHJlcXVpcmVkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OnNldDxzdHJpbmc+KiBmb3J3YXJkcykgY29uc3QgeworICAgIGlmIChmaWVsZC0+Y29udGFpbmluZ190eXBlKCktPmZ1bGxfbmFtZSgpICE9ICJnb29nbGUucHJvdG9idWYuYnJpZGdlLk1lc3NhZ2VTZXQiKSB7CisgICAgICByZXF1aXJlZC0+aW5zZXJ0KEdldFBhdGgob3B0aW9ucywgZmllbGQtPmNvbnRhaW5pbmdfdHlwZSgpKSk7CisgICAgfQorICAgIEZpbmRSZXF1aXJlc0ZvckZpZWxkKG9wdGlvbnMsIGZpZWxkLCByZXF1aXJlZCwgZm9yd2FyZHMpOworfQorCit2b2lkIEdlbmVyYXRvcjo6R2VuZXJhdGVUZXN0T25seShjb25zdCBHZW5lcmF0b3JPcHRpb25zJiBvcHRpb25zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgaWYgKG9wdGlvbnMudGVzdG9ubHkpIHsKKyAgICBwcmludGVyLT5QcmludCgiZ29vZy5zZXRUZXN0T25seSgpO1xuXG4iKTsKKyAgfQorICBwcmludGVyLT5QcmludCgiXG4iKTsKK30KKwordm9pZCBHZW5lcmF0b3I6OkdlbmVyYXRlQ2xhc3Nlc0FuZEVudW1zKGNvbnN0IEdlbmVyYXRvck9wdGlvbnMmIG9wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUpIGNvbnN0IHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlLT5tZXNzYWdlX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgR2VuZXJhdGVDbGFzcyhvcHRpb25zLCBwcmludGVyLCBmaWxlLT5tZXNzYWdlX3R5cGUoaSkpOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZS0+ZW51bV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIEdlbmVyYXRlRW51bShvcHRpb25zLCBwcmludGVyLCBmaWxlLT5lbnVtX3R5cGUoaSkpOworICB9Cit9CisKK3ZvaWQgR2VuZXJhdG9yOjpHZW5lcmF0ZUNsYXNzKGNvbnN0IEdlbmVyYXRvck9wdGlvbnMmIG9wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2MpIGNvbnN0IHsKKyAgaWYgKCFOYW1lc3BhY2VPbmx5KGRlc2MpKSB7CisgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisgICAgR2VuZXJhdGVDbGFzc0NvbnN0cnVjdG9yKG9wdGlvbnMsIHByaW50ZXIsIGRlc2MpOworICAgIEdlbmVyYXRlQ2xhc3NGaWVsZEluZm8ob3B0aW9ucywgcHJpbnRlciwgZGVzYyk7CisKKworICAgIEdlbmVyYXRlQ2xhc3NUb09iamVjdChvcHRpb25zLCBwcmludGVyLCBkZXNjKTsKKyAgICBpZiAob3B0aW9ucy5iaW5hcnkpIHsKKyAgICAgIC8vIFRoZXNlIG11c3QgY29tZSAqYmVmb3JlKiB0aGUgZXh0ZW5zaW9uLWZpZWxkIGluZm8gZ2VuZXJhdGlvbiBpbgorICAgICAgLy8gR2VuZXJhdGVDbGFzc1JlZ2lzdHJhdGlvbiBzbyB0aGF0IHJlZmVyZW5jZXMgdG8gdGhlIGJpbmFyeQorICAgICAgLy8gc2VyaWFsaXphdGlvbi9kZXNlcmlhbGl6YXRpb24gZnVuY3Rpb25zIG1heSBiZSBwbGFjZWQgaW4gdGhlIGV4dGVuc2lvbgorICAgICAgLy8gb2JqZWN0cy4KKyAgICAgIEdlbmVyYXRlQ2xhc3NEZXNlcmlhbGl6ZUJpbmFyeShvcHRpb25zLCBwcmludGVyLCBkZXNjKTsKKyAgICAgIEdlbmVyYXRlQ2xhc3NTZXJpYWxpemVCaW5hcnkob3B0aW9ucywgcHJpbnRlciwgZGVzYyk7CisgICAgfQorICAgIEdlbmVyYXRlQ2xhc3NDbG9uZShvcHRpb25zLCBwcmludGVyLCBkZXNjKTsKKyAgICBHZW5lcmF0ZUNsYXNzUmVnaXN0cmF0aW9uKG9wdGlvbnMsIHByaW50ZXIsIGRlc2MpOworICAgIEdlbmVyYXRlQ2xhc3NGaWVsZHMob3B0aW9ucywgcHJpbnRlciwgZGVzYyk7CisgICAgaWYgKElzRXh0ZW5kYWJsZShkZXNjKSAmJiBkZXNjLT5mdWxsX25hbWUoKSAhPSAiZ29vZ2xlLnByb3RvYnVmLmJyaWRnZS5NZXNzYWdlU2V0IikgeworICAgICAgR2VuZXJhdGVDbGFzc0V4dGVuc2lvbkZpZWxkSW5mbyhvcHRpb25zLCBwcmludGVyLCBkZXNjKTsKKyAgICB9CisgIH0KKworICAvLyBSZWN1cnNlIG9uIG5lc3RlZCB0eXBlcy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjLT5lbnVtX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgR2VuZXJhdGVFbnVtKG9wdGlvbnMsIHByaW50ZXIsIGRlc2MtPmVudW1fdHlwZShpKSk7CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjLT5uZXN0ZWRfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBHZW5lcmF0ZUNsYXNzKG9wdGlvbnMsIHByaW50ZXIsIGRlc2MtPm5lc3RlZF90eXBlKGkpKTsKKyAgfQorfQorCit2b2lkIEdlbmVyYXRvcjo6R2VuZXJhdGVDbGFzc0NvbnN0cnVjdG9yKGNvbnN0IEdlbmVyYXRvck9wdGlvbnMmIG9wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KAorICAgICAgIi8qKlxuIgorICAgICAgIiAqIEdlbmVyYXRlZCBieSBKc1BiQ29kZUdlbmVyYXRvci5cbiIKKyAgICAgICIgKiBAcGFyYW0ge0FycmF5PX0gb3B0X2RhdGEgT3B0aW9uYWwgaW5pdGlhbCBkYXRhIGFycmF5LCB0eXBpY2FsbHkgIgorICAgICAgImZyb20gYVxuIgorICAgICAgIiAqIHNlcnZlciByZXNwb25zZSwgb3IgY29uc3RydWN0ZWQgZGlyZWN0bHkgaW4gSmF2YXNjcmlwdC4gVGhlIGFycmF5ICIKKyAgICAgICJpcyB1c2VkXG4iCisgICAgICAiICogaW4gcGxhY2UgYW5kIGJlY29tZXMgcGFydCBvZiB0aGUgY29uc3RydWN0ZWQgb2JqZWN0LiBJdCBpcyBub3QgIgorICAgICAgImNsb25lZC5cbiIKKyAgICAgICIgKiBJZiBubyBkYXRhIGlzIHByb3ZpZGVkLCB0aGUgY29uc3RydWN0ZWQgb2JqZWN0IHdpbGwgYmUgZW1wdHksIGJ1dCAiCisgICAgICAic3RpbGxcbiIKKyAgICAgICIgKiB2YWxpZC5cbiIKKyAgICAgICIgKiBAZXh0ZW5kcyB7anNwYi5NZXNzYWdlfVxuIgorICAgICAgIiAqIEBjb25zdHJ1Y3RvclxuIgorICAgICAgIiAqL1xuIgorICAgICAgIiRjbGFzc25hbWUkID0gZnVuY3Rpb24ob3B0X2RhdGEpIHtcbiIsCisgICAgICAiY2xhc3NuYW1lIiwgR2V0UGF0aChvcHRpb25zLCBkZXNjKSk7CisgIHN0cmluZyBtZXNzYWdlX2lkID0gR2V0TWVzc2FnZUlkKGRlc2MpOworICBwcmludGVyLT5QcmludCgKKyAgICAgICIgIGpzcGIuTWVzc2FnZS5pbml0aWFsaXplKHRoaXMsIG9wdF9kYXRhLCAkbWVzc2FnZUlkJCwgJHBpdm90JCwgIgorICAgICAgIiRycHRmaWVsZHMkLCAkb25lb2ZmaWVsZHMkKTtcbiIsCisgICAgICAibWVzc2FnZUlkIiwgIW1lc3NhZ2VfaWQuZW1wdHkoKSA/CisgICAgICAgICAgICAgICAgICAgKCInIiArIG1lc3NhZ2VfaWQgKyAiJyIpIDoKKyAgICAgICAgICAgICAgICAgICAoSXNSZXNwb25zZShkZXNjKSA/ICInJyIgOiAiMCIpLAorICAgICAgInBpdm90IiwgR2V0UGl2b3QoZGVzYyksCisgICAgICAicnB0ZmllbGRzIiwgUmVwZWF0ZWRGaWVsZHNBcnJheU5hbWUob3B0aW9ucywgZGVzYyksCisgICAgICAib25lb2ZmaWVsZHMiLCBPbmVvZkZpZWxkc0FycmF5TmFtZShvcHRpb25zLCBkZXNjKSk7CisgIHByaW50ZXItPlByaW50KAorICAgICAgIn07XG4iCisgICAgICAiZ29vZy5pbmhlcml0cygkY2xhc3NuYW1lJCwganNwYi5NZXNzYWdlKTtcbiIKKyAgICAgICJpZiAoZ29vZy5ERUJVRyAmJiAhQ09NUElMRUQpIHtcbiIKKyAgICAgICIgICRjbGFzc25hbWUkLmRpc3BsYXlOYW1lID0gJyRjbGFzc25hbWUkJztcbiIKKyAgICAgICJ9XG4iLAorICAgICAgImNsYXNzbmFtZSIsIEdldFBhdGgob3B0aW9ucywgZGVzYykpOworfQorCit2b2lkIEdlbmVyYXRvcjo6R2VuZXJhdGVDbGFzc0ZpZWxkSW5mbyhjb25zdCBHZW5lcmF0b3JPcHRpb25zJiBvcHRpb25zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjKSBjb25zdCB7CisgIGlmIChIYXNSZXBlYXRlZEZpZWxkcyhkZXNjKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiLyoqXG4iCisgICAgICAgICIgKiBMaXN0IG9mIHJlcGVhdGVkIGZpZWxkcyB3aXRoaW4gdGhpcyBtZXNzYWdlIHR5cGUuXG4iCisgICAgICAgICIgKiBAcHJpdmF0ZSB7IUFycmF5PG51bWJlcj59XG4iCisgICAgICAgICIgKiBAY29uc3RcbiIKKyAgICAgICAgIiAqL1xuIgorICAgICAgICAiJGNsYXNzbmFtZSQkcnB0ZmllbGRhcnJheSQgPSAkcnB0ZmllbGRzJDtcbiIKKyAgICAgICAgIlxuIiwKKyAgICAgICAgImNsYXNzbmFtZSIsIEdldFBhdGgob3B0aW9ucywgZGVzYyksCisgICAgICAgICJycHRmaWVsZGFycmF5Iiwga1JlcGVhdGVkRmllbGRBcnJheU5hbWUsCisgICAgICAgICJycHRmaWVsZHMiLCBSZXBlYXRlZEZpZWxkTnVtYmVyTGlzdChkZXNjKSk7CisgIH0KKworICBpZiAoSGFzT25lb2ZGaWVsZHMoZGVzYykpIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIi8qKlxuIgorICAgICAgICAiICogT25lb2YgZ3JvdXAgZGVmaW5pdGlvbnMgZm9yIHRoaXMgbWVzc2FnZS4gRWFjaCBncm91cCBkZWZpbmVzIHRoZSAiCisgICAgICAgICJmaWVsZFxuIgorICAgICAgICAiICogbnVtYmVycyBiZWxvbmdpbmcgdG8gdGhhdCBncm91cC4gV2hlbiBvZiB0aGVzZSBmaWVsZHMnIHZhbHVlIGlzICIKKyAgICAgICAgInNldCwgYWxsXG4iCisgICAgICAgICIgKiBvdGhlciBmaWVsZHMgaW4gdGhlIGdyb3VwIGFyZSBjbGVhcmVkLiBEdXJpbmcgZGVzZXJpYWxpemF0aW9uLCBpZiAiCisgICAgICAgICJtdWx0aXBsZVxuIgorICAgICAgICAiICogZmllbGRzIGFyZSBlbmNvdW50ZXJlZCBmb3IgYSBncm91cCwgb25seSB0aGUgbGFzdCB2YWx1ZSBzZWVuIHdpbGwgIgorICAgICAgICAiYmUga2VwdC5cbiIKKyAgICAgICAgIiAqIEBwcml2YXRlIHshQXJyYXk8IUFycmF5PG51bWJlcj4+fVxuIgorICAgICAgICAiICogQGNvbnN0XG4iCisgICAgICAgICIgKi9cbiIKKyAgICAgICAgIiRjbGFzc25hbWUkJG9uZW9mZ3JvdXBhcnJheSQgPSAkb25lb2Zncm91cHMkO1xuIgorICAgICAgICAiXG4iLAorICAgICAgICAiY2xhc3NuYW1lIiwgR2V0UGF0aChvcHRpb25zLCBkZXNjKSwKKyAgICAgICAgIm9uZW9mZ3JvdXBhcnJheSIsIGtPbmVvZkdyb3VwQXJyYXlOYW1lLAorICAgICAgICAib25lb2Zncm91cHMiLCBPbmVvZkdyb3VwTGlzdChkZXNjKSk7CisKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2MtPm9uZW9mX2RlY2xfY291bnQoKTsgaSsrKSB7CisgICAgICBpZiAoSWdub3JlT25lb2YoZGVzYy0+b25lb2ZfZGVjbChpKSkpIHsKKyAgICAgICAgY29udGludWU7CisgICAgICB9CisgICAgICBHZW5lcmF0ZU9uZW9mQ2FzZURlZmluaXRpb24ob3B0aW9ucywgcHJpbnRlciwgZGVzYy0+b25lb2ZfZGVjbChpKSk7CisgICAgfQorICB9Cit9CisKK3ZvaWQgR2VuZXJhdG9yOjpHZW5lcmF0ZUNsYXNzWGlkKGNvbnN0IEdlbmVyYXRvck9wdGlvbnMmIG9wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2MpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiXG4iCisgICAgICAiXG4iCisgICAgICAiJGNsYXNzJC5wcm90b3R5cGUubWVzc2FnZVhpZCA9IHhpZCgnJGNsYXNzJCcpO1xuIiwKKyAgICAgICJjbGFzcyIsIEdldFBhdGgob3B0aW9ucywgZGVzYykpOworfQorCit2b2lkIEdlbmVyYXRvcjo6R2VuZXJhdGVPbmVvZkNhc2VEZWZpbml0aW9uKAorICAgIGNvbnN0IEdlbmVyYXRvck9wdGlvbnMmIG9wdGlvbnMsCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBvbmVvZikgY29uc3QgeworICBwcmludGVyLT5QcmludCgKKyAgICAgICIvKipcbiIKKyAgICAgICIgKiBAZW51bSB7bnVtYmVyfVxuIgorICAgICAgIiAqL1xuIgorICAgICAgIiRjbGFzc25hbWUkLiRvbmVvZiRDYXNlID0ge1xuIgorICAgICAgIiAgJHVwY2FzZSRfTk9UX1NFVDogMCIsCisgICAgICAiY2xhc3NuYW1lIiwgR2V0UGF0aChvcHRpb25zLCBvbmVvZi0+Y29udGFpbmluZ190eXBlKCkpLAorICAgICAgIm9uZW9mIiwgSlNPbmVvZk5hbWUob25lb2YpLAorICAgICAgInVwY2FzZSIsIFRvRW51bUNhc2Uob25lb2YtPm5hbWUoKSkpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgb25lb2YtPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGlmIChJZ25vcmVGaWVsZChvbmVvZi0+ZmllbGQoaSkpKSB7CisgICAgICBjb250aW51ZTsKKyAgICB9CisKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIixcbiIKKyAgICAgICAgIiAgJHVwY2FzZSQ6ICRudW1iZXIkIiwKKyAgICAgICAgInVwY2FzZSIsIFRvRW51bUNhc2Uob25lb2YtPmZpZWxkKGkpLT5uYW1lKCkpLAorICAgICAgICAibnVtYmVyIiwgSlNGaWVsZEluZGV4KG9uZW9mLT5maWVsZChpKSkpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiXG4iCisgICAgICAifTtcbiIKKyAgICAgICJcbiIKKyAgICAgICIvKipcbiIKKyAgICAgICIgKiBAcmV0dXJuIHskY2xhc3MkLiRvbmVvZiRDYXNlfVxuIgorICAgICAgIiAqL1xuIgorICAgICAgIiRjbGFzcyQucHJvdG90eXBlLmdldCRvbmVvZiRDYXNlID0gZnVuY3Rpb24oKSB7XG4iCisgICAgICAiICByZXR1cm4gLyoqIEB0eXBlIHskY2xhc3MkLiRvbmVvZiRDYXNlfSAqLyhqc3BiLk1lc3NhZ2UuIgorICAgICAgImNvbXB1dGVPbmVvZkNhc2UodGhpcywgJGNsYXNzJC5vbmVvZkdyb3Vwc19bJG9uZW9maW5kZXgkXSkpO1xuIgorICAgICAgIn07XG4iCisgICAgICAiXG4iLAorICAgICAgImNsYXNzIiwgR2V0UGF0aChvcHRpb25zLCBvbmVvZi0+Y29udGFpbmluZ190eXBlKCkpLAorICAgICAgIm9uZW9mIiwgSlNPbmVvZk5hbWUob25lb2YpLAorICAgICAgIm9uZW9maW5kZXgiLCBKU09uZW9mSW5kZXgob25lb2YpKTsKK30KKwordm9pZCBHZW5lcmF0b3I6OkdlbmVyYXRlQ2xhc3NUb09iamVjdChjb25zdCBHZW5lcmF0b3JPcHRpb25zJiBvcHRpb25zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVzY3JpcHRvciogZGVzYykgY29uc3QgeworICBwcmludGVyLT5QcmludCgKKyAgICAgICJcbiIKKyAgICAgICJcbiIKKyAgICAgICJpZiAoanNwYi5NZXNzYWdlLkdFTkVSQVRFX1RPX09CSkVDVCkge1xuIgorICAgICAgIi8qKlxuIgorICAgICAgIiAqIENyZWF0ZXMgYW4gb2JqZWN0IHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgcHJvdG8gc3VpdGFibGUgZm9yIHVzZSBpbiAiCisgICAgICAiU295IHRlbXBsYXRlcy5cbiIKKyAgICAgICIgKiBGaWVsZCBuYW1lcyB0aGF0IGFyZSByZXNlcnZlZCBpbiBKYXZhU2NyaXB0IGFuZCB3aWxsIGJlIHJlbmFtZWQgdG8gIgorICAgICAgInBiX25hbWUuXG4iCisgICAgICAiICogVG8gYWNjZXNzIGEgcmVzZXJ2ZWQgZmllbGQgdXNlLCBmb28ucGJfPG5hbWU+LCBlZywgZm9vLnBiX2RlZmF1bHQuXG4iCisgICAgICAiICogRm9yIHRoZSBsaXN0IG9mIHJlc2VydmVkIG5hbWVzIHBsZWFzZSBzZWU6XG4iCisgICAgICAiICogICAgIGNvbS5nb29nbGUuYXBwcy5qc3BiLkpzQ2xhc3NUZW1wbGF0ZS5KU19SRVNFUlZFRF9XT1JEUy5cbiIKKyAgICAgICIgKiBAcGFyYW0ge2Jvb2xlYW49fSBvcHRfaW5jbHVkZUluc3RhbmNlIFdoZXRoZXIgdG8gaW5jbHVkZSB0aGUgSlNQQiAiCisgICAgICAiaW5zdGFuY2VcbiIKKyAgICAgICIgKiAgICAgZm9yIHRyYW5zaXRpb25hbCBzb3kgcHJvdG8gc3VwcG9ydDogaHR0cDovL2dvdG8vc295LXBhcmFtLSIKKyAgICAgICJtaWdyYXRpb25cbiIKKyAgICAgICIgKiBAcmV0dXJuIHshT2JqZWN0fVxuIgorICAgICAgIiAqL1xuIgorICAgICAgIiRjbGFzc25hbWUkLnByb3RvdHlwZS50b09iamVjdCA9IGZ1bmN0aW9uKG9wdF9pbmNsdWRlSW5zdGFuY2UpIHtcbiIKKyAgICAgICIgIHJldHVybiAkY2xhc3NuYW1lJC50b09iamVjdChvcHRfaW5jbHVkZUluc3RhbmNlLCB0aGlzKTtcbiIKKyAgICAgICJ9O1xuIgorICAgICAgIlxuIgorICAgICAgIlxuIgorICAgICAgIi8qKlxuIgorICAgICAgIiAqIFN0YXRpYyB2ZXJzaW9uIG9mIHRoZSB7QHNlZSB0b09iamVjdH0gbWV0aG9kLlxuIgorICAgICAgIiAqIEBwYXJhbSB7Ym9vbGVhbnx1bmRlZmluZWR9IGluY2x1ZGVJbnN0YW5jZSBXaGV0aGVyIHRvIGluY2x1ZGUgdGhlICIKKyAgICAgICJKU1BCXG4iCisgICAgICAiICogICAgIGluc3RhbmNlIGZvciB0cmFuc2l0aW9uYWwgc295IHByb3RvIHN1cHBvcnQ6XG4iCisgICAgICAiICogICAgIGh0dHA6Ly9nb3RvL3NveS1wYXJhbS1taWdyYXRpb25cbiIKKyAgICAgICIgKiBAcGFyYW0geyEkY2xhc3NuYW1lJH0gbXNnIFRoZSBtc2cgaW5zdGFuY2UgdG8gdHJhbnNmb3JtLlxuIgorICAgICAgIiAqIEByZXR1cm4geyFPYmplY3R9XG4iCisgICAgICAiICovXG4iCisgICAgICAiJGNsYXNzbmFtZSQudG9PYmplY3QgPSBmdW5jdGlvbihpbmNsdWRlSW5zdGFuY2UsIG1zZykge1xuIgorICAgICAgIiAgdmFyIGYsIG9iaiA9IHsiLAorICAgICAgImNsYXNzbmFtZSIsIEdldFBhdGgob3B0aW9ucywgZGVzYykpOworCisgIGJvb2wgZmlyc3QgPSB0cnVlOworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2MtPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBkZXNjLT5maWVsZChpKTsKKyAgICBpZiAoSWdub3JlRmllbGQoZmllbGQpKSB7CisgICAgICBjb250aW51ZTsKKyAgICB9CisKKyAgICBpZiAoIWZpcnN0KSB7CisgICAgICBwcmludGVyLT5QcmludCgiLFxuICAgICIpOworICAgIH0gZWxzZSB7CisgICAgICBwcmludGVyLT5QcmludCgiXG4gICAgIik7CisgICAgICBmaXJzdCA9IGZhbHNlOworICAgIH0KKworICAgIEdlbmVyYXRlQ2xhc3NGaWVsZFRvT2JqZWN0KG9wdGlvbnMsIHByaW50ZXIsIGZpZWxkKTsKKyAgfQorCisgIGlmICghZmlyc3QpIHsKKyAgICBwcmludGVyLT5QcmludCgiXG4gIH07XG5cbiIpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KCJcblxuICB9O1xuXG4iKTsKKyAgfQorCisgIGlmIChJc0V4dGVuZGFibGUoZGVzYykpIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIiAganNwYi5NZXNzYWdlLnRvT2JqZWN0RXh0ZW5zaW9uKC8qKiBAdHlwZSB7IWpzcGIuTWVzc2FnZX0gKi8gKG1zZyksICIKKyAgICAgICAgIm9iaixcbiIKKyAgICAgICAgIiAgICAgICRleHRPYmplY3QkLCAkY2xhc3MkLnByb3RvdHlwZS5nZXRFeHRlbnNpb24sXG4iCisgICAgICAgICIgICAgICBpbmNsdWRlSW5zdGFuY2UpO1xuIiwKKyAgICAgICAgImV4dE9iamVjdCIsIEpTRXh0ZW5zaW9uc09iamVjdE5hbWUob3B0aW9ucywgZGVzYyksCisgICAgICAgICJjbGFzcyIsIEdldFBhdGgob3B0aW9ucywgZGVzYykpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiICBpZiAoaW5jbHVkZUluc3RhbmNlKSB7XG4iCisgICAgICAiICAgIG9iai4kJGpzcGJNZXNzYWdlSW5zdGFuY2UgPSBtc2dcbiIKKyAgICAgICIgIH1cbiIKKyAgICAgICIgIHJldHVybiBvYmo7XG4iCisgICAgICAifTtcbiIKKyAgICAgICJ9XG4iCisgICAgICAiXG4iCisgICAgICAiXG4iLAorICAgICAgImNsYXNzbmFtZSIsIEdldFBhdGgob3B0aW9ucywgZGVzYykpOworfQorCit2b2lkIEdlbmVyYXRvcjo6R2VuZXJhdGVDbGFzc0ZpZWxkVG9PYmplY3QoY29uc3QgR2VuZXJhdG9yT3B0aW9ucyYgb3B0aW9ucywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KCIkZmllbGRuYW1lJDogIiwKKyAgICAgICAgICAgICAgICAgImZpZWxkbmFtZSIsIEpTT2JqZWN0RmllbGROYW1lKGZpZWxkKSk7CisKKyAgaWYgKGZpZWxkLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFKSB7CisgICAgLy8gTWVzc2FnZSBmaWVsZC4KKyAgICBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkpIHsKKyAgICAgIHsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoImpzcGIuTWVzc2FnZS50b09iamVjdExpc3QobXNnLmdldCRnZXR0ZXIkKCksXG4iCisgICAgICAgICAgICAgICAgICAgICAgICIgICAgJHR5cGUkLnRvT2JqZWN0LCBpbmNsdWRlSW5zdGFuY2UpIiwKKyAgICAgICAgICAgICAgICAgICAgICAgImdldHRlciIsIEpTR2V0dGVyTmFtZShmaWVsZCksCisgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIiwgR2V0UGF0aChvcHRpb25zLCBmaWVsZC0+bWVzc2FnZV90eXBlKCkpKTsKKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgcHJpbnRlci0+UHJpbnQoIihmID0gbXNnLmdldCRnZXR0ZXIkKCkpICYmICIKKyAgICAgICAgICAgICAgICAgICAgICIkdHlwZSQudG9PYmplY3QoaW5jbHVkZUluc3RhbmNlLCBmKSIsCisgICAgICAgICAgICAgICAgICAgICAiZ2V0dGVyIiwgSlNHZXR0ZXJOYW1lKGZpZWxkKSwKKyAgICAgICAgICAgICAgICAgICAgICJ0eXBlIiwgR2V0UGF0aChvcHRpb25zLCBmaWVsZC0+bWVzc2FnZV90eXBlKCkpKTsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgLy8gU2ltcGxlIGZpZWxkIChzaW5ndWxhciBvciByZXBlYXRlZCkuCisgICAgaWYgKCFIYXNGaWVsZFByZXNlbmNlKGZpZWxkKSAmJiAhZmllbGQtPmlzX3JlcGVhdGVkKCkpIHsKKyAgICAgIC8vIERlbGVnYXRlIHRvIHRoZSBnZW5lcmF0ZWQgZ2V0PGZpZWxkPigpIG1ldGhvZCBpbiBvcmRlciBub3QgdG8gZHVwbGljYXRlCisgICAgICAvLyB0aGUgcHJvdG8zLWZpZWxkLWRlZmF1bHQtdmFsdWUgbG9naWMgaGVyZS4KKyAgICAgIHByaW50ZXItPlByaW50KCJtc2cuZ2V0JGdldHRlciQoKSIsCisgICAgICAgICAgICAgICAgICAgICAiZ2V0dGVyIiwgSlNHZXR0ZXJOYW1lKGZpZWxkKSk7CisgICAgfSBlbHNlIHsKKyAgICAgIGlmIChmaWVsZC0+aGFzX2RlZmF1bHRfdmFsdWUoKSkgeworICAgICAgICBwcmludGVyLT5QcmludCgianNwYi5NZXNzYWdlLmdldEZpZWxkKG1zZywgJGluZGV4JCkgIT0gbnVsbCA/ICIKKyAgICAgICAgICAgICAgICAgICAgICAgImpzcGIuTWVzc2FnZS5nZXRGaWVsZChtc2csICRpbmRleCQpIDogJGRlZmF1bHRWYWx1ZSQiLAorICAgICAgICAgICAgICAgICAgICAgICAiaW5kZXgiLCBKU0ZpZWxkSW5kZXgoZmllbGQpLAorICAgICAgICAgICAgICAgICAgICAgICAiZGVmYXVsdFZhbHVlIiwgSlNGaWVsZERlZmF1bHQoZmllbGQpKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHByaW50ZXItPlByaW50KCJqc3BiLk1lc3NhZ2UuZ2V0RmllbGQobXNnLCAkaW5kZXgkKSIsCisgICAgICAgICAgICAgICAgICAgICAgICJpbmRleCIsIEpTRmllbGRJbmRleChmaWVsZCkpOworICAgICAgfQorICAgIH0KKyAgfQorfQorCit2b2lkIEdlbmVyYXRvcjo6R2VuZXJhdGVDbGFzc0Zyb21PYmplY3QoY29uc3QgR2VuZXJhdG9yT3B0aW9ucyYgb3B0aW9ucywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KAorICAgICAgImlmIChqc3BiLk1lc3NhZ2UuR0VORVJBVEVfRlJPTV9PQkpFQ1QpIHtcbiIKKyAgICAgICIvKipcbiIKKyAgICAgICIgKiBMb2FkcyBkYXRhIGZyb20gYW4gb2JqZWN0IGludG8gYSBuZXcgaW5zdGFuY2Ugb2YgdGhpcyBwcm90by5cbiIKKyAgICAgICIgKiBAcGFyYW0geyFPYmplY3R9IG9iaiBUaGUgb2JqZWN0IHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgcHJvdG8gdG9cbiIKKyAgICAgICIgKiAgICAgbG9hZCB0aGUgZGF0YSBmcm9tLlxuIgorICAgICAgIiAqIEByZXR1cm4geyEkY2xhc3NuYW1lJH1cbiIKKyAgICAgICIgKi9cbiIKKyAgICAgICIkY2xhc3NuYW1lJC5mcm9tT2JqZWN0ID0gZnVuY3Rpb24ob2JqKSB7XG4iCisgICAgICAiICB2YXIgZiwgbXNnID0gbmV3ICRjbGFzc25hbWUkKCk7XG4iLAorICAgICAgImNsYXNzbmFtZSIsIEdldFBhdGgob3B0aW9ucywgZGVzYykpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzYy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2MtPmZpZWxkKGkpOworICAgIEdlbmVyYXRlQ2xhc3NGaWVsZEZyb21PYmplY3Qob3B0aW9ucywgcHJpbnRlciwgZmllbGQpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiICByZXR1cm4gbXNnO1xuIgorICAgICAgIn07XG4iCisgICAgICAifVxuIik7Cit9CisKK3ZvaWQgR2VuZXJhdG9yOjpHZW5lcmF0ZUNsYXNzRmllbGRGcm9tT2JqZWN0KAorICAgIGNvbnN0IEdlbmVyYXRvck9wdGlvbnMmIG9wdGlvbnMsCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3QgeworICBpZiAoZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UpIHsKKyAgICAvLyBNZXNzYWdlIGZpZWxkIChzaW5ndWxhciBvciByZXBlYXRlZCkKKyAgICBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkpIHsKKyAgICAgIHsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgICAiICBnb29nLmlzRGVmKG9iai4kbmFtZSQpICYmICIKKyAgICAgICAgICAgICJqc3BiLk1lc3NhZ2Uuc2V0UmVwZWF0ZWRXcmFwcGVyRmllbGQoXG4iCisgICAgICAgICAgICAiICAgICAgbXNnLCAkaW5kZXgkLCBnb29nLmFycmF5Lm1hcChvYmouJG5hbWUkLCBmdW5jdGlvbihpKSB7XG4iCisgICAgICAgICAgICAiICAgICAgICByZXR1cm4gJGZpZWxkY2xhc3MkLmZyb21PYmplY3QoaSk7XG4iCisgICAgICAgICAgICAiICAgICAgfSkpO1xuIiwKKyAgICAgICAgICAgICJuYW1lIiwgSlNPYmplY3RGaWVsZE5hbWUoZmllbGQpLAorICAgICAgICAgICAgImluZGV4IiwgSlNGaWVsZEluZGV4KGZpZWxkKSwKKyAgICAgICAgICAgICJmaWVsZGNsYXNzIiwgR2V0UGF0aChvcHRpb25zLCBmaWVsZC0+bWVzc2FnZV90eXBlKCkpKTsKKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgIiAgZ29vZy5pc0RlZihvYmouJG5hbWUkKSAmJiBqc3BiLk1lc3NhZ2Uuc2V0V3JhcHBlckZpZWxkKFxuIgorICAgICAgICAgICIgICAgICBtc2csICRpbmRleCQsICRmaWVsZGNsYXNzJC5mcm9tT2JqZWN0KG9iai4kbmFtZSQpKTtcbiIsCisgICAgICAgICAgIm5hbWUiLCBKU09iamVjdEZpZWxkTmFtZShmaWVsZCksCisgICAgICAgICAgImluZGV4IiwgSlNGaWVsZEluZGV4KGZpZWxkKSwKKyAgICAgICAgICAiZmllbGRjbGFzcyIsIEdldFBhdGgob3B0aW9ucywgZmllbGQtPm1lc3NhZ2VfdHlwZSgpKSk7CisgICAgfQorICB9IGVsc2UgeworICAgIC8vIFNpbXBsZSAocHJpbWl0aXZlKSBmaWVsZC4KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIiAgZ29vZy5pc0RlZihvYmouJG5hbWUkKSAmJiBqc3BiLk1lc3NhZ2Uuc2V0RmllbGQobXNnLCAkaW5kZXgkLCAiCisgICAgICAgICJvYmouJG5hbWUkKTtcbiIsCisgICAgICAgICJuYW1lIiwgSlNPYmplY3RGaWVsZE5hbWUoZmllbGQpLAorICAgICAgICAiaW5kZXgiLCBKU0ZpZWxkSW5kZXgoZmllbGQpKTsKKyAgfQorfQorCit2b2lkIEdlbmVyYXRvcjo6R2VuZXJhdGVDbGFzc0Nsb25lKGNvbnN0IEdlbmVyYXRvck9wdGlvbnMmIG9wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjKSBjb25zdCB7CisgIHByaW50ZXItPlByaW50KAorICAgICAgIi8qKlxuIgorICAgICAgIiAqIENyZWF0ZXMgYSBkZWVwIGNsb25lIG9mIHRoaXMgcHJvdG8uIE5vIGRhdGEgaXMgc2hhcmVkIHdpdGggdGhlICIKKyAgICAgICJvcmlnaW5hbC5cbiIKKyAgICAgICIgKiBAcmV0dXJuIHshJG5hbWUkfSBUaGUgY2xvbmUuXG4iCisgICAgICAiICovXG4iCisgICAgICAiJG5hbWUkLnByb3RvdHlwZS5jbG9uZU1lc3NhZ2UgPSBmdW5jdGlvbigpIHtcbiIKKyAgICAgICIgIHJldHVybiAvKiogQHR5cGUgeyEkbmFtZSR9ICovIChqc3BiLk1lc3NhZ2UuY2xvbmVNZXNzYWdlKHRoaXMpKTtcbiIKKyAgICAgICJ9O1xuXG5cbiIsCisgICAgICAibmFtZSIsIEdldFBhdGgob3B0aW9ucywgZGVzYykpOworfQorCit2b2lkIEdlbmVyYXRvcjo6R2VuZXJhdGVDbGFzc1JlZ2lzdHJhdGlvbihjb25zdCBHZW5lcmF0b3JPcHRpb25zJiBvcHRpb25zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjKSBjb25zdCB7CisgIC8vIFJlZ2lzdGVyIGFueSBleHRlbnNpb25zIGRlZmluZWQgaW5zaWRlIHRoaXMgbWVzc2FnZSB0eXBlLgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2MtPmV4dGVuc2lvbl9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGV4dGVuc2lvbiA9IGRlc2MtPmV4dGVuc2lvbihpKTsKKyAgICBpZiAoU2hvdWxkR2VuZXJhdGVFeHRlbnNpb24oZXh0ZW5zaW9uKSkgeworICAgICAgR2VuZXJhdGVFeHRlbnNpb24ob3B0aW9ucywgcHJpbnRlciwgZXh0ZW5zaW9uKTsKKyAgICB9CisgIH0KKworfQorCit2b2lkIEdlbmVyYXRvcjo6R2VuZXJhdGVDbGFzc0ZpZWxkcyhjb25zdCBHZW5lcmF0b3JPcHRpb25zJiBvcHRpb25zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjKSBjb25zdCB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzYy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgaWYgKCFJZ25vcmVGaWVsZChkZXNjLT5maWVsZChpKSkpIHsKKyAgICAgIEdlbmVyYXRlQ2xhc3NGaWVsZChvcHRpb25zLCBwcmludGVyLCBkZXNjLT5maWVsZChpKSk7CisgICAgfQorICB9Cit9CisKK3ZvaWQgR2VuZXJhdG9yOjpHZW5lcmF0ZUNsYXNzRmllbGQoY29uc3QgR2VuZXJhdG9yT3B0aW9ucyYgb3B0aW9ucywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0IHsKKyAgaWYgKGZpZWxkLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICIvKipcbiIKKyAgICAgICAgIiAqICRmaWVsZGRlZiRcbiIKKyAgICAgICAgIiRjb21tZW50JCIKKyAgICAgICAgIiAqIEByZXR1cm4geyR0eXBlJH1cbiIKKyAgICAgICAgIiAqL1xuIiwKKyAgICAgICAgImZpZWxkZGVmIiwgRmllbGREZWZpbml0aW9uKG9wdGlvbnMsIGZpZWxkKSwKKyAgICAgICAgImNvbW1lbnQiLCBGaWVsZENvbW1lbnRzKGZpZWxkKSwKKyAgICAgICAgInR5cGUiLCBKU0ZpZWxkVHlwZUFubm90YXRpb24ob3B0aW9ucywgZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGZvcmNlX29wdGlvbmFsID0gKi8gZmFsc2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGZvcmNlX3ByZXNlbnQgPSAqLyBmYWxzZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc2luZ3VsYXJfaWZfbm90X3BhY2tlZCA9ICovIGZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBhbHdheXNfc2luZ3VsYXIgPSAqLyBmYWxzZSkpOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiJGNsYXNzJC5wcm90b3R5cGUuZ2V0JG5hbWUkID0gZnVuY3Rpb24oKSB7XG4iCisgICAgICAgICIgIHJldHVybiAvKiogQHR5cGV7JHR5cGUkfSAqLyAoXG4iCisgICAgICAgICIgICAganNwYi5NZXNzYWdlLmdldCRycHQkV3JhcHBlckZpZWxkKHRoaXMsICR3cmFwcGVyY2xhc3MkLCAiCisgICAgICAgICIkaW5kZXgkJHJlcXVpcmVkJCkpO1xuIgorICAgICAgICAifTtcbiIKKyAgICAgICAgIlxuIgorICAgICAgICAiXG4iLAorICAgICAgICAiY2xhc3MiLCBHZXRQYXRoKG9wdGlvbnMsIGZpZWxkLT5jb250YWluaW5nX3R5cGUoKSksCisgICAgICAgICJuYW1lIiwgSlNHZXR0ZXJOYW1lKGZpZWxkKSwKKyAgICAgICAgInR5cGUiLCBKU0ZpZWxkVHlwZUFubm90YXRpb24ob3B0aW9ucywgZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGZvcmNlX29wdGlvbmFsID0gKi8gZmFsc2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGZvcmNlX3ByZXNlbnQgPSAqLyBmYWxzZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc2luZ3VsYXJfaWZfbm90X3BhY2tlZCA9ICovIGZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBhbHdheXNfc2luZ3VsYXIgPSAqLyBmYWxzZSksCisgICAgICAgICJycHQiLCAoZmllbGQtPmlzX3JlcGVhdGVkKCkgPyAiUmVwZWF0ZWQiIDogIiIpLAorICAgICAgICAiaW5kZXgiLCBKU0ZpZWxkSW5kZXgoZmllbGQpLAorICAgICAgICAid3JhcHBlcmNsYXNzIiwgR2V0UGF0aChvcHRpb25zLCBmaWVsZC0+bWVzc2FnZV90eXBlKCkpLAorICAgICAgICAicmVxdWlyZWQiLCAoZmllbGQtPmxhYmVsKCkgPT0gRmllbGREZXNjcmlwdG9yOjpMQUJFTF9SRVFVSVJFRCA/CisgICAgICAgICAgICAgICAgICAgICAiLCAxIiA6ICIiKSk7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICIvKiogQHBhcmFtIHskb3B0aW9uYWx0eXBlJH0gdmFsdWUgJHJldHVybmRvYyQgKi9cbiIKKyAgICAgICAgIiRjbGFzcyQucHJvdG90eXBlLnNldCRuYW1lJCA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4iCisgICAgICAgICIgIGpzcGIuTWVzc2FnZS5zZXQkb25lb2Z0YWckJHJlcGVhdGVkdGFnJFdyYXBwZXJGaWVsZCgiLAorICAgICAgICAib3B0aW9uYWx0eXBlIiwKKyAgICAgICAgSlNGaWVsZFR5cGVBbm5vdGF0aW9uKG9wdGlvbnMsIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZm9yY2Vfb3B0aW9uYWwgPSAqLyB0cnVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZm9yY2VfcHJlc2VudCA9ICovIGZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc2luZ3VsYXJfaWZfbm90X3BhY2tlZCA9ICovIGZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogYWx3YXlzX3Npbmd1bGFyID0gKi8gZmFsc2UpLAorICAgICAgICAicmV0dXJuZG9jIiwgSlNSZXR1cm5Eb2Mob3B0aW9ucywgZmllbGQpLAorICAgICAgICAiY2xhc3MiLCBHZXRQYXRoKG9wdGlvbnMsIGZpZWxkLT5jb250YWluaW5nX3R5cGUoKSksCisgICAgICAgICJuYW1lIiwgSlNHZXR0ZXJOYW1lKGZpZWxkKSwKKyAgICAgICAgIm9uZW9mdGFnIiwgKGZpZWxkLT5jb250YWluaW5nX29uZW9mKCkgPyAiT25lb2YiIDogIiIpLAorICAgICAgICAicmVwZWF0ZWR0YWciLCAoZmllbGQtPmlzX3JlcGVhdGVkKCkgPyAiUmVwZWF0ZWQiIDogIiIpKTsKKworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAidGhpcywgJGluZGV4JCRvbmVvZmdyb3VwJCwgdmFsdWUpOyRyZXR1cm52YWx1ZSRcbiIKKyAgICAgICAgIn07XG4iCisgICAgICAgICJcbiIKKyAgICAgICAgIlxuIiwKKyAgICAgICAgImluZGV4IiwgSlNGaWVsZEluZGV4KGZpZWxkKSwKKyAgICAgICAgIm9uZW9mZ3JvdXAiLCAoZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSA/CisgICAgICAgICAgICAgICAgICAgICAgICgiLCAiICsgSlNPbmVvZkFycmF5KG9wdGlvbnMsIGZpZWxkKSkgOiAiIiksCisgICAgICAgICJyZXR1cm52YWx1ZSIsIEpTUmV0dXJuQ2xhdXNlKGZpZWxkKSk7CisKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIiRjbGFzcyQucHJvdG90eXBlLmNsZWFyJG5hbWUkID0gZnVuY3Rpb24oKSB7XG4iCisgICAgICAgICIgIHRoaXMuc2V0JG5hbWUkKCRjbGVhcmVkdmFsdWUkKTskcmV0dXJudmFsdWUkXG4iCisgICAgICAgICJ9O1xuIgorICAgICAgICAiXG4iCisgICAgICAgICJcbiIsCisgICAgICAgICJjbGFzcyIsIEdldFBhdGgob3B0aW9ucywgZmllbGQtPmNvbnRhaW5pbmdfdHlwZSgpKSwKKyAgICAgICAgIm5hbWUiLCBKU0dldHRlck5hbWUoZmllbGQpLAorICAgICAgICAiY2xlYXJlZHZhbHVlIiwgKGZpZWxkLT5pc19yZXBlYXRlZCgpID8gIltdIiA6ICJ1bmRlZmluZWQiKSwKKyAgICAgICAgInJldHVybnZhbHVlIiwgSlNSZXR1cm5DbGF1c2UoZmllbGQpKTsKKworICB9IGVsc2UgeworICAgIHN0cmluZyB0eXBlZF9hbm5vdGF0aW9uOworCisgICAgLy8gU2ltcGxlIChwcmltaXRpdmUpIGZpZWxkLCBlaXRoZXIgc2luZ3VsYXIgb3IgcmVwZWF0ZWQuCisgICAgeworICAgICAgdHlwZWRfYW5ub3RhdGlvbiA9IEpTRmllbGRUeXBlQW5ub3RhdGlvbihvcHRpb25zLCBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGZvcmNlX29wdGlvbmFsID0gKi8gZmFsc2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBmb3JjZV9wcmVzZW50ID0gKi8gIUhhc0ZpZWxkUHJlc2VuY2UoZmllbGQpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc2luZ3VsYXJfaWZfbm90X3BhY2tlZCA9ICovIGZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogYWx3YXlzX3Npbmd1bGFyID0gKi8gZmFsc2UpLAorICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgIi8qKlxuIgorICAgICAgICAgICIgKiAkZmllbGRkZWYkXG4iCisgICAgICAgICAgIiRjb21tZW50JCIKKyAgICAgICAgICAiICogQHJldHVybiB7JHR5cGUkfVxuIgorICAgICAgICAgICIgKi9cbiIsCisgICAgICAgICAgImZpZWxkZGVmIiwgRmllbGREZWZpbml0aW9uKG9wdGlvbnMsIGZpZWxkKSwKKyAgICAgICAgICAiY29tbWVudCIsIEZpZWxkQ29tbWVudHMoZmllbGQpLAorICAgICAgICAgICJ0eXBlIiwgdHlwZWRfYW5ub3RhdGlvbik7CisgICAgfQorCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICIkY2xhc3MkLnByb3RvdHlwZS5nZXQkbmFtZSQgPSBmdW5jdGlvbigpIHtcbiIsCisgICAgICAgICJjbGFzcyIsIEdldFBhdGgob3B0aW9ucywgZmllbGQtPmNvbnRhaW5pbmdfdHlwZSgpKSwKKyAgICAgICAgIm5hbWUiLCBKU0dldHRlck5hbWUoZmllbGQpKTsKKworICAgIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICIgIHJldHVybiAvKiogQHR5cGUgeyR0eXBlJH0gKi8gKCIsCisgICAgICAgICAgInR5cGUiLCB0eXBlZF9hbm5vdGF0aW9uKTsKKyAgICB9CisKKyAgICAvLyBGb3IgcHJvdG8zIGZpZWxkcyB3aXRob3V0IHByZXNlbmNlLCB1c2Ugc3BlY2lhbCBnZXR0ZXJzIHRoYXQgd2lsbCByZXR1cm4KKyAgICAvLyBkZWZhdWx0cyB3aGVuIHRoZSBmaWVsZCBpcyB1bnNldCwgcG9zc2libHkgY29uc3RydWN0aW5nIGEgdmFsdWUgaWYKKyAgICAvLyByZXF1aXJlZC4KKyAgICBpZiAoIUhhc0ZpZWxkUHJlc2VuY2UoZmllbGQpICYmICFmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQoImpzcGIuTWVzc2FnZS5nZXRGaWVsZFByb3RvMyh0aGlzLCAkaW5kZXgkLCAkZGVmYXVsdCQpIiwKKyAgICAgICAgICAgICAgICAgICAgICJpbmRleCIsIEpTRmllbGRJbmRleChmaWVsZCksCisgICAgICAgICAgICAgICAgICAgICAiZGVmYXVsdCIsIFByb3RvM1ByaW1pdGl2ZUZpZWxkRGVmYXVsdChmaWVsZCkpOworICAgIH0gZWxzZSB7CisgICAgICBpZiAoZmllbGQtPmhhc19kZWZhdWx0X3ZhbHVlKCkpIHsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoImpzcGIuTWVzc2FnZS5nZXRGaWVsZCh0aGlzLCAkaW5kZXgkKSAhPSBudWxsID8gIgorICAgICAgICAgICAgICAgICAgICAgICAianNwYi5NZXNzYWdlLmdldEZpZWxkKHRoaXMsICRpbmRleCQpIDogJGRlZmF1bHRWYWx1ZSQiLAorICAgICAgICAgICAgICAgICAgICAgICAiaW5kZXgiLCBKU0ZpZWxkSW5kZXgoZmllbGQpLAorICAgICAgICAgICAgICAgICAgICAgICAiZGVmYXVsdFZhbHVlIiwgSlNGaWVsZERlZmF1bHQoZmllbGQpKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHByaW50ZXItPlByaW50KCJqc3BiLk1lc3NhZ2UuZ2V0RmllbGQodGhpcywgJGluZGV4JCkiLAorICAgICAgICAgICAgICAgICAgICAgICAiaW5kZXgiLCBKU0ZpZWxkSW5kZXgoZmllbGQpKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAiKTtcbiIKKyAgICAgICAgICAifTtcbiIKKyAgICAgICAgICAiXG4iCisgICAgICAgICAgIlxuIik7CisgICAgfQorCisgICAgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgIi8qKiBAcGFyYW0geyRvcHRpb25hbHR5cGUkfSB2YWx1ZSAkcmV0dXJuZG9jJCAqL1xuIiwKKyAgICAgICAgICAib3B0aW9uYWx0eXBlIiwKKyAgICAgICAgICBKU0ZpZWxkVHlwZUFubm90YXRpb24ob3B0aW9ucywgZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGZvcmNlX29wdGlvbmFsID0gKi8gdHJ1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZm9yY2VfcHJlc2VudCA9ICovICFIYXNGaWVsZFByZXNlbmNlKGZpZWxkKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc2luZ3VsYXJfaWZfbm90X3BhY2tlZCA9ICovIGZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBhbHdheXNfc2luZ3VsYXIgPSAqLyBmYWxzZSksCisgICAgICAgICAgInJldHVybmRvYyIsIEpTUmV0dXJuRG9jKG9wdGlvbnMsIGZpZWxkKSk7CisgICAgfQorCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICIkY2xhc3MkLnByb3RvdHlwZS5zZXQkbmFtZSQgPSBmdW5jdGlvbih2YWx1ZSkge1xuIgorICAgICAgICAiICBqc3BiLk1lc3NhZ2Uuc2V0JG9uZW9mdGFnJEZpZWxkKHRoaXMsICRpbmRleCQiLAorICAgICAgICAiY2xhc3MiLCBHZXRQYXRoKG9wdGlvbnMsIGZpZWxkLT5jb250YWluaW5nX3R5cGUoKSksCisgICAgICAgICJuYW1lIiwgSlNHZXR0ZXJOYW1lKGZpZWxkKSwKKyAgICAgICAgIm9uZW9mdGFnIiwgKGZpZWxkLT5jb250YWluaW5nX29uZW9mKCkgPyAiT25lb2YiIDogIiIpLAorICAgICAgICAiaW5kZXgiLCBKU0ZpZWxkSW5kZXgoZmllbGQpKTsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIiRvbmVvZmdyb3VwJCwgJHR5cGUkdmFsdWUkcnB0dmFsdWVpbml0JCR0eXBlY2xvc2UkKTskcmV0dXJudmFsdWUkXG4iCisgICAgICAgICJ9O1xuIgorICAgICAgICAiXG4iCisgICAgICAgICJcbiIsCisgICAgICAgICJ0eXBlIiwgIiIsCisgICAgICAgICJ0eXBlY2xvc2UiLCAiIiwKKyAgICAgICAgIm9uZW9mZ3JvdXAiLAorICAgICAgICAoZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSA/ICgiLCAiICsgSlNPbmVvZkFycmF5KG9wdGlvbnMsIGZpZWxkKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAiIiksCisgICAgICAgICJyZXR1cm52YWx1ZSIsIEpTUmV0dXJuQ2xhdXNlKGZpZWxkKSwgInJwdHZhbHVlaW5pdCIsCisgICAgICAgIChmaWVsZC0+aXNfcmVwZWF0ZWQoKSA/ICIgfHwgW10iIDogIiIpKTsKKworCisgICAgaWYgKEhhc0ZpZWxkUHJlc2VuY2UoZmllbGQpKSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAiJGNsYXNzJC5wcm90b3R5cGUuY2xlYXIkbmFtZSQgPSBmdW5jdGlvbigpIHtcbiIKKyAgICAgICAgICAiICBqc3BiLk1lc3NhZ2Uuc2V0JG9uZW9mdGFnJEZpZWxkKHRoaXMsICRpbmRleCQkb25lb2Zncm91cCQsICIsCisgICAgICAgICAgImNsYXNzIiwgR2V0UGF0aChvcHRpb25zLCBmaWVsZC0+Y29udGFpbmluZ190eXBlKCkpLAorICAgICAgICAgICJuYW1lIiwgSlNHZXR0ZXJOYW1lKGZpZWxkKSwKKyAgICAgICAgICAib25lb2Z0YWciLCAoZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSA/ICJPbmVvZiIgOiAiIiksCisgICAgICAgICAgIm9uZW9mZ3JvdXAiLCAoZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSA/CisgICAgICAgICAgICAgICAgICAgICAgICAgKCIsICIgKyBKU09uZW9mQXJyYXkob3B0aW9ucywgZmllbGQpKSA6ICIiKSwKKyAgICAgICAgICAiaW5kZXgiLCBKU0ZpZWxkSW5kZXgoZmllbGQpKTsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICIkY2xlYXJlZHZhbHVlJCk7JHJldHVybnZhbHVlJFxuIgorICAgICAgICAgICJ9O1xuIgorICAgICAgICAgICJcbiIKKyAgICAgICAgICAiXG4iLAorICAgICAgICAgICJjbGVhcmVkdmFsdWUiLCAoZmllbGQtPmlzX3JlcGVhdGVkKCkgPyAiW10iIDogInVuZGVmaW5lZCIpLAorICAgICAgICAgICJyZXR1cm52YWx1ZSIsIEpTUmV0dXJuQ2xhdXNlKGZpZWxkKSk7CisgICAgfQorICB9Cit9CisKK3ZvaWQgR2VuZXJhdG9yOjpHZW5lcmF0ZUNsYXNzRXh0ZW5zaW9uRmllbGRJbmZvKGNvbnN0IEdlbmVyYXRvck9wdGlvbnMmIG9wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2MpIGNvbnN0IHsKKyAgaWYgKElzRXh0ZW5kYWJsZShkZXNjKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiXG4iCisgICAgICAgICIvKipcbiIKKyAgICAgICAgIiAqIFRoZSBleHRlbnNpb25zIHJlZ2lzdGVyZWQgd2l0aCB0aGlzIG1lc3NhZ2UgY2xhc3MuIFRoaXMgaXMgYSAiCisgICAgICAgICJtYXAgb2ZcbiIKKyAgICAgICAgIiAqIGV4dGVuc2lvbiBmaWVsZCBudW1iZXIgdG8gZmllbGRJbmZvIG9iamVjdC5cbiIKKyAgICAgICAgIiAqXG4iCisgICAgICAgICIgKiBGb3IgZXhhbXBsZTpcbiIKKyAgICAgICAgIiAqICAgICB7IDEyMzoge2ZpZWxkSW5kZXg6IDEyMywgZmllbGROYW1lOiB7bXlfZmllbGRfbmFtZTogMH0sICIKKyAgICAgICAgImN0b3I6IHByb3RvLmV4YW1wbGUuTXlNZXNzYWdlfSB9XG4iCisgICAgICAgICIgKlxuIgorICAgICAgICAiICogZmllbGROYW1lIGNvbnRhaW5zIHRoZSBKc0NvbXBpbGVyIHJlbmFtZWQgZmllbGQgbmFtZSBwcm9wZXJ0eSAiCisgICAgICAgICJzbyB0aGF0IGl0XG4iCisgICAgICAgICIgKiB3b3JrcyBpbiBPUFRJTUlaRUQgbW9kZS5cbiIKKyAgICAgICAgIiAqXG4iCisgICAgICAgICIgKiBAdHlwZSB7IU9iamVjdC48bnVtYmVyLCBqc3BiLkV4dGVuc2lvbkZpZWxkSW5mbz59XG4iCisgICAgICAgICIgKi9cbiIKKyAgICAgICAgIiRjbGFzcyQuZXh0ZW5zaW9ucyA9IHt9O1xuIgorICAgICAgICAiXG4iLAorICAgICAgICAiY2xhc3MiLCBHZXRQYXRoKG9wdGlvbnMsIGRlc2MpKTsKKyAgfQorfQorCisKK3ZvaWQgR2VuZXJhdG9yOjpHZW5lcmF0ZUNsYXNzRGVzZXJpYWxpemVCaW5hcnkoY29uc3QgR2VuZXJhdG9yT3B0aW9ucyYgb3B0aW9ucywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2MpIGNvbnN0IHsKKyAgLy8gVE9ETyhjZmFsbGluKTogSGFuZGxlIGxhenkgZGVjb2Rpbmcgd2hlbiByZXF1ZXN0ZWQgYnkgZmllbGQgb3B0aW9uIGFuZC9vcgorICAvLyBieSBkZWZhdWx0IGZvciAnYnl0ZXMnIGZpZWxkcyBhbmQgcGFja2VkIHJlcGVhdGVkIGZpZWxkcy4KKworICBwcmludGVyLT5QcmludCgKKyAgICAgICIvKipcbiIKKyAgICAgICIgKiBEZXNlcmlhbGl6ZXMgYmluYXJ5IGRhdGEgKGluIHByb3RvYnVmIHdpcmUgZm9ybWF0KS5cbiIKKyAgICAgICIgKiBAcGFyYW0ge2pzcGIuQnl0ZVNvdXJjZX0gYnl0ZXMgVGhlIGJ5dGVzIHRvIGRlc2VyaWFsaXplLlxuIgorICAgICAgIiAqIEByZXR1cm4geyEkY2xhc3MkfVxuIgorICAgICAgIiAqL1xuIgorICAgICAgIiRjbGFzcyQuZGVzZXJpYWxpemVCaW5hcnkgPSBmdW5jdGlvbihieXRlcykge1xuIgorICAgICAgIiAgdmFyIHJlYWRlciA9IG5ldyBqc3BiLkJpbmFyeVJlYWRlcihieXRlcyk7XG4iCisgICAgICAiICB2YXIgbXNnID0gbmV3ICRjbGFzcyQ7XG4iCisgICAgICAiICByZXR1cm4gJGNsYXNzJC5kZXNlcmlhbGl6ZUJpbmFyeUZyb21SZWFkZXIobXNnLCByZWFkZXIpO1xuIgorICAgICAgIn07XG4iCisgICAgICAiXG4iCisgICAgICAiXG4iCisgICAgICAiLyoqXG4iCisgICAgICAiICogRGVzZXJpYWxpemVzIGJpbmFyeSBkYXRhIChpbiBwcm90b2J1ZiB3aXJlIGZvcm1hdCkgZnJvbSB0aGVcbiIKKyAgICAgICIgKiBnaXZlbiByZWFkZXIgaW50byB0aGUgZ2l2ZW4gbWVzc2FnZSBvYmplY3QuXG4iCisgICAgICAiICogQHBhcmFtIHshJGNsYXNzJH0gbXNnIFRoZSBtZXNzYWdlIG9iamVjdCB0byBkZXNlcmlhbGl6ZSBpbnRvLlxuIgorICAgICAgIiAqIEBwYXJhbSB7IWpzcGIuQmluYXJ5UmVhZGVyfSByZWFkZXIgVGhlIEJpbmFyeVJlYWRlciB0byB1c2UuXG4iCisgICAgICAiICogQHJldHVybiB7ISRjbGFzcyR9XG4iCisgICAgICAiICovXG4iCisgICAgICAiJGNsYXNzJC5kZXNlcmlhbGl6ZUJpbmFyeUZyb21SZWFkZXIgPSBmdW5jdGlvbihtc2csIHJlYWRlcikge1xuIgorICAgICAgIiAgd2hpbGUgKHJlYWRlci5uZXh0RmllbGQoKSkge1xuIgorICAgICAgIiAgICBpZiAocmVhZGVyLmlzRW5kR3JvdXAoKSkge1xuIgorICAgICAgIiAgICAgIGJyZWFrO1xuIgorICAgICAgIiAgICB9XG4iCisgICAgICAiICAgIHZhciBmaWVsZCA9IHJlYWRlci5nZXRGaWVsZE51bWJlcigpO1xuIgorICAgICAgIiAgICBzd2l0Y2ggKGZpZWxkKSB7XG4iLAorICAgICAgImNsYXNzIiwgR2V0UGF0aChvcHRpb25zLCBkZXNjKSk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBHZW5lcmF0ZUNsYXNzRGVzZXJpYWxpemVCaW5hcnlGaWVsZChvcHRpb25zLCBwcmludGVyLCBkZXNjLT5maWVsZChpKSk7CisgIH0KKworICBwcmludGVyLT5QcmludCgKKyAgICAgICIgICAgZGVmYXVsdDpcbiIpOworICBpZiAoSXNFeHRlbmRhYmxlKGRlc2MpKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICIgICAgICBqc3BiLk1lc3NhZ2UucmVhZEJpbmFyeUV4dGVuc2lvbihtc2csIHJlYWRlciwgJGV4dG9iaiQsXG4iCisgICAgICAgICIgICAgICAgICRjbGFzcyQucHJvdG90eXBlLmdldEV4dGVuc2lvbixcbiIKKyAgICAgICAgIiAgICAgICAgJGNsYXNzJC5wcm90b3R5cGUuc2V0RXh0ZW5zaW9uKTtcbiIKKyAgICAgICAgIiAgICAgIGJyZWFrO1xuIiwKKyAgICAgICAgImV4dG9iaiIsIEpTRXh0ZW5zaW9uc09iamVjdE5hbWUob3B0aW9ucywgZGVzYyksCisgICAgICAgICJjbGFzcyIsIEdldFBhdGgob3B0aW9ucywgZGVzYykpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiICAgICAgcmVhZGVyLnNraXBGaWVsZCgpO1xuIgorICAgICAgICAiICAgICAgYnJlYWs7XG4iKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KAorICAgICAgIiAgICB9XG4iCisgICAgICAiICB9XG4iCisgICAgICAiICByZXR1cm4gbXNnO1xuIgorICAgICAgIn07XG4iCisgICAgICAiXG4iCisgICAgICAiXG4iKTsKK30KKwordm9pZCBHZW5lcmF0b3I6OkdlbmVyYXRlQ2xhc3NEZXNlcmlhbGl6ZUJpbmFyeUZpZWxkKAorICAgIGNvbnN0IEdlbmVyYXRvck9wdGlvbnMmIG9wdGlvbnMsCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3QgeworCisgIHByaW50ZXItPlByaW50KCIgICAgY2FzZSAkbnVtJDpcbiIsCisgICAgICAgICAgICAgICAgICJudW0iLCBTaW1wbGVJdG9hKGZpZWxkLT5udW1iZXIoKSkpOworCisgIGlmIChmaWVsZC0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiICAgICAgdmFyIHZhbHVlID0gbmV3ICRmaWVsZGNsYXNzJDtcbiIKKyAgICAgICAgIiAgICAgIHJlYWRlci5yZWFkJG1zZ09yR3JvdXAkKCRncnBmaWVsZCR2YWx1ZSwiCisgICAgICAgICIkZmllbGRjbGFzcyQuZGVzZXJpYWxpemVCaW5hcnlGcm9tUmVhZGVyKTtcbiIsCisgICAgICAgICJmaWVsZGNsYXNzIiwgR2V0UGF0aChvcHRpb25zLCBmaWVsZC0+bWVzc2FnZV90eXBlKCkpLAorICAgICAgICAibXNnT3JHcm91cCIsIChmaWVsZC0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9HUk9VUCkgPworICAgICAgICAgICAgICAgICAgICAgICJHcm91cCIgOiAiTWVzc2FnZSIsCisgICAgICAgICJncnBmaWVsZCIsIChmaWVsZC0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9HUk9VUCkgPworICAgICAgICAgICAgICAgICAgICAoU2ltcGxlSXRvYShmaWVsZC0+bnVtYmVyKCkpICsgIiwgIikgOiAiIik7CisgIH0gZWxzZSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICIgICAgICB2YXIgdmFsdWUgPSAvKiogQHR5cGUgeyRmaWVsZHR5cGUkfSAqLyAocmVhZGVyLiRyZWFkZXIkKCkpO1xuIiwKKyAgICAgICAgImZpZWxkdHlwZSIsIEpTRmllbGRUeXBlQW5ub3RhdGlvbihvcHRpb25zLCBmaWVsZCwgZmFsc2UsIHRydWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc2luZ3VsYXJfaWZfbm90X3BhY2tlZCA9ICovIHRydWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogYWx3YXlzX3Npbmd1bGFyID0gKi8gZmFsc2UpLAorICAgICAgICAicmVhZGVyIiwgSlNCaW5hcnlSZWFkZXJNZXRob2ROYW1lKGZpZWxkKSk7CisgIH0KKworICBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkgJiYgIWZpZWxkLT5pc19wYWNrZWQoKSkgeworICAgIC8vIFJlcGVhdGVkIGZpZWxkcyByZWNlaXZlIGEgfHZhbHVlfCBvbmUgYXQgYXQgYSB0aW1lOyBhcHBlbmQgdG8gYXJyYXkKKyAgICAvLyByZXR1cm5lZCBieSBnZXQkbmFtZSQoKS4KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIiAgICAgIG1zZy5nZXQkbmFtZSQoKS5wdXNoKHZhbHVlKTtcbiIsCisgICAgICAgICJuYW1lIiwgSlNHZXR0ZXJOYW1lKGZpZWxkKSk7CisgIH0gZWxzZSB7CisgICAgLy8gU2luZ3VsYXIgZmllbGRzLCBhbmQgcGFja2VkIHJlcGVhdGVkIGZpZWxkcywgcmVjZWl2ZSBhIHx2YWx1ZXwgZWl0aGVyIGFzCisgICAgLy8gdGhlIGZpZWxkJ3MgdmFsdWUgb3IgYXMgdGhlIGFycmF5IG9mIGFsbCB0aGUgZmllbGQncyB2YWx1ZXM7IHNldCB0aGlzIGFzCisgICAgLy8gdGhlIGZpZWxkJ3MgdmFsdWUgZGlyZWN0bHkuCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICIgICAgICBtc2cuc2V0JG5hbWUkKHZhbHVlKTtcbiIsCisgICAgICAgICJuYW1lIiwgSlNHZXR0ZXJOYW1lKGZpZWxkKSk7CisgIH0KKworICBwcmludGVyLT5QcmludCgiICAgICAgYnJlYWs7XG4iKTsKK30KKwordm9pZCBHZW5lcmF0b3I6OkdlbmVyYXRlQ2xhc3NTZXJpYWxpemVCaW5hcnkoY29uc3QgR2VuZXJhdG9yT3B0aW9ucyYgb3B0aW9ucywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVzY3JpcHRvciogZGVzYykgY29uc3QgeworICBwcmludGVyLT5QcmludCgKKyAgICAgICIvKipcbiIKKyAgICAgICIgKiBDbGFzcyBtZXRob2QgdmFyaWFudDogc2VyaWFsaXplcyB0aGUgZ2l2ZW4gbWVzc2FnZSB0byBiaW5hcnkgZGF0YVxuIgorICAgICAgIiAqIChpbiBwcm90b2J1ZiB3aXJlIGZvcm1hdCksIHdyaXRpbmcgdG8gdGhlIGdpdmVuIEJpbmFyeVdyaXRlci5cbiIKKyAgICAgICIgKiBAcGFyYW0geyEkY2xhc3MkfSBtZXNzYWdlXG4iCisgICAgICAiICogQHBhcmFtIHshanNwYi5CaW5hcnlXcml0ZXJ9IHdyaXRlclxuIgorICAgICAgIiAqL1xuIgorICAgICAgIiRjbGFzcyQuc2VyaWFsaXplQmluYXJ5VG9Xcml0ZXIgPSBmdW5jdGlvbihtZXNzYWdlLCAiCisgICAgICAid3JpdGVyKSB7XG4iCisgICAgICAiICBtZXNzYWdlLnNlcmlhbGl6ZUJpbmFyeVRvV3JpdGVyKHdyaXRlcik7XG4iCisgICAgICAifTtcbiIKKyAgICAgICJcbiIKKyAgICAgICJcbiIKKyAgICAgICIvKipcbiIKKyAgICAgICIgKiBTZXJpYWxpemVzIHRoZSBtZXNzYWdlIHRvIGJpbmFyeSBkYXRhIChpbiBwcm90b2J1ZiB3aXJlIGZvcm1hdCkuXG4iCisgICAgICAiICogQHJldHVybiB7IVVpbnQ4QXJyYXl9XG4iCisgICAgICAiICovXG4iCisgICAgICAiJGNsYXNzJC5wcm90b3R5cGUuc2VyaWFsaXplQmluYXJ5ID0gZnVuY3Rpb24oKSB7XG4iCisgICAgICAiICB2YXIgd3JpdGVyID0gbmV3IGpzcGIuQmluYXJ5V3JpdGVyKCk7XG4iCisgICAgICAiICB0aGlzLnNlcmlhbGl6ZUJpbmFyeVRvV3JpdGVyKHdyaXRlcik7XG4iCisgICAgICAiICByZXR1cm4gd3JpdGVyLmdldFJlc3VsdEJ1ZmZlcigpO1xuIgorICAgICAgIn07XG4iCisgICAgICAiXG4iCisgICAgICAiXG4iCisgICAgICAiLyoqXG4iCisgICAgICAiICogU2VyaWFsaXplcyB0aGUgbWVzc2FnZSB0byBiaW5hcnkgZGF0YSAoaW4gcHJvdG9idWYgd2lyZSBmb3JtYXQpLFxuIgorICAgICAgIiAqIHdyaXRpbmcgdG8gdGhlIGdpdmVuIEJpbmFyeVdyaXRlci5cbiIKKyAgICAgICIgKiBAcGFyYW0geyFqc3BiLkJpbmFyeVdyaXRlcn0gd3JpdGVyXG4iCisgICAgICAiICovXG4iCisgICAgICAiJGNsYXNzJC5wcm90b3R5cGUuc2VyaWFsaXplQmluYXJ5VG9Xcml0ZXIgPSBmdW5jdGlvbiAod3JpdGVyKSB7XG4iCisgICAgICAiICB2YXIgZiA9IHVuZGVmaW5lZDtcbiIsCisgICAgICAiY2xhc3MiLCBHZXRQYXRoKG9wdGlvbnMsIGRlc2MpKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2MtPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIEdlbmVyYXRlQ2xhc3NTZXJpYWxpemVCaW5hcnlGaWVsZChvcHRpb25zLCBwcmludGVyLCBkZXNjLT5maWVsZChpKSk7CisgIH0KKworICBpZiAoSXNFeHRlbmRhYmxlKGRlc2MpKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICIgIGpzcGIuTWVzc2FnZS5zZXJpYWxpemVCaW5hcnlFeHRlbnNpb25zKHRoaXMsIHdyaXRlciwgJGV4dG9iaiQsXG4iCisgICAgICAgICIgICAgJGNsYXNzJC5wcm90b3R5cGUuZ2V0RXh0ZW5zaW9uKTtcbiIsCisgICAgICAgICJleHRvYmoiLCBKU0V4dGVuc2lvbnNPYmplY3ROYW1lKG9wdGlvbnMsIGRlc2MpLAorICAgICAgICAiY2xhc3MiLCBHZXRQYXRoKG9wdGlvbnMsIGRlc2MpKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KAorICAgICAgIn07XG4iCisgICAgICAiXG4iCisgICAgICAiXG4iKTsKK30KKwordm9pZCBHZW5lcmF0b3I6OkdlbmVyYXRlQ2xhc3NTZXJpYWxpemVCaW5hcnlGaWVsZCgKKyAgICBjb25zdCBHZW5lcmF0b3JPcHRpb25zJiBvcHRpb25zLAorICAgIGlvOjpQcmludGVyKiBwcmludGVyLAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiICBmID0gdGhpcy5nZXQkbmFtZSQoKTtcbiIsCisgICAgICAibmFtZSIsIEpTR2V0dGVyTmFtZShmaWVsZCkpOworCisgIGlmIChmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiICBpZiAoZi5sZW5ndGggPiAwKSB7XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBpZiAoSGFzRmllbGRQcmVzZW5jZShmaWVsZCkpIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICIgIGlmIChmICE9IG51bGwpIHtcbiIpOworICAgIH0gZWxzZSB7CisgICAgICAvLyBObyBmaWVsZCBwcmVzZW5jZTogc2VyaWFsaXplIG9udG8gdGhlIHdpcmUgb25seSBpZiB2YWx1ZSBpcworICAgICAgLy8gbm9uLWRlZmF1bHQuICBEZWZhdWx0cyBhcmUgZG9jdW1lbnRlZCBoZXJlOgorICAgICAgLy8gaHR0cHM6Ly9nb3RvLmdvb2dsZS5jb20vbGhkZm0KKyAgICAgIHN3aXRjaCAoZmllbGQtPmNwcF90eXBlKCkpIHsKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UMzI6CisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0lOVDY0OgorICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9VSU5UMzI6CisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1VJTlQ2NDogeworICAgICAgICAgIHsKKyAgICAgICAgICAgIHByaW50ZXItPlByaW50KCIgIGlmIChmICE9PSAwKSB7XG4iKTsKKyAgICAgICAgICB9CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKworICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9FTlVNOgorICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9GTE9BVDoKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRE9VQkxFOgorICAgICAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICAgICAiICBpZiAoZiAhPT0gMC4wKSB7XG4iKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfQk9PTDoKKyAgICAgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAgICAgIiAgaWYgKGYpIHtcbiIpOworICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9TVFJJTkc6CisgICAgICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgICAgICIgIGlmIChmLmxlbmd0aCA+IDApIHtcbiIpOworICAgICAgICAgIGJyZWFrOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgIGFzc2VydChmYWxzZSk7CisgICAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiICAgIHdyaXRlci4kd3JpdGVyJChcbiIKKyAgICAgICIgICAgICAkaW5kZXgkLFxuIgorICAgICAgIiAgICAgIGYiLAorICAgICAgIndyaXRlciIsIEpTQmluYXJ5V3JpdGVyTWV0aG9kTmFtZShmaWVsZCksCisgICAgICAibmFtZSIsIEpTR2V0dGVyTmFtZShmaWVsZCksCisgICAgICAiaW5kZXgiLCBTaW1wbGVJdG9hKGZpZWxkLT5udW1iZXIoKSkpOworCisgIGlmIChmaWVsZC0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiLFxuIgorICAgICAgICAiICAgICAgJHN1Ym1zZyQuc2VyaWFsaXplQmluYXJ5VG9Xcml0ZXJcbiIsCisgICAgICAgICJzdWJtc2ciLCBHZXRQYXRoKG9wdGlvbnMsIGZpZWxkLT5tZXNzYWdlX3R5cGUoKSkpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KCJcbiIpOworICB9CisgIHByaW50ZXItPlByaW50KAorICAgICAgIiAgICApO1xuIgorICAgICAgIiAgfVxuIik7Cit9CisKK3ZvaWQgR2VuZXJhdG9yOjpHZW5lcmF0ZUVudW0oY29uc3QgR2VuZXJhdG9yT3B0aW9ucyYgb3B0aW9ucywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBlbnVtZGVzYykgY29uc3QgeworICBwcmludGVyLT5QcmludCgKKyAgICAgICIvKipcbiIKKyAgICAgICIgKiBAZW51bSB7bnVtYmVyfVxuIgorICAgICAgIiAqL1xuIgorICAgICAgIiRuYW1lJCA9IHtcbiIsCisgICAgICAibmFtZSIsIEdldFBhdGgob3B0aW9ucywgZW51bWRlc2MpKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGVudW1kZXNjLT52YWx1ZV9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiB2YWx1ZSA9IGVudW1kZXNjLT52YWx1ZShpKTsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIiAgJG5hbWUkOiAkdmFsdWUkJGNvbW1hJFxuIiwKKyAgICAgICAgIm5hbWUiLCBUb0VudW1DYXNlKHZhbHVlLT5uYW1lKCkpLAorICAgICAgICAidmFsdWUiLCBTaW1wbGVJdG9hKHZhbHVlLT5udW1iZXIoKSksCisgICAgICAgICJjb21tYSIsIChpID09IGVudW1kZXNjLT52YWx1ZV9jb3VudCgpIC0gMSkgPyAiIiA6ICIsIik7CisgIH0KKworICBwcmludGVyLT5QcmludCgKKyAgICAgICJ9O1xuIgorICAgICAgIlxuIik7Cit9CisKK3ZvaWQgR2VuZXJhdG9yOjpHZW5lcmF0ZUV4dGVuc2lvbihjb25zdCBHZW5lcmF0b3JPcHRpb25zJiBvcHRpb25zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0IHsKKyAgc3RyaW5nIGV4dGVuc2lvbl9zY29wZSA9CisgICAgICAoZmllbGQtPmV4dGVuc2lvbl9zY29wZSgpID8KKyAgICAgICBHZXRQYXRoKG9wdGlvbnMsIGZpZWxkLT5leHRlbnNpb25fc2NvcGUoKSkgOgorICAgICAgIEdldFBhdGgob3B0aW9ucywgZmllbGQtPmZpbGUoKSkpOworCisgIHByaW50ZXItPlByaW50KAorICAgICAgIlxuIgorICAgICAgIi8qKlxuIgorICAgICAgIiAqIEEgdHVwbGUgb2Yge2ZpZWxkIG51bWJlciwgY2xhc3MgY29uc3RydWN0b3J9IGZvciB0aGUgZXh0ZW5zaW9uXG4iCisgICAgICAiICogZmllbGQgbmFtZWQgYCRuYW1lJGAuXG4iCisgICAgICAiICogQHR5cGUgeyFqc3BiLkV4dGVuc2lvbkZpZWxkSW5mby48JGV4dGVuc2lvblR5cGUkPn1cbiIKKyAgICAgICIgKi9cbiIKKyAgICAgICIkY2xhc3MkLiRuYW1lJCA9IG5ldyBqc3BiLkV4dGVuc2lvbkZpZWxkSW5mbyhcbiIsCisgICAgICAibmFtZSIsIEpTT2JqZWN0RmllbGROYW1lKGZpZWxkKSwKKyAgICAgICJjbGFzcyIsIGV4dGVuc2lvbl9zY29wZSwKKyAgICAgICJleHRlbnNpb25UeXBlIiwgSlNGaWVsZFR5cGVBbm5vdGF0aW9uKAorICAgICAgICAgIG9wdGlvbnMsIGZpZWxkLAorICAgICAgICAgIC8qIGZvcmNlX29wdGlvbmFsID0gKi8gZmFsc2UsCisgICAgICAgICAgLyogZm9yY2VfcHJlc2VudCA9ICovIHRydWUsCisgICAgICAgICAgLyogc2luZ3VsYXJfaWZfbm90X3BhY2tlZCA9ICovIGZhbHNlLAorICAgICAgICAgIC8qIGFsd2F5c19zaW5ndWxhciA9ICovIGZhbHNlKSk7CisgIHByaW50ZXItPlByaW50KAorICAgICAgIiAgICAkaW5kZXgkLFxuIgorICAgICAgIiAgICB7JG5hbWUkOiAwfSxcbiIKKyAgICAgICIgICAgJGN0b3IkLFxuIgorICAgICAgIiAgICAgLyoqIEB0eXBlIHs/ZnVuY3Rpb24oKGJvb2xlYW58dW5kZWZpbmVkKSwhanNwYi5NZXNzYWdlPSk6ICIKKyAgICAgICIhT2JqZWN0fSAqLyAoXG4iCisgICAgICAiICAgICAgICAgJHRvT2JqZWN0JCksXG4iCisgICAgICAiICAgICRyZXBlYXRlZCQiLAorICAgICAgImluZGV4IiwgU2ltcGxlSXRvYShmaWVsZC0+bnVtYmVyKCkpLAorICAgICAgIm5hbWUiLCBKU09iamVjdEZpZWxkTmFtZShmaWVsZCksCisgICAgICAiY3RvciIsIChmaWVsZC0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSA/CisgICAgICAgICAgICAgICBHZXRQYXRoKG9wdGlvbnMsIGZpZWxkLT5tZXNzYWdlX3R5cGUoKSkgOiBzdHJpbmcoIm51bGwiKSksCisgICAgICAidG9PYmplY3QiLCAoZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UgPworICAgICAgICAgICAgICAgICAgIChHZXRQYXRoKG9wdGlvbnMsIGZpZWxkLT5tZXNzYWdlX3R5cGUoKSkgKyAiLnRvT2JqZWN0IikgOgorICAgICAgICAgICAgICAgICAgIHN0cmluZygibnVsbCIpKSwKKyAgICAgICJyZXBlYXRlZCIsIChmaWVsZC0+aXNfcmVwZWF0ZWQoKSA/ICIxIiA6ICIwIikpOworCisgIGlmIChvcHRpb25zLmJpbmFyeSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiLFxuIgorICAgICAgICAiICAgIGpzcGIuQmluYXJ5UmVhZGVyLnByb3RvdHlwZS4kYmluYXJ5UmVhZGVyRm4kLFxuIgorICAgICAgICAiICAgIGpzcGIuQmluYXJ5V3JpdGVyLnByb3RvdHlwZS4kYmluYXJ5V3JpdGVyRm4kLFxuIgorICAgICAgICAiICAgICRiaW5hcnlNZXNzYWdlU2VyaWFsaXplRm4kLFxuIgorICAgICAgICAiICAgICRiaW5hcnlNZXNzYWdlRGVzZXJpYWxpemVGbiQsXG4iCisgICAgICAgICIgICAgJGlzUGFja2VkJCk7XG4iLAorICAgICAgICAiYmluYXJ5UmVhZGVyRm4iLCBKU0JpbmFyeVJlYWRlck1ldGhvZE5hbWUoZmllbGQpLAorICAgICAgICAiYmluYXJ5V3JpdGVyRm4iLCBKU0JpbmFyeVdyaXRlck1ldGhvZE5hbWUoZmllbGQpLAorICAgICAgICAiYmluYXJ5TWVzc2FnZVNlcmlhbGl6ZUZuIiwKKyAgICAgICAgKGZpZWxkLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFKSA/CisgICAgICAgIChHZXRQYXRoKG9wdGlvbnMsIGZpZWxkLT5tZXNzYWdlX3R5cGUoKSkgKworICAgICAgICAgIi5zZXJpYWxpemVCaW5hcnlUb1dyaXRlciIpIDogIm51bGwiLAorICAgICAgICAiYmluYXJ5TWVzc2FnZURlc2VyaWFsaXplRm4iLAorICAgICAgICAoZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UpID8KKyAgICAgICAgKEdldFBhdGgob3B0aW9ucywgZmllbGQtPm1lc3NhZ2VfdHlwZSgpKSArCisgICAgICAgICAiLmRlc2VyaWFsaXplQmluYXJ5RnJvbVJlYWRlciIpIDogIm51bGwiLAorICAgICAgICAiaXNQYWNrZWQiLCAoZmllbGQtPmlzX3BhY2tlZCgpID8gInRydWUiIDogImZhbHNlIikpOworICB9IGVsc2UgeworICAgIHByaW50ZXItPlByaW50KCIpO1xuIik7CisgIH0KKworICBwcmludGVyLT5QcmludCgKKyAgICAgICIvLyBUaGlzIHJlZ2lzdGVycyB0aGUgZXh0ZW5zaW9uIGZpZWxkIHdpdGggdGhlIGV4dGVuZGVkIGNsYXNzLCBzbyB0aGF0XG4iCisgICAgICAiLy8gdG9PYmplY3QoKSB3aWxsIGZ1bmN0aW9uIGNvcnJlY3RseS5cbiIKKyAgICAgICIkZXh0ZW5kTmFtZSRbJGluZGV4JF0gPSAkY2xhc3MkLiRuYW1lJDtcbiIKKyAgICAgICJcbiIsCisgICAgICAiZXh0ZW5kTmFtZSIsIEpTRXh0ZW5zaW9uc09iamVjdE5hbWUob3B0aW9ucywgZmllbGQtPmNvbnRhaW5pbmdfdHlwZSgpKSwKKyAgICAgICJpbmRleCIsIFNpbXBsZUl0b2EoZmllbGQtPm51bWJlcigpKSwKKyAgICAgICJjbGFzcyIsIGV4dGVuc2lvbl9zY29wZSwKKyAgICAgICJuYW1lIiwgSlNPYmplY3RGaWVsZE5hbWUoZmllbGQpKTsKK30KKworYm9vbCBHZW5lcmF0b3JPcHRpb25zOjpQYXJzZUZyb21PcHRpb25zKAorICAgIGNvbnN0IHZlY3RvcjwgcGFpcjwgc3RyaW5nLCBzdHJpbmcgPiA+JiBvcHRpb25zLAorICAgIHN0cmluZyogZXJyb3IpIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBvcHRpb25zLnNpemUoKTsgaSsrKSB7CisgICAgaWYgKG9wdGlvbnNbaV0uZmlyc3QgPT0gImFkZF9yZXF1aXJlX2Zvcl9lbnVtcyIpIHsKKyAgICAgIGlmIChvcHRpb25zW2ldLnNlY29uZCAhPSAiIikgeworICAgICAgICAqZXJyb3IgPSAiVW5leHBlY3RlZCBvcHRpb24gdmFsdWUgZm9yIGFkZF9yZXF1aXJlX2Zvcl9lbnVtcyI7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICAgIGFkZF9yZXF1aXJlX2Zvcl9lbnVtcyA9IHRydWU7CisgICAgfSBlbHNlIGlmIChvcHRpb25zW2ldLmZpcnN0ID09ICJiaW5hcnkiKSB7CisgICAgICBpZiAob3B0aW9uc1tpXS5zZWNvbmQgIT0gIiIpIHsKKyAgICAgICAgKmVycm9yID0gIlVuZXhwZWN0ZWQgb3B0aW9uIHZhbHVlIGZvciBiaW5hcnkiOworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgICBiaW5hcnkgPSB0cnVlOworICAgIH0gZWxzZSBpZiAob3B0aW9uc1tpXS5maXJzdCA9PSAidGVzdG9ubHkiKSB7CisgICAgICBpZiAob3B0aW9uc1tpXS5zZWNvbmQgIT0gIiIpIHsKKyAgICAgICAgKmVycm9yID0gIlVuZXhwZWN0ZWQgb3B0aW9uIHZhbHVlIGZvciB0ZXN0b25seSI7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICAgIHRlc3Rvbmx5ID0gdHJ1ZTsKKyAgICB9IGVsc2UgaWYgKG9wdGlvbnNbaV0uZmlyc3QgPT0gImVycm9yX29uX25hbWVfY29uZmxpY3QiKSB7CisgICAgICBpZiAob3B0aW9uc1tpXS5zZWNvbmQgIT0gIiIpIHsKKyAgICAgICAgKmVycm9yID0gIlVuZXhwZWN0ZWQgb3B0aW9uIHZhbHVlIGZvciBlcnJvcl9vbl9uYW1lX2NvbmZsaWN0IjsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgICAgZXJyb3Jfb25fbmFtZV9jb25mbGljdCA9IHRydWU7CisgICAgfSBlbHNlIGlmIChvcHRpb25zW2ldLmZpcnN0ID09ICJvdXRwdXRfZGlyIikgeworICAgICAgb3V0cHV0X2RpciA9IG9wdGlvbnNbaV0uc2Vjb25kOworICAgIH0gZWxzZSBpZiAob3B0aW9uc1tpXS5maXJzdCA9PSAibmFtZXNwYWNlX3ByZWZpeCIpIHsKKyAgICAgIG5hbWVzcGFjZV9wcmVmaXggPSBvcHRpb25zW2ldLnNlY29uZDsKKyAgICB9IGVsc2UgaWYgKG9wdGlvbnNbaV0uZmlyc3QgPT0gImxpYnJhcnkiKSB7CisgICAgICBsaWJyYXJ5ID0gb3B0aW9uc1tpXS5zZWNvbmQ7CisgICAgfSBlbHNlIHsKKyAgICAgIC8vIEFzc3VtZSBhbnkgb3RoZXIgb3B0aW9uIGlzIGFuIG91dHB1dCBkaXJlY3RvcnksIGFzIGxvbmcgYXMgaXQgaXMgYSBiYXJlCisgICAgICAvLyBga2V5YCByYXRoZXIgdGhhbiBhIGBrZXk9dmFsdWVgIG9wdGlvbi4KKyAgICAgIGlmIChvcHRpb25zW2ldLnNlY29uZCAhPSAiIikgeworICAgICAgICAqZXJyb3IgPSAiVW5rbm93biBvcHRpb246ICIgKyBvcHRpb25zW2ldLmZpcnN0OworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgICBvdXRwdXRfZGlyID0gb3B0aW9uc1tpXS5maXJzdDsKKyAgICB9CisgIH0KKworICByZXR1cm4gdHJ1ZTsKK30KKwordm9pZCBHZW5lcmF0b3I6OkdlbmVyYXRlRmlsZXNJbkRlcE9yZGVyKAorICAgIGNvbnN0IEdlbmVyYXRvck9wdGlvbnMmIG9wdGlvbnMsCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgY29uc3QgdmVjdG9yPGNvbnN0IEZpbGVEZXNjcmlwdG9yKj4mIGZpbGVzKSBjb25zdCB7CisgIC8vIEJ1aWxkIGEgc3RkOjpzZXQgb3ZlciBhbGwgZmlsZXMgc28gdGhhdCB0aGUgREZTIGNhbiBkZXRlY3Qgd2hlbiBpdCByZWN1cnNlcworICAvLyBpbnRvIGEgZGVwIG5vdCBzcGVjaWZpZWQgaW4gdGhlIHVzZXIncyBjb21tYW5kIGxpbmUuCisgIHN0ZDo6c2V0PGNvbnN0IEZpbGVEZXNjcmlwdG9yKj4gYWxsX2ZpbGVzKGZpbGVzLmJlZ2luKCksIGZpbGVzLmVuZCgpKTsKKyAgLy8gVHJhY2sgdGhlIGluLXByb2dyZXNzIHNldCBvZiBmaWxlcyB0aGF0IGhhdmUgYmVlbiBnZW5lcmF0ZWQgYWxyZWFkeS4KKyAgc3RkOjpzZXQ8Y29uc3QgRmlsZURlc2NyaXB0b3IqPiBnZW5lcmF0ZWQ7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZXMuc2l6ZSgpOyBpKyspIHsKKyAgICBHZW5lcmF0ZUZpbGVBbmREZXBzKG9wdGlvbnMsIHByaW50ZXIsIGZpbGVzW2ldLCAmYWxsX2ZpbGVzLCAmZ2VuZXJhdGVkKTsKKyAgfQorfQorCit2b2lkIEdlbmVyYXRvcjo6R2VuZXJhdGVGaWxlQW5kRGVwcygKKyAgICBjb25zdCBHZW5lcmF0b3JPcHRpb25zJiBvcHRpb25zLAorICAgIGlvOjpQcmludGVyKiBwcmludGVyLAorICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiByb290LAorICAgIHN0ZDo6c2V0PGNvbnN0IEZpbGVEZXNjcmlwdG9yKj4qIGFsbF9maWxlcywKKyAgICBzdGQ6OnNldDxjb25zdCBGaWxlRGVzY3JpcHRvcio+KiBnZW5lcmF0ZWQpIGNvbnN0IHsKKyAgLy8gU2tpcCBpZiBhbHJlYWR5IGdlbmVyYXRlZC4KKyAgaWYgKGdlbmVyYXRlZC0+ZmluZChyb290KSAhPSBnZW5lcmF0ZWQtPmVuZCgpKSB7CisgICAgcmV0dXJuOworICB9CisgIGdlbmVyYXRlZC0+aW5zZXJ0KHJvb3QpOworCisgIC8vIEdlbmVyYXRlIGFsbCBkZXBlbmRlbmNpZXMgYmVmb3JlIHRoaXMgZmlsZSdzIGNvbnRlbnQuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgcm9vdC0+ZGVwZW5kZW5jeV9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBGaWxlRGVzY3JpcHRvciogZGVwID0gcm9vdC0+ZGVwZW5kZW5jeShpKTsKKyAgICBHZW5lcmF0ZUZpbGVBbmREZXBzKG9wdGlvbnMsIHByaW50ZXIsIGRlcCwgYWxsX2ZpbGVzLCBnZW5lcmF0ZWQpOworICB9CisKKyAgLy8gR2VuZXJhdGUgdGhpcyBmaWxlJ3MgY29udGVudC4gIE9ubHkgZ2VuZXJhdGUgaWYgdGhlIGZpbGUgaXMgcGFydCBvZiB0aGUKKyAgLy8gb3JpZ2luYWwgc2V0IHJlcXVlc3RlZCB0byBiZSBnZW5lcmF0ZWQ7IGkuZS4sIGRvbid0IHRha2UgYWxsIHRyYW5zaXRpdmUKKyAgLy8gZGVwcyBkb3duIHRvIHRoZSByb290cy4KKyAgaWYgKGFsbF9maWxlcy0+ZmluZChyb290KSAhPSBhbGxfZmlsZXMtPmVuZCgpKSB7CisgICAgR2VuZXJhdGVDbGFzc2VzQW5kRW51bXMob3B0aW9ucywgcHJpbnRlciwgcm9vdCk7CisgIH0KK30KKworYm9vbCBHZW5lcmF0b3I6OkdlbmVyYXRlQWxsKGNvbnN0IHZlY3Rvcjxjb25zdCBGaWxlRGVzY3JpcHRvcio+JiBmaWxlcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHBhcmFtZXRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZW5lcmF0b3JDb250ZXh0KiBjb250ZXh0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyogZXJyb3IpIGNvbnN0IHsKKyAgdmVjdG9yPCBwYWlyPCBzdHJpbmcsIHN0cmluZyA+ID4gb3B0aW9uX3BhaXJzOworICBQYXJzZUdlbmVyYXRvclBhcmFtZXRlcihwYXJhbWV0ZXIsICZvcHRpb25fcGFpcnMpOworICBHZW5lcmF0b3JPcHRpb25zIG9wdGlvbnM7CisgIGlmICghb3B0aW9ucy5QYXJzZUZyb21PcHRpb25zKG9wdGlvbl9wYWlycywgZXJyb3IpKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKworICAvLyBXZSdyZSBlaXRoZXIgZ2VuZXJhdGluZyBhIHNpbmdsZSBsaWJyYXJ5IGZpbGUgd2l0aCBkZWZpbml0aW9ucyBmb3IgbWVzc2FnZQorICAvLyBhbmQgZW51bSB0eXBlcyBpbiAqYWxsKiBGaWxlRGVzY3JpcHRvciBpbnB1dHMsIG9yIHdlJ3JlIGdlbmVyYXRpbmcgYSBzaW5nbGUKKyAgLy8gZmlsZSBmb3IgZWFjaCB0eXBlLgorICBpZiAob3B0aW9ucy5saWJyYXJ5ICE9ICIiKSB7CisgICAgc3RyaW5nIGZpbGVuYW1lID0gb3B0aW9ucy5vdXRwdXRfZGlyICsgIi8iICsgb3B0aW9ucy5saWJyYXJ5ICsgIi5qcyI7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0+IG91dHB1dChjb250ZXh0LT5PcGVuKGZpbGVuYW1lKSk7CisgICAgR09PR0xFX0NIRUNLKG91dHB1dC5nZXQoKSk7CisgICAgaW86OlByaW50ZXIgcHJpbnRlcihvdXRwdXQuZ2V0KCksICckJyk7CisKKyAgICAvLyBQdWxsIG91dCBhbGwgZXh0ZW5zaW9ucyAtLSB3ZSBuZWVkIHRoZXNlIHRvIGdlbmVyYXRlIGFsbAorICAgIC8vIHByb3ZpZGVzL3JlcXVpcmVzLgorICAgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBleHRlbnNpb25zOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZXMuc2l6ZSgpOyBpKyspIHsKKyAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgZmlsZXNbaV0tPmV4dGVuc2lvbl9jb3VudCgpOyBqKyspIHsKKyAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBleHRlbnNpb24gPSBmaWxlc1tpXS0+ZXh0ZW5zaW9uKGopOworICAgICAgICBleHRlbnNpb25zLnB1c2hfYmFjayhleHRlbnNpb24pOworICAgICAgfQorICAgIH0KKworICAgIEdlbmVyYXRlSGVhZGVyKG9wdGlvbnMsICZwcmludGVyKTsKKworICAgIHN0ZDo6c2V0PHN0cmluZz4gcHJvdmlkZWQ7CisgICAgRmluZFByb3ZpZGVzKG9wdGlvbnMsICZwcmludGVyLCBmaWxlcywgJnByb3ZpZGVkKTsKKyAgICBGaW5kUHJvdmlkZXNGb3JGaWVsZHMob3B0aW9ucywgJnByaW50ZXIsIGV4dGVuc2lvbnMsICZwcm92aWRlZCk7CisgICAgR2VuZXJhdGVQcm92aWRlcyhvcHRpb25zLCAmcHJpbnRlciwgJnByb3ZpZGVkKTsKKyAgICBHZW5lcmF0ZVRlc3RPbmx5KG9wdGlvbnMsICZwcmludGVyKTsKKyAgICBHZW5lcmF0ZVJlcXVpcmVzKG9wdGlvbnMsICZwcmludGVyLCBmaWxlcywgJnByb3ZpZGVkKTsKKworICAgIEdlbmVyYXRlRmlsZXNJbkRlcE9yZGVyKG9wdGlvbnMsICZwcmludGVyLCBmaWxlcyk7CisKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGV4dGVuc2lvbnMuc2l6ZSgpOyBpKyspIHsKKyAgICAgIGlmIChTaG91bGRHZW5lcmF0ZUV4dGVuc2lvbihleHRlbnNpb25zW2ldKSkgeworICAgICAgICBHZW5lcmF0ZUV4dGVuc2lvbihvcHRpb25zLCAmcHJpbnRlciwgZXh0ZW5zaW9uc1tpXSk7CisgICAgICB9CisgICAgfQorCisgICAgaWYgKHByaW50ZXIuZmFpbGVkKCkpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgLy8gQ29sbGVjdCBhbGwgdHlwZXMsIGFuZCBwcmludCBlYWNoIHR5cGUgdG8gYSBzZXBhcmF0ZSBmaWxlLiBQdWxsIG91dAorICAgIC8vIGZyZWUtZmxvYXRpbmcgZXh0ZW5zaW9ucyB3aGlsZSB3ZSBtYWtlIHRoaXMgcGFzcy4KKyAgICBtYXA8IHN0cmluZywgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+ID4gZXh0ZW5zaW9uc19ieV9uYW1lc3BhY2U7CisKKyAgICAvLyBJZiB3ZSdyZSBnZW5lcmF0aW5nIGNvZGUgaW4gZmlsZS1wZXItdHlwZSBtb2RlLCBhdm9pZCBvdmVyd3JpdGluZyBmaWxlcworICAgIC8vIGJ5IGNob29zaW5nIHRoZSBsYXN0IGRlc2NyaXB0b3IgdGhhdCB3cml0ZXMgZWFjaCBmaWxlbmFtZSBhbmQgcGVybWl0dGluZworICAgIC8vIG9ubHkgdGhvc2UgdG8gZ2VuZXJhdGUgY29kZS4KKworICAgIC8vIEN1cnJlbnQgZGVzY3JpcHRvciB0aGF0IHdpbGwgZ2VuZXJhdGUgZWFjaCBmaWxlbmFtZSwgaW5kZXhlZCBieSBmaWxlbmFtZS4KKyAgICBtYXA8c3RyaW5nLCBjb25zdCB2b2lkKj4gZGVzY19ieV9maWxlbmFtZTsKKyAgICAvLyBTZXQgb2YgZGVzY3JpcHRvcnMgYWxsb3dlZCB0byBnZW5lcmF0ZSBmaWxlcy4KKyAgICBzZXQ8Y29uc3Qgdm9pZCo+IGFsbG93ZWRfZGVzY3M7CisKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVzLnNpemUoKTsgaSsrKSB7CisgICAgICAvLyBDb2xsZWN0IGFsbCAoZGVzY3JpcHRvciwgZmlsZW5hbWUpIHBhaXJzLgorICAgICAgbWFwPGNvbnN0IHZvaWQqLCBzdHJpbmc+IGRlc2NzX2luX2ZpbGU7CisgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGZpbGVzW2ldLT5tZXNzYWdlX3R5cGVfY291bnQoKTsgaisrKSB7CisgICAgICAgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2MgPSBmaWxlc1tpXS0+bWVzc2FnZV90eXBlKGopOworICAgICAgICBzdHJpbmcgZmlsZW5hbWUgPQorICAgICAgICAgICAgb3B0aW9ucy5vdXRwdXRfZGlyICsgIi8iICsgVG9GaWxlTmFtZShkZXNjLT5uYW1lKCkpICsgIi5qcyI7CisgICAgICAgIGRlc2NzX2luX2ZpbGVbZGVzY10gPSBmaWxlbmFtZTsKKyAgICAgIH0KKyAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgZmlsZXNbaV0tPmVudW1fdHlwZV9jb3VudCgpOyBqKyspIHsKKyAgICAgICAgY29uc3QgRW51bURlc2NyaXB0b3IqIGRlc2MgPSBmaWxlc1tpXS0+ZW51bV90eXBlKGopOworICAgICAgICBzdHJpbmcgZmlsZW5hbWUgPQorICAgICAgICAgICAgb3B0aW9ucy5vdXRwdXRfZGlyICsgIi8iICsgVG9GaWxlTmFtZShkZXNjLT5uYW1lKCkpICsgIi5qcyI7CisgICAgICAgIGRlc2NzX2luX2ZpbGVbZGVzY10gPSBmaWxlbmFtZTsKKyAgICAgIH0KKworICAgICAgLy8gRm9yIGVhY2ggKGRlc2NyaXB0b3IsIGZpbGVuYW1lKSBwYWlyLCB1cGRhdGUgdGhlCisgICAgICAvLyBkZXNjcmlwdG9ycy1ieS1maWxlbmFtZSBtYXAsIGFuZCBpZiBhIHByZXZpb3VzIGRlc2NyaXB0b3Igd2FzIGFscmVhZHkKKyAgICAgIC8vIHdyaXRpbmcgdGhlIGZpbGVuYW1lLCByZW1vdmUgaXQgZnJvbSB0aGUgYWxsb3dlZC1kZXNjcmlwdG9ycyBzZXQuCisgICAgICBtYXA8Y29uc3Qgdm9pZCosIHN0cmluZz46Oml0ZXJhdG9yIGl0OworICAgICAgZm9yIChpdCA9IGRlc2NzX2luX2ZpbGUuYmVnaW4oKTsgaXQgIT0gZGVzY3NfaW5fZmlsZS5lbmQoKTsgKytpdCkgeworICAgICAgICBjb25zdCB2b2lkKiBkZXNjID0gaXQtPmZpcnN0OworICAgICAgICBjb25zdCBzdHJpbmcmIGZpbGVuYW1lID0gaXQtPnNlY29uZDsKKyAgICAgICAgaWYgKGRlc2NfYnlfZmlsZW5hbWUuZmluZChmaWxlbmFtZSkgIT0gZGVzY19ieV9maWxlbmFtZS5lbmQoKSkgeworICAgICAgICAgIGlmIChvcHRpb25zLmVycm9yX29uX25hbWVfY29uZmxpY3QpIHsKKyAgICAgICAgICAgICplcnJvciA9ICJOYW1lIGNvbmZsaWN0OiBmaWxlIG5hbWUgIiArIGZpbGVuYW1lICsKKyAgICAgICAgICAgICAgICAgICAgICIgd291bGQgYmUgZ2VuZXJhdGVkIGJ5IHR3byBkZXNjcmlwdG9ycyI7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgfQorICAgICAgICAgIGFsbG93ZWRfZGVzY3MuZXJhc2UoZGVzY19ieV9maWxlbmFtZVtmaWxlbmFtZV0pOworICAgICAgICB9CisgICAgICAgIGRlc2NfYnlfZmlsZW5hbWVbZmlsZW5hbWVdID0gZGVzYzsKKyAgICAgICAgYWxsb3dlZF9kZXNjcy5pbnNlcnQoZGVzYyk7CisgICAgICB9CisgICAgfQorCisgICAgLy8gR2VuZXJhdGUgY29kZS4KKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVzLnNpemUoKTsgaSsrKSB7CisgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSA9IGZpbGVzW2ldOworICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBmaWxlLT5tZXNzYWdlX3R5cGVfY291bnQoKTsgaisrKSB7CisgICAgICAgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2MgPSBmaWxlLT5tZXNzYWdlX3R5cGUoaik7CisgICAgICAgIGlmIChhbGxvd2VkX2Rlc2NzLmZpbmQoZGVzYykgPT0gYWxsb3dlZF9kZXNjcy5lbmQoKSkgeworICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisKKyAgICAgICAgc3RyaW5nIGZpbGVuYW1lID0gb3B0aW9ucy5vdXRwdXRfZGlyICsgIi8iICsKKyAgICAgICAgICAgIFRvRmlsZU5hbWUoZGVzYy0+bmFtZSgpKSArICIuanMiOworICAgICAgICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPGlvOjpaZXJvQ29weU91dHB1dFN0cmVhbT4gb3V0cHV0KAorICAgICAgICAgICAgY29udGV4dC0+T3BlbihmaWxlbmFtZSkpOworICAgICAgICBHT09HTEVfQ0hFQ0sob3V0cHV0LmdldCgpKTsKKyAgICAgICAgaW86OlByaW50ZXIgcHJpbnRlcihvdXRwdXQuZ2V0KCksICckJyk7CisKKyAgICAgICAgR2VuZXJhdGVIZWFkZXIob3B0aW9ucywgJnByaW50ZXIpOworCisgICAgICAgIHN0ZDo6c2V0PHN0cmluZz4gcHJvdmlkZWQ7CisgICAgICAgIEZpbmRQcm92aWRlc0Zvck1lc3NhZ2Uob3B0aW9ucywgJnByaW50ZXIsIGRlc2MsICZwcm92aWRlZCk7CisgICAgICAgIEdlbmVyYXRlUHJvdmlkZXMob3B0aW9ucywgJnByaW50ZXIsICZwcm92aWRlZCk7CisgICAgICAgIEdlbmVyYXRlVGVzdE9ubHkob3B0aW9ucywgJnByaW50ZXIpOworICAgICAgICBHZW5lcmF0ZVJlcXVpcmVzKG9wdGlvbnMsICZwcmludGVyLCBkZXNjLCAmcHJvdmlkZWQpOworCisgICAgICAgIEdlbmVyYXRlQ2xhc3Mob3B0aW9ucywgJnByaW50ZXIsIGRlc2MpOworCisgICAgICAgIGlmIChwcmludGVyLmZhaWxlZCgpKSB7CisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICB9CisgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGZpbGUtPmVudW1fdHlwZV9jb3VudCgpOyBqKyspIHsKKyAgICAgICAgY29uc3QgRW51bURlc2NyaXB0b3IqIGVudW1kZXNjID0gZmlsZS0+ZW51bV90eXBlKGopOworICAgICAgICBpZiAoYWxsb3dlZF9kZXNjcy5maW5kKGVudW1kZXNjKSA9PSBhbGxvd2VkX2Rlc2NzLmVuZCgpKSB7CisgICAgICAgICAgY29udGludWU7CisgICAgICAgIH0KKworICAgICAgICBzdHJpbmcgZmlsZW5hbWUgPSBvcHRpb25zLm91dHB1dF9kaXIgKyAiLyIgKworICAgICAgICAgICAgVG9GaWxlTmFtZShlbnVtZGVzYy0+bmFtZSgpKSArICIuanMiOworCisgICAgICAgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8aW86Olplcm9Db3B5T3V0cHV0U3RyZWFtPiBvdXRwdXQoCisgICAgICAgICAgICBjb250ZXh0LT5PcGVuKGZpbGVuYW1lKSk7CisgICAgICAgIEdPT0dMRV9DSEVDSyhvdXRwdXQuZ2V0KCkpOworICAgICAgICBpbzo6UHJpbnRlciBwcmludGVyKG91dHB1dC5nZXQoKSwgJyQnKTsKKworICAgICAgICBHZW5lcmF0ZUhlYWRlcihvcHRpb25zLCAmcHJpbnRlcik7CisKKyAgICAgICAgc3RkOjpzZXQ8c3RyaW5nPiBwcm92aWRlZDsKKyAgICAgICAgRmluZFByb3ZpZGVzRm9yRW51bShvcHRpb25zLCAmcHJpbnRlciwgZW51bWRlc2MsICZwcm92aWRlZCk7CisgICAgICAgIEdlbmVyYXRlUHJvdmlkZXMob3B0aW9ucywgJnByaW50ZXIsICZwcm92aWRlZCk7CisgICAgICAgIEdlbmVyYXRlVGVzdE9ubHkob3B0aW9ucywgJnByaW50ZXIpOworCisgICAgICAgIEdlbmVyYXRlRW51bShvcHRpb25zLCAmcHJpbnRlciwgZW51bWRlc2MpOworCisgICAgICAgIGlmIChwcmludGVyLmZhaWxlZCgpKSB7CisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICB9CisgICAgICAvLyBQdWxsIG91dCBhbGwgZnJlZS1mbG9hdGluZyBleHRlbnNpb25zIGFuZCBnZW5lcmF0ZSBmaWxlcyBmb3IgdGhvc2UgdG9vLgorICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBmaWxlLT5leHRlbnNpb25fY291bnQoKTsgaisrKSB7CisgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZXh0ZW5zaW9uID0gZmlsZS0+ZXh0ZW5zaW9uKGopOworICAgICAgICBleHRlbnNpb25zX2J5X25hbWVzcGFjZVtHZXRQYXRoKG9wdGlvbnMsIGZpbGVzW2ldKV0KKyAgICAgICAgICAgIC5wdXNoX2JhY2soZXh0ZW5zaW9uKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvLyBHZW5lcmF0ZSBleHRlbnNpb25zIGluIHNlcGFyYXRlIGZpbGVzLgorICAgIG1hcDwgc3RyaW5nLCB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4gPjo6aXRlcmF0b3IgaXQ7CisgICAgZm9yIChpdCA9IGV4dGVuc2lvbnNfYnlfbmFtZXNwYWNlLmJlZ2luKCk7CisgICAgICAgICBpdCAhPSBleHRlbnNpb25zX2J5X25hbWVzcGFjZS5lbmQoKTsKKyAgICAgICAgICsraXQpIHsKKyAgICAgIHN0cmluZyBmaWxlbmFtZSA9IG9wdGlvbnMub3V0cHV0X2RpciArICIvIiArCisgICAgICAgICAgVG9GaWxlTmFtZShpdC0+Zmlyc3QpICsgIi5qcyI7CisKKyAgICAgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8aW86Olplcm9Db3B5T3V0cHV0U3RyZWFtPiBvdXRwdXQoCisgICAgICAgICAgY29udGV4dC0+T3BlbihmaWxlbmFtZSkpOworICAgICAgR09PR0xFX0NIRUNLKG91dHB1dC5nZXQoKSk7CisgICAgICBpbzo6UHJpbnRlciBwcmludGVyKG91dHB1dC5nZXQoKSwgJyQnKTsKKworICAgICAgR2VuZXJhdGVIZWFkZXIob3B0aW9ucywgJnByaW50ZXIpOworCisgICAgICBzdGQ6OnNldDxzdHJpbmc+IHByb3ZpZGVkOworICAgICAgRmluZFByb3ZpZGVzRm9yRmllbGRzKG9wdGlvbnMsICZwcmludGVyLCBpdC0+c2Vjb25kLCAmcHJvdmlkZWQpOworICAgICAgR2VuZXJhdGVQcm92aWRlcyhvcHRpb25zLCAmcHJpbnRlciwgJnByb3ZpZGVkKTsKKyAgICAgIEdlbmVyYXRlVGVzdE9ubHkob3B0aW9ucywgJnByaW50ZXIpOworICAgICAgR2VuZXJhdGVSZXF1aXJlcyhvcHRpb25zLCAmcHJpbnRlciwgaXQtPnNlY29uZCwgJnByb3ZpZGVkKTsKKworICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBpdC0+c2Vjb25kLnNpemUoKTsgaisrKSB7CisgICAgICAgIGlmIChTaG91bGRHZW5lcmF0ZUV4dGVuc2lvbihpdC0+c2Vjb25kW2pdKSkgeworICAgICAgICAgIEdlbmVyYXRlRXh0ZW5zaW9uKG9wdGlvbnMsICZwcmludGVyLCBpdC0+c2Vjb25kW2pdKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgfQorCisgIHJldHVybiB0cnVlOworfQorCit9ICAvLyBuYW1lc3BhY2UganMKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2pzL2pzX2dlbmVyYXRvci5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qcy9qc19nZW5lcmF0b3IuaApuZXcgZmlsZSBtb2RlIDEwMDc1NQppbmRleCAwMDAwMDAwLi5kYjJkY2ViCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qcy9qc19nZW5lcmF0b3IuaApAQCAtMCwwICsxLDI2NSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pTX0dFTkVSQVRPUl9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX0pTX0dFTkVSQVRPUl9IX18KKworI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxzZXQ+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY29kZV9nZW5lcmF0b3IuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCitjbGFzcyBEZXNjcmlwdG9yOworY2xhc3MgRW51bURlc2NyaXB0b3I7CitjbGFzcyBGaWVsZERlc2NyaXB0b3I7CitjbGFzcyBPbmVvZkRlc2NyaXB0b3I7CitjbGFzcyBGaWxlRGVzY3JpcHRvcjsKKworbmFtZXNwYWNlIGlvIHsgY2xhc3MgUHJpbnRlcjsgfQorCituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIGpzIHsKKworc3RydWN0IEdlbmVyYXRvck9wdGlvbnMgeworICAvLyBBZGQgYSBgZ29vZy5yZXF1aXJlcygpYCBjYWxsIGZvciBlYWNoIGVudW0gdHlwZSB1c2VkLiBJZiBub3Qgc2V0LCBhIGZvcndhcmQKKyAgLy8gZGVjbGFyYXRpb24gd2l0aCBgZ29vZy5mb3J3YXJkRGVjbGFyZWAgaXMgcHJvZHVjZWQgaW5zdGVhZC4KKyAgYm9vbCBhZGRfcmVxdWlyZV9mb3JfZW51bXM7CisgIC8vIFNldCB0aGlzIGFzIGEgdGVzdC1vbmx5IG1vZHVsZSB2aWEgYGdvb2cuc2V0VGVzdE9ubHkoKTtgLgorICBib29sIHRlc3Rvbmx5OworICAvLyBPdXRwdXQgcGF0aC4KKyAgc3RyaW5nIG91dHB1dF9kaXI7CisgIC8vIE5hbWVzcGFjZSBwcmVmaXguCisgIHN0cmluZyBuYW1lc3BhY2VfcHJlZml4OworICAvLyBDcmVhdGUgYSBsaWJyYXJ5IHdpdGggbmFtZSA8bmFtZT5fbGliLmpzIHJhdGhlciB0aGFuIGEgc2VwYXJhdGUgLmpzIGZpbGUKKyAgLy8gcGVyIHR5cGU/CisgIHN0cmluZyBsaWJyYXJ5OworICAvLyBFcnJvciBpZiB0aGVyZSBhcmUgdHdvIHR5cGVzIHRoYXQgd291bGQgZ2VuZXJhdGUgdGhlIHNhbWUgb3V0cHV0IGZpbGU/CisgIGJvb2wgZXJyb3Jfb25fbmFtZV9jb25mbGljdDsKKyAgLy8gRW5hYmxlIGJpbmFyeS1mb3JtYXQgc3VwcG9ydD8KKyAgYm9vbCBiaW5hcnk7CisKKyAgR2VuZXJhdG9yT3B0aW9ucygpCisgICAgICA6IGFkZF9yZXF1aXJlX2Zvcl9lbnVtcyhmYWxzZSksCisgICAgICAgIHRlc3Rvbmx5KGZhbHNlKSwKKyAgICAgICAgb3V0cHV0X2RpcigiLiIpLAorICAgICAgICBuYW1lc3BhY2VfcHJlZml4KCIiKSwKKyAgICAgICAgbGlicmFyeSgiIiksCisgICAgICAgIGVycm9yX29uX25hbWVfY29uZmxpY3QoZmFsc2UpLAorICAgICAgICBiaW5hcnkoZmFsc2UpIHt9CisKKyAgYm9vbCBQYXJzZUZyb21PcHRpb25zKAorICAgICAgY29uc3QgdmVjdG9yPCBwYWlyPCBzdHJpbmcsIHN0cmluZyA+ID4mIG9wdGlvbnMsCisgICAgICBzdHJpbmcqIGVycm9yKTsKK307CisKK2NsYXNzIExJQlBST1RPQ19FWFBPUlQgR2VuZXJhdG9yIDogcHVibGljIENvZGVHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgR2VuZXJhdG9yKCkge30KKyAgdmlydHVhbCB+R2VuZXJhdG9yKCkge30KKworICB2aXJ0dWFsIGJvb2wgR2VuZXJhdGUoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHBhcmFtZXRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgIEdlbmVyYXRvckNvbnRleHQqIGNvbnRleHQsCisgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcqIGVycm9yKSBjb25zdCB7CisgICAgKmVycm9yID0gIlVuaW1wbGVtZW50ZWQgR2VuZXJhdGUoKSBtZXRob2QuIENhbGwgR2VuZXJhdGVBbGwoKSBpbnN0ZWFkLiI7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgdmlydHVhbCBib29sIEhhc0dlbmVyYXRlQWxsKCkgY29uc3QgeyByZXR1cm4gdHJ1ZTsgfQorCisgIHZpcnR1YWwgYm9vbCBHZW5lcmF0ZUFsbChjb25zdCB2ZWN0b3I8Y29uc3QgRmlsZURlc2NyaXB0b3IqPiYgZmlsZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHBhcmFtZXRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIEdlbmVyYXRvckNvbnRleHQqIGNvbnRleHQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcqIGVycm9yKSBjb25zdDsKKworIHByaXZhdGU6CisgIHZvaWQgR2VuZXJhdGVIZWFkZXIoY29uc3QgR2VuZXJhdG9yT3B0aW9ucyYgb3B0aW9ucywKKyAgICAgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyAgLy8gR2VuZXJhdGUgZ29vZy5wcm92aWRlcygpIGNhbGxzLgorICB2b2lkIEZpbmRQcm92aWRlcyhjb25zdCBHZW5lcmF0b3JPcHRpb25zJiBvcHRpb25zLAorICAgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgY29uc3QgdmVjdG9yPGNvbnN0IEZpbGVEZXNjcmlwdG9yKj4mIGZpbGUsCisgICAgICAgICAgICAgICAgICAgIHN0ZDo6c2V0PHN0cmluZz4qIHByb3ZpZGVkKSBjb25zdDsKKyAgdm9pZCBGaW5kUHJvdmlkZXNGb3JNZXNzYWdlKGNvbnN0IEdlbmVyYXRvck9wdGlvbnMmIG9wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OnNldDxzdHJpbmc+KiBwcm92aWRlZCkgY29uc3Q7CisgIHZvaWQgRmluZFByb3ZpZGVzRm9yRW51bShjb25zdCBHZW5lcmF0b3JPcHRpb25zJiBvcHRpb25zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBFbnVtRGVzY3JpcHRvciogZW51bWRlc2MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OnNldDxzdHJpbmc+KiBwcm92aWRlZCkgY29uc3Q7CisgIC8vIEZvciBleHRlbnNpb24gZmllbGRzIGF0IGZpbGUgc2NvcGUuCisgIHZvaWQgRmluZFByb3ZpZGVzRm9yRmllbGRzKGNvbnN0IEdlbmVyYXRvck9wdGlvbnMmIG9wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4mIGZpZWxkcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjpzZXQ8c3RyaW5nPiogcHJvdmlkZWQpIGNvbnN0OworICAvLyBQcmludCB0aGUgZ29vZy5wcm92aWRlcygpIGZvdW5kIGJ5IHRoZSBtZXRob2RzIGFib3ZlLgorICB2b2lkIEdlbmVyYXRlUHJvdmlkZXMoY29uc3QgR2VuZXJhdG9yT3B0aW9ucyYgb3B0aW9ucywKKyAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjpzZXQ8c3RyaW5nPiogcHJvdmlkZWQpIGNvbnN0OworCisgIC8vIEdlbmVyYXRlIGdvb2cuc2V0VGVzdE9ubHkoKSBpZiBpbmRpY2F0ZWQuCisgIHZvaWQgR2VuZXJhdGVUZXN0T25seShjb25zdCBHZW5lcmF0b3JPcHRpb25zJiBvcHRpb25zLAorICAgICAgICAgICAgICAgICAgICAgICAgaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgIC8vIEdlbmVyYXRlIGdvb2cucmVxdWlyZXMoKSBjYWxscy4KKyAgdm9pZCBHZW5lcmF0ZVJlcXVpcmVzKGNvbnN0IEdlbmVyYXRvck9wdGlvbnMmIG9wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZlY3Rvcjxjb25zdCBGaWxlRGVzY3JpcHRvcio+JiBmaWxlLAorICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjpzZXQ8c3RyaW5nPiogcHJvdmlkZWQpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlUmVxdWlyZXMoY29uc3QgR2VuZXJhdG9yT3B0aW9ucyYgb3B0aW9ucywKKyAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVzY3JpcHRvciogZGVzYywKKyAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6c2V0PHN0cmluZz4qIHByb3ZpZGVkKSBjb25zdDsKKyAgLy8gRm9yIGV4dGVuc2lvbiBmaWVsZHMgYXQgZmlsZSBzY29wZS4KKyAgdm9pZCBHZW5lcmF0ZVJlcXVpcmVzKGNvbnN0IEdlbmVyYXRvck9wdGlvbnMmIG9wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiYgZmllbGRzLAorICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjpzZXQ8c3RyaW5nPiogcHJvdmlkZWQpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlUmVxdWlyZXNJbXBsKGNvbnN0IEdlbmVyYXRvck9wdGlvbnMmIG9wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjpzZXQ8c3RyaW5nPiogcmVxdWlyZWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjpzZXQ8c3RyaW5nPiogZm9yd2FyZHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjpzZXQ8c3RyaW5nPiogcHJvdmlkZWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCByZXF1aXJlX2pzcGIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCByZXF1aXJlX2V4dGVuc2lvbikgY29uc3Q7CisgIHZvaWQgRmluZFJlcXVpcmVzRm9yTWVzc2FnZShjb25zdCBHZW5lcmF0b3JPcHRpb25zJiBvcHRpb25zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVzY3JpcHRvciogZGVzYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6c2V0PHN0cmluZz4qIHJlcXVpcmVkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjpzZXQ8c3RyaW5nPiogZm9yd2FyZHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sKiBoYXZlX21lc3NhZ2UpIGNvbnN0OworICB2b2lkIEZpbmRSZXF1aXJlc0ZvckZpZWxkKGNvbnN0IEdlbmVyYXRvck9wdGlvbnMmIG9wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OnNldDxzdHJpbmc+KiByZXF1aXJlZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OnNldDxzdHJpbmc+KiBmb3J3YXJkcykgY29uc3Q7CisgIHZvaWQgRmluZFJlcXVpcmVzRm9yRXh0ZW5zaW9uKGNvbnN0IEdlbmVyYXRvck9wdGlvbnMmIG9wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6c2V0PHN0cmluZz4qIHJlcXVpcmVkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OnNldDxzdHJpbmc+KiBmb3J3YXJkcykgY29uc3Q7CisKKyAgLy8gR2VuZXJhdGUgZGVmaW5pdGlvbnMgZm9yIGFsbCBtZXNzYWdlIGNsYXNzZXMgYW5kIGVudW1zIGluIGFsbCBmaWxlcywKKyAgLy8gcHJvY2Vzc2luZyB0aGUgZmlsZXMgaW4gZGVwZW5kZW5jZSBvcmRlci4KKyAgdm9pZCBHZW5lcmF0ZUZpbGVzSW5EZXBPcmRlcihjb25zdCBHZW5lcmF0b3JPcHRpb25zJiBvcHRpb25zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZlY3Rvcjxjb25zdCBGaWxlRGVzY3JpcHRvcio+JiBmaWxlKSBjb25zdDsKKyAgLy8gSGVscGVyIGZvciBhYm92ZS4KKyAgdm9pZCBHZW5lcmF0ZUZpbGVBbmREZXBzKGNvbnN0IEdlbmVyYXRvck9wdGlvbnMmIG9wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiByb290LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjpzZXQ8Y29uc3QgRmlsZURlc2NyaXB0b3IqPiogYWxsX2ZpbGVzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjpzZXQ8Y29uc3QgRmlsZURlc2NyaXB0b3IqPiogZ2VuZXJhdGVkKSBjb25zdDsKKworICAvLyBHZW5lcmF0ZSBkZWZpbml0aW9ucyBmb3IgYWxsIG1lc3NhZ2UgY2xhc3NlcyBhbmQgZW51bXMuCisgIHZvaWQgR2VuZXJhdGVDbGFzc2VzQW5kRW51bXMoY29uc3QgR2VuZXJhdG9yT3B0aW9ucyYgb3B0aW9ucywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSkgY29uc3Q7CisKKyAgLy8gR2VuZXJhdGUgZGVmaW5pdGlvbiBmb3Igb25lIGNsYXNzLgorICB2b2lkIEdlbmVyYXRlQ2xhc3MoY29uc3QgR2VuZXJhdG9yT3B0aW9ucyYgb3B0aW9ucywKKyAgICAgICAgICAgICAgICAgICAgIGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVzY3JpcHRvciogZGVzYykgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVDbGFzc0NvbnN0cnVjdG9yKGNvbnN0IEdlbmVyYXRvck9wdGlvbnMmIG9wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUNsYXNzRmllbGRJbmZvKGNvbnN0IEdlbmVyYXRvck9wdGlvbnMmIG9wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2MpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQ2xhc3NYaWQoY29uc3QgR2VuZXJhdG9yT3B0aW9ucyYgb3B0aW9ucywKKyAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVzY3JpcHRvciogZGVzYykgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVPbmVvZkNhc2VEZWZpbml0aW9uKGNvbnN0IEdlbmVyYXRvck9wdGlvbnMmIG9wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBPbmVvZkRlc2NyaXB0b3IqIG9uZW9mKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUNsYXNzVG9PYmplY3QoY29uc3QgR2VuZXJhdG9yT3B0aW9ucyYgb3B0aW9ucywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2MpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQ2xhc3NGaWVsZFRvT2JqZWN0KGNvbnN0IEdlbmVyYXRvck9wdGlvbnMmIG9wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVDbGFzc0Zyb21PYmplY3QoY29uc3QgR2VuZXJhdG9yT3B0aW9ucyYgb3B0aW9ucywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUNsYXNzRmllbGRGcm9tT2JqZWN0KGNvbnN0IEdlbmVyYXRvck9wdGlvbnMmIG9wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQ2xhc3NDbG9uZShjb25zdCBHZW5lcmF0b3JPcHRpb25zJiBvcHRpb25zLAorICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVzY3JpcHRvciogZGVzYykgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVDbGFzc1JlZ2lzdHJhdGlvbihjb25zdCBHZW5lcmF0b3JPcHRpb25zJiBvcHRpb25zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUNsYXNzRmllbGRzKGNvbnN0IEdlbmVyYXRvck9wdGlvbnMmIG9wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2MpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQ2xhc3NGaWVsZChjb25zdCBHZW5lcmF0b3JPcHRpb25zJiBvcHRpb25zLAorICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUNsYXNzRXh0ZW5zaW9uRmllbGRJbmZvKGNvbnN0IEdlbmVyYXRvck9wdGlvbnMmIG9wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2MpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQ2xhc3NEZXNlcmlhbGl6ZShjb25zdCBHZW5lcmF0b3JPcHRpb25zJiBvcHRpb25zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVzY3JpcHRvciogZGVzYykgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVDbGFzc0Rlc2VyaWFsaXplQmluYXJ5KGNvbnN0IEdlbmVyYXRvck9wdGlvbnMmIG9wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjKSBjb25zdDsKKyAgdm9pZCBHZW5lcmF0ZUNsYXNzRGVzZXJpYWxpemVCaW5hcnlGaWVsZChjb25zdCBHZW5lcmF0b3JPcHRpb25zJiBvcHRpb25zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0OworICB2b2lkIEdlbmVyYXRlQ2xhc3NTZXJpYWxpemVCaW5hcnkoY29uc3QgR2VuZXJhdG9yT3B0aW9ucyYgb3B0aW9ucywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVzY3JpcHRvciogZGVzYykgY29uc3Q7CisgIHZvaWQgR2VuZXJhdGVDbGFzc1NlcmlhbGl6ZUJpbmFyeUZpZWxkKGNvbnN0IEdlbmVyYXRvck9wdGlvbnMmIG9wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdDsKKworICAvLyBHZW5lcmF0ZSBkZWZpbml0aW9uIGZvciBvbmUgZW51bS4KKyAgdm9pZCBHZW5lcmF0ZUVudW0oY29uc3QgR2VuZXJhdG9yT3B0aW9ucyYgb3B0aW9ucywKKyAgICAgICAgICAgICAgICAgICAgaW86OlByaW50ZXIqIHByaW50ZXIsCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBlbnVtZGVzYykgY29uc3Q7CisKKyAgLy8gR2VuZXJhdGUgYW4gZXh0ZW5zaW9uIGRlZmluaXRpb24uCisgIHZvaWQgR2VuZXJhdGVFeHRlbnNpb24oY29uc3QgR2VuZXJhdG9yT3B0aW9ucyYgb3B0aW9ucywKKyAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdDsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoR2VuZXJhdG9yKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBqcworfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfSlNfR0VORVJBVE9SX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9tYWluLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9tYWluLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk3ZGY1MzYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL21haW4uY2MKQEAgLTAsMCArMSw5MCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jb21tYW5kX2xpbmVfaW50ZXJmYWNlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2NwcC9jcHBfZ2VuZXJhdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3B5dGhvbi9weXRob25fZ2VuZXJhdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL2phdmEvamF2YV9nZW5lcmF0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvamF2YW5hbm8vamF2YW5hbm9fZ2VuZXJhdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3J1YnkvcnVieV9nZW5lcmF0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY3NoYXJwL2NzaGFycF9nZW5lcmF0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX2dlbmVyYXRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9qcy9qc19nZW5lcmF0b3IuaD4KKworaW50IG1haW4oaW50IGFyZ2MsIGNoYXIqIGFyZ3ZbXSkgeworCisgIGdvb2dsZTo6cHJvdG9idWY6OmNvbXBpbGVyOjpDb21tYW5kTGluZUludGVyZmFjZSBjbGk7CisgIGNsaS5BbGxvd1BsdWdpbnMoInByb3RvYy0iKTsKKworICAvLyBQcm90bzIgQysrCisgIGdvb2dsZTo6cHJvdG9idWY6OmNvbXBpbGVyOjpjcHA6OkNwcEdlbmVyYXRvciBjcHBfZ2VuZXJhdG9yOworICBjbGkuUmVnaXN0ZXJHZW5lcmF0b3IoIi0tY3BwX291dCIsICItLWNwcF9vcHQiLCAmY3BwX2dlbmVyYXRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJHZW5lcmF0ZSBDKysgaGVhZGVyIGFuZCBzb3VyY2UuIik7CisKKyAgLy8gUHJvdG8yIEphdmEKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6Y29tcGlsZXI6OmphdmE6OkphdmFHZW5lcmF0b3IgamF2YV9nZW5lcmF0b3I7CisgIGNsaS5SZWdpc3RlckdlbmVyYXRvcigiLS1qYXZhX291dCIsICZqYXZhX2dlbmVyYXRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJHZW5lcmF0ZSBKYXZhIHNvdXJjZSBmaWxlLiIpOworCisKKyAgLy8gUHJvdG8yIFB5dGhvbgorICBnb29nbGU6OnByb3RvYnVmOjpjb21waWxlcjo6cHl0aG9uOjpHZW5lcmF0b3IgcHlfZ2VuZXJhdG9yOworICBjbGkuUmVnaXN0ZXJHZW5lcmF0b3IoIi0tcHl0aG9uX291dCIsICZweV9nZW5lcmF0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAiR2VuZXJhdGUgUHl0aG9uIHNvdXJjZSBmaWxlLiIpOworCisgIC8vIEphdmEgTmFubworICBnb29nbGU6OnByb3RvYnVmOjpjb21waWxlcjo6amF2YW5hbm86OkphdmFOYW5vR2VuZXJhdG9yIGphdmFuYW5vX2dlbmVyYXRvcjsKKyAgY2xpLlJlZ2lzdGVyR2VuZXJhdG9yKCItLWphdmFuYW5vX291dCIsICZqYXZhbmFub19nZW5lcmF0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAiR2VuZXJhdGUgSmF2YSBOYW5vIHNvdXJjZSBmaWxlLiIpOworCisgIC8vIFJ1YnkKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6Y29tcGlsZXI6OnJ1Ynk6OkdlbmVyYXRvciByYl9nZW5lcmF0b3I7CisgIGNsaS5SZWdpc3RlckdlbmVyYXRvcigiLS1ydWJ5X291dCIsICZyYl9nZW5lcmF0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAiR2VuZXJhdGUgUnVieSBzb3VyY2UgZmlsZS4iKTsKKworICAvLyBDU2hhcnAKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6Y29tcGlsZXI6OmNzaGFycDo6R2VuZXJhdG9yIGNzaGFycF9nZW5lcmF0b3I7CisgIGNsaS5SZWdpc3RlckdlbmVyYXRvcigiLS1jc2hhcnBfb3V0IiwgIi0tY3NoYXJwX29wdCIsICZjc2hhcnBfZ2VuZXJhdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgIkdlbmVyYXRlIEMjIHNvdXJjZSBmaWxlLiIpOworCisgIC8vIE9iamVjdGl2ZSBDCisgIGdvb2dsZTo6cHJvdG9idWY6OmNvbXBpbGVyOjpvYmplY3RpdmVjOjpPYmplY3RpdmVDR2VuZXJhdG9yIG9iamNfZ2VuZXJhdG9yOworICBjbGkuUmVnaXN0ZXJHZW5lcmF0b3IoIi0tb2JqY19vdXQiLCAmb2JqY19nZW5lcmF0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAiR2VuZXJhdGUgT2JqZWN0aXZlIEMgaGVhZGVyIGFuZCBzb3VyY2UuIik7CisKKyAgLy8gSmF2YVNjcmlwdAorICBnb29nbGU6OnByb3RvYnVmOjpjb21waWxlcjo6anM6OkdlbmVyYXRvciBqc19nZW5lcmF0b3I7CisgIGNsaS5SZWdpc3RlckdlbmVyYXRvcigiLS1qc19vdXQiLCAmanNfZ2VuZXJhdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgIkdlbmVyYXRlIEphdmFTY3JpcHQgc291cmNlLiIpOworCisgIHJldHVybiBjbGkuUnVuKGFyZ2MsIGFyZ3YpOworfQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9tb2NrX2NvZGVfZ2VuZXJhdG9yLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9tb2NrX2NvZGVfZ2VuZXJhdG9yLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjEyMWQ5MTcKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL21vY2tfY29kZV9nZW5lcmF0b3IuY2MKQEAgLTAsMCArMSwyNDkgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvbW9ja19jb2RlX2dlbmVyYXRvci5oPgorCisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZmlsZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3Vic3RpdHV0ZS5oPgorI2luY2x1ZGUgPGd0ZXN0L2d0ZXN0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0bF91dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CisKKy8vIFJldHVybnMgdGhlIGxpc3Qgb2YgdGhlIG5hbWVzIG9mIGZpbGVzIGluIGFsbF9maWxlcyBpbiB0aGUgZm9ybSBvZiBhCisvLyBjb21tYS1zZXBhcmF0ZWQgc3RyaW5nLgorc3RyaW5nIENvbW1hU2VwYXJhdGVkTGlzdChjb25zdCB2ZWN0b3I8Y29uc3QgRmlsZURlc2NyaXB0b3IqPiBhbGxfZmlsZXMpIHsKKyAgdmVjdG9yPHN0cmluZz4gbmFtZXM7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgYWxsX2ZpbGVzLnNpemUoKTsgaSsrKSB7CisgICAgbmFtZXMucHVzaF9iYWNrKGFsbF9maWxlc1tpXS0+bmFtZSgpKTsKKyAgfQorICByZXR1cm4gSm9pbihuYW1lcywgIiwiKTsKK30KKworc3RhdGljIGNvbnN0IGNoYXIqIGtGaXJzdEluc2VydGlvblBvaW50TmFtZSA9ICJmaXJzdF9tb2NrX2luc2VydGlvbl9wb2ludCI7CitzdGF0aWMgY29uc3QgY2hhcioga1NlY29uZEluc2VydGlvblBvaW50TmFtZSA9ICJzZWNvbmRfbW9ja19pbnNlcnRpb25fcG9pbnQiOworc3RhdGljIGNvbnN0IGNoYXIqIGtGaXJzdEluc2VydGlvblBvaW50ID0KKyAgICAiIyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmlyc3RfbW9ja19pbnNlcnRpb25fcG9pbnQpIGlzIGhlcmVcbiI7CitzdGF0aWMgY29uc3QgY2hhcioga1NlY29uZEluc2VydGlvblBvaW50ID0KKyAgICAiICAjIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZWNvbmRfbW9ja19pbnNlcnRpb25fcG9pbnQpIGlzIGhlcmVcbiI7CisKK01vY2tDb2RlR2VuZXJhdG9yOjpNb2NrQ29kZUdlbmVyYXRvcihjb25zdCBzdHJpbmcmIG5hbWUpCisgICAgOiBuYW1lXyhuYW1lKSB7fQorCitNb2NrQ29kZUdlbmVyYXRvcjo6fk1vY2tDb2RlR2VuZXJhdG9yKCkge30KKwordm9pZCBNb2NrQ29kZUdlbmVyYXRvcjo6RXhwZWN0R2VuZXJhdGVkKAorICAgIGNvbnN0IHN0cmluZyYgbmFtZSwKKyAgICBjb25zdCBzdHJpbmcmIHBhcmFtZXRlciwKKyAgICBjb25zdCBzdHJpbmcmIGluc2VydGlvbnMsCisgICAgY29uc3Qgc3RyaW5nJiBmaWxlLAorICAgIGNvbnN0IHN0cmluZyYgZmlyc3RfbWVzc2FnZV9uYW1lLAorICAgIGNvbnN0IHN0cmluZyYgZmlyc3RfcGFyc2VkX2ZpbGVfbmFtZSwKKyAgICBjb25zdCBzdHJpbmcmIG91dHB1dF9kaXJlY3RvcnkpIHsKKyAgc3RyaW5nIGNvbnRlbnQ7CisgIEdPT0dMRV9DSEVDS19PSygKKyAgICAgIEZpbGU6OkdldENvbnRlbnRzKG91dHB1dF9kaXJlY3RvcnkgKyAiLyIgKyBHZXRPdXRwdXRGaWxlTmFtZShuYW1lLCBmaWxlKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICZjb250ZW50LCB0cnVlKSk7CisKKyAgdmVjdG9yPHN0cmluZz4gbGluZXMgPSBTcGxpdChjb250ZW50LCAiXG4iLCB0cnVlKTsKKworICB3aGlsZSAoIWxpbmVzLmVtcHR5KCkgJiYgbGluZXMuYmFjaygpLmVtcHR5KCkpIHsKKyAgICBsaW5lcy5wb3BfYmFjaygpOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgbGluZXMuc2l6ZSgpOyBpKyspIHsKKyAgICBsaW5lc1tpXSArPSAiXG4iOworICB9CisKKyAgdmVjdG9yPHN0cmluZz4gaW5zZXJ0aW9uX2xpc3Q7CisgIGlmICghaW5zZXJ0aW9ucy5lbXB0eSgpKSB7CisgICAgU3BsaXRTdHJpbmdVc2luZyhpbnNlcnRpb25zLCAiLCIsICZpbnNlcnRpb25fbGlzdCk7CisgIH0KKworICBFWFBFQ1RfRVEobGluZXMuc2l6ZSgpLCAzICsgaW5zZXJ0aW9uX2xpc3Quc2l6ZSgpICogMik7CisgIEVYUEVDVF9FUShHZXRPdXRwdXRGaWxlQ29udGVudChuYW1lLCBwYXJhbWV0ZXIsIGZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaXJzdF9wYXJzZWRfZmlsZV9uYW1lLCBmaXJzdF9tZXNzYWdlX25hbWUpLAorICAgICAgICAgICAgbGluZXNbMF0pOworCisgIEVYUEVDVF9FUShrRmlyc3RJbnNlcnRpb25Qb2ludCwgbGluZXNbMSArIGluc2VydGlvbl9saXN0LnNpemUoKV0pOworICBFWFBFQ1RfRVEoa1NlY29uZEluc2VydGlvblBvaW50LCBsaW5lc1syICsgaW5zZXJ0aW9uX2xpc3Quc2l6ZSgpICogMl0pOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgaW5zZXJ0aW9uX2xpc3Quc2l6ZSgpOyBpKyspIHsKKyAgICBFWFBFQ1RfRVEoR2V0T3V0cHV0RmlsZUNvbnRlbnQoaW5zZXJ0aW9uX2xpc3RbaV0sICJmaXJzdF9pbnNlcnQiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlLCBmaWxlLCBmaXJzdF9tZXNzYWdlX25hbWUpLAorICAgICAgICAgICAgICBsaW5lc1sxICsgaV0pOworICAgIC8vIFNlY29uZCBpbnNlcnRpb24gcG9pbnQgaXMgaW5kZW50ZWQsIHNvIHRoZSBpbnNlcnRlZCB0ZXh0IHNob3VsZAorICAgIC8vIGF1dG9tYXRpY2FsbHkgYmUgaW5kZW50ZWQgdG9vLgorICAgIEVYUEVDVF9FUSgiICAiICsgR2V0T3V0cHV0RmlsZUNvbnRlbnQoaW5zZXJ0aW9uX2xpc3RbaV0sICJzZWNvbmRfaW5zZXJ0IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGUsIGZpbGUsIGZpcnN0X21lc3NhZ2VfbmFtZSksCisgICAgICAgICAgICAgIGxpbmVzWzIgKyBpbnNlcnRpb25fbGlzdC5zaXplKCkgKyBpXSk7CisgIH0KK30KKworYm9vbCBNb2NrQ29kZUdlbmVyYXRvcjo6R2VuZXJhdGUoCisgICAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUsCisgICAgY29uc3Qgc3RyaW5nJiBwYXJhbWV0ZXIsCisgICAgR2VuZXJhdG9yQ29udGV4dCogY29udGV4dCwKKyAgICBzdHJpbmcqIGVycm9yKSBjb25zdCB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZS0+bWVzc2FnZV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIGlmIChIYXNQcmVmaXhTdHJpbmcoZmlsZS0+bWVzc2FnZV90eXBlKGkpLT5uYW1lKCksICJNb2NrQ29kZUdlbmVyYXRvcl8iKSkgeworICAgICAgc3RyaW5nIGNvbW1hbmQgPSBTdHJpcFByZWZpeFN0cmluZyhmaWxlLT5tZXNzYWdlX3R5cGUoaSktPm5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1vY2tDb2RlR2VuZXJhdG9yXyIpOworICAgICAgaWYgKGNvbW1hbmQgPT0gIkVycm9yIikgeworICAgICAgICAqZXJyb3IgPSAiU2F3IG1lc3NhZ2UgdHlwZSBNb2NrQ29kZUdlbmVyYXRvcl9FcnJvci4iOworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9IGVsc2UgaWYgKGNvbW1hbmQgPT0gIkV4aXQiKSB7CisgICAgICAgIHN0ZDo6Y2VyciA8PCAiU2F3IG1lc3NhZ2UgdHlwZSBNb2NrQ29kZUdlbmVyYXRvcl9FeGl0LiIgPDwgc3RkOjplbmRsOworICAgICAgICBleGl0KDEyMyk7CisgICAgICB9IGVsc2UgaWYgKGNvbW1hbmQgPT0gIkFib3J0IikgeworICAgICAgICBzdGQ6OmNlcnIgPDwgIlNhdyBtZXNzYWdlIHR5cGUgTW9ja0NvZGVHZW5lcmF0b3JfQWJvcnQuIiA8PCBzdGQ6OmVuZGw7CisgICAgICAgIGFib3J0KCk7CisgICAgICB9IGVsc2UgaWYgKGNvbW1hbmQgPT0gIkhhc1NvdXJjZUNvZGVJbmZvIikgeworICAgICAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGVfZGVzY3JpcHRvcl9wcm90bzsKKyAgICAgICAgZmlsZS0+Q29weVNvdXJjZUNvZGVJbmZvVG8oJmZpbGVfZGVzY3JpcHRvcl9wcm90byk7CisgICAgICAgIGJvb2wgaGFzX3NvdXJjZV9jb2RlX2luZm8gPQorICAgICAgICAgICAgZmlsZV9kZXNjcmlwdG9yX3Byb3RvLmhhc19zb3VyY2VfY29kZV9pbmZvKCkgJiYKKyAgICAgICAgICAgIGZpbGVfZGVzY3JpcHRvcl9wcm90by5zb3VyY2VfY29kZV9pbmZvKCkubG9jYXRpb25fc2l6ZSgpID4gMDsKKyAgICAgICAgc3RkOjpjZXJyIDw8ICJTYXcgbWVzc2FnZSB0eXBlIE1vY2tDb2RlR2VuZXJhdG9yX0hhc1NvdXJjZUNvZGVJbmZvOiAiCisgICAgICAgICAgICAgICAgICA8PCBoYXNfc291cmNlX2NvZGVfaW5mbyA8PCAiLiIgPDwgc3RkOjplbmRsOworICAgICAgICBhYm9ydCgpOworICAgICAgfSBlbHNlIGlmIChjb21tYW5kID09ICJIYXNKc29uTmFtZSIpIHsKKyAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG8gZmllbGRfZGVzY3JpcHRvcl9wcm90bzsKKyAgICAgICAgZmlsZS0+bWVzc2FnZV90eXBlKGkpLT5maWVsZCgwKS0+Q29weVRvKCZmaWVsZF9kZXNjcmlwdG9yX3Byb3RvKTsKKyAgICAgICAgc3RkOjpjZXJyIDw8ICJTYXcganNvbl9uYW1lOiAiCisgICAgICAgICAgICAgICAgICA8PCBmaWVsZF9kZXNjcmlwdG9yX3Byb3RvLmhhc19qc29uX25hbWUoKSA8PCBzdGQ6OmVuZGw7CisgICAgICAgIGFib3J0KCk7CisgICAgICB9IGVsc2UgeworICAgICAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiVW5rbm93biBNb2NrQ29kZUdlbmVyYXRvciBjb21tYW5kOiAiIDw8IGNvbW1hbmQ7CisgICAgICB9CisgICAgfQorICB9CisKKyAgaWYgKEhhc1ByZWZpeFN0cmluZyhwYXJhbWV0ZXIsICJpbnNlcnQ9IikpIHsKKyAgICB2ZWN0b3I8c3RyaW5nPiBpbnNlcnRfaW50bzsKKyAgICBTcGxpdFN0cmluZ1VzaW5nKFN0cmlwUHJlZml4U3RyaW5nKHBhcmFtZXRlciwgImluc2VydD0iKSwKKyAgICAgICAgICAgICAgICAgICAgICIsIiwgJmluc2VydF9pbnRvKTsKKworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW5zZXJ0X2ludG8uc2l6ZSgpOyBpKyspIHsKKyAgICAgIHsKKyAgICAgICAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0+IG91dHB1dChjb250ZXh0LT5PcGVuRm9ySW5zZXJ0KAorICAgICAgICAgICAgR2V0T3V0cHV0RmlsZU5hbWUoaW5zZXJ0X2ludG9baV0sIGZpbGUpLCBrRmlyc3RJbnNlcnRpb25Qb2ludE5hbWUpKTsKKyAgICAgICAgaW86OlByaW50ZXIgcHJpbnRlcihvdXRwdXQuZ2V0KCksICckJyk7CisgICAgICAgIHByaW50ZXIuUHJpbnRSYXcoR2V0T3V0cHV0RmlsZUNvbnRlbnQobmFtZV8sICJmaXJzdF9pbnNlcnQiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGUsIGNvbnRleHQpKTsKKyAgICAgICAgaWYgKHByaW50ZXIuZmFpbGVkKCkpIHsKKyAgICAgICAgICAqZXJyb3IgPSAiTW9ja0NvZGVHZW5lcmF0b3IgZGV0ZWN0ZWQgd3JpdGUgZXJyb3IuIjsKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgIH0KKworICAgICAgeworICAgICAgICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPGlvOjpaZXJvQ29weU91dHB1dFN0cmVhbT4gb3V0cHV0KAorICAgICAgICAgICAgY29udGV4dC0+T3BlbkZvckluc2VydChHZXRPdXRwdXRGaWxlTmFtZShpbnNlcnRfaW50b1tpXSwgZmlsZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtTZWNvbmRJbnNlcnRpb25Qb2ludE5hbWUpKTsKKyAgICAgICAgaW86OlByaW50ZXIgcHJpbnRlcihvdXRwdXQuZ2V0KCksICckJyk7CisgICAgICAgIHByaW50ZXIuUHJpbnRSYXcoR2V0T3V0cHV0RmlsZUNvbnRlbnQobmFtZV8sICJzZWNvbmRfaW5zZXJ0IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlLCBjb250ZXh0KSk7CisgICAgICAgIGlmIChwcmludGVyLmZhaWxlZCgpKSB7CisgICAgICAgICAgKmVycm9yID0gIk1vY2tDb2RlR2VuZXJhdG9yIGRldGVjdGVkIHdyaXRlIGVycm9yLiI7CisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICB9CisgICAgfQorICB9IGVsc2UgeworICAgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8aW86Olplcm9Db3B5T3V0cHV0U3RyZWFtPiBvdXRwdXQoCisgICAgICAgIGNvbnRleHQtPk9wZW4oR2V0T3V0cHV0RmlsZU5hbWUobmFtZV8sIGZpbGUpKSk7CisKKyAgICBpbzo6UHJpbnRlciBwcmludGVyKG91dHB1dC5nZXQoKSwgJyQnKTsKKyAgICBwcmludGVyLlByaW50UmF3KEdldE91dHB1dEZpbGVDb250ZW50KG5hbWVfLCBwYXJhbWV0ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlLCBjb250ZXh0KSk7CisgICAgcHJpbnRlci5QcmludFJhdyhrRmlyc3RJbnNlcnRpb25Qb2ludCk7CisgICAgcHJpbnRlci5QcmludFJhdyhrU2Vjb25kSW5zZXJ0aW9uUG9pbnQpOworCisgICAgaWYgKHByaW50ZXIuZmFpbGVkKCkpIHsKKyAgICAgICplcnJvciA9ICJNb2NrQ29kZUdlbmVyYXRvciBkZXRlY3RlZCB3cml0ZSBlcnJvci4iOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgfQorCisgIHJldHVybiB0cnVlOworfQorCitzdHJpbmcgTW9ja0NvZGVHZW5lcmF0b3I6OkdldE91dHB1dEZpbGVOYW1lKGNvbnN0IHN0cmluZyYgZ2VuZXJhdG9yX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKSB7CisgIHJldHVybiBHZXRPdXRwdXRGaWxlTmFtZShnZW5lcmF0b3JfbmFtZSwgZmlsZS0+bmFtZSgpKTsKK30KKworc3RyaW5nIE1vY2tDb2RlR2VuZXJhdG9yOjpHZXRPdXRwdXRGaWxlTmFtZShjb25zdCBzdHJpbmcmIGdlbmVyYXRvcl9uYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIGZpbGUpIHsKKyAgcmV0dXJuIGZpbGUgKyAiLk1vY2tDb2RlR2VuZXJhdG9yLiIgKyBnZW5lcmF0b3JfbmFtZTsKK30KKworc3RyaW5nIE1vY2tDb2RlR2VuZXJhdG9yOjpHZXRPdXRwdXRGaWxlQ29udGVudCgKKyAgICBjb25zdCBzdHJpbmcmIGdlbmVyYXRvcl9uYW1lLAorICAgIGNvbnN0IHN0cmluZyYgcGFyYW1ldGVyLAorICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlLAorICAgIEdlbmVyYXRvckNvbnRleHQgKmNvbnRleHQpIHsKKyAgdmVjdG9yPGNvbnN0IEZpbGVEZXNjcmlwdG9yKj4gYWxsX2ZpbGVzOworICBjb250ZXh0LT5MaXN0UGFyc2VkRmlsZXMoJmFsbF9maWxlcyk7CisgIHJldHVybiBHZXRPdXRwdXRGaWxlQ29udGVudCgKKyAgICAgIGdlbmVyYXRvcl9uYW1lLCBwYXJhbWV0ZXIsIGZpbGUtPm5hbWUoKSwKKyAgICAgIENvbW1hU2VwYXJhdGVkTGlzdChhbGxfZmlsZXMpLAorICAgICAgZmlsZS0+bWVzc2FnZV90eXBlX2NvdW50KCkgPiAwID8KKyAgICAgICAgICBmaWxlLT5tZXNzYWdlX3R5cGUoMCktPm5hbWUoKSA6ICIobm9uZSkiKTsKK30KKworc3RyaW5nIE1vY2tDb2RlR2VuZXJhdG9yOjpHZXRPdXRwdXRGaWxlQ29udGVudCgKKyAgICBjb25zdCBzdHJpbmcmIGdlbmVyYXRvcl9uYW1lLAorICAgIGNvbnN0IHN0cmluZyYgcGFyYW1ldGVyLAorICAgIGNvbnN0IHN0cmluZyYgZmlsZSwKKyAgICBjb25zdCBzdHJpbmcmIHBhcnNlZF9maWxlX2xpc3QsCisgICAgY29uc3Qgc3RyaW5nJiBmaXJzdF9tZXNzYWdlX25hbWUpIHsKKyAgcmV0dXJuIHN0cmluZ3M6OlN1YnN0aXR1dGUoIiQwOiAkMSwgJDIsICQzLCAkNFxuIiwKKyAgICAgIGdlbmVyYXRvcl9uYW1lLCBwYXJhbWV0ZXIsIGZpbGUsCisgICAgICBmaXJzdF9tZXNzYWdlX25hbWUsIHBhcnNlZF9maWxlX2xpc3QpOworfQorCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9tb2NrX2NvZGVfZ2VuZXJhdG9yLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL21vY2tfY29kZV9nZW5lcmF0b3IuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YzgzNDhkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9tb2NrX2NvZGVfZ2VuZXJhdG9yLmgKQEAgLTAsMCArMSwxMTcgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX01PQ0tfQ09ERV9HRU5FUkFUT1JfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9NT0NLX0NPREVfR0VORVJBVE9SX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jb2RlX2dlbmVyYXRvci5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworCisvLyBBIG1vY2sgQ29kZUdlbmVyYXRvciwgdXNlZCBieSBjb21tYW5kX2xpbmVfaW50ZXJmYWNlX3VuaXR0ZXN0LiAgVGhpcyBpcyBpbgorLy8gaXRzIG93biBmaWxlIHNvIHRoYXQgaXQgY2FuIGJlIHVzZWQgYm90aCBkaXJlY3RseSBhbmQgYXMgYSBwbHVnaW4uCisvLworLy8gR2VuZXJhdGUoKSBwcm9kdWNlcyBzb21lIG91dHB1dCB3aGljaCBjYW4gYmUgY2hlY2tlZCBieSBFeHBlY3RDYWxsZWQoKS4gIFRoZQorLy8gZ2VuZXJhdG9yIGNhbiBydW4gaW4gYSBkaWZmZXJlbnQgcHJvY2VzcyAoZS5nLiBhIHBsdWdpbikuCisvLworLy8gSWYgdGhlIHBhcmFtZXRlciBpcyAiaW5zZXJ0PU5BTUVTIiwgdGhlIE1vY2tDb2RlR2VuZXJhdG9yIHdpbGwgaW5zZXJ0IGxpbmVzCisvLyBpbnRvIHRoZSBmaWxlcyBnZW5lcmF0ZWQgYnkgb3RoZXIgTW9ja0NvZGVHZW5lcmF0b3JzIGluc3RlYWQgb2YgY3JlYXRpbmcKKy8vIGl0cyBvd24gZmlsZS4gIE5BTUVTIGlzIGEgY29tbWEtc2VwYXJhdGVkIGxpc3Qgb2YgdGhlIG5hbWVzIG9mIHRob3NlIG90aGVyCisvLyBNb2NrQ29kZUdlbmVyYXRvcnMuCisvLworLy8gTW9ja0NvZGVHZW5lcmF0b3Igd2lsbCBhbHNvIG1vZGlmeSBpdHMgYmVoYXZpb3Igc2xpZ2h0bHkgaWYgdGhlIGlucHV0IGZpbGUKKy8vIGNvbnRhaW5zIGEgbWVzc2FnZSB0eXBlIHdpdGggb25lIG9mIHRoZSBmb2xsb3dpbmcgbmFtZXM6CisvLyAgIE1vY2tDb2RlR2VuZXJhdG9yX0Vycm9yOiAgQ2F1c2VzIEdlbmVyYXRlKCkgdG8gcmV0dXJuIGZhbHNlIGFuZCBzZXQgdGhlCisvLyAgICAgZXJyb3IgbWVzc2FnZSB0byAiU2F3IG1lc3NhZ2UgdHlwZSBNb2NrQ29kZUdlbmVyYXRvcl9FcnJvci4iCisvLyAgIE1vY2tDb2RlR2VuZXJhdG9yX0V4aXQ6ICBHZW5lcmF0ZSgpIHByaW50cyAiU2F3IG1lc3NhZ2UgdHlwZQorLy8gICAgIE1vY2tDb2RlR2VuZXJhdG9yX0V4aXQuIiB0byBzdGRlcnIgYW5kIHRoZW4gY2FsbHMgZXhpdCgxMjMpLgorLy8gICBNb2NrQ29kZUdlbmVyYXRvcl9BYm9ydDogIEdlbmVyYXRlKCkgcHJpbnRzICJTYXcgbWVzc2FnZSB0eXBlCisvLyAgICAgTW9ja0NvZGVHZW5lcmF0b3JfQWJvcnQuIiB0byBzdGRlcnIgYW5kIHRoZW4gY2FsbHMgYWJvcnQoKS4KKy8vICAgTW9ja0NvZGVHZW5lcmF0b3JfSGFzU291cmNlQ29kZUluZm86ICBDYXVzZXMgR2VuZXJhdGUoKSB0byBhYm9ydCBhZnRlcgorLy8gICAgIHByaW50aW5nICJTYXcgbWVzc2FnZSB0eXBlIE1vY2tDb2RlR2VuZXJhdG9yX0hhc1NvdXJjZUNvZGVJbmZvOiBGT08uIiB0bworLy8gICAgIHN0ZGVyciwgd2hlcmUgRk9PIGlzICIxIiBpZiB0aGUgc3VwcGxpZWQgRmlsZURlc2NyaXB0b3JQcm90byBoYXMgc291cmNlCisvLyAgICAgY29kZSBpbmZvLCBhbmQgIjAiIG90aGVyd2lzZS4KK2NsYXNzIE1vY2tDb2RlR2VuZXJhdG9yIDogcHVibGljIENvZGVHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgTW9ja0NvZGVHZW5lcmF0b3IoY29uc3Qgc3RyaW5nJiBuYW1lKTsKKyAgdmlydHVhbCB+TW9ja0NvZGVHZW5lcmF0b3IoKTsKKworICAvLyBFeHBlY3QgKHZpYSBnVGVzdCkgdGhhdCBhIE1vY2tDb2RlR2VuZXJhdG9yIHdpdGggdGhlIGdpdmVuIG5hbWUgd2FzIGNhbGxlZAorICAvLyB3aXRoIHRoZSBnaXZlbiBwYXJhbWV0ZXJzIGJ5IGluc3BlY3RpbmcgdGhlIG91dHB1dCBsb2NhdGlvbi4KKyAgLy8KKyAgLy8gfGluc2VydGlvbnN8IGlzIGEgY29tbWEtc2VwYXJhdGVkIGxpc3Qgb2YgbmFtZXMgb2YgTW9ja0NvZGVHZW5lcmF0b3JzIHdoaWNoCisgIC8vIHNob3VsZCBoYXZlIGluc2VydGVkIGxpbmVzIGludG8gdGhpcyBmaWxlLgorICAvLyB8cGFyc2VkX2ZpbGVfbGlzdHwgaXMgYSBjb21tYS1zZXBhcmF0ZWQgbGlzdCBvZiBuYW1lcyBvZiB0aGUgZmlsZXMKKyAgLy8gdGhhdCBhcmUgYmVpbmcgY29tcGlsZWQgdG9nZXRoZXIgaW4gdGhpcyBydW4uCisgIHN0YXRpYyB2b2lkIEV4cGVjdEdlbmVyYXRlZChjb25zdCBzdHJpbmcmIG5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHBhcmFtZXRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgaW5zZXJ0aW9ucywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgZmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgZmlyc3RfbWVzc2FnZV9uYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBwYXJzZWRfZmlsZV9saXN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBvdXRwdXRfZGlyZWN0b3J5KTsKKworICAvLyBHZXQgdGhlIG5hbWUgb2YgdGhlIGZpbGUgd2hpY2ggd291bGQgYmUgd3JpdHRlbiBieSB0aGUgZ2l2ZW4gZ2VuZXJhdG9yLgorICBzdGF0aWMgc3RyaW5nIEdldE91dHB1dEZpbGVOYW1lKGNvbnN0IHN0cmluZyYgZ2VuZXJhdG9yX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUpOworICBzdGF0aWMgc3RyaW5nIEdldE91dHB1dEZpbGVOYW1lKGNvbnN0IHN0cmluZyYgZ2VuZXJhdG9yX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBmaWxlKTsKKworICAvLyBpbXBsZW1lbnRzIENvZGVHZW5lcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIHZpcnR1YWwgYm9vbCBHZW5lcmF0ZShjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgcGFyYW1ldGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgR2VuZXJhdG9yQ29udGV4dCogY29udGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyogZXJyb3IpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgc3RyaW5nIG5hbWVfOworCisgIHN0YXRpYyBzdHJpbmcgR2V0T3V0cHV0RmlsZUNvbnRlbnQoY29uc3Qgc3RyaW5nJiBnZW5lcmF0b3JfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHBhcmFtZXRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZW5lcmF0b3JDb250ZXh0ICpjb250ZXh0KTsKKyAgc3RhdGljIHN0cmluZyBHZXRPdXRwdXRGaWxlQ29udGVudChjb25zdCBzdHJpbmcmIGdlbmVyYXRvcl9uYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgcGFyYW1ldGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgZmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHBhcnNlZF9maWxlX2xpc3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBmaXJzdF9tZXNzYWdlX25hbWUpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfTU9DS19DT0RFX0dFTkVSQVRPUl9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX2VudW0uY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19lbnVtLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ2ZjAxYzYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19lbnVtLmNjCkBAIC0wLDAgKzEsMTk4IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2luY2x1ZGUgPG1hcD4KKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX2VudW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2Ugb2JqZWN0aXZlYyB7CisKK0VudW1HZW5lcmF0b3I6OkVudW1HZW5lcmF0b3IoY29uc3QgRW51bURlc2NyaXB0b3IqIGRlc2NyaXB0b3IpCisgICAgOiBkZXNjcmlwdG9yXyhkZXNjcmlwdG9yKSwKKyAgICAgIG5hbWVfKEVudW1OYW1lKGRlc2NyaXB0b3JfKSkgeworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT52YWx1ZV9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiB2YWx1ZSA9IGRlc2NyaXB0b3JfLT52YWx1ZShpKTsKKyAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBjYW5vbmljYWxfdmFsdWUgPQorICAgICAgICBkZXNjcmlwdG9yXy0+RmluZFZhbHVlQnlOdW1iZXIodmFsdWUtPm51bWJlcigpKTsKKworICAgIGlmICh2YWx1ZSA9PSBjYW5vbmljYWxfdmFsdWUpIHsKKyAgICAgIGJhc2VfdmFsdWVzXy5wdXNoX2JhY2sodmFsdWUpOworICAgIH0KKyAgICBhbGxfdmFsdWVzXy5wdXNoX2JhY2sodmFsdWUpOworICB9Cit9CisKK0VudW1HZW5lcmF0b3I6On5FbnVtR2VuZXJhdG9yKCkge30KKwordm9pZCBFbnVtR2VuZXJhdG9yOjpHZW5lcmF0ZUhlYWRlcihpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBzdHJpbmcgZW51bV9jb21tZW50czsKKyAgU291cmNlTG9jYXRpb24gbG9jYXRpb247CisgIGlmIChkZXNjcmlwdG9yXy0+R2V0U291cmNlTG9jYXRpb24oJmxvY2F0aW9uKSkgeworICAgIGVudW1fY29tbWVudHMgPSBCdWlsZENvbW1lbnRzU3RyaW5nKGxvY2F0aW9uKTsKKyAgfSBlbHNlIHsKKyAgICBlbnVtX2NvbW1lbnRzID0gIiI7CisgIH0KKworICBwcmludGVyLT5QcmludCgKKyAgICAgICIjcHJhZ21hIG1hcmsgLSBFbnVtICRuYW1lJFxuIgorICAgICAgIlxuIiwKKyAgICAgICJuYW1lIiwgbmFtZV8pOworCisgIHByaW50ZXItPlByaW50KCIkY29tbWVudHMkdHlwZWRlZiBHUEJfRU5VTSgkbmFtZSQpIHtcbiIsCisgICAgICAgICAgICAgICAgICJjb21tZW50cyIsIGVudW1fY29tbWVudHMsCisgICAgICAgICAgICAgICAgICJuYW1lIiwgbmFtZV8pOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBpZiAoSGFzUHJlc2VydmluZ1Vua25vd25FbnVtU2VtYW50aWNzKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgLy8gSW5jbHVkZSB0aGUgdW5rbm93biB2YWx1ZS4KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICIkbmFtZSRfR1BCVW5yZWNvZ25pemVkRW51bWVyYXRvclZhbHVlID0ga0dQQlVucmVjb2duaXplZEVudW1lcmF0b3JWYWx1ZSxcbiIsCisgICAgICAibmFtZSIsIG5hbWVfKTsKKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgYWxsX3ZhbHVlc18uc2l6ZSgpOyBpKyspIHsKKyAgICBTb3VyY2VMb2NhdGlvbiBsb2NhdGlvbjsKKyAgICBpZiAoYWxsX3ZhbHVlc19baV0tPkdldFNvdXJjZUxvY2F0aW9uKCZsb2NhdGlvbikpIHsKKyAgICAgIHN0cmluZyBjb21tZW50cyA9IEJ1aWxkQ29tbWVudHNTdHJpbmcobG9jYXRpb24pLmNfc3RyKCk7CisgICAgICBpZiAoY29tbWVudHMubGVuZ3RoKCkgPiAwKSB7CisgICAgICAgIGlmIChpID4gMCkgeworICAgICAgICAgIHByaW50ZXItPlByaW50KCJcbiIpOworICAgICAgICB9CisgICAgICAgIHByaW50ZXItPlByaW50KGNvbW1lbnRzLmNfc3RyKCkpOworICAgICAgfQorICAgIH0KKworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiJG5hbWUkID0gJHZhbHVlJCxcbiIsCisgICAgICAgICJuYW1lIiwgRW51bVZhbHVlTmFtZShhbGxfdmFsdWVzX1tpXSksCisgICAgICAgICJ2YWx1ZSIsIFNpbXBsZUl0b2EoYWxsX3ZhbHVlc19baV0tPm51bWJlcigpKSk7CisgIH0KKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAgICJ9O1xuIgorICAgICAgIlxuIgorICAgICAgIkdQQkVudW1EZXNjcmlwdG9yICokbmFtZSRfRW51bURlc2NyaXB0b3Iodm9pZCk7XG4iCisgICAgICAiXG4iCisgICAgICAiQk9PTCAkbmFtZSRfSXNWYWxpZFZhbHVlKGludDMyX3QgdmFsdWUpO1xuIgorICAgICAgIlxuIiwKKyAgICAgICJuYW1lIiwgbmFtZV8pOworfQorCit2b2lkIEVudW1HZW5lcmF0b3I6OkdlbmVyYXRlU291cmNlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgICAgIiNwcmFnbWEgbWFyayAtIEVudW0gJG5hbWUkXG4iCisgICAgICAiXG4iLAorICAgICAgIm5hbWUiLCBuYW1lXyk7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiR1BCRW51bURlc2NyaXB0b3IgKiRuYW1lJF9FbnVtRGVzY3JpcHRvcih2b2lkKSB7XG4iCisgICAgICAiICBzdGF0aWMgR1BCRW51bURlc2NyaXB0b3IgKmRlc2NyaXB0b3IgPSBOVUxMO1xuIgorICAgICAgIiAgaWYgKCFkZXNjcmlwdG9yKSB7XG4iCisgICAgICAiICAgIHN0YXRpYyBHUEJNZXNzYWdlRW51bVZhbHVlRGVzY3JpcHRpb24gdmFsdWVzW10gPSB7XG4iLAorICAgICAgIm5hbWUiLCBuYW1lXyk7CisgIHByaW50ZXItPkluZGVudCgpOworICBwcmludGVyLT5JbmRlbnQoKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgLy8gTm90ZTogRm9yIHRoZSBUZXh0Rm9ybWF0IGRlY29kZSBpbmZvLCB3ZSBjYW4ndCB1c2UgdGhlIGVudW0gdmFsdWUgYXMKKyAgLy8gdGhlIGtleSBiZWNhdXNlIHByb3RvY29sIGJ1ZmZlciBlbnVtcyBoYXZlICdhbGxvd19hbGlhcycsIHdoaWNoIGxldHMKKyAgLy8gYSB2YWx1ZSBiZSB1c2VkIG1vcmUgdGhhbiBvbmNlLiBJbnN0ZWFkLCB0aGUgaW5kZXggaW50byB0aGUgbGlzdCBvZgorICAvLyBlbnVtIHZhbHVlIGRlc2NyaXB0aW9ucyBpcyB1c2VkLiBOb3RlOiBzdGFydCB3aXRoIC0xIHNvIHRoZSBmaXJzdCBvbmUKKyAgLy8gd2lsbCBiZSB6ZXJvLgorICBUZXh0Rm9ybWF0RGVjb2RlRGF0YSB0ZXh0X2Zvcm1hdF9kZWNvZGVfZGF0YTsKKyAgaW50IGVudW1fdmFsdWVfZGVzY3JpcHRpb25fa2V5ID0gLTE7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBhbGxfdmFsdWVzXy5zaXplKCk7IGkrKykgeworICAgICsrZW51bV92YWx1ZV9kZXNjcmlwdGlvbl9rZXk7CisgICAgc3RyaW5nIHNob3J0X25hbWUoRW51bVZhbHVlU2hvcnROYW1lKGFsbF92YWx1ZXNfW2ldKSk7CisgICAgcHJpbnRlci0+UHJpbnQoInsgLm5hbWUgPSBcIiRzaG9ydF9uYW1lJFwiLCAubnVtYmVyID0gJG5hbWUkIH0sXG4iLAorICAgICAgICAgICAgICAgICAgICJzaG9ydF9uYW1lIiwgc2hvcnRfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAibmFtZSIsIEVudW1WYWx1ZU5hbWUoYWxsX3ZhbHVlc19baV0pKTsKKyAgICBpZiAoVW5DYW1lbENhc2VFbnVtU2hvcnROYW1lKHNob3J0X25hbWUpICE9IGFsbF92YWx1ZXNfW2ldLT5uYW1lKCkpIHsKKyAgICAgIHRleHRfZm9ybWF0X2RlY29kZV9kYXRhLkFkZFN0cmluZyhlbnVtX3ZhbHVlX2Rlc2NyaXB0aW9uX2tleSwgc2hvcnRfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbGxfdmFsdWVzX1tpXS0+bmFtZSgpKTsKKyAgICB9CisgIH0KKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoIiAgICB9O1xuIik7CisgIGlmICh0ZXh0X2Zvcm1hdF9kZWNvZGVfZGF0YS5udW1fZW50cmllcygpID09IDApIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIiAgICBkZXNjcmlwdG9yID0gW0dQQkVudW1EZXNjcmlwdG9yIGFsbG9jRGVzY3JpcHRvckZvck5hbWU6R1BCTlNTdHJpbmdpZnlTeW1ib2woJG5hbWUkKVxuIgorICAgICAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVzOnZhbHVlc1xuIgorICAgICAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZUNvdW50OnNpemVvZih2YWx1ZXMpIC8gc2l6ZW9mKEdQQk1lc3NhZ2VFbnVtVmFsdWVEZXNjcmlwdGlvbilcbiIKKyAgICAgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudW1WZXJpZmllcjokbmFtZSRfSXNWYWxpZFZhbHVlXTtcbiIsCisgICAgICAgICJuYW1lIiwgbmFtZV8pOworICAgIH0gZWxzZSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIiAgICBzdGF0aWMgY29uc3QgY2hhciAqZXh0cmFUZXh0Rm9ybWF0SW5mbyA9IFwiJGV4dHJhVGV4dEZvcm1hdEluZm8kXCI7XG4iCisgICAgICAgICIgICAgZGVzY3JpcHRvciA9IFtHUEJFbnVtRGVzY3JpcHRvciBhbGxvY0Rlc2NyaXB0b3JGb3JOYW1lOkdQQk5TU3RyaW5naWZ5U3ltYm9sKCRuYW1lJClcbiIKKyAgICAgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlczp2YWx1ZXNcbiIKKyAgICAgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVDb3VudDpzaXplb2YodmFsdWVzKSAvIHNpemVvZihHUEJNZXNzYWdlRW51bVZhbHVlRGVzY3JpcHRpb24pXG4iCisgICAgICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbnVtVmVyaWZpZXI6JG5hbWUkX0lzVmFsaWRWYWx1ZVxuIgorICAgICAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRyYVRleHRGb3JtYXRJbmZvOmV4dHJhVGV4dEZvcm1hdEluZm9dO1xuIiwKKyAgICAgICAgIm5hbWUiLCBuYW1lXywKKyAgICAgICAgImV4dHJhVGV4dEZvcm1hdEluZm8iLCBDRXNjYXBlKHRleHRfZm9ybWF0X2RlY29kZV9kYXRhLkRhdGEoKSkpOworICAgIH0KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICIgIH1cbiIKKyAgICAgICIgIHJldHVybiBkZXNjcmlwdG9yO1xuIgorICAgICAgIn1cblxuIik7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiQk9PTCAkbmFtZSRfSXNWYWxpZFZhbHVlKGludDMyX3QgdmFsdWVfXykge1xuIgorICAgICAgIiAgc3dpdGNoICh2YWx1ZV9fKSB7XG4iLAorICAgICAgIm5hbWUiLCBuYW1lXyk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBiYXNlX3ZhbHVlc18uc2l6ZSgpOyBpKyspIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIiAgICBjYXNlICRuYW1lJDpcbiIsCisgICAgICAgICJuYW1lIiwgRW51bVZhbHVlTmFtZShiYXNlX3ZhbHVlc19baV0pKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KAorICAgICAgIiAgICAgIHJldHVybiBZRVM7XG4iCisgICAgICAiICAgIGRlZmF1bHQ6XG4iCisgICAgICAiICAgICAgcmV0dXJuIE5PO1xuIgorICAgICAgIiAgfVxuIgorICAgICAgIn1cblxuIik7Cit9Cit9ICAvLyBuYW1lc3BhY2Ugb2JqZWN0aXZlYworfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX2VudW0uaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX2VudW0uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wYjQxY2Y3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfZW51bS5oCkBAIC0wLDAgKzEsNzMgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9PQkpFQ1RJVkVDX0VOVU1fSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9PQkpFQ1RJVkVDX0VOVU1fSF9fCisKKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8c2V0PgorI2luY2x1ZGUgPHZlY3Rvcj4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW8geworY2xhc3MgUHJpbnRlcjsgIC8vIHByaW50ZXIuaAorfQorfQorCituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBvYmplY3RpdmVjIHsKKworY2xhc3MgRW51bUdlbmVyYXRvciB7CisgcHVibGljOgorICBleHBsaWNpdCBFbnVtR2VuZXJhdG9yKGNvbnN0IEVudW1EZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKKyAgfkVudW1HZW5lcmF0b3IoKTsKKworICB2b2lkIEdlbmVyYXRlSGVhZGVyKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdm9pZCBHZW5lcmF0ZVNvdXJjZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyAgY29uc3Qgc3RyaW5nJiBuYW1lKCkgY29uc3QgeyByZXR1cm4gbmFtZV87IH0KKworIHByaXZhdGU6CisgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgdmVjdG9yPGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqPiBiYXNlX3ZhbHVlc187CisgIHZlY3Rvcjxjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKj4gYWxsX3ZhbHVlc187CisgIGNvbnN0IHN0cmluZyBuYW1lXzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoRW51bUdlbmVyYXRvcik7Cit9OworCit9ICAvLyBuYW1lc3BhY2Ugb2JqZWN0aXZlYworfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX09CSkVDVElWRUNfRU5VTV9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX2VudW1fZmllbGQuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19lbnVtX2ZpZWxkLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMwYTEzZGQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19lbnVtX2ZpZWxkLmNjCkBAIC0wLDAgKzEsMTQ0IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2luY2x1ZGUgPG1hcD4KKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX2VudW1fZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIG9iamVjdGl2ZWMgeworCituYW1lc3BhY2Ugewordm9pZCBTZXRFbnVtVmFyaWFibGVzKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICBtYXA8c3RyaW5nLCBzdHJpbmc+KiB2YXJpYWJsZXMpIHsKKyAgc3RyaW5nIHR5cGUgPSBFbnVtTmFtZShkZXNjcmlwdG9yLT5lbnVtX3R5cGUoKSk7CisgICgqdmFyaWFibGVzKVsic3RvcmFnZV90eXBlIl0gPSB0eXBlOworICAvLyBGb3Igbm9uIHJlcGVhdGVkIGZpZWxkcywgaWYgaXQgd2FzIGRlZmluZWQgaW4gYSBkaWZmZXJlbnQgZmlsZSwgdGhlCisgIC8vIHByb3BlcnR5IGRlY2xzIG5lZWQgdG8gdXNlICJlbnVtIE5BTUUiIHJhdGhlciB0aGFuIGp1c3QgIk5BTUUiIHRvIHN1cHBvcnQKKyAgLy8gdGhlIGZvcndhcmQgZGVjbGFyYXRpb24gb2YgdGhlIGVudW1zLgorICBpZiAoIWRlc2NyaXB0b3ItPmlzX3JlcGVhdGVkKCkgJiYKKyAgICAgIChkZXNjcmlwdG9yLT5maWxlKCkgIT0gZGVzY3JpcHRvci0+ZW51bV90eXBlKCktPmZpbGUoKSkpIHsKKyAgICAoKnZhcmlhYmxlcylbInByb3BlcnR5X3R5cGUiXSA9ICJlbnVtICIgKyB0eXBlOworICB9CisgICgqdmFyaWFibGVzKVsiZW51bV92ZXJpZmllciJdID0gdHlwZSArICJfSXNWYWxpZFZhbHVlIjsKKyAgKCp2YXJpYWJsZXMpWyJlbnVtX2Rlc2NfZnVuYyJdID0gdHlwZSArICJfRW51bURlc2NyaXB0b3IiOworCisgIGNvbnN0IERlc2NyaXB0b3IqIG1zZ19kZXNjcmlwdG9yID0gZGVzY3JpcHRvci0+Y29udGFpbmluZ190eXBlKCk7CisgICgqdmFyaWFibGVzKVsib3duaW5nX21lc3NhZ2VfY2xhc3MiXSA9IENsYXNzTmFtZShtc2dfZGVzY3JpcHRvcik7Cit9Cit9ICAvLyBuYW1lc3BhY2UKKworRW51bUZpZWxkR2VuZXJhdG9yOjpFbnVtRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yKQorICAgIDogU2luZ2xlRmllbGRHZW5lcmF0b3IoZGVzY3JpcHRvcikgeworICBTZXRFbnVtVmFyaWFibGVzKGRlc2NyaXB0b3IsICZ2YXJpYWJsZXNfKTsKK30KKworRW51bUZpZWxkR2VuZXJhdG9yOjp+RW51bUZpZWxkR2VuZXJhdG9yKCkge30KKwordm9pZCBFbnVtRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlRmllbGREZXNjcmlwdGlvblR5cGVTcGVjaWZpYygKKyAgICBpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCgKKyAgICAgIHZhcmlhYmxlc18sCisgICAgICAiICAuZGF0YVR5cGVTcGVjaWZpYy5lbnVtRGVzY0Z1bmMgPSAkZW51bV9kZXNjX2Z1bmMkLFxuIik7Cit9CisKK3ZvaWQgRW51bUZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZUNGdW5jdGlvbkRlY2xhcmF0aW9ucygKKyAgICBpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBpZiAoIUhhc1ByZXNlcnZpbmdVbmtub3duRW51bVNlbWFudGljcyhkZXNjcmlwdG9yXy0+ZmlsZSgpKSkgeworICAgIHJldHVybjsKKyAgfQorCisgIHByaW50ZXItPlByaW50KAorICAgICAgdmFyaWFibGVzXywKKyAgICAgICJpbnQzMl90ICRvd25pbmdfbWVzc2FnZV9jbGFzcyRfJGNhcGl0YWxpemVkX25hbWUkX1Jhd1ZhbHVlKCRvd25pbmdfbWVzc2FnZV9jbGFzcyQgKm1lc3NhZ2UpO1xuIgorICAgICAgInZvaWQgU2V0JG93bmluZ19tZXNzYWdlX2NsYXNzJF8kY2FwaXRhbGl6ZWRfbmFtZSRfUmF3VmFsdWUoJG93bmluZ19tZXNzYWdlX2NsYXNzJCAqbWVzc2FnZSwgaW50MzJfdCB2YWx1ZSk7XG4iCisgICAgICAiXG4iKTsKK30KKwordm9pZCBFbnVtRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlQ0Z1bmN0aW9uSW1wbGVtZW50YXRpb25zKAorICAgIGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmICghSGFzUHJlc2VydmluZ1Vua25vd25FbnVtU2VtYW50aWNzKGRlc2NyaXB0b3JfLT5maWxlKCkpKSByZXR1cm47CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICB2YXJpYWJsZXNfLAorICAgICAgImludDMyX3QgJG93bmluZ19tZXNzYWdlX2NsYXNzJF8kY2FwaXRhbGl6ZWRfbmFtZSRfUmF3VmFsdWUoJG93bmluZ19tZXNzYWdlX2NsYXNzJCAqbWVzc2FnZSkge1xuIgorICAgICAgIiAgR1BCRGVzY3JpcHRvciAqZGVzY3JpcHRvciA9IFskb3duaW5nX21lc3NhZ2VfY2xhc3MkIGRlc2NyaXB0b3JdO1xuIgorICAgICAgIiAgR1BCRmllbGREZXNjcmlwdG9yICpmaWVsZCA9IFtkZXNjcmlwdG9yIGZpZWxkV2l0aE51bWJlcjokZmllbGRfbnVtYmVyX25hbWUkXTtcbiIKKyAgICAgICIgIHJldHVybiBHUEJHZXRNZXNzYWdlSW50MzJGaWVsZChtZXNzYWdlLCBmaWVsZCk7XG4iCisgICAgICAifVxuIgorICAgICAgIlxuIgorICAgICAgInZvaWQgU2V0JG93bmluZ19tZXNzYWdlX2NsYXNzJF8kY2FwaXRhbGl6ZWRfbmFtZSRfUmF3VmFsdWUoJG93bmluZ19tZXNzYWdlX2NsYXNzJCAqbWVzc2FnZSwgaW50MzJfdCB2YWx1ZSkge1xuIgorICAgICAgIiAgR1BCRGVzY3JpcHRvciAqZGVzY3JpcHRvciA9IFskb3duaW5nX21lc3NhZ2VfY2xhc3MkIGRlc2NyaXB0b3JdO1xuIgorICAgICAgIiAgR1BCRmllbGREZXNjcmlwdG9yICpmaWVsZCA9IFtkZXNjcmlwdG9yIGZpZWxkV2l0aE51bWJlcjokZmllbGRfbnVtYmVyX25hbWUkXTtcbiIKKyAgICAgICIgIEdQQlNldEludDMySXZhcldpdGhGaWVsZEludGVybmFsKG1lc3NhZ2UsIGZpZWxkLCB2YWx1ZSwgZGVzY3JpcHRvci5maWxlLnN5bnRheCk7XG4iCisgICAgICAifVxuIgorICAgICAgIlxuIik7Cit9CisKK3ZvaWQgRW51bUZpZWxkR2VuZXJhdG9yOjpEZXRlcm1pbmVGb3J3YXJkRGVjbGFyYXRpb25zKAorICAgIHNldDxzdHJpbmc+KiBmd2RfZGVjbHMpIGNvbnN0IHsKKyAgLy8gSWYgaXQgaXMgYW4gZW51bSBkZWZpbmVkIGluIGEgZGlmZmVyZW50IGZpbGUsIHRoZW4gd2UnbGwgbmVlZCBhIGZvcndhcmQKKyAgLy8gZGVjbGFyYXRpb24gZm9yIGl0LiAgV2hlbiBpdCBpcyBpbiBvdXIgZmlsZSwgYWxsIHRoZSBlbnVtcyBhcmUgb3V0cHV0CisgIC8vIGJlZm9yZSB0aGUgbWVzc2FnZSwgc28gaXQgd2lsbCBiZSBkZWNsYXJlZCBiZWZvcmUgaXQgaXMgbmVlZGVkLgorICBpZiAoZGVzY3JpcHRvcl8tPmZpbGUoKSAhPSBkZXNjcmlwdG9yXy0+ZW51bV90eXBlKCktPmZpbGUoKSkgeworICAgIC8vIEVudW0gbmFtZSBpcyBhbHJlYWR5IGluICJzdG9yYWdlX3R5cGUiLgorICAgIGNvbnN0IHN0cmluZyYgbmFtZSA9IHZhcmlhYmxlKCJzdG9yYWdlX3R5cGUiKTsKKyAgICBmd2RfZGVjbHMtPmluc2VydCgiR1BCX0VOVU1fRldEX0RFQ0xBUkUoIiArIG5hbWUgKyAiKSIpOworICB9Cit9CisKK1JlcGVhdGVkRW51bUZpZWxkR2VuZXJhdG9yOjpSZXBlYXRlZEVudW1GaWVsZEdlbmVyYXRvcigKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpCisgICAgOiBSZXBlYXRlZEZpZWxkR2VuZXJhdG9yKGRlc2NyaXB0b3IpIHsKKyAgU2V0RW51bVZhcmlhYmxlcyhkZXNjcmlwdG9yLCAmdmFyaWFibGVzXyk7CisgIHZhcmlhYmxlc19bImFycmF5X3N0b3JhZ2VfdHlwZSJdID0gIkdQQkVudW1BcnJheSI7Cit9CisKK1JlcGVhdGVkRW51bUZpZWxkR2VuZXJhdG9yOjp+UmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3IoKSB7fQorCit2b2lkIFJlcGVhdGVkRW51bUZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZUZpZWxkRGVzY3JpcHRpb25UeXBlU3BlY2lmaWMoCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICB2YXJpYWJsZXNfLAorICAgICAgIiAgLmRhdGFUeXBlU3BlY2lmaWMuZW51bURlc2NGdW5jID0gJGVudW1fZGVzY19mdW5jJCxcbiIpOworfQorCit9ICAvLyBuYW1lc3BhY2Ugb2JqZWN0aXZlYworfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX2VudW1fZmllbGQuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX2VudW1fZmllbGQuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNjI5ZWFlCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfZW51bV9maWVsZC5oCkBAIC0wLDAgKzEsNzggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9PQkpFQ1RJVkVDX0VOVU1fRklFTERfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9PQkpFQ1RJVkVDX0VOVU1fRklFTERfSF9fCisKKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfZmllbGQuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBvYmplY3RpdmVjIHsKKworY2xhc3MgRW51bUZpZWxkR2VuZXJhdG9yIDogcHVibGljIFNpbmdsZUZpZWxkR2VuZXJhdG9yIHsKKyAgZnJpZW5kIEZpZWxkR2VuZXJhdG9yKiBGaWVsZEdlbmVyYXRvcjo6TWFrZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKTsKKworIHB1YmxpYzoKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlRmllbGREZXNjcmlwdGlvblR5cGVTcGVjaWZpYyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZUNGdW5jdGlvbkRlY2xhcmF0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZUNGdW5jdGlvbkltcGxlbWVudGF0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZpcnR1YWwgdm9pZCBEZXRlcm1pbmVGb3J3YXJkRGVjbGFyYXRpb25zKHNldDxzdHJpbmc+KiBmd2RfZGVjbHMpIGNvbnN0OworCisgcHJvdGVjdGVkOgorICBleHBsaWNpdCBFbnVtRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKKyAgdmlydHVhbCB+RW51bUZpZWxkR2VuZXJhdG9yKCk7CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoRW51bUZpZWxkR2VuZXJhdG9yKTsKK307CisKK2NsYXNzIFJlcGVhdGVkRW51bUZpZWxkR2VuZXJhdG9yIDogcHVibGljIFJlcGVhdGVkRmllbGRHZW5lcmF0b3IgeworICBmcmllbmQgRmllbGRHZW5lcmF0b3IqIEZpZWxkR2VuZXJhdG9yOjpNYWtlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpOworCisgcHVibGljOgorICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVGaWVsZERlc2NyaXB0aW9uVHlwZVNwZWNpZmljKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKworIHByb3RlY3RlZDoKKyAgUmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKKyAgdmlydHVhbCB+UmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3IoKTsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhSZXBlYXRlZEVudW1GaWVsZEdlbmVyYXRvcik7Cit9OworCit9ICAvLyBuYW1lc3BhY2Ugb2JqZWN0aXZlYworfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX09CSkVDVElWRUNfRU5VTV9GSUVMRF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX2V4dGVuc2lvbi5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX2V4dGVuc2lvbi5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ZTM0ODM5Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfZXh0ZW5zaW9uLmNjCkBAIC0wLDAgKzEsMTM2IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2luY2x1ZGUgPGlvc3RyZWFtPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19leHRlbnNpb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBvYmplY3RpdmVjIHsKKworRXh0ZW5zaW9uR2VuZXJhdG9yOjpFeHRlbnNpb25HZW5lcmF0b3IoY29uc3Qgc3RyaW5nJiByb290X2NsYXNzX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpCisgICAgOiBtZXRob2RfbmFtZV8oRXh0ZW5zaW9uTWV0aG9kTmFtZShkZXNjcmlwdG9yKSksCisgICAgICByb290X2NsYXNzX2FuZF9tZXRob2RfbmFtZV8ocm9vdF9jbGFzc19uYW1lICsgIl8iICsgbWV0aG9kX25hbWVfKSwKKyAgICAgIGRlc2NyaXB0b3JfKGRlc2NyaXB0b3IpIHsKKyAgaWYgKGRlc2NyaXB0b3ItPmlzX21hcCgpKSB7CisgICAgLy8gTk9URTogc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wbHVnaW4uY2MgbWFrZXMgdXNlIG9mIGNlcnIgZm9yIHNvbWUKKyAgICAvLyBlcnJvciBjYXNlcywgc28gaXQgc2VlbXMgdG8gYmUgb2sgdG8gdXNlIGFzIGEgYmFjayBkb29yIGZvciBlcnJvcnMuCisgICAgY2VyciA8PCAiZXJyb3I6IEV4dGVuc2lvbiBpcyBhIG1hcDw+ISIKKyAgICAgICAgIDw8ICIgVGhhdCB1c2VkIHRvIGJlIGJsb2NrZWQgYnkgdGhlIGNvbXBpbGVyLiIgPDwgZW5kbDsKKyAgICBjZXJyLmZsdXNoKCk7CisgICAgYWJvcnQoKTsKKyAgfQorfQorCitFeHRlbnNpb25HZW5lcmF0b3I6On5FeHRlbnNpb25HZW5lcmF0b3IoKSB7fQorCit2b2lkIEV4dGVuc2lvbkdlbmVyYXRvcjo6R2VuZXJhdGVNZW1iZXJzSGVhZGVyKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyczsKKyAgdmFyc1sibWV0aG9kX25hbWUiXSA9IG1ldGhvZF9uYW1lXzsKKyAgU291cmNlTG9jYXRpb24gbG9jYXRpb247CisgIGlmIChkZXNjcmlwdG9yXy0+R2V0U291cmNlTG9jYXRpb24oJmxvY2F0aW9uKSkgeworICAgIHZhcnNbImNvbW1lbnRzIl0gPSBCdWlsZENvbW1lbnRzU3RyaW5nKGxvY2F0aW9uKTsKKyAgfSBlbHNlIHsKKyAgICB2YXJzWyJjb21tZW50cyJdID0gIiI7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQodmFycywKKyAgICAgICAgICAgICAgICAgIiRjb21tZW50cyQiCisgICAgICAgICAgICAgICAgICIrIChHUEJFeHRlbnNpb25EZXNjcmlwdG9yICopJG1ldGhvZF9uYW1lJDtcbiIpOworfQorCit2b2lkIEV4dGVuc2lvbkdlbmVyYXRvcjo6R2VuZXJhdGVTdGF0aWNWYXJpYWJsZXNJbml0aWFsaXphdGlvbigKKyAgICBpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcnM7CisgIHZhcnNbInJvb3RfY2xhc3NfYW5kX21ldGhvZF9uYW1lIl0gPSByb290X2NsYXNzX2FuZF9tZXRob2RfbmFtZV87CisgIHZhcnNbImV4dGVuZGVkX3R5cGUiXSA9IENsYXNzTmFtZShkZXNjcmlwdG9yXy0+Y29udGFpbmluZ190eXBlKCkpOworICB2YXJzWyJudW1iZXIiXSA9IFNpbXBsZUl0b2EoZGVzY3JpcHRvcl8tPm51bWJlcigpKTsKKworICBzdGQ6OnZlY3RvcjxzdHJpbmc+IG9wdGlvbnM7CisgIGlmIChkZXNjcmlwdG9yXy0+aXNfcmVwZWF0ZWQoKSkgb3B0aW9ucy5wdXNoX2JhY2soIkdQQkV4dGVuc2lvblJlcGVhdGVkIik7CisgIGlmIChkZXNjcmlwdG9yXy0+aXNfcGFja2VkKCkpIG9wdGlvbnMucHVzaF9iYWNrKCJHUEJFeHRlbnNpb25QYWNrZWQiKTsKKyAgaWYgKGRlc2NyaXB0b3JfLT5jb250YWluaW5nX3R5cGUoKS0+b3B0aW9ucygpLm1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KCkpCisgICAgb3B0aW9ucy5wdXNoX2JhY2soIkdQQkV4dGVuc2lvblNldFdpcmVGb3JtYXQiKTsKKworICB2YXJzWyJvcHRpb25zIl0gPSBCdWlsZEZsYWdzU3RyaW5nKG9wdGlvbnMpOworCisgIE9iamVjdGl2ZUNUeXBlIG9iamNfdHlwZSA9IEdldE9iamVjdGl2ZUNUeXBlKGRlc2NyaXB0b3JfKTsKKyAgc3RyaW5nIHNpbmd1bGFyX3R5cGU7CisgIGlmIChvYmpjX3R5cGUgPT0gT0JKRUNUSVZFQ1RZUEVfTUVTU0FHRSkgeworICAgIHZhcnNbInR5cGUiXSA9IHN0cmluZygiR1BCU3RyaW5naWZ5U3ltYm9sKCIpICsKKyAgICAgICAgICAgICAgICAgICBDbGFzc05hbWUoZGVzY3JpcHRvcl8tPm1lc3NhZ2VfdHlwZSgpKSArICIpIjsKKyAgfSBlbHNlIHsKKyAgICB2YXJzWyJ0eXBlIl0gPSAiTlVMTCI7CisgIH0KKworICB2YXJzWyJkZWZhdWx0X25hbWUiXSA9IEdQQkdlbmVyaWNWYWx1ZUZpZWxkTmFtZShkZXNjcmlwdG9yXyk7CisgIGlmIChkZXNjcmlwdG9yXy0+aXNfcmVwZWF0ZWQoKSkgeworICAgIHZhcnNbImRlZmF1bHQiXSA9ICJuaWwiOworICB9IGVsc2UgeworICAgIHZhcnNbImRlZmF1bHQiXSA9IERlZmF1bHRWYWx1ZShkZXNjcmlwdG9yXyk7CisgIH0KKyAgc3RyaW5nIHR5cGUgPSBHZXRDYXBpdGFsaXplZFR5cGUoZGVzY3JpcHRvcl8pOworICB2YXJzWyJleHRlbnNpb25fdHlwZSJdID0gc3RyaW5nKCJHUEJEYXRhVHlwZSIpICsgdHlwZTsKKworICBpZiAob2JqY190eXBlID09IE9CSkVDVElWRUNUWVBFX0VOVU0pIHsKKyAgICB2YXJzWyJlbnVtX2Rlc2NfZnVuY19uYW1lIl0gPQorICAgICAgICAgRW51bU5hbWUoZGVzY3JpcHRvcl8tPmVudW1fdHlwZSgpKSArICJfRW51bURlc2NyaXB0b3IiOworICB9IGVsc2UgeworICAgIHZhcnNbImVudW1fZGVzY19mdW5jX25hbWUiXSA9ICJOVUxMIjsKKyAgfQorCisgIHByaW50ZXItPlByaW50KHZhcnMsCisgICAgICAgICAgICAgICAgICJ7XG4iCisgICAgICAgICAgICAgICAgICIgIC5zaW5nbGV0b25OYW1lID0gR1BCU3RyaW5naWZ5U3ltYm9sKCRyb290X2NsYXNzX2FuZF9tZXRob2RfbmFtZSQpLFxuIgorICAgICAgICAgICAgICAgICAiICAuZGF0YVR5cGUgPSAkZXh0ZW5zaW9uX3R5cGUkLFxuIgorICAgICAgICAgICAgICAgICAiICAuZXh0ZW5kZWRDbGFzcyA9IEdQQlN0cmluZ2lmeVN5bWJvbCgkZXh0ZW5kZWRfdHlwZSQpLFxuIgorICAgICAgICAgICAgICAgICAiICAuZmllbGROdW1iZXIgPSAkbnVtYmVyJCxcbiIKKyAgICAgICAgICAgICAgICAgIiAgLmRlZmF1bHRWYWx1ZS4kZGVmYXVsdF9uYW1lJCA9ICRkZWZhdWx0JCxcbiIKKyAgICAgICAgICAgICAgICAgIiAgLm1lc3NhZ2VPckdyb3VwQ2xhc3NOYW1lID0gJHR5cGUkLFxuIgorICAgICAgICAgICAgICAgICAiICAub3B0aW9ucyA9ICRvcHRpb25zJCxcbiIKKyAgICAgICAgICAgICAgICAgIiAgLmVudW1EZXNjcmlwdG9yRnVuYyA9ICRlbnVtX2Rlc2NfZnVuY19uYW1lJCxcbiIKKyAgICAgICAgICAgICAgICAgIn0sXG4iKTsKK30KKwordm9pZCBFeHRlbnNpb25HZW5lcmF0b3I6OkdlbmVyYXRlUmVnaXN0cmF0aW9uU291cmNlKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgICAgIltyZWdpc3RyeSBhZGRFeHRlbnNpb246JHJvb3RfY2xhc3NfYW5kX21ldGhvZF9uYW1lJF07XG4iLAorICAgICAgInJvb3RfY2xhc3NfYW5kX21ldGhvZF9uYW1lIiwgcm9vdF9jbGFzc19hbmRfbWV0aG9kX25hbWVfKTsKK30KK30gIC8vIG5hbWVzcGFjZSBvYmplY3RpdmVjCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfZXh0ZW5zaW9uLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19leHRlbnNpb24uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMzYxZTYzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfZXh0ZW5zaW9uLmgKQEAgLTAsMCArMSw2OSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX09CSkVDVElWRUNfRVhURU5TSU9OX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfT0JKRUNUSVZFQ19FWFRFTlNJT05fSF9fCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK2NsYXNzIEZpZWxkRGVzY3JpcHRvcjsgIC8vIGRlc2NyaXB0b3IuaAorbmFtZXNwYWNlIGlvIHsKK2NsYXNzIFByaW50ZXI7ICAvLyBwcmludGVyLmgKK30KK30KKworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2Ugb2JqZWN0aXZlYyB7CisKK2NsYXNzIEV4dGVuc2lvbkdlbmVyYXRvciB7CisgcHVibGljOgorICBFeHRlbnNpb25HZW5lcmF0b3IoY29uc3Qgc3RyaW5nJiByb290X2NsYXNzX25hbWUsCisgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworICB+RXh0ZW5zaW9uR2VuZXJhdG9yKCk7CisKKyAgdm9pZCBHZW5lcmF0ZU1lbWJlcnNIZWFkZXIoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2b2lkIEdlbmVyYXRlU3RhdGljVmFyaWFibGVzSW5pdGlhbGl6YXRpb24oaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2b2lkIEdlbmVyYXRlUmVnaXN0cmF0aW9uU291cmNlKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworIHByaXZhdGU6CisgIHN0cmluZyBtZXRob2RfbmFtZV87CisgIHN0cmluZyByb290X2NsYXNzX2FuZF9tZXRob2RfbmFtZV87CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcl87CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEV4dGVuc2lvbkdlbmVyYXRvcik7Cit9OworfSAgLy8gbmFtZXNwYWNlIG9iamVjdGl2ZWMKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9PQkpFQ1RJVkVDX01FU1NBR0VfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19maWVsZC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX2ZpZWxkLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNmNWQ4Y2YKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19maWVsZC5jYwpAQCAtMCwwICsxLDQzNCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19lbnVtX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19tYXBfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX21lc3NhZ2VfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX3ByaW1pdGl2ZV9maWVsZC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2Ugb2JqZWN0aXZlYyB7CisKK25hbWVzcGFjZSB7Cit2b2lkIFNldENvbW1vbkZpZWxkVmFyaWFibGVzKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwPHN0cmluZywgc3RyaW5nPiogdmFyaWFibGVzKSB7CisgIHN0cmluZyBjYW1lbF9jYXNlX25hbWUgPSBGaWVsZE5hbWUoZGVzY3JpcHRvcik7CisgIHN0cmluZyByYXdfZmllbGRfbmFtZTsKKyAgaWYgKGRlc2NyaXB0b3ItPnR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfR1JPVVApIHsKKyAgICByYXdfZmllbGRfbmFtZSA9IGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpLT5uYW1lKCk7CisgIH0gZWxzZSB7CisgICAgcmF3X2ZpZWxkX25hbWUgPSBkZXNjcmlwdG9yLT5uYW1lKCk7CisgIH0KKyAgLy8gVGhlIGxvZ2ljIGhlcmUgaGFzIHRvIG1hdGNoIC1bR0dQQkZpZWxkRGVzY3JpcHRvciB0ZXh0Rm9ybWF0TmFtZV0uCisgIGNvbnN0IHN0cmluZyB1bl9jYW1lbF9jYXNlX25hbWUoCisgICAgICBVbkNhbWVsQ2FzZUZpZWxkTmFtZShjYW1lbF9jYXNlX25hbWUsIGRlc2NyaXB0b3IpKTsKKyAgY29uc3QgYm9vbCBuZWVkc19jdXN0b21fbmFtZSA9IChyYXdfZmllbGRfbmFtZSAhPSB1bl9jYW1lbF9jYXNlX25hbWUpOworCisgIFNvdXJjZUxvY2F0aW9uIGxvY2F0aW9uOworICBpZiAoZGVzY3JpcHRvci0+R2V0U291cmNlTG9jYXRpb24oJmxvY2F0aW9uKSkgeworICAgICgqdmFyaWFibGVzKVsiY29tbWVudHMiXSA9IEJ1aWxkQ29tbWVudHNTdHJpbmcobG9jYXRpb24pOworICB9IGVsc2UgeworICAgICgqdmFyaWFibGVzKVsiY29tbWVudHMiXSA9ICJcbiI7CisgIH0KKyAgY29uc3Qgc3RyaW5nJiBjbGFzc25hbWUgPSBDbGFzc05hbWUoZGVzY3JpcHRvci0+Y29udGFpbmluZ190eXBlKCkpOworICAoKnZhcmlhYmxlcylbImNsYXNzbmFtZSJdID0gY2xhc3NuYW1lOworICAoKnZhcmlhYmxlcylbIm5hbWUiXSA9IGNhbWVsX2Nhc2VfbmFtZTsKKyAgY29uc3Qgc3RyaW5nJiBjYXBpdGFsaXplZF9uYW1lID0gRmllbGROYW1lQ2FwaXRhbGl6ZWQoZGVzY3JpcHRvcik7CisgICgqdmFyaWFibGVzKVsiY2FwaXRhbGl6ZWRfbmFtZSJdID0gY2FwaXRhbGl6ZWRfbmFtZTsKKyAgKCp2YXJpYWJsZXMpWyJyYXdfZmllbGRfbmFtZSJdID0gcmF3X2ZpZWxkX25hbWU7CisgICgqdmFyaWFibGVzKVsiZmllbGRfbnVtYmVyX25hbWUiXSA9CisgICAgICBjbGFzc25hbWUgKyAiX0ZpZWxkTnVtYmVyXyIgKyBjYXBpdGFsaXplZF9uYW1lOworICAoKnZhcmlhYmxlcylbImZpZWxkX251bWJlciJdID0gU2ltcGxlSXRvYShkZXNjcmlwdG9yLT5udW1iZXIoKSk7CisgICgqdmFyaWFibGVzKVsiaGFzX2luZGV4Il0gPSBTaW1wbGVJdG9hKGRlc2NyaXB0b3ItPmluZGV4KCkpOworICAoKnZhcmlhYmxlcylbImZpZWxkX3R5cGUiXSA9IEdldENhcGl0YWxpemVkVHlwZShkZXNjcmlwdG9yKTsKKyAgc3RkOjp2ZWN0b3I8c3RyaW5nPiBmaWVsZF9mbGFnczsKKyAgaWYgKGRlc2NyaXB0b3ItPmlzX3JlcGVhdGVkKCkpIGZpZWxkX2ZsYWdzLnB1c2hfYmFjaygiR1BCRmllbGRSZXBlYXRlZCIpOworICBpZiAoZGVzY3JpcHRvci0+aXNfcmVxdWlyZWQoKSkgZmllbGRfZmxhZ3MucHVzaF9iYWNrKCJHUEJGaWVsZFJlcXVpcmVkIik7CisgIGlmIChkZXNjcmlwdG9yLT5pc19vcHRpb25hbCgpKSBmaWVsZF9mbGFncy5wdXNoX2JhY2soIkdQQkZpZWxkT3B0aW9uYWwiKTsKKyAgaWYgKGRlc2NyaXB0b3ItPmlzX3BhY2tlZCgpKSBmaWVsZF9mbGFncy5wdXNoX2JhY2soIkdQQkZpZWxkUGFja2VkIik7CisKKyAgLy8gT2JqQyBjdXN0b20gZmxhZ3MuCisgIGlmIChkZXNjcmlwdG9yLT5oYXNfZGVmYXVsdF92YWx1ZSgpKQorICAgIGZpZWxkX2ZsYWdzLnB1c2hfYmFjaygiR1BCRmllbGRIYXNEZWZhdWx0VmFsdWUiKTsKKyAgaWYgKG5lZWRzX2N1c3RvbV9uYW1lKSBmaWVsZF9mbGFncy5wdXNoX2JhY2soIkdQQkZpZWxkVGV4dEZvcm1hdE5hbWVDdXN0b20iKTsKKyAgaWYgKGRlc2NyaXB0b3ItPnR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRU5VTSkgeworICAgIGZpZWxkX2ZsYWdzLnB1c2hfYmFjaygiR1BCRmllbGRIYXNFbnVtRGVzY3JpcHRvciIpOworICB9CisKKyAgKCp2YXJpYWJsZXMpWyJmaWVsZGZsYWdzIl0gPSBCdWlsZEZsYWdzU3RyaW5nKGZpZWxkX2ZsYWdzKTsKKworICAoKnZhcmlhYmxlcylbImRlZmF1bHQiXSA9IERlZmF1bHRWYWx1ZShkZXNjcmlwdG9yKTsKKyAgKCp2YXJpYWJsZXMpWyJkZWZhdWx0X25hbWUiXSA9IEdQQkdlbmVyaWNWYWx1ZUZpZWxkTmFtZShkZXNjcmlwdG9yKTsKKworICAoKnZhcmlhYmxlcylbImRhdGFUeXBlU3BlY2lmaWNfbmFtZSJdID0gImNsYXNzTmFtZSI7CisgICgqdmFyaWFibGVzKVsiZGF0YVR5cGVTcGVjaWZpY192YWx1ZSJdID0gIk5VTEwiOworCisgIHN0cmluZyBmaWVsZF9vcHRpb25zID0gZGVzY3JpcHRvci0+b3B0aW9ucygpLlNlcmlhbGl6ZUFzU3RyaW5nKCk7CisgIC8vIE11c3QgY29udmVydCB0byBhIHN0YW5kYXJkIGJ5dGUgb3JkZXIgZm9yIHBhY2tpbmcgbGVuZ3RoIGludG8KKyAgLy8gYSBjc3RyaW5nLgorICB1aW50MzIgbGVuZ3RoID0gZ2h0b25sKGZpZWxkX29wdGlvbnMubGVuZ3RoKCkpOworICBpZiAobGVuZ3RoID4gMCkgeworICAgIHN0cmluZyBieXRlcygoY29uc3QgY2hhciopJmxlbmd0aCwgc2l6ZW9mKGxlbmd0aCkpOworICAgIGJ5dGVzLmFwcGVuZChmaWVsZF9vcHRpb25zKTsKKyAgICBzdHJpbmcgb3B0aW9uc19zdHIgPSAiXCIiICsgQ0VzY2FwZShieXRlcykgKyAiXCIiOworICAgICgqdmFyaWFibGVzKVsiZmllbGRvcHRpb25zIl0gPSAiXCIiICsgQ0VzY2FwZShieXRlcykgKyAiXCIiOworICB9IGVsc2UgeworICAgICgqdmFyaWFibGVzKVsiZmllbGRvcHRpb25zIl0gPSAiIjsKKyAgfQorCisgIC8vIENsZWFyIHNvbWUgY29tbW9uIHRoaW5ncyBzbyB0aGV5IGNhbiBiZSBzZXQganVzdCB3aGVuIG5lZWRlZC4KKyAgKCp2YXJpYWJsZXMpWyJzdG9yYWdlX2F0dHJpYnV0ZSJdID0gIiI7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCitGaWVsZEdlbmVyYXRvciogRmllbGRHZW5lcmF0b3I6Ok1ha2UoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICBGaWVsZEdlbmVyYXRvciogcmVzdWx0ID0gTlVMTDsKKyAgaWYgKGZpZWxkLT5pc19yZXBlYXRlZCgpKSB7CisgICAgc3dpdGNoIChHZXRPYmplY3RpdmVDVHlwZShmaWVsZCkpIHsKKyAgICAgIGNhc2UgT0JKRUNUSVZFQ1RZUEVfTUVTU0FHRTogeworICAgICAgICBpZiAoZmllbGQtPmlzX21hcCgpKSB7CisgICAgICAgICAgcmVzdWx0ID0gbmV3IE1hcEZpZWxkR2VuZXJhdG9yKGZpZWxkKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICByZXN1bHQgPSBuZXcgUmVwZWF0ZWRNZXNzYWdlRmllbGRHZW5lcmF0b3IoZmllbGQpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgY2FzZSBPQkpFQ1RJVkVDVFlQRV9FTlVNOgorICAgICAgICByZXN1bHQgPSBuZXcgUmVwZWF0ZWRFbnVtRmllbGRHZW5lcmF0b3IoZmllbGQpOworICAgICAgICBicmVhazsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHJlc3VsdCA9IG5ldyBSZXBlYXRlZFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKGZpZWxkKTsKKyAgICAgICAgYnJlYWs7CisgICAgfQorICB9IGVsc2UgeworICAgIHN3aXRjaCAoR2V0T2JqZWN0aXZlQ1R5cGUoZmllbGQpKSB7CisgICAgICBjYXNlIE9CSkVDVElWRUNUWVBFX01FU1NBR0U6IHsKKyAgICAgICAgcmVzdWx0ID0gbmV3IE1lc3NhZ2VGaWVsZEdlbmVyYXRvcihmaWVsZCk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgY2FzZSBPQkpFQ1RJVkVDVFlQRV9FTlVNOgorICAgICAgICByZXN1bHQgPSBuZXcgRW51bUZpZWxkR2VuZXJhdG9yKGZpZWxkKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBkZWZhdWx0OgorICAgICAgICBpZiAoSXNSZWZlcmVuY2VUeXBlKGZpZWxkKSkgeworICAgICAgICAgIHJlc3VsdCA9IG5ldyBQcmltaXRpdmVPYmpGaWVsZEdlbmVyYXRvcihmaWVsZCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgcmVzdWx0ID0gbmV3IFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKGZpZWxkKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICB9CisgIH0KKyAgcmVzdWx0LT5GaW5pc2hJbml0aWFsaXphdGlvbigpOworICByZXR1cm4gcmVzdWx0OworfQorCisKK0ZpZWxkR2VuZXJhdG9yOjpGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpCisgICAgOiBkZXNjcmlwdG9yXyhkZXNjcmlwdG9yKSB7CisgIFNldENvbW1vbkZpZWxkVmFyaWFibGVzKGRlc2NyaXB0b3IsICZ2YXJpYWJsZXNfKTsKK30KKworRmllbGRHZW5lcmF0b3I6On5GaWVsZEdlbmVyYXRvcigpIHt9CisKK3ZvaWQgRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlRmllbGROdW1iZXJDb25zdGFudChpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCgKKyAgICAgIHZhcmlhYmxlc18sCisgICAgICAiJGZpZWxkX251bWJlcl9uYW1lJCA9ICRmaWVsZF9udW1iZXIkLFxuIik7Cit9CisKK3ZvaWQgRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlQ0Z1bmN0aW9uRGVjbGFyYXRpb25zKAorICAgIGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIE5vdGhpbmcKK30KKwordm9pZCBGaWVsZEdlbmVyYXRvcjo6R2VuZXJhdGVDRnVuY3Rpb25JbXBsZW1lbnRhdGlvbnMoCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgLy8gTm90aGluZworfQorCit2b2lkIEZpZWxkR2VuZXJhdG9yOjpEZXRlcm1pbmVGb3J3YXJkRGVjbGFyYXRpb25zKAorICAgIHNldDxzdHJpbmc+KiBmd2RfZGVjbHMpIGNvbnN0IHsKKyAgLy8gTm90aGluZworfQorCit2b2lkIEZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZUZpZWxkRGVzY3JpcHRpb24oCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICB2YXJpYWJsZXNfLAorICAgICAgIntcbiIKKyAgICAgICIgIC5uYW1lID0gXCIkbmFtZSRcIixcbiIKKyAgICAgICIgIC5udW1iZXIgPSAkZmllbGRfbnVtYmVyX25hbWUkLFxuIgorICAgICAgIiAgLmhhc0luZGV4ID0gJGhhc19pbmRleCQsXG4iCisgICAgICAiICAuZmxhZ3MgPSAkZmllbGRmbGFncyQsXG4iCisgICAgICAiICAuZGF0YVR5cGUgPSBHUEJEYXRhVHlwZSRmaWVsZF90eXBlJCxcbiIKKyAgICAgICIgIC5vZmZzZXQgPSBvZmZzZXRvZigkY2xhc3NuYW1lJF9fc3RvcmFnZV8sICRuYW1lJCksXG4iCisgICAgICAiICAuZGVmYXVsdFZhbHVlLiRkZWZhdWx0X25hbWUkID0gJGRlZmF1bHQkLFxuIik7CisKKyAgLy8gVE9ETyh0aG9tYXN2bCk6IEl0IG1pZ2h0IGJlIHVzZWZ1bCB0byBhZGQgYSBDUFAgd3JhcHBlciB0byBzdXBwb3J0CisgIC8vIGNvbXBpbGluZyBhd2F5IHRoZSBFbnVtRGVzY3JpcHRvcnMuICBUbyBkbyB0aGF0LCB3ZSdkIG5lZWQgYSAjaWYgaGVyZQorICAvLyB0byBjb250cm9sIHNldHRpbmcgdGhlIGRlc2NyaXB0b3IgdnMuIHRoZSB2YWxpZGF0b3IsIGFuZCBhYm92ZSBpbgorICAvLyBTZXRDb21tb25GaWVsZFZhcmlhYmxlcygpIHdlJ2Qgd2FudCB0byB3cmFwIGhvdyB3ZSBhZGQKKyAgLy8gR1BCRmllbGRIYXNEZWZhdWx0VmFsdWUgdG8gdGhlIGZsYWdzLgorCisgIC8vICIgIC5kYXRhVHlwZVNwZWNpZmljLnZhbHVlKiA9IFtzb21ldGhpbmddLCIKKyAgR2VuZXJhdGVGaWVsZERlc2NyaXB0aW9uVHlwZVNwZWNpZmljKHByaW50ZXIpOworCisgIGNvbnN0IHN0cmluZyYgZmllbGRfb3B0aW9ucyh2YXJpYWJsZXNfLmZpbmQoImZpZWxkb3B0aW9ucyIpLT5zZWNvbmQpOworICBpZiAoZmllbGRfb3B0aW9ucy5lbXB0eSgpKSB7CisgICAgcHJpbnRlci0+UHJpbnQoIiAgLmZpZWxkT3B0aW9ucyA9IE5VTEwsXG4iKTsKKyAgfSBlbHNlIHsKKyAgICAvLyBDYW4ndCB1c2UgUHJpbnRSYXcoKSBoZXJlIHRvIGdldCB0aGUgI2lmLyNlbHNlLyNlbmRpZiBsaW5lcyBjb21wbGV0ZWx5CisgICAgLy8gb3V0ZGVudGVkIGJlY2F1c2UgdGhlIG5lZWQgZm9yIGluZGVudCBjYXB0dXJlZCBvbiB0aGUgcHJldmlvdXMKKyAgICAvLyBwcmludGluZyBvZiBhIFxuIGFuZCB0aGVyZSBpcyBubyB3YXkgdG8gZ2V0IHRoZSBjdXJyZW50IGluZGVudCBsZXZlbAorICAgIC8vIHRvIGNhbGwgdGhlIHJpZ2h0IG51bWJlciBvZiBPdXRkZW50KCkvSW5kZW50cygpIHRvIG1haW50YWluIHN0YXRlLgorICAgIHByaW50ZXItPlByaW50KAorICAgICAgICB2YXJpYWJsZXNfLAorICAgICAgICAiI2lmIEdQQk9CSkNfSU5DTFVERV9GSUVMRF9PUFRJT05TXG4iCisgICAgICAgICIgIC5maWVsZE9wdGlvbnMgPSAkZmllbGRvcHRpb25zJCxcbiIKKyAgICAgICAgIiNlbHNlXG4iCisgICAgICAgICIgIC5maWVsZE9wdGlvbnMgPSBOVUxMLFxuIgorICAgICAgICAiI2VuZGlmICAvLyBHUEJPQkpDX0lOQ0xVREVfRklFTERfT1BUSU9OU1xuIik7CisgIH0KKworICBwcmludGVyLT5QcmludCgifSxcbiIpOworfQorCit2b2lkIEZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZUZpZWxkRGVzY3JpcHRpb25UeXBlU3BlY2lmaWMoCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICB2YXJpYWJsZXNfLAorICAgICAgIiAgLmRhdGFUeXBlU3BlY2lmaWMuJGRhdGFUeXBlU3BlY2lmaWNfbmFtZSQgPSAkZGF0YVR5cGVTcGVjaWZpY192YWx1ZSQsXG4iKTsKK30KKwordm9pZCBGaWVsZEdlbmVyYXRvcjo6U2V0T25lb2ZJbmRleEJhc2UoaW50IGluZGV4X2Jhc2UpIHsKKyAgaWYgKGRlc2NyaXB0b3JfLT5jb250YWluaW5nX29uZW9mKCkgIT0gTlVMTCkgeworICAgIGludCBpbmRleCA9IGRlc2NyaXB0b3JfLT5jb250YWluaW5nX29uZW9mKCktPmluZGV4KCkgKyBpbmRleF9iYXNlOworICAgIC8vIEZsaXAgdGhlIHNpZ24gdG8gbWFyayBpdCBhcyBhIG9uZW9mLgorICAgIHZhcmlhYmxlc19bImhhc19pbmRleCJdID0gU2ltcGxlSXRvYSgtaW5kZXgpOworICB9Cit9CisKK3ZvaWQgRmllbGRHZW5lcmF0b3I6OkZpbmlzaEluaXRpYWxpemF0aW9uKHZvaWQpIHsKKyAgLy8gSWYgInByb3BlcnR5X3R5cGUiIHdhc24ndCBzZXQsIG1ha2UgaXQgInN0b3JhZ2VfdHlwZSIuCisgIGlmICgodmFyaWFibGVzXy5maW5kKCJwcm9wZXJ0eV90eXBlIikgPT0gdmFyaWFibGVzXy5lbmQoKSkgJiYKKyAgICAgICh2YXJpYWJsZXNfLmZpbmQoInN0b3JhZ2VfdHlwZSIpICE9IHZhcmlhYmxlc18uZW5kKCkpKSB7CisgICAgdmFyaWFibGVzX1sicHJvcGVydHlfdHlwZSJdID0gdmFyaWFibGUoInN0b3JhZ2VfdHlwZSIpOworICB9Cit9CisKK1NpbmdsZUZpZWxkR2VuZXJhdG9yOjpTaW5nbGVGaWVsZEdlbmVyYXRvcigKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpCisgICAgOiBGaWVsZEdlbmVyYXRvcihkZXNjcmlwdG9yKSB7CisgIC8vIE5vdGhpbmcKK30KKworU2luZ2xlRmllbGRHZW5lcmF0b3I6On5TaW5nbGVGaWVsZEdlbmVyYXRvcigpIHt9CisKK3ZvaWQgU2luZ2xlRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlRmllbGRTdG9yYWdlRGVjbGFyYXRpb24oCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgIiRzdG9yYWdlX3R5cGUkICRuYW1lJDtcbiIpOworfQorCit2b2lkIFNpbmdsZUZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZVByb3BlcnR5RGVjbGFyYXRpb24oCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgIiRjb21tZW50cyQiKTsKKyAgaWYgKFdhbnRzSGFzUHJvcGVydHkoKSkgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICB2YXJpYWJsZXNfLAorICAgICAgICAiQHByb3BlcnR5KG5vbmF0b21pYywgcmVhZHdyaXRlKSBCT09MIGhhcyRjYXBpdGFsaXplZF9uYW1lJDtcbiIpOworICB9CisgIHByaW50ZXItPlByaW50KAorICAgICAgdmFyaWFibGVzXywKKyAgICAgICJAcHJvcGVydHkobm9uYXRvbWljLCByZWFkd3JpdGUpICRwcm9wZXJ0eV90eXBlJCAkbmFtZSQ7XG4iCisgICAgICAiXG4iKTsKK30KKwordm9pZCBTaW5nbGVGaWVsZEdlbmVyYXRvcjo6R2VuZXJhdGVQcm9wZXJ0eUltcGxlbWVudGF0aW9uKAorICAgIGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIGlmIChXYW50c0hhc1Byb3BlcnR5KCkpIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAiQGR5bmFtaWMgaGFzJGNhcGl0YWxpemVkX25hbWUkLCAkbmFtZSQ7XG4iKTsKKyAgfSBlbHNlIHsKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAiQGR5bmFtaWMgJG5hbWUkO1xuIik7CisgIH0KK30KKworYm9vbCBTaW5nbGVGaWVsZEdlbmVyYXRvcjo6V2FudHNIYXNQcm9wZXJ0eSh2b2lkKSBjb25zdCB7CisgIGlmIChkZXNjcmlwdG9yXy0+Y29udGFpbmluZ19vbmVvZigpICE9IE5VTEwpIHsKKyAgICAvLyBJZiBpbiBhIG9uZW9mLCBpdCB1c2VzIHRoZSBvbmVvZmNhc2UgaW5zdGVhZCBvZiBhIGhhcyBiaXQuCisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIGlmIChIYXNGaWVsZFByZXNlbmNlKGRlc2NyaXB0b3JfLT5maWxlKCkpKSB7CisgICAgLy8gSW4gcHJvdG8xL3Byb3RvMiwgZXZlcnkgZmllbGQgaGFzIGEgaGFzXyRuYW1lJCgpIG1ldGhvZC4KKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorICByZXR1cm4gZmFsc2U7Cit9CisKK09iakNPYmpGaWVsZEdlbmVyYXRvcjo6T2JqQ09iakZpZWxkR2VuZXJhdG9yKAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcikKKyAgICA6IFNpbmdsZUZpZWxkR2VuZXJhdG9yKGRlc2NyaXB0b3IpIHsKKyAgdmFyaWFibGVzX1sicHJvcGVydHlfc3RvcmFnZV9hdHRyaWJ1dGUiXSA9ICJzdHJvbmciOworICBpZiAoSXNSZXRhaW5lZE5hbWUodmFyaWFibGVzX1sibmFtZSJdKSkgeworICAgIHZhcmlhYmxlc19bInN0b3JhZ2VfYXR0cmlidXRlIl0gPSAiIE5TX1JFVFVSTlNfTk9UX1JFVEFJTkVEIjsKKyAgfQorfQorCitPYmpDT2JqRmllbGRHZW5lcmF0b3I6On5PYmpDT2JqRmllbGRHZW5lcmF0b3IoKSB7fQorCit2b2lkIE9iakNPYmpGaWVsZEdlbmVyYXRvcjo6R2VuZXJhdGVGaWVsZFN0b3JhZ2VEZWNsYXJhdGlvbigKKyAgICBpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgeworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAiJHN0b3JhZ2VfdHlwZSQgKiRuYW1lJDtcbiIpOworfQorCit2b2lkIE9iakNPYmpGaWVsZEdlbmVyYXRvcjo6R2VuZXJhdGVQcm9wZXJ0eURlY2xhcmF0aW9uKAorICAgIGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisKKyAgLy8gRGlmZmVycyBmcm9tIFNpbmdsZUZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZVByb3BlcnR5RGVjbGFyYXRpb24oKSBpbiB0aGF0CisgIC8vIGl0IHVzZXMgcG9pbnRlcnMgYW5kIGRlYWxzIHdpdGggT2JqZWN0aXZlIEMncyBydWxlcyBhcm91bmQgc3RvcmFnZSBuYW1lCisgIC8vIGNvbnZlbnRpb25zIChpbml0KiwgbmV3KiwgZXRjLikKKworICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLCAiJGNvbW1lbnRzJCIpOworICBpZiAoV2FudHNIYXNQcm9wZXJ0eSgpKSB7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgIHZhcmlhYmxlc18sCisgICAgICAgICJAcHJvcGVydHkobm9uYXRvbWljLCByZWFkd3JpdGUpIEJPT0wgaGFzJGNhcGl0YWxpemVkX25hbWUkO1xuIik7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICB2YXJpYWJsZXNfLAorICAgICAgIkBwcm9wZXJ0eShub25hdG9taWMsIHJlYWR3cml0ZSwgJHByb3BlcnR5X3N0b3JhZ2VfYXR0cmlidXRlJCwgbnVsbF9yZXNldHRhYmxlKSAkcHJvcGVydHlfdHlwZSQgKiRuYW1lJCRzdG9yYWdlX2F0dHJpYnV0ZSQ7XG4iKTsKKyAgaWYgKElzSW5pdE5hbWUodmFyaWFibGVzXy5maW5kKCJuYW1lIiktPnNlY29uZCkpIHsKKyAgICAvLyBJZiBwcm9wZXJ0eSBuYW1lIHN0YXJ0cyB3aXRoIGluaXQgd2UgbmVlZCB0byBhbm5vdGF0ZSBpdCB0byBnZXQgcGFzdCBBUkMuCisgICAgLy8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8xODcyMzIyNi9ob3ctZG8taS1hbm5vdGF0ZS1hbi1vYmplY3RpdmUtYy1wcm9wZXJ0eS13aXRoLWFuLW9iamMtbWV0aG9kLWZhbWlseS8xODcyMzIyNyMxODcyMzIyNworICAgIHByaW50ZXItPlByaW50KHZhcmlhYmxlc18sCisgICAgICAgICAgICAgICAgICAgIi0gKCRwcm9wZXJ0eV90eXBlJCAqKSRuYW1lJCBHUEJfTUVUSE9EX0ZBTUlMWV9OT05FO1xuIik7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQoIlxuIik7Cit9CisKK1JlcGVhdGVkRmllbGRHZW5lcmF0b3I6OlJlcGVhdGVkRmllbGRHZW5lcmF0b3IoCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yKQorICAgIDogT2JqQ09iakZpZWxkR2VuZXJhdG9yKGRlc2NyaXB0b3IpIHsKKyAgLy8gUmVwZWF0ZWQgZmllbGRzIGRvbid0IHVzZSB0aGUgaGFzIGluZGV4LgorICB2YXJpYWJsZXNfWyJoYXNfaW5kZXgiXSA9ICJHUEJOb0hhc0JpdCI7Cit9CisKK1JlcGVhdGVkRmllbGRHZW5lcmF0b3I6On5SZXBlYXRlZEZpZWxkR2VuZXJhdG9yKCkge30KKwordm9pZCBSZXBlYXRlZEZpZWxkR2VuZXJhdG9yOjpGaW5pc2hJbml0aWFsaXphdGlvbih2b2lkKSB7CisgIEZpZWxkR2VuZXJhdG9yOjpGaW5pc2hJbml0aWFsaXphdGlvbigpOworICB2YXJpYWJsZXNfWyJhcnJheV9jb21tZW50Il0gPQorICAgICAgIi8vIHwiICsgdmFyaWFibGVzX1sibmFtZSJdICsgInwgY29udGFpbnMgfCIgKyB2YXJpYWJsZXNfWyJzdG9yYWdlX3R5cGUiXSArICJ8XG4iOworfQorCit2b2lkIFJlcGVhdGVkRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlRmllbGRTdG9yYWdlRGVjbGFyYXRpb24oCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgIiRhcnJheV9zdG9yYWdlX3R5cGUkICokbmFtZSQ7XG4iKTsKK30KKwordm9pZCBSZXBlYXRlZEZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZVByb3BlcnR5SW1wbGVtZW50YXRpb24oCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0IHsKKyAgcHJpbnRlci0+UHJpbnQodmFyaWFibGVzXywgIkBkeW5hbWljICRuYW1lJCwgJG5hbWUkX0NvdW50O1xuIik7Cit9CisKK3ZvaWQgUmVwZWF0ZWRGaWVsZEdlbmVyYXRvcjo6R2VuZXJhdGVQcm9wZXJ0eURlY2xhcmF0aW9uKAorICAgIGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisKKyAgLy8gUmVwZWF0ZWQgZmllbGRzIGRvbid0IG5lZWQgdGhlIGhhcyogcHJvcGVydGllcywgYnV0IHRoZXkgZG8gZXhwb3NlIGEKKyAgLy8gKkNvdW50ICh0byBjaGVjayB3aXRob3V0IGF1dG9jcmVhdGlvbikuICBTbyBmb3IgdGhlIGZpZWxkIHByb3BlcnR5IHdlIG5lZWQKKyAgLy8gdGhlIHNhbWUgbG9naWMgYXMgT2JqQ09iakZpZWxkR2VuZXJhdG9yOjpHZW5lcmF0ZVByb3BlcnR5RGVjbGFyYXRpb24oKSBmb3IKKyAgLy8gZGVhbGluZyB3aXRoIG5lZWRpbmcgT2JqZWN0aXZlIEMncyBydWxlcyBhcm91bmQgc3RvcmFnZSBuYW1lIGNvbnZlbnRpb25zCisgIC8vIChpbml0KiwgbmV3KiwgZXRjLikKKworICBwcmludGVyLT5QcmludCgKKyAgICAgIHZhcmlhYmxlc18sCisgICAgICAiJGNvbW1lbnRzJCIKKyAgICAgICIkYXJyYXlfY29tbWVudCQiCisgICAgICAiQHByb3BlcnR5KG5vbmF0b21pYywgcmVhZHdyaXRlLCBzdHJvbmcsIG51bGxfcmVzZXR0YWJsZSkgJGFycmF5X3N0b3JhZ2VfdHlwZSQgKiRuYW1lJCRzdG9yYWdlX2F0dHJpYnV0ZSQ7XG4iCisgICAgICAiQHByb3BlcnR5KG5vbmF0b21pYywgcmVhZG9ubHkpIE5TVUludGVnZXIgJG5hbWUkX0NvdW50O1xuIik7CisgIGlmIChJc0luaXROYW1lKHZhcmlhYmxlc18uZmluZCgibmFtZSIpLT5zZWNvbmQpKSB7CisgICAgLy8gSWYgcHJvcGVydHkgbmFtZSBzdGFydHMgd2l0aCBpbml0IHdlIG5lZWQgdG8gYW5ub3RhdGUgaXQgdG8gZ2V0IHBhc3QgQVJDLgorICAgIC8vIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTg3MjMyMjYvaG93LWRvLWktYW5ub3RhdGUtYW4tb2JqZWN0aXZlLWMtcHJvcGVydHktd2l0aC1hbi1vYmpjLW1ldGhvZC1mYW1pbHkvMTg3MjMyMjcjMTg3MjMyMjcKKyAgICBwcmludGVyLT5QcmludCh2YXJpYWJsZXNfLAorICAgICAgICAgICAgICAgICAgICItICgkYXJyYXlfc3RvcmFnZV90eXBlJCAqKSRuYW1lJCBHUEJfTUVUSE9EX0ZBTUlMWV9OT05FO1xuIik7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQoIlxuIik7Cit9CisKK2Jvb2wgUmVwZWF0ZWRGaWVsZEdlbmVyYXRvcjo6V2FudHNIYXNQcm9wZXJ0eSh2b2lkKSBjb25zdCB7CisgIC8vIENvbnN1bWVyIGNoZWNrIHRoZSBhcnJheSBzaXplL2V4aXN0YW5jZSByYXRoZXIgdGhhbiBhIGhhcyBiaXQuCisgIHJldHVybiBmYWxzZTsKK30KKworRmllbGRHZW5lcmF0b3JNYXA6OkZpZWxkR2VuZXJhdG9yTWFwKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpCisgICAgOiBkZXNjcmlwdG9yXyhkZXNjcmlwdG9yKSwKKyAgICAgIGZpZWxkX2dlbmVyYXRvcnNfKAorICAgICAgICAgIG5ldyBzY29wZWRfcHRyPEZpZWxkR2VuZXJhdG9yPltkZXNjcmlwdG9yLT5maWVsZF9jb3VudCgpXSksCisgICAgICBleHRlbnNpb25fZ2VuZXJhdG9yc18oCisgICAgICAgICAgbmV3IHNjb3BlZF9wdHI8RmllbGRHZW5lcmF0b3I+W2Rlc2NyaXB0b3ItPmV4dGVuc2lvbl9jb3VudCgpXSkgeworICAvLyBDb25zdHJ1Y3QgYWxsIHRoZSBGaWVsZEdlbmVyYXRvcnMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvci0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgZmllbGRfZ2VuZXJhdG9yc19baV0ucmVzZXQoRmllbGRHZW5lcmF0b3I6Ok1ha2UoZGVzY3JpcHRvci0+ZmllbGQoaSkpKTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3ItPmV4dGVuc2lvbl9jb3VudCgpOyBpKyspIHsKKyAgICBleHRlbnNpb25fZ2VuZXJhdG9yc19baV0ucmVzZXQoRmllbGRHZW5lcmF0b3I6Ok1ha2UoZGVzY3JpcHRvci0+ZXh0ZW5zaW9uKGkpKSk7CisgIH0KK30KKworRmllbGRHZW5lcmF0b3JNYXA6On5GaWVsZEdlbmVyYXRvck1hcCgpIHt9CisKK2NvbnN0IEZpZWxkR2VuZXJhdG9yJiBGaWVsZEdlbmVyYXRvck1hcDo6Z2V0KAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0IHsKKyAgR09PR0xFX0NIRUNLX0VRKGZpZWxkLT5jb250YWluaW5nX3R5cGUoKSwgZGVzY3JpcHRvcl8pOworICByZXR1cm4gKmZpZWxkX2dlbmVyYXRvcnNfW2ZpZWxkLT5pbmRleCgpXTsKK30KKworY29uc3QgRmllbGRHZW5lcmF0b3ImIEZpZWxkR2VuZXJhdG9yTWFwOjpnZXRfZXh0ZW5zaW9uKGludCBpbmRleCkgY29uc3QgeworICByZXR1cm4gKmV4dGVuc2lvbl9nZW5lcmF0b3JzX1tpbmRleF07Cit9CisKK3ZvaWQgRmllbGRHZW5lcmF0b3JNYXA6OlNldE9uZW9mSW5kZXhCYXNlKGludCBpbmRleF9iYXNlKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGZpZWxkX2dlbmVyYXRvcnNfW2ldLT5TZXRPbmVvZkluZGV4QmFzZShpbmRleF9iYXNlKTsKKyAgfQorfQorCit9ICAvLyBuYW1lc3BhY2Ugb2JqZWN0aXZlYworfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX2ZpZWxkLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19maWVsZC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjEzMGE1MmQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19maWVsZC5oCkBAIC0wLDAgKzEsMTY4IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfT0JKRUNUSVZFQ19GSUVMRF9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX09CSkVDVElWRUNfRklFTERfSF9fCisKKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfaGVscGVycy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKK25hbWVzcGFjZSBpbyB7CitjbGFzcyBQcmludGVyOyAgLy8gcHJpbnRlci5oCit9ICAvLyBuYW1lc3BhY2UgaW8KKworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBvYmplY3RpdmVjIHsKKworY2xhc3MgRmllbGRHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgc3RhdGljIEZpZWxkR2VuZXJhdG9yKiBNYWtlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpOworCisgIHZpcnR1YWwgfkZpZWxkR2VuZXJhdG9yKCk7CisKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlRmllbGRTdG9yYWdlRGVjbGFyYXRpb24oaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlUHJvcGVydHlEZWNsYXJhdGlvbihpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3QgPSAwOworCisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZVByb3BlcnR5SW1wbGVtZW50YXRpb24oaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0ID0gMDsKKworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVGaWVsZERlc2NyaXB0aW9uKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlRmllbGREZXNjcmlwdGlvblR5cGVTcGVjaWZpYyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZUZpZWxkTnVtYmVyQ29uc3RhbnQoaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZUNGdW5jdGlvbkRlY2xhcmF0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZUNGdW5jdGlvbkltcGxlbWVudGF0aW9ucyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyAgdmlydHVhbCB2b2lkIERldGVybWluZUZvcndhcmREZWNsYXJhdGlvbnMoc2V0PHN0cmluZz4qIGZ3ZF9kZWNscykgY29uc3Q7CisKKyAgdm9pZCBTZXRPbmVvZkluZGV4QmFzZShpbnQgaW5kZXhfYmFzZSk7CisKKyAgc3RyaW5nIHZhcmlhYmxlKGNvbnN0IGNoYXIqIGtleSkgY29uc3QgeworICAgIHJldHVybiB2YXJpYWJsZXNfLmZpbmQoa2V5KS0+c2Vjb25kOworICB9CisKKyAgYm9vbCBuZWVkc190ZXh0Zm9ybWF0X25hbWVfc3VwcG9ydCgpIGNvbnN0IHsKKyAgICBjb25zdCBzdHJpbmcmIGZpZWxkX2ZsYWdzID0gdmFyaWFibGUoImZpZWxkZmxhZ3MiKTsKKyAgICByZXR1cm4gZmllbGRfZmxhZ3MuZmluZCgiR1BCRmllbGRUZXh0Rm9ybWF0TmFtZUN1c3RvbSIpICE9IHN0cmluZzo6bnBvczsKKyAgfQorICBzdHJpbmcgZ2VuZXJhdGVkX29iamNfbmFtZSgpIGNvbnN0IHsgcmV0dXJuIHZhcmlhYmxlKCJuYW1lIik7IH0KKyAgc3RyaW5nIHJhd19maWVsZF9uYW1lKCkgY29uc3QgeyByZXR1cm4gdmFyaWFibGUoInJhd19maWVsZF9uYW1lIik7IH0KKworIHByb3RlY3RlZDoKKyAgZXhwbGljaXQgRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKKworICB2aXJ0dWFsIHZvaWQgRmluaXNoSW5pdGlhbGl6YXRpb24odm9pZCk7CisgIHZpcnR1YWwgYm9vbCBXYW50c0hhc1Byb3BlcnR5KHZvaWQpIGNvbnN0ID0gMDsKKworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcmlhYmxlc187CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoRmllbGRHZW5lcmF0b3IpOworfTsKKworY2xhc3MgU2luZ2xlRmllbGRHZW5lcmF0b3IgOiBwdWJsaWMgRmllbGRHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgdmlydHVhbCB+U2luZ2xlRmllbGRHZW5lcmF0b3IoKTsKKworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVGaWVsZFN0b3JhZ2VEZWNsYXJhdGlvbihpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZVByb3BlcnR5RGVjbGFyYXRpb24oaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZVByb3BlcnR5SW1wbGVtZW50YXRpb24oaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworCisgcHJvdGVjdGVkOgorICBleHBsaWNpdCBTaW5nbGVGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworICB2aXJ0dWFsIGJvb2wgV2FudHNIYXNQcm9wZXJ0eSh2b2lkKSBjb25zdDsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhTaW5nbGVGaWVsZEdlbmVyYXRvcik7Cit9OworCisvLyBTdWJjbGFzcyB3aXRoIGNvbW1vbiBzdXBwb3J0IGZvciB3aGVuIHRoZSBmaWVsZCBlbmRzIHVwIGFzIGFuIE9iakMgT2JqZWN0LgorY2xhc3MgT2JqQ09iakZpZWxkR2VuZXJhdG9yIDogcHVibGljIFNpbmdsZUZpZWxkR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIHZpcnR1YWwgfk9iakNPYmpGaWVsZEdlbmVyYXRvcigpOworCisgIHZpcnR1YWwgdm9pZCBHZW5lcmF0ZUZpZWxkU3RvcmFnZURlY2xhcmF0aW9uKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlUHJvcGVydHlEZWNsYXJhdGlvbihpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyBwcm90ZWN0ZWQ6CisgIGV4cGxpY2l0IE9iakNPYmpGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKE9iakNPYmpGaWVsZEdlbmVyYXRvcik7Cit9OworCitjbGFzcyBSZXBlYXRlZEZpZWxkR2VuZXJhdG9yIDogcHVibGljIE9iakNPYmpGaWVsZEdlbmVyYXRvciB7CisgcHVibGljOgorICB2aXJ0dWFsIH5SZXBlYXRlZEZpZWxkR2VuZXJhdG9yKCk7CisKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlRmllbGRTdG9yYWdlRGVjbGFyYXRpb24oaW86OlByaW50ZXIqIHByaW50ZXIpIGNvbnN0OworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVQcm9wZXJ0eURlY2xhcmF0aW9uKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKworICB2aXJ0dWFsIHZvaWQgR2VuZXJhdGVQcm9wZXJ0eUltcGxlbWVudGF0aW9uKGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdDsKKworIHByb3RlY3RlZDoKKyAgZXhwbGljaXQgUmVwZWF0ZWRGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworICB2aXJ0dWFsIHZvaWQgRmluaXNoSW5pdGlhbGl6YXRpb24odm9pZCk7CisgIHZpcnR1YWwgYm9vbCBXYW50c0hhc1Byb3BlcnR5KHZvaWQpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFJlcGVhdGVkRmllbGRHZW5lcmF0b3IpOworfTsKKworLy8gQ29udmVuaWVuY2UgY2xhc3Mgd2hpY2ggY29uc3RydWN0cyBGaWVsZEdlbmVyYXRvcnMgZm9yIGEgRGVzY3JpcHRvci4KK2NsYXNzIEZpZWxkR2VuZXJhdG9yTWFwIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IEZpZWxkR2VuZXJhdG9yTWFwKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworICB+RmllbGRHZW5lcmF0b3JNYXAoKTsKKworICBjb25zdCBGaWVsZEdlbmVyYXRvciYgZ2V0KGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0OworICBjb25zdCBGaWVsZEdlbmVyYXRvciYgZ2V0X2V4dGVuc2lvbihpbnQgaW5kZXgpIGNvbnN0OworCisgIHZvaWQgU2V0T25lb2ZJbmRleEJhc2UoaW50IGluZGV4X2Jhc2UpOworCisgcHJpdmF0ZToKKyAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcl87CisgIHNjb3BlZF9hcnJheTxzY29wZWRfcHRyPEZpZWxkR2VuZXJhdG9yPiA+IGZpZWxkX2dlbmVyYXRvcnNfOworICBzY29wZWRfYXJyYXk8c2NvcGVkX3B0cjxGaWVsZEdlbmVyYXRvcj4gPiBleHRlbnNpb25fZ2VuZXJhdG9yc187CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEZpZWxkR2VuZXJhdG9yTWFwKTsKK307Cit9ICAvLyBuYW1lc3BhY2Ugb2JqZWN0aXZlYworfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX09CSkVDVElWRUNfRklFTERfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19maWxlLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfZmlsZS5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMjhjNjZmCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfZmlsZS5jYwpAQCAtMCwwICsxLDM2OCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX2ZpbGUuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX2VudW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX2V4dGVuc2lvbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfbWVzc2FnZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jb2RlX2dlbmVyYXRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdGxfdXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisjaW5jbHVkZSA8c3N0cmVhbT4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCisvLyBUaGlzIGlzIGFsc28gZm91bmQgaW4gR1BCQm9vdHN0cmFwLmgsIGFuZCBuZWVkcyB0byBiZSBrZXB0IGluIHN5bmMuICBJdAorLy8gaXMgdGhlIHZlcnNpb24gY2hlY2sgZG9uZSB0byBlbnN1cmUgZ2VuZXJhdGVkIGNvZGUgd29ya3Mgd2l0aCB0aGUgY3VycmVudAorLy8gcnVudGltZSBiZWluZyB1c2VkLgorY29uc3QgaW50MzIgR09PR0xFX1BST1RPQlVGX09CSkNfR0VOX1ZFUlNJT04gPSAzMDAwMDsKKworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBvYmplY3RpdmVjIHsKKworRmlsZUdlbmVyYXRvcjo6RmlsZUdlbmVyYXRvcihjb25zdCBGaWxlRGVzY3JpcHRvciAqZmlsZSkKKyAgICA6IGZpbGVfKGZpbGUpLAorICAgICAgcm9vdF9jbGFzc19uYW1lXyhGaWxlQ2xhc3NOYW1lKGZpbGUpKSwKKyAgICAgIGlzX3B1YmxpY19kZXBfKGZhbHNlKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPmVudW1fdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBFbnVtR2VuZXJhdG9yICpnZW5lcmF0b3IgPSBuZXcgRW51bUdlbmVyYXRvcihmaWxlXy0+ZW51bV90eXBlKGkpKTsKKyAgICBlbnVtX2dlbmVyYXRvcnNfLnB1c2hfYmFjayhnZW5lcmF0b3IpOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBNZXNzYWdlR2VuZXJhdG9yICpnZW5lcmF0b3IgPQorICAgICAgICBuZXcgTWVzc2FnZUdlbmVyYXRvcihyb290X2NsYXNzX25hbWVfLCBmaWxlXy0+bWVzc2FnZV90eXBlKGkpKTsKKyAgICBtZXNzYWdlX2dlbmVyYXRvcnNfLnB1c2hfYmFjayhnZW5lcmF0b3IpOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPmV4dGVuc2lvbl9jb3VudCgpOyBpKyspIHsKKyAgICBFeHRlbnNpb25HZW5lcmF0b3IgKmdlbmVyYXRvciA9CisgICAgICAgIG5ldyBFeHRlbnNpb25HZW5lcmF0b3Iocm9vdF9jbGFzc19uYW1lXywgZmlsZV8tPmV4dGVuc2lvbihpKSk7CisgICAgZXh0ZW5zaW9uX2dlbmVyYXRvcnNfLnB1c2hfYmFjayhnZW5lcmF0b3IpOworICB9Cit9CisKK0ZpbGVHZW5lcmF0b3I6On5GaWxlR2VuZXJhdG9yKCkgeworICBTVExEZWxldGVDb250YWluZXJQb2ludGVycyhkZXBlbmRlbmN5X2dlbmVyYXRvcnNfLmJlZ2luKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlcGVuZGVuY3lfZ2VuZXJhdG9yc18uZW5kKCkpOworICBTVExEZWxldGVDb250YWluZXJQb2ludGVycyhlbnVtX2dlbmVyYXRvcnNfLmJlZ2luKCksIGVudW1fZ2VuZXJhdG9yc18uZW5kKCkpOworICBTVExEZWxldGVDb250YWluZXJQb2ludGVycyhtZXNzYWdlX2dlbmVyYXRvcnNfLmJlZ2luKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2VfZ2VuZXJhdG9yc18uZW5kKCkpOworICBTVExEZWxldGVDb250YWluZXJQb2ludGVycyhleHRlbnNpb25fZ2VuZXJhdG9yc18uYmVnaW4oKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uX2dlbmVyYXRvcnNfLmVuZCgpKTsKK30KKwordm9pZCBGaWxlR2VuZXJhdG9yOjpHZW5lcmF0ZUhlYWRlcihpbzo6UHJpbnRlciAqcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICAgICIvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIVxuIgorICAgICAgIi8vIHNvdXJjZTogJGZpbGVuYW1lJFxuIgorICAgICAgIlxuIiwKKyAgICAgICJmaWxlbmFtZSIsIGZpbGVfLT5uYW1lKCkpOworCisgIHByaW50ZXItPlByaW50KAorICAgICAgIiNpbXBvcnQgXCJHUEJQcm90b2NvbEJ1ZmZlcnMuaFwiXG4iCisgICAgICAiXG4iKTsKKworICAvLyBBZGQgc29tZSB2ZXJpZmljYXRpb24gdGhhdCB0aGUgZ2VuZXJhdGVkIGNvZGUgbWF0Y2hlcyB0aGUgc291cmNlIHRoZQorICAvLyBjb2RlIGlzIGJlaW5nIGNvbXBpbGVkIHdpdGguCisgIHByaW50ZXItPlByaW50KAorICAgICAgIiNpZiBHT09HTEVfUFJPVE9CVUZfT0JKQ19HRU5fVkVSU0lPTiAhPSAkcHJvdG9jX2dlbl9vYmpjX3ZlcnNpb24kXG4iCisgICAgICAiI2Vycm9yIFRoaXMgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IGEgZGlmZmVyZW50IHZlcnNpb24gb2YgcHJvdG9jIHdoaWNoIGlzIGluY29tcGF0aWJsZSB3aXRoIHlvdXIgUHJvdG9jb2wgQnVmZmVyIGxpYnJhcnkgc291cmNlcy5cbiIKKyAgICAgICIjZW5kaWZcbiIKKyAgICAgICJcbiIsCisgICAgICAicHJvdG9jX2dlbl9vYmpjX3ZlcnNpb24iLAorICAgICAgU2ltcGxlSXRvYShHT09HTEVfUFJPVE9CVUZfT0JKQ19HRU5fVkVSU0lPTikpOworCisgIGNvbnN0IHZlY3RvcjxGaWxlR2VuZXJhdG9yICo+ICZkZXBlbmRlbmN5X2dlbmVyYXRvcnMgPSBEZXBlbmRlbmN5R2VuZXJhdG9ycygpOworICBmb3IgKHZlY3RvcjxGaWxlR2VuZXJhdG9yICo+Ojpjb25zdF9pdGVyYXRvciBpdGVyID0KKyAgICAgICAgICAgZGVwZW5kZW5jeV9nZW5lcmF0b3JzLmJlZ2luKCk7CisgICAgICAgaXRlciAhPSBkZXBlbmRlbmN5X2dlbmVyYXRvcnMuZW5kKCk7ICsraXRlcikgeworICAgIGlmICgoKml0ZXIpLT5Jc1B1YmxpY0RlcGVuZGVuY3koKSkgeworICAgICAgcHJpbnRlci0+UHJpbnQoIiNpbXBvcnQgXCIkaGVhZGVyJC5wYm9iamMuaFwiXG4iLAorICAgICAgICAgICAgICAgICAgICAgImhlYWRlciIsICgqaXRlciktPlBhdGgoKSk7CisgICAgfQorICB9CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGltcG9ydHMpXG4iCisgICAgICAiXG4iCisgICAgICAiQ0ZfRVhURVJOX0NfQkVHSU5cbiIKKyAgICAgICJcbiIpOworCisgIHNldDxzdHJpbmc+IGZ3ZF9kZWNsczsKKyAgZm9yICh2ZWN0b3I8TWVzc2FnZUdlbmVyYXRvciAqPjo6aXRlcmF0b3IgaXRlciA9IG1lc3NhZ2VfZ2VuZXJhdG9yc18uYmVnaW4oKTsKKyAgICAgICBpdGVyICE9IG1lc3NhZ2VfZ2VuZXJhdG9yc18uZW5kKCk7ICsraXRlcikgeworICAgICgqaXRlciktPkRldGVybWluZUZvcndhcmREZWNsYXJhdGlvbnMoJmZ3ZF9kZWNscyk7CisgIH0KKyAgZm9yIChzZXQ8c3RyaW5nPjo6Y29uc3RfaXRlcmF0b3IgaShmd2RfZGVjbHMuYmVnaW4oKSk7CisgICAgICAgaSAhPSBmd2RfZGVjbHMuZW5kKCk7ICsraSkgeworICAgIHByaW50ZXItPlByaW50KCIkdmFsdWUkO1xuIiwgInZhbHVlIiwgKmkpOworICB9CisgIGlmIChmd2RfZGVjbHMuYmVnaW4oKSAhPSBmd2RfZGVjbHMuZW5kKCkpIHsKKyAgICBwcmludGVyLT5QcmludCgiXG4iKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KAorICAgICAgIk5TX0FTU1VNRV9OT05OVUxMX0JFR0lOXG4iCisgICAgICAiXG4iKTsKKworICAvLyBuZWVkIHRvIHdyaXRlIG91dCBhbGwgZW51bXMgZmlyc3QKKyAgZm9yICh2ZWN0b3I8RW51bUdlbmVyYXRvciAqPjo6aXRlcmF0b3IgaXRlciA9IGVudW1fZ2VuZXJhdG9yc18uYmVnaW4oKTsKKyAgICAgICBpdGVyICE9IGVudW1fZ2VuZXJhdG9yc18uZW5kKCk7ICsraXRlcikgeworICAgICgqaXRlciktPkdlbmVyYXRlSGVhZGVyKHByaW50ZXIpOworICB9CisKKyAgZm9yICh2ZWN0b3I8TWVzc2FnZUdlbmVyYXRvciAqPjo6aXRlcmF0b3IgaXRlciA9IG1lc3NhZ2VfZ2VuZXJhdG9yc18uYmVnaW4oKTsKKyAgICAgICBpdGVyICE9IG1lc3NhZ2VfZ2VuZXJhdG9yc18uZW5kKCk7ICsraXRlcikgeworICAgICgqaXRlciktPkdlbmVyYXRlRW51bUhlYWRlcihwcmludGVyKTsKKyAgfQorCisgIC8vIEZvciBleHRlbnNpb25zIHRvIGNoYWluIHRvZ2V0aGVyLCB0aGUgUm9vdCBnZXRzIGNyZWF0ZWQgZXZlbiBpZiB0aGVyZQorICAvLyBhcmUgbm8gZXh0ZW5zaW9ucy4KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiI3ByYWdtYSBtYXJrIC0gJHJvb3RfY2xhc3NfbmFtZSRcbiIKKyAgICAgICJcbiIKKyAgICAgICJAaW50ZXJmYWNlICRyb290X2NsYXNzX25hbWUkIDogR1BCUm9vdE9iamVjdFxuIgorICAgICAgIlxuIgorICAgICAgIi8vIFRoZSBiYXNlIGNsYXNzIHByb3ZpZGVzOlxuIgorICAgICAgIi8vICAgKyAoR1BCRXh0ZW5zaW9uUmVnaXN0cnkgKilleHRlbnNpb25SZWdpc3RyeTtcbiIKKyAgICAgICIvLyB3aGljaCBpcyBhbiBHUEJFeHRlbnNpb25SZWdpc3RyeSB0aGF0IGluY2x1ZGVzIGFsbCB0aGUgZXh0ZW5zaW9ucyBkZWZpbmVkIGJ5XG4iCisgICAgICAiLy8gdGhpcyBmaWxlIGFuZCBhbGwgZmlsZXMgdGhhdCBpdCBkZXBlbmRzIG9uLlxuIgorICAgICAgIlxuIgorICAgICAgIkBlbmRcbiIKKyAgICAgICJcbiIsCisgICAgICAicm9vdF9jbGFzc19uYW1lIiwgcm9vdF9jbGFzc19uYW1lXyk7CisKKyAgaWYgKGV4dGVuc2lvbl9nZW5lcmF0b3JzXy5zaXplKCkgPiAwKSB7CisgICAgLy8gVGhlIGR5bmFtaWMgbWV0aG9kcyBibG9jayBpcyBvbmx5IG5lZWRlZCBpZiB0aGVyZSBhcmUgZXh0ZW5zaW9ucy4KKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIkBpbnRlcmZhY2UgJHJvb3RfY2xhc3NfbmFtZSQgKER5bmFtaWNNZXRob2RzKVxuIiwKKyAgICAgICAgInJvb3RfY2xhc3NfbmFtZSIsIHJvb3RfY2xhc3NfbmFtZV8pOworCisgICAgZm9yICh2ZWN0b3I8RXh0ZW5zaW9uR2VuZXJhdG9yICo+OjppdGVyYXRvciBpdGVyID0KKyAgICAgICAgICAgICBleHRlbnNpb25fZ2VuZXJhdG9yc18uYmVnaW4oKTsKKyAgICAgICAgIGl0ZXIgIT0gZXh0ZW5zaW9uX2dlbmVyYXRvcnNfLmVuZCgpOyArK2l0ZXIpIHsKKyAgICAgICgqaXRlciktPkdlbmVyYXRlTWVtYmVyc0hlYWRlcihwcmludGVyKTsKKyAgICB9CisKKyAgICBwcmludGVyLT5QcmludCgiQGVuZFxuXG4iKTsKKyAgfSAgLy8gZXh0ZW5zaW9uX2dlbmVyYXRvcnNfLnNpemUoKSA+IDAKKworICBmb3IgKHZlY3RvcjxNZXNzYWdlR2VuZXJhdG9yICo+OjppdGVyYXRvciBpdGVyID0gbWVzc2FnZV9nZW5lcmF0b3JzXy5iZWdpbigpOworICAgICAgIGl0ZXIgIT0gbWVzc2FnZV9nZW5lcmF0b3JzXy5lbmQoKTsgKytpdGVyKSB7CisgICAgKCppdGVyKS0+R2VuZXJhdGVNZXNzYWdlSGVhZGVyKHByaW50ZXIpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiTlNfQVNTVU1FX05PTk5VTExfRU5EXG4iCisgICAgICAiXG4iCisgICAgICAiQ0ZfRVhURVJOX0NfRU5EXG4iCisgICAgICAiXG4iCisgICAgICAiLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGdsb2JhbF9zY29wZSlcbiIpOworfQorCit2b2lkIEZpbGVHZW5lcmF0b3I6OkdlbmVyYXRlU291cmNlKGlvOjpQcmludGVyICpwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgICAgIi8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhXG4iCisgICAgICAiLy8gc291cmNlOiAkZmlsZW5hbWUkXG4iCisgICAgICAiXG4iLAorICAgICAgImZpbGVuYW1lIiwgZmlsZV8tPm5hbWUoKSk7CisKKyAgc3RyaW5nIGhlYWRlcl9maWxlID0gUGF0aCgpICsgIi5wYm9iamMuaCI7CisgIHByaW50ZXItPlByaW50KAorICAgICAgIiNpbXBvcnQgXCJHUEJQcm90b2NvbEJ1ZmZlcnNfUnVudGltZVN1cHBvcnQuaFwiXG4iCisgICAgICAiI2ltcG9ydCBcIiRoZWFkZXJfZmlsZSRcIlxuIiwKKyAgICAgICJoZWFkZXJfZmlsZSIsIGhlYWRlcl9maWxlKTsKKyAgY29uc3QgdmVjdG9yPEZpbGVHZW5lcmF0b3IgKj4gJmRlcGVuZGVuY3lfZ2VuZXJhdG9ycyA9CisgICAgICBEZXBlbmRlbmN5R2VuZXJhdG9ycygpOworICBmb3IgKHZlY3RvcjxGaWxlR2VuZXJhdG9yICo+Ojpjb25zdF9pdGVyYXRvciBpdGVyID0KKyAgICAgICAgICAgZGVwZW5kZW5jeV9nZW5lcmF0b3JzLmJlZ2luKCk7CisgICAgICAgaXRlciAhPSBkZXBlbmRlbmN5X2dlbmVyYXRvcnMuZW5kKCk7ICsraXRlcikgeworICAgIGlmICghKCppdGVyKS0+SXNQdWJsaWNEZXBlbmRlbmN5KCkpIHsKKyAgICAgIHByaW50ZXItPlByaW50KCIjaW1wb3J0IFwiJGhlYWRlciQucGJvYmpjLmhcIlxuIiwKKyAgICAgICAgICAgICAgICAgICAgICJoZWFkZXIiLCAoKml0ZXIpLT5QYXRoKCkpOworICAgIH0KKyAgfQorICBwcmludGVyLT5QcmludCgKKyAgICAgICIvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW1wb3J0cylcbiIKKyAgICAgICJcbiIpOworCisgIHByaW50ZXItPlByaW50KAorICAgICAgIiNwcmFnbWEgbWFyayAtICRyb290X2NsYXNzX25hbWUkXG4iCisgICAgICAiXG4iCisgICAgICAiQGltcGxlbWVudGF0aW9uICRyb290X2NsYXNzX25hbWUkXG5cbiIsCisgICAgICAicm9vdF9jbGFzc19uYW1lIiwgcm9vdF9jbGFzc19uYW1lXyk7CisKKyAgLy8gR2VuZXJhdGUgdGhlIGV4dGVuc2lvbiBpbml0aWFsaXphdGlvbiBzdHJ1Y3R1cmVzIGZvciB0aGUgdG9wIGxldmVsIGFuZAorICAvLyBhbnkgbmVzdGVkIG1lc3NhZ2VzLgorICBvc3RyaW5nc3RyZWFtIGV4dGVuc2lvbnNfc3RyaW5nc3RyZWFtOworICBpZiAoZmlsZV8tPmV4dGVuc2lvbl9jb3VudCgpICsgZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpID4gMCkgeworICAgIGlvOjpPc3RyZWFtT3V0cHV0U3RyZWFtIGV4dGVuc2lvbnNfb3V0cHV0c3RyZWFtKCZleHRlbnNpb25zX3N0cmluZ3N0cmVhbSk7CisgICAgaW86OlByaW50ZXIgZXh0ZW5zaW9uc19wcmludGVyKCZleHRlbnNpb25zX291dHB1dHN0cmVhbSwgJyQnKTsKKyAgICBmb3IgKHZlY3RvcjxFeHRlbnNpb25HZW5lcmF0b3IgKj46Oml0ZXJhdG9yIGl0ZXIgPQorICAgICAgICAgICAgIGV4dGVuc2lvbl9nZW5lcmF0b3JzXy5iZWdpbigpOworICAgICAgICAgaXRlciAhPSBleHRlbnNpb25fZ2VuZXJhdG9yc18uZW5kKCk7ICsraXRlcikgeworICAgICAgKCppdGVyKS0+R2VuZXJhdGVTdGF0aWNWYXJpYWJsZXNJbml0aWFsaXphdGlvbigmZXh0ZW5zaW9uc19wcmludGVyKTsKKyAgICB9CisgICAgZm9yICh2ZWN0b3I8TWVzc2FnZUdlbmVyYXRvciAqPjo6aXRlcmF0b3IgaXRlciA9CisgICAgICAgICAgICAgbWVzc2FnZV9nZW5lcmF0b3JzXy5iZWdpbigpOworICAgICAgICAgaXRlciAhPSBtZXNzYWdlX2dlbmVyYXRvcnNfLmVuZCgpOyArK2l0ZXIpIHsKKyAgICAgICgqaXRlciktPkdlbmVyYXRlU3RhdGljVmFyaWFibGVzSW5pdGlhbGl6YXRpb24oJmV4dGVuc2lvbnNfcHJpbnRlcik7CisgICAgfQorICAgIGV4dGVuc2lvbnNfc3RyaW5nc3RyZWFtLmZsdXNoKCk7CisgIH0KKworICAvLyBJZiB0aGVyZSB3ZXJlIGFueSBleHRlbnNpb25zIG9yIHRoaXMgZmlsZSBoYXMgYW55IGRlcGVuZGVuY2llcywgb3V0cHV0CisgIC8vIGEgcmVnaXN0cnkgdG8gb3ZlcnJpZGUgdG8gY3JlYXRlIHRoZSBmaWxlIHNwZWNpZmljIHJlZ2lzdHJ5LgorICBjb25zdCBzdHJpbmcmIGV4dGVuc2lvbnNfc3RyID0gZXh0ZW5zaW9uc19zdHJpbmdzdHJlYW0uc3RyKCk7CisgIGlmIChleHRlbnNpb25zX3N0ci5sZW5ndGgoKSA+IDAgfHwgZmlsZV8tPmRlcGVuZGVuY3lfY291bnQoKSA+IDApIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIisgKEdQQkV4dGVuc2lvblJlZ2lzdHJ5KilleHRlbnNpb25SZWdpc3RyeSB7XG4iCisgICAgICAgICIgIC8vIFRoaXMgaXMgY2FsbGVkIGJ5ICtpbml0aWFsaXplIHNvIHRoZXJlIGlzIG5vIG5lZWQgdG8gd29ycnlcbiIKKyAgICAgICAgIiAgLy8gYWJvdXQgdGhyZWFkIHNhZmV0eSBhbmQgaW5pdGlhbGl6YXRpb24gb2YgcmVnaXN0cnkuXG4iCisgICAgICAgICIgIHN0YXRpYyBHUEJFeHRlbnNpb25SZWdpc3RyeSogcmVnaXN0cnkgPSBuaWw7XG4iCisgICAgICAgICIgIGlmICghcmVnaXN0cnkpIHtcbiIKKyAgICAgICAgIiAgICBHUEJEZWJ1Z0NoZWNrUnVudGltZVZlcnNpb24oKTtcbiIKKyAgICAgICAgIiAgICByZWdpc3RyeSA9IFtbR1BCRXh0ZW5zaW9uUmVnaXN0cnkgYWxsb2NdIGluaXRdO1xuIik7CisKKyAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICBwcmludGVyLT5JbmRlbnQoKTsKKworICAgIGlmIChleHRlbnNpb25zX3N0ci5sZW5ndGgoKSA+IDApIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICJzdGF0aWMgR1BCRXh0ZW5zaW9uRGVzY3JpcHRpb24gZGVzY3JpcHRpb25zW10gPSB7XG4iKTsKKyAgICAgIHByaW50ZXItPkluZGVudCgpOworICAgICAgcHJpbnRlci0+UHJpbnQoZXh0ZW5zaW9uc19zdHIuY19zdHIoKSk7CisgICAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAifTtcbiIKKyAgICAgICAgICAiZm9yIChzaXplX3QgaSA9IDA7IGkgPCBzaXplb2YoZGVzY3JpcHRpb25zKSAvIHNpemVvZihkZXNjcmlwdGlvbnNbMF0pOyArK2kpIHtcbiIKKyAgICAgICAgICAiICBHUEJFeHRlbnNpb25EZXNjcmlwdG9yICpleHRlbnNpb24gPVxuIgorICAgICAgICAgICIgICAgICBbW0dQQkV4dGVuc2lvbkRlc2NyaXB0b3IgYWxsb2NdIGluaXRXaXRoRXh0ZW5zaW9uRGVzY3JpcHRpb246JmRlc2NyaXB0aW9uc1tpXV07XG4iCisgICAgICAgICAgIiAgW3JlZ2lzdHJ5IGFkZEV4dGVuc2lvbjpleHRlbnNpb25dO1xuIgorICAgICAgICAgICIgIFtzZWxmIGdsb2JhbGx5UmVnaXN0ZXJFeHRlbnNpb246ZXh0ZW5zaW9uXTtcbiIKKyAgICAgICAgICAiICBbZXh0ZW5zaW9uIHJlbGVhc2VdO1xuIgorICAgICAgICAgICJ9XG4iKTsKKyAgICB9CisKKyAgICBjb25zdCB2ZWN0b3I8RmlsZUdlbmVyYXRvciAqPiAmZGVwZW5kZW5jeV9nZW5lcmF0b3JzID0KKyAgICAgICAgRGVwZW5kZW5jeUdlbmVyYXRvcnMoKTsKKyAgICBmb3IgKHZlY3RvcjxGaWxlR2VuZXJhdG9yICo+Ojpjb25zdF9pdGVyYXRvciBpdGVyID0KKyAgICAgICAgICAgICBkZXBlbmRlbmN5X2dlbmVyYXRvcnMuYmVnaW4oKTsKKyAgICAgICAgIGl0ZXIgIT0gZGVwZW5kZW5jeV9nZW5lcmF0b3JzLmVuZCgpOyArK2l0ZXIpIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICJbcmVnaXN0cnkgYWRkRXh0ZW5zaW9uczpbJGRlcGVuZGVuY3kkIGV4dGVuc2lvblJlZ2lzdHJ5XV07XG4iLAorICAgICAgICAgICJkZXBlbmRlbmN5IiwgKCppdGVyKS0+Um9vdENsYXNzTmFtZSgpKTsKKyAgICB9CisKKyAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICIgIH1cbiIKKyAgICAgICAgIiAgcmV0dXJuIHJlZ2lzdHJ5O1xuIgorICAgICAgICAifVxuIgorICAgICAgICAiXG4iKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KCJAZW5kXG5cbiIpOworCisgIC8vIEZpbGUgZGVzY3JpcHRvciBvbmx5IG5lZWRlZCBpZiB0aGVyZSBhcmUgbWVzc2FnZXMgdG8gdXNlIGl0LgorICBpZiAobWVzc2FnZV9nZW5lcmF0b3JzXy5zaXplKCkgPiAwKSB7CisgICAgc3RyaW5nIHN5bnRheDsKKyAgICBzd2l0Y2ggKGZpbGVfLT5zeW50YXgoKSkgeworICAgICAgY2FzZSBGaWxlRGVzY3JpcHRvcjo6U1lOVEFYX1VOS05PV046CisgICAgICAgIHN5bnRheCA9ICJHUEJGaWxlU3ludGF4VW5rbm93biI7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBGaWxlRGVzY3JpcHRvcjo6U1lOVEFYX1BST1RPMjoKKyAgICAgICAgc3ludGF4ID0gIkdQQkZpbGVTeW50YXhQcm90bzIiOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgRmlsZURlc2NyaXB0b3I6OlNZTlRBWF9QUk9UTzM6CisgICAgICAgIHN5bnRheCA9ICJHUEJGaWxlU3ludGF4UHJvdG8zIjsKKyAgICAgICAgYnJlYWs7CisgICAgfQorICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiI3ByYWdtYSBtYXJrIC0gJHJvb3RfY2xhc3NfbmFtZSRfRmlsZURlc2NyaXB0b3JcbiIKKyAgICAgICAgIlxuIgorICAgICAgICAic3RhdGljIEdQQkZpbGVEZXNjcmlwdG9yICokcm9vdF9jbGFzc19uYW1lJF9GaWxlRGVzY3JpcHRvcih2b2lkKSB7XG4iCisgICAgICAgICIgIC8vIFRoaXMgaXMgY2FsbGVkIGJ5ICtpbml0aWFsaXplIHNvIHRoZXJlIGlzIG5vIG5lZWQgdG8gd29ycnlcbiIKKyAgICAgICAgIiAgLy8gYWJvdXQgdGhyZWFkIHNhZmV0eSBvZiB0aGUgc2luZ2xldG9uLlxuIgorICAgICAgICAiICBzdGF0aWMgR1BCRmlsZURlc2NyaXB0b3IgKmRlc2NyaXB0b3IgPSBOVUxMO1xuIgorICAgICAgICAiICBpZiAoIWRlc2NyaXB0b3IpIHtcbiIKKyAgICAgICAgIiAgICBHUEJEZWJ1Z0NoZWNrUnVudGltZVZlcnNpb24oKTtcbiIKKyAgICAgICAgIiAgICBkZXNjcmlwdG9yID0gW1tHUEJGaWxlRGVzY3JpcHRvciBhbGxvY10gaW5pdFdpdGhQYWNrYWdlOkBcIiRwYWNrYWdlJFwiXG4iCisgICAgICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bnRheDokc3ludGF4JF07XG4iCisgICAgICAgICIgIH1cbiIKKyAgICAgICAgIiAgcmV0dXJuIGRlc2NyaXB0b3I7XG4iCisgICAgICAgICJ9XG4iCisgICAgICAgICJcbiIsCisgICAgICAgICJyb290X2NsYXNzX25hbWUiLCByb290X2NsYXNzX25hbWVfLAorICAgICAgICAicGFja2FnZSIsIGZpbGVfLT5wYWNrYWdlKCksCisgICAgICAgICJzeW50YXgiLCBzeW50YXgpOworICB9CisKKyAgZm9yICh2ZWN0b3I8RW51bUdlbmVyYXRvciAqPjo6aXRlcmF0b3IgaXRlciA9IGVudW1fZ2VuZXJhdG9yc18uYmVnaW4oKTsKKyAgICAgICBpdGVyICE9IGVudW1fZ2VuZXJhdG9yc18uZW5kKCk7ICsraXRlcikgeworICAgICgqaXRlciktPkdlbmVyYXRlU291cmNlKHByaW50ZXIpOworICB9CisgIGZvciAodmVjdG9yPE1lc3NhZ2VHZW5lcmF0b3IgKj46Oml0ZXJhdG9yIGl0ZXIgPSBtZXNzYWdlX2dlbmVyYXRvcnNfLmJlZ2luKCk7CisgICAgICAgaXRlciAhPSBtZXNzYWdlX2dlbmVyYXRvcnNfLmVuZCgpOyArK2l0ZXIpIHsKKyAgICAoKml0ZXIpLT5HZW5lcmF0ZVNvdXJjZShwcmludGVyKTsKKyAgfQorCisgIHByaW50ZXItPlByaW50KAorICAgICJcbiIKKyAgICAiLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGdsb2JhbF9zY29wZSlcbiIpOworfQorCitjb25zdCBzdHJpbmcgRmlsZUdlbmVyYXRvcjo6UGF0aCgpIGNvbnN0IHsgcmV0dXJuIEZpbGVQYXRoKGZpbGVfKTsgfQorCitjb25zdCB2ZWN0b3I8RmlsZUdlbmVyYXRvciAqPiAmRmlsZUdlbmVyYXRvcjo6RGVwZW5kZW5jeUdlbmVyYXRvcnMoKSB7CisgIGlmIChmaWxlXy0+ZGVwZW5kZW5jeV9jb3VudCgpICE9IGRlcGVuZGVuY3lfZ2VuZXJhdG9yc18uc2l6ZSgpKSB7CisgICAgc2V0PHN0cmluZz4gcHVibGljX2ltcG9ydF9uYW1lczsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5wdWJsaWNfZGVwZW5kZW5jeV9jb3VudCgpOyBpKyspIHsKKyAgICAgIHB1YmxpY19pbXBvcnRfbmFtZXMuaW5zZXJ0KGZpbGVfLT5wdWJsaWNfZGVwZW5kZW5jeShpKS0+bmFtZSgpKTsKKyAgICB9CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+ZGVwZW5kZW5jeV9jb3VudCgpOyBpKyspIHsKKyAgICAgIEZpbGVHZW5lcmF0b3IgKmdlbmVyYXRvciA9IG5ldyBGaWxlR2VuZXJhdG9yKGZpbGVfLT5kZXBlbmRlbmN5KGkpKTsKKyAgICAgIGNvbnN0IHN0cmluZyYgbmFtZSA9IGZpbGVfLT5kZXBlbmRlbmN5KGkpLT5uYW1lKCk7CisgICAgICBib29sIHB1YmxpY19pbXBvcnQgPSAocHVibGljX2ltcG9ydF9uYW1lcy5jb3VudChuYW1lKSAhPSAwKTsKKyAgICAgIGdlbmVyYXRvci0+U2V0SXNQdWJsaWNEZXBlbmRlbmN5KHB1YmxpY19pbXBvcnQpOworICAgICAgZGVwZW5kZW5jeV9nZW5lcmF0b3JzXy5wdXNoX2JhY2soZ2VuZXJhdG9yKTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIGRlcGVuZGVuY3lfZ2VuZXJhdG9yc187Cit9CisKK30gIC8vIG5hbWVzcGFjZSBvYmplY3RpdmVjCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfZmlsZS5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfZmlsZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFiYjRmMGUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19maWxlLmgKQEAgLTAsMCArMSw5NyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX09CSkVDVElWRUNfRklMRV9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX09CSkVDVElWRUNfRklMRV9IX18KKworI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxzZXQ+CisjaW5jbHVkZSA8dmVjdG9yPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfaGVscGVycy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworY2xhc3MgRmlsZURlc2NyaXB0b3I7ICAvLyBkZXNjcmlwdG9yLmgKK25hbWVzcGFjZSBpbyB7CitjbGFzcyBQcmludGVyOyAgLy8gcHJpbnRlci5oCit9Cit9CisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIG9iamVjdGl2ZWMgeworCitjbGFzcyBFbnVtR2VuZXJhdG9yOworY2xhc3MgRXh0ZW5zaW9uR2VuZXJhdG9yOworY2xhc3MgTWVzc2FnZUdlbmVyYXRvcjsKKworY2xhc3MgRmlsZUdlbmVyYXRvciB7CisgcHVibGljOgorICBleHBsaWNpdCBGaWxlR2VuZXJhdG9yKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKTsKKyAgfkZpbGVHZW5lcmF0b3IoKTsKKworICB2b2lkIEdlbmVyYXRlU291cmNlKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdm9pZCBHZW5lcmF0ZUhlYWRlcihpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyAgY29uc3Qgc3RyaW5nJiBSb290Q2xhc3NOYW1lKCkgY29uc3QgeyByZXR1cm4gcm9vdF9jbGFzc19uYW1lXzsgfQorICBjb25zdCBzdHJpbmcgUGF0aCgpIGNvbnN0OworCisgIGJvb2wgSXNQdWJsaWNEZXBlbmRlbmN5KCkgY29uc3QgeyByZXR1cm4gaXNfcHVibGljX2RlcF87IH0KKworIHByb3RlY3RlZDoKKyAgdm9pZCBTZXRJc1B1YmxpY0RlcGVuZGVuY3koYm9vbCBpc19wdWJsaWNfZGVwKSB7CisgICAgaXNfcHVibGljX2RlcF8gPSBpc19wdWJsaWNfZGVwOworICB9CisKKyBwcml2YXRlOgorICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZV87CisgIHN0cmluZyByb290X2NsYXNzX25hbWVfOworCisgIC8vIEFjY2VzcyB0aGlzIGZpZWxkIHRocm91Z2ggdGhlIERlcGVuZGVuY3lHZW5lcmF0b3JzIGFjY2Vzc29yIGNhbGwgYmVsb3cuCisgIC8vIERvIG5vdCByZWZlcmVuY2UgaXQgZGlyZWN0bHkuCisgIHZlY3RvcjxGaWxlR2VuZXJhdG9yKj4gZGVwZW5kZW5jeV9nZW5lcmF0b3JzXzsKKworICB2ZWN0b3I8RW51bUdlbmVyYXRvcio+IGVudW1fZ2VuZXJhdG9yc187CisgIHZlY3RvcjxNZXNzYWdlR2VuZXJhdG9yKj4gbWVzc2FnZV9nZW5lcmF0b3JzXzsKKyAgdmVjdG9yPEV4dGVuc2lvbkdlbmVyYXRvcio+IGV4dGVuc2lvbl9nZW5lcmF0b3JzXzsKKyAgYm9vbCBpc19wdWJsaWNfZGVwXzsKKworICBjb25zdCB2ZWN0b3I8RmlsZUdlbmVyYXRvcio+JiBEZXBlbmRlbmN5R2VuZXJhdG9ycygpOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhGaWxlR2VuZXJhdG9yKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBvYmplY3RpdmVjCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9PQkpFQ1RJVkVDX0ZJTEVfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19nZW5lcmF0b3IuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19nZW5lcmF0b3IuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzc1YjRlMAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX2dlbmVyYXRvci5jYwpAQCAtMCwwICsxLDkxIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2luY2x1ZGUgPGlvc3RyZWFtPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfZ2VuZXJhdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19maWxlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2Ugb2JqZWN0aXZlYyB7CisKK09iamVjdGl2ZUNHZW5lcmF0b3I6Ok9iamVjdGl2ZUNHZW5lcmF0b3IoKSB7fQorCitPYmplY3RpdmVDR2VuZXJhdG9yOjp+T2JqZWN0aXZlQ0dlbmVyYXRvcigpIHt9CisKK2Jvb2wgT2JqZWN0aXZlQ0dlbmVyYXRvcjo6R2VuZXJhdGUoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgcGFyYW1ldGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPdXRwdXREaXJlY3RvcnkqIG91dHB1dF9kaXJlY3RvcnksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyogZXJyb3IpIGNvbnN0IHsKKyAgLy8gT2JqQyBkb2Vzbid0IGhhdmUgYW55IG9wdGlvbnMgYXQgdGhlIG1vbWVudCwgZXJyb3IgaWYgcGFzc2VkIG9uZS4KKyAgdmVjdG9yPHBhaXI8c3RyaW5nLCBzdHJpbmc+ID4gb3B0aW9uczsKKyAgUGFyc2VHZW5lcmF0b3JQYXJhbWV0ZXIocGFyYW1ldGVyLCAmb3B0aW9ucyk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgb3B0aW9ucy5zaXplKCk7IGkrKykgeworICAgICplcnJvciA9ICJlcnJvcjo6IFVua25vd24gZ2VuZXJhdG9yIG9wdGlvbjogIiArIG9wdGlvbnNbaV0uZmlyc3Q7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8gVmFsaWRhdGUgdGhlIG9iamMgcHJlZml4L3BhY2thZ2UgcGFpcmluZy4KKyAgaWYgKCFWYWxpZGF0ZU9iakNDbGFzc1ByZWZpeChmaWxlLCBlcnJvcikpIHsKKyAgICAvLyAqZXJyb3Igd2lsbCBoYXZlIGJlZW4gZmlsbGVkIGluLgorICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIEZpbGVHZW5lcmF0b3IgZmlsZV9nZW5lcmF0b3IoZmlsZSk7CisgIHN0cmluZyBmaWxlcGF0aCA9IEZpbGVQYXRoKGZpbGUpOworCisgIC8vIEdlbmVyYXRlIGhlYWRlci4KKyAgeworICAgIHNjb3BlZF9wdHI8aW86Olplcm9Db3B5T3V0cHV0U3RyZWFtPiBvdXRwdXQoCisgICAgICAgIG91dHB1dF9kaXJlY3RvcnktPk9wZW4oZmlsZXBhdGggKyAiLnBib2JqYy5oIikpOworICAgIGlvOjpQcmludGVyIHByaW50ZXIob3V0cHV0LmdldCgpLCAnJCcpOworICAgIGZpbGVfZ2VuZXJhdG9yLkdlbmVyYXRlSGVhZGVyKCZwcmludGVyKTsKKyAgfQorCisgIC8vIEdlbmVyYXRlIG0gZmlsZS4KKyAgeworICAgIHNjb3BlZF9wdHI8aW86Olplcm9Db3B5T3V0cHV0U3RyZWFtPiBvdXRwdXQoCisgICAgICAgIG91dHB1dF9kaXJlY3RvcnktPk9wZW4oZmlsZXBhdGggKyAiLnBib2JqYy5tIikpOworICAgIGlvOjpQcmludGVyIHByaW50ZXIob3V0cHV0LmdldCgpLCAnJCcpOworICAgIGZpbGVfZ2VuZXJhdG9yLkdlbmVyYXRlU291cmNlKCZwcmludGVyKTsKKyAgfQorCisgIHJldHVybiB0cnVlOworfQorCit9ICAvLyBuYW1lc3BhY2Ugb2JqZWN0aXZlYworfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX2dlbmVyYXRvci5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfZ2VuZXJhdG9yLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDkyNjZiMAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX2dlbmVyYXRvci5oCkBAIC0wLDAgKzEsNjEgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBHZW5lcmF0ZXMgT2JqZWN0aXZlQyBjb2RlIGZvciBhIGdpdmVuIC5wcm90byBmaWxlLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9PQkpFQ1RJVkVDX0dFTkVSQVRPUl9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX09CSkVDVElWRUNfR0VORVJBVE9SX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jb2RlX2dlbmVyYXRvci5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIG9iamVjdGl2ZWMgeworCitjbGFzcyBMSUJQUk9UT0NfRVhQT1JUIE9iamVjdGl2ZUNHZW5lcmF0b3IgOiBwdWJsaWMgQ29kZUdlbmVyYXRvciB7CisgcHVibGljOgorICBPYmplY3RpdmVDR2VuZXJhdG9yKCk7CisgIH5PYmplY3RpdmVDR2VuZXJhdG9yKCk7CisKKyAgLy8gaW1wbGVtZW50cyBDb2RlR2VuZXJhdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgYm9vbCBHZW5lcmF0ZShjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSwgY29uc3Qgc3RyaW5nJiBwYXJhbWV0ZXIsCisgICAgICAgICAgICAgICAgT3V0cHV0RGlyZWN0b3J5KiBvdXRwdXRfZGlyZWN0b3J5LCBzdHJpbmcqIGVycm9yKSBjb25zdDsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhPYmplY3RpdmVDR2VuZXJhdG9yKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBvYmplY3RpdmVjCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfT0JKRUNUSVZFQ19HRU5FUkFUT1JfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19oZWxwZXJzLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfaGVscGVycy5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NTI3Yjc0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfaGVscGVycy5jYwpAQCAtMCwwICsxLDEyMzggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaWZkZWYgX01TQ19WRVIKKyNpbmNsdWRlIDxpby5oPgorI2Vsc2UKKyNpbmNsdWRlIDx1bmlzdGQuaD4KKyNlbmRpZgorI2luY2x1ZGUgPGNsaW1pdHM+CisjaW5jbHVkZSA8ZXJybm8uaD4KKyNpbmNsdWRlIDxmY250bC5oPgorI2luY2x1ZGUgPGZzdHJlYW0+CisjaW5jbHVkZSA8aW9zdHJlYW0+CisjaW5jbHVkZSA8c3N0cmVhbT4KKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlIDx2ZWN0b3I+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvaGFzaC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfaGVscGVycy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbV9pbXBsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKworLy8gTk9URTogc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wbHVnaW4uY2MgbWFrZXMgdXNlIG9mIGNlcnIgZm9yIHNvbWUKKy8vIGVycm9yIGNhc2VzLCBzbyBpdCBzZWVtcyB0byBiZSBvayB0byB1c2UgYXMgYSBiYWNrIGRvb3IgZm9yIGVycm9ycy4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBvYmplY3RpdmVjIHsKKworbmFtZXNwYWNlIHsKKworaGFzaF9zZXQ8c3RyaW5nPiBNYWtlV29yZHNNYXAoY29uc3QgY2hhciogY29uc3Qgd29yZHNbXSwgc2l6ZV90IG51bV93b3JkcykgeworICBoYXNoX3NldDxzdHJpbmc+IHJlc3VsdDsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1fd29yZHM7IGkrKykgeworICAgIHJlc3VsdC5pbnNlcnQod29yZHNbaV0pOworICB9CisgIHJldHVybiByZXN1bHQ7Cit9CisKK2NvbnN0IGNoYXIqIGNvbnN0IGtVcHBlclNlZ21lbnRzTGlzdFtdID0geyJ1cmwiLCAiaHR0cCIsICJodHRwcyJ9OworCitoYXNoX3NldDxzdHJpbmc+IGtVcHBlclNlZ21lbnRzID0KKyAgICBNYWtlV29yZHNNYXAoa1VwcGVyU2VnbWVudHNMaXN0LCBHT09HTEVfQVJSQVlTSVpFKGtVcHBlclNlZ21lbnRzTGlzdCkpOworCisvLyBJbnRlcm5hbCBoZWxwZXIgZm9yIG5hbWUgaGFuZGluZy4KKy8vIERvIG5vdCBleHBvc2UgdGhpcyBvdXRzaWRlIG9mIGhlbHBlcnMsIHN0aWNrIHRvIGhhdmluZyBmdW5jdGlvbnMgZm9yIHNwZWNpZmljCisvLyBjYXNlcyAoQ2xhc3NOYW1lKCksIEZpZWxkTmFtZSgpKSwgc28gdGhlcmUgaXMgYWx3YXlzIGNvbnNpc3RlbnQgc3VmZml4IHJ1bGVzLgorc3RyaW5nIFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoY29uc3Qgc3RyaW5nJiBpbnB1dCwgYm9vbCBmaXJzdF9jYXBpdGFsaXplZCkgeworICB2ZWN0b3I8c3RyaW5nPiB2YWx1ZXM7CisgIHN0cmluZyBjdXJyZW50OworCisgIGJvb2wgbGFzdF9jaGFyX3dhc19udW1iZXIgPSBmYWxzZTsKKyAgYm9vbCBsYXN0X2NoYXJfd2FzX2xvd2VyID0gZmFsc2U7CisgIGJvb2wgbGFzdF9jaGFyX3dhc191cHBlciA9IGZhbHNlOworICBmb3IgKGludCBpID0gMDsgaSA8IGlucHV0LnNpemUoKTsgaSsrKSB7CisgICAgY2hhciBjID0gaW5wdXRbaV07CisgICAgaWYgKGFzY2lpX2lzZGlnaXQoYykpIHsKKyAgICAgIGlmICghbGFzdF9jaGFyX3dhc19udW1iZXIpIHsKKyAgICAgICAgdmFsdWVzLnB1c2hfYmFjayhjdXJyZW50KTsKKyAgICAgICAgY3VycmVudCA9ICIiOworICAgICAgfQorICAgICAgY3VycmVudCArPSBjOworICAgICAgbGFzdF9jaGFyX3dhc19udW1iZXIgPSBsYXN0X2NoYXJfd2FzX2xvd2VyID0gbGFzdF9jaGFyX3dhc191cHBlciA9IGZhbHNlOworICAgICAgbGFzdF9jaGFyX3dhc19udW1iZXIgPSB0cnVlOworICAgIH0gZWxzZSBpZiAoYXNjaWlfaXNsb3dlcihjKSkgeworICAgICAgLy8gbG93ZXJjYXNlIGxldHRlciBjYW4gZm9sbG93IGEgbG93ZXJjYXNlIG9yIHVwcGVyY2FzZSBsZXR0ZXIKKyAgICAgIGlmICghbGFzdF9jaGFyX3dhc19sb3dlciAmJiAhbGFzdF9jaGFyX3dhc191cHBlcikgeworICAgICAgICB2YWx1ZXMucHVzaF9iYWNrKGN1cnJlbnQpOworICAgICAgICBjdXJyZW50ID0gIiI7CisgICAgICB9CisgICAgICBjdXJyZW50ICs9IGM7ICAvLyBhbHJlYWR5IGxvd2VyCisgICAgICBsYXN0X2NoYXJfd2FzX251bWJlciA9IGxhc3RfY2hhcl93YXNfbG93ZXIgPSBsYXN0X2NoYXJfd2FzX3VwcGVyID0gZmFsc2U7CisgICAgICBsYXN0X2NoYXJfd2FzX2xvd2VyID0gdHJ1ZTsKKyAgICB9IGVsc2UgaWYgKGFzY2lpX2lzdXBwZXIoYykpIHsKKyAgICAgIGlmICghbGFzdF9jaGFyX3dhc191cHBlcikgeworICAgICAgICB2YWx1ZXMucHVzaF9iYWNrKGN1cnJlbnQpOworICAgICAgICBjdXJyZW50ID0gIiI7CisgICAgICB9CisgICAgICBjdXJyZW50ICs9IGFzY2lpX3RvbG93ZXIoYyk7CisgICAgICBsYXN0X2NoYXJfd2FzX251bWJlciA9IGxhc3RfY2hhcl93YXNfbG93ZXIgPSBsYXN0X2NoYXJfd2FzX3VwcGVyID0gZmFsc2U7CisgICAgICBsYXN0X2NoYXJfd2FzX3VwcGVyID0gdHJ1ZTsKKyAgICB9IGVsc2UgeworICAgICAgbGFzdF9jaGFyX3dhc19udW1iZXIgPSBsYXN0X2NoYXJfd2FzX2xvd2VyID0gbGFzdF9jaGFyX3dhc191cHBlciA9IGZhbHNlOworICAgIH0KKyAgfQorICB2YWx1ZXMucHVzaF9iYWNrKGN1cnJlbnQpOworCisgIGZvciAodmVjdG9yPHN0cmluZz46Oml0ZXJhdG9yIGkgPSB2YWx1ZXMuYmVnaW4oKTsgaSAhPSB2YWx1ZXMuZW5kKCk7ICsraSkgeworICAgIHN0cmluZyB2YWx1ZSA9ICppOworICAgIGJvb2wgYWxsX3VwcGVyID0gKGtVcHBlclNlZ21lbnRzLmNvdW50KHZhbHVlKSA+IDApOworICAgIGZvciAoaW50IGogPSAwOyBqIDwgdmFsdWUubGVuZ3RoKCk7IGorKykgeworICAgICAgaWYgKGogPT0gMCB8fCBhbGxfdXBwZXIpIHsKKyAgICAgICAgdmFsdWVbal0gPSBhc2NpaV90b3VwcGVyKHZhbHVlW2pdKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIC8vIE5vdGhpbmcsIGFscmVhZHkgaW4gbG93ZXIuCisgICAgICB9CisgICAgfQorICAgICppID0gdmFsdWU7CisgIH0KKyAgc3RyaW5nIHJlc3VsdDsKKyAgZm9yICh2ZWN0b3I8c3RyaW5nPjo6aXRlcmF0b3IgaSA9IHZhbHVlcy5iZWdpbigpOyBpICE9IHZhbHVlcy5lbmQoKTsgKytpKSB7CisgICAgcmVzdWx0ICs9ICppOworICB9CisgIGlmICgocmVzdWx0Lmxlbmd0aCgpICE9IDApICYmICFmaXJzdF9jYXBpdGFsaXplZCkgeworICAgIHJlc3VsdFswXSA9IGFzY2lpX3RvbG93ZXIocmVzdWx0WzBdKTsKKyAgfQorICByZXR1cm4gcmVzdWx0OworfQorCitjb25zdCBjaGFyKiBjb25zdCBrUmVzZXJ2ZWRXb3JkTGlzdFtdID0geworICAgIC8vIE9iamVjdGl2ZSBDICJrZXl3b3JkcyIgdGhhdCBhcmVuJ3QgaW4gQworICAgIC8vIEZyb20KKyAgICAvLyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzE4NzM2MzAvcmVzZXJ2ZWQta2V5d29yZHMtaW4tb2JqZWN0aXZlLWMKKyAgICAiaWQiLCAiX2NtZCIsICJzdXBlciIsICJpbiIsICJvdXQiLCAiaW5vdXQiLCAiYnljb3B5IiwgImJ5cmVmIiwgIm9uZXdheSIsCisgICAgInNlbGYiLAorCisgICAgLy8gQy9DKysga2V5d29yZHMgKEluY2wgQysrIDB4MTEpCisgICAgLy8gRnJvbSBodHRwOi8vZW4uY3BwcmVmZXJlbmNlLmNvbS93L2NwcC9rZXl3b3JkcworICAgICJhbmQiLCAiYW5kX2VxIiwgImFsaWduYXMiLCAiYWxpZ25vZiIsICJhc20iLCAiYXV0byIsICJiaXRhbmQiLCAiYml0b3IiLAorICAgICJib29sIiwgImJyZWFrIiwgImNhc2UiLCAiY2F0Y2giLCAiY2hhciIsICJjaGFyMTZfdCIsICJjaGFyMzJfdCIsICJjbGFzcyIsCisgICAgImNvbXBsIiwgImNvbnN0IiwgImNvbnN0ZXhwciIsICJjb25zdF9jYXN0IiwgImNvbnRpbnVlIiwgImRlY2x0eXBlIiwKKyAgICAiZGVmYXVsdCIsICJkZWxldGUiLCAiZG91YmxlIiwgImR5bmFtaWNfY2FzdCIsICJlbHNlIiwgImVudW0iLCAiZXhwbGljaXQiLAorICAgICJleHBvcnQiLCAiZXh0ZXJuICIsICJmYWxzZSIsICJmbG9hdCIsICJmb3IiLCAiZnJpZW5kIiwgImdvdG8iLCAiaWYiLAorICAgICJpbmxpbmUiLCAiaW50IiwgImxvbmciLCAibXV0YWJsZSIsICJuYW1lc3BhY2UiLCAibmV3IiwgIm5vZXhjZXB0IiwgIm5vdCIsCisgICAgIm5vdF9lcSIsICJudWxscHRyIiwgIm9wZXJhdG9yIiwgIm9yIiwgIm9yX2VxIiwgInByaXZhdGUiLCAicHJvdGVjdGVkIiwKKyAgICAicHVibGljIiwgInJlZ2lzdGVyIiwgInJlaW50ZXJwcmV0X2Nhc3QiLCAicmV0dXJuIiwgInNob3J0IiwgInNpZ25lZCIsCisgICAgInNpemVvZiIsICJzdGF0aWMiLCAic3RhdGljX2Fzc2VydCIsICJzdGF0aWNfY2FzdCIsICJzdHJ1Y3QiLCAic3dpdGNoIiwKKyAgICAidGVtcGxhdGUiLCAidGhpcyIsICJ0aHJlYWRfbG9jYWwiLCAidGhyb3ciLCAidHJ1ZSIsICJ0cnkiLCAidHlwZWRlZiIsCisgICAgInR5cGVpZCIsICJ0eXBlbmFtZSIsICJ1bmlvbiIsICJ1bnNpZ25lZCIsICJ1c2luZyIsICJ2aXJ0dWFsIiwgInZvaWQiLAorICAgICJ2b2xhdGlsZSIsICJ3Y2hhcl90IiwgIndoaWxlIiwgInhvciIsICJ4b3JfZXEiLAorCisgICAgLy8gQzk5IGtleXdvcmRzCisgICAgLy8gRnJvbQorICAgIC8vIGh0dHA6Ly9wdWJsaWIuYm91bGRlci5pYm0uY29tL2luZm9jZW50ZXIvbG54cGNvbXAvdjh2MTAxL2luZGV4LmpzcD90b3BpYz0lMkZjb20uaWJtLnhsY3BwOGwuZG9jJTJGbGFuZ3VhZ2UlMkZyZWYlMkZrZXl3Lmh0bQorICAgICJyZXN0cmljdCIsCisKKyAgICAvLyBPYmplY3RpdmUtQyBSdW50aW1lIHR5cGVkZWZzCisgICAgLy8gRnJvbSA8b2JjL3J1bnRpbWUuaD4KKyAgICAiQ2F0ZWdvcnkiLCAiSXZhciIsICJNZXRob2QiLCAiUHJvdG9jb2wiLAorCisgICAgLy8gTlNPYmplY3QgTWV0aG9kcworICAgIC8vIG5ldyBpcyBjb3ZlcmVkIGJ5IEMrKyBrZXl3b3Jkcy4KKyAgICAiZGVzY3JpcHRpb24iLCAiZGVidWdEZXNjcmlwdGlvbiIsICJmaW5hbGl6ZSIsICJoYXNoIiwgImRlYWxsb2MiLCAiaW5pdCIsCisgICAgImNsYXNzIiwgInN1cGVyY2xhc3MiLCAicmV0YWluIiwgInJlbGVhc2UiLCAiYXV0b3JlbGVhc2UiLCAicmV0YWluQ291bnQiLAorICAgICJ6b25lIiwgImlzUHJveHkiLCAiY29weSIsICJtdXRhYmxlQ29weSIsICJjbGFzc0ZvckNvZGVyIiwKKworICAgIC8vIEdQQk1lc3NhZ2UgTWV0aG9kcworICAgIC8vIE9ubHkgbmVlZCB0byBhZGQgaW5zdGFuY2UgbWV0aG9kcyB0aGF0IG1heSBjb25mbGljdCB3aXRoCisgICAgLy8gbWV0aG9kIGRlY2xhcmVkIGluIHByb3Rvcy4gVGhlIG1haW4gY2FzZXMgYXJlIG1ldGhvZHMKKyAgICAvLyB0aGF0IHRha2Ugbm8gYXJndW1lbnRzLCBvciBzZXRGb286L2hhc0ZvbzogdHlwZSBtZXRob2RzLgorICAgICJjbGVhciIsICJkYXRhIiwgImRlbGltaXRlZERhdGEiLCAiZGVzY3JpcHRvciIsICJleHRlbnNpb25SZWdpc3RyeSIsCisgICAgImV4dGVuc2lvbnNDdXJyZW50bHlTZXQiLCAiaXNJbml0aWFsaXplZCIsICJzZXJpYWxpemVkU2l6ZSIsCisgICAgInNvcnRlZEV4dGVuc2lvbnNJblVzZSIsICJ1bmtub3duRmllbGRzIiwKKworICAgIC8vIE1hY1R5cGVzLmggbmFtZXMKKyAgICAiRml4ZWQiLCAiRnJhY3QiLCAiU2l6ZSIsICJMb2dpY2FsQWRkcmVzcyIsICJQaHlzaWNhbEFkZHJlc3MiLCAiQnl0ZUNvdW50IiwKKyAgICAiQnl0ZU9mZnNldCIsICJEdXJhdGlvbiIsICJBYnNvbHV0ZVRpbWUiLCAiT3B0aW9uQml0cyIsICJJdGVtQ291bnQiLAorICAgICJQQlZlcnNpb24iLCAiU2NyaXB0Q29kZSIsICJMYW5nQ29kZSIsICJSZWdpb25Db2RlIiwgIk9TVHlwZSIsCisgICAgIlByb2Nlc3NTZXJpYWxOdW1iZXIiLCAiUG9pbnQiLCAiUmVjdCIsICJGaXhlZFBvaW50IiwgIkZpeGVkUmVjdCIsICJTdHlsZSIsCisgICAgIlN0eWxlUGFyYW1ldGVyIiwgIlN0eWxlRmllbGQiLCAiVGltZVNjYWxlIiwgIlRpbWVCYXNlIiwgIlRpbWVSZWNvcmQiLAorfTsKKworaGFzaF9zZXQ8c3RyaW5nPiBrUmVzZXJ2ZWRXb3JkcyA9CisgICAgTWFrZVdvcmRzTWFwKGtSZXNlcnZlZFdvcmRMaXN0LCBHT09HTEVfQVJSQVlTSVpFKGtSZXNlcnZlZFdvcmRMaXN0KSk7CisKK3N0cmluZyBTYW5pdGl6ZU5hbWVGb3JPYmpDKGNvbnN0IHN0cmluZyYgaW5wdXQsIGNvbnN0IHN0cmluZyYgZXh0ZW5zaW9uKSB7CisgIGlmIChrUmVzZXJ2ZWRXb3Jkcy5jb3VudChpbnB1dCkgPiAwKSB7CisgICAgcmV0dXJuIGlucHV0ICsgZXh0ZW5zaW9uOworICB9CisgIHJldHVybiBpbnB1dDsKK30KKworc3RyaW5nIE5hbWVGcm9tRmllbGREZXNjcmlwdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgaWYgKGZpZWxkLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQKSB7CisgICAgcmV0dXJuIGZpZWxkLT5tZXNzYWdlX3R5cGUoKS0+bmFtZSgpOworICB9IGVsc2UgeworICAgIHJldHVybiBmaWVsZC0+bmFtZSgpOworICB9Cit9CisKKy8vIEVzY2FwZSBDKysgdHJpZ3JhcGhzIGJ5IGVzY2FwaW5nIHF1ZXN0aW9uIG1hcmtzIHRvIFw/CitzdHJpbmcgRXNjYXBlVHJpZ3JhcGhzKGNvbnN0IHN0cmluZyYgdG9fZXNjYXBlKSB7CisgIHJldHVybiBTdHJpbmdSZXBsYWNlKHRvX2VzY2FwZSwgIj8iLCAiXFw/IiwgdHJ1ZSk7Cit9CisKK3ZvaWQgUGF0aFNwbGl0KGNvbnN0IHN0cmluZyYgcGF0aCwgc3RyaW5nKiBkaXJlY3RvcnksIHN0cmluZyogYmFzZW5hbWUpIHsKKyAgc3RyaW5nOjpzaXplX3R5cGUgbGFzdF9zbGFzaCA9IHBhdGgucmZpbmQoJy8nKTsKKyAgaWYgKGxhc3Rfc2xhc2ggPT0gc3RyaW5nOjpucG9zKSB7CisgICAgaWYgKGRpcmVjdG9yeSkgeworICAgICAgKmRpcmVjdG9yeSA9ICIiOworICAgIH0KKyAgICBpZiAoYmFzZW5hbWUpIHsKKyAgICAgICpiYXNlbmFtZSA9IHBhdGg7CisgICAgfQorICB9IGVsc2UgeworICAgIGlmIChkaXJlY3RvcnkpIHsKKyAgICAgICpkaXJlY3RvcnkgPSBwYXRoLnN1YnN0cigwLCBsYXN0X3NsYXNoKTsKKyAgICB9CisgICAgaWYgKGJhc2VuYW1lKSB7CisgICAgICAqYmFzZW5hbWUgPSBwYXRoLnN1YnN0cihsYXN0X3NsYXNoICsgMSk7CisgICAgfQorICB9Cit9CisKK2Jvb2wgSXNTcGVjaWFsTmFtZShjb25zdCBzdHJpbmcmIG5hbWUsIGNvbnN0IHN0cmluZyogc3BlY2lhbF9uYW1lcywKKyAgICAgICAgICAgICAgICAgICBzaXplX3QgY291bnQpIHsKKyAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBjb3VudDsgKytpKSB7CisgICAgc2l6ZV90IGxlbmd0aCA9IHNwZWNpYWxfbmFtZXNbaV0ubGVuZ3RoKCk7CisgICAgaWYgKG5hbWUuY29tcGFyZSgwLCBsZW5ndGgsIHNwZWNpYWxfbmFtZXNbaV0pID09IDApIHsKKyAgICAgIGlmIChuYW1lLmxlbmd0aCgpID4gbGVuZ3RoKSB7CisgICAgICAgIC8vIElmIG5hbWUgaXMgbG9uZ2VyIHRoYW4gdGhlIHJldGFpbmVkX25hbWVbaV0gdGhhdCBpdCBtYXRjaGVzCisgICAgICAgIC8vIHRoZSBuZXh0IGNoYXJhY3RlciBtdXN0IGJlIG5vdCBsb3dlciBjYXNlIChuZXd0b24gdnMgbmV3VG9uIHZzCisgICAgICAgIC8vIG5ld190b24pLgorICAgICAgICByZXR1cm4gIWFzY2lpX2lzbG93ZXIobmFtZVtsZW5ndGhdKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgfQorICAgIH0KKyAgfQorICByZXR1cm4gZmFsc2U7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCitzdHJpbmcgU3RyaXBQcm90byhjb25zdCBzdHJpbmcmIGZpbGVuYW1lKSB7CisgIGlmIChIYXNTdWZmaXhTdHJpbmcoZmlsZW5hbWUsICIucHJvdG9kZXZlbCIpKSB7CisgICAgcmV0dXJuIFN0cmlwU3VmZml4U3RyaW5nKGZpbGVuYW1lLCAiLnByb3RvZGV2ZWwiKTsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gU3RyaXBTdWZmaXhTdHJpbmcoZmlsZW5hbWUsICIucHJvdG8iKTsKKyAgfQorfQorCitib29sIElzUmV0YWluZWROYW1lKGNvbnN0IHN0cmluZyYgbmFtZSkgeworICAvLyBMaXN0IG9mIHByZWZpeGVzIGZyb20KKyAgLy8gaHR0cDovL2RldmVsb3Blci5hcHBsZS5jb20vbGlicmFyeS9tYWMvI2RvY3VtZW50YXRpb24vQ29jb2EvQ29uY2VwdHVhbC9NZW1vcnlNZ210L0FydGljbGVzL21tUnVsZXMuaHRtbAorICBzdGF0aWMgY29uc3Qgc3RyaW5nIHJldGFpbmVkX25hbWVzW10gPSB7Im5ldyIsICJhbGxvYyIsICJjb3B5IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJtdXRhYmxlQ29weSJ9OworICByZXR1cm4gSXNTcGVjaWFsTmFtZShuYW1lLCByZXRhaW5lZF9uYW1lcywKKyAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHJldGFpbmVkX25hbWVzKSAvIHNpemVvZihyZXRhaW5lZF9uYW1lc1swXSkpOworfQorCitib29sIElzSW5pdE5hbWUoY29uc3Qgc3RyaW5nJiBuYW1lKSB7CisgIHN0YXRpYyBjb25zdCBzdHJpbmcgaW5pdF9uYW1lc1tdID0geyJpbml0In07CisgIHJldHVybiBJc1NwZWNpYWxOYW1lKG5hbWUsIGluaXRfbmFtZXMsCisgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihpbml0X25hbWVzKSAvIHNpemVvZihpbml0X25hbWVzWzBdKSk7Cit9CisKK3N0cmluZyBCYXNlRmlsZU5hbWUoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUpIHsKKyAgc3RyaW5nIGJhc2VuYW1lOworICBQYXRoU3BsaXQoZmlsZS0+bmFtZSgpLCBOVUxMLCAmYmFzZW5hbWUpOworICByZXR1cm4gYmFzZW5hbWU7Cit9CisKK3N0cmluZyBGaWxlTmFtZShjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSkgeworICBzdHJpbmcgcGF0aCA9IEZpbGVQYXRoKGZpbGUpOworICBzdHJpbmcgYmFzZW5hbWU7CisgIFBhdGhTcGxpdChwYXRoLCBOVUxMLCAmYmFzZW5hbWUpOworICByZXR1cm4gYmFzZW5hbWU7Cit9CisKK3N0cmluZyBGaWxlUGF0aChjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSkgeworICBzdHJpbmcgb3V0cHV0OworICBzdHJpbmcgYmFzZW5hbWU7CisgIHN0cmluZyBkaXJlY3Rvcnk7CisgIFBhdGhTcGxpdChmaWxlLT5uYW1lKCksICZkaXJlY3RvcnksICZiYXNlbmFtZSk7CisgIGlmIChkaXJlY3RvcnkubGVuZ3RoKCkgPiAwKSB7CisgICAgb3V0cHV0ID0gZGlyZWN0b3J5ICsgIi8iOworICB9CisgIGJhc2VuYW1lID0gU3RyaXBQcm90byhiYXNlbmFtZSk7CisKKyAgLy8gQ2FtZWxDYXNlIHRvIGJlIG1vcmUgT2JqQyBmcmllbmRseS4KKyAgYmFzZW5hbWUgPSBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlKGJhc2VuYW1lLCB0cnVlKTsKKworICBvdXRwdXQgKz0gYmFzZW5hbWU7CisgIHJldHVybiBvdXRwdXQ7Cit9CisKK3N0cmluZyBGaWxlQ2xhc3NQcmVmaXgoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUpIHsKKyAgLy8gRGVmYXVsdCBpcyBlbXB0eSBzdHJpbmcsIG5vIG5lZWQgdG8gY2hlY2sgaGFzX29iamNfY2xhc3NfcHJlZml4LgorICBzdHJpbmcgcmVzdWx0ID0gZmlsZS0+b3B0aW9ucygpLm9iamNfY2xhc3NfcHJlZml4KCk7CisgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0cmluZyBGaWxlQ2xhc3NOYW1lKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKSB7CisgIHN0cmluZyBuYW1lID0gRmlsZUNsYXNzUHJlZml4KGZpbGUpOworICBuYW1lICs9IFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoU3RyaXBQcm90byhCYXNlRmlsZU5hbWUoZmlsZSkpLCB0cnVlKTsKKyAgbmFtZSArPSAiUm9vdCI7CisgIC8vIFRoZXJlIGFyZW4ndCByZWFsbHkgYW55IHJlc2VydmVkIHdvcmRzIHRoYXQgZW5kIGluICJSb290IiwgYnV0IHBsYXlpbmcKKyAgLy8gaXQgc2FmZSBhbmQgY2hlY2tpbmcuCisgIHJldHVybiBTYW5pdGl6ZU5hbWVGb3JPYmpDKG5hbWUsICJfUm9vdENsYXNzIik7Cit9CisKK3N0cmluZyBDbGFzc05hbWVXb3JrZXIoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBzdHJpbmcgbmFtZTsKKyAgaWYgKGRlc2NyaXB0b3ItPmNvbnRhaW5pbmdfdHlwZSgpICE9IE5VTEwpIHsKKyAgICBuYW1lID0gQ2xhc3NOYW1lV29ya2VyKGRlc2NyaXB0b3ItPmNvbnRhaW5pbmdfdHlwZSgpKTsKKyAgICBuYW1lICs9ICJfIjsKKyAgfQorICByZXR1cm4gbmFtZSArIGRlc2NyaXB0b3ItPm5hbWUoKTsKK30KKworc3RyaW5nIENsYXNzTmFtZVdvcmtlcihjb25zdCBFbnVtRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBzdHJpbmcgbmFtZTsKKyAgaWYgKGRlc2NyaXB0b3ItPmNvbnRhaW5pbmdfdHlwZSgpICE9IE5VTEwpIHsKKyAgICBuYW1lID0gQ2xhc3NOYW1lV29ya2VyKGRlc2NyaXB0b3ItPmNvbnRhaW5pbmdfdHlwZSgpKTsKKyAgICBuYW1lICs9ICJfIjsKKyAgfQorICByZXR1cm4gbmFtZSArIGRlc2NyaXB0b3ItPm5hbWUoKTsKK30KKworc3RyaW5nIENsYXNzTmFtZShjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIC8vIDEuIE1lc3NhZ2UgbmFtZXMgYXJlIHVzZWQgYXMgaXMgKHN0eWxlIGNhbGxzIGZvciBDYW1lbENhc2UsIHRydXN0IGl0KS4KKyAgLy8gMi4gQ2hlY2sgZm9yIHJlc2VydmVkIHdvcmQgYXQgdGhlIHZlcnkgZW5kIGFuZCB0aGVuIHN1ZmZpeCB0aGluZ3MuCisgIHN0cmluZyBwcmVmaXggPSBGaWxlQ2xhc3NQcmVmaXgoZGVzY3JpcHRvci0+ZmlsZSgpKTsKKyAgc3RyaW5nIG5hbWUgPSBDbGFzc05hbWVXb3JrZXIoZGVzY3JpcHRvcik7CisgIHJldHVybiBTYW5pdGl6ZU5hbWVGb3JPYmpDKHByZWZpeCArIG5hbWUsICJfQ2xhc3MiKTsKK30KKworc3RyaW5nIEVudW1OYW1lKGNvbnN0IEVudW1EZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIC8vIDEuIEVudW0gbmFtZXMgYXJlIHVzZWQgYXMgaXMgKHN0eWxlIGNhbGxzIGZvciBDYW1lbENhc2UsIHRydXN0IGl0KS4KKyAgLy8gMi4gQ2hlY2sgZm9yIHJlc2VydmVkIHdvcmQgYXQgdGhlIGV2ZXJ5IGVuZCBhbmQgdGhlbiBzdWZmaXggdGhpbmdzLgorICAvLyAgICAgIG1lc3NhZ2UgRml4ZWQgeworICAvLyAgICAgICAgbWVzc2FnZSBTaXplIHsuLi59CisgIC8vICAgICAgICBlbnVtIE11bWJsZSB7Li4ufQorICAvLyAgICAgIC4uLgorICAvLyAgICAgIH0KKyAgLy8gICAgeWllbGRzIEZpeGVkX0NsYXNzLCBGaXhlZF9TaXplLgorICBzdHJpbmcgbmFtZSA9IEZpbGVDbGFzc1ByZWZpeChkZXNjcmlwdG9yLT5maWxlKCkpOworICBuYW1lICs9IENsYXNzTmFtZVdvcmtlcihkZXNjcmlwdG9yKTsKKyAgcmV0dXJuIFNhbml0aXplTmFtZUZvck9iakMobmFtZSwgIl9FbnVtIik7Cit9CisKK3N0cmluZyBFbnVtVmFsdWVOYW1lKGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgLy8gQmVjYXVzZSBvZiB0aGUgU3dpdGNoIGVudW0gY29tcGF0aWJpbGl0eSwgdGhlIG5hbWUgb24gdGhlIGVudW0gaGFzIHRvIGhhdmUKKyAgLy8gdGhlIHN1ZmZpeCBoYW5kaW5nLCBzbyBpdCBzbGlnaHRseSBkaXZlcmdlcyBmcm9tIGhvdyBuZXN0ZWQgY2xhc3NlcyB3b3JrLgorICAvLyAgIGVudW0gRml4ZWQgeworICAvLyAgICAgRk9PID0gMQorICAvLyAgIH0KKyAgLy8geWllbGRzIEZpeGVkX0VudW0gYW5kIEZpeGVkX0VudW1fRm9vIChub3QgRml4ZWRfRm9vKS4KKyAgY29uc3Qgc3RyaW5nJiBjbGFzc19uYW1lID0gRW51bU5hbWUoZGVzY3JpcHRvci0+dHlwZSgpKTsKKyAgY29uc3Qgc3RyaW5nJiB2YWx1ZV9zdHIgPSBVbmRlcnNjb3Jlc1RvQ2FtZWxDYXNlKGRlc2NyaXB0b3ItPm5hbWUoKSwgdHJ1ZSk7CisgIGNvbnN0IHN0cmluZyYgbmFtZSA9IGNsYXNzX25hbWUgKyAiXyIgKyB2YWx1ZV9zdHI7CisgIC8vIFRoZXJlIGFyZW4ndCByZWFsbHkgYW55IHJlc2VydmVkIHdvcmRzIHdpdGggYW4gdW5kZXJzY29yZSBhbmQgYSBsZWFkaW5nCisgIC8vIGNhcGl0YWwgbGV0dGVyLCBidXQgcGxheWluZyBpdCBzYWZlIGFuZCBjaGVja2luZy4KKyAgcmV0dXJuIFNhbml0aXplTmFtZUZvck9iakMobmFtZSwgIl9WYWx1ZSIpOworfQorCitzdHJpbmcgRW51bVZhbHVlU2hvcnROYW1lKGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgLy8gRW51bSB2YWx1ZSBuYW1lcyAoRW51bVZhbHVlTmFtZSBhYm92ZSkgYXJlIHRoZSBlbnVtIG5hbWUgdHVybmVkIGludG8KKyAgLy8gYSBjbGFzcyBuYW1lIGFuZCB0aGVuIHRoZSB2YWx1ZSBuYW1lIGlzIENhbWVsQ2FzZWQgYW5kIGNvbmNhdGVuYXRlZDsgdGhlCisgIC8vIHdob2xlIHRoaW5nIHRoZW4gZ2V0cyBzYW5pdGl6ZWQgZm9yIHJlc2VydmVkIHdvcmRzLgorICAvLyBUaGUgInNob3J0IG5hbWUiIGlzIGludGVuZGVkIHRvIGJlIHRoZSBmaW5hbCBsZWFmLCB0aGUgdmFsdWUgbmFtZTsgYnV0CisgIC8vIHlvdSBjYW4ndCBzaW1wbHkgc2VuZCB0aGF0IG9mZiB0byBzYW5pdGl6ZSBhcyB0aGF0IGNvdWxkIHJlc3VsdCBpbiBpdAorICAvLyBnZXR0aW5nIG1vZGlmaWVkIHdoZW4gdGhlIGZ1bGwgbmFtZSBkaWRuJ3QuICBGb3IgZXhhbXBsZSBlbnVtCisgIC8vICJTdG9yYWdlTW9kZXMiIGhhcyBhIHZhbHVlICJyZXRhaW4iLiAgU28gdGhlIGZ1bGwgbmFtZSBpcworICAvLyAiU3RvcmFnZU1vZGVzX1JldGFpbiIsIGJ1dCBpZiB3ZSBzYW5pdGl6ZSAicmV0YWluIiBpdCB3b3VsZCBiZWNvbWUKKyAgLy8gIlJldGFpblZhbHVlIi4KKyAgLy8gU28gdGhlIHJpZ2h0IHdheSB0byBnZXQgdGhlIHNob3J0IG5hbWUgaXMgdG8gdGFrZSB0aGUgZnVsbCBlbnVtIG5hbWUKKyAgLy8gYW5kIHRoZW4gc3RyaXAgb2ZmIHRoZSBlbnVtIG5hbWUgKGxlYXZpbmcgdGhlIHZhbHVlIG5hbWUgYW5kIGFueXRoaW5nCisgIC8vIGRvbmUgYnkgc2FuaXRpemUpLgorICBjb25zdCBzdHJpbmcmIGNsYXNzX25hbWUgPSBFbnVtTmFtZShkZXNjcmlwdG9yLT50eXBlKCkpOworICBjb25zdCBzdHJpbmcmIGxvbmdfbmFtZV9wcmVmaXggPSBjbGFzc19uYW1lICsgIl8iOworICBjb25zdCBzdHJpbmcmIGxvbmdfbmFtZSA9IEVudW1WYWx1ZU5hbWUoZGVzY3JpcHRvcik7CisgIHJldHVybiBTdHJpcFByZWZpeFN0cmluZyhsb25nX25hbWUsIGxvbmdfbmFtZV9wcmVmaXgpOworfQorCitzdHJpbmcgVW5DYW1lbENhc2VFbnVtU2hvcnROYW1lKGNvbnN0IHN0cmluZyYgbmFtZSkgeworICBzdHJpbmcgcmVzdWx0OworICBmb3IgKGludCBpID0gMDsgaSA8IG5hbWUuc2l6ZSgpOyBpKyspIHsKKyAgICBjaGFyIGMgPSBuYW1lW2ldOworICAgIGlmIChpID4gMCAmJiBhc2NpaV9pc3VwcGVyKGMpKSB7CisgICAgICByZXN1bHQgKz0gJ18nOworICAgIH0KKyAgICByZXN1bHQgKz0gYXNjaWlfdG91cHBlcihjKTsKKyAgfQorICByZXR1cm4gcmVzdWx0OworfQorCitzdHJpbmcgRXh0ZW5zaW9uTWV0aG9kTmFtZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgY29uc3Qgc3RyaW5nJiBuYW1lID0gTmFtZUZyb21GaWVsZERlc2NyaXB0b3IoZGVzY3JpcHRvcik7CisgIGNvbnN0IHN0cmluZyYgcmVzdWx0ID0gVW5kZXJzY29yZXNUb0NhbWVsQ2FzZShuYW1lLCBmYWxzZSk7CisgIHJldHVybiBTYW5pdGl6ZU5hbWVGb3JPYmpDKHJlc3VsdCwgIl9FeHRlbnNpb24iKTsKK30KKworc3RyaW5nIEZpZWxkTmFtZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIGNvbnN0IHN0cmluZyYgbmFtZSA9IE5hbWVGcm9tRmllbGREZXNjcmlwdG9yKGZpZWxkKTsKKyAgc3RyaW5nIHJlc3VsdCA9IFVuZGVyc2NvcmVzVG9DYW1lbENhc2UobmFtZSwgZmFsc2UpOworICBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkgJiYgIWZpZWxkLT5pc19tYXAoKSkgeworICAgIC8vIEFkZCAiQXJyYXkiIGJlZm9yZSBkbyBjaGVjayBmb3IgcmVzZXJ2ZWQgd29ybGRzLgorICAgIHJlc3VsdCArPSAiQXJyYXkiOworICB9IGVsc2UgeworICAgIC8vIElmIGl0IHdhc24ndCByZXBlYXRlZCwgYnV0IGVuZHMgaW4gIkFycmF5IiwgZm9yY2Ugb24gdGhlIF9wIHN1ZmZpeC4KKyAgICBpZiAoSGFzU3VmZml4U3RyaW5nKHJlc3VsdCwgIkFycmF5IikpIHsKKyAgICAgIHJlc3VsdCArPSAiX3AiOworICAgIH0KKyAgfQorICByZXR1cm4gU2FuaXRpemVOYW1lRm9yT2JqQyhyZXN1bHQsICJfcCIpOworfQorCitzdHJpbmcgRmllbGROYW1lQ2FwaXRhbGl6ZWQoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICAvLyBXYW50IHRoZSBzYW1lIHN1ZmZpeCBoYW5kbGluZywgc28gdXBjYXNlIHRoZSBmaXJzdCBsZXR0ZXIgb2YgdGhlIG90aGVyCisgIC8vIG5hbWUuCisgIHN0cmluZyByZXN1bHQgPSBGaWVsZE5hbWUoZmllbGQpOworICBpZiAocmVzdWx0Lmxlbmd0aCgpID4gMCkgeworICAgIHJlc3VsdFswXSA9IGFzY2lpX3RvdXBwZXIocmVzdWx0WzBdKTsKKyAgfQorICByZXR1cm4gcmVzdWx0OworfQorCitzdHJpbmcgT25lb2ZFbnVtTmFtZShjb25zdCBPbmVvZkRlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgY29uc3QgRGVzY3JpcHRvciogZmllbGREZXNjcmlwdG9yID0gZGVzY3JpcHRvci0+Y29udGFpbmluZ190eXBlKCk7CisgIHN0cmluZyBuYW1lID0gQ2xhc3NOYW1lKGZpZWxkRGVzY3JpcHRvcik7CisgIG5hbWUgKz0gIl8iICsgVW5kZXJzY29yZXNUb0NhbWVsQ2FzZShkZXNjcmlwdG9yLT5uYW1lKCksIHRydWUpICsgIl9PbmVPZkNhc2UiOworICAvLyBObyBzYW5pdGl6ZSBuZWVkZWQgYmVjYXVzZSB0aGUgT1MgbmV2ZXIgaGFzIG5hbWVzIHRoYXQgZW5kIGluIF9PbmVPZkNhc2UuCisgIHJldHVybiBuYW1lOworfQorCitzdHJpbmcgT25lb2ZOYW1lKGNvbnN0IE9uZW9mRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBzdHJpbmcgbmFtZSA9IFVuZGVyc2NvcmVzVG9DYW1lbENhc2UoZGVzY3JpcHRvci0+bmFtZSgpLCBmYWxzZSk7CisgIC8vIE5vIHNhbml0aXplIG5lZWRlZCBiZWNhdXNlIGl0IGdldHMgT25lT2ZDYXNlIGFkZGVkIGFuZCB0aGF0IHNob3VsZG4ndAorICAvLyBldmVyIGNvbmZsaWN0LgorICByZXR1cm4gbmFtZTsKK30KKworc3RyaW5nIE9uZW9mTmFtZUNhcGl0YWxpemVkKGNvbnN0IE9uZW9mRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICAvLyBVc2UgdGhlIGNvbW1vbiBoYW5kbGluZyBhbmQgdGhlbiB1cC1jYXNlIHRoZSBmaXJzdCBsZXR0ZXIuCisgIHN0cmluZyByZXN1bHQgPSBPbmVvZk5hbWUoZGVzY3JpcHRvcik7CisgIGlmIChyZXN1bHQubGVuZ3RoKCkgPiAwKSB7CisgICAgcmVzdWx0WzBdID0gYXNjaWlfdG91cHBlcihyZXN1bHRbMF0pOworICB9CisgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0cmluZyBVbkNhbWVsQ2FzZUZpZWxkTmFtZShjb25zdCBzdHJpbmcmIG5hbWUsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgc3RyaW5nIHdvcmtlcihuYW1lKTsKKyAgaWYgKEhhc1N1ZmZpeFN0cmluZyh3b3JrZXIsICJfcCIpKSB7CisgICAgd29ya2VyID0gU3RyaXBTdWZmaXhTdHJpbmcod29ya2VyLCAiX3AiKTsKKyAgfQorICBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkgJiYgSGFzU3VmZml4U3RyaW5nKHdvcmtlciwgIkFycmF5IikpIHsKKyAgICB3b3JrZXIgPSBTdHJpcFN1ZmZpeFN0cmluZyh3b3JrZXIsICJBcnJheSIpOworICB9CisgIGlmIChmaWVsZC0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9HUk9VUCkgeworICAgIGlmICh3b3JrZXIubGVuZ3RoKCkgPiAwKSB7CisgICAgICBpZiAoYXNjaWlfaXNsb3dlcih3b3JrZXJbMF0pKSB7CisgICAgICAgIHdvcmtlclswXSA9IGFzY2lpX3RvdXBwZXIod29ya2VyWzBdKTsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIHdvcmtlcjsKKyAgfSBlbHNlIHsKKyAgICBzdHJpbmcgcmVzdWx0OworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgd29ya2VyLnNpemUoKTsgaSsrKSB7CisgICAgICBjaGFyIGMgPSB3b3JrZXJbaV07CisgICAgICBpZiAoYXNjaWlfaXN1cHBlcihjKSkgeworICAgICAgICBpZiAoaSA+IDApIHsKKyAgICAgICAgICByZXN1bHQgKz0gJ18nOworICAgICAgICB9CisgICAgICAgIHJlc3VsdCArPSBhc2NpaV90b2xvd2VyKGMpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcmVzdWx0ICs9IGM7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7CisgIH0KK30KKworc3RyaW5nIEdldENhcGl0YWxpemVkVHlwZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIHN3aXRjaCAoZmllbGQtPnR5cGUoKSkgeworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0lOVDMyOgorICAgICAgcmV0dXJuICJJbnQzMiI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfVUlOVDMyOgorICAgICAgcmV0dXJuICJVSW50MzIiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NJTlQzMjoKKyAgICAgIHJldHVybiAiU0ludDMyIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9GSVhFRDMyOgorICAgICAgcmV0dXJuICJGaXhlZDMyIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TRklYRUQzMjoKKyAgICAgIHJldHVybiAiU0ZpeGVkMzIiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0lOVDY0OgorICAgICAgcmV0dXJuICJJbnQ2NCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfVUlOVDY0OgorICAgICAgcmV0dXJuICJVSW50NjQiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NJTlQ2NDoKKyAgICAgIHJldHVybiAiU0ludDY0IjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9GSVhFRDY0OgorICAgICAgcmV0dXJuICJGaXhlZDY0IjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TRklYRUQ2NDoKKyAgICAgIHJldHVybiAiU0ZpeGVkNjQiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0ZMT0FUOgorICAgICAgcmV0dXJuICJGbG9hdCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRE9VQkxFOgorICAgICAgcmV0dXJuICJEb3VibGUiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0JPT0w6CisgICAgICByZXR1cm4gIkJvb2wiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NUUklORzoKKyAgICAgIHJldHVybiAiU3RyaW5nIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9CWVRFUzoKKyAgICAgIHJldHVybiAiQnl0ZXMiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0VOVU06CisgICAgICByZXR1cm4gIkVudW0iOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQOgorICAgICAgcmV0dXJuICJHcm91cCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfTUVTU0FHRToKKyAgICAgIHJldHVybiAiTWVzc2FnZSI7CisgIH0KKworICAvLyBTb21lIGNvbXBpbGVycyByZXBvcnQgcmVhY2hpbmcgZW5kIG9mIGZ1bmN0aW9uIGV2ZW4gdGhvdWdoIGFsbCBjYXNlcyBvZgorICAvLyB0aGUgZW51bSBhcmUgaGFuZGVkIGluIHRoZSBzd2l0Y2guCisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJDYW4ndCBnZXQgaGVyZS4iOworICByZXR1cm4gTlVMTDsKK30KKworT2JqZWN0aXZlQ1R5cGUgR2V0T2JqZWN0aXZlQ1R5cGUoRmllbGREZXNjcmlwdG9yOjpUeXBlIGZpZWxkX3R5cGUpIHsKKyAgc3dpdGNoIChmaWVsZF90eXBlKSB7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfSU5UMzI6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0lOVDMyOgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NGSVhFRDMyOgorICAgICAgcmV0dXJuIE9CSkVDVElWRUNUWVBFX0lOVDMyOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfVUlOVDMyOgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0ZJWEVEMzI6CisgICAgICByZXR1cm4gT0JKRUNUSVZFQ1RZUEVfVUlOVDMyOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfSU5UNjQ6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0lOVDY0OgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NGSVhFRDY0OgorICAgICAgcmV0dXJuIE9CSkVDVElWRUNUWVBFX0lOVDY0OworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfVUlOVDY0OgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0ZJWEVENjQ6CisgICAgICByZXR1cm4gT0JKRUNUSVZFQ1RZUEVfVUlOVDY0OworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRkxPQVQ6CisgICAgICByZXR1cm4gT0JKRUNUSVZFQ1RZUEVfRkxPQVQ7CisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9ET1VCTEU6CisgICAgICByZXR1cm4gT0JKRUNUSVZFQ1RZUEVfRE9VQkxFOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfQk9PTDoKKyAgICAgIHJldHVybiBPQkpFQ1RJVkVDVFlQRV9CT09MRUFOOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU1RSSU5HOgorICAgICAgcmV0dXJuIE9CSkVDVElWRUNUWVBFX1NUUklORzsKKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0JZVEVTOgorICAgICAgcmV0dXJuIE9CSkVDVElWRUNUWVBFX0RBVEE7CisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9FTlVNOgorICAgICAgcmV0dXJuIE9CSkVDVElWRUNUWVBFX0VOVU07CisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9HUk9VUDoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9NRVNTQUdFOgorICAgICAgcmV0dXJuIE9CSkVDVElWRUNUWVBFX01FU1NBR0U7CisgIH0KKworICAvLyBTb21lIGNvbXBpbGVycyByZXBvcnQgcmVhY2hpbmcgZW5kIG9mIGZ1bmN0aW9uIGV2ZW4gdGhvdWdoIGFsbCBjYXNlcyBvZgorICAvLyB0aGUgZW51bSBhcmUgaGFuZGVkIGluIHRoZSBzd2l0Y2guCisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJDYW4ndCBnZXQgaGVyZS4iOworICByZXR1cm4gT0JKRUNUSVZFQ1RZUEVfSU5UMzI7Cit9CisKK2Jvb2wgSXNQcmltaXRpdmVUeXBlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgT2JqZWN0aXZlQ1R5cGUgdHlwZSA9IEdldE9iamVjdGl2ZUNUeXBlKGZpZWxkKTsKKyAgc3dpdGNoICh0eXBlKSB7CisgICAgY2FzZSBPQkpFQ1RJVkVDVFlQRV9JTlQzMjoKKyAgICBjYXNlIE9CSkVDVElWRUNUWVBFX1VJTlQzMjoKKyAgICBjYXNlIE9CSkVDVElWRUNUWVBFX0lOVDY0OgorICAgIGNhc2UgT0JKRUNUSVZFQ1RZUEVfVUlOVDY0OgorICAgIGNhc2UgT0JKRUNUSVZFQ1RZUEVfRkxPQVQ6CisgICAgY2FzZSBPQkpFQ1RJVkVDVFlQRV9ET1VCTEU6CisgICAgY2FzZSBPQkpFQ1RJVkVDVFlQRV9CT09MRUFOOgorICAgIGNhc2UgT0JKRUNUSVZFQ1RZUEVfRU5VTToKKyAgICAgIHJldHVybiB0cnVlOworICAgICAgYnJlYWs7CisgICAgZGVmYXVsdDoKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgfQorfQorCitib29sIElzUmVmZXJlbmNlVHlwZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIHJldHVybiAhSXNQcmltaXRpdmVUeXBlKGZpZWxkKTsKK30KKworc3RhdGljIHN0cmluZyBIYW5kbGVFeHRyZW1lRmxvYXRpbmdQb2ludChzdHJpbmcgdmFsLCBib29sIGFkZF9mbG9hdF9zdWZmaXgpIHsKKyAgaWYgKHZhbCA9PSAibmFuIikgeworICAgIHJldHVybiAiTkFOIjsKKyAgfSBlbHNlIGlmICh2YWwgPT0gImluZiIpIHsKKyAgICByZXR1cm4gIklORklOSVRZIjsKKyAgfSBlbHNlIGlmICh2YWwgPT0gIi1pbmYiKSB7CisgICAgcmV0dXJuICItSU5GSU5JVFkiOworICB9IGVsc2UgeworICAgIC8vIGZsb2F0IHN0cmluZ3Mgd2l0aCAuLCBlIG9yIEUgbmVlZCB0byBoYXZlIGYgYXBwZW5kZWQKKyAgICBpZiAoYWRkX2Zsb2F0X3N1ZmZpeCAmJgorICAgICAgICAodmFsLmZpbmQoIi4iKSAhPSBzdHJpbmc6Om5wb3MgfHwgdmFsLmZpbmQoImUiKSAhPSBzdHJpbmc6Om5wb3MgfHwKKyAgICAgICAgIHZhbC5maW5kKCJFIikgIT0gc3RyaW5nOjpucG9zKSkgeworICAgICAgdmFsICs9ICJmIjsKKyAgICB9CisgICAgcmV0dXJuIHZhbDsKKyAgfQorfQorCitzdHJpbmcgR1BCR2VuZXJpY1ZhbHVlRmllbGROYW1lKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgLy8gUmV0dXJucyB0aGUgZmllbGQgd2l0aGluIHRoZSBHUEJHZW5lcmljVmFsdWUgdW5pb24gdG8gdXNlIGZvciB0aGUgZ2l2ZW4KKyAgLy8gZmllbGQuCisgIGlmIChmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgeworICAgICAgcmV0dXJuICJ2YWx1ZU1lc3NhZ2UiOworICB9CisgIHN3aXRjaCAoZmllbGQtPmNwcF90eXBlKCkpIHsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9JTlQzMjoKKyAgICAgIHJldHVybiAidmFsdWVJbnQzMiI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDMyOgorICAgICAgcmV0dXJuICJ2YWx1ZVVJbnQzMiI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UNjQ6CisgICAgICByZXR1cm4gInZhbHVlSW50NjQiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1VJTlQ2NDoKKyAgICAgIHJldHVybiAidmFsdWVVSW50NjQiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0ZMT0FUOgorICAgICAgcmV0dXJuICJ2YWx1ZUZsb2F0IjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9ET1VCTEU6CisgICAgICByZXR1cm4gInZhbHVlRG91YmxlIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9CT09MOgorICAgICAgcmV0dXJuICJ2YWx1ZUJvb2wiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORzoKKyAgICAgIGlmIChmaWVsZC0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9CWVRFUykgeworICAgICAgICByZXR1cm4gInZhbHVlRGF0YSI7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gInZhbHVlU3RyaW5nIjsKKyAgICAgIH0KKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9FTlVNOgorICAgICAgcmV0dXJuICJ2YWx1ZUVudW0iOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U6CisgICAgICByZXR1cm4gInZhbHVlTWVzc2FnZSI7CisgIH0KKworICAvLyBTb21lIGNvbXBpbGVycyByZXBvcnQgcmVhY2hpbmcgZW5kIG9mIGZ1bmN0aW9uIGV2ZW4gdGhvdWdoIGFsbCBjYXNlcyBvZgorICAvLyB0aGUgZW51bSBhcmUgaGFuZGVkIGluIHRoZSBzd2l0Y2guCisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJDYW4ndCBnZXQgaGVyZS4iOworICByZXR1cm4gTlVMTDsKK30KKworCitzdHJpbmcgRGVmYXVsdFZhbHVlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgLy8gUmVwZWF0ZWQgZmllbGRzIGRvbid0IGhhdmUgZGVmYXVsdHMuCisgIGlmIChmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgeworICAgIHJldHVybiAibmlsIjsKKyAgfQorCisgIC8vIFN3aXRjaCBvbiBjcHBfdHlwZSBzaW5jZSB3ZSBuZWVkIHRvIGtub3cgd2hpY2ggZGVmYXVsdF92YWx1ZV8qIG1ldGhvZAorICAvLyBvZiBGaWVsZERlc2NyaXB0b3IgdG8gY2FsbC4KKyAgc3dpdGNoIChmaWVsZC0+Y3BwX3R5cGUoKSkgeworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0lOVDMyOgorICAgICAgLy8gZ2NjIGFuZCBsbHZtIHJlamVjdCB0aGUgZGVjaW1hbCBmb3JtIG9mIGtpbnQzMm1pbiBhbmQga2ludDY0bWluLgorICAgICAgaWYgKGZpZWxkLT5kZWZhdWx0X3ZhbHVlX2ludDMyKCkgPT0gSU5UX01JTikgeworICAgICAgICByZXR1cm4gIi0weDgwMDAwMDAwIjsKKyAgICAgIH0KKyAgICAgIHJldHVybiBTaW1wbGVJdG9hKGZpZWxkLT5kZWZhdWx0X3ZhbHVlX2ludDMyKCkpOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1VJTlQzMjoKKyAgICAgIHJldHVybiBTaW1wbGVJdG9hKGZpZWxkLT5kZWZhdWx0X3ZhbHVlX3VpbnQzMigpKSArICJVIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9JTlQ2NDoKKyAgICAgIC8vIGdjYyBhbmQgbGx2bSByZWplY3QgdGhlIGRlY2ltYWwgZm9ybSBvZiBraW50MzJtaW4gYW5kIGtpbnQ2NG1pbi4KKyAgICAgIGlmIChmaWVsZC0+ZGVmYXVsdF92YWx1ZV9pbnQ2NCgpID09IExMT05HX01JTikgeworICAgICAgICByZXR1cm4gIi0weDgwMDAwMDAwMDAwMDAwMDBMTCI7CisgICAgICB9CisgICAgICByZXR1cm4gU2ltcGxlSXRvYShmaWVsZC0+ZGVmYXVsdF92YWx1ZV9pbnQ2NCgpKSArICJMTCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDY0OgorICAgICAgcmV0dXJuIFNpbXBsZUl0b2EoZmllbGQtPmRlZmF1bHRfdmFsdWVfdWludDY0KCkpICsgIlVMTCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRE9VQkxFOgorICAgICAgcmV0dXJuIEhhbmRsZUV4dHJlbWVGbG9hdGluZ1BvaW50KAorICAgICAgICAgIFNpbXBsZUR0b2EoZmllbGQtPmRlZmF1bHRfdmFsdWVfZG91YmxlKCkpLCBmYWxzZSk7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRkxPQVQ6CisgICAgICByZXR1cm4gSGFuZGxlRXh0cmVtZUZsb2F0aW5nUG9pbnQoCisgICAgICAgICAgU2ltcGxlRnRvYShmaWVsZC0+ZGVmYXVsdF92YWx1ZV9mbG9hdCgpKSwgdHJ1ZSk7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfQk9PTDoKKyAgICAgIHJldHVybiBmaWVsZC0+ZGVmYXVsdF92YWx1ZV9ib29sKCkgPyAiWUVTIiA6ICJOTyI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HOiB7CisgICAgICBjb25zdCBib29sIGhhc19kZWZhdWx0X3ZhbHVlID0gZmllbGQtPmhhc19kZWZhdWx0X3ZhbHVlKCk7CisgICAgICBjb25zdCBzdHJpbmcmIGRlZmF1bHRfc3RyaW5nID0gZmllbGQtPmRlZmF1bHRfdmFsdWVfc3RyaW5nKCk7CisgICAgICBpZiAoIWhhc19kZWZhdWx0X3ZhbHVlIHx8IGRlZmF1bHRfc3RyaW5nLmxlbmd0aCgpID09IDApIHsKKyAgICAgICAgLy8gSWYgdGhlIGZpZWxkIGlzIGRlZmluZWQgYXMgYmVpbmcgdGhlIGVtcHR5IHN0cmluZywKKyAgICAgICAgLy8gdGhlbiB3ZSB3aWxsIGp1c3QgYXNzaWduIHRvIG5pbCwgYXMgdGhlIGVtcHR5IHN0cmluZyBpcyB0aGUKKyAgICAgICAgLy8gZGVmYXVsdCBmb3IgYm90aCBzdHJpbmdzIGFuZCBkYXRhLgorICAgICAgICByZXR1cm4gIm5pbCI7CisgICAgICB9CisgICAgICBpZiAoZmllbGQtPnR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfQllURVMpIHsKKyAgICAgICAgLy8gV2Ugd2FudCBjb25zdGFudCBmaWVsZHMgaW4gb3VyIGRhdGEgc3RydWN0dXJlcyBzbyB3ZSBjYW4KKyAgICAgICAgLy8gZGVjbGFyZSB0aGVtIGFzIHN0YXRpYy4gVG8gYWNoaWV2ZSB0aGlzIHdlIGNoZWF0IGFuZCBzdHVmZgorICAgICAgICAvLyBhIGVzY2FwZWQgYyBzdHJpbmcgKHByZWZpeGVkIHdpdGggYSBsZW5ndGgpIGludG8gdGhlIGRhdGEKKyAgICAgICAgLy8gZmllbGQsIGFuZCBjYXN0IGl0IHRvIGFuIChOU0RhdGEqKSBzbyBpdCB3aWxsIGNvbXBpbGUuCisgICAgICAgIC8vIFRoZSBydW50aW1lIGxpYnJhcnkga25vd3MgaG93IHRvIGhhbmRsZSBpdC4KKworICAgICAgICAvLyBNdXN0IGNvbnZlcnQgdG8gYSBzdGFuZGFyZCBieXRlIG9yZGVyIGZvciBwYWNraW5nIGxlbmd0aCBpbnRvCisgICAgICAgIC8vIGEgY3N0cmluZy4KKyAgICAgICAgdWludDMyIGxlbmd0aCA9IGdodG9ubChkZWZhdWx0X3N0cmluZy5sZW5ndGgoKSk7CisgICAgICAgIHN0cmluZyBieXRlcygoY29uc3QgY2hhciopJmxlbmd0aCwgc2l6ZW9mKGxlbmd0aCkpOworICAgICAgICBieXRlcy5hcHBlbmQoZGVmYXVsdF9zdHJpbmcpOworICAgICAgICByZXR1cm4gIihOU0RhdGEqKVwiIiArIENFc2NhcGUoYnl0ZXMpICsgIlwiIjsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiAiQFwiIiArIEVzY2FwZVRyaWdyYXBocyhDRXNjYXBlKGRlZmF1bHRfc3RyaW5nKSkgKyAiXCIiOworICAgICAgfQorICAgIH0KKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9FTlVNOgorICAgICAgcmV0dXJuIEVudW1WYWx1ZU5hbWUoZmllbGQtPmRlZmF1bHRfdmFsdWVfZW51bSgpKTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgcmV0dXJuICJuaWwiOworICB9CisKKyAgLy8gU29tZSBjb21waWxlcnMgcmVwb3J0IHJlYWNoaW5nIGVuZCBvZiBmdW5jdGlvbiBldmVuIHRob3VnaCBhbGwgY2FzZXMgb2YKKyAgLy8gdGhlIGVudW0gYXJlIGhhbmRlZCBpbiB0aGUgc3dpdGNoLgorICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ2FuJ3QgZ2V0IGhlcmUuIjsKKyAgcmV0dXJuIE5VTEw7Cit9CisKK3N0cmluZyBCdWlsZEZsYWdzU3RyaW5nKGNvbnN0IHZlY3RvcjxzdHJpbmc+JiBzdHJpbmdzKSB7CisgIGlmIChzdHJpbmdzLnNpemUoKSA9PSAwKSB7CisgICAgcmV0dXJuICIwIjsKKyAgfQorICBzdHJpbmcgc3RyaW5nOworICBmb3IgKHNpemVfdCBpID0gMDsgaSAhPSBzdHJpbmdzLnNpemUoKTsgKytpKSB7CisgICAgaWYgKGkgPiAwKSB7CisgICAgICBzdHJpbmcuYXBwZW5kKCIgfCAiKTsKKyAgICB9CisgICAgc3RyaW5nLmFwcGVuZChzdHJpbmdzW2ldKTsKKyAgfQorICByZXR1cm4gc3RyaW5nOworfQorCitzdHJpbmcgQnVpbGRDb21tZW50c1N0cmluZyhjb25zdCBTb3VyY2VMb2NhdGlvbiYgbG9jYXRpb24pIHsKKyAgY29uc3Qgc3RyaW5nJiBjb21tZW50cyA9IGxvY2F0aW9uLmxlYWRpbmdfY29tbWVudHMuZW1wdHkoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gbG9jYXRpb24udHJhaWxpbmdfY29tbWVudHMKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGxvY2F0aW9uLmxlYWRpbmdfY29tbWVudHM7CisgIHZlY3RvcjxzdHJpbmc+IGxpbmVzOworICBTcGxpdFN0cmluZ0FsbG93RW1wdHkoY29tbWVudHMsICJcbiIsICZsaW5lcyk7CisgIHdoaWxlICghbGluZXMuZW1wdHkoKSAmJiBsaW5lcy5iYWNrKCkuZW1wdHkoKSkgeworICAgIGxpbmVzLnBvcF9iYWNrKCk7CisgIH0KKyAgc3RyaW5nIHByZWZpeCgiLy8iKTsKKyAgc3RyaW5nIHN1ZmZpeCgiXG4iKTsKKyAgc3RyaW5nIGZpbmFsX2NvbW1lbnRzOworICBmb3IgKGludCBpID0gMDsgaSA8IGxpbmVzLnNpemUoKTsgaSsrKSB7CisgICAgLy8gV2UgdXNlICQgZm9yIGRlbGltaXRlcnMsIHNvIHJlcGxhY2UgY29tbWVudHMgd2l0aCBkb2xsYXJzIHdpdGgKKyAgICAvLyBodG1sIGVzY2FwZWQgdmVyc2lvbi4KKyAgICAvLyBOb25lIG9mIHRoZSBvdGhlciBjb21waWxlcnMgaGFuZGxlIHRoaXMgKGFzIG9mIHRoaXMgd3JpdGluZykgYnV0IHdlCisgICAgLy8gcmFuIGludG8gaXQgb25jZSwgc28ganVzdCB0byBiZSBzYWZlLgorICAgIGZpbmFsX2NvbW1lbnRzICs9CisgICAgICAgIHByZWZpeCArIFN0cmluZ1JlcGxhY2UobGluZXNbaV0sICIkIiwgIiYjMzY7IiwgdHJ1ZSkgKyBzdWZmaXg7CisgIH0KKyAgcmV0dXJuIGZpbmFsX2NvbW1lbnRzOworfQorCituYW1lc3BhY2UgeworCisvLyBJbnRlcm5hbCBoZWxwZXIgY2xhc3MgdGhhdCBwYXJzZXMgdGhlIGV4cGVjdGVkIHBhY2thZ2UgdG8gcHJlZml4IG1hcHBpbmdzCisvLyBmaWxlLgorY2xhc3MgUGFyc2VyIHsKKyBwdWJsaWM6CisgIFBhcnNlcihtYXA8c3RyaW5nLCBzdHJpbmc+KiBpbm91dF9wYWNrYWdlX3RvX3ByZWZpeF9tYXApCisgICAgICA6IHByZWZpeF9tYXBfKGlub3V0X3BhY2thZ2VfdG9fcHJlZml4X21hcCksIGxpbmVfKDApIHt9CisKKyAgLy8gUGFyc2VzIGEgY2hlY2sgb2YgaW5wdXQsIHJldHVybmluZyBzdWNjZXNzL2ZhaWx1cmUuCisgIGJvb2wgUGFyc2VDaHVuayhTdHJpbmdQaWVjZSBjaHVuayk7CisKKyAgLy8gU2hvdWxkIGJlIGNhbGxlZCB0byBmaW5pc2ggcGFyc2luZyAoYWZ0ZXIgYWxsIGlucHV0IGhhcyBiZWVuIHByb3ZpZGVkIHZpYQorICAvLyBQYXJzZUNodW5rKCkpLiAgUmV0dXJucyBzdWNjZXNzL2ZhaWx1cmUuCisgIGJvb2wgRmluaXNoKCk7CisKKyAgaW50IGxhc3RfbGluZSgpIGNvbnN0IHsgcmV0dXJuIGxpbmVfOyB9CisgIHN0cmluZyBlcnJvcl9zdHIoKSBjb25zdCB7IHJldHVybiBlcnJvcl9zdHJfOyB9CisKKyBwcml2YXRlOgorICBib29sIFBhcnNlTG9vcCgpOworCisgIG1hcDxzdHJpbmcsIHN0cmluZz4qIHByZWZpeF9tYXBfOworICBpbnQgbGluZV87CisgIHN0cmluZyBlcnJvcl9zdHJfOworICBTdHJpbmdQaWVjZSBwXzsKKyAgc3RyaW5nIGxlZnRvdmVyXzsKK307CisKK2Jvb2wgUGFyc2VyOjpQYXJzZUNodW5rKFN0cmluZ1BpZWNlIGNodW5rKSB7CisgIGlmICghbGVmdG92ZXJfLmVtcHR5KCkpIHsKKyAgICBjaHVuay5BcHBlbmRUb1N0cmluZygmbGVmdG92ZXJfKTsKKyAgICBwXyA9IFN0cmluZ1BpZWNlKGxlZnRvdmVyXyk7CisgIH0gZWxzZSB7CisgICAgcF8gPSBjaHVuazsKKyAgfQorICBib29sIHJlc3VsdCA9IFBhcnNlTG9vcCgpOworICBpZiAocF8uZW1wdHkoKSkgeworICAgIGxlZnRvdmVyXy5jbGVhcigpOworICB9IGVsc2UgeworICAgIGxlZnRvdmVyXyA9IHBfLlRvU3RyaW5nKCk7CisgIH0KKyAgcmV0dXJuIHJlc3VsdDsKK30KKworYm9vbCBQYXJzZXI6OkZpbmlzaCgpIHsKKyAgaWYgKGxlZnRvdmVyXy5lbXB0eSgpKSB7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKyAgLy8gRm9yY2UgYSBuZXdsaW5lIG9udG8gdGhlIGVuZCB0byBmaW5pc2ggcGFyc2luZy4KKyAgcF8gPSBTdHJpbmdQaWVjZShsZWZ0b3Zlcl8gKyAiXG4iKTsKKyAgaWYgKCFQYXJzZUxvb3AoKSkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICByZXR1cm4gcF8uZW1wdHkoKTsgIC8vIEV2ZXJ5dGhpbmcgdXNlZD8KK30KKworc3RhdGljIGJvb2wgYXNjaWlfaXNuZXdsaW5lKGNoYXIgYykgeyByZXR1cm4gYyA9PSAnXG4nIHx8IGMgPT0gJ1xyJzsgfQorCitib29sIFJlYWRMaW5lKFN0cmluZ1BpZWNlKiBpbnB1dCwgU3RyaW5nUGllY2UqIGxpbmUpIHsKKyAgZm9yIChpbnQgbGVuID0gMDsgbGVuIDwgaW5wdXQtPnNpemUoKTsgKytsZW4pIHsKKyAgICBpZiAoYXNjaWlfaXNuZXdsaW5lKCgqaW5wdXQpW2xlbl0pKSB7CisgICAgICAqbGluZSA9IFN0cmluZ1BpZWNlKGlucHV0LT5kYXRhKCksIGxlbik7CisgICAgICArK2xlbjsgIC8vIGFkdmFuY2Ugb3ZlciB0aGUgbmV3bGluZQorICAgICAgKmlucHV0ID0gU3RyaW5nUGllY2UoaW5wdXQtPmRhdGEoKSArIGxlbiwgaW5wdXQtPnNpemUoKSAtIGxlbik7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIGZhbHNlOyAgLy8gUmFuIG91dCBvZiBpbnB1dCB3aXRoIG5vIG5ld2xpbmUuCit9CisKK3ZvaWQgVHJpbVdoaXRlc3BhY2UoU3RyaW5nUGllY2UqIGlucHV0KSB7CisgIHdoaWxlICghaW5wdXQtPmVtcHR5KCkgJiYgYXNjaWlfaXNzcGFjZSgqaW5wdXQtPmRhdGEoKSkpIHsKKyAgICBpbnB1dC0+cmVtb3ZlX3ByZWZpeCgxKTsKKyAgfQorICB3aGlsZSAoIWlucHV0LT5lbXB0eSgpICYmIGFzY2lpX2lzc3BhY2UoKCppbnB1dClbaW5wdXQtPmxlbmd0aCgpIC0gMV0pKSB7CisgICAgaW5wdXQtPnJlbW92ZV9zdWZmaXgoMSk7CisgIH0KK30KKwordm9pZCBSZW1vdmVDb21tZW50KFN0cmluZ1BpZWNlKiBpbnB1dCkgeworICBpbnQgb2Zmc2V0ID0gaW5wdXQtPmZpbmQoJyMnKTsKKyAgaWYgKG9mZnNldCAhPSBTdHJpbmdQaWVjZTo6bnBvcykgeworICAgIGlucHV0LT5yZW1vdmVfc3VmZml4KGlucHV0LT5sZW5ndGgoKSAtIG9mZnNldCk7CisgIH0KK30KKworYm9vbCBQYXJzZXI6OlBhcnNlTG9vcCgpIHsKKyAgU3RyaW5nUGllY2UgbGluZTsKKyAgd2hpbGUgKFJlYWRMaW5lKCZwXywgJmxpbmUpKSB7CisgICAgKytsaW5lXzsKKyAgICBSZW1vdmVDb21tZW50KCZsaW5lKTsKKyAgICBUcmltV2hpdGVzcGFjZSgmbGluZSk7CisgICAgaWYgKGxpbmUuc2l6ZSgpID09IDApIHsKKyAgICAgIGNvbnRpbnVlOyAgLy8gQmxhbmsgbGluZS4KKyAgICB9CisgICAgaW50IG9mZnNldCA9IGxpbmUuZmluZCgnPScpOworICAgIGlmIChvZmZzZXQgPT0gU3RyaW5nUGllY2U6Om5wb3MpIHsKKyAgICAgIGVycm9yX3N0cl8gPQorICAgICAgICAgIHN0cmluZygiTGluZSB3aXRob3V0IGVxdWFsIHNpZ246ICciKSArIGxpbmUuVG9TdHJpbmcoKSArICInLiI7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIFN0cmluZ1BpZWNlIHBhY2thZ2UobGluZSwgMCwgb2Zmc2V0KTsKKyAgICBTdHJpbmdQaWVjZSBwcmVmaXgobGluZSwgb2Zmc2V0ICsgMSwgbGluZS5sZW5ndGgoKSAtIG9mZnNldCAtIDEpOworICAgIFRyaW1XaGl0ZXNwYWNlKCZwYWNrYWdlKTsKKyAgICBUcmltV2hpdGVzcGFjZSgmcHJlZml4KTsKKyAgICAvLyBEb24ndCByZWFsbHkgd29ycnkgYWJvdXQgZXJyb3IgY2hlY2tpbmcgdGhlIHBhY2thZ2UvcHJlZml4IGZvcgorICAgIC8vIGJlaW5nIHZhbGlkLiAgQXNzdW1lIHRoZSBmaWxlIGlzIHZhbGlkYXRlZCB3aGVuIGl0IGlzIGNyZWF0ZWQvZWRpdGVkLgorICAgICgqcHJlZml4X21hcF8pW3BhY2thZ2UuVG9TdHJpbmcoKV0gPSBwcmVmaXguVG9TdHJpbmcoKTsKKyAgfQorICByZXR1cm4gdHJ1ZTsKK30KKworYm9vbCBMb2FkRXhwZWN0ZWRQYWNrYWdlUHJlZml4ZXMobWFwPHN0cmluZywgc3RyaW5nPiogcHJlZml4X21hcCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyogb3V0X2V4cGVjdF9maWxlX3BhdGgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcqIG91dF9lcnJvcikgeworICBjb25zdCBjaGFyKiBmaWxlX3BhdGggPSBnZXRlbnYoIkdQQl9PQkpDX0VYUEVDVEVEX1BBQ0tBR0VfUFJFRklYRVMiKTsKKyAgaWYgKGZpbGVfcGF0aCA9PSBOVUxMKSB7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICBpbnQgZmQ7CisgIGRvIHsKKyAgICBmZCA9IG9wZW4oZmlsZV9wYXRoLCBPX1JET05MWSk7CisgIH0gd2hpbGUgKGZkIDwgMCAmJiBlcnJubyA9PSBFSU5UUik7CisgIGlmIChmZCA8IDApIHsKKyAgICAqb3V0X2Vycm9yID0KKyAgICAgICAgc3RyaW5nKGZpbGVfcGF0aCkgKyAiOjA6MDogZXJyb3I6IFVuYWJsZSB0byBvcGVuLiIgKyBzdHJlcnJvcihlcnJubyk7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIGlvOjpGaWxlSW5wdXRTdHJlYW0gZmlsZV9zdHJlYW0oZmQpOworICBmaWxlX3N0cmVhbS5TZXRDbG9zZU9uRGVsZXRlKHRydWUpOworICAqb3V0X2V4cGVjdF9maWxlX3BhdGggPSBmaWxlX3BhdGg7CisKKyAgUGFyc2VyIHBhcnNlcihwcmVmaXhfbWFwKTsKKyAgY29uc3Qgdm9pZCogYnVmOworICBpbnQgYnVmX2xlbjsKKyAgd2hpbGUgKGZpbGVfc3RyZWFtLk5leHQoJmJ1ZiwgJmJ1Zl9sZW4pKSB7CisgICAgaWYgKGJ1Zl9sZW4gPT0gMCkgeworICAgICAgY29udGludWU7CisgICAgfQorCisgICAgaWYgKCFwYXJzZXIuUGFyc2VDaHVuayhTdHJpbmdQaWVjZShzdGF0aWNfY2FzdDxjb25zdCBjaGFyKj4oYnVmKSwgYnVmX2xlbikpKSB7CisgICAgICAqb3V0X2Vycm9yID0gc3RyaW5nKGZpbGVfcGF0aCkgKyAiOiIgKyBTaW1wbGVJdG9hKHBhcnNlci5sYXN0X2xpbmUoKSkgKworICAgICAgICAgICAgICAgICAgICI6MDogZXJyb3I6ICIgKyBwYXJzZXIuZXJyb3Jfc3RyKCk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICB9CisgIHJldHVybiBwYXJzZXIuRmluaXNoKCk7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCitib29sIFZhbGlkYXRlT2JqQ0NsYXNzUHJlZml4KGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlLCBzdHJpbmcqIG91dF9lcnJvcikgeworICBjb25zdCBzdHJpbmcgcHJlZml4ID0gZmlsZS0+b3B0aW9ucygpLm9iamNfY2xhc3NfcHJlZml4KCk7CisgIGNvbnN0IHN0cmluZyBwYWNrYWdlID0gZmlsZS0+cGFja2FnZSgpOworCisgIC8vIE5PVEU6IHNyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLmNjIG1ha2VzIHVzZSBvZiBjZXJyIGZvciBzb21lCisgIC8vIGVycm9yIGNhc2VzLCBzbyBpdCBzZWVtcyB0byBiZSBvayB0byB1c2UgYXMgYSBiYWNrIGRvb3IgZm9yIHdhcm5pbmdzLgorCisgIC8vIExvYWQgYW55IGV4cGVjdGVkIHBhY2thZ2UgcHJlZml4ZXMgdG8gdmFsaWRhdGUgYWdhaW5zdCB0aG9zZS4KKyAgbWFwPHN0cmluZywgc3RyaW5nPiBleHBlY3RlZF9wYWNrYWdlX3ByZWZpeGVzOworICBzdHJpbmcgZXhwZWN0X2ZpbGVfcGF0aDsKKyAgaWYgKCFMb2FkRXhwZWN0ZWRQYWNrYWdlUHJlZml4ZXMoJmV4cGVjdGVkX3BhY2thZ2VfcHJlZml4ZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZleHBlY3RfZmlsZV9wYXRoLCBvdXRfZXJyb3IpKSB7CisgICAgLy8gQW55IGVycm9yLCBjbGVhciB0aGUgZW50cmllcyB0aGF0IHdlcmUgcmVhZC4KKyAgICBleHBlY3RlZF9wYWNrYWdlX3ByZWZpeGVzLmNsZWFyKCk7CisgIH0KKworICAvLyBDaGVjazogRXJyb3IgLSBTZWUgaWYgdGhlcmUgd2FzIGFuIGV4cGVjdGVkIHByZWZpeCBmb3IgdGhlIHBhY2thZ2UgYW5kCisgIC8vIHJlcG9ydCBpZiBpdCBkb2Vzbid0IG1hdGNoICh3cm9uZyBvciBtaXNzaW5nKS4KKyAgbWFwPHN0cmluZywgc3RyaW5nPjo6aXRlcmF0b3IgcGFja2FnZV9tYXRjaCA9CisgICAgICBleHBlY3RlZF9wYWNrYWdlX3ByZWZpeGVzLmZpbmQocGFja2FnZSk7CisgIGlmIChwYWNrYWdlX21hdGNoICE9IGV4cGVjdGVkX3BhY2thZ2VfcHJlZml4ZXMuZW5kKCkpIHsKKyAgICAvLyBUaGVyZSB3YXMgYW4gZW50cnksIGFuZC4uLgorICAgIGlmIChwYWNrYWdlX21hdGNoLT5zZWNvbmQgPT0gcHJlZml4KSB7CisgICAgICAvLyAuLi5pdCBtYXRjaGVzLiAgQWxsIGdvb2QsIG91dCBvZiBoZXJlIQorICAgICAgcmV0dXJuIHRydWU7CisgICAgfSBlbHNlIHsKKyAgICAgIC8vIC4uLml0IGRpZG4ndCBtYXRjaCEKKyAgICAgICpvdXRfZXJyb3IgPSAicHJvdG9jOjA6IGVycm9yOiBFeHBlY3RlZCAnb3B0aW9uIG9iamNfY2xhc3NfcHJlZml4ID0gXCIiICsKKyAgICAgICAgICAgICAgICAgICBwYWNrYWdlX21hdGNoLT5zZWNvbmQgKyAiXCI7JyBpbiAnIiArIGZpbGUtPm5hbWUoKSArICInIjsKKyAgICAgIGlmIChwcmVmaXgubGVuZ3RoKCkpIHsKKyAgICAgICAgKm91dF9lcnJvciArPSAiOyBidXQgZm91bmQgJyIgKyBwcmVmaXggKyAiJyBpbnN0ZWFkIjsKKyAgICAgIH0KKyAgICAgICpvdXRfZXJyb3IgKz0gIi4iOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgfQorCisgIC8vIElmIHRoZXJlIHdhcyBubyBwcmVmaXggb3B0aW9uLCB3ZSdyZSBkb25lIGF0IHRoaXMgcG9pbnQuCisgIGlmIChwcmVmaXgubGVuZ3RoKCkgPT0gMCkgeworICAgIC8vIE5vIHByZWZpeCwgbm90aGluZyBsZWZ0IHRvIGNoZWNrLgorICAgIHJldHVybiB0cnVlOworICB9CisKKyAgLy8gQ2hlY2s6IEVycm9yIC0gTWFrZSBzdXJlIHRoZSBwcmVmaXggd2Fzbid0IGV4cGVjdGVkIGZvciBhIGRpZmZlcmVudAorICAvLyBwYWNrYWdlIChvdmVybGFwIGlzIGFsbG93ZWQsIGJ1dCBpdCBoYXMgdG8gYmUgbGlzdGVkIGFzIGFuIGV4cGVjdGVkCisgIC8vIG92ZXJsYXApLgorICBmb3IgKG1hcDxzdHJpbmcsIHN0cmluZz46Oml0ZXJhdG9yIGkgPSBleHBlY3RlZF9wYWNrYWdlX3ByZWZpeGVzLmJlZ2luKCk7CisgICAgICAgaSAhPSBleHBlY3RlZF9wYWNrYWdlX3ByZWZpeGVzLmVuZCgpOyArK2kpIHsKKyAgICBpZiAoaS0+c2Vjb25kID09IHByZWZpeCkgeworICAgICAgKm91dF9lcnJvciA9CisgICAgICAgICAgInByb3RvYzowOiBlcnJvcjogRm91bmQgJ29wdGlvbiBvYmpjX2NsYXNzX3ByZWZpeCA9IFwiIiArIHByZWZpeCArCisgICAgICAgICAgIlwiOycgaW4gJyIgKyBmaWxlLT5uYW1lKCkgKworICAgICAgICAgICInOyB0aGF0IHByZWZpeCBpcyBhbHJlYWR5IHVzZWQgZm9yICdwYWNrYWdlICIgKyBpLT5maXJzdCArCisgICAgICAgICAgIjsnLiBJdCBjYW4gb25seSBiZSByZXVzZWQgYnkgbGlzdGluZyBpdCBpbiB0aGUgZXhwZWN0ZWQgZmlsZSAoIiArCisgICAgICAgICAgZXhwZWN0X2ZpbGVfcGF0aCArICIpLiI7CisgICAgICByZXR1cm4gZmFsc2U7ICAvLyBPbmx5IHJlcG9ydCBmaXJzdCB1c2FnZSBvZiB0aGUgcHJlZml4LgorICAgIH0KKyAgfQorCisgIC8vIENoZWNrOiBXYXJuaW5nIC0gTWFrZSBzdXJlIHRoZSBwcmVmaXggaXMgaXMgYSByZWFzb25hYmxlIHZhbHVlIGFjY29yZGluZworICAvLyB0byBBcHBsZSdzIHJ1bGVzICh0aGUgY2hlY2tzIGFib3ZlIGltcGxpY2l0bHkgd2hpdGVsaXN0IGFueXRoaW5nIHRoYXQKKyAgLy8gZG9lc24ndCBtZWV0IHRoZXNlIHJ1bGVzKS4KKyAgaWYgKCFhc2NpaV9pc3VwcGVyKHByZWZpeFswXSkpIHsKKyAgICBjZXJyIDw8IGVuZGwKKyAgICAgICAgIDw8ICJwcm90b2M6MDogd2FybmluZzogSW52YWxpZCAnb3B0aW9uIG9iamNfY2xhc3NfcHJlZml4ID0gXCIiCisgICAgICAgICA8PCBwcmVmaXggPDwgIlwiOycgaW4gJyIgPDwgZmlsZS0+bmFtZSgpIDw8ICInOyIKKyAgICAgICAgIDw8ICIgaXQgc2hvdWxkIHN0YXJ0IHdpdGggYSBjYXBpdGFsIGxldHRlci4iIDw8IGVuZGw7CisgICAgY2Vyci5mbHVzaCgpOworICB9CisgIGlmIChwcmVmaXgubGVuZ3RoKCkgPCAzKSB7CisgICAgLy8gQXBwbGUgcmVzZXJ2ZXMgMiBjaGFyYWN0ZXIgcHJlZml4ZXMgZm9yIHRoZW1zZWx2ZXMuIFRoZXkgZG8gdXNlIHNvbWUKKyAgICAvLyAzIGNoYXJhY3RlciBwcmVmaXhlcywgYnV0IHRoZXkgaGF2ZW4ndCB1cGRhdGVkIHRoZSBydWxlcy9kb2NzLgorICAgIGNlcnIgPDwgZW5kbAorICAgICAgICAgPDwgInByb3RvYzowOiB3YXJuaW5nOiBJbnZhbGlkICdvcHRpb24gb2JqY19jbGFzc19wcmVmaXggPSBcIiIKKyAgICAgICAgIDw8IHByZWZpeCA8PCAiXCI7JyBpbiAnIiA8PCBmaWxlLT5uYW1lKCkgPDwgIic7IgorICAgICAgICAgPDwgIiBBcHBsZSByZWNvbW1lbmRzIHRoZXkgc2hvdWxkIGJlIGF0IGxlYXN0IDMgY2hhcmFjdGVycyBsb25nLiIKKyAgICAgICAgIDw8IGVuZGw7CisgICAgY2Vyci5mbHVzaCgpOworICB9CisKKyAgLy8gQ2hlY2s6IFdhcm5pbmcgLSBJZiB0aGUgZ2l2ZW4gcGFja2FnZS9wcmVmaXggcGFpciB3YXNuJ3QgZXhwZWN0ZWQsIGlzc3VlIGEKKyAgLy8gd2FybmluZyBpc3N1ZSBhIHdhcm5pbmcgc3VnZ2VzdGluZyBpdCBnZXRzIGFkZGVkIHRvIHRoZSBmaWxlLgorICBpZiAoIWV4cGVjdGVkX3BhY2thZ2VfcHJlZml4ZXMuZW1wdHkoKSkgeworICAgIGNlcnIgPDwgZW5kbAorICAgICAgICAgPDwgInByb3RvYzowOiB3YXJuaW5nOiBGb3VuZCB1bmV4cGVjdGVkICdvcHRpb24gb2JqY19jbGFzc19wcmVmaXggPSBcIiIKKyAgICAgICAgIDw8IHByZWZpeCA8PCAiXCI7JyBpbiAnIiA8PCBmaWxlLT5uYW1lKCkgPDwgIic7IgorICAgICAgICAgPDwgIiBjb25zaWRlciBhZGRpbmcgaXQgdG8gdGhlIGV4cGVjdGVkIHByZWZpeGVzIGZpbGUgKCIKKyAgICAgICAgIDw8IGV4cGVjdF9maWxlX3BhdGggPDwgIikuIiA8PCBlbmRsOworICAgIGNlcnIuZmx1c2goKTsKKyAgfQorCisgIHJldHVybiB0cnVlOworfQorCit2b2lkIFRleHRGb3JtYXREZWNvZGVEYXRhOjpBZGRTdHJpbmcoaW50MzIga2V5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgaW5wdXRfZm9yX2RlY29kZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIGRlc2lyZWRfb3V0cHV0KSB7CisgIGZvciAodmVjdG9yPERhdGFFbnRyeT46OmNvbnN0X2l0ZXJhdG9yIGkgPSBlbnRyaWVzXy5iZWdpbigpOworICAgICAgIGkgIT0gZW50cmllc18uZW5kKCk7ICsraSkgeworICAgIGlmIChpLT5maXJzdCA9PSBrZXkpIHsKKyAgICAgIGNlcnIgPDwgImVycm9yOiBkdXBsaWNhdGUga2V5ICgiIDw8IGtleQorICAgICAgICAgICA8PCAiKSBtYWtpbmcgVGV4dEZvcm1hdCBkYXRhLCBpbnB1dDogXCIiIDw8IGlucHV0X2Zvcl9kZWNvZGUKKyAgICAgICAgICAgPDwgIlwiLCBkZXNpcmVkOiBcIiIgPDwgZGVzaXJlZF9vdXRwdXQgPDwgIlwiLiIgPDwgZW5kbDsKKyAgICAgIGNlcnIuZmx1c2goKTsKKyAgICAgIGFib3J0KCk7CisgICAgfQorICB9CisKKyAgY29uc3Qgc3RyaW5nJiBkYXRhID0gVGV4dEZvcm1hdERlY29kZURhdGE6OkRlY29kZURhdGFGb3JTdHJpbmcoCisgICAgICBpbnB1dF9mb3JfZGVjb2RlLCBkZXNpcmVkX291dHB1dCk7CisgIGVudHJpZXNfLnB1c2hfYmFjayhEYXRhRW50cnkoa2V5LCBkYXRhKSk7Cit9CisKK3N0cmluZyBUZXh0Rm9ybWF0RGVjb2RlRGF0YTo6RGF0YSgpIGNvbnN0IHsKKyAgb3N0cmluZ3N0cmVhbSBkYXRhX3N0cmluZ3N0cmVhbTsKKworICBpZiAobnVtX2VudHJpZXMoKSA+IDApIHsKKyAgICBpbzo6T3N0cmVhbU91dHB1dFN0cmVhbSBkYXRhX291dHB1dHN0cmVhbSgmZGF0YV9zdHJpbmdzdHJlYW0pOworICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSBvdXRwdXRfc3RyZWFtKCZkYXRhX291dHB1dHN0cmVhbSk7CisKKyAgICBvdXRwdXRfc3RyZWFtLldyaXRlVmFyaW50MzIobnVtX2VudHJpZXMoKSk7CisgICAgZm9yICh2ZWN0b3I8RGF0YUVudHJ5Pjo6Y29uc3RfaXRlcmF0b3IgaSA9IGVudHJpZXNfLmJlZ2luKCk7CisgICAgICAgICBpICE9IGVudHJpZXNfLmVuZCgpOyArK2kpIHsKKyAgICAgIG91dHB1dF9zdHJlYW0uV3JpdGVWYXJpbnQzMihpLT5maXJzdCk7CisgICAgICBvdXRwdXRfc3RyZWFtLldyaXRlU3RyaW5nKGktPnNlY29uZCk7CisgICAgfQorICB9CisKKyAgZGF0YV9zdHJpbmdzdHJlYW0uZmx1c2goKTsKKyAgcmV0dXJuIGRhdGFfc3RyaW5nc3RyZWFtLnN0cigpOworfQorCituYW1lc3BhY2UgeworCisvLyBIZWxwZXIgdG8gYnVpbGQgdXAgdGhlIGRlY29kZSBkYXRhIGZvciBhIHN0cmluZy4KK2NsYXNzIERlY29kZURhdGFCdWlsZGVyIHsKKyBwdWJsaWM6CisgIERlY29kZURhdGFCdWlsZGVyKCkgeyBSZXNldCgpOyB9CisKKyAgYm9vbCBBZGRDaGFyYWN0ZXIoY29uc3QgY2hhciBkZXNpcmVkLCBjb25zdCBjaGFyIGlucHV0KTsKKyAgdm9pZCBBZGRVbmRlcnNjb3JlKCkgeworICAgIFB1c2goKTsKKyAgICBuZWVkX3VuZGVyc2NvcmVfID0gdHJ1ZTsKKyAgfQorICBzdHJpbmcgRmluaXNoKCkgeworICAgIFB1c2goKTsKKyAgICByZXR1cm4gZGVjb2RlX2RhdGFfOworICB9CisKKyBwcml2YXRlOgorICBzdGF0aWMgY29uc3QgdWludDgga0FkZFVuZGVyc2NvcmUgPSAweDgwOworCisgIHN0YXRpYyBjb25zdCB1aW50OCBrT3BBc0lzICAgICAgICA9IDB4MDA7CisgIHN0YXRpYyBjb25zdCB1aW50OCBrT3BGaXJzdFVwcGVyICA9IDB4NDA7CisgIHN0YXRpYyBjb25zdCB1aW50OCBrT3BGaXJzdExvd2VyICA9IDB4MjA7CisgIHN0YXRpYyBjb25zdCB1aW50OCBrT3BBbGxVcHBlciAgICA9IDB4NjA7CisKKyAgc3RhdGljIGNvbnN0IGludCBrTWF4U2VnbWVudExlbiAgICAgPSAweDFmOworCisgIHZvaWQgQWRkQ2hhcihjb25zdCBjaGFyIGRlc2lyZWQpIHsKKyAgICArK3NlZ21lbnRfbGVuXzsKKyAgICBpc19hbGxfdXBwZXJfICY9IGFzY2lpX2lzdXBwZXIoZGVzaXJlZCk7CisgIH0KKworICB2b2lkIFB1c2goKSB7CisgICAgdWludDggb3AgPSAob3BfIHwgc2VnbWVudF9sZW5fKTsKKyAgICBpZiAobmVlZF91bmRlcnNjb3JlXykgb3AgfD0ga0FkZFVuZGVyc2NvcmU7CisgICAgaWYgKG9wICE9IDApIHsKKyAgICAgIGRlY29kZV9kYXRhXyArPSAoY2hhcilvcDsKKyAgICB9CisgICAgUmVzZXQoKTsKKyAgfQorCisgIGJvb2wgQWRkRmlyc3QoY29uc3QgY2hhciBkZXNpcmVkLCBjb25zdCBjaGFyIGlucHV0KSB7CisgICAgaWYgKGRlc2lyZWQgPT0gaW5wdXQpIHsKKyAgICAgIG9wXyA9IGtPcEFzSXM7CisgICAgfSBlbHNlIGlmIChkZXNpcmVkID09IGFzY2lpX3RvdXBwZXIoaW5wdXQpKSB7CisgICAgICBvcF8gPSBrT3BGaXJzdFVwcGVyOworICAgIH0gZWxzZSBpZiAoZGVzaXJlZCA9PSBhc2NpaV90b2xvd2VyKGlucHV0KSkgeworICAgICAgb3BfID0ga09wRmlyc3RMb3dlcjsKKyAgICB9IGVsc2UgeworICAgICAgLy8gQ2FuJ3QgYmUgdHJhbnNmb3JtZWQgdG8gbWF0Y2guCisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIEFkZENoYXIoZGVzaXJlZCk7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICB2b2lkIFJlc2V0KCkgeworICAgIG5lZWRfdW5kZXJzY29yZV8gPSBmYWxzZTsKKyAgICBvcF8gPSAwOworICAgIHNlZ21lbnRfbGVuXyA9IDA7CisgICAgaXNfYWxsX3VwcGVyXyA9IHRydWU7CisgIH0KKworICBib29sIG5lZWRfdW5kZXJzY29yZV87CisgIGJvb2wgaXNfYWxsX3VwcGVyXzsKKyAgdWludDggb3BfOworICBpbnQgc2VnbWVudF9sZW5fOworCisgIHN0cmluZyBkZWNvZGVfZGF0YV87Cit9OworCitib29sIERlY29kZURhdGFCdWlsZGVyOjpBZGRDaGFyYWN0ZXIoY29uc3QgY2hhciBkZXNpcmVkLCBjb25zdCBjaGFyIGlucHV0KSB7CisgIC8vIElmIHdlJ3ZlIGhpdCB0aGUgbWF4IHNpemUsIHB1c2ggdG8gc3RhcnQgYSBuZXcgc2VnbWVudC4KKyAgaWYgKHNlZ21lbnRfbGVuXyA9PSBrTWF4U2VnbWVudExlbikgeworICAgIFB1c2goKTsKKyAgfQorICBpZiAoc2VnbWVudF9sZW5fID09IDApIHsKKyAgICByZXR1cm4gQWRkRmlyc3QoZGVzaXJlZCwgaW5wdXQpOworICB9CisKKyAgLy8gRGVzaXJlZCBhbmQgaW5wdXQgbWF0Y2guLi4KKyAgaWYgKGRlc2lyZWQgPT0gaW5wdXQpIHsKKyAgICAvLyBJZiB3ZSBhcmVuJ3QgdHJhbnNmb3JtaW5nIGl0LCBvciB3ZSdyZSB1cHBlciBjYXNpbmcgaXQgYW5kIGl0IGlzCisgICAgLy8gc3VwcG9zZWQgdG8gYmUgdXBwZXJjYXNlOyBqdXN0IGFkZCBpdCB0byB0aGUgc2VnbWVudC4KKyAgICBpZiAoKG9wXyAhPSBrT3BBbGxVcHBlcikgfHwgYXNjaWlfaXN1cHBlcihkZXNpcmVkKSkgeworICAgICAgQWRkQ2hhcihkZXNpcmVkKTsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIC8vIEFkZCB0aGUgY3VycmVudCBzZWdtZW50LCBhbmQgc3RhcnQgdGhlIG5leHQgb25lLgorICAgIFB1c2goKTsKKyAgICByZXR1cm4gQWRkRmlyc3QoZGVzaXJlZCwgaW5wdXQpOworICB9CisKKyAgLy8gSWYgd2UgbmVlZCB0byB1cHBlcmNhc2UsIGFuZCBldmVyeXRoaW5nIHNvIGZhciBoYXMgYmVlbiB1cHBlcmNhc2UsCisgIC8vIHByb21vdGUgb3AgdG8gQWxsVXBwZXIuCisgIGlmICgoZGVzaXJlZCA9PSBhc2NpaV90b3VwcGVyKGlucHV0KSkgJiYgaXNfYWxsX3VwcGVyXykgeworICAgIG9wXyA9IGtPcEFsbFVwcGVyOworICAgIEFkZENoYXIoZGVzaXJlZCk7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICAvLyBHaXZlIHVwLCBwdXNoIGFuZCBzdGFydCBhIG5ldyBzZWdtZW50LgorICBQdXNoKCk7CisgIHJldHVybiBBZGRGaXJzdChkZXNpcmVkLCBpbnB1dCk7Cit9CisKKy8vIElmIGRlY29kZSBkYXRhIGNhbid0IGJlIGdlbmVyYXRlZCwgYSBkaXJlY3RpdmUgZm9yIHRoZSByYXcgc3RyaW5nCisvLyBpcyB1c2VkIGluc3RlYWQuCitzdHJpbmcgRGlyZWN0RGVjb2RlU3RyaW5nKGNvbnN0IHN0cmluZyYgc3RyKSB7CisgIHN0cmluZyByZXN1bHQ7CisgIHJlc3VsdCArPSAoY2hhciknXDAnOyAgLy8gTWFya2VyIGZvciBmdWxsIHN0cmluZy4KKyAgcmVzdWx0ICs9IHN0cjsKKyAgcmVzdWx0ICs9IChjaGFyKSdcMCc7ICAvLyBFbmQgb2Ygc3RyaW5nLgorICByZXR1cm4gcmVzdWx0OworfQorCit9ICAvLyBuYW1lc3BhY2UKKworLy8gc3RhdGljCitzdHJpbmcgVGV4dEZvcm1hdERlY29kZURhdGE6OkRlY29kZURhdGFGb3JTdHJpbmcoY29uc3Qgc3RyaW5nJiBpbnB1dF9mb3JfZGVjb2RlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgZGVzaXJlZF9vdXRwdXQpIHsKKyAgaWYgKChpbnB1dF9mb3JfZGVjb2RlLnNpemUoKSA9PSAwKSB8fCAoZGVzaXJlZF9vdXRwdXQuc2l6ZSgpID09IDApKSB7CisgICAgY2VyciA8PCAiZXJyb3I6IGdvdCBlbXB0eSBzdHJpbmcgZm9yIG1ha2luZyBUZXh0Rm9ybWF0IGRhdGEsIGlucHV0OiBcIiIKKyAgICAgICAgIDw8IGlucHV0X2Zvcl9kZWNvZGUgPDwgIlwiLCBkZXNpcmVkOiBcIiIgPDwgZGVzaXJlZF9vdXRwdXQgPDwgIlwiLiIKKyAgICAgICAgIDw8IGVuZGw7CisgICAgY2Vyci5mbHVzaCgpOworICAgIGFib3J0KCk7CisgIH0KKyAgaWYgKChpbnB1dF9mb3JfZGVjb2RlLmZpbmQoJ1wwJykgIT0gc3RyaW5nOjpucG9zKSB8fAorICAgICAgKGRlc2lyZWRfb3V0cHV0LmZpbmQoJ1wwJykgIT0gc3RyaW5nOjpucG9zKSkgeworICAgIGNlcnIgPDwgImVycm9yOiBnb3QgYSBudWxsIGNoYXIgaW4gYSBzdHJpbmcgZm9yIG1ha2luZyBUZXh0Rm9ybWF0IGRhdGEsIgorICAgICAgICAgPDwgIiBpbnB1dDogXCIiIDw8IENFc2NhcGUoaW5wdXRfZm9yX2RlY29kZSkgPDwgIlwiLCBkZXNpcmVkOiBcIiIKKyAgICAgICAgIDw8IENFc2NhcGUoZGVzaXJlZF9vdXRwdXQpIDw8ICJcIi4iIDw8IGVuZGw7CisgICAgY2Vyci5mbHVzaCgpOworICAgIGFib3J0KCk7CisgIH0KKworICBEZWNvZGVEYXRhQnVpbGRlciBidWlsZGVyOworCisgIC8vIFdhbGsgdGhlIG91dHB1dCBidWlsZGluZyBpdCBmcm9tIHRoZSBpbnB1dC4KKyAgaW50IHggPSAwOworICBmb3IgKGludCB5ID0gMDsgeSA8IGRlc2lyZWRfb3V0cHV0LnNpemUoKTsgeSsrKSB7CisgICAgY29uc3QgY2hhciBkID0gZGVzaXJlZF9vdXRwdXRbeV07CisgICAgaWYgKGQgPT0gJ18nKSB7CisgICAgICBidWlsZGVyLkFkZFVuZGVyc2NvcmUoKTsKKyAgICAgIGNvbnRpbnVlOworICAgIH0KKworICAgIGlmICh4ID49IGlucHV0X2Zvcl9kZWNvZGUuc2l6ZSgpKSB7CisgICAgICAvLyBPdXQgb2YgaW5wdXQsIG5vIHdheSB0byBlbmNvZGUgaXQsIGp1c3QgcmV0dXJuIGEgZnVsbCBkZWNvZGUuCisgICAgICByZXR1cm4gRGlyZWN0RGVjb2RlU3RyaW5nKGRlc2lyZWRfb3V0cHV0KTsKKyAgICB9CisgICAgaWYgKGJ1aWxkZXIuQWRkQ2hhcmFjdGVyKGQsIGlucHV0X2Zvcl9kZWNvZGVbeF0pKSB7CisgICAgICArK3g7ICAvLyBDb25zdW1lZCBvbmUgaW5wdXQKKyAgICB9IGVsc2UgeworICAgICAgLy8gQ291bGRuJ3QgdHJhbnNmb3JtIGZvciB0aGUgbmV4dCBjaGFyYWN0ZXIsIGp1c3QgcmV0dXJuIGEgZnVsbCBkZWNvZGUuCisgICAgICByZXR1cm4gRGlyZWN0RGVjb2RlU3RyaW5nKGRlc2lyZWRfb3V0cHV0KTsKKyAgICB9CisgIH0KKworICBpZiAoeCAhPSBpbnB1dF9mb3JfZGVjb2RlLnNpemUoKSkgeworICAgIC8vIEV4dHJhIGlucHV0IChzdWZmaXggZnJvbSBuYW1lIHNhbml0aXppbmc/KSwganVzdCByZXR1cm4gYSBmdWxsIGRlY29kZS4KKyAgICByZXR1cm4gRGlyZWN0RGVjb2RlU3RyaW5nKGRlc2lyZWRfb3V0cHV0KTsKKyAgfQorCisgIC8vIEFkZCB0aGUgZW5kIG1hcmtlci4KKyAgcmV0dXJuIGJ1aWxkZXIuRmluaXNoKCkgKyAoY2hhciknXDAnOworfQorCit9ICAvLyBuYW1lc3BhY2Ugb2JqZWN0aXZlYworfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX2hlbHBlcnMuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX2hlbHBlcnMuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NTc0NDg2Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfaGVscGVycy5oCkBAIC0wLDAgKzEsMTc1IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfT0JKRUNUSVZFQ19IRUxQRVJTX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfT0JKRUNUSVZFQ19IRUxQRVJTX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPHZlY3Rvcj4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBvYmplY3RpdmVjIHsKKworLy8gU3RyaXBzICIucHJvdG8iIG9yICIucHJvdG9kZXZlbCIgZnJvbSB0aGUgZW5kIG9mIGEgZmlsZW5hbWUuCitzdHJpbmcgU3RyaXBQcm90byhjb25zdCBzdHJpbmcmIGZpbGVuYW1lKTsKKworLy8gUmV0dXJucyB0cnVlIGlmIHRoZSBuYW1lIHJlcXVpcmVzIGEgbnNfcmV0dXJuc19ub3RfcmV0YWluZWQgYXR0cmlidXRlIGFwcGxpZWQKKy8vIHRvIGl0LgorYm9vbCBJc1JldGFpbmVkTmFtZShjb25zdCBzdHJpbmcmIG5hbWUpOworCisvLyBSZXR1cm5zIHRydWUgaWYgdGhlIG5hbWUgc3RhcnRzIHdpdGggImluaXQiIGFuZCB3aWxsIG5lZWQgdG8gaGF2ZSBzcGVjaWFsCisvLyBoYW5kbGluZyB1bmRlciBBUkMuCitib29sIElzSW5pdE5hbWUoY29uc3Qgc3RyaW5nJiBuYW1lKTsKKworLy8gR2V0cyB0aGUgbmFtZSBvZiB0aGUgZmlsZSB3ZSdyZSBnb2luZyB0byBnZW5lcmF0ZSAoc2FucyB0aGUgLnBiLmgKKy8vIGV4dGVuc2lvbikuICBUaGlzIGRvZXMgbm90IGluY2x1ZGUgdGhlIHBhdGggdG8gdGhhdCBmaWxlLgorc3RyaW5nIEZpbGVOYW1lKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKTsKKworLy8gR2V0cyB0aGUgcGF0aCBvZiB0aGUgZmlsZSB3ZSdyZSBnb2luZyB0byBnZW5lcmF0ZSAoc2FucyB0aGUgLnBiLmgKKy8vIGV4dGVuc2lvbikuICBUaGUgcGF0aCB3aWxsIGJlIGRlcGVuZGVudCBvbiB0aGUgb2JqZWN0aXZlYyBwYWNrYWdlCisvLyBkZWNsYXJlZCBpbiB0aGUgcHJvdG8gcGFja2FnZS4KK3N0cmluZyBGaWxlUGF0aChjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSk7CisKKy8vIEdldHMgdGhlIG5hbWUgb2YgdGhlIHJvb3QgY2xhc3Mgd2UnbGwgZ2VuZXJhdGUgaW4gdGhlIGZpbGUuICBUaGlzIGNsYXNzCisvLyBpcyBub3QgbWVhbnQgZm9yIGV4dGVybmFsIGNvbnN1bXB0aW9uLCBidXQgaW5zdGVhZCBjb250YWlucyBoZWxwZXJzIHRoYXQKKy8vIHRoZSByZXN0IG9mIHRoZSBjbGFzc2VzIG5lZWQKK3N0cmluZyBGaWxlQ2xhc3NOYW1lKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKTsKKworLy8gVGhlc2UgcmV0dXJuIHRoZSBmdWxseS1xdWFsaWZpZWQgY2xhc3MgbmFtZSBjb3JyZXNwb25kaW5nIHRvIHRoZSBnaXZlbgorLy8gZGVzY3JpcHRvci4KK3N0cmluZyBDbGFzc05hbWUoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CitzdHJpbmcgRW51bU5hbWUoY29uc3QgRW51bURlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworCisvLyBSZXR1cm5zIHRoZSBmdWxseS1xdWFsaWZpZWQgbmFtZSBvZiB0aGUgZW51bSB2YWx1ZSBjb3JyZXNwb25kaW5nIHRvIHRoZQorLy8gdGhlIGRlc2NyaXB0b3IuCitzdHJpbmcgRW51bVZhbHVlTmFtZShjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKKworLy8gUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgZW51bSB2YWx1ZSBjb3JyZXNwb25kaW5nIHRvIHRoZSBkZXNjcmlwdG9yLgorc3RyaW5nIEVudW1WYWx1ZVNob3J0TmFtZShjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKKworLy8gUmV2ZXJzZSB3aGF0IGFuIGVudW0gZG9lcy4KK3N0cmluZyBVbkNhbWVsQ2FzZUVudW1TaG9ydE5hbWUoY29uc3Qgc3RyaW5nJiBuYW1lKTsKKworLy8gUmV0dXJucyB0aGUgbmFtZSB0byB1c2UgZm9yIHRoZSBleHRlbnNpb24gKHVzZWQgYXMgdGhlIG1ldGhvZCBvZmYgdGhlIGZpbGUncworLy8gUm9vdCBjbGFzcykuCitzdHJpbmcgRXh0ZW5zaW9uTWV0aG9kTmFtZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworCisvLyBSZXR1cm5zIHRoZSB0cmFuc2Zvcm1lZCBmaWVsZCBuYW1lLgorc3RyaW5nIEZpZWxkTmFtZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKTsKK3N0cmluZyBGaWVsZE5hbWVDYXBpdGFsaXplZChjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKTsKKworLy8gUmV0dXJucyB0aGUgdHJhbnNmb3JtZWQgb25lb2YgbmFtZS4KK3N0cmluZyBPbmVvZkVudW1OYW1lKGNvbnN0IE9uZW9mRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CitzdHJpbmcgT25lb2ZOYW1lKGNvbnN0IE9uZW9mRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CitzdHJpbmcgT25lb2ZOYW1lQ2FwaXRhbGl6ZWQoY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKKworaW5saW5lIGJvb2wgSGFzRmllbGRQcmVzZW5jZShjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSkgeworICByZXR1cm4gZmlsZS0+c3ludGF4KCkgIT0gRmlsZURlc2NyaXB0b3I6OlNZTlRBWF9QUk9UTzM7Cit9CisKK2lubGluZSBib29sIEhhc1ByZXNlcnZpbmdVbmtub3duRW51bVNlbWFudGljcyhjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSkgeworICByZXR1cm4gZmlsZS0+c3ludGF4KCkgPT0gRmlsZURlc2NyaXB0b3I6OlNZTlRBWF9QUk9UTzM7Cit9CisKK2lubGluZSBib29sIElzTWFwRW50cnlNZXNzYWdlKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgcmV0dXJuIGRlc2NyaXB0b3ItPm9wdGlvbnMoKS5tYXBfZW50cnkoKTsKK30KKworLy8gUmV2ZXJzZSBvZiB0aGUgYWJvdmUuCitzdHJpbmcgVW5DYW1lbENhc2VGaWVsZE5hbWUoY29uc3Qgc3RyaW5nJiBuYW1lLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKTsKKworZW51bSBPYmplY3RpdmVDVHlwZSB7CisgIE9CSkVDVElWRUNUWVBFX0lOVDMyLAorICBPQkpFQ1RJVkVDVFlQRV9VSU5UMzIsCisgIE9CSkVDVElWRUNUWVBFX0lOVDY0LAorICBPQkpFQ1RJVkVDVFlQRV9VSU5UNjQsCisgIE9CSkVDVElWRUNUWVBFX0ZMT0FULAorICBPQkpFQ1RJVkVDVFlQRV9ET1VCTEUsCisgIE9CSkVDVElWRUNUWVBFX0JPT0xFQU4sCisgIE9CSkVDVElWRUNUWVBFX1NUUklORywKKyAgT0JKRUNUSVZFQ1RZUEVfREFUQSwKKyAgT0JKRUNUSVZFQ1RZUEVfRU5VTSwKKyAgT0JKRUNUSVZFQ1RZUEVfTUVTU0FHRQorfTsKKworc3RyaW5nIEdldENhcGl0YWxpemVkVHlwZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKTsKKworT2JqZWN0aXZlQ1R5cGUgR2V0T2JqZWN0aXZlQ1R5cGUoRmllbGREZXNjcmlwdG9yOjpUeXBlIGZpZWxkX3R5cGUpOworCitpbmxpbmUgT2JqZWN0aXZlQ1R5cGUgR2V0T2JqZWN0aXZlQ1R5cGUoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICByZXR1cm4gR2V0T2JqZWN0aXZlQ1R5cGUoZmllbGQtPnR5cGUoKSk7Cit9CisKK2Jvb2wgSXNQcmltaXRpdmVUeXBlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpOworYm9vbCBJc1JlZmVyZW5jZVR5cGUoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCk7CisKK3N0cmluZyBHUEJHZW5lcmljVmFsdWVGaWVsZE5hbWUoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCk7CitzdHJpbmcgRGVmYXVsdFZhbHVlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpOworCitzdHJpbmcgQnVpbGRGbGFnc1N0cmluZyhjb25zdCB2ZWN0b3I8c3RyaW5nPiYgc3RyaW5ncyk7CisKK3N0cmluZyBCdWlsZENvbW1lbnRzU3RyaW5nKGNvbnN0IFNvdXJjZUxvY2F0aW9uJiBsb2NhdGlvbik7CisKKy8vIENoZWNrcyB0aGUgcHJlZml4IGZvciBhIGdpdmVuIGZpbGUgYW5kIG91dHB1dHMgYW55IHdhcm5pbmdzIG5lZWRlZCwgaWYKKy8vIHRoZXJlIGFyZSBmbGF0IG91dCBlcnJvcnMsIHRoZW4gb3V0X2Vycm9yIGlzIGZpbGxlZCBpbiBhbmQgdGhlIHJlc3VsdCBpcworLy8gZmFsc2UuCitib29sIFZhbGlkYXRlT2JqQ0NsYXNzUHJlZml4KGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlLCBzdHJpbmcgKm91dF9lcnJvcik7CisKKy8vIEdlbmVyYXRlIGRlY29kZSBkYXRhIG5lZWRlZCBmb3IgT2JqQydzIEdQQkRlY29kZVRleHRGb3JtYXROYW1lKCkgdG8gdHJhbnNmb3JtCisvLyB0aGUgaW5wdXQgaW50byB0aGUgZXhwZWN0ZWQgb3V0cHV0LgorY2xhc3MgTElCUFJPVE9DX0VYUE9SVCBUZXh0Rm9ybWF0RGVjb2RlRGF0YSB7CisgcHVibGljOgorICBUZXh0Rm9ybWF0RGVjb2RlRGF0YSgpIHt9CisKKyAgdm9pZCBBZGRTdHJpbmcoaW50MzIga2V5LCBjb25zdCBzdHJpbmcmIGlucHV0X2Zvcl9kZWNvZGUsCisgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgZGVzaXJlZF9vdXRwdXQpOworICBzaXplX3QgbnVtX2VudHJpZXMoKSBjb25zdCB7IHJldHVybiBlbnRyaWVzXy5zaXplKCk7IH0KKyAgc3RyaW5nIERhdGEoKSBjb25zdDsKKworICBzdGF0aWMgc3RyaW5nIERlY29kZURhdGFGb3JTdHJpbmcoY29uc3Qgc3RyaW5nJiBpbnB1dF9mb3JfZGVjb2RlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBkZXNpcmVkX291dHB1dCk7CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoVGV4dEZvcm1hdERlY29kZURhdGEpOworCisgIHR5cGVkZWYgc3RkOjpwYWlyPGludDMyLCBzdHJpbmc+IERhdGFFbnRyeTsKKyAgdmVjdG9yPERhdGFFbnRyeT4gZW50cmllc187Cit9OworCit9ICAvLyBuYW1lc3BhY2Ugb2JqZWN0aXZlYworfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX09CSkVDVElWRUNfSEVMUEVSU19IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX2hlbHBlcnNfdW5pdHRlc3QuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19oZWxwZXJzX3VuaXR0ZXN0LmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRjMWNlZjUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19oZWxwZXJzX3VuaXR0ZXN0LmNjCkBAIC0wLDAgKzEsMjU3IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDE0IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfaGVscGVycy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2dvb2dsZXRlc3QuaD4KKyNpbmNsdWRlIDxndGVzdC9ndGVzdC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIG9iamVjdGl2ZWMgeworbmFtZXNwYWNlIHsKKworVEVTVChPYmpDSGVscGVyLCBUZXh0Rm9ybWF0RGVjb2RlRGF0YV9EZWNvZGVEYXRhRm9yU3RyaW5nX1Jhd1N0cmluZ3MpIHsKKyAgc3RyaW5nIGlucHV0X2Zvcl9kZWNvZGUoImFiY2RlZmdoSUoiKTsKKyAgc3RyaW5nIGRlc2lyZWRfb3V0cHV0X2Zvcl9kZWNvZGU7CisgIHN0cmluZyBleHBlY3RlZDsKKyAgc3RyaW5nIHJlc3VsdDsKKworICAvLyBEaWZmZXJlbnQgZGF0YSwgY2FuJ3QgdHJhbnNmb3JtLgorCisgIGRlc2lyZWRfb3V0cHV0X2Zvcl9kZWNvZGUgPSAiemJjZGVmZ2hJSiI7CisgIGV4cGVjdGVkID0gc3RyaW5nKCJcMHpiY2RlZmdoSUpcMCIsIDEyKTsKKyAgcmVzdWx0ID0gVGV4dEZvcm1hdERlY29kZURhdGE6OkRlY29kZURhdGFGb3JTdHJpbmcoaW5wdXRfZm9yX2RlY29kZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzaXJlZF9vdXRwdXRfZm9yX2RlY29kZSk7CisgIEVYUEVDVF9FUShleHBlY3RlZCwgcmVzdWx0KTsKKworICBkZXNpcmVkX291dHB1dF9mb3JfZGVjb2RlID0gImFiY2RlemdoSUoiOworICBleHBlY3RlZCA9IHN0cmluZygiXDBhYmNkZXpnaElKXDAiLCAxMik7CisgIHJlc3VsdCA9IFRleHRGb3JtYXREZWNvZGVEYXRhOjpEZWNvZGVEYXRhRm9yU3RyaW5nKGlucHV0X2Zvcl9kZWNvZGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc2lyZWRfb3V0cHV0X2Zvcl9kZWNvZGUpOworICBFWFBFQ1RfRVEoZXhwZWN0ZWQsIHJlc3VsdCk7CisKKyAgLy8gU2hvcnRlbmVkIGRhdGEsIGNhbid0IHRyYW5zZm9ybS4KKworICBkZXNpcmVkX291dHB1dF9mb3JfZGVjb2RlID0gImFiY2RlZmdoSSI7CisgIGV4cGVjdGVkID0gc3RyaW5nKCJcMGFiY2RlZmdoSVwwIiwgMTEpOworICByZXN1bHQgPSBUZXh0Rm9ybWF0RGVjb2RlRGF0YTo6RGVjb2RlRGF0YUZvclN0cmluZyhpbnB1dF9mb3JfZGVjb2RlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXNpcmVkX291dHB1dF9mb3JfZGVjb2RlKTsKKyAgRVhQRUNUX0VRKGV4cGVjdGVkLCByZXN1bHQpOworCisgIC8vIEV4dHJhIGRhdGEsIGNhbid0IHRyYW5zZm9ybS4KKworICBkZXNpcmVkX291dHB1dF9mb3JfZGVjb2RlID0gImFiY2RlZmdoSUp6IjsKKyAgZXhwZWN0ZWQgPSBzdHJpbmcoIlwwYWJjZGVmZ2hJSnpcMCIsIDEzKTsKKyAgcmVzdWx0ID0gVGV4dEZvcm1hdERlY29kZURhdGE6OkRlY29kZURhdGFGb3JTdHJpbmcoaW5wdXRfZm9yX2RlY29kZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzaXJlZF9vdXRwdXRfZm9yX2RlY29kZSk7CisgIEVYUEVDVF9FUShleHBlY3RlZCwgcmVzdWx0KTsKK30KKworVEVTVChPYmpDSGVscGVyLCBUZXh0Rm9ybWF0RGVjb2RlRGF0YV9EZWNvZGVEYXRhRm9yU3RyaW5nX0J5dGVDb2RlcykgeworICBzdHJpbmcgaW5wdXRfZm9yX2RlY29kZSgiYWJjZGVmZ2hJSiIpOworICBzdHJpbmcgZGVzaXJlZF9vdXRwdXRfZm9yX2RlY29kZTsKKyAgc3RyaW5nIGV4cGVjdGVkOworICBzdHJpbmcgcmVzdWx0OworCisgIGRlc2lyZWRfb3V0cHV0X2Zvcl9kZWNvZGUgPSAiYWJjZGVmZ2hJSiI7CisgIGV4cGVjdGVkID0gc3RyaW5nKCJceDBBXHgwIiwgMik7CisgIHJlc3VsdCA9IFRleHRGb3JtYXREZWNvZGVEYXRhOjpEZWNvZGVEYXRhRm9yU3RyaW5nKGlucHV0X2Zvcl9kZWNvZGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc2lyZWRfb3V0cHV0X2Zvcl9kZWNvZGUpOworICBFWFBFQ1RfRVEoZXhwZWN0ZWQsIHJlc3VsdCk7CisKKyAgZGVzaXJlZF9vdXRwdXRfZm9yX2RlY29kZSA9ICJfQWJjZGVmZ2hJSiI7CisgIGV4cGVjdGVkID0gc3RyaW5nKCJceENBXHgwIiwgMik7CisgIHJlc3VsdCA9IFRleHRGb3JtYXREZWNvZGVEYXRhOjpEZWNvZGVEYXRhRm9yU3RyaW5nKGlucHV0X2Zvcl9kZWNvZGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc2lyZWRfb3V0cHV0X2Zvcl9kZWNvZGUpOworICBFWFBFQ1RfRVEoZXhwZWN0ZWQsIHJlc3VsdCk7CisKKyAgZGVzaXJlZF9vdXRwdXRfZm9yX2RlY29kZSA9ICJBQkNEX19FZmdoSV9qIjsKKyAgZXhwZWN0ZWQgPSBzdHJpbmcoIlx4NjRceDgwXHhDNVx4QTFceDAiLCA1KTsKKyAgcmVzdWx0ID0gVGV4dEZvcm1hdERlY29kZURhdGE6OkRlY29kZURhdGFGb3JTdHJpbmcoaW5wdXRfZm9yX2RlY29kZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzaXJlZF9vdXRwdXRfZm9yX2RlY29kZSk7CisgIEVYUEVDVF9FUShleHBlY3RlZCwgcmVzdWx0KTsKKworICAvLyBMb25nIG5hbWUgc28gbXVsdGlwbGUgZGVjb2RlIG9wcyBhcmUgbmVlZGVkLgorCisgIGlucHV0X2Zvcl9kZWNvZGUgPQorICAgICAgImxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDAwIjsKKyAgZGVzaXJlZF9vdXRwdXRfZm9yX2RlY29kZSA9CisgICAgICAibG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTAwMCI7CisgIGV4cGVjdGVkID0gc3RyaW5nKCJceDA0XHhBNVx4QTRceEEyXHhCRlx4MUZceDBFXHg4NFx4MCIsIDkpOworICByZXN1bHQgPSBUZXh0Rm9ybWF0RGVjb2RlRGF0YTo6RGVjb2RlRGF0YUZvclN0cmluZyhpbnB1dF9mb3JfZGVjb2RlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXNpcmVkX291dHB1dF9mb3JfZGVjb2RlKTsKKyAgRVhQRUNUX0VRKGV4cGVjdGVkLCByZXN1bHQpOworfQorCisvLyBEZWF0aCB0ZXN0cyBkbyBub3Qgd29yayBvbiBXaW5kb3dzIGFzIG9mIHlldC4KKyNpZmRlZiBQUk9UT0JVRl9IQVNfREVBVEhfVEVTVAorVEVTVChPYmpDSGVscGVyRGVhdGhUZXN0LCBUZXh0Rm9ybWF0RGVjb2RlRGF0YV9EZWNvZGVEYXRhRm9yU3RyaW5nX0ZhaWx1cmVzKSB7CisgIC8vIEVtcHR5IGlucHV0cy4KKworICBFWFBFQ1RfRVhJVChUZXh0Rm9ybWF0RGVjb2RlRGF0YTo6RGVjb2RlRGF0YUZvclN0cmluZygiIiwgIiIpLAorICAgICAgICAgICAgICA6OnRlc3Rpbmc6OktpbGxlZEJ5U2lnbmFsKFNJR0FCUlQpLAorICAgICAgICAgICAgICAiZXJyb3I6IGdvdCBlbXB0eSBzdHJpbmcgZm9yIG1ha2luZyBUZXh0Rm9ybWF0IGRhdGEsIGlucHV0OiIpOworICBFWFBFQ1RfRVhJVChUZXh0Rm9ybWF0RGVjb2RlRGF0YTo6RGVjb2RlRGF0YUZvclN0cmluZygiYSIsICIiKSwKKyAgICAgICAgICAgICAgOjp0ZXN0aW5nOjpLaWxsZWRCeVNpZ25hbChTSUdBQlJUKSwKKyAgICAgICAgICAgICAgImVycm9yOiBnb3QgZW1wdHkgc3RyaW5nIGZvciBtYWtpbmcgVGV4dEZvcm1hdCBkYXRhLCBpbnB1dDoiKTsKKyAgRVhQRUNUX0VYSVQoVGV4dEZvcm1hdERlY29kZURhdGE6OkRlY29kZURhdGFGb3JTdHJpbmcoIiIsICJhIiksCisgICAgICAgICAgICAgIDo6dGVzdGluZzo6S2lsbGVkQnlTaWduYWwoU0lHQUJSVCksCisgICAgICAgICAgICAgICJlcnJvcjogZ290IGVtcHR5IHN0cmluZyBmb3IgbWFraW5nIFRleHRGb3JtYXQgZGF0YSwgaW5wdXQ6Iik7CisKKyAgLy8gTnVsbCBjaGFyIGluIHRoZSBzdHJpbmcuCisKKyAgc3RyaW5nIHN0cl93aXRoX251bGxfY2hhcigiYWJcMGMiLCA0KTsKKyAgRVhQRUNUX0VYSVQoCisgICAgICBUZXh0Rm9ybWF0RGVjb2RlRGF0YTo6RGVjb2RlRGF0YUZvclN0cmluZyhzdHJfd2l0aF9udWxsX2NoYXIsICJkZWYiKSwKKyAgICAgIDo6dGVzdGluZzo6S2lsbGVkQnlTaWduYWwoU0lHQUJSVCksCisgICAgICAiZXJyb3I6IGdvdCBhIG51bGwgY2hhciBpbiBhIHN0cmluZyBmb3IgbWFraW5nIFRleHRGb3JtYXQgZGF0YSwgaW5wdXQ6Iik7CisgIEVYUEVDVF9FWElUKAorICAgICAgVGV4dEZvcm1hdERlY29kZURhdGE6OkRlY29kZURhdGFGb3JTdHJpbmcoImRlZiIsIHN0cl93aXRoX251bGxfY2hhciksCisgICAgICA6OnRlc3Rpbmc6OktpbGxlZEJ5U2lnbmFsKFNJR0FCUlQpLAorICAgICAgImVycm9yOiBnb3QgYSBudWxsIGNoYXIgaW4gYSBzdHJpbmcgZm9yIG1ha2luZyBUZXh0Rm9ybWF0IGRhdGEsIGlucHV0OiIpOworfQorI2VuZGlmICAvLyBQUk9UT0JVRl9IQVNfREVBVEhfVEVTVAorCitURVNUKE9iakNIZWxwZXIsIFRleHRGb3JtYXREZWNvZGVEYXRhX1Jhd1N0cmluZ3MpIHsKKyAgVGV4dEZvcm1hdERlY29kZURhdGEgZGVjb2RlX2RhdGE7CisKKyAgLy8gRGlmZmVyZW50IGRhdGEsIGNhbid0IHRyYW5zZm9ybS4KKyAgZGVjb2RlX2RhdGEuQWRkU3RyaW5nKDEsICJhYmNkZWZnaElKIiwgInpiY2RlZmdoSUoiKTsKKyAgZGVjb2RlX2RhdGEuQWRkU3RyaW5nKDMsICJhYmNkZWZnaElKIiwgImFiY2RlemdoSUoiKTsKKyAgLy8gU2hvcnRlbmVkIGRhdGEsIGNhbid0IHRyYW5zZm9ybS4KKyAgZGVjb2RlX2RhdGEuQWRkU3RyaW5nKDIsICJhYmNkZWZnaElKIiwgImFiY2RlZmdoSSIpOworICAvLyBFeHRyYSBkYXRhLCBjYW4ndCB0cmFuc2Zvcm0uCisgIGRlY29kZV9kYXRhLkFkZFN0cmluZyg0LCAiYWJjZGVmZ2hJSiIsICJhYmNkZWZnaElKeiIpOworCisgIEVYUEVDVF9FUSg0LCBkZWNvZGVfZGF0YS5udW1fZW50cmllcygpKTsKKworICB1aW50OCBleHBlY3RlZF9kYXRhW10gPSB7CisgICAgICAweDQsCisgICAgICAweDEsIDB4MCwgJ3onLCAnYicsICdjJywgJ2QnLCAnZScsICdmJywgJ2cnLCAnaCcsICdJJywgJ0onLCAweDAsCisgICAgICAweDMsIDB4MCwgJ2EnLCAnYicsICdjJywgJ2QnLCAnZScsICd6JywgJ2cnLCAnaCcsICdJJywgJ0onLCAweDAsCisgICAgICAweDIsIDB4MCwgJ2EnLCAnYicsICdjJywgJ2QnLCAnZScsICdmJywgJ2cnLCAnaCcsICdJJywgMHgwLAorICAgICAgMHg0LCAweDAsICdhJywgJ2InLCAnYycsICdkJywgJ2UnLCAnZicsICdnJywgJ2gnLCAnSScsICdKJywgJ3onLCAweDAsCisgIH07CisgIHN0cmluZyBleHBlY3RlZCgoY29uc3QgY2hhciopZXhwZWN0ZWRfZGF0YSwgc2l6ZW9mKGV4cGVjdGVkX2RhdGEpKTsKKworICBFWFBFQ1RfRVEoZXhwZWN0ZWQsIGRlY29kZV9kYXRhLkRhdGEoKSk7Cit9CisKK1RFU1QoT2JqQ0hlbHBlciwgVGV4dEZvcm1hdERlY29kZURhdGFfQnl0ZUNvZGVzKSB7CisgIFRleHRGb3JtYXREZWNvZGVEYXRhIGRlY29kZV9kYXRhOworCisgIGRlY29kZV9kYXRhLkFkZFN0cmluZygxLCAiYWJjZGVmZ2hJSiIsICJhYmNkZWZnaElKIik7CisgIGRlY29kZV9kYXRhLkFkZFN0cmluZygzLCAiYWJjZGVmZ2hJSiIsICJfQWJjZGVmZ2hJSiIpOworICBkZWNvZGVfZGF0YS5BZGRTdHJpbmcoMiwgImFiY2RlZmdoSUoiLCAiQWJjZF9FZmdoSUoiKTsKKyAgZGVjb2RlX2RhdGEuQWRkU3RyaW5nKDQsICJhYmNkZWZnaElKIiwgIkFCQ0RfX0VmZ2hJX2oiKTsKKyAgZGVjb2RlX2RhdGEuQWRkU3RyaW5nKDEwMDAsCisgICAgICAgICAgICAgICAgICAgICAgICAibG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMDAiLAorICAgICAgICAgICAgICAgICAgICAgICAgImxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwMDAiKTsKKworICBFWFBFQ1RfRVEoNSwgZGVjb2RlX2RhdGEubnVtX2VudHJpZXMoKSk7CisKKyAgdWludDggZXhwZWN0ZWRfZGF0YVtdID0geworICAgICAgMHg1LAorICAgICAgLy8gQWxsIGFzIGlzICgwMCBvcCkKKyAgICAgIDB4MSwgIDB4MEEsIDB4MCwKKyAgICAgIC8vIFVuZGVyc2NvcmUsIHVwcGVyICsgOSAoMTAgb3ApCisgICAgICAweDMsICAweENBLCAweDAsCisgICAgICAvLyAgVXBwZXIgKyAzICgxMCBvcCksIHVuZGVyc2NvcmUsIHVwcGVyICsgNSAoMTAgb3ApCisgICAgICAweDIsICAweDQ0LCAweEM2LCAweDAsCisgICAgICAvLyBBbGwgVXBwZXIgZm9yIDQgKDExIG9wKSwgdW5kZXJzY29yZSwgdW5kZXJzY29yZSwgdXBwZXIgKyA1ICgxMCBvcCksCisgICAgICAvLyB1bmRlcnNjb3JlLCBsb3dlciArIDAgKDAxIG9wKQorICAgICAgMHg0LCAgMHg2NCwgMHg4MCwgMHhDNSwgMHhBMSwgMHgwLAorICAgICAgLy8gMiBieXRlIGtleTogYXMgaXMgKyAzICgwMCBvcCksIHVuZGVyc2NvcmUsIGxvd2VyICsgNCAoMDEgb3ApLAorICAgICAgLy8gICB1bmRlcnNjb3JlLCBsb3dlciArIDMgKDAxIG9wKSwgdW5kZXJzY29yZSwgbG93ZXIgKyAxICgwMSBvcCksCisgICAgICAvLyAgIHVuZGVyc2NvcmUsIGxvd2VyICsgMzAgKDAxIG9wKSwgYXMgaXMgKyAzMCAoMDAgb3ApLCBhcyBpcyArIDEzICgwMAorICAgICAgLy8gICBvcCksCisgICAgICAvLyAgIHVuZGVyc2NvcmUsIGFzIGlzICsgMyAoMDAgb3ApCisgICAgICAweEU4LCAweDA3LCAweDA0LCAweEE1LCAweEE0LCAweEEyLCAweEJGLCAweDFGLCAweDBFLCAweDg0LCAweDAsCisgIH07CisgIHN0cmluZyBleHBlY3RlZCgoY29uc3QgY2hhciopZXhwZWN0ZWRfZGF0YSwgc2l6ZW9mKGV4cGVjdGVkX2RhdGEpKTsKKworICBFWFBFQ1RfRVEoZXhwZWN0ZWQsIGRlY29kZV9kYXRhLkRhdGEoKSk7Cit9CisKKworLy8gRGVhdGggdGVzdHMgZG8gbm90IHdvcmsgb24gV2luZG93cyBhcyBvZiB5ZXQuCisjaWZkZWYgUFJPVE9CVUZfSEFTX0RFQVRIX1RFU1QKK1RFU1QoT2JqQ0hlbHBlckRlYXRoVGVzdCwgVGV4dEZvcm1hdERlY29kZURhdGFfRmFpbHVyZXMpIHsKKyAgVGV4dEZvcm1hdERlY29kZURhdGEgZGVjb2RlX2RhdGE7CisKKyAgLy8gRW1wdHkgaW5wdXRzLgorCisgIEVYUEVDVF9FWElUKGRlY29kZV9kYXRhLkFkZFN0cmluZygxLCAiIiwgIiIpLAorICAgICAgICAgICAgICA6OnRlc3Rpbmc6OktpbGxlZEJ5U2lnbmFsKFNJR0FCUlQpLAorICAgICAgICAgICAgICAiZXJyb3I6IGdvdCBlbXB0eSBzdHJpbmcgZm9yIG1ha2luZyBUZXh0Rm9ybWF0IGRhdGEsIGlucHV0OiIpOworICBFWFBFQ1RfRVhJVChkZWNvZGVfZGF0YS5BZGRTdHJpbmcoMSwgImEiLCAiIiksCisgICAgICAgICAgICAgIDo6dGVzdGluZzo6S2lsbGVkQnlTaWduYWwoU0lHQUJSVCksCisgICAgICAgICAgICAgICJlcnJvcjogZ290IGVtcHR5IHN0cmluZyBmb3IgbWFraW5nIFRleHRGb3JtYXQgZGF0YSwgaW5wdXQ6Iik7CisgIEVYUEVDVF9FWElUKGRlY29kZV9kYXRhLkFkZFN0cmluZygxLCAiIiwgImEiKSwKKyAgICAgICAgICAgICAgOjp0ZXN0aW5nOjpLaWxsZWRCeVNpZ25hbChTSUdBQlJUKSwKKyAgICAgICAgICAgICAgImVycm9yOiBnb3QgZW1wdHkgc3RyaW5nIGZvciBtYWtpbmcgVGV4dEZvcm1hdCBkYXRhLCBpbnB1dDoiKTsKKworICAvLyBOdWxsIGNoYXIgaW4gdGhlIHN0cmluZy4KKworICBzdHJpbmcgc3RyX3dpdGhfbnVsbF9jaGFyKCJhYlwwYyIsIDQpOworICBFWFBFQ1RfRVhJVCgKKyAgICAgIGRlY29kZV9kYXRhLkFkZFN0cmluZygxLCBzdHJfd2l0aF9udWxsX2NoYXIsICJkZWYiKSwKKyAgICAgIDo6dGVzdGluZzo6S2lsbGVkQnlTaWduYWwoU0lHQUJSVCksCisgICAgICAiZXJyb3I6IGdvdCBhIG51bGwgY2hhciBpbiBhIHN0cmluZyBmb3IgbWFraW5nIFRleHRGb3JtYXQgZGF0YSwgaW5wdXQ6Iik7CisgIEVYUEVDVF9FWElUKAorICAgICAgZGVjb2RlX2RhdGEuQWRkU3RyaW5nKDEsICJkZWYiLCBzdHJfd2l0aF9udWxsX2NoYXIpLAorICAgICAgOjp0ZXN0aW5nOjpLaWxsZWRCeVNpZ25hbChTSUdBQlJUKSwKKyAgICAgICJlcnJvcjogZ290IGEgbnVsbCBjaGFyIGluIGEgc3RyaW5nIGZvciBtYWtpbmcgVGV4dEZvcm1hdCBkYXRhLCBpbnB1dDoiKTsKKworICAvLyBEdXBsaWNhdGUga2V5cworCisgIGRlY29kZV9kYXRhLkFkZFN0cmluZygxLCAiYWJjZGVmZ2hJSiIsICJhYmNkZWZnaElKIik7CisgIGRlY29kZV9kYXRhLkFkZFN0cmluZygzLCAiYWJjZGVmZ2hJSiIsICJfQWJjZGVmZ2hJSiIpOworICBkZWNvZGVfZGF0YS5BZGRTdHJpbmcoMiwgImFiY2RlZmdoSUoiLCAiQWJjZF9FZmdoSUoiKTsKKyAgRVhQRUNUX0VYSVQoZGVjb2RlX2RhdGEuQWRkU3RyaW5nKDIsICJ4eXoiLCAieF95eiIpLAorICAgICAgICAgICAgICA6OnRlc3Rpbmc6OktpbGxlZEJ5U2lnbmFsKFNJR0FCUlQpLAorICAgICAgICAgICAgICAiZXJyb3I6IGR1cGxpY2F0ZSBrZXkgXFwoMlxcKSBtYWtpbmcgVGV4dEZvcm1hdCBkYXRhLCBpbnB1dDoiKTsKK30KKyNlbmRpZiAgLy8gUFJPVE9CVUZfSEFTX0RFQVRIX1RFU1QKKworLy8gVE9ETyh0aG9tYXN2bCk6IFNob3VsZCBwcm9iYWJseSBhZGQgc29tZSB1bml0dGVzdHMgZm9yIGFsbCB0aGUgc3BlY2lhbCBjYXNlcworLy8gb2YgbmFtZSBtYW5nbGluZyAoY2xhc3MgbmFtZSwgZmllbGQgbmFtZSwgZW51bSBuYW1lcykuICBSYXRoZXIgdGhhbiBkb2luZworLy8gdGhpcyB3aXRoIGFuIE9iakMgdGVzdCBpbiB0aGUgb2JqZWN0aXZlYyBkaXJlY3RvcnksIHdlIHNob3VsZCBiZSBhYmxlIHRvCisvLyB1c2Ugc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9pbXBvcnRlciogKGxpa2Ugb3RoZXIgdGVzdHMpIHRvIHN1cHBvcnQgYQorLy8gdmlydHVhbCBmaWxlIHN5c3RlbSB0byBmZWVkIGluIHByb3Rvcywgb25jZSB3ZSBoYXZlIHRoZSBEZXNjcmlwdG9yIHRyZWUsIHRoZQorLy8gdGVzdHMgY291bGQgdXNlIHRoZSBoZWxwZXIgbWV0aG9kcyBmb3IgZ2VuZXJhdGluZyBuYW1lcyBhbmQgdmFsaWRhdGUgdGhlCisvLyByaWdodCB0aGluZ3MgYXJlIGhhcHBlbmluZy4KKworfSAgLy8gbmFtZXNwYWNlCit9ICAvLyBuYW1lc3BhY2Ugb2JqZWN0aXZlYworfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX21hcF9maWVsZC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX21hcF9maWVsZC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yOTg3ZjNkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfbWFwX2ZpZWxkLmNjCkBAIC0wLDAgKzEsMTYzIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDE1IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2luY2x1ZGUgPG1hcD4KKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX21hcF9maWVsZC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX2hlbHBlcnMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N1YnN0aXR1dGUuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBvYmplY3RpdmVjIHsKKworLy8gTWFwRmllbGRHZW5lcmF0b3IgdXNlcyBSZXBlYXRlZEZpZWxkR2VuZXJhdG9yIGFzIHRoZSBwYXJlbnQgYmVjYXVzZSBpdAorLy8gcHJvdmlkZXMgYSBidW5jaCBvZiB0aGluZ3MgKG5vIGhhcyogbWV0aG9kcywgY29tbWVudHMgZm9yIGNvbnRhaW5lZCB0eXBlLAorLy8gZXRjLikuCisKK25hbWVzcGFjZSB7CisKK2NvbnN0IGNoYXIqIE1hcEVudHJ5VHlwZU5hbWUoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBib29sIGlzS2V5KSB7CisgIE9iamVjdGl2ZUNUeXBlIHR5cGUgPSBHZXRPYmplY3RpdmVDVHlwZShkZXNjcmlwdG9yKTsKKyAgc3dpdGNoICh0eXBlKSB7CisgICAgY2FzZSBPQkpFQ1RJVkVDVFlQRV9JTlQzMjoKKyAgICAgIHJldHVybiAiSW50MzIiOworICAgIGNhc2UgT0JKRUNUSVZFQ1RZUEVfVUlOVDMyOgorICAgICAgcmV0dXJuICJVSW50MzIiOworICAgIGNhc2UgT0JKRUNUSVZFQ1RZUEVfSU5UNjQ6CisgICAgICByZXR1cm4gIkludDY0IjsKKyAgICBjYXNlIE9CSkVDVElWRUNUWVBFX1VJTlQ2NDoKKyAgICAgIHJldHVybiAiVUludDY0IjsKKyAgICBjYXNlIE9CSkVDVElWRUNUWVBFX0ZMT0FUOgorICAgICAgcmV0dXJuICJGbG9hdCI7CisgICAgY2FzZSBPQkpFQ1RJVkVDVFlQRV9ET1VCTEU6CisgICAgICByZXR1cm4gIkRvdWJsZSI7CisgICAgY2FzZSBPQkpFQ1RJVkVDVFlQRV9CT09MRUFOOgorICAgICAgcmV0dXJuICJCb29sIjsKKyAgICBjYXNlIE9CSkVDVElWRUNUWVBFX1NUUklORzoKKyAgICAgIHJldHVybiAoaXNLZXkgPyAiU3RyaW5nIiA6ICJPYmplY3QiKTsKKyAgICBjYXNlIE9CSkVDVElWRUNUWVBFX0RBVEE6CisgICAgICByZXR1cm4gIk9iamVjdCI7CisgICAgY2FzZSBPQkpFQ1RJVkVDVFlQRV9FTlVNOgorICAgICAgcmV0dXJuICJFbnVtIjsKKyAgICBjYXNlIE9CSkVDVElWRUNUWVBFX01FU1NBR0U6CisgICAgICByZXR1cm4gIk9iamVjdCI7CisgIH0KKworICAvLyBTb21lIGNvbXBpbGVycyByZXBvcnQgcmVhY2hpbmcgZW5kIG9mIGZ1bmN0aW9uIGV2ZW4gdGhvdWdoIGFsbCBjYXNlcyBvZgorICAvLyB0aGUgZW51bSBhcmUgaGFuZGVkIGluIHRoZSBzd2l0Y2guCisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJDYW4ndCBnZXQgaGVyZS4iOworICByZXR1cm4gTlVMTDsKK30KKworfSAgLy8gbmFtZXNwYWNlCisKK01hcEZpZWxkR2VuZXJhdG9yOjpNYXBGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpCisgICAgOiBSZXBlYXRlZEZpZWxkR2VuZXJhdG9yKGRlc2NyaXB0b3IpIHsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBrZXlfZGVzY3JpcHRvciA9CisgICAgICBkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJrZXkiKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiB2YWx1ZV9kZXNjcmlwdG9yID0KKyAgICAgIGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoInZhbHVlIik7CisgIHZhbHVlX2ZpZWxkX2dlbmVyYXRvcl8ucmVzZXQoRmllbGRHZW5lcmF0b3I6Ok1ha2UodmFsdWVfZGVzY3JpcHRvcikpOworCisgIC8vIFB1bGwgb3ZlciBzb21lIHZhcmlhYmxlc18gZnJvbSB0aGUgdmFsdWUuCisgIHZhcmlhYmxlc19bImZpZWxkX3R5cGUiXSA9IHZhbHVlX2ZpZWxkX2dlbmVyYXRvcl8tPnZhcmlhYmxlKCJmaWVsZF90eXBlIik7CisgIHZhcmlhYmxlc19bImRlZmF1bHQiXSA9IHZhbHVlX2ZpZWxkX2dlbmVyYXRvcl8tPnZhcmlhYmxlKCJkZWZhdWx0Iik7CisgIHZhcmlhYmxlc19bImRlZmF1bHRfbmFtZSJdID0gdmFsdWVfZmllbGRfZ2VuZXJhdG9yXy0+dmFyaWFibGUoImRlZmF1bHRfbmFtZSIpOworCisgIC8vIEJ1aWxkIGN1c3RvbSBmaWVsZCBmbGFncy4KKyAgc3RkOjp2ZWN0b3I8c3RyaW5nPiBmaWVsZF9mbGFnczsKKyAgZmllbGRfZmxhZ3MucHVzaF9iYWNrKCJHUEJGaWVsZE1hcEtleSIgKyBHZXRDYXBpdGFsaXplZFR5cGUoa2V5X2Rlc2NyaXB0b3IpKTsKKyAgLy8gUHVsbCBvdmVyIHRoZSBjdXJyZW50IHRleHQgZm9ybWF0IGN1c3RvbSBuYW1lIHZhbHVlcyB0aGF0IHdhcyBjYWxjdWxhdGVkLgorICBpZiAodmFyaWFibGVzX1siZmllbGRmbGFncyJdLmZpbmQoIkdQQkZpZWxkVGV4dEZvcm1hdE5hbWVDdXN0b20iKSAhPQorICAgICAgc3RyaW5nOjpucG9zKSB7CisgICAgZmllbGRfZmxhZ3MucHVzaF9iYWNrKCJHUEJGaWVsZFRleHRGb3JtYXROYW1lQ3VzdG9tIik7CisgIH0KKyAgLy8gUHVsbCBvdmVyIHNvbWUgaW5mbyBmcm9tIHRoZSB2YWx1ZSdzIGZsYWdzLgorICBjb25zdCBzdHJpbmcmIHZhbHVlX2ZpZWxkX2ZsYWdzID0KKyAgICAgIHZhbHVlX2ZpZWxkX2dlbmVyYXRvcl8tPnZhcmlhYmxlKCJmaWVsZGZsYWdzIik7CisgIGlmICh2YWx1ZV9maWVsZF9mbGFncy5maW5kKCJHUEJGaWVsZEhhc0RlZmF1bHRWYWx1ZSIpICE9IHN0cmluZzo6bnBvcykgeworICAgIGZpZWxkX2ZsYWdzLnB1c2hfYmFjaygiR1BCRmllbGRIYXNEZWZhdWx0VmFsdWUiKTsKKyAgfQorICBpZiAodmFsdWVfZmllbGRfZmxhZ3MuZmluZCgiR1BCRmllbGRIYXNFbnVtRGVzY3JpcHRvciIpICE9IHN0cmluZzo6bnBvcykgeworICAgIGZpZWxkX2ZsYWdzLnB1c2hfYmFjaygiR1BCRmllbGRIYXNFbnVtRGVzY3JpcHRvciIpOworICB9CisgIHZhcmlhYmxlc19bImZpZWxkZmxhZ3MiXSA9IEJ1aWxkRmxhZ3NTdHJpbmcoZmllbGRfZmxhZ3MpOworCisgIE9iamVjdGl2ZUNUeXBlIHZhbHVlX29iamNfdHlwZSA9IEdldE9iamVjdGl2ZUNUeXBlKHZhbHVlX2Rlc2NyaXB0b3IpOworICBpZiAoKEdldE9iamVjdGl2ZUNUeXBlKGtleV9kZXNjcmlwdG9yKSA9PSBPQkpFQ1RJVkVDVFlQRV9TVFJJTkcpICYmCisgICAgICAoKHZhbHVlX29iamNfdHlwZSA9PSBPQkpFQ1RJVkVDVFlQRV9TVFJJTkcpIHx8CisgICAgICAgKHZhbHVlX29iamNfdHlwZSA9PSBPQkpFQ1RJVkVDVFlQRV9EQVRBKSB8fAorICAgICAgICh2YWx1ZV9vYmpjX3R5cGUgPT0gT0JKRUNUSVZFQ1RZUEVfTUVTU0FHRSkpKSB7CisgICAgdmFyaWFibGVzX1siYXJyYXlfc3RvcmFnZV90eXBlIl0gPSAiTlNNdXRhYmxlRGljdGlvbmFyeSI7CisgIH0gZWxzZSB7CisgICAgc3RyaW5nIGJhc2VfbmFtZSA9IE1hcEVudHJ5VHlwZU5hbWUoa2V5X2Rlc2NyaXB0b3IsIHRydWUpOworICAgIGJhc2VfbmFtZSArPSBNYXBFbnRyeVR5cGVOYW1lKHZhbHVlX2Rlc2NyaXB0b3IsIGZhbHNlKTsKKyAgICBiYXNlX25hbWUgKz0gIkRpY3Rpb25hcnkiOworICAgIHZhcmlhYmxlc19bImFycmF5X3N0b3JhZ2VfdHlwZSJdID0gIkdQQiIgKyBiYXNlX25hbWU7CisgIH0KK30KKworTWFwRmllbGRHZW5lcmF0b3I6On5NYXBGaWVsZEdlbmVyYXRvcigpIHt9CisKK3ZvaWQgTWFwRmllbGRHZW5lcmF0b3I6OkZpbmlzaEluaXRpYWxpemF0aW9uKHZvaWQpIHsKKyAgUmVwZWF0ZWRGaWVsZEdlbmVyYXRvcjo6RmluaXNoSW5pdGlhbGl6YXRpb24oKTsKKyAgLy8gVXNlIHRoZSBhcnJheV9jb21tZW50IHN1cG9ydCBpbiBSZXBlYXRlZEZpZWxkR2VuZXJhdG9yIHRvIG91dHB1dCB3aGF0IHRoZQorICAvLyB2YWx1ZXMgaW4gdGhlIG1hcCBhcmUuCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogdmFsdWVfZGVzY3JpcHRvciA9CisgICAgICBkZXNjcmlwdG9yXy0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgidmFsdWUiKTsKKyAgT2JqZWN0aXZlQ1R5cGUgdmFsdWVfb2JqY190eXBlID0gR2V0T2JqZWN0aXZlQ1R5cGUodmFsdWVfZGVzY3JpcHRvcik7CisgIGlmICgodmFsdWVfb2JqY190eXBlID09IE9CSkVDVElWRUNUWVBFX01FU1NBR0UpIHx8CisgICAgICAodmFsdWVfb2JqY190eXBlID09IE9CSkVDVElWRUNUWVBFX0RBVEEpIHx8CisgICAgICAodmFsdWVfb2JqY190eXBlID09IE9CSkVDVElWRUNUWVBFX1NUUklORykgfHwKKyAgICAgICh2YWx1ZV9vYmpjX3R5cGUgPT0gT0JKRUNUSVZFQ1RZUEVfRU5VTSkpIHsKKyAgICB2YXJpYWJsZXNfWyJhcnJheV9jb21tZW50Il0gPQorICAgICAgICAiLy8gfCIgKyB2YXJpYWJsZXNfWyJuYW1lIl0gKyAifCB2YWx1ZXMgYXJlIHwiICsgdmFsdWVfZmllbGRfZ2VuZXJhdG9yXy0+dmFyaWFibGUoInN0b3JhZ2VfdHlwZSIpICsgInxcbiI7CisgIH0gZWxzZSB7CisgICAgdmFyaWFibGVzX1siYXJyYXlfY29tbWVudCJdID0gIiI7CisgIH0KK30KKwordm9pZCBNYXBGaWVsZEdlbmVyYXRvcjo6R2VuZXJhdGVGaWVsZERlc2NyaXB0aW9uVHlwZVNwZWNpZmljKAorICAgIGlvOjpQcmludGVyKiBwcmludGVyKSBjb25zdCB7CisgIC8vIFJlbGF5IGl0IHRvIHRoZSB2YWx1ZSBnZW5lcmF0b3IgdG8gcHJvdmlkZSBlbnVtIHZhbGlkYXRvciwgbWVzc2FnZQorICAvLyBjbGFzcywgZXRjLgorICB2YWx1ZV9maWVsZF9nZW5lcmF0b3JfLT5HZW5lcmF0ZUZpZWxkRGVzY3JpcHRpb25UeXBlU3BlY2lmaWMocHJpbnRlcik7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBvYmplY3RpdmVjCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfbWFwX2ZpZWxkLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19tYXBfZmllbGQuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNzM1NDFmCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfbWFwX2ZpZWxkLmgKQEAgLTAsMCArMSw2NCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAxNSBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX09CSkVDVElWRUNfTUFQX0ZJRUxEX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfT0JKRUNUSVZFQ19NQVBfRklFTERfSF9fCisKKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfZmllbGQuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBvYmplY3RpdmVjIHsKKworY2xhc3MgTWFwRmllbGRHZW5lcmF0b3IgOiBwdWJsaWMgUmVwZWF0ZWRGaWVsZEdlbmVyYXRvciB7CisgIGZyaWVuZCBGaWVsZEdlbmVyYXRvciogRmllbGRHZW5lcmF0b3I6Ok1ha2UoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCk7CisKKyBwdWJsaWM6CisgIHZpcnR1YWwgdm9pZCBGaW5pc2hJbml0aWFsaXphdGlvbih2b2lkKTsKKyAgdmlydHVhbCB2b2lkIEdlbmVyYXRlRmllbGREZXNjcmlwdGlvblR5cGVTcGVjaWZpYyhpbzo6UHJpbnRlciogcHJpbnRlcikgY29uc3Q7CisKKyBwcm90ZWN0ZWQ6CisgIGV4cGxpY2l0IE1hcEZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CisgIHZpcnR1YWwgfk1hcEZpZWxkR2VuZXJhdG9yKCk7CisKKyBwcml2YXRlOgorICBzY29wZWRfcHRyPEZpZWxkR2VuZXJhdG9yPiB2YWx1ZV9maWVsZF9nZW5lcmF0b3JfOworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoTWFwRmllbGRHZW5lcmF0b3IpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIG9iamVjdGl2ZWMKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX09CSkVDVElWRUNfTUFQX0ZJRUxEX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfbWVzc2FnZS5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX21lc3NhZ2UuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzI2NzFkNAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX21lc3NhZ2UuY2MKQEAgLTAsMCArMSw2NDcgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaW5jbHVkZSA8YWxnb3JpdGhtPgorI2luY2x1ZGUgPGlvc3RyZWFtPgorI2luY2x1ZGUgPHNzdHJlYW0+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvaGFzaC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfbWVzc2FnZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfZW51bS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfZXh0ZW5zaW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0bF91dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbV9pbXBsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0X2xpdGVfaW5sLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBvYmplY3RpdmVjIHsKKwordXNpbmcgaW50ZXJuYWw6OldpcmVGb3JtYXQ7Cit1c2luZyBpbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU7CisKK25hbWVzcGFjZSB7CitzdHJ1Y3QgRmllbGRPcmRlcmluZ0J5TnVtYmVyIHsKKyAgaW5saW5lIGJvb2wgb3BlcmF0b3IoKShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBiKSBjb25zdCB7CisgICAgcmV0dXJuIGEtPm51bWJlcigpIDwgYi0+bnVtYmVyKCk7CisgIH0KK307CisKK2ludCBPcmRlckdyb3VwRm9yRmllbGREZXNjcmlwdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICAvLyBUaGUgZmlyc3QgaXRlbSBpbiB0aGUgb2JqZWN0IHN0cnVjdHVyZSBpcyBvdXIgdWludDMyW10gZm9yIGhhcyBiaXRzLgorICAvLyBXZSB0aGVuIHdhbnQgdG8gb3JkZXIgdGhpbmdzIHRvIG1ha2UgdGhlIGluc3RhbmNlcyBhcyBzbWFsbCBhcworICAvLyBwb3NzaWJsZS4gU28gd2UgZm9sbG93IHRoZSBoYXMgYml0cyB3aXRoOgorICAvLyAgIDEuIEJvb2xzICgxIGJ5dGUpCisgIC8vICAgMi4gQW55dGhpbmcgYWx3YXlzIDQgYnl0ZXMgLSBmbG9hdCwgKjMyLCBlbnVtcworICAvLyAgIDMuIEFueXRoaW5nIHRoYXQgaXMgYWx3YXlzIGEgcG9pbnRlciAodGhleSB3aWxsIGJlIDggYnl0ZXMgb24gNjQgYml0CisgIC8vICAgICAgYnVpbGRzIGFuZCA0IGJ5dGVzIG9uIDMyYml0IGJ1aWxkcy4KKyAgLy8gICA0LiBBbnl0aGluZyBhbHdheXMgOCBieXRlcyAtIGRvdWJsZSwgKjY0CisgIC8vCisgIC8vIFdoeT8gVXNpbmcgNjRiaXQgYnVpbGRzIGFzIGFuIGV4YW1wbGUsIHRoaXMgbWVhbnMgd29yc2UgY2FzZSwgd2UgaGF2ZQorICAvLyBlbm91Z2ggYm9vbHMgdGhhdCB3ZSBvdmVyZmxvdyAxIGJ5dGUgZnJvbSA0IGJ5dGUgYWxpZ25tZW50LCBzbyAzIGJ5dGVzCisgIC8vIGFyZSB3YXN0ZWQgYmVmb3JlIHRoZSA0IGJ5dGUgdmFsdWVzLiBUaGVuIGlmIHdlIGhhdmUgYW4gb2RkIG51bWJlciBvZgorICAvLyB0aG9zZSA0IGJ5dGUgdmFsdWVzLCB0aGUgOCBieXRlIHZhbHVlcyB3aWxsIGJlIHB1c2hlZCBkb3duIGJ5IDMyYml0cyB0bworICAvLyBrZWVwIHRoZW0gYWxpZ25lZC4gQnV0IHRoZSBzdHJ1Y3R1cmUgd2lsbCBlbmQgOCBieXRlIGFsaWduZWQsIHNvIG5vCisgIC8vIHdhc3RlIG9uIHRoZSBlbmQuIElmIHlvdSBkaWQgdGhlIHJldmVyc2Ugb3JkZXIsIHlvdSBjb3VsZCB3YXN0ZSA0IGJ5dGVzCisgIC8vIGJlZm9yZSB0aGUgZmlyc3QgOCBieXRlIHZhbHVlIChhZnRlciB0aGUgaGFzIGFycmF5KSwgdGhlbiBhIHNpbmdsZQorICAvLyBib29sIG9uIHRoZSBlbmQgd291bGQgbmVlZCA3IGJ5dGVzIG9mIHBhZGRpbmcgdG8gbWFrZSB0aGUgb3ZlcmFsbAorICAvLyBzdHJ1Y3R1cmUgOCBieXRlIGFsaWduZWQ7IHNvIDExIGJ5dGVzLCB3YXN0ZWQgdG90YWwuCisKKyAgLy8gQW55dGhpbmcgcmVwZWF0ZWQgaXMgYSBHUEIqQXJyYXkvTlNBcnJheSwgc28gcG9pbnRlci4KKyAgaWYgKGRlc2NyaXB0b3ItPmlzX3JlcGVhdGVkKCkpIHsKKyAgICByZXR1cm4gMzsKKyAgfQorCisgIHN3aXRjaCAoZGVzY3JpcHRvci0+dHlwZSgpKSB7CisgICAgLy8gQWxsIGFsd2F5cyA4IGJ5dGVzLgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0RPVUJMRToKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9JTlQ2NDoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TSU5UNjQ6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfVUlOVDY0OgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NGSVhFRDY0OgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0ZJWEVENjQ6CisgICAgICByZXR1cm4gNDsKKworICAgIC8vIFBvaW50ZXJzIChzdHJpbmcgYW5kIGJ5dGVzIGFyZSBOU1N0cmluZyBhbmQgTlNEYXRhKTsgOCBvciA0IGJ5dGVzCisgICAgLy8gZGVwZW5kaW5nIG9uIHRoZSBidWlsZCBhcmNoaXRlY3R1cmUuCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfR1JPVVA6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfTUVTU0FHRToKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TVFJJTkc6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfQllURVM6CisgICAgICByZXR1cm4gMzsKKworICAgIC8vIEFsbCBhbHdheXMgNCBieXRlcyAoZW51bXMgYXJlIGludDMycykuCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRkxPQVQ6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfSU5UMzI6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0lOVDMyOgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1VJTlQzMjoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TRklYRUQzMjoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9GSVhFRDMyOgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0VOVU06CisgICAgICByZXR1cm4gMjsKKworICAgIC8vIDEgYnl0ZS4KKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9CT09MOgorICAgICAgcmV0dXJuIDE7CisgIH0KKworICAvLyBTb21lIGNvbXBpbGVycyByZXBvcnQgcmVhY2hpbmcgZW5kIG9mIGZ1bmN0aW9uIGV2ZW4gdGhvdWdoIGFsbCBjYXNlcyBvZgorICAvLyB0aGUgZW51bSBhcmUgaGFuZGVkIGluIHRoZSBzd2l0Y2guCisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJDYW4ndCBnZXQgaGVyZS4iOworICByZXR1cm4gMDsKK30KKworc3RydWN0IEZpZWxkT3JkZXJpbmdCeVN0b3JhZ2VTaXplIHsKKyAgaW5saW5lIGJvb2wgb3BlcmF0b3IoKShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBiKSBjb25zdCB7CisgICAgLy8gT3JkZXIgYnkgZ3JvdXBpbmcuCisgICAgY29uc3QgaW50IG9yZGVyX2dyb3VwX2EgPSBPcmRlckdyb3VwRm9yRmllbGREZXNjcmlwdG9yKGEpOworICAgIGNvbnN0IGludCBvcmRlcl9ncm91cF9iID0gT3JkZXJHcm91cEZvckZpZWxkRGVzY3JpcHRvcihiKTsKKyAgICBpZiAob3JkZXJfZ3JvdXBfYSAhPSBvcmRlcl9ncm91cF9iKSB7CisgICAgICByZXR1cm4gb3JkZXJfZ3JvdXBfYSA8IG9yZGVyX2dyb3VwX2I7CisgICAgfQorICAgIC8vIFdpdGhpbiB0aGUgZ3JvdXAsIG9yZGVyIGJ5IGZpZWxkIG51bWJlciAocHJvdmlkZXMgc3RhYmxlIG9yZGVyaW5nKS4KKyAgICByZXR1cm4gYS0+bnVtYmVyKCkgPCBiLT5udW1iZXIoKTsKKyAgfQorfTsKKworc3RydWN0IEV4dGVuc2lvblJhbmdlT3JkZXJpbmcgeworICBib29sIG9wZXJhdG9yKCkoY29uc3QgRGVzY3JpcHRvcjo6RXh0ZW5zaW9uUmFuZ2UqIGEsCisgICAgICAgICAgICAgICAgICBjb25zdCBEZXNjcmlwdG9yOjpFeHRlbnNpb25SYW5nZSogYikgY29uc3QgeworICAgIHJldHVybiBhLT5zdGFydCA8IGItPnN0YXJ0OworICB9Cit9OworCisvLyBTb3J0IHRoZSBmaWVsZHMgb2YgdGhlIGdpdmVuIERlc2NyaXB0b3IgYnkgbnVtYmVyIGludG8gYSBuZXdbXSdkIGFycmF5CisvLyBhbmQgcmV0dXJuIGl0LgorY29uc3QgRmllbGREZXNjcmlwdG9yKiogU29ydEZpZWxkc0J5TnVtYmVyKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiogZmllbGRzID0KKyAgICAgIG5ldyBjb25zdCBGaWVsZERlc2NyaXB0b3IqIFtkZXNjcmlwdG9yLT5maWVsZF9jb3VudCgpXTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBmaWVsZHNbaV0gPSBkZXNjcmlwdG9yLT5maWVsZChpKTsKKyAgfQorICBzb3J0KGZpZWxkcywgZmllbGRzICsgZGVzY3JpcHRvci0+ZmllbGRfY291bnQoKSwgRmllbGRPcmRlcmluZ0J5TnVtYmVyKCkpOworICByZXR1cm4gZmllbGRzOworfQorCisvLyBTb3J0IHRoZSBmaWVsZHMgb2YgdGhlIGdpdmVuIERlc2NyaXB0b3IgYnkgc3RvcmFnZSBzaXplIGludG8gYSBuZXdbXSdkCisvLyBhcnJheSBhbmQgcmV0dXJuIGl0LgorY29uc3QgRmllbGREZXNjcmlwdG9yKiogU29ydEZpZWxkc0J5U3RvcmFnZVNpemUoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqKiBmaWVsZHMgPQorICAgICAgbmV3IGNvbnN0IEZpZWxkRGVzY3JpcHRvciogW2Rlc2NyaXB0b3ItPmZpZWxkX2NvdW50KCldOworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3ItPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGZpZWxkc1tpXSA9IGRlc2NyaXB0b3ItPmZpZWxkKGkpOworICB9CisgIHNvcnQoZmllbGRzLCBmaWVsZHMgKyBkZXNjcmlwdG9yLT5maWVsZF9jb3VudCgpLAorICAgICAgIEZpZWxkT3JkZXJpbmdCeVN0b3JhZ2VTaXplKCkpOworICByZXR1cm4gZmllbGRzOworfQorfSAgLy8gbmFtZXNwYWNlCisKK01lc3NhZ2VHZW5lcmF0b3I6Ok1lc3NhZ2VHZW5lcmF0b3IoY29uc3Qgc3RyaW5nJiByb290X2NsYXNzbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcikKKyAgICA6IHJvb3RfY2xhc3NuYW1lXyhyb290X2NsYXNzbmFtZSksCisgICAgICBkZXNjcmlwdG9yXyhkZXNjcmlwdG9yKSwKKyAgICAgIGZpZWxkX2dlbmVyYXRvcnNfKGRlc2NyaXB0b3IpLAorICAgICAgY2xhc3NfbmFtZV8oQ2xhc3NOYW1lKGRlc2NyaXB0b3JfKSkgeworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5leHRlbnNpb25fY291bnQoKTsgaSsrKSB7CisgICAgZXh0ZW5zaW9uX2dlbmVyYXRvcnNfLnB1c2hfYmFjaygKKyAgICAgICAgbmV3IEV4dGVuc2lvbkdlbmVyYXRvcihjbGFzc19uYW1lXywgZGVzY3JpcHRvcl8tPmV4dGVuc2lvbihpKSkpOworICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbF9jb3VudCgpOyBpKyspIHsKKyAgICBPbmVvZkdlbmVyYXRvciogZ2VuZXJhdG9yID0gbmV3IE9uZW9mR2VuZXJhdG9yKGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpKTsKKyAgICBvbmVvZl9nZW5lcmF0b3JzXy5wdXNoX2JhY2soZ2VuZXJhdG9yKTsKKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmVudW1fdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBFbnVtR2VuZXJhdG9yKiBnZW5lcmF0b3IgPSBuZXcgRW51bUdlbmVyYXRvcihkZXNjcmlwdG9yXy0+ZW51bV90eXBlKGkpKTsKKyAgICBlbnVtX2dlbmVyYXRvcnNfLnB1c2hfYmFjayhnZW5lcmF0b3IpOworICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+bmVzdGVkX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgTWVzc2FnZUdlbmVyYXRvciogZ2VuZXJhdG9yID0KKyAgICAgICAgbmV3IE1lc3NhZ2VHZW5lcmF0b3Iocm9vdF9jbGFzc25hbWVfLCBkZXNjcmlwdG9yXy0+bmVzdGVkX3R5cGUoaSkpOworICAgIG5lc3RlZF9tZXNzYWdlX2dlbmVyYXRvcnNfLnB1c2hfYmFjayhnZW5lcmF0b3IpOworICB9Cit9CisKK01lc3NhZ2VHZW5lcmF0b3I6On5NZXNzYWdlR2VuZXJhdG9yKCkgeworICBTVExEZWxldGVDb250YWluZXJQb2ludGVycyhleHRlbnNpb25fZ2VuZXJhdG9yc18uYmVnaW4oKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uX2dlbmVyYXRvcnNfLmVuZCgpKTsKKyAgU1RMRGVsZXRlQ29udGFpbmVyUG9pbnRlcnMoZW51bV9nZW5lcmF0b3JzXy5iZWdpbigpLCBlbnVtX2dlbmVyYXRvcnNfLmVuZCgpKTsKKyAgU1RMRGVsZXRlQ29udGFpbmVyUG9pbnRlcnMobmVzdGVkX21lc3NhZ2VfZ2VuZXJhdG9yc18uYmVnaW4oKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmVzdGVkX21lc3NhZ2VfZ2VuZXJhdG9yc18uZW5kKCkpOworICBTVExEZWxldGVDb250YWluZXJQb2ludGVycyhvbmVvZl9nZW5lcmF0b3JzXy5iZWdpbigpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbmVvZl9nZW5lcmF0b3JzXy5lbmQoKSk7Cit9CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6R2VuZXJhdGVTdGF0aWNWYXJpYWJsZXNJbml0aWFsaXphdGlvbigKKyAgICBpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBmb3IgKHZlY3RvcjxFeHRlbnNpb25HZW5lcmF0b3IqPjo6aXRlcmF0b3IgaXRlciA9CisgICAgICAgICAgIGV4dGVuc2lvbl9nZW5lcmF0b3JzXy5iZWdpbigpOworICAgICAgIGl0ZXIgIT0gZXh0ZW5zaW9uX2dlbmVyYXRvcnNfLmVuZCgpOyArK2l0ZXIpIHsKKyAgICAoKml0ZXIpLT5HZW5lcmF0ZVN0YXRpY1ZhcmlhYmxlc0luaXRpYWxpemF0aW9uKHByaW50ZXIpOworICB9CisKKyAgZm9yICh2ZWN0b3I8TWVzc2FnZUdlbmVyYXRvcio+OjppdGVyYXRvciBpdGVyID0KKyAgICAgICAgICAgbmVzdGVkX21lc3NhZ2VfZ2VuZXJhdG9yc18uYmVnaW4oKTsKKyAgICAgICBpdGVyICE9IG5lc3RlZF9tZXNzYWdlX2dlbmVyYXRvcnNfLmVuZCgpOyArK2l0ZXIpIHsKKyAgICAoKml0ZXIpLT5HZW5lcmF0ZVN0YXRpY1ZhcmlhYmxlc0luaXRpYWxpemF0aW9uKHByaW50ZXIpOworICB9Cit9CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6RGV0ZXJtaW5lRm9yd2FyZERlY2xhcmF0aW9ucyhzZXQ8c3RyaW5nPiogZndkX2RlY2xzKSB7CisgIGlmICghSXNNYXBFbnRyeU1lc3NhZ2UoZGVzY3JpcHRvcl8pKSB7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkRGVzY3JpcHRvciA9IGRlc2NyaXB0b3JfLT5maWVsZChpKTsKKyAgICAgIC8vIElmIGl0IGlzIGEgdGhlIGZpZWxkIGlzIHJlcGVhdGVkLCB0aGUgdHlwZSB3aWxsIGJlIGFuZCAqQXJyYXksIGFuZCB3ZQorICAgICAgLy8gZG9uJ3QgbmVlZCBhbnkgZm9yd2FyZCBkZWNsLgorICAgICAgaWYgKGZpZWxkRGVzY3JpcHRvci0+aXNfcmVwZWF0ZWQoKSkgeworICAgICAgICBjb250aW51ZTsKKyAgICAgIH0KKyAgICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChmaWVsZERlc2NyaXB0b3IpCisgICAgICAgICAgLkRldGVybWluZUZvcndhcmREZWNsYXJhdGlvbnMoZndkX2RlY2xzKTsKKyAgICB9CisgIH0KKworICBmb3IgKHZlY3RvcjxNZXNzYWdlR2VuZXJhdG9yKj46Oml0ZXJhdG9yIGl0ZXIgPQorICAgICAgICAgICBuZXN0ZWRfbWVzc2FnZV9nZW5lcmF0b3JzXy5iZWdpbigpOworICAgICAgIGl0ZXIgIT0gbmVzdGVkX21lc3NhZ2VfZ2VuZXJhdG9yc18uZW5kKCk7ICsraXRlcikgeworICAgICgqaXRlciktPkRldGVybWluZUZvcndhcmREZWNsYXJhdGlvbnMoZndkX2RlY2xzKTsKKyAgfQorfQorCit2b2lkIE1lc3NhZ2VHZW5lcmF0b3I6OkdlbmVyYXRlRW51bUhlYWRlcihpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBmb3IgKHZlY3RvcjxFbnVtR2VuZXJhdG9yKj46Oml0ZXJhdG9yIGl0ZXIgPSBlbnVtX2dlbmVyYXRvcnNfLmJlZ2luKCk7CisgICAgICAgaXRlciAhPSBlbnVtX2dlbmVyYXRvcnNfLmVuZCgpOyArK2l0ZXIpIHsKKyAgICAoKml0ZXIpLT5HZW5lcmF0ZUhlYWRlcihwcmludGVyKTsKKyAgfQorCisgIGZvciAodmVjdG9yPE1lc3NhZ2VHZW5lcmF0b3IqPjo6aXRlcmF0b3IgaXRlciA9CisgICAgICAgICAgIG5lc3RlZF9tZXNzYWdlX2dlbmVyYXRvcnNfLmJlZ2luKCk7CisgICAgICAgaXRlciAhPSBuZXN0ZWRfbWVzc2FnZV9nZW5lcmF0b3JzXy5lbmQoKTsgKytpdGVyKSB7CisgICAgKCppdGVyKS0+R2VuZXJhdGVFbnVtSGVhZGVyKHByaW50ZXIpOworICB9Cit9CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6R2VuZXJhdGVFeHRlbnNpb25SZWdpc3RyYXRpb25Tb3VyY2UoCisgICAgaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgZm9yICh2ZWN0b3I8RXh0ZW5zaW9uR2VuZXJhdG9yKj46Oml0ZXJhdG9yIGl0ZXIgPQorICAgICAgICAgICBleHRlbnNpb25fZ2VuZXJhdG9yc18uYmVnaW4oKTsKKyAgICAgICBpdGVyICE9IGV4dGVuc2lvbl9nZW5lcmF0b3JzXy5lbmQoKTsgKytpdGVyKSB7CisgICAgKCppdGVyKS0+R2VuZXJhdGVSZWdpc3RyYXRpb25Tb3VyY2UocHJpbnRlcik7CisgIH0KKworICBmb3IgKHZlY3RvcjxNZXNzYWdlR2VuZXJhdG9yKj46Oml0ZXJhdG9yIGl0ZXIgPQorICAgICAgICAgICBuZXN0ZWRfbWVzc2FnZV9nZW5lcmF0b3JzXy5iZWdpbigpOworICAgICAgIGl0ZXIgIT0gbmVzdGVkX21lc3NhZ2VfZ2VuZXJhdG9yc18uZW5kKCk7ICsraXRlcikgeworICAgICgqaXRlciktPkdlbmVyYXRlRXh0ZW5zaW9uUmVnaXN0cmF0aW9uU291cmNlKHByaW50ZXIpOworICB9Cit9CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6R2VuZXJhdGVNZXNzYWdlSGVhZGVyKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIC8vIFRoaXMgYSBhIG1hcCBlbnRyeSBtZXNzYWdlLCBqdXN0IHJlY3Vyc2UgYW5kIGRvIG5vdGhpbmcgZGlyZWN0bHkuCisgIGlmIChJc01hcEVudHJ5TWVzc2FnZShkZXNjcmlwdG9yXykpIHsKKyAgICBmb3IgKHZlY3RvcjxNZXNzYWdlR2VuZXJhdG9yKj46Oml0ZXJhdG9yIGl0ZXIgPQorICAgICAgICAgICAgIG5lc3RlZF9tZXNzYWdlX2dlbmVyYXRvcnNfLmJlZ2luKCk7CisgICAgICAgICBpdGVyICE9IG5lc3RlZF9tZXNzYWdlX2dlbmVyYXRvcnNfLmVuZCgpOyArK2l0ZXIpIHsKKyAgICAgICgqaXRlciktPkdlbmVyYXRlTWVzc2FnZUhlYWRlcihwcmludGVyKTsKKyAgICB9CisgICAgcmV0dXJuOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiI3ByYWdtYSBtYXJrIC0gJGNsYXNzbmFtZSRcbiIKKyAgICAgICJcbiIsCisgICAgICAiY2xhc3NuYW1lIiwgY2xhc3NfbmFtZV8pOworCisgIGlmIChkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKSkgeworICAgIHNjb3BlZF9hcnJheTxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBzb3J0ZWRfZmllbGRzKAorICAgICAgICBTb3J0RmllbGRzQnlOdW1iZXIoZGVzY3JpcHRvcl8pKTsKKworICAgIHByaW50ZXItPlByaW50KCJ0eXBlZGVmIEdQQl9FTlVNKCRjbGFzc25hbWUkX0ZpZWxkTnVtYmVyKSB7XG4iLAorICAgICAgICAgICAgICAgICAgICJjbGFzc25hbWUiLCBjbGFzc19uYW1lXyk7CisgICAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChzb3J0ZWRfZmllbGRzW2ldKQorICAgICAgICAgIC5HZW5lcmF0ZUZpZWxkTnVtYmVyQ29uc3RhbnQocHJpbnRlcik7CisgICAgfQorCisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworICAgIHByaW50ZXItPlByaW50KCJ9O1xuXG4iKTsKKyAgfQorCisgIGZvciAodmVjdG9yPE9uZW9mR2VuZXJhdG9yKj46Oml0ZXJhdG9yIGl0ZXIgPSBvbmVvZl9nZW5lcmF0b3JzXy5iZWdpbigpOworICAgICAgIGl0ZXIgIT0gb25lb2ZfZ2VuZXJhdG9yc18uZW5kKCk7ICsraXRlcikgeworICAgICgqaXRlciktPkdlbmVyYXRlQ2FzZUVudW0ocHJpbnRlcik7CisgIH0KKworICBzdHJpbmcgbWVzc2FnZV9jb21tZW50czsKKyAgU291cmNlTG9jYXRpb24gbG9jYXRpb247CisgIGlmIChkZXNjcmlwdG9yXy0+R2V0U291cmNlTG9jYXRpb24oJmxvY2F0aW9uKSkgeworICAgIG1lc3NhZ2VfY29tbWVudHMgPSBCdWlsZENvbW1lbnRzU3RyaW5nKGxvY2F0aW9uKTsKKyAgfSBlbHNlIHsKKyAgICBtZXNzYWdlX2NvbW1lbnRzID0gIiI7CisgIH0KKworICBwcmludGVyLT5QcmludCgKKyAgICAgICIkY29tbWVudHMkQGludGVyZmFjZSAkY2xhc3NuYW1lJCA6IEdQQk1lc3NhZ2VcblxuIiwKKyAgICAgICJjbGFzc25hbWUiLCBjbGFzc19uYW1lXywKKyAgICAgICJjb21tZW50cyIsIG1lc3NhZ2VfY29tbWVudHMpOworCisgIHZlY3RvcjxjaGFyPiBzZWVuX29uZW9mcyhkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbF9jb3VudCgpLCAwKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3JfLT5maWVsZChpKTsKKyAgICBpZiAoZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSAhPSBOVUxMKSB7CisgICAgICBjb25zdCBpbnQgb25lb2ZfaW5kZXggPSBmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpLT5pbmRleCgpOworICAgICAgaWYgKCFzZWVuX29uZW9mc1tvbmVvZl9pbmRleF0pIHsKKyAgICAgICAgc2Vlbl9vbmVvZnNbb25lb2ZfaW5kZXhdID0gMTsKKyAgICAgICAgb25lb2ZfZ2VuZXJhdG9yc19bb25lb2ZfaW5kZXhdLT5HZW5lcmF0ZVB1YmxpY0Nhc2VQcm9wZXJ0eURlY2xhcmF0aW9uKAorICAgICAgICAgICAgcHJpbnRlcik7CisgICAgICB9CisgICAgfQorICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChmaWVsZCkuR2VuZXJhdGVQcm9wZXJ0eURlY2xhcmF0aW9uKHByaW50ZXIpOworICB9CisKKyAgcHJpbnRlci0+UHJpbnQoIkBlbmRcblxuIik7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGRlc2NyaXB0b3JfLT5maWVsZChpKSkKKyAgICAgICAgLkdlbmVyYXRlQ0Z1bmN0aW9uRGVjbGFyYXRpb25zKHByaW50ZXIpOworICB9CisKKyAgaWYgKCFvbmVvZl9nZW5lcmF0b3JzXy5lbXB0eSgpKSB7CisgICAgZm9yICh2ZWN0b3I8T25lb2ZHZW5lcmF0b3IqPjo6aXRlcmF0b3IgaXRlciA9IG9uZW9mX2dlbmVyYXRvcnNfLmJlZ2luKCk7CisgICAgICAgICBpdGVyICE9IG9uZW9mX2dlbmVyYXRvcnNfLmVuZCgpOyArK2l0ZXIpIHsKKyAgICAgICgqaXRlciktPkdlbmVyYXRlQ2xlYXJGdW5jdGlvbkRlY2xhcmF0aW9uKHByaW50ZXIpOworICAgIH0KKyAgICBwcmludGVyLT5QcmludCgiXG4iKTsKKyAgfQorCisgIGlmIChkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX2NvdW50KCkgPiAwKSB7CisgICAgcHJpbnRlci0+UHJpbnQoIkBpbnRlcmZhY2UgJGNsYXNzbmFtZSQgKER5bmFtaWNNZXRob2RzKVxuXG4iLAorICAgICAgICAgICAgICAgICAgICJjbGFzc25hbWUiLCBjbGFzc19uYW1lXyk7CisgICAgZm9yICh2ZWN0b3I8RXh0ZW5zaW9uR2VuZXJhdG9yKj46Oml0ZXJhdG9yIGl0ZXIgPQorICAgICAgICAgICAgIGV4dGVuc2lvbl9nZW5lcmF0b3JzXy5iZWdpbigpOworICAgICAgICAgaXRlciAhPSBleHRlbnNpb25fZ2VuZXJhdG9yc18uZW5kKCk7ICsraXRlcikgeworICAgICAgKCppdGVyKS0+R2VuZXJhdGVNZW1iZXJzSGVhZGVyKHByaW50ZXIpOworICAgIH0KKyAgICBwcmludGVyLT5QcmludCgiQGVuZFxuXG4iKTsKKyAgfQorCisgIGZvciAodmVjdG9yPE1lc3NhZ2VHZW5lcmF0b3IqPjo6aXRlcmF0b3IgaXRlciA9CisgICAgICAgICAgIG5lc3RlZF9tZXNzYWdlX2dlbmVyYXRvcnNfLmJlZ2luKCk7CisgICAgICAgaXRlciAhPSBuZXN0ZWRfbWVzc2FnZV9nZW5lcmF0b3JzXy5lbmQoKTsgKytpdGVyKSB7CisgICAgKCppdGVyKS0+R2VuZXJhdGVNZXNzYWdlSGVhZGVyKHByaW50ZXIpOworICB9Cit9CisKK3ZvaWQgTWVzc2FnZUdlbmVyYXRvcjo6R2VuZXJhdGVTb3VyY2UoaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgaWYgKCFJc01hcEVudHJ5TWVzc2FnZShkZXNjcmlwdG9yXykpIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIiNwcmFnbWEgbWFyayAtICRjbGFzc25hbWUkXG4iCisgICAgICAgICJcbiIsCisgICAgICAgICJjbGFzc25hbWUiLCBjbGFzc19uYW1lXyk7CisKKyAgICBwcmludGVyLT5QcmludCgiQGltcGxlbWVudGF0aW9uICRjbGFzc25hbWUkXG5cbiIsCisgICAgICAgICAgICAgICAgICAgImNsYXNzbmFtZSIsIGNsYXNzX25hbWVfKTsKKworICAgIGZvciAodmVjdG9yPE9uZW9mR2VuZXJhdG9yKj46Oml0ZXJhdG9yIGl0ZXIgPSBvbmVvZl9nZW5lcmF0b3JzXy5iZWdpbigpOworICAgICAgICAgaXRlciAhPSBvbmVvZl9nZW5lcmF0b3JzXy5lbmQoKTsgKytpdGVyKSB7CisgICAgICAoKml0ZXIpLT5HZW5lcmF0ZVByb3BlcnR5SW1wbGVtZW50YXRpb24ocHJpbnRlcik7CisgICAgfQorCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoZGVzY3JpcHRvcl8tPmZpZWxkKGkpKQorICAgICAgICAgIC5HZW5lcmF0ZVByb3BlcnR5SW1wbGVtZW50YXRpb24ocHJpbnRlcik7CisgICAgfQorCisgICAgc2NvcGVkX2FycmF5PGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+IHNvcnRlZF9maWVsZHMoCisgICAgICAgIFNvcnRGaWVsZHNCeU51bWJlcihkZXNjcmlwdG9yXykpOworICAgIHNjb3BlZF9hcnJheTxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBzaXplX29yZGVyX2ZpZWxkcygKKyAgICAgICAgU29ydEZpZWxkc0J5U3RvcmFnZVNpemUoZGVzY3JpcHRvcl8pKTsKKworICAgIHZlY3Rvcjxjb25zdCBEZXNjcmlwdG9yOjpFeHRlbnNpb25SYW5nZSo+IHNvcnRlZF9leHRlbnNpb25zOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmV4dGVuc2lvbl9yYW5nZV9jb3VudCgpOyArK2kpIHsKKyAgICAgIHNvcnRlZF9leHRlbnNpb25zLnB1c2hfYmFjayhkZXNjcmlwdG9yXy0+ZXh0ZW5zaW9uX3JhbmdlKGkpKTsKKyAgICB9CisKKyAgICBzb3J0KHNvcnRlZF9leHRlbnNpb25zLmJlZ2luKCksIHNvcnRlZF9leHRlbnNpb25zLmVuZCgpLAorICAgICAgICAgRXh0ZW5zaW9uUmFuZ2VPcmRlcmluZygpKTsKKworICAgIC8vIFRPRE8odGhvbWFzdmwpOiBGaW5pc2ggb3B0aW1pemluZyBoYXMgYml0LiBUaGUgY3VycmVudCBiZWhhdmlvciBpcyBhcworICAgIC8vIGZvbGxvd3M6CisgICAgLy8gMS4gb2JqZWN0aXZlY19maWVsZC5jYydzIFNldENvbW1vbkZpZWxkVmFyaWFibGVzKCkgZGVmYXVsdHMgdGhlIGhhc19pbmRleAorICAgIC8vICAgIHRvIHRoZSBmaWVsZCdzIGluZGV4IGluIHRoZSBsaXN0IG9mIGZpZWxkcy4KKyAgICAvLyAyLiBSZXBlYXRlZEZpZWxkR2VuZXJhdG9yOjpSZXBlYXRlZEZpZWxkR2VuZXJhdG9yKCkgc2V0cyBoYXNfaW5kZXggdG8KKyAgICAvLyAgICBHUEJOb0hhc0JpdCBiZWNhdXNlIHJlcGVhdGVkIGZpZWxkcyAmIG1hcDw+IGZpZWxkcyBkb24ndCB1c2UgdGhlIGhhcworICAgIC8vICAgIGJpdC4KKyAgICAvLyAzLiBGaWVsZEdlbmVyYXRvcjo6U2V0T25lb2ZJbmRleEJhc2UoKSBvdmVycmlkZXMgaGFzX2JpdCB3aXRoIGEgbmVnYXRpdmUKKyAgICAvLyAgICBpbmRleCB0aGF0IGdyb3VwcyBhbGwgdGhlIGVsZW1lbnRzIG9uIG9mIHRoZSBvbmVvZi4KKyAgICAvLyBTbyBpbiBoYXNfc3RvcmFnZSwgd2UgbmVlZCBlbm91Z2ggYml0cyBmb3IgdGhlIHNpbmdsZSBmaWVsZHMgdGhhdCBhcmVuJ3QKKyAgICAvLyBpbiBhbnkgb25lb2YsIGFuZCB0aGVuIG9uZSBpbnQzMiBmb3IgZWFjaCBvbmVvZiAodG8gc3RvcmUgdGhlIGZpZWxkCisgICAgLy8gbnVtYmVyKS4gIFNvIHdlIGNvdWxkIHNhdmUgYSBsaXR0bGUgc3BhY2UgYnkgbm90IHVzaW5nIHRoZSBmaWVsZCdzIGluZGV4CisgICAgLy8gYW5kIGluc3RlYWQgbWFrZSBhIHNlY29uZCBwYXNzIG9ubHkgYXNzaWduaW5nIGluZGV4ZXMgZm9yIHRoZSBmaWVsZHMKKyAgICAvLyB0aGF0IHdvdWxkIG5lZWQgaXQuICBUaGUgb25seSBzYXZpbmdzIHdvdWxkIGNvbWUgd2hlbiBtZXNzYWdlcyBoYXZlIG92ZXIKKyAgICAvLyBhIG11bHRpcGxlIG9mIDMyIGZpZWxkcyB3aXRoIHNvbWUgbnVtYmVyIGJlaW5nIHJlcGVhdGVkIG9yIGluIG9uZW9mcyB0bworICAgIC8vIGRyb3AgdGhlIGNvdW50IGJlbG93IHRoYXQgMzIgbXVsdGlwbGU7IHNvIGl0IGhhc24ndCBzZWVtZWQgd29ydGggZG9pbmcKKyAgICAvLyBhdCB0aGUgbW9tZW50LgorICAgIHNpemVfdCBudW1faGFzX2JpdHMgPSBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsKKyAgICBzaXplX3Qgc2l6ZW9mX2hhc19zdG9yYWdlID0gKG51bV9oYXNfYml0cyArIDMxKSAvIDMyOworICAgIC8vIFRlbGwgYWxsIHRoZSBmaWVsZHMgdGhlIG9uZW9mIGJhc2UuCisgICAgZm9yICh2ZWN0b3I8T25lb2ZHZW5lcmF0b3IqPjo6aXRlcmF0b3IgaXRlciA9IG9uZW9mX2dlbmVyYXRvcnNfLmJlZ2luKCk7CisgICAgICAgICBpdGVyICE9IG9uZW9mX2dlbmVyYXRvcnNfLmVuZCgpOyArK2l0ZXIpIHsKKyAgICAgICgqaXRlciktPlNldE9uZW9mSW5kZXhCYXNlKHNpemVvZl9oYXNfc3RvcmFnZSk7CisgICAgfQorICAgIGZpZWxkX2dlbmVyYXRvcnNfLlNldE9uZW9mSW5kZXhCYXNlKHNpemVvZl9oYXNfc3RvcmFnZSk7CisgICAgLy8gQWRkIGFuIGludDMyIGZvciBlYWNoIG9uZW9mIHRvIHN0b3JlIHdoaWNoIGlzIHNldC4KKyAgICBzaXplb2ZfaGFzX3N0b3JhZ2UgKz0gZGVzY3JpcHRvcl8tPm9uZW9mX2RlY2xfY291bnQoKTsKKworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiXG4iCisgICAgICAgICJ0eXBlZGVmIHN0cnVjdCAkY2xhc3NuYW1lJF9fc3RvcmFnZV8ge1xuIgorICAgICAgICAiICB1aW50MzJfdCBfaGFzX3N0b3JhZ2VfWyRzaXplb2ZfaGFzX3N0b3JhZ2UkXTtcbiIsCisgICAgICAgICJjbGFzc25hbWUiLCBjbGFzc19uYW1lXywKKyAgICAgICAgInNpemVvZl9oYXNfc3RvcmFnZSIsIFNpbXBsZUl0b2Eoc2l6ZW9mX2hhc19zdG9yYWdlKSk7CisgICAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICAgIGZpZWxkX2dlbmVyYXRvcnNfLmdldChzaXplX29yZGVyX2ZpZWxkc1tpXSkKKyAgICAgICAgICAuR2VuZXJhdGVGaWVsZFN0b3JhZ2VEZWNsYXJhdGlvbihwcmludGVyKTsKKyAgICB9CisgICAgcHJpbnRlci0+T3V0ZGVudCgpOworCisgICAgcHJpbnRlci0+UHJpbnQoIn0gJGNsYXNzbmFtZSRfX3N0b3JhZ2VfO1xuXG4iLCAiY2xhc3NuYW1lIiwgY2xhc3NfbmFtZV8pOworCisKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIi8vIFRoaXMgbWV0aG9kIGlzIHRocmVhZHNhZmUgYmVjYXVzZSBpdCBpcyBpbml0aWFsbHkgY2FsbGVkXG4iCisgICAgICAgICIvLyBpbiAraW5pdGlhbGl6ZSBmb3IgZWFjaCBzdWJjbGFzcy5cbiIKKyAgICAgICAgIisgKEdQQkRlc2NyaXB0b3IgKilkZXNjcmlwdG9yIHtcbiIKKyAgICAgICAgIiAgc3RhdGljIEdQQkRlc2NyaXB0b3IgKmRlc2NyaXB0b3IgPSBuaWw7XG4iCisgICAgICAgICIgIGlmICghZGVzY3JpcHRvcikge1xuIik7CisKKyAgICBib29sIGhhc19vbmVvZnMgPSBvbmVvZl9nZW5lcmF0b3JzXy5zaXplKCk7CisgICAgaWYgKGhhc19vbmVvZnMpIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICIgICAgc3RhdGljIEdQQk1lc3NhZ2VPbmVvZkRlc2NyaXB0aW9uIG9uZW9mc1tdID0ge1xuIik7CisgICAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICAgIHByaW50ZXItPkluZGVudCgpOworICAgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgICBmb3IgKHZlY3RvcjxPbmVvZkdlbmVyYXRvcio+OjppdGVyYXRvciBpdGVyID0gb25lb2ZfZ2VuZXJhdG9yc18uYmVnaW4oKTsKKyAgICAgICAgICAgaXRlciAhPSBvbmVvZl9nZW5lcmF0b3JzXy5lbmQoKTsgKytpdGVyKSB7CisgICAgICAgICgqaXRlciktPkdlbmVyYXRlRGVzY3JpcHRpb24ocHJpbnRlcik7CisgICAgICB9CisgICAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAiICAgIH07XG4iKTsKKyAgICB9CisKKyAgICBUZXh0Rm9ybWF0RGVjb2RlRGF0YSB0ZXh0X2Zvcm1hdF9kZWNvZGVfZGF0YTsKKyAgICBib29sIGhhc19maWVsZHMgPSBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKSA+IDA7CisgICAgaWYgKGhhc19maWVsZHMpIHsKKyAgICAgIC8vIFRPRE8odGhvbWFzdmwpOiBUaGUgcGx1Z2luJ3MgRmllbGRHZW5lcmF0b3I6OkdlbmVyYXRlRmllbGREZXNjcmlwdGlvbigpCisgICAgICAvLyB3cmFwcyB0aGUgZmllbGRPcHRpb25zJ3MgdmFsdWUgb2YgdGhpcyBzdHJ1Y3R1cmUgaW4gYW4gQ1BQIGdhdGUgc28KKyAgICAgIC8vIHRoZXkgY2FuIGJlIGNvbXBpbGVkIGF3YXk7IGJ1dCB0aGF0IHN0aWxsIHJlc3VsdHMgaW4gYSBjb25zdCBjaGFyKiBpbgorICAgICAgLy8gdGhlIHN0cnVjdHVyZSBmb3IgYSBOVUxMIHBvaW50ZXIgZm9yIGV2ZXJ5IG1lc3NhZ2UgZmllbGQuICBJZiB0aGUKKyAgICAgIC8vIGZpZWxkT3B0aW9ucyBhcmUgbW92ZWQgdG8gYSBzZXBhcmF0ZSBwYXlsb2FkIGxpa2UgdGhlIFRleHRGb3JtYXQgZXh0cmEKKyAgICAgIC8vIGRhdGEgaXMsIHRoZW4gaXQgd291bGQgc2hyaW5rIHRoYXQgc3RhdGljIGRhdGEgc2hyaW5raW5nIHRoZSBiaW5hcmllcworICAgICAgLy8gYSBsaXR0bGUgbW9yZS4KKyAgICAgIC8vIFRPRE8odGhvbWFzdmwpOiBwcm90bzMgc3ludGF4IGRvZW5zJ3QgbmVlZCBhIGRlZmF1bHRWYWx1ZSBpbiB0aGUKKyAgICAgIC8vIHN0cnVjdHVyZSBiZWNhdXNlIHByaW1pdGl2ZSB0eXBlcyBhcmUgYWx3YXlzIHplcm8uICBJZiB3ZSBhZGQgYSBzZWNvbmQKKyAgICAgIC8vIHN0cnVjdHVyZSBhbmQgYSBkaWZmZXJlbnQgaW5pdGlhbGl6ZXIsIHdlIGNhbiBhdm9pZCB0aGUgd2FzdGVkIHN0YXRpYworICAgICAgLy8gc3RvcmFnZSBmb3IgZXZlcnkgZmllbGQgaW4gYSBwcm90bzMgbWVzc2FnZS4KKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICIgICAgc3RhdGljIEdQQk1lc3NhZ2VGaWVsZERlc2NyaXB0aW9uIGZpZWxkc1tdID0ge1xuIik7CisgICAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICAgIHByaW50ZXItPkluZGVudCgpOworICAgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpOyArK2kpIHsKKyAgICAgICAgY29uc3QgRmllbGRHZW5lcmF0b3ImIGZpZWxkX2dlbmVyYXRvciA9CisgICAgICAgICAgICBmaWVsZF9nZW5lcmF0b3JzXy5nZXQoc29ydGVkX2ZpZWxkc1tpXSk7CisgICAgICAgIGZpZWxkX2dlbmVyYXRvci5HZW5lcmF0ZUZpZWxkRGVzY3JpcHRpb24ocHJpbnRlcik7CisgICAgICAgIGlmIChmaWVsZF9nZW5lcmF0b3IubmVlZHNfdGV4dGZvcm1hdF9uYW1lX3N1cHBvcnQoKSkgeworICAgICAgICAgIHRleHRfZm9ybWF0X2RlY29kZV9kYXRhLkFkZFN0cmluZyhzb3J0ZWRfZmllbGRzW2ldLT5udW1iZXIoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGRfZ2VuZXJhdG9yLmdlbmVyYXRlZF9vYmpjX25hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGRfZ2VuZXJhdG9yLnJhd19maWVsZF9uYW1lKCkpOworICAgICAgICB9CisgICAgICB9CisgICAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAiICAgIH07XG4iKTsKKyAgICB9CisKKyAgICBib29sIGhhc19lbnVtcyA9IGVudW1fZ2VuZXJhdG9yc18uc2l6ZSgpOworICAgIGlmIChoYXNfZW51bXMpIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICIgICAgc3RhdGljIEdQQk1lc3NhZ2VFbnVtRGVzY3JpcHRpb24gZW51bXNbXSA9IHtcbiIpOworICAgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICAgIHByaW50ZXItPkluZGVudCgpOworICAgICAgZm9yICh2ZWN0b3I8RW51bUdlbmVyYXRvcio+OjppdGVyYXRvciBpdGVyID0gZW51bV9nZW5lcmF0b3JzXy5iZWdpbigpOworICAgICAgICAgICBpdGVyICE9IGVudW1fZ2VuZXJhdG9yc18uZW5kKCk7ICsraXRlcikgeworICAgICAgICBwcmludGVyLT5QcmludCgieyAuZW51bURlc2NyaXB0b3JGdW5jID0gJG5hbWUkX0VudW1EZXNjcmlwdG9yIH0sXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAibmFtZSIsICgqaXRlciktPm5hbWUoKSk7CisgICAgICB9CisgICAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgICBwcmludGVyLT5PdXRkZW50KCk7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAiICAgIH07XG4iKTsKKyAgICB9CisKKyAgICBib29sIGhhc19leHRlbnNpb25zID0gc29ydGVkX2V4dGVuc2lvbnMuc2l6ZSgpOworICAgIGlmIChoYXNfZXh0ZW5zaW9ucykgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgIiAgICBzdGF0aWMgR1BCRXh0ZW5zaW9uUmFuZ2UgcmFuZ2VzW10gPSB7XG4iKTsKKyAgICAgIHByaW50ZXItPkluZGVudCgpOworICAgICAgcHJpbnRlci0+SW5kZW50KCk7CisgICAgICBwcmludGVyLT5JbmRlbnQoKTsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc29ydGVkX2V4dGVuc2lvbnMuc2l6ZSgpOyBpKyspIHsKKyAgICAgICAgcHJpbnRlci0+UHJpbnQoInsgLnN0YXJ0ID0gJHN0YXJ0JCwgLmVuZCA9ICRlbmQkIH0sXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAic3RhcnQiLCBTaW1wbGVJdG9hKHNvcnRlZF9leHRlbnNpb25zW2ldLT5zdGFydCksCisgICAgICAgICAgICAgICAgICAgICAgICJlbmQiLCBTaW1wbGVJdG9hKHNvcnRlZF9leHRlbnNpb25zW2ldLT5lbmQpKTsKKyAgICAgIH0KKyAgICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAgICIgICAgfTtcbiIpOworICAgIH0KKworICAgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyczsKKyAgICB2YXJzWyJjbGFzc25hbWUiXSA9IGNsYXNzX25hbWVfOworICAgIHZhcnNbInJvb3RjbGFzc25hbWUiXSA9IHJvb3RfY2xhc3NuYW1lXzsKKyAgICB2YXJzWyJmaWVsZHMiXSA9IGhhc19maWVsZHMgPyAiZmllbGRzIiA6ICJOVUxMIjsKKyAgICB2YXJzWyJmaWVsZHNfY291bnQiXSA9CisgICAgICAgIGhhc19maWVsZHMgPyAic2l6ZW9mKGZpZWxkcykgLyBzaXplb2YoR1BCTWVzc2FnZUZpZWxkRGVzY3JpcHRpb24pIiA6ICIwIjsKKyAgICB2YXJzWyJvbmVvZnMiXSA9IGhhc19vbmVvZnMgPyAib25lb2ZzIiA6ICJOVUxMIjsKKyAgICB2YXJzWyJvbmVvZl9jb3VudCJdID0KKyAgICAgICAgaGFzX29uZW9mcyA/ICJzaXplb2Yob25lb2ZzKSAvIHNpemVvZihHUEJNZXNzYWdlT25lb2ZEZXNjcmlwdGlvbikiIDogIjAiOworICAgIHZhcnNbImVudW1zIl0gPSBoYXNfZW51bXMgPyAiZW51bXMiIDogIk5VTEwiOworICAgIHZhcnNbImVudW1fY291bnQiXSA9CisgICAgICAgIGhhc19lbnVtcyA/ICJzaXplb2YoZW51bXMpIC8gc2l6ZW9mKEdQQk1lc3NhZ2VFbnVtRGVzY3JpcHRpb24pIiA6ICIwIjsKKyAgICB2YXJzWyJyYW5nZXMiXSA9IGhhc19leHRlbnNpb25zID8gInJhbmdlcyIgOiAiTlVMTCI7CisgICAgdmFyc1sicmFuZ2VfY291bnQiXSA9CisgICAgICAgIGhhc19leHRlbnNpb25zID8gInNpemVvZihyYW5nZXMpIC8gc2l6ZW9mKEdQQkV4dGVuc2lvblJhbmdlKSIgOiAiMCI7CisgICAgdmFyc1sid2lyZWZvcm1hdCJdID0KKyAgICAgICAgZGVzY3JpcHRvcl8tPm9wdGlvbnMoKS5tZXNzYWdlX3NldF93aXJlX2Zvcm1hdCgpID8gIllFUyIgOiAiTk8iOworCisgICAgaWYgKHRleHRfZm9ybWF0X2RlY29kZV9kYXRhLm51bV9lbnRyaWVzKCkgPT0gMCkgeworICAgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAgICAgdmFycywKKyAgICAgICAgICAiICAgIEdQQkRlc2NyaXB0b3IgKmxvY2FsRGVzY3JpcHRvciA9XG4iCisgICAgICAgICAgIiAgICAgICAgW0dQQkRlc2NyaXB0b3IgYWxsb2NEZXNjcmlwdG9yRm9yQ2xhc3M6WyRjbGFzc25hbWUkIGNsYXNzXVxuIgorICAgICAgICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm9vdENsYXNzOlskcm9vdGNsYXNzbmFtZSQgY2xhc3NdXG4iCisgICAgICAgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGU6JHJvb3RjbGFzc25hbWUkX0ZpbGVEZXNjcmlwdG9yKClcbiIKKyAgICAgICAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkczokZmllbGRzJFxuIgorICAgICAgICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZENvdW50OiRmaWVsZHNfY291bnQkXG4iCisgICAgICAgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbmVvZnM6JG9uZW9mcyRcbiIKKyAgICAgICAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25lb2ZDb3VudDokb25lb2ZfY291bnQkXG4iCisgICAgICAgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW51bXM6JGVudW1zJFxuIgorICAgICAgICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW51bUNvdW50OiRlbnVtX2NvdW50JFxuIgorICAgICAgICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmFuZ2VzOiRyYW5nZXMkXG4iCisgICAgICAgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhbmdlQ291bnQ6JHJhbmdlX2NvdW50JFxuIgorICAgICAgICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0b3JhZ2VTaXplOnNpemVvZigkY2xhc3NuYW1lJF9fc3RvcmFnZV8pXG4iCisgICAgICAgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpcmVGb3JtYXQ6JHdpcmVmb3JtYXQkXTtcbiIpOworICAgIH0gZWxzZSB7CisgICAgICB2YXJzWyJleHRyYVRleHRGb3JtYXRJbmZvIl0gPSBDRXNjYXBlKHRleHRfZm9ybWF0X2RlY29kZV9kYXRhLkRhdGEoKSk7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICB2YXJzLAorICAgICAgICAgICIjaWYgR1BCT0JKQ19TS0lQX01FU1NBR0VfVEVYVEZPUk1BVF9FWFRSQVNcbiIKKyAgICAgICAgICAiICAgIGNvbnN0IGNoYXIgKmV4dHJhVGV4dEZvcm1hdEluZm8gPSBOVUxMO1xuIgorICAgICAgICAgICIjZWxzZVxuIgorICAgICAgICAgICIgICAgc3RhdGljIGNvbnN0IGNoYXIgKmV4dHJhVGV4dEZvcm1hdEluZm8gPSBcIiRleHRyYVRleHRGb3JtYXRJbmZvJFwiO1xuIgorICAgICAgICAgICIjZW5kaWYgIC8vIEdQQk9CSkNfU0tJUF9NRVNTQUdFX1RFWFRGT1JNQVRfRVhUUkFTXG4iCisgICAgICAgICAgIiAgICBHUEJEZXNjcmlwdG9yICpsb2NhbERlc2NyaXB0b3IgPVxuIgorICAgICAgICAgICIgICAgICAgIFtHUEJEZXNjcmlwdG9yIGFsbG9jRGVzY3JpcHRvckZvckNsYXNzOlskY2xhc3NuYW1lJCBjbGFzc11cbiIKKyAgICAgICAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvb3RDbGFzczpbJHJvb3RjbGFzc25hbWUkIGNsYXNzXVxuIgorICAgICAgICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlOiRyb290Y2xhc3NuYW1lJF9GaWxlRGVzY3JpcHRvcigpXG4iCisgICAgICAgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZHM6JGZpZWxkcyRcbiIKKyAgICAgICAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGRDb3VudDokZmllbGRzX2NvdW50JFxuIgorICAgICAgICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25lb2ZzOiRvbmVvZnMkXG4iCisgICAgICAgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uZW9mQ291bnQ6JG9uZW9mX2NvdW50JFxuIgorICAgICAgICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudW1zOiRlbnVtcyRcbiIKKyAgICAgICAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudW1Db3VudDokZW51bV9jb3VudCRcbiIKKyAgICAgICAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhbmdlczokcmFuZ2VzJFxuIgorICAgICAgICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYW5nZUNvdW50OiRyYW5nZV9jb3VudCRcbiIKKyAgICAgICAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdG9yYWdlU2l6ZTpzaXplb2YoJGNsYXNzbmFtZSRfX3N0b3JhZ2VfKVxuIgorICAgICAgICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aXJlRm9ybWF0OiR3aXJlZm9ybWF0JFxuIgorICAgICAgICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRyYVRleHRGb3JtYXRJbmZvOmV4dHJhVGV4dEZvcm1hdEluZm9dO1xuIik7CisgICAgICB9CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgICAiICAgIE5TQXNzZXJ0KGRlc2NyaXB0b3IgPT0gbmlsLCBAXCJTdGFydHVwIHJlY3Vyc2VkIVwiKTtcbiIKKyAgICAgICAgICAiICAgIGRlc2NyaXB0b3IgPSBsb2NhbERlc2NyaXB0b3I7XG4iCisgICAgICAgICAgIiAgfVxuIgorICAgICAgICAgICIgIHJldHVybiBkZXNjcmlwdG9yO1xuIgorICAgICAgICAgICJ9XG5cbiIKKyAgICAgICAgICAiQGVuZFxuXG4iKTsKKworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgICAgZmllbGRfZ2VuZXJhdG9yc18uZ2V0KGRlc2NyaXB0b3JfLT5maWVsZChpKSkKKyAgICAgICAgICAuR2VuZXJhdGVDRnVuY3Rpb25JbXBsZW1lbnRhdGlvbnMocHJpbnRlcik7CisgICAgfQorCisgICAgZm9yICh2ZWN0b3I8T25lb2ZHZW5lcmF0b3IqPjo6aXRlcmF0b3IgaXRlciA9IG9uZW9mX2dlbmVyYXRvcnNfLmJlZ2luKCk7CisgICAgICAgICBpdGVyICE9IG9uZW9mX2dlbmVyYXRvcnNfLmVuZCgpOyArK2l0ZXIpIHsKKyAgICAgICgqaXRlciktPkdlbmVyYXRlQ2xlYXJGdW5jdGlvbkltcGxlbWVudGF0aW9uKHByaW50ZXIpOworICAgIH0KKyAgfQorCisgIGZvciAodmVjdG9yPEVudW1HZW5lcmF0b3IqPjo6aXRlcmF0b3IgaXRlciA9IGVudW1fZ2VuZXJhdG9yc18uYmVnaW4oKTsKKyAgICAgICBpdGVyICE9IGVudW1fZ2VuZXJhdG9yc18uZW5kKCk7ICsraXRlcikgeworICAgICgqaXRlciktPkdlbmVyYXRlU291cmNlKHByaW50ZXIpOworICB9CisKKyAgZm9yICh2ZWN0b3I8TWVzc2FnZUdlbmVyYXRvcio+OjppdGVyYXRvciBpdGVyID0KKyAgICAgICAgICAgbmVzdGVkX21lc3NhZ2VfZ2VuZXJhdG9yc18uYmVnaW4oKTsKKyAgICAgICBpdGVyICE9IG5lc3RlZF9tZXNzYWdlX2dlbmVyYXRvcnNfLmVuZCgpOyArK2l0ZXIpIHsKKyAgICAoKml0ZXIpLT5HZW5lcmF0ZVNvdXJjZShwcmludGVyKTsKKyAgfQorfQorCit9ICAvLyBuYW1lc3BhY2Ugb2JqZWN0aXZlYworfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX21lc3NhZ2UuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX21lc3NhZ2UuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wNmI1MzZmCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfbWVzc2FnZS5oCkBAIC0wLDAgKzEsOTQgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9PQkpFQ1RJVkVDX01FU1NBR0VfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9PQkpFQ1RJVkVDX01FU1NBR0VfSF9fCisKKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8c2V0PgorI2luY2x1ZGUgPHZlY3Rvcj4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19vbmVvZi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCituYW1lc3BhY2UgaW8geworY2xhc3MgUHJpbnRlcjsgIC8vIHByaW50ZXIuaAorfSAgLy8gbmFtZXNwYWNlIGlvCisKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2Ugb2JqZWN0aXZlYyB7CisKK2NsYXNzIEV4dGVuc2lvbkdlbmVyYXRvcjsKK2NsYXNzIEVudW1HZW5lcmF0b3I7CisKK2NsYXNzIE1lc3NhZ2VHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgTWVzc2FnZUdlbmVyYXRvcihjb25zdCBzdHJpbmcmIHJvb3RfY2xhc3NuYW1lLCBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKKyAgfk1lc3NhZ2VHZW5lcmF0b3IoKTsKKworICB2b2lkIEdlbmVyYXRlU3RhdGljVmFyaWFibGVzSW5pdGlhbGl6YXRpb24oaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2b2lkIEdlbmVyYXRlRW51bUhlYWRlcihpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZvaWQgR2VuZXJhdGVNZXNzYWdlSGVhZGVyKGlvOjpQcmludGVyKiBwcmludGVyKTsKKyAgdm9pZCBHZW5lcmF0ZVNvdXJjZShpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZvaWQgR2VuZXJhdGVFeHRlbnNpb25SZWdpc3RyYXRpb25Tb3VyY2UoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2b2lkIERldGVybWluZUZvcndhcmREZWNsYXJhdGlvbnMoc2V0PHN0cmluZz4qIGZ3ZF9kZWNscyk7CisKKyBwcml2YXRlOgorICB2b2lkIEdlbmVyYXRlUGFyc2VGcm9tTWV0aG9kc0hlYWRlcihpbzo6UHJpbnRlciogcHJpbnRlcik7CisKKyAgdm9pZCBHZW5lcmF0ZVNlcmlhbGl6ZU9uZUZpZWxkU291cmNlKGlvOjpQcmludGVyKiBwcmludGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCk7CisgIHZvaWQgR2VuZXJhdGVTZXJpYWxpemVPbmVFeHRlbnNpb25SYW5nZVNvdXJjZSgKKyAgICAgIGlvOjpQcmludGVyKiBwcmludGVyLCBjb25zdCBEZXNjcmlwdG9yOjpFeHRlbnNpb25SYW5nZSogcmFuZ2UpOworCisgIHZvaWQgR2VuZXJhdGVNZXNzYWdlRGVzY3JpcHRpb25Tb3VyY2UoaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2b2lkIEdlbmVyYXRlRGVzY3JpcHRpb25PbmVGaWVsZFNvdXJjZShpbzo6UHJpbnRlciogcHJpbnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCk7CisKKyAgY29uc3Qgc3RyaW5nIHJvb3RfY2xhc3NuYW1lXzsKKyAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcl87CisgIEZpZWxkR2VuZXJhdG9yTWFwIGZpZWxkX2dlbmVyYXRvcnNfOworICBjb25zdCBzdHJpbmcgY2xhc3NfbmFtZV87CisgIHZlY3RvcjxFeHRlbnNpb25HZW5lcmF0b3IqPiBleHRlbnNpb25fZ2VuZXJhdG9yc187CisgIHZlY3RvcjxFbnVtR2VuZXJhdG9yKj4gZW51bV9nZW5lcmF0b3JzXzsKKyAgdmVjdG9yPE1lc3NhZ2VHZW5lcmF0b3IqPiBuZXN0ZWRfbWVzc2FnZV9nZW5lcmF0b3JzXzsKKyAgdmVjdG9yPE9uZW9mR2VuZXJhdG9yKj4gb25lb2ZfZ2VuZXJhdG9yc187CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKE1lc3NhZ2VHZW5lcmF0b3IpOworfTsKK30gIC8vIG5hbWVzcGFjZSBvYmplY3RpdmVjCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfT0JKRUNUSVZFQ19NRVNTQUdFX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfbWVzc2FnZV9maWVsZC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX21lc3NhZ2VfZmllbGQuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjJjZTRlNQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX21lc3NhZ2VfZmllbGQuY2MKQEAgLTAsMCArMSw5NiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8c3RyaW5nPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19tZXNzYWdlX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIG9iamVjdGl2ZWMgeworCituYW1lc3BhY2UgeworCit2b2lkIFNldE1lc3NhZ2VWYXJpYWJsZXMoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgIG1hcDxzdHJpbmcsIHN0cmluZz4qIHZhcmlhYmxlcykgeworICBjb25zdCBzdHJpbmcmIG1lc3NhZ2VfdHlwZSA9IENsYXNzTmFtZShkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKSk7CisgICgqdmFyaWFibGVzKVsidHlwZSJdID0gbWVzc2FnZV90eXBlOworICAoKnZhcmlhYmxlcylbImNvbnRhaW5pbmdfY2xhc3MiXSA9IENsYXNzTmFtZShkZXNjcmlwdG9yLT5jb250YWluaW5nX3R5cGUoKSk7CisgICgqdmFyaWFibGVzKVsic3RvcmFnZV90eXBlIl0gPSBtZXNzYWdlX3R5cGU7CisgICgqdmFyaWFibGVzKVsiZ3JvdXBfb3JfbWVzc2FnZSJdID0KKyAgICAgIChkZXNjcmlwdG9yLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQKSA/ICJHcm91cCIgOiAiTWVzc2FnZSI7CisKKyAgKCp2YXJpYWJsZXMpWyJkYXRhVHlwZVNwZWNpZmljX3ZhbHVlIl0gPSAiR1BCU3RyaW5naWZ5U3ltYm9sKCIgKyBtZXNzYWdlX3R5cGUgKyAiKSI7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCitNZXNzYWdlRmllbGRHZW5lcmF0b3I6Ok1lc3NhZ2VGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpCisgICAgOiBPYmpDT2JqRmllbGRHZW5lcmF0b3IoZGVzY3JpcHRvcikgeworICBTZXRNZXNzYWdlVmFyaWFibGVzKGRlc2NyaXB0b3IsICZ2YXJpYWJsZXNfKTsKK30KKworTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjp+TWVzc2FnZUZpZWxkR2VuZXJhdG9yKCkge30KKwordm9pZCBNZXNzYWdlRmllbGRHZW5lcmF0b3I6OkRldGVybWluZUZvcndhcmREZWNsYXJhdGlvbnMoCisgICAgc2V0PHN0cmluZz4qIGZ3ZF9kZWNscykgY29uc3QgeworICAvLyBDbGFzcyBuYW1lIGlzIGFscmVhZHkgaW4gInN0b3JhZ2VfdHlwZSIuCisgIGZ3ZF9kZWNscy0+aW5zZXJ0KCJAY2xhc3MgIiArIHZhcmlhYmxlKCJzdG9yYWdlX3R5cGUiKSk7Cit9CisKK2Jvb2wgTWVzc2FnZUZpZWxkR2VuZXJhdG9yOjpXYW50c0hhc1Byb3BlcnR5KHZvaWQpIGNvbnN0IHsKKyAgaWYgKGRlc2NyaXB0b3JfLT5jb250YWluaW5nX29uZW9mKCkgIT0gTlVMTCkgeworICAgIC8vIElmIGluIGEgb25lb2YsIGl0IHVzZXMgdGhlIG9uZW9mY2FzZSBpbnN0ZWFkIG9mIGEgaGFzIGJpdC4KKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgLy8gSW4gYm90aCBwcm90bzIgJiBwcm90bzMsIG1lc3NhZ2UgZmllbGRzIGhhdmUgYSBoYXMqIHByb3BlcnR5IHRvIHRlbGwKKyAgLy8gd2hlbiBpdCBpcyBhIG5vbiBkZWZhdWx0IHZhbHVlLgorICByZXR1cm4gdHJ1ZTsKK30KKworUmVwZWF0ZWRNZXNzYWdlRmllbGRHZW5lcmF0b3I6OlJlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yKAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcikKKyAgICA6IFJlcGVhdGVkRmllbGRHZW5lcmF0b3IoZGVzY3JpcHRvcikgeworICBTZXRNZXNzYWdlVmFyaWFibGVzKGRlc2NyaXB0b3IsICZ2YXJpYWJsZXNfKTsKKyAgdmFyaWFibGVzX1siYXJyYXlfc3RvcmFnZV90eXBlIl0gPSAiTlNNdXRhYmxlQXJyYXkiOworfQorCitSZXBlYXRlZE1lc3NhZ2VGaWVsZEdlbmVyYXRvcjo6flJlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yKCkge30KKworfSAgLy8gbmFtZXNwYWNlIG9iamVjdGl2ZWMKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19tZXNzYWdlX2ZpZWxkLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19tZXNzYWdlX2ZpZWxkLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzA4ZWE1NgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX21lc3NhZ2VfZmllbGQuaApAQCAtMCwwICsxLDc0IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfT0JKRUNUSVZFQ19NRVNTQUdFX0ZJRUxEX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfT0JKRUNUSVZFQ19NRVNTQUdFX0ZJRUxEX0hfXworCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX2ZpZWxkLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2Ugb2JqZWN0aXZlYyB7CisKK2NsYXNzIE1lc3NhZ2VGaWVsZEdlbmVyYXRvciA6IHB1YmxpYyBPYmpDT2JqRmllbGRHZW5lcmF0b3IgeworICBmcmllbmQgRmllbGRHZW5lcmF0b3IqIEZpZWxkR2VuZXJhdG9yOjpNYWtlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpOworCisgcHJvdGVjdGVkOgorICBleHBsaWNpdCBNZXNzYWdlRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKKyAgdmlydHVhbCB+TWVzc2FnZUZpZWxkR2VuZXJhdG9yKCk7CisgIHZpcnR1YWwgYm9vbCBXYW50c0hhc1Byb3BlcnR5KHZvaWQpIGNvbnN0OworCisgcHVibGljOgorICB2aXJ0dWFsIHZvaWQgRGV0ZXJtaW5lRm9yd2FyZERlY2xhcmF0aW9ucyhzZXQ8c3RyaW5nPiogZndkX2RlY2xzKSBjb25zdDsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhNZXNzYWdlRmllbGRHZW5lcmF0b3IpOworfTsKKworY2xhc3MgUmVwZWF0ZWRNZXNzYWdlRmllbGRHZW5lcmF0b3IgOiBwdWJsaWMgUmVwZWF0ZWRGaWVsZEdlbmVyYXRvciB7CisgIGZyaWVuZCBGaWVsZEdlbmVyYXRvciogRmllbGRHZW5lcmF0b3I6Ok1ha2UoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCk7CisKKyBwcm90ZWN0ZWQ6CisgIGV4cGxpY2l0IFJlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CisgIHZpcnR1YWwgflJlcGVhdGVkTWVzc2FnZUZpZWxkR2VuZXJhdG9yKCk7CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoUmVwZWF0ZWRNZXNzYWdlRmllbGRHZW5lcmF0b3IpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIG9iamVjdGl2ZWMKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX09CSkVDVElWRUNfTUVTU0FHRV9GSUVMRF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX29uZW9mLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfb25lb2YuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2NiODc0OAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX29uZW9mLmNjCkBAIC0wLDAgKzEsMTM4IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2luY2x1ZGUgPG1hcD4KKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX29uZW9mLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIG9iamVjdGl2ZWMgeworCitPbmVvZkdlbmVyYXRvcjo6T25lb2ZHZW5lcmF0b3IoY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKQorICAgIDogZGVzY3JpcHRvcl8oZGVzY3JpcHRvcikgeworICB2YXJpYWJsZXNfWyJlbnVtX25hbWUiXSA9IE9uZW9mRW51bU5hbWUoZGVzY3JpcHRvcl8pOworICB2YXJpYWJsZXNfWyJuYW1lIl0gPSBPbmVvZk5hbWUoZGVzY3JpcHRvcl8pOworICB2YXJpYWJsZXNfWyJjYXBpdGFsaXplZF9uYW1lIl0gPSBPbmVvZk5hbWVDYXBpdGFsaXplZChkZXNjcmlwdG9yXyk7CisgIHZhcmlhYmxlc19bInJhd19pbmRleCJdID0gU2ltcGxlSXRvYShkZXNjcmlwdG9yXy0+aW5kZXgoKSk7CisgIGNvbnN0IERlc2NyaXB0b3IqIG1zZ19kZXNjcmlwdG9yID0gZGVzY3JpcHRvcl8tPmNvbnRhaW5pbmdfdHlwZSgpOworICB2YXJpYWJsZXNfWyJvd25pbmdfbWVzc2FnZV9jbGFzcyJdID0gQ2xhc3NOYW1lKG1zZ19kZXNjcmlwdG9yKTsKKworICBzdHJpbmcgY29tbWVudHM7CisgIFNvdXJjZUxvY2F0aW9uIGxvY2F0aW9uOworICBpZiAoZGVzY3JpcHRvcl8tPkdldFNvdXJjZUxvY2F0aW9uKCZsb2NhdGlvbikpIHsKKyAgICBjb21tZW50cyA9IEJ1aWxkQ29tbWVudHNTdHJpbmcobG9jYXRpb24pOworICB9IGVsc2UgeworICAgIGNvbW1lbnRzID0gIiI7CisgIH0KKyAgdmFyaWFibGVzX1siY29tbWVudHMiXSA9IGNvbW1lbnRzOworfQorCitPbmVvZkdlbmVyYXRvcjo6fk9uZW9mR2VuZXJhdG9yKCkge30KKwordm9pZCBPbmVvZkdlbmVyYXRvcjo6U2V0T25lb2ZJbmRleEJhc2UoaW50IGluZGV4X2Jhc2UpIHsKKyAgaW50IGluZGV4ID0gZGVzY3JpcHRvcl8tPmluZGV4KCkgKyBpbmRleF9iYXNlOworICAvLyBGbGlwIHRoZSBzaWduIHRvIG1hcmsgaXQgYXMgYSBvbmVvZi4KKyAgdmFyaWFibGVzX1siaW5kZXgiXSA9IFNpbXBsZUl0b2EoLWluZGV4KTsKK30KKwordm9pZCBPbmVvZkdlbmVyYXRvcjo6R2VuZXJhdGVDYXNlRW51bShpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICAgIHZhcmlhYmxlc18sCisgICAgICAidHlwZWRlZiBHUEJfRU5VTSgkZW51bV9uYW1lJCkge1xuIik7CisgIHByaW50ZXItPkluZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAgIHZhcmlhYmxlc18sCisgICAgICAiJGVudW1fbmFtZSRfR1BCVW5zZXRPbmVPZkNhc2UgPSAwLFxuIik7CisgIHN0cmluZyBlbnVtX25hbWUgPSB2YXJpYWJsZXNfWyJlbnVtX25hbWUiXTsKKyAgZm9yIChpbnQgaiA9IDA7IGogPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaisrKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3JfLT5maWVsZChqKTsKKyAgICBzdHJpbmcgZmllbGRfbmFtZSA9IEZpZWxkTmFtZUNhcGl0YWxpemVkKGZpZWxkKTsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIiRlbnVtX25hbWUkXyRmaWVsZF9uYW1lJCA9ICRmaWVsZF9udW1iZXIkLFxuIiwKKyAgICAgICAgImVudW1fbmFtZSIsIGVudW1fbmFtZSwKKyAgICAgICAgImZpZWxkX25hbWUiLCBmaWVsZF9uYW1lLAorICAgICAgICAiZmllbGRfbnVtYmVyIiwgU2ltcGxlSXRvYShmaWVsZC0+bnVtYmVyKCkpKTsKKyAgfQorICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KAorICAgICAgIn07XG4iCisgICAgICAiXG4iKTsKK30KKwordm9pZCBPbmVvZkdlbmVyYXRvcjo6R2VuZXJhdGVQdWJsaWNDYXNlUHJvcGVydHlEZWNsYXJhdGlvbigKKyAgICBpbzo6UHJpbnRlciogcHJpbnRlcikgeworICBwcmludGVyLT5QcmludCgKKyAgICAgIHZhcmlhYmxlc18sCisgICAgICAiJGNvbW1lbnRzJCIKKyAgICAgICJAcHJvcGVydHkobm9uYXRvbWljLCByZWFkb25seSkgJGVudW1fbmFtZSQgJG5hbWUkT25lT2ZDYXNlO1xuIgorICAgICAgIlxuIik7Cit9CisKK3ZvaWQgT25lb2ZHZW5lcmF0b3I6OkdlbmVyYXRlQ2xlYXJGdW5jdGlvbkRlY2xhcmF0aW9uKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgICAgdmFyaWFibGVzXywKKyAgICAgICJ2b2lkICRvd25pbmdfbWVzc2FnZV9jbGFzcyRfQ2xlYXIkY2FwaXRhbGl6ZWRfbmFtZSRPbmVPZkNhc2UoJG93bmluZ19tZXNzYWdlX2NsYXNzJCAqbWVzc2FnZSk7XG4iKTsKK30KKwordm9pZCBPbmVvZkdlbmVyYXRvcjo6R2VuZXJhdGVQcm9wZXJ0eUltcGxlbWVudGF0aW9uKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgICAgdmFyaWFibGVzXywKKyAgICAgICJAZHluYW1pYyAkbmFtZSRPbmVPZkNhc2U7XG4iKTsKK30KKwordm9pZCBPbmVvZkdlbmVyYXRvcjo6R2VuZXJhdGVDbGVhckZ1bmN0aW9uSW1wbGVtZW50YXRpb24oaW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICB2YXJpYWJsZXNfLAorICAgICAgInZvaWQgJG93bmluZ19tZXNzYWdlX2NsYXNzJF9DbGVhciRjYXBpdGFsaXplZF9uYW1lJE9uZU9mQ2FzZSgkb3duaW5nX21lc3NhZ2VfY2xhc3MkICptZXNzYWdlKSB7XG4iCisgICAgICAiICBHUEJEZXNjcmlwdG9yICpkZXNjcmlwdG9yID0gW21lc3NhZ2UgZGVzY3JpcHRvcl07XG4iCisgICAgICAiICBHUEJPbmVvZkRlc2NyaXB0b3IgKm9uZW9mID0gZGVzY3JpcHRvci0+b25lb2ZzX1skcmF3X2luZGV4JF07XG4iCisgICAgICAiICBHUEJNYXliZUNsZWFyT25lb2YobWVzc2FnZSwgb25lb2YsIDApO1xuIgorICAgICAgIn1cbiIpOworfQorCit2b2lkIE9uZW9mR2VuZXJhdG9yOjpHZW5lcmF0ZURlc2NyaXB0aW9uKGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgICAgdmFyaWFibGVzXywKKyAgICAgICJ7XG4iCisgICAgICAiICAubmFtZSA9IFwiJG5hbWUkXCIsXG4iCisgICAgICAiICAuaW5kZXggPSAkaW5kZXgkLFxuIgorICAgICAgIn0sXG4iKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIG9iamVjdGl2ZWMKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19vbmVvZi5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfb25lb2YuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iY2JhODJkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfb25lb2YuaApAQCAtMCwwICsxLDc3IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfT0JKRUNUSVZFQ19PTkVPRl9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX09CSkVDVElWRUNfT05FT0ZfSF9fCisKKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8c2V0PgorI2luY2x1ZGUgPHZlY3Rvcj4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW8geworY2xhc3MgUHJpbnRlcjsgIC8vIHByaW50ZXIuaAorfQorfQorCituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBvYmplY3RpdmVjIHsKKworY2xhc3MgT25lb2ZHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgT25lb2ZHZW5lcmF0b3IoY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKKyAgfk9uZW9mR2VuZXJhdG9yKCk7CisKKyAgdm9pZCBTZXRPbmVvZkluZGV4QmFzZShpbnQgaW5kZXhfYmFzZSk7CisKKyAgdm9pZCBHZW5lcmF0ZUNhc2VFbnVtKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworICB2b2lkIEdlbmVyYXRlUHVibGljQ2FzZVByb3BlcnR5RGVjbGFyYXRpb24oaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2b2lkIEdlbmVyYXRlQ2xlYXJGdW5jdGlvbkRlY2xhcmF0aW9uKGlvOjpQcmludGVyKiBwcmludGVyKTsKKworICB2b2lkIEdlbmVyYXRlUHJvcGVydHlJbXBsZW1lbnRhdGlvbihpbzo6UHJpbnRlciogcHJpbnRlcik7CisgIHZvaWQgR2VuZXJhdGVDbGVhckZ1bmN0aW9uSW1wbGVtZW50YXRpb24oaW86OlByaW50ZXIqIHByaW50ZXIpOworICB2b2lkIEdlbmVyYXRlRGVzY3JpcHRpb24oaW86OlByaW50ZXIqIHByaW50ZXIpOworCisgcHJpdmF0ZToKKyAgY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJpYWJsZXNfOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhPbmVvZkdlbmVyYXRvcik7Cit9OworCit9ICAvLyBuYW1lc3BhY2Ugb2JqZWN0aXZlYworfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX09CSkVDVElWRUNfT05FT0ZfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19wcmltaXRpdmVfZmllbGQuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19wcmltaXRpdmVfZmllbGQuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzE4NWI2NgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX3ByaW1pdGl2ZV9maWVsZC5jYwpAQCAtMCwwICsxLDE3MSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8c3RyaW5nPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19wcmltaXRpdmVfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL29iamVjdGl2ZWMvb2JqZWN0aXZlY19oZWxwZXJzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZV9pbmwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdWJzdGl0dXRlLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2Ugb2JqZWN0aXZlYyB7CisKK3VzaW5nIGludGVybmFsOjpXaXJlRm9ybWF0OwordXNpbmcgaW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOworCituYW1lc3BhY2UgeworCitjb25zdCBjaGFyKiBQcmltaXRpdmVUeXBlTmFtZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgT2JqZWN0aXZlQ1R5cGUgdHlwZSA9IEdldE9iamVjdGl2ZUNUeXBlKGRlc2NyaXB0b3IpOworICBzd2l0Y2ggKHR5cGUpIHsKKyAgICBjYXNlIE9CSkVDVElWRUNUWVBFX0lOVDMyOgorICAgICAgcmV0dXJuICJpbnQzMl90IjsKKyAgICBjYXNlIE9CSkVDVElWRUNUWVBFX1VJTlQzMjoKKyAgICAgIHJldHVybiAidWludDMyX3QiOworICAgIGNhc2UgT0JKRUNUSVZFQ1RZUEVfSU5UNjQ6CisgICAgICByZXR1cm4gImludDY0X3QiOworICAgIGNhc2UgT0JKRUNUSVZFQ1RZUEVfVUlOVDY0OgorICAgICAgcmV0dXJuICJ1aW50NjRfdCI7CisgICAgY2FzZSBPQkpFQ1RJVkVDVFlQRV9GTE9BVDoKKyAgICAgIHJldHVybiAiZmxvYXQiOworICAgIGNhc2UgT0JKRUNUSVZFQ1RZUEVfRE9VQkxFOgorICAgICAgcmV0dXJuICJkb3VibGUiOworICAgIGNhc2UgT0JKRUNUSVZFQ1RZUEVfQk9PTEVBTjoKKyAgICAgIHJldHVybiAiQk9PTCI7CisgICAgY2FzZSBPQkpFQ1RJVkVDVFlQRV9TVFJJTkc6CisgICAgICByZXR1cm4gIk5TU3RyaW5nIjsKKyAgICBjYXNlIE9CSkVDVElWRUNUWVBFX0RBVEE6CisgICAgICByZXR1cm4gIk5TRGF0YSI7CisgICAgY2FzZSBPQkpFQ1RJVkVDVFlQRV9FTlVNOgorICAgICAgcmV0dXJuICJpbnQzMl90IjsKKyAgICBjYXNlIE9CSkVDVElWRUNUWVBFX01FU1NBR0U6CisgICAgICByZXR1cm4gTlVMTDsKKyAgfQorCisgIC8vIFNvbWUgY29tcGlsZXJzIHJlcG9ydCByZWFjaGluZyBlbmQgb2YgZnVuY3Rpb24gZXZlbiB0aG91Z2ggYWxsIGNhc2VzIG9mCisgIC8vIHRoZSBlbnVtIGFyZSBoYW5kZWQgaW4gdGhlIHN3aXRjaC4KKyAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkNhbid0IGdldCBoZXJlLiI7CisgIHJldHVybiBOVUxMOworfQorCitjb25zdCBjaGFyKiBQcmltaXRpdmVBcnJheVR5cGVOYW1lKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBPYmplY3RpdmVDVHlwZSB0eXBlID0gR2V0T2JqZWN0aXZlQ1R5cGUoZGVzY3JpcHRvcik7CisgIHN3aXRjaCAodHlwZSkgeworICAgIGNhc2UgT0JKRUNUSVZFQ1RZUEVfSU5UMzI6CisgICAgICByZXR1cm4gIkludDMyIjsKKyAgICBjYXNlIE9CSkVDVElWRUNUWVBFX1VJTlQzMjoKKyAgICAgIHJldHVybiAiVUludDMyIjsKKyAgICBjYXNlIE9CSkVDVElWRUNUWVBFX0lOVDY0OgorICAgICAgcmV0dXJuICJJbnQ2NCI7CisgICAgY2FzZSBPQkpFQ1RJVkVDVFlQRV9VSU5UNjQ6CisgICAgICByZXR1cm4gIlVJbnQ2NCI7CisgICAgY2FzZSBPQkpFQ1RJVkVDVFlQRV9GTE9BVDoKKyAgICAgIHJldHVybiAiRmxvYXQiOworICAgIGNhc2UgT0JKRUNUSVZFQ1RZUEVfRE9VQkxFOgorICAgICAgcmV0dXJuICJEb3VibGUiOworICAgIGNhc2UgT0JKRUNUSVZFQ1RZUEVfQk9PTEVBTjoKKyAgICAgIHJldHVybiAiQm9vbCI7CisgICAgY2FzZSBPQkpFQ1RJVkVDVFlQRV9TVFJJTkc6CisgICAgICByZXR1cm4gIiI7ICAvLyBXYW50IE5TQXJyYXkKKyAgICBjYXNlIE9CSkVDVElWRUNUWVBFX0RBVEE6CisgICAgICByZXR1cm4gIiI7ICAvLyBXYW50IE5TQXJyYXkKKyAgICBjYXNlIE9CSkVDVElWRUNUWVBFX0VOVU06CisgICAgICByZXR1cm4gIkVudW0iOworICAgIGNhc2UgT0JKRUNUSVZFQ1RZUEVfTUVTU0FHRToKKyAgICAgIHJldHVybiAiIjsgIC8vIFdhbnQgTlNBcnJheQorICB9CisKKyAgLy8gU29tZSBjb21waWxlcnMgcmVwb3J0IHJlYWNoaW5nIGVuZCBvZiBmdW5jdGlvbiBldmVuIHRob3VnaCBhbGwgY2FzZXMgb2YKKyAgLy8gdGhlIGVudW0gYXJlIGhhbmRlZCBpbiB0aGUgc3dpdGNoLgorICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ2FuJ3QgZ2V0IGhlcmUuIjsKKyAgcmV0dXJuIE5VTEw7Cit9CisKK3ZvaWQgU2V0UHJpbWl0aXZlVmFyaWFibGVzKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcDxzdHJpbmcsIHN0cmluZz4qIHZhcmlhYmxlcykgeworICBzdGQ6OnN0cmluZyBwcmltaXRpdmVfbmFtZSA9IFByaW1pdGl2ZVR5cGVOYW1lKGRlc2NyaXB0b3IpOworICAoKnZhcmlhYmxlcylbInR5cGUiXSA9IHByaW1pdGl2ZV9uYW1lOworICAoKnZhcmlhYmxlcylbInN0b3JhZ2VfdHlwZSJdID0gcHJpbWl0aXZlX25hbWU7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCitQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6UHJpbWl0aXZlRmllbGRHZW5lcmF0b3IoCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yKQorICAgIDogU2luZ2xlRmllbGRHZW5lcmF0b3IoZGVzY3JpcHRvcikgeworICBTZXRQcmltaXRpdmVWYXJpYWJsZXMoZGVzY3JpcHRvciwgJnZhcmlhYmxlc18pOworfQorCitQcmltaXRpdmVGaWVsZEdlbmVyYXRvcjo6flByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKCkge30KKworUHJpbWl0aXZlT2JqRmllbGRHZW5lcmF0b3I6OlByaW1pdGl2ZU9iakZpZWxkR2VuZXJhdG9yKAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcikKKyAgICA6IE9iakNPYmpGaWVsZEdlbmVyYXRvcihkZXNjcmlwdG9yKSB7CisgIFNldFByaW1pdGl2ZVZhcmlhYmxlcyhkZXNjcmlwdG9yLCAmdmFyaWFibGVzXyk7CisgIHZhcmlhYmxlc19bInByb3BlcnR5X3N0b3JhZ2VfYXR0cmlidXRlIl0gPSAiY29weSI7Cit9CisKK1ByaW1pdGl2ZU9iakZpZWxkR2VuZXJhdG9yOjp+UHJpbWl0aXZlT2JqRmllbGRHZW5lcmF0b3IoKSB7fQorCitSZXBlYXRlZFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjpSZXBlYXRlZFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcikKKyAgICA6IFJlcGVhdGVkRmllbGRHZW5lcmF0b3IoZGVzY3JpcHRvcikgeworICBTZXRQcmltaXRpdmVWYXJpYWJsZXMoZGVzY3JpcHRvciwgJnZhcmlhYmxlc18pOworCisgIHN0cmluZyBiYXNlX25hbWUgPSBQcmltaXRpdmVBcnJheVR5cGVOYW1lKGRlc2NyaXB0b3IpOworICBpZiAoYmFzZV9uYW1lLmxlbmd0aCgpKSB7CisgICAgdmFyaWFibGVzX1siYXJyYXlfc3RvcmFnZV90eXBlIl0gPSAiR1BCIiArIGJhc2VfbmFtZSArICJBcnJheSI7CisgIH0gZWxzZSB7CisgICAgdmFyaWFibGVzX1siYXJyYXlfc3RvcmFnZV90eXBlIl0gPSAiTlNNdXRhYmxlQXJyYXkiOworICB9Cit9CisKK1JlcGVhdGVkUHJpbWl0aXZlRmllbGRHZW5lcmF0b3I6On5SZXBlYXRlZFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yKCkge30KKwordm9pZCBSZXBlYXRlZFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yOjpGaW5pc2hJbml0aWFsaXphdGlvbih2b2lkKSB7CisgIFJlcGVhdGVkRmllbGRHZW5lcmF0b3I6OkZpbmlzaEluaXRpYWxpemF0aW9uKCk7CisgIGlmIChJc1ByaW1pdGl2ZVR5cGUoZGVzY3JpcHRvcl8pKSB7CisgICAgLy8gTm8gY29tbWVudCBuZWVkZWQgZm9yIHByaW1pdGl2ZSB0eXBlcy4KKyAgICB2YXJpYWJsZXNfWyJhcnJheV9jb21tZW50Il0gPSAiIjsKKyAgfQorfQorCit9ICAvLyBuYW1lc3BhY2Ugb2JqZWN0aXZlYworfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX3ByaW1pdGl2ZV9maWVsZC5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9vYmplY3RpdmVjL29iamVjdGl2ZWNfcHJpbWl0aXZlX2ZpZWxkLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWJiNzkzNAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX3ByaW1pdGl2ZV9maWVsZC5oCkBAIC0wLDAgKzEsODIgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9PQkpFQ1RJVkVDX1BSSU1JVElWRV9GSUVMRF9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX09CSkVDVElWRUNfUFJJTUlUSVZFX0ZJRUxEX0hfXworCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvb2JqZWN0aXZlYy9vYmplY3RpdmVjX2ZpZWxkLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2Ugb2JqZWN0aXZlYyB7CisKK2NsYXNzIFByaW1pdGl2ZUZpZWxkR2VuZXJhdG9yIDogcHVibGljIFNpbmdsZUZpZWxkR2VuZXJhdG9yIHsKKyAgZnJpZW5kIEZpZWxkR2VuZXJhdG9yKiBGaWVsZEdlbmVyYXRvcjo6TWFrZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKTsKKworIHByb3RlY3RlZDoKKyAgZXhwbGljaXQgUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKKyAgdmlydHVhbCB+UHJpbWl0aXZlRmllbGRHZW5lcmF0b3IoKTsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhQcmltaXRpdmVGaWVsZEdlbmVyYXRvcik7Cit9OworCitjbGFzcyBQcmltaXRpdmVPYmpGaWVsZEdlbmVyYXRvciA6IHB1YmxpYyBPYmpDT2JqRmllbGRHZW5lcmF0b3IgeworICBmcmllbmQgRmllbGRHZW5lcmF0b3IqIEZpZWxkR2VuZXJhdG9yOjpNYWtlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpOworCisgcHJvdGVjdGVkOgorICBleHBsaWNpdCBQcmltaXRpdmVPYmpGaWVsZEdlbmVyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpOworICB2aXJ0dWFsIH5QcmltaXRpdmVPYmpGaWVsZEdlbmVyYXRvcigpOworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFByaW1pdGl2ZU9iakZpZWxkR2VuZXJhdG9yKTsKK307CisKK2NsYXNzIFJlcGVhdGVkUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IgOiBwdWJsaWMgUmVwZWF0ZWRGaWVsZEdlbmVyYXRvciB7CisgIGZyaWVuZCBGaWVsZEdlbmVyYXRvciogRmllbGRHZW5lcmF0b3I6Ok1ha2UoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCk7CisKKyBwcm90ZWN0ZWQ6CisgIGV4cGxpY2l0IFJlcGVhdGVkUHJpbWl0aXZlRmllbGRHZW5lcmF0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKKyAgdmlydHVhbCB+UmVwZWF0ZWRQcmltaXRpdmVGaWVsZEdlbmVyYXRvcigpOworICB2aXJ0dWFsIHZvaWQgRmluaXNoSW5pdGlhbGl6YXRpb24odm9pZCk7CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoUmVwZWF0ZWRQcmltaXRpdmVGaWVsZEdlbmVyYXRvcik7Cit9OworCit9ICAvLyBuYW1lc3BhY2Ugb2JqZWN0aXZlYworfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfT0JKRUNUSVZFQ19QUklNSVRJVkVfRklFTERfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BhY2thZ2VfaW5mby5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wYWNrYWdlX2luZm8uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mYjZiNDczCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wYWNrYWdlX2luZm8uaApAQCAtMCwwICsxLDY0IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisvLworLy8gVGhpcyBmaWxlIGV4aXN0cyBzb2xlbHkgdG8gZG9jdW1lbnQgdGhlIGdvb2dsZTo6cHJvdG9idWY6OmNvbXBpbGVyIG5hbWVzcGFjZS4KKy8vIEl0IGlzIG5vdCBjb21waWxlZCBpbnRvIGFueXRoaW5nLCBidXQgaXQgbWF5IGJlIHJlYWQgYnkgYW4gYXV0b21hdGVkCisvLyBkb2N1bWVudGF0aW9uIGdlbmVyYXRvci4KKworbmFtZXNwYWNlIGdvb2dsZSB7CisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKKy8vIEltcGxlbWVudGF0aW9uIG9mIHRoZSBQcm90b2NvbCBCdWZmZXIgY29tcGlsZXIuCisvLworLy8gVGhpcyBwYWNrYWdlIGNvbnRhaW5zIGNvZGUgZm9yIHBhcnNpbmcgLnByb3RvIGZpbGVzIGFuZCBnZW5lcmF0aW5nIGNvZGUKKy8vIGJhc2VkIG9uIHRoZW0uICBUaGVyZSBhcmUgdHdvIHJlYXNvbnMgeW91IG1pZ2h0IGJlIGludGVyZXN0ZWQgaW4gdGhpcworLy8gcGFja2FnZToKKy8vIC0gWW91IHdhbnQgdG8gcGFyc2UgLnByb3RvIGZpbGVzIGF0IHJ1bnRpbWUuICBJbiB0aGlzIGNhc2UsIHlvdSBzaG91bGQKKy8vICAgbG9vayBhdCBpbXBvcnRlci5oLiAgU2luY2UgdGhpcyBmdW5jdGlvbmFsaXR5IGlzIHdpZGVseSB1c2VmdWwsIGl0IGlzCisvLyAgIGluY2x1ZGVkIGluIHRoZSBsaWJwcm90b2J1ZiBiYXNlIGxpYnJhcnk7IHlvdSBkbyBub3QgaGF2ZSB0byBsaW5rIGFnYWluc3QKKy8vICAgbGlicHJvdG9jLgorLy8gLSBZb3Ugd2FudCB0byB3cml0ZSBhIGN1c3RvbSBwcm90b2NvbCBjb21waWxlciB3aGljaCBnZW5lcmF0ZXMgZGlmZmVyZW50CisvLyAgIGtpbmRzIG9mIGNvZGUsIGUuZy4gY29kZSBpbiBhIGRpZmZlcmVudCBsYW5ndWFnZSB3aGljaCBpcyBub3Qgc3VwcG9ydGVkCisvLyAgIGJ5IHRoZSBvZmZpY2lhbCBjb21waWxlci4gIEZvciB0aGlzIHB1cnBvc2UsIGNvbW1hbmRfbGluZV9pbnRlcmZhY2UuaAorLy8gICBwcm92aWRlcyB5b3Ugd2l0aCBhIGNvbXBsZXRlIGNvbXBpbGVyIGZyb250LWVuZCwgc28gYWxsIHlvdSBuZWVkIHRvIGRvCisvLyAgIGlzIHdyaXRlIGEgY3VzdG9tIGltcGxlbWVudGF0aW9uIG9mIENvZGVHZW5lcmF0b3IgYW5kIGEgdHJpdmlhbCBtYWluKCkKKy8vICAgZnVuY3Rpb24uICBZb3UgY2FuIGV2ZW4gbWFrZSB5b3VyIGNvbXBpbGVyIHN1cHBvcnQgdGhlIG9mZmljaWFsIGxhbmd1YWdlcworLy8gICBpbiBhZGRpdGlvbiB0byB5b3VyIG93bi4gIFNpbmNlIHRoaXMgZnVuY3Rpb25hbGl0eSBpcyBvbmx5IHVzZWZ1bCB0byB0aG9zZQorLy8gICB3cml0aW5nIGN1c3RvbSBjb21waWxlcnMsIGl0IGlzIGluIGEgc2VwYXJhdGUgbGlicmFyeSBjYWxsZWQgImxpYnByb3RvYyIKKy8vICAgd2hpY2ggeW91IHdpbGwgaGF2ZSB0byBsaW5rIGFnYWluc3QuCituYW1lc3BhY2UgY29tcGlsZXIge30KKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BhcnNlci5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGFyc2VyLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkwZGVkNGQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BhcnNlci5jYwpAQCAtMCwwICsxLDIxMDkgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBSZWN1cnNpdmUgZGVzY2VudCBGVFcuCisKKyNpbmNsdWRlIDxmbG9hdC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9oYXNoLmg+CisjaW5jbHVkZSA8bGltaXRzPgorCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGFyc2VyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby90b2tlbml6ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbG9nZ2luZy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9tYXBfdXRpbC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworCit1c2luZyBpbnRlcm5hbDo6V2lyZUZvcm1hdDsKKworbmFtZXNwYWNlIHsKKwordHlwZWRlZiBoYXNoX21hcDxzdHJpbmcsIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUeXBlPiBUeXBlTmFtZU1hcDsKKworVHlwZU5hbWVNYXAgTWFrZVR5cGVOYW1lVGFibGUoKSB7CisgIFR5cGVOYW1lTWFwIHJlc3VsdDsKKworICByZXN1bHRbImRvdWJsZSIgIF0gPSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9ET1VCTEU7CisgIHJlc3VsdFsiZmxvYXQiICAgXSA9IEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0ZMT0FUOworICByZXN1bHRbInVpbnQ2NCIgIF0gPSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9VSU5UNjQ7CisgIHJlc3VsdFsiZml4ZWQ2NCIgXSA9IEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0ZJWEVENjQ7CisgIHJlc3VsdFsiZml4ZWQzMiIgXSA9IEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0ZJWEVEMzI7CisgIHJlc3VsdFsiYm9vbCIgICAgXSA9IEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0JPT0w7CisgIHJlc3VsdFsic3RyaW5nIiAgXSA9IEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX1NUUklORzsKKyAgcmVzdWx0WyJncm91cCIgICBdID0gRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfR1JPVVA7CisKKyAgcmVzdWx0WyJieXRlcyIgICBdID0gRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfQllURVM7CisgIHJlc3VsdFsidWludDMyIiAgXSA9IEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX1VJTlQzMjsKKyAgcmVzdWx0WyJzZml4ZWQzMiJdID0gRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfU0ZJWEVEMzI7CisgIHJlc3VsdFsic2ZpeGVkNjQiXSA9IEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX1NGSVhFRDY0OworICByZXN1bHRbImludDMyIiAgIF0gPSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9JTlQzMjsKKyAgcmVzdWx0WyJpbnQ2NCIgICBdID0gRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfSU5UNjQ7CisgIHJlc3VsdFsic2ludDMyIiAgXSA9IEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX1NJTlQzMjsKKyAgcmVzdWx0WyJzaW50NjQiICBdID0gRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfU0lOVDY0OworCisgIHJldHVybiByZXN1bHQ7Cit9CisKK2NvbnN0IFR5cGVOYW1lTWFwIGtUeXBlTmFtZXMgPSBNYWtlVHlwZU5hbWVUYWJsZSgpOworCisvLyBDYW1lbC1jYXNlIHRoZSBmaWVsZCBuYW1lIGFuZCBhcHBlbmQgIkVudHJ5IiBmb3IgZ2VuZXJhdGVkIG1hcCBlbnRyeSBuYW1lLgorLy8gZS5nLiBtYXA8S2V5VHlwZSwgVmFsdWVUeXBlPiBmb29fbWFwID0+IEZvb01hcEVudHJ5CitzdHJpbmcgTWFwRW50cnlOYW1lKGNvbnN0IHN0cmluZyYgZmllbGRfbmFtZSkgeworICBzdHJpbmcgcmVzdWx0OworICBzdGF0aWMgY29uc3QgY2hhciBrU3VmZml4W10gPSAiRW50cnkiOworICByZXN1bHQucmVzZXJ2ZShmaWVsZF9uYW1lLnNpemUoKSArIHNpemVvZihrU3VmZml4KSk7CisgIGJvb2wgY2FwX25leHQgPSB0cnVlOworICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkX25hbWUuc2l6ZSgpOyArK2kpIHsKKyAgICBpZiAoZmllbGRfbmFtZVtpXSA9PSAnXycpIHsKKyAgICAgIGNhcF9uZXh0ID0gdHJ1ZTsKKyAgICB9IGVsc2UgaWYgKGNhcF9uZXh0KSB7CisgICAgICAvLyBOb3RlOiBEbyBub3QgdXNlIGN0eXBlLmggZHVlIHRvIGxvY2FsZXMuCisgICAgICBpZiAoJ2EnIDw9IGZpZWxkX25hbWVbaV0gJiYgZmllbGRfbmFtZVtpXSA8PSAneicpIHsKKyAgICAgICAgcmVzdWx0LnB1c2hfYmFjayhmaWVsZF9uYW1lW2ldIC0gJ2EnICsgJ0EnKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJlc3VsdC5wdXNoX2JhY2soZmllbGRfbmFtZVtpXSk7CisgICAgICB9CisgICAgICBjYXBfbmV4dCA9IGZhbHNlOworICAgIH0gZWxzZSB7CisgICAgICByZXN1bHQucHVzaF9iYWNrKGZpZWxkX25hbWVbaV0pOworICAgIH0KKyAgfQorICByZXN1bHQuYXBwZW5kKGtTdWZmaXgpOworICByZXR1cm4gcmVzdWx0OworfQorCit9ICAvLyBhbm9ueW1vdXMgbmFtZXNwYWNlCisKKy8vIE1ha2VzIGNvZGUgc2xpZ2h0bHkgbW9yZSByZWFkYWJsZS4gIFRoZSBtZWFuaW5nIG9mICJETyhmb28pIiBpcworLy8gIkV4ZWN1dGUgZm9vIGFuZCBmYWlsIGlmIGl0IGZhaWxzLiIsIHdoZXJlIGZhaWx1cmUgaXMgaW5kaWNhdGVkIGJ5CisvLyByZXR1cm5pbmcgZmFsc2UuCisjZGVmaW5lIERPKFNUQVRFTUVOVCkgaWYgKFNUQVRFTUVOVCkge30gZWxzZSByZXR1cm4gZmFsc2UKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitQYXJzZXI6OlBhcnNlcigpCisgIDogaW5wdXRfKE5VTEwpLAorICAgIGVycm9yX2NvbGxlY3Rvcl8oTlVMTCksCisgICAgc291cmNlX2xvY2F0aW9uX3RhYmxlXyhOVUxMKSwKKyAgICBoYWRfZXJyb3JzXyhmYWxzZSksCisgICAgcmVxdWlyZV9zeW50YXhfaWRlbnRpZmllcl8oZmFsc2UpLAorICAgIHN0b3BfYWZ0ZXJfc3ludGF4X2lkZW50aWZpZXJfKGZhbHNlKSB7Cit9CisKK1BhcnNlcjo6flBhcnNlcigpIHsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitpbmxpbmUgYm9vbCBQYXJzZXI6Okxvb2tpbmdBdChjb25zdCBjaGFyKiB0ZXh0KSB7CisgIHJldHVybiBpbnB1dF8tPmN1cnJlbnQoKS50ZXh0ID09IHRleHQ7Cit9CisKK2lubGluZSBib29sIFBhcnNlcjo6TG9va2luZ0F0VHlwZShpbzo6VG9rZW5pemVyOjpUb2tlblR5cGUgdG9rZW5fdHlwZSkgeworICByZXR1cm4gaW5wdXRfLT5jdXJyZW50KCkudHlwZSA9PSB0b2tlbl90eXBlOworfQorCitpbmxpbmUgYm9vbCBQYXJzZXI6OkF0RW5kKCkgeworICByZXR1cm4gTG9va2luZ0F0VHlwZShpbzo6VG9rZW5pemVyOjpUWVBFX0VORCk7Cit9CisKK2Jvb2wgUGFyc2VyOjpUcnlDb25zdW1lKGNvbnN0IGNoYXIqIHRleHQpIHsKKyAgaWYgKExvb2tpbmdBdCh0ZXh0KSkgeworICAgIGlucHV0Xy0+TmV4dCgpOworICAgIHJldHVybiB0cnVlOworICB9IGVsc2UgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorfQorCitib29sIFBhcnNlcjo6Q29uc3VtZShjb25zdCBjaGFyKiB0ZXh0LCBjb25zdCBjaGFyKiBlcnJvcikgeworICBpZiAoVHJ5Q29uc3VtZSh0ZXh0KSkgeworICAgIHJldHVybiB0cnVlOworICB9IGVsc2UgeworICAgIEFkZEVycm9yKGVycm9yKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KK30KKworYm9vbCBQYXJzZXI6OkNvbnN1bWUoY29uc3QgY2hhciogdGV4dCkgeworICBpZiAoVHJ5Q29uc3VtZSh0ZXh0KSkgeworICAgIHJldHVybiB0cnVlOworICB9IGVsc2UgeworICAgIEFkZEVycm9yKCJFeHBlY3RlZCBcIiIgKyBzdHJpbmcodGV4dCkgKyAiXCIuIik7CisgICAgcmV0dXJuIGZhbHNlOworICB9Cit9CisKK2Jvb2wgUGFyc2VyOjpDb25zdW1lSWRlbnRpZmllcihzdHJpbmcqIG91dHB1dCwgY29uc3QgY2hhciogZXJyb3IpIHsKKyAgaWYgKExvb2tpbmdBdFR5cGUoaW86OlRva2VuaXplcjo6VFlQRV9JREVOVElGSUVSKSkgeworICAgICpvdXRwdXQgPSBpbnB1dF8tPmN1cnJlbnQoKS50ZXh0OworICAgIGlucHV0Xy0+TmV4dCgpOworICAgIHJldHVybiB0cnVlOworICB9IGVsc2UgeworICAgIEFkZEVycm9yKGVycm9yKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KK30KKworYm9vbCBQYXJzZXI6OkNvbnN1bWVJbnRlZ2VyKGludCogb3V0cHV0LCBjb25zdCBjaGFyKiBlcnJvcikgeworICBpZiAoTG9va2luZ0F0VHlwZShpbzo6VG9rZW5pemVyOjpUWVBFX0lOVEVHRVIpKSB7CisgICAgdWludDY0IHZhbHVlID0gMDsKKyAgICBpZiAoIWlvOjpUb2tlbml6ZXI6OlBhcnNlSW50ZWdlcihpbnB1dF8tPmN1cnJlbnQoKS50ZXh0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtpbnQzMm1heCwgJnZhbHVlKSkgeworICAgICAgQWRkRXJyb3IoIkludGVnZXIgb3V0IG9mIHJhbmdlLiIpOworICAgICAgLy8gV2Ugc3RpbGwgcmV0dXJuIHRydWUgYmVjYXVzZSB3ZSBkaWQsIGluIGZhY3QsIHBhcnNlIGFuIGludGVnZXIuCisgICAgfQorICAgICpvdXRwdXQgPSB2YWx1ZTsKKyAgICBpbnB1dF8tPk5leHQoKTsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfSBlbHNlIHsKKyAgICBBZGRFcnJvcihlcnJvcik7CisgICAgcmV0dXJuIGZhbHNlOworICB9Cit9CisKK2Jvb2wgUGFyc2VyOjpDb25zdW1lU2lnbmVkSW50ZWdlcihpbnQqIG91dHB1dCwgY29uc3QgY2hhciogZXJyb3IpIHsKKyAgYm9vbCBpc19uZWdhdGl2ZSA9IGZhbHNlOworICB1aW50NjQgbWF4X3ZhbHVlID0ga2ludDMybWF4OworICBpZiAoVHJ5Q29uc3VtZSgiLSIpKSB7CisgICAgaXNfbmVnYXRpdmUgPSB0cnVlOworICAgIG1heF92YWx1ZSArPSAxOworICB9CisgIHVpbnQ2NCB2YWx1ZSA9IDA7CisgIERPKENvbnN1bWVJbnRlZ2VyNjQobWF4X3ZhbHVlLCAmdmFsdWUsIGVycm9yKSk7CisgIGlmIChpc19uZWdhdGl2ZSkgdmFsdWUgKj0gLTE7CisgICpvdXRwdXQgPSB2YWx1ZTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgUGFyc2VyOjpDb25zdW1lSW50ZWdlcjY0KHVpbnQ2NCBtYXhfdmFsdWUsIHVpbnQ2NCogb3V0cHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogZXJyb3IpIHsKKyAgaWYgKExvb2tpbmdBdFR5cGUoaW86OlRva2VuaXplcjo6VFlQRV9JTlRFR0VSKSkgeworICAgIGlmICghaW86OlRva2VuaXplcjo6UGFyc2VJbnRlZ2VyKGlucHV0Xy0+Y3VycmVudCgpLnRleHQsIG1heF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXQpKSB7CisgICAgICBBZGRFcnJvcigiSW50ZWdlciBvdXQgb2YgcmFuZ2UuIik7CisgICAgICAvLyBXZSBzdGlsbCByZXR1cm4gdHJ1ZSBiZWNhdXNlIHdlIGRpZCwgaW4gZmFjdCwgcGFyc2UgYW4gaW50ZWdlci4KKyAgICAgICpvdXRwdXQgPSAwOworICAgIH0KKyAgICBpbnB1dF8tPk5leHQoKTsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfSBlbHNlIHsKKyAgICBBZGRFcnJvcihlcnJvcik7CisgICAgcmV0dXJuIGZhbHNlOworICB9Cit9CisKK2Jvb2wgUGFyc2VyOjpDb25zdW1lTnVtYmVyKGRvdWJsZSogb3V0cHV0LCBjb25zdCBjaGFyKiBlcnJvcikgeworICBpZiAoTG9va2luZ0F0VHlwZShpbzo6VG9rZW5pemVyOjpUWVBFX0ZMT0FUKSkgeworICAgICpvdXRwdXQgPSBpbzo6VG9rZW5pemVyOjpQYXJzZUZsb2F0KGlucHV0Xy0+Y3VycmVudCgpLnRleHQpOworICAgIGlucHV0Xy0+TmV4dCgpOworICAgIHJldHVybiB0cnVlOworICB9IGVsc2UgaWYgKExvb2tpbmdBdFR5cGUoaW86OlRva2VuaXplcjo6VFlQRV9JTlRFR0VSKSkgeworICAgIC8vIEFsc28gYWNjZXB0IGludGVnZXJzLgorICAgIHVpbnQ2NCB2YWx1ZSA9IDA7CisgICAgaWYgKCFpbzo6VG9rZW5pemVyOjpQYXJzZUludGVnZXIoaW5wdXRfLT5jdXJyZW50KCkudGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrdWludDY0bWF4LCAmdmFsdWUpKSB7CisgICAgICBBZGRFcnJvcigiSW50ZWdlciBvdXQgb2YgcmFuZ2UuIik7CisgICAgICAvLyBXZSBzdGlsbCByZXR1cm4gdHJ1ZSBiZWNhdXNlIHdlIGRpZCwgaW4gZmFjdCwgcGFyc2UgYSBudW1iZXIuCisgICAgfQorICAgICpvdXRwdXQgPSB2YWx1ZTsKKyAgICBpbnB1dF8tPk5leHQoKTsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfSBlbHNlIGlmIChMb29raW5nQXQoImluZiIpKSB7CisgICAgKm91dHB1dCA9IG51bWVyaWNfbGltaXRzPGRvdWJsZT46OmluZmluaXR5KCk7CisgICAgaW5wdXRfLT5OZXh0KCk7CisgICAgcmV0dXJuIHRydWU7CisgIH0gZWxzZSBpZiAoTG9va2luZ0F0KCJuYW4iKSkgeworICAgICpvdXRwdXQgPSBudW1lcmljX2xpbWl0czxkb3VibGU+OjpxdWlldF9OYU4oKTsKKyAgICBpbnB1dF8tPk5leHQoKTsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfSBlbHNlIHsKKyAgICBBZGRFcnJvcihlcnJvcik7CisgICAgcmV0dXJuIGZhbHNlOworICB9Cit9CisKK2Jvb2wgUGFyc2VyOjpDb25zdW1lU3RyaW5nKHN0cmluZyogb3V0cHV0LCBjb25zdCBjaGFyKiBlcnJvcikgeworICBpZiAoTG9va2luZ0F0VHlwZShpbzo6VG9rZW5pemVyOjpUWVBFX1NUUklORykpIHsKKyAgICBpbzo6VG9rZW5pemVyOjpQYXJzZVN0cmluZyhpbnB1dF8tPmN1cnJlbnQoKS50ZXh0LCBvdXRwdXQpOworICAgIGlucHV0Xy0+TmV4dCgpOworICAgIC8vIEFsbG93IEMrKyBsaWtlIGNvbmNhdGVuYXRpb24gb2YgYWRqYWNlbnQgc3RyaW5nIHRva2Vucy4KKyAgICB3aGlsZSAoTG9va2luZ0F0VHlwZShpbzo6VG9rZW5pemVyOjpUWVBFX1NUUklORykpIHsKKyAgICAgIGlvOjpUb2tlbml6ZXI6OlBhcnNlU3RyaW5nQXBwZW5kKGlucHV0Xy0+Y3VycmVudCgpLnRleHQsIG91dHB1dCk7CisgICAgICBpbnB1dF8tPk5leHQoKTsKKyAgICB9CisgICAgcmV0dXJuIHRydWU7CisgIH0gZWxzZSB7CisgICAgQWRkRXJyb3IoZXJyb3IpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorfQorCitib29sIFBhcnNlcjo6VHJ5Q29uc3VtZUVuZE9mRGVjbGFyYXRpb24oCisgICAgY29uc3QgY2hhciogdGV4dCwgY29uc3QgTG9jYXRpb25SZWNvcmRlciogbG9jYXRpb24pIHsKKyAgaWYgKExvb2tpbmdBdCh0ZXh0KSkgeworICAgIHN0cmluZyBsZWFkaW5nLCB0cmFpbGluZzsKKyAgICB2ZWN0b3I8c3RyaW5nPiBkZXRhY2hlZDsKKyAgICBpbnB1dF8tPk5leHRXaXRoQ29tbWVudHMoJnRyYWlsaW5nLCAmZGV0YWNoZWQsICZsZWFkaW5nKTsKKworICAgIC8vIFNhdmUgdGhlIGxlYWRpbmcgY29tbWVudHMgZm9yIG5leHQgdGltZSwgYW5kIHJlY2FsbCB0aGUgbGVhZGluZyBjb21tZW50cworICAgIC8vIGZyb20gbGFzdCB0aW1lLgorICAgIGxlYWRpbmcuc3dhcCh1cGNvbWluZ19kb2NfY29tbWVudHNfKTsKKworICAgIGlmIChsb2NhdGlvbiAhPSBOVUxMKSB7CisgICAgICB1cGNvbWluZ19kZXRhY2hlZF9jb21tZW50c18uc3dhcChkZXRhY2hlZCk7CisgICAgICBsb2NhdGlvbi0+QXR0YWNoQ29tbWVudHMoJmxlYWRpbmcsICZ0cmFpbGluZywgJmRldGFjaGVkKTsKKyAgICB9IGVsc2UgaWYgKHN0cmNtcCh0ZXh0LCAifSIpID09IDApIHsKKyAgICAgIC8vIElmIHRoZSBjdXJyZW50IGxvY2F0aW9uIGlzIG51bGwgYW5kIHdlIGFyZSBmaW5pc2hpbmcgdGhlIGN1cnJlbnQgc2NvcGUsCisgICAgICAvLyBkcm9wIHBlbmRpbmcgdXBjb21pbmcgZGV0YWNoZWQgY29tbWVudHMuCisgICAgICB1cGNvbWluZ19kZXRhY2hlZF9jb21tZW50c18uc3dhcChkZXRhY2hlZCk7CisgICAgfSBlbHNlIHsKKyAgICAgIC8vIE90aGVyd2lzZSwgYXBwZW5kIHRoZSBuZXcgZGV0YWNoZWQgY29tbWVudHMgdG8gdGhlIGV4aXN0aW5nIHVwY29taW5nCisgICAgICAvLyBkZXRhY2hlZCBjb21tZW50cy4KKyAgICAgIHVwY29taW5nX2RldGFjaGVkX2NvbW1lbnRzXy5pbnNlcnQodXBjb21pbmdfZGV0YWNoZWRfY29tbWVudHNfLmVuZCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXRhY2hlZC5iZWdpbigpLCBkZXRhY2hlZC5lbmQoKSk7CisgICAgfQorCisgICAgcmV0dXJuIHRydWU7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9Cit9CisKK2Jvb2wgUGFyc2VyOjpDb25zdW1lRW5kT2ZEZWNsYXJhdGlvbigKKyAgICBjb25zdCBjaGFyKiB0ZXh0LCBjb25zdCBMb2NhdGlvblJlY29yZGVyKiBsb2NhdGlvbikgeworICBpZiAoVHJ5Q29uc3VtZUVuZE9mRGVjbGFyYXRpb24odGV4dCwgbG9jYXRpb24pKSB7CisgICAgcmV0dXJuIHRydWU7CisgIH0gZWxzZSB7CisgICAgQWRkRXJyb3IoIkV4cGVjdGVkIFwiIiArIHN0cmluZyh0ZXh0KSArICJcIi4iKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIFBhcnNlcjo6QWRkRXJyb3IoaW50IGxpbmUsIGludCBjb2x1bW4sIGNvbnN0IHN0cmluZyYgZXJyb3IpIHsKKyAgaWYgKGVycm9yX2NvbGxlY3Rvcl8gIT0gTlVMTCkgeworICAgIGVycm9yX2NvbGxlY3Rvcl8tPkFkZEVycm9yKGxpbmUsIGNvbHVtbiwgZXJyb3IpOworICB9CisgIGhhZF9lcnJvcnNfID0gdHJ1ZTsKK30KKwordm9pZCBQYXJzZXI6OkFkZEVycm9yKGNvbnN0IHN0cmluZyYgZXJyb3IpIHsKKyAgQWRkRXJyb3IoaW5wdXRfLT5jdXJyZW50KCkubGluZSwgaW5wdXRfLT5jdXJyZW50KCkuY29sdW1uLCBlcnJvcik7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworUGFyc2VyOjpMb2NhdGlvblJlY29yZGVyOjpMb2NhdGlvblJlY29yZGVyKFBhcnNlciogcGFyc2VyKQorICA6IHBhcnNlcl8ocGFyc2VyKSwKKyAgICBsb2NhdGlvbl8ocGFyc2VyXy0+c291cmNlX2NvZGVfaW5mb18tPmFkZF9sb2NhdGlvbigpKSB7CisgIGxvY2F0aW9uXy0+YWRkX3NwYW4ocGFyc2VyXy0+aW5wdXRfLT5jdXJyZW50KCkubGluZSk7CisgIGxvY2F0aW9uXy0+YWRkX3NwYW4ocGFyc2VyXy0+aW5wdXRfLT5jdXJyZW50KCkuY29sdW1uKTsKK30KKworUGFyc2VyOjpMb2NhdGlvblJlY29yZGVyOjpMb2NhdGlvblJlY29yZGVyKGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIHBhcmVudCkgeworICBJbml0KHBhcmVudCk7Cit9CisKK1BhcnNlcjo6TG9jYXRpb25SZWNvcmRlcjo6TG9jYXRpb25SZWNvcmRlcihjb25zdCBMb2NhdGlvblJlY29yZGVyJiBwYXJlbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHBhdGgxKSB7CisgIEluaXQocGFyZW50KTsKKyAgQWRkUGF0aChwYXRoMSk7Cit9CisKK1BhcnNlcjo6TG9jYXRpb25SZWNvcmRlcjo6TG9jYXRpb25SZWNvcmRlcihjb25zdCBMb2NhdGlvblJlY29yZGVyJiBwYXJlbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHBhdGgxLCBpbnQgcGF0aDIpIHsKKyAgSW5pdChwYXJlbnQpOworICBBZGRQYXRoKHBhdGgxKTsKKyAgQWRkUGF0aChwYXRoMik7Cit9CisKK3ZvaWQgUGFyc2VyOjpMb2NhdGlvblJlY29yZGVyOjpJbml0KGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIHBhcmVudCkgeworICBwYXJzZXJfID0gcGFyZW50LnBhcnNlcl87CisgIGxvY2F0aW9uXyA9IHBhcnNlcl8tPnNvdXJjZV9jb2RlX2luZm9fLT5hZGRfbG9jYXRpb24oKTsKKyAgbG9jYXRpb25fLT5tdXRhYmxlX3BhdGgoKS0+Q29weUZyb20ocGFyZW50LmxvY2F0aW9uXy0+cGF0aCgpKTsKKworICBsb2NhdGlvbl8tPmFkZF9zcGFuKHBhcnNlcl8tPmlucHV0Xy0+Y3VycmVudCgpLmxpbmUpOworICBsb2NhdGlvbl8tPmFkZF9zcGFuKHBhcnNlcl8tPmlucHV0Xy0+Y3VycmVudCgpLmNvbHVtbik7Cit9CisKK1BhcnNlcjo6TG9jYXRpb25SZWNvcmRlcjo6fkxvY2F0aW9uUmVjb3JkZXIoKSB7CisgIGlmIChsb2NhdGlvbl8tPnNwYW5fc2l6ZSgpIDw9IDIpIHsKKyAgICBFbmRBdChwYXJzZXJfLT5pbnB1dF8tPnByZXZpb3VzKCkpOworICB9Cit9CisKK3ZvaWQgUGFyc2VyOjpMb2NhdGlvblJlY29yZGVyOjpBZGRQYXRoKGludCBwYXRoX2NvbXBvbmVudCkgeworICBsb2NhdGlvbl8tPmFkZF9wYXRoKHBhdGhfY29tcG9uZW50KTsKK30KKwordm9pZCBQYXJzZXI6OkxvY2F0aW9uUmVjb3JkZXI6OlN0YXJ0QXQoY29uc3QgaW86OlRva2VuaXplcjo6VG9rZW4mIHRva2VuKSB7CisgIGxvY2F0aW9uXy0+c2V0X3NwYW4oMCwgdG9rZW4ubGluZSk7CisgIGxvY2F0aW9uXy0+c2V0X3NwYW4oMSwgdG9rZW4uY29sdW1uKTsKK30KKwordm9pZCBQYXJzZXI6OkxvY2F0aW9uUmVjb3JkZXI6OlN0YXJ0QXQoY29uc3QgTG9jYXRpb25SZWNvcmRlciYgb3RoZXIpIHsKKyAgbG9jYXRpb25fLT5zZXRfc3BhbigwLCBvdGhlci5sb2NhdGlvbl8tPnNwYW4oMCkpOworICBsb2NhdGlvbl8tPnNldF9zcGFuKDEsIG90aGVyLmxvY2F0aW9uXy0+c3BhbigxKSk7Cit9CisKK3ZvaWQgUGFyc2VyOjpMb2NhdGlvblJlY29yZGVyOjpFbmRBdChjb25zdCBpbzo6VG9rZW5pemVyOjpUb2tlbiYgdG9rZW4pIHsKKyAgaWYgKHRva2VuLmxpbmUgIT0gbG9jYXRpb25fLT5zcGFuKDApKSB7CisgICAgbG9jYXRpb25fLT5hZGRfc3Bhbih0b2tlbi5saW5lKTsKKyAgfQorICBsb2NhdGlvbl8tPmFkZF9zcGFuKHRva2VuLmVuZF9jb2x1bW4pOworfQorCit2b2lkIFBhcnNlcjo6TG9jYXRpb25SZWNvcmRlcjo6UmVjb3JkTGVnYWN5TG9jYXRpb24oY29uc3QgTWVzc2FnZSogZGVzY3JpcHRvciwKKyAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6OkVycm9yTG9jYXRpb24gbG9jYXRpb24pIHsKKyAgaWYgKHBhcnNlcl8tPnNvdXJjZV9sb2NhdGlvbl90YWJsZV8gIT0gTlVMTCkgeworICAgIHBhcnNlcl8tPnNvdXJjZV9sb2NhdGlvbl90YWJsZV8tPkFkZCgKKyAgICAgICAgZGVzY3JpcHRvciwgbG9jYXRpb24sIGxvY2F0aW9uXy0+c3BhbigwKSwgbG9jYXRpb25fLT5zcGFuKDEpKTsKKyAgfQorfQorCit2b2lkIFBhcnNlcjo6TG9jYXRpb25SZWNvcmRlcjo6QXR0YWNoQ29tbWVudHMoCisgICAgc3RyaW5nKiBsZWFkaW5nLCBzdHJpbmcqIHRyYWlsaW5nLAorICAgIHZlY3RvcjxzdHJpbmc+KiBkZXRhY2hlZF9jb21tZW50cykgY29uc3QgeworICBHT09HTEVfQ0hFQ0soIWxvY2F0aW9uXy0+aGFzX2xlYWRpbmdfY29tbWVudHMoKSk7CisgIEdPT0dMRV9DSEVDSyghbG9jYXRpb25fLT5oYXNfdHJhaWxpbmdfY29tbWVudHMoKSk7CisKKyAgaWYgKCFsZWFkaW5nLT5lbXB0eSgpKSB7CisgICAgbG9jYXRpb25fLT5tdXRhYmxlX2xlYWRpbmdfY29tbWVudHMoKS0+c3dhcCgqbGVhZGluZyk7CisgIH0KKyAgaWYgKCF0cmFpbGluZy0+ZW1wdHkoKSkgeworICAgIGxvY2F0aW9uXy0+bXV0YWJsZV90cmFpbGluZ19jb21tZW50cygpLT5zd2FwKCp0cmFpbGluZyk7CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXRhY2hlZF9jb21tZW50cy0+c2l6ZSgpOyArK2kpIHsKKyAgICBsb2NhdGlvbl8tPmFkZF9sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKCktPnN3YXAoCisgICAgICAgICgqZGV0YWNoZWRfY29tbWVudHMpW2ldKTsKKyAgfQorICBkZXRhY2hlZF9jb21tZW50cy0+Y2xlYXIoKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIFBhcnNlcjo6U2tpcFN0YXRlbWVudCgpIHsKKyAgd2hpbGUgKHRydWUpIHsKKyAgICBpZiAoQXRFbmQoKSkgeworICAgICAgcmV0dXJuOworICAgIH0gZWxzZSBpZiAoTG9va2luZ0F0VHlwZShpbzo6VG9rZW5pemVyOjpUWVBFX1NZTUJPTCkpIHsKKyAgICAgIGlmIChUcnlDb25zdW1lRW5kT2ZEZWNsYXJhdGlvbigiOyIsIE5VTEwpKSB7CisgICAgICAgIHJldHVybjsKKyAgICAgIH0gZWxzZSBpZiAoVHJ5Q29uc3VtZSgieyIpKSB7CisgICAgICAgIFNraXBSZXN0T2ZCbG9jaygpOworICAgICAgICByZXR1cm47CisgICAgICB9IGVsc2UgaWYgKExvb2tpbmdBdCgifSIpKSB7CisgICAgICAgIHJldHVybjsKKyAgICAgIH0KKyAgICB9CisgICAgaW5wdXRfLT5OZXh0KCk7CisgIH0KK30KKwordm9pZCBQYXJzZXI6OlNraXBSZXN0T2ZCbG9jaygpIHsKKyAgd2hpbGUgKHRydWUpIHsKKyAgICBpZiAoQXRFbmQoKSkgeworICAgICAgcmV0dXJuOworICAgIH0gZWxzZSBpZiAoTG9va2luZ0F0VHlwZShpbzo6VG9rZW5pemVyOjpUWVBFX1NZTUJPTCkpIHsKKyAgICAgIGlmIChUcnlDb25zdW1lRW5kT2ZEZWNsYXJhdGlvbigifSIsIE5VTEwpKSB7CisgICAgICAgIHJldHVybjsKKyAgICAgIH0gZWxzZSBpZiAoVHJ5Q29uc3VtZSgieyIpKSB7CisgICAgICAgIFNraXBSZXN0T2ZCbG9jaygpOworICAgICAgfQorICAgIH0KKyAgICBpbnB1dF8tPk5leHQoKTsKKyAgfQorfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK2Jvb2wgUGFyc2VyOjpWYWxpZGF0ZUVudW0oY29uc3QgRW51bURlc2NyaXB0b3JQcm90byogcHJvdG8pIHsKKyAgYm9vbCBoYXNfYWxsb3dfYWxpYXMgPSBmYWxzZTsKKyAgYm9vbCBhbGxvd19hbGlhcyA9IGZhbHNlOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgcHJvdG8tPm9wdGlvbnMoKS51bmludGVycHJldGVkX29wdGlvbl9zaXplKCk7IGkrKykgeworICAgIGNvbnN0IFVuaW50ZXJwcmV0ZWRPcHRpb24gb3B0aW9uID0gcHJvdG8tPm9wdGlvbnMoKS51bmludGVycHJldGVkX29wdGlvbihpKTsKKyAgICBpZiAob3B0aW9uLm5hbWVfc2l6ZSgpID4gMSkgeworICAgICAgY29udGludWU7CisgICAgfQorICAgIGlmICghb3B0aW9uLm5hbWUoMCkuaXNfZXh0ZW5zaW9uKCkgJiYKKyAgICAgICAgb3B0aW9uLm5hbWUoMCkubmFtZV9wYXJ0KCkgPT0gImFsbG93X2FsaWFzIikgeworICAgICAgaGFzX2FsbG93X2FsaWFzID0gdHJ1ZTsKKyAgICAgIGlmIChvcHRpb24uaWRlbnRpZmllcl92YWx1ZSgpID09ICJ0cnVlIikgeworICAgICAgICBhbGxvd19hbGlhcyA9IHRydWU7CisgICAgICB9CisgICAgICBicmVhazsKKyAgICB9CisgIH0KKworICBpZiAoaGFzX2FsbG93X2FsaWFzICYmICFhbGxvd19hbGlhcykgeworICAgIHN0cmluZyBlcnJvciA9CisgICAgICAgICJcIiIgKyBwcm90by0+bmFtZSgpICsKKyAgICAgICAgIlwiIGRlY2xhcmVzICdvcHRpb24gYWxsb3dfYWxpYXMgPSBmYWxzZTsnIHdoaWNoIGhhcyBubyBlZmZlY3QuICIKKyAgICAgICAgIlBsZWFzZSByZW1vdmUgdGhlIGRlY2xhcmF0aW9uLiI7CisgICAgLy8gVGhpcyBuZWVkbGVzc2x5IGNsdXR0ZXJzIGRlY2xhcmF0aW9ucyB3aXRoIG5vcHMuCisgICAgQWRkRXJyb3IoZXJyb3IpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIHNldDxpbnQ+IHVzZWRfdmFsdWVzOworICBib29sIGhhc19kdXBsaWNhdGVzID0gZmFsc2U7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgcHJvdG8tPnZhbHVlX3NpemUoKTsgKytpKSB7CisgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvIGVudW1fdmFsdWUgPSBwcm90by0+dmFsdWUoaSk7CisgICAgaWYgKHVzZWRfdmFsdWVzLmZpbmQoZW51bV92YWx1ZS5udW1iZXIoKSkgIT0gdXNlZF92YWx1ZXMuZW5kKCkpIHsKKyAgICAgIGhhc19kdXBsaWNhdGVzID0gdHJ1ZTsKKyAgICAgIGJyZWFrOworICAgIH0gZWxzZSB7CisgICAgICB1c2VkX3ZhbHVlcy5pbnNlcnQoZW51bV92YWx1ZS5udW1iZXIoKSk7CisgICAgfQorICB9CisgIGlmIChhbGxvd19hbGlhcyAmJiAhaGFzX2R1cGxpY2F0ZXMpIHsKKyAgICBzdHJpbmcgZXJyb3IgPQorICAgICAgICAiXCIiICsgcHJvdG8tPm5hbWUoKSArCisgICAgICAgICJcIiBkZWNsYXJlcyBzdXBwb3J0IGZvciBlbnVtIGFsaWFzZXMgYnV0IG5vIGVudW0gdmFsdWVzIHNoYXJlIGZpZWxkICIKKyAgICAgICAgIm51bWJlcnMuIFBsZWFzZSByZW1vdmUgdGhlIHVubmVjZXNzYXJ5ICdvcHRpb24gYWxsb3dfYWxpYXMgPSB0cnVlOycgIgorICAgICAgICAiZGVjbGFyYXRpb24uIjsKKyAgICAvLyBHZW5lcmF0ZSBhbiBlcnJvciBpZiBhbiBlbnVtIGRlY2xhcmVzIHN1cHBvcnQgZm9yIGR1cGxpY2F0ZSBlbnVtIHZhbHVlcworICAgIC8vIGFuZCBkb2VzIG5vdCB1c2UgaXQgcHJvdGVjdCBmdXR1cmUgYXV0aG9ycy4KKyAgICBBZGRFcnJvcihlcnJvcik7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgUGFyc2VyOjpQYXJzZShpbzo6VG9rZW5pemVyKiBpbnB1dCwgRmlsZURlc2NyaXB0b3JQcm90byogZmlsZSkgeworICBpbnB1dF8gPSBpbnB1dDsKKyAgaGFkX2Vycm9yc18gPSBmYWxzZTsKKyAgc3ludGF4X2lkZW50aWZpZXJfLmNsZWFyKCk7CisKKyAgLy8gTm90ZSB0aGF0IHxmaWxlfCBjb3VsZCBiZSBOVUxMIGF0IHRoaXMgcG9pbnQgaWYKKyAgLy8gc3RvcF9hZnRlcl9zeW50YXhfaWRlbnRpZmllcl8gaXMgdHJ1ZS4gIFNvLCB3ZSBjb25zZXJ2YXRpdmVseSBhbGxvY2F0ZQorICAvLyBTb3VyY2VDb2RlSW5mbyBvbiB0aGUgc3RhY2ssIHRoZW4gc3dhcCBpdCBpbnRvIHRoZSBGaWxlRGVzY3JpcHRvclByb3RvCisgIC8vIGxhdGVyIG9uLgorICBTb3VyY2VDb2RlSW5mbyBzb3VyY2VfY29kZV9pbmZvOworICBzb3VyY2VfY29kZV9pbmZvXyA9ICZzb3VyY2VfY29kZV9pbmZvOworCisgIHZlY3RvcjxzdHJpbmc+IHRvcF9kb2NfY29tbWVudHM7CisgIGlmIChMb29raW5nQXRUeXBlKGlvOjpUb2tlbml6ZXI6OlRZUEVfU1RBUlQpKSB7CisgICAgLy8gQWR2YW5jZSB0byBmaXJzdCB0b2tlbi4KKyAgICBpbnB1dF8tPk5leHRXaXRoQ29tbWVudHMoTlVMTCwgJnVwY29taW5nX2RldGFjaGVkX2NvbW1lbnRzXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnVwY29taW5nX2RvY19jb21tZW50c18pOworICB9CisKKyAgeworICAgIExvY2F0aW9uUmVjb3JkZXIgcm9vdF9sb2NhdGlvbih0aGlzKTsKKworICAgIGlmIChyZXF1aXJlX3N5bnRheF9pZGVudGlmaWVyXyB8fCBMb29raW5nQXQoInN5bnRheCIpKSB7CisgICAgICBpZiAoIVBhcnNlU3ludGF4SWRlbnRpZmllcihyb290X2xvY2F0aW9uKSkgeworICAgICAgICAvLyBEb24ndCBhdHRlbXB0IHRvIHBhcnNlIHRoZSBmaWxlIGlmIHdlIGRpZG4ndCByZWNvZ25pemUgdGhlIHN5bnRheAorICAgICAgICAvLyBpZGVudGlmaWVyLgorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgICAvLyBTdG9yZSB0aGUgc3ludGF4IGludG8gdGhlIGZpbGUuCisgICAgICBpZiAoZmlsZSAhPSBOVUxMKSBmaWxlLT5zZXRfc3ludGF4KHN5bnRheF9pZGVudGlmaWVyXyk7CisgICAgfSBlbHNlIGlmICghc3RvcF9hZnRlcl9zeW50YXhfaWRlbnRpZmllcl8pIHsKKyAgICAgIEdPT0dMRV9MT0coV0FSTklORykgPDwgIk5vIHN5bnRheCBzcGVjaWZpZWQgZm9yIHRoZSBwcm90byBmaWxlOiAiCisgICAgICAgICAgICAgICAgICAgPDwgZmlsZS0+bmFtZSgpIDw8ICIuIFBsZWFzZSB1c2UgJ3N5bnRheCA9IFwicHJvdG8yXCI7JyAiCisgICAgICAgICAgICAgICAgICAgPDwgIm9yICdzeW50YXggPSBcInByb3RvM1wiOycgdG8gc3BlY2lmeSBhIHN5bnRheCAiCisgICAgICAgICAgICAgICAgICAgPDwgInZlcnNpb24uIChEZWZhdWx0ZWQgdG8gcHJvdG8yIHN5bnRheC4pIjsKKyAgICAgIHN5bnRheF9pZGVudGlmaWVyXyA9ICJwcm90bzIiOworICAgIH0KKworICAgIGlmIChzdG9wX2FmdGVyX3N5bnRheF9pZGVudGlmaWVyXykgcmV0dXJuICFoYWRfZXJyb3JzXzsKKworICAgIC8vIFJlcGVhdGVkbHkgcGFyc2Ugc3RhdGVtZW50cyB1bnRpbCB3ZSByZWFjaCB0aGUgZW5kIG9mIHRoZSBmaWxlLgorICAgIHdoaWxlICghQXRFbmQoKSkgeworICAgICAgaWYgKCFQYXJzZVRvcExldmVsU3RhdGVtZW50KGZpbGUsIHJvb3RfbG9jYXRpb24pKSB7CisgICAgICAgIC8vIFRoaXMgc3RhdGVtZW50IGZhaWxlZCB0byBwYXJzZS4gIFNraXAgaXQsIGJ1dCBrZWVwIGxvb3BpbmcgdG8gcGFyc2UKKyAgICAgICAgLy8gb3RoZXIgc3RhdGVtZW50cy4KKyAgICAgICAgU2tpcFN0YXRlbWVudCgpOworCisgICAgICAgIGlmIChMb29raW5nQXQoIn0iKSkgeworICAgICAgICAgIEFkZEVycm9yKCJVbm1hdGNoZWQgXCJ9XCIuIik7CisgICAgICAgICAgaW5wdXRfLT5OZXh0V2l0aENvbW1lbnRzKE5VTEwsICZ1cGNvbWluZ19kZXRhY2hlZF9jb21tZW50c18sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ1cGNvbWluZ19kb2NfY29tbWVudHNfKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgfQorCisgIGlucHV0XyA9IE5VTEw7CisgIHNvdXJjZV9jb2RlX2luZm9fID0gTlVMTDsKKyAgc291cmNlX2NvZGVfaW5mby5Td2FwKGZpbGUtPm11dGFibGVfc291cmNlX2NvZGVfaW5mbygpKTsKKyAgcmV0dXJuICFoYWRfZXJyb3JzXzsKK30KKworYm9vbCBQYXJzZXI6OlBhcnNlU3ludGF4SWRlbnRpZmllcihjb25zdCBMb2NhdGlvblJlY29yZGVyJiBwYXJlbnQpIHsKKyAgTG9jYXRpb25SZWNvcmRlciBzeW50YXhfbG9jYXRpb24ocGFyZW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlRGVzY3JpcHRvclByb3RvOjprU3ludGF4RmllbGROdW1iZXIpOworICBETyhDb25zdW1lKAorICAgICAgInN5bnRheCIsCisgICAgICAiRmlsZSBtdXN0IGJlZ2luIHdpdGggYSBzeW50YXggc3RhdGVtZW50LCBlLmcuICdzeW50YXggPSBcInByb3RvMlwiOycuIikpOworICBETyhDb25zdW1lKCI9IikpOworICBpbzo6VG9rZW5pemVyOjpUb2tlbiBzeW50YXhfdG9rZW4gPSBpbnB1dF8tPmN1cnJlbnQoKTsKKyAgc3RyaW5nIHN5bnRheDsKKyAgRE8oQ29uc3VtZVN0cmluZygmc3ludGF4LCAiRXhwZWN0ZWQgc3ludGF4IGlkZW50aWZpZXIuIikpOworICBETyhDb25zdW1lRW5kT2ZEZWNsYXJhdGlvbigiOyIsICZzeW50YXhfbG9jYXRpb24pKTsKKworICBzeW50YXhfaWRlbnRpZmllcl8gPSBzeW50YXg7CisKKyAgaWYgKHN5bnRheCAhPSAicHJvdG8yIiAmJiBzeW50YXggIT0gInByb3RvMyIgJiYKKyAgICAgICFzdG9wX2FmdGVyX3N5bnRheF9pZGVudGlmaWVyXykgeworICAgIEFkZEVycm9yKHN5bnRheF90b2tlbi5saW5lLCBzeW50YXhfdG9rZW4uY29sdW1uLAorICAgICAgIlVucmVjb2duaXplZCBzeW50YXggaWRlbnRpZmllciBcIiIgKyBzeW50YXggKyAiXCIuICBUaGlzIHBhcnNlciAiCisgICAgICAib25seSByZWNvZ25pemVzIFwicHJvdG8yXCIgYW5kIFwicHJvdG8zXCIuIik7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgUGFyc2VyOjpQYXJzZVRvcExldmVsU3RhdGVtZW50KEZpbGVEZXNjcmlwdG9yUHJvdG8qIGZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiByb290X2xvY2F0aW9uKSB7CisgIGlmIChUcnlDb25zdW1lRW5kT2ZEZWNsYXJhdGlvbigiOyIsIE5VTEwpKSB7CisgICAgLy8gZW1wdHkgc3RhdGVtZW50OyBpZ25vcmUKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfSBlbHNlIGlmIChMb29raW5nQXQoIm1lc3NhZ2UiKSkgeworICAgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24ocm9vdF9sb2NhdGlvbiwKKyAgICAgIEZpbGVEZXNjcmlwdG9yUHJvdG86OmtNZXNzYWdlVHlwZUZpZWxkTnVtYmVyLCBmaWxlLT5tZXNzYWdlX3R5cGVfc2l6ZSgpKTsKKyAgICByZXR1cm4gUGFyc2VNZXNzYWdlRGVmaW5pdGlvbihmaWxlLT5hZGRfbWVzc2FnZV90eXBlKCksIGxvY2F0aW9uLCBmaWxlKTsKKyAgfSBlbHNlIGlmIChMb29raW5nQXQoImVudW0iKSkgeworICAgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24ocm9vdF9sb2NhdGlvbiwKKyAgICAgIEZpbGVEZXNjcmlwdG9yUHJvdG86OmtFbnVtVHlwZUZpZWxkTnVtYmVyLCBmaWxlLT5lbnVtX3R5cGVfc2l6ZSgpKTsKKyAgICByZXR1cm4gUGFyc2VFbnVtRGVmaW5pdGlvbihmaWxlLT5hZGRfZW51bV90eXBlKCksIGxvY2F0aW9uLCBmaWxlKTsKKyAgfSBlbHNlIGlmIChMb29raW5nQXQoInNlcnZpY2UiKSkgeworICAgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24ocm9vdF9sb2NhdGlvbiwKKyAgICAgIEZpbGVEZXNjcmlwdG9yUHJvdG86OmtTZXJ2aWNlRmllbGROdW1iZXIsIGZpbGUtPnNlcnZpY2Vfc2l6ZSgpKTsKKyAgICByZXR1cm4gUGFyc2VTZXJ2aWNlRGVmaW5pdGlvbihmaWxlLT5hZGRfc2VydmljZSgpLCBsb2NhdGlvbiwgZmlsZSk7CisgIH0gZWxzZSBpZiAoTG9va2luZ0F0KCJleHRlbmQiKSkgeworICAgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24ocm9vdF9sb2NhdGlvbiwKKyAgICAgICAgRmlsZURlc2NyaXB0b3JQcm90bzo6a0V4dGVuc2lvbkZpZWxkTnVtYmVyKTsKKyAgICByZXR1cm4gUGFyc2VFeHRlbmQoZmlsZS0+bXV0YWJsZV9leHRlbnNpb24oKSwKKyAgICAgICAgICAgICAgICAgICAgICAgZmlsZS0+bXV0YWJsZV9tZXNzYWdlX3R5cGUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgcm9vdF9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgRmlsZURlc2NyaXB0b3JQcm90bzo6a01lc3NhZ2VUeXBlRmllbGROdW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgIGxvY2F0aW9uLCBmaWxlKTsKKyAgfSBlbHNlIGlmIChMb29raW5nQXQoImltcG9ydCIpKSB7CisgICAgcmV0dXJuIFBhcnNlSW1wb3J0KGZpbGUtPm11dGFibGVfZGVwZW5kZW5jeSgpLAorICAgICAgICAgICAgICAgICAgICAgICBmaWxlLT5tdXRhYmxlX3B1YmxpY19kZXBlbmRlbmN5KCksCisgICAgICAgICAgICAgICAgICAgICAgIGZpbGUtPm11dGFibGVfd2Vha19kZXBlbmRlbmN5KCksCisgICAgICAgICAgICAgICAgICAgICAgIHJvb3RfbG9jYXRpb24sIGZpbGUpOworICB9IGVsc2UgaWYgKExvb2tpbmdBdCgicGFja2FnZSIpKSB7CisgICAgcmV0dXJuIFBhcnNlUGFja2FnZShmaWxlLCByb290X2xvY2F0aW9uLCBmaWxlKTsKKyAgfSBlbHNlIGlmIChMb29raW5nQXQoIm9wdGlvbiIpKSB7CisgICAgTG9jYXRpb25SZWNvcmRlciBsb2NhdGlvbihyb290X2xvY2F0aW9uLAorICAgICAgICBGaWxlRGVzY3JpcHRvclByb3RvOjprT3B0aW9uc0ZpZWxkTnVtYmVyKTsKKyAgICByZXR1cm4gUGFyc2VPcHRpb24oZmlsZS0+bXV0YWJsZV9vcHRpb25zKCksIGxvY2F0aW9uLCBmaWxlLAorICAgICAgICAgICAgICAgICAgICAgICBPUFRJT05fU1RBVEVNRU5UKTsKKyAgfSBlbHNlIHsKKyAgICBBZGRFcnJvcigiRXhwZWN0ZWQgdG9wLWxldmVsIHN0YXRlbWVudCAoZS5nLiBcIm1lc3NhZ2VcIikuIik7CisgICAgcmV0dXJuIGZhbHNlOworICB9Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIE1lc3NhZ2VzCisKK2Jvb2wgUGFyc2VyOjpQYXJzZU1lc3NhZ2VEZWZpbml0aW9uKAorICAgIERlc2NyaXB0b3JQcm90byogbWVzc2FnZSwKKyAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiBtZXNzYWdlX2xvY2F0aW9uLAorICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfZmlsZSkgeworICBETyhDb25zdW1lKCJtZXNzYWdlIikpOworICB7CisgICAgTG9jYXRpb25SZWNvcmRlciBsb2NhdGlvbihtZXNzYWdlX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVzY3JpcHRvclByb3RvOjprTmFtZUZpZWxkTnVtYmVyKTsKKyAgICBsb2NhdGlvbi5SZWNvcmRMZWdhY3lMb2NhdGlvbigKKyAgICAgICAgbWVzc2FnZSwgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpOQU1FKTsKKyAgICBETyhDb25zdW1lSWRlbnRpZmllcihtZXNzYWdlLT5tdXRhYmxlX25hbWUoKSwgIkV4cGVjdGVkIG1lc3NhZ2UgbmFtZS4iKSk7CisgIH0KKyAgRE8oUGFyc2VNZXNzYWdlQmxvY2sobWVzc2FnZSwgbWVzc2FnZV9sb2NhdGlvbiwgY29udGFpbmluZ19maWxlKSk7CisgIHJldHVybiB0cnVlOworfQorCituYW1lc3BhY2UgeworCitjb25zdCBpbnQga01heEV4dGVuc2lvblJhbmdlU2VudGluZWwgPSAtMTsKKworYm9vbCBJc01lc3NhZ2VTZXRXaXJlRm9ybWF0TWVzc2FnZShjb25zdCBEZXNjcmlwdG9yUHJvdG8mIG1lc3NhZ2UpIHsKKyAgY29uc3QgTWVzc2FnZU9wdGlvbnMmIG9wdGlvbnMgPSBtZXNzYWdlLm9wdGlvbnMoKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBvcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uX3NpemUoKTsgKytpKSB7CisgICAgY29uc3QgVW5pbnRlcnByZXRlZE9wdGlvbiYgdW5pbnRlcnByZXRlZCA9IG9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24oaSk7CisgICAgaWYgKHVuaW50ZXJwcmV0ZWQubmFtZV9zaXplKCkgPT0gMSAmJgorICAgICAgICB1bmludGVycHJldGVkLm5hbWUoMCkubmFtZV9wYXJ0KCkgPT0gIm1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0IiAmJgorICAgICAgICB1bmludGVycHJldGVkLmlkZW50aWZpZXJfdmFsdWUoKSA9PSAidHJ1ZSIpIHsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgfQorICByZXR1cm4gZmFsc2U7Cit9CisKKy8vIE1vZGlmaWVzIGFueSBleHRlbnNpb24gcmFuZ2VzIHRoYXQgc3BlY2lmaWVkICdtYXgnIGFzIHRoZSBlbmQgb2YgdGhlCisvLyBleHRlbnNpb24gcmFuZ2UsIGFuZCBzZXRzIHRoZW0gdG8gdGhlIHR5cGUtc3BlY2lmaWMgbWF4aW11bS4gVGhlIGFjdHVhbCBtYXgKKy8vIHRhZyBudW1iZXIgY2FuIG9ubHkgYmUgZGV0ZXJtaW5lZCBhZnRlciBhbGwgb3B0aW9ucyBoYXZlIGJlZW4gcGFyc2VkLgordm9pZCBBZGp1c3RFeHRlbnNpb25SYW5nZXNXaXRoTWF4RW5kTnVtYmVyKERlc2NyaXB0b3JQcm90byogbWVzc2FnZSkgeworICBjb25zdCBib29sIGlzX21lc3NhZ2Vfc2V0ID0gSXNNZXNzYWdlU2V0V2lyZUZvcm1hdE1lc3NhZ2UoKm1lc3NhZ2UpOworICBjb25zdCBpbnQgbWF4X2V4dGVuc2lvbl9udW1iZXIgPSBpc19tZXNzYWdlX3NldCA/CisgICAgICBraW50MzJtYXggOgorICAgICAgRmllbGREZXNjcmlwdG9yOjprTWF4TnVtYmVyICsgMTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZXNzYWdlLT5leHRlbnNpb25fcmFuZ2Vfc2l6ZSgpOyArK2kpIHsKKyAgICBpZiAobWVzc2FnZS0+ZXh0ZW5zaW9uX3JhbmdlKGkpLmVuZCgpID09IGtNYXhFeHRlbnNpb25SYW5nZVNlbnRpbmVsKSB7CisgICAgICBtZXNzYWdlLT5tdXRhYmxlX2V4dGVuc2lvbl9yYW5nZShpKS0+c2V0X2VuZChtYXhfZXh0ZW5zaW9uX251bWJlcik7CisgICAgfQorICB9Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCitib29sIFBhcnNlcjo6UGFyc2VNZXNzYWdlQmxvY2soRGVzY3JpcHRvclByb3RvKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIG1lc3NhZ2VfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byogY29udGFpbmluZ19maWxlKSB7CisgIERPKENvbnN1bWVFbmRPZkRlY2xhcmF0aW9uKCJ7IiwgJm1lc3NhZ2VfbG9jYXRpb24pKTsKKworICB3aGlsZSAoIVRyeUNvbnN1bWVFbmRPZkRlY2xhcmF0aW9uKCJ9IiwgTlVMTCkpIHsKKyAgICBpZiAoQXRFbmQoKSkgeworICAgICAgQWRkRXJyb3IoIlJlYWNoZWQgZW5kIG9mIGlucHV0IGluIG1lc3NhZ2UgZGVmaW5pdGlvbiAobWlzc2luZyAnfScpLiIpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIGlmICghUGFyc2VNZXNzYWdlU3RhdGVtZW50KG1lc3NhZ2UsIG1lc3NhZ2VfbG9jYXRpb24sIGNvbnRhaW5pbmdfZmlsZSkpIHsKKyAgICAgIC8vIFRoaXMgc3RhdGVtZW50IGZhaWxlZCB0byBwYXJzZS4gIFNraXAgaXQsIGJ1dCBrZWVwIGxvb3BpbmcgdG8gcGFyc2UKKyAgICAgIC8vIG90aGVyIHN0YXRlbWVudHMuCisgICAgICBTa2lwU3RhdGVtZW50KCk7CisgICAgfQorICB9CisKKyAgaWYgKG1lc3NhZ2UtPmV4dGVuc2lvbl9yYW5nZV9zaXplKCkgPiAwKSB7CisgICAgQWRqdXN0RXh0ZW5zaW9uUmFuZ2VzV2l0aE1heEVuZE51bWJlcihtZXNzYWdlKTsKKyAgfQorICByZXR1cm4gdHJ1ZTsKK30KKworYm9vbCBQYXJzZXI6OlBhcnNlTWVzc2FnZVN0YXRlbWVudChEZXNjcmlwdG9yUHJvdG8qIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIG1lc3NhZ2VfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfZmlsZSkgeworICBpZiAoVHJ5Q29uc3VtZUVuZE9mRGVjbGFyYXRpb24oIjsiLCBOVUxMKSkgeworICAgIC8vIGVtcHR5IHN0YXRlbWVudDsgaWdub3JlCisgICAgcmV0dXJuIHRydWU7CisgIH0gZWxzZSBpZiAoTG9va2luZ0F0KCJtZXNzYWdlIikpIHsKKyAgICBMb2NhdGlvblJlY29yZGVyIGxvY2F0aW9uKG1lc3NhZ2VfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZXNjcmlwdG9yUHJvdG86OmtOZXN0ZWRUeXBlRmllbGROdW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLT5uZXN0ZWRfdHlwZV9zaXplKCkpOworICAgIHJldHVybiBQYXJzZU1lc3NhZ2VEZWZpbml0aW9uKG1lc3NhZ2UtPmFkZF9uZXN0ZWRfdHlwZSgpLCBsb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250YWluaW5nX2ZpbGUpOworICB9IGVsc2UgaWYgKExvb2tpbmdBdCgiZW51bSIpKSB7CisgICAgTG9jYXRpb25SZWNvcmRlciBsb2NhdGlvbihtZXNzYWdlX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVzY3JpcHRvclByb3RvOjprRW51bVR5cGVGaWVsZE51bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UtPmVudW1fdHlwZV9zaXplKCkpOworICAgIHJldHVybiBQYXJzZUVudW1EZWZpbml0aW9uKG1lc3NhZ2UtPmFkZF9lbnVtX3R5cGUoKSwgbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGFpbmluZ19maWxlKTsKKyAgfSBlbHNlIGlmIChMb29raW5nQXQoImV4dGVuc2lvbnMiKSkgeworICAgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24obWVzc2FnZV9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlc2NyaXB0b3JQcm90bzo6a0V4dGVuc2lvblJhbmdlRmllbGROdW1iZXIpOworICAgIHJldHVybiBQYXJzZUV4dGVuc2lvbnMobWVzc2FnZSwgbG9jYXRpb24sIGNvbnRhaW5pbmdfZmlsZSk7CisgIH0gZWxzZSBpZiAoTG9va2luZ0F0KCJyZXNlcnZlZCIpKSB7CisgICAgcmV0dXJuIFBhcnNlUmVzZXJ2ZWQobWVzc2FnZSwgbWVzc2FnZV9sb2NhdGlvbik7CisgIH0gZWxzZSBpZiAoTG9va2luZ0F0KCJleHRlbmQiKSkgeworICAgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24obWVzc2FnZV9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlc2NyaXB0b3JQcm90bzo6a0V4dGVuc2lvbkZpZWxkTnVtYmVyKTsKKyAgICByZXR1cm4gUGFyc2VFeHRlbmQobWVzc2FnZS0+bXV0YWJsZV9leHRlbnNpb24oKSwKKyAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS0+bXV0YWJsZV9uZXN0ZWRfdHlwZSgpLAorICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICBEZXNjcmlwdG9yUHJvdG86OmtOZXN0ZWRUeXBlRmllbGROdW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgIGxvY2F0aW9uLCBjb250YWluaW5nX2ZpbGUpOworICB9IGVsc2UgaWYgKExvb2tpbmdBdCgib3B0aW9uIikpIHsKKyAgICBMb2NhdGlvblJlY29yZGVyIGxvY2F0aW9uKG1lc3NhZ2VfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZXNjcmlwdG9yUHJvdG86OmtPcHRpb25zRmllbGROdW1iZXIpOworICAgIHJldHVybiBQYXJzZU9wdGlvbihtZXNzYWdlLT5tdXRhYmxlX29wdGlvbnMoKSwgbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgIGNvbnRhaW5pbmdfZmlsZSwgT1BUSU9OX1NUQVRFTUVOVCk7CisgIH0gZWxzZSBpZiAoTG9va2luZ0F0KCJvbmVvZiIpKSB7CisgICAgaW50IG9uZW9mX2luZGV4ID0gbWVzc2FnZS0+b25lb2ZfZGVjbF9zaXplKCk7CisgICAgTG9jYXRpb25SZWNvcmRlciBvbmVvZl9sb2NhdGlvbihtZXNzYWdlX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVzY3JpcHRvclByb3RvOjprT25lb2ZEZWNsRmllbGROdW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbmVvZl9pbmRleCk7CisKKyAgICByZXR1cm4gUGFyc2VPbmVvZihtZXNzYWdlLT5hZGRfb25lb2ZfZGVjbCgpLCBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgIG9uZW9mX2luZGV4LCBvbmVvZl9sb2NhdGlvbiwgbWVzc2FnZV9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICBjb250YWluaW5nX2ZpbGUpOworICB9IGVsc2UgeworICAgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24obWVzc2FnZV9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlc2NyaXB0b3JQcm90bzo6a0ZpZWxkRmllbGROdW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLT5maWVsZF9zaXplKCkpOworICAgIHJldHVybiBQYXJzZU1lc3NhZ2VGaWVsZChtZXNzYWdlLT5hZGRfZmllbGQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS0+bXV0YWJsZV9uZXN0ZWRfdHlwZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZXNjcmlwdG9yUHJvdG86OmtOZXN0ZWRUeXBlRmllbGROdW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250YWluaW5nX2ZpbGUpOworICB9Cit9CisKK2Jvb2wgUGFyc2VyOjpQYXJzZU1lc3NhZ2VGaWVsZChGaWVsZERlc2NyaXB0b3JQcm90byogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVwZWF0ZWRQdHJGaWVsZDxEZXNjcmlwdG9yUHJvdG8+KiBtZXNzYWdlcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiBwYXJlbnRfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGxvY2F0aW9uX2ZpZWxkX251bWJlcl9mb3JfbmVzdGVkX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTG9jYXRpb25SZWNvcmRlciYgZmllbGRfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byogY29udGFpbmluZ19maWxlKSB7CisgIHsKKyAgICBMb2NhdGlvblJlY29yZGVyIGxvY2F0aW9uKGZpZWxkX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OmtMYWJlbEZpZWxkTnVtYmVyKTsKKyAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6TGFiZWwgbGFiZWw7CisgICAgaWYgKFBhcnNlTGFiZWwoJmxhYmVsLCBjb250YWluaW5nX2ZpbGUpKSB7CisgICAgICBmaWVsZC0+c2V0X2xhYmVsKGxhYmVsKTsKKyAgICAgIGlmIChsYWJlbCA9PSBGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfT1BUSU9OQUwgJiYKKyAgICAgICAgICBzeW50YXhfaWRlbnRpZmllcl8gPT0gInByb3RvMyIpIHsKKyAgICAgICAgQWRkRXJyb3IoCisgICAgICAgICAgICAiRXhwbGljaXQgJ29wdGlvbmFsJyBsYWJlbHMgYXJlIGRpc2FsbG93ZWQgaW4gdGhlIFByb3RvMyBzeW50YXguICIKKyAgICAgICAgICAgICJUbyBkZWZpbmUgJ29wdGlvbmFsJyBmaWVsZHMgaW4gUHJvdG8zLCBzaW1wbHkgcmVtb3ZlIHRoZSAiCisgICAgICAgICAgICAiJ29wdGlvbmFsJyBsYWJlbCwgYXMgZmllbGRzIGFyZSAnb3B0aW9uYWwnIGJ5IGRlZmF1bHQuIik7CisgICAgICB9CisgICAgfQorICB9CisKKyAgcmV0dXJuIFBhcnNlTWVzc2FnZUZpZWxkTm9MYWJlbChmaWVsZCwgbWVzc2FnZXMsIHBhcmVudF9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhdGlvbl9maWVsZF9udW1iZXJfZm9yX25lc3RlZF90eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRhaW5pbmdfZmlsZSk7Cit9CisKK2Jvb2wgUGFyc2VyOjpQYXJzZU1lc3NhZ2VGaWVsZE5vTGFiZWwoCisgICAgRmllbGREZXNjcmlwdG9yUHJvdG8qIGZpZWxkLAorICAgIFJlcGVhdGVkUHRyRmllbGQ8RGVzY3JpcHRvclByb3RvPiogbWVzc2FnZXMsCisgICAgY29uc3QgTG9jYXRpb25SZWNvcmRlciYgcGFyZW50X2xvY2F0aW9uLAorICAgIGludCBsb2NhdGlvbl9maWVsZF9udW1iZXJfZm9yX25lc3RlZF90eXBlLAorICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIGZpZWxkX2xvY2F0aW9uLAorICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfZmlsZSkgeworICBNYXBGaWVsZCBtYXBfZmllbGQ7CisgIC8vIFBhcnNlIHR5cGUuCisgIHsKKyAgICBMb2NhdGlvblJlY29yZGVyIGxvY2F0aW9uKGZpZWxkX2xvY2F0aW9uKTsgIC8vIGFkZCBwYXRoIGxhdGVyCisgICAgbG9jYXRpb24uUmVjb3JkTGVnYWN5TG9jYXRpb24oZmllbGQsIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6VFlQRSk7CisKKyAgICBib29sIHR5cGVfcGFyc2VkID0gZmFsc2U7CisgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OlR5cGUgdHlwZSA9IEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0lOVDMyOworICAgIHN0cmluZyB0eXBlX25hbWU7CisKKyAgICAvLyBTcGVjaWFsIGNhc2UgbWFwIGZpZWxkLiBXZSBvbmx5IHRyZWF0IHRoZSBmaWVsZCBhcyBhIG1hcCBmaWVsZCBpZiB0aGUKKyAgICAvLyBmaWVsZCB0eXBlIG5hbWUgc3RhcnRzIHdpdGggdGhlIHdvcmQgIm1hcCIgd2l0aCBhIGZvbGxvd2luZyAiPCIuCisgICAgaWYgKFRyeUNvbnN1bWUoIm1hcCIpKSB7CisgICAgICBpZiAoTG9va2luZ0F0KCI8IikpIHsKKyAgICAgICAgbWFwX2ZpZWxkLmlzX21hcF9maWVsZCA9IHRydWU7CisgICAgICB9IGVsc2UgeworICAgICAgICAvLyBGYWxzZSBwb3NpdGl2ZQorICAgICAgICB0eXBlX3BhcnNlZCA9IHRydWU7CisgICAgICAgIHR5cGVfbmFtZSA9ICJtYXAiOworICAgICAgfQorICAgIH0KKyAgICBpZiAobWFwX2ZpZWxkLmlzX21hcF9maWVsZCkgeworICAgICAgaWYgKGZpZWxkLT5oYXNfb25lb2ZfaW5kZXgoKSkgeworICAgICAgICBBZGRFcnJvcigiTWFwIGZpZWxkcyBhcmUgbm90IGFsbG93ZWQgaW4gb25lb2ZzLiIpOworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgICBpZiAoZmllbGQtPmhhc19sYWJlbCgpKSB7CisgICAgICAgIEFkZEVycm9yKAorICAgICAgICAgICAgIkZpZWxkIGxhYmVscyAocmVxdWlyZWQvb3B0aW9uYWwvcmVwZWF0ZWQpIGFyZSBub3QgYWxsb3dlZCBvbiAiCisgICAgICAgICAgICAibWFwIGZpZWxkcy4iKTsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgICAgaWYgKGZpZWxkLT5oYXNfZXh0ZW5kZWUoKSkgeworICAgICAgICBBZGRFcnJvcigiTWFwIGZpZWxkcyBhcmUgbm90IGFsbG93ZWQgdG8gYmUgZXh0ZW5zaW9ucy4iKTsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgICAgZmllbGQtPnNldF9sYWJlbChGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfUkVQRUFURUQpOworICAgICAgRE8oQ29uc3VtZSgiPCIpKTsKKyAgICAgIERPKFBhcnNlVHlwZSgmbWFwX2ZpZWxkLmtleV90eXBlLCAmbWFwX2ZpZWxkLmtleV90eXBlX25hbWUpKTsKKyAgICAgIERPKENvbnN1bWUoIiwiKSk7CisgICAgICBETyhQYXJzZVR5cGUoJm1hcF9maWVsZC52YWx1ZV90eXBlLCAmbWFwX2ZpZWxkLnZhbHVlX3R5cGVfbmFtZSkpOworICAgICAgRE8oQ29uc3VtZSgiPiIpKTsKKyAgICAgIC8vIERlZmVyIHNldHRpbmcgb2YgdGhlIHR5cGUgbmFtZSBvZiB0aGUgbWFwIGZpZWxkIHVudGlsIHRoZQorICAgICAgLy8gZmllbGQgbmFtZSBpcyBwYXJzZWQuIEFkZCB0aGUgc291cmNlIGxvY2F0aW9uIHRob3VnaC4KKyAgICAgIGxvY2F0aW9uLkFkZFBhdGgoRmllbGREZXNjcmlwdG9yUHJvdG86OmtUeXBlTmFtZUZpZWxkTnVtYmVyKTsKKyAgICB9IGVsc2UgeworICAgICAgLy8gSGFuZGxlIHRoZSBjYXNlIHdoZXJlIG5vIGV4cGxpY2l0IGxhYmVsIGlzIGdpdmVuIGZvciBhIG5vbi1tYXAgZmllbGQuCisgICAgICBpZiAoIWZpZWxkLT5oYXNfbGFiZWwoKSAmJiBEZWZhdWx0VG9PcHRpb25hbEZpZWxkcygpKSB7CisgICAgICAgIGZpZWxkLT5zZXRfbGFiZWwoRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX09QVElPTkFMKTsKKyAgICAgIH0KKyAgICAgIGlmICghZmllbGQtPmhhc19sYWJlbCgpKSB7CisgICAgICAgIEFkZEVycm9yKCJFeHBlY3RlZCBcInJlcXVpcmVkXCIsIFwib3B0aW9uYWxcIiwgb3IgXCJyZXBlYXRlZFwiLiIpOworICAgICAgICAvLyBXZSBjYW4gYWN0dWFsbHkgcmVhc29uYWJseSByZWNvdmVyIGhlcmUgYnkganVzdCBhc3N1bWluZyB0aGUgdXNlcgorICAgICAgICAvLyBmb3Jnb3QgdGhlIGxhYmVsIGFsdG9nZXRoZXIuCisgICAgICAgIGZpZWxkLT5zZXRfbGFiZWwoRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX09QVElPTkFMKTsKKyAgICAgIH0KKworICAgICAgLy8gSGFuZGxlIHRoZSBjYXNlIHdoZXJlIHRoZSBhY3R1YWwgdHlwZSBpcyBhIG1lc3NhZ2Ugb3IgZW51bSBuYW1lZCAibWFwIiwKKyAgICAgIC8vIHdoaWNoIHdlIGFscmVhZHkgY29uc3VtZWQgaW4gdGhlIGNvZGUgYWJvdmUuCisgICAgICBpZiAoIXR5cGVfcGFyc2VkKSB7CisgICAgICAgIERPKFBhcnNlVHlwZSgmdHlwZSwgJnR5cGVfbmFtZSkpOworICAgICAgfQorICAgICAgaWYgKHR5cGVfbmFtZS5lbXB0eSgpKSB7CisgICAgICAgIGxvY2F0aW9uLkFkZFBhdGgoRmllbGREZXNjcmlwdG9yUHJvdG86OmtUeXBlRmllbGROdW1iZXIpOworICAgICAgICBmaWVsZC0+c2V0X3R5cGUodHlwZSk7CisgICAgICB9IGVsc2UgeworICAgICAgICBsb2NhdGlvbi5BZGRQYXRoKEZpZWxkRGVzY3JpcHRvclByb3RvOjprVHlwZU5hbWVGaWVsZE51bWJlcik7CisgICAgICAgIGZpZWxkLT5zZXRfdHlwZV9uYW1lKHR5cGVfbmFtZSk7CisgICAgICB9CisgICAgfQorICB9CisKKyAgLy8gUGFyc2UgbmFtZSBhbmQgJz0nLgorICBpbzo6VG9rZW5pemVyOjpUb2tlbiBuYW1lX3Rva2VuID0gaW5wdXRfLT5jdXJyZW50KCk7CisgIHsKKyAgICBMb2NhdGlvblJlY29yZGVyIGxvY2F0aW9uKGZpZWxkX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OmtOYW1lRmllbGROdW1iZXIpOworICAgIGxvY2F0aW9uLlJlY29yZExlZ2FjeUxvY2F0aW9uKGZpZWxkLCBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok5BTUUpOworICAgIERPKENvbnN1bWVJZGVudGlmaWVyKGZpZWxkLT5tdXRhYmxlX25hbWUoKSwgIkV4cGVjdGVkIGZpZWxkIG5hbWUuIikpOworICB9CisgIERPKENvbnN1bWUoIj0iLCAiTWlzc2luZyBmaWVsZCBudW1iZXIuIikpOworCisgIC8vIFBhcnNlIGZpZWxkIG51bWJlci4KKyAgeworICAgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24oZmllbGRfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6a051bWJlckZpZWxkTnVtYmVyKTsKKyAgICBsb2NhdGlvbi5SZWNvcmRMZWdhY3lMb2NhdGlvbigKKyAgICAgICAgZmllbGQsIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6TlVNQkVSKTsKKyAgICBpbnQgbnVtYmVyOworICAgIERPKENvbnN1bWVJbnRlZ2VyKCZudW1iZXIsICJFeHBlY3RlZCBmaWVsZCBudW1iZXIuIikpOworICAgIGZpZWxkLT5zZXRfbnVtYmVyKG51bWJlcik7CisgIH0KKworICAvLyBQYXJzZSBvcHRpb25zLgorICBETyhQYXJzZUZpZWxkT3B0aW9ucyhmaWVsZCwgZmllbGRfbG9jYXRpb24sIGNvbnRhaW5pbmdfZmlsZSkpOworCisgIC8vIERlYWwgd2l0aCBncm91cHMuCisgIGlmIChmaWVsZC0+aGFzX3R5cGUoKSAmJiBmaWVsZC0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0dST1VQKSB7CisgICAgLy8gQXdrd2FyZDogIFNpbmNlIGEgZ3JvdXAgZGVjbGFyZXMgYm90aCBhIG1lc3NhZ2UgdHlwZSBhbmQgYSBmaWVsZCwgd2UKKyAgICAvLyAgIGhhdmUgdG8gY3JlYXRlIG92ZXJsYXBwaW5nIGxvY2F0aW9ucy4KKyAgICBMb2NhdGlvblJlY29yZGVyIGdyb3VwX2xvY2F0aW9uKHBhcmVudF9sb2NhdGlvbik7CisgICAgZ3JvdXBfbG9jYXRpb24uU3RhcnRBdChmaWVsZF9sb2NhdGlvbik7CisgICAgZ3JvdXBfbG9jYXRpb24uQWRkUGF0aChsb2NhdGlvbl9maWVsZF9udW1iZXJfZm9yX25lc3RlZF90eXBlKTsKKyAgICBncm91cF9sb2NhdGlvbi5BZGRQYXRoKG1lc3NhZ2VzLT5zaXplKCkpOworCisgICAgRGVzY3JpcHRvclByb3RvKiBncm91cCA9IG1lc3NhZ2VzLT5BZGQoKTsKKyAgICBncm91cC0+c2V0X25hbWUoZmllbGQtPm5hbWUoKSk7CisKKyAgICAvLyBSZWNvcmQgbmFtZSBsb2NhdGlvbiB0byBtYXRjaCB0aGUgZmllbGQgbmFtZSdzIGxvY2F0aW9uLgorICAgIHsKKyAgICAgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24oZ3JvdXBfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlc2NyaXB0b3JQcm90bzo6a05hbWVGaWVsZE51bWJlcik7CisgICAgICBsb2NhdGlvbi5TdGFydEF0KG5hbWVfdG9rZW4pOworICAgICAgbG9jYXRpb24uRW5kQXQobmFtZV90b2tlbik7CisgICAgICBsb2NhdGlvbi5SZWNvcmRMZWdhY3lMb2NhdGlvbigKKyAgICAgICAgICBncm91cCwgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpOQU1FKTsKKyAgICB9CisKKyAgICAvLyBUaGUgZmllbGQncyB0eXBlX25hbWUgYWxzbyBjb21lcyBmcm9tIHRoZSBuYW1lLiAgQ29uZnVzaW5nIQorICAgIHsKKyAgICAgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24oZmllbGRfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjprVHlwZU5hbWVGaWVsZE51bWJlcik7CisgICAgICBsb2NhdGlvbi5TdGFydEF0KG5hbWVfdG9rZW4pOworICAgICAgbG9jYXRpb24uRW5kQXQobmFtZV90b2tlbik7CisgICAgfQorCisgICAgLy8gQXMgYSBoYWNrIGZvciBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eSwgd2UgZm9yY2UgdGhlIGdyb3VwIG5hbWUgdG8gc3RhcnQKKyAgICAvLyB3aXRoIGEgY2FwaXRhbCBsZXR0ZXIgYW5kIGxvd2VyLWNhc2UgdGhlIGZpZWxkIG5hbWUuICBOZXcgY29kZSBzaG91bGQKKyAgICAvLyBub3QgdXNlIGdyb3VwczsgaXQgc2hvdWxkIHVzZSBuZXN0ZWQgbWVzc2FnZXMuCisgICAgaWYgKGdyb3VwLT5uYW1lKClbMF0gPCAnQScgfHwgJ1onIDwgZ3JvdXAtPm5hbWUoKVswXSkgeworICAgICAgQWRkRXJyb3IobmFtZV90b2tlbi5saW5lLCBuYW1lX3Rva2VuLmNvbHVtbiwKKyAgICAgICAgIkdyb3VwIG5hbWVzIG11c3Qgc3RhcnQgd2l0aCBhIGNhcGl0YWwgbGV0dGVyLiIpOworICAgIH0KKyAgICBMb3dlclN0cmluZyhmaWVsZC0+bXV0YWJsZV9uYW1lKCkpOworCisgICAgZmllbGQtPnNldF90eXBlX25hbWUoZ3JvdXAtPm5hbWUoKSk7CisgICAgaWYgKExvb2tpbmdBdCgieyIpKSB7CisgICAgICBETyhQYXJzZU1lc3NhZ2VCbG9jayhncm91cCwgZ3JvdXBfbG9jYXRpb24sIGNvbnRhaW5pbmdfZmlsZSkpOworICAgIH0gZWxzZSB7CisgICAgICBBZGRFcnJvcigiTWlzc2luZyBncm91cCBib2R5LiIpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICBETyhDb25zdW1lRW5kT2ZEZWNsYXJhdGlvbigiOyIsICZmaWVsZF9sb2NhdGlvbikpOworICB9CisKKyAgLy8gQ3JlYXRlIGEgbWFwIGVudHJ5IHR5cGUgaWYgdGhpcyBpcyBhIG1hcCBmaWVsZC4KKyAgaWYgKG1hcF9maWVsZC5pc19tYXBfZmllbGQpIHsKKyAgICBHZW5lcmF0ZU1hcEVudHJ5KG1hcF9maWVsZCwgZmllbGQsIG1lc3NhZ2VzKTsKKyAgfQorCisgIHJldHVybiB0cnVlOworfQorCit2b2lkIFBhcnNlcjo6R2VuZXJhdGVNYXBFbnRyeShjb25zdCBNYXBGaWVsZCYgbWFwX2ZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG8qIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVwZWF0ZWRQdHJGaWVsZDxEZXNjcmlwdG9yUHJvdG8+KiBtZXNzYWdlcykgeworICBEZXNjcmlwdG9yUHJvdG8qIGVudHJ5ID0gbWVzc2FnZXMtPkFkZCgpOworICBzdHJpbmcgZW50cnlfbmFtZSA9IE1hcEVudHJ5TmFtZShmaWVsZC0+bmFtZSgpKTsKKyAgZmllbGQtPnNldF90eXBlX25hbWUoZW50cnlfbmFtZSk7CisgIGVudHJ5LT5zZXRfbmFtZShlbnRyeV9uYW1lKTsKKyAgZW50cnktPm11dGFibGVfb3B0aW9ucygpLT5zZXRfbWFwX2VudHJ5KHRydWUpOworICBGaWVsZERlc2NyaXB0b3JQcm90byoga2V5X2ZpZWxkID0gZW50cnktPmFkZF9maWVsZCgpOworICBrZXlfZmllbGQtPnNldF9uYW1lKCJrZXkiKTsKKyAga2V5X2ZpZWxkLT5zZXRfbGFiZWwoRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX09QVElPTkFMKTsKKyAga2V5X2ZpZWxkLT5zZXRfbnVtYmVyKDEpOworICBpZiAobWFwX2ZpZWxkLmtleV90eXBlX25hbWUuZW1wdHkoKSkgeworICAgIGtleV9maWVsZC0+c2V0X3R5cGUobWFwX2ZpZWxkLmtleV90eXBlKTsKKyAgfSBlbHNlIHsKKyAgICBrZXlfZmllbGQtPnNldF90eXBlX25hbWUobWFwX2ZpZWxkLmtleV90eXBlX25hbWUpOworICB9CisgIEZpZWxkRGVzY3JpcHRvclByb3RvKiB2YWx1ZV9maWVsZCA9IGVudHJ5LT5hZGRfZmllbGQoKTsKKyAgdmFsdWVfZmllbGQtPnNldF9uYW1lKCJ2YWx1ZSIpOworICB2YWx1ZV9maWVsZC0+c2V0X2xhYmVsKEZpZWxkRGVzY3JpcHRvclByb3RvOjpMQUJFTF9PUFRJT05BTCk7CisgIHZhbHVlX2ZpZWxkLT5zZXRfbnVtYmVyKDIpOworICBpZiAobWFwX2ZpZWxkLnZhbHVlX3R5cGVfbmFtZS5lbXB0eSgpKSB7CisgICAgdmFsdWVfZmllbGQtPnNldF90eXBlKG1hcF9maWVsZC52YWx1ZV90eXBlKTsKKyAgfSBlbHNlIHsKKyAgICB2YWx1ZV9maWVsZC0+c2V0X3R5cGVfbmFtZShtYXBfZmllbGQudmFsdWVfdHlwZV9uYW1lKTsKKyAgfQorICAvLyBQcm9wYWdhdGUgdGhlICJlbmZvcmNlX3V0ZjgiIG9wdGlvbiB0byBrZXkgYW5kIHZhbHVlIGZpZWxkcyBpZiB0aGV5CisgIC8vIGFyZSBzdHJpbmdzLiBUaGlzIGhlbHBzIHNpbXBsaWZ5IHRoZSBpbXBsZW1lbnRhdGlvbiBvZiBjb2RlIGdlbmVyYXRvcnMKKyAgLy8gYW5kIGFsc28gcmVmbGVjdGlvbi1iYXNlZCBwYXJzaW5nIGNvZGUuCisgIC8vCisgIC8vIFRoZSBmb2xsb3dpbmcgZGVmaW5pdGlvbjoKKyAgLy8gICBtZXNzYWdlIEZvbyB7CisgIC8vICAgICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhbHVlID0gMSBbZW5mb3JjZV91dGY4ID0gZmFsc2VdOworICAvLyAgIH0KKyAgLy8gd2lsbCBiZSBpbnRlcnByZXRlZCBhczoKKyAgLy8gICBtZXNzYWdlIEZvbyB7CisgIC8vICAgICBtZXNzYWdlIFZhbHVlRW50cnkgeworICAvLyAgICAgICBvcHRpb24gbWFwX2VudHJ5ID0gdHJ1ZTsKKyAgLy8gICAgICAgc3RyaW5nIGtleSA9IDEgW2VuZm9yY2VfdXRmOCA9IGZhbHNlXTsKKyAgLy8gICAgICAgc3RyaW5nIHZhbHVlID0gMiBbZW5mb3JjZV91dGY4ID0gZmFsc2VdOworICAvLyAgICAgfQorICAvLyAgICAgcmVwZWF0ZWQgVmFsdWVFbnRyeSB2YWx1ZSA9IDEgW2VuZm9yY2VfdXRmOCA9IGZhbHNlXTsKKyAgLy8gIH0KKyAgLy8KKyAgLy8gVE9ETyh4aWFvZmVuZyk6IFJlbW92ZSB0aGlzIHdoZW4gdGhlICJlbmZvcmNlX3V0ZjgiIG9wdGlvbiBpcyByZW1vdmVkCisgIC8vIGZyb20gcHJvdG9jb2wgY29tcGlsZXIuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGQtPm9wdGlvbnMoKS51bmludGVycHJldGVkX29wdGlvbl9zaXplKCk7ICsraSkgeworICAgIGNvbnN0IFVuaW50ZXJwcmV0ZWRPcHRpb24mIG9wdGlvbiA9CisgICAgICAgIGZpZWxkLT5vcHRpb25zKCkudW5pbnRlcnByZXRlZF9vcHRpb24oaSk7CisgICAgaWYgKG9wdGlvbi5uYW1lX3NpemUoKSA9PSAxICYmCisgICAgICAgIG9wdGlvbi5uYW1lKDApLm5hbWVfcGFydCgpID09ICJlbmZvcmNlX3V0ZjgiICYmCisgICAgICAgICFvcHRpb24ubmFtZSgwKS5pc19leHRlbnNpb24oKSkgeworICAgICAgaWYgKGtleV9maWVsZC0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX1NUUklORykgeworICAgICAgICBrZXlfZmllbGQtPm11dGFibGVfb3B0aW9ucygpLT5hZGRfdW5pbnRlcnByZXRlZF9vcHRpb24oKQorICAgICAgICAgICAgLT5Db3B5RnJvbShvcHRpb24pOworICAgICAgfQorICAgICAgaWYgKHZhbHVlX2ZpZWxkLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfU1RSSU5HKSB7CisgICAgICAgIHZhbHVlX2ZpZWxkLT5tdXRhYmxlX29wdGlvbnMoKS0+YWRkX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCkKKyAgICAgICAgICAgIC0+Q29weUZyb20ob3B0aW9uKTsKKyAgICAgIH0KKyAgICB9CisgIH0KK30KKworYm9vbCBQYXJzZXI6OlBhcnNlRmllbGRPcHRpb25zKEZpZWxkRGVzY3JpcHRvclByb3RvKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiBmaWVsZF9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvKiBjb250YWluaW5nX2ZpbGUpIHsKKyAgaWYgKCFMb29raW5nQXQoIlsiKSkgcmV0dXJuIHRydWU7CisKKyAgTG9jYXRpb25SZWNvcmRlciBsb2NhdGlvbihmaWVsZF9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6a09wdGlvbnNGaWVsZE51bWJlcik7CisKKyAgRE8oQ29uc3VtZSgiWyIpKTsKKworICAvLyBQYXJzZSBmaWVsZCBvcHRpb25zLgorICBkbyB7CisgICAgaWYgKExvb2tpbmdBdCgiZGVmYXVsdCIpKSB7CisgICAgICAvLyBXZSBpbnRlbnRpb25hbGx5IHBhc3MgZmllbGRfbG9jYXRpb24gcmF0aGVyIHRoYW4gbG9jYXRpb24gaGVyZSwgc2luY2UKKyAgICAgIC8vIHRoZSBkZWZhdWx0IHZhbHVlIGlzIG5vdCBhY3R1YWxseSBhbiBvcHRpb24uCisgICAgICBETyhQYXJzZURlZmF1bHRBc3NpZ25tZW50KGZpZWxkLCBmaWVsZF9sb2NhdGlvbiwgY29udGFpbmluZ19maWxlKSk7CisgICAgfSBlbHNlIGlmIChMb29raW5nQXQoImpzb25fbmFtZSIpKSB7CisgICAgICAvLyBMaWtlIGRlZmF1bHQgdmFsdWUsIHRoaXMgImpzb25fbmFtZSIgaXMgbm90IGFuIGFjdHVhbCBvcHRpb24uCisgICAgICBETyhQYXJzZUpzb25OYW1lKGZpZWxkLCBmaWVsZF9sb2NhdGlvbiwgY29udGFpbmluZ19maWxlKSk7CisgICAgfSBlbHNlIHsKKyAgICAgIERPKFBhcnNlT3B0aW9uKGZpZWxkLT5tdXRhYmxlX29wdGlvbnMoKSwgbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICBjb250YWluaW5nX2ZpbGUsIE9QVElPTl9BU1NJR05NRU5UKSk7CisgICAgfQorICB9IHdoaWxlIChUcnlDb25zdW1lKCIsIikpOworCisgIERPKENvbnN1bWUoIl0iKSk7CisgIHJldHVybiB0cnVlOworfQorCitib29sIFBhcnNlcjo6UGFyc2VEZWZhdWx0QXNzaWdubWVudCgKKyAgICBGaWVsZERlc2NyaXB0b3JQcm90byogZmllbGQsCisgICAgY29uc3QgTG9jYXRpb25SZWNvcmRlciYgZmllbGRfbG9jYXRpb24sCisgICAgY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byogY29udGFpbmluZ19maWxlKSB7CisgIGlmIChmaWVsZC0+aGFzX2RlZmF1bHRfdmFsdWUoKSkgeworICAgIEFkZEVycm9yKCJBbHJlYWR5IHNldCBvcHRpb24gXCJkZWZhdWx0XCIuIik7CisgICAgZmllbGQtPmNsZWFyX2RlZmF1bHRfdmFsdWUoKTsKKyAgfQorCisgIERPKENvbnN1bWUoImRlZmF1bHQiKSk7CisgIERPKENvbnN1bWUoIj0iKSk7CisKKyAgTG9jYXRpb25SZWNvcmRlciBsb2NhdGlvbihmaWVsZF9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6a0RlZmF1bHRWYWx1ZUZpZWxkTnVtYmVyKTsKKyAgbG9jYXRpb24uUmVjb3JkTGVnYWN5TG9jYXRpb24oCisgICAgICBmaWVsZCwgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpERUZBVUxUX1ZBTFVFKTsKKyAgc3RyaW5nKiBkZWZhdWx0X3ZhbHVlID0gZmllbGQtPm11dGFibGVfZGVmYXVsdF92YWx1ZSgpOworCisgIGlmICghZmllbGQtPmhhc190eXBlKCkpIHsKKyAgICAvLyBUaGUgZmllbGQgaGFzIGEgdHlwZSBuYW1lLCBidXQgd2UgZG9uJ3Qga25vdyBpZiBpdCBpcyBhIG1lc3NhZ2Ugb3IgYW4KKyAgICAvLyBlbnVtIHlldC4gKElmIGl0IHdlcmUgYSBwcmltaXRpdmUgdHlwZSwgfGZpZWxkfCB3b3VsZCBoYXZlIGEgdHlwZSBzZXQKKyAgICAvLyBhbHJlYWR5LikgSW4gdGhpcyBjYXNlLCBzaW1wbHkgdGFrZSB0aGUgY3VycmVudCBzdHJpbmcgYXMgdGhlIGRlZmF1bHQKKyAgICAvLyB2YWx1ZTsgd2Ugd2lsbCBjYXRjaCB0aGUgZXJyb3IgbGF0ZXIgaWYgaXQgaXMgbm90IGEgdmFsaWQgZW51bSB2YWx1ZS4KKyAgICAvLyAoTi5CLiB0aGF0IHdlIGRvIG5vdCBjaGVjayB3aGV0aGVyIHRoZSBjdXJyZW50IHRva2VuIGlzIGFuIGlkZW50aWZpZXI6CisgICAgLy8gZG9pbmcgc28gdGhyb3dzIHN0cmFuZ2UgZXJyb3JzIHdoZW4gdGhlIHVzZXIgbWlzdHlwZXMgYSBwcmltaXRpdmUKKyAgICAvLyB0eXBlbmFtZSBhbmQgd2UgYXNzdW1lIGl0J3MgYW4gZW51bS4gRS5nLjogIm9wdGlvbmFsIGludCBmb28gPSAxIFtkZWZhdWx0CisgICAgLy8gPSA0Ml0iLiBJbiBzdWNoIGEgY2FzZSB0aGUgZnVuZGFtZW50YWwgZXJyb3IgaXMgcmVhbGx5IHRoYXQgImludCIgaXMgbm90CisgICAgLy8gYSB0eXBlLCBub3QgdGhhdCAiNDIiIGlzIG5vdCBhbiBpZGVudGlmaWVyLiBTZWUgYi8xMjUzMzU4Mi4pCisgICAgKmRlZmF1bHRfdmFsdWUgPSBpbnB1dF8tPmN1cnJlbnQoKS50ZXh0OworICAgIGlucHV0Xy0+TmV4dCgpOworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgc3dpdGNoIChmaWVsZC0+dHlwZSgpKSB7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9JTlQzMjoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0lOVDY0OgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfU0lOVDMyOgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfU0lOVDY0OgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfU0ZJWEVEMzI6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9TRklYRUQ2NDogeworICAgICAgdWludDY0IG1heF92YWx1ZSA9IGtpbnQ2NG1heDsKKyAgICAgIGlmIChmaWVsZC0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0lOVDMyIHx8CisgICAgICAgICAgZmllbGQtPnR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9TSU5UMzIgfHwKKyAgICAgICAgICBmaWVsZC0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX1NGSVhFRDMyKSB7CisgICAgICAgIG1heF92YWx1ZSA9IGtpbnQzMm1heDsKKyAgICAgIH0KKworICAgICAgLy8gVGhlc2UgdHlwZXMgY2FuIGJlIG5lZ2F0aXZlLgorICAgICAgaWYgKFRyeUNvbnN1bWUoIi0iKSkgeworICAgICAgICBkZWZhdWx0X3ZhbHVlLT5hcHBlbmQoIi0iKTsKKyAgICAgICAgLy8gVHdvJ3MgY29tcGxlbWVudCBhbHdheXMgaGFzIG9uZSBtb3JlIG5lZ2F0aXZlIHZhbHVlIHRoYW4gcG9zaXRpdmUuCisgICAgICAgICsrbWF4X3ZhbHVlOworICAgICAgfQorICAgICAgLy8gUGFyc2UgdGhlIGludGVnZXIgdG8gdmVyaWZ5IHRoYXQgaXQgaXMgbm90IG91dC1vZi1yYW5nZS4KKyAgICAgIHVpbnQ2NCB2YWx1ZTsKKyAgICAgIERPKENvbnN1bWVJbnRlZ2VyNjQobWF4X3ZhbHVlLCAmdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICJFeHBlY3RlZCBpbnRlZ2VyIGZvciBmaWVsZCBkZWZhdWx0IHZhbHVlLiIpKTsKKyAgICAgIC8vIEFuZCBzdHJpbmdpZnkgaXQgYWdhaW4uCisgICAgICBkZWZhdWx0X3ZhbHVlLT5hcHBlbmQoU2ltcGxlSXRvYSh2YWx1ZSkpOworICAgICAgYnJlYWs7CisgICAgfQorCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9VSU5UMzI6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9VSU5UNjQ6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9GSVhFRDMyOgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfRklYRUQ2NDogeworICAgICAgdWludDY0IG1heF92YWx1ZSA9IGt1aW50NjRtYXg7CisgICAgICBpZiAoZmllbGQtPnR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9VSU5UMzIgfHwKKyAgICAgICAgICBmaWVsZC0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0ZJWEVEMzIpIHsKKyAgICAgICAgbWF4X3ZhbHVlID0ga3VpbnQzMm1heDsKKyAgICAgIH0KKworICAgICAgLy8gTnVtZXJpYywgbm90IG5lZ2F0aXZlLgorICAgICAgaWYgKFRyeUNvbnN1bWUoIi0iKSkgeworICAgICAgICBBZGRFcnJvcigiVW5zaWduZWQgZmllbGQgY2FuJ3QgaGF2ZSBuZWdhdGl2ZSBkZWZhdWx0IHZhbHVlLiIpOworICAgICAgfQorICAgICAgLy8gUGFyc2UgdGhlIGludGVnZXIgdG8gdmVyaWZ5IHRoYXQgaXQgaXMgbm90IG91dC1vZi1yYW5nZS4KKyAgICAgIHVpbnQ2NCB2YWx1ZTsKKyAgICAgIERPKENvbnN1bWVJbnRlZ2VyNjQobWF4X3ZhbHVlLCAmdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICJFeHBlY3RlZCBpbnRlZ2VyIGZvciBmaWVsZCBkZWZhdWx0IHZhbHVlLiIpKTsKKyAgICAgIC8vIEFuZCBzdHJpbmdpZnkgaXQgYWdhaW4uCisgICAgICBkZWZhdWx0X3ZhbHVlLT5hcHBlbmQoU2ltcGxlSXRvYSh2YWx1ZSkpOworICAgICAgYnJlYWs7CisgICAgfQorCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9GTE9BVDoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0RPVUJMRToKKyAgICAgIC8vIFRoZXNlIHR5cGVzIGNhbiBiZSBuZWdhdGl2ZS4KKyAgICAgIGlmIChUcnlDb25zdW1lKCItIikpIHsKKyAgICAgICAgZGVmYXVsdF92YWx1ZS0+YXBwZW5kKCItIik7CisgICAgICB9CisgICAgICAvLyBQYXJzZSB0aGUgaW50ZWdlciBiZWNhdXNlIHdlIGhhdmUgdG8gY29udmVydCBoZXggaW50ZWdlcnMgdG8gZGVjaW1hbAorICAgICAgLy8gZmxvYXRzLgorICAgICAgZG91YmxlIHZhbHVlOworICAgICAgRE8oQ29uc3VtZU51bWJlcigmdmFsdWUsICJFeHBlY3RlZCBudW1iZXIuIikpOworICAgICAgLy8gQW5kIHN0cmluZ2lmeSBpdCBhZ2Fpbi4KKyAgICAgIGRlZmF1bHRfdmFsdWUtPmFwcGVuZChTaW1wbGVEdG9hKHZhbHVlKSk7CisgICAgICBicmVhazsKKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfQk9PTDoKKyAgICAgIGlmIChUcnlDb25zdW1lKCJ0cnVlIikpIHsKKyAgICAgICAgZGVmYXVsdF92YWx1ZS0+YXNzaWduKCJ0cnVlIik7CisgICAgICB9IGVsc2UgaWYgKFRyeUNvbnN1bWUoImZhbHNlIikpIHsKKyAgICAgICAgZGVmYXVsdF92YWx1ZS0+YXNzaWduKCJmYWxzZSIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgQWRkRXJyb3IoIkV4cGVjdGVkIFwidHJ1ZVwiIG9yIFwiZmFsc2VcIi4iKTsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgICAgYnJlYWs7CisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX1NUUklORzoKKyAgICAgIC8vIE5vdGU6IFdoZW4gZmlsZSBvcHRvbiBqYXZhX3N0cmluZ19jaGVja191dGY4IGlzIHRydWUsIGlmIGEKKyAgICAgIC8vIG5vbi1zdHJpbmcgcmVwcmVzZW50YXRpb24gKGVnIGJ5dGVbXSkgaXMgbGF0ZXIgc3VwcG9ydGVkLCBpdCBtdXN0CisgICAgICAvLyBiZSBjaGVja2VkIGZvciBVVEYtOC1uZXNzLgorICAgICAgRE8oQ29uc3VtZVN0cmluZyhkZWZhdWx0X3ZhbHVlLCAiRXhwZWN0ZWQgc3RyaW5nIGZvciBmaWVsZCBkZWZhdWx0ICIKKyAgICAgICAgICAgICAgICAgICAgICAgInZhbHVlLiIpKTsKKyAgICAgIGJyZWFrOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9CWVRFUzoKKyAgICAgIERPKENvbnN1bWVTdHJpbmcoZGVmYXVsdF92YWx1ZSwgIkV4cGVjdGVkIHN0cmluZy4iKSk7CisgICAgICAqZGVmYXVsdF92YWx1ZSA9IENFc2NhcGUoKmRlZmF1bHRfdmFsdWUpOworICAgICAgYnJlYWs7CisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0VOVU06CisgICAgICBETyhDb25zdW1lSWRlbnRpZmllcihkZWZhdWx0X3ZhbHVlLCAiRXhwZWN0ZWQgZW51bSBpZGVudGlmaWVyIGZvciBmaWVsZCAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZGVmYXVsdCB2YWx1ZS4iKSk7CisgICAgICBicmVhazsKKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfTUVTU0FHRToKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0dST1VQOgorICAgICAgQWRkRXJyb3IoIk1lc3NhZ2VzIGNhbid0IGhhdmUgZGVmYXVsdCB2YWx1ZXMuIik7CisgICAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICByZXR1cm4gdHJ1ZTsKK30KKworYm9vbCBQYXJzZXI6OlBhcnNlSnNvbk5hbWUoCisgICAgRmllbGREZXNjcmlwdG9yUHJvdG8qIGZpZWxkLAorICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIGZpZWxkX2xvY2F0aW9uLAorICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfZmlsZSkgeworICBpZiAoZmllbGQtPmhhc19qc29uX25hbWUoKSkgeworICAgIEFkZEVycm9yKCJBbHJlYWR5IHNldCBvcHRpb24gXCJqc29uX25hbWVcIi4iKTsKKyAgICBmaWVsZC0+Y2xlYXJfanNvbl9uYW1lKCk7CisgIH0KKworICBETyhDb25zdW1lKCJqc29uX25hbWUiKSk7CisgIERPKENvbnN1bWUoIj0iKSk7CisKKyAgTG9jYXRpb25SZWNvcmRlciBsb2NhdGlvbihmaWVsZF9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6a0pzb25OYW1lRmllbGROdW1iZXIpOworICBsb2NhdGlvbi5SZWNvcmRMZWdhY3lMb2NhdGlvbigKKyAgICAgIGZpZWxkLCBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok9QVElPTl9WQUxVRSk7CisgIERPKENvbnN1bWVTdHJpbmcoZmllbGQtPm11dGFibGVfanNvbl9uYW1lKCksCisgICAgICAgICAgICAgICAgICAgIkV4cGVjdGVkIHN0cmluZyBmb3IgSlNPTiBuYW1lLiIpKTsKKyAgcmV0dXJuIHRydWU7Cit9CisKKworYm9vbCBQYXJzZXI6OlBhcnNlT3B0aW9uTmFtZVBhcnQoVW5pbnRlcnByZXRlZE9wdGlvbiogdW5pbnRlcnByZXRlZF9vcHRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiBwYXJ0X2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byogY29udGFpbmluZ19maWxlKSB7CisgIFVuaW50ZXJwcmV0ZWRPcHRpb246Ok5hbWVQYXJ0KiBuYW1lID0gdW5pbnRlcnByZXRlZF9vcHRpb24tPmFkZF9uYW1lKCk7CisgIHN0cmluZyBpZGVudGlmaWVyOyAgLy8gV2UgcGFyc2UgaWRlbnRpZmllcnMgaW50byB0aGlzIHN0cmluZy4KKyAgaWYgKExvb2tpbmdBdCgiKCIpKSB7ICAvLyBUaGlzIGlzIGFuIGV4dGVuc2lvbi4KKyAgICBETyhDb25zdW1lKCIoIikpOworCisgICAgeworICAgICAgTG9jYXRpb25SZWNvcmRlciBsb2NhdGlvbigKKyAgICAgICAgICBwYXJ0X2xvY2F0aW9uLCBVbmludGVycHJldGVkT3B0aW9uOjpOYW1lUGFydDo6a05hbWVQYXJ0RmllbGROdW1iZXIpOworICAgICAgLy8gQW4gZXh0ZW5zaW9uIG5hbWUgY29uc2lzdHMgb2YgZG90LXNlcGFyYXRlZCBpZGVudGlmaWVycywgYW5kIG1heSBiZWdpbgorICAgICAgLy8gd2l0aCBhIGRvdC4KKyAgICAgIGlmIChMb29raW5nQXRUeXBlKGlvOjpUb2tlbml6ZXI6OlRZUEVfSURFTlRJRklFUikpIHsKKyAgICAgICAgRE8oQ29uc3VtZUlkZW50aWZpZXIoJmlkZW50aWZpZXIsICJFeHBlY3RlZCBpZGVudGlmaWVyLiIpKTsKKyAgICAgICAgbmFtZS0+bXV0YWJsZV9uYW1lX3BhcnQoKS0+YXBwZW5kKGlkZW50aWZpZXIpOworICAgICAgfQorICAgICAgd2hpbGUgKExvb2tpbmdBdCgiLiIpKSB7CisgICAgICAgIERPKENvbnN1bWUoIi4iKSk7CisgICAgICAgIG5hbWUtPm11dGFibGVfbmFtZV9wYXJ0KCktPmFwcGVuZCgiLiIpOworICAgICAgICBETyhDb25zdW1lSWRlbnRpZmllcigmaWRlbnRpZmllciwgIkV4cGVjdGVkIGlkZW50aWZpZXIuIikpOworICAgICAgICBuYW1lLT5tdXRhYmxlX25hbWVfcGFydCgpLT5hcHBlbmQoaWRlbnRpZmllcik7CisgICAgICB9CisgICAgfQorCisgICAgRE8oQ29uc3VtZSgiKSIpKTsKKyAgICBuYW1lLT5zZXRfaXNfZXh0ZW5zaW9uKHRydWUpOworICB9IGVsc2UgeyAgLy8gVGhpcyBpcyBhIHJlZ3VsYXIgZmllbGQuCisgICAgTG9jYXRpb25SZWNvcmRlciBsb2NhdGlvbigKKyAgICAgICAgcGFydF9sb2NhdGlvbiwgVW5pbnRlcnByZXRlZE9wdGlvbjo6TmFtZVBhcnQ6OmtOYW1lUGFydEZpZWxkTnVtYmVyKTsKKyAgICBETyhDb25zdW1lSWRlbnRpZmllcigmaWRlbnRpZmllciwgIkV4cGVjdGVkIGlkZW50aWZpZXIuIikpOworICAgIG5hbWUtPm11dGFibGVfbmFtZV9wYXJ0KCktPmFwcGVuZChpZGVudGlmaWVyKTsKKyAgICBuYW1lLT5zZXRfaXNfZXh0ZW5zaW9uKGZhbHNlKTsKKyAgfQorICByZXR1cm4gdHJ1ZTsKK30KKworYm9vbCBQYXJzZXI6OlBhcnNlVW5pbnRlcnByZXRlZEJsb2NrKHN0cmluZyogdmFsdWUpIHsKKyAgLy8gTm90ZSB0aGF0IGVuY2xvc2luZyBicmFjZXMgYXJlIG5vdCBhZGRlZCB0byAqdmFsdWUuCisgIC8vIFdlIGRvIE5PVCB1c2UgQ29uc3VtZUVuZE9mU3RhdGVtZW50IGZvciB0aGlzIGJyYWNlIGJlY2F1c2UgaXQncyBkZWxpbWl0aW5nCisgIC8vIGFuIGV4cHJlc3Npb24sIG5vdCBhIGJsb2NrIG9mIHN0YXRlbWVudHMuCisgIERPKENvbnN1bWUoInsiKSk7CisgIGludCBicmFjZV9kZXB0aCA9IDE7CisgIHdoaWxlICghQXRFbmQoKSkgeworICAgIGlmIChMb29raW5nQXQoInsiKSkgeworICAgICAgYnJhY2VfZGVwdGgrKzsKKyAgICB9IGVsc2UgaWYgKExvb2tpbmdBdCgifSIpKSB7CisgICAgICBicmFjZV9kZXB0aC0tOworICAgICAgaWYgKGJyYWNlX2RlcHRoID09IDApIHsKKyAgICAgICAgaW5wdXRfLT5OZXh0KCk7CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgfQorICAgIH0KKyAgICAvLyBUT0RPKHNhbmpheSk6IEludGVycHJldCBsaW5lL2NvbHVtbiBudW1iZXJzIHRvIHByZXNlcnZlIGZvcm1hdHRpbmcKKyAgICBpZiAoIXZhbHVlLT5lbXB0eSgpKSB2YWx1ZS0+cHVzaF9iYWNrKCcgJyk7CisgICAgdmFsdWUtPmFwcGVuZChpbnB1dF8tPmN1cnJlbnQoKS50ZXh0KTsKKyAgICBpbnB1dF8tPk5leHQoKTsKKyAgfQorICBBZGRFcnJvcigiVW5leHBlY3RlZCBlbmQgb2Ygc3RyZWFtIHdoaWxlIHBhcnNpbmcgYWdncmVnYXRlIHZhbHVlLiIpOworICByZXR1cm4gZmFsc2U7Cit9CisKKy8vIFdlIGRvbid0IGludGVycHJldCB0aGUgb3B0aW9uIGhlcmUuIEluc3RlYWQgd2Ugc3RvcmUgaXQgaW4gYW4KKy8vIFVuaW50ZXJwcmV0ZWRPcHRpb24sIHRvIGJlIGludGVycHJldGVkIGxhdGVyLgorYm9vbCBQYXJzZXI6OlBhcnNlT3B0aW9uKE1lc3NhZ2UqIG9wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTG9jYXRpb25SZWNvcmRlciYgb3B0aW9uc19sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvKiBjb250YWluaW5nX2ZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgT3B0aW9uU3R5bGUgc3R5bGUpIHsKKyAgLy8gQ3JlYXRlIGFuIGVudHJ5IGluIHRoZSB1bmludGVycHJldGVkX29wdGlvbiBmaWVsZC4KKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiB1bmludGVycHJldGVkX29wdGlvbl9maWVsZCA9IG9wdGlvbnMtPkdldERlc2NyaXB0b3IoKS0+CisgICAgICBGaW5kRmllbGRCeU5hbWUoInVuaW50ZXJwcmV0ZWRfb3B0aW9uIik7CisgIEdPT0dMRV9DSEVDSyh1bmludGVycHJldGVkX29wdGlvbl9maWVsZCAhPSBOVUxMKQorICAgICAgPDwgIk5vIGZpZWxkIG5hbWVkIFwidW5pbnRlcnByZXRlZF9vcHRpb25cIiBpbiB0aGUgT3B0aW9ucyBwcm90by4iOworCisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBvcHRpb25zLT5HZXRSZWZsZWN0aW9uKCk7CisKKyAgTG9jYXRpb25SZWNvcmRlciBsb2NhdGlvbigKKyAgICAgIG9wdGlvbnNfbG9jYXRpb24sIHVuaW50ZXJwcmV0ZWRfb3B0aW9uX2ZpZWxkLT5udW1iZXIoKSwKKyAgICAgIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZSgqb3B0aW9ucywgdW5pbnRlcnByZXRlZF9vcHRpb25fZmllbGQpKTsKKworICBpZiAoc3R5bGUgPT0gT1BUSU9OX1NUQVRFTUVOVCkgeworICAgIERPKENvbnN1bWUoIm9wdGlvbiIpKTsKKyAgfQorCisgIFVuaW50ZXJwcmV0ZWRPcHRpb24qIHVuaW50ZXJwcmV0ZWRfb3B0aW9uID0gZG93bl9jYXN0PFVuaW50ZXJwcmV0ZWRPcHRpb24qPigKKyAgICAgIG9wdGlvbnMtPkdldFJlZmxlY3Rpb24oKS0+QWRkTWVzc2FnZShvcHRpb25zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uX2ZpZWxkKSk7CisKKyAgLy8gUGFyc2UgZG90LXNlcGFyYXRlZCBuYW1lLgorICB7CisgICAgTG9jYXRpb25SZWNvcmRlciBuYW1lX2xvY2F0aW9uKGxvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVbmludGVycHJldGVkT3B0aW9uOjprTmFtZUZpZWxkTnVtYmVyKTsKKyAgICBuYW1lX2xvY2F0aW9uLlJlY29yZExlZ2FjeUxvY2F0aW9uKAorICAgICAgICB1bmludGVycHJldGVkX29wdGlvbiwgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpPUFRJT05fTkFNRSk7CisKKyAgICB7CisgICAgICBMb2NhdGlvblJlY29yZGVyIHBhcnRfbG9jYXRpb24obmFtZV9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmludGVycHJldGVkX29wdGlvbi0+bmFtZV9zaXplKCkpOworICAgICAgRE8oUGFyc2VPcHRpb25OYW1lUGFydCh1bmludGVycHJldGVkX29wdGlvbiwgcGFydF9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGFpbmluZ19maWxlKSk7CisgICAgfQorCisgICAgd2hpbGUgKExvb2tpbmdBdCgiLiIpKSB7CisgICAgICBETyhDb25zdW1lKCIuIikpOworICAgICAgTG9jYXRpb25SZWNvcmRlciBwYXJ0X2xvY2F0aW9uKG5hbWVfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pbnRlcnByZXRlZF9vcHRpb24tPm5hbWVfc2l6ZSgpKTsKKyAgICAgIERPKFBhcnNlT3B0aW9uTmFtZVBhcnQodW5pbnRlcnByZXRlZF9vcHRpb24sIHBhcnRfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRhaW5pbmdfZmlsZSkpOworICAgIH0KKyAgfQorCisgIERPKENvbnN1bWUoIj0iKSk7CisKKyAgeworICAgIExvY2F0aW9uUmVjb3JkZXIgdmFsdWVfbG9jYXRpb24obG9jYXRpb24pOworICAgIHZhbHVlX2xvY2F0aW9uLlJlY29yZExlZ2FjeUxvY2F0aW9uKAorICAgICAgICB1bmludGVycHJldGVkX29wdGlvbiwgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpPUFRJT05fVkFMVUUpOworCisgICAgLy8gQWxsIHZhbHVlcyBhcmUgYSBzaW5nbGUgdG9rZW4sIGV4Y2VwdCBmb3IgbmVnYXRpdmUgbnVtYmVycywgd2hpY2ggY29uc2lzdAorICAgIC8vIG9mIGEgc2luZ2xlICctJyBzeW1ib2wsIGZvbGxvd2VkIGJ5IGEgcG9zaXRpdmUgbnVtYmVyLgorICAgIGJvb2wgaXNfbmVnYXRpdmUgPSBUcnlDb25zdW1lKCItIik7CisKKyAgICBzd2l0Y2ggKGlucHV0Xy0+Y3VycmVudCgpLnR5cGUpIHsKKyAgICAgIGNhc2UgaW86OlRva2VuaXplcjo6VFlQRV9TVEFSVDoKKyAgICAgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIlRyeWluZyB0byByZWFkIHZhbHVlIGJlZm9yZSBhbnkgdG9rZW5zIGhhdmUgYmVlbiByZWFkLiI7CisgICAgICAgIHJldHVybiBmYWxzZTsKKworICAgICAgY2FzZSBpbzo6VG9rZW5pemVyOjpUWVBFX0VORDoKKyAgICAgICAgQWRkRXJyb3IoIlVuZXhwZWN0ZWQgZW5kIG9mIHN0cmVhbSB3aGlsZSBwYXJzaW5nIG9wdGlvbiB2YWx1ZS4iKTsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgICBjYXNlIGlvOjpUb2tlbml6ZXI6OlRZUEVfSURFTlRJRklFUjogeworICAgICAgICB2YWx1ZV9sb2NhdGlvbi5BZGRQYXRoKAorICAgICAgICAgICAgVW5pbnRlcnByZXRlZE9wdGlvbjo6a0lkZW50aWZpZXJWYWx1ZUZpZWxkTnVtYmVyKTsKKyAgICAgICAgaWYgKGlzX25lZ2F0aXZlKSB7CisgICAgICAgICAgQWRkRXJyb3IoIkludmFsaWQgJy0nIHN5bWJvbCBiZWZvcmUgaWRlbnRpZmllci4iKTsKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgc3RyaW5nIHZhbHVlOworICAgICAgICBETyhDb25zdW1lSWRlbnRpZmllcigmdmFsdWUsICJFeHBlY3RlZCBpZGVudGlmaWVyLiIpKTsKKyAgICAgICAgdW5pbnRlcnByZXRlZF9vcHRpb24tPnNldF9pZGVudGlmaWVyX3ZhbHVlKHZhbHVlKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGNhc2UgaW86OlRva2VuaXplcjo6VFlQRV9JTlRFR0VSOiB7CisgICAgICAgIHVpbnQ2NCB2YWx1ZTsKKyAgICAgICAgdWludDY0IG1heF92YWx1ZSA9CisgICAgICAgICAgICBpc19uZWdhdGl2ZSA/IHN0YXRpY19jYXN0PHVpbnQ2ND4oa2ludDY0bWF4KSArIDEgOiBrdWludDY0bWF4OworICAgICAgICBETyhDb25zdW1lSW50ZWdlcjY0KG1heF92YWx1ZSwgJnZhbHVlLCAiRXhwZWN0ZWQgaW50ZWdlci4iKSk7CisgICAgICAgIGlmIChpc19uZWdhdGl2ZSkgeworICAgICAgICAgIHZhbHVlX2xvY2F0aW9uLkFkZFBhdGgoCisgICAgICAgICAgICAgIFVuaW50ZXJwcmV0ZWRPcHRpb246OmtOZWdhdGl2ZUludFZhbHVlRmllbGROdW1iZXIpOworICAgICAgICAgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uLT5zZXRfbmVnYXRpdmVfaW50X3ZhbHVlKAorICAgICAgICAgICAgICAtc3RhdGljX2Nhc3Q8aW50NjQ+KHZhbHVlKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgdmFsdWVfbG9jYXRpb24uQWRkUGF0aCgKKyAgICAgICAgICAgICAgVW5pbnRlcnByZXRlZE9wdGlvbjo6a1Bvc2l0aXZlSW50VmFsdWVGaWVsZE51bWJlcik7CisgICAgICAgICAgdW5pbnRlcnByZXRlZF9vcHRpb24tPnNldF9wb3NpdGl2ZV9pbnRfdmFsdWUodmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBjYXNlIGlvOjpUb2tlbml6ZXI6OlRZUEVfRkxPQVQ6IHsKKyAgICAgICAgdmFsdWVfbG9jYXRpb24uQWRkUGF0aChVbmludGVycHJldGVkT3B0aW9uOjprRG91YmxlVmFsdWVGaWVsZE51bWJlcik7CisgICAgICAgIGRvdWJsZSB2YWx1ZTsKKyAgICAgICAgRE8oQ29uc3VtZU51bWJlcigmdmFsdWUsICJFeHBlY3RlZCBudW1iZXIuIikpOworICAgICAgICB1bmludGVycHJldGVkX29wdGlvbi0+c2V0X2RvdWJsZV92YWx1ZShpc19uZWdhdGl2ZSA/IC12YWx1ZSA6IHZhbHVlKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGNhc2UgaW86OlRva2VuaXplcjo6VFlQRV9TVFJJTkc6IHsKKyAgICAgICAgdmFsdWVfbG9jYXRpb24uQWRkUGF0aChVbmludGVycHJldGVkT3B0aW9uOjprU3RyaW5nVmFsdWVGaWVsZE51bWJlcik7CisgICAgICAgIGlmIChpc19uZWdhdGl2ZSkgeworICAgICAgICAgIEFkZEVycm9yKCJJbnZhbGlkICctJyBzeW1ib2wgYmVmb3JlIHN0cmluZy4iKTsKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgc3RyaW5nIHZhbHVlOworICAgICAgICBETyhDb25zdW1lU3RyaW5nKCZ2YWx1ZSwgIkV4cGVjdGVkIHN0cmluZy4iKSk7CisgICAgICAgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uLT5zZXRfc3RyaW5nX3ZhbHVlKHZhbHVlKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGNhc2UgaW86OlRva2VuaXplcjo6VFlQRV9TWU1CT0w6CisgICAgICAgIGlmIChMb29raW5nQXQoInsiKSkgeworICAgICAgICAgIHZhbHVlX2xvY2F0aW9uLkFkZFBhdGgoCisgICAgICAgICAgICAgIFVuaW50ZXJwcmV0ZWRPcHRpb246OmtBZ2dyZWdhdGVWYWx1ZUZpZWxkTnVtYmVyKTsKKyAgICAgICAgICBETyhQYXJzZVVuaW50ZXJwcmV0ZWRCbG9jaygKKyAgICAgICAgICAgICAgdW5pbnRlcnByZXRlZF9vcHRpb24tPm11dGFibGVfYWdncmVnYXRlX3ZhbHVlKCkpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBBZGRFcnJvcigiRXhwZWN0ZWQgb3B0aW9uIHZhbHVlLiIpOworICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICB9CisgIH0KKworICBpZiAoc3R5bGUgPT0gT1BUSU9OX1NUQVRFTUVOVCkgeworICAgIERPKENvbnN1bWVFbmRPZkRlY2xhcmF0aW9uKCI7IiwgJmxvY2F0aW9uKSk7CisgIH0KKworICByZXR1cm4gdHJ1ZTsKK30KKworYm9vbCBQYXJzZXI6OlBhcnNlRXh0ZW5zaW9ucyhEZXNjcmlwdG9yUHJvdG8qIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIGV4dGVuc2lvbnNfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfZmlsZSkgeworICAvLyBQYXJzZSB0aGUgZGVjbGFyYXRpb24uCisgIERPKENvbnN1bWUoImV4dGVuc2lvbnMiKSk7CisKKyAgZG8geworICAgIC8vIE5vdGUgdGhhdCBrRXh0ZW5zaW9uUmFuZ2VGaWVsZE51bWJlciB3YXMgYWxyZWFkeSBwdXNoZWQgYnkgdGhlIHBhcmVudC4KKyAgICBMb2NhdGlvblJlY29yZGVyIGxvY2F0aW9uKGV4dGVuc2lvbnNfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLT5leHRlbnNpb25fcmFuZ2Vfc2l6ZSgpKTsKKworICAgIERlc2NyaXB0b3JQcm90bzo6RXh0ZW5zaW9uUmFuZ2UqIHJhbmdlID0gbWVzc2FnZS0+YWRkX2V4dGVuc2lvbl9yYW5nZSgpOworICAgIGxvY2F0aW9uLlJlY29yZExlZ2FjeUxvY2F0aW9uKAorICAgICAgICByYW5nZSwgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpOVU1CRVIpOworCisgICAgaW50IHN0YXJ0LCBlbmQ7CisgICAgaW86OlRva2VuaXplcjo6VG9rZW4gc3RhcnRfdG9rZW47CisKKyAgICB7CisgICAgICBMb2NhdGlvblJlY29yZGVyIHN0YXJ0X2xvY2F0aW9uKAorICAgICAgICAgIGxvY2F0aW9uLCBEZXNjcmlwdG9yUHJvdG86OkV4dGVuc2lvblJhbmdlOjprU3RhcnRGaWVsZE51bWJlcik7CisgICAgICBzdGFydF90b2tlbiA9IGlucHV0Xy0+Y3VycmVudCgpOworICAgICAgRE8oQ29uc3VtZUludGVnZXIoJnN0YXJ0LCAiRXhwZWN0ZWQgZmllbGQgbnVtYmVyIHJhbmdlLiIpKTsKKyAgICB9CisKKyAgICBpZiAoVHJ5Q29uc3VtZSgidG8iKSkgeworICAgICAgTG9jYXRpb25SZWNvcmRlciBlbmRfbG9jYXRpb24oCisgICAgICAgICAgbG9jYXRpb24sIERlc2NyaXB0b3JQcm90bzo6RXh0ZW5zaW9uUmFuZ2U6OmtFbmRGaWVsZE51bWJlcik7CisgICAgICBpZiAoVHJ5Q29uc3VtZSgibWF4IikpIHsKKyAgICAgICAgLy8gU2V0IHRvIHRoZSBzZW50aW5lbCB2YWx1ZSAtIDEgc2luY2Ugd2UgaW5jcmVtZW50IHRoZSB2YWx1ZSBiZWxvdy4KKyAgICAgICAgLy8gVGhlIGFjdHVhbCB2YWx1ZSBvZiB0aGUgZW5kIG9mIHRoZSByYW5nZSBzaG91bGQgYmUgc2V0IHdpdGgKKyAgICAgICAgLy8gQWRqdXN0RXh0ZW5zaW9uUmFuZ2VzV2l0aE1heEVuZE51bWJlci4KKyAgICAgICAgZW5kID0ga01heEV4dGVuc2lvblJhbmdlU2VudGluZWwgLSAxOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgRE8oQ29uc3VtZUludGVnZXIoJmVuZCwgIkV4cGVjdGVkIGludGVnZXIuIikpOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICBMb2NhdGlvblJlY29yZGVyIGVuZF9sb2NhdGlvbigKKyAgICAgICAgICBsb2NhdGlvbiwgRGVzY3JpcHRvclByb3RvOjpFeHRlbnNpb25SYW5nZTo6a0VuZEZpZWxkTnVtYmVyKTsKKyAgICAgIGVuZF9sb2NhdGlvbi5TdGFydEF0KHN0YXJ0X3Rva2VuKTsKKyAgICAgIGVuZF9sb2NhdGlvbi5FbmRBdChzdGFydF90b2tlbik7CisgICAgICBlbmQgPSBzdGFydDsKKyAgICB9CisKKyAgICAvLyBVc2VycyBsaWtlIHRvIHNwZWNpZnkgaW5jbHVzaXZlIHJhbmdlcywgYnV0IGluIGNvZGUgd2UgbGlrZSB0aGUgZW5kCisgICAgLy8gbnVtYmVyIHRvIGJlIGV4Y2x1c2l2ZS4KKyAgICArK2VuZDsKKworICAgIHJhbmdlLT5zZXRfc3RhcnQoc3RhcnQpOworICAgIHJhbmdlLT5zZXRfZW5kKGVuZCk7CisgIH0gd2hpbGUgKFRyeUNvbnN1bWUoIiwiKSk7CisKKyAgRE8oQ29uc3VtZUVuZE9mRGVjbGFyYXRpb24oIjsiLCAmZXh0ZW5zaW9uc19sb2NhdGlvbikpOworICByZXR1cm4gdHJ1ZTsKK30KKworLy8gVGhpcyBpcyBzaW1pbGFyIHRvIGV4dGVuc2lvbiByYW5nZSBwYXJzaW5nLCBleGNlcHQgdGhhdCAibWF4IiBpcyBub3QKKy8vIHN1cHBvcnRlZCwgYW5kIGFjY2VwdHMgZmllbGQgbmFtZSBsaXRlcmFscy4KK2Jvb2wgUGFyc2VyOjpQYXJzZVJlc2VydmVkKERlc2NyaXB0b3JQcm90byogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIG1lc3NhZ2VfbG9jYXRpb24pIHsKKyAgLy8gUGFyc2UgdGhlIGRlY2xhcmF0aW9uLgorICBETyhDb25zdW1lKCJyZXNlcnZlZCIpKTsKKyAgaWYgKExvb2tpbmdBdFR5cGUoaW86OlRva2VuaXplcjo6VFlQRV9TVFJJTkcpKSB7CisgICAgTG9jYXRpb25SZWNvcmRlciBsb2NhdGlvbihtZXNzYWdlX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVzY3JpcHRvclByb3RvOjprUmVzZXJ2ZWROYW1lRmllbGROdW1iZXIpOworICAgIHJldHVybiBQYXJzZVJlc2VydmVkTmFtZXMobWVzc2FnZSwgbG9jYXRpb24pOworICB9IGVsc2UgeworICAgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24obWVzc2FnZV9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlc2NyaXB0b3JQcm90bzo6a1Jlc2VydmVkUmFuZ2VGaWVsZE51bWJlcik7CisgICAgcmV0dXJuIFBhcnNlUmVzZXJ2ZWROdW1iZXJzKG1lc3NhZ2UsIGxvY2F0aW9uKTsKKyAgfQorfQorCisKK2Jvb2wgUGFyc2VyOjpQYXJzZVJlc2VydmVkTmFtZXMoRGVzY3JpcHRvclByb3RvKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiBwYXJlbnRfbG9jYXRpb24pIHsKKyAgZG8geworICAgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24ocGFyZW50X2xvY2F0aW9uLCBtZXNzYWdlLT5yZXNlcnZlZF9uYW1lX3NpemUoKSk7CisgICAgRE8oQ29uc3VtZVN0cmluZyhtZXNzYWdlLT5hZGRfcmVzZXJ2ZWRfbmFtZSgpLCAiRXhwZWN0ZWQgZmllbGQgbmFtZS4iKSk7CisgIH0gd2hpbGUgKFRyeUNvbnN1bWUoIiwiKSk7CisgIERPKENvbnN1bWVFbmRPZkRlY2xhcmF0aW9uKCI7IiwgJnBhcmVudF9sb2NhdGlvbikpOworICByZXR1cm4gdHJ1ZTsKK30KKworYm9vbCBQYXJzZXI6OlBhcnNlUmVzZXJ2ZWROdW1iZXJzKERlc2NyaXB0b3JQcm90byogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiBwYXJlbnRfbG9jYXRpb24pIHsKKyAgYm9vbCBmaXJzdCA9IHRydWU7CisgIGRvIHsKKyAgICBMb2NhdGlvblJlY29yZGVyIGxvY2F0aW9uKHBhcmVudF9sb2NhdGlvbiwgbWVzc2FnZS0+cmVzZXJ2ZWRfcmFuZ2Vfc2l6ZSgpKTsKKworICAgIERlc2NyaXB0b3JQcm90bzo6UmVzZXJ2ZWRSYW5nZSogcmFuZ2UgPSBtZXNzYWdlLT5hZGRfcmVzZXJ2ZWRfcmFuZ2UoKTsKKyAgICBpbnQgc3RhcnQsIGVuZDsKKyAgICBpbzo6VG9rZW5pemVyOjpUb2tlbiBzdGFydF90b2tlbjsKKyAgICB7CisgICAgICBMb2NhdGlvblJlY29yZGVyIHN0YXJ0X2xvY2F0aW9uKAorICAgICAgICAgIGxvY2F0aW9uLCBEZXNjcmlwdG9yUHJvdG86OlJlc2VydmVkUmFuZ2U6OmtTdGFydEZpZWxkTnVtYmVyKTsKKyAgICAgIHN0YXJ0X3Rva2VuID0gaW5wdXRfLT5jdXJyZW50KCk7CisgICAgICBETyhDb25zdW1lSW50ZWdlcigmc3RhcnQsIChmaXJzdCA/CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRXhwZWN0ZWQgZmllbGQgbmFtZSBvciBudW1iZXIgcmFuZ2UuIiA6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRXhwZWN0ZWQgZmllbGQgbnVtYmVyIHJhbmdlLiIpKSk7CisgICAgfQorCisgICAgaWYgKFRyeUNvbnN1bWUoInRvIikpIHsKKyAgICAgIExvY2F0aW9uUmVjb3JkZXIgZW5kX2xvY2F0aW9uKAorICAgICAgICAgIGxvY2F0aW9uLCBEZXNjcmlwdG9yUHJvdG86OlJlc2VydmVkUmFuZ2U6OmtFbmRGaWVsZE51bWJlcik7CisgICAgICBETyhDb25zdW1lSW50ZWdlcigmZW5kLCAiRXhwZWN0ZWQgaW50ZWdlci4iKSk7CisgICAgfSBlbHNlIHsKKyAgICAgIExvY2F0aW9uUmVjb3JkZXIgZW5kX2xvY2F0aW9uKAorICAgICAgICAgIGxvY2F0aW9uLCBEZXNjcmlwdG9yUHJvdG86OlJlc2VydmVkUmFuZ2U6OmtFbmRGaWVsZE51bWJlcik7CisgICAgICBlbmRfbG9jYXRpb24uU3RhcnRBdChzdGFydF90b2tlbik7CisgICAgICBlbmRfbG9jYXRpb24uRW5kQXQoc3RhcnRfdG9rZW4pOworICAgICAgZW5kID0gc3RhcnQ7CisgICAgfQorCisgICAgLy8gVXNlcnMgbGlrZSB0byBzcGVjaWZ5IGluY2x1c2l2ZSByYW5nZXMsIGJ1dCBpbiBjb2RlIHdlIGxpa2UgdGhlIGVuZAorICAgIC8vIG51bWJlciB0byBiZSBleGNsdXNpdmUuCisgICAgKytlbmQ7CisKKyAgICByYW5nZS0+c2V0X3N0YXJ0KHN0YXJ0KTsKKyAgICByYW5nZS0+c2V0X2VuZChlbmQpOworICAgIGZpcnN0ID0gZmFsc2U7CisgIH0gd2hpbGUgKFRyeUNvbnN1bWUoIiwiKSk7CisKKyAgRE8oQ29uc3VtZUVuZE9mRGVjbGFyYXRpb24oIjsiLCAmcGFyZW50X2xvY2F0aW9uKSk7CisgIHJldHVybiB0cnVlOworfQorCitib29sIFBhcnNlcjo6UGFyc2VFeHRlbmQoUmVwZWF0ZWRQdHJGaWVsZDxGaWVsZERlc2NyaXB0b3JQcm90bz4qIGV4dGVuc2lvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgUmVwZWF0ZWRQdHJGaWVsZDxEZXNjcmlwdG9yUHJvdG8+KiBtZXNzYWdlcywKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiBwYXJlbnRfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGxvY2F0aW9uX2ZpZWxkX251bWJlcl9mb3JfbmVzdGVkX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTG9jYXRpb25SZWNvcmRlciYgZXh0ZW5kX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfZmlsZSkgeworICBETyhDb25zdW1lKCJleHRlbmQiKSk7CisKKyAgLy8gUGFyc2UgdGhlIGV4dGVuZGVlIHR5cGUuCisgIGlvOjpUb2tlbml6ZXI6OlRva2VuIGV4dGVuZGVlX3N0YXJ0ID0gaW5wdXRfLT5jdXJyZW50KCk7CisgIHN0cmluZyBleHRlbmRlZTsKKyAgRE8oUGFyc2VVc2VyRGVmaW5lZFR5cGUoJmV4dGVuZGVlKSk7CisgIGlvOjpUb2tlbml6ZXI6OlRva2VuIGV4dGVuZGVlX2VuZCA9IGlucHV0Xy0+cHJldmlvdXMoKTsKKworICAvLyBQYXJzZSB0aGUgYmxvY2suCisgIERPKENvbnN1bWVFbmRPZkRlY2xhcmF0aW9uKCJ7IiwgJmV4dGVuZF9sb2NhdGlvbikpOworCisgIGJvb2wgaXNfZmlyc3QgPSB0cnVlOworCisgIGRvIHsKKyAgICBpZiAoQXRFbmQoKSkgeworICAgICAgQWRkRXJyb3IoIlJlYWNoZWQgZW5kIG9mIGlucHV0IGluIGV4dGVuZCBkZWZpbml0aW9uIChtaXNzaW5nICd9JykuIik7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLy8gTm90ZSB0aGF0IGtFeHRlbnNpb25GaWVsZE51bWJlciB3YXMgYWxyZWFkeSBwdXNoZWQgYnkgdGhlIHBhcmVudC4KKyAgICBMb2NhdGlvblJlY29yZGVyIGxvY2F0aW9uKGV4dGVuZF9sb2NhdGlvbiwgZXh0ZW5zaW9ucy0+c2l6ZSgpKTsKKworICAgIEZpZWxkRGVzY3JpcHRvclByb3RvKiBmaWVsZCA9IGV4dGVuc2lvbnMtPkFkZCgpOworCisgICAgeworICAgICAgTG9jYXRpb25SZWNvcmRlciBleHRlbmRlZV9sb2NhdGlvbigKKyAgICAgICAgICBsb2NhdGlvbiwgRmllbGREZXNjcmlwdG9yUHJvdG86OmtFeHRlbmRlZUZpZWxkTnVtYmVyKTsKKyAgICAgIGV4dGVuZGVlX2xvY2F0aW9uLlN0YXJ0QXQoZXh0ZW5kZWVfc3RhcnQpOworICAgICAgZXh0ZW5kZWVfbG9jYXRpb24uRW5kQXQoZXh0ZW5kZWVfZW5kKTsKKworICAgICAgaWYgKGlzX2ZpcnN0KSB7CisgICAgICAgIGV4dGVuZGVlX2xvY2F0aW9uLlJlY29yZExlZ2FjeUxvY2F0aW9uKAorICAgICAgICAgICAgZmllbGQsIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6RVhURU5ERUUpOworICAgICAgICBpc19maXJzdCA9IGZhbHNlOworICAgICAgfQorICAgIH0KKworICAgIGZpZWxkLT5zZXRfZXh0ZW5kZWUoZXh0ZW5kZWUpOworCisgICAgaWYgKCFQYXJzZU1lc3NhZ2VGaWVsZChmaWVsZCwgbWVzc2FnZXMsIHBhcmVudF9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2F0aW9uX2ZpZWxkX251bWJlcl9mb3JfbmVzdGVkX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRhaW5pbmdfZmlsZSkpIHsKKyAgICAgIC8vIFRoaXMgc3RhdGVtZW50IGZhaWxlZCB0byBwYXJzZS4gIFNraXAgaXQsIGJ1dCBrZWVwIGxvb3BpbmcgdG8gcGFyc2UKKyAgICAgIC8vIG90aGVyIHN0YXRlbWVudHMuCisgICAgICBTa2lwU3RhdGVtZW50KCk7CisgICAgfQorICB9IHdoaWxlICghVHJ5Q29uc3VtZUVuZE9mRGVjbGFyYXRpb24oIn0iLCBOVUxMKSk7CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgUGFyc2VyOjpQYXJzZU9uZW9mKE9uZW9mRGVzY3JpcHRvclByb3RvKiBvbmVvZl9kZWNsLAorICAgICAgICAgICAgICAgICAgICAgICAgRGVzY3JpcHRvclByb3RvKiBjb250YWluaW5nX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICBpbnQgb25lb2ZfaW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiBvbmVvZl9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIGNvbnRhaW5pbmdfdHlwZV9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfZmlsZSkgeworICBETyhDb25zdW1lKCJvbmVvZiIpKTsKKworICB7CisgICAgTG9jYXRpb25SZWNvcmRlciBuYW1lX2xvY2F0aW9uKG9uZW9mX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPbmVvZkRlc2NyaXB0b3JQcm90bzo6a05hbWVGaWVsZE51bWJlcik7CisgICAgRE8oQ29uc3VtZUlkZW50aWZpZXIob25lb2ZfZGVjbC0+bXV0YWJsZV9uYW1lKCksICJFeHBlY3RlZCBvbmVvZiBuYW1lLiIpKTsKKyAgfQorCisgIERPKENvbnN1bWVFbmRPZkRlY2xhcmF0aW9uKCJ7IiwgJm9uZW9mX2xvY2F0aW9uKSk7CisKKyAgZG8geworICAgIGlmIChBdEVuZCgpKSB7CisgICAgICBBZGRFcnJvcigiUmVhY2hlZCBlbmQgb2YgaW5wdXQgaW4gb25lb2YgZGVmaW5pdGlvbiAobWlzc2luZyAnfScpLiIpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8vIFByaW50IGEgbmljZSBlcnJvciBpZiB0aGUgdXNlciBhY2NpZGVudGFsbHkgdHJpZXMgdG8gcGxhY2UgYSBsYWJlbAorICAgIC8vIG9uIGFuIGluZGl2aWR1YWwgbWVtYmVyIG9mIGEgb25lb2YuCisgICAgaWYgKExvb2tpbmdBdCgicmVxdWlyZWQiKSB8fAorICAgICAgICBMb29raW5nQXQoIm9wdGlvbmFsIikgfHwKKyAgICAgICAgTG9va2luZ0F0KCJyZXBlYXRlZCIpKSB7CisgICAgICBBZGRFcnJvcigiRmllbGRzIGluIG9uZW9mcyBtdXN0IG5vdCBoYXZlIGxhYmVscyAocmVxdWlyZWQgLyBvcHRpb25hbCAiCisgICAgICAgICAgICAgICAiLyByZXBlYXRlZCkuIik7CisgICAgICAvLyBXZSBjYW4gY29udGludWUgcGFyc2luZyBoZXJlIGJlY2F1c2Ugd2UgdW5kZXJzdGFuZCB3aGF0IHRoZSB1c2VyCisgICAgICAvLyBtZWFudC4gIFRoZSBlcnJvciByZXBvcnQgd2lsbCBzdGlsbCBtYWtlIHBhcnNpbmcgZmFpbCBvdmVyYWxsLgorICAgICAgaW5wdXRfLT5OZXh0KCk7CisgICAgfQorCisgICAgTG9jYXRpb25SZWNvcmRlciBmaWVsZF9sb2NhdGlvbihjb250YWluaW5nX3R5cGVfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZXNjcmlwdG9yUHJvdG86OmtGaWVsZEZpZWxkTnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGFpbmluZ190eXBlLT5maWVsZF9zaXplKCkpOworCisgICAgRmllbGREZXNjcmlwdG9yUHJvdG8qIGZpZWxkID0gY29udGFpbmluZ190eXBlLT5hZGRfZmllbGQoKTsKKyAgICBmaWVsZC0+c2V0X2xhYmVsKEZpZWxkRGVzY3JpcHRvclByb3RvOjpMQUJFTF9PUFRJT05BTCk7CisgICAgZmllbGQtPnNldF9vbmVvZl9pbmRleChvbmVvZl9pbmRleCk7CisKKyAgICBpZiAoIVBhcnNlTWVzc2FnZUZpZWxkTm9MYWJlbChmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250YWluaW5nX3R5cGUtPm11dGFibGVfbmVzdGVkX3R5cGUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250YWluaW5nX3R5cGVfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVzY3JpcHRvclByb3RvOjprTmVzdGVkVHlwZUZpZWxkTnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRhaW5pbmdfZmlsZSkpIHsKKyAgICAgIC8vIFRoaXMgc3RhdGVtZW50IGZhaWxlZCB0byBwYXJzZS4gIFNraXAgaXQsIGJ1dCBrZWVwIGxvb3BpbmcgdG8gcGFyc2UKKyAgICAgIC8vIG90aGVyIHN0YXRlbWVudHMuCisgICAgICBTa2lwU3RhdGVtZW50KCk7CisgICAgfQorICB9IHdoaWxlICghVHJ5Q29uc3VtZUVuZE9mRGVjbGFyYXRpb24oIn0iLCBOVUxMKSk7CisKKyAgcmV0dXJuIHRydWU7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIEVudW1zCisKK2Jvb2wgUGFyc2VyOjpQYXJzZUVudW1EZWZpbml0aW9uKEVudW1EZXNjcmlwdG9yUHJvdG8qIGVudW1fdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIGVudW1fbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvKiBjb250YWluaW5nX2ZpbGUpIHsKKyAgRE8oQ29uc3VtZSgiZW51bSIpKTsKKworICB7CisgICAgTG9jYXRpb25SZWNvcmRlciBsb2NhdGlvbihlbnVtX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRW51bURlc2NyaXB0b3JQcm90bzo6a05hbWVGaWVsZE51bWJlcik7CisgICAgbG9jYXRpb24uUmVjb3JkTGVnYWN5TG9jYXRpb24oCisgICAgICAgIGVudW1fdHlwZSwgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpOQU1FKTsKKyAgICBETyhDb25zdW1lSWRlbnRpZmllcihlbnVtX3R5cGUtPm11dGFibGVfbmFtZSgpLCAiRXhwZWN0ZWQgZW51bSBuYW1lLiIpKTsKKyAgfQorCisgIERPKFBhcnNlRW51bUJsb2NrKGVudW1fdHlwZSwgZW51bV9sb2NhdGlvbiwgY29udGFpbmluZ19maWxlKSk7CisKKyAgRE8oVmFsaWRhdGVFbnVtKGVudW1fdHlwZSkpOworCisgIHJldHVybiB0cnVlOworfQorCitib29sIFBhcnNlcjo6UGFyc2VFbnVtQmxvY2soRW51bURlc2NyaXB0b3JQcm90byogZW51bV90eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIGVudW1fbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byogY29udGFpbmluZ19maWxlKSB7CisgIERPKENvbnN1bWVFbmRPZkRlY2xhcmF0aW9uKCJ7IiwgJmVudW1fbG9jYXRpb24pKTsKKworICB3aGlsZSAoIVRyeUNvbnN1bWVFbmRPZkRlY2xhcmF0aW9uKCJ9IiwgTlVMTCkpIHsKKyAgICBpZiAoQXRFbmQoKSkgeworICAgICAgQWRkRXJyb3IoIlJlYWNoZWQgZW5kIG9mIGlucHV0IGluIGVudW0gZGVmaW5pdGlvbiAobWlzc2luZyAnfScpLiIpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIGlmICghUGFyc2VFbnVtU3RhdGVtZW50KGVudW1fdHlwZSwgZW51bV9sb2NhdGlvbiwgY29udGFpbmluZ19maWxlKSkgeworICAgICAgLy8gVGhpcyBzdGF0ZW1lbnQgZmFpbGVkIHRvIHBhcnNlLiAgU2tpcCBpdCwgYnV0IGtlZXAgbG9vcGluZyB0byBwYXJzZQorICAgICAgLy8gb3RoZXIgc3RhdGVtZW50cy4KKyAgICAgIFNraXBTdGF0ZW1lbnQoKTsKKyAgICB9CisgIH0KKworICByZXR1cm4gdHJ1ZTsKK30KKworYm9vbCBQYXJzZXI6OlBhcnNlRW51bVN0YXRlbWVudChFbnVtRGVzY3JpcHRvclByb3RvKiBlbnVtX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIGVudW1fbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfZmlsZSkgeworICBpZiAoVHJ5Q29uc3VtZUVuZE9mRGVjbGFyYXRpb24oIjsiLCBOVUxMKSkgeworICAgIC8vIGVtcHR5IHN0YXRlbWVudDsgaWdub3JlCisgICAgcmV0dXJuIHRydWU7CisgIH0gZWxzZSBpZiAoTG9va2luZ0F0KCJvcHRpb24iKSkgeworICAgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24oZW51bV9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVudW1EZXNjcmlwdG9yUHJvdG86OmtPcHRpb25zRmllbGROdW1iZXIpOworICAgIHJldHVybiBQYXJzZU9wdGlvbihlbnVtX3R5cGUtPm11dGFibGVfb3B0aW9ucygpLCBsb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgY29udGFpbmluZ19maWxlLCBPUFRJT05fU1RBVEVNRU5UKTsKKyAgfSBlbHNlIHsKKyAgICBMb2NhdGlvblJlY29yZGVyIGxvY2F0aW9uKGVudW1fbG9jYXRpb24sCisgICAgICAgIEVudW1EZXNjcmlwdG9yUHJvdG86OmtWYWx1ZUZpZWxkTnVtYmVyLCBlbnVtX3R5cGUtPnZhbHVlX3NpemUoKSk7CisgICAgcmV0dXJuIFBhcnNlRW51bUNvbnN0YW50KGVudW1fdHlwZS0+YWRkX3ZhbHVlKCksIGxvY2F0aW9uLCBjb250YWluaW5nX2ZpbGUpOworICB9Cit9CisKK2Jvb2wgUGFyc2VyOjpQYXJzZUVudW1Db25zdGFudChFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8qIGVudW1fdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTG9jYXRpb25SZWNvcmRlciYgZW51bV92YWx1ZV9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvKiBjb250YWluaW5nX2ZpbGUpIHsKKyAgLy8gUGFyc2UgbmFtZS4KKyAgeworICAgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24oZW51bV92YWx1ZV9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6a05hbWVGaWVsZE51bWJlcik7CisgICAgbG9jYXRpb24uUmVjb3JkTGVnYWN5TG9jYXRpb24oCisgICAgICAgIGVudW1fdmFsdWUsIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6TkFNRSk7CisgICAgRE8oQ29uc3VtZUlkZW50aWZpZXIoZW51bV92YWx1ZS0+bXV0YWJsZV9uYW1lKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgIkV4cGVjdGVkIGVudW0gY29uc3RhbnQgbmFtZS4iKSk7CisgIH0KKworICBETyhDb25zdW1lKCI9IiwgIk1pc3NpbmcgbnVtZXJpYyB2YWx1ZSBmb3IgZW51bSBjb25zdGFudC4iKSk7CisKKyAgLy8gUGFyc2UgdmFsdWUuCisgIHsKKyAgICBMb2NhdGlvblJlY29yZGVyIGxvY2F0aW9uKAorICAgICAgICBlbnVtX3ZhbHVlX2xvY2F0aW9uLCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86OmtOdW1iZXJGaWVsZE51bWJlcik7CisgICAgbG9jYXRpb24uUmVjb3JkTGVnYWN5TG9jYXRpb24oCisgICAgICAgIGVudW1fdmFsdWUsIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6TlVNQkVSKTsKKworICAgIGludCBudW1iZXI7CisgICAgRE8oQ29uc3VtZVNpZ25lZEludGVnZXIoJm51bWJlciwgIkV4cGVjdGVkIGludGVnZXIuIikpOworICAgIGVudW1fdmFsdWUtPnNldF9udW1iZXIobnVtYmVyKTsKKyAgfQorCisgIERPKFBhcnNlRW51bUNvbnN0YW50T3B0aW9ucyhlbnVtX3ZhbHVlLCBlbnVtX3ZhbHVlX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGFpbmluZ19maWxlKSk7CisKKyAgRE8oQ29uc3VtZUVuZE9mRGVjbGFyYXRpb24oIjsiLCAmZW51bV92YWx1ZV9sb2NhdGlvbikpOworCisgIHJldHVybiB0cnVlOworfQorCitib29sIFBhcnNlcjo6UGFyc2VFbnVtQ29uc3RhbnRPcHRpb25zKAorICAgIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90byogdmFsdWUsCisgICAgY29uc3QgTG9jYXRpb25SZWNvcmRlciYgZW51bV92YWx1ZV9sb2NhdGlvbiwKKyAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvKiBjb250YWluaW5nX2ZpbGUpIHsKKyAgaWYgKCFMb29raW5nQXQoIlsiKSkgcmV0dXJuIHRydWU7CisKKyAgTG9jYXRpb25SZWNvcmRlciBsb2NhdGlvbigKKyAgICAgIGVudW1fdmFsdWVfbG9jYXRpb24sIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6a09wdGlvbnNGaWVsZE51bWJlcik7CisKKyAgRE8oQ29uc3VtZSgiWyIpKTsKKworICBkbyB7CisgICAgRE8oUGFyc2VPcHRpb24odmFsdWUtPm11dGFibGVfb3B0aW9ucygpLCBsb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICBjb250YWluaW5nX2ZpbGUsIE9QVElPTl9BU1NJR05NRU5UKSk7CisgIH0gd2hpbGUgKFRyeUNvbnN1bWUoIiwiKSk7CisKKyAgRE8oQ29uc3VtZSgiXSIpKTsKKyAgcmV0dXJuIHRydWU7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIFNlcnZpY2VzCisKK2Jvb2wgUGFyc2VyOjpQYXJzZVNlcnZpY2VEZWZpbml0aW9uKAorICAgIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG8qIHNlcnZpY2UsCisgICAgY29uc3QgTG9jYXRpb25SZWNvcmRlciYgc2VydmljZV9sb2NhdGlvbiwKKyAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvKiBjb250YWluaW5nX2ZpbGUpIHsKKyAgRE8oQ29uc3VtZSgic2VydmljZSIpKTsKKworICB7CisgICAgTG9jYXRpb25SZWNvcmRlciBsb2NhdGlvbihzZXJ2aWNlX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2VydmljZURlc2NyaXB0b3JQcm90bzo6a05hbWVGaWVsZE51bWJlcik7CisgICAgbG9jYXRpb24uUmVjb3JkTGVnYWN5TG9jYXRpb24oCisgICAgICAgIHNlcnZpY2UsIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6TkFNRSk7CisgICAgRE8oQ29uc3VtZUlkZW50aWZpZXIoc2VydmljZS0+bXV0YWJsZV9uYW1lKCksICJFeHBlY3RlZCBzZXJ2aWNlIG5hbWUuIikpOworICB9CisKKyAgRE8oUGFyc2VTZXJ2aWNlQmxvY2soc2VydmljZSwgc2VydmljZV9sb2NhdGlvbiwgY29udGFpbmluZ19maWxlKSk7CisgIHJldHVybiB0cnVlOworfQorCitib29sIFBhcnNlcjo6UGFyc2VTZXJ2aWNlQmxvY2soU2VydmljZURlc2NyaXB0b3JQcm90byogc2VydmljZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiBzZXJ2aWNlX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfZmlsZSkgeworICBETyhDb25zdW1lRW5kT2ZEZWNsYXJhdGlvbigieyIsICZzZXJ2aWNlX2xvY2F0aW9uKSk7CisKKyAgd2hpbGUgKCFUcnlDb25zdW1lRW5kT2ZEZWNsYXJhdGlvbigifSIsIE5VTEwpKSB7CisgICAgaWYgKEF0RW5kKCkpIHsKKyAgICAgIEFkZEVycm9yKCJSZWFjaGVkIGVuZCBvZiBpbnB1dCBpbiBzZXJ2aWNlIGRlZmluaXRpb24gKG1pc3NpbmcgJ30nKS4iKTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBpZiAoIVBhcnNlU2VydmljZVN0YXRlbWVudChzZXJ2aWNlLCBzZXJ2aWNlX2xvY2F0aW9uLCBjb250YWluaW5nX2ZpbGUpKSB7CisgICAgICAvLyBUaGlzIHN0YXRlbWVudCBmYWlsZWQgdG8gcGFyc2UuICBTa2lwIGl0LCBidXQga2VlcCBsb29waW5nIHRvIHBhcnNlCisgICAgICAvLyBvdGhlciBzdGF0ZW1lbnRzLgorICAgICAgU2tpcFN0YXRlbWVudCgpOworICAgIH0KKyAgfQorCisgIHJldHVybiB0cnVlOworfQorCitib29sIFBhcnNlcjo6UGFyc2VTZXJ2aWNlU3RhdGVtZW50KFNlcnZpY2VEZXNjcmlwdG9yUHJvdG8qIHNlcnZpY2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIHNlcnZpY2VfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfZmlsZSkgeworICBpZiAoVHJ5Q29uc3VtZUVuZE9mRGVjbGFyYXRpb24oIjsiLCBOVUxMKSkgeworICAgIC8vIGVtcHR5IHN0YXRlbWVudDsgaWdub3JlCisgICAgcmV0dXJuIHRydWU7CisgIH0gZWxzZSBpZiAoTG9va2luZ0F0KCJvcHRpb24iKSkgeworICAgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24oCisgICAgICAgIHNlcnZpY2VfbG9jYXRpb24sIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86OmtPcHRpb25zRmllbGROdW1iZXIpOworICAgIHJldHVybiBQYXJzZU9wdGlvbihzZXJ2aWNlLT5tdXRhYmxlX29wdGlvbnMoKSwgbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgIGNvbnRhaW5pbmdfZmlsZSwgT1BUSU9OX1NUQVRFTUVOVCk7CisgIH0gZWxzZSB7CisgICAgTG9jYXRpb25SZWNvcmRlciBsb2NhdGlvbihzZXJ2aWNlX2xvY2F0aW9uLAorICAgICAgICBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjprTWV0aG9kRmllbGROdW1iZXIsIHNlcnZpY2UtPm1ldGhvZF9zaXplKCkpOworICAgIHJldHVybiBQYXJzZVNlcnZpY2VNZXRob2Qoc2VydmljZS0+YWRkX21ldGhvZCgpLCBsb2NhdGlvbiwgY29udGFpbmluZ19maWxlKTsKKyAgfQorfQorCitib29sIFBhcnNlcjo6UGFyc2VTZXJ2aWNlTWV0aG9kKE1ldGhvZERlc2NyaXB0b3JQcm90byogbWV0aG9kLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiBtZXRob2RfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfZmlsZSkgeworICBETyhDb25zdW1lKCJycGMiKSk7CisKKyAgeworICAgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24obWV0aG9kX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWV0aG9kRGVzY3JpcHRvclByb3RvOjprTmFtZUZpZWxkTnVtYmVyKTsKKyAgICBsb2NhdGlvbi5SZWNvcmRMZWdhY3lMb2NhdGlvbigKKyAgICAgICAgbWV0aG9kLCBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok5BTUUpOworICAgIERPKENvbnN1bWVJZGVudGlmaWVyKG1ldGhvZC0+bXV0YWJsZV9uYW1lKCksICJFeHBlY3RlZCBtZXRob2QgbmFtZS4iKSk7CisgIH0KKworICAvLyBQYXJzZSBpbnB1dCB0eXBlLgorICBETyhDb25zdW1lKCIoIikpOworICB7CisgICAgaWYgKExvb2tpbmdBdCgic3RyZWFtIikpIHsKKyAgICAgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24oCisgICAgICAgICAgbWV0aG9kX2xvY2F0aW9uLCBNZXRob2REZXNjcmlwdG9yUHJvdG86OmtDbGllbnRTdHJlYW1pbmdGaWVsZE51bWJlcik7CisgICAgICBsb2NhdGlvbi5SZWNvcmRMZWdhY3lMb2NhdGlvbigKKyAgICAgICAgICBtZXRob2QsIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6T1RIRVIpOworICAgICAgbWV0aG9kLT5zZXRfY2xpZW50X3N0cmVhbWluZyh0cnVlKTsKKyAgICAgIERPKENvbnN1bWUoInN0cmVhbSIpKTsKKworICAgIH0KKyAgICBMb2NhdGlvblJlY29yZGVyIGxvY2F0aW9uKG1ldGhvZF9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6a0lucHV0VHlwZUZpZWxkTnVtYmVyKTsKKyAgICBsb2NhdGlvbi5SZWNvcmRMZWdhY3lMb2NhdGlvbigKKyAgICAgICAgbWV0aG9kLCBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6OklOUFVUX1RZUEUpOworICAgIERPKFBhcnNlVXNlckRlZmluZWRUeXBlKG1ldGhvZC0+bXV0YWJsZV9pbnB1dF90eXBlKCkpKTsKKyAgfQorICBETyhDb25zdW1lKCIpIikpOworCisgIC8vIFBhcnNlIG91dHB1dCB0eXBlLgorICBETyhDb25zdW1lKCJyZXR1cm5zIikpOworICBETyhDb25zdW1lKCIoIikpOworICB7CisgICAgaWYgKExvb2tpbmdBdCgic3RyZWFtIikpIHsKKyAgICAgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24oCisgICAgICAgICAgbWV0aG9kX2xvY2F0aW9uLCBNZXRob2REZXNjcmlwdG9yUHJvdG86OmtTZXJ2ZXJTdHJlYW1pbmdGaWVsZE51bWJlcik7CisgICAgICBsb2NhdGlvbi5SZWNvcmRMZWdhY3lMb2NhdGlvbigKKyAgICAgICAgICBtZXRob2QsIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6T1RIRVIpOworICAgICAgRE8oQ29uc3VtZSgic3RyZWFtIikpOworICAgICAgbWV0aG9kLT5zZXRfc2VydmVyX3N0cmVhbWluZyh0cnVlKTsKKworICAgIH0KKyAgICBMb2NhdGlvblJlY29yZGVyIGxvY2F0aW9uKG1ldGhvZF9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6a091dHB1dFR5cGVGaWVsZE51bWJlcik7CisgICAgbG9jYXRpb24uUmVjb3JkTGVnYWN5TG9jYXRpb24oCisgICAgICAgIG1ldGhvZCwgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpPVVRQVVRfVFlQRSk7CisgICAgRE8oUGFyc2VVc2VyRGVmaW5lZFR5cGUobWV0aG9kLT5tdXRhYmxlX291dHB1dF90eXBlKCkpKTsKKyAgfQorICBETyhDb25zdW1lKCIpIikpOworCisgIGlmIChMb29raW5nQXQoInsiKSkgeworICAgIC8vIE9wdGlvbnMhCisgICAgRE8oUGFyc2VNZXRob2RPcHRpb25zKG1ldGhvZF9sb2NhdGlvbiwgY29udGFpbmluZ19maWxlLAorICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2REZXNjcmlwdG9yUHJvdG86OmtPcHRpb25zRmllbGROdW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZC0+bXV0YWJsZV9vcHRpb25zKCkpKTsKKyAgfSBlbHNlIHsKKyAgICBETyhDb25zdW1lRW5kT2ZEZWNsYXJhdGlvbigiOyIsICZtZXRob2RfbG9jYXRpb24pKTsKKyAgfQorCisgIHJldHVybiB0cnVlOworfQorCisKK2Jvb2wgUGFyc2VyOjpQYXJzZU1ldGhvZE9wdGlvbnMoY29uc3QgTG9jYXRpb25SZWNvcmRlciYgcGFyZW50X2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvKiBjb250YWluaW5nX2ZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGludCBvcHRpb25zRmllbGROdW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UqIG11dGFibGVfb3B0aW9ucykgeworICAvLyBPcHRpb25zIQorICBDb25zdW1lRW5kT2ZEZWNsYXJhdGlvbigieyIsICZwYXJlbnRfbG9jYXRpb24pOworICB3aGlsZSAoIVRyeUNvbnN1bWVFbmRPZkRlY2xhcmF0aW9uKCJ9IiwgTlVMTCkpIHsKKyAgICBpZiAoQXRFbmQoKSkgeworICAgICAgQWRkRXJyb3IoIlJlYWNoZWQgZW5kIG9mIGlucHV0IGluIG1ldGhvZCBvcHRpb25zIChtaXNzaW5nICd9JykuIik7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgaWYgKFRyeUNvbnN1bWVFbmRPZkRlY2xhcmF0aW9uKCI7IiwgTlVMTCkpIHsKKyAgICAgIC8vIGVtcHR5IHN0YXRlbWVudDsgaWdub3JlCisgICAgfSBlbHNlIHsKKyAgICAgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24ocGFyZW50X2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zRmllbGROdW1iZXIpOworICAgICAgaWYgKCFQYXJzZU9wdGlvbihtdXRhYmxlX29wdGlvbnMsIGxvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICBjb250YWluaW5nX2ZpbGUsIE9QVElPTl9TVEFURU1FTlQpKSB7CisgICAgICAgIC8vIFRoaXMgc3RhdGVtZW50IGZhaWxlZCB0byBwYXJzZS4gIFNraXAgaXQsIGJ1dCBrZWVwIGxvb3BpbmcgdG8KKyAgICAgICAgLy8gcGFyc2Ugb3RoZXIgc3RhdGVtZW50cy4KKyAgICAgICAgU2tpcFN0YXRlbWVudCgpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIHJldHVybiB0cnVlOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2Jvb2wgUGFyc2VyOjpQYXJzZUxhYmVsKEZpZWxkRGVzY3JpcHRvclByb3RvOjpMYWJlbCogbGFiZWwsCisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvKiBjb250YWluaW5nX2ZpbGUpIHsKKyAgaWYgKFRyeUNvbnN1bWUoIm9wdGlvbmFsIikpIHsKKyAgICAqbGFiZWwgPSBGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfT1BUSU9OQUw7CisgICAgcmV0dXJuIHRydWU7CisgIH0gZWxzZSBpZiAoVHJ5Q29uc3VtZSgicmVwZWF0ZWQiKSkgeworICAgICpsYWJlbCA9IEZpZWxkRGVzY3JpcHRvclByb3RvOjpMQUJFTF9SRVBFQVRFRDsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfSBlbHNlIGlmIChUcnlDb25zdW1lKCJyZXF1aXJlZCIpKSB7CisgICAgKmxhYmVsID0gRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX1JFUVVJUkVEOworICAgIHJldHVybiB0cnVlOworICB9CisgIHJldHVybiBmYWxzZTsKK30KKworYm9vbCBQYXJzZXI6OlBhcnNlVHlwZShGaWVsZERlc2NyaXB0b3JQcm90bzo6VHlwZSogdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nKiB0eXBlX25hbWUpIHsKKyAgVHlwZU5hbWVNYXA6OmNvbnN0X2l0ZXJhdG9yIGl0ZXIgPSBrVHlwZU5hbWVzLmZpbmQoaW5wdXRfLT5jdXJyZW50KCkudGV4dCk7CisgIGlmIChpdGVyICE9IGtUeXBlTmFtZXMuZW5kKCkpIHsKKyAgICAqdHlwZSA9IGl0ZXItPnNlY29uZDsKKyAgICBpbnB1dF8tPk5leHQoKTsKKyAgfSBlbHNlIHsKKyAgICBETyhQYXJzZVVzZXJEZWZpbmVkVHlwZSh0eXBlX25hbWUpKTsKKyAgfQorICByZXR1cm4gdHJ1ZTsKK30KKworYm9vbCBQYXJzZXI6OlBhcnNlVXNlckRlZmluZWRUeXBlKHN0cmluZyogdHlwZV9uYW1lKSB7CisgIHR5cGVfbmFtZS0+Y2xlYXIoKTsKKworICBUeXBlTmFtZU1hcDo6Y29uc3RfaXRlcmF0b3IgaXRlciA9IGtUeXBlTmFtZXMuZmluZChpbnB1dF8tPmN1cnJlbnQoKS50ZXh0KTsKKyAgaWYgKGl0ZXIgIT0ga1R5cGVOYW1lcy5lbmQoKSkgeworICAgIC8vIE5vdGU6ICBUaGUgb25seSBwbGFjZSBlbnVtIHR5cGVzIGFyZSBhbGxvd2VkIGlzIGZvciBmaWVsZCB0eXBlcywgYnV0CisgICAgLy8gICBpZiB3ZSBhcmUgcGFyc2luZyBhIGZpZWxkIHR5cGUgdGhlbiB3ZSB3b3VsZCBub3QgZ2V0IGhlcmUgYmVjYXVzZQorICAgIC8vICAgcHJpbWl0aXZlcyBhcmUgYWxsb3dlZCB0aGVyZSBhcyB3ZWxsLiAgU28gdGhpcyBlcnJvciBtZXNzYWdlIGRvZXNuJ3QKKyAgICAvLyAgIG5lZWQgdG8gYWNjb3VudCBmb3IgZW51bXMuCisgICAgQWRkRXJyb3IoIkV4cGVjdGVkIG1lc3NhZ2UgdHlwZS4iKTsKKworICAgIC8vIFByZXRlbmQgdG8gYWNjZXB0IHRoaXMgdHlwZSBzbyB0aGF0IHdlIGNhbiBnbyBvbiBwYXJzaW5nLgorICAgICp0eXBlX25hbWUgPSBpbnB1dF8tPmN1cnJlbnQoKS50ZXh0OworICAgIGlucHV0Xy0+TmV4dCgpOworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgLy8gQSBsZWFkaW5nICIuIiBtZWFucyB0aGUgbmFtZSBpcyBmdWxseS1xdWFsaWZpZWQuCisgIGlmIChUcnlDb25zdW1lKCIuIikpIHR5cGVfbmFtZS0+YXBwZW5kKCIuIik7CisKKyAgLy8gQ29uc3VtZSB0aGUgZmlyc3QgcGFydCBvZiB0aGUgbmFtZS4KKyAgc3RyaW5nIGlkZW50aWZpZXI7CisgIERPKENvbnN1bWVJZGVudGlmaWVyKCZpZGVudGlmaWVyLCAiRXhwZWN0ZWQgdHlwZSBuYW1lLiIpKTsKKyAgdHlwZV9uYW1lLT5hcHBlbmQoaWRlbnRpZmllcik7CisKKyAgLy8gQ29uc3VtZSBtb3JlIHBhcnRzLgorICB3aGlsZSAoVHJ5Q29uc3VtZSgiLiIpKSB7CisgICAgdHlwZV9uYW1lLT5hcHBlbmQoIi4iKTsKKyAgICBETyhDb25zdW1lSWRlbnRpZmllcigmaWRlbnRpZmllciwgIkV4cGVjdGVkIGlkZW50aWZpZXIuIikpOworICAgIHR5cGVfbmFtZS0+YXBwZW5kKGlkZW50aWZpZXIpOworICB9CisKKyAgcmV0dXJuIHRydWU7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworYm9vbCBQYXJzZXI6OlBhcnNlUGFja2FnZShGaWxlRGVzY3JpcHRvclByb3RvKiBmaWxlLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiByb290X2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvKiBjb250YWluaW5nX2ZpbGUpIHsKKyAgaWYgKGZpbGUtPmhhc19wYWNrYWdlKCkpIHsKKyAgICBBZGRFcnJvcigiTXVsdGlwbGUgcGFja2FnZSBkZWZpbml0aW9ucy4iKTsKKyAgICAvLyBEb24ndCBhcHBlbmQgdGhlIG5ldyBwYWNrYWdlIHRvIHRoZSBvbGQgb25lLiAgSnVzdCByZXBsYWNlIGl0LiAgTm90CisgICAgLy8gdGhhdCBpdCByZWFsbHkgbWF0dGVycyBzaW5jZSB0aGlzIGlzIGFuIGVycm9yIGFueXdheS4KKyAgICBmaWxlLT5jbGVhcl9wYWNrYWdlKCk7CisgIH0KKworICBETyhDb25zdW1lKCJwYWNrYWdlIikpOworCisgIHsKKyAgICBMb2NhdGlvblJlY29yZGVyIGxvY2F0aW9uKHJvb3RfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlRGVzY3JpcHRvclByb3RvOjprUGFja2FnZUZpZWxkTnVtYmVyKTsKKyAgICBsb2NhdGlvbi5SZWNvcmRMZWdhY3lMb2NhdGlvbihmaWxlLCBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok5BTUUpOworCisgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgIHN0cmluZyBpZGVudGlmaWVyOworICAgICAgRE8oQ29uc3VtZUlkZW50aWZpZXIoJmlkZW50aWZpZXIsICJFeHBlY3RlZCBpZGVudGlmaWVyLiIpKTsKKyAgICAgIGZpbGUtPm11dGFibGVfcGFja2FnZSgpLT5hcHBlbmQoaWRlbnRpZmllcik7CisgICAgICBpZiAoIVRyeUNvbnN1bWUoIi4iKSkgYnJlYWs7CisgICAgICBmaWxlLT5tdXRhYmxlX3BhY2thZ2UoKS0+YXBwZW5kKCIuIik7CisgICAgfQorCisgICAgbG9jYXRpb24uRW5kQXQoaW5wdXRfLT5wcmV2aW91cygpKTsKKworICAgIERPKENvbnN1bWVFbmRPZkRlY2xhcmF0aW9uKCI7IiwgJmxvY2F0aW9uKSk7CisgIH0KKworICByZXR1cm4gdHJ1ZTsKK30KKworYm9vbCBQYXJzZXI6OlBhcnNlSW1wb3J0KFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPiogZGVwZW5kZW5jeSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBSZXBlYXRlZEZpZWxkPGludDMyPiogcHVibGljX2RlcGVuZGVuY3ksCisgICAgICAgICAgICAgICAgICAgICAgICAgUmVwZWF0ZWRGaWVsZDxpbnQzMj4qIHdlYWtfZGVwZW5kZW5jeSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiByb290X2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfZmlsZSkgeworICBETyhDb25zdW1lKCJpbXBvcnQiKSk7CisgIGlmIChMb29raW5nQXQoInB1YmxpYyIpKSB7CisgICAgTG9jYXRpb25SZWNvcmRlciBsb2NhdGlvbigKKyAgICAgICAgcm9vdF9sb2NhdGlvbiwgRmlsZURlc2NyaXB0b3JQcm90bzo6a1B1YmxpY0RlcGVuZGVuY3lGaWVsZE51bWJlciwKKyAgICAgICAgcHVibGljX2RlcGVuZGVuY3ktPnNpemUoKSk7CisgICAgRE8oQ29uc3VtZSgicHVibGljIikpOworICAgICpwdWJsaWNfZGVwZW5kZW5jeS0+QWRkKCkgPSBkZXBlbmRlbmN5LT5zaXplKCk7CisgIH0gZWxzZSBpZiAoTG9va2luZ0F0KCJ3ZWFrIikpIHsKKyAgICBMb2NhdGlvblJlY29yZGVyIGxvY2F0aW9uKAorICAgICAgICByb290X2xvY2F0aW9uLCBGaWxlRGVzY3JpcHRvclByb3RvOjprV2Vha0RlcGVuZGVuY3lGaWVsZE51bWJlciwKKyAgICAgICAgd2Vha19kZXBlbmRlbmN5LT5zaXplKCkpOworICAgIERPKENvbnN1bWUoIndlYWsiKSk7CisgICAgKndlYWtfZGVwZW5kZW5jeS0+QWRkKCkgPSBkZXBlbmRlbmN5LT5zaXplKCk7CisgIH0KKyAgeworICAgIExvY2F0aW9uUmVjb3JkZXIgbG9jYXRpb24ocm9vdF9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpbGVEZXNjcmlwdG9yUHJvdG86OmtEZXBlbmRlbmN5RmllbGROdW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXBlbmRlbmN5LT5zaXplKCkpOworICAgIERPKENvbnN1bWVTdHJpbmcoZGVwZW5kZW5jeS0+QWRkKCksCisgICAgICAiRXhwZWN0ZWQgYSBzdHJpbmcgbmFtaW5nIHRoZSBmaWxlIHRvIGltcG9ydC4iKSk7CisKKyAgICBsb2NhdGlvbi5FbmRBdChpbnB1dF8tPnByZXZpb3VzKCkpOworCisgICAgRE8oQ29uc3VtZUVuZE9mRGVjbGFyYXRpb24oIjsiLCAmbG9jYXRpb24pKTsKKyAgfQorICByZXR1cm4gdHJ1ZTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitTb3VyY2VMb2NhdGlvblRhYmxlOjpTb3VyY2VMb2NhdGlvblRhYmxlKCkge30KK1NvdXJjZUxvY2F0aW9uVGFibGU6On5Tb3VyY2VMb2NhdGlvblRhYmxlKCkge30KKworYm9vbCBTb3VyY2VMb2NhdGlvblRhYmxlOjpGaW5kKAorICAgIGNvbnN0IE1lc3NhZ2UqIGRlc2NyaXB0b3IsCisgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpFcnJvckxvY2F0aW9uIGxvY2F0aW9uLAorICAgIGludCogbGluZSwgaW50KiBjb2x1bW4pIGNvbnN0IHsKKyAgY29uc3QgcGFpcjxpbnQsIGludD4qIHJlc3VsdCA9CisgICAgICBGaW5kT3JOdWxsKGxvY2F0aW9uX21hcF8sIHN0ZDo6bWFrZV9wYWlyKGRlc2NyaXB0b3IsIGxvY2F0aW9uKSk7CisgIGlmIChyZXN1bHQgPT0gTlVMTCkgeworICAgICpsaW5lICAgPSAtMTsKKyAgICAqY29sdW1uID0gMDsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0gZWxzZSB7CisgICAgKmxpbmUgICA9IHJlc3VsdC0+Zmlyc3Q7CisgICAgKmNvbHVtbiA9IHJlc3VsdC0+c2Vjb25kOworICAgIHJldHVybiB0cnVlOworICB9Cit9CisKK3ZvaWQgU291cmNlTG9jYXRpb25UYWJsZTo6QWRkKAorICAgIGNvbnN0IE1lc3NhZ2UqIGRlc2NyaXB0b3IsCisgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpFcnJvckxvY2F0aW9uIGxvY2F0aW9uLAorICAgIGludCBsaW5lLCBpbnQgY29sdW1uKSB7CisgIGxvY2F0aW9uX21hcF9bc3RkOjptYWtlX3BhaXIoZGVzY3JpcHRvciwgbG9jYXRpb24pXSA9CisgICAgICBzdGQ6Om1ha2VfcGFpcihsaW5lLCBjb2x1bW4pOworfQorCit2b2lkIFNvdXJjZUxvY2F0aW9uVGFibGU6OkNsZWFyKCkgeworICBsb2NhdGlvbl9tYXBfLmNsZWFyKCk7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BhcnNlci5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wYXJzZXIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYzU2MWMyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wYXJzZXIuaApAQCAtMCwwICsxLDU2OSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorLy8KKy8vIEltcGxlbWVudHMgcGFyc2luZyBvZiAucHJvdG8gZmlsZXMgdG8gRmlsZURlc2NyaXB0b3JQcm90b3MuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX1BBUlNFUl9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX1BBUlNFUl9IX18KKworI2luY2x1ZGUgPG1hcD4KKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8dXRpbGl0eT4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3JlcGVhdGVkX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3Rva2VuaXplci5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7IGNsYXNzIE1lc3NhZ2U7IH0KKworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CisKKy8vIERlZmluZWQgaW4gdGhpcyBmaWxlLgorY2xhc3MgUGFyc2VyOworY2xhc3MgU291cmNlTG9jYXRpb25UYWJsZTsKKworLy8gSW1wbGVtZW50cyBwYXJzaW5nIG9mIHByb3RvY29sIGRlZmluaXRpb25zIChzdWNoIGFzIC5wcm90byBmaWxlcykuCisvLworLy8gTm90ZSB0aGF0IG1vc3QgdXNlcnMgd2lsbCBiZSBtb3JlIGludGVyZXN0ZWQgaW4gdGhlIEltcG9ydGVyIGNsYXNzLgorLy8gUGFyc2VyIGlzIGEgbG93ZXItbGV2ZWwgY2xhc3Mgd2hpY2ggc2ltcGx5IGNvbnZlcnRzIGEgc2luZ2xlIC5wcm90byBmaWxlCisvLyB0byBhIEZpbGVEZXNjcmlwdG9yUHJvdG8uICBJdCBkb2VzIG5vdCByZXNvbHZlIGltcG9ydCBkaXJlY3RpdmVzIG9yIHBlcmZvcm0KKy8vIG1hbnkgb3RoZXIga2luZHMgb2YgdmFsaWRhdGlvbiBuZWVkZWQgdG8gY29uc3RydWN0IGEgY29tcGxldGUKKy8vIEZpbGVEZXNjcmlwdG9yLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFBhcnNlciB7CisgcHVibGljOgorICBQYXJzZXIoKTsKKyAgflBhcnNlcigpOworCisgIC8vIFBhcnNlIHRoZSBlbnRpcmUgaW5wdXQgYW5kIGNvbnN0cnVjdCBhIEZpbGVEZXNjcmlwdG9yUHJvdG8gcmVwcmVzZW50aW5nCisgIC8vIGl0LiAgUmV0dXJucyB0cnVlIGlmIG5vIGVycm9ycyBvY2N1cnJlZCwgZmFsc2Ugb3RoZXJ3aXNlLgorICBib29sIFBhcnNlKGlvOjpUb2tlbml6ZXIqIGlucHV0LCBGaWxlRGVzY3JpcHRvclByb3RvKiBmaWxlKTsKKworICAvLyBPcHRpb25hbCBmZXRhdXJlczoKKworICAvLyBERVBSRUNBVEVEOiAgTmV3IGNvZGUgc2hvdWxkIHVzZSB0aGUgU291cmNlQ29kZUluZm8gZW1iZWRkZWQgaW4gdGhlCisgIC8vICAgRmlsZURlc2NyaXB0b3JQcm90by4KKyAgLy8KKyAgLy8gUmVxdWVzdHMgdGhhdCBsb2NhdGlvbnMgb2YgY2VydGFpbiBkZWZpbml0aW9ucyBiZSByZWNvcmRlZCB0byB0aGUgZ2l2ZW4KKyAgLy8gU291cmNlTG9jYXRpb25UYWJsZSB3aGlsZSBwYXJzaW5nLiAgVGhpcyBjYW4gYmUgdXNlZCB0byBsb29rIHVwIGV4YWN0IGxpbmUKKyAgLy8gYW5kIGNvbHVtbiBudW1iZXJzIGZvciBlcnJvcnMgcmVwb3J0ZWQgYnkgRGVzY3JpcHRvclBvb2wgZHVyaW5nIHZhbGlkYXRpb24uCisgIC8vIFNldCB0byBOVUxMICh0aGUgZGVmYXVsdCkgdG8gZGlzY2FyZCBzb3VyY2UgbG9jYXRpb24gaW5mb3JtYXRpb24uCisgIHZvaWQgUmVjb3JkU291cmNlTG9jYXRpb25zVG8oU291cmNlTG9jYXRpb25UYWJsZSogbG9jYXRpb25fdGFibGUpIHsKKyAgICBzb3VyY2VfbG9jYXRpb25fdGFibGVfID0gbG9jYXRpb25fdGFibGU7CisgIH0KKworICAvLyBSZXF1ZXN0cyB0aGF0IGVycm9ycyBiZSByZWNvcmRlZCB0byB0aGUgZ2l2ZW4gRXJyb3JDb2xsZWN0b3Igd2hpbGUKKyAgLy8gcGFyc2luZy4gIFNldCB0byBOVUxMICh0aGUgZGVmYXVsdCkgdG8gZGlzY2FyZCBlcnJvciBtZXNzYWdlcy4KKyAgdm9pZCBSZWNvcmRFcnJvcnNUbyhpbzo6RXJyb3JDb2xsZWN0b3IqIGVycm9yX2NvbGxlY3RvcikgeworICAgIGVycm9yX2NvbGxlY3Rvcl8gPSBlcnJvcl9jb2xsZWN0b3I7CisgIH0KKworICAvLyBSZXR1cm5zIHRoZSBpZGVudGlmaWVyIHVzZWQgaW4gdGhlICJzeW50YXggPSAiIGRlY2xhcmF0aW9uLCBpZiBvbmUgd2FzCisgIC8vIHNlZW4gZHVyaW5nIHRoZSBsYXN0IGNhbGwgdG8gUGFyc2UoKSwgb3IgdGhlIGVtcHR5IHN0cmluZyBvdGhlcndpc2UuCisgIGNvbnN0IHN0cmluZyYgR2V0U3ludGF4SWRlbnRpZmllcigpIHsgcmV0dXJuIHN5bnRheF9pZGVudGlmaWVyXzsgfQorCisgIC8vIElmIHNldCB0cnVlLCBpbnB1dCBmaWxlcyB3aWxsIGJlIHJlcXVpcmVkIHRvIGJlZ2luIHdpdGggYSBzeW50YXgKKyAgLy8gaWRlbnRpZmllci4gIE90aGVyd2lzZSwgZmlsZXMgbWF5IG9taXQgdGhpcy4gIElmIGEgc3ludGF4IGlkZW50aWZpZXIKKyAgLy8gaXMgcHJvdmlkZWQsIGl0IG11c3QgYmUgJ3N5bnRheCA9ICJwcm90bzIiOycgYW5kIG11c3QgYXBwZWFyIGF0IHRoZQorICAvLyB0b3Agb2YgdGhpcyBmaWxlIHJlZ2FyZGxlc3Mgb2Ygd2hldGhlciBvciBub3QgaXQgd2FzIHJlcXVpcmVkLgorICB2b2lkIFNldFJlcXVpcmVTeW50YXhJZGVudGlmaWVyKGJvb2wgdmFsdWUpIHsKKyAgICByZXF1aXJlX3N5bnRheF9pZGVudGlmaWVyXyA9IHZhbHVlOworICB9CisKKyAgLy8gQ2FsbCBTZXRTdG9wQWZ0ZXJTeW50YXhJZGVudGlmaWVyKHRydWUpIHRvIHRlbGwgdGhlIHBhcnNlciB0byBzdG9wCisgIC8vIHBhcnNpbmcgYXMgc29vbiBhcyBpdCBoYXMgc2VlbiB0aGUgc3ludGF4IGlkZW50aWZpZXIsIG9yIGxhY2sgdGhlcmVvZi4KKyAgLy8gVGhpcyBpcyB1c2VmdWwgZm9yIHF1aWNrbHkgaWRlbnRpZnlpbmcgdGhlIHN5bnRheCBvZiB0aGUgZmlsZSB3aXRob3V0CisgIC8vIHBhcnNpbmcgdGhlIHdob2xlIHRoaW5nLiAgSWYgdGhpcyBpcyBlbmFibGVkLCBubyBlcnJvciB3aWxsIGJlIHJlY29yZGVkCisgIC8vIGlmIHRoZSBzeW50YXggaWRlbnRpZmllciBpcyBzb21ldGhpbmcgb3RoZXIgdGhhbiAicHJvdG8yIiAoc2luY2UKKyAgLy8gcHJlc3VtYWJseSB0aGUgY2FsbGVyIGludGVuZHMgdG8gZGVhbCB3aXRoIHRoYXQpLCBidXQgb3RoZXIga2luZHMgb2YKKyAgLy8gZXJyb3JzIChlLmcuIHBhcnNlIGVycm9ycykgd2lsbCBzdGlsbCBiZSByZXBvcnRlZC4gIFdoZW4gdGhpcyBpcyBlbmFibGVkLAorICAvLyB5b3UgbWF5IHBhc3MgYSBOVUxMIEZpbGVEZXNjcmlwdG9yUHJvdG8gdG8gUGFyc2UoKS4KKyAgdm9pZCBTZXRTdG9wQWZ0ZXJTeW50YXhJZGVudGlmaWVyKGJvb2wgdmFsdWUpIHsKKyAgICBzdG9wX2FmdGVyX3N5bnRheF9pZGVudGlmaWVyXyA9IHZhbHVlOworICB9CisKKyBwcml2YXRlOgorICBjbGFzcyBMb2NhdGlvblJlY29yZGVyOworCisgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgIC8vIEVycm9yIHJlY292ZXJ5IGhlbHBlcnMKKworICAvLyBDb25zdW1lIHRoZSByZXN0IG9mIHRoZSBjdXJyZW50IHN0YXRlbWVudC4gIFRoaXMgY29uc3VtZXMgdG9rZW5zCisgIC8vIHVudGlsIGl0IHNlZXMgb25lIG9mOgorICAvLyAgICc7JyAgQ29uc3VtZXMgdGhlIHRva2VuIGFuZCByZXR1cm5zLgorICAvLyAgICd7JyAgQ29uc3VtZXMgdGhlIGJyYWNlIHRoZW4gY2FsbHMgU2tpcFJlc3RPZkJsb2NrKCkuCisgIC8vICAgJ30nICBSZXR1cm5zIHdpdGhvdXQgY29uc3VtaW5nLgorICAvLyAgIEVPRiAgUmV0dXJucyAoY2FuJ3QgY29uc3VtZSkuCisgIC8vIFRoZSBQYXJzZXIgb2Z0ZW4gY2FsbHMgU2tpcFN0YXRlbWVudCgpIGFmdGVyIGVuY291bnRlcmluZyBhIHN5bnRheAorICAvLyBlcnJvci4gIFRoaXMgYWxsb3dzIGl0IHRvIGdvIG9uIHBhcnNpbmcgdGhlIGZvbGxvd2luZyBsaW5lcywgYWxsb3dpbmcKKyAgLy8gaXQgdG8gcmVwb3J0IG1vcmUgdGhhbiBqdXN0IG9uZSBlcnJvciBpbiB0aGUgZmlsZS4KKyAgdm9pZCBTa2lwU3RhdGVtZW50KCk7CisKKyAgLy8gQ29uc3VtZSB0aGUgcmVzdCBvZiB0aGUgY3VycmVudCBibG9jaywgaW5jbHVkaW5nIG5lc3RlZCBibG9ja3MsCisgIC8vIGVuZGluZyBhZnRlciB0aGUgY2xvc2luZyAnfScgaXMgZW5jb3VudGVyZWQgYW5kIGNvbnN1bWVkLCBvciBhdCBFT0YuCisgIHZvaWQgU2tpcFJlc3RPZkJsb2NrKCk7CisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgLy8gU2luZ2xlLXRva2VuIGNvbnN1bWluZyBoZWxwZXJzCisgIC8vCisgIC8vIFRoZXNlIG1ha2UgcGFyc2luZyBjb2RlIG1vcmUgcmVhZGFibGUuCisKKyAgLy8gVHJ1ZSBpZiB0aGUgY3VycmVudCB0b2tlbiBpcyBUWVBFX0VORC4KKyAgaW5saW5lIGJvb2wgQXRFbmQoKTsKKworICAvLyBUcnVlIGlmIHRoZSBuZXh0IHRva2VuIG1hdGNoZXMgdGhlIGdpdmVuIHRleHQuCisgIGlubGluZSBib29sIExvb2tpbmdBdChjb25zdCBjaGFyKiB0ZXh0KTsKKyAgLy8gVHJ1ZSBpZiB0aGUgbmV4dCB0b2tlbiBpcyBvZiB0aGUgZ2l2ZW4gdHlwZS4KKyAgaW5saW5lIGJvb2wgTG9va2luZ0F0VHlwZShpbzo6VG9rZW5pemVyOjpUb2tlblR5cGUgdG9rZW5fdHlwZSk7CisKKyAgLy8gSWYgdGhlIG5leHQgdG9rZW4gZXhhY3RseSBtYXRjaGVzIHRoZSB0ZXh0IGdpdmVuLCBjb25zdW1lIGl0IGFuZCByZXR1cm4KKyAgLy8gdHJ1ZS4gIE90aGVyd2lzZSwgcmV0dXJuIGZhbHNlIHdpdGhvdXQgbG9nZ2luZyBhbiBlcnJvci4KKyAgYm9vbCBUcnlDb25zdW1lKGNvbnN0IGNoYXIqIHRleHQpOworCisgIC8vIFRoZXNlIGF0dGVtcHQgdG8gcmVhZCBzb21lIGtpbmQgb2YgdG9rZW4gZnJvbSB0aGUgaW5wdXQuICBJZiBzdWNjZXNzZnVsLAorICAvLyB0aGV5IHJldHVybiB0cnVlLiAgT3RoZXJ3aXNlIHRoZXkgcmV0dXJuIGZhbHNlIGFuZCBhZGQgdGhlIGdpdmVuIGVycm9yCisgIC8vIHRvIHRoZSBlcnJvciBsaXN0LgorCisgIC8vIENvbnN1bWUgYSB0b2tlbiB3aXRoIHRoZSBleGFjdCB0ZXh0IGdpdmVuLgorICBib29sIENvbnN1bWUoY29uc3QgY2hhciogdGV4dCwgY29uc3QgY2hhciogZXJyb3IpOworICAvLyBTYW1lIGFzIGFib3ZlLCBidXQgYXV0b21hdGljYWxseSBnZW5lcmF0ZXMgdGhlIGVycm9yICJFeHBlY3RlZCBcInRleHRcIi4iLAorICAvLyB3aGVyZSAidGV4dCIgaXMgdGhlIGV4cGVjdGVkIHRva2VuIHRleHQuCisgIGJvb2wgQ29uc3VtZShjb25zdCBjaGFyKiB0ZXh0KTsKKyAgLy8gQ29uc3VtZSBhIHRva2VuIG9mIHR5cGUgSURFTlRJRklFUiBhbmQgc3RvcmUgaXRzIHRleHQgaW4gIm91dHB1dCIuCisgIGJvb2wgQ29uc3VtZUlkZW50aWZpZXIoc3RyaW5nKiBvdXRwdXQsIGNvbnN0IGNoYXIqIGVycm9yKTsKKyAgLy8gQ29uc3VtZSBhbiBpbnRlZ2VyIGFuZCBzdG9yZSBpdHMgdmFsdWUgaW4gIm91dHB1dCIuCisgIGJvb2wgQ29uc3VtZUludGVnZXIoaW50KiBvdXRwdXQsIGNvbnN0IGNoYXIqIGVycm9yKTsKKyAgLy8gQ29uc3VtZSBhIHNpZ25lZCBpbnRlZ2VyIGFuZCBzdG9yZSBpdHMgdmFsdWUgaW4gIm91dHB1dCIuCisgIGJvb2wgQ29uc3VtZVNpZ25lZEludGVnZXIoaW50KiBvdXRwdXQsIGNvbnN0IGNoYXIqIGVycm9yKTsKKyAgLy8gQ29uc3VtZSBhIDY0LWJpdCBpbnRlZ2VyIGFuZCBzdG9yZSBpdHMgdmFsdWUgaW4gIm91dHB1dCIuICBJZiB0aGUgdmFsdWUKKyAgLy8gaXMgZ3JlYXRlciB0aGFuIG1heF92YWx1ZSwgYW4gZXJyb3Igd2lsbCBiZSByZXBvcnRlZC4KKyAgYm9vbCBDb25zdW1lSW50ZWdlcjY0KHVpbnQ2NCBtYXhfdmFsdWUsIHVpbnQ2NCogb3V0cHV0LCBjb25zdCBjaGFyKiBlcnJvcik7CisgIC8vIENvbnN1bWUgYSBudW1iZXIgYW5kIHN0b3JlIGl0cyB2YWx1ZSBpbiAib3V0cHV0Ii4gIFRoaXMgd2lsbCBhY2NlcHQKKyAgLy8gdG9rZW5zIG9mIGVpdGhlciBJTlRFR0VSIG9yIEZMT0FUIHR5cGUuCisgIGJvb2wgQ29uc3VtZU51bWJlcihkb3VibGUqIG91dHB1dCwgY29uc3QgY2hhciogZXJyb3IpOworICAvLyBDb25zdW1lIGEgc3RyaW5nIGxpdGVyYWwgYW5kIHN0b3JlIGl0cyAodW5lc2NhcGVkKSB2YWx1ZSBpbiAib3V0cHV0Ii4KKyAgYm9vbCBDb25zdW1lU3RyaW5nKHN0cmluZyogb3V0cHV0LCBjb25zdCBjaGFyKiBlcnJvcik7CisKKyAgLy8gQ29uc3VtZSBhIHRva2VuIHJlcHJlc2VudGluZyB0aGUgZW5kIG9mIHRoZSBzdGF0ZW1lbnQuICBDb21tZW50cyBiZXR3ZWVuCisgIC8vIHRoaXMgdG9rZW4gYW5kIHRoZSBuZXh0IHdpbGwgYmUgaGFydmVzdGVkIGZvciBkb2N1bWVudGF0aW9uLiAgVGhlIGdpdmVuCisgIC8vIExvY2F0aW9uUmVjb3JkZXIgc2hvdWxkIHJlZmVyIHRvIHRoZSBkZWNsYXJhdGlvbiB0aGF0IHdhcyBqdXN0IHBhcnNlZDsKKyAgLy8gaXQgd2lsbCBiZSBwb3B1bGF0ZWQgd2l0aCB0aGVzZSBjb21tZW50cy4KKyAgLy8KKyAgLy8gVE9ETyhrZW50b24pOiAgVGhlIExvY2F0aW9uUmVjb3JkZXIgaXMgY29uc3QgYmVjYXVzZSBoaXN0b3JpY2FsbHkgbG9jYXRpb25zCisgIC8vICAgaGF2ZSBiZWVuIHBhc3NlZCBhcm91bmQgYnkgY29uc3QgcmVmZXJlbmNlLCBmb3Igbm8gcGFydGljdWxhcmx5IGdvb2QKKyAgLy8gICByZWFzb24uICBXZSBzaG91bGQgcHJvYmFibHkgZ28gdGhyb3VnaCBhbmQgY2hhbmdlIHRoZW0gYWxsIHRvIG11dGFibGUKKyAgLy8gICBwb2ludGVyIHRvIG1ha2UgdGhpcyBtb3JlIGludHVpdGl2ZS4KKyAgYm9vbCBUcnlDb25zdW1lRW5kT2ZEZWNsYXJhdGlvbigKKyAgICAgIGNvbnN0IGNoYXIqIHRleHQsIGNvbnN0IExvY2F0aW9uUmVjb3JkZXIqIGxvY2F0aW9uKTsKKyAgYm9vbCBUcnlDb25zdW1lRW5kT2ZEZWNsYXJhdGlvbkZpbmlzaFNjb3BlKAorICAgICAgY29uc3QgY2hhciogdGV4dCwgY29uc3QgTG9jYXRpb25SZWNvcmRlciogbG9jYXRpb24pOworCisgIGJvb2wgQ29uc3VtZUVuZE9mRGVjbGFyYXRpb24oCisgICAgICBjb25zdCBjaGFyKiB0ZXh0LCBjb25zdCBMb2NhdGlvblJlY29yZGVyKiBsb2NhdGlvbik7CisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgLy8gRXJyb3IgbG9nZ2luZyBoZWxwZXJzCisKKyAgLy8gSW52b2tlcyBlcnJvcl9jb2xsZWN0b3JfLT5BZGRFcnJvcigpLCBpZiBlcnJvcl9jb2xsZWN0b3JfIGlzIG5vdCBOVUxMLgorICB2b2lkIEFkZEVycm9yKGludCBsaW5lLCBpbnQgY29sdW1uLCBjb25zdCBzdHJpbmcmIGVycm9yKTsKKworICAvLyBJbnZva2VzIGVycm9yX2NvbGxlY3Rvcl8tPkFkZEVycm9yKCkgd2l0aCB0aGUgbGluZSBhbmQgY29sdW1uIG51bWJlcgorICAvLyBvZiB0aGUgY3VycmVudCB0b2tlbi4KKyAgdm9pZCBBZGRFcnJvcihjb25zdCBzdHJpbmcmIGVycm9yKTsKKworICAvLyBSZWNvcmRzIGEgbG9jYXRpb24gaW4gdGhlIFNvdXJjZUNvZGVJbmZvLmxvY2F0aW9uIHRhYmxlIChzZWUKKyAgLy8gZGVzY3JpcHRvci5wcm90bykuICBXZSB1c2UgUkFJSSB0byBlbnN1cmUgdGhhdCB0aGUgc3RhcnQgYW5kIGVuZCBsb2NhdGlvbnMKKyAgLy8gYXJlIHJlY29yZGVkIC0tIHRoZSBjb25zdHJ1Y3RvciByZWNvcmRzIHRoZSBzdGFydCBsb2NhdGlvbiBhbmQgdGhlCisgIC8vIGRlc3RydWN0b3IgcmVjb3JkcyB0aGUgZW5kIGxvY2F0aW9uLiAgU2luY2UgdGhlIHBhcnNlciBpcworICAvLyByZWN1cnNpdmUtZGVzY2VudCwgdGhpcyB3b3JrcyBvdXQgYmVhdXRpZnVsbHkuCisgIGNsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBMb2NhdGlvblJlY29yZGVyIHsKKyAgIHB1YmxpYzoKKyAgICAvLyBDb25zdHJ1Y3QgdGhlIGZpbGUncyAicm9vdCIgbG9jYXRpb24uCisgICAgTG9jYXRpb25SZWNvcmRlcihQYXJzZXIqIHBhcnNlcik7CisKKyAgICAvLyBDb25zdHJ1Y3QgYSBsb2NhdGlvbiB0aGF0IHJlcHJlc2VudHMgYSBkZWNsYXJhdGlvbiBuZXN0ZWQgd2l0aGluIHRoZQorICAgIC8vIGdpdmVuIHBhcmVudC4gIEUuZy4gYSBmaWVsZCdzIGxvY2F0aW9uIGlzIG5lc3RlZCB3aXRoaW4gdGhlIGxvY2F0aW9uCisgICAgLy8gZm9yIGEgbWVzc2FnZSB0eXBlLiAgVGhlIHBhcmVudCdzIHBhdGggd2lsbCBiZSBjb3BpZWQsIHNvIHlvdSBzaG91bGQKKyAgICAvLyBjYWxsIEFkZFBhdGgoKSBvbmx5IHRvIGFkZCB0aGUgcGF0aCBjb21wb25lbnRzIGxlYWRpbmcgZnJvbSB0aGUgcGFyZW50CisgICAgLy8gdG8gdGhlIGNoaWxkIChhcyBvcHBvc2VkIHRvIGxlYWRpbmcgZnJvbSB0aGUgcm9vdCB0byB0aGUgY2hpbGQpLgorICAgIExvY2F0aW9uUmVjb3JkZXIoY29uc3QgTG9jYXRpb25SZWNvcmRlciYgcGFyZW50KTsKKworICAgIC8vIENvbnZlbmllbmNlIGNvbnN0cnVjdG9ycyB0aGF0IGNhbGwgQWRkUGF0aCgpIG9uZSBvciB0d28gdGltZXMuCisgICAgTG9jYXRpb25SZWNvcmRlcihjb25zdCBMb2NhdGlvblJlY29yZGVyJiBwYXJlbnQsIGludCBwYXRoMSk7CisgICAgTG9jYXRpb25SZWNvcmRlcihjb25zdCBMb2NhdGlvblJlY29yZGVyJiBwYXJlbnQsIGludCBwYXRoMSwgaW50IHBhdGgyKTsKKworICAgIH5Mb2NhdGlvblJlY29yZGVyKCk7CisKKyAgICAvLyBBZGQgYSBwYXRoIGNvbXBvbmVudC4gIFNlZSBTb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5wYXRoIGluCisgICAgLy8gZGVzY3JpcHRvci5wcm90by4KKyAgICB2b2lkIEFkZFBhdGgoaW50IHBhdGhfY29tcG9uZW50KTsKKworICAgIC8vIEJ5IGRlZmF1bHQgdGhlIGxvY2F0aW9uIGlzIGNvbnNpZGVyZWQgdG8gc3RhcnQgYXQgdGhlIGN1cnJlbnQgdG9rZW4gYXQKKyAgICAvLyB0aGUgdGltZSB0aGUgTG9jYXRpb25SZWNvcmRlciBpcyBjcmVhdGVkLiAgU3RhcnRBdCgpIHNldHMgdGhlIHN0YXJ0CisgICAgLy8gbG9jYXRpb24gdG8gdGhlIGdpdmVuIHRva2VuIGluc3RlYWQuCisgICAgdm9pZCBTdGFydEF0KGNvbnN0IGlvOjpUb2tlbml6ZXI6OlRva2VuJiB0b2tlbik7CisKKyAgICAvLyBTdGFydCBhdCB0aGUgc2FtZSBsb2NhdGlvbiBhcyBzb21lIG90aGVyIExvY2F0aW9uUmVjb3JkZXIuCisgICAgdm9pZCBTdGFydEF0KGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIG90aGVyKTsKKworICAgIC8vIEJ5IGRlZmF1bHQgdGhlIGxvY2F0aW9uIGlzIGNvbnNpZGVyZWQgdG8gZW5kIGF0IHRoZSBwcmV2aW91cyB0b2tlbiBhdAorICAgIC8vIHRoZSB0aW1lIHRoZSBMb2NhdGlvblJlY29yZGVyIGlzIGRlc3Ryb3llZC4gIEVuZEF0KCkgc2V0cyB0aGUgZW5kCisgICAgLy8gbG9jYXRpb24gdG8gdGhlIGdpdmVuIHRva2VuIGluc3RlYWQuCisgICAgdm9pZCBFbmRBdChjb25zdCBpbzo6VG9rZW5pemVyOjpUb2tlbiYgdG9rZW4pOworCisgICAgLy8gUmVjb3JkcyB0aGUgc3RhcnQgcG9pbnQgb2YgdGhpcyBsb2NhdGlvbiB0byB0aGUgU291cmNlTG9jYXRpb25UYWJsZSB0aGF0CisgICAgLy8gd2FzIHBhc3NlZCB0byBSZWNvcmRTb3VyY2VMb2NhdGlvbnNUbygpLCBpZiBhbnkuICBTb3VyY2VMb2NhdGlvblRhYmxlCisgICAgLy8gaXMgYW4gb2xkZXIgd2F5IG9mIGtlZXBpbmcgdHJhY2sgb2Ygc291cmNlIGxvY2F0aW9ucyB3aGljaCBpcyBzdGlsbAorICAgIC8vIHVzZWQgaW4gc29tZSBwbGFjZXMuCisgICAgdm9pZCBSZWNvcmRMZWdhY3lMb2NhdGlvbihjb25zdCBNZXNzYWdlKiBkZXNjcmlwdG9yLAorICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6OkVycm9yTG9jYXRpb24gbG9jYXRpb24pOworCisgICAgLy8gQXR0YWNoZXMgbGVhZGluZyBhbmQgdHJhaWxpbmcgY29tbWVudHMgdG8gdGhlIGxvY2F0aW9uLiAgVGhlIHR3byBzdHJpbmdzCisgICAgLy8gd2lsbCBiZSBzd2FwcGVkIGludG8gcGxhY2UsIHNvIGFmdGVyIHRoaXMgaXMgY2FsbGVkICpsZWFkaW5nIGFuZAorICAgIC8vICp0cmFpbGluZyB3aWxsIGJlIGVtcHR5LgorICAgIC8vCisgICAgLy8gVE9ETyhrZW50b24pOiAgU2VlIGNvbW1lbnQgb24gVHJ5Q29uc3VtZUVuZE9mRGVjbGFyYXRpb24oKSwgYWJvdmUsIGZvcgorICAgIC8vICAgd2h5IHRoaXMgaXMgY29uc3QuCisgICAgdm9pZCBBdHRhY2hDb21tZW50cyhzdHJpbmcqIGxlYWRpbmcsIHN0cmluZyogdHJhaWxpbmcsCisgICAgICAgICAgICAgICAgICAgICAgICB2ZWN0b3I8c3RyaW5nPiogZGV0YWNoZWRfY29tbWVudHMpIGNvbnN0OworCisgICBwcml2YXRlOgorICAgIC8vIEluZGV4ZXMgb2YgcGFyZW50IGFuZCBjdXJyZW50IGxvY2F0aW9uIGluIHRoZSBwYXJlbnQKKyAgICAvLyBTb3VyY2VDb2RlSW5mby5sb2NhdGlvbiByZXBlYXRlZCBmaWVsZC4gRm9yIHRvcC1sZXZlbCBlbGVtZW50cywKKyAgICAvLyBwYXJlbnRfaW5kZXhfIGlzIC0xLgorICAgIFBhcnNlciogcGFyc2VyXzsKKyAgICBTb3VyY2VDb2RlSW5mbzo6TG9jYXRpb24qIGxvY2F0aW9uXzsKKworICAgIHZvaWQgSW5pdChjb25zdCBMb2NhdGlvblJlY29yZGVyJiBwYXJlbnQpOworICB9OworCisgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgIC8vIFBhcnNlcnMgZm9yIHZhcmlvdXMgbGFuZ3VhZ2UgY29uc3RydWN0cworCisgIC8vIFBhcnNlcyB0aGUgInN5bnRheCA9IFwicHJvdG8yXCI7IiBsaW5lIGF0IHRoZSB0b3Agb2YgdGhlIGZpbGUuICBSZXR1cm5zCisgIC8vIGZhbHNlIGlmIGl0IGZhaWxlZCB0byBwYXJzZSBvciBpZiB0aGUgc3ludGF4IGlkZW50aWZpZXIgd2FzIG5vdAorICAvLyByZWNvZ25pemVkLgorICBib29sIFBhcnNlU3ludGF4SWRlbnRpZmllcihjb25zdCBMb2NhdGlvblJlY29yZGVyJiBwYXJlbnQpOworCisgIC8vIFRoZXNlIG1ldGhvZHMgcGFyc2UgdmFyaW91cyBpbmRpdmlkdWFsIGJpdHMgb2YgY29kZS4gIFRoZXkgcmV0dXJuCisgIC8vIGZhbHNlIGlmIHRoZXkgY29tcGxldGVseSBmYWlsIHRvIHBhcnNlIHRoZSBjb25zdHJ1Y3QuICBJbiB0aGlzIGNhc2UsCisgIC8vIGl0IGlzIHByb2JhYmx5IG5lY2Vzc2FyeSB0byBza2lwIHRoZSByZXN0IG9mIHRoZSBzdGF0ZW1lbnQgdG8gcmVjb3Zlci4KKyAgLy8gSG93ZXZlciwgaWYgdGhlc2UgbWV0aG9kcyByZXR1cm4gdHJ1ZSwgaXQgZG9lcyBOT1QgbWVhbiB0aGF0IHRoZXJlCisgIC8vIHdlcmUgbm8gZXJyb3JzOyBvbmx5IHRoYXQgdGhlcmUgd2VyZSBubyAqc3ludGF4KiBlcnJvcnMuICBGb3IgaW5zdGFuY2UsCisgIC8vIGlmIGEgc2VydmljZSBtZXRob2QgaXMgZGVmaW5lZCB1c2luZyBwcm9wZXIgc3ludGF4IGJ1dCB1c2VzIGEgcHJpbWl0aXZlCisgIC8vIHR5cGUgYXMgaXRzIGlucHV0IG9yIG91dHB1dCwgUGFyc2VNZXRob2RGaWVsZCgpIHN0aWxsIHJldHVybnMgdHJ1ZQorICAvLyBhbmQgb25seSByZXBvcnRzIHRoZSBlcnJvciBieSBjYWxsaW5nIEFkZEVycm9yKCkuICBJbiBwcmFjdGljZSwgdGhpcworICAvLyBtYWtlcyBsb2dpYyBtdWNoIHNpbXBsZXIgZm9yIHRoZSBjYWxsZXIuCisKKyAgLy8gUGFyc2UgYSB0b3AtbGV2ZWwgbWVzc2FnZSwgZW51bSwgc2VydmljZSwgZXRjLgorICBib29sIFBhcnNlVG9wTGV2ZWxTdGF0ZW1lbnQoRmlsZURlc2NyaXB0b3JQcm90byogZmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIHJvb3RfbG9jYXRpb24pOworCisgIC8vIFBhcnNlIHZhcmlvdXMgbGFuZ3VhZ2UgaGlnaC1sZXZlbCBsYW5ndWFnZSBjb25zdHJ1cmN0cy4KKyAgYm9vbCBQYXJzZU1lc3NhZ2VEZWZpbml0aW9uKERlc2NyaXB0b3JQcm90byogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIG1lc3NhZ2VfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvKiBjb250YWluaW5nX2ZpbGUpOworICBib29sIFBhcnNlRW51bURlZmluaXRpb24oRW51bURlc2NyaXB0b3JQcm90byogZW51bV90eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTG9jYXRpb25SZWNvcmRlciYgZW51bV9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfZmlsZSk7CisgIGJvb2wgUGFyc2VTZXJ2aWNlRGVmaW5pdGlvbihTZXJ2aWNlRGVzY3JpcHRvclByb3RvKiBzZXJ2aWNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTG9jYXRpb25SZWNvcmRlciYgc2VydmljZV9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfZmlsZSk7CisgIGJvb2wgUGFyc2VQYWNrYWdlKEZpbGVEZXNjcmlwdG9yUHJvdG8qIGZpbGUsCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIHJvb3RfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfZmlsZSk7CisgIGJvb2wgUGFyc2VJbXBvcnQoUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+KiBkZXBlbmRlbmN5LAorICAgICAgICAgICAgICAgICAgIFJlcGVhdGVkRmllbGQ8aW50MzI+KiBwdWJsaWNfZGVwZW5kZW5jeSwKKyAgICAgICAgICAgICAgICAgICBSZXBlYXRlZEZpZWxkPGludDMyPiogd2Vha19kZXBlbmRlbmN5LAorICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIHJvb3RfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byogY29udGFpbmluZ19maWxlKTsKKworICAvLyBUaGVzZSBtZXRob2RzIHBhcnNlIHRoZSBjb250ZW50cyBvZiBhIG1lc3NhZ2UsIGVudW0sIG9yIHNlcnZpY2UgdHlwZSBhbmQKKyAgLy8gYWRkIHRoZW0gdG8gdGhlIGdpdmVuIG9iamVjdC4gIFRoZXkgY29uc3VtZSB0aGUgZW50aXJlIGJsb2NrIGluY2x1ZGluZworICAvLyB0aGUgYmVnaW5uaW5nIGFuZCBlbmRpbmcgYnJhY2UuCisgIGJvb2wgUGFyc2VNZXNzYWdlQmxvY2soRGVzY3JpcHRvclByb3RvKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIG1lc3NhZ2VfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byogY29udGFpbmluZ19maWxlKTsKKyAgYm9vbCBQYXJzZUVudW1CbG9jayhFbnVtRGVzY3JpcHRvclByb3RvKiBlbnVtX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTG9jYXRpb25SZWNvcmRlciYgZW51bV9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvKiBjb250YWluaW5nX2ZpbGUpOworICBib29sIFBhcnNlU2VydmljZUJsb2NrKFNlcnZpY2VEZXNjcmlwdG9yUHJvdG8qIHNlcnZpY2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTG9jYXRpb25SZWNvcmRlciYgc2VydmljZV9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvKiBjb250YWluaW5nX2ZpbGUpOworCisgIC8vIFBhcnNlIG9uZSBzdGF0ZW1lbnQgd2l0aGluIGEgbWVzc2FnZSwgZW51bSwgb3Igc2VydmljZSBibG9jaywgaW5jbHVkaW5nCisgIC8vIGZpbmFsIHNlbWljb2xvbi4KKyAgYm9vbCBQYXJzZU1lc3NhZ2VTdGF0ZW1lbnQoRGVzY3JpcHRvclByb3RvKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiBtZXNzYWdlX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvKiBjb250YWluaW5nX2ZpbGUpOworICBib29sIFBhcnNlRW51bVN0YXRlbWVudChFbnVtRGVzY3JpcHRvclByb3RvKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiBlbnVtX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvKiBjb250YWluaW5nX2ZpbGUpOworICBib29sIFBhcnNlU2VydmljZVN0YXRlbWVudChTZXJ2aWNlRGVzY3JpcHRvclByb3RvKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiBzZXJ2aWNlX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvKiBjb250YWluaW5nX2ZpbGUpOworCisgIC8vIFBhcnNlIGEgZmllbGQgb2YgYSBtZXNzYWdlLiAgSWYgdGhlIGZpZWxkIGlzIGEgZ3JvdXAsIGl0cyB0eXBlIHdpbGwgYmUKKyAgLy8gYWRkZWQgdG8gIm1lc3NhZ2VzIi4KKyAgLy8KKyAgLy8gcGFyZW50X2xvY2F0aW9uIGFuZCBsb2NhdGlvbl9maWVsZF9udW1iZXJfZm9yX25lc3RlZF90eXBlIGFyZSBuZWVkZWQgd2hlbgorICAvLyBwYXJzaW5nIGdyb3VwcyAtLSB3ZSBuZWVkIHRvIGdlbmVyYXRlIGEgbmVzdGVkIG1lc3NhZ2UgdHlwZSB3aXRoaW4gdGhlCisgIC8vIHBhcmVudCBhbmQgcmVjb3JkIGl0cyBsb2NhdGlvbiBhY2NvcmRpbmdseS4gIFNpbmNlIHRoZSBwYXJlbnQgY291bGQgYmUKKyAgLy8gZWl0aGVyIGEgRmlsZURlc2NyaXB0b3JQcm90byBvciBhIERlc2NyaXB0b3JQcm90bywgd2UgbXVzdCBwYXNzIGluIHRoZQorICAvLyBjb3JyZWN0IGZpZWxkIG51bWJlciB0byB1c2UuCisgIGJvb2wgUGFyc2VNZXNzYWdlRmllbGQoRmllbGREZXNjcmlwdG9yUHJvdG8qIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgIFJlcGVhdGVkUHRyRmllbGQ8RGVzY3JpcHRvclByb3RvPiogbWVzc2FnZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTG9jYXRpb25SZWNvcmRlciYgcGFyZW50X2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgIGludCBsb2NhdGlvbl9maWVsZF9udW1iZXJfZm9yX25lc3RlZF90eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIGZpZWxkX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfZmlsZSk7CisKKyAgLy8gTGlrZSBQYXJzZU1lc3NhZ2VGaWVsZCgpIGJ1dCBleHBlY3RzIHRoZSBsYWJlbCBoYXMgYWxyZWFkeSBiZWVuIGZpbGxlZCBpbgorICAvLyBieSB0aGUgY2FsbGVyLgorICBib29sIFBhcnNlTWVzc2FnZUZpZWxkTm9MYWJlbChGaWVsZERlc2NyaXB0b3JQcm90byogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlcGVhdGVkUHRyRmllbGQ8RGVzY3JpcHRvclByb3RvPiogbWVzc2FnZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIHBhcmVudF9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGxvY2F0aW9uX2ZpZWxkX251bWJlcl9mb3JfbmVzdGVkX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIGZpZWxkX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvKiBjb250YWluaW5nX2ZpbGUpOworCisgIC8vIFBhcnNlIGFuICJleHRlbnNpb25zIiBkZWNsYXJhdGlvbi4KKyAgYm9vbCBQYXJzZUV4dGVuc2lvbnMoRGVzY3JpcHRvclByb3RvKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiBleHRlbnNpb25zX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvKiBjb250YWluaW5nX2ZpbGUpOworCisgIC8vIFBhcnNlIGEgInJlc2VydmVkIiBkZWNsYXJhdGlvbi4KKyAgYm9vbCBQYXJzZVJlc2VydmVkKERlc2NyaXB0b3JQcm90byogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIG1lc3NhZ2VfbG9jYXRpb24pOworICBib29sIFBhcnNlUmVzZXJ2ZWROYW1lcyhEZXNjcmlwdG9yUHJvdG8qIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIHBhcmVudF9sb2NhdGlvbik7CisgIGJvb2wgUGFyc2VSZXNlcnZlZE51bWJlcnMoRGVzY3JpcHRvclByb3RvKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIHBhcmVudF9sb2NhdGlvbik7CisKKyAgLy8gUGFyc2UgYW4gImV4dGVuZCIgZGVjbGFyYXRpb24uICAoU2VlIGFsc28gY29tbWVudHMgZm9yCisgIC8vIFBhcnNlTWVzc2FnZUZpZWxkKCkuKQorICBib29sIFBhcnNlRXh0ZW5kKFJlcGVhdGVkUHRyRmllbGQ8RmllbGREZXNjcmlwdG9yUHJvdG8+KiBleHRlbnNpb25zLAorICAgICAgICAgICAgICAgICAgIFJlcGVhdGVkUHRyRmllbGQ8RGVzY3JpcHRvclByb3RvPiogbWVzc2FnZXMsCisgICAgICAgICAgICAgICAgICAgY29uc3QgTG9jYXRpb25SZWNvcmRlciYgcGFyZW50X2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgIGludCBsb2NhdGlvbl9maWVsZF9udW1iZXJfZm9yX25lc3RlZF90eXBlLAorICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIGV4dGVuZF9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvKiBjb250YWluaW5nX2ZpbGUpOworCisgIC8vIFBhcnNlIGEgIm9uZW9mIiBkZWNsYXJhdGlvbi4gIFRoZSBjYWxsZXIgaXMgcmVzcG9uc2libGUgZm9yIHNldHRpbmcKKyAgLy8gb25lb2ZfZGVjbC0+bGFiZWwoKSBzaW5jZSBpdCB3aWxsIGhhdmUgaGFkIHRvIHBhcnNlIHRoZSBsYWJlbCBiZWZvcmUgaXQKKyAgLy8ga25ldyBpdCB3YXMgcGFyc2luZyBhIG9uZW9mLgorICBib29sIFBhcnNlT25lb2YoT25lb2ZEZXNjcmlwdG9yUHJvdG8qIG9uZW9mX2RlY2wsCisgICAgICAgICAgICAgICAgICBEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfdHlwZSwKKyAgICAgICAgICAgICAgICAgIGludCBvbmVvZl9pbmRleCwKKyAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIG9uZW9mX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgY29uc3QgTG9jYXRpb25SZWNvcmRlciYgY29udGFpbmluZ190eXBlX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byogY29udGFpbmluZ19maWxlKTsKKworICAvLyBQYXJzZSBhIHNpbmdsZSBlbnVtIHZhbHVlIHdpdGhpbiBhbiBlbnVtIGJsb2NrLgorICBib29sIFBhcnNlRW51bUNvbnN0YW50KEVudW1WYWx1ZURlc2NyaXB0b3JQcm90byogZW51bV92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiBlbnVtX3ZhbHVlX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfZmlsZSk7CisKKyAgLy8gUGFyc2UgZW51bSBjb25zdGFudCBvcHRpb25zLCBpLmUuIHRoZSBsaXN0IGluIHNxdWFyZSBicmFja2V0cyBhdCB0aGUgZW5kCisgIC8vIG9mIHRoZSBlbnVtIGNvbnN0YW50IHZhbHVlIGRlZmluaXRpb24uCisgIGJvb2wgUGFyc2VFbnVtQ29uc3RhbnRPcHRpb25zKEVudW1WYWx1ZURlc2NyaXB0b3JQcm90byogdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIGVudW1fdmFsdWVfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfZmlsZSk7CisKKyAgLy8gUGFyc2UgYSBzaW5nbGUgbWV0aG9kIHdpdGhpbiBhIHNlcnZpY2UgZGVmaW5pdGlvbi4KKyAgYm9vbCBQYXJzZVNlcnZpY2VNZXRob2QoTWV0aG9kRGVzY3JpcHRvclByb3RvKiBtZXRob2QsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIG1ldGhvZF9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byogY29udGFpbmluZ19maWxlKTsKKworCisgIC8vIFBhcnNlIG9wdGlvbnMgb2YgYSBzaW5nbGUgbWV0aG9kIG9yIHN0cmVhbS4KKyAgYm9vbCBQYXJzZU1ldGhvZE9wdGlvbnMoY29uc3QgTG9jYXRpb25SZWNvcmRlciYgcGFyZW50X2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvKiBjb250YWluaW5nX2ZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGludCBvcHRpb25zRmllbGROdW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UqIG11dGFibGVfb3B0aW9ucyk7CisKKyAgLy8gUGFyc2UgInJlcXVpcmVkIiwgIm9wdGlvbmFsIiwgb3IgInJlcGVhdGVkIiBhbmQgZmlsbCBpbiAibGFiZWwiCisgIC8vIHdpdGggdGhlIHZhbHVlLiBSZXR1cm5zIHRydWUgaWYgc3VjaCBhIGxhYmVsIGlzIGNvbnN1bWVkLgorICBib29sIFBhcnNlTGFiZWwoRmllbGREZXNjcmlwdG9yUHJvdG86OkxhYmVsKiBsYWJlbCwKKyAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfZmlsZSk7CisKKyAgLy8gUGFyc2UgYSB0eXBlIG5hbWUgYW5kIGZpbGwgaW4gInR5cGUiIChpZiBpdCBpcyBhIHByaW1pdGl2ZSkgb3IKKyAgLy8gInR5cGVfbmFtZSIgKGlmIGl0IGlzIG5vdCkgd2l0aCB0aGUgdHlwZSBwYXJzZWQuCisgIGJvb2wgUGFyc2VUeXBlKEZpZWxkRGVzY3JpcHRvclByb3RvOjpUeXBlKiB0eXBlLAorICAgICAgICAgICAgICAgICBzdHJpbmcqIHR5cGVfbmFtZSk7CisgIC8vIFBhcnNlIGEgdXNlci1kZWZpbmVkIHR5cGUgYW5kIGZpbGwgaW4gInR5cGVfbmFtZSIgd2l0aCB0aGUgbmFtZS4KKyAgLy8gSWYgYSBwcmltaXRpdmUgdHlwZSBpcyBuYW1lZCwgaXQgaXMgdHJlYXRlZCBhcyBhbiBlcnJvci4KKyAgYm9vbCBQYXJzZVVzZXJEZWZpbmVkVHlwZShzdHJpbmcqIHR5cGVfbmFtZSk7CisKKyAgLy8gUGFyc2VzIGZpZWxkIG9wdGlvbnMsIGkuZS4gdGhlIHN0dWZmIGluIHNxdWFyZSBicmFja2V0cyBhdCB0aGUgZW5kCisgIC8vIG9mIGEgZmllbGQgZGVmaW5pdGlvbi4gIEFsc28gcGFyc2VzIGRlZmF1bHQgdmFsdWUuCisgIGJvb2wgUGFyc2VGaWVsZE9wdGlvbnMoRmllbGREZXNjcmlwdG9yUHJvdG8qIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2F0aW9uUmVjb3JkZXImIGZpZWxkX2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfZmlsZSk7CisKKyAgLy8gUGFyc2UgdGhlICJkZWZhdWx0IiBvcHRpb24uICBUaGlzIG5lZWRzIHNwZWNpYWwgaGFuZGxpbmcgYmVjYXVzZSBpdHMKKyAgLy8gdHlwZSBpcyB0aGUgZmllbGQncyB0eXBlLgorICBib29sIFBhcnNlRGVmYXVsdEFzc2lnbm1lbnQoRmllbGREZXNjcmlwdG9yUHJvdG8qIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTG9jYXRpb25SZWNvcmRlciYgZmllbGRfbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvKiBjb250YWluaW5nX2ZpbGUpOworCisgIGJvb2wgUGFyc2VKc29uTmFtZShGaWVsZERlc2NyaXB0b3JQcm90byogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiBmaWVsZF9sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGNvbnRhaW5pbmdfZmlsZSk7CisKKyAgZW51bSBPcHRpb25TdHlsZSB7CisgICAgT1BUSU9OX0FTU0lHTk1FTlQsICAvLyBqdXN0ICJuYW1lID0gdmFsdWUiCisgICAgT1BUSU9OX1NUQVRFTUVOVCAgICAvLyAib3B0aW9uIG5hbWUgPSB2YWx1ZTsiCisgIH07CisKKyAgLy8gUGFyc2UgYSBzaW5nbGUgb3B0aW9uIG5hbWUvdmFsdWUgcGFpciwgZS5nLiAiY3R5cGUgPSBDT1JEIi4gIFRoZSBuYW1lCisgIC8vIGlkZW50aWZpZXMgYSBmaWVsZCBvZiB0aGUgZ2l2ZW4gTWVzc2FnZSwgYW5kIHRoZSB2YWx1ZSBvZiB0aGF0IGZpZWxkCisgIC8vIGlzIHNldCB0byB0aGUgcGFyc2VkIHZhbHVlLgorICBib29sIFBhcnNlT3B0aW9uKE1lc3NhZ2UqIG9wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgY29uc3QgTG9jYXRpb25SZWNvcmRlciYgb3B0aW9uc19sb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvKiBjb250YWluaW5nX2ZpbGUsCisgICAgICAgICAgICAgICAgICAgT3B0aW9uU3R5bGUgc3R5bGUpOworCisgIC8vIFBhcnNlcyBhIHNpbmdsZSBwYXJ0IG9mIGEgbXVsdGlwYXJ0IG9wdGlvbiBuYW1lLiBBIG11bHRpcGFydCBuYW1lIGNvbnNpc3RzCisgIC8vIG9mIG5hbWVzIHNlcGFyYXRlZCBieSBkb3RzLiBFYWNoIG5hbWUgaXMgZWl0aGVyIGFuIGlkZW50aWZpZXIgb3IgYSBzZXJpZXMKKyAgLy8gb2YgaWRlbnRpZmllcnMgc2VwYXJhdGVkIGJ5IGRvdHMgYW5kIGVuY2xvc2VkIGluIHBhcmVudGhlc2VzLiBFLmcuLAorICAvLyAiZm9vLihiYXIuYmF6KS5xdXgiLgorICBib29sIFBhcnNlT3B0aW9uTmFtZVBhcnQoVW5pbnRlcnByZXRlZE9wdGlvbiogdW5pbnRlcnByZXRlZF9vcHRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhdGlvblJlY29yZGVyJiBwYXJ0X2xvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byogY29udGFpbmluZ19maWxlKTsKKworICAvLyBQYXJzZXMgYSBzdHJpbmcgc3Vycm91bmRlZCBieSBiYWxhbmNlZCBicmFjZXMuICBTdHJpcHMgb2ZmIHRoZSBvdXRlcgorICAvLyBicmFjZXMgYW5kIHN0b3JlcyB0aGUgZW5jbG9zZWQgc3RyaW5nIGluICp2YWx1ZS4KKyAgLy8gRS5nLiwKKyAgLy8gICAgIHsgZm9vIH0gICAgICAgICAgICAgICAgICAgICAqdmFsdWUgZ2V0cyAnZm9vJworICAvLyAgICAgeyBmb28geyBiYXI6IGJveCB9IH0gICAgICAgICp2YWx1ZSBnZXRzICdmb28geyBiYXI6IGJveCB9JworICAvLyAgICAge30gICAgICAgICAgICAgICAgICAgICAgICAgICp2YWx1ZSBnZXRzICcnCisgIC8vCisgIC8vIFJFUVVJUkVTOiBMb29raW5nQXQoInsiKQorICAvLyBXaGVuIGZpbmlzaGVkIHN1Y2Nlc3NmdWxseSwgd2UgYXJlIGxvb2tpbmcgYXQgdGhlIGZpcnN0IHRva2VuIHBhc3QKKyAgLy8gdGhlIGVuZGluZyBicmFjZS4KKyAgYm9vbCBQYXJzZVVuaW50ZXJwcmV0ZWRCbG9jayhzdHJpbmcqIHZhbHVlKTsKKworICBzdHJ1Y3QgTWFwRmllbGQgeworICAgIC8vIFdoZXRoZXIgdGhlIGZpZWxkIGlzIGEgbWFwIGZpZWxkLgorICAgIGJvb2wgaXNfbWFwX2ZpZWxkOworICAgIC8vIFRoZSB0eXBlcyBvZiB0aGUga2V5IGFuZCB2YWx1ZSBpZiB0aGV5IGFyZSBwcmltaXRpdmUgdHlwZXMuCisgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OlR5cGUga2V5X3R5cGU7CisgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OlR5cGUgdmFsdWVfdHlwZTsKKyAgICAvLyBPciB0aGUgdHlwZSBuYW1lcyBzdHJpbmcgaWYgdGhlIHR5cGVzIGFyZSBjdXN0b21pemVkIHR5cGVzLgorICAgIHN0cmluZyBrZXlfdHlwZV9uYW1lOworICAgIHN0cmluZyB2YWx1ZV90eXBlX25hbWU7CisKKyAgICBNYXBGaWVsZCgpIDogaXNfbWFwX2ZpZWxkKGZhbHNlKSB7fQorICB9OworICAvLyBEZXN1Z2FyIHRoZSBtYXAgc3ludGF4IHRvIGdlbmVyYXRlIGEgbmVzdGVkIG1hcCBlbnRyeSBtZXNzYWdlLgorICB2b2lkIEdlbmVyYXRlTWFwRW50cnkoY29uc3QgTWFwRmllbGQmIG1hcF9maWVsZCwgRmllbGREZXNjcmlwdG9yUHJvdG8qIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgUmVwZWF0ZWRQdHJGaWVsZDxEZXNjcmlwdG9yUHJvdG8+KiBtZXNzYWdlcyk7CisKKyAgLy8gV2hldGhlciBmaWVsZHMgd2l0aG91dCBsYWJlbCBkZWZhdWx0IHRvIG9wdGlvbmFsIGZpZWxkcy4KKyAgYm9vbCBEZWZhdWx0VG9PcHRpb25hbEZpZWxkcygpIGNvbnN0IHsKKyAgICByZXR1cm4gc3ludGF4X2lkZW50aWZpZXJfID09ICJwcm90bzMiOworICB9CisKKworICBib29sIFZhbGlkYXRlRW51bShjb25zdCBFbnVtRGVzY3JpcHRvclByb3RvKiBwcm90byk7CisKKyAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworICBpbzo6VG9rZW5pemVyKiBpbnB1dF87CisgIGlvOjpFcnJvckNvbGxlY3RvciogZXJyb3JfY29sbGVjdG9yXzsKKyAgU291cmNlQ29kZUluZm8qIHNvdXJjZV9jb2RlX2luZm9fOworICBTb3VyY2VMb2NhdGlvblRhYmxlKiBzb3VyY2VfbG9jYXRpb25fdGFibGVfOyAgLy8gbGVnYWN5CisgIGJvb2wgaGFkX2Vycm9yc187CisgIGJvb2wgcmVxdWlyZV9zeW50YXhfaWRlbnRpZmllcl87CisgIGJvb2wgc3RvcF9hZnRlcl9zeW50YXhfaWRlbnRpZmllcl87CisgIHN0cmluZyBzeW50YXhfaWRlbnRpZmllcl87CisKKyAgLy8gTGVhZGluZyBkb2MgY29tbWVudHMgZm9yIHRoZSBuZXh0IGRlY2xhcmF0aW9uLiAgVGhlc2UgYXJlIG5vdCBjb21wbGV0ZQorICAvLyB5ZXQ7IHVzZSBDb25zdW1lRW5kT2ZEZWNsYXJhdGlvbigpIHRvIGdldCB0aGUgY29tcGxldGUgY29tbWVudHMuCisgIHN0cmluZyB1cGNvbWluZ19kb2NfY29tbWVudHNfOworCisgIC8vIERldGFjaGVkIGNvbW1lbnRzIGFyZSBub3QgY29ubmVjdGVkIHRvIGFueSBzeW50YXggZW50aXRpZXMuIEVsZW1lbnRzIGluCisgIC8vIHRoaXMgdmVjdG9yIGFyZSBwYXJhZ3JhcGhzIG9mIGNvbW1lbnRzIHNlcGFyYXRlZCBieSBlbXB0eSBsaW5lcy4gVGhlCisgIC8vIGRldGFjaGVkIGNvbW1lbnRzIHdpbGwgYmUgcHV0IGludG8gdGhlIGxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMgZmllbGQgZm9yCisgIC8vIHRoZSBuZXh0IGVsZW1lbnQgKFNlZSBTb3VyY2VDb2RlSW5mby5Mb2NhdGlvbiBpbiBkZXNjcmlwdG9yLnByb3RvKSwgd2hlbgorICAvLyBDb25zdW1lRW5kT2ZEZWNsYXJhdGlvbigpIGlzIGNhbGxlZC4KKyAgdmVjdG9yPHN0cmluZz4gdXBjb21pbmdfZGV0YWNoZWRfY29tbWVudHNfOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhQYXJzZXIpOworfTsKKworLy8gQSB0YWJsZSBtYXBwaW5nIChkZXNjcmlwdG9yLCBFcnJvckxvY2F0aW9uKSBwYWlycyAtLSBhcyByZXBvcnRlZCBieQorLy8gRGVzY3JpcHRvclBvb2wgd2hlbiB2YWxpZGF0aW5nIGRlc2NyaXB0b3JzIC0tIHRvIGxpbmUgYW5kIGNvbHVtbiBudW1iZXJzCisvLyB3aXRoaW4gdGhlIG9yaWdpbmFsIHNvdXJjZSBjb2RlLgorLy8KKy8vIFRoaXMgaXMgc2VtaS1vYnNvbGV0ZTogIEZpbGVEZXNjcmlwdG9yUHJvdG8uc291cmNlX2NvZGVfaW5mbyBub3cgY29udGFpbnMKKy8vIGZhciBtb3JlIGNvbXBsZXRlIGluZm9ybWF0aW9uIGFib3V0IHNvdXJjZSBsb2NhdGlvbnMuICBIb3dldmVyLCBhcyBvZiB0aGlzCisvLyB3cml0aW5nIHlvdSBzdGlsbCBuZWVkIHRvIHVzZSBTb3VyY2VMb2NhdGlvblRhYmxlIHdoZW4gaW50ZWdyYXRpbmcgd2l0aAorLy8gRGVzY3JpcHRvclBvb2wuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgU291cmNlTG9jYXRpb25UYWJsZSB7CisgcHVibGljOgorICBTb3VyY2VMb2NhdGlvblRhYmxlKCk7CisgIH5Tb3VyY2VMb2NhdGlvblRhYmxlKCk7CisKKyAgLy8gRmluZHMgdGhlIHByZWNpc2UgbG9jYXRpb24gb2YgdGhlIGdpdmVuIGVycm9yIGFuZCBmaWxscyBpbiAqbGluZSBhbmQKKyAgLy8gKmNvbHVtbiB3aXRoIHRoZSBsaW5lIGFuZCBjb2x1bW4gbnVtYmVycy4gIElmIG5vdCBmb3VuZCwgc2V0cyAqbGluZSB0bworICAvLyAtMSBhbmQgKmNvbHVtbiB0byAwIChzaW5jZSBsaW5lID0gLTEgaXMgdXNlZCB0byBtZWFuICJlcnJvciBoYXMgbm8gZXhhY3QKKyAgLy8gbG9jYXRpb24iIGluIHRoZSBFcnJvckNvbGxlY3RvciBpbnRlcmZhY2UpLiAgUmV0dXJucyB0cnVlIGlmIGZvdW5kLCBmYWxzZQorICAvLyBvdGhlcndpc2UuCisgIGJvb2wgRmluZChjb25zdCBNZXNzYWdlKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpFcnJvckxvY2F0aW9uIGxvY2F0aW9uLAorICAgICAgICAgICAgaW50KiBsaW5lLCBpbnQqIGNvbHVtbikgY29uc3Q7CisKKyAgLy8gQWRkcyBhIGxvY2F0aW9uIHRvIHRoZSB0YWJsZS4KKyAgdm9pZCBBZGQoY29uc3QgTWVzc2FnZSogZGVzY3JpcHRvciwKKyAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpFcnJvckxvY2F0aW9uIGxvY2F0aW9uLAorICAgICAgICAgICBpbnQgbGluZSwgaW50IGNvbHVtbik7CisKKyAgLy8gQ2xlYXJzIHRoZSBjb250ZW50cyBvZiB0aGUgdGFibGUuCisgIHZvaWQgQ2xlYXIoKTsKKworIHByaXZhdGU6CisgIHR5cGVkZWYgbWFwPAorICAgIHBhaXI8Y29uc3QgTWVzc2FnZSosIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6RXJyb3JMb2NhdGlvbj4sCisgICAgcGFpcjxpbnQsIGludD4gPiBMb2NhdGlvbk1hcDsKKyAgTG9jYXRpb25NYXAgbG9jYXRpb25fbWFwXzsKK307CisKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX1BBUlNFUl9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGFyc2VyX3VuaXR0ZXN0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wYXJzZXJfdW5pdHRlc3QuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWQ2MjNkZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGFyc2VyX3VuaXR0ZXN0LmNjCkBAIC0wLDAgKzEsMzE1NyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorI2luY2x1ZGUgPHZlY3Rvcj4KKyNpbmNsdWRlIDxhbGdvcml0aG0+CisjaW5jbHVkZSA8bWFwPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BhcnNlci5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3Rva2VuaXplci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX2ltcGwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXh0X2Zvcm1hdC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9jdXN0b21fb3B0aW9ucy5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N1YnN0aXR1dGUuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbWFwX3V0aWwuaD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2dvb2dsZXRlc3QuaD4KKyNpbmNsdWRlIDxndGVzdC9ndGVzdC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworCituYW1lc3BhY2UgeworCitjbGFzcyBNb2NrRXJyb3JDb2xsZWN0b3IgOiBwdWJsaWMgaW86OkVycm9yQ29sbGVjdG9yIHsKKyBwdWJsaWM6CisgIE1vY2tFcnJvckNvbGxlY3RvcigpIHt9CisgIH5Nb2NrRXJyb3JDb2xsZWN0b3IoKSB7fQorCisgIHN0cmluZyB0ZXh0XzsKKworICAvLyBpbXBsZW1lbnRzIEVycm9yQ29sbGVjdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICB2b2lkIEFkZEVycm9yKGludCBsaW5lLCBpbnQgY29sdW1uLCBjb25zdCBzdHJpbmcmIG1lc3NhZ2UpIHsKKyAgICBzdHJpbmdzOjpTdWJzdGl0dXRlQW5kQXBwZW5kKCZ0ZXh0XywgIiQwOiQxOiAkMlxuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmUsIGNvbHVtbiwgbWVzc2FnZSk7CisgIH0KK307CisKK2NsYXNzIE1vY2tWYWxpZGF0aW9uRXJyb3JDb2xsZWN0b3IgOiBwdWJsaWMgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yIHsKKyBwdWJsaWM6CisgIE1vY2tWYWxpZGF0aW9uRXJyb3JDb2xsZWN0b3IoY29uc3QgU291cmNlTG9jYXRpb25UYWJsZSYgc291cmNlX2xvY2F0aW9ucywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6RXJyb3JDb2xsZWN0b3IqIHdyYXBwZWRfY29sbGVjdG9yKQorICAgIDogc291cmNlX2xvY2F0aW9uc18oc291cmNlX2xvY2F0aW9ucyksCisgICAgICB3cmFwcGVkX2NvbGxlY3Rvcl8od3JhcHBlZF9jb2xsZWN0b3IpIHt9CisgIH5Nb2NrVmFsaWRhdGlvbkVycm9yQ29sbGVjdG9yKCkge30KKworICAvLyBpbXBsZW1lbnRzIEVycm9yQ29sbGVjdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICB2b2lkIEFkZEVycm9yKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUsCisgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBlbGVtZW50X25hbWUsCisgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZSogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICBFcnJvckxvY2F0aW9uIGxvY2F0aW9uLAorICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgbWVzc2FnZSkgeworICAgIGludCBsaW5lLCBjb2x1bW47CisgICAgc291cmNlX2xvY2F0aW9uc18uRmluZChkZXNjcmlwdG9yLCBsb2NhdGlvbiwgJmxpbmUsICZjb2x1bW4pOworICAgIHdyYXBwZWRfY29sbGVjdG9yXy0+QWRkRXJyb3IobGluZSwgY29sdW1uLCBtZXNzYWdlKTsKKyAgfQorCisgcHJpdmF0ZToKKyAgY29uc3QgU291cmNlTG9jYXRpb25UYWJsZSYgc291cmNlX2xvY2F0aW9uc187CisgIGlvOjpFcnJvckNvbGxlY3Rvciogd3JhcHBlZF9jb2xsZWN0b3JfOworfTsKKworY2xhc3MgUGFyc2VyVGVzdCA6IHB1YmxpYyB0ZXN0aW5nOjpUZXN0IHsKKyBwcm90ZWN0ZWQ6CisgIFBhcnNlclRlc3QoKQorICAgIDogcmVxdWlyZV9zeW50YXhfaWRlbnRpZmllcl8oZmFsc2UpIHt9CisKKyAgLy8gU2V0IHVwIHRoZSBwYXJzZXIgdG8gcGFyc2UgdGhlIGdpdmVuIHRleHQuCisgIHZvaWQgU2V0dXBQYXJzZXIoY29uc3QgY2hhciogdGV4dCkgeworICAgIHJhd19pbnB1dF8ucmVzZXQobmV3IGlvOjpBcnJheUlucHV0U3RyZWFtKHRleHQsIHN0cmxlbih0ZXh0KSkpOworICAgIGlucHV0Xy5yZXNldChuZXcgaW86OlRva2VuaXplcihyYXdfaW5wdXRfLmdldCgpLCAmZXJyb3JfY29sbGVjdG9yXykpOworICAgIHBhcnNlcl8ucmVzZXQobmV3IFBhcnNlcigpKTsKKyAgICBwYXJzZXJfLT5SZWNvcmRFcnJvcnNUbygmZXJyb3JfY29sbGVjdG9yXyk7CisgICAgcGFyc2VyXy0+U2V0UmVxdWlyZVN5bnRheElkZW50aWZpZXIocmVxdWlyZV9zeW50YXhfaWRlbnRpZmllcl8pOworICB9CisKKyAgLy8gUGFyc2UgdGhlIGlucHV0IGFuZCBleHBlY3QgdGhhdCB0aGUgcmVzdWx0aW5nIEZpbGVEZXNjcmlwdG9yUHJvdG8gbWF0Y2hlcworICAvLyB0aGUgZ2l2ZW4gb3V0cHV0LiAgVGhlIG91dHB1dCBpcyBhIEZpbGVEZXNjcmlwdG9yUHJvdG8gaW4gcHJvdG9jb2wgYnVmZmVyCisgIC8vIHRleHQgZm9ybWF0LgorICB2b2lkIEV4cGVjdFBhcnNlc1RvKGNvbnN0IGNoYXIqIGlucHV0LCBjb25zdCBjaGFyKiBvdXRwdXQpIHsKKyAgICBTZXR1cFBhcnNlcihpbnB1dCk7CisgICAgRmlsZURlc2NyaXB0b3JQcm90byBhY3R1YWwsIGV4cGVjdGVkOworCisgICAgcGFyc2VyXy0+UGFyc2UoaW5wdXRfLmdldCgpLCAmYWN0dWFsKTsKKyAgICBFWFBFQ1RfRVEoaW86OlRva2VuaXplcjo6VFlQRV9FTkQsIGlucHV0Xy0+Y3VycmVudCgpLnR5cGUpOworICAgIEFTU0VSVF9FUSgiIiwgZXJyb3JfY29sbGVjdG9yXy50ZXh0Xyk7CisKKyAgICAvLyBXZSBkb24ndCBjb3ZlciBTb3VyY2VDb2RlSW5mbyBpbiB0aGVzZSB0ZXN0cy4KKyAgICBhY3R1YWwuY2xlYXJfc291cmNlX2NvZGVfaW5mbygpOworCisgICAgLy8gUGFyc2UgdGhlIEFTQ0lJIHJlcHJlc2VudGF0aW9uIGluIG9yZGVyIHRvIGNhbm9uaWNhbGl6ZSBpdC4gIFdlIGNvdWxkCisgICAgLy8ganVzdCBjb21wYXJlIGRpcmVjdGx5IHRvIGFjdHVhbC5EZWJ1Z1N0cmluZygpLCBidXQgdGhhdCB3b3VsZCByZXF1aXJlCisgICAgLy8gdGhhdCB0aGUgY2FsbGVyIHByZWNpc2VseSBtYXRjaCB0aGUgZm9ybWF0dGluZyB0aGF0IERlYnVnU3RyaW5nKCkKKyAgICAvLyBwcm9kdWNlcy4KKyAgICBBU1NFUlRfVFJVRShUZXh0Rm9ybWF0OjpQYXJzZUZyb21TdHJpbmcob3V0cHV0LCAmZXhwZWN0ZWQpKTsKKworICAgIC8vIENvbXBhcmUgYnkgY29tcGFyaW5nIGRlYnVnIHN0cmluZ3MuCisgICAgLy8gVE9ETyhrZW50b24pOiAgVXNlIGRpZmZlcmVuY2VyLCBvbmNlIGl0IGlzIGF2YWlsYWJsZS4KKyAgICBFWFBFQ1RfRVEoZXhwZWN0ZWQuRGVidWdTdHJpbmcoKSwgYWN0dWFsLkRlYnVnU3RyaW5nKCkpOworICB9CisKKyAgLy8gUGFyc2UgdGhlIHRleHQgYW5kIGV4cGVjdCB0aGF0IHRoZSBnaXZlbiBlcnJvcnMgYXJlIHJlcG9ydGVkLgorICB2b2lkIEV4cGVjdEhhc0Vycm9ycyhjb25zdCBjaGFyKiB0ZXh0LCBjb25zdCBjaGFyKiBleHBlY3RlZF9lcnJvcnMpIHsKKyAgICBFeHBlY3RIYXNFYXJseUV4aXRFcnJvcnModGV4dCwgZXhwZWN0ZWRfZXJyb3JzKTsKKyAgICBFWFBFQ1RfRVEoaW86OlRva2VuaXplcjo6VFlQRV9FTkQsIGlucHV0Xy0+Y3VycmVudCgpLnR5cGUpOworICB9CisKKyAgLy8gU2FtZSBhcyBhYm92ZSBidXQgZG9lcyBub3QgZXhwZWN0IHRoYXQgdGhlIHBhcnNlciBwYXJzZXMgdGhlIGNvbXBsZXRlCisgIC8vIGlucHV0LgorICB2b2lkIEV4cGVjdEhhc0Vhcmx5RXhpdEVycm9ycyhjb25zdCBjaGFyKiB0ZXh0LCBjb25zdCBjaGFyKiBleHBlY3RlZF9lcnJvcnMpIHsKKyAgICBTZXR1cFBhcnNlcih0ZXh0KTsKKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGU7CisgICAgcGFyc2VyXy0+UGFyc2UoaW5wdXRfLmdldCgpLCAmZmlsZSk7CisgICAgRVhQRUNUX0VRKGV4cGVjdGVkX2Vycm9ycywgZXJyb3JfY29sbGVjdG9yXy50ZXh0Xyk7CisgIH0KKworICAvLyBQYXJzZSB0aGUgdGV4dCBhcyBhIGZpbGUgYW5kIHZhbGlkYXRlIGl0ICh3aXRoIGEgRGVzY3JpcHRvclBvb2wpLCBhbmQKKyAgLy8gZXhwZWN0IHRoYXQgdGhlIHZhbGlkYXRpb24gc3RlcCByZXBvcnRzIHRoZSBnaXZlbiBlcnJvcnMuCisgIHZvaWQgRXhwZWN0SGFzVmFsaWRhdGlvbkVycm9ycyhjb25zdCBjaGFyKiB0ZXh0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogZXhwZWN0ZWRfZXJyb3JzKSB7CisgICAgU2V0dXBQYXJzZXIodGV4dCk7CisgICAgU291cmNlTG9jYXRpb25UYWJsZSBzb3VyY2VfbG9jYXRpb25zOworICAgIHBhcnNlcl8tPlJlY29yZFNvdXJjZUxvY2F0aW9uc1RvKCZzb3VyY2VfbG9jYXRpb25zKTsKKworICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZTsKKyAgICBmaWxlLnNldF9uYW1lKCJmb28ucHJvdG8iKTsKKyAgICBwYXJzZXJfLT5QYXJzZShpbnB1dF8uZ2V0KCksICZmaWxlKTsKKyAgICBFWFBFQ1RfRVEoaW86OlRva2VuaXplcjo6VFlQRV9FTkQsIGlucHV0Xy0+Y3VycmVudCgpLnR5cGUpOworICAgIEFTU0VSVF9FUSgiIiwgZXJyb3JfY29sbGVjdG9yXy50ZXh0Xyk7CisKKyAgICBNb2NrVmFsaWRhdGlvbkVycm9yQ29sbGVjdG9yIHZhbGlkYXRpb25fZXJyb3JfY29sbGVjdG9yKAorICAgICAgc291cmNlX2xvY2F0aW9ucywgJmVycm9yX2NvbGxlY3Rvcl8pOworICAgIEVYUEVDVF9UUlVFKHBvb2xfLkJ1aWxkRmlsZUNvbGxlY3RpbmdFcnJvcnMoCisgICAgICBmaWxlLCAmdmFsaWRhdGlvbl9lcnJvcl9jb2xsZWN0b3IpID09IE5VTEwpOworICAgIEVYUEVDVF9FUShleHBlY3RlZF9lcnJvcnMsIGVycm9yX2NvbGxlY3Rvcl8udGV4dF8pOworICB9CisKKyAgTW9ja0Vycm9yQ29sbGVjdG9yIGVycm9yX2NvbGxlY3Rvcl87CisgIERlc2NyaXB0b3JQb29sIHBvb2xfOworCisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8aW86Olplcm9Db3B5SW5wdXRTdHJlYW0+IHJhd19pbnB1dF87CisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8aW86OlRva2VuaXplcj4gaW5wdXRfOworICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPFBhcnNlcj4gcGFyc2VyXzsKKyAgYm9vbCByZXF1aXJlX3N5bnRheF9pZGVudGlmaWVyXzsKK307CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworVEVTVF9GKFBhcnNlclRlc3QsIFN0b3BBZnRlclN5bnRheElkZW50aWZpZXIpIHsKKyAgU2V0dXBQYXJzZXIoCisgICAgIi8vIGJsYWhcbiIKKyAgICAic3ludGF4ID0gXCJmb29iYXJcIjtcbiIKKyAgICAidGhpcyBsaW5lIHdpbGwgbm90IGJlIHBhcnNlZFxuIik7CisgIHBhcnNlcl8tPlNldFN0b3BBZnRlclN5bnRheElkZW50aWZpZXIodHJ1ZSk7CisgIEVYUEVDVF9UUlVFKHBhcnNlcl8tPlBhcnNlKGlucHV0Xy5nZXQoKSwgTlVMTCkpOworICBFWFBFQ1RfRVEoIiIsIGVycm9yX2NvbGxlY3Rvcl8udGV4dF8pOworICBFWFBFQ1RfRVEoImZvb2JhciIsIHBhcnNlcl8tPkdldFN5bnRheElkZW50aWZpZXIoKSk7Cit9CisKK1RFU1RfRihQYXJzZXJUZXN0LCBTdG9wQWZ0ZXJPbWl0dGVkU3ludGF4SWRlbnRpZmllcikgeworICBTZXR1cFBhcnNlcigKKyAgICAiLy8gYmxhaFxuIgorICAgICJ0aGlzIGxpbmUgd2lsbCBub3QgYmUgcGFyc2VkXG4iKTsKKyAgcGFyc2VyXy0+U2V0U3RvcEFmdGVyU3ludGF4SWRlbnRpZmllcih0cnVlKTsKKyAgRVhQRUNUX1RSVUUocGFyc2VyXy0+UGFyc2UoaW5wdXRfLmdldCgpLCBOVUxMKSk7CisgIEVYUEVDVF9FUSgiIiwgZXJyb3JfY29sbGVjdG9yXy50ZXh0Xyk7CisgIEVYUEVDVF9FUSgiIiwgcGFyc2VyXy0+R2V0U3ludGF4SWRlbnRpZmllcigpKTsKK30KKworVEVTVF9GKFBhcnNlclRlc3QsIFN0b3BBZnRlclN5bnRheElkZW50aWZpZXJXaXRoRXJyb3JzKSB7CisgIFNldHVwUGFyc2VyKAorICAgICIvLyBibGFoXG4iCisgICAgInN5bnRheCA9IGVycm9yO1xuIik7CisgIHBhcnNlcl8tPlNldFN0b3BBZnRlclN5bnRheElkZW50aWZpZXIodHJ1ZSk7CisgIEVYUEVDVF9GQUxTRShwYXJzZXJfLT5QYXJzZShpbnB1dF8uZ2V0KCksIE5VTEwpKTsKKyAgRVhQRUNUX0VRKCIxOjk6IEV4cGVjdGVkIHN5bnRheCBpZGVudGlmaWVyLlxuIiwgZXJyb3JfY29sbGVjdG9yXy50ZXh0Xyk7Cit9CisKK1RFU1RfRihQYXJzZXJUZXN0LCBXYXJuSWZTeW50YXhJZGVudGlmaWVyT21taXR0ZWQpIHsKKyAgU2V0dXBQYXJzZXIoIm1lc3NhZ2UgQSB7fSIpOworICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGU7CisgIENhcHR1cmVUZXN0U3RkZXJyKCk7CisgIEVYUEVDVF9UUlVFKHBhcnNlcl8tPlBhcnNlKGlucHV0Xy5nZXQoKSwgJmZpbGUpKTsKKyAgRVhQRUNUX1RSVUUoCisgICAgICBHZXRDYXB0dXJlZFRlc3RTdGRlcnIoKS5maW5kKCJObyBzeW50YXggc3BlY2lmaWVkIikgIT0gc3RyaW5nOjpucG9zKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCit0eXBlZGVmIFBhcnNlclRlc3QgUGFyc2VNZXNzYWdlVGVzdDsKKworVEVTVF9GKFBhcnNlTWVzc2FnZVRlc3QsIElnbm9yZUJPTSkgeworICBjaGFyIGlucHV0W10gPSAiICAgbWVzc2FnZSBUZXN0TWVzc2FnZSB7XG4iCisgICAgICAiICByZXF1aXJlZCBpbnQzMiBmb28gPSAxO1xuIgorICAgICAgIn1cbiI7CisgIC8vIFNldCBVVEYtOCBCT00uCisgIGlucHV0WzBdID0gKGNoYXIpMHhFRjsKKyAgaW5wdXRbMV0gPSAoY2hhcikweEJCOworICBpbnB1dFsyXSA9IChjaGFyKTB4QkY7CisgIEV4cGVjdFBhcnNlc1RvKGlucHV0LAorICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIlRlc3RNZXNzYWdlXCIiCisgICAgIiAgZmllbGQgeyBuYW1lOlwiZm9vXCIgbGFiZWw6TEFCRUxfUkVRVUlSRUQgdHlwZTpUWVBFX0lOVDMyIG51bWJlcjoxIH0iCisgICAgIn0iKTsKK30KKworVEVTVF9GKFBhcnNlTWVzc2FnZVRlc3QsIEJPTUVycm9yKSB7CisgIGNoYXIgaW5wdXRbXSA9ICIgICBtZXNzYWdlIFRlc3RNZXNzYWdlIHtcbiIKKyAgICAgICIgIHJlcXVpcmVkIGludDMyIGZvbyA9IDE7XG4iCisgICAgICAifVxuIjsKKyAgaW5wdXRbMF0gPSAoY2hhcikweEVGOworICBFeHBlY3RIYXNFcnJvcnMoaW5wdXQsCisgICAgICAgICAgICAgICAgICAiMDoxOiBQcm90byBmaWxlIHN0YXJ0cyB3aXRoIDB4RUYgYnV0IG5vdCBVVEYtOCBCT00uICIKKyAgICAgICAgICAgICAgICAgICJPbmx5IFVURi04IGlzIGFjY2VwdGVkIGZvciBwcm90byBmaWxlLlxuIgorICAgICAgICAgICAgICAgICAgIjA6MDogRXhwZWN0ZWQgdG9wLWxldmVsIHN0YXRlbWVudCAoZS5nLiBcIm1lc3NhZ2VcIikuXG4iKTsKK30KKworVEVTVF9GKFBhcnNlTWVzc2FnZVRlc3QsIFNpbXBsZU1lc3NhZ2UpIHsKKyAgRXhwZWN0UGFyc2VzVG8oCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIHJlcXVpcmVkIGludDMyIGZvbyA9IDE7XG4iCisgICAgIn1cbiIsCisKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJUZXN0TWVzc2FnZVwiIgorICAgICIgIGZpZWxkIHsgbmFtZTpcImZvb1wiIGxhYmVsOkxBQkVMX1JFUVVJUkVEIHR5cGU6VFlQRV9JTlQzMiBudW1iZXI6MSB9IgorICAgICJ9Iik7Cit9CisKK1RFU1RfRihQYXJzZU1lc3NhZ2VUZXN0LCBJbXBsaWNpdFN5bnRheElkZW50aWZpZXIpIHsKKyAgcmVxdWlyZV9zeW50YXhfaWRlbnRpZmllcl8gPSBmYWxzZTsKKyAgRXhwZWN0UGFyc2VzVG8oCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIHJlcXVpcmVkIGludDMyIGZvbyA9IDE7XG4iCisgICAgIn1cbiIsCisKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJUZXN0TWVzc2FnZVwiIgorICAgICIgIGZpZWxkIHsgbmFtZTpcImZvb1wiIGxhYmVsOkxBQkVMX1JFUVVJUkVEIHR5cGU6VFlQRV9JTlQzMiBudW1iZXI6MSB9IgorICAgICJ9Iik7CisgIEVYUEVDVF9FUSgicHJvdG8yIiwgcGFyc2VyXy0+R2V0U3ludGF4SWRlbnRpZmllcigpKTsKK30KKworVEVTVF9GKFBhcnNlTWVzc2FnZVRlc3QsIEV4cGxpY2l0U3ludGF4SWRlbnRpZmllcikgeworICBFeHBlY3RQYXJzZXNUbygKKyAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAibWVzc2FnZSBUZXN0TWVzc2FnZSB7XG4iCisgICAgIiAgcmVxdWlyZWQgaW50MzIgZm9vID0gMTtcbiIKKyAgICAifVxuIiwKKworICAgICJzeW50YXg6ICdwcm90bzInICIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJUZXN0TWVzc2FnZVwiIgorICAgICIgIGZpZWxkIHsgbmFtZTpcImZvb1wiIGxhYmVsOkxBQkVMX1JFUVVJUkVEIHR5cGU6VFlQRV9JTlQzMiBudW1iZXI6MSB9IgorICAgICJ9Iik7CisgIEVYUEVDVF9FUSgicHJvdG8yIiwgcGFyc2VyXy0+R2V0U3ludGF4SWRlbnRpZmllcigpKTsKK30KKworVEVTVF9GKFBhcnNlTWVzc2FnZVRlc3QsIEV4cGxpY2l0UmVxdWlyZWRTeW50YXhJZGVudGlmaWVyKSB7CisgIHJlcXVpcmVfc3ludGF4X2lkZW50aWZpZXJfID0gdHJ1ZTsKKyAgRXhwZWN0UGFyc2VzVG8oCisgICAgInN5bnRheCA9IFwicHJvdG8yXCI7XG4iCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIHJlcXVpcmVkIGludDMyIGZvbyA9IDE7XG4iCisgICAgIn1cbiIsCisKKyAgICAic3ludGF4OiAncHJvdG8yJyAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiVGVzdE1lc3NhZ2VcIiIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJmb29cIiBsYWJlbDpMQUJFTF9SRVFVSVJFRCB0eXBlOlRZUEVfSU5UMzIgbnVtYmVyOjEgfSIKKyAgICAifSIpOworICBFWFBFQ1RfRVEoInByb3RvMiIsIHBhcnNlcl8tPkdldFN5bnRheElkZW50aWZpZXIoKSk7Cit9CisKK1RFU1RfRihQYXJzZU1lc3NhZ2VUZXN0LCBTaW1wbGVGaWVsZHMpIHsKKyAgRXhwZWN0UGFyc2VzVG8oCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIHJlcXVpcmVkIGludDMyIGZvbyA9IDE1O1xuIgorICAgICIgIG9wdGlvbmFsIGludDMyIGJhciA9IDM0O1xuIgorICAgICIgIHJlcGVhdGVkIGludDMyIGJheiA9IDM7XG4iCisgICAgIn1cbiIsCisKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJUZXN0TWVzc2FnZVwiIgorICAgICIgIGZpZWxkIHsgbmFtZTpcImZvb1wiIGxhYmVsOkxBQkVMX1JFUVVJUkVEIHR5cGU6VFlQRV9JTlQzMiBudW1iZXI6MTUgfSIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJiYXJcIiBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgbnVtYmVyOjM0IH0iCisgICAgIiAgZmllbGQgeyBuYW1lOlwiYmF6XCIgbGFiZWw6TEFCRUxfUkVQRUFURUQgdHlwZTpUWVBFX0lOVDMyIG51bWJlcjozICB9IgorICAgICJ9Iik7Cit9CisKK1RFU1RfRihQYXJzZU1lc3NhZ2VUZXN0LCBQcmltaXRpdmVGaWVsZFR5cGVzKSB7CisgIEV4cGVjdFBhcnNlc1RvKAorICAgICJtZXNzYWdlIFRlc3RNZXNzYWdlIHtcbiIKKyAgICAiICByZXF1aXJlZCBpbnQzMiAgICBmb28gPSAxO1xuIgorICAgICIgIHJlcXVpcmVkIGludDY0ICAgIGZvbyA9IDE7XG4iCisgICAgIiAgcmVxdWlyZWQgdWludDMyICAgZm9vID0gMTtcbiIKKyAgICAiICByZXF1aXJlZCB1aW50NjQgICBmb28gPSAxO1xuIgorICAgICIgIHJlcXVpcmVkIHNpbnQzMiAgIGZvbyA9IDE7XG4iCisgICAgIiAgcmVxdWlyZWQgc2ludDY0ICAgZm9vID0gMTtcbiIKKyAgICAiICByZXF1aXJlZCBmaXhlZDMyICBmb28gPSAxO1xuIgorICAgICIgIHJlcXVpcmVkIGZpeGVkNjQgIGZvbyA9IDE7XG4iCisgICAgIiAgcmVxdWlyZWQgc2ZpeGVkMzIgZm9vID0gMTtcbiIKKyAgICAiICByZXF1aXJlZCBzZml4ZWQ2NCBmb28gPSAxO1xuIgorICAgICIgIHJlcXVpcmVkIGZsb2F0ICAgIGZvbyA9IDE7XG4iCisgICAgIiAgcmVxdWlyZWQgZG91YmxlICAgZm9vID0gMTtcbiIKKyAgICAiICByZXF1aXJlZCBzdHJpbmcgICBmb28gPSAxO1xuIgorICAgICIgIHJlcXVpcmVkIGJ5dGVzICAgIGZvbyA9IDE7XG4iCisgICAgIiAgcmVxdWlyZWQgYm9vbCAgICAgZm9vID0gMTtcbiIKKyAgICAifVxuIiwKKworICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIlRlc3RNZXNzYWdlXCIiCisgICAgIiAgZmllbGQgeyBuYW1lOlwiZm9vXCIgbGFiZWw6TEFCRUxfUkVRVUlSRUQgdHlwZTpUWVBFX0lOVDMyICAgIG51bWJlcjoxIH0iCisgICAgIiAgZmllbGQgeyBuYW1lOlwiZm9vXCIgbGFiZWw6TEFCRUxfUkVRVUlSRUQgdHlwZTpUWVBFX0lOVDY0ICAgIG51bWJlcjoxIH0iCisgICAgIiAgZmllbGQgeyBuYW1lOlwiZm9vXCIgbGFiZWw6TEFCRUxfUkVRVUlSRUQgdHlwZTpUWVBFX1VJTlQzMiAgIG51bWJlcjoxIH0iCisgICAgIiAgZmllbGQgeyBuYW1lOlwiZm9vXCIgbGFiZWw6TEFCRUxfUkVRVUlSRUQgdHlwZTpUWVBFX1VJTlQ2NCAgIG51bWJlcjoxIH0iCisgICAgIiAgZmllbGQgeyBuYW1lOlwiZm9vXCIgbGFiZWw6TEFCRUxfUkVRVUlSRUQgdHlwZTpUWVBFX1NJTlQzMiAgIG51bWJlcjoxIH0iCisgICAgIiAgZmllbGQgeyBuYW1lOlwiZm9vXCIgbGFiZWw6TEFCRUxfUkVRVUlSRUQgdHlwZTpUWVBFX1NJTlQ2NCAgIG51bWJlcjoxIH0iCisgICAgIiAgZmllbGQgeyBuYW1lOlwiZm9vXCIgbGFiZWw6TEFCRUxfUkVRVUlSRUQgdHlwZTpUWVBFX0ZJWEVEMzIgIG51bWJlcjoxIH0iCisgICAgIiAgZmllbGQgeyBuYW1lOlwiZm9vXCIgbGFiZWw6TEFCRUxfUkVRVUlSRUQgdHlwZTpUWVBFX0ZJWEVENjQgIG51bWJlcjoxIH0iCisgICAgIiAgZmllbGQgeyBuYW1lOlwiZm9vXCIgbGFiZWw6TEFCRUxfUkVRVUlSRUQgdHlwZTpUWVBFX1NGSVhFRDMyIG51bWJlcjoxIH0iCisgICAgIiAgZmllbGQgeyBuYW1lOlwiZm9vXCIgbGFiZWw6TEFCRUxfUkVRVUlSRUQgdHlwZTpUWVBFX1NGSVhFRDY0IG51bWJlcjoxIH0iCisgICAgIiAgZmllbGQgeyBuYW1lOlwiZm9vXCIgbGFiZWw6TEFCRUxfUkVRVUlSRUQgdHlwZTpUWVBFX0ZMT0FUICAgIG51bWJlcjoxIH0iCisgICAgIiAgZmllbGQgeyBuYW1lOlwiZm9vXCIgbGFiZWw6TEFCRUxfUkVRVUlSRUQgdHlwZTpUWVBFX0RPVUJMRSAgIG51bWJlcjoxIH0iCisgICAgIiAgZmllbGQgeyBuYW1lOlwiZm9vXCIgbGFiZWw6TEFCRUxfUkVRVUlSRUQgdHlwZTpUWVBFX1NUUklORyAgIG51bWJlcjoxIH0iCisgICAgIiAgZmllbGQgeyBuYW1lOlwiZm9vXCIgbGFiZWw6TEFCRUxfUkVRVUlSRUQgdHlwZTpUWVBFX0JZVEVTICAgIG51bWJlcjoxIH0iCisgICAgIiAgZmllbGQgeyBuYW1lOlwiZm9vXCIgbGFiZWw6TEFCRUxfUkVRVUlSRUQgdHlwZTpUWVBFX0JPT0wgICAgIG51bWJlcjoxIH0iCisgICAgIn0iKTsKK30KKworVEVTVF9GKFBhcnNlTWVzc2FnZVRlc3QsIEZpZWxkRGVmYXVsdHMpIHsKKyAgRXhwZWN0UGFyc2VzVG8oCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIHJlcXVpcmVkIGludDMyICBmb28gPSAxIFtkZWZhdWx0PSAgMSAgXTtcbiIKKyAgICAiICByZXF1aXJlZCBpbnQzMiAgZm9vID0gMSBbZGVmYXVsdD0gLTIgIF07XG4iCisgICAgIiAgcmVxdWlyZWQgaW50NjQgIGZvbyA9IDEgW2RlZmF1bHQ9ICAzICBdO1xuIgorICAgICIgIHJlcXVpcmVkIGludDY0ICBmb28gPSAxIFtkZWZhdWx0PSAtNCAgXTtcbiIKKyAgICAiICByZXF1aXJlZCB1aW50MzIgZm9vID0gMSBbZGVmYXVsdD0gIDUgIF07XG4iCisgICAgIiAgcmVxdWlyZWQgdWludDY0IGZvbyA9IDEgW2RlZmF1bHQ9ICA2ICBdO1xuIgorICAgICIgIHJlcXVpcmVkIGZsb2F0ICBmb28gPSAxIFtkZWZhdWx0PSAgNy41XTtcbiIKKyAgICAiICByZXF1aXJlZCBmbG9hdCAgZm9vID0gMSBbZGVmYXVsdD0gLTguNV07XG4iCisgICAgIiAgcmVxdWlyZWQgZmxvYXQgIGZvbyA9IDEgW2RlZmF1bHQ9ICA5ICBdO1xuIgorICAgICIgIHJlcXVpcmVkIGRvdWJsZSBmb28gPSAxIFtkZWZhdWx0PSAxMC41XTtcbiIKKyAgICAiICByZXF1aXJlZCBkb3VibGUgZm9vID0gMSBbZGVmYXVsdD0tMTEuNV07XG4iCisgICAgIiAgcmVxdWlyZWQgZG91YmxlIGZvbyA9IDEgW2RlZmF1bHQ9IDEyICBdO1xuIgorICAgICIgIHJlcXVpcmVkIGRvdWJsZSBmb28gPSAxIFtkZWZhdWx0PSBpbmYgXTtcbiIKKyAgICAiICByZXF1aXJlZCBkb3VibGUgZm9vID0gMSBbZGVmYXVsdD0taW5mIF07XG4iCisgICAgIiAgcmVxdWlyZWQgZG91YmxlIGZvbyA9IDEgW2RlZmF1bHQ9IG5hbiBdO1xuIgorICAgICIgIHJlcXVpcmVkIHN0cmluZyBmb28gPSAxIFtkZWZhdWx0PScxM1xcMDAxJ107XG4iCisgICAgIiAgcmVxdWlyZWQgc3RyaW5nIGZvbyA9IDEgW2RlZmF1bHQ9J2EnIFwiYlwiIFxuIFwiY1wiXTtcbiIKKyAgICAiICByZXF1aXJlZCBieXRlcyAgZm9vID0gMSBbZGVmYXVsdD0nMTRcXDAwMiddO1xuIgorICAgICIgIHJlcXVpcmVkIGJ5dGVzICBmb28gPSAxIFtkZWZhdWx0PSdhJyBcImJcIiBcbiAnYyddO1xuIgorICAgICIgIHJlcXVpcmVkIGJvb2wgICBmb28gPSAxIFtkZWZhdWx0PXRydWUgXTtcbiIKKyAgICAiICByZXF1aXJlZCBGb28gICAgZm9vID0gMSBbZGVmYXVsdD1GT08gIF07XG4iCisKKyAgICAiICByZXF1aXJlZCBpbnQzMiAgZm9vID0gMSBbZGVmYXVsdD0gMHg3RkZGRkZGRl07XG4iCisgICAgIiAgcmVxdWlyZWQgaW50MzIgIGZvbyA9IDEgW2RlZmF1bHQ9LTB4ODAwMDAwMDBdO1xuIgorICAgICIgIHJlcXVpcmVkIHVpbnQzMiBmb28gPSAxIFtkZWZhdWx0PSAweEZGRkZGRkZGXTtcbiIKKyAgICAiICByZXF1aXJlZCBpbnQ2NCAgZm9vID0gMSBbZGVmYXVsdD0gMHg3RkZGRkZGRkZGRkZGRkZGXTtcbiIKKyAgICAiICByZXF1aXJlZCBpbnQ2NCAgZm9vID0gMSBbZGVmYXVsdD0tMHg4MDAwMDAwMDAwMDAwMDAwXTtcbiIKKyAgICAiICByZXF1aXJlZCB1aW50NjQgZm9vID0gMSBbZGVmYXVsdD0gMHhGRkZGRkZGRkZGRkZGRkZGXTtcbiIKKyAgICAiICByZXF1aXJlZCBkb3VibGUgZm9vID0gMSBbZGVmYXVsdD0gMHhhYmNkXTtcbiIKKyAgICAifVxuIiwKKworI2RlZmluZSBFVEMgIm5hbWU6XCJmb29cIiBsYWJlbDpMQUJFTF9SRVFVSVJFRCBudW1iZXI6MSIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJUZXN0TWVzc2FnZVwiIgorICAgICIgIGZpZWxkIHsgdHlwZTpUWVBFX0lOVDMyICAgZGVmYXVsdF92YWx1ZTpcIjFcIiAgICAgICAgICIgRVRDICIgfSIKKyAgICAiICBmaWVsZCB7IHR5cGU6VFlQRV9JTlQzMiAgIGRlZmF1bHRfdmFsdWU6XCItMlwiICAgICAgICAiIEVUQyAiIH0iCisgICAgIiAgZmllbGQgeyB0eXBlOlRZUEVfSU5UNjQgICBkZWZhdWx0X3ZhbHVlOlwiM1wiICAgICAgICAgIiBFVEMgIiB9IgorICAgICIgIGZpZWxkIHsgdHlwZTpUWVBFX0lOVDY0ICAgZGVmYXVsdF92YWx1ZTpcIi00XCIgICAgICAgICIgRVRDICIgfSIKKyAgICAiICBmaWVsZCB7IHR5cGU6VFlQRV9VSU5UMzIgIGRlZmF1bHRfdmFsdWU6XCI1XCIgICAgICAgICAiIEVUQyAiIH0iCisgICAgIiAgZmllbGQgeyB0eXBlOlRZUEVfVUlOVDY0ICBkZWZhdWx0X3ZhbHVlOlwiNlwiICAgICAgICAgIiBFVEMgIiB9IgorICAgICIgIGZpZWxkIHsgdHlwZTpUWVBFX0ZMT0FUICAgZGVmYXVsdF92YWx1ZTpcIjcuNVwiICAgICAgICIgRVRDICIgfSIKKyAgICAiICBmaWVsZCB7IHR5cGU6VFlQRV9GTE9BVCAgIGRlZmF1bHRfdmFsdWU6XCItOC41XCIgICAgICAiIEVUQyAiIH0iCisgICAgIiAgZmllbGQgeyB0eXBlOlRZUEVfRkxPQVQgICBkZWZhdWx0X3ZhbHVlOlwiOVwiICAgICAgICAgIiBFVEMgIiB9IgorICAgICIgIGZpZWxkIHsgdHlwZTpUWVBFX0RPVUJMRSAgZGVmYXVsdF92YWx1ZTpcIjEwLjVcIiAgICAgICIgRVRDICIgfSIKKyAgICAiICBmaWVsZCB7IHR5cGU6VFlQRV9ET1VCTEUgIGRlZmF1bHRfdmFsdWU6XCItMTEuNVwiICAgICAiIEVUQyAiIH0iCisgICAgIiAgZmllbGQgeyB0eXBlOlRZUEVfRE9VQkxFICBkZWZhdWx0X3ZhbHVlOlwiMTJcIiAgICAgICAgIiBFVEMgIiB9IgorICAgICIgIGZpZWxkIHsgdHlwZTpUWVBFX0RPVUJMRSAgZGVmYXVsdF92YWx1ZTpcImluZlwiICAgICAgICIgRVRDICIgfSIKKyAgICAiICBmaWVsZCB7IHR5cGU6VFlQRV9ET1VCTEUgIGRlZmF1bHRfdmFsdWU6XCItaW5mXCIgICAgICAiIEVUQyAiIH0iCisgICAgIiAgZmllbGQgeyB0eXBlOlRZUEVfRE9VQkxFICBkZWZhdWx0X3ZhbHVlOlwibmFuXCIgICAgICAgIiBFVEMgIiB9IgorICAgICIgIGZpZWxkIHsgdHlwZTpUWVBFX1NUUklORyAgZGVmYXVsdF92YWx1ZTpcIjEzXFwwMDFcIiAgICIgRVRDICIgfSIKKyAgICAiICBmaWVsZCB7IHR5cGU6VFlQRV9TVFJJTkcgIGRlZmF1bHRfdmFsdWU6XCJhYmNcIiAgICAgICAiIEVUQyAiIH0iCisgICAgIiAgZmllbGQgeyB0eXBlOlRZUEVfQllURVMgICBkZWZhdWx0X3ZhbHVlOlwiMTRcXFxcMDAyXCIgIiBFVEMgIiB9IgorICAgICIgIGZpZWxkIHsgdHlwZTpUWVBFX0JZVEVTICAgZGVmYXVsdF92YWx1ZTpcImFiY1wiICAgICAgICIgRVRDICIgfSIKKyAgICAiICBmaWVsZCB7IHR5cGU6VFlQRV9CT09MICAgIGRlZmF1bHRfdmFsdWU6XCJ0cnVlXCIgICAgICAiIEVUQyAiIH0iCisgICAgIiAgZmllbGQgeyB0eXBlX25hbWU6XCJGb29cIiBkZWZhdWx0X3ZhbHVlOlwiRk9PXCIgICAgICAgIiBFVEMgIiB9IgorCisgICAgIiAgZmllbGQgeyIKKyAgICAiICAgIHR5cGU6VFlQRV9JTlQzMiAgIGRlZmF1bHRfdmFsdWU6XCIyMTQ3NDgzNjQ3XCIgICAgICAgICAgICIgRVRDCisgICAgIiAgfSIKKyAgICAiICBmaWVsZCB7IgorICAgICIgICAgdHlwZTpUWVBFX0lOVDMyICAgZGVmYXVsdF92YWx1ZTpcIi0yMTQ3NDgzNjQ4XCIgICAgICAgICAgIiBFVEMKKyAgICAiICB9IgorICAgICIgIGZpZWxkIHsiCisgICAgIiAgICB0eXBlOlRZUEVfVUlOVDMyICBkZWZhdWx0X3ZhbHVlOlwiNDI5NDk2NzI5NVwiICAgICAgICAgICAiIEVUQworICAgICIgIH0iCisgICAgIiAgZmllbGQgeyIKKyAgICAiICAgIHR5cGU6VFlQRV9JTlQ2NCAgIGRlZmF1bHRfdmFsdWU6XCI5MjIzMzcyMDM2ODU0Nzc1ODA3XCIgICIgRVRDCisgICAgIiAgfSIKKyAgICAiICBmaWVsZCB7IgorICAgICIgICAgdHlwZTpUWVBFX0lOVDY0ICAgZGVmYXVsdF92YWx1ZTpcIi05MjIzMzcyMDM2ODU0Nzc1ODA4XCIgIiBFVEMKKyAgICAiICB9IgorICAgICIgIGZpZWxkIHsiCisgICAgIiAgICB0eXBlOlRZUEVfVUlOVDY0ICBkZWZhdWx0X3ZhbHVlOlwiMTg0NDY3NDQwNzM3MDk1NTE2MTVcIiAiIEVUQworICAgICIgIH0iCisgICAgIiAgZmllbGQgeyIKKyAgICAiICAgIHR5cGU6VFlQRV9ET1VCTEUgIGRlZmF1bHRfdmFsdWU6XCI0Mzk4MVwiICAgICAgICAgICAgICAgICIgRVRDCisgICAgIiAgfSIKKyAgICAifSIpOworI3VuZGVmIEVUQworfQorCitURVNUX0YoUGFyc2VNZXNzYWdlVGVzdCwgRmllbGRKc29uTmFtZSkgeworICBFeHBlY3RQYXJzZXNUbygKKyAgICAibWVzc2FnZSBUZXN0TWVzc2FnZSB7XG4iCisgICAgIiAgb3B0aW9uYWwgc3RyaW5nIGZvbyA9IDEgW2pzb25fbmFtZSA9IFwiQHR5cGVcIl07XG4iCisgICAgIn1cbiIsCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiVGVzdE1lc3NhZ2VcIiIKKyAgICAiICBmaWVsZCB7XG4iCisgICAgIiAgICBuYW1lOiBcImZvb1wiIGxhYmVsOiBMQUJFTF9PUFRJT05BTCB0eXBlOiBUWVBFX1NUUklORyBudW1iZXI6IDEiCisgICAgIiAgICBqc29uX25hbWU6IFwiQHR5cGVcIlxuIgorICAgICIgIH1cbiIKKyAgICAifVxuIik7Cit9CisKK1RFU1RfRihQYXJzZU1lc3NhZ2VUZXN0LCBGaWVsZE9wdGlvbnMpIHsKKyAgRXhwZWN0UGFyc2VzVG8oCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIG9wdGlvbmFsIHN0cmluZyBmb28gPSAxXG4iCisgICAgIiAgICAgIFtjdHlwZT1DT1JELCAoZm9vKT03LCBmb28uKC5iYXIuYmF6KS5xdXgucXV1eC4oY29yZ2UpPS0zMywgXG4iCisgICAgIiAgICAgICAocXV1eCk9XCJ4XDA0MHlcIiwgKGJhei5xdXgpPWhleV07XG4iCisgICAgIn1cbiIsCisKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJUZXN0TWVzc2FnZVwiIgorICAgICIgIGZpZWxkIHsgbmFtZTogXCJmb29cIiBsYWJlbDogTEFCRUxfT1BUSU9OQUwgdHlwZTogVFlQRV9TVFJJTkcgbnVtYmVyOiAxIgorICAgICIgICAgICAgICAgb3B0aW9ucyB7IHVuaW50ZXJwcmV0ZWRfb3B0aW9uOiB7IG5hbWUgeyBuYW1lX3BhcnQ6IFwiY3R5cGVcIiAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzX2V4dGVuc2lvbjogZmFsc2UgfSAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWRlbnRpZmllcl92YWx1ZTogXCJDT1JEXCIgIH0iCisgICAgIiAgICAgICAgICAgICAgICAgICAgdW5pbnRlcnByZXRlZF9vcHRpb246IHsgbmFtZSB7IG5hbWVfcGFydDogXCJmb29cIiAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzX2V4dGVuc2lvbjogdHJ1ZSB9ICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3NpdGl2ZV9pbnRfdmFsdWU6IDcgIH0iCisgICAgIiAgICAgICAgICAgICAgICAgICAgdW5pbnRlcnByZXRlZF9vcHRpb246IHsgbmFtZSB7IG5hbWVfcGFydDogXCJmb29cIiAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzX2V4dGVuc2lvbjogZmFsc2UgfSAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSB7IG5hbWVfcGFydDogXCIuYmFyLmJhelwiIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc19leHRlbnNpb246IHRydWUgfSAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSB7IG5hbWVfcGFydDogXCJxdXhcIiAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzX2V4dGVuc2lvbjogZmFsc2UgfSAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSB7IG5hbWVfcGFydDogXCJxdXV4XCIgIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc19leHRlbnNpb246IGZhbHNlIH0gIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgeyBuYW1lX3BhcnQ6IFwiY29yZ2VcIiAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzX2V4dGVuc2lvbjogdHJ1ZSB9ICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZWdhdGl2ZV9pbnRfdmFsdWU6IC0zMyB9IgorICAgICIgICAgICAgICAgICAgICAgICAgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uOiB7IG5hbWUgeyBuYW1lX3BhcnQ6IFwicXV1eFwiICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNfZXh0ZW5zaW9uOiB0cnVlIH0gIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ192YWx1ZTogXCJ4IHlcIiB9IgorICAgICIgICAgICAgICAgICAgICAgICAgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uOiB7IG5hbWUgeyBuYW1lX3BhcnQ6IFwiYmF6LnF1eFwiICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNfZXh0ZW5zaW9uOiB0cnVlIH0gIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkZW50aWZpZXJfdmFsdWU6IFwiaGV5XCIgfSIKKyAgICAiICAgICAgICAgIH0iCisgICAgIiAgfSIKKyAgICAifSIpOworfQorCitURVNUX0YoUGFyc2VNZXNzYWdlVGVzdCwgT25lb2YpIHsKKyAgRXhwZWN0UGFyc2VzVG8oCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIG9uZW9mIGZvbyB7XG4iCisgICAgIiAgICBpbnQzMiBhID0gMTtcbiIKKyAgICAiICAgIHN0cmluZyBiID0gMjtcbiIKKyAgICAiICAgIFRlc3RNZXNzYWdlIGMgPSAzO1xuIgorICAgICIgICAgZ3JvdXAgRCA9IDQgeyBvcHRpb25hbCBpbnQzMiBpID0gNTsgfVxuIgorICAgICIgIH1cbiIKKyAgICAifVxuIiwKKworICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIlRlc3RNZXNzYWdlXCIiCisgICAgIiAgZmllbGQgeyBuYW1lOlwiYVwiIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiBudW1iZXI6MSAiCisgICAgIiAgICAgICAgICBvbmVvZl9pbmRleDowIH0iCisgICAgIiAgZmllbGQgeyBuYW1lOlwiYlwiIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9TVFJJTkcgbnVtYmVyOjIgIgorICAgICIgICAgICAgICAgb25lb2ZfaW5kZXg6MCB9IgorICAgICIgIGZpZWxkIHsgbmFtZTpcImNcIiBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlX25hbWU6XCJUZXN0TWVzc2FnZVwiICIKKyAgICAiICAgICAgICAgIG51bWJlcjozIG9uZW9mX2luZGV4OjAgfSIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJkXCIgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZTpUWVBFX0dST1VQICIKKyAgICAiICAgICAgICAgIHR5cGVfbmFtZTpcIkRcIiBudW1iZXI6NCBvbmVvZl9pbmRleDowIH0iCisgICAgIiAgb25lb2ZfZGVjbCB7IgorICAgICIgICAgbmFtZTogXCJmb29cIiIKKyAgICAiICB9IgorICAgICIgIG5lc3RlZF90eXBlIHsiCisgICAgIiAgICBuYW1lOiBcIkRcIiIKKyAgICAiICAgIGZpZWxkIHsgbmFtZTpcImlcIiBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgbnVtYmVyOjUgfSIKKyAgICAiICB9IgorICAgICJ9Iik7Cit9CisKK1RFU1RfRihQYXJzZU1lc3NhZ2VUZXN0LCBNdWx0aXBsZU9uZW9mcykgeworICBFeHBlY3RQYXJzZXNUbygKKyAgICAibWVzc2FnZSBUZXN0TWVzc2FnZSB7XG4iCisgICAgIiAgb25lb2YgZm9vIHtcbiIKKyAgICAiICAgIGludDMyIGEgPSAxO1xuIgorICAgICIgICAgc3RyaW5nIGIgPSAyO1xuIgorICAgICIgIH1cbiIKKyAgICAiICBvbmVvZiBiYXIge1xuIgorICAgICIgICAgaW50MzIgYyA9IDM7XG4iCisgICAgIiAgICBzdHJpbmcgZCA9IDQ7XG4iCisgICAgIiAgfVxuIgorICAgICJ9XG4iLAorCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiVGVzdE1lc3NhZ2VcIiIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJhXCIgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZTpUWVBFX0lOVDMyIG51bWJlcjoxICIKKyAgICAiICAgICAgICAgIG9uZW9mX2luZGV4OjAgfSIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJiXCIgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZTpUWVBFX1NUUklORyBudW1iZXI6MiAiCisgICAgIiAgICAgICAgICBvbmVvZl9pbmRleDowIH0iCisgICAgIiAgZmllbGQgeyBuYW1lOlwiY1wiIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiBudW1iZXI6MyAiCisgICAgIiAgICAgICAgICBvbmVvZl9pbmRleDoxIH0iCisgICAgIiAgZmllbGQgeyBuYW1lOlwiZFwiIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9TVFJJTkcgbnVtYmVyOjQgIgorICAgICIgICAgICAgICAgb25lb2ZfaW5kZXg6MSB9IgorICAgICIgIG9uZW9mX2RlY2wgeyIKKyAgICAiICAgIG5hbWU6IFwiZm9vXCIiCisgICAgIiAgfSIKKyAgICAiICBvbmVvZl9kZWNsIHsiCisgICAgIiAgICBuYW1lOiBcImJhclwiIgorICAgICIgIH0iCisgICAgIn0iKTsKK30KKworVEVTVF9GKFBhcnNlTWVzc2FnZVRlc3QsIE1hcHMpIHsKKyAgRXhwZWN0UGFyc2VzVG8oCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIG1hcDxpbnQzMiwgc3RyaW5nPiBwcmltaXRpdmVfdHlwZV9tYXAgPSAxO1xuIgorICAgICIgIG1hcDxLZXlUeXBlLCBWYWx1ZVR5cGU+IGNvbXBvc2l0ZV90eXBlX21hcCA9IDI7XG4iCisgICAgIn1cbiIsCisKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJUZXN0TWVzc2FnZVwiIgorICAgICIgIG5lc3RlZF90eXBlIHsiCisgICAgIiAgICBuYW1lOiBcIlByaW1pdGl2ZVR5cGVNYXBFbnRyeVwiIgorICAgICIgICAgZmllbGQgeyAiCisgICAgIiAgICAgICBuYW1lOiBcImtleVwiIG51bWJlcjogMSBsYWJlbDpMQUJFTF9PUFRJT05BTCIKKyAgICAiICAgICAgIHR5cGU6VFlQRV9JTlQzMiIKKyAgICAiICAgIH0iCisgICAgIiAgICBmaWVsZCB7ICIKKyAgICAiICAgICAgIG5hbWU6IFwidmFsdWVcIiBudW1iZXI6IDIgbGFiZWw6TEFCRUxfT1BUSU9OQUwiCisgICAgIiAgICAgICB0eXBlOlRZUEVfU1RSSU5HIgorICAgICIgICAgfSIKKyAgICAiICAgIG9wdGlvbnMgeyBtYXBfZW50cnk6IHRydWUgfSIKKyAgICAiICB9IgorICAgICIgIG5lc3RlZF90eXBlIHsiCisgICAgIiAgICBuYW1lOiBcIkNvbXBvc2l0ZVR5cGVNYXBFbnRyeVwiIgorICAgICIgICAgZmllbGQgeyAiCisgICAgIiAgICAgICBuYW1lOiBcImtleVwiIG51bWJlcjogMSBsYWJlbDpMQUJFTF9PUFRJT05BTCIKKyAgICAiICAgICAgIHR5cGVfbmFtZTogXCJLZXlUeXBlXCIiCisgICAgIiAgICB9IgorICAgICIgICAgZmllbGQgeyAiCisgICAgIiAgICAgICBuYW1lOiBcInZhbHVlXCIgbnVtYmVyOiAyIGxhYmVsOkxBQkVMX09QVElPTkFMIgorICAgICIgICAgICAgdHlwZV9uYW1lOiBcIlZhbHVlVHlwZVwiIgorICAgICIgICAgfSIKKyAgICAiICAgIG9wdGlvbnMgeyBtYXBfZW50cnk6IHRydWUgfSIKKyAgICAiICB9IgorICAgICIgIGZpZWxkIHsiCisgICAgIiAgICBuYW1lOiBcInByaW1pdGl2ZV90eXBlX21hcFwiIgorICAgICIgICAgbGFiZWw6IExBQkVMX1JFUEVBVEVEIgorICAgICIgICAgdHlwZV9uYW1lOiBcIlByaW1pdGl2ZVR5cGVNYXBFbnRyeVwiIgorICAgICIgICAgbnVtYmVyOiAxIgorICAgICIgIH0iCisgICAgIiAgZmllbGQgeyIKKyAgICAiICAgIG5hbWU6IFwiY29tcG9zaXRlX3R5cGVfbWFwXCIiCisgICAgIiAgICBsYWJlbDogTEFCRUxfUkVQRUFURUQiCisgICAgIiAgICB0eXBlX25hbWU6IFwiQ29tcG9zaXRlVHlwZU1hcEVudHJ5XCIiCisgICAgIiAgICBudW1iZXI6IDIiCisgICAgIiAgfSIKKyAgICAifSIpOworfQorCitURVNUX0YoUGFyc2VNZXNzYWdlVGVzdCwgR3JvdXApIHsKKyAgRXhwZWN0UGFyc2VzVG8oCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIG9wdGlvbmFsIGdyb3VwIFRlc3RHcm91cCA9IDEge307XG4iCisgICAgIn1cbiIsCisKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJUZXN0TWVzc2FnZVwiIgorICAgICIgIG5lc3RlZF90eXBlIHsgbmFtZTogXCJUZXN0R3JvdXBcIiB9IgorICAgICIgIGZpZWxkIHsgbmFtZTpcInRlc3Rncm91cFwiIGxhYmVsOkxBQkVMX09QVElPTkFMIG51bWJlcjoxIgorICAgICIgICAgICAgICAgdHlwZTpUWVBFX0dST1VQIHR5cGVfbmFtZTogXCJUZXN0R3JvdXBcIiB9IgorICAgICJ9Iik7Cit9CisKK1RFU1RfRihQYXJzZU1lc3NhZ2VUZXN0LCBOZXN0ZWRNZXNzYWdlKSB7CisgIEV4cGVjdFBhcnNlc1RvKAorICAgICJtZXNzYWdlIFRlc3RNZXNzYWdlIHtcbiIKKyAgICAiICBtZXNzYWdlIE5lc3RlZCB7fVxuIgorICAgICIgIG9wdGlvbmFsIE5lc3RlZCB0ZXN0X25lc3RlZCA9IDE7XG4iCisgICAgIn1cbiIsCisKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJUZXN0TWVzc2FnZVwiIgorICAgICIgIG5lc3RlZF90eXBlIHsgbmFtZTogXCJOZXN0ZWRcIiB9IgorICAgICIgIGZpZWxkIHsgbmFtZTpcInRlc3RfbmVzdGVkXCIgbGFiZWw6TEFCRUxfT1BUSU9OQUwgbnVtYmVyOjEiCisgICAgIiAgICAgICAgICB0eXBlX25hbWU6IFwiTmVzdGVkXCIgfSIKKyAgICAifSIpOworfQorCitURVNUX0YoUGFyc2VNZXNzYWdlVGVzdCwgTmVzdGVkRW51bSkgeworICBFeHBlY3RQYXJzZXNUbygKKyAgICAibWVzc2FnZSBUZXN0TWVzc2FnZSB7XG4iCisgICAgIiAgZW51bSBOZXN0ZWRFbnVtIHt9XG4iCisgICAgIiAgb3B0aW9uYWwgTmVzdGVkRW51bSB0ZXN0X2VudW0gPSAxO1xuIgorICAgICJ9XG4iLAorCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiVGVzdE1lc3NhZ2VcIiIKKyAgICAiICBlbnVtX3R5cGUgeyBuYW1lOiBcIk5lc3RlZEVudW1cIiB9IgorICAgICIgIGZpZWxkIHsgbmFtZTpcInRlc3RfZW51bVwiIGxhYmVsOkxBQkVMX09QVElPTkFMIG51bWJlcjoxIgorICAgICIgICAgICAgICAgdHlwZV9uYW1lOiBcIk5lc3RlZEVudW1cIiB9IgorICAgICJ9Iik7Cit9CisKK1RFU1RfRihQYXJzZU1lc3NhZ2VUZXN0LCBSZXNlcnZlZFJhbmdlKSB7CisgIEV4cGVjdFBhcnNlc1RvKAorICAgICJtZXNzYWdlIFRlc3RNZXNzYWdlIHtcbiIKKyAgICAiICByZXF1aXJlZCBpbnQzMiBmb28gPSAxO1xuIgorICAgICIgIHJlc2VydmVkIDIsIDE1LCA5IHRvIDExLCAzO1xuIgorICAgICJ9XG4iLAorCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiVGVzdE1lc3NhZ2VcIiIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJmb29cIiBsYWJlbDpMQUJFTF9SRVFVSVJFRCB0eXBlOlRZUEVfSU5UMzIgbnVtYmVyOjEgfSIKKyAgICAiICByZXNlcnZlZF9yYW5nZSB7IHN0YXJ0OjIgICBlbmQ6MyAgICAgICAgIH0iCisgICAgIiAgcmVzZXJ2ZWRfcmFuZ2UgeyBzdGFydDoxNSAgZW5kOjE2ICAgICAgICB9IgorICAgICIgIHJlc2VydmVkX3JhbmdlIHsgc3RhcnQ6OSAgIGVuZDoxMiAgICAgICAgfSIKKyAgICAiICByZXNlcnZlZF9yYW5nZSB7IHN0YXJ0OjMgICBlbmQ6NCAgICAgICAgIH0iCisgICAgIn0iKTsKK30KKworVEVTVF9GKFBhcnNlTWVzc2FnZVRlc3QsIFJlc2VydmVkTmFtZXMpIHsKKyAgRXhwZWN0UGFyc2VzVG8oCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIHJlc2VydmVkIFwiZm9vXCIsIFwiYmFyXCI7XG4iCisgICAgIn1cbiIsCisKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJUZXN0TWVzc2FnZVwiIgorICAgICIgIHJlc2VydmVkX25hbWU6IFwiZm9vXCIiCisgICAgIiAgcmVzZXJ2ZWRfbmFtZTogXCJiYXJcIiIKKyAgICAifSIpOworfQorCitURVNUX0YoUGFyc2VNZXNzYWdlVGVzdCwgRXh0ZW5zaW9uUmFuZ2UpIHsKKyAgRXhwZWN0UGFyc2VzVG8oCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIGV4dGVuc2lvbnMgMTAgdG8gMTk7XG4iCisgICAgIiAgZXh0ZW5zaW9ucyAzMCB0byBtYXg7XG4iCisgICAgIn1cbiIsCisKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJUZXN0TWVzc2FnZVwiIgorICAgICIgIGV4dGVuc2lvbl9yYW5nZSB7IHN0YXJ0OjEwIGVuZDoyMCAgICAgICAgfSIKKyAgICAiICBleHRlbnNpb25fcmFuZ2UgeyBzdGFydDozMCBlbmQ6NTM2ODcwOTEyIH0iCisgICAgIn0iKTsKK30KKworVEVTVF9GKFBhcnNlTWVzc2FnZVRlc3QsIENvbXBvdW5kRXh0ZW5zaW9uUmFuZ2UpIHsKKyAgRXhwZWN0UGFyc2VzVG8oCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIGV4dGVuc2lvbnMgMiwgMTUsIDkgdG8gMTEsIDEwMCB0byBtYXgsIDM7XG4iCisgICAgIn1cbiIsCisKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJUZXN0TWVzc2FnZVwiIgorICAgICIgIGV4dGVuc2lvbl9yYW5nZSB7IHN0YXJ0OjIgICBlbmQ6MyAgICAgICAgIH0iCisgICAgIiAgZXh0ZW5zaW9uX3JhbmdlIHsgc3RhcnQ6MTUgIGVuZDoxNiAgICAgICAgfSIKKyAgICAiICBleHRlbnNpb25fcmFuZ2UgeyBzdGFydDo5ICAgZW5kOjEyICAgICAgICB9IgorICAgICIgIGV4dGVuc2lvbl9yYW5nZSB7IHN0YXJ0OjEwMCBlbmQ6NTM2ODcwOTEyIH0iCisgICAgIiAgZXh0ZW5zaW9uX3JhbmdlIHsgc3RhcnQ6MyAgIGVuZDo0ICAgICAgICAgfSIKKyAgICAifSIpOworfQorCitURVNUX0YoUGFyc2VNZXNzYWdlVGVzdCwgTGFyZ2VyTWF4Rm9yTWVzc2FnZVNldFdpcmVGb3JtYXRNZXNzYWdlcykgeworICAvLyBNZXNzYWdlcyB1c2luZyB0aGUgbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQgb3B0aW9uIGNhbiBhY2NlcHQgbGFyZ2VyCisgIC8vIGV4dGVuc2lvbiBudW1iZXJzLCBhcyB0aGUgbnVtYmVycyBhcmUgbm90IGVuY29kZWQgYXMgaW50MzIgZmllbGQgdmFsdWVzCisgIC8vIHJhdGhlciB0aGFuIHRhZ3MuCisgIEV4cGVjdFBhcnNlc1RvKAorICAgICJtZXNzYWdlIFRlc3RNZXNzYWdlIHtcbiIKKyAgICAiICBleHRlbnNpb25zIDQgdG8gbWF4O1xuIgorICAgICIgIG9wdGlvbiBtZXNzYWdlX3NldF93aXJlX2Zvcm1hdCA9IHRydWU7XG4iCisgICAgIn1cbiIsCisKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJUZXN0TWVzc2FnZVwiIgorICAgICIgICAgZXh0ZW5zaW9uX3JhbmdlIHsgc3RhcnQ6NCBlbmQ6IDB4N2ZmZmZmZmYgfSIKKyAgICAiICBvcHRpb25zIHtcbiIKKyAgICAiICAgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uIHsgXG4iCisgICAgIiAgICAgIG5hbWUge1xuIgorICAgICIgICAgICAgIG5hbWVfcGFydDogXCJtZXNzYWdlX3NldF93aXJlX2Zvcm1hdFwiXG4iCisgICAgIiAgICAgICAgaXNfZXh0ZW5zaW9uOiBmYWxzZVxuIgorICAgICIgICAgICB9XG4iCisgICAgIiAgICAgIGlkZW50aWZpZXJfdmFsdWU6IFwidHJ1ZVwiXG4iCisgICAgIiAgICB9XG4iCisgICAgIiAgfVxuIgorICAgICJ9Iik7Cit9CisKK1RFU1RfRihQYXJzZU1lc3NhZ2VUZXN0LCBFeHRlbnNpb25zKSB7CisgIEV4cGVjdFBhcnNlc1RvKAorICAgICJleHRlbmQgRXh0ZW5kZWUxIHsgb3B0aW9uYWwgaW50MzIgZm9vID0gMTI7IH1cbiIKKyAgICAiZXh0ZW5kIEV4dGVuZGVlMiB7IHJlcGVhdGVkIFRlc3RNZXNzYWdlIGJhciA9IDIyOyB9XG4iLAorCisgICAgImV4dGVuc2lvbiB7IG5hbWU6XCJmb29cIiBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgbnVtYmVyOjEyIgorICAgICIgICAgICAgICAgICBleHRlbmRlZTogXCJFeHRlbmRlZTFcIiB9ICIKKyAgICAiZXh0ZW5zaW9uIHsgbmFtZTpcImJhclwiIGxhYmVsOkxBQkVMX1JFUEVBVEVEIG51bWJlcjoyMiIKKyAgICAiICAgICAgICAgICAgdHlwZV9uYW1lOlwiVGVzdE1lc3NhZ2VcIiBleHRlbmRlZTogXCJFeHRlbmRlZTJcIiB9Iik7Cit9CisKK1RFU1RfRihQYXJzZU1lc3NhZ2VUZXN0LCBFeHRlbnNpb25zSW5NZXNzYWdlU2NvcGUpIHsKKyAgRXhwZWN0UGFyc2VzVG8oCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIGV4dGVuZCBFeHRlbmRlZTEgeyBvcHRpb25hbCBpbnQzMiBmb28gPSAxMjsgfVxuIgorICAgICIgIGV4dGVuZCBFeHRlbmRlZTIgeyByZXBlYXRlZCBUZXN0TWVzc2FnZSBiYXIgPSAyMjsgfVxuIgorICAgICJ9XG4iLAorCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiVGVzdE1lc3NhZ2VcIiIKKyAgICAiICBleHRlbnNpb24geyBuYW1lOlwiZm9vXCIgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZTpUWVBFX0lOVDMyIG51bWJlcjoxMiIKKyAgICAiICAgICAgICAgICAgICBleHRlbmRlZTogXCJFeHRlbmRlZTFcIiB9IgorICAgICIgIGV4dGVuc2lvbiB7IG5hbWU6XCJiYXJcIiBsYWJlbDpMQUJFTF9SRVBFQVRFRCBudW1iZXI6MjIiCisgICAgIiAgICAgICAgICAgICAgdHlwZV9uYW1lOlwiVGVzdE1lc3NhZ2VcIiBleHRlbmRlZTogXCJFeHRlbmRlZTJcIiB9IgorICAgICJ9Iik7Cit9CisKK1RFU1RfRihQYXJzZU1lc3NhZ2VUZXN0LCBNdWx0aXBsZUV4dGVuc2lvbnNPbmVFeHRlbmRlZSkgeworICBFeHBlY3RQYXJzZXNUbygKKyAgICAiZXh0ZW5kIEV4dGVuZGVlMSB7XG4iCisgICAgIiAgb3B0aW9uYWwgaW50MzIgZm9vID0gMTI7XG4iCisgICAgIiAgcmVwZWF0ZWQgVGVzdE1lc3NhZ2UgYmFyID0gMjI7XG4iCisgICAgIn1cbiIsCisKKyAgICAiZXh0ZW5zaW9uIHsgbmFtZTpcImZvb1wiIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiBudW1iZXI6MTIiCisgICAgIiAgICAgICAgICAgIGV4dGVuZGVlOiBcIkV4dGVuZGVlMVwiIH0gIgorICAgICJleHRlbnNpb24geyBuYW1lOlwiYmFyXCIgbGFiZWw6TEFCRUxfUkVQRUFURUQgbnVtYmVyOjIyIgorICAgICIgICAgICAgICAgICB0eXBlX25hbWU6XCJUZXN0TWVzc2FnZVwiIGV4dGVuZGVlOiBcIkV4dGVuZGVlMVwiIH0iKTsKK30KKworVEVTVF9GKFBhcnNlTWVzc2FnZVRlc3QsIE9wdGlvbmFsTGFiZWxQcm90bzMpIHsKKyAgRXhwZWN0UGFyc2VzVG8oCisgICAgInN5bnRheCA9IFwicHJvdG8zXCI7XG4iCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIGludDMyIGZvbyA9IDE7XG4iCisgICAgIn1cbiIsCisKKyAgICAic3ludGF4OiBcInByb3RvM1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJUZXN0TWVzc2FnZVwiIgorICAgICIgIGZpZWxkIHsgbmFtZTpcImZvb1wiIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiBudW1iZXI6MSB9IH0iKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCit0eXBlZGVmIFBhcnNlclRlc3QgUGFyc2VFbnVtVGVzdDsKKworVEVTVF9GKFBhcnNlRW51bVRlc3QsIFNpbXBsZUVudW0pIHsKKyAgRXhwZWN0UGFyc2VzVG8oCisgICAgImVudW0gVGVzdEVudW0ge1xuIgorICAgICIgIEZPTyA9IDA7XG4iCisgICAgIn1cbiIsCisKKyAgICAiZW51bV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJUZXN0RW51bVwiIgorICAgICIgIHZhbHVlIHsgbmFtZTpcIkZPT1wiIG51bWJlcjowIH0iCisgICAgIn0iKTsKK30KKworVEVTVF9GKFBhcnNlRW51bVRlc3QsIFZhbHVlcykgeworICBFeHBlY3RQYXJzZXNUbygKKyAgICAiZW51bSBUZXN0RW51bSB7XG4iCisgICAgIiAgRk9PID0gMTM7XG4iCisgICAgIiAgQkFSID0gLTEwO1xuIgorICAgICIgIEJBWiA9IDUwMDtcbiIKKyAgICAiICBIRVhfTUFYID0gMHg3RkZGRkZGRjtcbiIKKyAgICAiICBIRVhfTUlOID0gLTB4ODAwMDAwMDA7XG4iCisgICAgIiAgSU5UX01BWCA9IDIxNDc0ODM2NDc7XG4iCisgICAgIiAgSU5UX01JTiA9IC0yMTQ3NDgzNjQ4O1xuIgorICAgICJ9XG4iLAorCisgICAgImVudW1fdHlwZSB7IgorICAgICIgIG5hbWU6IFwiVGVzdEVudW1cIiIKKyAgICAiICB2YWx1ZSB7IG5hbWU6XCJGT09cIiBudW1iZXI6MTMgfSIKKyAgICAiICB2YWx1ZSB7IG5hbWU6XCJCQVJcIiBudW1iZXI6LTEwIH0iCisgICAgIiAgdmFsdWUgeyBuYW1lOlwiQkFaXCIgbnVtYmVyOjUwMCB9IgorICAgICIgIHZhbHVlIHsgbmFtZTpcIkhFWF9NQVhcIiBudW1iZXI6MjE0NzQ4MzY0NyB9IgorICAgICIgIHZhbHVlIHsgbmFtZTpcIkhFWF9NSU5cIiBudW1iZXI6LTIxNDc0ODM2NDggfSIKKyAgICAiICB2YWx1ZSB7IG5hbWU6XCJJTlRfTUFYXCIgbnVtYmVyOjIxNDc0ODM2NDcgfSIKKyAgICAiICB2YWx1ZSB7IG5hbWU6XCJJTlRfTUlOXCIgbnVtYmVyOi0yMTQ3NDgzNjQ4IH0iCisgICAgIn0iKTsKK30KKworVEVTVF9GKFBhcnNlRW51bVRlc3QsIFZhbHVlT3B0aW9ucykgeworICBFeHBlY3RQYXJzZXNUbygKKyAgICAiZW51bSBUZXN0RW51bSB7XG4iCisgICAgIiAgRk9PID0gMTM7XG4iCisgICAgIiAgQkFSID0gLTEwIFsgKHNvbWV0aGluZy50ZXh0KSA9ICdhYmMnIF07XG4iCisgICAgIiAgQkFaID0gNTAwIFsgKHNvbWV0aGluZy50ZXh0KSA9ICdkZWYnLCBvdGhlciA9IDEgXTtcbiIKKyAgICAifVxuIiwKKworICAgICJlbnVtX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIlRlc3RFbnVtXCIiCisgICAgIiAgdmFsdWUgeyBuYW1lOiBcIkZPT1wiIG51bWJlcjogMTMgfSIKKyAgICAiICB2YWx1ZSB7IG5hbWU6IFwiQkFSXCIgbnVtYmVyOiAtMTAgIgorICAgICIgICAgb3B0aW9ucyB7ICIKKyAgICAiICAgICAgdW5pbnRlcnByZXRlZF9vcHRpb24geyAiCisgICAgIiAgICAgICAgbmFtZSB7IG5hbWVfcGFydDogXCJzb21ldGhpbmcudGV4dFwiIGlzX2V4dGVuc2lvbjogdHJ1ZSB9ICIKKyAgICAiICAgICAgICBzdHJpbmdfdmFsdWU6IFwiYWJjXCIgIgorICAgICIgICAgICB9ICIKKyAgICAiICAgIH0gIgorICAgICIgIH0gIgorICAgICIgIHZhbHVlIHsgbmFtZTogXCJCQVpcIiBudW1iZXI6IDUwMCAiCisgICAgIiAgICBvcHRpb25zIHsgIgorICAgICIgICAgICB1bmludGVycHJldGVkX29wdGlvbiB7ICIKKyAgICAiICAgICAgICBuYW1lIHsgbmFtZV9wYXJ0OiBcInNvbWV0aGluZy50ZXh0XCIgaXNfZXh0ZW5zaW9uOiB0cnVlIH0gIgorICAgICIgICAgICAgIHN0cmluZ192YWx1ZTogXCJkZWZcIiAiCisgICAgIiAgICAgIH0gIgorICAgICIgICAgICB1bmludGVycHJldGVkX29wdGlvbiB7ICIKKyAgICAiICAgICAgICBuYW1lIHsgbmFtZV9wYXJ0OiBcIm90aGVyXCIgaXNfZXh0ZW5zaW9uOiBmYWxzZSB9ICIKKyAgICAiICAgICAgICBwb3NpdGl2ZV9pbnRfdmFsdWU6IDEgIgorICAgICIgICAgICB9ICIKKyAgICAiICAgIH0gIgorICAgICIgIH0gIgorICAgICJ9Iik7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKwordHlwZWRlZiBQYXJzZXJUZXN0IFBhcnNlU2VydmljZVRlc3Q7CisKK1RFU1RfRihQYXJzZVNlcnZpY2VUZXN0LCBTaW1wbGVTZXJ2aWNlKSB7CisgIEV4cGVjdFBhcnNlc1RvKAorICAgICJzZXJ2aWNlIFRlc3RTZXJ2aWNlIHtcbiIKKyAgICAiICBycGMgRm9vKEluKSByZXR1cm5zIChPdXQpO1xuIgorICAgICJ9XG4iLAorCisgICAgInNlcnZpY2UgeyIKKyAgICAiICBuYW1lOiBcIlRlc3RTZXJ2aWNlXCIiCisgICAgIiAgbWV0aG9kIHsgbmFtZTpcIkZvb1wiIGlucHV0X3R5cGU6XCJJblwiIG91dHB1dF90eXBlOlwiT3V0XCIgfSIKKyAgICAifSIpOworfQorCitURVNUX0YoUGFyc2VTZXJ2aWNlVGVzdCwgTWV0aG9kc0FuZFN0cmVhbXMpIHsKKyAgRXhwZWN0UGFyc2VzVG8oCisgICAgInNlcnZpY2UgVGVzdFNlcnZpY2Uge1xuIgorICAgICIgIHJwYyBGb28oSW4xKSByZXR1cm5zIChPdXQxKTtcbiIKKyAgICAiICBycGMgQmFyKEluMikgcmV0dXJucyAoT3V0Mik7XG4iCisgICAgIiAgcnBjIEJheihJbjMpIHJldHVybnMgKE91dDMpO1xuIgorICAgICJ9XG4iLAorCisgICAgInNlcnZpY2UgeyIKKyAgICAiICBuYW1lOiBcIlRlc3RTZXJ2aWNlXCIiCisgICAgIiAgbWV0aG9kIHsgbmFtZTpcIkZvb1wiIGlucHV0X3R5cGU6XCJJbjFcIiBvdXRwdXRfdHlwZTpcIk91dDFcIiB9IgorICAgICIgIG1ldGhvZCB7IG5hbWU6XCJCYXJcIiBpbnB1dF90eXBlOlwiSW4yXCIgb3V0cHV0X3R5cGU6XCJPdXQyXCIgfSIKKyAgICAiICBtZXRob2QgeyBuYW1lOlwiQmF6XCIgaW5wdXRfdHlwZTpcIkluM1wiIG91dHB1dF90eXBlOlwiT3V0M1wiIH0iCisgICAgIn0iKTsKK30KKworCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKy8vIGltcG9ydHMgYW5kIHBhY2thZ2VzCisKK3R5cGVkZWYgUGFyc2VyVGVzdCBQYXJzZU1pc2NUZXN0OworCitURVNUX0YoUGFyc2VNaXNjVGVzdCwgUGFyc2VJbXBvcnQpIHsKKyAgRXhwZWN0UGFyc2VzVG8oCisgICAgImltcG9ydCBcImZvby9iYXIvYmF6LnByb3RvXCI7XG4iLAorICAgICJkZXBlbmRlbmN5OiBcImZvby9iYXIvYmF6LnByb3RvXCIiKTsKK30KKworVEVTVF9GKFBhcnNlTWlzY1Rlc3QsIFBhcnNlTXVsdGlwbGVJbXBvcnRzKSB7CisgIEV4cGVjdFBhcnNlc1RvKAorICAgICJpbXBvcnQgXCJmb28ucHJvdG9cIjtcbiIKKyAgICAiaW1wb3J0IFwiYmFyLnByb3RvXCI7XG4iCisgICAgImltcG9ydCBcImJhei5wcm90b1wiO1xuIiwKKyAgICAiZGVwZW5kZW5jeTogXCJmb28ucHJvdG9cIiIKKyAgICAiZGVwZW5kZW5jeTogXCJiYXIucHJvdG9cIiIKKyAgICAiZGVwZW5kZW5jeTogXCJiYXoucHJvdG9cIiIpOworfQorCitURVNUX0YoUGFyc2VNaXNjVGVzdCwgUGFyc2VQdWJsaWNJbXBvcnRzKSB7CisgIEV4cGVjdFBhcnNlc1RvKAorICAgICJpbXBvcnQgXCJmb28ucHJvdG9cIjtcbiIKKyAgICAiaW1wb3J0IHB1YmxpYyBcImJhci5wcm90b1wiO1xuIgorICAgICJpbXBvcnQgXCJiYXoucHJvdG9cIjtcbiIKKyAgICAiaW1wb3J0IHB1YmxpYyBcInF1eC5wcm90b1wiO1xuIiwKKyAgICAiZGVwZW5kZW5jeTogXCJmb28ucHJvdG9cIiIKKyAgICAiZGVwZW5kZW5jeTogXCJiYXIucHJvdG9cIiIKKyAgICAiZGVwZW5kZW5jeTogXCJiYXoucHJvdG9cIiIKKyAgICAiZGVwZW5kZW5jeTogXCJxdXgucHJvdG9cIiIKKyAgICAicHVibGljX2RlcGVuZGVuY3k6IDEgIgorICAgICJwdWJsaWNfZGVwZW5kZW5jeTogMyAiKTsKK30KKworVEVTVF9GKFBhcnNlTWlzY1Rlc3QsIFBhcnNlUGFja2FnZSkgeworICBFeHBlY3RQYXJzZXNUbygKKyAgICAicGFja2FnZSBmb28uYmFyLmJhejtcbiIsCisgICAgInBhY2thZ2U6IFwiZm9vLmJhci5iYXpcIiIpOworfQorCitURVNUX0YoUGFyc2VNaXNjVGVzdCwgUGFyc2VQYWNrYWdlV2l0aFNwYWNlcykgeworICBFeHBlY3RQYXJzZXNUbygKKyAgICAicGFja2FnZSBmb28gICAuICAgYmFyLiAgXG4iCisgICAgIiAgYmF6O1xuIiwKKyAgICAicGFja2FnZTogXCJmb28uYmFyLmJhelwiIik7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKy8vIG9wdGlvbnMKKworVEVTVF9GKFBhcnNlTWlzY1Rlc3QsIFBhcnNlRmlsZU9wdGlvbnMpIHsKKyAgRXhwZWN0UGFyc2VzVG8oCisgICAgIm9wdGlvbiBqYXZhX3BhY2thZ2UgPSBcImNvbS5nb29nbGUuZm9vXCI7XG4iCisgICAgIm9wdGlvbiBvcHRpbWl6ZV9mb3IgPSBDT0RFX1NJWkU7IiwKKworICAgICJvcHRpb25zIHsiCisgICAgInVuaW50ZXJwcmV0ZWRfb3B0aW9uIHsgbmFtZSB7IG5hbWVfcGFydDogXCJqYXZhX3BhY2thZ2VcIiAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzX2V4dGVuc2lvbjogZmFsc2UgfSIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmdfdmFsdWU6IFwiY29tLmdvb2dsZS5mb29cIn0gIgorICAgICJ1bmludGVycHJldGVkX29wdGlvbiB7IG5hbWUgeyBuYW1lX3BhcnQ6IFwib3B0aW1pemVfZm9yXCIgIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc19leHRlbnNpb246IGZhbHNlIH0iCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgaWRlbnRpZmllcl92YWx1ZTogXCJDT0RFX1NJWkVcIiB9ICIKKyAgICAifSIpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisvLyBFcnJvciB0ZXN0cworLy8KKy8vIFRoZXJlIGFyZSBhIHZlcnkgbGFyZ2UgbnVtYmVyIG9mIHBvc3NpYmxlIGVycm9ycyB0aGF0IHRoZSBwYXJzZXIgY291bGQKKy8vIHJlcG9ydCwgc28gaXQncyBpbmZlYXNpYmxlIHRvIHRlc3QgZXZlcnkgc2luZ2xlIG9uZSBvZiB0aGVtLiAgSW5zdGVhZCwKKy8vIHdlIHRlc3QgZWFjaCB1bmlxdWUgY2FsbCB0byBBZGRFcnJvcigpIGluIHBhcnNlci5oLiAgVGhpcyBkb2VzIG5vdCBtZWFuCisvLyB3ZSBhcmUgdGVzdGluZyBldmVyeSBwb3NzaWJsZSBlcnJvciB0aGF0IFBhcnNlciBjYW4gZ2VuZXJhdGUgYmVjYXVzZQorLy8gZWFjaCB2YXJpYW50IG9mIHRoZSBDb25zdW1lKCkgaGVscGVyIG9ubHkgY291bnRzIGFzIG9uZSB1bmlxdWUgY2FsbCB0bworLy8gQWRkRXJyb3IoKS4KKwordHlwZWRlZiBQYXJzZXJUZXN0IFBhcnNlRXJyb3JUZXN0OworCitURVNUX0YoUGFyc2VFcnJvclRlc3QsIE1pc3NpbmdTeW50YXhJZGVudGlmaWVyKSB7CisgIHJlcXVpcmVfc3ludGF4X2lkZW50aWZpZXJfID0gdHJ1ZTsKKyAgRXhwZWN0SGFzRWFybHlFeGl0RXJyb3JzKCJtZXNzYWdlIFRlc3RNZXNzYWdlIHt9IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICIwOjA6IEZpbGUgbXVzdCBiZWdpbiB3aXRoIGEgc3ludGF4IHN0YXRlbWVudCwgZS5nLiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAiJ3N5bnRheCA9IFwicHJvdG8yXCI7Jy5cbiIpOworICBFWFBFQ1RfRVEoIiIsIHBhcnNlcl8tPkdldFN5bnRheElkZW50aWZpZXIoKSk7Cit9CisKK1RFU1RfRihQYXJzZUVycm9yVGVzdCwgVW5rbm93blN5bnRheElkZW50aWZpZXIpIHsKKyAgRXhwZWN0SGFzRWFybHlFeGl0RXJyb3JzKAorICAgICJzeW50YXggPSBcIm5vX3N1Y2hfc3ludGF4XCI7IiwKKyAgICAiMDo5OiBVbnJlY29nbml6ZWQgc3ludGF4IGlkZW50aWZpZXIgXCJub19zdWNoX3N5bnRheFwiLiAgVGhpcyBwYXJzZXIgIgorICAgICAgIm9ubHkgcmVjb2duaXplcyBcInByb3RvMlwiIGFuZCBcInByb3RvM1wiLlxuIik7CisgIEVYUEVDVF9FUSgibm9fc3VjaF9zeW50YXgiLCBwYXJzZXJfLT5HZXRTeW50YXhJZGVudGlmaWVyKCkpOworfQorCitURVNUX0YoUGFyc2VFcnJvclRlc3QsIFNpbXBsZVN5bnRheEVycm9yKSB7CisgIEV4cGVjdEhhc0Vycm9ycygKKyAgICAibWVzc2FnZSBUZXN0TWVzc2FnZSBAIyQgeyBibGFoIH0iLAorICAgICIwOjIwOiBFeHBlY3RlZCBcIntcIi5cbiIpOworICBFWFBFQ1RfRVEoInByb3RvMiIsIHBhcnNlcl8tPkdldFN5bnRheElkZW50aWZpZXIoKSk7Cit9CisKK1RFU1RfRihQYXJzZUVycm9yVGVzdCwgRXhwZWN0ZWRUb3BMZXZlbCkgeworICBFeHBlY3RIYXNFcnJvcnMoCisgICAgImJsYWg7IiwKKyAgICAiMDowOiBFeHBlY3RlZCB0b3AtbGV2ZWwgc3RhdGVtZW50IChlLmcuIFwibWVzc2FnZVwiKS5cbiIpOworfQorCitURVNUX0YoUGFyc2VFcnJvclRlc3QsIFVubWF0Y2hlZENsb3NlQnJhY2UpIHsKKyAgLy8gVGhpcyB1c2VkIHRvIGNhdXNlIGFuIGluZmluaXRlIGxvb3AuICBEb2guCisgIEV4cGVjdEhhc0Vycm9ycygKKyAgICAifSIsCisgICAgIjA6MDogRXhwZWN0ZWQgdG9wLWxldmVsIHN0YXRlbWVudCAoZS5nLiBcIm1lc3NhZ2VcIikuXG4iCisgICAgIjA6MDogVW5tYXRjaGVkIFwifVwiLlxuIik7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIE1lc3NhZ2UgZXJyb3JzCisKK1RFU1RfRihQYXJzZUVycm9yVGVzdCwgTWVzc2FnZU1pc3NpbmdOYW1lKSB7CisgIEV4cGVjdEhhc0Vycm9ycygKKyAgICAibWVzc2FnZSB7fSIsCisgICAgIjA6ODogRXhwZWN0ZWQgbWVzc2FnZSBuYW1lLlxuIik7Cit9CisKK1RFU1RfRihQYXJzZUVycm9yVGVzdCwgTWVzc2FnZU1pc3NpbmdCb2R5KSB7CisgIEV4cGVjdEhhc0Vycm9ycygKKyAgICAibWVzc2FnZSBUZXN0TWVzc2FnZTsiLAorICAgICIwOjE5OiBFeHBlY3RlZCBcIntcIi5cbiIpOworfQorCitURVNUX0YoUGFyc2VFcnJvclRlc3QsIEVvZkluTWVzc2FnZSkgeworICBFeHBlY3RIYXNFcnJvcnMoCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2UgeyIsCisgICAgIjA6MjE6IFJlYWNoZWQgZW5kIG9mIGlucHV0IGluIG1lc3NhZ2UgZGVmaW5pdGlvbiAobWlzc2luZyAnfScpLlxuIik7Cit9CisKK1RFU1RfRihQYXJzZUVycm9yVGVzdCwgTWlzc2luZ0ZpZWxkTnVtYmVyKSB7CisgIEV4cGVjdEhhc0Vycm9ycygKKyAgICAibWVzc2FnZSBUZXN0TWVzc2FnZSB7XG4iCisgICAgIiAgb3B0aW9uYWwgaW50MzIgZm9vO1xuIgorICAgICJ9XG4iLAorICAgICIxOjIwOiBNaXNzaW5nIGZpZWxkIG51bWJlci5cbiIpOworfQorCitURVNUX0YoUGFyc2VFcnJvclRlc3QsIEV4cGVjdGVkRmllbGROdW1iZXIpIHsKKyAgRXhwZWN0SGFzRXJyb3JzKAorICAgICJtZXNzYWdlIFRlc3RNZXNzYWdlIHtcbiIKKyAgICAiICBvcHRpb25hbCBpbnQzMiBmb28gPSA7XG4iCisgICAgIn1cbiIsCisgICAgIjE6MjM6IEV4cGVjdGVkIGZpZWxkIG51bWJlci5cbiIpOworfQorCitURVNUX0YoUGFyc2VFcnJvclRlc3QsIEZpZWxkTnVtYmVyT3V0T2ZSYW5nZSkgeworICBFeHBlY3RIYXNFcnJvcnMoCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIG9wdGlvbmFsIGludDMyIGZvbyA9IDB4MTAwMDAwMDAwO1xuIgorICAgICJ9XG4iLAorICAgICIxOjIzOiBJbnRlZ2VyIG91dCBvZiByYW5nZS5cbiIpOworfQorCitURVNUX0YoUGFyc2VFcnJvclRlc3QsIE1pc3NpbmdMYWJlbCkgeworICBFeHBlY3RIYXNFcnJvcnMoCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIGludDMyIGZvbyA9IDE7XG4iCisgICAgIn1cbiIsCisgICAgIjE6MjogRXhwZWN0ZWQgXCJyZXF1aXJlZFwiLCBcIm9wdGlvbmFsXCIsIG9yIFwicmVwZWF0ZWRcIi5cbiIpOworfQorCitURVNUX0YoUGFyc2VFcnJvclRlc3QsIEV4cGVjdGVkT3B0aW9uTmFtZSkgeworICBFeHBlY3RIYXNFcnJvcnMoCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIG9wdGlvbmFsIHVpbnQzMiBmb28gPSAxIFtdO1xuIgorICAgICJ9XG4iLAorICAgICIxOjI3OiBFeHBlY3RlZCBpZGVudGlmaWVyLlxuIik7Cit9CisKK1RFU1RfRihQYXJzZUVycm9yVGVzdCwgTm9uRXh0ZW5zaW9uT3B0aW9uTmFtZUJlZ2lubmluZ1dpdGhEb3QpIHsKKyAgRXhwZWN0SGFzRXJyb3JzKAorICAgICJtZXNzYWdlIFRlc3RNZXNzYWdlIHtcbiIKKyAgICAiICBvcHRpb25hbCB1aW50MzIgZm9vID0gMSBbLmZvbz0xXTtcbiIKKyAgICAifVxuIiwKKyAgICAiMToyNzogRXhwZWN0ZWQgaWRlbnRpZmllci5cbiIpOworfQorCitURVNUX0YoUGFyc2VFcnJvclRlc3QsIERlZmF1bHRWYWx1ZVR5cGVNaXNtYXRjaCkgeworICBFeHBlY3RIYXNFcnJvcnMoCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIG9wdGlvbmFsIHVpbnQzMiBmb28gPSAxIFtkZWZhdWx0PXRydWVdO1xuIgorICAgICJ9XG4iLAorICAgICIxOjM1OiBFeHBlY3RlZCBpbnRlZ2VyIGZvciBmaWVsZCBkZWZhdWx0IHZhbHVlLlxuIik7Cit9CisKK1RFU1RfRihQYXJzZUVycm9yVGVzdCwgRGVmYXVsdFZhbHVlTm90Qm9vbGVhbikgeworICBFeHBlY3RIYXNFcnJvcnMoCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIG9wdGlvbmFsIGJvb2wgZm9vID0gMSBbZGVmYXVsdD1ibGFoXTtcbiIKKyAgICAifVxuIiwKKyAgICAiMTozMzogRXhwZWN0ZWQgXCJ0cnVlXCIgb3IgXCJmYWxzZVwiLlxuIik7Cit9CisKK1RFU1RfRihQYXJzZUVycm9yVGVzdCwgRGVmYXVsdFZhbHVlTm90U3RyaW5nKSB7CisgIEV4cGVjdEhhc0Vycm9ycygKKyAgICAibWVzc2FnZSBUZXN0TWVzc2FnZSB7XG4iCisgICAgIiAgb3B0aW9uYWwgc3RyaW5nIGZvbyA9IDEgW2RlZmF1bHQ9MV07XG4iCisgICAgIn1cbiIsCisgICAgIjE6MzU6IEV4cGVjdGVkIHN0cmluZyBmb3IgZmllbGQgZGVmYXVsdCB2YWx1ZS5cbiIpOworfQorCitURVNUX0YoUGFyc2VFcnJvclRlc3QsIERlZmF1bHRWYWx1ZVVuc2lnbmVkTmVnYXRpdmUpIHsKKyAgRXhwZWN0SGFzRXJyb3JzKAorICAgICJtZXNzYWdlIFRlc3RNZXNzYWdlIHtcbiIKKyAgICAiICBvcHRpb25hbCB1aW50MzIgZm9vID0gMSBbZGVmYXVsdD0tMV07XG4iCisgICAgIn1cbiIsCisgICAgIjE6MzY6IFVuc2lnbmVkIGZpZWxkIGNhbid0IGhhdmUgbmVnYXRpdmUgZGVmYXVsdCB2YWx1ZS5cbiIpOworfQorCitURVNUX0YoUGFyc2VFcnJvclRlc3QsIERlZmF1bHRWYWx1ZVRvb0xhcmdlKSB7CisgIEV4cGVjdEhhc0Vycm9ycygKKyAgICAibWVzc2FnZSBUZXN0TWVzc2FnZSB7XG4iCisgICAgIiAgb3B0aW9uYWwgaW50MzIgIGZvbyA9IDEgW2RlZmF1bHQ9IDB4ODAwMDAwMDBdO1xuIgorICAgICIgIG9wdGlvbmFsIGludDMyICBmb28gPSAxIFtkZWZhdWx0PS0weDgwMDAwMDAxXTtcbiIKKyAgICAiICBvcHRpb25hbCB1aW50MzIgZm9vID0gMSBbZGVmYXVsdD0gMHgxMDAwMDAwMDBdO1xuIgorICAgICIgIG9wdGlvbmFsIGludDY0ICBmb28gPSAxIFtkZWZhdWx0PSAweDgwMDAwMDAwMDAwMDAwMDAwXTtcbiIKKyAgICAiICBvcHRpb25hbCBpbnQ2NCAgZm9vID0gMSBbZGVmYXVsdD0tMHg4MDAwMDAwMDAwMDAwMDAwMV07XG4iCisgICAgIiAgb3B0aW9uYWwgdWludDY0IGZvbyA9IDEgW2RlZmF1bHQ9IDB4MTAwMDAwMDAwMDAwMDAwMDAwXTtcbiIKKyAgICAifVxuIiwKKyAgICAiMTozNjogSW50ZWdlciBvdXQgb2YgcmFuZ2UuXG4iCisgICAgIjI6MzY6IEludGVnZXIgb3V0IG9mIHJhbmdlLlxuIgorICAgICIzOjM2OiBJbnRlZ2VyIG91dCBvZiByYW5nZS5cbiIKKyAgICAiNDozNjogSW50ZWdlciBvdXQgb2YgcmFuZ2UuXG4iCisgICAgIjU6MzY6IEludGVnZXIgb3V0IG9mIHJhbmdlLlxuIgorICAgICI2OjM2OiBJbnRlZ2VyIG91dCBvZiByYW5nZS5cbiIpOworfQorCitURVNUX0YoUGFyc2VFcnJvclRlc3QsIEpzb25OYW1lTm90U3RyaW5nKSB7CisgIEV4cGVjdEhhc0Vycm9ycygKKyAgICAibWVzc2FnZSBUZXN0TWVzc2FnZSB7XG4iCisgICAgIiAgb3B0aW9uYWwgc3RyaW5nIGZvbyA9IDEgW2pzb25fbmFtZT0xXTtcbiIKKyAgICAifVxuIiwKKyAgICAiMTozNzogRXhwZWN0ZWQgc3RyaW5nIGZvciBKU09OIG5hbWUuXG4iKTsKK30KKworVEVTVF9GKFBhcnNlRXJyb3JUZXN0LCBEdXBsaWNhdGVKc29uTmFtZSkgeworICBFeHBlY3RIYXNFcnJvcnMoCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIG9wdGlvbmFsIHVpbnQzMiBmb28gPSAxIFtqc29uX25hbWU9XCJhXCIsanNvbl9uYW1lPVwiYlwiXTtcbiIKKyAgICAifVxuIiwKKyAgICAiMTo0MTogQWxyZWFkeSBzZXQgb3B0aW9uIFwianNvbl9uYW1lXCIuXG4iKTsKK30KKworVEVTVF9GKFBhcnNlRXJyb3JUZXN0LCBFbnVtVmFsdWVPdXRPZlJhbmdlKSB7CisgIEV4cGVjdEhhc0Vycm9ycygKKyAgICAiZW51bSBUZXN0RW51bSB7XG4iCisgICAgIiAgSEVYX1RPT19CSUcgICA9ICAweDgwMDAwMDAwO1xuIgorICAgICIgIEhFWF9UT09fU01BTEwgPSAtMHg4MDAwMDAwMTtcbiIKKyAgICAiICBJTlRfVE9PX0JJRyAgID0gIDIxNDc0ODM2NDg7XG4iCisgICAgIiAgSU5UX1RPT19TTUFMTCA9IC0yMTQ3NDgzNjQ5O1xuIgorICAgICJ9XG4iLAorICAgICIxOjE5OiBJbnRlZ2VyIG91dCBvZiByYW5nZS5cbiIKKyAgICAiMjoxOTogSW50ZWdlciBvdXQgb2YgcmFuZ2UuXG4iCisgICAgIjM6MTk6IEludGVnZXIgb3V0IG9mIHJhbmdlLlxuIgorICAgICI0OjE5OiBJbnRlZ2VyIG91dCBvZiByYW5nZS5cbiIpOworfQorCitURVNUX0YoUGFyc2VFcnJvclRlc3QsIEVudW1BbGxvd0FsaWFzRmFsc2UpIHsKKyAgRXhwZWN0SGFzRXJyb3JzKAorICAgICJlbnVtIEZvbyB7XG4iCisgICAgIiAgb3B0aW9uIGFsbG93X2FsaWFzID0gZmFsc2U7XG4iCisgICAgIiAgQkFSID0gMTtcbiIKKyAgICAiICBCQVogPSAyO1xuIgorICAgICJ9XG4iLAorICAgICI1OjA6IFwiRm9vXCIgZGVjbGFyZXMgJ29wdGlvbiBhbGxvd19hbGlhcyA9IGZhbHNlOycgd2hpY2ggaGFzIG5vIGVmZmVjdC4gIgorICAgICJQbGVhc2UgcmVtb3ZlIHRoZSBkZWNsYXJhdGlvbi5cbiIpOworfQorCitURVNUX0YoUGFyc2VFcnJvclRlc3QsIFVubmVjZXNzYXJ5RW51bUFsbG93QWxpYXMpIHsKKyAgRXhwZWN0SGFzRXJyb3JzKAorICAgICJlbnVtIEZvbyB7XG4iCisgICAgIiAgb3B0aW9uIGFsbG93X2FsaWFzID0gdHJ1ZTtcbiIKKyAgICAiICBCQVIgPSAxO1xuIgorICAgICIgIEJBWiA9IDI7XG4iCisgICAgIn1cbiIsCisgICAgIjU6MDogXCJGb29cIiBkZWNsYXJlcyBzdXBwb3J0IGZvciBlbnVtIGFsaWFzZXMgYnV0IG5vIGVudW0gdmFsdWVzIHNoYXJlICIKKyAgICAiZmllbGQgbnVtYmVycy4gUGxlYXNlIHJlbW92ZSB0aGUgdW5uZWNlc3NhcnkgJ29wdGlvbiBhbGxvd19hbGlhcyA9IHRydWU7JyAiCisgICAgImRlY2xhcmF0aW9uLlxuIik7Cit9CisKK1RFU1RfRihQYXJzZUVycm9yVGVzdCwgRGVmYXVsdFZhbHVlTWlzc2luZykgeworICBFeHBlY3RIYXNFcnJvcnMoCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIG9wdGlvbmFsIHVpbnQzMiBmb28gPSAxIFtkZWZhdWx0PV07XG4iCisgICAgIn1cbiIsCisgICAgIjE6MzU6IEV4cGVjdGVkIGludGVnZXIgZm9yIGZpZWxkIGRlZmF1bHQgdmFsdWUuXG4iKTsKK30KKworVEVTVF9GKFBhcnNlRXJyb3JUZXN0LCBEZWZhdWx0VmFsdWVGb3JHcm91cCkgeworICBFeHBlY3RIYXNFcnJvcnMoCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIG9wdGlvbmFsIGdyb3VwIEZvbyA9IDEgW2RlZmF1bHQ9YmxhaF0ge31cbiIKKyAgICAifVxuIiwKKyAgICAiMTozNDogTWVzc2FnZXMgY2FuJ3QgaGF2ZSBkZWZhdWx0IHZhbHVlcy5cbiIpOworfQorCitURVNUX0YoUGFyc2VFcnJvclRlc3QsIER1cGxpY2F0ZURlZmF1bHRWYWx1ZSkgeworICBFeHBlY3RIYXNFcnJvcnMoCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIG9wdGlvbmFsIHVpbnQzMiBmb28gPSAxIFtkZWZhdWx0PTEsZGVmYXVsdD0yXTtcbiIKKyAgICAifVxuIiwKKyAgICAiMTozNzogQWxyZWFkeSBzZXQgb3B0aW9uIFwiZGVmYXVsdFwiLlxuIik7Cit9CisKK1RFU1RfRihQYXJzZUVycm9yVGVzdCwgTWlzc2luZ09uZW9mTmFtZSkgeworICBFeHBlY3RIYXNFcnJvcnMoCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIG9uZW9mIHtcbiIKKyAgICAiICAgIGludDMyIGJhciA9IDE7XG4iCisgICAgIiAgfVxuIgorICAgICJ9XG4iLAorICAgICIxOjg6IEV4cGVjdGVkIG9uZW9mIG5hbWUuXG4iKTsKK30KKworVEVTVF9GKFBhcnNlRXJyb3JUZXN0LCBMYWJlbEluT25lb2YpIHsKKyAgRXhwZWN0SGFzRXJyb3JzKAorICAgICJtZXNzYWdlIFRlc3RNZXNzYWdlIHtcbiIKKyAgICAiICBvbmVvZiBmb28ge1xuIgorICAgICIgICAgb3B0aW9uYWwgaW50MzIgYmFyID0gMTtcbiIKKyAgICAiICB9XG4iCisgICAgIn1cbiIsCisgICAgIjI6NDogRmllbGRzIGluIG9uZW9mcyBtdXN0IG5vdCBoYXZlIGxhYmVscyAocmVxdWlyZWQgLyBvcHRpb25hbCAiCisgICAgICAiLyByZXBlYXRlZCkuXG4iKTsKK30KKworVEVTVF9GKFBhcnNlRXJyb3JUZXN0LCBNYXBJbk9uZW9mKSB7CisgIEV4cGVjdEhhc0Vycm9ycygKKyAgICAibWVzc2FnZSBUZXN0TWVzc2FnZSB7XG4iCisgICAgIiAgb25lb2YgZm9vIHtcbiIKKyAgICAiICAgIG1hcDxpbnQzMiwgaW50MzI+IGZvb19tYXAgPSAxO1xuIgorICAgICIgICAgbWFwIG1lc3NhZ2VfZmllbGQgPSAyO1xuIiAgLy8gYSBub3JtYWwgbWVzc2FnZSBmaWVsZCBpcyBPSworICAgICIgIH1cbiIKKyAgICAifVxuIiwKKyAgICAiMjo3OiBNYXAgZmllbGRzIGFyZSBub3QgYWxsb3dlZCBpbiBvbmVvZnMuXG4iKTsKK30KKworVEVTVF9GKFBhcnNlRXJyb3JUZXN0LCBMYWJlbEZvck1hcCkgeworICBFeHBlY3RIYXNFcnJvcnMoCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIG9wdGlvbmFsIG1hcDxpbnQzMiwgaW50MzI+IGludF9tYXAgPSAxO1xuIgorICAgICIgIHJlcXVpcmVkIG1hcDxpbnQzMiwgaW50MzI+IGludF9tYXAyID0gMjtcbiIKKyAgICAiICByZXBlYXRlZCBtYXA8aW50MzIsIGludDMyPiBpbnRfbWFwMyA9IDM7XG4iCisgICAgIiAgb3B0aW9uYWwgbWFwIG1hcF9tZXNzYWdlID0gNDtcbiIgIC8vIGEgbm9ybWFsIG1lc3NhZ2UgZmllbGQgaXMgT0sKKyAgICAifVxuIiwKKyAgICAiMToxNDogRmllbGQgbGFiZWxzIChyZXF1aXJlZC9vcHRpb25hbC9yZXBlYXRlZCkgYXJlIG5vdCBhbGxvd2VkIG9uIG1hcCAiCisgICAgImZpZWxkcy5cbiIKKyAgICAiMjoxNDogRmllbGQgbGFiZWxzIChyZXF1aXJlZC9vcHRpb25hbC9yZXBlYXRlZCkgYXJlIG5vdCBhbGxvd2VkIG9uIG1hcCAiCisgICAgImZpZWxkcy5cbiIKKyAgICAiMzoxNDogRmllbGQgbGFiZWxzIChyZXF1aXJlZC9vcHRpb25hbC9yZXBlYXRlZCkgYXJlIG5vdCBhbGxvd2VkIG9uIG1hcCAiCisgICAgImZpZWxkcy5cbiIpOworfQorCitURVNUX0YoUGFyc2VFcnJvclRlc3QsIE1hbGZvcm1lZE1hcHMpIHsKKyAgRXhwZWN0SGFzRXJyb3JzKAorICAgICJtZXNzYWdlIFRlc3RNZXNzYWdlIHtcbiIKKyAgICAiICBtYXAgbWFwX21lc3NhZ2UgPSAxO1xuIiAgIC8vIGEgbm9ybWFsIG1lc3NhZ2UgZmllbGQgbGFja2luZyBsYWJlbAorICAgICIgIG1hcDxzdHJpbmc+IHN0cl9tYXAgPSAyO1xuIgorICAgICIgIG1hcDxzdHJpbmcsPiBzdHJfbWFwMiA9IDM7XG4iCisgICAgIiAgbWFwPCxzdHJpbmc+IHN0cl9tYXAzID0gNDtcbiIKKyAgICAiICBtYXA8PiBlbXB0eV9tYXAgPSA1O1xuIgorICAgICIgIG1hcDxzdHJpbmcsc3RyaW5nIHN0cl9tYXA2ID0gNjtcbiIKKyAgICAifSIKKyAgICAiZXh0ZW5kIFNvbWVNZXNzYWdlIHtcbiIKKyAgICAiICBtYXA8aW50MzIsIGludDMyPiBpbnRfbWFwID0gMTtcbiIKKyAgICAifSIsCisgICAgIjE6NjogRXhwZWN0ZWQgXCJyZXF1aXJlZFwiLCBcIm9wdGlvbmFsXCIsIG9yIFwicmVwZWF0ZWRcIi5cbiIKKyAgICAiMjoxMjogRXhwZWN0ZWQgXCIsXCIuXG4iCisgICAgIjM6MTM6IEV4cGVjdGVkIHR5cGUgbmFtZS5cbiIKKyAgICAiNDo2OiBFeHBlY3RlZCB0eXBlIG5hbWUuXG4iCisgICAgIjU6NjogRXhwZWN0ZWQgdHlwZSBuYW1lLlxuIgorICAgICI2OjIwOiBFeHBlY3RlZCBcIj5cIi5cbiIKKyAgICAiODo1OiBNYXAgZmllbGRzIGFyZSBub3QgYWxsb3dlZCB0byBiZSBleHRlbnNpb25zLlxuIik7Cit9CisKK1RFU1RfRihQYXJzZUVycm9yVGVzdCwgR3JvdXBOb3RDYXBpdGFsaXplZCkgeworICBFeHBlY3RIYXNFcnJvcnMoCisgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICIgIG9wdGlvbmFsIGdyb3VwIGZvbyA9IDEge31cbiIKKyAgICAifVxuIiwKKyAgICAiMToxNzogR3JvdXAgbmFtZXMgbXVzdCBzdGFydCB3aXRoIGEgY2FwaXRhbCBsZXR0ZXIuXG4iKTsKK30KKworVEVTVF9GKFBhcnNlRXJyb3JUZXN0LCBHcm91cE1pc3NpbmdCb2R5KSB7CisgIEV4cGVjdEhhc0Vycm9ycygKKyAgICAibWVzc2FnZSBUZXN0TWVzc2FnZSB7XG4iCisgICAgIiAgb3B0aW9uYWwgZ3JvdXAgRm9vID0gMTtcbiIKKyAgICAifVxuIiwKKyAgICAiMToyNDogTWlzc2luZyBncm91cCBib2R5LlxuIik7Cit9CisKK1RFU1RfRihQYXJzZUVycm9yVGVzdCwgRXh0ZW5kaW5nUHJpbWl0aXZlKSB7CisgIEV4cGVjdEhhc0Vycm9ycygKKyAgICAiZXh0ZW5kIGludDMyIHsgb3B0aW9uYWwgc3RyaW5nIGZvbyA9IDQ7IH1cbiIsCisgICAgIjA6NzogRXhwZWN0ZWQgbWVzc2FnZSB0eXBlLlxuIik7Cit9CisKK1RFU1RfRihQYXJzZUVycm9yVGVzdCwgRXJyb3JJbkV4dGVuc2lvbikgeworICBFeHBlY3RIYXNFcnJvcnMoCisgICAgIm1lc3NhZ2UgRm9vIHsgZXh0ZW5zaW9ucyAxMDAgdG8gMTk5OyB9XG4iCisgICAgImV4dGVuZCBGb28geyBvcHRpb25hbCBzdHJpbmcgZm9vOyB9XG4iLAorICAgICIxOjMyOiBNaXNzaW5nIGZpZWxkIG51bWJlci5cbiIpOworfQorCitURVNUX0YoUGFyc2VFcnJvclRlc3QsIE11bHRpcGxlUGFyc2VFcnJvcnMpIHsKKyAgLy8gV2hlbiBhIHN0YXRlbWVudCBoYXMgYSBwYXJzZSBlcnJvciwgdGhlIHBhcnNlciBzaG91bGQgYmUgYWJsZSB0byBjb250aW51ZQorICAvLyBwYXJzaW5nIGF0IHRoZSBuZXh0IHN0YXRlbWVudC4KKyAgRXhwZWN0SGFzRXJyb3JzKAorICAgICJtZXNzYWdlIFRlc3RNZXNzYWdlIHtcbiIKKyAgICAiICBvcHRpb25hbCBpbnQzMiBmb287XG4iCisgICAgIiAgIWludmFsaWQgc3RhdGVtZW50IGVuZGluZyBpbiBhIGJsb2NrIHsgYmxhaCBibGFoIHsgYmxhaCB9IGJsYWggfVxuIgorICAgICIgIG9wdGlvbmFsIGludDMyIGJhciA9IDMge31cbiIKKyAgICAifVxuIiwKKyAgICAiMToyMDogTWlzc2luZyBmaWVsZCBudW1iZXIuXG4iCisgICAgIjI6MjogRXhwZWN0ZWQgXCJyZXF1aXJlZFwiLCBcIm9wdGlvbmFsXCIsIG9yIFwicmVwZWF0ZWRcIi5cbiIKKyAgICAiMjoyOiBFeHBlY3RlZCB0eXBlIG5hbWUuXG4iCisgICAgIjM6MjU6IEV4cGVjdGVkIFwiO1wiLlxuIik7Cit9CisKK1RFU1RfRihQYXJzZUVycm9yVGVzdCwgRW9mSW5BZ2dyZWdhdGVWYWx1ZSkgeworICBFeHBlY3RIYXNFcnJvcnMoCisgICAgICAib3B0aW9uIChmaWxlb3B0KSA9IHsgaToxMDBcbiIsCisgICAgICAiMTowOiBVbmV4cGVjdGVkIGVuZCBvZiBzdHJlYW0gd2hpbGUgcGFyc2luZyBhZ2dyZWdhdGUgdmFsdWUuXG4iKTsKK30KKworVEVTVF9GKFBhcnNlRXJyb3JUZXN0LCBFeHBsaWNpdE9wdGlvbmFsTGFiZWxQcm90bzMpIHsKKyAgRXhwZWN0SGFzRXJyb3JzKAorICAgICAgInN5bnRheCA9ICdwcm90bzMnO1xuIgorICAgICAgIm1lc3NhZ2UgVGVzdE1lc3NhZ2Uge1xuIgorICAgICAgIiAgb3B0aW9uYWwgaW50MzIgZm9vID0gMTtcbiIKKyAgICAgICJ9XG4iLAorICAgICAgIjI6MTE6IEV4cGxpY2l0ICdvcHRpb25hbCcgbGFiZWxzIGFyZSBkaXNhbGxvd2VkIGluIHRoZSBQcm90bzMgc3ludGF4LiAiCisgICAgICAiVG8gZGVmaW5lICdvcHRpb25hbCcgZmllbGRzIGluIFByb3RvMywgc2ltcGx5IHJlbW92ZSB0aGUgJ29wdGlvbmFsJyAiCisgICAgICAibGFiZWwsIGFzIGZpZWxkcyBhcmUgJ29wdGlvbmFsJyBieSBkZWZhdWx0LlxuIik7Cit9CisKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gRW51bSBlcnJvcnMKKworVEVTVF9GKFBhcnNlRXJyb3JUZXN0LCBFb2ZJbkVudW0pIHsKKyAgRXhwZWN0SGFzRXJyb3JzKAorICAgICJlbnVtIFRlc3RFbnVtIHsiLAorICAgICIwOjE1OiBSZWFjaGVkIGVuZCBvZiBpbnB1dCBpbiBlbnVtIGRlZmluaXRpb24gKG1pc3NpbmcgJ30nKS5cbiIpOworfQorCitURVNUX0YoUGFyc2VFcnJvclRlc3QsIEVudW1WYWx1ZU1pc3NpbmdOdW1iZXIpIHsKKyAgRXhwZWN0SGFzRXJyb3JzKAorICAgICJlbnVtIFRlc3RFbnVtIHtcbiIKKyAgICAiICBGT087XG4iCisgICAgIn1cbiIsCisgICAgIjE6NTogTWlzc2luZyBudW1lcmljIHZhbHVlIGZvciBlbnVtIGNvbnN0YW50LlxuIik7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIFJlc2VydmVkIGZpZWxkIG51bWJlciBlcnJvcnMKKworVEVTVF9GKFBhcnNlRXJyb3JUZXN0LCBSZXNlcnZlZE1heE5vdEFsbG93ZWQpIHsKKyAgRXhwZWN0SGFzRXJyb3JzKAorICAgICJtZXNzYWdlIEZvbyB7XG4iCisgICAgIiAgcmVzZXJ2ZWQgMTAgdG8gbWF4O1xuIgorICAgICJ9XG4iLAorICAgICIxOjE3OiBFeHBlY3RlZCBpbnRlZ2VyLlxuIik7Cit9CisKK1RFU1RfRihQYXJzZUVycm9yVGVzdCwgUmVzZXJ2ZWRNaXhOYW1lQW5kTnVtYmVyKSB7CisgIEV4cGVjdEhhc0Vycm9ycygKKyAgICAibWVzc2FnZSBGb28ge1xuIgorICAgICIgIHJlc2VydmVkIDEwLCBcImZvb1wiO1xuIgorICAgICJ9XG4iLAorICAgICIxOjE1OiBFeHBlY3RlZCBmaWVsZCBudW1iZXIgcmFuZ2UuXG4iKTsKK30KKworVEVTVF9GKFBhcnNlRXJyb3JUZXN0LCBSZXNlcnZlZE1pc3NpbmdRdW90ZXMpIHsKKyAgRXhwZWN0SGFzRXJyb3JzKAorICAgICJtZXNzYWdlIEZvbyB7XG4iCisgICAgIiAgcmVzZXJ2ZWQgZm9vO1xuIgorICAgICJ9XG4iLAorICAgICIxOjExOiBFeHBlY3RlZCBmaWVsZCBuYW1lIG9yIG51bWJlciByYW5nZS5cbiIpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBTZXJ2aWNlIGVycm9ycworCitURVNUX0YoUGFyc2VFcnJvclRlc3QsIEVvZkluU2VydmljZSkgeworICBFeHBlY3RIYXNFcnJvcnMoCisgICAgInNlcnZpY2UgVGVzdFNlcnZpY2UgeyIsCisgICAgIjA6MjE6IFJlYWNoZWQgZW5kIG9mIGlucHV0IGluIHNlcnZpY2UgZGVmaW5pdGlvbiAobWlzc2luZyAnfScpLlxuIik7Cit9CisKK1RFU1RfRihQYXJzZUVycm9yVGVzdCwgU2VydmljZU1ldGhvZFByaW1pdGl2ZVBhcmFtcykgeworICBFeHBlY3RIYXNFcnJvcnMoCisgICAgInNlcnZpY2UgVGVzdFNlcnZpY2Uge1xuIgorICAgICIgIHJwYyBGb28oaW50MzIpIHJldHVybnMgKHN0cmluZyk7XG4iCisgICAgIn1cbiIsCisgICAgIjE6MTA6IEV4cGVjdGVkIG1lc3NhZ2UgdHlwZS5cbiIKKyAgICAiMToyNjogRXhwZWN0ZWQgbWVzc2FnZSB0eXBlLlxuIik7Cit9CisKKworVEVTVF9GKFBhcnNlRXJyb3JUZXN0LCBFb2ZJbk1ldGhvZE9wdGlvbnMpIHsKKyAgRXhwZWN0SGFzRXJyb3JzKAorICAgICJzZXJ2aWNlIFRlc3RTZXJ2aWNlIHtcbiIKKyAgICAiICBycGMgRm9vKEJhcikgcmV0dXJucyhCYXIpIHsiLAorICAgICIxOjI5OiBSZWFjaGVkIGVuZCBvZiBpbnB1dCBpbiBtZXRob2Qgb3B0aW9ucyAobWlzc2luZyAnfScpLlxuIgorICAgICIxOjI5OiBSZWFjaGVkIGVuZCBvZiBpbnB1dCBpbiBzZXJ2aWNlIGRlZmluaXRpb24gKG1pc3NpbmcgJ30nKS5cbiIpOworfQorCisKK1RFU1RfRihQYXJzZUVycm9yVGVzdCwgUHJpbWl0aXZlTWV0aG9kSW5wdXQpIHsKKyAgRXhwZWN0SGFzRXJyb3JzKAorICAgICJzZXJ2aWNlIFRlc3RTZXJ2aWNlIHtcbiIKKyAgICAiICBycGMgRm9vKGludDMyKSByZXR1cm5zKEJhcik7XG4iCisgICAgIn1cbiIsCisgICAgIjE6MTA6IEV4cGVjdGVkIG1lc3NhZ2UgdHlwZS5cbiIpOworfQorCisKK1RFU1RfRihQYXJzZUVycm9yVGVzdCwgTWV0aG9kT3B0aW9uVHlwZUVycm9yKSB7CisgIC8vIFRoaXMgdXNlZCB0byBjYXVzZSBhbiBpbmZpbml0ZSBsb29wLgorICBFeHBlY3RIYXNFcnJvcnMoCisgICAgIm1lc3NhZ2UgQmF6IHt9XG4iCisgICAgInNlcnZpY2UgRm9vIHtcbiIKKyAgICAiICBycGMgQmFyKEJheikgcmV0dXJucyhCYXopIHsgb3B0aW9uIGludmFsaWQgc3ludGF4OyB9XG4iCisgICAgIn1cbiIsCisgICAgIjI6NDU6IEV4cGVjdGVkIFwiPVwiLlxuIik7Cit9CisKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gSW1wb3J0IGFuZCBwYWNrYWdlIGVycm9ycworCitURVNUX0YoUGFyc2VFcnJvclRlc3QsIEltcG9ydE5vdFF1b3RlZCkgeworICBFeHBlY3RIYXNFcnJvcnMoCisgICAgImltcG9ydCBmb287XG4iLAorICAgICIwOjc6IEV4cGVjdGVkIGEgc3RyaW5nIG5hbWluZyB0aGUgZmlsZSB0byBpbXBvcnQuXG4iKTsKK30KKworVEVTVF9GKFBhcnNlRXJyb3JUZXN0LCBNdWx0aXBsZVBhY2thZ2VzSW5GaWxlKSB7CisgIEV4cGVjdEhhc0Vycm9ycygKKyAgICAicGFja2FnZSBmb287XG4iCisgICAgInBhY2thZ2UgYmFyO1xuIiwKKyAgICAiMTowOiBNdWx0aXBsZSBwYWNrYWdlIGRlZmluaXRpb25zLlxuIik7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKy8vIFRlc3QgdGhhdCBlcnJvcnMgZGV0ZWN0ZWQgYnkgRGVzY3JpcHRvclBvb2wgY29ycmVjdGx5IHJlcG9ydCBsaW5lIGFuZAorLy8gY29sdW1uIG51bWJlcnMuICBXZSBoYXZlIG9uZSB0ZXN0IGZvciBldmVyeSBjYWxsIHRvIFJlY29yZExvY2F0aW9uKCkgaW4KKy8vIHBhcnNlci5jYy4KKwordHlwZWRlZiBQYXJzZXJUZXN0IFBhcnNlclZhbGlkYXRpb25FcnJvclRlc3Q7CisKK1RFU1RfRihQYXJzZXJWYWxpZGF0aW9uRXJyb3JUZXN0LCBQYWNrYWdlTmFtZUVycm9yKSB7CisgIC8vIENyZWF0ZSBhbm90aGVyIGZpbGUgd2hpY2ggZGVmaW5lcyBzeW1ib2wgImZvbyIuCisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gb3RoZXJfZmlsZTsKKyAgb3RoZXJfZmlsZS5zZXRfbmFtZSgiYmFyLnByb3RvIik7CisgIG90aGVyX2ZpbGUuYWRkX21lc3NhZ2VfdHlwZSgpLT5zZXRfbmFtZSgiZm9vIik7CisgIEVYUEVDVF9UUlVFKHBvb2xfLkJ1aWxkRmlsZShvdGhlcl9maWxlKSAhPSBOVUxMKTsKKworICAvLyBOb3cgdHJ5IHRvIGRlZmluZSBpdCBhcyBhIHBhY2thZ2UuCisgIEV4cGVjdEhhc1ZhbGlkYXRpb25FcnJvcnMoCisgICAgInBhY2thZ2UgZm9vLmJhcjsiLAorICAgICIwOjg6IFwiZm9vXCIgaXMgYWxyZWFkeSBkZWZpbmVkIChhcyBzb21ldGhpbmcgb3RoZXIgdGhhbiBhIHBhY2thZ2UpICIKKyAgICAgICJpbiBmaWxlIFwiYmFyLnByb3RvXCIuXG4iKTsKK30KKworVEVTVF9GKFBhcnNlclZhbGlkYXRpb25FcnJvclRlc3QsIE1lc3NhZ2VOYW1lRXJyb3IpIHsKKyAgRXhwZWN0SGFzVmFsaWRhdGlvbkVycm9ycygKKyAgICAibWVzc2FnZSBGb28ge31cbiIKKyAgICAibWVzc2FnZSBGb28ge31cbiIsCisgICAgIjE6ODogXCJGb29cIiBpcyBhbHJlYWR5IGRlZmluZWQuXG4iKTsKK30KKworVEVTVF9GKFBhcnNlclZhbGlkYXRpb25FcnJvclRlc3QsIEZpZWxkTmFtZUVycm9yKSB7CisgIEV4cGVjdEhhc1ZhbGlkYXRpb25FcnJvcnMoCisgICAgIm1lc3NhZ2UgRm9vIHtcbiIKKyAgICAiICBvcHRpb25hbCBpbnQzMiBiYXIgPSAxO1xuIgorICAgICIgIG9wdGlvbmFsIGludDMyIGJhciA9IDI7XG4iCisgICAgIn1cbiIsCisgICAgIjI6MTc6IFwiYmFyXCIgaXMgYWxyZWFkeSBkZWZpbmVkIGluIFwiRm9vXCIuXG4iKTsKK30KKworVEVTVF9GKFBhcnNlclZhbGlkYXRpb25FcnJvclRlc3QsIEZpZWxkVHlwZUVycm9yKSB7CisgIEV4cGVjdEhhc1ZhbGlkYXRpb25FcnJvcnMoCisgICAgIm1lc3NhZ2UgRm9vIHtcbiIKKyAgICAiICBvcHRpb25hbCBCYXogYmFyID0gMTtcbiIKKyAgICAifVxuIiwKKyAgICAiMToxMTogXCJCYXpcIiBpcyBub3QgZGVmaW5lZC5cbiIpOworfQorCitURVNUX0YoUGFyc2VyVmFsaWRhdGlvbkVycm9yVGVzdCwgRmllbGROdW1iZXJFcnJvcikgeworICBFeHBlY3RIYXNWYWxpZGF0aW9uRXJyb3JzKAorICAgICJtZXNzYWdlIEZvbyB7XG4iCisgICAgIiAgb3B0aW9uYWwgaW50MzIgYmFyID0gMDtcbiIKKyAgICAifVxuIiwKKyAgICAiMToyMzogRmllbGQgbnVtYmVycyBtdXN0IGJlIHBvc2l0aXZlIGludGVnZXJzLlxuIik7Cit9CisKK1RFU1RfRihQYXJzZXJWYWxpZGF0aW9uRXJyb3JUZXN0LCBGaWVsZEV4dGVuZGVlRXJyb3IpIHsKKyAgRXhwZWN0SGFzVmFsaWRhdGlvbkVycm9ycygKKyAgICAiZXh0ZW5kIEJheiB7IG9wdGlvbmFsIGludDMyIGJhciA9IDE7IH1cbiIsCisgICAgIjA6NzogXCJCYXpcIiBpcyBub3QgZGVmaW5lZC5cbiIpOworfQorCitURVNUX0YoUGFyc2VyVmFsaWRhdGlvbkVycm9yVGVzdCwgRmllbGREZWZhdWx0VmFsdWVFcnJvcikgeworICBFeHBlY3RIYXNWYWxpZGF0aW9uRXJyb3JzKAorICAgICJlbnVtIEJheiB7IFFVWCA9IDE7IH1cbiIKKyAgICAibWVzc2FnZSBGb28ge1xuIgorICAgICIgIG9wdGlvbmFsIEJheiBiYXIgPSAxIFtkZWZhdWx0PU5PX1NVQ0hfVkFMVUVdO1xuIgorICAgICJ9XG4iLAorICAgICIyOjMyOiBFbnVtIHR5cGUgXCJCYXpcIiBoYXMgbm8gdmFsdWUgbmFtZWQgXCJOT19TVUNIX1ZBTFVFXCIuXG4iKTsKK30KKworVEVTVF9GKFBhcnNlclZhbGlkYXRpb25FcnJvclRlc3QsIEZpbGVPcHRpb25OYW1lRXJyb3IpIHsKKyAgRXhwZWN0SGFzVmFsaWRhdGlvbkVycm9ycygKKyAgICAib3B0aW9uIGZvbyA9IDU7IiwKKyAgICAiMDo3OiBPcHRpb24gXCJmb29cIiB1bmtub3duLlxuIik7Cit9CisKK1RFU1RfRihQYXJzZXJWYWxpZGF0aW9uRXJyb3JUZXN0LCBGaWxlT3B0aW9uVmFsdWVFcnJvcikgeworICBFeHBlY3RIYXNWYWxpZGF0aW9uRXJyb3JzKAorICAgICJvcHRpb24gamF2YV9vdXRlcl9jbGFzc25hbWUgPSA1OyIsCisgICAgIjA6MzA6IFZhbHVlIG11c3QgYmUgcXVvdGVkIHN0cmluZyBmb3Igc3RyaW5nIG9wdGlvbiAiCisgICAgIlwiZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmphdmFfb3V0ZXJfY2xhc3NuYW1lXCIuXG4iKTsKK30KKworVEVTVF9GKFBhcnNlclZhbGlkYXRpb25FcnJvclRlc3QsIEZpZWxkT3B0aW9uTmFtZUVycm9yKSB7CisgIEV4cGVjdEhhc1ZhbGlkYXRpb25FcnJvcnMoCisgICAgIm1lc3NhZ2UgRm9vIHtcbiIKKyAgICAiICBvcHRpb25hbCBib29sIGJhciA9IDEgW2Zvbz0xXTtcbiIKKyAgICAifVxuIiwKKyAgICAiMToyNTogT3B0aW9uIFwiZm9vXCIgdW5rbm93bi5cbiIpOworfQorCitURVNUX0YoUGFyc2VyVmFsaWRhdGlvbkVycm9yVGVzdCwgRmllbGRPcHRpb25WYWx1ZUVycm9yKSB7CisgIEV4cGVjdEhhc1ZhbGlkYXRpb25FcnJvcnMoCisgICAgIm1lc3NhZ2UgRm9vIHtcbiIKKyAgICAiICBvcHRpb25hbCBpbnQzMiBiYXIgPSAxIFtjdHlwZT0xXTtcbiIKKyAgICAifVxuIiwKKyAgICAiMTozMjogVmFsdWUgbXVzdCBiZSBpZGVudGlmaWVyIGZvciBlbnVtLXZhbHVlZCBvcHRpb24gIgorICAgICJcImdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuY3R5cGVcIi5cbiIpOworfQorCitURVNUX0YoUGFyc2VyVmFsaWRhdGlvbkVycm9yVGVzdCwgRXh0ZW5zaW9uUmFuZ2VOdW1iZXJFcnJvcikgeworICBFeHBlY3RIYXNWYWxpZGF0aW9uRXJyb3JzKAorICAgICJtZXNzYWdlIEZvbyB7XG4iCisgICAgIiAgZXh0ZW5zaW9ucyAwO1xuIgorICAgICJ9XG4iLAorICAgICIxOjEzOiBFeHRlbnNpb24gbnVtYmVycyBtdXN0IGJlIHBvc2l0aXZlIGludGVnZXJzLlxuIik7Cit9CisKK1RFU1RfRihQYXJzZXJWYWxpZGF0aW9uRXJyb3JUZXN0LCBFbnVtTmFtZUVycm9yKSB7CisgIEV4cGVjdEhhc1ZhbGlkYXRpb25FcnJvcnMoCisgICAgImVudW0gRm9vIHtBID0gMTt9XG4iCisgICAgImVudW0gRm9vIHtCID0gMTt9XG4iLAorICAgICIxOjU6IFwiRm9vXCIgaXMgYWxyZWFkeSBkZWZpbmVkLlxuIik7Cit9CisKK1RFU1RfRihQYXJzZXJWYWxpZGF0aW9uRXJyb3JUZXN0LCBFbnVtVmFsdWVOYW1lRXJyb3IpIHsKKyAgRXhwZWN0SGFzVmFsaWRhdGlvbkVycm9ycygKKyAgICAiZW51bSBGb28ge1xuIgorICAgICIgIEJBUiA9IDE7XG4iCisgICAgIiAgQkFSID0gMTtcbiIKKyAgICAifVxuIiwKKyAgICAiMjoyOiBcIkJBUlwiIGlzIGFscmVhZHkgZGVmaW5lZC5cbiIpOworfQorCitURVNUX0YoUGFyc2VyVmFsaWRhdGlvbkVycm9yVGVzdCwgU2VydmljZU5hbWVFcnJvcikgeworICBFeHBlY3RIYXNWYWxpZGF0aW9uRXJyb3JzKAorICAgICJzZXJ2aWNlIEZvbyB7fVxuIgorICAgICJzZXJ2aWNlIEZvbyB7fVxuIiwKKyAgICAiMTo4OiBcIkZvb1wiIGlzIGFscmVhZHkgZGVmaW5lZC5cbiIpOworfQorCitURVNUX0YoUGFyc2VyVmFsaWRhdGlvbkVycm9yVGVzdCwgTWV0aG9kTmFtZUVycm9yKSB7CisgIEV4cGVjdEhhc1ZhbGlkYXRpb25FcnJvcnMoCisgICAgIm1lc3NhZ2UgQmF6IHt9XG4iCisgICAgInNlcnZpY2UgRm9vIHtcbiIKKyAgICAiICBycGMgQmFyKEJheikgcmV0dXJucyhCYXopO1xuIgorICAgICIgIHJwYyBCYXIoQmF6KSByZXR1cm5zKEJheik7XG4iCisgICAgIn1cbiIsCisgICAgIjM6NjogXCJCYXJcIiBpcyBhbHJlYWR5IGRlZmluZWQgaW4gXCJGb29cIi5cbiIpOworfQorCisKK1RFU1RfRihQYXJzZXJWYWxpZGF0aW9uRXJyb3JUZXN0LCBNZXRob2RJbnB1dFR5cGVFcnJvcikgeworICBFeHBlY3RIYXNWYWxpZGF0aW9uRXJyb3JzKAorICAgICJtZXNzYWdlIEJheiB7fVxuIgorICAgICJzZXJ2aWNlIEZvbyB7XG4iCisgICAgIiAgcnBjIEJhcihRdXgpIHJldHVybnMoQmF6KTtcbiIKKyAgICAifVxuIiwKKyAgICAiMjoxMDogXCJRdXhcIiBpcyBub3QgZGVmaW5lZC5cbiIpOworfQorCisKK1RFU1RfRihQYXJzZXJWYWxpZGF0aW9uRXJyb3JUZXN0LCBNZXRob2RPdXRwdXRUeXBlRXJyb3IpIHsKKyAgRXhwZWN0SGFzVmFsaWRhdGlvbkVycm9ycygKKyAgICAibWVzc2FnZSBCYXoge31cbiIKKyAgICAic2VydmljZSBGb28ge1xuIgorICAgICIgIHJwYyBCYXIoQmF6KSByZXR1cm5zKFF1eCk7XG4iCisgICAgIn1cbiIsCisgICAgIjI6MjM6IFwiUXV4XCIgaXMgbm90IGRlZmluZWQuXG4iKTsKK30KKworCitURVNUX0YoUGFyc2VyVmFsaWRhdGlvbkVycm9yVGVzdCwgUmVzb3ZsZWRVbmRlZmluZWRFcnJvcikgeworICAvLyBDcmVhdGUgYW5vdGhlciBmaWxlIHdoaWNoIGRlZmluZXMgc3ltYm9sICIuYmFzZS5iYXIiLgorICBGaWxlRGVzY3JpcHRvclByb3RvIG90aGVyX2ZpbGU7CisgIG90aGVyX2ZpbGUuc2V0X25hbWUoImJhc2UucHJvdG8iKTsKKyAgb3RoZXJfZmlsZS5zZXRfcGFja2FnZSgiYmFzZSIpOworICBvdGhlcl9maWxlLmFkZF9tZXNzYWdlX3R5cGUoKS0+c2V0X25hbWUoImJhciIpOworICBFWFBFQ1RfVFJVRShwb29sXy5CdWlsZEZpbGUob3RoZXJfZmlsZSkgIT0gTlVMTCk7CisKKyAgLy8gRGVmaW5lICJmb28uYmFzZSIgYW5kIHRyeSAiYmFzZS5iYXIiLgorICAvLyAiYmFzZS5iYXIiIGlzIHJlc29sdmVkIHRvICJmb28uYmFzZS5iYXIiIHdoaWNoIGlzIG5vdCBkZWZpbmVkLgorICBFeHBlY3RIYXNWYWxpZGF0aW9uRXJyb3JzKAorICAgICJwYWNrYWdlIGZvby5iYXNlO1xuIgorICAgICJpbXBvcnQgXCJiYXNlLnByb3RvXCI7XG4iCisgICAgIm1lc3NhZ2UgcXV4IHtcbiIKKyAgICAiICBvcHRpb25hbCBiYXNlLmJhciBiYXogPSAxO1xuIgorICAgICIgIG9wdGlvbmFsIC5iYXNlLmJhciBxdXogPSAyO1xuIgorICAgICJ9XG4iLAorICAgICIzOjExOiBcImJhc2UuYmFyXCIgaXMgcmVzb2x2ZWQgdG8gXCJmb28uYmFzZS5iYXJcIiwiCisgICAgIiB3aGljaCBpcyBub3QgZGVmaW5lZC4gVGhlIGlubmVybW9zdCBzY29wZSBpcyBzZWFyY2hlZCBmaXJzdCAiCisgICAgImluIG5hbWUgcmVzb2x1dGlvbi4gQ29uc2lkZXIgdXNpbmcgYSBsZWFkaW5nICcuJyhpLmUuLCBcIi5iYXNlLmJhclwiKSIKKyAgICAiIHRvIHN0YXJ0IGZyb20gdGhlIG91dGVybW9zdCBzY29wZS5cbiIpOworfQorCitURVNUX0YoUGFyc2VyVmFsaWRhdGlvbkVycm9yVGVzdCwgUmVzb3ZsZWRVbmRlZmluZWRPcHRpb25FcnJvcikgeworICAvLyBCdWlsZCBkZXNjcmlwdG9yIG1lc3NhZ2UgaW4gdGVzdCBwb29sCisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZGVzY3JpcHRvcl9wcm90bzsKKyAgRGVzY3JpcHRvclByb3RvOjpkZXNjcmlwdG9yKCktPmZpbGUoKS0+Q29weVRvKCZkZXNjcmlwdG9yX3Byb3RvKTsKKyAgQVNTRVJUX1RSVUUocG9vbF8uQnVpbGRGaWxlKGRlc2NyaXB0b3JfcHJvdG8pICE9IE5VTEwpOworCisgIC8vIGJhc2UyLnByb3RvOgorICAvLyAgIHBhY2thZ2UgYmF6CisgIC8vICAgaW1wb3J0IGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvCisgIC8vICAgbWVzc2FnZSBCYXIgeyBvcHRpb25hbCBpbnQzMiBmb28gPSAxOyB9CisgIC8vICAgZXh0ZW5kIEZpbGVPcHRpb25zIHsgb3B0aW9uYWwgQmFyIGJhciA9IDc2NzI3NTc7IH0KKyAgRmlsZURlc2NyaXB0b3JQcm90byBvdGhlcl9maWxlOworICBvdGhlcl9maWxlLnNldF9uYW1lKCJiYXNlMi5wcm90byIpOworICBvdGhlcl9maWxlLnNldF9wYWNrYWdlKCJiYXoiKTsKKyAgb3RoZXJfZmlsZS5hZGRfZGVwZW5kZW5jeSgpOworICBvdGhlcl9maWxlLnNldF9kZXBlbmRlbmN5KDAsIGRlc2NyaXB0b3JfcHJvdG8ubmFtZSgpKTsKKworICBEZXNjcmlwdG9yUHJvdG8qIG1lc3NhZ2Uob3RoZXJfZmlsZS5hZGRfbWVzc2FnZV90eXBlKCkpOworICBtZXNzYWdlLT5zZXRfbmFtZSgiQmFyIik7CisgIEZpZWxkRGVzY3JpcHRvclByb3RvKiBmaWVsZChtZXNzYWdlLT5hZGRfZmllbGQoKSk7CisgIGZpZWxkLT5zZXRfbmFtZSgiZm9vIik7CisgIGZpZWxkLT5zZXRfbnVtYmVyKDEpOworICBmaWVsZC0+c2V0X2xhYmVsKEZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsX0xBQkVMX09QVElPTkFMKTsKKyAgZmllbGQtPnNldF90eXBlKEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfVFlQRV9JTlQzMik7CisKKyAgRmllbGREZXNjcmlwdG9yUHJvdG8qIGV4dGVuc2lvbihvdGhlcl9maWxlLmFkZF9leHRlbnNpb24oKSk7CisgIGV4dGVuc2lvbi0+c2V0X25hbWUoImJhciIpOworICBleHRlbnNpb24tPnNldF9udW1iZXIoNzY3Mjc1Nyk7CisgIGV4dGVuc2lvbi0+c2V0X2xhYmVsKEZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsX0xBQkVMX09QVElPTkFMKTsKKyAgZXh0ZW5zaW9uLT5zZXRfdHlwZShGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX1RZUEVfTUVTU0FHRSk7CisgIGV4dGVuc2lvbi0+c2V0X3R5cGVfbmFtZSgiQmFyIik7CisgIGV4dGVuc2lvbi0+c2V0X2V4dGVuZGVlKCJnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMiKTsKKworICBFWFBFQ1RfVFJVRShwb29sXy5CdWlsZEZpbGUob3RoZXJfZmlsZSkgIT0gTlVMTCk7CisKKyAgLy8gcXV4LnByb3RvOgorICAvLyAgIHBhY2thZ2UgcXV4LmJhegorICAvLyAgIG9wdGlvbiAoYmF6LmJhcikuZm9vID0gMTsKKyAgLy8KKyAgLy8gQWx0aG91Z2ggImJhei5iYXIiIGlzIGFscmVhZHkgZGVmaW5lZCwgdGhlIGxvb2t1cCBjb2RlIHdpbGwgdHJ5CisgIC8vICJxdXguYmF6LmJhciIsIHNpbmNlIGl0J3MgdGhlIG1hdGNoIGZyb20gdGhlIGlubmVybW9zdCBzY29wZSwKKyAgLy8gd2hpY2ggd2lsbCBjYXVzZSBhIHN5bWJvbCBub3QgZGVmaW5lZCBlcnJvci4KKyAgRXhwZWN0SGFzVmFsaWRhdGlvbkVycm9ycygKKyAgICAgICJwYWNrYWdlIHF1eC5iYXo7XG4iCisgICAgICAiaW1wb3J0IFwiYmFzZTIucHJvdG9cIjtcbiIKKyAgICAgICJvcHRpb24gKGJhei5iYXIpLmZvbyA9IDE7XG4iLAorICAgICAgIjI6NzogT3B0aW9uIFwiKGJhei5iYXIpXCIgaXMgcmVzb2x2ZWQgdG8gXCIocXV4LmJhei5iYXIpXCIsIgorICAgICAgIiB3aGljaCBpcyBub3QgZGVmaW5lZC4gVGhlIGlubmVybW9zdCBzY29wZSBpcyBzZWFyY2hlZCBmaXJzdCAiCisgICAgICAiaW4gbmFtZSByZXNvbHV0aW9uLiBDb25zaWRlciB1c2luZyBhIGxlYWRpbmcgJy4nKGkuZS4sIFwiKC5iYXouYmFyKVwiKSIKKyAgICAgICIgdG8gc3RhcnQgZnJvbSB0aGUgb3V0ZXJtb3N0IHNjb3BlLlxuIik7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKy8vIFRlc3QgdGhhdCB0aGUgb3V0cHV0IGZyb20gRmlsZURlc2NyaXB0b3I6OkRlYnVnU3RyaW5nKCkgKGFuZCBhbGwgb3RoZXIKKy8vIGRlc2NyaXB0b3IgdHlwZXMpIGlzIHBhcnNlYWJsZSwgYW5kIHJlc3VsdHMgaW4gdGhlIHNhbWUgRGVzY3JpcHRvcgorLy8gZGVmaW5pdGlvbnMgYWdhaW4gYWZvdGVyIHBhcnNpbmcgKG5vdGUsIGhvd2V2ZXIsIHRoYXQgdGhlIG9yZGVyIG9mIG1lc3NhZ2VzCisvLyBjYW5ub3QgYmUgZ3VhcmFudGVlZCB0byBiZSB0aGUgc2FtZSkKKwordHlwZWRlZiBQYXJzZXJUZXN0IFBhcnNlRGVzY3JpcHRvckRlYnVnVGVzdDsKKworY2xhc3MgQ29tcGFyZURlc2NyaXB0b3JOYW1lcyB7CisgcHVibGljOgorICBib29sIG9wZXJhdG9yKCkoY29uc3QgRGVzY3JpcHRvclByb3RvKiBsZWZ0LAorICAgICAgICAgICAgICAgICAgY29uc3QgRGVzY3JpcHRvclByb3RvKiByaWdodCkgY29uc3QgeworICAgIHJldHVybiBsZWZ0LT5uYW1lKCkgPCByaWdodC0+bmFtZSgpOworICB9Cit9OworCisvLyBTb3J0cyBuZXN0ZWQgRGVzY3JpcHRvclByb3RvcyBvZiBhIERlc2NyaXB0b1Byb3RvLCBieSBuYW1lLgordm9pZCBTb3J0TWVzc2FnZXMoRGVzY3JpcHRvclByb3RvICpkZXNjcmlwdG9yX3Byb3RvKSB7CisgIGludCBzaXplID0gZGVzY3JpcHRvcl9wcm90by0+bmVzdGVkX3R5cGVfc2l6ZSgpOworICAvLyByZWN1cnNpdmVseSBzb3J0OyB3ZSBjYW4ndCBndWFyYW50ZWUgdGhlIG9yZGVyIG9mIG5lc3RlZCBtZXNzYWdlcyBlaXRoZXIKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyArK2kpIHsKKyAgICBTb3J0TWVzc2FnZXMoZGVzY3JpcHRvcl9wcm90by0+bXV0YWJsZV9uZXN0ZWRfdHlwZShpKSk7CisgIH0KKyAgRGVzY3JpcHRvclByb3RvICoqZGF0YSA9CisgICAgZGVzY3JpcHRvcl9wcm90by0+bXV0YWJsZV9uZXN0ZWRfdHlwZSgpLT5tdXRhYmxlX2RhdGEoKTsKKyAgc3RkOjpzb3J0KGRhdGEsIGRhdGEgKyBzaXplLCBDb21wYXJlRGVzY3JpcHRvck5hbWVzKCkpOworfQorCisvLyBTb3J0cyBEZXNjcmlwdG9yUHJvdG9zIGJlbG9uZ2luZyB0byBhIEZpbGVEZXNjcmlwdG9yUHJvdG8sIGJ5IG5hbWUuCit2b2lkIFNvcnRNZXNzYWdlcyhGaWxlRGVzY3JpcHRvclByb3RvICpmaWxlX2Rlc2NyaXB0b3JfcHJvdG8pIHsKKyAgaW50IHNpemUgPSBmaWxlX2Rlc2NyaXB0b3JfcHJvdG8tPm1lc3NhZ2VfdHlwZV9zaXplKCk7CisgIC8vIHJlY3Vyc2l2ZWx5IHNvcnQ7IHdlIGNhbid0IGd1YXJhbnRlZSB0aGUgb3JkZXIgb2YgbmVzdGVkIG1lc3NhZ2VzIGVpdGhlcgorICBmb3IgKGludCBpID0gMDsgaSA8IHNpemU7ICsraSkgeworICAgIFNvcnRNZXNzYWdlcyhmaWxlX2Rlc2NyaXB0b3JfcHJvdG8tPm11dGFibGVfbWVzc2FnZV90eXBlKGkpKTsKKyAgfQorICBEZXNjcmlwdG9yUHJvdG8gKipkYXRhID0KKyAgICBmaWxlX2Rlc2NyaXB0b3JfcHJvdG8tPm11dGFibGVfbWVzc2FnZV90eXBlKCktPm11dGFibGVfZGF0YSgpOworICBzdGQ6OnNvcnQoZGF0YSwgZGF0YSArIHNpemUsIENvbXBhcmVEZXNjcmlwdG9yTmFtZXMoKSk7Cit9CisKKy8vIFN0cmlwcyB0aGUgbWVzc2FnZSBhbmQgZW51bSBmaWVsZCB0eXBlIG5hbWVzIGZvciBjb21wYXJpc29uIHB1cnBvc2Ugb25seS4KK3ZvaWQgU3RyaXBGaWVsZFR5cGVOYW1lKERlc2NyaXB0b3JQcm90byogcHJvdG8pIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBwcm90by0+ZmllbGRfc2l6ZSgpOyArK2kpIHsKKyAgICBzdHJpbmcgdHlwZV9uYW1lID0gcHJvdG8tPmZpZWxkKGkpLnR5cGVfbmFtZSgpOworICAgIHN0cmluZzo6c2l6ZV90eXBlIHBvcyA9IHR5cGVfbmFtZS5maW5kX2xhc3Rfb2YoIi4iKTsKKyAgICBpZiAocG9zICE9IHN0cmluZzo6bnBvcykgeworICAgICAgcHJvdG8tPm11dGFibGVfZmllbGQoaSktPm11dGFibGVfdHlwZV9uYW1lKCktPmFzc2lnbigKKyAgICAgICAgICB0eXBlX25hbWUuYmVnaW4oKSArIHBvcyArIDEsIHR5cGVfbmFtZS5lbmQoKSk7CisgICAgfQorICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgcHJvdG8tPm5lc3RlZF90eXBlX3NpemUoKTsgKytpKSB7CisgICAgU3RyaXBGaWVsZFR5cGVOYW1lKHByb3RvLT5tdXRhYmxlX25lc3RlZF90eXBlKGkpKTsKKyAgfQorfQorCit2b2lkIFN0cmlwRmllbGRUeXBlTmFtZShGaWxlRGVzY3JpcHRvclByb3RvKiBmaWxlX3Byb3RvKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV9wcm90by0+bWVzc2FnZV90eXBlX3NpemUoKTsgKytpKSB7CisgICAgU3RyaXBGaWVsZFR5cGVOYW1lKGZpbGVfcHJvdG8tPm11dGFibGVfbWVzc2FnZV90eXBlKGkpKTsKKyAgfQorfQorCitURVNUX0YoUGFyc2VEZXNjcmlwdG9yRGVidWdUZXN0LCBUZXN0QWxsRGVzY3JpcHRvclR5cGVzKSB7CisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBvcmlnaW5hbF9maWxlID0KKyAgICAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6ZGVzY3JpcHRvcigpLT5maWxlKCk7CisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZXhwZWN0ZWQ7CisgIG9yaWdpbmFsX2ZpbGUtPkNvcHlUbygmZXhwZWN0ZWQpOworCisgIC8vIEdldCB0aGUgRGVidWdTdHJpbmcgb2YgdGhlIHVuaXR0ZXN0LnByb3RvIEZpbGVEZWNyaXB0b3IsIHdoaWNoIGluY2x1ZGVzCisgIC8vIGFsbCBvdGhlciBkZXNjcmlwdG9yIHR5cGVzCisgIHN0cmluZyBkZWJ1Z19zdHJpbmcgPSBvcmlnaW5hbF9maWxlLT5EZWJ1Z1N0cmluZygpOworCisgIC8vIFBhcnNlIHRoZSBkZWJ1ZyBzdHJpbmcKKyAgU2V0dXBQYXJzZXIoZGVidWdfc3RyaW5nLmNfc3RyKCkpOworICBGaWxlRGVzY3JpcHRvclByb3RvIHBhcnNlZDsKKyAgcGFyc2VyXy0+UGFyc2UoaW5wdXRfLmdldCgpLCAmcGFyc2VkKTsKKyAgRVhQRUNUX0VRKGlvOjpUb2tlbml6ZXI6OlRZUEVfRU5ELCBpbnB1dF8tPmN1cnJlbnQoKS50eXBlKTsKKyAgQVNTRVJUX0VRKCIiLCBlcnJvcl9jb2xsZWN0b3JfLnRleHRfKQorICAgICAgPDwgIkZhaWxlZCB0byBwYXJzZTpcbiIgPDwgZGVidWdfc3RyaW5nOworCisgIC8vIFdlIG5vdyBoYXZlIGEgRmlsZURlc2NyaXB0b3JQcm90bywgYnV0IHRvIGNvbXBhcmUgd2l0aCB0aGUgZXhwZWN0ZWQgd2UKKyAgLy8gbmVlZCB0byBsaW5rIHRvIGEgRmlsZURlY3JpcHRvciwgdGhlbiBvdXRwdXQgYmFjayB0byBhIHByb3RvLiBXZSdsbAorICAvLyBhbHNvIG5lZWQgdG8gZ2l2ZSBpdCB0aGUgc2FtZSBuYW1lIGFzIHRoZSBvcmlnaW5hbC4KKyAgcGFyc2VkLnNldF9uYW1lKCJnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucHJvdG8iKTsKKyAgLy8gV2UgbmVlZCB0aGUgaW1wb3J0ZWQgZGVwZW5kZW5jeSBiZWZvcmUgd2UgY2FuIGJ1aWxkIG91ciBwYXJzZWQgcHJvdG8KKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIHB1YmxpY19pbXBvcnQgPQorICAgICAgcHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0OjpQdWJsaWNJbXBvcnRNZXNzYWdlOjpkZXNjcmlwdG9yKCktPmZpbGUoKTsKKyAgRmlsZURlc2NyaXB0b3JQcm90byBwdWJsaWNfaW1wb3J0X3Byb3RvOworICBwdWJsaWNfaW1wb3J0LT5Db3B5VG8oJnB1YmxpY19pbXBvcnRfcHJvdG8pOworICBBU1NFUlRfVFJVRShwb29sXy5CdWlsZEZpbGUocHVibGljX2ltcG9ydF9wcm90bykgIT0gTlVMTCk7CisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBpbXBvcnQgPQorICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydDo6SW1wb3J0TWVzc2FnZTo6ZGVzY3JpcHRvcigpLT5maWxlKCk7CisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gaW1wb3J0X3Byb3RvOworICBpbXBvcnQtPkNvcHlUbygmaW1wb3J0X3Byb3RvKTsKKyAgQVNTRVJUX1RSVUUocG9vbF8uQnVpbGRGaWxlKGltcG9ydF9wcm90bykgIT0gTlVMTCk7CisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBhY3R1YWwgPSBwb29sXy5CdWlsZEZpbGUocGFyc2VkKTsKKyAgcGFyc2VkLkNsZWFyKCk7CisgIEFTU0VSVF9UUlVFKGFjdHVhbCAhPSBOVUxMKQorICAgICAgPDwgIkZhaWxlZCB0byB2YWxpZGF0ZTpcbiIgPDwgZGVidWdfc3RyaW5nOworICBhY3R1YWwtPkNvcHlUbygmcGFyc2VkKTsKKyAgQVNTRVJUX1RSVUUoYWN0dWFsICE9IE5VTEwpOworCisgIC8vIFRoZSBtZXNzYWdlcyBtaWdodCBiZSBpbiBkaWZmZXJlbnQgb3JkZXJzLCBtYWtpbmcgdGhlbSBoYXJkIHRvIGNvbXBhcmUuCisgIC8vIFNvLCBzb3J0IHRoZSBtZXNzYWdlcyBpbiB0aGUgZGVzY3JpcHRvciBwcm90b3MgKGluY2x1ZGluZyBuZXN0ZWQgbWVzc2FnZXMsCisgIC8vIHJlY3Vyc2l2ZWx5KS4KKyAgU29ydE1lc3NhZ2VzKCZleHBlY3RlZCk7CisgIFNvcnRNZXNzYWdlcygmcGFyc2VkKTsKKworICAvLyBJIHJlYWxseSB3YW50ZWQgdG8gdXNlIFN0cmluZ0RpZmYgaGVyZSBmb3IgdGhlIGRlYnVnIG91dHB1dCBvbiBmYWlsLAorICAvLyBidXQgdGhlIHN0cmluZ3MgYXJlIHRvbyBsb25nIGZvciBpdCwgYW5kIGlmIEkgaW5jcmVhc2UgaXRzIG1heCBzaXplLAorICAvLyB3ZSBnZXQgYSBtZW1vcnkgYWxsb2NhdGlvbiBmYWlsdXJlIDooCisgIEVYUEVDVF9FUShleHBlY3RlZC5EZWJ1Z1N0cmluZygpLCBwYXJzZWQuRGVidWdTdHJpbmcoKSk7Cit9CisKK1RFU1RfRihQYXJzZURlc2NyaXB0b3JEZWJ1Z1Rlc3QsIFRlc3RDdXN0b21PcHRpb25zKSB7CisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBvcmlnaW5hbF9maWxlID0KKyAgICAgcHJvdG9idWZfdW5pdHRlc3Q6OkFnZ3JlZ2F0ZU1lc3NhZ2U6OmRlc2NyaXB0b3IoKS0+ZmlsZSgpOworICBGaWxlRGVzY3JpcHRvclByb3RvIGV4cGVjdGVkOworICBvcmlnaW5hbF9maWxlLT5Db3B5VG8oJmV4cGVjdGVkKTsKKworICBzdHJpbmcgZGVidWdfc3RyaW5nID0gb3JpZ2luYWxfZmlsZS0+RGVidWdTdHJpbmcoKTsKKworICAvLyBQYXJzZSB0aGUgZGVidWcgc3RyaW5nCisgIFNldHVwUGFyc2VyKGRlYnVnX3N0cmluZy5jX3N0cigpKTsKKyAgRmlsZURlc2NyaXB0b3JQcm90byBwYXJzZWQ7CisgIHBhcnNlcl8tPlBhcnNlKGlucHV0Xy5nZXQoKSwgJnBhcnNlZCk7CisgIEVYUEVDVF9FUShpbzo6VG9rZW5pemVyOjpUWVBFX0VORCwgaW5wdXRfLT5jdXJyZW50KCkudHlwZSk7CisgIEFTU0VSVF9FUSgiIiwgZXJyb3JfY29sbGVjdG9yXy50ZXh0Xyk7CisKKyAgLy8gV2Ugbm93IGhhdmUgYSBGaWxlRGVzY3JpcHRvclByb3RvLCBidXQgdG8gY29tcGFyZSB3aXRoIHRoZSBleHBlY3RlZCB3ZQorICAvLyBuZWVkIHRvIGxpbmsgdG8gYSBGaWxlRGVjcmlwdG9yLCB0aGVuIG91dHB1dCBiYWNrIHRvIGEgcHJvdG8uIFdlJ2xsCisgIC8vIGFsc28gbmVlZCB0byBnaXZlIGl0IHRoZSBzYW1lIG5hbWUgYXMgdGhlIG9yaWdpbmFsLgorICBwYXJzZWQuc2V0X25hbWUob3JpZ2luYWxfZmlsZS0+bmFtZSgpKTsKKworICAvLyB1bml0dGVzdF9jdXN0b21fb3B0aW9ucy5wcm90byBkZXBlbmRzIG9uIGRlc2NyaXB0b3IucHJvdG8uCisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBpbXBvcnQgPSBGaWxlRGVzY3JpcHRvclByb3RvOjpkZXNjcmlwdG9yKCktPmZpbGUoKTsKKyAgRmlsZURlc2NyaXB0b3JQcm90byBpbXBvcnRfcHJvdG87CisgIGltcG9ydC0+Q29weVRvKCZpbXBvcnRfcHJvdG8pOworICBBU1NFUlRfVFJVRShwb29sXy5CdWlsZEZpbGUoaW1wb3J0X3Byb3RvKSAhPSBOVUxMKTsKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGFjdHVhbCA9IHBvb2xfLkJ1aWxkRmlsZShwYXJzZWQpOworICBBU1NFUlRfVFJVRShhY3R1YWwgIT0gTlVMTCk7CisgIHBhcnNlZC5DbGVhcigpOworICBhY3R1YWwtPkNvcHlUbygmcGFyc2VkKTsKKworICAvLyBUaGUgbWVzc2FnZXMgbWlnaHQgYmUgaW4gZGlmZmVyZW50IG9yZGVycywgbWFraW5nIHRoZW0gaGFyZCB0byBjb21wYXJlLgorICAvLyBTbywgc29ydCB0aGUgbWVzc2FnZXMgaW4gdGhlIGRlc2NyaXB0b3IgcHJvdG9zIChpbmNsdWRpbmcgbmVzdGVkIG1lc3NhZ2VzLAorICAvLyByZWN1cnNpdmVseSkuCisgIFNvcnRNZXNzYWdlcygmZXhwZWN0ZWQpOworICBTb3J0TWVzc2FnZXMoJnBhcnNlZCk7CisKKyAgRVhQRUNUX0VRKGV4cGVjdGVkLkRlYnVnU3RyaW5nKCksIHBhcnNlZC5EZWJ1Z1N0cmluZygpKTsKK30KKworLy8gRW5zdXJlIHRoYXQgRGVidWdTdHJpbmdXaXRoT3B0aW9ucygpLCB3aXRoIHxpbmNsdWRlX2NvbW1lbnRzfCBzZXQgdG8gdHJ1ZSwKKy8vIGluY2x1ZGVzIGNvbW1lbnRzIGZyb20gdGhlIG9yaWdpbmFsIHBhcnNlciBpbnB1dCBpbiBhbGwgb2YgdGhlIGFwcHJvcHJpYXRlCisvLyBwbGFjZXMuCitURVNUX0YoUGFyc2VEZXNjcmlwdG9yRGVidWdUZXN0LCBUZXN0Q29tbWVudHNJbkRlYnVnU3RyaW5nKSB7CisgIFNldHVwUGFyc2VyKAorICAgICAgIi8vIERldGFjaGVkIGNvbW1lbnQgYmVmb3JlIHN5bnRheC5cbiIKKyAgICAgICJcbiIKKyAgICAgICIvLyBTeW50YXggY29tbWVudC5cbiIKKyAgICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAgICAgIlxuIgorICAgICAgIi8vIERldGFjaGVkIGNvbW1lbnQgYmVmb3JlIHBhY2thZ2UuXG4iCisgICAgICAiXG4iCisgICAgICAiLy8gUGFja2FnZSBjb21tZW50LlxuIgorICAgICAgInBhY2thZ2UgY29tbWVudF90ZXN0O1xuIgorICAgICAgIlxuIgorICAgICAgIi8vIERldGFjaGVkIGNvbW1lbnQgYmVmb3JlIFRlc3RNZXNzYWdlMS5cbiIKKyAgICAgICJcbiIKKyAgICAgICIvLyBNZXNzYWdlIGNvbW1lbnQuXG4iCisgICAgICAiLy9cbiIKKyAgICAgICIvLyBNb3JlIGRldGFpbCBpbiBtZXNzYWdlIGNvbW1lbnQuXG4iCisgICAgICAibWVzc2FnZSBUZXN0TWVzc2FnZTEge1xuIgorICAgICAgIlxuIgorICAgICAgIiAgLy8gRGV0YWNoZWQgY29tbWVudCBiZWZvcmUgZm9vLlxuIgorICAgICAgIlxuIgorICAgICAgIiAgLy8gRmllbGQgY29tbWVudC5cbiIKKyAgICAgICIgIG9wdGlvbmFsIGludDMyIGZvbyA9IDE7XG4iCisgICAgICAiXG4iCisgICAgICAiICAvLyBEZXRhY2hlZCBjb21tZW50IGJlZm9yZSBOZXN0ZWRNZXNzYWdlLlxuIgorICAgICAgIlxuIgorICAgICAgIiAgLy8gTmVzdGVkLW1lc3NhZ2UgY29tbWVudC5cbiIKKyAgICAgICIgIG1lc3NhZ2UgTmVzdGVkTWVzc2FnZSB7XG4iCisgICAgICAiICAgIG9wdGlvbmFsIGludDMyIGJhciA9IDE7XG4iCisgICAgICAiICB9XG4iCisgICAgICAifVxuIgorICAgICAgIlxuIgorICAgICAgIi8vIERldGFjaGVkIGNvbW1lbnQgYmVmb3JlIE15RW51bVR5cGUuXG4iCisgICAgICAiXG4iCisgICAgICAiLy8gRW51bSBjb21tZW50LlxuIgorICAgICAgImVudW0gTXlFbnVtVHlwZSB7XG4iCisgICAgICAiXG4iCisgICAgICAiICAvLyBEZXRhY2hlZCBjb21tZW50IGJlZm9yZSBBU0RGLlxuIgorICAgICAgIlxuIgorICAgICAgIiAgLy8gRW51bS12YWx1ZSBjb21tZW50LlxuIgorICAgICAgIiAgQVNERiA9IDE7XG4iCisgICAgICAifVxuIgorICAgICAgIlxuIgorICAgICAgIi8vIERldGFjaGVkIGNvbW1lbnQgYmVmb3JlIE15U2VydmljZS5cbiIKKyAgICAgICJcbiIKKyAgICAgICIvLyBTZXJ2aWNlIGNvbW1lbnQuXG4iCisgICAgICAic2VydmljZSBNeVNlcnZpY2Uge1xuIgorICAgICAgIlxuIgorICAgICAgIiAgLy8gRGV0YWNoZWQgY29tbWVudCBiZWZvcmUgTXlSUENDYWxsLlxuIgorICAgICAgIlxuIgorICAgICAgIiAgLy8gUlBDIGNvbW1lbnQuXG4iCisgICAgICAiICBycGMgTXlSUENDYWxsKFRlc3RNZXNzYWdlMSkgcmV0dXJucyAoVGVzdE1lc3NhZ2UxKSB7IH1cbiIKKyAgICAgICJ9XG4iKTsKKworICBGaWxlRGVzY3JpcHRvclByb3RvIHBhcnNlZF9kZXNjOworICBwYXJzZWRfZGVzYy5zZXRfbmFtZSgiZm9vLnByb3RvIik7CisgIFNvdXJjZUxvY2F0aW9uVGFibGUgc291cmNlX2xvY2F0aW9uczsKKyAgcGFyc2VyXy0+UmVjb3JkU291cmNlTG9jYXRpb25zVG8oJnNvdXJjZV9sb2NhdGlvbnMpOworICBwYXJzZXJfLT5QYXJzZShpbnB1dF8uZ2V0KCksICZwYXJzZWRfZGVzYyk7CisgIEVYUEVDVF9FUShpbzo6VG9rZW5pemVyOjpUWVBFX0VORCwgaW5wdXRfLT5jdXJyZW50KCkudHlwZSk7CisgIEFTU0VSVF9FUSgiIiwgZXJyb3JfY29sbGVjdG9yXy50ZXh0Xyk7CisKKyAgLy8gV2UgbmVlZCB0byBpbXBvcnQgdGhlIEZpbGVEZXNjcmlwdG9yUHJvdG8gdG8gZ2V0IGEgRmlsZURlc2NyaXB0b3IuCisgIE1vY2tWYWxpZGF0aW9uRXJyb3JDb2xsZWN0b3IgY29sbGVjdG9yKHNvdXJjZV9sb2NhdGlvbnMsICZlcnJvcl9jb2xsZWN0b3JfKTsKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPQorICAgICAgcG9vbF8uQnVpbGRGaWxlQ29sbGVjdGluZ0Vycm9ycyhwYXJzZWRfZGVzYywgJmNvbGxlY3Rvcik7CisgIEFTU0VSVF9UUlVFKGRlc2NyaXB0b3IgIT0gTlVMTCk7CisKKyAgLy8gRW5zdXJlIHRoYXQgZWFjaCBvZiB0aGUgY29tbWVudHMgYXBwZWFycyBzb21ld2hlcmUgaW4gdGhlIERlYnVnU3RyaW5nKCkuCisgIC8vIFdlIGRvbid0IHRlc3QgdGhlIGV4YWN0IGNvbW1lbnQgcGxhY2VtZW50IG9yIGZvcm1hdHRpbmcsIGJlY2F1c2Ugd2UgZG8gbm90CisgIC8vIHdhbnQgdG8gYmUgdG9vIGZyYWdpbGUgaGVyZS4KKyAgY29uc3QgY2hhciogZXhwZWN0ZWRfY29tbWVudHNbXSA9IHsKKyAgICAiRGV0YWNoZWQgY29tbWVudCBiZWZvcmUgc3ludGF4LiIsCisgICAgIlN5bnRheCBjb21tZW50LiIsCisgICAgIkRldGFjaGVkIGNvbW1lbnQgYmVmb3JlIHBhY2thZ2UuIiwKKyAgICAiUGFja2FnZSBjb21tZW50LiIsCisgICAgIkRldGFjaGVkIGNvbW1lbnQgYmVmb3JlIFRlc3RNZXNzYWdlMS4iLAorICAgICJNZXNzYWdlIGNvbW1lbnQuIiwKKyAgICAiTW9yZSBkZXRhaWwgaW4gbWVzc2FnZSBjb21tZW50LiIsCisgICAgIkRldGFjaGVkIGNvbW1lbnQgYmVmb3JlIGZvby4iLAorICAgICJGaWVsZCBjb21tZW50IiwKKyAgICAiRGV0YWNoZWQgY29tbWVudCBiZWZvcmUgTmVzdGVkTWVzc2FnZS4iLAorICAgICJOZXN0ZWQtbWVzc2FnZSBjb21tZW50IiwKKyAgICAiRGV0YWNoZWQgY29tbWVudCBiZWZvcmUgTXlFbnVtVHlwZS4iLAorICAgICJFbnVtIGNvbW1lbnQiLAorICAgICJEZXRhY2hlZCBjb21tZW50IGJlZm9yZSBBU0RGLiIsCisgICAgIkVudW0tdmFsdWUgY29tbWVudCIsCisgICAgIkRldGFjaGVkIGNvbW1lbnQgYmVmb3JlIE15U2VydmljZS4iLAorICAgICJTZXJ2aWNlIGNvbW1lbnQiLAorICAgICJEZXRhY2hlZCBjb21tZW50IGJlZm9yZSBNeVJQQ0NhbGwuIiwKKyAgICAiUlBDIGNvbW1lbnQiLAorICB9OworCisgIERlYnVnU3RyaW5nT3B0aW9ucyBkZWJ1Z19zdHJpbmdfb3B0aW9uczsKKyAgZGVidWdfc3RyaW5nX29wdGlvbnMuaW5jbHVkZV9jb21tZW50cyA9IHRydWU7CisKKyAgeworICAgIGNvbnN0IHN0cmluZyBkZWJ1Z19zdHJpbmcgPQorICAgICAgICBkZXNjcmlwdG9yLT5EZWJ1Z1N0cmluZ1dpdGhPcHRpb25zKGRlYnVnX3N0cmluZ19vcHRpb25zKTsKKworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgR09PR0xFX0FSUkFZU0laRShleHBlY3RlZF9jb21tZW50cyk7ICsraSkgeworICAgICAgc3RyaW5nOjpzaXplX3R5cGUgZm91bmRfcG9zID0gZGVidWdfc3RyaW5nLmZpbmQoZXhwZWN0ZWRfY29tbWVudHNbaV0pOworICAgICAgRVhQRUNUX1RSVUUoZm91bmRfcG9zICE9IHN0cmluZzo6bnBvcykKKyAgICAgICAgICA8PCAiXCIiIDw8IGV4cGVjdGVkX2NvbW1lbnRzW2ldIDw8ICJcIiBub3QgZm91bmQuIjsKKyAgICB9CisKKyAgICAvLyBSZXN1bHQgb2YgRGVidWdTdHJpbmdXaXRoT3B0aW9ucyBzaG91bGQgYmUgcGFyc2VhYmxlLgorICAgIFNldHVwUGFyc2VyKGRlYnVnX3N0cmluZy5jX3N0cigpKTsKKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIHBhcnNlZDsKKyAgICBwYXJzZXJfLT5QYXJzZShpbnB1dF8uZ2V0KCksICZwYXJzZWQpOworICAgIEVYUEVDVF9FUShpbzo6VG9rZW5pemVyOjpUWVBFX0VORCwgaW5wdXRfLT5jdXJyZW50KCkudHlwZSk7CisgICAgQVNTRVJUX0VRKCIiLCBlcnJvcl9jb2xsZWN0b3JfLnRleHRfKQorICAgICAgICA8PCAiRmFpbGVkIHRvIHBhcnNlOlxuIiA8PCBkZWJ1Z19zdHJpbmc7CisgIH0KKworfQorCitURVNUX0YoUGFyc2VEZXNjcmlwdG9yRGVidWdUZXN0LCBUZXN0TWFwcykgeworICBTZXR1cFBhcnNlcigKKyAgICAgICJzeW50YXggPSBcInByb3RvM1wiOyAiCisgICAgICAibWVzc2FnZSBGb28geyAiCisgICAgICAiICBtZXNzYWdlIEJhciB7IH0gIgorICAgICAgIiAgbWFwPGludDMyLCBCYXI+IGVudW1fbWVzc2FnZV9tYXAgPSAxOyAiCisgICAgICAiICBtYXA8c3RyaW5nLCBmbG9hdD4gcHJpbWl0aXZlX21hcCA9IDI7ICIKKyAgICAgICJ9ICIpOworICBGaWxlRGVzY3JpcHRvclByb3RvIG9yaWdpbmFsOworICBFWFBFQ1RfVFJVRShwYXJzZXJfLT5QYXJzZShpbnB1dF8uZ2V0KCksICZvcmlnaW5hbCkpOworICBvcmlnaW5hbC5zZXRfbmFtZSgiZm9vLnByb3RvIik7CisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlID0gcG9vbF8uQnVpbGRGaWxlKG9yaWdpbmFsKTsKKyAgQVNTRVJUX1RSVUUoZmlsZSAhPSBOVUxMKTsKKworICAvLyBNYWtlIHN1cmUgdGhlIGRlYnVnIHN0cmluZyB1c2VzIG1hcCBzeW50YXggYW5kIGRvZXMgbm90IGhhdmUgdGhlIGF1dG8KKyAgLy8gZ2VuZXJhdGVkIGVudHJ5LgorICBzdHJpbmcgZGVidWdfc3RyaW5nID0gZmlsZS0+RGVidWdTdHJpbmcoKTsKKyAgRVhQRUNUX1RSVUUoZGVidWdfc3RyaW5nLmZpbmQoIm1hcDwiKSAhPSBzdHJpbmc6Om5wb3MpOworICBFWFBFQ1RfVFJVRShkZWJ1Z19zdHJpbmcuZmluZCgib3B0aW9uIG1hcF9lbnRyeSIpID09IHN0cmluZzo6bnBvcyk7CisgIEVYUEVDVF9UUlVFKGRlYnVnX3N0cmluZy5maW5kKCJNYXBFbnRyeSIpID09IHN0cmluZzo6bnBvcyk7CisKKyAgLy8gTWFrZSBzdXJlIHRoZSBkZXNjcmlwdG9yIGRlYnVnIHN0cmluZyBpcyBwYXJzYWJsZS4KKyAgRmlsZURlc2NyaXB0b3JQcm90byBwYXJzZWQ7CisgIFNldHVwUGFyc2VyKGRlYnVnX3N0cmluZy5jX3N0cigpKTsKKyAgcGFyc2VkLnNldF9uYW1lKCJmb28ucHJvdG8iKTsKKyAgQVNTRVJUX1RSVUUocGFyc2VyXy0+UGFyc2UoaW5wdXRfLmdldCgpLCAmcGFyc2VkKSk7CisKKyAgb3JpZ2luYWwuY2xlYXJfc291cmNlX2NvZGVfaW5mbygpOworICBwYXJzZWQuY2xlYXJfc291cmNlX2NvZGVfaW5mbygpOworICBTdHJpcEZpZWxkVHlwZU5hbWUoJm9yaWdpbmFsKTsKKyAgU3RyaXBGaWVsZFR5cGVOYW1lKCZwYXJzZWQpOworICBFWFBFQ1RfRVEob3JpZ2luYWwuRGVidWdTdHJpbmcoKSwgcGFyc2VkLkRlYnVnU3RyaW5nKCkpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisvLyBTb3VyY2VDb2RlSW5mbyB0ZXN0cy4KKworLy8gRm9sbG93cyBhIHBhdGggLS0gYXMgZGVmaW5lZCBieSBTb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5wYXRoIC0tIGZyb20gYQorLy8gbWVzc2FnZSB0byBhIHBhcnRpY3VsYXIgc3ViLWZpZWxkLgorLy8gKiBJZiB0aGUgdGFyZ2V0IGlzIGl0c2VsZiBhIG1lc3NhZ2UsIHNldHMgKm91dHB1dF9tZXNzYWdlIHRvIHBvaW50IGF0IGl0LAorLy8gICAqb3V0cHV0X2ZpZWxkIHRvIE5VTEwsIGFuZCAqb3V0cHV0X2luZGV4IHRvIC0xLgorLy8gKiBPdGhlcndpc2UsIGlmIHRoZSB0YXJnZXQgaXMgYW4gZWxlbWVudCBvZiBhIHJlcGVhdGVkIGZpZWxkLCBzZXRzCisvLyAgICpvdXRwdXRfbWVzc2FnZSB0byB0aGUgY29udGFpbmluZyBtZXNzYWdlLCAqb3V0cHV0X2ZpZWxkIHRvIHRoZSBkZXNjcmlwdG9yCisvLyAgIG9mIHRoZSBmaWVsZCwgYW5kICpvdXRwdXRfaW5kZXggdG8gdGhlIGluZGV4IG9mIHRoZSBlbGVtZW50LgorLy8gKiBPdGhlcndpc2UsIHRoZSB0YXJnZXQgaXMgYSBmaWVsZCAocG9zc2libHkgYSByZXBlYXRlZCBmaWVsZCwgYnV0IG5vdCBhbnkKKy8vICAgb25lIGVsZW1lbnQpLiAgU2V0cyAqb3V0cHV0X21lc3NhZ2UgdG8gdGhlIGNvbnRhaW5pbmcgbWVzc2FnZSwKKy8vICAgKm91dHB1dF9maWVsZCB0byB0aGUgZGVzY3JpcHRvciBvZiB0aGUgZmllbGQsIGFuZCAqb3V0cHV0X2luZGV4IHRvIC0xLgorLy8gUmV0dXJucyB0cnVlIGlmIHRoZSBwYXRoIHdhcyB2YWxpZCwgZmFsc2Ugb3RoZXJ3aXNlLiAgQSBnVGVzdCBmYWlsdXJlIGlzCisvLyByZWNvcmRlZCBiZWZvcmUgcmV0dXJuaW5nIGZhbHNlLgorYm9vbCBGb2xsb3dQYXRoKGNvbnN0IE1lc3NhZ2UmIHJvb3QsCisgICAgICAgICAgICAgICAgY29uc3QgaW50KiBwYXRoX2JlZ2luLCBjb25zdCBpbnQqIHBhdGhfZW5kLAorICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2UqKiBvdXRwdXRfbWVzc2FnZSwKKyAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqKiBvdXRwdXRfZmllbGQsCisgICAgICAgICAgICAgICAgaW50KiBvdXRwdXRfaW5kZXgpIHsKKyAgaWYgKHBhdGhfYmVnaW4gPT0gcGF0aF9lbmQpIHsKKyAgICAvLyBQYXRoIHJlZmVycyB0byB0aGlzIHdob2xlIG1lc3NhZ2UuCisgICAgKm91dHB1dF9tZXNzYWdlID0gJnJvb3Q7CisgICAgKm91dHB1dF9maWVsZCA9IE5VTEw7CisgICAgKm91dHB1dF9pbmRleCA9IC0xOworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciA9IHJvb3QuR2V0RGVzY3JpcHRvcigpOworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gcm9vdC5HZXRSZWZsZWN0aW9uKCk7CisKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TnVtYmVyKCpwYXRoX2JlZ2luKTsKKworICBpZiAoZmllbGQgPT0gTlVMTCkgeworICAgIEFERF9GQUlMVVJFKCkgPDwgZGVzY3JpcHRvci0+bmFtZSgpIDw8ICIgaGFzIG5vIGZpZWxkIG51bWJlcjogIgorICAgICAgICAgICAgICAgICAgPDwgKnBhdGhfYmVnaW47CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgKytwYXRoX2JlZ2luOworCisgIGlmIChmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgeworICAgIGlmIChwYXRoX2JlZ2luID09IHBhdGhfZW5kKSB7CisgICAgICAvLyBQYXRoIHJlZmVycyB0byB0aGUgd2hvbGUgcmVwZWF0ZWQgZmllbGQuCisgICAgICAqb3V0cHV0X21lc3NhZ2UgPSAmcm9vdDsKKyAgICAgICpvdXRwdXRfZmllbGQgPSBmaWVsZDsKKyAgICAgICpvdXRwdXRfaW5kZXggPSAtMTsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIGludCBpbmRleCA9ICpwYXRoX2JlZ2luKys7CisgICAgaW50IHNpemUgPSByZWZsZWN0aW9uLT5GaWVsZFNpemUocm9vdCwgZmllbGQpOworCisgICAgaWYgKGluZGV4ID49IHNpemUpIHsKKyAgICAgIEFERF9GQUlMVVJFKCkgPDwgZGVzY3JpcHRvci0+bmFtZSgpIDw8ICIuIiA8PCBmaWVsZC0+bmFtZSgpCisgICAgICAgICAgICAgICAgICAgIDw8ICIgaGFzIHNpemUgIiA8PCBzaXplIDw8ICIsIGJ1dCBwYXRoIGNvbnRhaW5lZCBpbmRleDogIgorICAgICAgICAgICAgICAgICAgICA8PCBpbmRleDsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBpZiAoZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UpIHsKKyAgICAgIC8vIERlc2NlbmQgaW50byBjaGlsZCBtZXNzYWdlLgorICAgICAgY29uc3QgTWVzc2FnZSYgY2hpbGQgPSByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZE1lc3NhZ2Uocm9vdCwgZmllbGQsIGluZGV4KTsKKyAgICAgIHJldHVybiBGb2xsb3dQYXRoKGNoaWxkLCBwYXRoX2JlZ2luLCBwYXRoX2VuZCwKKyAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dF9tZXNzYWdlLCBvdXRwdXRfZmllbGQsIG91dHB1dF9pbmRleCk7CisgICAgfSBlbHNlIGlmIChwYXRoX2JlZ2luID09IHBhdGhfZW5kKSB7CisgICAgICAvLyBQYXRoIHJlZmVycyB0byB0aGlzIGVsZW1lbnQuCisgICAgICAqb3V0cHV0X21lc3NhZ2UgPSAmcm9vdDsKKyAgICAgICpvdXRwdXRfZmllbGQgPSBmaWVsZDsKKyAgICAgICpvdXRwdXRfaW5kZXggPSBpbmRleDsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0gZWxzZSB7CisgICAgICBBRERfRkFJTFVSRSgpIDw8IGRlc2NyaXB0b3ItPm5hbWUoKSA8PCAiLiIgPDwgZmllbGQtPm5hbWUoKQorICAgICAgICAgICAgICAgICAgICA8PCAiIGlzIG5vdCBhIG1lc3NhZ2U7IGNhbm5vdCBkZXNjZW5kIGludG8gaXQuIjsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgaWYgKGZpZWxkLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFKSB7CisgICAgICBjb25zdCBNZXNzYWdlJiBjaGlsZCA9IHJlZmxlY3Rpb24tPkdldE1lc3NhZ2Uocm9vdCwgZmllbGQpOworICAgICAgcmV0dXJuIEZvbGxvd1BhdGgoY2hpbGQsIHBhdGhfYmVnaW4sIHBhdGhfZW5kLAorICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0X21lc3NhZ2UsIG91dHB1dF9maWVsZCwgb3V0cHV0X2luZGV4KTsKKyAgICB9IGVsc2UgaWYgKHBhdGhfYmVnaW4gPT0gcGF0aF9lbmQpIHsKKyAgICAgIC8vIFBhdGggcmVmZXJzIHRvIHRoaXMgZmllbGQuCisgICAgICAqb3V0cHV0X21lc3NhZ2UgPSAmcm9vdDsKKyAgICAgICpvdXRwdXRfZmllbGQgPSBmaWVsZDsKKyAgICAgICpvdXRwdXRfaW5kZXggPSAtMTsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0gZWxzZSB7CisgICAgICBBRERfRkFJTFVSRSgpIDw8IGRlc2NyaXB0b3ItPm5hbWUoKSA8PCAiLiIgPDwgZmllbGQtPm5hbWUoKQorICAgICAgICAgICAgICAgICAgICA8PCAiIGlzIG5vdCBhIG1lc3NhZ2U7IGNhbm5vdCBkZXNjZW5kIGludG8gaXQuIjsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0KK30KKworLy8gQ2hlY2sgaWYgdHdvIHNwYW5zIGFyZSBlcXVhbC4KK2Jvb2wgQ29tcGFyZVNwYW5zKGNvbnN0IFJlcGVhdGVkRmllbGQ8aW50PiYgc3BhbjEsCisgICAgICAgICAgICAgICAgICBjb25zdCBSZXBlYXRlZEZpZWxkPGludD4mIHNwYW4yKSB7CisgIGlmIChzcGFuMS5zaXplKCkgIT0gc3BhbjIuc2l6ZSgpKSByZXR1cm4gZmFsc2U7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgc3BhbjEuc2l6ZSgpOyBpKyspIHsKKyAgICBpZiAoc3BhbjEuR2V0KGkpICE9IHNwYW4yLkdldChpKSkgcmV0dXJuIGZhbHNlOworICB9CisgIHJldHVybiB0cnVlOworfQorCisvLyBUZXN0IGZpeHR1cmUgZm9yIHNvdXJjZSBpbmZvIHRlc3RzLCB3aGljaCBjaGVjayB0aGF0IHNvdXJjZSBsb2NhdGlvbnMgYXJlCisvLyByZWNvcmRlZCBjb3JyZWN0bHkgaW4gRmlsZURlc2NyaXB0b3JQcm90by5zb3VyY2VfY29kZV9pbmZvLmxvY2F0aW9uLgorY2xhc3MgU291cmNlSW5mb1Rlc3QgOiBwdWJsaWMgUGFyc2VyVGVzdCB7CisgcHJvdGVjdGVkOgorICAvLyBUaGUgcGFyc2VkIGZpbGUgKGluaXRpYWxpemVkIGJ5IFBhcnNlKCkpLgorICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGVfOworCisgIC8vIFBhcnNlIHRoZSBnaXZlbiB0ZXh0IGFzIGEgLnByb3RvIGZpbGUgYW5kIHBvcHVsYXRlIHRoZSBzcGFuc18gbWFwIHdpdGgKKyAgLy8gYWxsIHRoZSBzb3VyY2UgbG9jYXRpb24gc3BhbnMgaW4gaXRzIFNvdXJjZUNvZGVJbmZvIHRhYmxlLgorICBib29sIFBhcnNlKGNvbnN0IGNoYXIqIHRleHQpIHsKKyAgICBFeHRyYWN0TWFya2Vycyh0ZXh0KTsKKyAgICBTZXR1cFBhcnNlcih0ZXh0X3dpdGhvdXRfbWFya2Vyc18uY19zdHIoKSk7CisgICAgaWYgKCFwYXJzZXJfLT5QYXJzZShpbnB1dF8uZ2V0KCksICZmaWxlXykpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBjb25zdCBTb3VyY2VDb2RlSW5mbyYgc291cmNlX2luZm8gPSBmaWxlXy5zb3VyY2VfY29kZV9pbmZvKCk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzb3VyY2VfaW5mby5sb2NhdGlvbl9zaXplKCk7IGkrKykgeworICAgICAgY29uc3QgU291cmNlQ29kZUluZm86OkxvY2F0aW9uJiBsb2NhdGlvbiA9IHNvdXJjZV9pbmZvLmxvY2F0aW9uKGkpOworICAgICAgY29uc3QgTWVzc2FnZSogZGVzY3JpcHRvcl9wcm90byA9IE5VTEw7CisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gTlVMTDsKKyAgICAgIGludCBpbmRleCA9IDA7CisgICAgICBpZiAoIUZvbGxvd1BhdGgoZmlsZV8sIGxvY2F0aW9uLnBhdGgoKS5iZWdpbigpLCBsb2NhdGlvbi5wYXRoKCkuZW5kKCksCisgICAgICAgICAgICAgICAgICAgICAgJmRlc2NyaXB0b3JfcHJvdG8sICZmaWVsZCwgJmluZGV4KSkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgIHNwYW5zXy5pbnNlcnQoCisgICAgICAgICAgc3RkOjptYWtlX3BhaXIoU3BhbktleSgqZGVzY3JpcHRvcl9wcm90bywgZmllbGQsIGluZGV4KSwgJmxvY2F0aW9uKSk7CisgICAgfQorCisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICB2aXJ0dWFsIHZvaWQgVGVhckRvd24oKSB7CisgICAgRVhQRUNUX1RSVUUoc3BhbnNfLmVtcHR5KCkpCisgICAgICAgIDw8ICJGb3Jnb3QgdG8gY2FsbCBIYXNTcGFuKCkgZm9yOlxuIgorICAgICAgICA8PCBzcGFuc18uYmVnaW4oKS0+c2Vjb25kLT5EZWJ1Z1N0cmluZygpOworICB9CisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgLy8gSGFzU3BhbigpIGNoZWNrcyB0aGF0IHRoZSBzcGFuIG9mIHNvdXJjZSBjb2RlIGRlbGltaXRlZCBieSB0aGUgZ2l2ZW4KKyAgLy8gdGFncyAoY29tbWVudHMpIGNvcnJlc3BvbmQgdmlhIHRoZSBTb3VyY2VDb2RlSW5mbyB0YWJsZSB0byB0aGUgZ2l2ZW4KKyAgLy8gcGFydCBvZiB0aGUgRmlsZURlc2NyaXB0b3JQcm90by4gIChJZiB1bmNsZWFyLCBsb29rIGF0IHRoZSBhY3R1YWwgdGVzdHM7CisgIC8vIGl0IHNob3VsZCBxdWlja2x5IGJlY29tZSBvYnZpb3VzLikKKworICBib29sIEhhc1NwYW4oY2hhciBzdGFydF9tYXJrZXIsIGNoYXIgZW5kX21hcmtlciwKKyAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2UmIGRlc2NyaXB0b3JfcHJvdG8pIHsKKyAgICByZXR1cm4gSGFzU3BhbldpdGhDb21tZW50KAorICAgICAgICBzdGFydF9tYXJrZXIsIGVuZF9tYXJrZXIsIGRlc2NyaXB0b3JfcHJvdG8sIE5VTEwsIC0xLCBOVUxMLCBOVUxMLCBOVUxMKTsKKyAgfQorCisgIGJvb2wgSGFzU3BhbldpdGhDb21tZW50KGNoYXIgc3RhcnRfbWFya2VyLCBjaGFyIGVuZF9tYXJrZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2UmIGRlc2NyaXB0b3JfcHJvdG8sCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIGV4cGVjdGVkX2xlYWRpbmdfY29tbWVudHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIGV4cGVjdGVkX3RyYWlsaW5nX2NvbW1lbnRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiBleHBlY3RlZF9sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKSB7CisgICAgcmV0dXJuIEhhc1NwYW5XaXRoQ29tbWVudCgKKyAgICAgICAgc3RhcnRfbWFya2VyLCBlbmRfbWFya2VyLCBkZXNjcmlwdG9yX3Byb3RvLCBOVUxMLCAtMSwKKyAgICAgICAgZXhwZWN0ZWRfbGVhZGluZ19jb21tZW50cywgZXhwZWN0ZWRfdHJhaWxpbmdfY29tbWVudHMsCisgICAgICAgIGV4cGVjdGVkX2xlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMpOworICB9CisKKyAgYm9vbCBIYXNTcGFuKGNoYXIgc3RhcnRfbWFya2VyLCBjaGFyIGVuZF9tYXJrZXIsCisgICAgICAgICAgICAgICBjb25zdCBNZXNzYWdlJiBkZXNjcmlwdG9yX3Byb3RvLCBjb25zdCBzdHJpbmcmIGZpZWxkX25hbWUpIHsKKyAgICByZXR1cm4gSGFzU3BhbihzdGFydF9tYXJrZXIsIGVuZF9tYXJrZXIsIGRlc2NyaXB0b3JfcHJvdG8sIGZpZWxkX25hbWUsIC0xKTsKKyAgfQorCisgIGJvb2wgSGFzU3BhbihjaGFyIHN0YXJ0X21hcmtlciwgY2hhciBlbmRfbWFya2VyLAorICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZSYgZGVzY3JpcHRvcl9wcm90bywgY29uc3Qgc3RyaW5nJiBmaWVsZF9uYW1lLAorICAgICAgICAgICAgICAgaW50IGluZGV4KSB7CisgICAgcmV0dXJuIEhhc1NwYW4oc3RhcnRfbWFya2VyLCBlbmRfbWFya2VyLCBkZXNjcmlwdG9yX3Byb3RvLAorICAgICAgICAgICAgICAgICAgIGZpZWxkX25hbWUsIGluZGV4LCBOVUxMLCBOVUxMLCBOVUxMKTsKKyAgfQorCisgIGJvb2wgSGFzU3BhbihjaGFyIHN0YXJ0X21hcmtlciwgY2hhciBlbmRfbWFya2VyLAorICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZSYgZGVzY3JpcHRvcl9wcm90bywKKyAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgZmllbGRfbmFtZSwgaW50IGluZGV4LAorICAgICAgICAgICAgICAgY29uc3QgY2hhciogZXhwZWN0ZWRfbGVhZGluZ19jb21tZW50cywKKyAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIGV4cGVjdGVkX3RyYWlsaW5nX2NvbW1lbnRzLAorICAgICAgICAgICAgICAgY29uc3QgY2hhciogZXhwZWN0ZWRfbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cykgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPQorICAgICAgICBkZXNjcmlwdG9yX3Byb3RvLkdldERlc2NyaXB0b3IoKS0+RmluZEZpZWxkQnlOYW1lKGZpZWxkX25hbWUpOworICAgIGlmIChmaWVsZCA9PSBOVUxMKSB7CisgICAgICBBRERfRkFJTFVSRSgpIDw8IGRlc2NyaXB0b3JfcHJvdG8uR2V0RGVzY3JpcHRvcigpLT5uYW1lKCkKKyAgICAgICAgICAgICAgICAgICAgPDwgIiBoYXMgbm8gc3VjaCBmaWVsZDogIiA8PCBmaWVsZF9uYW1lOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHJldHVybiBIYXNTcGFuV2l0aENvbW1lbnQoCisgICAgICAgIHN0YXJ0X21hcmtlciwgZW5kX21hcmtlciwgZGVzY3JpcHRvcl9wcm90bywgZmllbGQsIGluZGV4LAorICAgICAgICBleHBlY3RlZF9sZWFkaW5nX2NvbW1lbnRzLCBleHBlY3RlZF90cmFpbGluZ19jb21tZW50cywKKyAgICAgICAgZXhwZWN0ZWRfbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyk7CisgIH0KKworICBib29sIEhhc1NwYW4oY29uc3QgTWVzc2FnZSYgZGVzY3JpcHRvcl9wcm90bykgeworICAgIHJldHVybiBIYXNTcGFuV2l0aENvbW1lbnQoCisgICAgICAgICdcMCcsICdcMCcsIGRlc2NyaXB0b3JfcHJvdG8sIE5VTEwsIC0xLCBOVUxMLCBOVUxMLCBOVUxMKTsKKyAgfQorCisgIGJvb2wgSGFzU3Bhbihjb25zdCBNZXNzYWdlJiBkZXNjcmlwdG9yX3Byb3RvLCBjb25zdCBzdHJpbmcmIGZpZWxkX25hbWUpIHsKKyAgICByZXR1cm4gSGFzU3BhbignXDAnLCAnXDAnLCBkZXNjcmlwdG9yX3Byb3RvLCBmaWVsZF9uYW1lLCAtMSk7CisgIH0KKworICBib29sIEhhc1NwYW4oY29uc3QgTWVzc2FnZSYgZGVzY3JpcHRvcl9wcm90bywgY29uc3Qgc3RyaW5nJiBmaWVsZF9uYW1lLAorICAgICAgICAgICAgICAgaW50IGluZGV4KSB7CisgICAgcmV0dXJuIEhhc1NwYW4oJ1wwJywgJ1wwJywgZGVzY3JpcHRvcl9wcm90bywgZmllbGRfbmFtZSwgaW5kZXgpOworICB9CisKKyAgYm9vbCBIYXNTcGFuV2l0aENvbW1lbnQoCisgICAgICBjaGFyIHN0YXJ0X21hcmtlciwgY2hhciBlbmRfbWFya2VyLCBjb25zdCBNZXNzYWdlJiBkZXNjcmlwdG9yX3Byb3RvLAorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50IGluZGV4LAorICAgICAgY29uc3QgY2hhciogZXhwZWN0ZWRfbGVhZGluZ19jb21tZW50cywKKyAgICAgIGNvbnN0IGNoYXIqIGV4cGVjdGVkX3RyYWlsaW5nX2NvbW1lbnRzLAorICAgICAgY29uc3QgY2hhciogZXhwZWN0ZWRfbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cykgeworICAgIHBhaXI8U3Bhbk1hcDo6aXRlcmF0b3IsIFNwYW5NYXA6Oml0ZXJhdG9yPiByYW5nZSA9CisgICAgICAgIHNwYW5zXy5lcXVhbF9yYW5nZShTcGFuS2V5KGRlc2NyaXB0b3JfcHJvdG8sIGZpZWxkLCBpbmRleCkpOworCisgICAgaWYgKHN0YXJ0X21hcmtlciA9PSAnXDAnKSB7CisgICAgICBpZiAocmFuZ2UuZmlyc3QgPT0gcmFuZ2Uuc2Vjb25kKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNwYW5zXy5lcmFzZShyYW5nZS5maXJzdCk7CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICBwYWlyPGludCwgaW50PiBzdGFydF9wb3MgPSBGaW5kT3JEaWUobWFya2Vyc18sIHN0YXJ0X21hcmtlcik7CisgICAgICBwYWlyPGludCwgaW50PiBlbmRfcG9zID0gRmluZE9yRGllKG1hcmtlcnNfLCBlbmRfbWFya2VyKTsKKworICAgICAgUmVwZWF0ZWRGaWVsZDxpbnQ+IGV4cGVjdGVkX3NwYW47CisgICAgICBleHBlY3RlZF9zcGFuLkFkZChzdGFydF9wb3MuZmlyc3QpOworICAgICAgZXhwZWN0ZWRfc3Bhbi5BZGQoc3RhcnRfcG9zLnNlY29uZCk7CisgICAgICBpZiAoZW5kX3Bvcy5maXJzdCAhPSBzdGFydF9wb3MuZmlyc3QpIHsKKyAgICAgICAgZXhwZWN0ZWRfc3Bhbi5BZGQoZW5kX3Bvcy5maXJzdCk7CisgICAgICB9CisgICAgICBleHBlY3RlZF9zcGFuLkFkZChlbmRfcG9zLnNlY29uZCk7CisKKyAgICAgIGZvciAoU3Bhbk1hcDo6aXRlcmF0b3IgaXRlciA9IHJhbmdlLmZpcnN0OyBpdGVyICE9IHJhbmdlLnNlY29uZDsgKytpdGVyKSB7CisgICAgICAgIGlmIChDb21wYXJlU3BhbnMoZXhwZWN0ZWRfc3BhbiwgaXRlci0+c2Vjb25kLT5zcGFuKCkpKSB7CisgICAgICAgICAgaWYgKGV4cGVjdGVkX2xlYWRpbmdfY29tbWVudHMgPT0gTlVMTCkgeworICAgICAgICAgICAgRVhQRUNUX0ZBTFNFKGl0ZXItPnNlY29uZC0+aGFzX2xlYWRpbmdfY29tbWVudHMoKSk7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIEVYUEVDVF9UUlVFKGl0ZXItPnNlY29uZC0+aGFzX2xlYWRpbmdfY29tbWVudHMoKSk7CisgICAgICAgICAgICBFWFBFQ1RfRVEoZXhwZWN0ZWRfbGVhZGluZ19jb21tZW50cywKKyAgICAgICAgICAgICAgICAgICAgICBpdGVyLT5zZWNvbmQtPmxlYWRpbmdfY29tbWVudHMoKSk7CisgICAgICAgICAgfQorICAgICAgICAgIGlmIChleHBlY3RlZF90cmFpbGluZ19jb21tZW50cyA9PSBOVUxMKSB7CisgICAgICAgICAgICBFWFBFQ1RfRkFMU0UoaXRlci0+c2Vjb25kLT5oYXNfdHJhaWxpbmdfY29tbWVudHMoKSk7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIEVYUEVDVF9UUlVFKGl0ZXItPnNlY29uZC0+aGFzX3RyYWlsaW5nX2NvbW1lbnRzKCkpOworICAgICAgICAgICAgRVhQRUNUX0VRKGV4cGVjdGVkX3RyYWlsaW5nX2NvbW1lbnRzLAorICAgICAgICAgICAgICAgICAgICAgIGl0ZXItPnNlY29uZC0+dHJhaWxpbmdfY29tbWVudHMoKSk7CisgICAgICAgICAgfQorICAgICAgICAgIGlmIChleHBlY3RlZF9sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzID09IE5VTEwpIHsKKyAgICAgICAgICAgIEVYUEVDVF9FUSgwLCBpdGVyLT5zZWNvbmQtPmxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHNfc2l6ZSgpKTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgRVhQRUNUX0VRKAorICAgICAgICAgICAgICAgIGV4cGVjdGVkX2xlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMsCisgICAgICAgICAgICAgICAgSm9pbihpdGVyLT5zZWNvbmQtPmxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMoKSwgIlxuIikpOworICAgICAgICAgIH0KKworICAgICAgICAgIHNwYW5zXy5lcmFzZShpdGVyKTsKKyAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgfQorCisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICB9CisKKyBwcml2YXRlOgorICBzdHJ1Y3QgU3BhbktleSB7CisgICAgY29uc3QgTWVzc2FnZSogZGVzY3JpcHRvcl9wcm90bzsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkOworICAgIGludCBpbmRleDsKKworICAgIGlubGluZSBTcGFuS2V5KCkge30KKyAgICBpbmxpbmUgU3BhbktleShjb25zdCBNZXNzYWdlJiBkZXNjcmlwdG9yX3Byb3RvX3BhcmFtLAorICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGRfcGFyYW0sCisgICAgICAgICAgICAgICAgICAgaW50IGluZGV4X3BhcmFtKQorICAgICAgICA6IGRlc2NyaXB0b3JfcHJvdG8oJmRlc2NyaXB0b3JfcHJvdG9fcGFyYW0pLCBmaWVsZChmaWVsZF9wYXJhbSksCisgICAgICAgICAgaW5kZXgoaW5kZXhfcGFyYW0pIHt9CisKKyAgICBpbmxpbmUgYm9vbCBvcGVyYXRvcjwoY29uc3QgU3BhbktleSYgb3RoZXIpIGNvbnN0IHsKKyAgICAgIGlmIChkZXNjcmlwdG9yX3Byb3RvIDwgb3RoZXIuZGVzY3JpcHRvcl9wcm90bykgcmV0dXJuIHRydWU7CisgICAgICBpZiAoZGVzY3JpcHRvcl9wcm90byA+IG90aGVyLmRlc2NyaXB0b3JfcHJvdG8pIHJldHVybiBmYWxzZTsKKyAgICAgIGlmIChmaWVsZCA8IG90aGVyLmZpZWxkKSByZXR1cm4gdHJ1ZTsKKyAgICAgIGlmIChmaWVsZCA+IG90aGVyLmZpZWxkKSByZXR1cm4gZmFsc2U7CisgICAgICByZXR1cm4gaW5kZXggPCBvdGhlci5pbmRleDsKKyAgICB9CisgIH07CisKKyAgdHlwZWRlZiBtdWx0aW1hcDxTcGFuS2V5LCBjb25zdCBTb3VyY2VDb2RlSW5mbzo6TG9jYXRpb24qPiBTcGFuTWFwOworICBTcGFuTWFwIHNwYW5zXzsKKyAgbWFwPGNoYXIsIHBhaXI8aW50LCBpbnQ+ID4gbWFya2Vyc187CisgIHN0cmluZyB0ZXh0X3dpdGhvdXRfbWFya2Vyc187CisKKyAgdm9pZCBFeHRyYWN0TWFya2Vycyhjb25zdCBjaGFyKiB0ZXh0KSB7CisgICAgbWFya2Vyc18uY2xlYXIoKTsKKyAgICB0ZXh0X3dpdGhvdXRfbWFya2Vyc18uY2xlYXIoKTsKKyAgICBpbnQgbGluZSA9IDA7CisgICAgaW50IGNvbHVtbiA9IDA7CisgICAgd2hpbGUgKCp0ZXh0ICE9ICdcMCcpIHsKKyAgICAgIGlmICgqdGV4dCA9PSAnJCcpIHsKKyAgICAgICAgKyt0ZXh0OworICAgICAgICBHT09HTEVfQ0hFQ0tfTkUoJ1wwJywgKnRleHQpOworICAgICAgICBpZiAoKnRleHQgPT0gJyQnKSB7CisgICAgICAgICAgdGV4dF93aXRob3V0X21hcmtlcnNfICs9ICckJzsKKyAgICAgICAgICArK2NvbHVtbjsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBtYXJrZXJzX1sqdGV4dF0gPSBzdGQ6Om1ha2VfcGFpcihsaW5lLCBjb2x1bW4pOworICAgICAgICAgICsrdGV4dDsKKyAgICAgICAgICBHT09HTEVfQ0hFQ0tfRVEoJyQnLCAqdGV4dCk7CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSBpZiAoKnRleHQgPT0gJ1xuJykgeworICAgICAgICArK2xpbmU7CisgICAgICAgIGNvbHVtbiA9IDA7CisgICAgICAgIHRleHRfd2l0aG91dF9tYXJrZXJzXyArPSAqdGV4dDsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHRleHRfd2l0aG91dF9tYXJrZXJzXyArPSAqdGV4dDsKKyAgICAgICAgKytjb2x1bW47CisgICAgICB9CisgICAgICArK3RleHQ7CisgICAgfQorICB9Cit9OworCitURVNUX0YoU291cmNlSW5mb1Rlc3QsIEJhc2ljRmlsZURlY2xzKSB7CisgIEVYUEVDVF9UUlVFKFBhcnNlKAorICAgICAgIiRhJHN5bnRheCA9IFwicHJvdG8yXCI7JGkkXG4iCisgICAgICAicGFja2FnZSAkYiRmb28uYmFyJGMkO1xuIgorICAgICAgImltcG9ydCAkZCRcImJhei5wcm90b1wiJGUkO1xuIgorICAgICAgImltcG9ydCAkZiRcInF1eC5wcm90b1wiJGckOyRoJFxuIgorICAgICAgIlxuIgorICAgICAgIi8vIGNvbW1lbnQgaWdub3JlZFxuIikpOworCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2EnLCAnaCcsIGZpbGVfKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2InLCAnYycsIGZpbGVfLCAicGFja2FnZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignZCcsICdlJywgZmlsZV8sICJkZXBlbmRlbmN5IiwgMCkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdmJywgJ2cnLCBmaWxlXywgImRlcGVuZGVuY3kiLCAxKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2EnLCAnaScsIGZpbGVfLCAic3ludGF4IikpOworfQorCitURVNUX0YoU291cmNlSW5mb1Rlc3QsIE1lc3NhZ2VzKSB7CisgIEVYUEVDVF9UUlVFKFBhcnNlKAorICAgICAgIiRhJG1lc3NhZ2UgJGIkRm9vJGMkIHt9JGQkXG4iCisgICAgICAiJGUkbWVzc2FnZSAkZiRCYXIkZyQge30kaCRcbiIpKTsKKworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdhJywgJ2QnLCBmaWxlXy5tZXNzYWdlX3R5cGUoMCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignYicsICdjJywgZmlsZV8ubWVzc2FnZV90eXBlKDApLCAibmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignZScsICdoJywgZmlsZV8ubWVzc2FnZV90eXBlKDEpKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2YnLCAnZycsIGZpbGVfLm1lc3NhZ2VfdHlwZSgxKSwgIm5hbWUiKSk7CisKKyAgLy8gSWdub3JlIHRoZXNlLgorICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfKSk7Cit9CisKK1RFU1RfRihTb3VyY2VJbmZvVGVzdCwgRmllbGRzKSB7CisgIEVYUEVDVF9UUlVFKFBhcnNlKAorICAgICAgIm1lc3NhZ2UgRm9vIHtcbiIKKyAgICAgICIgICRhJG9wdGlvbmFsJGIkICRjJGludDMyJGQkICRlJGJhciRmJCA9ICRnJDEkaCQ7JGkkXG4iCisgICAgICAiICAkaiRyZXBlYXRlZCRrJCAkbCRYLlkkbSQgJG4kYmF6JG8kID0gJHAkMiRxJDskciRcbiIKKyAgICAgICJ9XG4iKSk7CisKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG8mIGZpZWxkMSA9IGZpbGVfLm1lc3NhZ2VfdHlwZSgwKS5maWVsZCgwKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG8mIGZpZWxkMiA9IGZpbGVfLm1lc3NhZ2VfdHlwZSgwKS5maWVsZCgxKTsKKworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdhJywgJ2knLCBmaWVsZDEpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignYScsICdiJywgZmllbGQxLCAibGFiZWwiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2MnLCAnZCcsIGZpZWxkMSwgInR5cGUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2UnLCAnZicsIGZpZWxkMSwgIm5hbWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2cnLCAnaCcsIGZpZWxkMSwgIm51bWJlciIpKTsKKworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdqJywgJ3InLCBmaWVsZDIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignaicsICdrJywgZmllbGQyLCAibGFiZWwiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2wnLCAnbScsIGZpZWxkMiwgInR5cGVfbmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignbicsICdvJywgZmllbGQyLCAibmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbigncCcsICdxJywgZmllbGQyLCAibnVtYmVyIikpOworCisgIC8vIElnbm9yZSB0aGVzZS4KKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXykpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfLm1lc3NhZ2VfdHlwZSgwKSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfLm1lc3NhZ2VfdHlwZSgwKSwgIm5hbWUiKSk7Cit9CisKK1RFU1RfRihTb3VyY2VJbmZvVGVzdCwgRXh0ZW5zaW9ucykgeworICBFWFBFQ1RfVFJVRShQYXJzZSgKKyAgICAgICIkYSRleHRlbmQgJGIkRm9vJGMkIHtcbiIKKyAgICAgICIgICRkJG9wdGlvbmFsJGUkIGludDMyIGJhciA9IDE7JGYkXG4iCisgICAgICAiICAkZyRyZXBlYXRlZCRoJCBYLlkgYmF6ID0gMjskaSRcbiIKKyAgICAgICJ9JGokXG4iCisgICAgICAiJGskZXh0ZW5kICRsJEJhciRtJCB7XG4iCisgICAgICAiICAkbiRvcHRpb25hbCBpbnQzMiBxdXggPSAxOyRvJFxuIgorICAgICAgIn0kcCRcbiIpKTsKKworICBjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90byYgZmllbGQxID0gZmlsZV8uZXh0ZW5zaW9uKDApOworICBjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90byYgZmllbGQyID0gZmlsZV8uZXh0ZW5zaW9uKDEpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90byYgZmllbGQzID0gZmlsZV8uZXh0ZW5zaW9uKDIpOworCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2EnLCAnaicsIGZpbGVfLCAiZXh0ZW5zaW9uIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdrJywgJ3AnLCBmaWxlXywgImV4dGVuc2lvbiIpKTsKKworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdkJywgJ2YnLCBmaWVsZDEpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignZCcsICdlJywgZmllbGQxLCAibGFiZWwiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2InLCAnYycsIGZpZWxkMSwgImV4dGVuZGVlIikpOworCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2cnLCAnaScsIGZpZWxkMikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdnJywgJ2gnLCBmaWVsZDIsICJsYWJlbCIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignYicsICdjJywgZmllbGQyLCAiZXh0ZW5kZWUiKSk7CisKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignbicsICdvJywgZmllbGQzKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2wnLCAnbScsIGZpZWxkMywgImV4dGVuZGVlIikpOworCisgIC8vIElnbm9yZSB0aGVzZS4KKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXykpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpZWxkMSwgInR5cGUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmllbGQxLCAibmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWVsZDEsICJudW1iZXIiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmllbGQyLCAidHlwZV9uYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpZWxkMiwgIm5hbWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmllbGQyLCAibnVtYmVyIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpZWxkMywgImxhYmVsIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpZWxkMywgInR5cGUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmllbGQzLCAibmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWVsZDMsICJudW1iZXIiKSk7Cit9CisKK1RFU1RfRihTb3VyY2VJbmZvVGVzdCwgTmVzdGVkRXh0ZW5zaW9ucykgeworICBFWFBFQ1RfVFJVRShQYXJzZSgKKyAgICAgICJtZXNzYWdlIE1lc3NhZ2Uge1xuIgorICAgICAgIiAgJGEkZXh0ZW5kICRiJEZvbyRjJCB7XG4iCisgICAgICAiICAgICRkJG9wdGlvbmFsJGUkIGludDMyIGJhciA9IDE7JGYkXG4iCisgICAgICAiICAgICRnJHJlcGVhdGVkJGgkIFguWSBiYXogPSAyOyRpJFxuIgorICAgICAgIiAgfSRqJFxuIgorICAgICAgIiAgJGskZXh0ZW5kICRsJEJhciRtJCB7XG4iCisgICAgICAiICAgICRuJG9wdGlvbmFsIGludDMyIHF1eCA9IDE7JG8kXG4iCisgICAgICAiICB9JHAkXG4iCisgICAgICAifVxuIikpOworCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvJiBmaWVsZDEgPSBmaWxlXy5tZXNzYWdlX3R5cGUoMCkuZXh0ZW5zaW9uKDApOworICBjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90byYgZmllbGQyID0gZmlsZV8ubWVzc2FnZV90eXBlKDApLmV4dGVuc2lvbigxKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG8mIGZpZWxkMyA9IGZpbGVfLm1lc3NhZ2VfdHlwZSgwKS5leHRlbnNpb24oMik7CisKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignYScsICdqJywgZmlsZV8ubWVzc2FnZV90eXBlKDApLCAiZXh0ZW5zaW9uIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdrJywgJ3AnLCBmaWxlXy5tZXNzYWdlX3R5cGUoMCksICJleHRlbnNpb24iKSk7CisKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignZCcsICdmJywgZmllbGQxKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2QnLCAnZScsIGZpZWxkMSwgImxhYmVsIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdiJywgJ2MnLCBmaWVsZDEsICJleHRlbmRlZSIpKTsKKworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdnJywgJ2knLCBmaWVsZDIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignZycsICdoJywgZmllbGQyLCAibGFiZWwiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2InLCAnYycsIGZpZWxkMiwgImV4dGVuZGVlIikpOworCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ24nLCAnbycsIGZpZWxkMykpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdsJywgJ20nLCBmaWVsZDMsICJleHRlbmRlZSIpKTsKKworICAvLyBJZ25vcmUgdGhlc2UuCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8pKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5tZXNzYWdlX3R5cGUoMCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5tZXNzYWdlX3R5cGUoMCksICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpZWxkMSwgInR5cGUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmllbGQxLCAibmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWVsZDEsICJudW1iZXIiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmllbGQyLCAidHlwZV9uYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpZWxkMiwgIm5hbWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmllbGQyLCAibnVtYmVyIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpZWxkMywgImxhYmVsIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpZWxkMywgInR5cGUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmllbGQzLCAibmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWVsZDMsICJudW1iZXIiKSk7Cit9CisKK1RFU1RfRihTb3VyY2VJbmZvVGVzdCwgRXh0ZW5zaW9uUmFuZ2VzKSB7CisgIEVYUEVDVF9UUlVFKFBhcnNlKAorICAgICAgIm1lc3NhZ2UgTWVzc2FnZSB7XG4iCisgICAgICAiICAkYSRleHRlbnNpb25zICRiJDEkYyQgdG8gJGQkNCRlJCwgJGYkNiRnJDskaCRcbiIKKyAgICAgICIgICRpJGV4dGVuc2lvbnMgJGokOCRrJCB0byAkbCRtYXgkbSQ7JG4kXG4iCisgICAgICAifVxuIikpOworCisgIGNvbnN0IERlc2NyaXB0b3JQcm90bzo6RXh0ZW5zaW9uUmFuZ2UmIHJhbmdlMSA9CisgICAgICBmaWxlXy5tZXNzYWdlX3R5cGUoMCkuZXh0ZW5zaW9uX3JhbmdlKDApOworICBjb25zdCBEZXNjcmlwdG9yUHJvdG86OkV4dGVuc2lvblJhbmdlJiByYW5nZTIgPQorICAgICAgZmlsZV8ubWVzc2FnZV90eXBlKDApLmV4dGVuc2lvbl9yYW5nZSgxKTsKKyAgY29uc3QgRGVzY3JpcHRvclByb3RvOjpFeHRlbnNpb25SYW5nZSYgcmFuZ2UzID0KKyAgICAgIGZpbGVfLm1lc3NhZ2VfdHlwZSgwKS5leHRlbnNpb25fcmFuZ2UoMik7CisKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignYScsICdoJywgZmlsZV8ubWVzc2FnZV90eXBlKDApLCAiZXh0ZW5zaW9uX3JhbmdlIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdpJywgJ24nLCBmaWxlXy5tZXNzYWdlX3R5cGUoMCksICJleHRlbnNpb25fcmFuZ2UiKSk7CisKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignYicsICdlJywgcmFuZ2UxKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2InLCAnYycsIHJhbmdlMSwgInN0YXJ0IikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdkJywgJ2UnLCByYW5nZTEsICJlbmQiKSk7CisKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignZicsICdnJywgcmFuZ2UyKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2YnLCAnZycsIHJhbmdlMiwgInN0YXJ0IikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdmJywgJ2cnLCByYW5nZTIsICJlbmQiKSk7CisKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignaicsICdtJywgcmFuZ2UzKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2onLCAnaycsIHJhbmdlMywgInN0YXJ0IikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdsJywgJ20nLCByYW5nZTMsICJlbmQiKSk7CisKKyAgLy8gSWdub3JlIHRoZXNlLgorICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8ubWVzc2FnZV90eXBlKDApKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8ubWVzc2FnZV90eXBlKDApLCAibmFtZSIpKTsKK30KKworVEVTVF9GKFNvdXJjZUluZm9UZXN0LCBPbmVvZnMpIHsKKyAgRVhQRUNUX1RSVUUoUGFyc2UoCisgICAgICAibWVzc2FnZSBGb28ge1xuIgorICAgICAgIiAgJGEkb25lb2YgJGMkZm9vJGQkIHtcbiIKKyAgICAgICIgICAgJGUkaW50MzIkZiQgJGckYSRoJCA9ICRpJDEkaiQ7JGskXG4iCisgICAgICAiICB9JHIkXG4iCisgICAgICAifVxuIikpOworCisgIGNvbnN0IE9uZW9mRGVzY3JpcHRvclByb3RvJiBvbmVvZl9kZWNsID0gZmlsZV8ubWVzc2FnZV90eXBlKDApLm9uZW9mX2RlY2woMCk7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvJiBmaWVsZCA9IGZpbGVfLm1lc3NhZ2VfdHlwZSgwKS5maWVsZCgwKTsKKworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdhJywgJ3InLCBvbmVvZl9kZWNsKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2MnLCAnZCcsIG9uZW9mX2RlY2wsICJuYW1lIikpOworCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2UnLCAnaycsIGZpZWxkKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2UnLCAnZicsIGZpZWxkLCAidHlwZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignZycsICdoJywgZmllbGQsICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdpJywgJ2onLCBmaWVsZCwgIm51bWJlciIpKTsKKworICAvLyBJZ25vcmUgdGhlc2UuCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8pKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5tZXNzYWdlX3R5cGUoMCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5tZXNzYWdlX3R5cGUoMCksICJuYW1lIikpOworfQorCitURVNUX0YoU291cmNlSW5mb1Rlc3QsIE5lc3RlZE1lc3NhZ2VzKSB7CisgIEVYUEVDVF9UUlVFKFBhcnNlKAorICAgICAgIm1lc3NhZ2UgRm9vIHtcbiIKKyAgICAgICIgICRhJG1lc3NhZ2UgJGIkQmFyJGMkIHtcbiIKKyAgICAgICIgICAgJGQkbWVzc2FnZSAkZSRCYXokZiQge30kZyRcbiIKKyAgICAgICIgIH0kaCRcbiIKKyAgICAgICIgICRpJG1lc3NhZ2UgJGokUXV4JGskIHt9JGwkXG4iCisgICAgICAifVxuIikpOworCisgIGNvbnN0IERlc2NyaXB0b3JQcm90byYgYmFyID0gZmlsZV8ubWVzc2FnZV90eXBlKDApLm5lc3RlZF90eXBlKDApOworICBjb25zdCBEZXNjcmlwdG9yUHJvdG8mIGJheiA9IGJhci5uZXN0ZWRfdHlwZSgwKTsKKyAgY29uc3QgRGVzY3JpcHRvclByb3RvJiBxdXggPSBmaWxlXy5tZXNzYWdlX3R5cGUoMCkubmVzdGVkX3R5cGUoMSk7CisKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignYScsICdoJywgYmFyKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2InLCAnYycsIGJhciwgIm5hbWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2QnLCAnZycsIGJheikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdlJywgJ2YnLCBiYXosICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdpJywgJ2wnLCBxdXgpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignaicsICdrJywgcXV4LCAibmFtZSIpKTsKKworICAvLyBJZ25vcmUgdGhlc2UuCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8pKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5tZXNzYWdlX3R5cGUoMCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5tZXNzYWdlX3R5cGUoMCksICJuYW1lIikpOworfQorCitURVNUX0YoU291cmNlSW5mb1Rlc3QsIEdyb3VwcykgeworICBFWFBFQ1RfVFJVRShQYXJzZSgKKyAgICAgICJtZXNzYWdlIEZvbyB7XG4iCisgICAgICAiICBtZXNzYWdlIEJhciB7fVxuIgorICAgICAgIiAgJGEkb3B0aW9uYWwkYiQgJGMkZ3JvdXAkZCQgJGUkQmF6JGYkID0gJGckMSRoJCB7XG4iCisgICAgICAiICAgICRpJG1lc3NhZ2UgUXV4IHt9JGokXG4iCisgICAgICAiICB9JGskXG4iCisgICAgICAifVxuIikpOworCisgIGNvbnN0IERlc2NyaXB0b3JQcm90byYgYmFyID0gZmlsZV8ubWVzc2FnZV90eXBlKDApLm5lc3RlZF90eXBlKDApOworICBjb25zdCBEZXNjcmlwdG9yUHJvdG8mIGJheiA9IGZpbGVfLm1lc3NhZ2VfdHlwZSgwKS5uZXN0ZWRfdHlwZSgxKTsKKyAgY29uc3QgRGVzY3JpcHRvclByb3RvJiBxdXggPSBiYXoubmVzdGVkX3R5cGUoMCk7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvJiBmaWVsZCA9IGZpbGVfLm1lc3NhZ2VfdHlwZSgwKS5maWVsZCgwKTsKKworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdhJywgJ2snLCBmaWVsZCkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdhJywgJ2InLCBmaWVsZCwgImxhYmVsIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdjJywgJ2QnLCBmaWVsZCwgInR5cGUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2UnLCAnZicsIGZpZWxkLCAibmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignZScsICdmJywgZmllbGQsICJ0eXBlX25hbWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2cnLCAnaCcsIGZpZWxkLCAibnVtYmVyIikpOworCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2EnLCAnaycsIGJheikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdlJywgJ2YnLCBiYXosICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdpJywgJ2onLCBxdXgpKTsKKworICAvLyBJZ25vcmUgdGhlc2UuCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8pKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5tZXNzYWdlX3R5cGUoMCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5tZXNzYWdlX3R5cGUoMCksICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGJhcikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGJhciwgIm5hbWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4ocXV4LCAibmFtZSIpKTsKK30KKworVEVTVF9GKFNvdXJjZUluZm9UZXN0LCBFbnVtcykgeworICBFWFBFQ1RfVFJVRShQYXJzZSgKKyAgICAgICIkYSRlbnVtICRiJEZvbyRjJCB7fSRkJFxuIgorICAgICAgIiRlJGVudW0gJGYkQmFyJGckIHt9JGgkXG4iKSk7CisKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignYScsICdkJywgZmlsZV8uZW51bV90eXBlKDApKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2InLCAnYycsIGZpbGVfLmVudW1fdHlwZSgwKSwgIm5hbWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2UnLCAnaCcsIGZpbGVfLmVudW1fdHlwZSgxKSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdmJywgJ2cnLCBmaWxlXy5lbnVtX3R5cGUoMSksICJuYW1lIikpOworCisgIC8vIElnbm9yZSB0aGVzZS4KKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXykpOworfQorCitURVNUX0YoU291cmNlSW5mb1Rlc3QsIEVudW1WYWx1ZXMpIHsKKyAgRVhQRUNUX1RSVUUoUGFyc2UoCisgICAgICAiZW51bSBGb28ge1xuIgorICAgICAgIiAgJGEkQkFSJGIkID0gJGMkMSRkJDskZSRcbiIKKyAgICAgICIgICRmJEJBWiRnJCA9ICRoJDIkaSQ7JGokXG4iCisgICAgICAifSIpKTsKKworICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8mIGJhciA9IGZpbGVfLmVudW1fdHlwZSgwKS52YWx1ZSgwKTsKKyAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvJiBiYXogPSBmaWxlXy5lbnVtX3R5cGUoMCkudmFsdWUoMSk7CisKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignYScsICdlJywgYmFyKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2EnLCAnYicsIGJhciwgIm5hbWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2MnLCAnZCcsIGJhciwgIm51bWJlciIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignZicsICdqJywgYmF6KSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2YnLCAnZycsIGJheiwgIm5hbWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2gnLCAnaScsIGJheiwgIm51bWJlciIpKTsKKworICAvLyBJZ25vcmUgdGhlc2UuCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8pKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5lbnVtX3R5cGUoMCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5lbnVtX3R5cGUoMCksICJuYW1lIikpOworfQorCitURVNUX0YoU291cmNlSW5mb1Rlc3QsIE5lc3RlZEVudW1zKSB7CisgIEVYUEVDVF9UUlVFKFBhcnNlKAorICAgICAgIm1lc3NhZ2UgRm9vIHtcbiIKKyAgICAgICIgICRhJGVudW0gJGIkQmFyJGMkIHt9JGQkXG4iCisgICAgICAiICAkZSRlbnVtICRmJEJheiRnJCB7fSRoJFxuIgorICAgICAgIn1cbiIpKTsKKworICBjb25zdCBFbnVtRGVzY3JpcHRvclByb3RvJiBiYXIgPSBmaWxlXy5tZXNzYWdlX3R5cGUoMCkuZW51bV90eXBlKDApOworICBjb25zdCBFbnVtRGVzY3JpcHRvclByb3RvJiBiYXogPSBmaWxlXy5tZXNzYWdlX3R5cGUoMCkuZW51bV90eXBlKDEpOworCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2EnLCAnZCcsIGJhcikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdiJywgJ2MnLCBiYXIsICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdlJywgJ2gnLCBiYXopKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignZicsICdnJywgYmF6LCAibmFtZSIpKTsKKworICAvLyBJZ25vcmUgdGhlc2UuCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8pKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5tZXNzYWdlX3R5cGUoMCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5tZXNzYWdlX3R5cGUoMCksICJuYW1lIikpOworfQorCitURVNUX0YoU291cmNlSW5mb1Rlc3QsIFNlcnZpY2VzKSB7CisgIEVYUEVDVF9UUlVFKFBhcnNlKAorICAgICAgIiRhJHNlcnZpY2UgJGIkRm9vJGMkIHt9JGQkXG4iCisgICAgICAiJGUkc2VydmljZSAkZiRCYXIkZyQge30kaCRcbiIpKTsKKworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdhJywgJ2QnLCBmaWxlXy5zZXJ2aWNlKDApKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2InLCAnYycsIGZpbGVfLnNlcnZpY2UoMCksICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdlJywgJ2gnLCBmaWxlXy5zZXJ2aWNlKDEpKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2YnLCAnZycsIGZpbGVfLnNlcnZpY2UoMSksICJuYW1lIikpOworCisgIC8vIElnbm9yZSB0aGVzZS4KKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXykpOworfQorCitURVNUX0YoU291cmNlSW5mb1Rlc3QsIE1ldGhvZHNBbmRTdHJlYW1zKSB7CisgIEVYUEVDVF9UUlVFKFBhcnNlKAorICAgICAgInNlcnZpY2UgRm9vIHtcbiIKKyAgICAgICIgICRhJHJwYyAkYiRCYXIkYyQoJGQkWCRlJCkgcmV0dXJucygkZiRZJGckKTskaCQiCisgICAgICAiICAkaSRycGMgJGokQmF6JGskKCRsJFokbSQpIHJldHVybnMoJG4kVyRvJCk7JHAkIgorICAgICAgIn0iKSk7CisKKyAgY29uc3QgTWV0aG9kRGVzY3JpcHRvclByb3RvJiBiYXIgPSBmaWxlXy5zZXJ2aWNlKDApLm1ldGhvZCgwKTsKKyAgY29uc3QgTWV0aG9kRGVzY3JpcHRvclByb3RvJiBiYXogPSBmaWxlXy5zZXJ2aWNlKDApLm1ldGhvZCgxKTsKKworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdhJywgJ2gnLCBiYXIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignYicsICdjJywgYmFyLCAibmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignZCcsICdlJywgYmFyLCAiaW5wdXRfdHlwZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignZicsICdnJywgYmFyLCAib3V0cHV0X3R5cGUiKSk7CisKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignaScsICdwJywgYmF6KSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2onLCAnaycsIGJheiwgIm5hbWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2wnLCAnbScsIGJheiwgImlucHV0X3R5cGUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ24nLCAnbycsIGJheiwgIm91dHB1dF90eXBlIikpOworCisgIC8vIElnbm9yZSB0aGVzZS4KKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXykpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfLnNlcnZpY2UoMCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5zZXJ2aWNlKDApLCAibmFtZSIpKTsKK30KKworCitURVNUX0YoU291cmNlSW5mb1Rlc3QsIE9wdGlvbnMpIHsKKyAgRVhQRUNUX1RSVUUoUGFyc2UoCisgICAgICAiJGEkb3B0aW9uICRiJGZvbyRjJC4kZCQoJGUkYmFyLmJheiRmJCkkZyQgPSAiCisgICAgICAgICAgIiRoJDEyMyRpJDskaiRcbiIKKyAgICAgICIkayRvcHRpb24gcXV4ID0gJGwkLTEyMyRtJDskbiRcbiIKKyAgICAgICIkbyRvcHRpb24gY29yZ2UgPSAkcCRhYmMkcSQ7JHIkXG4iCisgICAgICAiJHMkb3B0aW9uIGdyYXVsdCA9ICR0JCdibGFoJyR1JDskdiRcbiIKKyAgICAgICIkdyRvcHRpb24gZ2FycGx5ID0gJHgkeyB5YWRkYSB5YWRkYSB9JHkkOyR6JFxuIgorICAgICAgIiQwJG9wdGlvbiB3YWxkbyA9ICQxJDEyMy4wJDIkOyQzJFxuIgorICApKTsKKworICBjb25zdCBVbmludGVycHJldGVkT3B0aW9uJiBvcHRpb24xID0gZmlsZV8ub3B0aW9ucygpLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKDApOworICBjb25zdCBVbmludGVycHJldGVkT3B0aW9uJiBvcHRpb24yID0gZmlsZV8ub3B0aW9ucygpLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKDEpOworICBjb25zdCBVbmludGVycHJldGVkT3B0aW9uJiBvcHRpb24zID0gZmlsZV8ub3B0aW9ucygpLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKDIpOworICBjb25zdCBVbmludGVycHJldGVkT3B0aW9uJiBvcHRpb240ID0gZmlsZV8ub3B0aW9ucygpLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKDMpOworICBjb25zdCBVbmludGVycHJldGVkT3B0aW9uJiBvcHRpb241ID0gZmlsZV8ub3B0aW9ucygpLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKDQpOworICBjb25zdCBVbmludGVycHJldGVkT3B0aW9uJiBvcHRpb242ID0gZmlsZV8ub3B0aW9ucygpLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKDUpOworCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2EnLCAnaicsIGZpbGVfLm9wdGlvbnMoKSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdhJywgJ2onLCBvcHRpb24xKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2InLCAnZycsIG9wdGlvbjEsICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdiJywgJ2MnLCBvcHRpb24xLm5hbWUoMCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignYicsICdjJywgb3B0aW9uMS5uYW1lKDApLCAibmFtZV9wYXJ0IikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdkJywgJ2cnLCBvcHRpb24xLm5hbWUoMSkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignZScsICdmJywgb3B0aW9uMS5uYW1lKDEpLCAibmFtZV9wYXJ0IikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdoJywgJ2knLCBvcHRpb24xLCAicG9zaXRpdmVfaW50X3ZhbHVlIikpOworCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2snLCAnbicsIGZpbGVfLm9wdGlvbnMoKSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdsJywgJ20nLCBvcHRpb24yLCAibmVnYXRpdmVfaW50X3ZhbHVlIikpOworCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ28nLCAncicsIGZpbGVfLm9wdGlvbnMoKSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdwJywgJ3EnLCBvcHRpb24zLCAiaWRlbnRpZmllcl92YWx1ZSIpKTsKKworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdzJywgJ3YnLCBmaWxlXy5vcHRpb25zKCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbigndCcsICd1Jywgb3B0aW9uNCwgInN0cmluZ192YWx1ZSIpKTsKKworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCd3JywgJ3onLCBmaWxlXy5vcHRpb25zKCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbigneCcsICd5Jywgb3B0aW9uNSwgImFnZ3JlZ2F0ZV92YWx1ZSIpKTsKKworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCcwJywgJzMnLCBmaWxlXy5vcHRpb25zKCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignMScsICcyJywgb3B0aW9uNiwgImRvdWJsZV92YWx1ZSIpKTsKKworICAvLyBJZ25vcmUgdGhlc2UuCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8pKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihvcHRpb24yKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4ob3B0aW9uMykpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKG9wdGlvbjQpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihvcHRpb241KSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4ob3B0aW9uNikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKG9wdGlvbjIsICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKG9wdGlvbjMsICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKG9wdGlvbjQsICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKG9wdGlvbjUsICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKG9wdGlvbjYsICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKG9wdGlvbjIubmFtZSgwKSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKG9wdGlvbjMubmFtZSgwKSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKG9wdGlvbjQubmFtZSgwKSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKG9wdGlvbjUubmFtZSgwKSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKG9wdGlvbjYubmFtZSgwKSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKG9wdGlvbjIubmFtZSgwKSwgIm5hbWVfcGFydCIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihvcHRpb24zLm5hbWUoMCksICJuYW1lX3BhcnQiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4ob3B0aW9uNC5uYW1lKDApLCAibmFtZV9wYXJ0IikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKG9wdGlvbjUubmFtZSgwKSwgIm5hbWVfcGFydCIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihvcHRpb242Lm5hbWUoMCksICJuYW1lX3BhcnQiKSk7Cit9CisKK1RFU1RfRihTb3VyY2VJbmZvVGVzdCwgU2NvcGVkT3B0aW9ucykgeworICBFWFBFQ1RfVFJVRShQYXJzZSgKKyAgICAibWVzc2FnZSBGb28ge1xuIgorICAgICIgICRhJG9wdGlvbiBtb3B0ID0gMTskYiRcbiIKKyAgICAifVxuIgorICAgICJlbnVtIEJhciB7XG4iCisgICAgIiAgJGMkb3B0aW9uIGVvcHQgPSAxOyRkJFxuIgorICAgICJ9XG4iCisgICAgInNlcnZpY2UgQmF6IHtcbiIKKyAgICAiICAkZSRvcHRpb24gc29wdCA9IDE7JGYkXG4iCisgICAgIiAgcnBjIE0oWCkgcmV0dXJucyhZKSB7XG4iCisgICAgIiAgICAkZyRvcHRpb24gbW9wdCA9IDE7JGgkXG4iCisgICAgIiAgfVxuIgorICAgICIgIHJwYyBNUzQoJDEkc3RyZWFtJDIkIFgpIHJldHVybnMoJDMkc3RyZWFtJDQkIFkpIHtcbiIKKyAgICAiICAgICRrJG9wdGlvbiBtb3B0ID0gMTskbCRcbiIKKyAgICAiICB9XG4iCisgICAgIn1cbiIpKTsKKworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdhJywgJ2InLCBmaWxlXy5tZXNzYWdlX3R5cGUoMCkub3B0aW9ucygpKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2MnLCAnZCcsIGZpbGVfLmVudW1fdHlwZSgwKS5vcHRpb25zKCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignZScsICdmJywgZmlsZV8uc2VydmljZSgwKS5vcHRpb25zKCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignZycsICdoJywgZmlsZV8uc2VydmljZSgwKS5tZXRob2QoMCkub3B0aW9ucygpKSk7CisKKyAgLy8gSWdub3JlIHRoZXNlLgorICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8ubWVzc2FnZV90eXBlKDApKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8ubWVzc2FnZV90eXBlKDApLCAibmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5tZXNzYWdlX3R5cGUoMCkub3B0aW9ucygpCisgICAgICAgICAgICAgICAgICAgICAgLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKDApKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8ubWVzc2FnZV90eXBlKDApLm9wdGlvbnMoKQorICAgICAgICAgICAgICAgICAgICAgIC51bmludGVycHJldGVkX29wdGlvbigwKSwgIm5hbWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8ubWVzc2FnZV90eXBlKDApLm9wdGlvbnMoKQorICAgICAgICAgICAgICAgICAgICAgIC51bmludGVycHJldGVkX29wdGlvbigwKS5uYW1lKDApKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8ubWVzc2FnZV90eXBlKDApLm9wdGlvbnMoKQorICAgICAgICAgICAgICAgICAgICAgIC51bmludGVycHJldGVkX29wdGlvbigwKS5uYW1lKDApLCAibmFtZV9wYXJ0IikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfLm1lc3NhZ2VfdHlwZSgwKS5vcHRpb25zKCkKKyAgICAgICAgICAgICAgICAgICAgICAudW5pbnRlcnByZXRlZF9vcHRpb24oMCksICJwb3NpdGl2ZV9pbnRfdmFsdWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8uZW51bV90eXBlKDApKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8uZW51bV90eXBlKDApLCAibmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5lbnVtX3R5cGUoMCkub3B0aW9ucygpCisgICAgICAgICAgICAgICAgICAgICAgLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKDApKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8uZW51bV90eXBlKDApLm9wdGlvbnMoKQorICAgICAgICAgICAgICAgICAgICAgIC51bmludGVycHJldGVkX29wdGlvbigwKSwgIm5hbWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8uZW51bV90eXBlKDApLm9wdGlvbnMoKQorICAgICAgICAgICAgICAgICAgICAgIC51bmludGVycHJldGVkX29wdGlvbigwKS5uYW1lKDApKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8uZW51bV90eXBlKDApLm9wdGlvbnMoKQorICAgICAgICAgICAgICAgICAgICAgIC51bmludGVycHJldGVkX29wdGlvbigwKS5uYW1lKDApLCAibmFtZV9wYXJ0IikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfLmVudW1fdHlwZSgwKS5vcHRpb25zKCkKKyAgICAgICAgICAgICAgICAgICAgICAudW5pbnRlcnByZXRlZF9vcHRpb24oMCksICJwb3NpdGl2ZV9pbnRfdmFsdWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8uc2VydmljZSgwKSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfLnNlcnZpY2UoMCksICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfLnNlcnZpY2UoMCkubWV0aG9kKDApKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8uc2VydmljZSgwKS5vcHRpb25zKCkKKyAgICAgICAgICAgICAgICAgICAgICAudW5pbnRlcnByZXRlZF9vcHRpb24oMCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5zZXJ2aWNlKDApLm9wdGlvbnMoKQorICAgICAgICAgICAgICAgICAgICAgIC51bmludGVycHJldGVkX29wdGlvbigwKSwgIm5hbWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8uc2VydmljZSgwKS5vcHRpb25zKCkKKyAgICAgICAgICAgICAgICAgICAgICAudW5pbnRlcnByZXRlZF9vcHRpb24oMCkubmFtZSgwKSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfLnNlcnZpY2UoMCkub3B0aW9ucygpCisgICAgICAgICAgICAgICAgICAgICAgLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKDApLm5hbWUoMCksICJuYW1lX3BhcnQiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8uc2VydmljZSgwKS5vcHRpb25zKCkKKyAgICAgICAgICAgICAgICAgICAgICAudW5pbnRlcnByZXRlZF9vcHRpb24oMCksICJwb3NpdGl2ZV9pbnRfdmFsdWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8uc2VydmljZSgwKS5tZXRob2QoMCksICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfLnNlcnZpY2UoMCkubWV0aG9kKDApLCAiaW5wdXRfdHlwZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5zZXJ2aWNlKDApLm1ldGhvZCgwKSwgIm91dHB1dF90eXBlIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfLnNlcnZpY2UoMCkubWV0aG9kKDApLm9wdGlvbnMoKQorICAgICAgICAgICAgICAgICAgICAgIC51bmludGVycHJldGVkX29wdGlvbigwKSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfLnNlcnZpY2UoMCkubWV0aG9kKDApLm9wdGlvbnMoKQorICAgICAgICAgICAgICAgICAgICAgIC51bmludGVycHJldGVkX29wdGlvbigwKSwgIm5hbWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8uc2VydmljZSgwKS5tZXRob2QoMCkub3B0aW9ucygpCisgICAgICAgICAgICAgICAgICAgICAgLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKDApLm5hbWUoMCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5zZXJ2aWNlKDApLm1ldGhvZCgwKS5vcHRpb25zKCkKKyAgICAgICAgICAgICAgICAgICAgICAudW5pbnRlcnByZXRlZF9vcHRpb24oMCkubmFtZSgwKSwgIm5hbWVfcGFydCIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5zZXJ2aWNlKDApLm1ldGhvZCgwKS5vcHRpb25zKCkKKyAgICAgICAgICAgICAgICAgICAgICAudW5pbnRlcnByZXRlZF9vcHRpb24oMCksICJwb3NpdGl2ZV9pbnRfdmFsdWUiKSk7CisKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignaycsICdsJywgZmlsZV8uc2VydmljZSgwKS5tZXRob2QoMSkub3B0aW9ucygpKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8uc2VydmljZSgwKS5tZXRob2QoMSkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5zZXJ2aWNlKDApLm1ldGhvZCgxKSwgIm5hbWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8uc2VydmljZSgwKS5tZXRob2QoMSksICJpbnB1dF90eXBlIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfLnNlcnZpY2UoMCkubWV0aG9kKDEpLCAib3V0cHV0X3R5cGUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8uc2VydmljZSgwKS5tZXRob2QoMSkub3B0aW9ucygpCisgICAgICAgICAgICAgICAgICAgICAgLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKDApKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8uc2VydmljZSgwKS5tZXRob2QoMSkub3B0aW9ucygpCisgICAgICAgICAgICAgICAgICAgICAgLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKDApLCAibmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5zZXJ2aWNlKDApLm1ldGhvZCgxKS5vcHRpb25zKCkKKyAgICAgICAgICAgICAgICAgICAgICAudW5pbnRlcnByZXRlZF9vcHRpb24oMCkubmFtZSgwKSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfLnNlcnZpY2UoMCkubWV0aG9kKDEpLm9wdGlvbnMoKQorICAgICAgICAgICAgICAgICAgICAgIC51bmludGVycHJldGVkX29wdGlvbigwKS5uYW1lKDApLCAibmFtZV9wYXJ0IikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfLnNlcnZpY2UoMCkubWV0aG9kKDEpLm9wdGlvbnMoKQorICAgICAgICAgICAgICAgICAgICAgIC51bmludGVycHJldGVkX29wdGlvbigwKSwgInBvc2l0aXZlX2ludF92YWx1ZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignMScsICcyJywgZmlsZV8uc2VydmljZSgwKS5tZXRob2QoMSksCisgICAgICAgICAgICAgICAgICAgICAgImNsaWVudF9zdHJlYW1pbmciKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJzMnLCAnNCcsIGZpbGVfLnNlcnZpY2UoMCkubWV0aG9kKDEpLAorICAgICAgICAgICAgICAgICAgICAgICJzZXJ2ZXJfc3RyZWFtaW5nIikpOworfQorCitURVNUX0YoU291cmNlSW5mb1Rlc3QsIEZpZWxkT3B0aW9ucykgeworICAvLyBUaGUgYWN0dWFsICJuYW1lID0gdmFsdWUiIHBhaXJzIGFyZSBwYXJzZWQgYnkgdGhlIHNhbWUgY29kZSBhcyBmb3IKKyAgLy8gdG9wLWxldmVsIG9wdGlvbnMgc28gd2Ugd29uJ3QgcmUtdGVzdCB0aGF0IC0tIGp1c3QgbWFrZSBzdXJlIHRoYXQgdGhlCisgIC8vIHN5bnRheCB1c2VkIGZvciBmaWVsZCBvcHRpb25zIGlzIHVuZGVyc3Rvb2QuCisgIEVYUEVDVF9UUlVFKFBhcnNlKAorICAgICAgIm1lc3NhZ2UgRm9vIHsiCisgICAgICAiICBvcHRpb25hbCBpbnQzMiBiYXIgPSAxICIKKyAgICAgICAgICAiJGEkW2RlZmF1bHQ9JGIkMTIzJGMkLCRkJG9wdDE9MTIzJGUkLCIKKyAgICAgICAgICAiJGYkb3B0Mj0naGknJGckXSRoJDsiCisgICAgICAifVxuIgorICApKTsKKworICBjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90byYgZmllbGQgPSBmaWxlXy5tZXNzYWdlX3R5cGUoMCkuZmllbGQoMCk7CisgIGNvbnN0IFVuaW50ZXJwcmV0ZWRPcHRpb24mIG9wdGlvbjEgPSBmaWVsZC5vcHRpb25zKCkudW5pbnRlcnByZXRlZF9vcHRpb24oMCk7CisgIGNvbnN0IFVuaW50ZXJwcmV0ZWRPcHRpb24mIG9wdGlvbjIgPSBmaWVsZC5vcHRpb25zKCkudW5pbnRlcnByZXRlZF9vcHRpb24oMSk7CisKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignYScsICdoJywgZmllbGQub3B0aW9ucygpKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2InLCAnYycsIGZpZWxkLCAiZGVmYXVsdF92YWx1ZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbignZCcsICdlJywgb3B0aW9uMSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdmJywgJ2cnLCBvcHRpb24yKSk7CisKKyAgLy8gSWdub3JlIHRoZXNlLgorICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8ubWVzc2FnZV90eXBlKDApKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8ubWVzc2FnZV90eXBlKDApLCAibmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWVsZCkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpZWxkLCAibGFiZWwiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmllbGQsICJ0eXBlIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpZWxkLCAibmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWVsZCwgIm51bWJlciIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihvcHRpb24xLCAibmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihvcHRpb24yLCAibmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihvcHRpb24xLm5hbWUoMCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihvcHRpb24yLm5hbWUoMCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihvcHRpb24xLm5hbWUoMCksICJuYW1lX3BhcnQiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4ob3B0aW9uMi5uYW1lKDApLCAibmFtZV9wYXJ0IikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKG9wdGlvbjEsICJwb3NpdGl2ZV9pbnRfdmFsdWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4ob3B0aW9uMiwgInN0cmluZ192YWx1ZSIpKTsKK30KKworVEVTVF9GKFNvdXJjZUluZm9UZXN0LCBFbnVtVmFsdWVPcHRpb25zKSB7CisgIC8vIFRoZSBhY3R1YWwgIm5hbWUgPSB2YWx1ZSIgcGFpcnMgYXJlIHBhcnNlZCBieSB0aGUgc2FtZSBjb2RlIGFzIGZvcgorICAvLyB0b3AtbGV2ZWwgb3B0aW9ucyBzbyB3ZSB3b24ndCByZS10ZXN0IHRoYXQgLS0ganVzdCBtYWtlIHN1cmUgdGhhdCB0aGUKKyAgLy8gc3ludGF4IHVzZWQgZm9yIGVudW0gb3B0aW9ucyBpcyB1bmRlcnN0b29kLgorICBFWFBFQ1RfVFJVRShQYXJzZSgKKyAgICAgICJlbnVtIEZvbyB7IgorICAgICAgIiAgQkFSID0gMSAkYSRbJGIkb3B0MT0xMjMkYyQsJGQkb3B0Mj0naGknJGUkXSRmJDsiCisgICAgICAifVxuIgorICApKTsKKworICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8mIHZhbHVlID0gZmlsZV8uZW51bV90eXBlKDApLnZhbHVlKDApOworICBjb25zdCBVbmludGVycHJldGVkT3B0aW9uJiBvcHRpb24xID0gdmFsdWUub3B0aW9ucygpLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKDApOworICBjb25zdCBVbmludGVycHJldGVkT3B0aW9uJiBvcHRpb24yID0gdmFsdWUub3B0aW9ucygpLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKDEpOworCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2EnLCAnZicsIHZhbHVlLm9wdGlvbnMoKSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdiJywgJ2MnLCBvcHRpb24xKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2QnLCAnZScsIG9wdGlvbjIpKTsKKworICAvLyBJZ25vcmUgdGhlc2UuCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8pKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5lbnVtX3R5cGUoMCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXy5lbnVtX3R5cGUoMCksICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKHZhbHVlKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4odmFsdWUsICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKHZhbHVlLCAibnVtYmVyIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKG9wdGlvbjEsICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKG9wdGlvbjIsICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKG9wdGlvbjEubmFtZSgwKSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKG9wdGlvbjIubmFtZSgwKSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKG9wdGlvbjEubmFtZSgwKSwgIm5hbWVfcGFydCIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihvcHRpb24yLm5hbWUoMCksICJuYW1lX3BhcnQiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4ob3B0aW9uMSwgInBvc2l0aXZlX2ludF92YWx1ZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihvcHRpb24yLCAic3RyaW5nX3ZhbHVlIikpOworfQorCitURVNUX0YoU291cmNlSW5mb1Rlc3QsIERvY0NvbW1lbnRzKSB7CisgIEVYUEVDVF9UUlVFKFBhcnNlKAorICAgICAgIi8vIEZvbyBsZWFkaW5nXG4iCisgICAgICAiLy8gbGluZSAyXG4iCisgICAgICAiJGEkbWVzc2FnZSBGb28ge1xuIgorICAgICAgIiAgLy8gRm9vIHRyYWlsaW5nXG4iCisgICAgICAiICAvLyBsaW5lIDJcbiIKKyAgICAgICJcbiIKKyAgICAgICIgIC8vIGRldGFjaGVkXG4iCisgICAgICAiXG4iCisgICAgICAiICAvLyBiYXIgbGVhZGluZ1xuIgorICAgICAgIiAgJGIkb3B0aW9uYWwgaW50MzIgYmFyID0gMTskYyRcbiIKKyAgICAgICIgIC8vIGJhciB0cmFpbGluZ1xuIgorICAgICAgIn0kZCRcbiIKKyAgICAgICIvLyBpZ25vcmVkXG4iCisgICkpOworCisgIGNvbnN0IERlc2NyaXB0b3JQcm90byYgZm9vID0gZmlsZV8ubWVzc2FnZV90eXBlKDApOworICBjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90byYgYmFyID0gZm9vLmZpZWxkKDApOworCisgIEVYUEVDVF9UUlVFKEhhc1NwYW5XaXRoQ29tbWVudCgnYScsICdkJywgZm9vLAorICAgICAgIiBGb28gbGVhZGluZ1xuIGxpbmUgMlxuIiwKKyAgICAgICIgRm9vIHRyYWlsaW5nXG4gbGluZSAyXG4iLAorICAgICAgTlVMTCkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuV2l0aENvbW1lbnQoJ2InLCAnYycsIGJhciwKKyAgICAgICIgYmFyIGxlYWRpbmdcbiIsCisgICAgICAiIGJhciB0cmFpbGluZ1xuIiwKKyAgICAgICIgZGV0YWNoZWRcbiIpKTsKKworICAvLyBJZ25vcmUgdGhlc2UuCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8pKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3Bhbihmb28sICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGJhciwgImxhYmVsIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGJhciwgInR5cGUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oYmFyLCAibmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihiYXIsICJudW1iZXIiKSk7Cit9CisKK1RFU1RfRihTb3VyY2VJbmZvVGVzdCwgRG9jQ29tbWVudHMyKSB7CisgIEVYUEVDVF9UUlVFKFBhcnNlKAorICAgICAgIi8vIGRldGFjaGVkIGJlZm9yZSBtZXNzYWdlLlxuIgorICAgICAgIlxuIgorICAgICAgIi8vIEZvbyBsZWFkaW5nXG4iCisgICAgICAiLy8gbGluZSAyXG4iCisgICAgICAiJGEkbWVzc2FnZSBGb28ge1xuIgorICAgICAgIiAgLyogRm9vIHRyYWlsaW5nXG4iCisgICAgICAiICAgKiBsaW5lIDIgKi9cbiIKKyAgICAgICIgIC8vIGRldGFjaGVkXG4iCisgICAgICAiICAvKiBiYXIgbGVhZGluZ1xuIgorICAgICAgIiAgICovIgorICAgICAgIiAgJGIkb3B0aW9uYWwgaW50MzIgYmFyID0gMTskYyQgIC8vIGJhciB0cmFpbGluZ1xuIgorICAgICAgIiAgLy8gaWdub3JlZCBkZXRhY2hlZFxuIgorICAgICAgIn0kZCRcbiIKKyAgICAgICIvLyBpZ25vcmVkXG4iCisgICAgICAiXG4iCisgICAgICAiLy8gZGV0YWNoZWQgYmVmb3JlIG9wdGlvblxuIgorICAgICAgIlxuIgorICAgICAgIi8vIG9wdGlvbiBsZWFkaW5nXG4iCisgICAgICAiJGUkb3B0aW9uIGJheiA9IDEyMzskZiRcbiIKKyAgICAgICIvLyBvcHRpb24gdHJhaWxpbmdcbiIKKyAgKSk7CisKKyAgY29uc3QgRGVzY3JpcHRvclByb3RvJiBmb28gPSBmaWxlXy5tZXNzYWdlX3R5cGUoMCk7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvJiBiYXIgPSBmb28uZmllbGQoMCk7CisgIGNvbnN0IFVuaW50ZXJwcmV0ZWRPcHRpb24mIGJheiA9IGZpbGVfLm9wdGlvbnMoKS51bmludGVycHJldGVkX29wdGlvbigwKTsKKworICBFWFBFQ1RfVFJVRShIYXNTcGFuV2l0aENvbW1lbnQoJ2EnLCAnZCcsIGZvbywKKyAgICAgICIgRm9vIGxlYWRpbmdcbiBsaW5lIDJcbiIsCisgICAgICAiIEZvbyB0cmFpbGluZ1xuIGxpbmUgMiAiLAorICAgICAgIiBkZXRhY2hlZCBiZWZvcmUgbWVzc2FnZS5cbiIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbldpdGhDb21tZW50KCdiJywgJ2MnLCBiYXIsCisgICAgICAiIGJhciBsZWFkaW5nXG4iLAorICAgICAgIiBiYXIgdHJhaWxpbmdcbiIsCisgICAgICAiIGRldGFjaGVkXG4iKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW5XaXRoQ29tbWVudCgnZScsICdmJywgYmF6LAorICAgICAgIiBvcHRpb24gbGVhZGluZ1xuIiwKKyAgICAgICIgb3B0aW9uIHRyYWlsaW5nXG4iLAorICAgICAgIiBkZXRhY2hlZCBiZWZvcmUgb3B0aW9uXG4iKSk7CisKKyAgLy8gSWdub3JlIHRoZXNlLgorICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZm9vLCAibmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihiYXIsICJsYWJlbCIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihiYXIsICJ0eXBlIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGJhciwgIm5hbWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oYmFyLCAibnVtYmVyIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGZpbGVfLm9wdGlvbnMoKSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGJheiwgIm5hbWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oYmF6Lm5hbWUoMCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihiYXoubmFtZSgwKSwgIm5hbWVfcGFydCIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihiYXosICJwb3NpdGl2ZV9pbnRfdmFsdWUiKSk7Cit9CisKK1RFU1RfRihTb3VyY2VJbmZvVGVzdCwgRG9jQ29tbWVudHMzKSB7CisgIEVYUEVDVF9UUlVFKFBhcnNlKAorICAgICAgIiRhJG1lc3NhZ2UgRm9vIHtcbiIKKyAgICAgICIgIC8vIGJhciBsZWFkaW5nXG4iCisgICAgICAiICAkYiRvcHRpb25hbCBpbnQzMiBiYXIgPSAxIFsoYmF6LnF1eCkgPSB7fV07JGMkXG4iCisgICAgICAiICAvLyBiYXIgdHJhaWxpbmdcbiIKKyAgICAgICJ9JGQkXG4iCisgICAgICAiLy8gaWdub3JlZFxuIgorICApKTsKKworICBjb25zdCBEZXNjcmlwdG9yUHJvdG8mIGZvbyA9IGZpbGVfLm1lc3NhZ2VfdHlwZSgwKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG8mIGJhciA9IGZvby5maWVsZCgwKTsKKworICBFWFBFQ1RfVFJVRShIYXNTcGFuV2l0aENvbW1lbnQoJ2InLCAnYycsIGJhciwKKyAgICAgICIgYmFyIGxlYWRpbmdcbiIsCisgICAgICAiIGJhciB0cmFpbGluZ1xuIiwKKyAgICAgIE5VTEwpKTsKKworICAvLyBJZ25vcmUgdGhlc2UuCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8pKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3Bhbihmb28pKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3Bhbihmb28sICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGJhciwgImxhYmVsIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGJhciwgInR5cGUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oYmFyLCAibmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihiYXIsICJudW1iZXIiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oYmFyLm9wdGlvbnMoKSkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGJhci5vcHRpb25zKCkudW5pbnRlcnByZXRlZF9vcHRpb24oMCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihiYXIub3B0aW9ucygpLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKDApLCAibmFtZSIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihiYXIub3B0aW9ucygpLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKDApLm5hbWUoMCkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbigKKyAgICAgIGJhci5vcHRpb25zKCkudW5pbnRlcnByZXRlZF9vcHRpb24oMCkubmFtZSgwKSwgIm5hbWVfcGFydCIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3BhbigKKyAgICAgIGJhci5vcHRpb25zKCkudW5pbnRlcnByZXRlZF9vcHRpb24oMCksICJhZ2dyZWdhdGVfdmFsdWUiKSk7Cit9CisKK1RFU1RfRihTb3VyY2VJbmZvVGVzdCwgRG9jQ29tbWVudHNUb3BMZXZlbCkgeworICBFWFBFQ1RfVFJVRShQYXJzZSgKKyAgICAgICIvLyBkZXRhY2hlZCBiZWZvcmUgc3ludGF4IHBhcmFncmFwaCAxXG4iCisgICAgICAiXG4iCisgICAgICAiLy8gZGV0YWNoZWQgYmVmb3JlIHN5bnRheCBwYXJhZ3JhcGggMlxuIgorICAgICAgIlxuIgorICAgICAgIi8vIHN5bnRheCBsZWFkaW5nXG4iCisgICAgICAiJGEkc3ludGF4ID0gXCJwcm90bzJcIjskYiRcbiIKKyAgICAgICIvLyBzeW50YXggdHJhaWxpbmdcbiIKKyAgICAgICJcbiIKKyAgICAgICIvLyBzeW50YXgtcGFja2FnZSBkZXRhY2hlZCBjb21tZW50c1xuIgorICAgICAgIlxuIgorICAgICAgIjtcbiIKKyAgICAgICJcbiIKKyAgICAgICIvLyBkZXRhY2hlZCBhZnRlciBlbXB0eSBiZWZvcmUgcGFja2FnZVxuIgorICAgICAgIlxuIgorICAgICAgIi8vIHBhY2thZ2UgbGVhZGluZ1xuIgorICAgICAgInBhY2thZ2UgJGMkZm9vJGQkO1xuIgorICAgICAgIi8vIHBhY2thZ2UgdHJhaWxpbmdcbiIKKyAgICAgICJcbiIKKyAgICAgICIvLyBpZ25vcmVkIGRldGFjaFxuIgorICAgICAgIlxuIikpOworCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oJ2EnLCAnYicsIGZpbGVfLCAic3ludGF4IiwgLTEsCisgICAgICAiIHN5bnRheCBsZWFkaW5nXG4iLAorICAgICAgIiBzeW50YXggdHJhaWxpbmdcbiIsCisgICAgICAiIGRldGFjaGVkIGJlZm9yZSBzeW50YXggcGFyYWdyYXBoIDFcbiIKKyAgICAgICJcbiIKKyAgICAgICIgZGV0YWNoZWQgYmVmb3JlIHN5bnRheCBwYXJhZ3JhcGggMlxuIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKCdjJywgJ2QnLCBmaWxlXywgInBhY2thZ2UiLCAtMSwKKyAgICAgICIgcGFja2FnZSBsZWFkaW5nXG4iLAorICAgICAgIiBwYWNrYWdlIHRyYWlsaW5nXG4iLAorICAgICAgIiBzeW50YXgtcGFja2FnZSBkZXRhY2hlZCBjb21tZW50c1xuIgorICAgICAgIlxuIgorICAgICAgIiBkZXRhY2hlZCBhZnRlciBlbXB0eSBiZWZvcmUgcGFja2FnZVxuIikpOworCisgIC8vIGlnbm9yZSB0aGVzZS4KKyAgRVhQRUNUX1RSVUUoSGFzU3BhbihmaWxlXykpOworfQorCitURVNUX0YoU291cmNlSW5mb1Rlc3QsIERvY0NvbW1lbnRzT25lb2YpIHsKKyAgRVhQRUNUX1RSVUUoUGFyc2UoCisgICAgICAiLy8gRm9vIGxlYWRpbmdcbiIKKyAgICAgICIkYSRtZXNzYWdlIEZvbyB7XG4iCisgICAgICAiICAvKiBGb28gdHJhaWxpbmdcbiIKKyAgICAgICIgICAqL1xuIgorICAgICAgIiAgLy8gZGV0YWNoZWQgYmVmb3JlIG9uZW9mXG4iCisgICAgICAiICAvKiBiYXIgbGVhZGluZ1xuIgorICAgICAgIiAgICogbGluZSAyICovXG4iCisgICAgICAiICAkYiRvbmVvZiBiYXIge1xuIgorICAgICAgIiAgLyogYmFyIHRyYWlsaW5nXG4iCisgICAgICAiICAgKiBsaW5lIDIgKi9cbiIKKyAgICAgICIgIC8vIGRldGFjaGVkIGJlZm9yZSBiYXJfaW50XG4iCisgICAgICAiICAvKiBiYXJfaW50IGxlYWRpbmdcbiIKKyAgICAgICIgICAqL1xuIgorICAgICAgIiAgJGMkaW50MzIgYmFyX2ludCA9IDE7JGQkICAvLyBiYXJfaW50IHRyYWlsaW5nXG4iCisgICAgICAiICAvLyBkZXRhY2ggY29tbWVudCBpZ25vcmVkXG4iCisgICAgICAiICB9JGUkXG4iCisgICAgICAifSRmJFxuIikpOworCisgIGNvbnN0IERlc2NyaXB0b3JQcm90byYgZm9vID0gZmlsZV8ubWVzc2FnZV90eXBlKDApOworICBjb25zdCBPbmVvZkRlc2NyaXB0b3JQcm90byYgYmFyID0gZm9vLm9uZW9mX2RlY2woMCk7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvJiBiYXJfaW50ID0gZm9vLmZpZWxkKDApOworCisgIEVYUEVDVF9UUlVFKEhhc1NwYW5XaXRoQ29tbWVudCgnYScsICdmJywgZm9vLAorICAgICAgIiBGb28gbGVhZGluZ1xuIiwKKyAgICAgICIgRm9vIHRyYWlsaW5nXG4iLAorICAgICAgTlVMTCkpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuV2l0aENvbW1lbnQoJ2InLCAnZScsIGJhciwKKyAgICAgICIgYmFyIGxlYWRpbmdcbiBsaW5lIDIgIiwKKyAgICAgICIgYmFyIHRyYWlsaW5nXG4gbGluZSAyICIsCisgICAgICAiIGRldGFjaGVkIGJlZm9yZSBvbmVvZlxuIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuV2l0aENvbW1lbnQoJ2MnLCAnZCcsIGJhcl9pbnQsCisgICAgICAiIGJhcl9pbnQgbGVhZGluZ1xuIiwKKyAgICAgICIgYmFyX2ludCB0cmFpbGluZ1xuIiwKKyAgICAgICIgZGV0YWNoZWQgYmVmb3JlIGJhcl9pbnRcbiIpKTsKKworICAvLyBJZ25vcmUgdGhlc2UuCisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oZmlsZV8pKTsKKyAgRVhQRUNUX1RSVUUoSGFzU3Bhbihmb28sICJuYW1lIikpOworICBFWFBFQ1RfVFJVRShIYXNTcGFuKGJhciwgIm5hbWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oYmFyX2ludCwgInR5cGUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oYmFyX2ludCwgIm5hbWUiKSk7CisgIEVYUEVDVF9UUlVFKEhhc1NwYW4oYmFyX2ludCwgIm51bWJlciIpKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCit9ICAvLyBhbm9ueW1vdXMgbmFtZXNwYWNlCisKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BsdWdpbi5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJiZWJmMWYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BsdWdpbi5jYwpAQCAtMCwwICsxLDE3OSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wbHVnaW4uaD4KKworI2luY2x1ZGUgPGlvc3RyZWFtPgorI2luY2x1ZGUgPHNldD4KKworI2lmZGVmIF9XSU4zMgorI2luY2x1ZGUgPGlvLmg+CisjaW5jbHVkZSA8ZmNudGwuaD4KKyNpZm5kZWYgU1RESU5fRklMRU5PCisjZGVmaW5lIFNURElOX0ZJTEVOTyAwCisjZW5kaWYKKyNpZm5kZWYgU1RET1VUX0ZJTEVOTworI2RlZmluZSBTVERPVVRfRklMRU5PIDEKKyNlbmRpZgorI2Vsc2UKKyNpbmNsdWRlIDx1bmlzdGQuaD4KKyNlbmRpZgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2xvZ2dpbmcuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BsdWdpbi5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jb2RlX2dlbmVyYXRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbC5oPgorCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CisKK2NsYXNzIEdlbmVyYXRvclJlc3BvbnNlQ29udGV4dCA6IHB1YmxpYyBHZW5lcmF0b3JDb250ZXh0IHsKKyBwdWJsaWM6CisgIEdlbmVyYXRvclJlc3BvbnNlQ29udGV4dChDb2RlR2VuZXJhdG9yUmVzcG9uc2UqIHJlc3BvbnNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmVjdG9yPGNvbnN0IEZpbGVEZXNjcmlwdG9yKj4mIHBhcnNlZF9maWxlcykKKyAgICAgIDogcmVzcG9uc2VfKHJlc3BvbnNlKSwKKyAgICAgICAgcGFyc2VkX2ZpbGVzXyhwYXJzZWRfZmlsZXMpIHt9CisgIHZpcnR1YWwgfkdlbmVyYXRvclJlc3BvbnNlQ29udGV4dCgpIHt9CisKKyAgLy8gaW1wbGVtZW50cyBHZW5lcmF0b3JDb250ZXh0IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgdmlydHVhbCBpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0qIE9wZW4oY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSkgeworICAgIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6RmlsZSogZmlsZSA9IHJlc3BvbnNlXy0+YWRkX2ZpbGUoKTsKKyAgICBmaWxlLT5zZXRfbmFtZShmaWxlbmFtZSk7CisgICAgcmV0dXJuIG5ldyBpbzo6U3RyaW5nT3V0cHV0U3RyZWFtKGZpbGUtPm11dGFibGVfY29udGVudCgpKTsKKyAgfQorCisgIHZpcnR1YWwgaW86Olplcm9Db3B5T3V0cHV0U3RyZWFtKiBPcGVuRm9ySW5zZXJ0KAorICAgICAgY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSwgY29uc3Qgc3RyaW5nJiBpbnNlcnRpb25fcG9pbnQpIHsKKyAgICBDb2RlR2VuZXJhdG9yUmVzcG9uc2U6OkZpbGUqIGZpbGUgPSByZXNwb25zZV8tPmFkZF9maWxlKCk7CisgICAgZmlsZS0+c2V0X25hbWUoZmlsZW5hbWUpOworICAgIGZpbGUtPnNldF9pbnNlcnRpb25fcG9pbnQoaW5zZXJ0aW9uX3BvaW50KTsKKyAgICByZXR1cm4gbmV3IGlvOjpTdHJpbmdPdXRwdXRTdHJlYW0oZmlsZS0+bXV0YWJsZV9jb250ZW50KCkpOworICB9CisKKyAgdm9pZCBMaXN0UGFyc2VkRmlsZXModmVjdG9yPGNvbnN0IEZpbGVEZXNjcmlwdG9yKj4qIG91dHB1dCkgeworICAgICpvdXRwdXQgPSBwYXJzZWRfZmlsZXNfOworICB9CisKKyBwcml2YXRlOgorICBDb2RlR2VuZXJhdG9yUmVzcG9uc2UqIHJlc3BvbnNlXzsKKyAgY29uc3QgdmVjdG9yPGNvbnN0IEZpbGVEZXNjcmlwdG9yKj4mIHBhcnNlZF9maWxlc187Cit9OworCitpbnQgUGx1Z2luTWFpbihpbnQgYXJnYywgY2hhciogYXJndltdLCBjb25zdCBDb2RlR2VuZXJhdG9yKiBnZW5lcmF0b3IpIHsKKworICBpZiAoYXJnYyA+IDEpIHsKKyAgICBzdGQ6OmNlcnIgPDwgYXJndlswXSA8PCAiOiBVbmtub3duIG9wdGlvbjogIiA8PCBhcmd2WzFdIDw8IHN0ZDo6ZW5kbDsKKyAgICByZXR1cm4gMTsKKyAgfQorCisjaWZkZWYgX1dJTjMyCisgIF9zZXRtb2RlKFNURElOX0ZJTEVOTywgX09fQklOQVJZKTsKKyAgX3NldG1vZGUoU1RET1VUX0ZJTEVOTywgX09fQklOQVJZKTsKKyNlbmRpZgorCisgIENvZGVHZW5lcmF0b3JSZXF1ZXN0IHJlcXVlc3Q7CisgIGlmICghcmVxdWVzdC5QYXJzZUZyb21GaWxlRGVzY3JpcHRvcihTVERJTl9GSUxFTk8pKSB7CisgICAgc3RkOjpjZXJyIDw8IGFyZ3ZbMF0gPDwgIjogcHJvdG9jIHNlbnQgdW5wYXJzZWFibGUgcmVxdWVzdCB0byBwbHVnaW4uIgorICAgICAgICAgICAgICA8PCBzdGQ6OmVuZGw7CisgICAgcmV0dXJuIDE7CisgIH0KKworICBEZXNjcmlwdG9yUG9vbCBwb29sOworICBmb3IgKGludCBpID0gMDsgaSA8IHJlcXVlc3QucHJvdG9fZmlsZV9zaXplKCk7IGkrKykgeworICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlID0gcG9vbC5CdWlsZEZpbGUocmVxdWVzdC5wcm90b19maWxlKGkpKTsKKyAgICBpZiAoZmlsZSA9PSBOVUxMKSB7CisgICAgICAvLyBCdWlsZEZpbGUoKSBhbHJlYWR5IHdyb3RlIGFuIGVycm9yIG1lc3NhZ2UuCisgICAgICByZXR1cm4gMTsKKyAgICB9CisgIH0KKworICB2ZWN0b3I8Y29uc3QgRmlsZURlc2NyaXB0b3IqPiBwYXJzZWRfZmlsZXM7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVxdWVzdC5maWxlX3RvX2dlbmVyYXRlX3NpemUoKTsgaSsrKSB7CisgICAgcGFyc2VkX2ZpbGVzLnB1c2hfYmFjayhwb29sLkZpbmRGaWxlQnlOYW1lKHJlcXVlc3QuZmlsZV90b19nZW5lcmF0ZShpKSkpOworICAgIGlmIChwYXJzZWRfZmlsZXMuYmFjaygpID09IE5VTEwpIHsKKyAgICAgIHN0ZDo6Y2VyciA8PCBhcmd2WzBdIDw8ICI6IHByb3RvYyBhc2tlZCBwbHVnaW4gdG8gZ2VuZXJhdGUgYSBmaWxlIGJ1dCAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZGlkIG5vdCBwcm92aWRlIGEgZGVzY3JpcHRvciBmb3IgdGhlIGZpbGU6ICIKKyAgICAgICAgICAgICAgICA8PCByZXF1ZXN0LmZpbGVfdG9fZ2VuZXJhdGUoaSkgPDwgc3RkOjplbmRsOworICAgICAgcmV0dXJuIDE7CisgICAgfQorICB9CisKKyAgQ29kZUdlbmVyYXRvclJlc3BvbnNlIHJlc3BvbnNlOworICBHZW5lcmF0b3JSZXNwb25zZUNvbnRleHQgY29udGV4dCgmcmVzcG9uc2UsIHBhcnNlZF9maWxlcyk7CisKKyAgaWYgKGdlbmVyYXRvci0+SGFzR2VuZXJhdGVBbGwoKSkgeworICAgIHN0cmluZyBlcnJvcjsKKyAgICBib29sIHN1Y2NlZWRlZCA9IGdlbmVyYXRvci0+R2VuZXJhdGVBbGwoCisgICAgICAgIHBhcnNlZF9maWxlcywgcmVxdWVzdC5wYXJhbWV0ZXIoKSwgJmNvbnRleHQsICZlcnJvcik7CisKKyAgICBpZiAoIXN1Y2NlZWRlZCAmJiBlcnJvci5lbXB0eSgpKSB7CisgICAgICBlcnJvciA9ICJDb2RlIGdlbmVyYXRvciByZXR1cm5lZCBmYWxzZSBidXQgcHJvdmlkZWQgbm8gZXJyb3IgIgorICAgICAgICAgICAgICAiZGVzY3JpcHRpb24uIjsKKyAgICB9CisgICAgaWYgKCFlcnJvci5lbXB0eSgpKSB7CisgICAgICByZXNwb25zZS5zZXRfZXJyb3IoZXJyb3IpOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhcnNlZF9maWxlcy5zaXplKCk7IGkrKykgeworICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUgPSBwYXJzZWRfZmlsZXNbaV07CisKKyAgICAgIHN0cmluZyBlcnJvcjsKKyAgICAgIGJvb2wgc3VjY2VlZGVkID0gZ2VuZXJhdG9yLT5HZW5lcmF0ZSgKKyAgICAgICAgICBmaWxlLCByZXF1ZXN0LnBhcmFtZXRlcigpLCAmY29udGV4dCwgJmVycm9yKTsKKworICAgICAgaWYgKCFzdWNjZWVkZWQgJiYgZXJyb3IuZW1wdHkoKSkgeworICAgICAgICBlcnJvciA9ICJDb2RlIGdlbmVyYXRvciByZXR1cm5lZCBmYWxzZSBidXQgcHJvdmlkZWQgbm8gZXJyb3IgIgorICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbi4iOworICAgICAgfQorICAgICAgaWYgKCFlcnJvci5lbXB0eSgpKSB7CisgICAgICAgIHJlc3BvbnNlLnNldF9lcnJvcihmaWxlLT5uYW1lKCkgKyAiOiAiICsgZXJyb3IpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICBpZiAoIXJlc3BvbnNlLlNlcmlhbGl6ZVRvRmlsZURlc2NyaXB0b3IoU1RET1VUX0ZJTEVOTykpIHsKKyAgICBzdGQ6OmNlcnIgPDwgYXJndlswXSA8PCAiOiBFcnJvciB3cml0aW5nIHRvIHN0ZG91dC4iIDw8IHN0ZDo6ZW5kbDsKKyAgICByZXR1cm4gMTsKKyAgfQorCisgIHJldHVybiAwOworfQorCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wbHVnaW4uaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjc5ZjliZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLmgKQEAgLTAsMCArMSw3MiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vCisvLyBGcm9udC1lbmQgZm9yIHByb3RvYyBjb2RlIGdlbmVyYXRvciBwbHVnaW5zIHdyaXR0ZW4gaW4gQysrLgorLy8KKy8vIFRvIGltcGxlbWVudCBhIHByb3RvYyBwbHVnaW4gaW4gQysrLCBzaW1wbHkgd3JpdGUgYW4gaW1wbGVtZW50YXRpb24gb2YKKy8vIENvZGVHZW5lcmF0b3IsIHRoZW4gY3JlYXRlIGEgbWFpbigpIGZ1bmN0aW9uIGxpa2U6CisvLyAgIGludCBtYWluKGludCBhcmdjLCBjaGFyKiBhcmd2W10pIHsKKy8vICAgICBNeUNvZGVHZW5lcmF0b3IgZ2VuZXJhdG9yOworLy8gICAgIHJldHVybiBnb29nbGU6OnByb3RvYnVmOjpjb21waWxlcjo6UGx1Z2luTWFpbihhcmdjLCBhcmd2LCAmZ2VuZXJhdG9yKTsKKy8vICAgfQorLy8gWW91IG11c3QgbGluayB5b3VyIHBsdWdpbiBhZ2FpbnN0IGxpYnByb3RvYnVmIGFuZCBsaWJwcm90b2MuCisvLworLy8gVG8gZ2V0IHByb3RvYyB0byB1c2UgdGhlIHBsdWdpbiwgZG8gb25lIG9mIHRoZSBmb2xsb3dpbmc6CisvLyAqIFBsYWNlIHRoZSBwbHVnaW4gYmluYXJ5IHNvbWV3aGVyZSBpbiB0aGUgUEFUSCBhbmQgZ2l2ZSBpdCB0aGUgbmFtZQorLy8gICAicHJvdG9jLWdlbi1OQU1FIiAocmVwbGFjaW5nICJOQU1FIiB3aXRoIHRoZSBuYW1lIG9mIHlvdXIgcGx1Z2luKS4gIElmIHlvdQorLy8gICB0aGVuIGludm9rZSBwcm90b2Mgd2l0aCB0aGUgcGFyYW1ldGVyIC0tTkFNRV9vdXQ9T1VUX0RJUiAoYWdhaW4sIHJlcGxhY2UKKy8vICAgIk5BTUUiIHdpdGggeW91ciBwbHVnaW4ncyBuYW1lKSwgcHJvdG9jIHdpbGwgaW52b2tlIHlvdXIgcGx1Z2luIHRvIGdlbmVyYXRlCisvLyAgIHRoZSBvdXRwdXQsIHdoaWNoIHdpbGwgYmUgcGxhY2VkIGluIE9VVF9ESVIuCisvLyAqIFBsYWNlIHRoZSBwbHVnaW4gYmluYXJ5IGFueXdoZXJlLCB3aXRoIGFueSBuYW1lLCBhbmQgcGFzcyB0aGUgLS1wbHVnaW4KKy8vICAgcGFyYW1ldGVyIHRvIHByb3RvYyB0byBkaXJlY3QgaXQgdG8geW91ciBwbHVnaW4gbGlrZSBzbzoKKy8vICAgICBwcm90b2MgLS1wbHVnaW49cHJvdG9jLWdlbi1OQU1FPXBhdGgvdG8vbXliaW5hcnkgLS1OQU1FX291dD1PVVRfRElSCisvLyAgIE9uIFdpbmRvd3MsIG1ha2Ugc3VyZSB0byBpbmNsdWRlIHRoZSAuZXhlIHN1ZmZpeDoKKy8vICAgICBwcm90b2MgLS1wbHVnaW49cHJvdG9jLWdlbi1OQU1FPXBhdGgvdG8vbXliaW5hcnkuZXhlIC0tTkFNRV9vdXQ9T1VUX0RJUgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9QTFVHSU5fSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9QTFVHSU5fSF9fCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworCitjbGFzcyBDb2RlR2VuZXJhdG9yOyAgICAvLyBjb2RlX2dlbmVyYXRvci5oCisKKy8vIEltcGxlbWVudHMgbWFpbigpIGZvciBhIHByb3RvYyBwbHVnaW4gZXhwb3NpbmcgdGhlIGdpdmVuIGNvZGUgZ2VuZXJhdG9yLgorTElCUFJPVE9DX0VYUE9SVCBpbnQgUGx1Z2luTWFpbihpbnQgYXJnYywgY2hhciogYXJndltdLCBjb25zdCBDb2RlR2VuZXJhdG9yKiBnZW5lcmF0b3IpOworCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9QTFVHSU5fSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BsdWdpbi5wYi5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLnBiLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmEyZGE4ZWUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BsdWdpbi5wYi5jYwpAQCAtMCwwICsxLDE1NzAgQEAKKy8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCisvLyBzb3VyY2U6IGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wbHVnaW4ucHJvdG8KKworI2RlZmluZSBJTlRFUk5BTF9TVVBQUkVTU19QUk9UT0JVRl9GSUVMRF9ERVBSRUNBVElPTgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wbHVnaW4ucGIuaD4KKworI2luY2x1ZGUgPGFsZ29yaXRobT4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvcG9ydC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9vbmNlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdF9saXRlX2lubC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9tZXNzYWdlX3JlZmxlY3Rpb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcmVmbGVjdGlvbl9vcHMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuaD4KKy8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbmNsdWRlcykKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKKworbmFtZXNwYWNlIHsKKworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBDb2RlR2VuZXJhdG9yUmVxdWVzdF9kZXNjcmlwdG9yXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbioKKyAgQ29kZUdlbmVyYXRvclJlcXVlc3RfcmVmbGVjdGlvbl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfZGVzY3JpcHRvcl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24qCisgIENvZGVHZW5lcmF0b3JSZXNwb25zZV9yZWZsZWN0aW9uXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlX2Rlc2NyaXB0b3JfID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKgorICBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZV9yZWZsZWN0aW9uXyA9IE5VTEw7CisKK30gIC8vIG5hbWVzcGFjZQorCisKK3ZvaWQgcHJvdG9idWZfQXNzaWduRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmNvbXBpbGVyXzJmcGx1Z2luXzJlcHJvdG8oKSB7CisgIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZjb21waWxlcl8yZnBsdWdpbl8yZXByb3RvKCk7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZURlc2NyaXB0b3IqIGZpbGUgPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclBvb2w6OmdlbmVyYXRlZF9wb29sKCktPkZpbmRGaWxlQnlOYW1lKAorICAgICAgImdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wbHVnaW4ucHJvdG8iKTsKKyAgR09PR0xFX0NIRUNLKGZpbGUgIT0gTlVMTCk7CisgIENvZGVHZW5lcmF0b3JSZXF1ZXN0X2Rlc2NyaXB0b3JfID0gZmlsZS0+bWVzc2FnZV90eXBlKDApOworICBzdGF0aWMgY29uc3QgaW50IENvZGVHZW5lcmF0b3JSZXF1ZXN0X29mZnNldHNfWzNdID0geworICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoQ29kZUdlbmVyYXRvclJlcXVlc3QsIGZpbGVfdG9fZ2VuZXJhdGVfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKENvZGVHZW5lcmF0b3JSZXF1ZXN0LCBwYXJhbWV0ZXJfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKENvZGVHZW5lcmF0b3JSZXF1ZXN0LCBwcm90b19maWxlXyksCisgIH07CisgIENvZGVHZW5lcmF0b3JSZXF1ZXN0X3JlZmxlY3Rpb25fID0KKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6TmV3R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24oCisgICAgICBDb2RlR2VuZXJhdG9yUmVxdWVzdF9kZXNjcmlwdG9yXywKKyAgICAgIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjpkZWZhdWx0X2luc3RhbmNlXywKKyAgICAgIENvZGVHZW5lcmF0b3JSZXF1ZXN0X29mZnNldHNfLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChDb2RlR2VuZXJhdG9yUmVxdWVzdCwgX2hhc19iaXRzX1swXSksCisgICAgICAtMSwKKyAgICAgIC0xLAorICAgICAgc2l6ZW9mKENvZGVHZW5lcmF0b3JSZXF1ZXN0KSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoQ29kZUdlbmVyYXRvclJlcXVlc3QsIF9pbnRlcm5hbF9tZXRhZGF0YV8pLAorICAgICAgLTEpOworICBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfZGVzY3JpcHRvcl8gPSBmaWxlLT5tZXNzYWdlX3R5cGUoMSk7CisgIHN0YXRpYyBjb25zdCBpbnQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX29mZnNldHNfWzJdID0geworICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoQ29kZUdlbmVyYXRvclJlc3BvbnNlLCBlcnJvcl8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoQ29kZUdlbmVyYXRvclJlc3BvbnNlLCBmaWxlXyksCisgIH07CisgIENvZGVHZW5lcmF0b3JSZXNwb25zZV9yZWZsZWN0aW9uXyA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok5ld0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKAorICAgICAgQ29kZUdlbmVyYXRvclJlc3BvbnNlX2Rlc2NyaXB0b3JfLAorICAgICAgQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpkZWZhdWx0X2luc3RhbmNlXywKKyAgICAgIENvZGVHZW5lcmF0b3JSZXNwb25zZV9vZmZzZXRzXywKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoQ29kZUdlbmVyYXRvclJlc3BvbnNlLCBfaGFzX2JpdHNfWzBdKSwKKyAgICAgIC0xLAorICAgICAgLTEsCisgICAgICBzaXplb2YoQ29kZUdlbmVyYXRvclJlc3BvbnNlKSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoQ29kZUdlbmVyYXRvclJlc3BvbnNlLCBfaW50ZXJuYWxfbWV0YWRhdGFfKSwKKyAgICAgIC0xKTsKKyAgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGVfZGVzY3JpcHRvcl8gPSBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlKDApOworICBzdGF0aWMgY29uc3QgaW50IENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlX29mZnNldHNfWzNdID0geworICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUsIG5hbWVfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlLCBpbnNlcnRpb25fcG9pbnRfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlLCBjb250ZW50XyksCisgIH07CisgIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlX3JlZmxlY3Rpb25fID0KKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6TmV3R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24oCisgICAgICBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZV9kZXNjcmlwdG9yXywKKyAgICAgIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpkZWZhdWx0X2luc3RhbmNlXywKKyAgICAgIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlX29mZnNldHNfLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZSwgX2hhc19iaXRzX1swXSksCisgICAgICAtMSwKKyAgICAgIC0xLAorICAgICAgc2l6ZW9mKENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlKSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUsIF9pbnRlcm5hbF9tZXRhZGF0YV8pLAorICAgICAgLTEpOworfQorCituYW1lc3BhY2UgeworCitHT09HTEVfUFJPVE9CVUZfREVDTEFSRV9PTkNFKHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzX29uY2VfKTsKK2lubGluZSB2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpIHsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpHb29nbGVPbmNlSW5pdCgmcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNfb25jZV8sCisgICAgICAgICAgICAgICAgICZwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmY29tcGlsZXJfMmZwbHVnaW5fMmVwcm90byk7Cit9CisKK3ZvaWQgcHJvdG9idWZfUmVnaXN0ZXJUeXBlcyhjb25zdCA6OnN0ZDo6c3RyaW5nJikgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZE1lc3NhZ2UoCisgICAgICBDb2RlR2VuZXJhdG9yUmVxdWVzdF9kZXNjcmlwdG9yXywgJkNvZGVHZW5lcmF0b3JSZXF1ZXN0OjpkZWZhdWx0X2luc3RhbmNlKCkpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VGYWN0b3J5OjpJbnRlcm5hbFJlZ2lzdGVyR2VuZXJhdGVkTWVzc2FnZSgKKyAgICAgIENvZGVHZW5lcmF0b3JSZXNwb25zZV9kZXNjcmlwdG9yXywgJkNvZGVHZW5lcmF0b3JSZXNwb25zZTo6ZGVmYXVsdF9pbnN0YW5jZSgpKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZE1lc3NhZ2UoCisgICAgICBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZV9kZXNjcmlwdG9yXywgJkNvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpkZWZhdWx0X2luc3RhbmNlKCkpOworfQorCit9ICAvLyBuYW1lc3BhY2UKKwordm9pZCBwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZjb21waWxlcl8yZnBsdWdpbl8yZXByb3RvKCkgeworICBkZWxldGUgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OmRlZmF1bHRfaW5zdGFuY2VfOworICBkZWxldGUgQ29kZUdlbmVyYXRvclJlcXVlc3RfcmVmbGVjdGlvbl87CisgIGRlbGV0ZSBDb2RlR2VuZXJhdG9yUmVzcG9uc2U6OmRlZmF1bHRfaW5zdGFuY2VfOworICBkZWxldGUgQ29kZUdlbmVyYXRvclJlc3BvbnNlX3JlZmxlY3Rpb25fOworICBkZWxldGUgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OmRlZmF1bHRfaW5zdGFuY2VfOworICBkZWxldGUgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGVfcmVmbGVjdGlvbl87Cit9CisKK3ZvaWQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmNvbXBpbGVyXzJmcGx1Z2luXzJlcHJvdG8oKSB7CisgIHN0YXRpYyBib29sIGFscmVhZHlfaGVyZSA9IGZhbHNlOworICBpZiAoYWxyZWFkeV9oZXJlKSByZXR1cm47CisgIGFscmVhZHlfaGVyZSA9IHRydWU7CisgIEdPT0dMRV9QUk9UT0JVRl9WRVJJRllfVkVSU0lPTjsKKworICA6Omdvb2dsZTo6cHJvdG9idWY6OnByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUG9vbDo6SW50ZXJuYWxBZGRHZW5lcmF0ZWRGaWxlKAorICAgICJcbiVnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLnByb3RvXDAyMiIKKyAgICAiXDAzMGdvb2dsZS5wcm90b2J1Zi5jb21waWxlclwwMzIgZ29vZ2xlL3Byb3RvYiIKKyAgICAidWYvZGVzY3JpcHRvci5wcm90b1wifVxuXDAyNENvZGVHZW5lcmF0b3JSZXF1IgorICAgICJlc3RcMDIyXDAzMFxuXDAyMGZpbGVfdG9fZ2VuZXJhdGVcMDMwXDAwMSBcMDAzKFx0XDAyMlwwMjFcblx0cGFyYW1ldCIKKyAgICAiZXJcMDMwXDAwMiBcMDAxKFx0XDAyMjhcblxucHJvdG9fZmlsZVwwMzBcMDE3IFwwMDMoXDAxMzIkLmdvb2dsZS5wciIKKyAgICAib3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG9cIlwyNTJcMDAxXG5cMDI1Q29kZUdlbmVyIgorICAgICJhdG9yUmVzcG9uc2VcMDIyXHJcblwwMDVlcnJvclwwMzBcMDAxIFwwMDEoXHRcMDIyQlxuXDAwNGZpbGVcMDMwXDAxNyBcMDAzKCIKKyAgICAiXDAxMzI0Lmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdCIKKyAgICAib3JSZXNwb25zZS5GaWxlXDAzMj5cblwwMDRGaWxlXDAyMlwwMTRcblwwMDRuYW1lXDAzMFwwMDEgXDAwMShcdFwwMjJcMDI3XG4iCisgICAgIlwwMTdpbnNlcnRpb25fcG9pbnRcMDMwXDAwMiBcMDAxKFx0XDAyMlwwMTdcblwwMDdjb250ZW50XDAzMFwwMTcgXDAwMShcdEIiCisgICAgIjdcblwwMzRjb20uZ29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyQlwwMTRQbHVnaW5QIgorICAgICJyb3Rvc1pcdHBsdWdpbl9nbyIsIDQ1Nik7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZUZhY3Rvcnk6OkludGVybmFsUmVnaXN0ZXJHZW5lcmF0ZWRGaWxlKAorICAgICJnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLnByb3RvIiwgJnByb3RvYnVmX1JlZ2lzdGVyVHlwZXMpOworICBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBuZXcgQ29kZUdlbmVyYXRvclJlcXVlc3QoKTsKKyAgQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpkZWZhdWx0X2luc3RhbmNlXyA9IG5ldyBDb2RlR2VuZXJhdG9yUmVzcG9uc2UoKTsKKyAgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OmRlZmF1bHRfaW5zdGFuY2VfID0gbmV3IENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlKCk7CisgIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjpkZWZhdWx0X2luc3RhbmNlXy0+SW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6ZGVmYXVsdF9pbnN0YW5jZV8tPkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6ZGVmYXVsdF9pbnN0YW5jZV8tPkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpPblNodXRkb3duKCZwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZjb21waWxlcl8yZnBsdWdpbl8yZXByb3RvKTsKK30KKworLy8gRm9yY2UgQWRkRGVzY3JpcHRvcnMoKSB0byBiZSBjYWxsZWQgYXQgc3RhdGljIGluaXRpYWxpemF0aW9uIHRpbWUuCitzdHJ1Y3QgU3RhdGljRGVzY3JpcHRvckluaXRpYWxpemVyX2dvb2dsZV8yZnByb3RvYnVmXzJmY29tcGlsZXJfMmZwbHVnaW5fMmVwcm90byB7CisgIFN0YXRpY0Rlc2NyaXB0b3JJbml0aWFsaXplcl9nb29nbGVfMmZwcm90b2J1Zl8yZmNvbXBpbGVyXzJmcGx1Z2luXzJlcHJvdG8oKSB7CisgICAgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmNvbXBpbGVyXzJmcGx1Z2luXzJlcHJvdG8oKTsKKyAgfQorfSBzdGF0aWNfZGVzY3JpcHRvcl9pbml0aWFsaXplcl9nb29nbGVfMmZwcm90b2J1Zl8yZmNvbXBpbGVyXzJmcGx1Z2luXzJlcHJvdG9fOworCituYW1lc3BhY2UgeworCitzdGF0aWMgdm9pZCBNZXJnZUZyb21GYWlsKGludCBsaW5lKSBHT09HTEVfQVRUUklCVVRFX0NPTEQ7CitzdGF0aWMgdm9pZCBNZXJnZUZyb21GYWlsKGludCBsaW5lKSB7CisgIEdPT0dMRV9DSEVDSyhmYWxzZSkgPDwgX19GSUxFX18gPDwgIjoiIDw8IGxpbmU7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworI2lmICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCitjb25zdCBpbnQgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OmtGaWxlVG9HZW5lcmF0ZUZpZWxkTnVtYmVyOworY29uc3QgaW50IENvZGVHZW5lcmF0b3JSZXF1ZXN0OjprUGFyYW1ldGVyRmllbGROdW1iZXI7Citjb25zdCBpbnQgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OmtQcm90b0ZpbGVGaWVsZE51bWJlcjsKKyNlbmRpZiAgLy8gIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKKworQ29kZUdlbmVyYXRvclJlcXVlc3Q6OkNvZGVHZW5lcmF0b3JSZXF1ZXN0KCkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdCkKK30KKwordm9pZCBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6SW5pdEFzRGVmYXVsdEluc3RhbmNlKCkgeworfQorCitDb2RlR2VuZXJhdG9yUmVxdWVzdDo6Q29kZUdlbmVyYXRvclJlcXVlc3QoY29uc3QgQ29kZUdlbmVyYXRvclJlcXVlc3QmIGZyb20pCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksCisgICAgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29weV9jb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlcXVlc3QpCit9CisKK3ZvaWQgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OlNoYXJlZEN0b3IoKSB7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSAwOworICBwYXJhbWV0ZXJfLlVuc2FmZVNldERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgOjptZW1zZXQoX2hhc19iaXRzXywgMCwgc2l6ZW9mKF9oYXNfYml0c18pKTsKK30KKworQ29kZUdlbmVyYXRvclJlcXVlc3Q6On5Db2RlR2VuZXJhdG9yUmVxdWVzdCgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGRlc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXF1ZXN0KQorICBTaGFyZWREdG9yKCk7Cit9CisKK3ZvaWQgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OlNoYXJlZER0b3IoKSB7CisgIHBhcmFtZXRlcl8uRGVzdHJveU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgaWYgKHRoaXMgIT0gZGVmYXVsdF9pbnN0YW5jZV8pIHsKKyAgfQorfQorCit2b2lkIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjpTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdCB7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSBzaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogQ29kZUdlbmVyYXRvclJlcXVlc3Q6OmRlc2NyaXB0b3IoKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICByZXR1cm4gQ29kZUdlbmVyYXRvclJlcXVlc3RfZGVzY3JpcHRvcl87Cit9CisKK2NvbnN0IENvZGVHZW5lcmF0b3JSZXF1ZXN0JiBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6ZGVmYXVsdF9pbnN0YW5jZSgpIHsKKyAgaWYgKGRlZmF1bHRfaW5zdGFuY2VfID09IE5VTEwpIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZjb21waWxlcl8yZnBsdWdpbl8yZXByb3RvKCk7CisgIHJldHVybiAqZGVmYXVsdF9pbnN0YW5jZV87Cit9CisKK0NvZGVHZW5lcmF0b3JSZXF1ZXN0KiBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBOVUxMOworCitDb2RlR2VuZXJhdG9yUmVxdWVzdCogQ29kZUdlbmVyYXRvclJlcXVlc3Q6Ok5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3QgeworICBDb2RlR2VuZXJhdG9yUmVxdWVzdCogbiA9IG5ldyBDb2RlR2VuZXJhdG9yUmVxdWVzdDsKKyAgaWYgKGFyZW5hICE9IE5VTEwpIHsKKyAgICBhcmVuYS0+T3duKG4pOworICB9CisgIHJldHVybiBuOworfQorCit2b2lkIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjpDbGVhcigpIHsKKyAgaWYgKGhhc19wYXJhbWV0ZXIoKSkgeworICAgIHBhcmFtZXRlcl8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICB9CisgIGZpbGVfdG9fZ2VuZXJhdGVfLkNsZWFyKCk7CisgIHByb3RvX2ZpbGVfLkNsZWFyKCk7CisgIDo6bWVtc2V0KF9oYXNfYml0c18sIDAsIHNpemVvZihfaGFzX2JpdHNfKSk7CisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+Q2xlYXIoKTsKKyAgfQorfQorCitib29sIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjpNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyNkZWZpbmUgRE9fKEVYUFJFU1NJT04pIGlmICghKEVYUFJFU1NJT04pKSBnb3RvIGZhaWx1cmUKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgdGFnOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXF1ZXN0KQorICBmb3IgKDs7KSB7CisgICAgOjpzdGQ6OnBhaXI8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyLCBib29sPiBwID0gaW5wdXQtPlJlYWRUYWdXaXRoQ3V0b2ZmKDEyNyk7CisgICAgdGFnID0gcC5maXJzdDsKKyAgICBpZiAoIXAuc2Vjb25kKSBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgIHN3aXRjaCAoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ0ZpZWxkTnVtYmVyKHRhZykpIHsKKyAgICAgIC8vIHJlcGVhdGVkIHN0cmluZyBmaWxlX3RvX2dlbmVyYXRlID0gMTsKKyAgICAgIGNhc2UgMTogeworICAgICAgICBpZiAodGFnID09IDEwKSB7CisgICAgICAgICBwYXJzZV9maWxlX3RvX2dlbmVyYXRlOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFN0cmluZygKKyAgICAgICAgICAgICAgICBpbnB1dCwgdGhpcy0+YWRkX2ZpbGVfdG9fZ2VuZXJhdGUoKSkpOworICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgICAgICAgdGhpcy0+ZmlsZV90b19nZW5lcmF0ZSh0aGlzLT5maWxlX3RvX2dlbmVyYXRlX3NpemUoKSAtIDEpLmRhdGEoKSwKKyAgICAgICAgICAgIHRoaXMtPmZpbGVfdG9fZ2VuZXJhdGUodGhpcy0+ZmlsZV90b19nZW5lcmF0ZV9zaXplKCkgLSAxKS5sZW5ndGgoKSwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlBBUlNFLAorICAgICAgICAgICAgImdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdC5maWxlX3RvX2dlbmVyYXRlIik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygxMCkpIGdvdG8gcGFyc2VfZmlsZV90b19nZW5lcmF0ZTsKKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMTgpKSBnb3RvIHBhcnNlX3BhcmFtZXRlcjsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIHN0cmluZyBwYXJhbWV0ZXIgPSAyOworICAgICAgY2FzZSAyOiB7CisgICAgICAgIGlmICh0YWcgPT0gMTgpIHsKKyAgICAgICAgIHBhcnNlX3BhcmFtZXRlcjoKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoCisgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPm11dGFibGVfcGFyYW1ldGVyKCkpKTsKKyAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgICAgICAgIHRoaXMtPnBhcmFtZXRlcigpLmRhdGEoKSwgdGhpcy0+cGFyYW1ldGVyKCkubGVuZ3RoKCksCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpQQVJTRSwKKyAgICAgICAgICAgICJnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlcXVlc3QucGFyYW1ldGVyIik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygxMjIpKSBnb3RvIHBhcnNlX3Byb3RvX2ZpbGU7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8gcHJvdG9fZmlsZSA9IDE1OworICAgICAgY2FzZSAxNTogeworICAgICAgICBpZiAodGFnID09IDEyMikgeworICAgICAgICAgcGFyc2VfcHJvdG9fZmlsZToKKyAgICAgICAgICBET18oaW5wdXQtPkluY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCkpOworICAgICAgICAgcGFyc2VfbG9vcF9wcm90b19maWxlOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZE1lc3NhZ2VOb1ZpcnR1YWxOb1JlY3Vyc2lvbkRlcHRoKAorICAgICAgICAgICAgICAgIGlucHV0LCBhZGRfcHJvdG9fZmlsZSgpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygxMjIpKSBnb3RvIHBhcnNlX2xvb3BfcHJvdG9fZmlsZTsKKyAgICAgICAgaW5wdXQtPlVuc2FmZURlY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCk7CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0QXRFbmQoKSkgZ290byBzdWNjZXNzOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgZGVmYXVsdDogeworICAgICAgaGFuZGxlX3VudXN1YWw6CisgICAgICAgIGlmICh0YWcgPT0gMCB8fAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ1dpcmVUeXBlKHRhZykgPT0KKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVApIHsKKyAgICAgICAgICBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIH0KKyAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNraXBGaWVsZCgKKyAgICAgICAgICAgICAgaW5wdXQsIHRhZywgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpKSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgfQorc3VjY2VzczoKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N1Y2Nlc3M6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXF1ZXN0KQorICByZXR1cm4gdHJ1ZTsKK2ZhaWx1cmU6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9mYWlsdXJlOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdCkKKyAgcmV0dXJuIGZhbHNlOworI3VuZGVmIERPXworfQorCit2b2lkIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdCkKKyAgLy8gcmVwZWF0ZWQgc3RyaW5nIGZpbGVfdG9fZ2VuZXJhdGUgPSAxOworICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPmZpbGVfdG9fZ2VuZXJhdGVfc2l6ZSgpOyBpKyspIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgIHRoaXMtPmZpbGVfdG9fZ2VuZXJhdGUoaSkuZGF0YSgpLCB0aGlzLT5maWxlX3RvX2dlbmVyYXRlKGkpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdC5maWxlX3RvX2dlbmVyYXRlIik7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nKAorICAgICAgMSwgdGhpcy0+ZmlsZV90b19nZW5lcmF0ZShpKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIHN0cmluZyBwYXJhbWV0ZXIgPSAyOworICBpZiAoaGFzX3BhcmFtZXRlcigpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5wYXJhbWV0ZXIoKS5kYXRhKCksIHRoaXMtPnBhcmFtZXRlcigpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdC5wYXJhbWV0ZXIiKTsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdNYXliZUFsaWFzZWQoCisgICAgICAyLCB0aGlzLT5wYXJhbWV0ZXIoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90byBwcm90b19maWxlID0gMTU7CisgIGZvciAodW5zaWduZWQgaW50IGkgPSAwLCBuID0gdGhpcy0+cHJvdG9fZmlsZV9zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgMTUsIHRoaXMtPnByb3RvX2ZpbGUoaSksIG91dHB1dCk7CisgIH0KKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTZXJpYWxpemVVbmtub3duRmllbGRzKAorICAgICAgICB1bmtub3duX2ZpZWxkcygpLCBvdXRwdXQpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfZW5kOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdCkKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogQ29kZUdlbmVyYXRvclJlcXVlc3Q6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogdGFyZ2V0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXF1ZXN0KQorICAvLyByZXBlYXRlZCBzdHJpbmcgZmlsZV90b19nZW5lcmF0ZSA9IDE7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+ZmlsZV90b19nZW5lcmF0ZV9zaXplKCk7IGkrKykgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+ZmlsZV90b19nZW5lcmF0ZShpKS5kYXRhKCksIHRoaXMtPmZpbGVfdG9fZ2VuZXJhdGUoaSkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXF1ZXN0LmZpbGVfdG9fZ2VuZXJhdGUiKTsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6CisgICAgICBXcml0ZVN0cmluZ1RvQXJyYXkoMSwgdGhpcy0+ZmlsZV90b19nZW5lcmF0ZShpKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIHN0cmluZyBwYXJhbWV0ZXIgPSAyOworICBpZiAoaGFzX3BhcmFtZXRlcigpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5wYXJhbWV0ZXIoKS5kYXRhKCksIHRoaXMtPnBhcmFtZXRlcigpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdC5wYXJhbWV0ZXIiKTsKKyAgICB0YXJnZXQgPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nVG9BcnJheSgKKyAgICAgICAgMiwgdGhpcy0+cGFyYW1ldGVyKCksIHRhcmdldCk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8gcHJvdG9fZmlsZSA9IDE1OworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPnByb3RvX2ZpbGVfc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OgorICAgICAgV3JpdGVNZXNzYWdlTm9WaXJ0dWFsVG9BcnJheSgKKyAgICAgICAgMTUsIHRoaXMtPnByb3RvX2ZpbGUoaSksIHRhcmdldCk7CisgIH0KKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTZXJpYWxpemVVbmtub3duRmllbGRzVG9BcnJheSgKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSwgdGFyZ2V0KTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X2VuZDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlcXVlc3QpCisgIHJldHVybiB0YXJnZXQ7Cit9CisKK2ludCBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6Qnl0ZVNpemUoKSBjb25zdCB7CisgIGludCB0b3RhbF9zaXplID0gMDsKKworICAvLyBvcHRpb25hbCBzdHJpbmcgcGFyYW1ldGVyID0gMjsKKyAgaWYgKGhhc19wYXJhbWV0ZXIoKSkgeworICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U3RyaW5nU2l6ZSgKKyAgICAgICAgdGhpcy0+cGFyYW1ldGVyKCkpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgc3RyaW5nIGZpbGVfdG9fZ2VuZXJhdGUgPSAxOworICB0b3RhbF9zaXplICs9IDEgKiB0aGlzLT5maWxlX3RvX2dlbmVyYXRlX3NpemUoKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT5maWxlX3RvX2dlbmVyYXRlX3NpemUoKTsgaSsrKSB7CisgICAgdG90YWxfc2l6ZSArPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U3RyaW5nU2l6ZSgKKyAgICAgIHRoaXMtPmZpbGVfdG9fZ2VuZXJhdGUoaSkpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvIHByb3RvX2ZpbGUgPSAxNTsKKyAgdG90YWxfc2l6ZSArPSAxICogdGhpcy0+cHJvdG9fZmlsZV9zaXplKCk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+cHJvdG9fZmlsZV9zaXplKCk7IGkrKykgeworICAgIHRvdGFsX3NpemUgKz0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpNZXNzYWdlU2l6ZU5vVmlydHVhbCgKKyAgICAgICAgdGhpcy0+cHJvdG9fZmlsZShpKSk7CisgIH0KKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICB0b3RhbF9zaXplICs9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpDb21wdXRlVW5rbm93bkZpZWxkc1NpemUoCisgICAgICAgIHVua25vd25fZmllbGRzKCkpOworICB9CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSB0b3RhbF9zaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKKyAgcmV0dXJuIHRvdGFsX3NpemU7Cit9CisKK3ZvaWQgQ29kZUdlbmVyYXRvclJlcXVlc3Q6Ok1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgY29uc3QgQ29kZUdlbmVyYXRvclJlcXVlc3QqIHNvdXJjZSA9IAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RHluYW1pY0Nhc3RUb0dlbmVyYXRlZDxjb25zdCBDb2RlR2VuZXJhdG9yUmVxdWVzdD4oCisgICAgICAgICAgJmZyb20pOworICBpZiAoc291cmNlID09IE5VTEwpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpSZWZsZWN0aW9uT3BzOjpNZXJnZShmcm9tLCB0aGlzKTsKKyAgfSBlbHNlIHsKKyAgICBNZXJnZUZyb20oKnNvdXJjZSk7CisgIH0KK30KKwordm9pZCBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6TWVyZ2VGcm9tKGNvbnN0IENvZGVHZW5lcmF0b3JSZXF1ZXN0JiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGZpbGVfdG9fZ2VuZXJhdGVfLk1lcmdlRnJvbShmcm9tLmZpbGVfdG9fZ2VuZXJhdGVfKTsKKyAgcHJvdG9fZmlsZV8uTWVyZ2VGcm9tKGZyb20ucHJvdG9fZmlsZV8pOworICBpZiAoZnJvbS5faGFzX2JpdHNfWzEgLyAzMl0gJiAoMHhmZnUgPDwgKDEgJSAzMikpKSB7CisgICAgaWYgKGZyb20uaGFzX3BhcmFtZXRlcigpKSB7CisgICAgICBzZXRfaGFzX3BhcmFtZXRlcigpOworICAgICAgcGFyYW1ldGVyXy5Bc3NpZ25XaXRoRGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGZyb20ucGFyYW1ldGVyXyk7CisgICAgfQorICB9CisgIGlmIChmcm9tLl9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5NZXJnZUZyb20oZnJvbS51bmtub3duX2ZpZWxkcygpKTsKKyAgfQorfQorCit2b2lkIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjpDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCit2b2lkIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjpDb3B5RnJvbShjb25zdCBDb2RlR2VuZXJhdG9yUmVxdWVzdCYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK2Jvb2wgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OklzSW5pdGlhbGl6ZWQoKSBjb25zdCB7CisKKyAgaWYgKCE6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBbGxBcmVJbml0aWFsaXplZCh0aGlzLT5wcm90b19maWxlKCkpKSByZXR1cm4gZmFsc2U7CisgIHJldHVybiB0cnVlOworfQorCit2b2lkIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjpTd2FwKENvZGVHZW5lcmF0b3JSZXF1ZXN0KiBvdGhlcikgeworICBpZiAob3RoZXIgPT0gdGhpcykgcmV0dXJuOworICBJbnRlcm5hbFN3YXAob3RoZXIpOworfQordm9pZCBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6SW50ZXJuYWxTd2FwKENvZGVHZW5lcmF0b3JSZXF1ZXN0KiBvdGhlcikgeworICBmaWxlX3RvX2dlbmVyYXRlXy5VbnNhZmVBcmVuYVN3YXAoJm90aGVyLT5maWxlX3RvX2dlbmVyYXRlXyk7CisgIHBhcmFtZXRlcl8uU3dhcCgmb3RoZXItPnBhcmFtZXRlcl8pOworICBwcm90b19maWxlXy5VbnNhZmVBcmVuYVN3YXAoJm90aGVyLT5wcm90b19maWxlXyk7CisgIHN0ZDo6c3dhcChfaGFzX2JpdHNfWzBdLCBvdGhlci0+X2hhc19iaXRzX1swXSk7CisgIF9pbnRlcm5hbF9tZXRhZGF0YV8uU3dhcCgmb3RoZXItPl9pbnRlcm5hbF9tZXRhZGF0YV8pOworICBzdGQ6OnN3YXAoX2NhY2hlZF9zaXplXywgb3RoZXItPl9jYWNoZWRfc2l6ZV8pOworfQorCis6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjpHZXRNZXRhZGF0YSgpIGNvbnN0IHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgbWV0YWRhdGE7CisgIG1ldGFkYXRhLmRlc2NyaXB0b3IgPSBDb2RlR2VuZXJhdG9yUmVxdWVzdF9kZXNjcmlwdG9yXzsKKyAgbWV0YWRhdGEucmVmbGVjdGlvbiA9IENvZGVHZW5lcmF0b3JSZXF1ZXN0X3JlZmxlY3Rpb25fOworICByZXR1cm4gbWV0YWRhdGE7Cit9CisKKyNpZiBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKy8vIENvZGVHZW5lcmF0b3JSZXF1ZXN0CisKKy8vIHJlcGVhdGVkIHN0cmluZyBmaWxlX3RvX2dlbmVyYXRlID0gMTsKK2ludCBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6ZmlsZV90b19nZW5lcmF0ZV9zaXplKCkgY29uc3QgeworICByZXR1cm4gZmlsZV90b19nZW5lcmF0ZV8uc2l6ZSgpOworfQordm9pZCBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6Y2xlYXJfZmlsZV90b19nZW5lcmF0ZSgpIHsKKyAgZmlsZV90b19nZW5lcmF0ZV8uQ2xlYXIoKTsKK30KKyBjb25zdCA6OnN0ZDo6c3RyaW5nJiBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6ZmlsZV90b19nZW5lcmF0ZShpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlcXVlc3QuZmlsZV90b19nZW5lcmF0ZSkKKyAgcmV0dXJuIGZpbGVfdG9fZ2VuZXJhdGVfLkdldChpbmRleCk7Cit9CisgOjpzdGQ6OnN0cmluZyogQ29kZUdlbmVyYXRvclJlcXVlc3Q6Om11dGFibGVfZmlsZV90b19nZW5lcmF0ZShpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXF1ZXN0LmZpbGVfdG9fZ2VuZXJhdGUpCisgIHJldHVybiBmaWxlX3RvX2dlbmVyYXRlXy5NdXRhYmxlKGluZGV4KTsKK30KKyB2b2lkIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjpzZXRfZmlsZV90b19nZW5lcmF0ZShpbnQgaW5kZXgsIGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXF1ZXN0LmZpbGVfdG9fZ2VuZXJhdGUpCisgIGZpbGVfdG9fZ2VuZXJhdGVfLk11dGFibGUoaW5kZXgpLT5hc3NpZ24odmFsdWUpOworfQorIHZvaWQgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OnNldF9maWxlX3RvX2dlbmVyYXRlKGludCBpbmRleCwgY29uc3QgY2hhciogdmFsdWUpIHsKKyAgZmlsZV90b19nZW5lcmF0ZV8uTXV0YWJsZShpbmRleCktPmFzc2lnbih2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlcXVlc3QuZmlsZV90b19nZW5lcmF0ZSkKK30KKyB2b2lkIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjpzZXRfZmlsZV90b19nZW5lcmF0ZShpbnQgaW5kZXgsIGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBmaWxlX3RvX2dlbmVyYXRlXy5NdXRhYmxlKGluZGV4KS0+YXNzaWduKAorICAgIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlcXVlc3QuZmlsZV90b19nZW5lcmF0ZSkKK30KKyA6OnN0ZDo6c3RyaW5nKiBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6YWRkX2ZpbGVfdG9fZ2VuZXJhdGUoKSB7CisgIHJldHVybiBmaWxlX3RvX2dlbmVyYXRlXy5BZGQoKTsKK30KKyB2b2lkIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjphZGRfZmlsZV90b19nZW5lcmF0ZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBmaWxlX3RvX2dlbmVyYXRlXy5BZGQoKS0+YXNzaWduKHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlcXVlc3QuZmlsZV90b19nZW5lcmF0ZSkKK30KKyB2b2lkIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjphZGRfZmlsZV90b19nZW5lcmF0ZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBmaWxlX3RvX2dlbmVyYXRlXy5BZGQoKS0+YXNzaWduKHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdC5maWxlX3RvX2dlbmVyYXRlKQorfQorIHZvaWQgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OmFkZF9maWxlX3RvX2dlbmVyYXRlKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBmaWxlX3RvX2dlbmVyYXRlXy5BZGQoKS0+YXNzaWduKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlcXVlc3QuZmlsZV90b19nZW5lcmF0ZSkKK30KKyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6c3RkOjpzdHJpbmc+JgorQ29kZUdlbmVyYXRvclJlcXVlc3Q6OmZpbGVfdG9fZ2VuZXJhdGUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdC5maWxlX3RvX2dlbmVyYXRlKQorICByZXR1cm4gZmlsZV90b19nZW5lcmF0ZV87Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6OnN0ZDo6c3RyaW5nPioKK0NvZGVHZW5lcmF0b3JSZXF1ZXN0OjptdXRhYmxlX2ZpbGVfdG9fZ2VuZXJhdGUoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXF1ZXN0LmZpbGVfdG9fZ2VuZXJhdGUpCisgIHJldHVybiAmZmlsZV90b19nZW5lcmF0ZV87Cit9CisKKy8vIG9wdGlvbmFsIHN0cmluZyBwYXJhbWV0ZXIgPSAyOworYm9vbCBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6aGFzX3BhcmFtZXRlcigpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMnUpICE9IDA7Cit9Cit2b2lkIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjpzZXRfaGFzX3BhcmFtZXRlcigpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAydTsKK30KK3ZvaWQgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OmNsZWFyX2hhc19wYXJhbWV0ZXIoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDJ1OworfQordm9pZCBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6Y2xlYXJfcGFyYW1ldGVyKCkgeworICBwYXJhbWV0ZXJfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX3BhcmFtZXRlcigpOworfQorIGNvbnN0IDo6c3RkOjpzdHJpbmcmIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjpwYXJhbWV0ZXIoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXF1ZXN0LnBhcmFtZXRlcikKKyAgcmV0dXJuIHBhcmFtZXRlcl8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OnNldF9wYXJhbWV0ZXIoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgc2V0X2hhc19wYXJhbWV0ZXIoKTsKKyAgcGFyYW1ldGVyXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdC5wYXJhbWV0ZXIpCit9Cisgdm9pZCBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6c2V0X3BhcmFtZXRlcihjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX3BhcmFtZXRlcigpOworICBwYXJhbWV0ZXJfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlcXVlc3QucGFyYW1ldGVyKQorfQorIHZvaWQgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OnNldF9wYXJhbWV0ZXIoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHNldF9oYXNfcGFyYW1ldGVyKCk7CisgIHBhcmFtZXRlcl8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXF1ZXN0LnBhcmFtZXRlcikKK30KKyA6OnN0ZDo6c3RyaW5nKiBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6bXV0YWJsZV9wYXJhbWV0ZXIoKSB7CisgIHNldF9oYXNfcGFyYW1ldGVyKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdC5wYXJhbWV0ZXIpCisgIHJldHVybiBwYXJhbWV0ZXJfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CisgOjpzdGQ6OnN0cmluZyogQ29kZUdlbmVyYXRvclJlcXVlc3Q6OnJlbGVhc2VfcGFyYW1ldGVyKCkgeworICBjbGVhcl9oYXNfcGFyYW1ldGVyKCk7CisgIHJldHVybiBwYXJhbWV0ZXJfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6c2V0X2FsbG9jYXRlZF9wYXJhbWV0ZXIoOjpzdGQ6OnN0cmluZyogcGFyYW1ldGVyKSB7CisgIGlmIChwYXJhbWV0ZXIgIT0gTlVMTCkgeworICAgIHNldF9oYXNfcGFyYW1ldGVyKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX3BhcmFtZXRlcigpOworICB9CisgIHBhcmFtZXRlcl8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHBhcmFtZXRlcik7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdC5wYXJhbWV0ZXIpCit9CisKKy8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90byBwcm90b19maWxlID0gMTU7CitpbnQgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OnByb3RvX2ZpbGVfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIHByb3RvX2ZpbGVfLnNpemUoKTsKK30KK3ZvaWQgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OmNsZWFyX3Byb3RvX2ZpbGUoKSB7CisgIHByb3RvX2ZpbGVfLkNsZWFyKCk7Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVEZXNjcmlwdG9yUHJvdG8mIENvZGVHZW5lcmF0b3JSZXF1ZXN0Ojpwcm90b19maWxlKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdC5wcm90b19maWxlKQorICByZXR1cm4gcHJvdG9fZmlsZV8uR2V0KGluZGV4KTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZURlc2NyaXB0b3JQcm90byogQ29kZUdlbmVyYXRvclJlcXVlc3Q6Om11dGFibGVfcHJvdG9fZmlsZShpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXF1ZXN0LnByb3RvX2ZpbGUpCisgIHJldHVybiBwcm90b19maWxlXy5NdXRhYmxlKGluZGV4KTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZURlc2NyaXB0b3JQcm90byogQ29kZUdlbmVyYXRvclJlcXVlc3Q6OmFkZF9wcm90b19maWxlKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdC5wcm90b19maWxlKQorICByZXR1cm4gcHJvdG9fZmlsZV8uQWRkKCk7Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZURlc2NyaXB0b3JQcm90byA+KgorQ29kZUdlbmVyYXRvclJlcXVlc3Q6Om11dGFibGVfcHJvdG9fZmlsZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlcXVlc3QucHJvdG9fZmlsZSkKKyAgcmV0dXJuICZwcm90b19maWxlXzsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlRGVzY3JpcHRvclByb3RvID4mCitDb2RlR2VuZXJhdG9yUmVxdWVzdDo6cHJvdG9fZmlsZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXF1ZXN0LnByb3RvX2ZpbGUpCisgIHJldHVybiBwcm90b19maWxlXzsKK30KKworI2VuZGlmICAvLyBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisjaWYgIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKK2NvbnN0IGludCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6a05hbWVGaWVsZE51bWJlcjsKK2NvbnN0IGludCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6a0luc2VydGlvblBvaW50RmllbGROdW1iZXI7Citjb25zdCBpbnQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OmtDb250ZW50RmllbGROdW1iZXI7CisjZW5kaWYgIC8vICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCisKK0NvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZSgpCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgeworICBTaGFyZWRDdG9yKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUpCit9CisKK3ZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpIHsKK30KKworQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OkNvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlKGNvbnN0IENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlJiBmcm9tKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpLAorICAgIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgeworICBTaGFyZWRDdG9yKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvcHlfY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlKQorfQorCit2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpTaGFyZWRDdG9yKCkgeworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZygpOworICBfY2FjaGVkX3NpemVfID0gMDsKKyAgbmFtZV8uVW5zYWZlU2V0RGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBpbnNlcnRpb25fcG9pbnRfLlVuc2FmZVNldERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY29udGVudF8uVW5zYWZlU2V0RGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICA6Om1lbXNldChfaGFzX2JpdHNfLCAwLCBzaXplb2YoX2hhc19iaXRzXykpOworfQorCitDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6fkNvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZGVzdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUpCisgIFNoYXJlZER0b3IoKTsKK30KKwordm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6U2hhcmVkRHRvcigpIHsKKyAgbmFtZV8uRGVzdHJveU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgaW5zZXJ0aW9uX3BvaW50Xy5EZXN0cm95Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjb250ZW50Xy5EZXN0cm95Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBpZiAodGhpcyAhPSBkZWZhdWx0X2luc3RhbmNlXykgeworICB9Cit9CisKK3ZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OlNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0IHsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHNpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6ZGVzY3JpcHRvcigpIHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIHJldHVybiBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZV9kZXNjcmlwdG9yXzsKK30KKworY29uc3QgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUmIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpkZWZhdWx0X2luc3RhbmNlKCkgeworICBpZiAoZGVmYXVsdF9pbnN0YW5jZV8gPT0gTlVMTCkgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmNvbXBpbGVyXzJmcGx1Z2luXzJlcHJvdG8oKTsKKyAgcmV0dXJuICpkZWZhdWx0X2luc3RhbmNlXzsKK30KKworQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUqIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpkZWZhdWx0X2luc3RhbmNlXyA9IE5VTEw7CisKK0NvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlKiBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6TmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdCB7CisgIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlKiBuID0gbmV3IENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOworICBpZiAoYXJlbmEgIT0gTlVMTCkgeworICAgIGFyZW5hLT5Pd24obik7CisgIH0KKyAgcmV0dXJuIG47Cit9CisKK3ZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OkNsZWFyKCkgeworICBpZiAoX2hhc19iaXRzX1swIC8gMzJdICYgN3UpIHsKKyAgICBpZiAoaGFzX25hbWUoKSkgeworICAgICAgbmFtZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICAgIH0KKyAgICBpZiAoaGFzX2luc2VydGlvbl9wb2ludCgpKSB7CisgICAgICBpbnNlcnRpb25fcG9pbnRfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgICB9CisgICAgaWYgKGhhc19jb250ZW50KCkpIHsKKyAgICAgIGNvbnRlbnRfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgICB9CisgIH0KKyAgOjptZW1zZXQoX2hhc19iaXRzXywgMCwgc2l6ZW9mKF9oYXNfYml0c18pKTsKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5DbGVhcigpOworICB9Cit9CisKK2Jvb2wgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6Ok1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCkgeworI2RlZmluZSBET18oRVhQUkVTU0lPTikgaWYgKCEoRVhQUkVTU0lPTikpIGdvdG8gZmFpbHVyZQorICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiB0YWc7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdGFydDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUpCisgIGZvciAoOzspIHsKKyAgICA6OnN0ZDo6cGFpcjwgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIsIGJvb2w+IHAgPSBpbnB1dC0+UmVhZFRhZ1dpdGhDdXRvZmYoMTI3KTsKKyAgICB0YWcgPSBwLmZpcnN0OworICAgIGlmICghcC5zZWNvbmQpIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgc3dpdGNoICg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnRmllbGROdW1iZXIodGFnKSkgeworICAgICAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICAgICAgY2FzZSAxOiB7CisgICAgICAgIGlmICh0YWcgPT0gMTApIHsKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoCisgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPm11dGFibGVfbmFtZSgpKSk7CisgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICAgICAgICB0aGlzLT5uYW1lKCkuZGF0YSgpLCB0aGlzLT5uYW1lKCkubGVuZ3RoKCksCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpQQVJTRSwKKyAgICAgICAgICAgICJnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUubmFtZSIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMTgpKSBnb3RvIHBhcnNlX2luc2VydGlvbl9wb2ludDsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIHN0cmluZyBpbnNlcnRpb25fcG9pbnQgPSAyOworICAgICAgY2FzZSAyOiB7CisgICAgICAgIGlmICh0YWcgPT0gMTgpIHsKKyAgICAgICAgIHBhcnNlX2luc2VydGlvbl9wb2ludDoKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoCisgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPm11dGFibGVfaW5zZXJ0aW9uX3BvaW50KCkpKTsKKyAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgICAgICAgIHRoaXMtPmluc2VydGlvbl9wb2ludCgpLmRhdGEoKSwgdGhpcy0+aW5zZXJ0aW9uX3BvaW50KCkubGVuZ3RoKCksCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpQQVJTRSwKKyAgICAgICAgICAgICJnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUuaW5zZXJ0aW9uX3BvaW50Iik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygxMjIpKSBnb3RvIHBhcnNlX2NvbnRlbnQ7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCBzdHJpbmcgY29udGVudCA9IDE1OworICAgICAgY2FzZSAxNTogeworICAgICAgICBpZiAodGFnID09IDEyMikgeworICAgICAgICAgcGFyc2VfY29udGVudDoKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoCisgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPm11dGFibGVfY29udGVudCgpKSk7CisgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICAgICAgICB0aGlzLT5jb250ZW50KCkuZGF0YSgpLCB0aGlzLT5jb250ZW50KCkubGVuZ3RoKCksCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpQQVJTRSwKKyAgICAgICAgICAgICJnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUuY29udGVudCIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RBdEVuZCgpKSBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBkZWZhdWx0OiB7CisgICAgICBoYW5kbGVfdW51c3VhbDoKKyAgICAgICAgaWYgKHRhZyA9PSAwIHx8CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnV2lyZVR5cGUodGFnKSA9PQorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0VORF9HUk9VUCkgeworICAgICAgICAgIGdvdG8gc3VjY2VzczsKKyAgICAgICAgfQorICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2tpcEZpZWxkKAorICAgICAgICAgICAgICBpbnB1dCwgdGFnLCBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CitzdWNjZXNzOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3VjY2Vzczpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUpCisgIHJldHVybiB0cnVlOworZmFpbHVyZToKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX2ZhaWx1cmU6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlKQorICByZXR1cm4gZmFsc2U7CisjdW5kZWYgRE9fCit9CisKK3ZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlKQorICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgIGlmIChoYXNfbmFtZSgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5uYW1lKCkuZGF0YSgpLCB0aGlzLT5uYW1lKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlLm5hbWUiKTsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdNYXliZUFsaWFzZWQoCisgICAgICAxLCB0aGlzLT5uYW1lKCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgaW5zZXJ0aW9uX3BvaW50ID0gMjsKKyAgaWYgKGhhc19pbnNlcnRpb25fcG9pbnQoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+aW5zZXJ0aW9uX3BvaW50KCkuZGF0YSgpLCB0aGlzLT5pbnNlcnRpb25fcG9pbnQoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUuaW5zZXJ0aW9uX3BvaW50Iik7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nTWF5YmVBbGlhc2VkKAorICAgICAgMiwgdGhpcy0+aW5zZXJ0aW9uX3BvaW50KCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgY29udGVudCA9IDE1OworICBpZiAoaGFzX2NvbnRlbnQoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+Y29udGVudCgpLmRhdGEoKSwgdGhpcy0+Y29udGVudCgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZS5jb250ZW50Iik7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nTWF5YmVBbGlhc2VkKAorICAgICAgMTUsIHRoaXMtPmNvbnRlbnQoKSwgb3V0cHV0KTsKKyAgfQorCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25GaWVsZHMoCisgICAgICAgIHVua25vd25fZmllbGRzKCksIG91dHB1dCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9lbmQ6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlKQorfQorCis6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiB0YXJnZXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9zdGFydDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUpCisgIC8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKKyAgaWYgKGhhc19uYW1lKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgIHRoaXMtPm5hbWUoKS5kYXRhKCksIHRoaXMtPm5hbWUoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUubmFtZSIpOworICAgIHRhcmdldCA9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdUb0FycmF5KAorICAgICAgICAxLCB0aGlzLT5uYW1lKCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgaW5zZXJ0aW9uX3BvaW50ID0gMjsKKyAgaWYgKGhhc19pbnNlcnRpb25fcG9pbnQoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+aW5zZXJ0aW9uX3BvaW50KCkuZGF0YSgpLCB0aGlzLT5pbnNlcnRpb25fcG9pbnQoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUuaW5zZXJ0aW9uX3BvaW50Iik7CisgICAgdGFyZ2V0ID0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ1RvQXJyYXkoCisgICAgICAgIDIsIHRoaXMtPmluc2VydGlvbl9wb2ludCgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIGNvbnRlbnQgPSAxNTsKKyAgaWYgKGhhc19jb250ZW50KCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgIHRoaXMtPmNvbnRlbnQoKS5kYXRhKCksIHRoaXMtPmNvbnRlbnQoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUuY29udGVudCIpOworICAgIHRhcmdldCA9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdUb0FycmF5KAorICAgICAgICAxNSwgdGhpcy0+Y29udGVudCgpLCB0YXJnZXQpOworICB9CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bkZpZWxkc1RvQXJyYXkoCisgICAgICAgIHVua25vd25fZmllbGRzKCksIHRhcmdldCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9lbmQ6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlKQorICByZXR1cm4gdGFyZ2V0OworfQorCitpbnQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OkJ5dGVTaXplKCkgY29uc3QgeworICBpbnQgdG90YWxfc2l6ZSA9IDA7CisKKyAgaWYgKF9oYXNfYml0c19bMCAvIDMyXSAmIDd1KSB7CisgICAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICAgIGlmIChoYXNfbmFtZSgpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U3RyaW5nU2l6ZSgKKyAgICAgICAgICB0aGlzLT5uYW1lKCkpOworICAgIH0KKworICAgIC8vIG9wdGlvbmFsIHN0cmluZyBpbnNlcnRpb25fcG9pbnQgPSAyOworICAgIGlmIChoYXNfaW5zZXJ0aW9uX3BvaW50KCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTdHJpbmdTaXplKAorICAgICAgICAgIHRoaXMtPmluc2VydGlvbl9wb2ludCgpKTsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCBzdHJpbmcgY29udGVudCA9IDE1OworICAgIGlmIChoYXNfY29udGVudCgpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U3RyaW5nU2l6ZSgKKyAgICAgICAgICB0aGlzLT5jb250ZW50KCkpOworICAgIH0KKworICB9CisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHRvdGFsX3NpemUgKz0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OkNvbXB1dGVVbmtub3duRmllbGRzU2l6ZSgKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSk7CisgIH0KKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHRvdGFsX3NpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworICByZXR1cm4gdG90YWxfc2l6ZTsKK30KKwordm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6TWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBjb25zdCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZSogc291cmNlID0gCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpEeW5hbWljQ2FzdFRvR2VuZXJhdGVkPGNvbnN0IENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlPigKKyAgICAgICAgICAmZnJvbSk7CisgIGlmIChzb3VyY2UgPT0gTlVMTCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlJlZmxlY3Rpb25PcHM6Ok1lcmdlKGZyb20sIHRoaXMpOworICB9IGVsc2UgeworICAgIE1lcmdlRnJvbSgqc291cmNlKTsKKyAgfQorfQorCit2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpNZXJnZUZyb20oY29uc3QgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgaWYgKGZyb20uX2hhc19iaXRzX1swIC8gMzJdICYgKDB4ZmZ1IDw8ICgwICUgMzIpKSkgeworICAgIGlmIChmcm9tLmhhc19uYW1lKCkpIHsKKyAgICAgIHNldF9oYXNfbmFtZSgpOworICAgICAgbmFtZV8uQXNzaWduV2l0aERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBmcm9tLm5hbWVfKTsKKyAgICB9CisgICAgaWYgKGZyb20uaGFzX2luc2VydGlvbl9wb2ludCgpKSB7CisgICAgICBzZXRfaGFzX2luc2VydGlvbl9wb2ludCgpOworICAgICAgaW5zZXJ0aW9uX3BvaW50Xy5Bc3NpZ25XaXRoRGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGZyb20uaW5zZXJ0aW9uX3BvaW50Xyk7CisgICAgfQorICAgIGlmIChmcm9tLmhhc19jb250ZW50KCkpIHsKKyAgICAgIHNldF9oYXNfY29udGVudCgpOworICAgICAgY29udGVudF8uQXNzaWduV2l0aERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBmcm9tLmNvbnRlbnRfKTsKKyAgICB9CisgIH0KKyAgaWYgKGZyb20uX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPk1lcmdlRnJvbShmcm9tLnVua25vd25fZmllbGRzKCkpOworICB9Cit9CisKK3ZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OkNvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK3ZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OkNvcHlGcm9tKGNvbnN0IENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKworYm9vbCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6SXNJbml0aWFsaXplZCgpIGNvbnN0IHsKKworICByZXR1cm4gdHJ1ZTsKK30KKwordm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6U3dhcChDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZSogb3RoZXIpIHsKKyAgaWYgKG90aGVyID09IHRoaXMpIHJldHVybjsKKyAgSW50ZXJuYWxTd2FwKG90aGVyKTsKK30KK3ZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OkludGVybmFsU3dhcChDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZSogb3RoZXIpIHsKKyAgbmFtZV8uU3dhcCgmb3RoZXItPm5hbWVfKTsKKyAgaW5zZXJ0aW9uX3BvaW50Xy5Td2FwKCZvdGhlci0+aW5zZXJ0aW9uX3BvaW50Xyk7CisgIGNvbnRlbnRfLlN3YXAoJm90aGVyLT5jb250ZW50Xyk7CisgIHN0ZDo6c3dhcChfaGFzX2JpdHNfWzBdLCBvdGhlci0+X2hhc19iaXRzX1swXSk7CisgIF9pbnRlcm5hbF9tZXRhZGF0YV8uU3dhcCgmb3RoZXItPl9pbnRlcm5hbF9tZXRhZGF0YV8pOworICBzdGQ6OnN3YXAoX2NhY2hlZF9zaXplXywgb3RoZXItPl9jYWNoZWRfc2l6ZV8pOworfQorCis6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpHZXRNZXRhZGF0YSgpIGNvbnN0IHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgbWV0YWRhdGE7CisgIG1ldGFkYXRhLmRlc2NyaXB0b3IgPSBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZV9kZXNjcmlwdG9yXzsKKyAgbWV0YWRhdGEucmVmbGVjdGlvbiA9IENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlX3JlZmxlY3Rpb25fOworICByZXR1cm4gbWV0YWRhdGE7Cit9CisKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisjaWYgIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKK2NvbnN0IGludCBDb2RlR2VuZXJhdG9yUmVzcG9uc2U6OmtFcnJvckZpZWxkTnVtYmVyOworY29uc3QgaW50IENvZGVHZW5lcmF0b3JSZXNwb25zZTo6a0ZpbGVGaWVsZE51bWJlcjsKKyNlbmRpZiAgLy8gIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKKworQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpDb2RlR2VuZXJhdG9yUmVzcG9uc2UoKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpLCBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZSkKK30KKwordm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2U6OkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpIHsKK30KKworQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpDb2RlR2VuZXJhdG9yUmVzcG9uc2UoY29uc3QgQ29kZUdlbmVyYXRvclJlc3BvbnNlJiBmcm9tKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpLAorICAgIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgeworICBTaGFyZWRDdG9yKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvcHlfY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZSkKK30KKwordm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2U6OlNoYXJlZEN0b3IoKSB7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSAwOworICBlcnJvcl8uVW5zYWZlU2V0RGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICA6Om1lbXNldChfaGFzX2JpdHNfLCAwLCBzaXplb2YoX2hhc19iaXRzXykpOworfQorCitDb2RlR2VuZXJhdG9yUmVzcG9uc2U6On5Db2RlR2VuZXJhdG9yUmVzcG9uc2UoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChkZXN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UpCisgIFNoYXJlZER0b3IoKTsKK30KKwordm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2U6OlNoYXJlZER0b3IoKSB7CisgIGVycm9yXy5EZXN0cm95Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBpZiAodGhpcyAhPSBkZWZhdWx0X2luc3RhbmNlXykgeworICB9Cit9CisKK3ZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdCB7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSBzaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpkZXNjcmlwdG9yKCkgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgcmV0dXJuIENvZGVHZW5lcmF0b3JSZXNwb25zZV9kZXNjcmlwdG9yXzsKK30KKworY29uc3QgQ29kZUdlbmVyYXRvclJlc3BvbnNlJiBDb2RlR2VuZXJhdG9yUmVzcG9uc2U6OmRlZmF1bHRfaW5zdGFuY2UoKSB7CisgIGlmIChkZWZhdWx0X2luc3RhbmNlXyA9PSBOVUxMKSBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmY29tcGlsZXJfMmZwbHVnaW5fMmVwcm90bygpOworICByZXR1cm4gKmRlZmF1bHRfaW5zdGFuY2VfOworfQorCitDb2RlR2VuZXJhdG9yUmVzcG9uc2UqIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBOVUxMOworCitDb2RlR2VuZXJhdG9yUmVzcG9uc2UqIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6TmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdCB7CisgIENvZGVHZW5lcmF0b3JSZXNwb25zZSogbiA9IG5ldyBDb2RlR2VuZXJhdG9yUmVzcG9uc2U7CisgIGlmIChhcmVuYSAhPSBOVUxMKSB7CisgICAgYXJlbmEtPk93bihuKTsKKyAgfQorICByZXR1cm4gbjsKK30KKwordm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2U6OkNsZWFyKCkgeworICBpZiAoaGFzX2Vycm9yKCkpIHsKKyAgICBlcnJvcl8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICB9CisgIGZpbGVfLkNsZWFyKCk7CisgIDo6bWVtc2V0KF9oYXNfYml0c18sIDAsIHNpemVvZihfaGFzX2JpdHNfKSk7CisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+Q2xlYXIoKTsKKyAgfQorfQorCitib29sIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6TWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KSB7CisjZGVmaW5lIERPXyhFWFBSRVNTSU9OKSBpZiAoIShFWFBSRVNTSU9OKSkgZ290byBmYWlsdXJlCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIHRhZzsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UpCisgIGZvciAoOzspIHsKKyAgICA6OnN0ZDo6cGFpcjwgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIsIGJvb2w+IHAgPSBpbnB1dC0+UmVhZFRhZ1dpdGhDdXRvZmYoMTI3KTsKKyAgICB0YWcgPSBwLmZpcnN0OworICAgIGlmICghcC5zZWNvbmQpIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgc3dpdGNoICg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnRmllbGROdW1iZXIodGFnKSkgeworICAgICAgLy8gb3B0aW9uYWwgc3RyaW5nIGVycm9yID0gMTsKKyAgICAgIGNhc2UgMTogeworICAgICAgICBpZiAodGFnID09IDEwKSB7CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkU3RyaW5nKAorICAgICAgICAgICAgICAgIGlucHV0LCB0aGlzLT5tdXRhYmxlX2Vycm9yKCkpKTsKKyAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgICAgICAgIHRoaXMtPmVycm9yKCkuZGF0YSgpLCB0aGlzLT5lcnJvcigpLmxlbmd0aCgpLAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6UEFSU0UsCisgICAgICAgICAgICAiZ29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5lcnJvciIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMTIyKSkgZ290byBwYXJzZV9maWxlOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZSBmaWxlID0gMTU7CisgICAgICBjYXNlIDE1OiB7CisgICAgICAgIGlmICh0YWcgPT0gMTIyKSB7CisgICAgICAgICBwYXJzZV9maWxlOgorICAgICAgICAgIERPXyhpbnB1dC0+SW5jcmVtZW50UmVjdXJzaW9uRGVwdGgoKSk7CisgICAgICAgICBwYXJzZV9sb29wX2ZpbGU6CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkTWVzc2FnZU5vVmlydHVhbE5vUmVjdXJzaW9uRGVwdGgoCisgICAgICAgICAgICAgICAgaW5wdXQsIGFkZF9maWxlKCkpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDEyMikpIGdvdG8gcGFyc2VfbG9vcF9maWxlOworICAgICAgICBpbnB1dC0+VW5zYWZlRGVjcmVtZW50UmVjdXJzaW9uRGVwdGgoKTsKKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RBdEVuZCgpKSBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBkZWZhdWx0OiB7CisgICAgICBoYW5kbGVfdW51c3VhbDoKKyAgICAgICAgaWYgKHRhZyA9PSAwIHx8CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnV2lyZVR5cGUodGFnKSA9PQorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0VORF9HUk9VUCkgeworICAgICAgICAgIGdvdG8gc3VjY2VzczsKKyAgICAgICAgfQorICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2tpcEZpZWxkKAorICAgICAgICAgICAgICBpbnB1dCwgdGFnLCBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CitzdWNjZXNzOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3VjY2Vzczpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlKQorICByZXR1cm4gdHJ1ZTsKK2ZhaWx1cmU6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9mYWlsdXJlOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UpCisgIHJldHVybiBmYWxzZTsKKyN1bmRlZiBET18KK30KKwordm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2U6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZSkKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIGVycm9yID0gMTsKKyAgaWYgKGhhc19lcnJvcigpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5lcnJvcigpLmRhdGEoKSwgdGhpcy0+ZXJyb3IoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLmVycm9yIik7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nTWF5YmVBbGlhc2VkKAorICAgICAgMSwgdGhpcy0+ZXJyb3IoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUgZmlsZSA9IDE1OworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPmZpbGVfc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlTWVzc2FnZU1heWJlVG9BcnJheSgKKyAgICAgIDE1LCB0aGlzLT5maWxlKGkpLCBvdXRwdXQpOworICB9CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bkZpZWxkcygKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSwgb3V0cHV0KTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX2VuZDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlKQorfQorCis6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBDb2RlR2VuZXJhdG9yUmVzcG9uc2U6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogdGFyZ2V0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZSkKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIGVycm9yID0gMTsKKyAgaWYgKGhhc19lcnJvcigpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5lcnJvcigpLmRhdGEoKSwgdGhpcy0+ZXJyb3IoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLmVycm9yIik7CisgICAgdGFyZ2V0ID0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ1RvQXJyYXkoCisgICAgICAgIDEsIHRoaXMtPmVycm9yKCksIHRhcmdldCk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlIGZpbGUgPSAxNTsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT5maWxlX3NpemUoKTsgaSA8IG47IGkrKykgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjoKKyAgICAgIFdyaXRlTWVzc2FnZU5vVmlydHVhbFRvQXJyYXkoCisgICAgICAgIDE1LCB0aGlzLT5maWxlKGkpLCB0YXJnZXQpOworICB9CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bkZpZWxkc1RvQXJyYXkoCisgICAgICAgIHVua25vd25fZmllbGRzKCksIHRhcmdldCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9lbmQ6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZSkKKyAgcmV0dXJuIHRhcmdldDsKK30KKworaW50IENvZGVHZW5lcmF0b3JSZXNwb25zZTo6Qnl0ZVNpemUoKSBjb25zdCB7CisgIGludCB0b3RhbF9zaXplID0gMDsKKworICAvLyBvcHRpb25hbCBzdHJpbmcgZXJyb3IgPSAxOworICBpZiAoaGFzX2Vycm9yKCkpIHsKKyAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlN0cmluZ1NpemUoCisgICAgICAgIHRoaXMtPmVycm9yKCkpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZSBmaWxlID0gMTU7CisgIHRvdGFsX3NpemUgKz0gMSAqIHRoaXMtPmZpbGVfc2l6ZSgpOworICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPmZpbGVfc2l6ZSgpOyBpKyspIHsKKyAgICB0b3RhbF9zaXplICs9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6TWVzc2FnZVNpemVOb1ZpcnR1YWwoCisgICAgICAgIHRoaXMtPmZpbGUoaSkpOworICB9CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6Q29tcHV0ZVVua25vd25GaWVsZHNTaXplKAorICAgICAgICB1bmtub3duX2ZpZWxkcygpKTsKKyAgfQorICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gdG90YWxfc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7CisgIHJldHVybiB0b3RhbF9zaXplOworfQorCit2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6TWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBjb25zdCBDb2RlR2VuZXJhdG9yUmVzcG9uc2UqIHNvdXJjZSA9IAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RHluYW1pY0Nhc3RUb0dlbmVyYXRlZDxjb25zdCBDb2RlR2VuZXJhdG9yUmVzcG9uc2U+KAorICAgICAgICAgICZmcm9tKTsKKyAgaWYgKHNvdXJjZSA9PSBOVUxMKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6UmVmbGVjdGlvbk9wczo6TWVyZ2UoZnJvbSwgdGhpcyk7CisgIH0gZWxzZSB7CisgICAgTWVyZ2VGcm9tKCpzb3VyY2UpOworICB9Cit9CisKK3ZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpNZXJnZUZyb20oY29uc3QgQ29kZUdlbmVyYXRvclJlc3BvbnNlJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGZpbGVfLk1lcmdlRnJvbShmcm9tLmZpbGVfKTsKKyAgaWYgKGZyb20uX2hhc19iaXRzX1swIC8gMzJdICYgKDB4ZmZ1IDw8ICgwICUgMzIpKSkgeworICAgIGlmIChmcm9tLmhhc19lcnJvcigpKSB7CisgICAgICBzZXRfaGFzX2Vycm9yKCk7CisgICAgICBlcnJvcl8uQXNzaWduV2l0aERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBmcm9tLmVycm9yXyk7CisgICAgfQorICB9CisgIGlmIChmcm9tLl9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5NZXJnZUZyb20oZnJvbS51bmtub3duX2ZpZWxkcygpKTsKKyAgfQorfQorCit2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6Q29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKwordm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2U6OkNvcHlGcm9tKGNvbnN0IENvZGVHZW5lcmF0b3JSZXNwb25zZSYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK2Jvb2wgQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpJc0luaXRpYWxpemVkKCkgY29uc3QgeworCisgIHJldHVybiB0cnVlOworfQorCit2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6U3dhcChDb2RlR2VuZXJhdG9yUmVzcG9uc2UqIG90aGVyKSB7CisgIGlmIChvdGhlciA9PSB0aGlzKSByZXR1cm47CisgIEludGVybmFsU3dhcChvdGhlcik7Cit9Cit2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6SW50ZXJuYWxTd2FwKENvZGVHZW5lcmF0b3JSZXNwb25zZSogb3RoZXIpIHsKKyAgZXJyb3JfLlN3YXAoJm90aGVyLT5lcnJvcl8pOworICBmaWxlXy5VbnNhZmVBcmVuYVN3YXAoJm90aGVyLT5maWxlXyk7CisgIHN0ZDo6c3dhcChfaGFzX2JpdHNfWzBdLCBvdGhlci0+X2hhc19iaXRzX1swXSk7CisgIF9pbnRlcm5hbF9tZXRhZGF0YV8uU3dhcCgmb3RoZXItPl9pbnRlcm5hbF9tZXRhZGF0YV8pOworICBzdGQ6OnN3YXAoX2NhY2hlZF9zaXplXywgb3RoZXItPl9jYWNoZWRfc2l6ZV8pOworfQorCis6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6R2V0TWV0YWRhdGEoKSBjb25zdCB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIG1ldGFkYXRhOworICBtZXRhZGF0YS5kZXNjcmlwdG9yID0gQ29kZUdlbmVyYXRvclJlc3BvbnNlX2Rlc2NyaXB0b3JfOworICBtZXRhZGF0YS5yZWZsZWN0aW9uID0gQ29kZUdlbmVyYXRvclJlc3BvbnNlX3JlZmxlY3Rpb25fOworICByZXR1cm4gbWV0YWRhdGE7Cit9CisKKyNpZiBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKy8vIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlCisKKy8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKK2Jvb2wgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6Omhhc19uYW1lKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAxdSkgIT0gMDsKK30KK3ZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OnNldF9oYXNfbmFtZSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAxdTsKK30KK3ZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OmNsZWFyX2hhc19uYW1lKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAxdTsKK30KK3ZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OmNsZWFyX25hbWUoKSB7CisgIG5hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX25hbWUoKTsKK30KKyBjb25zdCA6OnN0ZDo6c3RyaW5nJiBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6bmFtZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUubmFtZSkKKyAgcmV0dXJuIG5hbWVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpzZXRfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUubmFtZSkKK30KKyB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZS5uYW1lKQorfQorIHZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OnNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlLm5hbWUpCit9CisgOjpzdGQ6OnN0cmluZyogQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6Om11dGFibGVfbmFtZSgpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZS5uYW1lKQorICByZXR1cm4gbmFtZV8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyA6OnN0ZDo6c3RyaW5nKiBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6cmVsZWFzZV9uYW1lKCkgeworICBjbGVhcl9oYXNfbmFtZSgpOworICByZXR1cm4gbmFtZV8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpzZXRfYWxsb2NhdGVkX25hbWUoOjpzdGQ6OnN0cmluZyogbmFtZSkgeworICBpZiAobmFtZSAhPSBOVUxMKSB7CisgICAgc2V0X2hhc19uYW1lKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX25hbWUoKTsKKyAgfQorICBuYW1lXy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgbmFtZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZS5uYW1lKQorfQorCisvLyBvcHRpb25hbCBzdHJpbmcgaW5zZXJ0aW9uX3BvaW50ID0gMjsKK2Jvb2wgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6Omhhc19pbnNlcnRpb25fcG9pbnQoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDJ1KSAhPSAwOworfQordm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6c2V0X2hhc19pbnNlcnRpb25fcG9pbnQoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMnU7Cit9Cit2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpjbGVhcl9oYXNfaW5zZXJ0aW9uX3BvaW50KCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAydTsKK30KK3ZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OmNsZWFyX2luc2VydGlvbl9wb2ludCgpIHsKKyAgaW5zZXJ0aW9uX3BvaW50Xy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGNsZWFyX2hhc19pbnNlcnRpb25fcG9pbnQoKTsKK30KKyBjb25zdCA6OnN0ZDo6c3RyaW5nJiBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6aW5zZXJ0aW9uX3BvaW50KCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZS5pbnNlcnRpb25fcG9pbnQpCisgIHJldHVybiBpbnNlcnRpb25fcG9pbnRfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpzZXRfaW5zZXJ0aW9uX3BvaW50KGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfaW5zZXJ0aW9uX3BvaW50KCk7CisgIGluc2VydGlvbl9wb2ludF8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUuaW5zZXJ0aW9uX3BvaW50KQorfQorIHZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OnNldF9pbnNlcnRpb25fcG9pbnQoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgc2V0X2hhc19pbnNlcnRpb25fcG9pbnQoKTsKKyAgaW5zZXJ0aW9uX3BvaW50Xy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlLmluc2VydGlvbl9wb2ludCkKK30KKyB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpzZXRfaW5zZXJ0aW9uX3BvaW50KGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX2luc2VydGlvbl9wb2ludCgpOworICBpbnNlcnRpb25fcG9pbnRfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZS5pbnNlcnRpb25fcG9pbnQpCit9CisgOjpzdGQ6OnN0cmluZyogQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6Om11dGFibGVfaW5zZXJ0aW9uX3BvaW50KCkgeworICBzZXRfaGFzX2luc2VydGlvbl9wb2ludCgpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUuaW5zZXJ0aW9uX3BvaW50KQorICByZXR1cm4gaW5zZXJ0aW9uX3BvaW50Xy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIDo6c3RkOjpzdHJpbmcqIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpyZWxlYXNlX2luc2VydGlvbl9wb2ludCgpIHsKKyAgY2xlYXJfaGFzX2luc2VydGlvbl9wb2ludCgpOworICByZXR1cm4gaW5zZXJ0aW9uX3BvaW50Xy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OnNldF9hbGxvY2F0ZWRfaW5zZXJ0aW9uX3BvaW50KDo6c3RkOjpzdHJpbmcqIGluc2VydGlvbl9wb2ludCkgeworICBpZiAoaW5zZXJ0aW9uX3BvaW50ICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX2luc2VydGlvbl9wb2ludCgpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19pbnNlcnRpb25fcG9pbnQoKTsKKyAgfQorICBpbnNlcnRpb25fcG9pbnRfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBpbnNlcnRpb25fcG9pbnQpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUuaW5zZXJ0aW9uX3BvaW50KQorfQorCisvLyBvcHRpb25hbCBzdHJpbmcgY29udGVudCA9IDE1OworYm9vbCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6aGFzX2NvbnRlbnQoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDR1KSAhPSAwOworfQordm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6c2V0X2hhc19jb250ZW50KCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDR1OworfQordm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6Y2xlYXJfaGFzX2NvbnRlbnQoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDR1OworfQordm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6Y2xlYXJfY29udGVudCgpIHsKKyAgY29udGVudF8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfY29udGVudCgpOworfQorIGNvbnN0IDo6c3RkOjpzdHJpbmcmIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpjb250ZW50KCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZS5jb250ZW50KQorICByZXR1cm4gY29udGVudF8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OnNldF9jb250ZW50KGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfY29udGVudCgpOworICBjb250ZW50Xy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZS5jb250ZW50KQorfQorIHZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OnNldF9jb250ZW50KGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfY29udGVudCgpOworICBjb250ZW50Xy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlLmNvbnRlbnQpCit9Cisgdm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6c2V0X2NvbnRlbnQoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHNldF9oYXNfY29udGVudCgpOworICBjb250ZW50Xy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUuY29udGVudCkKK30KKyA6OnN0ZDo6c3RyaW5nKiBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6bXV0YWJsZV9jb250ZW50KCkgeworICBzZXRfaGFzX2NvbnRlbnQoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlLmNvbnRlbnQpCisgIHJldHVybiBjb250ZW50Xy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIDo6c3RkOjpzdHJpbmcqIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpyZWxlYXNlX2NvbnRlbnQoKSB7CisgIGNsZWFyX2hhc19jb250ZW50KCk7CisgIHJldHVybiBjb250ZW50Xy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OnNldF9hbGxvY2F0ZWRfY29udGVudCg6OnN0ZDo6c3RyaW5nKiBjb250ZW50KSB7CisgIGlmIChjb250ZW50ICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX2NvbnRlbnQoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfY29udGVudCgpOworICB9CisgIGNvbnRlbnRfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBjb250ZW50KTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlLmNvbnRlbnQpCit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gQ29kZUdlbmVyYXRvclJlc3BvbnNlCisKKy8vIG9wdGlvbmFsIHN0cmluZyBlcnJvciA9IDE7Citib29sIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6aGFzX2Vycm9yKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAxdSkgIT0gMDsKK30KK3ZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpzZXRfaGFzX2Vycm9yKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDF1OworfQordm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2U6OmNsZWFyX2hhc19lcnJvcigpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMXU7Cit9Cit2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6Y2xlYXJfZXJyb3IoKSB7CisgIGVycm9yXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGNsZWFyX2hhc19lcnJvcigpOworfQorIGNvbnN0IDo6c3RkOjpzdHJpbmcmIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6ZXJyb3IoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5lcnJvcikKKyAgcmV0dXJuIGVycm9yXy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2U6OnNldF9lcnJvcihjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBzZXRfaGFzX2Vycm9yKCk7CisgIGVycm9yXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuZXJyb3IpCit9Cisgdm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2U6OnNldF9lcnJvcihjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX2Vycm9yKCk7CisgIGVycm9yXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5lcnJvcikKK30KKyB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6c2V0X2Vycm9yKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX2Vycm9yKCk7CisgIGVycm9yXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLmVycm9yKQorfQorIDo6c3RkOjpzdHJpbmcqIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6bXV0YWJsZV9lcnJvcigpIHsKKyAgc2V0X2hhc19lcnJvcigpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLmVycm9yKQorICByZXR1cm4gZXJyb3JfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CisgOjpzdGQ6OnN0cmluZyogQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpyZWxlYXNlX2Vycm9yKCkgeworICBjbGVhcl9oYXNfZXJyb3IoKTsKKyAgcmV0dXJuIGVycm9yXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpzZXRfYWxsb2NhdGVkX2Vycm9yKDo6c3RkOjpzdHJpbmcqIGVycm9yKSB7CisgIGlmIChlcnJvciAhPSBOVUxMKSB7CisgICAgc2V0X2hhc19lcnJvcigpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19lcnJvcigpOworICB9CisgIGVycm9yXy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgZXJyb3IpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLmVycm9yKQorfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlIGZpbGUgPSAxNTsKK2ludCBDb2RlR2VuZXJhdG9yUmVzcG9uc2U6OmZpbGVfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIGZpbGVfLnNpemUoKTsKK30KK3ZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpjbGVhcl9maWxlKCkgeworICBmaWxlXy5DbGVhcigpOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpjb21waWxlcjo6Q29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUmIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6ZmlsZShpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLmZpbGUpCisgIHJldHVybiBmaWxlXy5HZXQoaW5kZXgpOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpjb21waWxlcjo6Q29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUqIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6bXV0YWJsZV9maWxlKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLmZpbGUpCisgIHJldHVybiBmaWxlXy5NdXRhYmxlKGluZGV4KTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6Y29tcGlsZXI6OkNvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlKiBDb2RlR2VuZXJhdG9yUmVzcG9uc2U6OmFkZF9maWxlKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuZmlsZSkKKyAgcmV0dXJuIGZpbGVfLkFkZCgpOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OmNvbXBpbGVyOjpDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZSA+KgorQ29kZUdlbmVyYXRvclJlc3BvbnNlOjptdXRhYmxlX2ZpbGUoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5maWxlKQorICByZXR1cm4gJmZpbGVfOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OmNvbXBpbGVyOjpDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZSA+JgorQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpmaWxlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLmZpbGUpCisgIHJldHVybiBmaWxlXzsKK30KKworI2VuZGlmICAvLyBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKworLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG5hbWVzcGFjZV9zY29wZSkKKworfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGdsb2JhbF9zY29wZSkKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLnBiLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BsdWdpbi5wYi5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBhMDNlOTcKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3BsdWdpbi5wYi5oCkBAIC0wLDAgKzEsODEyIEBACisvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQorLy8gc291cmNlOiBnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLnByb3RvCisKKyNpZm5kZWYgUFJPVE9CVUZfZ29vZ2xlXzJmcHJvdG9idWZfMmZjb21waWxlcl8yZnBsdWdpbl8yZXByb3RvX19JTkNMVURFRAorI2RlZmluZSBQUk9UT0JVRl9nb29nbGVfMmZwcm90b2J1Zl8yZmNvbXBpbGVyXzJmcGx1Z2luXzJlcHJvdG9fX0lOQ0xVREVECisKKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisKKyNpZiBHT09HTEVfUFJPVE9CVUZfVkVSU0lPTiA8IDMwMDAwMDAKKyNlcnJvciBUaGlzIGZpbGUgd2FzIGdlbmVyYXRlZCBieSBhIG5ld2VyIHZlcnNpb24gb2YgcHJvdG9jIHdoaWNoIGlzCisjZXJyb3IgaW5jb21wYXRpYmxlIHdpdGggeW91ciBQcm90b2NvbCBCdWZmZXIgaGVhZGVycy4gIFBsZWFzZSB1cGRhdGUKKyNlcnJvciB5b3VyIGhlYWRlcnMuCisjZW5kaWYKKyNpZiAzMDAwMDAwIDwgR09PR0xFX1BST1RPQlVGX01JTl9QUk9UT0NfVkVSU0lPTgorI2Vycm9yIFRoaXMgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IGFuIG9sZGVyIHZlcnNpb24gb2YgcHJvdG9jIHdoaWNoIGlzCisjZXJyb3IgaW5jb21wYXRpYmxlIHdpdGggeW91ciBQcm90b2NvbCBCdWZmZXIgaGVhZGVycy4gIFBsZWFzZQorI2Vycm9yIHJlZ2VuZXJhdGUgdGhpcyBmaWxlIHdpdGggYSBuZXdlciB2ZXJzaW9uIG9mIHByb3RvYy4KKyNlbmRpZgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2FyZW5hLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2FyZW5hc3RyaW5nLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9tZXNzYWdlX3V0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWV0YWRhdGEuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWVzc2FnZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9yZXBlYXRlZF9maWVsZC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9leHRlbnNpb25fc2V0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Vua25vd25fZmllbGRfc2V0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaD4KKy8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbmNsdWRlcykKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKKworLy8gSW50ZXJuYWwgaW1wbGVtZW50YXRpb24gZGV0YWlsIC0tIGRvIG5vdCBjYWxsIHRoZXNlLgordm9pZCBMSUJQUk9UT0NfRVhQT1JUIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZjb21waWxlcl8yZnBsdWdpbl8yZXByb3RvKCk7Cit2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZjb21waWxlcl8yZnBsdWdpbl8yZXByb3RvKCk7Cit2b2lkIHByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZmNvbXBpbGVyXzJmcGx1Z2luXzJlcHJvdG8oKTsKKworY2xhc3MgQ29kZUdlbmVyYXRvclJlcXVlc3Q7CitjbGFzcyBDb2RlR2VuZXJhdG9yUmVzcG9uc2U7CitjbGFzcyBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTsKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitjbGFzcyBMSUJQUk9UT0NfRVhQT1JUIENvZGVHZW5lcmF0b3JSZXF1ZXN0IDogcHVibGljIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSB7CisgcHVibGljOgorICBDb2RlR2VuZXJhdG9yUmVxdWVzdCgpOworICB2aXJ0dWFsIH5Db2RlR2VuZXJhdG9yUmVxdWVzdCgpOworCisgIENvZGVHZW5lcmF0b3JSZXF1ZXN0KGNvbnN0IENvZGVHZW5lcmF0b3JSZXF1ZXN0JiBmcm9tKTsKKworICBpbmxpbmUgQ29kZUdlbmVyYXRvclJlcXVlc3QmIG9wZXJhdG9yPShjb25zdCBDb2RlR2VuZXJhdG9yUmVxdWVzdCYgZnJvbSkgeworICAgIENvcHlGcm9tKGZyb20pOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIGlubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlVua25vd25GaWVsZFNldCYgdW5rbm93bl9maWVsZHMoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8udW5rbm93bl9maWVsZHMoKTsKKyAgfQorCisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlVua25vd25GaWVsZFNldCogbXV0YWJsZV91bmtub3duX2ZpZWxkcygpIHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5tdXRhYmxlX3Vua25vd25fZmllbGRzKCk7CisgIH0KKworICBzdGF0aWMgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKCk7CisgIHN0YXRpYyBjb25zdCBDb2RlR2VuZXJhdG9yUmVxdWVzdCYgZGVmYXVsdF9pbnN0YW5jZSgpOworCisgIHZvaWQgU3dhcChDb2RlR2VuZXJhdG9yUmVxdWVzdCogb3RoZXIpOworCisgIC8vIGltcGxlbWVudHMgTWVzc2FnZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgaW5saW5lIENvZGVHZW5lcmF0b3JSZXF1ZXN0KiBOZXcoKSBjb25zdCB7IHJldHVybiBOZXcoTlVMTCk7IH0KKworICBDb2RlR2VuZXJhdG9yUmVxdWVzdCogTmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdDsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIENvcHlGcm9tKGNvbnN0IENvZGVHZW5lcmF0b3JSZXF1ZXN0JiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgQ29kZUdlbmVyYXRvclJlcXVlc3QmIGZyb20pOworICB2b2lkIENsZWFyKCk7CisgIGJvb2wgSXNJbml0aWFsaXplZCgpIGNvbnN0OworCisgIGludCBCeXRlU2l6ZSgpIGNvbnN0OworICBib29sIE1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KTsKKyAgdm9pZCBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSg6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBvdXRwdXQpIGNvbnN0OworICBpbnQgR2V0Q2FjaGVkU2l6ZSgpIGNvbnN0IHsgcmV0dXJuIF9jYWNoZWRfc2l6ZV87IH0KKyAgcHJpdmF0ZToKKyAgdm9pZCBTaGFyZWRDdG9yKCk7CisgIHZvaWQgU2hhcmVkRHRvcigpOworICB2b2lkIFNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0OworICB2b2lkIEludGVybmFsU3dhcChDb2RlR2VuZXJhdG9yUmVxdWVzdCogb3RoZXIpOworICBwcml2YXRlOgorICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogR2V0QXJlbmFOb1ZpcnR1YWwoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8uYXJlbmEoKTsKKyAgfQorICBpbmxpbmUgdm9pZCogTWF5YmVBcmVuYVB0cigpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5yYXdfYXJlbmFfcHRyKCk7CisgIH0KKyAgcHVibGljOgorCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgR2V0TWV0YWRhdGEoKSBjb25zdDsKKworICAvLyBuZXN0ZWQgdHlwZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIGFjY2Vzc29ycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gcmVwZWF0ZWQgc3RyaW5nIGZpbGVfdG9fZ2VuZXJhdGUgPSAxOworICBpbnQgZmlsZV90b19nZW5lcmF0ZV9zaXplKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfZmlsZV90b19nZW5lcmF0ZSgpOworICBzdGF0aWMgY29uc3QgaW50IGtGaWxlVG9HZW5lcmF0ZUZpZWxkTnVtYmVyID0gMTsKKyAgY29uc3QgOjpzdGQ6OnN0cmluZyYgZmlsZV90b19nZW5lcmF0ZShpbnQgaW5kZXgpIGNvbnN0OworICA6OnN0ZDo6c3RyaW5nKiBtdXRhYmxlX2ZpbGVfdG9fZ2VuZXJhdGUoaW50IGluZGV4KTsKKyAgdm9pZCBzZXRfZmlsZV90b19nZW5lcmF0ZShpbnQgaW5kZXgsIGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKTsKKyAgdm9pZCBzZXRfZmlsZV90b19nZW5lcmF0ZShpbnQgaW5kZXgsIGNvbnN0IGNoYXIqIHZhbHVlKTsKKyAgdm9pZCBzZXRfZmlsZV90b19nZW5lcmF0ZShpbnQgaW5kZXgsIGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIDo6c3RkOjpzdHJpbmcqIGFkZF9maWxlX3RvX2dlbmVyYXRlKCk7CisgIHZvaWQgYWRkX2ZpbGVfdG9fZ2VuZXJhdGUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpOworICB2b2lkIGFkZF9maWxlX3RvX2dlbmVyYXRlKGNvbnN0IGNoYXIqIHZhbHVlKTsKKyAgdm9pZCBhZGRfZmlsZV90b19nZW5lcmF0ZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6c3RkOjpzdHJpbmc+JiBmaWxlX3RvX2dlbmVyYXRlKCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpzdGQ6OnN0cmluZz4qIG11dGFibGVfZmlsZV90b19nZW5lcmF0ZSgpOworCisgIC8vIG9wdGlvbmFsIHN0cmluZyBwYXJhbWV0ZXIgPSAyOworICBib29sIGhhc19wYXJhbWV0ZXIoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9wYXJhbWV0ZXIoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrUGFyYW1ldGVyRmllbGROdW1iZXIgPSAyOworICBjb25zdCA6OnN0ZDo6c3RyaW5nJiBwYXJhbWV0ZXIoKSBjb25zdDsKKyAgdm9pZCBzZXRfcGFyYW1ldGVyKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKTsKKyAgdm9pZCBzZXRfcGFyYW1ldGVyKGNvbnN0IGNoYXIqIHZhbHVlKTsKKyAgdm9pZCBzZXRfcGFyYW1ldGVyKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIDo6c3RkOjpzdHJpbmcqIG11dGFibGVfcGFyYW1ldGVyKCk7CisgIDo6c3RkOjpzdHJpbmcqIHJlbGVhc2VfcGFyYW1ldGVyKCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF9wYXJhbWV0ZXIoOjpzdGQ6OnN0cmluZyogcGFyYW1ldGVyKTsKKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8gcHJvdG9fZmlsZSA9IDE1OworICBpbnQgcHJvdG9fZmlsZV9zaXplKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfcHJvdG9fZmlsZSgpOworICBzdGF0aWMgY29uc3QgaW50IGtQcm90b0ZpbGVGaWVsZE51bWJlciA9IDE1OworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVEZXNjcmlwdG9yUHJvdG8mIHByb3RvX2ZpbGUoaW50IGluZGV4KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlRGVzY3JpcHRvclByb3RvKiBtdXRhYmxlX3Byb3RvX2ZpbGUoaW50IGluZGV4KTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlRGVzY3JpcHRvclByb3RvKiBhZGRfcHJvdG9fZmlsZSgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZURlc2NyaXB0b3JQcm90byA+KgorICAgICAgbXV0YWJsZV9wcm90b19maWxlKCk7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlRGVzY3JpcHRvclByb3RvID4mCisgICAgICBwcm90b19maWxlKCkgY29uc3Q7CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdCkKKyBwcml2YXRlOgorICBpbmxpbmUgdm9pZCBzZXRfaGFzX3BhcmFtZXRlcigpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfcGFyYW1ldGVyKCk7CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6SW50ZXJuYWxNZXRhZGF0YVdpdGhBcmVuYSBfaW50ZXJuYWxfbWV0YWRhdGFfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiBfaGFzX2JpdHNfWzFdOworICBtdXRhYmxlIGludCBfY2FjaGVkX3NpemVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6c3RkOjpzdHJpbmc+IGZpbGVfdG9fZ2VuZXJhdGVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBcmVuYVN0cmluZ1B0ciBwYXJhbWV0ZXJfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZURlc2NyaXB0b3JQcm90byA+IHByb3RvX2ZpbGVfOworICBmcmllbmQgdm9pZCBMSUJQUk9UT0NfRVhQT1JUIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZjb21waWxlcl8yZnBsdWdpbl8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZjb21waWxlcl8yZnBsdWdpbl8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZmNvbXBpbGVyXzJmcGx1Z2luXzJlcHJvdG8oKTsKKworICB2b2lkIEluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICBzdGF0aWMgQ29kZUdlbmVyYXRvclJlcXVlc3QqIGRlZmF1bHRfaW5zdGFuY2VfOworfTsKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgTElCUFJPVE9DX0VYUE9SVCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZSA6IHB1YmxpYyA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UgeworIHB1YmxpYzoKKyAgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUoKTsKKyAgdmlydHVhbCB+Q29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUoKTsKKworICBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZShjb25zdCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZSYgZnJvbSk7CisKKyAgaW5saW5lIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlJiBvcGVyYXRvcj0oY29uc3QgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUmIGZyb20pIHsKKyAgICBDb3B5RnJvbShmcm9tKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworICBpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpVbmtub3duRmllbGRTZXQmIHVua25vd25fZmllbGRzKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnVua25vd25fZmllbGRzKCk7CisgIH0KKworICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpVbmtub3duRmllbGRTZXQqIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ubXV0YWJsZV91bmtub3duX2ZpZWxkcygpOworICB9CisKKyAgc3RhdGljIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogZGVzY3JpcHRvcigpOworICBzdGF0aWMgY29uc3QgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUmIGRlZmF1bHRfaW5zdGFuY2UoKTsKKworICB2b2lkIFN3YXAoQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUqIG90aGVyKTsKKworICAvLyBpbXBsZW1lbnRzIE1lc3NhZ2UgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIGlubGluZSBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZSogTmV3KCkgY29uc3QgeyByZXR1cm4gTmV3KE5VTEwpOyB9CisKKyAgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUqIE5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3Q7CisgIHZvaWQgQ29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZSYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlJiBmcm9tKTsKKyAgdm9pZCBDbGVhcigpOworICBib29sIElzSW5pdGlhbGl6ZWQoKSBjb25zdDsKKworICBpbnQgQnl0ZVNpemUoKSBjb25zdDsKKyAgYm9vbCBNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCk7CisgIHZvaWQgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogb3V0cHV0KSBjb25zdDsKKyAgaW50IEdldENhY2hlZFNpemUoKSBjb25zdCB7IHJldHVybiBfY2FjaGVkX3NpemVfOyB9CisgIHByaXZhdGU6CisgIHZvaWQgU2hhcmVkQ3RvcigpOworICB2b2lkIFNoYXJlZER0b3IoKTsKKyAgdm9pZCBTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdDsKKyAgdm9pZCBJbnRlcm5hbFN3YXAoQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUqIG90aGVyKTsKKyAgcHJpdmF0ZToKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hTm9WaXJ0dWFsKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLmFyZW5hKCk7CisgIH0KKyAgaW5saW5lIHZvaWQqIE1heWJlQXJlbmFQdHIoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ucmF3X2FyZW5hX3B0cigpOworICB9CisgIHB1YmxpYzoKKworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEdldE1ldGFkYXRhKCkgY29uc3Q7CisKKyAgLy8gbmVzdGVkIHR5cGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBhY2Nlc3NvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKKyAgYm9vbCBoYXNfbmFtZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX25hbWUoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrTmFtZUZpZWxkTnVtYmVyID0gMTsKKyAgY29uc3QgOjpzdGQ6OnN0cmluZyYgbmFtZSgpIGNvbnN0OworICB2b2lkIHNldF9uYW1lKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKTsKKyAgdm9pZCBzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSk7CisgIHZvaWQgc2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKTsKKyAgOjpzdGQ6OnN0cmluZyogbXV0YWJsZV9uYW1lKCk7CisgIDo6c3RkOjpzdHJpbmcqIHJlbGVhc2VfbmFtZSgpOworICB2b2lkIHNldF9hbGxvY2F0ZWRfbmFtZSg6OnN0ZDo6c3RyaW5nKiBuYW1lKTsKKworICAvLyBvcHRpb25hbCBzdHJpbmcgaW5zZXJ0aW9uX3BvaW50ID0gMjsKKyAgYm9vbCBoYXNfaW5zZXJ0aW9uX3BvaW50KCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfaW5zZXJ0aW9uX3BvaW50KCk7CisgIHN0YXRpYyBjb25zdCBpbnQga0luc2VydGlvblBvaW50RmllbGROdW1iZXIgPSAyOworICBjb25zdCA6OnN0ZDo6c3RyaW5nJiBpbnNlcnRpb25fcG9pbnQoKSBjb25zdDsKKyAgdm9pZCBzZXRfaW5zZXJ0aW9uX3BvaW50KGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKTsKKyAgdm9pZCBzZXRfaW5zZXJ0aW9uX3BvaW50KGNvbnN0IGNoYXIqIHZhbHVlKTsKKyAgdm9pZCBzZXRfaW5zZXJ0aW9uX3BvaW50KGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIDo6c3RkOjpzdHJpbmcqIG11dGFibGVfaW5zZXJ0aW9uX3BvaW50KCk7CisgIDo6c3RkOjpzdHJpbmcqIHJlbGVhc2VfaW5zZXJ0aW9uX3BvaW50KCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF9pbnNlcnRpb25fcG9pbnQoOjpzdGQ6OnN0cmluZyogaW5zZXJ0aW9uX3BvaW50KTsKKworICAvLyBvcHRpb25hbCBzdHJpbmcgY29udGVudCA9IDE1OworICBib29sIGhhc19jb250ZW50KCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfY29udGVudCgpOworICBzdGF0aWMgY29uc3QgaW50IGtDb250ZW50RmllbGROdW1iZXIgPSAxNTsKKyAgY29uc3QgOjpzdGQ6OnN0cmluZyYgY29udGVudCgpIGNvbnN0OworICB2b2lkIHNldF9jb250ZW50KGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKTsKKyAgdm9pZCBzZXRfY29udGVudChjb25zdCBjaGFyKiB2YWx1ZSk7CisgIHZvaWQgc2V0X2NvbnRlbnQoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKTsKKyAgOjpzdGQ6OnN0cmluZyogbXV0YWJsZV9jb250ZW50KCk7CisgIDo6c3RkOjpzdHJpbmcqIHJlbGVhc2VfY29udGVudCgpOworICB2b2lkIHNldF9hbGxvY2F0ZWRfY29udGVudCg6OnN0ZDo6c3RyaW5nKiBjb250ZW50KTsKKworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlKQorIHByaXZhdGU6CisgIGlubGluZSB2b2lkIHNldF9oYXNfbmFtZSgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfbmFtZSgpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX2luc2VydGlvbl9wb2ludCgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfaW5zZXJ0aW9uX3BvaW50KCk7CisgIGlubGluZSB2b2lkIHNldF9oYXNfY29udGVudCgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfY29udGVudCgpOworCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEgX2ludGVybmFsX21ldGFkYXRhXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgX2hhc19iaXRzX1sxXTsKKyAgbXV0YWJsZSBpbnQgX2NhY2hlZF9zaXplXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QXJlbmFTdHJpbmdQdHIgbmFtZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFyZW5hU3RyaW5nUHRyIGluc2VydGlvbl9wb2ludF87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFyZW5hU3RyaW5nUHRyIGNvbnRlbnRfOworICBmcmllbmQgdm9pZCBMSUJQUk9UT0NfRVhQT1JUIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZjb21waWxlcl8yZnBsdWdpbl8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZjb21waWxlcl8yZnBsdWdpbl8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZmNvbXBpbGVyXzJmcGx1Z2luXzJlcHJvdG8oKTsKKworICB2b2lkIEluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICBzdGF0aWMgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUqIGRlZmF1bHRfaW5zdGFuY2VfOworfTsKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgTElCUFJPVE9DX0VYUE9SVCBDb2RlR2VuZXJhdG9yUmVzcG9uc2UgOiBwdWJsaWMgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlIHsKKyBwdWJsaWM6CisgIENvZGVHZW5lcmF0b3JSZXNwb25zZSgpOworICB2aXJ0dWFsIH5Db2RlR2VuZXJhdG9yUmVzcG9uc2UoKTsKKworICBDb2RlR2VuZXJhdG9yUmVzcG9uc2UoY29uc3QgQ29kZUdlbmVyYXRvclJlc3BvbnNlJiBmcm9tKTsKKworICBpbmxpbmUgQ29kZUdlbmVyYXRvclJlc3BvbnNlJiBvcGVyYXRvcj0oY29uc3QgQ29kZUdlbmVyYXRvclJlc3BvbnNlJiBmcm9tKSB7CisgICAgQ29weUZyb20oZnJvbSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgaW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcygpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy51bmtub3duX2ZpZWxkcygpOworICB9CisKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5rbm93bkZpZWxkU2V0KiBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLm11dGFibGVfdW5rbm93bl9maWVsZHMoKTsKKyAgfQorCisgIHN0YXRpYyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIGRlc2NyaXB0b3IoKTsKKyAgc3RhdGljIGNvbnN0IENvZGVHZW5lcmF0b3JSZXNwb25zZSYgZGVmYXVsdF9pbnN0YW5jZSgpOworCisgIHZvaWQgU3dhcChDb2RlR2VuZXJhdG9yUmVzcG9uc2UqIG90aGVyKTsKKworICAvLyBpbXBsZW1lbnRzIE1lc3NhZ2UgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIGlubGluZSBDb2RlR2VuZXJhdG9yUmVzcG9uc2UqIE5ldygpIGNvbnN0IHsgcmV0dXJuIE5ldyhOVUxMKTsgfQorCisgIENvZGVHZW5lcmF0b3JSZXNwb25zZSogTmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdDsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIENvcHlGcm9tKGNvbnN0IENvZGVHZW5lcmF0b3JSZXNwb25zZSYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IENvZGVHZW5lcmF0b3JSZXNwb25zZSYgZnJvbSk7CisgIHZvaWQgQ2xlYXIoKTsKKyAgYm9vbCBJc0luaXRpYWxpemVkKCkgY29uc3Q7CisKKyAgaW50IEJ5dGVTaXplKCkgY29uc3Q7CisgIGJvb2wgTWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpOworICB2b2lkIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIG91dHB1dCkgY29uc3Q7CisgIGludCBHZXRDYWNoZWRTaXplKCkgY29uc3QgeyByZXR1cm4gX2NhY2hlZF9zaXplXzsgfQorICBwcml2YXRlOgorICB2b2lkIFNoYXJlZEN0b3IoKTsKKyAgdm9pZCBTaGFyZWREdG9yKCk7CisgIHZvaWQgU2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3Q7CisgIHZvaWQgSW50ZXJuYWxTd2FwKENvZGVHZW5lcmF0b3JSZXNwb25zZSogb3RoZXIpOworICBwcml2YXRlOgorICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogR2V0QXJlbmFOb1ZpcnR1YWwoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8uYXJlbmEoKTsKKyAgfQorICBpbmxpbmUgdm9pZCogTWF5YmVBcmVuYVB0cigpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5yYXdfYXJlbmFfcHRyKCk7CisgIH0KKyAgcHVibGljOgorCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgR2V0TWV0YWRhdGEoKSBjb25zdDsKKworICAvLyBuZXN0ZWQgdHlwZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIHR5cGVkZWYgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUgRmlsZTsKKworICAvLyBhY2Nlc3NvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIG9wdGlvbmFsIHN0cmluZyBlcnJvciA9IDE7CisgIGJvb2wgaGFzX2Vycm9yKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfZXJyb3IoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrRXJyb3JGaWVsZE51bWJlciA9IDE7CisgIGNvbnN0IDo6c3RkOjpzdHJpbmcmIGVycm9yKCkgY29uc3Q7CisgIHZvaWQgc2V0X2Vycm9yKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKTsKKyAgdm9pZCBzZXRfZXJyb3IoY29uc3QgY2hhciogdmFsdWUpOworICB2b2lkIHNldF9lcnJvcihjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpOworICA6OnN0ZDo6c3RyaW5nKiBtdXRhYmxlX2Vycm9yKCk7CisgIDo6c3RkOjpzdHJpbmcqIHJlbGVhc2VfZXJyb3IoKTsKKyAgdm9pZCBzZXRfYWxsb2NhdGVkX2Vycm9yKDo6c3RkOjpzdHJpbmcqIGVycm9yKTsKKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlIGZpbGUgPSAxNTsKKyAgaW50IGZpbGVfc2l6ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX2ZpbGUoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrRmlsZUZpZWxkTnVtYmVyID0gMTU7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6Y29tcGlsZXI6OkNvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlJiBmaWxlKGludCBpbmRleCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6Y29tcGlsZXI6OkNvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlKiBtdXRhYmxlX2ZpbGUoaW50IGluZGV4KTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpjb21waWxlcjo6Q29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUqIGFkZF9maWxlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpjb21waWxlcjo6Q29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUgPioKKyAgICAgIG11dGFibGVfZmlsZSgpOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6Y29tcGlsZXI6OkNvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlID4mCisgICAgICBmaWxlKCkgY29uc3Q7CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UpCisgcHJpdmF0ZToKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19lcnJvcigpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfZXJyb3IoKTsKKworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpJbnRlcm5hbE1ldGFkYXRhV2l0aEFyZW5hIF9pbnRlcm5hbF9tZXRhZGF0YV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIF9oYXNfYml0c19bMV07CisgIG11dGFibGUgaW50IF9jYWNoZWRfc2l6ZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFyZW5hU3RyaW5nUHRyIGVycm9yXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OmNvbXBpbGVyOjpDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZSA+IGZpbGVfOworICBmcmllbmQgdm9pZCBMSUJQUk9UT0NfRVhQT1JUIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZjb21waWxlcl8yZnBsdWdpbl8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZjb21waWxlcl8yZnBsdWdpbl8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZmNvbXBpbGVyXzJmcGx1Z2luXzJlcHJvdG8oKTsKKworICB2b2lkIEluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICBzdGF0aWMgQ29kZUdlbmVyYXRvclJlc3BvbnNlKiBkZWZhdWx0X2luc3RhbmNlXzsKK307CisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisjaWYgIVBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworLy8gQ29kZUdlbmVyYXRvclJlcXVlc3QKKworLy8gcmVwZWF0ZWQgc3RyaW5nIGZpbGVfdG9fZ2VuZXJhdGUgPSAxOworaW5saW5lIGludCBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6ZmlsZV90b19nZW5lcmF0ZV9zaXplKCkgY29uc3QgeworICByZXR1cm4gZmlsZV90b19nZW5lcmF0ZV8uc2l6ZSgpOworfQoraW5saW5lIHZvaWQgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OmNsZWFyX2ZpbGVfdG9fZ2VuZXJhdGUoKSB7CisgIGZpbGVfdG9fZ2VuZXJhdGVfLkNsZWFyKCk7Cit9CitpbmxpbmUgY29uc3QgOjpzdGQ6OnN0cmluZyYgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OmZpbGVfdG9fZ2VuZXJhdGUoaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXF1ZXN0LmZpbGVfdG9fZ2VuZXJhdGUpCisgIHJldHVybiBmaWxlX3RvX2dlbmVyYXRlXy5HZXQoaW5kZXgpOworfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjptdXRhYmxlX2ZpbGVfdG9fZ2VuZXJhdGUoaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdC5maWxlX3RvX2dlbmVyYXRlKQorICByZXR1cm4gZmlsZV90b19nZW5lcmF0ZV8uTXV0YWJsZShpbmRleCk7Cit9CitpbmxpbmUgdm9pZCBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6c2V0X2ZpbGVfdG9fZ2VuZXJhdGUoaW50IGluZGV4LCBjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdC5maWxlX3RvX2dlbmVyYXRlKQorICBmaWxlX3RvX2dlbmVyYXRlXy5NdXRhYmxlKGluZGV4KS0+YXNzaWduKHZhbHVlKTsKK30KK2lubGluZSB2b2lkIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjpzZXRfZmlsZV90b19nZW5lcmF0ZShpbnQgaW5kZXgsIGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIGZpbGVfdG9fZ2VuZXJhdGVfLk11dGFibGUoaW5kZXgpLT5hc3NpZ24odmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXF1ZXN0LmZpbGVfdG9fZ2VuZXJhdGUpCit9CitpbmxpbmUgdm9pZCBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6c2V0X2ZpbGVfdG9fZ2VuZXJhdGUoaW50IGluZGV4LCBjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgZmlsZV90b19nZW5lcmF0ZV8uTXV0YWJsZShpbmRleCktPmFzc2lnbigKKyAgICByZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXF1ZXN0LmZpbGVfdG9fZ2VuZXJhdGUpCit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogQ29kZUdlbmVyYXRvclJlcXVlc3Q6OmFkZF9maWxlX3RvX2dlbmVyYXRlKCkgeworICByZXR1cm4gZmlsZV90b19nZW5lcmF0ZV8uQWRkKCk7Cit9CitpbmxpbmUgdm9pZCBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6YWRkX2ZpbGVfdG9fZ2VuZXJhdGUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgZmlsZV90b19nZW5lcmF0ZV8uQWRkKCktPmFzc2lnbih2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXF1ZXN0LmZpbGVfdG9fZ2VuZXJhdGUpCit9CitpbmxpbmUgdm9pZCBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6YWRkX2ZpbGVfdG9fZ2VuZXJhdGUoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgZmlsZV90b19nZW5lcmF0ZV8uQWRkKCktPmFzc2lnbih2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGRfY2hhcjpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlcXVlc3QuZmlsZV90b19nZW5lcmF0ZSkKK30KK2lubGluZSB2b2lkIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjphZGRfZmlsZV90b19nZW5lcmF0ZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgZmlsZV90b19nZW5lcmF0ZV8uQWRkKCktPmFzc2lnbihyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkX3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXF1ZXN0LmZpbGVfdG9fZ2VuZXJhdGUpCit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6OnN0ZDo6c3RyaW5nPiYKK0NvZGVHZW5lcmF0b3JSZXF1ZXN0OjpmaWxlX3RvX2dlbmVyYXRlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlcXVlc3QuZmlsZV90b19nZW5lcmF0ZSkKKyAgcmV0dXJuIGZpbGVfdG9fZ2VuZXJhdGVfOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpzdGQ6OnN0cmluZz4qCitDb2RlR2VuZXJhdG9yUmVxdWVzdDo6bXV0YWJsZV9maWxlX3RvX2dlbmVyYXRlKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdC5maWxlX3RvX2dlbmVyYXRlKQorICByZXR1cm4gJmZpbGVfdG9fZ2VuZXJhdGVfOworfQorCisvLyBvcHRpb25hbCBzdHJpbmcgcGFyYW1ldGVyID0gMjsKK2lubGluZSBib29sIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjpoYXNfcGFyYW1ldGVyKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAydSkgIT0gMDsKK30KK2lubGluZSB2b2lkIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjpzZXRfaGFzX3BhcmFtZXRlcigpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAydTsKK30KK2lubGluZSB2b2lkIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjpjbGVhcl9oYXNfcGFyYW1ldGVyKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAydTsKK30KK2lubGluZSB2b2lkIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjpjbGVhcl9wYXJhbWV0ZXIoKSB7CisgIHBhcmFtZXRlcl8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfcGFyYW1ldGVyKCk7Cit9CitpbmxpbmUgY29uc3QgOjpzdGQ6OnN0cmluZyYgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OnBhcmFtZXRlcigpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlcXVlc3QucGFyYW1ldGVyKQorICByZXR1cm4gcGFyYW1ldGVyXy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6c2V0X3BhcmFtZXRlcihjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBzZXRfaGFzX3BhcmFtZXRlcigpOworICBwYXJhbWV0ZXJfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXF1ZXN0LnBhcmFtZXRlcikKK30KK2lubGluZSB2b2lkIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjpzZXRfcGFyYW1ldGVyKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfcGFyYW1ldGVyKCk7CisgIHBhcmFtZXRlcl8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdC5wYXJhbWV0ZXIpCit9CitpbmxpbmUgdm9pZCBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6c2V0X3BhcmFtZXRlcihjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19wYXJhbWV0ZXIoKTsKKyAgcGFyYW1ldGVyXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlcXVlc3QucGFyYW1ldGVyKQorfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjptdXRhYmxlX3BhcmFtZXRlcigpIHsKKyAgc2V0X2hhc19wYXJhbWV0ZXIoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXF1ZXN0LnBhcmFtZXRlcikKKyAgcmV0dXJuIHBhcmFtZXRlcl8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBDb2RlR2VuZXJhdG9yUmVxdWVzdDo6cmVsZWFzZV9wYXJhbWV0ZXIoKSB7CisgIGNsZWFyX2hhc19wYXJhbWV0ZXIoKTsKKyAgcmV0dXJuIHBhcmFtZXRlcl8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjpzZXRfYWxsb2NhdGVkX3BhcmFtZXRlcig6OnN0ZDo6c3RyaW5nKiBwYXJhbWV0ZXIpIHsKKyAgaWYgKHBhcmFtZXRlciAhPSBOVUxMKSB7CisgICAgc2V0X2hhc19wYXJhbWV0ZXIoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfcGFyYW1ldGVyKCk7CisgIH0KKyAgcGFyYW1ldGVyXy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgcGFyYW1ldGVyKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXF1ZXN0LnBhcmFtZXRlcikKK30KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvIHByb3RvX2ZpbGUgPSAxNTsKK2lubGluZSBpbnQgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OnByb3RvX2ZpbGVfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIHByb3RvX2ZpbGVfLnNpemUoKTsKK30KK2lubGluZSB2b2lkIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjpjbGVhcl9wcm90b19maWxlKCkgeworICBwcm90b19maWxlXy5DbGVhcigpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZURlc2NyaXB0b3JQcm90byYgQ29kZUdlbmVyYXRvclJlcXVlc3Q6OnByb3RvX2ZpbGUoaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXF1ZXN0LnByb3RvX2ZpbGUpCisgIHJldHVybiBwcm90b19maWxlXy5HZXQoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZURlc2NyaXB0b3JQcm90byogQ29kZUdlbmVyYXRvclJlcXVlc3Q6Om11dGFibGVfcHJvdG9fZmlsZShpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXF1ZXN0LnByb3RvX2ZpbGUpCisgIHJldHVybiBwcm90b19maWxlXy5NdXRhYmxlKGluZGV4KTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVEZXNjcmlwdG9yUHJvdG8qIENvZGVHZW5lcmF0b3JSZXF1ZXN0OjphZGRfcHJvdG9fZmlsZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlcXVlc3QucHJvdG9fZmlsZSkKKyAgcmV0dXJuIHByb3RvX2ZpbGVfLkFkZCgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlRGVzY3JpcHRvclByb3RvID4qCitDb2RlR2VuZXJhdG9yUmVxdWVzdDo6bXV0YWJsZV9wcm90b19maWxlKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVxdWVzdC5wcm90b19maWxlKQorICByZXR1cm4gJnByb3RvX2ZpbGVfOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlRGVzY3JpcHRvclByb3RvID4mCitDb2RlR2VuZXJhdG9yUmVxdWVzdDo6cHJvdG9fZmlsZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXF1ZXN0LnByb3RvX2ZpbGUpCisgIHJldHVybiBwcm90b19maWxlXzsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZQorCisvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CitpbmxpbmUgYm9vbCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6aGFzX25hbWUoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDF1KSAhPSAwOworfQoraW5saW5lIHZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OnNldF9oYXNfbmFtZSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAxdTsKK30KK2lubGluZSB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpjbGVhcl9oYXNfbmFtZSgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMXU7Cit9CitpbmxpbmUgdm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6Y2xlYXJfbmFtZSgpIHsKKyAgbmFtZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfbmFtZSgpOworfQoraW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpuYW1lKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZS5uYW1lKQorICByZXR1cm4gbmFtZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OnNldF9uYW1lKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfbmFtZSgpOworICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZS5uYW1lKQorfQoraW5saW5lIHZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OnNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfbmFtZSgpOworICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlLm5hbWUpCit9CitpbmxpbmUgdm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6c2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHNldF9oYXNfbmFtZSgpOworICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUubmFtZSkKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6bXV0YWJsZV9uYW1lKCkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlLm5hbWUpCisgIHJldHVybiBuYW1lXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpyZWxlYXNlX25hbWUoKSB7CisgIGNsZWFyX2hhc19uYW1lKCk7CisgIHJldHVybiBuYW1lXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OnNldF9hbGxvY2F0ZWRfbmFtZSg6OnN0ZDo6c3RyaW5nKiBuYW1lKSB7CisgIGlmIChuYW1lICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX25hbWUoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfbmFtZSgpOworICB9CisgIG5hbWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBuYW1lKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlLm5hbWUpCit9CisKKy8vIG9wdGlvbmFsIHN0cmluZyBpbnNlcnRpb25fcG9pbnQgPSAyOworaW5saW5lIGJvb2wgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6Omhhc19pbnNlcnRpb25fcG9pbnQoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDJ1KSAhPSAwOworfQoraW5saW5lIHZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OnNldF9oYXNfaW5zZXJ0aW9uX3BvaW50KCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDJ1OworfQoraW5saW5lIHZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OmNsZWFyX2hhc19pbnNlcnRpb25fcG9pbnQoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDJ1OworfQoraW5saW5lIHZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OmNsZWFyX2luc2VydGlvbl9wb2ludCgpIHsKKyAgaW5zZXJ0aW9uX3BvaW50Xy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGNsZWFyX2hhc19pbnNlcnRpb25fcG9pbnQoKTsKK30KK2lubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6aW5zZXJ0aW9uX3BvaW50KCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZS5pbnNlcnRpb25fcG9pbnQpCisgIHJldHVybiBpbnNlcnRpb25fcG9pbnRfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpzZXRfaW5zZXJ0aW9uX3BvaW50KGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfaW5zZXJ0aW9uX3BvaW50KCk7CisgIGluc2VydGlvbl9wb2ludF8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUuaW5zZXJ0aW9uX3BvaW50KQorfQoraW5saW5lIHZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OnNldF9pbnNlcnRpb25fcG9pbnQoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgc2V0X2hhc19pbnNlcnRpb25fcG9pbnQoKTsKKyAgaW5zZXJ0aW9uX3BvaW50Xy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlLmluc2VydGlvbl9wb2ludCkKK30KK2lubGluZSB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpzZXRfaW5zZXJ0aW9uX3BvaW50KGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX2luc2VydGlvbl9wb2ludCgpOworICBpbnNlcnRpb25fcG9pbnRfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZS5pbnNlcnRpb25fcG9pbnQpCit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6Om11dGFibGVfaW5zZXJ0aW9uX3BvaW50KCkgeworICBzZXRfaGFzX2luc2VydGlvbl9wb2ludCgpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUuaW5zZXJ0aW9uX3BvaW50KQorICByZXR1cm4gaW5zZXJ0aW9uX3BvaW50Xy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpyZWxlYXNlX2luc2VydGlvbl9wb2ludCgpIHsKKyAgY2xlYXJfaGFzX2luc2VydGlvbl9wb2ludCgpOworICByZXR1cm4gaW5zZXJ0aW9uX3BvaW50Xy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OnNldF9hbGxvY2F0ZWRfaW5zZXJ0aW9uX3BvaW50KDo6c3RkOjpzdHJpbmcqIGluc2VydGlvbl9wb2ludCkgeworICBpZiAoaW5zZXJ0aW9uX3BvaW50ICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX2luc2VydGlvbl9wb2ludCgpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19pbnNlcnRpb25fcG9pbnQoKTsKKyAgfQorICBpbnNlcnRpb25fcG9pbnRfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBpbnNlcnRpb25fcG9pbnQpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUuaW5zZXJ0aW9uX3BvaW50KQorfQorCisvLyBvcHRpb25hbCBzdHJpbmcgY29udGVudCA9IDE1OworaW5saW5lIGJvb2wgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6Omhhc19jb250ZW50KCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDA0dSkgIT0gMDsKK30KK2lubGluZSB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpzZXRfaGFzX2NvbnRlbnQoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwNHU7Cit9CitpbmxpbmUgdm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6Y2xlYXJfaGFzX2NvbnRlbnQoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDR1OworfQoraW5saW5lIHZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OmNsZWFyX2NvbnRlbnQoKSB7CisgIGNvbnRlbnRfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX2NvbnRlbnQoKTsKK30KK2lubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6Y29udGVudCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUuY29udGVudCkKKyAgcmV0dXJuIGNvbnRlbnRfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpzZXRfY29udGVudChjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBzZXRfaGFzX2NvbnRlbnQoKTsKKyAgY29udGVudF8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUuY29udGVudCkKK30KK2lubGluZSB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpzZXRfY29udGVudChjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX2NvbnRlbnQoKTsKKyAgY29udGVudF8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZS5jb250ZW50KQorfQoraW5saW5lIHZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6OnNldF9jb250ZW50KGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX2NvbnRlbnQoKTsKKyAgY29udGVudF8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlLmNvbnRlbnQpCit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogQ29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGU6Om11dGFibGVfY29udGVudCgpIHsKKyAgc2V0X2hhc19jb250ZW50KCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZS5jb250ZW50KQorICByZXR1cm4gY29udGVudF8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZTo6cmVsZWFzZV9jb250ZW50KCkgeworICBjbGVhcl9oYXNfY29udGVudCgpOworICByZXR1cm4gY29udGVudF8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlOjpzZXRfYWxsb2NhdGVkX2NvbnRlbnQoOjpzdGQ6OnN0cmluZyogY29udGVudCkgeworICBpZiAoY29udGVudCAhPSBOVUxMKSB7CisgICAgc2V0X2hhc19jb250ZW50KCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX2NvbnRlbnQoKTsKKyAgfQorICBjb250ZW50Xy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgY29udGVudCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZS5jb250ZW50KQorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIENvZGVHZW5lcmF0b3JSZXNwb25zZQorCisvLyBvcHRpb25hbCBzdHJpbmcgZXJyb3IgPSAxOworaW5saW5lIGJvb2wgQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpoYXNfZXJyb3IoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDF1KSAhPSAwOworfQoraW5saW5lIHZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpzZXRfaGFzX2Vycm9yKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDF1OworfQoraW5saW5lIHZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpjbGVhcl9oYXNfZXJyb3IoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDF1OworfQoraW5saW5lIHZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpjbGVhcl9lcnJvcigpIHsKKyAgZXJyb3JfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX2Vycm9yKCk7Cit9CitpbmxpbmUgY29uc3QgOjpzdGQ6OnN0cmluZyYgQ29kZUdlbmVyYXRvclJlc3BvbnNlOjplcnJvcigpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLmVycm9yKQorICByZXR1cm4gZXJyb3JfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6c2V0X2Vycm9yKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfZXJyb3IoKTsKKyAgZXJyb3JfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5lcnJvcikKK30KK2lubGluZSB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6c2V0X2Vycm9yKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfZXJyb3IoKTsKKyAgZXJyb3JfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLmVycm9yKQorfQoraW5saW5lIHZvaWQgQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpzZXRfZXJyb3IoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHNldF9oYXNfZXJyb3IoKTsKKyAgZXJyb3JfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuZXJyb3IpCit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogQ29kZUdlbmVyYXRvclJlc3BvbnNlOjptdXRhYmxlX2Vycm9yKCkgeworICBzZXRfaGFzX2Vycm9yKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuZXJyb3IpCisgIHJldHVybiBlcnJvcl8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBDb2RlR2VuZXJhdG9yUmVzcG9uc2U6OnJlbGVhc2VfZXJyb3IoKSB7CisgIGNsZWFyX2hhc19lcnJvcigpOworICByZXR1cm4gZXJyb3JfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2U6OnNldF9hbGxvY2F0ZWRfZXJyb3IoOjpzdGQ6OnN0cmluZyogZXJyb3IpIHsKKyAgaWYgKGVycm9yICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX2Vycm9yKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX2Vycm9yKCk7CisgIH0KKyAgZXJyb3JfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBlcnJvcik7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuZXJyb3IpCit9CisKKy8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLkZpbGUgZmlsZSA9IDE1OworaW5saW5lIGludCBDb2RlR2VuZXJhdG9yUmVzcG9uc2U6OmZpbGVfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIGZpbGVfLnNpemUoKTsKK30KK2lubGluZSB2b2lkIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6Y2xlYXJfZmlsZSgpIHsKKyAgZmlsZV8uQ2xlYXIoKTsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OmNvbXBpbGVyOjpDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZSYgQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpmaWxlKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5jb21waWxlci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuZmlsZSkKKyAgcmV0dXJuIGZpbGVfLkdldChpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpjb21waWxlcjo6Q29kZUdlbmVyYXRvclJlc3BvbnNlX0ZpbGUqIENvZGVHZW5lcmF0b3JSZXNwb25zZTo6bXV0YWJsZV9maWxlKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLmZpbGUpCisgIHJldHVybiBmaWxlXy5NdXRhYmxlKGluZGV4KTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OmNvbXBpbGVyOjpDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZSogQ29kZUdlbmVyYXRvclJlc3BvbnNlOjphZGRfZmlsZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLmZpbGUpCisgIHJldHVybiBmaWxlXy5BZGQoKTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6Y29tcGlsZXI6OkNvZGVHZW5lcmF0b3JSZXNwb25zZV9GaWxlID4qCitDb2RlR2VuZXJhdG9yUmVzcG9uc2U6Om11dGFibGVfZmlsZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLmZpbGUpCisgIHJldHVybiAmZmlsZV87Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OmNvbXBpbGVyOjpDb2RlR2VuZXJhdG9yUmVzcG9uc2VfRmlsZSA+JgorQ29kZUdlbmVyYXRvclJlc3BvbnNlOjpmaWxlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdlbmVyYXRvclJlc3BvbnNlLmZpbGUpCisgIHJldHVybiBmaWxlXzsKK30KKworI2VuZGlmICAvLyAhUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworCisvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobmFtZXNwYWNlX3Njb3BlKQorCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZ2xvYmFsX3Njb3BlKQorCisjZW5kaWYgIC8vIFBST1RPQlVGX2dvb2dsZV8yZnByb3RvYnVmXzJmY29tcGlsZXJfMmZwbHVnaW5fMmVwcm90b19fSU5DTFVERUQKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLnByb3RvIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wbHVnaW4ucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWNhZWUxZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLnByb3RvCkBAIC0wLDAgKzEsMTUwIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8KKy8vIFdBUk5JTkc6ICBUaGUgcGx1Z2luIGludGVyZmFjZSBpcyBjdXJyZW50bHkgRVhQRVJJTUVOVEFMIGFuZCBpcyBzdWJqZWN0IHRvCisvLyAgIGNoYW5nZS4KKy8vCisvLyBwcm90b2MgKGFrYSB0aGUgUHJvdG9jb2wgQ29tcGlsZXIpIGNhbiBiZSBleHRlbmRlZCB2aWEgcGx1Z2lucy4gIEEgcGx1Z2luIGlzCisvLyBqdXN0IGEgcHJvZ3JhbSB0aGF0IHJlYWRzIGEgQ29kZUdlbmVyYXRvclJlcXVlc3QgZnJvbSBzdGRpbiBhbmQgd3JpdGVzIGEKKy8vIENvZGVHZW5lcmF0b3JSZXNwb25zZSB0byBzdGRvdXQuCisvLworLy8gUGx1Z2lucyB3cml0dGVuIHVzaW5nIEMrKyBjYW4gdXNlIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9wbHVnaW4uaCBpbnN0ZWFkCisvLyBvZiBkZWFsaW5nIHdpdGggdGhlIHJhdyBwcm90b2NvbCBkZWZpbmVkIGhlcmUuCisvLworLy8gQSBwbHVnaW4gZXhlY3V0YWJsZSBuZWVkcyBvbmx5IHRvIGJlIHBsYWNlZCBzb21ld2hlcmUgaW4gdGhlIHBhdGguICBUaGUKKy8vIHBsdWdpbiBzaG91bGQgYmUgbmFtZWQgInByb3RvYy1nZW4tJE5BTUUiLCBhbmQgd2lsbCB0aGVuIGJlIHVzZWQgd2hlbiB0aGUKKy8vIGZsYWcgIi0tJHtOQU1FfV9vdXQiIGlzIHBhc3NlZCB0byBwcm90b2MuCisKK3N5bnRheCA9ICJwcm90bzIiOworcGFja2FnZSBnb29nbGUucHJvdG9idWYuY29tcGlsZXI7CitvcHRpb24gamF2YV9wYWNrYWdlID0gImNvbS5nb29nbGUucHJvdG9idWYuY29tcGlsZXIiOworb3B0aW9uIGphdmFfb3V0ZXJfY2xhc3NuYW1lID0gIlBsdWdpblByb3RvcyI7CisKK29wdGlvbiBnb19wYWNrYWdlID0gInBsdWdpbl9nbyI7CisKK2ltcG9ydCAiZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8iOworCisvLyBBbiBlbmNvZGVkIENvZGVHZW5lcmF0b3JSZXF1ZXN0IGlzIHdyaXR0ZW4gdG8gdGhlIHBsdWdpbidzIHN0ZGluLgorbWVzc2FnZSBDb2RlR2VuZXJhdG9yUmVxdWVzdCB7CisgIC8vIFRoZSAucHJvdG8gZmlsZXMgdGhhdCB3ZXJlIGV4cGxpY2l0bHkgbGlzdGVkIG9uIHRoZSBjb21tYW5kLWxpbmUuICBUaGUKKyAgLy8gY29kZSBnZW5lcmF0b3Igc2hvdWxkIGdlbmVyYXRlIGNvZGUgb25seSBmb3IgdGhlc2UgZmlsZXMuICBFYWNoIGZpbGUncworICAvLyBkZXNjcmlwdG9yIHdpbGwgYmUgaW5jbHVkZWQgaW4gcHJvdG9fZmlsZSwgYmVsb3cuCisgIHJlcGVhdGVkIHN0cmluZyBmaWxlX3RvX2dlbmVyYXRlID0gMTsKKworICAvLyBUaGUgZ2VuZXJhdG9yIHBhcmFtZXRlciBwYXNzZWQgb24gdGhlIGNvbW1hbmQtbGluZS4KKyAgb3B0aW9uYWwgc3RyaW5nIHBhcmFtZXRlciA9IDI7CisKKyAgLy8gRmlsZURlc2NyaXB0b3JQcm90b3MgZm9yIGFsbCBmaWxlcyBpbiBmaWxlc190b19nZW5lcmF0ZSBhbmQgZXZlcnl0aGluZworICAvLyB0aGV5IGltcG9ydC4gIFRoZSBmaWxlcyB3aWxsIGFwcGVhciBpbiB0b3BvbG9naWNhbCBvcmRlciwgc28gZWFjaCBmaWxlCisgIC8vIGFwcGVhcnMgYmVmb3JlIGFueSBmaWxlIHRoYXQgaW1wb3J0cyBpdC4KKyAgLy8KKyAgLy8gcHJvdG9jIGd1YXJhbnRlZXMgdGhhdCBhbGwgcHJvdG9fZmlsZXMgd2lsbCBiZSB3cml0dGVuIGFmdGVyCisgIC8vIHRoZSBmaWVsZHMgYWJvdmUsIGV2ZW4gdGhvdWdoIHRoaXMgaXMgbm90IHRlY2huaWNhbGx5IGd1YXJhbnRlZWQgYnkgdGhlCisgIC8vIHByb3RvYnVmIHdpcmUgZm9ybWF0LiAgVGhpcyB0aGVvcmV0aWNhbGx5IGNvdWxkIGFsbG93IGEgcGx1Z2luIHRvIHN0cmVhbQorICAvLyBpbiB0aGUgRmlsZURlc2NyaXB0b3JQcm90b3MgYW5kIGhhbmRsZSB0aGVtIG9uZSBieSBvbmUgcmF0aGVyIHRoYW4gcmVhZAorICAvLyB0aGUgZW50aXJlIHNldCBpbnRvIG1lbW9yeSBhdCBvbmNlLiAgSG93ZXZlciwgYXMgb2YgdGhpcyB3cml0aW5nLCB0aGlzCisgIC8vIGlzIG5vdCBzaW1pbGFybHkgb3B0aW1pemVkIG9uIHByb3RvYydzIGVuZCAtLSBpdCB3aWxsIHN0b3JlIGFsbCBmaWVsZHMgaW4KKyAgLy8gbWVtb3J5IGF0IG9uY2UgYmVmb3JlIHNlbmRpbmcgdGhlbSB0byB0aGUgcGx1Z2luLgorICByZXBlYXRlZCBGaWxlRGVzY3JpcHRvclByb3RvIHByb3RvX2ZpbGUgPSAxNTsKK30KKworLy8gVGhlIHBsdWdpbiB3cml0ZXMgYW4gZW5jb2RlZCBDb2RlR2VuZXJhdG9yUmVzcG9uc2UgdG8gc3Rkb3V0LgorbWVzc2FnZSBDb2RlR2VuZXJhdG9yUmVzcG9uc2UgeworICAvLyBFcnJvciBtZXNzYWdlLiAgSWYgbm9uLWVtcHR5LCBjb2RlIGdlbmVyYXRpb24gZmFpbGVkLiAgVGhlIHBsdWdpbiBwcm9jZXNzCisgIC8vIHNob3VsZCBleGl0IHdpdGggc3RhdHVzIGNvZGUgemVybyBldmVuIGlmIGl0IHJlcG9ydHMgYW4gZXJyb3IgaW4gdGhpcyB3YXkuCisgIC8vCisgIC8vIFRoaXMgc2hvdWxkIGJlIHVzZWQgdG8gaW5kaWNhdGUgZXJyb3JzIGluIC5wcm90byBmaWxlcyB3aGljaCBwcmV2ZW50IHRoZQorICAvLyBjb2RlIGdlbmVyYXRvciBmcm9tIGdlbmVyYXRpbmcgY29ycmVjdCBjb2RlLiAgRXJyb3JzIHdoaWNoIGluZGljYXRlIGEKKyAgLy8gcHJvYmxlbSBpbiBwcm90b2MgaXRzZWxmIC0tIHN1Y2ggYXMgdGhlIGlucHV0IENvZGVHZW5lcmF0b3JSZXF1ZXN0IGJlaW5nCisgIC8vIHVucGFyc2VhYmxlIC0tIHNob3VsZCBiZSByZXBvcnRlZCBieSB3cml0aW5nIGEgbWVzc2FnZSB0byBzdGRlcnIgYW5kCisgIC8vIGV4aXRpbmcgd2l0aCBhIG5vbi16ZXJvIHN0YXR1cyBjb2RlLgorICBvcHRpb25hbCBzdHJpbmcgZXJyb3IgPSAxOworCisgIC8vIFJlcHJlc2VudHMgYSBzaW5nbGUgZ2VuZXJhdGVkIGZpbGUuCisgIG1lc3NhZ2UgRmlsZSB7CisgICAgLy8gVGhlIGZpbGUgbmFtZSwgcmVsYXRpdmUgdG8gdGhlIG91dHB1dCBkaXJlY3RvcnkuICBUaGUgbmFtZSBtdXN0IG5vdAorICAgIC8vIGNvbnRhaW4gIi4iIG9yICIuLiIgY29tcG9uZW50cyBhbmQgbXVzdCBiZSByZWxhdGl2ZSwgbm90IGJlIGFic29sdXRlIChzbywKKyAgICAvLyB0aGUgZmlsZSBjYW5ub3QgbGllIG91dHNpZGUgdGhlIG91dHB1dCBkaXJlY3RvcnkpLiAgIi8iIG11c3QgYmUgdXNlZCBhcworICAgIC8vIHRoZSBwYXRoIHNlcGFyYXRvciwgbm90ICJcIi4KKyAgICAvLworICAgIC8vIElmIHRoZSBuYW1lIGlzIG9taXR0ZWQsIHRoZSBjb250ZW50IHdpbGwgYmUgYXBwZW5kZWQgdG8gdGhlIHByZXZpb3VzCisgICAgLy8gZmlsZS4gIFRoaXMgYWxsb3dzIHRoZSBnZW5lcmF0b3IgdG8gYnJlYWsgbGFyZ2UgZmlsZXMgaW50byBzbWFsbCBjaHVua3MsCisgICAgLy8gYW5kIGFsbG93cyB0aGUgZ2VuZXJhdGVkIHRleHQgdG8gYmUgc3RyZWFtZWQgYmFjayB0byBwcm90b2Mgc28gdGhhdCBsYXJnZQorICAgIC8vIGZpbGVzIG5lZWQgbm90IHJlc2lkZSBjb21wbGV0ZWx5IGluIG1lbW9yeSBhdCBvbmUgdGltZS4gIE5vdGUgdGhhdCBhcyBvZgorICAgIC8vIHRoaXMgd3JpdGluZyBwcm90b2MgZG9lcyBub3Qgb3B0aW1pemUgZm9yIHRoaXMgLS0gaXQgd2lsbCByZWFkIHRoZSBlbnRpcmUKKyAgICAvLyBDb2RlR2VuZXJhdG9yUmVzcG9uc2UgYmVmb3JlIHdyaXRpbmcgZmlsZXMgdG8gZGlzay4KKyAgICBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisKKyAgICAvLyBJZiBub24tZW1wdHksIGluZGljYXRlcyB0aGF0IHRoZSBuYW1lZCBmaWxlIHNob3VsZCBhbHJlYWR5IGV4aXN0LCBhbmQgdGhlCisgICAgLy8gY29udGVudCBoZXJlIGlzIHRvIGJlIGluc2VydGVkIGludG8gdGhhdCBmaWxlIGF0IGEgZGVmaW5lZCBpbnNlcnRpb24KKyAgICAvLyBwb2ludC4gIFRoaXMgZmVhdHVyZSBhbGxvd3MgYSBjb2RlIGdlbmVyYXRvciB0byBleHRlbmQgdGhlIG91dHB1dAorICAgIC8vIHByb2R1Y2VkIGJ5IGFub3RoZXIgY29kZSBnZW5lcmF0b3IuICBUaGUgb3JpZ2luYWwgZ2VuZXJhdG9yIG1heSBwcm92aWRlCisgICAgLy8gaW5zZXJ0aW9uIHBvaW50cyBieSBwbGFjaW5nIHNwZWNpYWwgYW5ub3RhdGlvbnMgaW4gdGhlIGZpbGUgdGhhdCBsb29rCisgICAgLy8gbGlrZToKKyAgICAvLyAgIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChOQU1FKQorICAgIC8vIFRoZSBhbm5vdGF0aW9uIGNhbiBoYXZlIGFyYml0cmFyeSB0ZXh0IGJlZm9yZSBhbmQgYWZ0ZXIgaXQgb24gdGhlIGxpbmUsCisgICAgLy8gd2hpY2ggYWxsb3dzIGl0IHRvIGJlIHBsYWNlZCBpbiBhIGNvbW1lbnQuICBOQU1FIHNob3VsZCBiZSByZXBsYWNlZCB3aXRoCisgICAgLy8gYW4gaWRlbnRpZmllciBuYW1pbmcgdGhlIHBvaW50IC0tIHRoaXMgaXMgd2hhdCBvdGhlciBnZW5lcmF0b3JzIHdpbGwgdXNlCisgICAgLy8gYXMgdGhlIGluc2VydGlvbl9wb2ludC4gIENvZGUgaW5zZXJ0ZWQgYXQgdGhpcyBwb2ludCB3aWxsIGJlIHBsYWNlZAorICAgIC8vIGltbWVkaWF0ZWx5IGFib3ZlIHRoZSBsaW5lIGNvbnRhaW5pbmcgdGhlIGluc2VydGlvbiBwb2ludCAodGh1cyBtdWx0aXBsZQorICAgIC8vIGluc2VydGlvbnMgdG8gdGhlIHNhbWUgcG9pbnQgd2lsbCBjb21lIG91dCBpbiB0aGUgb3JkZXIgdGhleSB3ZXJlIGFkZGVkKS4KKyAgICAvLyBUaGUgZG91YmxlLUAgaXMgaW50ZW5kZWQgdG8gbWFrZSBpdCB1bmxpa2VseSB0aGF0IHRoZSBnZW5lcmF0ZWQgY29kZQorICAgIC8vIGNvdWxkIGNvbnRhaW4gdGhpbmdzIHRoYXQgbG9vayBsaWtlIGluc2VydGlvbiBwb2ludHMgYnkgYWNjaWRlbnQuCisgICAgLy8KKyAgICAvLyBGb3IgZXhhbXBsZSwgdGhlIEMrKyBjb2RlIGdlbmVyYXRvciBwbGFjZXMgdGhlIGZvbGxvd2luZyBsaW5lIGluIHRoZQorICAgIC8vIC5wYi5oIGZpbGVzIHRoYXQgaXQgZ2VuZXJhdGVzOgorICAgIC8vICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG5hbWVzcGFjZV9zY29wZSkKKyAgICAvLyBUaGlzIGxpbmUgYXBwZWFycyB3aXRoaW4gdGhlIHNjb3BlIG9mIHRoZSBmaWxlJ3MgcGFja2FnZSBuYW1lc3BhY2UsIGJ1dAorICAgIC8vIG91dHNpZGUgb2YgYW55IHBhcnRpY3VsYXIgY2xhc3MuICBBbm90aGVyIHBsdWdpbiBjYW4gdGhlbiBzcGVjaWZ5IHRoZQorICAgIC8vIGluc2VydGlvbl9wb2ludCAibmFtZXNwYWNlX3Njb3BlIiB0byBnZW5lcmF0ZSBhZGRpdGlvbmFsIGNsYXNzZXMgb3IKKyAgICAvLyBvdGhlciBkZWNsYXJhdGlvbnMgdGhhdCBzaG91bGQgYmUgcGxhY2VkIGluIHRoaXMgc2NvcGUuCisgICAgLy8KKyAgICAvLyBOb3RlIHRoYXQgaWYgdGhlIGxpbmUgY29udGFpbmluZyB0aGUgaW5zZXJ0aW9uIHBvaW50IGJlZ2lucyB3aXRoCisgICAgLy8gd2hpdGVzcGFjZSwgdGhlIHNhbWUgd2hpdGVzcGFjZSB3aWxsIGJlIGFkZGVkIHRvIGV2ZXJ5IGxpbmUgb2YgdGhlCisgICAgLy8gaW5zZXJ0ZWQgdGV4dC4gIFRoaXMgaXMgdXNlZnVsIGZvciBsYW5ndWFnZXMgbGlrZSBQeXRob24sIHdoZXJlCisgICAgLy8gaW5kZW50YXRpb24gbWF0dGVycy4gIEluIHRoZXNlIGxhbmd1YWdlcywgdGhlIGluc2VydGlvbiBwb2ludCBjb21tZW50CisgICAgLy8gc2hvdWxkIGJlIGluZGVudGVkIHRoZSBzYW1lIGFtb3VudCBhcyBhbnkgaW5zZXJ0ZWQgY29kZSB3aWxsIG5lZWQgdG8gYmUKKyAgICAvLyBpbiBvcmRlciB0byB3b3JrIGNvcnJlY3RseSBpbiB0aGF0IGNvbnRleHQuCisgICAgLy8KKyAgICAvLyBUaGUgY29kZSBnZW5lcmF0b3IgdGhhdCBnZW5lcmF0ZXMgdGhlIGluaXRpYWwgZmlsZSBhbmQgdGhlIG9uZSB3aGljaAorICAgIC8vIGluc2VydHMgaW50byBpdCBtdXN0IGJvdGggcnVuIGFzIHBhcnQgb2YgYSBzaW5nbGUgaW52b2NhdGlvbiBvZiBwcm90b2MuCisgICAgLy8gQ29kZSBnZW5lcmF0b3JzIGFyZSBleGVjdXRlZCBpbiB0aGUgb3JkZXIgaW4gd2hpY2ggdGhleSBhcHBlYXIgb24gdGhlCisgICAgLy8gY29tbWFuZCBsaW5lLgorICAgIC8vCisgICAgLy8gSWYgfGluc2VydGlvbl9wb2ludHwgaXMgcHJlc2VudCwgfG5hbWV8IG11c3QgYWxzbyBiZSBwcmVzZW50LgorICAgIG9wdGlvbmFsIHN0cmluZyBpbnNlcnRpb25fcG9pbnQgPSAyOworCisgICAgLy8gVGhlIGZpbGUgY29udGVudHMuCisgICAgb3B0aW9uYWwgc3RyaW5nIGNvbnRlbnQgPSAxNTsKKyAgfQorICByZXBlYXRlZCBGaWxlIGZpbGUgPSAxNTsKK30KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcHl0aG9uL3B5dGhvbl9nZW5lcmF0b3IuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3B5dGhvbi9weXRob25fZ2VuZXJhdG9yLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRkNTAwZjkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3B5dGhvbi9weXRob25fZ2VuZXJhdG9yLmNjCkBAIC0wLDAgKzEsMTMzMSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vI1BZMjUgY29tcGF0aWJsZSBnZW5lcmF0ZWQgY29kZSBmb3IgR0FFLgorLy8gQ29weXJpZ2h0IDIwMDcgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKy8vIEF1dGhvcjogcm9iaW5zb25AZ29vZ2xlLmNvbSAoV2lsbCBSb2JpbnNvbikKKy8vCisvLyBUaGlzIG1vZHVsZSBvdXRwdXRzIHB1cmUtUHl0aG9uIHByb3RvY29sIG1lc3NhZ2UgY2xhc3NlcyB0aGF0IHdpbGwKKy8vIGxhcmdlbHkgYmUgY29uc3RydWN0ZWQgYXQgcnVudGltZSB2aWEgdGhlIG1ldGFjbGFzcyBpbiByZWZsZWN0aW9uLnB5LgorLy8gSW4gb3RoZXIgd29yZHMsIG91ciBqb2IgaXMgYmFzaWNhbGx5IHRvIG91dHB1dCBhIFB5dGhvbiBlcXVpdmFsZW50CisvLyBvZiB0aGUgQysrICpEZXNjcmlwdG9yIG9iamVjdHMsIGFuZCBmaXggdXAgYWxsIGNpcmN1bGFyIHJlZmVyZW5jZXMKKy8vIHdpdGhpbiB0aGVzZSBvYmplY3RzLgorLy8KKy8vIE5vdGUgdGhhdCB0aGUgcnVudGltZSBwZXJmb3JtYW5jZSBvZiBwcm90b2NvbCBtZXNzYWdlIGNsYXNzZXMgY3JlYXRlZCBpbgorLy8gdGhpcyB3YXkgaXMgZXhwZWN0ZWQgdG8gYmUgbG91c3kuICBUaGUgcGxhbiBpcyB0byBjcmVhdGUgYW4gYWx0ZXJuYXRlCisvLyBnZW5lcmF0b3IgdGhhdCBvdXRwdXRzIGEgUHl0aG9uL0MgZXh0ZW5zaW9uIG1vZHVsZSB0aGF0IGxldHMKKy8vIHBlcmZvcm1hbmNlLW1pbmRlZCBQeXRob24gY29kZSBsZXZlcmFnZSB0aGUgZmFzdCBDKysgaW1wbGVtZW50YXRpb24KKy8vIGRpcmVjdGx5LgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2hhc2guaD4KKyNpbmNsdWRlIDxsaW1pdHM+CisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPG1lbW9yeT4KKyNpZm5kZWYgX1NIQVJFRF9QVFJfSAorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaGFyZWRfcHRyLmg+CisjZW5kaWYKKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8dXRpbGl0eT4KKyNpbmNsdWRlIDx2ZWN0b3I+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcHl0aG9uL3B5dGhvbl9nZW5lcmF0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2xvZ2dpbmcuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cmluZ3ByaW50Zi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N1YnN0aXR1dGUuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBweXRob24geworCituYW1lc3BhY2UgeworCisvLyBSZXR1cm5zIGEgY29weSBvZiB8ZmlsZW5hbWV8IHdpdGggYW55IHRyYWlsaW5nICIucHJvdG9kZXZlbCIgb3IgIi5wcm90bworLy8gc3VmZml4IHN0cmlwcGVkLgorLy8gVE9ETyhyb2JpbnNvbik6IFVuaWZ5IHdpdGggY29weSBpbiBjb21waWxlci9jcHAvaW50ZXJuYWwvaGVscGVycy5jYy4KK3N0cmluZyBTdHJpcFByb3RvKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUpIHsKKyAgY29uc3QgY2hhciogc3VmZml4ID0gSGFzU3VmZml4U3RyaW5nKGZpbGVuYW1lLCAiLnByb3RvZGV2ZWwiKQorICAgICAgPyAiLnByb3RvZGV2ZWwiIDogIi5wcm90byI7CisgIHJldHVybiBTdHJpcFN1ZmZpeFN0cmluZyhmaWxlbmFtZSwgc3VmZml4KTsKK30KKworCisvLyBSZXR1cm5zIHRoZSBQeXRob24gbW9kdWxlIG5hbWUgZXhwZWN0ZWQgZm9yIGEgZ2l2ZW4gLnByb3RvIGZpbGVuYW1lLgorc3RyaW5nIE1vZHVsZU5hbWUoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSkgeworICBzdHJpbmcgYmFzZW5hbWUgPSBTdHJpcFByb3RvKGZpbGVuYW1lKTsKKyAgU3RyaXBTdHJpbmcoJmJhc2VuYW1lLCAiLSIsICdfJyk7CisgIFN0cmlwU3RyaW5nKCZiYXNlbmFtZSwgIi8iLCAnLicpOworICByZXR1cm4gYmFzZW5hbWUgKyAiX3BiMiI7Cit9CisKKworLy8gUmV0dXJucyB0aGUgYWxpYXMgd2UgYXNzaWduIHRvIHRoZSBtb2R1bGUgb2YgdGhlIGdpdmVuIC5wcm90byBmaWxlbmFtZQorLy8gd2hlbiBpbXBvcnRpbmcuIFNlZSB0ZXN0UGFja2FnZUluaXRpYWxpemF0aW9uSW1wb3J0IGluCisvLyBnb29nbGUvcHJvdG9idWYvcHl0aG9uL3JlZmxlY3Rpb25fdGVzdC5weQorLy8gdG8gc2VlIHdoeSB3ZSBuZWVkIHRoZSBhbGlhcy4KK3N0cmluZyBNb2R1bGVBbGlhcyhjb25zdCBzdHJpbmcmIGZpbGVuYW1lKSB7CisgIHN0cmluZyBtb2R1bGVfbmFtZSA9IE1vZHVsZU5hbWUoZmlsZW5hbWUpOworICAvLyBXZSBjYW4ndCBoYXZlIGRvdHMgaW4gdGhlIG1vZHVsZSBuYW1lLCBzbyB3ZSByZXBsYWNlIGVhY2ggd2l0aCBfZG90Xy4KKyAgLy8gQnV0IHRoYXQgY291bGQgbGVhZCB0byBhIGNvbGxpc2lvbiBiZXR3ZWVuIGEuYiBhbmQgYV9kb3RfYiwgc28gd2UgYWxzbworICAvLyBkdXBsaWNhdGUgZWFjaCB1bmRlcnNjb3JlLgorICBHbG9iYWxSZXBsYWNlU3Vic3RyaW5nKCJfIiwgIl9fIiwgJm1vZHVsZV9uYW1lKTsKKyAgR2xvYmFsUmVwbGFjZVN1YnN0cmluZygiLiIsICJfZG90XyIsICZtb2R1bGVfbmFtZSk7CisgIHJldHVybiBtb2R1bGVfbmFtZTsKK30KKworCisvLyBSZXR1cm5zIGFuIGltcG9ydCBzdGF0ZW1lbnQgb2YgZm9ybSAiZnJvbSBYLlkuWiBpbXBvcnQgVCIgZm9yIHRoZSBnaXZlbgorLy8gLnByb3RvIGZpbGVuYW1lLgorc3RyaW5nIE1vZHVsZUltcG9ydFN0YXRlbWVudChjb25zdCBzdHJpbmcmIGZpbGVuYW1lKSB7CisgIHN0cmluZyBtb2R1bGVfbmFtZSA9IE1vZHVsZU5hbWUoZmlsZW5hbWUpOworICBpbnQgbGFzdF9kb3RfcG9zID0gbW9kdWxlX25hbWUucmZpbmQoJy4nKTsKKyAgaWYgKGxhc3RfZG90X3BvcyA9PSBzdHJpbmc6Om5wb3MpIHsKKyAgICAvLyBOT1RFKHBldHlhKTogdGhpcyBpcyBub3QgdGVzdGVkIGFzIGl0IHdvdWxkIHJlcXVpcmUgYSBwcm90b2NvbCBidWZmZXIKKyAgICAvLyBvdXRzaWRlIG9mIGFueSBwYWNrYWdlLCBhbmQgSSBkb24ndCB0aGluayB0aGF0IGlzIGVhc2lseSBhY2hpZXZhYmxlLgorICAgIHJldHVybiAiaW1wb3J0ICIgKyBtb2R1bGVfbmFtZTsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gImZyb20gIiArIG1vZHVsZV9uYW1lLnN1YnN0cigwLCBsYXN0X2RvdF9wb3MpICsgIiBpbXBvcnQgIiArCisgICAgICAgIG1vZHVsZV9uYW1lLnN1YnN0cihsYXN0X2RvdF9wb3MgKyAxKTsKKyAgfQorfQorCisKKy8vIFJldHVybnMgdGhlIG5hbWUgb2YgYWxsIGNvbnRhaW5pbmcgdHlwZXMgZm9yIGRlc2NyaXB0b3IsCisvLyBpbiBvcmRlciBmcm9tIG91dGVybW9zdCB0byBpbm5lcm1vc3QsIGZvbGxvd2VkIGJ5IGRlc2NyaXB0b3IncworLy8gb3duIG5hbWUuICBFYWNoIG5hbWUgaXMgc2VwYXJhdGVkIGJ5IHxzZXBhcmF0b3J8LgordGVtcGxhdGUgPHR5cGVuYW1lIERlc2NyaXB0b3JUPgorc3RyaW5nIE5hbWVQcmVmaXhlZFdpdGhOZXN0ZWRUeXBlcyhjb25zdCBEZXNjcmlwdG9yVCYgZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBzZXBhcmF0b3IpIHsKKyAgc3RyaW5nIG5hbWUgPSBkZXNjcmlwdG9yLm5hbWUoKTsKKyAgZm9yIChjb25zdCBEZXNjcmlwdG9yKiBjdXJyZW50ID0gZGVzY3JpcHRvci5jb250YWluaW5nX3R5cGUoKTsKKyAgICAgICBjdXJyZW50ICE9IE5VTEw7IGN1cnJlbnQgPSBjdXJyZW50LT5jb250YWluaW5nX3R5cGUoKSkgeworICAgIG5hbWUgPSBjdXJyZW50LT5uYW1lKCkgKyBzZXBhcmF0b3IgKyBuYW1lOworICB9CisgIHJldHVybiBuYW1lOworfQorCisKKy8vIE5hbWUgb2YgdGhlIGNsYXNzIGF0dHJpYnV0ZSB3aGVyZSB3ZSBzdG9yZSB0aGUgUHl0aG9uCisvLyBkZXNjcmlwdG9yLkRlc2NyaXB0b3IgaW5zdGFuY2UgZm9yIHRoZSBnZW5lcmF0ZWQgY2xhc3MuCisvLyBNdXN0IHN0YXkgY29uc2lzdGVudCB3aXRoIHRoZSBfREVTQ1JJUFRPUl9LRVkgY29uc3RhbnQKKy8vIGluIHByb3RvMi9wdWJsaWMvcmVmbGVjdGlvbi5weS4KK2NvbnN0IGNoYXIga0Rlc2NyaXB0b3JLZXlbXSA9ICJERVNDUklQVE9SIjsKKworCisvLyBEb2VzIHRoZSBmaWxlIGhhdmUgdG9wLWxldmVsIGVudW1zPworaW5saW5lIGJvb2wgSGFzVG9wTGV2ZWxFbnVtcyhjb25zdCBGaWxlRGVzY3JpcHRvciAqZmlsZSkgeworICByZXR1cm4gZmlsZS0+ZW51bV90eXBlX2NvdW50KCkgPiAwOworfQorCisKKy8vIFNob3VsZCB3ZSBnZW5lcmF0ZSBnZW5lcmljIHNlcnZpY2VzIGZvciB0aGlzIGZpbGU/CitpbmxpbmUgYm9vbCBIYXNHZW5lcmljU2VydmljZXMoY29uc3QgRmlsZURlc2NyaXB0b3IgKmZpbGUpIHsKKyAgcmV0dXJuIGZpbGUtPnNlcnZpY2VfY291bnQoKSA+IDAgJiYKKyAgICAgICAgIGZpbGUtPm9wdGlvbnMoKS5weV9nZW5lcmljX3NlcnZpY2VzKCk7Cit9CisKKworLy8gUHJpbnRzIHRoZSBjb21tb24gYm9pbGVycGxhdGUgbmVlZGVkIGF0IHRoZSB0b3Agb2YgZXZlcnkgLnB5CisvLyBmaWxlIG91dHB1dCBieSB0aGlzIGdlbmVyYXRvci4KK3ZvaWQgUHJpbnRUb3BCb2lsZXJwbGF0ZSgKKyAgICBpbzo6UHJpbnRlciogcHJpbnRlciwgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUsIGJvb2wgZGVzY3JpcHRvcl9wcm90bykgeworICAvLyBUT0RPKHJvYmluc29uKTogQWxsb3cgcGFyYW1ldGVyaXphdGlvbiBvZiBQeXRob24gdmVyc2lvbj8KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiIyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIVxuIgorICAgICAgIiMgc291cmNlOiAkZmlsZW5hbWUkXG4iCisgICAgICAiXG5pbXBvcnQgc3lzXG5fYj1zeXMudmVyc2lvbl9pbmZvWzBdPDMgYW5kIChsYW1iZGEgeDp4KSBvciAobGFtYmRhIHg6eC5lbmNvZGUoJ2xhdGluMScpKSIgIC8vIyNQWTI1CisgICAgICAiXG4iLAorICAgICAgImZpbGVuYW1lIiwgZmlsZS0+bmFtZSgpKTsKKyAgaWYgKEhhc1RvcExldmVsRW51bXMoZmlsZSkpIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgImZyb20gZ29vZ2xlLnByb3RvYnVmLmludGVybmFsIGltcG9ydCBlbnVtX3R5cGVfd3JhcHBlclxuIik7CisgIH0KKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IGRlc2NyaXB0b3IgYXMgX2Rlc2NyaXB0b3JcbiIKKyAgICAgICJmcm9tIGdvb2dsZS5wcm90b2J1ZiBpbXBvcnQgbWVzc2FnZSBhcyBfbWVzc2FnZVxuIgorICAgICAgImZyb20gZ29vZ2xlLnByb3RvYnVmIGltcG9ydCByZWZsZWN0aW9uIGFzIF9yZWZsZWN0aW9uXG4iCisgICAgICAiZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IHN5bWJvbF9kYXRhYmFzZSBhcyAiCisgICAgICAiX3N5bWJvbF9kYXRhYmFzZVxuIik7CisgIGlmIChIYXNHZW5lcmljU2VydmljZXMoZmlsZSkpIHsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgImZyb20gZ29vZ2xlLnByb3RvYnVmIGltcG9ydCBzZXJ2aWNlIGFzIF9zZXJ2aWNlXG4iCisgICAgICAgICJmcm9tIGdvb2dsZS5wcm90b2J1ZiBpbXBvcnQgc2VydmljZV9yZWZsZWN0aW9uXG4iKTsKKyAgfQorCisgIC8vIEF2b2lkIGNpcmN1bGFyIGltcG9ydHMgaWYgdGhpcyBtb2R1bGUgaXMgZGVzY3JpcHRvcl9wYjIuCisgIGlmICghZGVzY3JpcHRvcl9wcm90bykgeworICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiZnJvbSBnb29nbGUucHJvdG9idWYgaW1wb3J0IGRlc2NyaXB0b3JfcGIyXG4iKTsKKyAgfQorICBwcmludGVyLT5QcmludCgKKyAgICAgICIjIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbXBvcnRzKVxuXG4iCisgICAgICAiX3N5bV9kYiA9IF9zeW1ib2xfZGF0YWJhc2UuRGVmYXVsdCgpXG4iKTsKKyAgcHJpbnRlci0+UHJpbnQoIlxuXG4iKTsKK30KKworCisvLyBSZXR1cm5zIGEgUHl0aG9uIGxpdGVyYWwgZ2l2aW5nIHRoZSBkZWZhdWx0IHZhbHVlIGZvciBhIGZpZWxkLgorLy8gSWYgdGhlIGZpZWxkIHNwZWNpZmllcyBubyBleHBsaWNpdCBkZWZhdWx0IHZhbHVlLCB3ZSdsbCByZXR1cm4KKy8vIHRoZSBkZWZhdWx0IGRlZmF1bHQgdmFsdWUgZm9yIHRoZSBmaWVsZCB0eXBlICh6ZXJvIGZvciBudW1iZXJzLAorLy8gZW1wdHkgc3RyaW5nIGZvciBzdHJpbmdzLCBlbXB0eSBsaXN0IGZvciByZXBlYXRlZCBmaWVsZHMsIGFuZAorLy8gTm9uZSBmb3Igbm9uLXJlcGVhdGVkLCBjb21wb3NpdGUgZmllbGRzKS4KKy8vCisvLyBUT0RPKHJvYmluc29uKTogVW5pZnkgd2l0aCBjb2RlIGZyb20KKy8vIC8vY29tcGlsZXIvY3BwL2ludGVybmFsL3ByaW1pdGl2ZV9maWVsZC5jYworLy8gLy9jb21waWxlci9jcHAvaW50ZXJuYWwvZW51bV9maWVsZC5jYworLy8gLy9jb21waWxlci9jcHAvaW50ZXJuYWwvc3RyaW5nX2ZpZWxkLmNjCitzdHJpbmcgU3RyaW5naWZ5RGVmYXVsdFZhbHVlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciYgZmllbGQpIHsKKyAgaWYgKGZpZWxkLmlzX3JlcGVhdGVkKCkpIHsKKyAgICByZXR1cm4gIltdIjsKKyAgfQorCisgIHN3aXRjaCAoZmllbGQuY3BwX3R5cGUoKSkgeworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0lOVDMyOgorICAgICAgcmV0dXJuIFNpbXBsZUl0b2EoZmllbGQuZGVmYXVsdF92YWx1ZV9pbnQzMigpKTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9VSU5UMzI6CisgICAgICByZXR1cm4gU2ltcGxlSXRvYShmaWVsZC5kZWZhdWx0X3ZhbHVlX3VpbnQzMigpKTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9JTlQ2NDoKKyAgICAgIHJldHVybiBTaW1wbGVJdG9hKGZpZWxkLmRlZmF1bHRfdmFsdWVfaW50NjQoKSk7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDY0OgorICAgICAgcmV0dXJuIFNpbXBsZUl0b2EoZmllbGQuZGVmYXVsdF92YWx1ZV91aW50NjQoKSk7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRE9VQkxFOiB7CisgICAgICBkb3VibGUgdmFsdWUgPSBmaWVsZC5kZWZhdWx0X3ZhbHVlX2RvdWJsZSgpOworICAgICAgaWYgKHZhbHVlID09IG51bWVyaWNfbGltaXRzPGRvdWJsZT46OmluZmluaXR5KCkpIHsKKyAgICAgICAgLy8gUHl0aG9uIHByZS0yLjYgb24gV2luZG93cyBkb2VzIG5vdCBwYXJzZSAiaW5mIiBjb3JyZWN0bHkuICBIb3dldmVyLAorICAgICAgICAvLyBhIG51bWVyaWMgbGl0ZXJhbCB0aGF0IGlzIHRvbyBiaWcgZm9yIGEgZG91YmxlIHdpbGwgYmVjb21lIGluZmluaXR5LgorICAgICAgICByZXR1cm4gIjFlMTAwMDAiOworICAgICAgfSBlbHNlIGlmICh2YWx1ZSA9PSAtbnVtZXJpY19saW1pdHM8ZG91YmxlPjo6aW5maW5pdHkoKSkgeworICAgICAgICAvLyBTZWUgYWJvdmUuCisgICAgICAgIHJldHVybiAiLTFlMTAwMDAiOworICAgICAgfSBlbHNlIGlmICh2YWx1ZSAhPSB2YWx1ZSkgeworICAgICAgICAvLyBpbmZpbml0eSAqIDAgPSBuYW4KKyAgICAgICAgcmV0dXJuICIoMWUxMDAwMCAqIDApIjsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiBTaW1wbGVEdG9hKHZhbHVlKTsKKyAgICAgIH0KKyAgICB9CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRkxPQVQ6IHsKKyAgICAgIGZsb2F0IHZhbHVlID0gZmllbGQuZGVmYXVsdF92YWx1ZV9mbG9hdCgpOworICAgICAgaWYgKHZhbHVlID09IG51bWVyaWNfbGltaXRzPGZsb2F0Pjo6aW5maW5pdHkoKSkgeworICAgICAgICAvLyBQeXRob24gcHJlLTIuNiBvbiBXaW5kb3dzIGRvZXMgbm90IHBhcnNlICJpbmYiIGNvcnJlY3RseS4gIEhvd2V2ZXIsCisgICAgICAgIC8vIGEgbnVtZXJpYyBsaXRlcmFsIHRoYXQgaXMgdG9vIGJpZyBmb3IgYSBkb3VibGUgd2lsbCBiZWNvbWUgaW5maW5pdHkuCisgICAgICAgIHJldHVybiAiMWUxMDAwMCI7CisgICAgICB9IGVsc2UgaWYgKHZhbHVlID09IC1udW1lcmljX2xpbWl0czxmbG9hdD46OmluZmluaXR5KCkpIHsKKyAgICAgICAgLy8gU2VlIGFib3ZlLgorICAgICAgICByZXR1cm4gIi0xZTEwMDAwIjsKKyAgICAgIH0gZWxzZSBpZiAodmFsdWUgIT0gdmFsdWUpIHsKKyAgICAgICAgLy8gaW5maW5pdHkgLSBpbmZpbml0eSA9IG5hbgorICAgICAgICByZXR1cm4gIigxZTEwMDAwICogMCkiOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcmV0dXJuIFNpbXBsZUZ0b2EodmFsdWUpOworICAgICAgfQorICAgIH0KKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9CT09MOgorICAgICAgcmV0dXJuIGZpZWxkLmRlZmF1bHRfdmFsdWVfYm9vbCgpID8gIlRydWUiIDogIkZhbHNlIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9FTlVNOgorICAgICAgcmV0dXJuIFNpbXBsZUl0b2EoZmllbGQuZGVmYXVsdF92YWx1ZV9lbnVtKCktPm51bWJlcigpKTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9TVFJJTkc6CisvLyMjIVBZMjUgICAgICByZXR1cm4gImJcIiIgKyBDRXNjYXBlKGZpZWxkLmRlZmF1bHRfdmFsdWVfc3RyaW5nKCkpICsKKy8vIyMhUFkyNSAgICAgICAgICAgICAoZmllbGQudHlwZSgpICE9IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TVFJJTkcgPyAiXCIiIDoKKy8vIyMhUFkyNSAgICAgICAgICAgICAgICJcIi5kZWNvZGUoJ3V0Zi04JykiKTsKKyAgICAgIHJldHVybiAiX2IoXCIiICsgQ0VzY2FwZShmaWVsZC5kZWZhdWx0X3ZhbHVlX3N0cmluZygpKSArICAvLyMjUFkyNQorICAgICAgICAgICAgIChmaWVsZC50eXBlKCkgIT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX1NUUklORyA/ICJcIikiIDogIC8vIyNQWTI1CisgICAgICAgICAgICAgICAiXCIpLmRlY29kZSgndXRmLTgnKSIpOyAgLy8jI1BZMjUKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgcmV0dXJuICJOb25lIjsKKyAgfQorICAvLyAoV2UgY291bGQgYWRkIGEgZGVmYXVsdCBjYXNlIGFib3ZlIGJ1dCB0aGVuIHdlIHdvdWxkbid0IGdldCB0aGUgbmljZQorICAvLyBjb21waWxlciB3YXJuaW5nIHdoZW4gYSBuZXcgdHlwZSBpcyBhZGRlZC4pCisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJOb3QgcmVhY2hlZC4iOworICByZXR1cm4gIiI7Cit9CisKK3N0cmluZyBTdHJpbmdpZnlTeW50YXgoRmlsZURlc2NyaXB0b3I6OlN5bnRheCBzeW50YXgpIHsKKyAgc3dpdGNoIChzeW50YXgpIHsKKyAgICBjYXNlIEZpbGVEZXNjcmlwdG9yOjpTWU5UQVhfUFJPVE8yOgorICAgICAgcmV0dXJuICJwcm90bzIiOworICAgIGNhc2UgRmlsZURlc2NyaXB0b3I6OlNZTlRBWF9QUk9UTzM6CisgICAgICByZXR1cm4gInByb3RvMyI7CisgICAgY2FzZSBGaWxlRGVzY3JpcHRvcjo6U1lOVEFYX1VOS05PV046CisgICAgZGVmYXVsdDoKKyAgICAgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJVbnN1cHBvcnRlZCBzeW50YXg7IHRoaXMgZ2VuZXJhdG9yIG9ubHkgc3VwcG9ydHMgcHJvdG8yICIKKyAgICAgICAgICAgICAgICAgICAgImFuZCBwcm90bzMgc3ludGF4LiI7CisgICAgICByZXR1cm4gIiI7CisgIH0KK30KKworCit9ICAvLyBuYW1lc3BhY2UKKworCitHZW5lcmF0b3I6OkdlbmVyYXRvcigpIDogZmlsZV8oTlVMTCkgeworfQorCitHZW5lcmF0b3I6On5HZW5lcmF0b3IoKSB7Cit9CisKK2Jvb2wgR2VuZXJhdG9yOjpHZW5lcmF0ZShjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHBhcmFtZXRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICBHZW5lcmF0b3JDb250ZXh0KiBjb250ZXh0LAorICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyogZXJyb3IpIGNvbnN0IHsKKworICAvLyBDb21wbGV0ZWx5IHNlcmlhbGl6ZSBhbGwgR2VuZXJhdGUoKSBjYWxscyBvbiB0aGlzIGluc3RhbmNlLiAgVGhlCisgIC8vIHRocmVhZC1zYWZldHkgY29uc3RyYWludHMgb2YgdGhlIENvZGVHZW5lcmF0b3IgaW50ZXJmYWNlIGFyZW4ndCBjbGVhciBzbworICAvLyBqdXN0IGJlIGFzIGNvbnNlcnZhdGl2ZSBhcyBwb3NzaWJsZS4gIEl0J3MgZWFzaWVyIHRvIHJlbGF4IHRoaXMgbGF0ZXIgaWYKKyAgLy8gd2UgbmVlZCB0bywgYnV0IEkgZG91YnQgaXQgd2lsbCBiZSBhbiBpc3N1ZS4KKyAgLy8gVE9ETyhrZW50b24pOiAgVGhlIHByb3BlciB0aGluZyB0byBkbyB3b3VsZCBiZSB0byBhbGxvY2F0ZSBhbnkgc3RhdGUgb24KKyAgLy8gICB0aGUgc3RhY2sgYW5kIHVzZSB0aGF0LCBzbyB0aGF0IHRoZSBHZW5lcmF0b3IgY2xhc3MgaXRzZWxmIGRvZXMgbm90IG5lZWQKKyAgLy8gICB0byBoYXZlIGFueSBtdXRhYmxlIG1lbWJlcnMuICBUaGVuIGl0IGlzIGltcGxpY2l0bHkgdGhyZWFkLXNhZmUuCisgIE11dGV4TG9jayBsb2NrKCZtdXRleF8pOworICBmaWxlXyA9IGZpbGU7CisgIHN0cmluZyBtb2R1bGVfbmFtZSA9IE1vZHVsZU5hbWUoZmlsZS0+bmFtZSgpKTsKKyAgc3RyaW5nIGZpbGVuYW1lID0gbW9kdWxlX25hbWU7CisgIFN0cmlwU3RyaW5nKCZmaWxlbmFtZSwgIi4iLCAnLycpOworICBmaWxlbmFtZSArPSAiLnB5IjsKKworICBGaWxlRGVzY3JpcHRvclByb3RvIGZkcDsKKyAgZmlsZV8tPkNvcHlUbygmZmRwKTsKKyAgZmRwLlNlcmlhbGl6ZVRvU3RyaW5nKCZmaWxlX2Rlc2NyaXB0b3Jfc2VyaWFsaXplZF8pOworCisKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0+IG91dHB1dChjb250ZXh0LT5PcGVuKGZpbGVuYW1lKSk7CisgIEdPT0dMRV9DSEVDSyhvdXRwdXQuZ2V0KCkpOworICBpbzo6UHJpbnRlciBwcmludGVyKG91dHB1dC5nZXQoKSwgJyQnKTsKKyAgcHJpbnRlcl8gPSAmcHJpbnRlcjsKKworICBQcmludFRvcEJvaWxlcnBsYXRlKHByaW50ZXJfLCBmaWxlXywgR2VuZXJhdGluZ0Rlc2NyaXB0b3JQcm90bygpKTsKKyAgUHJpbnRJbXBvcnRzKCk7CisgIFByaW50RmlsZURlc2NyaXB0b3IoKTsKKyAgUHJpbnRUb3BMZXZlbEVudW1zKCk7CisgIFByaW50VG9wTGV2ZWxFeHRlbnNpb25zKCk7CisgIFByaW50QWxsTmVzdGVkRW51bXNJbkZpbGUoKTsKKyAgUHJpbnRNZXNzYWdlRGVzY3JpcHRvcnMoKTsKKyAgRml4Rm9yZWlnbkZpZWxkc0luRGVzY3JpcHRvcnMoKTsKKyAgUHJpbnRNZXNzYWdlcygpOworICAvLyBXZSBoYXZlIHRvIGZpeCB1cCB0aGUgZXh0ZW5zaW9ucyBhZnRlciB0aGUgbWVzc2FnZSBjbGFzc2VzIHRoZW1zZWx2ZXMsCisgIC8vIHNpbmNlIHRoZXkgbmVlZCB0byBjYWxsIHN0YXRpYyBSZWdpc3RlckV4dGVuc2lvbigpIG1ldGhvZHMgb24gdGhlc2UKKyAgLy8gY2xhc3Nlcy4KKyAgRml4Rm9yZWlnbkZpZWxkc0luRXh0ZW5zaW9ucygpOworICAvLyBEZXNjcmlwdG9yIG9wdGlvbnMgbWF5IGhhdmUgY3VzdG9tIGV4dGVuc2lvbnMuIFRoZXNlIGN1c3RvbSBvcHRpb25zCisgIC8vIGNhbiBvbmx5IGJlIHN1Y2Nlc3NmdWxseSBwYXJzZWQgYWZ0ZXIgd2UgcmVnaXN0ZXIgY29ycmVzcG9uZGluZworICAvLyBleHRlbnNpb25zLiBUaGVyZWZvcmUgd2UgcGFyc2UgYWxsIG9wdGlvbnMgYWdhaW4gaGVyZSB0byByZWNvZ25pemUKKyAgLy8gY3VzdG9tIG9wdGlvbnMgdGhhdCBtYXkgYmUgdW5rbm93biB3aGVuIHdlIGRlZmluZSB0aGUgZGVzY3JpcHRvcnMuCisgIEZpeEFsbERlc2NyaXB0b3JPcHRpb25zKCk7CisgIGlmIChIYXNHZW5lcmljU2VydmljZXMoZmlsZSkpIHsKKyAgICBQcmludFNlcnZpY2VzKCk7CisgIH0KKworICBwcmludGVyLlByaW50KAorICAgICIjIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtb2R1bGVfc2NvcGUpXG4iKTsKKworICByZXR1cm4gIXByaW50ZXIuZmFpbGVkKCk7Cit9CisKKy8vIFByaW50cyBQeXRob24gaW1wb3J0cyBmb3IgYWxsIG1vZHVsZXMgaW1wb3J0ZWQgYnkgfGZpbGV8Lgordm9pZCBHZW5lcmF0b3I6OlByaW50SW1wb3J0cygpIGNvbnN0IHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+ZGVwZW5kZW5jeV9jb3VudCgpOyArK2kpIHsKKyAgICBjb25zdCBzdHJpbmcmIGZpbGVuYW1lID0gZmlsZV8tPmRlcGVuZGVuY3koaSktPm5hbWUoKTsKKyAgICBzdHJpbmcgaW1wb3J0X3N0YXRlbWVudCA9IE1vZHVsZUltcG9ydFN0YXRlbWVudChmaWxlbmFtZSk7CisgICAgc3RyaW5nIG1vZHVsZV9hbGlhcyA9IE1vZHVsZUFsaWFzKGZpbGVuYW1lKTsKKyAgICBwcmludGVyXy0+UHJpbnQoIiRzdGF0ZW1lbnQkIGFzICRhbGlhcyRcbiIsICJzdGF0ZW1lbnQiLAorICAgICAgICAgICAgICAgICAgICBpbXBvcnRfc3RhdGVtZW50LCAiYWxpYXMiLCBtb2R1bGVfYWxpYXMpOworICAgIENvcHlQdWJsaWNEZXBlbmRlbmNpZXNBbGlhc2VzKG1vZHVsZV9hbGlhcywgZmlsZV8tPmRlcGVuZGVuY3koaSkpOworICB9CisgIHByaW50ZXJfLT5QcmludCgiXG4iKTsKKworICAvLyBQcmludCBwdWJsaWMgaW1wb3J0cy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+cHVibGljX2RlcGVuZGVuY3lfY291bnQoKTsgKytpKSB7CisgICAgc3RyaW5nIG1vZHVsZV9uYW1lID0gTW9kdWxlTmFtZShmaWxlXy0+cHVibGljX2RlcGVuZGVuY3koaSktPm5hbWUoKSk7CisgICAgcHJpbnRlcl8tPlByaW50KCJmcm9tICRtb2R1bGUkIGltcG9ydCAqXG4iLCAibW9kdWxlIiwgbW9kdWxlX25hbWUpOworICB9CisgIHByaW50ZXJfLT5QcmludCgiXG4iKTsKK30KKworLy8gUHJpbnRzIHRoZSBzaW5nbGUgZmlsZSBkZXNjcmlwdG9yIGZvciB0aGlzIGZpbGUuCit2b2lkIEdlbmVyYXRvcjo6UHJpbnRGaWxlRGVzY3JpcHRvcigpIGNvbnN0IHsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiBtOworICBtWyJkZXNjcmlwdG9yX25hbWUiXSA9IGtEZXNjcmlwdG9yS2V5OworICBtWyJuYW1lIl0gPSBmaWxlXy0+bmFtZSgpOworICBtWyJwYWNrYWdlIl0gPSBmaWxlXy0+cGFja2FnZSgpOworICBtWyJzeW50YXgiXSA9IFN0cmluZ2lmeVN5bnRheChmaWxlXy0+c3ludGF4KCkpOworICBjb25zdCBjaGFyIGZpbGVfZGVzY3JpcHRvcl90ZW1wbGF0ZVtdID0KKyAgICAgICIkZGVzY3JpcHRvcl9uYW1lJCA9IF9kZXNjcmlwdG9yLkZpbGVEZXNjcmlwdG9yKFxuIgorICAgICAgIiAgbmFtZT0nJG5hbWUkJyxcbiIKKyAgICAgICIgIHBhY2thZ2U9JyRwYWNrYWdlJCcsXG4iCisgICAgICAiICBzeW50YXg9JyRzeW50YXgkJyxcbiI7CisgIHByaW50ZXJfLT5QcmludChtLCBmaWxlX2Rlc2NyaXB0b3JfdGVtcGxhdGUpOworICBwcmludGVyXy0+SW5kZW50KCk7CisgIHByaW50ZXJfLT5QcmludCgKKy8vIyMhUFkyNSAgICAgICJzZXJpYWxpemVkX3BiPWInJHZhbHVlJCdcbiIsCisgICAgICAic2VyaWFsaXplZF9wYj1fYignJHZhbHVlJCcpXG4iLCAgLy8jI1BZMjUKKyAgICAgICJ2YWx1ZSIsIHN0cmluZ3M6OkNIZXhFc2NhcGUoZmlsZV9kZXNjcmlwdG9yX3NlcmlhbGl6ZWRfKSk7CisgIGlmIChmaWxlXy0+ZGVwZW5kZW5jeV9jb3VudCgpICE9IDApIHsKKyAgICBwcmludGVyXy0+UHJpbnQoIixcbmRlcGVuZGVuY2llcz1bIik7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+ZGVwZW5kZW5jeV9jb3VudCgpOyArK2kpIHsKKyAgICAgIHN0cmluZyBtb2R1bGVfYWxpYXMgPSBNb2R1bGVBbGlhcyhmaWxlXy0+ZGVwZW5kZW5jeShpKS0+bmFtZSgpKTsKKyAgICAgIHByaW50ZXJfLT5QcmludCgiJG1vZHVsZV9hbGlhcyQuREVTQ1JJUFRPUiwiLCAibW9kdWxlX2FsaWFzIiwKKyAgICAgICAgICAgICAgICAgICAgICBtb2R1bGVfYWxpYXMpOworICAgIH0KKyAgICBwcmludGVyXy0+UHJpbnQoIl0iKTsKKyAgfQorCisgIC8vIFRPRE8oZmFsayk6IEFsc28gcHJpbnQgb3B0aW9ucyBhbmQgZml4IHRoZSBtZXNzYWdlX3R5cGUsIGVudW1fdHlwZSwKKyAgLy8gICAgICAgICAgICAgc2VydmljZSBhbmQgZXh0ZW5zaW9uIGxhdGVyIGluIHRoZSBnZW5lcmF0aW9uLgorCisgIHByaW50ZXJfLT5PdXRkZW50KCk7CisgIHByaW50ZXJfLT5QcmludCgiKVxuIik7CisgIHByaW50ZXJfLT5QcmludCgiX3N5bV9kYi5SZWdpc3RlckZpbGVEZXNjcmlwdG9yKCRuYW1lJClcbiIsICJuYW1lIiwKKyAgICAgICAgICAgICAgICAgIGtEZXNjcmlwdG9yS2V5KTsKKyAgcHJpbnRlcl8tPlByaW50KCJcbiIpOworfQorCisvLyBQcmludHMgZGVzY3JpcHRvcnMgYW5kIG1vZHVsZS1sZXZlbCBjb25zdGFudHMgZm9yIGFsbCB0b3AtbGV2ZWwKKy8vIGVudW1zIGRlZmluZWQgaW4gfGZpbGV8Lgordm9pZCBHZW5lcmF0b3I6OlByaW50VG9wTGV2ZWxFbnVtcygpIGNvbnN0IHsKKyAgdmVjdG9yPHBhaXI8c3RyaW5nLCBpbnQ+ID4gdG9wX2xldmVsX2VudW1fdmFsdWVzOworICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5lbnVtX3R5cGVfY291bnQoKTsgKytpKSB7CisgICAgY29uc3QgRW51bURlc2NyaXB0b3ImIGVudW1fZGVzY3JpcHRvciA9ICpmaWxlXy0+ZW51bV90eXBlKGkpOworICAgIFByaW50RW51bShlbnVtX2Rlc2NyaXB0b3IpOworICAgIHByaW50ZXJfLT5QcmludCgiJG5hbWUkID0gIgorICAgICAgICAgICAgICAgICAgICAiZW51bV90eXBlX3dyYXBwZXIuRW51bVR5cGVXcmFwcGVyKCRkZXNjcmlwdG9yX25hbWUkKSIsCisgICAgICAgICAgICAgICAgICAgICJuYW1lIiwgZW51bV9kZXNjcmlwdG9yLm5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0b3JfbmFtZSIsCisgICAgICAgICAgICAgICAgICAgIE1vZHVsZUxldmVsRGVzY3JpcHRvck5hbWUoZW51bV9kZXNjcmlwdG9yKSk7CisgICAgcHJpbnRlcl8tPlByaW50KCJcbiIpOworCisgICAgZm9yIChpbnQgaiA9IDA7IGogPCBlbnVtX2Rlc2NyaXB0b3IudmFsdWVfY291bnQoKTsgKytqKSB7CisgICAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yJiB2YWx1ZV9kZXNjcmlwdG9yID0gKmVudW1fZGVzY3JpcHRvci52YWx1ZShqKTsKKyAgICAgIHRvcF9sZXZlbF9lbnVtX3ZhbHVlcy5wdXNoX2JhY2soCisgICAgICAgICAgc3RkOjptYWtlX3BhaXIodmFsdWVfZGVzY3JpcHRvci5uYW1lKCksIHZhbHVlX2Rlc2NyaXB0b3IubnVtYmVyKCkpKTsKKyAgICB9CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IHRvcF9sZXZlbF9lbnVtX3ZhbHVlcy5zaXplKCk7ICsraSkgeworICAgIHByaW50ZXJfLT5QcmludCgiJG5hbWUkID0gJHZhbHVlJFxuIiwKKyAgICAgICAgICAgICAgICAgICAgIm5hbWUiLCB0b3BfbGV2ZWxfZW51bV92YWx1ZXNbaV0uZmlyc3QsCisgICAgICAgICAgICAgICAgICAgICJ2YWx1ZSIsIFNpbXBsZUl0b2EodG9wX2xldmVsX2VudW1fdmFsdWVzW2ldLnNlY29uZCkpOworICB9CisgIHByaW50ZXJfLT5QcmludCgiXG4iKTsKK30KKworLy8gUHJpbnRzIGFsbCBlbnVtcyBjb250YWluZWQgaW4gYWxsIG1lc3NhZ2UgdHlwZXMgaW4gfGZpbGV8Lgordm9pZCBHZW5lcmF0b3I6OlByaW50QWxsTmVzdGVkRW51bXNJbkZpbGUoKSBjb25zdCB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpOyArK2kpIHsKKyAgICBQcmludE5lc3RlZEVudW1zKCpmaWxlXy0+bWVzc2FnZV90eXBlKGkpKTsKKyAgfQorfQorCisvLyBQcmludHMgYSBQeXRob24gc3RhdGVtZW50IGFzc2lnbmluZyB0aGUgYXBwcm9wcmlhdGUgbW9kdWxlLWxldmVsCisvLyBlbnVtIG5hbWUgdG8gYSBQeXRob24gRW51bURlc2NyaXB0b3Igb2JqZWN0IGVxdWl2YWxlbnQgdG8KKy8vIGVudW1fZGVzY3JpcHRvci4KK3ZvaWQgR2VuZXJhdG9yOjpQcmludEVudW0oY29uc3QgRW51bURlc2NyaXB0b3ImIGVudW1fZGVzY3JpcHRvcikgY29uc3QgeworICBtYXA8c3RyaW5nLCBzdHJpbmc+IG07CisgIHN0cmluZyBtb2R1bGVfbGV2ZWxfZGVzY3JpcHRvcl9uYW1lID0KKyAgICAgIE1vZHVsZUxldmVsRGVzY3JpcHRvck5hbWUoZW51bV9kZXNjcmlwdG9yKTsKKyAgbVsiZGVzY3JpcHRvcl9uYW1lIl0gPSBtb2R1bGVfbGV2ZWxfZGVzY3JpcHRvcl9uYW1lOworICBtWyJuYW1lIl0gPSBlbnVtX2Rlc2NyaXB0b3IubmFtZSgpOworICBtWyJmdWxsX25hbWUiXSA9IGVudW1fZGVzY3JpcHRvci5mdWxsX25hbWUoKTsKKyAgbVsiZmlsZSJdID0ga0Rlc2NyaXB0b3JLZXk7CisgIGNvbnN0IGNoYXIgZW51bV9kZXNjcmlwdG9yX3RlbXBsYXRlW10gPQorICAgICAgIiRkZXNjcmlwdG9yX25hbWUkID0gX2Rlc2NyaXB0b3IuRW51bURlc2NyaXB0b3IoXG4iCisgICAgICAiICBuYW1lPSckbmFtZSQnLFxuIgorICAgICAgIiAgZnVsbF9uYW1lPSckZnVsbF9uYW1lJCcsXG4iCisgICAgICAiICBmaWxlbmFtZT1Ob25lLFxuIgorICAgICAgIiAgZmlsZT0kZmlsZSQsXG4iCisgICAgICAiICB2YWx1ZXM9W1xuIjsKKyAgc3RyaW5nIG9wdGlvbnNfc3RyaW5nOworICBlbnVtX2Rlc2NyaXB0b3Iub3B0aW9ucygpLlNlcmlhbGl6ZVRvU3RyaW5nKCZvcHRpb25zX3N0cmluZyk7CisgIHByaW50ZXJfLT5QcmludChtLCBlbnVtX2Rlc2NyaXB0b3JfdGVtcGxhdGUpOworICBwcmludGVyXy0+SW5kZW50KCk7CisgIHByaW50ZXJfLT5JbmRlbnQoKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBlbnVtX2Rlc2NyaXB0b3IudmFsdWVfY291bnQoKTsgKytpKSB7CisgICAgUHJpbnRFbnVtVmFsdWVEZXNjcmlwdG9yKCplbnVtX2Rlc2NyaXB0b3IudmFsdWUoaSkpOworICAgIHByaW50ZXJfLT5QcmludCgiLFxuIik7CisgIH0KKyAgcHJpbnRlcl8tPk91dGRlbnQoKTsKKyAgcHJpbnRlcl8tPlByaW50KCJdLFxuIik7CisgIHByaW50ZXJfLT5QcmludCgiY29udGFpbmluZ190eXBlPU5vbmUsXG4iKTsKKyAgcHJpbnRlcl8tPlByaW50KCJvcHRpb25zPSRvcHRpb25zX3ZhbHVlJCxcbiIsCisgICAgICAgICAgICAgICAgICAib3B0aW9uc192YWx1ZSIsCisgICAgICAgICAgICAgICAgICBPcHRpb25zVmFsdWUoIkVudW1PcHRpb25zIiwgb3B0aW9uc19zdHJpbmcpKTsKKyAgRW51bURlc2NyaXB0b3JQcm90byBlZHA7CisgIFByaW50U2VyaWFsaXplZFBiSW50ZXJ2YWwoZW51bV9kZXNjcmlwdG9yLCBlZHApOworICBwcmludGVyXy0+T3V0ZGVudCgpOworICBwcmludGVyXy0+UHJpbnQoIilcbiIpOworICBwcmludGVyXy0+UHJpbnQoIl9zeW1fZGIuUmVnaXN0ZXJFbnVtRGVzY3JpcHRvcigkbmFtZSQpXG4iLCAibmFtZSIsCisgICAgICAgICAgICAgICAgICBtb2R1bGVfbGV2ZWxfZGVzY3JpcHRvcl9uYW1lKTsKKyAgcHJpbnRlcl8tPlByaW50KCJcbiIpOworfQorCisvLyBSZWN1cnNpdmVseSBwcmludHMgZW51bXMgaW4gbmVzdGVkIHR5cGVzIHdpdGhpbiBkZXNjcmlwdG9yLCB0aGVuCisvLyBwcmludHMgZW51bXMgY29udGFpbmVkIGF0IHRoZSB0b3AgbGV2ZWwgaW4gZGVzY3JpcHRvci4KK3ZvaWQgR2VuZXJhdG9yOjpQcmludE5lc3RlZEVudW1zKGNvbnN0IERlc2NyaXB0b3ImIGRlc2NyaXB0b3IpIGNvbnN0IHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yLm5lc3RlZF90eXBlX2NvdW50KCk7ICsraSkgeworICAgIFByaW50TmVzdGVkRW51bXMoKmRlc2NyaXB0b3IubmVzdGVkX3R5cGUoaSkpOworICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yLmVudW1fdHlwZV9jb3VudCgpOyArK2kpIHsKKyAgICBQcmludEVudW0oKmRlc2NyaXB0b3IuZW51bV90eXBlKGkpKTsKKyAgfQorfQorCit2b2lkIEdlbmVyYXRvcjo6UHJpbnRUb3BMZXZlbEV4dGVuc2lvbnMoKSBjb25zdCB7CisgIGNvbnN0IGJvb2wgaXNfZXh0ZW5zaW9uID0gdHJ1ZTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+ZXh0ZW5zaW9uX2NvdW50KCk7ICsraSkgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciYgZXh0ZW5zaW9uX2ZpZWxkID0gKmZpbGVfLT5leHRlbnNpb24oaSk7CisgICAgc3RyaW5nIGNvbnN0YW50X25hbWUgPSBleHRlbnNpb25fZmllbGQubmFtZSgpICsgIl9GSUVMRF9OVU1CRVIiOworICAgIFVwcGVyU3RyaW5nKCZjb25zdGFudF9uYW1lKTsKKyAgICBwcmludGVyXy0+UHJpbnQoIiRjb25zdGFudF9uYW1lJCA9ICRudW1iZXIkXG4iLAorICAgICAgImNvbnN0YW50X25hbWUiLCBjb25zdGFudF9uYW1lLAorICAgICAgIm51bWJlciIsIFNpbXBsZUl0b2EoZXh0ZW5zaW9uX2ZpZWxkLm51bWJlcigpKSk7CisgICAgcHJpbnRlcl8tPlByaW50KCIkbmFtZSQgPSAiLCAibmFtZSIsIGV4dGVuc2lvbl9maWVsZC5uYW1lKCkpOworICAgIFByaW50RmllbGREZXNjcmlwdG9yKGV4dGVuc2lvbl9maWVsZCwgaXNfZXh0ZW5zaW9uKTsKKyAgICBwcmludGVyXy0+UHJpbnQoIlxuIik7CisgIH0KKyAgcHJpbnRlcl8tPlByaW50KCJcbiIpOworfQorCisvLyBQcmludHMgUHl0aG9uIGVxdWl2YWxlbnRzIG9mIGFsbCBEZXNjcmlwdG9ycyBpbiB8ZmlsZXwuCit2b2lkIEdlbmVyYXRvcjo6UHJpbnRNZXNzYWdlRGVzY3JpcHRvcnMoKSBjb25zdCB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpOyArK2kpIHsKKyAgICBQcmludERlc2NyaXB0b3IoKmZpbGVfLT5tZXNzYWdlX3R5cGUoaSkpOworICAgIHByaW50ZXJfLT5QcmludCgiXG4iKTsKKyAgfQorfQorCit2b2lkIEdlbmVyYXRvcjo6UHJpbnRTZXJ2aWNlcygpIGNvbnN0IHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+c2VydmljZV9jb3VudCgpOyArK2kpIHsKKyAgICBQcmludFNlcnZpY2VEZXNjcmlwdG9yKCpmaWxlXy0+c2VydmljZShpKSk7CisgICAgUHJpbnRTZXJ2aWNlQ2xhc3MoKmZpbGVfLT5zZXJ2aWNlKGkpKTsKKyAgICBQcmludFNlcnZpY2VTdHViKCpmaWxlXy0+c2VydmljZShpKSk7CisgICAgcHJpbnRlcl8tPlByaW50KCJcbiIpOworICB9Cit9CisKK3ZvaWQgR2VuZXJhdG9yOjpQcmludFNlcnZpY2VEZXNjcmlwdG9yKAorICAgIGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yJiBkZXNjcmlwdG9yKSBjb25zdCB7CisgIHByaW50ZXJfLT5QcmludCgiXG4iKTsKKyAgc3RyaW5nIHNlcnZpY2VfbmFtZSA9IE1vZHVsZUxldmVsU2VydmljZURlc2NyaXB0b3JOYW1lKGRlc2NyaXB0b3IpOworICBzdHJpbmcgb3B0aW9uc19zdHJpbmc7CisgIGRlc2NyaXB0b3Iub3B0aW9ucygpLlNlcmlhbGl6ZVRvU3RyaW5nKCZvcHRpb25zX3N0cmluZyk7CisKKyAgcHJpbnRlcl8tPlByaW50KAorICAgICAgIiRzZXJ2aWNlX25hbWUkID0gX2Rlc2NyaXB0b3IuU2VydmljZURlc2NyaXB0b3IoXG4iLAorICAgICAgInNlcnZpY2VfbmFtZSIsIHNlcnZpY2VfbmFtZSk7CisgIHByaW50ZXJfLT5JbmRlbnQoKTsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiBtOworICBtWyJuYW1lIl0gPSBkZXNjcmlwdG9yLm5hbWUoKTsKKyAgbVsiZnVsbF9uYW1lIl0gPSBkZXNjcmlwdG9yLmZ1bGxfbmFtZSgpOworICBtWyJmaWxlIl0gPSBrRGVzY3JpcHRvcktleTsKKyAgbVsiaW5kZXgiXSA9IFNpbXBsZUl0b2EoZGVzY3JpcHRvci5pbmRleCgpKTsKKyAgbVsib3B0aW9uc192YWx1ZSJdID0gT3B0aW9uc1ZhbHVlKCJTZXJ2aWNlT3B0aW9ucyIsIG9wdGlvbnNfc3RyaW5nKTsKKyAgY29uc3QgY2hhciByZXF1aXJlZF9mdW5jdGlvbl9hcmd1bWVudHNbXSA9CisgICAgICAibmFtZT0nJG5hbWUkJyxcbiIKKyAgICAgICJmdWxsX25hbWU9JyRmdWxsX25hbWUkJyxcbiIKKyAgICAgICJmaWxlPSRmaWxlJCxcbiIKKyAgICAgICJpbmRleD0kaW5kZXgkLFxuIgorICAgICAgIm9wdGlvbnM9JG9wdGlvbnNfdmFsdWUkLFxuIjsKKyAgcHJpbnRlcl8tPlByaW50KG0sIHJlcXVpcmVkX2Z1bmN0aW9uX2FyZ3VtZW50cyk7CisKKyAgU2VydmljZURlc2NyaXB0b3JQcm90byBzZHA7CisgIFByaW50U2VyaWFsaXplZFBiSW50ZXJ2YWwoZGVzY3JpcHRvciwgc2RwKTsKKworICBwcmludGVyXy0+UHJpbnQoIm1ldGhvZHM9W1xuIik7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvci5tZXRob2RfY291bnQoKTsgKytpKSB7CisgICAgY29uc3QgTWV0aG9kRGVzY3JpcHRvciogbWV0aG9kID0gZGVzY3JpcHRvci5tZXRob2QoaSk7CisgICAgbWV0aG9kLT5vcHRpb25zKCkuU2VyaWFsaXplVG9TdHJpbmcoJm9wdGlvbnNfc3RyaW5nKTsKKworICAgIG0uY2xlYXIoKTsKKyAgICBtWyJuYW1lIl0gPSBtZXRob2QtPm5hbWUoKTsKKyAgICBtWyJmdWxsX25hbWUiXSA9IG1ldGhvZC0+ZnVsbF9uYW1lKCk7CisgICAgbVsiaW5kZXgiXSA9IFNpbXBsZUl0b2EobWV0aG9kLT5pbmRleCgpKTsKKyAgICBtWyJzZXJpYWxpemVkX29wdGlvbnMiXSA9IENFc2NhcGUob3B0aW9uc19zdHJpbmcpOworICAgIG1bImlucHV0X3R5cGUiXSA9IE1vZHVsZUxldmVsRGVzY3JpcHRvck5hbWUoKihtZXRob2QtPmlucHV0X3R5cGUoKSkpOworICAgIG1bIm91dHB1dF90eXBlIl0gPSBNb2R1bGVMZXZlbERlc2NyaXB0b3JOYW1lKCoobWV0aG9kLT5vdXRwdXRfdHlwZSgpKSk7CisgICAgbVsib3B0aW9uc192YWx1ZSJdID0gT3B0aW9uc1ZhbHVlKCJNZXRob2RPcHRpb25zIiwgb3B0aW9uc19zdHJpbmcpOworICAgIHByaW50ZXJfLT5QcmludCgiX2Rlc2NyaXB0b3IuTWV0aG9kRGVzY3JpcHRvcihcbiIpOworICAgIHByaW50ZXJfLT5JbmRlbnQoKTsKKyAgICBwcmludGVyXy0+UHJpbnQoCisgICAgICAgIG0sCisgICAgICAgICJuYW1lPSckbmFtZSQnLFxuIgorICAgICAgICAiZnVsbF9uYW1lPSckZnVsbF9uYW1lJCcsXG4iCisgICAgICAgICJpbmRleD0kaW5kZXgkLFxuIgorICAgICAgICAiY29udGFpbmluZ19zZXJ2aWNlPU5vbmUsXG4iCisgICAgICAgICJpbnB1dF90eXBlPSRpbnB1dF90eXBlJCxcbiIKKyAgICAgICAgIm91dHB1dF90eXBlPSRvdXRwdXRfdHlwZSQsXG4iCisgICAgICAgICJvcHRpb25zPSRvcHRpb25zX3ZhbHVlJCxcbiIpOworICAgIHByaW50ZXJfLT5PdXRkZW50KCk7CisgICAgcHJpbnRlcl8tPlByaW50KCIpLFxuIik7CisgIH0KKworICBwcmludGVyXy0+T3V0ZGVudCgpOworICBwcmludGVyXy0+UHJpbnQoIl0pXG5cbiIpOworfQorCisKK3ZvaWQgR2VuZXJhdG9yOjpQcmludERlc2NyaXB0b3JLZXlBbmRNb2R1bGVOYW1lKAorICAgIGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yJiBkZXNjcmlwdG9yKSBjb25zdCB7CisgIHByaW50ZXJfLT5QcmludCgKKyAgICAgICIkZGVzY3JpcHRvcl9rZXkkID0gJGRlc2NyaXB0b3JfbmFtZSQsXG4iLAorICAgICAgImRlc2NyaXB0b3Jfa2V5Iiwga0Rlc2NyaXB0b3JLZXksCisgICAgICAiZGVzY3JpcHRvcl9uYW1lIiwgTW9kdWxlTGV2ZWxTZXJ2aWNlRGVzY3JpcHRvck5hbWUoZGVzY3JpcHRvcikpOworICBwcmludGVyXy0+UHJpbnQoCisgICAgICAiX19tb2R1bGVfXyA9ICckbW9kdWxlX25hbWUkJ1xuIiwKKyAgICAgICJtb2R1bGVfbmFtZSIsIE1vZHVsZU5hbWUoZmlsZV8tPm5hbWUoKSkpOworfQorCit2b2lkIEdlbmVyYXRvcjo6UHJpbnRTZXJ2aWNlQ2xhc3MoY29uc3QgU2VydmljZURlc2NyaXB0b3ImIGRlc2NyaXB0b3IpIGNvbnN0IHsKKyAgLy8gUHJpbnQgdGhlIHNlcnZpY2UuCisgIHByaW50ZXJfLT5QcmludCgiJGNsYXNzX25hbWUkID0gc2VydmljZV9yZWZsZWN0aW9uLkdlbmVyYXRlZFNlcnZpY2VUeXBlKCIKKyAgICAgICAgICAgICAgICAgICInJGNsYXNzX25hbWUkJywgKF9zZXJ2aWNlLlNlcnZpY2UsKSwgZGljdChcbiIsCisgICAgICAgICAgICAgICAgICAiY2xhc3NfbmFtZSIsIGRlc2NyaXB0b3IubmFtZSgpKTsKKyAgcHJpbnRlcl8tPkluZGVudCgpOworICBHZW5lcmF0b3I6OlByaW50RGVzY3JpcHRvcktleUFuZE1vZHVsZU5hbWUoZGVzY3JpcHRvcik7CisgIHByaW50ZXJfLT5QcmludCgiKSlcblxuIik7CisgIHByaW50ZXJfLT5PdXRkZW50KCk7Cit9CisKK3ZvaWQgR2VuZXJhdG9yOjpQcmludFNlcnZpY2VTdHViKGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yJiBkZXNjcmlwdG9yKSBjb25zdCB7CisgIC8vIFByaW50IHRoZSBzZXJ2aWNlIHN0dWIuCisgIHByaW50ZXJfLT5QcmludCgiJGNsYXNzX25hbWUkX1N0dWIgPSAiCisgICAgICAgICAgICAgICAgICAic2VydmljZV9yZWZsZWN0aW9uLkdlbmVyYXRlZFNlcnZpY2VTdHViVHlwZSgiCisgICAgICAgICAgICAgICAgICAiJyRjbGFzc19uYW1lJF9TdHViJywgKCRjbGFzc19uYW1lJCwpLCBkaWN0KFxuIiwKKyAgICAgICAgICAgICAgICAgICJjbGFzc19uYW1lIiwgZGVzY3JpcHRvci5uYW1lKCkpOworICBwcmludGVyXy0+SW5kZW50KCk7CisgIEdlbmVyYXRvcjo6UHJpbnREZXNjcmlwdG9yS2V5QW5kTW9kdWxlTmFtZShkZXNjcmlwdG9yKTsKKyAgcHJpbnRlcl8tPlByaW50KCIpKVxuXG4iKTsKKyAgcHJpbnRlcl8tPk91dGRlbnQoKTsKK30KKworLy8gUHJpbnRzIHN0YXRlbWVudCBhc3NpZ25pbmcgTW9kdWxlTGV2ZWxEZXNjcmlwdG9yTmFtZShtZXNzYWdlX2Rlc2NyaXB0b3IpCisvLyB0byBhIFB5dGhvbiBEZXNjcmlwdG9yIG9iamVjdCBmb3IgbWVzc2FnZV9kZXNjcmlwdG9yLgorLy8KKy8vIE11dHVhbGx5IHJlY3Vyc2l2ZSB3aXRoIFByaW50TmVzdGVkRGVzY3JpcHRvcnMoKS4KK3ZvaWQgR2VuZXJhdG9yOjpQcmludERlc2NyaXB0b3IoY29uc3QgRGVzY3JpcHRvciYgbWVzc2FnZV9kZXNjcmlwdG9yKSBjb25zdCB7CisgIFByaW50TmVzdGVkRGVzY3JpcHRvcnMobWVzc2FnZV9kZXNjcmlwdG9yKTsKKworICBwcmludGVyXy0+UHJpbnQoIlxuIik7CisgIHByaW50ZXJfLT5QcmludCgiJGRlc2NyaXB0b3JfbmFtZSQgPSBfZGVzY3JpcHRvci5EZXNjcmlwdG9yKFxuIiwKKyAgICAgICAgICAgICAgICAgICJkZXNjcmlwdG9yX25hbWUiLAorICAgICAgICAgICAgICAgICAgTW9kdWxlTGV2ZWxEZXNjcmlwdG9yTmFtZShtZXNzYWdlX2Rlc2NyaXB0b3IpKTsKKyAgcHJpbnRlcl8tPkluZGVudCgpOworICBtYXA8c3RyaW5nLCBzdHJpbmc+IG07CisgIG1bIm5hbWUiXSA9IG1lc3NhZ2VfZGVzY3JpcHRvci5uYW1lKCk7CisgIG1bImZ1bGxfbmFtZSJdID0gbWVzc2FnZV9kZXNjcmlwdG9yLmZ1bGxfbmFtZSgpOworICBtWyJmaWxlIl0gPSBrRGVzY3JpcHRvcktleTsKKyAgY29uc3QgY2hhciByZXF1aXJlZF9mdW5jdGlvbl9hcmd1bWVudHNbXSA9CisgICAgICAibmFtZT0nJG5hbWUkJyxcbiIKKyAgICAgICJmdWxsX25hbWU9JyRmdWxsX25hbWUkJyxcbiIKKyAgICAgICJmaWxlbmFtZT1Ob25lLFxuIgorICAgICAgImZpbGU9JGZpbGUkLFxuIgorICAgICAgImNvbnRhaW5pbmdfdHlwZT1Ob25lLFxuIjsKKyAgcHJpbnRlcl8tPlByaW50KG0sIHJlcXVpcmVkX2Z1bmN0aW9uX2FyZ3VtZW50cyk7CisgIFByaW50RmllbGRzSW5EZXNjcmlwdG9yKG1lc3NhZ2VfZGVzY3JpcHRvcik7CisgIFByaW50RXh0ZW5zaW9uc0luRGVzY3JpcHRvcihtZXNzYWdlX2Rlc2NyaXB0b3IpOworCisgIC8vIE5lc3RlZCB0eXBlcworICBwcmludGVyXy0+UHJpbnQoIm5lc3RlZF90eXBlcz1bIik7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZV9kZXNjcmlwdG9yLm5lc3RlZF90eXBlX2NvdW50KCk7ICsraSkgeworICAgIGNvbnN0IHN0cmluZyBuZXN0ZWRfbmFtZSA9IE1vZHVsZUxldmVsRGVzY3JpcHRvck5hbWUoCisgICAgICAgICptZXNzYWdlX2Rlc2NyaXB0b3IubmVzdGVkX3R5cGUoaSkpOworICAgIHByaW50ZXJfLT5QcmludCgiJG5hbWUkLCAiLCAibmFtZSIsIG5lc3RlZF9uYW1lKTsKKyAgfQorICBwcmludGVyXy0+UHJpbnQoIl0sXG4iKTsKKworICAvLyBFbnVtIHR5cGVzCisgIHByaW50ZXJfLT5QcmludCgiZW51bV90eXBlcz1bXG4iKTsKKyAgcHJpbnRlcl8tPkluZGVudCgpOworICBmb3IgKGludCBpID0gMDsgaSA8IG1lc3NhZ2VfZGVzY3JpcHRvci5lbnVtX3R5cGVfY291bnQoKTsgKytpKSB7CisgICAgY29uc3Qgc3RyaW5nIGRlc2NyaXB0b3JfbmFtZSA9IE1vZHVsZUxldmVsRGVzY3JpcHRvck5hbWUoCisgICAgICAgICptZXNzYWdlX2Rlc2NyaXB0b3IuZW51bV90eXBlKGkpKTsKKyAgICBwcmludGVyXy0+UHJpbnQoZGVzY3JpcHRvcl9uYW1lLmNfc3RyKCkpOworICAgIHByaW50ZXJfLT5QcmludCgiLFxuIik7CisgIH0KKyAgcHJpbnRlcl8tPk91dGRlbnQoKTsKKyAgcHJpbnRlcl8tPlByaW50KCJdLFxuIik7CisgIHN0cmluZyBvcHRpb25zX3N0cmluZzsKKyAgbWVzc2FnZV9kZXNjcmlwdG9yLm9wdGlvbnMoKS5TZXJpYWxpemVUb1N0cmluZygmb3B0aW9uc19zdHJpbmcpOworICBwcmludGVyXy0+UHJpbnQoCisgICAgICAib3B0aW9ucz0kb3B0aW9uc192YWx1ZSQsXG4iCisgICAgICAiaXNfZXh0ZW5kYWJsZT0kZXh0ZW5kYWJsZSQsXG4iCisgICAgICAic3ludGF4PSckc3ludGF4JCciLAorICAgICAgIm9wdGlvbnNfdmFsdWUiLCBPcHRpb25zVmFsdWUoIk1lc3NhZ2VPcHRpb25zIiwgb3B0aW9uc19zdHJpbmcpLAorICAgICAgImV4dGVuZGFibGUiLCBtZXNzYWdlX2Rlc2NyaXB0b3IuZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCkgPiAwID8KKyAgICAgICAgICAgICAgICAgICAgICAiVHJ1ZSIgOiAiRmFsc2UiLAorICAgICAgInN5bnRheCIsIFN0cmluZ2lmeVN5bnRheChtZXNzYWdlX2Rlc2NyaXB0b3IuZmlsZSgpLT5zeW50YXgoKSkpOworICBwcmludGVyXy0+UHJpbnQoIixcbiIpOworCisgIC8vIEV4dGVuc2lvbiByYW5nZXMKKyAgcHJpbnRlcl8tPlByaW50KCJleHRlbnNpb25fcmFuZ2VzPVsiKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZXNzYWdlX2Rlc2NyaXB0b3IuZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCk7ICsraSkgeworICAgIGNvbnN0IERlc2NyaXB0b3I6OkV4dGVuc2lvblJhbmdlKiByYW5nZSA9CisgICAgICAgIG1lc3NhZ2VfZGVzY3JpcHRvci5leHRlbnNpb25fcmFuZ2UoaSk7CisgICAgcHJpbnRlcl8tPlByaW50KCIoJHN0YXJ0JCwgJGVuZCQpLCAiLAorICAgICAgICAgICAgICAgICAgICAic3RhcnQiLCBTaW1wbGVJdG9hKHJhbmdlLT5zdGFydCksCisgICAgICAgICAgICAgICAgICAgICJlbmQiLCBTaW1wbGVJdG9hKHJhbmdlLT5lbmQpKTsKKyAgfQorICBwcmludGVyXy0+UHJpbnQoIl0sXG4iKTsKKyAgcHJpbnRlcl8tPlByaW50KCJvbmVvZnM9W1xuIik7CisgIHByaW50ZXJfLT5JbmRlbnQoKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZXNzYWdlX2Rlc2NyaXB0b3Iub25lb2ZfZGVjbF9jb3VudCgpOyArK2kpIHsKKyAgICBjb25zdCBPbmVvZkRlc2NyaXB0b3IqIGRlc2MgPSBtZXNzYWdlX2Rlc2NyaXB0b3Iub25lb2ZfZGVjbChpKTsKKyAgICBtYXA8c3RyaW5nLCBzdHJpbmc+IG07CisgICAgbVsibmFtZSJdID0gZGVzYy0+bmFtZSgpOworICAgIG1bImZ1bGxfbmFtZSJdID0gZGVzYy0+ZnVsbF9uYW1lKCk7CisgICAgbVsiaW5kZXgiXSA9IFNpbXBsZUl0b2EoZGVzYy0+aW5kZXgoKSk7CisgICAgcHJpbnRlcl8tPlByaW50KAorICAgICAgICBtLAorICAgICAgICAiX2Rlc2NyaXB0b3IuT25lb2ZEZXNjcmlwdG9yKFxuIgorICAgICAgICAiICBuYW1lPSckbmFtZSQnLCBmdWxsX25hbWU9JyRmdWxsX25hbWUkJyxcbiIKKyAgICAgICAgIiAgaW5kZXg9JGluZGV4JCwgY29udGFpbmluZ190eXBlPU5vbmUsIGZpZWxkcz1bXSksXG4iKTsKKyAgfQorICBwcmludGVyXy0+T3V0ZGVudCgpOworICBwcmludGVyXy0+UHJpbnQoIl0sXG4iKTsKKyAgLy8gU2VyaWFsaXphdGlvbiBvZiBwcm90bworICBEZXNjcmlwdG9yUHJvdG8gZWRwOworICBQcmludFNlcmlhbGl6ZWRQYkludGVydmFsKG1lc3NhZ2VfZGVzY3JpcHRvciwgZWRwKTsKKworICBwcmludGVyXy0+T3V0ZGVudCgpOworICBwcmludGVyXy0+UHJpbnQoIilcbiIpOworfQorCisvLyBQcmludHMgUHl0aG9uIERlc2NyaXB0b3Igb2JqZWN0cyBmb3IgYWxsIG5lc3RlZCB0eXBlcyBjb250YWluZWQgaW4KKy8vIG1lc3NhZ2VfZGVzY3JpcHRvci4KKy8vCisvLyBNdXR1YWxseSByZWN1cnNpdmUgd2l0aCBQcmludERlc2NyaXB0b3IoKS4KK3ZvaWQgR2VuZXJhdG9yOjpQcmludE5lc3RlZERlc2NyaXB0b3JzKAorICAgIGNvbnN0IERlc2NyaXB0b3ImIGNvbnRhaW5pbmdfZGVzY3JpcHRvcikgY29uc3QgeworICBmb3IgKGludCBpID0gMDsgaSA8IGNvbnRhaW5pbmdfZGVzY3JpcHRvci5uZXN0ZWRfdHlwZV9jb3VudCgpOyArK2kpIHsKKyAgICBQcmludERlc2NyaXB0b3IoKmNvbnRhaW5pbmdfZGVzY3JpcHRvci5uZXN0ZWRfdHlwZShpKSk7CisgIH0KK30KKworLy8gUHJpbnRzIGFsbCBtZXNzYWdlcyBpbiB8ZmlsZXwuCit2b2lkIEdlbmVyYXRvcjo6UHJpbnRNZXNzYWdlcygpIGNvbnN0IHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+bWVzc2FnZV90eXBlX2NvdW50KCk7ICsraSkgeworICAgIHZlY3RvcjxzdHJpbmc+IHRvX3JlZ2lzdGVyOworICAgIFByaW50TWVzc2FnZSgqZmlsZV8tPm1lc3NhZ2VfdHlwZShpKSwgIiIsICZ0b19yZWdpc3Rlcik7CisgICAgZm9yIChpbnQgaiA9IDA7IGogPCB0b19yZWdpc3Rlci5zaXplKCk7ICsraikgeworICAgICAgcHJpbnRlcl8tPlByaW50KCJfc3ltX2RiLlJlZ2lzdGVyTWVzc2FnZSgkbmFtZSQpXG4iLCAibmFtZSIsCisgICAgICAgICAgICAgICAgICAgICAgdG9fcmVnaXN0ZXJbal0pOworICAgIH0KKyAgICBwcmludGVyXy0+UHJpbnQoIlxuIik7CisgIH0KK30KKworLy8gUHJpbnRzIGEgUHl0aG9uIGNsYXNzIGZvciB0aGUgZ2l2ZW4gbWVzc2FnZSBkZXNjcmlwdG9yLiAgV2UgZGVmZXIgdG8gdGhlCisvLyBtZXRhY2xhc3MgdG8gZG8gYWxtb3N0IGFsbCBvZiB0aGUgd29yayBvZiBhY3R1YWxseSBjcmVhdGluZyBhIHVzZWZ1bCBjbGFzcy4KKy8vIFRoZSBwdXJwb3NlIG9mIHRoaXMgZnVuY3Rpb24gYW5kIGl0cyBtYW55IGhlbHBlciBmdW5jdGlvbnMgYWJvdmUgaXMgbWVyZWx5CisvLyB0byBvdXRwdXQgYSBQeXRob24gdmVyc2lvbiBvZiB0aGUgZGVzY3JpcHRvcnMsIHdoaWNoIHRoZSBtZXRhY2xhc3MgaW4KKy8vIHJlZmxlY3Rpb24ucHkgd2lsbCB1c2UgdG8gY29uc3RydWN0IHRoZSBtZWF0IG9mIHRoZSBjbGFzcyBpdHNlbGYuCisvLworLy8gTXV0dWFsbHkgcmVjdXJzaXZlIHdpdGggUHJpbnROZXN0ZWRNZXNzYWdlcygpLgorLy8gQ29sbGVjdCBuZXN0ZWQgbWVzc2FnZSBuYW1lcyB0b19yZWdpc3RlciBmb3IgdGhlIHN5bWJvbF9kYXRhYmFzZS4KK3ZvaWQgR2VuZXJhdG9yOjpQcmludE1lc3NhZ2UoY29uc3QgRGVzY3JpcHRvciYgbWVzc2FnZV9kZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHByZWZpeCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjdG9yPHN0cmluZz4qIHRvX3JlZ2lzdGVyKSBjb25zdCB7CisgIHN0cmluZyBxdWFsaWZpZWRfbmFtZShwcmVmaXggKyBtZXNzYWdlX2Rlc2NyaXB0b3IubmFtZSgpKTsKKyAgdG9fcmVnaXN0ZXItPnB1c2hfYmFjayhxdWFsaWZpZWRfbmFtZSk7CisgIHByaW50ZXJfLT5QcmludCgKKyAgICAgICIkbmFtZSQgPSBfcmVmbGVjdGlvbi5HZW5lcmF0ZWRQcm90b2NvbE1lc3NhZ2VUeXBlKCckbmFtZSQnLCAiCisgICAgICAiKF9tZXNzYWdlLk1lc3NhZ2UsKSwgZGljdChcbiIsCisgICAgICAibmFtZSIsIG1lc3NhZ2VfZGVzY3JpcHRvci5uYW1lKCkpOworICBwcmludGVyXy0+SW5kZW50KCk7CisKKyAgUHJpbnROZXN0ZWRNZXNzYWdlcyhtZXNzYWdlX2Rlc2NyaXB0b3IsIHF1YWxpZmllZF9uYW1lICsgIi4iLCB0b19yZWdpc3Rlcik7CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gbTsKKyAgbVsiZGVzY3JpcHRvcl9rZXkiXSA9IGtEZXNjcmlwdG9yS2V5OworICBtWyJkZXNjcmlwdG9yX25hbWUiXSA9IE1vZHVsZUxldmVsRGVzY3JpcHRvck5hbWUobWVzc2FnZV9kZXNjcmlwdG9yKTsKKyAgcHJpbnRlcl8tPlByaW50KG0sICIkZGVzY3JpcHRvcl9rZXkkID0gJGRlc2NyaXB0b3JfbmFtZSQsXG4iKTsKKyAgcHJpbnRlcl8tPlByaW50KCJfX21vZHVsZV9fID0gJyRtb2R1bGVfbmFtZSQnXG4iLAorICAgICAgICAgICAgICAgICAgIm1vZHVsZV9uYW1lIiwgTW9kdWxlTmFtZShmaWxlXy0+bmFtZSgpKSk7CisgIHByaW50ZXJfLT5QcmludCgiIyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6JGZ1bGxfbmFtZSQpXG4iLAorICAgICAgICAgICAgICAgICAgImZ1bGxfbmFtZSIsIG1lc3NhZ2VfZGVzY3JpcHRvci5mdWxsX25hbWUoKSk7CisgIHByaW50ZXJfLT5QcmludCgiKSlcbiIpOworICBwcmludGVyXy0+T3V0ZGVudCgpOworfQorCisvLyBQcmludHMgYWxsIG5lc3RlZCBtZXNzYWdlcyB3aXRoaW4gfGNvbnRhaW5pbmdfZGVzY3JpcHRvcnwuCisvLyBNdXR1YWxseSByZWN1cnNpdmUgd2l0aCBQcmludE1lc3NhZ2UoKS4KK3ZvaWQgR2VuZXJhdG9yOjpQcmludE5lc3RlZE1lc3NhZ2VzKGNvbnN0IERlc2NyaXB0b3ImIGNvbnRhaW5pbmdfZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgcHJlZml4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjdG9yPHN0cmluZz4qIHRvX3JlZ2lzdGVyKSBjb25zdCB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgY29udGFpbmluZ19kZXNjcmlwdG9yLm5lc3RlZF90eXBlX2NvdW50KCk7ICsraSkgeworICAgIHByaW50ZXJfLT5QcmludCgiXG4iKTsKKyAgICBQcmludE1lc3NhZ2UoKmNvbnRhaW5pbmdfZGVzY3JpcHRvci5uZXN0ZWRfdHlwZShpKSwgcHJlZml4LCB0b19yZWdpc3Rlcik7CisgICAgcHJpbnRlcl8tPlByaW50KCIsXG4iKTsKKyAgfQorfQorCisvLyBSZWN1cnNpdmVseSBmaXhlcyBmb3JlaWduIGZpZWxkcyBpbiBhbGwgbmVzdGVkIHR5cGVzIGluIHxkZXNjcmlwdG9yfCwgdGhlbgorLy8gc2V0cyB0aGUgbWVzc2FnZV90eXBlIGFuZCBlbnVtX3R5cGUgb2YgYWxsIG1lc3NhZ2UgYW5kIGVudW0gZmllbGRzIHRvIHBvaW50CisvLyB0byB0aGVpciByZXNwZWN0aXZlIGRlc2NyaXB0b3JzLgorLy8gQXJnczoKKy8vICAgZGVzY3JpcHRvcjogZGVzY3JpcHRvciB0byBwcmludCBmaWVsZHMgZm9yLgorLy8gICBjb250YWluaW5nX2Rlc2NyaXB0b3I6IGlmIGRlc2NyaXB0b3IgaXMgYSBuZXN0ZWQgdHlwZSwgdGhpcyBpcyBpdHMKKy8vICAgICAgIGNvbnRhaW5pbmcgdHlwZSwgb3IgTlVMTCBpZiB0aGlzIGlzIGEgcm9vdC90b3AtbGV2ZWwgdHlwZS4KK3ZvaWQgR2VuZXJhdG9yOjpGaXhGb3JlaWduRmllbGRzSW5EZXNjcmlwdG9yKAorICAgIGNvbnN0IERlc2NyaXB0b3ImIGRlc2NyaXB0b3IsCisgICAgY29uc3QgRGVzY3JpcHRvciogY29udGFpbmluZ19kZXNjcmlwdG9yKSBjb25zdCB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvci5uZXN0ZWRfdHlwZV9jb3VudCgpOyArK2kpIHsKKyAgICBGaXhGb3JlaWduRmllbGRzSW5EZXNjcmlwdG9yKCpkZXNjcmlwdG9yLm5lc3RlZF90eXBlKGkpLCAmZGVzY3JpcHRvcik7CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3IuZmllbGRfY291bnQoKTsgKytpKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yJiBmaWVsZF9kZXNjcmlwdG9yID0gKmRlc2NyaXB0b3IuZmllbGQoaSk7CisgICAgRml4Rm9yZWlnbkZpZWxkc0luRmllbGQoJmRlc2NyaXB0b3IsIGZpZWxkX2Rlc2NyaXB0b3IsICJmaWVsZHNfYnlfbmFtZSIpOworICB9CisKKyAgRml4Q29udGFpbmluZ1R5cGVJbkRlc2NyaXB0b3IoZGVzY3JpcHRvciwgY29udGFpbmluZ19kZXNjcmlwdG9yKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yLmVudW1fdHlwZV9jb3VudCgpOyArK2kpIHsKKyAgICBjb25zdCBFbnVtRGVzY3JpcHRvciYgZW51bV9kZXNjcmlwdG9yID0gKmRlc2NyaXB0b3IuZW51bV90eXBlKGkpOworICAgIEZpeENvbnRhaW5pbmdUeXBlSW5EZXNjcmlwdG9yKGVudW1fZGVzY3JpcHRvciwgJmRlc2NyaXB0b3IpOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvci5vbmVvZl9kZWNsX2NvdW50KCk7ICsraSkgeworICAgIG1hcDxzdHJpbmcsIHN0cmluZz4gbTsKKyAgICBjb25zdCBPbmVvZkRlc2NyaXB0b3IqIG9uZW9mID0gZGVzY3JpcHRvci5vbmVvZl9kZWNsKGkpOworICAgIG1bImRlc2NyaXB0b3JfbmFtZSJdID0gTW9kdWxlTGV2ZWxEZXNjcmlwdG9yTmFtZShkZXNjcmlwdG9yKTsKKyAgICBtWyJvbmVvZl9uYW1lIl0gPSBvbmVvZi0+bmFtZSgpOworICAgIGZvciAoaW50IGogPSAwOyBqIDwgb25lb2YtPmZpZWxkX2NvdW50KCk7ICsraikgeworICAgICAgbVsiZmllbGRfbmFtZSJdID0gb25lb2YtPmZpZWxkKGopLT5uYW1lKCk7CisgICAgICBwcmludGVyXy0+UHJpbnQoCisgICAgICAgICAgbSwKKyAgICAgICAgICAiJGRlc2NyaXB0b3JfbmFtZSQub25lb2ZzX2J5X25hbWVbJyRvbmVvZl9uYW1lJCddLmZpZWxkcy5hcHBlbmQoXG4iCisgICAgICAgICAgIiAgJGRlc2NyaXB0b3JfbmFtZSQuZmllbGRzX2J5X25hbWVbJyRmaWVsZF9uYW1lJCddKVxuIik7CisgICAgICBwcmludGVyXy0+UHJpbnQoCisgICAgICAgICAgbSwKKyAgICAgICAgICAiJGRlc2NyaXB0b3JfbmFtZSQuZmllbGRzX2J5X25hbWVbJyRmaWVsZF9uYW1lJCddLmNvbnRhaW5pbmdfb25lb2YgPSAiCisgICAgICAgICAgIiRkZXNjcmlwdG9yX25hbWUkLm9uZW9mc19ieV9uYW1lWyckb25lb2ZfbmFtZSQnXVxuIik7CisgICAgfQorICB9Cit9CisKK3ZvaWQgR2VuZXJhdG9yOjpBZGRNZXNzYWdlVG9GaWxlRGVzY3JpcHRvcihjb25zdCBEZXNjcmlwdG9yJiBkZXNjcmlwdG9yKSBjb25zdCB7CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gbTsKKyAgbVsiZGVzY3JpcHRvcl9uYW1lIl0gPSBrRGVzY3JpcHRvcktleTsKKyAgbVsibWVzc2FnZV9uYW1lIl0gPSBkZXNjcmlwdG9yLm5hbWUoKTsKKyAgbVsibWVzc2FnZV9kZXNjcmlwdG9yX25hbWUiXSA9IE1vZHVsZUxldmVsRGVzY3JpcHRvck5hbWUoZGVzY3JpcHRvcik7CisgIGNvbnN0IGNoYXIgZmlsZV9kZXNjcmlwdG9yX3RlbXBsYXRlW10gPQorICAgICAgIiRkZXNjcmlwdG9yX25hbWUkLm1lc3NhZ2VfdHlwZXNfYnlfbmFtZVsnJG1lc3NhZ2VfbmFtZSQnXSA9ICIKKyAgICAgICIkbWVzc2FnZV9kZXNjcmlwdG9yX25hbWUkXG4iOworICBwcmludGVyXy0+UHJpbnQobSwgZmlsZV9kZXNjcmlwdG9yX3RlbXBsYXRlKTsKK30KKwordm9pZCBHZW5lcmF0b3I6OkFkZEVudW1Ub0ZpbGVEZXNjcmlwdG9yKAorICAgIGNvbnN0IEVudW1EZXNjcmlwdG9yJiBkZXNjcmlwdG9yKSBjb25zdCB7CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gbTsKKyAgbVsiZGVzY3JpcHRvcl9uYW1lIl0gPSBrRGVzY3JpcHRvcktleTsKKyAgbVsiZW51bV9uYW1lIl0gPSBkZXNjcmlwdG9yLm5hbWUoKTsKKyAgbVsiZW51bV9kZXNjcmlwdG9yX25hbWUiXSA9IE1vZHVsZUxldmVsRGVzY3JpcHRvck5hbWUoZGVzY3JpcHRvcik7CisgIGNvbnN0IGNoYXIgZmlsZV9kZXNjcmlwdG9yX3RlbXBsYXRlW10gPQorICAgICAgIiRkZXNjcmlwdG9yX25hbWUkLmVudW1fdHlwZXNfYnlfbmFtZVsnJGVudW1fbmFtZSQnXSA9ICIKKyAgICAgICIkZW51bV9kZXNjcmlwdG9yX25hbWUkXG4iOworICBwcmludGVyXy0+UHJpbnQobSwgZmlsZV9kZXNjcmlwdG9yX3RlbXBsYXRlKTsKK30KKwordm9pZCBHZW5lcmF0b3I6OkFkZEV4dGVuc2lvblRvRmlsZURlc2NyaXB0b3IoCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yJiBkZXNjcmlwdG9yKSBjb25zdCB7CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gbTsKKyAgbVsiZGVzY3JpcHRvcl9uYW1lIl0gPSBrRGVzY3JpcHRvcktleTsKKyAgbVsiZmllbGRfbmFtZSJdID0gZGVzY3JpcHRvci5uYW1lKCk7CisgIGNvbnN0IGNoYXIgZmlsZV9kZXNjcmlwdG9yX3RlbXBsYXRlW10gPQorICAgICAgIiRkZXNjcmlwdG9yX25hbWUkLmV4dGVuc2lvbnNfYnlfbmFtZVsnJGZpZWxkX25hbWUkJ10gPSAiCisgICAgICAiJGZpZWxkX25hbWUkXG4iOworICBwcmludGVyXy0+UHJpbnQobSwgZmlsZV9kZXNjcmlwdG9yX3RlbXBsYXRlKTsKK30KKworLy8gU2V0cyBhbnkgbmVjZXNzYXJ5IG1lc3NhZ2VfdHlwZSBhbmQgZW51bV90eXBlIGF0dHJpYnV0ZXMKKy8vIGZvciB0aGUgUHl0aG9uIHZlcnNpb24gb2YgfGZpZWxkfC4KKy8vCisvLyBjb250YWluaW5nX3R5cGUgbWF5IGJlIE5VTEwsIGluIHdoaWNoIGNhc2UgdGhpcyBpcyBhIG1vZHVsZS1sZXZlbCBmaWVsZC4KKy8vCisvLyBweXRob25fZGljdF9uYW1lIGlzIHRoZSBuYW1lIG9mIHRoZSBQeXRob24gZGljdCB3aGVyZSB3ZSBzaG91bGQKKy8vIGxvb2sgdGhlIGZpZWxkIHVwIGluIHRoZSBjb250YWluaW5nIHR5cGUuICAoZS5nLiwgZmllbGRzX2J5X25hbWUKKy8vIG9yIGV4dGVuc2lvbnNfYnlfbmFtZSkuICBXZSBpZ25vcmUgcHl0aG9uX2RpY3RfbmFtZSBpZiBjb250YWluaW5nX3R5cGUKKy8vIGlzIE5VTEwuCit2b2lkIEdlbmVyYXRvcjo6Rml4Rm9yZWlnbkZpZWxkc0luRmllbGQoY29uc3QgRGVzY3JpcHRvciogY29udGFpbmluZ190eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciYgZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBweXRob25fZGljdF9uYW1lKSBjb25zdCB7CisgIGNvbnN0IHN0cmluZyBmaWVsZF9yZWZlcmVuY2luZ19leHByZXNzaW9uID0gRmllbGRSZWZlcmVuY2luZ0V4cHJlc3Npb24oCisgICAgICBjb250YWluaW5nX3R5cGUsIGZpZWxkLCBweXRob25fZGljdF9uYW1lKTsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiBtOworICBtWyJmaWVsZF9yZWYiXSA9IGZpZWxkX3JlZmVyZW5jaW5nX2V4cHJlc3Npb247CisgIGNvbnN0IERlc2NyaXB0b3IqIGZvcmVpZ25fbWVzc2FnZV90eXBlID0gZmllbGQubWVzc2FnZV90eXBlKCk7CisgIGlmIChmb3JlaWduX21lc3NhZ2VfdHlwZSkgeworICAgIG1bImZvcmVpZ25fdHlwZSJdID0gTW9kdWxlTGV2ZWxEZXNjcmlwdG9yTmFtZSgqZm9yZWlnbl9tZXNzYWdlX3R5cGUpOworICAgIHByaW50ZXJfLT5QcmludChtLCAiJGZpZWxkX3JlZiQubWVzc2FnZV90eXBlID0gJGZvcmVpZ25fdHlwZSRcbiIpOworICB9CisgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBlbnVtX3R5cGUgPSBmaWVsZC5lbnVtX3R5cGUoKTsKKyAgaWYgKGVudW1fdHlwZSkgeworICAgIG1bImVudW1fdHlwZSJdID0gTW9kdWxlTGV2ZWxEZXNjcmlwdG9yTmFtZSgqZW51bV90eXBlKTsKKyAgICBwcmludGVyXy0+UHJpbnQobSwgIiRmaWVsZF9yZWYkLmVudW1fdHlwZSA9ICRlbnVtX3R5cGUkXG4iKTsKKyAgfQorfQorCisvLyBSZXR1cm5zIHRoZSBtb2R1bGUtbGV2ZWwgZXhwcmVzc2lvbiBmb3IgdGhlIGdpdmVuIEZpZWxkRGVzY3JpcHRvci4KKy8vIE9ubHkgd29ya3MgZm9yIGZpZWxkcyBpbiB0aGUgLnByb3RvIGZpbGUgdGhpcyBHZW5lcmF0b3IgaXMgZ2VuZXJhdGluZyBmb3IuCisvLworLy8gY29udGFpbmluZ190eXBlIG1heSBiZSBOVUxMLCBpbiB3aGljaCBjYXNlIHRoaXMgaXMgYSBtb2R1bGUtbGV2ZWwgZmllbGQuCisvLworLy8gcHl0aG9uX2RpY3RfbmFtZSBpcyB0aGUgbmFtZSBvZiB0aGUgUHl0aG9uIGRpY3Qgd2hlcmUgd2Ugc2hvdWxkCisvLyBsb29rIHRoZSBmaWVsZCB1cCBpbiB0aGUgY29udGFpbmluZyB0eXBlLiAgKGUuZy4sIGZpZWxkc19ieV9uYW1lCisvLyBvciBleHRlbnNpb25zX2J5X25hbWUpLiAgV2UgaWdub3JlIHB5dGhvbl9kaWN0X25hbWUgaWYgY29udGFpbmluZ190eXBlCisvLyBpcyBOVUxMLgorc3RyaW5nIEdlbmVyYXRvcjo6RmllbGRSZWZlcmVuY2luZ0V4cHJlc3Npb24oCisgICAgY29uc3QgRGVzY3JpcHRvciogY29udGFpbmluZ190eXBlLAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciYgZmllbGQsCisgICAgY29uc3Qgc3RyaW5nJiBweXRob25fZGljdF9uYW1lKSBjb25zdCB7CisgIC8vIFdlIHNob3VsZCBvbmx5IGV2ZXIgYmUgbG9va2luZyB1cCBmaWVsZHMgaW4gdGhlIGN1cnJlbnQgZmlsZS4KKyAgLy8gVGhlIG9ubHkgdGhpbmdzIHdlIHJlZmVyIHRvIGZyb20gb3RoZXIgZmlsZXMgYXJlIG1lc3NhZ2UgZGVzY3JpcHRvcnMuCisgIEdPT0dMRV9DSEVDS19FUShmaWVsZC5maWxlKCksIGZpbGVfKSA8PCBmaWVsZC5maWxlKCktPm5hbWUoKSA8PCAiIHZzLiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDw8IGZpbGVfLT5uYW1lKCk7CisgIGlmICghY29udGFpbmluZ190eXBlKSB7CisgICAgcmV0dXJuIGZpZWxkLm5hbWUoKTsKKyAgfQorICByZXR1cm4gc3RyaW5nczo6U3Vic3RpdHV0ZSgKKyAgICAgICIkMC4kMVsnJDInXSIsCisgICAgICBNb2R1bGVMZXZlbERlc2NyaXB0b3JOYW1lKCpjb250YWluaW5nX3R5cGUpLAorICAgICAgcHl0aG9uX2RpY3RfbmFtZSwgZmllbGQubmFtZSgpKTsKK30KKworLy8gUHJpbnRzIGNvbnRhaW5pbmdfdHlwZSBmb3IgbmVzdGVkIGRlc2NyaXB0b3JzIG9yIGVudW0gZGVzY3JpcHRvcnMuCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRGVzY3JpcHRvclQ+Cit2b2lkIEdlbmVyYXRvcjo6Rml4Q29udGFpbmluZ1R5cGVJbkRlc2NyaXB0b3IoCisgICAgY29uc3QgRGVzY3JpcHRvclQmIGRlc2NyaXB0b3IsCisgICAgY29uc3QgRGVzY3JpcHRvciogY29udGFpbmluZ19kZXNjcmlwdG9yKSBjb25zdCB7CisgIGlmIChjb250YWluaW5nX2Rlc2NyaXB0b3IgIT0gTlVMTCkgeworICAgIGNvbnN0IHN0cmluZyBuZXN0ZWRfbmFtZSA9IE1vZHVsZUxldmVsRGVzY3JpcHRvck5hbWUoZGVzY3JpcHRvcik7CisgICAgY29uc3Qgc3RyaW5nIHBhcmVudF9uYW1lID0gTW9kdWxlTGV2ZWxEZXNjcmlwdG9yTmFtZSgKKyAgICAgICAgKmNvbnRhaW5pbmdfZGVzY3JpcHRvcik7CisgICAgcHJpbnRlcl8tPlByaW50KAorICAgICAgICAiJG5lc3RlZF9uYW1lJC5jb250YWluaW5nX3R5cGUgPSAkcGFyZW50X25hbWUkXG4iLAorICAgICAgICAibmVzdGVkX25hbWUiLCBuZXN0ZWRfbmFtZSwKKyAgICAgICAgInBhcmVudF9uYW1lIiwgcGFyZW50X25hbWUpOworICB9Cit9CisKKy8vIFByaW50cyBzdGF0ZW1lbnRzIHNldHRpbmcgdGhlIG1lc3NhZ2VfdHlwZSBhbmQgZW51bV90eXBlIGZpZWxkcyBpbiB0aGUKKy8vIFB5dGhvbiBkZXNjcmlwdG9yIG9iamVjdHMgd2UndmUgYWxyZWFkeSBvdXRwdXQgaW4gdGhzIGZpbGUuICBXZSBtdXN0CisvLyBkbyB0aGlzIGluIGEgc2VwYXJhdGUgc3RlcCBkdWUgdG8gY2lyY3VsYXIgcmVmZXJlbmNlcyAob3RoZXJ3aXNlLCB3ZSdkCisvLyBqdXN0IHNldCBldmVyeXRoaW5nIGluIHRoZSBpbml0aWFsIGFzc2lnbm1lbnQgc3RhdGVtZW50cykuCit2b2lkIEdlbmVyYXRvcjo6Rml4Rm9yZWlnbkZpZWxkc0luRGVzY3JpcHRvcnMoKSBjb25zdCB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpOyArK2kpIHsKKyAgICBGaXhGb3JlaWduRmllbGRzSW5EZXNjcmlwdG9yKCpmaWxlXy0+bWVzc2FnZV90eXBlKGkpLCBOVUxMKTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5tZXNzYWdlX3R5cGVfY291bnQoKTsgKytpKSB7CisgICAgQWRkTWVzc2FnZVRvRmlsZURlc2NyaXB0b3IoKmZpbGVfLT5tZXNzYWdlX3R5cGUoaSkpOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPmVudW1fdHlwZV9jb3VudCgpOyArK2kpIHsKKyAgICBBZGRFbnVtVG9GaWxlRGVzY3JpcHRvcigqZmlsZV8tPmVudW1fdHlwZShpKSk7CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlXy0+ZXh0ZW5zaW9uX2NvdW50KCk7ICsraSkgeworICAgIEFkZEV4dGVuc2lvblRvRmlsZURlc2NyaXB0b3IoKmZpbGVfLT5leHRlbnNpb24oaSkpOworICB9CisgIHByaW50ZXJfLT5QcmludCgiXG4iKTsKK30KKworLy8gV2UgbmVlZCB0byBub3Qgb25seSBzZXQgYW55IG5lY2Vzc2FyeSBtZXNzYWdlX3R5cGUgZmllbGRzLCBidXQKKy8vIGFsc28gbmVlZCB0byBjYWxsIFJlZ2lzdGVyRXh0ZW5zaW9uKCkgb24gZWFjaCBtZXNzYWdlIHdlJ3JlCisvLyBleHRlbmRpbmcuCit2b2lkIEdlbmVyYXRvcjo6Rml4Rm9yZWlnbkZpZWxkc0luRXh0ZW5zaW9ucygpIGNvbnN0IHsKKyAgLy8gVG9wLWxldmVsIGV4dGVuc2lvbnMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPmV4dGVuc2lvbl9jb3VudCgpOyArK2kpIHsKKyAgICBGaXhGb3JlaWduRmllbGRzSW5FeHRlbnNpb24oKmZpbGVfLT5leHRlbnNpb24oaSkpOworICB9CisgIC8vIE5lc3RlZCBleHRlbnNpb25zLgorICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5tZXNzYWdlX3R5cGVfY291bnQoKTsgKytpKSB7CisgICAgRml4Rm9yZWlnbkZpZWxkc0luTmVzdGVkRXh0ZW5zaW9ucygqZmlsZV8tPm1lc3NhZ2VfdHlwZShpKSk7CisgIH0KKyAgcHJpbnRlcl8tPlByaW50KCJcbiIpOworfQorCit2b2lkIEdlbmVyYXRvcjo6Rml4Rm9yZWlnbkZpZWxkc0luRXh0ZW5zaW9uKAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciYgZXh0ZW5zaW9uX2ZpZWxkKSBjb25zdCB7CisgIEdPT0dMRV9DSEVDSyhleHRlbnNpb25fZmllbGQuaXNfZXh0ZW5zaW9uKCkpOworICAvLyBleHRlbnNpb25fc2NvcGUoKSB3aWxsIGJlIE5VTEwgZm9yIHRvcC1sZXZlbCBleHRlbnNpb25zLCB3aGljaCBpcworICAvLyBleGFjdGx5IHdoYXQgRml4Rm9yZWlnbkZpZWxkc0luRmllbGQoKSB3YW50cy4KKyAgRml4Rm9yZWlnbkZpZWxkc0luRmllbGQoZXh0ZW5zaW9uX2ZpZWxkLmV4dGVuc2lvbl9zY29wZSgpLCBleHRlbnNpb25fZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICJleHRlbnNpb25zX2J5X25hbWUiKTsKKworICBtYXA8c3RyaW5nLCBzdHJpbmc+IG07CisgIC8vIENvbmZ1c2luZ2x5LCBmb3IgRmllbGREZXNjcmlwdG9ycyB0aGF0IGhhcHBlbiB0byBiZSBleHRlbnNpb25zLAorICAvLyBjb250YWluaW5nX3R5cGUoKSBtZWFucyAiZXh0ZW5kZWQgdHlwZS4iCisgIC8vIE9uIHRoZSBvdGhlciBoYW5kLCBleHRlbnNpb25fc2NvcGUoKSB3aWxsIGdpdmUgdXMgd2hhdCB3ZSBub3JtYWxseQorICAvLyBtZWFuIGJ5IGNvbnRhaW5pbmdfdHlwZSgpLgorICBtWyJleHRlbmRlZF9tZXNzYWdlX2NsYXNzIl0gPSBNb2R1bGVMZXZlbE1lc3NhZ2VOYW1lKAorICAgICAgKmV4dGVuc2lvbl9maWVsZC5jb250YWluaW5nX3R5cGUoKSk7CisgIG1bImZpZWxkIl0gPSBGaWVsZFJlZmVyZW5jaW5nRXhwcmVzc2lvbihleHRlbnNpb25fZmllbGQuZXh0ZW5zaW9uX3Njb3BlKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25fZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZXh0ZW5zaW9uc19ieV9uYW1lIik7CisgIHByaW50ZXJfLT5QcmludChtLCAiJGV4dGVuZGVkX21lc3NhZ2VfY2xhc3MkLlJlZ2lzdGVyRXh0ZW5zaW9uKCRmaWVsZCQpXG4iKTsKK30KKwordm9pZCBHZW5lcmF0b3I6OkZpeEZvcmVpZ25GaWVsZHNJbk5lc3RlZEV4dGVuc2lvbnMoCisgICAgY29uc3QgRGVzY3JpcHRvciYgZGVzY3JpcHRvcikgY29uc3QgeworICAvLyBSZWN1cnNpdmVseSBmaXggdXAgZXh0ZW5zaW9ucyBpbiBhbGwgbmVzdGVkIHR5cGVzLgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3IubmVzdGVkX3R5cGVfY291bnQoKTsgKytpKSB7CisgICAgRml4Rm9yZWlnbkZpZWxkc0luTmVzdGVkRXh0ZW5zaW9ucygqZGVzY3JpcHRvci5uZXN0ZWRfdHlwZShpKSk7CisgIH0KKyAgLy8gRml4IHVwIGV4dGVuc2lvbnMgZGlyZWN0bHkgY29udGFpbmVkIHdpdGhpbiB0aGlzIHR5cGUuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvci5leHRlbnNpb25fY291bnQoKTsgKytpKSB7CisgICAgRml4Rm9yZWlnbkZpZWxkc0luRXh0ZW5zaW9uKCpkZXNjcmlwdG9yLmV4dGVuc2lvbihpKSk7CisgIH0KK30KKworLy8gUmV0dXJucyBhIFB5dGhvbiBleHByZXNzaW9uIHRoYXQgaW5zdGFudGlhdGVzIGEgUHl0aG9uIEVudW1WYWx1ZURlc2NyaXB0b3IKKy8vIG9iamVjdCBmb3IgdGhlIGdpdmVuIEMrKyBkZXNjcmlwdG9yLgordm9pZCBHZW5lcmF0b3I6OlByaW50RW51bVZhbHVlRGVzY3JpcHRvcigKKyAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yJiBkZXNjcmlwdG9yKSBjb25zdCB7CisgIC8vIFRPRE8ocm9iaW5zb24pOiBGaXggdXAgRW51bVZhbHVlRGVzY3JpcHRvciAidHlwZSIgZmllbGRzLgorICAvLyBNb3JlIGNpcmN1bGFyIHJlZmVyZW5jZXMuICA6OnNpZ2g6OgorICBzdHJpbmcgb3B0aW9uc19zdHJpbmc7CisgIGRlc2NyaXB0b3Iub3B0aW9ucygpLlNlcmlhbGl6ZVRvU3RyaW5nKCZvcHRpb25zX3N0cmluZyk7CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gbTsKKyAgbVsibmFtZSJdID0gZGVzY3JpcHRvci5uYW1lKCk7CisgIG1bImluZGV4Il0gPSBTaW1wbGVJdG9hKGRlc2NyaXB0b3IuaW5kZXgoKSk7CisgIG1bIm51bWJlciJdID0gU2ltcGxlSXRvYShkZXNjcmlwdG9yLm51bWJlcigpKTsKKyAgbVsib3B0aW9ucyJdID0gT3B0aW9uc1ZhbHVlKCJFbnVtVmFsdWVPcHRpb25zIiwgb3B0aW9uc19zdHJpbmcpOworICBwcmludGVyXy0+UHJpbnQoCisgICAgICBtLAorICAgICAgIl9kZXNjcmlwdG9yLkVudW1WYWx1ZURlc2NyaXB0b3IoXG4iCisgICAgICAiICBuYW1lPSckbmFtZSQnLCBpbmRleD0kaW5kZXgkLCBudW1iZXI9JG51bWJlciQsXG4iCisgICAgICAiICBvcHRpb25zPSRvcHRpb25zJCxcbiIKKyAgICAgICIgIHR5cGU9Tm9uZSkiKTsKK30KKworLy8gUmV0dXJucyBhIFB5dGhvbiBleHByZXNzaW9uIHRoYXQgY2FsbHMgZGVzY3JpcHRvci5fUGFyc2VPcHRpb25zIHVzaW5nCisvLyB0aGUgZ2l2ZW4gZGVzY3JpcHRvciBjbGFzcyBuYW1lIGFuZCBzZXJpYWxpemVkIG9wdGlvbnMgcHJvdG9idWYgc3RyaW5nLgorc3RyaW5nIEdlbmVyYXRvcjo6T3B0aW9uc1ZhbHVlKAorICAgIGNvbnN0IHN0cmluZyYgY2xhc3NfbmFtZSwgY29uc3Qgc3RyaW5nJiBzZXJpYWxpemVkX29wdGlvbnMpIGNvbnN0IHsKKyAgaWYgKHNlcmlhbGl6ZWRfb3B0aW9ucy5sZW5ndGgoKSA9PSAwIHx8IEdlbmVyYXRpbmdEZXNjcmlwdG9yUHJvdG8oKSkgeworICAgIHJldHVybiAiTm9uZSI7CisgIH0gZWxzZSB7CisgICAgc3RyaW5nIGZ1bGxfY2xhc3NfbmFtZSA9ICJkZXNjcmlwdG9yX3BiMi4iICsgY2xhc3NfbmFtZTsKKy8vIyMhUFkyNSAgICByZXR1cm4gIl9kZXNjcmlwdG9yLl9QYXJzZU9wdGlvbnMoIiArIGZ1bGxfY2xhc3NfbmFtZSArICIoKSwgYiciCisvLyMjIVBZMjUgICAgICAgICsgQ0VzY2FwZShzZXJpYWxpemVkX29wdGlvbnMpKyAiJykiOworICAgIHJldHVybiAiX2Rlc2NyaXB0b3IuX1BhcnNlT3B0aW9ucygiICsgZnVsbF9jbGFzc19uYW1lICsgIigpLCBfYignIiAgLy8jI1BZMjUKKyAgICAgICAgKyBDRXNjYXBlKHNlcmlhbGl6ZWRfb3B0aW9ucykrICInKSkiOyAgLy8jI1BZMjUKKyAgfQorfQorCisvLyBQcmludHMgYW4gZXhwcmVzc2lvbiBmb3IgYSBQeXRob24gRmllbGREZXNjcmlwdG9yIGZvciB8ZmllbGR8Lgordm9pZCBHZW5lcmF0b3I6OlByaW50RmllbGREZXNjcmlwdG9yKAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciYgZmllbGQsIGJvb2wgaXNfZXh0ZW5zaW9uKSBjb25zdCB7CisgIHN0cmluZyBvcHRpb25zX3N0cmluZzsKKyAgZmllbGQub3B0aW9ucygpLlNlcmlhbGl6ZVRvU3RyaW5nKCZvcHRpb25zX3N0cmluZyk7CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gbTsKKyAgbVsibmFtZSJdID0gZmllbGQubmFtZSgpOworICBtWyJmdWxsX25hbWUiXSA9IGZpZWxkLmZ1bGxfbmFtZSgpOworICBtWyJpbmRleCJdID0gU2ltcGxlSXRvYShmaWVsZC5pbmRleCgpKTsKKyAgbVsibnVtYmVyIl0gPSBTaW1wbGVJdG9hKGZpZWxkLm51bWJlcigpKTsKKyAgbVsidHlwZSJdID0gU2ltcGxlSXRvYShmaWVsZC50eXBlKCkpOworICBtWyJjcHBfdHlwZSJdID0gU2ltcGxlSXRvYShmaWVsZC5jcHBfdHlwZSgpKTsKKyAgbVsibGFiZWwiXSA9IFNpbXBsZUl0b2EoZmllbGQubGFiZWwoKSk7CisgIG1bImhhc19kZWZhdWx0X3ZhbHVlIl0gPSBmaWVsZC5oYXNfZGVmYXVsdF92YWx1ZSgpID8gIlRydWUiIDogIkZhbHNlIjsKKyAgbVsiZGVmYXVsdF92YWx1ZSJdID0gU3RyaW5naWZ5RGVmYXVsdFZhbHVlKGZpZWxkKTsKKyAgbVsiaXNfZXh0ZW5zaW9uIl0gPSBpc19leHRlbnNpb24gPyAiVHJ1ZSIgOiAiRmFsc2UiOworICBtWyJvcHRpb25zIl0gPSBPcHRpb25zVmFsdWUoIkZpZWxkT3B0aW9ucyIsIG9wdGlvbnNfc3RyaW5nKTsKKyAgLy8gV2UgYWx3YXlzIHNldCBtZXNzYWdlX3R5cGUgYW5kIGVudW1fdHlwZSB0byBOb25lIGF0IHRoaXMgcG9pbnQsIGFuZCB0aGVuCisgIC8vIHRoZXNlIGZpZWxkcyBpbiBjb3JyZWN0bHkgYWZ0ZXIgYWxsIHJlZmVyZW5jZWQgZGVzY3JpcHRvcnMgaGF2ZSBiZWVuCisgIC8vIGRlZmluZWQgYW5kL29yIGltcG9ydGVkIChzZWUgRml4Rm9yZWlnbkZpZWxkc0luRGVzY3JpcHRvcnMoKSkuCisgIGNvbnN0IGNoYXIgZmllbGRfZGVzY3JpcHRvcl9kZWNsW10gPQorICAgICJfZGVzY3JpcHRvci5GaWVsZERlc2NyaXB0b3IoXG4iCisgICAgIiAgbmFtZT0nJG5hbWUkJywgZnVsbF9uYW1lPSckZnVsbF9uYW1lJCcsIGluZGV4PSRpbmRleCQsXG4iCisgICAgIiAgbnVtYmVyPSRudW1iZXIkLCB0eXBlPSR0eXBlJCwgY3BwX3R5cGU9JGNwcF90eXBlJCwgbGFiZWw9JGxhYmVsJCxcbiIKKyAgICAiICBoYXNfZGVmYXVsdF92YWx1ZT0kaGFzX2RlZmF1bHRfdmFsdWUkLCBkZWZhdWx0X3ZhbHVlPSRkZWZhdWx0X3ZhbHVlJCxcbiIKKyAgICAiICBtZXNzYWdlX3R5cGU9Tm9uZSwgZW51bV90eXBlPU5vbmUsIGNvbnRhaW5pbmdfdHlwZT1Ob25lLFxuIgorICAgICIgIGlzX2V4dGVuc2lvbj0kaXNfZXh0ZW5zaW9uJCwgZXh0ZW5zaW9uX3Njb3BlPU5vbmUsXG4iCisgICAgIiAgb3B0aW9ucz0kb3B0aW9ucyQpIjsKKyAgcHJpbnRlcl8tPlByaW50KG0sIGZpZWxkX2Rlc2NyaXB0b3JfZGVjbCk7Cit9CisKKy8vIEhlbHBlciBmb3IgUHJpbnR7RmllbGRzLEV4dGVuc2lvbnN9SW5EZXNjcmlwdG9yKCkuCit2b2lkIEdlbmVyYXRvcjo6UHJpbnRGaWVsZERlc2NyaXB0b3JzSW5EZXNjcmlwdG9yKAorICAgIGNvbnN0IERlc2NyaXB0b3ImIG1lc3NhZ2VfZGVzY3JpcHRvciwKKyAgICBib29sIGlzX2V4dGVuc2lvbiwKKyAgICBjb25zdCBzdHJpbmcmIGxpc3RfdmFyaWFibGVfbmFtZSwKKyAgICBpbnQgKERlc2NyaXB0b3I6OipDb3VudEZuKSgpIGNvbnN0LAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogKERlc2NyaXB0b3I6OipHZXR0ZXJGbikoaW50KSBjb25zdCkgY29uc3QgeworICBwcmludGVyXy0+UHJpbnQoIiRsaXN0JD1bXG4iLCAibGlzdCIsIGxpc3RfdmFyaWFibGVfbmFtZSk7CisgIHByaW50ZXJfLT5JbmRlbnQoKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAobWVzc2FnZV9kZXNjcmlwdG9yLipDb3VudEZuKSgpOyArK2kpIHsKKyAgICBQcmludEZpZWxkRGVzY3JpcHRvcigqKG1lc3NhZ2VfZGVzY3JpcHRvci4qR2V0dGVyRm4pKGkpLAorICAgICAgICAgICAgICAgICAgICAgICAgIGlzX2V4dGVuc2lvbik7CisgICAgcHJpbnRlcl8tPlByaW50KCIsXG4iKTsKKyAgfQorICBwcmludGVyXy0+T3V0ZGVudCgpOworICBwcmludGVyXy0+UHJpbnQoIl0sXG4iKTsKK30KKworLy8gUHJpbnRzIGEgc3RhdGVtZW50IGFzc2lnbmluZyAiZmllbGRzIiB0byBhIGxpc3Qgb2YgUHl0aG9uIEZpZWxkRGVzY3JpcHRvcnMsCisvLyBvbmUgZm9yIGVhY2ggZmllbGQgcHJlc2VudCBpbiBtZXNzYWdlX2Rlc2NyaXB0b3IuCit2b2lkIEdlbmVyYXRvcjo6UHJpbnRGaWVsZHNJbkRlc2NyaXB0b3IoCisgICAgY29uc3QgRGVzY3JpcHRvciYgbWVzc2FnZV9kZXNjcmlwdG9yKSBjb25zdCB7CisgIGNvbnN0IGJvb2wgaXNfZXh0ZW5zaW9uID0gZmFsc2U7CisgIFByaW50RmllbGREZXNjcmlwdG9yc0luRGVzY3JpcHRvcigKKyAgICAgIG1lc3NhZ2VfZGVzY3JpcHRvciwgaXNfZXh0ZW5zaW9uLCAiZmllbGRzIiwKKyAgICAgICZEZXNjcmlwdG9yOjpmaWVsZF9jb3VudCwgJkRlc2NyaXB0b3I6OmZpZWxkKTsKK30KKworLy8gUHJpbnRzIGEgc3RhdGVtZW50IGFzc2lnbmluZyAiZXh0ZW5zaW9ucyIgdG8gYSBsaXN0IG9mIFB5dGhvbgorLy8gRmllbGREZXNjcmlwdG9ycywgb25lIGZvciBlYWNoIGV4dGVuc2lvbiBwcmVzZW50IGluIG1lc3NhZ2VfZGVzY3JpcHRvci4KK3ZvaWQgR2VuZXJhdG9yOjpQcmludEV4dGVuc2lvbnNJbkRlc2NyaXB0b3IoCisgICAgY29uc3QgRGVzY3JpcHRvciYgbWVzc2FnZV9kZXNjcmlwdG9yKSBjb25zdCB7CisgIGNvbnN0IGJvb2wgaXNfZXh0ZW5zaW9uID0gdHJ1ZTsKKyAgUHJpbnRGaWVsZERlc2NyaXB0b3JzSW5EZXNjcmlwdG9yKAorICAgICAgbWVzc2FnZV9kZXNjcmlwdG9yLCBpc19leHRlbnNpb24sICJleHRlbnNpb25zIiwKKyAgICAgICZEZXNjcmlwdG9yOjpleHRlbnNpb25fY291bnQsICZEZXNjcmlwdG9yOjpleHRlbnNpb24pOworfQorCitib29sIEdlbmVyYXRvcjo6R2VuZXJhdGluZ0Rlc2NyaXB0b3JQcm90bygpIGNvbnN0IHsKKyAgcmV0dXJuIGZpbGVfLT5uYW1lKCkgPT0gImdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvIjsKK30KKworLy8gUmV0dXJucyB0aGUgdW5pcXVlIFB5dGhvbiBtb2R1bGUtbGV2ZWwgaWRlbnRpZmllciBnaXZlbiB0byBhIGRlc2NyaXB0b3IuCisvLyBUaGlzIG5hbWUgaXMgbW9kdWxlLXF1YWxpZmllZCBpZmYgdGhlIGdpdmVuIGRlc2NyaXB0b3IgZGVzY3JpYmVzIGFuCisvLyBlbnRpdHkgdGhhdCBkb2Vzbid0IGNvbWUgZnJvbSB0aGUgY3VycmVudCBmaWxlLgordGVtcGxhdGUgPHR5cGVuYW1lIERlc2NyaXB0b3JUPgorc3RyaW5nIEdlbmVyYXRvcjo6TW9kdWxlTGV2ZWxEZXNjcmlwdG9yTmFtZSgKKyAgICBjb25zdCBEZXNjcmlwdG9yVCYgZGVzY3JpcHRvcikgY29uc3QgeworICAvLyBGSVhNRShyb2JpbnNvbik6CisgIC8vIFdlIGN1cnJlbnRseSBkb24ndCB3b3JyeSBhYm91dCBjb2xsaXNpb25zIHdpdGggdW5kZXJzY29yZXMgaW4gdGhlIHR5cGUKKyAgLy8gbmFtZXMsIHNvIHRoZXNlIHdvdWxkIGNvbGxpZGUgaW4gbmFzdHkgd2F5cyBpZiBmb3VuZCBpbiB0aGUgc2FtZSBmaWxlOgorICAvLyAgIE91dGVyUHJvdG8uUHJvdG9BLlByb3RvQgorICAvLyAgIE91dGVyUHJvdG9fUHJvdG9BLlByb3RvQiAgIyBVbmRlcnNjb3JlIGluc3RlYWQgb2YgcGVyaW9kLgorICAvLyBBcyB3b3VsZCB0aGVzZToKKyAgLy8gICBPdXRlclByb3RvLlByb3RvQV8uUHJvdG9CCisgIC8vICAgT3V0ZXJQcm90by5Qcm90b0EuX1Byb3RvQiAgIyBMZWFkaW5nIHZzLiB0cmFpbGluZyB1bmRlcnNjb3JlLgorICAvLyAoQ29udHJpdmVkLCBidXQgY2VydGFpbmx5IHBvc3NpYmxlKS4KKyAgLy8KKyAgLy8gVGhlIEMrKyBpbXBsZW1lbnRhdGlvbiBkb2Vzbid0IGd1YXJkIGFnYWluc3QgdGhpcyBlaXRoZXIuICBMZWF2aW5nCisgIC8vIGl0IGZvciBub3cuLi4KKyAgc3RyaW5nIG5hbWUgPSBOYW1lUHJlZml4ZWRXaXRoTmVzdGVkVHlwZXMoZGVzY3JpcHRvciwgIl8iKTsKKyAgVXBwZXJTdHJpbmcoJm5hbWUpOworICAvLyBNb2R1bGUtcHJpdmF0ZSBmb3Igbm93LiAgRWFzeSB0byBtYWtlIHB1YmxpYyBsYXRlcjsgYWxtb3N0IGltcG9zc2libGUKKyAgLy8gdG8gbWFrZSBwcml2YXRlIGxhdGVyLgorICBuYW1lID0gIl8iICsgbmFtZTsKKyAgLy8gV2Ugbm93IGhhdmUgdGhlIG5hbWUgcmVsYXRpdmUgdG8gaXRzIG93biBtb2R1bGUuICBBbHNvIHF1YWxpZnkgd2l0aAorICAvLyB0aGUgbW9kdWxlIG5hbWUgaWZmIHRoaXMgZGVzY3JpcHRvciBpcyBmcm9tIGEgZGlmZmVyZW50IC5wcm90byBmaWxlLgorICBpZiAoZGVzY3JpcHRvci5maWxlKCkgIT0gZmlsZV8pIHsKKyAgICBuYW1lID0gTW9kdWxlQWxpYXMoZGVzY3JpcHRvci5maWxlKCktPm5hbWUoKSkgKyAiLiIgKyBuYW1lOworICB9CisgIHJldHVybiBuYW1lOworfQorCisvLyBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBtZXNzYWdlIGNsYXNzIGl0c2VsZiwgbm90IHRoZSBkZXNjcmlwdG9yLgorLy8gTGlrZSBNb2R1bGVMZXZlbERlc2NyaXB0b3JOYW1lKCksIG1vZHVsZS1xdWFsaWZpZXMgdGhlIG5hbWUgaWZmCisvLyB0aGUgZ2l2ZW4gZGVzY3JpcHRvciBkZXNjcmliZXMgYW4gZW50aXR5IHRoYXQgZG9lc24ndCBjb21lIGZyb20KKy8vIHRoZSBjdXJyZW50IGZpbGUuCitzdHJpbmcgR2VuZXJhdG9yOjpNb2R1bGVMZXZlbE1lc3NhZ2VOYW1lKGNvbnN0IERlc2NyaXB0b3ImIGRlc2NyaXB0b3IpIGNvbnN0IHsKKyAgc3RyaW5nIG5hbWUgPSBOYW1lUHJlZml4ZWRXaXRoTmVzdGVkVHlwZXMoZGVzY3JpcHRvciwgIi4iKTsKKyAgaWYgKGRlc2NyaXB0b3IuZmlsZSgpICE9IGZpbGVfKSB7CisgICAgbmFtZSA9IE1vZHVsZUFsaWFzKGRlc2NyaXB0b3IuZmlsZSgpLT5uYW1lKCkpICsgIi4iICsgbmFtZTsKKyAgfQorICByZXR1cm4gbmFtZTsKK30KKworLy8gUmV0dXJucyB0aGUgdW5pcXVlIFB5dGhvbiBtb2R1bGUtbGV2ZWwgaWRlbnRpZmllciBnaXZlbiB0byBhIHNlcnZpY2UKKy8vIGRlc2NyaXB0b3IuCitzdHJpbmcgR2VuZXJhdG9yOjpNb2R1bGVMZXZlbFNlcnZpY2VEZXNjcmlwdG9yTmFtZSgKKyAgICBjb25zdCBTZXJ2aWNlRGVzY3JpcHRvciYgZGVzY3JpcHRvcikgY29uc3QgeworICBzdHJpbmcgbmFtZSA9IGRlc2NyaXB0b3IubmFtZSgpOworICBVcHBlclN0cmluZygmbmFtZSk7CisgIG5hbWUgPSAiXyIgKyBuYW1lOworICBpZiAoZGVzY3JpcHRvci5maWxlKCkgIT0gZmlsZV8pIHsKKyAgICBuYW1lID0gTW9kdWxlQWxpYXMoZGVzY3JpcHRvci5maWxlKCktPm5hbWUoKSkgKyAiLiIgKyBuYW1lOworICB9CisgIHJldHVybiBuYW1lOworfQorCisvLyBQcmludHMgc3RhbmRhcmQgY29uc3RydWN0b3IgYXJndW1lbnRzIHNlcmlhbGl6ZWRfc3RhcnQgYW5kIHNlcmlhbGl6ZWRfZW5kLgorLy8gQXJnczoKKy8vICAgZGVzY3JpcHRvcjogVGhlIGNwcCBkZXNjcmlwdG9yIHRvIGhhdmUgYSBzZXJpYWxpemVkIHJlZmVyZW5jZS4KKy8vICAgcHJvdG86IEEgcHJvdG8KKy8vIEV4YW1wbGUgcHJpbnRlciBvdXRwdXQ6CisvLyBzZXJpYWxpemVkX3N0YXJ0PTQxLAorLy8gc2VyaWFsaXplZF9lbmQ9NDMsCisvLwordGVtcGxhdGUgPHR5cGVuYW1lIERlc2NyaXB0b3JULCB0eXBlbmFtZSBEZXNjcmlwdG9yUHJvdG9UPgordm9pZCBHZW5lcmF0b3I6OlByaW50U2VyaWFsaXplZFBiSW50ZXJ2YWwoCisgICAgY29uc3QgRGVzY3JpcHRvclQmIGRlc2NyaXB0b3IsIERlc2NyaXB0b3JQcm90b1QmIHByb3RvKSBjb25zdCB7CisgIGRlc2NyaXB0b3IuQ29weVRvKCZwcm90byk7CisgIHN0cmluZyBzcDsKKyAgcHJvdG8uU2VyaWFsaXplVG9TdHJpbmcoJnNwKTsKKyAgaW50IG9mZnNldCA9IGZpbGVfZGVzY3JpcHRvcl9zZXJpYWxpemVkXy5maW5kKHNwKTsKKyAgR09PR0xFX0NIRUNLX0dFKG9mZnNldCwgMCk7CisKKyAgcHJpbnRlcl8tPlByaW50KCJzZXJpYWxpemVkX3N0YXJ0PSRzZXJpYWxpemVkX3N0YXJ0JCxcbiIKKyAgICAgICAgICAgICAgICAgICJzZXJpYWxpemVkX2VuZD0kc2VyaWFsaXplZF9lbmQkLFxuIiwKKyAgICAgICAgICAgICAgICAgICJzZXJpYWxpemVkX3N0YXJ0IiwgU2ltcGxlSXRvYShvZmZzZXQpLAorICAgICAgICAgICAgICAgICAgInNlcmlhbGl6ZWRfZW5kIiwgU2ltcGxlSXRvYShvZmZzZXQgKyBzcC5zaXplKCkpKTsKK30KKworbmFtZXNwYWNlIHsKK3ZvaWQgUHJpbnREZXNjcmlwdG9yT3B0aW9uc0ZpeGluZ0NvZGUoY29uc3Qgc3RyaW5nJiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIG9wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIC8vIFRPRE8oeGlhb2ZlbmcpOiBJIGhhdmUgYWRkZWQgYSBtZXRob2QgX1NldE9wdGlvbnMoKSB0byBEZXNjcmlwdG9yQmFzZQorICAvLyBpbiBwcm90bzIgcHl0aG9uIHJ1bnRpbWUgYnV0IGl0IGNvdWxkbid0IGJlIHVzZWQgaGVyZSBiZWNhdXNlIGFwcGVuZ2luZQorICAvLyB1c2VzIGEgc25hcHNob3QgdmVyc2lvbiBvZiB0aGUgbGlicmFyeSBpbiB3aGljaCB0aGUgbmV3IG1ldGhvZCBpcyBub3QKKyAgLy8geWV0IHByZXNlbnQuIEFmdGVyIGFwcGVuZ2luZSBoYXMgc3luY2VkIHRoZWlyIHJ1bnRpbWUgbGlicmFyeSwgdGhlIGNvZGUKKyAgLy8gYmVsb3cgc2hvdWxkIGJlIGNsZWFuZWQgdXAgdG8gdXNlIF9TZXRPcHRpb25zKCkuCisgIHByaW50ZXItPlByaW50KAorICAgICAgIiRkZXNjcmlwdG9yJC5oYXNfb3B0aW9ucyA9IFRydWVcbiIKKyAgICAgICIkZGVzY3JpcHRvciQuX29wdGlvbnMgPSAkb3B0aW9ucyRcbiIsCisgICAgICAiZGVzY3JpcHRvciIsIGRlc2NyaXB0b3IsICJvcHRpb25zIiwgb3B0aW9ucyk7Cit9Cit9ICAvLyBuYW1lc3BhY2UKKworLy8gUHJpbnRzIGV4cHJlc3Npb25zIHRoYXQgc2V0IHRoZSBvcHRpb25zIGZpZWxkIG9mIGFsbCBkZXNjcmlwdG9ycy4KK3ZvaWQgR2VuZXJhdG9yOjpGaXhBbGxEZXNjcmlwdG9yT3B0aW9ucygpIGNvbnN0IHsKKyAgLy8gUHJpbnRzIGFuIGV4cHJlc3Npb24gdGhhdCBzZXRzIHRoZSBmaWxlIGRlc2NyaXB0b3IncyBvcHRpb25zLgorICBzdHJpbmcgZmlsZV9vcHRpb25zID0gT3B0aW9uc1ZhbHVlKAorICAgICAgIkZpbGVPcHRpb25zIiwgZmlsZV8tPm9wdGlvbnMoKS5TZXJpYWxpemVBc1N0cmluZygpKTsKKyAgaWYgKGZpbGVfb3B0aW9ucyAhPSAiTm9uZSIpIHsKKyAgICBQcmludERlc2NyaXB0b3JPcHRpb25zRml4aW5nQ29kZShrRGVzY3JpcHRvcktleSwgZmlsZV9vcHRpb25zLCBwcmludGVyXyk7CisgIH0KKyAgLy8gUHJpbnRzIGV4cHJlc3Npb25zIHRoYXQgc2V0IHRoZSBvcHRpb25zIGZvciBhbGwgdG9wIGxldmVsIGVudW1zLgorICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfLT5lbnVtX3R5cGVfY291bnQoKTsgKytpKSB7CisgICAgY29uc3QgRW51bURlc2NyaXB0b3ImIGVudW1fZGVzY3JpcHRvciA9ICpmaWxlXy0+ZW51bV90eXBlKGkpOworICAgIEZpeE9wdGlvbnNGb3JFbnVtKGVudW1fZGVzY3JpcHRvcik7CisgIH0KKyAgLy8gUHJpbnRzIGV4cHJlc3Npb25zIHRoYXQgc2V0IHRoZSBvcHRpb25zIGZvciBhbGwgdG9wIGxldmVsIGV4dGVuc2lvbnMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPmV4dGVuc2lvbl9jb3VudCgpOyArK2kpIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3ImIGZpZWxkID0gKmZpbGVfLT5leHRlbnNpb24oaSk7CisgICAgRml4T3B0aW9uc0ZvckZpZWxkKGZpZWxkKTsKKyAgfQorICAvLyBQcmludHMgZXhwcmVzc2lvbnMgdGhhdCBzZXQgdGhlIG9wdGlvbnMgZm9yIGFsbCBtZXNzYWdlcywgbmVzdGVkIGVudW1zLAorICAvLyBuZXN0ZWQgZXh0ZW5zaW9ucyBhbmQgbWVzc2FnZSBmaWVsZHMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpOyArK2kpIHsKKyAgICBGaXhPcHRpb25zRm9yTWVzc2FnZSgqZmlsZV8tPm1lc3NhZ2VfdHlwZShpKSk7CisgIH0KK30KKworLy8gUHJpbnRzIGV4cHJlc3Npb25zIHRoYXQgc2V0IHRoZSBvcHRpb25zIGZvciBhbiBlbnVtIGRlc2NyaXB0b3IgYW5kIGl0cworLy8gdmFsdWUgZGVzY3JpcHRvcnMuCit2b2lkIEdlbmVyYXRvcjo6Rml4T3B0aW9uc0ZvckVudW0oY29uc3QgRW51bURlc2NyaXB0b3ImIGVudW1fZGVzY3JpcHRvcikgY29uc3QgeworICBzdHJpbmcgZGVzY3JpcHRvcl9uYW1lID0gTW9kdWxlTGV2ZWxEZXNjcmlwdG9yTmFtZShlbnVtX2Rlc2NyaXB0b3IpOworICBzdHJpbmcgZW51bV9vcHRpb25zID0gT3B0aW9uc1ZhbHVlKAorICAgICAgIkVudW1PcHRpb25zIiwgZW51bV9kZXNjcmlwdG9yLm9wdGlvbnMoKS5TZXJpYWxpemVBc1N0cmluZygpKTsKKyAgaWYgKGVudW1fb3B0aW9ucyAhPSAiTm9uZSIpIHsKKyAgICBQcmludERlc2NyaXB0b3JPcHRpb25zRml4aW5nQ29kZShkZXNjcmlwdG9yX25hbWUsIGVudW1fb3B0aW9ucywgcHJpbnRlcl8pOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZW51bV9kZXNjcmlwdG9yLnZhbHVlX2NvdW50KCk7ICsraSkgeworICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3ImIHZhbHVlX2Rlc2NyaXB0b3IgPSAqZW51bV9kZXNjcmlwdG9yLnZhbHVlKGkpOworICAgIHN0cmluZyB2YWx1ZV9vcHRpb25zID0gT3B0aW9uc1ZhbHVlKAorICAgICAgICAiRW51bVZhbHVlT3B0aW9ucyIsIHZhbHVlX2Rlc2NyaXB0b3Iub3B0aW9ucygpLlNlcmlhbGl6ZUFzU3RyaW5nKCkpOworICAgIGlmICh2YWx1ZV9vcHRpb25zICE9ICJOb25lIikgeworICAgICAgUHJpbnREZXNjcmlwdG9yT3B0aW9uc0ZpeGluZ0NvZGUoCisgICAgICAgICAgU3RyaW5nUHJpbnRmKCIlcy52YWx1ZXNfYnlfbmFtZVtcIiVzXCJdIiwgZGVzY3JpcHRvcl9uYW1lLmNfc3RyKCksCisgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlX2Rlc2NyaXB0b3IubmFtZSgpLmNfc3RyKCkpLAorICAgICAgICAgIHZhbHVlX29wdGlvbnMsIHByaW50ZXJfKTsKKyAgICB9CisgIH0KK30KKworLy8gUHJpbnRzIGV4cHJlc3Npb25zIHRoYXQgc2V0IHRoZSBvcHRpb25zIGZvciBmaWVsZCBkZXNjcmlwdG9ycyAoaW5jbHVkaW5nCisvLyBleHRlbnNpb25zKS4KK3ZvaWQgR2VuZXJhdG9yOjpGaXhPcHRpb25zRm9yRmllbGQoCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yJiBmaWVsZCkgY29uc3QgeworICBzdHJpbmcgZmllbGRfb3B0aW9ucyA9IE9wdGlvbnNWYWx1ZSgKKyAgICAgICJGaWVsZE9wdGlvbnMiLCBmaWVsZC5vcHRpb25zKCkuU2VyaWFsaXplQXNTdHJpbmcoKSk7CisgIGlmIChmaWVsZF9vcHRpb25zICE9ICJOb25lIikgeworICAgIHN0cmluZyBmaWVsZF9uYW1lOworICAgIGlmIChmaWVsZC5pc19leHRlbnNpb24oKSkgeworICAgICAgaWYgKGZpZWxkLmV4dGVuc2lvbl9zY29wZSgpID09IE5VTEwpIHsKKyAgICAgICAgLy8gVG9wIGxldmVsIGV4dGVuc2lvbnMuCisgICAgICAgIGZpZWxkX25hbWUgPSBmaWVsZC5uYW1lKCk7CisgICAgICB9IGVsc2UgeworICAgICAgICBmaWVsZF9uYW1lID0gRmllbGRSZWZlcmVuY2luZ0V4cHJlc3Npb24oCisgICAgICAgICAgICBmaWVsZC5leHRlbnNpb25fc2NvcGUoKSwgZmllbGQsICJleHRlbnNpb25zX2J5X25hbWUiKTsKKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgZmllbGRfbmFtZSA9IEZpZWxkUmVmZXJlbmNpbmdFeHByZXNzaW9uKAorICAgICAgICAgIGZpZWxkLmNvbnRhaW5pbmdfdHlwZSgpLCBmaWVsZCwgImZpZWxkc19ieV9uYW1lIik7CisgICAgfQorICAgIFByaW50RGVzY3JpcHRvck9wdGlvbnNGaXhpbmdDb2RlKGZpZWxkX25hbWUsIGZpZWxkX29wdGlvbnMsIHByaW50ZXJfKTsKKyAgfQorfQorCisvLyBQcmludHMgZXhwcmVzc2lvbnMgdGhhdCBzZXQgdGhlIG9wdGlvbnMgZm9yIGEgbWVzc2FnZSBhbmQgYWxsIGl0cyBpbm5lcgorLy8gdHlwZXMgKG5lc3RlZCBtZXNzYWdlcywgbmVzdGVkIGVudW1zLCBleHRlbnNpb25zLCBmaWVsZHMpLgordm9pZCBHZW5lcmF0b3I6OkZpeE9wdGlvbnNGb3JNZXNzYWdlKGNvbnN0IERlc2NyaXB0b3ImIGRlc2NyaXB0b3IpIGNvbnN0IHsKKyAgLy8gTmVzdGVkIG1lc3NhZ2VzLgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3IubmVzdGVkX3R5cGVfY291bnQoKTsgKytpKSB7CisgICAgRml4T3B0aW9uc0Zvck1lc3NhZ2UoKmRlc2NyaXB0b3IubmVzdGVkX3R5cGUoaSkpOworICB9CisgIC8vIEVudW1zLgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3IuZW51bV90eXBlX2NvdW50KCk7ICsraSkgeworICAgIEZpeE9wdGlvbnNGb3JFbnVtKCpkZXNjcmlwdG9yLmVudW1fdHlwZShpKSk7CisgIH0KKyAgLy8gRmllbGRzLgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3IuZmllbGRfY291bnQoKTsgKytpKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yJiBmaWVsZCA9ICpkZXNjcmlwdG9yLmZpZWxkKGkpOworICAgIEZpeE9wdGlvbnNGb3JGaWVsZChmaWVsZCk7CisgIH0KKyAgLy8gRXh0ZW5zaW9ucy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yLmV4dGVuc2lvbl9jb3VudCgpOyArK2kpIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3ImIGZpZWxkID0gKmRlc2NyaXB0b3IuZXh0ZW5zaW9uKGkpOworICAgIEZpeE9wdGlvbnNGb3JGaWVsZChmaWVsZCk7CisgIH0KKyAgLy8gTWVzc2FnZSBvcHRpb24gZm9yIHRoaXMgbWVzc2FnZS4KKyAgc3RyaW5nIG1lc3NhZ2Vfb3B0aW9ucyA9IE9wdGlvbnNWYWx1ZSgKKyAgICAgICJNZXNzYWdlT3B0aW9ucyIsIGRlc2NyaXB0b3Iub3B0aW9ucygpLlNlcmlhbGl6ZUFzU3RyaW5nKCkpOworICBpZiAobWVzc2FnZV9vcHRpb25zICE9ICJOb25lIikgeworICAgIHN0cmluZyBkZXNjcmlwdG9yX25hbWUgPSBNb2R1bGVMZXZlbERlc2NyaXB0b3JOYW1lKGRlc2NyaXB0b3IpOworICAgIFByaW50RGVzY3JpcHRvck9wdGlvbnNGaXhpbmdDb2RlKGRlc2NyaXB0b3JfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlX29wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnRlcl8pOworICB9Cit9CisKKy8vIElmIGEgZGVwZW5kZW5jeSBmb3J3YXJkcyBvdGhlciBmaWxlcyB0aHJvdWdoIHB1YmxpYyBkZXBlbmRlbmNpZXMsIGxldCdzCisvLyBjb3B5IG92ZXIgdGhlIGNvcnJlc3BvbmRpbmcgbW9kdWxlIGFsaWFzZXMuCit2b2lkIEdlbmVyYXRvcjo6Q29weVB1YmxpY0RlcGVuZGVuY2llc0FsaWFzZXMoCisgICAgY29uc3Qgc3RyaW5nJiBjb3B5X2Zyb20sIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKSBjb25zdCB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZS0+cHVibGljX2RlcGVuZGVuY3lfY291bnQoKTsgKytpKSB7CisgICAgc3RyaW5nIG1vZHVsZV9hbGlhcyA9IE1vZHVsZUFsaWFzKGZpbGUtPnB1YmxpY19kZXBlbmRlbmN5KGkpLT5uYW1lKCkpOworICAgIHByaW50ZXJfLT5QcmludCgiJGFsaWFzJCA9ICRjb3B5X2Zyb20kLiRhbGlhcyRcbiIsICJhbGlhcyIsIG1vZHVsZV9hbGlhcywKKyAgICAgICAgICAgICAgICAgICAgImNvcHlfZnJvbSIsIGNvcHlfZnJvbSk7CisgICAgQ29weVB1YmxpY0RlcGVuZGVuY2llc0FsaWFzZXMoY29weV9mcm9tLCBmaWxlLT5wdWJsaWNfZGVwZW5kZW5jeShpKSk7CisgIH0KK30KKworfSAgLy8gbmFtZXNwYWNlIHB5dGhvbgorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcHl0aG9uL3B5dGhvbl9nZW5lcmF0b3IuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcHl0aG9uL3B5dGhvbl9nZW5lcmF0b3IuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hYTBmNWZjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9weXRob24vcHl0aG9uX2dlbmVyYXRvci5oCkBAIC0wLDAgKzEsMTcyIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiByb2JpbnNvbkBnb29nbGUuY29tIChXaWxsIFJvYmluc29uKQorLy8KKy8vIEdlbmVyYXRlcyBQeXRob24gY29kZSBmb3IgYSBnaXZlbiAucHJvdG8gZmlsZS4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfUFlUSE9OX0dFTkVSQVRPUl9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX1BZVEhPTl9HRU5FUkFUT1JfSF9fCisKKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY29kZV9nZW5lcmF0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbXV0ZXguaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworY2xhc3MgRGVzY3JpcHRvcjsKK2NsYXNzIEVudW1EZXNjcmlwdG9yOworY2xhc3MgRW51bVZhbHVlRGVzY3JpcHRvcjsKK2NsYXNzIEZpZWxkRGVzY3JpcHRvcjsKK2NsYXNzIFNlcnZpY2VEZXNjcmlwdG9yOworCituYW1lc3BhY2UgaW8geyBjbGFzcyBQcmludGVyOyB9CisKK25hbWVzcGFjZSBjb21waWxlciB7CituYW1lc3BhY2UgcHl0aG9uIHsKKworLy8gQ29kZUdlbmVyYXRvciBpbXBsZW1lbnRhdGlvbiBmb3IgZ2VuZXJhdGVkIFB5dGhvbiBwcm90b2NvbCBidWZmZXIgY2xhc3Nlcy4KKy8vIElmIHlvdSBjcmVhdGUgeW91ciBvd24gcHJvdG9jb2wgY29tcGlsZXIgYmluYXJ5IGFuZCB5b3Ugd2FudCBpdCB0byBzdXBwb3J0CisvLyBQeXRob24gb3V0cHV0LCB5b3UgY2FuIGRvIHNvIGJ5IHJlZ2lzdGVyaW5nIGFuIGluc3RhbmNlIG9mIHRoaXMKKy8vIENvZGVHZW5lcmF0b3Igd2l0aCB0aGUgQ29tbWFuZExpbmVJbnRlcmZhY2UgaW4geW91ciBtYWluKCkgZnVuY3Rpb24uCitjbGFzcyBMSUJQUk9UT0NfRVhQT1JUIEdlbmVyYXRvciA6IHB1YmxpYyBDb2RlR2VuZXJhdG9yIHsKKyBwdWJsaWM6CisgIEdlbmVyYXRvcigpOworICB2aXJ0dWFsIH5HZW5lcmF0b3IoKTsKKworICAvLyBDb2RlR2VuZXJhdG9yIG1ldGhvZHMuCisgIHZpcnR1YWwgYm9vbCBHZW5lcmF0ZShjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgcGFyYW1ldGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgR2VuZXJhdG9yQ29udGV4dCogZ2VuZXJhdG9yX2NvbnRleHQsCisgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcqIGVycm9yKSBjb25zdDsKKworIHByaXZhdGU6CisgIHZvaWQgUHJpbnRJbXBvcnRzKCkgY29uc3Q7CisgIHZvaWQgUHJpbnRGaWxlRGVzY3JpcHRvcigpIGNvbnN0OworICB2b2lkIFByaW50VG9wTGV2ZWxFbnVtcygpIGNvbnN0OworICB2b2lkIFByaW50QWxsTmVzdGVkRW51bXNJbkZpbGUoKSBjb25zdDsKKyAgdm9pZCBQcmludE5lc3RlZEVudW1zKGNvbnN0IERlc2NyaXB0b3ImIGRlc2NyaXB0b3IpIGNvbnN0OworICB2b2lkIFByaW50RW51bShjb25zdCBFbnVtRGVzY3JpcHRvciYgZW51bV9kZXNjcmlwdG9yKSBjb25zdDsKKworICB2b2lkIFByaW50VG9wTGV2ZWxFeHRlbnNpb25zKCkgY29uc3Q7CisKKyAgdm9pZCBQcmludEZpZWxkRGVzY3JpcHRvcigKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciYgZmllbGQsIGJvb2wgaXNfZXh0ZW5zaW9uKSBjb25zdDsKKyAgdm9pZCBQcmludEZpZWxkRGVzY3JpcHRvcnNJbkRlc2NyaXB0b3IoCisgICAgICBjb25zdCBEZXNjcmlwdG9yJiBtZXNzYWdlX2Rlc2NyaXB0b3IsCisgICAgICBib29sIGlzX2V4dGVuc2lvbiwKKyAgICAgIGNvbnN0IHN0cmluZyYgbGlzdF92YXJpYWJsZV9uYW1lLAorICAgICAgaW50IChEZXNjcmlwdG9yOjoqQ291bnRGbikoKSBjb25zdCwKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogKERlc2NyaXB0b3I6OipHZXR0ZXJGbikoaW50KSBjb25zdCkgY29uc3Q7CisgIHZvaWQgUHJpbnRGaWVsZHNJbkRlc2NyaXB0b3IoY29uc3QgRGVzY3JpcHRvciYgbWVzc2FnZV9kZXNjcmlwdG9yKSBjb25zdDsKKyAgdm9pZCBQcmludEV4dGVuc2lvbnNJbkRlc2NyaXB0b3IoY29uc3QgRGVzY3JpcHRvciYgbWVzc2FnZV9kZXNjcmlwdG9yKSBjb25zdDsKKyAgdm9pZCBQcmludE1lc3NhZ2VEZXNjcmlwdG9ycygpIGNvbnN0OworICB2b2lkIFByaW50RGVzY3JpcHRvcihjb25zdCBEZXNjcmlwdG9yJiBtZXNzYWdlX2Rlc2NyaXB0b3IpIGNvbnN0OworICB2b2lkIFByaW50TmVzdGVkRGVzY3JpcHRvcnMoY29uc3QgRGVzY3JpcHRvciYgY29udGFpbmluZ19kZXNjcmlwdG9yKSBjb25zdDsKKworICB2b2lkIFByaW50TWVzc2FnZXMoKSBjb25zdDsKKyAgdm9pZCBQcmludE1lc3NhZ2UoY29uc3QgRGVzY3JpcHRvciYgbWVzc2FnZV9kZXNjcmlwdG9yLCBjb25zdCBzdHJpbmcmIHByZWZpeCwKKyAgICAgICAgICAgICAgICAgICAgdmVjdG9yPHN0cmluZz4qIHRvX3JlZ2lzdGVyKSBjb25zdDsKKyAgdm9pZCBQcmludE5lc3RlZE1lc3NhZ2VzKGNvbnN0IERlc2NyaXB0b3ImIGNvbnRhaW5pbmdfZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgcHJlZml4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjdG9yPHN0cmluZz4qIHRvX3JlZ2lzdGVyKSBjb25zdDsKKworICB2b2lkIEZpeEZvcmVpZ25GaWVsZHNJbkRlc2NyaXB0b3JzKCkgY29uc3Q7CisgIHZvaWQgRml4Rm9yZWlnbkZpZWxkc0luRGVzY3JpcHRvcigKKyAgICAgIGNvbnN0IERlc2NyaXB0b3ImIGRlc2NyaXB0b3IsCisgICAgICBjb25zdCBEZXNjcmlwdG9yKiBjb250YWluaW5nX2Rlc2NyaXB0b3IpIGNvbnN0OworICB2b2lkIEZpeEZvcmVpZ25GaWVsZHNJbkZpZWxkKGNvbnN0IERlc2NyaXB0b3IqIGNvbnRhaW5pbmdfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3ImIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgcHl0aG9uX2RpY3RfbmFtZSkgY29uc3Q7CisgIHZvaWQgQWRkTWVzc2FnZVRvRmlsZURlc2NyaXB0b3IoY29uc3QgRGVzY3JpcHRvciYgZGVzY3JpcHRvcikgY29uc3Q7CisgIHZvaWQgQWRkRW51bVRvRmlsZURlc2NyaXB0b3IoY29uc3QgRW51bURlc2NyaXB0b3ImIGRlc2NyaXB0b3IpIGNvbnN0OworICB2b2lkIEFkZEV4dGVuc2lvblRvRmlsZURlc2NyaXB0b3IoY29uc3QgRmllbGREZXNjcmlwdG9yJiBkZXNjcmlwdG9yKSBjb25zdDsKKyAgc3RyaW5nIEZpZWxkUmVmZXJlbmNpbmdFeHByZXNzaW9uKGNvbnN0IERlc2NyaXB0b3IqIGNvbnRhaW5pbmdfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciYgZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHB5dGhvbl9kaWN0X25hbWUpIGNvbnN0OworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgRGVzY3JpcHRvclQ+CisgIHZvaWQgRml4Q29udGFpbmluZ1R5cGVJbkRlc2NyaXB0b3IoCisgICAgICBjb25zdCBEZXNjcmlwdG9yVCYgZGVzY3JpcHRvciwKKyAgICAgIGNvbnN0IERlc2NyaXB0b3IqIGNvbnRhaW5pbmdfZGVzY3JpcHRvcikgY29uc3Q7CisKKyAgdm9pZCBGaXhGb3JlaWduRmllbGRzSW5FeHRlbnNpb25zKCkgY29uc3Q7CisgIHZvaWQgRml4Rm9yZWlnbkZpZWxkc0luRXh0ZW5zaW9uKAorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yJiBleHRlbnNpb25fZmllbGQpIGNvbnN0OworICB2b2lkIEZpeEZvcmVpZ25GaWVsZHNJbk5lc3RlZEV4dGVuc2lvbnMoY29uc3QgRGVzY3JpcHRvciYgZGVzY3JpcHRvcikgY29uc3Q7CisKKyAgdm9pZCBQcmludFNlcnZpY2VzKCkgY29uc3Q7CisgIHZvaWQgUHJpbnRTZXJ2aWNlRGVzY3JpcHRvcihjb25zdCBTZXJ2aWNlRGVzY3JpcHRvciYgZGVzY3JpcHRvcikgY29uc3Q7CisgIHZvaWQgUHJpbnRTZXJ2aWNlQ2xhc3MoY29uc3QgU2VydmljZURlc2NyaXB0b3ImIGRlc2NyaXB0b3IpIGNvbnN0OworICB2b2lkIFByaW50U2VydmljZVN0dWIoY29uc3QgU2VydmljZURlc2NyaXB0b3ImIGRlc2NyaXB0b3IpIGNvbnN0OworICB2b2lkIFByaW50RGVzY3JpcHRvcktleUFuZE1vZHVsZU5hbWUoCisgICAgICBjb25zdCBTZXJ2aWNlRGVzY3JpcHRvciYgZGVzY3JpcHRvcikgY29uc3QgOworCisgIHZvaWQgUHJpbnRFbnVtVmFsdWVEZXNjcmlwdG9yKGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3ImIGRlc2NyaXB0b3IpIGNvbnN0OworICBzdHJpbmcgT3B0aW9uc1ZhbHVlKGNvbnN0IHN0cmluZyYgY2xhc3NfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHNlcmlhbGl6ZWRfb3B0aW9ucykgY29uc3Q7CisgIGJvb2wgR2VuZXJhdGluZ0Rlc2NyaXB0b3JQcm90bygpIGNvbnN0OworCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBEZXNjcmlwdG9yVD4KKyAgc3RyaW5nIE1vZHVsZUxldmVsRGVzY3JpcHRvck5hbWUoY29uc3QgRGVzY3JpcHRvclQmIGRlc2NyaXB0b3IpIGNvbnN0OworICBzdHJpbmcgTW9kdWxlTGV2ZWxNZXNzYWdlTmFtZShjb25zdCBEZXNjcmlwdG9yJiBkZXNjcmlwdG9yKSBjb25zdDsKKyAgc3RyaW5nIE1vZHVsZUxldmVsU2VydmljZURlc2NyaXB0b3JOYW1lKAorICAgICAgY29uc3QgU2VydmljZURlc2NyaXB0b3ImIGRlc2NyaXB0b3IpIGNvbnN0OworCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBEZXNjcmlwdG9yVCwgdHlwZW5hbWUgRGVzY3JpcHRvclByb3RvVD4KKyAgdm9pZCBQcmludFNlcmlhbGl6ZWRQYkludGVydmFsKAorICAgICAgY29uc3QgRGVzY3JpcHRvclQmIGRlc2NyaXB0b3IsIERlc2NyaXB0b3JQcm90b1QmIHByb3RvKSBjb25zdDsKKworICB2b2lkIEZpeEFsbERlc2NyaXB0b3JPcHRpb25zKCkgY29uc3Q7CisgIHZvaWQgRml4T3B0aW9uc0ZvckZpZWxkKGNvbnN0IEZpZWxkRGVzY3JpcHRvciYgZmllbGQpIGNvbnN0OworICB2b2lkIEZpeE9wdGlvbnNGb3JFbnVtKGNvbnN0IEVudW1EZXNjcmlwdG9yJiBkZXNjcmlwdG9yKSBjb25zdDsKKyAgdm9pZCBGaXhPcHRpb25zRm9yTWVzc2FnZShjb25zdCBEZXNjcmlwdG9yJiBkZXNjcmlwdG9yKSBjb25zdDsKKworICB2b2lkIENvcHlQdWJsaWNEZXBlbmRlbmNpZXNBbGlhc2VzKAorICAgICAgY29uc3Qgc3RyaW5nJiBjb3B5X2Zyb20sIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKSBjb25zdDsKKworICAvLyBWZXJ5IGNvYXJzZS1ncmFpbmVkIGxvY2sgdG8gZW5zdXJlIHRoYXQgR2VuZXJhdGUoKSBpcyByZWVudHJhbnQuCisgIC8vIEd1YXJkcyBmaWxlXywgcHJpbnRlcl8gYW5kIGZpbGVfZGVzY3JpcHRvcl9zZXJpYWxpemVkXy4KKyAgbXV0YWJsZSBNdXRleCBtdXRleF87CisgIG11dGFibGUgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGVfOyAgLy8gU2V0IGluIEdlbmVyYXRlKCkuICBVbmRlciBtdXRleF8uCisgIG11dGFibGUgc3RyaW5nIGZpbGVfZGVzY3JpcHRvcl9zZXJpYWxpemVkXzsKKyAgbXV0YWJsZSBpbzo6UHJpbnRlciogcHJpbnRlcl87ICAvLyBTZXQgaW4gR2VuZXJhdGUoKS4gIFVuZGVyIG11dGV4Xy4KKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoR2VuZXJhdG9yKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBweXRob24KK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX1BZVEhPTl9HRU5FUkFUT1JfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3B5dGhvbi9weXRob25fcGx1Z2luX3VuaXR0ZXN0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9weXRob24vcHl0aG9uX3BsdWdpbl91bml0dGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lODJiYmFlCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9weXRob24vcHl0aG9uX3BsdWdpbl91bml0dGVzdC5jYwpAQCAtMCwwICsxLDEyMSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vCisvLyBUT0RPKGtlbnRvbik6ICBTaGFyZSBjb2RlIHdpdGggdGhlIHZlcnNpb25zIG9mIHRoaXMgdGVzdCBpbiBvdGhlciBsYW5ndWFnZXM/CisvLyAgIEl0IHNlZW1lZCBsaWtlIHBhcmFtZXRlcml6aW5nIGl0IHdvdWxkIGFkZCBtb3JlIGNvbXBsZXhpdHkgdGhhbiBpdCBpcworLy8gICB3b3J0aC4KKworI2luY2x1ZGUgPG1lbW9yeT4KKyNpZm5kZWYgX1NIQVJFRF9QVFJfSAorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaGFyZWRfcHRyLmg+CisjZW5kaWYKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9weXRob24vcHl0aG9uX2dlbmVyYXRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jb21tYW5kX2xpbmVfaW50ZXJmYWNlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZ29vZ2xldGVzdC5oPgorI2luY2x1ZGUgPGd0ZXN0L2d0ZXN0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZmlsZS5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIHB5dGhvbiB7CituYW1lc3BhY2UgeworCitjbGFzcyBUZXN0R2VuZXJhdG9yIDogcHVibGljIENvZGVHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgVGVzdEdlbmVyYXRvcigpIHt9CisgIH5UZXN0R2VuZXJhdG9yKCkge30KKworICB2aXJ0dWFsIGJvb2wgR2VuZXJhdGUoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHBhcmFtZXRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgIEdlbmVyYXRvckNvbnRleHQqIGNvbnRleHQsCisgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcqIGVycm9yKSBjb25zdCB7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0X3BiMi5weSIsICJpbXBvcnRzIiwgY29udGV4dCk7CisgICAgVHJ5SW5zZXJ0KCJ0ZXN0X3BiMi5weSIsICJtb2R1bGVfc2NvcGUiLCBjb250ZXh0KTsKKyAgICBUcnlJbnNlcnQoInRlc3RfcGIyLnB5IiwgImNsYXNzX3Njb3BlOmZvby5CYXIiLCBjb250ZXh0KTsKKyAgICBUcnlJbnNlcnQoInRlc3RfcGIyLnB5IiwgImNsYXNzX3Njb3BlOmZvby5CYXIuQmF6IiwgY29udGV4dCk7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICB2b2lkIFRyeUluc2VydChjb25zdCBzdHJpbmcmIGZpbGVuYW1lLCBjb25zdCBzdHJpbmcmIGluc2VydGlvbl9wb2ludCwKKyAgICAgICAgICAgICAgICAgR2VuZXJhdG9yQ29udGV4dCogY29udGV4dCkgY29uc3QgeworICAgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8aW86Olplcm9Db3B5T3V0cHV0U3RyZWFtPiBvdXRwdXQoCisgICAgICAgIGNvbnRleHQtPk9wZW5Gb3JJbnNlcnQoZmlsZW5hbWUsIGluc2VydGlvbl9wb2ludCkpOworICAgIGlvOjpQcmludGVyIHByaW50ZXIob3V0cHV0LmdldCgpLCAnJCcpOworICAgIHByaW50ZXIuUHJpbnQoIi8vIGluc2VydGVkICRuYW1lJFxuIiwgIm5hbWUiLCBpbnNlcnRpb25fcG9pbnQpOworICB9Cit9OworCisvLyBUaGlzIHRlc3QgdmVyaWZpZXMgdGhhdCBhbGwgdGhlIGV4cGVjdGVkIGluc2VydGlvbiBwb2ludHMgZXhpc3QuICBJdCBkb2VzCisvLyBub3QgdmVyaWZ5IHRoYXQgdGhleSBhcmUgY29ycmVjdGx5LXBsYWNlZDsgdGhhdCB3b3VsZCByZXF1aXJlIGFjdHVhbGx5CisvLyBjb21waWxpbmcgdGhlIG91dHB1dCB3aGljaCBpcyBhIGJpdCBtb3JlIHRoYW4gSSBjYXJlIHRvIGRvIGZvciB0aGlzIHRlc3QuCitURVNUKFB5dGhvblBsdWdpblRlc3QsIFBsdWdpblRlc3QpIHsKKyAgR09PR0xFX0NIRUNLX09LKEZpbGU6OlNldENvbnRlbnRzKFRlc3RUZW1wRGlyKCkgKyAiL3Rlc3QucHJvdG8iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInBhY2thZ2UgZm9vO1xuIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibWVzc2FnZSBCYXIge1xuIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICBtZXNzYWdlIEJheiB7fVxuIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAifVxuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSkpOworCisgIGdvb2dsZTo6cHJvdG9idWY6OmNvbXBpbGVyOjpDb21tYW5kTGluZUludGVyZmFjZSBjbGk7CisgIGNsaS5TZXRJbnB1dHNBcmVQcm90b1BhdGhSZWxhdGl2ZSh0cnVlKTsKKworICBweXRob246OkdlbmVyYXRvciBweXRob25fZ2VuZXJhdG9yOworICBUZXN0R2VuZXJhdG9yIHRlc3RfZ2VuZXJhdG9yOworICBjbGkuUmVnaXN0ZXJHZW5lcmF0b3IoIi0tcHl0aG9uX291dCIsICZweXRob25fZ2VuZXJhdG9yLCAiIik7CisgIGNsaS5SZWdpc3RlckdlbmVyYXRvcigiLS10ZXN0X291dCIsICZ0ZXN0X2dlbmVyYXRvciwgIiIpOworCisgIHN0cmluZyBwcm90b19wYXRoID0gIi1JIiArIFRlc3RUZW1wRGlyKCk7CisgIHN0cmluZyBweXRob25fb3V0ID0gIi0tcHl0aG9uX291dD0iICsgVGVzdFRlbXBEaXIoKTsKKyAgc3RyaW5nIHRlc3Rfb3V0ID0gIi0tdGVzdF9vdXQ9IiArIFRlc3RUZW1wRGlyKCk7CisKKyAgY29uc3QgY2hhciogYXJndltdID0geworICAgICJwcm90b2MiLAorICAgIHByb3RvX3BhdGguY19zdHIoKSwKKyAgICBweXRob25fb3V0LmNfc3RyKCksCisgICAgdGVzdF9vdXQuY19zdHIoKSwKKyAgICAidGVzdC5wcm90byIKKyAgfTsKKworICBFWFBFQ1RfRVEoMCwgY2xpLlJ1big1LCBhcmd2KSk7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorfSAgLy8gbmFtZXNwYWNlIHB5dGhvbgorfSAgLy8gbmFtZXNwYWNlIGNvbXBpbGVyCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcnVieS9ydWJ5X2dlbmVyYXRlZF9jb2RlLnByb3RvIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9ydWJ5L3J1YnlfZ2VuZXJhdGVkX2NvZGUucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDJkODJhNgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcnVieS9ydWJ5X2dlbmVyYXRlZF9jb2RlLnByb3RvCkBAIC0wLDAgKzEsNjcgQEAKK3N5bnRheCA9ICJwcm90bzMiOworCitwYWNrYWdlIEEuQi5DOworCittZXNzYWdlIFRlc3RNZXNzYWdlIHsKKyAgaW50MzIgb3B0aW9uYWxfaW50MzIgPSAxOworICBpbnQ2NCBvcHRpb25hbF9pbnQ2NCA9IDI7CisgIHVpbnQzMiBvcHRpb25hbF91aW50MzIgPSAzOworICB1aW50NjQgb3B0aW9uYWxfdWludDY0ID0gNDsKKyAgYm9vbCBvcHRpb25hbF9ib29sID0gNTsKKyAgZG91YmxlIG9wdGlvbmFsX2RvdWJsZSA9IDY7CisgIGZsb2F0IG9wdGlvbmFsX2Zsb2F0ID0gNzsKKyAgc3RyaW5nIG9wdGlvbmFsX3N0cmluZyA9IDg7CisgIGJ5dGVzIG9wdGlvbmFsX2J5dGVzID0gOTsKKyAgVGVzdEVudW0gb3B0aW9uYWxfZW51bSA9IDEwOworICBUZXN0TWVzc2FnZSBvcHRpb25hbF9tc2cgPSAxMTsKKworICByZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDIxOworICByZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDIyOworICByZXBlYXRlZCB1aW50MzIgcmVwZWF0ZWRfdWludDMyID0gMjM7CisgIHJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSAyNDsKKyAgcmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sID0gMjU7CisgIHJlcGVhdGVkIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgPSAyNjsKKyAgcmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSAyNzsKKyAgcmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDI4OworICByZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlcyA9IDI5OworICByZXBlYXRlZCBUZXN0RW51bSByZXBlYXRlZF9lbnVtID0gMzA7CisgIHJlcGVhdGVkIFRlc3RNZXNzYWdlIHJlcGVhdGVkX21zZyA9IDMxOworCisgIG9uZW9mIG15X29uZW9mIHsKKyAgICBpbnQzMiBvbmVvZl9pbnQzMiA9IDQxOworICAgIGludDY0IG9uZW9mX2ludDY0ID0gNDI7CisgICAgdWludDMyIG9uZW9mX3VpbnQzMiA9IDQzOworICAgIHVpbnQ2NCBvbmVvZl91aW50NjQgPSA0NDsKKyAgICBib29sIG9uZW9mX2Jvb2wgPSA0NTsKKyAgICBkb3VibGUgb25lb2ZfZG91YmxlID0gNDY7CisgICAgZmxvYXQgb25lb2ZfZmxvYXQgPSA0NzsKKyAgICBzdHJpbmcgb25lb2Zfc3RyaW5nID0gNDg7CisgICAgYnl0ZXMgb25lb2ZfYnl0ZXMgPSA0OTsKKyAgICBUZXN0RW51bSBvbmVvZl9lbnVtID0gNTA7CisgICAgVGVzdE1lc3NhZ2Ugb25lb2ZfbXNnID0gNTE7CisgIH0KKworICBtYXA8aW50MzIsIHN0cmluZz4gbWFwX2ludDMyX3N0cmluZyA9IDYxOworICBtYXA8aW50NjQsIHN0cmluZz4gbWFwX2ludDY0X3N0cmluZyA9IDYyOworICBtYXA8dWludDMyLCBzdHJpbmc+IG1hcF91aW50MzJfc3RyaW5nID0gNjM7CisgIG1hcDx1aW50NjQsIHN0cmluZz4gbWFwX3VpbnQ2NF9zdHJpbmcgPSA2NDsKKyAgbWFwPGJvb2wsIHN0cmluZz4gbWFwX2Jvb2xfc3RyaW5nID0gNjU7CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gbWFwX3N0cmluZ19zdHJpbmcgPSA2NjsKKyAgbWFwPHN0cmluZywgVGVzdE1lc3NhZ2U+IG1hcF9zdHJpbmdfbXNnID0gNjc7CisgIG1hcDxzdHJpbmcsIFRlc3RFbnVtPiBtYXBfc3RyaW5nX2VudW0gPSA2ODsKKyAgbWFwPHN0cmluZywgaW50MzI+IG1hcF9zdHJpbmdfaW50MzIgPSA2OTsKKyAgbWFwPHN0cmluZywgYm9vbD4gbWFwX3N0cmluZ19ib29sID0gNzA7CisKKyAgbWVzc2FnZSBOZXN0ZWRNZXNzYWdlIHsKKyAgICBpbnQzMiBmb28gPSAxOworICB9CisKKyAgTmVzdGVkTWVzc2FnZSBuZXN0ZWRfbWVzc2FnZSA9IDgwOworfQorCitlbnVtIFRlc3RFbnVtIHsKKyAgRGVmYXVsdCA9IDA7CisgIEEgPSAxOworICBCID0gMjsKKyAgQyA9IDM7Cit9CmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3J1YnkvcnVieV9nZW5lcmF0ZWRfY29kZS5yYiBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcnVieS9ydWJ5X2dlbmVyYXRlZF9jb2RlLnJiCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ5YjIzZmIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3J1YnkvcnVieV9nZW5lcmF0ZWRfY29kZS5yYgpAQCAtMCwwICsxLDc0IEBACisjIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCisjIHNvdXJjZTogcnVieV9nZW5lcmF0ZWRfY29kZS5wcm90bworCityZXF1aXJlICdnb29nbGUvcHJvdG9idWYnCisKK0dvb2dsZTo6UHJvdG9idWY6OkRlc2NyaXB0b3JQb29sLmdlbmVyYXRlZF9wb29sLmJ1aWxkIGRvCisgIGFkZF9tZXNzYWdlICJBLkIuQy5UZXN0TWVzc2FnZSIgZG8KKyAgICBvcHRpb25hbCA6b3B0aW9uYWxfaW50MzIsIDppbnQzMiwgMQorICAgIG9wdGlvbmFsIDpvcHRpb25hbF9pbnQ2NCwgOmludDY0LCAyCisgICAgb3B0aW9uYWwgOm9wdGlvbmFsX3VpbnQzMiwgOnVpbnQzMiwgMworICAgIG9wdGlvbmFsIDpvcHRpb25hbF91aW50NjQsIDp1aW50NjQsIDQKKyAgICBvcHRpb25hbCA6b3B0aW9uYWxfYm9vbCwgOmJvb2wsIDUKKyAgICBvcHRpb25hbCA6b3B0aW9uYWxfZG91YmxlLCA6ZG91YmxlLCA2CisgICAgb3B0aW9uYWwgOm9wdGlvbmFsX2Zsb2F0LCA6ZmxvYXQsIDcKKyAgICBvcHRpb25hbCA6b3B0aW9uYWxfc3RyaW5nLCA6c3RyaW5nLCA4CisgICAgb3B0aW9uYWwgOm9wdGlvbmFsX2J5dGVzLCA6Ynl0ZXMsIDkKKyAgICBvcHRpb25hbCA6b3B0aW9uYWxfZW51bSwgOmVudW0sIDEwLCAiQS5CLkMuVGVzdEVudW0iCisgICAgb3B0aW9uYWwgOm9wdGlvbmFsX21zZywgOm1lc3NhZ2UsIDExLCAiQS5CLkMuVGVzdE1lc3NhZ2UiCisgICAgcmVwZWF0ZWQgOnJlcGVhdGVkX2ludDMyLCA6aW50MzIsIDIxCisgICAgcmVwZWF0ZWQgOnJlcGVhdGVkX2ludDY0LCA6aW50NjQsIDIyCisgICAgcmVwZWF0ZWQgOnJlcGVhdGVkX3VpbnQzMiwgOnVpbnQzMiwgMjMKKyAgICByZXBlYXRlZCA6cmVwZWF0ZWRfdWludDY0LCA6dWludDY0LCAyNAorICAgIHJlcGVhdGVkIDpyZXBlYXRlZF9ib29sLCA6Ym9vbCwgMjUKKyAgICByZXBlYXRlZCA6cmVwZWF0ZWRfZG91YmxlLCA6ZG91YmxlLCAyNgorICAgIHJlcGVhdGVkIDpyZXBlYXRlZF9mbG9hdCwgOmZsb2F0LCAyNworICAgIHJlcGVhdGVkIDpyZXBlYXRlZF9zdHJpbmcsIDpzdHJpbmcsIDI4CisgICAgcmVwZWF0ZWQgOnJlcGVhdGVkX2J5dGVzLCA6Ynl0ZXMsIDI5CisgICAgcmVwZWF0ZWQgOnJlcGVhdGVkX2VudW0sIDplbnVtLCAzMCwgIkEuQi5DLlRlc3RFbnVtIgorICAgIHJlcGVhdGVkIDpyZXBlYXRlZF9tc2csIDptZXNzYWdlLCAzMSwgIkEuQi5DLlRlc3RNZXNzYWdlIgorICAgIG1hcCA6bWFwX2ludDMyX3N0cmluZywgOmludDMyLCA6c3RyaW5nLCA2MQorICAgIG1hcCA6bWFwX2ludDY0X3N0cmluZywgOmludDY0LCA6c3RyaW5nLCA2MgorICAgIG1hcCA6bWFwX3VpbnQzMl9zdHJpbmcsIDp1aW50MzIsIDpzdHJpbmcsIDYzCisgICAgbWFwIDptYXBfdWludDY0X3N0cmluZywgOnVpbnQ2NCwgOnN0cmluZywgNjQKKyAgICBtYXAgOm1hcF9ib29sX3N0cmluZywgOmJvb2wsIDpzdHJpbmcsIDY1CisgICAgbWFwIDptYXBfc3RyaW5nX3N0cmluZywgOnN0cmluZywgOnN0cmluZywgNjYKKyAgICBtYXAgOm1hcF9zdHJpbmdfbXNnLCA6c3RyaW5nLCA6bWVzc2FnZSwgNjcsICJBLkIuQy5UZXN0TWVzc2FnZSIKKyAgICBtYXAgOm1hcF9zdHJpbmdfZW51bSwgOnN0cmluZywgOmVudW0sIDY4LCAiQS5CLkMuVGVzdEVudW0iCisgICAgbWFwIDptYXBfc3RyaW5nX2ludDMyLCA6c3RyaW5nLCA6aW50MzIsIDY5CisgICAgbWFwIDptYXBfc3RyaW5nX2Jvb2wsIDpzdHJpbmcsIDpib29sLCA3MAorICAgIG9wdGlvbmFsIDpuZXN0ZWRfbWVzc2FnZSwgOm1lc3NhZ2UsIDgwLCAiQS5CLkMuVGVzdE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSIKKyAgICBvbmVvZiA6bXlfb25lb2YgZG8KKyAgICAgIG9wdGlvbmFsIDpvbmVvZl9pbnQzMiwgOmludDMyLCA0MQorICAgICAgb3B0aW9uYWwgOm9uZW9mX2ludDY0LCA6aW50NjQsIDQyCisgICAgICBvcHRpb25hbCA6b25lb2ZfdWludDMyLCA6dWludDMyLCA0MworICAgICAgb3B0aW9uYWwgOm9uZW9mX3VpbnQ2NCwgOnVpbnQ2NCwgNDQKKyAgICAgIG9wdGlvbmFsIDpvbmVvZl9ib29sLCA6Ym9vbCwgNDUKKyAgICAgIG9wdGlvbmFsIDpvbmVvZl9kb3VibGUsIDpkb3VibGUsIDQ2CisgICAgICBvcHRpb25hbCA6b25lb2ZfZmxvYXQsIDpmbG9hdCwgNDcKKyAgICAgIG9wdGlvbmFsIDpvbmVvZl9zdHJpbmcsIDpzdHJpbmcsIDQ4CisgICAgICBvcHRpb25hbCA6b25lb2ZfYnl0ZXMsIDpieXRlcywgNDkKKyAgICAgIG9wdGlvbmFsIDpvbmVvZl9lbnVtLCA6ZW51bSwgNTAsICJBLkIuQy5UZXN0RW51bSIKKyAgICAgIG9wdGlvbmFsIDpvbmVvZl9tc2csIDptZXNzYWdlLCA1MSwgIkEuQi5DLlRlc3RNZXNzYWdlIgorICAgIGVuZAorICBlbmQKKyAgYWRkX21lc3NhZ2UgIkEuQi5DLlRlc3RNZXNzYWdlLk5lc3RlZE1lc3NhZ2UiIGRvCisgICAgb3B0aW9uYWwgOmZvbywgOmludDMyLCAxCisgIGVuZAorICBhZGRfZW51bSAiQS5CLkMuVGVzdEVudW0iIGRvCisgICAgdmFsdWUgOkRlZmF1bHQsIDAKKyAgICB2YWx1ZSA6QSwgMQorICAgIHZhbHVlIDpCLCAyCisgICAgdmFsdWUgOkMsIDMKKyAgZW5kCitlbmQKKworbW9kdWxlIEEKKyAgbW9kdWxlIEIKKyAgICBtb2R1bGUgQworICAgICAgVGVzdE1lc3NhZ2UgPSBHb29nbGU6OlByb3RvYnVmOjpEZXNjcmlwdG9yUG9vbC5nZW5lcmF0ZWRfcG9vbC5sb29rdXAoIkEuQi5DLlRlc3RNZXNzYWdlIikubXNnY2xhc3MKKyAgICAgIFRlc3RNZXNzYWdlOjpOZXN0ZWRNZXNzYWdlID0gR29vZ2xlOjpQcm90b2J1Zjo6RGVzY3JpcHRvclBvb2wuZ2VuZXJhdGVkX3Bvb2wubG9va3VwKCJBLkIuQy5UZXN0TWVzc2FnZS5OZXN0ZWRNZXNzYWdlIikubXNnY2xhc3MKKyAgICAgIFRlc3RFbnVtID0gR29vZ2xlOjpQcm90b2J1Zjo6RGVzY3JpcHRvclBvb2wuZ2VuZXJhdGVkX3Bvb2wubG9va3VwKCJBLkIuQy5UZXN0RW51bSIpLmVudW1tb2R1bGUKKyAgICBlbmQKKyAgZW5kCitlbmQKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcnVieS9ydWJ5X2dlbmVyYXRvci5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcnVieS9ydWJ5X2dlbmVyYXRvci5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NjkyZjFiCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9ydWJ5L3J1YnlfZ2VuZXJhdG9yLmNjCkBAIC0wLDAgKzEsNDAxIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2luY2x1ZGUgPHNzdHJlYW0+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY29kZV9nZW5lcmF0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW0uaD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9ydWJ5L3J1YnlfZ2VuZXJhdG9yLmg+CisKK3VzaW5nIGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpzY29wZWRfcHRyOworCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIHJ1YnkgeworCisvLyBGb3J3YXJkIGRlY2xzLgorc3RkOjpzdHJpbmcgSW50VG9TdHJpbmcoaW50MzIgdmFsdWUpOworc3RkOjpzdHJpbmcgU3RyaXBEb3RQcm90byhjb25zdCBzdGQ6OnN0cmluZyYgcHJvdG9fZmlsZSk7CitzdGQ6OnN0cmluZyBMYWJlbEZvckZpZWxkKGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvciogZmllbGQpOworc3RkOjpzdHJpbmcgVHlwZU5hbWUoZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yKiBmaWVsZCk7Cit2b2lkIEdlbmVyYXRlTWVzc2FnZShjb25zdCBnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgZ29vZ2xlOjpwcm90b2J1Zjo6aW86OlByaW50ZXIqIHByaW50ZXIpOwordm9pZCBHZW5lcmF0ZUVudW0oY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RW51bURlc2NyaXB0b3IqIGVuLAorICAgICAgICAgICAgICAgICAgZ29vZ2xlOjpwcm90b2J1Zjo6aW86OlByaW50ZXIqIHByaW50ZXIpOwordm9pZCBHZW5lcmF0ZU1lc3NhZ2VBc3NpZ25tZW50KAorICAgIGNvbnN0IHN0ZDo6c3RyaW5nJiBwcmVmaXgsCisgICAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogbWVzc2FnZSwKKyAgICBnb29nbGU6OnByb3RvYnVmOjppbzo6UHJpbnRlciogcHJpbnRlcik7Cit2b2lkIEdlbmVyYXRlRW51bUFzc2lnbm1lbnQoCisgICAgY29uc3Qgc3RkOjpzdHJpbmcmIHByZWZpeCwKKyAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvciogZW4sCisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6aW86OlByaW50ZXIqIHByaW50ZXIpOworCitzdGQ6OnN0cmluZyBJbnRUb1N0cmluZyhpbnQzMiB2YWx1ZSkgeworICBzdGQ6Om9zdHJpbmdzdHJlYW0gb3M7CisgIG9zIDw8IHZhbHVlOworICByZXR1cm4gb3Muc3RyKCk7Cit9CisKK3N0ZDo6c3RyaW5nIFN0cmlwRG90UHJvdG8oY29uc3Qgc3RkOjpzdHJpbmcmIHByb3RvX2ZpbGUpIHsKKyAgaW50IGxhc3RpbmRleCA9IHByb3RvX2ZpbGUuZmluZF9sYXN0X29mKCIuIik7CisgIHJldHVybiBwcm90b19maWxlLnN1YnN0cigwLCBsYXN0aW5kZXgpOworfQorCitzdGQ6OnN0cmluZyBMYWJlbEZvckZpZWxkKGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgc3dpdGNoIChmaWVsZC0+bGFiZWwoKSkgeworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpMQUJFTF9PUFRJT05BTDogcmV0dXJuICJvcHRpb25hbCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkxBQkVMX1JFUVVJUkVEOiByZXR1cm4gInJlcXVpcmVkIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6TEFCRUxfUkVQRUFURUQ6IHJldHVybiAicmVwZWF0ZWQiOworICAgIGRlZmF1bHQ6IGFzc2VydChmYWxzZSk7IHJldHVybiAiIjsKKyAgfQorfQorCitzdGQ6OnN0cmluZyBUeXBlTmFtZShjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIHN3aXRjaCAoZmllbGQtPnR5cGUoKSkgeworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0lOVDMyOiByZXR1cm4gImludDMyIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9JTlQ2NDogcmV0dXJuICJpbnQ2NCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfVUlOVDMyOiByZXR1cm4gInVpbnQzMiI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfVUlOVDY0OiByZXR1cm4gInVpbnQ2NCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0lOVDMyOiByZXR1cm4gInNpbnQzMiI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0lOVDY0OiByZXR1cm4gInNpbnQ2NCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRklYRUQzMjogcmV0dXJuICJmaXhlZDMyIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9GSVhFRDY0OiByZXR1cm4gImZpeGVkNjQiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NGSVhFRDMyOiByZXR1cm4gInNmaXhlZDMyIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TRklYRUQ2NDogcmV0dXJuICJzZml4ZWQ2NCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRE9VQkxFOiByZXR1cm4gImRvdWJsZSI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRkxPQVQ6IHJldHVybiAiZmxvYXQiOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0JPT0w6IHJldHVybiAiYm9vbCI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRU5VTTogcmV0dXJuICJlbnVtIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TVFJJTkc6IHJldHVybiAic3RyaW5nIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9CWVRFUzogcmV0dXJuICJieXRlcyI7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfTUVTU0FHRTogcmV0dXJuICJtZXNzYWdlIjsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9HUk9VUDogcmV0dXJuICJncm91cCI7CisgICAgZGVmYXVsdDogYXNzZXJ0KGZhbHNlKTsgcmV0dXJuICIiOworICB9Cit9CisKK3ZvaWQgR2VuZXJhdGVGaWVsZChjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgIGdvb2dsZTo6cHJvdG9idWY6OmlvOjpQcmludGVyKiBwcmludGVyKSB7CisKKyAgaWYgKGZpZWxkLT5pc19tYXAoKSkgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvcioga2V5X2ZpZWxkID0KKyAgICAgICAgZmllbGQtPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU51bWJlcigxKTsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHZhbHVlX2ZpZWxkID0KKyAgICAgICAgZmllbGQtPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU51bWJlcigyKTsKKworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIm1hcCA6JG5hbWUkLCA6JGtleV90eXBlJCwgOiR2YWx1ZV90eXBlJCwgJG51bWJlciQiLAorICAgICAgIm5hbWUiLCBmaWVsZC0+bmFtZSgpLAorICAgICAgImtleV90eXBlIiwgVHlwZU5hbWUoa2V5X2ZpZWxkKSwKKyAgICAgICJ2YWx1ZV90eXBlIiwgVHlwZU5hbWUodmFsdWVfZmllbGQpLAorICAgICAgIm51bWJlciIsIEludFRvU3RyaW5nKGZpZWxkLT5udW1iZXIoKSkpOworCisgICAgaWYgKHZhbHVlX2ZpZWxkLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFKSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIiwgXCIkc3VidHlwZSRcIlxuIiwKKyAgICAgICAgInN1YnR5cGUiLCB2YWx1ZV9maWVsZC0+bWVzc2FnZV90eXBlKCktPmZ1bGxfbmFtZSgpKTsKKyAgICB9IGVsc2UgaWYgKHZhbHVlX2ZpZWxkLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9FTlVNKSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIiwgXCIkc3VidHlwZSRcIlxuIiwKKyAgICAgICAgInN1YnR5cGUiLCB2YWx1ZV9maWVsZC0+ZW51bV90eXBlKCktPmZ1bGxfbmFtZSgpKTsKKyAgICB9IGVsc2UgeworICAgICAgcHJpbnRlci0+UHJpbnQoIlxuIik7CisgICAgfQorICB9IGVsc2UgeworCisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAiJGxhYmVsJCA6JG5hbWUkLCAiLAorICAgICAgImxhYmVsIiwgTGFiZWxGb3JGaWVsZChmaWVsZCksCisgICAgICAibmFtZSIsIGZpZWxkLT5uYW1lKCkpOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgIjokdHlwZSQsICRudW1iZXIkIiwKKyAgICAgICJ0eXBlIiwgVHlwZU5hbWUoZmllbGQpLAorICAgICAgIm51bWJlciIsIEludFRvU3RyaW5nKGZpZWxkLT5udW1iZXIoKSkpOworCisgICAgaWYgKGZpZWxkLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFKSB7CisgICAgICBwcmludGVyLT5QcmludCgKKyAgICAgICAgIiwgXCIkc3VidHlwZSRcIlxuIiwKKyAgICAgICAic3VidHlwZSIsIGZpZWxkLT5tZXNzYWdlX3R5cGUoKS0+ZnVsbF9uYW1lKCkpOworICAgIH0gZWxzZSBpZiAoZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0VOVU0pIHsKKyAgICAgIHByaW50ZXItPlByaW50KAorICAgICAgICAiLCBcIiRzdWJ0eXBlJFwiXG4iLAorICAgICAgICAic3VidHlwZSIsIGZpZWxkLT5lbnVtX3R5cGUoKS0+ZnVsbF9uYW1lKCkpOworICAgIH0gZWxzZSB7CisgICAgICBwcmludGVyLT5QcmludCgiXG4iKTsKKyAgICB9CisgIH0KK30KKwordm9pZCBHZW5lcmF0ZU9uZW9mKGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6Ok9uZW9mRGVzY3JpcHRvciogb25lb2YsCisgICAgICAgICAgICAgICAgICAgZ29vZ2xlOjpwcm90b2J1Zjo6aW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgICAib25lb2YgOiRuYW1lJCBkb1xuIiwKKyAgICAgICJuYW1lIiwgb25lb2YtPm5hbWUoKSk7CisgIHByaW50ZXItPkluZGVudCgpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgb25lb2YtPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBvbmVvZi0+ZmllbGQoaSk7CisgICAgR2VuZXJhdGVGaWVsZChmaWVsZCwgcHJpbnRlcik7CisgIH0KKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KCJlbmRcbiIpOworfQorCit2b2lkIEdlbmVyYXRlTWVzc2FnZShjb25zdCBnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgZ29vZ2xlOjpwcm90b2J1Zjo6aW86OlByaW50ZXIqIHByaW50ZXIpIHsKKworICAvLyBEb24ndCBnZW5lcmF0ZSBNYXBFbnRyeSBtZXNzYWdlcyAtLSB3ZSB1c2UgdGhlIFJ1YnkgZXh0ZW5zaW9uJ3MgbmF0aXZlCisgIC8vIHN1cHBvcnQgZm9yIG1hcCBmaWVsZHMgaW5zdGVhZC4KKyAgaWYgKG1lc3NhZ2UtPm9wdGlvbnMoKS5tYXBfZW50cnkoKSkgeworICAgIHJldHVybjsKKyAgfQorCisgIHByaW50ZXItPlByaW50KAorICAgICJhZGRfbWVzc2FnZSBcIiRuYW1lJFwiIGRvXG4iLAorICAgICJuYW1lIiwgbWVzc2FnZS0+ZnVsbF9uYW1lKCkpOworICBwcmludGVyLT5JbmRlbnQoKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IG1lc3NhZ2UtPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBtZXNzYWdlLT5maWVsZChpKTsKKyAgICBpZiAoIWZpZWxkLT5jb250YWluaW5nX29uZW9mKCkpIHsKKyAgICAgIEdlbmVyYXRlRmllbGQoZmllbGQsIHByaW50ZXIpOworICAgIH0KKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZS0+b25lb2ZfZGVjbF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBPbmVvZkRlc2NyaXB0b3IqIG9uZW9mID0gbWVzc2FnZS0+b25lb2ZfZGVjbChpKTsKKyAgICBHZW5lcmF0ZU9uZW9mKG9uZW9mLCBwcmludGVyKTsKKyAgfQorCisgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgcHJpbnRlci0+UHJpbnQoImVuZFxuIik7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZXNzYWdlLT5uZXN0ZWRfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBHZW5lcmF0ZU1lc3NhZ2UobWVzc2FnZS0+bmVzdGVkX3R5cGUoaSksIHByaW50ZXIpOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZS0+ZW51bV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIEdlbmVyYXRlRW51bShtZXNzYWdlLT5lbnVtX3R5cGUoaSksIHByaW50ZXIpOworICB9Cit9CisKK3ZvaWQgR2VuZXJhdGVFbnVtKGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yKiBlbiwKKyAgICAgICAgICAgICAgICAgIGdvb2dsZTo6cHJvdG9idWY6OmlvOjpQcmludGVyKiBwcmludGVyKSB7CisgIHByaW50ZXItPlByaW50KAorICAgICJhZGRfZW51bSBcIiRuYW1lJFwiIGRvXG4iLAorICAgICJuYW1lIiwgZW4tPmZ1bGxfbmFtZSgpKTsKKyAgcHJpbnRlci0+SW5kZW50KCk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBlbi0+dmFsdWVfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogdmFsdWUgPSBlbi0+dmFsdWUoaSk7CisgICAgcHJpbnRlci0+UHJpbnQoCisgICAgICAidmFsdWUgOiRuYW1lJCwgJG51bWJlciRcbiIsCisgICAgICAibmFtZSIsIHZhbHVlLT5uYW1lKCksCisgICAgICAibnVtYmVyIiwgSW50VG9TdHJpbmcodmFsdWUtPm51bWJlcigpKSk7CisgIH0KKworICBwcmludGVyLT5PdXRkZW50KCk7CisgIHByaW50ZXItPlByaW50KAorICAgICJlbmRcbiIpOworfQorCisvLyBNb2R1bGUgbmFtZXMsIGNsYXNzIG5hbWVzLCBhbmQgZW51bSB2YWx1ZSBuYW1lcyBuZWVkIHRvIGJlIFJ1YnkgY29uc3RhbnRzLAorLy8gd2hpY2ggbXVzdCBzdGFydCB3aXRoIGEgY2FwaXRhbCBsZXR0ZXIuCitzdGQ6OnN0cmluZyBSdWJpZnlDb25zdGFudChjb25zdCBzdGQ6OnN0cmluZyYgbmFtZSkgeworICBzdGQ6OnN0cmluZyByZXQgPSBuYW1lOworICBpZiAoIXJldC5lbXB0eSgpKSB7CisgICAgaWYgKHJldFswXSA+PSAnYScgJiYgcmV0WzBdIDw9ICd6JykgeworICAgICAgLy8gSWYgaXQgc3RhcnRzIHdpdGggYSBsb3dlcmNhc2UgbGV0dGVyLCBjYXBpdGFsaXplIGl0LgorICAgICAgcmV0WzBdID0gcmV0WzBdIC0gJ2EnICsgJ0EnOworICAgIH0gZWxzZSBpZiAocmV0WzBdIDwgJ0EnIHx8IHJldFswXSA+ICdaJykgeworICAgICAgLy8gT3RoZXJ3aXNlIChlLmcuIGlmIGl0IGJlZ2lucyB3aXRoIGFuIHVuZGVyc2NvcmUpLCB3ZSBuZWVkIHRvIGNvbWUgdXAKKyAgICAgIC8vIHdpdGggc29tZSBwcmVmaXggdGhhdCBzdGFydHMgd2l0aCBhIGNhcGl0YWwgbGV0dGVyLiBXZSBjb3VsZCBiZSBzbWFydGVyCisgICAgICAvLyBoZXJlLCBlLmcuIHRyeSB0byBzdHJpcCBsZWFkaW5nIHVuZGVyc2NvcmVzLCBidXQgdGhpcyBtYXkgY2F1c2Ugb3RoZXIKKyAgICAgIC8vIHByb2JsZW1zIGlmIHRoZSB1c2VyIHJlYWxseSBpbnRlbmRlZCB0aGUgbmFtZS4gU28gbGV0J3MganVzdCBwcmVwZW5kIGEKKyAgICAgIC8vIHdlbGwta25vd24gc3VmZml4LgorICAgICAgcmV0ID0gIlBCXyIgKyByZXQ7CisgICAgfQorICB9CisgIHJldHVybiByZXQ7Cit9CisKK3ZvaWQgR2VuZXJhdGVNZXNzYWdlQXNzaWdubWVudCgKKyAgICBjb25zdCBzdGQ6OnN0cmluZyYgcHJlZml4LAorICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIG1lc3NhZ2UsCisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6aW86OlByaW50ZXIqIHByaW50ZXIpIHsKKworICAvLyBEb24ndCBnZW5lcmF0ZSBNYXBFbnRyeSBtZXNzYWdlcyAtLSB3ZSB1c2UgdGhlIFJ1YnkgZXh0ZW5zaW9uJ3MgbmF0aXZlCisgIC8vIHN1cHBvcnQgZm9yIG1hcCBmaWVsZHMgaW5zdGVhZC4KKyAgaWYgKG1lc3NhZ2UtPm9wdGlvbnMoKS5tYXBfZW50cnkoKSkgeworICAgIHJldHVybjsKKyAgfQorCisgIHByaW50ZXItPlByaW50KAorICAgICIkcHJlZml4JCRuYW1lJCA9ICIsCisgICAgInByZWZpeCIsIHByZWZpeCwKKyAgICAibmFtZSIsIFJ1YmlmeUNvbnN0YW50KG1lc3NhZ2UtPm5hbWUoKSkpOworICBwcmludGVyLT5QcmludCgKKyAgICAiR29vZ2xlOjpQcm90b2J1Zjo6RGVzY3JpcHRvclBvb2wuZ2VuZXJhdGVkX3Bvb2wuIgorICAgICJsb29rdXAoXCIkZnVsbF9uYW1lJFwiKS5tc2djbGFzc1xuIiwKKyAgICAiZnVsbF9uYW1lIiwgbWVzc2FnZS0+ZnVsbF9uYW1lKCkpOworCisgIHN0ZDo6c3RyaW5nIG5lc3RlZF9wcmVmaXggPSBwcmVmaXggKyBtZXNzYWdlLT5uYW1lKCkgKyAiOjoiOworICBmb3IgKGludCBpID0gMDsgaSA8IG1lc3NhZ2UtPm5lc3RlZF90eXBlX2NvdW50KCk7IGkrKykgeworICAgIEdlbmVyYXRlTWVzc2FnZUFzc2lnbm1lbnQobmVzdGVkX3ByZWZpeCwgbWVzc2FnZS0+bmVzdGVkX3R5cGUoaSksIHByaW50ZXIpOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZS0+ZW51bV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIEdlbmVyYXRlRW51bUFzc2lnbm1lbnQobmVzdGVkX3ByZWZpeCwgbWVzc2FnZS0+ZW51bV90eXBlKGkpLCBwcmludGVyKTsKKyAgfQorfQorCit2b2lkIEdlbmVyYXRlRW51bUFzc2lnbm1lbnQoCisgICAgY29uc3Qgc3RkOjpzdHJpbmcmIHByZWZpeCwKKyAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvciogZW4sCisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6aW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIiRwcmVmaXgkJG5hbWUkID0gIiwKKyAgICAicHJlZml4IiwgcHJlZml4LAorICAgICJuYW1lIiwgUnViaWZ5Q29uc3RhbnQoZW4tPm5hbWUoKSkpOworICBwcmludGVyLT5QcmludCgKKyAgICAiR29vZ2xlOjpQcm90b2J1Zjo6RGVzY3JpcHRvclBvb2wuZ2VuZXJhdGVkX3Bvb2wuIgorICAgICJsb29rdXAoXCIkZnVsbF9uYW1lJFwiKS5lbnVtbW9kdWxlXG4iLAorICAgICJmdWxsX25hbWUiLCBlbi0+ZnVsbF9uYW1lKCkpOworfQorCitpbnQgR2VuZXJhdGVQYWNrYWdlTW9kdWxlcygKKyAgICBzdGQ6OnN0cmluZyBwYWNrYWdlX25hbWUsCisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6aW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgaW50IGxldmVscyA9IDA7CisgIHdoaWxlICghcGFja2FnZV9uYW1lLmVtcHR5KCkpIHsKKyAgICBzaXplX3QgZG90X2luZGV4ID0gcGFja2FnZV9uYW1lLmZpbmQoIi4iKTsKKyAgICBzdHJpbmcgY29tcG9uZW50OworICAgIGlmIChkb3RfaW5kZXggPT0gc3RyaW5nOjpucG9zKSB7CisgICAgICBjb21wb25lbnQgPSBwYWNrYWdlX25hbWU7CisgICAgICBwYWNrYWdlX25hbWUgPSAiIjsKKyAgICB9IGVsc2UgeworICAgICAgY29tcG9uZW50ID0gcGFja2FnZV9uYW1lLnN1YnN0cigwLCBkb3RfaW5kZXgpOworICAgICAgcGFja2FnZV9uYW1lID0gcGFja2FnZV9uYW1lLnN1YnN0cihkb3RfaW5kZXggKyAxKTsKKyAgICB9CisgICAgY29tcG9uZW50ID0gUnViaWZ5Q29uc3RhbnQoY29tcG9uZW50KTsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJtb2R1bGUgJG5hbWUkXG4iLAorICAgICAgIm5hbWUiLCBjb21wb25lbnQpOworICAgIHByaW50ZXItPkluZGVudCgpOworICAgIGxldmVscysrOworICB9CisgIHJldHVybiBsZXZlbHM7Cit9CisKK3ZvaWQgRW5kUGFja2FnZU1vZHVsZXMoCisgICAgaW50IGxldmVscywKKyAgICBnb29nbGU6OnByb3RvYnVmOjppbzo6UHJpbnRlciogcHJpbnRlcikgeworICB3aGlsZSAobGV2ZWxzID4gMCkgeworICAgIGxldmVscy0tOworICAgIHByaW50ZXItPk91dGRlbnQoKTsKKyAgICBwcmludGVyLT5QcmludCgKKyAgICAgICJlbmRcbiIpOworICB9Cit9CisKK3ZvaWQgR2VuZXJhdGVGaWxlKGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpbGVEZXNjcmlwdG9yKiBmaWxlLAorICAgICAgICAgICAgICAgICAgZ29vZ2xlOjpwcm90b2J1Zjo6aW86OlByaW50ZXIqIHByaW50ZXIpIHsKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgIiMgR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCFcbiIKKyAgICAiIyBzb3VyY2U6ICRmaWxlbmFtZSRcbiIKKyAgICAiXG4iLAorICAgICJmaWxlbmFtZSIsIGZpbGUtPm5hbWUoKSk7CisKKyAgcHJpbnRlci0+UHJpbnQoCisgICAgInJlcXVpcmUgJ2dvb2dsZS9wcm90b2J1ZidcblxuIik7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlLT5kZXBlbmRlbmN5X2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IHN0ZDo6c3RyaW5nJiBuYW1lID0gZmlsZS0+ZGVwZW5kZW5jeShpKS0+bmFtZSgpOworICAgIHByaW50ZXItPlByaW50KAorICAgICAgInJlcXVpcmUgJyRuYW1lJCdcbiIsICJuYW1lIiwgU3RyaXBEb3RQcm90byhuYW1lKSk7CisgIH0KKworICBwcmludGVyLT5QcmludCgKKyAgICAiR29vZ2xlOjpQcm90b2J1Zjo6RGVzY3JpcHRvclBvb2wuZ2VuZXJhdGVkX3Bvb2wuYnVpbGQgZG9cbiIpOworICBwcmludGVyLT5JbmRlbnQoKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlLT5tZXNzYWdlX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgR2VuZXJhdGVNZXNzYWdlKGZpbGUtPm1lc3NhZ2VfdHlwZShpKSwgcHJpbnRlcik7CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlLT5lbnVtX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgR2VuZXJhdGVFbnVtKGZpbGUtPmVudW1fdHlwZShpKSwgcHJpbnRlcik7CisgIH0KKyAgcHJpbnRlci0+T3V0ZGVudCgpOworICBwcmludGVyLT5QcmludCgKKyAgICAiZW5kXG5cbiIpOworCisgIGludCBsZXZlbHMgPSBHZW5lcmF0ZVBhY2thZ2VNb2R1bGVzKGZpbGUtPnBhY2thZ2UoKSwgcHJpbnRlcik7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZS0+bWVzc2FnZV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIEdlbmVyYXRlTWVzc2FnZUFzc2lnbm1lbnQoIiIsIGZpbGUtPm1lc3NhZ2VfdHlwZShpKSwgcHJpbnRlcik7CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlLT5lbnVtX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgR2VuZXJhdGVFbnVtQXNzaWdubWVudCgiIiwgZmlsZS0+ZW51bV90eXBlKGkpLCBwcmludGVyKTsKKyAgfQorICBFbmRQYWNrYWdlTW9kdWxlcyhsZXZlbHMsIHByaW50ZXIpOworfQorCitib29sIEdlbmVyYXRvcjo6R2VuZXJhdGUoCisgICAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUsCisgICAgY29uc3Qgc3RyaW5nJiBwYXJhbWV0ZXIsCisgICAgR2VuZXJhdG9yQ29udGV4dCogZ2VuZXJhdG9yX2NvbnRleHQsCisgICAgc3RyaW5nKiBlcnJvcikgY29uc3QgeworCisgIGlmIChmaWxlLT5zeW50YXgoKSAhPSBGaWxlRGVzY3JpcHRvcjo6U1lOVEFYX1BST1RPMykgeworICAgICplcnJvciA9CisgICAgICAgICJDYW4gb25seSBnZW5lcmF0ZSBSdWJ5IGNvZGUgZm9yIHByb3RvMyAucHJvdG8gZmlsZXMuXG4iCisgICAgICAgICJQbGVhc2UgYWRkICdzeW50YXggPSBcInByb3RvM1wiOycgdG8gdGhlIHRvcCBvZiB5b3VyIC5wcm90byBmaWxlLlxuIjsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBzdGQ6OnN0cmluZyBmaWxlbmFtZSA9CisgICAgICBTdHJpcERvdFByb3RvKGZpbGUtPm5hbWUoKSkgKyAiLnJiIjsKKyAgc2NvcGVkX3B0cjxpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0+IG91dHB1dCgKKyAgICAgIGdlbmVyYXRvcl9jb250ZXh0LT5PcGVuKGZpbGVuYW1lKSk7CisgIGlvOjpQcmludGVyIHByaW50ZXIob3V0cHV0LmdldCgpLCAnJCcpOworCisgIEdlbmVyYXRlRmlsZShmaWxlLCAmcHJpbnRlcik7CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBydWJ5Cit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9ydWJ5L3J1YnlfZ2VuZXJhdG9yLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3J1YnkvcnVieV9nZW5lcmF0b3IuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NTU1NWMzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9ydWJ5L3J1YnlfZ2VuZXJhdG9yLmgKQEAgLTAsMCArMSw1OCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX1JVQllfR0VORVJBVE9SX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ09NUElMRVJfUlVCWV9HRU5FUkFUT1JfSF9fCisKKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvY29kZV9nZW5lcmF0b3IuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKK25hbWVzcGFjZSBydWJ5IHsKKworY2xhc3MgTElCUFJPVE9DX0VYUE9SVCBHZW5lcmF0b3IKKyAgICA6IHB1YmxpYyBnb29nbGU6OnByb3RvYnVmOjpjb21waWxlcjo6Q29kZUdlbmVyYXRvciB7CisgIHZpcnR1YWwgYm9vbCBHZW5lcmF0ZSgKKyAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlLAorICAgICAgY29uc3Qgc3RyaW5nJiBwYXJhbWV0ZXIsCisgICAgICBHZW5lcmF0b3JDb250ZXh0KiBnZW5lcmF0b3JfY29udGV4dCwKKyAgICAgIHN0cmluZyogZXJyb3IpIGNvbnN0OworfTsKKworfSAgLy8gbmFtZXNwYWNlIHJ1YnkKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX1JVQllfR0VORVJBVE9SX0hfXworCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3J1YnkvcnVieV9nZW5lcmF0b3JfdW5pdHRlc3QuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3J1YnkvcnVieV9nZW5lcmF0b3JfdW5pdHRlc3QuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWIwNGNiMwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcnVieS9ydWJ5X2dlbmVyYXRvcl91bml0dGVzdC5jYwpAQCAtMCwwICsxLDEyMyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAxNCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlIDxtZW1vcnk+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcnVieS9ydWJ5X2dlbmVyYXRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jb21tYW5kX2xpbmVfaW50ZXJmYWNlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZ29vZ2xldGVzdC5oPgorI2luY2x1ZGUgPGd0ZXN0L2d0ZXN0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZmlsZS5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworbmFtZXNwYWNlIHJ1YnkgeworbmFtZXNwYWNlIHsKKworc3RyaW5nIEZpbmRSdWJ5VGVzdERpcihjb25zdCBzdHJpbmcmIGZpbGUpIHsKKyAgLy8gSW5zcGlyZWQgYnkgVGVzdFNvdXJjZURpcigpIGluIHNyYy9nb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0LmNjLgorI2lmbmRlZiBHT09HTEVfVEhJUkRfUEFSVFlfUFJPVE9CVUYKKyAgc3RyaW5nIHByZWZpeCA9ICIuIjsKKyAgd2hpbGUgKCFGaWxlOjpFeGlzdHMocHJlZml4ICsgIi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3J1YnkiICsgZmlsZSkpIHsKKyAgICBpZiAoIUZpbGU6OkV4aXN0cyhwcmVmaXgpKSB7CisgICAgICBHT09HTEVfTE9HKEZBVEFMKQorICAgICAgICAgIDw8ICJDb3VsZCBub3QgZmluZCBSdWJ5IHRlc3QgZGlyZWN0b3J5LiBQbGVhc2UgcnVuIHRlc3RzIGZyb20gIgorICAgICAgICAgICAgICJzb21ld2hlcmUgd2l0aGluIHRoZSBwcm90b2J1ZiBzb3VyY2UgcGFja2FnZS4iOworICAgIH0KKyAgICBwcmVmaXggKz0gIi8uLiI7CisgIH0KKyAgcmV0dXJuIHByZWZpeCArICIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9ydWJ5IjsKKyNlbHNlCisgIHJldHVybiAidGhpcmRfcGFydHkvcHJvdG9idWYvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9ydWJ5IjsKKyNlbmRpZiAgLy8gR09PR0xFX1RISVJEX1BBUlRZX1BST1RPQlVGCit9CisKKy8vIFRoaXMgdGVzdCBpcyBhIHNpbXBsZSBnb2xkZW4tZmlsZSB0ZXN0IG92ZXIgdGhlIG91dHB1dCBvZiB0aGUgUnVieSBjb2RlCisvLyBnZW5lcmF0b3IuIFdoZW4gd2UgbWFrZSBjaGFuZ2VzIHRvIHRoZSBSdWJ5IGV4dGVuc2lvbiBhbmQgYWx0ZXIgdGhlIFJ1YnkgY29kZQorLy8gZ2VuZXJhdG9yIHRvIHVzZSB0aG9zZSBjaGFuZ2VzLCB3ZSBzaG91bGQgKGkpIG1hbnVhbGx5IHRlc3QgdGhlIG91dHB1dCBvZiB0aGUKKy8vIGNvZGUgZ2VuZXJhdG9yIHdpdGggdGhlIGV4dGVuc2lvbiwgYW5kIChpaSkgdXBkYXRlIHRoZSBnb2xkZW4gb3V0cHV0IGFib3ZlLgorLy8gU29tZSBkYXksIHdlIG1heSBpbnRlZ3JhdGUgYnVpbGQgc3lzdGVtcyBiZXR3ZWVuIHByb3RvYyBhbmQgdGhlIGxhbmd1YWdlCisvLyBleHRlbnNpb25zIHRvIHRoZSBwb2ludCB3aGVyZSB3ZSBjYW4gZG8gdGhpcyB0ZXN0IGluIGEgbW9yZSBhdXRvbWF0ZWQgd2F5LgorCitURVNUKFJ1YnlHZW5lcmF0b3JUZXN0LCBHZW5lcmF0b3JUZXN0KSB7CisgIHN0cmluZyBydWJ5X3Rlc3RzID0gRmluZFJ1YnlUZXN0RGlyKCIvcnVieV9nZW5lcmF0ZWRfY29kZS5wcm90byIpOworCisgIGdvb2dsZTo6cHJvdG9idWY6OmNvbXBpbGVyOjpDb21tYW5kTGluZUludGVyZmFjZSBjbGk7CisgIGNsaS5TZXRJbnB1dHNBcmVQcm90b1BhdGhSZWxhdGl2ZSh0cnVlKTsKKworICBydWJ5OjpHZW5lcmF0b3IgcnVieV9nZW5lcmF0b3I7CisgIGNsaS5SZWdpc3RlckdlbmVyYXRvcigiLS1ydWJ5X291dCIsICZydWJ5X2dlbmVyYXRvciwgIiIpOworCisgIC8vIENvcHkgZ2VuZXJhdGVkX2NvZGUucHJvdG8gdG8gdGhlIHRlbXBvcmFyeSB0ZXN0IGRpcmVjdG9yeS4KKyAgc3RyaW5nIHRlc3RfaW5wdXQ7CisgIEdPT0dMRV9DSEVDS19PSyhGaWxlOjpHZXRDb250ZW50cygKKyAgICAgIHJ1YnlfdGVzdHMgKyAiL3J1YnlfZ2VuZXJhdGVkX2NvZGUucHJvdG8iLAorICAgICAgJnRlc3RfaW5wdXQsCisgICAgICB0cnVlKSk7CisgIEdPT0dMRV9DSEVDS19PSyhGaWxlOjpTZXRDb250ZW50cygKKyAgICAgIFRlc3RUZW1wRGlyKCkgKyAiL3J1YnlfZ2VuZXJhdGVkX2NvZGUucHJvdG8iLAorICAgICAgdGVzdF9pbnB1dCwKKyAgICAgIHRydWUpKTsKKworICAvLyBJbnZva2UgdGhlIHByb3RvIGNvbXBpbGVyICh3ZSB3aWxsIGJlIGluc2lkZSBUZXN0VGVtcERpcigpIGF0IHRoaXMgcG9pbnQpLgorICBzdHJpbmcgcnVieV9vdXQgPSAiLS1ydWJ5X291dD0iICsgVGVzdFRlbXBEaXIoKTsKKyAgc3RyaW5nIHByb3RvX3BhdGggPSAiLS1wcm90b19wYXRoPSIgKyBUZXN0VGVtcERpcigpOworICBjb25zdCBjaGFyKiBhcmd2W10gPSB7CisgICAgInByb3RvYyIsCisgICAgcnVieV9vdXQuY19zdHIoKSwKKyAgICBwcm90b19wYXRoLmNfc3RyKCksCisgICAgInJ1YnlfZ2VuZXJhdGVkX2NvZGUucHJvdG8iLAorICB9OworCisgIEVYUEVDVF9FUSgwLCBjbGkuUnVuKDQsIGFyZ3YpKTsKKworICAvLyBMb2FkIHRoZSBnZW5lcmF0ZWQgb3V0cHV0IGFuZCBjb21wYXJlIHRvIHRoZSBleHBlY3RlZCByZXN1bHQuCisgIHN0cmluZyBvdXRwdXQ7CisgIEdPT0dMRV9DSEVDS19PSyhGaWxlOjpHZXRDb250ZW50cygKKyAgICAgIFRlc3RUZW1wRGlyKCkgKyAiL3J1YnlfZ2VuZXJhdGVkX2NvZGUucmIiLAorICAgICAgJm91dHB1dCwKKyAgICAgIHRydWUpKTsKKyAgc3RyaW5nIGV4cGVjdGVkX291dHB1dDsKKyAgR09PR0xFX0NIRUNLX09LKEZpbGU6OkdldENvbnRlbnRzKAorICAgICAgcnVieV90ZXN0cyArICIvcnVieV9nZW5lcmF0ZWRfY29kZS5yYiIsCisgICAgICAmZXhwZWN0ZWRfb3V0cHV0LAorICAgICAgdHJ1ZSkpOworICBFWFBFQ1RfRVEoZXhwZWN0ZWRfb3V0cHV0LCBvdXRwdXQpOworfQorCit9ICAvLyBuYW1lc3BhY2UKK30gIC8vIG5hbWVzcGFjZSBydWJ5Cit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9zdWJwcm9jZXNzLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9zdWJwcm9jZXNzLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmEzMGFjMzAKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3N1YnByb2Nlc3MuY2MKQEAgLTAsMCArMSw0NjUgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvc3VicHJvY2Vzcy5oPgorCisjaW5jbHVkZSA8YWxnb3JpdGhtPgorI2luY2x1ZGUgPGlvc3RyZWFtPgorCisjaWZuZGVmIF9XSU4zMgorI2luY2x1ZGUgPGVycm5vLmg+CisjaW5jbHVkZSA8c3lzL3NlbGVjdC5oPgorI2luY2x1ZGUgPHN5cy93YWl0Lmg+CisjaW5jbHVkZSA8c2lnbmFsLmg+CisjZW5kaWYKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9sb2dnaW5nLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tZXNzYWdlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N1YnN0aXR1dGUuaD4KKworCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgY29tcGlsZXIgeworCisjaWZkZWYgX1dJTjMyCisKK3N0YXRpYyB2b2lkIENsb3NlSGFuZGxlT3JEaWUoSEFORExFIGhhbmRsZSkgeworICBpZiAoIUNsb3NlSGFuZGxlKGhhbmRsZSkpIHsKKyAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ2xvc2VIYW5kbGU6ICIKKyAgICAgICAgICAgICAgICAgICAgICA8PCBTdWJwcm9jZXNzOjpXaW4zMkVycm9yTWVzc2FnZShHZXRMYXN0RXJyb3IoKSk7CisgIH0KK30KKworU3VicHJvY2Vzczo6U3VicHJvY2VzcygpCisgICAgOiBwcm9jZXNzX3N0YXJ0X2Vycm9yXyhFUlJPUl9TVUNDRVNTKSwKKyAgICAgIGNoaWxkX2hhbmRsZV8oTlVMTCksIGNoaWxkX3N0ZGluXyhOVUxMKSwgY2hpbGRfc3Rkb3V0XyhOVUxMKSB7fQorCitTdWJwcm9jZXNzOjp+U3VicHJvY2VzcygpIHsKKyAgaWYgKGNoaWxkX3N0ZGluXyAhPSBOVUxMKSB7CisgICAgQ2xvc2VIYW5kbGVPckRpZShjaGlsZF9zdGRpbl8pOworICB9CisgIGlmIChjaGlsZF9zdGRvdXRfICE9IE5VTEwpIHsKKyAgICBDbG9zZUhhbmRsZU9yRGllKGNoaWxkX3N0ZG91dF8pOworICB9Cit9CisKK3ZvaWQgU3VicHJvY2Vzczo6U3RhcnQoY29uc3Qgc3RyaW5nJiBwcm9ncmFtLCBTZWFyY2hNb2RlIHNlYXJjaF9tb2RlKSB7CisgIC8vIENyZWF0ZSB0aGUgcGlwZXMuCisgIEhBTkRMRSBzdGRpbl9waXBlX3JlYWQ7CisgIEhBTkRMRSBzdGRpbl9waXBlX3dyaXRlOworICBIQU5ETEUgc3Rkb3V0X3BpcGVfcmVhZDsKKyAgSEFORExFIHN0ZG91dF9waXBlX3dyaXRlOworCisgIGlmICghQ3JlYXRlUGlwZSgmc3RkaW5fcGlwZV9yZWFkLCAmc3RkaW5fcGlwZV93cml0ZSwgTlVMTCwgMCkpIHsKKyAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ3JlYXRlUGlwZTogIiA8PCBXaW4zMkVycm9yTWVzc2FnZShHZXRMYXN0RXJyb3IoKSk7CisgIH0KKyAgaWYgKCFDcmVhdGVQaXBlKCZzdGRvdXRfcGlwZV9yZWFkLCAmc3Rkb3V0X3BpcGVfd3JpdGUsIE5VTEwsIDApKSB7CisgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkNyZWF0ZVBpcGU6ICIgPDwgV2luMzJFcnJvck1lc3NhZ2UoR2V0TGFzdEVycm9yKCkpOworICB9CisKKyAgLy8gTWFrZSBjaGlsZCBzaWRlIG9mIHRoZSBwaXBlcyBpbmhlcml0YWJsZS4KKyAgaWYgKCFTZXRIYW5kbGVJbmZvcm1hdGlvbihzdGRpbl9waXBlX3JlYWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX0ZMQUdfSU5IRVJJVCwgSEFORExFX0ZMQUdfSU5IRVJJVCkpIHsKKyAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiU2V0SGFuZGxlSW5mb3JtYXRpb246ICIKKyAgICAgICAgICAgICAgICAgICAgICA8PCBXaW4zMkVycm9yTWVzc2FnZShHZXRMYXN0RXJyb3IoKSk7CisgIH0KKyAgaWYgKCFTZXRIYW5kbGVJbmZvcm1hdGlvbihzdGRvdXRfcGlwZV93cml0ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfRkxBR19JTkhFUklULCBIQU5ETEVfRkxBR19JTkhFUklUKSkgeworICAgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJTZXRIYW5kbGVJbmZvcm1hdGlvbjogIgorICAgICAgICAgICAgICAgICAgICAgIDw8IFdpbjMyRXJyb3JNZXNzYWdlKEdldExhc3RFcnJvcigpKTsKKyAgfQorCisgIC8vIFNldHVwIFNUQVJUVVBJTkZPIHRvIHJlZGlyZWN0IGhhbmRsZXMuCisgIFNUQVJUVVBJTkZPQSBzdGFydHVwX2luZm87CisgIFplcm9NZW1vcnkoJnN0YXJ0dXBfaW5mbywgc2l6ZW9mKHN0YXJ0dXBfaW5mbykpOworICBzdGFydHVwX2luZm8uY2IgPSBzaXplb2Yoc3RhcnR1cF9pbmZvKTsKKyAgc3RhcnR1cF9pbmZvLmR3RmxhZ3MgPSBTVEFSVEZfVVNFU1RESEFORExFUzsKKyAgc3RhcnR1cF9pbmZvLmhTdGRJbnB1dCA9IHN0ZGluX3BpcGVfcmVhZDsKKyAgc3RhcnR1cF9pbmZvLmhTdGRPdXRwdXQgPSBzdGRvdXRfcGlwZV93cml0ZTsKKyAgc3RhcnR1cF9pbmZvLmhTdGRFcnJvciA9IEdldFN0ZEhhbmRsZShTVERfRVJST1JfSEFORExFKTsKKworICBpZiAoc3RhcnR1cF9pbmZvLmhTdGRFcnJvciA9PSBJTlZBTElEX0hBTkRMRV9WQUxVRSkgeworICAgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJHZXRTdGRIYW5kbGU6ICIKKyAgICAgICAgICAgICAgICAgICAgICA8PCBXaW4zMkVycm9yTWVzc2FnZShHZXRMYXN0RXJyb3IoKSk7CisgIH0KKworICAvLyBDcmVhdGVQcm9jZXNzKCkgbXV0YXRlcyBpdHMgc2Vjb25kIHBhcmFtZXRlci4gIFdURj8KKyAgY2hhciogbmFtZV9jb3B5ID0gc3RyZHVwKHByb2dyYW0uY19zdHIoKSk7CisKKyAgLy8gQ3JlYXRlIHRoZSBwcm9jZXNzLgorICBQUk9DRVNTX0lORk9STUFUSU9OIHByb2Nlc3NfaW5mbzsKKworICBpZiAoQ3JlYXRlUHJvY2Vzc0EoKHNlYXJjaF9tb2RlID09IFNFQVJDSF9QQVRIKSA/IE5VTEwgOiBwcm9ncmFtLmNfc3RyKCksCisgICAgICAgICAgICAgICAgICAgICAoc2VhcmNoX21vZGUgPT0gU0VBUkNIX1BBVEgpID8gbmFtZV9jb3B5IDogTlVMTCwKKyAgICAgICAgICAgICAgICAgICAgIE5VTEwsICAvLyBwcm9jZXNzIHNlY3VyaXR5IGF0dHJpYnV0ZXMKKyAgICAgICAgICAgICAgICAgICAgIE5VTEwsICAvLyB0aHJlYWQgc2VjdXJpdHkgYXR0cmlidXRlcworICAgICAgICAgICAgICAgICAgICAgVFJVRSwgIC8vIGluaGVyaXQgaGFuZGxlcz8KKyAgICAgICAgICAgICAgICAgICAgIDAsICAgICAvLyBvYnNjdXJlIGNyZWF0aW9uIGZsYWdzCisgICAgICAgICAgICAgICAgICAgICBOVUxMLCAgLy8gZW52aXJvbm1lbnQgKGluaGVyaXQgZnJvbSBwYXJlbnQpCisgICAgICAgICAgICAgICAgICAgICBOVUxMLCAgLy8gY3VycmVudCBkaXJlY3RvcnkgKGluaGVyaXQgZnJvbSBwYXJlbnQpCisgICAgICAgICAgICAgICAgICAgICAmc3RhcnR1cF9pbmZvLAorICAgICAgICAgICAgICAgICAgICAgJnByb2Nlc3NfaW5mbykpIHsKKyAgICBjaGlsZF9oYW5kbGVfID0gcHJvY2Vzc19pbmZvLmhQcm9jZXNzOworICAgIENsb3NlSGFuZGxlT3JEaWUocHJvY2Vzc19pbmZvLmhUaHJlYWQpOworICAgIGNoaWxkX3N0ZGluXyA9IHN0ZGluX3BpcGVfd3JpdGU7CisgICAgY2hpbGRfc3Rkb3V0XyA9IHN0ZG91dF9waXBlX3JlYWQ7CisgIH0gZWxzZSB7CisgICAgcHJvY2Vzc19zdGFydF9lcnJvcl8gPSBHZXRMYXN0RXJyb3IoKTsKKyAgICBDbG9zZUhhbmRsZU9yRGllKHN0ZGluX3BpcGVfd3JpdGUpOworICAgIENsb3NlSGFuZGxlT3JEaWUoc3Rkb3V0X3BpcGVfcmVhZCk7CisgIH0KKworICBDbG9zZUhhbmRsZU9yRGllKHN0ZGluX3BpcGVfcmVhZCk7CisgIENsb3NlSGFuZGxlT3JEaWUoc3Rkb3V0X3BpcGVfd3JpdGUpOworICBmcmVlKG5hbWVfY29weSk7Cit9CisKK2Jvb2wgU3VicHJvY2Vzczo6Q29tbXVuaWNhdGUoY29uc3QgTWVzc2FnZSYgaW5wdXQsIE1lc3NhZ2UqIG91dHB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nKiBlcnJvcikgeworICBpZiAocHJvY2Vzc19zdGFydF9lcnJvcl8gIT0gRVJST1JfU1VDQ0VTUykgeworICAgICplcnJvciA9IFdpbjMyRXJyb3JNZXNzYWdlKHByb2Nlc3Nfc3RhcnRfZXJyb3JfKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBHT09HTEVfQ0hFQ0soY2hpbGRfaGFuZGxlXyAhPSBOVUxMKSA8PCAiTXVzdCBjYWxsIFN0YXJ0KCkgZmlyc3QuIjsKKworICBzdHJpbmcgaW5wdXRfZGF0YSA9IGlucHV0LlNlcmlhbGl6ZUFzU3RyaW5nKCk7CisgIHN0cmluZyBvdXRwdXRfZGF0YTsKKworICBpbnQgaW5wdXRfcG9zID0gMDsKKworICB3aGlsZSAoY2hpbGRfc3Rkb3V0XyAhPSBOVUxMKSB7CisgICAgSEFORExFIGhhbmRsZXNbMl07CisgICAgaW50IGhhbmRsZV9jb3VudCA9IDA7CisKKyAgICBpZiAoY2hpbGRfc3RkaW5fICE9IE5VTEwpIHsKKyAgICAgIGhhbmRsZXNbaGFuZGxlX2NvdW50KytdID0gY2hpbGRfc3RkaW5fOworICAgIH0KKyAgICBpZiAoY2hpbGRfc3Rkb3V0XyAhPSBOVUxMKSB7CisgICAgICBoYW5kbGVzW2hhbmRsZV9jb3VudCsrXSA9IGNoaWxkX3N0ZG91dF87CisgICAgfQorCisgICAgRFdPUkQgd2FpdF9yZXN1bHQgPQorICAgICAgICBXYWl0Rm9yTXVsdGlwbGVPYmplY3RzKGhhbmRsZV9jb3VudCwgaGFuZGxlcywgRkFMU0UsIElORklOSVRFKTsKKworICAgIEhBTkRMRSBzaWduYWxlZF9oYW5kbGUgPSBOVUxMOworICAgIGlmICh3YWl0X3Jlc3VsdCA+PSBXQUlUX09CSkVDVF8wICYmCisgICAgICAgIHdhaXRfcmVzdWx0IDwgV0FJVF9PQkpFQ1RfMCArIGhhbmRsZV9jb3VudCkgeworICAgICAgc2lnbmFsZWRfaGFuZGxlID0gaGFuZGxlc1t3YWl0X3Jlc3VsdCAtIFdBSVRfT0JKRUNUXzBdOworICAgIH0gZWxzZSBpZiAod2FpdF9yZXN1bHQgPT0gV0FJVF9GQUlMRUQpIHsKKyAgICAgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJXYWl0Rm9yTXVsdGlwbGVPYmplY3RzOiAiCisgICAgICAgICAgICAgICAgICAgICAgICA8PCBXaW4zMkVycm9yTWVzc2FnZShHZXRMYXN0RXJyb3IoKSk7CisgICAgfSBlbHNlIHsKKyAgICAgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJXYWl0Rm9yTXVsdGlwbGVPYmplY3RzOiBVbmV4cGVjdGVkIHJldHVybiBjb2RlOiAiCisgICAgICAgICAgICAgICAgICAgICAgICA8PCB3YWl0X3Jlc3VsdDsKKyAgICB9CisKKyAgICBpZiAoc2lnbmFsZWRfaGFuZGxlID09IGNoaWxkX3N0ZGluXykgeworICAgICAgRFdPUkQgbjsKKyAgICAgIGlmICghV3JpdGVGaWxlKGNoaWxkX3N0ZGluXywKKyAgICAgICAgICAgICAgICAgICAgIGlucHV0X2RhdGEuZGF0YSgpICsgaW5wdXRfcG9zLAorICAgICAgICAgICAgICAgICAgICAgaW5wdXRfZGF0YS5zaXplKCkgLSBpbnB1dF9wb3MsCisgICAgICAgICAgICAgICAgICAgICAmbiwgTlVMTCkpIHsKKyAgICAgICAgLy8gQ2hpbGQgY2xvc2VkIHBpcGUuICBQcmVzdW1hYmx5IGl0IHdpbGwgcmVwb3J0IGFuIGVycm9yIGxhdGVyLgorICAgICAgICAvLyBQcmV0ZW5kIHdlJ3JlIGRvbmUgZm9yIG5vdy4KKyAgICAgICAgaW5wdXRfcG9zID0gaW5wdXRfZGF0YS5zaXplKCk7CisgICAgICB9IGVsc2UgeworICAgICAgICBpbnB1dF9wb3MgKz0gbjsKKyAgICAgIH0KKworICAgICAgaWYgKGlucHV0X3BvcyA9PSBpbnB1dF9kYXRhLnNpemUoKSkgeworICAgICAgICAvLyBXZSdyZSBkb25lIHdyaXRpbmcuICBDbG9zZS4KKyAgICAgICAgQ2xvc2VIYW5kbGVPckRpZShjaGlsZF9zdGRpbl8pOworICAgICAgICBjaGlsZF9zdGRpbl8gPSBOVUxMOworICAgICAgfQorICAgIH0gZWxzZSBpZiAoc2lnbmFsZWRfaGFuZGxlID09IGNoaWxkX3N0ZG91dF8pIHsKKyAgICAgIGNoYXIgYnVmZmVyWzQwOTZdOworICAgICAgRFdPUkQgbjsKKworICAgICAgaWYgKCFSZWFkRmlsZShjaGlsZF9zdGRvdXRfLCBidWZmZXIsIHNpemVvZihidWZmZXIpLCAmbiwgTlVMTCkpIHsKKyAgICAgICAgLy8gV2UncmUgZG9uZSByZWFkaW5nLiAgQ2xvc2UuCisgICAgICAgIENsb3NlSGFuZGxlT3JEaWUoY2hpbGRfc3Rkb3V0Xyk7CisgICAgICAgIGNoaWxkX3N0ZG91dF8gPSBOVUxMOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgb3V0cHV0X2RhdGEuYXBwZW5kKGJ1ZmZlciwgbik7CisgICAgICB9CisgICAgfQorICB9CisKKyAgaWYgKGNoaWxkX3N0ZGluXyAhPSBOVUxMKSB7CisgICAgLy8gQ2hpbGQgZGlkIG5vdCBmaW5pc2ggcmVhZGluZyBpbnB1dCBiZWZvcmUgaXQgY2xvc2VkIHRoZSBvdXRwdXQuCisgICAgLy8gUHJlc3VtYWJseSBpdCBleGl0ZWQgd2l0aCBhbiBlcnJvci4KKyAgICBDbG9zZUhhbmRsZU9yRGllKGNoaWxkX3N0ZGluXyk7CisgICAgY2hpbGRfc3RkaW5fID0gTlVMTDsKKyAgfQorCisgIERXT1JEIHdhaXRfcmVzdWx0ID0gV2FpdEZvclNpbmdsZU9iamVjdChjaGlsZF9oYW5kbGVfLCBJTkZJTklURSk7CisKKyAgaWYgKHdhaXRfcmVzdWx0ID09IFdBSVRfRkFJTEVEKSB7CisgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIldhaXRGb3JTaW5nbGVPYmplY3Q6ICIKKyAgICAgICAgICAgICAgICAgICAgICA8PCBXaW4zMkVycm9yTWVzc2FnZShHZXRMYXN0RXJyb3IoKSk7CisgIH0gZWxzZSBpZiAod2FpdF9yZXN1bHQgIT0gV0FJVF9PQkpFQ1RfMCkgeworICAgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJXYWl0Rm9yU2luZ2xlT2JqZWN0OiBVbmV4cGVjdGVkIHJldHVybiBjb2RlOiAiCisgICAgICAgICAgICAgICAgICAgICAgPDwgd2FpdF9yZXN1bHQ7CisgIH0KKworICBEV09SRCBleGl0X2NvZGU7CisgIGlmICghR2V0RXhpdENvZGVQcm9jZXNzKGNoaWxkX2hhbmRsZV8sICZleGl0X2NvZGUpKSB7CisgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkdldEV4aXRDb2RlUHJvY2VzczogIgorICAgICAgICAgICAgICAgICAgICAgIDw8IFdpbjMyRXJyb3JNZXNzYWdlKEdldExhc3RFcnJvcigpKTsKKyAgfQorCisgIENsb3NlSGFuZGxlT3JEaWUoY2hpbGRfaGFuZGxlXyk7CisgIGNoaWxkX2hhbmRsZV8gPSBOVUxMOworCisgIGlmIChleGl0X2NvZGUgIT0gMCkgeworICAgICplcnJvciA9IHN0cmluZ3M6OlN1YnN0aXR1dGUoCisgICAgICAgICJQbHVnaW4gZmFpbGVkIHdpdGggc3RhdHVzIGNvZGUgJDAuIiwgZXhpdF9jb2RlKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBpZiAoIW91dHB1dC0+UGFyc2VGcm9tU3RyaW5nKG91dHB1dF9kYXRhKSkgeworICAgICplcnJvciA9ICJQbHVnaW4gb3V0cHV0IGlzIHVucGFyc2VhYmxlOiAiICsgQ0VzY2FwZShvdXRwdXRfZGF0YSk7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK3N0cmluZyBTdWJwcm9jZXNzOjpXaW4zMkVycm9yTWVzc2FnZShEV09SRCBlcnJvcl9jb2RlKSB7CisgIGNoYXIqIG1lc3NhZ2U7CisKKyAgLy8gV1RGPworICBGb3JtYXRNZXNzYWdlKEZPUk1BVF9NRVNTQUdFX0FMTE9DQVRFX0JVRkZFUiB8CisgICAgICAgICAgICAgICAgRk9STUFUX01FU1NBR0VfRlJPTV9TWVNURU0gfAorICAgICAgICAgICAgICAgIEZPUk1BVF9NRVNTQUdFX0lHTk9SRV9JTlNFUlRTLAorICAgICAgICAgICAgICAgIE5VTEwsIGVycm9yX2NvZGUsIDAsCisgICAgICAgICAgICAgICAgKExQVFNUUikmbWVzc2FnZSwgIC8vIE5PVCBBIEJVRyEKKyAgICAgICAgICAgICAgICAwLCBOVUxMKTsKKworICBzdHJpbmcgcmVzdWx0ID0gbWVzc2FnZTsKKyAgTG9jYWxGcmVlKG1lc3NhZ2UpOworICByZXR1cm4gcmVzdWx0OworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKyNlbHNlICAvLyBfV0lOMzIKKworU3VicHJvY2Vzczo6U3VicHJvY2VzcygpCisgICAgOiBjaGlsZF9waWRfKC0xKSwgY2hpbGRfc3RkaW5fKC0xKSwgY2hpbGRfc3Rkb3V0XygtMSkge30KKworU3VicHJvY2Vzczo6flN1YnByb2Nlc3MoKSB7CisgIGlmIChjaGlsZF9zdGRpbl8gIT0gLTEpIHsKKyAgICBjbG9zZShjaGlsZF9zdGRpbl8pOworICB9CisgIGlmIChjaGlsZF9zdGRvdXRfICE9IC0xKSB7CisgICAgY2xvc2UoY2hpbGRfc3Rkb3V0Xyk7CisgIH0KK30KKwordm9pZCBTdWJwcm9jZXNzOjpTdGFydChjb25zdCBzdHJpbmcmIHByb2dyYW0sIFNlYXJjaE1vZGUgc2VhcmNoX21vZGUpIHsKKyAgLy8gTm90ZSB0aGF0IHdlIGFzc3VtZSB0aGF0IHRoZXJlIGFyZSBubyBvdGhlciB0aHJlYWRzLCB0aHVzIHdlIGRvbid0IGhhdmUgdG8KKyAgLy8gZG8gY3Jhenkgc3R1ZmYgbGlrZSB1c2luZyBzb2NrZXQgcGFpcnMgb3IgYXZvaWRpbmcgbGliYyBsb2Nrcy4KKworICAvLyBbMF0gaXMgcmVhZCBlbmQsIFsxXSBpcyB3cml0ZSBlbmQuCisgIGludCBzdGRpbl9waXBlWzJdOworICBpbnQgc3Rkb3V0X3BpcGVbMl07CisKKyAgR09PR0xFX0NIRUNLKHBpcGUoc3RkaW5fcGlwZSkgIT0gLTEpOworICBHT09HTEVfQ0hFQ0socGlwZShzdGRvdXRfcGlwZSkgIT0gLTEpOworCisgIGNoYXIqIGFyZ3ZbMl0gPSB7IHN0cmR1cChwcm9ncmFtLmNfc3RyKCkpLCBOVUxMIH07CisKKyAgY2hpbGRfcGlkXyA9IGZvcmsoKTsKKyAgaWYgKGNoaWxkX3BpZF8gPT0gLTEpIHsKKyAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiZm9yazogIiA8PCBzdHJlcnJvcihlcnJubyk7CisgIH0gZWxzZSBpZiAoY2hpbGRfcGlkXyA9PSAwKSB7CisgICAgLy8gV2UgYXJlIHRoZSBjaGlsZC4KKyAgICBkdXAyKHN0ZGluX3BpcGVbMF0sIFNURElOX0ZJTEVOTyk7CisgICAgZHVwMihzdGRvdXRfcGlwZVsxXSwgU1RET1VUX0ZJTEVOTyk7CisKKyAgICBjbG9zZShzdGRpbl9waXBlWzBdKTsKKyAgICBjbG9zZShzdGRpbl9waXBlWzFdKTsKKyAgICBjbG9zZShzdGRvdXRfcGlwZVswXSk7CisgICAgY2xvc2Uoc3Rkb3V0X3BpcGVbMV0pOworCisgICAgc3dpdGNoIChzZWFyY2hfbW9kZSkgeworICAgICAgY2FzZSBTRUFSQ0hfUEFUSDoKKyAgICAgICAgZXhlY3ZwKGFyZ3ZbMF0sIGFyZ3YpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgRVhBQ1RfTkFNRToKKyAgICAgICAgZXhlY3YoYXJndlswXSwgYXJndik7CisgICAgICAgIGJyZWFrOworICAgIH0KKworICAgIC8vIFdyaXRlIGRpcmVjdGx5IHRvIFNUREVSUl9GSUxFTk8gdG8gYXZvaWQgc3RkaW8gY29kZSBwYXRocyB0aGF0IG1heSBkbworICAgIC8vIHN0dWZmIHRoYXQgaXMgdW5zYWZlIGhlcmUuCisgICAgaW50IGlnbm9yZWQ7CisgICAgaWdub3JlZCA9IHdyaXRlKFNUREVSUl9GSUxFTk8sIGFyZ3ZbMF0sIHN0cmxlbihhcmd2WzBdKSk7CisgICAgY29uc3QgY2hhciogbWVzc2FnZSA9ICI6IHByb2dyYW0gbm90IGZvdW5kIG9yIGlzIG5vdCBleGVjdXRhYmxlXG4iOworICAgIGlnbm9yZWQgPSB3cml0ZShTVERFUlJfRklMRU5PLCBtZXNzYWdlLCBzdHJsZW4obWVzc2FnZSkpOworICAgICh2b2lkKSBpZ25vcmVkOworCisgICAgLy8gTXVzdCB1c2UgX2V4aXQoKSByYXRoZXIgdGhhbiBleGl0KCkgdG8gYXZvaWQgZmx1c2hpbmcgb3V0cHV0IGJ1ZmZlcnMKKyAgICAvLyB0aGF0IHdpbGwgYWxzbyBiZSBmbHVzaGVkIGJ5IHRoZSBwYXJlbnQuCisgICAgX2V4aXQoMSk7CisgIH0gZWxzZSB7CisgICAgZnJlZShhcmd2WzBdKTsKKworICAgIGNsb3NlKHN0ZGluX3BpcGVbMF0pOworICAgIGNsb3NlKHN0ZG91dF9waXBlWzFdKTsKKworICAgIGNoaWxkX3N0ZGluXyA9IHN0ZGluX3BpcGVbMV07CisgICAgY2hpbGRfc3Rkb3V0XyA9IHN0ZG91dF9waXBlWzBdOworICB9Cit9CisKK2Jvb2wgU3VicHJvY2Vzczo6Q29tbXVuaWNhdGUoY29uc3QgTWVzc2FnZSYgaW5wdXQsIE1lc3NhZ2UqIG91dHB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nKiBlcnJvcikgeworCisgIEdPT0dMRV9DSEVDS19ORShjaGlsZF9zdGRpbl8sIC0xKSA8PCAiTXVzdCBjYWxsIFN0YXJ0KCkgZmlyc3QuIjsKKworICAvLyBUaGUgInNpZ2hhbmRsZXJfdCIgdHlwZWRlZiBpcyBHTlUtc3BlY2lmaWMsIHNvIGRlZmluZSBvdXIgb3duLgorICB0eXBlZGVmIHZvaWQgU2lnbmFsSGFuZGxlcihpbnQpOworCisgIC8vIE1ha2Ugc3VyZSBTSUdQSVBFIGlzIGRpc2FibGVkIHNvIHRoYXQgaWYgdGhlIGNoaWxkIGRpZXMgaXQgZG9lc24ndCBraWxsIHVzLgorICBTaWduYWxIYW5kbGVyKiBvbGRfcGlwZV9oYW5kbGVyID0gc2lnbmFsKFNJR1BJUEUsIFNJR19JR04pOworCisgIHN0cmluZyBpbnB1dF9kYXRhID0gaW5wdXQuU2VyaWFsaXplQXNTdHJpbmcoKTsKKyAgc3RyaW5nIG91dHB1dF9kYXRhOworCisgIGludCBpbnB1dF9wb3MgPSAwOworICBpbnQgbWF4X2ZkID0gbWF4KGNoaWxkX3N0ZGluXywgY2hpbGRfc3Rkb3V0Xyk7CisKKyAgd2hpbGUgKGNoaWxkX3N0ZG91dF8gIT0gLTEpIHsKKyAgICBmZF9zZXQgcmVhZF9mZHM7CisgICAgZmRfc2V0IHdyaXRlX2ZkczsKKyAgICBGRF9aRVJPKCZyZWFkX2Zkcyk7CisgICAgRkRfWkVSTygmd3JpdGVfZmRzKTsKKyAgICBpZiAoY2hpbGRfc3Rkb3V0XyAhPSAtMSkgeworICAgICAgRkRfU0VUKGNoaWxkX3N0ZG91dF8sICZyZWFkX2Zkcyk7CisgICAgfQorICAgIGlmIChjaGlsZF9zdGRpbl8gIT0gLTEpIHsKKyAgICAgIEZEX1NFVChjaGlsZF9zdGRpbl8sICZ3cml0ZV9mZHMpOworICAgIH0KKworICAgIGlmIChzZWxlY3QobWF4X2ZkICsgMSwgJnJlYWRfZmRzLCAmd3JpdGVfZmRzLCBOVUxMLCBOVUxMKSA8IDApIHsKKyAgICAgIGlmIChlcnJubyA9PSBFSU5UUikgeworICAgICAgICAvLyBJbnRlcnJ1cHRlZCBieSBzaWduYWwuICBUcnkgYWdhaW4uCisgICAgICAgIGNvbnRpbnVlOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgInNlbGVjdDogIiA8PCBzdHJlcnJvcihlcnJubyk7CisgICAgICB9CisgICAgfQorCisgICAgaWYgKGNoaWxkX3N0ZGluXyAhPSAtMSAmJiBGRF9JU1NFVChjaGlsZF9zdGRpbl8sICZ3cml0ZV9mZHMpKSB7CisgICAgICBpbnQgbiA9IHdyaXRlKGNoaWxkX3N0ZGluXywgaW5wdXRfZGF0YS5kYXRhKCkgKyBpbnB1dF9wb3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXRfZGF0YS5zaXplKCkgLSBpbnB1dF9wb3MpOworICAgICAgaWYgKG4gPCAwKSB7CisgICAgICAgIC8vIENoaWxkIGNsb3NlZCBwaXBlLiAgUHJlc3VtYWJseSBpdCB3aWxsIHJlcG9ydCBhbiBlcnJvciBsYXRlci4KKyAgICAgICAgLy8gUHJldGVuZCB3ZSdyZSBkb25lIGZvciBub3cuCisgICAgICAgIGlucHV0X3BvcyA9IGlucHV0X2RhdGEuc2l6ZSgpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgaW5wdXRfcG9zICs9IG47CisgICAgICB9CisKKyAgICAgIGlmIChpbnB1dF9wb3MgPT0gaW5wdXRfZGF0YS5zaXplKCkpIHsKKyAgICAgICAgLy8gV2UncmUgZG9uZSB3cml0aW5nLiAgQ2xvc2UuCisgICAgICAgIGNsb3NlKGNoaWxkX3N0ZGluXyk7CisgICAgICAgIGNoaWxkX3N0ZGluXyA9IC0xOworICAgICAgfQorICAgIH0KKworICAgIGlmIChjaGlsZF9zdGRvdXRfICE9IC0xICYmIEZEX0lTU0VUKGNoaWxkX3N0ZG91dF8sICZyZWFkX2ZkcykpIHsKKyAgICAgIGNoYXIgYnVmZmVyWzQwOTZdOworICAgICAgaW50IG4gPSByZWFkKGNoaWxkX3N0ZG91dF8sIGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlcikpOworCisgICAgICBpZiAobiA+IDApIHsKKyAgICAgICAgb3V0cHV0X2RhdGEuYXBwZW5kKGJ1ZmZlciwgbik7CisgICAgICB9IGVsc2UgeworICAgICAgICAvLyBXZSdyZSBkb25lIHJlYWRpbmcuICBDbG9zZS4KKyAgICAgICAgY2xvc2UoY2hpbGRfc3Rkb3V0Xyk7CisgICAgICAgIGNoaWxkX3N0ZG91dF8gPSAtMTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICBpZiAoY2hpbGRfc3RkaW5fICE9IC0xKSB7CisgICAgLy8gQ2hpbGQgZGlkIG5vdCBmaW5pc2ggcmVhZGluZyBpbnB1dCBiZWZvcmUgaXQgY2xvc2VkIHRoZSBvdXRwdXQuCisgICAgLy8gUHJlc3VtYWJseSBpdCBleGl0ZWQgd2l0aCBhbiBlcnJvci4KKyAgICBjbG9zZShjaGlsZF9zdGRpbl8pOworICAgIGNoaWxkX3N0ZGluXyA9IC0xOworICB9CisKKyAgaW50IHN0YXR1czsKKyAgd2hpbGUgKHdhaXRwaWQoY2hpbGRfcGlkXywgJnN0YXR1cywgMCkgPT0gLTEpIHsKKyAgICBpZiAoZXJybm8gIT0gRUlOVFIpIHsKKyAgICAgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJ3YWl0cGlkOiAiIDw8IHN0cmVycm9yKGVycm5vKTsKKyAgICB9CisgIH0KKworICAvLyBSZXN0b3JlIFNJR1BJUEUgaGFuZGxpbmcuCisgIHNpZ25hbChTSUdQSVBFLCBvbGRfcGlwZV9oYW5kbGVyKTsKKworICBpZiAoV0lGRVhJVEVEKHN0YXR1cykpIHsKKyAgICBpZiAoV0VYSVRTVEFUVVMoc3RhdHVzKSAhPSAwKSB7CisgICAgICBpbnQgZXJyb3JfY29kZSA9IFdFWElUU1RBVFVTKHN0YXR1cyk7CisgICAgICAqZXJyb3IgPSBzdHJpbmdzOjpTdWJzdGl0dXRlKAorICAgICAgICAgICJQbHVnaW4gZmFpbGVkIHdpdGggc3RhdHVzIGNvZGUgJDAuIiwgZXJyb3JfY29kZSk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICB9IGVsc2UgaWYgKFdJRlNJR05BTEVEKHN0YXR1cykpIHsKKyAgICBpbnQgc2lnbmFsID0gV1RFUk1TSUcoc3RhdHVzKTsKKyAgICAqZXJyb3IgPSBzdHJpbmdzOjpTdWJzdGl0dXRlKAorICAgICAgICAiUGx1Z2luIGtpbGxlZCBieSBzaWduYWwgJDAuIiwgc2lnbmFsKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0gZWxzZSB7CisgICAgKmVycm9yID0gIk5laXRoZXIgV0VYSVRTVEFUVVMgbm9yIFdURVJNU0lHIGlzIHRydWU/IjsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBpZiAoIW91dHB1dC0+UGFyc2VGcm9tU3RyaW5nKG91dHB1dF9kYXRhKSkgeworICAgICplcnJvciA9ICJQbHVnaW4gb3V0cHV0IGlzIHVucGFyc2VhYmxlOiAiICsgQ0VzY2FwZShvdXRwdXRfZGF0YSk7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgcmV0dXJuIHRydWU7Cit9CisKKyNlbmRpZiAgLy8gIV9XSU4zMgorCit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9zdWJwcm9jZXNzLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3N1YnByb2Nlc3MuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNTEzODYzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci9zdWJwcm9jZXNzLmgKQEAgLTAsMCArMSwxMDggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX1NVQlBST0NFU1NfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9DT01QSUxFUl9TVUJQUk9DRVNTX0hfXworCisjaWZkZWYgX1dJTjMyCisjZGVmaW5lIFdJTjMyX0xFQU5fQU5EX01FQU4gICAvLyByaWdodC4uLgorI2luY2x1ZGUgPHdpbmRvd3MuaD4KKyNlbHNlICAvLyBfV0lOMzIKKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKyNpbmNsdWRlIDx1bmlzdGQuaD4KKyNlbmRpZiAgLy8gIV9XSU4zMgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKworI2luY2x1ZGUgPHN0cmluZz4KKworCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKK2NsYXNzIE1lc3NhZ2U7CisKK25hbWVzcGFjZSBjb21waWxlciB7CisKKy8vIFV0aWxpdHkgY2xhc3MgZm9yIGxhdW5jaGluZyBzdWItcHJvY2Vzc2VzLgorY2xhc3MgTElCUFJPVE9DX0VYUE9SVCBTdWJwcm9jZXNzIHsKKyBwdWJsaWM6CisgIFN1YnByb2Nlc3MoKTsKKyAgflN1YnByb2Nlc3MoKTsKKworICBlbnVtIFNlYXJjaE1vZGUgeworICAgIFNFQVJDSF9QQVRILCAgIC8vIFVzZSBQQVRIIGVudmlyb25tZW50IHZhcmlhYmxlLgorICAgIEVYQUNUX05BTUUgICAgIC8vIFByb2dyYW0gaXMgYW4gZXhhY3QgZmlsZSBuYW1lOyBkb24ndCB1c2UgdGhlIFBBVEguCisgIH07CisKKyAgLy8gU3RhcnQgdGhlIHN1YnByb2Nlc3MuICBDdXJyZW50bHkgd2UgZG9uJ3QgcHJvdmlkZSBhIHdheSB0byBzcGVjaWZ5CisgIC8vIGFyZ3VtZW50cyBhcyBwcm90b2MgcGx1Z2lucyBkb24ndCBoYXZlIGFueS4KKyAgdm9pZCBTdGFydChjb25zdCBzdHJpbmcmIHByb2dyYW0sIFNlYXJjaE1vZGUgc2VhcmNoX21vZGUpOworCisgIC8vIFNlcmlhbGl6ZSB0aGUgaW5wdXQgbWVzc2FnZSBhbmQgcGlwZSBpdCB0byB0aGUgc3VicHJvY2VzcydzIHN0ZGluLCB0aGVuCisgIC8vIGNsb3NlIHRoZSBwaXBlLiAgTWVhbndoaWxlLCByZWFkIGZyb20gdGhlIHN1YnByb2Nlc3MncyBzdGRvdXQgYW5kIHBhcnNlCisgIC8vIHRoZSBkYXRhIGludG8gKm91dHB1dC4gIEFsbCB0aGlzIGlzIGRvbmUgY2FyZWZ1bGx5IHRvIGF2b2lkIGRlYWRsb2Nrcy4KKyAgLy8gUmV0dXJucyB0cnVlIGlmIHN1Y2Nlc3NmdWwuICBPbiBhbnkgc29ydCBvZiBlcnJvciwgcmV0dXJucyBmYWxzZSBhbmQgc2V0cworICAvLyAqZXJyb3IgdG8gYSBkZXNjcmlwdGlvbiBvZiB0aGUgcHJvYmxlbS4KKyAgYm9vbCBDb21tdW5pY2F0ZShjb25zdCBNZXNzYWdlJiBpbnB1dCwgTWVzc2FnZSogb3V0cHV0LCBzdHJpbmcqIGVycm9yKTsKKworI2lmZGVmIF9XSU4zMgorICAvLyBHaXZlbiBhbiBlcnJvciBjb2RlLCByZXR1cm5zIGEgaHVtYW4tcmVhZGFibGUgZXJyb3IgbWVzc2FnZS4gIFRoaXMgaXMKKyAgLy8gZGVmaW5lZCBoZXJlIHNvIHRoYXQgQ29tbWFuZExpbmVJbnRlcmZhY2UgY2FuIHNoYXJlIGl0LgorICBzdGF0aWMgc3RyaW5nIFdpbjMyRXJyb3JNZXNzYWdlKERXT1JEIGVycm9yX2NvZGUpOworI2VuZGlmCisKKyBwcml2YXRlOgorI2lmZGVmIF9XSU4zMgorICBEV09SRCBwcm9jZXNzX3N0YXJ0X2Vycm9yXzsKKyAgSEFORExFIGNoaWxkX2hhbmRsZV87CisKKyAgLy8gVGhlIGZpbGUgaGFuZGxlcyBmb3Igb3VyIGVuZCBvZiB0aGUgY2hpbGQncyBwaXBlcy4gIFdlIGNsb3NlIGVhY2ggYW5kCisgIC8vIHNldCBpdCB0byBOVUxMIHdoZW4gbm8gbG9uZ2VyIG5lZWRlZC4KKyAgSEFORExFIGNoaWxkX3N0ZGluXzsKKyAgSEFORExFIGNoaWxkX3N0ZG91dF87CisKKyNlbHNlICAvLyBfV0lOMzIKKyAgcGlkX3QgY2hpbGRfcGlkXzsKKworICAvLyBUaGUgZmlsZSBkZXNjcmlwdG9ycyBmb3Igb3VyIGVuZCBvZiB0aGUgY2hpbGQncyBwaXBlcy4gIFdlIGNsb3NlIGVhY2ggYW5kCisgIC8vIHNldCBpdCB0byAtMSB3aGVuIG5vIGxvbmdlciBuZWVkZWQuCisgIGludCBjaGlsZF9zdGRpbl87CisgIGludCBjaGlsZF9zdGRvdXRfOworCisjZW5kaWYgIC8vICFfV0lOMzIKK307CisKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0NPTVBJTEVSX1NVQlBST0NFU1NfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3Rlc3RfcGx1Z2luLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci90ZXN0X3BsdWdpbi5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ODMwZmQ3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci90ZXN0X3BsdWdpbi5jYwpAQCAtMCwwICsxLDUxIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8KKy8vIFRoaXMgaXMgYSBkdW1teSBjb2RlIGdlbmVyYXRvciBwbHVnaW4gdXNlZCBieQorLy8gY29tbWFuZF9saW5lX2ludGVyZmFjZV91bml0dGVzdC4KKworI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL21vY2tfY29kZV9nZW5lcmF0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorCitpbnQgbWFpbihpbnQgYXJnYywgY2hhciogYXJndltdKSB7CisjaWZkZWYgX01TQ19WRVIKKyAgLy8gRG9uJ3QgcHJpbnQgYSBzaWxseSBtZXNzYWdlIG9yIHN0aWNrIGEgbW9kYWwgZGlhbG9nIGJveCBpbiBteSBmYWNlLAorICAvLyBwbGVhc2UuCisgIF9zZXRfYWJvcnRfYmVoYXZpb3IoMCwgfjApOworI2VuZGlmICAvLyAhX01TQ19WRVIKKworICBnb29nbGU6OnByb3RvYnVmOjpjb21waWxlcjo6TW9ja0NvZGVHZW5lcmF0b3IgZ2VuZXJhdG9yKCJ0ZXN0X3BsdWdpbiIpOworICByZXR1cm4gZ29vZ2xlOjpwcm90b2J1Zjo6Y29tcGlsZXI6OlBsdWdpbk1haW4oYXJnYywgYXJndiwgJmdlbmVyYXRvcik7Cit9CmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3ppcF9vdXRwdXRfdW5pdHRlc3Quc2ggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3ppcF9vdXRwdXRfdW5pdHRlc3Quc2gKbmV3IGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMDAwMDAwMC4uNmZjNzEzNgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvemlwX291dHB1dF91bml0dGVzdC5zaApAQCAtMCwwICsxLDkxIEBACisjIS9iaW4vc2gKKyMKKyMgUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisjIENvcHlyaWdodCAyMDA5IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorIyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworIworIyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKyMgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorIyBtZXQ6CisjCisjICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisjIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKyMgICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorIyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisjIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKyMgZGlzdHJpYnV0aW9uLgorIyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisjIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisjIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisjCisjIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKyMgIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKyMgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisjIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisjIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorIyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisjIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorIyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKyMgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorIyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKyMgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworIyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisjCisjIFRlc3QgcHJvdG9jJ3MgemlwIG91dHB1dCBtb2RlLgorCitmYWlsKCkgeworICBlY2hvICIkQCIgPiYyCisgIGV4aXQgMQorfQorCitURVNUX1RNUERJUj0uCitQUk9UT0M9Li9wcm90b2MKKworZWNobyAnCisgIHN5bnRheCA9ICJwcm90bzIiOworICBvcHRpb24gamF2YV9tdWx0aXBsZV9maWxlcyA9IHRydWU7CisgIG9wdGlvbiBqYXZhX3BhY2thZ2UgPSAidGVzdC5qYXIiOworICBvcHRpb24gamF2YV9vdXRlcl9jbGFzc25hbWUgPSAiT3V0ZXIiOworICBtZXNzYWdlIEZvbyB7fQorICBtZXNzYWdlIEJhciB7fQorJyA+ICRURVNUX1RNUERJUi90ZXN0emlwLnByb3RvCisKKyRQUk9UT0MgXAorICAgIC0tY3BwX291dD0kVEVTVF9UTVBESVIvdGVzdHppcC56aXAgLS1weXRob25fb3V0PSRURVNUX1RNUERJUi90ZXN0emlwLnppcCBcCisgICAgLS1qYXZhX291dD0kVEVTVF9UTVBESVIvdGVzdHppcC5qYXIgLUkkVEVTVF9UTVBESVIgdGVzdHppcC5wcm90byBcCisgICAgfHwgZmFpbCAncHJvdG9jIGZhaWxlZC4nCisKK2VjaG8gIlRlc3Rpbmcgb3V0cHV0IHRvIHppcC4uLiIKK2lmIHVuemlwIC1oID4gL2Rldi9udWxsOyB0aGVuCisgIHVuemlwIC10ICRURVNUX1RNUERJUi90ZXN0emlwLnppcCA+ICRURVNUX1RNUERJUi90ZXN0emlwLmxpc3QgfHwgZmFpbCAndW56aXAgZmFpbGVkLicKKworICBncmVwICd0ZXN0aW5nOiB0ZXN0emlwXC5wYlwuY2MgKk9LJCcgJFRFU1RfVE1QRElSL3Rlc3R6aXAubGlzdCA+IC9kZXYvbnVsbCBcCisgICAgfHwgZmFpbCAndGVzdHppcC5wYi5jYyBub3QgZm91bmQgaW4gb3V0cHV0IHppcC4nCisgIGdyZXAgJ3Rlc3Rpbmc6IHRlc3R6aXBcLnBiXC5oICpPSyQnICRURVNUX1RNUERJUi90ZXN0emlwLmxpc3QgPiAvZGV2L251bGwgXAorICAgIHx8IGZhaWwgJ3Rlc3R6aXAucGIuaCBub3QgZm91bmQgaW4gb3V0cHV0IHppcC4nCisgIGdyZXAgJ3Rlc3Rpbmc6IHRlc3R6aXBfcGIyXC5weSAqT0skJyAkVEVTVF9UTVBESVIvdGVzdHppcC5saXN0ID4gL2Rldi9udWxsIFwKKyAgICB8fCBmYWlsICd0ZXN0emlwX3BiMi5weSBub3QgZm91bmQgaW4gb3V0cHV0IHppcC4nCisgIGdyZXAgLWkgJ21hbmlmZXN0JyAkVEVTVF9UTVBESVIvdGVzdHppcC5saXN0ID4gL2Rldi9udWxsIFwKKyAgICAmJiBmYWlsICdaaXAgZmlsZSBjb250YWluZWQgbWFuaWZlc3QuJworZWxzZQorICBlY2hvICJXYXJuaW5nOiAgJ3VuemlwJyBjb21tYW5kIG5vdCBhdmFpbGFibGUuICBTa2lwcGluZyB0ZXN0LiIKK2ZpCisKK2VjaG8gIlRlc3Rpbmcgb3V0cHV0IHRvIGphci4uLiIKK2lmIGphciBjICRURVNUX1RNUERJUi90ZXN0emlwLnByb3RvID4gL2Rldi9udWxsOyB0aGVuCisgIGphciB0ZiAkVEVTVF9UTVBESVIvdGVzdHppcC5qYXIgPiAkVEVTVF9UTVBESVIvdGVzdHppcC5saXN0IHx8IGZhaWwgJ2phciBmYWlsZWQuJworCisgIGdyZXAgJ150ZXN0L2phci9Gb29cLmphdmEkJyAkVEVTVF9UTVBESVIvdGVzdHppcC5saXN0ID4gL2Rldi9udWxsIFwKKyAgICB8fCBmYWlsICdGb28uamF2YSBub3QgZm91bmQgaW4gb3V0cHV0IGphci4nCisgIGdyZXAgJ150ZXN0L2phci9CYXJcLmphdmEkJyAkVEVTVF9UTVBESVIvdGVzdHppcC5saXN0ID4gL2Rldi9udWxsIFwKKyAgICB8fCBmYWlsICdCYXIuamF2YSBub3QgZm91bmQgaW4gb3V0cHV0IGphci4nCisgIGdyZXAgJ150ZXN0L2phci9PdXRlclwuamF2YSQnICRURVNUX1RNUERJUi90ZXN0emlwLmxpc3QgPiAvZGV2L251bGwgXAorICAgIHx8IGZhaWwgJ091dGVyLmphdmEgbm90IGZvdW5kIGluIG91dHB1dCBqYXIuJworICBncmVwICdeTUVUQS1JTkYvTUFOSUZFU1RcLk1GJCcgJFRFU1RfVE1QRElSL3Rlc3R6aXAubGlzdCA+IC9kZXYvbnVsbCBcCisgICAgfHwgZmFpbCAnTWFuaWZlc3Qgbm90IGZvdW5kIGluIG91dHB1dCBqYXIuJworZWxzZQorICBlY2hvICJXYXJuaW5nOiAgJ2phcicgY29tbWFuZCBub3QgYXZhaWxhYmxlLiAgU2tpcHBpbmcgdGVzdC4iCitmaQorCitlY2hvIFBBU1MKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvemlwX3dyaXRlci5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvemlwX3dyaXRlci5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NThjY2VkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9jb21waWxlci96aXBfd3JpdGVyLmNjCkBAIC0wLDAgKzEsMjE4IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjogYW1icm9zZUBnb29nbGUuY29tIChBbWJyb3NlIEZlaW5zdGVpbiksCisvLyAgICAgICAgIGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLworLy8gQmFzZWQgb24gaHR0cDovL3d3dy5wa3dhcmUuY29tL2RvY3VtZW50cy9jYXNlc3R1ZGllcy9BUFBOT1RFLlRYVAorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3ppcF93cml0ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBjb21waWxlciB7CisKK3N0YXRpYyBjb25zdCB1aW50MzIga0NSQzMyVGFibGVbMjU2XSA9IHsKKyAgMHgwMDAwMDAwMCwgMHg3NzA3MzA5NiwgMHhlZTBlNjEyYywgMHg5OTA5NTFiYSwgMHgwNzZkYzQxOSwgMHg3MDZhZjQ4ZiwKKyAgMHhlOTYzYTUzNSwgMHg5ZTY0OTVhMywgMHgwZWRiODgzMiwgMHg3OWRjYjhhNCwgMHhlMGQ1ZTkxZSwgMHg5N2QyZDk4OCwKKyAgMHgwOWI2NGMyYiwgMHg3ZWIxN2NiZCwgMHhlN2I4MmQwNywgMHg5MGJmMWQ5MSwgMHgxZGI3MTA2NCwgMHg2YWIwMjBmMiwKKyAgMHhmM2I5NzE0OCwgMHg4NGJlNDFkZSwgMHgxYWRhZDQ3ZCwgMHg2ZGRkZTRlYiwgMHhmNGQ0YjU1MSwgMHg4M2QzODVjNywKKyAgMHgxMzZjOTg1NiwgMHg2NDZiYThjMCwgMHhmZDYyZjk3YSwgMHg4YTY1YzllYywgMHgxNDAxNWM0ZiwgMHg2MzA2NmNkOSwKKyAgMHhmYTBmM2Q2MywgMHg4ZDA4MGRmNSwgMHgzYjZlMjBjOCwgMHg0YzY5MTA1ZSwgMHhkNTYwNDFlNCwgMHhhMjY3NzE3MiwKKyAgMHgzYzAzZTRkMSwgMHg0YjA0ZDQ0NywgMHhkMjBkODVmZCwgMHhhNTBhYjU2YiwgMHgzNWI1YThmYSwgMHg0MmIyOTg2YywKKyAgMHhkYmJiYzlkNiwgMHhhY2JjZjk0MCwgMHgzMmQ4NmNlMywgMHg0NWRmNWM3NSwgMHhkY2Q2MGRjZiwgMHhhYmQxM2Q1OSwKKyAgMHgyNmQ5MzBhYywgMHg1MWRlMDAzYSwgMHhjOGQ3NTE4MCwgMHhiZmQwNjExNiwgMHgyMWI0ZjRiNSwgMHg1NmIzYzQyMywKKyAgMHhjZmJhOTU5OSwgMHhiOGJkYTUwZiwgMHgyODAyYjg5ZSwgMHg1ZjA1ODgwOCwgMHhjNjBjZDliMiwgMHhiMTBiZTkyNCwKKyAgMHgyZjZmN2M4NywgMHg1ODY4NGMxMSwgMHhjMTYxMWRhYiwgMHhiNjY2MmQzZCwgMHg3NmRjNDE5MCwgMHgwMWRiNzEwNiwKKyAgMHg5OGQyMjBiYywgMHhlZmQ1MTAyYSwgMHg3MWIxODU4OSwgMHgwNmI2YjUxZiwgMHg5ZmJmZTRhNSwgMHhlOGI4ZDQzMywKKyAgMHg3ODA3YzlhMiwgMHgwZjAwZjkzNCwgMHg5NjA5YTg4ZSwgMHhlMTBlOTgxOCwgMHg3ZjZhMGRiYiwgMHgwODZkM2QyZCwKKyAgMHg5MTY0NmM5NywgMHhlNjYzNWMwMSwgMHg2YjZiNTFmNCwgMHgxYzZjNjE2MiwgMHg4NTY1MzBkOCwgMHhmMjYyMDA0ZSwKKyAgMHg2YzA2OTVlZCwgMHgxYjAxYTU3YiwgMHg4MjA4ZjRjMSwgMHhmNTBmYzQ1NywgMHg2NWIwZDljNiwgMHgxMmI3ZTk1MCwKKyAgMHg4YmJlYjhlYSwgMHhmY2I5ODg3YywgMHg2MmRkMWRkZiwgMHgxNWRhMmQ0OSwgMHg4Y2QzN2NmMywgMHhmYmQ0NGM2NSwKKyAgMHg0ZGIyNjE1OCwgMHgzYWI1NTFjZSwgMHhhM2JjMDA3NCwgMHhkNGJiMzBlMiwgMHg0YWRmYTU0MSwgMHgzZGQ4OTVkNywKKyAgMHhhNGQxYzQ2ZCwgMHhkM2Q2ZjRmYiwgMHg0MzY5ZTk2YSwgMHgzNDZlZDlmYywgMHhhZDY3ODg0NiwgMHhkYTYwYjhkMCwKKyAgMHg0NDA0MmQ3MywgMHgzMzAzMWRlNSwgMHhhYTBhNGM1ZiwgMHhkZDBkN2NjOSwgMHg1MDA1NzEzYywgMHgyNzAyNDFhYSwKKyAgMHhiZTBiMTAxMCwgMHhjOTBjMjA4NiwgMHg1NzY4YjUyNSwgMHgyMDZmODViMywgMHhiOTY2ZDQwOSwgMHhjZTYxZTQ5ZiwKKyAgMHg1ZWRlZjkwZSwgMHgyOWQ5Yzk5OCwgMHhiMGQwOTgyMiwgMHhjN2Q3YThiNCwgMHg1OWIzM2QxNywgMHgyZWI0MGQ4MSwKKyAgMHhiN2JkNWMzYiwgMHhjMGJhNmNhZCwgMHhlZGI4ODMyMCwgMHg5YWJmYjNiNiwgMHgwM2I2ZTIwYywgMHg3NGIxZDI5YSwKKyAgMHhlYWQ1NDczOSwgMHg5ZGQyNzdhZiwgMHgwNGRiMjYxNSwgMHg3M2RjMTY4MywgMHhlMzYzMGIxMiwgMHg5NDY0M2I4NCwKKyAgMHgwZDZkNmEzZSwgMHg3YTZhNWFhOCwgMHhlNDBlY2YwYiwgMHg5MzA5ZmY5ZCwgMHgwYTAwYWUyNywgMHg3ZDA3OWViMSwKKyAgMHhmMDBmOTM0NCwgMHg4NzA4YTNkMiwgMHgxZTAxZjI2OCwgMHg2OTA2YzJmZSwgMHhmNzYyNTc1ZCwgMHg4MDY1NjdjYiwKKyAgMHgxOTZjMzY3MSwgMHg2ZTZiMDZlNywgMHhmZWQ0MWI3NiwgMHg4OWQzMmJlMCwgMHgxMGRhN2E1YSwgMHg2N2RkNGFjYywKKyAgMHhmOWI5ZGY2ZiwgMHg4ZWJlZWZmOSwgMHgxN2I3YmU0MywgMHg2MGIwOGVkNSwgMHhkNmQ2YTNlOCwgMHhhMWQxOTM3ZSwKKyAgMHgzOGQ4YzJjNCwgMHg0ZmRmZjI1MiwgMHhkMWJiNjdmMSwgMHhhNmJjNTc2NywgMHgzZmI1MDZkZCwgMHg0OGIyMzY0YiwKKyAgMHhkODBkMmJkYSwgMHhhZjBhMWI0YywgMHgzNjAzNGFmNiwgMHg0MTA0N2E2MCwgMHhkZjYwZWZjMywgMHhhODY3ZGY1NSwKKyAgMHgzMTZlOGVlZiwgMHg0NjY5YmU3OSwgMHhjYjYxYjM4YywgMHhiYzY2ODMxYSwgMHgyNTZmZDJhMCwgMHg1MjY4ZTIzNiwKKyAgMHhjYzBjNzc5NSwgMHhiYjBiNDcwMywgMHgyMjAyMTZiOSwgMHg1NTA1MjYyZiwgMHhjNWJhM2JiZSwgMHhiMmJkMGIyOCwKKyAgMHgyYmI0NWE5MiwgMHg1Y2IzNmEwNCwgMHhjMmQ3ZmZhNywgMHhiNWQwY2YzMSwgMHgyY2Q5OWU4YiwgMHg1YmRlYWUxZCwKKyAgMHg5YjY0YzJiMCwgMHhlYzYzZjIyNiwgMHg3NTZhYTM5YywgMHgwMjZkOTMwYSwgMHg5YzA5MDZhOSwgMHhlYjBlMzYzZiwKKyAgMHg3MjA3Njc4NSwgMHgwNTAwNTcxMywgMHg5NWJmNGE4MiwgMHhlMmI4N2ExNCwgMHg3YmIxMmJhZSwgMHgwY2I2MWIzOCwKKyAgMHg5MmQyOGU5YiwgMHhlNWQ1YmUwZCwgMHg3Y2RjZWZiNywgMHgwYmRiZGYyMSwgMHg4NmQzZDJkNCwgMHhmMWQ0ZTI0MiwKKyAgMHg2OGRkYjNmOCwgMHgxZmRhODM2ZSwgMHg4MWJlMTZjZCwgMHhmNmI5MjY1YiwgMHg2ZmIwNzdlMSwgMHgxOGI3NDc3NywKKyAgMHg4ODA4NWFlNiwgMHhmZjBmNmE3MCwgMHg2NjA2M2JjYSwgMHgxMTAxMGI1YywgMHg4ZjY1OWVmZiwgMHhmODYyYWU2OSwKKyAgMHg2MTZiZmZkMywgMHgxNjZjY2Y0NSwgMHhhMDBhZTI3OCwgMHhkNzBkZDJlZSwgMHg0ZTA0ODM1NCwgMHgzOTAzYjNjMiwKKyAgMHhhNzY3MjY2MSwgMHhkMDYwMTZmNywgMHg0OTY5NDc0ZCwgMHgzZTZlNzdkYiwgMHhhZWQxNmE0YSwgMHhkOWQ2NWFkYywKKyAgMHg0MGRmMGI2NiwgMHgzN2Q4M2JmMCwgMHhhOWJjYWU1MywgMHhkZWJiOWVjNSwgMHg0N2IyY2Y3ZiwgMHgzMGI1ZmZlOSwKKyAgMHhiZGJkZjIxYywgMHhjYWJhYzI4YSwgMHg1M2IzOTMzMCwgMHgyNGI0YTNhNiwgMHhiYWQwMzYwNSwgMHhjZGQ3MDY5MywKKyAgMHg1NGRlNTcyOSwgMHgyM2Q5NjdiZiwgMHhiMzY2N2EyZSwgMHhjNDYxNGFiOCwgMHg1ZDY4MWIwMiwgMHgyYTZmMmI5NCwKKyAgMHhiNDBiYmUzNywgMHhjMzBjOGVhMSwgMHg1YTA1ZGYxYiwgMHgyZDAyZWY4ZAorfTsKKworc3RhdGljIHVpbnQzMiBDb21wdXRlQ1JDMzIoY29uc3Qgc3RyaW5nICZidWYpIHsKKyAgdWludDMyIHggPSB+MFU7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgYnVmLnNpemUoKTsgKytpKSB7CisgICAgdW5zaWduZWQgY2hhciBjID0gYnVmW2ldOworICAgIHggPSBrQ1JDMzJUYWJsZVsoeCBeIGMpICYgMHhmZl0gXiAoeCA+PiA4KTsKKyAgfQorICByZXR1cm4gfng7Cit9CisKK3N0YXRpYyB2b2lkIFdyaXRlU2hvcnQoaW86OkNvZGVkT3V0cHV0U3RyZWFtICpvdXQsIHVpbnQxNiB2YWwpIHsKKyAgdWludDggcFsyXTsKKyAgcFswXSA9IHN0YXRpY19jYXN0PHVpbnQ4Pih2YWwpOworICBwWzFdID0gc3RhdGljX2Nhc3Q8dWludDg+KHZhbCA+PiA4KTsKKyAgb3V0LT5Xcml0ZVJhdyhwLCAyKTsKK30KKworWmlwV3JpdGVyOjpaaXBXcml0ZXIoaW86Olplcm9Db3B5T3V0cHV0U3RyZWFtKiByYXdfb3V0cHV0KQorICA6IHJhd19vdXRwdXRfKHJhd19vdXRwdXQpIHt9CitaaXBXcml0ZXI6On5aaXBXcml0ZXIoKSB7fQorCitib29sIFppcFdyaXRlcjo6V3JpdGUoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSwgY29uc3Qgc3RyaW5nJiBjb250ZW50cykgeworICBGaWxlSW5mbyBpbmZvOworCisgIGluZm8ubmFtZSA9IGZpbGVuYW1lOworICB1aW50MTYgZmlsZW5hbWVfc2l6ZSA9IGZpbGVuYW1lLnNpemUoKTsKKyAgaW5mby5vZmZzZXQgPSByYXdfb3V0cHV0Xy0+Qnl0ZUNvdW50KCk7CisgIGluZm8uc2l6ZSA9IGNvbnRlbnRzLnNpemUoKTsKKyAgaW5mby5jcmMzMiA9IENvbXB1dGVDUkMzMihjb250ZW50cyk7CisKKyAgZmlsZXNfLnB1c2hfYmFjayhpbmZvKTsKKworICAvLyB3cml0ZSBmaWxlIGhlYWRlcgorICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KHJhd19vdXRwdXRfKTsKKyAgb3V0cHV0LldyaXRlTGl0dGxlRW5kaWFuMzIoMHgwNDAzNGI1MCk7ICAvLyBtYWdpYworICBXcml0ZVNob3J0KCZvdXRwdXQsIDEwKTsgIC8vIHZlcnNpb24gbmVlZGVkIHRvIGV4dHJhY3QKKyAgV3JpdGVTaG9ydCgmb3V0cHV0LCAwKTsgIC8vIGZsYWdzCisgIFdyaXRlU2hvcnQoJm91dHB1dCwgMCk7ICAvLyBjb21wcmVzc2lvbiBtZXRob2Q6IHN0b3JlZAorICBXcml0ZVNob3J0KCZvdXRwdXQsIDApOyAgLy8gbGFzdCBtb2RpZmllZCB0aW1lCisgIFdyaXRlU2hvcnQoJm91dHB1dCwgMCk7ICAvLyBsYXN0IG1vZGlmaWVkIGRhdGUKKyAgb3V0cHV0LldyaXRlTGl0dGxlRW5kaWFuMzIoaW5mby5jcmMzMik7ICAvLyBjcmMtMzIKKyAgb3V0cHV0LldyaXRlTGl0dGxlRW5kaWFuMzIoaW5mby5zaXplKTsgIC8vIGNvbXByZXNzZWQgc2l6ZQorICBvdXRwdXQuV3JpdGVMaXR0bGVFbmRpYW4zMihpbmZvLnNpemUpOyAgLy8gdW5jb21wcmVzc2VkIHNpemUKKyAgV3JpdGVTaG9ydCgmb3V0cHV0LCBmaWxlbmFtZV9zaXplKTsgIC8vIGZpbGUgbmFtZSBsZW5ndGgKKyAgV3JpdGVTaG9ydCgmb3V0cHV0LCAwKTsgICAvLyBleHRyYSBmaWVsZCBsZW5ndGgKKyAgb3V0cHV0LldyaXRlU3RyaW5nKGZpbGVuYW1lKTsgIC8vIGZpbGUgbmFtZQorICBvdXRwdXQuV3JpdGVTdHJpbmcoY29udGVudHMpOyAgLy8gZmlsZSBkYXRhCisKKyAgcmV0dXJuICFvdXRwdXQuSGFkRXJyb3IoKTsKK30KKworYm9vbCBaaXBXcml0ZXI6OldyaXRlRGlyZWN0b3J5KCkgeworICB1aW50MTYgbnVtX2VudHJpZXMgPSBmaWxlc18uc2l6ZSgpOworICB1aW50MzIgZGlyX29mcyA9IHJhd19vdXRwdXRfLT5CeXRlQ291bnQoKTsKKworICAvLyB3cml0ZSBjZW50cmFsIGRpcmVjdG9yeQorICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KHJhd19vdXRwdXRfKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1fZW50cmllczsgKytpKSB7CisgICAgY29uc3Qgc3RyaW5nICZmaWxlbmFtZSA9IGZpbGVzX1tpXS5uYW1lOworICAgIHVpbnQxNiBmaWxlbmFtZV9zaXplID0gZmlsZW5hbWUuc2l6ZSgpOworICAgIHVpbnQzMiBjcmMzMiA9IGZpbGVzX1tpXS5jcmMzMjsKKyAgICB1aW50MzIgc2l6ZSA9IGZpbGVzX1tpXS5zaXplOworICAgIHVpbnQzMiBvZmZzZXQgPSBmaWxlc19baV0ub2Zmc2V0OworCisgICAgb3V0cHV0LldyaXRlTGl0dGxlRW5kaWFuMzIoMHgwMjAxNGI1MCk7ICAvLyBtYWdpYworICAgIFdyaXRlU2hvcnQoJm91dHB1dCwgMTApOyAgLy8gdmVyc2lvbiBtYWRlIGJ5CisgICAgV3JpdGVTaG9ydCgmb3V0cHV0LCAxMCk7ICAvLyB2ZXJzaW9uIG5lZWRlZCB0byBleHRyYWN0CisgICAgV3JpdGVTaG9ydCgmb3V0cHV0LCAwKTsgIC8vIGZsYWdzCisgICAgV3JpdGVTaG9ydCgmb3V0cHV0LCAwKTsgIC8vIGNvbXByZXNzaW9uIG1ldGhvZDogc3RvcmVkCisgICAgV3JpdGVTaG9ydCgmb3V0cHV0LCAwKTsgIC8vIGxhc3QgbW9kaWZpZWQgdGltZQorICAgIFdyaXRlU2hvcnQoJm91dHB1dCwgMCk7ICAvLyBsYXN0IG1vZGlmaWVkIGRhdGUKKyAgICBvdXRwdXQuV3JpdGVMaXR0bGVFbmRpYW4zMihjcmMzMik7ICAvLyBjcmMtMzIKKyAgICBvdXRwdXQuV3JpdGVMaXR0bGVFbmRpYW4zMihzaXplKTsgIC8vIGNvbXByZXNzZWQgc2l6ZQorICAgIG91dHB1dC5Xcml0ZUxpdHRsZUVuZGlhbjMyKHNpemUpOyAgLy8gdW5jb21wcmVzc2VkIHNpemUKKyAgICBXcml0ZVNob3J0KCZvdXRwdXQsIGZpbGVuYW1lX3NpemUpOyAgLy8gZmlsZSBuYW1lIGxlbmd0aAorICAgIFdyaXRlU2hvcnQoJm91dHB1dCwgMCk7ICAgLy8gZXh0cmEgZmllbGQgbGVuZ3RoCisgICAgV3JpdGVTaG9ydCgmb3V0cHV0LCAwKTsgICAvLyBmaWxlIGNvbW1lbnQgbGVuZ3RoCisgICAgV3JpdGVTaG9ydCgmb3V0cHV0LCAwKTsgICAvLyBzdGFydGluZyBkaXNrIG51bWJlcgorICAgIFdyaXRlU2hvcnQoJm91dHB1dCwgMCk7ICAgLy8gaW50ZXJuYWwgZmlsZSBhdHRyaWJ1dGVzCisgICAgb3V0cHV0LldyaXRlTGl0dGxlRW5kaWFuMzIoMCk7ICAvLyBleHRlcm5hbCBmaWxlIGF0dHJpYnV0ZXMKKyAgICBvdXRwdXQuV3JpdGVMaXR0bGVFbmRpYW4zMihvZmZzZXQpOyAgLy8gbG9jYWwgaGVhZGVyIG9mZnNldAorICAgIG91dHB1dC5Xcml0ZVN0cmluZyhmaWxlbmFtZSk7ICAvLyBmaWxlIG5hbWUKKyAgfQorICB1aW50MzIgZGlyX2xlbiA9IG91dHB1dC5CeXRlQ291bnQoKTsKKworICAvLyB3cml0ZSBlbmQgb2YgY2VudHJhbCBkaXJlY3RvcnkgbWFya2VyCisgIG91dHB1dC5Xcml0ZUxpdHRsZUVuZGlhbjMyKDB4MDYwNTRiNTApOyAgLy8gbWFnaWMKKyAgV3JpdGVTaG9ydCgmb3V0cHV0LCAwKTsgIC8vIGRpc2sgbnVtYmVyCisgIFdyaXRlU2hvcnQoJm91dHB1dCwgMCk7ICAvLyBkaXNrIHdpdGggc3RhcnQgb2YgY2VudHJhbCBkaXJlY3RvcnkKKyAgV3JpdGVTaG9ydCgmb3V0cHV0LCBudW1fZW50cmllcyk7ICAvLyBjZW50cmFsIGRpcmVjdG9yeSBlbnRyaWVzICh0aGlzIGRpc2spCisgIFdyaXRlU2hvcnQoJm91dHB1dCwgbnVtX2VudHJpZXMpOyAgLy8gY2VudHJhbCBkaXJlY3RvcnkgZW50cmllcyAodG90YWwpCisgIG91dHB1dC5Xcml0ZUxpdHRsZUVuZGlhbjMyKGRpcl9sZW4pOyAgLy8gY2VudHJhbCBkaXJlY3RvcnkgYnl0ZSBzaXplCisgIG91dHB1dC5Xcml0ZUxpdHRsZUVuZGlhbjMyKGRpcl9vZnMpOyAgLy8gY2VudHJhbCBkaXJlY3Rvcnkgb2Zmc2V0CisgIFdyaXRlU2hvcnQoJm91dHB1dCwgMCk7ICAgLy8gY29tbWVudCBsZW5ndGgKKworICByZXR1cm4gb3V0cHV0LkhhZEVycm9yKCk7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3ppcF93cml0ZXIuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvY29tcGlsZXIvemlwX3dyaXRlci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYwMmU1MDgKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2NvbXBpbGVyL3ppcF93cml0ZXIuaApAQCAtMCwwICsxLDkzIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKworI2luY2x1ZGUgPHZlY3Rvcj4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW0uaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGNvbXBpbGVyIHsKKworY2xhc3MgWmlwV3JpdGVyIHsKKyBwdWJsaWM6CisgIFppcFdyaXRlcihpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0qIHJhd19vdXRwdXQpOworICB+WmlwV3JpdGVyKCk7CisKKyAgYm9vbCBXcml0ZShjb25zdCBzdHJpbmcmIGZpbGVuYW1lLCBjb25zdCBzdHJpbmcmIGNvbnRlbnRzKTsKKyAgYm9vbCBXcml0ZURpcmVjdG9yeSgpOworCisgcHJpdmF0ZToKKyAgc3RydWN0IEZpbGVJbmZvIHsKKyAgICBzdHJpbmcgbmFtZTsKKyAgICB1aW50MzIgb2Zmc2V0OworICAgIHVpbnQzMiBzaXplOworICAgIHVpbnQzMiBjcmMzMjsKKyAgfTsKKworICBpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0qIHJhd19vdXRwdXRfOworICB2ZWN0b3I8RmlsZUluZm8+IGZpbGVzXzsKK307CisKK30gIC8vIG5hbWVzcGFjZSBjb21waWxlcgorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzhhMzQ2MQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5jYwpAQCAtMCwwICsxLDYyNjcgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9oYXNoLmg+CisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPG1lbW9yeT4KKyNpZm5kZWYgX1NIQVJFRF9QVFJfSAorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaGFyZWRfcHRyLmg+CisjZW5kaWYKKyNpbmNsdWRlIDxzZXQ+CisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPHZlY3Rvcj4KKyNpbmNsdWRlIDxhbGdvcml0aG0+CisjaW5jbHVkZSA8bGltaXRzPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvcl9kYXRhYmFzZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2R5bmFtaWNfbWVzc2FnZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfbWVzc2FnZV91dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3RleHRfZm9ybWF0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Vua25vd25fZmllbGRfc2V0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3N0cnRvZC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vdG9rZW5pemVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbG9nZ2luZy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9tdXRleC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9vbmNlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cmluZ3ByaW50Zi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N1YnN0aXR1dGUuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbWFwX3V0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RsX3V0aWwuaD4KKworI3VuZGVmIFBBQ0tBR0UgIC8vIGF1dG9oZWFkZXIgI2RlZmluZXMgdGhpcy4gIDooCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworY29uc3QgRmllbGREZXNjcmlwdG9yOjpDcHBUeXBlCitGaWVsZERlc2NyaXB0b3I6OmtUeXBlVG9DcHBUeXBlTWFwW01BWF9UWVBFICsgMV0gPSB7CisgIHN0YXRpY19jYXN0PENwcFR5cGU+KDApLCAgLy8gMCBpcyByZXNlcnZlZCBmb3IgZXJyb3JzCisKKyAgQ1BQVFlQRV9ET1VCTEUsICAgLy8gVFlQRV9ET1VCTEUKKyAgQ1BQVFlQRV9GTE9BVCwgICAgLy8gVFlQRV9GTE9BVAorICBDUFBUWVBFX0lOVDY0LCAgICAvLyBUWVBFX0lOVDY0CisgIENQUFRZUEVfVUlOVDY0LCAgIC8vIFRZUEVfVUlOVDY0CisgIENQUFRZUEVfSU5UMzIsICAgIC8vIFRZUEVfSU5UMzIKKyAgQ1BQVFlQRV9VSU5UNjQsICAgLy8gVFlQRV9GSVhFRDY0CisgIENQUFRZUEVfVUlOVDMyLCAgIC8vIFRZUEVfRklYRUQzMgorICBDUFBUWVBFX0JPT0wsICAgICAvLyBUWVBFX0JPT0wKKyAgQ1BQVFlQRV9TVFJJTkcsICAgLy8gVFlQRV9TVFJJTkcKKyAgQ1BQVFlQRV9NRVNTQUdFLCAgLy8gVFlQRV9HUk9VUAorICBDUFBUWVBFX01FU1NBR0UsICAvLyBUWVBFX01FU1NBR0UKKyAgQ1BQVFlQRV9TVFJJTkcsICAgLy8gVFlQRV9CWVRFUworICBDUFBUWVBFX1VJTlQzMiwgICAvLyBUWVBFX1VJTlQzMgorICBDUFBUWVBFX0VOVU0sICAgICAvLyBUWVBFX0VOVU0KKyAgQ1BQVFlQRV9JTlQzMiwgICAgLy8gVFlQRV9TRklYRUQzMgorICBDUFBUWVBFX0lOVDY0LCAgICAvLyBUWVBFX1NGSVhFRDY0CisgIENQUFRZUEVfSU5UMzIsICAgIC8vIFRZUEVfU0lOVDMyCisgIENQUFRZUEVfSU5UNjQsICAgIC8vIFRZUEVfU0lOVDY0Cit9OworCitjb25zdCBjaGFyICogY29uc3QgRmllbGREZXNjcmlwdG9yOjprVHlwZVRvTmFtZVtNQVhfVFlQRSArIDFdID0geworICAiRVJST1IiLCAgICAgLy8gMCBpcyByZXNlcnZlZCBmb3IgZXJyb3JzCisKKyAgImRvdWJsZSIsICAgIC8vIFRZUEVfRE9VQkxFCisgICJmbG9hdCIsICAgICAvLyBUWVBFX0ZMT0FUCisgICJpbnQ2NCIsICAgICAvLyBUWVBFX0lOVDY0CisgICJ1aW50NjQiLCAgICAvLyBUWVBFX1VJTlQ2NAorICAiaW50MzIiLCAgICAgLy8gVFlQRV9JTlQzMgorICAiZml4ZWQ2NCIsICAgLy8gVFlQRV9GSVhFRDY0CisgICJmaXhlZDMyIiwgICAvLyBUWVBFX0ZJWEVEMzIKKyAgImJvb2wiLCAgICAgIC8vIFRZUEVfQk9PTAorICAic3RyaW5nIiwgICAgLy8gVFlQRV9TVFJJTkcKKyAgImdyb3VwIiwgICAgIC8vIFRZUEVfR1JPVVAKKyAgIm1lc3NhZ2UiLCAgIC8vIFRZUEVfTUVTU0FHRQorICAiYnl0ZXMiLCAgICAgLy8gVFlQRV9CWVRFUworICAidWludDMyIiwgICAgLy8gVFlQRV9VSU5UMzIKKyAgImVudW0iLCAgICAgIC8vIFRZUEVfRU5VTQorICAic2ZpeGVkMzIiLCAgLy8gVFlQRV9TRklYRUQzMgorICAic2ZpeGVkNjQiLCAgLy8gVFlQRV9TRklYRUQ2NAorICAic2ludDMyIiwgICAgLy8gVFlQRV9TSU5UMzIKKyAgInNpbnQ2NCIsICAgIC8vIFRZUEVfU0lOVDY0Cit9OworCitjb25zdCBjaGFyICogY29uc3QgRmllbGREZXNjcmlwdG9yOjprQ3BwVHlwZVRvTmFtZVtNQVhfQ1BQVFlQRSArIDFdID0geworICAiRVJST1IiLCAgICAgLy8gMCBpcyByZXNlcnZlZCBmb3IgZXJyb3JzCisKKyAgImludDMyIiwgICAgIC8vIENQUFRZUEVfSU5UMzIKKyAgImludDY0IiwgICAgIC8vIENQUFRZUEVfSU5UNjQKKyAgInVpbnQzMiIsICAgIC8vIENQUFRZUEVfVUlOVDMyCisgICJ1aW50NjQiLCAgICAvLyBDUFBUWVBFX1VJTlQ2NAorICAiZG91YmxlIiwgICAgLy8gQ1BQVFlQRV9ET1VCTEUKKyAgImZsb2F0IiwgICAgIC8vIENQUFRZUEVfRkxPQVQKKyAgImJvb2wiLCAgICAgIC8vIENQUFRZUEVfQk9PTAorICAiZW51bSIsICAgICAgLy8gQ1BQVFlQRV9FTlVNCisgICJzdHJpbmciLCAgICAvLyBDUFBUWVBFX1NUUklORworICAibWVzc2FnZSIsICAgLy8gQ1BQVFlQRV9NRVNTQUdFCit9OworCitjb25zdCBjaGFyICogY29uc3QgRmllbGREZXNjcmlwdG9yOjprTGFiZWxUb05hbWVbTUFYX0xBQkVMICsgMV0gPSB7CisgICJFUlJPUiIsICAgICAvLyAwIGlzIHJlc2VydmVkIGZvciBlcnJvcnMKKworICAib3B0aW9uYWwiLCAgLy8gTEFCRUxfT1BUSU9OQUwKKyAgInJlcXVpcmVkIiwgIC8vIExBQkVMX1JFUVVJUkVECisgICJyZXBlYXRlZCIsICAvLyBMQUJFTF9SRVBFQVRFRAorfTsKKworY29uc3QgY2hhciogRmlsZURlc2NyaXB0b3I6OlN5bnRheE5hbWUoRmlsZURlc2NyaXB0b3I6OlN5bnRheCBzeW50YXgpIHsKKyAgc3dpdGNoIChzeW50YXgpIHsKKyAgICBjYXNlIFNZTlRBWF9QUk9UTzI6CisgICAgICByZXR1cm4gInByb3RvMiI7CisgICAgY2FzZSBTWU5UQVhfUFJPVE8zOgorICAgICAgcmV0dXJuICJwcm90bzMiOworICAgIGNhc2UgU1lOVEFYX1VOS05PV046CisgICAgICByZXR1cm4gInVua25vd24iOworICB9CisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJjYW4ndCByZWFjaCBoZXJlLiI7CisgIHJldHVybiBOVUxMOworfQorCitzdGF0aWMgY29uc3QgY2hhciAqIGNvbnN0IGtOb25MaW5rZWRXZWFrTWVzc2FnZVJlcGxhY2VtZW50TmFtZSA9ICJnb29nbGUucHJvdG9idWYuRW1wdHkiOworCisjaWYgIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKK2NvbnN0IGludCBGaWVsZERlc2NyaXB0b3I6OmtNYXhOdW1iZXI7Citjb25zdCBpbnQgRmllbGREZXNjcmlwdG9yOjprRmlyc3RSZXNlcnZlZE51bWJlcjsKK2NvbnN0IGludCBGaWVsZERlc2NyaXB0b3I6OmtMYXN0UmVzZXJ2ZWROdW1iZXI7CisjZW5kaWYKKworbmFtZXNwYWNlIHsKKworc3RyaW5nIFRvQ2FtZWxDYXNlKGNvbnN0IHN0cmluZyYgaW5wdXQsIGJvb2wgbG93ZXJfZmlyc3QpIHsKKyAgYm9vbCBjYXBpdGFsaXplX25leHQgPSAhbG93ZXJfZmlyc3Q7CisgIHN0cmluZyByZXN1bHQ7CisgIHJlc3VsdC5yZXNlcnZlKGlucHV0LnNpemUoKSk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbnB1dC5zaXplKCk7IGkrKykgeworICAgIGlmIChpbnB1dFtpXSA9PSAnXycpIHsKKyAgICAgIGNhcGl0YWxpemVfbmV4dCA9IHRydWU7CisgICAgfSBlbHNlIGlmIChjYXBpdGFsaXplX25leHQpIHsKKyAgICAgIC8vIE5vdGU6ICBJIGRpc3RydXN0IGN0eXBlLmggZHVlIHRvIGxvY2FsZXMuCisgICAgICBpZiAoJ2EnIDw9IGlucHV0W2ldICYmIGlucHV0W2ldIDw9ICd6JykgeworICAgICAgICByZXN1bHQucHVzaF9iYWNrKGlucHV0W2ldIC0gJ2EnICsgJ0EnKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJlc3VsdC5wdXNoX2JhY2soaW5wdXRbaV0pOworICAgICAgfQorICAgICAgY2FwaXRhbGl6ZV9uZXh0ID0gZmFsc2U7CisgICAgfSBlbHNlIHsKKyAgICAgIHJlc3VsdC5wdXNoX2JhY2soaW5wdXRbaV0pOworICAgIH0KKyAgfQorCisgIC8vIExvd2VyLWNhc2UgdGhlIGZpcnN0IGxldHRlci4KKyAgaWYgKGxvd2VyX2ZpcnN0ICYmICFyZXN1bHQuZW1wdHkoKSAmJiAnQScgPD0gcmVzdWx0WzBdICYmIHJlc3VsdFswXSA8PSAnWicpIHsKKyAgICAgIHJlc3VsdFswXSA9IHJlc3VsdFswXSAtICdBJyArICdhJzsKKyAgfQorCisgIHJldHVybiByZXN1bHQ7Cit9CisKKy8vIEEgRGVzY3JpcHRvclBvb2wgY29udGFpbnMgYSBidW5jaCBvZiBoYXNoX21hcHMgdG8gaW1wbGVtZW50IHRoZQorLy8gdmFyaW91cyBGaW5kKkJ5KigpIG1ldGhvZHMuICBTaW5jZSBoYXNodGFibGUgbG9va3VwcyBhcmUgTygxKSwgaXQncworLy8gbW9zdCBlZmZpY2llbnQgdG8gY29uc3RydWN0IGEgZml4ZWQgc2V0IG9mIGxhcmdlIGhhc2hfbWFwcyB1c2VkIGJ5CisvLyBhbGwgb2JqZWN0cyBpbiB0aGUgcG9vbCByYXRoZXIgdGhhbiBjb25zdHJ1Y3Qgb25lIG9yIG1vcmUgc21hbGwKKy8vIGhhc2hfbWFwcyBmb3IgZWFjaCBvYmplY3QuCisvLworLy8gVGhlIGtleXMgdG8gdGhlc2UgaGFzaF9tYXBzIGFyZSAocGFyZW50LCBuYW1lKSBvciAocGFyZW50LCBudW1iZXIpCisvLyBwYWlycy4gIFVuZm9ydHVuYXRlbHkgU1RMIGRvZXNuJ3QgcHJvdmlkZSBoYXNoIGZ1bmN0aW9ucyBmb3IgcGFpcjw+LAorLy8gc28gd2UgbXVzdCBpbnZlbnQgb3VyIG93bi4KKy8vCisvLyBUT0RPKGtlbnRvbik6ICBVc2UgU3RyaW5nUGllY2UgcmF0aGVyIHRoYW4gY29uc3QgY2hhciogaW4ga2V5cz8gIEl0IHdvdWxkCisvLyAgIGJlIGEgbG90IGNsZWFuZXIgYnV0IHdlJ2QganVzdCBoYXZlIHRvIGNvbnZlcnQgaXQgYmFjayB0byBjb25zdCBjaGFyKgorLy8gICBmb3IgdGhlIG9wZW4gc291cmNlIHJlbGVhc2UuCisKK3R5cGVkZWYgcGFpcjxjb25zdCB2b2lkKiwgY29uc3QgY2hhcio+IFBvaW50ZXJTdHJpbmdQYWlyOworCitzdHJ1Y3QgUG9pbnRlclN0cmluZ1BhaXJFcXVhbCB7CisgIGlubGluZSBib29sIG9wZXJhdG9yKCkoY29uc3QgUG9pbnRlclN0cmluZ1BhaXImIGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUG9pbnRlclN0cmluZ1BhaXImIGIpIGNvbnN0IHsKKyAgICByZXR1cm4gYS5maXJzdCA9PSBiLmZpcnN0ICYmIHN0cmNtcChhLnNlY29uZCwgYi5zZWNvbmQpID09IDA7CisgIH0KK307CisKK3RlbXBsYXRlPHR5cGVuYW1lIFBhaXJUeXBlPgorc3RydWN0IFBvaW50ZXJJbnRlZ2VyUGFpckhhc2ggeworICBzaXplX3Qgb3BlcmF0b3IoKShjb25zdCBQYWlyVHlwZSYgcCkgY29uc3QgeworICAgIC8vIEZJWE1FKGtlbnRvbik6ICBXaGF0IGlzIHRoZSBiZXN0IHdheSB0byBjb21wdXRlIHRoaXMgaGFzaD8gIEkgaGF2ZQorICAgIC8vIG5vIGlkZWEhICBUaGlzIHNlZW1zIGEgYml0IGJldHRlciB0aGFuIGFuIFhPUi4KKyAgICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxpbnRwdHJfdD4ocC5maXJzdCkgKiAoKDEgPDwgMTYpIC0gMSkgKyBwLnNlY29uZDsKKyAgfQorCisjaWZkZWYgX01TQ19WRVIKKyAgLy8gVXNlZCBvbmx5IGJ5IE1TVkMgYW5kIHBsYXRmb3JtcyB3aGVyZSBoYXNoX21hcCBpcyBub3QgYXZhaWxhYmxlLgorICBzdGF0aWMgY29uc3Qgc2l6ZV90IGJ1Y2tldF9zaXplID0gNDsKKyAgc3RhdGljIGNvbnN0IHNpemVfdCBtaW5fYnVja2V0cyA9IDg7CisjZW5kaWYKKyAgaW5saW5lIGJvb2wgb3BlcmF0b3IoKShjb25zdCBQYWlyVHlwZSYgYSwgY29uc3QgUGFpclR5cGUmIGIpIGNvbnN0IHsKKyAgICByZXR1cm4gYS5maXJzdCA8IGIuZmlyc3QgfHwKKyAgICAgICAgICAoYS5maXJzdCA9PSBiLmZpcnN0ICYmIGEuc2Vjb25kIDwgYi5zZWNvbmQpOworICB9Cit9OworCit0eXBlZGVmIHBhaXI8Y29uc3QgRGVzY3JpcHRvciosIGludD4gRGVzY3JpcHRvckludFBhaXI7Cit0eXBlZGVmIHBhaXI8Y29uc3QgRW51bURlc2NyaXB0b3IqLCBpbnQ+IEVudW1JbnRQYWlyOworCitzdHJ1Y3QgUG9pbnRlclN0cmluZ1BhaXJIYXNoIHsKKyAgc2l6ZV90IG9wZXJhdG9yKCkoY29uc3QgUG9pbnRlclN0cmluZ1BhaXImIHApIGNvbnN0IHsKKyAgICAvLyBGSVhNRShrZW50b24pOiAgV2hhdCBpcyB0aGUgYmVzdCB3YXkgdG8gY29tcHV0ZSB0aGlzIGhhc2g/ICBJIGhhdmUKKyAgICAvLyBubyBpZGVhISAgVGhpcyBzZWVtcyBhIGJpdCBiZXR0ZXIgdGhhbiBhbiBYT1IuCisgICAgaGFzaDxjb25zdCBjaGFyKj4gY3N0cmluZ19oYXNoOworICAgIHJldHVybiByZWludGVycHJldF9jYXN0PGludHB0cl90PihwLmZpcnN0KSAqICgoMSA8PCAxNikgLSAxKSArCisgICAgICAgICAgIGNzdHJpbmdfaGFzaChwLnNlY29uZCk7CisgIH0KKworI2lmZGVmIF9NU0NfVkVSCisgIC8vIFVzZWQgb25seSBieSBNU1ZDIGFuZCBwbGF0Zm9ybXMgd2hlcmUgaGFzaF9tYXAgaXMgbm90IGF2YWlsYWJsZS4KKyAgc3RhdGljIGNvbnN0IHNpemVfdCBidWNrZXRfc2l6ZSA9IDQ7CisgIHN0YXRpYyBjb25zdCBzaXplX3QgbWluX2J1Y2tldHMgPSA4OworI2VuZGlmCisgIGlubGluZSBib29sIG9wZXJhdG9yKCkoY29uc3QgUG9pbnRlclN0cmluZ1BhaXImIGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUG9pbnRlclN0cmluZ1BhaXImIGIpIGNvbnN0IHsKKyAgICBpZiAoYS5maXJzdCA8IGIuZmlyc3QpIHJldHVybiB0cnVlOworICAgIGlmIChhLmZpcnN0ID4gYi5maXJzdCkgcmV0dXJuIGZhbHNlOworICAgIHJldHVybiBzdHJjbXAoYS5zZWNvbmQsIGIuc2Vjb25kKSA8IDA7CisgIH0KK307CisKKworc3RydWN0IFN5bWJvbCB7CisgIGVudW0gVHlwZSB7CisgICAgTlVMTF9TWU1CT0wsIE1FU1NBR0UsIEZJRUxELCBPTkVPRiwgRU5VTSwgRU5VTV9WQUxVRSwgU0VSVklDRSwgTUVUSE9ELAorICAgIFBBQ0tBR0UKKyAgfTsKKyAgVHlwZSB0eXBlOworICB1bmlvbiB7CisgICAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcjsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkX2Rlc2NyaXB0b3I7CisgICAgY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBvbmVvZl9kZXNjcmlwdG9yOworICAgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBlbnVtX2Rlc2NyaXB0b3I7CisgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogZW51bV92YWx1ZV9kZXNjcmlwdG9yOworICAgIGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yKiBzZXJ2aWNlX2Rlc2NyaXB0b3I7CisgICAgY29uc3QgTWV0aG9kRGVzY3JpcHRvciogbWV0aG9kX2Rlc2NyaXB0b3I7CisgICAgY29uc3QgRmlsZURlc2NyaXB0b3IqIHBhY2thZ2VfZmlsZV9kZXNjcmlwdG9yOworICB9OworCisgIGlubGluZSBTeW1ib2woKSA6IHR5cGUoTlVMTF9TWU1CT0wpIHsgZGVzY3JpcHRvciA9IE5VTEw7IH0KKyAgaW5saW5lIGJvb2wgSXNOdWxsKCkgY29uc3QgeyByZXR1cm4gdHlwZSA9PSBOVUxMX1NZTUJPTDsgfQorICBpbmxpbmUgYm9vbCBJc1R5cGUoKSBjb25zdCB7CisgICAgcmV0dXJuIHR5cGUgPT0gTUVTU0FHRSB8fCB0eXBlID09IEVOVU07CisgIH0KKyAgaW5saW5lIGJvb2wgSXNBZ2dyZWdhdGUoKSBjb25zdCB7CisgICAgcmV0dXJuIHR5cGUgPT0gTUVTU0FHRSB8fCB0eXBlID09IFBBQ0tBR0UKKyAgICAgICAgfHwgdHlwZSA9PSBFTlVNIHx8IHR5cGUgPT0gU0VSVklDRTsKKyAgfQorCisjZGVmaW5lIENPTlNUUlVDVE9SKFRZUEUsIFRZUEVfQ09OU1RBTlQsIEZJRUxEKSAgXAorICBpbmxpbmUgZXhwbGljaXQgU3ltYm9sKGNvbnN0IFRZUEUqIHZhbHVlKSB7ICAgIFwKKyAgICB0eXBlID0gVFlQRV9DT05TVEFOVDsgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgdGhpcy0+RklFTEQgPSB2YWx1ZTsgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9CisKKyAgQ09OU1RSVUNUT1IoRGVzY3JpcHRvciAgICAgICAgICwgTUVTU0FHRSAgICwgZGVzY3JpcHRvciAgICAgICAgICAgICApCisgIENPTlNUUlVDVE9SKEZpZWxkRGVzY3JpcHRvciAgICAsIEZJRUxEICAgICAsIGZpZWxkX2Rlc2NyaXB0b3IgICAgICAgKQorICBDT05TVFJVQ1RPUihPbmVvZkRlc2NyaXB0b3IgICAgLCBPTkVPRiAgICAgLCBvbmVvZl9kZXNjcmlwdG9yICAgICAgICkKKyAgQ09OU1RSVUNUT1IoRW51bURlc2NyaXB0b3IgICAgICwgRU5VTSAgICAgICwgZW51bV9kZXNjcmlwdG9yICAgICAgICApCisgIENPTlNUUlVDVE9SKEVudW1WYWx1ZURlc2NyaXB0b3IsIEVOVU1fVkFMVUUsIGVudW1fdmFsdWVfZGVzY3JpcHRvciAgKQorICBDT05TVFJVQ1RPUihTZXJ2aWNlRGVzY3JpcHRvciAgLCBTRVJWSUNFICAgLCBzZXJ2aWNlX2Rlc2NyaXB0b3IgICAgICkKKyAgQ09OU1RSVUNUT1IoTWV0aG9kRGVzY3JpcHRvciAgICwgTUVUSE9EICAgICwgbWV0aG9kX2Rlc2NyaXB0b3IgICAgICApCisgIENPTlNUUlVDVE9SKEZpbGVEZXNjcmlwdG9yICAgICAsIFBBQ0tBR0UgICAsIHBhY2thZ2VfZmlsZV9kZXNjcmlwdG9yKQorI3VuZGVmIENPTlNUUlVDVE9SCisKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIEdldEZpbGUoKSBjb25zdCB7CisgICAgc3dpdGNoICh0eXBlKSB7CisgICAgICBjYXNlIE5VTExfU1lNQk9MOiByZXR1cm4gTlVMTDsKKyAgICAgIGNhc2UgTUVTU0FHRSAgICA6IHJldHVybiBkZXNjcmlwdG9yICAgICAgICAgICAtPmZpbGUoKTsKKyAgICAgIGNhc2UgRklFTEQgICAgICA6IHJldHVybiBmaWVsZF9kZXNjcmlwdG9yICAgICAtPmZpbGUoKTsKKyAgICAgIGNhc2UgT05FT0YgICAgICA6IHJldHVybiBvbmVvZl9kZXNjcmlwdG9yICAgICAtPmNvbnRhaW5pbmdfdHlwZSgpLT5maWxlKCk7CisgICAgICBjYXNlIEVOVU0gICAgICAgOiByZXR1cm4gZW51bV9kZXNjcmlwdG9yICAgICAgLT5maWxlKCk7CisgICAgICBjYXNlIEVOVU1fVkFMVUUgOiByZXR1cm4gZW51bV92YWx1ZV9kZXNjcmlwdG9yLT50eXBlKCktPmZpbGUoKTsKKyAgICAgIGNhc2UgU0VSVklDRSAgICA6IHJldHVybiBzZXJ2aWNlX2Rlc2NyaXB0b3IgICAtPmZpbGUoKTsKKyAgICAgIGNhc2UgTUVUSE9EICAgICA6IHJldHVybiBtZXRob2RfZGVzY3JpcHRvciAgICAtPnNlcnZpY2UoKS0+ZmlsZSgpOworICAgICAgY2FzZSBQQUNLQUdFICAgIDogcmV0dXJuIHBhY2thZ2VfZmlsZV9kZXNjcmlwdG9yOworICAgIH0KKyAgICByZXR1cm4gTlVMTDsKKyAgfQorfTsKKworY29uc3QgU3ltYm9sIGtOdWxsU3ltYm9sOworCit0eXBlZGVmIGhhc2hfbWFwPGNvbnN0IGNoYXIqLCBTeW1ib2wsCisgICAgICAgICAgICAgICAgIGhhc2g8Y29uc3QgY2hhcio+LCBzdHJlcT4KKyAgU3ltYm9sc0J5TmFtZU1hcDsKK3R5cGVkZWYgaGFzaF9tYXA8UG9pbnRlclN0cmluZ1BhaXIsIFN5bWJvbCwKKyAgICAgICAgICAgICAgICAgUG9pbnRlclN0cmluZ1BhaXJIYXNoLCBQb2ludGVyU3RyaW5nUGFpckVxdWFsPgorICBTeW1ib2xzQnlQYXJlbnRNYXA7Cit0eXBlZGVmIGhhc2hfbWFwPGNvbnN0IGNoYXIqLCBjb25zdCBGaWxlRGVzY3JpcHRvciosCisgICAgICAgICAgICAgICAgIGhhc2g8Y29uc3QgY2hhcio+LCBzdHJlcT4KKyAgRmlsZXNCeU5hbWVNYXA7Cit0eXBlZGVmIGhhc2hfbWFwPFBvaW50ZXJTdHJpbmdQYWlyLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqLAorICAgICAgICAgICAgICAgICBQb2ludGVyU3RyaW5nUGFpckhhc2gsIFBvaW50ZXJTdHJpbmdQYWlyRXF1YWw+CisgIEZpZWxkc0J5TmFtZU1hcDsKK3R5cGVkZWYgaGFzaF9tYXA8RGVzY3JpcHRvckludFBhaXIsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciosCisgICAgICAgICAgICAgICAgIFBvaW50ZXJJbnRlZ2VyUGFpckhhc2g8RGVzY3JpcHRvckludFBhaXI+ID4KKyAgRmllbGRzQnlOdW1iZXJNYXA7Cit0eXBlZGVmIGhhc2hfbWFwPEVudW1JbnRQYWlyLCBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiwKKyAgICAgICAgICAgICAgICAgUG9pbnRlckludGVnZXJQYWlySGFzaDxFbnVtSW50UGFpcj4gPgorICBFbnVtVmFsdWVzQnlOdW1iZXJNYXA7CisvLyBUaGlzIGlzIGEgbWFwIHJhdGhlciB0aGFuIGEgaGFzaF9tYXAsIHNpbmNlIHdlIHVzZSBpdCB0byBpdGVyYXRlCisvLyB0aHJvdWdoIGFsbCB0aGUgZXh0ZW5zaW9ucyB0aGF0IGV4dGVuZCBhIGdpdmVuIERlc2NyaXB0b3IsIGFuZCBhbgorLy8gb3JkZXJlZCBkYXRhIHN0cnVjdHVyZSB0aGF0IGltcGxlbWVudHMgbG93ZXJfYm91bmQgaXMgY29udmVuaWVudAorLy8gZm9yIHRoYXQuCit0eXBlZGVmIG1hcDxEZXNjcmlwdG9ySW50UGFpciwgY29uc3QgRmllbGREZXNjcmlwdG9yKj4KKyAgRXh0ZW5zaW9uc0dyb3VwZWRCeURlc2NyaXB0b3JNYXA7Cit0eXBlZGVmIGhhc2hfbWFwPHN0cmluZywgY29uc3QgU291cmNlQ29kZUluZm9fTG9jYXRpb24qPiBMb2NhdGlvbnNCeVBhdGhNYXA7CisKK3NldDxzdHJpbmc+KiBhbGxvd2VkX3Byb3RvM19leHRlbmRlZXNfID0gTlVMTDsKK0dPT0dMRV9QUk9UT0JVRl9ERUNMQVJFX09OQ0UoYWxsb3dlZF9wcm90bzNfZXh0ZW5kZWVzX2luaXRfKTsKKwordm9pZCBEZWxldGVBbGxvd2VkUHJvdG8zRXh0ZW5kZWUoKSB7CisgIGRlbGV0ZSBhbGxvd2VkX3Byb3RvM19leHRlbmRlZXNfOworfQorCit2b2lkIEluaXRBbGxvd2VkUHJvdG8zRXh0ZW5kZWUoKSB7CisgIGFsbG93ZWRfcHJvdG8zX2V4dGVuZGVlc18gPSBuZXcgc2V0PHN0cmluZz47CisgIGFsbG93ZWRfcHJvdG8zX2V4dGVuZGVlc18tPmluc2VydCgiZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zIik7CisgIGFsbG93ZWRfcHJvdG8zX2V4dGVuZGVlc18tPmluc2VydCgiZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zIik7CisgIGFsbG93ZWRfcHJvdG8zX2V4dGVuZGVlc18tPmluc2VydCgiZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucyIpOworICBhbGxvd2VkX3Byb3RvM19leHRlbmRlZXNfLT5pbnNlcnQoImdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucyIpOworICBhbGxvd2VkX3Byb3RvM19leHRlbmRlZXNfLT5pbnNlcnQoImdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVPcHRpb25zIik7CisgIGFsbG93ZWRfcHJvdG8zX2V4dGVuZGVlc18tPmluc2VydCgiZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zIik7CisgIGFsbG93ZWRfcHJvdG8zX2V4dGVuZGVlc18tPmluc2VydCgiZ29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMiKTsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6Ok9uU2h1dGRvd24oJkRlbGV0ZUFsbG93ZWRQcm90bzNFeHRlbmRlZSk7Cit9CisKKy8vIENoZWNrcyB3aGV0aGVyIHRoZSBleHRlbmRlZSB0eXBlIGlzIGFsbG93ZWQgaW4gcHJvdG8zLgorLy8gT25seSBleHRlbnNpb25zIHRvIGRlc2NyaXB0b3Igb3B0aW9ucyBhcmUgYWxsb3dlZC4gV2UgdXNlIG5hbWUgY29tcGFyaXNvbgorLy8gaW5zdGVhZCBvZiBjb21wYXJpbmcgdGhlIGRlc2NyaXB0b3IgZGlyZWN0bHkgYmVjYXVzZSB0aGUgZXh0ZW5zaW9ucyBtYXkgYmUKKy8vIGRlZmluZWQgaW4gYSBkaWZmZXJlbnQgcG9vbC4KK2Jvb2wgQWxsb3dlZEV4dGVuZGVlSW5Qcm90bzMoY29uc3Qgc3RyaW5nJiBuYW1lKSB7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6R29vZ2xlT25jZUluaXQoJmFsbG93ZWRfcHJvdG8zX2V4dGVuZGVlc19pbml0XywgJkluaXRBbGxvd2VkUHJvdG8zRXh0ZW5kZWUpOworICByZXR1cm4gYWxsb3dlZF9wcm90bzNfZXh0ZW5kZWVzXy0+ZmluZChuYW1lKSAhPQorICAgICAgICAgYWxsb3dlZF9wcm90bzNfZXh0ZW5kZWVzXy0+ZW5kKCk7Cit9CisKK30gIC8vIGFub255bW91cyBuYW1lc3BhY2UKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorLy8gRGVzY3JpcHRvclBvb2w6OlRhYmxlcworCitjbGFzcyBEZXNjcmlwdG9yUG9vbDo6VGFibGVzIHsKKyBwdWJsaWM6CisgIFRhYmxlcygpOworICB+VGFibGVzKCk7CisKKyAgLy8gUmVjb3JkIHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSB0YWJsZXMgdG8gdGhlIHN0YWNrIG9mIGNoZWNrcG9pbnRzLgorICAvLyBFYWNoIGNhbGwgdG8gQWRkQ2hlY2twb2ludCgpIG11c3QgYmUgcGFpcmVkIHdpdGggZXhhY3RseSBvbmUgY2FsbCB0byBlaXRoZXIKKyAgLy8gQ2xlYXJMYXN0Q2hlY2twb2ludCgpIG9yIFJvbGxiYWNrVG9MYXN0Q2hlY2twb2ludCgpLgorICAvLworICAvLyBUaGlzIGlzIHVzZWQgd2hlbiBidWlsZGluZyBmaWxlcywgc2luY2Ugc29tZSBraW5kcyBvZiB2YWxpZGF0aW9uIGVycm9ycworICAvLyBjYW5ub3QgYmUgZGV0ZWN0ZWQgdW50aWwgdGhlIGZpbGUncyBkZXNjcmlwdG9ycyBoYXZlIGFscmVhZHkgYmVlbiBhZGRlZCB0bworICAvLyB0aGUgdGFibGVzLgorICAvLworICAvLyBUaGlzIHN1cHBvcnRzIHJlY3Vyc2l2ZSBjaGVja3BvaW50cywgc2luY2UgYnVpbGRpbmcgYSBmaWxlIG1heSB0cmlnZ2VyCisgIC8vIHJlY3Vyc2l2ZSBidWlsZGluZyBvZiBvdGhlciBmaWxlcy4gTm90ZSB0aGF0IHJlY3Vyc2l2ZSBjaGVja3BvaW50cyBhcmUgbm90CisgIC8vIG5vcm1hbGx5IG5lY2Vzc2FyeTsgZXhwbGljaXQgZGVwZW5kZW5jaWVzIGFyZSBidWlsdCBwcmlvciB0byBjaGVja3BvaW50aW5nLgorICAvLyBTbyBhbHRob3VnaCB3ZSByZWN1cnNpdmVseSBidWlsZCB0cmFuc2l0aXZlIGltcG9ydHMsIHRoZXJlIGlzIGF0IG1vc3Qgb25lCisgIC8vIGNoZWNrcG9pbnQgaW4gdGhlIHN0YWNrIGR1cmluZyBkZXBlbmRlbmN5IGJ1aWxkaW5nLgorICAvLworICAvLyBSZWN1cnNpdmUgY2hlY2twb2ludHMgb25seSBhcmlzZSBkdXJpbmcgY3Jvc3MtbGlua2luZyBvZiB0aGUgZGVzY3JpcHRvcnMuCisgIC8vIFN5bWJvbCByZWZlcmVuY2VzIG11c3QgYmUgcmVzb2x2ZWQsIHZpYSBEZXNjcmlwdG9yQnVpbGRlcjo6RmluZFN5bWJvbCBhbmQKKyAgLy8gZnJpZW5kcy4gSWYgdGhlIHBlbmRpbmcgZmlsZSByZWZlcmVuY2VzIGFuIHVua25vd24gc3ltYm9sCisgIC8vIChlLmcuLCBpdCBpcyBub3QgZGVmaW5lZCBpbiB0aGUgcGVuZGluZyBmaWxlJ3MgZXhwbGljaXQgZGVwZW5kZW5jaWVzKSwgYW5kCisgIC8vIHRoZSBwb29sIGlzIHVzaW5nIGEgZmFsbGJhY2sgZGF0YWJhc2UsIGFuZCB0aGF0IGRhdGFiYXNlIGNvbnRhaW5zIGEgZmlsZQorICAvLyBkZWZpbmluZyB0aGF0IHN5bWJvbCwgYW5kIHRoYXQgZmlsZSBoYXMgbm90IHlldCBiZWVuIGJ1aWx0IGJ5IHRoZSBwb29sLAorICAvLyB0aGUgcG9vbCBidWlsZHMgdGhlIGZpbGUgZHVyaW5nIGNyb3NzLWxpbmtpbmcsIGxlYWRpbmcgdG8gYW5vdGhlcgorICAvLyBjaGVja3BvaW50LgorICB2b2lkIEFkZENoZWNrcG9pbnQoKTsKKworICAvLyBNYXJrIHRoZSBsYXN0IGNoZWNrcG9pbnQgYXMgaGF2aW5nIGNsZWFyZWQgc3VjY2Vzc2Z1bGx5LCByZW1vdmluZyBpdCBmcm9tCisgIC8vIHRoZSBzdGFjay4gSWYgdGhlIHN0YWNrIGlzIGVtcHR5LCBhbGwgcGVuZGluZyBzeW1ib2xzIHdpbGwgYmUgY29tbWl0dGVkLgorICAvLworICAvLyBOb3RlIHRoYXQgdGhpcyBkb2VzIG5vdCBndWFyYW50ZWUgdGhhdCB0aGUgc3ltYm9scyBhZGRlZCBzaW5jZSB0aGUgbGFzdAorICAvLyBjaGVja3BvaW50IHdvbid0IGJlIHJvbGxlZCBiYWNrOiBpZiBhIGNoZWNrcG9pbnQgZ2V0cyByb2xsZWQgYmFjaywKKyAgLy8gZXZlcnl0aGluZyBwYXN0IHRoYXQgcG9pbnQgZ2V0cyByb2xsZWQgYmFjaywgaW5jbHVkaW5nIHN5bWJvbHMgYWRkZWQgYWZ0ZXIKKyAgLy8gY2hlY2twb2ludHMgdGhhdCB3ZXJlIHB1c2hlZCBvbnRvIHRoZSBzdGFjayBhZnRlciBpdCBhbmQgbWFya2VkIGFzIGNsZWFyZWQuCisgIHZvaWQgQ2xlYXJMYXN0Q2hlY2twb2ludCgpOworCisgIC8vIFJvbGwgYmFjayB0aGUgVGFibGVzIHRvIHRoZSBzdGF0ZSBvZiB0aGUgY2hlY2twb2ludCBhdCB0aGUgdG9wIG9mIHRoZQorICAvLyBzdGFjaywgcmVtb3ZpbmcgZXZlcnl0aGluZyB0aGF0IHdhcyBhZGRlZCBhZnRlciB0aGF0IHBvaW50LgorICB2b2lkIFJvbGxiYWNrVG9MYXN0Q2hlY2twb2ludCgpOworCisgIC8vIFRoZSBzdGFjayBvZiBmaWxlcyB3aGljaCBhcmUgY3VycmVudGx5IGJlaW5nIGJ1aWx0LiAgVXNlZCB0byBkZXRlY3QKKyAgLy8gY3ljbGljIGRlcGVuZGVuY2llcyB3aGVuIGxvYWRpbmcgZmlsZXMgZnJvbSBhIERlc2NyaXB0b3JEYXRhYmFzZS4gIE5vdAorICAvLyB1c2VkIHdoZW4gZmFsbGJhY2tfZGF0YWJhc2VfID09IE5VTEwuCisgIHZlY3RvcjxzdHJpbmc+IHBlbmRpbmdfZmlsZXNfOworCisgIC8vIEEgc2V0IG9mIGZpbGVzIHdoaWNoIHdlIGhhdmUgdHJpZWQgdG8gbG9hZCBmcm9tIHRoZSBmYWxsYmFjayBkYXRhYmFzZQorICAvLyBhbmQgZW5jb3VudGVyZWQgZXJyb3JzLiAgV2Ugd2lsbCBub3QgYXR0ZW1wdCB0byBsb2FkIHRoZW0gYWdhaW4gZHVyaW5nCisgIC8vIGV4ZWN1dGlvbiBvZiB0aGUgY3VycmVudCBwdWJsaWMgQVBJIGNhbGwsIGJ1dCBmb3IgY29tcGF0aWJpbGl0eSB3aXRoCisgIC8vIGxlZ2FjeSBjbGllbnRzLCB0aGlzIGlzIGNsZWFyZWQgYXQgdGhlIGJlZ2lubmluZyBvZiBlYWNoIHB1YmxpYyBBUEkgY2FsbC4KKyAgLy8gTm90IHVzZWQgd2hlbiBmYWxsYmFja19kYXRhYmFzZV8gPT0gTlVMTC4KKyAgaGFzaF9zZXQ8c3RyaW5nPiBrbm93bl9iYWRfZmlsZXNfOworCisgIC8vIEEgc2V0IG9mIHN5bWJvbHMgd2hpY2ggd2UgaGF2ZSB0cmllZCB0byBsb2FkIGZyb20gdGhlIGZhbGxiYWNrIGRhdGFiYXNlCisgIC8vIGFuZCBlbmNvdW50ZXJlZCBlcnJvcnMuIFdlIHdpbGwgbm90IGF0dGVtcHQgdG8gbG9hZCB0aGVtIGFnYWluIGR1cmluZworICAvLyBleGVjdXRpb24gb2YgdGhlIGN1cnJlbnQgcHVibGljIEFQSSBjYWxsLCBidXQgZm9yIGNvbXBhdGliaWxpdHkgd2l0aAorICAvLyBsZWdhY3kgY2xpZW50cywgdGhpcyBpcyBjbGVhcmVkIGF0IHRoZSBiZWdpbm5pbmcgb2YgZWFjaCBwdWJsaWMgQVBJIGNhbGwuCisgIGhhc2hfc2V0PHN0cmluZz4ga25vd25fYmFkX3N5bWJvbHNfOworCisgIC8vIFRoZSBzZXQgb2YgZGVzY3JpcHRvcnMgZm9yIHdoaWNoIHdlJ3ZlIGFscmVhZHkgbG9hZGVkIHRoZSBmdWxsCisgIC8vIHNldCBvZiBleHRlbnNpb25zIG51bWJlcnMgZnJvbSBmYWxsYmFja19kYXRhYmFzZV8uCisgIGhhc2hfc2V0PGNvbnN0IERlc2NyaXB0b3IqPiBleHRlbnNpb25zX2xvYWRlZF9mcm9tX2RiXzsKKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAvLyBGaW5kaW5nIGl0ZW1zLgorCisgIC8vIEZpbmQgc3ltYm9scy4gIFRoaXMgcmV0dXJucyBhIG51bGwgU3ltYm9sIChzeW1ib2wuSXNOdWxsKCkgaXMgdHJ1ZSkKKyAgLy8gaWYgbm90IGZvdW5kLgorICBpbmxpbmUgU3ltYm9sIEZpbmRTeW1ib2woY29uc3Qgc3RyaW5nJiBrZXkpIGNvbnN0OworCisgIC8vIFRoaXMgaW1wbGVtZW50cyB0aGUgYm9keSBvZiBEZXNjcmlwdG9yUG9vbDo6RmluZCpCeU5hbWUoKS4gIEl0IHNob3VsZAorICAvLyByZWFsbHkgYmUgYSBwcml2YXRlIG1ldGhvZCBvZiBEZXNjcmlwdG9yUG9vbCwgYnV0IHRoYXQgd291bGQgcmVxdWlyZQorICAvLyBkZWNsYXJpbmcgU3ltYm9sIGluIGRlc2NyaXB0b3IuaCwgd2hpY2ggd291bGQgZHJhZyBhbGwga2luZHMgb2Ygb3RoZXIKKyAgLy8gc3R1ZmYgaW50byB0aGUgaGVhZGVyLiAgWWF5IEMrKy4KKyAgU3ltYm9sIEZpbmRCeU5hbWVIZWxwZXIoCisgICAgY29uc3QgRGVzY3JpcHRvclBvb2wqIHBvb2wsIGNvbnN0IHN0cmluZyYgbmFtZSk7CisKKyAgLy8gVGhlc2UgcmV0dXJuIE5VTEwgaWYgbm90IGZvdW5kLgorICBpbmxpbmUgY29uc3QgRmlsZURlc2NyaXB0b3IqIEZpbmRGaWxlKGNvbnN0IHN0cmluZyYga2V5KSBjb25zdDsKKyAgaW5saW5lIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogRmluZEV4dGVuc2lvbihjb25zdCBEZXNjcmlwdG9yKiBleHRlbmRlZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbnVtYmVyKTsKKyAgaW5saW5lIHZvaWQgRmluZEFsbEV4dGVuc2lvbnMoY29uc3QgRGVzY3JpcHRvciogZXh0ZW5kZWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiogb3V0KSBjb25zdDsKKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAvLyBBZGRpbmcgaXRlbXMuCisKKyAgLy8gVGhlc2UgYWRkIGl0ZW1zIHRvIHRoZSBjb3JyZXNwb25kaW5nIHRhYmxlcy4gIFRoZXkgcmV0dXJuIGZhbHNlIGlmCisgIC8vIHRoZSBrZXkgYWxyZWFkeSBleGlzdHMgaW4gdGhlIHRhYmxlLiAgRm9yIEFkZFN5bWJvbCgpLCB0aGUgc3RyaW5nIHBhc3NlZAorICAvLyBpbiBtdXN0IGJlIG9uZSB0aGF0IHdhcyBjb25zdHJ1Y3RlZCB1c2luZyBBbGxvY2F0ZVN0cmluZygpLCBhcyBpdCB3aWxsCisgIC8vIGJlIHVzZWQgYXMgYSBrZXkgaW4gdGhlIHN5bWJvbHNfYnlfbmFtZV8gbWFwIHdpdGhvdXQgY29weWluZy4KKyAgYm9vbCBBZGRTeW1ib2woY29uc3Qgc3RyaW5nJiBmdWxsX25hbWUsIFN5bWJvbCBzeW1ib2wpOworICBib29sIEFkZEZpbGUoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUpOworICBib29sIEFkZEV4dGVuc2lvbihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKTsKKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAvLyBBbGxvY2F0aW5nIG1lbW9yeS4KKworICAvLyBBbGxvY2F0ZSBhbiBvYmplY3Qgd2hpY2ggd2lsbCBiZSByZWNsYWltZWQgd2hlbiB0aGUgcG9vbCBpcworICAvLyBkZXN0cm95ZWQuICBOb3RlIHRoYXQgdGhlIG9iamVjdCdzIGRlc3RydWN0b3Igd2lsbCBuZXZlciBiZSBjYWxsZWQsCisgIC8vIHNvIGl0cyBmaWVsZHMgbXVzdCBiZSBwbGFpbiBvbGQgZGF0YSAocHJpbWl0aXZlIGRhdGEgdHlwZXMgYW5kCisgIC8vIHBvaW50ZXJzKS4gIEFsbCBvZiB0aGUgZGVzY3JpcHRvciB0eXBlcyBhcmUgc3VjaCBvYmplY3RzLgorICB0ZW1wbGF0ZTx0eXBlbmFtZSBUeXBlPiBUeXBlKiBBbGxvY2F0ZSgpOworCisgIC8vIEFsbG9jYXRlIGFuIGFycmF5IG9mIG9iamVjdHMgd2hpY2ggd2lsbCBiZSByZWNsYWltZWQgd2hlbiB0aGUKKyAgLy8gcG9vbCBpbiBkZXN0cm95ZWQuICBBZ2FpbiwgZGVzdHJ1Y3RvcnMgYXJlIG5ldmVyIGNhbGxlZC4KKyAgdGVtcGxhdGU8dHlwZW5hbWUgVHlwZT4gVHlwZSogQWxsb2NhdGVBcnJheShpbnQgY291bnQpOworCisgIC8vIEFsbG9jYXRlIGEgc3RyaW5nIHdoaWNoIHdpbGwgYmUgZGVzdHJveWVkIHdoZW4gdGhlIHBvb2wgaXMgZGVzdHJveWVkLgorICAvLyBUaGUgc3RyaW5nIGlzIGluaXRpYWxpemVkIHRvIHRoZSBnaXZlbiB2YWx1ZSBmb3IgY29udmVuaWVuY2UuCisgIHN0cmluZyogQWxsb2NhdGVTdHJpbmcoY29uc3Qgc3RyaW5nJiB2YWx1ZSk7CisKKyAgLy8gQWxsb2NhdGUgYSBwcm90b2NvbCBtZXNzYWdlIG9iamVjdC4gIFNvbWUgb2xkZXIgdmVyc2lvbnMgb2YgR0NDIGhhdmUKKyAgLy8gdHJvdWJsZSB1bmRlcnN0YW5kaW5nIGV4cGxpY2l0IHRlbXBsYXRlIGluc3RhbnRpYXRpb25zIGluIHNvbWUgY2FzZXMsIHNvCisgIC8vIGluIHRob3NlIGNhc2VzIHdlIGhhdmUgdG8gcGFzcyBhIGR1bW15IHBvaW50ZXIgb2YgdGhlIHJpZ2h0IHR5cGUgYXMgdGhlCisgIC8vIHBhcmFtZXRlciBpbnN0ZWFkIG9mIHNwZWNpZnlpbmcgdGhlIHR5cGUgZXhwbGljaXRseS4KKyAgdGVtcGxhdGU8dHlwZW5hbWUgVHlwZT4gVHlwZSogQWxsb2NhdGVNZXNzYWdlKFR5cGUqIGR1bW15ID0gTlVMTCk7CisKKyAgLy8gQWxsb2NhdGUgYSBGaWxlRGVzY3JpcHRvclRhYmxlcyBvYmplY3QuCisgIEZpbGVEZXNjcmlwdG9yVGFibGVzKiBBbGxvY2F0ZUZpbGVUYWJsZXMoKTsKKworIHByaXZhdGU6CisgIHZlY3RvcjxzdHJpbmcqPiBzdHJpbmdzXzsgICAgLy8gQWxsIHN0cmluZ3MgaW4gdGhlIHBvb2wuCisgIHZlY3RvcjxNZXNzYWdlKj4gbWVzc2FnZXNfOyAgLy8gQWxsIG1lc3NhZ2VzIGluIHRoZSBwb29sLgorICB2ZWN0b3I8RmlsZURlc2NyaXB0b3JUYWJsZXMqPiBmaWxlX3RhYmxlc187ICAvLyBBbGwgZmlsZSB0YWJsZXMgaW4gdGhlIHBvb2wuCisgIHZlY3Rvcjx2b2lkKj4gYWxsb2NhdGlvbnNfOyAgLy8gQWxsIG90aGVyIG1lbW9yeSBhbGxvY2F0ZWQgaW4gdGhlIHBvb2wuCisKKyAgU3ltYm9sc0J5TmFtZU1hcCAgICAgIHN5bWJvbHNfYnlfbmFtZV87CisgIEZpbGVzQnlOYW1lTWFwICAgICAgICBmaWxlc19ieV9uYW1lXzsKKyAgRXh0ZW5zaW9uc0dyb3VwZWRCeURlc2NyaXB0b3JNYXAgZXh0ZW5zaW9uc187CisKKyAgc3RydWN0IENoZWNrUG9pbnQgeworICAgIGV4cGxpY2l0IENoZWNrUG9pbnQoY29uc3QgVGFibGVzKiB0YWJsZXMpCisgICAgICA6IHN0cmluZ3NfYmVmb3JlX2NoZWNrcG9pbnQodGFibGVzLT5zdHJpbmdzXy5zaXplKCkpLAorICAgICAgICBtZXNzYWdlc19iZWZvcmVfY2hlY2twb2ludCh0YWJsZXMtPm1lc3NhZ2VzXy5zaXplKCkpLAorICAgICAgICBmaWxlX3RhYmxlc19iZWZvcmVfY2hlY2twb2ludCh0YWJsZXMtPmZpbGVfdGFibGVzXy5zaXplKCkpLAorICAgICAgICBhbGxvY2F0aW9uc19iZWZvcmVfY2hlY2twb2ludCh0YWJsZXMtPmFsbG9jYXRpb25zXy5zaXplKCkpLAorICAgICAgICBwZW5kaW5nX3N5bWJvbHNfYmVmb3JlX2NoZWNrcG9pbnQoCisgICAgICAgICAgICB0YWJsZXMtPnN5bWJvbHNfYWZ0ZXJfY2hlY2twb2ludF8uc2l6ZSgpKSwKKyAgICAgICAgcGVuZGluZ19maWxlc19iZWZvcmVfY2hlY2twb2ludCgKKyAgICAgICAgICAgIHRhYmxlcy0+ZmlsZXNfYWZ0ZXJfY2hlY2twb2ludF8uc2l6ZSgpKSwKKyAgICAgICAgcGVuZGluZ19leHRlbnNpb25zX2JlZm9yZV9jaGVja3BvaW50KAorICAgICAgICAgICAgdGFibGVzLT5leHRlbnNpb25zX2FmdGVyX2NoZWNrcG9pbnRfLnNpemUoKSkgeworICAgIH0KKyAgICBpbnQgc3RyaW5nc19iZWZvcmVfY2hlY2twb2ludDsKKyAgICBpbnQgbWVzc2FnZXNfYmVmb3JlX2NoZWNrcG9pbnQ7CisgICAgaW50IGZpbGVfdGFibGVzX2JlZm9yZV9jaGVja3BvaW50OworICAgIGludCBhbGxvY2F0aW9uc19iZWZvcmVfY2hlY2twb2ludDsKKyAgICBpbnQgcGVuZGluZ19zeW1ib2xzX2JlZm9yZV9jaGVja3BvaW50OworICAgIGludCBwZW5kaW5nX2ZpbGVzX2JlZm9yZV9jaGVja3BvaW50OworICAgIGludCBwZW5kaW5nX2V4dGVuc2lvbnNfYmVmb3JlX2NoZWNrcG9pbnQ7CisgIH07CisgIHZlY3RvcjxDaGVja1BvaW50PiBjaGVja3BvaW50c187CisgIHZlY3Rvcjxjb25zdCBjaGFyKiAgICAgID4gc3ltYm9sc19hZnRlcl9jaGVja3BvaW50XzsKKyAgdmVjdG9yPGNvbnN0IGNoYXIqICAgICAgPiBmaWxlc19hZnRlcl9jaGVja3BvaW50XzsKKyAgdmVjdG9yPERlc2NyaXB0b3JJbnRQYWlyPiBleHRlbnNpb25zX2FmdGVyX2NoZWNrcG9pbnRfOworCisgIC8vIEFsbG9jYXRlIHNvbWUgYnl0ZXMgd2hpY2ggd2lsbCBiZSByZWNsYWltZWQgd2hlbiB0aGUgcG9vbCBpcworICAvLyBkZXN0cm95ZWQuCisgIHZvaWQqIEFsbG9jYXRlQnl0ZXMoaW50IHNpemUpOworfTsKKworLy8gQ29udGFpbnMgdGFibGVzIHNwZWNpZmljIHRvIGEgcGFydGljdWxhciBmaWxlLiAgVGhlc2UgdGFibGVzIGFyZSBub3QKKy8vIG1vZGlmaWVkIG9uY2UgdGhlIGZpbGUgaGFzIGJlZW4gY29uc3RydWN0ZWQsIHNvIHRoZXkgbmVlZCBub3QgYmUKKy8vIHByb3RlY3RlZCBieSBhIG11dGV4LiAgVGhpcyBtYWtlcyBvcGVyYXRpb25zIHRoYXQgZGVwZW5kIG9ubHkgb24gdGhlCisvLyBjb250ZW50cyBvZiBhIHNpbmdsZSBmaWxlIC0tIGUuZy4gRGVzY3JpcHRvcjo6RmluZEZpZWxkQnlOYW1lKCkgLS0KKy8vIGxvY2stZnJlZS4KKy8vCisvLyBGb3IgaGlzdG9yaWNhbCByZWFzb25zLCB0aGUgZGVmaW5pdGlvbnMgb2YgdGhlIG1ldGhvZHMgb2YKKy8vIEZpbGVEZXNjcmlwdG9yVGFibGVzIGFuZCBEZXNjcmlwdG9yUG9vbDo6VGFibGVzIGFyZSBpbnRlcmxlYXZlZCBiZWxvdy4KKy8vIFRoZXNlIHVzZWQgdG8gYmUgYSBzaW5nbGUgY2xhc3MuCitjbGFzcyBGaWxlRGVzY3JpcHRvclRhYmxlcyB7CisgcHVibGljOgorICBGaWxlRGVzY3JpcHRvclRhYmxlcygpOworICB+RmlsZURlc2NyaXB0b3JUYWJsZXMoKTsKKworICAvLyBFbXB0eSB0YWJsZSwgdXNlZCB3aXRoIHBsYWNlaG9sZGVyIGZpbGVzLgorICBpbmxpbmUgc3RhdGljIGNvbnN0IEZpbGVEZXNjcmlwdG9yVGFibGVzJiBHZXRFbXB0eUluc3RhbmNlKCk7CisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgLy8gRmluZGluZyBpdGVtcy4KKworICAvLyBGaW5kIHN5bWJvbHMuICBUaGVzZSByZXR1cm4gYSBudWxsIFN5bWJvbCAoc3ltYm9sLklzTnVsbCgpIGlzIHRydWUpCisgIC8vIGlmIG5vdCBmb3VuZC4KKyAgaW5saW5lIFN5bWJvbCBGaW5kTmVzdGVkU3ltYm9sKGNvbnN0IHZvaWQqIHBhcmVudCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgbmFtZSkgY29uc3Q7CisgIGlubGluZSBTeW1ib2wgRmluZE5lc3RlZFN5bWJvbE9mVHlwZShjb25zdCB2b2lkKiBwYXJlbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIG5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBTeW1ib2w6OlR5cGUgdHlwZSkgY29uc3Q7CisKKyAgLy8gVGhlc2UgcmV0dXJuIE5VTEwgaWYgbm90IGZvdW5kLgorICBpbmxpbmUgY29uc3QgRmllbGREZXNjcmlwdG9yKiBGaW5kRmllbGRCeU51bWJlcigKKyAgICBjb25zdCBEZXNjcmlwdG9yKiBwYXJlbnQsIGludCBudW1iZXIpIGNvbnN0OworICBpbmxpbmUgY29uc3QgRmllbGREZXNjcmlwdG9yKiBGaW5kRmllbGRCeUxvd2VyY2FzZU5hbWUoCisgICAgY29uc3Qgdm9pZCogcGFyZW50LCBjb25zdCBzdHJpbmcmIGxvd2VyY2FzZV9uYW1lKSBjb25zdDsKKyAgaW5saW5lIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogRmluZEZpZWxkQnlDYW1lbGNhc2VOYW1lKAorICAgIGNvbnN0IHZvaWQqIHBhcmVudCwgY29uc3Qgc3RyaW5nJiBjYW1lbGNhc2VfbmFtZSkgY29uc3Q7CisgIGlubGluZSBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBGaW5kRW51bVZhbHVlQnlOdW1iZXIoCisgICAgY29uc3QgRW51bURlc2NyaXB0b3IqIHBhcmVudCwgaW50IG51bWJlcikgY29uc3Q7CisgIC8vIFRoaXMgY3JlYXRlcyBhIG5ldyBFbnVtVmFsdWVEZXNjcmlwdG9yIGlmIG5vdCBmb3VuZCwgaW4gYSB0aHJlYWQtc2FmZSB3YXkuCisgIGlubGluZSBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBGaW5kRW51bVZhbHVlQnlOdW1iZXJDcmVhdGluZ0lmVW5rbm93bigKKyAgICAgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBwYXJlbnQsIGludCBudW1iZXIpIGNvbnN0OworCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8vIEFkZGluZyBpdGVtcy4KKworICAvLyBUaGVzZSBhZGQgaXRlbXMgdG8gdGhlIGNvcnJlc3BvbmRpbmcgdGFibGVzLiAgVGhleSByZXR1cm4gZmFsc2UgaWYKKyAgLy8gdGhlIGtleSBhbHJlYWR5IGV4aXN0cyBpbiB0aGUgdGFibGUuICBGb3IgQWRkQWxpYXNVbmRlclBhcmVudCgpLCB0aGUKKyAgLy8gc3RyaW5nIHBhc3NlZCBpbiBtdXN0IGJlIG9uZSB0aGF0IHdhcyBjb25zdHJ1Y3RlZCB1c2luZyBBbGxvY2F0ZVN0cmluZygpLAorICAvLyBhcyBpdCB3aWxsIGJlIHVzZWQgYXMgYSBrZXkgaW4gdGhlIHN5bWJvbHNfYnlfcGFyZW50XyBtYXAgd2l0aG91dCBjb3B5aW5nLgorICBib29sIEFkZEFsaWFzVW5kZXJQYXJlbnQoY29uc3Qgdm9pZCogcGFyZW50LCBjb25zdCBzdHJpbmcmIG5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBTeW1ib2wgc3ltYm9sKTsKKyAgYm9vbCBBZGRGaWVsZEJ5TnVtYmVyKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpOworICBib29sIEFkZEVudW1WYWx1ZUJ5TnVtYmVyKGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIHZhbHVlKTsKKworICAvLyBBZGRzIHRoZSBmaWVsZCB0byB0aGUgbG93ZXJjYXNlX25hbWUgYW5kIGNhbWVsY2FzZV9uYW1lIG1hcHMuICBOZXZlcgorICAvLyBmYWlscyBiZWNhdXNlIHdlIGFsbG93IGR1cGxpY2F0ZXM7IHRoZSBmaXJzdCBmaWVsZCBieSB0aGUgbmFtZSB3aW5zLgorICB2b2lkIEFkZEZpZWxkQnlTdHlsaXplZE5hbWVzKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpOworCisgIC8vIFBvcHVsYXRlcyBwLT5maXJzdC0+bG9jYXRpb25zX2J5X3BhdGhfIGZyb20gcC0+c2Vjb25kLgorICAvLyBVbnVzdWFsIHNpZ25hdHVyZSBkaWN0YXRlZCBieSBHb29nbGVPbmNlRHluYW1pYy4KKyAgc3RhdGljIHZvaWQgQnVpbGRMb2NhdGlvbnNCeVBhdGgoCisgICAgICBwYWlyPGNvbnN0IEZpbGVEZXNjcmlwdG9yVGFibGVzKiwgY29uc3QgU291cmNlQ29kZUluZm8qPiogcCk7CisKKyAgLy8gUmV0dXJucyB0aGUgbG9jYXRpb24gZGVub3RlZCBieSB0aGUgc3BlY2lmaWVkIHBhdGggdGhyb3VnaCBpbmZvLAorICAvLyBvciBOVUxMIGlmIG5vdCBmb3VuZC4KKyAgLy8gVGhlIHZhbHVlIG9mIGluZm8gbXVzdCBiZSB0aGF0IG9mIHRoZSBjb3JyZXNwb25kaW5nIEZpbGVEZXNjcmlwdG9yLgorICAvLyAoQ29uY2VwdHVhbGx5IGEgcHVyZSBmdW5jdGlvbiwgYnV0IHN0YXRlZnVsIGFzIGFuIG9wdGltaXNhdGlvbi4pCisgIGNvbnN0IFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uKiBHZXRTb3VyY2VMb2NhdGlvbigKKyAgICAgIGNvbnN0IHZlY3RvcjxpbnQ+JiBwYXRoLCBjb25zdCBTb3VyY2VDb2RlSW5mbyogaW5mbykgY29uc3Q7CisKKyBwcml2YXRlOgorICBTeW1ib2xzQnlQYXJlbnRNYXAgICAgc3ltYm9sc19ieV9wYXJlbnRfOworICBGaWVsZHNCeU5hbWVNYXAgICAgICAgZmllbGRzX2J5X2xvd2VyY2FzZV9uYW1lXzsKKyAgRmllbGRzQnlOYW1lTWFwICAgICAgIGZpZWxkc19ieV9jYW1lbGNhc2VfbmFtZV87CisgIEZpZWxkc0J5TnVtYmVyTWFwICAgICBmaWVsZHNfYnlfbnVtYmVyXzsgICAgICAgLy8gTm90IGluY2x1ZGluZyBleHRlbnNpb25zLgorICBFbnVtVmFsdWVzQnlOdW1iZXJNYXAgZW51bV92YWx1ZXNfYnlfbnVtYmVyXzsKKyAgbXV0YWJsZSBFbnVtVmFsdWVzQnlOdW1iZXJNYXAgdW5rbm93bl9lbnVtX3ZhbHVlc19ieV9udW1iZXJfCisgICAgICBHT09HTEVfR1VBUkRFRF9CWSh1bmtub3duX2VudW1fdmFsdWVzX211Xyk7CisKKyAgLy8gUG9wdWxhdGVkIG9uIGZpcnN0IHJlcXVlc3QgdG8gc2F2ZSBzcGFjZSwgaGVuY2UgY29uc3RuZXNzIGdhbWVzLgorICBtdXRhYmxlIEdvb2dsZU9uY2VEeW5hbWljIGxvY2F0aW9uc19ieV9wYXRoX29uY2VfOworICBtdXRhYmxlIExvY2F0aW9uc0J5UGF0aE1hcCBsb2NhdGlvbnNfYnlfcGF0aF87CisKKyAgLy8gTXV0ZXggdG8gcHJvdGVjdCB0aGUgdW5rbm93bi1lbnVtLXZhbHVlIG1hcCBkdWUgdG8gZHluYW1pYworICAvLyBFbnVtVmFsdWVEZXNjcmlwdG9yIGNyZWF0aW9uIG9uIHVua25vd24gdmFsdWVzLgorICBtdXRhYmxlIE11dGV4IHVua25vd25fZW51bV92YWx1ZXNfbXVfOworfTsKKworRGVzY3JpcHRvclBvb2w6OlRhYmxlczo6VGFibGVzKCkKKyAgICAvLyBTdGFydCBzb21lIGhhc2hfbWFwIGFuZCBoYXNoX3NldCBvYmplY3RzIHdpdGggYSBzbWFsbCAjIG9mIGJ1Y2tldHMKKyAgICA6IGtub3duX2JhZF9maWxlc18oMyksCisgICAgICBrbm93bl9iYWRfc3ltYm9sc18oMyksCisgICAgICBleHRlbnNpb25zX2xvYWRlZF9mcm9tX2RiXygzKSwKKyAgICAgIHN5bWJvbHNfYnlfbmFtZV8oMyksCisgICAgICBmaWxlc19ieV9uYW1lXygzKSB7fQorCisKK0Rlc2NyaXB0b3JQb29sOjpUYWJsZXM6On5UYWJsZXMoKSB7CisgIEdPT0dMRV9EQ0hFQ0soY2hlY2twb2ludHNfLmVtcHR5KCkpOworICAvLyBOb3RlIHRoYXQgdGhlIGRlbGV0aW9uIG9yZGVyIGlzIGltcG9ydGFudCwgc2luY2UgdGhlIGRlc3RydWN0b3JzIG9mIHNvbWUKKyAgLy8gbWVzc2FnZXMgbWF5IHJlZmVyIHRvIG9iamVjdHMgaW4gYWxsb2NhdGlvbnNfLgorICBTVExEZWxldGVFbGVtZW50cygmbWVzc2FnZXNfKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBhbGxvY2F0aW9uc18uc2l6ZSgpOyBpKyspIHsKKyAgICBvcGVyYXRvciBkZWxldGUoYWxsb2NhdGlvbnNfW2ldKTsKKyAgfQorICBTVExEZWxldGVFbGVtZW50cygmc3RyaW5nc18pOworICBTVExEZWxldGVFbGVtZW50cygmZmlsZV90YWJsZXNfKTsKK30KKworRmlsZURlc2NyaXB0b3JUYWJsZXM6OkZpbGVEZXNjcmlwdG9yVGFibGVzKCkKKyAgICAvLyBJbml0aWFsaXplIGFsbCB0aGUgaGFzaCB0YWJsZXMgdG8gc3RhcnQgb3V0IHdpdGggYSBzbWFsbCAjIG9mIGJ1Y2tldHMKKyAgICA6IHN5bWJvbHNfYnlfcGFyZW50XygzKSwKKyAgICAgIGZpZWxkc19ieV9sb3dlcmNhc2VfbmFtZV8oMyksCisgICAgICBmaWVsZHNfYnlfY2FtZWxjYXNlX25hbWVfKDMpLAorICAgICAgZmllbGRzX2J5X251bWJlcl8oMyksCisgICAgICBlbnVtX3ZhbHVlc19ieV9udW1iZXJfKDMpLAorICAgICAgdW5rbm93bl9lbnVtX3ZhbHVlc19ieV9udW1iZXJfKDMpIHsKK30KKworRmlsZURlc2NyaXB0b3JUYWJsZXM6On5GaWxlRGVzY3JpcHRvclRhYmxlcygpIHt9CisKK25hbWVzcGFjZSB7CisKK0ZpbGVEZXNjcmlwdG9yVGFibGVzKiBmaWxlX2Rlc2NyaXB0b3JfdGFibGVzXyA9IE5VTEw7CitHT09HTEVfUFJPVE9CVUZfREVDTEFSRV9PTkNFKGZpbGVfZGVzY3JpcHRvcl90YWJsZXNfb25jZV9pbml0Xyk7CisKK3ZvaWQgRGVsZXRlRmlsZURlc2NyaXB0b3JUYWJsZXMoKSB7CisgIGRlbGV0ZSBmaWxlX2Rlc2NyaXB0b3JfdGFibGVzXzsKKyAgZmlsZV9kZXNjcmlwdG9yX3RhYmxlc18gPSBOVUxMOworfQorCit2b2lkIEluaXRGaWxlRGVzY3JpcHRvclRhYmxlcygpIHsKKyAgZmlsZV9kZXNjcmlwdG9yX3RhYmxlc18gPSBuZXcgRmlsZURlc2NyaXB0b3JUYWJsZXMoKTsKKyAgaW50ZXJuYWw6Ok9uU2h1dGRvd24oJkRlbGV0ZUZpbGVEZXNjcmlwdG9yVGFibGVzKTsKK30KKworaW5saW5lIHZvaWQgSW5pdEZpbGVEZXNjcmlwdG9yVGFibGVzT25jZSgpIHsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpHb29nbGVPbmNlSW5pdCgKKyAgICAgICZmaWxlX2Rlc2NyaXB0b3JfdGFibGVzX29uY2VfaW5pdF8sICZJbml0RmlsZURlc2NyaXB0b3JUYWJsZXMpOworfQorCit9ICAvLyBhbm9ueW1vdXMgbmFtZXNwYWNlCisKK2lubGluZSBjb25zdCBGaWxlRGVzY3JpcHRvclRhYmxlcyYgRmlsZURlc2NyaXB0b3JUYWJsZXM6OkdldEVtcHR5SW5zdGFuY2UoKSB7CisgIEluaXRGaWxlRGVzY3JpcHRvclRhYmxlc09uY2UoKTsKKyAgcmV0dXJuICpmaWxlX2Rlc2NyaXB0b3JfdGFibGVzXzsKK30KKwordm9pZCBEZXNjcmlwdG9yUG9vbDo6VGFibGVzOjpBZGRDaGVja3BvaW50KCkgeworICBjaGVja3BvaW50c18ucHVzaF9iYWNrKENoZWNrUG9pbnQodGhpcykpOworfQorCit2b2lkIERlc2NyaXB0b3JQb29sOjpUYWJsZXM6OkNsZWFyTGFzdENoZWNrcG9pbnQoKSB7CisgIEdPT0dMRV9EQ0hFQ0soIWNoZWNrcG9pbnRzXy5lbXB0eSgpKTsKKyAgY2hlY2twb2ludHNfLnBvcF9iYWNrKCk7CisgIGlmIChjaGVja3BvaW50c18uZW1wdHkoKSkgeworICAgIC8vIEFsbCBjaGVja3BvaW50cyBoYXZlIGJlZW4gY2xlYXJlZDogd2UgY2FuIG5vdyBjb21taXQgYWxsIG9mIHRoZSBwZW5kaW5nCisgICAgLy8gZGF0YS4KKyAgICBzeW1ib2xzX2FmdGVyX2NoZWNrcG9pbnRfLmNsZWFyKCk7CisgICAgZmlsZXNfYWZ0ZXJfY2hlY2twb2ludF8uY2xlYXIoKTsKKyAgICBleHRlbnNpb25zX2FmdGVyX2NoZWNrcG9pbnRfLmNsZWFyKCk7CisgIH0KK30KKwordm9pZCBEZXNjcmlwdG9yUG9vbDo6VGFibGVzOjpSb2xsYmFja1RvTGFzdENoZWNrcG9pbnQoKSB7CisgIEdPT0dMRV9EQ0hFQ0soIWNoZWNrcG9pbnRzXy5lbXB0eSgpKTsKKyAgY29uc3QgQ2hlY2tQb2ludCYgY2hlY2twb2ludCA9IGNoZWNrcG9pbnRzXy5iYWNrKCk7CisKKyAgZm9yIChpbnQgaSA9IGNoZWNrcG9pbnQucGVuZGluZ19zeW1ib2xzX2JlZm9yZV9jaGVja3BvaW50OworICAgICAgIGkgPCBzeW1ib2xzX2FmdGVyX2NoZWNrcG9pbnRfLnNpemUoKTsKKyAgICAgICBpKyspIHsKKyAgICBzeW1ib2xzX2J5X25hbWVfLmVyYXNlKHN5bWJvbHNfYWZ0ZXJfY2hlY2twb2ludF9baV0pOworICB9CisgIGZvciAoaW50IGkgPSBjaGVja3BvaW50LnBlbmRpbmdfZmlsZXNfYmVmb3JlX2NoZWNrcG9pbnQ7CisgICAgICAgaSA8IGZpbGVzX2FmdGVyX2NoZWNrcG9pbnRfLnNpemUoKTsKKyAgICAgICBpKyspIHsKKyAgICBmaWxlc19ieV9uYW1lXy5lcmFzZShmaWxlc19hZnRlcl9jaGVja3BvaW50X1tpXSk7CisgIH0KKyAgZm9yIChpbnQgaSA9IGNoZWNrcG9pbnQucGVuZGluZ19leHRlbnNpb25zX2JlZm9yZV9jaGVja3BvaW50OworICAgICAgIGkgPCBleHRlbnNpb25zX2FmdGVyX2NoZWNrcG9pbnRfLnNpemUoKTsKKyAgICAgICBpKyspIHsKKyAgICBleHRlbnNpb25zXy5lcmFzZShleHRlbnNpb25zX2FmdGVyX2NoZWNrcG9pbnRfW2ldKTsKKyAgfQorCisgIHN5bWJvbHNfYWZ0ZXJfY2hlY2twb2ludF8ucmVzaXplKAorICAgICAgY2hlY2twb2ludC5wZW5kaW5nX3N5bWJvbHNfYmVmb3JlX2NoZWNrcG9pbnQpOworICBmaWxlc19hZnRlcl9jaGVja3BvaW50Xy5yZXNpemUoY2hlY2twb2ludC5wZW5kaW5nX2ZpbGVzX2JlZm9yZV9jaGVja3BvaW50KTsKKyAgZXh0ZW5zaW9uc19hZnRlcl9jaGVja3BvaW50Xy5yZXNpemUoCisgICAgICBjaGVja3BvaW50LnBlbmRpbmdfZXh0ZW5zaW9uc19iZWZvcmVfY2hlY2twb2ludCk7CisKKyAgU1RMRGVsZXRlQ29udGFpbmVyUG9pbnRlcnMoCisgICAgICBzdHJpbmdzXy5iZWdpbigpICsgY2hlY2twb2ludC5zdHJpbmdzX2JlZm9yZV9jaGVja3BvaW50LCBzdHJpbmdzXy5lbmQoKSk7CisgIFNUTERlbGV0ZUNvbnRhaW5lclBvaW50ZXJzKAorICAgICAgbWVzc2FnZXNfLmJlZ2luKCkgKyBjaGVja3BvaW50Lm1lc3NhZ2VzX2JlZm9yZV9jaGVja3BvaW50LAorICAgICAgbWVzc2FnZXNfLmVuZCgpKTsKKyAgU1RMRGVsZXRlQ29udGFpbmVyUG9pbnRlcnMoCisgICAgICBmaWxlX3RhYmxlc18uYmVnaW4oKSArIGNoZWNrcG9pbnQuZmlsZV90YWJsZXNfYmVmb3JlX2NoZWNrcG9pbnQsCisgICAgICBmaWxlX3RhYmxlc18uZW5kKCkpOworICBmb3IgKGludCBpID0gY2hlY2twb2ludC5hbGxvY2F0aW9uc19iZWZvcmVfY2hlY2twb2ludDsKKyAgICAgICBpIDwgYWxsb2NhdGlvbnNfLnNpemUoKTsKKyAgICAgICBpKyspIHsKKyAgICBvcGVyYXRvciBkZWxldGUoYWxsb2NhdGlvbnNfW2ldKTsKKyAgfQorCisgIHN0cmluZ3NfLnJlc2l6ZShjaGVja3BvaW50LnN0cmluZ3NfYmVmb3JlX2NoZWNrcG9pbnQpOworICBtZXNzYWdlc18ucmVzaXplKGNoZWNrcG9pbnQubWVzc2FnZXNfYmVmb3JlX2NoZWNrcG9pbnQpOworICBmaWxlX3RhYmxlc18ucmVzaXplKGNoZWNrcG9pbnQuZmlsZV90YWJsZXNfYmVmb3JlX2NoZWNrcG9pbnQpOworICBhbGxvY2F0aW9uc18ucmVzaXplKGNoZWNrcG9pbnQuYWxsb2NhdGlvbnNfYmVmb3JlX2NoZWNrcG9pbnQpOworICBjaGVja3BvaW50c18ucG9wX2JhY2soKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitpbmxpbmUgU3ltYm9sIERlc2NyaXB0b3JQb29sOjpUYWJsZXM6OkZpbmRTeW1ib2woY29uc3Qgc3RyaW5nJiBrZXkpIGNvbnN0IHsKKyAgY29uc3QgU3ltYm9sKiByZXN1bHQgPSBGaW5kT3JOdWxsKHN5bWJvbHNfYnlfbmFtZV8sIGtleS5jX3N0cigpKTsKKyAgaWYgKHJlc3VsdCA9PSBOVUxMKSB7CisgICAgcmV0dXJuIGtOdWxsU3ltYm9sOworICB9IGVsc2UgeworICAgIHJldHVybiAqcmVzdWx0OworICB9Cit9CisKK2lubGluZSBTeW1ib2wgRmlsZURlc2NyaXB0b3JUYWJsZXM6OkZpbmROZXN0ZWRTeW1ib2woCisgICAgY29uc3Qgdm9pZCogcGFyZW50LCBjb25zdCBzdHJpbmcmIG5hbWUpIGNvbnN0IHsKKyAgY29uc3QgU3ltYm9sKiByZXN1bHQgPQorICAgIEZpbmRPck51bGwoc3ltYm9sc19ieV9wYXJlbnRfLCBQb2ludGVyU3RyaW5nUGFpcihwYXJlbnQsIG5hbWUuY19zdHIoKSkpOworICBpZiAocmVzdWx0ID09IE5VTEwpIHsKKyAgICByZXR1cm4ga051bGxTeW1ib2w7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuICpyZXN1bHQ7CisgIH0KK30KKworaW5saW5lIFN5bWJvbCBGaWxlRGVzY3JpcHRvclRhYmxlczo6RmluZE5lc3RlZFN5bWJvbE9mVHlwZSgKKyAgICBjb25zdCB2b2lkKiBwYXJlbnQsIGNvbnN0IHN0cmluZyYgbmFtZSwgY29uc3QgU3ltYm9sOjpUeXBlIHR5cGUpIGNvbnN0IHsKKyAgU3ltYm9sIHJlc3VsdCA9IEZpbmROZXN0ZWRTeW1ib2wocGFyZW50LCBuYW1lKTsKKyAgaWYgKHJlc3VsdC50eXBlICE9IHR5cGUpIHJldHVybiBrTnVsbFN5bWJvbDsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworU3ltYm9sIERlc2NyaXB0b3JQb29sOjpUYWJsZXM6OkZpbmRCeU5hbWVIZWxwZXIoCisgICAgY29uc3QgRGVzY3JpcHRvclBvb2wqIHBvb2wsIGNvbnN0IHN0cmluZyYgbmFtZSkgeworICBNdXRleExvY2tNYXliZSBsb2NrKHBvb2wtPm11dGV4Xyk7CisgIGtub3duX2JhZF9zeW1ib2xzXy5jbGVhcigpOworICBrbm93bl9iYWRfZmlsZXNfLmNsZWFyKCk7CisgIFN5bWJvbCByZXN1bHQgPSBGaW5kU3ltYm9sKG5hbWUpOworCisgIGlmIChyZXN1bHQuSXNOdWxsKCkgJiYgcG9vbC0+dW5kZXJsYXlfICE9IE5VTEwpIHsKKyAgICAvLyBTeW1ib2wgbm90IGZvdW5kOyBjaGVjayB0aGUgdW5kZXJsYXkuCisgICAgcmVzdWx0ID0KKyAgICAgIHBvb2wtPnVuZGVybGF5Xy0+dGFibGVzXy0+RmluZEJ5TmFtZUhlbHBlcihwb29sLT51bmRlcmxheV8sIG5hbWUpOworICB9CisKKyAgaWYgKHJlc3VsdC5Jc051bGwoKSkgeworICAgIC8vIFN5bWJvbCBzdGlsbCBub3QgZm91bmQsIHNvIGNoZWNrIGZhbGxiYWNrIGRhdGFiYXNlLgorICAgIGlmIChwb29sLT5UcnlGaW5kU3ltYm9sSW5GYWxsYmFja0RhdGFiYXNlKG5hbWUpKSB7CisgICAgICByZXN1bHQgPSBGaW5kU3ltYm9sKG5hbWUpOworICAgIH0KKyAgfQorCisgIHJldHVybiByZXN1bHQ7Cit9CisKK2lubGluZSBjb25zdCBGaWxlRGVzY3JpcHRvciogRGVzY3JpcHRvclBvb2w6OlRhYmxlczo6RmluZEZpbGUoCisgICAgY29uc3Qgc3RyaW5nJiBrZXkpIGNvbnN0IHsKKyAgcmV0dXJuIEZpbmRQdHJPck51bGwoZmlsZXNfYnlfbmFtZV8sIGtleS5jX3N0cigpKTsKK30KKworaW5saW5lIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogRmlsZURlc2NyaXB0b3JUYWJsZXM6OkZpbmRGaWVsZEJ5TnVtYmVyKAorICAgIGNvbnN0IERlc2NyaXB0b3IqIHBhcmVudCwgaW50IG51bWJlcikgY29uc3QgeworICByZXR1cm4gRmluZFB0ck9yTnVsbChmaWVsZHNfYnlfbnVtYmVyXywgc3RkOjptYWtlX3BhaXIocGFyZW50LCBudW1iZXIpKTsKK30KKworaW5saW5lIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogRmlsZURlc2NyaXB0b3JUYWJsZXM6OkZpbmRGaWVsZEJ5TG93ZXJjYXNlTmFtZSgKKyAgICBjb25zdCB2b2lkKiBwYXJlbnQsIGNvbnN0IHN0cmluZyYgbG93ZXJjYXNlX25hbWUpIGNvbnN0IHsKKyAgcmV0dXJuIEZpbmRQdHJPck51bGwoZmllbGRzX2J5X2xvd2VyY2FzZV9uYW1lXywKKyAgICAgICAgICAgICAgICAgICAgICAgUG9pbnRlclN0cmluZ1BhaXIocGFyZW50LCBsb3dlcmNhc2VfbmFtZS5jX3N0cigpKSk7Cit9CisKK2lubGluZSBjb25zdCBGaWVsZERlc2NyaXB0b3IqIEZpbGVEZXNjcmlwdG9yVGFibGVzOjpGaW5kRmllbGRCeUNhbWVsY2FzZU5hbWUoCisgICAgY29uc3Qgdm9pZCogcGFyZW50LCBjb25zdCBzdHJpbmcmIGNhbWVsY2FzZV9uYW1lKSBjb25zdCB7CisgIHJldHVybiBGaW5kUHRyT3JOdWxsKGZpZWxkc19ieV9jYW1lbGNhc2VfbmFtZV8sCisgICAgICAgICAgICAgICAgICAgICAgIFBvaW50ZXJTdHJpbmdQYWlyKHBhcmVudCwgY2FtZWxjYXNlX25hbWUuY19zdHIoKSkpOworfQorCitpbmxpbmUgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogRmlsZURlc2NyaXB0b3JUYWJsZXM6OkZpbmRFbnVtVmFsdWVCeU51bWJlcigKKyAgICBjb25zdCBFbnVtRGVzY3JpcHRvciogcGFyZW50LCBpbnQgbnVtYmVyKSBjb25zdCB7CisgIHJldHVybiBGaW5kUHRyT3JOdWxsKGVudW1fdmFsdWVzX2J5X251bWJlcl8sIHN0ZDo6bWFrZV9wYWlyKHBhcmVudCwgbnVtYmVyKSk7Cit9CisKK2lubGluZSBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKgorRmlsZURlc2NyaXB0b3JUYWJsZXM6OkZpbmRFbnVtVmFsdWVCeU51bWJlckNyZWF0aW5nSWZVbmtub3duKAorICAgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBwYXJlbnQsIGludCBudW1iZXIpIGNvbnN0IHsKKyAgLy8gRmlyc3QgdHJ5LCB3aXRoIG1hcCBvZiBjb21waWxlZC1pbiB2YWx1ZXMuCisgIHsKKyAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBkZXNjID0KKyAgICAgICAgRmluZFB0ck9yTnVsbChlbnVtX3ZhbHVlc19ieV9udW1iZXJfLCBzdGQ6Om1ha2VfcGFpcihwYXJlbnQsIG51bWJlcikpOworICAgIGlmIChkZXNjICE9IE5VTEwpIHsKKyAgICAgIHJldHVybiBkZXNjOworICAgIH0KKyAgfQorICAvLyBTZWNvbmQgdHJ5LCB3aXRoIHJlYWRlciBsb2NrIGhlbGQgb24gdW5rbm93biBlbnVtIHZhbHVlczogY29tbW9uIGNhc2UuCisgIHsKKyAgICBSZWFkZXJNdXRleExvY2sgbCgmdW5rbm93bl9lbnVtX3ZhbHVlc19tdV8pOworICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIGRlc2MgPSBGaW5kUHRyT3JOdWxsKAorICAgICAgICB1bmtub3duX2VudW1fdmFsdWVzX2J5X251bWJlcl8sIHN0ZDo6bWFrZV9wYWlyKHBhcmVudCwgbnVtYmVyKSk7CisgICAgaWYgKGRlc2MgIT0gTlVMTCkgeworICAgICAgcmV0dXJuIGRlc2M7CisgICAgfQorICB9CisgIC8vIElmIG5vdCBmb3VuZCwgdHJ5IGFnYWluIHdpdGggd3JpdGVyIGxvY2sgaGVsZCwgYW5kIGNyZWF0ZSBuZXcgZGVzY3JpcHRvciBpZgorICAvLyBuZWNlc3NhcnkuCisgIHsKKyAgICBXcml0ZXJNdXRleExvY2sgbCgmdW5rbm93bl9lbnVtX3ZhbHVlc19tdV8pOworICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIGRlc2MgPSBGaW5kUHRyT3JOdWxsKAorICAgICAgICB1bmtub3duX2VudW1fdmFsdWVzX2J5X251bWJlcl8sIHN0ZDo6bWFrZV9wYWlyKHBhcmVudCwgbnVtYmVyKSk7CisgICAgaWYgKGRlc2MgIT0gTlVMTCkgeworICAgICAgcmV0dXJuIGRlc2M7CisgICAgfQorCisgICAgLy8gQ3JlYXRlIGFuIEVudW1WYWx1ZURlc2NyaXB0b3IgZHluYW1pY2FsbHkuIFdlIGRvbid0IGluc2VydCBpdCBpbnRvIHRoZQorICAgIC8vIEVudW1EZXNjcmlwdG9yIChpdCdzIG5vdCBhIHBhcnQgb2YgdGhlIGVudW0gYXMgb3JpZ2luYWxseSBkZWZpbmVkKSwgYnV0CisgICAgLy8gd2UgZG8gaW5zZXJ0IGl0IGludG8gdGhlIHRhYmxlIHNvIHRoYXQgd2UgY2FuIHJldHVybiB0aGUgc2FtZSBwb2ludGVyCisgICAgLy8gbGF0ZXIuCisgICAgc3RyaW5nIGVudW1fdmFsdWVfbmFtZSA9IFN0cmluZ1ByaW50ZigKKyAgICAgICAgIlVOS05PV05fRU5VTV9WQUxVRV8lc18lZCIsIHBhcmVudC0+bmFtZSgpLmNfc3RyKCksIG51bWJlcik7CisgICAgRGVzY3JpcHRvclBvb2w6OlRhYmxlcyogdGFibGVzID0KKyAgICAgICAgY29uc3RfY2FzdDxEZXNjcmlwdG9yUG9vbDo6VGFibGVzKj4oRGVzY3JpcHRvclBvb2w6OmdlbmVyYXRlZF9wb29sKCktPgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YWJsZXNfLmdldCgpKTsKKyAgICBFbnVtVmFsdWVEZXNjcmlwdG9yKiByZXN1bHQgPSB0YWJsZXMtPkFsbG9jYXRlPEVudW1WYWx1ZURlc2NyaXB0b3I+KCk7CisgICAgcmVzdWx0LT5uYW1lXyA9IHRhYmxlcy0+QWxsb2NhdGVTdHJpbmcoZW51bV92YWx1ZV9uYW1lKTsKKyAgICByZXN1bHQtPmZ1bGxfbmFtZV8gPSB0YWJsZXMtPkFsbG9jYXRlU3RyaW5nKHBhcmVudC0+ZnVsbF9uYW1lKCkgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIi4iICsgZW51bV92YWx1ZV9uYW1lKTsKKyAgICByZXN1bHQtPm51bWJlcl8gPSBudW1iZXI7CisgICAgcmVzdWx0LT50eXBlXyA9IHBhcmVudDsKKyAgICByZXN1bHQtPm9wdGlvbnNfID0gJkVudW1WYWx1ZU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2UoKTsKKyAgICBJbnNlcnRJZk5vdFByZXNlbnQoJnVua25vd25fZW51bV92YWx1ZXNfYnlfbnVtYmVyXywKKyAgICAgICAgICAgICAgICAgICAgICAgc3RkOjptYWtlX3BhaXIocGFyZW50LCBudW1iZXIpLCByZXN1bHQpOworICAgIHJldHVybiByZXN1bHQ7CisgIH0KK30KKworCitpbmxpbmUgY29uc3QgRmllbGREZXNjcmlwdG9yKiBEZXNjcmlwdG9yUG9vbDo6VGFibGVzOjpGaW5kRXh0ZW5zaW9uKAorICAgIGNvbnN0IERlc2NyaXB0b3IqIGV4dGVuZGVlLCBpbnQgbnVtYmVyKSB7CisgIHJldHVybiBGaW5kUHRyT3JOdWxsKGV4dGVuc2lvbnNfLCBzdGQ6Om1ha2VfcGFpcihleHRlbmRlZSwgbnVtYmVyKSk7Cit9CisKK2lubGluZSB2b2lkIERlc2NyaXB0b3JQb29sOjpUYWJsZXM6OkZpbmRBbGxFeHRlbnNpb25zKAorICAgIGNvbnN0IERlc2NyaXB0b3IqIGV4dGVuZGVlLCB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4qIG91dCkgY29uc3QgeworICBFeHRlbnNpb25zR3JvdXBlZEJ5RGVzY3JpcHRvck1hcDo6Y29uc3RfaXRlcmF0b3IgaXQgPQorICAgICAgZXh0ZW5zaW9uc18ubG93ZXJfYm91bmQoc3RkOjptYWtlX3BhaXIoZXh0ZW5kZWUsIDApKTsKKyAgZm9yICg7IGl0ICE9IGV4dGVuc2lvbnNfLmVuZCgpICYmIGl0LT5maXJzdC5maXJzdCA9PSBleHRlbmRlZTsgKytpdCkgeworICAgIG91dC0+cHVzaF9iYWNrKGl0LT5zZWNvbmQpOworICB9Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworYm9vbCBEZXNjcmlwdG9yUG9vbDo6VGFibGVzOjpBZGRTeW1ib2woCisgICAgY29uc3Qgc3RyaW5nJiBmdWxsX25hbWUsIFN5bWJvbCBzeW1ib2wpIHsKKyAgaWYgKEluc2VydElmTm90UHJlc2VudCgmc3ltYm9sc19ieV9uYW1lXywgZnVsbF9uYW1lLmNfc3RyKCksIHN5bWJvbCkpIHsKKyAgICBzeW1ib2xzX2FmdGVyX2NoZWNrcG9pbnRfLnB1c2hfYmFjayhmdWxsX25hbWUuY19zdHIoKSk7CisgICAgcmV0dXJuIHRydWU7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9Cit9CisKK2Jvb2wgRmlsZURlc2NyaXB0b3JUYWJsZXM6OkFkZEFsaWFzVW5kZXJQYXJlbnQoCisgICAgY29uc3Qgdm9pZCogcGFyZW50LCBjb25zdCBzdHJpbmcmIG5hbWUsIFN5bWJvbCBzeW1ib2wpIHsKKyAgUG9pbnRlclN0cmluZ1BhaXIgYnlfcGFyZW50X2tleShwYXJlbnQsIG5hbWUuY19zdHIoKSk7CisgIHJldHVybiBJbnNlcnRJZk5vdFByZXNlbnQoJnN5bWJvbHNfYnlfcGFyZW50XywgYnlfcGFyZW50X2tleSwgc3ltYm9sKTsKK30KKworYm9vbCBEZXNjcmlwdG9yUG9vbDo6VGFibGVzOjpBZGRGaWxlKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKSB7CisgIGlmIChJbnNlcnRJZk5vdFByZXNlbnQoJmZpbGVzX2J5X25hbWVfLCBmaWxlLT5uYW1lKCkuY19zdHIoKSwgZmlsZSkpIHsKKyAgICBmaWxlc19hZnRlcl9jaGVja3BvaW50Xy5wdXNoX2JhY2soZmlsZS0+bmFtZSgpLmNfc3RyKCkpOworICAgIHJldHVybiB0cnVlOworICB9IGVsc2UgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorfQorCit2b2lkIEZpbGVEZXNjcmlwdG9yVGFibGVzOjpBZGRGaWVsZEJ5U3R5bGl6ZWROYW1lcygKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgIGNvbnN0IHZvaWQqIHBhcmVudDsKKyAgaWYgKGZpZWxkLT5pc19leHRlbnNpb24oKSkgeworICAgIGlmIChmaWVsZC0+ZXh0ZW5zaW9uX3Njb3BlKCkgPT0gTlVMTCkgeworICAgICAgcGFyZW50ID0gZmllbGQtPmZpbGUoKTsKKyAgICB9IGVsc2UgeworICAgICAgcGFyZW50ID0gZmllbGQtPmV4dGVuc2lvbl9zY29wZSgpOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICBwYXJlbnQgPSBmaWVsZC0+Y29udGFpbmluZ190eXBlKCk7CisgIH0KKworICBQb2ludGVyU3RyaW5nUGFpciBsb3dlcmNhc2Vfa2V5KHBhcmVudCwgZmllbGQtPmxvd2VyY2FzZV9uYW1lKCkuY19zdHIoKSk7CisgIEluc2VydElmTm90UHJlc2VudCgmZmllbGRzX2J5X2xvd2VyY2FzZV9uYW1lXywgbG93ZXJjYXNlX2tleSwgZmllbGQpOworCisgIFBvaW50ZXJTdHJpbmdQYWlyIGNhbWVsY2FzZV9rZXkocGFyZW50LCBmaWVsZC0+Y2FtZWxjYXNlX25hbWUoKS5jX3N0cigpKTsKKyAgSW5zZXJ0SWZOb3RQcmVzZW50KCZmaWVsZHNfYnlfY2FtZWxjYXNlX25hbWVfLCBjYW1lbGNhc2Vfa2V5LCBmaWVsZCk7Cit9CisKK2Jvb2wgRmlsZURlc2NyaXB0b3JUYWJsZXM6OkFkZEZpZWxkQnlOdW1iZXIoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICBEZXNjcmlwdG9ySW50UGFpciBrZXkoZmllbGQtPmNvbnRhaW5pbmdfdHlwZSgpLCBmaWVsZC0+bnVtYmVyKCkpOworICByZXR1cm4gSW5zZXJ0SWZOb3RQcmVzZW50KCZmaWVsZHNfYnlfbnVtYmVyXywga2V5LCBmaWVsZCk7Cit9CisKK2Jvb2wgRmlsZURlc2NyaXB0b3JUYWJsZXM6OkFkZEVudW1WYWx1ZUJ5TnVtYmVyKAorICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIHZhbHVlKSB7CisgIEVudW1JbnRQYWlyIGtleSh2YWx1ZS0+dHlwZSgpLCB2YWx1ZS0+bnVtYmVyKCkpOworICByZXR1cm4gSW5zZXJ0SWZOb3RQcmVzZW50KCZlbnVtX3ZhbHVlc19ieV9udW1iZXJfLCBrZXksIHZhbHVlKTsKK30KKworYm9vbCBEZXNjcmlwdG9yUG9vbDo6VGFibGVzOjpBZGRFeHRlbnNpb24oY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICBEZXNjcmlwdG9ySW50UGFpciBrZXkoZmllbGQtPmNvbnRhaW5pbmdfdHlwZSgpLCBmaWVsZC0+bnVtYmVyKCkpOworICBpZiAoSW5zZXJ0SWZOb3RQcmVzZW50KCZleHRlbnNpb25zXywga2V5LCBmaWVsZCkpIHsKKyAgICBleHRlbnNpb25zX2FmdGVyX2NoZWNrcG9pbnRfLnB1c2hfYmFjayhrZXkpOworICAgIHJldHVybiB0cnVlOworICB9IGVsc2UgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3RlbXBsYXRlPHR5cGVuYW1lIFR5cGU+CitUeXBlKiBEZXNjcmlwdG9yUG9vbDo6VGFibGVzOjpBbGxvY2F0ZSgpIHsKKyAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8VHlwZSo+KEFsbG9jYXRlQnl0ZXMoc2l6ZW9mKFR5cGUpKSk7Cit9CisKK3RlbXBsYXRlPHR5cGVuYW1lIFR5cGU+CitUeXBlKiBEZXNjcmlwdG9yUG9vbDo6VGFibGVzOjpBbGxvY2F0ZUFycmF5KGludCBjb3VudCkgeworICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxUeXBlKj4oQWxsb2NhdGVCeXRlcyhzaXplb2YoVHlwZSkgKiBjb3VudCkpOworfQorCitzdHJpbmcqIERlc2NyaXB0b3JQb29sOjpUYWJsZXM6OkFsbG9jYXRlU3RyaW5nKGNvbnN0IHN0cmluZyYgdmFsdWUpIHsKKyAgc3RyaW5nKiByZXN1bHQgPSBuZXcgc3RyaW5nKHZhbHVlKTsKKyAgc3RyaW5nc18ucHVzaF9iYWNrKHJlc3VsdCk7CisgIHJldHVybiByZXN1bHQ7Cit9CisKK3RlbXBsYXRlPHR5cGVuYW1lIFR5cGU+CitUeXBlKiBEZXNjcmlwdG9yUG9vbDo6VGFibGVzOjpBbGxvY2F0ZU1lc3NhZ2UoVHlwZSogLyogZHVtbXkgKi8pIHsKKyAgVHlwZSogcmVzdWx0ID0gbmV3IFR5cGU7CisgIG1lc3NhZ2VzXy5wdXNoX2JhY2socmVzdWx0KTsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworRmlsZURlc2NyaXB0b3JUYWJsZXMqIERlc2NyaXB0b3JQb29sOjpUYWJsZXM6OkFsbG9jYXRlRmlsZVRhYmxlcygpIHsKKyAgRmlsZURlc2NyaXB0b3JUYWJsZXMqIHJlc3VsdCA9IG5ldyBGaWxlRGVzY3JpcHRvclRhYmxlczsKKyAgZmlsZV90YWJsZXNfLnB1c2hfYmFjayhyZXN1bHQpOworICByZXR1cm4gcmVzdWx0OworfQorCit2b2lkKiBEZXNjcmlwdG9yUG9vbDo6VGFibGVzOjpBbGxvY2F0ZUJ5dGVzKGludCBzaXplKSB7CisgIC8vIFRPRE8oa2VudG9uKTogIFdvdWxkIGl0IGJlIHdvcnRod2hpbGUgdG8gaW1wbGVtZW50IHRoaXMgaW4gc29tZSBtb3JlCisgIC8vIHNvcGhpc3RpY2F0ZWQgd2F5PyAgUHJvYmFibHkgbm90IGZvciB0aGUgb3BlbiBzb3VyY2UgcmVsZWFzZSwgYnV0IGZvcgorICAvLyBpbnRlcm5hbCB1c2Ugd2UgY291bGQgZWFzaWx5IHBsdWcgaW4gb25lIG9mIG91ciBleGlzdGluZyBtZW1vcnkgcG9vbAorICAvLyBhbGxvY2F0b3JzLi4uCisgIGlmIChzaXplID09IDApIHJldHVybiBOVUxMOworCisgIHZvaWQqIHJlc3VsdCA9IG9wZXJhdG9yIG5ldyhzaXplKTsKKyAgYWxsb2NhdGlvbnNfLnB1c2hfYmFjayhyZXN1bHQpOworICByZXR1cm4gcmVzdWx0OworfQorCit2b2lkIEZpbGVEZXNjcmlwdG9yVGFibGVzOjpCdWlsZExvY2F0aW9uc0J5UGF0aCgKKyAgICBwYWlyPGNvbnN0IEZpbGVEZXNjcmlwdG9yVGFibGVzKiwgY29uc3QgU291cmNlQ29kZUluZm8qPiogcCkgeworICBmb3IgKGludCBpID0gMCwgbGVuID0gcC0+c2Vjb25kLT5sb2NhdGlvbl9zaXplKCk7IGkgPCBsZW47ICsraSkgeworICAgIGNvbnN0IFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uKiBsb2MgPSAmcC0+c2Vjb25kLT5sb2NhdGlvbigpLkdldChpKTsKKyAgICBwLT5maXJzdC0+bG9jYXRpb25zX2J5X3BhdGhfW0pvaW4obG9jLT5wYXRoKCksICIsIildID0gbG9jOworICB9Cit9CisKK2NvbnN0IFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uKiBGaWxlRGVzY3JpcHRvclRhYmxlczo6R2V0U291cmNlTG9jYXRpb24oCisgICAgY29uc3QgdmVjdG9yPGludD4mIHBhdGgsIGNvbnN0IFNvdXJjZUNvZGVJbmZvKiBpbmZvKSBjb25zdCB7CisgIHBhaXI8Y29uc3QgRmlsZURlc2NyaXB0b3JUYWJsZXMqLCBjb25zdCBTb3VyY2VDb2RlSW5mbyo+IHAoCisgICAgICBzdGQ6Om1ha2VfcGFpcih0aGlzLCBpbmZvKSk7CisgIGxvY2F0aW9uc19ieV9wYXRoX29uY2VfLkluaXQoJkZpbGVEZXNjcmlwdG9yVGFibGVzOjpCdWlsZExvY2F0aW9uc0J5UGF0aCwgJnApOworICByZXR1cm4gRmluZFB0ck9yTnVsbChsb2NhdGlvbnNfYnlfcGF0aF8sIEpvaW4ocGF0aCwgIiwiKSk7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKy8vIERlc2NyaXB0b3JQb29sCisKK0Rlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6fkVycm9yQ29sbGVjdG9yKCkge30KKworRGVzY3JpcHRvclBvb2w6OkRlc2NyaXB0b3JQb29sKCkKKyAgOiBtdXRleF8oTlVMTCksCisgICAgZmFsbGJhY2tfZGF0YWJhc2VfKE5VTEwpLAorICAgIGRlZmF1bHRfZXJyb3JfY29sbGVjdG9yXyhOVUxMKSwKKyAgICB1bmRlcmxheV8oTlVMTCksCisgICAgdGFibGVzXyhuZXcgVGFibGVzKSwKKyAgICBlbmZvcmNlX2RlcGVuZGVuY2llc18odHJ1ZSksCisgICAgYWxsb3dfdW5rbm93bl8oZmFsc2UpLAorICAgIGVuZm9yY2Vfd2Vha18oZmFsc2UpIHt9CisKK0Rlc2NyaXB0b3JQb29sOjpEZXNjcmlwdG9yUG9vbChEZXNjcmlwdG9yRGF0YWJhc2UqIGZhbGxiYWNrX2RhdGFiYXNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVycm9yQ29sbGVjdG9yKiBlcnJvcl9jb2xsZWN0b3IpCisgIDogbXV0ZXhfKG5ldyBNdXRleCksCisgICAgZmFsbGJhY2tfZGF0YWJhc2VfKGZhbGxiYWNrX2RhdGFiYXNlKSwKKyAgICBkZWZhdWx0X2Vycm9yX2NvbGxlY3Rvcl8oZXJyb3JfY29sbGVjdG9yKSwKKyAgICB1bmRlcmxheV8oTlVMTCksCisgICAgdGFibGVzXyhuZXcgVGFibGVzKSwKKyAgICBlbmZvcmNlX2RlcGVuZGVuY2llc18odHJ1ZSksCisgICAgYWxsb3dfdW5rbm93bl8oZmFsc2UpLAorICAgIGVuZm9yY2Vfd2Vha18oZmFsc2UpIHsKK30KKworRGVzY3JpcHRvclBvb2w6OkRlc2NyaXB0b3JQb29sKGNvbnN0IERlc2NyaXB0b3JQb29sKiB1bmRlcmxheSkKKyAgOiBtdXRleF8oTlVMTCksCisgICAgZmFsbGJhY2tfZGF0YWJhc2VfKE5VTEwpLAorICAgIGRlZmF1bHRfZXJyb3JfY29sbGVjdG9yXyhOVUxMKSwKKyAgICB1bmRlcmxheV8odW5kZXJsYXkpLAorICAgIHRhYmxlc18obmV3IFRhYmxlcyksCisgICAgZW5mb3JjZV9kZXBlbmRlbmNpZXNfKHRydWUpLAorICAgIGFsbG93X3Vua25vd25fKGZhbHNlKSwKKyAgICBlbmZvcmNlX3dlYWtfKGZhbHNlKSB7fQorCitEZXNjcmlwdG9yUG9vbDo6fkRlc2NyaXB0b3JQb29sKCkgeworICBpZiAobXV0ZXhfICE9IE5VTEwpIGRlbGV0ZSBtdXRleF87Cit9CisKKy8vIERlc2NyaXB0b3JQb29sOjpCdWlsZEZpbGUoKSBkZWZpbmVkIGxhdGVyLgorLy8gRGVzY3JpcHRvclBvb2w6OkJ1aWxkRmlsZUNvbGxlY3RpbmdFcnJvcnMoKSBkZWZpbmVkIGxhdGVyLgorCit2b2lkIERlc2NyaXB0b3JQb29sOjpJbnRlcm5hbERvbnRFbmZvcmNlRGVwZW5kZW5jaWVzKCkgeworICBlbmZvcmNlX2RlcGVuZGVuY2llc18gPSBmYWxzZTsKK30KKwordm9pZCBEZXNjcmlwdG9yUG9vbDo6QWRkVW51c2VkSW1wb3J0VHJhY2tGaWxlKGNvbnN0IHN0cmluZyYgZmlsZV9uYW1lKSB7CisgIHVudXNlZF9pbXBvcnRfdHJhY2tfZmlsZXNfLmluc2VydChmaWxlX25hbWUpOworfQorCit2b2lkIERlc2NyaXB0b3JQb29sOjpDbGVhclVudXNlZEltcG9ydFRyYWNrRmlsZXMoKSB7CisgIHVudXNlZF9pbXBvcnRfdHJhY2tfZmlsZXNfLmNsZWFyKCk7Cit9CisKK2Jvb2wgRGVzY3JpcHRvclBvb2w6OkludGVybmFsSXNGaWxlTG9hZGVkKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUpIGNvbnN0IHsKKyAgTXV0ZXhMb2NrTWF5YmUgbG9jayhtdXRleF8pOworICByZXR1cm4gdGFibGVzXy0+RmluZEZpbGUoZmlsZW5hbWUpICE9IE5VTEw7Cit9CisKKy8vIGdlbmVyYXRlZF9wb29sID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworbmFtZXNwYWNlIHsKKworCitFbmNvZGVkRGVzY3JpcHRvckRhdGFiYXNlKiBnZW5lcmF0ZWRfZGF0YWJhc2VfID0gTlVMTDsKK0Rlc2NyaXB0b3JQb29sKiBnZW5lcmF0ZWRfcG9vbF8gPSBOVUxMOworR09PR0xFX1BST1RPQlVGX0RFQ0xBUkVfT05DRShnZW5lcmF0ZWRfcG9vbF9pbml0Xyk7CisKK3ZvaWQgRGVsZXRlR2VuZXJhdGVkUG9vbCgpIHsKKyAgZGVsZXRlIGdlbmVyYXRlZF9kYXRhYmFzZV87CisgIGdlbmVyYXRlZF9kYXRhYmFzZV8gPSBOVUxMOworICBkZWxldGUgZ2VuZXJhdGVkX3Bvb2xfOworICBnZW5lcmF0ZWRfcG9vbF8gPSBOVUxMOworfQorCitzdGF0aWMgdm9pZCBJbml0R2VuZXJhdGVkUG9vbCgpIHsKKyAgZ2VuZXJhdGVkX2RhdGFiYXNlXyA9IG5ldyBFbmNvZGVkRGVzY3JpcHRvckRhdGFiYXNlOworICBnZW5lcmF0ZWRfcG9vbF8gPSBuZXcgRGVzY3JpcHRvclBvb2woZ2VuZXJhdGVkX2RhdGFiYXNlXyk7CisKKyAgaW50ZXJuYWw6Ok9uU2h1dGRvd24oJkRlbGV0ZUdlbmVyYXRlZFBvb2wpOworfQorCitpbmxpbmUgdm9pZCBJbml0R2VuZXJhdGVkUG9vbE9uY2UoKSB7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6R29vZ2xlT25jZUluaXQoJmdlbmVyYXRlZF9wb29sX2luaXRfLCAmSW5pdEdlbmVyYXRlZFBvb2wpOworfQorCit9ICAvLyBhbm9ueW1vdXMgbmFtZXNwYWNlCisKK2NvbnN0IERlc2NyaXB0b3JQb29sKiBEZXNjcmlwdG9yUG9vbDo6Z2VuZXJhdGVkX3Bvb2woKSB7CisgIEluaXRHZW5lcmF0ZWRQb29sT25jZSgpOworICByZXR1cm4gZ2VuZXJhdGVkX3Bvb2xfOworfQorCisKK0Rlc2NyaXB0b3JQb29sKiBEZXNjcmlwdG9yUG9vbDo6aW50ZXJuYWxfZ2VuZXJhdGVkX3Bvb2woKSB7CisgIEluaXRHZW5lcmF0ZWRQb29sT25jZSgpOworICByZXR1cm4gZ2VuZXJhdGVkX3Bvb2xfOworfQorCit2b2lkIERlc2NyaXB0b3JQb29sOjpJbnRlcm5hbEFkZEdlbmVyYXRlZEZpbGUoCisgICAgY29uc3Qgdm9pZCogZW5jb2RlZF9maWxlX2Rlc2NyaXB0b3IsIGludCBzaXplKSB7CisgIC8vIFNvLCB0aGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBpbiB0aGUgcHJvY2VzcyBvZiBpbml0aWFsaXppbmcgdGhlCisgIC8vIGRlc2NyaXB0b3JzIGZvciBnZW5lcmF0ZWQgcHJvdG8gY2xhc3Nlcy4gIEVhY2ggZ2VuZXJhdGVkIC5wYi5jYyBmaWxlCisgIC8vIGhhcyBhbiBpbnRlcm5hbCBwcm9jZWR1cmUgY2FsbGVkIEFkZERlc2NyaXB0b3JzKCkgd2hpY2ggaXMgY2FsbGVkIGF0CisgIC8vIHByb2Nlc3Mgc3RhcnR1cCwgYW5kIHRoYXQgZnVuY3Rpb24gY2FsbHMgdGhpcyBvbmUgaW4gb3JkZXIgdG8gcmVnaXN0ZXIKKyAgLy8gdGhlIHJhdyBieXRlcyBvZiB0aGUgRmlsZURlc2NyaXB0b3JQcm90byByZXByZXNlbnRpbmcgdGhlIGZpbGUuCisgIC8vCisgIC8vIFdlIGRvIG5vdCBhY3R1YWxseSBjb25zdHJ1Y3QgdGhlIGRlc2NyaXB0b3Igb2JqZWN0cyByaWdodCBhd2F5LiAgV2UganVzdAorICAvLyBoYW5nIG9uIHRvIHRoZSBieXRlcyB1bnRpbCB0aGV5IGFyZSBhY3R1YWxseSBuZWVkZWQuICBXZSBhY3R1YWxseSBjb25zdHJ1Y3QKKyAgLy8gdGhlIGRlc2NyaXB0b3IgdGhlIGZpcnN0IHRpbWUgb25lIG9mIHRoZSBmb2xsb3dpbmcgdGhpbmdzIGhhcHBlbnM6CisgIC8vICogU29tZW9uZSBjYWxscyBhIG1ldGhvZCBsaWtlIGRlc2NyaXB0b3IoKSwgR2V0RGVzY3JpcHRvcigpLCBvcgorICAvLyAgIEdldFJlZmxlY3Rpb24oKSBvbiB0aGUgZ2VuZXJhdGVkIHR5cGVzLCB3aGljaCByZXF1aXJlcyByZXR1cm5pbmcgdGhlCisgIC8vICAgZGVzY3JpcHRvciBvciBhbiBvYmplY3QgYmFzZWQgb24gaXQuCisgIC8vICogU29tZW9uZSBsb29rcyB1cCB0aGUgZGVzY3JpcHRvciBpbiBEZXNjcmlwdG9yUG9vbDo6Z2VuZXJhdGVkX3Bvb2woKS4KKyAgLy8KKyAgLy8gT25jZSBvbmUgb2YgdGhlc2UgaGFwcGVucywgdGhlIERlc2NyaXB0b3JQb29sIGFjdHVhbGx5IHBhcnNlcyB0aGUKKyAgLy8gRmlsZURlc2NyaXB0b3JQcm90byBhbmQgZ2VuZXJhdGVzIGEgRmlsZURlc2NyaXB0b3IgKGFuZCBhbGwgaXRzIGNoaWxkcmVuKQorICAvLyBiYXNlZCBvbiBpdC4KKyAgLy8KKyAgLy8gTm90ZSB0aGF0IEZpbGVEZXNjcmlwdG9yUHJvdG8gaXMgaXRzZWxmIGEgZ2VuZXJhdGVkIHByb3RvY29sIG1lc3NhZ2UuCisgIC8vIFRoZXJlZm9yZSwgd2hlbiB3ZSBwYXJzZSBvbmUsIHdlIGhhdmUgdG8gYmUgdmVyeSBjYXJlZnVsIHRvIGF2b2lkIHVzaW5nCisgIC8vIGFueSBkZXNjcmlwdG9yLWJhc2VkIG9wZXJhdGlvbnMsIHNpbmNlIHRoaXMgbWlnaHQgY2F1c2UgaW5maW5pdGUgcmVjdXJzaW9uCisgIC8vIG9yIGRlYWRsb2NrLgorICBJbml0R2VuZXJhdGVkUG9vbE9uY2UoKTsKKyAgR09PR0xFX0NIRUNLKGdlbmVyYXRlZF9kYXRhYmFzZV8tPkFkZChlbmNvZGVkX2ZpbGVfZGVzY3JpcHRvciwgc2l6ZSkpOworfQorCisKKy8vIEZpbmQqQnkqIG1ldGhvZHMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworLy8gVE9ETyhrZW50b24pOiAgVGhlcmUncyBhIGxvdCBvZiByZXBlYXRlZCBjb2RlIGhlcmUsIGJ1dCBJJ20gbm90IHN1cmUgaWYKKy8vICAgdGhlcmUncyBhbnkgZ29vZCB3YXkgdG8gZmFjdG9yIGl0IG91dC4gIFRoaW5rIGFib3V0IHRoaXMgc29tZSB0aW1lIHdoZW4KKy8vICAgdGhlcmUncyBub3RoaW5nIG1vcmUgaW1wb3J0YW50IHRvIGRvIChyZWFkOiBuZXZlcikuCisKK2NvbnN0IEZpbGVEZXNjcmlwdG9yKiBEZXNjcmlwdG9yUG9vbDo6RmluZEZpbGVCeU5hbWUoY29uc3Qgc3RyaW5nJiBuYW1lKSBjb25zdCB7CisgIE11dGV4TG9ja01heWJlIGxvY2sobXV0ZXhfKTsKKyAgdGFibGVzXy0+a25vd25fYmFkX3N5bWJvbHNfLmNsZWFyKCk7CisgIHRhYmxlc18tPmtub3duX2JhZF9maWxlc18uY2xlYXIoKTsKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIHJlc3VsdCA9IHRhYmxlc18tPkZpbmRGaWxlKG5hbWUpOworICBpZiAocmVzdWx0ICE9IE5VTEwpIHJldHVybiByZXN1bHQ7CisgIGlmICh1bmRlcmxheV8gIT0gTlVMTCkgeworICAgIHJlc3VsdCA9IHVuZGVybGF5Xy0+RmluZEZpbGVCeU5hbWUobmFtZSk7CisgICAgaWYgKHJlc3VsdCAhPSBOVUxMKSByZXR1cm4gcmVzdWx0OworICB9CisgIGlmIChUcnlGaW5kRmlsZUluRmFsbGJhY2tEYXRhYmFzZShuYW1lKSkgeworICAgIHJlc3VsdCA9IHRhYmxlc18tPkZpbmRGaWxlKG5hbWUpOworICAgIGlmIChyZXN1bHQgIT0gTlVMTCkgcmV0dXJuIHJlc3VsdDsKKyAgfQorICByZXR1cm4gTlVMTDsKK30KKworY29uc3QgRmlsZURlc2NyaXB0b3IqIERlc2NyaXB0b3JQb29sOjpGaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2woCisgICAgY29uc3Qgc3RyaW5nJiBzeW1ib2xfbmFtZSkgY29uc3QgeworICBNdXRleExvY2tNYXliZSBsb2NrKG11dGV4Xyk7CisgIHRhYmxlc18tPmtub3duX2JhZF9zeW1ib2xzXy5jbGVhcigpOworICB0YWJsZXNfLT5rbm93bl9iYWRfZmlsZXNfLmNsZWFyKCk7CisgIFN5bWJvbCByZXN1bHQgPSB0YWJsZXNfLT5GaW5kU3ltYm9sKHN5bWJvbF9uYW1lKTsKKyAgaWYgKCFyZXN1bHQuSXNOdWxsKCkpIHJldHVybiByZXN1bHQuR2V0RmlsZSgpOworICBpZiAodW5kZXJsYXlfICE9IE5VTEwpIHsKKyAgICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZV9yZXN1bHQgPQorICAgICAgdW5kZXJsYXlfLT5GaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2woc3ltYm9sX25hbWUpOworICAgIGlmIChmaWxlX3Jlc3VsdCAhPSBOVUxMKSByZXR1cm4gZmlsZV9yZXN1bHQ7CisgIH0KKyAgaWYgKFRyeUZpbmRTeW1ib2xJbkZhbGxiYWNrRGF0YWJhc2Uoc3ltYm9sX25hbWUpKSB7CisgICAgcmVzdWx0ID0gdGFibGVzXy0+RmluZFN5bWJvbChzeW1ib2xfbmFtZSk7CisgICAgaWYgKCFyZXN1bHQuSXNOdWxsKCkpIHJldHVybiByZXN1bHQuR2V0RmlsZSgpOworICB9CisgIHJldHVybiBOVUxMOworfQorCitjb25zdCBEZXNjcmlwdG9yKiBEZXNjcmlwdG9yUG9vbDo6RmluZE1lc3NhZ2VUeXBlQnlOYW1lKAorICAgIGNvbnN0IHN0cmluZyYgbmFtZSkgY29uc3QgeworICBTeW1ib2wgcmVzdWx0ID0gdGFibGVzXy0+RmluZEJ5TmFtZUhlbHBlcih0aGlzLCBuYW1lKTsKKyAgcmV0dXJuIChyZXN1bHQudHlwZSA9PSBTeW1ib2w6Ok1FU1NBR0UpID8gcmVzdWx0LmRlc2NyaXB0b3IgOiBOVUxMOworfQorCitjb25zdCBGaWVsZERlc2NyaXB0b3IqIERlc2NyaXB0b3JQb29sOjpGaW5kRmllbGRCeU5hbWUoCisgICAgY29uc3Qgc3RyaW5nJiBuYW1lKSBjb25zdCB7CisgIFN5bWJvbCByZXN1bHQgPSB0YWJsZXNfLT5GaW5kQnlOYW1lSGVscGVyKHRoaXMsIG5hbWUpOworICBpZiAocmVzdWx0LnR5cGUgPT0gU3ltYm9sOjpGSUVMRCAmJgorICAgICAgIXJlc3VsdC5maWVsZF9kZXNjcmlwdG9yLT5pc19leHRlbnNpb24oKSkgeworICAgIHJldHVybiByZXN1bHQuZmllbGRfZGVzY3JpcHRvcjsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorfQorCitjb25zdCBGaWVsZERlc2NyaXB0b3IqIERlc2NyaXB0b3JQb29sOjpGaW5kRXh0ZW5zaW9uQnlOYW1lKAorICAgIGNvbnN0IHN0cmluZyYgbmFtZSkgY29uc3QgeworICBTeW1ib2wgcmVzdWx0ID0gdGFibGVzXy0+RmluZEJ5TmFtZUhlbHBlcih0aGlzLCBuYW1lKTsKKyAgaWYgKHJlc3VsdC50eXBlID09IFN5bWJvbDo6RklFTEQgJiYKKyAgICAgIHJlc3VsdC5maWVsZF9kZXNjcmlwdG9yLT5pc19leHRlbnNpb24oKSkgeworICAgIHJldHVybiByZXN1bHQuZmllbGRfZGVzY3JpcHRvcjsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorfQorCitjb25zdCBPbmVvZkRlc2NyaXB0b3IqIERlc2NyaXB0b3JQb29sOjpGaW5kT25lb2ZCeU5hbWUoCisgICAgY29uc3Qgc3RyaW5nJiBuYW1lKSBjb25zdCB7CisgIFN5bWJvbCByZXN1bHQgPSB0YWJsZXNfLT5GaW5kQnlOYW1lSGVscGVyKHRoaXMsIG5hbWUpOworICByZXR1cm4gKHJlc3VsdC50eXBlID09IFN5bWJvbDo6T05FT0YpID8gcmVzdWx0Lm9uZW9mX2Rlc2NyaXB0b3IgOiBOVUxMOworfQorCitjb25zdCBFbnVtRGVzY3JpcHRvciogRGVzY3JpcHRvclBvb2w6OkZpbmRFbnVtVHlwZUJ5TmFtZSgKKyAgICBjb25zdCBzdHJpbmcmIG5hbWUpIGNvbnN0IHsKKyAgU3ltYm9sIHJlc3VsdCA9IHRhYmxlc18tPkZpbmRCeU5hbWVIZWxwZXIodGhpcywgbmFtZSk7CisgIHJldHVybiAocmVzdWx0LnR5cGUgPT0gU3ltYm9sOjpFTlVNKSA/IHJlc3VsdC5lbnVtX2Rlc2NyaXB0b3IgOiBOVUxMOworfQorCitjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBEZXNjcmlwdG9yUG9vbDo6RmluZEVudW1WYWx1ZUJ5TmFtZSgKKyAgICBjb25zdCBzdHJpbmcmIG5hbWUpIGNvbnN0IHsKKyAgU3ltYm9sIHJlc3VsdCA9IHRhYmxlc18tPkZpbmRCeU5hbWVIZWxwZXIodGhpcywgbmFtZSk7CisgIHJldHVybiAocmVzdWx0LnR5cGUgPT0gU3ltYm9sOjpFTlVNX1ZBTFVFKSA/CisgICAgcmVzdWx0LmVudW1fdmFsdWVfZGVzY3JpcHRvciA6IE5VTEw7Cit9CisKK2NvbnN0IFNlcnZpY2VEZXNjcmlwdG9yKiBEZXNjcmlwdG9yUG9vbDo6RmluZFNlcnZpY2VCeU5hbWUoCisgICAgY29uc3Qgc3RyaW5nJiBuYW1lKSBjb25zdCB7CisgIFN5bWJvbCByZXN1bHQgPSB0YWJsZXNfLT5GaW5kQnlOYW1lSGVscGVyKHRoaXMsIG5hbWUpOworICByZXR1cm4gKHJlc3VsdC50eXBlID09IFN5bWJvbDo6U0VSVklDRSkgPyByZXN1bHQuc2VydmljZV9kZXNjcmlwdG9yIDogTlVMTDsKK30KKworY29uc3QgTWV0aG9kRGVzY3JpcHRvciogRGVzY3JpcHRvclBvb2w6OkZpbmRNZXRob2RCeU5hbWUoCisgICAgY29uc3Qgc3RyaW5nJiBuYW1lKSBjb25zdCB7CisgIFN5bWJvbCByZXN1bHQgPSB0YWJsZXNfLT5GaW5kQnlOYW1lSGVscGVyKHRoaXMsIG5hbWUpOworICByZXR1cm4gKHJlc3VsdC50eXBlID09IFN5bWJvbDo6TUVUSE9EKSA/IHJlc3VsdC5tZXRob2RfZGVzY3JpcHRvciA6IE5VTEw7Cit9CisKK2NvbnN0IEZpZWxkRGVzY3JpcHRvciogRGVzY3JpcHRvclBvb2w6OkZpbmRFeHRlbnNpb25CeU51bWJlcigKKyAgICBjb25zdCBEZXNjcmlwdG9yKiBleHRlbmRlZSwgaW50IG51bWJlcikgY29uc3QgeworICBNdXRleExvY2tNYXliZSBsb2NrKG11dGV4Xyk7CisgIHRhYmxlc18tPmtub3duX2JhZF9zeW1ib2xzXy5jbGVhcigpOworICB0YWJsZXNfLT5rbm93bl9iYWRfZmlsZXNfLmNsZWFyKCk7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogcmVzdWx0ID0gdGFibGVzXy0+RmluZEV4dGVuc2lvbihleHRlbmRlZSwgbnVtYmVyKTsKKyAgaWYgKHJlc3VsdCAhPSBOVUxMKSB7CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorICBpZiAodW5kZXJsYXlfICE9IE5VTEwpIHsKKyAgICByZXN1bHQgPSB1bmRlcmxheV8tPkZpbmRFeHRlbnNpb25CeU51bWJlcihleHRlbmRlZSwgbnVtYmVyKTsKKyAgICBpZiAocmVzdWx0ICE9IE5VTEwpIHJldHVybiByZXN1bHQ7CisgIH0KKyAgaWYgKFRyeUZpbmRFeHRlbnNpb25JbkZhbGxiYWNrRGF0YWJhc2UoZXh0ZW5kZWUsIG51bWJlcikpIHsKKyAgICByZXN1bHQgPSB0YWJsZXNfLT5GaW5kRXh0ZW5zaW9uKGV4dGVuZGVlLCBudW1iZXIpOworICAgIGlmIChyZXN1bHQgIT0gTlVMTCkgeworICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisgIH0KKyAgcmV0dXJuIE5VTEw7Cit9CisKK3ZvaWQgRGVzY3JpcHRvclBvb2w6OkZpbmRBbGxFeHRlbnNpb25zKAorICAgIGNvbnN0IERlc2NyaXB0b3IqIGV4dGVuZGVlLCB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4qIG91dCkgY29uc3QgeworICBNdXRleExvY2tNYXliZSBsb2NrKG11dGV4Xyk7CisgIHRhYmxlc18tPmtub3duX2JhZF9zeW1ib2xzXy5jbGVhcigpOworICB0YWJsZXNfLT5rbm93bl9iYWRfZmlsZXNfLmNsZWFyKCk7CisKKyAgLy8gSW5pdGlhbGl6ZSB0YWJsZXNfLT5leHRlbnNpb25zXyBmcm9tIHRoZSBmYWxsYmFjayBkYXRhYmFzZSBmaXJzdAorICAvLyAoYnV0IGRvIHRoaXMgb25seSBvbmNlIHBlciBkZXNjcmlwdG9yKS4KKyAgaWYgKGZhbGxiYWNrX2RhdGFiYXNlXyAhPSBOVUxMICYmCisgICAgICB0YWJsZXNfLT5leHRlbnNpb25zX2xvYWRlZF9mcm9tX2RiXy5jb3VudChleHRlbmRlZSkgPT0gMCkgeworICAgIHZlY3RvcjxpbnQ+IG51bWJlcnM7CisgICAgaWYgKGZhbGxiYWNrX2RhdGFiYXNlXy0+RmluZEFsbEV4dGVuc2lvbk51bWJlcnMoZXh0ZW5kZWUtPmZ1bGxfbmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZudW1iZXJzKSkgeworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1iZXJzLnNpemUoKTsgKytpKSB7CisgICAgICAgIGludCBudW1iZXIgPSBudW1iZXJzW2ldOworICAgICAgICBpZiAodGFibGVzXy0+RmluZEV4dGVuc2lvbihleHRlbmRlZSwgbnVtYmVyKSA9PSBOVUxMKSB7CisgICAgICAgICAgVHJ5RmluZEV4dGVuc2lvbkluRmFsbGJhY2tEYXRhYmFzZShleHRlbmRlZSwgbnVtYmVyKTsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgdGFibGVzXy0+ZXh0ZW5zaW9uc19sb2FkZWRfZnJvbV9kYl8uaW5zZXJ0KGV4dGVuZGVlKTsKKyAgICB9CisgIH0KKworICB0YWJsZXNfLT5GaW5kQWxsRXh0ZW5zaW9ucyhleHRlbmRlZSwgb3V0KTsKKyAgaWYgKHVuZGVybGF5XyAhPSBOVUxMKSB7CisgICAgdW5kZXJsYXlfLT5GaW5kQWxsRXh0ZW5zaW9ucyhleHRlbmRlZSwgb3V0KTsKKyAgfQorfQorCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY29uc3QgRmllbGREZXNjcmlwdG9yKgorRGVzY3JpcHRvcjo6RmluZEZpZWxkQnlOdW1iZXIoaW50IGtleSkgY29uc3QgeworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHJlc3VsdCA9CisgICAgZmlsZSgpLT50YWJsZXNfLT5GaW5kRmllbGRCeU51bWJlcih0aGlzLCBrZXkpOworICBpZiAocmVzdWx0ID09IE5VTEwgfHwgcmVzdWx0LT5pc19leHRlbnNpb24oKSkgeworICAgIHJldHVybiBOVUxMOworICB9IGVsc2UgeworICAgIHJldHVybiByZXN1bHQ7CisgIH0KK30KKworY29uc3QgRmllbGREZXNjcmlwdG9yKgorRGVzY3JpcHRvcjo6RmluZEZpZWxkQnlMb3dlcmNhc2VOYW1lKGNvbnN0IHN0cmluZyYga2V5KSBjb25zdCB7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogcmVzdWx0ID0KKyAgICBmaWxlKCktPnRhYmxlc18tPkZpbmRGaWVsZEJ5TG93ZXJjYXNlTmFtZSh0aGlzLCBrZXkpOworICBpZiAocmVzdWx0ID09IE5VTEwgfHwgcmVzdWx0LT5pc19leHRlbnNpb24oKSkgeworICAgIHJldHVybiBOVUxMOworICB9IGVsc2UgeworICAgIHJldHVybiByZXN1bHQ7CisgIH0KK30KKworY29uc3QgRmllbGREZXNjcmlwdG9yKgorRGVzY3JpcHRvcjo6RmluZEZpZWxkQnlDYW1lbGNhc2VOYW1lKGNvbnN0IHN0cmluZyYga2V5KSBjb25zdCB7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogcmVzdWx0ID0KKyAgICBmaWxlKCktPnRhYmxlc18tPkZpbmRGaWVsZEJ5Q2FtZWxjYXNlTmFtZSh0aGlzLCBrZXkpOworICBpZiAocmVzdWx0ID09IE5VTEwgfHwgcmVzdWx0LT5pc19leHRlbnNpb24oKSkgeworICAgIHJldHVybiBOVUxMOworICB9IGVsc2UgeworICAgIHJldHVybiByZXN1bHQ7CisgIH0KK30KKworY29uc3QgRmllbGREZXNjcmlwdG9yKgorRGVzY3JpcHRvcjo6RmluZEZpZWxkQnlOYW1lKGNvbnN0IHN0cmluZyYga2V5KSBjb25zdCB7CisgIFN5bWJvbCByZXN1bHQgPQorICAgIGZpbGUoKS0+dGFibGVzXy0+RmluZE5lc3RlZFN5bWJvbE9mVHlwZSh0aGlzLCBrZXksIFN5bWJvbDo6RklFTEQpOworICBpZiAoIXJlc3VsdC5Jc051bGwoKSAmJiAhcmVzdWx0LmZpZWxkX2Rlc2NyaXB0b3ItPmlzX2V4dGVuc2lvbigpKSB7CisgICAgcmV0dXJuIHJlc3VsdC5maWVsZF9kZXNjcmlwdG9yOworICB9IGVsc2UgeworICAgIHJldHVybiBOVUxMOworICB9Cit9CisKK2NvbnN0IE9uZW9mRGVzY3JpcHRvcioKK0Rlc2NyaXB0b3I6OkZpbmRPbmVvZkJ5TmFtZShjb25zdCBzdHJpbmcmIGtleSkgY29uc3QgeworICBTeW1ib2wgcmVzdWx0ID0KKyAgICBmaWxlKCktPnRhYmxlc18tPkZpbmROZXN0ZWRTeW1ib2xPZlR5cGUodGhpcywga2V5LCBTeW1ib2w6Ok9ORU9GKTsKKyAgaWYgKCFyZXN1bHQuSXNOdWxsKCkpIHsKKyAgICByZXR1cm4gcmVzdWx0Lm9uZW9mX2Rlc2NyaXB0b3I7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KK30KKworY29uc3QgRmllbGREZXNjcmlwdG9yKgorRGVzY3JpcHRvcjo6RmluZEV4dGVuc2lvbkJ5TmFtZShjb25zdCBzdHJpbmcmIGtleSkgY29uc3QgeworICBTeW1ib2wgcmVzdWx0ID0KKyAgICBmaWxlKCktPnRhYmxlc18tPkZpbmROZXN0ZWRTeW1ib2xPZlR5cGUodGhpcywga2V5LCBTeW1ib2w6OkZJRUxEKTsKKyAgaWYgKCFyZXN1bHQuSXNOdWxsKCkgJiYgcmVzdWx0LmZpZWxkX2Rlc2NyaXB0b3ItPmlzX2V4dGVuc2lvbigpKSB7CisgICAgcmV0dXJuIHJlc3VsdC5maWVsZF9kZXNjcmlwdG9yOworICB9IGVsc2UgeworICAgIHJldHVybiBOVUxMOworICB9Cit9CisKK2NvbnN0IEZpZWxkRGVzY3JpcHRvcioKK0Rlc2NyaXB0b3I6OkZpbmRFeHRlbnNpb25CeUxvd2VyY2FzZU5hbWUoY29uc3Qgc3RyaW5nJiBrZXkpIGNvbnN0IHsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiByZXN1bHQgPQorICAgIGZpbGUoKS0+dGFibGVzXy0+RmluZEZpZWxkQnlMb3dlcmNhc2VOYW1lKHRoaXMsIGtleSk7CisgIGlmIChyZXN1bHQgPT0gTlVMTCB8fCAhcmVzdWx0LT5pc19leHRlbnNpb24oKSkgeworICAgIHJldHVybiBOVUxMOworICB9IGVsc2UgeworICAgIHJldHVybiByZXN1bHQ7CisgIH0KK30KKworY29uc3QgRmllbGREZXNjcmlwdG9yKgorRGVzY3JpcHRvcjo6RmluZEV4dGVuc2lvbkJ5Q2FtZWxjYXNlTmFtZShjb25zdCBzdHJpbmcmIGtleSkgY29uc3QgeworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHJlc3VsdCA9CisgICAgZmlsZSgpLT50YWJsZXNfLT5GaW5kRmllbGRCeUNhbWVsY2FzZU5hbWUodGhpcywga2V5KTsKKyAgaWYgKHJlc3VsdCA9PSBOVUxMIHx8ICFyZXN1bHQtPmlzX2V4dGVuc2lvbigpKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorfQorCitjb25zdCBEZXNjcmlwdG9yKgorRGVzY3JpcHRvcjo6RmluZE5lc3RlZFR5cGVCeU5hbWUoY29uc3Qgc3RyaW5nJiBrZXkpIGNvbnN0IHsKKyAgU3ltYm9sIHJlc3VsdCA9CisgICAgZmlsZSgpLT50YWJsZXNfLT5GaW5kTmVzdGVkU3ltYm9sT2ZUeXBlKHRoaXMsIGtleSwgU3ltYm9sOjpNRVNTQUdFKTsKKyAgaWYgKCFyZXN1bHQuSXNOdWxsKCkpIHsKKyAgICByZXR1cm4gcmVzdWx0LmRlc2NyaXB0b3I7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KK30KKworY29uc3QgRW51bURlc2NyaXB0b3IqCitEZXNjcmlwdG9yOjpGaW5kRW51bVR5cGVCeU5hbWUoY29uc3Qgc3RyaW5nJiBrZXkpIGNvbnN0IHsKKyAgU3ltYm9sIHJlc3VsdCA9CisgICAgZmlsZSgpLT50YWJsZXNfLT5GaW5kTmVzdGVkU3ltYm9sT2ZUeXBlKHRoaXMsIGtleSwgU3ltYm9sOjpFTlVNKTsKKyAgaWYgKCFyZXN1bHQuSXNOdWxsKCkpIHsKKyAgICByZXR1cm4gcmVzdWx0LmVudW1fZGVzY3JpcHRvcjsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorfQorCitjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKgorRGVzY3JpcHRvcjo6RmluZEVudW1WYWx1ZUJ5TmFtZShjb25zdCBzdHJpbmcmIGtleSkgY29uc3QgeworICBTeW1ib2wgcmVzdWx0ID0KKyAgICBmaWxlKCktPnRhYmxlc18tPkZpbmROZXN0ZWRTeW1ib2xPZlR5cGUodGhpcywga2V5LCBTeW1ib2w6OkVOVU1fVkFMVUUpOworICBpZiAoIXJlc3VsdC5Jc051bGwoKSkgeworICAgIHJldHVybiByZXN1bHQuZW51bV92YWx1ZV9kZXNjcmlwdG9yOworICB9IGVsc2UgeworICAgIHJldHVybiBOVUxMOworICB9Cit9CisKK2NvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqCitFbnVtRGVzY3JpcHRvcjo6RmluZFZhbHVlQnlOYW1lKGNvbnN0IHN0cmluZyYga2V5KSBjb25zdCB7CisgIFN5bWJvbCByZXN1bHQgPQorICAgIGZpbGUoKS0+dGFibGVzXy0+RmluZE5lc3RlZFN5bWJvbE9mVHlwZSh0aGlzLCBrZXksIFN5bWJvbDo6RU5VTV9WQUxVRSk7CisgIGlmICghcmVzdWx0LklzTnVsbCgpKSB7CisgICAgcmV0dXJuIHJlc3VsdC5lbnVtX3ZhbHVlX2Rlc2NyaXB0b3I7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KK30KKworY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvcioKK0VudW1EZXNjcmlwdG9yOjpGaW5kVmFsdWVCeU51bWJlcihpbnQga2V5KSBjb25zdCB7CisgIHJldHVybiBmaWxlKCktPnRhYmxlc18tPkZpbmRFbnVtVmFsdWVCeU51bWJlcih0aGlzLCBrZXkpOworfQorCitjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKgorRW51bURlc2NyaXB0b3I6OkZpbmRWYWx1ZUJ5TnVtYmVyQ3JlYXRpbmdJZlVua25vd24oaW50IGtleSkgY29uc3QgeworICByZXR1cm4gZmlsZSgpLT50YWJsZXNfLT5GaW5kRW51bVZhbHVlQnlOdW1iZXJDcmVhdGluZ0lmVW5rbm93bih0aGlzLCBrZXkpOworfQorCitjb25zdCBNZXRob2REZXNjcmlwdG9yKgorU2VydmljZURlc2NyaXB0b3I6OkZpbmRNZXRob2RCeU5hbWUoY29uc3Qgc3RyaW5nJiBrZXkpIGNvbnN0IHsKKyAgU3ltYm9sIHJlc3VsdCA9CisgICAgZmlsZSgpLT50YWJsZXNfLT5GaW5kTmVzdGVkU3ltYm9sT2ZUeXBlKHRoaXMsIGtleSwgU3ltYm9sOjpNRVRIT0QpOworICBpZiAoIXJlc3VsdC5Jc051bGwoKSkgeworICAgIHJldHVybiByZXN1bHQubWV0aG9kX2Rlc2NyaXB0b3I7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KK30KKworY29uc3QgRGVzY3JpcHRvcioKK0ZpbGVEZXNjcmlwdG9yOjpGaW5kTWVzc2FnZVR5cGVCeU5hbWUoY29uc3Qgc3RyaW5nJiBrZXkpIGNvbnN0IHsKKyAgU3ltYm9sIHJlc3VsdCA9IHRhYmxlc18tPkZpbmROZXN0ZWRTeW1ib2xPZlR5cGUodGhpcywga2V5LCBTeW1ib2w6Ok1FU1NBR0UpOworICBpZiAoIXJlc3VsdC5Jc051bGwoKSkgeworICAgIHJldHVybiByZXN1bHQuZGVzY3JpcHRvcjsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorfQorCitjb25zdCBFbnVtRGVzY3JpcHRvcioKK0ZpbGVEZXNjcmlwdG9yOjpGaW5kRW51bVR5cGVCeU5hbWUoY29uc3Qgc3RyaW5nJiBrZXkpIGNvbnN0IHsKKyAgU3ltYm9sIHJlc3VsdCA9IHRhYmxlc18tPkZpbmROZXN0ZWRTeW1ib2xPZlR5cGUodGhpcywga2V5LCBTeW1ib2w6OkVOVU0pOworICBpZiAoIXJlc3VsdC5Jc051bGwoKSkgeworICAgIHJldHVybiByZXN1bHQuZW51bV9kZXNjcmlwdG9yOworICB9IGVsc2UgeworICAgIHJldHVybiBOVUxMOworICB9Cit9CisKK2NvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqCitGaWxlRGVzY3JpcHRvcjo6RmluZEVudW1WYWx1ZUJ5TmFtZShjb25zdCBzdHJpbmcmIGtleSkgY29uc3QgeworICBTeW1ib2wgcmVzdWx0ID0KKyAgICB0YWJsZXNfLT5GaW5kTmVzdGVkU3ltYm9sT2ZUeXBlKHRoaXMsIGtleSwgU3ltYm9sOjpFTlVNX1ZBTFVFKTsKKyAgaWYgKCFyZXN1bHQuSXNOdWxsKCkpIHsKKyAgICByZXR1cm4gcmVzdWx0LmVudW1fdmFsdWVfZGVzY3JpcHRvcjsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorfQorCitjb25zdCBTZXJ2aWNlRGVzY3JpcHRvcioKK0ZpbGVEZXNjcmlwdG9yOjpGaW5kU2VydmljZUJ5TmFtZShjb25zdCBzdHJpbmcmIGtleSkgY29uc3QgeworICBTeW1ib2wgcmVzdWx0ID0gdGFibGVzXy0+RmluZE5lc3RlZFN5bWJvbE9mVHlwZSh0aGlzLCBrZXksIFN5bWJvbDo6U0VSVklDRSk7CisgIGlmICghcmVzdWx0LklzTnVsbCgpKSB7CisgICAgcmV0dXJuIHJlc3VsdC5zZXJ2aWNlX2Rlc2NyaXB0b3I7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KK30KKworY29uc3QgRmllbGREZXNjcmlwdG9yKgorRmlsZURlc2NyaXB0b3I6OkZpbmRFeHRlbnNpb25CeU5hbWUoY29uc3Qgc3RyaW5nJiBrZXkpIGNvbnN0IHsKKyAgU3ltYm9sIHJlc3VsdCA9IHRhYmxlc18tPkZpbmROZXN0ZWRTeW1ib2xPZlR5cGUodGhpcywga2V5LCBTeW1ib2w6OkZJRUxEKTsKKyAgaWYgKCFyZXN1bHQuSXNOdWxsKCkgJiYgcmVzdWx0LmZpZWxkX2Rlc2NyaXB0b3ItPmlzX2V4dGVuc2lvbigpKSB7CisgICAgcmV0dXJuIHJlc3VsdC5maWVsZF9kZXNjcmlwdG9yOworICB9IGVsc2UgeworICAgIHJldHVybiBOVUxMOworICB9Cit9CisKK2NvbnN0IEZpZWxkRGVzY3JpcHRvcioKK0ZpbGVEZXNjcmlwdG9yOjpGaW5kRXh0ZW5zaW9uQnlMb3dlcmNhc2VOYW1lKGNvbnN0IHN0cmluZyYga2V5KSBjb25zdCB7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogcmVzdWx0ID0gdGFibGVzXy0+RmluZEZpZWxkQnlMb3dlcmNhc2VOYW1lKHRoaXMsIGtleSk7CisgIGlmIChyZXN1bHQgPT0gTlVMTCB8fCAhcmVzdWx0LT5pc19leHRlbnNpb24oKSkgeworICAgIHJldHVybiBOVUxMOworICB9IGVsc2UgeworICAgIHJldHVybiByZXN1bHQ7CisgIH0KK30KKworY29uc3QgRmllbGREZXNjcmlwdG9yKgorRmlsZURlc2NyaXB0b3I6OkZpbmRFeHRlbnNpb25CeUNhbWVsY2FzZU5hbWUoY29uc3Qgc3RyaW5nJiBrZXkpIGNvbnN0IHsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiByZXN1bHQgPSB0YWJsZXNfLT5GaW5kRmllbGRCeUNhbWVsY2FzZU5hbWUodGhpcywga2V5KTsKKyAgaWYgKHJlc3VsdCA9PSBOVUxMIHx8ICFyZXN1bHQtPmlzX2V4dGVuc2lvbigpKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorfQorCitjb25zdCBEZXNjcmlwdG9yOjpFeHRlbnNpb25SYW5nZSoKK0Rlc2NyaXB0b3I6OkZpbmRFeHRlbnNpb25SYW5nZUNvbnRhaW5pbmdOdW1iZXIoaW50IG51bWJlcikgY29uc3QgeworICAvLyBMaW5lYXIgc2VhcmNoIHNob3VsZCBiZSBmaW5lIGJlY2F1c2Ugd2UgZG9uJ3QgZXhwZWN0IGEgbWVzc2FnZSB0byBoYXZlCisgIC8vIG1vcmUgdGhhbiBhIGNvdXBsZSBleHRlbnNpb24gcmFuZ2VzLgorICBmb3IgKGludCBpID0gMDsgaSA8IGV4dGVuc2lvbl9yYW5nZV9jb3VudCgpOyBpKyspIHsKKyAgICBpZiAobnVtYmVyID49IGV4dGVuc2lvbl9yYW5nZShpKS0+c3RhcnQgJiYKKyAgICAgICAgbnVtYmVyIDwgIGV4dGVuc2lvbl9yYW5nZShpKS0+ZW5kKSB7CisgICAgICByZXR1cm4gZXh0ZW5zaW9uX3JhbmdlKGkpOworICAgIH0KKyAgfQorICByZXR1cm4gTlVMTDsKK30KKworY29uc3QgRGVzY3JpcHRvcjo6UmVzZXJ2ZWRSYW5nZSoKK0Rlc2NyaXB0b3I6OkZpbmRSZXNlcnZlZFJhbmdlQ29udGFpbmluZ051bWJlcihpbnQgbnVtYmVyKSBjb25zdCB7CisgIC8vIFRPRE8oY2hyaXNuKTogQ29uc2lkZXIgYSBub24tbGluZWFyIHNlYXJjaC4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXNlcnZlZF9yYW5nZV9jb3VudCgpOyBpKyspIHsKKyAgICBpZiAobnVtYmVyID49IHJlc2VydmVkX3JhbmdlKGkpLT5zdGFydCAmJgorICAgICAgICBudW1iZXIgPCAgcmVzZXJ2ZWRfcmFuZ2UoaSktPmVuZCkgeworICAgICAgcmV0dXJuIHJlc2VydmVkX3JhbmdlKGkpOworICAgIH0KKyAgfQorICByZXR1cm4gTlVMTDsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitib29sIERlc2NyaXB0b3JQb29sOjpUcnlGaW5kRmlsZUluRmFsbGJhY2tEYXRhYmFzZShjb25zdCBzdHJpbmcmIG5hbWUpIGNvbnN0IHsKKyAgaWYgKGZhbGxiYWNrX2RhdGFiYXNlXyA9PSBOVUxMKSByZXR1cm4gZmFsc2U7CisKKyAgaWYgKHRhYmxlc18tPmtub3duX2JhZF9maWxlc18uY291bnQobmFtZSkgPiAwKSByZXR1cm4gZmFsc2U7CisKKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICBpZiAoIWZhbGxiYWNrX2RhdGFiYXNlXy0+RmluZEZpbGVCeU5hbWUobmFtZSwgJmZpbGVfcHJvdG8pIHx8CisgICAgICBCdWlsZEZpbGVGcm9tRGF0YWJhc2UoZmlsZV9wcm90bykgPT0gTlVMTCkgeworICAgIHRhYmxlc18tPmtub3duX2JhZF9maWxlc18uaW5zZXJ0KG5hbWUpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICByZXR1cm4gdHJ1ZTsKK30KKworYm9vbCBEZXNjcmlwdG9yUG9vbDo6SXNTdWJTeW1ib2xPZkJ1aWx0VHlwZShjb25zdCBzdHJpbmcmIG5hbWUpIGNvbnN0IHsKKyAgc3RyaW5nIHByZWZpeCA9IG5hbWU7CisgIGZvciAoOzspIHsKKyAgICBzdHJpbmc6OnNpemVfdHlwZSBkb3RfcG9zID0gcHJlZml4LmZpbmRfbGFzdF9vZignLicpOworICAgIGlmIChkb3RfcG9zID09IHN0cmluZzo6bnBvcykgeworICAgICAgYnJlYWs7CisgICAgfQorICAgIHByZWZpeCA9IHByZWZpeC5zdWJzdHIoMCwgZG90X3Bvcyk7CisgICAgU3ltYm9sIHN5bWJvbCA9IHRhYmxlc18tPkZpbmRTeW1ib2wocHJlZml4KTsKKyAgICAvLyBJZiB0aGUgc3ltYm9sIHR5cGUgaXMgYW55dGhpbmcgb3RoZXIgdGhhbiBQQUNLQUdFLCB0aGVuIGl0cyBjb21wbGV0ZQorICAgIC8vIGRlZmluaXRpb24gaXMgYWxyZWFkeSBrbm93bi4KKyAgICBpZiAoIXN5bWJvbC5Jc051bGwoKSAmJiBzeW1ib2wudHlwZSAhPSBTeW1ib2w6OlBBQ0tBR0UpIHsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgfQorICBpZiAodW5kZXJsYXlfICE9IE5VTEwpIHsKKyAgICAvLyBDaGVjayB0byBzZWUgaWYgYW55IHByZWZpeCBvZiB0aGlzIHN5bWJvbCBleGlzdHMgaW4gdGhlIHVuZGVybGF5LgorICAgIHJldHVybiB1bmRlcmxheV8tPklzU3ViU3ltYm9sT2ZCdWlsdFR5cGUobmFtZSk7CisgIH0KKyAgcmV0dXJuIGZhbHNlOworfQorCitib29sIERlc2NyaXB0b3JQb29sOjpUcnlGaW5kU3ltYm9sSW5GYWxsYmFja0RhdGFiYXNlKGNvbnN0IHN0cmluZyYgbmFtZSkgY29uc3QgeworICBpZiAoZmFsbGJhY2tfZGF0YWJhc2VfID09IE5VTEwpIHJldHVybiBmYWxzZTsKKworICBpZiAodGFibGVzXy0+a25vd25fYmFkX3N5bWJvbHNfLmNvdW50KG5hbWUpID4gMCkgcmV0dXJuIGZhbHNlOworCisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZV9wcm90bzsKKyAgaWYgKC8vIFdlIHNraXAgbG9va2luZyBpbiB0aGUgZmFsbGJhY2sgZGF0YWJhc2UgaWYgdGhlIG5hbWUgaXMgYSBzdWItc3ltYm9sCisgICAgICAvLyBvZiBhbnkgZGVzY3JpcHRvciB0aGF0IGFscmVhZHkgZXhpc3RzIGluIHRoZSBkZXNjcmlwdG9yIHBvb2wgKGV4Y2VwdAorICAgICAgLy8gZm9yIHBhY2thZ2UgZGVzY3JpcHRvcnMpLiAgVGhpcyBpcyB2YWxpZCBiZWNhdXNlIGFsbCBzeW1ib2xzIGV4Y2VwdAorICAgICAgLy8gZm9yIHBhY2thZ2VzIGFyZSBkZWZpbmVkIGluIGEgc2luZ2xlIGZpbGUsIHNvIGlmIHRoZSBzeW1ib2wgZXhpc3RzCisgICAgICAvLyB0aGVuIHdlIHNob3VsZCBhbHJlYWR5IGhhdmUgaXRzIGRlZmluaXRpb24uCisgICAgICAvLworICAgICAgLy8gVGhlIG90aGVyIHJlYXNvbiB0byBkbyB0aGlzIGlzIHRvIHN1cHBvcnQgIm92ZXJyaWRpbmciIHR5cGUKKyAgICAgIC8vIGRlZmluaXRpb25zIGJ5IG1lcmdpbmcgdHdvIGRhdGFiYXNlcyB0aGF0IGRlZmluZSB0aGUgc2FtZSB0eXBlLiAgKFllcywKKyAgICAgIC8vIHBlb3BsZSBkbyB0aGlzLikgIFRoZSBtYWluIGRpZmZpY3VsdHkgd2l0aCBtYWtpbmcgdGhpcyB3b3JrIGlzIHRoYXQKKyAgICAgIC8vIEZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbCgpIGlzIGFsbG93ZWQgdG8gcmV0dXJuIGJvdGggZmFsc2UgcG9zaXRpdmVzCisgICAgICAvLyAoZS5nLiwgU2ltcGxlRGVzY3JpcHRvckRhdGFiYXNlLCBVcGdyYWRlZERlc2NyaXB0b3JEYXRhYmFzZSkgYW5kIGZhbHNlCisgICAgICAvLyBuZWdhdGl2ZXMgKGUuZy4gUHJvdG9GaWxlUGFyc2VyLCBTb3VyY2VUcmVlRGVzY3JpcHRvckRhdGFiYXNlKS4KKyAgICAgIC8vIFdoZW4gdHdvIHN1Y2ggZGF0YWJhc2VzIGFyZSBtZXJnZWQsIGxvb2tpbmcgdXAgYSBub24tZXhpc3RlbnQKKyAgICAgIC8vIHN1Yi1zeW1ib2wgb2YgYSB0eXBlIHRoYXQgYWxyZWFkeSBleGlzdHMgaW4gdGhlIGRlc2NyaXB0b3IgcG9vbCBjYW4KKyAgICAgIC8vIHJlc3VsdCBpbiBhbiBhdHRlbXB0IHRvIGxvYWQgbXVsdGlwbGUgZGVmaW5pdGlvbnMgb2YgdGhlIHNhbWUgdHlwZS4KKyAgICAgIC8vIFRoZSBjaGVjayBiZWxvdyBhdm9pZHMgdGhpcy4KKyAgICAgIElzU3ViU3ltYm9sT2ZCdWlsdFR5cGUobmFtZSkKKworICAgICAgLy8gTG9vayB1cCBmaWxlIGNvbnRhaW5pbmcgdGhpcyBzeW1ib2wgaW4gZmFsbGJhY2sgZGF0YWJhc2UuCisgICAgICB8fCAhZmFsbGJhY2tfZGF0YWJhc2VfLT5GaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2wobmFtZSwgJmZpbGVfcHJvdG8pCisKKyAgICAgIC8vIENoZWNrIGlmIHdlJ3ZlIGFscmVhZHkgYnVpbHQgdGhpcyBmaWxlLiBJZiBzbywgaXQgYXBwYXJlbnRseSBkb2Vzbid0CisgICAgICAvLyBjb250YWluIHRoZSBzeW1ib2wgd2UncmUgbG9va2luZyBmb3IuICBTb21lIERlc2NyaXB0b3JEYXRhYmFzZXMKKyAgICAgIC8vIHJldHVybiBmYWxzZSBwb3NpdGl2ZXMuCisgICAgICB8fCB0YWJsZXNfLT5GaW5kRmlsZShmaWxlX3Byb3RvLm5hbWUoKSkgIT0gTlVMTAorCisgICAgICAvLyBCdWlsZCB0aGUgZmlsZS4KKyAgICAgIHx8IEJ1aWxkRmlsZUZyb21EYXRhYmFzZShmaWxlX3Byb3RvKSA9PSBOVUxMKSB7CisgICAgdGFibGVzXy0+a25vd25fYmFkX3N5bWJvbHNfLmluc2VydChuYW1lKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICByZXR1cm4gdHJ1ZTsKK30KKworYm9vbCBEZXNjcmlwdG9yUG9vbDo6VHJ5RmluZEV4dGVuc2lvbkluRmFsbGJhY2tEYXRhYmFzZSgKKyAgICBjb25zdCBEZXNjcmlwdG9yKiBjb250YWluaW5nX3R5cGUsIGludCBmaWVsZF9udW1iZXIpIGNvbnN0IHsKKyAgaWYgKGZhbGxiYWNrX2RhdGFiYXNlXyA9PSBOVUxMKSByZXR1cm4gZmFsc2U7CisKKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICBpZiAoIWZhbGxiYWNrX2RhdGFiYXNlXy0+RmluZEZpbGVDb250YWluaW5nRXh0ZW5zaW9uKAorICAgICAgICBjb250YWluaW5nX3R5cGUtPmZ1bGxfbmFtZSgpLCBmaWVsZF9udW1iZXIsICZmaWxlX3Byb3RvKSkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIGlmICh0YWJsZXNfLT5GaW5kRmlsZShmaWxlX3Byb3RvLm5hbWUoKSkgIT0gTlVMTCkgeworICAgIC8vIFdlJ3ZlIGFscmVhZHkgbG9hZGVkIHRoaXMgZmlsZSwgYW5kIGl0IGFwcGFyZW50bHkgZG9lc24ndCBjb250YWluIHRoZQorICAgIC8vIGV4dGVuc2lvbiB3ZSdyZSBsb29raW5nIGZvci4gIFNvbWUgRGVzY3JpcHRvckRhdGFiYXNlcyByZXR1cm4gZmFsc2UKKyAgICAvLyBwb3NpdGl2ZXMuCisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgaWYgKEJ1aWxkRmlsZUZyb21EYXRhYmFzZShmaWxlX3Byb3RvKSA9PSBOVUxMKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgcmV0dXJuIHRydWU7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworYm9vbCBGaWVsZERlc2NyaXB0b3I6OmlzX21hcCgpIGNvbnN0IHsKKyAgcmV0dXJuIHR5cGUoKSA9PSBUWVBFX01FU1NBR0UgJiYgbWVzc2FnZV90eXBlKCktPm9wdGlvbnMoKS5tYXBfZW50cnkoKTsKK30KKworc3RyaW5nIEZpZWxkRGVzY3JpcHRvcjo6RGVmYXVsdFZhbHVlQXNTdHJpbmcoYm9vbCBxdW90ZV9zdHJpbmdfdHlwZSkgY29uc3QgeworICBHT09HTEVfQ0hFQ0soaGFzX2RlZmF1bHRfdmFsdWUoKSkgPDwgIk5vIGRlZmF1bHQgdmFsdWUiOworICBzd2l0Y2ggKGNwcF90eXBlKCkpIHsKKyAgICBjYXNlIENQUFRZUEVfSU5UMzI6CisgICAgICByZXR1cm4gU2ltcGxlSXRvYShkZWZhdWx0X3ZhbHVlX2ludDMyKCkpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBDUFBUWVBFX0lOVDY0OgorICAgICAgcmV0dXJuIFNpbXBsZUl0b2EoZGVmYXVsdF92YWx1ZV9pbnQ2NCgpKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgQ1BQVFlQRV9VSU5UMzI6CisgICAgICByZXR1cm4gU2ltcGxlSXRvYShkZWZhdWx0X3ZhbHVlX3VpbnQzMigpKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgQ1BQVFlQRV9VSU5UNjQ6CisgICAgICByZXR1cm4gU2ltcGxlSXRvYShkZWZhdWx0X3ZhbHVlX3VpbnQ2NCgpKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgQ1BQVFlQRV9GTE9BVDoKKyAgICAgIHJldHVybiBTaW1wbGVGdG9hKGRlZmF1bHRfdmFsdWVfZmxvYXQoKSk7CisgICAgICBicmVhazsKKyAgICBjYXNlIENQUFRZUEVfRE9VQkxFOgorICAgICAgcmV0dXJuIFNpbXBsZUR0b2EoZGVmYXVsdF92YWx1ZV9kb3VibGUoKSk7CisgICAgICBicmVhazsKKyAgICBjYXNlIENQUFRZUEVfQk9PTDoKKyAgICAgIHJldHVybiBkZWZhdWx0X3ZhbHVlX2Jvb2woKSA/ICJ0cnVlIiA6ICJmYWxzZSI7CisgICAgICBicmVhazsKKyAgICBjYXNlIENQUFRZUEVfU1RSSU5HOgorICAgICAgaWYgKHF1b3RlX3N0cmluZ190eXBlKSB7CisgICAgICAgIHJldHVybiAiXCIiICsgQ0VzY2FwZShkZWZhdWx0X3ZhbHVlX3N0cmluZygpKSArICJcIiI7CisgICAgICB9IGVsc2UgeworICAgICAgICBpZiAodHlwZSgpID09IFRZUEVfQllURVMpIHsKKyAgICAgICAgICByZXR1cm4gQ0VzY2FwZShkZWZhdWx0X3ZhbHVlX3N0cmluZygpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICByZXR1cm4gZGVmYXVsdF92YWx1ZV9zdHJpbmcoKTsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgYnJlYWs7CisgICAgY2FzZSBDUFBUWVBFX0VOVU06CisgICAgICByZXR1cm4gZGVmYXVsdF92YWx1ZV9lbnVtKCktPm5hbWUoKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgQ1BQVFlQRV9NRVNTQUdFOgorICAgICAgR09PR0xFX0xPRyhERkFUQUwpIDw8ICJNZXNzYWdlcyBjYW4ndCBoYXZlIGRlZmF1bHQgdmFsdWVzISI7CisgICAgICBicmVhazsKKyAgfQorICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ2FuJ3QgZ2V0IGhlcmU6IGZhaWxlZCB0byBnZXQgZGVmYXVsdCB2YWx1ZSBhcyBzdHJpbmciOworICByZXR1cm4gIiI7Cit9CisKKy8vIENvcHlUbyBtZXRob2RzID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKwordm9pZCBGaWxlRGVzY3JpcHRvcjo6Q29weVRvKEZpbGVEZXNjcmlwdG9yUHJvdG8qIHByb3RvKSBjb25zdCB7CisgIHByb3RvLT5zZXRfbmFtZShuYW1lKCkpOworICBpZiAoIXBhY2thZ2UoKS5lbXB0eSgpKSBwcm90by0+c2V0X3BhY2thZ2UocGFja2FnZSgpKTsKKyAgLy8gVE9ETyhsaXVqaXNpKTogQWxzbyBwb3B1bGF0ZSB3aGVuIHN5bnRheD0icHJvdG8yIi4KKyAgaWYgKHN5bnRheCgpID09IFNZTlRBWF9QUk9UTzMpIHByb3RvLT5zZXRfc3ludGF4KFN5bnRheE5hbWUoc3ludGF4KCkpKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGRlcGVuZGVuY3lfY291bnQoKTsgaSsrKSB7CisgICAgcHJvdG8tPmFkZF9kZXBlbmRlbmN5KGRlcGVuZGVuY3koaSktPm5hbWUoKSk7CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IHB1YmxpY19kZXBlbmRlbmN5X2NvdW50KCk7IGkrKykgeworICAgIHByb3RvLT5hZGRfcHVibGljX2RlcGVuZGVuY3kocHVibGljX2RlcGVuZGVuY2llc19baV0pOworICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB3ZWFrX2RlcGVuZGVuY3lfY291bnQoKTsgaSsrKSB7CisgICAgcHJvdG8tPmFkZF93ZWFrX2RlcGVuZGVuY3kod2Vha19kZXBlbmRlbmNpZXNfW2ldKTsKKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIG1lc3NhZ2VfdHlwZShpKS0+Q29weVRvKHByb3RvLT5hZGRfbWVzc2FnZV90eXBlKCkpOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZW51bV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIGVudW1fdHlwZShpKS0+Q29weVRvKHByb3RvLT5hZGRfZW51bV90eXBlKCkpOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgc2VydmljZV9jb3VudCgpOyBpKyspIHsKKyAgICBzZXJ2aWNlKGkpLT5Db3B5VG8ocHJvdG8tPmFkZF9zZXJ2aWNlKCkpOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZXh0ZW5zaW9uX2NvdW50KCk7IGkrKykgeworICAgIGV4dGVuc2lvbihpKS0+Q29weVRvKHByb3RvLT5hZGRfZXh0ZW5zaW9uKCkpOworICB9CisKKyAgaWYgKCZvcHRpb25zKCkgIT0gJkZpbGVPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlKCkpIHsKKyAgICBwcm90by0+bXV0YWJsZV9vcHRpb25zKCktPkNvcHlGcm9tKG9wdGlvbnMoKSk7CisgIH0KK30KKwordm9pZCBGaWxlRGVzY3JpcHRvcjo6Q29weUpzb25OYW1lVG8oRmlsZURlc2NyaXB0b3JQcm90byogcHJvdG8pIGNvbnN0IHsKKyAgaWYgKG1lc3NhZ2VfdHlwZV9jb3VudCgpICE9IHByb3RvLT5tZXNzYWdlX3R5cGVfc2l6ZSgpIHx8CisgICAgICBleHRlbnNpb25fY291bnQoKSAhPSBwcm90by0+ZXh0ZW5zaW9uX3NpemUoKSkgeworICAgIEdPT0dMRV9MT0coRVJST1IpIDw8ICJDYW5ub3QgY29weSBqc29uX25hbWUgdG8gYSBwcm90byBvZiBhIGRpZmZlcmVudCBzaXplLiI7CisgICAgcmV0dXJuOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIG1lc3NhZ2VfdHlwZShpKS0+Q29weUpzb25OYW1lVG8ocHJvdG8tPm11dGFibGVfbWVzc2FnZV90eXBlKGkpKTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IGV4dGVuc2lvbl9jb3VudCgpOyBpKyspIHsKKyAgICBleHRlbnNpb24oaSktPkNvcHlKc29uTmFtZVRvKHByb3RvLT5tdXRhYmxlX2V4dGVuc2lvbihpKSk7CisgIH0KK30KKwordm9pZCBGaWxlRGVzY3JpcHRvcjo6Q29weVNvdXJjZUNvZGVJbmZvVG8oRmlsZURlc2NyaXB0b3JQcm90byogcHJvdG8pIGNvbnN0IHsKKyAgaWYgKHNvdXJjZV9jb2RlX2luZm9fICYmCisgICAgICBzb3VyY2VfY29kZV9pbmZvXyAhPSAmU291cmNlQ29kZUluZm86OmRlZmF1bHRfaW5zdGFuY2UoKSkgeworICAgIHByb3RvLT5tdXRhYmxlX3NvdXJjZV9jb2RlX2luZm8oKS0+Q29weUZyb20oKnNvdXJjZV9jb2RlX2luZm9fKTsKKyAgfQorfQorCit2b2lkIERlc2NyaXB0b3I6OkNvcHlUbyhEZXNjcmlwdG9yUHJvdG8qIHByb3RvKSBjb25zdCB7CisgIHByb3RvLT5zZXRfbmFtZShuYW1lKCkpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgZmllbGQoaSktPkNvcHlUbyhwcm90by0+YWRkX2ZpZWxkKCkpOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgb25lb2ZfZGVjbF9jb3VudCgpOyBpKyspIHsKKyAgICBvbmVvZl9kZWNsKGkpLT5Db3B5VG8ocHJvdG8tPmFkZF9vbmVvZl9kZWNsKCkpOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgbmVzdGVkX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgbmVzdGVkX3R5cGUoaSktPkNvcHlUbyhwcm90by0+YWRkX25lc3RlZF90eXBlKCkpOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZW51bV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIGVudW1fdHlwZShpKS0+Q29weVRvKHByb3RvLT5hZGRfZW51bV90eXBlKCkpOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCk7IGkrKykgeworICAgIERlc2NyaXB0b3JQcm90bzo6RXh0ZW5zaW9uUmFuZ2UqIHJhbmdlID0gcHJvdG8tPmFkZF9leHRlbnNpb25fcmFuZ2UoKTsKKyAgICByYW5nZS0+c2V0X3N0YXJ0KGV4dGVuc2lvbl9yYW5nZShpKS0+c3RhcnQpOworICAgIHJhbmdlLT5zZXRfZW5kKGV4dGVuc2lvbl9yYW5nZShpKS0+ZW5kKTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IGV4dGVuc2lvbl9jb3VudCgpOyBpKyspIHsKKyAgICBleHRlbnNpb24oaSktPkNvcHlUbyhwcm90by0+YWRkX2V4dGVuc2lvbigpKTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IHJlc2VydmVkX3JhbmdlX2NvdW50KCk7IGkrKykgeworICAgIERlc2NyaXB0b3JQcm90bzo6UmVzZXJ2ZWRSYW5nZSogcmFuZ2UgPSBwcm90by0+YWRkX3Jlc2VydmVkX3JhbmdlKCk7CisgICAgcmFuZ2UtPnNldF9zdGFydChyZXNlcnZlZF9yYW5nZShpKS0+c3RhcnQpOworICAgIHJhbmdlLT5zZXRfZW5kKHJlc2VydmVkX3JhbmdlKGkpLT5lbmQpOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVzZXJ2ZWRfbmFtZV9jb3VudCgpOyBpKyspIHsKKyAgICBwcm90by0+YWRkX3Jlc2VydmVkX25hbWUocmVzZXJ2ZWRfbmFtZShpKSk7CisgIH0KKworICBpZiAoJm9wdGlvbnMoKSAhPSAmTWVzc2FnZU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2UoKSkgeworICAgIHByb3RvLT5tdXRhYmxlX29wdGlvbnMoKS0+Q29weUZyb20ob3B0aW9ucygpKTsKKyAgfQorfQorCit2b2lkIERlc2NyaXB0b3I6OkNvcHlKc29uTmFtZVRvKERlc2NyaXB0b3JQcm90byogcHJvdG8pIGNvbnN0IHsKKyAgaWYgKGZpZWxkX2NvdW50KCkgIT0gcHJvdG8tPmZpZWxkX3NpemUoKSB8fAorICAgICAgbmVzdGVkX3R5cGVfY291bnQoKSAhPSBwcm90by0+bmVzdGVkX3R5cGVfc2l6ZSgpIHx8CisgICAgICBleHRlbnNpb25fY291bnQoKSAhPSBwcm90by0+ZXh0ZW5zaW9uX3NpemUoKSkgeworICAgIEdPT0dMRV9MT0coRVJST1IpIDw8ICJDYW5ub3QgY29weSBqc29uX25hbWUgdG8gYSBwcm90byBvZiBhIGRpZmZlcmVudCBzaXplLiI7CisgICAgcmV0dXJuOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgZmllbGQoaSktPkNvcHlKc29uTmFtZVRvKHByb3RvLT5tdXRhYmxlX2ZpZWxkKGkpKTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IG5lc3RlZF90eXBlX2NvdW50KCk7IGkrKykgeworICAgIG5lc3RlZF90eXBlKGkpLT5Db3B5SnNvbk5hbWVUbyhwcm90by0+bXV0YWJsZV9uZXN0ZWRfdHlwZShpKSk7CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBleHRlbnNpb25fY291bnQoKTsgaSsrKSB7CisgICAgZXh0ZW5zaW9uKGkpLT5Db3B5SnNvbk5hbWVUbyhwcm90by0+bXV0YWJsZV9leHRlbnNpb24oaSkpOworICB9Cit9CisKK3ZvaWQgRmllbGREZXNjcmlwdG9yOjpDb3B5VG8oRmllbGREZXNjcmlwdG9yUHJvdG8qIHByb3RvKSBjb25zdCB7CisgIHByb3RvLT5zZXRfbmFtZShuYW1lKCkpOworICBwcm90by0+c2V0X251bWJlcihudW1iZXIoKSk7CisgIGlmIChoYXNfanNvbl9uYW1lXykgeworICAgIHByb3RvLT5zZXRfanNvbl9uYW1lKGpzb25fbmFtZSgpKTsKKyAgfQorCisgIC8vIFNvbWUgY29tcGlsZXJzIGRvIG5vdCBhbGxvdyBzdGF0aWNfY2FzdCBkaXJlY3RseSBiZXR3ZWVuIHR3byBlbnVtIHR5cGVzLAorICAvLyBzbyB3ZSBtdXN0IGNhc3QgdG8gaW50IGZpcnN0LgorICBwcm90by0+c2V0X2xhYmVsKHN0YXRpY19jYXN0PEZpZWxkRGVzY3JpcHRvclByb3RvOjpMYWJlbD4oCisgICAgICAgICAgICAgICAgICAgICBpbXBsaWNpdF9jYXN0PGludD4obGFiZWwoKSkpKTsKKyAgcHJvdG8tPnNldF90eXBlKHN0YXRpY19jYXN0PEZpZWxkRGVzY3JpcHRvclByb3RvOjpUeXBlPigKKyAgICAgICAgICAgICAgICAgICAgaW1wbGljaXRfY2FzdDxpbnQ+KHR5cGUoKSkpKTsKKworICBpZiAoaXNfZXh0ZW5zaW9uKCkpIHsKKyAgICBpZiAoIWNvbnRhaW5pbmdfdHlwZSgpLT5pc191bnF1YWxpZmllZF9wbGFjZWhvbGRlcl8pIHsKKyAgICAgIHByb3RvLT5zZXRfZXh0ZW5kZWUoIi4iKTsKKyAgICB9CisgICAgcHJvdG8tPm11dGFibGVfZXh0ZW5kZWUoKS0+YXBwZW5kKGNvbnRhaW5pbmdfdHlwZSgpLT5mdWxsX25hbWUoKSk7CisgIH0KKworICBpZiAoY3BwX3R5cGUoKSA9PSBDUFBUWVBFX01FU1NBR0UpIHsKKyAgICBpZiAobWVzc2FnZV90eXBlKCktPmlzX3BsYWNlaG9sZGVyXykgeworICAgICAgLy8gV2UgZG9uJ3QgYWN0dWFsbHkga25vdyBpZiB0aGUgdHlwZSBpcyBhIG1lc3NhZ2UgdHlwZS4gIEl0IGNvdWxkIGJlCisgICAgICAvLyBhbiBlbnVtLgorICAgICAgcHJvdG8tPmNsZWFyX3R5cGUoKTsKKyAgICB9CisKKyAgICBpZiAoIW1lc3NhZ2VfdHlwZSgpLT5pc191bnF1YWxpZmllZF9wbGFjZWhvbGRlcl8pIHsKKyAgICAgIHByb3RvLT5zZXRfdHlwZV9uYW1lKCIuIik7CisgICAgfQorICAgIHByb3RvLT5tdXRhYmxlX3R5cGVfbmFtZSgpLT5hcHBlbmQobWVzc2FnZV90eXBlKCktPmZ1bGxfbmFtZSgpKTsKKyAgfSBlbHNlIGlmIChjcHBfdHlwZSgpID09IENQUFRZUEVfRU5VTSkgeworICAgIGlmICghZW51bV90eXBlKCktPmlzX3VucXVhbGlmaWVkX3BsYWNlaG9sZGVyXykgeworICAgICAgcHJvdG8tPnNldF90eXBlX25hbWUoIi4iKTsKKyAgICB9CisgICAgcHJvdG8tPm11dGFibGVfdHlwZV9uYW1lKCktPmFwcGVuZChlbnVtX3R5cGUoKS0+ZnVsbF9uYW1lKCkpOworICB9CisKKyAgaWYgKGhhc19kZWZhdWx0X3ZhbHVlKCkpIHsKKyAgICBwcm90by0+c2V0X2RlZmF1bHRfdmFsdWUoRGVmYXVsdFZhbHVlQXNTdHJpbmcoZmFsc2UpKTsKKyAgfQorCisgIGlmIChjb250YWluaW5nX29uZW9mKCkgIT0gTlVMTCAmJiAhaXNfZXh0ZW5zaW9uKCkpIHsKKyAgICBwcm90by0+c2V0X29uZW9mX2luZGV4KGNvbnRhaW5pbmdfb25lb2YoKS0+aW5kZXgoKSk7CisgIH0KKworICBpZiAoJm9wdGlvbnMoKSAhPSAmRmllbGRPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlKCkpIHsKKyAgICBwcm90by0+bXV0YWJsZV9vcHRpb25zKCktPkNvcHlGcm9tKG9wdGlvbnMoKSk7CisgIH0KK30KKwordm9pZCBGaWVsZERlc2NyaXB0b3I6OkNvcHlKc29uTmFtZVRvKEZpZWxkRGVzY3JpcHRvclByb3RvKiBwcm90bykgY29uc3QgeworICBwcm90by0+c2V0X2pzb25fbmFtZShqc29uX25hbWUoKSk7Cit9CisKK3ZvaWQgT25lb2ZEZXNjcmlwdG9yOjpDb3B5VG8oT25lb2ZEZXNjcmlwdG9yUHJvdG8qIHByb3RvKSBjb25zdCB7CisgIHByb3RvLT5zZXRfbmFtZShuYW1lKCkpOworfQorCit2b2lkIEVudW1EZXNjcmlwdG9yOjpDb3B5VG8oRW51bURlc2NyaXB0b3JQcm90byogcHJvdG8pIGNvbnN0IHsKKyAgcHJvdG8tPnNldF9uYW1lKG5hbWUoKSk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWx1ZV9jb3VudCgpOyBpKyspIHsKKyAgICB2YWx1ZShpKS0+Q29weVRvKHByb3RvLT5hZGRfdmFsdWUoKSk7CisgIH0KKworICBpZiAoJm9wdGlvbnMoKSAhPSAmRW51bU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2UoKSkgeworICAgIHByb3RvLT5tdXRhYmxlX29wdGlvbnMoKS0+Q29weUZyb20ob3B0aW9ucygpKTsKKyAgfQorfQorCit2b2lkIEVudW1WYWx1ZURlc2NyaXB0b3I6OkNvcHlUbyhFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8qIHByb3RvKSBjb25zdCB7CisgIHByb3RvLT5zZXRfbmFtZShuYW1lKCkpOworICBwcm90by0+c2V0X251bWJlcihudW1iZXIoKSk7CisKKyAgaWYgKCZvcHRpb25zKCkgIT0gJkVudW1WYWx1ZU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2UoKSkgeworICAgIHByb3RvLT5tdXRhYmxlX29wdGlvbnMoKS0+Q29weUZyb20ob3B0aW9ucygpKTsKKyAgfQorfQorCit2b2lkIFNlcnZpY2VEZXNjcmlwdG9yOjpDb3B5VG8oU2VydmljZURlc2NyaXB0b3JQcm90byogcHJvdG8pIGNvbnN0IHsKKyAgcHJvdG8tPnNldF9uYW1lKG5hbWUoKSk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZXRob2RfY291bnQoKTsgaSsrKSB7CisgICAgbWV0aG9kKGkpLT5Db3B5VG8ocHJvdG8tPmFkZF9tZXRob2QoKSk7CisgIH0KKworICBpZiAoJm9wdGlvbnMoKSAhPSAmU2VydmljZU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2UoKSkgeworICAgIHByb3RvLT5tdXRhYmxlX29wdGlvbnMoKS0+Q29weUZyb20ob3B0aW9ucygpKTsKKyAgfQorfQorCit2b2lkIE1ldGhvZERlc2NyaXB0b3I6OkNvcHlUbyhNZXRob2REZXNjcmlwdG9yUHJvdG8qIHByb3RvKSBjb25zdCB7CisgIHByb3RvLT5zZXRfbmFtZShuYW1lKCkpOworCisgIGlmICghaW5wdXRfdHlwZSgpLT5pc191bnF1YWxpZmllZF9wbGFjZWhvbGRlcl8pIHsKKyAgICBwcm90by0+c2V0X2lucHV0X3R5cGUoIi4iKTsKKyAgfQorICBwcm90by0+bXV0YWJsZV9pbnB1dF90eXBlKCktPmFwcGVuZChpbnB1dF90eXBlKCktPmZ1bGxfbmFtZSgpKTsKKworICBpZiAoIW91dHB1dF90eXBlKCktPmlzX3VucXVhbGlmaWVkX3BsYWNlaG9sZGVyXykgeworICAgIHByb3RvLT5zZXRfb3V0cHV0X3R5cGUoIi4iKTsKKyAgfQorICBwcm90by0+bXV0YWJsZV9vdXRwdXRfdHlwZSgpLT5hcHBlbmQob3V0cHV0X3R5cGUoKS0+ZnVsbF9uYW1lKCkpOworCisgIGlmICgmb3B0aW9ucygpICE9ICZNZXRob2RPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlKCkpIHsKKyAgICBwcm90by0+bXV0YWJsZV9vcHRpb25zKCktPkNvcHlGcm9tKG9wdGlvbnMoKSk7CisgIH0KKworICBpZiAoY2xpZW50X3N0cmVhbWluZ18pIHsKKyAgICBwcm90by0+c2V0X2NsaWVudF9zdHJlYW1pbmcodHJ1ZSk7CisgIH0KKyAgaWYgKHNlcnZlcl9zdHJlYW1pbmdfKSB7CisgICAgcHJvdG8tPnNldF9zZXJ2ZXJfc3RyZWFtaW5nKHRydWUpOworICB9Cit9CisKKy8vIERlYnVnU3RyaW5nIG1ldGhvZHMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworbmFtZXNwYWNlIHsKKworLy8gVXNlZCBieSBlYWNoIG9mIHRoZSBvcHRpb24gZm9ybWF0dGVycy4KK2Jvb2wgUmV0cmlldmVPcHRpb25zKGludCBkZXB0aCwKKyAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2UgJm9wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICB2ZWN0b3I8c3RyaW5nPiAqb3B0aW9uX2VudHJpZXMpIHsKKyAgb3B0aW9uX2VudHJpZXMtPmNsZWFyKCk7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBvcHRpb25zLkdldFJlZmxlY3Rpb24oKTsKKyAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+IGZpZWxkczsKKyAgcmVmbGVjdGlvbi0+TGlzdEZpZWxkcyhvcHRpb25zLCAmZmllbGRzKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZHMuc2l6ZSgpOyBpKyspIHsKKyAgICBpbnQgY291bnQgPSAxOworICAgIGJvb2wgcmVwZWF0ZWQgPSBmYWxzZTsKKyAgICBpZiAoZmllbGRzW2ldLT5pc19yZXBlYXRlZCgpKSB7CisgICAgICBjb3VudCA9IHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShvcHRpb25zLCBmaWVsZHNbaV0pOworICAgICAgcmVwZWF0ZWQgPSB0cnVlOworICAgIH0KKyAgICBmb3IgKGludCBqID0gMDsgaiA8IGNvdW50OyBqKyspIHsKKyAgICAgIHN0cmluZyBmaWVsZHZhbDsKKyAgICAgIGlmIChmaWVsZHNbaV0tPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UpIHsKKyAgICAgICAgc3RyaW5nIHRtcDsKKyAgICAgICAgVGV4dEZvcm1hdDo6UHJpbnRlciBwcmludGVyOworICAgICAgICBwcmludGVyLlNldEluaXRpYWxJbmRlbnRMZXZlbChkZXB0aCArIDEpOworICAgICAgICBwcmludGVyLlByaW50RmllbGRWYWx1ZVRvU3RyaW5nKG9wdGlvbnMsIGZpZWxkc1tpXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBlYXRlZCA/IGogOiAtMSwgJnRtcCk7CisgICAgICAgIGZpZWxkdmFsLmFwcGVuZCgie1xuIik7CisgICAgICAgIGZpZWxkdmFsLmFwcGVuZCh0bXApOworICAgICAgICBmaWVsZHZhbC5hcHBlbmQoZGVwdGggKiAyLCAnICcpOworICAgICAgICBmaWVsZHZhbC5hcHBlbmQoIn0iKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIFRleHRGb3JtYXQ6OlByaW50RmllbGRWYWx1ZVRvU3RyaW5nKG9wdGlvbnMsIGZpZWxkc1tpXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwZWF0ZWQgPyBqIDogLTEsICZmaWVsZHZhbCk7CisgICAgICB9CisgICAgICBzdHJpbmcgbmFtZTsKKyAgICAgIGlmIChmaWVsZHNbaV0tPmlzX2V4dGVuc2lvbigpKSB7CisgICAgICAgIG5hbWUgPSAiKC4iICsgZmllbGRzW2ldLT5mdWxsX25hbWUoKSArICIpIjsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIG5hbWUgPSBmaWVsZHNbaV0tPm5hbWUoKTsKKyAgICAgIH0KKyAgICAgIG9wdGlvbl9lbnRyaWVzLT5wdXNoX2JhY2sobmFtZSArICIgPSAiICsgZmllbGR2YWwpOworICAgIH0KKyAgfQorICByZXR1cm4gIW9wdGlvbl9lbnRyaWVzLT5lbXB0eSgpOworfQorCisvLyBGb3JtYXRzIG9wdGlvbnMgdGhhdCBhbGwgYXBwZWFyIHRvZ2V0aGVyIGluIGJyYWNrZXRzLiBEb2VzIG5vdCBpbmNsdWRlCisvLyBicmFja2V0cy4KK2Jvb2wgRm9ybWF0QnJhY2tldGVkT3B0aW9ucyhpbnQgZGVwdGgsIGNvbnN0IE1lc3NhZ2UgJm9wdGlvbnMsIHN0cmluZyAqb3V0cHV0KSB7CisgIHZlY3RvcjxzdHJpbmc+IGFsbF9vcHRpb25zOworICBpZiAoUmV0cmlldmVPcHRpb25zKGRlcHRoLCBvcHRpb25zLCAmYWxsX29wdGlvbnMpKSB7CisgICAgb3V0cHV0LT5hcHBlbmQoSm9pbihhbGxfb3B0aW9ucywgIiwgIikpOworICB9CisgIHJldHVybiAhYWxsX29wdGlvbnMuZW1wdHkoKTsKK30KKworLy8gRm9ybWF0cyBvcHRpb25zIG9uZSBwZXIgbGluZQorYm9vbCBGb3JtYXRMaW5lT3B0aW9ucyhpbnQgZGVwdGgsIGNvbnN0IE1lc3NhZ2UgJm9wdGlvbnMsIHN0cmluZyAqb3V0cHV0KSB7CisgIHN0cmluZyBwcmVmaXgoZGVwdGggKiAyLCAnICcpOworICB2ZWN0b3I8c3RyaW5nPiBhbGxfb3B0aW9uczsKKyAgaWYgKFJldHJpZXZlT3B0aW9ucyhkZXB0aCwgb3B0aW9ucywgJmFsbF9vcHRpb25zKSkgeworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYWxsX29wdGlvbnMuc2l6ZSgpOyBpKyspIHsKKyAgICAgIHN0cmluZ3M6OlN1YnN0aXR1dGVBbmRBcHBlbmQob3V0cHV0LCAiJDBvcHRpb24gJDE7XG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXgsIGFsbF9vcHRpb25zW2ldKTsKKyAgICB9CisgIH0KKyAgcmV0dXJuICFhbGxfb3B0aW9ucy5lbXB0eSgpOworfQorCitjbGFzcyBTb3VyY2VMb2NhdGlvbkNvbW1lbnRQcmludGVyIHsKKyBwdWJsaWM6CisgIHRlbXBsYXRlPHR5cGVuYW1lIERlc2NUeXBlPgorICBTb3VyY2VMb2NhdGlvbkNvbW1lbnRQcmludGVyKGNvbnN0IERlc2NUeXBlKiBkZXNjLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgcHJlZml4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlYnVnU3RyaW5nT3B0aW9ucyYgb3B0aW9ucykKKyAgICAgIDogb3B0aW9uc18ob3B0aW9ucyksIHByZWZpeF8ocHJlZml4KSB7CisgICAgLy8gUGVyZm9ybSB0aGUgU291cmNlTG9jYXRpb24gbG9va3VwIG9ubHkgaWYgd2UncmUgaW5jbHVkaW5nIHVzZXIgY29tbWVudHMsCisgICAgLy8gYmVjYXVzZSB0aGUgbG9va3VwIGlzIGZhaXJseSBleHBlbnNpdmUuCisgICAgaGF2ZV9zb3VyY2VfbG9jXyA9IG9wdGlvbnMuaW5jbHVkZV9jb21tZW50cyAmJgorICAgICAgICBkZXNjLT5HZXRTb3VyY2VMb2NhdGlvbigmc291cmNlX2xvY18pOworICB9CisgIFNvdXJjZUxvY2F0aW9uQ29tbWVudFByaW50ZXIoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmVjdG9yPGludD4mIHBhdGgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBwcmVmaXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVidWdTdHJpbmdPcHRpb25zJiBvcHRpb25zKQorICAgICAgOiBvcHRpb25zXyhvcHRpb25zKSwgcHJlZml4XyhwcmVmaXgpIHsKKyAgICAvLyBQZXJmb3JtIHRoZSBTb3VyY2VMb2NhdGlvbiBsb29rdXAgb25seSBpZiB3ZSdyZSBpbmNsdWRpbmcgdXNlciBjb21tZW50cywKKyAgICAvLyBiZWNhdXNlIHRoZSBsb29rdXAgaXMgZmFpcmx5IGV4cGVuc2l2ZS4KKyAgICBoYXZlX3NvdXJjZV9sb2NfID0gb3B0aW9ucy5pbmNsdWRlX2NvbW1lbnRzICYmCisgICAgICAgIGZpbGUtPkdldFNvdXJjZUxvY2F0aW9uKHBhdGgsICZzb3VyY2VfbG9jXyk7CisgIH0KKyAgdm9pZCBBZGRQcmVDb21tZW50KHN0cmluZyogb3V0cHV0KSB7CisgICAgaWYgKGhhdmVfc291cmNlX2xvY18pIHsKKyAgICAgIC8vIERldGFjaGVkIGxlYWRpbmcgY29tbWVudHMuCisgICAgICBmb3IgKGludCBpID0gMCA7IGkgPCBzb3VyY2VfbG9jXy5sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzLnNpemUoKTsgKytpKSB7CisgICAgICAgICpvdXRwdXQgKz0gRm9ybWF0Q29tbWVudChzb3VyY2VfbG9jXy5sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzW2ldKTsKKyAgICAgICAgKm91dHB1dCArPSAiXG4iOworICAgICAgfQorICAgICAgLy8gQXR0YWNoZWQgbGVhZGluZyBjb21tZW50cy4KKyAgICAgIGlmICghc291cmNlX2xvY18ubGVhZGluZ19jb21tZW50cy5lbXB0eSgpKSB7CisgICAgICAgICpvdXRwdXQgKz0gRm9ybWF0Q29tbWVudChzb3VyY2VfbG9jXy5sZWFkaW5nX2NvbW1lbnRzKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKyAgdm9pZCBBZGRQb3N0Q29tbWVudChzdHJpbmcqIG91dHB1dCkgeworICAgIGlmIChoYXZlX3NvdXJjZV9sb2NfICYmIHNvdXJjZV9sb2NfLnRyYWlsaW5nX2NvbW1lbnRzLnNpemUoKSA+IDApIHsKKyAgICAgICpvdXRwdXQgKz0gRm9ybWF0Q29tbWVudChzb3VyY2VfbG9jXy50cmFpbGluZ19jb21tZW50cyk7CisgICAgfQorICB9CisKKyAgLy8gRm9ybWF0IGNvbW1lbnQgc3VjaCB0aGF0IGVhY2ggbGluZSBiZWNvbWVzIGEgZnVsbC1saW5lIEMrKy1zdHlsZSBjb21tZW50IGluCisgIC8vIHRoZSBEZWJ1Z1N0cmluZygpIG91dHB1dC4KKyAgc3RyaW5nIEZvcm1hdENvbW1lbnQoY29uc3Qgc3RyaW5nJiBjb21tZW50X3RleHQpIHsKKyAgICBzdHJpbmcgc3RyaXBwZWRfY29tbWVudCA9IGNvbW1lbnRfdGV4dDsKKyAgICBTdHJpcFdoaXRlc3BhY2UoJnN0cmlwcGVkX2NvbW1lbnQpOworICAgIHZlY3RvcjxzdHJpbmc+IGxpbmVzID0gU3BsaXQoc3RyaXBwZWRfY29tbWVudCwgIlxuIik7CisgICAgc3RyaW5nIG91dHB1dDsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGxpbmVzLnNpemUoKTsgKytpKSB7CisgICAgICBjb25zdCBzdHJpbmcmIGxpbmUgPSBsaW5lc1tpXTsKKyAgICAgIHN0cmluZ3M6OlN1YnN0aXR1dGVBbmRBcHBlbmQoJm91dHB1dCwgIiQwLy8gJDFcbiIsIHByZWZpeF8sIGxpbmUpOworICAgIH0KKyAgICByZXR1cm4gb3V0cHV0OworICB9CisKKyBwcml2YXRlOgorCisgIGJvb2wgaGF2ZV9zb3VyY2VfbG9jXzsKKyAgU291cmNlTG9jYXRpb24gc291cmNlX2xvY187CisgIERlYnVnU3RyaW5nT3B0aW9ucyBvcHRpb25zXzsKKyAgc3RyaW5nIHByZWZpeF87Cit9OworCit9ICAvLyBhbm9ueW1vdXMgbmFtZXNwYWNlCisKK3N0cmluZyBGaWxlRGVzY3JpcHRvcjo6RGVidWdTdHJpbmcoKSBjb25zdCB7CisgIERlYnVnU3RyaW5nT3B0aW9ucyBvcHRpb25zOyAgLy8gZGVmYXVsdCBvcHRpb25zCisgIHJldHVybiBEZWJ1Z1N0cmluZ1dpdGhPcHRpb25zKG9wdGlvbnMpOworfQorCitzdHJpbmcgRmlsZURlc2NyaXB0b3I6OkRlYnVnU3RyaW5nV2l0aE9wdGlvbnMoCisgICAgY29uc3QgRGVidWdTdHJpbmdPcHRpb25zJiBkZWJ1Z19zdHJpbmdfb3B0aW9ucykgY29uc3QgeworICBzdHJpbmcgY29udGVudHM7CisgIHsKKyAgICB2ZWN0b3I8aW50PiBwYXRoOworICAgIHBhdGgucHVzaF9iYWNrKEZpbGVEZXNjcmlwdG9yUHJvdG86OmtTeW50YXhGaWVsZE51bWJlcik7CisgICAgU291cmNlTG9jYXRpb25Db21tZW50UHJpbnRlciBzeW50YXhfY29tbWVudCgKKyAgICAgICAgdGhpcywgcGF0aCwgIiIsIGRlYnVnX3N0cmluZ19vcHRpb25zKTsKKyAgICBzeW50YXhfY29tbWVudC5BZGRQcmVDb21tZW50KCZjb250ZW50cyk7CisgICAgc3RyaW5nczo6U3Vic3RpdHV0ZUFuZEFwcGVuZCgmY29udGVudHMsICJzeW50YXggPSBcIiQwXCI7XG5cbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeW50YXhOYW1lKHN5bnRheCgpKSk7CisgICAgc3ludGF4X2NvbW1lbnQuQWRkUG9zdENvbW1lbnQoJmNvbnRlbnRzKTsKKyAgfQorCisgIFNvdXJjZUxvY2F0aW9uQ29tbWVudFByaW50ZXIKKyAgICAgIGNvbW1lbnRfcHJpbnRlcih0aGlzLCAiIiwgZGVidWdfc3RyaW5nX29wdGlvbnMpOworICBjb21tZW50X3ByaW50ZXIuQWRkUHJlQ29tbWVudCgmY29udGVudHMpOworCisgIHNldDxpbnQ+IHB1YmxpY19kZXBlbmRlbmNpZXM7CisgIHNldDxpbnQ+IHdlYWtfZGVwZW5kZW5jaWVzOworICBwdWJsaWNfZGVwZW5kZW5jaWVzLmluc2VydChwdWJsaWNfZGVwZW5kZW5jaWVzXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljX2RlcGVuZGVuY2llc18gKyBwdWJsaWNfZGVwZW5kZW5jeV9jb3VudF8pOworICB3ZWFrX2RlcGVuZGVuY2llcy5pbnNlcnQod2Vha19kZXBlbmRlbmNpZXNfLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgd2Vha19kZXBlbmRlbmNpZXNfICsgd2Vha19kZXBlbmRlbmN5X2NvdW50Xyk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXBlbmRlbmN5X2NvdW50KCk7IGkrKykgeworICAgIGlmIChwdWJsaWNfZGVwZW5kZW5jaWVzLmNvdW50KGkpID4gMCkgeworICAgICAgc3RyaW5nczo6U3Vic3RpdHV0ZUFuZEFwcGVuZCgmY29udGVudHMsICJpbXBvcnQgcHVibGljIFwiJDBcIjtcbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlcGVuZGVuY3koaSktPm5hbWUoKSk7CisgICAgfSBlbHNlIGlmICh3ZWFrX2RlcGVuZGVuY2llcy5jb3VudChpKSA+IDApIHsKKyAgICAgIHN0cmluZ3M6OlN1YnN0aXR1dGVBbmRBcHBlbmQoJmNvbnRlbnRzLCAiaW1wb3J0IHdlYWsgXCIkMFwiO1xuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwZW5kZW5jeShpKS0+bmFtZSgpKTsKKyAgICB9IGVsc2UgeworICAgICAgc3RyaW5nczo6U3Vic3RpdHV0ZUFuZEFwcGVuZCgmY29udGVudHMsICJpbXBvcnQgXCIkMFwiO1xuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwZW5kZW5jeShpKS0+bmFtZSgpKTsKKyAgICB9CisgIH0KKworICBpZiAoIXBhY2thZ2UoKS5lbXB0eSgpKSB7CisgICAgdmVjdG9yPGludD4gcGF0aDsKKyAgICBwYXRoLnB1c2hfYmFjayhGaWxlRGVzY3JpcHRvclByb3RvOjprUGFja2FnZUZpZWxkTnVtYmVyKTsKKyAgICBTb3VyY2VMb2NhdGlvbkNvbW1lbnRQcmludGVyIHBhY2thZ2VfY29tbWVudCgKKyAgICAgICAgdGhpcywgcGF0aCwgIiIsIGRlYnVnX3N0cmluZ19vcHRpb25zKTsKKyAgICBwYWNrYWdlX2NvbW1lbnQuQWRkUHJlQ29tbWVudCgmY29udGVudHMpOworICAgIHN0cmluZ3M6OlN1YnN0aXR1dGVBbmRBcHBlbmQoJmNvbnRlbnRzLCAicGFja2FnZSAkMDtcblxuIiwgcGFja2FnZSgpKTsKKyAgICBwYWNrYWdlX2NvbW1lbnQuQWRkUG9zdENvbW1lbnQoJmNvbnRlbnRzKTsKKyAgfQorCisgIGlmIChGb3JtYXRMaW5lT3B0aW9ucygwLCBvcHRpb25zKCksICZjb250ZW50cykpIHsKKyAgICBjb250ZW50cy5hcHBlbmQoIlxuIik7ICAvLyBhZGQgc29tZSBzcGFjZSBpZiB3ZSBoYWQgb3B0aW9ucworICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBlbnVtX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgZW51bV90eXBlKGkpLT5EZWJ1Z1N0cmluZygwLCAmY29udGVudHMsIGRlYnVnX3N0cmluZ19vcHRpb25zKTsKKyAgICBjb250ZW50cy5hcHBlbmQoIlxuIik7CisgIH0KKworICAvLyBGaW5kIGFsbCB0aGUgJ2dyb3VwJyB0eXBlIGV4dGVuc2lvbnM7IHdlIHdpbGwgbm90IG91dHB1dCB0aGVpciBuZXN0ZWQKKyAgLy8gZGVmaW5pdGlvbnMgKHRob3NlIHdpbGwgYmUgZG9uZSB3aXRoIHRoZWlyIGdyb3VwIGZpZWxkIGRlc2NyaXB0b3IpLgorICBzZXQ8Y29uc3QgRGVzY3JpcHRvcio+IGdyb3VwczsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBleHRlbnNpb25fY291bnQoKTsgaSsrKSB7CisgICAgaWYgKGV4dGVuc2lvbihpKS0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9HUk9VUCkgeworICAgICAgZ3JvdXBzLmluc2VydChleHRlbnNpb24oaSktPm1lc3NhZ2VfdHlwZSgpKTsKKyAgICB9CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IG1lc3NhZ2VfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBpZiAoZ3JvdXBzLmNvdW50KG1lc3NhZ2VfdHlwZShpKSkgPT0gMCkgeworICAgICAgbWVzc2FnZV90eXBlKGkpLT5EZWJ1Z1N0cmluZygwLCAmY29udGVudHMsIGRlYnVnX3N0cmluZ19vcHRpb25zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBpbmNsdWRlX29wZW5pbmdfY2xhdXNlICovIHRydWUpOworICAgICAgY29udGVudHMuYXBwZW5kKCJcbiIpOworICAgIH0KKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgc2VydmljZV9jb3VudCgpOyBpKyspIHsKKyAgICBzZXJ2aWNlKGkpLT5EZWJ1Z1N0cmluZygmY29udGVudHMsIGRlYnVnX3N0cmluZ19vcHRpb25zKTsKKyAgICBjb250ZW50cy5hcHBlbmQoIlxuIik7CisgIH0KKworICBjb25zdCBEZXNjcmlwdG9yKiBjb250YWluaW5nX3R5cGUgPSBOVUxMOworICBmb3IgKGludCBpID0gMDsgaSA8IGV4dGVuc2lvbl9jb3VudCgpOyBpKyspIHsKKyAgICBpZiAoZXh0ZW5zaW9uKGkpLT5jb250YWluaW5nX3R5cGUoKSAhPSBjb250YWluaW5nX3R5cGUpIHsKKyAgICAgIGlmIChpID4gMCkgY29udGVudHMuYXBwZW5kKCJ9XG5cbiIpOworICAgICAgY29udGFpbmluZ190eXBlID0gZXh0ZW5zaW9uKGkpLT5jb250YWluaW5nX3R5cGUoKTsKKyAgICAgIHN0cmluZ3M6OlN1YnN0aXR1dGVBbmRBcHBlbmQoJmNvbnRlbnRzLCAiZXh0ZW5kIC4kMCB7XG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250YWluaW5nX3R5cGUtPmZ1bGxfbmFtZSgpKTsKKyAgICB9CisgICAgZXh0ZW5zaW9uKGkpLT5EZWJ1Z1N0cmluZygxLCBGaWVsZERlc2NyaXB0b3I6OlBSSU5UX0xBQkVMLCAmY29udGVudHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWJ1Z19zdHJpbmdfb3B0aW9ucyk7CisgIH0KKyAgaWYgKGV4dGVuc2lvbl9jb3VudCgpID4gMCkgY29udGVudHMuYXBwZW5kKCJ9XG5cbiIpOworCisgIGNvbW1lbnRfcHJpbnRlci5BZGRQb3N0Q29tbWVudCgmY29udGVudHMpOworCisgIHJldHVybiBjb250ZW50czsKK30KKworc3RyaW5nIERlc2NyaXB0b3I6OkRlYnVnU3RyaW5nKCkgY29uc3QgeworICBEZWJ1Z1N0cmluZ09wdGlvbnMgb3B0aW9uczsgIC8vIGRlZmF1bHQgb3B0aW9ucworICByZXR1cm4gRGVidWdTdHJpbmdXaXRoT3B0aW9ucyhvcHRpb25zKTsKK30KKworc3RyaW5nIERlc2NyaXB0b3I6OkRlYnVnU3RyaW5nV2l0aE9wdGlvbnMoCisgICAgY29uc3QgRGVidWdTdHJpbmdPcHRpb25zJiBvcHRpb25zKSBjb25zdCB7CisgIHN0cmluZyBjb250ZW50czsKKyAgRGVidWdTdHJpbmcoMCwgJmNvbnRlbnRzLCBvcHRpb25zLCAvKiBpbmNsdWRlX29wZW5pbmdfY2xhdXNlICovIHRydWUpOworICByZXR1cm4gY29udGVudHM7Cit9CisKK3ZvaWQgRGVzY3JpcHRvcjo6RGVidWdTdHJpbmcoaW50IGRlcHRoLCBzdHJpbmcgKmNvbnRlbnRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEZWJ1Z1N0cmluZ09wdGlvbnMmCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlYnVnX3N0cmluZ19vcHRpb25zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGluY2x1ZGVfb3BlbmluZ19jbGF1c2UpIGNvbnN0IHsKKyAgaWYgKG9wdGlvbnMoKS5tYXBfZW50cnkoKSkgeworICAgIC8vIERvIG5vdCBnZW5lcmF0ZSBkZWJ1ZyBzdHJpbmcgZm9yIGF1dG8tZ2VuZXJhdGVkIG1hcC1lbnRyeSB0eXBlLgorICAgIHJldHVybjsKKyAgfQorICBzdHJpbmcgcHJlZml4KGRlcHRoICogMiwgJyAnKTsKKyAgKytkZXB0aDsKKworICBTb3VyY2VMb2NhdGlvbkNvbW1lbnRQcmludGVyCisgICAgICBjb21tZW50X3ByaW50ZXIodGhpcywgcHJlZml4LCBkZWJ1Z19zdHJpbmdfb3B0aW9ucyk7CisgIGNvbW1lbnRfcHJpbnRlci5BZGRQcmVDb21tZW50KGNvbnRlbnRzKTsKKworICBpZiAoaW5jbHVkZV9vcGVuaW5nX2NsYXVzZSkgeworICAgIHN0cmluZ3M6OlN1YnN0aXR1dGVBbmRBcHBlbmQoY29udGVudHMsICIkMG1lc3NhZ2UgJDEiLCBwcmVmaXgsIG5hbWUoKSk7CisgIH0KKyAgY29udGVudHMtPmFwcGVuZCgiIHtcbiIpOworCisgIEZvcm1hdExpbmVPcHRpb25zKGRlcHRoLCBvcHRpb25zKCksIGNvbnRlbnRzKTsKKworICAvLyBGaW5kIGFsbCB0aGUgJ2dyb3VwJyB0eXBlcyBmb3IgZmllbGRzIGFuZCBleHRlbnNpb25zOyB3ZSB3aWxsIG5vdCBvdXRwdXQKKyAgLy8gdGhlaXIgbmVzdGVkIGRlZmluaXRpb25zICh0aG9zZSB3aWxsIGJlIGRvbmUgd2l0aCB0aGVpciBncm91cCBmaWVsZAorICAvLyBkZXNjcmlwdG9yKS4KKyAgc2V0PGNvbnN0IERlc2NyaXB0b3IqPiBncm91cHM7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgaWYgKGZpZWxkKGkpLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQKSB7CisgICAgICBncm91cHMuaW5zZXJ0KGZpZWxkKGkpLT5tZXNzYWdlX3R5cGUoKSk7CisgICAgfQorICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZXh0ZW5zaW9uX2NvdW50KCk7IGkrKykgeworICAgIGlmIChleHRlbnNpb24oaSktPnR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfR1JPVVApIHsKKyAgICAgIGdyb3Vwcy5pbnNlcnQoZXh0ZW5zaW9uKGkpLT5tZXNzYWdlX3R5cGUoKSk7CisgICAgfQorICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBuZXN0ZWRfdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBpZiAoZ3JvdXBzLmNvdW50KG5lc3RlZF90eXBlKGkpKSA9PSAwKSB7CisgICAgICBuZXN0ZWRfdHlwZShpKS0+RGVidWdTdHJpbmcoZGVwdGgsIGNvbnRlbnRzLCBkZWJ1Z19zdHJpbmdfb3B0aW9ucywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBpbmNsdWRlX29wZW5pbmdfY2xhdXNlICovIHRydWUpOworICAgIH0KKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IGVudW1fdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBlbnVtX3R5cGUoaSktPkRlYnVnU3RyaW5nKGRlcHRoLCBjb250ZW50cywgZGVidWdfc3RyaW5nX29wdGlvbnMpOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgaWYgKGZpZWxkKGkpLT5jb250YWluaW5nX29uZW9mKCkgPT0gTlVMTCkgeworICAgICAgZmllbGQoaSktPkRlYnVnU3RyaW5nKGRlcHRoLCBGaWVsZERlc2NyaXB0b3I6OlBSSU5UX0xBQkVMLCBjb250ZW50cywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWJ1Z19zdHJpbmdfb3B0aW9ucyk7CisgICAgfSBlbHNlIGlmIChmaWVsZChpKS0+Y29udGFpbmluZ19vbmVvZigpLT5maWVsZCgwKSA9PSBmaWVsZChpKSkgeworICAgICAgLy8gVGhpcyBpcyB0aGUgZmlyc3QgZmllbGQgaW4gdGhpcyBvbmVvZiwgc28gcHJpbnQgdGhlIHdob2xlIG9uZW9mLgorICAgICAgZmllbGQoaSktPmNvbnRhaW5pbmdfb25lb2YoKS0+RGVidWdTdHJpbmcoZGVwdGgsIGNvbnRlbnRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVidWdfc3RyaW5nX29wdGlvbnMpOworICAgIH0KKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCk7IGkrKykgeworICAgIHN0cmluZ3M6OlN1YnN0aXR1dGVBbmRBcHBlbmQoY29udGVudHMsICIkMCAgZXh0ZW5zaW9ucyAkMSB0byAkMjtcbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25fcmFuZ2UoaSktPnN0YXJ0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uX3JhbmdlKGkpLT5lbmQgLSAxKTsKKyAgfQorCisgIC8vIEdyb3VwIGV4dGVuc2lvbnMgYnkgd2hhdCB0aGV5IGV4dGVuZCwgc28gdGhleSBjYW4gYmUgcHJpbnRlZCBvdXQgdG9nZXRoZXIuCisgIGNvbnN0IERlc2NyaXB0b3IqIGNvbnRhaW5pbmdfdHlwZSA9IE5VTEw7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZXh0ZW5zaW9uX2NvdW50KCk7IGkrKykgeworICAgIGlmIChleHRlbnNpb24oaSktPmNvbnRhaW5pbmdfdHlwZSgpICE9IGNvbnRhaW5pbmdfdHlwZSkgeworICAgICAgaWYgKGkgPiAwKSBzdHJpbmdzOjpTdWJzdGl0dXRlQW5kQXBwZW5kKGNvbnRlbnRzLCAiJDAgIH1cbiIsIHByZWZpeCk7CisgICAgICBjb250YWluaW5nX3R5cGUgPSBleHRlbnNpb24oaSktPmNvbnRhaW5pbmdfdHlwZSgpOworICAgICAgc3RyaW5nczo6U3Vic3RpdHV0ZUFuZEFwcGVuZChjb250ZW50cywgIiQwICBleHRlbmQgLiQxIHtcbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZWZpeCwgY29udGFpbmluZ190eXBlLT5mdWxsX25hbWUoKSk7CisgICAgfQorICAgIGV4dGVuc2lvbihpKS0+RGVidWdTdHJpbmcoCisgICAgICAgIGRlcHRoICsgMSwgRmllbGREZXNjcmlwdG9yOjpQUklOVF9MQUJFTCwgY29udGVudHMsCisgICAgICAgIGRlYnVnX3N0cmluZ19vcHRpb25zKTsKKyAgfQorICBpZiAoZXh0ZW5zaW9uX2NvdW50KCkgPiAwKQorICAgIHN0cmluZ3M6OlN1YnN0aXR1dGVBbmRBcHBlbmQoY29udGVudHMsICIkMCAgfVxuIiwgcHJlZml4KTsKKworICBpZiAocmVzZXJ2ZWRfcmFuZ2VfY291bnQoKSA+IDApIHsKKyAgICBzdHJpbmdzOjpTdWJzdGl0dXRlQW5kQXBwZW5kKGNvbnRlbnRzLCAiJDAgIHJlc2VydmVkICIsIHByZWZpeCk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXNlcnZlZF9yYW5nZV9jb3VudCgpOyBpKyspIHsKKyAgICAgIGNvbnN0IERlc2NyaXB0b3I6OlJlc2VydmVkUmFuZ2UqIHJhbmdlID0gcmVzZXJ2ZWRfcmFuZ2UoaSk7CisgICAgICBpZiAocmFuZ2UtPmVuZCA9PSByYW5nZS0+c3RhcnQgKyAxKSB7CisgICAgICAgIHN0cmluZ3M6OlN1YnN0aXR1dGVBbmRBcHBlbmQoY29udGVudHMsICIkMCwgIiwgcmFuZ2UtPnN0YXJ0KTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHN0cmluZ3M6OlN1YnN0aXR1dGVBbmRBcHBlbmQoY29udGVudHMsICIkMCB0byAkMSwgIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYW5nZS0+c3RhcnQsIHJhbmdlLT5lbmQgLSAxKTsKKyAgICAgIH0KKyAgICB9CisgICAgY29udGVudHMtPnJlcGxhY2UoY29udGVudHMtPnNpemUoKSAtIDIsIDIsICI7XG4iKTsKKyAgfQorCisgIGlmIChyZXNlcnZlZF9uYW1lX2NvdW50KCkgPiAwKSB7CisgICAgc3RyaW5nczo6U3Vic3RpdHV0ZUFuZEFwcGVuZChjb250ZW50cywgIiQwICByZXNlcnZlZCAiLCBwcmVmaXgpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVzZXJ2ZWRfbmFtZV9jb3VudCgpOyBpKyspIHsKKyAgICAgIHN0cmluZ3M6OlN1YnN0aXR1dGVBbmRBcHBlbmQoY29udGVudHMsICJcIiQwXCIsICIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENFc2NhcGUocmVzZXJ2ZWRfbmFtZShpKSkpOworICAgIH0KKyAgICBjb250ZW50cy0+cmVwbGFjZShjb250ZW50cy0+c2l6ZSgpIC0gMiwgMiwgIjtcbiIpOworICB9CisKKyAgc3RyaW5nczo6U3Vic3RpdHV0ZUFuZEFwcGVuZChjb250ZW50cywgIiQwfVxuIiwgcHJlZml4KTsKKyAgY29tbWVudF9wcmludGVyLkFkZFBvc3RDb21tZW50KGNvbnRlbnRzKTsKK30KKworc3RyaW5nIEZpZWxkRGVzY3JpcHRvcjo6RGVidWdTdHJpbmcoKSBjb25zdCB7CisgIERlYnVnU3RyaW5nT3B0aW9ucyBvcHRpb25zOyAgLy8gZGVmYXVsdCBvcHRpb25zCisgIHJldHVybiBEZWJ1Z1N0cmluZ1dpdGhPcHRpb25zKG9wdGlvbnMpOworfQorCitzdHJpbmcgRmllbGREZXNjcmlwdG9yOjpEZWJ1Z1N0cmluZ1dpdGhPcHRpb25zKAorICAgIGNvbnN0IERlYnVnU3RyaW5nT3B0aW9ucyYgZGVidWdfc3RyaW5nX29wdGlvbnMpIGNvbnN0IHsKKyAgc3RyaW5nIGNvbnRlbnRzOworICBpbnQgZGVwdGggPSAwOworICBpZiAoaXNfZXh0ZW5zaW9uKCkpIHsKKyAgICBzdHJpbmdzOjpTdWJzdGl0dXRlQW5kQXBwZW5kKCZjb250ZW50cywgImV4dGVuZCAuJDAge1xuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRhaW5pbmdfdHlwZSgpLT5mdWxsX25hbWUoKSk7CisgICAgZGVwdGggPSAxOworICB9CisgIERlYnVnU3RyaW5nKGRlcHRoLCBQUklOVF9MQUJFTCwgJmNvbnRlbnRzLCBkZWJ1Z19zdHJpbmdfb3B0aW9ucyk7CisgIGlmIChpc19leHRlbnNpb24oKSkgeworICAgIGNvbnRlbnRzLmFwcGVuZCgifVxuIik7CisgIH0KKyAgcmV0dXJuIGNvbnRlbnRzOworfQorCisvLyBUaGUgZmllbGQgdHlwZSBzdHJpbmcgdXNlZCBpbiBGaWVsZERlc2NyaXB0b3I6OkRlYnVnU3RyaW5nKCkKK3N0cmluZyBGaWVsZERlc2NyaXB0b3I6OkZpZWxkVHlwZU5hbWVEZWJ1Z1N0cmluZygpIGNvbnN0IHsKKyAgc3dpdGNoKHR5cGUoKSkgeworICAgIGNhc2UgVFlQRV9NRVNTQUdFOgorICAgICAgcmV0dXJuICIuIiArIG1lc3NhZ2VfdHlwZSgpLT5mdWxsX25hbWUoKTsKKyAgICBjYXNlIFRZUEVfRU5VTToKKyAgICAgIHJldHVybiAiLiIgKyBlbnVtX3R5cGUoKS0+ZnVsbF9uYW1lKCk7CisgICAgZGVmYXVsdDoKKyAgICAgIHJldHVybiBrVHlwZVRvTmFtZVt0eXBlKCldOworICB9Cit9CisKK3ZvaWQgRmllbGREZXNjcmlwdG9yOjpEZWJ1Z1N0cmluZyhpbnQgZGVwdGgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJpbnRMYWJlbEZsYWcgcHJpbnRfbGFiZWxfZmxhZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcgKmNvbnRlbnRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlYnVnU3RyaW5nT3B0aW9ucyYKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWJ1Z19zdHJpbmdfb3B0aW9ucykgY29uc3QgeworICBzdHJpbmcgcHJlZml4KGRlcHRoICogMiwgJyAnKTsKKyAgc3RyaW5nIGZpZWxkX3R5cGU7CisKKyAgLy8gU3BlY2lhbCBjYXNlIG1hcCBmaWVsZHMuCisgIGlmIChpc19tYXAoKSkgeworICAgIHN0cmluZ3M6OlN1YnN0aXR1dGVBbmRBcHBlbmQoCisgICAgICAgICZmaWVsZF90eXBlLCAibWFwPCQwLCAkMT4iLAorICAgICAgICBtZXNzYWdlX3R5cGUoKS0+ZmllbGQoMCktPkZpZWxkVHlwZU5hbWVEZWJ1Z1N0cmluZygpLAorICAgICAgICBtZXNzYWdlX3R5cGUoKS0+ZmllbGQoMSktPkZpZWxkVHlwZU5hbWVEZWJ1Z1N0cmluZygpKTsKKyAgfSBlbHNlIHsKKyAgICBmaWVsZF90eXBlID0gRmllbGRUeXBlTmFtZURlYnVnU3RyaW5nKCk7CisgIH0KKworICBzdHJpbmcgbGFiZWw7CisgIGlmIChwcmludF9sYWJlbF9mbGFnID09IFBSSU5UX0xBQkVMICYmICFpc19tYXAoKSkgeworICAgIGxhYmVsID0ga0xhYmVsVG9OYW1lW3RoaXMtPmxhYmVsKCldOworICAgIGxhYmVsLnB1c2hfYmFjaygnICcpOworICB9CisKKyAgU291cmNlTG9jYXRpb25Db21tZW50UHJpbnRlcgorICAgICAgY29tbWVudF9wcmludGVyKHRoaXMsIHByZWZpeCwgZGVidWdfc3RyaW5nX29wdGlvbnMpOworICBjb21tZW50X3ByaW50ZXIuQWRkUHJlQ29tbWVudChjb250ZW50cyk7CisKKyAgc3RyaW5nczo6U3Vic3RpdHV0ZUFuZEFwcGVuZChjb250ZW50cywgIiQwJDEkMiAkMyA9ICQ0IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGRfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlKCkgPT0gVFlQRV9HUk9VUCA/IG1lc3NhZ2VfdHlwZSgpLT5uYW1lKCkgOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bWJlcigpKTsKKworICBib29sIGJyYWNrZXRlZCA9IGZhbHNlOworICBpZiAoaGFzX2RlZmF1bHRfdmFsdWUoKSkgeworICAgIGJyYWNrZXRlZCA9IHRydWU7CisgICAgc3RyaW5nczo6U3Vic3RpdHV0ZUFuZEFwcGVuZChjb250ZW50cywgIiBbZGVmYXVsdCA9ICQwIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlZmF1bHRWYWx1ZUFzU3RyaW5nKHRydWUpKTsKKyAgfQorCisgIHN0cmluZyBmb3JtYXR0ZWRfb3B0aW9uczsKKyAgaWYgKEZvcm1hdEJyYWNrZXRlZE9wdGlvbnMoZGVwdGgsIG9wdGlvbnMoKSwgJmZvcm1hdHRlZF9vcHRpb25zKSkgeworICAgIGNvbnRlbnRzLT5hcHBlbmQoYnJhY2tldGVkID8gIiwgIiA6ICIgWyIpOworICAgIGJyYWNrZXRlZCA9IHRydWU7CisgICAgY29udGVudHMtPmFwcGVuZChmb3JtYXR0ZWRfb3B0aW9ucyk7CisgIH0KKworICBpZiAoYnJhY2tldGVkKSB7CisgICAgY29udGVudHMtPmFwcGVuZCgiXSIpOworICB9CisKKyAgaWYgKHR5cGUoKSA9PSBUWVBFX0dST1VQKSB7CisgICAgaWYgKGRlYnVnX3N0cmluZ19vcHRpb25zLmVsaWRlX2dyb3VwX2JvZHkpIHsKKyAgICAgIGNvbnRlbnRzLT5hcHBlbmQoIiB7IC4uLiB9O1xuIik7CisgICAgfSBlbHNlIHsKKyAgICAgIG1lc3NhZ2VfdHlwZSgpLT5EZWJ1Z1N0cmluZyhkZXB0aCwgY29udGVudHMsIGRlYnVnX3N0cmluZ19vcHRpb25zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGluY2x1ZGVfb3BlbmluZ19jbGF1c2UgKi8gZmFsc2UpOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICBjb250ZW50cy0+YXBwZW5kKCI7XG4iKTsKKyAgfQorCisgIGNvbW1lbnRfcHJpbnRlci5BZGRQb3N0Q29tbWVudChjb250ZW50cyk7Cit9CisKK3N0cmluZyBPbmVvZkRlc2NyaXB0b3I6OkRlYnVnU3RyaW5nKCkgY29uc3QgeworICBEZWJ1Z1N0cmluZ09wdGlvbnMgb3B0aW9uczsgIC8vIGRlZmF1bHQgdmFsdWVzCisgIHJldHVybiBEZWJ1Z1N0cmluZ1dpdGhPcHRpb25zKG9wdGlvbnMpOworfQorCitzdHJpbmcgT25lb2ZEZXNjcmlwdG9yOjpEZWJ1Z1N0cmluZ1dpdGhPcHRpb25zKAorICAgIGNvbnN0IERlYnVnU3RyaW5nT3B0aW9ucyYgb3B0aW9ucykgY29uc3QgeworICBzdHJpbmcgY29udGVudHM7CisgIERlYnVnU3RyaW5nKDAsICZjb250ZW50cywgb3B0aW9ucyk7CisgIHJldHVybiBjb250ZW50czsKK30KKwordm9pZCBPbmVvZkRlc2NyaXB0b3I6OkRlYnVnU3RyaW5nKGludCBkZXB0aCwgc3RyaW5nKiBjb250ZW50cywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEZWJ1Z1N0cmluZ09wdGlvbnMmCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVidWdfc3RyaW5nX29wdGlvbnMpIGNvbnN0IHsKKyAgc3RyaW5nIHByZWZpeChkZXB0aCAqIDIsICcgJyk7CisgICsrZGVwdGg7CisgIFNvdXJjZUxvY2F0aW9uQ29tbWVudFByaW50ZXIKKyAgICAgIGNvbW1lbnRfcHJpbnRlcih0aGlzLCBwcmVmaXgsIGRlYnVnX3N0cmluZ19vcHRpb25zKTsKKyAgY29tbWVudF9wcmludGVyLkFkZFByZUNvbW1lbnQoY29udGVudHMpOworICBzdHJpbmdzOjpTdWJzdGl0dXRlQW5kQXBwZW5kKAorICAgICAgY29udGVudHMsICIkMCBvbmVvZiAkMSB7IiwgcHJlZml4LCBuYW1lKCkpOworICBpZiAoZGVidWdfc3RyaW5nX29wdGlvbnMuZWxpZGVfb25lb2ZfYm9keSkgeworICAgIGNvbnRlbnRzLT5hcHBlbmQoIiAuLi4gfVxuIik7CisgIH0gZWxzZSB7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICAgIGZpZWxkKGkpLT5EZWJ1Z1N0cmluZyhkZXB0aCwgRmllbGREZXNjcmlwdG9yOjpPTUlUX0xBQkVMLCBjb250ZW50cywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWJ1Z19zdHJpbmdfb3B0aW9ucyk7CisgICAgfQorICAgIHN0cmluZ3M6OlN1YnN0aXR1dGVBbmRBcHBlbmQoY29udGVudHMsICIkMH1cbiIsIHByZWZpeCk7CisgIH0KKyAgY29tbWVudF9wcmludGVyLkFkZFBvc3RDb21tZW50KGNvbnRlbnRzKTsKK30KKworc3RyaW5nIEVudW1EZXNjcmlwdG9yOjpEZWJ1Z1N0cmluZygpIGNvbnN0IHsKKyAgRGVidWdTdHJpbmdPcHRpb25zIG9wdGlvbnM7ICAvLyBkZWZhdWx0IHZhbHVlcworICByZXR1cm4gRGVidWdTdHJpbmdXaXRoT3B0aW9ucyhvcHRpb25zKTsKK30KKworc3RyaW5nIEVudW1EZXNjcmlwdG9yOjpEZWJ1Z1N0cmluZ1dpdGhPcHRpb25zKAorICAgIGNvbnN0IERlYnVnU3RyaW5nT3B0aW9ucyYgb3B0aW9ucykgY29uc3QgeworICBzdHJpbmcgY29udGVudHM7CisgIERlYnVnU3RyaW5nKDAsICZjb250ZW50cywgb3B0aW9ucyk7CisgIHJldHVybiBjb250ZW50czsKK30KKwordm9pZCBFbnVtRGVzY3JpcHRvcjo6RGVidWdTdHJpbmcoaW50IGRlcHRoLCBzdHJpbmcgKmNvbnRlbnRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVidWdTdHJpbmdPcHRpb25zJgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVidWdfc3RyaW5nX29wdGlvbnMpIGNvbnN0IHsKKyAgc3RyaW5nIHByZWZpeChkZXB0aCAqIDIsICcgJyk7CisgICsrZGVwdGg7CisKKyAgU291cmNlTG9jYXRpb25Db21tZW50UHJpbnRlcgorICAgICAgY29tbWVudF9wcmludGVyKHRoaXMsIHByZWZpeCwgZGVidWdfc3RyaW5nX29wdGlvbnMpOworICBjb21tZW50X3ByaW50ZXIuQWRkUHJlQ29tbWVudChjb250ZW50cyk7CisKKyAgc3RyaW5nczo6U3Vic3RpdHV0ZUFuZEFwcGVuZChjb250ZW50cywgIiQwZW51bSAkMSB7XG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZWZpeCwgbmFtZSgpKTsKKworICBGb3JtYXRMaW5lT3B0aW9ucyhkZXB0aCwgb3B0aW9ucygpLCBjb250ZW50cyk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWx1ZV9jb3VudCgpOyBpKyspIHsKKyAgICB2YWx1ZShpKS0+RGVidWdTdHJpbmcoZGVwdGgsIGNvbnRlbnRzLCBkZWJ1Z19zdHJpbmdfb3B0aW9ucyk7CisgIH0KKyAgc3RyaW5nczo6U3Vic3RpdHV0ZUFuZEFwcGVuZChjb250ZW50cywgIiQwfVxuIiwgcHJlZml4KTsKKworICBjb21tZW50X3ByaW50ZXIuQWRkUG9zdENvbW1lbnQoY29udGVudHMpOworfQorCitzdHJpbmcgRW51bVZhbHVlRGVzY3JpcHRvcjo6RGVidWdTdHJpbmcoKSBjb25zdCB7CisgIERlYnVnU3RyaW5nT3B0aW9ucyBvcHRpb25zOyAgLy8gZGVmYXVsdCB2YWx1ZXMKKyAgcmV0dXJuIERlYnVnU3RyaW5nV2l0aE9wdGlvbnMob3B0aW9ucyk7Cit9CisKK3N0cmluZyBFbnVtVmFsdWVEZXNjcmlwdG9yOjpEZWJ1Z1N0cmluZ1dpdGhPcHRpb25zKAorICAgIGNvbnN0IERlYnVnU3RyaW5nT3B0aW9ucyYgb3B0aW9ucykgY29uc3QgeworICBzdHJpbmcgY29udGVudHM7CisgIERlYnVnU3RyaW5nKDAsICZjb250ZW50cywgb3B0aW9ucyk7CisgIHJldHVybiBjb250ZW50czsKK30KKwordm9pZCBFbnVtVmFsdWVEZXNjcmlwdG9yOjpEZWJ1Z1N0cmluZyhpbnQgZGVwdGgsIHN0cmluZyAqY29udGVudHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlYnVnU3RyaW5nT3B0aW9ucyYKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVidWdfc3RyaW5nX29wdGlvbnMpIGNvbnN0IHsKKyAgc3RyaW5nIHByZWZpeChkZXB0aCAqIDIsICcgJyk7CisKKyAgU291cmNlTG9jYXRpb25Db21tZW50UHJpbnRlcgorICAgICAgY29tbWVudF9wcmludGVyKHRoaXMsIHByZWZpeCwgZGVidWdfc3RyaW5nX29wdGlvbnMpOworICBjb21tZW50X3ByaW50ZXIuQWRkUHJlQ29tbWVudChjb250ZW50cyk7CisKKyAgc3RyaW5nczo6U3Vic3RpdHV0ZUFuZEFwcGVuZChjb250ZW50cywgIiQwJDEgPSAkMiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlZml4LCBuYW1lKCksIG51bWJlcigpKTsKKworICBzdHJpbmcgZm9ybWF0dGVkX29wdGlvbnM7CisgIGlmIChGb3JtYXRCcmFja2V0ZWRPcHRpb25zKGRlcHRoLCBvcHRpb25zKCksICZmb3JtYXR0ZWRfb3B0aW9ucykpIHsKKyAgICBzdHJpbmdzOjpTdWJzdGl0dXRlQW5kQXBwZW5kKGNvbnRlbnRzLCAiIFskMF0iLCBmb3JtYXR0ZWRfb3B0aW9ucyk7CisgIH0KKyAgY29udGVudHMtPmFwcGVuZCgiO1xuIik7CisKKyAgY29tbWVudF9wcmludGVyLkFkZFBvc3RDb21tZW50KGNvbnRlbnRzKTsKK30KKworc3RyaW5nIFNlcnZpY2VEZXNjcmlwdG9yOjpEZWJ1Z1N0cmluZygpIGNvbnN0IHsKKyAgRGVidWdTdHJpbmdPcHRpb25zIG9wdGlvbnM7ICAvLyBkZWZhdWx0IHZhbHVlcworICByZXR1cm4gRGVidWdTdHJpbmdXaXRoT3B0aW9ucyhvcHRpb25zKTsKK30KKworc3RyaW5nIFNlcnZpY2VEZXNjcmlwdG9yOjpEZWJ1Z1N0cmluZ1dpdGhPcHRpb25zKAorICAgIGNvbnN0IERlYnVnU3RyaW5nT3B0aW9ucyYgb3B0aW9ucykgY29uc3QgeworICBzdHJpbmcgY29udGVudHM7CisgIERlYnVnU3RyaW5nKCZjb250ZW50cywgb3B0aW9ucyk7CisgIHJldHVybiBjb250ZW50czsKK30KKwordm9pZCBTZXJ2aWNlRGVzY3JpcHRvcjo6RGVidWdTdHJpbmcoc3RyaW5nICpjb250ZW50cywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlYnVnU3RyaW5nT3B0aW9ucyYKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlYnVnX3N0cmluZ19vcHRpb25zKSBjb25zdCB7CisgIFNvdXJjZUxvY2F0aW9uQ29tbWVudFByaW50ZXIKKyAgICAgIGNvbW1lbnRfcHJpbnRlcih0aGlzLCAvKiBwcmVmaXggKi8gIiIsIGRlYnVnX3N0cmluZ19vcHRpb25zKTsKKyAgY29tbWVudF9wcmludGVyLkFkZFByZUNvbW1lbnQoY29udGVudHMpOworCisgIHN0cmluZ3M6OlN1YnN0aXR1dGVBbmRBcHBlbmQoY29udGVudHMsICJzZXJ2aWNlICQwIHtcbiIsIG5hbWUoKSk7CisKKyAgRm9ybWF0TGluZU9wdGlvbnMoMSwgb3B0aW9ucygpLCBjb250ZW50cyk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZXRob2RfY291bnQoKTsgaSsrKSB7CisgICAgbWV0aG9kKGkpLT5EZWJ1Z1N0cmluZygxLCBjb250ZW50cywgZGVidWdfc3RyaW5nX29wdGlvbnMpOworICB9CisKKyAgY29udGVudHMtPmFwcGVuZCgifVxuIik7CisKKyAgY29tbWVudF9wcmludGVyLkFkZFBvc3RDb21tZW50KGNvbnRlbnRzKTsKK30KKworc3RyaW5nIE1ldGhvZERlc2NyaXB0b3I6OkRlYnVnU3RyaW5nKCkgY29uc3QgeworICBEZWJ1Z1N0cmluZ09wdGlvbnMgb3B0aW9uczsgIC8vIGRlZmF1bHQgdmFsdWVzCisgIHJldHVybiBEZWJ1Z1N0cmluZ1dpdGhPcHRpb25zKG9wdGlvbnMpOworfQorCitzdHJpbmcgTWV0aG9kRGVzY3JpcHRvcjo6RGVidWdTdHJpbmdXaXRoT3B0aW9ucygKKyAgICBjb25zdCBEZWJ1Z1N0cmluZ09wdGlvbnMmIG9wdGlvbnMpIGNvbnN0IHsKKyAgc3RyaW5nIGNvbnRlbnRzOworICBEZWJ1Z1N0cmluZygwLCAmY29udGVudHMsIG9wdGlvbnMpOworICByZXR1cm4gY29udGVudHM7Cit9CisKK3ZvaWQgTWV0aG9kRGVzY3JpcHRvcjo6RGVidWdTdHJpbmcoaW50IGRlcHRoLCBzdHJpbmcgKmNvbnRlbnRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEZWJ1Z1N0cmluZ09wdGlvbnMmCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlYnVnX3N0cmluZ19vcHRpb25zKSBjb25zdCB7CisgIHN0cmluZyBwcmVmaXgoZGVwdGggKiAyLCAnICcpOworICArK2RlcHRoOworCisgIFNvdXJjZUxvY2F0aW9uQ29tbWVudFByaW50ZXIKKyAgICAgIGNvbW1lbnRfcHJpbnRlcih0aGlzLCBwcmVmaXgsIGRlYnVnX3N0cmluZ19vcHRpb25zKTsKKyAgY29tbWVudF9wcmludGVyLkFkZFByZUNvbW1lbnQoY29udGVudHMpOworCisgIHN0cmluZ3M6OlN1YnN0aXR1dGVBbmRBcHBlbmQoY29udGVudHMsICIkMHJwYyAkMSgkNC4kMikgcmV0dXJucyAoJDUuJDMpIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXgsIG5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dF90eXBlKCktPmZ1bGxfbmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dF90eXBlKCktPmZ1bGxfbmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsaWVudF9zdHJlYW1pbmcoKSA/ICJzdHJlYW0gIiA6ICIiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcnZlcl9zdHJlYW1pbmcoKSA/ICJzdHJlYW0gIiA6ICIiKTsKKworICBzdHJpbmcgZm9ybWF0dGVkX29wdGlvbnM7CisgIGlmIChGb3JtYXRMaW5lT3B0aW9ucyhkZXB0aCwgb3B0aW9ucygpLCAmZm9ybWF0dGVkX29wdGlvbnMpKSB7CisgICAgc3RyaW5nczo6U3Vic3RpdHV0ZUFuZEFwcGVuZChjb250ZW50cywgIiB7XG4kMCQxfVxuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1hdHRlZF9vcHRpb25zLCBwcmVmaXgpOworICB9IGVsc2UgeworICAgIGNvbnRlbnRzLT5hcHBlbmQoIjtcbiIpOworICB9CisKKyAgY29tbWVudF9wcmludGVyLkFkZFBvc3RDb21tZW50KGNvbnRlbnRzKTsKK30KKworCisvLyBMb2NhdGlvbiBtZXRob2RzID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK2Jvb2wgRmlsZURlc2NyaXB0b3I6OkdldFNvdXJjZUxvY2F0aW9uKGNvbnN0IHZlY3RvcjxpbnQ+JiBwYXRoLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU291cmNlTG9jYXRpb24qIG91dF9sb2NhdGlvbikgY29uc3QgeworICBHT09HTEVfQ0hFQ0tfTk9UTlVMTChvdXRfbG9jYXRpb24pOworICBpZiAoc291cmNlX2NvZGVfaW5mb18pIHsKKyAgICBpZiAoY29uc3QgU291cmNlQ29kZUluZm9fTG9jYXRpb24qIGxvYyA9CisgICAgICAgIHRhYmxlc18tPkdldFNvdXJjZUxvY2F0aW9uKHBhdGgsIHNvdXJjZV9jb2RlX2luZm9fKSkgeworICAgICAgY29uc3QgUmVwZWF0ZWRGaWVsZDxpbnQzMj4mIHNwYW4gPSBsb2MtPnNwYW4oKTsKKyAgICAgIGlmIChzcGFuLnNpemUoKSA9PSAzIHx8IHNwYW4uc2l6ZSgpID09IDQpIHsKKyAgICAgICAgb3V0X2xvY2F0aW9uLT5zdGFydF9saW5lICAgPSBzcGFuLkdldCgwKTsKKyAgICAgICAgb3V0X2xvY2F0aW9uLT5zdGFydF9jb2x1bW4gPSBzcGFuLkdldCgxKTsKKyAgICAgICAgb3V0X2xvY2F0aW9uLT5lbmRfbGluZSAgICAgPSBzcGFuLkdldChzcGFuLnNpemUoKSA9PSAzID8gMCA6IDIpOworICAgICAgICBvdXRfbG9jYXRpb24tPmVuZF9jb2x1bW4gICA9IHNwYW4uR2V0KHNwYW4uc2l6ZSgpIC0gMSk7CisKKyAgICAgICAgb3V0X2xvY2F0aW9uLT5sZWFkaW5nX2NvbW1lbnRzID0gbG9jLT5sZWFkaW5nX2NvbW1lbnRzKCk7CisgICAgICAgIG91dF9sb2NhdGlvbi0+dHJhaWxpbmdfY29tbWVudHMgPSBsb2MtPnRyYWlsaW5nX2NvbW1lbnRzKCk7CisgICAgICAgIG91dF9sb2NhdGlvbi0+bGVhZGluZ19kZXRhY2hlZF9jb21tZW50cy5hc3NpZ24oCisgICAgICAgICAgICBsb2MtPmxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMoKS5iZWdpbigpLAorICAgICAgICAgICAgbG9jLT5sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKCkuZW5kKCkpOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0KKyAgICB9CisgIH0KKyAgcmV0dXJuIGZhbHNlOworfQorCitib29sIEZpbGVEZXNjcmlwdG9yOjpHZXRTb3VyY2VMb2NhdGlvbihTb3VyY2VMb2NhdGlvbiogb3V0X2xvY2F0aW9uKSBjb25zdCB7CisgIHZlY3RvcjxpbnQ+IHBhdGg7ICAvLyBlbXB0eSBwYXRoIGZvciByb290IEZpbGVEZXNjcmlwdG9yCisgIHJldHVybiBHZXRTb3VyY2VMb2NhdGlvbihwYXRoLCBvdXRfbG9jYXRpb24pOworfQorCitib29sIEZpZWxkRGVzY3JpcHRvcjo6aXNfcGFja2VkKCkgY29uc3QgeworICBpZiAoIWlzX3BhY2thYmxlKCkpIHJldHVybiBmYWxzZTsKKyAgaWYgKGZpbGVfLT5zeW50YXgoKSA9PSBGaWxlRGVzY3JpcHRvcjo6U1lOVEFYX1BST1RPMikgeworICAgIHJldHVybiAob3B0aW9uc18gIT0gTlVMTCkgJiYgb3B0aW9uc18tPnBhY2tlZCgpOworICB9IGVsc2UgeworICAgIHJldHVybiBvcHRpb25zXyA9PSBOVUxMIHx8ICFvcHRpb25zXy0+aGFzX3BhY2tlZCgpIHx8IG9wdGlvbnNfLT5wYWNrZWQoKTsKKyAgfQorfQorCitib29sIERlc2NyaXB0b3I6OkdldFNvdXJjZUxvY2F0aW9uKFNvdXJjZUxvY2F0aW9uKiBvdXRfbG9jYXRpb24pIGNvbnN0IHsKKyAgdmVjdG9yPGludD4gcGF0aDsKKyAgR2V0TG9jYXRpb25QYXRoKCZwYXRoKTsKKyAgcmV0dXJuIGZpbGUoKS0+R2V0U291cmNlTG9jYXRpb24ocGF0aCwgb3V0X2xvY2F0aW9uKTsKK30KKworYm9vbCBGaWVsZERlc2NyaXB0b3I6OkdldFNvdXJjZUxvY2F0aW9uKFNvdXJjZUxvY2F0aW9uKiBvdXRfbG9jYXRpb24pIGNvbnN0IHsKKyAgdmVjdG9yPGludD4gcGF0aDsKKyAgR2V0TG9jYXRpb25QYXRoKCZwYXRoKTsKKyAgcmV0dXJuIGZpbGUoKS0+R2V0U291cmNlTG9jYXRpb24ocGF0aCwgb3V0X2xvY2F0aW9uKTsKK30KKworYm9vbCBPbmVvZkRlc2NyaXB0b3I6OkdldFNvdXJjZUxvY2F0aW9uKFNvdXJjZUxvY2F0aW9uKiBvdXRfbG9jYXRpb24pIGNvbnN0IHsKKyAgdmVjdG9yPGludD4gcGF0aDsKKyAgR2V0TG9jYXRpb25QYXRoKCZwYXRoKTsKKyAgcmV0dXJuIGNvbnRhaW5pbmdfdHlwZSgpLT5maWxlKCktPkdldFNvdXJjZUxvY2F0aW9uKHBhdGgsIG91dF9sb2NhdGlvbik7Cit9CisKK2Jvb2wgRW51bURlc2NyaXB0b3I6OkdldFNvdXJjZUxvY2F0aW9uKFNvdXJjZUxvY2F0aW9uKiBvdXRfbG9jYXRpb24pIGNvbnN0IHsKKyAgdmVjdG9yPGludD4gcGF0aDsKKyAgR2V0TG9jYXRpb25QYXRoKCZwYXRoKTsKKyAgcmV0dXJuIGZpbGUoKS0+R2V0U291cmNlTG9jYXRpb24ocGF0aCwgb3V0X2xvY2F0aW9uKTsKK30KKworYm9vbCBNZXRob2REZXNjcmlwdG9yOjpHZXRTb3VyY2VMb2NhdGlvbihTb3VyY2VMb2NhdGlvbiogb3V0X2xvY2F0aW9uKSBjb25zdCB7CisgIHZlY3RvcjxpbnQ+IHBhdGg7CisgIEdldExvY2F0aW9uUGF0aCgmcGF0aCk7CisgIHJldHVybiBzZXJ2aWNlKCktPmZpbGUoKS0+R2V0U291cmNlTG9jYXRpb24ocGF0aCwgb3V0X2xvY2F0aW9uKTsKK30KKworYm9vbCBTZXJ2aWNlRGVzY3JpcHRvcjo6R2V0U291cmNlTG9jYXRpb24oU291cmNlTG9jYXRpb24qIG91dF9sb2NhdGlvbikgY29uc3QgeworICB2ZWN0b3I8aW50PiBwYXRoOworICBHZXRMb2NhdGlvblBhdGgoJnBhdGgpOworICByZXR1cm4gZmlsZSgpLT5HZXRTb3VyY2VMb2NhdGlvbihwYXRoLCBvdXRfbG9jYXRpb24pOworfQorCitib29sIEVudW1WYWx1ZURlc2NyaXB0b3I6OkdldFNvdXJjZUxvY2F0aW9uKAorICAgIFNvdXJjZUxvY2F0aW9uKiBvdXRfbG9jYXRpb24pIGNvbnN0IHsKKyAgdmVjdG9yPGludD4gcGF0aDsKKyAgR2V0TG9jYXRpb25QYXRoKCZwYXRoKTsKKyAgcmV0dXJuIHR5cGUoKS0+ZmlsZSgpLT5HZXRTb3VyY2VMb2NhdGlvbihwYXRoLCBvdXRfbG9jYXRpb24pOworfQorCit2b2lkIERlc2NyaXB0b3I6OkdldExvY2F0aW9uUGF0aCh2ZWN0b3I8aW50Piogb3V0cHV0KSBjb25zdCB7CisgIGlmIChjb250YWluaW5nX3R5cGUoKSkgeworICAgIGNvbnRhaW5pbmdfdHlwZSgpLT5HZXRMb2NhdGlvblBhdGgob3V0cHV0KTsKKyAgICBvdXRwdXQtPnB1c2hfYmFjayhEZXNjcmlwdG9yUHJvdG86OmtOZXN0ZWRUeXBlRmllbGROdW1iZXIpOworICAgIG91dHB1dC0+cHVzaF9iYWNrKGluZGV4KCkpOworICB9IGVsc2UgeworICAgIG91dHB1dC0+cHVzaF9iYWNrKEZpbGVEZXNjcmlwdG9yUHJvdG86OmtNZXNzYWdlVHlwZUZpZWxkTnVtYmVyKTsKKyAgICBvdXRwdXQtPnB1c2hfYmFjayhpbmRleCgpKTsKKyAgfQorfQorCit2b2lkIEZpZWxkRGVzY3JpcHRvcjo6R2V0TG9jYXRpb25QYXRoKHZlY3RvcjxpbnQ+KiBvdXRwdXQpIGNvbnN0IHsKKyAgaWYgKGlzX2V4dGVuc2lvbigpKSB7CisgICAgaWYgKGV4dGVuc2lvbl9zY29wZSgpID09IE5VTEwpIHsKKyAgICAgIG91dHB1dC0+cHVzaF9iYWNrKEZpbGVEZXNjcmlwdG9yUHJvdG86OmtFeHRlbnNpb25GaWVsZE51bWJlcik7CisgICAgICBvdXRwdXQtPnB1c2hfYmFjayhpbmRleCgpKTsKKyAgICB9IGVsc2UgeworICAgICAgZXh0ZW5zaW9uX3Njb3BlKCktPkdldExvY2F0aW9uUGF0aChvdXRwdXQpOworICAgICAgb3V0cHV0LT5wdXNoX2JhY2soRGVzY3JpcHRvclByb3RvOjprRXh0ZW5zaW9uRmllbGROdW1iZXIpOworICAgICAgb3V0cHV0LT5wdXNoX2JhY2soaW5kZXgoKSk7CisgICAgfQorICB9IGVsc2UgeworICAgIGNvbnRhaW5pbmdfdHlwZSgpLT5HZXRMb2NhdGlvblBhdGgob3V0cHV0KTsKKyAgICBvdXRwdXQtPnB1c2hfYmFjayhEZXNjcmlwdG9yUHJvdG86OmtGaWVsZEZpZWxkTnVtYmVyKTsKKyAgICBvdXRwdXQtPnB1c2hfYmFjayhpbmRleCgpKTsKKyAgfQorfQorCit2b2lkIE9uZW9mRGVzY3JpcHRvcjo6R2V0TG9jYXRpb25QYXRoKHZlY3RvcjxpbnQ+KiBvdXRwdXQpIGNvbnN0IHsKKyAgY29udGFpbmluZ190eXBlKCktPkdldExvY2F0aW9uUGF0aChvdXRwdXQpOworICBvdXRwdXQtPnB1c2hfYmFjayhEZXNjcmlwdG9yUHJvdG86OmtPbmVvZkRlY2xGaWVsZE51bWJlcik7CisgIG91dHB1dC0+cHVzaF9iYWNrKGluZGV4KCkpOworfQorCit2b2lkIEVudW1EZXNjcmlwdG9yOjpHZXRMb2NhdGlvblBhdGgodmVjdG9yPGludD4qIG91dHB1dCkgY29uc3QgeworICBpZiAoY29udGFpbmluZ190eXBlKCkpIHsKKyAgICBjb250YWluaW5nX3R5cGUoKS0+R2V0TG9jYXRpb25QYXRoKG91dHB1dCk7CisgICAgb3V0cHV0LT5wdXNoX2JhY2soRGVzY3JpcHRvclByb3RvOjprRW51bVR5cGVGaWVsZE51bWJlcik7CisgICAgb3V0cHV0LT5wdXNoX2JhY2soaW5kZXgoKSk7CisgIH0gZWxzZSB7CisgICAgb3V0cHV0LT5wdXNoX2JhY2soRmlsZURlc2NyaXB0b3JQcm90bzo6a0VudW1UeXBlRmllbGROdW1iZXIpOworICAgIG91dHB1dC0+cHVzaF9iYWNrKGluZGV4KCkpOworICB9Cit9CisKK3ZvaWQgRW51bVZhbHVlRGVzY3JpcHRvcjo6R2V0TG9jYXRpb25QYXRoKHZlY3RvcjxpbnQ+KiBvdXRwdXQpIGNvbnN0IHsKKyAgdHlwZSgpLT5HZXRMb2NhdGlvblBhdGgob3V0cHV0KTsKKyAgb3V0cHV0LT5wdXNoX2JhY2soRW51bURlc2NyaXB0b3JQcm90bzo6a1ZhbHVlRmllbGROdW1iZXIpOworICBvdXRwdXQtPnB1c2hfYmFjayhpbmRleCgpKTsKK30KKwordm9pZCBTZXJ2aWNlRGVzY3JpcHRvcjo6R2V0TG9jYXRpb25QYXRoKHZlY3RvcjxpbnQ+KiBvdXRwdXQpIGNvbnN0IHsKKyAgb3V0cHV0LT5wdXNoX2JhY2soRmlsZURlc2NyaXB0b3JQcm90bzo6a1NlcnZpY2VGaWVsZE51bWJlcik7CisgIG91dHB1dC0+cHVzaF9iYWNrKGluZGV4KCkpOworfQorCit2b2lkIE1ldGhvZERlc2NyaXB0b3I6OkdldExvY2F0aW9uUGF0aCh2ZWN0b3I8aW50Piogb3V0cHV0KSBjb25zdCB7CisgIHNlcnZpY2UoKS0+R2V0TG9jYXRpb25QYXRoKG91dHB1dCk7CisgIG91dHB1dC0+cHVzaF9iYWNrKFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86OmtNZXRob2RGaWVsZE51bWJlcik7CisgIG91dHB1dC0+cHVzaF9iYWNrKGluZGV4KCkpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK25hbWVzcGFjZSB7CisKKy8vIFJlcHJlc2VudHMgYW4gb3B0aW9ucyBtZXNzYWdlIHRvIGludGVycHJldC4gRXh0ZW5zaW9uIG5hbWVzIGluIHRoZSBvcHRpb24KKy8vIG5hbWUgYXJlIHJlc29sdmVkIHJlbGF0aXZlIHRvIG5hbWVfc2NvcGUuIGVsZW1lbnRfbmFtZSBhbmQgb3JpZ19vcHQgYXJlCisvLyB1c2VkIG9ubHkgZm9yIGVycm9yIHJlcG9ydGluZyAoc2luY2UgdGhlIHBhcnNlciByZWNvcmRzIGxvY2F0aW9ucyBhZ2FpbnN0CisvLyBwb2ludGVycyBpbiB0aGUgb3JpZ2luYWwgb3B0aW9ucywgbm90IHRoZSBtdXRhYmxlIGNvcHkpLiBUaGUgTWVzc2FnZSBtdXN0IGJlCisvLyBvbmUgb2YgdGhlIE9wdGlvbnMgbWVzc2FnZXMgaW4gZGVzY3JpcHRvci5wcm90by4KK3N0cnVjdCBPcHRpb25zVG9JbnRlcnByZXQgeworICBPcHRpb25zVG9JbnRlcnByZXQoY29uc3Qgc3RyaW5nJiBucywKKyAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgZWwsCisgICAgICAgICAgICAgICAgICAgICBjb25zdCBNZXNzYWdlKiBvcmlnX29wdCwKKyAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UqIG9wdCkKKyAgICAgIDogbmFtZV9zY29wZShucyksCisgICAgICAgIGVsZW1lbnRfbmFtZShlbCksCisgICAgICAgIG9yaWdpbmFsX29wdGlvbnMob3JpZ19vcHQpLAorICAgICAgICBvcHRpb25zKG9wdCkgeworICB9CisgIHN0cmluZyBuYW1lX3Njb3BlOworICBzdHJpbmcgZWxlbWVudF9uYW1lOworICBjb25zdCBNZXNzYWdlKiBvcmlnaW5hbF9vcHRpb25zOworICBNZXNzYWdlKiBvcHRpb25zOworfTsKKworfSAgLy8gbmFtZXNwYWNlCisKK2NsYXNzIERlc2NyaXB0b3JCdWlsZGVyIHsKKyBwdWJsaWM6CisgIERlc2NyaXB0b3JCdWlsZGVyKGNvbnN0IERlc2NyaXB0b3JQb29sKiBwb29sLAorICAgICAgICAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6VGFibGVzKiB0YWJsZXMsCisgICAgICAgICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3RvciogZXJyb3JfY29sbGVjdG9yKTsKKyAgfkRlc2NyaXB0b3JCdWlsZGVyKCk7CisKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIEJ1aWxkRmlsZShjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvJiBwcm90byk7CisKKyBwcml2YXRlOgorICBmcmllbmQgY2xhc3MgT3B0aW9uSW50ZXJwcmV0ZXI7CisKKyAgY29uc3QgRGVzY3JpcHRvclBvb2wqIHBvb2xfOworICBEZXNjcmlwdG9yUG9vbDo6VGFibGVzKiB0YWJsZXNfOyAgLy8gZm9yIGNvbnZlbmllbmNlCisgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3RvciogZXJyb3JfY29sbGVjdG9yXzsKKworICAvLyBBcyB3ZSBidWlsZCBkZXNjcmlwdG9ycyB3ZSBzdG9yZSBjb3BpZXMgb2YgdGhlIG9wdGlvbnMgbWVzc2FnZXMgaW4KKyAgLy8gdGhlbS4gV2UgcHV0IHBvaW50ZXJzIHRvIHRob3NlIGNvcGllcyBpbiB0aGlzIHZlY3RvciwgYXMgd2UgYnVpbGQsIHNvIHdlCisgIC8vIGNhbiBsYXRlciAoYWZ0ZXIgY3Jvc3MtbGlua2luZykgaW50ZXJwcmV0IHRob3NlIG9wdGlvbnMuCisgIHZlY3RvcjxPcHRpb25zVG9JbnRlcnByZXQ+IG9wdGlvbnNfdG9faW50ZXJwcmV0XzsKKworICBib29sIGhhZF9lcnJvcnNfOworICBzdHJpbmcgZmlsZW5hbWVfOworICBGaWxlRGVzY3JpcHRvciogZmlsZV87CisgIEZpbGVEZXNjcmlwdG9yVGFibGVzKiBmaWxlX3RhYmxlc187CisgIHNldDxjb25zdCBGaWxlRGVzY3JpcHRvcio+IGRlcGVuZGVuY2llc187CisKKyAgLy8gdW51c2VkX2RlcGVuZGVuY3lfIGlzIHVzZWQgdG8gcmVjb3JkIHRoZSB1bnVzZWQgaW1wb3J0ZWQgZmlsZXMuCisgIC8vIE5vdGU6IHB1YmxpYyBpbXBvcnQgaXMgbm90IGNvbnNpZGVyZWQuCisgIHNldDxjb25zdCBGaWxlRGVzY3JpcHRvcio+IHVudXNlZF9kZXBlbmRlbmN5XzsKKworICAvLyBJZiBMb29rdXBTeW1ib2woKSBmaW5kcyBhIHN5bWJvbCB0aGF0IGlzIGluIGEgZmlsZSB3aGljaCBpcyBub3QgYSBkZWNsYXJlZAorICAvLyBkZXBlbmRlbmN5IG9mIHRoaXMgZmlsZSwgaXQgd2lsbCBmYWlsLCBidXQgd2lsbCBzZXQKKyAgLy8gcG9zc2libGVfdW5kZWNsYXJlZF9kZXBlbmRlbmN5XyB0byBwb2ludCBhdCB0aGF0IGZpbGUuICBUaGlzIGlzIG9ubHkgdXNlZAorICAvLyBieSBBZGROb3REZWZpbmVkRXJyb3IoKSB0byByZXBvcnQgYSBtb3JlIHVzZWZ1bCBlcnJvciBtZXNzYWdlLgorICAvLyBwb3NzaWJsZV91bmRlY2xhcmVkX2RlcGVuZGVuY3lfbmFtZV8gaXMgdGhlIG5hbWUgb2YgdGhlIHN5bWJvbCB0aGF0IHdhcworICAvLyBhY3R1YWxseSBmb3VuZCBpbiBwb3NzaWJsZV91bmRlY2xhcmVkX2RlcGVuZGVuY3lfLCB3aGljaCBtYXkgYmUgYSBwYXJlbnQKKyAgLy8gb2YgdGhlIHN5bWJvbCBhY3R1YWxseSBsb29rZWQgZm9yLgorICBjb25zdCBGaWxlRGVzY3JpcHRvciogcG9zc2libGVfdW5kZWNsYXJlZF9kZXBlbmRlbmN5XzsKKyAgc3RyaW5nIHBvc3NpYmxlX3VuZGVjbGFyZWRfZGVwZW5kZW5jeV9uYW1lXzsKKworICAvLyBJZiBMb29rdXBTeW1ib2woKSBjb3VsZCByZXNvbHZlIGEgc3ltYm9sIHdoaWNoIGlzIG5vdCBkZWZpbmVkLAorICAvLyByZWNvcmQgdGhlIHJlc29sdmVkIG5hbWUuICBUaGlzIGlzIG9ubHkgdXNlZCBieSBBZGROb3REZWZpbmVkRXJyb3IoKQorICAvLyB0byByZXBvcnQgYSBtb3JlIHVzZWZ1bCBlcnJvciBtZXNzYWdlLgorICBzdHJpbmcgdW5kZWZpbmVfcmVzb2x2ZWRfbmFtZV87CisKKyAgdm9pZCBBZGRFcnJvcihjb25zdCBzdHJpbmcmIGVsZW1lbnRfbmFtZSwKKyAgICAgICAgICAgICAgICBjb25zdCBNZXNzYWdlJiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6RXJyb3JMb2NhdGlvbiBsb2NhdGlvbiwKKyAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIGVycm9yKTsKKyAgdm9pZCBBZGRFcnJvcihjb25zdCBzdHJpbmcmIGVsZW1lbnRfbmFtZSwKKyAgICAgICAgICAgICAgICBjb25zdCBNZXNzYWdlJiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6RXJyb3JMb2NhdGlvbiBsb2NhdGlvbiwKKyAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiBlcnJvcik7CisgIHZvaWQgQWRkUmVjdXJzaXZlSW1wb3J0RXJyb3IoY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byYgcHJvdG8sIGludCBmcm9tX2hlcmUpOworICB2b2lkIEFkZFR3aWNlTGlzdGVkRXJyb3IoY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byYgcHJvdG8sIGludCBpbmRleCk7CisgIHZvaWQgQWRkSW1wb3J0RXJyb3IoY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byYgcHJvdG8sIGludCBpbmRleCk7CisKKyAgLy8gQWRkcyBhbiBlcnJvciBpbmRpY2F0aW5nIHRoYXQgdW5kZWZpbmVkX3N5bWJvbCB3YXMgbm90IGRlZmluZWQuICBNdXN0CisgIC8vIG9ubHkgYmUgY2FsbGVkIGFmdGVyIExvb2t1cFN5bWJvbCgpIGZhaWxzLgorICB2b2lkIEFkZE5vdERlZmluZWRFcnJvcigKKyAgICBjb25zdCBzdHJpbmcmIGVsZW1lbnRfbmFtZSwKKyAgICBjb25zdCBNZXNzYWdlJiBkZXNjcmlwdG9yLAorICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6RXJyb3JMb2NhdGlvbiBsb2NhdGlvbiwKKyAgICBjb25zdCBzdHJpbmcmIHVuZGVmaW5lZF9zeW1ib2wpOworCisgIHZvaWQgQWRkV2FybmluZyhjb25zdCBzdHJpbmcmIGVsZW1lbnRfbmFtZSwgY29uc3QgTWVzc2FnZSYgZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6RXJyb3JMb2NhdGlvbiBsb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgZXJyb3IpOworCisgIC8vIFNpbGx5IGhlbHBlciB3aGljaCBkZXRlcm1pbmVzIGlmIHRoZSBnaXZlbiBmaWxlIGlzIGluIHRoZSBnaXZlbiBwYWNrYWdlLgorICAvLyBJLmUuLCBlaXRoZXIgZmlsZS0+cGFja2FnZSgpID09IHBhY2thZ2VfbmFtZSBvciBmaWxlLT5wYWNrYWdlKCkgaXMgYQorICAvLyBuZXN0ZWQgcGFja2FnZSB3aXRoaW4gcGFja2FnZV9uYW1lLgorICBib29sIElzSW5QYWNrYWdlKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlLCBjb25zdCBzdHJpbmcmIHBhY2thZ2VfbmFtZSk7CisKKyAgLy8gSGVscGVyIGZ1bmN0aW9uIHdoaWNoIGZpbmRzIGFsbCBwdWJsaWMgZGVwZW5kZW5jaWVzIG9mIHRoZSBnaXZlbiBmaWxlLCBhbmQKKyAgLy8gc3RvcmVzIHRoZSB0aGVtIGluIHRoZSBkZXBlbmRlbmNpZXNfIHNldCBpbiB0aGUgYnVpbGRlci4KKyAgdm9pZCBSZWNvcmRQdWJsaWNEZXBlbmRlbmNpZXMoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUpOworCisgIC8vIExpa2UgdGFibGVzXy0+RmluZFN5bWJvbCgpLCBidXQgYWRkaXRpb25hbGx5OgorICAvLyAtIFNlYXJjaCB0aGUgcG9vbCdzIHVuZGVybGF5IGlmIG5vdCBmb3VuZCBpbiB0YWJsZXNfLgorICAvLyAtIEluc3VyZSB0aGF0IHRoZSByZXN1bHRpbmcgU3ltYm9sIGlzIGZyb20gb25lIG9mIHRoZSBmaWxlJ3MgZGVjbGFyZWQKKyAgLy8gICBkZXBlbmRlbmNpZXMuCisgIFN5bWJvbCBGaW5kU3ltYm9sKGNvbnN0IHN0cmluZyYgbmFtZSk7CisKKyAgLy8gTGlrZSBGaW5kU3ltYm9sKCkgYnV0IGRvZXMgbm90IHJlcXVpcmUgdGhhdCB0aGUgc3ltYm9sIGlzIGluIG9uZSBvZiB0aGUKKyAgLy8gZmlsZSdzIGRlY2xhcmVkIGRlcGVuZGVuY2llcy4KKyAgU3ltYm9sIEZpbmRTeW1ib2xOb3RFbmZvcmNpbmdEZXBzKGNvbnN0IHN0cmluZyYgbmFtZSk7CisKKyAgLy8gVGhpcyBpbXBsZW1lbnRzIHRoZSBib2R5IG9mIEZpbmRTeW1ib2xOb3RFbmZvcmNpbmdEZXBzKCkuCisgIFN5bWJvbCBGaW5kU3ltYm9sTm90RW5mb3JjaW5nRGVwc0hlbHBlcihjb25zdCBEZXNjcmlwdG9yUG9vbCogcG9vbCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgbmFtZSk7CisKKyAgLy8gTGlrZSBGaW5kU3ltYm9sKCksIGJ1dCBsb29rcyB1cCB0aGUgbmFtZSByZWxhdGl2ZSB0byBzb21lIG90aGVyIHN5bWJvbAorICAvLyBuYW1lLiAgVGhpcyBmaXJzdCBzZWFyY2hlcyBzaWJsaW5ncyBvZiByZWxhdGl2ZV90bywgdGhlbiBzaWJsaW5ncyBvZiBpdHMKKyAgLy8gcGFyZW50cywgZXRjLiAgRm9yIGV4YW1wbGUsIExvb2t1cFN5bWJvbCgiZm9vLmJhciIsICJiYXoucXV4LmNvcmdlIikgbWFrZXMKKyAgLy8gdGhlIGZvbGxvd2luZyBjYWxscywgcmV0dXJuaW5nIHRoZSBmaXJzdCBub24tbnVsbCByZXN1bHQ6CisgIC8vIEZpbmRTeW1ib2woImJhei5xdXguZm9vLmJhciIpLCBGaW5kU3ltYm9sKCJiYXouZm9vLmJhciIpLAorICAvLyBGaW5kU3ltYm9sKCJmb28uYmFyIikuICBJZiBBbGxvd1Vua25vd25EZXBlbmRlbmNpZXMoKSBoYXMgYmVlbiBjYWxsZWQKKyAgLy8gb24gdGhlIERlc2NyaXB0b3JQb29sLCB0aGlzIHdpbGwgZ2VuZXJhdGUgYSBwbGFjZWhvbGRlciB0eXBlIGlmCisgIC8vIHRoZSBuYW1lIGlzIG5vdCBmb3VuZCAodW5sZXNzIHRoZSBuYW1lIGl0c2VsZiBpcyBtYWxmb3JtZWQpLiAgVGhlCisgIC8vIHBsYWNlaG9sZGVyX3R5cGUgcGFyYW1ldGVyIGluZGljYXRlcyB3aGF0IGtpbmQgb2YgcGxhY2Vob2xkZXIgc2hvdWxkIGJlCisgIC8vIGNvbnN0cnVjdGVkIGluIHRoaXMgY2FzZS4gIFRoZSByZXNvbHZlX21vZGUgcGFyYW1ldGVyIGRldGVybWluZXMgd2hldGhlcgorICAvLyBhbnkgc3ltYm9sIGlzIHJldHVybmVkLCBvciBvbmx5IHN5bWJvbHMgdGhhdCBhcmUgdHlwZXMuICBOb3RlLCBob3dldmVyLAorICAvLyB0aGF0IExvb2t1cFN5bWJvbCBtYXkgc3RpbGwgcmV0dXJuIGEgbm9uLXR5cGUgc3ltYm9sIGluIExPT0tVUF9UWVBFUyBtb2RlLAorICAvLyBpZiBpdCBiZWxpZXZlcyB0aGF0J3MgYWxsIGl0IGNvdWxkIHJlZmVyIHRvLiAgVGhlIGNhbGxlciBzaG91bGQgYWx3YXlzCisgIC8vIGNoZWNrIHRoYXQgaXQgcmVjZWl2ZXMgdGhlIHR5cGUgb2Ygc3ltYm9sIGl0IHdhcyBleHBlY3RpbmcuCisgIGVudW0gUGxhY2Vob2xkZXJUeXBlIHsKKyAgICBQTEFDRUhPTERFUl9NRVNTQUdFLAorICAgIFBMQUNFSE9MREVSX0VOVU0sCisgICAgUExBQ0VIT0xERVJfRVhURU5EQUJMRV9NRVNTQUdFCisgIH07CisgIGVudW0gUmVzb2x2ZU1vZGUgeworICAgIExPT0tVUF9BTEwsIExPT0tVUF9UWVBFUworICB9OworICBTeW1ib2wgTG9va3VwU3ltYm9sKGNvbnN0IHN0cmluZyYgbmFtZSwgY29uc3Qgc3RyaW5nJiByZWxhdGl2ZV90bywKKyAgICAgICAgICAgICAgICAgICAgICBQbGFjZWhvbGRlclR5cGUgcGxhY2Vob2xkZXJfdHlwZSA9IFBMQUNFSE9MREVSX01FU1NBR0UsCisgICAgICAgICAgICAgICAgICAgICAgUmVzb2x2ZU1vZGUgcmVzb2x2ZV9tb2RlID0gTE9PS1VQX0FMTCk7CisKKyAgLy8gTGlrZSBMb29rdXBTeW1ib2woKSBidXQgd2lsbCBub3QgcmV0dXJuIGEgcGxhY2Vob2xkZXIgZXZlbiBpZgorICAvLyBBbGxvd1Vua25vd25EZXBlbmRlbmNpZXMoKSBoYXMgYmVlbiB1c2VkLgorICBTeW1ib2wgTG9va3VwU3ltYm9sTm9QbGFjZWhvbGRlcihjb25zdCBzdHJpbmcmIG5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgcmVsYXRpdmVfdG8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlc29sdmVNb2RlIHJlc29sdmVfbW9kZSA9IExPT0tVUF9BTEwpOworCisgIC8vIENyZWF0ZXMgYSBwbGFjZWhvbGRlciB0eXBlIHN1aXRhYmxlIGZvciByZXR1cm4gZnJvbSBMb29rdXBTeW1ib2woKS4gIE1heQorICAvLyByZXR1cm4ga051bGxTeW1ib2wgaWYgdGhlIG5hbWUgaXMgbm90IGEgdmFsaWQgdHlwZSBuYW1lLgorICBTeW1ib2wgTmV3UGxhY2Vob2xkZXIoY29uc3Qgc3RyaW5nJiBuYW1lLCBQbGFjZWhvbGRlclR5cGUgcGxhY2Vob2xkZXJfdHlwZSk7CisKKyAgLy8gQ3JlYXRlcyBhIHBsYWNlaG9sZGVyIGZpbGUuICBOZXZlciByZXR1cm5zIE5VTEwuICBUaGlzIGlzIHVzZWQgd2hlbiBhbgorICAvLyBpbXBvcnQgaXMgbm90IGZvdW5kIGFuZCBBbGxvd1Vua25vd25EZXBlbmRlbmNpZXMoKSBpcyBlbmFibGVkLgorICBGaWxlRGVzY3JpcHRvciogTmV3UGxhY2Vob2xkZXJGaWxlKGNvbnN0IHN0cmluZyYgbmFtZSk7CisKKyAgLy8gQ2FsbHMgdGFibGVzXy0+QWRkU3ltYm9sKCkgYW5kIHJlY29yZHMgYW4gZXJyb3IgaWYgaXQgZmFpbHMuICBSZXR1cm5zCisgIC8vIHRydWUgaWYgc3VjY2Vzc2Z1bCBvciBmYWxzZSBpZiBmYWlsZWQsIHRob3VnaCBtb3N0IGNhbGxlcnMgY2FuIGlnbm9yZQorICAvLyB0aGUgcmV0dXJuIHZhbHVlIHNpbmNlIGFuIGVycm9yIGhhcyBhbHJlYWR5IGJlZW4gcmVjb3JkZWQuCisgIGJvb2wgQWRkU3ltYm9sKGNvbnN0IHN0cmluZyYgZnVsbF9uYW1lLAorICAgICAgICAgICAgICAgICBjb25zdCB2b2lkKiBwYXJlbnQsIGNvbnN0IHN0cmluZyYgbmFtZSwKKyAgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZSYgcHJvdG8sIFN5bWJvbCBzeW1ib2wpOworCisgIC8vIExpa2UgQWRkU3ltYm9sKCksIGJ1dCBzdWNjZWVkcyBpZiB0aGUgc3ltYm9sIGlzIGFscmVhZHkgZGVmaW5lZCBhcyBsb25nCisgIC8vIGFzIHRoZSBleGlzdGluZyBkZWZpbml0aW9uIGlzIGFsc28gYSBwYWNrYWdlIChiZWNhdXNlIGl0J3MgT0sgdG8gZGVmaW5lCisgIC8vIHRoZSBzYW1lIHBhY2thZ2UgaW4gdHdvIGRpZmZlcmVudCBmaWxlcykuICBBbHNvIGFkZHMgYWxsIHBhcmVudHMgb2YgdGhlCisgIC8vIHBhY2tnYWUgdG8gdGhlIHN5bWJvbCB0YWJsZSAoZS5nLiBBZGRQYWNrYWdlKCJmb28uYmFyIiwgLi4uKSB3aWxsIGFkZAorICAvLyAiZm9vLmJhciIgYW5kICJmb28iIHRvIHRoZSB0YWJsZSkuCisgIHZvaWQgQWRkUGFja2FnZShjb25zdCBzdHJpbmcmIG5hbWUsIGNvbnN0IE1lc3NhZ2UmIHByb3RvLAorICAgICAgICAgICAgICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUpOworCisgIC8vIENoZWNrcyB0aGF0IHRoZSBzeW1ib2wgbmFtZSBjb250YWlucyBvbmx5IGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzIGFuZAorICAvLyB1bmRlcnNjb3Jlcy4gIFJlY29yZHMgYW4gZXJyb3Igb3RoZXJ3aXNlLgorICB2b2lkIFZhbGlkYXRlU3ltYm9sTmFtZShjb25zdCBzdHJpbmcmIG5hbWUsIGNvbnN0IHN0cmluZyYgZnVsbF9uYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNZXNzYWdlJiBwcm90byk7CisKKyAgLy8gTGlrZSBWYWxpZGF0ZVN5bWJvbE5hbWUoKSwgYnV0IHRoZSBuYW1lIGlzIGFsbG93ZWQgdG8gY29udGFpbiBwZXJpb2RzIGFuZAorICAvLyBhbiBlcnJvciBpcyBpbmRpY2F0ZWQgYnkgcmV0dXJuaW5nIGZhbHNlIChub3QgcmVjb3JkaW5nIHRoZSBlcnJvcikuCisgIGJvb2wgVmFsaWRhdGVRdWFsaWZpZWROYW1lKGNvbnN0IHN0cmluZyYgbmFtZSk7CisKKyAgLy8gVXNlZCBieSBCVUlMRF9BUlJBWSBtYWNybyAoYmVsb3cpIHRvIGF2b2lkIGhhdmluZyB0byBoYXZlIHRoZSB0eXBlCisgIC8vIHNwZWNpZmllZCBhcyBhIG1hY3JvIHBhcmFtZXRlci4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+CisgIGlubGluZSB2b2lkIEFsbG9jYXRlQXJyYXkoaW50IHNpemUsIFR5cGUqKiBvdXRwdXQpIHsKKyAgICAqb3V0cHV0ID0gdGFibGVzXy0+QWxsb2NhdGVBcnJheTxUeXBlPihzaXplKTsKKyAgfQorCisgIC8vIEFsbG9jYXRlcyBhIGNvcHkgb2Ygb3JpZ19vcHRpb25zIGluIHRhYmxlc18gYW5kIHN0b3JlcyBpdCBpbiB0aGUKKyAgLy8gZGVzY3JpcHRvci4gUmVtZW1iZXJzIGl0cyB1bmludGVycHJldGVkIG9wdGlvbnMsIHRvIGJlIGludGVycHJldGVkCisgIC8vIGxhdGVyLiBEZXNjcmlwdG9yVCBtdXN0IGJlIG9uZSBvZiB0aGUgRGVzY3JpcHRvciBtZXNzYWdlcyBmcm9tCisgIC8vIGRlc2NyaXB0b3IucHJvdG8uCisgIHRlbXBsYXRlPGNsYXNzIERlc2NyaXB0b3JUPiB2b2lkIEFsbG9jYXRlT3B0aW9ucygKKyAgICAgIGNvbnN0IHR5cGVuYW1lIERlc2NyaXB0b3JUOjpPcHRpb25zVHlwZSYgb3JpZ19vcHRpb25zLAorICAgICAgRGVzY3JpcHRvclQqIGRlc2NyaXB0b3IpOworICAvLyBTcGVjaWFsaXphdGlvbiBmb3IgRmlsZU9wdGlvbnMuCisgIHZvaWQgQWxsb2NhdGVPcHRpb25zKGNvbnN0IEZpbGVPcHRpb25zJiBvcmlnX29wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgIEZpbGVEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKKworICAvLyBJbXBsZW1lbnRhdGlvbiBmb3IgQWxsb2NhdGVPcHRpb25zKCkuIERvbid0IGNhbGwgdGhpcyBkaXJlY3RseS4KKyAgdGVtcGxhdGU8Y2xhc3MgRGVzY3JpcHRvclQ+IHZvaWQgQWxsb2NhdGVPcHRpb25zSW1wbCgKKyAgICAgIGNvbnN0IHN0cmluZyYgbmFtZV9zY29wZSwKKyAgICAgIGNvbnN0IHN0cmluZyYgZWxlbWVudF9uYW1lLAorICAgICAgY29uc3QgdHlwZW5hbWUgRGVzY3JpcHRvclQ6Ok9wdGlvbnNUeXBlJiBvcmlnX29wdGlvbnMsCisgICAgICBEZXNjcmlwdG9yVCogZGVzY3JpcHRvcik7CisKKyAgLy8gVGhlc2UgbWV0aG9kcyBhbGwgaGF2ZSB0aGUgc2FtZSBzaWduYXR1cmUgZm9yIHRoZSBzYWtlIG9mIHRoZSBCVUlMRF9BUlJBWQorICAvLyBtYWNybywgYmVsb3cuCisgIHZvaWQgQnVpbGRNZXNzYWdlKGNvbnN0IERlc2NyaXB0b3JQcm90byYgcHJvdG8sCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlc2NyaXB0b3IqIHBhcmVudCwKKyAgICAgICAgICAgICAgICAgICAgRGVzY3JpcHRvciogcmVzdWx0KTsKKyAgdm9pZCBCdWlsZEZpZWxkT3JFeHRlbnNpb24oY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG8mIHByb3RvLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEZXNjcmlwdG9yKiBwYXJlbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvciogcmVzdWx0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGlzX2V4dGVuc2lvbik7CisgIHZvaWQgQnVpbGRGaWVsZChjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90byYgcHJvdG8sCisgICAgICAgICAgICAgICAgICBjb25zdCBEZXNjcmlwdG9yKiBwYXJlbnQsCisgICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3IqIHJlc3VsdCkgeworICAgIEJ1aWxkRmllbGRPckV4dGVuc2lvbihwcm90bywgcGFyZW50LCByZXN1bHQsIGZhbHNlKTsKKyAgfQorICB2b2lkIEJ1aWxkRXh0ZW5zaW9uKGNvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvJiBwcm90bywKKyAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEZXNjcmlwdG9yKiBwYXJlbnQsCisgICAgICAgICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yKiByZXN1bHQpIHsKKyAgICBCdWlsZEZpZWxkT3JFeHRlbnNpb24ocHJvdG8sIHBhcmVudCwgcmVzdWx0LCB0cnVlKTsKKyAgfQorICB2b2lkIEJ1aWxkRXh0ZW5zaW9uUmFuZ2UoY29uc3QgRGVzY3JpcHRvclByb3RvOjpFeHRlbnNpb25SYW5nZSYgcHJvdG8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEZXNjcmlwdG9yKiBwYXJlbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBEZXNjcmlwdG9yOjpFeHRlbnNpb25SYW5nZSogcmVzdWx0KTsKKyAgdm9pZCBCdWlsZFJlc2VydmVkUmFuZ2UoY29uc3QgRGVzY3JpcHRvclByb3RvOjpSZXNlcnZlZFJhbmdlJiBwcm90bywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlc2NyaXB0b3IqIHBhcmVudCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIERlc2NyaXB0b3I6OlJlc2VydmVkUmFuZ2UqIHJlc3VsdCk7CisgIHZvaWQgQnVpbGRPbmVvZihjb25zdCBPbmVvZkRlc2NyaXB0b3JQcm90byYgcHJvdG8sCisgICAgICAgICAgICAgICAgICBEZXNjcmlwdG9yKiBwYXJlbnQsCisgICAgICAgICAgICAgICAgICBPbmVvZkRlc2NyaXB0b3IqIHJlc3VsdCk7CisgIHZvaWQgQnVpbGRFbnVtKGNvbnN0IEVudW1EZXNjcmlwdG9yUHJvdG8mIHByb3RvLAorICAgICAgICAgICAgICAgICBjb25zdCBEZXNjcmlwdG9yKiBwYXJlbnQsCisgICAgICAgICAgICAgICAgIEVudW1EZXNjcmlwdG9yKiByZXN1bHQpOworICB2b2lkIEJ1aWxkRW51bVZhbHVlKGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3JQcm90byYgcHJvdG8sCisgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRW51bURlc2NyaXB0b3IqIHBhcmVudCwKKyAgICAgICAgICAgICAgICAgICAgICBFbnVtVmFsdWVEZXNjcmlwdG9yKiByZXN1bHQpOworICB2b2lkIEJ1aWxkU2VydmljZShjb25zdCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvJiBwcm90bywKKyAgICAgICAgICAgICAgICAgICAgY29uc3Qgdm9pZCogZHVtbXksCisgICAgICAgICAgICAgICAgICAgIFNlcnZpY2VEZXNjcmlwdG9yKiByZXN1bHQpOworICB2b2lkIEJ1aWxkTWV0aG9kKGNvbnN0IE1ldGhvZERlc2NyaXB0b3JQcm90byYgcHJvdG8sCisgICAgICAgICAgICAgICAgICAgY29uc3QgU2VydmljZURlc2NyaXB0b3IqIHBhcmVudCwKKyAgICAgICAgICAgICAgICAgICBNZXRob2REZXNjcmlwdG9yKiByZXN1bHQpOworCisgIHZvaWQgTG9nVW51c2VkRGVwZW5kZW5jeShjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvJiBwcm90bywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiByZXN1bHQpOworCisgIC8vIE11c3QgYmUgcnVuIG9ubHkgYWZ0ZXIgYnVpbGRpbmcuCisgIC8vCisgIC8vIE5PVEU6IE9wdGlvbnMgd2lsbCBub3QgYmUgYXZhaWxhYmxlIGR1cmluZyBjcm9zcy1saW5raW5nLCBhcyB0aGV5CisgIC8vIGhhdmUgbm90IHlldCBiZWVuIGludGVycHJldGVkLiBEZWZlciBhbnkgaGFuZGxpbmcgb2Ygb3B0aW9ucyB0byB0aGUKKyAgLy8gVmFsaWRhdGUqT3B0aW9ucyBtZXRob2RzLgorICB2b2lkIENyb3NzTGlua0ZpbGUoRmlsZURlc2NyaXB0b3IqIGZpbGUsIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8mIHByb3RvKTsKKyAgdm9pZCBDcm9zc0xpbmtNZXNzYWdlKERlc2NyaXB0b3IqIG1lc3NhZ2UsIGNvbnN0IERlc2NyaXB0b3JQcm90byYgcHJvdG8pOworICB2b2lkIENyb3NzTGlua0ZpZWxkKEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG8mIHByb3RvKTsKKyAgdm9pZCBDcm9zc0xpbmtFbnVtKEVudW1EZXNjcmlwdG9yKiBlbnVtX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICBjb25zdCBFbnVtRGVzY3JpcHRvclByb3RvJiBwcm90byk7CisgIHZvaWQgQ3Jvc3NMaW5rRW51bVZhbHVlKEVudW1WYWx1ZURlc2NyaXB0b3IqIGVudW1fdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3JQcm90byYgcHJvdG8pOworICB2b2lkIENyb3NzTGlua1NlcnZpY2UoU2VydmljZURlc2NyaXB0b3IqIHNlcnZpY2UsCisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvJiBwcm90byk7CisgIHZvaWQgQ3Jvc3NMaW5rTWV0aG9kKE1ldGhvZERlc2NyaXB0b3IqIG1ldGhvZCwKKyAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWV0aG9kRGVzY3JpcHRvclByb3RvJiBwcm90byk7CisKKyAgLy8gTXVzdCBiZSBydW4gb25seSBhZnRlciBjcm9zcy1saW5raW5nLgorICB2b2lkIEludGVycHJldE9wdGlvbnMoKTsKKworICAvLyBBIGhlbHBlciBjbGFzcyBmb3IgaW50ZXJwcmV0aW5nIG9wdGlvbnMuCisgIGNsYXNzIE9wdGlvbkludGVycHJldGVyIHsKKyAgIHB1YmxpYzoKKyAgICAvLyBDcmVhdGVzIGFuIGludGVycHJldGVyIHRoYXQgb3BlcmF0ZXMgaW4gdGhlIGNvbnRleHQgb2YgdGhlIHBvb2wgb2YgdGhlCisgICAgLy8gc3BlY2lmaWVkIGJ1aWxkZXIsIHdoaWNoIG11c3Qgbm90IGJlIE5VTEwuIFdlIGRvbid0IHRha2Ugb3duZXJzaGlwIG9mIHRoZQorICAgIC8vIGJ1aWxkZXIuCisgICAgZXhwbGljaXQgT3B0aW9uSW50ZXJwcmV0ZXIoRGVzY3JpcHRvckJ1aWxkZXIqIGJ1aWxkZXIpOworCisgICAgfk9wdGlvbkludGVycHJldGVyKCk7CisKKyAgICAvLyBJbnRlcnByZXRzIHRoZSB1bmludGVycHJldGVkIG9wdGlvbnMgaW4gdGhlIHNwZWNpZmllZCBPcHRpb25zIG1lc3NhZ2UuCisgICAgLy8gT24gZXJyb3IsIGNhbGxzIEFkZEVycm9yKCkgb24gdGhlIHVuZGVybHlpbmcgYnVpbGRlciBhbmQgcmV0dXJucyBmYWxzZS4KKyAgICAvLyBPdGhlcndpc2UgcmV0dXJucyB0cnVlLgorICAgIGJvb2wgSW50ZXJwcmV0T3B0aW9ucyhPcHRpb25zVG9JbnRlcnByZXQqIG9wdGlvbnNfdG9faW50ZXJwcmV0KTsKKworICAgIGNsYXNzIEFnZ3JlZ2F0ZU9wdGlvbkZpbmRlcjsKKworICAgcHJpdmF0ZToKKyAgICAvLyBJbnRlcnByZXRzIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXyBvbiB0aGUgc3BlY2lmaWVkIG1lc3NhZ2UsIHdoaWNoCisgICAgLy8gbXVzdCBiZSB0aGUgbXV0YWJsZSBjb3B5IG9mIHRoZSBvcmlnaW5hbCBvcHRpb25zIG1lc3NhZ2UgdG8gd2hpY2gKKyAgICAvLyB1bmludGVycHJldGVkX29wdGlvbl8gYmVsb25ncy4KKyAgICBib29sIEludGVycHJldFNpbmdsZU9wdGlvbihNZXNzYWdlKiBvcHRpb25zKTsKKworICAgIC8vIEFkZHMgdGhlIHVuaW50ZXJwcmV0ZWRfb3B0aW9uIHRvIHRoZSBnaXZlbiBvcHRpb25zIG1lc3NhZ2UgdmVyYmF0aW0uCisgICAgLy8gVXNlZCB3aGVuIEFsbG93VW5rbm93bkRlcGVuZGVuY2llcygpIGlzIGluIGVmZmVjdCBhbmQgd2UgY2FuJ3QgZmluZAorICAgIC8vIHRoZSBvcHRpb24ncyBkZWZpbml0aW9uLgorICAgIHZvaWQgQWRkV2l0aG91dEludGVycHJldGluZyhjb25zdCBVbmludGVycHJldGVkT3B0aW9uJiB1bmludGVycHJldGVkX29wdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZSogb3B0aW9ucyk7CisKKyAgICAvLyBBIHJlY3Vyc2l2ZSBoZWxwZXIgZnVuY3Rpb24gdGhhdCBkcmlsbHMgaW50byB0aGUgaW50ZXJtZWRpYXRlIGZpZWxkcworICAgIC8vIGluIHVua25vd25fZmllbGRzIHRvIGNoZWNrIGlmIGZpZWxkIGlubmVybW9zdF9maWVsZCBpcyBzZXQgb24gdGhlCisgICAgLy8gaW5uZXJtb3N0IG1lc3NhZ2UuIFJldHVybnMgZmFsc2UgYW5kIHNldHMgYW4gZXJyb3IgaWYgc28uCisgICAgYm9vbCBFeGFtaW5lSWZPcHRpb25Jc1NldCgKKyAgICAgICAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+Ojpjb25zdF9pdGVyYXRvciBpbnRlcm1lZGlhdGVfZmllbGRzX2l0ZXIsCisgICAgICAgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPjo6Y29uc3RfaXRlcmF0b3IgaW50ZXJtZWRpYXRlX2ZpZWxkc19lbmQsCisgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogaW5uZXJtb3N0X2ZpZWxkLCBjb25zdCBzdHJpbmcmIGRlYnVnX21zZ19uYW1lLAorICAgICAgICBjb25zdCBVbmtub3duRmllbGRTZXQmIHVua25vd25fZmllbGRzKTsKKworICAgIC8vIFZhbGlkYXRlcyB0aGUgdmFsdWUgZm9yIHRoZSBvcHRpb24gZmllbGQgb2YgdGhlIGN1cnJlbnRseSBpbnRlcnByZXRlZAorICAgIC8vIG9wdGlvbiBhbmQgdGhlbiBzZXRzIGl0IG9uIHRoZSB1bmtub3duX2ZpZWxkLgorICAgIGJvb2wgU2V0T3B0aW9uVmFsdWUoY29uc3QgRmllbGREZXNjcmlwdG9yKiBvcHRpb25fZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICBVbmtub3duRmllbGRTZXQqIHVua25vd25fZmllbGRzKTsKKworICAgIC8vIFBhcnNlcyBhbiBhZ2dyZWdhdGUgdmFsdWUgZm9yIGEgQ1BQVFlQRV9NRVNTQUdFIG9wdGlvbiBhbmQKKyAgICAvLyBzYXZlcyBpdCBpbnRvICp1bmtub3duX2ZpZWxkcy4KKyAgICBib29sIFNldEFnZ3JlZ2F0ZU9wdGlvbihjb25zdCBGaWVsZERlc2NyaXB0b3IqIG9wdGlvbl9maWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBVbmtub3duRmllbGRTZXQqIHVua25vd25fZmllbGRzKTsKKworICAgIC8vIENvbnZlbmllbmNlIGZ1bmN0aW9ucyB0byBzZXQgYW4gaW50IGZpZWxkIHRoZSByaWdodCB3YXksIGRlcGVuZGluZyBvbgorICAgIC8vIGl0cyB3aXJlIHR5cGUgKGEgc2luZ2xlIGludCBDcHBUeXBlIGNhbiByZXByZXNlbnQgbXVsdGlwbGUgd2lyZSB0eXBlcykuCisgICAgdm9pZCBTZXRJbnQzMihpbnQgbnVtYmVyLCBpbnQzMiB2YWx1ZSwgRmllbGREZXNjcmlwdG9yOjpUeXBlIHR5cGUsCisgICAgICAgICAgICAgICAgICBVbmtub3duRmllbGRTZXQqIHVua25vd25fZmllbGRzKTsKKyAgICB2b2lkIFNldEludDY0KGludCBudW1iZXIsIGludDY0IHZhbHVlLCBGaWVsZERlc2NyaXB0b3I6OlR5cGUgdHlwZSwKKyAgICAgICAgICAgICAgICAgIFVua25vd25GaWVsZFNldCogdW5rbm93bl9maWVsZHMpOworICAgIHZvaWQgU2V0VUludDMyKGludCBudW1iZXIsIHVpbnQzMiB2YWx1ZSwgRmllbGREZXNjcmlwdG9yOjpUeXBlIHR5cGUsCisgICAgICAgICAgICAgICAgICAgVW5rbm93bkZpZWxkU2V0KiB1bmtub3duX2ZpZWxkcyk7CisgICAgdm9pZCBTZXRVSW50NjQoaW50IG51bWJlciwgdWludDY0IHZhbHVlLCBGaWVsZERlc2NyaXB0b3I6OlR5cGUgdHlwZSwKKyAgICAgICAgICAgICAgICAgICBVbmtub3duRmllbGRTZXQqIHVua25vd25fZmllbGRzKTsKKworICAgIC8vIEEgaGVscGVyIGZ1bmN0aW9uIHRoYXQgYWRkcyBhbiBlcnJvciBhdCB0aGUgc3BlY2lmaWVkIGxvY2F0aW9uIG9mIHRoZQorICAgIC8vIG9wdGlvbiB3ZSdyZSBjdXJyZW50bHkgaW50ZXJwcmV0aW5nLCBhbmQgcmV0dXJucyBmYWxzZS4KKyAgICBib29sIEFkZE9wdGlvbkVycm9yKERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6RXJyb3JMb2NhdGlvbiBsb2NhdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgbXNnKSB7CisgICAgICBidWlsZGVyXy0+QWRkRXJyb3Iob3B0aW9uc190b19pbnRlcnByZXRfLT5lbGVtZW50X25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgKnVuaW50ZXJwcmV0ZWRfb3B0aW9uXywgbG9jYXRpb24sIG1zZyk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLy8gQSBoZWxwZXIgZnVuY3Rpb24gdGhhdCBhZGRzIGFuIGVycm9yIGF0IHRoZSBsb2NhdGlvbiBvZiB0aGUgb3B0aW9uIG5hbWUKKyAgICAvLyBhbmQgcmV0dXJucyBmYWxzZS4KKyAgICBib29sIEFkZE5hbWVFcnJvcihjb25zdCBzdHJpbmcmIG1zZykgeworICAgICAgcmV0dXJuIEFkZE9wdGlvbkVycm9yKERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6T1BUSU9OX05BTUUsIG1zZyk7CisgICAgfQorCisgICAgLy8gQSBoZWxwZXIgZnVuY3Rpb24gdGhhdCBhZGRzIGFuIGVycm9yIGF0IHRoZSBsb2NhdGlvbiBvZiB0aGUgb3B0aW9uIG5hbWUKKyAgICAvLyBhbmQgcmV0dXJucyBmYWxzZS4KKyAgICBib29sIEFkZFZhbHVlRXJyb3IoY29uc3Qgc3RyaW5nJiBtc2cpIHsKKyAgICAgIHJldHVybiBBZGRPcHRpb25FcnJvcihEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok9QVElPTl9WQUxVRSwgbXNnKTsKKyAgICB9CisKKyAgICAvLyBXZSBpbnRlcnByZXQgYWdhaW5zdCB0aGlzIGJ1aWxkZXIncyBwb29sLiBJcyBuZXZlciBOVUxMLiBXZSBkb24ndCBvd24KKyAgICAvLyB0aGlzIHBvaW50ZXIuCisgICAgRGVzY3JpcHRvckJ1aWxkZXIqIGJ1aWxkZXJfOworCisgICAgLy8gVGhlIG9wdGlvbnMgd2UncmUgY3VycmVudGx5IGludGVycHJldGluZywgb3IgTlVMTCBpZiB3ZSdyZSBub3QgaW4gYSBjYWxsCisgICAgLy8gdG8gSW50ZXJwcmV0T3B0aW9ucy4KKyAgICBjb25zdCBPcHRpb25zVG9JbnRlcnByZXQqIG9wdGlvbnNfdG9faW50ZXJwcmV0XzsKKworICAgIC8vIFRoZSBvcHRpb24gd2UncmUgY3VycmVudGx5IGludGVycHJldGluZyB3aXRoaW4gb3B0aW9uc190b19pbnRlcnByZXRfLCBvcgorICAgIC8vIE5VTEwgaWYgd2UncmUgbm90IGluIGEgY2FsbCB0byBJbnRlcnByZXRPcHRpb25zKCkuIFRoaXMgcG9pbnRzIHRvIGEKKyAgICAvLyBzdWJtZXNzYWdlIG9mIHRoZSBvcmlnaW5hbCBvcHRpb24sIG5vdCB0aGUgbXV0YWJsZSBjb3B5LiBUaGVyZWZvcmUgd2UKKyAgICAvLyBjYW4gdXNlIGl0IHRvIGZpbmQgbG9jYXRpb25zIHJlY29yZGVkIGJ5IHRoZSBwYXJzZXIuCisgICAgY29uc3QgVW5pbnRlcnByZXRlZE9wdGlvbiogdW5pbnRlcnByZXRlZF9vcHRpb25fOworCisgICAgLy8gRmFjdG9yeSB1c2VkIHRvIGNyZWF0ZSB0aGUgZHluYW1pYyBtZXNzYWdlcyB3ZSBuZWVkIHRvIHBhcnNlCisgICAgLy8gYW55IGFnZ3JlZ2F0ZSBvcHRpb24gdmFsdWVzIHdlIGVuY291bnRlci4KKyAgICBEeW5hbWljTWVzc2FnZUZhY3RvcnkgZHluYW1pY19mYWN0b3J5XzsKKworICAgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhPcHRpb25JbnRlcnByZXRlcik7CisgIH07CisKKyAgLy8gV29yay1hcm91bmQgZm9yIGJyb2tlbiBjb21waWxlcnM6ICBBY2NvcmRpbmcgdG8gdGhlIEMrKyBzdGFuZGFyZCwKKyAgLy8gT3B0aW9uSW50ZXJwcmV0ZXIgc2hvdWxkIGhhdmUgYWNjZXNzIHRvIHRoZSBwcml2YXRlIG1lbWJlcnMgb2YgYW55IGNsYXNzCisgIC8vIHdoaWNoIGhhcyBkZWNsYXJlZCBEZXNjcmlwdG9yQnVpbGRlciBhcyBhIGZyaWVuZC4gIFVuZm9ydHVuYXRlbHkgc29tZSBvbGQKKyAgLy8gdmVyc2lvbnMgb2YgR0NDIGFuZCBvdGhlciBjb21waWxlcnMgZG8gbm90IGltcGxlbWVudCB0aGlzIGNvcnJlY3RseS4gIFNvLAorICAvLyB3ZSBoYXZlIHRvIGhhdmUgdGhlc2UgaW50ZXJtZWRpYXRlIG1ldGhvZHMgdG8gcHJvdmlkZSBhY2Nlc3MuICBXZSBhbHNvCisgIC8vIHJlZHVuZGFudGx5IGRlY2xhcmUgT3B0aW9uSW50ZXJwcmV0ZXIgYSBmcmllbmQganVzdCB0byBtYWtlIHRoaW5ncyBleHRyYQorICAvLyBjbGVhciBmb3IgdGhlc2UgYmFkIGNvbXBpbGVycy4KKyAgZnJpZW5kIGNsYXNzIE9wdGlvbkludGVycHJldGVyOworICBmcmllbmQgY2xhc3MgT3B0aW9uSW50ZXJwcmV0ZXI6OkFnZ3JlZ2F0ZU9wdGlvbkZpbmRlcjsKKworICBzdGF0aWMgaW5saW5lIGJvb2wgZ2V0X2FsbG93X3Vua25vd24oY29uc3QgRGVzY3JpcHRvclBvb2wqIHBvb2wpIHsKKyAgICByZXR1cm4gcG9vbC0+YWxsb3dfdW5rbm93bl87CisgIH0KKyAgc3RhdGljIGlubGluZSBib29sIGdldF9lbmZvcmNlX3dlYWsoY29uc3QgRGVzY3JpcHRvclBvb2wqIHBvb2wpIHsKKyAgICByZXR1cm4gcG9vbC0+ZW5mb3JjZV93ZWFrXzsKKyAgfQorICBzdGF0aWMgaW5saW5lIGJvb2wgZ2V0X2lzX3BsYWNlaG9sZGVyKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgICByZXR1cm4gZGVzY3JpcHRvci0+aXNfcGxhY2Vob2xkZXJfOworICB9CisgIHN0YXRpYyBpbmxpbmUgdm9pZCBhc3NlcnRfbXV0ZXhfaGVsZChjb25zdCBEZXNjcmlwdG9yUG9vbCogcG9vbCkgeworICAgIGlmIChwb29sLT5tdXRleF8gIT0gTlVMTCkgeworICAgICAgcG9vbC0+bXV0ZXhfLT5Bc3NlcnRIZWxkKCk7CisgICAgfQorICB9CisKKyAgLy8gTXVzdCBiZSBydW4gb25seSBhZnRlciBvcHRpb25zIGhhdmUgYmVlbiBpbnRlcnByZXRlZC4KKyAgLy8KKyAgLy8gTk9URTogVmFsaWRhdGlvbiBjb2RlIG11c3Qgb25seSByZWZlcmVuY2UgdGhlIG9wdGlvbnMgaW4gdGhlIG11dGFibGUKKyAgLy8gZGVzY3JpcHRvcnMsIHdoaWNoIGFyZSB0aGUgb25lcyB0aGF0IGhhdmUgYmVlbiBpbnRlcnByZXRlZC4gVGhlIGNvbnN0CisgIC8vIHByb3RvIHJlZmVyZW5jZXMgYXJlIHBhc3NlZCBpbiBvbmx5IHNvIHRoZXkgY2FuIGJlIHByb3ZpZGVkIHRvIGNhbGxzIHRvCisgIC8vIEFkZEVycm9yKCkuIERvIG5vdCBsb29rIGF0IHRoZWlyIG9wdGlvbnMsIHdoaWNoIGhhdmUgbm90IGJlZW4gaW50ZXJwcmV0ZWQuCisgIHZvaWQgVmFsaWRhdGVGaWxlT3B0aW9ucyhGaWxlRGVzY3JpcHRvciogZmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8mIHByb3RvKTsKKyAgdm9pZCBWYWxpZGF0ZU1lc3NhZ2VPcHRpb25zKERlc2NyaXB0b3IqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEZXNjcmlwdG9yUHJvdG8mIHByb3RvKTsKKyAgdm9pZCBWYWxpZGF0ZUZpZWxkT3B0aW9ucyhGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvJiBwcm90byk7CisgIHZvaWQgVmFsaWRhdGVFbnVtT3B0aW9ucyhFbnVtRGVzY3JpcHRvciogZW5tLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRW51bURlc2NyaXB0b3JQcm90byYgcHJvdG8pOworICB2b2lkIFZhbGlkYXRlRW51bVZhbHVlT3B0aW9ucyhFbnVtVmFsdWVEZXNjcmlwdG9yKiBlbnVtX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8mIHByb3RvKTsKKyAgdm9pZCBWYWxpZGF0ZVNlcnZpY2VPcHRpb25zKFNlcnZpY2VEZXNjcmlwdG9yKiBzZXJ2aWNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgU2VydmljZURlc2NyaXB0b3JQcm90byYgcHJvdG8pOworICB2b2lkIFZhbGlkYXRlTWV0aG9kT3B0aW9ucyhNZXRob2REZXNjcmlwdG9yKiBtZXRob2QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1ldGhvZERlc2NyaXB0b3JQcm90byYgcHJvdG8pOworICB2b2lkIFZhbGlkYXRlUHJvdG8zKEZpbGVEZXNjcmlwdG9yKiBmaWxlLAorICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8mIHByb3RvKTsKKyAgdm9pZCBWYWxpZGF0ZVByb3RvM01lc3NhZ2UoRGVzY3JpcHRvciogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVzY3JpcHRvclByb3RvJiBwcm90byk7CisgIHZvaWQgVmFsaWRhdGVQcm90bzNGaWVsZChGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG8mIHByb3RvKTsKKyAgdm9pZCBWYWxpZGF0ZVByb3RvM0VudW0oRW51bURlc2NyaXB0b3IqIGVubSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRW51bURlc2NyaXB0b3JQcm90byYgcHJvdG8pOworCisgIC8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgbWFwIGVudHJ5IG1lc3NhZ2UgaXMgY29tcGF0aWJsZSB3aXRoIHRoZQorICAvLyBhdXRvLWdlbmVyYXRlZCBlbnRyeSBtZXNzYWdlIGZyb20gbWFwIGZpZWxkcyBzeW50YXguCisgIGJvb2wgVmFsaWRhdGVNYXBFbnRyeShGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG8mIHByb3RvKTsKKworICAvLyBSZWN1cnNpdmVseSBkZXRlY3RzIG5hbWluZyBjb25mbGljdHMgd2l0aCBtYXAgZW50cnkgdHlwZXMgZm9yIGEKKyAgLy8gYmV0dGVyIGVycm9yIG1lc3NhZ2UuCisgIHZvaWQgRGV0ZWN0TWFwQ29uZmxpY3RzKGNvbnN0IERlc2NyaXB0b3IqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlc2NyaXB0b3JQcm90byYgcHJvdG8pOworCit9OworCitjb25zdCBGaWxlRGVzY3JpcHRvciogRGVzY3JpcHRvclBvb2w6OkJ1aWxkRmlsZSgKKyAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvJiBwcm90bykgeworICBHT09HTEVfQ0hFQ0soZmFsbGJhY2tfZGF0YWJhc2VfID09IE5VTEwpCisgICAgPDwgIkNhbm5vdCBjYWxsIEJ1aWxkRmlsZSBvbiBhIERlc2NyaXB0b3JQb29sIHRoYXQgdXNlcyBhICIKKyAgICAgICAiRGVzY3JpcHRvckRhdGFiYXNlLiAgWW91IG11c3QgaW5zdGVhZCBmaW5kIGEgd2F5IHRvIGdldCB5b3VyIGZpbGUgIgorICAgICAgICJpbnRvIHRoZSB1bmRlcmx5aW5nIGRhdGFiYXNlLiI7CisgIEdPT0dMRV9DSEVDSyhtdXRleF8gPT0gTlVMTCk7ICAgLy8gSW1wbGllZCBieSB0aGUgYWJvdmUgR09PR0xFX0NIRUNLLgorICB0YWJsZXNfLT5rbm93bl9iYWRfc3ltYm9sc18uY2xlYXIoKTsKKyAgdGFibGVzXy0+a25vd25fYmFkX2ZpbGVzXy5jbGVhcigpOworICByZXR1cm4gRGVzY3JpcHRvckJ1aWxkZXIodGhpcywgdGFibGVzXy5nZXQoKSwgTlVMTCkuQnVpbGRGaWxlKHByb3RvKTsKK30KKworY29uc3QgRmlsZURlc2NyaXB0b3IqIERlc2NyaXB0b3JQb29sOjpCdWlsZEZpbGVDb2xsZWN0aW5nRXJyb3JzKAorICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8mIHByb3RvLAorICAgIEVycm9yQ29sbGVjdG9yKiBlcnJvcl9jb2xsZWN0b3IpIHsKKyAgR09PR0xFX0NIRUNLKGZhbGxiYWNrX2RhdGFiYXNlXyA9PSBOVUxMKQorICAgIDw8ICJDYW5ub3QgY2FsbCBCdWlsZEZpbGUgb24gYSBEZXNjcmlwdG9yUG9vbCB0aGF0IHVzZXMgYSAiCisgICAgICAgIkRlc2NyaXB0b3JEYXRhYmFzZS4gIFlvdSBtdXN0IGluc3RlYWQgZmluZCBhIHdheSB0byBnZXQgeW91ciBmaWxlICIKKyAgICAgICAiaW50byB0aGUgdW5kZXJseWluZyBkYXRhYmFzZS4iOworICBHT09HTEVfQ0hFQ0sobXV0ZXhfID09IE5VTEwpOyAgIC8vIEltcGxpZWQgYnkgdGhlIGFib3ZlIEdPT0dMRV9DSEVDSy4KKyAgdGFibGVzXy0+a25vd25fYmFkX3N5bWJvbHNfLmNsZWFyKCk7CisgIHRhYmxlc18tPmtub3duX2JhZF9maWxlc18uY2xlYXIoKTsKKyAgcmV0dXJuIERlc2NyaXB0b3JCdWlsZGVyKHRoaXMsIHRhYmxlc18uZ2V0KCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvcl9jb2xsZWN0b3IpLkJ1aWxkRmlsZShwcm90byk7Cit9CisKK2NvbnN0IEZpbGVEZXNjcmlwdG9yKiBEZXNjcmlwdG9yUG9vbDo6QnVpbGRGaWxlRnJvbURhdGFiYXNlKAorICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8mIHByb3RvKSBjb25zdCB7CisgIG11dGV4Xy0+QXNzZXJ0SGVsZCgpOworICBpZiAodGFibGVzXy0+a25vd25fYmFkX2ZpbGVzXy5jb3VudChwcm90by5uYW1lKCkpID4gMCkgeworICAgIHJldHVybiBOVUxMOworICB9CisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiByZXN1bHQgPQorICAgICAgRGVzY3JpcHRvckJ1aWxkZXIodGhpcywgdGFibGVzXy5nZXQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRfZXJyb3JfY29sbGVjdG9yXykuQnVpbGRGaWxlKHByb3RvKTsKKyAgaWYgKHJlc3VsdCA9PSBOVUxMKSB7CisgICAgdGFibGVzXy0+a25vd25fYmFkX2ZpbGVzXy5pbnNlcnQocHJvdG8ubmFtZSgpKTsKKyAgfQorICByZXR1cm4gcmVzdWx0OworfQorCitEZXNjcmlwdG9yQnVpbGRlcjo6RGVzY3JpcHRvckJ1aWxkZXIoCisgICAgY29uc3QgRGVzY3JpcHRvclBvb2wqIHBvb2wsCisgICAgRGVzY3JpcHRvclBvb2w6OlRhYmxlcyogdGFibGVzLAorICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3RvciogZXJyb3JfY29sbGVjdG9yKQorICA6IHBvb2xfKHBvb2wpLAorICAgIHRhYmxlc18odGFibGVzKSwKKyAgICBlcnJvcl9jb2xsZWN0b3JfKGVycm9yX2NvbGxlY3RvciksCisgICAgaGFkX2Vycm9yc18oZmFsc2UpLAorICAgIHBvc3NpYmxlX3VuZGVjbGFyZWRfZGVwZW5kZW5jeV8oTlVMTCksCisgICAgdW5kZWZpbmVfcmVzb2x2ZWRfbmFtZV8oIiIpIHt9CisKK0Rlc2NyaXB0b3JCdWlsZGVyOjp+RGVzY3JpcHRvckJ1aWxkZXIoKSB7fQorCit2b2lkIERlc2NyaXB0b3JCdWlsZGVyOjpBZGRFcnJvcigKKyAgICBjb25zdCBzdHJpbmcmIGVsZW1lbnRfbmFtZSwKKyAgICBjb25zdCBNZXNzYWdlJiBkZXNjcmlwdG9yLAorICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6RXJyb3JMb2NhdGlvbiBsb2NhdGlvbiwKKyAgICBjb25zdCBzdHJpbmcmIGVycm9yKSB7CisgIGlmIChlcnJvcl9jb2xsZWN0b3JfID09IE5VTEwpIHsKKyAgICBpZiAoIWhhZF9lcnJvcnNfKSB7CisgICAgICBHT09HTEVfTE9HKEVSUk9SKSA8PCAiSW52YWxpZCBwcm90byBkZXNjcmlwdG9yIGZvciBmaWxlIFwiIiA8PCBmaWxlbmFtZV8KKyAgICAgICAgICAgICAgICAgPDwgIlwiOiI7CisgICAgfQorICAgIEdPT0dMRV9MT0coRVJST1IpIDw8ICIgICIgPDwgZWxlbWVudF9uYW1lIDw8ICI6ICIgPDwgZXJyb3I7CisgIH0gZWxzZSB7CisgICAgZXJyb3JfY29sbGVjdG9yXy0+QWRkRXJyb3IoZmlsZW5hbWVfLCBlbGVtZW50X25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmRlc2NyaXB0b3IsIGxvY2F0aW9uLCBlcnJvcik7CisgIH0KKyAgaGFkX2Vycm9yc18gPSB0cnVlOworfQorCit2b2lkIERlc2NyaXB0b3JCdWlsZGVyOjpBZGRFcnJvcigKKyAgICBjb25zdCBzdHJpbmcmIGVsZW1lbnRfbmFtZSwKKyAgICBjb25zdCBNZXNzYWdlJiBkZXNjcmlwdG9yLAorICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6RXJyb3JMb2NhdGlvbiBsb2NhdGlvbiwKKyAgICBjb25zdCBjaGFyKiBlcnJvcikgeworICBBZGRFcnJvcihlbGVtZW50X25hbWUsIGRlc2NyaXB0b3IsIGxvY2F0aW9uLCBzdHJpbmcoZXJyb3IpKTsKK30KKwordm9pZCBEZXNjcmlwdG9yQnVpbGRlcjo6QWRkTm90RGVmaW5lZEVycm9yKAorICAgIGNvbnN0IHN0cmluZyYgZWxlbWVudF9uYW1lLAorICAgIGNvbnN0IE1lc3NhZ2UmIGRlc2NyaXB0b3IsCisgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpFcnJvckxvY2F0aW9uIGxvY2F0aW9uLAorICAgIGNvbnN0IHN0cmluZyYgdW5kZWZpbmVkX3N5bWJvbCkgeworICBpZiAocG9zc2libGVfdW5kZWNsYXJlZF9kZXBlbmRlbmN5XyA9PSBOVUxMICYmCisgICAgICB1bmRlZmluZV9yZXNvbHZlZF9uYW1lXy5lbXB0eSgpKSB7CisgICAgQWRkRXJyb3IoZWxlbWVudF9uYW1lLCBkZXNjcmlwdG9yLCBsb2NhdGlvbiwKKyAgICAgICAgICAgICAiXCIiICsgdW5kZWZpbmVkX3N5bWJvbCArICJcIiBpcyBub3QgZGVmaW5lZC4iKTsKKyAgfSBlbHNlIHsKKyAgICBpZiAocG9zc2libGVfdW5kZWNsYXJlZF9kZXBlbmRlbmN5XyAhPSBOVUxMKSB7CisgICAgICBBZGRFcnJvcihlbGVtZW50X25hbWUsIGRlc2NyaXB0b3IsIGxvY2F0aW9uLAorICAgICAgICAgICAgICAgIlwiIiArIHBvc3NpYmxlX3VuZGVjbGFyZWRfZGVwZW5kZW5jeV9uYW1lXyArCisgICAgICAgICAgICAgICAiXCIgc2VlbXMgdG8gYmUgZGVmaW5lZCBpbiBcIiIgKworICAgICAgICAgICAgICAgcG9zc2libGVfdW5kZWNsYXJlZF9kZXBlbmRlbmN5Xy0+bmFtZSgpICsgIlwiLCB3aGljaCBpcyBub3QgIgorICAgICAgICAgICAgICAgImltcG9ydGVkIGJ5IFwiIiArIGZpbGVuYW1lXyArICJcIi4gIFRvIHVzZSBpdCBoZXJlLCBwbGVhc2UgIgorICAgICAgICAgICAgICAgImFkZCB0aGUgbmVjZXNzYXJ5IGltcG9ydC4iKTsKKyAgICB9CisgICAgaWYgKCF1bmRlZmluZV9yZXNvbHZlZF9uYW1lXy5lbXB0eSgpKSB7CisgICAgICBBZGRFcnJvcihlbGVtZW50X25hbWUsIGRlc2NyaXB0b3IsIGxvY2F0aW9uLAorICAgICAgICAgICAgICAgIlwiIiArIHVuZGVmaW5lZF9zeW1ib2wgKyAiXCIgaXMgcmVzb2x2ZWQgdG8gXCIiICsKKyAgICAgICAgICAgICAgIHVuZGVmaW5lX3Jlc29sdmVkX25hbWVfICsgIlwiLCB3aGljaCBpcyBub3QgZGVmaW5lZC4gIgorICAgICAgICAgICAgICAgIlRoZSBpbm5lcm1vc3Qgc2NvcGUgaXMgc2VhcmNoZWQgZmlyc3QgaW4gbmFtZSByZXNvbHV0aW9uLiAiCisgICAgICAgICAgICAgICAiQ29uc2lkZXIgdXNpbmcgYSBsZWFkaW5nICcuJyhpLmUuLCBcIi4iCisgICAgICAgICAgICAgICArIHVuZGVmaW5lZF9zeW1ib2wgKworICAgICAgICAgICAgICAgIlwiKSB0byBzdGFydCBmcm9tIHRoZSBvdXRlcm1vc3Qgc2NvcGUuIik7CisgICAgfQorICB9Cit9CisKK3ZvaWQgRGVzY3JpcHRvckJ1aWxkZXI6OkFkZFdhcm5pbmcoCisgICAgY29uc3Qgc3RyaW5nJiBlbGVtZW50X25hbWUsIGNvbnN0IE1lc3NhZ2UmIGRlc2NyaXB0b3IsCisgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpFcnJvckxvY2F0aW9uIGxvY2F0aW9uLAorICAgIGNvbnN0IHN0cmluZyYgZXJyb3IpIHsKKyAgaWYgKGVycm9yX2NvbGxlY3Rvcl8gPT0gTlVMTCkgeworICAgIEdPT0dMRV9MT0coV0FSTklORykgPDwgZmlsZW5hbWVfIDw8ICIgIiA8PCBlbGVtZW50X25hbWUgPDwgIjogIiA8PCBlcnJvcjsKKyAgfSBlbHNlIHsKKyAgICBlcnJvcl9jb2xsZWN0b3JfLT5BZGRXYXJuaW5nKGZpbGVuYW1lXywgZWxlbWVudF9uYW1lLCAmZGVzY3JpcHRvciwgbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvcik7CisgIH0KK30KKworYm9vbCBEZXNjcmlwdG9yQnVpbGRlcjo6SXNJblBhY2thZ2UoY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHBhY2thZ2VfbmFtZSkgeworICByZXR1cm4gSGFzUHJlZml4U3RyaW5nKGZpbGUtPnBhY2thZ2UoKSwgcGFja2FnZV9uYW1lKSAmJgorICAgICAgICAgICAoZmlsZS0+cGFja2FnZSgpLnNpemUoKSA9PSBwYWNrYWdlX25hbWUuc2l6ZSgpIHx8CisgICAgICAgICAgICBmaWxlLT5wYWNrYWdlKClbcGFja2FnZV9uYW1lLnNpemUoKV0gPT0gJy4nKTsKK30KKwordm9pZCBEZXNjcmlwdG9yQnVpbGRlcjo6UmVjb3JkUHVibGljRGVwZW5kZW5jaWVzKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKSB7CisgIGlmIChmaWxlID09IE5VTEwgfHwgIWRlcGVuZGVuY2llc18uaW5zZXJ0KGZpbGUpLnNlY29uZCkgcmV0dXJuOworICBmb3IgKGludCBpID0gMDsgZmlsZSAhPSBOVUxMICYmIGkgPCBmaWxlLT5wdWJsaWNfZGVwZW5kZW5jeV9jb3VudCgpOyBpKyspIHsKKyAgICBSZWNvcmRQdWJsaWNEZXBlbmRlbmNpZXMoZmlsZS0+cHVibGljX2RlcGVuZGVuY3koaSkpOworICB9Cit9CisKK1N5bWJvbCBEZXNjcmlwdG9yQnVpbGRlcjo6RmluZFN5bWJvbE5vdEVuZm9yY2luZ0RlcHNIZWxwZXIoCisgICAgY29uc3QgRGVzY3JpcHRvclBvb2wqIHBvb2wsIGNvbnN0IHN0cmluZyYgbmFtZSkgeworICAvLyBJZiB3ZSBhcmUgbG9va2luZyBhdCBhbiB1bmRlcmxheSwgd2UgbXVzdCBsb2NrIGl0cyBtdXRleF8sIHNpbmNlIHdlIGFyZQorICAvLyBhY2Nlc3NpbmcgdGhlIHVuZGVybGF5J3MgdGFibGVzXyBkaXJlY3RseS4KKyAgTXV0ZXhMb2NrTWF5YmUgbG9jaygocG9vbCA9PSBwb29sXykgPyBOVUxMIDogcG9vbC0+bXV0ZXhfKTsKKworICBTeW1ib2wgcmVzdWx0ID0gcG9vbC0+dGFibGVzXy0+RmluZFN5bWJvbChuYW1lKTsKKyAgaWYgKHJlc3VsdC5Jc051bGwoKSAmJiBwb29sLT51bmRlcmxheV8gIT0gTlVMTCkgeworICAgIC8vIFN5bWJvbCBub3QgZm91bmQ7IGNoZWNrIHRoZSB1bmRlcmxheS4KKyAgICByZXN1bHQgPSBGaW5kU3ltYm9sTm90RW5mb3JjaW5nRGVwc0hlbHBlcihwb29sLT51bmRlcmxheV8sIG5hbWUpOworICB9CisKKyAgaWYgKHJlc3VsdC5Jc051bGwoKSkgeworICAgIC8vIEluIHRoZW9yeSwgd2Ugc2hvdWxkbid0IG5lZWQgdG8gY2hlY2sgZmFsbGJhY2tfZGF0YWJhc2VfIGJlY2F1c2UgdGhlCisgICAgLy8gc3ltYm9sIHNob3VsZCBiZSBpbiBvbmUgb2YgaXRzIGZpbGUncyBkaXJlY3QgZGVwZW5kZW5jaWVzLCBhbmQgd2UgaGF2ZQorICAgIC8vIGFscmVhZHkgbG9hZGVkIHRob3NlIGJ5IHRoZSB0aW1lIHdlIGdldCBoZXJlLiAgQnV0IHdlIGNoZWNrIGFueXdheSBzbworICAgIC8vIHRoYXQgd2UgY2FuIGdlbmVyYXRlIGJldHRlciBlcnJvciBtZXNzYWdlIHdoZW4gZGVwZW5kZW5jaWVzIGFyZSBtaXNzaW5nCisgICAgLy8gKGkuZS4sICJtaXNzaW5nIGRlcGVuZGVuY3kiIHJhdGhlciB0aGFuICJ0eXBlIGlzIG5vdCBkZWZpbmVkIikuCisgICAgaWYgKHBvb2wtPlRyeUZpbmRTeW1ib2xJbkZhbGxiYWNrRGF0YWJhc2UobmFtZSkpIHsKKyAgICAgIHJlc3VsdCA9IHBvb2wtPnRhYmxlc18tPkZpbmRTeW1ib2wobmFtZSk7CisgICAgfQorICB9CisKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworU3ltYm9sIERlc2NyaXB0b3JCdWlsZGVyOjpGaW5kU3ltYm9sTm90RW5mb3JjaW5nRGVwcyhjb25zdCBzdHJpbmcmIG5hbWUpIHsKKyAgcmV0dXJuIEZpbmRTeW1ib2xOb3RFbmZvcmNpbmdEZXBzSGVscGVyKHBvb2xfLCBuYW1lKTsKK30KKworU3ltYm9sIERlc2NyaXB0b3JCdWlsZGVyOjpGaW5kU3ltYm9sKGNvbnN0IHN0cmluZyYgbmFtZSkgeworICBTeW1ib2wgcmVzdWx0ID0gRmluZFN5bWJvbE5vdEVuZm9yY2luZ0RlcHMobmFtZSk7CisKKyAgaWYgKHJlc3VsdC5Jc051bGwoKSkgcmV0dXJuIHJlc3VsdDsKKworICBpZiAoIXBvb2xfLT5lbmZvcmNlX2RlcGVuZGVuY2llc18pIHsKKyAgICAvLyBIYWNrIGZvciBDb21waWxlclVwZ3JhZGVyLgorICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworICAvLyBPbmx5IGZpbmQgc3ltYm9scyB3aGljaCB3ZXJlIGRlZmluZWQgaW4gdGhpcyBmaWxlIG9yIG9uZSBvZiBpdHMKKyAgLy8gZGVwZW5kZW5jaWVzLgorICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSA9IHJlc3VsdC5HZXRGaWxlKCk7CisgIGlmIChmaWxlID09IGZpbGVfIHx8IGRlcGVuZGVuY2llc18uY291bnQoZmlsZSkgPiAwKSB7CisgICAgdW51c2VkX2RlcGVuZGVuY3lfLmVyYXNlKGZpbGUpOworICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworICBpZiAocmVzdWx0LnR5cGUgPT0gU3ltYm9sOjpQQUNLQUdFKSB7CisgICAgLy8gQXJnLCB0aGlzIGlzIG92ZXJjb21wbGljYXRlZC4gIFRoZSBzeW1ib2wgaXMgYSBwYWNrYWdlIG5hbWUuICBJdCBjb3VsZAorICAgIC8vIGJlIHRoYXQgdGhlIHBhY2thZ2Ugd2FzIGRlZmluZWQgaW4gbXVsdGlwbGUgZmlsZXMuICByZXN1bHQuR2V0RmlsZSgpCisgICAgLy8gcmV0dXJucyB0aGUgZmlyc3QgZmlsZSB3ZSBzYXcgdGhhdCB1c2VkIHRoaXMgcGFja2FnZS4gIFdlJ3ZlIGRldGVybWluZWQKKyAgICAvLyB0aGF0IHRoYXQgZmlsZSBpcyBub3QgYSBkaXJlY3QgZGVwZW5kZW5jeSBvZiB0aGUgZmlsZSB3ZSBhcmUgY3VycmVudGx5CisgICAgLy8gYnVpbGRpbmcsIGJ1dCBpdCBjb3VsZCBiZSB0aGF0IHNvbWUgb3RoZXIgZmlsZSB3aGljaCAqaXMqIGEgZGlyZWN0CisgICAgLy8gZGVwZW5kZW5jeSBhbHNvIGRlZmluZXMgdGhlIHNhbWUgcGFja2FnZS4gIFdlIGNhbid0IHJlYWxseSBydWxlIG91dCB0aGlzCisgICAgLy8gc3ltYm9sIHVubGVzcyBub25lIG9mIHRoZSBkZXBlbmRlbmNpZXMgZGVmaW5lIGl0LgorICAgIGlmIChJc0luUGFja2FnZShmaWxlXywgbmFtZSkpIHJldHVybiByZXN1bHQ7CisgICAgZm9yIChzZXQ8Y29uc3QgRmlsZURlc2NyaXB0b3IqPjo6Y29uc3RfaXRlcmF0b3IgaXQgPSBkZXBlbmRlbmNpZXNfLmJlZ2luKCk7CisgICAgICAgICBpdCAhPSBkZXBlbmRlbmNpZXNfLmVuZCgpOyArK2l0KSB7CisgICAgICAvLyBOb3RlOiAgQSBkZXBlbmRlbmN5IG1heSBiZSBOVUxMIGlmIGl0IHdhcyBub3QgZm91bmQgb3IgaGFkIGVycm9ycy4KKyAgICAgIGlmICgqaXQgIT0gTlVMTCAmJiBJc0luUGFja2FnZSgqaXQsIG5hbWUpKSByZXR1cm4gcmVzdWx0OworICAgIH0KKyAgfQorCisgIHBvc3NpYmxlX3VuZGVjbGFyZWRfZGVwZW5kZW5jeV8gPSBmaWxlOworICBwb3NzaWJsZV91bmRlY2xhcmVkX2RlcGVuZGVuY3lfbmFtZV8gPSBuYW1lOworICByZXR1cm4ga051bGxTeW1ib2w7Cit9CisKK1N5bWJvbCBEZXNjcmlwdG9yQnVpbGRlcjo6TG9va3VwU3ltYm9sTm9QbGFjZWhvbGRlcigKKyAgICBjb25zdCBzdHJpbmcmIG5hbWUsIGNvbnN0IHN0cmluZyYgcmVsYXRpdmVfdG8sIFJlc29sdmVNb2RlIHJlc29sdmVfbW9kZSkgeworICBwb3NzaWJsZV91bmRlY2xhcmVkX2RlcGVuZGVuY3lfID0gTlVMTDsKKyAgdW5kZWZpbmVfcmVzb2x2ZWRfbmFtZV8uY2xlYXIoKTsKKworICBpZiAobmFtZS5zaXplKCkgPiAwICYmIG5hbWVbMF0gPT0gJy4nKSB7CisgICAgLy8gRnVsbHktcXVhbGlmaWVkIG5hbWUuCisgICAgcmV0dXJuIEZpbmRTeW1ib2wobmFtZS5zdWJzdHIoMSkpOworICB9CisKKyAgLy8gSWYgbmFtZSBpcyBzb21ldGhpbmcgbGlrZSAiRm9vLkJhci5iYXoiLCBhbmQgc3ltYm9scyBuYW1lZCAiRm9vIiBhcmUKKyAgLy8gZGVmaW5lZCBpbiBtdWx0aXBsZSBwYXJlbnQgc2NvcGVzLCB3ZSBvbmx5IHdhbnQgdG8gZmluZCAiQmFyLmJheiIgaW4gdGhlCisgIC8vIGlubmVybW9zdCBvbmUuICBFLmcuLCB0aGUgZm9sbG93aW5nIHNob3VsZCBwcm9kdWNlIGFuIGVycm9yOgorICAvLyAgIG1lc3NhZ2UgQmFyIHsgbWVzc2FnZSBCYXoge30gfQorICAvLyAgIG1lc3NhZ2UgRm9vIHsKKyAgLy8gICAgIG1lc3NhZ2UgQmFyIHsKKyAgLy8gICAgIH0KKyAgLy8gICAgIG9wdGlvbmFsIEJhci5CYXogYmF6ID0gMTsKKyAgLy8gICB9CisgIC8vIFNvLCB3ZSBsb29rIGZvciBqdXN0ICJGb28iIGZpcnN0LCB0aGVuIGxvb2sgZm9yICJCYXIuYmF6IiB3aXRoaW4gaXQgaWYKKyAgLy8gZm91bmQuCisgIHN0cmluZzo6c2l6ZV90eXBlIG5hbWVfZG90X3BvcyA9IG5hbWUuZmluZF9maXJzdF9vZignLicpOworICBzdHJpbmcgZmlyc3RfcGFydF9vZl9uYW1lOworICBpZiAobmFtZV9kb3RfcG9zID09IHN0cmluZzo6bnBvcykgeworICAgIGZpcnN0X3BhcnRfb2ZfbmFtZSA9IG5hbWU7CisgIH0gZWxzZSB7CisgICAgZmlyc3RfcGFydF9vZl9uYW1lID0gbmFtZS5zdWJzdHIoMCwgbmFtZV9kb3RfcG9zKTsKKyAgfQorCisgIHN0cmluZyBzY29wZV90b190cnkocmVsYXRpdmVfdG8pOworCisgIHdoaWxlICh0cnVlKSB7CisgICAgLy8gQ2hvcCBvZmYgdGhlIGxhc3QgY29tcG9uZW50IG9mIHRoZSBzY29wZS4KKyAgICBzdHJpbmc6OnNpemVfdHlwZSBkb3RfcG9zID0gc2NvcGVfdG9fdHJ5LmZpbmRfbGFzdF9vZignLicpOworICAgIGlmIChkb3RfcG9zID09IHN0cmluZzo6bnBvcykgeworICAgICAgcmV0dXJuIEZpbmRTeW1ib2wobmFtZSk7CisgICAgfSBlbHNlIHsKKyAgICAgIHNjb3BlX3RvX3RyeS5lcmFzZShkb3RfcG9zKTsKKyAgICB9CisKKyAgICAvLyBBcHBlbmQgIi5maXJzdF9wYXJ0X29mX25hbWUiIGFuZCB0cnkgdG8gZmluZC4KKyAgICBzdHJpbmc6OnNpemVfdHlwZSBvbGRfc2l6ZSA9IHNjb3BlX3RvX3RyeS5zaXplKCk7CisgICAgc2NvcGVfdG9fdHJ5LmFwcGVuZCgxLCAnLicpOworICAgIHNjb3BlX3RvX3RyeS5hcHBlbmQoZmlyc3RfcGFydF9vZl9uYW1lKTsKKyAgICBTeW1ib2wgcmVzdWx0ID0gRmluZFN5bWJvbChzY29wZV90b190cnkpOworICAgIGlmICghcmVzdWx0LklzTnVsbCgpKSB7CisgICAgICBpZiAoZmlyc3RfcGFydF9vZl9uYW1lLnNpemUoKSA8IG5hbWUuc2l6ZSgpKSB7CisgICAgICAgIC8vIG5hbWUgaXMgYSBjb21wb3VuZCBzeW1ib2wsIG9mIHdoaWNoIHdlIG9ubHkgZm91bmQgdGhlIGZpcnN0IHBhcnQuCisgICAgICAgIC8vIE5vdyB0cnkgdG8gbG9vayB1cCB0aGUgcmVzdCBvZiBpdC4KKyAgICAgICAgaWYgKHJlc3VsdC5Jc0FnZ3JlZ2F0ZSgpKSB7CisgICAgICAgICAgc2NvcGVfdG9fdHJ5LmFwcGVuZChuYW1lLCBmaXJzdF9wYXJ0X29mX25hbWUuc2l6ZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZS5zaXplKCkgLSBmaXJzdF9wYXJ0X29mX25hbWUuc2l6ZSgpKTsKKyAgICAgICAgICByZXN1bHQgPSBGaW5kU3ltYm9sKHNjb3BlX3RvX3RyeSk7CisgICAgICAgICAgaWYgKHJlc3VsdC5Jc051bGwoKSkgeworICAgICAgICAgICAgdW5kZWZpbmVfcmVzb2x2ZWRfbmFtZV8gPSBzY29wZV90b190cnk7CisgICAgICAgICAgfQorICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgLy8gV2UgZm91bmQgYSBzeW1ib2wgYnV0IGl0J3Mgbm90IGFuIGFnZ3JlZ2F0ZS4gIENvbnRpbnVlIHRoZSBsb29wLgorICAgICAgICB9CisgICAgICB9IGVsc2UgeworICAgICAgICBpZiAocmVzb2x2ZV9tb2RlID09IExPT0tVUF9UWVBFUyAmJiAhcmVzdWx0LklzVHlwZSgpKSB7CisgICAgICAgICAgLy8gV2UgZm91bmQgYSBzeW1ib2wgYnV0IGl0J3Mgbm90IGEgdHlwZS4gIENvbnRpbnVlIHRoZSBsb29wLgorICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisKKyAgICAvLyBOb3QgZm91bmQuICBSZW1vdmUgdGhlIG5hbWUgc28gd2UgY2FuIHRyeSBhZ2Fpbi4KKyAgICBzY29wZV90b190cnkuZXJhc2Uob2xkX3NpemUpOworICB9Cit9CisKK1N5bWJvbCBEZXNjcmlwdG9yQnVpbGRlcjo6TG9va3VwU3ltYm9sKAorICAgIGNvbnN0IHN0cmluZyYgbmFtZSwgY29uc3Qgc3RyaW5nJiByZWxhdGl2ZV90bywKKyAgICBQbGFjZWhvbGRlclR5cGUgcGxhY2Vob2xkZXJfdHlwZSwgUmVzb2x2ZU1vZGUgcmVzb2x2ZV9tb2RlKSB7CisgIFN5bWJvbCByZXN1bHQgPSBMb29rdXBTeW1ib2xOb1BsYWNlaG9sZGVyKAorICAgICAgbmFtZSwgcmVsYXRpdmVfdG8sIHJlc29sdmVfbW9kZSk7CisgIGlmIChyZXN1bHQuSXNOdWxsKCkgJiYgcG9vbF8tPmFsbG93X3Vua25vd25fKSB7CisgICAgLy8gTm90IGZvdW5kLCBidXQgQWxsb3dVbmtub3duRGVwZW5kZW5jaWVzKCkgaXMgZW5hYmxlZC4gIFJldHVybiBhCisgICAgLy8gcGxhY2Vob2xkZXIgaW5zdGVhZC4KKyAgICByZXN1bHQgPSBOZXdQbGFjZWhvbGRlcihuYW1lLCBwbGFjZWhvbGRlcl90eXBlKTsKKyAgfQorICByZXR1cm4gcmVzdWx0OworfQorCitTeW1ib2wgRGVzY3JpcHRvckJ1aWxkZXI6Ok5ld1BsYWNlaG9sZGVyKGNvbnN0IHN0cmluZyYgbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUGxhY2Vob2xkZXJUeXBlIHBsYWNlaG9sZGVyX3R5cGUpIHsKKyAgLy8gQ29tcHV0ZSBuYW1lcy4KKyAgY29uc3Qgc3RyaW5nKiBwbGFjZWhvbGRlcl9mdWxsX25hbWU7CisgIGNvbnN0IHN0cmluZyogcGxhY2Vob2xkZXJfbmFtZTsKKyAgY29uc3Qgc3RyaW5nKiBwbGFjZWhvbGRlcl9wYWNrYWdlOworCisgIGlmICghVmFsaWRhdGVRdWFsaWZpZWROYW1lKG5hbWUpKSByZXR1cm4ga051bGxTeW1ib2w7CisgIGlmIChuYW1lWzBdID09ICcuJykgeworICAgIC8vIEZ1bGx5LXF1YWxpZmllZC4KKyAgICBwbGFjZWhvbGRlcl9mdWxsX25hbWUgPSB0YWJsZXNfLT5BbGxvY2F0ZVN0cmluZyhuYW1lLnN1YnN0cigxKSk7CisgIH0gZWxzZSB7CisgICAgcGxhY2Vob2xkZXJfZnVsbF9uYW1lID0gdGFibGVzXy0+QWxsb2NhdGVTdHJpbmcobmFtZSk7CisgIH0KKworICBzdHJpbmc6OnNpemVfdHlwZSBkb3Rwb3MgPSBwbGFjZWhvbGRlcl9mdWxsX25hbWUtPmZpbmRfbGFzdF9vZignLicpOworICBpZiAoZG90cG9zICE9IHN0cmluZzo6bnBvcykgeworICAgIHBsYWNlaG9sZGVyX3BhY2thZ2UgPSB0YWJsZXNfLT5BbGxvY2F0ZVN0cmluZygKKyAgICAgIHBsYWNlaG9sZGVyX2Z1bGxfbmFtZS0+c3Vic3RyKDAsIGRvdHBvcykpOworICAgIHBsYWNlaG9sZGVyX25hbWUgPSB0YWJsZXNfLT5BbGxvY2F0ZVN0cmluZygKKyAgICAgIHBsYWNlaG9sZGVyX2Z1bGxfbmFtZS0+c3Vic3RyKGRvdHBvcyArIDEpKTsKKyAgfSBlbHNlIHsKKyAgICBwbGFjZWhvbGRlcl9wYWNrYWdlID0gJmludGVybmFsOjpHZXRFbXB0eVN0cmluZygpOworICAgIHBsYWNlaG9sZGVyX25hbWUgPSBwbGFjZWhvbGRlcl9mdWxsX25hbWU7CisgIH0KKworICAvLyBDcmVhdGUgdGhlIHBsYWNlaG9sZGVycy4KKyAgRmlsZURlc2NyaXB0b3IqIHBsYWNlaG9sZGVyX2ZpbGUgPSBOZXdQbGFjZWhvbGRlckZpbGUoCisgICAgICAqcGxhY2Vob2xkZXJfZnVsbF9uYW1lICsgIi5wbGFjZWhvbGRlci5wcm90byIpOworICBwbGFjZWhvbGRlcl9maWxlLT5wYWNrYWdlXyA9IHBsYWNlaG9sZGVyX3BhY2thZ2U7CisKKyAgaWYgKHBsYWNlaG9sZGVyX3R5cGUgPT0gUExBQ0VIT0xERVJfRU5VTSkgeworICAgIHBsYWNlaG9sZGVyX2ZpbGUtPmVudW1fdHlwZV9jb3VudF8gPSAxOworICAgIHBsYWNlaG9sZGVyX2ZpbGUtPmVudW1fdHlwZXNfID0KKyAgICAgIHRhYmxlc18tPkFsbG9jYXRlQXJyYXk8RW51bURlc2NyaXB0b3I+KDEpOworCisgICAgRW51bURlc2NyaXB0b3IqIHBsYWNlaG9sZGVyX2VudW0gPSAmcGxhY2Vob2xkZXJfZmlsZS0+ZW51bV90eXBlc19bMF07CisgICAgbWVtc2V0KHBsYWNlaG9sZGVyX2VudW0sIDAsIHNpemVvZigqcGxhY2Vob2xkZXJfZW51bSkpOworCisgICAgcGxhY2Vob2xkZXJfZW51bS0+ZnVsbF9uYW1lXyA9IHBsYWNlaG9sZGVyX2Z1bGxfbmFtZTsKKyAgICBwbGFjZWhvbGRlcl9lbnVtLT5uYW1lXyA9IHBsYWNlaG9sZGVyX25hbWU7CisgICAgcGxhY2Vob2xkZXJfZW51bS0+ZmlsZV8gPSBwbGFjZWhvbGRlcl9maWxlOworICAgIHBsYWNlaG9sZGVyX2VudW0tPm9wdGlvbnNfID0gJkVudW1PcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlKCk7CisgICAgcGxhY2Vob2xkZXJfZW51bS0+aXNfcGxhY2Vob2xkZXJfID0gdHJ1ZTsKKyAgICBwbGFjZWhvbGRlcl9lbnVtLT5pc191bnF1YWxpZmllZF9wbGFjZWhvbGRlcl8gPSAobmFtZVswXSAhPSAnLicpOworCisgICAgLy8gRW51bXMgbXVzdCBoYXZlIGF0IGxlYXN0IG9uZSB2YWx1ZS4KKyAgICBwbGFjZWhvbGRlcl9lbnVtLT52YWx1ZV9jb3VudF8gPSAxOworICAgIHBsYWNlaG9sZGVyX2VudW0tPnZhbHVlc18gPSB0YWJsZXNfLT5BbGxvY2F0ZUFycmF5PEVudW1WYWx1ZURlc2NyaXB0b3I+KDEpOworCisgICAgRW51bVZhbHVlRGVzY3JpcHRvciogcGxhY2Vob2xkZXJfdmFsdWUgPSAmcGxhY2Vob2xkZXJfZW51bS0+dmFsdWVzX1swXTsKKyAgICBtZW1zZXQocGxhY2Vob2xkZXJfdmFsdWUsIDAsIHNpemVvZigqcGxhY2Vob2xkZXJfdmFsdWUpKTsKKworICAgIHBsYWNlaG9sZGVyX3ZhbHVlLT5uYW1lXyA9IHRhYmxlc18tPkFsbG9jYXRlU3RyaW5nKCJQTEFDRUhPTERFUl9WQUxVRSIpOworICAgIC8vIE5vdGUgdGhhdCBlbnVtIHZhbHVlIG5hbWVzIGFyZSBzaWJsaW5ncyBvZiB0aGVpciB0eXBlLCBub3QgY2hpbGRyZW4uCisgICAgcGxhY2Vob2xkZXJfdmFsdWUtPmZ1bGxfbmFtZV8gPQorICAgICAgcGxhY2Vob2xkZXJfcGFja2FnZS0+ZW1wdHkoKSA/IHBsYWNlaG9sZGVyX3ZhbHVlLT5uYW1lXyA6CisgICAgICAgIHRhYmxlc18tPkFsbG9jYXRlU3RyaW5nKCpwbGFjZWhvbGRlcl9wYWNrYWdlICsgIi5QTEFDRUhPTERFUl9WQUxVRSIpOworCisgICAgcGxhY2Vob2xkZXJfdmFsdWUtPm51bWJlcl8gPSAwOworICAgIHBsYWNlaG9sZGVyX3ZhbHVlLT50eXBlXyA9IHBsYWNlaG9sZGVyX2VudW07CisgICAgcGxhY2Vob2xkZXJfdmFsdWUtPm9wdGlvbnNfID0gJkVudW1WYWx1ZU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2UoKTsKKworICAgIHJldHVybiBTeW1ib2wocGxhY2Vob2xkZXJfZW51bSk7CisgIH0gZWxzZSB7CisgICAgcGxhY2Vob2xkZXJfZmlsZS0+bWVzc2FnZV90eXBlX2NvdW50XyA9IDE7CisgICAgcGxhY2Vob2xkZXJfZmlsZS0+bWVzc2FnZV90eXBlc18gPQorICAgICAgdGFibGVzXy0+QWxsb2NhdGVBcnJheTxEZXNjcmlwdG9yPigxKTsKKworICAgIERlc2NyaXB0b3IqIHBsYWNlaG9sZGVyX21lc3NhZ2UgPSAmcGxhY2Vob2xkZXJfZmlsZS0+bWVzc2FnZV90eXBlc19bMF07CisgICAgbWVtc2V0KHBsYWNlaG9sZGVyX21lc3NhZ2UsIDAsIHNpemVvZigqcGxhY2Vob2xkZXJfbWVzc2FnZSkpOworCisgICAgcGxhY2Vob2xkZXJfbWVzc2FnZS0+ZnVsbF9uYW1lXyA9IHBsYWNlaG9sZGVyX2Z1bGxfbmFtZTsKKyAgICBwbGFjZWhvbGRlcl9tZXNzYWdlLT5uYW1lXyA9IHBsYWNlaG9sZGVyX25hbWU7CisgICAgcGxhY2Vob2xkZXJfbWVzc2FnZS0+ZmlsZV8gPSBwbGFjZWhvbGRlcl9maWxlOworICAgIHBsYWNlaG9sZGVyX21lc3NhZ2UtPm9wdGlvbnNfID0gJk1lc3NhZ2VPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlKCk7CisgICAgcGxhY2Vob2xkZXJfbWVzc2FnZS0+aXNfcGxhY2Vob2xkZXJfID0gdHJ1ZTsKKyAgICBwbGFjZWhvbGRlcl9tZXNzYWdlLT5pc191bnF1YWxpZmllZF9wbGFjZWhvbGRlcl8gPSAobmFtZVswXSAhPSAnLicpOworCisgICAgaWYgKHBsYWNlaG9sZGVyX3R5cGUgPT0gUExBQ0VIT0xERVJfRVhURU5EQUJMRV9NRVNTQUdFKSB7CisgICAgICBwbGFjZWhvbGRlcl9tZXNzYWdlLT5leHRlbnNpb25fcmFuZ2VfY291bnRfID0gMTsKKyAgICAgIHBsYWNlaG9sZGVyX21lc3NhZ2UtPmV4dGVuc2lvbl9yYW5nZXNfID0KKyAgICAgICAgdGFibGVzXy0+QWxsb2NhdGVBcnJheTxEZXNjcmlwdG9yOjpFeHRlbnNpb25SYW5nZT4oMSk7CisgICAgICBwbGFjZWhvbGRlcl9tZXNzYWdlLT5leHRlbnNpb25fcmFuZ2VzXy0+c3RhcnQgPSAxOworICAgICAgLy8ga01heE51bWJlciArIDEgYmVjYXVzZSBFeHRlbnNpb25SYW5nZTo6ZW5kIGlzIGV4Y2x1c2l2ZS4KKyAgICAgIHBsYWNlaG9sZGVyX21lc3NhZ2UtPmV4dGVuc2lvbl9yYW5nZXNfLT5lbmQgPQorICAgICAgICBGaWVsZERlc2NyaXB0b3I6OmtNYXhOdW1iZXIgKyAxOworICAgIH0KKworICAgIHJldHVybiBTeW1ib2wocGxhY2Vob2xkZXJfbWVzc2FnZSk7CisgIH0KK30KKworRmlsZURlc2NyaXB0b3IqIERlc2NyaXB0b3JCdWlsZGVyOjpOZXdQbGFjZWhvbGRlckZpbGUoCisgICAgY29uc3Qgc3RyaW5nJiBuYW1lKSB7CisgIEZpbGVEZXNjcmlwdG9yKiBwbGFjZWhvbGRlciA9IHRhYmxlc18tPkFsbG9jYXRlPEZpbGVEZXNjcmlwdG9yPigpOworICBtZW1zZXQocGxhY2Vob2xkZXIsIDAsIHNpemVvZigqcGxhY2Vob2xkZXIpKTsKKworICBwbGFjZWhvbGRlci0+bmFtZV8gPSB0YWJsZXNfLT5BbGxvY2F0ZVN0cmluZyhuYW1lKTsKKyAgcGxhY2Vob2xkZXItPnBhY2thZ2VfID0gJmludGVybmFsOjpHZXRFbXB0eVN0cmluZygpOworICBwbGFjZWhvbGRlci0+cG9vbF8gPSBwb29sXzsKKyAgcGxhY2Vob2xkZXItPm9wdGlvbnNfID0gJkZpbGVPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlKCk7CisgIHBsYWNlaG9sZGVyLT50YWJsZXNfID0gJkZpbGVEZXNjcmlwdG9yVGFibGVzOjpHZXRFbXB0eUluc3RhbmNlKCk7CisgIHBsYWNlaG9sZGVyLT5zb3VyY2VfY29kZV9pbmZvXyA9ICZTb3VyY2VDb2RlSW5mbzo6ZGVmYXVsdF9pbnN0YW5jZSgpOworICBwbGFjZWhvbGRlci0+aXNfcGxhY2Vob2xkZXJfID0gdHJ1ZTsKKyAgcGxhY2Vob2xkZXItPnN5bnRheF8gPSBGaWxlRGVzY3JpcHRvcjo6U1lOVEFYX1BST1RPMjsKKyAgLy8gQWxsIG90aGVyIGZpZWxkcyBhcmUgemVybyBvciBOVUxMLgorCisgIHJldHVybiBwbGFjZWhvbGRlcjsKK30KKworYm9vbCBEZXNjcmlwdG9yQnVpbGRlcjo6QWRkU3ltYm9sKAorICAgIGNvbnN0IHN0cmluZyYgZnVsbF9uYW1lLCBjb25zdCB2b2lkKiBwYXJlbnQsIGNvbnN0IHN0cmluZyYgbmFtZSwKKyAgICBjb25zdCBNZXNzYWdlJiBwcm90bywgU3ltYm9sIHN5bWJvbCkgeworICAvLyBJZiB0aGUgY2FsbGVyIHBhc3NlZCBOVUxMIGZvciB0aGUgcGFyZW50LCB0aGUgc3ltYm9sIGlzIGF0IGZpbGUgc2NvcGUuCisgIC8vIFVzZSBpdHMgZmlsZSBhcyB0aGUgcGFyZW50IGluc3RlYWQuCisgIGlmIChwYXJlbnQgPT0gTlVMTCkgcGFyZW50ID0gZmlsZV87CisKKyAgaWYgKHRhYmxlc18tPkFkZFN5bWJvbChmdWxsX25hbWUsIHN5bWJvbCkpIHsKKyAgICBpZiAoIWZpbGVfdGFibGVzXy0+QWRkQWxpYXNVbmRlclBhcmVudChwYXJlbnQsIG5hbWUsIHN5bWJvbCkpIHsKKyAgICAgIEdPT0dMRV9MT0coREZBVEFMKSA8PCAiXCIiIDw8IGZ1bGxfbmFtZSA8PCAiXCIgbm90IHByZXZpb3VzbHkgZGVmaW5lZCBpbiAiCisgICAgICAgICAgICAgICAgICAgICAic3ltYm9sc19ieV9uYW1lXywgYnV0IHdhcyBkZWZpbmVkIGluIHN5bWJvbHNfYnlfcGFyZW50XzsgIgorICAgICAgICAgICAgICAgICAgICAgInRoaXMgc2hvdWxkbid0IGJlIHBvc3NpYmxlLiI7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIHJldHVybiB0cnVlOworICB9IGVsc2UgeworICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBvdGhlcl9maWxlID0gdGFibGVzXy0+RmluZFN5bWJvbChmdWxsX25hbWUpLkdldEZpbGUoKTsKKyAgICBpZiAob3RoZXJfZmlsZSA9PSBmaWxlXykgeworICAgICAgc3RyaW5nOjpzaXplX3R5cGUgZG90X3BvcyA9IGZ1bGxfbmFtZS5maW5kX2xhc3Rfb2YoJy4nKTsKKyAgICAgIGlmIChkb3RfcG9zID09IHN0cmluZzo6bnBvcykgeworICAgICAgICBBZGRFcnJvcihmdWxsX25hbWUsIHByb3RvLCBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok5BTUUsCisgICAgICAgICAgICAgICAgICJcIiIgKyBmdWxsX25hbWUgKyAiXCIgaXMgYWxyZWFkeSBkZWZpbmVkLiIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgQWRkRXJyb3IoZnVsbF9uYW1lLCBwcm90bywgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpOQU1FLAorICAgICAgICAgICAgICAgICAiXCIiICsgZnVsbF9uYW1lLnN1YnN0cihkb3RfcG9zICsgMSkgKworICAgICAgICAgICAgICAgICAiXCIgaXMgYWxyZWFkeSBkZWZpbmVkIGluIFwiIiArCisgICAgICAgICAgICAgICAgIGZ1bGxfbmFtZS5zdWJzdHIoMCwgZG90X3BvcykgKyAiXCIuIik7CisgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgIC8vIFN5bWJvbCBzZWVtcyB0byBoYXZlIGJlZW4gZGVmaW5lZCBpbiBhIGRpZmZlcmVudCBmaWxlLgorICAgICAgQWRkRXJyb3IoZnVsbF9uYW1lLCBwcm90bywgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpOQU1FLAorICAgICAgICAgICAgICAgIlwiIiArIGZ1bGxfbmFtZSArICJcIiBpcyBhbHJlYWR5IGRlZmluZWQgaW4gZmlsZSBcIiIgKworICAgICAgICAgICAgICAgb3RoZXJfZmlsZS0+bmFtZSgpICsgIlwiLiIpOworICAgIH0KKyAgICByZXR1cm4gZmFsc2U7CisgIH0KK30KKwordm9pZCBEZXNjcmlwdG9yQnVpbGRlcjo6QWRkUGFja2FnZSgKKyAgICBjb25zdCBzdHJpbmcmIG5hbWUsIGNvbnN0IE1lc3NhZ2UmIHByb3RvLCBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSkgeworICBpZiAodGFibGVzXy0+QWRkU3ltYm9sKG5hbWUsIFN5bWJvbChmaWxlKSkpIHsKKyAgICAvLyBTdWNjZXNzLiAgQWxzbyBhZGQgcGFyZW50IHBhY2thZ2UsIGlmIGFueS4KKyAgICBzdHJpbmc6OnNpemVfdHlwZSBkb3RfcG9zID0gbmFtZS5maW5kX2xhc3Rfb2YoJy4nKTsKKyAgICBpZiAoZG90X3BvcyA9PSBzdHJpbmc6Om5wb3MpIHsKKyAgICAgIC8vIE5vIHBhcmVudHMuCisgICAgICBWYWxpZGF0ZVN5bWJvbE5hbWUobmFtZSwgbmFtZSwgcHJvdG8pOworICAgIH0gZWxzZSB7CisgICAgICAvLyBIYXMgcGFyZW50LgorICAgICAgc3RyaW5nKiBwYXJlbnRfbmFtZSA9IHRhYmxlc18tPkFsbG9jYXRlU3RyaW5nKG5hbWUuc3Vic3RyKDAsIGRvdF9wb3MpKTsKKyAgICAgIEFkZFBhY2thZ2UoKnBhcmVudF9uYW1lLCBwcm90bywgZmlsZSk7CisgICAgICBWYWxpZGF0ZVN5bWJvbE5hbWUobmFtZS5zdWJzdHIoZG90X3BvcyArIDEpLCBuYW1lLCBwcm90byk7CisgICAgfQorICB9IGVsc2UgeworICAgIFN5bWJvbCBleGlzdGluZ19zeW1ib2wgPSB0YWJsZXNfLT5GaW5kU3ltYm9sKG5hbWUpOworICAgIC8vIEl0J3MgT0sgdG8gcmVkZWZpbmUgYSBwYWNrYWdlLgorICAgIGlmIChleGlzdGluZ19zeW1ib2wudHlwZSAhPSBTeW1ib2w6OlBBQ0tBR0UpIHsKKyAgICAgIC8vIFN5bWJvbCBzZWVtcyB0byBoYXZlIGJlZW4gZGVmaW5lZCBpbiBhIGRpZmZlcmVudCBmaWxlLgorICAgICAgQWRkRXJyb3IobmFtZSwgcHJvdG8sIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6TkFNRSwKKyAgICAgICAgICAgICAgICJcIiIgKyBuYW1lICsgIlwiIGlzIGFscmVhZHkgZGVmaW5lZCAoYXMgc29tZXRoaW5nIG90aGVyIHRoYW4gIgorICAgICAgICAgICAgICAgImEgcGFja2FnZSkgaW4gZmlsZSBcIiIgKyBleGlzdGluZ19zeW1ib2wuR2V0RmlsZSgpLT5uYW1lKCkgKworICAgICAgICAgICAgICAgIlwiLiIpOworICAgIH0KKyAgfQorfQorCit2b2lkIERlc2NyaXB0b3JCdWlsZGVyOjpWYWxpZGF0ZVN5bWJvbE5hbWUoCisgICAgY29uc3Qgc3RyaW5nJiBuYW1lLCBjb25zdCBzdHJpbmcmIGZ1bGxfbmFtZSwgY29uc3QgTWVzc2FnZSYgcHJvdG8pIHsKKyAgaWYgKG5hbWUuZW1wdHkoKSkgeworICAgIEFkZEVycm9yKGZ1bGxfbmFtZSwgcHJvdG8sIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6TkFNRSwKKyAgICAgICAgICAgICAiTWlzc2luZyBuYW1lLiIpOworICB9IGVsc2UgeworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbmFtZS5zaXplKCk7IGkrKykgeworICAgICAgLy8gSSBkb24ndCB0cnVzdCBpc2FsbnVtKCkgZHVlIHRvIGxvY2FsZXMuICA6KAorICAgICAgaWYgKChuYW1lW2ldIDwgJ2EnIHx8ICd6JyA8IG5hbWVbaV0pICYmCisgICAgICAgICAgKG5hbWVbaV0gPCAnQScgfHwgJ1onIDwgbmFtZVtpXSkgJiYKKyAgICAgICAgICAobmFtZVtpXSA8ICcwJyB8fCAnOScgPCBuYW1lW2ldKSAmJgorICAgICAgICAgIChuYW1lW2ldICE9ICdfJykpIHsKKyAgICAgICAgQWRkRXJyb3IoZnVsbF9uYW1lLCBwcm90bywgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpOQU1FLAorICAgICAgICAgICAgICAgICAiXCIiICsgbmFtZSArICJcIiBpcyBub3QgYSB2YWxpZCBpZGVudGlmaWVyLiIpOworICAgICAgfQorICAgIH0KKyAgfQorfQorCitib29sIERlc2NyaXB0b3JCdWlsZGVyOjpWYWxpZGF0ZVF1YWxpZmllZE5hbWUoY29uc3Qgc3RyaW5nJiBuYW1lKSB7CisgIGJvb2wgbGFzdF93YXNfcGVyaW9kID0gZmFsc2U7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBuYW1lLnNpemUoKTsgaSsrKSB7CisgICAgLy8gSSBkb24ndCB0cnVzdCBpc2FsbnVtKCkgZHVlIHRvIGxvY2FsZXMuICA6KAorICAgIGlmICgoJ2EnIDw9IG5hbWVbaV0gJiYgbmFtZVtpXSA8PSAneicpIHx8CisgICAgICAgICgnQScgPD0gbmFtZVtpXSAmJiBuYW1lW2ldIDw9ICdaJykgfHwKKyAgICAgICAgKCcwJyA8PSBuYW1lW2ldICYmIG5hbWVbaV0gPD0gJzknKSB8fAorICAgICAgICAobmFtZVtpXSA9PSAnXycpKSB7CisgICAgICBsYXN0X3dhc19wZXJpb2QgPSBmYWxzZTsKKyAgICB9IGVsc2UgaWYgKG5hbWVbaV0gPT0gJy4nKSB7CisgICAgICBpZiAobGFzdF93YXNfcGVyaW9kKSByZXR1cm4gZmFsc2U7CisgICAgICBsYXN0X3dhc19wZXJpb2QgPSB0cnVlOworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICB9CisKKyAgcmV0dXJuICFuYW1lLmVtcHR5KCkgJiYgIWxhc3Rfd2FzX3BlcmlvZDsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBUaGlzIGdlbmVyaWMgaW1wbGVtZW50YXRpb24gaXMgZ29vZCBmb3IgYWxsIGRlc2NyaXB0b3JzIGV4Y2VwdAorLy8gRmlsZURlc2NyaXB0b3IuCit0ZW1wbGF0ZTxjbGFzcyBEZXNjcmlwdG9yVD4gdm9pZCBEZXNjcmlwdG9yQnVpbGRlcjo6QWxsb2NhdGVPcHRpb25zKAorICAgIGNvbnN0IHR5cGVuYW1lIERlc2NyaXB0b3JUOjpPcHRpb25zVHlwZSYgb3JpZ19vcHRpb25zLAorICAgIERlc2NyaXB0b3JUKiBkZXNjcmlwdG9yKSB7CisgIEFsbG9jYXRlT3B0aW9uc0ltcGwoZGVzY3JpcHRvci0+ZnVsbF9uYW1lKCksIGRlc2NyaXB0b3ItPmZ1bGxfbmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgIG9yaWdfb3B0aW9ucywgZGVzY3JpcHRvcik7Cit9CisKKy8vIFdlIHNwZWNpYWxpemUgZm9yIEZpbGVEZXNjcmlwdG9yLgordm9pZCBEZXNjcmlwdG9yQnVpbGRlcjo6QWxsb2NhdGVPcHRpb25zKGNvbnN0IEZpbGVPcHRpb25zJiBvcmlnX29wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmlsZURlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgLy8gV2UgYWRkIHRoZSBkdW1teSB0b2tlbiBzbyB0aGF0IExvb2t1cFN5bWJvbCBkb2VzIHRoZSByaWdodCB0aGluZy4KKyAgQWxsb2NhdGVPcHRpb25zSW1wbChkZXNjcmlwdG9yLT5wYWNrYWdlKCkgKyAiLmR1bW15IiwgZGVzY3JpcHRvci0+bmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgIG9yaWdfb3B0aW9ucywgZGVzY3JpcHRvcik7Cit9CisKK3RlbXBsYXRlPGNsYXNzIERlc2NyaXB0b3JUPiB2b2lkIERlc2NyaXB0b3JCdWlsZGVyOjpBbGxvY2F0ZU9wdGlvbnNJbXBsKAorICAgIGNvbnN0IHN0cmluZyYgbmFtZV9zY29wZSwKKyAgICBjb25zdCBzdHJpbmcmIGVsZW1lbnRfbmFtZSwKKyAgICBjb25zdCB0eXBlbmFtZSBEZXNjcmlwdG9yVDo6T3B0aW9uc1R5cGUmIG9yaWdfb3B0aW9ucywKKyAgICBEZXNjcmlwdG9yVCogZGVzY3JpcHRvcikgeworICAvLyBXZSBuZWVkIHRvIHVzZSBhIGR1bW15IHBvaW50ZXIgdG8gd29yayBhcm91bmQgYSBidWcgaW4gb2xkZXIgdmVyc2lvbnMgb2YKKyAgLy8gR0NDLiAgT3RoZXJ3aXNlLCB0aGUgZm9sbG93aW5nIHR3byBsaW5lcyBjb3VsZCBiZSByZXBsYWNlZCB3aXRoOgorICAvLyAgIHR5cGVuYW1lIERlc2NyaXB0b3JUOjpPcHRpb25zVHlwZSogb3B0aW9ucyA9CisgIC8vICAgICAgIHRhYmxlc18tPkFsbG9jYXRlTWVzc2FnZTx0eXBlbmFtZSBEZXNjcmlwdG9yVDo6T3B0aW9uc1R5cGU+KCk7CisgIHR5cGVuYW1lIERlc2NyaXB0b3JUOjpPcHRpb25zVHlwZSogY29uc3QgZHVtbXkgPSBOVUxMOworICB0eXBlbmFtZSBEZXNjcmlwdG9yVDo6T3B0aW9uc1R5cGUqIG9wdGlvbnMgPSB0YWJsZXNfLT5BbGxvY2F0ZU1lc3NhZ2UoZHVtbXkpOworICAvLyBBdm9pZCB1c2luZyBNZXJnZUZyb20oKS9Db3B5RnJvbSgpIGluIHRoaXMgY2xhc3MgdG8gbWFrZSBpdCAtZm5vLXJ0dGkKKyAgLy8gZnJpZW5kbHkuIFdpdGhvdXQgUlRUSSwgTWVyZ2VGcm9tKCkgYW5kIENvcHlGcm9tKCkgd2lsbCBmYWxsYmFjayB0byB0aGUKKyAgLy8gcmVmbGVjdGlvbiBiYXNlZCBtZXRob2QsIHdoaWNoIHJlcXVpcmVzIHRoZSBEZXNjcmlwdG9yLiBIb3dldmVyLCB3ZSBhcmUgaW4KKyAgLy8gdGhlIG1pZGRsZSBvZiBidWlsZGluZyB0aGUgZGVzY3JpcHRvcnMsIHRodXMgdGhlIGRlYWRsb2NrLgorICBvcHRpb25zLT5QYXJzZUZyb21TdHJpbmcob3JpZ19vcHRpb25zLlNlcmlhbGl6ZUFzU3RyaW5nKCkpOworICBkZXNjcmlwdG9yLT5vcHRpb25zXyA9IG9wdGlvbnM7CisKKyAgLy8gRG9uJ3QgYWRkIHRvIG9wdGlvbnNfdG9faW50ZXJwcmV0XyB1bmxlc3MgdGhlcmUgd2VyZSB1bmludGVycHJldGVkCisgIC8vIG9wdGlvbnMuICBUaGlzIG5vdCBvbmx5IGF2b2lkcyB1bm5lY2Vzc2FyeSB3b3JrLCBidXQgcHJldmVudHMgYQorICAvLyBib290c3RyYXBwaW5nIHByb2JsZW0gd2hlbiBidWlsZGluZyBkZXNjcmlwdG9ycyBmb3IgZGVzY3JpcHRvci5wcm90by4KKyAgLy8gZGVzY3JpcHRvci5wcm90byBkb2VzIG5vdCBjb250YWluIGFueSB1bmludGVycHJldGVkIG9wdGlvbnMsIGJ1dAorICAvLyBhdHRlbXB0aW5nIHRvIGludGVycHJldCBvcHRpb25zIGFueXdheSB3aWxsIGNhdXNlCisgIC8vIE9wdGlvbnNUeXBlOjpHZXREZXNjcmlwdG9yKCkgdG8gYmUgY2FsbGVkIHdoaWNoIG1heSB0aGVuIGRlYWRsb2NrIHNpbmNlCisgIC8vIHdlJ3JlIHN0aWxsIHRyeWluZyB0byBidWlsZCBpdC4KKyAgaWYgKG9wdGlvbnMtPnVuaW50ZXJwcmV0ZWRfb3B0aW9uX3NpemUoKSA+IDApIHsKKyAgICBvcHRpb25zX3RvX2ludGVycHJldF8ucHVzaF9iYWNrKAorICAgICAgICBPcHRpb25zVG9JbnRlcnByZXQobmFtZV9zY29wZSwgZWxlbWVudF9uYW1lLCAmb3JpZ19vcHRpb25zLCBvcHRpb25zKSk7CisgIH0KK30KKworCisvLyBBIGNvbW1vbiBwYXR0ZXJuOiAgV2Ugd2FudCB0byBjb252ZXJ0IGEgcmVwZWF0ZWQgZmllbGQgaW4gdGhlIGRlc2NyaXB0b3IKKy8vIHRvIGFuIGFycmF5IG9mIHZhbHVlcywgY2FsbGluZyBzb21lIG1ldGhvZCB0byBidWlsZCBlYWNoIHZhbHVlLgorI2RlZmluZSBCVUlMRF9BUlJBWShJTlBVVCwgT1VUUFVULCBOQU1FLCBNRVRIT0QsIFBBUkVOVCkgICAgICAgICAgICAgXAorICBPVVRQVVQtPk5BTUUjI19jb3VudF8gPSBJTlBVVC5OQU1FIyNfc2l6ZSgpOyAgICAgICAgICAgICAgICAgICAgICAgXAorICBBbGxvY2F0ZUFycmF5KElOUFVULk5BTUUjI19zaXplKCksICZPVVRQVVQtPk5BTUUjI3NfKTsgICAgICAgICAgICAgXAorICBmb3IgKGludCBpID0gMDsgaSA8IElOUFVULk5BTUUjI19zaXplKCk7IGkrKykgeyAgICAgICAgICAgICAgICAgICAgXAorICAgIE1FVEhPRChJTlBVVC5OQU1FKGkpLCBQQVJFTlQsIE9VVFBVVC0+TkFNRSMjc18gKyBpKTsgICAgICAgICAgICAgXAorICB9CisKK3ZvaWQgRGVzY3JpcHRvckJ1aWxkZXI6OkFkZFJlY3Vyc2l2ZUltcG9ydEVycm9yKAorICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8mIHByb3RvLCBpbnQgZnJvbV9oZXJlKSB7CisgIHN0cmluZyBlcnJvcl9tZXNzYWdlKCJGaWxlIHJlY3Vyc2l2ZWx5IGltcG9ydHMgaXRzZWxmOiAiKTsKKyAgZm9yIChpbnQgaSA9IGZyb21faGVyZTsgaSA8IHRhYmxlc18tPnBlbmRpbmdfZmlsZXNfLnNpemUoKTsgaSsrKSB7CisgICAgZXJyb3JfbWVzc2FnZS5hcHBlbmQodGFibGVzXy0+cGVuZGluZ19maWxlc19baV0pOworICAgIGVycm9yX21lc3NhZ2UuYXBwZW5kKCIgLT4gIik7CisgIH0KKyAgZXJyb3JfbWVzc2FnZS5hcHBlbmQocHJvdG8ubmFtZSgpKTsKKworICBBZGRFcnJvcihwcm90by5uYW1lKCksIHByb3RvLCBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok9USEVSLAorICAgICAgICAgICBlcnJvcl9tZXNzYWdlKTsKK30KKwordm9pZCBEZXNjcmlwdG9yQnVpbGRlcjo6QWRkVHdpY2VMaXN0ZWRFcnJvcihjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvJiBwcm90bywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGluZGV4KSB7CisgIEFkZEVycm9yKHByb3RvLm5hbWUoKSwgcHJvdG8sIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6T1RIRVIsCisgICAgICAgICAgICJJbXBvcnQgXCIiICsgcHJvdG8uZGVwZW5kZW5jeShpbmRleCkgKyAiXCIgd2FzIGxpc3RlZCB0d2ljZS4iKTsKK30KKwordm9pZCBEZXNjcmlwdG9yQnVpbGRlcjo6QWRkSW1wb3J0RXJyb3IoY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byYgcHJvdG8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXgpIHsKKyAgc3RyaW5nIG1lc3NhZ2U7CisgIGlmIChwb29sXy0+ZmFsbGJhY2tfZGF0YWJhc2VfID09IE5VTEwpIHsKKyAgICBtZXNzYWdlID0gIkltcG9ydCBcIiIgKyBwcm90by5kZXBlbmRlbmN5KGluZGV4KSArCisgICAgICAgICAgICAgICJcIiBoYXMgbm90IGJlZW4gbG9hZGVkLiI7CisgIH0gZWxzZSB7CisgICAgbWVzc2FnZSA9ICJJbXBvcnQgXCIiICsgcHJvdG8uZGVwZW5kZW5jeShpbmRleCkgKworICAgICAgICAgICAgICAiXCIgd2FzIG5vdCBmb3VuZCBvciBoYWQgZXJyb3JzLiI7CisgIH0KKyAgQWRkRXJyb3IocHJvdG8ubmFtZSgpLCBwcm90bywgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpPVEhFUiwgbWVzc2FnZSk7Cit9CisKK3N0YXRpYyBib29sIEV4aXN0aW5nRmlsZU1hdGNoZXNQcm90byhjb25zdCBGaWxlRGVzY3JpcHRvciogZXhpc3RpbmdfZmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvJiBwcm90bykgeworICBGaWxlRGVzY3JpcHRvclByb3RvIGV4aXN0aW5nX3Byb3RvOworICBleGlzdGluZ19maWxlLT5Db3B5VG8oJmV4aXN0aW5nX3Byb3RvKTsKKyAgLy8gVE9ETyhsaXVqaXNpKTogUmVtb3ZlIGl0IHdoZW4gQ29weVRvIHN1cHBvcnRzIGNvcHlpbmcgc3ludGF4IHBhcmFtcyB3aGVuCisgIC8vIHN5bnRheD0icHJvdG8yIi4KKyAgaWYgKGV4aXN0aW5nX2ZpbGUtPnN5bnRheCgpID09IEZpbGVEZXNjcmlwdG9yOjpTWU5UQVhfUFJPVE8yICYmCisgICAgICBwcm90by5oYXNfc3ludGF4KCkpIHsKKyAgICBleGlzdGluZ19wcm90by5zZXRfc3ludGF4KAorICAgICAgICBleGlzdGluZ19maWxlLT5TeW50YXhOYW1lKGV4aXN0aW5nX2ZpbGUtPnN5bnRheCgpKSk7CisgIH0KKworICByZXR1cm4gZXhpc3RpbmdfcHJvdG8uU2VyaWFsaXplQXNTdHJpbmcoKSA9PSBwcm90by5TZXJpYWxpemVBc1N0cmluZygpOworfQorCitjb25zdCBGaWxlRGVzY3JpcHRvciogRGVzY3JpcHRvckJ1aWxkZXI6OkJ1aWxkRmlsZSgKKyAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvJiBwcm90bykgeworICBmaWxlbmFtZV8gPSBwcm90by5uYW1lKCk7CisKKyAgLy8gQ2hlY2sgaWYgdGhlIGZpbGUgYWxyZWFkeSBleGlzdHMgYW5kIGlzIGlkZW50aWNhbCB0byB0aGUgb25lIGJlaW5nIGJ1aWx0LgorICAvLyBOb3RlOiAgVGhpcyBvbmx5IHdvcmtzIGlmIHRoZSBpbnB1dCBpcyBjYW5vbmljYWwgLS0gdGhhdCBpcywgaXQKKyAgLy8gICBmdWxseS1xdWFsaWZpZXMgYWxsIHR5cGUgbmFtZXMsIGhhcyBubyBVbmludGVycHJldGVkT3B0aW9ucywgZXRjLgorICAvLyAgIFRoaXMgaXMgZmluZSwgYmVjYXVzZSB0aGlzIGlkZW1wb3RlbmN5ICJmZWF0dXJlIiByZWFsbHkgb25seSBleGlzdHMgdG8KKyAgLy8gICBhY2NvbW1vZGF0ZSBvbmUgaGFjayBpbiB0aGUgcHJvdG8xLT5wcm90bzIgbWlncmF0aW9uIGxheWVyLgorICBjb25zdCBGaWxlRGVzY3JpcHRvciogZXhpc3RpbmdfZmlsZSA9IHRhYmxlc18tPkZpbmRGaWxlKGZpbGVuYW1lXyk7CisgIGlmIChleGlzdGluZ19maWxlICE9IE5VTEwpIHsKKyAgICAvLyBGaWxlIGFscmVhZHkgaW4gcG9vbC4gIENvbXBhcmUgdGhlIGV4aXN0aW5nIG9uZSB0byB0aGUgaW5wdXQuCisgICAgaWYgKEV4aXN0aW5nRmlsZU1hdGNoZXNQcm90byhleGlzdGluZ19maWxlLCBwcm90bykpIHsKKyAgICAgIC8vIFRoZXkncmUgaWRlbnRpY2FsLiAgUmV0dXJuIHRoZSBleGlzdGluZyBkZXNjcmlwdG9yLgorICAgICAgcmV0dXJuIGV4aXN0aW5nX2ZpbGU7CisgICAgfQorCisgICAgLy8gTm90IGEgbWF0Y2guICBUaGUgZXJyb3Igd2lsbCBiZSBkZXRlY3RlZCBhbmQgaGFuZGxlZCBsYXRlci4KKyAgfQorCisgIC8vIENoZWNrIHRvIHNlZSBpZiB0aGlzIGZpbGUgaXMgYWxyZWFkeSBvbiB0aGUgcGVuZGluZyBmaWxlcyBsaXN0LgorICAvLyBUT0RPKGtlbnRvbik6ICBBbGxvdyByZWN1cnNpdmUgaW1wb3J0cz8gIEl0IG1heSBub3Qgd29yayB3aXRoIHNvbWUKKyAgLy8gICAobW9zdD8pIHByb2dyYW1taW5nIGxhbmd1YWdlcy4gIEUuZy4sIGluIEMrKywgYSBmb3J3YXJkIGRlY2xhcmF0aW9uCisgIC8vICAgb2YgYSB0eXBlIGlzIG5vdCBzdWZmaWNpZW50IHRvIGFsbG93IGl0IHRvIGJlIHVzZWQgZXZlbiBpbiBhCisgIC8vICAgZ2VuZXJhdGVkIGhlYWRlciBmaWxlIGR1ZSB0byBpbmxpbmluZy4gIFRoaXMgY291bGQgcGVyaGFwcyBiZQorICAvLyAgIHdvcmtlZCBhcm91bmQgdXNpbmcgdHJpY2tzIGludm9sdmluZyBpbnNlcnRpbmcgI2luY2x1ZGUgc3RhdGVtZW50cworICAvLyAgIG1pZC1maWxlLCBidXQgdGhhdCdzIHByZXR0eSB1Z2x5LCBhbmQgSSdtIHByZXR0eSBzdXJlIHRoZXJlIGFyZQorICAvLyAgIHNvbWUgbGFuZ3VhZ2VzIG91dCB0aGVyZSB0aGF0IGRvIG5vdCBhbGxvdyByZWN1cnNpdmUgZGVwZW5kZW5jaWVzCisgIC8vICAgYXQgYWxsLgorICBmb3IgKGludCBpID0gMDsgaSA8IHRhYmxlc18tPnBlbmRpbmdfZmlsZXNfLnNpemUoKTsgaSsrKSB7CisgICAgaWYgKHRhYmxlc18tPnBlbmRpbmdfZmlsZXNfW2ldID09IHByb3RvLm5hbWUoKSkgeworICAgICAgQWRkUmVjdXJzaXZlSW1wb3J0RXJyb3IocHJvdG8sIGkpOworICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICB9CisKKyAgLy8gSWYgd2UgaGF2ZSBhIGZhbGxiYWNrX2RhdGFiYXNlXywgYXR0ZW1wdCB0byBsb2FkIGFsbCBkZXBlbmRlbmNpZXMgbm93LAorICAvLyBiZWZvcmUgY2hlY2twb2ludGluZyB0YWJsZXNfLiAgVGhpcyBhdm9pZHMgY29uZnVzaW9uIHdpdGggcmVjdXJzaXZlCisgIC8vIGNoZWNrcG9pbnRzLgorICBpZiAocG9vbF8tPmZhbGxiYWNrX2RhdGFiYXNlXyAhPSBOVUxMKSB7CisgICAgdGFibGVzXy0+cGVuZGluZ19maWxlc18ucHVzaF9iYWNrKHByb3RvLm5hbWUoKSk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwcm90by5kZXBlbmRlbmN5X3NpemUoKTsgaSsrKSB7CisgICAgICBpZiAodGFibGVzXy0+RmluZEZpbGUocHJvdG8uZGVwZW5kZW5jeShpKSkgPT0gTlVMTCAmJgorICAgICAgICAgIChwb29sXy0+dW5kZXJsYXlfID09IE5VTEwgfHwKKyAgICAgICAgICAgcG9vbF8tPnVuZGVybGF5Xy0+RmluZEZpbGVCeU5hbWUocHJvdG8uZGVwZW5kZW5jeShpKSkgPT0gTlVMTCkpIHsKKyAgICAgICAgLy8gV2UgZG9uJ3QgY2FyZSB3aGF0IHRoaXMgcmV0dXJucyBzaW5jZSB3ZSdsbCBmaW5kIG91dCBiZWxvdyBhbnl3YXkuCisgICAgICAgIHBvb2xfLT5UcnlGaW5kRmlsZUluRmFsbGJhY2tEYXRhYmFzZShwcm90by5kZXBlbmRlbmN5KGkpKTsKKyAgICAgIH0KKyAgICB9CisgICAgdGFibGVzXy0+cGVuZGluZ19maWxlc18ucG9wX2JhY2soKTsKKyAgfQorCisgIC8vIENoZWNrcG9pbnQgdGhlIHRhYmxlcyBzbyB0aGF0IHdlIGNhbiByb2xsIGJhY2sgaWYgc29tZXRoaW5nIGdvZXMgd3JvbmcuCisgIHRhYmxlc18tPkFkZENoZWNrcG9pbnQoKTsKKworICBGaWxlRGVzY3JpcHRvciogcmVzdWx0ID0gdGFibGVzXy0+QWxsb2NhdGU8RmlsZURlc2NyaXB0b3I+KCk7CisgIGZpbGVfID0gcmVzdWx0OworCisgIHJlc3VsdC0+aXNfcGxhY2Vob2xkZXJfID0gZmFsc2U7CisgIGlmIChwcm90by5oYXNfc291cmNlX2NvZGVfaW5mbygpKSB7CisgICAgU291cmNlQ29kZUluZm8gKmluZm8gPSB0YWJsZXNfLT5BbGxvY2F0ZU1lc3NhZ2U8U291cmNlQ29kZUluZm8+KCk7CisgICAgaW5mby0+Q29weUZyb20ocHJvdG8uc291cmNlX2NvZGVfaW5mbygpKTsKKyAgICByZXN1bHQtPnNvdXJjZV9jb2RlX2luZm9fID0gaW5mbzsKKyAgfSBlbHNlIHsKKyAgICByZXN1bHQtPnNvdXJjZV9jb2RlX2luZm9fID0gJlNvdXJjZUNvZGVJbmZvOjpkZWZhdWx0X2luc3RhbmNlKCk7CisgIH0KKworICBmaWxlX3RhYmxlc18gPSB0YWJsZXNfLT5BbGxvY2F0ZUZpbGVUYWJsZXMoKTsKKyAgZmlsZV8tPnRhYmxlc18gPSBmaWxlX3RhYmxlc187CisKKyAgaWYgKCFwcm90by5oYXNfbmFtZSgpKSB7CisgICAgQWRkRXJyb3IoIiIsIHByb3RvLCBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok9USEVSLAorICAgICAgICAgICAgICJNaXNzaW5nIGZpZWxkOiBGaWxlRGVzY3JpcHRvclByb3RvLm5hbWUuIik7CisgIH0KKworICAvLyBUT0RPKGxpdWppc2kpOiBSZXBvcnQgZXJyb3Igd2hlbiB0aGUgc3ludGF4IGlzIGVtcHR5IGFmdGVyIGFsbCB0aGUgcHJvdG9zCisgIC8vIGhhdmUgYWRkZWQgdGhlIHN5bnRheCBzdGF0ZW1lbnQuCisgIGlmIChwcm90by5zeW50YXgoKS5lbXB0eSgpIHx8IHByb3RvLnN5bnRheCgpID09ICJwcm90bzIiKSB7CisgICAgZmlsZV8tPnN5bnRheF8gPSBGaWxlRGVzY3JpcHRvcjo6U1lOVEFYX1BST1RPMjsKKyAgfSBlbHNlIGlmIChwcm90by5zeW50YXgoKSA9PSAicHJvdG8zIikgeworICAgIGZpbGVfLT5zeW50YXhfID0gRmlsZURlc2NyaXB0b3I6OlNZTlRBWF9QUk9UTzM7CisgIH0gZWxzZSB7CisgICAgZmlsZV8tPnN5bnRheF8gPSBGaWxlRGVzY3JpcHRvcjo6U1lOVEFYX1VOS05PV047CisgICAgQWRkRXJyb3IocHJvdG8ubmFtZSgpLCBwcm90bywgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpPVEhFUiwKKyAgICAgICAgICAgICAiVW5yZWNvZ25pemVkIHN5bnRheDogIiArIHByb3RvLnN5bnRheCgpKTsKKyAgfQorCisgIHJlc3VsdC0+bmFtZV8gPSB0YWJsZXNfLT5BbGxvY2F0ZVN0cmluZyhwcm90by5uYW1lKCkpOworICBpZiAocHJvdG8uaGFzX3BhY2thZ2UoKSkgeworICAgIHJlc3VsdC0+cGFja2FnZV8gPSB0YWJsZXNfLT5BbGxvY2F0ZVN0cmluZyhwcm90by5wYWNrYWdlKCkpOworICB9IGVsc2UgeworICAgIC8vIFdlIGNhbm5vdCByZWx5IG9uIHByb3RvLnBhY2thZ2UoKSByZXR1cm5pbmcgYSB2YWxpZCBzdHJpbmcgaWYKKyAgICAvLyBwcm90by5oYXNfcGFja2FnZSgpIGlzIGZhbHNlLCBiZWNhdXNlIHdlIG1pZ2h0IGJlIHJ1bm5pbmcgYXQgc3RhdGljCisgICAgLy8gaW5pdGlhbGl6YXRpb24gdGltZSwgaW4gd2hpY2ggY2FzZSBkZWZhdWx0IHZhbHVlcyBoYXZlIG5vdCB5ZXQgYmVlbgorICAgIC8vIGluaXRpYWxpemVkLgorICAgIHJlc3VsdC0+cGFja2FnZV8gPSB0YWJsZXNfLT5BbGxvY2F0ZVN0cmluZygiIik7CisgIH0KKyAgcmVzdWx0LT5wb29sXyA9IHBvb2xfOworCisgIC8vIEFkZCB0byB0YWJsZXMuCisgIGlmICghdGFibGVzXy0+QWRkRmlsZShyZXN1bHQpKSB7CisgICAgQWRkRXJyb3IocHJvdG8ubmFtZSgpLCBwcm90bywgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpPVEhFUiwKKyAgICAgICAgICAgICAiQSBmaWxlIHdpdGggdGhpcyBuYW1lIGlzIGFscmVhZHkgaW4gdGhlIHBvb2wuIik7CisgICAgLy8gQmFpbCBvdXQgZWFybHkgc28gdGhhdCBpZiB0aGlzIGlzIGFjdHVhbGx5IHRoZSBleGFjdCBzYW1lIGZpbGUsIHdlCisgICAgLy8gZG9uJ3QgZW5kIHVwIHJlcG9ydGluZyB0aGF0IGV2ZXJ5IHNpbmdsZSBzeW1ib2wgaXMgYWxyZWFkeSBkZWZpbmVkLgorICAgIHRhYmxlc18tPlJvbGxiYWNrVG9MYXN0Q2hlY2twb2ludCgpOworICAgIHJldHVybiBOVUxMOworICB9CisgIGlmICghcmVzdWx0LT5wYWNrYWdlKCkuZW1wdHkoKSkgeworICAgIEFkZFBhY2thZ2UocmVzdWx0LT5wYWNrYWdlKCksIHByb3RvLCByZXN1bHQpOworICB9CisKKyAgLy8gTWFrZSBzdXJlIGFsbCBkZXBlbmRlbmNpZXMgYXJlIGxvYWRlZC4KKyAgc2V0PHN0cmluZz4gc2Vlbl9kZXBlbmRlbmNpZXM7CisgIHJlc3VsdC0+ZGVwZW5kZW5jeV9jb3VudF8gPSBwcm90by5kZXBlbmRlbmN5X3NpemUoKTsKKyAgcmVzdWx0LT5kZXBlbmRlbmNpZXNfID0KKyAgICB0YWJsZXNfLT5BbGxvY2F0ZUFycmF5PGNvbnN0IEZpbGVEZXNjcmlwdG9yKj4ocHJvdG8uZGVwZW5kZW5jeV9zaXplKCkpOworICB1bnVzZWRfZGVwZW5kZW5jeV8uY2xlYXIoKTsKKyAgc2V0PGludD4gd2Vha19kZXBzOworICBmb3IgKGludCBpID0gMDsgaSA8IHByb3RvLndlYWtfZGVwZW5kZW5jeV9zaXplKCk7ICsraSkgeworICAgIHdlYWtfZGVwcy5pbnNlcnQocHJvdG8ud2Vha19kZXBlbmRlbmN5KGkpKTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IHByb3RvLmRlcGVuZGVuY3lfc2l6ZSgpOyBpKyspIHsKKyAgICBpZiAoIXNlZW5fZGVwZW5kZW5jaWVzLmluc2VydChwcm90by5kZXBlbmRlbmN5KGkpKS5zZWNvbmQpIHsKKyAgICAgIEFkZFR3aWNlTGlzdGVkRXJyb3IocHJvdG8sIGkpOworICAgIH0KKworICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBkZXBlbmRlbmN5ID0gdGFibGVzXy0+RmluZEZpbGUocHJvdG8uZGVwZW5kZW5jeShpKSk7CisgICAgaWYgKGRlcGVuZGVuY3kgPT0gTlVMTCAmJiBwb29sXy0+dW5kZXJsYXlfICE9IE5VTEwpIHsKKyAgICAgIGRlcGVuZGVuY3kgPSBwb29sXy0+dW5kZXJsYXlfLT5GaW5kRmlsZUJ5TmFtZShwcm90by5kZXBlbmRlbmN5KGkpKTsKKyAgICB9CisKKyAgICBpZiAoZGVwZW5kZW5jeSA9PSBOVUxMKSB7CisgICAgICBpZiAocG9vbF8tPmFsbG93X3Vua25vd25fIHx8CisgICAgICAgICAgKCFwb29sXy0+ZW5mb3JjZV93ZWFrXyAmJiB3ZWFrX2RlcHMuZmluZChpKSAhPSB3ZWFrX2RlcHMuZW5kKCkpKSB7CisgICAgICAgIGRlcGVuZGVuY3kgPSBOZXdQbGFjZWhvbGRlckZpbGUocHJvdG8uZGVwZW5kZW5jeShpKSk7CisgICAgICB9IGVsc2UgeworICAgICAgICBBZGRJbXBvcnRFcnJvcihwcm90bywgaSk7CisgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgIC8vIEFkZCB0byB1bnVzZWRfZGVwZW5kZW5jeV8gdG8gdHJhY2sgdW51c2VkIGltcG9ydGVkIGZpbGVzLgorICAgICAgLy8gTm90ZTogZG8gbm90IHRyYWNrIHVudXNlZCBpbXBvcnRlZCBmaWxlcyBmb3IgcHVibGljIGltcG9ydC4KKyAgICAgIGlmIChwb29sXy0+ZW5mb3JjZV9kZXBlbmRlbmNpZXNfICYmCisgICAgICAgICAgKHBvb2xfLT51bnVzZWRfaW1wb3J0X3RyYWNrX2ZpbGVzXy5maW5kKHByb3RvLm5hbWUoKSkgIT0KKyAgICAgICAgICAgcG9vbF8tPnVudXNlZF9pbXBvcnRfdHJhY2tfZmlsZXNfLmVuZCgpKSAmJgorICAgICAgICAgIChkZXBlbmRlbmN5LT5wdWJsaWNfZGVwZW5kZW5jeV9jb3VudCgpID09IDApKSB7CisgICAgICAgIHVudXNlZF9kZXBlbmRlbmN5Xy5pbnNlcnQoZGVwZW5kZW5jeSk7CisgICAgICB9CisgICAgfQorCisgICAgcmVzdWx0LT5kZXBlbmRlbmNpZXNfW2ldID0gZGVwZW5kZW5jeTsKKyAgfQorCisgIC8vIENoZWNrIHB1YmxpYyBkZXBlbmRlbmNpZXMuCisgIGludCBwdWJsaWNfZGVwZW5kZW5jeV9jb3VudCA9IDA7CisgIHJlc3VsdC0+cHVibGljX2RlcGVuZGVuY2llc18gPSB0YWJsZXNfLT5BbGxvY2F0ZUFycmF5PGludD4oCisgICAgICBwcm90by5wdWJsaWNfZGVwZW5kZW5jeV9zaXplKCkpOworICBmb3IgKGludCBpID0gMDsgaSA8IHByb3RvLnB1YmxpY19kZXBlbmRlbmN5X3NpemUoKTsgaSsrKSB7CisgICAgLy8gT25seSBwdXQgdmFsaWQgcHVibGljIGRlcGVuZGVuY3kgaW5kZXhlcy4KKyAgICBpbnQgaW5kZXggPSBwcm90by5wdWJsaWNfZGVwZW5kZW5jeShpKTsKKyAgICBpZiAoaW5kZXggPj0gMCAmJiBpbmRleCA8IHByb3RvLmRlcGVuZGVuY3lfc2l6ZSgpKSB7CisgICAgICByZXN1bHQtPnB1YmxpY19kZXBlbmRlbmNpZXNfW3B1YmxpY19kZXBlbmRlbmN5X2NvdW50KytdID0gaW5kZXg7CisgICAgICAvLyBEbyBub3QgdHJhY2sgdW51c2VkIGltcG9ydGVkIGZpbGVzIGZvciBwdWJsaWMgaW1wb3J0LgorICAgICAgdW51c2VkX2RlcGVuZGVuY3lfLmVyYXNlKHJlc3VsdC0+ZGVwZW5kZW5jeShpbmRleCkpOworICAgIH0gZWxzZSB7CisgICAgICBBZGRFcnJvcihwcm90by5uYW1lKCksIHByb3RvLAorICAgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpPVEhFUiwKKyAgICAgICAgICAgICAgICJJbnZhbGlkIHB1YmxpYyBkZXBlbmRlbmN5IGluZGV4LiIpOworICAgIH0KKyAgfQorICByZXN1bHQtPnB1YmxpY19kZXBlbmRlbmN5X2NvdW50XyA9IHB1YmxpY19kZXBlbmRlbmN5X2NvdW50OworCisgIC8vIEJ1aWxkIGRlcGVuZGVuY3kgc2V0CisgIGRlcGVuZGVuY2llc18uY2xlYXIoKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXN1bHQtPmRlcGVuZGVuY3lfY291bnQoKTsgaSsrKSB7CisgICAgUmVjb3JkUHVibGljRGVwZW5kZW5jaWVzKHJlc3VsdC0+ZGVwZW5kZW5jeShpKSk7CisgIH0KKworICAvLyBDaGVjayB3ZWFrIGRlcGVuZGVuY2llcy4KKyAgaW50IHdlYWtfZGVwZW5kZW5jeV9jb3VudCA9IDA7CisgIHJlc3VsdC0+d2Vha19kZXBlbmRlbmNpZXNfID0gdGFibGVzXy0+QWxsb2NhdGVBcnJheTxpbnQ+KAorICAgICAgcHJvdG8ud2Vha19kZXBlbmRlbmN5X3NpemUoKSk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgcHJvdG8ud2Vha19kZXBlbmRlbmN5X3NpemUoKTsgaSsrKSB7CisgICAgaW50IGluZGV4ID0gcHJvdG8ud2Vha19kZXBlbmRlbmN5KGkpOworICAgIGlmIChpbmRleCA+PSAwICYmIGluZGV4IDwgcHJvdG8uZGVwZW5kZW5jeV9zaXplKCkpIHsKKyAgICAgIHJlc3VsdC0+d2Vha19kZXBlbmRlbmNpZXNfW3dlYWtfZGVwZW5kZW5jeV9jb3VudCsrXSA9IGluZGV4OworICAgIH0gZWxzZSB7CisgICAgICBBZGRFcnJvcihwcm90by5uYW1lKCksIHByb3RvLAorICAgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpPVEhFUiwKKyAgICAgICAgICAgICAgICJJbnZhbGlkIHdlYWsgZGVwZW5kZW5jeSBpbmRleC4iKTsKKyAgICB9CisgIH0KKyAgcmVzdWx0LT53ZWFrX2RlcGVuZGVuY3lfY291bnRfID0gd2Vha19kZXBlbmRlbmN5X2NvdW50OworCisgIC8vIENvbnZlcnQgY2hpbGRyZW4uCisgIEJVSUxEX0FSUkFZKHByb3RvLCByZXN1bHQsIG1lc3NhZ2VfdHlwZSwgQnVpbGRNZXNzYWdlICAsIE5VTEwpOworICBCVUlMRF9BUlJBWShwcm90bywgcmVzdWx0LCBlbnVtX3R5cGUgICAsIEJ1aWxkRW51bSAgICAgLCBOVUxMKTsKKyAgQlVJTERfQVJSQVkocHJvdG8sIHJlc3VsdCwgc2VydmljZSAgICAgLCBCdWlsZFNlcnZpY2UgICwgTlVMTCk7CisgIEJVSUxEX0FSUkFZKHByb3RvLCByZXN1bHQsIGV4dGVuc2lvbiAgICwgQnVpbGRFeHRlbnNpb24sIE5VTEwpOworCisgIC8vIENvcHkgb3B0aW9ucy4KKyAgaWYgKCFwcm90by5oYXNfb3B0aW9ucygpKSB7CisgICAgcmVzdWx0LT5vcHRpb25zXyA9IE5VTEw7ICAvLyBXaWxsIHNldCB0byBkZWZhdWx0X2luc3RhbmNlIGxhdGVyLgorICB9IGVsc2UgeworICAgIEFsbG9jYXRlT3B0aW9ucyhwcm90by5vcHRpb25zKCksIHJlc3VsdCk7CisgIH0KKworICAvLyBOb3RlIHRoYXQgdGhlIGZvbGxvd2luZyBzdGVwcyBtdXN0IG9jY3VyIGluIGV4YWN0bHkgdGhlIHNwZWNpZmllZCBvcmRlci4KKworICAvLyBDcm9zcy1saW5rLgorICBDcm9zc0xpbmtGaWxlKHJlc3VsdCwgcHJvdG8pOworCisgIC8vIEludGVycHJldCBhbnkgcmVtYWluaW5nIHVuaW50ZXJwcmV0ZWQgb3B0aW9ucyBnYXRoZXJlZCBpbnRvCisgIC8vIG9wdGlvbnNfdG9faW50ZXJwcmV0XyBkdXJpbmcgZGVzY3JpcHRvciBidWlsZGluZy4gIENyb3NzLWxpbmtpbmcgaGFzIG1hZGUKKyAgLy8gZXh0ZW5zaW9uIG9wdGlvbnMga25vd24sIHNvIGFsbCBpbnRlcnByZXRhdGlvbnMgc2hvdWxkIG5vdyBzdWNjZWVkLgorICBpZiAoIWhhZF9lcnJvcnNfKSB7CisgICAgT3B0aW9uSW50ZXJwcmV0ZXIgb3B0aW9uX2ludGVycHJldGVyKHRoaXMpOworICAgIGZvciAodmVjdG9yPE9wdGlvbnNUb0ludGVycHJldD46Oml0ZXJhdG9yIGl0ZXIgPQorICAgICAgICAgICAgIG9wdGlvbnNfdG9faW50ZXJwcmV0Xy5iZWdpbigpOworICAgICAgICAgaXRlciAhPSBvcHRpb25zX3RvX2ludGVycHJldF8uZW5kKCk7ICsraXRlcikgeworICAgICAgb3B0aW9uX2ludGVycHJldGVyLkludGVycHJldE9wdGlvbnMoJigqaXRlcikpOworICAgIH0KKyAgICBvcHRpb25zX3RvX2ludGVycHJldF8uY2xlYXIoKTsKKyAgfQorCisgIC8vIFZhbGlkYXRlIG9wdGlvbnMuCisgIGlmICghaGFkX2Vycm9yc18pIHsKKyAgICBWYWxpZGF0ZUZpbGVPcHRpb25zKHJlc3VsdCwgcHJvdG8pOworICB9CisKKyAgLy8gQWRkaXRpb25hbCBuYW1pbmcgY29uZmxpY3QgY2hlY2sgZm9yIG1hcCBlbnRyeSB0eXBlcy4gT25seSBuZWVkIHRvIGNoZWNrCisgIC8vIHRoaXMgaWYgdGhlcmUgYXJlIGFscmVhZHkgZXJyb3JzLgorICBpZiAoaGFkX2Vycm9yc18pIHsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHByb3RvLm1lc3NhZ2VfdHlwZV9zaXplKCk7ICsraSkgeworICAgICAgRGV0ZWN0TWFwQ29uZmxpY3RzKHJlc3VsdC0+bWVzc2FnZV90eXBlKGkpLCBwcm90by5tZXNzYWdlX3R5cGUoaSkpOworICAgIH0KKyAgfQorCisKKyAgaWYgKCF1bnVzZWRfZGVwZW5kZW5jeV8uZW1wdHkoKSkgeworICAgIExvZ1VudXNlZERlcGVuZGVuY3kocHJvdG8sIHJlc3VsdCk7CisgIH0KKworICBpZiAoaGFkX2Vycm9yc18pIHsKKyAgICB0YWJsZXNfLT5Sb2xsYmFja1RvTGFzdENoZWNrcG9pbnQoKTsKKyAgICByZXR1cm4gTlVMTDsKKyAgfSBlbHNlIHsKKyAgICB0YWJsZXNfLT5DbGVhckxhc3RDaGVja3BvaW50KCk7CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorfQorCit2b2lkIERlc2NyaXB0b3JCdWlsZGVyOjpCdWlsZE1lc3NhZ2UoY29uc3QgRGVzY3JpcHRvclByb3RvJiBwcm90bywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEZXNjcmlwdG9yKiBwYXJlbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVzY3JpcHRvciogcmVzdWx0KSB7CisgIGNvbnN0IHN0cmluZyYgc2NvcGUgPSAocGFyZW50ID09IE5VTEwpID8KKyAgICBmaWxlXy0+cGFja2FnZSgpIDogcGFyZW50LT5mdWxsX25hbWUoKTsKKyAgc3RyaW5nKiBmdWxsX25hbWUgPSB0YWJsZXNfLT5BbGxvY2F0ZVN0cmluZyhzY29wZSk7CisgIGlmICghZnVsbF9uYW1lLT5lbXB0eSgpKSBmdWxsX25hbWUtPmFwcGVuZCgxLCAnLicpOworICBmdWxsX25hbWUtPmFwcGVuZChwcm90by5uYW1lKCkpOworCisgIFZhbGlkYXRlU3ltYm9sTmFtZShwcm90by5uYW1lKCksICpmdWxsX25hbWUsIHByb3RvKTsKKworICByZXN1bHQtPm5hbWVfICAgICAgICAgICAgPSB0YWJsZXNfLT5BbGxvY2F0ZVN0cmluZyhwcm90by5uYW1lKCkpOworICByZXN1bHQtPmZ1bGxfbmFtZV8gICAgICAgPSBmdWxsX25hbWU7CisgIHJlc3VsdC0+ZmlsZV8gICAgICAgICAgICA9IGZpbGVfOworICByZXN1bHQtPmNvbnRhaW5pbmdfdHlwZV8gPSBwYXJlbnQ7CisgIHJlc3VsdC0+aXNfcGxhY2Vob2xkZXJfICA9IGZhbHNlOworICByZXN1bHQtPmlzX3VucXVhbGlmaWVkX3BsYWNlaG9sZGVyXyA9IGZhbHNlOworCisgIC8vIEJ1aWxkIG9uZW9mcyBmaXJzdCBzbyB0aGF0IGZpZWxkcyBhbmQgZXh0ZW5zaW9uIHJhbmdlcyBjYW4gcmVmZXIgdG8gdGhlbS4KKyAgQlVJTERfQVJSQVkocHJvdG8sIHJlc3VsdCwgb25lb2ZfZGVjbCAgICAgLCBCdWlsZE9uZW9mICAgICAgICAgLCByZXN1bHQpOworICBCVUlMRF9BUlJBWShwcm90bywgcmVzdWx0LCBmaWVsZCAgICAgICAgICAsIEJ1aWxkRmllbGQgICAgICAgICAsIHJlc3VsdCk7CisgIEJVSUxEX0FSUkFZKHByb3RvLCByZXN1bHQsIG5lc3RlZF90eXBlICAgICwgQnVpbGRNZXNzYWdlICAgICAgICwgcmVzdWx0KTsKKyAgQlVJTERfQVJSQVkocHJvdG8sIHJlc3VsdCwgZW51bV90eXBlICAgICAgLCBCdWlsZEVudW0gICAgICAgICAgLCByZXN1bHQpOworICBCVUlMRF9BUlJBWShwcm90bywgcmVzdWx0LCBleHRlbnNpb25fcmFuZ2UsIEJ1aWxkRXh0ZW5zaW9uUmFuZ2UsIHJlc3VsdCk7CisgIEJVSUxEX0FSUkFZKHByb3RvLCByZXN1bHQsIGV4dGVuc2lvbiAgICAgICwgQnVpbGRFeHRlbnNpb24gICAgICwgcmVzdWx0KTsKKyAgQlVJTERfQVJSQVkocHJvdG8sIHJlc3VsdCwgcmVzZXJ2ZWRfcmFuZ2UgLCBCdWlsZFJlc2VydmVkUmFuZ2UgLCByZXN1bHQpOworCisgIC8vIENvcHkgcmVzZXJ2ZWQgbmFtZXMuCisgIGludCByZXNlcnZlZF9uYW1lX2NvdW50ID0gcHJvdG8ucmVzZXJ2ZWRfbmFtZV9zaXplKCk7CisgIHJlc3VsdC0+cmVzZXJ2ZWRfbmFtZV9jb3VudF8gPSByZXNlcnZlZF9uYW1lX2NvdW50OworICByZXN1bHQtPnJlc2VydmVkX25hbWVzXyA9CisgICAgICB0YWJsZXNfLT5BbGxvY2F0ZUFycmF5PGNvbnN0IHN0cmluZyo+KHJlc2VydmVkX25hbWVfY291bnQpOworICBmb3IgKGludCBpID0gMDsgaSA8IHJlc2VydmVkX25hbWVfY291bnQ7ICsraSkgeworICAgIHJlc3VsdC0+cmVzZXJ2ZWRfbmFtZXNfW2ldID0KKyAgICAgICAgdGFibGVzXy0+QWxsb2NhdGVTdHJpbmcocHJvdG8ucmVzZXJ2ZWRfbmFtZShpKSk7CisgIH0KKworICAvLyBDb3B5IG9wdGlvbnMuCisgIGlmICghcHJvdG8uaGFzX29wdGlvbnMoKSkgeworICAgIHJlc3VsdC0+b3B0aW9uc18gPSBOVUxMOyAgLy8gV2lsbCBzZXQgdG8gZGVmYXVsdF9pbnN0YW5jZSBsYXRlci4KKyAgfSBlbHNlIHsKKyAgICBBbGxvY2F0ZU9wdGlvbnMocHJvdG8ub3B0aW9ucygpLCByZXN1bHQpOworICB9CisKKyAgQWRkU3ltYm9sKHJlc3VsdC0+ZnVsbF9uYW1lKCksIHBhcmVudCwgcmVzdWx0LT5uYW1lKCksCisgICAgICAgICAgICBwcm90bywgU3ltYm9sKHJlc3VsdCkpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgcHJvdG8ucmVzZXJ2ZWRfcmFuZ2Vfc2l6ZSgpOyBpKyspIHsKKyAgICBjb25zdCBEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZSYgcmFuZ2UxID0gcHJvdG8ucmVzZXJ2ZWRfcmFuZ2UoaSk7CisgICAgZm9yIChpbnQgaiA9IGkgKyAxOyBqIDwgcHJvdG8ucmVzZXJ2ZWRfcmFuZ2Vfc2l6ZSgpOyBqKyspIHsKKyAgICAgIGNvbnN0IERlc2NyaXB0b3JQcm90b19SZXNlcnZlZFJhbmdlJiByYW5nZTIgPSBwcm90by5yZXNlcnZlZF9yYW5nZShqKTsKKyAgICAgIGlmIChyYW5nZTEuZW5kKCkgPiByYW5nZTIuc3RhcnQoKSAmJiByYW5nZTIuZW5kKCkgPiByYW5nZTEuc3RhcnQoKSkgeworICAgICAgICBBZGRFcnJvcihyZXN1bHQtPmZ1bGxfbmFtZSgpLCBwcm90by5yZXNlcnZlZF9yYW5nZShpKSwKKyAgICAgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpOVU1CRVIsCisgICAgICAgICAgICAgICAgIHN0cmluZ3M6OlN1YnN0aXR1dGUoIlJlc2VydmVkIHJhbmdlICQwIHRvICQxIG92ZXJsYXBzIHdpdGggIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJhbHJlYWR5LWRlZmluZWQgcmFuZ2UgJDIgdG8gJDMuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYW5nZTIuc3RhcnQoKSwgcmFuZ2UyLmVuZCgpIC0gMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYW5nZTEuc3RhcnQoKSwgcmFuZ2UxLmVuZCgpIC0gMSkpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIGhhc2hfc2V0PHN0cmluZz4gcmVzZXJ2ZWRfbmFtZV9zZXQ7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgcHJvdG8ucmVzZXJ2ZWRfbmFtZV9zaXplKCk7IGkrKykgeworICAgIGNvbnN0IHN0cmluZyYgbmFtZSA9IHByb3RvLnJlc2VydmVkX25hbWUoaSk7CisgICAgaWYgKHJlc2VydmVkX25hbWVfc2V0LmZpbmQobmFtZSkgPT0gcmVzZXJ2ZWRfbmFtZV9zZXQuZW5kKCkpIHsKKyAgICAgIHJlc2VydmVkX25hbWVfc2V0Lmluc2VydChuYW1lKTsKKyAgICB9IGVsc2UgeworICAgICAgQWRkRXJyb3IobmFtZSwgcHJvdG8sIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6TkFNRSwKKyAgICAgICAgICAgICAgIHN0cmluZ3M6OlN1YnN0aXR1dGUoCisgICAgICAgICAgICAgICAgICJGaWVsZCBuYW1lIFwiJDBcIiBpcyByZXNlcnZlZCBtdWx0aXBsZSB0aW1lcy4iLAorICAgICAgICAgICAgICAgICBuYW1lKSk7CisgICAgfQorICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXN1bHQtPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSByZXN1bHQtPmZpZWxkKGkpOworICAgIGZvciAoaW50IGogPSAwOyBqIDwgcmVzdWx0LT5leHRlbnNpb25fcmFuZ2VfY291bnQoKTsgaisrKSB7CisgICAgICBjb25zdCBEZXNjcmlwdG9yOjpFeHRlbnNpb25SYW5nZSogcmFuZ2UgPSByZXN1bHQtPmV4dGVuc2lvbl9yYW5nZShqKTsKKyAgICAgIGlmIChyYW5nZS0+c3RhcnQgPD0gZmllbGQtPm51bWJlcigpICYmIGZpZWxkLT5udW1iZXIoKSA8IHJhbmdlLT5lbmQpIHsKKyAgICAgICAgQWRkRXJyb3IoZmllbGQtPmZ1bGxfbmFtZSgpLCBwcm90by5leHRlbnNpb25fcmFuZ2UoaiksCisgICAgICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6TlVNQkVSLAorICAgICAgICAgICAgICAgICBzdHJpbmdzOjpTdWJzdGl0dXRlKAorICAgICAgICAgICAgICAgICAgICJFeHRlbnNpb24gcmFuZ2UgJDAgdG8gJDEgaW5jbHVkZXMgZmllbGQgXCIkMlwiICgkMykuIiwKKyAgICAgICAgICAgICAgICAgICByYW5nZS0+c3RhcnQsIHJhbmdlLT5lbmQgLSAxLAorICAgICAgICAgICAgICAgICAgIGZpZWxkLT5uYW1lKCksIGZpZWxkLT5udW1iZXIoKSkpOworICAgICAgfQorICAgIH0KKyAgICBmb3IgKGludCBqID0gMDsgaiA8IHJlc3VsdC0+cmVzZXJ2ZWRfcmFuZ2VfY291bnQoKTsgaisrKSB7CisgICAgICBjb25zdCBEZXNjcmlwdG9yOjpSZXNlcnZlZFJhbmdlKiByYW5nZSA9IHJlc3VsdC0+cmVzZXJ2ZWRfcmFuZ2Uoaik7CisgICAgICBpZiAocmFuZ2UtPnN0YXJ0IDw9IGZpZWxkLT5udW1iZXIoKSAmJiBmaWVsZC0+bnVtYmVyKCkgPCByYW5nZS0+ZW5kKSB7CisgICAgICAgIEFkZEVycm9yKGZpZWxkLT5mdWxsX25hbWUoKSwgcHJvdG8ucmVzZXJ2ZWRfcmFuZ2UoaiksCisgICAgICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6TlVNQkVSLAorICAgICAgICAgICAgICAgICBzdHJpbmdzOjpTdWJzdGl0dXRlKAorICAgICAgICAgICAgICAgICAgICJGaWVsZCBcIiQwXCIgdXNlcyByZXNlcnZlZCBudW1iZXIgJDEuIiwKKyAgICAgICAgICAgICAgICAgICBmaWVsZC0+bmFtZSgpLCBmaWVsZC0+bnVtYmVyKCkpKTsKKyAgICAgIH0KKyAgICB9CisgICAgaWYgKHJlc2VydmVkX25hbWVfc2V0LmZpbmQoZmllbGQtPm5hbWUoKSkgIT0gcmVzZXJ2ZWRfbmFtZV9zZXQuZW5kKCkpIHsKKyAgICAgIEFkZEVycm9yKGZpZWxkLT5mdWxsX25hbWUoKSwgcHJvdG8uZmllbGQoaSksCisgICAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok5BTUUsCisgICAgICAgICAgICAgICBzdHJpbmdzOjpTdWJzdGl0dXRlKAorICAgICAgICAgICAgICAgICAiRmllbGQgbmFtZSBcIiQwXCIgaXMgcmVzZXJ2ZWQuIiwgZmllbGQtPm5hbWUoKSkpOworICAgIH0KKyAgfQorCisgIC8vIENoZWNrIHRoYXQgZXh0ZW5zaW9uIHJhbmdlcyBkb24ndCBvdmVybGFwIGFuZCBkb24ndCBpbmNsdWRlCisgIC8vIHJlc2VydmVkIGZpZWxkIG51bWJlcnMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVzdWx0LT5leHRlbnNpb25fcmFuZ2VfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgRGVzY3JpcHRvcjo6RXh0ZW5zaW9uUmFuZ2UqIHJhbmdlMSA9IHJlc3VsdC0+ZXh0ZW5zaW9uX3JhbmdlKGkpOworICAgIGZvciAoaW50IGogPSAwOyBqIDwgcmVzdWx0LT5yZXNlcnZlZF9yYW5nZV9jb3VudCgpOyBqKyspIHsKKyAgICAgIGNvbnN0IERlc2NyaXB0b3I6OlJlc2VydmVkUmFuZ2UqIHJhbmdlMiA9IHJlc3VsdC0+cmVzZXJ2ZWRfcmFuZ2Uoaik7CisgICAgICBpZiAocmFuZ2UxLT5lbmQgPiByYW5nZTItPnN0YXJ0ICYmIHJhbmdlMi0+ZW5kID4gcmFuZ2UxLT5zdGFydCkgeworICAgICAgICBBZGRFcnJvcihyZXN1bHQtPmZ1bGxfbmFtZSgpLCBwcm90by5leHRlbnNpb25fcmFuZ2UoaiksCisgICAgICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6TlVNQkVSLAorICAgICAgICAgICAgICAgICBzdHJpbmdzOjpTdWJzdGl0dXRlKCJFeHRlbnNpb24gcmFuZ2UgJDAgdG8gJDEgb3ZlcmxhcHMgd2l0aCAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInJlc2VydmVkIHJhbmdlICQyIHRvICQzLiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmFuZ2UxLT5zdGFydCwgcmFuZ2UxLT5lbmQgLSAxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhbmdlMi0+c3RhcnQsIHJhbmdlMi0+ZW5kIC0gMSkpOworICAgICAgfQorICAgIH0KKyAgICBmb3IgKGludCBqID0gaSArIDE7IGogPCByZXN1bHQtPmV4dGVuc2lvbl9yYW5nZV9jb3VudCgpOyBqKyspIHsKKyAgICAgIGNvbnN0IERlc2NyaXB0b3I6OkV4dGVuc2lvblJhbmdlKiByYW5nZTIgPSByZXN1bHQtPmV4dGVuc2lvbl9yYW5nZShqKTsKKyAgICAgIGlmIChyYW5nZTEtPmVuZCA+IHJhbmdlMi0+c3RhcnQgJiYgcmFuZ2UyLT5lbmQgPiByYW5nZTEtPnN0YXJ0KSB7CisgICAgICAgIEFkZEVycm9yKHJlc3VsdC0+ZnVsbF9uYW1lKCksIHByb3RvLmV4dGVuc2lvbl9yYW5nZShqKSwKKyAgICAgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpOVU1CRVIsCisgICAgICAgICAgICAgICAgIHN0cmluZ3M6OlN1YnN0aXR1dGUoIkV4dGVuc2lvbiByYW5nZSAkMCB0byAkMSBvdmVybGFwcyB3aXRoICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYWxyZWFkeS1kZWZpbmVkIHJhbmdlICQyIHRvICQzLiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmFuZ2UyLT5zdGFydCwgcmFuZ2UyLT5lbmQgLSAxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhbmdlMS0+c3RhcnQsIHJhbmdlMS0+ZW5kIC0gMSkpOworICAgICAgfQorICAgIH0KKyAgfQorfQorCisKK3ZvaWQgRGVzY3JpcHRvckJ1aWxkZXI6OkJ1aWxkRmllbGRPckV4dGVuc2lvbihjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90byYgcHJvdG8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVzY3JpcHRvciogcGFyZW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvciogcmVzdWx0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaXNfZXh0ZW5zaW9uKSB7CisgIGNvbnN0IHN0cmluZyYgc2NvcGUgPSAocGFyZW50ID09IE5VTEwpID8KKyAgICBmaWxlXy0+cGFja2FnZSgpIDogcGFyZW50LT5mdWxsX25hbWUoKTsKKyAgc3RyaW5nKiBmdWxsX25hbWUgPSB0YWJsZXNfLT5BbGxvY2F0ZVN0cmluZyhzY29wZSk7CisgIGlmICghZnVsbF9uYW1lLT5lbXB0eSgpKSBmdWxsX25hbWUtPmFwcGVuZCgxLCAnLicpOworICBmdWxsX25hbWUtPmFwcGVuZChwcm90by5uYW1lKCkpOworCisgIFZhbGlkYXRlU3ltYm9sTmFtZShwcm90by5uYW1lKCksICpmdWxsX25hbWUsIHByb3RvKTsKKworICByZXN1bHQtPm5hbWVfICAgICAgICAgPSB0YWJsZXNfLT5BbGxvY2F0ZVN0cmluZyhwcm90by5uYW1lKCkpOworICByZXN1bHQtPmZ1bGxfbmFtZV8gICAgPSBmdWxsX25hbWU7CisgIHJlc3VsdC0+ZmlsZV8gICAgICAgICA9IGZpbGVfOworICByZXN1bHQtPm51bWJlcl8gICAgICAgPSBwcm90by5udW1iZXIoKTsKKyAgcmVzdWx0LT5pc19leHRlbnNpb25fID0gaXNfZXh0ZW5zaW9uOworCisgIC8vIElmIC5wcm90byBmaWxlcyBmb2xsb3cgdGhlIHN0eWxlIGd1aWRlIHRoZW4gdGhlIG5hbWUgc2hvdWxkIGFscmVhZHkgYmUKKyAgLy8gbG93ZXItY2FzZWQuICBJZiB0aGF0J3MgdGhlIGNhc2Ugd2UgY2FuIGp1c3QgcmV1c2UgdGhlIHN0cmluZyB3ZSBhbHJlYWR5CisgIC8vIGFsbG9jYXRlZCByYXRoZXIgdGhhbiBhbGxvY2F0ZSBhIG5ldyBvbmUuCisgIHN0cmluZyBsb3dlcmNhc2VfbmFtZShwcm90by5uYW1lKCkpOworICBMb3dlclN0cmluZygmbG93ZXJjYXNlX25hbWUpOworICBpZiAobG93ZXJjYXNlX25hbWUgPT0gcHJvdG8ubmFtZSgpKSB7CisgICAgcmVzdWx0LT5sb3dlcmNhc2VfbmFtZV8gPSByZXN1bHQtPm5hbWVfOworICB9IGVsc2UgeworICAgIHJlc3VsdC0+bG93ZXJjYXNlX25hbWVfID0gdGFibGVzXy0+QWxsb2NhdGVTdHJpbmcobG93ZXJjYXNlX25hbWUpOworICB9CisKKyAgLy8gRG9uJ3QgYm90aGVyIHdpdGggdGhlIGFib3ZlIG9wdGltaXphdGlvbiBmb3IgY2FtZWwtY2FzZSBuYW1lcyBzaW5jZQorICAvLyAucHJvdG8gZmlsZXMgdGhhdCBmb2xsb3cgdGhlIGd1aWRlIHNob3VsZG4ndCBiZSB1c2luZyBuYW1lcyBpbiB0aGlzCisgIC8vIGZvcm1hdCwgc28gdGhlIG9wdGltaXphdGlvbiB3b3VsZG4ndCBoZWxwIG11Y2guCisgIHJlc3VsdC0+Y2FtZWxjYXNlX25hbWVfID0KKyAgICAgIHRhYmxlc18tPkFsbG9jYXRlU3RyaW5nKFRvQ2FtZWxDYXNlKHByb3RvLm5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGxvd2VyX2ZpcnN0ID0gKi8gdHJ1ZSkpOworCisgIGlmIChwcm90by5oYXNfanNvbl9uYW1lKCkpIHsKKyAgICByZXN1bHQtPmhhc19qc29uX25hbWVfID0gdHJ1ZTsKKyAgICByZXN1bHQtPmpzb25fbmFtZV8gPSB0YWJsZXNfLT5BbGxvY2F0ZVN0cmluZyhwcm90by5qc29uX25hbWUoKSk7CisgIH0gZWxzZSB7CisgICAgcmVzdWx0LT5oYXNfanNvbl9uYW1lXyA9IGZhbHNlOworICAgIHJlc3VsdC0+anNvbl9uYW1lXyA9IHJlc3VsdC0+Y2FtZWxjYXNlX25hbWVfOworICB9CisKKyAgLy8gU29tZSBjb21waWxlcnMgZG8gbm90IGFsbG93IHN0YXRpY19jYXN0IGRpcmVjdGx5IGJldHdlZW4gdHdvIGVudW0gdHlwZXMsCisgIC8vIHNvIHdlIG11c3QgY2FzdCB0byBpbnQgZmlyc3QuCisgIHJlc3VsdC0+dHlwZV8gID0gc3RhdGljX2Nhc3Q8RmllbGREZXNjcmlwdG9yOjpUeXBlPigKKyAgICAgICAgICAgICAgICAgICAgIGltcGxpY2l0X2Nhc3Q8aW50Pihwcm90by50eXBlKCkpKTsKKyAgcmVzdWx0LT5sYWJlbF8gPSBzdGF0aWNfY2FzdDxGaWVsZERlc2NyaXB0b3I6OkxhYmVsPigKKyAgICAgICAgICAgICAgICAgICAgIGltcGxpY2l0X2Nhc3Q8aW50Pihwcm90by5sYWJlbCgpKSk7CisKKyAgLy8gQW4gZXh0ZW5zaW9uIGNhbm5vdCBoYXZlIGEgcmVxdWlyZWQgZmllbGQgKGIvMTMzNjU4MzYpLgorICBpZiAocmVzdWx0LT5pc19leHRlbnNpb25fICYmCisgICAgICByZXN1bHQtPmxhYmVsXyA9PSBGaWVsZERlc2NyaXB0b3I6OkxBQkVMX1JFUVVJUkVEKSB7CisgICAgQWRkRXJyb3IocmVzdWx0LT5mdWxsX25hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgLy8gRXJyb3IgbG9jYXRpb24gYFRZUEVgOiB3ZSB3b3VsZCByZWFsbHkgbGlrZSB0byBpbmRpY2F0ZQorICAgICAgICAgICAgIC8vIGBMQUJFTGAsIGJ1dCB0aGUgYEVycm9yTG9jYXRpb25gIGVudW0gaGFzIG5vIGVudHJ5IGZvciB0aGlzLCBhbmQKKyAgICAgICAgICAgICAvLyB3ZSBkb24ndCBuZWNlc3NhcmlseSBrbm93IGFib3V0IGFsbCBpbXBsZW1lbnRhdGlvbnMgb2YgdGhlCisgICAgICAgICAgICAgLy8gYEVycm9yQ29sbGVjdG9yYCBpbnRlcmZhY2UgdG8gZXh0ZW5kIHRoZW0gdG8gaGFuZGxlIHRoZSBuZXcKKyAgICAgICAgICAgICAvLyBlcnJvciBsb2NhdGlvbiB0eXBlIHByb3Blcmx5LgorICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6VFlQRSwKKyAgICAgICAgICAgICAiTWVzc2FnZSBleHRlbnNpb25zIGNhbm5vdCBoYXZlIHJlcXVpcmVkIGZpZWxkcy4iKTsKKyAgfQorCisgIC8vIFNvbWUgb2YgdGhlc2UgbWF5IGJlIGZpbGxlZCBpbiB3aGVuIGNyb3NzLWxpbmtpbmcuCisgIHJlc3VsdC0+Y29udGFpbmluZ190eXBlXyA9IE5VTEw7CisgIHJlc3VsdC0+ZXh0ZW5zaW9uX3Njb3BlXyA9IE5VTEw7CisgIHJlc3VsdC0+bWVzc2FnZV90eXBlXyA9IE5VTEw7CisgIHJlc3VsdC0+ZW51bV90eXBlXyA9IE5VTEw7CisKKyAgcmVzdWx0LT5oYXNfZGVmYXVsdF92YWx1ZV8gPSBwcm90by5oYXNfZGVmYXVsdF92YWx1ZSgpOworICBpZiAocHJvdG8uaGFzX2RlZmF1bHRfdmFsdWUoKSAmJiByZXN1bHQtPmlzX3JlcGVhdGVkKCkpIHsKKyAgICBBZGRFcnJvcihyZXN1bHQtPmZ1bGxfbmFtZSgpLCBwcm90bywKKyAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6OkRFRkFVTFRfVkFMVUUsCisgICAgICAgICAgICAgIlJlcGVhdGVkIGZpZWxkcyBjYW4ndCBoYXZlIGRlZmF1bHQgdmFsdWVzLiIpOworICB9CisKKyAgaWYgKHByb3RvLmhhc190eXBlKCkpIHsKKyAgICBpZiAocHJvdG8uaGFzX2RlZmF1bHRfdmFsdWUoKSkgeworICAgICAgY2hhciogZW5kX3BvcyA9IE5VTEw7CisgICAgICBzd2l0Y2ggKHJlc3VsdC0+Y3BwX3R5cGUoKSkgeworICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9JTlQzMjoKKyAgICAgICAgICByZXN1bHQtPmRlZmF1bHRfdmFsdWVfaW50MzJfID0KKyAgICAgICAgICAgIHN0cnRvbChwcm90by5kZWZhdWx0X3ZhbHVlKCkuY19zdHIoKSwgJmVuZF9wb3MsIDApOworICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9JTlQ2NDoKKyAgICAgICAgICByZXN1bHQtPmRlZmF1bHRfdmFsdWVfaW50NjRfID0KKyAgICAgICAgICAgIHN0cnRvNjQocHJvdG8uZGVmYXVsdF92YWx1ZSgpLmNfc3RyKCksICZlbmRfcG9zLCAwKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDMyOgorICAgICAgICAgIHJlc3VsdC0+ZGVmYXVsdF92YWx1ZV91aW50MzJfID0KKyAgICAgICAgICAgIHN0cnRvdWwocHJvdG8uZGVmYXVsdF92YWx1ZSgpLmNfc3RyKCksICZlbmRfcG9zLCAwKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDY0OgorICAgICAgICAgIHJlc3VsdC0+ZGVmYXVsdF92YWx1ZV91aW50NjRfID0KKyAgICAgICAgICAgIHN0cnRvdTY0KHByb3RvLmRlZmF1bHRfdmFsdWUoKS5jX3N0cigpLCAmZW5kX3BvcywgMCk7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0ZMT0FUOgorICAgICAgICAgIGlmIChwcm90by5kZWZhdWx0X3ZhbHVlKCkgPT0gImluZiIpIHsKKyAgICAgICAgICAgIHJlc3VsdC0+ZGVmYXVsdF92YWx1ZV9mbG9hdF8gPSBudW1lcmljX2xpbWl0czxmbG9hdD46OmluZmluaXR5KCk7CisgICAgICAgICAgfSBlbHNlIGlmIChwcm90by5kZWZhdWx0X3ZhbHVlKCkgPT0gIi1pbmYiKSB7CisgICAgICAgICAgICByZXN1bHQtPmRlZmF1bHRfdmFsdWVfZmxvYXRfID0gLW51bWVyaWNfbGltaXRzPGZsb2F0Pjo6aW5maW5pdHkoKTsKKyAgICAgICAgICB9IGVsc2UgaWYgKHByb3RvLmRlZmF1bHRfdmFsdWUoKSA9PSAibmFuIikgeworICAgICAgICAgICAgcmVzdWx0LT5kZWZhdWx0X3ZhbHVlX2Zsb2F0XyA9IG51bWVyaWNfbGltaXRzPGZsb2F0Pjo6cXVpZXRfTmFOKCk7CisgICAgICAgICAgfSBlbHNlICB7CisgICAgICAgICAgICByZXN1bHQtPmRlZmF1bHRfdmFsdWVfZmxvYXRfID0gaW86OlNhZmVEb3VibGVUb0Zsb2F0KAorICAgICAgICAgICAgICAgIGlvOjpOb0xvY2FsZVN0cnRvZChwcm90by5kZWZhdWx0X3ZhbHVlKCkuY19zdHIoKSwgJmVuZF9wb3MpKTsKKyAgICAgICAgICB9CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0RPVUJMRToKKyAgICAgICAgICBpZiAocHJvdG8uZGVmYXVsdF92YWx1ZSgpID09ICJpbmYiKSB7CisgICAgICAgICAgICByZXN1bHQtPmRlZmF1bHRfdmFsdWVfZG91YmxlXyA9IG51bWVyaWNfbGltaXRzPGRvdWJsZT46OmluZmluaXR5KCk7CisgICAgICAgICAgfSBlbHNlIGlmIChwcm90by5kZWZhdWx0X3ZhbHVlKCkgPT0gIi1pbmYiKSB7CisgICAgICAgICAgICByZXN1bHQtPmRlZmF1bHRfdmFsdWVfZG91YmxlXyA9IC1udW1lcmljX2xpbWl0czxkb3VibGU+OjppbmZpbml0eSgpOworICAgICAgICAgIH0gZWxzZSBpZiAocHJvdG8uZGVmYXVsdF92YWx1ZSgpID09ICJuYW4iKSB7CisgICAgICAgICAgICByZXN1bHQtPmRlZmF1bHRfdmFsdWVfZG91YmxlXyA9IG51bWVyaWNfbGltaXRzPGRvdWJsZT46OnF1aWV0X05hTigpOworICAgICAgICAgIH0gZWxzZSAgeworICAgICAgICAgICAgcmVzdWx0LT5kZWZhdWx0X3ZhbHVlX2RvdWJsZV8gPQorICAgICAgICAgICAgICAgIGlvOjpOb0xvY2FsZVN0cnRvZChwcm90by5kZWZhdWx0X3ZhbHVlKCkuY19zdHIoKSwgJmVuZF9wb3MpOworICAgICAgICAgIH0KKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfQk9PTDoKKyAgICAgICAgICBpZiAocHJvdG8uZGVmYXVsdF92YWx1ZSgpID09ICJ0cnVlIikgeworICAgICAgICAgICAgcmVzdWx0LT5kZWZhdWx0X3ZhbHVlX2Jvb2xfID0gdHJ1ZTsKKyAgICAgICAgICB9IGVsc2UgaWYgKHByb3RvLmRlZmF1bHRfdmFsdWUoKSA9PSAiZmFsc2UiKSB7CisgICAgICAgICAgICByZXN1bHQtPmRlZmF1bHRfdmFsdWVfYm9vbF8gPSBmYWxzZTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgQWRkRXJyb3IocmVzdWx0LT5mdWxsX25hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6OkRFRkFVTFRfVkFMVUUsCisgICAgICAgICAgICAgICAgICAgICAiQm9vbGVhbiBkZWZhdWx0IG11c3QgYmUgdHJ1ZSBvciBmYWxzZS4iKTsKKyAgICAgICAgICB9CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0VOVU06CisgICAgICAgICAgLy8gVGhpcyB3aWxsIGJlIGZpbGxlZCBpbiB3aGVuIGNyb3NzLWxpbmtpbmcuCisgICAgICAgICAgcmVzdWx0LT5kZWZhdWx0X3ZhbHVlX2VudW1fID0gTlVMTDsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HOgorICAgICAgICAgIGlmIChyZXN1bHQtPnR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfQllURVMpIHsKKyAgICAgICAgICAgIHJlc3VsdC0+ZGVmYXVsdF92YWx1ZV9zdHJpbmdfID0gdGFibGVzXy0+QWxsb2NhdGVTdHJpbmcoCisgICAgICAgICAgICAgIFVuZXNjYXBlQ0VzY2FwZVN0cmluZyhwcm90by5kZWZhdWx0X3ZhbHVlKCkpKTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmVzdWx0LT5kZWZhdWx0X3ZhbHVlX3N0cmluZ18gPQorICAgICAgICAgICAgICAgIHRhYmxlc18tPkFsbG9jYXRlU3RyaW5nKHByb3RvLmRlZmF1bHRfdmFsdWUoKSk7CisgICAgICAgICAgfQorICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgICAgIEFkZEVycm9yKHJlc3VsdC0+ZnVsbF9uYW1lKCksIHByb3RvLAorICAgICAgICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6REVGQVVMVF9WQUxVRSwKKyAgICAgICAgICAgICAgICAgICAiTWVzc2FnZXMgY2FuJ3QgaGF2ZSBkZWZhdWx0IHZhbHVlcy4iKTsKKyAgICAgICAgICByZXN1bHQtPmhhc19kZWZhdWx0X3ZhbHVlXyA9IGZhbHNlOworICAgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBpZiAoZW5kX3BvcyAhPSBOVUxMKSB7CisgICAgICAgIC8vIGVuZF9wb3MgaXMgb25seSBzZXQgbm9uLU5VTEwgYnkgdGhlIHBhcnNlcnMgZm9yIG51bWVyaWMgdHlwZXMsIGFib3ZlLgorICAgICAgICAvLyBUaGlzIGNoZWNrcyB0aGF0IHRoZSBkZWZhdWx0IHdhcyBub24tZW1wdHkgYW5kIGhhZCBubyBleHRyYSBqdW5rCisgICAgICAgIC8vIGFmdGVyIHRoZSBlbmQgb2YgdGhlIG51bWJlci4KKyAgICAgICAgaWYgKHByb3RvLmRlZmF1bHRfdmFsdWUoKS5lbXB0eSgpIHx8ICplbmRfcG9zICE9ICdcMCcpIHsKKyAgICAgICAgICBBZGRFcnJvcihyZXN1bHQtPmZ1bGxfbmFtZSgpLCBwcm90bywKKyAgICAgICAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6OkRFRkFVTFRfVkFMVUUsCisgICAgICAgICAgICAgICAgICAgIkNvdWxkbid0IHBhcnNlIGRlZmF1bHQgdmFsdWUgXCIiICsgcHJvdG8uZGVmYXVsdF92YWx1ZSgpICsKKyAgICAgICAgICAgICAgICAgICAiXCIuIik7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgLy8gTm8gZXhwbGljaXQgZGVmYXVsdCB2YWx1ZQorICAgICAgc3dpdGNoIChyZXN1bHQtPmNwcF90eXBlKCkpIHsKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UMzI6CisgICAgICAgICAgcmVzdWx0LT5kZWZhdWx0X3ZhbHVlX2ludDMyXyA9IDA7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0lOVDY0OgorICAgICAgICAgIHJlc3VsdC0+ZGVmYXVsdF92YWx1ZV9pbnQ2NF8gPSAwOworICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9VSU5UMzI6CisgICAgICAgICAgcmVzdWx0LT5kZWZhdWx0X3ZhbHVlX3VpbnQzMl8gPSAwOworICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9VSU5UNjQ6CisgICAgICAgICAgcmVzdWx0LT5kZWZhdWx0X3ZhbHVlX3VpbnQ2NF8gPSAwOworICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9GTE9BVDoKKyAgICAgICAgICByZXN1bHQtPmRlZmF1bHRfdmFsdWVfZmxvYXRfID0gMC4wZjsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRE9VQkxFOgorICAgICAgICAgIHJlc3VsdC0+ZGVmYXVsdF92YWx1ZV9kb3VibGVfID0gMC4wOworICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9CT09MOgorICAgICAgICAgIHJlc3VsdC0+ZGVmYXVsdF92YWx1ZV9ib29sXyA9IGZhbHNlOworICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9FTlVNOgorICAgICAgICAgIC8vIFRoaXMgd2lsbCBiZSBmaWxsZWQgaW4gd2hlbiBjcm9zcy1saW5raW5nLgorICAgICAgICAgIHJlc3VsdC0+ZGVmYXVsdF92YWx1ZV9lbnVtXyA9IE5VTEw7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORzoKKyAgICAgICAgICByZXN1bHQtPmRlZmF1bHRfdmFsdWVfc3RyaW5nXyA9ICZpbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmcoKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRToKKyAgICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICBpZiAocmVzdWx0LT5udW1iZXIoKSA8PSAwKSB7CisgICAgQWRkRXJyb3IocmVzdWx0LT5mdWxsX25hbWUoKSwgcHJvdG8sIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6TlVNQkVSLAorICAgICAgICAgICAgICJGaWVsZCBudW1iZXJzIG11c3QgYmUgcG9zaXRpdmUgaW50ZWdlcnMuIik7CisgIH0gZWxzZSBpZiAoIWlzX2V4dGVuc2lvbiAmJiByZXN1bHQtPm51bWJlcigpID4gRmllbGREZXNjcmlwdG9yOjprTWF4TnVtYmVyKSB7CisgICAgLy8gT25seSB2YWxpZGF0ZSB0aGF0IHRoZSBudW1iZXIgaXMgd2l0aGluIHRoZSB2YWxpZCBmaWVsZCByYW5nZSBpZiBpdCBpcworICAgIC8vIG5vdCBhbiBleHRlbnNpb24uIFNpbmNlIGV4dGVuc2lvbiBudW1iZXJzIGFyZSB2YWxpZGF0ZWQgd2l0aCB0aGUKKyAgICAvLyBleHRlbmRlZSdzIHZhbGlkIHNldCBvZiBleHRlbnNpb24gbnVtYmVycywgYW5kIHRob3NlIGFyZSBpbiB0dXJuCisgICAgLy8gdmFsaWRhdGVkIGFnYWluc3QgdGhlIG1heCBhbGxvd2VkIG51bWJlciwgdGhlIGNoZWNrIGlzIHVubmVjZXNzYXJ5IGZvcgorICAgIC8vIGV4dGVuc2lvbiBmaWVsZHMuCisgICAgLy8gVGhpcyBhdm9pZHMgY3Jvc3MtbGlua2luZyBpc3N1ZXMgdGhhdCBhcmlzZSB3aGVuIGF0dGVtcHRpbmcgdG8gY2hlY2sgaWYKKyAgICAvLyB0aGUgZXh0ZW5kZWUgaXMgYSBtZXNzYWdlX3NldF93aXJlX2Zvcm1hdCBtZXNzYWdlLCB3aGljaCBoYXMgYSBoaWdoZXIgbWF4CisgICAgLy8gb24gZXh0ZW5zaW9uIG51bWJlcnMuCisgICAgQWRkRXJyb3IocmVzdWx0LT5mdWxsX25hbWUoKSwgcHJvdG8sIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6TlVNQkVSLAorICAgICAgICAgICAgIHN0cmluZ3M6OlN1YnN0aXR1dGUoIkZpZWxkIG51bWJlcnMgY2Fubm90IGJlIGdyZWF0ZXIgdGhhbiAkMC4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yOjprTWF4TnVtYmVyKSk7CisgIH0gZWxzZSBpZiAocmVzdWx0LT5udW1iZXIoKSA+PSBGaWVsZERlc2NyaXB0b3I6OmtGaXJzdFJlc2VydmVkTnVtYmVyICYmCisgICAgICAgICAgICAgcmVzdWx0LT5udW1iZXIoKSA8PSBGaWVsZERlc2NyaXB0b3I6OmtMYXN0UmVzZXJ2ZWROdW1iZXIpIHsKKyAgICBBZGRFcnJvcihyZXN1bHQtPmZ1bGxfbmFtZSgpLCBwcm90bywgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpOVU1CRVIsCisgICAgICAgICAgICAgc3RyaW5nczo6U3Vic3RpdHV0ZSgKKyAgICAgICAgICAgICAgICJGaWVsZCBudW1iZXJzICQwIHRocm91Z2ggJDEgYXJlIHJlc2VydmVkIGZvciB0aGUgcHJvdG9jb2wgIgorICAgICAgICAgICAgICAgImJ1ZmZlciBsaWJyYXJ5IGltcGxlbWVudGF0aW9uLiIsCisgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3I6OmtGaXJzdFJlc2VydmVkTnVtYmVyLAorICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yOjprTGFzdFJlc2VydmVkTnVtYmVyKSk7CisgIH0KKworICBpZiAoaXNfZXh0ZW5zaW9uKSB7CisgICAgaWYgKCFwcm90by5oYXNfZXh0ZW5kZWUoKSkgeworICAgICAgQWRkRXJyb3IocmVzdWx0LT5mdWxsX25hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6OkVYVEVOREVFLAorICAgICAgICAgICAgICAgIkZpZWxkRGVzY3JpcHRvclByb3RvLmV4dGVuZGVlIG5vdCBzZXQgZm9yIGV4dGVuc2lvbiBmaWVsZC4iKTsKKyAgICB9CisKKyAgICByZXN1bHQtPmV4dGVuc2lvbl9zY29wZV8gPSBwYXJlbnQ7CisKKyAgICBpZiAocHJvdG8uaGFzX29uZW9mX2luZGV4KCkpIHsKKyAgICAgIEFkZEVycm9yKHJlc3VsdC0+ZnVsbF9uYW1lKCksIHByb3RvLAorICAgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpPVEhFUiwKKyAgICAgICAgICAgICAgICJGaWVsZERlc2NyaXB0b3JQcm90by5vbmVvZl9pbmRleCBzaG91bGQgbm90IGJlIHNldCBmb3IgIgorICAgICAgICAgICAgICAgImV4dGVuc2lvbnMuIik7CisgICAgfQorCisgICAgLy8gRmlsbCBpbiBsYXRlciAobWF5YmUpLgorICAgIHJlc3VsdC0+Y29udGFpbmluZ19vbmVvZl8gPSBOVUxMOworICB9IGVsc2UgeworICAgIGlmIChwcm90by5oYXNfZXh0ZW5kZWUoKSkgeworICAgICAgQWRkRXJyb3IocmVzdWx0LT5mdWxsX25hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6OkVYVEVOREVFLAorICAgICAgICAgICAgICAgIkZpZWxkRGVzY3JpcHRvclByb3RvLmV4dGVuZGVlIHNldCBmb3Igbm9uLWV4dGVuc2lvbiBmaWVsZC4iKTsKKyAgICB9CisKKyAgICByZXN1bHQtPmNvbnRhaW5pbmdfdHlwZV8gPSBwYXJlbnQ7CisKKyAgICBpZiAocHJvdG8uaGFzX29uZW9mX2luZGV4KCkpIHsKKyAgICAgIGlmIChwcm90by5vbmVvZl9pbmRleCgpIDwgMCB8fAorICAgICAgICAgIHByb3RvLm9uZW9mX2luZGV4KCkgPj0gcGFyZW50LT5vbmVvZl9kZWNsX2NvdW50KCkpIHsKKyAgICAgICAgQWRkRXJyb3IocmVzdWx0LT5mdWxsX25hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6T1RIRVIsCisgICAgICAgICAgICAgICAgIHN0cmluZ3M6OlN1YnN0aXR1dGUoIkZpZWxkRGVzY3JpcHRvclByb3RvLm9uZW9mX2luZGV4ICQwIGlzICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib3V0IG9mIHJhbmdlIGZvciB0eXBlIFwiJDFcIi4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3RvLm9uZW9mX2luZGV4KCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50LT5uYW1lKCkpKTsKKyAgICAgICAgcmVzdWx0LT5jb250YWluaW5nX29uZW9mXyA9IE5VTEw7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXN1bHQtPmNvbnRhaW5pbmdfb25lb2ZfID0gcGFyZW50LT5vbmVvZl9kZWNsKHByb3RvLm9uZW9mX2luZGV4KCkpOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICByZXN1bHQtPmNvbnRhaW5pbmdfb25lb2ZfID0gTlVMTDsKKyAgICB9CisgIH0KKworICAvLyBDb3B5IG9wdGlvbnMuCisgIGlmICghcHJvdG8uaGFzX29wdGlvbnMoKSkgeworICAgIHJlc3VsdC0+b3B0aW9uc18gPSBOVUxMOyAgLy8gV2lsbCBzZXQgdG8gZGVmYXVsdF9pbnN0YW5jZSBsYXRlci4KKyAgfSBlbHNlIHsKKyAgICBBbGxvY2F0ZU9wdGlvbnMocHJvdG8ub3B0aW9ucygpLCByZXN1bHQpOworICB9CisKKworICBBZGRTeW1ib2wocmVzdWx0LT5mdWxsX25hbWUoKSwgcGFyZW50LCByZXN1bHQtPm5hbWUoKSwKKyAgICAgICAgICAgIHByb3RvLCBTeW1ib2wocmVzdWx0KSk7Cit9CisKK3ZvaWQgRGVzY3JpcHRvckJ1aWxkZXI6OkJ1aWxkRXh0ZW5zaW9uUmFuZ2UoCisgICAgY29uc3QgRGVzY3JpcHRvclByb3RvOjpFeHRlbnNpb25SYW5nZSYgcHJvdG8sCisgICAgY29uc3QgRGVzY3JpcHRvciogcGFyZW50LAorICAgIERlc2NyaXB0b3I6OkV4dGVuc2lvblJhbmdlKiByZXN1bHQpIHsKKyAgcmVzdWx0LT5zdGFydCA9IHByb3RvLnN0YXJ0KCk7CisgIHJlc3VsdC0+ZW5kID0gcHJvdG8uZW5kKCk7CisgIGlmIChyZXN1bHQtPnN0YXJ0IDw9IDApIHsKKyAgICBBZGRFcnJvcihwYXJlbnQtPmZ1bGxfbmFtZSgpLCBwcm90bywKKyAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok5VTUJFUiwKKyAgICAgICAgICAgICAiRXh0ZW5zaW9uIG51bWJlcnMgbXVzdCBiZSBwb3NpdGl2ZSBpbnRlZ2Vycy4iKTsKKyAgfQorCisgIC8vIENoZWNraW5nIG9mIHRoZSB1cHBlciBib3VuZCBvZiB0aGUgZXh0ZW5zaW9uIHJhbmdlIGlzIGRlZmVycmVkIHVudGlsIGFmdGVyCisgIC8vIG9wdGlvbnMgaW50ZXJwcmV0aW5nLiBUaGlzIGFsbG93cyBtZXNzYWdlcyB3aXRoIG1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0IHRvCisgIC8vIGhhdmUgZXh0ZW5zaW9ucyBiZXlvbmQgRmllbGREZXNjcmlwdG9yOjprTWF4TnVtYmVyLCBzaW5jZSB0aGUgZXh0ZW5zaW9uCisgIC8vIG51bWJlcnMgYXJlIGFjdHVhbGx5IHVzZWQgYXMgaW50MzJzIGluIHRoZSBtZXNzYWdlX3NldF93aXJlX2Zvcm1hdC4KKworICBpZiAocmVzdWx0LT5zdGFydCA+PSByZXN1bHQtPmVuZCkgeworICAgIEFkZEVycm9yKHBhcmVudC0+ZnVsbF9uYW1lKCksIHByb3RvLAorICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6TlVNQkVSLAorICAgICAgICAgICAgICJFeHRlbnNpb24gcmFuZ2UgZW5kIG51bWJlciBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBzdGFydCBudW1iZXIuIik7CisgIH0KK30KKwordm9pZCBEZXNjcmlwdG9yQnVpbGRlcjo6QnVpbGRSZXNlcnZlZFJhbmdlKAorICAgIGNvbnN0IERlc2NyaXB0b3JQcm90bzo6UmVzZXJ2ZWRSYW5nZSYgcHJvdG8sCisgICAgY29uc3QgRGVzY3JpcHRvciogcGFyZW50LAorICAgIERlc2NyaXB0b3I6OlJlc2VydmVkUmFuZ2UqIHJlc3VsdCkgeworICByZXN1bHQtPnN0YXJ0ID0gcHJvdG8uc3RhcnQoKTsKKyAgcmVzdWx0LT5lbmQgPSBwcm90by5lbmQoKTsKKyAgaWYgKHJlc3VsdC0+c3RhcnQgPD0gMCkgeworICAgIEFkZEVycm9yKHBhcmVudC0+ZnVsbF9uYW1lKCksIHByb3RvLAorICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6TlVNQkVSLAorICAgICAgICAgICAgICJSZXNlcnZlZCBudW1iZXJzIG11c3QgYmUgcG9zaXRpdmUgaW50ZWdlcnMuIik7CisgIH0KK30KKwordm9pZCBEZXNjcmlwdG9yQnVpbGRlcjo6QnVpbGRPbmVvZihjb25zdCBPbmVvZkRlc2NyaXB0b3JQcm90byYgcHJvdG8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlc2NyaXB0b3IqIHBhcmVudCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT25lb2ZEZXNjcmlwdG9yKiByZXN1bHQpIHsKKyAgc3RyaW5nKiBmdWxsX25hbWUgPSB0YWJsZXNfLT5BbGxvY2F0ZVN0cmluZyhwYXJlbnQtPmZ1bGxfbmFtZSgpKTsKKyAgZnVsbF9uYW1lLT5hcHBlbmQoMSwgJy4nKTsKKyAgZnVsbF9uYW1lLT5hcHBlbmQocHJvdG8ubmFtZSgpKTsKKworICBWYWxpZGF0ZVN5bWJvbE5hbWUocHJvdG8ubmFtZSgpLCAqZnVsbF9uYW1lLCBwcm90byk7CisKKyAgcmVzdWx0LT5uYW1lXyA9IHRhYmxlc18tPkFsbG9jYXRlU3RyaW5nKHByb3RvLm5hbWUoKSk7CisgIHJlc3VsdC0+ZnVsbF9uYW1lXyA9IGZ1bGxfbmFtZTsKKworICByZXN1bHQtPmNvbnRhaW5pbmdfdHlwZV8gPSBwYXJlbnQ7CisKKyAgLy8gV2UgbmVlZCB0byBmaWxsIHRoZXNlIGluIGxhdGVyLgorICByZXN1bHQtPmZpZWxkX2NvdW50XyA9IDA7CisgIHJlc3VsdC0+ZmllbGRzXyA9IE5VTEw7CisKKyAgQWRkU3ltYm9sKHJlc3VsdC0+ZnVsbF9uYW1lKCksIHBhcmVudCwgcmVzdWx0LT5uYW1lKCksCisgICAgICAgICAgICBwcm90bywgU3ltYm9sKHJlc3VsdCkpOworfQorCit2b2lkIERlc2NyaXB0b3JCdWlsZGVyOjpCdWlsZEVudW0oY29uc3QgRW51bURlc2NyaXB0b3JQcm90byYgcHJvdG8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVzY3JpcHRvciogcGFyZW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVudW1EZXNjcmlwdG9yKiByZXN1bHQpIHsKKyAgY29uc3Qgc3RyaW5nJiBzY29wZSA9IChwYXJlbnQgPT0gTlVMTCkgPworICAgIGZpbGVfLT5wYWNrYWdlKCkgOiBwYXJlbnQtPmZ1bGxfbmFtZSgpOworICBzdHJpbmcqIGZ1bGxfbmFtZSA9IHRhYmxlc18tPkFsbG9jYXRlU3RyaW5nKHNjb3BlKTsKKyAgaWYgKCFmdWxsX25hbWUtPmVtcHR5KCkpIGZ1bGxfbmFtZS0+YXBwZW5kKDEsICcuJyk7CisgIGZ1bGxfbmFtZS0+YXBwZW5kKHByb3RvLm5hbWUoKSk7CisKKyAgVmFsaWRhdGVTeW1ib2xOYW1lKHByb3RvLm5hbWUoKSwgKmZ1bGxfbmFtZSwgcHJvdG8pOworCisgIHJlc3VsdC0+bmFtZV8gICAgICAgICAgICA9IHRhYmxlc18tPkFsbG9jYXRlU3RyaW5nKHByb3RvLm5hbWUoKSk7CisgIHJlc3VsdC0+ZnVsbF9uYW1lXyAgICAgICA9IGZ1bGxfbmFtZTsKKyAgcmVzdWx0LT5maWxlXyAgICAgICAgICAgID0gZmlsZV87CisgIHJlc3VsdC0+Y29udGFpbmluZ190eXBlXyA9IHBhcmVudDsKKyAgcmVzdWx0LT5pc19wbGFjZWhvbGRlcl8gID0gZmFsc2U7CisgIHJlc3VsdC0+aXNfdW5xdWFsaWZpZWRfcGxhY2Vob2xkZXJfID0gZmFsc2U7CisKKyAgaWYgKHByb3RvLnZhbHVlX3NpemUoKSA9PSAwKSB7CisgICAgLy8gV2UgY2Fubm90IGFsbG93IGVudW1zIHdpdGggbm8gdmFsdWVzIGJlY2F1c2UgdGhpcyB3b3VsZCBtZWFuIHRoZXJlCisgICAgLy8gd291bGQgYmUgbm8gdmFsaWQgZGVmYXVsdCB2YWx1ZSBmb3IgZmllbGRzIG9mIHRoaXMgdHlwZS4KKyAgICBBZGRFcnJvcihyZXN1bHQtPmZ1bGxfbmFtZSgpLCBwcm90bywKKyAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok5BTUUsCisgICAgICAgICAgICAgIkVudW1zIG11c3QgY29udGFpbiBhdCBsZWFzdCBvbmUgdmFsdWUuIik7CisgIH0KKworICBCVUlMRF9BUlJBWShwcm90bywgcmVzdWx0LCB2YWx1ZSwgQnVpbGRFbnVtVmFsdWUsIHJlc3VsdCk7CisKKyAgLy8gQ29weSBvcHRpb25zLgorICBpZiAoIXByb3RvLmhhc19vcHRpb25zKCkpIHsKKyAgICByZXN1bHQtPm9wdGlvbnNfID0gTlVMTDsgIC8vIFdpbGwgc2V0IHRvIGRlZmF1bHRfaW5zdGFuY2UgbGF0ZXIuCisgIH0gZWxzZSB7CisgICAgQWxsb2NhdGVPcHRpb25zKHByb3RvLm9wdGlvbnMoKSwgcmVzdWx0KTsKKyAgfQorCisgIEFkZFN5bWJvbChyZXN1bHQtPmZ1bGxfbmFtZSgpLCBwYXJlbnQsIHJlc3VsdC0+bmFtZSgpLAorICAgICAgICAgICAgcHJvdG8sIFN5bWJvbChyZXN1bHQpKTsKK30KKwordm9pZCBEZXNjcmlwdG9yQnVpbGRlcjo6QnVpbGRFbnVtVmFsdWUoY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvJiBwcm90bywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBwYXJlbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbnVtVmFsdWVEZXNjcmlwdG9yKiByZXN1bHQpIHsKKyAgcmVzdWx0LT5uYW1lXyAgID0gdGFibGVzXy0+QWxsb2NhdGVTdHJpbmcocHJvdG8ubmFtZSgpKTsKKyAgcmVzdWx0LT5udW1iZXJfID0gcHJvdG8ubnVtYmVyKCk7CisgIHJlc3VsdC0+dHlwZV8gICA9IHBhcmVudDsKKworICAvLyBOb3RlOiAgZnVsbF9uYW1lIGZvciBlbnVtIHZhbHVlcyBpcyBhIHNpYmxpbmcgdG8gdGhlIHBhcmVudCdzIG5hbWUsIG5vdCBhCisgIC8vICAgY2hpbGQgb2YgaXQuCisgIHN0cmluZyogZnVsbF9uYW1lID0gdGFibGVzXy0+QWxsb2NhdGVTdHJpbmcoKnBhcmVudC0+ZnVsbF9uYW1lXyk7CisgIGZ1bGxfbmFtZS0+cmVzaXplKGZ1bGxfbmFtZS0+c2l6ZSgpIC0gcGFyZW50LT5uYW1lXy0+c2l6ZSgpKTsKKyAgZnVsbF9uYW1lLT5hcHBlbmQoKnJlc3VsdC0+bmFtZV8pOworICByZXN1bHQtPmZ1bGxfbmFtZV8gPSBmdWxsX25hbWU7CisKKyAgVmFsaWRhdGVTeW1ib2xOYW1lKHByb3RvLm5hbWUoKSwgKmZ1bGxfbmFtZSwgcHJvdG8pOworCisgIC8vIENvcHkgb3B0aW9ucy4KKyAgaWYgKCFwcm90by5oYXNfb3B0aW9ucygpKSB7CisgICAgcmVzdWx0LT5vcHRpb25zXyA9IE5VTEw7ICAvLyBXaWxsIHNldCB0byBkZWZhdWx0X2luc3RhbmNlIGxhdGVyLgorICB9IGVsc2UgeworICAgIEFsbG9jYXRlT3B0aW9ucyhwcm90by5vcHRpb25zKCksIHJlc3VsdCk7CisgIH0KKworICAvLyBBZ2FpbiwgZW51bSB2YWx1ZXMgYXJlIHdlaXJkIGJlY2F1c2Ugd2UgbWFrZXMgdGhlbSBhcHBlYXIgYXMgc2libGluZ3MKKyAgLy8gb2YgdGhlIGVudW0gdHlwZSBpbnN0ZWFkIG9mIGNoaWxkcmVuIG9mIGl0LiAgU28sIHdlIHVzZQorICAvLyBwYXJlbnQtPmNvbnRhaW5pbmdfdHlwZSgpIGFzIHRoZSB2YWx1ZSdzIHBhcmVudC4KKyAgYm9vbCBhZGRlZF90b19vdXRlcl9zY29wZSA9CisgICAgQWRkU3ltYm9sKHJlc3VsdC0+ZnVsbF9uYW1lKCksIHBhcmVudC0+Y29udGFpbmluZ190eXBlKCksIHJlc3VsdC0+bmFtZSgpLAorICAgICAgICAgICAgICBwcm90bywgU3ltYm9sKHJlc3VsdCkpOworCisgIC8vIEhvd2V2ZXIsIHdlIGFsc28gd2FudCB0byBiZSBhYmxlIHRvIHNlYXJjaCBmb3IgdmFsdWVzIHdpdGhpbiBhIHNpbmdsZQorICAvLyBlbnVtIHR5cGUsIHNvIHdlIGFkZCBpdCBhcyBhIGNoaWxkIG9mIHRoZSBlbnVtIHR5cGUgaXRzZWxmLCB0b28uCisgIC8vIE5vdGU6ICBUaGlzIGNvdWxkIGZhaWwsIGJ1dCBpZiBpdCBkb2VzLCB0aGUgZXJyb3IgaGFzIGFscmVhZHkgYmVlbgorICAvLyAgIHJlcG9ydGVkIGJ5IHRoZSBhYm92ZSBBZGRTeW1ib2woKSBjYWxsLCBzbyB3ZSBpZ25vcmUgdGhlIHJldHVybiBjb2RlLgorICBib29sIGFkZGVkX3RvX2lubmVyX3Njb3BlID0KKyAgICBmaWxlX3RhYmxlc18tPkFkZEFsaWFzVW5kZXJQYXJlbnQocGFyZW50LCByZXN1bHQtPm5hbWUoKSwgU3ltYm9sKHJlc3VsdCkpOworCisgIGlmIChhZGRlZF90b19pbm5lcl9zY29wZSAmJiAhYWRkZWRfdG9fb3V0ZXJfc2NvcGUpIHsKKyAgICAvLyBUaGlzIHZhbHVlIGRpZCBub3QgY29uZmxpY3Qgd2l0aCBhbnkgdmFsdWVzIGRlZmluZWQgaW4gdGhlIHNhbWUgZW51bSwKKyAgICAvLyBidXQgaXQgZGlkIGNvbmZsaWN0IHdpdGggc29tZSBvdGhlciBzeW1ib2wgZGVmaW5lZCBpbiB0aGUgZW51bSB0eXBlJ3MKKyAgICAvLyBzY29wZS4gIExldCdzIHByaW50IGFuIGFkZGl0aW9uYWwgZXJyb3IgdG8gZXhwbGFpbiB0aGlzLgorICAgIHN0cmluZyBvdXRlcl9zY29wZTsKKyAgICBpZiAocGFyZW50LT5jb250YWluaW5nX3R5cGUoKSA9PSBOVUxMKSB7CisgICAgICBvdXRlcl9zY29wZSA9IGZpbGVfLT5wYWNrYWdlKCk7CisgICAgfSBlbHNlIHsKKyAgICAgIG91dGVyX3Njb3BlID0gcGFyZW50LT5jb250YWluaW5nX3R5cGUoKS0+ZnVsbF9uYW1lKCk7CisgICAgfQorCisgICAgaWYgKG91dGVyX3Njb3BlLmVtcHR5KCkpIHsKKyAgICAgIG91dGVyX3Njb3BlID0gInRoZSBnbG9iYWwgc2NvcGUiOworICAgIH0gZWxzZSB7CisgICAgICBvdXRlcl9zY29wZSA9ICJcIiIgKyBvdXRlcl9zY29wZSArICJcIiI7CisgICAgfQorCisgICAgQWRkRXJyb3IocmVzdWx0LT5mdWxsX25hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpOQU1FLAorICAgICAgICAgICAgICJOb3RlIHRoYXQgZW51bSB2YWx1ZXMgdXNlIEMrKyBzY29waW5nIHJ1bGVzLCBtZWFuaW5nIHRoYXQgIgorICAgICAgICAgICAgICJlbnVtIHZhbHVlcyBhcmUgc2libGluZ3Mgb2YgdGhlaXIgdHlwZSwgbm90IGNoaWxkcmVuIG9mIGl0LiAgIgorICAgICAgICAgICAgICJUaGVyZWZvcmUsIFwiIiArIHJlc3VsdC0+bmFtZSgpICsgIlwiIG11c3QgYmUgdW5pcXVlIHdpdGhpbiAiCisgICAgICAgICAgICAgKyBvdXRlcl9zY29wZSArICIsIG5vdCBqdXN0IHdpdGhpbiBcIiIgKyBwYXJlbnQtPm5hbWUoKSArICJcIi4iKTsKKyAgfQorCisgIC8vIEFuIGVudW0gaXMgYWxsb3dlZCB0byBkZWZpbmUgdHdvIG51bWJlcnMgdGhhdCByZWZlciB0byB0aGUgc2FtZSB2YWx1ZS4KKyAgLy8gRmluZFZhbHVlQnlOdW1iZXIoKSBzaG91bGQgcmV0dXJuIHRoZSBmaXJzdCBzdWNoIHZhbHVlLCBzbyB3ZSBzaW1wbHkKKyAgLy8gaWdub3JlIEFkZEVudW1WYWx1ZUJ5TnVtYmVyKCkncyByZXR1cm4gY29kZS4KKyAgZmlsZV90YWJsZXNfLT5BZGRFbnVtVmFsdWVCeU51bWJlcihyZXN1bHQpOworfQorCit2b2lkIERlc2NyaXB0b3JCdWlsZGVyOjpCdWlsZFNlcnZpY2UoY29uc3QgU2VydmljZURlc2NyaXB0b3JQcm90byYgcHJvdG8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgdm9pZCogLyogZHVtbXkgKi8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2VydmljZURlc2NyaXB0b3IqIHJlc3VsdCkgeworICBzdHJpbmcqIGZ1bGxfbmFtZSA9IHRhYmxlc18tPkFsbG9jYXRlU3RyaW5nKGZpbGVfLT5wYWNrYWdlKCkpOworICBpZiAoIWZ1bGxfbmFtZS0+ZW1wdHkoKSkgZnVsbF9uYW1lLT5hcHBlbmQoMSwgJy4nKTsKKyAgZnVsbF9uYW1lLT5hcHBlbmQocHJvdG8ubmFtZSgpKTsKKworICBWYWxpZGF0ZVN5bWJvbE5hbWUocHJvdG8ubmFtZSgpLCAqZnVsbF9uYW1lLCBwcm90byk7CisKKyAgcmVzdWx0LT5uYW1lXyAgICAgID0gdGFibGVzXy0+QWxsb2NhdGVTdHJpbmcocHJvdG8ubmFtZSgpKTsKKyAgcmVzdWx0LT5mdWxsX25hbWVfID0gZnVsbF9uYW1lOworICByZXN1bHQtPmZpbGVfICAgICAgPSBmaWxlXzsKKworICBCVUlMRF9BUlJBWShwcm90bywgcmVzdWx0LCBtZXRob2QsIEJ1aWxkTWV0aG9kLCByZXN1bHQpOworCisgIC8vIENvcHkgb3B0aW9ucy4KKyAgaWYgKCFwcm90by5oYXNfb3B0aW9ucygpKSB7CisgICAgcmVzdWx0LT5vcHRpb25zXyA9IE5VTEw7ICAvLyBXaWxsIHNldCB0byBkZWZhdWx0X2luc3RhbmNlIGxhdGVyLgorICB9IGVsc2UgeworICAgIEFsbG9jYXRlT3B0aW9ucyhwcm90by5vcHRpb25zKCksIHJlc3VsdCk7CisgIH0KKworICBBZGRTeW1ib2wocmVzdWx0LT5mdWxsX25hbWUoKSwgTlVMTCwgcmVzdWx0LT5uYW1lKCksCisgICAgICAgICAgICBwcm90bywgU3ltYm9sKHJlc3VsdCkpOworfQorCit2b2lkIERlc2NyaXB0b3JCdWlsZGVyOjpCdWlsZE1ldGhvZChjb25zdCBNZXRob2REZXNjcmlwdG9yUHJvdG8mIHByb3RvLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgU2VydmljZURlc2NyaXB0b3IqIHBhcmVudCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1ldGhvZERlc2NyaXB0b3IqIHJlc3VsdCkgeworICByZXN1bHQtPm5hbWVfICAgID0gdGFibGVzXy0+QWxsb2NhdGVTdHJpbmcocHJvdG8ubmFtZSgpKTsKKyAgcmVzdWx0LT5zZXJ2aWNlXyA9IHBhcmVudDsKKworICBzdHJpbmcqIGZ1bGxfbmFtZSA9IHRhYmxlc18tPkFsbG9jYXRlU3RyaW5nKHBhcmVudC0+ZnVsbF9uYW1lKCkpOworICBmdWxsX25hbWUtPmFwcGVuZCgxLCAnLicpOworICBmdWxsX25hbWUtPmFwcGVuZCgqcmVzdWx0LT5uYW1lXyk7CisgIHJlc3VsdC0+ZnVsbF9uYW1lXyA9IGZ1bGxfbmFtZTsKKworICBWYWxpZGF0ZVN5bWJvbE5hbWUocHJvdG8ubmFtZSgpLCAqZnVsbF9uYW1lLCBwcm90byk7CisKKyAgLy8gVGhlc2Ugd2lsbCBiZSBmaWxsZWQgaW4gd2hlbiBjcm9zcy1saW5raW5nLgorICByZXN1bHQtPmlucHV0X3R5cGVfID0gTlVMTDsKKyAgcmVzdWx0LT5vdXRwdXRfdHlwZV8gPSBOVUxMOworCisgIC8vIENvcHkgb3B0aW9ucy4KKyAgaWYgKCFwcm90by5oYXNfb3B0aW9ucygpKSB7CisgICAgcmVzdWx0LT5vcHRpb25zXyA9IE5VTEw7ICAvLyBXaWxsIHNldCB0byBkZWZhdWx0X2luc3RhbmNlIGxhdGVyLgorICB9IGVsc2UgeworICAgIEFsbG9jYXRlT3B0aW9ucyhwcm90by5vcHRpb25zKCksIHJlc3VsdCk7CisgIH0KKworICByZXN1bHQtPmNsaWVudF9zdHJlYW1pbmdfID0gcHJvdG8uY2xpZW50X3N0cmVhbWluZygpOworICByZXN1bHQtPnNlcnZlcl9zdHJlYW1pbmdfID0gcHJvdG8uc2VydmVyX3N0cmVhbWluZygpOworCisgIEFkZFN5bWJvbChyZXN1bHQtPmZ1bGxfbmFtZSgpLCBwYXJlbnQsIHJlc3VsdC0+bmFtZSgpLAorICAgICAgICAgICAgcHJvdG8sIFN5bWJvbChyZXN1bHQpKTsKK30KKworI3VuZGVmIEJVSUxEX0FSUkFZCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBEZXNjcmlwdG9yQnVpbGRlcjo6Q3Jvc3NMaW5rRmlsZSgKKyAgICBGaWxlRGVzY3JpcHRvciogZmlsZSwgY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byYgcHJvdG8pIHsKKyAgaWYgKGZpbGUtPm9wdGlvbnNfID09IE5VTEwpIHsKKyAgICBmaWxlLT5vcHRpb25zXyA9ICZGaWxlT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZSgpOworICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlLT5tZXNzYWdlX3R5cGVfY291bnQoKTsgaSsrKSB7CisgICAgQ3Jvc3NMaW5rTWVzc2FnZSgmZmlsZS0+bWVzc2FnZV90eXBlc19baV0sIHByb3RvLm1lc3NhZ2VfdHlwZShpKSk7CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGUtPmV4dGVuc2lvbl9jb3VudCgpOyBpKyspIHsKKyAgICBDcm9zc0xpbmtGaWVsZCgmZmlsZS0+ZXh0ZW5zaW9uc19baV0sIHByb3RvLmV4dGVuc2lvbihpKSk7CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGUtPmVudW1fdHlwZV9jb3VudCgpOyBpKyspIHsKKyAgICBDcm9zc0xpbmtFbnVtKCZmaWxlLT5lbnVtX3R5cGVzX1tpXSwgcHJvdG8uZW51bV90eXBlKGkpKTsKKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZS0+c2VydmljZV9jb3VudCgpOyBpKyspIHsKKyAgICBDcm9zc0xpbmtTZXJ2aWNlKCZmaWxlLT5zZXJ2aWNlc19baV0sIHByb3RvLnNlcnZpY2UoaSkpOworICB9Cit9CisKK3ZvaWQgRGVzY3JpcHRvckJ1aWxkZXI6OkNyb3NzTGlua01lc3NhZ2UoCisgICAgRGVzY3JpcHRvciogbWVzc2FnZSwgY29uc3QgRGVzY3JpcHRvclByb3RvJiBwcm90bykgeworICBpZiAobWVzc2FnZS0+b3B0aW9uc18gPT0gTlVMTCkgeworICAgIG1lc3NhZ2UtPm9wdGlvbnNfID0gJk1lc3NhZ2VPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlKCk7CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IG1lc3NhZ2UtPm5lc3RlZF90eXBlX2NvdW50KCk7IGkrKykgeworICAgIENyb3NzTGlua01lc3NhZ2UoJm1lc3NhZ2UtPm5lc3RlZF90eXBlc19baV0sIHByb3RvLm5lc3RlZF90eXBlKGkpKTsKKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZS0+ZW51bV90eXBlX2NvdW50KCk7IGkrKykgeworICAgIENyb3NzTGlua0VudW0oJm1lc3NhZ2UtPmVudW1fdHlwZXNfW2ldLCBwcm90by5lbnVtX3R5cGUoaSkpOworICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZXNzYWdlLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBDcm9zc0xpbmtGaWVsZCgmbWVzc2FnZS0+ZmllbGRzX1tpXSwgcHJvdG8uZmllbGQoaSkpOworICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZXNzYWdlLT5leHRlbnNpb25fY291bnQoKTsgaSsrKSB7CisgICAgQ3Jvc3NMaW5rRmllbGQoJm1lc3NhZ2UtPmV4dGVuc2lvbnNfW2ldLCBwcm90by5leHRlbnNpb24oaSkpOworICB9CisKKyAgLy8gU2V0IHVwIGZpZWxkIGFycmF5IGZvciBlYWNoIG9uZW9mLgorCisgIC8vIEZpcnN0IGNvdW50IHRoZSBudW1iZXIgb2YgZmllbGRzIHBlciBvbmVvZi4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZXNzYWdlLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBPbmVvZkRlc2NyaXB0b3IqIG9uZW9mX2RlY2wgPSBtZXNzYWdlLT5maWVsZChpKS0+Y29udGFpbmluZ19vbmVvZigpOworICAgIGlmIChvbmVvZl9kZWNsICE9IE5VTEwpIHsKKyAgICAgIC8vIE1ha2Ugc3VyZSBmaWVsZHMgYmVsb25naW5nIHRvIHRoZSBzYW1lIG9uZW9mIGFyZSBkZWZpbmVkIGNvbnNlY3V0aXZlbHkuCisgICAgICAvLyBUaGlzIGVuYWJsZXMgb3B0aW1pemF0aW9ucyBpbiBjb2RlZ2VucyBhbmQgcmVmbGVjdGlvbiBsaWJyYXJpZXMgdG8KKyAgICAgIC8vIHNraXAgZmllbGRzIGluIHRoZSBvbmVvZiBncm91cCwgYXMgb25seSBvbmUgb2YgdGhlIGZpZWxkIGNhbiBiZSBzZXQuCisgICAgICAvLyBOb3RlIHRoYXQgZmllbGRfY291bnQoKSByZXR1cm5zIGhvdyBtYW55IGZpZWxkcyBpbiB0aGlzIG9uZW9mIHdlIGhhdmUKKyAgICAgIC8vIHNlZW4gc28gZmFyLiBmaWVsZF9jb3VudCgpID4gMCBndWFyYW50ZWVzIHRoYXQgaSA+IDAsIHNvIGZpZWxkKGktMSkgaXMKKyAgICAgIC8vIHNhZmUuCisgICAgICBpZiAob25lb2ZfZGVjbC0+ZmllbGRfY291bnQoKSA+IDAgJiYKKyAgICAgICAgICBtZXNzYWdlLT5maWVsZChpIC0gMSktPmNvbnRhaW5pbmdfb25lb2YoKSAhPSBvbmVvZl9kZWNsKSB7CisgICAgICAgIEFkZEVycm9yKAorICAgICAgICAgICAgbWVzc2FnZS0+ZnVsbF9uYW1lKCkgKyAiLiIgKyBtZXNzYWdlLT5maWVsZChpIC0gMSktPm5hbWUoKSwKKyAgICAgICAgICAgIHByb3RvLmZpZWxkKGkgLSAxKSwgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpPVEhFUiwKKyAgICAgICAgICAgIHN0cmluZ3M6OlN1YnN0aXR1dGUoCisgICAgICAgICAgICAgICAgIkZpZWxkcyBpbiB0aGUgc2FtZSBvbmVvZiBtdXN0IGJlIGRlZmluZWQgY29uc2VjdXRpdmVseS4gIgorICAgICAgICAgICAgICAgICJcIiQwXCIgY2Fubm90IGJlIGRlZmluZWQgYmVmb3JlIHRoZSBjb21wbGV0aW9uIG9mIHRoZSAiCisgICAgICAgICAgICAgICAgIlwiJDFcIiBvbmVvZiBkZWZpbml0aW9uLiIsCisgICAgICAgICAgICAgICAgbWVzc2FnZS0+ZmllbGQoaSAtIDEpLT5uYW1lKCksIG9uZW9mX2RlY2wtPm5hbWUoKSkpOworICAgICAgfQorICAgICAgLy8gTXVzdCBnbyB0aHJvdWdoIG9uZW9mX2RlY2xzXyBhcnJheSB0byBnZXQgYSBub24tY29uc3QgdmVyc2lvbiBvZiB0aGUKKyAgICAgIC8vIE9uZW9mRGVzY3JpcHRvci4KKyAgICAgICsrbWVzc2FnZS0+b25lb2ZfZGVjbHNfW29uZW9mX2RlY2wtPmluZGV4KCldLmZpZWxkX2NvdW50XzsKKyAgICB9CisgIH0KKworICAvLyBUaGVuIGFsbG9jYXRlIHRoZSBhcnJheXMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZS0+b25lb2ZfZGVjbF9jb3VudCgpOyBpKyspIHsKKyAgICBPbmVvZkRlc2NyaXB0b3IqIG9uZW9mX2RlY2wgPSAmbWVzc2FnZS0+b25lb2ZfZGVjbHNfW2ldOworCisgICAgaWYgKG9uZW9mX2RlY2wtPmZpZWxkX2NvdW50KCkgPT0gMCkgeworICAgICAgQWRkRXJyb3IobWVzc2FnZS0+ZnVsbF9uYW1lKCkgKyAiLiIgKyBvbmVvZl9kZWNsLT5uYW1lKCksCisgICAgICAgICAgICAgICBwcm90by5vbmVvZl9kZWNsKGkpLAorICAgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpOQU1FLAorICAgICAgICAgICAgICAgIk9uZW9mIG11c3QgaGF2ZSBhdCBsZWFzdCBvbmUgZmllbGQuIik7CisgICAgfQorCisgICAgb25lb2ZfZGVjbC0+ZmllbGRzXyA9CisgICAgICB0YWJsZXNfLT5BbGxvY2F0ZUFycmF5PGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+KG9uZW9mX2RlY2wtPmZpZWxkX2NvdW50Xyk7CisgICAgb25lb2ZfZGVjbC0+ZmllbGRfY291bnRfID0gMDsKKyAgfQorCisgIC8vIFRoZW4gZmlsbCB0aGVtIGluLgorICBmb3IgKGludCBpID0gMDsgaSA8IG1lc3NhZ2UtPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IE9uZW9mRGVzY3JpcHRvciogb25lb2ZfZGVjbCA9IG1lc3NhZ2UtPmZpZWxkKGkpLT5jb250YWluaW5nX29uZW9mKCk7CisgICAgaWYgKG9uZW9mX2RlY2wgIT0gTlVMTCkgeworICAgICAgT25lb2ZEZXNjcmlwdG9yKiBtdXRhYmxlX29uZW9mX2RlY2wgPQorICAgICAgICAgICZtZXNzYWdlLT5vbmVvZl9kZWNsc19bb25lb2ZfZGVjbC0+aW5kZXgoKV07CisgICAgICBtZXNzYWdlLT5maWVsZHNfW2ldLmluZGV4X2luX29uZW9mXyA9IG11dGFibGVfb25lb2ZfZGVjbC0+ZmllbGRfY291bnRfOworICAgICAgbXV0YWJsZV9vbmVvZl9kZWNsLT5maWVsZHNfW211dGFibGVfb25lb2ZfZGVjbC0+ZmllbGRfY291bnRfKytdID0KKyAgICAgICAgICBtZXNzYWdlLT5maWVsZChpKTsKKyAgICB9CisgIH0KK30KKwordm9pZCBEZXNjcmlwdG9yQnVpbGRlcjo6Q3Jvc3NMaW5rRmllbGQoCisgICAgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG8mIHByb3RvKSB7CisgIGlmIChmaWVsZC0+b3B0aW9uc18gPT0gTlVMTCkgeworICAgIGZpZWxkLT5vcHRpb25zXyA9ICZGaWVsZE9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2UoKTsKKyAgfQorCisgIGlmIChwcm90by5oYXNfZXh0ZW5kZWUoKSkgeworICAgIFN5bWJvbCBleHRlbmRlZSA9IExvb2t1cFN5bWJvbChwcm90by5leHRlbmRlZSgpLCBmaWVsZC0+ZnVsbF9uYW1lKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBMQUNFSE9MREVSX0VYVEVOREFCTEVfTUVTU0FHRSk7CisgICAgaWYgKGV4dGVuZGVlLklzTnVsbCgpKSB7CisgICAgICBBZGROb3REZWZpbmVkRXJyb3IoZmllbGQtPmZ1bGxfbmFtZSgpLCBwcm90bywKKyAgICAgICAgICAgICAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6OkVYVEVOREVFLAorICAgICAgICAgICAgICAgICAgICAgICAgIHByb3RvLmV4dGVuZGVlKCkpOworICAgICAgcmV0dXJuOworICAgIH0gZWxzZSBpZiAoZXh0ZW5kZWUudHlwZSAhPSBTeW1ib2w6Ok1FU1NBR0UpIHsKKyAgICAgIEFkZEVycm9yKGZpZWxkLT5mdWxsX25hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6OkVYVEVOREVFLAorICAgICAgICAgICAgICAgIlwiIiArIHByb3RvLmV4dGVuZGVlKCkgKyAiXCIgaXMgbm90IGEgbWVzc2FnZSB0eXBlLiIpOworICAgICAgcmV0dXJuOworICAgIH0KKyAgICBmaWVsZC0+Y29udGFpbmluZ190eXBlXyA9IGV4dGVuZGVlLmRlc2NyaXB0b3I7CisKKyAgICBjb25zdCBEZXNjcmlwdG9yOjpFeHRlbnNpb25SYW5nZSogZXh0ZW5zaW9uX3JhbmdlID0gZmllbGQtPmNvbnRhaW5pbmdfdHlwZSgpCisgICAgICAgIC0+RmluZEV4dGVuc2lvblJhbmdlQ29udGFpbmluZ051bWJlcihmaWVsZC0+bnVtYmVyKCkpOworCisgICAgaWYgKGV4dGVuc2lvbl9yYW5nZSA9PSBOVUxMKSB7CisgICAgICBBZGRFcnJvcihmaWVsZC0+ZnVsbF9uYW1lKCksIHByb3RvLAorICAgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpOVU1CRVIsCisgICAgICAgICAgICAgICBzdHJpbmdzOjpTdWJzdGl0dXRlKCJcIiQwXCIgZG9lcyBub3QgZGVjbGFyZSAkMSBhcyBhbiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJleHRlbnNpb24gbnVtYmVyLiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkLT5jb250YWluaW5nX3R5cGUoKS0+ZnVsbF9uYW1lKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkLT5udW1iZXIoKSkpOworICAgIH0KKyAgfQorCisgIGlmIChmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpICE9IE5VTEwpIHsKKyAgICBpZiAoZmllbGQtPmxhYmVsKCkgIT0gRmllbGREZXNjcmlwdG9yOjpMQUJFTF9PUFRJT05BTCkgeworICAgICAgLy8gTm90ZSB0aGF0IHRoaXMgZXJyb3Igd2lsbCBuZXZlciBoYXBwZW4gd2hlbiBwYXJzaW5nIC5wcm90byBmaWxlcy4KKyAgICAgIC8vIEl0IGNhbiBvbmx5IGhhcHBlbiBpZiB5b3UgbWFudWFsbHkgY29uc3RydWN0IGEgRmlsZURlc2NyaXB0b3JQcm90bworICAgICAgLy8gdGhhdCBpcyBpbmNvcnJlY3QuCisgICAgICBBZGRFcnJvcihmaWVsZC0+ZnVsbF9uYW1lKCksIHByb3RvLAorICAgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpOQU1FLAorICAgICAgICAgICAgICAgIkZpZWxkcyBvZiBvbmVvZnMgbXVzdCB0aGVtc2VsdmVzIGhhdmUgbGFiZWwgTEFCRUxfT1BUSU9OQUwuIik7CisgICAgfQorICB9CisKKyAgaWYgKHByb3RvLmhhc190eXBlX25hbWUoKSkgeworICAgIC8vIEFzc3VtZSB3ZSBhcmUgZXhwZWN0aW5nIGEgbWVzc2FnZSB0eXBlIHVubGVzcyB0aGUgcHJvdG8gY29udGFpbnMgc29tZQorICAgIC8vIGV2aWRlbmNlIHRoYXQgaXQgZXhwZWN0cyBhbiBlbnVtIHR5cGUuICBUaGlzIG9ubHkgbWFrZXMgYSBkaWZmZXJlbmNlIGlmCisgICAgLy8gd2UgZW5kIHVwIGNyZWF0aW5nIGEgcGxhY2Vob2xkZXIuCisgICAgYm9vbCBleHBlY3RpbmdfZW51bSA9IChwcm90by50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfRU5VTSkgfHwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdG8uaGFzX2RlZmF1bHRfdmFsdWUoKTsKKworICAgIFN5bWJvbCB0eXBlID0KKyAgICAgIExvb2t1cFN5bWJvbChwcm90by50eXBlX25hbWUoKSwgZmllbGQtPmZ1bGxfbmFtZSgpLAorICAgICAgICAgICAgICAgICAgIGV4cGVjdGluZ19lbnVtID8gUExBQ0VIT0xERVJfRU5VTSA6IFBMQUNFSE9MREVSX01FU1NBR0UsCisgICAgICAgICAgICAgICAgICAgTE9PS1VQX1RZUEVTKTsKKworICAgIC8vIElmIHRoZSB0eXBlIGlzIGEgd2VhayB0eXBlLCB3ZSBjaGFuZ2UgdGhlIHR5cGUgdG8gYSBnb29nbGUucHJvdG9idWYuRW1wdHkgZmllbGQuCisgICAgaWYgKHR5cGUuSXNOdWxsKCkgJiYgIXBvb2xfLT5lbmZvcmNlX3dlYWtfICYmIHByb3RvLm9wdGlvbnMoKS53ZWFrKCkpIHsKKyAgICAgIHR5cGUgPSBGaW5kU3ltYm9sKGtOb25MaW5rZWRXZWFrTWVzc2FnZVJlcGxhY2VtZW50TmFtZSk7CisgICAgfQorCisgICAgaWYgKHR5cGUuSXNOdWxsKCkpIHsKKyAgICAgIEFkZE5vdERlZmluZWRFcnJvcihmaWVsZC0+ZnVsbF9uYW1lKCksIHByb3RvLAorICAgICAgICAgICAgICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6VFlQRSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBwcm90by50eXBlX25hbWUoKSk7CisgICAgICByZXR1cm47CisgICAgfQorCisgICAgaWYgKCFwcm90by5oYXNfdHlwZSgpKSB7CisgICAgICAvLyBDaG9vc2UgZmllbGQgdHlwZSBiYXNlZCBvbiBzeW1ib2wuCisgICAgICBpZiAodHlwZS50eXBlID09IFN5bWJvbDo6TUVTU0FHRSkgeworICAgICAgICBmaWVsZC0+dHlwZV8gPSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfTUVTU0FHRTsKKyAgICAgIH0gZWxzZSBpZiAodHlwZS50eXBlID09IFN5bWJvbDo6RU5VTSkgeworICAgICAgICBmaWVsZC0+dHlwZV8gPSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRU5VTTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIEFkZEVycm9yKGZpZWxkLT5mdWxsX25hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6VFlQRSwKKyAgICAgICAgICAgICAgICAgIlwiIiArIHByb3RvLnR5cGVfbmFtZSgpICsgIlwiIGlzIG5vdCBhIHR5cGUuIik7CisgICAgICAgIHJldHVybjsKKyAgICAgIH0KKyAgICB9CisKKyAgICBpZiAoZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UpIHsKKyAgICAgIGlmICh0eXBlLnR5cGUgIT0gU3ltYm9sOjpNRVNTQUdFKSB7CisgICAgICAgIEFkZEVycm9yKGZpZWxkLT5mdWxsX25hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6VFlQRSwKKyAgICAgICAgICAgICAgICAgIlwiIiArIHByb3RvLnR5cGVfbmFtZSgpICsgIlwiIGlzIG5vdCBhIG1lc3NhZ2UgdHlwZS4iKTsKKyAgICAgICAgcmV0dXJuOworICAgICAgfQorICAgICAgZmllbGQtPm1lc3NhZ2VfdHlwZV8gPSB0eXBlLmRlc2NyaXB0b3I7CisKKyAgICAgIGlmIChmaWVsZC0+aGFzX2RlZmF1bHRfdmFsdWUoKSkgeworICAgICAgICBBZGRFcnJvcihmaWVsZC0+ZnVsbF9uYW1lKCksIHByb3RvLAorICAgICAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6OkRFRkFVTFRfVkFMVUUsCisgICAgICAgICAgICAgICAgICJNZXNzYWdlcyBjYW4ndCBoYXZlIGRlZmF1bHQgdmFsdWVzLiIpOworICAgICAgfQorICAgIH0gZWxzZSBpZiAoZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0VOVU0pIHsKKyAgICAgIGlmICh0eXBlLnR5cGUgIT0gU3ltYm9sOjpFTlVNKSB7CisgICAgICAgIEFkZEVycm9yKGZpZWxkLT5mdWxsX25hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6VFlQRSwKKyAgICAgICAgICAgICAgICAgIlwiIiArIHByb3RvLnR5cGVfbmFtZSgpICsgIlwiIGlzIG5vdCBhbiBlbnVtIHR5cGUuIik7CisgICAgICAgIHJldHVybjsKKyAgICAgIH0KKyAgICAgIGZpZWxkLT5lbnVtX3R5cGVfID0gdHlwZS5lbnVtX2Rlc2NyaXB0b3I7CisKKyAgICAgIGlmIChmaWVsZC0+ZW51bV90eXBlKCktPmlzX3BsYWNlaG9sZGVyXykgeworICAgICAgICAvLyBXZSBjYW4ndCBsb29rIHVwIGRlZmF1bHQgdmFsdWVzIGZvciBwbGFjZWhvbGRlciB0eXBlcy4gIFdlJ2xsIGhhdmUKKyAgICAgICAgLy8gdG8ganVzdCBkcm9wIHRoZW0uCisgICAgICAgIGZpZWxkLT5oYXNfZGVmYXVsdF92YWx1ZV8gPSBmYWxzZTsKKyAgICAgIH0KKworICAgICAgaWYgKGZpZWxkLT5oYXNfZGVmYXVsdF92YWx1ZSgpKSB7CisgICAgICAgIC8vIEVuc3VyZSB0aGF0IHRoZSBkZWZhdWx0IHZhbHVlIGlzIGFuIGlkZW50aWZpZXIuIFBhcnNlciBjYW5ub3QgYWx3YXlzCisgICAgICAgIC8vIHZlcmlmeSB0aGlzIGJlY2F1c2UgaXQgZG9lcyBub3QgaGF2ZSBjb21wbGV0ZSB0eXBlIGluZm9ybWF0aW9uLgorICAgICAgICAvLyBOLkIuIHRoYXQgdGhpcyBjaGVjayB5aWVsZHMgYmV0dGVyIGVycm9yIG1lc3NhZ2VzIGJ1dCBpcyBub3QKKyAgICAgICAgLy8gbmVjZXNzYXJ5IGZvciBjb3JyZWN0bmVzcyAoYW4gZW51bSBzeW1ib2wgbXVzdCBiZSBhIHZhbGlkIGlkZW50aWZpZXIKKyAgICAgICAgLy8gYW55d2F5KSwgb25seSBmb3IgYmV0dGVyIGVycm9ycy4KKyAgICAgICAgaWYgKCFpbzo6VG9rZW5pemVyOjpJc0lkZW50aWZpZXIocHJvdG8uZGVmYXVsdF92YWx1ZSgpKSkgeworICAgICAgICAgIEFkZEVycm9yKGZpZWxkLT5mdWxsX25hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpERUZBVUxUX1ZBTFVFLAorICAgICAgICAgICAgICAgICAgICJEZWZhdWx0IHZhbHVlIGZvciBhbiBlbnVtIGZpZWxkIG11c3QgYmUgYW4gaWRlbnRpZmllci4iKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAvLyBXZSBjYW4ndCBqdXN0IHVzZSBmaWVsZC0+ZW51bV90eXBlKCktPkZpbmRWYWx1ZUJ5TmFtZSgpIGhlcmUKKyAgICAgICAgICAvLyBiZWNhdXNlIHRoYXQgbG9ja3MgdGhlIHBvb2wncyBtdXRleCwgd2hpY2ggd2UgaGF2ZSBhbHJlYWR5IGxvY2tlZAorICAgICAgICAgIC8vIGF0IHRoaXMgcG9pbnQuCisgICAgICAgICAgU3ltYm9sIGRlZmF1bHRfdmFsdWUgPQorICAgICAgICAgICAgTG9va3VwU3ltYm9sTm9QbGFjZWhvbGRlcihwcm90by5kZWZhdWx0X3ZhbHVlKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkLT5lbnVtX3R5cGUoKS0+ZnVsbF9uYW1lKCkpOworCisgICAgICAgICAgaWYgKGRlZmF1bHRfdmFsdWUudHlwZSA9PSBTeW1ib2w6OkVOVU1fVkFMVUUgJiYKKyAgICAgICAgICAgICAgZGVmYXVsdF92YWx1ZS5lbnVtX3ZhbHVlX2Rlc2NyaXB0b3ItPnR5cGUoKSA9PQorICAgICAgICAgICAgICBmaWVsZC0+ZW51bV90eXBlKCkpIHsKKyAgICAgICAgICAgIGZpZWxkLT5kZWZhdWx0X3ZhbHVlX2VudW1fID0gZGVmYXVsdF92YWx1ZS5lbnVtX3ZhbHVlX2Rlc2NyaXB0b3I7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIEFkZEVycm9yKGZpZWxkLT5mdWxsX25hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6OkRFRkFVTFRfVkFMVUUsCisgICAgICAgICAgICAgICAgICAgICAiRW51bSB0eXBlIFwiIiArIGZpZWxkLT5lbnVtX3R5cGUoKS0+ZnVsbF9uYW1lKCkgKworICAgICAgICAgICAgICAgICAgICAgIlwiIGhhcyBubyB2YWx1ZSBuYW1lZCBcIiIgKyBwcm90by5kZWZhdWx0X3ZhbHVlKCkgKworICAgICAgICAgICAgICAgICAgICAgIlwiLiIpOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfSBlbHNlIGlmIChmaWVsZC0+ZW51bV90eXBlKCktPnZhbHVlX2NvdW50KCkgPiAwKSB7CisgICAgICAgIC8vIEFsbCBlbnVtcyBtdXN0IGhhdmUgYXQgbGVhc3Qgb25lIHZhbHVlLCBvciB3ZSB3b3VsZCBoYXZlIHJlcG9ydGVkCisgICAgICAgIC8vIGFuIGVycm9yIGVsc2V3aGVyZS4gIFdlIHVzZSB0aGUgZmlyc3QgZGVmaW5lZCB2YWx1ZSBhcyB0aGUgZGVmYXVsdAorICAgICAgICAvLyBpZiBhIGRlZmF1bHQgaXMgbm90IGV4cGxpY2l0bHkgZGVmaW5lZC4KKyAgICAgICAgZmllbGQtPmRlZmF1bHRfdmFsdWVfZW51bV8gPSBmaWVsZC0+ZW51bV90eXBlKCktPnZhbHVlKDApOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICBBZGRFcnJvcihmaWVsZC0+ZnVsbF9uYW1lKCksIHByb3RvLCBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6OlRZUEUsCisgICAgICAgICAgICAgICAiRmllbGQgd2l0aCBwcmltaXRpdmUgdHlwZSBoYXMgdHlwZV9uYW1lLiIpOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICBpZiAoZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UgfHwKKyAgICAgICAgZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0VOVU0pIHsKKyAgICAgIEFkZEVycm9yKGZpZWxkLT5mdWxsX25hbWUoKSwgcHJvdG8sIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6VFlQRSwKKyAgICAgICAgICAgICAgICJGaWVsZCB3aXRoIG1lc3NhZ2Ugb3IgZW51bSB0eXBlIG1pc3NpbmcgdHlwZV9uYW1lLiIpOworICAgIH0KKyAgfQorCisgIC8vIEFkZCB0aGUgZmllbGQgdG8gdGhlIGZpZWxkcy1ieS1udW1iZXIgdGFibGUuCisgIC8vIE5vdGU6ICBXZSBoYXZlIHRvIGRvIHRoaXMgKmFmdGVyKiBjcm9zcy1saW5raW5nIGJlY2F1c2UgZXh0ZW5zaW9ucyBkbyBub3QKKyAgLy8gICBrbm93IHRoZWlyIGNvbnRhaW5pbmcgdHlwZSB1bnRpbCBub3cuCisgIGlmICghZmlsZV90YWJsZXNfLT5BZGRGaWVsZEJ5TnVtYmVyKGZpZWxkKSkgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogY29uZmxpY3RpbmdfZmllbGQgPQorICAgICAgZmlsZV90YWJsZXNfLT5GaW5kRmllbGRCeU51bWJlcihmaWVsZC0+Y29udGFpbmluZ190eXBlKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkLT5udW1iZXIoKSk7CisgICAgaWYgKGZpZWxkLT5pc19leHRlbnNpb24oKSkgeworICAgICAgQWRkRXJyb3IoZmllbGQtPmZ1bGxfbmFtZSgpLCBwcm90bywKKyAgICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6TlVNQkVSLAorICAgICAgICAgICAgICAgc3RyaW5nczo6U3Vic3RpdHV0ZSgiRXh0ZW5zaW9uIG51bWJlciAkMCBoYXMgYWxyZWFkeSBiZWVuIHVzZWQgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaW4gXCIkMVwiIGJ5IGV4dGVuc2lvbiBcIiQyXCIuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGQtPm51bWJlcigpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZC0+Y29udGFpbmluZ190eXBlKCktPmZ1bGxfbmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25mbGljdGluZ19maWVsZC0+ZnVsbF9uYW1lKCkpKTsKKyAgICB9IGVsc2UgeworICAgICAgQWRkRXJyb3IoZmllbGQtPmZ1bGxfbmFtZSgpLCBwcm90bywKKyAgICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6TlVNQkVSLAorICAgICAgICAgICAgICAgc3RyaW5nczo6U3Vic3RpdHV0ZSgiRmllbGQgbnVtYmVyICQwIGhhcyBhbHJlYWR5IGJlZW4gdXNlZCBpbiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJcIiQxXCIgYnkgZmllbGQgXCIkMlwiLiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkLT5udW1iZXIoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGQtPmNvbnRhaW5pbmdfdHlwZSgpLT5mdWxsX25hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmxpY3RpbmdfZmllbGQtPm5hbWUoKSkpOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICBpZiAoZmllbGQtPmlzX2V4dGVuc2lvbigpKSB7CisgICAgICBpZiAoIXRhYmxlc18tPkFkZEV4dGVuc2lvbihmaWVsZCkpIHsKKyAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBjb25mbGljdGluZ19maWVsZCA9CisgICAgICAgICAgICB0YWJsZXNfLT5GaW5kRXh0ZW5zaW9uKGZpZWxkLT5jb250YWluaW5nX3R5cGUoKSwgZmllbGQtPm51bWJlcigpKTsKKyAgICAgICAgc3RyaW5nIGVycm9yX21zZyA9IHN0cmluZ3M6OlN1YnN0aXR1dGUoCisgICAgICAgICAgICAiRXh0ZW5zaW9uIG51bWJlciAkMCBoYXMgYWxyZWFkeSBiZWVuIHVzZWQgaW4gXCIkMVwiIGJ5IGV4dGVuc2lvbiAiCisgICAgICAgICAgICAiXCIkMlwiIGRlZmluZWQgaW4gJDMuIiwKKyAgICAgICAgICAgIGZpZWxkLT5udW1iZXIoKSwKKyAgICAgICAgICAgIGZpZWxkLT5jb250YWluaW5nX3R5cGUoKS0+ZnVsbF9uYW1lKCksCisgICAgICAgICAgICBjb25mbGljdGluZ19maWVsZC0+ZnVsbF9uYW1lKCksCisgICAgICAgICAgICBjb25mbGljdGluZ19maWVsZC0+ZmlsZSgpLT5uYW1lKCkpOworICAgICAgICAvLyBDb25mbGljdGluZyBleHRlbnNpb24gbnVtYmVycyBzaG91bGQgYmUgYW4gZXJyb3IuIEhvd2V2ZXIsIGJlZm9yZQorICAgICAgICAvLyB0dXJuaW5nIHRoaXMgaW50byBhbiBlcnJvciB3ZSBuZWVkIHRvIGZpeCBhbGwgZXhpc3RpbmcgYnJva2VuCisgICAgICAgIC8vIHByb3RvcyBmaXJzdC4KKyAgICAgICAgLy8gVE9ETyh4aWFvZmVuZyk6IENoYW5nZSB0aGlzIHRvIGFuIGVycm9yLgorICAgICAgICBBZGRXYXJuaW5nKGZpZWxkLT5mdWxsX25hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpOVU1CRVIsIGVycm9yX21zZyk7CisgICAgICB9CisgICAgfQorICB9CisKKyAgLy8gQWRkIHRoZSBmaWVsZCB0byB0aGUgbG93ZXJjYXNlLW5hbWUgYW5kIGNhbWVsY2FzZS1uYW1lIHRhYmxlcy4KKyAgZmlsZV90YWJsZXNfLT5BZGRGaWVsZEJ5U3R5bGl6ZWROYW1lcyhmaWVsZCk7Cit9CisKK3ZvaWQgRGVzY3JpcHRvckJ1aWxkZXI6OkNyb3NzTGlua0VudW0oCisgICAgRW51bURlc2NyaXB0b3IqIGVudW1fdHlwZSwgY29uc3QgRW51bURlc2NyaXB0b3JQcm90byYgcHJvdG8pIHsKKyAgaWYgKGVudW1fdHlwZS0+b3B0aW9uc18gPT0gTlVMTCkgeworICAgIGVudW1fdHlwZS0+b3B0aW9uc18gPSAmRW51bU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2UoKTsKKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZW51bV90eXBlLT52YWx1ZV9jb3VudCgpOyBpKyspIHsKKyAgICBDcm9zc0xpbmtFbnVtVmFsdWUoJmVudW1fdHlwZS0+dmFsdWVzX1tpXSwgcHJvdG8udmFsdWUoaSkpOworICB9Cit9CisKK3ZvaWQgRGVzY3JpcHRvckJ1aWxkZXI6OkNyb3NzTGlua0VudW1WYWx1ZSgKKyAgICBFbnVtVmFsdWVEZXNjcmlwdG9yKiBlbnVtX3ZhbHVlLAorICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3JQcm90byYgLyogcHJvdG8gKi8pIHsKKyAgaWYgKGVudW1fdmFsdWUtPm9wdGlvbnNfID09IE5VTEwpIHsKKyAgICBlbnVtX3ZhbHVlLT5vcHRpb25zXyA9ICZFbnVtVmFsdWVPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlKCk7CisgIH0KK30KKwordm9pZCBEZXNjcmlwdG9yQnVpbGRlcjo6Q3Jvc3NMaW5rU2VydmljZSgKKyAgICBTZXJ2aWNlRGVzY3JpcHRvciogc2VydmljZSwgY29uc3QgU2VydmljZURlc2NyaXB0b3JQcm90byYgcHJvdG8pIHsKKyAgaWYgKHNlcnZpY2UtPm9wdGlvbnNfID09IE5VTEwpIHsKKyAgICBzZXJ2aWNlLT5vcHRpb25zXyA9ICZTZXJ2aWNlT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZSgpOworICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBzZXJ2aWNlLT5tZXRob2RfY291bnQoKTsgaSsrKSB7CisgICAgQ3Jvc3NMaW5rTWV0aG9kKCZzZXJ2aWNlLT5tZXRob2RzX1tpXSwgcHJvdG8ubWV0aG9kKGkpKTsKKyAgfQorfQorCit2b2lkIERlc2NyaXB0b3JCdWlsZGVyOjpDcm9zc0xpbmtNZXRob2QoCisgICAgTWV0aG9kRGVzY3JpcHRvciogbWV0aG9kLCBjb25zdCBNZXRob2REZXNjcmlwdG9yUHJvdG8mIHByb3RvKSB7CisgIGlmIChtZXRob2QtPm9wdGlvbnNfID09IE5VTEwpIHsKKyAgICBtZXRob2QtPm9wdGlvbnNfID0gJk1ldGhvZE9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2UoKTsKKyAgfQorCisgIFN5bWJvbCBpbnB1dF90eXBlID0gTG9va3VwU3ltYm9sKHByb3RvLmlucHV0X3R5cGUoKSwgbWV0aG9kLT5mdWxsX25hbWUoKSk7CisgIGlmIChpbnB1dF90eXBlLklzTnVsbCgpKSB7CisgICAgQWRkTm90RGVmaW5lZEVycm9yKG1ldGhvZC0+ZnVsbF9uYW1lKCksIHByb3RvLAorICAgICAgICAgICAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6OklOUFVUX1RZUEUsCisgICAgICAgICAgICAgICAgICAgICAgIHByb3RvLmlucHV0X3R5cGUoKSk7CisgIH0gZWxzZSBpZiAoaW5wdXRfdHlwZS50eXBlICE9IFN5bWJvbDo6TUVTU0FHRSkgeworICAgIEFkZEVycm9yKG1ldGhvZC0+ZnVsbF9uYW1lKCksIHByb3RvLAorICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6SU5QVVRfVFlQRSwKKyAgICAgICAgICAgICAiXCIiICsgcHJvdG8uaW5wdXRfdHlwZSgpICsgIlwiIGlzIG5vdCBhIG1lc3NhZ2UgdHlwZS4iKTsKKyAgfSBlbHNlIHsKKyAgICBtZXRob2QtPmlucHV0X3R5cGVfID0gaW5wdXRfdHlwZS5kZXNjcmlwdG9yOworICB9CisKKyAgU3ltYm9sIG91dHB1dF90eXBlID0gTG9va3VwU3ltYm9sKHByb3RvLm91dHB1dF90eXBlKCksIG1ldGhvZC0+ZnVsbF9uYW1lKCkpOworICBpZiAob3V0cHV0X3R5cGUuSXNOdWxsKCkpIHsKKyAgICBBZGROb3REZWZpbmVkRXJyb3IobWV0aG9kLT5mdWxsX25hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6T1VUUFVUX1RZUEUsCisgICAgICAgICAgICAgICAgICAgICAgIHByb3RvLm91dHB1dF90eXBlKCkpOworICB9IGVsc2UgaWYgKG91dHB1dF90eXBlLnR5cGUgIT0gU3ltYm9sOjpNRVNTQUdFKSB7CisgICAgQWRkRXJyb3IobWV0aG9kLT5mdWxsX25hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpPVVRQVVRfVFlQRSwKKyAgICAgICAgICAgICAiXCIiICsgcHJvdG8ub3V0cHV0X3R5cGUoKSArICJcIiBpcyBub3QgYSBtZXNzYWdlIHR5cGUuIik7CisgIH0gZWxzZSB7CisgICAgbWV0aG9kLT5vdXRwdXRfdHlwZV8gPSBvdXRwdXRfdHlwZS5kZXNjcmlwdG9yOworICB9Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworI2RlZmluZSBWQUxJREFURV9PUFRJT05TX0ZST01fQVJSQVkoZGVzY3JpcHRvciwgYXJyYXlfbmFtZSwgdHlwZSkgIFwKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yLT5hcnJheV9uYW1lIyNfY291bnQoKTsgKytpKSB7ICAgICBcCisgICAgVmFsaWRhdGUjI3R5cGUjI09wdGlvbnMoZGVzY3JpcHRvci0+YXJyYXlfbmFtZSMjc18gKyBpLCAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3RvLmFycmF5X25hbWUoaSkpOyAgICAgICAgICAgICAgICAgIFwKKyAgfQorCisvLyBEZXRlcm1pbmUgaWYgdGhlIGZpbGUgdXNlcyBvcHRpbWl6ZV9mb3IgPSBMSVRFX1JVTlRJTUUsIGJlaW5nIGNhcmVmdWwgdG8KKy8vIGF2b2lkIHByb2JsZW1zIHRoYXQgZXhpc3QgYXQgaW5pdCB0aW1lLgorc3RhdGljIGJvb2wgSXNMaXRlKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKSB7CisgIC8vIFRPRE8oa2VudG9uKTogIEkgZG9uJ3QgZXZlbiByZW1lbWJlciBob3cgbWFueSBvZiB0aGVzZSBjb25kaXRpb25zIGFyZQorICAvLyAgIGFjdHVhbGx5IHBvc3NpYmxlLiAgSSdtIGp1c3QgYmVpbmcgc3VwZXItc2FmZS4KKyAgcmV0dXJuIGZpbGUgIT0gTlVMTCAmJgorICAgICAgICAgJmZpbGUtPm9wdGlvbnMoKSAhPSAmRmlsZU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2UoKSAmJgorICAgICAgICAgZmlsZS0+b3B0aW9ucygpLm9wdGltaXplX2ZvcigpID09IEZpbGVPcHRpb25zOjpMSVRFX1JVTlRJTUU7Cit9CisKK3ZvaWQgRGVzY3JpcHRvckJ1aWxkZXI6OlZhbGlkYXRlRmlsZU9wdGlvbnMoRmlsZURlc2NyaXB0b3IqIGZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8mIHByb3RvKSB7CisgIFZBTElEQVRFX09QVElPTlNfRlJPTV9BUlJBWShmaWxlLCBtZXNzYWdlX3R5cGUsIE1lc3NhZ2UpOworICBWQUxJREFURV9PUFRJT05TX0ZST01fQVJSQVkoZmlsZSwgZW51bV90eXBlLCBFbnVtKTsKKyAgVkFMSURBVEVfT1BUSU9OU19GUk9NX0FSUkFZKGZpbGUsIHNlcnZpY2UsIFNlcnZpY2UpOworICBWQUxJREFURV9PUFRJT05TX0ZST01fQVJSQVkoZmlsZSwgZXh0ZW5zaW9uLCBGaWVsZCk7CisKKyAgLy8gTGl0ZSBmaWxlcyBjYW4gb25seSBiZSBpbXBvcnRlZCBieSBvdGhlciBMaXRlIGZpbGVzLgorICBpZiAoIUlzTGl0ZShmaWxlKSkgeworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZS0+ZGVwZW5kZW5jeV9jb3VudCgpOyBpKyspIHsKKyAgICAgIGlmIChJc0xpdGUoZmlsZS0+ZGVwZW5kZW5jeShpKSkpIHsKKyAgICAgICAgQWRkRXJyb3IoCisgICAgICAgICAgZmlsZS0+bmFtZSgpLCBwcm90bywKKyAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok9USEVSLAorICAgICAgICAgICJGaWxlcyB0aGF0IGRvIG5vdCB1c2Ugb3B0aW1pemVfZm9yID0gTElURV9SVU5USU1FIGNhbm5vdCBpbXBvcnQgIgorICAgICAgICAgICJmaWxlcyB3aGljaCBkbyB1c2UgdGhpcyBvcHRpb24uICBUaGlzIGZpbGUgaXMgbm90IGxpdGUsIGJ1dCBpdCAiCisgICAgICAgICAgImltcG9ydHMgXCIiICsgZmlsZS0+ZGVwZW5kZW5jeShpKS0+bmFtZSgpICsgIlwiIHdoaWNoIGlzLiIpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KKyAgaWYgKGZpbGUtPnN5bnRheCgpID09IEZpbGVEZXNjcmlwdG9yOjpTWU5UQVhfUFJPVE8zKSB7CisgICAgVmFsaWRhdGVQcm90bzMoZmlsZSwgcHJvdG8pOworICB9Cit9CisKK3ZvaWQgRGVzY3JpcHRvckJ1aWxkZXI6OlZhbGlkYXRlUHJvdG8zKAorICAgIEZpbGVEZXNjcmlwdG9yKiBmaWxlLCBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvJiBwcm90bykgeworICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGUtPmV4dGVuc2lvbl9jb3VudCgpOyArK2kpIHsKKyAgICBWYWxpZGF0ZVByb3RvM0ZpZWxkKGZpbGUtPmV4dGVuc2lvbnNfICsgaSwgcHJvdG8uZXh0ZW5zaW9uKGkpKTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGUtPm1lc3NhZ2VfdHlwZV9jb3VudCgpOyArK2kpIHsKKyAgICBWYWxpZGF0ZVByb3RvM01lc3NhZ2UoZmlsZS0+bWVzc2FnZV90eXBlc18gKyBpLCBwcm90by5tZXNzYWdlX3R5cGUoaSkpOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZS0+ZW51bV90eXBlX2NvdW50KCk7ICsraSkgeworICAgIFZhbGlkYXRlUHJvdG8zRW51bShmaWxlLT5lbnVtX3R5cGVzXyArIGksIHByb3RvLmVudW1fdHlwZShpKSk7CisgIH0KKyAgaWYgKElzTGl0ZShmaWxlKSkgeworICAgIEFkZEVycm9yKGZpbGUtPm5hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpPVEhFUiwKKyAgICAgICAgICAgICAiTGl0ZSBydW50aW1lIGlzIG5vdCBzdXBwb3J0ZWQgaW4gcHJvdG8zLiIpOworICB9Cit9CisKK3N0YXRpYyBzdHJpbmcgVG9Mb3dlcmNhc2VXaXRob3V0VW5kZXJzY29yZXMoY29uc3Qgc3RyaW5nJiBuYW1lKSB7CisgIHN0cmluZyByZXN1bHQ7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgbmFtZS5zaXplKCk7ICsraSkgeworICAgIGlmIChuYW1lW2ldICE9ICdfJykgeworICAgICAgaWYgKG5hbWVbaV0gPj0gJ0EnICYmIG5hbWVbaV0gPD0gJ1onKSB7CisgICAgICAgIHJlc3VsdC5wdXNoX2JhY2sobmFtZVtpXSAtICdBJyArICdhJyk7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXN1bHQucHVzaF9iYWNrKG5hbWVbaV0pOworICAgICAgfQorICAgIH0KKyAgfQorICByZXR1cm4gcmVzdWx0OworfQorCit2b2lkIERlc2NyaXB0b3JCdWlsZGVyOjpWYWxpZGF0ZVByb3RvM01lc3NhZ2UoCisgICAgRGVzY3JpcHRvciogbWVzc2FnZSwgY29uc3QgRGVzY3JpcHRvclByb3RvJiBwcm90bykgeworICBmb3IgKGludCBpID0gMDsgaSA8IG1lc3NhZ2UtPm5lc3RlZF90eXBlX2NvdW50KCk7ICsraSkgeworICAgIFZhbGlkYXRlUHJvdG8zTWVzc2FnZShtZXNzYWdlLT5uZXN0ZWRfdHlwZXNfICsgaSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3RvLm5lc3RlZF90eXBlKGkpKTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IG1lc3NhZ2UtPmVudW1fdHlwZV9jb3VudCgpOyArK2kpIHsKKyAgICBWYWxpZGF0ZVByb3RvM0VudW0obWVzc2FnZS0+ZW51bV90eXBlc18gKyBpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdG8uZW51bV90eXBlKGkpKTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IG1lc3NhZ2UtPmZpZWxkX2NvdW50KCk7ICsraSkgeworICAgIFZhbGlkYXRlUHJvdG8zRmllbGQobWVzc2FnZS0+ZmllbGRzXyArIGksIHByb3RvLmZpZWxkKGkpKTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IG1lc3NhZ2UtPmV4dGVuc2lvbl9jb3VudCgpOyArK2kpIHsKKyAgICBWYWxpZGF0ZVByb3RvM0ZpZWxkKG1lc3NhZ2UtPmV4dGVuc2lvbnNfICtpLCBwcm90by5leHRlbnNpb24oaSkpOworICB9CisgIGlmIChtZXNzYWdlLT5leHRlbnNpb25fcmFuZ2VfY291bnQoKSA+IDApIHsKKyAgICBBZGRFcnJvcihtZXNzYWdlLT5mdWxsX25hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpPVEhFUiwKKyAgICAgICAgICAgICAiRXh0ZW5zaW9uIHJhbmdlcyBhcmUgbm90IGFsbG93ZWQgaW4gcHJvdG8zLiIpOworICB9CisgIGlmIChtZXNzYWdlLT5vcHRpb25zKCkubWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQoKSkgeworICAgIC8vIFVzaW5nIE1lc3NhZ2VTZXQgZG9lc24ndCBtYWtlIHNlbnNlIHNpbmNlIHdlIGRpc2FsbG93IGV4dGVuc2lvbnMuCisgICAgQWRkRXJyb3IobWVzc2FnZS0+ZnVsbF9uYW1lKCksIHByb3RvLAorICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6T1RIRVIsCisgICAgICAgICAgICAgIk1lc3NhZ2VTZXQgaXMgbm90IHN1cHBvcnRlZCBpbiBwcm90bzMuIik7CisgIH0KKworICAvLyBJbiBwcm90bzMsIHdlIHJlamVjdCBmaWVsZCBuYW1lcyBpZiB0aGV5IGNvbmZsaWN0IGluIGNhbWVsQ2FzZS4KKyAgLy8gTm90ZSB0aGF0IHdlIGN1cnJlbnRseSBlbmZvcmNlIGEgc3RyaWN0ZXIgcnVsZTogRmllbGQgbmFtZXMgbXVzdCBiZQorICAvLyB1bmlxdWUgYWZ0ZXIgYmVpbmcgY29udmVydGVkIHRvIGxvd2VyY2FzZSB3aXRoIHVuZGVyc2NvcmVzIHJlbW92ZWQuCisgIG1hcDxzdHJpbmcsIGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+IG5hbWVfdG9fZmllbGQ7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZS0+ZmllbGRfY291bnQoKTsgKytpKSB7CisgICAgc3RyaW5nIGxvd2VyY2FzZV9uYW1lID0gVG9Mb3dlcmNhc2VXaXRob3V0VW5kZXJzY29yZXMoCisgICAgICAgIG1lc3NhZ2UtPmZpZWxkKGkpLT5uYW1lKCkpOworICAgIGlmIChuYW1lX3RvX2ZpZWxkLmZpbmQobG93ZXJjYXNlX25hbWUpICE9IG5hbWVfdG9fZmllbGQuZW5kKCkpIHsKKyAgICAgIEFkZEVycm9yKG1lc3NhZ2UtPmZ1bGxfbmFtZSgpLCBwcm90bywKKyAgICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6T1RIRVIsCisgICAgICAgICAgICAgICAiVGhlIEpTT04gY2FtY2VsLWNhc2UgbmFtZSBvZiBmaWVsZCBcIiIgKworICAgICAgICAgICAgICAgbWVzc2FnZS0+ZmllbGQoaSktPm5hbWUoKSArICJcIiBjb25mbGljdHMgd2l0aCBmaWVsZCBcIiIgKworICAgICAgICAgICAgICAgbmFtZV90b19maWVsZFtsb3dlcmNhc2VfbmFtZV0tPm5hbWUoKSArICJcIi4gVGhpcyBpcyBub3QgIiArCisgICAgICAgICAgICAgICAiYWxsb3dlZCBpbiBwcm90bzMuIik7CisgICAgfSBlbHNlIHsKKyAgICAgIG5hbWVfdG9fZmllbGRbbG93ZXJjYXNlX25hbWVdID0gbWVzc2FnZS0+ZmllbGQoaSk7CisgICAgfQorICB9Cit9CisKK3ZvaWQgRGVzY3JpcHRvckJ1aWxkZXI6OlZhbGlkYXRlUHJvdG8zRmllbGQoCisgICAgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG8mIHByb3RvKSB7CisgIGlmIChmaWVsZC0+aXNfZXh0ZW5zaW9uKCkgJiYKKyAgICAgICFBbGxvd2VkRXh0ZW5kZWVJblByb3RvMyhmaWVsZC0+Y29udGFpbmluZ190eXBlKCktPmZ1bGxfbmFtZSgpKSkgeworICAgIEFkZEVycm9yKGZpZWxkLT5mdWxsX25hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpPVEhFUiwKKyAgICAgICAgICAgICAiRXh0ZW5zaW9ucyBpbiBwcm90bzMgYXJlIG9ubHkgYWxsb3dlZCBmb3IgZGVmaW5pbmcgb3B0aW9ucy4iKTsKKyAgfQorICBpZiAoZmllbGQtPmlzX3JlcXVpcmVkKCkpIHsKKyAgICBBZGRFcnJvcihmaWVsZC0+ZnVsbF9uYW1lKCksIHByb3RvLAorICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6T1RIRVIsCisgICAgICAgICAgICAgIlJlcXVpcmVkIGZpZWxkcyBhcmUgbm90IGFsbG93ZWQgaW4gcHJvdG8zLiIpOworICB9CisgIGlmIChmaWVsZC0+aGFzX2RlZmF1bHRfdmFsdWUoKSkgeworICAgIEFkZEVycm9yKAorICAgICAgICBmaWVsZC0+ZnVsbF9uYW1lKCksIHByb3RvLCBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok9USEVSLAorICAgICAgICAiRXhwbGljaXQgZGVmYXVsdCB2YWx1ZXMgYXJlIG5vdCBhbGxvd2VkIGluIHByb3RvMy4iKTsKKyAgfQorICBpZiAoZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0VOVU0gJiYKKyAgICAgIGZpZWxkLT5lbnVtX3R5cGUoKSAmJgorICAgICAgZmllbGQtPmVudW1fdHlwZSgpLT5maWxlKCktPnN5bnRheCgpICE9IEZpbGVEZXNjcmlwdG9yOjpTWU5UQVhfUFJPVE8zKSB7CisgICAgLy8gUHJvdG8zIG1lc3NhZ2VzIGNhbiBvbmx5IHVzZSBQcm90bzMgZW51bSB0eXBlczsgb3RoZXJ3aXNlIHdlIGNhbid0CisgICAgLy8gZ3VhcmFudGVlIHRoYXQgdGhlIGRlZmF1bHQgdmFsdWUgaXMgemVyby4KKyAgICBBZGRFcnJvcihmaWVsZC0+ZnVsbF9uYW1lKCksIHByb3RvLAorICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6VFlQRSwKKyAgICAgICAgICAgICAiRW51bSB0eXBlIFwiIiArIGZpZWxkLT5lbnVtX3R5cGUoKS0+ZnVsbF9uYW1lKCkgKworICAgICAgICAgICAgICJcIiBpcyBub3QgYSBwcm90bzMgZW51bSwgYnV0IGlzIHVzZWQgaW4gXCIiICsKKyAgICAgICAgICAgICBmaWVsZC0+Y29udGFpbmluZ190eXBlKCktPmZ1bGxfbmFtZSgpICsKKyAgICAgICAgICAgICAiXCIgd2hpY2ggaXMgYSBwcm90bzMgbWVzc2FnZSB0eXBlLiIpOworICB9CisgIGlmIChmaWVsZC0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9HUk9VUCkgeworICAgIEFkZEVycm9yKGZpZWxkLT5mdWxsX25hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpUWVBFLAorICAgICAgICAgICAgICJHcm91cHMgYXJlIG5vdCBzdXBwb3J0ZWQgaW4gcHJvdG8zIHN5bnRheC4iKTsKKyAgfQorfQorCit2b2lkIERlc2NyaXB0b3JCdWlsZGVyOjpWYWxpZGF0ZVByb3RvM0VudW0oCisgICAgRW51bURlc2NyaXB0b3IqIGVubSwgY29uc3QgRW51bURlc2NyaXB0b3JQcm90byYgcHJvdG8pIHsKKyAgaWYgKGVubS0+dmFsdWVfY291bnQoKSA+IDAgJiYgZW5tLT52YWx1ZSgwKS0+bnVtYmVyKCkgIT0gMCkgeworICAgIEFkZEVycm9yKAorICAgICAgICBlbm0tPmZ1bGxfbmFtZSgpLCBwcm90bywgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpPVEhFUiwKKyAgICAgICAgIlRoZSBmaXJzdCBlbnVtIHZhbHVlIG11c3QgYmUgemVybyBpbiBwcm90bzMuIik7CisgIH0KK30KKwordm9pZCBEZXNjcmlwdG9yQnVpbGRlcjo6VmFsaWRhdGVNZXNzYWdlT3B0aW9ucyhEZXNjcmlwdG9yKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEZXNjcmlwdG9yUHJvdG8mIHByb3RvKSB7CisgIFZBTElEQVRFX09QVElPTlNfRlJPTV9BUlJBWShtZXNzYWdlLCBmaWVsZCwgRmllbGQpOworICBWQUxJREFURV9PUFRJT05TX0ZST01fQVJSQVkobWVzc2FnZSwgbmVzdGVkX3R5cGUsIE1lc3NhZ2UpOworICBWQUxJREFURV9PUFRJT05TX0ZST01fQVJSQVkobWVzc2FnZSwgZW51bV90eXBlLCBFbnVtKTsKKyAgVkFMSURBVEVfT1BUSU9OU19GUk9NX0FSUkFZKG1lc3NhZ2UsIGV4dGVuc2lvbiwgRmllbGQpOworCisgIGNvbnN0IGludDY0IG1heF9leHRlbnNpb25fcmFuZ2UgPQorICAgICAgc3RhdGljX2Nhc3Q8aW50NjQ+KG1lc3NhZ2UtPm9wdGlvbnMoKS5tZXNzYWdlX3NldF93aXJlX2Zvcm1hdCgpID8KKyAgICAgICAgICAgICAgICAgICAgICAgICBraW50MzJtYXggOgorICAgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvcjo6a01heE51bWJlcik7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZS0+ZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCk7ICsraSkgeworICAgIGlmIChtZXNzYWdlLT5leHRlbnNpb25fcmFuZ2UoaSktPmVuZCA+IG1heF9leHRlbnNpb25fcmFuZ2UgKyAxKSB7CisgICAgICBBZGRFcnJvcigKKyAgICAgICAgICBtZXNzYWdlLT5mdWxsX25hbWUoKSwgcHJvdG8uZXh0ZW5zaW9uX3JhbmdlKGkpLAorICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6TlVNQkVSLAorICAgICAgICAgIHN0cmluZ3M6OlN1YnN0aXR1dGUoIkV4dGVuc2lvbiBudW1iZXJzIGNhbm5vdCBiZSBncmVhdGVyIHRoYW4gJDAuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heF9leHRlbnNpb25fcmFuZ2UpKTsKKyAgICB9CisgIH0KK30KKwordm9pZCBEZXNjcmlwdG9yQnVpbGRlcjo6VmFsaWRhdGVGaWVsZE9wdGlvbnMoRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90byYgcHJvdG8pIHsKKyAgLy8gT25seSBtZXNzYWdlIHR5cGUgZmllbGRzIG1heSBiZSBsYXp5LgorICBpZiAoZmllbGQtPm9wdGlvbnMoKS5sYXp5KCkpIHsKKyAgICBpZiAoZmllbGQtPnR5cGUoKSAhPSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfTUVTU0FHRSkgeworICAgICAgQWRkRXJyb3IoZmllbGQtPmZ1bGxfbmFtZSgpLCBwcm90bywKKyAgICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6VFlQRSwKKyAgICAgICAgICAgICAgICJbbGF6eSA9IHRydWVdIGNhbiBvbmx5IGJlIHNwZWNpZmllZCBmb3Igc3VibWVzc2FnZSBmaWVsZHMuIik7CisgICAgfQorICB9CisKKyAgLy8gT25seSByZXBlYXRlZCBwcmltaXRpdmUgZmllbGRzIG1heSBiZSBwYWNrZWQuCisgIGlmIChmaWVsZC0+b3B0aW9ucygpLnBhY2tlZCgpICYmICFmaWVsZC0+aXNfcGFja2FibGUoKSkgeworICAgIEFkZEVycm9yKAorICAgICAgZmllbGQtPmZ1bGxfbmFtZSgpLCBwcm90bywKKyAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6VFlQRSwKKyAgICAgICJbcGFja2VkID0gdHJ1ZV0gY2FuIG9ubHkgYmUgc3BlY2lmaWVkIGZvciByZXBlYXRlZCBwcmltaXRpdmUgZmllbGRzLiIpOworICB9CisKKyAgLy8gTm90ZTogIERlZmF1bHQgaW5zdGFuY2UgbWF5IG5vdCB5ZXQgYmUgaW5pdGlhbGl6ZWQgaGVyZSwgc28gd2UgaGF2ZSB0bworICAvLyAgIGF2b2lkIHJlYWRpbmcgZnJvbSBpdC4KKyAgaWYgKGZpZWxkLT5jb250YWluaW5nX3R5cGVfICE9IE5VTEwgJiYKKyAgICAgICZmaWVsZC0+Y29udGFpbmluZ190eXBlKCktPm9wdGlvbnMoKSAhPQorICAgICAgJk1lc3NhZ2VPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlKCkgJiYKKyAgICAgIGZpZWxkLT5jb250YWluaW5nX3R5cGUoKS0+b3B0aW9ucygpLm1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KCkpIHsKKyAgICBpZiAoZmllbGQtPmlzX2V4dGVuc2lvbigpKSB7CisgICAgICBpZiAoIWZpZWxkLT5pc19vcHRpb25hbCgpIHx8CisgICAgICAgICAgZmllbGQtPnR5cGUoKSAhPSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfTUVTU0FHRSkgeworICAgICAgICBBZGRFcnJvcihmaWVsZC0+ZnVsbF9uYW1lKCksIHByb3RvLAorICAgICAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6OlRZUEUsCisgICAgICAgICAgICAgICAgICJFeHRlbnNpb25zIG9mIE1lc3NhZ2VTZXRzIG11c3QgYmUgb3B0aW9uYWwgbWVzc2FnZXMuIik7CisgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgIEFkZEVycm9yKGZpZWxkLT5mdWxsX25hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok5BTUUsCisgICAgICAgICAgICAgICAiTWVzc2FnZVNldHMgY2Fubm90IGhhdmUgZmllbGRzLCBvbmx5IGV4dGVuc2lvbnMuIik7CisgICAgfQorICB9CisKKyAgLy8gTGl0ZSBleHRlbnNpb25zIGNhbiBvbmx5IGJlIG9mIExpdGUgdHlwZXMuCisgIGlmIChJc0xpdGUoZmllbGQtPmZpbGUoKSkgJiYKKyAgICAgIGZpZWxkLT5jb250YWluaW5nX3R5cGVfICE9IE5VTEwgJiYKKyAgICAgICFJc0xpdGUoZmllbGQtPmNvbnRhaW5pbmdfdHlwZSgpLT5maWxlKCkpKSB7CisgICAgQWRkRXJyb3IoZmllbGQtPmZ1bGxfbmFtZSgpLCBwcm90bywKKyAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6OkVYVEVOREVFLAorICAgICAgICAgICAgICJFeHRlbnNpb25zIHRvIG5vbi1saXRlIHR5cGVzIGNhbiBvbmx5IGJlIGRlY2xhcmVkIGluIG5vbi1saXRlICIKKyAgICAgICAgICAgICAiZmlsZXMuICBOb3RlIHRoYXQgeW91IGNhbm5vdCBleHRlbmQgYSBub24tbGl0ZSB0eXBlIHRvIGNvbnRhaW4gIgorICAgICAgICAgICAgICJhIGxpdGUgdHlwZSwgYnV0IHRoZSByZXZlcnNlIGlzIGFsbG93ZWQuIik7CisgIH0KKworICAvLyBWYWxpZGF0ZSBtYXAgdHlwZXMuCisgIGlmIChmaWVsZC0+aXNfbWFwKCkpIHsKKyAgICBpZiAoIVZhbGlkYXRlTWFwRW50cnkoZmllbGQsIHByb3RvKSkgeworICAgICAgQWRkRXJyb3IoZmllbGQtPmZ1bGxfbmFtZSgpLCBwcm90bywKKyAgICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6T1RIRVIsCisgICAgICAgICAgICAgICAibWFwX2VudHJ5IHNob3VsZCBub3QgYmUgc2V0IGV4cGxpY2l0bHkuIFVzZSBtYXA8S2V5VHlwZSwgIgorICAgICAgICAgICAgICAgIlZhbHVlVHlwZT4gaW5zdGVhZC4iKTsKKyAgICB9CisgIH0KKworfQorCit2b2lkIERlc2NyaXB0b3JCdWlsZGVyOjpWYWxpZGF0ZUVudW1PcHRpb25zKEVudW1EZXNjcmlwdG9yKiBlbm0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEVudW1EZXNjcmlwdG9yUHJvdG8mIHByb3RvKSB7CisgIFZBTElEQVRFX09QVElPTlNfRlJPTV9BUlJBWShlbm0sIHZhbHVlLCBFbnVtVmFsdWUpOworICBpZiAoIWVubS0+b3B0aW9ucygpLmhhc19hbGxvd19hbGlhcygpIHx8ICFlbm0tPm9wdGlvbnMoKS5hbGxvd19hbGlhcygpKSB7CisgICAgbWFwPGludCwgc3RyaW5nPiB1c2VkX3ZhbHVlczsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGVubS0+dmFsdWVfY291bnQoKTsgKytpKSB7CisgICAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBlbnVtX3ZhbHVlID0gZW5tLT52YWx1ZShpKTsKKyAgICAgIGlmICh1c2VkX3ZhbHVlcy5maW5kKGVudW1fdmFsdWUtPm51bWJlcigpKSAhPSB1c2VkX3ZhbHVlcy5lbmQoKSkgeworICAgICAgICBzdHJpbmcgZXJyb3IgPQorICAgICAgICAgICAgIlwiIiArIGVudW1fdmFsdWUtPmZ1bGxfbmFtZSgpICsKKyAgICAgICAgICAgICJcIiB1c2VzIHRoZSBzYW1lIGVudW0gdmFsdWUgYXMgXCIiICsKKyAgICAgICAgICAgIHVzZWRfdmFsdWVzW2VudW1fdmFsdWUtPm51bWJlcigpXSArICJcIi4gSWYgdGhpcyBpcyBpbnRlbmRlZCwgc2V0ICIKKyAgICAgICAgICAgICInb3B0aW9uIGFsbG93X2FsaWFzID0gdHJ1ZTsnIHRvIHRoZSBlbnVtIGRlZmluaXRpb24uIjsKKyAgICAgICAgaWYgKCFlbm0tPm9wdGlvbnMoKS5hbGxvd19hbGlhcygpKSB7CisgICAgICAgICAgLy8gR2VuZXJhdGUgZXJyb3IgaWYgZHVwbGljYXRlZCBlbnVtIHZhbHVlcyBhcmUgZXhwbGljaXRseSBkaXNhbGxvd2VkLgorICAgICAgICAgIEFkZEVycm9yKGVubS0+ZnVsbF9uYW1lKCksIHByb3RvLAorICAgICAgICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6TlVNQkVSLAorICAgICAgICAgICAgICAgICAgIGVycm9yKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAvLyBHZW5lcmF0ZSB3YXJuaW5nIGlmIGR1cGxpY2F0ZWQgdmFsdWVzIGFyZSBmb3VuZCBidXQgdGhlIG9wdGlvbgorICAgICAgICAgIC8vIGlzbid0IHNldC4KKyAgICAgICAgICBHT09HTEVfTE9HKEVSUk9SKSA8PCBlcnJvcjsKKyAgICAgICAgfQorICAgICAgfSBlbHNlIHsKKyAgICAgICAgdXNlZF92YWx1ZXNbZW51bV92YWx1ZS0+bnVtYmVyKCldID0gZW51bV92YWx1ZS0+ZnVsbF9uYW1lKCk7CisgICAgICB9CisgICAgfQorICB9Cit9CisKK3ZvaWQgRGVzY3JpcHRvckJ1aWxkZXI6OlZhbGlkYXRlRW51bVZhbHVlT3B0aW9ucygKKyAgICBFbnVtVmFsdWVEZXNjcmlwdG9yKiAvKiBlbnVtX3ZhbHVlICovLAorICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3JQcm90byYgLyogcHJvdG8gKi8pIHsKKyAgLy8gTm90aGluZyB0byBkbyBzbyBmYXIuCit9Cit2b2lkIERlc2NyaXB0b3JCdWlsZGVyOjpWYWxpZGF0ZVNlcnZpY2VPcHRpb25zKFNlcnZpY2VEZXNjcmlwdG9yKiBzZXJ2aWNlLAorICAgIGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yUHJvdG8mIHByb3RvKSB7CisgIGlmIChJc0xpdGUoc2VydmljZS0+ZmlsZSgpKSAmJgorICAgICAgKHNlcnZpY2UtPmZpbGUoKS0+b3B0aW9ucygpLmNjX2dlbmVyaWNfc2VydmljZXMoKSB8fAorICAgICAgIHNlcnZpY2UtPmZpbGUoKS0+b3B0aW9ucygpLmphdmFfZ2VuZXJpY19zZXJ2aWNlcygpKSkgeworICAgIEFkZEVycm9yKHNlcnZpY2UtPmZ1bGxfbmFtZSgpLCBwcm90bywKKyAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok5BTUUsCisgICAgICAgICAgICAgIkZpbGVzIHdpdGggb3B0aW1pemVfZm9yID0gTElURV9SVU5USU1FIGNhbm5vdCBkZWZpbmUgc2VydmljZXMgIgorICAgICAgICAgICAgICJ1bmxlc3MgeW91IHNldCBib3RoIG9wdGlvbnMgY2NfZ2VuZXJpY19zZXJ2aWNlcyBhbmQgIgorICAgICAgICAgICAgICJqYXZhX2dlbmVyaWNfc2V2aWNlcyB0byBmYWxzZS4iKTsKKyAgfQorCisgIFZBTElEQVRFX09QVElPTlNfRlJPTV9BUlJBWShzZXJ2aWNlLCBtZXRob2QsIE1ldGhvZCk7Cit9CisKK3ZvaWQgRGVzY3JpcHRvckJ1aWxkZXI6OlZhbGlkYXRlTWV0aG9kT3B0aW9ucyhNZXRob2REZXNjcmlwdG9yKiAvKiBtZXRob2QgKi8sCisgICAgY29uc3QgTWV0aG9kRGVzY3JpcHRvclByb3RvJiAvKiBwcm90byAqLykgeworICAvLyBOb3RoaW5nIHRvIGRvIHNvIGZhci4KK30KKworYm9vbCBEZXNjcmlwdG9yQnVpbGRlcjo6VmFsaWRhdGVNYXBFbnRyeShGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90byYgcHJvdG8pIHsKKyAgY29uc3QgRGVzY3JpcHRvciogbWVzc2FnZSA9IGZpZWxkLT5tZXNzYWdlX3R5cGUoKTsKKyAgaWYgKC8vIE11c3Qgbm90IGNvbnRhaW4gZXh0ZW5zaW9ucywgZXh0ZW5zaW9uIHJhbmdlIG9yIG5lc3RlZCBtZXNzYWdlIG9yCisgICAgICAvLyBlbnVtcworICAgICAgbWVzc2FnZS0+ZXh0ZW5zaW9uX2NvdW50KCkgIT0gMCB8fAorICAgICAgZmllbGQtPmxhYmVsKCkgIT0gRmllbGREZXNjcmlwdG9yOjpMQUJFTF9SRVBFQVRFRCB8fAorICAgICAgbWVzc2FnZS0+ZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCkgIT0gMCB8fAorICAgICAgbWVzc2FnZS0+bmVzdGVkX3R5cGVfY291bnQoKSAhPSAwIHx8IG1lc3NhZ2UtPmVudW1fdHlwZV9jb3VudCgpICE9IDAgfHwKKyAgICAgIC8vIE11c3QgY29udGFpbiBleGFjdGx5IHR3byBmaWVsZHMKKyAgICAgIG1lc3NhZ2UtPmZpZWxkX2NvdW50KCkgIT0gMiB8fAorICAgICAgLy8gRmllbGQgbmFtZSBhbmQgbWVzc2FnZSBuYW1lIG11c3QgbWF0Y2gKKyAgICAgIG1lc3NhZ2UtPm5hbWUoKSAhPSBUb0NhbWVsQ2FzZShmaWVsZC0+bmFtZSgpLCBmYWxzZSkgKyAiRW50cnkiIHx8CisgICAgICAvLyBFbnRyeSBtZXNzYWdlIG11c3QgYmUgaW4gdGhlIHNhbWUgY29udGFpbmluZyB0eXBlIG9mIHRoZSBmaWVsZC4KKyAgICAgIGZpZWxkLT5jb250YWluaW5nX3R5cGUoKSAhPSBtZXNzYWdlLT5jb250YWluaW5nX3R5cGUoKSkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvcioga2V5ID0gbWVzc2FnZS0+ZmllbGQoMCk7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogdmFsdWUgPSBtZXNzYWdlLT5maWVsZCgxKTsKKyAgaWYgKGtleS0+bGFiZWwoKSAhPSBGaWVsZERlc2NyaXB0b3I6OkxBQkVMX09QVElPTkFMIHx8IGtleS0+bnVtYmVyKCkgIT0gMSB8fAorICAgICAga2V5LT5uYW1lKCkgIT0gImtleSIpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgaWYgKHZhbHVlLT5sYWJlbCgpICE9IEZpZWxkRGVzY3JpcHRvcjo6TEFCRUxfT1BUSU9OQUwgfHwKKyAgICAgIHZhbHVlLT5udW1iZXIoKSAhPSAyIHx8IHZhbHVlLT5uYW1lKCkgIT0gInZhbHVlIikgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vIENoZWNrIGtleSB0eXBlcyBhcmUgbGVnYWwuCisgIHN3aXRjaCAoa2V5LT50eXBlKCkpIHsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9FTlVNOgorICAgICAgQWRkRXJyb3IoCisgICAgICAgICAgZmllbGQtPmZ1bGxfbmFtZSgpLCBwcm90bywgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpUWVBFLAorICAgICAgICAgICJLZXkgaW4gbWFwIGZpZWxkcyBjYW5ub3QgYmUgZW51bSB0eXBlcy4iKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0ZMT0FUOgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0RPVUJMRToKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9NRVNTQUdFOgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQOgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0JZVEVTOgorICAgICAgQWRkRXJyb3IoCisgICAgICAgICAgZmllbGQtPmZ1bGxfbmFtZSgpLCBwcm90bywgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpUWVBFLAorICAgICAgICAgICJLZXkgaW4gbWFwIGZpZWxkcyBjYW5ub3QgYmUgZmxvYXQvZG91YmxlLCBieXRlcyBvciBtZXNzYWdlIHR5cGVzLiIpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfQk9PTDoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9JTlQzMjoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9JTlQ2NDoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TSU5UMzI6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU0lOVDY0OgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NUUklORzoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9VSU5UMzI6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfVUlOVDY0OgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0ZJWEVEMzI6CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRklYRUQ2NDoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TRklYRUQzMjoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TRklYRUQ2NDoKKyAgICAgIC8vIExlZ2FsIGNhc2VzCisgICAgICBicmVhazsKKyAgICAvLyBEbyBub3QgYWRkIGEgZGVmYXVsdCwgc28gdGhhdCB0aGUgY29tcGlsZXIgd2lsbCBjb21wbGFpbiB3aGVuIG5ldyB0eXBlcworICAgIC8vIGFyZSBhZGRlZC4KKyAgfQorCisgIGlmICh2YWx1ZS0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9FTlVNKSB7CisgICAgaWYgKHZhbHVlLT5lbnVtX3R5cGUoKS0+dmFsdWUoMCktPm51bWJlcigpICE9IDApIHsKKyAgICAgIEFkZEVycm9yKAorICAgICAgICAgIGZpZWxkLT5mdWxsX25hbWUoKSwgcHJvdG8sIERlc2NyaXB0b3JQb29sOjpFcnJvckNvbGxlY3Rvcjo6VFlQRSwKKyAgICAgICAgICAiRW51bSB2YWx1ZSBpbiBtYXAgbXVzdCBkZWZpbmUgMCBhcyB0aGUgZmlyc3QgdmFsdWUuIik7CisgICAgfQorICB9CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgRGVzY3JpcHRvckJ1aWxkZXI6OkRldGVjdE1hcENvbmZsaWN0cyhjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlc2NyaXB0b3JQcm90byYgcHJvdG8pIHsKKyAgbWFwPHN0cmluZywgY29uc3QgRGVzY3JpcHRvcio+IHNlZW5fdHlwZXM7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZS0+bmVzdGVkX3R5cGVfY291bnQoKTsgKytpKSB7CisgICAgY29uc3QgRGVzY3JpcHRvciogbmVzdGVkID0gbWVzc2FnZS0+bmVzdGVkX3R5cGUoaSk7CisgICAgcGFpcjxtYXA8c3RyaW5nLCBjb25zdCBEZXNjcmlwdG9yKj46Oml0ZXJhdG9yLCBib29sPiByZXN1bHQgPQorICAgICAgICBzZWVuX3R5cGVzLmluc2VydChzdGQ6Om1ha2VfcGFpcihuZXN0ZWQtPm5hbWUoKSwgbmVzdGVkKSk7CisgICAgaWYgKCFyZXN1bHQuc2Vjb25kKSB7CisgICAgICBpZiAocmVzdWx0LmZpcnN0LT5zZWNvbmQtPm9wdGlvbnMoKS5tYXBfZW50cnkoKSB8fAorICAgICAgICAgIG5lc3RlZC0+b3B0aW9ucygpLm1hcF9lbnRyeSgpKSB7CisgICAgICAgIEFkZEVycm9yKG1lc3NhZ2UtPmZ1bGxfbmFtZSgpLCBwcm90bywKKyAgICAgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpOQU1FLAorICAgICAgICAgICAgICAgICAiRXhwYW5kZWQgbWFwIGVudHJ5IHR5cGUgIiArIG5lc3RlZC0+bmFtZSgpICsKKyAgICAgICAgICAgICAgICAgIiBjb25mbGljdHMgd2l0aCBhbiBleGlzdGluZyBuZXN0ZWQgbWVzc2FnZSB0eXBlLiIpOworICAgICAgfQorICAgIH0KKyAgICAvLyBSZWN1cnNpdmVseSB0ZXN0IG9uIHRoZSBuZXN0ZWQgdHlwZXMuCisgICAgRGV0ZWN0TWFwQ29uZmxpY3RzKG1lc3NhZ2UtPm5lc3RlZF90eXBlKGkpLCBwcm90by5uZXN0ZWRfdHlwZShpKSk7CisgIH0KKyAgLy8gQ2hlY2sgZm9yIGNvbmZsaWN0ZWQgZmllbGQgbmFtZXMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZS0+ZmllbGRfY291bnQoKTsgKytpKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IG1lc3NhZ2UtPmZpZWxkKGkpOworICAgIG1hcDxzdHJpbmcsIGNvbnN0IERlc2NyaXB0b3IqPjo6aXRlcmF0b3IgaXRlciA9CisgICAgICAgIHNlZW5fdHlwZXMuZmluZChmaWVsZC0+bmFtZSgpKTsKKyAgICBpZiAoaXRlciAhPSBzZWVuX3R5cGVzLmVuZCgpICYmIGl0ZXItPnNlY29uZC0+b3B0aW9ucygpLm1hcF9lbnRyeSgpKSB7CisgICAgICBBZGRFcnJvcihtZXNzYWdlLT5mdWxsX25hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok5BTUUsCisgICAgICAgICAgICAgICAiRXhwYW5kZWQgbWFwIGVudHJ5IHR5cGUgIiArIGl0ZXItPnNlY29uZC0+bmFtZSgpICsKKyAgICAgICAgICAgICAgICIgY29uZmxpY3RzIHdpdGggYW4gZXhpc3RpbmcgZmllbGQuIik7CisgICAgfQorICB9CisgIC8vIENoZWNrIGZvciBjb25mbGljdGVkIGVudW0gbmFtZXMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZS0+ZW51bV90eXBlX2NvdW50KCk7ICsraSkgeworICAgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBlbnVtX2Rlc2MgPSBtZXNzYWdlLT5lbnVtX3R5cGUoaSk7CisgICAgbWFwPHN0cmluZywgY29uc3QgRGVzY3JpcHRvcio+OjppdGVyYXRvciBpdGVyID0KKyAgICAgICAgc2Vlbl90eXBlcy5maW5kKGVudW1fZGVzYy0+bmFtZSgpKTsKKyAgICBpZiAoaXRlciAhPSBzZWVuX3R5cGVzLmVuZCgpICYmIGl0ZXItPnNlY29uZC0+b3B0aW9ucygpLm1hcF9lbnRyeSgpKSB7CisgICAgICBBZGRFcnJvcihtZXNzYWdlLT5mdWxsX25hbWUoKSwgcHJvdG8sCisgICAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok5BTUUsCisgICAgICAgICAgICAgICAiRXhwYW5kZWQgbWFwIGVudHJ5IHR5cGUgIiArIGl0ZXItPnNlY29uZC0+bmFtZSgpICsKKyAgICAgICAgICAgICAgICIgY29uZmxpY3RzIHdpdGggYW4gZXhpc3RpbmcgZW51bSB0eXBlLiIpOworICAgIH0KKyAgfQorICAvLyBDaGVjayBmb3IgY29uZmxpY3RlZCBvbmVvZiBuYW1lcy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZXNzYWdlLT5vbmVvZl9kZWNsX2NvdW50KCk7ICsraSkgeworICAgIGNvbnN0IE9uZW9mRGVzY3JpcHRvciogb25lb2ZfZGVzYyA9IG1lc3NhZ2UtPm9uZW9mX2RlY2woaSk7CisgICAgbWFwPHN0cmluZywgY29uc3QgRGVzY3JpcHRvcio+OjppdGVyYXRvciBpdGVyID0KKyAgICAgICAgc2Vlbl90eXBlcy5maW5kKG9uZW9mX2Rlc2MtPm5hbWUoKSk7CisgICAgaWYgKGl0ZXIgIT0gc2Vlbl90eXBlcy5lbmQoKSAmJiBpdGVyLT5zZWNvbmQtPm9wdGlvbnMoKS5tYXBfZW50cnkoKSkgeworICAgICAgQWRkRXJyb3IobWVzc2FnZS0+ZnVsbF9uYW1lKCksIHByb3RvLAorICAgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpOQU1FLAorICAgICAgICAgICAgICAgIkV4cGFuZGVkIG1hcCBlbnRyeSB0eXBlICIgKyBpdGVyLT5zZWNvbmQtPm5hbWUoKSArCisgICAgICAgICAgICAgICAiIGNvbmZsaWN0cyB3aXRoIGFuIGV4aXN0aW5nIG9uZW9mIHR5cGUuIik7CisgICAgfQorICB9Cit9CisKKworI3VuZGVmIFZBTElEQVRFX09QVElPTlNfRlJPTV9BUlJBWQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0Rlc2NyaXB0b3JCdWlsZGVyOjpPcHRpb25JbnRlcnByZXRlcjo6T3B0aW9uSW50ZXJwcmV0ZXIoCisgICAgRGVzY3JpcHRvckJ1aWxkZXIqIGJ1aWxkZXIpIDogYnVpbGRlcl8oYnVpbGRlcikgeworICBHT09HTEVfQ0hFQ0soYnVpbGRlcl8pOworfQorCitEZXNjcmlwdG9yQnVpbGRlcjo6T3B0aW9uSW50ZXJwcmV0ZXI6On5PcHRpb25JbnRlcnByZXRlcigpIHsKK30KKworYm9vbCBEZXNjcmlwdG9yQnVpbGRlcjo6T3B0aW9uSW50ZXJwcmV0ZXI6OkludGVycHJldE9wdGlvbnMoCisgICAgT3B0aW9uc1RvSW50ZXJwcmV0KiBvcHRpb25zX3RvX2ludGVycHJldCkgeworICAvLyBOb3RlIHRoYXQgdGhlc2UgbWF5IGJlIGluIGRpZmZlcmVudCBwb29scywgc28gd2UgY2FuJ3QgdXNlIHRoZSBzYW1lCisgIC8vIGRlc2NyaXB0b3IgYW5kIHJlZmxlY3Rpb24gb2JqZWN0cyBvbiBib3RoLgorICBNZXNzYWdlKiBvcHRpb25zID0gb3B0aW9uc190b19pbnRlcnByZXQtPm9wdGlvbnM7CisgIGNvbnN0IE1lc3NhZ2UqIG9yaWdpbmFsX29wdGlvbnMgPSBvcHRpb25zX3RvX2ludGVycHJldC0+b3JpZ2luYWxfb3B0aW9uczsKKworICBib29sIGZhaWxlZCA9IGZhbHNlOworICBvcHRpb25zX3RvX2ludGVycHJldF8gPSBvcHRpb25zX3RvX2ludGVycHJldDsKKworICAvLyBGaW5kIHRoZSB1bmludGVycHJldGVkX29wdGlvbiBmaWVsZCBpbiB0aGUgbXV0YWJsZSBjb3B5IG9mIHRoZSBvcHRpb25zCisgIC8vIGFuZCBjbGVhciB0aGVtLCBzaW5jZSB3ZSdyZSBhYm91dCB0byBpbnRlcnByZXQgdGhlbS4KKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiB1bmludGVycHJldGVkX29wdGlvbnNfZmllbGQgPQorICAgICAgb3B0aW9ucy0+R2V0RGVzY3JpcHRvcigpLT5GaW5kRmllbGRCeU5hbWUoInVuaW50ZXJwcmV0ZWRfb3B0aW9uIik7CisgIEdPT0dMRV9DSEVDSyh1bmludGVycHJldGVkX29wdGlvbnNfZmllbGQgIT0gTlVMTCkKKyAgICAgIDw8ICJObyBmaWVsZCBuYW1lZCBcInVuaW50ZXJwcmV0ZWRfb3B0aW9uXCIgaW4gdGhlIE9wdGlvbnMgcHJvdG8uIjsKKyAgb3B0aW9ucy0+R2V0UmVmbGVjdGlvbigpLT5DbGVhckZpZWxkKG9wdGlvbnMsIHVuaW50ZXJwcmV0ZWRfb3B0aW9uc19maWVsZCk7CisKKyAgLy8gRmluZCB0aGUgdW5pbnRlcnByZXRlZF9vcHRpb24gZmllbGQgaW4gdGhlIG9yaWdpbmFsIG9wdGlvbnMuCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogb3JpZ2luYWxfdW5pbnRlcnByZXRlZF9vcHRpb25zX2ZpZWxkID0KKyAgICAgIG9yaWdpbmFsX29wdGlvbnMtPkdldERlc2NyaXB0b3IoKS0+CisgICAgICAgICAgRmluZEZpZWxkQnlOYW1lKCJ1bmludGVycHJldGVkX29wdGlvbiIpOworICBHT09HTEVfQ0hFQ0sob3JpZ2luYWxfdW5pbnRlcnByZXRlZF9vcHRpb25zX2ZpZWxkICE9IE5VTEwpCisgICAgICA8PCAiTm8gZmllbGQgbmFtZWQgXCJ1bmludGVycHJldGVkX29wdGlvblwiIGluIHRoZSBPcHRpb25zIHByb3RvLiI7CisKKyAgY29uc3QgaW50IG51bV91bmludGVycHJldGVkX29wdGlvbnMgPSBvcmlnaW5hbF9vcHRpb25zLT5HZXRSZWZsZWN0aW9uKCktPgorICAgICAgRmllbGRTaXplKCpvcmlnaW5hbF9vcHRpb25zLCBvcmlnaW5hbF91bmludGVycHJldGVkX29wdGlvbnNfZmllbGQpOworICBmb3IgKGludCBpID0gMDsgaSA8IG51bV91bmludGVycHJldGVkX29wdGlvbnM7ICsraSkgeworICAgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXyA9IGRvd25fY2FzdDxjb25zdCBVbmludGVycHJldGVkT3B0aW9uKj4oCisgICAgICAgICZvcmlnaW5hbF9vcHRpb25zLT5HZXRSZWZsZWN0aW9uKCktPkdldFJlcGVhdGVkTWVzc2FnZSgKKyAgICAgICAgICAgICpvcmlnaW5hbF9vcHRpb25zLCBvcmlnaW5hbF91bmludGVycHJldGVkX29wdGlvbnNfZmllbGQsIGkpKTsKKyAgICBpZiAoIUludGVycHJldFNpbmdsZU9wdGlvbihvcHRpb25zKSkgeworICAgICAgLy8gRXJyb3IgYWxyZWFkeSBhZGRlZCBieSBJbnRlcnByZXRTaW5nbGVPcHRpb24oKS4KKyAgICAgIGZhaWxlZCA9IHRydWU7CisgICAgICBicmVhazsKKyAgICB9CisgIH0KKyAgLy8gUmVzZXQgdGhlc2UsIHNvIHdlIGRvbid0IGhhdmUgYW55IGRhbmdsaW5nIHBvaW50ZXJzLgorICB1bmludGVycHJldGVkX29wdGlvbl8gPSBOVUxMOworICBvcHRpb25zX3RvX2ludGVycHJldF8gPSBOVUxMOworCisgIGlmICghZmFpbGVkKSB7CisgICAgLy8gSW50ZXJwcmV0U2luZ2xlT3B0aW9uKCkgYWRkZWQgdGhlIGludGVycHJldGVkIG9wdGlvbnMgaW4gdGhlCisgICAgLy8gVW5rbm93bkZpZWxkU2V0LCBpbiBjYXNlIHRoZSBvcHRpb24gaXNuJ3QgeWV0IGtub3duIHRvIHVzLiAgTm93IHdlCisgICAgLy8gc2VyaWFsaXplIHRoZSBvcHRpb25zIG1lc3NhZ2UgYW5kIGRlc2VyaWFsaXplIGl0IGJhY2suICBUaGF0IHdheSwgYW55CisgICAgLy8gb3B0aW9uIGZpZWxkcyB0aGF0IHdlIGRvIGhhcHBlbiB0byBrbm93IGFib3V0IHdpbGwgZ2V0IG1vdmVkIGZyb20gdGhlCisgICAgLy8gVW5rbm93bkZpZWxkU2V0IGludG8gdGhlIHJlYWwgZmllbGRzLCBhbmQgdGh1cyBiZSBhdmFpbGFibGUgcmlnaHQgYXdheS4KKyAgICAvLyBJZiB0aGV5IGFyZSBub3Qga25vd24sIHRoYXQncyBPSyB0b28uIFRoZXkgd2lsbCBnZXQgcmVwYXJzZWQgaW50byB0aGUKKyAgICAvLyBVbmtub3duRmllbGRTZXQgYW5kIHdhaXQgdGhlcmUgdW50aWwgdGhlIG1lc3NhZ2UgaXMgcGFyc2VkIGJ5IHNvbWV0aGluZworICAgIC8vIHRoYXQgZG9lcyBrbm93IGFib3V0IHRoZSBvcHRpb25zLgorICAgIHN0cmluZyBidWY7CisgICAgR09PR0xFX0NIRUNLKG9wdGlvbnMtPkFwcGVuZFBhcnRpYWxUb1N0cmluZygmYnVmKSkKKyAgICAgICAgPDwgIlByb3RvY29sIG1lc3NhZ2UgY291bGQgbm90IGJlIHNlcmlhbGl6ZWQuIjsKKyAgICBHT09HTEVfQ0hFQ0sob3B0aW9ucy0+UGFyc2VQYXJ0aWFsRnJvbVN0cmluZyhidWYpKQorICAgICAgICA8PCAiUHJvdG9jb2wgbWVzc2FnZSBzZXJpYWxpemVkIGl0c2VsZiBpbiBpbnZhbGlkIGZhc2hpb24uIjsKKyAgICBpZiAoIW9wdGlvbnMtPklzSW5pdGlhbGl6ZWQoKSkgeworICAgICAgYnVpbGRlcl8tPkFkZFdhcm5pbmcoCisgICAgICAgICAgb3B0aW9uc190b19pbnRlcnByZXQtPmVsZW1lbnRfbmFtZSwgKm9yaWdpbmFsX29wdGlvbnMsCisgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yOjpPVEhFUiwKKyAgICAgICAgICAiT3B0aW9ucyBjb3VsZCBub3QgYmUgZnVsbHkgcGFyc2VkIHVzaW5nIHRoZSBwcm90byBkZXNjcmlwdG9ycyAiCisgICAgICAgICAgImNvbXBpbGVkIGludG8gdGhpcyBiaW5hcnkuIE1pc3NpbmcgcmVxdWlyZWQgZmllbGRzOiAiICsKKyAgICAgICAgICBvcHRpb25zLT5Jbml0aWFsaXphdGlvbkVycm9yU3RyaW5nKCkpOworICAgIH0KKyAgfQorICByZXR1cm4gIWZhaWxlZDsKK30KKworYm9vbCBEZXNjcmlwdG9yQnVpbGRlcjo6T3B0aW9uSW50ZXJwcmV0ZXI6OkludGVycHJldFNpbmdsZU9wdGlvbigKKyAgICBNZXNzYWdlKiBvcHRpb25zKSB7CisgIC8vIEZpcnN0IGRvIHNvbWUgYmFzaWMgdmFsaWRhdGlvbi4KKyAgaWYgKHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy0+bmFtZV9zaXplKCkgPT0gMCkgeworICAgIC8vIFRoaXMgc2hvdWxkIG5ldmVyIGhhcHBlbiB1bmxlc3MgdGhlIHBhcnNlciBoYXMgZ29uZSBzZXJpb3VzbHkgYXdyeSBvcgorICAgIC8vIHNvbWVvbmUgaGFzIG1hbnVhbGx5IGNyZWF0ZWQgdGhlIHVuaW50ZXJwcmV0ZWQgb3B0aW9uIGJhZGx5LgorICAgIHJldHVybiBBZGROYW1lRXJyb3IoIk9wdGlvbiBtdXN0IGhhdmUgYSBuYW1lLiIpOworICB9CisgIGlmICh1bmludGVycHJldGVkX29wdGlvbl8tPm5hbWUoMCkubmFtZV9wYXJ0KCkgPT0gInVuaW50ZXJwcmV0ZWRfb3B0aW9uIikgeworICAgIHJldHVybiBBZGROYW1lRXJyb3IoIk9wdGlvbiBtdXN0IG5vdCB1c2UgcmVzZXJ2ZWQgbmFtZSAiCisgICAgICAgICAgICAgICAgICAgICAgICAiXCJ1bmludGVycHJldGVkX29wdGlvblwiLiIpOworICB9CisKKyAgY29uc3QgRGVzY3JpcHRvciogb3B0aW9uc19kZXNjcmlwdG9yID0gTlVMTDsKKyAgLy8gR2V0IHRoZSBvcHRpb25zIG1lc3NhZ2UncyBkZXNjcmlwdG9yIGZyb20gdGhlIGJ1aWxkZXIncyBwb29sLCBzbyB0aGF0IHdlCisgIC8vIGdldCB0aGUgdmVyc2lvbiB0aGF0IGtub3dzIGFib3V0IGFueSBleHRlbnNpb24gb3B0aW9ucyBkZWNsYXJlZCBpbiB0aGUKKyAgLy8gZmlsZSB3ZSdyZSBjdXJyZW50bHkgYnVpbGRpbmcuIFRoZSBkZXNjcmlwdG9yIHNob3VsZCBiZSB0aGVyZSBhcyBsb25nIGFzCisgIC8vIHRoZSBmaWxlIHdlJ3JlIGJ1aWxkaW5nIGltcG9ydGVkICJnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvcnMucHJvdG8iLgorCisgIC8vIE5vdGUgdGhhdCB3ZSB1c2UgRGVzY3JpcHRvckJ1aWxkZXI6OkZpbmRTeW1ib2xOb3RFbmZvcmNpbmdEZXBzKCksIG5vdAorICAvLyBEZXNjcmlwdG9yUG9vbDo6RmluZE1lc3NhZ2VUeXBlQnlOYW1lKCkgYmVjYXVzZSB3ZSdyZSBhbHJlYWR5IGhvbGRpbmcgdGhlCisgIC8vIHBvb2wncyBtdXRleCwgYW5kIHRoZSBsYXR0ZXIgbWV0aG9kIGxvY2tzIGl0IGFnYWluLiAgV2UgZG9uJ3QgdXNlCisgIC8vIEZpbmRTeW1ib2woKSBiZWNhdXNlIGZpbGVzIHRoYXQgdXNlIGN1c3RvbSBvcHRpb25zIG9ubHkgbmVlZCB0byBkZXBlbmQgb24KKyAgLy8gdGhlIGZpbGUgdGhhdCBkZWZpbmVzIHRoZSBvcHRpb24sIG5vdCBkZXNjcmlwdG9yLnByb3RvIGl0c2VsZi4KKyAgU3ltYm9sIHN5bWJvbCA9IGJ1aWxkZXJfLT5GaW5kU3ltYm9sTm90RW5mb3JjaW5nRGVwcygKKyAgICBvcHRpb25zLT5HZXREZXNjcmlwdG9yKCktPmZ1bGxfbmFtZSgpKTsKKyAgaWYgKCFzeW1ib2wuSXNOdWxsKCkgJiYgc3ltYm9sLnR5cGUgPT0gU3ltYm9sOjpNRVNTQUdFKSB7CisgICAgb3B0aW9uc19kZXNjcmlwdG9yID0gc3ltYm9sLmRlc2NyaXB0b3I7CisgIH0gZWxzZSB7CisgICAgLy8gVGhlIG9wdGlvbnMgbWVzc2FnZSdzIGRlc2NyaXB0b3Igd2FzIG5vdCBpbiB0aGUgYnVpbGRlcidzIHBvb2wsIHNvIHVzZQorICAgIC8vIHRoZSBzdGFuZGFyZCB2ZXJzaW9uIGZyb20gdGhlIGdlbmVyYXRlZCBwb29sLiBXZSdyZSBub3QgaG9sZGluZyB0aGUKKyAgICAvLyBnZW5lcmF0ZWQgcG9vbCdzIG11dGV4LCBzbyB3ZSBjYW4gc2VhcmNoIGl0IHRoZSBzdHJhaWdodGZvcndhcmQgd2F5LgorICAgIG9wdGlvbnNfZGVzY3JpcHRvciA9IG9wdGlvbnMtPkdldERlc2NyaXB0b3IoKTsKKyAgfQorICBHT09HTEVfQ0hFQ0sob3B0aW9uc19kZXNjcmlwdG9yKTsKKworICAvLyBXZSBpdGVyYXRlIG92ZXIgdGhlIG5hbWUgcGFydHMgdG8gZHJpbGwgaW50byB0aGUgc3VibWVzc2FnZXMgdW50aWwgd2UgZmluZAorICAvLyB0aGUgbGVhZiBmaWVsZCBmb3IgdGhlIG9wdGlvbi4gQXMgd2UgZHJpbGwgZG93biB3ZSByZW1lbWJlciB0aGUgY3VycmVudAorICAvLyBzdWJtZXNzYWdlJ3MgZGVzY3JpcHRvciBpbiB8ZGVzY3JpcHRvcnwgYW5kIHRoZSBuZXh0IGZpZWxkIGluIHRoYXQKKyAgLy8gc3VibWVzc2FnZSBpbiB8ZmllbGR8LiBXZSBhbHNvIHRyYWNrIHRoZSBmaWVsZHMgd2UncmUgZHJpbGxpbmcgZG93bgorICAvLyB0aHJvdWdoIGluIHxpbnRlcm1lZGlhdGVfZmllbGRzfC4gQXMgd2UgZ28sIHdlIHJlY29uc3RydWN0IHRoZSBmdWxsIG9wdGlvbgorICAvLyBuYW1lIGluIHxkZWJ1Z19tc2dfbmFtZXwsIGZvciB1c2UgaW4gZXJyb3IgbWVzc2FnZXMuCisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBvcHRpb25zX2Rlc2NyaXB0b3I7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBOVUxMOworICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4gaW50ZXJtZWRpYXRlX2ZpZWxkczsKKyAgc3RyaW5nIGRlYnVnX21zZ19uYW1lID0gIiI7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB1bmludGVycHJldGVkX29wdGlvbl8tPm5hbWVfc2l6ZSgpOyArK2kpIHsKKyAgICBjb25zdCBzdHJpbmcmIG5hbWVfcGFydCA9IHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy0+bmFtZShpKS5uYW1lX3BhcnQoKTsKKyAgICBpZiAoZGVidWdfbXNnX25hbWUuc2l6ZSgpID4gMCkgeworICAgICAgZGVidWdfbXNnX25hbWUgKz0gIi4iOworICAgIH0KKyAgICBpZiAodW5pbnRlcnByZXRlZF9vcHRpb25fLT5uYW1lKGkpLmlzX2V4dGVuc2lvbigpKSB7CisgICAgICBkZWJ1Z19tc2dfbmFtZSArPSAiKCIgKyBuYW1lX3BhcnQgKyAiKSI7CisgICAgICAvLyBTZWFyY2ggZm9yIHRoZSBleHRlbnNpb24ncyBkZXNjcmlwdG9yIGFzIGFuIGV4dGVuc2lvbiBpbiB0aGUgYnVpbGRlcidzCisgICAgICAvLyBwb29sLiBOb3RlIHRoYXQgd2UgdXNlIERlc2NyaXB0b3JCdWlsZGVyOjpMb29rdXBTeW1ib2woKSwgbm90CisgICAgICAvLyBEZXNjcmlwdG9yUG9vbDo6RmluZEV4dGVuc2lvbkJ5TmFtZSgpLCBmb3IgdHdvIHJlYXNvbnM6IDEpIEl0IGFsbG93cworICAgICAgLy8gcmVsYXRpdmUgbG9va3VwcywgYW5kIDIpIGJlY2F1c2Ugd2UncmUgYWxyZWFkeSBob2xkaW5nIHRoZSBwb29sJ3MKKyAgICAgIC8vIG11dGV4LCBhbmQgdGhlIGxhdHRlciBtZXRob2QgbG9ja3MgaXQgYWdhaW4uCisgICAgICBzeW1ib2wgPSBidWlsZGVyXy0+TG9va3VwU3ltYm9sKG5hbWVfcGFydCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uc190b19pbnRlcnByZXRfLT5uYW1lX3Njb3BlKTsKKyAgICAgIGlmICghc3ltYm9sLklzTnVsbCgpICYmIHN5bWJvbC50eXBlID09IFN5bWJvbDo6RklFTEQpIHsKKyAgICAgICAgZmllbGQgPSBzeW1ib2wuZmllbGRfZGVzY3JpcHRvcjsKKyAgICAgIH0KKyAgICAgIC8vIElmIHdlIGRvbid0IGZpbmQgdGhlIGZpZWxkIHRoZW4gdGhlIGZpZWxkJ3MgZGVzY3JpcHRvciB3YXMgbm90IGluIHRoZQorICAgICAgLy8gYnVpbGRlcidzIHBvb2wsIGJ1dCB0aGVyZSdzIG5vIHBvaW50IGluIGxvb2tpbmcgaW4gdGhlIGdlbmVyYXRlZAorICAgICAgLy8gcG9vbC4gV2UgcmVxdWlyZSB0aGF0IHlvdSBpbXBvcnQgdGhlIGZpbGUgdGhhdCBkZWZpbmVzIGFueSBleHRlbnNpb25zCisgICAgICAvLyB5b3UgdXNlLCBzbyB0aGV5IG11c3QgYmUgcHJlc2VudCBpbiB0aGUgYnVpbGRlcidzIHBvb2wuCisgICAgfSBlbHNlIHsKKyAgICAgIGRlYnVnX21zZ19uYW1lICs9IG5hbWVfcGFydDsKKyAgICAgIC8vIFNlYXJjaCBmb3IgdGhlIGZpZWxkJ3MgZGVzY3JpcHRvciBhcyBhIHJlZ3VsYXIgZmllbGQuCisgICAgICBmaWVsZCA9IGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZShuYW1lX3BhcnQpOworICAgIH0KKworICAgIGlmIChmaWVsZCA9PSBOVUxMKSB7CisgICAgICBpZiAoZ2V0X2FsbG93X3Vua25vd24oYnVpbGRlcl8tPnBvb2xfKSkgeworICAgICAgICAvLyBXZSBjYW4ndCBmaW5kIHRoZSBvcHRpb24sIGJ1dCBBbGxvd1Vua25vd25EZXBlbmRlbmNpZXMoKSBpcyBlbmFibGVkLAorICAgICAgICAvLyBzbyB3ZSB3aWxsIGp1c3QgbGVhdmUgaXQgYXMgdW5pbnRlcnByZXRlZC4KKyAgICAgICAgQWRkV2l0aG91dEludGVycHJldGluZygqdW5pbnRlcnByZXRlZF9vcHRpb25fLCBvcHRpb25zKTsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICB9IGVsc2UgaWYgKCEoYnVpbGRlcl8tPnVuZGVmaW5lX3Jlc29sdmVkX25hbWVfKS5lbXB0eSgpKSB7CisgICAgICAgIC8vIE9wdGlvbiBpcyByZXNvbHZlZCB0byBhIG5hbWUgd2hpY2ggaXMgbm90IGRlZmluZWQuCisgICAgICAgIHJldHVybiBBZGROYW1lRXJyb3IoCisgICAgICAgICAgICAiT3B0aW9uIFwiIiArIGRlYnVnX21zZ19uYW1lICsgIlwiIGlzIHJlc29sdmVkIHRvIFwiKCIgKworICAgICAgICAgICAgYnVpbGRlcl8tPnVuZGVmaW5lX3Jlc29sdmVkX25hbWVfICsKKyAgICAgICAgICAgICIpXCIsIHdoaWNoIGlzIG5vdCBkZWZpbmVkLiBUaGUgaW5uZXJtb3N0IHNjb3BlIGlzIHNlYXJjaGVkIGZpcnN0ICIKKyAgICAgICAgICAgICJpbiBuYW1lIHJlc29sdXRpb24uIENvbnNpZGVyIHVzaW5nIGEgbGVhZGluZyAnLicoaS5lLiwgXCIoLiIgKworICAgICAgICAgICAgZGVidWdfbXNnX25hbWUuc3Vic3RyKDEpICsKKyAgICAgICAgICAgICJcIikgdG8gc3RhcnQgZnJvbSB0aGUgb3V0ZXJtb3N0IHNjb3BlLiIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcmV0dXJuIEFkZE5hbWVFcnJvcigiT3B0aW9uIFwiIiArIGRlYnVnX21zZ19uYW1lICsgIlwiIHVua25vd24uIik7CisgICAgICB9CisgICAgfSBlbHNlIGlmIChmaWVsZC0+Y29udGFpbmluZ190eXBlKCkgIT0gZGVzY3JpcHRvcikgeworICAgICAgaWYgKGdldF9pc19wbGFjZWhvbGRlcihmaWVsZC0+Y29udGFpbmluZ190eXBlKCkpKSB7CisgICAgICAgIC8vIFRoZSBmaWVsZCBpcyBhbiBleHRlbnNpb24gb2YgYSBwbGFjZWhvbGRlciB0eXBlLCBzbyB3ZSBjYW4ndAorICAgICAgICAvLyByZWxpYWJseSB2ZXJpZnkgd2hldGhlciBpdCBpcyBhIHZhbGlkIGV4dGVuc2lvbiB0byB1c2UgaGVyZSAoZS5nLgorICAgICAgICAvLyB3ZSBkb24ndCBrbm93IGlmIGl0IGlzIGFuIGV4dGVuc2lvbiBvZiB0aGUgY29ycmVjdCAqT3B0aW9ucyBtZXNzYWdlLAorICAgICAgICAvLyBvciBpZiBpdCBoYXMgYSB2YWxpZCBmaWVsZCBudW1iZXIsIGV0Yy4pLiAgSnVzdCBsZWF2ZSBpdCBhcworICAgICAgICAvLyB1bmludGVycHJldGVkIGluc3RlYWQuCisgICAgICAgIEFkZFdpdGhvdXRJbnRlcnByZXRpbmcoKnVuaW50ZXJwcmV0ZWRfb3B0aW9uXywgb3B0aW9ucyk7CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgLy8gVGhpcyBjYW4gb25seSBoYXBwZW4gaWYsIGR1ZSB0byBzb21lIGluc2FuZSBtaXNjb25maWd1cmF0aW9uIG9mIHRoZQorICAgICAgICAvLyBwb29scywgd2UgZmluZCB0aGUgb3B0aW9ucyBtZXNzYWdlIGluIG9uZSBwb29sIGJ1dCB0aGUgZmllbGQgaW4KKyAgICAgICAgLy8gYW5vdGhlci4gVGhpcyB3b3VsZCBwcm9iYWJseSBpbXBseSBhIGhlZnR5IGJ1ZyBzb21ld2hlcmUuCisgICAgICAgIHJldHVybiBBZGROYW1lRXJyb3IoIk9wdGlvbiBmaWVsZCBcIiIgKyBkZWJ1Z19tc2dfbmFtZSArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlwiIGlzIG5vdCBhIGZpZWxkIG9yIGV4dGVuc2lvbiBvZiBtZXNzYWdlIFwiIiArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRvci0+bmFtZSgpICsgIlwiLiIpOworICAgICAgfQorICAgIH0gZWxzZSBpZiAoaSA8IHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy0+bmFtZV9zaXplKCkgLSAxKSB7CisgICAgICBpZiAoZmllbGQtPmNwcF90eXBlKCkgIT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UpIHsKKyAgICAgICAgcmV0dXJuIEFkZE5hbWVFcnJvcigiT3B0aW9uIFwiIiArICBkZWJ1Z19tc2dfbmFtZSArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlwiIGlzIGFuIGF0b21pYyB0eXBlLCBub3QgYSBtZXNzYWdlLiIpOworICAgICAgfSBlbHNlIGlmIChmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgeworICAgICAgICByZXR1cm4gQWRkTmFtZUVycm9yKCJPcHRpb24gZmllbGQgXCIiICsgZGVidWdfbXNnX25hbWUgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICJcIiBpcyBhIHJlcGVhdGVkIG1lc3NhZ2UuIFJlcGVhdGVkIG1lc3NhZ2UgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJvcHRpb25zIG11c3QgYmUgaW5pdGlhbGl6ZWQgdXNpbmcgYW4gIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJhZ2dyZWdhdGUgdmFsdWUuIik7CisgICAgICB9IGVsc2UgeworICAgICAgICAvLyBEcmlsbCBkb3duIGludG8gdGhlIHN1Ym1lc3NhZ2UuCisgICAgICAgIGludGVybWVkaWF0ZV9maWVsZHMucHVzaF9iYWNrKGZpZWxkKTsKKyAgICAgICAgZGVzY3JpcHRvciA9IGZpZWxkLT5tZXNzYWdlX3R5cGUoKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvLyBXZSd2ZSBmb3VuZCB0aGUgbGVhZiBmaWVsZC4gTm93IHdlIHVzZSBVbmtub3duRmllbGRTZXRzIHRvIHNldCBpdHMgdmFsdWUKKyAgLy8gb24gdGhlIG9wdGlvbnMgbWVzc2FnZS4gV2UgZG8gc28gYmVjYXVzZSB0aGUgbWVzc2FnZSBtYXkgbm90IHlldCBrbm93CisgIC8vIGFib3V0IGl0cyBleHRlbnNpb24gZmllbGRzLCBzbyB3ZSBtYXkgbm90IGJlIGFibGUgdG8gc2V0IHRoZSBmaWVsZHMKKyAgLy8gZGlyZWN0bHkuIEJ1dCB0aGUgVW5rbm93bkZpZWxkU2V0cyB3aWxsIHNlcmlhbGl6ZSB0byB0aGUgc2FtZSB3aXJlLWZvcm1hdAorICAvLyBtZXNzYWdlLCBzbyByZWFkaW5nIHRoYXQgbWVzc2FnZSBiYWNrIGluIG9uY2UgdGhlIGV4dGVuc2lvbiBmaWVsZHMgYXJlCisgIC8vIGtub3duIHdpbGwgcG9wdWxhdGUgdGhlbSBjb3JyZWN0bHkuCisKKyAgLy8gRmlyc3Qgc2VlIGlmIHRoZSBvcHRpb24gaXMgYWxyZWFkeSBzZXQuCisgIGlmICghZmllbGQtPmlzX3JlcGVhdGVkKCkgJiYgIUV4YW1pbmVJZk9wdGlvbklzU2V0KAorICAgICAgICAgIGludGVybWVkaWF0ZV9maWVsZHMuYmVnaW4oKSwKKyAgICAgICAgICBpbnRlcm1lZGlhdGVfZmllbGRzLmVuZCgpLAorICAgICAgICAgIGZpZWxkLCBkZWJ1Z19tc2dfbmFtZSwKKyAgICAgICAgICBvcHRpb25zLT5HZXRSZWZsZWN0aW9uKCktPkdldFVua25vd25GaWVsZHMoKm9wdGlvbnMpKSkgeworICAgIHJldHVybiBmYWxzZTsgIC8vIEV4YW1pbmVJZk9wdGlvbklzU2V0KCkgYWxyZWFkeSBhZGRlZCB0aGUgZXJyb3IuCisgIH0KKworCisgIC8vIEZpcnN0IHNldCB0aGUgdmFsdWUgb24gdGhlIFVua25vd25GaWVsZFNldCBjb3JyZXNwb25kaW5nIHRvIHRoZQorICAvLyBpbm5lcm1vc3QgbWVzc2FnZS4KKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxVbmtub3duRmllbGRTZXQ+IHVua25vd25fZmllbGRzKG5ldyBVbmtub3duRmllbGRTZXQoKSk7CisgIGlmICghU2V0T3B0aW9uVmFsdWUoZmllbGQsIHVua25vd25fZmllbGRzLmdldCgpKSkgeworICAgIHJldHVybiBmYWxzZTsgIC8vIFNldE9wdGlvblZhbHVlKCkgYWxyZWFkeSBhZGRlZCB0aGUgZXJyb3IuCisgIH0KKworICAvLyBOb3cgd3JhcCB0aGUgVW5rbm93bkZpZWxkU2V0IHdpdGggVW5rbm93bkZpZWxkU2V0cyBjb3JyZXNwb25kaW5nIHRvIGFsbAorICAvLyB0aGUgaW50ZXJtZWRpYXRlIG1lc3NhZ2VzLgorICBmb3IgKHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPjo6cmV2ZXJzZV9pdGVyYXRvciBpdGVyID0KKyAgICAgICAgICAgaW50ZXJtZWRpYXRlX2ZpZWxkcy5yYmVnaW4oKTsKKyAgICAgICBpdGVyICE9IGludGVybWVkaWF0ZV9maWVsZHMucmVuZCgpOyArK2l0ZXIpIHsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPFVua25vd25GaWVsZFNldD4gcGFyZW50X3Vua25vd25fZmllbGRzKAorICAgICAgICBuZXcgVW5rbm93bkZpZWxkU2V0KCkpOworICAgIHN3aXRjaCAoKCppdGVyKS0+dHlwZSgpKSB7CisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9NRVNTQUdFOiB7CisgICAgICAgIGlvOjpTdHJpbmdPdXRwdXRTdHJlYW0gb3V0c3RyKAorICAgICAgICAgICAgcGFyZW50X3Vua25vd25fZmllbGRzLT5BZGRMZW5ndGhEZWxpbWl0ZWQoKCppdGVyKS0+bnVtYmVyKCkpKTsKKyAgICAgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtIG91dCgmb3V0c3RyKTsKKyAgICAgICAgaW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25GaWVsZHMoKnVua25vd25fZmllbGRzLCAmb3V0KTsKKyAgICAgICAgR09PR0xFX0NIRUNLKCFvdXQuSGFkRXJyb3IoKSkKKyAgICAgICAgICAgIDw8ICJVbmV4cGVjdGVkIGZhaWx1cmUgd2hpbGUgc2VyaWFsaXppbmcgb3B0aW9uIHN1Ym1lc3NhZ2UgIgorICAgICAgICAgICAgPDwgZGVidWdfbXNnX25hbWUgPDwgIlwiLiI7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9HUk9VUDogeworICAgICAgICAgcGFyZW50X3Vua25vd25fZmllbGRzLT5BZGRHcm91cCgoKml0ZXIpLT5udW1iZXIoKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0+TWVyZ2VGcm9tKCp1bmtub3duX2ZpZWxkcyk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBkZWZhdWx0OgorICAgICAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiSW52YWxpZCB3aXJlIHR5cGUgZm9yIENQUFRZUEVfTUVTU0FHRTogIgorICAgICAgICAgICAgICAgICAgIDw8ICgqaXRlciktPnR5cGUoKTsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICB1bmtub3duX2ZpZWxkcy5yZXNldChwYXJlbnRfdW5rbm93bl9maWVsZHMucmVsZWFzZSgpKTsKKyAgfQorCisgIC8vIE5vdyBtZXJnZSB0aGUgVW5rbm93bkZpZWxkU2V0IGNvcnJlc3BvbmRpbmcgdG8gdGhlIHRvcC1sZXZlbCBtZXNzYWdlIGludG8KKyAgLy8gdGhlIG9wdGlvbnMgbWVzc2FnZS4KKyAgb3B0aW9ucy0+R2V0UmVmbGVjdGlvbigpLT5NdXRhYmxlVW5rbm93bkZpZWxkcyhvcHRpb25zKS0+TWVyZ2VGcm9tKAorICAgICAgKnVua25vd25fZmllbGRzKTsKKworICByZXR1cm4gdHJ1ZTsKK30KKwordm9pZCBEZXNjcmlwdG9yQnVpbGRlcjo6T3B0aW9uSW50ZXJwcmV0ZXI6OkFkZFdpdGhvdXRJbnRlcnByZXRpbmcoCisgICAgY29uc3QgVW5pbnRlcnByZXRlZE9wdGlvbiYgdW5pbnRlcnByZXRlZF9vcHRpb24sIE1lc3NhZ2UqIG9wdGlvbnMpIHsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9CisgICAgb3B0aW9ucy0+R2V0RGVzY3JpcHRvcigpLT5GaW5kRmllbGRCeU5hbWUoInVuaW50ZXJwcmV0ZWRfb3B0aW9uIik7CisgIEdPT0dMRV9DSEVDSyhmaWVsZCAhPSBOVUxMKTsKKworICBvcHRpb25zLT5HZXRSZWZsZWN0aW9uKCktPkFkZE1lc3NhZ2Uob3B0aW9ucywgZmllbGQpCisgICAgLT5Db3B5RnJvbSh1bmludGVycHJldGVkX29wdGlvbik7Cit9CisKK2Jvb2wgRGVzY3JpcHRvckJ1aWxkZXI6Ok9wdGlvbkludGVycHJldGVyOjpFeGFtaW5lSWZPcHRpb25Jc1NldCgKKyAgICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj46OmNvbnN0X2l0ZXJhdG9yIGludGVybWVkaWF0ZV9maWVsZHNfaXRlciwKKyAgICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj46OmNvbnN0X2l0ZXJhdG9yIGludGVybWVkaWF0ZV9maWVsZHNfZW5kLAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogaW5uZXJtb3N0X2ZpZWxkLCBjb25zdCBzdHJpbmcmIGRlYnVnX21zZ19uYW1lLAorICAgIGNvbnN0IFVua25vd25GaWVsZFNldCYgdW5rbm93bl9maWVsZHMpIHsKKyAgLy8gV2UgZG8gbGluZWFyIHNlYXJjaGVzIG9mIHRoZSBVbmtub3duRmllbGRTZXQgYW5kIGl0cyBzdWItZ3JvdXBzLiAgVGhpcworICAvLyBzaG91bGQgYmUgZmluZSBzaW5jZSBpdCdzIHVubGlrZWx5IHRoYXQgYW55IG9uZSBvcHRpb25zIHN0cnVjdHVyZSB3aWxsCisgIC8vIGNvbnRhaW4gbW9yZSB0aGFuIGEgaGFuZGZ1bCBvZiBvcHRpb25zLgorCisgIGlmIChpbnRlcm1lZGlhdGVfZmllbGRzX2l0ZXIgPT0gaW50ZXJtZWRpYXRlX2ZpZWxkc19lbmQpIHsKKyAgICAvLyBXZSdyZSBhdCB0aGUgaW5uZXJtb3N0IHN1Ym1lc3NhZ2UuCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB1bmtub3duX2ZpZWxkcy5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICAgIGlmICh1bmtub3duX2ZpZWxkcy5maWVsZChpKS5udW1iZXIoKSA9PSBpbm5lcm1vc3RfZmllbGQtPm51bWJlcigpKSB7CisgICAgICAgIHJldHVybiBBZGROYW1lRXJyb3IoIk9wdGlvbiBcIiIgKyBkZWJ1Z19tc2dfbmFtZSArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlwiIHdhcyBhbHJlYWR5IHNldC4iKTsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IHVua25vd25fZmllbGRzLmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGlmICh1bmtub3duX2ZpZWxkcy5maWVsZChpKS5udW1iZXIoKSA9PQorICAgICAgICAoKmludGVybWVkaWF0ZV9maWVsZHNfaXRlciktPm51bWJlcigpKSB7CisgICAgICBjb25zdCBVbmtub3duRmllbGQqIHVua25vd25fZmllbGQgPSAmdW5rbm93bl9maWVsZHMuZmllbGQoaSk7CisgICAgICBGaWVsZERlc2NyaXB0b3I6OlR5cGUgdHlwZSA9ICgqaW50ZXJtZWRpYXRlX2ZpZWxkc19pdGVyKS0+dHlwZSgpOworICAgICAgLy8gUmVjdXJzZSBpbnRvIHRoZSBuZXh0IHN1Ym1lc3NhZ2UuCisgICAgICBzd2l0Y2ggKHR5cGUpIHsKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfTUVTU0FHRToKKyAgICAgICAgICBpZiAodW5rbm93bl9maWVsZC0+dHlwZSgpID09IFVua25vd25GaWVsZDo6VFlQRV9MRU5HVEhfREVMSU1JVEVEKSB7CisgICAgICAgICAgICBVbmtub3duRmllbGRTZXQgaW50ZXJtZWRpYXRlX3Vua25vd25fZmllbGRzOworICAgICAgICAgICAgaWYgKGludGVybWVkaWF0ZV91bmtub3duX2ZpZWxkcy5QYXJzZUZyb21TdHJpbmcoCisgICAgICAgICAgICAgICAgICAgIHVua25vd25fZmllbGQtPmxlbmd0aF9kZWxpbWl0ZWQoKSkgJiYKKyAgICAgICAgICAgICAgICAhRXhhbWluZUlmT3B0aW9uSXNTZXQoaW50ZXJtZWRpYXRlX2ZpZWxkc19pdGVyICsgMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJtZWRpYXRlX2ZpZWxkc19lbmQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlubmVybW9zdF9maWVsZCwgZGVidWdfbXNnX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludGVybWVkaWF0ZV91bmtub3duX2ZpZWxkcykpIHsKKyAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOyAgLy8gRXJyb3IgYWxyZWFkeSBhZGRlZC4KKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9CisgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfR1JPVVA6CisgICAgICAgICAgaWYgKHVua25vd25fZmllbGQtPnR5cGUoKSA9PSBVbmtub3duRmllbGQ6OlRZUEVfR1JPVVApIHsKKyAgICAgICAgICAgIGlmICghRXhhbWluZUlmT3B0aW9uSXNTZXQoaW50ZXJtZWRpYXRlX2ZpZWxkc19pdGVyICsgMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJtZWRpYXRlX2ZpZWxkc19lbmQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlubmVybW9zdF9maWVsZCwgZGVidWdfbXNnX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVua25vd25fZmllbGQtPmdyb3VwKCkpKSB7CisgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsgIC8vIEVycm9yIGFscmVhZHkgYWRkZWQuCisgICAgICAgICAgICB9CisgICAgICAgICAgfQorICAgICAgICAgIGJyZWFrOworCisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkludmFsaWQgd2lyZSB0eXBlIGZvciBDUFBUWVBFX01FU1NBR0U6ICIgPDwgdHlwZTsKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgfQorICB9CisgIHJldHVybiB0cnVlOworfQorCitib29sIERlc2NyaXB0b3JCdWlsZGVyOjpPcHRpb25JbnRlcnByZXRlcjo6U2V0T3B0aW9uVmFsdWUoCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBvcHRpb25fZmllbGQsCisgICAgVW5rbm93bkZpZWxkU2V0KiB1bmtub3duX2ZpZWxkcykgeworICAvLyBXZSBzd2l0Y2ggb24gdGhlIENwcFR5cGUgdG8gdmFsaWRhdGUuCisgIHN3aXRjaCAob3B0aW9uX2ZpZWxkLT5jcHBfdHlwZSgpKSB7CisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9JTlQzMjoKKyAgICAgIGlmICh1bmludGVycHJldGVkX29wdGlvbl8tPmhhc19wb3NpdGl2ZV9pbnRfdmFsdWUoKSkgeworICAgICAgICBpZiAodW5pbnRlcnByZXRlZF9vcHRpb25fLT5wb3NpdGl2ZV9pbnRfdmFsdWUoKSA+CisgICAgICAgICAgICBzdGF0aWNfY2FzdDx1aW50NjQ+KGtpbnQzMm1heCkpIHsKKyAgICAgICAgICByZXR1cm4gQWRkVmFsdWVFcnJvcigiVmFsdWUgb3V0IG9mIHJhbmdlIGZvciBpbnQzMiBvcHRpb24gXCIiICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25fZmllbGQtPmZ1bGxfbmFtZSgpICsgIlwiLiIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIFNldEludDMyKG9wdGlvbl9maWVsZC0+bnVtYmVyKCksCisgICAgICAgICAgICAgICAgICAgdW5pbnRlcnByZXRlZF9vcHRpb25fLT5wb3NpdGl2ZV9pbnRfdmFsdWUoKSwKKyAgICAgICAgICAgICAgICAgICBvcHRpb25fZmllbGQtPnR5cGUoKSwgdW5rbm93bl9maWVsZHMpOworICAgICAgICB9CisgICAgICB9IGVsc2UgaWYgKHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy0+aGFzX25lZ2F0aXZlX2ludF92YWx1ZSgpKSB7CisgICAgICAgIGlmICh1bmludGVycHJldGVkX29wdGlvbl8tPm5lZ2F0aXZlX2ludF92YWx1ZSgpIDwKKyAgICAgICAgICAgIHN0YXRpY19jYXN0PGludDY0PihraW50MzJtaW4pKSB7CisgICAgICAgICAgcmV0dXJuIEFkZFZhbHVlRXJyb3IoIlZhbHVlIG91dCBvZiByYW5nZSBmb3IgaW50MzIgb3B0aW9uIFwiIiArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uX2ZpZWxkLT5mdWxsX25hbWUoKSArICJcIi4iKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBTZXRJbnQzMihvcHRpb25fZmllbGQtPm51bWJlcigpLAorICAgICAgICAgICAgICAgICAgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy0+bmVnYXRpdmVfaW50X3ZhbHVlKCksCisgICAgICAgICAgICAgICAgICAgb3B0aW9uX2ZpZWxkLT50eXBlKCksIHVua25vd25fZmllbGRzKTsKKyAgICAgICAgfQorICAgICAgfSBlbHNlIHsKKyAgICAgICAgcmV0dXJuIEFkZFZhbHVlRXJyb3IoIlZhbHVlIG11c3QgYmUgaW50ZWdlciBmb3IgaW50MzIgb3B0aW9uIFwiIiArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbl9maWVsZC0+ZnVsbF9uYW1lKCkgKyAiXCIuIik7CisgICAgICB9CisgICAgICBicmVhazsKKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0lOVDY0OgorICAgICAgaWYgKHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy0+aGFzX3Bvc2l0aXZlX2ludF92YWx1ZSgpKSB7CisgICAgICAgIGlmICh1bmludGVycHJldGVkX29wdGlvbl8tPnBvc2l0aXZlX2ludF92YWx1ZSgpID4KKyAgICAgICAgICAgIHN0YXRpY19jYXN0PHVpbnQ2ND4oa2ludDY0bWF4KSkgeworICAgICAgICAgIHJldHVybiBBZGRWYWx1ZUVycm9yKCJWYWx1ZSBvdXQgb2YgcmFuZ2UgZm9yIGludDY0IG9wdGlvbiBcIiIgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbl9maWVsZC0+ZnVsbF9uYW1lKCkgKyAiXCIuIik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgU2V0SW50NjQob3B0aW9uX2ZpZWxkLT5udW1iZXIoKSwKKyAgICAgICAgICAgICAgICAgICB1bmludGVycHJldGVkX29wdGlvbl8tPnBvc2l0aXZlX2ludF92YWx1ZSgpLAorICAgICAgICAgICAgICAgICAgIG9wdGlvbl9maWVsZC0+dHlwZSgpLCB1bmtub3duX2ZpZWxkcyk7CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSBpZiAodW5pbnRlcnByZXRlZF9vcHRpb25fLT5oYXNfbmVnYXRpdmVfaW50X3ZhbHVlKCkpIHsKKyAgICAgICAgU2V0SW50NjQob3B0aW9uX2ZpZWxkLT5udW1iZXIoKSwKKyAgICAgICAgICAgICAgICAgdW5pbnRlcnByZXRlZF9vcHRpb25fLT5uZWdhdGl2ZV9pbnRfdmFsdWUoKSwKKyAgICAgICAgICAgICAgICAgb3B0aW9uX2ZpZWxkLT50eXBlKCksIHVua25vd25fZmllbGRzKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiBBZGRWYWx1ZUVycm9yKCJWYWx1ZSBtdXN0IGJlIGludGVnZXIgZm9yIGludDY0IG9wdGlvbiBcIiIgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25fZmllbGQtPmZ1bGxfbmFtZSgpICsgIlwiLiIpOworICAgICAgfQorICAgICAgYnJlYWs7CisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9VSU5UMzI6CisgICAgICBpZiAodW5pbnRlcnByZXRlZF9vcHRpb25fLT5oYXNfcG9zaXRpdmVfaW50X3ZhbHVlKCkpIHsKKyAgICAgICAgaWYgKHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy0+cG9zaXRpdmVfaW50X3ZhbHVlKCkgPiBrdWludDMybWF4KSB7CisgICAgICAgICAgcmV0dXJuIEFkZFZhbHVlRXJyb3IoIlZhbHVlIG91dCBvZiByYW5nZSBmb3IgdWludDMyIG9wdGlvbiBcIiIgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbl9maWVsZC0+bmFtZSgpICsgIlwiLiIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIFNldFVJbnQzMihvcHRpb25fZmllbGQtPm51bWJlcigpLAorICAgICAgICAgICAgICAgICAgICB1bmludGVycHJldGVkX29wdGlvbl8tPnBvc2l0aXZlX2ludF92YWx1ZSgpLAorICAgICAgICAgICAgICAgICAgICBvcHRpb25fZmllbGQtPnR5cGUoKSwgdW5rbm93bl9maWVsZHMpOworICAgICAgICB9CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gQWRkVmFsdWVFcnJvcigiVmFsdWUgbXVzdCBiZSBub24tbmVnYXRpdmUgaW50ZWdlciBmb3IgdWludDMyICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm9wdGlvbiBcIiIgKyBvcHRpb25fZmllbGQtPmZ1bGxfbmFtZSgpICsgIlwiLiIpOworICAgICAgfQorICAgICAgYnJlYWs7CisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9VSU5UNjQ6CisgICAgICBpZiAodW5pbnRlcnByZXRlZF9vcHRpb25fLT5oYXNfcG9zaXRpdmVfaW50X3ZhbHVlKCkpIHsKKyAgICAgICAgU2V0VUludDY0KG9wdGlvbl9maWVsZC0+bnVtYmVyKCksCisgICAgICAgICAgICAgICAgICB1bmludGVycHJldGVkX29wdGlvbl8tPnBvc2l0aXZlX2ludF92YWx1ZSgpLAorICAgICAgICAgICAgICAgICAgb3B0aW9uX2ZpZWxkLT50eXBlKCksIHVua25vd25fZmllbGRzKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiBBZGRWYWx1ZUVycm9yKCJWYWx1ZSBtdXN0IGJlIG5vbi1uZWdhdGl2ZSBpbnRlZ2VyIGZvciB1aW50NjQgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib3B0aW9uIFwiIiArIG9wdGlvbl9maWVsZC0+ZnVsbF9uYW1lKCkgKyAiXCIuIik7CisgICAgICB9CisgICAgICBicmVhazsKKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0ZMT0FUOiB7CisgICAgICBmbG9hdCB2YWx1ZTsKKyAgICAgIGlmICh1bmludGVycHJldGVkX29wdGlvbl8tPmhhc19kb3VibGVfdmFsdWUoKSkgeworICAgICAgICB2YWx1ZSA9IHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy0+ZG91YmxlX3ZhbHVlKCk7CisgICAgICB9IGVsc2UgaWYgKHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy0+aGFzX3Bvc2l0aXZlX2ludF92YWx1ZSgpKSB7CisgICAgICAgIHZhbHVlID0gdW5pbnRlcnByZXRlZF9vcHRpb25fLT5wb3NpdGl2ZV9pbnRfdmFsdWUoKTsKKyAgICAgIH0gZWxzZSBpZiAodW5pbnRlcnByZXRlZF9vcHRpb25fLT5oYXNfbmVnYXRpdmVfaW50X3ZhbHVlKCkpIHsKKyAgICAgICAgdmFsdWUgPSB1bmludGVycHJldGVkX29wdGlvbl8tPm5lZ2F0aXZlX2ludF92YWx1ZSgpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcmV0dXJuIEFkZFZhbHVlRXJyb3IoIlZhbHVlIG11c3QgYmUgbnVtYmVyIGZvciBmbG9hdCBvcHRpb24gXCIiICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uX2ZpZWxkLT5mdWxsX25hbWUoKSArICJcIi4iKTsKKyAgICAgIH0KKyAgICAgIHVua25vd25fZmllbGRzLT5BZGRGaXhlZDMyKG9wdGlvbl9maWVsZC0+bnVtYmVyKCksCisgICAgICAgICAgZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpFbmNvZGVGbG9hdCh2YWx1ZSkpOworICAgICAgYnJlYWs7CisgICAgfQorCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRE9VQkxFOiB7CisgICAgICBkb3VibGUgdmFsdWU7CisgICAgICBpZiAodW5pbnRlcnByZXRlZF9vcHRpb25fLT5oYXNfZG91YmxlX3ZhbHVlKCkpIHsKKyAgICAgICAgdmFsdWUgPSB1bmludGVycHJldGVkX29wdGlvbl8tPmRvdWJsZV92YWx1ZSgpOworICAgICAgfSBlbHNlIGlmICh1bmludGVycHJldGVkX29wdGlvbl8tPmhhc19wb3NpdGl2ZV9pbnRfdmFsdWUoKSkgeworICAgICAgICB2YWx1ZSA9IHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy0+cG9zaXRpdmVfaW50X3ZhbHVlKCk7CisgICAgICB9IGVsc2UgaWYgKHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy0+aGFzX25lZ2F0aXZlX2ludF92YWx1ZSgpKSB7CisgICAgICAgIHZhbHVlID0gdW5pbnRlcnByZXRlZF9vcHRpb25fLT5uZWdhdGl2ZV9pbnRfdmFsdWUoKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiBBZGRWYWx1ZUVycm9yKCJWYWx1ZSBtdXN0IGJlIG51bWJlciBmb3IgZG91YmxlIG9wdGlvbiBcIiIgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25fZmllbGQtPmZ1bGxfbmFtZSgpICsgIlwiLiIpOworICAgICAgfQorICAgICAgdW5rbm93bl9maWVsZHMtPkFkZEZpeGVkNjQob3B0aW9uX2ZpZWxkLT5udW1iZXIoKSwKKyAgICAgICAgICBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkVuY29kZURvdWJsZSh2YWx1ZSkpOworICAgICAgYnJlYWs7CisgICAgfQorCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfQk9PTDoKKyAgICAgIHVpbnQ2NCB2YWx1ZTsKKyAgICAgIGlmICghdW5pbnRlcnByZXRlZF9vcHRpb25fLT5oYXNfaWRlbnRpZmllcl92YWx1ZSgpKSB7CisgICAgICAgIHJldHVybiBBZGRWYWx1ZUVycm9yKCJWYWx1ZSBtdXN0IGJlIGlkZW50aWZpZXIgZm9yIGJvb2xlYW4gb3B0aW9uICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlwiIiArIG9wdGlvbl9maWVsZC0+ZnVsbF9uYW1lKCkgKyAiXCIuIik7CisgICAgICB9CisgICAgICBpZiAodW5pbnRlcnByZXRlZF9vcHRpb25fLT5pZGVudGlmaWVyX3ZhbHVlKCkgPT0gInRydWUiKSB7CisgICAgICAgIHZhbHVlID0gMTsKKyAgICAgIH0gZWxzZSBpZiAodW5pbnRlcnByZXRlZF9vcHRpb25fLT5pZGVudGlmaWVyX3ZhbHVlKCkgPT0gImZhbHNlIikgeworICAgICAgICB2YWx1ZSA9IDA7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gQWRkVmFsdWVFcnJvcigiVmFsdWUgbXVzdCBiZSBcInRydWVcIiBvciBcImZhbHNlXCIgZm9yIGJvb2xlYW4gIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib3B0aW9uIFwiIiArIG9wdGlvbl9maWVsZC0+ZnVsbF9uYW1lKCkgKyAiXCIuIik7CisgICAgICB9CisgICAgICB1bmtub3duX2ZpZWxkcy0+QWRkVmFyaW50KG9wdGlvbl9maWVsZC0+bnVtYmVyKCksIHZhbHVlKTsKKyAgICAgIGJyZWFrOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRU5VTTogeworICAgICAgaWYgKCF1bmludGVycHJldGVkX29wdGlvbl8tPmhhc19pZGVudGlmaWVyX3ZhbHVlKCkpIHsKKyAgICAgICAgcmV0dXJuIEFkZFZhbHVlRXJyb3IoIlZhbHVlIG11c3QgYmUgaWRlbnRpZmllciBmb3IgZW51bS12YWx1ZWQgb3B0aW9uICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlwiIiArIG9wdGlvbl9maWVsZC0+ZnVsbF9uYW1lKCkgKyAiXCIuIik7CisgICAgICB9CisgICAgICBjb25zdCBFbnVtRGVzY3JpcHRvciogZW51bV90eXBlID0gb3B0aW9uX2ZpZWxkLT5lbnVtX3R5cGUoKTsKKyAgICAgIGNvbnN0IHN0cmluZyYgdmFsdWVfbmFtZSA9IHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy0+aWRlbnRpZmllcl92YWx1ZSgpOworICAgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogZW51bV92YWx1ZSA9IE5VTEw7CisKKyAgICAgIGlmIChlbnVtX3R5cGUtPmZpbGUoKS0+cG9vbCgpICE9IERlc2NyaXB0b3JQb29sOjpnZW5lcmF0ZWRfcG9vbCgpKSB7CisgICAgICAgIC8vIE5vdGUgdGhhdCB0aGUgZW51bSB2YWx1ZSdzIGZ1bGx5LXF1YWxpZmllZCBuYW1lIGlzIGEgc2libGluZyBvZiB0aGUKKyAgICAgICAgLy8gZW51bSdzIG5hbWUsIG5vdCBhIGNoaWxkIG9mIGl0LgorICAgICAgICBzdHJpbmcgZnVsbHlfcXVhbGlmaWVkX25hbWUgPSBlbnVtX3R5cGUtPmZ1bGxfbmFtZSgpOworICAgICAgICBmdWxseV9xdWFsaWZpZWRfbmFtZS5yZXNpemUoZnVsbHlfcXVhbGlmaWVkX25hbWUuc2l6ZSgpIC0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudW1fdHlwZS0+bmFtZSgpLnNpemUoKSk7CisgICAgICAgIGZ1bGx5X3F1YWxpZmllZF9uYW1lICs9IHZhbHVlX25hbWU7CisKKyAgICAgICAgLy8gU2VhcmNoIGZvciB0aGUgZW51bSB2YWx1ZSdzIGRlc2NyaXB0b3IgaW4gdGhlIGJ1aWxkZXIncyBwb29sLiBOb3RlCisgICAgICAgIC8vIHRoYXQgd2UgdXNlIERlc2NyaXB0b3JCdWlsZGVyOjpGaW5kU3ltYm9sTm90RW5mb3JjaW5nRGVwcygpLCBub3QKKyAgICAgICAgLy8gRGVzY3JpcHRvclBvb2w6OkZpbmRFbnVtVmFsdWVCeU5hbWUoKSBiZWNhdXNlIHdlJ3JlIGFscmVhZHkgaG9sZGluZworICAgICAgICAvLyB0aGUgcG9vbCdzIG11dGV4LCBhbmQgdGhlIGxhdHRlciBtZXRob2QgbG9ja3MgaXQgYWdhaW4uCisgICAgICAgIFN5bWJvbCBzeW1ib2wgPQorICAgICAgICAgIGJ1aWxkZXJfLT5GaW5kU3ltYm9sTm90RW5mb3JjaW5nRGVwcyhmdWxseV9xdWFsaWZpZWRfbmFtZSk7CisgICAgICAgIGlmICghc3ltYm9sLklzTnVsbCgpICYmIHN5bWJvbC50eXBlID09IFN5bWJvbDo6RU5VTV9WQUxVRSkgeworICAgICAgICAgIGlmIChzeW1ib2wuZW51bV92YWx1ZV9kZXNjcmlwdG9yLT50eXBlKCkgIT0gZW51bV90eXBlKSB7CisgICAgICAgICAgICByZXR1cm4gQWRkVmFsdWVFcnJvcigiRW51bSB0eXBlIFwiIiArIGVudW1fdHlwZS0+ZnVsbF9uYW1lKCkgKworICAgICAgICAgICAgICAgICJcIiBoYXMgbm8gdmFsdWUgbmFtZWQgXCIiICsgdmFsdWVfbmFtZSArICJcIiBmb3Igb3B0aW9uIFwiIiArCisgICAgICAgICAgICAgICAgb3B0aW9uX2ZpZWxkLT5mdWxsX25hbWUoKSArCisgICAgICAgICAgICAgICAgIlwiLiBUaGlzIGFwcGVhcnMgdG8gYmUgYSB2YWx1ZSBmcm9tIGEgc2libGluZyB0eXBlLiIpOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBlbnVtX3ZhbHVlID0gc3ltYm9sLmVudW1fdmFsdWVfZGVzY3JpcHRvcjsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSB7CisgICAgICAgIC8vIFRoZSBlbnVtIHR5cGUgaXMgaW4gdGhlIGdlbmVyYXRlZCBwb29sLCBzbyB3ZSBjYW4gc2VhcmNoIGZvciB0aGUKKyAgICAgICAgLy8gdmFsdWUgdGhlcmUuCisgICAgICAgIGVudW1fdmFsdWUgPSBlbnVtX3R5cGUtPkZpbmRWYWx1ZUJ5TmFtZSh2YWx1ZV9uYW1lKTsKKyAgICAgIH0KKworICAgICAgaWYgKGVudW1fdmFsdWUgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gQWRkVmFsdWVFcnJvcigiRW51bSB0eXBlIFwiIiArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbl9maWVsZC0+ZW51bV90eXBlKCktPmZ1bGxfbmFtZSgpICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlwiIGhhcyBubyB2YWx1ZSBuYW1lZCBcIiIgKyB2YWx1ZV9uYW1lICsgIlwiIGZvciAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJvcHRpb24gXCIiICsgb3B0aW9uX2ZpZWxkLT5mdWxsX25hbWUoKSArICJcIi4iKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIC8vIFNpZ24tZXh0ZW5zaW9uIGlzIG5vdCBhIHByb2JsZW0sIHNpbmNlIHdlIGNhc3QgZGlyZWN0bHkgZnJvbSBpbnQzMiB0bworICAgICAgICAvLyB1aW50NjQsIHdpdGhvdXQgZmlyc3QgZ29pbmcgdGhyb3VnaCB1aW50MzIuCisgICAgICAgIHVua25vd25fZmllbGRzLT5BZGRWYXJpbnQob3B0aW9uX2ZpZWxkLT5udW1iZXIoKSwKKyAgICAgICAgICBzdGF0aWNfY2FzdDx1aW50NjQ+KHN0YXRpY19jYXN0PGludDY0PihlbnVtX3ZhbHVlLT5udW1iZXIoKSkpKTsKKyAgICAgIH0KKyAgICAgIGJyZWFrOworICAgIH0KKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORzoKKyAgICAgIGlmICghdW5pbnRlcnByZXRlZF9vcHRpb25fLT5oYXNfc3RyaW5nX3ZhbHVlKCkpIHsKKyAgICAgICAgcmV0dXJuIEFkZFZhbHVlRXJyb3IoIlZhbHVlIG11c3QgYmUgcXVvdGVkIHN0cmluZyBmb3Igc3RyaW5nIG9wdGlvbiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJcIiIgKyBvcHRpb25fZmllbGQtPmZ1bGxfbmFtZSgpICsgIlwiLiIpOworICAgICAgfQorICAgICAgLy8gVGhlIHN0cmluZyBoYXMgYWxyZWFkeSBiZWVuIHVucXVvdGVkIGFuZCB1bmVzY2FwZWQgYnkgdGhlIHBhcnNlci4KKyAgICAgIHVua25vd25fZmllbGRzLT5BZGRMZW5ndGhEZWxpbWl0ZWQob3B0aW9uX2ZpZWxkLT5udW1iZXIoKSwKKyAgICAgICAgICB1bmludGVycHJldGVkX29wdGlvbl8tPnN0cmluZ192YWx1ZSgpKTsKKyAgICAgIGJyZWFrOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRToKKyAgICAgIGlmICghU2V0QWdncmVnYXRlT3B0aW9uKG9wdGlvbl9maWVsZCwgdW5rbm93bl9maWVsZHMpKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICAgIGJyZWFrOworICB9CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK2NsYXNzIERlc2NyaXB0b3JCdWlsZGVyOjpPcHRpb25JbnRlcnByZXRlcjo6QWdncmVnYXRlT3B0aW9uRmluZGVyCisgICAgOiBwdWJsaWMgVGV4dEZvcm1hdDo6RmluZGVyIHsKKyBwdWJsaWM6CisgIERlc2NyaXB0b3JCdWlsZGVyKiBidWlsZGVyXzsKKworICB2aXJ0dWFsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogRmluZEV4dGVuc2lvbigKKyAgICAgIE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IHN0cmluZyYgbmFtZSkgY29uc3QgeworICAgIGFzc2VydF9tdXRleF9oZWxkKGJ1aWxkZXJfLT5wb29sXyk7CisgICAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciA9IG1lc3NhZ2UtPkdldERlc2NyaXB0b3IoKTsKKyAgICBTeW1ib2wgcmVzdWx0ID0gYnVpbGRlcl8tPkxvb2t1cFN5bWJvbE5vUGxhY2Vob2xkZXIoCisgICAgICAgIG5hbWUsIGRlc2NyaXB0b3ItPmZ1bGxfbmFtZSgpKTsKKyAgICBpZiAocmVzdWx0LnR5cGUgPT0gU3ltYm9sOjpGSUVMRCAmJgorICAgICAgICByZXN1bHQuZmllbGRfZGVzY3JpcHRvci0+aXNfZXh0ZW5zaW9uKCkpIHsKKyAgICAgIHJldHVybiByZXN1bHQuZmllbGRfZGVzY3JpcHRvcjsKKyAgICB9IGVsc2UgaWYgKHJlc3VsdC50eXBlID09IFN5bWJvbDo6TUVTU0FHRSAmJgorICAgICAgICAgICAgICAgZGVzY3JpcHRvci0+b3B0aW9ucygpLm1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KCkpIHsKKyAgICAgIGNvbnN0IERlc2NyaXB0b3IqIGZvcmVpZ25fdHlwZSA9IHJlc3VsdC5kZXNjcmlwdG9yOworICAgICAgLy8gVGhlIHRleHQgZm9ybWF0IGFsbG93cyBNZXNzYWdlU2V0IGl0ZW1zIHRvIGJlIHNwZWNpZmllZCB1c2luZworICAgICAgLy8gdGhlIHR5cGUgbmFtZSwgcmF0aGVyIHRoYW4gdGhlIGV4dGVuc2lvbiBpZGVudGlmaWVyLiBJZiB0aGUgc3ltYm9sCisgICAgICAvLyBsb29rdXAgcmV0dXJuZWQgYSBNZXNzYWdlLCBhbmQgdGhlIGVuY2xvc2luZyBNZXNzYWdlIGhhcworICAgICAgLy8gbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQgPSB0cnVlLCB0aGVuIHJldHVybiB0aGUgbWVzc2FnZSBzZXQKKyAgICAgIC8vIGV4dGVuc2lvbiwgaWYgb25lIGV4aXN0cy4KKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZm9yZWlnbl90eXBlLT5leHRlbnNpb25fY291bnQoKTsgaSsrKSB7CisgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZXh0ZW5zaW9uID0gZm9yZWlnbl90eXBlLT5leHRlbnNpb24oaSk7CisgICAgICAgIGlmIChleHRlbnNpb24tPmNvbnRhaW5pbmdfdHlwZSgpID09IGRlc2NyaXB0b3IgJiYKKyAgICAgICAgICAgIGV4dGVuc2lvbi0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9NRVNTQUdFICYmCisgICAgICAgICAgICBleHRlbnNpb24tPmlzX29wdGlvbmFsKCkgJiYKKyAgICAgICAgICAgIGV4dGVuc2lvbi0+bWVzc2FnZV90eXBlKCkgPT0gZm9yZWlnbl90eXBlKSB7CisgICAgICAgICAgLy8gRm91bmQgaXQuCisgICAgICAgICAgcmV0dXJuIGV4dGVuc2lvbjsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gTlVMTDsKKyAgfQorfTsKKworLy8gQSBjdXN0b20gZXJyb3IgY29sbGVjdG9yIHRvIHJlY29yZCBhbnkgdGV4dC1mb3JtYXQgcGFyc2luZyBlcnJvcnMKK25hbWVzcGFjZSB7CitjbGFzcyBBZ2dyZWdhdGVFcnJvckNvbGxlY3RvciA6IHB1YmxpYyBpbzo6RXJyb3JDb2xsZWN0b3IgeworIHB1YmxpYzoKKyAgc3RyaW5nIGVycm9yXzsKKworICB2aXJ0dWFsIHZvaWQgQWRkRXJyb3IoaW50IC8qIGxpbmUgKi8sIGludCAvKiBjb2x1bW4gKi8sCisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIG1lc3NhZ2UpIHsKKyAgICBpZiAoIWVycm9yXy5lbXB0eSgpKSB7CisgICAgICBlcnJvcl8gKz0gIjsgIjsKKyAgICB9CisgICAgZXJyb3JfICs9IG1lc3NhZ2U7CisgIH0KKworICB2aXJ0dWFsIHZvaWQgQWRkV2FybmluZyhpbnQgLyogbGluZSAqLywgaW50IC8qIGNvbHVtbiAqLywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiAvKiBtZXNzYWdlICovKSB7CisgICAgLy8gSWdub3JlIHdhcm5pbmdzCisgIH0KK307Cit9CisKKy8vIFdlIGNvbnN0cnVjdCBhIGR5bmFtaWMgbWVzc2FnZSBvZiB0aGUgdHlwZSBjb3JyZXNwb25kaW5nIHRvCisvLyBvcHRpb25fZmllbGQsIHBhcnNlIHRoZSBzdXBwbGllZCB0ZXh0LWZvcm1hdCBzdHJpbmcgaW50byB0aGlzCisvLyBtZXNzYWdlLCBhbmQgc2VyaWFsaXplIHRoZSByZXN1bHRpbmcgbWVzc2FnZSB0byBwcm9kdWNlIHRoZSB2YWx1ZS4KK2Jvb2wgRGVzY3JpcHRvckJ1aWxkZXI6Ok9wdGlvbkludGVycHJldGVyOjpTZXRBZ2dyZWdhdGVPcHRpb24oCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBvcHRpb25fZmllbGQsCisgICAgVW5rbm93bkZpZWxkU2V0KiB1bmtub3duX2ZpZWxkcykgeworICBpZiAoIXVuaW50ZXJwcmV0ZWRfb3B0aW9uXy0+aGFzX2FnZ3JlZ2F0ZV92YWx1ZSgpKSB7CisgICAgcmV0dXJuIEFkZFZhbHVlRXJyb3IoIk9wdGlvbiBcIiIgKyBvcHRpb25fZmllbGQtPmZ1bGxfbmFtZSgpICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAiXCIgaXMgYSBtZXNzYWdlLiBUbyBzZXQgdGhlIGVudGlyZSBtZXNzYWdlLCB1c2UgIgorICAgICAgICAgICAgICAgICAgICAgICAgICJzeW50YXggbGlrZSBcIiIgKyBvcHRpb25fZmllbGQtPm5hbWUoKSArCisgICAgICAgICAgICAgICAgICAgICAgICAgIiA9IHsgPHByb3RvIHRleHQgZm9ybWF0PiB9XCIuICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAiVG8gc2V0IGZpZWxkcyB3aXRoaW4gaXQsIHVzZSAiCisgICAgICAgICAgICAgICAgICAgICAgICAgInN5bnRheCBsaWtlIFwiIiArIG9wdGlvbl9maWVsZC0+bmFtZSgpICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAiLmZvbyA9IHZhbHVlXCIuIik7CisgIH0KKworICBjb25zdCBEZXNjcmlwdG9yKiB0eXBlID0gb3B0aW9uX2ZpZWxkLT5tZXNzYWdlX3R5cGUoKTsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxNZXNzYWdlPiBkeW5hbWljKGR5bmFtaWNfZmFjdG9yeV8uR2V0UHJvdG90eXBlKHR5cGUpLT5OZXcoKSk7CisgIEdPT0dMRV9DSEVDSyhkeW5hbWljLmdldCgpICE9IE5VTEwpCisgICAgICA8PCAiQ291bGQgbm90IGNyZWF0ZSBhbiBpbnN0YW5jZSBvZiAiIDw8IG9wdGlvbl9maWVsZC0+RGVidWdTdHJpbmcoKTsKKworICBBZ2dyZWdhdGVFcnJvckNvbGxlY3RvciBjb2xsZWN0b3I7CisgIEFnZ3JlZ2F0ZU9wdGlvbkZpbmRlciBmaW5kZXI7CisgIGZpbmRlci5idWlsZGVyXyA9IGJ1aWxkZXJfOworICBUZXh0Rm9ybWF0OjpQYXJzZXIgcGFyc2VyOworICBwYXJzZXIuUmVjb3JkRXJyb3JzVG8oJmNvbGxlY3Rvcik7CisgIHBhcnNlci5TZXRGaW5kZXIoJmZpbmRlcik7CisgIGlmICghcGFyc2VyLlBhcnNlRnJvbVN0cmluZyh1bmludGVycHJldGVkX29wdGlvbl8tPmFnZ3JlZ2F0ZV92YWx1ZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHluYW1pYy5nZXQoKSkpIHsKKyAgICBBZGRWYWx1ZUVycm9yKCJFcnJvciB3aGlsZSBwYXJzaW5nIG9wdGlvbiB2YWx1ZSBmb3IgXCIiICsKKyAgICAgICAgICAgICAgICAgIG9wdGlvbl9maWVsZC0+bmFtZSgpICsgIlwiOiAiICsgY29sbGVjdG9yLmVycm9yXyk7CisgICAgcmV0dXJuIGZhbHNlOworICB9IGVsc2UgeworICAgIHN0cmluZyBzZXJpYWw7CisgICAgZHluYW1pYy0+U2VyaWFsaXplVG9TdHJpbmcoJnNlcmlhbCk7ICAvLyBOZXZlciBmYWlscworICAgIGlmIChvcHRpb25fZmllbGQtPnR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfTUVTU0FHRSkgeworICAgICAgdW5rbm93bl9maWVsZHMtPkFkZExlbmd0aERlbGltaXRlZChvcHRpb25fZmllbGQtPm51bWJlcigpLCBzZXJpYWwpOworICAgIH0gZWxzZSB7CisgICAgICBHT09HTEVfQ0hFQ0tfRVEob3B0aW9uX2ZpZWxkLT50eXBlKCksICBGaWVsZERlc2NyaXB0b3I6OlRZUEVfR1JPVVApOworICAgICAgVW5rbm93bkZpZWxkU2V0KiBncm91cCA9IHVua25vd25fZmllbGRzLT5BZGRHcm91cChvcHRpb25fZmllbGQtPm51bWJlcigpKTsKKyAgICAgIGdyb3VwLT5QYXJzZUZyb21TdHJpbmcoc2VyaWFsKTsKKyAgICB9CisgICAgcmV0dXJuIHRydWU7CisgIH0KK30KKwordm9pZCBEZXNjcmlwdG9yQnVpbGRlcjo6T3B0aW9uSW50ZXJwcmV0ZXI6OlNldEludDMyKGludCBudW1iZXIsIGludDMyIHZhbHVlLAorICAgIEZpZWxkRGVzY3JpcHRvcjo6VHlwZSB0eXBlLCBVbmtub3duRmllbGRTZXQqIHVua25vd25fZmllbGRzKSB7CisgIHN3aXRjaCAodHlwZSkgeworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0lOVDMyOgorICAgICAgdW5rbm93bl9maWVsZHMtPkFkZFZhcmludChudW1iZXIsCisgICAgICAgIHN0YXRpY19jYXN0PHVpbnQ2ND4oc3RhdGljX2Nhc3Q8aW50NjQ+KHZhbHVlKSkpOworICAgICAgYnJlYWs7CisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TRklYRUQzMjoKKyAgICAgIHVua25vd25fZmllbGRzLT5BZGRGaXhlZDMyKG51bWJlciwgc3RhdGljX2Nhc3Q8dWludDMyPih2YWx1ZSkpOworICAgICAgYnJlYWs7CisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TSU5UMzI6CisgICAgICB1bmtub3duX2ZpZWxkcy0+QWRkVmFyaW50KG51bWJlciwKKyAgICAgICAgICBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlppZ1phZ0VuY29kZTMyKHZhbHVlKSk7CisgICAgICBicmVhazsKKworICAgIGRlZmF1bHQ6CisgICAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiSW52YWxpZCB3aXJlIHR5cGUgZm9yIENQUFRZUEVfSU5UMzI6ICIgPDwgdHlwZTsKKyAgICAgIGJyZWFrOworICB9Cit9CisKK3ZvaWQgRGVzY3JpcHRvckJ1aWxkZXI6Ok9wdGlvbkludGVycHJldGVyOjpTZXRJbnQ2NChpbnQgbnVtYmVyLCBpbnQ2NCB2YWx1ZSwKKyAgICBGaWVsZERlc2NyaXB0b3I6OlR5cGUgdHlwZSwgVW5rbm93bkZpZWxkU2V0KiB1bmtub3duX2ZpZWxkcykgeworICBzd2l0Y2ggKHR5cGUpIHsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9JTlQ2NDoKKyAgICAgIHVua25vd25fZmllbGRzLT5BZGRWYXJpbnQobnVtYmVyLCBzdGF0aWNfY2FzdDx1aW50NjQ+KHZhbHVlKSk7CisgICAgICBicmVhazsKKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NGSVhFRDY0OgorICAgICAgdW5rbm93bl9maWVsZHMtPkFkZEZpeGVkNjQobnVtYmVyLCBzdGF0aWNfY2FzdDx1aW50NjQ+KHZhbHVlKSk7CisgICAgICBicmVhazsKKworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NJTlQ2NDoKKyAgICAgIHVua25vd25fZmllbGRzLT5BZGRWYXJpbnQobnVtYmVyLAorICAgICAgICAgIGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6WmlnWmFnRW5jb2RlNjQodmFsdWUpKTsKKyAgICAgIGJyZWFrOworCisgICAgZGVmYXVsdDoKKyAgICAgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJJbnZhbGlkIHdpcmUgdHlwZSBmb3IgQ1BQVFlQRV9JTlQ2NDogIiA8PCB0eXBlOworICAgICAgYnJlYWs7CisgIH0KK30KKwordm9pZCBEZXNjcmlwdG9yQnVpbGRlcjo6T3B0aW9uSW50ZXJwcmV0ZXI6OlNldFVJbnQzMihpbnQgbnVtYmVyLCB1aW50MzIgdmFsdWUsCisgICAgRmllbGREZXNjcmlwdG9yOjpUeXBlIHR5cGUsIFVua25vd25GaWVsZFNldCogdW5rbm93bl9maWVsZHMpIHsKKyAgc3dpdGNoICh0eXBlKSB7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfVUlOVDMyOgorICAgICAgdW5rbm93bl9maWVsZHMtPkFkZFZhcmludChudW1iZXIsIHN0YXRpY19jYXN0PHVpbnQ2ND4odmFsdWUpKTsKKyAgICAgIGJyZWFrOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRklYRUQzMjoKKyAgICAgIHVua25vd25fZmllbGRzLT5BZGRGaXhlZDMyKG51bWJlciwgc3RhdGljX2Nhc3Q8dWludDMyPih2YWx1ZSkpOworICAgICAgYnJlYWs7CisKKyAgICBkZWZhdWx0OgorICAgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkludmFsaWQgd2lyZSB0eXBlIGZvciBDUFBUWVBFX1VJTlQzMjogIiA8PCB0eXBlOworICAgICAgYnJlYWs7CisgIH0KK30KKwordm9pZCBEZXNjcmlwdG9yQnVpbGRlcjo6T3B0aW9uSW50ZXJwcmV0ZXI6OlNldFVJbnQ2NChpbnQgbnVtYmVyLCB1aW50NjQgdmFsdWUsCisgICAgRmllbGREZXNjcmlwdG9yOjpUeXBlIHR5cGUsIFVua25vd25GaWVsZFNldCogdW5rbm93bl9maWVsZHMpIHsKKyAgc3dpdGNoICh0eXBlKSB7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfVUlOVDY0OgorICAgICAgdW5rbm93bl9maWVsZHMtPkFkZFZhcmludChudW1iZXIsIHZhbHVlKTsKKyAgICAgIGJyZWFrOworCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRklYRUQ2NDoKKyAgICAgIHVua25vd25fZmllbGRzLT5BZGRGaXhlZDY0KG51bWJlciwgdmFsdWUpOworICAgICAgYnJlYWs7CisKKyAgICBkZWZhdWx0OgorICAgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkludmFsaWQgd2lyZSB0eXBlIGZvciBDUFBUWVBFX1VJTlQ2NDogIiA8PCB0eXBlOworICAgICAgYnJlYWs7CisgIH0KK30KKwordm9pZCBEZXNjcmlwdG9yQnVpbGRlcjo6TG9nVW51c2VkRGVwZW5kZW5jeShjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvJiBwcm90bywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmlsZURlc2NyaXB0b3IqIHJlc3VsdCkgeworCisgIGlmICghdW51c2VkX2RlcGVuZGVuY3lfLmVtcHR5KCkpIHsKKyAgICBzdGQ6OnNldDxzdHJpbmc+IGFubm90YXRpb25fZXh0ZW5zaW9uczsKKyAgICBhbm5vdGF0aW9uX2V4dGVuc2lvbnMuaW5zZXJ0KCJnb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMiKTsKKyAgICBhbm5vdGF0aW9uX2V4dGVuc2lvbnMuaW5zZXJ0KCJnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMiKTsKKyAgICBhbm5vdGF0aW9uX2V4dGVuc2lvbnMuaW5zZXJ0KCJnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zIik7CisgICAgYW5ub3RhdGlvbl9leHRlbnNpb25zLmluc2VydCgiZ29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zIik7CisgICAgYW5ub3RhdGlvbl9leHRlbnNpb25zLmluc2VydCgiZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnMiKTsKKyAgICBhbm5vdGF0aW9uX2V4dGVuc2lvbnMuaW5zZXJ0KCJnb29nbGUucHJvdG9idWYuU2VydmljZU9wdGlvbnMiKTsKKyAgICBhbm5vdGF0aW9uX2V4dGVuc2lvbnMuaW5zZXJ0KCJnb29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucyIpOworICAgIGFubm90YXRpb25fZXh0ZW5zaW9ucy5pbnNlcnQoImdvb2dsZS5wcm90b2J1Zi5TdHJlYW1PcHRpb25zIik7CisgICAgZm9yIChzZXQ8Y29uc3QgRmlsZURlc2NyaXB0b3IqPjo6Y29uc3RfaXRlcmF0b3IKKyAgICAgICAgICAgICBpdCA9IHVudXNlZF9kZXBlbmRlbmN5Xy5iZWdpbigpOworICAgICAgICAgaXQgIT0gdW51c2VkX2RlcGVuZGVuY3lfLmVuZCgpOyArK2l0KSB7CisgICAgICAvLyBEbyBub3QgbG9nIHdhcm5pbmdzIGZvciBwcm90byBmaWxlcyB3aGljaCBleHRlbmQgYW5ub3RhdGlvbnMuCisgICAgICBpbnQgaTsKKyAgICAgIGZvciAoaSA9IDAgOyBpIDwgKCppdCktPmV4dGVuc2lvbl9jb3VudCgpOyArK2kpIHsKKyAgICAgICAgaWYgKGFubm90YXRpb25fZXh0ZW5zaW9ucy5maW5kKAorICAgICAgICAgICAgICAgICgqaXQpLT5leHRlbnNpb24oaSktPmNvbnRhaW5pbmdfdHlwZSgpLT5mdWxsX25hbWUoKSkKKyAgICAgICAgICAgICE9IGFubm90YXRpb25fZXh0ZW5zaW9ucy5lbmQoKSkgeworICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICB9CisgICAgICAvLyBMb2cgd2FybmluZ3MgZm9yIHVudXNlZCBpbXBvcnRlZCBmaWxlcy4KKyAgICAgIGlmIChpID09ICgqaXQpLT5leHRlbnNpb25fY291bnQoKSkgeworICAgICAgICBzdHJpbmcgZXJyb3JfbWVzc2FnZSA9ICJJbXBvcnQgIiArICgqaXQpLT5uYW1lKCkgKyAiIGJ1dCBub3QgdXNlZC4iOworICAgICAgICBBZGRXYXJuaW5nKCgqaXQpLT5uYW1lKCksIHByb3RvLCBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3I6Ok9USEVSLAorICAgICAgICAgICAgICAgICAgIGVycm9yX21lc3NhZ2UpOworICAgICAgfQorICAgIH0KKyAgfQorfQorCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2UzYTc0OQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oCkBAIC0wLDAgKzEsMTg4NiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorLy8KKy8vIFRoaXMgZmlsZSBjb250YWlucyBjbGFzc2VzIHdoaWNoIGRlc2NyaWJlIGEgdHlwZSBvZiBwcm90b2NvbCBtZXNzYWdlLgorLy8gWW91IGNhbiB1c2UgYSBtZXNzYWdlJ3MgZGVzY3JpcHRvciB0byBsZWFybiBhdCBydW50aW1lIHdoYXQgZmllbGRzCisvLyBpdCBjb250YWlucyBhbmQgd2hhdCB0aGUgdHlwZXMgb2YgdGhvc2UgZmllbGRzIGFyZS4gIFRoZSBNZXNzYWdlCisvLyBpbnRlcmZhY2UgYWxzbyBhbGxvd3MgeW91IHRvIGR5bmFtaWNhbGx5IGFjY2VzcyBhbmQgbW9kaWZ5IGluZGl2aWR1YWwKKy8vIGZpZWxkcyBieSBwYXNzaW5nIHRoZSBGaWVsZERlc2NyaXB0b3Igb2YgdGhlIGZpZWxkIHlvdSBhcmUgaW50ZXJlc3RlZAorLy8gaW4uCisvLworLy8gTW9zdCB1c2VycyB3aWxsIG5vdCBjYXJlIGFib3V0IGRlc2NyaXB0b3JzLCBiZWNhdXNlIHRoZXkgd2lsbCB3cml0ZQorLy8gY29kZSBzcGVjaWZpYyB0byBjZXJ0YWluIHByb3RvY29sIHR5cGVzIGFuZCB3aWxsIHNpbXBseSB1c2UgdGhlIGNsYXNzZXMKKy8vIGdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgY29tcGlsZXIgZGlyZWN0bHkuICBBZHZhbmNlZCB1c2VycyB3aG8gd2FudAorLy8gdG8gb3BlcmF0ZSBvbiBhcmJpdHJhcnkgdHlwZXMgKG5vdCBrbm93biBhdCBjb21waWxlIHRpbWUpIG1heSB3YW50IHRvCisvLyByZWFkIGRlc2NyaXB0b3JzIGluIG9yZGVyIHRvIGxlYXJuIGFib3V0IHRoZSBjb250ZW50cyBvZiBhIG1lc3NhZ2UuCisvLyBBIHZlcnkgc21hbGwgbnVtYmVyIG9mIHVzZXJzIHdpbGwgd2FudCB0byBjb25zdHJ1Y3QgdGhlaXIgb3duCisvLyBEZXNjcmlwdG9ycywgZWl0aGVyIGJlY2F1c2UgdGhleSBhcmUgaW1wbGVtZW50aW5nIE1lc3NhZ2UgbWFudWFsbHkgb3IKKy8vIGJlY2F1c2UgdGhleSBhcmUgd3JpdGluZyBzb21ldGhpbmcgbGlrZSB0aGUgcHJvdG9jb2wgY29tcGlsZXIuCisvLworLy8gRm9yIGFuIGV4YW1wbGUgb2YgaG93IHlvdSBtaWdodCB1c2UgZGVzY3JpcHRvcnMsIHNlZSB0aGUgY29kZSBleGFtcGxlCisvLyBhdCB0aGUgdG9wIG9mIG1lc3NhZ2UuaC4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfREVTQ1JJUFRPUl9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0RFU0NSSVBUT1JfSF9fCisKKyNpbmNsdWRlIDxtZW1vcnk+CisjaWZuZGVmIF9TSEFSRURfUFRSX0gKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc2hhcmVkX3B0ci5oPgorI2VuZGlmCisjaW5jbHVkZSA8c2V0PgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDx2ZWN0b3I+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zY29wZWRfcHRyLmg+CisKKy8vIFRZUEVfQk9PTCBpcyBkZWZpbmVkIGluIHRoZSBNYWNPUydzIENvbmRpdGlvbmFsTWFjcm9zLmguCisjaWZkZWYgVFlQRV9CT09MCisjdW5kZWYgVFlQRV9CT09MCisjZW5kaWYgIC8vIFRZUEVfQk9PTAorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKKy8vIERlZmluZWQgaW4gdGhpcyBmaWxlLgorY2xhc3MgRGVzY3JpcHRvcjsKK2NsYXNzIEZpZWxkRGVzY3JpcHRvcjsKK2NsYXNzIE9uZW9mRGVzY3JpcHRvcjsKK2NsYXNzIEVudW1EZXNjcmlwdG9yOworY2xhc3MgRW51bVZhbHVlRGVzY3JpcHRvcjsKK2NsYXNzIFNlcnZpY2VEZXNjcmlwdG9yOworY2xhc3MgTWV0aG9kRGVzY3JpcHRvcjsKK2NsYXNzIEZpbGVEZXNjcmlwdG9yOworY2xhc3MgRGVzY3JpcHRvckRhdGFiYXNlOworY2xhc3MgRGVzY3JpcHRvclBvb2w7CisKKy8vIERlZmluZWQgaW4gZGVzY3JpcHRvci5wcm90bworY2xhc3MgRGVzY3JpcHRvclByb3RvOworY2xhc3MgRmllbGREZXNjcmlwdG9yUHJvdG87CitjbGFzcyBPbmVvZkRlc2NyaXB0b3JQcm90bzsKK2NsYXNzIEVudW1EZXNjcmlwdG9yUHJvdG87CitjbGFzcyBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG87CitjbGFzcyBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOworY2xhc3MgTWV0aG9kRGVzY3JpcHRvclByb3RvOworY2xhc3MgRmlsZURlc2NyaXB0b3JQcm90bzsKK2NsYXNzIE1lc3NhZ2VPcHRpb25zOworY2xhc3MgRmllbGRPcHRpb25zOworY2xhc3MgRW51bU9wdGlvbnM7CitjbGFzcyBFbnVtVmFsdWVPcHRpb25zOworY2xhc3MgU2VydmljZU9wdGlvbnM7CitjbGFzcyBNZXRob2RPcHRpb25zOworY2xhc3MgRmlsZU9wdGlvbnM7CitjbGFzcyBVbmludGVycHJldGVkT3B0aW9uOworY2xhc3MgU291cmNlQ29kZUluZm87CisKKy8vIERlZmluZWQgaW4gbWVzc2FnZS5oCitjbGFzcyBNZXNzYWdlOworCisvLyBEZWZpbmVkIGluIGRlc2NyaXB0b3IuY2MKK2NsYXNzIERlc2NyaXB0b3JCdWlsZGVyOworY2xhc3MgRmlsZURlc2NyaXB0b3JUYWJsZXM7CisKKy8vIERlZmluZWQgaW4gdW5rbm93bl9maWVsZF9zZXQuaC4KK2NsYXNzIFVua25vd25GaWVsZDsKKworLy8gRGVmaW5lZCBpbiBnZW5lcmF0ZWRfbWVzc2FnZV9yZWZsZWN0aW9uLmguCituYW1lc3BhY2UgaW50ZXJuYWwgeworY2xhc3MgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb247Cit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKKworLy8gRGVmaW5lZCBpbiBjb21tYW5kX2xpbmVfaW50ZXJmYWNlLmNjCituYW1lc3BhY2UgY29tcGlsZXIgeworY2xhc3MgQ29tbWFuZExpbmVJbnRlcmZhY2U7Cit9ICAvLyBuYW1lc3BhY2UgY29tcGlsZXIKKworbmFtZXNwYWNlIGRlc2NyaXB0b3JfdW5pdHRlc3QgeworY2xhc3MgRGVzY3JpcHRvclRlc3Q7Cit9ICAvLyBuYW1lc3BhY2UgZGVzY3JpcHRvcl91bml0dGVzdAorCisvLyBOQiwgYWxsIGluZGljZXMgYXJlIHplcm8tYmFzZWQuCitzdHJ1Y3QgU291cmNlTG9jYXRpb24geworICBpbnQgc3RhcnRfbGluZTsKKyAgaW50IGVuZF9saW5lOworICBpbnQgc3RhcnRfY29sdW1uOworICBpbnQgZW5kX2NvbHVtbjsKKworICAvLyBEb2MgY29tbWVudHMgZm91bmQgYXQgdGhlIHNvdXJjZSBsb2NhdGlvbi4KKyAgLy8gU2VlIHRoZSBjb21tZW50cyBpbiBTb3VyY2VDb2RlSW5mby5Mb2NhdGlvbiAoZGVzY3JpcHRvci5wcm90bykgZm9yIGRldGFpbHMuCisgIHN0cmluZyBsZWFkaW5nX2NvbW1lbnRzOworICBzdHJpbmcgdHJhaWxpbmdfY29tbWVudHM7CisgIHZlY3RvcjxzdHJpbmc+IGxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHM7Cit9OworCisvLyBPcHRpb25zIHdoZW4gZ2VuZXJhdGluZyBtYWNoaW5lLXBhcnNhYmxlIG91dHB1dCBmcm9tIGEgZGVzY3JpcHRvciB3aXRoCisvLyBEZWJ1Z1N0cmluZygpLgorc3RydWN0IERlYnVnU3RyaW5nT3B0aW9ucyB7CisgIC8vIGluY2x1ZGUgb3JpZ2luYWwgdXNlciBjb21tZW50cyBhcyByZWNvcmRlZCBpbiBTb3VyY2VMb2NhdGlvbiBlbnRyaWVzLiBOLkIuCisgIC8vIHRoYXQgdGhpcyBtdXN0IGJlIHxmYWxzZXwgYnkgZGVmYXVsdDogc2V2ZXJhbCBvdGhlciBwaWVjZXMgb2YgY29kZSAoZm9yCisgIC8vIGV4YW1wbGUsIHRoZSBDKysgY29kZSBnZW5lcmF0aW9uIGZvciBmaWVsZHMgaW4gdGhlIHByb3RvIGNvbXBpbGVyKSByZWx5IG9uCisgIC8vIERlYnVnU3RyaW5nKCkgb3V0cHV0IGJlaW5nIHVub2JzdHJ1Y3RlZCBieSB1c2VyIGNvbW1lbnRzLgorICBib29sIGluY2x1ZGVfY29tbWVudHM7CisgIC8vIElmIHRydWUsIGVsaWRlIHRoZSBicmFjZWQgYm9keSBpbiB0aGUgZGVidWcgc3RyaW5nLgorICBib29sIGVsaWRlX2dyb3VwX2JvZHk7CisgIGJvb2wgZWxpZGVfb25lb2ZfYm9keTsKKworICBEZWJ1Z1N0cmluZ09wdGlvbnMoKQorICAgICAgOiBpbmNsdWRlX2NvbW1lbnRzKGZhbHNlKSwKKyAgICAgICAgZWxpZGVfZ3JvdXBfYm9keShmYWxzZSksCisgICAgICAgIGVsaWRlX29uZW9mX2JvZHkoZmFsc2UpIHt9Cit9OworCisvLyBEZXNjcmliZXMgYSB0eXBlIG9mIHByb3RvY29sIG1lc3NhZ2UsIG9yIGEgcGFydGljdWxhciBncm91cCB3aXRoaW4gYQorLy8gbWVzc2FnZS4gIFRvIG9idGFpbiB0aGUgRGVzY3JpcHRvciBmb3IgYSBnaXZlbiBtZXNzYWdlIG9iamVjdCwgY2FsbAorLy8gTWVzc2FnZTo6R2V0RGVzY3JpcHRvcigpLiAgR2VuZXJhdGVkIG1lc3NhZ2UgY2xhc3NlcyBhbHNvIGhhdmUgYQorLy8gc3RhdGljIG1ldGhvZCBjYWxsZWQgZGVzY3JpcHRvcigpIHdoaWNoIHJldHVybnMgdGhlIHR5cGUncyBkZXNjcmlwdG9yLgorLy8gVXNlIERlc2NyaXB0b3JQb29sIHRvIGNvbnN0cnVjdCB5b3VyIG93biBkZXNjcmlwdG9ycy4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBEZXNjcmlwdG9yIHsKKyBwdWJsaWM6CisgIC8vIFRoZSBuYW1lIG9mIHRoZSBtZXNzYWdlIHR5cGUsIG5vdCBpbmNsdWRpbmcgaXRzIHNjb3BlLgorICBjb25zdCBzdHJpbmcmIG5hbWUoKSBjb25zdDsKKworICAvLyBUaGUgZnVsbHktcXVhbGlmaWVkIG5hbWUgb2YgdGhlIG1lc3NhZ2UgdHlwZSwgc2NvcGUgZGVsaW1pdGVkIGJ5CisgIC8vIHBlcmlvZHMuICBGb3IgZXhhbXBsZSwgbWVzc2FnZSB0eXBlICJGb28iIHdoaWNoIGlzIGRlY2xhcmVkIGluIHBhY2thZ2UKKyAgLy8gImJhciIgaGFzIGZ1bGwgbmFtZSAiYmFyLkZvbyIuICBJZiBhIHR5cGUgIkJheiIgaXMgbmVzdGVkIHdpdGhpbgorICAvLyBGb28sIEJheidzIGZ1bGxfbmFtZSBpcyAiYmFyLkZvby5CYXoiLiAgVG8gZ2V0IG9ubHkgdGhlIHBhcnQgdGhhdAorICAvLyBjb21lcyBhZnRlciB0aGUgbGFzdCAnLicsIHVzZSBuYW1lKCkuCisgIGNvbnN0IHN0cmluZyYgZnVsbF9uYW1lKCkgY29uc3Q7CisKKyAgLy8gSW5kZXggb2YgdGhpcyBkZXNjcmlwdG9yIHdpdGhpbiB0aGUgZmlsZSBvciBjb250YWluaW5nIHR5cGUncyBtZXNzYWdlCisgIC8vIHR5cGUgYXJyYXkuCisgIGludCBpbmRleCgpIGNvbnN0OworCisgIC8vIFRoZSAucHJvdG8gZmlsZSBpbiB3aGljaCB0aGlzIG1lc3NhZ2UgdHlwZSB3YXMgZGVmaW5lZC4gIE5ldmVyIE5VTEwuCisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKCkgY29uc3Q7CisKKyAgLy8gSWYgdGhpcyBEZXNjcmlwdG9yIGRlc2NyaWJlcyBhIG5lc3RlZCB0eXBlLCB0aGlzIHJldHVybnMgdGhlIHR5cGUKKyAgLy8gaW4gd2hpY2ggaXQgaXMgbmVzdGVkLiAgT3RoZXJ3aXNlLCByZXR1cm5zIE5VTEwuCisgIGNvbnN0IERlc2NyaXB0b3IqIGNvbnRhaW5pbmdfdHlwZSgpIGNvbnN0OworCisgIC8vIEdldCBvcHRpb25zIGZvciB0aGlzIG1lc3NhZ2UgdHlwZS4gIFRoZXNlIGFyZSBzcGVjaWZpZWQgaW4gdGhlIC5wcm90byBmaWxlCisgIC8vIGJ5IHBsYWNpbmcgbGluZXMgbGlrZSAib3B0aW9uIGZvbyA9IDEyMzQ7IiBpbiB0aGUgbWVzc2FnZSBkZWZpbml0aW9uLgorICAvLyBBbGxvd2VkIG9wdGlvbnMgYXJlIGRlZmluZWQgYnkgTWVzc2FnZU9wdGlvbnMgaW4KKyAgLy8gZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8sIGFuZCBhbnkgYXZhaWxhYmxlIGV4dGVuc2lvbnMgb2YgdGhhdAorICAvLyBtZXNzYWdlLgorICBjb25zdCBNZXNzYWdlT3B0aW9ucyYgb3B0aW9ucygpIGNvbnN0OworCisgIC8vIFdyaXRlIHRoZSBjb250ZW50cyBvZiB0aGlzIERlc2NyaXB0b3IgaW50byB0aGUgZ2l2ZW4gRGVzY3JpcHRvclByb3RvLgorICAvLyBUaGUgdGFyZ2V0IERlc2NyaXB0b3JQcm90byBtdXN0IGJlIGNsZWFyIGJlZm9yZSBjYWxsaW5nIHRoaXM7IGlmIGl0CisgIC8vIGlzbid0LCB0aGUgcmVzdWx0IG1heSBiZSBnYXJiYWdlLgorICB2b2lkIENvcHlUbyhEZXNjcmlwdG9yUHJvdG8qIHByb3RvKSBjb25zdDsKKworICAvLyBXcml0ZSB0aGUgY29udGVudHMgb2YgdGhpcyBkZWNyaXB0b3IgaW4gYSBodW1hbi1yZWFkYWJsZSBmb3JtLiBPdXRwdXQKKyAgLy8gd2lsbCBiZSBzdWl0YWJsZSBmb3IgcmUtcGFyc2luZy4KKyAgc3RyaW5nIERlYnVnU3RyaW5nKCkgY29uc3Q7CisKKyAgLy8gU2ltaWxhciB0byBEZWJ1Z1N0cmluZygpLCBidXQgYWRkaXRpb25hbGx5IHRha2VzIG9wdGlvbnMgKGUuZy4sCisgIC8vIGluY2x1ZGUgb3JpZ2luYWwgdXNlciBjb21tZW50cyBpbiBvdXRwdXQpLgorICBzdHJpbmcgRGVidWdTdHJpbmdXaXRoT3B0aW9ucyhjb25zdCBEZWJ1Z1N0cmluZ09wdGlvbnMmIG9wdGlvbnMpIGNvbnN0OworCisgIC8vIFJldHVybnMgdHJ1ZSBpZiB0aGlzIGlzIGEgcGxhY2Vob2xkZXIgZm9yIGFuIHVua25vd24gdHlwZS4gVGhpcyB3aWxsCisgIC8vIG9ubHkgYmUgdGhlIGNhc2UgaWYgdGhpcyBkZXNjcmlwdG9yIGNvbWVzIGZyb20gYSBEZXNjcmlwdG9yUG9vbAorICAvLyB3aXRoIEFsbG93VW5rbm93bkRlcGVuZGVuY2llcygpIHNldC4KKyAgYm9vbCBpc19wbGFjZWhvbGRlcigpIGNvbnN0OworCisgIC8vIEZpZWxkIHN0dWZmIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gVGhlIG51bWJlciBvZiBmaWVsZHMgaW4gdGhpcyBtZXNzYWdlIHR5cGUuCisgIGludCBmaWVsZF9jb3VudCgpIGNvbnN0OworICAvLyBHZXRzIGEgZmllbGQgYnkgaW5kZXgsIHdoZXJlIDAgPD0gaW5kZXggPCBmaWVsZF9jb3VudCgpLgorICAvLyBUaGVzZSBhcmUgcmV0dXJuZWQgaW4gdGhlIG9yZGVyIHRoZXkgd2VyZSBkZWZpbmVkIGluIHRoZSAucHJvdG8gZmlsZS4KKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZChpbnQgaW5kZXgpIGNvbnN0OworCisgIC8vIExvb2tzIHVwIGEgZmllbGQgYnkgZGVjbGFyZWQgdGFnIG51bWJlci4gIFJldHVybnMgTlVMTCBpZiBubyBzdWNoIGZpZWxkCisgIC8vIGV4aXN0cy4KKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBGaW5kRmllbGRCeU51bWJlcihpbnQgbnVtYmVyKSBjb25zdDsKKyAgLy8gTG9va3MgdXAgYSBmaWVsZCBieSBuYW1lLiAgUmV0dXJucyBOVUxMIGlmIG5vIHN1Y2ggZmllbGQgZXhpc3RzLgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIEZpbmRGaWVsZEJ5TmFtZShjb25zdCBzdHJpbmcmIG5hbWUpIGNvbnN0OworCisgIC8vIExvb2tzIHVwIGEgZmllbGQgYnkgbG93ZXJjYXNlZCBuYW1lIChhcyByZXR1cm5lZCBieSBsb3dlcmNhc2VfbmFtZSgpKS4KKyAgLy8gVGhpcyBsb29rdXAgbWF5IGJlIGFtYmlndW91cyBpZiBtdWx0aXBsZSBmaWVsZCBuYW1lcyBkaWZmZXIgb25seSBieSBjYXNlLAorICAvLyBpbiB3aGljaCBjYXNlIHRoZSBmaWVsZCByZXR1cm5lZCBpcyBjaG9zZW4gYXJiaXRyYXJpbHkgZnJvbSB0aGUgbWF0Y2hlcy4KKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBGaW5kRmllbGRCeUxvd2VyY2FzZU5hbWUoCisgICAgICBjb25zdCBzdHJpbmcmIGxvd2VyY2FzZV9uYW1lKSBjb25zdDsKKworICAvLyBMb29rcyB1cCBhIGZpZWxkIGJ5IGNhbWVsLWNhc2UgbmFtZSAoYXMgcmV0dXJuZWQgYnkgY2FtZWxjYXNlX25hbWUoKSkuCisgIC8vIFRoaXMgbG9va3VwIG1heSBiZSBhbWJpZ3VvdXMgaWYgbXVsdGlwbGUgZmllbGQgbmFtZXMgZGlmZmVyIGluIGEgd2F5IHRoYXQKKyAgLy8gbGVhZHMgdGhlbSB0byBoYXZlIGlkZW50aWNhbCBjYW1lbC1jYXNlIG5hbWVzLCBpbiB3aGljaCBjYXNlIHRoZSBmaWVsZAorICAvLyByZXR1cm5lZCBpcyBjaG9zZW4gYXJiaXRyYXJpbHkgZnJvbSB0aGUgbWF0Y2hlcy4KKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBGaW5kRmllbGRCeUNhbWVsY2FzZU5hbWUoCisgICAgICBjb25zdCBzdHJpbmcmIGNhbWVsY2FzZV9uYW1lKSBjb25zdDsKKworICAvLyBUaGUgbnVtYmVyIG9mIG9uZW9mcyBpbiB0aGlzIG1lc3NhZ2UgdHlwZS4KKyAgaW50IG9uZW9mX2RlY2xfY291bnQoKSBjb25zdDsKKyAgLy8gR2V0IGEgb25lb2YgYnkgaW5kZXgsIHdoZXJlIDAgPD0gaW5kZXggPCBvbmVvZl9kZWNsX2NvdW50KCkuCisgIC8vIFRoZXNlIGFyZSByZXR1cm5lZCBpbiB0aGUgb3JkZXIgdGhleSB3ZXJlIGRlZmluZWQgaW4gdGhlIC5wcm90byBmaWxlLgorICBjb25zdCBPbmVvZkRlc2NyaXB0b3IqIG9uZW9mX2RlY2woaW50IGluZGV4KSBjb25zdDsKKworICAvLyBMb29rcyB1cCBhIG9uZW9mIGJ5IG5hbWUuICBSZXR1cm5zIE5VTEwgaWYgbm8gc3VjaCBvbmVvZiBleGlzdHMuCisgIGNvbnN0IE9uZW9mRGVzY3JpcHRvciogRmluZE9uZW9mQnlOYW1lKGNvbnN0IHN0cmluZyYgbmFtZSkgY29uc3Q7CisKKyAgLy8gTmVzdGVkIHR5cGUgc3R1ZmYgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBUaGUgbnVtYmVyIG9mIG5lc3RlZCB0eXBlcyBpbiB0aGlzIG1lc3NhZ2UgdHlwZS4KKyAgaW50IG5lc3RlZF90eXBlX2NvdW50KCkgY29uc3Q7CisgIC8vIEdldHMgYSBuZXN0ZWQgdHlwZSBieSBpbmRleCwgd2hlcmUgMCA8PSBpbmRleCA8IG5lc3RlZF90eXBlX2NvdW50KCkuCisgIC8vIFRoZXNlIGFyZSByZXR1cm5lZCBpbiB0aGUgb3JkZXIgdGhleSB3ZXJlIGRlZmluZWQgaW4gdGhlIC5wcm90byBmaWxlLgorICBjb25zdCBEZXNjcmlwdG9yKiBuZXN0ZWRfdHlwZShpbnQgaW5kZXgpIGNvbnN0OworCisgIC8vIExvb2tzIHVwIGEgbmVzdGVkIHR5cGUgYnkgbmFtZS4gIFJldHVybnMgTlVMTCBpZiBubyBzdWNoIG5lc3RlZCB0eXBlCisgIC8vIGV4aXN0cy4KKyAgY29uc3QgRGVzY3JpcHRvciogRmluZE5lc3RlZFR5cGVCeU5hbWUoY29uc3Qgc3RyaW5nJiBuYW1lKSBjb25zdDsKKworICAvLyBFbnVtIHN0dWZmIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIFRoZSBudW1iZXIgb2YgZW51bSB0eXBlcyBpbiB0aGlzIG1lc3NhZ2UgdHlwZS4KKyAgaW50IGVudW1fdHlwZV9jb3VudCgpIGNvbnN0OworICAvLyBHZXRzIGFuIGVudW0gdHlwZSBieSBpbmRleCwgd2hlcmUgMCA8PSBpbmRleCA8IGVudW1fdHlwZV9jb3VudCgpLgorICAvLyBUaGVzZSBhcmUgcmV0dXJuZWQgaW4gdGhlIG9yZGVyIHRoZXkgd2VyZSBkZWZpbmVkIGluIHRoZSAucHJvdG8gZmlsZS4KKyAgY29uc3QgRW51bURlc2NyaXB0b3IqIGVudW1fdHlwZShpbnQgaW5kZXgpIGNvbnN0OworCisgIC8vIExvb2tzIHVwIGFuIGVudW0gdHlwZSBieSBuYW1lLiAgUmV0dXJucyBOVUxMIGlmIG5vIHN1Y2ggZW51bSB0eXBlIGV4aXN0cy4KKyAgY29uc3QgRW51bURlc2NyaXB0b3IqIEZpbmRFbnVtVHlwZUJ5TmFtZShjb25zdCBzdHJpbmcmIG5hbWUpIGNvbnN0OworCisgIC8vIExvb2tzIHVwIGFuIGVudW0gdmFsdWUgYnkgbmFtZSwgYW1vbmcgYWxsIGVudW0gdHlwZXMgaW4gdGhpcyBtZXNzYWdlLgorICAvLyBSZXR1cm5zIE5VTEwgaWYgbm8gc3VjaCB2YWx1ZSBleGlzdHMuCisgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIEZpbmRFbnVtVmFsdWVCeU5hbWUoY29uc3Qgc3RyaW5nJiBuYW1lKSBjb25zdDsKKworICAvLyBFeHRlbnNpb25zIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIEEgcmFuZ2Ugb2YgZmllbGQgbnVtYmVycyB3aGljaCBhcmUgZGVzaWduYXRlZCBmb3IgdGhpcmQtcGFydHkKKyAgLy8gZXh0ZW5zaW9ucy4KKyAgc3RydWN0IEV4dGVuc2lvblJhbmdlIHsKKyAgICBpbnQgc3RhcnQ7ICAvLyBpbmNsdXNpdmUKKyAgICBpbnQgZW5kOyAgICAvLyBleGNsdXNpdmUKKyAgfTsKKworICAvLyBUaGUgbnVtYmVyIG9mIGV4dGVuc2lvbiByYW5nZXMgaW4gdGhpcyBtZXNzYWdlIHR5cGUuCisgIGludCBleHRlbnNpb25fcmFuZ2VfY291bnQoKSBjb25zdDsKKyAgLy8gR2V0cyBhbiBleHRlbnNpb24gcmFuZ2UgYnkgaW5kZXgsIHdoZXJlIDAgPD0gaW5kZXggPAorICAvLyBleHRlbnNpb25fcmFuZ2VfY291bnQoKS4gVGhlc2UgYXJlIHJldHVybmVkIGluIHRoZSBvcmRlciB0aGV5IHdlcmUgZGVmaW5lZAorICAvLyBpbiB0aGUgLnByb3RvIGZpbGUuCisgIGNvbnN0IEV4dGVuc2lvblJhbmdlKiBleHRlbnNpb25fcmFuZ2UoaW50IGluZGV4KSBjb25zdDsKKworICAvLyBSZXR1cm5zIHRydWUgaWYgdGhlIG51bWJlciBpcyBpbiBvbmUgb2YgdGhlIGV4dGVuc2lvbiByYW5nZXMuCisgIGJvb2wgSXNFeHRlbnNpb25OdW1iZXIoaW50IG51bWJlcikgY29uc3Q7CisKKyAgLy8gUmV0dXJucyBOVUxMIGlmIG5vIGV4dGVuc2lvbiByYW5nZSBjb250YWlucyB0aGUgZ2l2ZW4gbnVtYmVyLgorICBjb25zdCBFeHRlbnNpb25SYW5nZSogRmluZEV4dGVuc2lvblJhbmdlQ29udGFpbmluZ051bWJlcihpbnQgbnVtYmVyKSBjb25zdDsKKworICAvLyBUaGUgbnVtYmVyIG9mIGV4dGVuc2lvbnMgLS0gZXh0ZW5kaW5nICpvdGhlciogbWVzc2FnZXMgLS0gdGhhdCB3ZXJlCisgIC8vIGRlZmluZWQgbmVzdGVkIHdpdGhpbiB0aGlzIG1lc3NhZ2UgdHlwZSdzIHNjb3BlLgorICBpbnQgZXh0ZW5zaW9uX2NvdW50KCkgY29uc3Q7CisgIC8vIEdldCBhbiBleHRlbnNpb24gYnkgaW5kZXgsIHdoZXJlIDAgPD0gaW5kZXggPCBleHRlbnNpb25fY291bnQoKS4KKyAgLy8gVGhlc2UgYXJlIHJldHVybmVkIGluIHRoZSBvcmRlciB0aGV5IHdlcmUgZGVmaW5lZCBpbiB0aGUgLnByb3RvIGZpbGUuCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZXh0ZW5zaW9uKGludCBpbmRleCkgY29uc3Q7CisKKyAgLy8gTG9va3MgdXAgYSBuYW1lZCBleHRlbnNpb24gKHdoaWNoIGV4dGVuZHMgc29tZSAqb3RoZXIqIG1lc3NhZ2UgdHlwZSkKKyAgLy8gZGVmaW5lZCB3aXRoaW4gdGhpcyBtZXNzYWdlIHR5cGUncyBzY29wZS4KKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBGaW5kRXh0ZW5zaW9uQnlOYW1lKGNvbnN0IHN0cmluZyYgbmFtZSkgY29uc3Q7CisKKyAgLy8gU2ltaWxhciB0byBGaW5kRmllbGRCeUxvd2VyY2FzZU5hbWUoKSwgYnV0IGZpbmRzIGV4dGVuc2lvbnMgZGVmaW5lZCB3aXRoaW4KKyAgLy8gdGhpcyBtZXNzYWdlIHR5cGUncyBzY29wZS4KKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBGaW5kRXh0ZW5zaW9uQnlMb3dlcmNhc2VOYW1lKGNvbnN0IHN0cmluZyYgbmFtZSkgY29uc3Q7CisKKyAgLy8gU2ltaWxhciB0byBGaW5kRmllbGRCeUNhbWVsY2FzZU5hbWUoKSwgYnV0IGZpbmRzIGV4dGVuc2lvbnMgZGVmaW5lZCB3aXRoaW4KKyAgLy8gdGhpcyBtZXNzYWdlIHR5cGUncyBzY29wZS4KKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBGaW5kRXh0ZW5zaW9uQnlDYW1lbGNhc2VOYW1lKGNvbnN0IHN0cmluZyYgbmFtZSkgY29uc3Q7CisKKyAgLy8gUmVzZXJ2ZWQgZmllbGRzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBBIHJhbmdlIG9mIHJlc2VydmVkIGZpZWxkIG51bWJlcnMuCisgIHN0cnVjdCBSZXNlcnZlZFJhbmdlIHsKKyAgICBpbnQgc3RhcnQ7ICAvLyBpbmNsdXNpdmUKKyAgICBpbnQgZW5kOyAgICAvLyBleGNsdXNpdmUKKyAgfTsKKworICAvLyBUaGUgbnVtYmVyIG9mIHJlc2VydmVkIHJhbmdlcyBpbiB0aGlzIG1lc3NhZ2UgdHlwZS4KKyAgaW50IHJlc2VydmVkX3JhbmdlX2NvdW50KCkgY29uc3Q7CisgIC8vIEdldHMgYW4gcmVzZXJ2ZWQgcmFuZ2UgYnkgaW5kZXgsIHdoZXJlIDAgPD0gaW5kZXggPAorICAvLyByZXNlcnZlZF9yYW5nZV9jb3VudCgpLiBUaGVzZSBhcmUgcmV0dXJuZWQgaW4gdGhlIG9yZGVyIHRoZXkgd2VyZSBkZWZpbmVkCisgIC8vIGluIHRoZSAucHJvdG8gZmlsZS4KKyAgY29uc3QgUmVzZXJ2ZWRSYW5nZSogcmVzZXJ2ZWRfcmFuZ2UoaW50IGluZGV4KSBjb25zdDsKKworICAvLyBSZXR1cm5zIHRydWUgaWYgdGhlIG51bWJlciBpcyBpbiBvbmUgb2YgdGhlIHJlc2VydmVkIHJhbmdlcy4KKyAgYm9vbCBJc1Jlc2VydmVkTnVtYmVyKGludCBudW1iZXIpIGNvbnN0OworCisgIC8vIFJldHVybnMgTlVMTCBpZiBubyByZXNlcnZlZCByYW5nZSBjb250YWlucyB0aGUgZ2l2ZW4gbnVtYmVyLgorICBjb25zdCBSZXNlcnZlZFJhbmdlKiBGaW5kUmVzZXJ2ZWRSYW5nZUNvbnRhaW5pbmdOdW1iZXIoaW50IG51bWJlcikgY29uc3Q7CisKKyAgLy8gVGhlIG51bWJlciBvZiByZXNlcnZlZCBmaWVsZCBuYW1lcyBpbiB0aGlzIG1lc3NhZ2UgdHlwZS4KKyAgaW50IHJlc2VydmVkX25hbWVfY291bnQoKSBjb25zdDsKKworICAvLyBHZXRzIGEgcmVzZXJ2ZWQgbmFtZSBieSBpbmRleCwgd2hlcmUgMCA8PSBpbmRleCA8IHJlc2VydmVkX25hbWVfY291bnQoKS4KKyAgY29uc3Qgc3RyaW5nJiByZXNlcnZlZF9uYW1lKGludCBpbmRleCkgY29uc3Q7CisKKyAgLy8gUmV0dXJucyB0cnVlIGlmIHRoZSBmaWVsZCBuYW1lIGlzIHJlc2VydmVkLgorICBib29sIElzUmVzZXJ2ZWROYW1lKGNvbnN0IHN0cmluZyYgbmFtZSkgY29uc3Q7CisKKyAgLy8gU291cmNlIExvY2F0aW9uIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIFVwZGF0ZXMgfCpvdXRfbG9jYXRpb258IHRvIHRoZSBzb3VyY2UgbG9jYXRpb24gb2YgdGhlIGNvbXBsZXRlCisgIC8vIGV4dGVudCBvZiB0aGlzIG1lc3NhZ2UgZGVjbGFyYXRpb24uICBSZXR1cm5zIGZhbHNlIGFuZCBsZWF2ZXMKKyAgLy8gfCpvdXRfbG9jYXRpb258IHVuY2hhbmdlZCBpZmYgbG9jYXRpb24gaW5mb3JtYXRpb24gd2FzIG5vdCBhdmFpbGFibGUuCisgIGJvb2wgR2V0U291cmNlTG9jYXRpb24oU291cmNlTG9jYXRpb24qIG91dF9sb2NhdGlvbikgY29uc3Q7CisKKyBwcml2YXRlOgorICB0eXBlZGVmIE1lc3NhZ2VPcHRpb25zIE9wdGlvbnNUeXBlOworCisgIC8vIEFsbG93cyB0ZXN0cyB0byB0ZXN0IENvcHlUbyhwcm90bywgdHJ1ZSkuCisgIGZyaWVuZCBjbGFzcyA6Omdvb2dsZTo6cHJvdG9idWY6OmRlc2NyaXB0b3JfdW5pdHRlc3Q6OkRlc2NyaXB0b3JUZXN0OworCisgIC8vIEZpbGwgdGhlIGpzb25fbmFtZSBmaWVsZCBvZiBGaWVsZERlc2NyaXB0b3JQcm90by4KKyAgdm9pZCBDb3B5SnNvbk5hbWVUbyhEZXNjcmlwdG9yUHJvdG8qIHByb3RvKSBjb25zdDsKKworICAvLyBJbnRlcm5hbCB2ZXJzaW9uIG9mIERlYnVnU3RyaW5nOyBjb250cm9scyB0aGUgbGV2ZWwgb2YgaW5kZW50aW5nIGZvcgorICAvLyBjb3JyZWN0IGRlcHRoLiBUYWtlcyB8b3B0aW9uc3wgdG8gY29udHJvbCBkZWJ1Zy1zdHJpbmcgb3B0aW9ucywgYW5kCisgIC8vIHxpbmNsdWRlX29wZW5pbmdfY2xhdXNlfCB0byBpbmRpY2F0ZSB3aGV0aGVyIHRoZSAibWVzc2FnZSAuLi4gIiBwYXJ0IG9mIHRoZQorICAvLyBjbGF1c2UgaGFzIGFscmVhZHkgYmVlbiBnZW5lcmF0ZWQgKHRoaXMgdmFyaWVzIGRlcGVuZGluZyBvbiBjb250ZXh0KS4KKyAgdm9pZCBEZWJ1Z1N0cmluZyhpbnQgZGVwdGgsIHN0cmluZyAqY29udGVudHMsCisgICAgICAgICAgICAgICAgICAgY29uc3QgRGVidWdTdHJpbmdPcHRpb25zJiBvcHRpb25zLAorICAgICAgICAgICAgICAgICAgIGJvb2wgaW5jbHVkZV9vcGVuaW5nX2NsYXVzZSkgY29uc3Q7CisKKyAgLy8gV2Fsa3MgdXAgdGhlIGRlc2NyaXB0b3IgdHJlZSB0byBnZW5lcmF0ZSB0aGUgc291cmNlIGxvY2F0aW9uIHBhdGgKKyAgLy8gdG8gdGhpcyBkZXNjcmlwdG9yIGZyb20gdGhlIGZpbGUgcm9vdC4KKyAgdm9pZCBHZXRMb2NhdGlvblBhdGgoc3RkOjp2ZWN0b3I8aW50Piogb3V0cHV0KSBjb25zdDsKKworICBjb25zdCBzdHJpbmcqIG5hbWVfOworICBjb25zdCBzdHJpbmcqIGZ1bGxfbmFtZV87CisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlXzsKKyAgY29uc3QgRGVzY3JpcHRvciogY29udGFpbmluZ190eXBlXzsKKyAgY29uc3QgTWVzc2FnZU9wdGlvbnMqIG9wdGlvbnNfOworCisgIC8vIFRydWUgaWYgdGhpcyBpcyBhIHBsYWNlaG9sZGVyIGZvciBhbiB1bmtub3duIHR5cGUuCisgIGJvb2wgaXNfcGxhY2Vob2xkZXJfOworICAvLyBUcnVlIGlmIHRoaXMgaXMgYSBwbGFjZWhvbGRlciBhbmQgdGhlIHR5cGUgbmFtZSB3YXNuJ3QgZnVsbHktcXVhbGlmaWVkLgorICBib29sIGlzX3VucXVhbGlmaWVkX3BsYWNlaG9sZGVyXzsKKworICBpbnQgZmllbGRfY291bnRfOworICBGaWVsZERlc2NyaXB0b3IqIGZpZWxkc187CisgIGludCBvbmVvZl9kZWNsX2NvdW50XzsKKyAgT25lb2ZEZXNjcmlwdG9yKiBvbmVvZl9kZWNsc187CisgIGludCBuZXN0ZWRfdHlwZV9jb3VudF87CisgIERlc2NyaXB0b3IqIG5lc3RlZF90eXBlc187CisgIGludCBlbnVtX3R5cGVfY291bnRfOworICBFbnVtRGVzY3JpcHRvciogZW51bV90eXBlc187CisgIGludCBleHRlbnNpb25fcmFuZ2VfY291bnRfOworICBFeHRlbnNpb25SYW5nZSogZXh0ZW5zaW9uX3Jhbmdlc187CisgIGludCBleHRlbnNpb25fY291bnRfOworICBGaWVsZERlc2NyaXB0b3IqIGV4dGVuc2lvbnNfOworICBpbnQgcmVzZXJ2ZWRfcmFuZ2VfY291bnRfOworICBSZXNlcnZlZFJhbmdlKiByZXNlcnZlZF9yYW5nZXNfOworICBpbnQgcmVzZXJ2ZWRfbmFtZV9jb3VudF87CisgIGNvbnN0IHN0cmluZyoqIHJlc2VydmVkX25hbWVzXzsKKyAgLy8gSU1QT1JUQU5UOiAgSWYgeW91IGFkZCBhIG5ldyBmaWVsZCwgbWFrZSBzdXJlIHRvIHNlYXJjaCBmb3IgYWxsIGluc3RhbmNlcworICAvLyBvZiBBbGxvY2F0ZTxEZXNjcmlwdG9yPigpIGFuZCBBbGxvY2F0ZUFycmF5PERlc2NyaXB0b3I+KCkgaW4gZGVzY3JpcHRvci5jYworICAvLyBhbmQgdXBkYXRlIHRoZW0gdG8gaW5pdGlhbGl6ZSB0aGUgZmllbGQuCisKKyAgLy8gTXVzdCBiZSBjb25zdHJ1Y3RlZCB1c2luZyBEZXNjcmlwdG9yUG9vbC4KKyAgRGVzY3JpcHRvcigpIHt9CisgIGZyaWVuZCBjbGFzcyBEZXNjcmlwdG9yQnVpbGRlcjsKKyAgZnJpZW5kIGNsYXNzIEVudW1EZXNjcmlwdG9yOworICBmcmllbmQgY2xhc3MgRmllbGREZXNjcmlwdG9yOworICBmcmllbmQgY2xhc3MgT25lb2ZEZXNjcmlwdG9yOworICBmcmllbmQgY2xhc3MgTWV0aG9kRGVzY3JpcHRvcjsKKyAgZnJpZW5kIGNsYXNzIEZpbGVEZXNjcmlwdG9yOworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoRGVzY3JpcHRvcik7Cit9OworCisvLyBEZXNjcmliZXMgYSBzaW5nbGUgZmllbGQgb2YgYSBtZXNzYWdlLiAgVG8gZ2V0IHRoZSBkZXNjcmlwdG9yIGZvciBhIGdpdmVuCisvLyBmaWVsZCwgZmlyc3QgZ2V0IHRoZSBEZXNjcmlwdG9yIGZvciB0aGUgbWVzc2FnZSBpbiB3aGljaCBpdCBpcyBkZWZpbmVkLAorLy8gdGhlbiBjYWxsIERlc2NyaXB0b3I6OkZpbmRGaWVsZEJ5TmFtZSgpLiAgVG8gZ2V0IGEgRmllbGREZXNjcmlwdG9yIGZvcgorLy8gYW4gZXh0ZW5zaW9uLCBkbyBvbmUgb2YgdGhlIGZvbGxvd2luZzoKKy8vIC0gR2V0IHRoZSBEZXNjcmlwdG9yIG9yIEZpbGVEZXNjcmlwdG9yIGZvciBpdHMgY29udGFpbmluZyBzY29wZSwgdGhlbgorLy8gICBjYWxsIERlc2NyaXB0b3I6OkZpbmRFeHRlbnNpb25CeU5hbWUoKSBvcgorLy8gICBGaWxlRGVzY3JpcHRvcjo6RmluZEV4dGVuc2lvbkJ5TmFtZSgpLgorLy8gLSBHaXZlbiBhIERlc2NyaXB0b3JQb29sLCBjYWxsIERlc2NyaXB0b3JQb29sOjpGaW5kRXh0ZW5zaW9uQnlOdW1iZXIoKS4KKy8vIC0gR2l2ZW4gYSBSZWZsZWN0aW9uIGZvciBhIG1lc3NhZ2Ugb2JqZWN0LCBjYWxsCisvLyAgIFJlZmxlY3Rpb246OkZpbmRLbm93bkV4dGVuc2lvbkJ5TmFtZSgpIG9yCisvLyAgIFJlZmxlY3Rpb246OkZpbmRLbm93bkV4dGVuc2lvbkJ5TnVtYmVyKCkuCisvLyBVc2UgRGVzY3JpcHRvclBvb2wgdG8gY29uc3RydWN0IHlvdXIgb3duIGRlc2NyaXB0b3JzLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEZpZWxkRGVzY3JpcHRvciB7CisgcHVibGljOgorICAvLyBJZGVudGlmaWVzIGEgZmllbGQgdHlwZS4gIDAgaXMgcmVzZXJ2ZWQgZm9yIGVycm9ycy4gIFRoZSBvcmRlciBpcyB3ZWlyZAorICAvLyBmb3IgaGlzdG9yaWNhbCByZWFzb25zLiAgVHlwZXMgMTIgYW5kIHVwIGFyZSBuZXcgaW4gcHJvdG8yLgorICBlbnVtIFR5cGUgeworICAgIFRZUEVfRE9VQkxFICAgICAgICAgPSAxLCAgIC8vIGRvdWJsZSwgZXhhY3RseSBlaWdodCBieXRlcyBvbiB0aGUgd2lyZS4KKyAgICBUWVBFX0ZMT0FUICAgICAgICAgID0gMiwgICAvLyBmbG9hdCwgZXhhY3RseSBmb3VyIGJ5dGVzIG9uIHRoZSB3aXJlLgorICAgIFRZUEVfSU5UNjQgICAgICAgICAgPSAzLCAgIC8vIGludDY0LCB2YXJpbnQgb24gdGhlIHdpcmUuICBOZWdhdGl2ZSBudW1iZXJzCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGFrZSAxMCBieXRlcy4gIFVzZSBUWVBFX1NJTlQ2NCBpZiBuZWdhdGl2ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHZhbHVlcyBhcmUgbGlrZWx5LgorICAgIFRZUEVfVUlOVDY0ICAgICAgICAgPSA0LCAgIC8vIHVpbnQ2NCwgdmFyaW50IG9uIHRoZSB3aXJlLgorICAgIFRZUEVfSU5UMzIgICAgICAgICAgPSA1LCAgIC8vIGludDMyLCB2YXJpbnQgb24gdGhlIHdpcmUuICBOZWdhdGl2ZSBudW1iZXJzCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGFrZSAxMCBieXRlcy4gIFVzZSBUWVBFX1NJTlQzMiBpZiBuZWdhdGl2ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHZhbHVlcyBhcmUgbGlrZWx5LgorICAgIFRZUEVfRklYRUQ2NCAgICAgICAgPSA2LCAgIC8vIHVpbnQ2NCwgZXhhY3RseSBlaWdodCBieXRlcyBvbiB0aGUgd2lyZS4KKyAgICBUWVBFX0ZJWEVEMzIgICAgICAgID0gNywgICAvLyB1aW50MzIsIGV4YWN0bHkgZm91ciBieXRlcyBvbiB0aGUgd2lyZS4KKyAgICBUWVBFX0JPT0wgICAgICAgICAgID0gOCwgICAvLyBib29sLCB2YXJpbnQgb24gdGhlIHdpcmUuCisgICAgVFlQRV9TVFJJTkcgICAgICAgICA9IDksICAgLy8gVVRGLTggdGV4dC4KKyAgICBUWVBFX0dST1VQICAgICAgICAgID0gMTAsICAvLyBUYWctZGVsaW1pdGVkIG1lc3NhZ2UuICBEZXByZWNhdGVkLgorICAgIFRZUEVfTUVTU0FHRSAgICAgICAgPSAxMSwgIC8vIExlbmd0aC1kZWxpbWl0ZWQgbWVzc2FnZS4KKworICAgIFRZUEVfQllURVMgICAgICAgICAgPSAxMiwgIC8vIEFyYml0cmFyeSBieXRlIGFycmF5LgorICAgIFRZUEVfVUlOVDMyICAgICAgICAgPSAxMywgIC8vIHVpbnQzMiwgdmFyaW50IG9uIHRoZSB3aXJlCisgICAgVFlQRV9FTlVNICAgICAgICAgICA9IDE0LCAgLy8gRW51bSwgdmFyaW50IG9uIHRoZSB3aXJlCisgICAgVFlQRV9TRklYRUQzMiAgICAgICA9IDE1LCAgLy8gaW50MzIsIGV4YWN0bHkgZm91ciBieXRlcyBvbiB0aGUgd2lyZQorICAgIFRZUEVfU0ZJWEVENjQgICAgICAgPSAxNiwgIC8vIGludDY0LCBleGFjdGx5IGVpZ2h0IGJ5dGVzIG9uIHRoZSB3aXJlCisgICAgVFlQRV9TSU5UMzIgICAgICAgICA9IDE3LCAgLy8gaW50MzIsIFppZ1phZy1lbmNvZGVkIHZhcmludCBvbiB0aGUgd2lyZQorICAgIFRZUEVfU0lOVDY0ICAgICAgICAgPSAxOCwgIC8vIGludDY0LCBaaWdaYWctZW5jb2RlZCB2YXJpbnQgb24gdGhlIHdpcmUKKworICAgIE1BWF9UWVBFICAgICAgICAgICAgPSAxOCwgIC8vIENvbnN0YW50IHVzZWZ1bCBmb3IgZGVmaW5pbmcgbG9va3VwIHRhYmxlcworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGluZGV4ZWQgYnkgVHlwZS4KKyAgfTsKKworICAvLyBTcGVjaWZpZXMgdGhlIEMrKyBkYXRhIHR5cGUgdXNlZCB0byByZXByZXNlbnQgdGhlIGZpZWxkLiAgVGhlcmUgaXMgYQorICAvLyBmaXhlZCBtYXBwaW5nIGZyb20gVHlwZSB0byBDcHBUeXBlIHdoZXJlIGVhY2ggVHlwZSBtYXBzIHRvIGV4YWN0bHkgb25lCisgIC8vIENwcFR5cGUuICAwIGlzIHJlc2VydmVkIGZvciBlcnJvcnMuCisgIGVudW0gQ3BwVHlwZSB7CisgICAgQ1BQVFlQRV9JTlQzMiAgICAgICA9IDEsICAgICAvLyBUWVBFX0lOVDMyLCBUWVBFX1NJTlQzMiwgVFlQRV9TRklYRUQzMgorICAgIENQUFRZUEVfSU5UNjQgICAgICAgPSAyLCAgICAgLy8gVFlQRV9JTlQ2NCwgVFlQRV9TSU5UNjQsIFRZUEVfU0ZJWEVENjQKKyAgICBDUFBUWVBFX1VJTlQzMiAgICAgID0gMywgICAgIC8vIFRZUEVfVUlOVDMyLCBUWVBFX0ZJWEVEMzIKKyAgICBDUFBUWVBFX1VJTlQ2NCAgICAgID0gNCwgICAgIC8vIFRZUEVfVUlOVDY0LCBUWVBFX0ZJWEVENjQKKyAgICBDUFBUWVBFX0RPVUJMRSAgICAgID0gNSwgICAgIC8vIFRZUEVfRE9VQkxFCisgICAgQ1BQVFlQRV9GTE9BVCAgICAgICA9IDYsICAgICAvLyBUWVBFX0ZMT0FUCisgICAgQ1BQVFlQRV9CT09MICAgICAgICA9IDcsICAgICAvLyBUWVBFX0JPT0wKKyAgICBDUFBUWVBFX0VOVU0gICAgICAgID0gOCwgICAgIC8vIFRZUEVfRU5VTQorICAgIENQUFRZUEVfU1RSSU5HICAgICAgPSA5LCAgICAgLy8gVFlQRV9TVFJJTkcsIFRZUEVfQllURVMKKyAgICBDUFBUWVBFX01FU1NBR0UgICAgID0gMTAsICAgIC8vIFRZUEVfTUVTU0FHRSwgVFlQRV9HUk9VUAorCisgICAgTUFYX0NQUFRZUEUgICAgICAgICA9IDEwLCAgICAvLyBDb25zdGFudCB1c2VmdWwgZm9yIGRlZmluaW5nIGxvb2t1cCB0YWJsZXMKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGluZGV4ZWQgYnkgQ3BwVHlwZS4KKyAgfTsKKworICAvLyBJZGVudGlmaWVzIHdoZXRoZXIgdGhlIGZpZWxkIGlzIG9wdGlvbmFsLCByZXF1aXJlZCwgb3IgcmVwZWF0ZWQuICAwIGlzCisgIC8vIHJlc2VydmVkIGZvciBlcnJvcnMuCisgIGVudW0gTGFiZWwgeworICAgIExBQkVMX09QVElPTkFMICAgICAgPSAxLCAgICAvLyBvcHRpb25hbAorICAgIExBQkVMX1JFUVVJUkVEICAgICAgPSAyLCAgICAvLyByZXF1aXJlZAorICAgIExBQkVMX1JFUEVBVEVEICAgICAgPSAzLCAgICAvLyByZXBlYXRlZAorCisgICAgTUFYX0xBQkVMICAgICAgICAgICA9IDMsICAgIC8vIENvbnN0YW50IHVzZWZ1bCBmb3IgZGVmaW5pbmcgbG9va3VwIHRhYmxlcworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpbmRleGVkIGJ5IExhYmVsLgorICB9OworCisgIC8vIFZhbGlkIGZpZWxkIG51bWJlcnMgYXJlIHBvc2l0aXZlIGludGVnZXJzIHVwIHRvIGtNYXhOdW1iZXIuCisgIHN0YXRpYyBjb25zdCBpbnQga01heE51bWJlciA9ICgxIDw8IDI5KSAtIDE7CisKKyAgLy8gRmlyc3QgZmllbGQgbnVtYmVyIHJlc2VydmVkIGZvciB0aGUgcHJvdG9jb2wgYnVmZmVyIGxpYnJhcnkgaW1wbGVtZW50YXRpb24uCisgIC8vIFVzZXJzIG1heSBub3QgZGVjbGFyZSBmaWVsZHMgdGhhdCB1c2UgcmVzZXJ2ZWQgbnVtYmVycy4KKyAgc3RhdGljIGNvbnN0IGludCBrRmlyc3RSZXNlcnZlZE51bWJlciA9IDE5MDAwOworICAvLyBMYXN0IGZpZWxkIG51bWJlciByZXNlcnZlZCBmb3IgdGhlIHByb3RvY29sIGJ1ZmZlciBsaWJyYXJ5IGltcGxlbWVudGF0aW9uLgorICAvLyBVc2VycyBtYXkgbm90IGRlY2xhcmUgZmllbGRzIHRoYXQgdXNlIHJlc2VydmVkIG51bWJlcnMuCisgIHN0YXRpYyBjb25zdCBpbnQga0xhc3RSZXNlcnZlZE51bWJlciAgPSAxOTk5OTsKKworICBjb25zdCBzdHJpbmcmIG5hbWUoKSBjb25zdDsgICAgICAgIC8vIE5hbWUgb2YgdGhpcyBmaWVsZCB3aXRoaW4gdGhlIG1lc3NhZ2UuCisgIGNvbnN0IHN0cmluZyYgZnVsbF9uYW1lKCkgY29uc3Q7ICAgLy8gRnVsbHktcXVhbGlmaWVkIG5hbWUgb2YgdGhlIGZpZWxkLgorICBjb25zdCBzdHJpbmcmIGpzb25fbmFtZSgpIGNvbnN0OyAgIC8vIEpTT04gbmFtZSBvZiB0aGlzIGZpZWxkLgorICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSgpIGNvbnN0Oy8vIEZpbGUgaW4gd2hpY2ggdGhpcyBmaWVsZCB3YXMgZGVmaW5lZC4KKyAgYm9vbCBpc19leHRlbnNpb24oKSBjb25zdDsgICAgICAgICAvLyBJcyB0aGlzIGFuIGV4dGVuc2lvbiBmaWVsZD8KKyAgaW50IG51bWJlcigpIGNvbnN0OyAgICAgICAgICAgICAgICAvLyBEZWNsYXJlZCB0YWcgbnVtYmVyLgorCisgIC8vIFNhbWUgYXMgbmFtZSgpIGV4Y2VwdCBjb252ZXJ0ZWQgdG8gbG93ZXItY2FzZS4gIFRoaXMgKGFuZCBlc3BlY2lhbGx5IHRoZQorICAvLyBGaW5kRmllbGRCeUxvd2VyY2FzZU5hbWUoKSBtZXRob2QpIGNhbiBiZSB1c2VmdWwgd2hlbiBwYXJzaW5nIGZvcm1hdHMKKyAgLy8gd2hpY2ggcHJlZmVyIHRvIHVzZSBsb3dlcmNhc2UgbmFtaW5nIHN0eWxlLiAgKEFsdGhvdWdoLCB0ZWNobmljYWxseQorICAvLyBmaWVsZCBuYW1lcyBzaG91bGQgYmUgbG93ZXJjYXNlZCBhbnl3YXkgYWNjb3JkaW5nIHRvIHRoZSBwcm90b2J1ZiBzdHlsZQorICAvLyBndWlkZSwgc28gdGhpcyBvbmx5IG1ha2VzIGEgZGlmZmVyZW5jZSB3aGVuIGRlYWxpbmcgd2l0aCBvbGQgLnByb3RvIGZpbGVzCisgIC8vIHdoaWNoIGRvIG5vdCBmb2xsb3cgdGhlIGd1aWRlLikKKyAgY29uc3Qgc3RyaW5nJiBsb3dlcmNhc2VfbmFtZSgpIGNvbnN0OworCisgIC8vIFNhbWUgYXMgbmFtZSgpIGV4Y2VwdCBjb252ZXJ0ZWQgdG8gY2FtZWwtY2FzZS4gIEluIHRoaXMgY29udmVyc2lvbiwgYW55CisgIC8vIHRpbWUgYW4gdW5kZXJzY29yZSBhcHBlYXJzIGluIHRoZSBuYW1lLCBpdCBpcyByZW1vdmVkIGFuZCB0aGUgbmV4dAorICAvLyBsZXR0ZXIgaXMgY2FwaXRhbGl6ZWQuICBGdXJ0aGVybW9yZSwgdGhlIGZpcnN0IGxldHRlciBvZiB0aGUgbmFtZSBpcworICAvLyBsb3dlci1jYXNlZC4gIEV4YW1wbGVzOgorICAvLyAgIEZvb0JhciAtPiBmb29CYXIKKyAgLy8gICBmb29fYmFyIC0+IGZvb0JhcgorICAvLyAgIGZvb0JhciAtPiBmb29CYXIKKyAgLy8gVGhpcyAoYW5kIGVzcGVjaWFsbHkgdGhlIEZpbmRGaWVsZEJ5Q2FtZWxjYXNlTmFtZSgpIG1ldGhvZCkgY2FuIGJlIHVzZWZ1bAorICAvLyB3aGVuIHBhcnNpbmcgZm9ybWF0cyB3aGljaCBwcmVmZXIgdG8gdXNlIGNhbWVsLWNhc2UgbmFtaW5nIHN0eWxlLgorICBjb25zdCBzdHJpbmcmIGNhbWVsY2FzZV9uYW1lKCkgY29uc3Q7CisKKyAgVHlwZSB0eXBlKCkgY29uc3Q7ICAgICAgICAgICAgICAgICAgLy8gRGVjbGFyZWQgdHlwZSBvZiB0aGlzIGZpZWxkLgorICBjb25zdCBjaGFyKiB0eXBlX25hbWUoKSBjb25zdDsgICAgICAvLyBOYW1lIG9mIHRoZSBkZWNsYXJlZCB0eXBlLgorICBDcHBUeXBlIGNwcF90eXBlKCkgY29uc3Q7ICAgICAgICAgICAvLyBDKysgdHlwZSBvZiB0aGlzIGZpZWxkLgorICBjb25zdCBjaGFyKiBjcHBfdHlwZV9uYW1lKCkgY29uc3Q7ICAvLyBOYW1lIG9mIHRoZSBDKysgdHlwZS4KKyAgTGFiZWwgbGFiZWwoKSBjb25zdDsgICAgICAgICAgICAgICAgLy8gb3B0aW9uYWwvcmVxdWlyZWQvcmVwZWF0ZWQKKworICBib29sIGlzX3JlcXVpcmVkKCkgY29uc3Q7ICAgICAgLy8gc2hvcnRoYW5kIGZvciBsYWJlbCgpID09IExBQkVMX1JFUVVJUkVECisgIGJvb2wgaXNfb3B0aW9uYWwoKSBjb25zdDsgICAgICAvLyBzaG9ydGhhbmQgZm9yIGxhYmVsKCkgPT0gTEFCRUxfT1BUSU9OQUwKKyAgYm9vbCBpc19yZXBlYXRlZCgpIGNvbnN0OyAgICAgIC8vIHNob3J0aGFuZCBmb3IgbGFiZWwoKSA9PSBMQUJFTF9SRVBFQVRFRAorICBib29sIGlzX3BhY2thYmxlKCkgY29uc3Q7ICAgICAgLy8gc2hvcnRoYW5kIGZvciBpc19yZXBlYXRlZCgpICYmCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgICAgIElzVHlwZVBhY2thYmxlKHR5cGUoKSkKKyAgYm9vbCBpc19wYWNrZWQoKSBjb25zdDsgICAgICAgIC8vIHNob3J0aGFuZCBmb3IgaXNfcGFja2FibGUoKSAmJgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgICAgICAgICBvcHRpb25zKCkucGFja2VkKCkKKyAgYm9vbCBpc19tYXAoKSBjb25zdDsgICAgICAgICAgIC8vIHNob3J0aGFuZCBmb3IgdHlwZSgpID09IFRZUEVfTUVTU0FHRSAmJgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWVzc2FnZV90eXBlKCktPm9wdGlvbnMoKS5tYXBfZW50cnkoKQorCisgIC8vIEluZGV4IG9mIHRoaXMgZmllbGQgd2l0aGluIHRoZSBtZXNzYWdlJ3MgZmllbGQgYXJyYXksIG9yIHRoZSBmaWxlIG9yCisgIC8vIGV4dGVuc2lvbiBzY29wZSdzIGV4dGVuc2lvbnMgYXJyYXkuCisgIGludCBpbmRleCgpIGNvbnN0OworCisgIC8vIERvZXMgdGhpcyBmaWVsZCBoYXZlIGFuIGV4cGxpY2l0bHktZGVjbGFyZWQgZGVmYXVsdCB2YWx1ZT8KKyAgYm9vbCBoYXNfZGVmYXVsdF92YWx1ZSgpIGNvbnN0OworCisgIC8vIEdldCB0aGUgZmllbGQgZGVmYXVsdCB2YWx1ZSBpZiBjcHBfdHlwZSgpID09IENQUFRZUEVfSU5UMzIuICBJZiBubworICAvLyBleHBsaWNpdCBkZWZhdWx0IHdhcyBkZWZpbmVkLCB0aGUgZGVmYXVsdCBpcyAwLgorICBpbnQzMiBkZWZhdWx0X3ZhbHVlX2ludDMyKCkgY29uc3Q7CisgIC8vIEdldCB0aGUgZmllbGQgZGVmYXVsdCB2YWx1ZSBpZiBjcHBfdHlwZSgpID09IENQUFRZUEVfSU5UNjQuICBJZiBubworICAvLyBleHBsaWNpdCBkZWZhdWx0IHdhcyBkZWZpbmVkLCB0aGUgZGVmYXVsdCBpcyAwLgorICBpbnQ2NCBkZWZhdWx0X3ZhbHVlX2ludDY0KCkgY29uc3Q7CisgIC8vIEdldCB0aGUgZmllbGQgZGVmYXVsdCB2YWx1ZSBpZiBjcHBfdHlwZSgpID09IENQUFRZUEVfVUlOVDMyLiAgSWYgbm8KKyAgLy8gZXhwbGljaXQgZGVmYXVsdCB3YXMgZGVmaW5lZCwgdGhlIGRlZmF1bHQgaXMgMC4KKyAgdWludDMyIGRlZmF1bHRfdmFsdWVfdWludDMyKCkgY29uc3Q7CisgIC8vIEdldCB0aGUgZmllbGQgZGVmYXVsdCB2YWx1ZSBpZiBjcHBfdHlwZSgpID09IENQUFRZUEVfVUlOVDY0LiAgSWYgbm8KKyAgLy8gZXhwbGljaXQgZGVmYXVsdCB3YXMgZGVmaW5lZCwgdGhlIGRlZmF1bHQgaXMgMC4KKyAgdWludDY0IGRlZmF1bHRfdmFsdWVfdWludDY0KCkgY29uc3Q7CisgIC8vIEdldCB0aGUgZmllbGQgZGVmYXVsdCB2YWx1ZSBpZiBjcHBfdHlwZSgpID09IENQUFRZUEVfRkxPQVQuICBJZiBubworICAvLyBleHBsaWNpdCBkZWZhdWx0IHdhcyBkZWZpbmVkLCB0aGUgZGVmYXVsdCBpcyAwLjAuCisgIGZsb2F0IGRlZmF1bHRfdmFsdWVfZmxvYXQoKSBjb25zdDsKKyAgLy8gR2V0IHRoZSBmaWVsZCBkZWZhdWx0IHZhbHVlIGlmIGNwcF90eXBlKCkgPT0gQ1BQVFlQRV9ET1VCTEUuICBJZiBubworICAvLyBleHBsaWNpdCBkZWZhdWx0IHdhcyBkZWZpbmVkLCB0aGUgZGVmYXVsdCBpcyAwLjAuCisgIGRvdWJsZSBkZWZhdWx0X3ZhbHVlX2RvdWJsZSgpIGNvbnN0OworICAvLyBHZXQgdGhlIGZpZWxkIGRlZmF1bHQgdmFsdWUgaWYgY3BwX3R5cGUoKSA9PSBDUFBUWVBFX0JPT0wuICBJZiBubworICAvLyBleHBsaWNpdCBkZWZhdWx0IHdhcyBkZWZpbmVkLCB0aGUgZGVmYXVsdCBpcyBmYWxzZS4KKyAgYm9vbCBkZWZhdWx0X3ZhbHVlX2Jvb2woKSBjb25zdDsKKyAgLy8gR2V0IHRoZSBmaWVsZCBkZWZhdWx0IHZhbHVlIGlmIGNwcF90eXBlKCkgPT0gQ1BQVFlQRV9FTlVNLiAgSWYgbm8KKyAgLy8gZXhwbGljaXQgZGVmYXVsdCB3YXMgZGVmaW5lZCwgdGhlIGRlZmF1bHQgaXMgdGhlIGZpcnN0IHZhbHVlIGRlZmluZWQKKyAgLy8gaW4gdGhlIGVudW0gdHlwZSAoYWxsIGVudW0gdHlwZXMgYXJlIHJlcXVpcmVkIHRvIGhhdmUgYXQgbGVhc3Qgb25lIHZhbHVlKS4KKyAgLy8gVGhpcyBuZXZlciByZXR1cm5zIE5VTEwuCisgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIGRlZmF1bHRfdmFsdWVfZW51bSgpIGNvbnN0OworICAvLyBHZXQgdGhlIGZpZWxkIGRlZmF1bHQgdmFsdWUgaWYgY3BwX3R5cGUoKSA9PSBDUFBUWVBFX1NUUklORy4gIElmIG5vCisgIC8vIGV4cGxpY2l0IGRlZmF1bHQgd2FzIGRlZmluZWQsIHRoZSBkZWZhdWx0IGlzIHRoZSBlbXB0eSBzdHJpbmcuCisgIGNvbnN0IHN0cmluZyYgZGVmYXVsdF92YWx1ZV9zdHJpbmcoKSBjb25zdDsKKworICAvLyBUaGUgRGVzY3JpcHRvciBmb3IgdGhlIG1lc3NhZ2Ugb2Ygd2hpY2ggdGhpcyBpcyBhIGZpZWxkLiAgRm9yIGV4dGVuc2lvbnMsCisgIC8vIHRoaXMgaXMgdGhlIGV4dGVuZGVkIHR5cGUuICBOZXZlciBOVUxMLgorICBjb25zdCBEZXNjcmlwdG9yKiBjb250YWluaW5nX3R5cGUoKSBjb25zdDsKKworICAvLyBJZiB0aGUgZmllbGQgaXMgYSBtZW1iZXIgb2YgYSBvbmVvZiwgdGhpcyBpcyB0aGUgb25lLCBvdGhlcndpc2UgdGhpcyBpcworICAvLyBOVUxMLgorICBjb25zdCBPbmVvZkRlc2NyaXB0b3IqIGNvbnRhaW5pbmdfb25lb2YoKSBjb25zdDsKKworICAvLyBJZiB0aGUgZmllbGQgaXMgYSBtZW1iZXIgb2YgYSBvbmVvZiwgcmV0dXJucyB0aGUgaW5kZXggaW4gdGhhdCBvbmVvZi4KKyAgaW50IGluZGV4X2luX29uZW9mKCkgY29uc3Q7CisKKyAgLy8gQW4gZXh0ZW5zaW9uIG1heSBiZSBkZWNsYXJlZCB3aXRoaW4gdGhlIHNjb3BlIG9mIGFub3RoZXIgbWVzc2FnZS4gIElmIHRoaXMKKyAgLy8gZmllbGQgaXMgYW4gZXh0ZW5zaW9uIChpc19leHRlbnNpb24oKSBpcyB0cnVlKSwgdGhlbiBleHRlbnNpb25fc2NvcGUoKQorICAvLyByZXR1cm5zIHRoYXQgbWVzc2FnZSwgb3IgTlVMTCBpZiB0aGUgZXh0ZW5zaW9uIHdhcyBkZWNsYXJlZCBhdCBnbG9iYWwKKyAgLy8gc2NvcGUuICBJZiB0aGlzIGlzIG5vdCBhbiBleHRlbnNpb24sIGV4dGVuc2lvbl9zY29wZSgpIGlzIHVuZGVmaW5lZCAobWF5CisgIC8vIGFzc2VydC1mYWlsKS4KKyAgY29uc3QgRGVzY3JpcHRvciogZXh0ZW5zaW9uX3Njb3BlKCkgY29uc3Q7CisKKyAgLy8gSWYgdHlwZSBpcyBUWVBFX01FU1NBR0Ugb3IgVFlQRV9HUk9VUCwgcmV0dXJucyBhIGRlc2NyaXB0b3IgZm9yIHRoZQorICAvLyBtZXNzYWdlIG9yIHRoZSBncm91cCB0eXBlLiAgT3RoZXJ3aXNlLCByZXR1cm5zIG51bGwuCisgIGNvbnN0IERlc2NyaXB0b3IqIG1lc3NhZ2VfdHlwZSgpIGNvbnN0OworICAvLyBJZiB0eXBlIGlzIFRZUEVfRU5VTSwgcmV0dXJucyBhIGRlc2NyaXB0b3IgZm9yIHRoZSBlbnVtLiAgT3RoZXJ3aXNlLAorICAvLyByZXR1cm5zIG51bGwuCisgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBlbnVtX3R5cGUoKSBjb25zdDsKKworICAvLyBHZXQgdGhlIEZpZWxkT3B0aW9ucyBmb3IgdGhpcyBmaWVsZC4gIFRoaXMgaW5jbHVkZXMgdGhpbmdzIGxpc3RlZCBpbgorICAvLyBzcXVhcmUgYnJhY2tldHMgYWZ0ZXIgdGhlIGZpZWxkIGRlZmluaXRpb24uICBFLmcuLCB0aGUgZmllbGQ6CisgIC8vICAgb3B0aW9uYWwgc3RyaW5nIHRleHQgPSAxIFtjdHlwZT1DT1JEXTsKKyAgLy8gaGFzIHRoZSAiY3R5cGUiIG9wdGlvbiBzZXQuICBBbGxvd2VkIG9wdGlvbnMgYXJlIGRlZmluZWQgYnkgRmllbGRPcHRpb25zCisgIC8vIGluIGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvLCBhbmQgYW55IGF2YWlsYWJsZSBleHRlbnNpb25zIG9mIHRoYXQKKyAgLy8gbWVzc2FnZS4KKyAgY29uc3QgRmllbGRPcHRpb25zJiBvcHRpb25zKCkgY29uc3Q7CisKKyAgLy8gU2VlIERlc2NyaXB0b3I6OkNvcHlUbygpLgorICB2b2lkIENvcHlUbyhGaWVsZERlc2NyaXB0b3JQcm90byogcHJvdG8pIGNvbnN0OworCisgIC8vIFNlZSBEZXNjcmlwdG9yOjpEZWJ1Z1N0cmluZygpLgorICBzdHJpbmcgRGVidWdTdHJpbmcoKSBjb25zdDsKKworICAvLyBTZWUgRGVzY3JpcHRvcjo6RGVidWdTdHJpbmdXaXRoT3B0aW9ucygpLgorICBzdHJpbmcgRGVidWdTdHJpbmdXaXRoT3B0aW9ucyhjb25zdCBEZWJ1Z1N0cmluZ09wdGlvbnMmIG9wdGlvbnMpIGNvbnN0OworCisgIC8vIEhlbHBlciBtZXRob2QgdG8gZ2V0IHRoZSBDcHBUeXBlIGZvciBhIHBhcnRpY3VsYXIgVHlwZS4KKyAgc3RhdGljIENwcFR5cGUgVHlwZVRvQ3BwVHlwZShUeXBlIHR5cGUpOworCisgIC8vIEhlbHBlciBtZXRob2QgdG8gZ2V0IHRoZSBuYW1lIG9mIGEgVHlwZS4KKyAgc3RhdGljIGNvbnN0IGNoYXIqIFR5cGVOYW1lKFR5cGUgdHlwZSk7CisKKyAgLy8gSGVscGVyIG1ldGhvZCB0byBnZXQgdGhlIG5hbWUgb2YgYSBDcHBUeXBlLgorICBzdGF0aWMgY29uc3QgY2hhciogQ3BwVHlwZU5hbWUoQ3BwVHlwZSBjcHBfdHlwZSk7CisKKyAgLy8gUmV0dXJuIHRydWUgaWZmIFtwYWNrZWQgPSB0cnVlXSBpcyB2YWxpZCBmb3IgZmllbGRzIG9mIHRoaXMgdHlwZS4KKyAgc3RhdGljIGlubGluZSBib29sIElzVHlwZVBhY2thYmxlKFR5cGUgZmllbGRfdHlwZSk7CisKKyAgLy8gU291cmNlIExvY2F0aW9uIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIFVwZGF0ZXMgfCpvdXRfbG9jYXRpb258IHRvIHRoZSBzb3VyY2UgbG9jYXRpb24gb2YgdGhlIGNvbXBsZXRlCisgIC8vIGV4dGVudCBvZiB0aGlzIGZpZWxkIGRlY2xhcmF0aW9uLiAgUmV0dXJucyBmYWxzZSBhbmQgbGVhdmVzCisgIC8vIHwqb3V0X2xvY2F0aW9ufCB1bmNoYW5nZWQgaWZmIGxvY2F0aW9uIGluZm9ybWF0aW9uIHdhcyBub3QgYXZhaWxhYmxlLgorICBib29sIEdldFNvdXJjZUxvY2F0aW9uKFNvdXJjZUxvY2F0aW9uKiBvdXRfbG9jYXRpb24pIGNvbnN0OworCisgcHJpdmF0ZToKKyAgdHlwZWRlZiBGaWVsZE9wdGlvbnMgT3B0aW9uc1R5cGU7CisKKyAgLy8gRmlsbCB0aGUganNvbl9uYW1lIGZpZWxkIG9mIEZpZWxkRGVzY3JpcHRvclByb3RvLgorICB2b2lkIENvcHlKc29uTmFtZVRvKEZpZWxkRGVzY3JpcHRvclByb3RvKiBwcm90bykgY29uc3Q7CisKKyAgLy8gU2VlIERlc2NyaXB0b3I6OkRlYnVnU3RyaW5nKCkuCisgIGVudW0gUHJpbnRMYWJlbEZsYWcgeyBQUklOVF9MQUJFTCwgT01JVF9MQUJFTCB9OworICB2b2lkIERlYnVnU3RyaW5nKGludCBkZXB0aCwgUHJpbnRMYWJlbEZsYWcgcHJpbnRfbGFiZWxfZmxhZywKKyAgICAgICAgICAgICAgICAgICBzdHJpbmcqIGNvbnRlbnRzLCBjb25zdCBEZWJ1Z1N0cmluZ09wdGlvbnMmIG9wdGlvbnMpIGNvbnN0OworCisgIC8vIGZvcm1hdHMgdGhlIGRlZmF1bHQgdmFsdWUgYXBwcm9wcmlhdGVseSBhbmQgcmV0dXJucyBpdCBhcyBhIHN0cmluZy4KKyAgLy8gTXVzdCBoYXZlIGEgZGVmYXVsdCB2YWx1ZSB0byBjYWxsIHRoaXMuIElmIHF1b3RlX3N0cmluZ190eXBlIGlzIHRydWUsIHRoZW4KKyAgLy8gdHlwZXMgb2YgQ1BQVFlQRV9TVFJJTkcgd2hpbGwgYmUgc3Vycm91bmRlZCBieSBxdW90ZXMgYW5kIENFc2NhcGVkLgorICBzdHJpbmcgRGVmYXVsdFZhbHVlQXNTdHJpbmcoYm9vbCBxdW90ZV9zdHJpbmdfdHlwZSkgY29uc3Q7CisKKyAgLy8gSGVscGVyIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyB0aGUgZmllbGQgdHlwZSBuYW1lIGZvciBEZWJ1Z1N0cmluZy4KKyAgc3RyaW5nIEZpZWxkVHlwZU5hbWVEZWJ1Z1N0cmluZygpIGNvbnN0OworCisgIC8vIFdhbGtzIHVwIHRoZSBkZXNjcmlwdG9yIHRyZWUgdG8gZ2VuZXJhdGUgdGhlIHNvdXJjZSBsb2NhdGlvbiBwYXRoCisgIC8vIHRvIHRoaXMgZGVzY3JpcHRvciBmcm9tIHRoZSBmaWxlIHJvb3QuCisgIHZvaWQgR2V0TG9jYXRpb25QYXRoKHN0ZDo6dmVjdG9yPGludD4qIG91dHB1dCkgY29uc3Q7CisKKyAgY29uc3Qgc3RyaW5nKiBuYW1lXzsKKyAgY29uc3Qgc3RyaW5nKiBmdWxsX25hbWVfOworICBjb25zdCBzdHJpbmcqIGxvd2VyY2FzZV9uYW1lXzsKKyAgY29uc3Qgc3RyaW5nKiBjYW1lbGNhc2VfbmFtZV87CisgIC8vIFdoZXRoZXIgdGhlIHVzZXIgaGFzIHNwZWNpZmllZCB0aGUganNvbl9uYW1lIGZpZWxkIG9wdGlvbiBpbiB0aGUgLnByb3RvCisgIC8vIGZpbGUuCisgIGJvb2wgaGFzX2pzb25fbmFtZV87CisgIC8vIElmIGhhc19qc29uX25hbWVfIGlzIHRydWUsIGl0J3MgdGhlIHZhbHVlIHNwZWNpZmllZCBieSB0aGUgdXNlci4KKyAgLy8gT3RoZXJ3aXNlLCBpdCBoYXMgdGhlIHNhbWUgdmFsdWUgYXMgbG93ZXJjYXNlX25hbWVfLgorICBjb25zdCBzdHJpbmcqIGpzb25fbmFtZV87CisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlXzsKKyAgaW50IG51bWJlcl87CisgIFR5cGUgdHlwZV87CisgIExhYmVsIGxhYmVsXzsKKyAgYm9vbCBpc19leHRlbnNpb25fOworICBpbnQgaW5kZXhfaW5fb25lb2ZfOworICBjb25zdCBEZXNjcmlwdG9yKiBjb250YWluaW5nX3R5cGVfOworICBjb25zdCBPbmVvZkRlc2NyaXB0b3IqIGNvbnRhaW5pbmdfb25lb2ZfOworICBjb25zdCBEZXNjcmlwdG9yKiBleHRlbnNpb25fc2NvcGVfOworICBjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlX3R5cGVfOworICBjb25zdCBFbnVtRGVzY3JpcHRvciogZW51bV90eXBlXzsKKyAgY29uc3QgRmllbGRPcHRpb25zKiBvcHRpb25zXzsKKyAgLy8gSU1QT1JUQU5UOiAgSWYgeW91IGFkZCBhIG5ldyBmaWVsZCwgbWFrZSBzdXJlIHRvIHNlYXJjaCBmb3IgYWxsIGluc3RhbmNlcworICAvLyBvZiBBbGxvY2F0ZTxGaWVsZERlc2NyaXB0b3I+KCkgYW5kIEFsbG9jYXRlQXJyYXk8RmllbGREZXNjcmlwdG9yPigpIGluCisgIC8vIGRlc2NyaXB0b3IuY2MgYW5kIHVwZGF0ZSB0aGVtIHRvIGluaXRpYWxpemUgdGhlIGZpZWxkLgorCisgIGJvb2wgaGFzX2RlZmF1bHRfdmFsdWVfOworICB1bmlvbiB7CisgICAgaW50MzIgIGRlZmF1bHRfdmFsdWVfaW50MzJfOworICAgIGludDY0ICBkZWZhdWx0X3ZhbHVlX2ludDY0XzsKKyAgICB1aW50MzIgZGVmYXVsdF92YWx1ZV91aW50MzJfOworICAgIHVpbnQ2NCBkZWZhdWx0X3ZhbHVlX3VpbnQ2NF87CisgICAgZmxvYXQgIGRlZmF1bHRfdmFsdWVfZmxvYXRfOworICAgIGRvdWJsZSBkZWZhdWx0X3ZhbHVlX2RvdWJsZV87CisgICAgYm9vbCAgIGRlZmF1bHRfdmFsdWVfYm9vbF87CisKKyAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBkZWZhdWx0X3ZhbHVlX2VudW1fOworICAgIGNvbnN0IHN0cmluZyogZGVmYXVsdF92YWx1ZV9zdHJpbmdfOworICB9OworCisgIHN0YXRpYyBjb25zdCBDcHBUeXBlIGtUeXBlVG9DcHBUeXBlTWFwW01BWF9UWVBFICsgMV07CisKKyAgc3RhdGljIGNvbnN0IGNoYXIgKiBjb25zdCBrVHlwZVRvTmFtZVtNQVhfVFlQRSArIDFdOworCisgIHN0YXRpYyBjb25zdCBjaGFyICogY29uc3Qga0NwcFR5cGVUb05hbWVbTUFYX0NQUFRZUEUgKyAxXTsKKworICBzdGF0aWMgY29uc3QgY2hhciAqIGNvbnN0IGtMYWJlbFRvTmFtZVtNQVhfTEFCRUwgKyAxXTsKKworICAvLyBNdXN0IGJlIGNvbnN0cnVjdGVkIHVzaW5nIERlc2NyaXB0b3JQb29sLgorICBGaWVsZERlc2NyaXB0b3IoKSB7fQorICBmcmllbmQgY2xhc3MgRGVzY3JpcHRvckJ1aWxkZXI7CisgIGZyaWVuZCBjbGFzcyBGaWxlRGVzY3JpcHRvcjsKKyAgZnJpZW5kIGNsYXNzIERlc2NyaXB0b3I7CisgIGZyaWVuZCBjbGFzcyBPbmVvZkRlc2NyaXB0b3I7CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhGaWVsZERlc2NyaXB0b3IpOworfTsKKworLy8gRGVzY3JpYmVzIGEgb25lb2YgZGVmaW5lZCBpbiBhIG1lc3NhZ2UgdHlwZS4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBPbmVvZkRlc2NyaXB0b3IgeworIHB1YmxpYzoKKyAgY29uc3Qgc3RyaW5nJiBuYW1lKCkgY29uc3Q7ICAgICAgIC8vIE5hbWUgb2YgdGhpcyBvbmVvZi4KKyAgY29uc3Qgc3RyaW5nJiBmdWxsX25hbWUoKSBjb25zdDsgIC8vIEZ1bGx5LXF1YWxpZmllZCBuYW1lIG9mIHRoZSBvbmVvZi4KKworICAvLyBJbmRleCBvZiB0aGlzIG9uZW9mIHdpdGhpbiB0aGUgbWVzc2FnZSdzIG9uZW9mIGFycmF5LgorICBpbnQgaW5kZXgoKSBjb25zdDsKKworICAvLyBUaGUgRGVzY3JpcHRvciBmb3IgdGhlIG1lc3NhZ2UgY29udGFpbmluZyB0aGlzIG9uZW9mLgorICBjb25zdCBEZXNjcmlwdG9yKiBjb250YWluaW5nX3R5cGUoKSBjb25zdDsKKworICAvLyBUaGUgbnVtYmVyIG9mIChub24tZXh0ZW5zaW9uKSBmaWVsZHMgd2hpY2ggYXJlIG1lbWJlcnMgb2YgdGhpcyBvbmVvZi4KKyAgaW50IGZpZWxkX2NvdW50KCkgY29uc3Q7CisgIC8vIEdldCBhIG1lbWJlciBvZiB0aGlzIG9uZW9mLCBpbiB0aGUgb3JkZXIgaW4gd2hpY2ggdGhleSB3ZXJlIGRlY2xhcmVkIGluIHRoZQorICAvLyAucHJvdG8gZmlsZS4gIERvZXMgbm90IGluY2x1ZGUgZXh0ZW5zaW9ucy4KKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZChpbnQgaW5kZXgpIGNvbnN0OworCisgIC8vIFNlZSBEZXNjcmlwdG9yOjpDb3B5VG8oKS4KKyAgdm9pZCBDb3B5VG8oT25lb2ZEZXNjcmlwdG9yUHJvdG8qIHByb3RvKSBjb25zdDsKKworICAvLyBTZWUgRGVzY3JpcHRvcjo6RGVidWdTdHJpbmcoKS4KKyAgc3RyaW5nIERlYnVnU3RyaW5nKCkgY29uc3Q7CisKKyAgLy8gU2VlIERlc2NyaXB0b3I6OkRlYnVnU3RyaW5nV2l0aE9wdGlvbnMoKS4KKyAgc3RyaW5nIERlYnVnU3RyaW5nV2l0aE9wdGlvbnMoY29uc3QgRGVidWdTdHJpbmdPcHRpb25zJiBvcHRpb25zKSBjb25zdDsKKworICAvLyBTb3VyY2UgTG9jYXRpb24gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gVXBkYXRlcyB8Km91dF9sb2NhdGlvbnwgdG8gdGhlIHNvdXJjZSBsb2NhdGlvbiBvZiB0aGUgY29tcGxldGUKKyAgLy8gZXh0ZW50IG9mIHRoaXMgb25lb2YgZGVjbGFyYXRpb24uICBSZXR1cm5zIGZhbHNlIGFuZCBsZWF2ZXMKKyAgLy8gfCpvdXRfbG9jYXRpb258IHVuY2hhbmdlZCBpZmYgbG9jYXRpb24gaW5mb3JtYXRpb24gd2FzIG5vdCBhdmFpbGFibGUuCisgIGJvb2wgR2V0U291cmNlTG9jYXRpb24oU291cmNlTG9jYXRpb24qIG91dF9sb2NhdGlvbikgY29uc3Q7CisKKyBwcml2YXRlOgorICAvLyBTZWUgRGVzY3JpcHRvcjo6RGVidWdTdHJpbmcoKS4KKyAgdm9pZCBEZWJ1Z1N0cmluZyhpbnQgZGVwdGgsIHN0cmluZyogY29udGVudHMsCisgICAgICAgICAgICAgICAgICAgY29uc3QgRGVidWdTdHJpbmdPcHRpb25zJiBvcHRpb25zKSBjb25zdDsKKworICAvLyBXYWxrcyB1cCB0aGUgZGVzY3JpcHRvciB0cmVlIHRvIGdlbmVyYXRlIHRoZSBzb3VyY2UgbG9jYXRpb24gcGF0aAorICAvLyB0byB0aGlzIGRlc2NyaXB0b3IgZnJvbSB0aGUgZmlsZSByb290LgorICB2b2lkIEdldExvY2F0aW9uUGF0aChzdGQ6OnZlY3RvcjxpbnQ+KiBvdXRwdXQpIGNvbnN0OworCisgIGNvbnN0IHN0cmluZyogbmFtZV87CisgIGNvbnN0IHN0cmluZyogZnVsbF9uYW1lXzsKKyAgY29uc3QgRGVzY3JpcHRvciogY29udGFpbmluZ190eXBlXzsKKyAgYm9vbCBpc19leHRlbmRhYmxlXzsKKyAgaW50IGZpZWxkX2NvdW50XzsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiogZmllbGRzXzsKKyAgLy8gSU1QT1JUQU5UOiAgSWYgeW91IGFkZCBhIG5ldyBmaWVsZCwgbWFrZSBzdXJlIHRvIHNlYXJjaCBmb3IgYWxsIGluc3RhbmNlcworICAvLyBvZiBBbGxvY2F0ZTxPbmVvZkRlc2NyaXB0b3I+KCkgYW5kIEFsbG9jYXRlQXJyYXk8T25lb2ZEZXNjcmlwdG9yPigpCisgIC8vIGluIGRlc2NyaXB0b3IuY2MgYW5kIHVwZGF0ZSB0aGVtIHRvIGluaXRpYWxpemUgdGhlIGZpZWxkLgorCisgIC8vIE11c3QgYmUgY29uc3RydWN0ZWQgdXNpbmcgRGVzY3JpcHRvclBvb2wuCisgIE9uZW9mRGVzY3JpcHRvcigpIHt9CisgIGZyaWVuZCBjbGFzcyBEZXNjcmlwdG9yQnVpbGRlcjsKKyAgZnJpZW5kIGNsYXNzIERlc2NyaXB0b3I7CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhPbmVvZkRlc2NyaXB0b3IpOworfTsKKworLy8gRGVzY3JpYmVzIGFuIGVudW0gdHlwZSBkZWZpbmVkIGluIGEgLnByb3RvIGZpbGUuICBUbyBnZXQgdGhlIEVudW1EZXNjcmlwdG9yCisvLyBmb3IgYSBnZW5lcmF0ZWQgZW51bSB0eXBlLCBjYWxsIFR5cGVOYW1lX2Rlc2NyaXB0b3IoKS4gIFVzZSBEZXNjcmlwdG9yUG9vbAorLy8gdG8gY29uc3RydWN0IHlvdXIgb3duIGRlc2NyaXB0b3JzLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEVudW1EZXNjcmlwdG9yIHsKKyBwdWJsaWM6CisgIC8vIFRoZSBuYW1lIG9mIHRoaXMgZW51bSB0eXBlIGluIHRoZSBjb250YWluaW5nIHNjb3BlLgorICBjb25zdCBzdHJpbmcmIG5hbWUoKSBjb25zdDsKKworICAvLyBUaGUgZnVsbHktcXVhbGlmaWVkIG5hbWUgb2YgdGhlIGVudW0gdHlwZSwgc2NvcGUgZGVsaW1pdGVkIGJ5IHBlcmlvZHMuCisgIGNvbnN0IHN0cmluZyYgZnVsbF9uYW1lKCkgY29uc3Q7CisKKyAgLy8gSW5kZXggb2YgdGhpcyBlbnVtIHdpdGhpbiB0aGUgZmlsZSBvciBjb250YWluaW5nIG1lc3NhZ2UncyBlbnVtIGFycmF5LgorICBpbnQgaW5kZXgoKSBjb25zdDsKKworICAvLyBUaGUgLnByb3RvIGZpbGUgaW4gd2hpY2ggdGhpcyBlbnVtIHR5cGUgd2FzIGRlZmluZWQuICBOZXZlciBOVUxMLgorICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSgpIGNvbnN0OworCisgIC8vIFRoZSBudW1iZXIgb2YgdmFsdWVzIGZvciB0aGlzIEVudW1EZXNjcmlwdG9yLiAgR3VhcmFudGVlZCB0byBiZSBncmVhdGVyCisgIC8vIHRoYW4gemVyby4KKyAgaW50IHZhbHVlX2NvdW50KCkgY29uc3Q7CisgIC8vIEdldHMgYSB2YWx1ZSBieSBpbmRleCwgd2hlcmUgMCA8PSBpbmRleCA8IHZhbHVlX2NvdW50KCkuCisgIC8vIFRoZXNlIGFyZSByZXR1cm5lZCBpbiB0aGUgb3JkZXIgdGhleSB3ZXJlIGRlZmluZWQgaW4gdGhlIC5wcm90byBmaWxlLgorICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiB2YWx1ZShpbnQgaW5kZXgpIGNvbnN0OworCisgIC8vIExvb2tzIHVwIGEgdmFsdWUgYnkgbmFtZS4gIFJldHVybnMgTlVMTCBpZiBubyBzdWNoIHZhbHVlIGV4aXN0cy4KKyAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogRmluZFZhbHVlQnlOYW1lKGNvbnN0IHN0cmluZyYgbmFtZSkgY29uc3Q7CisgIC8vIExvb2tzIHVwIGEgdmFsdWUgYnkgbnVtYmVyLiAgUmV0dXJucyBOVUxMIGlmIG5vIHN1Y2ggdmFsdWUgZXhpc3RzLiAgSWYKKyAgLy8gbXVsdGlwbGUgdmFsdWVzIGhhdmUgdGhpcyBudW1iZXIsIHRoZSBmaXJzdCBvbmUgZGVmaW5lZCBpcyByZXR1cm5lZC4KKyAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogRmluZFZhbHVlQnlOdW1iZXIoaW50IG51bWJlcikgY29uc3Q7CisKKyAgLy8gSWYgdGhpcyBlbnVtIHR5cGUgaXMgbmVzdGVkIGluIGEgbWVzc2FnZSB0eXBlLCB0aGlzIGlzIHRoYXQgbWVzc2FnZSB0eXBlLgorICAvLyBPdGhlcndpc2UsIE5VTEwuCisgIGNvbnN0IERlc2NyaXB0b3IqIGNvbnRhaW5pbmdfdHlwZSgpIGNvbnN0OworCisgIC8vIEdldCBvcHRpb25zIGZvciB0aGlzIGVudW0gdHlwZS4gIFRoZXNlIGFyZSBzcGVjaWZpZWQgaW4gdGhlIC5wcm90byBmaWxlIGJ5CisgIC8vIHBsYWNpbmcgbGluZXMgbGlrZSAib3B0aW9uIGZvbyA9IDEyMzQ7IiBpbiB0aGUgZW51bSBkZWZpbml0aW9uLiAgQWxsb3dlZAorICAvLyBvcHRpb25zIGFyZSBkZWZpbmVkIGJ5IEVudW1PcHRpb25zIGluIGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvLAorICAvLyBhbmQgYW55IGF2YWlsYWJsZSBleHRlbnNpb25zIG9mIHRoYXQgbWVzc2FnZS4KKyAgY29uc3QgRW51bU9wdGlvbnMmIG9wdGlvbnMoKSBjb25zdDsKKworICAvLyBTZWUgRGVzY3JpcHRvcjo6Q29weVRvKCkuCisgIHZvaWQgQ29weVRvKEVudW1EZXNjcmlwdG9yUHJvdG8qIHByb3RvKSBjb25zdDsKKworICAvLyBTZWUgRGVzY3JpcHRvcjo6RGVidWdTdHJpbmcoKS4KKyAgc3RyaW5nIERlYnVnU3RyaW5nKCkgY29uc3Q7CisKKyAgLy8gU2VlIERlc2NyaXB0b3I6OkRlYnVnU3RyaW5nV2l0aE9wdGlvbnMoKS4KKyAgc3RyaW5nIERlYnVnU3RyaW5nV2l0aE9wdGlvbnMoY29uc3QgRGVidWdTdHJpbmdPcHRpb25zJiBvcHRpb25zKSBjb25zdDsKKworCisgIC8vIFJldHVybnMgdHJ1ZSBpZiB0aGlzIGlzIGEgcGxhY2Vob2xkZXIgZm9yIGFuIHVua25vd24gZW51bS4gVGhpcyB3aWxsCisgIC8vIG9ubHkgYmUgdGhlIGNhc2UgaWYgdGhpcyBkZXNjcmlwdG9yIGNvbWVzIGZyb20gYSBEZXNjcmlwdG9yUG9vbAorICAvLyB3aXRoIEFsbG93VW5rbm93bkRlcGVuZGVuY2llcygpIHNldC4KKyAgYm9vbCBpc19wbGFjZWhvbGRlcigpIGNvbnN0OworCisgIC8vIFNvdXJjZSBMb2NhdGlvbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBVcGRhdGVzIHwqb3V0X2xvY2F0aW9ufCB0byB0aGUgc291cmNlIGxvY2F0aW9uIG9mIHRoZSBjb21wbGV0ZQorICAvLyBleHRlbnQgb2YgdGhpcyBlbnVtIGRlY2xhcmF0aW9uLiAgUmV0dXJucyBmYWxzZSBhbmQgbGVhdmVzCisgIC8vIHwqb3V0X2xvY2F0aW9ufCB1bmNoYW5nZWQgaWZmIGxvY2F0aW9uIGluZm9ybWF0aW9uIHdhcyBub3QgYXZhaWxhYmxlLgorICBib29sIEdldFNvdXJjZUxvY2F0aW9uKFNvdXJjZUxvY2F0aW9uKiBvdXRfbG9jYXRpb24pIGNvbnN0OworCisgcHJpdmF0ZToKKyAgdHlwZWRlZiBFbnVtT3B0aW9ucyBPcHRpb25zVHlwZTsKKworICAvLyBMb29rcyB1cCBhIHZhbHVlIGJ5IG51bWJlci4gIElmIHRoZSB2YWx1ZSBkb2VzIG5vdCBleGlzdCwgZHluYW1pY2FsbHkKKyAgLy8gY3JlYXRlcyBhIG5ldyBFbnVtVmFsdWVEZXNjcmlwdG9yIGZvciB0aGF0IHZhbHVlLCBhc3N1bWluZyB0aGF0IGl0IHdhcworICAvLyB1bmtub3duLiBJZiBhIG5ldyBkZXNjcmlwdG9yIGlzIGNyZWF0ZWQsIHRoaXMgaXMgZG9uZSBpbiBhIHRocmVhZC1zYWZlIHdheSwKKyAgLy8gYW5kIGZ1dHVyZSBjYWxscyB3aWxsIHJldHVybiB0aGUgc2FtZSB2YWx1ZSBkZXNjcmlwdG9yIHBvaW50ZXIuCisgIC8vCisgIC8vIFRoaXMgaXMgcHJpdmF0ZSBidXQgaXMgdXNlZCBieSBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbiAod2hpY2ggaXMKKyAgLy8gZnJpZW5kZWQgYmVsb3cpIHRvIHJldHVybiBhIHZhbGlkIEVudW1WYWx1ZURlc2NyaXB0b3IgZnJvbSBHZXRFbnVtKCkgd2hlbgorICAvLyB0aGlzIGZlYXR1cmUgaXMgZW5hYmxlZC4KKyAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvcioKKyAgICAgIEZpbmRWYWx1ZUJ5TnVtYmVyQ3JlYXRpbmdJZlVua25vd24oaW50IG51bWJlcikgY29uc3Q7CisKKworICAvLyBTZWUgRGVzY3JpcHRvcjo6RGVidWdTdHJpbmcoKS4KKyAgdm9pZCBEZWJ1Z1N0cmluZyhpbnQgZGVwdGgsIHN0cmluZyAqY29udGVudHMsCisgICAgICAgICAgICAgICAgICAgY29uc3QgRGVidWdTdHJpbmdPcHRpb25zJiBvcHRpb25zKSBjb25zdDsKKworICAvLyBXYWxrcyB1cCB0aGUgZGVzY3JpcHRvciB0cmVlIHRvIGdlbmVyYXRlIHRoZSBzb3VyY2UgbG9jYXRpb24gcGF0aAorICAvLyB0byB0aGlzIGRlc2NyaXB0b3IgZnJvbSB0aGUgZmlsZSByb290LgorICB2b2lkIEdldExvY2F0aW9uUGF0aChzdGQ6OnZlY3RvcjxpbnQ+KiBvdXRwdXQpIGNvbnN0OworCisgIGNvbnN0IHN0cmluZyogbmFtZV87CisgIGNvbnN0IHN0cmluZyogZnVsbF9uYW1lXzsKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGVfOworICBjb25zdCBEZXNjcmlwdG9yKiBjb250YWluaW5nX3R5cGVfOworICBjb25zdCBFbnVtT3B0aW9ucyogb3B0aW9uc187CisKKyAgLy8gVHJ1ZSBpZiB0aGlzIGlzIGEgcGxhY2Vob2xkZXIgZm9yIGFuIHVua25vd24gdHlwZS4KKyAgYm9vbCBpc19wbGFjZWhvbGRlcl87CisgIC8vIFRydWUgaWYgdGhpcyBpcyBhIHBsYWNlaG9sZGVyIGFuZCB0aGUgdHlwZSBuYW1lIHdhc24ndCBmdWxseS1xdWFsaWZpZWQuCisgIGJvb2wgaXNfdW5xdWFsaWZpZWRfcGxhY2Vob2xkZXJfOworCisgIGludCB2YWx1ZV9jb3VudF87CisgIEVudW1WYWx1ZURlc2NyaXB0b3IqIHZhbHVlc187CisgIC8vIElNUE9SVEFOVDogIElmIHlvdSBhZGQgYSBuZXcgZmllbGQsIG1ha2Ugc3VyZSB0byBzZWFyY2ggZm9yIGFsbCBpbnN0YW5jZXMKKyAgLy8gb2YgQWxsb2NhdGU8RW51bURlc2NyaXB0b3I+KCkgYW5kIEFsbG9jYXRlQXJyYXk8RW51bURlc2NyaXB0b3I+KCkgaW4KKyAgLy8gZGVzY3JpcHRvci5jYyBhbmQgdXBkYXRlIHRoZW0gdG8gaW5pdGlhbGl6ZSB0aGUgZmllbGQuCisKKyAgLy8gTXVzdCBiZSBjb25zdHJ1Y3RlZCB1c2luZyBEZXNjcmlwdG9yUG9vbC4KKyAgRW51bURlc2NyaXB0b3IoKSB7fQorICBmcmllbmQgY2xhc3MgRGVzY3JpcHRvckJ1aWxkZXI7CisgIGZyaWVuZCBjbGFzcyBEZXNjcmlwdG9yOworICBmcmllbmQgY2xhc3MgRmllbGREZXNjcmlwdG9yOworICBmcmllbmQgY2xhc3MgRW51bVZhbHVlRGVzY3JpcHRvcjsKKyAgZnJpZW5kIGNsYXNzIEZpbGVEZXNjcmlwdG9yOworICBmcmllbmQgY2xhc3MgaW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoRW51bURlc2NyaXB0b3IpOworfTsKKworLy8gRGVzY3JpYmVzIGFuIGluZGl2aWR1YWwgZW51bSBjb25zdGFudCBvZiBhIHBhcnRpY3VsYXIgdHlwZS4gIFRvIGdldCB0aGUKKy8vIEVudW1WYWx1ZURlc2NyaXB0b3IgZm9yIGEgZ2l2ZW4gZW51bSB2YWx1ZSwgZmlyc3QgZ2V0IHRoZSBFbnVtRGVzY3JpcHRvcgorLy8gZm9yIGl0cyB0eXBlLCB0aGVuIHVzZSBFbnVtRGVzY3JpcHRvcjo6RmluZFZhbHVlQnlOYW1lKCkgb3IKKy8vIEVudW1EZXNjcmlwdG9yOjpGaW5kVmFsdWVCeU51bWJlcigpLiAgVXNlIERlc2NyaXB0b3JQb29sIHRvIGNvbnN0cnVjdAorLy8geW91ciBvd24gZGVzY3JpcHRvcnMuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgRW51bVZhbHVlRGVzY3JpcHRvciB7CisgcHVibGljOgorICBjb25zdCBzdHJpbmcmIG5hbWUoKSBjb25zdDsgIC8vIE5hbWUgb2YgdGhpcyBlbnVtIGNvbnN0YW50LgorICBpbnQgaW5kZXgoKSBjb25zdDsgICAgICAgICAgIC8vIEluZGV4IHdpdGhpbiB0aGUgZW51bXMncyBEZXNjcmlwdG9yLgorICBpbnQgbnVtYmVyKCkgY29uc3Q7ICAgICAgICAgIC8vIE51bWVyaWMgdmFsdWUgb2YgdGhpcyBlbnVtIGNvbnN0YW50LgorCisgIC8vIFRoZSBmdWxsX25hbWUgb2YgYW4gZW51bSB2YWx1ZSBpcyBhIHNpYmxpbmcgc3ltYm9sIG9mIHRoZSBlbnVtIHR5cGUuCisgIC8vIGUuZy4gdGhlIGZ1bGwgbmFtZSBvZiBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9JTlQzMiBpcyBhY3R1YWxseQorICAvLyAiZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLlRZUEVfSU5UMzIiLCBOT1QKKyAgLy8gImdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5UeXBlLlRZUEVfSU5UMzIiLiAgVGhpcyBpcyB0byBjb25mb3JtCisgIC8vIHdpdGggQysrIHNjb3BpbmcgcnVsZXMgZm9yIGVudW1zLgorICBjb25zdCBzdHJpbmcmIGZ1bGxfbmFtZSgpIGNvbnN0OworCisgIC8vIFRoZSB0eXBlIG9mIHRoaXMgdmFsdWUuICBOZXZlciBOVUxMLgorICBjb25zdCBFbnVtRGVzY3JpcHRvciogdHlwZSgpIGNvbnN0OworCisgIC8vIEdldCBvcHRpb25zIGZvciB0aGlzIGVudW0gdmFsdWUuICBUaGVzZSBhcmUgc3BlY2lmaWVkIGluIHRoZSAucHJvdG8gZmlsZQorICAvLyBieSBhZGRpbmcgdGV4dCBsaWtlICJbZm9vID0gMTIzNF0iIGFmdGVyIGFuIGVudW0gdmFsdWUgZGVmaW5pdGlvbi4KKyAgLy8gQWxsb3dlZCBvcHRpb25zIGFyZSBkZWZpbmVkIGJ5IEVudW1WYWx1ZU9wdGlvbnMgaW4KKyAgLy8gZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8sIGFuZCBhbnkgYXZhaWxhYmxlIGV4dGVuc2lvbnMgb2YgdGhhdAorICAvLyBtZXNzYWdlLgorICBjb25zdCBFbnVtVmFsdWVPcHRpb25zJiBvcHRpb25zKCkgY29uc3Q7CisKKyAgLy8gU2VlIERlc2NyaXB0b3I6OkNvcHlUbygpLgorICB2b2lkIENvcHlUbyhFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8qIHByb3RvKSBjb25zdDsKKworICAvLyBTZWUgRGVzY3JpcHRvcjo6RGVidWdTdHJpbmcoKS4KKyAgc3RyaW5nIERlYnVnU3RyaW5nKCkgY29uc3Q7CisKKyAgLy8gU2VlIERlc2NyaXB0b3I6OkRlYnVnU3RyaW5nV2l0aE9wdGlvbnMoKS4KKyAgc3RyaW5nIERlYnVnU3RyaW5nV2l0aE9wdGlvbnMoY29uc3QgRGVidWdTdHJpbmdPcHRpb25zJiBvcHRpb25zKSBjb25zdDsKKworCisgIC8vIFNvdXJjZSBMb2NhdGlvbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBVcGRhdGVzIHwqb3V0X2xvY2F0aW9ufCB0byB0aGUgc291cmNlIGxvY2F0aW9uIG9mIHRoZSBjb21wbGV0ZQorICAvLyBleHRlbnQgb2YgdGhpcyBlbnVtIHZhbHVlIGRlY2xhcmF0aW9uLiAgUmV0dXJucyBmYWxzZSBhbmQgbGVhdmVzCisgIC8vIHwqb3V0X2xvY2F0aW9ufCB1bmNoYW5nZWQgaWZmIGxvY2F0aW9uIGluZm9ybWF0aW9uIHdhcyBub3QgYXZhaWxhYmxlLgorICBib29sIEdldFNvdXJjZUxvY2F0aW9uKFNvdXJjZUxvY2F0aW9uKiBvdXRfbG9jYXRpb24pIGNvbnN0OworCisgcHJpdmF0ZToKKyAgdHlwZWRlZiBFbnVtVmFsdWVPcHRpb25zIE9wdGlvbnNUeXBlOworCisgIC8vIFNlZSBEZXNjcmlwdG9yOjpEZWJ1Z1N0cmluZygpLgorICB2b2lkIERlYnVnU3RyaW5nKGludCBkZXB0aCwgc3RyaW5nICpjb250ZW50cywKKyAgICAgICAgICAgICAgICAgICBjb25zdCBEZWJ1Z1N0cmluZ09wdGlvbnMmIG9wdGlvbnMpIGNvbnN0OworCisgIC8vIFdhbGtzIHVwIHRoZSBkZXNjcmlwdG9yIHRyZWUgdG8gZ2VuZXJhdGUgdGhlIHNvdXJjZSBsb2NhdGlvbiBwYXRoCisgIC8vIHRvIHRoaXMgZGVzY3JpcHRvciBmcm9tIHRoZSBmaWxlIHJvb3QuCisgIHZvaWQgR2V0TG9jYXRpb25QYXRoKHN0ZDo6dmVjdG9yPGludD4qIG91dHB1dCkgY29uc3Q7CisKKyAgY29uc3Qgc3RyaW5nKiBuYW1lXzsKKyAgY29uc3Qgc3RyaW5nKiBmdWxsX25hbWVfOworICBpbnQgbnVtYmVyXzsKKyAgY29uc3QgRW51bURlc2NyaXB0b3IqIHR5cGVfOworICBjb25zdCBFbnVtVmFsdWVPcHRpb25zKiBvcHRpb25zXzsKKyAgLy8gSU1QT1JUQU5UOiAgSWYgeW91IGFkZCBhIG5ldyBmaWVsZCwgbWFrZSBzdXJlIHRvIHNlYXJjaCBmb3IgYWxsIGluc3RhbmNlcworICAvLyBvZiBBbGxvY2F0ZTxFbnVtVmFsdWVEZXNjcmlwdG9yPigpIGFuZCBBbGxvY2F0ZUFycmF5PEVudW1WYWx1ZURlc2NyaXB0b3I+KCkKKyAgLy8gaW4gZGVzY3JpcHRvci5jYyBhbmQgdXBkYXRlIHRoZW0gdG8gaW5pdGlhbGl6ZSB0aGUgZmllbGQuCisKKyAgLy8gTXVzdCBiZSBjb25zdHJ1Y3RlZCB1c2luZyBEZXNjcmlwdG9yUG9vbC4KKyAgRW51bVZhbHVlRGVzY3JpcHRvcigpIHt9CisgIGZyaWVuZCBjbGFzcyBEZXNjcmlwdG9yQnVpbGRlcjsKKyAgZnJpZW5kIGNsYXNzIEVudW1EZXNjcmlwdG9yOworICBmcmllbmQgY2xhc3MgRmlsZURlc2NyaXB0b3JUYWJsZXM7CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhFbnVtVmFsdWVEZXNjcmlwdG9yKTsKK307CisKKy8vIERlc2NyaWJlcyBhbiBSUEMgc2VydmljZS4gIFRvIGdldCB0aGUgU2VydmljZURlc2NyaXB0b3IgZm9yIGEgc2VydmljZSwKKy8vIGNhbGwgU2VydmljZTo6R2V0RGVzY3JpcHRvcigpLiAgR2VuZXJhdGVkIHNlcnZpY2UgY2xhc3NlcyBhbHNvIGhhdmUgYQorLy8gc3RhdGljIG1ldGhvZCBjYWxsZWQgZGVzY3JpcHRvcigpIHdoaWNoIHJldHVybnMgdGhlIHR5cGUncworLy8gU2VydmljZURlc2NyaXB0b3IuICBVc2UgRGVzY3JpcHRvclBvb2wgdG8gY29uc3RydWN0IHlvdXIgb3duIGRlc2NyaXB0b3JzLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFNlcnZpY2VEZXNjcmlwdG9yIHsKKyBwdWJsaWM6CisgIC8vIFRoZSBuYW1lIG9mIHRoZSBzZXJ2aWNlLCBub3QgaW5jbHVkaW5nIGl0cyBjb250YWluaW5nIHNjb3BlLgorICBjb25zdCBzdHJpbmcmIG5hbWUoKSBjb25zdDsKKyAgLy8gVGhlIGZ1bGx5LXF1YWxpZmllZCBuYW1lIG9mIHRoZSBzZXJ2aWNlLCBzY29wZSBkZWxpbWl0ZWQgYnkgcGVyaW9kcy4KKyAgY29uc3Qgc3RyaW5nJiBmdWxsX25hbWUoKSBjb25zdDsKKyAgLy8gSW5kZXggb2YgdGhpcyBzZXJ2aWNlIHdpdGhpbiB0aGUgZmlsZSdzIHNlcnZpY2VzIGFycmF5LgorICBpbnQgaW5kZXgoKSBjb25zdDsKKworICAvLyBUaGUgLnByb3RvIGZpbGUgaW4gd2hpY2ggdGhpcyBzZXJ2aWNlIHdhcyBkZWZpbmVkLiAgTmV2ZXIgTlVMTC4KKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUoKSBjb25zdDsKKworICAvLyBHZXQgb3B0aW9ucyBmb3IgdGhpcyBzZXJ2aWNlIHR5cGUuICBUaGVzZSBhcmUgc3BlY2lmaWVkIGluIHRoZSAucHJvdG8gZmlsZQorICAvLyBieSBwbGFjaW5nIGxpbmVzIGxpa2UgIm9wdGlvbiBmb28gPSAxMjM0OyIgaW4gdGhlIHNlcnZpY2UgZGVmaW5pdGlvbi4KKyAgLy8gQWxsb3dlZCBvcHRpb25zIGFyZSBkZWZpbmVkIGJ5IFNlcnZpY2VPcHRpb25zIGluCisgIC8vIGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvLCBhbmQgYW55IGF2YWlsYWJsZSBleHRlbnNpb25zIG9mIHRoYXQKKyAgLy8gbWVzc2FnZS4KKyAgY29uc3QgU2VydmljZU9wdGlvbnMmIG9wdGlvbnMoKSBjb25zdDsKKworICAvLyBUaGUgbnVtYmVyIG9mIG1ldGhvZHMgdGhpcyBzZXJ2aWNlIGRlZmluZXMuCisgIGludCBtZXRob2RfY291bnQoKSBjb25zdDsKKyAgLy8gR2V0cyBhIE1ldGhvZERlc2NyaXB0b3IgYnkgaW5kZXgsIHdoZXJlIDAgPD0gaW5kZXggPCBtZXRob2RfY291bnQoKS4KKyAgLy8gVGhlc2UgYXJlIHJldHVybmVkIGluIHRoZSBvcmRlciB0aGV5IHdlcmUgZGVmaW5lZCBpbiB0aGUgLnByb3RvIGZpbGUuCisgIGNvbnN0IE1ldGhvZERlc2NyaXB0b3IqIG1ldGhvZChpbnQgaW5kZXgpIGNvbnN0OworCisgIC8vIExvb2sgdXAgYSBNZXRob2REZXNjcmlwdG9yIGJ5IG5hbWUuCisgIGNvbnN0IE1ldGhvZERlc2NyaXB0b3IqIEZpbmRNZXRob2RCeU5hbWUoY29uc3Qgc3RyaW5nJiBuYW1lKSBjb25zdDsKKyAgLy8gU2VlIERlc2NyaXB0b3I6OkNvcHlUbygpLgorICB2b2lkIENvcHlUbyhTZXJ2aWNlRGVzY3JpcHRvclByb3RvKiBwcm90bykgY29uc3Q7CisKKyAgLy8gU2VlIERlc2NyaXB0b3I6OkRlYnVnU3RyaW5nKCkuCisgIHN0cmluZyBEZWJ1Z1N0cmluZygpIGNvbnN0OworCisgIC8vIFNlZSBEZXNjcmlwdG9yOjpEZWJ1Z1N0cmluZ1dpdGhPcHRpb25zKCkuCisgIHN0cmluZyBEZWJ1Z1N0cmluZ1dpdGhPcHRpb25zKGNvbnN0IERlYnVnU3RyaW5nT3B0aW9ucyYgb3B0aW9ucykgY29uc3Q7CisKKworICAvLyBTb3VyY2UgTG9jYXRpb24gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gVXBkYXRlcyB8Km91dF9sb2NhdGlvbnwgdG8gdGhlIHNvdXJjZSBsb2NhdGlvbiBvZiB0aGUgY29tcGxldGUKKyAgLy8gZXh0ZW50IG9mIHRoaXMgc2VydmljZSBkZWNsYXJhdGlvbi4gIFJldHVybnMgZmFsc2UgYW5kIGxlYXZlcworICAvLyB8Km91dF9sb2NhdGlvbnwgdW5jaGFuZ2VkIGlmZiBsb2NhdGlvbiBpbmZvcm1hdGlvbiB3YXMgbm90IGF2YWlsYWJsZS4KKyAgYm9vbCBHZXRTb3VyY2VMb2NhdGlvbihTb3VyY2VMb2NhdGlvbiogb3V0X2xvY2F0aW9uKSBjb25zdDsKKworIHByaXZhdGU6CisgIHR5cGVkZWYgU2VydmljZU9wdGlvbnMgT3B0aW9uc1R5cGU7CisKKyAgLy8gU2VlIERlc2NyaXB0b3I6OkRlYnVnU3RyaW5nKCkuCisgIHZvaWQgRGVidWdTdHJpbmcoc3RyaW5nICpjb250ZW50cywgY29uc3QgRGVidWdTdHJpbmdPcHRpb25zJiBvcHRpb25zKSBjb25zdDsKKworICAvLyBXYWxrcyB1cCB0aGUgZGVzY3JpcHRvciB0cmVlIHRvIGdlbmVyYXRlIHRoZSBzb3VyY2UgbG9jYXRpb24gcGF0aAorICAvLyB0byB0aGlzIGRlc2NyaXB0b3IgZnJvbSB0aGUgZmlsZSByb290LgorICB2b2lkIEdldExvY2F0aW9uUGF0aChzdGQ6OnZlY3RvcjxpbnQ+KiBvdXRwdXQpIGNvbnN0OworCisgIGNvbnN0IHN0cmluZyogbmFtZV87CisgIGNvbnN0IHN0cmluZyogZnVsbF9uYW1lXzsKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGVfOworICBjb25zdCBTZXJ2aWNlT3B0aW9ucyogb3B0aW9uc187CisgIGludCBtZXRob2RfY291bnRfOworICBNZXRob2REZXNjcmlwdG9yKiBtZXRob2RzXzsKKyAgLy8gSU1QT1JUQU5UOiAgSWYgeW91IGFkZCBhIG5ldyBmaWVsZCwgbWFrZSBzdXJlIHRvIHNlYXJjaCBmb3IgYWxsIGluc3RhbmNlcworICAvLyBvZiBBbGxvY2F0ZTxTZXJ2aWNlRGVzY3JpcHRvcj4oKSBhbmQgQWxsb2NhdGVBcnJheTxTZXJ2aWNlRGVzY3JpcHRvcj4oKSBpbgorICAvLyBkZXNjcmlwdG9yLmNjIGFuZCB1cGRhdGUgdGhlbSB0byBpbml0aWFsaXplIHRoZSBmaWVsZC4KKworICAvLyBNdXN0IGJlIGNvbnN0cnVjdGVkIHVzaW5nIERlc2NyaXB0b3JQb29sLgorICBTZXJ2aWNlRGVzY3JpcHRvcigpIHt9CisgIGZyaWVuZCBjbGFzcyBEZXNjcmlwdG9yQnVpbGRlcjsKKyAgZnJpZW5kIGNsYXNzIEZpbGVEZXNjcmlwdG9yOworICBmcmllbmQgY2xhc3MgTWV0aG9kRGVzY3JpcHRvcjsKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFNlcnZpY2VEZXNjcmlwdG9yKTsKK307CisKKy8vIERlc2NyaWJlcyBhbiBpbmRpdmlkdWFsIHNlcnZpY2UgbWV0aG9kLiAgVG8gb2J0YWluIGEgTWV0aG9kRGVzY3JpcHRvciBnaXZlbgorLy8gYSBzZXJ2aWNlLCBmaXJzdCBnZXQgaXRzIFNlcnZpY2VEZXNjcmlwdG9yLCB0aGVuIGNhbGwKKy8vIFNlcnZpY2VEZXNjcmlwdG9yOjpGaW5kTWV0aG9kQnlOYW1lKCkuICBVc2UgRGVzY3JpcHRvclBvb2wgdG8gY29uc3RydWN0IHlvdXIKKy8vIG93biBkZXNjcmlwdG9ycy4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBNZXRob2REZXNjcmlwdG9yIHsKKyBwdWJsaWM6CisgIC8vIE5hbWUgb2YgdGhpcyBtZXRob2QsIG5vdCBpbmNsdWRpbmcgY29udGFpbmluZyBzY29wZS4KKyAgY29uc3Qgc3RyaW5nJiBuYW1lKCkgY29uc3Q7CisgIC8vIFRoZSBmdWxseS1xdWFsaWZpZWQgbmFtZSBvZiB0aGUgbWV0aG9kLCBzY29wZSBkZWxpbWl0ZWQgYnkgcGVyaW9kcy4KKyAgY29uc3Qgc3RyaW5nJiBmdWxsX25hbWUoKSBjb25zdDsKKyAgLy8gSW5kZXggd2l0aGluIHRoZSBzZXJ2aWNlJ3MgRGVzY3JpcHRvci4KKyAgaW50IGluZGV4KCkgY29uc3Q7CisKKyAgLy8gR2V0cyB0aGUgc2VydmljZSB0byB3aGljaCB0aGlzIG1ldGhvZCBiZWxvbmdzLiAgTmV2ZXIgTlVMTC4KKyAgY29uc3QgU2VydmljZURlc2NyaXB0b3IqIHNlcnZpY2UoKSBjb25zdDsKKworICAvLyBHZXRzIHRoZSB0eXBlIG9mIHByb3RvY29sIG1lc3NhZ2Ugd2hpY2ggdGhpcyBtZXRob2QgYWNjZXB0cyBhcyBpbnB1dC4KKyAgY29uc3QgRGVzY3JpcHRvciogaW5wdXRfdHlwZSgpIGNvbnN0OworICAvLyBHZXRzIHRoZSB0eXBlIG9mIHByb3RvY29sIG1lc3NhZ2Ugd2hpY2ggdGhpcyBtZXNzYWdlIHByb2R1Y2VzIGFzIG91dHB1dC4KKyAgY29uc3QgRGVzY3JpcHRvciogb3V0cHV0X3R5cGUoKSBjb25zdDsKKworICAvLyBHZXRzIHdoZXRoZXIgdGhlIGNsaWVudCBzdHJlYW1zIG11bHRpcGxlIHJlcXVlc3RzLgorICBib29sIGNsaWVudF9zdHJlYW1pbmcoKSBjb25zdDsKKyAgLy8gR2V0cyB3aGV0aGVyIHRoZSBzZXJ2ZXIgc3RyZWFtcyBtdWx0aXBsZSByZXNwb25zZXMuCisgIGJvb2wgc2VydmVyX3N0cmVhbWluZygpIGNvbnN0OworCisgIC8vIEdldCBvcHRpb25zIGZvciB0aGlzIG1ldGhvZC4gIFRoZXNlIGFyZSBzcGVjaWZpZWQgaW4gdGhlIC5wcm90byBmaWxlIGJ5CisgIC8vIHBsYWNpbmcgbGluZXMgbGlrZSAib3B0aW9uIGZvbyA9IDEyMzQ7IiBpbiBjdXJseS1icmFjZXMgYWZ0ZXIgYSBtZXRob2QKKyAgLy8gZGVjbGFyYXRpb24uICBBbGxvd2VkIG9wdGlvbnMgYXJlIGRlZmluZWQgYnkgTWV0aG9kT3B0aW9ucyBpbgorICAvLyBnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90bywgYW5kIGFueSBhdmFpbGFibGUgZXh0ZW5zaW9ucyBvZiB0aGF0CisgIC8vIG1lc3NhZ2UuCisgIGNvbnN0IE1ldGhvZE9wdGlvbnMmIG9wdGlvbnMoKSBjb25zdDsKKworICAvLyBTZWUgRGVzY3JpcHRvcjo6Q29weVRvKCkuCisgIHZvaWQgQ29weVRvKE1ldGhvZERlc2NyaXB0b3JQcm90byogcHJvdG8pIGNvbnN0OworCisgIC8vIFNlZSBEZXNjcmlwdG9yOjpEZWJ1Z1N0cmluZygpLgorICBzdHJpbmcgRGVidWdTdHJpbmcoKSBjb25zdDsKKworICAvLyBTZWUgRGVzY3JpcHRvcjo6RGVidWdTdHJpbmdXaXRoT3B0aW9ucygpLgorICBzdHJpbmcgRGVidWdTdHJpbmdXaXRoT3B0aW9ucyhjb25zdCBEZWJ1Z1N0cmluZ09wdGlvbnMmIG9wdGlvbnMpIGNvbnN0OworCisKKyAgLy8gU291cmNlIExvY2F0aW9uIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIFVwZGF0ZXMgfCpvdXRfbG9jYXRpb258IHRvIHRoZSBzb3VyY2UgbG9jYXRpb24gb2YgdGhlIGNvbXBsZXRlCisgIC8vIGV4dGVudCBvZiB0aGlzIG1ldGhvZCBkZWNsYXJhdGlvbi4gIFJldHVybnMgZmFsc2UgYW5kIGxlYXZlcworICAvLyB8Km91dF9sb2NhdGlvbnwgdW5jaGFuZ2VkIGlmZiBsb2NhdGlvbiBpbmZvcm1hdGlvbiB3YXMgbm90IGF2YWlsYWJsZS4KKyAgYm9vbCBHZXRTb3VyY2VMb2NhdGlvbihTb3VyY2VMb2NhdGlvbiogb3V0X2xvY2F0aW9uKSBjb25zdDsKKworIHByaXZhdGU6CisgIHR5cGVkZWYgTWV0aG9kT3B0aW9ucyBPcHRpb25zVHlwZTsKKworICAvLyBTZWUgRGVzY3JpcHRvcjo6RGVidWdTdHJpbmcoKS4KKyAgdm9pZCBEZWJ1Z1N0cmluZyhpbnQgZGVwdGgsIHN0cmluZyAqY29udGVudHMsCisgICAgICAgICAgICAgICAgICAgY29uc3QgRGVidWdTdHJpbmdPcHRpb25zJiBvcHRpb25zKSBjb25zdDsKKworICAvLyBXYWxrcyB1cCB0aGUgZGVzY3JpcHRvciB0cmVlIHRvIGdlbmVyYXRlIHRoZSBzb3VyY2UgbG9jYXRpb24gcGF0aAorICAvLyB0byB0aGlzIGRlc2NyaXB0b3IgZnJvbSB0aGUgZmlsZSByb290LgorICB2b2lkIEdldExvY2F0aW9uUGF0aChzdGQ6OnZlY3RvcjxpbnQ+KiBvdXRwdXQpIGNvbnN0OworCisgIGNvbnN0IHN0cmluZyogbmFtZV87CisgIGNvbnN0IHN0cmluZyogZnVsbF9uYW1lXzsKKyAgY29uc3QgU2VydmljZURlc2NyaXB0b3IqIHNlcnZpY2VfOworICBjb25zdCBEZXNjcmlwdG9yKiBpbnB1dF90eXBlXzsKKyAgY29uc3QgRGVzY3JpcHRvciogb3V0cHV0X3R5cGVfOworICBjb25zdCBNZXRob2RPcHRpb25zKiBvcHRpb25zXzsKKyAgYm9vbCBjbGllbnRfc3RyZWFtaW5nXzsKKyAgYm9vbCBzZXJ2ZXJfc3RyZWFtaW5nXzsKKyAgLy8gSU1QT1JUQU5UOiAgSWYgeW91IGFkZCBhIG5ldyBmaWVsZCwgbWFrZSBzdXJlIHRvIHNlYXJjaCBmb3IgYWxsIGluc3RhbmNlcworICAvLyBvZiBBbGxvY2F0ZTxNZXRob2REZXNjcmlwdG9yPigpIGFuZCBBbGxvY2F0ZUFycmF5PE1ldGhvZERlc2NyaXB0b3I+KCkgaW4KKyAgLy8gZGVzY3JpcHRvci5jYyBhbmQgdXBkYXRlIHRoZW0gdG8gaW5pdGlhbGl6ZSB0aGUgZmllbGQuCisKKyAgLy8gTXVzdCBiZSBjb25zdHJ1Y3RlZCB1c2luZyBEZXNjcmlwdG9yUG9vbC4KKyAgTWV0aG9kRGVzY3JpcHRvcigpIHt9CisgIGZyaWVuZCBjbGFzcyBEZXNjcmlwdG9yQnVpbGRlcjsKKyAgZnJpZW5kIGNsYXNzIFNlcnZpY2VEZXNjcmlwdG9yOworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoTWV0aG9kRGVzY3JpcHRvcik7Cit9OworCisKKy8vIERlc2NyaWJlcyBhIHdob2xlIC5wcm90byBmaWxlLiAgVG8gZ2V0IHRoZSBGaWxlRGVzY3JpcHRvciBmb3IgYSBjb21waWxlZC1pbgorLy8gZmlsZSwgZ2V0IHRoZSBkZXNjcmlwdG9yIGZvciBzb21ldGhpbmcgZGVmaW5lZCBpbiB0aGF0IGZpbGUgYW5kIGNhbGwKKy8vIGRlc2NyaXB0b3ItPmZpbGUoKS4gIFVzZSBEZXNjcmlwdG9yUG9vbCB0byBjb25zdHJ1Y3QgeW91ciBvd24gZGVzY3JpcHRvcnMuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgRmlsZURlc2NyaXB0b3IgeworIHB1YmxpYzoKKyAgLy8gVGhlIGZpbGVuYW1lLCByZWxhdGl2ZSB0byB0aGUgc291cmNlIHRyZWUuCisgIC8vIGUuZy4gImdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvIgorICBjb25zdCBzdHJpbmcmIG5hbWUoKSBjb25zdDsKKworICAvLyBUaGUgcGFja2FnZSwgZS5nLiAiZ29vZ2xlLnByb3RvYnVmLmNvbXBpbGVyIi4KKyAgY29uc3Qgc3RyaW5nJiBwYWNrYWdlKCkgY29uc3Q7CisKKyAgLy8gVGhlIERlc2NyaXB0b3JQb29sIGluIHdoaWNoIHRoaXMgRmlsZURlc2NyaXB0b3IgYW5kIGFsbCBpdHMgY29udGVudHMgd2VyZQorICAvLyBhbGxvY2F0ZWQuICBOZXZlciBOVUxMLgorICBjb25zdCBEZXNjcmlwdG9yUG9vbCogcG9vbCgpIGNvbnN0OworCisgIC8vIFRoZSBudW1iZXIgb2YgZmlsZXMgaW1wb3J0ZWQgYnkgdGhpcyBvbmUuCisgIGludCBkZXBlbmRlbmN5X2NvdW50KCkgY29uc3Q7CisgIC8vIEdldHMgYW4gaW1wb3J0ZWQgZmlsZSBieSBpbmRleCwgd2hlcmUgMCA8PSBpbmRleCA8IGRlcGVuZGVuY3lfY291bnQoKS4KKyAgLy8gVGhlc2UgYXJlIHJldHVybmVkIGluIHRoZSBvcmRlciB0aGV5IHdlcmUgZGVmaW5lZCBpbiB0aGUgLnByb3RvIGZpbGUuCisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBkZXBlbmRlbmN5KGludCBpbmRleCkgY29uc3Q7CisKKyAgLy8gVGhlIG51bWJlciBvZiBmaWxlcyBwdWJsaWMgaW1wb3J0ZWQgYnkgdGhpcyBvbmUuCisgIC8vIFRoZSBwdWJsaWMgZGVwZW5kZW5jeSBsaXN0IGlzIGEgc3Vic2V0IG9mIHRoZSBkZXBlbmRlbmN5IGxpc3QuCisgIGludCBwdWJsaWNfZGVwZW5kZW5jeV9jb3VudCgpIGNvbnN0OworICAvLyBHZXRzIGEgcHVibGljIGltcG9ydGVkIGZpbGUgYnkgaW5kZXgsIHdoZXJlIDAgPD0gaW5kZXggPAorICAvLyBwdWJsaWNfZGVwZW5kZW5jeV9jb3VudCgpLgorICAvLyBUaGVzZSBhcmUgcmV0dXJuZWQgaW4gdGhlIG9yZGVyIHRoZXkgd2VyZSBkZWZpbmVkIGluIHRoZSAucHJvdG8gZmlsZS4KKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIHB1YmxpY19kZXBlbmRlbmN5KGludCBpbmRleCkgY29uc3Q7CisKKyAgLy8gVGhlIG51bWJlciBvZiBmaWxlcyB0aGF0IGFyZSBpbXBvcnRlZCBmb3Igd2VhayBmaWVsZHMuCisgIC8vIFRoZSB3ZWFrIGRlcGVuZGVuY3kgbGlzdCBpcyBhIHN1YnNldCBvZiB0aGUgZGVwZW5kZW5jeSBsaXN0LgorICBpbnQgd2Vha19kZXBlbmRlbmN5X2NvdW50KCkgY29uc3Q7CisgIC8vIEdldHMgYSB3ZWFrIGltcG9ydGVkIGZpbGUgYnkgaW5kZXgsIHdoZXJlIDAgPD0gaW5kZXggPAorICAvLyB3ZWFrX2RlcGVuZGVuY3lfY291bnQoKS4KKyAgLy8gVGhlc2UgYXJlIHJldHVybmVkIGluIHRoZSBvcmRlciB0aGV5IHdlcmUgZGVmaW5lZCBpbiB0aGUgLnByb3RvIGZpbGUuCisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiB3ZWFrX2RlcGVuZGVuY3koaW50IGluZGV4KSBjb25zdDsKKworICAvLyBOdW1iZXIgb2YgdG9wLWxldmVsIG1lc3NhZ2UgdHlwZXMgZGVmaW5lZCBpbiB0aGlzIGZpbGUuICAoVGhpcyBkb2VzIG5vdAorICAvLyBpbmNsdWRlIG5lc3RlZCB0eXBlcy4pCisgIGludCBtZXNzYWdlX3R5cGVfY291bnQoKSBjb25zdDsKKyAgLy8gR2V0cyBhIHRvcC1sZXZlbCBtZXNzYWdlIHR5cGUsIHdoZXJlIDAgPD0gaW5kZXggPCBtZXNzYWdlX3R5cGVfY291bnQoKS4KKyAgLy8gVGhlc2UgYXJlIHJldHVybmVkIGluIHRoZSBvcmRlciB0aGV5IHdlcmUgZGVmaW5lZCBpbiB0aGUgLnByb3RvIGZpbGUuCisgIGNvbnN0IERlc2NyaXB0b3IqIG1lc3NhZ2VfdHlwZShpbnQgaW5kZXgpIGNvbnN0OworCisgIC8vIE51bWJlciBvZiB0b3AtbGV2ZWwgZW51bSB0eXBlcyBkZWZpbmVkIGluIHRoaXMgZmlsZS4gIChUaGlzIGRvZXMgbm90CisgIC8vIGluY2x1ZGUgbmVzdGVkIHR5cGVzLikKKyAgaW50IGVudW1fdHlwZV9jb3VudCgpIGNvbnN0OworICAvLyBHZXRzIGEgdG9wLWxldmVsIGVudW0gdHlwZSwgd2hlcmUgMCA8PSBpbmRleCA8IGVudW1fdHlwZV9jb3VudCgpLgorICAvLyBUaGVzZSBhcmUgcmV0dXJuZWQgaW4gdGhlIG9yZGVyIHRoZXkgd2VyZSBkZWZpbmVkIGluIHRoZSAucHJvdG8gZmlsZS4KKyAgY29uc3QgRW51bURlc2NyaXB0b3IqIGVudW1fdHlwZShpbnQgaW5kZXgpIGNvbnN0OworCisgIC8vIE51bWJlciBvZiBzZXJ2aWNlcyBkZWZpbmVkIGluIHRoaXMgZmlsZS4KKyAgaW50IHNlcnZpY2VfY291bnQoKSBjb25zdDsKKyAgLy8gR2V0cyBhIHNlcnZpY2UsIHdoZXJlIDAgPD0gaW5kZXggPCBzZXJ2aWNlX2NvdW50KCkuCisgIC8vIFRoZXNlIGFyZSByZXR1cm5lZCBpbiB0aGUgb3JkZXIgdGhleSB3ZXJlIGRlZmluZWQgaW4gdGhlIC5wcm90byBmaWxlLgorICBjb25zdCBTZXJ2aWNlRGVzY3JpcHRvciogc2VydmljZShpbnQgaW5kZXgpIGNvbnN0OworCisgIC8vIE51bWJlciBvZiBleHRlbnNpb25zIGRlZmluZWQgYXQgZmlsZSBzY29wZS4gIChUaGlzIGRvZXMgbm90IGluY2x1ZGUKKyAgLy8gZXh0ZW5zaW9ucyBuZXN0ZWQgd2l0aGluIG1lc3NhZ2UgdHlwZXMuKQorICBpbnQgZXh0ZW5zaW9uX2NvdW50KCkgY29uc3Q7CisgIC8vIEdldHMgYW4gZXh0ZW5zaW9uJ3MgZGVzY3JpcHRvciwgd2hlcmUgMCA8PSBpbmRleCA8IGV4dGVuc2lvbl9jb3VudCgpLgorICAvLyBUaGVzZSBhcmUgcmV0dXJuZWQgaW4gdGhlIG9yZGVyIHRoZXkgd2VyZSBkZWZpbmVkIGluIHRoZSAucHJvdG8gZmlsZS4KKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBleHRlbnNpb24oaW50IGluZGV4KSBjb25zdDsKKworICAvLyBHZXQgb3B0aW9ucyBmb3IgdGhpcyBmaWxlLiAgVGhlc2UgYXJlIHNwZWNpZmllZCBpbiB0aGUgLnByb3RvIGZpbGUgYnkKKyAgLy8gcGxhY2luZyBsaW5lcyBsaWtlICJvcHRpb24gZm9vID0gMTIzNDsiIGF0IHRoZSB0b3AgbGV2ZWwsIG91dHNpZGUgb2YgYW55CisgIC8vIG90aGVyIGRlZmluaXRpb25zLiAgQWxsb3dlZCBvcHRpb25zIGFyZSBkZWZpbmVkIGJ5IEZpbGVPcHRpb25zIGluCisgIC8vIGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvLCBhbmQgYW55IGF2YWlsYWJsZSBleHRlbnNpb25zIG9mIHRoYXQKKyAgLy8gbWVzc2FnZS4KKyAgY29uc3QgRmlsZU9wdGlvbnMmIG9wdGlvbnMoKSBjb25zdDsKKworICAvLyBTeW50YXggb2YgdGhpcyBmaWxlLgorICBlbnVtIFN5bnRheCB7CisgICAgU1lOVEFYX1VOS05PV04gPSAwLAorICAgIFNZTlRBWF9QUk9UTzIgID0gMiwKKyAgICBTWU5UQVhfUFJPVE8zICA9IDMsCisgIH07CisgIFN5bnRheCBzeW50YXgoKSBjb25zdDsKKyAgc3RhdGljIGNvbnN0IGNoYXIqIFN5bnRheE5hbWUoU3ludGF4IHN5bnRheCk7CisKKyAgLy8gRmluZCBhIHRvcC1sZXZlbCBtZXNzYWdlIHR5cGUgYnkgbmFtZS4gIFJldHVybnMgTlVMTCBpZiBub3QgZm91bmQuCisgIGNvbnN0IERlc2NyaXB0b3IqIEZpbmRNZXNzYWdlVHlwZUJ5TmFtZShjb25zdCBzdHJpbmcmIG5hbWUpIGNvbnN0OworICAvLyBGaW5kIGEgdG9wLWxldmVsIGVudW0gdHlwZSBieSBuYW1lLiAgUmV0dXJucyBOVUxMIGlmIG5vdCBmb3VuZC4KKyAgY29uc3QgRW51bURlc2NyaXB0b3IqIEZpbmRFbnVtVHlwZUJ5TmFtZShjb25zdCBzdHJpbmcmIG5hbWUpIGNvbnN0OworICAvLyBGaW5kIGFuIGVudW0gdmFsdWUgZGVmaW5lZCBpbiBhbnkgdG9wLWxldmVsIGVudW0gYnkgbmFtZS4gIFJldHVybnMgTlVMTCBpZgorICAvLyBub3QgZm91bmQuCisgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIEZpbmRFbnVtVmFsdWVCeU5hbWUoY29uc3Qgc3RyaW5nJiBuYW1lKSBjb25zdDsKKyAgLy8gRmluZCBhIHNlcnZpY2UgZGVmaW5pdGlvbiBieSBuYW1lLiAgUmV0dXJucyBOVUxMIGlmIG5vdCBmb3VuZC4KKyAgY29uc3QgU2VydmljZURlc2NyaXB0b3IqIEZpbmRTZXJ2aWNlQnlOYW1lKGNvbnN0IHN0cmluZyYgbmFtZSkgY29uc3Q7CisgIC8vIEZpbmQgYSB0b3AtbGV2ZWwgZXh0ZW5zaW9uIGRlZmluaXRpb24gYnkgbmFtZS4gIFJldHVybnMgTlVMTCBpZiBub3QgZm91bmQuCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogRmluZEV4dGVuc2lvbkJ5TmFtZShjb25zdCBzdHJpbmcmIG5hbWUpIGNvbnN0OworICAvLyBTaW1pbGFyIHRvIEZpbmRFeHRlbnNpb25CeU5hbWUoKSwgYnV0IHNlYXJjaGVzIGJ5IGxvd2VyY2FzZWQtbmFtZS4gIFNlZQorICAvLyBEZXNjcmlwdG9yOjpGaW5kRmllbGRCeUxvd2VyY2FzZU5hbWUoKS4KKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBGaW5kRXh0ZW5zaW9uQnlMb3dlcmNhc2VOYW1lKGNvbnN0IHN0cmluZyYgbmFtZSkgY29uc3Q7CisgIC8vIFNpbWlsYXIgdG8gRmluZEV4dGVuc2lvbkJ5TmFtZSgpLCBidXQgc2VhcmNoZXMgYnkgY2FtZWxjYXNlZC1uYW1lLiAgU2VlCisgIC8vIERlc2NyaXB0b3I6OkZpbmRGaWVsZEJ5Q2FtZWxjYXNlTmFtZSgpLgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIEZpbmRFeHRlbnNpb25CeUNhbWVsY2FzZU5hbWUoY29uc3Qgc3RyaW5nJiBuYW1lKSBjb25zdDsKKworICAvLyBTZWUgRGVzY3JpcHRvcjo6Q29weVRvKCkuCisgIC8vIE5vdGVzOgorICAvLyAtIFRoaXMgbWV0aG9kIGRvZXMgTk9UIGNvcHkgc291cmNlIGNvZGUgaW5mb3JtYXRpb24gc2luY2UgaXQgaXMgcmVsYXRpdmVseQorICAvLyAgIGxhcmdlIGFuZCByYXJlbHkgbmVlZGVkLiAgU2VlIENvcHlTb3VyY2VDb2RlSW5mb1RvKCkgYmVsb3cuCisgIHZvaWQgQ29weVRvKEZpbGVEZXNjcmlwdG9yUHJvdG8qIHByb3RvKSBjb25zdDsKKyAgLy8gV3JpdGUgdGhlIHNvdXJjZSBjb2RlIGluZm9ybWF0aW9uIG9mIHRoaXMgRmlsZURlc2NyaXB0b3IgaW50byB0aGUgZ2l2ZW4KKyAgLy8gRmlsZURlc2NyaXB0b3JQcm90by4gIFNlZSBDb3B5VG8oKSBhYm92ZS4KKyAgdm9pZCBDb3B5U291cmNlQ29kZUluZm9UbyhGaWxlRGVzY3JpcHRvclByb3RvKiBwcm90bykgY29uc3Q7CisgIC8vIEZpbGwgdGhlIGpzb25fbmFtZSBmaWVsZCBvZiBGaWVsZERlc2NyaXB0b3JQcm90byBmb3IgYWxsIGZpZWxkcy4gQ2FuIG9ubHkKKyAgLy8gYmUgY2FsbGVkIGFmdGVyIENvcHlUbygpLgorICB2b2lkIENvcHlKc29uTmFtZVRvKEZpbGVEZXNjcmlwdG9yUHJvdG8qIHByb3RvKSBjb25zdDsKKworICAvLyBTZWUgRGVzY3JpcHRvcjo6RGVidWdTdHJpbmcoKS4KKyAgc3RyaW5nIERlYnVnU3RyaW5nKCkgY29uc3Q7CisKKyAgLy8gU2VlIERlc2NyaXB0b3I6OkRlYnVnU3RyaW5nV2l0aE9wdGlvbnMoKS4KKyAgc3RyaW5nIERlYnVnU3RyaW5nV2l0aE9wdGlvbnMoY29uc3QgRGVidWdTdHJpbmdPcHRpb25zJiBvcHRpb25zKSBjb25zdDsKKworICAvLyBSZXR1cm5zIHRydWUgaWYgdGhpcyBpcyBhIHBsYWNlaG9sZGVyIGZvciBhbiB1bmtub3duIGZpbGUuIFRoaXMgd2lsbAorICAvLyBvbmx5IGJlIHRoZSBjYXNlIGlmIHRoaXMgZGVzY3JpcHRvciBjb21lcyBmcm9tIGEgRGVzY3JpcHRvclBvb2wKKyAgLy8gd2l0aCBBbGxvd1Vua25vd25EZXBlbmRlbmNpZXMoKSBzZXQuCisgIGJvb2wgaXNfcGxhY2Vob2xkZXIoKSBjb25zdDsKKworICAvLyBVcGRhdGVzIHwqb3V0X2xvY2F0aW9ufCB0byB0aGUgc291cmNlIGxvY2F0aW9uIG9mIHRoZSBjb21wbGV0ZSBleHRlbnQgb2YKKyAgLy8gdGhpcyBmaWxlIGRlY2xhcmF0aW9uIChuYW1lbHksIHRoZSBlbXB0eSBwYXRoKS4KKyAgYm9vbCBHZXRTb3VyY2VMb2NhdGlvbihTb3VyY2VMb2NhdGlvbiogb3V0X2xvY2F0aW9uKSBjb25zdDsKKworICAvLyBVcGRhdGVzIHwqb3V0X2xvY2F0aW9ufCB0byB0aGUgc291cmNlIGxvY2F0aW9uIG9mIHRoZSBjb21wbGV0ZQorICAvLyBleHRlbnQgb2YgdGhlIGRlY2xhcmF0aW9uIG9yIGRlY2xhcmF0aW9uLXBhcnQgZGVub3RlZCBieSB8cGF0aHwuCisgIC8vIFJldHVybnMgZmFsc2UgYW5kIGxlYXZlcyB8Km91dF9sb2NhdGlvbnwgdW5jaGFuZ2VkIGlmZiBsb2NhdGlvbgorICAvLyBpbmZvcm1hdGlvbiB3YXMgbm90IGF2YWlsYWJsZS4gIChTZWUgU291cmNlQ29kZUluZm8gZm9yCisgIC8vIGRlc2NyaXB0aW9uIG9mIHBhdGggZW5jb2RpbmcuKQorICBib29sIEdldFNvdXJjZUxvY2F0aW9uKGNvbnN0IHN0ZDo6dmVjdG9yPGludD4mIHBhdGgsCisgICAgICAgICAgICAgICAgICAgICAgICAgU291cmNlTG9jYXRpb24qIG91dF9sb2NhdGlvbikgY29uc3Q7CisKKyBwcml2YXRlOgorICB0eXBlZGVmIEZpbGVPcHRpb25zIE9wdGlvbnNUeXBlOworCisgIGNvbnN0IHN0cmluZyogbmFtZV87CisgIGNvbnN0IHN0cmluZyogcGFja2FnZV87CisgIGNvbnN0IERlc2NyaXB0b3JQb29sKiBwb29sXzsKKyAgaW50IGRlcGVuZGVuY3lfY291bnRfOworICBjb25zdCBGaWxlRGVzY3JpcHRvcioqIGRlcGVuZGVuY2llc187CisgIGludCBwdWJsaWNfZGVwZW5kZW5jeV9jb3VudF87CisgIGludCogcHVibGljX2RlcGVuZGVuY2llc187CisgIGludCB3ZWFrX2RlcGVuZGVuY3lfY291bnRfOworICBpbnQqIHdlYWtfZGVwZW5kZW5jaWVzXzsKKyAgaW50IG1lc3NhZ2VfdHlwZV9jb3VudF87CisgIERlc2NyaXB0b3IqIG1lc3NhZ2VfdHlwZXNfOworICBpbnQgZW51bV90eXBlX2NvdW50XzsKKyAgRW51bURlc2NyaXB0b3IqIGVudW1fdHlwZXNfOworICBpbnQgc2VydmljZV9jb3VudF87CisgIFNlcnZpY2VEZXNjcmlwdG9yKiBzZXJ2aWNlc187CisgIGludCBleHRlbnNpb25fY291bnRfOworICBTeW50YXggc3ludGF4XzsKKyAgYm9vbCBpc19wbGFjZWhvbGRlcl87CisgIEZpZWxkRGVzY3JpcHRvciogZXh0ZW5zaW9uc187CisgIGNvbnN0IEZpbGVPcHRpb25zKiBvcHRpb25zXzsKKworICBjb25zdCBGaWxlRGVzY3JpcHRvclRhYmxlcyogdGFibGVzXzsKKyAgY29uc3QgU291cmNlQ29kZUluZm8qIHNvdXJjZV9jb2RlX2luZm9fOworICAvLyBJTVBPUlRBTlQ6ICBJZiB5b3UgYWRkIGEgbmV3IGZpZWxkLCBtYWtlIHN1cmUgdG8gc2VhcmNoIGZvciBhbGwgaW5zdGFuY2VzCisgIC8vIG9mIEFsbG9jYXRlPEZpbGVEZXNjcmlwdG9yPigpIGFuZCBBbGxvY2F0ZUFycmF5PEZpbGVEZXNjcmlwdG9yPigpIGluCisgIC8vIGRlc2NyaXB0b3IuY2MgYW5kIHVwZGF0ZSB0aGVtIHRvIGluaXRpYWxpemUgdGhlIGZpZWxkLgorCisgIEZpbGVEZXNjcmlwdG9yKCkge30KKyAgZnJpZW5kIGNsYXNzIERlc2NyaXB0b3JCdWlsZGVyOworICBmcmllbmQgY2xhc3MgRGVzY3JpcHRvcjsKKyAgZnJpZW5kIGNsYXNzIEZpZWxkRGVzY3JpcHRvcjsKKyAgZnJpZW5kIGNsYXNzIE9uZW9mRGVzY3JpcHRvcjsKKyAgZnJpZW5kIGNsYXNzIEVudW1EZXNjcmlwdG9yOworICBmcmllbmQgY2xhc3MgRW51bVZhbHVlRGVzY3JpcHRvcjsKKyAgZnJpZW5kIGNsYXNzIE1ldGhvZERlc2NyaXB0b3I7CisgIGZyaWVuZCBjbGFzcyBTZXJ2aWNlRGVzY3JpcHRvcjsKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEZpbGVEZXNjcmlwdG9yKTsKK307CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworLy8gVXNlZCB0byBjb25zdHJ1Y3QgZGVzY3JpcHRvcnMuCisvLworLy8gTm9ybWFsbHkgeW91IHdvbid0IHdhbnQgdG8gYnVpbGQgeW91ciBvd24gZGVzY3JpcHRvcnMuICBNZXNzYWdlIGNsYXNzZXMKKy8vIGNvbnN0cnVjdGVkIGJ5IHRoZSBwcm90b2NvbCBjb21waWxlciB3aWxsIHByb3ZpZGUgdGhlbSBmb3IgeW91LiAgSG93ZXZlciwKKy8vIGlmIHlvdSBhcmUgaW1wbGVtZW50aW5nIE1lc3NhZ2Ugb24geW91ciBvd24sIG9yIGlmIHlvdSBhcmUgd3JpdGluZyBhCisvLyBwcm9ncmFtIHdoaWNoIGNhbiBvcGVyYXRlIG9uIHRvdGFsbHkgYXJiaXRyYXJ5IHR5cGVzIGFuZCBuZWVkcyB0byBsb2FkCisvLyB0aGVtIGZyb20gc29tZSBzb3J0IG9mIGRhdGFiYXNlLCB5b3UgbWlnaHQgbmVlZCB0by4KKy8vCisvLyBTaW5jZSBEZXNjcmlwdG9ycyBhcmUgY29tcG9zZWQgb2YgYSB3aG9sZSBsb3Qgb2YgY3Jvc3MtbGlua2VkIGJpdHMgb2YKKy8vIGRhdGEgdGhhdCB3b3VsZCBiZSBhIHBhaW4gdG8gcHV0IHRvZ2V0aGVyIG1hbnVhbGx5LCB0aGUKKy8vIERlc2NyaXB0b3JQb29sIGNsYXNzIGlzIHByb3ZpZGVkIHRvIG1ha2UgdGhlIHByb2Nlc3MgZWFzaWVyLiAgSXQgY2FuCisvLyB0YWtlIGEgRmlsZURlc2NyaXB0b3JQcm90byAoZGVmaW5lZCBpbiBkZXNjcmlwdG9yLnByb3RvKSwgdmFsaWRhdGUgaXQsCisvLyBhbmQgY29udmVydCBpdCB0byBhIHNldCBvZiBuaWNlbHkgY3Jvc3MtbGlua2VkIERlc2NyaXB0b3JzLgorLy8KKy8vIERlc2NyaXB0b3JQb29sIGFsc28gaGVscHMgd2l0aCBtZW1vcnkgbWFuYWdlbWVudC4gIERlc2NyaXB0b3JzIGFyZQorLy8gY29tcG9zZWQgb2YgbWFueSBvYmplY3RzIGNvbnRhaW5pbmcgc3RhdGljIGRhdGEgYW5kIHBvaW50ZXJzIHRvIGVhY2gKKy8vIG90aGVyLiAgSW4gYWxsIGxpa2VsaWhvb2QsIHdoZW4gaXQgY29tZXMgdGltZSB0byBkZWxldGUgdGhpcyBkYXRhLAorLy8geW91J2xsIHdhbnQgdG8gZGVsZXRlIGl0IGFsbCBhdCBvbmNlLiAgSW4gZmFjdCwgaXQgaXMgbm90IHVuY29tbW9uIHRvCisvLyBoYXZlIGEgd2hvbGUgcG9vbCBvZiBkZXNjcmlwdG9ycyBhbGwgY3Jvc3MtbGlua2VkIHdpdGggZWFjaCBvdGhlciB3aGljaAorLy8geW91IHdpc2ggdG8gZGVsZXRlIGFsbCBhdCBvbmNlLiAgVGhpcyBjbGFzcyByZXByZXNlbnRzIHN1Y2ggYSBwb29sLCBhbmQKKy8vIGhhbmRsZXMgdGhlIG1lbW9yeSBtYW5hZ2VtZW50IGZvciB5b3UuCisvLworLy8gWW91IGNhbiBhbHNvIHNlYXJjaCBmb3IgZGVzY3JpcHRvcnMgd2l0aGluIGEgRGVzY3JpcHRvclBvb2wgYnkgbmFtZSwgYW5kCisvLyBleHRlbnNpb25zIGJ5IG51bWJlci4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBEZXNjcmlwdG9yUG9vbCB7CisgcHVibGljOgorICAvLyBDcmVhdGUgYSBub3JtYWwsIGVtcHR5IERlc2NyaXB0b3JQb29sLgorICBEZXNjcmlwdG9yUG9vbCgpOworCisgIC8vIENvbnN0cnVjdHMgYSBEZXNjcmlwdG9yUG9vbCB0aGF0LCB3aGVuIGl0IGNhbid0IGZpbmQgc29tZXRoaW5nIGFtb25nIHRoZQorICAvLyBkZXNjcmlwdG9ycyBhbHJlYWR5IGluIHRoZSBwb29sLCBsb29rcyBmb3IgaXQgaW4gdGhlIGdpdmVuCisgIC8vIERlc2NyaXB0b3JEYXRhYmFzZS4KKyAgLy8gTm90ZXM6CisgIC8vIC0gSWYgYSBEZXNjcmlwdG9yUG9vbCBpcyBjb25zdHJ1Y3RlZCB0aGlzIHdheSwgaXRzIEJ1aWxkRmlsZSooKSBtZXRob2RzCisgIC8vICAgbXVzdCBub3QgYmUgY2FsbGVkICh0aGV5IHdpbGwgYXNzZXJ0LWZhaWwpLiAgVGhlIG9ubHkgd2F5IHRvIHBvcHVsYXRlCisgIC8vICAgdGhlIHBvb2wgd2l0aCBkZXNjcmlwdG9ycyBpcyB0byBjYWxsIHRoZSBGaW5kKkJ5KigpIG1ldGhvZHMuCisgIC8vIC0gVGhlIEZpbmQqQnkqKCkgbWV0aG9kcyBtYXkgYmxvY2sgdGhlIGNhbGxpbmcgdGhyZWFkIGlmIHRoZQorICAvLyAgIERlc2NyaXB0b3JEYXRhYmFzZSBibG9ja3MuICBUaGlzIGluIHR1cm4gbWVhbnMgdGhhdCBwYXJzaW5nIG1lc3NhZ2VzCisgIC8vICAgbWF5IGJsb2NrIGlmIHRoZXkgbmVlZCB0byBsb29rIHVwIGV4dGVuc2lvbnMuCisgIC8vIC0gVGhlIEZpbmQqQnkqKCkgbWV0aG9kcyB3aWxsIHVzZSBtdXRleGVzIGZvciB0aHJlYWQtc2FmZXR5LCB0aHVzIG1ha2luZworICAvLyAgIHRoZW0gc2xvd2VyIGV2ZW4gd2hlbiB0aGV5IGRvbid0IGhhdmUgdG8gZmFsbCBiYWNrIHRvIHRoZSBkYXRhYmFzZS4KKyAgLy8gICBJbiBmYWN0LCBldmVuIHRoZSBGaW5kKkJ5KigpIG1ldGhvZHMgb2YgZGVzY3JpcHRvciBvYmplY3RzIG93bmVkIGJ5CisgIC8vICAgdGhpcyBwb29sIHdpbGwgYmUgc2xvd2VyLCBzaW5jZSB0aGV5IHdpbGwgaGF2ZSB0byBvYnRhaW4gbG9ja3MgdG9vLgorICAvLyAtIEFuIEVycm9yQ29sbGVjdG9yIG1heSBvcHRpb25hbGx5IGJlIGdpdmVuIHRvIGNvbGxlY3QgdmFsaWRhdGlvbiBlcnJvcnMKKyAgLy8gICBpbiBmaWxlcyBsb2FkZWQgZnJvbSB0aGUgZGF0YWJhc2UuICBJZiBub3QgZ2l2ZW4sIGVycm9ycyB3aWxsIGJlIHByaW50ZWQKKyAgLy8gICB0byBHT09HTEVfTE9HKEVSUk9SKS4gIFJlbWVtYmVyIHRoYXQgZmlsZXMgYXJlIGJ1aWx0IG9uLWRlbWFuZCwgc28gdGhpcworICAvLyAgIEVycm9yQ29sbGVjdG9yIG1heSBiZSBjYWxsZWQgZnJvbSBhbnkgdGhyZWFkIHRoYXQgY2FsbHMgb25lIG9mIHRoZQorICAvLyAgIEZpbmQqQnkqKCkgbWV0aG9kcy4KKyAgLy8gLSBUaGUgRGVzY3JpcHRvckRhdGFiYXNlIG11c3Qgbm90IGJlIG11dGF0ZWQgZHVyaW5nIHRoZSBsaWZldGltZSBvZgorICAvLyAgIHRoZSBEZXNjcmlwdG9yUG9vbC4gRXZlbiBpZiB0aGUgY2xpZW50IHRha2VzIGNhcmUgdG8gYXZvaWQgZGF0YSByYWNlcywKKyAgLy8gICBjaGFuZ2VzIHRvIHRoZSBjb250ZW50IG9mIHRoZSBEZXNjcmlwdG9yRGF0YWJhc2UgbWF5IG5vdCBiZSByZWZsZWN0ZWQKKyAgLy8gICBpbiBzdWJzZXF1ZW50IGxvb2t1cHMgaW4gdGhlIERlc2NyaXB0b3JQb29sLgorICBjbGFzcyBFcnJvckNvbGxlY3RvcjsKKyAgZXhwbGljaXQgRGVzY3JpcHRvclBvb2woRGVzY3JpcHRvckRhdGFiYXNlKiBmYWxsYmFja19kYXRhYmFzZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgRXJyb3JDb2xsZWN0b3IqIGVycm9yX2NvbGxlY3RvciA9IE5VTEwpOworCisgIH5EZXNjcmlwdG9yUG9vbCgpOworCisgIC8vIEdldCBhIHBvaW50ZXIgdG8gdGhlIGdlbmVyYXRlZCBwb29sLiAgR2VuZXJhdGVkIHByb3RvY29sIG1lc3NhZ2UgY2xhc3NlcworICAvLyB3aGljaCBhcmUgY29tcGlsZWQgaW50byB0aGUgYmluYXJ5IHdpbGwgYWxsb2NhdGUgdGhlaXIgZGVzY3JpcHRvcnMgaW4KKyAgLy8gdGhpcyBwb29sLiAgRG8gbm90IGFkZCB5b3VyIG93biBkZXNjcmlwdG9ycyB0byB0aGlzIHBvb2wuCisgIHN0YXRpYyBjb25zdCBEZXNjcmlwdG9yUG9vbCogZ2VuZXJhdGVkX3Bvb2woKTsKKworCisgIC8vIEZpbmQgYSBGaWxlRGVzY3JpcHRvciBpbiB0aGUgcG9vbCBieSBmaWxlIG5hbWUuICBSZXR1cm5zIE5VTEwgaWYgbm90CisgIC8vIGZvdW5kLgorICBjb25zdCBGaWxlRGVzY3JpcHRvciogRmluZEZpbGVCeU5hbWUoY29uc3Qgc3RyaW5nJiBuYW1lKSBjb25zdDsKKworICAvLyBGaW5kIHRoZSBGaWxlRGVzY3JpcHRvciBpbiB0aGUgcG9vbCB3aGljaCBkZWZpbmVzIHRoZSBnaXZlbiBzeW1ib2wuCisgIC8vIElmIGFueSBvZiB0aGUgRmluZCpCeU5hbWUoKSBtZXRob2RzIGJlbG93IHdvdWxkIHN1Y2NlZWQsIHRoZW4gdGhpcyBpcworICAvLyBlcXVpdmFsZW50IHRvIGNhbGxpbmcgdGhhdCBtZXRob2QgYW5kIGNhbGxpbmcgdGhlIHJlc3VsdCdzIGZpbGUoKSBtZXRob2QuCisgIC8vIE90aGVyd2lzZSB0aGlzIHJldHVybnMgTlVMTC4KKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIEZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbCgKKyAgICAgIGNvbnN0IHN0cmluZyYgc3ltYm9sX25hbWUpIGNvbnN0OworCisgIC8vIExvb2tpbmcgdXAgZGVzY3JpcHRvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8vIFRoZXNlIGZpbmQgZGVzY3JpcHRvcnMgYnkgZnVsbHktcXVhbGlmaWVkIG5hbWUuICBUaGVzZSB3aWxsIGZpbmQgYm90aAorICAvLyB0b3AtbGV2ZWwgZGVzY3JpcHRvcnMgYW5kIG5lc3RlZCBkZXNjcmlwdG9ycy4gIFRoZXkgcmV0dXJuIE5VTEwgaWYgbm90CisgIC8vIGZvdW5kLgorCisgIGNvbnN0IERlc2NyaXB0b3IqIEZpbmRNZXNzYWdlVHlwZUJ5TmFtZShjb25zdCBzdHJpbmcmIG5hbWUpIGNvbnN0OworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIEZpbmRGaWVsZEJ5TmFtZShjb25zdCBzdHJpbmcmIG5hbWUpIGNvbnN0OworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIEZpbmRFeHRlbnNpb25CeU5hbWUoY29uc3Qgc3RyaW5nJiBuYW1lKSBjb25zdDsKKyAgY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBGaW5kT25lb2ZCeU5hbWUoY29uc3Qgc3RyaW5nJiBuYW1lKSBjb25zdDsKKyAgY29uc3QgRW51bURlc2NyaXB0b3IqIEZpbmRFbnVtVHlwZUJ5TmFtZShjb25zdCBzdHJpbmcmIG5hbWUpIGNvbnN0OworICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBGaW5kRW51bVZhbHVlQnlOYW1lKGNvbnN0IHN0cmluZyYgbmFtZSkgY29uc3Q7CisgIGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yKiBGaW5kU2VydmljZUJ5TmFtZShjb25zdCBzdHJpbmcmIG5hbWUpIGNvbnN0OworICBjb25zdCBNZXRob2REZXNjcmlwdG9yKiBGaW5kTWV0aG9kQnlOYW1lKGNvbnN0IHN0cmluZyYgbmFtZSkgY29uc3Q7CisKKyAgLy8gRmluZHMgYW4gZXh0ZW5zaW9uIG9mIHRoZSBnaXZlbiB0eXBlIGJ5IG51bWJlci4gIFRoZSBleHRlbmRlZSBtdXN0IGJlCisgIC8vIGEgbWVtYmVyIG9mIHRoaXMgRGVzY3JpcHRvclBvb2wgb3Igb25lIG9mIGl0cyB1bmRlcmxheXMuCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogRmluZEV4dGVuc2lvbkJ5TnVtYmVyKGNvbnN0IERlc2NyaXB0b3IqIGV4dGVuZGVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbnVtYmVyKSBjb25zdDsKKworICAvLyBGaW5kcyBleHRlbnNpb25zIG9mIGV4dGVuZGVlLiBUaGUgZXh0ZW5zaW9ucyB3aWxsIGJlIGFwcGVuZGVkIHRvCisgIC8vIG91dCBpbiBhbiB1bmRlZmluZWQgb3JkZXIuIE9ubHkgZXh0ZW5zaW9ucyBkZWZpbmVkIGRpcmVjdGx5IGluCisgIC8vIHRoaXMgRGVzY3JpcHRvclBvb2wgb3Igb25lIG9mIGl0cyB1bmRlcmxheXMgYXJlIGd1YXJhbnRlZWQgdG8gYmUKKyAgLy8gZm91bmQ6IGV4dGVuc2lvbnMgZGVmaW5lZCBpbiB0aGUgZmFsbGJhY2sgZGF0YWJhc2UgbWlnaHQgbm90IGJlIGZvdW5kCisgIC8vIGRlcGVuZGluZyBvbiB0aGUgZGF0YWJhc2UgaW1wbGVtZW50YXRpb24uCisgIHZvaWQgRmluZEFsbEV4dGVuc2lvbnMoY29uc3QgRGVzY3JpcHRvciogZXh0ZW5kZWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjp2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4qIG91dCkgY29uc3Q7CisKKyAgLy8gQnVpbGRpbmcgZGVzY3JpcHRvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBXaGVuIGNvbnZlcnRpbmcgYSBGaWxlRGVzY3JpcHRvclByb3RvIHRvIGEgRmlsZURlc2NyaXB0b3IsIHZhcmlvdXMKKyAgLy8gZXJyb3JzIG1pZ2h0IGJlIGRldGVjdGVkIGluIHRoZSBpbnB1dC4gIFRoZSBjYWxsZXIgbWF5IGhhbmRsZSB0aGVzZQorICAvLyBwcm9ncmFtbWF0aWNhbGx5IGJ5IGltcGxlbWVudGluZyBhbiBFcnJvckNvbGxlY3Rvci4KKyAgY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEVycm9yQ29sbGVjdG9yIHsKKyAgIHB1YmxpYzoKKyAgICBpbmxpbmUgRXJyb3JDb2xsZWN0b3IoKSB7fQorICAgIHZpcnR1YWwgfkVycm9yQ29sbGVjdG9yKCk7CisKKyAgICAvLyBUaGVzZSBjb25zdGFudHMgc3BlY2lmeSB3aGF0IGV4YWN0IHBhcnQgb2YgdGhlIGNvbnN0cnVjdCBpcyBicm9rZW4uCisgICAgLy8gVGhpcyBpcyB1c2VmdWwgZS5nLiBmb3IgbWFwcGluZyB0aGUgZXJyb3IgYmFjayB0byBhbiBleGFjdCBsb2NhdGlvbgorICAgIC8vIGluIGEgLnByb3RvIGZpbGUuCisgICAgZW51bSBFcnJvckxvY2F0aW9uIHsKKyAgICAgIE5BTUUsICAgICAgICAgICAgICAvLyB0aGUgc3ltYm9sIG5hbWUsIG9yIHRoZSBwYWNrYWdlIG5hbWUgZm9yIGZpbGVzCisgICAgICBOVU1CRVIsICAgICAgICAgICAgLy8gZmllbGQgb3IgZXh0ZW5zaW9uIHJhbmdlIG51bWJlcgorICAgICAgVFlQRSwgICAgICAgICAgICAgIC8vIGZpZWxkIHR5cGUKKyAgICAgIEVYVEVOREVFLCAgICAgICAgICAvLyBmaWVsZCBleHRlbmRlZQorICAgICAgREVGQVVMVF9WQUxVRSwgICAgIC8vIGZpZWxkIGRlZmF1bHQgdmFsdWUKKyAgICAgIElOUFVUX1RZUEUsICAgICAgICAvLyBtZXRob2QgaW5wdXQgdHlwZQorICAgICAgT1VUUFVUX1RZUEUsICAgICAgIC8vIG1ldGhvZCBvdXRwdXQgdHlwZQorICAgICAgT1BUSU9OX05BTUUsICAgICAgIC8vIG5hbWUgaW4gYXNzaWdubWVudAorICAgICAgT1BUSU9OX1ZBTFVFLCAgICAgIC8vIHZhbHVlIGluIG9wdGlvbiBhc3NpZ25tZW50CisgICAgICBPVEhFUiAgICAgICAgICAgICAgLy8gc29tZSBvdGhlciBwcm9ibGVtCisgICAgfTsKKworICAgIC8vIFJlcG9ydHMgYW4gZXJyb3IgaW4gdGhlIEZpbGVEZXNjcmlwdG9yUHJvdG8uIFVzZSB0aGlzIGZ1bmN0aW9uIGlmIHRoZQorICAgIC8vIHByb2JsZW0gb2NjdXJyZWQgc2hvdWxkIGludGVycnVwdCBidWlsZGluZyB0aGUgRmlsZURlc2NyaXB0b3JQcm90by4KKyAgICB2aXJ0dWFsIHZvaWQgQWRkRXJyb3IoCisgICAgICBjb25zdCBzdHJpbmcmIGZpbGVuYW1lLCAgICAgIC8vIEZpbGUgbmFtZSBpbiB3aGljaCB0aGUgZXJyb3Igb2NjdXJyZWQuCisgICAgICBjb25zdCBzdHJpbmcmIGVsZW1lbnRfbmFtZSwgIC8vIEZ1bGwgbmFtZSBvZiB0aGUgZXJyb25lb3VzIGVsZW1lbnQuCisgICAgICBjb25zdCBNZXNzYWdlKiBkZXNjcmlwdG9yLCAgIC8vIERlc2NyaXB0b3Igb2YgdGhlIGVycm9uZW91cyBlbGVtZW50LgorICAgICAgRXJyb3JMb2NhdGlvbiBsb2NhdGlvbiwgICAgICAvLyBPbmUgb2YgdGhlIGxvY2F0aW9uIGNvbnN0YW50cywgYWJvdmUuCisgICAgICBjb25zdCBzdHJpbmcmIG1lc3NhZ2UgICAgICAgIC8vIEh1bWFuLXJlYWRhYmxlIGVycm9yIG1lc3NhZ2UuCisgICAgICApID0gMDsKKworICAgIC8vIFJlcG9ydHMgYSB3YXJuaW5nIGluIHRoZSBGaWxlRGVzY3JpcHRvclByb3RvLiBVc2UgdGhpcyBmdW5jdGlvbiBpZiB0aGUKKyAgICAvLyBwcm9ibGVtIG9jY3VycmVkIHNob3VsZCBOT1QgaW50ZXJydXB0IGJ1aWxkaW5nIHRoZSBGaWxlRGVzY3JpcHRvclByb3RvLgorICAgIHZpcnR1YWwgdm9pZCBBZGRXYXJuaW5nKAorICAgICAgY29uc3Qgc3RyaW5nJiAvKmZpbGVuYW1lKi8sICAgICAgLy8gRmlsZSBuYW1lIGluIHdoaWNoIHRoZSBlcnJvciBvY2N1cnJlZC4KKyAgICAgIGNvbnN0IHN0cmluZyYgLyplbGVtZW50X25hbWUqLywgIC8vIEZ1bGwgbmFtZSBvZiB0aGUgZXJyb25lb3VzIGVsZW1lbnQuCisgICAgICBjb25zdCBNZXNzYWdlKiAvKmRlc2NyaXB0b3IqLywgICAvLyBEZXNjcmlwdG9yIG9mIHRoZSBlcnJvbmVvdXMgZWxlbWVudC4KKyAgICAgIEVycm9yTG9jYXRpb24gLypsb2NhdGlvbiovLCAgICAgIC8vIE9uZSBvZiB0aGUgbG9jYXRpb24gY29uc3RhbnRzLCBhYm92ZS4KKyAgICAgIGNvbnN0IHN0cmluZyYgLyptZXNzYWdlKi8gICAgICAgIC8vIEh1bWFuLXJlYWRhYmxlIGVycm9yIG1lc3NhZ2UuCisgICAgICApIHt9CisKKyAgIHByaXZhdGU6CisgICAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEVycm9yQ29sbGVjdG9yKTsKKyAgfTsKKworICAvLyBDb252ZXJ0IHRoZSBGaWxlRGVzY3JpcHRvclByb3RvIHRvIHJlYWwgZGVzY3JpcHRvcnMgYW5kIHBsYWNlIHRoZW0gaW4KKyAgLy8gdGhpcyBEZXNjcmlwdG9yUG9vbC4gIEFsbCBkZXBlbmRlbmNpZXMgb2YgdGhlIGZpbGUgbXVzdCBhbHJlYWR5IGJlIGluCisgIC8vIHRoZSBwb29sLiAgUmV0dXJucyB0aGUgcmVzdWx0aW5nIEZpbGVEZXNjcmlwdG9yLCBvciBOVUxMIGlmIHRoZXJlIHdlcmUKKyAgLy8gcHJvYmxlbXMgd2l0aCB0aGUgaW5wdXQgKGUuZy4gdGhlIG1lc3NhZ2Ugd2FzIGludmFsaWQsIG9yIGRlcGVuZGVuY2llcworICAvLyB3ZXJlIG1pc3NpbmcpLiAgRGV0YWlscyBhYm91dCB0aGUgZXJyb3JzIGFyZSB3cml0dGVuIHRvIEdPT0dMRV9MT0coRVJST1IpLgorICBjb25zdCBGaWxlRGVzY3JpcHRvciogQnVpbGRGaWxlKGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8mIHByb3RvKTsKKworICAvLyBTYW1lIGFzIEJ1aWxkRmlsZSgpIGV4Y2VwdCBlcnJvcnMgYXJlIHNlbnQgdG8gdGhlIGdpdmVuIEVycm9yQ29sbGVjdG9yLgorICBjb25zdCBGaWxlRGVzY3JpcHRvciogQnVpbGRGaWxlQ29sbGVjdGluZ0Vycm9ycygKKyAgICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvJiBwcm90bywKKyAgICBFcnJvckNvbGxlY3RvciogZXJyb3JfY29sbGVjdG9yKTsKKworICAvLyBCeSBkZWZhdWx0LCBpdCBpcyBhbiBlcnJvciBpZiBhIEZpbGVEZXNjcmlwdG9yUHJvdG8gY29udGFpbnMgcmVmZXJlbmNlcworICAvLyB0byB0eXBlcyBvciBvdGhlciBmaWxlcyB0aGF0IGFyZSBub3QgZm91bmQgaW4gdGhlIERlc2NyaXB0b3JQb29sIChvciBpdHMKKyAgLy8gYmFja2luZyBEZXNjcmlwdG9yRGF0YWJhc2UsIGlmIGFueSkuICBJZiB5b3UgY2FsbAorICAvLyBBbGxvd1Vua25vd25EZXBlbmRlbmNpZXMoKSwgaG93ZXZlciwgdGhlbiB1bmtub3duIHR5cGVzIGFuZCBmaWxlcworICAvLyB3aWxsIGJlIHJlcGxhY2VkIGJ5IHBsYWNlaG9sZGVyIGRlc2NyaXB0b3JzICh3aGljaCBjYW4gYmUgaWRlbnRpZmllZCBieQorICAvLyB0aGUgaXNfcGxhY2Vob2xkZXIoKSBtZXRob2QpLiAgVGhpcyBjYW4gYWxsb3cgeW91IHRvCisgIC8vIHBlcmZvcm0gc29tZSB1c2VmdWwgb3BlcmF0aW9ucyB3aXRoIGEgLnByb3RvIGZpbGUgZXZlbiBpZiB5b3UgZG8gbm90CisgIC8vIGhhdmUgYWNjZXNzIHRvIG90aGVyIC5wcm90byBmaWxlcyBvbiB3aGljaCBpdCBkZXBlbmRzLiAgSG93ZXZlciwgc29tZQorICAvLyBoZXVyaXN0aWNzIG11c3QgYmUgdXNlZCB0byBmaWxsIGluIHRoZSBnYXBzIGluIGluZm9ybWF0aW9uLCBhbmQgdGhlc2UKKyAgLy8gY2FuIGxlYWQgdG8gZGVzY3JpcHRvcnMgd2hpY2ggYXJlIGluYWNjdXJhdGUuICBGb3IgZXhhbXBsZSwgdGhlCisgIC8vIERlc2NyaXB0b3JQb29sIG1heSBiZSBmb3JjZWQgdG8gZ3Vlc3Mgd2hldGhlciBhbiB1bmtub3duIHR5cGUgaXMgYSBtZXNzYWdlCisgIC8vIG9yIGFuIGVudW0sIGFzIHdlbGwgYXMgd2hhdCBwYWNrYWdlIGl0IHJlc2lkZXMgaW4uICBGdXJ0aGVybW9yZSwKKyAgLy8gcGxhY2Vob2xkZXIgdHlwZXMgd2lsbCBub3QgYmUgZGlzY292ZXJhYmxlIHZpYSBGaW5kTWVzc2FnZVR5cGVCeU5hbWUoKQorICAvLyBhbmQgc2ltaWxhciBtZXRob2RzLCB3aGljaCBjb3VsZCBjb25mdXNlIHNvbWUgZGVzY3JpcHRvci1iYXNlZCBhbGdvcml0aG1zLgorICAvLyBHZW5lcmFsbHksIHRoZSByZXN1bHRzIG9mIHRoaXMgb3B0aW9uIHNob3VsZCBiZSBoYW5kbGVkIHdpdGggZXh0cmVtZSBjYXJlLgorICB2b2lkIEFsbG93VW5rbm93bkRlcGVuZGVuY2llcygpIHsgYWxsb3dfdW5rbm93bl8gPSB0cnVlOyB9CisKKyAgLy8gQnkgZGVmYXVsdCwgd2VhayBpbXBvcnRzIGFyZSBhbGxvd2VkIHRvIGJlIG1pc3NpbmcsIGluIHdoaWNoIGNhc2Ugd2Ugd2lsbAorICAvLyB1c2UgYSBwbGFjZWhvbGRlciBmb3IgdGhlIGRlcGVuZGVuY3kgYW5kIGNvbnZlcnQgdGhlIGZpZWxkIHRvIGJlIGFuIEVtcHR5CisgIC8vIG1lc3NhZ2UgZmllbGQuIElmIHlvdSBjYWxsIEVuZm9yY2VXZWFrRGVwZW5kZW5jaWVzKHRydWUpLCBob3dldmVyLCB0aGUKKyAgLy8gRGVzY3JpcHRvclBvb2wgd2lsbCByZXBvcnQgYSBpbXBvcnQgbm90IGZvdW5kIGVycm9yLgorICB2b2lkIEVuZm9yY2VXZWFrRGVwZW5kZW5jaWVzKGJvb2wgZW5mb3JjZSkgeyBlbmZvcmNlX3dlYWtfID0gZW5mb3JjZTsgfQorCisgIC8vIEludGVybmFsIHN0dWZmIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8vIFRoZXNlIG1ldGhvZHMgTVVTVCBOT1QgYmUgY2FsbGVkIGZyb20gb3V0c2lkZSB0aGUgcHJvdG8yIGxpYnJhcnkuCisgIC8vIFRoZXNlIG1ldGhvZHMgbWF5IGNvbnRhaW4gaGlkZGVuIHBpdGZhbGxzIGFuZCBtYXkgYmUgcmVtb3ZlZCBpbiBhCisgIC8vIGZ1dHVyZSBsaWJyYXJ5IHZlcnNpb24uCisKKyAgLy8gQ3JlYXRlIGEgRGVzY3JpcHRvclBvb2wgd2hpY2ggaXMgb3ZlcmxhaWQgb24gdG9wIG9mIHNvbWUgb3RoZXIgcG9vbC4KKyAgLy8gSWYgeW91IHNlYXJjaCBmb3IgYSBkZXNjcmlwdG9yIGluIHRoZSBvdmVybGF5IGFuZCBpdCBpcyBub3QgZm91bmQsIHRoZQorICAvLyB1bmRlcmxheSB3aWxsIGJlIHNlYXJjaGVkIGFzIGEgYmFja3VwLiAgSWYgdGhlIHVuZGVybGF5IGhhcyBpdHMgb3duCisgIC8vIHVuZGVybGF5LCB0aGF0IHdpbGwgYmUgc2VhcmNoZWQgbmV4dCwgYW5kIHNvIG9uLiAgVGhpcyBhbHNvIG1lYW5zIHRoYXQKKyAgLy8gZmlsZXMgYnVpbHQgaW4gdGhlIG92ZXJsYXkgd2lsbCBiZSBjcm9zcy1saW5rZWQgd2l0aCB0aGUgdW5kZXJsYXkncworICAvLyBkZXNjcmlwdG9ycyBpZiBuZWNlc3NhcnkuICBUaGUgdW5kZXJsYXkgcmVtYWlucyBwcm9wZXJ0eSBvZiB0aGUgY2FsbGVyOworICAvLyBpdCBtdXN0IHJlbWFpbiB2YWxpZCBmb3IgdGhlIGxpZmV0aW1lIG9mIHRoZSBuZXdseS1jb25zdHJ1Y3RlZCBwb29sLgorICAvLworICAvLyBFeGFtcGxlOiAgU2F5IHlvdSB3YW50IHRvIHBhcnNlIGEgLnByb3RvIGZpbGUgYXQgcnVudGltZSBpbiBvcmRlciB0byB1c2UKKyAgLy8gaXRzIHR5cGUgd2l0aCBhIER5bmFtaWNNZXNzYWdlLiAgU2F5IHRoaXMgLnByb3RvIGZpbGUgaGFzIGRlcGVuZGVuY2llcywKKyAgLy8gYnV0IHlvdSBrbm93IHRoYXQgYWxsIHRoZSBkZXBlbmRlbmNpZXMgd2lsbCBiZSB0aGluZ3MgdGhhdCBhcmUgYWxyZWFkeQorICAvLyBjb21waWxlZCBpbnRvIHRoZSBiaW5hcnkuICBGb3IgZWFzZSBvZiB1c2UsIHlvdSdkIGxpa2UgdG8gbG9hZCB0aGUgdHlwZXMKKyAgLy8gcmlnaHQgb3V0IG9mIGdlbmVyYXRlZF9wb29sKCkgcmF0aGVyIHRoYW4gaGF2ZSB0byBwYXJzZSByZWR1bmRhbnQgY29waWVzCisgIC8vIG9mIGFsbCB0aGVzZSAucHJvdG9zIGFuZCBydW50aW1lLiAgQnV0LCB5b3UgZG9uJ3Qgd2FudCB0byBhZGQgdGhlIHBhcnNlZAorICAvLyB0eXBlcyBkaXJlY3RseSBpbnRvIGdlbmVyYXRlZF9wb29sKCk6IHRoaXMgaXMgbm90IGFsbG93ZWQsIGFuZCB3b3VsZCBiZQorICAvLyBiYWQgZGVzaWduIGFueXdheS4gIFNvLCBpbnN0ZWFkLCB5b3UgY291bGQgdXNlIGdlbmVyYXRlZF9wb29sKCkgYXMgYW4KKyAgLy8gdW5kZXJsYXkgZm9yIGEgbmV3IERlc2NyaXB0b3JQb29sIGluIHdoaWNoIHlvdSBhZGQgb25seSB0aGUgbmV3IGZpbGUuCisgIC8vCisgIC8vIFdBUk5JTkc6ICBVc2Ugb2YgdW5kZXJsYXlzIGNhbiBsZWFkIHRvIG1hbnkgc3VidGxlIGdvdGNoYXMuICBJbnN0ZWFkLAorICAvLyAgIHRyeSB0byBmb3JtdWxhdGUgd2hhdCB5b3Ugd2FudCB0byBkbyBpbiB0ZXJtcyBvZiBEZXNjcmlwdG9yRGF0YWJhc2VzLgorICBleHBsaWNpdCBEZXNjcmlwdG9yUG9vbChjb25zdCBEZXNjcmlwdG9yUG9vbCogdW5kZXJsYXkpOworCisgIC8vIENhbGxlZCBieSBnZW5lcmF0ZWQgY2xhc3NlcyBhdCBpbml0IHRpbWUgdG8gYWRkIHRoZWlyIGRlc2NyaXB0b3JzIHRvCisgIC8vIGdlbmVyYXRlZF9wb29sLiAgRG8gTk9UIGNhbGwgdGhpcyBpbiB5b3VyIG93biBjb2RlISAgZmlsZW5hbWUgbXVzdCBiZSBhCisgIC8vIHBlcm1hbmVudCBzdHJpbmcgKGUuZy4gYSBzdHJpbmcgbGl0ZXJhbCkuCisgIHN0YXRpYyB2b2lkIEludGVybmFsQWRkR2VuZXJhdGVkRmlsZSgKKyAgICAgIGNvbnN0IHZvaWQqIGVuY29kZWRfZmlsZV9kZXNjcmlwdG9yLCBpbnQgc2l6ZSk7CisKKworICAvLyBGb3IgaW50ZXJuYWwgdXNlIG9ubHk6ICBHZXRzIGEgbm9uLWNvbnN0IHBvaW50ZXIgdG8gdGhlIGdlbmVyYXRlZCBwb29sLgorICAvLyBUaGlzIGlzIGNhbGxlZCBhdCBzdGF0aWMtaW5pdGlhbGl6YXRpb24gdGltZSBvbmx5LCBzbyB0aHJlYWQtc2FmZXR5IGlzCisgIC8vIG5vdCBhIGNvbmNlcm4uICBJZiBib3RoIGFuIHVuZGVybGF5IGFuZCBhIGZhbGxiYWNrIGRhdGFiYXNlIGFyZSBwcmVzZW50LAorICAvLyB0aGUgdW5kZXJsYXkgdGFrZXMgcHJlY2VkZW5jZS4KKyAgc3RhdGljIERlc2NyaXB0b3JQb29sKiBpbnRlcm5hbF9nZW5lcmF0ZWRfcG9vbCgpOworCisgIC8vIEZvciBpbnRlcm5hbCB1c2Ugb25seTogIENoYW5nZXMgdGhlIGJlaGF2aW9yIG9mIEJ1aWxkRmlsZSgpIHN1Y2ggdGhhdCBpdAorICAvLyBhbGxvd3MgdGhlIGZpbGUgdG8gbWFrZSByZWZlcmVuY2UgdG8gbWVzc2FnZSB0eXBlcyBkZWNsYXJlZCBpbiBvdGhlciBmaWxlcworICAvLyB3aGljaCBpdCBkaWQgbm90IG9mZmljaWFsbHkgZGVjbGFyZSBhcyBkZXBlbmRlbmNpZXMuCisgIHZvaWQgSW50ZXJuYWxEb250RW5mb3JjZURlcGVuZGVuY2llcygpOworCisgIC8vIEZvciBpbnRlcm5hbCB1c2Ugb25seS4KKyAgdm9pZCBpbnRlcm5hbF9zZXRfdW5kZXJsYXkoY29uc3QgRGVzY3JpcHRvclBvb2wqIHVuZGVybGF5KSB7CisgICAgdW5kZXJsYXlfID0gdW5kZXJsYXk7CisgIH0KKworICAvLyBGb3IgaW50ZXJuYWwgKHVuaXQgdGVzdCkgdXNlIG9ubHk6ICBSZXR1cm5zIHRydWUgaWYgYSBGaWxlRGVzY3JpcHRvciBoYXMKKyAgLy8gYmVlbiBjb25zdHJ1Y3RlZCBmb3IgdGhlIGdpdmVuIGZpbGUsIGZhbHNlIG90aGVyd2lzZS4gIFVzZWZ1bCBmb3IgdGVzdGluZworICAvLyBsYXp5IGRlc2NyaXB0b3IgaW5pdGlhbGl6YXRpb24gYmVoYXZpb3IuCisgIGJvb2wgSW50ZXJuYWxJc0ZpbGVMb2FkZWQoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSkgY29uc3Q7CisKKworICAvLyBBZGQgYSBmaWxlIHRvIHVudXNlZF9pbXBvcnRfdHJhY2tfZmlsZXNfLiBEZXNjcmlwdG9yQnVpbGRlciB3aWxsIGxvZworICAvLyB3YXJuaW5ncyBmb3IgdGhvc2UgZmlsZXMgaWYgdGhlcmUgaXMgYW55IHVudXNlZCBpbXBvcnQuCisgIHZvaWQgQWRkVW51c2VkSW1wb3J0VHJhY2tGaWxlKGNvbnN0IHN0cmluZyYgZmlsZV9uYW1lKTsKKyAgdm9pZCBDbGVhclVudXNlZEltcG9ydFRyYWNrRmlsZXMoKTsKKworIHByaXZhdGU6CisgIGZyaWVuZCBjbGFzcyBEZXNjcmlwdG9yOworICBmcmllbmQgY2xhc3MgRmllbGREZXNjcmlwdG9yOworICBmcmllbmQgY2xhc3MgRW51bURlc2NyaXB0b3I7CisgIGZyaWVuZCBjbGFzcyBTZXJ2aWNlRGVzY3JpcHRvcjsKKyAgZnJpZW5kIGNsYXNzIEZpbGVEZXNjcmlwdG9yOworICBmcmllbmQgY2xhc3MgRGVzY3JpcHRvckJ1aWxkZXI7CisgIGZyaWVuZCBjbGFzcyBGaWxlRGVzY3JpcHRvclRhYmxlczsKKworICAvLyBSZXR1cm4gdHJ1ZSBpZiB0aGUgZ2l2ZW4gbmFtZSBpcyBhIHN1Yi1zeW1ib2wgb2YgYW55IG5vbi1wYWNrYWdlCisgIC8vIGRlc2NyaXB0b3IgdGhhdCBhbHJlYWR5IGV4aXN0cyBpbiB0aGUgZGVzY3JpcHRvciBwb29sLiAgKFRoZSBmdWxsCisgIC8vIGRlZmluaXRpb24gb2Ygc3VjaCB0eXBlcyBpcyBhbHJlYWR5IGtub3duLikKKyAgYm9vbCBJc1N1YlN5bWJvbE9mQnVpbHRUeXBlKGNvbnN0IHN0cmluZyYgbmFtZSkgY29uc3Q7CisKKyAgLy8gVHJpZXMgdG8gZmluZCBzb21ldGhpbmcgaW4gdGhlIGZhbGxiYWNrIGRhdGFiYXNlIGFuZCBsaW5rIGluIHRoZQorICAvLyBjb3JyZXNwb25kaW5nIHByb3RvIGZpbGUuICBSZXR1cm5zIHRydWUgaWYgc3VjY2Vzc2Z1bCwgaW4gd2hpY2ggY2FzZQorICAvLyB0aGUgY2FsbGVyIHNob3VsZCBzZWFyY2ggZm9yIHRoZSB0aGluZyBhZ2Fpbi4gIFRoZXNlIGFyZSBkZWNsYXJlZAorICAvLyBjb25zdCBiZWNhdXNlIHRoZXkgYXJlIGNhbGxlZCBieSAoc2VtYW50aWNhbGx5KSBjb25zdCBtZXRob2RzLgorICBib29sIFRyeUZpbmRGaWxlSW5GYWxsYmFja0RhdGFiYXNlKGNvbnN0IHN0cmluZyYgbmFtZSkgY29uc3Q7CisgIGJvb2wgVHJ5RmluZFN5bWJvbEluRmFsbGJhY2tEYXRhYmFzZShjb25zdCBzdHJpbmcmIG5hbWUpIGNvbnN0OworICBib29sIFRyeUZpbmRFeHRlbnNpb25JbkZhbGxiYWNrRGF0YWJhc2UoY29uc3QgRGVzY3JpcHRvciogY29udGFpbmluZ190eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGZpZWxkX251bWJlcikgY29uc3Q7CisKKyAgLy8gTGlrZSBCdWlsZEZpbGUoKSBidXQgY2FsbGVkIGludGVybmFsbHkgd2hlbiB0aGUgZmlsZSBoYXMgYmVlbiBsb2FkZWQgZnJvbQorICAvLyBmYWxsYmFja19kYXRhYmFzZV8uICBEZWNsYXJlZCBjb25zdCBiZWNhdXNlIGl0IGlzIGNhbGxlZCBieSAoc2VtYW50aWNhbGx5KQorICAvLyBjb25zdCBtZXRob2RzLgorICBjb25zdCBGaWxlRGVzY3JpcHRvciogQnVpbGRGaWxlRnJvbURhdGFiYXNlKAorICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8mIHByb3RvKSBjb25zdDsKKworICAvLyBJZiBmYWxsYmFja19kYXRhYmFzZV8gaXMgTlVMTCwgdGhpcyBpcyBOVUxMLiAgT3RoZXJ3aXNlLCB0aGlzIGlzIGEgbXV0ZXgKKyAgLy8gd2hpY2ggbXVzdCBiZSBsb2NrZWQgd2hpbGUgYWNjZXNzaW5nIHRhYmxlc18uCisgIE11dGV4KiBtdXRleF87CisKKyAgLy8gU2VlIGNvbnN0cnVjdG9yLgorICBEZXNjcmlwdG9yRGF0YWJhc2UqIGZhbGxiYWNrX2RhdGFiYXNlXzsKKyAgRXJyb3JDb2xsZWN0b3IqIGRlZmF1bHRfZXJyb3JfY29sbGVjdG9yXzsKKyAgY29uc3QgRGVzY3JpcHRvclBvb2wqIHVuZGVybGF5XzsKKworICAvLyBUaGlzIGNsYXNzIGNvbnRhaW5zIGEgbG90IG9mIGhhc2ggbWFwcyB3aXRoIGNvbXBsaWNhdGVkIHR5cGVzIHRoYXQKKyAgLy8gd2UnZCBsaWtlIHRvIGtlZXAgb3V0IG9mIHRoZSBoZWFkZXIuCisgIGNsYXNzIFRhYmxlczsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxUYWJsZXM+IHRhYmxlc187CisKKyAgYm9vbCBlbmZvcmNlX2RlcGVuZGVuY2llc187CisgIGJvb2wgYWxsb3dfdW5rbm93bl87CisgIGJvb2wgZW5mb3JjZV93ZWFrXzsKKyAgc3RkOjpzZXQ8c3RyaW5nPiB1bnVzZWRfaW1wb3J0X3RyYWNrX2ZpbGVzXzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoRGVzY3JpcHRvclBvb2wpOworfTsKKworLy8gaW5saW5lIG1ldGhvZHMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisvLyBUaGVzZSBtYWNyb3MgbWFrZXMgdGhpcyByZXBldGl0aXZlIGNvZGUgbW9yZSByZWFkYWJsZS4KKyNkZWZpbmUgUFJPVE9CVUZfREVGSU5FX0FDQ0VTU09SKENMQVNTLCBGSUVMRCwgVFlQRSkgXAorICBpbmxpbmUgVFlQRSBDTEFTUzo6RklFTEQoKSBjb25zdCB7IHJldHVybiBGSUVMRCMjXzsgfQorCisvLyBTdHJpbmdzIGZpZWxkcyBhcmUgc3RvcmVkIGFzIHBvaW50ZXJzIGJ1dCByZXR1cm5lZCBhcyBjb25zdCByZWZlcmVuY2VzLgorI2RlZmluZSBQUk9UT0JVRl9ERUZJTkVfU1RSSU5HX0FDQ0VTU09SKENMQVNTLCBGSUVMRCkgXAorICBpbmxpbmUgY29uc3Qgc3RyaW5nJiBDTEFTUzo6RklFTEQoKSBjb25zdCB7IHJldHVybiAqRklFTEQjI187IH0KKworLy8gQXJyYXlzIHRha2UgYW4gaW5kZXggcGFyYW1ldGVyLCBvYnZpb3VzbHkuCisjZGVmaW5lIFBST1RPQlVGX0RFRklORV9BUlJBWV9BQ0NFU1NPUihDTEFTUywgRklFTEQsIFRZUEUpIFwKKyAgaW5saW5lIFRZUEUgQ0xBU1M6OkZJRUxEKGludCBpbmRleCkgY29uc3QgeyByZXR1cm4gRklFTEQjI3NfICsgaW5kZXg7IH0KKworI2RlZmluZSBQUk9UT0JVRl9ERUZJTkVfT1BUSU9OU19BQ0NFU1NPUihDTEFTUywgVFlQRSkgXAorICBpbmxpbmUgY29uc3QgVFlQRSYgQ0xBU1M6Om9wdGlvbnMoKSBjb25zdCB7IHJldHVybiAqb3B0aW9uc187IH0KKworUFJPVE9CVUZfREVGSU5FX1NUUklOR19BQ0NFU1NPUihEZXNjcmlwdG9yLCBuYW1lKQorUFJPVE9CVUZfREVGSU5FX1NUUklOR19BQ0NFU1NPUihEZXNjcmlwdG9yLCBmdWxsX25hbWUpCitQUk9UT0JVRl9ERUZJTkVfQUNDRVNTT1IoRGVzY3JpcHRvciwgZmlsZSwgY29uc3QgRmlsZURlc2NyaXB0b3IqKQorUFJPVE9CVUZfREVGSU5FX0FDQ0VTU09SKERlc2NyaXB0b3IsIGNvbnRhaW5pbmdfdHlwZSwgY29uc3QgRGVzY3JpcHRvciopCisKK1BST1RPQlVGX0RFRklORV9BQ0NFU1NPUihEZXNjcmlwdG9yLCBmaWVsZF9jb3VudCwgaW50KQorUFJPVE9CVUZfREVGSU5FX0FDQ0VTU09SKERlc2NyaXB0b3IsIG9uZW9mX2RlY2xfY291bnQsIGludCkKK1BST1RPQlVGX0RFRklORV9BQ0NFU1NPUihEZXNjcmlwdG9yLCBuZXN0ZWRfdHlwZV9jb3VudCwgaW50KQorUFJPVE9CVUZfREVGSU5FX0FDQ0VTU09SKERlc2NyaXB0b3IsIGVudW1fdHlwZV9jb3VudCwgaW50KQorCitQUk9UT0JVRl9ERUZJTkVfQVJSQVlfQUNDRVNTT1IoRGVzY3JpcHRvciwgZmllbGQsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciopCitQUk9UT0JVRl9ERUZJTkVfQVJSQVlfQUNDRVNTT1IoRGVzY3JpcHRvciwgb25lb2ZfZGVjbCwgY29uc3QgT25lb2ZEZXNjcmlwdG9yKikKK1BST1RPQlVGX0RFRklORV9BUlJBWV9BQ0NFU1NPUihEZXNjcmlwdG9yLCBuZXN0ZWRfdHlwZSwgY29uc3QgRGVzY3JpcHRvciopCitQUk9UT0JVRl9ERUZJTkVfQVJSQVlfQUNDRVNTT1IoRGVzY3JpcHRvciwgZW51bV90eXBlLCBjb25zdCBFbnVtRGVzY3JpcHRvciopCisKK1BST1RPQlVGX0RFRklORV9BQ0NFU1NPUihEZXNjcmlwdG9yLCBleHRlbnNpb25fcmFuZ2VfY291bnQsIGludCkKK1BST1RPQlVGX0RFRklORV9BQ0NFU1NPUihEZXNjcmlwdG9yLCBleHRlbnNpb25fY291bnQsIGludCkKK1BST1RPQlVGX0RFRklORV9BUlJBWV9BQ0NFU1NPUihEZXNjcmlwdG9yLCBleHRlbnNpb25fcmFuZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVzY3JpcHRvcjo6RXh0ZW5zaW9uUmFuZ2UqKQorUFJPVE9CVUZfREVGSU5FX0FSUkFZX0FDQ0VTU09SKERlc2NyaXB0b3IsIGV4dGVuc2lvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqKQorCitQUk9UT0JVRl9ERUZJTkVfQUNDRVNTT1IoRGVzY3JpcHRvciwgcmVzZXJ2ZWRfcmFuZ2VfY291bnQsIGludCkKK1BST1RPQlVGX0RFRklORV9BUlJBWV9BQ0NFU1NPUihEZXNjcmlwdG9yLCByZXNlcnZlZF9yYW5nZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEZXNjcmlwdG9yOjpSZXNlcnZlZFJhbmdlKikKK1BST1RPQlVGX0RFRklORV9BQ0NFU1NPUihEZXNjcmlwdG9yLCByZXNlcnZlZF9uYW1lX2NvdW50LCBpbnQpCisKK1BST1RPQlVGX0RFRklORV9PUFRJT05TX0FDQ0VTU09SKERlc2NyaXB0b3IsIE1lc3NhZ2VPcHRpb25zKQorUFJPVE9CVUZfREVGSU5FX0FDQ0VTU09SKERlc2NyaXB0b3IsIGlzX3BsYWNlaG9sZGVyLCBib29sKQorCitQUk9UT0JVRl9ERUZJTkVfU1RSSU5HX0FDQ0VTU09SKEZpZWxkRGVzY3JpcHRvciwgbmFtZSkKK1BST1RPQlVGX0RFRklORV9TVFJJTkdfQUNDRVNTT1IoRmllbGREZXNjcmlwdG9yLCBmdWxsX25hbWUpCitQUk9UT0JVRl9ERUZJTkVfU1RSSU5HX0FDQ0VTU09SKEZpZWxkRGVzY3JpcHRvciwganNvbl9uYW1lKQorUFJPVE9CVUZfREVGSU5FX1NUUklOR19BQ0NFU1NPUihGaWVsZERlc2NyaXB0b3IsIGxvd2VyY2FzZV9uYW1lKQorUFJPVE9CVUZfREVGSU5FX1NUUklOR19BQ0NFU1NPUihGaWVsZERlc2NyaXB0b3IsIGNhbWVsY2FzZV9uYW1lKQorUFJPVE9CVUZfREVGSU5FX0FDQ0VTU09SKEZpZWxkRGVzY3JpcHRvciwgZmlsZSwgY29uc3QgRmlsZURlc2NyaXB0b3IqKQorUFJPVE9CVUZfREVGSU5FX0FDQ0VTU09SKEZpZWxkRGVzY3JpcHRvciwgbnVtYmVyLCBpbnQpCitQUk9UT0JVRl9ERUZJTkVfQUNDRVNTT1IoRmllbGREZXNjcmlwdG9yLCBpc19leHRlbnNpb24sIGJvb2wpCitQUk9UT0JVRl9ERUZJTkVfQUNDRVNTT1IoRmllbGREZXNjcmlwdG9yLCB0eXBlLCBGaWVsZERlc2NyaXB0b3I6OlR5cGUpCitQUk9UT0JVRl9ERUZJTkVfQUNDRVNTT1IoRmllbGREZXNjcmlwdG9yLCBsYWJlbCwgRmllbGREZXNjcmlwdG9yOjpMYWJlbCkKK1BST1RPQlVGX0RFRklORV9BQ0NFU1NPUihGaWVsZERlc2NyaXB0b3IsIGNvbnRhaW5pbmdfdHlwZSwgY29uc3QgRGVzY3JpcHRvciopCitQUk9UT0JVRl9ERUZJTkVfQUNDRVNTT1IoRmllbGREZXNjcmlwdG9yLCBjb250YWluaW5nX29uZW9mLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE9uZW9mRGVzY3JpcHRvciopCitQUk9UT0JVRl9ERUZJTkVfQUNDRVNTT1IoRmllbGREZXNjcmlwdG9yLCBpbmRleF9pbl9vbmVvZiwgaW50KQorUFJPVE9CVUZfREVGSU5FX0FDQ0VTU09SKEZpZWxkRGVzY3JpcHRvciwgZXh0ZW5zaW9uX3Njb3BlLCBjb25zdCBEZXNjcmlwdG9yKikKK1BST1RPQlVGX0RFRklORV9BQ0NFU1NPUihGaWVsZERlc2NyaXB0b3IsIG1lc3NhZ2VfdHlwZSwgY29uc3QgRGVzY3JpcHRvciopCitQUk9UT0JVRl9ERUZJTkVfQUNDRVNTT1IoRmllbGREZXNjcmlwdG9yLCBlbnVtX3R5cGUsIGNvbnN0IEVudW1EZXNjcmlwdG9yKikKK1BST1RPQlVGX0RFRklORV9PUFRJT05TX0FDQ0VTU09SKEZpZWxkRGVzY3JpcHRvciwgRmllbGRPcHRpb25zKQorUFJPVE9CVUZfREVGSU5FX0FDQ0VTU09SKEZpZWxkRGVzY3JpcHRvciwgaGFzX2RlZmF1bHRfdmFsdWUsIGJvb2wpCitQUk9UT0JVRl9ERUZJTkVfQUNDRVNTT1IoRmllbGREZXNjcmlwdG9yLCBkZWZhdWx0X3ZhbHVlX2ludDMyICwgaW50MzIgKQorUFJPVE9CVUZfREVGSU5FX0FDQ0VTU09SKEZpZWxkRGVzY3JpcHRvciwgZGVmYXVsdF92YWx1ZV9pbnQ2NCAsIGludDY0ICkKK1BST1RPQlVGX0RFRklORV9BQ0NFU1NPUihGaWVsZERlc2NyaXB0b3IsIGRlZmF1bHRfdmFsdWVfdWludDMyLCB1aW50MzIpCitQUk9UT0JVRl9ERUZJTkVfQUNDRVNTT1IoRmllbGREZXNjcmlwdG9yLCBkZWZhdWx0X3ZhbHVlX3VpbnQ2NCwgdWludDY0KQorUFJPVE9CVUZfREVGSU5FX0FDQ0VTU09SKEZpZWxkRGVzY3JpcHRvciwgZGVmYXVsdF92YWx1ZV9mbG9hdCAsIGZsb2F0ICkKK1BST1RPQlVGX0RFRklORV9BQ0NFU1NPUihGaWVsZERlc2NyaXB0b3IsIGRlZmF1bHRfdmFsdWVfZG91YmxlLCBkb3VibGUpCitQUk9UT0JVRl9ERUZJTkVfQUNDRVNTT1IoRmllbGREZXNjcmlwdG9yLCBkZWZhdWx0X3ZhbHVlX2Jvb2wgICwgYm9vbCAgKQorUFJPVE9CVUZfREVGSU5FX0FDQ0VTU09SKEZpZWxkRGVzY3JpcHRvciwgZGVmYXVsdF92YWx1ZV9lbnVtLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqKQorUFJPVE9CVUZfREVGSU5FX1NUUklOR19BQ0NFU1NPUihGaWVsZERlc2NyaXB0b3IsIGRlZmF1bHRfdmFsdWVfc3RyaW5nKQorCitQUk9UT0JVRl9ERUZJTkVfU1RSSU5HX0FDQ0VTU09SKE9uZW9mRGVzY3JpcHRvciwgbmFtZSkKK1BST1RPQlVGX0RFRklORV9TVFJJTkdfQUNDRVNTT1IoT25lb2ZEZXNjcmlwdG9yLCBmdWxsX25hbWUpCitQUk9UT0JVRl9ERUZJTkVfQUNDRVNTT1IoT25lb2ZEZXNjcmlwdG9yLCBjb250YWluaW5nX3R5cGUsIGNvbnN0IERlc2NyaXB0b3IqKQorUFJPVE9CVUZfREVGSU5FX0FDQ0VTU09SKE9uZW9mRGVzY3JpcHRvciwgZmllbGRfY291bnQsIGludCkKKworUFJPVE9CVUZfREVGSU5FX1NUUklOR19BQ0NFU1NPUihFbnVtRGVzY3JpcHRvciwgbmFtZSkKK1BST1RPQlVGX0RFRklORV9TVFJJTkdfQUNDRVNTT1IoRW51bURlc2NyaXB0b3IsIGZ1bGxfbmFtZSkKK1BST1RPQlVGX0RFRklORV9BQ0NFU1NPUihFbnVtRGVzY3JpcHRvciwgZmlsZSwgY29uc3QgRmlsZURlc2NyaXB0b3IqKQorUFJPVE9CVUZfREVGSU5FX0FDQ0VTU09SKEVudW1EZXNjcmlwdG9yLCBjb250YWluaW5nX3R5cGUsIGNvbnN0IERlc2NyaXB0b3IqKQorUFJPVE9CVUZfREVGSU5FX0FDQ0VTU09SKEVudW1EZXNjcmlwdG9yLCB2YWx1ZV9jb3VudCwgaW50KQorUFJPVE9CVUZfREVGSU5FX0FSUkFZX0FDQ0VTU09SKEVudW1EZXNjcmlwdG9yLCB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKikKK1BST1RPQlVGX0RFRklORV9PUFRJT05TX0FDQ0VTU09SKEVudW1EZXNjcmlwdG9yLCBFbnVtT3B0aW9ucykKK1BST1RPQlVGX0RFRklORV9BQ0NFU1NPUihFbnVtRGVzY3JpcHRvciwgaXNfcGxhY2Vob2xkZXIsIGJvb2wpCisKK1BST1RPQlVGX0RFRklORV9TVFJJTkdfQUNDRVNTT1IoRW51bVZhbHVlRGVzY3JpcHRvciwgbmFtZSkKK1BST1RPQlVGX0RFRklORV9TVFJJTkdfQUNDRVNTT1IoRW51bVZhbHVlRGVzY3JpcHRvciwgZnVsbF9uYW1lKQorUFJPVE9CVUZfREVGSU5FX0FDQ0VTU09SKEVudW1WYWx1ZURlc2NyaXB0b3IsIG51bWJlciwgaW50KQorUFJPVE9CVUZfREVGSU5FX0FDQ0VTU09SKEVudW1WYWx1ZURlc2NyaXB0b3IsIHR5cGUsIGNvbnN0IEVudW1EZXNjcmlwdG9yKikKK1BST1RPQlVGX0RFRklORV9PUFRJT05TX0FDQ0VTU09SKEVudW1WYWx1ZURlc2NyaXB0b3IsIEVudW1WYWx1ZU9wdGlvbnMpCisKK1BST1RPQlVGX0RFRklORV9TVFJJTkdfQUNDRVNTT1IoU2VydmljZURlc2NyaXB0b3IsIG5hbWUpCitQUk9UT0JVRl9ERUZJTkVfU1RSSU5HX0FDQ0VTU09SKFNlcnZpY2VEZXNjcmlwdG9yLCBmdWxsX25hbWUpCitQUk9UT0JVRl9ERUZJTkVfQUNDRVNTT1IoU2VydmljZURlc2NyaXB0b3IsIGZpbGUsIGNvbnN0IEZpbGVEZXNjcmlwdG9yKikKK1BST1RPQlVGX0RFRklORV9BQ0NFU1NPUihTZXJ2aWNlRGVzY3JpcHRvciwgbWV0aG9kX2NvdW50LCBpbnQpCitQUk9UT0JVRl9ERUZJTkVfQVJSQVlfQUNDRVNTT1IoU2VydmljZURlc2NyaXB0b3IsIG1ldGhvZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNZXRob2REZXNjcmlwdG9yKikKK1BST1RPQlVGX0RFRklORV9PUFRJT05TX0FDQ0VTU09SKFNlcnZpY2VEZXNjcmlwdG9yLCBTZXJ2aWNlT3B0aW9ucykKKworUFJPVE9CVUZfREVGSU5FX1NUUklOR19BQ0NFU1NPUihNZXRob2REZXNjcmlwdG9yLCBuYW1lKQorUFJPVE9CVUZfREVGSU5FX1NUUklOR19BQ0NFU1NPUihNZXRob2REZXNjcmlwdG9yLCBmdWxsX25hbWUpCitQUk9UT0JVRl9ERUZJTkVfQUNDRVNTT1IoTWV0aG9kRGVzY3JpcHRvciwgc2VydmljZSwgY29uc3QgU2VydmljZURlc2NyaXB0b3IqKQorUFJPVE9CVUZfREVGSU5FX0FDQ0VTU09SKE1ldGhvZERlc2NyaXB0b3IsIGlucHV0X3R5cGUsIGNvbnN0IERlc2NyaXB0b3IqKQorUFJPVE9CVUZfREVGSU5FX0FDQ0VTU09SKE1ldGhvZERlc2NyaXB0b3IsIG91dHB1dF90eXBlLCBjb25zdCBEZXNjcmlwdG9yKikKK1BST1RPQlVGX0RFRklORV9PUFRJT05TX0FDQ0VTU09SKE1ldGhvZERlc2NyaXB0b3IsIE1ldGhvZE9wdGlvbnMpCitQUk9UT0JVRl9ERUZJTkVfQUNDRVNTT1IoTWV0aG9kRGVzY3JpcHRvciwgY2xpZW50X3N0cmVhbWluZywgYm9vbCkKK1BST1RPQlVGX0RFRklORV9BQ0NFU1NPUihNZXRob2REZXNjcmlwdG9yLCBzZXJ2ZXJfc3RyZWFtaW5nLCBib29sKQorCitQUk9UT0JVRl9ERUZJTkVfU1RSSU5HX0FDQ0VTU09SKEZpbGVEZXNjcmlwdG9yLCBuYW1lKQorUFJPVE9CVUZfREVGSU5FX1NUUklOR19BQ0NFU1NPUihGaWxlRGVzY3JpcHRvciwgcGFja2FnZSkKK1BST1RPQlVGX0RFRklORV9BQ0NFU1NPUihGaWxlRGVzY3JpcHRvciwgcG9vbCwgY29uc3QgRGVzY3JpcHRvclBvb2wqKQorUFJPVE9CVUZfREVGSU5FX0FDQ0VTU09SKEZpbGVEZXNjcmlwdG9yLCBkZXBlbmRlbmN5X2NvdW50LCBpbnQpCitQUk9UT0JVRl9ERUZJTkVfQUNDRVNTT1IoRmlsZURlc2NyaXB0b3IsIHB1YmxpY19kZXBlbmRlbmN5X2NvdW50LCBpbnQpCitQUk9UT0JVRl9ERUZJTkVfQUNDRVNTT1IoRmlsZURlc2NyaXB0b3IsIHdlYWtfZGVwZW5kZW5jeV9jb3VudCwgaW50KQorUFJPVE9CVUZfREVGSU5FX0FDQ0VTU09SKEZpbGVEZXNjcmlwdG9yLCBtZXNzYWdlX3R5cGVfY291bnQsIGludCkKK1BST1RPQlVGX0RFRklORV9BQ0NFU1NPUihGaWxlRGVzY3JpcHRvciwgZW51bV90eXBlX2NvdW50LCBpbnQpCitQUk9UT0JVRl9ERUZJTkVfQUNDRVNTT1IoRmlsZURlc2NyaXB0b3IsIHNlcnZpY2VfY291bnQsIGludCkKK1BST1RPQlVGX0RFRklORV9BQ0NFU1NPUihGaWxlRGVzY3JpcHRvciwgZXh0ZW5zaW9uX2NvdW50LCBpbnQpCitQUk9UT0JVRl9ERUZJTkVfT1BUSU9OU19BQ0NFU1NPUihGaWxlRGVzY3JpcHRvciwgRmlsZU9wdGlvbnMpCitQUk9UT0JVRl9ERUZJTkVfQUNDRVNTT1IoRmlsZURlc2NyaXB0b3IsIGlzX3BsYWNlaG9sZGVyLCBib29sKQorCitQUk9UT0JVRl9ERUZJTkVfQVJSQVlfQUNDRVNTT1IoRmlsZURlc2NyaXB0b3IsIG1lc3NhZ2VfdHlwZSwgY29uc3QgRGVzY3JpcHRvciopCitQUk9UT0JVRl9ERUZJTkVfQVJSQVlfQUNDRVNTT1IoRmlsZURlc2NyaXB0b3IsIGVudW1fdHlwZSwgY29uc3QgRW51bURlc2NyaXB0b3IqKQorUFJPVE9CVUZfREVGSU5FX0FSUkFZX0FDQ0VTU09SKEZpbGVEZXNjcmlwdG9yLCBzZXJ2aWNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yKikKK1BST1RPQlVGX0RFRklORV9BUlJBWV9BQ0NFU1NPUihGaWxlRGVzY3JpcHRvciwgZXh0ZW5zaW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciopCisKKyN1bmRlZiBQUk9UT0JVRl9ERUZJTkVfQUNDRVNTT1IKKyN1bmRlZiBQUk9UT0JVRl9ERUZJTkVfU1RSSU5HX0FDQ0VTU09SCisjdW5kZWYgUFJPVE9CVUZfREVGSU5FX0FSUkFZX0FDQ0VTU09SCisKKy8vIEEgZmV3IGFjY2Vzc29ycyBkaWZmZXIgZnJvbSB0aGUgbWFjcm9zLi4uCisKK2lubGluZSBib29sIERlc2NyaXB0b3I6OklzRXh0ZW5zaW9uTnVtYmVyKGludCBudW1iZXIpIGNvbnN0IHsKKyAgcmV0dXJuIEZpbmRFeHRlbnNpb25SYW5nZUNvbnRhaW5pbmdOdW1iZXIobnVtYmVyKSAhPSBOVUxMOworfQorCitpbmxpbmUgYm9vbCBEZXNjcmlwdG9yOjpJc1Jlc2VydmVkTnVtYmVyKGludCBudW1iZXIpIGNvbnN0IHsKKyAgcmV0dXJuIEZpbmRSZXNlcnZlZFJhbmdlQ29udGFpbmluZ051bWJlcihudW1iZXIpICE9IE5VTEw7Cit9CisKK2lubGluZSBib29sIERlc2NyaXB0b3I6OklzUmVzZXJ2ZWROYW1lKGNvbnN0IHN0cmluZyYgbmFtZSkgY29uc3QgeworICBmb3IgKGludCBpID0gMDsgaSA8IHJlc2VydmVkX25hbWVfY291bnQoKTsgaSsrKSB7CisgICAgaWYgKG5hbWUgPT0gcmVzZXJ2ZWRfbmFtZShpKSkgeworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICB9CisgIHJldHVybiBmYWxzZTsKK30KKworLy8gQ2FuJ3QgdXNlIFBST1RPQlVGX0RFRklORV9BUlJBWV9BQ0NFU1NPUiBiZWNhdXNlIHJlc2VydmVkX25hbWVzXyBpcyBhY3R1YWxseQorLy8gYW4gYXJyYXkgb2YgcG9pbnRlcnMgcmF0aGVyIHRoYW4gdGhlIHVzdWFsIGFycmF5IG9mIG9iamVjdHMuCitpbmxpbmUgY29uc3Qgc3RyaW5nJiBEZXNjcmlwdG9yOjpyZXNlcnZlZF9uYW1lKGludCBpbmRleCkgY29uc3QgeworICByZXR1cm4gKnJlc2VydmVkX25hbWVzX1tpbmRleF07Cit9CisKK2lubGluZSBib29sIEZpZWxkRGVzY3JpcHRvcjo6aXNfcmVxdWlyZWQoKSBjb25zdCB7CisgIHJldHVybiBsYWJlbCgpID09IExBQkVMX1JFUVVJUkVEOworfQorCitpbmxpbmUgYm9vbCBGaWVsZERlc2NyaXB0b3I6OmlzX29wdGlvbmFsKCkgY29uc3QgeworICByZXR1cm4gbGFiZWwoKSA9PSBMQUJFTF9PUFRJT05BTDsKK30KKworaW5saW5lIGJvb2wgRmllbGREZXNjcmlwdG9yOjppc19yZXBlYXRlZCgpIGNvbnN0IHsKKyAgcmV0dXJuIGxhYmVsKCkgPT0gTEFCRUxfUkVQRUFURUQ7Cit9CisKK2lubGluZSBib29sIEZpZWxkRGVzY3JpcHRvcjo6aXNfcGFja2FibGUoKSBjb25zdCB7CisgIHJldHVybiBpc19yZXBlYXRlZCgpICYmIElzVHlwZVBhY2thYmxlKHR5cGUoKSk7Cit9CisKKy8vIFRvIHNhdmUgc3BhY2UsIGluZGV4KCkgaXMgY29tcHV0ZWQgYnkgbG9va2luZyBhdCB0aGUgZGVzY3JpcHRvcidzIHBvc2l0aW9uCisvLyBpbiB0aGUgcGFyZW50J3MgYXJyYXkgb2YgY2hpbGRyZW4uCitpbmxpbmUgaW50IEZpZWxkRGVzY3JpcHRvcjo6aW5kZXgoKSBjb25zdCB7CisgIGlmICghaXNfZXh0ZW5zaW9uXykgeworICAgIHJldHVybiBzdGF0aWNfY2FzdDxpbnQ+KHRoaXMgLSBjb250YWluaW5nX3R5cGVfLT5maWVsZHNfKTsKKyAgfSBlbHNlIGlmIChleHRlbnNpb25fc2NvcGVfICE9IE5VTEwpIHsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8aW50Pih0aGlzIC0gZXh0ZW5zaW9uX3Njb3BlXy0+ZXh0ZW5zaW9uc18pOworICB9IGVsc2UgeworICAgIHJldHVybiBzdGF0aWNfY2FzdDxpbnQ+KHRoaXMgLSBmaWxlXy0+ZXh0ZW5zaW9uc18pOworICB9Cit9CisKK2lubGluZSBpbnQgRGVzY3JpcHRvcjo6aW5kZXgoKSBjb25zdCB7CisgIGlmIChjb250YWluaW5nX3R5cGVfID09IE5VTEwpIHsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8aW50Pih0aGlzIC0gZmlsZV8tPm1lc3NhZ2VfdHlwZXNfKTsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8aW50Pih0aGlzIC0gY29udGFpbmluZ190eXBlXy0+bmVzdGVkX3R5cGVzXyk7CisgIH0KK30KKworaW5saW5lIGludCBPbmVvZkRlc2NyaXB0b3I6OmluZGV4KCkgY29uc3QgeworICByZXR1cm4gc3RhdGljX2Nhc3Q8aW50Pih0aGlzIC0gY29udGFpbmluZ190eXBlXy0+b25lb2ZfZGVjbHNfKTsKK30KKworaW5saW5lIGludCBFbnVtRGVzY3JpcHRvcjo6aW5kZXgoKSBjb25zdCB7CisgIGlmIChjb250YWluaW5nX3R5cGVfID09IE5VTEwpIHsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8aW50Pih0aGlzIC0gZmlsZV8tPmVudW1fdHlwZXNfKTsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8aW50Pih0aGlzIC0gY29udGFpbmluZ190eXBlXy0+ZW51bV90eXBlc18pOworICB9Cit9CisKK2lubGluZSBpbnQgRW51bVZhbHVlRGVzY3JpcHRvcjo6aW5kZXgoKSBjb25zdCB7CisgIHJldHVybiBzdGF0aWNfY2FzdDxpbnQ+KHRoaXMgLSB0eXBlXy0+dmFsdWVzXyk7Cit9CisKK2lubGluZSBpbnQgU2VydmljZURlc2NyaXB0b3I6OmluZGV4KCkgY29uc3QgeworICByZXR1cm4gc3RhdGljX2Nhc3Q8aW50Pih0aGlzIC0gZmlsZV8tPnNlcnZpY2VzXyk7Cit9CisKK2lubGluZSBpbnQgTWV0aG9kRGVzY3JpcHRvcjo6aW5kZXgoKSBjb25zdCB7CisgIHJldHVybiBzdGF0aWNfY2FzdDxpbnQ+KHRoaXMgLSBzZXJ2aWNlXy0+bWV0aG9kc18pOworfQorCitpbmxpbmUgY29uc3QgY2hhciogRmllbGREZXNjcmlwdG9yOjp0eXBlX25hbWUoKSBjb25zdCB7CisgIHJldHVybiBrVHlwZVRvTmFtZVt0eXBlX107Cit9CisKK2lubGluZSBGaWVsZERlc2NyaXB0b3I6OkNwcFR5cGUgRmllbGREZXNjcmlwdG9yOjpjcHBfdHlwZSgpIGNvbnN0IHsKKyAgcmV0dXJuIGtUeXBlVG9DcHBUeXBlTWFwW3R5cGVfXTsKK30KKworaW5saW5lIGNvbnN0IGNoYXIqIEZpZWxkRGVzY3JpcHRvcjo6Y3BwX3R5cGVfbmFtZSgpIGNvbnN0IHsKKyAgcmV0dXJuIGtDcHBUeXBlVG9OYW1lW2tUeXBlVG9DcHBUeXBlTWFwW3R5cGVfXV07Cit9CisKK2lubGluZSBGaWVsZERlc2NyaXB0b3I6OkNwcFR5cGUgRmllbGREZXNjcmlwdG9yOjpUeXBlVG9DcHBUeXBlKFR5cGUgdHlwZSkgeworICByZXR1cm4ga1R5cGVUb0NwcFR5cGVNYXBbdHlwZV07Cit9CisKK2lubGluZSBjb25zdCBjaGFyKiBGaWVsZERlc2NyaXB0b3I6OlR5cGVOYW1lKFR5cGUgdHlwZSkgeworICByZXR1cm4ga1R5cGVUb05hbWVbdHlwZV07Cit9CisKK2lubGluZSBjb25zdCBjaGFyKiBGaWVsZERlc2NyaXB0b3I6OkNwcFR5cGVOYW1lKENwcFR5cGUgY3BwX3R5cGUpIHsKKyAgcmV0dXJuIGtDcHBUeXBlVG9OYW1lW2NwcF90eXBlXTsKK30KKworaW5saW5lIGJvb2wgRmllbGREZXNjcmlwdG9yOjpJc1R5cGVQYWNrYWJsZShUeXBlIGZpZWxkX3R5cGUpIHsKKyAgcmV0dXJuIChmaWVsZF90eXBlICE9IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TVFJJTkcgJiYKKyAgICAgICAgICBmaWVsZF90eXBlICE9IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9HUk9VUCAmJgorICAgICAgICAgIGZpZWxkX3R5cGUgIT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX01FU1NBR0UgJiYKKyAgICAgICAgICBmaWVsZF90eXBlICE9IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9CWVRFUyk7Cit9CisKK2lubGluZSBjb25zdCBGaWxlRGVzY3JpcHRvciogRmlsZURlc2NyaXB0b3I6OmRlcGVuZGVuY3koaW50IGluZGV4KSBjb25zdCB7CisgIHJldHVybiBkZXBlbmRlbmNpZXNfW2luZGV4XTsKK30KKworaW5saW5lIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBGaWxlRGVzY3JpcHRvcjo6cHVibGljX2RlcGVuZGVuY3koCisgICAgaW50IGluZGV4KSBjb25zdCB7CisgIHJldHVybiBkZXBlbmRlbmNpZXNfW3B1YmxpY19kZXBlbmRlbmNpZXNfW2luZGV4XV07Cit9CisKK2lubGluZSBjb25zdCBGaWxlRGVzY3JpcHRvciogRmlsZURlc2NyaXB0b3I6OndlYWtfZGVwZW5kZW5jeSgKKyAgICBpbnQgaW5kZXgpIGNvbnN0IHsKKyAgcmV0dXJuIGRlcGVuZGVuY2llc19bd2Vha19kZXBlbmRlbmNpZXNfW2luZGV4XV07Cit9CisKK2lubGluZSBGaWxlRGVzY3JpcHRvcjo6U3ludGF4IEZpbGVEZXNjcmlwdG9yOjpzeW50YXgoKSBjb25zdCB7CisgIHJldHVybiBzeW50YXhfOworfQorCisvLyBDYW4ndCB1c2UgUFJPVE9CVUZfREVGSU5FX0FSUkFZX0FDQ0VTU09SIGJlY2F1c2UgZmllbGRzXyBpcyBhY3R1YWxseSBhbiBhcnJheQorLy8gb2YgcG9pbnRlcnMgcmF0aGVyIHRoYW4gdGhlIHVzdWFsIGFycmF5IG9mIG9iamVjdHMuCitpbmxpbmUgY29uc3QgRmllbGREZXNjcmlwdG9yKiBPbmVvZkRlc2NyaXB0b3I6OmZpZWxkKGludCBpbmRleCkgY29uc3QgeworICByZXR1cm4gZmllbGRzX1tpbmRleF07Cit9CisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9ERVNDUklQVE9SX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZmMGNmY2YKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuY2MKQEAgLTAsMCArMSwxNDkyNiBAQAorLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCEKKy8vIHNvdXJjZTogZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8KKworI2RlZmluZSBJTlRFUk5BTF9TVVBQUkVTU19QUk9UT0JVRl9GSUVMRF9ERVBSRUNBVElPTgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisKKyNpbmNsdWRlIDxhbGdvcml0aG0+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3BvcnQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvb25jZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZV9pbmwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfbWVzc2FnZV9yZWZsZWN0aW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3JlZmxlY3Rpb25fb3BzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0Lmg+CisvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW5jbHVkZXMpCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworbmFtZXNwYWNlIHsKKworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBGaWxlRGVzY3JpcHRvclNldF9kZXNjcmlwdG9yXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbioKKyAgRmlsZURlc2NyaXB0b3JTZXRfcmVmbGVjdGlvbl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBGaWxlRGVzY3JpcHRvclByb3RvX2Rlc2NyaXB0b3JfID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKgorICBGaWxlRGVzY3JpcHRvclByb3RvX3JlZmxlY3Rpb25fID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogRGVzY3JpcHRvclByb3RvX2Rlc2NyaXB0b3JfID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKgorICBEZXNjcmlwdG9yUHJvdG9fcmVmbGVjdGlvbl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2VfZGVzY3JpcHRvcl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24qCisgIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZV9yZWZsZWN0aW9uXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIERlc2NyaXB0b3JQcm90b19SZXNlcnZlZFJhbmdlX2Rlc2NyaXB0b3JfID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKgorICBEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZV9yZWZsZWN0aW9uXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIEZpZWxkRGVzY3JpcHRvclByb3RvX2Rlc2NyaXB0b3JfID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKgorICBGaWVsZERlc2NyaXB0b3JQcm90b19yZWZsZWN0aW9uXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yKiBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX2Rlc2NyaXB0b3JfID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bURlc2NyaXB0b3IqIEZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsX2Rlc2NyaXB0b3JfID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogT25lb2ZEZXNjcmlwdG9yUHJvdG9fZGVzY3JpcHRvcl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24qCisgIE9uZW9mRGVzY3JpcHRvclByb3RvX3JlZmxlY3Rpb25fID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogRW51bURlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbioKKyAgRW51bURlc2NyaXB0b3JQcm90b19yZWZsZWN0aW9uXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbioKKyAgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvX3JlZmxlY3Rpb25fID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogU2VydmljZURlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbioKKyAgU2VydmljZURlc2NyaXB0b3JQcm90b19yZWZsZWN0aW9uXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIE1ldGhvZERlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbioKKyAgTWV0aG9kRGVzY3JpcHRvclByb3RvX3JlZmxlY3Rpb25fID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogRmlsZU9wdGlvbnNfZGVzY3JpcHRvcl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24qCisgIEZpbGVPcHRpb25zX3JlZmxlY3Rpb25fID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bURlc2NyaXB0b3IqIEZpbGVPcHRpb25zX09wdGltaXplTW9kZV9kZXNjcmlwdG9yXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIE1lc3NhZ2VPcHRpb25zX2Rlc2NyaXB0b3JfID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKgorICBNZXNzYWdlT3B0aW9uc19yZWZsZWN0aW9uXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIEZpZWxkT3B0aW9uc19kZXNjcmlwdG9yXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbioKKyAgRmllbGRPcHRpb25zX3JlZmxlY3Rpb25fID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bURlc2NyaXB0b3IqIEZpZWxkT3B0aW9uc19DVHlwZV9kZXNjcmlwdG9yXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yKiBGaWVsZE9wdGlvbnNfSlNUeXBlX2Rlc2NyaXB0b3JfID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogRW51bU9wdGlvbnNfZGVzY3JpcHRvcl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24qCisgIEVudW1PcHRpb25zX3JlZmxlY3Rpb25fID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogRW51bVZhbHVlT3B0aW9uc19kZXNjcmlwdG9yXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbioKKyAgRW51bVZhbHVlT3B0aW9uc19yZWZsZWN0aW9uXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIFNlcnZpY2VPcHRpb25zX2Rlc2NyaXB0b3JfID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKgorICBTZXJ2aWNlT3B0aW9uc19yZWZsZWN0aW9uXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIE1ldGhvZE9wdGlvbnNfZGVzY3JpcHRvcl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24qCisgIE1ldGhvZE9wdGlvbnNfcmVmbGVjdGlvbl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBVbmludGVycHJldGVkT3B0aW9uX2Rlc2NyaXB0b3JfID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKgorICBVbmludGVycHJldGVkT3B0aW9uX3JlZmxlY3Rpb25fID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydF9kZXNjcmlwdG9yXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbioKKyAgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydF9yZWZsZWN0aW9uXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIFNvdXJjZUNvZGVJbmZvX2Rlc2NyaXB0b3JfID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKgorICBTb3VyY2VDb2RlSW5mb19yZWZsZWN0aW9uXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uX2Rlc2NyaXB0b3JfID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKgorICBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbl9yZWZsZWN0aW9uXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIEdlbmVyYXRlZENvZGVJbmZvX2Rlc2NyaXB0b3JfID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKgorICBHZW5lcmF0ZWRDb2RlSW5mb19yZWZsZWN0aW9uXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb25fZGVzY3JpcHRvcl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24qCisgIEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb25fcmVmbGVjdGlvbl8gPSBOVUxMOworCit9ICAvLyBuYW1lc3BhY2UKKworCit2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKSB7CisgIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlRGVzY3JpcHRvciogZmlsZSA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUG9vbDo6Z2VuZXJhdGVkX3Bvb2woKS0+RmluZEZpbGVCeU5hbWUoCisgICAgICAiZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8iKTsKKyAgR09PR0xFX0NIRUNLKGZpbGUgIT0gTlVMTCk7CisgIEZpbGVEZXNjcmlwdG9yU2V0X2Rlc2NyaXB0b3JfID0gZmlsZS0+bWVzc2FnZV90eXBlKDApOworICBzdGF0aWMgY29uc3QgaW50IEZpbGVEZXNjcmlwdG9yU2V0X29mZnNldHNfWzFdID0geworICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRmlsZURlc2NyaXB0b3JTZXQsIGZpbGVfKSwKKyAgfTsKKyAgRmlsZURlc2NyaXB0b3JTZXRfcmVmbGVjdGlvbl8gPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpOZXdHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbigKKyAgICAgIEZpbGVEZXNjcmlwdG9yU2V0X2Rlc2NyaXB0b3JfLAorICAgICAgRmlsZURlc2NyaXB0b3JTZXQ6OmRlZmF1bHRfaW5zdGFuY2VfLAorICAgICAgRmlsZURlc2NyaXB0b3JTZXRfb2Zmc2V0c18sCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpbGVEZXNjcmlwdG9yU2V0LCBfaGFzX2JpdHNfWzBdKSwKKyAgICAgIC0xLAorICAgICAgLTEsCisgICAgICBzaXplb2YoRmlsZURlc2NyaXB0b3JTZXQpLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWxlRGVzY3JpcHRvclNldCwgX2ludGVybmFsX21ldGFkYXRhXyksCisgICAgICAtMSk7CisgIEZpbGVEZXNjcmlwdG9yUHJvdG9fZGVzY3JpcHRvcl8gPSBmaWxlLT5tZXNzYWdlX3R5cGUoMSk7CisgIHN0YXRpYyBjb25zdCBpbnQgRmlsZURlc2NyaXB0b3JQcm90b19vZmZzZXRzX1sxMl0gPSB7CisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWxlRGVzY3JpcHRvclByb3RvLCBuYW1lXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWxlRGVzY3JpcHRvclByb3RvLCBwYWNrYWdlXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWxlRGVzY3JpcHRvclByb3RvLCBkZXBlbmRlbmN5XyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWxlRGVzY3JpcHRvclByb3RvLCBwdWJsaWNfZGVwZW5kZW5jeV8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRmlsZURlc2NyaXB0b3JQcm90bywgd2Vha19kZXBlbmRlbmN5XyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWxlRGVzY3JpcHRvclByb3RvLCBtZXNzYWdlX3R5cGVfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpbGVEZXNjcmlwdG9yUHJvdG8sIGVudW1fdHlwZV8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRmlsZURlc2NyaXB0b3JQcm90bywgc2VydmljZV8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRmlsZURlc2NyaXB0b3JQcm90bywgZXh0ZW5zaW9uXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWxlRGVzY3JpcHRvclByb3RvLCBvcHRpb25zXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWxlRGVzY3JpcHRvclByb3RvLCBzb3VyY2VfY29kZV9pbmZvXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWxlRGVzY3JpcHRvclByb3RvLCBzeW50YXhfKSwKKyAgfTsKKyAgRmlsZURlc2NyaXB0b3JQcm90b19yZWZsZWN0aW9uXyA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok5ld0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKAorICAgICAgRmlsZURlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXywKKyAgICAgIEZpbGVEZXNjcmlwdG9yUHJvdG86OmRlZmF1bHRfaW5zdGFuY2VfLAorICAgICAgRmlsZURlc2NyaXB0b3JQcm90b19vZmZzZXRzXywKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRmlsZURlc2NyaXB0b3JQcm90bywgX2hhc19iaXRzX1swXSksCisgICAgICAtMSwKKyAgICAgIC0xLAorICAgICAgc2l6ZW9mKEZpbGVEZXNjcmlwdG9yUHJvdG8pLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWxlRGVzY3JpcHRvclByb3RvLCBfaW50ZXJuYWxfbWV0YWRhdGFfKSwKKyAgICAgIC0xKTsKKyAgRGVzY3JpcHRvclByb3RvX2Rlc2NyaXB0b3JfID0gZmlsZS0+bWVzc2FnZV90eXBlKDIpOworICBzdGF0aWMgY29uc3QgaW50IERlc2NyaXB0b3JQcm90b19vZmZzZXRzX1sxMF0gPSB7CisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChEZXNjcmlwdG9yUHJvdG8sIG5hbWVfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKERlc2NyaXB0b3JQcm90bywgZmllbGRfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKERlc2NyaXB0b3JQcm90bywgZXh0ZW5zaW9uXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChEZXNjcmlwdG9yUHJvdG8sIG5lc3RlZF90eXBlXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChEZXNjcmlwdG9yUHJvdG8sIGVudW1fdHlwZV8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRGVzY3JpcHRvclByb3RvLCBleHRlbnNpb25fcmFuZ2VfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKERlc2NyaXB0b3JQcm90bywgb25lb2ZfZGVjbF8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRGVzY3JpcHRvclByb3RvLCBvcHRpb25zXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChEZXNjcmlwdG9yUHJvdG8sIHJlc2VydmVkX3JhbmdlXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChEZXNjcmlwdG9yUHJvdG8sIHJlc2VydmVkX25hbWVfKSwKKyAgfTsKKyAgRGVzY3JpcHRvclByb3RvX3JlZmxlY3Rpb25fID0KKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6TmV3R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24oCisgICAgICBEZXNjcmlwdG9yUHJvdG9fZGVzY3JpcHRvcl8sCisgICAgICBEZXNjcmlwdG9yUHJvdG86OmRlZmF1bHRfaW5zdGFuY2VfLAorICAgICAgRGVzY3JpcHRvclByb3RvX29mZnNldHNfLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChEZXNjcmlwdG9yUHJvdG8sIF9oYXNfYml0c19bMF0pLAorICAgICAgLTEsCisgICAgICAtMSwKKyAgICAgIHNpemVvZihEZXNjcmlwdG9yUHJvdG8pLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChEZXNjcmlwdG9yUHJvdG8sIF9pbnRlcm5hbF9tZXRhZGF0YV8pLAorICAgICAgLTEpOworICBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2VfZGVzY3JpcHRvcl8gPSBEZXNjcmlwdG9yUHJvdG9fZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlKDApOworICBzdGF0aWMgY29uc3QgaW50IERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZV9vZmZzZXRzX1syXSA9IHsKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZSwgc3RhcnRfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZSwgZW5kXyksCisgIH07CisgIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZV9yZWZsZWN0aW9uXyA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok5ld0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKAorICAgICAgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlX2Rlc2NyaXB0b3JfLAorICAgICAgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOjpkZWZhdWx0X2luc3RhbmNlXywKKyAgICAgIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZV9vZmZzZXRzXywKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlLCBfaGFzX2JpdHNfWzBdKSwKKyAgICAgIC0xLAorICAgICAgLTEsCisgICAgICBzaXplb2YoRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlKSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlLCBfaW50ZXJuYWxfbWV0YWRhdGFfKSwKKyAgICAgIC0xKTsKKyAgRGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2VfZGVzY3JpcHRvcl8gPSBEZXNjcmlwdG9yUHJvdG9fZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlKDEpOworICBzdGF0aWMgY29uc3QgaW50IERlc2NyaXB0b3JQcm90b19SZXNlcnZlZFJhbmdlX29mZnNldHNfWzJdID0geworICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2UsIHN0YXJ0XyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZSwgZW5kXyksCisgIH07CisgIERlc2NyaXB0b3JQcm90b19SZXNlcnZlZFJhbmdlX3JlZmxlY3Rpb25fID0KKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6TmV3R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24oCisgICAgICBEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZV9kZXNjcmlwdG9yXywKKyAgICAgIERlc2NyaXB0b3JQcm90b19SZXNlcnZlZFJhbmdlOjpkZWZhdWx0X2luc3RhbmNlXywKKyAgICAgIERlc2NyaXB0b3JQcm90b19SZXNlcnZlZFJhbmdlX29mZnNldHNfLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZSwgX2hhc19iaXRzX1swXSksCisgICAgICAtMSwKKyAgICAgIC0xLAorICAgICAgc2l6ZW9mKERlc2NyaXB0b3JQcm90b19SZXNlcnZlZFJhbmdlKSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2UsIF9pbnRlcm5hbF9tZXRhZGF0YV8pLAorICAgICAgLTEpOworICBGaWVsZERlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXyA9IGZpbGUtPm1lc3NhZ2VfdHlwZSgzKTsKKyAgc3RhdGljIGNvbnN0IGludCBGaWVsZERlc2NyaXB0b3JQcm90b19vZmZzZXRzX1sxMF0gPSB7CisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWVsZERlc2NyaXB0b3JQcm90bywgbmFtZV8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRmllbGREZXNjcmlwdG9yUHJvdG8sIG51bWJlcl8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRmllbGREZXNjcmlwdG9yUHJvdG8sIGxhYmVsXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWVsZERlc2NyaXB0b3JQcm90bywgdHlwZV8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRmllbGREZXNjcmlwdG9yUHJvdG8sIHR5cGVfbmFtZV8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRmllbGREZXNjcmlwdG9yUHJvdG8sIGV4dGVuZGVlXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWVsZERlc2NyaXB0b3JQcm90bywgZGVmYXVsdF92YWx1ZV8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRmllbGREZXNjcmlwdG9yUHJvdG8sIG9uZW9mX2luZGV4XyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWVsZERlc2NyaXB0b3JQcm90bywganNvbl9uYW1lXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWVsZERlc2NyaXB0b3JQcm90bywgb3B0aW9uc18pLAorICB9OworICBGaWVsZERlc2NyaXB0b3JQcm90b19yZWZsZWN0aW9uXyA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok5ld0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKAorICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG9fZGVzY3JpcHRvcl8sCisgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZV8sCisgICAgICBGaWVsZERlc2NyaXB0b3JQcm90b19vZmZzZXRzXywKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRmllbGREZXNjcmlwdG9yUHJvdG8sIF9oYXNfYml0c19bMF0pLAorICAgICAgLTEsCisgICAgICAtMSwKKyAgICAgIHNpemVvZihGaWVsZERlc2NyaXB0b3JQcm90byksCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpZWxkRGVzY3JpcHRvclByb3RvLCBfaW50ZXJuYWxfbWV0YWRhdGFfKSwKKyAgICAgIC0xKTsKKyAgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9kZXNjcmlwdG9yXyA9IEZpZWxkRGVzY3JpcHRvclByb3RvX2Rlc2NyaXB0b3JfLT5lbnVtX3R5cGUoMCk7CisgIEZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsX2Rlc2NyaXB0b3JfID0gRmllbGREZXNjcmlwdG9yUHJvdG9fZGVzY3JpcHRvcl8tPmVudW1fdHlwZSgxKTsKKyAgT25lb2ZEZXNjcmlwdG9yUHJvdG9fZGVzY3JpcHRvcl8gPSBmaWxlLT5tZXNzYWdlX3R5cGUoNCk7CisgIHN0YXRpYyBjb25zdCBpbnQgT25lb2ZEZXNjcmlwdG9yUHJvdG9fb2Zmc2V0c19bMV0gPSB7CisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChPbmVvZkRlc2NyaXB0b3JQcm90bywgbmFtZV8pLAorICB9OworICBPbmVvZkRlc2NyaXB0b3JQcm90b19yZWZsZWN0aW9uXyA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok5ld0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKAorICAgICAgT25lb2ZEZXNjcmlwdG9yUHJvdG9fZGVzY3JpcHRvcl8sCisgICAgICBPbmVvZkRlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZV8sCisgICAgICBPbmVvZkRlc2NyaXB0b3JQcm90b19vZmZzZXRzXywKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoT25lb2ZEZXNjcmlwdG9yUHJvdG8sIF9oYXNfYml0c19bMF0pLAorICAgICAgLTEsCisgICAgICAtMSwKKyAgICAgIHNpemVvZihPbmVvZkRlc2NyaXB0b3JQcm90byksCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKE9uZW9mRGVzY3JpcHRvclByb3RvLCBfaW50ZXJuYWxfbWV0YWRhdGFfKSwKKyAgICAgIC0xKTsKKyAgRW51bURlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXyA9IGZpbGUtPm1lc3NhZ2VfdHlwZSg1KTsKKyAgc3RhdGljIGNvbnN0IGludCBFbnVtRGVzY3JpcHRvclByb3RvX29mZnNldHNfWzNdID0geworICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRW51bURlc2NyaXB0b3JQcm90bywgbmFtZV8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRW51bURlc2NyaXB0b3JQcm90bywgdmFsdWVfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEVudW1EZXNjcmlwdG9yUHJvdG8sIG9wdGlvbnNfKSwKKyAgfTsKKyAgRW51bURlc2NyaXB0b3JQcm90b19yZWZsZWN0aW9uXyA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok5ld0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKAorICAgICAgRW51bURlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXywKKyAgICAgIEVudW1EZXNjcmlwdG9yUHJvdG86OmRlZmF1bHRfaW5zdGFuY2VfLAorICAgICAgRW51bURlc2NyaXB0b3JQcm90b19vZmZzZXRzXywKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRW51bURlc2NyaXB0b3JQcm90bywgX2hhc19iaXRzX1swXSksCisgICAgICAtMSwKKyAgICAgIC0xLAorICAgICAgc2l6ZW9mKEVudW1EZXNjcmlwdG9yUHJvdG8pLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChFbnVtRGVzY3JpcHRvclByb3RvLCBfaW50ZXJuYWxfbWV0YWRhdGFfKSwKKyAgICAgIC0xKTsKKyAgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvX2Rlc2NyaXB0b3JfID0gZmlsZS0+bWVzc2FnZV90eXBlKDYpOworICBzdGF0aWMgY29uc3QgaW50IEVudW1WYWx1ZURlc2NyaXB0b3JQcm90b19vZmZzZXRzX1szXSA9IHsKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bywgbmFtZV8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRW51bVZhbHVlRGVzY3JpcHRvclByb3RvLCBudW1iZXJfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bywgb3B0aW9uc18pLAorICB9OworICBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG9fcmVmbGVjdGlvbl8gPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpOZXdHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbigKKyAgICAgIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXywKKyAgICAgIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZV8sCisgICAgICBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG9fb2Zmc2V0c18sCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bywgX2hhc19iaXRzX1swXSksCisgICAgICAtMSwKKyAgICAgIC0xLAorICAgICAgc2l6ZW9mKEVudW1WYWx1ZURlc2NyaXB0b3JQcm90byksCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bywgX2ludGVybmFsX21ldGFkYXRhXyksCisgICAgICAtMSk7CisgIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG9fZGVzY3JpcHRvcl8gPSBmaWxlLT5tZXNzYWdlX3R5cGUoNyk7CisgIHN0YXRpYyBjb25zdCBpbnQgU2VydmljZURlc2NyaXB0b3JQcm90b19vZmZzZXRzX1szXSA9IHsKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKFNlcnZpY2VEZXNjcmlwdG9yUHJvdG8sIG5hbWVfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKFNlcnZpY2VEZXNjcmlwdG9yUHJvdG8sIG1ldGhvZF8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoU2VydmljZURlc2NyaXB0b3JQcm90bywgb3B0aW9uc18pLAorICB9OworICBTZXJ2aWNlRGVzY3JpcHRvclByb3RvX3JlZmxlY3Rpb25fID0KKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6TmV3R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24oCisgICAgICBTZXJ2aWNlRGVzY3JpcHRvclByb3RvX2Rlc2NyaXB0b3JfLAorICAgICAgU2VydmljZURlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZV8sCisgICAgICBTZXJ2aWNlRGVzY3JpcHRvclByb3RvX29mZnNldHNfLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChTZXJ2aWNlRGVzY3JpcHRvclByb3RvLCBfaGFzX2JpdHNfWzBdKSwKKyAgICAgIC0xLAorICAgICAgLTEsCisgICAgICBzaXplb2YoU2VydmljZURlc2NyaXB0b3JQcm90byksCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKFNlcnZpY2VEZXNjcmlwdG9yUHJvdG8sIF9pbnRlcm5hbF9tZXRhZGF0YV8pLAorICAgICAgLTEpOworICBNZXRob2REZXNjcmlwdG9yUHJvdG9fZGVzY3JpcHRvcl8gPSBmaWxlLT5tZXNzYWdlX3R5cGUoOCk7CisgIHN0YXRpYyBjb25zdCBpbnQgTWV0aG9kRGVzY3JpcHRvclByb3RvX29mZnNldHNfWzZdID0geworICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoTWV0aG9kRGVzY3JpcHRvclByb3RvLCBuYW1lXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChNZXRob2REZXNjcmlwdG9yUHJvdG8sIGlucHV0X3R5cGVfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKE1ldGhvZERlc2NyaXB0b3JQcm90bywgb3V0cHV0X3R5cGVfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKE1ldGhvZERlc2NyaXB0b3JQcm90bywgb3B0aW9uc18pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoTWV0aG9kRGVzY3JpcHRvclByb3RvLCBjbGllbnRfc3RyZWFtaW5nXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChNZXRob2REZXNjcmlwdG9yUHJvdG8sIHNlcnZlcl9zdHJlYW1pbmdfKSwKKyAgfTsKKyAgTWV0aG9kRGVzY3JpcHRvclByb3RvX3JlZmxlY3Rpb25fID0KKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6TmV3R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24oCisgICAgICBNZXRob2REZXNjcmlwdG9yUHJvdG9fZGVzY3JpcHRvcl8sCisgICAgICBNZXRob2REZXNjcmlwdG9yUHJvdG86OmRlZmF1bHRfaW5zdGFuY2VfLAorICAgICAgTWV0aG9kRGVzY3JpcHRvclByb3RvX29mZnNldHNfLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChNZXRob2REZXNjcmlwdG9yUHJvdG8sIF9oYXNfYml0c19bMF0pLAorICAgICAgLTEsCisgICAgICAtMSwKKyAgICAgIHNpemVvZihNZXRob2REZXNjcmlwdG9yUHJvdG8pLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChNZXRob2REZXNjcmlwdG9yUHJvdG8sIF9pbnRlcm5hbF9tZXRhZGF0YV8pLAorICAgICAgLTEpOworICBGaWxlT3B0aW9uc19kZXNjcmlwdG9yXyA9IGZpbGUtPm1lc3NhZ2VfdHlwZSg5KTsKKyAgc3RhdGljIGNvbnN0IGludCBGaWxlT3B0aW9uc19vZmZzZXRzX1sxNl0gPSB7CisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWxlT3B0aW9ucywgamF2YV9wYWNrYWdlXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWxlT3B0aW9ucywgamF2YV9vdXRlcl9jbGFzc25hbWVfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpbGVPcHRpb25zLCBqYXZhX211bHRpcGxlX2ZpbGVzXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWxlT3B0aW9ucywgamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2hfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpbGVPcHRpb25zLCBqYXZhX3N0cmluZ19jaGVja191dGY4XyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWxlT3B0aW9ucywgb3B0aW1pemVfZm9yXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWxlT3B0aW9ucywgZ29fcGFja2FnZV8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRmlsZU9wdGlvbnMsIGNjX2dlbmVyaWNfc2VydmljZXNfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpbGVPcHRpb25zLCBqYXZhX2dlbmVyaWNfc2VydmljZXNfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpbGVPcHRpb25zLCBweV9nZW5lcmljX3NlcnZpY2VzXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWxlT3B0aW9ucywgZGVwcmVjYXRlZF8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRmlsZU9wdGlvbnMsIGNjX2VuYWJsZV9hcmVuYXNfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpbGVPcHRpb25zLCBvYmpjX2NsYXNzX3ByZWZpeF8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRmlsZU9wdGlvbnMsIGNzaGFycF9uYW1lc3BhY2VfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpbGVPcHRpb25zLCBqYXZhbmFub191c2VfZGVwcmVjYXRlZF9wYWNrYWdlXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWxlT3B0aW9ucywgdW5pbnRlcnByZXRlZF9vcHRpb25fKSwKKyAgfTsKKyAgRmlsZU9wdGlvbnNfcmVmbGVjdGlvbl8gPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpOZXdHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbigKKyAgICAgIEZpbGVPcHRpb25zX2Rlc2NyaXB0b3JfLAorICAgICAgRmlsZU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2VfLAorICAgICAgRmlsZU9wdGlvbnNfb2Zmc2V0c18sCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpbGVPcHRpb25zLCBfaGFzX2JpdHNfWzBdKSwKKyAgICAgIC0xLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWxlT3B0aW9ucywgX2V4dGVuc2lvbnNfKSwKKyAgICAgIHNpemVvZihGaWxlT3B0aW9ucyksCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpbGVPcHRpb25zLCBfaW50ZXJuYWxfbWV0YWRhdGFfKSwKKyAgICAgIC0xKTsKKyAgRmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlX2Rlc2NyaXB0b3JfID0gRmlsZU9wdGlvbnNfZGVzY3JpcHRvcl8tPmVudW1fdHlwZSgwKTsKKyAgTWVzc2FnZU9wdGlvbnNfZGVzY3JpcHRvcl8gPSBmaWxlLT5tZXNzYWdlX3R5cGUoMTApOworICBzdGF0aWMgY29uc3QgaW50IE1lc3NhZ2VPcHRpb25zX29mZnNldHNfWzVdID0geworICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoTWVzc2FnZU9wdGlvbnMsIG1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0XyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChNZXNzYWdlT3B0aW9ucywgbm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3Nvcl8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoTWVzc2FnZU9wdGlvbnMsIGRlcHJlY2F0ZWRfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKE1lc3NhZ2VPcHRpb25zLCBtYXBfZW50cnlfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKE1lc3NhZ2VPcHRpb25zLCB1bmludGVycHJldGVkX29wdGlvbl8pLAorICB9OworICBNZXNzYWdlT3B0aW9uc19yZWZsZWN0aW9uXyA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok5ld0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKAorICAgICAgTWVzc2FnZU9wdGlvbnNfZGVzY3JpcHRvcl8sCisgICAgICBNZXNzYWdlT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZV8sCisgICAgICBNZXNzYWdlT3B0aW9uc19vZmZzZXRzXywKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoTWVzc2FnZU9wdGlvbnMsIF9oYXNfYml0c19bMF0pLAorICAgICAgLTEsCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKE1lc3NhZ2VPcHRpb25zLCBfZXh0ZW5zaW9uc18pLAorICAgICAgc2l6ZW9mKE1lc3NhZ2VPcHRpb25zKSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoTWVzc2FnZU9wdGlvbnMsIF9pbnRlcm5hbF9tZXRhZGF0YV8pLAorICAgICAgLTEpOworICBGaWVsZE9wdGlvbnNfZGVzY3JpcHRvcl8gPSBmaWxlLT5tZXNzYWdlX3R5cGUoMTEpOworICBzdGF0aWMgY29uc3QgaW50IEZpZWxkT3B0aW9uc19vZmZzZXRzX1s3XSA9IHsKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpZWxkT3B0aW9ucywgY3R5cGVfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpZWxkT3B0aW9ucywgcGFja2VkXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWVsZE9wdGlvbnMsIGpzdHlwZV8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRmllbGRPcHRpb25zLCBsYXp5XyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWVsZE9wdGlvbnMsIGRlcHJlY2F0ZWRfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpZWxkT3B0aW9ucywgd2Vha18pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRmllbGRPcHRpb25zLCB1bmludGVycHJldGVkX29wdGlvbl8pLAorICB9OworICBGaWVsZE9wdGlvbnNfcmVmbGVjdGlvbl8gPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpOZXdHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbigKKyAgICAgIEZpZWxkT3B0aW9uc19kZXNjcmlwdG9yXywKKyAgICAgIEZpZWxkT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZV8sCisgICAgICBGaWVsZE9wdGlvbnNfb2Zmc2V0c18sCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpZWxkT3B0aW9ucywgX2hhc19iaXRzX1swXSksCisgICAgICAtMSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRmllbGRPcHRpb25zLCBfZXh0ZW5zaW9uc18pLAorICAgICAgc2l6ZW9mKEZpZWxkT3B0aW9ucyksCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpZWxkT3B0aW9ucywgX2ludGVybmFsX21ldGFkYXRhXyksCisgICAgICAtMSk7CisgIEZpZWxkT3B0aW9uc19DVHlwZV9kZXNjcmlwdG9yXyA9IEZpZWxkT3B0aW9uc19kZXNjcmlwdG9yXy0+ZW51bV90eXBlKDApOworICBGaWVsZE9wdGlvbnNfSlNUeXBlX2Rlc2NyaXB0b3JfID0gRmllbGRPcHRpb25zX2Rlc2NyaXB0b3JfLT5lbnVtX3R5cGUoMSk7CisgIEVudW1PcHRpb25zX2Rlc2NyaXB0b3JfID0gZmlsZS0+bWVzc2FnZV90eXBlKDEyKTsKKyAgc3RhdGljIGNvbnN0IGludCBFbnVtT3B0aW9uc19vZmZzZXRzX1szXSA9IHsKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEVudW1PcHRpb25zLCBhbGxvd19hbGlhc18pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRW51bU9wdGlvbnMsIGRlcHJlY2F0ZWRfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEVudW1PcHRpb25zLCB1bmludGVycHJldGVkX29wdGlvbl8pLAorICB9OworICBFbnVtT3B0aW9uc19yZWZsZWN0aW9uXyA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok5ld0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKAorICAgICAgRW51bU9wdGlvbnNfZGVzY3JpcHRvcl8sCisgICAgICBFbnVtT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZV8sCisgICAgICBFbnVtT3B0aW9uc19vZmZzZXRzXywKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRW51bU9wdGlvbnMsIF9oYXNfYml0c19bMF0pLAorICAgICAgLTEsCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEVudW1PcHRpb25zLCBfZXh0ZW5zaW9uc18pLAorICAgICAgc2l6ZW9mKEVudW1PcHRpb25zKSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRW51bU9wdGlvbnMsIF9pbnRlcm5hbF9tZXRhZGF0YV8pLAorICAgICAgLTEpOworICBFbnVtVmFsdWVPcHRpb25zX2Rlc2NyaXB0b3JfID0gZmlsZS0+bWVzc2FnZV90eXBlKDEzKTsKKyAgc3RhdGljIGNvbnN0IGludCBFbnVtVmFsdWVPcHRpb25zX29mZnNldHNfWzJdID0geworICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRW51bVZhbHVlT3B0aW9ucywgZGVwcmVjYXRlZF8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRW51bVZhbHVlT3B0aW9ucywgdW5pbnRlcnByZXRlZF9vcHRpb25fKSwKKyAgfTsKKyAgRW51bVZhbHVlT3B0aW9uc19yZWZsZWN0aW9uXyA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok5ld0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKAorICAgICAgRW51bVZhbHVlT3B0aW9uc19kZXNjcmlwdG9yXywKKyAgICAgIEVudW1WYWx1ZU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2VfLAorICAgICAgRW51bVZhbHVlT3B0aW9uc19vZmZzZXRzXywKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRW51bVZhbHVlT3B0aW9ucywgX2hhc19iaXRzX1swXSksCisgICAgICAtMSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRW51bVZhbHVlT3B0aW9ucywgX2V4dGVuc2lvbnNfKSwKKyAgICAgIHNpemVvZihFbnVtVmFsdWVPcHRpb25zKSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRW51bVZhbHVlT3B0aW9ucywgX2ludGVybmFsX21ldGFkYXRhXyksCisgICAgICAtMSk7CisgIFNlcnZpY2VPcHRpb25zX2Rlc2NyaXB0b3JfID0gZmlsZS0+bWVzc2FnZV90eXBlKDE0KTsKKyAgc3RhdGljIGNvbnN0IGludCBTZXJ2aWNlT3B0aW9uc19vZmZzZXRzX1syXSA9IHsKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKFNlcnZpY2VPcHRpb25zLCBkZXByZWNhdGVkXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChTZXJ2aWNlT3B0aW9ucywgdW5pbnRlcnByZXRlZF9vcHRpb25fKSwKKyAgfTsKKyAgU2VydmljZU9wdGlvbnNfcmVmbGVjdGlvbl8gPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpOZXdHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbigKKyAgICAgIFNlcnZpY2VPcHRpb25zX2Rlc2NyaXB0b3JfLAorICAgICAgU2VydmljZU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2VfLAorICAgICAgU2VydmljZU9wdGlvbnNfb2Zmc2V0c18sCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKFNlcnZpY2VPcHRpb25zLCBfaGFzX2JpdHNfWzBdKSwKKyAgICAgIC0xLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChTZXJ2aWNlT3B0aW9ucywgX2V4dGVuc2lvbnNfKSwKKyAgICAgIHNpemVvZihTZXJ2aWNlT3B0aW9ucyksCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKFNlcnZpY2VPcHRpb25zLCBfaW50ZXJuYWxfbWV0YWRhdGFfKSwKKyAgICAgIC0xKTsKKyAgTWV0aG9kT3B0aW9uc19kZXNjcmlwdG9yXyA9IGZpbGUtPm1lc3NhZ2VfdHlwZSgxNSk7CisgIHN0YXRpYyBjb25zdCBpbnQgTWV0aG9kT3B0aW9uc19vZmZzZXRzX1syXSA9IHsKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKE1ldGhvZE9wdGlvbnMsIGRlcHJlY2F0ZWRfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKE1ldGhvZE9wdGlvbnMsIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXyksCisgIH07CisgIE1ldGhvZE9wdGlvbnNfcmVmbGVjdGlvbl8gPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpOZXdHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbigKKyAgICAgIE1ldGhvZE9wdGlvbnNfZGVzY3JpcHRvcl8sCisgICAgICBNZXRob2RPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlXywKKyAgICAgIE1ldGhvZE9wdGlvbnNfb2Zmc2V0c18sCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKE1ldGhvZE9wdGlvbnMsIF9oYXNfYml0c19bMF0pLAorICAgICAgLTEsCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKE1ldGhvZE9wdGlvbnMsIF9leHRlbnNpb25zXyksCisgICAgICBzaXplb2YoTWV0aG9kT3B0aW9ucyksCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKE1ldGhvZE9wdGlvbnMsIF9pbnRlcm5hbF9tZXRhZGF0YV8pLAorICAgICAgLTEpOworICBVbmludGVycHJldGVkT3B0aW9uX2Rlc2NyaXB0b3JfID0gZmlsZS0+bWVzc2FnZV90eXBlKDE2KTsKKyAgc3RhdGljIGNvbnN0IGludCBVbmludGVycHJldGVkT3B0aW9uX29mZnNldHNfWzddID0geworICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoVW5pbnRlcnByZXRlZE9wdGlvbiwgbmFtZV8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoVW5pbnRlcnByZXRlZE9wdGlvbiwgaWRlbnRpZmllcl92YWx1ZV8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoVW5pbnRlcnByZXRlZE9wdGlvbiwgcG9zaXRpdmVfaW50X3ZhbHVlXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChVbmludGVycHJldGVkT3B0aW9uLCBuZWdhdGl2ZV9pbnRfdmFsdWVfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKFVuaW50ZXJwcmV0ZWRPcHRpb24sIGRvdWJsZV92YWx1ZV8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoVW5pbnRlcnByZXRlZE9wdGlvbiwgc3RyaW5nX3ZhbHVlXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChVbmludGVycHJldGVkT3B0aW9uLCBhZ2dyZWdhdGVfdmFsdWVfKSwKKyAgfTsKKyAgVW5pbnRlcnByZXRlZE9wdGlvbl9yZWZsZWN0aW9uXyA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok5ld0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKAorICAgICAgVW5pbnRlcnByZXRlZE9wdGlvbl9kZXNjcmlwdG9yXywKKyAgICAgIFVuaW50ZXJwcmV0ZWRPcHRpb246OmRlZmF1bHRfaW5zdGFuY2VfLAorICAgICAgVW5pbnRlcnByZXRlZE9wdGlvbl9vZmZzZXRzXywKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoVW5pbnRlcnByZXRlZE9wdGlvbiwgX2hhc19iaXRzX1swXSksCisgICAgICAtMSwKKyAgICAgIC0xLAorICAgICAgc2l6ZW9mKFVuaW50ZXJwcmV0ZWRPcHRpb24pLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChVbmludGVycHJldGVkT3B0aW9uLCBfaW50ZXJuYWxfbWV0YWRhdGFfKSwKKyAgICAgIC0xKTsKKyAgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydF9kZXNjcmlwdG9yXyA9IFVuaW50ZXJwcmV0ZWRPcHRpb25fZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlKDApOworICBzdGF0aWMgY29uc3QgaW50IFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnRfb2Zmc2V0c19bMl0gPSB7CisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0LCBuYW1lX3BhcnRfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQsIGlzX2V4dGVuc2lvbl8pLAorICB9OworICBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0X3JlZmxlY3Rpb25fID0KKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6TmV3R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24oCisgICAgICBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0X2Rlc2NyaXB0b3JfLAorICAgICAgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6ZGVmYXVsdF9pbnN0YW5jZV8sCisgICAgICBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0X29mZnNldHNfLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0LCBfaGFzX2JpdHNfWzBdKSwKKyAgICAgIC0xLAorICAgICAgLTEsCisgICAgICBzaXplb2YoVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydCksCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQsIF9pbnRlcm5hbF9tZXRhZGF0YV8pLAorICAgICAgLTEpOworICBTb3VyY2VDb2RlSW5mb19kZXNjcmlwdG9yXyA9IGZpbGUtPm1lc3NhZ2VfdHlwZSgxNyk7CisgIHN0YXRpYyBjb25zdCBpbnQgU291cmNlQ29kZUluZm9fb2Zmc2V0c19bMV0gPSB7CisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChTb3VyY2VDb2RlSW5mbywgbG9jYXRpb25fKSwKKyAgfTsKKyAgU291cmNlQ29kZUluZm9fcmVmbGVjdGlvbl8gPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpOZXdHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbigKKyAgICAgIFNvdXJjZUNvZGVJbmZvX2Rlc2NyaXB0b3JfLAorICAgICAgU291cmNlQ29kZUluZm86OmRlZmF1bHRfaW5zdGFuY2VfLAorICAgICAgU291cmNlQ29kZUluZm9fb2Zmc2V0c18sCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKFNvdXJjZUNvZGVJbmZvLCBfaGFzX2JpdHNfWzBdKSwKKyAgICAgIC0xLAorICAgICAgLTEsCisgICAgICBzaXplb2YoU291cmNlQ29kZUluZm8pLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChTb3VyY2VDb2RlSW5mbywgX2ludGVybmFsX21ldGFkYXRhXyksCisgICAgICAtMSk7CisgIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uX2Rlc2NyaXB0b3JfID0gU291cmNlQ29kZUluZm9fZGVzY3JpcHRvcl8tPm5lc3RlZF90eXBlKDApOworICBzdGF0aWMgY29uc3QgaW50IFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uX29mZnNldHNfWzVdID0geworICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoU291cmNlQ29kZUluZm9fTG9jYXRpb24sIHBhdGhfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uLCBzcGFuXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbiwgbGVhZGluZ19jb21tZW50c18pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoU291cmNlQ29kZUluZm9fTG9jYXRpb24sIHRyYWlsaW5nX2NvbW1lbnRzXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbiwgbGVhZGluZ19kZXRhY2hlZF9jb21tZW50c18pLAorICB9OworICBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbl9yZWZsZWN0aW9uXyA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok5ld0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKAorICAgICAgU291cmNlQ29kZUluZm9fTG9jYXRpb25fZGVzY3JpcHRvcl8sCisgICAgICBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6ZGVmYXVsdF9pbnN0YW5jZV8sCisgICAgICBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbl9vZmZzZXRzXywKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoU291cmNlQ29kZUluZm9fTG9jYXRpb24sIF9oYXNfYml0c19bMF0pLAorICAgICAgLTEsCisgICAgICAtMSwKKyAgICAgIHNpemVvZihTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbiksCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uLCBfaW50ZXJuYWxfbWV0YWRhdGFfKSwKKyAgICAgIC0xKTsKKyAgR2VuZXJhdGVkQ29kZUluZm9fZGVzY3JpcHRvcl8gPSBmaWxlLT5tZXNzYWdlX3R5cGUoMTgpOworICBzdGF0aWMgY29uc3QgaW50IEdlbmVyYXRlZENvZGVJbmZvX29mZnNldHNfWzFdID0geworICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoR2VuZXJhdGVkQ29kZUluZm8sIGFubm90YXRpb25fKSwKKyAgfTsKKyAgR2VuZXJhdGVkQ29kZUluZm9fcmVmbGVjdGlvbl8gPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpOZXdHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbigKKyAgICAgIEdlbmVyYXRlZENvZGVJbmZvX2Rlc2NyaXB0b3JfLAorICAgICAgR2VuZXJhdGVkQ29kZUluZm86OmRlZmF1bHRfaW5zdGFuY2VfLAorICAgICAgR2VuZXJhdGVkQ29kZUluZm9fb2Zmc2V0c18sCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEdlbmVyYXRlZENvZGVJbmZvLCBfaGFzX2JpdHNfWzBdKSwKKyAgICAgIC0xLAorICAgICAgLTEsCisgICAgICBzaXplb2YoR2VuZXJhdGVkQ29kZUluZm8pLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChHZW5lcmF0ZWRDb2RlSW5mbywgX2ludGVybmFsX21ldGFkYXRhXyksCisgICAgICAtMSk7CisgIEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb25fZGVzY3JpcHRvcl8gPSBHZW5lcmF0ZWRDb2RlSW5mb19kZXNjcmlwdG9yXy0+bmVzdGVkX3R5cGUoMCk7CisgIHN0YXRpYyBjb25zdCBpbnQgR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbl9vZmZzZXRzX1s0XSA9IHsKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb24sIHBhdGhfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb24sIHNvdXJjZV9maWxlXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uLCBiZWdpbl8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbiwgZW5kXyksCisgIH07CisgIEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb25fcmVmbGVjdGlvbl8gPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpOZXdHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbigKKyAgICAgIEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb25fZGVzY3JpcHRvcl8sCisgICAgICBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uOjpkZWZhdWx0X2luc3RhbmNlXywKKyAgICAgIEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb25fb2Zmc2V0c18sCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb24sIF9oYXNfYml0c19bMF0pLAorICAgICAgLTEsCisgICAgICAtMSwKKyAgICAgIHNpemVvZihHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uKSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbiwgX2ludGVybmFsX21ldGFkYXRhXyksCisgICAgICAtMSk7Cit9CisKK25hbWVzcGFjZSB7CisKK0dPT0dMRV9QUk9UT0JVRl9ERUNMQVJFX09OQ0UocHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNfb25jZV8pOworaW5saW5lIHZvaWQgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCkgeworICA6Omdvb2dsZTo6cHJvdG9idWY6Okdvb2dsZU9uY2VJbml0KCZwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc19vbmNlXywKKyAgICAgICAgICAgICAgICAgJnByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8pOworfQorCit2b2lkIHByb3RvYnVmX1JlZ2lzdGVyVHlwZXMoY29uc3QgOjpzdGQ6OnN0cmluZyYpIHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZUZhY3Rvcnk6OkludGVybmFsUmVnaXN0ZXJHZW5lcmF0ZWRNZXNzYWdlKAorICAgICAgRmlsZURlc2NyaXB0b3JTZXRfZGVzY3JpcHRvcl8sICZGaWxlRGVzY3JpcHRvclNldDo6ZGVmYXVsdF9pbnN0YW5jZSgpKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZE1lc3NhZ2UoCisgICAgICBGaWxlRGVzY3JpcHRvclByb3RvX2Rlc2NyaXB0b3JfLCAmRmlsZURlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZSgpKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZE1lc3NhZ2UoCisgICAgICBEZXNjcmlwdG9yUHJvdG9fZGVzY3JpcHRvcl8sICZEZXNjcmlwdG9yUHJvdG86OmRlZmF1bHRfaW5zdGFuY2UoKSk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZUZhY3Rvcnk6OkludGVybmFsUmVnaXN0ZXJHZW5lcmF0ZWRNZXNzYWdlKAorICAgICAgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlX2Rlc2NyaXB0b3JfLCAmRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOjpkZWZhdWx0X2luc3RhbmNlKCkpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VGYWN0b3J5OjpJbnRlcm5hbFJlZ2lzdGVyR2VuZXJhdGVkTWVzc2FnZSgKKyAgICAgIERlc2NyaXB0b3JQcm90b19SZXNlcnZlZFJhbmdlX2Rlc2NyaXB0b3JfLCAmRGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2U6OmRlZmF1bHRfaW5zdGFuY2UoKSk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZUZhY3Rvcnk6OkludGVybmFsUmVnaXN0ZXJHZW5lcmF0ZWRNZXNzYWdlKAorICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG9fZGVzY3JpcHRvcl8sICZGaWVsZERlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZSgpKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZE1lc3NhZ2UoCisgICAgICBPbmVvZkRlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXywgJk9uZW9mRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlKCkpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VGYWN0b3J5OjpJbnRlcm5hbFJlZ2lzdGVyR2VuZXJhdGVkTWVzc2FnZSgKKyAgICAgIEVudW1EZXNjcmlwdG9yUHJvdG9fZGVzY3JpcHRvcl8sICZFbnVtRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlKCkpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VGYWN0b3J5OjpJbnRlcm5hbFJlZ2lzdGVyR2VuZXJhdGVkTWVzc2FnZSgKKyAgICAgIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXywgJkVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZSgpKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZE1lc3NhZ2UoCisgICAgICBTZXJ2aWNlRGVzY3JpcHRvclByb3RvX2Rlc2NyaXB0b3JfLCAmU2VydmljZURlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZSgpKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZE1lc3NhZ2UoCisgICAgICBNZXRob2REZXNjcmlwdG9yUHJvdG9fZGVzY3JpcHRvcl8sICZNZXRob2REZXNjcmlwdG9yUHJvdG86OmRlZmF1bHRfaW5zdGFuY2UoKSk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZUZhY3Rvcnk6OkludGVybmFsUmVnaXN0ZXJHZW5lcmF0ZWRNZXNzYWdlKAorICAgICAgRmlsZU9wdGlvbnNfZGVzY3JpcHRvcl8sICZGaWxlT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZSgpKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZE1lc3NhZ2UoCisgICAgICBNZXNzYWdlT3B0aW9uc19kZXNjcmlwdG9yXywgJk1lc3NhZ2VPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlKCkpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VGYWN0b3J5OjpJbnRlcm5hbFJlZ2lzdGVyR2VuZXJhdGVkTWVzc2FnZSgKKyAgICAgIEZpZWxkT3B0aW9uc19kZXNjcmlwdG9yXywgJkZpZWxkT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZSgpKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZE1lc3NhZ2UoCisgICAgICBFbnVtT3B0aW9uc19kZXNjcmlwdG9yXywgJkVudW1PcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlKCkpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VGYWN0b3J5OjpJbnRlcm5hbFJlZ2lzdGVyR2VuZXJhdGVkTWVzc2FnZSgKKyAgICAgIEVudW1WYWx1ZU9wdGlvbnNfZGVzY3JpcHRvcl8sICZFbnVtVmFsdWVPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlKCkpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VGYWN0b3J5OjpJbnRlcm5hbFJlZ2lzdGVyR2VuZXJhdGVkTWVzc2FnZSgKKyAgICAgIFNlcnZpY2VPcHRpb25zX2Rlc2NyaXB0b3JfLCAmU2VydmljZU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2UoKSk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZUZhY3Rvcnk6OkludGVybmFsUmVnaXN0ZXJHZW5lcmF0ZWRNZXNzYWdlKAorICAgICAgTWV0aG9kT3B0aW9uc19kZXNjcmlwdG9yXywgJk1ldGhvZE9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2UoKSk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZUZhY3Rvcnk6OkludGVybmFsUmVnaXN0ZXJHZW5lcmF0ZWRNZXNzYWdlKAorICAgICAgVW5pbnRlcnByZXRlZE9wdGlvbl9kZXNjcmlwdG9yXywgJlVuaW50ZXJwcmV0ZWRPcHRpb246OmRlZmF1bHRfaW5zdGFuY2UoKSk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZUZhY3Rvcnk6OkludGVybmFsUmVnaXN0ZXJHZW5lcmF0ZWRNZXNzYWdlKAorICAgICAgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydF9kZXNjcmlwdG9yXywgJlVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQ6OmRlZmF1bHRfaW5zdGFuY2UoKSk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZUZhY3Rvcnk6OkludGVybmFsUmVnaXN0ZXJHZW5lcmF0ZWRNZXNzYWdlKAorICAgICAgU291cmNlQ29kZUluZm9fZGVzY3JpcHRvcl8sICZTb3VyY2VDb2RlSW5mbzo6ZGVmYXVsdF9pbnN0YW5jZSgpKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZE1lc3NhZ2UoCisgICAgICBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbl9kZXNjcmlwdG9yXywgJlNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpkZWZhdWx0X2luc3RhbmNlKCkpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VGYWN0b3J5OjpJbnRlcm5hbFJlZ2lzdGVyR2VuZXJhdGVkTWVzc2FnZSgKKyAgICAgIEdlbmVyYXRlZENvZGVJbmZvX2Rlc2NyaXB0b3JfLCAmR2VuZXJhdGVkQ29kZUluZm86OmRlZmF1bHRfaW5zdGFuY2UoKSk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZUZhY3Rvcnk6OkludGVybmFsUmVnaXN0ZXJHZW5lcmF0ZWRNZXNzYWdlKAorICAgICAgR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbl9kZXNjcmlwdG9yXywgJkdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb246OmRlZmF1bHRfaW5zdGFuY2UoKSk7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCit2b2lkIHByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpIHsKKyAgZGVsZXRlIEZpbGVEZXNjcmlwdG9yU2V0OjpkZWZhdWx0X2luc3RhbmNlXzsKKyAgZGVsZXRlIEZpbGVEZXNjcmlwdG9yU2V0X3JlZmxlY3Rpb25fOworICBkZWxldGUgRmlsZURlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZV87CisgIGRlbGV0ZSBGaWxlRGVzY3JpcHRvclByb3RvX3JlZmxlY3Rpb25fOworICBkZWxldGUgRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlXzsKKyAgZGVsZXRlIERlc2NyaXB0b3JQcm90b19yZWZsZWN0aW9uXzsKKyAgZGVsZXRlIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZTo6ZGVmYXVsdF9pbnN0YW5jZV87CisgIGRlbGV0ZSBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2VfcmVmbGVjdGlvbl87CisgIGRlbGV0ZSBEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZTo6ZGVmYXVsdF9pbnN0YW5jZV87CisgIGRlbGV0ZSBEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZV9yZWZsZWN0aW9uXzsKKyAgZGVsZXRlIEZpZWxkRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlXzsKKyAgZGVsZXRlIEZpZWxkRGVzY3JpcHRvclByb3RvX3JlZmxlY3Rpb25fOworICBkZWxldGUgT25lb2ZEZXNjcmlwdG9yUHJvdG86OmRlZmF1bHRfaW5zdGFuY2VfOworICBkZWxldGUgT25lb2ZEZXNjcmlwdG9yUHJvdG9fcmVmbGVjdGlvbl87CisgIGRlbGV0ZSBFbnVtRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlXzsKKyAgZGVsZXRlIEVudW1EZXNjcmlwdG9yUHJvdG9fcmVmbGVjdGlvbl87CisgIGRlbGV0ZSBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86OmRlZmF1bHRfaW5zdGFuY2VfOworICBkZWxldGUgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvX3JlZmxlY3Rpb25fOworICBkZWxldGUgU2VydmljZURlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZV87CisgIGRlbGV0ZSBTZXJ2aWNlRGVzY3JpcHRvclByb3RvX3JlZmxlY3Rpb25fOworICBkZWxldGUgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlXzsKKyAgZGVsZXRlIE1ldGhvZERlc2NyaXB0b3JQcm90b19yZWZsZWN0aW9uXzsKKyAgZGVsZXRlIEZpbGVPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlXzsKKyAgZGVsZXRlIEZpbGVPcHRpb25zX3JlZmxlY3Rpb25fOworICBkZWxldGUgTWVzc2FnZU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2VfOworICBkZWxldGUgTWVzc2FnZU9wdGlvbnNfcmVmbGVjdGlvbl87CisgIGRlbGV0ZSBGaWVsZE9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2VfOworICBkZWxldGUgRmllbGRPcHRpb25zX3JlZmxlY3Rpb25fOworICBkZWxldGUgRW51bU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2VfOworICBkZWxldGUgRW51bU9wdGlvbnNfcmVmbGVjdGlvbl87CisgIGRlbGV0ZSBFbnVtVmFsdWVPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlXzsKKyAgZGVsZXRlIEVudW1WYWx1ZU9wdGlvbnNfcmVmbGVjdGlvbl87CisgIGRlbGV0ZSBTZXJ2aWNlT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZV87CisgIGRlbGV0ZSBTZXJ2aWNlT3B0aW9uc19yZWZsZWN0aW9uXzsKKyAgZGVsZXRlIE1ldGhvZE9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2VfOworICBkZWxldGUgTWV0aG9kT3B0aW9uc19yZWZsZWN0aW9uXzsKKyAgZGVsZXRlIFVuaW50ZXJwcmV0ZWRPcHRpb246OmRlZmF1bHRfaW5zdGFuY2VfOworICBkZWxldGUgVW5pbnRlcnByZXRlZE9wdGlvbl9yZWZsZWN0aW9uXzsKKyAgZGVsZXRlIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQ6OmRlZmF1bHRfaW5zdGFuY2VfOworICBkZWxldGUgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydF9yZWZsZWN0aW9uXzsKKyAgZGVsZXRlIFNvdXJjZUNvZGVJbmZvOjpkZWZhdWx0X2luc3RhbmNlXzsKKyAgZGVsZXRlIFNvdXJjZUNvZGVJbmZvX3JlZmxlY3Rpb25fOworICBkZWxldGUgU291cmNlQ29kZUluZm9fTG9jYXRpb246OmRlZmF1bHRfaW5zdGFuY2VfOworICBkZWxldGUgU291cmNlQ29kZUluZm9fTG9jYXRpb25fcmVmbGVjdGlvbl87CisgIGRlbGV0ZSBHZW5lcmF0ZWRDb2RlSW5mbzo6ZGVmYXVsdF9pbnN0YW5jZV87CisgIGRlbGV0ZSBHZW5lcmF0ZWRDb2RlSW5mb19yZWZsZWN0aW9uXzsKKyAgZGVsZXRlIEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb246OmRlZmF1bHRfaW5zdGFuY2VfOworICBkZWxldGUgR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbl9yZWZsZWN0aW9uXzsKK30KKwordm9pZCBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCkgeworICBzdGF0aWMgYm9vbCBhbHJlYWR5X2hlcmUgPSBmYWxzZTsKKyAgaWYgKGFscmVhZHlfaGVyZSkgcmV0dXJuOworICBhbHJlYWR5X2hlcmUgPSB0cnVlOworICBHT09HTEVfUFJPVE9CVUZfVkVSSUZZX1ZFUlNJT047CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUG9vbDo6SW50ZXJuYWxBZGRHZW5lcmF0ZWRGaWxlKAorICAgICJcbiBnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90b1wwMjJcMDE3Z29vZyIKKyAgICAibGUucHJvdG9idWZcIkdcblwwMjFGaWxlRGVzY3JpcHRvclNldFwwMjIyXG5cMDA0ZmlsZSIKKyAgICAiXDAzMFwwMDEgXDAwMyhcMDEzMiQuZ29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUCIKKyAgICAicm90b1wiXDMzM1wwMDNcblwwMjNGaWxlRGVzY3JpcHRvclByb3RvXDAyMlwwMTRcblwwMDRuYW1lXDAzMFwwMDEgXDAwMSIKKyAgICAiKFx0XDAyMlwwMTdcblwwMDdwYWNrYWdlXDAzMFwwMDIgXDAwMShcdFwwMjJcMDIyXG5cbmRlcGVuZGVuY3lcMDMwXDAwMyBcMDAzKFx0XDAyMiIKKyAgICAiXDAzMVxuXDAyMXB1YmxpY19kZXBlbmRlbmN5XDAzMFxuIFwwMDMoXDAwNVwwMjJcMDI3XG5cMDE3d2Vha19kZXBlbiIKKyAgICAiZGVuY3lcMDMwXDAxMyBcMDAzKFwwMDVcMDIyNlxuXDAxNG1lc3NhZ2VfdHlwZVwwMzBcMDA0IFwwMDMoXDAxMzIgLmdvb2ciCisgICAgImxlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b1wwMjI3XG5cdGVudW1fdHlwZSIKKyAgICAiXDAzMFwwMDUgXDAwMyhcMDEzMiQuZ29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUCIKKyAgICAicm90b1wwMjI4XG5cMDA3c2VydmljZVwwMzBcMDA2IFwwMDMoXDAxMzJcJy5nb29nbGUucHJvdG9idWYuIgorICAgICJTZXJ2aWNlRGVzY3JpcHRvclByb3RvXDAyMjhcblx0ZXh0ZW5zaW9uXDAzMFwwMDcgXDAwMygiCisgICAgIlwwMTMyJS5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8iCisgICAgIlwwMjItXG5cMDA3b3B0aW9uc1wwMzBcMDEwIFwwMDEoXDAxMzJcMDM0Lmdvb2dsZS5wcm90b2J1Zi5GaWxlIgorICAgICJPcHRpb25zXDAyMjlcblwwMjBzb3VyY2VfY29kZV9pbmZvXDAzMFx0IFwwMDEoXDAxMzJcMDM3Lmdvb2ciCisgICAgImxlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvXDAyMlwwMTZcblwwMDZzeW50YXhcMDMwXDAxNCBcMDAxIgorICAgICIoXHRcIlwzNjBcMDA0XG5cMDE3RGVzY3JpcHRvclByb3RvXDAyMlwwMTRcblwwMDRuYW1lXDAzMFwwMDEgXDAwMShcdFwwMjI0XG5cMDA1IgorICAgICJmaWVsZFwwMzBcMDAyIFwwMDMoXDAxMzIlLmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyIgorICAgICJpcHRvclByb3RvXDAyMjhcblx0ZXh0ZW5zaW9uXDAzMFwwMDYgXDAwMyhcMDEzMiUuZ29vZ2xlLnAiCisgICAgInJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG9cMDIyNVxuXDAxM25lc3RlZF90IgorICAgICJ5cGVcMDMwXDAwMyBcMDAzKFwwMTMyIC5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByIgorICAgICJvdG9cMDIyN1xuXHRlbnVtX3R5cGVcMDMwXDAwNCBcMDAzKFwwMTMyJC5nb29nbGUucHJvdG9idWYiCisgICAgIi5FbnVtRGVzY3JpcHRvclByb3RvXDAyMkhcblwwMTdleHRlbnNpb25fcmFuZ2VcMDMwIgorICAgICJcMDA1IFwwMDMoXDAxMzIvLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uIgorICAgICJFeHRlbnNpb25SYW5nZVwwMjI5XG5cbm9uZW9mX2RlY2xcMDMwXDAxMCBcMDAzKFwwMTMyJS5nb28iCisgICAgImdsZS5wcm90b2J1Zi5PbmVvZkRlc2NyaXB0b3JQcm90b1wwMjIwXG5cMDA3b3B0IgorICAgICJpb25zXDAzMFwwMDcgXDAwMShcMDEzMlwwMzcuZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpIgorICAgICJvbnNcMDIyRlxuXDAxNnJlc2VydmVkX3JhbmdlXDAzMFx0IFwwMDMoXDAxMzIuLmdvb2dsZS5wcm8iCisgICAgInRvYnVmLkRlc2NyaXB0b3JQcm90by5SZXNlcnZlZFJhbmdlXDAyMlwwMjVcblxyciIKKyAgICAiZXNlcnZlZF9uYW1lXDAzMFxuIFwwMDMoXHRcMDMyLFxuXDAxNkV4dGVuc2lvblJhbmdlXDAyMlxyXG5cMDA1IgorICAgICJzdGFydFwwMzBcMDAxIFwwMDEoXDAwNVwwMjJcMDEzXG5cMDAzZW5kXDAzMFwwMDIgXDAwMShcMDA1XDAzMitcblxyUmVzZXJ2ZWRSYW5nIgorICAgICJlXDAyMlxyXG5cMDA1c3RhcnRcMDMwXDAwMSBcMDAxKFwwMDVcMDIyXDAxM1xuXDAwM2VuZFwwMzBcMDAyIFwwMDEoXDAwNVwiXDI3NFwwMDVcblwwMjRGaWVsZEQiCisgICAgImVzY3JpcHRvclByb3RvXDAyMlwwMTRcblwwMDRuYW1lXDAzMFwwMDEgXDAwMShcdFwwMjJcMDE2XG5cMDA2bnVtYmVyXDAzMFwwMDMiCisgICAgIiBcMDAxKFwwMDVcMDIyOlxuXDAwNWxhYmVsXDAzMFwwMDQgXDAwMShcMDE2MisuZ29vZ2xlLnByb3RvYnVmLkZpIgorICAgICJlbGREZXNjcmlwdG9yUHJvdG8uTGFiZWxcMDIyOFxuXDAwNHR5cGVcMDMwXDAwNSBcMDAxKFwwMTYyKiIKKyAgICAiLmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5UeSIKKyAgICAicGVcMDIyXDAyMVxuXHR0eXBlX25hbWVcMDMwXDAwNiBcMDAxKFx0XDAyMlwwMjBcblwwMTBleHRlbmRlZVwwMzBcMDAyIFwwMDEoXHRcMDIyIgorICAgICJcMDI1XG5ccmRlZmF1bHRfdmFsdWVcMDMwXDAwNyBcMDAxKFx0XDAyMlwwMjNcblwwMTNvbmVvZl9pbmRleFwwMzBcdCAiCisgICAgIlwwMDEoXDAwNVwwMjJcMDIxXG5cdGpzb25fbmFtZVwwMzBcbiBcMDAxKFx0XDAyMi5cblwwMDdvcHRpb25zXDAzMFwwMTAgXDAwMShcMDEzMiIKKyAgICAiXDAzNS5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zXCJcMjY2XDAwMlxuXDAwNFR5cGVcMDIyIgorICAgICJcMDE3XG5cMDEzVFlQRV9ET1VCTEVcMDIwXDAwMVwwMjJcMDE2XG5cblRZUEVfRkxPQVRcMDIwXDAwMlwwMjJcMDE2XG5cblRZUEUiCisgICAgIl9JTlQ2NFwwMjBcMDAzXDAyMlwwMTdcblwwMTNUWVBFX1VJTlQ2NFwwMjBcMDA0XDAyMlwwMTZcblxuVFlQRV9JTlQzMlwwMjAiCisgICAgIlwwMDVcMDIyXDAyMFxuXDAxNFRZUEVfRklYRUQ2NFwwMjBcMDA2XDAyMlwwMjBcblwwMTRUWVBFX0ZJWEVEMzJcMDIwXDAwN1wwMjJcclxuIgorICAgICJcdFRZUEVfQk9PTFwwMjBcMDEwXDAyMlwwMTdcblwwMTNUWVBFX1NUUklOR1wwMjBcdFwwMjJcMDE2XG5cblRZUEVfR1IiCisgICAgIk9VUFwwMjBcblwwMjJcMDIwXG5cMDE0VFlQRV9NRVNTQUdFXDAyMFwwMTNcMDIyXDAxNlxuXG5UWVBFX0JZVEVTXDAyMFwwMTRcMDIyIgorICAgICJcMDE3XG5cMDEzVFlQRV9VSU5UMzJcMDIwXHJcMDIyXHJcblx0VFlQRV9FTlVNXDAyMFwwMTZcMDIyXDAyMVxuXHJUWVBFXyIKKyAgICAiU0ZJWEVEMzJcMDIwXDAxN1wwMjJcMDIxXG5cclRZUEVfU0ZJWEVENjRcMDIwXDAyMFwwMjJcMDE3XG5cMDEzVFlQRV9TSSIKKyAgICAiTlQzMlwwMjBcMDIxXDAyMlwwMTdcblwwMTNUWVBFX1NJTlQ2NFwwMjBcMDIyXCJDXG5cMDA1TGFiZWxcMDIyXDAyMlxuXDAxNkxBQkUiCisgICAgIkxfT1BUSU9OQUxcMDIwXDAwMVwwMjJcMDIyXG5cMDE2TEFCRUxfUkVRVUlSRURcMDIwXDAwMlwwMjJcMDIyXG5cMDE2TEFCRSIKKyAgICAiTF9SRVBFQVRFRFwwMjBcMDAzXCIkXG5cMDI0T25lb2ZEZXNjcmlwdG9yUHJvdG9cMDIyXDAxNFxuXDAwNCIKKyAgICAibmFtZVwwMzBcMDAxIFwwMDEoXHRcIlwyMTRcMDAxXG5cMDIzRW51bURlc2NyaXB0b3JQcm90b1wwMjJcMDE0XG5cMDA0bmEiCisgICAgIm1lXDAzMFwwMDEgXDAwMShcdFwwMjI4XG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAzKFwwMTMyKS5nb29nbGUucHJvdG9idSIKKyAgICAiZi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG9cMDIyLVxuXDAwN29wdGlvbnNcMDMwXDAwMyAiCisgICAgIlwwMDEoXDAxMzJcMDM0Lmdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9uc1wibFxuXDAzMEVudSIKKyAgICAibVZhbHVlRGVzY3JpcHRvclByb3RvXDAyMlwwMTRcblwwMDRuYW1lXDAzMFwwMDEgXDAwMShcdFwwMjJcMDE2XG5cMDA2biIKKyAgICAidW1iZXJcMDMwXDAwMiBcMDAxKFwwMDVcMDIyMlxuXDAwN29wdGlvbnNcMDMwXDAwMyBcMDAxKFwwMTMyIS5nb29nbGUucHIiCisgICAgIm90b2J1Zi5FbnVtVmFsdWVPcHRpb25zXCJcMjIwXDAwMVxuXDAyNlNlcnZpY2VEZXNjciIKKyAgICAiaXB0b3JQcm90b1wwMjJcMDE0XG5cMDA0bmFtZVwwMzBcMDAxIFwwMDEoXHRcMDIyNlxuXDAwNm1ldGhvZFwwMzBcMDAyIFwwMDMoXDAxMyIKKyAgICAiMiYuZ29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90byIKKyAgICAiXDAyMjBcblwwMDdvcHRpb25zXDAzMFwwMDMgXDAwMShcMDEzMlwwMzcuZ29vZ2xlLnByb3RvYnVmLlNlcnYiCisgICAgImljZU9wdGlvbnNcIlwzMDFcMDAxXG5cMDI1TWV0aG9kRGVzY3JpcHRvclByb3RvXDAyMlwwMTRcblwwMDQiCisgICAgIm5hbWVcMDMwXDAwMSBcMDAxKFx0XDAyMlwwMjJcblxuaW5wdXRfdHlwZVwwMzBcMDAyIFwwMDEoXHRcMDIyXDAyM1xuXDAxM291dHB1dCIKKyAgICAiX3R5cGVcMDMwXDAwMyBcMDAxKFx0XDAyMi9cblwwMDdvcHRpb25zXDAzMFwwMDQgXDAwMShcMDEzMlwwMzYuZ29vZ2xlLnByIgorICAgICJvdG9idWYuTWV0aG9kT3B0aW9uc1wwMjJcMDM3XG5cMDIwY2xpZW50X3N0cmVhbWluZyIKKyAgICAiXDAzMFwwMDUgXDAwMShcMDEwOlwwMDVmYWxzZVwwMjJcMDM3XG5cMDIwc2VydmVyX3N0cmVhbWluZ1wwMzBcMDA2IFwwMDEoXDAxMDoiCisgICAgIlwwMDVmYWxzZVwiXDI1NlwwMDVcblwwMTNGaWxlT3B0aW9uc1wwMjJcMDI0XG5cMDE0amF2YV9wYWNrYWdlXDAzMFwwMDEiCisgICAgIiBcMDAxKFx0XDAyMlwwMzRcblwwMjRqYXZhX291dGVyX2NsYXNzbmFtZVwwMzBcMDEwIFwwMDEoXHRcMDIyXCJcblwwMjNqYSIKKyAgICAidmFfbXVsdGlwbGVfZmlsZXNcMDMwXG4gXDAwMShcMDEwOlwwMDVmYWxzZVwwMjIsXG5cMDM1amF2YV9nIgorICAgICJlbmVyYXRlX2VxdWFsc19hbmRfaGFzaFwwMzBcMDI0IFwwMDEoXDAxMDpcMDA1ZmFsc2VcMDIyJVxuXDAyNiIKKyAgICAiamF2YV9zdHJpbmdfY2hlY2tfdXRmOFwwMzBcMDMzIFwwMDEoXDAxMDpcMDA1ZmFsc2VcMDIyRlxuXDAxNG8iCisgICAgInB0aW1pemVfZm9yXDAzMFx0IFwwMDEoXDAxNjIpLmdvb2dsZS5wcm90b2J1Zi5GaWxlIgorICAgICJPcHRpb25zLk9wdGltaXplTW9kZTpcMDA1U1BFRURcMDIyXDAyMlxuXG5nb19wYWNrYWciCisgICAgImVcMDMwXDAxMyBcMDAxKFx0XDAyMlwiXG5cMDIzY2NfZ2VuZXJpY19zZXJ2aWNlc1wwMzBcMDIwIFwwMDEoXDAxMDpcMDA1ZmEiCisgICAgImxzZVwwMjIkXG5cMDI1amF2YV9nZW5lcmljX3NlcnZpY2VzXDAzMFwwMjEgXDAwMShcMDEwOlwwMDVmYWxzIgorICAgICJlXDAyMlwiXG5cMDIzcHlfZ2VuZXJpY19zZXJ2aWNlc1wwMzBcMDIyIFwwMDEoXDAxMDpcMDA1ZmFsc2VcMDIyXDAzMVxuIgorICAgICJcbmRlcHJlY2F0ZWRcMDMwXDAyNyBcMDAxKFwwMTA6XDAwNWZhbHNlXDAyMlwwMzdcblwwMjBjY19lbmFibGVfYXIiCisgICAgImVuYXNcMDMwXDAzNyBcMDAxKFwwMTA6XDAwNWZhbHNlXDAyMlwwMzFcblwwMjFvYmpjX2NsYXNzX3ByZWZpeFwwMzAkIgorICAgICIgXDAwMShcdFwwMjJcMDMwXG5cMDIwY3NoYXJwX25hbWVzcGFjZVwwMzAlIFwwMDEoXHRcMDIyK1xuXDAzN2phdmFuYSIKKyAgICAibm9fdXNlX2RlcHJlY2F0ZWRfcGFja2FnZVwwMzAmIFwwMDEoXDAxMEJcMDAyXDAzMFwwMDFcMDIyQ1xuXDAyNHUiCisgICAgIm5pbnRlcnByZXRlZF9vcHRpb25cMDMwXDM0N1wwMDcgXDAwMyhcMDEzMiQuZ29vZ2xlLnByb3QiCisgICAgIm9idWYuVW5pbnRlcnByZXRlZE9wdGlvblwiOlxuXDAxNE9wdGltaXplTW9kZSIKKyAgICAiXDAyMlx0XG5cMDA1U1BFRURcMDIwXDAwMVwwMjJcclxuXHRDT0RFX1NJWkVcMDIwXDAwMlwwMjJcMDIwXG5cMDE0TElURV9SVU5USSIKKyAgICAiTUVcMDIwXDAwMypcdFwwMTBcMzUwXDAwN1wwMjBcMjAwXDIwMFwyMDBcMjAwXDAwMlwiXDM0NlwwMDFcblwwMTZNZXNzYWdlT3B0aW9uc1wwMjImXG5cMDI3bWUiCisgICAgInNzYWdlX3NldF93aXJlX2Zvcm1hdFwwMzBcMDAxIFwwMDEoXDAxMDpcMDA1ZmFsc2VcMDIyLlxuXDAzN25vIgorICAgICJfc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvclwwMzBcMDAyIFwwMDEoXDAxMDpcMDA1ZmFsIgorICAgICJzZVwwMjJcMDMxXG5cbmRlcHJlY2F0ZWRcMDMwXDAwMyBcMDAxKFwwMTA6XDAwNWZhbHNlXDAyMlwwMjFcblx0bWFwX2VudCIKKyAgICAicnlcMDMwXDAwNyBcMDAxKFwwMTBcMDIyQ1xuXDAyNHVuaW50ZXJwcmV0ZWRfb3B0aW9uXDAzMFwzNDdcMDA3IFwwMDMoXDAxMzIiCisgICAgIiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24qXHRcMDEwIgorICAgICJcMzUwXDAwN1wwMjBcMjAwXDIwMFwyMDBcMjAwXDAwMlwiXDIzMFwwMDNcblwwMTRGaWVsZE9wdGlvbnNcMDIyOlxuXDAwNWN0eXBlXDAzMFwwMDEgXDAwMShcMDE2IgorICAgICIyIy5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLkNUeXBlOlwwMDZTIgorICAgICJUUklOR1wwMjJcMDE2XG5cMDA2cGFja2VkXDAzMFwwMDIgXDAwMShcMDEwXDAyMlw/XG5cMDA2anN0eXBlXDAzMFwwMDYgXDAwMShcMDE2MiQuIgorICAgICJnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLkpTVHlwZTpcdEpTXyIKKyAgICAiTk9STUFMXDAyMlwwMjNcblwwMDRsYXp5XDAzMFwwMDUgXDAwMShcMDEwOlwwMDVmYWxzZVwwMjJcMDMxXG5cbmRlcHJlY2F0ZSIKKyAgICAiZFwwMzBcMDAzIFwwMDEoXDAxMDpcMDA1ZmFsc2VcMDIyXDAyM1xuXDAwNHdlYWtcMDMwXG4gXDAwMShcMDEwOlwwMDVmYWxzZVwwMjJDXG5cMDI0dSIKKyAgICAibmludGVycHJldGVkX29wdGlvblwwMzBcMzQ3XDAwNyBcMDAzKFwwMTMyJC5nb29nbGUucHJvdCIKKyAgICAib2J1Zi5VbmludGVycHJldGVkT3B0aW9uXCIvXG5cMDA1Q1R5cGVcMDIyXG5cblwwMDZTVFIiCisgICAgIklOR1wwMjBcMDAwXDAyMlwwMTBcblwwMDRDT1JEXDAyMFwwMDFcMDIyXDAyMFxuXDAxNFNUUklOR19QSUVDRVwwMjBcMDAyXCI1XG5cMDA2SlNUIgorICAgICJ5cGVcMDIyXHJcblx0SlNfTk9STUFMXDAyMFwwMDBcMDIyXHJcblx0SlNfU1RSSU5HXDAyMFwwMDFcMDIyXHJcblx0SlNfIgorICAgICJOVU1CRVJcMDIwXDAwMipcdFwwMTBcMzUwXDAwN1wwMjBcMjAwXDIwMFwyMDBcMjAwXDAwMlwiXDIxNVwwMDFcblwwMTNFbnVtT3B0aW9uc1wwMjJcMDIzXG5cMDEzYSIKKyAgICAibGxvd19hbGlhc1wwMzBcMDAyIFwwMDEoXDAxMFwwMjJcMDMxXG5cbmRlcHJlY2F0ZWRcMDMwXDAwMyBcMDAxKFwwMTA6XDAwNWZhIgorICAgICJsc2VcMDIyQ1xuXDAyNHVuaW50ZXJwcmV0ZWRfb3B0aW9uXDAzMFwzNDdcMDA3IFwwMDMoXDAxMzIkLmdvbyIKKyAgICAiZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24qXHRcMDEwXDM1MFwwMDdcMDIwXDIwMFwyMDAiCisgICAgIlwyMDBcMjAwXDAwMlwifVxuXDAyMEVudW1WYWx1ZU9wdGlvbnNcMDIyXDAzMVxuXG5kZXByZWNhdGVkXDAzMFwwMDEgIgorICAgICJcMDAxKFwwMTA6XDAwNWZhbHNlXDAyMkNcblwwMjR1bmludGVycHJldGVkX29wdGlvblwwMzBcMzQ3XDAwNyBcMDAzKCIKKyAgICAiXDAxMzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKiIKKyAgICAiXHRcMDEwXDM1MFwwMDdcMDIwXDIwMFwyMDBcMjAwXDIwMFwwMDJcIntcblwwMTZTZXJ2aWNlT3B0aW9uc1wwMjJcMDMxXG5cbmRlcHJlY2F0IgorICAgICJlZFwwMzAhIFwwMDEoXDAxMDpcMDA1ZmFsc2VcMDIyQ1xuXDAyNHVuaW50ZXJwcmV0ZWRfb3B0aW9uXDAzMCIKKyAgICAiXDM0N1wwMDcgXDAwMyhcMDEzMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcCIKKyAgICAidGlvbipcdFwwMTBcMzUwXDAwN1wwMjBcMjAwXDIwMFwyMDBcMjAwXDAwMlwielxuXHJNZXRob2RPcHRpb25zXDAyMlwwMzFcblxuZGVwciIKKyAgICAiZWNhdGVkXDAzMCEgXDAwMShcMDEwOlwwMDVmYWxzZVwwMjJDXG5cMDI0dW5pbnRlcnByZXRlZF9vcHQiCisgICAgImlvblwwMzBcMzQ3XDAwNyBcMDAzKFwwMTMyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXQiCisgICAgImVkT3B0aW9uKlx0XDAxMFwzNTBcMDA3XDAyMFwyMDBcMjAwXDIwMFwyMDBcMDAyXCJcMjM2XDAwMlxuXDAyM1VuaW50ZXJwcmV0ZWRPcHQiCisgICAgImlvblwwMjI7XG5cMDA0bmFtZVwwMzBcMDAyIFwwMDMoXDAxMzItLmdvb2dsZS5wcm90b2J1Zi5VbmluIgorICAgICJ0ZXJwcmV0ZWRPcHRpb24uTmFtZVBhcnRcMDIyXDAzMFxuXDAyMGlkZW50aWZpZXJfdiIKKyAgICAiYWx1ZVwwMzBcMDAzIFwwMDEoXHRcMDIyXDAzMlxuXDAyMnBvc2l0aXZlX2ludF92YWx1ZVwwMzBcMDA0IFwwMDEoXDAwNFwwMjJcMDMyIgorICAgICJcblwwMjJuZWdhdGl2ZV9pbnRfdmFsdWVcMDMwXDAwNSBcMDAxKFwwMDNcMDIyXDAyNFxuXDAxNGRvdWJsZV92YWwiCisgICAgInVlXDAzMFwwMDYgXDAwMShcMDAxXDAyMlwwMjRcblwwMTRzdHJpbmdfdmFsdWVcMDMwXDAwNyBcMDAxKFwwMTRcMDIyXDAyN1xuXDAxN2FnZ3JlZyIKKyAgICAiYXRlX3ZhbHVlXDAzMFwwMTAgXDAwMShcdFwwMzIzXG5cMDEwTmFtZVBhcnRcMDIyXDAyMVxuXHRuYW1lX3BhcnQiCisgICAgIlwwMzBcMDAxIFwwMDIoXHRcMDIyXDAyNFxuXDAxNGlzX2V4dGVuc2lvblwwMzBcMDAyIFwwMDIoXDAxMFwiXDMyNVwwMDFcblwwMTZTb3VyY2VDIgorICAgICJvZGVJbmZvXDAyMjpcblwwMTBsb2NhdGlvblwwMzBcMDAxIFwwMDMoXDAxMzIoLmdvb2dsZS5wcm90byIKKyAgICAiYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uXDAzMlwyMDZcMDAxXG5cMDEwTG9jYXRpb24iCisgICAgIlwwMjJcMDIwXG5cMDA0cGF0aFwwMzBcMDAxIFwwMDMoXDAwNUJcMDAyXDAyMFwwMDFcMDIyXDAyMFxuXDAwNHNwYW5cMDMwXDAwMiBcMDAzKFwwMDVCXDAwMlwwMjBcMDAxXDAyMlwwMzBcblwwMjAiCisgICAgImxlYWRpbmdfY29tbWVudHNcMDMwXDAwMyBcMDAxKFx0XDAyMlwwMzFcblwwMjF0cmFpbGluZ19jb21tZSIKKyAgICAibnRzXDAzMFwwMDQgXDAwMShcdFwwMjIhXG5cMDMxbGVhZGluZ19kZXRhY2hlZF9jb21tZW50c1wwMzBcMDA2IgorICAgICIgXDAwMyhcdFwiXDI0N1wwMDFcblwwMjFHZW5lcmF0ZWRDb2RlSW5mb1wwMjJBXG5cbmFubm90YXRpb24iCisgICAgIlwwMzBcMDAxIFwwMDMoXDAxMzItLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRDb2RlSW4iCisgICAgImZvLkFubm90YXRpb25cMDMyT1xuXG5Bbm5vdGF0aW9uXDAyMlwwMjBcblwwMDRwYXRoXDAzMFwwMDEgXDAwMygiCisgICAgIlwwMDVCXDAwMlwwMjBcMDAxXDAyMlwwMjNcblwwMTNzb3VyY2VfZmlsZVwwMzBcMDAyIFwwMDEoXHRcMDIyXHJcblwwMDViZWdpblwwMzBcMDAzIFwwMDEoIgorICAgICJcMDA1XDAyMlwwMTNcblwwMDNlbmRcMDMwXDAwNCBcMDAxKFwwMDVCWFxuXDAyM2NvbS5nb29nbGUucHJvdG9idWZCXDAyMEQiCisgICAgImVzY3JpcHRvclByb3Rvc0hcMDAxWlxuZGVzY3JpcHRvclwyNDJcMDAyXDAwM0dQQlwyNTJcMDAyXDAzMkdvIgorICAgICJvZ2xlLlByb3RvYnVmLlJlZmxlY3Rpb24iLCA1MTg0KTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZEZpbGUoCisgICAgImdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvIiwgJnByb3RvYnVmX1JlZ2lzdGVyVHlwZXMpOworICBGaWxlRGVzY3JpcHRvclNldDo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBuZXcgRmlsZURlc2NyaXB0b3JTZXQoKTsKKyAgRmlsZURlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBuZXcgRmlsZURlc2NyaXB0b3JQcm90bygpOworICBEZXNjcmlwdG9yUHJvdG86OmRlZmF1bHRfaW5zdGFuY2VfID0gbmV3IERlc2NyaXB0b3JQcm90bygpOworICBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6OmRlZmF1bHRfaW5zdGFuY2VfID0gbmV3IERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZSgpOworICBEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZTo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBuZXcgRGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2UoKTsKKyAgRmllbGREZXNjcmlwdG9yUHJvdG86OmRlZmF1bHRfaW5zdGFuY2VfID0gbmV3IEZpZWxkRGVzY3JpcHRvclByb3RvKCk7CisgIE9uZW9mRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlXyA9IG5ldyBPbmVvZkRlc2NyaXB0b3JQcm90bygpOworICBFbnVtRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlXyA9IG5ldyBFbnVtRGVzY3JpcHRvclByb3RvKCk7CisgIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBuZXcgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvKCk7CisgIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86OmRlZmF1bHRfaW5zdGFuY2VfID0gbmV3IFNlcnZpY2VEZXNjcmlwdG9yUHJvdG8oKTsKKyAgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlXyA9IG5ldyBNZXRob2REZXNjcmlwdG9yUHJvdG8oKTsKKyAgRmlsZU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2VfID0gbmV3IEZpbGVPcHRpb25zKCk7CisgIE1lc3NhZ2VPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlXyA9IG5ldyBNZXNzYWdlT3B0aW9ucygpOworICBGaWVsZE9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2VfID0gbmV3IEZpZWxkT3B0aW9ucygpOworICBFbnVtT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBuZXcgRW51bU9wdGlvbnMoKTsKKyAgRW51bVZhbHVlT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBuZXcgRW51bVZhbHVlT3B0aW9ucygpOworICBTZXJ2aWNlT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBuZXcgU2VydmljZU9wdGlvbnMoKTsKKyAgTWV0aG9kT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBuZXcgTWV0aG9kT3B0aW9ucygpOworICBVbmludGVycHJldGVkT3B0aW9uOjpkZWZhdWx0X2luc3RhbmNlXyA9IG5ldyBVbmludGVycHJldGVkT3B0aW9uKCk7CisgIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQ6OmRlZmF1bHRfaW5zdGFuY2VfID0gbmV3IFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQoKTsKKyAgU291cmNlQ29kZUluZm86OmRlZmF1bHRfaW5zdGFuY2VfID0gbmV3IFNvdXJjZUNvZGVJbmZvKCk7CisgIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpkZWZhdWx0X2luc3RhbmNlXyA9IG5ldyBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbigpOworICBHZW5lcmF0ZWRDb2RlSW5mbzo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBuZXcgR2VuZXJhdGVkQ29kZUluZm8oKTsKKyAgR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbjo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBuZXcgR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbigpOworICBGaWxlRGVzY3JpcHRvclNldDo6ZGVmYXVsdF9pbnN0YW5jZV8tPkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICBGaWxlRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlXy0+SW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIERlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZV8tPkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6OmRlZmF1bHRfaW5zdGFuY2VfLT5Jbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgRGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2U6OmRlZmF1bHRfaW5zdGFuY2VfLT5Jbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgRmllbGREZXNjcmlwdG9yUHJvdG86OmRlZmF1bHRfaW5zdGFuY2VfLT5Jbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgT25lb2ZEZXNjcmlwdG9yUHJvdG86OmRlZmF1bHRfaW5zdGFuY2VfLT5Jbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgRW51bURlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZV8tPkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86OmRlZmF1bHRfaW5zdGFuY2VfLT5Jbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgU2VydmljZURlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZV8tPkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICBNZXRob2REZXNjcmlwdG9yUHJvdG86OmRlZmF1bHRfaW5zdGFuY2VfLT5Jbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgRmlsZU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2VfLT5Jbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgTWVzc2FnZU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2VfLT5Jbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgRmllbGRPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlXy0+SW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIEVudW1PcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlXy0+SW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIEVudW1WYWx1ZU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2VfLT5Jbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgU2VydmljZU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2VfLT5Jbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgTWV0aG9kT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZV8tPkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICBVbmludGVycHJldGVkT3B0aW9uOjpkZWZhdWx0X2luc3RhbmNlXy0+SW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQ6OmRlZmF1bHRfaW5zdGFuY2VfLT5Jbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgU291cmNlQ29kZUluZm86OmRlZmF1bHRfaW5zdGFuY2VfLT5Jbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgU291cmNlQ29kZUluZm9fTG9jYXRpb246OmRlZmF1bHRfaW5zdGFuY2VfLT5Jbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgR2VuZXJhdGVkQ29kZUluZm86OmRlZmF1bHRfaW5zdGFuY2VfLT5Jbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbjo6ZGVmYXVsdF9pbnN0YW5jZV8tPkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpPblNodXRkb3duKCZwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8pOworfQorCisvLyBGb3JjZSBBZGREZXNjcmlwdG9ycygpIHRvIGJlIGNhbGxlZCBhdCBzdGF0aWMgaW5pdGlhbGl6YXRpb24gdGltZS4KK3N0cnVjdCBTdGF0aWNEZXNjcmlwdG9ySW5pdGlhbGl6ZXJfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8geworICBTdGF0aWNEZXNjcmlwdG9ySW5pdGlhbGl6ZXJfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKSB7CisgICAgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICB9Cit9IHN0YXRpY19kZXNjcmlwdG9yX2luaXRpYWxpemVyX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvXzsKKworbmFtZXNwYWNlIHsKKworc3RhdGljIHZvaWQgTWVyZ2VGcm9tRmFpbChpbnQgbGluZSkgR09PR0xFX0FUVFJJQlVURV9DT0xEOworc3RhdGljIHZvaWQgTWVyZ2VGcm9tRmFpbChpbnQgbGluZSkgeworICBHT09HTEVfQ0hFQ0soZmFsc2UpIDw8IF9fRklMRV9fIDw8ICI6IiA8PCBsaW5lOworfQorCit9ICAvLyBuYW1lc3BhY2UKKworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKyNpZiAhZGVmaW5lZChfTVNDX1ZFUikgfHwgX01TQ19WRVIgPj0gMTkwMAorY29uc3QgaW50IEZpbGVEZXNjcmlwdG9yU2V0OjprRmlsZUZpZWxkTnVtYmVyOworI2VuZGlmICAvLyAhZGVmaW5lZChfTVNDX1ZFUikgfHwgX01TQ19WRVIgPj0gMTkwMAorCitGaWxlRGVzY3JpcHRvclNldDo6RmlsZURlc2NyaXB0b3JTZXQoKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpLCBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yU2V0KQorfQorCit2b2lkIEZpbGVEZXNjcmlwdG9yU2V0OjpJbml0QXNEZWZhdWx0SW5zdGFuY2UoKSB7Cit9CisKK0ZpbGVEZXNjcmlwdG9yU2V0OjpGaWxlRGVzY3JpcHRvclNldChjb25zdCBGaWxlRGVzY3JpcHRvclNldCYgZnJvbSkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwKKyAgICBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICBNZXJnZUZyb20oZnJvbSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb3B5X2NvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclNldCkKK30KKwordm9pZCBGaWxlRGVzY3JpcHRvclNldDo6U2hhcmVkQ3RvcigpIHsKKyAgX2NhY2hlZF9zaXplXyA9IDA7CisgIDo6bWVtc2V0KF9oYXNfYml0c18sIDAsIHNpemVvZihfaGFzX2JpdHNfKSk7Cit9CisKK0ZpbGVEZXNjcmlwdG9yU2V0Ojp+RmlsZURlc2NyaXB0b3JTZXQoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChkZXN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclNldCkKKyAgU2hhcmVkRHRvcigpOworfQorCit2b2lkIEZpbGVEZXNjcmlwdG9yU2V0OjpTaGFyZWREdG9yKCkgeworICBpZiAodGhpcyAhPSBkZWZhdWx0X2luc3RhbmNlXykgeworICB9Cit9CisKK3ZvaWQgRmlsZURlc2NyaXB0b3JTZXQ6OlNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0IHsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHNpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBGaWxlRGVzY3JpcHRvclNldDo6ZGVzY3JpcHRvcigpIHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIHJldHVybiBGaWxlRGVzY3JpcHRvclNldF9kZXNjcmlwdG9yXzsKK30KKworY29uc3QgRmlsZURlc2NyaXB0b3JTZXQmIEZpbGVEZXNjcmlwdG9yU2V0OjpkZWZhdWx0X2luc3RhbmNlKCkgeworICBpZiAoZGVmYXVsdF9pbnN0YW5jZV8gPT0gTlVMTCkgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICByZXR1cm4gKmRlZmF1bHRfaW5zdGFuY2VfOworfQorCitGaWxlRGVzY3JpcHRvclNldCogRmlsZURlc2NyaXB0b3JTZXQ6OmRlZmF1bHRfaW5zdGFuY2VfID0gTlVMTDsKKworRmlsZURlc2NyaXB0b3JTZXQqIEZpbGVEZXNjcmlwdG9yU2V0OjpOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0IHsKKyAgRmlsZURlc2NyaXB0b3JTZXQqIG4gPSBuZXcgRmlsZURlc2NyaXB0b3JTZXQ7CisgIGlmIChhcmVuYSAhPSBOVUxMKSB7CisgICAgYXJlbmEtPk93bihuKTsKKyAgfQorICByZXR1cm4gbjsKK30KKwordm9pZCBGaWxlRGVzY3JpcHRvclNldDo6Q2xlYXIoKSB7CisgIGZpbGVfLkNsZWFyKCk7CisgIDo6bWVtc2V0KF9oYXNfYml0c18sIDAsIHNpemVvZihfaGFzX2JpdHNfKSk7CisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+Q2xlYXIoKTsKKyAgfQorfQorCitib29sIEZpbGVEZXNjcmlwdG9yU2V0OjpNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyNkZWZpbmUgRE9fKEVYUFJFU1NJT04pIGlmICghKEVYUFJFU1NJT04pKSBnb3RvIGZhaWx1cmUKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgdGFnOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yU2V0KQorICBmb3IgKDs7KSB7CisgICAgOjpzdGQ6OnBhaXI8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyLCBib29sPiBwID0gaW5wdXQtPlJlYWRUYWdXaXRoQ3V0b2ZmKDEyNyk7CisgICAgdGFnID0gcC5maXJzdDsKKyAgICBpZiAoIXAuc2Vjb25kKSBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgIHN3aXRjaCAoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ0ZpZWxkTnVtYmVyKHRhZykpIHsKKyAgICAgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90byBmaWxlID0gMTsKKyAgICAgIGNhc2UgMTogeworICAgICAgICBpZiAodGFnID09IDEwKSB7CisgICAgICAgICAgRE9fKGlucHV0LT5JbmNyZW1lbnRSZWN1cnNpb25EZXB0aCgpKTsKKyAgICAgICAgIHBhcnNlX2xvb3BfZmlsZToKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRNZXNzYWdlTm9WaXJ0dWFsTm9SZWN1cnNpb25EZXB0aCgKKyAgICAgICAgICAgICAgICBpbnB1dCwgYWRkX2ZpbGUoKSkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMTApKSBnb3RvIHBhcnNlX2xvb3BfZmlsZTsKKyAgICAgICAgaW5wdXQtPlVuc2FmZURlY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCk7CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0QXRFbmQoKSkgZ290byBzdWNjZXNzOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgZGVmYXVsdDogeworICAgICAgaGFuZGxlX3VudXN1YWw6CisgICAgICAgIGlmICh0YWcgPT0gMCB8fAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ1dpcmVUeXBlKHRhZykgPT0KKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVApIHsKKyAgICAgICAgICBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIH0KKyAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNraXBGaWVsZCgKKyAgICAgICAgICAgICAgaW5wdXQsIHRhZywgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpKSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgfQorc3VjY2VzczoKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N1Y2Nlc3M6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yU2V0KQorICByZXR1cm4gdHJ1ZTsKK2ZhaWx1cmU6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9mYWlsdXJlOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclNldCkKKyAgcmV0dXJuIGZhbHNlOworI3VuZGVmIERPXworfQorCit2b2lkIEZpbGVEZXNjcmlwdG9yU2V0OjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclNldCkKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvIGZpbGUgPSAxOworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPmZpbGVfc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlTWVzc2FnZU1heWJlVG9BcnJheSgKKyAgICAgIDEsIHRoaXMtPmZpbGUoaSksIG91dHB1dCk7CisgIH0KKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTZXJpYWxpemVVbmtub3duRmllbGRzKAorICAgICAgICB1bmtub3duX2ZpZWxkcygpLCBvdXRwdXQpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfZW5kOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclNldCkKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogRmlsZURlc2NyaXB0b3JTZXQ6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogdGFyZ2V0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yU2V0KQorICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZSA9IDE7CisgIGZvciAodW5zaWduZWQgaW50IGkgPSAwLCBuID0gdGhpcy0+ZmlsZV9zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6CisgICAgICBXcml0ZU1lc3NhZ2VOb1ZpcnR1YWxUb0FycmF5KAorICAgICAgICAxLCB0aGlzLT5maWxlKGkpLCB0YXJnZXQpOworICB9CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bkZpZWxkc1RvQXJyYXkoCisgICAgICAgIHVua25vd25fZmllbGRzKCksIHRhcmdldCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9lbmQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yU2V0KQorICByZXR1cm4gdGFyZ2V0OworfQorCitpbnQgRmlsZURlc2NyaXB0b3JTZXQ6OkJ5dGVTaXplKCkgY29uc3QgeworICBpbnQgdG90YWxfc2l6ZSA9IDA7CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvIGZpbGUgPSAxOworICB0b3RhbF9zaXplICs9IDEgKiB0aGlzLT5maWxlX3NpemUoKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT5maWxlX3NpemUoKTsgaSsrKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1lc3NhZ2VTaXplTm9WaXJ0dWFsKAorICAgICAgICB0aGlzLT5maWxlKGkpKTsKKyAgfQorCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHRvdGFsX3NpemUgKz0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OkNvbXB1dGVVbmtub3duRmllbGRzU2l6ZSgKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSk7CisgIH0KKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHRvdGFsX3NpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworICByZXR1cm4gdG90YWxfc2l6ZTsKK30KKwordm9pZCBGaWxlRGVzY3JpcHRvclNldDo6TWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBjb25zdCBGaWxlRGVzY3JpcHRvclNldCogc291cmNlID0gCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpEeW5hbWljQ2FzdFRvR2VuZXJhdGVkPGNvbnN0IEZpbGVEZXNjcmlwdG9yU2V0PigKKyAgICAgICAgICAmZnJvbSk7CisgIGlmIChzb3VyY2UgPT0gTlVMTCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlJlZmxlY3Rpb25PcHM6Ok1lcmdlKGZyb20sIHRoaXMpOworICB9IGVsc2UgeworICAgIE1lcmdlRnJvbSgqc291cmNlKTsKKyAgfQorfQorCit2b2lkIEZpbGVEZXNjcmlwdG9yU2V0OjpNZXJnZUZyb20oY29uc3QgRmlsZURlc2NyaXB0b3JTZXQmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgZmlsZV8uTWVyZ2VGcm9tKGZyb20uZmlsZV8pOworICBpZiAoZnJvbS5faW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+TWVyZ2VGcm9tKGZyb20udW5rbm93bl9maWVsZHMoKSk7CisgIH0KK30KKwordm9pZCBGaWxlRGVzY3JpcHRvclNldDo6Q29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKwordm9pZCBGaWxlRGVzY3JpcHRvclNldDo6Q29weUZyb20oY29uc3QgRmlsZURlc2NyaXB0b3JTZXQmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCitib29sIEZpbGVEZXNjcmlwdG9yU2V0OjpJc0luaXRpYWxpemVkKCkgY29uc3QgeworCisgIGlmICghOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QWxsQXJlSW5pdGlhbGl6ZWQodGhpcy0+ZmlsZSgpKSkgcmV0dXJuIGZhbHNlOworICByZXR1cm4gdHJ1ZTsKK30KKwordm9pZCBGaWxlRGVzY3JpcHRvclNldDo6U3dhcChGaWxlRGVzY3JpcHRvclNldCogb3RoZXIpIHsKKyAgaWYgKG90aGVyID09IHRoaXMpIHJldHVybjsKKyAgSW50ZXJuYWxTd2FwKG90aGVyKTsKK30KK3ZvaWQgRmlsZURlc2NyaXB0b3JTZXQ6OkludGVybmFsU3dhcChGaWxlRGVzY3JpcHRvclNldCogb3RoZXIpIHsKKyAgZmlsZV8uVW5zYWZlQXJlbmFTd2FwKCZvdGhlci0+ZmlsZV8pOworICBzdGQ6OnN3YXAoX2hhc19iaXRzX1swXSwgb3RoZXItPl9oYXNfYml0c19bMF0pOworICBfaW50ZXJuYWxfbWV0YWRhdGFfLlN3YXAoJm90aGVyLT5faW50ZXJuYWxfbWV0YWRhdGFfKTsKKyAgc3RkOjpzd2FwKF9jYWNoZWRfc2l6ZV8sIG90aGVyLT5fY2FjaGVkX3NpemVfKTsKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBGaWxlRGVzY3JpcHRvclNldDo6R2V0TWV0YWRhdGEoKSBjb25zdCB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIG1ldGFkYXRhOworICBtZXRhZGF0YS5kZXNjcmlwdG9yID0gRmlsZURlc2NyaXB0b3JTZXRfZGVzY3JpcHRvcl87CisgIG1ldGFkYXRhLnJlZmxlY3Rpb24gPSBGaWxlRGVzY3JpcHRvclNldF9yZWZsZWN0aW9uXzsKKyAgcmV0dXJuIG1ldGFkYXRhOworfQorCisjaWYgUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisvLyBGaWxlRGVzY3JpcHRvclNldAorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZSA9IDE7CitpbnQgRmlsZURlc2NyaXB0b3JTZXQ6OmZpbGVfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIGZpbGVfLnNpemUoKTsKK30KK3ZvaWQgRmlsZURlc2NyaXB0b3JTZXQ6OmNsZWFyX2ZpbGUoKSB7CisgIGZpbGVfLkNsZWFyKCk7Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVEZXNjcmlwdG9yUHJvdG8mIEZpbGVEZXNjcmlwdG9yU2V0OjpmaWxlKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclNldC5maWxlKQorICByZXR1cm4gZmlsZV8uR2V0KGluZGV4KTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZURlc2NyaXB0b3JQcm90byogRmlsZURlc2NyaXB0b3JTZXQ6Om11dGFibGVfZmlsZShpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yU2V0LmZpbGUpCisgIHJldHVybiBmaWxlXy5NdXRhYmxlKGluZGV4KTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZURlc2NyaXB0b3JQcm90byogRmlsZURlc2NyaXB0b3JTZXQ6OmFkZF9maWxlKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclNldC5maWxlKQorICByZXR1cm4gZmlsZV8uQWRkKCk7Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZURlc2NyaXB0b3JQcm90byA+KgorRmlsZURlc2NyaXB0b3JTZXQ6Om11dGFibGVfZmlsZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JTZXQuZmlsZSkKKyAgcmV0dXJuICZmaWxlXzsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlRGVzY3JpcHRvclByb3RvID4mCitGaWxlRGVzY3JpcHRvclNldDo6ZmlsZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yU2V0LmZpbGUpCisgIHJldHVybiBmaWxlXzsKK30KKworI2VuZGlmICAvLyBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisjaWYgIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKK2NvbnN0IGludCBGaWxlRGVzY3JpcHRvclByb3RvOjprTmFtZUZpZWxkTnVtYmVyOworY29uc3QgaW50IEZpbGVEZXNjcmlwdG9yUHJvdG86OmtQYWNrYWdlRmllbGROdW1iZXI7Citjb25zdCBpbnQgRmlsZURlc2NyaXB0b3JQcm90bzo6a0RlcGVuZGVuY3lGaWVsZE51bWJlcjsKK2NvbnN0IGludCBGaWxlRGVzY3JpcHRvclByb3RvOjprUHVibGljRGVwZW5kZW5jeUZpZWxkTnVtYmVyOworY29uc3QgaW50IEZpbGVEZXNjcmlwdG9yUHJvdG86OmtXZWFrRGVwZW5kZW5jeUZpZWxkTnVtYmVyOworY29uc3QgaW50IEZpbGVEZXNjcmlwdG9yUHJvdG86OmtNZXNzYWdlVHlwZUZpZWxkTnVtYmVyOworY29uc3QgaW50IEZpbGVEZXNjcmlwdG9yUHJvdG86OmtFbnVtVHlwZUZpZWxkTnVtYmVyOworY29uc3QgaW50IEZpbGVEZXNjcmlwdG9yUHJvdG86OmtTZXJ2aWNlRmllbGROdW1iZXI7Citjb25zdCBpbnQgRmlsZURlc2NyaXB0b3JQcm90bzo6a0V4dGVuc2lvbkZpZWxkTnVtYmVyOworY29uc3QgaW50IEZpbGVEZXNjcmlwdG9yUHJvdG86OmtPcHRpb25zRmllbGROdW1iZXI7Citjb25zdCBpbnQgRmlsZURlc2NyaXB0b3JQcm90bzo6a1NvdXJjZUNvZGVJbmZvRmllbGROdW1iZXI7Citjb25zdCBpbnQgRmlsZURlc2NyaXB0b3JQcm90bzo6a1N5bnRheEZpZWxkTnVtYmVyOworI2VuZGlmICAvLyAhZGVmaW5lZChfTVNDX1ZFUikgfHwgX01TQ19WRVIgPj0gMTkwMAorCitGaWxlRGVzY3JpcHRvclByb3RvOjpGaWxlRGVzY3JpcHRvclByb3RvKCkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvKQorfQorCit2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpIHsKKyAgb3B0aW9uc18gPSBjb25zdF9jYXN0PCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVPcHRpb25zKj4oJjo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2UoKSk7CisgIHNvdXJjZV9jb2RlX2luZm9fID0gY29uc3RfY2FzdDwgOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb2RlSW5mbyo+KCY6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvZGVJbmZvOjpkZWZhdWx0X2luc3RhbmNlKCkpOworfQorCitGaWxlRGVzY3JpcHRvclByb3RvOjpGaWxlRGVzY3JpcHRvclByb3RvKGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8mIGZyb20pCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksCisgICAgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29weV9jb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90bykKK30KKwordm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpTaGFyZWRDdG9yKCkgeworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZygpOworICBfY2FjaGVkX3NpemVfID0gMDsKKyAgbmFtZV8uVW5zYWZlU2V0RGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBwYWNrYWdlXy5VbnNhZmVTZXREZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIG9wdGlvbnNfID0gTlVMTDsKKyAgc291cmNlX2NvZGVfaW5mb18gPSBOVUxMOworICBzeW50YXhfLlVuc2FmZVNldERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgOjptZW1zZXQoX2hhc19iaXRzXywgMCwgc2l6ZW9mKF9oYXNfYml0c18pKTsKK30KKworRmlsZURlc2NyaXB0b3JQcm90bzo6fkZpbGVEZXNjcmlwdG9yUHJvdG8oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChkZXN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvKQorICBTaGFyZWREdG9yKCk7Cit9CisKK3ZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6U2hhcmVkRHRvcigpIHsKKyAgbmFtZV8uRGVzdHJveU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgcGFja2FnZV8uRGVzdHJveU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgc3ludGF4Xy5EZXN0cm95Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBpZiAodGhpcyAhPSBkZWZhdWx0X2luc3RhbmNlXykgeworICAgIGRlbGV0ZSBvcHRpb25zXzsKKyAgICBkZWxldGUgc291cmNlX2NvZGVfaW5mb187CisgIH0KK30KKwordm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdCB7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSBzaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogRmlsZURlc2NyaXB0b3JQcm90bzo6ZGVzY3JpcHRvcigpIHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIHJldHVybiBGaWxlRGVzY3JpcHRvclByb3RvX2Rlc2NyaXB0b3JfOworfQorCitjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvJiBGaWxlRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlKCkgeworICBpZiAoZGVmYXVsdF9pbnN0YW5jZV8gPT0gTlVMTCkgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICByZXR1cm4gKmRlZmF1bHRfaW5zdGFuY2VfOworfQorCitGaWxlRGVzY3JpcHRvclByb3RvKiBGaWxlRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlXyA9IE5VTEw7CisKK0ZpbGVEZXNjcmlwdG9yUHJvdG8qIEZpbGVEZXNjcmlwdG9yUHJvdG86Ok5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3QgeworICBGaWxlRGVzY3JpcHRvclByb3RvKiBuID0gbmV3IEZpbGVEZXNjcmlwdG9yUHJvdG87CisgIGlmIChhcmVuYSAhPSBOVUxMKSB7CisgICAgYXJlbmEtPk93bihuKTsKKyAgfQorICByZXR1cm4gbjsKK30KKwordm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpDbGVhcigpIHsKKyAgaWYgKF9oYXNfYml0c19bMCAvIDMyXSAmIDN1KSB7CisgICAgaWYgKGhhc19uYW1lKCkpIHsKKyAgICAgIG5hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgICB9CisgICAgaWYgKGhhc19wYWNrYWdlKCkpIHsKKyAgICAgIHBhY2thZ2VfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgICB9CisgIH0KKyAgaWYgKF9oYXNfYml0c19bOCAvIDMyXSAmIDM1ODR1KSB7CisgICAgaWYgKGhhc19vcHRpb25zKCkpIHsKKyAgICAgIGlmIChvcHRpb25zXyAhPSBOVUxMKSBvcHRpb25zXy0+Ojpnb29nbGU6OnByb3RvYnVmOjpGaWxlT3B0aW9uczo6Q2xlYXIoKTsKKyAgICB9CisgICAgaWYgKGhhc19zb3VyY2VfY29kZV9pbmZvKCkpIHsKKyAgICAgIGlmIChzb3VyY2VfY29kZV9pbmZvXyAhPSBOVUxMKSBzb3VyY2VfY29kZV9pbmZvXy0+Ojpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb2RlSW5mbzo6Q2xlYXIoKTsKKyAgICB9CisgICAgaWYgKGhhc19zeW50YXgoKSkgeworICAgICAgc3ludGF4Xy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgICAgfQorICB9CisgIGRlcGVuZGVuY3lfLkNsZWFyKCk7CisgIHB1YmxpY19kZXBlbmRlbmN5Xy5DbGVhcigpOworICB3ZWFrX2RlcGVuZGVuY3lfLkNsZWFyKCk7CisgIG1lc3NhZ2VfdHlwZV8uQ2xlYXIoKTsKKyAgZW51bV90eXBlXy5DbGVhcigpOworICBzZXJ2aWNlXy5DbGVhcigpOworICBleHRlbnNpb25fLkNsZWFyKCk7CisgIDo6bWVtc2V0KF9oYXNfYml0c18sIDAsIHNpemVvZihfaGFzX2JpdHNfKSk7CisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+Q2xlYXIoKTsKKyAgfQorfQorCitib29sIEZpbGVEZXNjcmlwdG9yUHJvdG86Ok1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCkgeworI2RlZmluZSBET18oRVhQUkVTU0lPTikgaWYgKCEoRVhQUkVTU0lPTikpIGdvdG8gZmFpbHVyZQorICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiB0YWc7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdGFydDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90bykKKyAgZm9yICg7OykgeworICAgIDo6c3RkOjpwYWlyPCA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiwgYm9vbD4gcCA9IGlucHV0LT5SZWFkVGFnV2l0aEN1dG9mZigxMjcpOworICAgIHRhZyA9IHAuZmlyc3Q7CisgICAgaWYgKCFwLnNlY29uZCkgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICBzd2l0Y2ggKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdGaWVsZE51bWJlcih0YWcpKSB7CisgICAgICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgICAgICBjYXNlIDE6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAxMCkgeworICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFN0cmluZygKKyAgICAgICAgICAgICAgICBpbnB1dCwgdGhpcy0+bXV0YWJsZV9uYW1lKCkpKTsKKyAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgICAgICAgIHRoaXMtPm5hbWUoKS5kYXRhKCksIHRoaXMtPm5hbWUoKS5sZW5ndGgoKSwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlBBUlNFLAorICAgICAgICAgICAgImdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLm5hbWUiKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDE4KSkgZ290byBwYXJzZV9wYWNrYWdlOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgc3RyaW5nIHBhY2thZ2UgPSAyOworICAgICAgY2FzZSAyOiB7CisgICAgICAgIGlmICh0YWcgPT0gMTgpIHsKKyAgICAgICAgIHBhcnNlX3BhY2thZ2U6CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkU3RyaW5nKAorICAgICAgICAgICAgICAgIGlucHV0LCB0aGlzLT5tdXRhYmxlX3BhY2thZ2UoKSkpOworICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgICAgICAgdGhpcy0+cGFja2FnZSgpLmRhdGEoKSwgdGhpcy0+cGFja2FnZSgpLmxlbmd0aCgpLAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6UEFSU0UsCisgICAgICAgICAgICAiZ29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ucGFja2FnZSIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMjYpKSBnb3RvIHBhcnNlX2RlcGVuZGVuY3k7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyByZXBlYXRlZCBzdHJpbmcgZGVwZW5kZW5jeSA9IDM7CisgICAgICBjYXNlIDM6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAyNikgeworICAgICAgICAgcGFyc2VfZGVwZW5kZW5jeToKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoCisgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPmFkZF9kZXBlbmRlbmN5KCkpKTsKKyAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgICAgICAgIHRoaXMtPmRlcGVuZGVuY3kodGhpcy0+ZGVwZW5kZW5jeV9zaXplKCkgLSAxKS5kYXRhKCksCisgICAgICAgICAgICB0aGlzLT5kZXBlbmRlbmN5KHRoaXMtPmRlcGVuZGVuY3lfc2l6ZSgpIC0gMSkubGVuZ3RoKCksCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpQQVJTRSwKKyAgICAgICAgICAgICJnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5kZXBlbmRlbmN5Iik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygyNikpIGdvdG8gcGFyc2VfZGVwZW5kZW5jeTsKKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMzQpKSBnb3RvIHBhcnNlX21lc3NhZ2VfdHlwZTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvIG1lc3NhZ2VfdHlwZSA9IDQ7CisgICAgICBjYXNlIDQ6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAzNCkgeworICAgICAgICAgcGFyc2VfbWVzc2FnZV90eXBlOgorICAgICAgICAgIERPXyhpbnB1dC0+SW5jcmVtZW50UmVjdXJzaW9uRGVwdGgoKSk7CisgICAgICAgICBwYXJzZV9sb29wX21lc3NhZ2VfdHlwZToKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRNZXNzYWdlTm9WaXJ0dWFsTm9SZWN1cnNpb25EZXB0aCgKKyAgICAgICAgICAgICAgICBpbnB1dCwgYWRkX21lc3NhZ2VfdHlwZSgpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygzNCkpIGdvdG8gcGFyc2VfbG9vcF9tZXNzYWdlX3R5cGU7CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDQyKSkgZ290byBwYXJzZV9sb29wX2VudW1fdHlwZTsKKyAgICAgICAgaW5wdXQtPlVuc2FmZURlY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8gZW51bV90eXBlID0gNTsKKyAgICAgIGNhc2UgNTogeworICAgICAgICBpZiAodGFnID09IDQyKSB7CisgICAgICAgICAgRE9fKGlucHV0LT5JbmNyZW1lbnRSZWN1cnNpb25EZXB0aCgpKTsKKyAgICAgICAgIHBhcnNlX2xvb3BfZW51bV90eXBlOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZE1lc3NhZ2VOb1ZpcnR1YWxOb1JlY3Vyc2lvbkRlcHRoKAorICAgICAgICAgICAgICAgIGlucHV0LCBhZGRfZW51bV90eXBlKCkpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDQyKSkgZ290byBwYXJzZV9sb29wX2VudW1fdHlwZTsKKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNTApKSBnb3RvIHBhcnNlX2xvb3Bfc2VydmljZTsKKyAgICAgICAgaW5wdXQtPlVuc2FmZURlY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8gc2VydmljZSA9IDY7CisgICAgICBjYXNlIDY6IHsKKyAgICAgICAgaWYgKHRhZyA9PSA1MCkgeworICAgICAgICAgIERPXyhpbnB1dC0+SW5jcmVtZW50UmVjdXJzaW9uRGVwdGgoKSk7CisgICAgICAgICBwYXJzZV9sb29wX3NlcnZpY2U6CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkTWVzc2FnZU5vVmlydHVhbE5vUmVjdXJzaW9uRGVwdGgoCisgICAgICAgICAgICAgICAgaW5wdXQsIGFkZF9zZXJ2aWNlKCkpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDUwKSkgZ290byBwYXJzZV9sb29wX3NlcnZpY2U7CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDU4KSkgZ290byBwYXJzZV9sb29wX2V4dGVuc2lvbjsKKyAgICAgICAgaW5wdXQtPlVuc2FmZURlY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvIGV4dGVuc2lvbiA9IDc7CisgICAgICBjYXNlIDc6IHsKKyAgICAgICAgaWYgKHRhZyA9PSA1OCkgeworICAgICAgICAgIERPXyhpbnB1dC0+SW5jcmVtZW50UmVjdXJzaW9uRGVwdGgoKSk7CisgICAgICAgICBwYXJzZV9sb29wX2V4dGVuc2lvbjoKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRNZXNzYWdlTm9WaXJ0dWFsTm9SZWN1cnNpb25EZXB0aCgKKyAgICAgICAgICAgICAgICBpbnB1dCwgYWRkX2V4dGVuc2lvbigpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg1OCkpIGdvdG8gcGFyc2VfbG9vcF9leHRlbnNpb247CisgICAgICAgIGlucHV0LT5VbnNhZmVEZWNyZW1lbnRSZWN1cnNpb25EZXB0aCgpOworICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg2NikpIGdvdG8gcGFyc2Vfb3B0aW9uczsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMgb3B0aW9ucyA9IDg7CisgICAgICBjYXNlIDg6IHsKKyAgICAgICAgaWYgKHRhZyA9PSA2NikgeworICAgICAgICAgcGFyc2Vfb3B0aW9uczoKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRNZXNzYWdlTm9WaXJ0dWFsKAorICAgICAgICAgICAgICAgaW5wdXQsIG11dGFibGVfb3B0aW9ucygpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg3NCkpIGdvdG8gcGFyc2Vfc291cmNlX2NvZGVfaW5mbzsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8gc291cmNlX2NvZGVfaW5mbyA9IDk7CisgICAgICBjYXNlIDk6IHsKKyAgICAgICAgaWYgKHRhZyA9PSA3NCkgeworICAgICAgICAgcGFyc2Vfc291cmNlX2NvZGVfaW5mbzoKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRNZXNzYWdlTm9WaXJ0dWFsKAorICAgICAgICAgICAgICAgaW5wdXQsIG11dGFibGVfc291cmNlX2NvZGVfaW5mbygpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg4MCkpIGdvdG8gcGFyc2VfcHVibGljX2RlcGVuZGVuY3k7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyByZXBlYXRlZCBpbnQzMiBwdWJsaWNfZGVwZW5kZW5jeSA9IDEwOworICAgICAgY2FzZSAxMDogeworICAgICAgICBpZiAodGFnID09IDgwKSB7CisgICAgICAgICBwYXJzZV9wdWJsaWNfZGVwZW5kZW5jeToKKyAgICAgICAgICBET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUmVwZWF0ZWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfSU5UMzI+KAorICAgICAgICAgICAgICAgICAxLCA4MCwgaW5wdXQsIHRoaXMtPm11dGFibGVfcHVibGljX2RlcGVuZGVuY3koKSkpKTsKKyAgICAgICAgfSBlbHNlIGlmICh0YWcgPT0gODIpIHsKKyAgICAgICAgICBET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUGFja2VkUHJpbWl0aXZlTm9JbmxpbmU8CisgICAgICAgICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfSU5UMzI+KAorICAgICAgICAgICAgICAgICBpbnB1dCwgdGhpcy0+bXV0YWJsZV9wdWJsaWNfZGVwZW5kZW5jeSgpKSkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoODApKSBnb3RvIHBhcnNlX3B1YmxpY19kZXBlbmRlbmN5OworICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg4OCkpIGdvdG8gcGFyc2Vfd2Vha19kZXBlbmRlbmN5OworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gcmVwZWF0ZWQgaW50MzIgd2Vha19kZXBlbmRlbmN5ID0gMTE7CisgICAgICBjYXNlIDExOiB7CisgICAgICAgIGlmICh0YWcgPT0gODgpIHsKKyAgICAgICAgIHBhcnNlX3dlYWtfZGVwZW5kZW5jeToKKyAgICAgICAgICBET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUmVwZWF0ZWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfSU5UMzI+KAorICAgICAgICAgICAgICAgICAxLCA4OCwgaW5wdXQsIHRoaXMtPm11dGFibGVfd2Vha19kZXBlbmRlbmN5KCkpKSk7CisgICAgICAgIH0gZWxzZSBpZiAodGFnID09IDkwKSB7CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFBhY2tlZFByaW1pdGl2ZU5vSW5saW5lPAorICAgICAgICAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0lOVDMyPigKKyAgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPm11dGFibGVfd2Vha19kZXBlbmRlbmN5KCkpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg4OCkpIGdvdG8gcGFyc2Vfd2Vha19kZXBlbmRlbmN5OworICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg5OCkpIGdvdG8gcGFyc2Vfc3ludGF4OworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgc3RyaW5nIHN5bnRheCA9IDEyOworICAgICAgY2FzZSAxMjogeworICAgICAgICBpZiAodGFnID09IDk4KSB7CisgICAgICAgICBwYXJzZV9zeW50YXg6CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkU3RyaW5nKAorICAgICAgICAgICAgICAgIGlucHV0LCB0aGlzLT5tdXRhYmxlX3N5bnRheCgpKSk7CisgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICAgICAgICB0aGlzLT5zeW50YXgoKS5kYXRhKCksIHRoaXMtPnN5bnRheCgpLmxlbmd0aCgpLAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6UEFSU0UsCisgICAgICAgICAgICAiZ29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uc3ludGF4Iik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdEF0RW5kKCkpIGdvdG8gc3VjY2VzczsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGRlZmF1bHQ6IHsKKyAgICAgIGhhbmRsZV91bnVzdWFsOgorICAgICAgICBpZiAodGFnID09IDAgfHwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdXaXJlVHlwZSh0YWcpID09CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRU5EX0dST1VQKSB7CisgICAgICAgICAgZ290byBzdWNjZXNzOworICAgICAgICB9CisgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTa2lwRmllbGQoCisgICAgICAgICAgICAgIGlucHV0LCB0YWcsIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSkpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KK3N1Y2Nlc3M6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdWNjZXNzOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvKQorICByZXR1cm4gdHJ1ZTsKK2ZhaWx1cmU6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9mYWlsdXJlOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvKQorICByZXR1cm4gZmFsc2U7CisjdW5kZWYgRE9fCit9CisKK3ZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9zdGFydDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90bykKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICBpZiAoaGFzX25hbWUoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+bmFtZSgpLmRhdGEoKSwgdGhpcy0+bmFtZSgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLm5hbWUiKTsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdNYXliZUFsaWFzZWQoCisgICAgICAxLCB0aGlzLT5uYW1lKCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgcGFja2FnZSA9IDI7CisgIGlmIChoYXNfcGFja2FnZSgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5wYWNrYWdlKCkuZGF0YSgpLCB0aGlzLT5wYWNrYWdlKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ucGFja2FnZSIpOworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ01heWJlQWxpYXNlZCgKKyAgICAgIDIsIHRoaXMtPnBhY2thZ2UoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIHN0cmluZyBkZXBlbmRlbmN5ID0gMzsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT5kZXBlbmRlbmN5X3NpemUoKTsgaSsrKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5kZXBlbmRlbmN5KGkpLmRhdGEoKSwgdGhpcy0+ZGVwZW5kZW5jeShpKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5kZXBlbmRlbmN5Iik7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nKAorICAgICAgMywgdGhpcy0+ZGVwZW5kZW5jeShpKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvIG1lc3NhZ2VfdHlwZSA9IDQ7CisgIGZvciAodW5zaWduZWQgaW50IGkgPSAwLCBuID0gdGhpcy0+bWVzc2FnZV90eXBlX3NpemUoKTsgaSA8IG47IGkrKykgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZU1lc3NhZ2VNYXliZVRvQXJyYXkoCisgICAgICA0LCB0aGlzLT5tZXNzYWdlX3R5cGUoaSksIG91dHB1dCk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8gZW51bV90eXBlID0gNTsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT5lbnVtX3R5cGVfc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlTWVzc2FnZU1heWJlVG9BcnJheSgKKyAgICAgIDUsIHRoaXMtPmVudW1fdHlwZShpKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuU2VydmljZURlc2NyaXB0b3JQcm90byBzZXJ2aWNlID0gNjsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT5zZXJ2aWNlX3NpemUoKTsgaSA8IG47IGkrKykgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZU1lc3NhZ2VNYXliZVRvQXJyYXkoCisgICAgICA2LCB0aGlzLT5zZXJ2aWNlKGkpLCBvdXRwdXQpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90byBleHRlbnNpb24gPSA3OworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPmV4dGVuc2lvbl9zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgNywgdGhpcy0+ZXh0ZW5zaW9uKGkpLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucyBvcHRpb25zID0gODsKKyAgaWYgKGhhc19vcHRpb25zKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgOCwgKnRoaXMtPm9wdGlvbnNfLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mbyBzb3VyY2VfY29kZV9pbmZvID0gOTsKKyAgaWYgKGhhc19zb3VyY2VfY29kZV9pbmZvKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgOSwgKnRoaXMtPnNvdXJjZV9jb2RlX2luZm9fLCBvdXRwdXQpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgaW50MzIgcHVibGljX2RlcGVuZGVuY3kgPSAxMDsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT5wdWJsaWNfZGVwZW5kZW5jeV9zaXplKCk7IGkrKykgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUludDMyKAorICAgICAgMTAsIHRoaXMtPnB1YmxpY19kZXBlbmRlbmN5KGkpLCBvdXRwdXQpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgaW50MzIgd2Vha19kZXBlbmRlbmN5ID0gMTE7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+d2Vha19kZXBlbmRlbmN5X3NpemUoKTsgaSsrKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlSW50MzIoCisgICAgICAxMSwgdGhpcy0+d2Vha19kZXBlbmRlbmN5KGkpLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIHN5bnRheCA9IDEyOworICBpZiAoaGFzX3N5bnRheCgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5zeW50YXgoKS5kYXRhKCksIHRoaXMtPnN5bnRheCgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLnN5bnRheCIpOworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ01heWJlQWxpYXNlZCgKKyAgICAgIDEyLCB0aGlzLT5zeW50YXgoKSwgb3V0cHV0KTsKKyAgfQorCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25GaWVsZHMoCisgICAgICAgIHVua25vd25fZmllbGRzKCksIG91dHB1dCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9lbmQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8pCit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIEZpbGVEZXNjcmlwdG9yUHJvdG86OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogdGFyZ2V0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8pCisgIC8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKKyAgaWYgKGhhc19uYW1lKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgIHRoaXMtPm5hbWUoKS5kYXRhKCksIHRoaXMtPm5hbWUoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5uYW1lIik7CisgICAgdGFyZ2V0ID0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ1RvQXJyYXkoCisgICAgICAgIDEsIHRoaXMtPm5hbWUoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIHN0cmluZyBwYWNrYWdlID0gMjsKKyAgaWYgKGhhc19wYWNrYWdlKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgIHRoaXMtPnBhY2thZ2UoKS5kYXRhKCksIHRoaXMtPnBhY2thZ2UoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5wYWNrYWdlIik7CisgICAgdGFyZ2V0ID0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ1RvQXJyYXkoCisgICAgICAgIDIsIHRoaXMtPnBhY2thZ2UoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIHN0cmluZyBkZXBlbmRlbmN5ID0gMzsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT5kZXBlbmRlbmN5X3NpemUoKTsgaSsrKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5kZXBlbmRlbmN5KGkpLmRhdGEoKSwgdGhpcy0+ZGVwZW5kZW5jeShpKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5kZXBlbmRlbmN5Iik7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OgorICAgICAgV3JpdGVTdHJpbmdUb0FycmF5KDMsIHRoaXMtPmRlcGVuZGVuY3koaSksIHRhcmdldCk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90byBtZXNzYWdlX3R5cGUgPSA0OworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPm1lc3NhZ2VfdHlwZV9zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6CisgICAgICBXcml0ZU1lc3NhZ2VOb1ZpcnR1YWxUb0FycmF5KAorICAgICAgICA0LCB0aGlzLT5tZXNzYWdlX3R5cGUoaSksIHRhcmdldCk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8gZW51bV90eXBlID0gNTsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT5lbnVtX3R5cGVfc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OgorICAgICAgV3JpdGVNZXNzYWdlTm9WaXJ0dWFsVG9BcnJheSgKKyAgICAgICAgNSwgdGhpcy0+ZW51bV90eXBlKGkpLCB0YXJnZXQpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvIHNlcnZpY2UgPSA2OworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPnNlcnZpY2Vfc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OgorICAgICAgV3JpdGVNZXNzYWdlTm9WaXJ0dWFsVG9BcnJheSgKKyAgICAgICAgNiwgdGhpcy0+c2VydmljZShpKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8gZXh0ZW5zaW9uID0gNzsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT5leHRlbnNpb25fc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OgorICAgICAgV3JpdGVNZXNzYWdlTm9WaXJ0dWFsVG9BcnJheSgKKyAgICAgICAgNywgdGhpcy0+ZXh0ZW5zaW9uKGkpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucyBvcHRpb25zID0gODsKKyAgaWYgKGhhc19vcHRpb25zKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6CisgICAgICBXcml0ZU1lc3NhZ2VOb1ZpcnR1YWxUb0FycmF5KAorICAgICAgICA4LCAqdGhpcy0+b3B0aW9uc18sIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvIHNvdXJjZV9jb2RlX2luZm8gPSA5OworICBpZiAoaGFzX3NvdXJjZV9jb2RlX2luZm8oKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjoKKyAgICAgIFdyaXRlTWVzc2FnZU5vVmlydHVhbFRvQXJyYXkoCisgICAgICAgIDksICp0aGlzLT5zb3VyY2VfY29kZV9pbmZvXywgdGFyZ2V0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIGludDMyIHB1YmxpY19kZXBlbmRlbmN5ID0gMTA7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+cHVibGljX2RlcGVuZGVuY3lfc2l6ZSgpOyBpKyspIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6CisgICAgICBXcml0ZUludDMyVG9BcnJheSgxMCwgdGhpcy0+cHVibGljX2RlcGVuZGVuY3koaSksIHRhcmdldCk7CisgIH0KKworICAvLyByZXBlYXRlZCBpbnQzMiB3ZWFrX2RlcGVuZGVuY3kgPSAxMTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT53ZWFrX2RlcGVuZGVuY3lfc2l6ZSgpOyBpKyspIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6CisgICAgICBXcml0ZUludDMyVG9BcnJheSgxMSwgdGhpcy0+d2Vha19kZXBlbmRlbmN5KGkpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIHN5bnRheCA9IDEyOworICBpZiAoaGFzX3N5bnRheCgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5zeW50YXgoKS5kYXRhKCksIHRoaXMtPnN5bnRheCgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLnN5bnRheCIpOworICAgIHRhcmdldCA9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdUb0FycmF5KAorICAgICAgICAxMiwgdGhpcy0+c3ludGF4KCksIHRhcmdldCk7CisgIH0KKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTZXJpYWxpemVVbmtub3duRmllbGRzVG9BcnJheSgKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSwgdGFyZ2V0KTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X2VuZDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90bykKKyAgcmV0dXJuIHRhcmdldDsKK30KKworaW50IEZpbGVEZXNjcmlwdG9yUHJvdG86OkJ5dGVTaXplKCkgY29uc3QgeworICBpbnQgdG90YWxfc2l6ZSA9IDA7CisKKyAgaWYgKF9oYXNfYml0c19bMCAvIDMyXSAmIDN1KSB7CisgICAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICAgIGlmIChoYXNfbmFtZSgpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U3RyaW5nU2l6ZSgKKyAgICAgICAgICB0aGlzLT5uYW1lKCkpOworICAgIH0KKworICAgIC8vIG9wdGlvbmFsIHN0cmluZyBwYWNrYWdlID0gMjsKKyAgICBpZiAoaGFzX3BhY2thZ2UoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlN0cmluZ1NpemUoCisgICAgICAgICAgdGhpcy0+cGFja2FnZSgpKTsKKyAgICB9CisKKyAgfQorICBpZiAoX2hhc19iaXRzX1s5IC8gMzJdICYgMzU4NHUpIHsKKyAgICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zIG9wdGlvbnMgPSA4OworICAgIGlmIChoYXNfb3B0aW9ucygpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6TWVzc2FnZVNpemVOb1ZpcnR1YWwoCisgICAgICAgICAgKnRoaXMtPm9wdGlvbnNfKTsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvIHNvdXJjZV9jb2RlX2luZm8gPSA5OworICAgIGlmIChoYXNfc291cmNlX2NvZGVfaW5mbygpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6TWVzc2FnZVNpemVOb1ZpcnR1YWwoCisgICAgICAgICAgKnRoaXMtPnNvdXJjZV9jb2RlX2luZm9fKTsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCBzdHJpbmcgc3ludGF4ID0gMTI7CisgICAgaWYgKGhhc19zeW50YXgoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlN0cmluZ1NpemUoCisgICAgICAgICAgdGhpcy0+c3ludGF4KCkpOworICAgIH0KKworICB9CisgIC8vIHJlcGVhdGVkIHN0cmluZyBkZXBlbmRlbmN5ID0gMzsKKyAgdG90YWxfc2l6ZSArPSAxICogdGhpcy0+ZGVwZW5kZW5jeV9zaXplKCk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+ZGVwZW5kZW5jeV9zaXplKCk7IGkrKykgeworICAgIHRvdGFsX3NpemUgKz0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlN0cmluZ1NpemUoCisgICAgICB0aGlzLT5kZXBlbmRlbmN5KGkpKTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIGludDMyIHB1YmxpY19kZXBlbmRlbmN5ID0gMTA7CisgIHsKKyAgICBpbnQgZGF0YV9zaXplID0gMDsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPnB1YmxpY19kZXBlbmRlbmN5X3NpemUoKTsgaSsrKSB7CisgICAgICBkYXRhX3NpemUgKz0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OgorICAgICAgICBJbnQzMlNpemUodGhpcy0+cHVibGljX2RlcGVuZGVuY3koaSkpOworICAgIH0KKyAgICB0b3RhbF9zaXplICs9IDEgKiB0aGlzLT5wdWJsaWNfZGVwZW5kZW5jeV9zaXplKCkgKyBkYXRhX3NpemU7CisgIH0KKworICAvLyByZXBlYXRlZCBpbnQzMiB3ZWFrX2RlcGVuZGVuY3kgPSAxMTsKKyAgeworICAgIGludCBkYXRhX3NpemUgPSAwOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+d2Vha19kZXBlbmRlbmN5X3NpemUoKTsgaSsrKSB7CisgICAgICBkYXRhX3NpemUgKz0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OgorICAgICAgICBJbnQzMlNpemUodGhpcy0+d2Vha19kZXBlbmRlbmN5KGkpKTsKKyAgICB9CisgICAgdG90YWxfc2l6ZSArPSAxICogdGhpcy0+d2Vha19kZXBlbmRlbmN5X3NpemUoKSArIGRhdGFfc2l6ZTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvIG1lc3NhZ2VfdHlwZSA9IDQ7CisgIHRvdGFsX3NpemUgKz0gMSAqIHRoaXMtPm1lc3NhZ2VfdHlwZV9zaXplKCk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+bWVzc2FnZV90eXBlX3NpemUoKTsgaSsrKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1lc3NhZ2VTaXplTm9WaXJ0dWFsKAorICAgICAgICB0aGlzLT5tZXNzYWdlX3R5cGUoaSkpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvIGVudW1fdHlwZSA9IDU7CisgIHRvdGFsX3NpemUgKz0gMSAqIHRoaXMtPmVudW1fdHlwZV9zaXplKCk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+ZW51bV90eXBlX3NpemUoKTsgaSsrKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1lc3NhZ2VTaXplTm9WaXJ0dWFsKAorICAgICAgICB0aGlzLT5lbnVtX3R5cGUoaSkpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvIHNlcnZpY2UgPSA2OworICB0b3RhbF9zaXplICs9IDEgKiB0aGlzLT5zZXJ2aWNlX3NpemUoKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT5zZXJ2aWNlX3NpemUoKTsgaSsrKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1lc3NhZ2VTaXplTm9WaXJ0dWFsKAorICAgICAgICB0aGlzLT5zZXJ2aWNlKGkpKTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8gZXh0ZW5zaW9uID0gNzsKKyAgdG90YWxfc2l6ZSArPSAxICogdGhpcy0+ZXh0ZW5zaW9uX3NpemUoKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT5leHRlbnNpb25fc2l6ZSgpOyBpKyspIHsKKyAgICB0b3RhbF9zaXplICs9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6TWVzc2FnZVNpemVOb1ZpcnR1YWwoCisgICAgICAgIHRoaXMtPmV4dGVuc2lvbihpKSk7CisgIH0KKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICB0b3RhbF9zaXplICs9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpDb21wdXRlVW5rbm93bkZpZWxkc1NpemUoCisgICAgICAgIHVua25vd25fZmllbGRzKCkpOworICB9CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSB0b3RhbF9zaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKKyAgcmV0dXJuIHRvdGFsX3NpemU7Cit9CisKK3ZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6TWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvKiBzb3VyY2UgPSAKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkR5bmFtaWNDYXN0VG9HZW5lcmF0ZWQ8Y29uc3QgRmlsZURlc2NyaXB0b3JQcm90bz4oCisgICAgICAgICAgJmZyb20pOworICBpZiAoc291cmNlID09IE5VTEwpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpSZWZsZWN0aW9uT3BzOjpNZXJnZShmcm9tLCB0aGlzKTsKKyAgfSBlbHNlIHsKKyAgICBNZXJnZUZyb20oKnNvdXJjZSk7CisgIH0KK30KKwordm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpNZXJnZUZyb20oY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBkZXBlbmRlbmN5Xy5NZXJnZUZyb20oZnJvbS5kZXBlbmRlbmN5Xyk7CisgIHB1YmxpY19kZXBlbmRlbmN5Xy5NZXJnZUZyb20oZnJvbS5wdWJsaWNfZGVwZW5kZW5jeV8pOworICB3ZWFrX2RlcGVuZGVuY3lfLk1lcmdlRnJvbShmcm9tLndlYWtfZGVwZW5kZW5jeV8pOworICBtZXNzYWdlX3R5cGVfLk1lcmdlRnJvbShmcm9tLm1lc3NhZ2VfdHlwZV8pOworICBlbnVtX3R5cGVfLk1lcmdlRnJvbShmcm9tLmVudW1fdHlwZV8pOworICBzZXJ2aWNlXy5NZXJnZUZyb20oZnJvbS5zZXJ2aWNlXyk7CisgIGV4dGVuc2lvbl8uTWVyZ2VGcm9tKGZyb20uZXh0ZW5zaW9uXyk7CisgIGlmIChmcm9tLl9oYXNfYml0c19bMCAvIDMyXSAmICgweGZmdSA8PCAoMCAlIDMyKSkpIHsKKyAgICBpZiAoZnJvbS5oYXNfbmFtZSgpKSB7CisgICAgICBzZXRfaGFzX25hbWUoKTsKKyAgICAgIG5hbWVfLkFzc2lnbldpdGhEZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgZnJvbS5uYW1lXyk7CisgICAgfQorICAgIGlmIChmcm9tLmhhc19wYWNrYWdlKCkpIHsKKyAgICAgIHNldF9oYXNfcGFja2FnZSgpOworICAgICAgcGFja2FnZV8uQXNzaWduV2l0aERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBmcm9tLnBhY2thZ2VfKTsKKyAgICB9CisgIH0KKyAgaWYgKGZyb20uX2hhc19iaXRzX1s5IC8gMzJdICYgKDB4ZmZ1IDw8ICg5ICUgMzIpKSkgeworICAgIGlmIChmcm9tLmhhc19vcHRpb25zKCkpIHsKKyAgICAgIG11dGFibGVfb3B0aW9ucygpLT46Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVPcHRpb25zOjpNZXJnZUZyb20oZnJvbS5vcHRpb25zKCkpOworICAgIH0KKyAgICBpZiAoZnJvbS5oYXNfc291cmNlX2NvZGVfaW5mbygpKSB7CisgICAgICBtdXRhYmxlX3NvdXJjZV9jb2RlX2luZm8oKS0+Ojpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb2RlSW5mbzo6TWVyZ2VGcm9tKGZyb20uc291cmNlX2NvZGVfaW5mbygpKTsKKyAgICB9CisgICAgaWYgKGZyb20uaGFzX3N5bnRheCgpKSB7CisgICAgICBzZXRfaGFzX3N5bnRheCgpOworICAgICAgc3ludGF4Xy5Bc3NpZ25XaXRoRGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGZyb20uc3ludGF4Xyk7CisgICAgfQorICB9CisgIGlmIChmcm9tLl9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5NZXJnZUZyb20oZnJvbS51bmtub3duX2ZpZWxkcygpKTsKKyAgfQorfQorCit2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OkNvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK3ZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6Q29weUZyb20oY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK2Jvb2wgRmlsZURlc2NyaXB0b3JQcm90bzo6SXNJbml0aWFsaXplZCgpIGNvbnN0IHsKKworICBpZiAoITo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFsbEFyZUluaXRpYWxpemVkKHRoaXMtPm1lc3NhZ2VfdHlwZSgpKSkgcmV0dXJuIGZhbHNlOworICBpZiAoITo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFsbEFyZUluaXRpYWxpemVkKHRoaXMtPmVudW1fdHlwZSgpKSkgcmV0dXJuIGZhbHNlOworICBpZiAoITo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFsbEFyZUluaXRpYWxpemVkKHRoaXMtPnNlcnZpY2UoKSkpIHJldHVybiBmYWxzZTsKKyAgaWYgKCE6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBbGxBcmVJbml0aWFsaXplZCh0aGlzLT5leHRlbnNpb24oKSkpIHJldHVybiBmYWxzZTsKKyAgaWYgKGhhc19vcHRpb25zKCkpIHsKKyAgICBpZiAoIXRoaXMtPm9wdGlvbnNfLT5Jc0luaXRpYWxpemVkKCkpIHJldHVybiBmYWxzZTsKKyAgfQorICByZXR1cm4gdHJ1ZTsKK30KKwordm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpTd2FwKEZpbGVEZXNjcmlwdG9yUHJvdG8qIG90aGVyKSB7CisgIGlmIChvdGhlciA9PSB0aGlzKSByZXR1cm47CisgIEludGVybmFsU3dhcChvdGhlcik7Cit9Cit2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OkludGVybmFsU3dhcChGaWxlRGVzY3JpcHRvclByb3RvKiBvdGhlcikgeworICBuYW1lXy5Td2FwKCZvdGhlci0+bmFtZV8pOworICBwYWNrYWdlXy5Td2FwKCZvdGhlci0+cGFja2FnZV8pOworICBkZXBlbmRlbmN5Xy5VbnNhZmVBcmVuYVN3YXAoJm90aGVyLT5kZXBlbmRlbmN5Xyk7CisgIHB1YmxpY19kZXBlbmRlbmN5Xy5VbnNhZmVBcmVuYVN3YXAoJm90aGVyLT5wdWJsaWNfZGVwZW5kZW5jeV8pOworICB3ZWFrX2RlcGVuZGVuY3lfLlVuc2FmZUFyZW5hU3dhcCgmb3RoZXItPndlYWtfZGVwZW5kZW5jeV8pOworICBtZXNzYWdlX3R5cGVfLlVuc2FmZUFyZW5hU3dhcCgmb3RoZXItPm1lc3NhZ2VfdHlwZV8pOworICBlbnVtX3R5cGVfLlVuc2FmZUFyZW5hU3dhcCgmb3RoZXItPmVudW1fdHlwZV8pOworICBzZXJ2aWNlXy5VbnNhZmVBcmVuYVN3YXAoJm90aGVyLT5zZXJ2aWNlXyk7CisgIGV4dGVuc2lvbl8uVW5zYWZlQXJlbmFTd2FwKCZvdGhlci0+ZXh0ZW5zaW9uXyk7CisgIHN0ZDo6c3dhcChvcHRpb25zXywgb3RoZXItPm9wdGlvbnNfKTsKKyAgc3RkOjpzd2FwKHNvdXJjZV9jb2RlX2luZm9fLCBvdGhlci0+c291cmNlX2NvZGVfaW5mb18pOworICBzeW50YXhfLlN3YXAoJm90aGVyLT5zeW50YXhfKTsKKyAgc3RkOjpzd2FwKF9oYXNfYml0c19bMF0sIG90aGVyLT5faGFzX2JpdHNfWzBdKTsKKyAgX2ludGVybmFsX21ldGFkYXRhXy5Td2FwKCZvdGhlci0+X2ludGVybmFsX21ldGFkYXRhXyk7CisgIHN0ZDo6c3dhcChfY2FjaGVkX3NpemVfLCBvdGhlci0+X2NhY2hlZF9zaXplXyk7Cit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgRmlsZURlc2NyaXB0b3JQcm90bzo6R2V0TWV0YWRhdGEoKSBjb25zdCB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIG1ldGFkYXRhOworICBtZXRhZGF0YS5kZXNjcmlwdG9yID0gRmlsZURlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXzsKKyAgbWV0YWRhdGEucmVmbGVjdGlvbiA9IEZpbGVEZXNjcmlwdG9yUHJvdG9fcmVmbGVjdGlvbl87CisgIHJldHVybiBtZXRhZGF0YTsKK30KKworI2lmIFBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworLy8gRmlsZURlc2NyaXB0b3JQcm90bworCisvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7Citib29sIEZpbGVEZXNjcmlwdG9yUHJvdG86Omhhc19uYW1lKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAxdSkgIT0gMDsKK30KK3ZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19uYW1lKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDF1OworfQordm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfbmFtZSgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMXU7Cit9Cit2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OmNsZWFyX25hbWUoKSB7CisgIG5hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX25hbWUoKTsKK30KKyBjb25zdCA6OnN0ZDo6c3RyaW5nJiBGaWxlRGVzY3JpcHRvclByb3RvOjpuYW1lKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLm5hbWUpCisgIHJldHVybiBuYW1lXy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpzZXRfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5uYW1lKQorfQorIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6c2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5uYW1lKQorfQorIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6c2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHNldF9oYXNfbmFtZSgpOworICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5uYW1lKQorfQorIDo6c3RkOjpzdHJpbmcqIEZpbGVEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfbmFtZSgpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLm5hbWUpCisgIHJldHVybiBuYW1lXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIDo6c3RkOjpzdHJpbmcqIEZpbGVEZXNjcmlwdG9yUHJvdG86OnJlbGVhc2VfbmFtZSgpIHsKKyAgY2xlYXJfaGFzX25hbWUoKTsKKyAgcmV0dXJuIG5hbWVfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpzZXRfYWxsb2NhdGVkX25hbWUoOjpzdGQ6OnN0cmluZyogbmFtZSkgeworICBpZiAobmFtZSAhPSBOVUxMKSB7CisgICAgc2V0X2hhc19uYW1lKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX25hbWUoKTsKKyAgfQorICBuYW1lXy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgbmFtZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLm5hbWUpCit9CisKKy8vIG9wdGlvbmFsIHN0cmluZyBwYWNrYWdlID0gMjsKK2Jvb2wgRmlsZURlc2NyaXB0b3JQcm90bzo6aGFzX3BhY2thZ2UoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDJ1KSAhPSAwOworfQordm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX3BhY2thZ2UoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMnU7Cit9Cit2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OmNsZWFyX2hhc19wYWNrYWdlKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAydTsKK30KK3ZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6Y2xlYXJfcGFja2FnZSgpIHsKKyAgcGFja2FnZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfcGFja2FnZSgpOworfQorIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEZpbGVEZXNjcmlwdG9yUHJvdG86OnBhY2thZ2UoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ucGFja2FnZSkKKyAgcmV0dXJuIHBhY2thZ2VfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OnNldF9wYWNrYWdlKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfcGFja2FnZSgpOworICBwYWNrYWdlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLnBhY2thZ2UpCit9Cisgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpzZXRfcGFja2FnZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX3BhY2thZ2UoKTsKKyAgcGFja2FnZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLnBhY2thZ2UpCit9Cisgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpzZXRfcGFja2FnZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19wYWNrYWdlKCk7CisgIHBhY2thZ2VfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLnBhY2thZ2UpCit9CisgOjpzdGQ6OnN0cmluZyogRmlsZURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9wYWNrYWdlKCkgeworICBzZXRfaGFzX3BhY2thZ2UoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ucGFja2FnZSkKKyAgcmV0dXJuIHBhY2thZ2VfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CisgOjpzdGQ6OnN0cmluZyogRmlsZURlc2NyaXB0b3JQcm90bzo6cmVsZWFzZV9wYWNrYWdlKCkgeworICBjbGVhcl9oYXNfcGFja2FnZSgpOworICByZXR1cm4gcGFja2FnZV8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OnNldF9hbGxvY2F0ZWRfcGFja2FnZSg6OnN0ZDo6c3RyaW5nKiBwYWNrYWdlKSB7CisgIGlmIChwYWNrYWdlICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX3BhY2thZ2UoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfcGFja2FnZSgpOworICB9CisgIHBhY2thZ2VfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBwYWNrYWdlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ucGFja2FnZSkKK30KKworLy8gcmVwZWF0ZWQgc3RyaW5nIGRlcGVuZGVuY3kgPSAzOworaW50IEZpbGVEZXNjcmlwdG9yUHJvdG86OmRlcGVuZGVuY3lfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIGRlcGVuZGVuY3lfLnNpemUoKTsKK30KK3ZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6Y2xlYXJfZGVwZW5kZW5jeSgpIHsKKyAgZGVwZW5kZW5jeV8uQ2xlYXIoKTsKK30KKyBjb25zdCA6OnN0ZDo6c3RyaW5nJiBGaWxlRGVzY3JpcHRvclByb3RvOjpkZXBlbmRlbmN5KGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLmRlcGVuZGVuY3kpCisgIHJldHVybiBkZXBlbmRlbmN5Xy5HZXQoaW5kZXgpOworfQorIDo6c3RkOjpzdHJpbmcqIEZpbGVEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfZGVwZW5kZW5jeShpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uZGVwZW5kZW5jeSkKKyAgcmV0dXJuIGRlcGVuZGVuY3lfLk11dGFibGUoaW5kZXgpOworfQorIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6c2V0X2RlcGVuZGVuY3koaW50IGluZGV4LCBjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLmRlcGVuZGVuY3kpCisgIGRlcGVuZGVuY3lfLk11dGFibGUoaW5kZXgpLT5hc3NpZ24odmFsdWUpOworfQorIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6c2V0X2RlcGVuZGVuY3koaW50IGluZGV4LCBjb25zdCBjaGFyKiB2YWx1ZSkgeworICBkZXBlbmRlbmN5Xy5NdXRhYmxlKGluZGV4KS0+YXNzaWduKHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLmRlcGVuZGVuY3kpCit9Cisgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpzZXRfZGVwZW5kZW5jeShpbnQgaW5kZXgsIGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBkZXBlbmRlbmN5Xy5NdXRhYmxlKGluZGV4KS0+YXNzaWduKAorICAgIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5kZXBlbmRlbmN5KQorfQorIDo6c3RkOjpzdHJpbmcqIEZpbGVEZXNjcmlwdG9yUHJvdG86OmFkZF9kZXBlbmRlbmN5KCkgeworICByZXR1cm4gZGVwZW5kZW5jeV8uQWRkKCk7Cit9Cisgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjphZGRfZGVwZW5kZW5jeShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBkZXBlbmRlbmN5Xy5BZGQoKS0+YXNzaWduKHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5kZXBlbmRlbmN5KQorfQorIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6YWRkX2RlcGVuZGVuY3koY29uc3QgY2hhciogdmFsdWUpIHsKKyAgZGVwZW5kZW5jeV8uQWRkKCktPmFzc2lnbih2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGRfY2hhcjpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5kZXBlbmRlbmN5KQorfQorIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6YWRkX2RlcGVuZGVuY3koY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIGRlcGVuZGVuY3lfLkFkZCgpLT5hc3NpZ24ocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLmRlcGVuZGVuY3kpCit9CisgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6OnN0ZDo6c3RyaW5nPiYKK0ZpbGVEZXNjcmlwdG9yUHJvdG86OmRlcGVuZGVuY3koKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLmRlcGVuZGVuY3kpCisgIHJldHVybiBkZXBlbmRlbmN5XzsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6c3RkOjpzdHJpbmc+KgorRmlsZURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9kZXBlbmRlbmN5KCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLmRlcGVuZGVuY3kpCisgIHJldHVybiAmZGVwZW5kZW5jeV87Cit9CisKKy8vIHJlcGVhdGVkIGludDMyIHB1YmxpY19kZXBlbmRlbmN5ID0gMTA7CitpbnQgRmlsZURlc2NyaXB0b3JQcm90bzo6cHVibGljX2RlcGVuZGVuY3lfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIHB1YmxpY19kZXBlbmRlbmN5Xy5zaXplKCk7Cit9Cit2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OmNsZWFyX3B1YmxpY19kZXBlbmRlbmN5KCkgeworICBwdWJsaWNfZGVwZW5kZW5jeV8uQ2xlYXIoKTsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIEZpbGVEZXNjcmlwdG9yUHJvdG86OnB1YmxpY19kZXBlbmRlbmN5KGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLnB1YmxpY19kZXBlbmRlbmN5KQorICByZXR1cm4gcHVibGljX2RlcGVuZGVuY3lfLkdldChpbmRleCk7Cit9Cisgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpzZXRfcHVibGljX2RlcGVuZGVuY3koaW50IGluZGV4LCA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKSB7CisgIHB1YmxpY19kZXBlbmRlbmN5Xy5TZXQoaW5kZXgsIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5wdWJsaWNfZGVwZW5kZW5jeSkKK30KKyB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OmFkZF9wdWJsaWNfZGVwZW5kZW5jeSg6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKSB7CisgIHB1YmxpY19kZXBlbmRlbmN5Xy5BZGQodmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLnB1YmxpY19kZXBlbmRlbmN5KQorfQorIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiA+JgorRmlsZURlc2NyaXB0b3JQcm90bzo6cHVibGljX2RlcGVuZGVuY3koKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLnB1YmxpY19kZXBlbmRlbmN5KQorICByZXR1cm4gcHVibGljX2RlcGVuZGVuY3lfOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiA+KgorRmlsZURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9wdWJsaWNfZGVwZW5kZW5jeSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5wdWJsaWNfZGVwZW5kZW5jeSkKKyAgcmV0dXJuICZwdWJsaWNfZGVwZW5kZW5jeV87Cit9CisKKy8vIHJlcGVhdGVkIGludDMyIHdlYWtfZGVwZW5kZW5jeSA9IDExOworaW50IEZpbGVEZXNjcmlwdG9yUHJvdG86OndlYWtfZGVwZW5kZW5jeV9zaXplKCkgY29uc3QgeworICByZXR1cm4gd2Vha19kZXBlbmRlbmN5Xy5zaXplKCk7Cit9Cit2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OmNsZWFyX3dlYWtfZGVwZW5kZW5jeSgpIHsKKyAgd2Vha19kZXBlbmRlbmN5Xy5DbGVhcigpOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgRmlsZURlc2NyaXB0b3JQcm90bzo6d2Vha19kZXBlbmRlbmN5KGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLndlYWtfZGVwZW5kZW5jeSkKKyAgcmV0dXJuIHdlYWtfZGVwZW5kZW5jeV8uR2V0KGluZGV4KTsKK30KKyB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OnNldF93ZWFrX2RlcGVuZGVuY3koaW50IGluZGV4LCA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKSB7CisgIHdlYWtfZGVwZW5kZW5jeV8uU2V0KGluZGV4LCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ud2Vha19kZXBlbmRlbmN5KQorfQorIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6YWRkX3dlYWtfZGVwZW5kZW5jeSg6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKSB7CisgIHdlYWtfZGVwZW5kZW5jeV8uQWRkKHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by53ZWFrX2RlcGVuZGVuY3kpCit9CisgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZEZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyID4mCitGaWxlRGVzY3JpcHRvclByb3RvOjp3ZWFrX2RlcGVuZGVuY3koKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLndlYWtfZGVwZW5kZW5jeSkKKyAgcmV0dXJuIHdlYWtfZGVwZW5kZW5jeV87Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZEZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyID4qCitGaWxlRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX3dlYWtfZGVwZW5kZW5jeSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by53ZWFrX2RlcGVuZGVuY3kpCisgIHJldHVybiAmd2Vha19kZXBlbmRlbmN5XzsKK30KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8gbWVzc2FnZV90eXBlID0gNDsKK2ludCBGaWxlRGVzY3JpcHRvclByb3RvOjptZXNzYWdlX3R5cGVfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIG1lc3NhZ2VfdHlwZV8uc2l6ZSgpOworfQordm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9tZXNzYWdlX3R5cGUoKSB7CisgIG1lc3NhZ2VfdHlwZV8uQ2xlYXIoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclByb3RvJiBGaWxlRGVzY3JpcHRvclByb3RvOjptZXNzYWdlX3R5cGUoaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ubWVzc2FnZV90eXBlKQorICByZXR1cm4gbWVzc2FnZV90eXBlXy5HZXQoaW5kZXgpOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG8qIEZpbGVEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfbWVzc2FnZV90eXBlKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5tZXNzYWdlX3R5cGUpCisgIHJldHVybiBtZXNzYWdlX3R5cGVfLk11dGFibGUoaW5kZXgpOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG8qIEZpbGVEZXNjcmlwdG9yUHJvdG86OmFkZF9tZXNzYWdlX3R5cGUoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ubWVzc2FnZV90eXBlKQorICByZXR1cm4gbWVzc2FnZV90eXBlXy5BZGQoKTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG8gPioKK0ZpbGVEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfbWVzc2FnZV90eXBlKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLm1lc3NhZ2VfdHlwZSkKKyAgcmV0dXJuICZtZXNzYWdlX3R5cGVfOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQcm90byA+JgorRmlsZURlc2NyaXB0b3JQcm90bzo6bWVzc2FnZV90eXBlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5tZXNzYWdlX3R5cGUpCisgIHJldHVybiBtZXNzYWdlX3R5cGVfOworfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8gZW51bV90eXBlID0gNTsKK2ludCBGaWxlRGVzY3JpcHRvclByb3RvOjplbnVtX3R5cGVfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIGVudW1fdHlwZV8uc2l6ZSgpOworfQordm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9lbnVtX3R5cGUoKSB7CisgIGVudW1fdHlwZV8uQ2xlYXIoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bURlc2NyaXB0b3JQcm90byYgRmlsZURlc2NyaXB0b3JQcm90bzo6ZW51bV90eXBlKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLmVudW1fdHlwZSkKKyAgcmV0dXJuIGVudW1fdHlwZV8uR2V0KGluZGV4KTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bURlc2NyaXB0b3JQcm90byogRmlsZURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9lbnVtX3R5cGUoaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLmVudW1fdHlwZSkKKyAgcmV0dXJuIGVudW1fdHlwZV8uTXV0YWJsZShpbmRleCk7Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yUHJvdG8qIEZpbGVEZXNjcmlwdG9yUHJvdG86OmFkZF9lbnVtX3R5cGUoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uZW51bV90eXBlKQorICByZXR1cm4gZW51bV90eXBlXy5BZGQoKTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvclByb3RvID4qCitGaWxlRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX2VudW1fdHlwZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5lbnVtX3R5cGUpCisgIHJldHVybiAmZW51bV90eXBlXzsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvclByb3RvID4mCitGaWxlRGVzY3JpcHRvclByb3RvOjplbnVtX3R5cGUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLmVudW1fdHlwZSkKKyAgcmV0dXJuIGVudW1fdHlwZV87Cit9CisKKy8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuU2VydmljZURlc2NyaXB0b3JQcm90byBzZXJ2aWNlID0gNjsKK2ludCBGaWxlRGVzY3JpcHRvclByb3RvOjpzZXJ2aWNlX3NpemUoKSBjb25zdCB7CisgIHJldHVybiBzZXJ2aWNlXy5zaXplKCk7Cit9Cit2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OmNsZWFyX3NlcnZpY2UoKSB7CisgIHNlcnZpY2VfLkNsZWFyKCk7Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8mIEZpbGVEZXNjcmlwdG9yUHJvdG86OnNlcnZpY2UoaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uc2VydmljZSkKKyAgcmV0dXJuIHNlcnZpY2VfLkdldChpbmRleCk7Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6OlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8qIEZpbGVEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfc2VydmljZShpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uc2VydmljZSkKKyAgcmV0dXJuIHNlcnZpY2VfLk11dGFibGUoaW5kZXgpOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpTZXJ2aWNlRGVzY3JpcHRvclByb3RvKiBGaWxlRGVzY3JpcHRvclByb3RvOjphZGRfc2VydmljZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5zZXJ2aWNlKQorICByZXR1cm4gc2VydmljZV8uQWRkKCk7Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6U2VydmljZURlc2NyaXB0b3JQcm90byA+KgorRmlsZURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9zZXJ2aWNlKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLnNlcnZpY2UpCisgIHJldHVybiAmc2VydmljZV87Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6U2VydmljZURlc2NyaXB0b3JQcm90byA+JgorRmlsZURlc2NyaXB0b3JQcm90bzo6c2VydmljZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uc2VydmljZSkKKyAgcmV0dXJuIHNlcnZpY2VfOworfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvIGV4dGVuc2lvbiA9IDc7CitpbnQgRmlsZURlc2NyaXB0b3JQcm90bzo6ZXh0ZW5zaW9uX3NpemUoKSBjb25zdCB7CisgIHJldHVybiBleHRlbnNpb25fLnNpemUoKTsKK30KK3ZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6Y2xlYXJfZXh0ZW5zaW9uKCkgeworICBleHRlbnNpb25fLkNsZWFyKCk7Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvJiBGaWxlRGVzY3JpcHRvclByb3RvOjpleHRlbnNpb24oaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uZXh0ZW5zaW9uKQorICByZXR1cm4gZXh0ZW5zaW9uXy5HZXQoaW5kZXgpOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90byogRmlsZURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9leHRlbnNpb24oaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLmV4dGVuc2lvbikKKyAgcmV0dXJuIGV4dGVuc2lvbl8uTXV0YWJsZShpbmRleCk7Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvKiBGaWxlRGVzY3JpcHRvclByb3RvOjphZGRfZXh0ZW5zaW9uKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLmV4dGVuc2lvbikKKyAgcmV0dXJuIGV4dGVuc2lvbl8uQWRkKCk7Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG8gPioKK0ZpbGVEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfZXh0ZW5zaW9uKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLmV4dGVuc2lvbikKKyAgcmV0dXJuICZleHRlbnNpb25fOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvID4mCitGaWxlRGVzY3JpcHRvclByb3RvOjpleHRlbnNpb24oKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLmV4dGVuc2lvbikKKyAgcmV0dXJuIGV4dGVuc2lvbl87Cit9CisKKy8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMgb3B0aW9ucyA9IDg7Citib29sIEZpbGVEZXNjcmlwdG9yUHJvdG86Omhhc19vcHRpb25zKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMjAwdSkgIT0gMDsKK30KK3ZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19vcHRpb25zKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAyMDB1OworfQordm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfb3B0aW9ucygpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDIwMHU7Cit9Cit2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OmNsZWFyX29wdGlvbnMoKSB7CisgIGlmIChvcHRpb25zXyAhPSBOVUxMKSBvcHRpb25zXy0+Ojpnb29nbGU6OnByb3RvYnVmOjpGaWxlT3B0aW9uczo6Q2xlYXIoKTsKKyAgY2xlYXJfaGFzX29wdGlvbnMoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZU9wdGlvbnMmIEZpbGVEZXNjcmlwdG9yUHJvdG86Om9wdGlvbnMoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ub3B0aW9ucykKKyAgcmV0dXJuIG9wdGlvbnNfICE9IE5VTEwgPyAqb3B0aW9uc18gOiAqZGVmYXVsdF9pbnN0YW5jZV8tPm9wdGlvbnNfOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlT3B0aW9ucyogRmlsZURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9vcHRpb25zKCkgeworICBzZXRfaGFzX29wdGlvbnMoKTsKKyAgaWYgKG9wdGlvbnNfID09IE5VTEwpIHsKKyAgICBvcHRpb25zXyA9IG5ldyA6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVPcHRpb25zOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLm9wdGlvbnMpCisgIHJldHVybiBvcHRpb25zXzsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZU9wdGlvbnMqIEZpbGVEZXNjcmlwdG9yUHJvdG86OnJlbGVhc2Vfb3B0aW9ucygpIHsKKyAgY2xlYXJfaGFzX29wdGlvbnMoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlT3B0aW9ucyogdGVtcCA9IG9wdGlvbnNfOworICBvcHRpb25zXyA9IE5VTEw7CisgIHJldHVybiB0ZW1wOworfQordm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpzZXRfYWxsb2NhdGVkX29wdGlvbnMoOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlT3B0aW9ucyogb3B0aW9ucykgeworICBkZWxldGUgb3B0aW9uc187CisgIG9wdGlvbnNfID0gb3B0aW9uczsKKyAgaWYgKG9wdGlvbnMpIHsKKyAgICBzZXRfaGFzX29wdGlvbnMoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfb3B0aW9ucygpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLm9wdGlvbnMpCit9CisKKy8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8gc291cmNlX2NvZGVfaW5mbyA9IDk7Citib29sIEZpbGVEZXNjcmlwdG9yUHJvdG86Omhhc19zb3VyY2VfY29kZV9pbmZvKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwNDAwdSkgIT0gMDsKK30KK3ZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19zb3VyY2VfY29kZV9pbmZvKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDA0MDB1OworfQordm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfc291cmNlX2NvZGVfaW5mbygpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDQwMHU7Cit9Cit2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OmNsZWFyX3NvdXJjZV9jb2RlX2luZm8oKSB7CisgIGlmIChzb3VyY2VfY29kZV9pbmZvXyAhPSBOVUxMKSBzb3VyY2VfY29kZV9pbmZvXy0+Ojpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb2RlSW5mbzo6Q2xlYXIoKTsKKyAgY2xlYXJfaGFzX3NvdXJjZV9jb2RlX2luZm8oKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29kZUluZm8mIEZpbGVEZXNjcmlwdG9yUHJvdG86OnNvdXJjZV9jb2RlX2luZm8oKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uc291cmNlX2NvZGVfaW5mbykKKyAgcmV0dXJuIHNvdXJjZV9jb2RlX2luZm9fICE9IE5VTEwgPyAqc291cmNlX2NvZGVfaW5mb18gOiAqZGVmYXVsdF9pbnN0YW5jZV8tPnNvdXJjZV9jb2RlX2luZm9fOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb2RlSW5mbyogRmlsZURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9zb3VyY2VfY29kZV9pbmZvKCkgeworICBzZXRfaGFzX3NvdXJjZV9jb2RlX2luZm8oKTsKKyAgaWYgKHNvdXJjZV9jb2RlX2luZm9fID09IE5VTEwpIHsKKyAgICBzb3VyY2VfY29kZV9pbmZvXyA9IG5ldyA6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvZGVJbmZvOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLnNvdXJjZV9jb2RlX2luZm8pCisgIHJldHVybiBzb3VyY2VfY29kZV9pbmZvXzsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29kZUluZm8qIEZpbGVEZXNjcmlwdG9yUHJvdG86OnJlbGVhc2Vfc291cmNlX2NvZGVfaW5mbygpIHsKKyAgY2xlYXJfaGFzX3NvdXJjZV9jb2RlX2luZm8oKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb2RlSW5mbyogdGVtcCA9IHNvdXJjZV9jb2RlX2luZm9fOworICBzb3VyY2VfY29kZV9pbmZvXyA9IE5VTEw7CisgIHJldHVybiB0ZW1wOworfQordm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpzZXRfYWxsb2NhdGVkX3NvdXJjZV9jb2RlX2luZm8oOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb2RlSW5mbyogc291cmNlX2NvZGVfaW5mbykgeworICBkZWxldGUgc291cmNlX2NvZGVfaW5mb187CisgIHNvdXJjZV9jb2RlX2luZm9fID0gc291cmNlX2NvZGVfaW5mbzsKKyAgaWYgKHNvdXJjZV9jb2RlX2luZm8pIHsKKyAgICBzZXRfaGFzX3NvdXJjZV9jb2RlX2luZm8oKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfc291cmNlX2NvZGVfaW5mbygpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLnNvdXJjZV9jb2RlX2luZm8pCit9CisKKy8vIG9wdGlvbmFsIHN0cmluZyBzeW50YXggPSAxMjsKK2Jvb2wgRmlsZURlc2NyaXB0b3JQcm90bzo6aGFzX3N5bnRheCgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDgwMHUpICE9IDA7Cit9Cit2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OnNldF9oYXNfc3ludGF4KCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDA4MDB1OworfQordm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfc3ludGF4KCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwODAwdTsKK30KK3ZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6Y2xlYXJfc3ludGF4KCkgeworICBzeW50YXhfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX3N5bnRheCgpOworfQorIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEZpbGVEZXNjcmlwdG9yUHJvdG86OnN5bnRheCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5zeW50YXgpCisgIHJldHVybiBzeW50YXhfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OnNldF9zeW50YXgoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgc2V0X2hhc19zeW50YXgoKTsKKyAgc3ludGF4Xy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLnN5bnRheCkKK30KKyB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OnNldF9zeW50YXgoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgc2V0X2hhc19zeW50YXgoKTsKKyAgc3ludGF4Xy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uc3ludGF4KQorfQorIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6c2V0X3N5bnRheChjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19zeW50YXgoKTsKKyAgc3ludGF4Xy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5zeW50YXgpCit9CisgOjpzdGQ6OnN0cmluZyogRmlsZURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9zeW50YXgoKSB7CisgIHNldF9oYXNfc3ludGF4KCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLnN5bnRheCkKKyAgcmV0dXJuIHN5bnRheF8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyA6OnN0ZDo6c3RyaW5nKiBGaWxlRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX3N5bnRheCgpIHsKKyAgY2xlYXJfaGFzX3N5bnRheCgpOworICByZXR1cm4gc3ludGF4Xy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6c2V0X2FsbG9jYXRlZF9zeW50YXgoOjpzdGQ6OnN0cmluZyogc3ludGF4KSB7CisgIGlmIChzeW50YXggIT0gTlVMTCkgeworICAgIHNldF9oYXNfc3ludGF4KCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX3N5bnRheCgpOworICB9CisgIHN5bnRheF8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHN5bnRheCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLnN5bnRheCkKK30KKworI2VuZGlmICAvLyBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisjaWYgIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKK2NvbnN0IGludCBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6OmtTdGFydEZpZWxkTnVtYmVyOworY29uc3QgaW50IERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZTo6a0VuZEZpZWxkTnVtYmVyOworI2VuZGlmICAvLyAhZGVmaW5lZChfTVNDX1ZFUikgfHwgX01TQ19WRVIgPj0gMTkwMAorCitEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6OkRlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZSgpCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgeworICBTaGFyZWRDdG9yKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLkV4dGVuc2lvblJhbmdlKQorfQorCit2b2lkIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZTo6SW5pdEFzRGVmYXVsdEluc3RhbmNlKCkgeworfQorCitEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6OkRlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZShjb25zdCBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UmIGZyb20pCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksCisgICAgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29weV9jb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLkV4dGVuc2lvblJhbmdlKQorfQorCit2b2lkIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZTo6U2hhcmVkQ3RvcigpIHsKKyAgX2NhY2hlZF9zaXplXyA9IDA7CisgIHN0YXJ0XyA9IDA7CisgIGVuZF8gPSAwOworICA6Om1lbXNldChfaGFzX2JpdHNfLCAwLCBzaXplb2YoX2hhc19iaXRzXykpOworfQorCitEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6On5EZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChkZXN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uRXh0ZW5zaW9uUmFuZ2UpCisgIFNoYXJlZER0b3IoKTsKK30KKwordm9pZCBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6OlNoYXJlZER0b3IoKSB7CisgIGlmICh0aGlzICE9IGRlZmF1bHRfaW5zdGFuY2VfKSB7CisgIH0KK30KKwordm9pZCBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6OlNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0IHsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHNpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6OmRlc2NyaXB0b3IoKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICByZXR1cm4gRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlX2Rlc2NyaXB0b3JfOworfQorCitjb25zdCBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UmIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZTo6ZGVmYXVsdF9pbnN0YW5jZSgpIHsKKyAgaWYgKGRlZmF1bHRfaW5zdGFuY2VfID09IE5VTEwpIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgcmV0dXJuICpkZWZhdWx0X2luc3RhbmNlXzsKK30KKworRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlKiBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6OmRlZmF1bHRfaW5zdGFuY2VfID0gTlVMTDsKKworRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlKiBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6Ok5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3QgeworICBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UqIG4gPSBuZXcgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOworICBpZiAoYXJlbmEgIT0gTlVMTCkgeworICAgIGFyZW5hLT5Pd24obik7CisgIH0KKyAgcmV0dXJuIG47Cit9CisKK3ZvaWQgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOjpDbGVhcigpIHsKKyNkZWZpbmUgWlJfSEVMUEVSXyhmKSByZWludGVycHJldF9jYXN0PGNoYXIqPihcCisgICZyZWludGVycHJldF9jYXN0PERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZSo+KDE2KS0+ZikKKworI2RlZmluZSBaUl8oZmlyc3QsIGxhc3QpIGRvIHtcCisgIDo6bWVtc2V0KCZmaXJzdCwgMCxcCisgICAgICAgICAgIFpSX0hFTFBFUl8obGFzdCkgLSBaUl9IRUxQRVJfKGZpcnN0KSArIHNpemVvZihsYXN0KSk7XAorfSB3aGlsZSAoMCkKKworICBaUl8oc3RhcnRfLCBlbmRfKTsKKworI3VuZGVmIFpSX0hFTFBFUl8KKyN1bmRlZiBaUl8KKworICA6Om1lbXNldChfaGFzX2JpdHNfLCAwLCBzaXplb2YoX2hhc19iaXRzXykpOworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkNsZWFyKCk7CisgIH0KK30KKworYm9vbCBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6Ok1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCkgeworI2RlZmluZSBET18oRVhQUkVTU0lPTikgaWYgKCEoRVhQUkVTU0lPTikpIGdvdG8gZmFpbHVyZQorICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiB0YWc7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdGFydDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLkV4dGVuc2lvblJhbmdlKQorICBmb3IgKDs7KSB7CisgICAgOjpzdGQ6OnBhaXI8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyLCBib29sPiBwID0gaW5wdXQtPlJlYWRUYWdXaXRoQ3V0b2ZmKDEyNyk7CisgICAgdGFnID0gcC5maXJzdDsKKyAgICBpZiAoIXAuc2Vjb25kKSBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgIHN3aXRjaCAoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ0ZpZWxkTnVtYmVyKHRhZykpIHsKKyAgICAgIC8vIG9wdGlvbmFsIGludDMyIHN0YXJ0ID0gMTsKKyAgICAgIGNhc2UgMTogeworICAgICAgICBpZiAodGFnID09IDgpIHsKKyAgICAgICAgICBET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPAorICAgICAgICAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0lOVDMyPigKKyAgICAgICAgICAgICAgICAgaW5wdXQsICZzdGFydF8pKSk7CisgICAgICAgICAgc2V0X2hhc19zdGFydCgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMTYpKSBnb3RvIHBhcnNlX2VuZDsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIGludDMyIGVuZCA9IDI7CisgICAgICBjYXNlIDI6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAxNikgeworICAgICAgICAgcGFyc2VfZW5kOgorICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfSU5UMzI+KAorICAgICAgICAgICAgICAgICBpbnB1dCwgJmVuZF8pKSk7CisgICAgICAgICAgc2V0X2hhc19lbmQoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0QXRFbmQoKSkgZ290byBzdWNjZXNzOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgZGVmYXVsdDogeworICAgICAgaGFuZGxlX3VudXN1YWw6CisgICAgICAgIGlmICh0YWcgPT0gMCB8fAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ1dpcmVUeXBlKHRhZykgPT0KKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVApIHsKKyAgICAgICAgICBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIH0KKyAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNraXBGaWVsZCgKKyAgICAgICAgICAgICAgaW5wdXQsIHRhZywgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpKSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgfQorc3VjY2VzczoKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N1Y2Nlc3M6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5FeHRlbnNpb25SYW5nZSkKKyAgcmV0dXJuIHRydWU7CitmYWlsdXJlOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2VfZmFpbHVyZTpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLkV4dGVuc2lvblJhbmdlKQorICByZXR1cm4gZmFsc2U7CisjdW5kZWYgRE9fCit9CisKK3ZvaWQgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uRXh0ZW5zaW9uUmFuZ2UpCisgIC8vIG9wdGlvbmFsIGludDMyIHN0YXJ0ID0gMTsKKyAgaWYgKGhhc19zdGFydCgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlSW50MzIoMSwgdGhpcy0+c3RhcnQoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGludDMyIGVuZCA9IDI7CisgIGlmIChoYXNfZW5kKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVJbnQzMigyLCB0aGlzLT5lbmQoKSwgb3V0cHV0KTsKKyAgfQorCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25GaWVsZHMoCisgICAgICAgIHVua25vd25fZmllbGRzKCksIG91dHB1dCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9lbmQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5FeHRlbnNpb25SYW5nZSkKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIHRhcmdldCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uRXh0ZW5zaW9uUmFuZ2UpCisgIC8vIG9wdGlvbmFsIGludDMyIHN0YXJ0ID0gMTsKKyAgaWYgKGhhc19zdGFydCgpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlSW50MzJUb0FycmF5KDEsIHRoaXMtPnN0YXJ0KCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBpbnQzMiBlbmQgPSAyOworICBpZiAoaGFzX2VuZCgpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlSW50MzJUb0FycmF5KDIsIHRoaXMtPmVuZCgpLCB0YXJnZXQpOworICB9CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bkZpZWxkc1RvQXJyYXkoCisgICAgICAgIHVua25vd25fZmllbGRzKCksIHRhcmdldCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9lbmQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5FeHRlbnNpb25SYW5nZSkKKyAgcmV0dXJuIHRhcmdldDsKK30KKworaW50IERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZTo6Qnl0ZVNpemUoKSBjb25zdCB7CisgIGludCB0b3RhbF9zaXplID0gMDsKKworICBpZiAoX2hhc19iaXRzX1swIC8gMzJdICYgM3UpIHsKKyAgICAvLyBvcHRpb25hbCBpbnQzMiBzdGFydCA9IDE7CisgICAgaWYgKGhhc19zdGFydCgpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6SW50MzJTaXplKAorICAgICAgICAgIHRoaXMtPnN0YXJ0KCkpOworICAgIH0KKworICAgIC8vIG9wdGlvbmFsIGludDMyIGVuZCA9IDI7CisgICAgaWYgKGhhc19lbmQoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkludDMyU2l6ZSgKKyAgICAgICAgICB0aGlzLT5lbmQoKSk7CisgICAgfQorCisgIH0KKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6Q29tcHV0ZVVua25vd25GaWVsZHNTaXplKAorICAgICAgICB1bmtub3duX2ZpZWxkcygpKTsKKyAgfQorICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gdG90YWxfc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7CisgIHJldHVybiB0b3RhbF9zaXplOworfQorCit2b2lkIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZTo6TWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBjb25zdCBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UqIHNvdXJjZSA9IAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RHluYW1pY0Nhc3RUb0dlbmVyYXRlZDxjb25zdCBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U+KAorICAgICAgICAgICZmcm9tKTsKKyAgaWYgKHNvdXJjZSA9PSBOVUxMKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6UmVmbGVjdGlvbk9wczo6TWVyZ2UoZnJvbSwgdGhpcyk7CisgIH0gZWxzZSB7CisgICAgTWVyZ2VGcm9tKCpzb3VyY2UpOworICB9Cit9CisKK3ZvaWQgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOjpNZXJnZUZyb20oY29uc3QgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGlmIChmcm9tLl9oYXNfYml0c19bMCAvIDMyXSAmICgweGZmdSA8PCAoMCAlIDMyKSkpIHsKKyAgICBpZiAoZnJvbS5oYXNfc3RhcnQoKSkgeworICAgICAgc2V0X3N0YXJ0KGZyb20uc3RhcnQoKSk7CisgICAgfQorICAgIGlmIChmcm9tLmhhc19lbmQoKSkgeworICAgICAgc2V0X2VuZChmcm9tLmVuZCgpKTsKKyAgICB9CisgIH0KKyAgaWYgKGZyb20uX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPk1lcmdlRnJvbShmcm9tLnVua25vd25fZmllbGRzKCkpOworICB9Cit9CisKK3ZvaWQgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOjpDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCit2b2lkIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZTo6Q29weUZyb20oY29uc3QgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKworYm9vbCBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6OklzSW5pdGlhbGl6ZWQoKSBjb25zdCB7CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOjpTd2FwKERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZSogb3RoZXIpIHsKKyAgaWYgKG90aGVyID09IHRoaXMpIHJldHVybjsKKyAgSW50ZXJuYWxTd2FwKG90aGVyKTsKK30KK3ZvaWQgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOjpJbnRlcm5hbFN3YXAoRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlKiBvdGhlcikgeworICBzdGQ6OnN3YXAoc3RhcnRfLCBvdGhlci0+c3RhcnRfKTsKKyAgc3RkOjpzd2FwKGVuZF8sIG90aGVyLT5lbmRfKTsKKyAgc3RkOjpzd2FwKF9oYXNfYml0c19bMF0sIG90aGVyLT5faGFzX2JpdHNfWzBdKTsKKyAgX2ludGVybmFsX21ldGFkYXRhXy5Td2FwKCZvdGhlci0+X2ludGVybmFsX21ldGFkYXRhXyk7CisgIHN0ZDo6c3dhcChfY2FjaGVkX3NpemVfLCBvdGhlci0+X2NhY2hlZF9zaXplXyk7Cit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOjpHZXRNZXRhZGF0YSgpIGNvbnN0IHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgbWV0YWRhdGE7CisgIG1ldGFkYXRhLmRlc2NyaXB0b3IgPSBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2VfZGVzY3JpcHRvcl87CisgIG1ldGFkYXRhLnJlZmxlY3Rpb24gPSBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2VfcmVmbGVjdGlvbl87CisgIHJldHVybiBtZXRhZGF0YTsKK30KKworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyNpZiAhZGVmaW5lZChfTVNDX1ZFUikgfHwgX01TQ19WRVIgPj0gMTkwMAorY29uc3QgaW50IERlc2NyaXB0b3JQcm90b19SZXNlcnZlZFJhbmdlOjprU3RhcnRGaWVsZE51bWJlcjsKK2NvbnN0IGludCBEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZTo6a0VuZEZpZWxkTnVtYmVyOworI2VuZGlmICAvLyAhZGVmaW5lZChfTVNDX1ZFUikgfHwgX01TQ19WRVIgPj0gMTkwMAorCitEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZTo6RGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2UoKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpLCBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5SZXNlcnZlZFJhbmdlKQorfQorCit2b2lkIERlc2NyaXB0b3JQcm90b19SZXNlcnZlZFJhbmdlOjpJbml0QXNEZWZhdWx0SW5zdGFuY2UoKSB7Cit9CisKK0Rlc2NyaXB0b3JQcm90b19SZXNlcnZlZFJhbmdlOjpEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZShjb25zdCBEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZSYgZnJvbSkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwKKyAgICBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICBNZXJnZUZyb20oZnJvbSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb3B5X2NvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uUmVzZXJ2ZWRSYW5nZSkKK30KKwordm9pZCBEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZTo6U2hhcmVkQ3RvcigpIHsKKyAgX2NhY2hlZF9zaXplXyA9IDA7CisgIHN0YXJ0XyA9IDA7CisgIGVuZF8gPSAwOworICA6Om1lbXNldChfaGFzX2JpdHNfLCAwLCBzaXplb2YoX2hhc19iaXRzXykpOworfQorCitEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZTo6fkRlc2NyaXB0b3JQcm90b19SZXNlcnZlZFJhbmdlKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZGVzdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLlJlc2VydmVkUmFuZ2UpCisgIFNoYXJlZER0b3IoKTsKK30KKwordm9pZCBEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZTo6U2hhcmVkRHRvcigpIHsKKyAgaWYgKHRoaXMgIT0gZGVmYXVsdF9pbnN0YW5jZV8pIHsKKyAgfQorfQorCit2b2lkIERlc2NyaXB0b3JQcm90b19SZXNlcnZlZFJhbmdlOjpTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdCB7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSBzaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogRGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2U6OmRlc2NyaXB0b3IoKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICByZXR1cm4gRGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2VfZGVzY3JpcHRvcl87Cit9CisKK2NvbnN0IERlc2NyaXB0b3JQcm90b19SZXNlcnZlZFJhbmdlJiBEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZTo6ZGVmYXVsdF9pbnN0YW5jZSgpIHsKKyAgaWYgKGRlZmF1bHRfaW5zdGFuY2VfID09IE5VTEwpIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgcmV0dXJuICpkZWZhdWx0X2luc3RhbmNlXzsKK30KKworRGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2UqIERlc2NyaXB0b3JQcm90b19SZXNlcnZlZFJhbmdlOjpkZWZhdWx0X2luc3RhbmNlXyA9IE5VTEw7CisKK0Rlc2NyaXB0b3JQcm90b19SZXNlcnZlZFJhbmdlKiBEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZTo6TmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdCB7CisgIERlc2NyaXB0b3JQcm90b19SZXNlcnZlZFJhbmdlKiBuID0gbmV3IERlc2NyaXB0b3JQcm90b19SZXNlcnZlZFJhbmdlOworICBpZiAoYXJlbmEgIT0gTlVMTCkgeworICAgIGFyZW5hLT5Pd24obik7CisgIH0KKyAgcmV0dXJuIG47Cit9CisKK3ZvaWQgRGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2U6OkNsZWFyKCkgeworI2RlZmluZSBaUl9IRUxQRVJfKGYpIHJlaW50ZXJwcmV0X2Nhc3Q8Y2hhcio+KFwKKyAgJnJlaW50ZXJwcmV0X2Nhc3Q8RGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2UqPigxNiktPmYpCisKKyNkZWZpbmUgWlJfKGZpcnN0LCBsYXN0KSBkbyB7XAorICA6Om1lbXNldCgmZmlyc3QsIDAsXAorICAgICAgICAgICBaUl9IRUxQRVJfKGxhc3QpIC0gWlJfSEVMUEVSXyhmaXJzdCkgKyBzaXplb2YobGFzdCkpO1wKK30gd2hpbGUgKDApCisKKyAgWlJfKHN0YXJ0XywgZW5kXyk7CisKKyN1bmRlZiBaUl9IRUxQRVJfCisjdW5kZWYgWlJfCisKKyAgOjptZW1zZXQoX2hhc19iaXRzXywgMCwgc2l6ZW9mKF9oYXNfYml0c18pKTsKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5DbGVhcigpOworICB9Cit9CisKK2Jvb2wgRGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2U6Ok1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCkgeworI2RlZmluZSBET18oRVhQUkVTU0lPTikgaWYgKCEoRVhQUkVTU0lPTikpIGdvdG8gZmFpbHVyZQorICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiB0YWc7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdGFydDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLlJlc2VydmVkUmFuZ2UpCisgIGZvciAoOzspIHsKKyAgICA6OnN0ZDo6cGFpcjwgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIsIGJvb2w+IHAgPSBpbnB1dC0+UmVhZFRhZ1dpdGhDdXRvZmYoMTI3KTsKKyAgICB0YWcgPSBwLmZpcnN0OworICAgIGlmICghcC5zZWNvbmQpIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgc3dpdGNoICg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnRmllbGROdW1iZXIodGFnKSkgeworICAgICAgLy8gb3B0aW9uYWwgaW50MzIgc3RhcnQgPSAxOworICAgICAgY2FzZSAxOiB7CisgICAgICAgIGlmICh0YWcgPT0gOCkgeworICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfSU5UMzI+KAorICAgICAgICAgICAgICAgICBpbnB1dCwgJnN0YXJ0XykpKTsKKyAgICAgICAgICBzZXRfaGFzX3N0YXJ0KCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygxNikpIGdvdG8gcGFyc2VfZW5kOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgaW50MzIgZW5kID0gMjsKKyAgICAgIGNhc2UgMjogeworICAgICAgICBpZiAodGFnID09IDE2KSB7CisgICAgICAgICBwYXJzZV9lbmQ6CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyLCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9JTlQzMj4oCisgICAgICAgICAgICAgICAgIGlucHV0LCAmZW5kXykpKTsKKyAgICAgICAgICBzZXRfaGFzX2VuZCgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RBdEVuZCgpKSBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBkZWZhdWx0OiB7CisgICAgICBoYW5kbGVfdW51c3VhbDoKKyAgICAgICAgaWYgKHRhZyA9PSAwIHx8CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnV2lyZVR5cGUodGFnKSA9PQorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0VORF9HUk9VUCkgeworICAgICAgICAgIGdvdG8gc3VjY2VzczsKKyAgICAgICAgfQorICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2tpcEZpZWxkKAorICAgICAgICAgICAgICBpbnB1dCwgdGFnLCBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CitzdWNjZXNzOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3VjY2Vzczpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLlJlc2VydmVkUmFuZ2UpCisgIHJldHVybiB0cnVlOworZmFpbHVyZToKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX2ZhaWx1cmU6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5SZXNlcnZlZFJhbmdlKQorICByZXR1cm4gZmFsc2U7CisjdW5kZWYgRE9fCit9CisKK3ZvaWQgRGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2U6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5SZXNlcnZlZFJhbmdlKQorICAvLyBvcHRpb25hbCBpbnQzMiBzdGFydCA9IDE7CisgIGlmIChoYXNfc3RhcnQoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUludDMyKDEsIHRoaXMtPnN0YXJ0KCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBpbnQzMiBlbmQgPSAyOworICBpZiAoaGFzX2VuZCgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlSW50MzIoMiwgdGhpcy0+ZW5kKCksIG91dHB1dCk7CisgIH0KKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTZXJpYWxpemVVbmtub3duRmllbGRzKAorICAgICAgICB1bmtub3duX2ZpZWxkcygpLCBvdXRwdXQpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfZW5kOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uUmVzZXJ2ZWRSYW5nZSkKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogRGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2U6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogdGFyZ2V0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5SZXNlcnZlZFJhbmdlKQorICAvLyBvcHRpb25hbCBpbnQzMiBzdGFydCA9IDE7CisgIGlmIChoYXNfc3RhcnQoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUludDMyVG9BcnJheSgxLCB0aGlzLT5zdGFydCgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgaW50MzIgZW5kID0gMjsKKyAgaWYgKGhhc19lbmQoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUludDMyVG9BcnJheSgyLCB0aGlzLT5lbmQoKSwgdGFyZ2V0KTsKKyAgfQorCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25GaWVsZHNUb0FycmF5KAorICAgICAgICB1bmtub3duX2ZpZWxkcygpLCB0YXJnZXQpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfZW5kOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uUmVzZXJ2ZWRSYW5nZSkKKyAgcmV0dXJuIHRhcmdldDsKK30KKworaW50IERlc2NyaXB0b3JQcm90b19SZXNlcnZlZFJhbmdlOjpCeXRlU2l6ZSgpIGNvbnN0IHsKKyAgaW50IHRvdGFsX3NpemUgPSAwOworCisgIGlmIChfaGFzX2JpdHNfWzAgLyAzMl0gJiAzdSkgeworICAgIC8vIG9wdGlvbmFsIGludDMyIHN0YXJ0ID0gMTsKKyAgICBpZiAoaGFzX3N0YXJ0KCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpJbnQzMlNpemUoCisgICAgICAgICAgdGhpcy0+c3RhcnQoKSk7CisgICAgfQorCisgICAgLy8gb3B0aW9uYWwgaW50MzIgZW5kID0gMjsKKyAgICBpZiAoaGFzX2VuZCgpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6SW50MzJTaXplKAorICAgICAgICAgIHRoaXMtPmVuZCgpKTsKKyAgICB9CisKKyAgfQorICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICB0b3RhbF9zaXplICs9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpDb21wdXRlVW5rbm93bkZpZWxkc1NpemUoCisgICAgICAgIHVua25vd25fZmllbGRzKCkpOworICB9CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSB0b3RhbF9zaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKKyAgcmV0dXJuIHRvdGFsX3NpemU7Cit9CisKK3ZvaWQgRGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2U6Ok1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgY29uc3QgRGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2UqIHNvdXJjZSA9IAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RHluYW1pY0Nhc3RUb0dlbmVyYXRlZDxjb25zdCBEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZT4oCisgICAgICAgICAgJmZyb20pOworICBpZiAoc291cmNlID09IE5VTEwpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpSZWZsZWN0aW9uT3BzOjpNZXJnZShmcm9tLCB0aGlzKTsKKyAgfSBlbHNlIHsKKyAgICBNZXJnZUZyb20oKnNvdXJjZSk7CisgIH0KK30KKwordm9pZCBEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZTo6TWVyZ2VGcm9tKGNvbnN0IERlc2NyaXB0b3JQcm90b19SZXNlcnZlZFJhbmdlJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGlmIChmcm9tLl9oYXNfYml0c19bMCAvIDMyXSAmICgweGZmdSA8PCAoMCAlIDMyKSkpIHsKKyAgICBpZiAoZnJvbS5oYXNfc3RhcnQoKSkgeworICAgICAgc2V0X3N0YXJ0KGZyb20uc3RhcnQoKSk7CisgICAgfQorICAgIGlmIChmcm9tLmhhc19lbmQoKSkgeworICAgICAgc2V0X2VuZChmcm9tLmVuZCgpKTsKKyAgICB9CisgIH0KKyAgaWYgKGZyb20uX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPk1lcmdlRnJvbShmcm9tLnVua25vd25fZmllbGRzKCkpOworICB9Cit9CisKK3ZvaWQgRGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2U6OkNvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK3ZvaWQgRGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2U6OkNvcHlGcm9tKGNvbnN0IERlc2NyaXB0b3JQcm90b19SZXNlcnZlZFJhbmdlJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKworYm9vbCBEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZTo6SXNJbml0aWFsaXplZCgpIGNvbnN0IHsKKworICByZXR1cm4gdHJ1ZTsKK30KKwordm9pZCBEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZTo6U3dhcChEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZSogb3RoZXIpIHsKKyAgaWYgKG90aGVyID09IHRoaXMpIHJldHVybjsKKyAgSW50ZXJuYWxTd2FwKG90aGVyKTsKK30KK3ZvaWQgRGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2U6OkludGVybmFsU3dhcChEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZSogb3RoZXIpIHsKKyAgc3RkOjpzd2FwKHN0YXJ0Xywgb3RoZXItPnN0YXJ0Xyk7CisgIHN0ZDo6c3dhcChlbmRfLCBvdGhlci0+ZW5kXyk7CisgIHN0ZDo6c3dhcChfaGFzX2JpdHNfWzBdLCBvdGhlci0+X2hhc19iaXRzX1swXSk7CisgIF9pbnRlcm5hbF9tZXRhZGF0YV8uU3dhcCgmb3RoZXItPl9pbnRlcm5hbF9tZXRhZGF0YV8pOworICBzdGQ6OnN3YXAoX2NhY2hlZF9zaXplXywgb3RoZXItPl9jYWNoZWRfc2l6ZV8pOworfQorCis6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIERlc2NyaXB0b3JQcm90b19SZXNlcnZlZFJhbmdlOjpHZXRNZXRhZGF0YSgpIGNvbnN0IHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgbWV0YWRhdGE7CisgIG1ldGFkYXRhLmRlc2NyaXB0b3IgPSBEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZV9kZXNjcmlwdG9yXzsKKyAgbWV0YWRhdGEucmVmbGVjdGlvbiA9IERlc2NyaXB0b3JQcm90b19SZXNlcnZlZFJhbmdlX3JlZmxlY3Rpb25fOworICByZXR1cm4gbWV0YWRhdGE7Cit9CisKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisjaWYgIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKK2NvbnN0IGludCBEZXNjcmlwdG9yUHJvdG86OmtOYW1lRmllbGROdW1iZXI7Citjb25zdCBpbnQgRGVzY3JpcHRvclByb3RvOjprRmllbGRGaWVsZE51bWJlcjsKK2NvbnN0IGludCBEZXNjcmlwdG9yUHJvdG86OmtFeHRlbnNpb25GaWVsZE51bWJlcjsKK2NvbnN0IGludCBEZXNjcmlwdG9yUHJvdG86OmtOZXN0ZWRUeXBlRmllbGROdW1iZXI7Citjb25zdCBpbnQgRGVzY3JpcHRvclByb3RvOjprRW51bVR5cGVGaWVsZE51bWJlcjsKK2NvbnN0IGludCBEZXNjcmlwdG9yUHJvdG86OmtFeHRlbnNpb25SYW5nZUZpZWxkTnVtYmVyOworY29uc3QgaW50IERlc2NyaXB0b3JQcm90bzo6a09uZW9mRGVjbEZpZWxkTnVtYmVyOworY29uc3QgaW50IERlc2NyaXB0b3JQcm90bzo6a09wdGlvbnNGaWVsZE51bWJlcjsKK2NvbnN0IGludCBEZXNjcmlwdG9yUHJvdG86OmtSZXNlcnZlZFJhbmdlRmllbGROdW1iZXI7Citjb25zdCBpbnQgRGVzY3JpcHRvclByb3RvOjprUmVzZXJ2ZWROYW1lRmllbGROdW1iZXI7CisjZW5kaWYgIC8vICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCisKK0Rlc2NyaXB0b3JQcm90bzo6RGVzY3JpcHRvclByb3RvKCkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8pCit9CisKK3ZvaWQgRGVzY3JpcHRvclByb3RvOjpJbml0QXNEZWZhdWx0SW5zdGFuY2UoKSB7CisgIG9wdGlvbnNfID0gY29uc3RfY2FzdDwgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlT3B0aW9ucyo+KCY6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlKCkpOworfQorCitEZXNjcmlwdG9yUHJvdG86OkRlc2NyaXB0b3JQcm90byhjb25zdCBEZXNjcmlwdG9yUHJvdG8mIGZyb20pCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksCisgICAgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29weV9jb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvKQorfQorCit2b2lkIERlc2NyaXB0b3JQcm90bzo6U2hhcmVkQ3RvcigpIHsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmcoKTsKKyAgX2NhY2hlZF9zaXplXyA9IDA7CisgIG5hbWVfLlVuc2FmZVNldERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgb3B0aW9uc18gPSBOVUxMOworICA6Om1lbXNldChfaGFzX2JpdHNfLCAwLCBzaXplb2YoX2hhc19iaXRzXykpOworfQorCitEZXNjcmlwdG9yUHJvdG86On5EZXNjcmlwdG9yUHJvdG8oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChkZXN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8pCisgIFNoYXJlZER0b3IoKTsKK30KKwordm9pZCBEZXNjcmlwdG9yUHJvdG86OlNoYXJlZER0b3IoKSB7CisgIG5hbWVfLkRlc3Ryb3lOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGlmICh0aGlzICE9IGRlZmF1bHRfaW5zdGFuY2VfKSB7CisgICAgZGVsZXRlIG9wdGlvbnNfOworICB9Cit9CisKK3ZvaWQgRGVzY3JpcHRvclByb3RvOjpTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdCB7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSBzaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogRGVzY3JpcHRvclByb3RvOjpkZXNjcmlwdG9yKCkgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgcmV0dXJuIERlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXzsKK30KKworY29uc3QgRGVzY3JpcHRvclByb3RvJiBEZXNjcmlwdG9yUHJvdG86OmRlZmF1bHRfaW5zdGFuY2UoKSB7CisgIGlmIChkZWZhdWx0X2luc3RhbmNlXyA9PSBOVUxMKSBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIHJldHVybiAqZGVmYXVsdF9pbnN0YW5jZV87Cit9CisKK0Rlc2NyaXB0b3JQcm90byogRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlXyA9IE5VTEw7CisKK0Rlc2NyaXB0b3JQcm90byogRGVzY3JpcHRvclByb3RvOjpOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0IHsKKyAgRGVzY3JpcHRvclByb3RvKiBuID0gbmV3IERlc2NyaXB0b3JQcm90bzsKKyAgaWYgKGFyZW5hICE9IE5VTEwpIHsKKyAgICBhcmVuYS0+T3duKG4pOworICB9CisgIHJldHVybiBuOworfQorCit2b2lkIERlc2NyaXB0b3JQcm90bzo6Q2xlYXIoKSB7CisgIGlmIChfaGFzX2JpdHNfWzAgLyAzMl0gJiAxMjl1KSB7CisgICAgaWYgKGhhc19uYW1lKCkpIHsKKyAgICAgIG5hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgICB9CisgICAgaWYgKGhhc19vcHRpb25zKCkpIHsKKyAgICAgIGlmIChvcHRpb25zXyAhPSBOVUxMKSBvcHRpb25zXy0+Ojpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlT3B0aW9uczo6Q2xlYXIoKTsKKyAgICB9CisgIH0KKyAgZmllbGRfLkNsZWFyKCk7CisgIGV4dGVuc2lvbl8uQ2xlYXIoKTsKKyAgbmVzdGVkX3R5cGVfLkNsZWFyKCk7CisgIGVudW1fdHlwZV8uQ2xlYXIoKTsKKyAgZXh0ZW5zaW9uX3JhbmdlXy5DbGVhcigpOworICBvbmVvZl9kZWNsXy5DbGVhcigpOworICByZXNlcnZlZF9yYW5nZV8uQ2xlYXIoKTsKKyAgcmVzZXJ2ZWRfbmFtZV8uQ2xlYXIoKTsKKyAgOjptZW1zZXQoX2hhc19iaXRzXywgMCwgc2l6ZW9mKF9oYXNfYml0c18pKTsKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5DbGVhcigpOworICB9Cit9CisKK2Jvb2wgRGVzY3JpcHRvclByb3RvOjpNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyNkZWZpbmUgRE9fKEVYUFJFU1NJT04pIGlmICghKEVYUFJFU1NJT04pKSBnb3RvIGZhaWx1cmUKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgdGFnOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90bykKKyAgZm9yICg7OykgeworICAgIDo6c3RkOjpwYWlyPCA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiwgYm9vbD4gcCA9IGlucHV0LT5SZWFkVGFnV2l0aEN1dG9mZigxMjcpOworICAgIHRhZyA9IHAuZmlyc3Q7CisgICAgaWYgKCFwLnNlY29uZCkgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICBzd2l0Y2ggKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdGaWVsZE51bWJlcih0YWcpKSB7CisgICAgICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgICAgICBjYXNlIDE6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAxMCkgeworICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFN0cmluZygKKyAgICAgICAgICAgICAgICBpbnB1dCwgdGhpcy0+bXV0YWJsZV9uYW1lKCkpKTsKKyAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgICAgICAgIHRoaXMtPm5hbWUoKS5kYXRhKCksIHRoaXMtPm5hbWUoKS5sZW5ndGgoKSwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlBBUlNFLAorICAgICAgICAgICAgImdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ubmFtZSIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMTgpKSBnb3RvIHBhcnNlX2ZpZWxkOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90byBmaWVsZCA9IDI7CisgICAgICBjYXNlIDI6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAxOCkgeworICAgICAgICAgcGFyc2VfZmllbGQ6CisgICAgICAgICAgRE9fKGlucHV0LT5JbmNyZW1lbnRSZWN1cnNpb25EZXB0aCgpKTsKKyAgICAgICAgIHBhcnNlX2xvb3BfZmllbGQ6CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkTWVzc2FnZU5vVmlydHVhbE5vUmVjdXJzaW9uRGVwdGgoCisgICAgICAgICAgICAgICAgaW5wdXQsIGFkZF9maWVsZCgpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygxOCkpIGdvdG8gcGFyc2VfbG9vcF9maWVsZDsKKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMjYpKSBnb3RvIHBhcnNlX2xvb3BfbmVzdGVkX3R5cGU7CisgICAgICAgIGlucHV0LT5VbnNhZmVEZWNyZW1lbnRSZWN1cnNpb25EZXB0aCgpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8gbmVzdGVkX3R5cGUgPSAzOworICAgICAgY2FzZSAzOiB7CisgICAgICAgIGlmICh0YWcgPT0gMjYpIHsKKyAgICAgICAgICBET18oaW5wdXQtPkluY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCkpOworICAgICAgICAgcGFyc2VfbG9vcF9uZXN0ZWRfdHlwZToKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRNZXNzYWdlTm9WaXJ0dWFsTm9SZWN1cnNpb25EZXB0aCgKKyAgICAgICAgICAgICAgICBpbnB1dCwgYWRkX25lc3RlZF90eXBlKCkpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDI2KSkgZ290byBwYXJzZV9sb29wX25lc3RlZF90eXBlOworICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygzNCkpIGdvdG8gcGFyc2VfbG9vcF9lbnVtX3R5cGU7CisgICAgICAgIGlucHV0LT5VbnNhZmVEZWNyZW1lbnRSZWN1cnNpb25EZXB0aCgpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvIGVudW1fdHlwZSA9IDQ7CisgICAgICBjYXNlIDQ6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAzNCkgeworICAgICAgICAgIERPXyhpbnB1dC0+SW5jcmVtZW50UmVjdXJzaW9uRGVwdGgoKSk7CisgICAgICAgICBwYXJzZV9sb29wX2VudW1fdHlwZToKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRNZXNzYWdlTm9WaXJ0dWFsTm9SZWN1cnNpb25EZXB0aCgKKyAgICAgICAgICAgICAgICBpbnB1dCwgYWRkX2VudW1fdHlwZSgpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygzNCkpIGdvdG8gcGFyc2VfbG9vcF9lbnVtX3R5cGU7CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDQyKSkgZ290byBwYXJzZV9sb29wX2V4dGVuc2lvbl9yYW5nZTsKKyAgICAgICAgaW5wdXQtPlVuc2FmZURlY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5FeHRlbnNpb25SYW5nZSBleHRlbnNpb25fcmFuZ2UgPSA1OworICAgICAgY2FzZSA1OiB7CisgICAgICAgIGlmICh0YWcgPT0gNDIpIHsKKyAgICAgICAgICBET18oaW5wdXQtPkluY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCkpOworICAgICAgICAgcGFyc2VfbG9vcF9leHRlbnNpb25fcmFuZ2U6CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkTWVzc2FnZU5vVmlydHVhbE5vUmVjdXJzaW9uRGVwdGgoCisgICAgICAgICAgICAgICAgaW5wdXQsIGFkZF9leHRlbnNpb25fcmFuZ2UoKSkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNDIpKSBnb3RvIHBhcnNlX2xvb3BfZXh0ZW5zaW9uX3JhbmdlOworICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg1MCkpIGdvdG8gcGFyc2VfbG9vcF9leHRlbnNpb247CisgICAgICAgIGlucHV0LT5VbnNhZmVEZWNyZW1lbnRSZWN1cnNpb25EZXB0aCgpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90byBleHRlbnNpb24gPSA2OworICAgICAgY2FzZSA2OiB7CisgICAgICAgIGlmICh0YWcgPT0gNTApIHsKKyAgICAgICAgICBET18oaW5wdXQtPkluY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCkpOworICAgICAgICAgcGFyc2VfbG9vcF9leHRlbnNpb246CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkTWVzc2FnZU5vVmlydHVhbE5vUmVjdXJzaW9uRGVwdGgoCisgICAgICAgICAgICAgICAgaW5wdXQsIGFkZF9leHRlbnNpb24oKSkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNTApKSBnb3RvIHBhcnNlX2xvb3BfZXh0ZW5zaW9uOworICAgICAgICBpbnB1dC0+VW5zYWZlRGVjcmVtZW50UmVjdXJzaW9uRGVwdGgoKTsKKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNTgpKSBnb3RvIHBhcnNlX29wdGlvbnM7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zIG9wdGlvbnMgPSA3OworICAgICAgY2FzZSA3OiB7CisgICAgICAgIGlmICh0YWcgPT0gNTgpIHsKKyAgICAgICAgIHBhcnNlX29wdGlvbnM6CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkTWVzc2FnZU5vVmlydHVhbCgKKyAgICAgICAgICAgICAgIGlucHV0LCBtdXRhYmxlX29wdGlvbnMoKSkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNjYpKSBnb3RvIHBhcnNlX29uZW9mX2RlY2w7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLk9uZW9mRGVzY3JpcHRvclByb3RvIG9uZW9mX2RlY2wgPSA4OworICAgICAgY2FzZSA4OiB7CisgICAgICAgIGlmICh0YWcgPT0gNjYpIHsKKyAgICAgICAgIHBhcnNlX29uZW9mX2RlY2w6CisgICAgICAgICAgRE9fKGlucHV0LT5JbmNyZW1lbnRSZWN1cnNpb25EZXB0aCgpKTsKKyAgICAgICAgIHBhcnNlX2xvb3Bfb25lb2ZfZGVjbDoKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRNZXNzYWdlTm9WaXJ0dWFsTm9SZWN1cnNpb25EZXB0aCgKKyAgICAgICAgICAgICAgICBpbnB1dCwgYWRkX29uZW9mX2RlY2woKSkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNjYpKSBnb3RvIHBhcnNlX2xvb3Bfb25lb2ZfZGVjbDsKKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNzQpKSBnb3RvIHBhcnNlX2xvb3BfcmVzZXJ2ZWRfcmFuZ2U7CisgICAgICAgIGlucHV0LT5VbnNhZmVEZWNyZW1lbnRSZWN1cnNpb25EZXB0aCgpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uUmVzZXJ2ZWRSYW5nZSByZXNlcnZlZF9yYW5nZSA9IDk7CisgICAgICBjYXNlIDk6IHsKKyAgICAgICAgaWYgKHRhZyA9PSA3NCkgeworICAgICAgICAgIERPXyhpbnB1dC0+SW5jcmVtZW50UmVjdXJzaW9uRGVwdGgoKSk7CisgICAgICAgICBwYXJzZV9sb29wX3Jlc2VydmVkX3JhbmdlOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZE1lc3NhZ2VOb1ZpcnR1YWxOb1JlY3Vyc2lvbkRlcHRoKAorICAgICAgICAgICAgICAgIGlucHV0LCBhZGRfcmVzZXJ2ZWRfcmFuZ2UoKSkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNzQpKSBnb3RvIHBhcnNlX2xvb3BfcmVzZXJ2ZWRfcmFuZ2U7CisgICAgICAgIGlucHV0LT5VbnNhZmVEZWNyZW1lbnRSZWN1cnNpb25EZXB0aCgpOworICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg4MikpIGdvdG8gcGFyc2VfcmVzZXJ2ZWRfbmFtZTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIHJlcGVhdGVkIHN0cmluZyByZXNlcnZlZF9uYW1lID0gMTA7CisgICAgICBjYXNlIDEwOiB7CisgICAgICAgIGlmICh0YWcgPT0gODIpIHsKKyAgICAgICAgIHBhcnNlX3Jlc2VydmVkX25hbWU6CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkU3RyaW5nKAorICAgICAgICAgICAgICAgIGlucHV0LCB0aGlzLT5hZGRfcmVzZXJ2ZWRfbmFtZSgpKSk7CisgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICAgICAgICB0aGlzLT5yZXNlcnZlZF9uYW1lKHRoaXMtPnJlc2VydmVkX25hbWVfc2l6ZSgpIC0gMSkuZGF0YSgpLAorICAgICAgICAgICAgdGhpcy0+cmVzZXJ2ZWRfbmFtZSh0aGlzLT5yZXNlcnZlZF9uYW1lX3NpemUoKSAtIDEpLmxlbmd0aCgpLAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6UEFSU0UsCisgICAgICAgICAgICAiZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5yZXNlcnZlZF9uYW1lIik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg4MikpIGdvdG8gcGFyc2VfcmVzZXJ2ZWRfbmFtZTsKKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RBdEVuZCgpKSBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBkZWZhdWx0OiB7CisgICAgICBoYW5kbGVfdW51c3VhbDoKKyAgICAgICAgaWYgKHRhZyA9PSAwIHx8CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnV2lyZVR5cGUodGFnKSA9PQorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0VORF9HUk9VUCkgeworICAgICAgICAgIGdvdG8gc3VjY2VzczsKKyAgICAgICAgfQorICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2tpcEZpZWxkKAorICAgICAgICAgICAgICBpbnB1dCwgdGFnLCBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CitzdWNjZXNzOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3VjY2Vzczpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvKQorICByZXR1cm4gdHJ1ZTsKK2ZhaWx1cmU6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9mYWlsdXJlOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8pCisgIHJldHVybiBmYWxzZTsKKyN1bmRlZiBET18KK30KKwordm9pZCBEZXNjcmlwdG9yUHJvdG86OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90bykKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICBpZiAoaGFzX25hbWUoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+bmFtZSgpLmRhdGEoKSwgdGhpcy0+bmFtZSgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ubmFtZSIpOworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ01heWJlQWxpYXNlZCgKKyAgICAgIDEsIHRoaXMtPm5hbWUoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8gZmllbGQgPSAyOworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPmZpZWxkX3NpemUoKTsgaSA8IG47IGkrKykgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZU1lc3NhZ2VNYXliZVRvQXJyYXkoCisgICAgICAyLCB0aGlzLT5maWVsZChpKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvIG5lc3RlZF90eXBlID0gMzsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT5uZXN0ZWRfdHlwZV9zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgMywgdGhpcy0+bmVzdGVkX3R5cGUoaSksIG91dHB1dCk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8gZW51bV90eXBlID0gNDsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT5lbnVtX3R5cGVfc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlTWVzc2FnZU1heWJlVG9BcnJheSgKKyAgICAgIDQsIHRoaXMtPmVudW1fdHlwZShpKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLkV4dGVuc2lvblJhbmdlIGV4dGVuc2lvbl9yYW5nZSA9IDU7CisgIGZvciAodW5zaWduZWQgaW50IGkgPSAwLCBuID0gdGhpcy0+ZXh0ZW5zaW9uX3JhbmdlX3NpemUoKTsgaSA8IG47IGkrKykgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZU1lc3NhZ2VNYXliZVRvQXJyYXkoCisgICAgICA1LCB0aGlzLT5leHRlbnNpb25fcmFuZ2UoaSksIG91dHB1dCk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvIGV4dGVuc2lvbiA9IDY7CisgIGZvciAodW5zaWduZWQgaW50IGkgPSAwLCBuID0gdGhpcy0+ZXh0ZW5zaW9uX3NpemUoKTsgaSA8IG47IGkrKykgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZU1lc3NhZ2VNYXliZVRvQXJyYXkoCisgICAgICA2LCB0aGlzLT5leHRlbnNpb24oaSksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zIG9wdGlvbnMgPSA3OworICBpZiAoaGFzX29wdGlvbnMoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZU1lc3NhZ2VNYXliZVRvQXJyYXkoCisgICAgICA3LCAqdGhpcy0+b3B0aW9uc18sIG91dHB1dCk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLk9uZW9mRGVzY3JpcHRvclByb3RvIG9uZW9mX2RlY2wgPSA4OworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPm9uZW9mX2RlY2xfc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlTWVzc2FnZU1heWJlVG9BcnJheSgKKyAgICAgIDgsIHRoaXMtPm9uZW9mX2RlY2woaSksIG91dHB1dCk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5SZXNlcnZlZFJhbmdlIHJlc2VydmVkX3JhbmdlID0gOTsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT5yZXNlcnZlZF9yYW5nZV9zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgOSwgdGhpcy0+cmVzZXJ2ZWRfcmFuZ2UoaSksIG91dHB1dCk7CisgIH0KKworICAvLyByZXBlYXRlZCBzdHJpbmcgcmVzZXJ2ZWRfbmFtZSA9IDEwOworICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPnJlc2VydmVkX25hbWVfc2l6ZSgpOyBpKyspIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgIHRoaXMtPnJlc2VydmVkX25hbWUoaSkuZGF0YSgpLCB0aGlzLT5yZXNlcnZlZF9uYW1lKGkpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ucmVzZXJ2ZWRfbmFtZSIpOworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZygKKyAgICAgIDEwLCB0aGlzLT5yZXNlcnZlZF9uYW1lKGkpLCBvdXRwdXQpOworICB9CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bkZpZWxkcygKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSwgb3V0cHV0KTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX2VuZDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvKQorfQorCis6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBEZXNjcmlwdG9yUHJvdG86OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogdGFyZ2V0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90bykKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICBpZiAoaGFzX25hbWUoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+bmFtZSgpLmRhdGEoKSwgdGhpcy0+bmFtZSgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ubmFtZSIpOworICAgIHRhcmdldCA9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdUb0FycmF5KAorICAgICAgICAxLCB0aGlzLT5uYW1lKCksIHRhcmdldCk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvIGZpZWxkID0gMjsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT5maWVsZF9zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6CisgICAgICBXcml0ZU1lc3NhZ2VOb1ZpcnR1YWxUb0FycmF5KAorICAgICAgICAyLCB0aGlzLT5maWVsZChpKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvIG5lc3RlZF90eXBlID0gMzsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT5uZXN0ZWRfdHlwZV9zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6CisgICAgICBXcml0ZU1lc3NhZ2VOb1ZpcnR1YWxUb0FycmF5KAorICAgICAgICAzLCB0aGlzLT5uZXN0ZWRfdHlwZShpKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRW51bURlc2NyaXB0b3JQcm90byBlbnVtX3R5cGUgPSA0OworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPmVudW1fdHlwZV9zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6CisgICAgICBXcml0ZU1lc3NhZ2VOb1ZpcnR1YWxUb0FycmF5KAorICAgICAgICA0LCB0aGlzLT5lbnVtX3R5cGUoaSksIHRhcmdldCk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5FeHRlbnNpb25SYW5nZSBleHRlbnNpb25fcmFuZ2UgPSA1OworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPmV4dGVuc2lvbl9yYW5nZV9zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6CisgICAgICBXcml0ZU1lc3NhZ2VOb1ZpcnR1YWxUb0FycmF5KAorICAgICAgICA1LCB0aGlzLT5leHRlbnNpb25fcmFuZ2UoaSksIHRhcmdldCk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvIGV4dGVuc2lvbiA9IDY7CisgIGZvciAodW5zaWduZWQgaW50IGkgPSAwLCBuID0gdGhpcy0+ZXh0ZW5zaW9uX3NpemUoKTsgaSA8IG47IGkrKykgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjoKKyAgICAgIFdyaXRlTWVzc2FnZU5vVmlydHVhbFRvQXJyYXkoCisgICAgICAgIDYsIHRoaXMtPmV4dGVuc2lvbihpKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMgb3B0aW9ucyA9IDc7CisgIGlmIChoYXNfb3B0aW9ucygpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OgorICAgICAgV3JpdGVNZXNzYWdlTm9WaXJ0dWFsVG9BcnJheSgKKyAgICAgICAgNywgKnRoaXMtPm9wdGlvbnNfLCB0YXJnZXQpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5PbmVvZkRlc2NyaXB0b3JQcm90byBvbmVvZl9kZWNsID0gODsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT5vbmVvZl9kZWNsX3NpemUoKTsgaSA8IG47IGkrKykgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjoKKyAgICAgIFdyaXRlTWVzc2FnZU5vVmlydHVhbFRvQXJyYXkoCisgICAgICAgIDgsIHRoaXMtPm9uZW9mX2RlY2woaSksIHRhcmdldCk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5SZXNlcnZlZFJhbmdlIHJlc2VydmVkX3JhbmdlID0gOTsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT5yZXNlcnZlZF9yYW5nZV9zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6CisgICAgICBXcml0ZU1lc3NhZ2VOb1ZpcnR1YWxUb0FycmF5KAorICAgICAgICA5LCB0aGlzLT5yZXNlcnZlZF9yYW5nZShpKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIHN0cmluZyByZXNlcnZlZF9uYW1lID0gMTA7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+cmVzZXJ2ZWRfbmFtZV9zaXplKCk7IGkrKykgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+cmVzZXJ2ZWRfbmFtZShpKS5kYXRhKCksIHRoaXMtPnJlc2VydmVkX25hbWUoaSkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5yZXNlcnZlZF9uYW1lIik7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OgorICAgICAgV3JpdGVTdHJpbmdUb0FycmF5KDEwLCB0aGlzLT5yZXNlcnZlZF9uYW1lKGkpLCB0YXJnZXQpOworICB9CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bkZpZWxkc1RvQXJyYXkoCisgICAgICAgIHVua25vd25fZmllbGRzKCksIHRhcmdldCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9lbmQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90bykKKyAgcmV0dXJuIHRhcmdldDsKK30KKworaW50IERlc2NyaXB0b3JQcm90bzo6Qnl0ZVNpemUoKSBjb25zdCB7CisgIGludCB0b3RhbF9zaXplID0gMDsKKworICBpZiAoX2hhc19iaXRzX1swIC8gMzJdICYgMTI5dSkgeworICAgIC8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKKyAgICBpZiAoaGFzX25hbWUoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlN0cmluZ1NpemUoCisgICAgICAgICAgdGhpcy0+bmFtZSgpKTsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zIG9wdGlvbnMgPSA3OworICAgIGlmIChoYXNfb3B0aW9ucygpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6TWVzc2FnZVNpemVOb1ZpcnR1YWwoCisgICAgICAgICAgKnRoaXMtPm9wdGlvbnNfKTsKKyAgICB9CisKKyAgfQorICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvIGZpZWxkID0gMjsKKyAgdG90YWxfc2l6ZSArPSAxICogdGhpcy0+ZmllbGRfc2l6ZSgpOworICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPmZpZWxkX3NpemUoKTsgaSsrKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1lc3NhZ2VTaXplTm9WaXJ0dWFsKAorICAgICAgICB0aGlzLT5maWVsZChpKSk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvIGV4dGVuc2lvbiA9IDY7CisgIHRvdGFsX3NpemUgKz0gMSAqIHRoaXMtPmV4dGVuc2lvbl9zaXplKCk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+ZXh0ZW5zaW9uX3NpemUoKTsgaSsrKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1lc3NhZ2VTaXplTm9WaXJ0dWFsKAorICAgICAgICB0aGlzLT5leHRlbnNpb24oaSkpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8gbmVzdGVkX3R5cGUgPSAzOworICB0b3RhbF9zaXplICs9IDEgKiB0aGlzLT5uZXN0ZWRfdHlwZV9zaXplKCk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+bmVzdGVkX3R5cGVfc2l6ZSgpOyBpKyspIHsKKyAgICB0b3RhbF9zaXplICs9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6TWVzc2FnZVNpemVOb1ZpcnR1YWwoCisgICAgICAgIHRoaXMtPm5lc3RlZF90eXBlKGkpKTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRW51bURlc2NyaXB0b3JQcm90byBlbnVtX3R5cGUgPSA0OworICB0b3RhbF9zaXplICs9IDEgKiB0aGlzLT5lbnVtX3R5cGVfc2l6ZSgpOworICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPmVudW1fdHlwZV9zaXplKCk7IGkrKykgeworICAgIHRvdGFsX3NpemUgKz0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpNZXNzYWdlU2l6ZU5vVmlydHVhbCgKKyAgICAgICAgdGhpcy0+ZW51bV90eXBlKGkpKTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLkV4dGVuc2lvblJhbmdlIGV4dGVuc2lvbl9yYW5nZSA9IDU7CisgIHRvdGFsX3NpemUgKz0gMSAqIHRoaXMtPmV4dGVuc2lvbl9yYW5nZV9zaXplKCk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+ZXh0ZW5zaW9uX3JhbmdlX3NpemUoKTsgaSsrKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1lc3NhZ2VTaXplTm9WaXJ0dWFsKAorICAgICAgICB0aGlzLT5leHRlbnNpb25fcmFuZ2UoaSkpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5PbmVvZkRlc2NyaXB0b3JQcm90byBvbmVvZl9kZWNsID0gODsKKyAgdG90YWxfc2l6ZSArPSAxICogdGhpcy0+b25lb2ZfZGVjbF9zaXplKCk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+b25lb2ZfZGVjbF9zaXplKCk7IGkrKykgeworICAgIHRvdGFsX3NpemUgKz0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpNZXNzYWdlU2l6ZU5vVmlydHVhbCgKKyAgICAgICAgdGhpcy0+b25lb2ZfZGVjbChpKSk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5SZXNlcnZlZFJhbmdlIHJlc2VydmVkX3JhbmdlID0gOTsKKyAgdG90YWxfc2l6ZSArPSAxICogdGhpcy0+cmVzZXJ2ZWRfcmFuZ2Vfc2l6ZSgpOworICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPnJlc2VydmVkX3JhbmdlX3NpemUoKTsgaSsrKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1lc3NhZ2VTaXplTm9WaXJ0dWFsKAorICAgICAgICB0aGlzLT5yZXNlcnZlZF9yYW5nZShpKSk7CisgIH0KKworICAvLyByZXBlYXRlZCBzdHJpbmcgcmVzZXJ2ZWRfbmFtZSA9IDEwOworICB0b3RhbF9zaXplICs9IDEgKiB0aGlzLT5yZXNlcnZlZF9uYW1lX3NpemUoKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT5yZXNlcnZlZF9uYW1lX3NpemUoKTsgaSsrKSB7CisgICAgdG90YWxfc2l6ZSArPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U3RyaW5nU2l6ZSgKKyAgICAgIHRoaXMtPnJlc2VydmVkX25hbWUoaSkpOworICB9CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6Q29tcHV0ZVVua25vd25GaWVsZHNTaXplKAorICAgICAgICB1bmtub3duX2ZpZWxkcygpKTsKKyAgfQorICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gdG90YWxfc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7CisgIHJldHVybiB0b3RhbF9zaXplOworfQorCit2b2lkIERlc2NyaXB0b3JQcm90bzo6TWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBjb25zdCBEZXNjcmlwdG9yUHJvdG8qIHNvdXJjZSA9IAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RHluYW1pY0Nhc3RUb0dlbmVyYXRlZDxjb25zdCBEZXNjcmlwdG9yUHJvdG8+KAorICAgICAgICAgICZmcm9tKTsKKyAgaWYgKHNvdXJjZSA9PSBOVUxMKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6UmVmbGVjdGlvbk9wczo6TWVyZ2UoZnJvbSwgdGhpcyk7CisgIH0gZWxzZSB7CisgICAgTWVyZ2VGcm9tKCpzb3VyY2UpOworICB9Cit9CisKK3ZvaWQgRGVzY3JpcHRvclByb3RvOjpNZXJnZUZyb20oY29uc3QgRGVzY3JpcHRvclByb3RvJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGZpZWxkXy5NZXJnZUZyb20oZnJvbS5maWVsZF8pOworICBleHRlbnNpb25fLk1lcmdlRnJvbShmcm9tLmV4dGVuc2lvbl8pOworICBuZXN0ZWRfdHlwZV8uTWVyZ2VGcm9tKGZyb20ubmVzdGVkX3R5cGVfKTsKKyAgZW51bV90eXBlXy5NZXJnZUZyb20oZnJvbS5lbnVtX3R5cGVfKTsKKyAgZXh0ZW5zaW9uX3JhbmdlXy5NZXJnZUZyb20oZnJvbS5leHRlbnNpb25fcmFuZ2VfKTsKKyAgb25lb2ZfZGVjbF8uTWVyZ2VGcm9tKGZyb20ub25lb2ZfZGVjbF8pOworICByZXNlcnZlZF9yYW5nZV8uTWVyZ2VGcm9tKGZyb20ucmVzZXJ2ZWRfcmFuZ2VfKTsKKyAgcmVzZXJ2ZWRfbmFtZV8uTWVyZ2VGcm9tKGZyb20ucmVzZXJ2ZWRfbmFtZV8pOworICBpZiAoZnJvbS5faGFzX2JpdHNfWzAgLyAzMl0gJiAoMHhmZnUgPDwgKDAgJSAzMikpKSB7CisgICAgaWYgKGZyb20uaGFzX25hbWUoKSkgeworICAgICAgc2V0X2hhc19uYW1lKCk7CisgICAgICBuYW1lXy5Bc3NpZ25XaXRoRGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGZyb20ubmFtZV8pOworICAgIH0KKyAgICBpZiAoZnJvbS5oYXNfb3B0aW9ucygpKSB7CisgICAgICBtdXRhYmxlX29wdGlvbnMoKS0+Ojpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlT3B0aW9uczo6TWVyZ2VGcm9tKGZyb20ub3B0aW9ucygpKTsKKyAgICB9CisgIH0KKyAgaWYgKGZyb20uX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPk1lcmdlRnJvbShmcm9tLnVua25vd25fZmllbGRzKCkpOworICB9Cit9CisKK3ZvaWQgRGVzY3JpcHRvclByb3RvOjpDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCit2b2lkIERlc2NyaXB0b3JQcm90bzo6Q29weUZyb20oY29uc3QgRGVzY3JpcHRvclByb3RvJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKworYm9vbCBEZXNjcmlwdG9yUHJvdG86OklzSW5pdGlhbGl6ZWQoKSBjb25zdCB7CisKKyAgaWYgKCE6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBbGxBcmVJbml0aWFsaXplZCh0aGlzLT5maWVsZCgpKSkgcmV0dXJuIGZhbHNlOworICBpZiAoITo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFsbEFyZUluaXRpYWxpemVkKHRoaXMtPmV4dGVuc2lvbigpKSkgcmV0dXJuIGZhbHNlOworICBpZiAoITo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFsbEFyZUluaXRpYWxpemVkKHRoaXMtPm5lc3RlZF90eXBlKCkpKSByZXR1cm4gZmFsc2U7CisgIGlmICghOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QWxsQXJlSW5pdGlhbGl6ZWQodGhpcy0+ZW51bV90eXBlKCkpKSByZXR1cm4gZmFsc2U7CisgIGlmIChoYXNfb3B0aW9ucygpKSB7CisgICAgaWYgKCF0aGlzLT5vcHRpb25zXy0+SXNJbml0aWFsaXplZCgpKSByZXR1cm4gZmFsc2U7CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgRGVzY3JpcHRvclByb3RvOjpTd2FwKERlc2NyaXB0b3JQcm90byogb3RoZXIpIHsKKyAgaWYgKG90aGVyID09IHRoaXMpIHJldHVybjsKKyAgSW50ZXJuYWxTd2FwKG90aGVyKTsKK30KK3ZvaWQgRGVzY3JpcHRvclByb3RvOjpJbnRlcm5hbFN3YXAoRGVzY3JpcHRvclByb3RvKiBvdGhlcikgeworICBuYW1lXy5Td2FwKCZvdGhlci0+bmFtZV8pOworICBmaWVsZF8uVW5zYWZlQXJlbmFTd2FwKCZvdGhlci0+ZmllbGRfKTsKKyAgZXh0ZW5zaW9uXy5VbnNhZmVBcmVuYVN3YXAoJm90aGVyLT5leHRlbnNpb25fKTsKKyAgbmVzdGVkX3R5cGVfLlVuc2FmZUFyZW5hU3dhcCgmb3RoZXItPm5lc3RlZF90eXBlXyk7CisgIGVudW1fdHlwZV8uVW5zYWZlQXJlbmFTd2FwKCZvdGhlci0+ZW51bV90eXBlXyk7CisgIGV4dGVuc2lvbl9yYW5nZV8uVW5zYWZlQXJlbmFTd2FwKCZvdGhlci0+ZXh0ZW5zaW9uX3JhbmdlXyk7CisgIG9uZW9mX2RlY2xfLlVuc2FmZUFyZW5hU3dhcCgmb3RoZXItPm9uZW9mX2RlY2xfKTsKKyAgc3RkOjpzd2FwKG9wdGlvbnNfLCBvdGhlci0+b3B0aW9uc18pOworICByZXNlcnZlZF9yYW5nZV8uVW5zYWZlQXJlbmFTd2FwKCZvdGhlci0+cmVzZXJ2ZWRfcmFuZ2VfKTsKKyAgcmVzZXJ2ZWRfbmFtZV8uVW5zYWZlQXJlbmFTd2FwKCZvdGhlci0+cmVzZXJ2ZWRfbmFtZV8pOworICBzdGQ6OnN3YXAoX2hhc19iaXRzX1swXSwgb3RoZXItPl9oYXNfYml0c19bMF0pOworICBfaW50ZXJuYWxfbWV0YWRhdGFfLlN3YXAoJm90aGVyLT5faW50ZXJuYWxfbWV0YWRhdGFfKTsKKyAgc3RkOjpzd2FwKF9jYWNoZWRfc2l6ZV8sIG90aGVyLT5fY2FjaGVkX3NpemVfKTsKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBEZXNjcmlwdG9yUHJvdG86OkdldE1ldGFkYXRhKCkgY29uc3QgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBtZXRhZGF0YTsKKyAgbWV0YWRhdGEuZGVzY3JpcHRvciA9IERlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXzsKKyAgbWV0YWRhdGEucmVmbGVjdGlvbiA9IERlc2NyaXB0b3JQcm90b19yZWZsZWN0aW9uXzsKKyAgcmV0dXJuIG1ldGFkYXRhOworfQorCisjaWYgUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisvLyBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UKKworLy8gb3B0aW9uYWwgaW50MzIgc3RhcnQgPSAxOworYm9vbCBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6Omhhc19zdGFydCgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMXUpICE9IDA7Cit9Cit2b2lkIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZTo6c2V0X2hhc19zdGFydCgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAxdTsKK30KK3ZvaWQgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOjpjbGVhcl9oYXNfc3RhcnQoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDF1OworfQordm9pZCBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6OmNsZWFyX3N0YXJ0KCkgeworICBzdGFydF8gPSAwOworICBjbGVhcl9oYXNfc3RhcnQoKTsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZTo6c3RhcnQoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5FeHRlbnNpb25SYW5nZS5zdGFydCkKKyAgcmV0dXJuIHN0YXJ0XzsKK30KKyB2b2lkIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZTo6c2V0X3N0YXJ0KDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgdmFsdWUpIHsKKyAgc2V0X2hhc19zdGFydCgpOworICBzdGFydF8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLkV4dGVuc2lvblJhbmdlLnN0YXJ0KQorfQorCisvLyBvcHRpb25hbCBpbnQzMiBlbmQgPSAyOworYm9vbCBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6Omhhc19lbmQoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDJ1KSAhPSAwOworfQordm9pZCBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6OnNldF9oYXNfZW5kKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDJ1OworfQordm9pZCBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6OmNsZWFyX2hhc19lbmQoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDJ1OworfQordm9pZCBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6OmNsZWFyX2VuZCgpIHsKKyAgZW5kXyA9IDA7CisgIGNsZWFyX2hhc19lbmQoKTsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZTo6ZW5kKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uRXh0ZW5zaW9uUmFuZ2UuZW5kKQorICByZXR1cm4gZW5kXzsKK30KKyB2b2lkIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZTo6c2V0X2VuZCg6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKSB7CisgIHNldF9oYXNfZW5kKCk7CisgIGVuZF8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLkV4dGVuc2lvblJhbmdlLmVuZCkKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZQorCisvLyBvcHRpb25hbCBpbnQzMiBzdGFydCA9IDE7Citib29sIERlc2NyaXB0b3JQcm90b19SZXNlcnZlZFJhbmdlOjpoYXNfc3RhcnQoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDF1KSAhPSAwOworfQordm9pZCBEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZTo6c2V0X2hhc19zdGFydCgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAxdTsKK30KK3ZvaWQgRGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2U6OmNsZWFyX2hhc19zdGFydCgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMXU7Cit9Cit2b2lkIERlc2NyaXB0b3JQcm90b19SZXNlcnZlZFJhbmdlOjpjbGVhcl9zdGFydCgpIHsKKyAgc3RhcnRfID0gMDsKKyAgY2xlYXJfaGFzX3N0YXJ0KCk7Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiBEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZTo6c3RhcnQoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5SZXNlcnZlZFJhbmdlLnN0YXJ0KQorICByZXR1cm4gc3RhcnRfOworfQorIHZvaWQgRGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2U6OnNldF9zdGFydCg6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKSB7CisgIHNldF9oYXNfc3RhcnQoKTsKKyAgc3RhcnRfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5SZXNlcnZlZFJhbmdlLnN0YXJ0KQorfQorCisvLyBvcHRpb25hbCBpbnQzMiBlbmQgPSAyOworYm9vbCBEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZTo6aGFzX2VuZCgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMnUpICE9IDA7Cit9Cit2b2lkIERlc2NyaXB0b3JQcm90b19SZXNlcnZlZFJhbmdlOjpzZXRfaGFzX2VuZCgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAydTsKK30KK3ZvaWQgRGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2U6OmNsZWFyX2hhc19lbmQoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDJ1OworfQordm9pZCBEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZTo6Y2xlYXJfZW5kKCkgeworICBlbmRfID0gMDsKKyAgY2xlYXJfaGFzX2VuZCgpOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgRGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2U6OmVuZCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLlJlc2VydmVkUmFuZ2UuZW5kKQorICByZXR1cm4gZW5kXzsKK30KKyB2b2lkIERlc2NyaXB0b3JQcm90b19SZXNlcnZlZFJhbmdlOjpzZXRfZW5kKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgdmFsdWUpIHsKKyAgc2V0X2hhc19lbmQoKTsKKyAgZW5kXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uUmVzZXJ2ZWRSYW5nZS5lbmQpCit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gRGVzY3JpcHRvclByb3RvCisKKy8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKK2Jvb2wgRGVzY3JpcHRvclByb3RvOjpoYXNfbmFtZSgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMXUpICE9IDA7Cit9Cit2b2lkIERlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19uYW1lKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDF1OworfQordm9pZCBEZXNjcmlwdG9yUHJvdG86OmNsZWFyX2hhc19uYW1lKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAxdTsKK30KK3ZvaWQgRGVzY3JpcHRvclByb3RvOjpjbGVhcl9uYW1lKCkgeworICBuYW1lXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGNsZWFyX2hhc19uYW1lKCk7Cit9CisgY29uc3QgOjpzdGQ6OnN0cmluZyYgRGVzY3JpcHRvclByb3RvOjpuYW1lKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ubmFtZSkKKyAgcmV0dXJuIG5hbWVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIERlc2NyaXB0b3JQcm90bzo6c2V0X25hbWUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5uYW1lKQorfQorIHZvaWQgRGVzY3JpcHRvclByb3RvOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KKyB2b2lkIERlc2NyaXB0b3JQcm90bzo6c2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHNldF9oYXNfbmFtZSgpOworICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLm5hbWUpCit9CisgOjpzdGQ6OnN0cmluZyogRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX25hbWUoKSB7CisgIHNldF9oYXNfbmFtZSgpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLm5hbWUpCisgIHJldHVybiBuYW1lXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIDo6c3RkOjpzdHJpbmcqIERlc2NyaXB0b3JQcm90bzo6cmVsZWFzZV9uYW1lKCkgeworICBjbGVhcl9oYXNfbmFtZSgpOworICByZXR1cm4gbmFtZV8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIERlc2NyaXB0b3JQcm90bzo6c2V0X2FsbG9jYXRlZF9uYW1lKDo6c3RkOjpzdHJpbmcqIG5hbWUpIHsKKyAgaWYgKG5hbWUgIT0gTlVMTCkgeworICAgIHNldF9oYXNfbmFtZSgpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19uYW1lKCk7CisgIH0KKyAgbmFtZV8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIG5hbWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLm5hbWUpCit9CisKKy8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8gZmllbGQgPSAyOworaW50IERlc2NyaXB0b3JQcm90bzo6ZmllbGRfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIGZpZWxkXy5zaXplKCk7Cit9Cit2b2lkIERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfZmllbGQoKSB7CisgIGZpZWxkXy5DbGVhcigpOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90byYgRGVzY3JpcHRvclByb3RvOjpmaWVsZChpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLmZpZWxkKQorICByZXR1cm4gZmllbGRfLkdldChpbmRleCk7Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvKiBEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfZmllbGQoaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uZmllbGQpCisgIHJldHVybiBmaWVsZF8uTXV0YWJsZShpbmRleCk7Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvKiBEZXNjcmlwdG9yUHJvdG86OmFkZF9maWVsZCgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLmZpZWxkKQorICByZXR1cm4gZmllbGRfLkFkZCgpOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvID4qCitEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfZmllbGQoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5maWVsZCkKKyAgcmV0dXJuICZmaWVsZF87Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG8gPiYKK0Rlc2NyaXB0b3JQcm90bzo6ZmllbGQoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uZmllbGQpCisgIHJldHVybiBmaWVsZF87Cit9CisKKy8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8gZXh0ZW5zaW9uID0gNjsKK2ludCBEZXNjcmlwdG9yUHJvdG86OmV4dGVuc2lvbl9zaXplKCkgY29uc3QgeworICByZXR1cm4gZXh0ZW5zaW9uXy5zaXplKCk7Cit9Cit2b2lkIERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfZXh0ZW5zaW9uKCkgeworICBleHRlbnNpb25fLkNsZWFyKCk7Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvJiBEZXNjcmlwdG9yUHJvdG86OmV4dGVuc2lvbihpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLmV4dGVuc2lvbikKKyAgcmV0dXJuIGV4dGVuc2lvbl8uR2V0KGluZGV4KTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG8qIERlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9leHRlbnNpb24oaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uZXh0ZW5zaW9uKQorICByZXR1cm4gZXh0ZW5zaW9uXy5NdXRhYmxlKGluZGV4KTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG8qIERlc2NyaXB0b3JQcm90bzo6YWRkX2V4dGVuc2lvbigpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLmV4dGVuc2lvbikKKyAgcmV0dXJuIGV4dGVuc2lvbl8uQWRkKCk7Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG8gPioKK0Rlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9leHRlbnNpb24oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5leHRlbnNpb24pCisgIHJldHVybiAmZXh0ZW5zaW9uXzsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90byA+JgorRGVzY3JpcHRvclByb3RvOjpleHRlbnNpb24oKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uZXh0ZW5zaW9uKQorICByZXR1cm4gZXh0ZW5zaW9uXzsKK30KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8gbmVzdGVkX3R5cGUgPSAzOworaW50IERlc2NyaXB0b3JQcm90bzo6bmVzdGVkX3R5cGVfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIG5lc3RlZF90eXBlXy5zaXplKCk7Cit9Cit2b2lkIERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfbmVzdGVkX3R5cGUoKSB7CisgIG5lc3RlZF90eXBlXy5DbGVhcigpOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG8mIERlc2NyaXB0b3JQcm90bzo6bmVzdGVkX3R5cGUoaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5uZXN0ZWRfdHlwZSkKKyAgcmV0dXJuIG5lc3RlZF90eXBlXy5HZXQoaW5kZXgpOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG8qIERlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9uZXN0ZWRfdHlwZShpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5uZXN0ZWRfdHlwZSkKKyAgcmV0dXJuIG5lc3RlZF90eXBlXy5NdXRhYmxlKGluZGV4KTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclByb3RvKiBEZXNjcmlwdG9yUHJvdG86OmFkZF9uZXN0ZWRfdHlwZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLm5lc3RlZF90eXBlKQorICByZXR1cm4gbmVzdGVkX3R5cGVfLkFkZCgpOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQcm90byA+KgorRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX25lc3RlZF90eXBlKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ubmVzdGVkX3R5cGUpCisgIHJldHVybiAmbmVzdGVkX3R5cGVfOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQcm90byA+JgorRGVzY3JpcHRvclByb3RvOjpuZXN0ZWRfdHlwZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5uZXN0ZWRfdHlwZSkKKyAgcmV0dXJuIG5lc3RlZF90eXBlXzsKK30KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvIGVudW1fdHlwZSA9IDQ7CitpbnQgRGVzY3JpcHRvclByb3RvOjplbnVtX3R5cGVfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIGVudW1fdHlwZV8uc2l6ZSgpOworfQordm9pZCBEZXNjcmlwdG9yUHJvdG86OmNsZWFyX2VudW1fdHlwZSgpIHsKKyAgZW51bV90eXBlXy5DbGVhcigpOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvclByb3RvJiBEZXNjcmlwdG9yUHJvdG86OmVudW1fdHlwZShpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLmVudW1fdHlwZSkKKyAgcmV0dXJuIGVudW1fdHlwZV8uR2V0KGluZGV4KTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bURlc2NyaXB0b3JQcm90byogRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX2VudW1fdHlwZShpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5lbnVtX3R5cGUpCisgIHJldHVybiBlbnVtX3R5cGVfLk11dGFibGUoaW5kZXgpOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvclByb3RvKiBEZXNjcmlwdG9yUHJvdG86OmFkZF9lbnVtX3R5cGUoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5lbnVtX3R5cGUpCisgIHJldHVybiBlbnVtX3R5cGVfLkFkZCgpOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yUHJvdG8gPioKK0Rlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9lbnVtX3R5cGUoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5lbnVtX3R5cGUpCisgIHJldHVybiAmZW51bV90eXBlXzsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvclByb3RvID4mCitEZXNjcmlwdG9yUHJvdG86OmVudW1fdHlwZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5lbnVtX3R5cGUpCisgIHJldHVybiBlbnVtX3R5cGVfOworfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5FeHRlbnNpb25SYW5nZSBleHRlbnNpb25fcmFuZ2UgPSA1OworaW50IERlc2NyaXB0b3JQcm90bzo6ZXh0ZW5zaW9uX3JhbmdlX3NpemUoKSBjb25zdCB7CisgIHJldHVybiBleHRlbnNpb25fcmFuZ2VfLnNpemUoKTsKK30KK3ZvaWQgRGVzY3JpcHRvclByb3RvOjpjbGVhcl9leHRlbnNpb25fcmFuZ2UoKSB7CisgIGV4dGVuc2lvbl9yYW5nZV8uQ2xlYXIoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlJiBEZXNjcmlwdG9yUHJvdG86OmV4dGVuc2lvbl9yYW5nZShpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLmV4dGVuc2lvbl9yYW5nZSkKKyAgcmV0dXJuIGV4dGVuc2lvbl9yYW5nZV8uR2V0KGluZGV4KTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlKiBEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfZXh0ZW5zaW9uX3JhbmdlKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLmV4dGVuc2lvbl9yYW5nZSkKKyAgcmV0dXJuIGV4dGVuc2lvbl9yYW5nZV8uTXV0YWJsZShpbmRleCk7Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZSogRGVzY3JpcHRvclByb3RvOjphZGRfZXh0ZW5zaW9uX3JhbmdlKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uZXh0ZW5zaW9uX3JhbmdlKQorICByZXR1cm4gZXh0ZW5zaW9uX3JhbmdlXy5BZGQoKTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UgPioKK0Rlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9leHRlbnNpb25fcmFuZ2UoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5leHRlbnNpb25fcmFuZ2UpCisgIHJldHVybiAmZXh0ZW5zaW9uX3JhbmdlXzsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UgPiYKK0Rlc2NyaXB0b3JQcm90bzo6ZXh0ZW5zaW9uX3JhbmdlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLmV4dGVuc2lvbl9yYW5nZSkKKyAgcmV0dXJuIGV4dGVuc2lvbl9yYW5nZV87Cit9CisKKy8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuT25lb2ZEZXNjcmlwdG9yUHJvdG8gb25lb2ZfZGVjbCA9IDg7CitpbnQgRGVzY3JpcHRvclByb3RvOjpvbmVvZl9kZWNsX3NpemUoKSBjb25zdCB7CisgIHJldHVybiBvbmVvZl9kZWNsXy5zaXplKCk7Cit9Cit2b2lkIERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfb25lb2ZfZGVjbCgpIHsKKyAgb25lb2ZfZGVjbF8uQ2xlYXIoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6T25lb2ZEZXNjcmlwdG9yUHJvdG8mIERlc2NyaXB0b3JQcm90bzo6b25lb2ZfZGVjbChpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLm9uZW9mX2RlY2wpCisgIHJldHVybiBvbmVvZl9kZWNsXy5HZXQoaW5kZXgpOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpPbmVvZkRlc2NyaXB0b3JQcm90byogRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX29uZW9mX2RlY2woaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ub25lb2ZfZGVjbCkKKyAgcmV0dXJuIG9uZW9mX2RlY2xfLk11dGFibGUoaW5kZXgpOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpPbmVvZkRlc2NyaXB0b3JQcm90byogRGVzY3JpcHRvclByb3RvOjphZGRfb25lb2ZfZGVjbCgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLm9uZW9mX2RlY2wpCisgIHJldHVybiBvbmVvZl9kZWNsXy5BZGQoKTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpPbmVvZkRlc2NyaXB0b3JQcm90byA+KgorRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX29uZW9mX2RlY2woKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5vbmVvZl9kZWNsKQorICByZXR1cm4gJm9uZW9mX2RlY2xfOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok9uZW9mRGVzY3JpcHRvclByb3RvID4mCitEZXNjcmlwdG9yUHJvdG86Om9uZW9mX2RlY2woKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ub25lb2ZfZGVjbCkKKyAgcmV0dXJuIG9uZW9mX2RlY2xfOworfQorCisvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zIG9wdGlvbnMgPSA3OworYm9vbCBEZXNjcmlwdG9yUHJvdG86Omhhc19vcHRpb25zKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDgwdSkgIT0gMDsKK30KK3ZvaWQgRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX29wdGlvbnMoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDA4MHU7Cit9Cit2b2lkIERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX29wdGlvbnMoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwODB1OworfQordm9pZCBEZXNjcmlwdG9yUHJvdG86OmNsZWFyX29wdGlvbnMoKSB7CisgIGlmIChvcHRpb25zXyAhPSBOVUxMKSBvcHRpb25zXy0+Ojpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlT3B0aW9uczo6Q2xlYXIoKTsKKyAgY2xlYXJfaGFzX29wdGlvbnMoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZU9wdGlvbnMmIERlc2NyaXB0b3JQcm90bzo6b3B0aW9ucygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLm9wdGlvbnMpCisgIHJldHVybiBvcHRpb25zXyAhPSBOVUxMID8gKm9wdGlvbnNfIDogKmRlZmF1bHRfaW5zdGFuY2VfLT5vcHRpb25zXzsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZU9wdGlvbnMqIERlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9vcHRpb25zKCkgeworICBzZXRfaGFzX29wdGlvbnMoKTsKKyAgaWYgKG9wdGlvbnNfID09IE5VTEwpIHsKKyAgICBvcHRpb25zXyA9IG5ldyA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VPcHRpb25zOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ub3B0aW9ucykKKyAgcmV0dXJuIG9wdGlvbnNfOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlT3B0aW9ucyogRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX29wdGlvbnMoKSB7CisgIGNsZWFyX2hhc19vcHRpb25zKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZU9wdGlvbnMqIHRlbXAgPSBvcHRpb25zXzsKKyAgb3B0aW9uc18gPSBOVUxMOworICByZXR1cm4gdGVtcDsKK30KK3ZvaWQgRGVzY3JpcHRvclByb3RvOjpzZXRfYWxsb2NhdGVkX29wdGlvbnMoOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlT3B0aW9ucyogb3B0aW9ucykgeworICBkZWxldGUgb3B0aW9uc187CisgIG9wdGlvbnNfID0gb3B0aW9uczsKKyAgaWYgKG9wdGlvbnMpIHsKKyAgICBzZXRfaGFzX29wdGlvbnMoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfb3B0aW9ucygpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ub3B0aW9ucykKK30KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uUmVzZXJ2ZWRSYW5nZSByZXNlcnZlZF9yYW5nZSA9IDk7CitpbnQgRGVzY3JpcHRvclByb3RvOjpyZXNlcnZlZF9yYW5nZV9zaXplKCkgY29uc3QgeworICByZXR1cm4gcmVzZXJ2ZWRfcmFuZ2VfLnNpemUoKTsKK30KK3ZvaWQgRGVzY3JpcHRvclByb3RvOjpjbGVhcl9yZXNlcnZlZF9yYW5nZSgpIHsKKyAgcmVzZXJ2ZWRfcmFuZ2VfLkNsZWFyKCk7Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQcm90b19SZXNlcnZlZFJhbmdlJiBEZXNjcmlwdG9yUHJvdG86OnJlc2VydmVkX3JhbmdlKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ucmVzZXJ2ZWRfcmFuZ2UpCisgIHJldHVybiByZXNlcnZlZF9yYW5nZV8uR2V0KGluZGV4KTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2UqIERlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9yZXNlcnZlZF9yYW5nZShpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5yZXNlcnZlZF9yYW5nZSkKKyAgcmV0dXJuIHJlc2VydmVkX3JhbmdlXy5NdXRhYmxlKGluZGV4KTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2UqIERlc2NyaXB0b3JQcm90bzo6YWRkX3Jlc2VydmVkX3JhbmdlKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ucmVzZXJ2ZWRfcmFuZ2UpCisgIHJldHVybiByZXNlcnZlZF9yYW5nZV8uQWRkKCk7Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2UgPioKK0Rlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9yZXNlcnZlZF9yYW5nZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLnJlc2VydmVkX3JhbmdlKQorICByZXR1cm4gJnJlc2VydmVkX3JhbmdlXzsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZSA+JgorRGVzY3JpcHRvclByb3RvOjpyZXNlcnZlZF9yYW5nZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5yZXNlcnZlZF9yYW5nZSkKKyAgcmV0dXJuIHJlc2VydmVkX3JhbmdlXzsKK30KKworLy8gcmVwZWF0ZWQgc3RyaW5nIHJlc2VydmVkX25hbWUgPSAxMDsKK2ludCBEZXNjcmlwdG9yUHJvdG86OnJlc2VydmVkX25hbWVfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIHJlc2VydmVkX25hbWVfLnNpemUoKTsKK30KK3ZvaWQgRGVzY3JpcHRvclByb3RvOjpjbGVhcl9yZXNlcnZlZF9uYW1lKCkgeworICByZXNlcnZlZF9uYW1lXy5DbGVhcigpOworfQorIGNvbnN0IDo6c3RkOjpzdHJpbmcmIERlc2NyaXB0b3JQcm90bzo6cmVzZXJ2ZWRfbmFtZShpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLnJlc2VydmVkX25hbWUpCisgIHJldHVybiByZXNlcnZlZF9uYW1lXy5HZXQoaW5kZXgpOworfQorIDo6c3RkOjpzdHJpbmcqIERlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9yZXNlcnZlZF9uYW1lKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLnJlc2VydmVkX25hbWUpCisgIHJldHVybiByZXNlcnZlZF9uYW1lXy5NdXRhYmxlKGluZGV4KTsKK30KKyB2b2lkIERlc2NyaXB0b3JQcm90bzo6c2V0X3Jlc2VydmVkX25hbWUoaW50IGluZGV4LCBjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ucmVzZXJ2ZWRfbmFtZSkKKyAgcmVzZXJ2ZWRfbmFtZV8uTXV0YWJsZShpbmRleCktPmFzc2lnbih2YWx1ZSk7Cit9Cisgdm9pZCBEZXNjcmlwdG9yUHJvdG86OnNldF9yZXNlcnZlZF9uYW1lKGludCBpbmRleCwgY29uc3QgY2hhciogdmFsdWUpIHsKKyAgcmVzZXJ2ZWRfbmFtZV8uTXV0YWJsZShpbmRleCktPmFzc2lnbih2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLnJlc2VydmVkX25hbWUpCit9Cisgdm9pZCBEZXNjcmlwdG9yUHJvdG86OnNldF9yZXNlcnZlZF9uYW1lKGludCBpbmRleCwgY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHJlc2VydmVkX25hbWVfLk11dGFibGUoaW5kZXgpLT5hc3NpZ24oCisgICAgcmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ucmVzZXJ2ZWRfbmFtZSkKK30KKyA6OnN0ZDo6c3RyaW5nKiBEZXNjcmlwdG9yUHJvdG86OmFkZF9yZXNlcnZlZF9uYW1lKCkgeworICByZXR1cm4gcmVzZXJ2ZWRfbmFtZV8uQWRkKCk7Cit9Cisgdm9pZCBEZXNjcmlwdG9yUHJvdG86OmFkZF9yZXNlcnZlZF9uYW1lKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHJlc2VydmVkX25hbWVfLkFkZCgpLT5hc3NpZ24odmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ucmVzZXJ2ZWRfbmFtZSkKK30KKyB2b2lkIERlc2NyaXB0b3JQcm90bzo6YWRkX3Jlc2VydmVkX25hbWUoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgcmVzZXJ2ZWRfbmFtZV8uQWRkKCktPmFzc2lnbih2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGRfY2hhcjpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLnJlc2VydmVkX25hbWUpCit9Cisgdm9pZCBEZXNjcmlwdG9yUHJvdG86OmFkZF9yZXNlcnZlZF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICByZXNlcnZlZF9uYW1lXy5BZGQoKS0+YXNzaWduKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLnJlc2VydmVkX25hbWUpCit9CisgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6OnN0ZDo6c3RyaW5nPiYKK0Rlc2NyaXB0b3JQcm90bzo6cmVzZXJ2ZWRfbmFtZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5yZXNlcnZlZF9uYW1lKQorICByZXR1cm4gcmVzZXJ2ZWRfbmFtZV87Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6OnN0ZDo6c3RyaW5nPioKK0Rlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9yZXNlcnZlZF9uYW1lKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ucmVzZXJ2ZWRfbmFtZSkKKyAgcmV0dXJuICZyZXNlcnZlZF9uYW1lXzsKK30KKworI2VuZGlmICAvLyBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yKiBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX2Rlc2NyaXB0b3IoKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICByZXR1cm4gRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9kZXNjcmlwdG9yXzsKK30KK2Jvb2wgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9Jc1ZhbGlkKGludCB2YWx1ZSkgeworICBzd2l0Y2godmFsdWUpIHsKKyAgICBjYXNlIDE6CisgICAgY2FzZSAyOgorICAgIGNhc2UgMzoKKyAgICBjYXNlIDQ6CisgICAgY2FzZSA1OgorICAgIGNhc2UgNjoKKyAgICBjYXNlIDc6CisgICAgY2FzZSA4OgorICAgIGNhc2UgOToKKyAgICBjYXNlIDEwOgorICAgIGNhc2UgMTE6CisgICAgY2FzZSAxMjoKKyAgICBjYXNlIDEzOgorICAgIGNhc2UgMTQ6CisgICAgY2FzZSAxNToKKyAgICBjYXNlIDE2OgorICAgIGNhc2UgMTc6CisgICAgY2FzZSAxODoKKyAgICAgIHJldHVybiB0cnVlOworICAgIGRlZmF1bHQ6CisgICAgICByZXR1cm4gZmFsc2U7CisgIH0KK30KKworI2lmICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCitjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0RPVUJMRTsKK2NvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGUgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfRkxPQVQ7Citjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0lOVDY0OworY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9VSU5UNjQ7Citjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0lOVDMyOworY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9GSVhFRDY0OworY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9GSVhFRDMyOworY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9CT09MOworY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9TVFJJTkc7Citjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0dST1VQOworY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9NRVNTQUdFOworY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9CWVRFUzsKK2NvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGUgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfVUlOVDMyOworY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9FTlVNOworY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9TRklYRUQzMjsKK2NvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGUgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfU0ZJWEVENjQ7Citjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX1NJTlQzMjsKK2NvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGUgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfU0lOVDY0OworY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZSBGaWVsZERlc2NyaXB0b3JQcm90bzo6VHlwZV9NSU47Citjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUeXBlX01BWDsKK2NvbnN0IGludCBGaWVsZERlc2NyaXB0b3JQcm90bzo6VHlwZV9BUlJBWVNJWkU7CisjZW5kaWYgIC8vICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCitjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yKiBGaWVsZERlc2NyaXB0b3JQcm90b19MYWJlbF9kZXNjcmlwdG9yKCkgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgcmV0dXJuIEZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsX2Rlc2NyaXB0b3JfOworfQorYm9vbCBGaWVsZERlc2NyaXB0b3JQcm90b19MYWJlbF9Jc1ZhbGlkKGludCB2YWx1ZSkgeworICBzd2l0Y2godmFsdWUpIHsKKyAgICBjYXNlIDE6CisgICAgY2FzZSAyOgorICAgIGNhc2UgMzoKKyAgICAgIHJldHVybiB0cnVlOworICAgIGRlZmF1bHQ6CisgICAgICByZXR1cm4gZmFsc2U7CisgIH0KK30KKworI2lmICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCitjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90b19MYWJlbCBGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfT1BUSU9OQUw7Citjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90b19MYWJlbCBGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfUkVRVUlSRUQ7Citjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90b19MYWJlbCBGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfUkVQRUFURUQ7Citjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90b19MYWJlbCBGaWVsZERlc2NyaXB0b3JQcm90bzo6TGFiZWxfTUlOOworY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWwgRmllbGREZXNjcmlwdG9yUHJvdG86OkxhYmVsX01BWDsKK2NvbnN0IGludCBGaWVsZERlc2NyaXB0b3JQcm90bzo6TGFiZWxfQVJSQVlTSVpFOworI2VuZGlmICAvLyAhZGVmaW5lZChfTVNDX1ZFUikgfHwgX01TQ19WRVIgPj0gMTkwMAorI2lmICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCitjb25zdCBpbnQgRmllbGREZXNjcmlwdG9yUHJvdG86OmtOYW1lRmllbGROdW1iZXI7Citjb25zdCBpbnQgRmllbGREZXNjcmlwdG9yUHJvdG86OmtOdW1iZXJGaWVsZE51bWJlcjsKK2NvbnN0IGludCBGaWVsZERlc2NyaXB0b3JQcm90bzo6a0xhYmVsRmllbGROdW1iZXI7Citjb25zdCBpbnQgRmllbGREZXNjcmlwdG9yUHJvdG86OmtUeXBlRmllbGROdW1iZXI7Citjb25zdCBpbnQgRmllbGREZXNjcmlwdG9yUHJvdG86OmtUeXBlTmFtZUZpZWxkTnVtYmVyOworY29uc3QgaW50IEZpZWxkRGVzY3JpcHRvclByb3RvOjprRXh0ZW5kZWVGaWVsZE51bWJlcjsKK2NvbnN0IGludCBGaWVsZERlc2NyaXB0b3JQcm90bzo6a0RlZmF1bHRWYWx1ZUZpZWxkTnVtYmVyOworY29uc3QgaW50IEZpZWxkRGVzY3JpcHRvclByb3RvOjprT25lb2ZJbmRleEZpZWxkTnVtYmVyOworY29uc3QgaW50IEZpZWxkRGVzY3JpcHRvclByb3RvOjprSnNvbk5hbWVGaWVsZE51bWJlcjsKK2NvbnN0IGludCBGaWVsZERlc2NyaXB0b3JQcm90bzo6a09wdGlvbnNGaWVsZE51bWJlcjsKKyNlbmRpZiAgLy8gIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKKworRmllbGREZXNjcmlwdG9yUHJvdG86OkZpZWxkRGVzY3JpcHRvclByb3RvKCkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90bykKK30KKwordm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6SW5pdEFzRGVmYXVsdEluc3RhbmNlKCkgeworICBvcHRpb25zXyA9IGNvbnN0X2Nhc3Q8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGRPcHRpb25zKj4oJjo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGRPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlKCkpOworfQorCitGaWVsZERlc2NyaXB0b3JQcm90bzo6RmllbGREZXNjcmlwdG9yUHJvdG8oY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG8mIGZyb20pCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksCisgICAgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29weV9jb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8pCit9CisKK3ZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OlNoYXJlZEN0b3IoKSB7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSAwOworICBuYW1lXy5VbnNhZmVTZXREZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIG51bWJlcl8gPSAwOworICBsYWJlbF8gPSAxOworICB0eXBlXyA9IDE7CisgIHR5cGVfbmFtZV8uVW5zYWZlU2V0RGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBleHRlbmRlZV8uVW5zYWZlU2V0RGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBkZWZhdWx0X3ZhbHVlXy5VbnNhZmVTZXREZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIG9uZW9mX2luZGV4XyA9IDA7CisgIGpzb25fbmFtZV8uVW5zYWZlU2V0RGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBvcHRpb25zXyA9IE5VTEw7CisgIDo6bWVtc2V0KF9oYXNfYml0c18sIDAsIHNpemVvZihfaGFzX2JpdHNfKSk7Cit9CisKK0ZpZWxkRGVzY3JpcHRvclByb3RvOjp+RmllbGREZXNjcmlwdG9yUHJvdG8oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChkZXN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90bykKKyAgU2hhcmVkRHRvcigpOworfQorCit2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpTaGFyZWREdG9yKCkgeworICBuYW1lXy5EZXN0cm95Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICB0eXBlX25hbWVfLkRlc3Ryb3lOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGV4dGVuZGVlXy5EZXN0cm95Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBkZWZhdWx0X3ZhbHVlXy5EZXN0cm95Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBqc29uX25hbWVfLkRlc3Ryb3lOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGlmICh0aGlzICE9IGRlZmF1bHRfaW5zdGFuY2VfKSB7CisgICAgZGVsZXRlIG9wdGlvbnNfOworICB9Cit9CisKK3ZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OlNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0IHsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHNpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBGaWVsZERlc2NyaXB0b3JQcm90bzo6ZGVzY3JpcHRvcigpIHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIHJldHVybiBGaWVsZERlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXzsKK30KKworY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG8mIEZpZWxkRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlKCkgeworICBpZiAoZGVmYXVsdF9pbnN0YW5jZV8gPT0gTlVMTCkgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICByZXR1cm4gKmRlZmF1bHRfaW5zdGFuY2VfOworfQorCitGaWVsZERlc2NyaXB0b3JQcm90byogRmllbGREZXNjcmlwdG9yUHJvdG86OmRlZmF1bHRfaW5zdGFuY2VfID0gTlVMTDsKKworRmllbGREZXNjcmlwdG9yUHJvdG8qIEZpZWxkRGVzY3JpcHRvclByb3RvOjpOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0IHsKKyAgRmllbGREZXNjcmlwdG9yUHJvdG8qIG4gPSBuZXcgRmllbGREZXNjcmlwdG9yUHJvdG87CisgIGlmIChhcmVuYSAhPSBOVUxMKSB7CisgICAgYXJlbmEtPk93bihuKTsKKyAgfQorICByZXR1cm4gbjsKK30KKwordm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6Q2xlYXIoKSB7CisgIGlmIChfaGFzX2JpdHNfWzAgLyAzMl0gJiAyNTV1KSB7CisgICAgaWYgKGhhc19uYW1lKCkpIHsKKyAgICAgIG5hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgICB9CisgICAgbnVtYmVyXyA9IDA7CisgICAgbGFiZWxfID0gMTsKKyAgICB0eXBlXyA9IDE7CisgICAgaWYgKGhhc190eXBlX25hbWUoKSkgeworICAgICAgdHlwZV9uYW1lXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgICAgfQorICAgIGlmIChoYXNfZXh0ZW5kZWUoKSkgeworICAgICAgZXh0ZW5kZWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgICB9CisgICAgaWYgKGhhc19kZWZhdWx0X3ZhbHVlKCkpIHsKKyAgICAgIGRlZmF1bHRfdmFsdWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgICB9CisgICAgb25lb2ZfaW5kZXhfID0gMDsKKyAgfQorICBpZiAoX2hhc19iaXRzX1s4IC8gMzJdICYgNzY4dSkgeworICAgIGlmIChoYXNfanNvbl9uYW1lKCkpIHsKKyAgICAgIGpzb25fbmFtZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICAgIH0KKyAgICBpZiAoaGFzX29wdGlvbnMoKSkgeworICAgICAgaWYgKG9wdGlvbnNfICE9IE5VTEwpIG9wdGlvbnNfLT46Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkT3B0aW9uczo6Q2xlYXIoKTsKKyAgICB9CisgIH0KKyAgOjptZW1zZXQoX2hhc19iaXRzXywgMCwgc2l6ZW9mKF9oYXNfYml0c18pKTsKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5DbGVhcigpOworICB9Cit9CisKK2Jvb2wgRmllbGREZXNjcmlwdG9yUHJvdG86Ok1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCkgeworI2RlZmluZSBET18oRVhQUkVTU0lPTikgaWYgKCEoRVhQUkVTU0lPTikpIGdvdG8gZmFpbHVyZQorICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiB0YWc7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdGFydDpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8pCisgIGZvciAoOzspIHsKKyAgICA6OnN0ZDo6cGFpcjwgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIsIGJvb2w+IHAgPSBpbnB1dC0+UmVhZFRhZ1dpdGhDdXRvZmYoMTI3KTsKKyAgICB0YWcgPSBwLmZpcnN0OworICAgIGlmICghcC5zZWNvbmQpIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgc3dpdGNoICg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnRmllbGROdW1iZXIodGFnKSkgeworICAgICAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICAgICAgY2FzZSAxOiB7CisgICAgICAgIGlmICh0YWcgPT0gMTApIHsKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoCisgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPm11dGFibGVfbmFtZSgpKSk7CisgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICAgICAgICB0aGlzLT5uYW1lKCkuZGF0YSgpLCB0aGlzLT5uYW1lKCkubGVuZ3RoKCksCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpQQVJTRSwKKyAgICAgICAgICAgICJnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8ubmFtZSIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMTgpKSBnb3RvIHBhcnNlX2V4dGVuZGVlOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgc3RyaW5nIGV4dGVuZGVlID0gMjsKKyAgICAgIGNhc2UgMjogeworICAgICAgICBpZiAodGFnID09IDE4KSB7CisgICAgICAgICBwYXJzZV9leHRlbmRlZToKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoCisgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPm11dGFibGVfZXh0ZW5kZWUoKSkpOworICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgICAgICAgdGhpcy0+ZXh0ZW5kZWUoKS5kYXRhKCksIHRoaXMtPmV4dGVuZGVlKCkubGVuZ3RoKCksCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpQQVJTRSwKKyAgICAgICAgICAgICJnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uZXh0ZW5kZWUiKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDI0KSkgZ290byBwYXJzZV9udW1iZXI7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCBpbnQzMiBudW1iZXIgPSAzOworICAgICAgY2FzZSAzOiB7CisgICAgICAgIGlmICh0YWcgPT0gMjQpIHsKKyAgICAgICAgIHBhcnNlX251bWJlcjoKKyAgICAgICAgICBET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPAorICAgICAgICAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0lOVDMyPigKKyAgICAgICAgICAgICAgICAgaW5wdXQsICZudW1iZXJfKSkpOworICAgICAgICAgIHNldF9oYXNfbnVtYmVyKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygzMikpIGdvdG8gcGFyc2VfbGFiZWw7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLkxhYmVsIGxhYmVsID0gNDsKKyAgICAgIGNhc2UgNDogeworICAgICAgICBpZiAodGFnID09IDMyKSB7CisgICAgICAgICBwYXJzZV9sYWJlbDoKKyAgICAgICAgICBpbnQgdmFsdWU7CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICBpbnQsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0VOVU0+KAorICAgICAgICAgICAgICAgICBpbnB1dCwgJnZhbHVlKSkpOworICAgICAgICAgIGlmICg6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsX0lzVmFsaWQodmFsdWUpKSB7CisgICAgICAgICAgICBzZXRfbGFiZWwoc3RhdGljX2Nhc3Q8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWwgPih2YWx1ZSkpOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkFkZFZhcmludCg0LCB2YWx1ZSk7CisgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNDApKSBnb3RvIHBhcnNlX3R5cGU7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLlR5cGUgdHlwZSA9IDU7CisgICAgICBjYXNlIDU6IHsKKyAgICAgICAgaWYgKHRhZyA9PSA0MCkgeworICAgICAgICAgcGFyc2VfdHlwZToKKyAgICAgICAgICBpbnQgdmFsdWU7CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICBpbnQsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0VOVU0+KAorICAgICAgICAgICAgICAgICBpbnB1dCwgJnZhbHVlKSkpOworICAgICAgICAgIGlmICg6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfSXNWYWxpZCh2YWx1ZSkpIHsKKyAgICAgICAgICAgIHNldF90eXBlKHN0YXRpY19jYXN0PCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGUgPih2YWx1ZSkpOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkFkZFZhcmludCg1LCB2YWx1ZSk7CisgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNTApKSBnb3RvIHBhcnNlX3R5cGVfbmFtZTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIHN0cmluZyB0eXBlX25hbWUgPSA2OworICAgICAgY2FzZSA2OiB7CisgICAgICAgIGlmICh0YWcgPT0gNTApIHsKKyAgICAgICAgIHBhcnNlX3R5cGVfbmFtZToKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoCisgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPm11dGFibGVfdHlwZV9uYW1lKCkpKTsKKyAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgICAgICAgIHRoaXMtPnR5cGVfbmFtZSgpLmRhdGEoKSwgdGhpcy0+dHlwZV9uYW1lKCkubGVuZ3RoKCksCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpQQVJTRSwKKyAgICAgICAgICAgICJnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8udHlwZV9uYW1lIik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg1OCkpIGdvdG8gcGFyc2VfZGVmYXVsdF92YWx1ZTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIHN0cmluZyBkZWZhdWx0X3ZhbHVlID0gNzsKKyAgICAgIGNhc2UgNzogeworICAgICAgICBpZiAodGFnID09IDU4KSB7CisgICAgICAgICBwYXJzZV9kZWZhdWx0X3ZhbHVlOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFN0cmluZygKKyAgICAgICAgICAgICAgICBpbnB1dCwgdGhpcy0+bXV0YWJsZV9kZWZhdWx0X3ZhbHVlKCkpKTsKKyAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgICAgICAgIHRoaXMtPmRlZmF1bHRfdmFsdWUoKS5kYXRhKCksIHRoaXMtPmRlZmF1bHRfdmFsdWUoKS5sZW5ndGgoKSwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlBBUlNFLAorICAgICAgICAgICAgImdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5kZWZhdWx0X3ZhbHVlIik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg2NikpIGdvdG8gcGFyc2Vfb3B0aW9uczsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zIG9wdGlvbnMgPSA4OworICAgICAgY2FzZSA4OiB7CisgICAgICAgIGlmICh0YWcgPT0gNjYpIHsKKyAgICAgICAgIHBhcnNlX29wdGlvbnM6CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkTWVzc2FnZU5vVmlydHVhbCgKKyAgICAgICAgICAgICAgIGlucHV0LCBtdXRhYmxlX29wdGlvbnMoKSkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNzIpKSBnb3RvIHBhcnNlX29uZW9mX2luZGV4OworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgaW50MzIgb25lb2ZfaW5kZXggPSA5OworICAgICAgY2FzZSA5OiB7CisgICAgICAgIGlmICh0YWcgPT0gNzIpIHsKKyAgICAgICAgIHBhcnNlX29uZW9mX2luZGV4OgorICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfSU5UMzI+KAorICAgICAgICAgICAgICAgICBpbnB1dCwgJm9uZW9mX2luZGV4XykpKTsKKyAgICAgICAgICBzZXRfaGFzX29uZW9mX2luZGV4KCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg4MikpIGdvdG8gcGFyc2VfanNvbl9uYW1lOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgc3RyaW5nIGpzb25fbmFtZSA9IDEwOworICAgICAgY2FzZSAxMDogeworICAgICAgICBpZiAodGFnID09IDgyKSB7CisgICAgICAgICBwYXJzZV9qc29uX25hbWU6CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkU3RyaW5nKAorICAgICAgICAgICAgICAgIGlucHV0LCB0aGlzLT5tdXRhYmxlX2pzb25fbmFtZSgpKSk7CisgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICAgICAgICB0aGlzLT5qc29uX25hbWUoKS5kYXRhKCksIHRoaXMtPmpzb25fbmFtZSgpLmxlbmd0aCgpLAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6UEFSU0UsCisgICAgICAgICAgICAiZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLmpzb25fbmFtZSIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RBdEVuZCgpKSBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBkZWZhdWx0OiB7CisgICAgICBoYW5kbGVfdW51c3VhbDoKKyAgICAgICAgaWYgKHRhZyA9PSAwIHx8CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnV2lyZVR5cGUodGFnKSA9PQorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0VORF9HUk9VUCkgeworICAgICAgICAgIGdvdG8gc3VjY2VzczsKKyAgICAgICAgfQorICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2tpcEZpZWxkKAorICAgICAgICAgICAgICBpbnB1dCwgdGFnLCBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CitzdWNjZXNzOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3VjY2Vzczpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8pCisgIHJldHVybiB0cnVlOworZmFpbHVyZToKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX2ZhaWx1cmU6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvKQorICByZXR1cm4gZmFsc2U7CisjdW5kZWYgRE9fCit9CisKK3ZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvKQorICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgIGlmIChoYXNfbmFtZSgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5uYW1lKCkuZGF0YSgpLCB0aGlzLT5uYW1lKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLm5hbWUiKTsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdNYXliZUFsaWFzZWQoCisgICAgICAxLCB0aGlzLT5uYW1lKCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgZXh0ZW5kZWUgPSAyOworICBpZiAoaGFzX2V4dGVuZGVlKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgIHRoaXMtPmV4dGVuZGVlKCkuZGF0YSgpLCB0aGlzLT5leHRlbmRlZSgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5leHRlbmRlZSIpOworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ01heWJlQWxpYXNlZCgKKyAgICAgIDIsIHRoaXMtPmV4dGVuZGVlKCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBpbnQzMiBudW1iZXIgPSAzOworICBpZiAoaGFzX251bWJlcigpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlSW50MzIoMywgdGhpcy0+bnVtYmVyKCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLkxhYmVsIGxhYmVsID0gNDsKKyAgaWYgKGhhc19sYWJlbCgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlRW51bSgKKyAgICAgIDQsIHRoaXMtPmxhYmVsKCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLlR5cGUgdHlwZSA9IDU7CisgIGlmIChoYXNfdHlwZSgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlRW51bSgKKyAgICAgIDUsIHRoaXMtPnR5cGUoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIHN0cmluZyB0eXBlX25hbWUgPSA2OworICBpZiAoaGFzX3R5cGVfbmFtZSgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT50eXBlX25hbWUoKS5kYXRhKCksIHRoaXMtPnR5cGVfbmFtZSgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by50eXBlX25hbWUiKTsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdNYXliZUFsaWFzZWQoCisgICAgICA2LCB0aGlzLT50eXBlX25hbWUoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIHN0cmluZyBkZWZhdWx0X3ZhbHVlID0gNzsKKyAgaWYgKGhhc19kZWZhdWx0X3ZhbHVlKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgIHRoaXMtPmRlZmF1bHRfdmFsdWUoKS5kYXRhKCksIHRoaXMtPmRlZmF1bHRfdmFsdWUoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uZGVmYXVsdF92YWx1ZSIpOworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ01heWJlQWxpYXNlZCgKKyAgICAgIDcsIHRoaXMtPmRlZmF1bHRfdmFsdWUoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zIG9wdGlvbnMgPSA4OworICBpZiAoaGFzX29wdGlvbnMoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZU1lc3NhZ2VNYXliZVRvQXJyYXkoCisgICAgICA4LCAqdGhpcy0+b3B0aW9uc18sIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBpbnQzMiBvbmVvZl9pbmRleCA9IDk7CisgIGlmIChoYXNfb25lb2ZfaW5kZXgoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUludDMyKDksIHRoaXMtPm9uZW9mX2luZGV4KCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBzdHJpbmcganNvbl9uYW1lID0gMTA7CisgIGlmIChoYXNfanNvbl9uYW1lKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgIHRoaXMtPmpzb25fbmFtZSgpLmRhdGEoKSwgdGhpcy0+anNvbl9uYW1lKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLmpzb25fbmFtZSIpOworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ01heWJlQWxpYXNlZCgKKyAgICAgIDEwLCB0aGlzLT5qc29uX25hbWUoKSwgb3V0cHV0KTsKKyAgfQorCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25GaWVsZHMoCisgICAgICAgIHVua25vd25fZmllbGRzKCksIG91dHB1dCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9lbmQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvKQorfQorCis6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBGaWVsZERlc2NyaXB0b3JQcm90bzo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiB0YXJnZXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9zdGFydDpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8pCisgIC8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKKyAgaWYgKGhhc19uYW1lKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgIHRoaXMtPm5hbWUoKS5kYXRhKCksIHRoaXMtPm5hbWUoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8ubmFtZSIpOworICAgIHRhcmdldCA9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdUb0FycmF5KAorICAgICAgICAxLCB0aGlzLT5uYW1lKCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgZXh0ZW5kZWUgPSAyOworICBpZiAoaGFzX2V4dGVuZGVlKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgIHRoaXMtPmV4dGVuZGVlKCkuZGF0YSgpLCB0aGlzLT5leHRlbmRlZSgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5leHRlbmRlZSIpOworICAgIHRhcmdldCA9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdUb0FycmF5KAorICAgICAgICAyLCB0aGlzLT5leHRlbmRlZSgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgaW50MzIgbnVtYmVyID0gMzsKKyAgaWYgKGhhc19udW1iZXIoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUludDMyVG9BcnJheSgzLCB0aGlzLT5udW1iZXIoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uTGFiZWwgbGFiZWwgPSA0OworICBpZiAoaGFzX2xhYmVsKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVFbnVtVG9BcnJheSgKKyAgICAgIDQsIHRoaXMtPmxhYmVsKCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLlR5cGUgdHlwZSA9IDU7CisgIGlmIChoYXNfdHlwZSgpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlRW51bVRvQXJyYXkoCisgICAgICA1LCB0aGlzLT50eXBlKCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgdHlwZV9uYW1lID0gNjsKKyAgaWYgKGhhc190eXBlX25hbWUoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+dHlwZV9uYW1lKCkuZGF0YSgpLCB0aGlzLT50eXBlX25hbWUoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8udHlwZV9uYW1lIik7CisgICAgdGFyZ2V0ID0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ1RvQXJyYXkoCisgICAgICAgIDYsIHRoaXMtPnR5cGVfbmFtZSgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIGRlZmF1bHRfdmFsdWUgPSA3OworICBpZiAoaGFzX2RlZmF1bHRfdmFsdWUoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+ZGVmYXVsdF92YWx1ZSgpLmRhdGEoKSwgdGhpcy0+ZGVmYXVsdF92YWx1ZSgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5kZWZhdWx0X3ZhbHVlIik7CisgICAgdGFyZ2V0ID0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ1RvQXJyYXkoCisgICAgICAgIDcsIHRoaXMtPmRlZmF1bHRfdmFsdWUoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zIG9wdGlvbnMgPSA4OworICBpZiAoaGFzX29wdGlvbnMoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjoKKyAgICAgIFdyaXRlTWVzc2FnZU5vVmlydHVhbFRvQXJyYXkoCisgICAgICAgIDgsICp0aGlzLT5vcHRpb25zXywgdGFyZ2V0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGludDMyIG9uZW9mX2luZGV4ID0gOTsKKyAgaWYgKGhhc19vbmVvZl9pbmRleCgpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlSW50MzJUb0FycmF5KDksIHRoaXMtPm9uZW9mX2luZGV4KCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBzdHJpbmcganNvbl9uYW1lID0gMTA7CisgIGlmIChoYXNfanNvbl9uYW1lKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgIHRoaXMtPmpzb25fbmFtZSgpLmRhdGEoKSwgdGhpcy0+anNvbl9uYW1lKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLmpzb25fbmFtZSIpOworICAgIHRhcmdldCA9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdUb0FycmF5KAorICAgICAgICAxMCwgdGhpcy0+anNvbl9uYW1lKCksIHRhcmdldCk7CisgIH0KKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTZXJpYWxpemVVbmtub3duRmllbGRzVG9BcnJheSgKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSwgdGFyZ2V0KTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X2VuZDpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8pCisgIHJldHVybiB0YXJnZXQ7Cit9CisKK2ludCBGaWVsZERlc2NyaXB0b3JQcm90bzo6Qnl0ZVNpemUoKSBjb25zdCB7CisgIGludCB0b3RhbF9zaXplID0gMDsKKworICBpZiAoX2hhc19iaXRzX1swIC8gMzJdICYgMjU1dSkgeworICAgIC8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKKyAgICBpZiAoaGFzX25hbWUoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlN0cmluZ1NpemUoCisgICAgICAgICAgdGhpcy0+bmFtZSgpKTsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCBpbnQzMiBudW1iZXIgPSAzOworICAgIGlmIChoYXNfbnVtYmVyKCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpJbnQzMlNpemUoCisgICAgICAgICAgdGhpcy0+bnVtYmVyKCkpOworICAgIH0KKworICAgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uTGFiZWwgbGFiZWwgPSA0OworICAgIGlmIChoYXNfbGFiZWwoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkVudW1TaXplKHRoaXMtPmxhYmVsKCkpOworICAgIH0KKworICAgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uVHlwZSB0eXBlID0gNTsKKyAgICBpZiAoaGFzX3R5cGUoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkVudW1TaXplKHRoaXMtPnR5cGUoKSk7CisgICAgfQorCisgICAgLy8gb3B0aW9uYWwgc3RyaW5nIHR5cGVfbmFtZSA9IDY7CisgICAgaWYgKGhhc190eXBlX25hbWUoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlN0cmluZ1NpemUoCisgICAgICAgICAgdGhpcy0+dHlwZV9uYW1lKCkpOworICAgIH0KKworICAgIC8vIG9wdGlvbmFsIHN0cmluZyBleHRlbmRlZSA9IDI7CisgICAgaWYgKGhhc19leHRlbmRlZSgpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U3RyaW5nU2l6ZSgKKyAgICAgICAgICB0aGlzLT5leHRlbmRlZSgpKTsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCBzdHJpbmcgZGVmYXVsdF92YWx1ZSA9IDc7CisgICAgaWYgKGhhc19kZWZhdWx0X3ZhbHVlKCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTdHJpbmdTaXplKAorICAgICAgICAgIHRoaXMtPmRlZmF1bHRfdmFsdWUoKSk7CisgICAgfQorCisgICAgLy8gb3B0aW9uYWwgaW50MzIgb25lb2ZfaW5kZXggPSA5OworICAgIGlmIChoYXNfb25lb2ZfaW5kZXgoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkludDMyU2l6ZSgKKyAgICAgICAgICB0aGlzLT5vbmVvZl9pbmRleCgpKTsKKyAgICB9CisKKyAgfQorICBpZiAoX2hhc19iaXRzX1s4IC8gMzJdICYgNzY4dSkgeworICAgIC8vIG9wdGlvbmFsIHN0cmluZyBqc29uX25hbWUgPSAxMDsKKyAgICBpZiAoaGFzX2pzb25fbmFtZSgpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U3RyaW5nU2l6ZSgKKyAgICAgICAgICB0aGlzLT5qc29uX25hbWUoKSk7CisgICAgfQorCisgICAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMgb3B0aW9ucyA9IDg7CisgICAgaWYgKGhhc19vcHRpb25zKCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpNZXNzYWdlU2l6ZU5vVmlydHVhbCgKKyAgICAgICAgICAqdGhpcy0+b3B0aW9uc18pOworICAgIH0KKworICB9CisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHRvdGFsX3NpemUgKz0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OkNvbXB1dGVVbmtub3duRmllbGRzU2l6ZSgKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSk7CisgIH0KKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHRvdGFsX3NpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworICByZXR1cm4gdG90YWxfc2l6ZTsKK30KKwordm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6TWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90byogc291cmNlID0gCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpEeW5hbWljQ2FzdFRvR2VuZXJhdGVkPGNvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvPigKKyAgICAgICAgICAmZnJvbSk7CisgIGlmIChzb3VyY2UgPT0gTlVMTCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlJlZmxlY3Rpb25PcHM6Ok1lcmdlKGZyb20sIHRoaXMpOworICB9IGVsc2UgeworICAgIE1lcmdlRnJvbSgqc291cmNlKTsKKyAgfQorfQorCit2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpNZXJnZUZyb20oY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG8mIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgaWYgKGZyb20uX2hhc19iaXRzX1swIC8gMzJdICYgKDB4ZmZ1IDw8ICgwICUgMzIpKSkgeworICAgIGlmIChmcm9tLmhhc19uYW1lKCkpIHsKKyAgICAgIHNldF9oYXNfbmFtZSgpOworICAgICAgbmFtZV8uQXNzaWduV2l0aERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBmcm9tLm5hbWVfKTsKKyAgICB9CisgICAgaWYgKGZyb20uaGFzX251bWJlcigpKSB7CisgICAgICBzZXRfbnVtYmVyKGZyb20ubnVtYmVyKCkpOworICAgIH0KKyAgICBpZiAoZnJvbS5oYXNfbGFiZWwoKSkgeworICAgICAgc2V0X2xhYmVsKGZyb20ubGFiZWwoKSk7CisgICAgfQorICAgIGlmIChmcm9tLmhhc190eXBlKCkpIHsKKyAgICAgIHNldF90eXBlKGZyb20udHlwZSgpKTsKKyAgICB9CisgICAgaWYgKGZyb20uaGFzX3R5cGVfbmFtZSgpKSB7CisgICAgICBzZXRfaGFzX3R5cGVfbmFtZSgpOworICAgICAgdHlwZV9uYW1lXy5Bc3NpZ25XaXRoRGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGZyb20udHlwZV9uYW1lXyk7CisgICAgfQorICAgIGlmIChmcm9tLmhhc19leHRlbmRlZSgpKSB7CisgICAgICBzZXRfaGFzX2V4dGVuZGVlKCk7CisgICAgICBleHRlbmRlZV8uQXNzaWduV2l0aERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBmcm9tLmV4dGVuZGVlXyk7CisgICAgfQorICAgIGlmIChmcm9tLmhhc19kZWZhdWx0X3ZhbHVlKCkpIHsKKyAgICAgIHNldF9oYXNfZGVmYXVsdF92YWx1ZSgpOworICAgICAgZGVmYXVsdF92YWx1ZV8uQXNzaWduV2l0aERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBmcm9tLmRlZmF1bHRfdmFsdWVfKTsKKyAgICB9CisgICAgaWYgKGZyb20uaGFzX29uZW9mX2luZGV4KCkpIHsKKyAgICAgIHNldF9vbmVvZl9pbmRleChmcm9tLm9uZW9mX2luZGV4KCkpOworICAgIH0KKyAgfQorICBpZiAoZnJvbS5faGFzX2JpdHNfWzggLyAzMl0gJiAoMHhmZnUgPDwgKDggJSAzMikpKSB7CisgICAgaWYgKGZyb20uaGFzX2pzb25fbmFtZSgpKSB7CisgICAgICBzZXRfaGFzX2pzb25fbmFtZSgpOworICAgICAganNvbl9uYW1lXy5Bc3NpZ25XaXRoRGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGZyb20uanNvbl9uYW1lXyk7CisgICAgfQorICAgIGlmIChmcm9tLmhhc19vcHRpb25zKCkpIHsKKyAgICAgIG11dGFibGVfb3B0aW9ucygpLT46Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkT3B0aW9uczo6TWVyZ2VGcm9tKGZyb20ub3B0aW9ucygpKTsKKyAgICB9CisgIH0KKyAgaWYgKGZyb20uX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPk1lcmdlRnJvbShmcm9tLnVua25vd25fZmllbGRzKCkpOworICB9Cit9CisKK3ZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OkNvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK3ZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OkNvcHlGcm9tKGNvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKworYm9vbCBGaWVsZERlc2NyaXB0b3JQcm90bzo6SXNJbml0aWFsaXplZCgpIGNvbnN0IHsKKworICBpZiAoaGFzX29wdGlvbnMoKSkgeworICAgIGlmICghdGhpcy0+b3B0aW9uc18tPklzSW5pdGlhbGl6ZWQoKSkgcmV0dXJuIGZhbHNlOworICB9CisgIHJldHVybiB0cnVlOworfQorCit2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpTd2FwKEZpZWxkRGVzY3JpcHRvclByb3RvKiBvdGhlcikgeworICBpZiAob3RoZXIgPT0gdGhpcykgcmV0dXJuOworICBJbnRlcm5hbFN3YXAob3RoZXIpOworfQordm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6SW50ZXJuYWxTd2FwKEZpZWxkRGVzY3JpcHRvclByb3RvKiBvdGhlcikgeworICBuYW1lXy5Td2FwKCZvdGhlci0+bmFtZV8pOworICBzdGQ6OnN3YXAobnVtYmVyXywgb3RoZXItPm51bWJlcl8pOworICBzdGQ6OnN3YXAobGFiZWxfLCBvdGhlci0+bGFiZWxfKTsKKyAgc3RkOjpzd2FwKHR5cGVfLCBvdGhlci0+dHlwZV8pOworICB0eXBlX25hbWVfLlN3YXAoJm90aGVyLT50eXBlX25hbWVfKTsKKyAgZXh0ZW5kZWVfLlN3YXAoJm90aGVyLT5leHRlbmRlZV8pOworICBkZWZhdWx0X3ZhbHVlXy5Td2FwKCZvdGhlci0+ZGVmYXVsdF92YWx1ZV8pOworICBzdGQ6OnN3YXAob25lb2ZfaW5kZXhfLCBvdGhlci0+b25lb2ZfaW5kZXhfKTsKKyAganNvbl9uYW1lXy5Td2FwKCZvdGhlci0+anNvbl9uYW1lXyk7CisgIHN0ZDo6c3dhcChvcHRpb25zXywgb3RoZXItPm9wdGlvbnNfKTsKKyAgc3RkOjpzd2FwKF9oYXNfYml0c19bMF0sIG90aGVyLT5faGFzX2JpdHNfWzBdKTsKKyAgX2ludGVybmFsX21ldGFkYXRhXy5Td2FwKCZvdGhlci0+X2ludGVybmFsX21ldGFkYXRhXyk7CisgIHN0ZDo6c3dhcChfY2FjaGVkX3NpemVfLCBvdGhlci0+X2NhY2hlZF9zaXplXyk7Cit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgRmllbGREZXNjcmlwdG9yUHJvdG86OkdldE1ldGFkYXRhKCkgY29uc3QgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBtZXRhZGF0YTsKKyAgbWV0YWRhdGEuZGVzY3JpcHRvciA9IEZpZWxkRGVzY3JpcHRvclByb3RvX2Rlc2NyaXB0b3JfOworICBtZXRhZGF0YS5yZWZsZWN0aW9uID0gRmllbGREZXNjcmlwdG9yUHJvdG9fcmVmbGVjdGlvbl87CisgIHJldHVybiBtZXRhZGF0YTsKK30KKworI2lmIFBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworLy8gRmllbGREZXNjcmlwdG9yUHJvdG8KKworLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworYm9vbCBGaWVsZERlc2NyaXB0b3JQcm90bzo6aGFzX25hbWUoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDF1KSAhPSAwOworfQordm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19uYW1lKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDF1OworfQordm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX25hbWUoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDF1OworfQordm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfbmFtZSgpIHsKKyAgbmFtZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfbmFtZSgpOworfQorIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEZpZWxkRGVzY3JpcHRvclByb3RvOjpuYW1lKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5uYW1lKQorICByZXR1cm4gbmFtZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9uYW1lKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfbmFtZSgpOworICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5uYW1lKQorfQorIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfbmFtZSgpOworICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLm5hbWUpCit9Cisgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6c2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHNldF9oYXNfbmFtZSgpOworICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KKyA6OnN0ZDo6c3RyaW5nKiBGaWVsZERlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9uYW1lKCkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLm5hbWUpCisgIHJldHVybiBuYW1lXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIDo6c3RkOjpzdHJpbmcqIEZpZWxkRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX25hbWUoKSB7CisgIGNsZWFyX2hhc19uYW1lKCk7CisgIHJldHVybiBuYW1lXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9hbGxvY2F0ZWRfbmFtZSg6OnN0ZDo6c3RyaW5nKiBuYW1lKSB7CisgIGlmIChuYW1lICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX25hbWUoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfbmFtZSgpOworICB9CisgIG5hbWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBuYW1lKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLm5hbWUpCit9CisKKy8vIG9wdGlvbmFsIGludDMyIG51bWJlciA9IDM7Citib29sIEZpZWxkRGVzY3JpcHRvclByb3RvOjpoYXNfbnVtYmVyKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAydSkgIT0gMDsKK30KK3ZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9oYXNfbnVtYmVyKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDJ1OworfQordm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX251bWJlcigpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMnU7Cit9Cit2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpjbGVhcl9udW1iZXIoKSB7CisgIG51bWJlcl8gPSAwOworICBjbGVhcl9oYXNfbnVtYmVyKCk7Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiBGaWVsZERlc2NyaXB0b3JQcm90bzo6bnVtYmVyKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5udW1iZXIpCisgIHJldHVybiBudW1iZXJfOworfQorIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9udW1iZXIoOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiB2YWx1ZSkgeworICBzZXRfaGFzX251bWJlcigpOworICBudW1iZXJfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLm51bWJlcikKK30KKworLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5MYWJlbCBsYWJlbCA9IDQ7Citib29sIEZpZWxkRGVzY3JpcHRvclByb3RvOjpoYXNfbGFiZWwoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDR1KSAhPSAwOworfQordm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19sYWJlbCgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDA0dTsKK30KK3ZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OmNsZWFyX2hhc19sYWJlbCgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwNHU7Cit9Cit2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpjbGVhcl9sYWJlbCgpIHsKKyAgbGFiZWxfID0gMTsKKyAgY2xlYXJfaGFzX2xhYmVsKCk7Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90b19MYWJlbCBGaWVsZERlc2NyaXB0b3JQcm90bzo6bGFiZWwoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLmxhYmVsKQorICByZXR1cm4gc3RhdGljX2Nhc3Q8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWwgPihsYWJlbF8pOworfQorIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9sYWJlbCg6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsIHZhbHVlKSB7CisgIGFzc2VydCg6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsX0lzVmFsaWQodmFsdWUpKTsKKyAgc2V0X2hhc19sYWJlbCgpOworICBsYWJlbF8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8ubGFiZWwpCit9CisKKy8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uVHlwZSB0eXBlID0gNTsKK2Jvb2wgRmllbGREZXNjcmlwdG9yUHJvdG86Omhhc190eXBlKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDA4dSkgIT0gMDsKK30KK3ZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9oYXNfdHlwZSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDA4dTsKK30KK3ZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OmNsZWFyX2hhc190eXBlKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDA4dTsKK30KK3ZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OmNsZWFyX3R5cGUoKSB7CisgIHR5cGVfID0gMTsKKyAgY2xlYXJfaGFzX3R5cGUoKTsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGUgRmllbGREZXNjcmlwdG9yUHJvdG86OnR5cGUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLnR5cGUpCisgIHJldHVybiBzdGF0aWNfY2FzdDwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlID4odHlwZV8pOworfQorIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF90eXBlKDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZSB2YWx1ZSkgeworICBhc3NlcnQoOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX0lzVmFsaWQodmFsdWUpKTsKKyAgc2V0X2hhc190eXBlKCk7CisgIHR5cGVfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLnR5cGUpCit9CisKKy8vIG9wdGlvbmFsIHN0cmluZyB0eXBlX25hbWUgPSA2OworYm9vbCBGaWVsZERlc2NyaXB0b3JQcm90bzo6aGFzX3R5cGVfbmFtZSgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAxMHUpICE9IDA7Cit9Cit2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX3R5cGVfbmFtZSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDEwdTsKK30KK3ZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OmNsZWFyX2hhc190eXBlX25hbWUoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMTB1OworfQordm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfdHlwZV9uYW1lKCkgeworICB0eXBlX25hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX3R5cGVfbmFtZSgpOworfQorIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEZpZWxkRGVzY3JpcHRvclByb3RvOjp0eXBlX25hbWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLnR5cGVfbmFtZSkKKyAgcmV0dXJuIHR5cGVfbmFtZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF90eXBlX25hbWUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgc2V0X2hhc190eXBlX25hbWUoKTsKKyAgdHlwZV9uYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by50eXBlX25hbWUpCit9Cisgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6c2V0X3R5cGVfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX3R5cGVfbmFtZSgpOworICB0eXBlX25hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8udHlwZV9uYW1lKQorfQorIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF90eXBlX25hbWUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHNldF9oYXNfdHlwZV9uYW1lKCk7CisgIHR5cGVfbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLnR5cGVfbmFtZSkKK30KKyA6OnN0ZDo6c3RyaW5nKiBGaWVsZERlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV90eXBlX25hbWUoKSB7CisgIHNldF9oYXNfdHlwZV9uYW1lKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by50eXBlX25hbWUpCisgIHJldHVybiB0eXBlX25hbWVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CisgOjpzdGQ6OnN0cmluZyogRmllbGREZXNjcmlwdG9yUHJvdG86OnJlbGVhc2VfdHlwZV9uYW1lKCkgeworICBjbGVhcl9oYXNfdHlwZV9uYW1lKCk7CisgIHJldHVybiB0eXBlX25hbWVfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6c2V0X2FsbG9jYXRlZF90eXBlX25hbWUoOjpzdGQ6OnN0cmluZyogdHlwZV9uYW1lKSB7CisgIGlmICh0eXBlX25hbWUgIT0gTlVMTCkgeworICAgIHNldF9oYXNfdHlwZV9uYW1lKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX3R5cGVfbmFtZSgpOworICB9CisgIHR5cGVfbmFtZV8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHR5cGVfbmFtZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by50eXBlX25hbWUpCit9CisKKy8vIG9wdGlvbmFsIHN0cmluZyBleHRlbmRlZSA9IDI7Citib29sIEZpZWxkRGVzY3JpcHRvclByb3RvOjpoYXNfZXh0ZW5kZWUoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMjB1KSAhPSAwOworfQordm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19leHRlbmRlZSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDIwdTsKK30KK3ZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OmNsZWFyX2hhc19leHRlbmRlZSgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAyMHU7Cit9Cit2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpjbGVhcl9leHRlbmRlZSgpIHsKKyAgZXh0ZW5kZWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX2V4dGVuZGVlKCk7Cit9CisgY29uc3QgOjpzdGQ6OnN0cmluZyYgRmllbGREZXNjcmlwdG9yUHJvdG86OmV4dGVuZGVlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5leHRlbmRlZSkKKyAgcmV0dXJuIGV4dGVuZGVlXy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6c2V0X2V4dGVuZGVlKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfZXh0ZW5kZWUoKTsKKyAgZXh0ZW5kZWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLmV4dGVuZGVlKQorfQorIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9leHRlbmRlZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX2V4dGVuZGVlKCk7CisgIGV4dGVuZGVlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLmV4dGVuZGVlKQorfQorIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9leHRlbmRlZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19leHRlbmRlZSgpOworICBleHRlbmRlZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLmV4dGVuZGVlKQorfQorIDo6c3RkOjpzdHJpbmcqIEZpZWxkRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX2V4dGVuZGVlKCkgeworICBzZXRfaGFzX2V4dGVuZGVlKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5leHRlbmRlZSkKKyAgcmV0dXJuIGV4dGVuZGVlXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIDo6c3RkOjpzdHJpbmcqIEZpZWxkRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX2V4dGVuZGVlKCkgeworICBjbGVhcl9oYXNfZXh0ZW5kZWUoKTsKKyAgcmV0dXJuIGV4dGVuZGVlXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9hbGxvY2F0ZWRfZXh0ZW5kZWUoOjpzdGQ6OnN0cmluZyogZXh0ZW5kZWUpIHsKKyAgaWYgKGV4dGVuZGVlICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX2V4dGVuZGVlKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX2V4dGVuZGVlKCk7CisgIH0KKyAgZXh0ZW5kZWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBleHRlbmRlZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5leHRlbmRlZSkKK30KKworLy8gb3B0aW9uYWwgc3RyaW5nIGRlZmF1bHRfdmFsdWUgPSA3OworYm9vbCBGaWVsZERlc2NyaXB0b3JQcm90bzo6aGFzX2RlZmF1bHRfdmFsdWUoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwNDB1KSAhPSAwOworfQordm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19kZWZhdWx0X3ZhbHVlKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwNDB1OworfQordm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX2RlZmF1bHRfdmFsdWUoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwNDB1OworfQordm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfZGVmYXVsdF92YWx1ZSgpIHsKKyAgZGVmYXVsdF92YWx1ZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfZGVmYXVsdF92YWx1ZSgpOworfQorIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEZpZWxkRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X3ZhbHVlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5kZWZhdWx0X3ZhbHVlKQorICByZXR1cm4gZGVmYXVsdF92YWx1ZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9kZWZhdWx0X3ZhbHVlKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfZGVmYXVsdF92YWx1ZSgpOworICBkZWZhdWx0X3ZhbHVlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5kZWZhdWx0X3ZhbHVlKQorfQorIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9kZWZhdWx0X3ZhbHVlKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfZGVmYXVsdF92YWx1ZSgpOworICBkZWZhdWx0X3ZhbHVlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLmRlZmF1bHRfdmFsdWUpCit9Cisgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6c2V0X2RlZmF1bHRfdmFsdWUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHNldF9oYXNfZGVmYXVsdF92YWx1ZSgpOworICBkZWZhdWx0X3ZhbHVlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uZGVmYXVsdF92YWx1ZSkKK30KKyA6OnN0ZDo6c3RyaW5nKiBGaWVsZERlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9kZWZhdWx0X3ZhbHVlKCkgeworICBzZXRfaGFzX2RlZmF1bHRfdmFsdWUoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLmRlZmF1bHRfdmFsdWUpCisgIHJldHVybiBkZWZhdWx0X3ZhbHVlXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIDo6c3RkOjpzdHJpbmcqIEZpZWxkRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX2RlZmF1bHRfdmFsdWUoKSB7CisgIGNsZWFyX2hhc19kZWZhdWx0X3ZhbHVlKCk7CisgIHJldHVybiBkZWZhdWx0X3ZhbHVlXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9hbGxvY2F0ZWRfZGVmYXVsdF92YWx1ZSg6OnN0ZDo6c3RyaW5nKiBkZWZhdWx0X3ZhbHVlKSB7CisgIGlmIChkZWZhdWx0X3ZhbHVlICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX2RlZmF1bHRfdmFsdWUoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfZGVmYXVsdF92YWx1ZSgpOworICB9CisgIGRlZmF1bHRfdmFsdWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBkZWZhdWx0X3ZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLmRlZmF1bHRfdmFsdWUpCit9CisKKy8vIG9wdGlvbmFsIGludDMyIG9uZW9mX2luZGV4ID0gOTsKK2Jvb2wgRmllbGREZXNjcmlwdG9yUHJvdG86Omhhc19vbmVvZl9pbmRleCgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDA4MHUpICE9IDA7Cit9Cit2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX29uZW9mX2luZGV4KCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwODB1OworfQordm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX29uZW9mX2luZGV4KCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDgwdTsKK30KK3ZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OmNsZWFyX29uZW9mX2luZGV4KCkgeworICBvbmVvZl9pbmRleF8gPSAwOworICBjbGVhcl9oYXNfb25lb2ZfaW5kZXgoKTsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIEZpZWxkRGVzY3JpcHRvclByb3RvOjpvbmVvZl9pbmRleCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8ub25lb2ZfaW5kZXgpCisgIHJldHVybiBvbmVvZl9pbmRleF87Cit9Cisgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6c2V0X29uZW9mX2luZGV4KDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgdmFsdWUpIHsKKyAgc2V0X2hhc19vbmVvZl9pbmRleCgpOworICBvbmVvZl9pbmRleF8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8ub25lb2ZfaW5kZXgpCit9CisKKy8vIG9wdGlvbmFsIHN0cmluZyBqc29uX25hbWUgPSAxMDsKK2Jvb2wgRmllbGREZXNjcmlwdG9yUHJvdG86Omhhc19qc29uX25hbWUoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAxMDB1KSAhPSAwOworfQordm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19qc29uX25hbWUoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDEwMHU7Cit9Cit2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfanNvbl9uYW1lKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMTAwdTsKK30KK3ZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OmNsZWFyX2pzb25fbmFtZSgpIHsKKyAganNvbl9uYW1lXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGNsZWFyX2hhc19qc29uX25hbWUoKTsKK30KKyBjb25zdCA6OnN0ZDo6c3RyaW5nJiBGaWVsZERlc2NyaXB0b3JQcm90bzo6anNvbl9uYW1lKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5qc29uX25hbWUpCisgIHJldHVybiBqc29uX25hbWVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpzZXRfanNvbl9uYW1lKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfanNvbl9uYW1lKCk7CisgIGpzb25fbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uanNvbl9uYW1lKQorfQorIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9qc29uX25hbWUoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgc2V0X2hhc19qc29uX25hbWUoKTsKKyAganNvbl9uYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLmpzb25fbmFtZSkKK30KKyB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpzZXRfanNvbl9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX2pzb25fbmFtZSgpOworICBqc29uX25hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5qc29uX25hbWUpCit9CisgOjpzdGQ6OnN0cmluZyogRmllbGREZXNjcmlwdG9yUHJvdG86Om11dGFibGVfanNvbl9uYW1lKCkgeworICBzZXRfaGFzX2pzb25fbmFtZSgpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uanNvbl9uYW1lKQorICByZXR1cm4ganNvbl9uYW1lXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIDo6c3RkOjpzdHJpbmcqIEZpZWxkRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX2pzb25fbmFtZSgpIHsKKyAgY2xlYXJfaGFzX2pzb25fbmFtZSgpOworICByZXR1cm4ganNvbl9uYW1lXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9hbGxvY2F0ZWRfanNvbl9uYW1lKDo6c3RkOjpzdHJpbmcqIGpzb25fbmFtZSkgeworICBpZiAoanNvbl9uYW1lICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX2pzb25fbmFtZSgpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19qc29uX25hbWUoKTsKKyAgfQorICBqc29uX25hbWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBqc29uX25hbWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uanNvbl9uYW1lKQorfQorCisvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucyBvcHRpb25zID0gODsKK2Jvb2wgRmllbGREZXNjcmlwdG9yUHJvdG86Omhhc19vcHRpb25zKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMjAwdSkgIT0gMDsKK30KK3ZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9oYXNfb3B0aW9ucygpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMjAwdTsKK30KK3ZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OmNsZWFyX2hhc19vcHRpb25zKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMjAwdTsKK30KK3ZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OmNsZWFyX29wdGlvbnMoKSB7CisgIGlmIChvcHRpb25zXyAhPSBOVUxMKSBvcHRpb25zXy0+Ojpnb29nbGU6OnByb3RvYnVmOjpGaWVsZE9wdGlvbnM6OkNsZWFyKCk7CisgIGNsZWFyX2hhc19vcHRpb25zKCk7Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkT3B0aW9ucyYgRmllbGREZXNjcmlwdG9yUHJvdG86Om9wdGlvbnMoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLm9wdGlvbnMpCisgIHJldHVybiBvcHRpb25zXyAhPSBOVUxMID8gKm9wdGlvbnNfIDogKmRlZmF1bHRfaW5zdGFuY2VfLT5vcHRpb25zXzsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGRPcHRpb25zKiBGaWVsZERlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9vcHRpb25zKCkgeworICBzZXRfaGFzX29wdGlvbnMoKTsKKyAgaWYgKG9wdGlvbnNfID09IE5VTEwpIHsKKyAgICBvcHRpb25zXyA9IG5ldyA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkT3B0aW9uczsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8ub3B0aW9ucykKKyAgcmV0dXJuIG9wdGlvbnNfOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZE9wdGlvbnMqIEZpZWxkRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX29wdGlvbnMoKSB7CisgIGNsZWFyX2hhc19vcHRpb25zKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGRPcHRpb25zKiB0ZW1wID0gb3B0aW9uc187CisgIG9wdGlvbnNfID0gTlVMTDsKKyAgcmV0dXJuIHRlbXA7Cit9Cit2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpzZXRfYWxsb2NhdGVkX29wdGlvbnMoOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZE9wdGlvbnMqIG9wdGlvbnMpIHsKKyAgZGVsZXRlIG9wdGlvbnNfOworICBvcHRpb25zXyA9IG9wdGlvbnM7CisgIGlmIChvcHRpb25zKSB7CisgICAgc2V0X2hhc19vcHRpb25zKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX29wdGlvbnMoKTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8ub3B0aW9ucykKK30KKworI2VuZGlmICAvLyBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisjaWYgIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKK2NvbnN0IGludCBPbmVvZkRlc2NyaXB0b3JQcm90bzo6a05hbWVGaWVsZE51bWJlcjsKKyNlbmRpZiAgLy8gIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKKworT25lb2ZEZXNjcmlwdG9yUHJvdG86Ok9uZW9mRGVzY3JpcHRvclByb3RvKCkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5PbmVvZkRlc2NyaXB0b3JQcm90bykKK30KKwordm9pZCBPbmVvZkRlc2NyaXB0b3JQcm90bzo6SW5pdEFzRGVmYXVsdEluc3RhbmNlKCkgeworfQorCitPbmVvZkRlc2NyaXB0b3JQcm90bzo6T25lb2ZEZXNjcmlwdG9yUHJvdG8oY29uc3QgT25lb2ZEZXNjcmlwdG9yUHJvdG8mIGZyb20pCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksCisgICAgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29weV9jb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuT25lb2ZEZXNjcmlwdG9yUHJvdG8pCit9CisKK3ZvaWQgT25lb2ZEZXNjcmlwdG9yUHJvdG86OlNoYXJlZEN0b3IoKSB7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSAwOworICBuYW1lXy5VbnNhZmVTZXREZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIDo6bWVtc2V0KF9oYXNfYml0c18sIDAsIHNpemVvZihfaGFzX2JpdHNfKSk7Cit9CisKK09uZW9mRGVzY3JpcHRvclByb3RvOjp+T25lb2ZEZXNjcmlwdG9yUHJvdG8oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChkZXN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5PbmVvZkRlc2NyaXB0b3JQcm90bykKKyAgU2hhcmVkRHRvcigpOworfQorCit2b2lkIE9uZW9mRGVzY3JpcHRvclByb3RvOjpTaGFyZWREdG9yKCkgeworICBuYW1lXy5EZXN0cm95Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBpZiAodGhpcyAhPSBkZWZhdWx0X2luc3RhbmNlXykgeworICB9Cit9CisKK3ZvaWQgT25lb2ZEZXNjcmlwdG9yUHJvdG86OlNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0IHsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHNpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBPbmVvZkRlc2NyaXB0b3JQcm90bzo6ZGVzY3JpcHRvcigpIHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIHJldHVybiBPbmVvZkRlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXzsKK30KKworY29uc3QgT25lb2ZEZXNjcmlwdG9yUHJvdG8mIE9uZW9mRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlKCkgeworICBpZiAoZGVmYXVsdF9pbnN0YW5jZV8gPT0gTlVMTCkgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICByZXR1cm4gKmRlZmF1bHRfaW5zdGFuY2VfOworfQorCitPbmVvZkRlc2NyaXB0b3JQcm90byogT25lb2ZEZXNjcmlwdG9yUHJvdG86OmRlZmF1bHRfaW5zdGFuY2VfID0gTlVMTDsKKworT25lb2ZEZXNjcmlwdG9yUHJvdG8qIE9uZW9mRGVzY3JpcHRvclByb3RvOjpOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0IHsKKyAgT25lb2ZEZXNjcmlwdG9yUHJvdG8qIG4gPSBuZXcgT25lb2ZEZXNjcmlwdG9yUHJvdG87CisgIGlmIChhcmVuYSAhPSBOVUxMKSB7CisgICAgYXJlbmEtPk93bihuKTsKKyAgfQorICByZXR1cm4gbjsKK30KKwordm9pZCBPbmVvZkRlc2NyaXB0b3JQcm90bzo6Q2xlYXIoKSB7CisgIGlmIChoYXNfbmFtZSgpKSB7CisgICAgbmFtZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICB9CisgIDo6bWVtc2V0KF9oYXNfYml0c18sIDAsIHNpemVvZihfaGFzX2JpdHNfKSk7CisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+Q2xlYXIoKTsKKyAgfQorfQorCitib29sIE9uZW9mRGVzY3JpcHRvclByb3RvOjpNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyNkZWZpbmUgRE9fKEVYUFJFU1NJT04pIGlmICghKEVYUFJFU1NJT04pKSBnb3RvIGZhaWx1cmUKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgdGFnOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLk9uZW9mRGVzY3JpcHRvclByb3RvKQorICBmb3IgKDs7KSB7CisgICAgOjpzdGQ6OnBhaXI8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyLCBib29sPiBwID0gaW5wdXQtPlJlYWRUYWdXaXRoQ3V0b2ZmKDEyNyk7CisgICAgdGFnID0gcC5maXJzdDsKKyAgICBpZiAoIXAuc2Vjb25kKSBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgIHN3aXRjaCAoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ0ZpZWxkTnVtYmVyKHRhZykpIHsKKyAgICAgIC8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKKyAgICAgIGNhc2UgMTogeworICAgICAgICBpZiAodGFnID09IDEwKSB7CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkU3RyaW5nKAorICAgICAgICAgICAgICAgIGlucHV0LCB0aGlzLT5tdXRhYmxlX25hbWUoKSkpOworICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgICAgICAgdGhpcy0+bmFtZSgpLmRhdGEoKSwgdGhpcy0+bmFtZSgpLmxlbmd0aCgpLAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6UEFSU0UsCisgICAgICAgICAgICAiZ29vZ2xlLnByb3RvYnVmLk9uZW9mRGVzY3JpcHRvclByb3RvLm5hbWUiKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0QXRFbmQoKSkgZ290byBzdWNjZXNzOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgZGVmYXVsdDogeworICAgICAgaGFuZGxlX3VudXN1YWw6CisgICAgICAgIGlmICh0YWcgPT0gMCB8fAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ1dpcmVUeXBlKHRhZykgPT0KKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVApIHsKKyAgICAgICAgICBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIH0KKyAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNraXBGaWVsZCgKKyAgICAgICAgICAgICAgaW5wdXQsIHRhZywgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpKSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgfQorc3VjY2VzczoKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N1Y2Nlc3M6Z29vZ2xlLnByb3RvYnVmLk9uZW9mRGVzY3JpcHRvclByb3RvKQorICByZXR1cm4gdHJ1ZTsKK2ZhaWx1cmU6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9mYWlsdXJlOmdvb2dsZS5wcm90b2J1Zi5PbmVvZkRlc2NyaXB0b3JQcm90bykKKyAgcmV0dXJuIGZhbHNlOworI3VuZGVmIERPXworfQorCit2b2lkIE9uZW9mRGVzY3JpcHRvclByb3RvOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5PbmVvZkRlc2NyaXB0b3JQcm90bykKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICBpZiAoaGFzX25hbWUoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+bmFtZSgpLmRhdGEoKSwgdGhpcy0+bmFtZSgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5PbmVvZkRlc2NyaXB0b3JQcm90by5uYW1lIik7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nTWF5YmVBbGlhc2VkKAorICAgICAgMSwgdGhpcy0+bmFtZSgpLCBvdXRwdXQpOworICB9CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bkZpZWxkcygKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSwgb3V0cHV0KTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX2VuZDpnb29nbGUucHJvdG9idWYuT25lb2ZEZXNjcmlwdG9yUHJvdG8pCit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIE9uZW9mRGVzY3JpcHRvclByb3RvOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIHRhcmdldCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5PbmVvZkRlc2NyaXB0b3JQcm90bykKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICBpZiAoaGFzX25hbWUoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+bmFtZSgpLmRhdGEoKSwgdGhpcy0+bmFtZSgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5PbmVvZkRlc2NyaXB0b3JQcm90by5uYW1lIik7CisgICAgdGFyZ2V0ID0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ1RvQXJyYXkoCisgICAgICAgIDEsIHRoaXMtPm5hbWUoKSwgdGFyZ2V0KTsKKyAgfQorCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25GaWVsZHNUb0FycmF5KAorICAgICAgICB1bmtub3duX2ZpZWxkcygpLCB0YXJnZXQpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfZW5kOmdvb2dsZS5wcm90b2J1Zi5PbmVvZkRlc2NyaXB0b3JQcm90bykKKyAgcmV0dXJuIHRhcmdldDsKK30KKworaW50IE9uZW9mRGVzY3JpcHRvclByb3RvOjpCeXRlU2l6ZSgpIGNvbnN0IHsKKyAgaW50IHRvdGFsX3NpemUgPSAwOworCisgIC8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKKyAgaWYgKGhhc19uYW1lKCkpIHsKKyAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlN0cmluZ1NpemUoCisgICAgICAgIHRoaXMtPm5hbWUoKSk7CisgIH0KKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICB0b3RhbF9zaXplICs9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpDb21wdXRlVW5rbm93bkZpZWxkc1NpemUoCisgICAgICAgIHVua25vd25fZmllbGRzKCkpOworICB9CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSB0b3RhbF9zaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKKyAgcmV0dXJuIHRvdGFsX3NpemU7Cit9CisKK3ZvaWQgT25lb2ZEZXNjcmlwdG9yUHJvdG86Ok1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgY29uc3QgT25lb2ZEZXNjcmlwdG9yUHJvdG8qIHNvdXJjZSA9IAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RHluYW1pY0Nhc3RUb0dlbmVyYXRlZDxjb25zdCBPbmVvZkRlc2NyaXB0b3JQcm90bz4oCisgICAgICAgICAgJmZyb20pOworICBpZiAoc291cmNlID09IE5VTEwpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpSZWZsZWN0aW9uT3BzOjpNZXJnZShmcm9tLCB0aGlzKTsKKyAgfSBlbHNlIHsKKyAgICBNZXJnZUZyb20oKnNvdXJjZSk7CisgIH0KK30KKwordm9pZCBPbmVvZkRlc2NyaXB0b3JQcm90bzo6TWVyZ2VGcm9tKGNvbnN0IE9uZW9mRGVzY3JpcHRvclByb3RvJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGlmIChmcm9tLl9oYXNfYml0c19bMCAvIDMyXSAmICgweGZmdSA8PCAoMCAlIDMyKSkpIHsKKyAgICBpZiAoZnJvbS5oYXNfbmFtZSgpKSB7CisgICAgICBzZXRfaGFzX25hbWUoKTsKKyAgICAgIG5hbWVfLkFzc2lnbldpdGhEZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgZnJvbS5uYW1lXyk7CisgICAgfQorICB9CisgIGlmIChmcm9tLl9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5NZXJnZUZyb20oZnJvbS51bmtub3duX2ZpZWxkcygpKTsKKyAgfQorfQorCit2b2lkIE9uZW9mRGVzY3JpcHRvclByb3RvOjpDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCit2b2lkIE9uZW9mRGVzY3JpcHRvclByb3RvOjpDb3B5RnJvbShjb25zdCBPbmVvZkRlc2NyaXB0b3JQcm90byYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK2Jvb2wgT25lb2ZEZXNjcmlwdG9yUHJvdG86OklzSW5pdGlhbGl6ZWQoKSBjb25zdCB7CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgT25lb2ZEZXNjcmlwdG9yUHJvdG86OlN3YXAoT25lb2ZEZXNjcmlwdG9yUHJvdG8qIG90aGVyKSB7CisgIGlmIChvdGhlciA9PSB0aGlzKSByZXR1cm47CisgIEludGVybmFsU3dhcChvdGhlcik7Cit9Cit2b2lkIE9uZW9mRGVzY3JpcHRvclByb3RvOjpJbnRlcm5hbFN3YXAoT25lb2ZEZXNjcmlwdG9yUHJvdG8qIG90aGVyKSB7CisgIG5hbWVfLlN3YXAoJm90aGVyLT5uYW1lXyk7CisgIHN0ZDo6c3dhcChfaGFzX2JpdHNfWzBdLCBvdGhlci0+X2hhc19iaXRzX1swXSk7CisgIF9pbnRlcm5hbF9tZXRhZGF0YV8uU3dhcCgmb3RoZXItPl9pbnRlcm5hbF9tZXRhZGF0YV8pOworICBzdGQ6OnN3YXAoX2NhY2hlZF9zaXplXywgb3RoZXItPl9jYWNoZWRfc2l6ZV8pOworfQorCis6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIE9uZW9mRGVzY3JpcHRvclByb3RvOjpHZXRNZXRhZGF0YSgpIGNvbnN0IHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgbWV0YWRhdGE7CisgIG1ldGFkYXRhLmRlc2NyaXB0b3IgPSBPbmVvZkRlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXzsKKyAgbWV0YWRhdGEucmVmbGVjdGlvbiA9IE9uZW9mRGVzY3JpcHRvclByb3RvX3JlZmxlY3Rpb25fOworICByZXR1cm4gbWV0YWRhdGE7Cit9CisKKyNpZiBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKy8vIE9uZW9mRGVzY3JpcHRvclByb3RvCisKKy8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKK2Jvb2wgT25lb2ZEZXNjcmlwdG9yUHJvdG86Omhhc19uYW1lKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAxdSkgIT0gMDsKK30KK3ZvaWQgT25lb2ZEZXNjcmlwdG9yUHJvdG86OnNldF9oYXNfbmFtZSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAxdTsKK30KK3ZvaWQgT25lb2ZEZXNjcmlwdG9yUHJvdG86OmNsZWFyX2hhc19uYW1lKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAxdTsKK30KK3ZvaWQgT25lb2ZEZXNjcmlwdG9yUHJvdG86OmNsZWFyX25hbWUoKSB7CisgIG5hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX25hbWUoKTsKK30KKyBjb25zdCA6OnN0ZDo6c3RyaW5nJiBPbmVvZkRlc2NyaXB0b3JQcm90bzo6bmFtZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuT25lb2ZEZXNjcmlwdG9yUHJvdG8ubmFtZSkKKyAgcmV0dXJuIG5hbWVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIE9uZW9mRGVzY3JpcHRvclByb3RvOjpzZXRfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuT25lb2ZEZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KKyB2b2lkIE9uZW9mRGVzY3JpcHRvclByb3RvOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5PbmVvZkRlc2NyaXB0b3JQcm90by5uYW1lKQorfQorIHZvaWQgT25lb2ZEZXNjcmlwdG9yUHJvdG86OnNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLk9uZW9mRGVzY3JpcHRvclByb3RvLm5hbWUpCit9CisgOjpzdGQ6OnN0cmluZyogT25lb2ZEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfbmFtZSgpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5PbmVvZkRlc2NyaXB0b3JQcm90by5uYW1lKQorICByZXR1cm4gbmFtZV8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyA6OnN0ZDo6c3RyaW5nKiBPbmVvZkRlc2NyaXB0b3JQcm90bzo6cmVsZWFzZV9uYW1lKCkgeworICBjbGVhcl9oYXNfbmFtZSgpOworICByZXR1cm4gbmFtZV8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIE9uZW9mRGVzY3JpcHRvclByb3RvOjpzZXRfYWxsb2NhdGVkX25hbWUoOjpzdGQ6OnN0cmluZyogbmFtZSkgeworICBpZiAobmFtZSAhPSBOVUxMKSB7CisgICAgc2V0X2hhc19uYW1lKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX25hbWUoKTsKKyAgfQorICBuYW1lXy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgbmFtZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5PbmVvZkRlc2NyaXB0b3JQcm90by5uYW1lKQorfQorCisjZW5kaWYgIC8vIFBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKyNpZiAhZGVmaW5lZChfTVNDX1ZFUikgfHwgX01TQ19WRVIgPj0gMTkwMAorY29uc3QgaW50IEVudW1EZXNjcmlwdG9yUHJvdG86OmtOYW1lRmllbGROdW1iZXI7Citjb25zdCBpbnQgRW51bURlc2NyaXB0b3JQcm90bzo6a1ZhbHVlRmllbGROdW1iZXI7Citjb25zdCBpbnQgRW51bURlc2NyaXB0b3JQcm90bzo6a09wdGlvbnNGaWVsZE51bWJlcjsKKyNlbmRpZiAgLy8gIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKKworRW51bURlc2NyaXB0b3JQcm90bzo6RW51bURlc2NyaXB0b3JQcm90bygpCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgeworICBTaGFyZWRDdG9yKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuRW51bURlc2NyaXB0b3JQcm90bykKK30KKwordm9pZCBFbnVtRGVzY3JpcHRvclByb3RvOjpJbml0QXNEZWZhdWx0SW5zdGFuY2UoKSB7CisgIG9wdGlvbnNfID0gY29uc3RfY2FzdDwgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtT3B0aW9ucyo+KCY6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1PcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlKCkpOworfQorCitFbnVtRGVzY3JpcHRvclByb3RvOjpFbnVtRGVzY3JpcHRvclByb3RvKGNvbnN0IEVudW1EZXNjcmlwdG9yUHJvdG8mIGZyb20pCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksCisgICAgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29weV9jb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuRW51bURlc2NyaXB0b3JQcm90bykKK30KKwordm9pZCBFbnVtRGVzY3JpcHRvclByb3RvOjpTaGFyZWRDdG9yKCkgeworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZygpOworICBfY2FjaGVkX3NpemVfID0gMDsKKyAgbmFtZV8uVW5zYWZlU2V0RGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBvcHRpb25zXyA9IE5VTEw7CisgIDo6bWVtc2V0KF9oYXNfYml0c18sIDAsIHNpemVvZihfaGFzX2JpdHNfKSk7Cit9CisKK0VudW1EZXNjcmlwdG9yUHJvdG86On5FbnVtRGVzY3JpcHRvclByb3RvKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZGVzdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuRW51bURlc2NyaXB0b3JQcm90bykKKyAgU2hhcmVkRHRvcigpOworfQorCit2b2lkIEVudW1EZXNjcmlwdG9yUHJvdG86OlNoYXJlZER0b3IoKSB7CisgIG5hbWVfLkRlc3Ryb3lOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGlmICh0aGlzICE9IGRlZmF1bHRfaW5zdGFuY2VfKSB7CisgICAgZGVsZXRlIG9wdGlvbnNfOworICB9Cit9CisKK3ZvaWQgRW51bURlc2NyaXB0b3JQcm90bzo6U2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3QgeworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIEVudW1EZXNjcmlwdG9yUHJvdG86OmRlc2NyaXB0b3IoKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICByZXR1cm4gRW51bURlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXzsKK30KKworY29uc3QgRW51bURlc2NyaXB0b3JQcm90byYgRW51bURlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZSgpIHsKKyAgaWYgKGRlZmF1bHRfaW5zdGFuY2VfID09IE5VTEwpIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgcmV0dXJuICpkZWZhdWx0X2luc3RhbmNlXzsKK30KKworRW51bURlc2NyaXB0b3JQcm90byogRW51bURlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBOVUxMOworCitFbnVtRGVzY3JpcHRvclByb3RvKiBFbnVtRGVzY3JpcHRvclByb3RvOjpOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0IHsKKyAgRW51bURlc2NyaXB0b3JQcm90byogbiA9IG5ldyBFbnVtRGVzY3JpcHRvclByb3RvOworICBpZiAoYXJlbmEgIT0gTlVMTCkgeworICAgIGFyZW5hLT5Pd24obik7CisgIH0KKyAgcmV0dXJuIG47Cit9CisKK3ZvaWQgRW51bURlc2NyaXB0b3JQcm90bzo6Q2xlYXIoKSB7CisgIGlmIChfaGFzX2JpdHNfWzAgLyAzMl0gJiA1dSkgeworICAgIGlmIChoYXNfbmFtZSgpKSB7CisgICAgICBuYW1lXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgICAgfQorICAgIGlmIChoYXNfb3B0aW9ucygpKSB7CisgICAgICBpZiAob3B0aW9uc18gIT0gTlVMTCkgb3B0aW9uc18tPjo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bU9wdGlvbnM6OkNsZWFyKCk7CisgICAgfQorICB9CisgIHZhbHVlXy5DbGVhcigpOworICA6Om1lbXNldChfaGFzX2JpdHNfLCAwLCBzaXplb2YoX2hhc19iaXRzXykpOworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkNsZWFyKCk7CisgIH0KK30KKworYm9vbCBFbnVtRGVzY3JpcHRvclByb3RvOjpNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyNkZWZpbmUgRE9fKEVYUFJFU1NJT04pIGlmICghKEVYUFJFU1NJT04pKSBnb3RvIGZhaWx1cmUKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgdGFnOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8pCisgIGZvciAoOzspIHsKKyAgICA6OnN0ZDo6cGFpcjwgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIsIGJvb2w+IHAgPSBpbnB1dC0+UmVhZFRhZ1dpdGhDdXRvZmYoMTI3KTsKKyAgICB0YWcgPSBwLmZpcnN0OworICAgIGlmICghcC5zZWNvbmQpIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgc3dpdGNoICg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnRmllbGROdW1iZXIodGFnKSkgeworICAgICAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICAgICAgY2FzZSAxOiB7CisgICAgICAgIGlmICh0YWcgPT0gMTApIHsKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoCisgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPm11dGFibGVfbmFtZSgpKSk7CisgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICAgICAgICB0aGlzLT5uYW1lKCkuZGF0YSgpLCB0aGlzLT5uYW1lKCkubGVuZ3RoKCksCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpQQVJTRSwKKyAgICAgICAgICAgICJnb29nbGUucHJvdG9idWYuRW51bURlc2NyaXB0b3JQcm90by5uYW1lIik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygxOCkpIGdvdG8gcGFyc2VfdmFsdWU7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZURlc2NyaXB0b3JQcm90byB2YWx1ZSA9IDI7CisgICAgICBjYXNlIDI6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAxOCkgeworICAgICAgICAgcGFyc2VfdmFsdWU6CisgICAgICAgICAgRE9fKGlucHV0LT5JbmNyZW1lbnRSZWN1cnNpb25EZXB0aCgpKTsKKyAgICAgICAgIHBhcnNlX2xvb3BfdmFsdWU6CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkTWVzc2FnZU5vVmlydHVhbE5vUmVjdXJzaW9uRGVwdGgoCisgICAgICAgICAgICAgICAgaW5wdXQsIGFkZF92YWx1ZSgpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygxOCkpIGdvdG8gcGFyc2VfbG9vcF92YWx1ZTsKKyAgICAgICAgaW5wdXQtPlVuc2FmZURlY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCk7CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDI2KSkgZ290byBwYXJzZV9vcHRpb25zOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucyBvcHRpb25zID0gMzsKKyAgICAgIGNhc2UgMzogeworICAgICAgICBpZiAodGFnID09IDI2KSB7CisgICAgICAgICBwYXJzZV9vcHRpb25zOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZE1lc3NhZ2VOb1ZpcnR1YWwoCisgICAgICAgICAgICAgICBpbnB1dCwgbXV0YWJsZV9vcHRpb25zKCkpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0QXRFbmQoKSkgZ290byBzdWNjZXNzOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgZGVmYXVsdDogeworICAgICAgaGFuZGxlX3VudXN1YWw6CisgICAgICAgIGlmICh0YWcgPT0gMCB8fAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ1dpcmVUeXBlKHRhZykgPT0KKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVApIHsKKyAgICAgICAgICBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIH0KKyAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNraXBGaWVsZCgKKyAgICAgICAgICAgICAgaW5wdXQsIHRhZywgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpKSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgfQorc3VjY2VzczoKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N1Y2Nlc3M6Z29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8pCisgIHJldHVybiB0cnVlOworZmFpbHVyZToKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX2ZhaWx1cmU6Z29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8pCisgIHJldHVybiBmYWxzZTsKKyN1bmRlZiBET18KK30KKwordm9pZCBFbnVtRGVzY3JpcHRvclByb3RvOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvKQorICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgIGlmIChoYXNfbmFtZSgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5uYW1lKCkuZGF0YSgpLCB0aGlzLT5uYW1lKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8ubmFtZSIpOworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ01heWJlQWxpYXNlZCgKKyAgICAgIDEsIHRoaXMtPm5hbWUoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRW51bVZhbHVlRGVzY3JpcHRvclByb3RvIHZhbHVlID0gMjsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT52YWx1ZV9zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgMiwgdGhpcy0+dmFsdWUoaSksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zIG9wdGlvbnMgPSAzOworICBpZiAoaGFzX29wdGlvbnMoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZU1lc3NhZ2VNYXliZVRvQXJyYXkoCisgICAgICAzLCAqdGhpcy0+b3B0aW9uc18sIG91dHB1dCk7CisgIH0KKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTZXJpYWxpemVVbmtub3duRmllbGRzKAorICAgICAgICB1bmtub3duX2ZpZWxkcygpLCBvdXRwdXQpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfZW5kOmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvKQorfQorCis6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBFbnVtRGVzY3JpcHRvclByb3RvOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIHRhcmdldCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvKQorICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgIGlmIChoYXNfbmFtZSgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5uYW1lKCkuZGF0YSgpLCB0aGlzLT5uYW1lKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8ubmFtZSIpOworICAgIHRhcmdldCA9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdUb0FycmF5KAorICAgICAgICAxLCB0aGlzLT5uYW1lKCksIHRhcmdldCk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZURlc2NyaXB0b3JQcm90byB2YWx1ZSA9IDI7CisgIGZvciAodW5zaWduZWQgaW50IGkgPSAwLCBuID0gdGhpcy0+dmFsdWVfc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OgorICAgICAgV3JpdGVNZXNzYWdlTm9WaXJ0dWFsVG9BcnJheSgKKyAgICAgICAgMiwgdGhpcy0+dmFsdWUoaSksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zIG9wdGlvbnMgPSAzOworICBpZiAoaGFzX29wdGlvbnMoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjoKKyAgICAgIFdyaXRlTWVzc2FnZU5vVmlydHVhbFRvQXJyYXkoCisgICAgICAgIDMsICp0aGlzLT5vcHRpb25zXywgdGFyZ2V0KTsKKyAgfQorCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25GaWVsZHNUb0FycmF5KAorICAgICAgICB1bmtub3duX2ZpZWxkcygpLCB0YXJnZXQpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfZW5kOmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvKQorICByZXR1cm4gdGFyZ2V0OworfQorCitpbnQgRW51bURlc2NyaXB0b3JQcm90bzo6Qnl0ZVNpemUoKSBjb25zdCB7CisgIGludCB0b3RhbF9zaXplID0gMDsKKworICBpZiAoX2hhc19iaXRzX1swIC8gMzJdICYgNXUpIHsKKyAgICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgICAgaWYgKGhhc19uYW1lKCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTdHJpbmdTaXplKAorICAgICAgICAgIHRoaXMtPm5hbWUoKSk7CisgICAgfQorCisgICAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucyBvcHRpb25zID0gMzsKKyAgICBpZiAoaGFzX29wdGlvbnMoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1lc3NhZ2VTaXplTm9WaXJ0dWFsKAorICAgICAgICAgICp0aGlzLT5vcHRpb25zXyk7CisgICAgfQorCisgIH0KKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8gdmFsdWUgPSAyOworICB0b3RhbF9zaXplICs9IDEgKiB0aGlzLT52YWx1ZV9zaXplKCk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+dmFsdWVfc2l6ZSgpOyBpKyspIHsKKyAgICB0b3RhbF9zaXplICs9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6TWVzc2FnZVNpemVOb1ZpcnR1YWwoCisgICAgICAgIHRoaXMtPnZhbHVlKGkpKTsKKyAgfQorCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHRvdGFsX3NpemUgKz0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OkNvbXB1dGVVbmtub3duRmllbGRzU2l6ZSgKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSk7CisgIH0KKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHRvdGFsX3NpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworICByZXR1cm4gdG90YWxfc2l6ZTsKK30KKwordm9pZCBFbnVtRGVzY3JpcHRvclByb3RvOjpNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGNvbnN0IEVudW1EZXNjcmlwdG9yUHJvdG8qIHNvdXJjZSA9IAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RHluYW1pY0Nhc3RUb0dlbmVyYXRlZDxjb25zdCBFbnVtRGVzY3JpcHRvclByb3RvPigKKyAgICAgICAgICAmZnJvbSk7CisgIGlmIChzb3VyY2UgPT0gTlVMTCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlJlZmxlY3Rpb25PcHM6Ok1lcmdlKGZyb20sIHRoaXMpOworICB9IGVsc2UgeworICAgIE1lcmdlRnJvbSgqc291cmNlKTsKKyAgfQorfQorCit2b2lkIEVudW1EZXNjcmlwdG9yUHJvdG86Ok1lcmdlRnJvbShjb25zdCBFbnVtRGVzY3JpcHRvclByb3RvJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIHZhbHVlXy5NZXJnZUZyb20oZnJvbS52YWx1ZV8pOworICBpZiAoZnJvbS5faGFzX2JpdHNfWzAgLyAzMl0gJiAoMHhmZnUgPDwgKDAgJSAzMikpKSB7CisgICAgaWYgKGZyb20uaGFzX25hbWUoKSkgeworICAgICAgc2V0X2hhc19uYW1lKCk7CisgICAgICBuYW1lXy5Bc3NpZ25XaXRoRGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGZyb20ubmFtZV8pOworICAgIH0KKyAgICBpZiAoZnJvbS5oYXNfb3B0aW9ucygpKSB7CisgICAgICBtdXRhYmxlX29wdGlvbnMoKS0+Ojpnb29nbGU6OnByb3RvYnVmOjpFbnVtT3B0aW9uczo6TWVyZ2VGcm9tKGZyb20ub3B0aW9ucygpKTsKKyAgICB9CisgIH0KKyAgaWYgKGZyb20uX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPk1lcmdlRnJvbShmcm9tLnVua25vd25fZmllbGRzKCkpOworICB9Cit9CisKK3ZvaWQgRW51bURlc2NyaXB0b3JQcm90bzo6Q29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKwordm9pZCBFbnVtRGVzY3JpcHRvclByb3RvOjpDb3B5RnJvbShjb25zdCBFbnVtRGVzY3JpcHRvclByb3RvJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKworYm9vbCBFbnVtRGVzY3JpcHRvclByb3RvOjpJc0luaXRpYWxpemVkKCkgY29uc3QgeworCisgIGlmICghOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QWxsQXJlSW5pdGlhbGl6ZWQodGhpcy0+dmFsdWUoKSkpIHJldHVybiBmYWxzZTsKKyAgaWYgKGhhc19vcHRpb25zKCkpIHsKKyAgICBpZiAoIXRoaXMtPm9wdGlvbnNfLT5Jc0luaXRpYWxpemVkKCkpIHJldHVybiBmYWxzZTsKKyAgfQorICByZXR1cm4gdHJ1ZTsKK30KKwordm9pZCBFbnVtRGVzY3JpcHRvclByb3RvOjpTd2FwKEVudW1EZXNjcmlwdG9yUHJvdG8qIG90aGVyKSB7CisgIGlmIChvdGhlciA9PSB0aGlzKSByZXR1cm47CisgIEludGVybmFsU3dhcChvdGhlcik7Cit9Cit2b2lkIEVudW1EZXNjcmlwdG9yUHJvdG86OkludGVybmFsU3dhcChFbnVtRGVzY3JpcHRvclByb3RvKiBvdGhlcikgeworICBuYW1lXy5Td2FwKCZvdGhlci0+bmFtZV8pOworICB2YWx1ZV8uVW5zYWZlQXJlbmFTd2FwKCZvdGhlci0+dmFsdWVfKTsKKyAgc3RkOjpzd2FwKG9wdGlvbnNfLCBvdGhlci0+b3B0aW9uc18pOworICBzdGQ6OnN3YXAoX2hhc19iaXRzX1swXSwgb3RoZXItPl9oYXNfYml0c19bMF0pOworICBfaW50ZXJuYWxfbWV0YWRhdGFfLlN3YXAoJm90aGVyLT5faW50ZXJuYWxfbWV0YWRhdGFfKTsKKyAgc3RkOjpzd2FwKF9jYWNoZWRfc2l6ZV8sIG90aGVyLT5fY2FjaGVkX3NpemVfKTsKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBFbnVtRGVzY3JpcHRvclByb3RvOjpHZXRNZXRhZGF0YSgpIGNvbnN0IHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgbWV0YWRhdGE7CisgIG1ldGFkYXRhLmRlc2NyaXB0b3IgPSBFbnVtRGVzY3JpcHRvclByb3RvX2Rlc2NyaXB0b3JfOworICBtZXRhZGF0YS5yZWZsZWN0aW9uID0gRW51bURlc2NyaXB0b3JQcm90b19yZWZsZWN0aW9uXzsKKyAgcmV0dXJuIG1ldGFkYXRhOworfQorCisjaWYgUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisvLyBFbnVtRGVzY3JpcHRvclByb3RvCisKKy8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKK2Jvb2wgRW51bURlc2NyaXB0b3JQcm90bzo6aGFzX25hbWUoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDF1KSAhPSAwOworfQordm9pZCBFbnVtRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX25hbWUoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMXU7Cit9Cit2b2lkIEVudW1EZXNjcmlwdG9yUHJvdG86OmNsZWFyX2hhc19uYW1lKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAxdTsKK30KK3ZvaWQgRW51bURlc2NyaXB0b3JQcm90bzo6Y2xlYXJfbmFtZSgpIHsKKyAgbmFtZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfbmFtZSgpOworfQorIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEVudW1EZXNjcmlwdG9yUHJvdG86Om5hbWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8ubmFtZSkKKyAgcmV0dXJuIG5hbWVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIEVudW1EZXNjcmlwdG9yUHJvdG86OnNldF9uYW1lKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfbmFtZSgpOworICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvLm5hbWUpCit9Cisgdm9pZCBFbnVtRGVzY3JpcHRvclByb3RvOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvLm5hbWUpCit9Cisgdm9pZCBFbnVtRGVzY3JpcHRvclByb3RvOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvLm5hbWUpCit9CisgOjpzdGQ6OnN0cmluZyogRW51bURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9uYW1lKCkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8ubmFtZSkKKyAgcmV0dXJuIG5hbWVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CisgOjpzdGQ6OnN0cmluZyogRW51bURlc2NyaXB0b3JQcm90bzo6cmVsZWFzZV9uYW1lKCkgeworICBjbGVhcl9oYXNfbmFtZSgpOworICByZXR1cm4gbmFtZV8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIEVudW1EZXNjcmlwdG9yUHJvdG86OnNldF9hbGxvY2F0ZWRfbmFtZSg6OnN0ZDo6c3RyaW5nKiBuYW1lKSB7CisgIGlmIChuYW1lICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX25hbWUoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfbmFtZSgpOworICB9CisgIG5hbWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBuYW1lKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8gdmFsdWUgPSAyOworaW50IEVudW1EZXNjcmlwdG9yUHJvdG86OnZhbHVlX3NpemUoKSBjb25zdCB7CisgIHJldHVybiB2YWx1ZV8uc2l6ZSgpOworfQordm9pZCBFbnVtRGVzY3JpcHRvclByb3RvOjpjbGVhcl92YWx1ZSgpIHsKKyAgdmFsdWVfLkNsZWFyKCk7Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZURlc2NyaXB0b3JQcm90byYgRW51bURlc2NyaXB0b3JQcm90bzo6dmFsdWUoaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8udmFsdWUpCisgIHJldHVybiB2YWx1ZV8uR2V0KGluZGV4KTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlRGVzY3JpcHRvclByb3RvKiBFbnVtRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX3ZhbHVlKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRW51bURlc2NyaXB0b3JQcm90by52YWx1ZSkKKyAgcmV0dXJuIHZhbHVlXy5NdXRhYmxlKGluZGV4KTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlRGVzY3JpcHRvclByb3RvKiBFbnVtRGVzY3JpcHRvclByb3RvOjphZGRfdmFsdWUoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8udmFsdWUpCisgIHJldHVybiB2YWx1ZV8uQWRkKCk7Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlRGVzY3JpcHRvclByb3RvID4qCitFbnVtRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX3ZhbHVlKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvLnZhbHVlKQorICByZXR1cm4gJnZhbHVlXzsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8gPiYKK0VudW1EZXNjcmlwdG9yUHJvdG86OnZhbHVlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuRW51bURlc2NyaXB0b3JQcm90by52YWx1ZSkKKyAgcmV0dXJuIHZhbHVlXzsKK30KKworLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucyBvcHRpb25zID0gMzsKK2Jvb2wgRW51bURlc2NyaXB0b3JQcm90bzo6aGFzX29wdGlvbnMoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDR1KSAhPSAwOworfQordm9pZCBFbnVtRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX29wdGlvbnMoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwNHU7Cit9Cit2b2lkIEVudW1EZXNjcmlwdG9yUHJvdG86OmNsZWFyX2hhc19vcHRpb25zKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDA0dTsKK30KK3ZvaWQgRW51bURlc2NyaXB0b3JQcm90bzo6Y2xlYXJfb3B0aW9ucygpIHsKKyAgaWYgKG9wdGlvbnNfICE9IE5VTEwpIG9wdGlvbnNfLT46Omdvb2dsZTo6cHJvdG9idWY6OkVudW1PcHRpb25zOjpDbGVhcigpOworICBjbGVhcl9oYXNfb3B0aW9ucygpOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtT3B0aW9ucyYgRW51bURlc2NyaXB0b3JQcm90bzo6b3B0aW9ucygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRW51bURlc2NyaXB0b3JQcm90by5vcHRpb25zKQorICByZXR1cm4gb3B0aW9uc18gIT0gTlVMTCA/ICpvcHRpb25zXyA6ICpkZWZhdWx0X2luc3RhbmNlXy0+b3B0aW9uc187Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1PcHRpb25zKiBFbnVtRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX29wdGlvbnMoKSB7CisgIHNldF9oYXNfb3B0aW9ucygpOworICBpZiAob3B0aW9uc18gPT0gTlVMTCkgeworICAgIG9wdGlvbnNfID0gbmV3IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bU9wdGlvbnM7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8ub3B0aW9ucykKKyAgcmV0dXJuIG9wdGlvbnNfOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtT3B0aW9ucyogRW51bURlc2NyaXB0b3JQcm90bzo6cmVsZWFzZV9vcHRpb25zKCkgeworICBjbGVhcl9oYXNfb3B0aW9ucygpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1PcHRpb25zKiB0ZW1wID0gb3B0aW9uc187CisgIG9wdGlvbnNfID0gTlVMTDsKKyAgcmV0dXJuIHRlbXA7Cit9Cit2b2lkIEVudW1EZXNjcmlwdG9yUHJvdG86OnNldF9hbGxvY2F0ZWRfb3B0aW9ucyg6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1PcHRpb25zKiBvcHRpb25zKSB7CisgIGRlbGV0ZSBvcHRpb25zXzsKKyAgb3B0aW9uc18gPSBvcHRpb25zOworICBpZiAob3B0aW9ucykgeworICAgIHNldF9oYXNfb3B0aW9ucygpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19vcHRpb25zKCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8ub3B0aW9ucykKK30KKworI2VuZGlmICAvLyBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisjaWYgIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKK2NvbnN0IGludCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86OmtOYW1lRmllbGROdW1iZXI7Citjb25zdCBpbnQgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjprTnVtYmVyRmllbGROdW1iZXI7Citjb25zdCBpbnQgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjprT3B0aW9uc0ZpZWxkTnVtYmVyOworI2VuZGlmICAvLyAhZGVmaW5lZChfTVNDX1ZFUikgfHwgX01TQ19WRVIgPj0gMTkwMAorCitFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86OkVudW1WYWx1ZURlc2NyaXB0b3JQcm90bygpCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgeworICBTaGFyZWRDdG9yKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlRGVzY3JpcHRvclByb3RvKQorfQorCit2b2lkIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6SW5pdEFzRGVmYXVsdEluc3RhbmNlKCkgeworICBvcHRpb25zXyA9IGNvbnN0X2Nhc3Q8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlT3B0aW9ucyo+KCY6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2UoKSk7Cit9CisKK0VudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6RW51bVZhbHVlRGVzY3JpcHRvclByb3RvKGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3JQcm90byYgZnJvbSkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwKKyAgICBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICBNZXJnZUZyb20oZnJvbSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb3B5X2NvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8pCit9CisKK3ZvaWQgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpTaGFyZWRDdG9yKCkgeworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZygpOworICBfY2FjaGVkX3NpemVfID0gMDsKKyAgbmFtZV8uVW5zYWZlU2V0RGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBudW1iZXJfID0gMDsKKyAgb3B0aW9uc18gPSBOVUxMOworICA6Om1lbXNldChfaGFzX2JpdHNfLCAwLCBzaXplb2YoX2hhc19iaXRzXykpOworfQorCitFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86On5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChkZXN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8pCisgIFNoYXJlZER0b3IoKTsKK30KKwordm9pZCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86OlNoYXJlZER0b3IoKSB7CisgIG5hbWVfLkRlc3Ryb3lOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGlmICh0aGlzICE9IGRlZmF1bHRfaW5zdGFuY2VfKSB7CisgICAgZGVsZXRlIG9wdGlvbnNfOworICB9Cit9CisKK3ZvaWQgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdCB7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSBzaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpkZXNjcmlwdG9yKCkgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgcmV0dXJuIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXzsKK30KKworY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvJiBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86OmRlZmF1bHRfaW5zdGFuY2UoKSB7CisgIGlmIChkZWZhdWx0X2luc3RhbmNlXyA9PSBOVUxMKSBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIHJldHVybiAqZGVmYXVsdF9pbnN0YW5jZV87Cit9CisKK0VudW1WYWx1ZURlc2NyaXB0b3JQcm90byogRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlXyA9IE5VTEw7CisKK0VudW1WYWx1ZURlc2NyaXB0b3JQcm90byogRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0IHsKKyAgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvKiBuID0gbmV3IEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzsKKyAgaWYgKGFyZW5hICE9IE5VTEwpIHsKKyAgICBhcmVuYS0+T3duKG4pOworICB9CisgIHJldHVybiBuOworfQorCit2b2lkIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6Q2xlYXIoKSB7CisgIGlmIChfaGFzX2JpdHNfWzAgLyAzMl0gJiA3dSkgeworICAgIGlmIChoYXNfbmFtZSgpKSB7CisgICAgICBuYW1lXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgICAgfQorICAgIG51bWJlcl8gPSAwOworICAgIGlmIChoYXNfb3B0aW9ucygpKSB7CisgICAgICBpZiAob3B0aW9uc18gIT0gTlVMTCkgb3B0aW9uc18tPjo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlT3B0aW9uczo6Q2xlYXIoKTsKKyAgICB9CisgIH0KKyAgOjptZW1zZXQoX2hhc19iaXRzXywgMCwgc2l6ZW9mKF9oYXNfYml0c18pKTsKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5DbGVhcigpOworICB9Cit9CisKK2Jvb2wgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyNkZWZpbmUgRE9fKEVYUFJFU1NJT04pIGlmICghKEVYUFJFU1NJT04pKSBnb3RvIGZhaWx1cmUKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgdGFnOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZURlc2NyaXB0b3JQcm90bykKKyAgZm9yICg7OykgeworICAgIDo6c3RkOjpwYWlyPCA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiwgYm9vbD4gcCA9IGlucHV0LT5SZWFkVGFnV2l0aEN1dG9mZigxMjcpOworICAgIHRhZyA9IHAuZmlyc3Q7CisgICAgaWYgKCFwLnNlY29uZCkgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICBzd2l0Y2ggKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdGaWVsZE51bWJlcih0YWcpKSB7CisgICAgICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgICAgICBjYXNlIDE6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAxMCkgeworICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFN0cmluZygKKyAgICAgICAgICAgICAgICBpbnB1dCwgdGhpcy0+bXV0YWJsZV9uYW1lKCkpKTsKKyAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgICAgICAgIHRoaXMtPm5hbWUoKS5kYXRhKCksIHRoaXMtPm5hbWUoKS5sZW5ndGgoKSwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlBBUlNFLAorICAgICAgICAgICAgImdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8ubmFtZSIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMTYpKSBnb3RvIHBhcnNlX251bWJlcjsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIGludDMyIG51bWJlciA9IDI7CisgICAgICBjYXNlIDI6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAxNikgeworICAgICAgICAgcGFyc2VfbnVtYmVyOgorICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfSU5UMzI+KAorICAgICAgICAgICAgICAgICBpbnB1dCwgJm51bWJlcl8pKSk7CisgICAgICAgICAgc2V0X2hhc19udW1iZXIoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDI2KSkgZ290byBwYXJzZV9vcHRpb25zOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVPcHRpb25zIG9wdGlvbnMgPSAzOworICAgICAgY2FzZSAzOiB7CisgICAgICAgIGlmICh0YWcgPT0gMjYpIHsKKyAgICAgICAgIHBhcnNlX29wdGlvbnM6CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkTWVzc2FnZU5vVmlydHVhbCgKKyAgICAgICAgICAgICAgIGlucHV0LCBtdXRhYmxlX29wdGlvbnMoKSkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RBdEVuZCgpKSBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBkZWZhdWx0OiB7CisgICAgICBoYW5kbGVfdW51c3VhbDoKKyAgICAgICAgaWYgKHRhZyA9PSAwIHx8CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnV2lyZVR5cGUodGFnKSA9PQorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0VORF9HUk9VUCkgeworICAgICAgICAgIGdvdG8gc3VjY2VzczsKKyAgICAgICAgfQorICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2tpcEZpZWxkKAorICAgICAgICAgICAgICBpbnB1dCwgdGFnLCBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CitzdWNjZXNzOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3VjY2Vzczpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlRGVzY3JpcHRvclByb3RvKQorICByZXR1cm4gdHJ1ZTsKK2ZhaWx1cmU6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9mYWlsdXJlOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8pCisgIHJldHVybiBmYWxzZTsKKyN1bmRlZiBET18KK30KKwordm9pZCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZURlc2NyaXB0b3JQcm90bykKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICBpZiAoaGFzX25hbWUoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+bmFtZSgpLmRhdGEoKSwgdGhpcy0+bmFtZSgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8ubmFtZSIpOworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ01heWJlQWxpYXNlZCgKKyAgICAgIDEsIHRoaXMtPm5hbWUoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGludDMyIG51bWJlciA9IDI7CisgIGlmIChoYXNfbnVtYmVyKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVJbnQzMigyLCB0aGlzLT5udW1iZXIoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRW51bVZhbHVlT3B0aW9ucyBvcHRpb25zID0gMzsKKyAgaWYgKGhhc19vcHRpb25zKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgMywgKnRoaXMtPm9wdGlvbnNfLCBvdXRwdXQpOworICB9CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bkZpZWxkcygKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSwgb3V0cHV0KTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX2VuZDpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlRGVzY3JpcHRvclByb3RvKQorfQorCis6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogdGFyZ2V0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZURlc2NyaXB0b3JQcm90bykKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICBpZiAoaGFzX25hbWUoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+bmFtZSgpLmRhdGEoKSwgdGhpcy0+bmFtZSgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8ubmFtZSIpOworICAgIHRhcmdldCA9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdUb0FycmF5KAorICAgICAgICAxLCB0aGlzLT5uYW1lKCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBpbnQzMiBudW1iZXIgPSAyOworICBpZiAoaGFzX251bWJlcigpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlSW50MzJUb0FycmF5KDIsIHRoaXMtPm51bWJlcigpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVPcHRpb25zIG9wdGlvbnMgPSAzOworICBpZiAoaGFzX29wdGlvbnMoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjoKKyAgICAgIFdyaXRlTWVzc2FnZU5vVmlydHVhbFRvQXJyYXkoCisgICAgICAgIDMsICp0aGlzLT5vcHRpb25zXywgdGFyZ2V0KTsKKyAgfQorCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25GaWVsZHNUb0FycmF5KAorICAgICAgICB1bmtub3duX2ZpZWxkcygpLCB0YXJnZXQpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfZW5kOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8pCisgIHJldHVybiB0YXJnZXQ7Cit9CisKK2ludCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86OkJ5dGVTaXplKCkgY29uc3QgeworICBpbnQgdG90YWxfc2l6ZSA9IDA7CisKKyAgaWYgKF9oYXNfYml0c19bMCAvIDMyXSAmIDd1KSB7CisgICAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICAgIGlmIChoYXNfbmFtZSgpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U3RyaW5nU2l6ZSgKKyAgICAgICAgICB0aGlzLT5uYW1lKCkpOworICAgIH0KKworICAgIC8vIG9wdGlvbmFsIGludDMyIG51bWJlciA9IDI7CisgICAgaWYgKGhhc19udW1iZXIoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkludDMyU2l6ZSgKKyAgICAgICAgICB0aGlzLT5udW1iZXIoKSk7CisgICAgfQorCisgICAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVPcHRpb25zIG9wdGlvbnMgPSAzOworICAgIGlmIChoYXNfb3B0aW9ucygpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6TWVzc2FnZVNpemVOb1ZpcnR1YWwoCisgICAgICAgICAgKnRoaXMtPm9wdGlvbnNfKTsKKyAgICB9CisKKyAgfQorICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICB0b3RhbF9zaXplICs9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpDb21wdXRlVW5rbm93bkZpZWxkc1NpemUoCisgICAgICAgIHVua25vd25fZmllbGRzKCkpOworICB9CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSB0b3RhbF9zaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKKyAgcmV0dXJuIHRvdGFsX3NpemU7Cit9CisKK3ZvaWQgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3JQcm90byogc291cmNlID0gCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpEeW5hbWljQ2FzdFRvR2VuZXJhdGVkPGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bz4oCisgICAgICAgICAgJmZyb20pOworICBpZiAoc291cmNlID09IE5VTEwpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpSZWZsZWN0aW9uT3BzOjpNZXJnZShmcm9tLCB0aGlzKTsKKyAgfSBlbHNlIHsKKyAgICBNZXJnZUZyb20oKnNvdXJjZSk7CisgIH0KK30KKwordm9pZCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86Ok1lcmdlRnJvbShjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8mIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgaWYgKGZyb20uX2hhc19iaXRzX1swIC8gMzJdICYgKDB4ZmZ1IDw8ICgwICUgMzIpKSkgeworICAgIGlmIChmcm9tLmhhc19uYW1lKCkpIHsKKyAgICAgIHNldF9oYXNfbmFtZSgpOworICAgICAgbmFtZV8uQXNzaWduV2l0aERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBmcm9tLm5hbWVfKTsKKyAgICB9CisgICAgaWYgKGZyb20uaGFzX251bWJlcigpKSB7CisgICAgICBzZXRfbnVtYmVyKGZyb20ubnVtYmVyKCkpOworICAgIH0KKyAgICBpZiAoZnJvbS5oYXNfb3B0aW9ucygpKSB7CisgICAgICBtdXRhYmxlX29wdGlvbnMoKS0+Ojpnb29nbGU6OnByb3RvYnVmOjpFbnVtVmFsdWVPcHRpb25zOjpNZXJnZUZyb20oZnJvbS5vcHRpb25zKCkpOworICAgIH0KKyAgfQorICBpZiAoZnJvbS5faW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+TWVyZ2VGcm9tKGZyb20udW5rbm93bl9maWVsZHMoKSk7CisgIH0KK30KKwordm9pZCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86OkNvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK3ZvaWQgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpDb3B5RnJvbShjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8mIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCitib29sIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6SXNJbml0aWFsaXplZCgpIGNvbnN0IHsKKworICBpZiAoaGFzX29wdGlvbnMoKSkgeworICAgIGlmICghdGhpcy0+b3B0aW9uc18tPklzSW5pdGlhbGl6ZWQoKSkgcmV0dXJuIGZhbHNlOworICB9CisgIHJldHVybiB0cnVlOworfQorCit2b2lkIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6U3dhcChFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8qIG90aGVyKSB7CisgIGlmIChvdGhlciA9PSB0aGlzKSByZXR1cm47CisgIEludGVybmFsU3dhcChvdGhlcik7Cit9Cit2b2lkIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6SW50ZXJuYWxTd2FwKEVudW1WYWx1ZURlc2NyaXB0b3JQcm90byogb3RoZXIpIHsKKyAgbmFtZV8uU3dhcCgmb3RoZXItPm5hbWVfKTsKKyAgc3RkOjpzd2FwKG51bWJlcl8sIG90aGVyLT5udW1iZXJfKTsKKyAgc3RkOjpzd2FwKG9wdGlvbnNfLCBvdGhlci0+b3B0aW9uc18pOworICBzdGQ6OnN3YXAoX2hhc19iaXRzX1swXSwgb3RoZXItPl9oYXNfYml0c19bMF0pOworICBfaW50ZXJuYWxfbWV0YWRhdGFfLlN3YXAoJm90aGVyLT5faW50ZXJuYWxfbWV0YWRhdGFfKTsKKyAgc3RkOjpzd2FwKF9jYWNoZWRfc2l6ZV8sIG90aGVyLT5fY2FjaGVkX3NpemVfKTsKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86OkdldE1ldGFkYXRhKCkgY29uc3QgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBtZXRhZGF0YTsKKyAgbWV0YWRhdGEuZGVzY3JpcHRvciA9IEVudW1WYWx1ZURlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXzsKKyAgbWV0YWRhdGEucmVmbGVjdGlvbiA9IEVudW1WYWx1ZURlc2NyaXB0b3JQcm90b19yZWZsZWN0aW9uXzsKKyAgcmV0dXJuIG1ldGFkYXRhOworfQorCisjaWYgUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisvLyBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8KKworLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworYm9vbCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86Omhhc19uYW1lKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAxdSkgIT0gMDsKK30KK3ZvaWQgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX25hbWUoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMXU7Cit9Cit2b2lkIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX25hbWUoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDF1OworfQordm9pZCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86OmNsZWFyX25hbWUoKSB7CisgIG5hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX25hbWUoKTsKK30KKyBjb25zdCA6OnN0ZDo6c3RyaW5nJiBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86Om5hbWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZURlc2NyaXB0b3JQcm90by5uYW1lKQorICByZXR1cm4gbmFtZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpzZXRfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlRGVzY3JpcHRvclByb3RvLm5hbWUpCit9Cisgdm9pZCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86OnNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfbmFtZSgpOworICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZURlc2NyaXB0b3JQcm90by5uYW1lKQorfQorIHZvaWQgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KKyA6OnN0ZDo6c3RyaW5nKiBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfbmFtZSgpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8ubmFtZSkKKyAgcmV0dXJuIG5hbWVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CisgOjpzdGQ6OnN0cmluZyogRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX25hbWUoKSB7CisgIGNsZWFyX2hhc19uYW1lKCk7CisgIHJldHVybiBuYW1lXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpzZXRfYWxsb2NhdGVkX25hbWUoOjpzdGQ6OnN0cmluZyogbmFtZSkgeworICBpZiAobmFtZSAhPSBOVUxMKSB7CisgICAgc2V0X2hhc19uYW1lKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX25hbWUoKTsKKyAgfQorICBuYW1lXy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgbmFtZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KKworLy8gb3B0aW9uYWwgaW50MzIgbnVtYmVyID0gMjsKK2Jvb2wgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpoYXNfbnVtYmVyKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAydSkgIT0gMDsKK30KK3ZvaWQgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX251bWJlcigpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAydTsKK30KK3ZvaWQgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfbnVtYmVyKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAydTsKK30KK3ZvaWQgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9udW1iZXIoKSB7CisgIG51bWJlcl8gPSAwOworICBjbGVhcl9oYXNfbnVtYmVyKCk7Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86Om51bWJlcigpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlRGVzY3JpcHRvclByb3RvLm51bWJlcikKKyAgcmV0dXJuIG51bWJlcl87Cit9Cisgdm9pZCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86OnNldF9udW1iZXIoOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiB2YWx1ZSkgeworICBzZXRfaGFzX251bWJlcigpOworICBudW1iZXJfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZURlc2NyaXB0b3JQcm90by5udW1iZXIpCit9CisKKy8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRW51bVZhbHVlT3B0aW9ucyBvcHRpb25zID0gMzsKK2Jvb2wgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpoYXNfb3B0aW9ucygpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwNHUpICE9IDA7Cit9Cit2b2lkIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19vcHRpb25zKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDR1OworfQordm9pZCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86OmNsZWFyX2hhc19vcHRpb25zKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDA0dTsKK30KK3ZvaWQgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9vcHRpb25zKCkgeworICBpZiAob3B0aW9uc18gIT0gTlVMTCkgb3B0aW9uc18tPjo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlT3B0aW9uczo6Q2xlYXIoKTsKKyAgY2xlYXJfaGFzX29wdGlvbnMoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlT3B0aW9ucyYgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpvcHRpb25zKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8ub3B0aW9ucykKKyAgcmV0dXJuIG9wdGlvbnNfICE9IE5VTEwgPyAqb3B0aW9uc18gOiAqZGVmYXVsdF9pbnN0YW5jZV8tPm9wdGlvbnNfOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtVmFsdWVPcHRpb25zKiBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfb3B0aW9ucygpIHsKKyAgc2V0X2hhc19vcHRpb25zKCk7CisgIGlmIChvcHRpb25zXyA9PSBOVUxMKSB7CisgICAgb3B0aW9uc18gPSBuZXcgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtVmFsdWVPcHRpb25zOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8ub3B0aW9ucykKKyAgcmV0dXJuIG9wdGlvbnNfOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtVmFsdWVPcHRpb25zKiBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86OnJlbGVhc2Vfb3B0aW9ucygpIHsKKyAgY2xlYXJfaGFzX29wdGlvbnMoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtVmFsdWVPcHRpb25zKiB0ZW1wID0gb3B0aW9uc187CisgIG9wdGlvbnNfID0gTlVMTDsKKyAgcmV0dXJuIHRlbXA7Cit9Cit2b2lkIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6c2V0X2FsbG9jYXRlZF9vcHRpb25zKDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlT3B0aW9ucyogb3B0aW9ucykgeworICBkZWxldGUgb3B0aW9uc187CisgIG9wdGlvbnNfID0gb3B0aW9uczsKKyAgaWYgKG9wdGlvbnMpIHsKKyAgICBzZXRfaGFzX29wdGlvbnMoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfb3B0aW9ucygpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8ub3B0aW9ucykKK30KKworI2VuZGlmICAvLyBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisjaWYgIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKK2NvbnN0IGludCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjprTmFtZUZpZWxkTnVtYmVyOworY29uc3QgaW50IFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86OmtNZXRob2RGaWVsZE51bWJlcjsKK2NvbnN0IGludCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjprT3B0aW9uc0ZpZWxkTnVtYmVyOworI2VuZGlmICAvLyAhZGVmaW5lZChfTVNDX1ZFUikgfHwgX01TQ19WRVIgPj0gMTkwMAorCitTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpTZXJ2aWNlRGVzY3JpcHRvclByb3RvKCkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvKQorfQorCit2b2lkIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86OkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpIHsKKyAgb3B0aW9uc18gPSBjb25zdF9jYXN0PCA6Omdvb2dsZTo6cHJvdG9idWY6OlNlcnZpY2VPcHRpb25zKj4oJjo6Z29vZ2xlOjpwcm90b2J1Zjo6U2VydmljZU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2UoKSk7Cit9CisKK1NlcnZpY2VEZXNjcmlwdG9yUHJvdG86OlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8oY29uc3QgU2VydmljZURlc2NyaXB0b3JQcm90byYgZnJvbSkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwKKyAgICBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICBNZXJnZUZyb20oZnJvbSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb3B5X2NvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvKQorfQorCit2b2lkIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86OlNoYXJlZEN0b3IoKSB7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSAwOworICBuYW1lXy5VbnNhZmVTZXREZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIG9wdGlvbnNfID0gTlVMTDsKKyAgOjptZW1zZXQoX2hhc19iaXRzXywgMCwgc2l6ZW9mKF9oYXNfYml0c18pKTsKK30KKworU2VydmljZURlc2NyaXB0b3JQcm90bzo6flNlcnZpY2VEZXNjcmlwdG9yUHJvdG8oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChkZXN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvKQorICBTaGFyZWREdG9yKCk7Cit9CisKK3ZvaWQgU2VydmljZURlc2NyaXB0b3JQcm90bzo6U2hhcmVkRHRvcigpIHsKKyAgbmFtZV8uRGVzdHJveU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgaWYgKHRoaXMgIT0gZGVmYXVsdF9pbnN0YW5jZV8pIHsKKyAgICBkZWxldGUgb3B0aW9uc187CisgIH0KK30KKwordm9pZCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdCB7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSBzaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogU2VydmljZURlc2NyaXB0b3JQcm90bzo6ZGVzY3JpcHRvcigpIHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIHJldHVybiBTZXJ2aWNlRGVzY3JpcHRvclByb3RvX2Rlc2NyaXB0b3JfOworfQorCitjb25zdCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvJiBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlKCkgeworICBpZiAoZGVmYXVsdF9pbnN0YW5jZV8gPT0gTlVMTCkgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICByZXR1cm4gKmRlZmF1bHRfaW5zdGFuY2VfOworfQorCitTZXJ2aWNlRGVzY3JpcHRvclByb3RvKiBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X2luc3RhbmNlXyA9IE5VTEw7CisKK1NlcnZpY2VEZXNjcmlwdG9yUHJvdG8qIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86Ok5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3QgeworICBTZXJ2aWNlRGVzY3JpcHRvclByb3RvKiBuID0gbmV3IFNlcnZpY2VEZXNjcmlwdG9yUHJvdG87CisgIGlmIChhcmVuYSAhPSBOVUxMKSB7CisgICAgYXJlbmEtPk93bihuKTsKKyAgfQorICByZXR1cm4gbjsKK30KKwordm9pZCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpDbGVhcigpIHsKKyAgaWYgKF9oYXNfYml0c19bMCAvIDMyXSAmIDV1KSB7CisgICAgaWYgKGhhc19uYW1lKCkpIHsKKyAgICAgIG5hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgICB9CisgICAgaWYgKGhhc19vcHRpb25zKCkpIHsKKyAgICAgIGlmIChvcHRpb25zXyAhPSBOVUxMKSBvcHRpb25zXy0+Ojpnb29nbGU6OnByb3RvYnVmOjpTZXJ2aWNlT3B0aW9uczo6Q2xlYXIoKTsKKyAgICB9CisgIH0KKyAgbWV0aG9kXy5DbGVhcigpOworICA6Om1lbXNldChfaGFzX2JpdHNfLCAwLCBzaXplb2YoX2hhc19iaXRzXykpOworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkNsZWFyKCk7CisgIH0KK30KKworYm9vbCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyNkZWZpbmUgRE9fKEVYUFJFU1NJT04pIGlmICghKEVYUFJFU1NJT04pKSBnb3RvIGZhaWx1cmUKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgdGFnOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8pCisgIGZvciAoOzspIHsKKyAgICA6OnN0ZDo6cGFpcjwgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIsIGJvb2w+IHAgPSBpbnB1dC0+UmVhZFRhZ1dpdGhDdXRvZmYoMTI3KTsKKyAgICB0YWcgPSBwLmZpcnN0OworICAgIGlmICghcC5zZWNvbmQpIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgc3dpdGNoICg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnRmllbGROdW1iZXIodGFnKSkgeworICAgICAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICAgICAgY2FzZSAxOiB7CisgICAgICAgIGlmICh0YWcgPT0gMTApIHsKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoCisgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPm11dGFibGVfbmFtZSgpKSk7CisgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICAgICAgICB0aGlzLT5uYW1lKCkuZGF0YSgpLCB0aGlzLT5uYW1lKCkubGVuZ3RoKCksCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpQQVJTRSwKKyAgICAgICAgICAgICJnb29nbGUucHJvdG9idWYuU2VydmljZURlc2NyaXB0b3JQcm90by5uYW1lIik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygxOCkpIGdvdG8gcGFyc2VfbWV0aG9kOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8gbWV0aG9kID0gMjsKKyAgICAgIGNhc2UgMjogeworICAgICAgICBpZiAodGFnID09IDE4KSB7CisgICAgICAgICBwYXJzZV9tZXRob2Q6CisgICAgICAgICAgRE9fKGlucHV0LT5JbmNyZW1lbnRSZWN1cnNpb25EZXB0aCgpKTsKKyAgICAgICAgIHBhcnNlX2xvb3BfbWV0aG9kOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZE1lc3NhZ2VOb1ZpcnR1YWxOb1JlY3Vyc2lvbkRlcHRoKAorICAgICAgICAgICAgICAgIGlucHV0LCBhZGRfbWV0aG9kKCkpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDE4KSkgZ290byBwYXJzZV9sb29wX21ldGhvZDsKKyAgICAgICAgaW5wdXQtPlVuc2FmZURlY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCk7CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDI2KSkgZ290byBwYXJzZV9vcHRpb25zOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlT3B0aW9ucyBvcHRpb25zID0gMzsKKyAgICAgIGNhc2UgMzogeworICAgICAgICBpZiAodGFnID09IDI2KSB7CisgICAgICAgICBwYXJzZV9vcHRpb25zOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZE1lc3NhZ2VOb1ZpcnR1YWwoCisgICAgICAgICAgICAgICBpbnB1dCwgbXV0YWJsZV9vcHRpb25zKCkpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0QXRFbmQoKSkgZ290byBzdWNjZXNzOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgZGVmYXVsdDogeworICAgICAgaGFuZGxlX3VudXN1YWw6CisgICAgICAgIGlmICh0YWcgPT0gMCB8fAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ1dpcmVUeXBlKHRhZykgPT0KKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVApIHsKKyAgICAgICAgICBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIH0KKyAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNraXBGaWVsZCgKKyAgICAgICAgICAgICAgaW5wdXQsIHRhZywgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpKSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgfQorc3VjY2VzczoKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N1Y2Nlc3M6Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8pCisgIHJldHVybiB0cnVlOworZmFpbHVyZToKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX2ZhaWx1cmU6Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8pCisgIHJldHVybiBmYWxzZTsKKyN1bmRlZiBET18KK30KKwordm9pZCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvKQorICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgIGlmIChoYXNfbmFtZSgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5uYW1lKCkuZGF0YSgpLCB0aGlzLT5uYW1lKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8ubmFtZSIpOworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ01heWJlQWxpYXNlZCgKKyAgICAgIDEsIHRoaXMtPm5hbWUoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvIG1ldGhvZCA9IDI7CisgIGZvciAodW5zaWduZWQgaW50IGkgPSAwLCBuID0gdGhpcy0+bWV0aG9kX3NpemUoKTsgaSA8IG47IGkrKykgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZU1lc3NhZ2VNYXliZVRvQXJyYXkoCisgICAgICAyLCB0aGlzLT5tZXRob2QoaSksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zIG9wdGlvbnMgPSAzOworICBpZiAoaGFzX29wdGlvbnMoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZU1lc3NhZ2VNYXliZVRvQXJyYXkoCisgICAgICAzLCAqdGhpcy0+b3B0aW9uc18sIG91dHB1dCk7CisgIH0KKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTZXJpYWxpemVVbmtub3duRmllbGRzKAorICAgICAgICB1bmtub3duX2ZpZWxkcygpLCBvdXRwdXQpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfZW5kOmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvKQorfQorCis6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIHRhcmdldCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvKQorICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgIGlmIChoYXNfbmFtZSgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5uYW1lKCkuZGF0YSgpLCB0aGlzLT5uYW1lKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8ubmFtZSIpOworICAgIHRhcmdldCA9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdUb0FycmF5KAorICAgICAgICAxLCB0aGlzLT5uYW1lKCksIHRhcmdldCk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90byBtZXRob2QgPSAyOworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPm1ldGhvZF9zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6CisgICAgICBXcml0ZU1lc3NhZ2VOb1ZpcnR1YWxUb0FycmF5KAorICAgICAgICAyLCB0aGlzLT5tZXRob2QoaSksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zIG9wdGlvbnMgPSAzOworICBpZiAoaGFzX29wdGlvbnMoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjoKKyAgICAgIFdyaXRlTWVzc2FnZU5vVmlydHVhbFRvQXJyYXkoCisgICAgICAgIDMsICp0aGlzLT5vcHRpb25zXywgdGFyZ2V0KTsKKyAgfQorCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25GaWVsZHNUb0FycmF5KAorICAgICAgICB1bmtub3duX2ZpZWxkcygpLCB0YXJnZXQpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfZW5kOmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvKQorICByZXR1cm4gdGFyZ2V0OworfQorCitpbnQgU2VydmljZURlc2NyaXB0b3JQcm90bzo6Qnl0ZVNpemUoKSBjb25zdCB7CisgIGludCB0b3RhbF9zaXplID0gMDsKKworICBpZiAoX2hhc19iaXRzX1swIC8gMzJdICYgNXUpIHsKKyAgICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgICAgaWYgKGhhc19uYW1lKCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTdHJpbmdTaXplKAorICAgICAgICAgIHRoaXMtPm5hbWUoKSk7CisgICAgfQorCisgICAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlT3B0aW9ucyBvcHRpb25zID0gMzsKKyAgICBpZiAoaGFzX29wdGlvbnMoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1lc3NhZ2VTaXplTm9WaXJ0dWFsKAorICAgICAgICAgICp0aGlzLT5vcHRpb25zXyk7CisgICAgfQorCisgIH0KKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8gbWV0aG9kID0gMjsKKyAgdG90YWxfc2l6ZSArPSAxICogdGhpcy0+bWV0aG9kX3NpemUoKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT5tZXRob2Rfc2l6ZSgpOyBpKyspIHsKKyAgICB0b3RhbF9zaXplICs9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6TWVzc2FnZVNpemVOb1ZpcnR1YWwoCisgICAgICAgIHRoaXMtPm1ldGhvZChpKSk7CisgIH0KKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICB0b3RhbF9zaXplICs9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpDb21wdXRlVW5rbm93bkZpZWxkc1NpemUoCisgICAgICAgIHVua25vd25fZmllbGRzKCkpOworICB9CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSB0b3RhbF9zaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKKyAgcmV0dXJuIHRvdGFsX3NpemU7Cit9CisKK3ZvaWQgU2VydmljZURlc2NyaXB0b3JQcm90bzo6TWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBjb25zdCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvKiBzb3VyY2UgPSAKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkR5bmFtaWNDYXN0VG9HZW5lcmF0ZWQ8Y29uc3QgU2VydmljZURlc2NyaXB0b3JQcm90bz4oCisgICAgICAgICAgJmZyb20pOworICBpZiAoc291cmNlID09IE5VTEwpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpSZWZsZWN0aW9uT3BzOjpNZXJnZShmcm9tLCB0aGlzKTsKKyAgfSBlbHNlIHsKKyAgICBNZXJnZUZyb20oKnNvdXJjZSk7CisgIH0KK30KKwordm9pZCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpNZXJnZUZyb20oY29uc3QgU2VydmljZURlc2NyaXB0b3JQcm90byYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBtZXRob2RfLk1lcmdlRnJvbShmcm9tLm1ldGhvZF8pOworICBpZiAoZnJvbS5faGFzX2JpdHNfWzAgLyAzMl0gJiAoMHhmZnUgPDwgKDAgJSAzMikpKSB7CisgICAgaWYgKGZyb20uaGFzX25hbWUoKSkgeworICAgICAgc2V0X2hhc19uYW1lKCk7CisgICAgICBuYW1lXy5Bc3NpZ25XaXRoRGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGZyb20ubmFtZV8pOworICAgIH0KKyAgICBpZiAoZnJvbS5oYXNfb3B0aW9ucygpKSB7CisgICAgICBtdXRhYmxlX29wdGlvbnMoKS0+Ojpnb29nbGU6OnByb3RvYnVmOjpTZXJ2aWNlT3B0aW9uczo6TWVyZ2VGcm9tKGZyb20ub3B0aW9ucygpKTsKKyAgICB9CisgIH0KKyAgaWYgKGZyb20uX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPk1lcmdlRnJvbShmcm9tLnVua25vd25fZmllbGRzKCkpOworICB9Cit9CisKK3ZvaWQgU2VydmljZURlc2NyaXB0b3JQcm90bzo6Q29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKwordm9pZCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpDb3B5RnJvbShjb25zdCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKworYm9vbCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpJc0luaXRpYWxpemVkKCkgY29uc3QgeworCisgIGlmICghOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QWxsQXJlSW5pdGlhbGl6ZWQodGhpcy0+bWV0aG9kKCkpKSByZXR1cm4gZmFsc2U7CisgIGlmIChoYXNfb3B0aW9ucygpKSB7CisgICAgaWYgKCF0aGlzLT5vcHRpb25zXy0+SXNJbml0aWFsaXplZCgpKSByZXR1cm4gZmFsc2U7CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgU2VydmljZURlc2NyaXB0b3JQcm90bzo6U3dhcChTZXJ2aWNlRGVzY3JpcHRvclByb3RvKiBvdGhlcikgeworICBpZiAob3RoZXIgPT0gdGhpcykgcmV0dXJuOworICBJbnRlcm5hbFN3YXAob3RoZXIpOworfQordm9pZCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpJbnRlcm5hbFN3YXAoU2VydmljZURlc2NyaXB0b3JQcm90byogb3RoZXIpIHsKKyAgbmFtZV8uU3dhcCgmb3RoZXItPm5hbWVfKTsKKyAgbWV0aG9kXy5VbnNhZmVBcmVuYVN3YXAoJm90aGVyLT5tZXRob2RfKTsKKyAgc3RkOjpzd2FwKG9wdGlvbnNfLCBvdGhlci0+b3B0aW9uc18pOworICBzdGQ6OnN3YXAoX2hhc19iaXRzX1swXSwgb3RoZXItPl9oYXNfYml0c19bMF0pOworICBfaW50ZXJuYWxfbWV0YWRhdGFfLlN3YXAoJm90aGVyLT5faW50ZXJuYWxfbWV0YWRhdGFfKTsKKyAgc3RkOjpzd2FwKF9jYWNoZWRfc2l6ZV8sIG90aGVyLT5fY2FjaGVkX3NpemVfKTsKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpHZXRNZXRhZGF0YSgpIGNvbnN0IHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgbWV0YWRhdGE7CisgIG1ldGFkYXRhLmRlc2NyaXB0b3IgPSBTZXJ2aWNlRGVzY3JpcHRvclByb3RvX2Rlc2NyaXB0b3JfOworICBtZXRhZGF0YS5yZWZsZWN0aW9uID0gU2VydmljZURlc2NyaXB0b3JQcm90b19yZWZsZWN0aW9uXzsKKyAgcmV0dXJuIG1ldGFkYXRhOworfQorCisjaWYgUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisvLyBTZXJ2aWNlRGVzY3JpcHRvclByb3RvCisKKy8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKK2Jvb2wgU2VydmljZURlc2NyaXB0b3JQcm90bzo6aGFzX25hbWUoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDF1KSAhPSAwOworfQordm9pZCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX25hbWUoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMXU7Cit9Cit2b2lkIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86OmNsZWFyX2hhc19uYW1lKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAxdTsKK30KK3ZvaWQgU2VydmljZURlc2NyaXB0b3JQcm90bzo6Y2xlYXJfbmFtZSgpIHsKKyAgbmFtZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfbmFtZSgpOworfQorIGNvbnN0IDo6c3RkOjpzdHJpbmcmIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86Om5hbWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8ubmFtZSkKKyAgcmV0dXJuIG5hbWVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86OnNldF9uYW1lKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfbmFtZSgpOworICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvLm5hbWUpCit9Cisgdm9pZCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvLm5hbWUpCit9Cisgdm9pZCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvLm5hbWUpCit9CisgOjpzdGQ6OnN0cmluZyogU2VydmljZURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9uYW1lKCkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8ubmFtZSkKKyAgcmV0dXJuIG5hbWVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CisgOjpzdGQ6OnN0cmluZyogU2VydmljZURlc2NyaXB0b3JQcm90bzo6cmVsZWFzZV9uYW1lKCkgeworICBjbGVhcl9oYXNfbmFtZSgpOworICByZXR1cm4gbmFtZV8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86OnNldF9hbGxvY2F0ZWRfbmFtZSg6OnN0ZDo6c3RyaW5nKiBuYW1lKSB7CisgIGlmIChuYW1lICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX25hbWUoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfbmFtZSgpOworICB9CisgIG5hbWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBuYW1lKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8gbWV0aG9kID0gMjsKK2ludCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjptZXRob2Rfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIG1ldGhvZF8uc2l6ZSgpOworfQordm9pZCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9tZXRob2QoKSB7CisgIG1ldGhvZF8uQ2xlYXIoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0aG9kRGVzY3JpcHRvclByb3RvJiBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjptZXRob2QoaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8ubWV0aG9kKQorICByZXR1cm4gbWV0aG9kXy5HZXQoaW5kZXgpOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpNZXRob2REZXNjcmlwdG9yUHJvdG8qIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfbWV0aG9kKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuU2VydmljZURlc2NyaXB0b3JQcm90by5tZXRob2QpCisgIHJldHVybiBtZXRob2RfLk11dGFibGUoaW5kZXgpOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpNZXRob2REZXNjcmlwdG9yUHJvdG8qIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86OmFkZF9tZXRob2QoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8ubWV0aG9kKQorICByZXR1cm4gbWV0aG9kXy5BZGQoKTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRob2REZXNjcmlwdG9yUHJvdG8gPioKK1NlcnZpY2VEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfbWV0aG9kKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvLm1ldGhvZCkKKyAgcmV0dXJuICZtZXRob2RfOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGhvZERlc2NyaXB0b3JQcm90byA+JgorU2VydmljZURlc2NyaXB0b3JQcm90bzo6bWV0aG9kKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuU2VydmljZURlc2NyaXB0b3JQcm90by5tZXRob2QpCisgIHJldHVybiBtZXRob2RfOworfQorCisvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zIG9wdGlvbnMgPSAzOworYm9vbCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpoYXNfb3B0aW9ucygpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwNHUpICE9IDA7Cit9Cit2b2lkIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86OnNldF9oYXNfb3B0aW9ucygpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDA0dTsKK30KK3ZvaWQgU2VydmljZURlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX29wdGlvbnMoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDR1OworfQordm9pZCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9vcHRpb25zKCkgeworICBpZiAob3B0aW9uc18gIT0gTlVMTCkgb3B0aW9uc18tPjo6Z29vZ2xlOjpwcm90b2J1Zjo6U2VydmljZU9wdGlvbnM6OkNsZWFyKCk7CisgIGNsZWFyX2hhc19vcHRpb25zKCk7Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlNlcnZpY2VPcHRpb25zJiBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpvcHRpb25zKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvLm9wdGlvbnMpCisgIHJldHVybiBvcHRpb25zXyAhPSBOVUxMID8gKm9wdGlvbnNfIDogKmRlZmF1bHRfaW5zdGFuY2VfLT5vcHRpb25zXzsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6U2VydmljZU9wdGlvbnMqIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfb3B0aW9ucygpIHsKKyAgc2V0X2hhc19vcHRpb25zKCk7CisgIGlmIChvcHRpb25zXyA9PSBOVUxMKSB7CisgICAgb3B0aW9uc18gPSBuZXcgOjpnb29nbGU6OnByb3RvYnVmOjpTZXJ2aWNlT3B0aW9uczsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuU2VydmljZURlc2NyaXB0b3JQcm90by5vcHRpb25zKQorICByZXR1cm4gb3B0aW9uc187Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6OlNlcnZpY2VPcHRpb25zKiBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX29wdGlvbnMoKSB7CisgIGNsZWFyX2hhc19vcHRpb25zKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6U2VydmljZU9wdGlvbnMqIHRlbXAgPSBvcHRpb25zXzsKKyAgb3B0aW9uc18gPSBOVUxMOworICByZXR1cm4gdGVtcDsKK30KK3ZvaWQgU2VydmljZURlc2NyaXB0b3JQcm90bzo6c2V0X2FsbG9jYXRlZF9vcHRpb25zKDo6Z29vZ2xlOjpwcm90b2J1Zjo6U2VydmljZU9wdGlvbnMqIG9wdGlvbnMpIHsKKyAgZGVsZXRlIG9wdGlvbnNfOworICBvcHRpb25zXyA9IG9wdGlvbnM7CisgIGlmIChvcHRpb25zKSB7CisgICAgc2V0X2hhc19vcHRpb25zKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX29wdGlvbnMoKTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuU2VydmljZURlc2NyaXB0b3JQcm90by5vcHRpb25zKQorfQorCisjZW5kaWYgIC8vIFBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKyNpZiAhZGVmaW5lZChfTVNDX1ZFUikgfHwgX01TQ19WRVIgPj0gMTkwMAorY29uc3QgaW50IE1ldGhvZERlc2NyaXB0b3JQcm90bzo6a05hbWVGaWVsZE51bWJlcjsKK2NvbnN0IGludCBNZXRob2REZXNjcmlwdG9yUHJvdG86OmtJbnB1dFR5cGVGaWVsZE51bWJlcjsKK2NvbnN0IGludCBNZXRob2REZXNjcmlwdG9yUHJvdG86OmtPdXRwdXRUeXBlRmllbGROdW1iZXI7Citjb25zdCBpbnQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjprT3B0aW9uc0ZpZWxkTnVtYmVyOworY29uc3QgaW50IE1ldGhvZERlc2NyaXB0b3JQcm90bzo6a0NsaWVudFN0cmVhbWluZ0ZpZWxkTnVtYmVyOworY29uc3QgaW50IE1ldGhvZERlc2NyaXB0b3JQcm90bzo6a1NlcnZlclN0cmVhbWluZ0ZpZWxkTnVtYmVyOworI2VuZGlmICAvLyAhZGVmaW5lZChfTVNDX1ZFUikgfHwgX01TQ19WRVIgPj0gMTkwMAorCitNZXRob2REZXNjcmlwdG9yUHJvdG86Ok1ldGhvZERlc2NyaXB0b3JQcm90bygpCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgeworICBTaGFyZWRDdG9yKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvKQorfQorCit2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6SW5pdEFzRGVmYXVsdEluc3RhbmNlKCkgeworICBvcHRpb25zXyA9IGNvbnN0X2Nhc3Q8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0aG9kT3B0aW9ucyo+KCY6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGhvZE9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2UoKSk7Cit9CisKK01ldGhvZERlc2NyaXB0b3JQcm90bzo6TWV0aG9kRGVzY3JpcHRvclByb3RvKGNvbnN0IE1ldGhvZERlc2NyaXB0b3JQcm90byYgZnJvbSkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwKKyAgICBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICBNZXJnZUZyb20oZnJvbSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb3B5X2NvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8pCit9CisKK3ZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpTaGFyZWRDdG9yKCkgeworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZygpOworICBfY2FjaGVkX3NpemVfID0gMDsKKyAgbmFtZV8uVW5zYWZlU2V0RGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBpbnB1dF90eXBlXy5VbnNhZmVTZXREZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIG91dHB1dF90eXBlXy5VbnNhZmVTZXREZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIG9wdGlvbnNfID0gTlVMTDsKKyAgY2xpZW50X3N0cmVhbWluZ18gPSBmYWxzZTsKKyAgc2VydmVyX3N0cmVhbWluZ18gPSBmYWxzZTsKKyAgOjptZW1zZXQoX2hhc19iaXRzXywgMCwgc2l6ZW9mKF9oYXNfYml0c18pKTsKK30KKworTWV0aG9kRGVzY3JpcHRvclByb3RvOjp+TWV0aG9kRGVzY3JpcHRvclByb3RvKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZGVzdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvKQorICBTaGFyZWREdG9yKCk7Cit9CisKK3ZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpTaGFyZWREdG9yKCkgeworICBuYW1lXy5EZXN0cm95Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBpbnB1dF90eXBlXy5EZXN0cm95Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBvdXRwdXRfdHlwZV8uRGVzdHJveU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgaWYgKHRoaXMgIT0gZGVmYXVsdF9pbnN0YW5jZV8pIHsKKyAgICBkZWxldGUgb3B0aW9uc187CisgIH0KK30KKwordm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OlNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0IHsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHNpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBNZXRob2REZXNjcmlwdG9yUHJvdG86OmRlc2NyaXB0b3IoKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICByZXR1cm4gTWV0aG9kRGVzY3JpcHRvclByb3RvX2Rlc2NyaXB0b3JfOworfQorCitjb25zdCBNZXRob2REZXNjcmlwdG9yUHJvdG8mIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6ZGVmYXVsdF9pbnN0YW5jZSgpIHsKKyAgaWYgKGRlZmF1bHRfaW5zdGFuY2VfID09IE5VTEwpIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgcmV0dXJuICpkZWZhdWx0X2luc3RhbmNlXzsKK30KKworTWV0aG9kRGVzY3JpcHRvclByb3RvKiBNZXRob2REZXNjcmlwdG9yUHJvdG86OmRlZmF1bHRfaW5zdGFuY2VfID0gTlVMTDsKKworTWV0aG9kRGVzY3JpcHRvclByb3RvKiBNZXRob2REZXNjcmlwdG9yUHJvdG86Ok5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3QgeworICBNZXRob2REZXNjcmlwdG9yUHJvdG8qIG4gPSBuZXcgTWV0aG9kRGVzY3JpcHRvclByb3RvOworICBpZiAoYXJlbmEgIT0gTlVMTCkgeworICAgIGFyZW5hLT5Pd24obik7CisgIH0KKyAgcmV0dXJuIG47Cit9CisKK3ZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpDbGVhcigpIHsKKyNkZWZpbmUgWlJfSEVMUEVSXyhmKSByZWludGVycHJldF9jYXN0PGNoYXIqPihcCisgICZyZWludGVycHJldF9jYXN0PE1ldGhvZERlc2NyaXB0b3JQcm90byo+KDE2KS0+ZikKKworI2RlZmluZSBaUl8oZmlyc3QsIGxhc3QpIGRvIHtcCisgIDo6bWVtc2V0KCZmaXJzdCwgMCxcCisgICAgICAgICAgIFpSX0hFTFBFUl8obGFzdCkgLSBaUl9IRUxQRVJfKGZpcnN0KSArIHNpemVvZihsYXN0KSk7XAorfSB3aGlsZSAoMCkKKworICBpZiAoX2hhc19iaXRzX1swIC8gMzJdICYgNjN1KSB7CisgICAgWlJfKGNsaWVudF9zdHJlYW1pbmdfLCBzZXJ2ZXJfc3RyZWFtaW5nXyk7CisgICAgaWYgKGhhc19uYW1lKCkpIHsKKyAgICAgIG5hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgICB9CisgICAgaWYgKGhhc19pbnB1dF90eXBlKCkpIHsKKyAgICAgIGlucHV0X3R5cGVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgICB9CisgICAgaWYgKGhhc19vdXRwdXRfdHlwZSgpKSB7CisgICAgICBvdXRwdXRfdHlwZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICAgIH0KKyAgICBpZiAoaGFzX29wdGlvbnMoKSkgeworICAgICAgaWYgKG9wdGlvbnNfICE9IE5VTEwpIG9wdGlvbnNfLT46Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGhvZE9wdGlvbnM6OkNsZWFyKCk7CisgICAgfQorICB9CisKKyN1bmRlZiBaUl9IRUxQRVJfCisjdW5kZWYgWlJfCisKKyAgOjptZW1zZXQoX2hhc19iaXRzXywgMCwgc2l6ZW9mKF9oYXNfYml0c18pKTsKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5DbGVhcigpOworICB9Cit9CisKK2Jvb2wgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyNkZWZpbmUgRE9fKEVYUFJFU1NJT04pIGlmICghKEVYUFJFU1NJT04pKSBnb3RvIGZhaWx1cmUKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgdGFnOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90bykKKyAgZm9yICg7OykgeworICAgIDo6c3RkOjpwYWlyPCA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiwgYm9vbD4gcCA9IGlucHV0LT5SZWFkVGFnV2l0aEN1dG9mZigxMjcpOworICAgIHRhZyA9IHAuZmlyc3Q7CisgICAgaWYgKCFwLnNlY29uZCkgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICBzd2l0Y2ggKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdGaWVsZE51bWJlcih0YWcpKSB7CisgICAgICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgICAgICBjYXNlIDE6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAxMCkgeworICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFN0cmluZygKKyAgICAgICAgICAgICAgICBpbnB1dCwgdGhpcy0+bXV0YWJsZV9uYW1lKCkpKTsKKyAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgICAgICAgIHRoaXMtPm5hbWUoKS5kYXRhKCksIHRoaXMtPm5hbWUoKS5sZW5ndGgoKSwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlBBUlNFLAorICAgICAgICAgICAgImdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8ubmFtZSIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMTgpKSBnb3RvIHBhcnNlX2lucHV0X3R5cGU7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCBzdHJpbmcgaW5wdXRfdHlwZSA9IDI7CisgICAgICBjYXNlIDI6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAxOCkgeworICAgICAgICAgcGFyc2VfaW5wdXRfdHlwZToKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoCisgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPm11dGFibGVfaW5wdXRfdHlwZSgpKSk7CisgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICAgICAgICB0aGlzLT5pbnB1dF90eXBlKCkuZGF0YSgpLCB0aGlzLT5pbnB1dF90eXBlKCkubGVuZ3RoKCksCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpQQVJTRSwKKyAgICAgICAgICAgICJnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvLmlucHV0X3R5cGUiKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDI2KSkgZ290byBwYXJzZV9vdXRwdXRfdHlwZTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIHN0cmluZyBvdXRwdXRfdHlwZSA9IDM7CisgICAgICBjYXNlIDM6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAyNikgeworICAgICAgICAgcGFyc2Vfb3V0cHV0X3R5cGU6CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkU3RyaW5nKAorICAgICAgICAgICAgICAgIGlucHV0LCB0aGlzLT5tdXRhYmxlX291dHB1dF90eXBlKCkpKTsKKyAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgICAgICAgIHRoaXMtPm91dHB1dF90eXBlKCkuZGF0YSgpLCB0aGlzLT5vdXRwdXRfdHlwZSgpLmxlbmd0aCgpLAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6UEFSU0UsCisgICAgICAgICAgICAiZ29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90by5vdXRwdXRfdHlwZSIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMzQpKSBnb3RvIHBhcnNlX29wdGlvbnM7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMgb3B0aW9ucyA9IDQ7CisgICAgICBjYXNlIDQ6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAzNCkgeworICAgICAgICAgcGFyc2Vfb3B0aW9uczoKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRNZXNzYWdlTm9WaXJ0dWFsKAorICAgICAgICAgICAgICAgaW5wdXQsIG11dGFibGVfb3B0aW9ucygpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg0MCkpIGdvdG8gcGFyc2VfY2xpZW50X3N0cmVhbWluZzsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIGJvb2wgY2xpZW50X3N0cmVhbWluZyA9IDUgW2RlZmF1bHQgPSBmYWxzZV07CisgICAgICBjYXNlIDU6IHsKKyAgICAgICAgaWYgKHRhZyA9PSA0MCkgeworICAgICAgICAgcGFyc2VfY2xpZW50X3N0cmVhbWluZzoKKyAgICAgICAgICBET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPAorICAgICAgICAgICAgICAgICAgIGJvb2wsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0JPT0w+KAorICAgICAgICAgICAgICAgICBpbnB1dCwgJmNsaWVudF9zdHJlYW1pbmdfKSkpOworICAgICAgICAgIHNldF9oYXNfY2xpZW50X3N0cmVhbWluZygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNDgpKSBnb3RvIHBhcnNlX3NlcnZlcl9zdHJlYW1pbmc7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCBib29sIHNlcnZlcl9zdHJlYW1pbmcgPSA2IFtkZWZhdWx0ID0gZmFsc2VdOworICAgICAgY2FzZSA2OiB7CisgICAgICAgIGlmICh0YWcgPT0gNDgpIHsKKyAgICAgICAgIHBhcnNlX3NlcnZlcl9zdHJlYW1pbmc6CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICBib29sLCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9CT09MPigKKyAgICAgICAgICAgICAgICAgaW5wdXQsICZzZXJ2ZXJfc3RyZWFtaW5nXykpKTsKKyAgICAgICAgICBzZXRfaGFzX3NlcnZlcl9zdHJlYW1pbmcoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0QXRFbmQoKSkgZ290byBzdWNjZXNzOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgZGVmYXVsdDogeworICAgICAgaGFuZGxlX3VudXN1YWw6CisgICAgICAgIGlmICh0YWcgPT0gMCB8fAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ1dpcmVUeXBlKHRhZykgPT0KKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVApIHsKKyAgICAgICAgICBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIH0KKyAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNraXBGaWVsZCgKKyAgICAgICAgICAgICAgaW5wdXQsIHRhZywgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpKSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgfQorc3VjY2VzczoKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N1Y2Nlc3M6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90bykKKyAgcmV0dXJuIHRydWU7CitmYWlsdXJlOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2VfZmFpbHVyZTpnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvKQorICByZXR1cm4gZmFsc2U7CisjdW5kZWYgRE9fCit9CisKK3ZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8pCisgIC8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKKyAgaWYgKGhhc19uYW1lKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgIHRoaXMtPm5hbWUoKS5kYXRhKCksIHRoaXMtPm5hbWUoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvLm5hbWUiKTsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdNYXliZUFsaWFzZWQoCisgICAgICAxLCB0aGlzLT5uYW1lKCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgaW5wdXRfdHlwZSA9IDI7CisgIGlmIChoYXNfaW5wdXRfdHlwZSgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5pbnB1dF90eXBlKCkuZGF0YSgpLCB0aGlzLT5pbnB1dF90eXBlKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90by5pbnB1dF90eXBlIik7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nTWF5YmVBbGlhc2VkKAorICAgICAgMiwgdGhpcy0+aW5wdXRfdHlwZSgpLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIG91dHB1dF90eXBlID0gMzsKKyAgaWYgKGhhc19vdXRwdXRfdHlwZSgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5vdXRwdXRfdHlwZSgpLmRhdGEoKSwgdGhpcy0+b3V0cHV0X3R5cGUoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvLm91dHB1dF90eXBlIik7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nTWF5YmVBbGlhc2VkKAorICAgICAgMywgdGhpcy0+b3V0cHV0X3R5cGUoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucyBvcHRpb25zID0gNDsKKyAgaWYgKGhhc19vcHRpb25zKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgNCwgKnRoaXMtPm9wdGlvbnNfLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgYm9vbCBjbGllbnRfc3RyZWFtaW5nID0gNSBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgaWYgKGhhc19jbGllbnRfc3RyZWFtaW5nKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCb29sKDUsIHRoaXMtPmNsaWVudF9zdHJlYW1pbmcoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGJvb2wgc2VydmVyX3N0cmVhbWluZyA9IDYgW2RlZmF1bHQgPSBmYWxzZV07CisgIGlmIChoYXNfc2VydmVyX3N0cmVhbWluZygpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlQm9vbCg2LCB0aGlzLT5zZXJ2ZXJfc3RyZWFtaW5nKCksIG91dHB1dCk7CisgIH0KKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTZXJpYWxpemVVbmtub3duRmllbGRzKAorICAgICAgICB1bmtub3duX2ZpZWxkcygpLCBvdXRwdXQpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfZW5kOmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8pCit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiB0YXJnZXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9zdGFydDpnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvKQorICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgIGlmIChoYXNfbmFtZSgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5uYW1lKCkuZGF0YSgpLCB0aGlzLT5uYW1lKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90by5uYW1lIik7CisgICAgdGFyZ2V0ID0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ1RvQXJyYXkoCisgICAgICAgIDEsIHRoaXMtPm5hbWUoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIHN0cmluZyBpbnB1dF90eXBlID0gMjsKKyAgaWYgKGhhc19pbnB1dF90eXBlKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgIHRoaXMtPmlucHV0X3R5cGUoKS5kYXRhKCksIHRoaXMtPmlucHV0X3R5cGUoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvLmlucHV0X3R5cGUiKTsKKyAgICB0YXJnZXQgPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nVG9BcnJheSgKKyAgICAgICAgMiwgdGhpcy0+aW5wdXRfdHlwZSgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIG91dHB1dF90eXBlID0gMzsKKyAgaWYgKGhhc19vdXRwdXRfdHlwZSgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5vdXRwdXRfdHlwZSgpLmRhdGEoKSwgdGhpcy0+b3V0cHV0X3R5cGUoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvLm91dHB1dF90eXBlIik7CisgICAgdGFyZ2V0ID0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ1RvQXJyYXkoCisgICAgICAgIDMsIHRoaXMtPm91dHB1dF90eXBlKCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMgb3B0aW9ucyA9IDQ7CisgIGlmIChoYXNfb3B0aW9ucygpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OgorICAgICAgV3JpdGVNZXNzYWdlTm9WaXJ0dWFsVG9BcnJheSgKKyAgICAgICAgNCwgKnRoaXMtPm9wdGlvbnNfLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgYm9vbCBjbGllbnRfc3RyZWFtaW5nID0gNSBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgaWYgKGhhc19jbGllbnRfc3RyZWFtaW5nKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCb29sVG9BcnJheSg1LCB0aGlzLT5jbGllbnRfc3RyZWFtaW5nKCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBib29sIHNlcnZlcl9zdHJlYW1pbmcgPSA2IFtkZWZhdWx0ID0gZmFsc2VdOworICBpZiAoaGFzX3NlcnZlcl9zdHJlYW1pbmcoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2xUb0FycmF5KDYsIHRoaXMtPnNlcnZlcl9zdHJlYW1pbmcoKSwgdGFyZ2V0KTsKKyAgfQorCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25GaWVsZHNUb0FycmF5KAorICAgICAgICB1bmtub3duX2ZpZWxkcygpLCB0YXJnZXQpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfZW5kOmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8pCisgIHJldHVybiB0YXJnZXQ7Cit9CisKK2ludCBNZXRob2REZXNjcmlwdG9yUHJvdG86OkJ5dGVTaXplKCkgY29uc3QgeworICBpbnQgdG90YWxfc2l6ZSA9IDA7CisKKyAgaWYgKF9oYXNfYml0c19bMCAvIDMyXSAmIDYzdSkgeworICAgIC8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKKyAgICBpZiAoaGFzX25hbWUoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlN0cmluZ1NpemUoCisgICAgICAgICAgdGhpcy0+bmFtZSgpKTsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCBzdHJpbmcgaW5wdXRfdHlwZSA9IDI7CisgICAgaWYgKGhhc19pbnB1dF90eXBlKCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTdHJpbmdTaXplKAorICAgICAgICAgIHRoaXMtPmlucHV0X3R5cGUoKSk7CisgICAgfQorCisgICAgLy8gb3B0aW9uYWwgc3RyaW5nIG91dHB1dF90eXBlID0gMzsKKyAgICBpZiAoaGFzX291dHB1dF90eXBlKCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTdHJpbmdTaXplKAorICAgICAgICAgIHRoaXMtPm91dHB1dF90eXBlKCkpOworICAgIH0KKworICAgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucyBvcHRpb25zID0gNDsKKyAgICBpZiAoaGFzX29wdGlvbnMoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1lc3NhZ2VTaXplTm9WaXJ0dWFsKAorICAgICAgICAgICp0aGlzLT5vcHRpb25zXyk7CisgICAgfQorCisgICAgLy8gb3B0aW9uYWwgYm9vbCBjbGllbnRfc3RyZWFtaW5nID0gNSBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgICBpZiAoaGFzX2NsaWVudF9zdHJlYW1pbmcoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsgMTsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCBib29sIHNlcnZlcl9zdHJlYW1pbmcgPSA2IFtkZWZhdWx0ID0gZmFsc2VdOworICAgIGlmIChoYXNfc2VydmVyX3N0cmVhbWluZygpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKyAxOworICAgIH0KKworICB9CisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHRvdGFsX3NpemUgKz0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OkNvbXB1dGVVbmtub3duRmllbGRzU2l6ZSgKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSk7CisgIH0KKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHRvdGFsX3NpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworICByZXR1cm4gdG90YWxfc2l6ZTsKK30KKwordm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86Ok1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgY29uc3QgTWV0aG9kRGVzY3JpcHRvclByb3RvKiBzb3VyY2UgPSAKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkR5bmFtaWNDYXN0VG9HZW5lcmF0ZWQ8Y29uc3QgTWV0aG9kRGVzY3JpcHRvclByb3RvPigKKyAgICAgICAgICAmZnJvbSk7CisgIGlmIChzb3VyY2UgPT0gTlVMTCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlJlZmxlY3Rpb25PcHM6Ok1lcmdlKGZyb20sIHRoaXMpOworICB9IGVsc2UgeworICAgIE1lcmdlRnJvbSgqc291cmNlKTsKKyAgfQorfQorCit2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6TWVyZ2VGcm9tKGNvbnN0IE1ldGhvZERlc2NyaXB0b3JQcm90byYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBpZiAoZnJvbS5faGFzX2JpdHNfWzAgLyAzMl0gJiAoMHhmZnUgPDwgKDAgJSAzMikpKSB7CisgICAgaWYgKGZyb20uaGFzX25hbWUoKSkgeworICAgICAgc2V0X2hhc19uYW1lKCk7CisgICAgICBuYW1lXy5Bc3NpZ25XaXRoRGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGZyb20ubmFtZV8pOworICAgIH0KKyAgICBpZiAoZnJvbS5oYXNfaW5wdXRfdHlwZSgpKSB7CisgICAgICBzZXRfaGFzX2lucHV0X3R5cGUoKTsKKyAgICAgIGlucHV0X3R5cGVfLkFzc2lnbldpdGhEZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgZnJvbS5pbnB1dF90eXBlXyk7CisgICAgfQorICAgIGlmIChmcm9tLmhhc19vdXRwdXRfdHlwZSgpKSB7CisgICAgICBzZXRfaGFzX291dHB1dF90eXBlKCk7CisgICAgICBvdXRwdXRfdHlwZV8uQXNzaWduV2l0aERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBmcm9tLm91dHB1dF90eXBlXyk7CisgICAgfQorICAgIGlmIChmcm9tLmhhc19vcHRpb25zKCkpIHsKKyAgICAgIG11dGFibGVfb3B0aW9ucygpLT46Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGhvZE9wdGlvbnM6Ok1lcmdlRnJvbShmcm9tLm9wdGlvbnMoKSk7CisgICAgfQorICAgIGlmIChmcm9tLmhhc19jbGllbnRfc3RyZWFtaW5nKCkpIHsKKyAgICAgIHNldF9jbGllbnRfc3RyZWFtaW5nKGZyb20uY2xpZW50X3N0cmVhbWluZygpKTsKKyAgICB9CisgICAgaWYgKGZyb20uaGFzX3NlcnZlcl9zdHJlYW1pbmcoKSkgeworICAgICAgc2V0X3NlcnZlcl9zdHJlYW1pbmcoZnJvbS5zZXJ2ZXJfc3RyZWFtaW5nKCkpOworICAgIH0KKyAgfQorICBpZiAoZnJvbS5faW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+TWVyZ2VGcm9tKGZyb20udW5rbm93bl9maWVsZHMoKSk7CisgIH0KK30KKwordm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OkNvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK3ZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpDb3B5RnJvbShjb25zdCBNZXRob2REZXNjcmlwdG9yUHJvdG8mIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCitib29sIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6SXNJbml0aWFsaXplZCgpIGNvbnN0IHsKKworICBpZiAoaGFzX29wdGlvbnMoKSkgeworICAgIGlmICghdGhpcy0+b3B0aW9uc18tPklzSW5pdGlhbGl6ZWQoKSkgcmV0dXJuIGZhbHNlOworICB9CisgIHJldHVybiB0cnVlOworfQorCit2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6U3dhcChNZXRob2REZXNjcmlwdG9yUHJvdG8qIG90aGVyKSB7CisgIGlmIChvdGhlciA9PSB0aGlzKSByZXR1cm47CisgIEludGVybmFsU3dhcChvdGhlcik7Cit9Cit2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6SW50ZXJuYWxTd2FwKE1ldGhvZERlc2NyaXB0b3JQcm90byogb3RoZXIpIHsKKyAgbmFtZV8uU3dhcCgmb3RoZXItPm5hbWVfKTsKKyAgaW5wdXRfdHlwZV8uU3dhcCgmb3RoZXItPmlucHV0X3R5cGVfKTsKKyAgb3V0cHV0X3R5cGVfLlN3YXAoJm90aGVyLT5vdXRwdXRfdHlwZV8pOworICBzdGQ6OnN3YXAob3B0aW9uc18sIG90aGVyLT5vcHRpb25zXyk7CisgIHN0ZDo6c3dhcChjbGllbnRfc3RyZWFtaW5nXywgb3RoZXItPmNsaWVudF9zdHJlYW1pbmdfKTsKKyAgc3RkOjpzd2FwKHNlcnZlcl9zdHJlYW1pbmdfLCBvdGhlci0+c2VydmVyX3N0cmVhbWluZ18pOworICBzdGQ6OnN3YXAoX2hhc19iaXRzX1swXSwgb3RoZXItPl9oYXNfYml0c19bMF0pOworICBfaW50ZXJuYWxfbWV0YWRhdGFfLlN3YXAoJm90aGVyLT5faW50ZXJuYWxfbWV0YWRhdGFfKTsKKyAgc3RkOjpzd2FwKF9jYWNoZWRfc2l6ZV8sIG90aGVyLT5fY2FjaGVkX3NpemVfKTsKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBNZXRob2REZXNjcmlwdG9yUHJvdG86OkdldE1ldGFkYXRhKCkgY29uc3QgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBtZXRhZGF0YTsKKyAgbWV0YWRhdGEuZGVzY3JpcHRvciA9IE1ldGhvZERlc2NyaXB0b3JQcm90b19kZXNjcmlwdG9yXzsKKyAgbWV0YWRhdGEucmVmbGVjdGlvbiA9IE1ldGhvZERlc2NyaXB0b3JQcm90b19yZWZsZWN0aW9uXzsKKyAgcmV0dXJuIG1ldGFkYXRhOworfQorCisjaWYgUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisvLyBNZXRob2REZXNjcmlwdG9yUHJvdG8KKworLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworYm9vbCBNZXRob2REZXNjcmlwdG9yUHJvdG86Omhhc19uYW1lKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAxdSkgIT0gMDsKK30KK3ZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX25hbWUoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMXU7Cit9Cit2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX25hbWUoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDF1OworfQordm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OmNsZWFyX25hbWUoKSB7CisgIG5hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX25hbWUoKTsKK30KKyBjb25zdCA6OnN0ZDo6c3RyaW5nJiBNZXRob2REZXNjcmlwdG9yUHJvdG86Om5hbWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90by5uYW1lKQorICByZXR1cm4gbmFtZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpzZXRfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvLm5hbWUpCit9Cisgdm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OnNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfbmFtZSgpOworICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90by5uYW1lKQorfQorIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KKyA6OnN0ZDo6c3RyaW5nKiBNZXRob2REZXNjcmlwdG9yUHJvdG86Om11dGFibGVfbmFtZSgpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8ubmFtZSkKKyAgcmV0dXJuIG5hbWVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CisgOjpzdGQ6OnN0cmluZyogTWV0aG9kRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX25hbWUoKSB7CisgIGNsZWFyX2hhc19uYW1lKCk7CisgIHJldHVybiBuYW1lXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpzZXRfYWxsb2NhdGVkX25hbWUoOjpzdGQ6OnN0cmluZyogbmFtZSkgeworICBpZiAobmFtZSAhPSBOVUxMKSB7CisgICAgc2V0X2hhc19uYW1lKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX25hbWUoKTsKKyAgfQorICBuYW1lXy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgbmFtZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KKworLy8gb3B0aW9uYWwgc3RyaW5nIGlucHV0X3R5cGUgPSAyOworYm9vbCBNZXRob2REZXNjcmlwdG9yUHJvdG86Omhhc19pbnB1dF90eXBlKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAydSkgIT0gMDsKK30KK3ZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX2lucHV0X3R5cGUoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMnU7Cit9Cit2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX2lucHV0X3R5cGUoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDJ1OworfQordm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OmNsZWFyX2lucHV0X3R5cGUoKSB7CisgIGlucHV0X3R5cGVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX2lucHV0X3R5cGUoKTsKK30KKyBjb25zdCA6OnN0ZDo6c3RyaW5nJiBNZXRob2REZXNjcmlwdG9yUHJvdG86OmlucHV0X3R5cGUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90by5pbnB1dF90eXBlKQorICByZXR1cm4gaW5wdXRfdHlwZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpzZXRfaW5wdXRfdHlwZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBzZXRfaGFzX2lucHV0X3R5cGUoKTsKKyAgaW5wdXRfdHlwZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvLmlucHV0X3R5cGUpCit9Cisgdm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OnNldF9pbnB1dF90eXBlKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfaW5wdXRfdHlwZSgpOworICBpbnB1dF90eXBlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90by5pbnB1dF90eXBlKQorfQorIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpzZXRfaW5wdXRfdHlwZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19pbnB1dF90eXBlKCk7CisgIGlucHV0X3R5cGVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8uaW5wdXRfdHlwZSkKK30KKyA6OnN0ZDo6c3RyaW5nKiBNZXRob2REZXNjcmlwdG9yUHJvdG86Om11dGFibGVfaW5wdXRfdHlwZSgpIHsKKyAgc2V0X2hhc19pbnB1dF90eXBlKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8uaW5wdXRfdHlwZSkKKyAgcmV0dXJuIGlucHV0X3R5cGVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CisgOjpzdGQ6OnN0cmluZyogTWV0aG9kRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX2lucHV0X3R5cGUoKSB7CisgIGNsZWFyX2hhc19pbnB1dF90eXBlKCk7CisgIHJldHVybiBpbnB1dF90eXBlXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpzZXRfYWxsb2NhdGVkX2lucHV0X3R5cGUoOjpzdGQ6OnN0cmluZyogaW5wdXRfdHlwZSkgeworICBpZiAoaW5wdXRfdHlwZSAhPSBOVUxMKSB7CisgICAgc2V0X2hhc19pbnB1dF90eXBlKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX2lucHV0X3R5cGUoKTsKKyAgfQorICBpbnB1dF90eXBlXy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgaW5wdXRfdHlwZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8uaW5wdXRfdHlwZSkKK30KKworLy8gb3B0aW9uYWwgc3RyaW5nIG91dHB1dF90eXBlID0gMzsKK2Jvb2wgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpoYXNfb3V0cHV0X3R5cGUoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDR1KSAhPSAwOworfQordm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OnNldF9oYXNfb3V0cHV0X3R5cGUoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwNHU7Cit9Cit2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX291dHB1dF90eXBlKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDA0dTsKK30KK3ZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpjbGVhcl9vdXRwdXRfdHlwZSgpIHsKKyAgb3V0cHV0X3R5cGVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX291dHB1dF90eXBlKCk7Cit9CisgY29uc3QgOjpzdGQ6OnN0cmluZyYgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpvdXRwdXRfdHlwZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvLm91dHB1dF90eXBlKQorICByZXR1cm4gb3V0cHV0X3R5cGVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6c2V0X291dHB1dF90eXBlKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfb3V0cHV0X3R5cGUoKTsKKyAgb3V0cHV0X3R5cGVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90by5vdXRwdXRfdHlwZSkKK30KKyB2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6c2V0X291dHB1dF90eXBlKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfb3V0cHV0X3R5cGUoKTsKKyAgb3V0cHV0X3R5cGVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvLm91dHB1dF90eXBlKQorfQorIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpzZXRfb3V0cHV0X3R5cGUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHNldF9oYXNfb3V0cHV0X3R5cGUoKTsKKyAgb3V0cHV0X3R5cGVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8ub3V0cHV0X3R5cGUpCit9CisgOjpzdGQ6OnN0cmluZyogTWV0aG9kRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX291dHB1dF90eXBlKCkgeworICBzZXRfaGFzX291dHB1dF90eXBlKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8ub3V0cHV0X3R5cGUpCisgIHJldHVybiBvdXRwdXRfdHlwZV8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyA6OnN0ZDo6c3RyaW5nKiBNZXRob2REZXNjcmlwdG9yUHJvdG86OnJlbGVhc2Vfb3V0cHV0X3R5cGUoKSB7CisgIGNsZWFyX2hhc19vdXRwdXRfdHlwZSgpOworICByZXR1cm4gb3V0cHV0X3R5cGVfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OnNldF9hbGxvY2F0ZWRfb3V0cHV0X3R5cGUoOjpzdGQ6OnN0cmluZyogb3V0cHV0X3R5cGUpIHsKKyAgaWYgKG91dHB1dF90eXBlICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX291dHB1dF90eXBlKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX291dHB1dF90eXBlKCk7CisgIH0KKyAgb3V0cHV0X3R5cGVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBvdXRwdXRfdHlwZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8ub3V0cHV0X3R5cGUpCit9CisKKy8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucyBvcHRpb25zID0gNDsKK2Jvb2wgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpoYXNfb3B0aW9ucygpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwOHUpICE9IDA7Cit9Cit2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19vcHRpb25zKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDh1OworfQordm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OmNsZWFyX2hhc19vcHRpb25zKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDA4dTsKK30KK3ZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpjbGVhcl9vcHRpb25zKCkgeworICBpZiAob3B0aW9uc18gIT0gTlVMTCkgb3B0aW9uc18tPjo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0aG9kT3B0aW9uczo6Q2xlYXIoKTsKKyAgY2xlYXJfaGFzX29wdGlvbnMoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0aG9kT3B0aW9ucyYgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpvcHRpb25zKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8ub3B0aW9ucykKKyAgcmV0dXJuIG9wdGlvbnNfICE9IE5VTEwgPyAqb3B0aW9uc18gOiAqZGVmYXVsdF9pbnN0YW5jZV8tPm9wdGlvbnNfOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpNZXRob2RPcHRpb25zKiBNZXRob2REZXNjcmlwdG9yUHJvdG86Om11dGFibGVfb3B0aW9ucygpIHsKKyAgc2V0X2hhc19vcHRpb25zKCk7CisgIGlmIChvcHRpb25zXyA9PSBOVUxMKSB7CisgICAgb3B0aW9uc18gPSBuZXcgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRob2RPcHRpb25zOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8ub3B0aW9ucykKKyAgcmV0dXJuIG9wdGlvbnNfOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpNZXRob2RPcHRpb25zKiBNZXRob2REZXNjcmlwdG9yUHJvdG86OnJlbGVhc2Vfb3B0aW9ucygpIHsKKyAgY2xlYXJfaGFzX29wdGlvbnMoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRob2RPcHRpb25zKiB0ZW1wID0gb3B0aW9uc187CisgIG9wdGlvbnNfID0gTlVMTDsKKyAgcmV0dXJuIHRlbXA7Cit9Cit2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6c2V0X2FsbG9jYXRlZF9vcHRpb25zKDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0aG9kT3B0aW9ucyogb3B0aW9ucykgeworICBkZWxldGUgb3B0aW9uc187CisgIG9wdGlvbnNfID0gb3B0aW9uczsKKyAgaWYgKG9wdGlvbnMpIHsKKyAgICBzZXRfaGFzX29wdGlvbnMoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfb3B0aW9ucygpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8ub3B0aW9ucykKK30KKworLy8gb3B0aW9uYWwgYm9vbCBjbGllbnRfc3RyZWFtaW5nID0gNSBbZGVmYXVsdCA9IGZhbHNlXTsKK2Jvb2wgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpoYXNfY2xpZW50X3N0cmVhbWluZygpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAxMHUpICE9IDA7Cit9Cit2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19jbGllbnRfc3RyZWFtaW5nKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMTB1OworfQordm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OmNsZWFyX2hhc19jbGllbnRfc3RyZWFtaW5nKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDEwdTsKK30KK3ZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpjbGVhcl9jbGllbnRfc3RyZWFtaW5nKCkgeworICBjbGllbnRfc3RyZWFtaW5nXyA9IGZhbHNlOworICBjbGVhcl9oYXNfY2xpZW50X3N0cmVhbWluZygpOworfQorIGJvb2wgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpjbGllbnRfc3RyZWFtaW5nKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8uY2xpZW50X3N0cmVhbWluZykKKyAgcmV0dXJuIGNsaWVudF9zdHJlYW1pbmdfOworfQorIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpzZXRfY2xpZW50X3N0cmVhbWluZyhib29sIHZhbHVlKSB7CisgIHNldF9oYXNfY2xpZW50X3N0cmVhbWluZygpOworICBjbGllbnRfc3RyZWFtaW5nXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8uY2xpZW50X3N0cmVhbWluZykKK30KKworLy8gb3B0aW9uYWwgYm9vbCBzZXJ2ZXJfc3RyZWFtaW5nID0gNiBbZGVmYXVsdCA9IGZhbHNlXTsKK2Jvb2wgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpoYXNfc2VydmVyX3N0cmVhbWluZygpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAyMHUpICE9IDA7Cit9Cit2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19zZXJ2ZXJfc3RyZWFtaW5nKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMjB1OworfQordm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OmNsZWFyX2hhc19zZXJ2ZXJfc3RyZWFtaW5nKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDIwdTsKK30KK3ZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpjbGVhcl9zZXJ2ZXJfc3RyZWFtaW5nKCkgeworICBzZXJ2ZXJfc3RyZWFtaW5nXyA9IGZhbHNlOworICBjbGVhcl9oYXNfc2VydmVyX3N0cmVhbWluZygpOworfQorIGJvb2wgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpzZXJ2ZXJfc3RyZWFtaW5nKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8uc2VydmVyX3N0cmVhbWluZykKKyAgcmV0dXJuIHNlcnZlcl9zdHJlYW1pbmdfOworfQorIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpzZXRfc2VydmVyX3N0cmVhbWluZyhib29sIHZhbHVlKSB7CisgIHNldF9oYXNfc2VydmVyX3N0cmVhbWluZygpOworICBzZXJ2ZXJfc3RyZWFtaW5nXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8uc2VydmVyX3N0cmVhbWluZykKK30KKworI2VuZGlmICAvLyBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yKiBGaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGVfZGVzY3JpcHRvcigpIHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIHJldHVybiBGaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGVfZGVzY3JpcHRvcl87Cit9Citib29sIEZpbGVPcHRpb25zX09wdGltaXplTW9kZV9Jc1ZhbGlkKGludCB2YWx1ZSkgeworICBzd2l0Y2godmFsdWUpIHsKKyAgICBjYXNlIDE6CisgICAgY2FzZSAyOgorICAgIGNhc2UgMzoKKyAgICAgIHJldHVybiB0cnVlOworICAgIGRlZmF1bHQ6CisgICAgICByZXR1cm4gZmFsc2U7CisgIH0KK30KKworI2lmICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCitjb25zdCBGaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGUgRmlsZU9wdGlvbnM6OlNQRUVEOworY29uc3QgRmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlIEZpbGVPcHRpb25zOjpDT0RFX1NJWkU7Citjb25zdCBGaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGUgRmlsZU9wdGlvbnM6OkxJVEVfUlVOVElNRTsKK2NvbnN0IEZpbGVPcHRpb25zX09wdGltaXplTW9kZSBGaWxlT3B0aW9uczo6T3B0aW1pemVNb2RlX01JTjsKK2NvbnN0IEZpbGVPcHRpb25zX09wdGltaXplTW9kZSBGaWxlT3B0aW9uczo6T3B0aW1pemVNb2RlX01BWDsKK2NvbnN0IGludCBGaWxlT3B0aW9uczo6T3B0aW1pemVNb2RlX0FSUkFZU0laRTsKKyNlbmRpZiAgLy8gIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKKyNpZiAhZGVmaW5lZChfTVNDX1ZFUikgfHwgX01TQ19WRVIgPj0gMTkwMAorY29uc3QgaW50IEZpbGVPcHRpb25zOjprSmF2YVBhY2thZ2VGaWVsZE51bWJlcjsKK2NvbnN0IGludCBGaWxlT3B0aW9uczo6a0phdmFPdXRlckNsYXNzbmFtZUZpZWxkTnVtYmVyOworY29uc3QgaW50IEZpbGVPcHRpb25zOjprSmF2YU11bHRpcGxlRmlsZXNGaWVsZE51bWJlcjsKK2NvbnN0IGludCBGaWxlT3B0aW9uczo6a0phdmFHZW5lcmF0ZUVxdWFsc0FuZEhhc2hGaWVsZE51bWJlcjsKK2NvbnN0IGludCBGaWxlT3B0aW9uczo6a0phdmFTdHJpbmdDaGVja1V0ZjhGaWVsZE51bWJlcjsKK2NvbnN0IGludCBGaWxlT3B0aW9uczo6a09wdGltaXplRm9yRmllbGROdW1iZXI7Citjb25zdCBpbnQgRmlsZU9wdGlvbnM6OmtHb1BhY2thZ2VGaWVsZE51bWJlcjsKK2NvbnN0IGludCBGaWxlT3B0aW9uczo6a0NjR2VuZXJpY1NlcnZpY2VzRmllbGROdW1iZXI7Citjb25zdCBpbnQgRmlsZU9wdGlvbnM6OmtKYXZhR2VuZXJpY1NlcnZpY2VzRmllbGROdW1iZXI7Citjb25zdCBpbnQgRmlsZU9wdGlvbnM6OmtQeUdlbmVyaWNTZXJ2aWNlc0ZpZWxkTnVtYmVyOworY29uc3QgaW50IEZpbGVPcHRpb25zOjprRGVwcmVjYXRlZEZpZWxkTnVtYmVyOworY29uc3QgaW50IEZpbGVPcHRpb25zOjprQ2NFbmFibGVBcmVuYXNGaWVsZE51bWJlcjsKK2NvbnN0IGludCBGaWxlT3B0aW9uczo6a09iamNDbGFzc1ByZWZpeEZpZWxkTnVtYmVyOworY29uc3QgaW50IEZpbGVPcHRpb25zOjprQ3NoYXJwTmFtZXNwYWNlRmllbGROdW1iZXI7Citjb25zdCBpbnQgRmlsZU9wdGlvbnM6OmtKYXZhbmFub1VzZURlcHJlY2F0ZWRQYWNrYWdlRmllbGROdW1iZXI7Citjb25zdCBpbnQgRmlsZU9wdGlvbnM6OmtVbmludGVycHJldGVkT3B0aW9uRmllbGROdW1iZXI7CisjZW5kaWYgIC8vICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCisKK0ZpbGVPcHRpb25zOjpGaWxlT3B0aW9ucygpCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgeworICBTaGFyZWRDdG9yKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMpCit9CisKK3ZvaWQgRmlsZU9wdGlvbnM6OkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpIHsKK30KKworRmlsZU9wdGlvbnM6OkZpbGVPcHRpb25zKGNvbnN0IEZpbGVPcHRpb25zJiBmcm9tKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpLAorICAgIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgeworICBTaGFyZWRDdG9yKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvcHlfY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zKQorfQorCit2b2lkIEZpbGVPcHRpb25zOjpTaGFyZWRDdG9yKCkgeworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZygpOworICBfY2FjaGVkX3NpemVfID0gMDsKKyAgamF2YV9wYWNrYWdlXy5VbnNhZmVTZXREZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGphdmFfb3V0ZXJfY2xhc3NuYW1lXy5VbnNhZmVTZXREZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGphdmFfbXVsdGlwbGVfZmlsZXNfID0gZmFsc2U7CisgIGphdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoXyA9IGZhbHNlOworICBqYXZhX3N0cmluZ19jaGVja191dGY4XyA9IGZhbHNlOworICBvcHRpbWl6ZV9mb3JfID0gMTsKKyAgZ29fcGFja2FnZV8uVW5zYWZlU2V0RGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjY19nZW5lcmljX3NlcnZpY2VzXyA9IGZhbHNlOworICBqYXZhX2dlbmVyaWNfc2VydmljZXNfID0gZmFsc2U7CisgIHB5X2dlbmVyaWNfc2VydmljZXNfID0gZmFsc2U7CisgIGRlcHJlY2F0ZWRfID0gZmFsc2U7CisgIGNjX2VuYWJsZV9hcmVuYXNfID0gZmFsc2U7CisgIG9iamNfY2xhc3NfcHJlZml4Xy5VbnNhZmVTZXREZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGNzaGFycF9uYW1lc3BhY2VfLlVuc2FmZVNldERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgamF2YW5hbm9fdXNlX2RlcHJlY2F0ZWRfcGFja2FnZV8gPSBmYWxzZTsKKyAgOjptZW1zZXQoX2hhc19iaXRzXywgMCwgc2l6ZW9mKF9oYXNfYml0c18pKTsKK30KKworRmlsZU9wdGlvbnM6On5GaWxlT3B0aW9ucygpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGRlc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zKQorICBTaGFyZWREdG9yKCk7Cit9CisKK3ZvaWQgRmlsZU9wdGlvbnM6OlNoYXJlZER0b3IoKSB7CisgIGphdmFfcGFja2FnZV8uRGVzdHJveU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgamF2YV9vdXRlcl9jbGFzc25hbWVfLkRlc3Ryb3lOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGdvX3BhY2thZ2VfLkRlc3Ryb3lOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIG9iamNfY2xhc3NfcHJlZml4Xy5EZXN0cm95Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjc2hhcnBfbmFtZXNwYWNlXy5EZXN0cm95Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBpZiAodGhpcyAhPSBkZWZhdWx0X2luc3RhbmNlXykgeworICB9Cit9CisKK3ZvaWQgRmlsZU9wdGlvbnM6OlNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0IHsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHNpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBGaWxlT3B0aW9uczo6ZGVzY3JpcHRvcigpIHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIHJldHVybiBGaWxlT3B0aW9uc19kZXNjcmlwdG9yXzsKK30KKworY29uc3QgRmlsZU9wdGlvbnMmIEZpbGVPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlKCkgeworICBpZiAoZGVmYXVsdF9pbnN0YW5jZV8gPT0gTlVMTCkgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICByZXR1cm4gKmRlZmF1bHRfaW5zdGFuY2VfOworfQorCitGaWxlT3B0aW9ucyogRmlsZU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2VfID0gTlVMTDsKKworRmlsZU9wdGlvbnMqIEZpbGVPcHRpb25zOjpOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0IHsKKyAgRmlsZU9wdGlvbnMqIG4gPSBuZXcgRmlsZU9wdGlvbnM7CisgIGlmIChhcmVuYSAhPSBOVUxMKSB7CisgICAgYXJlbmEtPk93bihuKTsKKyAgfQorICByZXR1cm4gbjsKK30KKwordm9pZCBGaWxlT3B0aW9uczo6Q2xlYXIoKSB7CisgIF9leHRlbnNpb25zXy5DbGVhcigpOworI2RlZmluZSBaUl9IRUxQRVJfKGYpIHJlaW50ZXJwcmV0X2Nhc3Q8Y2hhcio+KFwKKyAgJnJlaW50ZXJwcmV0X2Nhc3Q8RmlsZU9wdGlvbnMqPigxNiktPmYpCisKKyNkZWZpbmUgWlJfKGZpcnN0LCBsYXN0KSBkbyB7XAorICA6Om1lbXNldCgmZmlyc3QsIDAsXAorICAgICAgICAgICBaUl9IRUxQRVJfKGxhc3QpIC0gWlJfSEVMUEVSXyhmaXJzdCkgKyBzaXplb2YobGFzdCkpO1wKK30gd2hpbGUgKDApCisKKyAgaWYgKF9oYXNfYml0c19bMCAvIDMyXSAmIDI1NXUpIHsKKyAgICBaUl8oamF2YV9tdWx0aXBsZV9maWxlc18sIGNjX2dlbmVyaWNfc2VydmljZXNfKTsKKyAgICBpZiAoaGFzX2phdmFfcGFja2FnZSgpKSB7CisgICAgICBqYXZhX3BhY2thZ2VfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgICB9CisgICAgaWYgKGhhc19qYXZhX291dGVyX2NsYXNzbmFtZSgpKSB7CisgICAgICBqYXZhX291dGVyX2NsYXNzbmFtZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICAgIH0KKyAgICBvcHRpbWl6ZV9mb3JfID0gMTsKKyAgICBpZiAoaGFzX2dvX3BhY2thZ2UoKSkgeworICAgICAgZ29fcGFja2FnZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICAgIH0KKyAgfQorICBpZiAoX2hhc19iaXRzX1s4IC8gMzJdICYgMzI1MTJ1KSB7CisgICAgWlJfKGphdmFfZ2VuZXJpY19zZXJ2aWNlc18sIGphdmFuYW5vX3VzZV9kZXByZWNhdGVkX3BhY2thZ2VfKTsKKyAgICBpZiAoaGFzX29iamNfY2xhc3NfcHJlZml4KCkpIHsKKyAgICAgIG9iamNfY2xhc3NfcHJlZml4Xy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgICAgfQorICAgIGlmIChoYXNfY3NoYXJwX25hbWVzcGFjZSgpKSB7CisgICAgICBjc2hhcnBfbmFtZXNwYWNlXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgICAgfQorICB9CisKKyN1bmRlZiBaUl9IRUxQRVJfCisjdW5kZWYgWlJfCisKKyAgdW5pbnRlcnByZXRlZF9vcHRpb25fLkNsZWFyKCk7CisgIDo6bWVtc2V0KF9oYXNfYml0c18sIDAsIHNpemVvZihfaGFzX2JpdHNfKSk7CisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+Q2xlYXIoKTsKKyAgfQorfQorCitib29sIEZpbGVPcHRpb25zOjpNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyNkZWZpbmUgRE9fKEVYUFJFU1NJT04pIGlmICghKEVYUFJFU1NJT04pKSBnb3RvIGZhaWx1cmUKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgdGFnOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zKQorICBmb3IgKDs7KSB7CisgICAgOjpzdGQ6OnBhaXI8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyLCBib29sPiBwID0gaW5wdXQtPlJlYWRUYWdXaXRoQ3V0b2ZmKDE2MzgzKTsKKyAgICB0YWcgPSBwLmZpcnN0OworICAgIGlmICghcC5zZWNvbmQpIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgc3dpdGNoICg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnRmllbGROdW1iZXIodGFnKSkgeworICAgICAgLy8gb3B0aW9uYWwgc3RyaW5nIGphdmFfcGFja2FnZSA9IDE7CisgICAgICBjYXNlIDE6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAxMCkgeworICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFN0cmluZygKKyAgICAgICAgICAgICAgICBpbnB1dCwgdGhpcy0+bXV0YWJsZV9qYXZhX3BhY2thZ2UoKSkpOworICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgICAgICAgdGhpcy0+amF2YV9wYWNrYWdlKCkuZGF0YSgpLCB0aGlzLT5qYXZhX3BhY2thZ2UoKS5sZW5ndGgoKSwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlBBUlNFLAorICAgICAgICAgICAgImdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5qYXZhX3BhY2thZ2UiKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDY2KSkgZ290byBwYXJzZV9qYXZhX291dGVyX2NsYXNzbmFtZTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIHN0cmluZyBqYXZhX291dGVyX2NsYXNzbmFtZSA9IDg7CisgICAgICBjYXNlIDg6IHsKKyAgICAgICAgaWYgKHRhZyA9PSA2NikgeworICAgICAgICAgcGFyc2VfamF2YV9vdXRlcl9jbGFzc25hbWU6CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkU3RyaW5nKAorICAgICAgICAgICAgICAgIGlucHV0LCB0aGlzLT5tdXRhYmxlX2phdmFfb3V0ZXJfY2xhc3NuYW1lKCkpKTsKKyAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgICAgICAgIHRoaXMtPmphdmFfb3V0ZXJfY2xhc3NuYW1lKCkuZGF0YSgpLCB0aGlzLT5qYXZhX291dGVyX2NsYXNzbmFtZSgpLmxlbmd0aCgpLAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6UEFSU0UsCisgICAgICAgICAgICAiZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmphdmFfb3V0ZXJfY2xhc3NuYW1lIik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg3MikpIGdvdG8gcGFyc2Vfb3B0aW1pemVfZm9yOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5PcHRpbWl6ZU1vZGUgb3B0aW1pemVfZm9yID0gOSBbZGVmYXVsdCA9IFNQRUVEXTsKKyAgICAgIGNhc2UgOTogeworICAgICAgICBpZiAodGFnID09IDcyKSB7CisgICAgICAgICBwYXJzZV9vcHRpbWl6ZV9mb3I6CisgICAgICAgICAgaW50IHZhbHVlOworICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgaW50LCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9FTlVNPigKKyAgICAgICAgICAgICAgICAgaW5wdXQsICZ2YWx1ZSkpKTsKKyAgICAgICAgICBpZiAoOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGVfSXNWYWxpZCh2YWx1ZSkpIHsKKyAgICAgICAgICAgIHNldF9vcHRpbWl6ZV9mb3Ioc3RhdGljX2Nhc3Q8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlID4odmFsdWUpKTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5BZGRWYXJpbnQoOSwgdmFsdWUpOworICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDgwKSkgZ290byBwYXJzZV9qYXZhX211bHRpcGxlX2ZpbGVzOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgYm9vbCBqYXZhX211bHRpcGxlX2ZpbGVzID0gMTAgW2RlZmF1bHQgPSBmYWxzZV07CisgICAgICBjYXNlIDEwOiB7CisgICAgICAgIGlmICh0YWcgPT0gODApIHsKKyAgICAgICAgIHBhcnNlX2phdmFfbXVsdGlwbGVfZmlsZXM6CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICBib29sLCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9CT09MPigKKyAgICAgICAgICAgICAgICAgaW5wdXQsICZqYXZhX211bHRpcGxlX2ZpbGVzXykpKTsKKyAgICAgICAgICBzZXRfaGFzX2phdmFfbXVsdGlwbGVfZmlsZXMoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDkwKSkgZ290byBwYXJzZV9nb19wYWNrYWdlOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgc3RyaW5nIGdvX3BhY2thZ2UgPSAxMTsKKyAgICAgIGNhc2UgMTE6IHsKKyAgICAgICAgaWYgKHRhZyA9PSA5MCkgeworICAgICAgICAgcGFyc2VfZ29fcGFja2FnZToKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoCisgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPm11dGFibGVfZ29fcGFja2FnZSgpKSk7CisgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICAgICAgICB0aGlzLT5nb19wYWNrYWdlKCkuZGF0YSgpLCB0aGlzLT5nb19wYWNrYWdlKCkubGVuZ3RoKCksCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpQQVJTRSwKKyAgICAgICAgICAgICJnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuZ29fcGFja2FnZSIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMTI4KSkgZ290byBwYXJzZV9jY19nZW5lcmljX3NlcnZpY2VzOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgYm9vbCBjY19nZW5lcmljX3NlcnZpY2VzID0gMTYgW2RlZmF1bHQgPSBmYWxzZV07CisgICAgICBjYXNlIDE2OiB7CisgICAgICAgIGlmICh0YWcgPT0gMTI4KSB7CisgICAgICAgICBwYXJzZV9jY19nZW5lcmljX3NlcnZpY2VzOgorICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgYm9vbCwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfQk9PTD4oCisgICAgICAgICAgICAgICAgIGlucHV0LCAmY2NfZ2VuZXJpY19zZXJ2aWNlc18pKSk7CisgICAgICAgICAgc2V0X2hhc19jY19nZW5lcmljX3NlcnZpY2VzKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygxMzYpKSBnb3RvIHBhcnNlX2phdmFfZ2VuZXJpY19zZXJ2aWNlczsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIGJvb2wgamF2YV9nZW5lcmljX3NlcnZpY2VzID0gMTcgW2RlZmF1bHQgPSBmYWxzZV07CisgICAgICBjYXNlIDE3OiB7CisgICAgICAgIGlmICh0YWcgPT0gMTM2KSB7CisgICAgICAgICBwYXJzZV9qYXZhX2dlbmVyaWNfc2VydmljZXM6CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICBib29sLCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9CT09MPigKKyAgICAgICAgICAgICAgICAgaW5wdXQsICZqYXZhX2dlbmVyaWNfc2VydmljZXNfKSkpOworICAgICAgICAgIHNldF9oYXNfamF2YV9nZW5lcmljX3NlcnZpY2VzKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygxNDQpKSBnb3RvIHBhcnNlX3B5X2dlbmVyaWNfc2VydmljZXM7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCBib29sIHB5X2dlbmVyaWNfc2VydmljZXMgPSAxOCBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgICAgIGNhc2UgMTg6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAxNDQpIHsKKyAgICAgICAgIHBhcnNlX3B5X2dlbmVyaWNfc2VydmljZXM6CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICBib29sLCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9CT09MPigKKyAgICAgICAgICAgICAgICAgaW5wdXQsICZweV9nZW5lcmljX3NlcnZpY2VzXykpKTsKKyAgICAgICAgICBzZXRfaGFzX3B5X2dlbmVyaWNfc2VydmljZXMoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDE2MCkpIGdvdG8gcGFyc2VfamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2g7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCBib29sIGphdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoID0gMjAgW2RlZmF1bHQgPSBmYWxzZV07CisgICAgICBjYXNlIDIwOiB7CisgICAgICAgIGlmICh0YWcgPT0gMTYwKSB7CisgICAgICAgICBwYXJzZV9qYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaDoKKyAgICAgICAgICBET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPAorICAgICAgICAgICAgICAgICAgIGJvb2wsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0JPT0w+KAorICAgICAgICAgICAgICAgICBpbnB1dCwgJmphdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoXykpKTsKKyAgICAgICAgICBzZXRfaGFzX2phdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygxODQpKSBnb3RvIHBhcnNlX2RlcHJlY2F0ZWQ7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCBib29sIGRlcHJlY2F0ZWQgPSAyMyBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgICAgIGNhc2UgMjM6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAxODQpIHsKKyAgICAgICAgIHBhcnNlX2RlcHJlY2F0ZWQ6CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICBib29sLCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9CT09MPigKKyAgICAgICAgICAgICAgICAgaW5wdXQsICZkZXByZWNhdGVkXykpKTsKKyAgICAgICAgICBzZXRfaGFzX2RlcHJlY2F0ZWQoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDIxNikpIGdvdG8gcGFyc2VfamF2YV9zdHJpbmdfY2hlY2tfdXRmODsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIGJvb2wgamF2YV9zdHJpbmdfY2hlY2tfdXRmOCA9IDI3IFtkZWZhdWx0ID0gZmFsc2VdOworICAgICAgY2FzZSAyNzogeworICAgICAgICBpZiAodGFnID09IDIxNikgeworICAgICAgICAgcGFyc2VfamF2YV9zdHJpbmdfY2hlY2tfdXRmODoKKyAgICAgICAgICBET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPAorICAgICAgICAgICAgICAgICAgIGJvb2wsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0JPT0w+KAorICAgICAgICAgICAgICAgICBpbnB1dCwgJmphdmFfc3RyaW5nX2NoZWNrX3V0ZjhfKSkpOworICAgICAgICAgIHNldF9oYXNfamF2YV9zdHJpbmdfY2hlY2tfdXRmOCgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMjQ4KSkgZ290byBwYXJzZV9jY19lbmFibGVfYXJlbmFzOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgYm9vbCBjY19lbmFibGVfYXJlbmFzID0gMzEgW2RlZmF1bHQgPSBmYWxzZV07CisgICAgICBjYXNlIDMxOiB7CisgICAgICAgIGlmICh0YWcgPT0gMjQ4KSB7CisgICAgICAgICBwYXJzZV9jY19lbmFibGVfYXJlbmFzOgorICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgYm9vbCwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfQk9PTD4oCisgICAgICAgICAgICAgICAgIGlucHV0LCAmY2NfZW5hYmxlX2FyZW5hc18pKSk7CisgICAgICAgICAgc2V0X2hhc19jY19lbmFibGVfYXJlbmFzKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygyOTApKSBnb3RvIHBhcnNlX29iamNfY2xhc3NfcHJlZml4OworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgc3RyaW5nIG9iamNfY2xhc3NfcHJlZml4ID0gMzY7CisgICAgICBjYXNlIDM2OiB7CisgICAgICAgIGlmICh0YWcgPT0gMjkwKSB7CisgICAgICAgICBwYXJzZV9vYmpjX2NsYXNzX3ByZWZpeDoKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoCisgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPm11dGFibGVfb2JqY19jbGFzc19wcmVmaXgoKSkpOworICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgICAgICAgdGhpcy0+b2JqY19jbGFzc19wcmVmaXgoKS5kYXRhKCksIHRoaXMtPm9iamNfY2xhc3NfcHJlZml4KCkubGVuZ3RoKCksCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpQQVJTRSwKKyAgICAgICAgICAgICJnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMub2JqY19jbGFzc19wcmVmaXgiKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDI5OCkpIGdvdG8gcGFyc2VfY3NoYXJwX25hbWVzcGFjZTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIHN0cmluZyBjc2hhcnBfbmFtZXNwYWNlID0gMzc7CisgICAgICBjYXNlIDM3OiB7CisgICAgICAgIGlmICh0YWcgPT0gMjk4KSB7CisgICAgICAgICBwYXJzZV9jc2hhcnBfbmFtZXNwYWNlOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFN0cmluZygKKyAgICAgICAgICAgICAgICBpbnB1dCwgdGhpcy0+bXV0YWJsZV9jc2hhcnBfbmFtZXNwYWNlKCkpKTsKKyAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgICAgICAgIHRoaXMtPmNzaGFycF9uYW1lc3BhY2UoKS5kYXRhKCksIHRoaXMtPmNzaGFycF9uYW1lc3BhY2UoKS5sZW5ndGgoKSwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlBBUlNFLAorICAgICAgICAgICAgImdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5jc2hhcnBfbmFtZXNwYWNlIik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygzMDQpKSBnb3RvIHBhcnNlX2phdmFuYW5vX3VzZV9kZXByZWNhdGVkX3BhY2thZ2U7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCBib29sIGphdmFuYW5vX3VzZV9kZXByZWNhdGVkX3BhY2thZ2UgPSAzOCBbZGVwcmVjYXRlZCA9IHRydWVdOworICAgICAgY2FzZSAzODogeworICAgICAgICBpZiAodGFnID09IDMwNCkgeworICAgICAgICAgcGFyc2VfamF2YW5hbm9fdXNlX2RlcHJlY2F0ZWRfcGFja2FnZToKKyAgICAgICAgICBET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPAorICAgICAgICAgICAgICAgICAgIGJvb2wsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0JPT0w+KAorICAgICAgICAgICAgICAgICBpbnB1dCwgJmphdmFuYW5vX3VzZV9kZXByZWNhdGVkX3BhY2thZ2VfKSkpOworICAgICAgICAgIHNldF9oYXNfamF2YW5hbm9fdXNlX2RlcHJlY2F0ZWRfcGFja2FnZSgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNzk5NCkpIGdvdG8gcGFyc2VfdW5pbnRlcnByZXRlZF9vcHRpb247CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CisgICAgICBjYXNlIDk5OTogeworICAgICAgICBpZiAodGFnID09IDc5OTQpIHsKKyAgICAgICAgIHBhcnNlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uOgorICAgICAgICAgIERPXyhpbnB1dC0+SW5jcmVtZW50UmVjdXJzaW9uRGVwdGgoKSk7CisgICAgICAgICBwYXJzZV9sb29wX3VuaW50ZXJwcmV0ZWRfb3B0aW9uOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZE1lc3NhZ2VOb1ZpcnR1YWxOb1JlY3Vyc2lvbkRlcHRoKAorICAgICAgICAgICAgICAgIGlucHV0LCBhZGRfdW5pbnRlcnByZXRlZF9vcHRpb24oKSkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNzk5NCkpIGdvdG8gcGFyc2VfbG9vcF91bmludGVycHJldGVkX29wdGlvbjsKKyAgICAgICAgaW5wdXQtPlVuc2FmZURlY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCk7CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0QXRFbmQoKSkgZ290byBzdWNjZXNzOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgZGVmYXVsdDogeworICAgICAgaGFuZGxlX3VudXN1YWw6CisgICAgICAgIGlmICh0YWcgPT0gMCB8fAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ1dpcmVUeXBlKHRhZykgPT0KKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVApIHsKKyAgICAgICAgICBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCg4MDAwdSA8PSB0YWcpKSB7CisgICAgICAgICAgRE9fKF9leHRlbnNpb25zXy5QYXJzZUZpZWxkKHRhZywgaW5wdXQsIGRlZmF1bHRfaW5zdGFuY2VfLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkpKTsKKyAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2tpcEZpZWxkKAorICAgICAgICAgICAgICBpbnB1dCwgdGFnLCBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CitzdWNjZXNzOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3VjY2Vzczpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMpCisgIHJldHVybiB0cnVlOworZmFpbHVyZToKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX2ZhaWx1cmU6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zKQorICByZXR1cm4gZmFsc2U7CisjdW5kZWYgRE9fCit9CisKK3ZvaWQgRmlsZU9wdGlvbnM6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zKQorICAvLyBvcHRpb25hbCBzdHJpbmcgamF2YV9wYWNrYWdlID0gMTsKKyAgaWYgKGhhc19qYXZhX3BhY2thZ2UoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+amF2YV9wYWNrYWdlKCkuZGF0YSgpLCB0aGlzLT5qYXZhX3BhY2thZ2UoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuamF2YV9wYWNrYWdlIik7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nTWF5YmVBbGlhc2VkKAorICAgICAgMSwgdGhpcy0+amF2YV9wYWNrYWdlKCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgamF2YV9vdXRlcl9jbGFzc25hbWUgPSA4OworICBpZiAoaGFzX2phdmFfb3V0ZXJfY2xhc3NuYW1lKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgIHRoaXMtPmphdmFfb3V0ZXJfY2xhc3NuYW1lKCkuZGF0YSgpLCB0aGlzLT5qYXZhX291dGVyX2NsYXNzbmFtZSgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5qYXZhX291dGVyX2NsYXNzbmFtZSIpOworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ01heWJlQWxpYXNlZCgKKyAgICAgIDgsIHRoaXMtPmphdmFfb3V0ZXJfY2xhc3NuYW1lKCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLk9wdGltaXplTW9kZSBvcHRpbWl6ZV9mb3IgPSA5IFtkZWZhdWx0ID0gU1BFRURdOworICBpZiAoaGFzX29wdGltaXplX2ZvcigpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlRW51bSgKKyAgICAgIDksIHRoaXMtPm9wdGltaXplX2ZvcigpLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgYm9vbCBqYXZhX211bHRpcGxlX2ZpbGVzID0gMTAgW2RlZmF1bHQgPSBmYWxzZV07CisgIGlmIChoYXNfamF2YV9tdWx0aXBsZV9maWxlcygpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlQm9vbCgxMCwgdGhpcy0+amF2YV9tdWx0aXBsZV9maWxlcygpLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIGdvX3BhY2thZ2UgPSAxMTsKKyAgaWYgKGhhc19nb19wYWNrYWdlKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgIHRoaXMtPmdvX3BhY2thZ2UoKS5kYXRhKCksIHRoaXMtPmdvX3BhY2thZ2UoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuZ29fcGFja2FnZSIpOworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ01heWJlQWxpYXNlZCgKKyAgICAgIDExLCB0aGlzLT5nb19wYWNrYWdlKCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBib29sIGNjX2dlbmVyaWNfc2VydmljZXMgPSAxNiBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgaWYgKGhhc19jY19nZW5lcmljX3NlcnZpY2VzKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCb29sKDE2LCB0aGlzLT5jY19nZW5lcmljX3NlcnZpY2VzKCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBib29sIGphdmFfZ2VuZXJpY19zZXJ2aWNlcyA9IDE3IFtkZWZhdWx0ID0gZmFsc2VdOworICBpZiAoaGFzX2phdmFfZ2VuZXJpY19zZXJ2aWNlcygpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlQm9vbCgxNywgdGhpcy0+amF2YV9nZW5lcmljX3NlcnZpY2VzKCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBib29sIHB5X2dlbmVyaWNfc2VydmljZXMgPSAxOCBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgaWYgKGhhc19weV9nZW5lcmljX3NlcnZpY2VzKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCb29sKDE4LCB0aGlzLT5weV9nZW5lcmljX3NlcnZpY2VzKCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBib29sIGphdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoID0gMjAgW2RlZmF1bHQgPSBmYWxzZV07CisgIGlmIChoYXNfamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2goKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2woMjAsIHRoaXMtPmphdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoKCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBib29sIGRlcHJlY2F0ZWQgPSAyMyBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgaWYgKGhhc19kZXByZWNhdGVkKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCb29sKDIzLCB0aGlzLT5kZXByZWNhdGVkKCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBib29sIGphdmFfc3RyaW5nX2NoZWNrX3V0ZjggPSAyNyBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgaWYgKGhhc19qYXZhX3N0cmluZ19jaGVja191dGY4KCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCb29sKDI3LCB0aGlzLT5qYXZhX3N0cmluZ19jaGVja191dGY4KCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBib29sIGNjX2VuYWJsZV9hcmVuYXMgPSAzMSBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgaWYgKGhhc19jY19lbmFibGVfYXJlbmFzKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCb29sKDMxLCB0aGlzLT5jY19lbmFibGVfYXJlbmFzKCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgb2JqY19jbGFzc19wcmVmaXggPSAzNjsKKyAgaWYgKGhhc19vYmpjX2NsYXNzX3ByZWZpeCgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5vYmpjX2NsYXNzX3ByZWZpeCgpLmRhdGEoKSwgdGhpcy0+b2JqY19jbGFzc19wcmVmaXgoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMub2JqY19jbGFzc19wcmVmaXgiKTsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdNYXliZUFsaWFzZWQoCisgICAgICAzNiwgdGhpcy0+b2JqY19jbGFzc19wcmVmaXgoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIHN0cmluZyBjc2hhcnBfbmFtZXNwYWNlID0gMzc7CisgIGlmIChoYXNfY3NoYXJwX25hbWVzcGFjZSgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5jc2hhcnBfbmFtZXNwYWNlKCkuZGF0YSgpLCB0aGlzLT5jc2hhcnBfbmFtZXNwYWNlKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmNzaGFycF9uYW1lc3BhY2UiKTsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdNYXliZUFsaWFzZWQoCisgICAgICAzNywgdGhpcy0+Y3NoYXJwX25hbWVzcGFjZSgpLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgYm9vbCBqYXZhbmFub191c2VfZGVwcmVjYXRlZF9wYWNrYWdlID0gMzggW2RlcHJlY2F0ZWQgPSB0cnVlXTsKKyAgaWYgKGhhc19qYXZhbmFub191c2VfZGVwcmVjYXRlZF9wYWNrYWdlKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCb29sKDM4LCB0aGlzLT5qYXZhbmFub191c2VfZGVwcmVjYXRlZF9wYWNrYWdlKCksIG91dHB1dCk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CisgIGZvciAodW5zaWduZWQgaW50IGkgPSAwLCBuID0gdGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb25fc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlTWVzc2FnZU1heWJlVG9BcnJheSgKKyAgICAgIDk5OSwgdGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb24oaSksIG91dHB1dCk7CisgIH0KKworICAvLyBFeHRlbnNpb24gcmFuZ2UgWzEwMDAsIDUzNjg3MDkxMikKKyAgX2V4dGVuc2lvbnNfLlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICAgIDEwMDAsIDUzNjg3MDkxMiwgb3V0cHV0KTsKKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTZXJpYWxpemVVbmtub3duRmllbGRzKAorICAgICAgICB1bmtub3duX2ZpZWxkcygpLCBvdXRwdXQpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfZW5kOmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucykKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogRmlsZU9wdGlvbnM6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogdGFyZ2V0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zKQorICAvLyBvcHRpb25hbCBzdHJpbmcgamF2YV9wYWNrYWdlID0gMTsKKyAgaWYgKGhhc19qYXZhX3BhY2thZ2UoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+amF2YV9wYWNrYWdlKCkuZGF0YSgpLCB0aGlzLT5qYXZhX3BhY2thZ2UoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuamF2YV9wYWNrYWdlIik7CisgICAgdGFyZ2V0ID0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ1RvQXJyYXkoCisgICAgICAgIDEsIHRoaXMtPmphdmFfcGFja2FnZSgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIGphdmFfb3V0ZXJfY2xhc3NuYW1lID0gODsKKyAgaWYgKGhhc19qYXZhX291dGVyX2NsYXNzbmFtZSgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5qYXZhX291dGVyX2NsYXNzbmFtZSgpLmRhdGEoKSwgdGhpcy0+amF2YV9vdXRlcl9jbGFzc25hbWUoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuamF2YV9vdXRlcl9jbGFzc25hbWUiKTsKKyAgICB0YXJnZXQgPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nVG9BcnJheSgKKyAgICAgICAgOCwgdGhpcy0+amF2YV9vdXRlcl9jbGFzc25hbWUoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuT3B0aW1pemVNb2RlIG9wdGltaXplX2ZvciA9IDkgW2RlZmF1bHQgPSBTUEVFRF07CisgIGlmIChoYXNfb3B0aW1pemVfZm9yKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVFbnVtVG9BcnJheSgKKyAgICAgIDksIHRoaXMtPm9wdGltaXplX2ZvcigpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgYm9vbCBqYXZhX211bHRpcGxlX2ZpbGVzID0gMTAgW2RlZmF1bHQgPSBmYWxzZV07CisgIGlmIChoYXNfamF2YV9tdWx0aXBsZV9maWxlcygpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlQm9vbFRvQXJyYXkoMTAsIHRoaXMtPmphdmFfbXVsdGlwbGVfZmlsZXMoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIHN0cmluZyBnb19wYWNrYWdlID0gMTE7CisgIGlmIChoYXNfZ29fcGFja2FnZSgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5nb19wYWNrYWdlKCkuZGF0YSgpLCB0aGlzLT5nb19wYWNrYWdlKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmdvX3BhY2thZ2UiKTsKKyAgICB0YXJnZXQgPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nVG9BcnJheSgKKyAgICAgICAgMTEsIHRoaXMtPmdvX3BhY2thZ2UoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGJvb2wgY2NfZ2VuZXJpY19zZXJ2aWNlcyA9IDE2IFtkZWZhdWx0ID0gZmFsc2VdOworICBpZiAoaGFzX2NjX2dlbmVyaWNfc2VydmljZXMoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2xUb0FycmF5KDE2LCB0aGlzLT5jY19nZW5lcmljX3NlcnZpY2VzKCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBib29sIGphdmFfZ2VuZXJpY19zZXJ2aWNlcyA9IDE3IFtkZWZhdWx0ID0gZmFsc2VdOworICBpZiAoaGFzX2phdmFfZ2VuZXJpY19zZXJ2aWNlcygpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlQm9vbFRvQXJyYXkoMTcsIHRoaXMtPmphdmFfZ2VuZXJpY19zZXJ2aWNlcygpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgYm9vbCBweV9nZW5lcmljX3NlcnZpY2VzID0gMTggW2RlZmF1bHQgPSBmYWxzZV07CisgIGlmIChoYXNfcHlfZ2VuZXJpY19zZXJ2aWNlcygpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlQm9vbFRvQXJyYXkoMTgsIHRoaXMtPnB5X2dlbmVyaWNfc2VydmljZXMoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGJvb2wgamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2ggPSAyMCBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgaWYgKGhhc19qYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaCgpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlQm9vbFRvQXJyYXkoMjAsIHRoaXMtPmphdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoKCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBib29sIGRlcHJlY2F0ZWQgPSAyMyBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgaWYgKGhhc19kZXByZWNhdGVkKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCb29sVG9BcnJheSgyMywgdGhpcy0+ZGVwcmVjYXRlZCgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgYm9vbCBqYXZhX3N0cmluZ19jaGVja191dGY4ID0gMjcgW2RlZmF1bHQgPSBmYWxzZV07CisgIGlmIChoYXNfamF2YV9zdHJpbmdfY2hlY2tfdXRmOCgpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlQm9vbFRvQXJyYXkoMjcsIHRoaXMtPmphdmFfc3RyaW5nX2NoZWNrX3V0ZjgoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGJvb2wgY2NfZW5hYmxlX2FyZW5hcyA9IDMxIFtkZWZhdWx0ID0gZmFsc2VdOworICBpZiAoaGFzX2NjX2VuYWJsZV9hcmVuYXMoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2xUb0FycmF5KDMxLCB0aGlzLT5jY19lbmFibGVfYXJlbmFzKCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgb2JqY19jbGFzc19wcmVmaXggPSAzNjsKKyAgaWYgKGhhc19vYmpjX2NsYXNzX3ByZWZpeCgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5vYmpjX2NsYXNzX3ByZWZpeCgpLmRhdGEoKSwgdGhpcy0+b2JqY19jbGFzc19wcmVmaXgoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMub2JqY19jbGFzc19wcmVmaXgiKTsKKyAgICB0YXJnZXQgPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nVG9BcnJheSgKKyAgICAgICAgMzYsIHRoaXMtPm9iamNfY2xhc3NfcHJlZml4KCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgY3NoYXJwX25hbWVzcGFjZSA9IDM3OworICBpZiAoaGFzX2NzaGFycF9uYW1lc3BhY2UoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+Y3NoYXJwX25hbWVzcGFjZSgpLmRhdGEoKSwgdGhpcy0+Y3NoYXJwX25hbWVzcGFjZSgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5jc2hhcnBfbmFtZXNwYWNlIik7CisgICAgdGFyZ2V0ID0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ1RvQXJyYXkoCisgICAgICAgIDM3LCB0aGlzLT5jc2hhcnBfbmFtZXNwYWNlKCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBib29sIGphdmFuYW5vX3VzZV9kZXByZWNhdGVkX3BhY2thZ2UgPSAzOCBbZGVwcmVjYXRlZCA9IHRydWVdOworICBpZiAoaGFzX2phdmFuYW5vX3VzZV9kZXByZWNhdGVkX3BhY2thZ2UoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2xUb0FycmF5KDM4LCB0aGlzLT5qYXZhbmFub191c2VfZGVwcmVjYXRlZF9wYWNrYWdlKCksIHRhcmdldCk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CisgIGZvciAodW5zaWduZWQgaW50IGkgPSAwLCBuID0gdGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb25fc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OgorICAgICAgV3JpdGVNZXNzYWdlTm9WaXJ0dWFsVG9BcnJheSgKKyAgICAgICAgOTk5LCB0aGlzLT51bmludGVycHJldGVkX29wdGlvbihpKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIEV4dGVuc2lvbiByYW5nZSBbMTAwMCwgNTM2ODcwOTEyKQorICB0YXJnZXQgPSBfZXh0ZW5zaW9uc18uU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICAgIDEwMDAsIDUzNjg3MDkxMiwgdGFyZ2V0KTsKKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTZXJpYWxpemVVbmtub3duRmllbGRzVG9BcnJheSgKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSwgdGFyZ2V0KTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X2VuZDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMpCisgIHJldHVybiB0YXJnZXQ7Cit9CisKK2ludCBGaWxlT3B0aW9uczo6Qnl0ZVNpemUoKSBjb25zdCB7CisgIGludCB0b3RhbF9zaXplID0gMDsKKworICBpZiAoX2hhc19iaXRzX1swIC8gMzJdICYgMjU1dSkgeworICAgIC8vIG9wdGlvbmFsIHN0cmluZyBqYXZhX3BhY2thZ2UgPSAxOworICAgIGlmIChoYXNfamF2YV9wYWNrYWdlKCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTdHJpbmdTaXplKAorICAgICAgICAgIHRoaXMtPmphdmFfcGFja2FnZSgpKTsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCBzdHJpbmcgamF2YV9vdXRlcl9jbGFzc25hbWUgPSA4OworICAgIGlmIChoYXNfamF2YV9vdXRlcl9jbGFzc25hbWUoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlN0cmluZ1NpemUoCisgICAgICAgICAgdGhpcy0+amF2YV9vdXRlcl9jbGFzc25hbWUoKSk7CisgICAgfQorCisgICAgLy8gb3B0aW9uYWwgYm9vbCBqYXZhX211bHRpcGxlX2ZpbGVzID0gMTAgW2RlZmF1bHQgPSBmYWxzZV07CisgICAgaWYgKGhhc19qYXZhX211bHRpcGxlX2ZpbGVzKCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArIDE7CisgICAgfQorCisgICAgLy8gb3B0aW9uYWwgYm9vbCBqYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaCA9IDIwIFtkZWZhdWx0ID0gZmFsc2VdOworICAgIGlmIChoYXNfamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2goKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAyICsgMTsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCBib29sIGphdmFfc3RyaW5nX2NoZWNrX3V0ZjggPSAyNyBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgICBpZiAoaGFzX2phdmFfc3RyaW5nX2NoZWNrX3V0ZjgoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAyICsgMTsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLk9wdGltaXplTW9kZSBvcHRpbWl6ZV9mb3IgPSA5IFtkZWZhdWx0ID0gU1BFRURdOworICAgIGlmIChoYXNfb3B0aW1pemVfZm9yKCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpFbnVtU2l6ZSh0aGlzLT5vcHRpbWl6ZV9mb3IoKSk7CisgICAgfQorCisgICAgLy8gb3B0aW9uYWwgc3RyaW5nIGdvX3BhY2thZ2UgPSAxMTsKKyAgICBpZiAoaGFzX2dvX3BhY2thZ2UoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlN0cmluZ1NpemUoCisgICAgICAgICAgdGhpcy0+Z29fcGFja2FnZSgpKTsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCBib29sIGNjX2dlbmVyaWNfc2VydmljZXMgPSAxNiBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgICBpZiAoaGFzX2NjX2dlbmVyaWNfc2VydmljZXMoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAyICsgMTsKKyAgICB9CisKKyAgfQorICBpZiAoX2hhc19iaXRzX1s4IC8gMzJdICYgMzI1MTJ1KSB7CisgICAgLy8gb3B0aW9uYWwgYm9vbCBqYXZhX2dlbmVyaWNfc2VydmljZXMgPSAxNyBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgICBpZiAoaGFzX2phdmFfZ2VuZXJpY19zZXJ2aWNlcygpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDIgKyAxOworICAgIH0KKworICAgIC8vIG9wdGlvbmFsIGJvb2wgcHlfZ2VuZXJpY19zZXJ2aWNlcyA9IDE4IFtkZWZhdWx0ID0gZmFsc2VdOworICAgIGlmIChoYXNfcHlfZ2VuZXJpY19zZXJ2aWNlcygpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDIgKyAxOworICAgIH0KKworICAgIC8vIG9wdGlvbmFsIGJvb2wgZGVwcmVjYXRlZCA9IDIzIFtkZWZhdWx0ID0gZmFsc2VdOworICAgIGlmIChoYXNfZGVwcmVjYXRlZCgpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDIgKyAxOworICAgIH0KKworICAgIC8vIG9wdGlvbmFsIGJvb2wgY2NfZW5hYmxlX2FyZW5hcyA9IDMxIFtkZWZhdWx0ID0gZmFsc2VdOworICAgIGlmIChoYXNfY2NfZW5hYmxlX2FyZW5hcygpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDIgKyAxOworICAgIH0KKworICAgIC8vIG9wdGlvbmFsIHN0cmluZyBvYmpjX2NsYXNzX3ByZWZpeCA9IDM2OworICAgIGlmIChoYXNfb2JqY19jbGFzc19wcmVmaXgoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAyICsKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlN0cmluZ1NpemUoCisgICAgICAgICAgdGhpcy0+b2JqY19jbGFzc19wcmVmaXgoKSk7CisgICAgfQorCisgICAgLy8gb3B0aW9uYWwgc3RyaW5nIGNzaGFycF9uYW1lc3BhY2UgPSAzNzsKKyAgICBpZiAoaGFzX2NzaGFycF9uYW1lc3BhY2UoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAyICsKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlN0cmluZ1NpemUoCisgICAgICAgICAgdGhpcy0+Y3NoYXJwX25hbWVzcGFjZSgpKTsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCBib29sIGphdmFuYW5vX3VzZV9kZXByZWNhdGVkX3BhY2thZ2UgPSAzOCBbZGVwcmVjYXRlZCA9IHRydWVdOworICAgIGlmIChoYXNfamF2YW5hbm9fdXNlX2RlcHJlY2F0ZWRfcGFja2FnZSgpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDIgKyAxOworICAgIH0KKworICB9CisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiB1bmludGVycHJldGVkX29wdGlvbiA9IDk5OTsKKyAgdG90YWxfc2l6ZSArPSAyICogdGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb25fc2l6ZSgpOworICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPnVuaW50ZXJwcmV0ZWRfb3B0aW9uX3NpemUoKTsgaSsrKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1lc3NhZ2VTaXplTm9WaXJ0dWFsKAorICAgICAgICB0aGlzLT51bmludGVycHJldGVkX29wdGlvbihpKSk7CisgIH0KKworICB0b3RhbF9zaXplICs9IF9leHRlbnNpb25zXy5CeXRlU2l6ZSgpOworCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHRvdGFsX3NpemUgKz0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OkNvbXB1dGVVbmtub3duRmllbGRzU2l6ZSgKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSk7CisgIH0KKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHRvdGFsX3NpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworICByZXR1cm4gdG90YWxfc2l6ZTsKK30KKwordm9pZCBGaWxlT3B0aW9uczo6TWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBjb25zdCBGaWxlT3B0aW9ucyogc291cmNlID0gCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpEeW5hbWljQ2FzdFRvR2VuZXJhdGVkPGNvbnN0IEZpbGVPcHRpb25zPigKKyAgICAgICAgICAmZnJvbSk7CisgIGlmIChzb3VyY2UgPT0gTlVMTCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlJlZmxlY3Rpb25PcHM6Ok1lcmdlKGZyb20sIHRoaXMpOworICB9IGVsc2UgeworICAgIE1lcmdlRnJvbSgqc291cmNlKTsKKyAgfQorfQorCit2b2lkIEZpbGVPcHRpb25zOjpNZXJnZUZyb20oY29uc3QgRmlsZU9wdGlvbnMmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgdW5pbnRlcnByZXRlZF9vcHRpb25fLk1lcmdlRnJvbShmcm9tLnVuaW50ZXJwcmV0ZWRfb3B0aW9uXyk7CisgIGlmIChmcm9tLl9oYXNfYml0c19bMCAvIDMyXSAmICgweGZmdSA8PCAoMCAlIDMyKSkpIHsKKyAgICBpZiAoZnJvbS5oYXNfamF2YV9wYWNrYWdlKCkpIHsKKyAgICAgIHNldF9oYXNfamF2YV9wYWNrYWdlKCk7CisgICAgICBqYXZhX3BhY2thZ2VfLkFzc2lnbldpdGhEZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgZnJvbS5qYXZhX3BhY2thZ2VfKTsKKyAgICB9CisgICAgaWYgKGZyb20uaGFzX2phdmFfb3V0ZXJfY2xhc3NuYW1lKCkpIHsKKyAgICAgIHNldF9oYXNfamF2YV9vdXRlcl9jbGFzc25hbWUoKTsKKyAgICAgIGphdmFfb3V0ZXJfY2xhc3NuYW1lXy5Bc3NpZ25XaXRoRGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGZyb20uamF2YV9vdXRlcl9jbGFzc25hbWVfKTsKKyAgICB9CisgICAgaWYgKGZyb20uaGFzX2phdmFfbXVsdGlwbGVfZmlsZXMoKSkgeworICAgICAgc2V0X2phdmFfbXVsdGlwbGVfZmlsZXMoZnJvbS5qYXZhX211bHRpcGxlX2ZpbGVzKCkpOworICAgIH0KKyAgICBpZiAoZnJvbS5oYXNfamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2goKSkgeworICAgICAgc2V0X2phdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoKGZyb20uamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2goKSk7CisgICAgfQorICAgIGlmIChmcm9tLmhhc19qYXZhX3N0cmluZ19jaGVja191dGY4KCkpIHsKKyAgICAgIHNldF9qYXZhX3N0cmluZ19jaGVja191dGY4KGZyb20uamF2YV9zdHJpbmdfY2hlY2tfdXRmOCgpKTsKKyAgICB9CisgICAgaWYgKGZyb20uaGFzX29wdGltaXplX2ZvcigpKSB7CisgICAgICBzZXRfb3B0aW1pemVfZm9yKGZyb20ub3B0aW1pemVfZm9yKCkpOworICAgIH0KKyAgICBpZiAoZnJvbS5oYXNfZ29fcGFja2FnZSgpKSB7CisgICAgICBzZXRfaGFzX2dvX3BhY2thZ2UoKTsKKyAgICAgIGdvX3BhY2thZ2VfLkFzc2lnbldpdGhEZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgZnJvbS5nb19wYWNrYWdlXyk7CisgICAgfQorICAgIGlmIChmcm9tLmhhc19jY19nZW5lcmljX3NlcnZpY2VzKCkpIHsKKyAgICAgIHNldF9jY19nZW5lcmljX3NlcnZpY2VzKGZyb20uY2NfZ2VuZXJpY19zZXJ2aWNlcygpKTsKKyAgICB9CisgIH0KKyAgaWYgKGZyb20uX2hhc19iaXRzX1s4IC8gMzJdICYgKDB4ZmZ1IDw8ICg4ICUgMzIpKSkgeworICAgIGlmIChmcm9tLmhhc19qYXZhX2dlbmVyaWNfc2VydmljZXMoKSkgeworICAgICAgc2V0X2phdmFfZ2VuZXJpY19zZXJ2aWNlcyhmcm9tLmphdmFfZ2VuZXJpY19zZXJ2aWNlcygpKTsKKyAgICB9CisgICAgaWYgKGZyb20uaGFzX3B5X2dlbmVyaWNfc2VydmljZXMoKSkgeworICAgICAgc2V0X3B5X2dlbmVyaWNfc2VydmljZXMoZnJvbS5weV9nZW5lcmljX3NlcnZpY2VzKCkpOworICAgIH0KKyAgICBpZiAoZnJvbS5oYXNfZGVwcmVjYXRlZCgpKSB7CisgICAgICBzZXRfZGVwcmVjYXRlZChmcm9tLmRlcHJlY2F0ZWQoKSk7CisgICAgfQorICAgIGlmIChmcm9tLmhhc19jY19lbmFibGVfYXJlbmFzKCkpIHsKKyAgICAgIHNldF9jY19lbmFibGVfYXJlbmFzKGZyb20uY2NfZW5hYmxlX2FyZW5hcygpKTsKKyAgICB9CisgICAgaWYgKGZyb20uaGFzX29iamNfY2xhc3NfcHJlZml4KCkpIHsKKyAgICAgIHNldF9oYXNfb2JqY19jbGFzc19wcmVmaXgoKTsKKyAgICAgIG9iamNfY2xhc3NfcHJlZml4Xy5Bc3NpZ25XaXRoRGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGZyb20ub2JqY19jbGFzc19wcmVmaXhfKTsKKyAgICB9CisgICAgaWYgKGZyb20uaGFzX2NzaGFycF9uYW1lc3BhY2UoKSkgeworICAgICAgc2V0X2hhc19jc2hhcnBfbmFtZXNwYWNlKCk7CisgICAgICBjc2hhcnBfbmFtZXNwYWNlXy5Bc3NpZ25XaXRoRGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGZyb20uY3NoYXJwX25hbWVzcGFjZV8pOworICAgIH0KKyAgICBpZiAoZnJvbS5oYXNfamF2YW5hbm9fdXNlX2RlcHJlY2F0ZWRfcGFja2FnZSgpKSB7CisgICAgICBzZXRfamF2YW5hbm9fdXNlX2RlcHJlY2F0ZWRfcGFja2FnZShmcm9tLmphdmFuYW5vX3VzZV9kZXByZWNhdGVkX3BhY2thZ2UoKSk7CisgICAgfQorICB9CisgIF9leHRlbnNpb25zXy5NZXJnZUZyb20oZnJvbS5fZXh0ZW5zaW9uc18pOworICBpZiAoZnJvbS5faW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+TWVyZ2VGcm9tKGZyb20udW5rbm93bl9maWVsZHMoKSk7CisgIH0KK30KKwordm9pZCBGaWxlT3B0aW9uczo6Q29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKwordm9pZCBGaWxlT3B0aW9uczo6Q29weUZyb20oY29uc3QgRmlsZU9wdGlvbnMmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCitib29sIEZpbGVPcHRpb25zOjpJc0luaXRpYWxpemVkKCkgY29uc3QgeworCisgIGlmICghOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QWxsQXJlSW5pdGlhbGl6ZWQodGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb24oKSkpIHJldHVybiBmYWxzZTsKKworICBpZiAoIV9leHRlbnNpb25zXy5Jc0luaXRpYWxpemVkKCkpIHJldHVybiBmYWxzZTsgIHJldHVybiB0cnVlOworfQorCit2b2lkIEZpbGVPcHRpb25zOjpTd2FwKEZpbGVPcHRpb25zKiBvdGhlcikgeworICBpZiAob3RoZXIgPT0gdGhpcykgcmV0dXJuOworICBJbnRlcm5hbFN3YXAob3RoZXIpOworfQordm9pZCBGaWxlT3B0aW9uczo6SW50ZXJuYWxTd2FwKEZpbGVPcHRpb25zKiBvdGhlcikgeworICBqYXZhX3BhY2thZ2VfLlN3YXAoJm90aGVyLT5qYXZhX3BhY2thZ2VfKTsKKyAgamF2YV9vdXRlcl9jbGFzc25hbWVfLlN3YXAoJm90aGVyLT5qYXZhX291dGVyX2NsYXNzbmFtZV8pOworICBzdGQ6OnN3YXAoamF2YV9tdWx0aXBsZV9maWxlc18sIG90aGVyLT5qYXZhX211bHRpcGxlX2ZpbGVzXyk7CisgIHN0ZDo6c3dhcChqYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaF8sIG90aGVyLT5qYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaF8pOworICBzdGQ6OnN3YXAoamF2YV9zdHJpbmdfY2hlY2tfdXRmOF8sIG90aGVyLT5qYXZhX3N0cmluZ19jaGVja191dGY4Xyk7CisgIHN0ZDo6c3dhcChvcHRpbWl6ZV9mb3JfLCBvdGhlci0+b3B0aW1pemVfZm9yXyk7CisgIGdvX3BhY2thZ2VfLlN3YXAoJm90aGVyLT5nb19wYWNrYWdlXyk7CisgIHN0ZDo6c3dhcChjY19nZW5lcmljX3NlcnZpY2VzXywgb3RoZXItPmNjX2dlbmVyaWNfc2VydmljZXNfKTsKKyAgc3RkOjpzd2FwKGphdmFfZ2VuZXJpY19zZXJ2aWNlc18sIG90aGVyLT5qYXZhX2dlbmVyaWNfc2VydmljZXNfKTsKKyAgc3RkOjpzd2FwKHB5X2dlbmVyaWNfc2VydmljZXNfLCBvdGhlci0+cHlfZ2VuZXJpY19zZXJ2aWNlc18pOworICBzdGQ6OnN3YXAoZGVwcmVjYXRlZF8sIG90aGVyLT5kZXByZWNhdGVkXyk7CisgIHN0ZDo6c3dhcChjY19lbmFibGVfYXJlbmFzXywgb3RoZXItPmNjX2VuYWJsZV9hcmVuYXNfKTsKKyAgb2JqY19jbGFzc19wcmVmaXhfLlN3YXAoJm90aGVyLT5vYmpjX2NsYXNzX3ByZWZpeF8pOworICBjc2hhcnBfbmFtZXNwYWNlXy5Td2FwKCZvdGhlci0+Y3NoYXJwX25hbWVzcGFjZV8pOworICBzdGQ6OnN3YXAoamF2YW5hbm9fdXNlX2RlcHJlY2F0ZWRfcGFja2FnZV8sIG90aGVyLT5qYXZhbmFub191c2VfZGVwcmVjYXRlZF9wYWNrYWdlXyk7CisgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5VbnNhZmVBcmVuYVN3YXAoJm90aGVyLT51bmludGVycHJldGVkX29wdGlvbl8pOworICBzdGQ6OnN3YXAoX2hhc19iaXRzX1swXSwgb3RoZXItPl9oYXNfYml0c19bMF0pOworICBfaW50ZXJuYWxfbWV0YWRhdGFfLlN3YXAoJm90aGVyLT5faW50ZXJuYWxfbWV0YWRhdGFfKTsKKyAgc3RkOjpzd2FwKF9jYWNoZWRfc2l6ZV8sIG90aGVyLT5fY2FjaGVkX3NpemVfKTsKKyAgX2V4dGVuc2lvbnNfLlN3YXAoJm90aGVyLT5fZXh0ZW5zaW9uc18pOworfQorCis6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEZpbGVPcHRpb25zOjpHZXRNZXRhZGF0YSgpIGNvbnN0IHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgbWV0YWRhdGE7CisgIG1ldGFkYXRhLmRlc2NyaXB0b3IgPSBGaWxlT3B0aW9uc19kZXNjcmlwdG9yXzsKKyAgbWV0YWRhdGEucmVmbGVjdGlvbiA9IEZpbGVPcHRpb25zX3JlZmxlY3Rpb25fOworICByZXR1cm4gbWV0YWRhdGE7Cit9CisKKyNpZiBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKy8vIEZpbGVPcHRpb25zCisKKy8vIG9wdGlvbmFsIHN0cmluZyBqYXZhX3BhY2thZ2UgPSAxOworYm9vbCBGaWxlT3B0aW9uczo6aGFzX2phdmFfcGFja2FnZSgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMXUpICE9IDA7Cit9Cit2b2lkIEZpbGVPcHRpb25zOjpzZXRfaGFzX2phdmFfcGFja2FnZSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAxdTsKK30KK3ZvaWQgRmlsZU9wdGlvbnM6OmNsZWFyX2hhc19qYXZhX3BhY2thZ2UoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDF1OworfQordm9pZCBGaWxlT3B0aW9uczo6Y2xlYXJfamF2YV9wYWNrYWdlKCkgeworICBqYXZhX3BhY2thZ2VfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX2phdmFfcGFja2FnZSgpOworfQorIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEZpbGVPcHRpb25zOjpqYXZhX3BhY2thZ2UoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmphdmFfcGFja2FnZSkKKyAgcmV0dXJuIGphdmFfcGFja2FnZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9qYXZhX3BhY2thZ2UoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgc2V0X2hhc19qYXZhX3BhY2thZ2UoKTsKKyAgamF2YV9wYWNrYWdlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5qYXZhX3BhY2thZ2UpCit9Cisgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2phdmFfcGFja2FnZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX2phdmFfcGFja2FnZSgpOworICBqYXZhX3BhY2thZ2VfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuamF2YV9wYWNrYWdlKQorfQorIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9qYXZhX3BhY2thZ2UoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHNldF9oYXNfamF2YV9wYWNrYWdlKCk7CisgIGphdmFfcGFja2FnZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmphdmFfcGFja2FnZSkKK30KKyA6OnN0ZDo6c3RyaW5nKiBGaWxlT3B0aW9uczo6bXV0YWJsZV9qYXZhX3BhY2thZ2UoKSB7CisgIHNldF9oYXNfamF2YV9wYWNrYWdlKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5qYXZhX3BhY2thZ2UpCisgIHJldHVybiBqYXZhX3BhY2thZ2VfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CisgOjpzdGQ6OnN0cmluZyogRmlsZU9wdGlvbnM6OnJlbGVhc2VfamF2YV9wYWNrYWdlKCkgeworICBjbGVhcl9oYXNfamF2YV9wYWNrYWdlKCk7CisgIHJldHVybiBqYXZhX3BhY2thZ2VfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2FsbG9jYXRlZF9qYXZhX3BhY2thZ2UoOjpzdGQ6OnN0cmluZyogamF2YV9wYWNrYWdlKSB7CisgIGlmIChqYXZhX3BhY2thZ2UgIT0gTlVMTCkgeworICAgIHNldF9oYXNfamF2YV9wYWNrYWdlKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX2phdmFfcGFja2FnZSgpOworICB9CisgIGphdmFfcGFja2FnZV8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGphdmFfcGFja2FnZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5qYXZhX3BhY2thZ2UpCit9CisKKy8vIG9wdGlvbmFsIHN0cmluZyBqYXZhX291dGVyX2NsYXNzbmFtZSA9IDg7Citib29sIEZpbGVPcHRpb25zOjpoYXNfamF2YV9vdXRlcl9jbGFzc25hbWUoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDJ1KSAhPSAwOworfQordm9pZCBGaWxlT3B0aW9uczo6c2V0X2hhc19qYXZhX291dGVyX2NsYXNzbmFtZSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAydTsKK30KK3ZvaWQgRmlsZU9wdGlvbnM6OmNsZWFyX2hhc19qYXZhX291dGVyX2NsYXNzbmFtZSgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMnU7Cit9Cit2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl9qYXZhX291dGVyX2NsYXNzbmFtZSgpIHsKKyAgamF2YV9vdXRlcl9jbGFzc25hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX2phdmFfb3V0ZXJfY2xhc3NuYW1lKCk7Cit9CisgY29uc3QgOjpzdGQ6OnN0cmluZyYgRmlsZU9wdGlvbnM6OmphdmFfb3V0ZXJfY2xhc3NuYW1lKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5qYXZhX291dGVyX2NsYXNzbmFtZSkKKyAgcmV0dXJuIGphdmFfb3V0ZXJfY2xhc3NuYW1lXy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2phdmFfb3V0ZXJfY2xhc3NuYW1lKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfamF2YV9vdXRlcl9jbGFzc25hbWUoKTsKKyAgamF2YV9vdXRlcl9jbGFzc25hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmphdmFfb3V0ZXJfY2xhc3NuYW1lKQorfQorIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9qYXZhX291dGVyX2NsYXNzbmFtZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX2phdmFfb3V0ZXJfY2xhc3NuYW1lKCk7CisgIGphdmFfb3V0ZXJfY2xhc3NuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmphdmFfb3V0ZXJfY2xhc3NuYW1lKQorfQorIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9qYXZhX291dGVyX2NsYXNzbmFtZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19qYXZhX291dGVyX2NsYXNzbmFtZSgpOworICBqYXZhX291dGVyX2NsYXNzbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmphdmFfb3V0ZXJfY2xhc3NuYW1lKQorfQorIDo6c3RkOjpzdHJpbmcqIEZpbGVPcHRpb25zOjptdXRhYmxlX2phdmFfb3V0ZXJfY2xhc3NuYW1lKCkgeworICBzZXRfaGFzX2phdmFfb3V0ZXJfY2xhc3NuYW1lKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5qYXZhX291dGVyX2NsYXNzbmFtZSkKKyAgcmV0dXJuIGphdmFfb3V0ZXJfY2xhc3NuYW1lXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIDo6c3RkOjpzdHJpbmcqIEZpbGVPcHRpb25zOjpyZWxlYXNlX2phdmFfb3V0ZXJfY2xhc3NuYW1lKCkgeworICBjbGVhcl9oYXNfamF2YV9vdXRlcl9jbGFzc25hbWUoKTsKKyAgcmV0dXJuIGphdmFfb3V0ZXJfY2xhc3NuYW1lXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9hbGxvY2F0ZWRfamF2YV9vdXRlcl9jbGFzc25hbWUoOjpzdGQ6OnN0cmluZyogamF2YV9vdXRlcl9jbGFzc25hbWUpIHsKKyAgaWYgKGphdmFfb3V0ZXJfY2xhc3NuYW1lICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX2phdmFfb3V0ZXJfY2xhc3NuYW1lKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX2phdmFfb3V0ZXJfY2xhc3NuYW1lKCk7CisgIH0KKyAgamF2YV9vdXRlcl9jbGFzc25hbWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBqYXZhX291dGVyX2NsYXNzbmFtZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5qYXZhX291dGVyX2NsYXNzbmFtZSkKK30KKworLy8gb3B0aW9uYWwgYm9vbCBqYXZhX211bHRpcGxlX2ZpbGVzID0gMTAgW2RlZmF1bHQgPSBmYWxzZV07Citib29sIEZpbGVPcHRpb25zOjpoYXNfamF2YV9tdWx0aXBsZV9maWxlcygpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwNHUpICE9IDA7Cit9Cit2b2lkIEZpbGVPcHRpb25zOjpzZXRfaGFzX2phdmFfbXVsdGlwbGVfZmlsZXMoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwNHU7Cit9Cit2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl9oYXNfamF2YV9tdWx0aXBsZV9maWxlcygpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwNHU7Cit9Cit2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl9qYXZhX211bHRpcGxlX2ZpbGVzKCkgeworICBqYXZhX211bHRpcGxlX2ZpbGVzXyA9IGZhbHNlOworICBjbGVhcl9oYXNfamF2YV9tdWx0aXBsZV9maWxlcygpOworfQorIGJvb2wgRmlsZU9wdGlvbnM6OmphdmFfbXVsdGlwbGVfZmlsZXMoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmphdmFfbXVsdGlwbGVfZmlsZXMpCisgIHJldHVybiBqYXZhX211bHRpcGxlX2ZpbGVzXzsKK30KKyB2b2lkIEZpbGVPcHRpb25zOjpzZXRfamF2YV9tdWx0aXBsZV9maWxlcyhib29sIHZhbHVlKSB7CisgIHNldF9oYXNfamF2YV9tdWx0aXBsZV9maWxlcygpOworICBqYXZhX211bHRpcGxlX2ZpbGVzXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5qYXZhX211bHRpcGxlX2ZpbGVzKQorfQorCisvLyBvcHRpb25hbCBib29sIGphdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoID0gMjAgW2RlZmF1bHQgPSBmYWxzZV07Citib29sIEZpbGVPcHRpb25zOjpoYXNfamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2goKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDh1KSAhPSAwOworfQordm9pZCBGaWxlT3B0aW9uczo6c2V0X2hhc19qYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaCgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDA4dTsKK30KK3ZvaWQgRmlsZU9wdGlvbnM6OmNsZWFyX2hhc19qYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaCgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwOHU7Cit9Cit2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl9qYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaCgpIHsKKyAgamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2hfID0gZmFsc2U7CisgIGNsZWFyX2hhc19qYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaCgpOworfQorIGJvb2wgRmlsZU9wdGlvbnM6OmphdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5qYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaCkKKyAgcmV0dXJuIGphdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoXzsKK30KKyB2b2lkIEZpbGVPcHRpb25zOjpzZXRfamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2goYm9vbCB2YWx1ZSkgeworICBzZXRfaGFzX2phdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoKCk7CisgIGphdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5qYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaCkKK30KKworLy8gb3B0aW9uYWwgYm9vbCBqYXZhX3N0cmluZ19jaGVja191dGY4ID0gMjcgW2RlZmF1bHQgPSBmYWxzZV07Citib29sIEZpbGVPcHRpb25zOjpoYXNfamF2YV9zdHJpbmdfY2hlY2tfdXRmOCgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAxMHUpICE9IDA7Cit9Cit2b2lkIEZpbGVPcHRpb25zOjpzZXRfaGFzX2phdmFfc3RyaW5nX2NoZWNrX3V0ZjgoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAxMHU7Cit9Cit2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl9oYXNfamF2YV9zdHJpbmdfY2hlY2tfdXRmOCgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAxMHU7Cit9Cit2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl9qYXZhX3N0cmluZ19jaGVja191dGY4KCkgeworICBqYXZhX3N0cmluZ19jaGVja191dGY4XyA9IGZhbHNlOworICBjbGVhcl9oYXNfamF2YV9zdHJpbmdfY2hlY2tfdXRmOCgpOworfQorIGJvb2wgRmlsZU9wdGlvbnM6OmphdmFfc3RyaW5nX2NoZWNrX3V0ZjgoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmphdmFfc3RyaW5nX2NoZWNrX3V0ZjgpCisgIHJldHVybiBqYXZhX3N0cmluZ19jaGVja191dGY4XzsKK30KKyB2b2lkIEZpbGVPcHRpb25zOjpzZXRfamF2YV9zdHJpbmdfY2hlY2tfdXRmOChib29sIHZhbHVlKSB7CisgIHNldF9oYXNfamF2YV9zdHJpbmdfY2hlY2tfdXRmOCgpOworICBqYXZhX3N0cmluZ19jaGVja191dGY4XyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5qYXZhX3N0cmluZ19jaGVja191dGY4KQorfQorCisvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLk9wdGltaXplTW9kZSBvcHRpbWl6ZV9mb3IgPSA5IFtkZWZhdWx0ID0gU1BFRURdOworYm9vbCBGaWxlT3B0aW9uczo6aGFzX29wdGltaXplX2ZvcigpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAyMHUpICE9IDA7Cit9Cit2b2lkIEZpbGVPcHRpb25zOjpzZXRfaGFzX29wdGltaXplX2ZvcigpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDIwdTsKK30KK3ZvaWQgRmlsZU9wdGlvbnM6OmNsZWFyX2hhc19vcHRpbWl6ZV9mb3IoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMjB1OworfQordm9pZCBGaWxlT3B0aW9uczo6Y2xlYXJfb3B0aW1pemVfZm9yKCkgeworICBvcHRpbWl6ZV9mb3JfID0gMTsKKyAgY2xlYXJfaGFzX29wdGltaXplX2ZvcigpOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlIEZpbGVPcHRpb25zOjpvcHRpbWl6ZV9mb3IoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLm9wdGltaXplX2ZvcikKKyAgcmV0dXJuIHN0YXRpY19jYXN0PCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVPcHRpb25zX09wdGltaXplTW9kZSA+KG9wdGltaXplX2Zvcl8pOworfQorIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9vcHRpbWl6ZV9mb3IoOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGUgdmFsdWUpIHsKKyAgYXNzZXJ0KDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlX0lzVmFsaWQodmFsdWUpKTsKKyAgc2V0X2hhc19vcHRpbWl6ZV9mb3IoKTsKKyAgb3B0aW1pemVfZm9yXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5vcHRpbWl6ZV9mb3IpCit9CisKKy8vIG9wdGlvbmFsIHN0cmluZyBnb19wYWNrYWdlID0gMTE7Citib29sIEZpbGVPcHRpb25zOjpoYXNfZ29fcGFja2FnZSgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDA0MHUpICE9IDA7Cit9Cit2b2lkIEZpbGVPcHRpb25zOjpzZXRfaGFzX2dvX3BhY2thZ2UoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDA0MHU7Cit9Cit2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl9oYXNfZ29fcGFja2FnZSgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDA0MHU7Cit9Cit2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl9nb19wYWNrYWdlKCkgeworICBnb19wYWNrYWdlXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGNsZWFyX2hhc19nb19wYWNrYWdlKCk7Cit9CisgY29uc3QgOjpzdGQ6OnN0cmluZyYgRmlsZU9wdGlvbnM6OmdvX3BhY2thZ2UoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmdvX3BhY2thZ2UpCisgIHJldHVybiBnb19wYWNrYWdlXy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2dvX3BhY2thZ2UoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgc2V0X2hhc19nb19wYWNrYWdlKCk7CisgIGdvX3BhY2thZ2VfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmdvX3BhY2thZ2UpCit9Cisgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2dvX3BhY2thZ2UoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgc2V0X2hhc19nb19wYWNrYWdlKCk7CisgIGdvX3BhY2thZ2VfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuZ29fcGFja2FnZSkKK30KKyB2b2lkIEZpbGVPcHRpb25zOjpzZXRfZ29fcGFja2FnZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19nb19wYWNrYWdlKCk7CisgIGdvX3BhY2thZ2VfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5nb19wYWNrYWdlKQorfQorIDo6c3RkOjpzdHJpbmcqIEZpbGVPcHRpb25zOjptdXRhYmxlX2dvX3BhY2thZ2UoKSB7CisgIHNldF9oYXNfZ29fcGFja2FnZSgpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuZ29fcGFja2FnZSkKKyAgcmV0dXJuIGdvX3BhY2thZ2VfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CisgOjpzdGQ6OnN0cmluZyogRmlsZU9wdGlvbnM6OnJlbGVhc2VfZ29fcGFja2FnZSgpIHsKKyAgY2xlYXJfaGFzX2dvX3BhY2thZ2UoKTsKKyAgcmV0dXJuIGdvX3BhY2thZ2VfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2FsbG9jYXRlZF9nb19wYWNrYWdlKDo6c3RkOjpzdHJpbmcqIGdvX3BhY2thZ2UpIHsKKyAgaWYgKGdvX3BhY2thZ2UgIT0gTlVMTCkgeworICAgIHNldF9oYXNfZ29fcGFja2FnZSgpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19nb19wYWNrYWdlKCk7CisgIH0KKyAgZ29fcGFja2FnZV8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGdvX3BhY2thZ2UpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuZ29fcGFja2FnZSkKK30KKworLy8gb3B0aW9uYWwgYm9vbCBjY19nZW5lcmljX3NlcnZpY2VzID0gMTYgW2RlZmF1bHQgPSBmYWxzZV07Citib29sIEZpbGVPcHRpb25zOjpoYXNfY2NfZ2VuZXJpY19zZXJ2aWNlcygpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDA4MHUpICE9IDA7Cit9Cit2b2lkIEZpbGVPcHRpb25zOjpzZXRfaGFzX2NjX2dlbmVyaWNfc2VydmljZXMoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDA4MHU7Cit9Cit2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl9oYXNfY2NfZ2VuZXJpY19zZXJ2aWNlcygpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDA4MHU7Cit9Cit2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl9jY19nZW5lcmljX3NlcnZpY2VzKCkgeworICBjY19nZW5lcmljX3NlcnZpY2VzXyA9IGZhbHNlOworICBjbGVhcl9oYXNfY2NfZ2VuZXJpY19zZXJ2aWNlcygpOworfQorIGJvb2wgRmlsZU9wdGlvbnM6OmNjX2dlbmVyaWNfc2VydmljZXMoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmNjX2dlbmVyaWNfc2VydmljZXMpCisgIHJldHVybiBjY19nZW5lcmljX3NlcnZpY2VzXzsKK30KKyB2b2lkIEZpbGVPcHRpb25zOjpzZXRfY2NfZ2VuZXJpY19zZXJ2aWNlcyhib29sIHZhbHVlKSB7CisgIHNldF9oYXNfY2NfZ2VuZXJpY19zZXJ2aWNlcygpOworICBjY19nZW5lcmljX3NlcnZpY2VzXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5jY19nZW5lcmljX3NlcnZpY2VzKQorfQorCisvLyBvcHRpb25hbCBib29sIGphdmFfZ2VuZXJpY19zZXJ2aWNlcyA9IDE3IFtkZWZhdWx0ID0gZmFsc2VdOworYm9vbCBGaWxlT3B0aW9uczo6aGFzX2phdmFfZ2VuZXJpY19zZXJ2aWNlcygpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDEwMHUpICE9IDA7Cit9Cit2b2lkIEZpbGVPcHRpb25zOjpzZXRfaGFzX2phdmFfZ2VuZXJpY19zZXJ2aWNlcygpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMTAwdTsKK30KK3ZvaWQgRmlsZU9wdGlvbnM6OmNsZWFyX2hhc19qYXZhX2dlbmVyaWNfc2VydmljZXMoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAxMDB1OworfQordm9pZCBGaWxlT3B0aW9uczo6Y2xlYXJfamF2YV9nZW5lcmljX3NlcnZpY2VzKCkgeworICBqYXZhX2dlbmVyaWNfc2VydmljZXNfID0gZmFsc2U7CisgIGNsZWFyX2hhc19qYXZhX2dlbmVyaWNfc2VydmljZXMoKTsKK30KKyBib29sIEZpbGVPcHRpb25zOjpqYXZhX2dlbmVyaWNfc2VydmljZXMoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmphdmFfZ2VuZXJpY19zZXJ2aWNlcykKKyAgcmV0dXJuIGphdmFfZ2VuZXJpY19zZXJ2aWNlc187Cit9Cisgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2phdmFfZ2VuZXJpY19zZXJ2aWNlcyhib29sIHZhbHVlKSB7CisgIHNldF9oYXNfamF2YV9nZW5lcmljX3NlcnZpY2VzKCk7CisgIGphdmFfZ2VuZXJpY19zZXJ2aWNlc18gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuamF2YV9nZW5lcmljX3NlcnZpY2VzKQorfQorCisvLyBvcHRpb25hbCBib29sIHB5X2dlbmVyaWNfc2VydmljZXMgPSAxOCBbZGVmYXVsdCA9IGZhbHNlXTsKK2Jvb2wgRmlsZU9wdGlvbnM6Omhhc19weV9nZW5lcmljX3NlcnZpY2VzKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMjAwdSkgIT0gMDsKK30KK3ZvaWQgRmlsZU9wdGlvbnM6OnNldF9oYXNfcHlfZ2VuZXJpY19zZXJ2aWNlcygpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMjAwdTsKK30KK3ZvaWQgRmlsZU9wdGlvbnM6OmNsZWFyX2hhc19weV9nZW5lcmljX3NlcnZpY2VzKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMjAwdTsKK30KK3ZvaWQgRmlsZU9wdGlvbnM6OmNsZWFyX3B5X2dlbmVyaWNfc2VydmljZXMoKSB7CisgIHB5X2dlbmVyaWNfc2VydmljZXNfID0gZmFsc2U7CisgIGNsZWFyX2hhc19weV9nZW5lcmljX3NlcnZpY2VzKCk7Cit9CisgYm9vbCBGaWxlT3B0aW9uczo6cHlfZ2VuZXJpY19zZXJ2aWNlcygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMucHlfZ2VuZXJpY19zZXJ2aWNlcykKKyAgcmV0dXJuIHB5X2dlbmVyaWNfc2VydmljZXNfOworfQorIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9weV9nZW5lcmljX3NlcnZpY2VzKGJvb2wgdmFsdWUpIHsKKyAgc2V0X2hhc19weV9nZW5lcmljX3NlcnZpY2VzKCk7CisgIHB5X2dlbmVyaWNfc2VydmljZXNfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLnB5X2dlbmVyaWNfc2VydmljZXMpCit9CisKKy8vIG9wdGlvbmFsIGJvb2wgZGVwcmVjYXRlZCA9IDIzIFtkZWZhdWx0ID0gZmFsc2VdOworYm9vbCBGaWxlT3B0aW9uczo6aGFzX2RlcHJlY2F0ZWQoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDA0MDB1KSAhPSAwOworfQordm9pZCBGaWxlT3B0aW9uczo6c2V0X2hhc19kZXByZWNhdGVkKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDA0MDB1OworfQordm9pZCBGaWxlT3B0aW9uczo6Y2xlYXJfaGFzX2RlcHJlY2F0ZWQoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDA0MDB1OworfQordm9pZCBGaWxlT3B0aW9uczo6Y2xlYXJfZGVwcmVjYXRlZCgpIHsKKyAgZGVwcmVjYXRlZF8gPSBmYWxzZTsKKyAgY2xlYXJfaGFzX2RlcHJlY2F0ZWQoKTsKK30KKyBib29sIEZpbGVPcHRpb25zOjpkZXByZWNhdGVkKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5kZXByZWNhdGVkKQorICByZXR1cm4gZGVwcmVjYXRlZF87Cit9Cisgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2RlcHJlY2F0ZWQoYm9vbCB2YWx1ZSkgeworICBzZXRfaGFzX2RlcHJlY2F0ZWQoKTsKKyAgZGVwcmVjYXRlZF8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuZGVwcmVjYXRlZCkKK30KKworLy8gb3B0aW9uYWwgYm9vbCBjY19lbmFibGVfYXJlbmFzID0gMzEgW2RlZmF1bHQgPSBmYWxzZV07Citib29sIEZpbGVPcHRpb25zOjpoYXNfY2NfZW5hYmxlX2FyZW5hcygpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDgwMHUpICE9IDA7Cit9Cit2b2lkIEZpbGVPcHRpb25zOjpzZXRfaGFzX2NjX2VuYWJsZV9hcmVuYXMoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDgwMHU7Cit9Cit2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl9oYXNfY2NfZW5hYmxlX2FyZW5hcygpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDgwMHU7Cit9Cit2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl9jY19lbmFibGVfYXJlbmFzKCkgeworICBjY19lbmFibGVfYXJlbmFzXyA9IGZhbHNlOworICBjbGVhcl9oYXNfY2NfZW5hYmxlX2FyZW5hcygpOworfQorIGJvb2wgRmlsZU9wdGlvbnM6OmNjX2VuYWJsZV9hcmVuYXMoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmNjX2VuYWJsZV9hcmVuYXMpCisgIHJldHVybiBjY19lbmFibGVfYXJlbmFzXzsKK30KKyB2b2lkIEZpbGVPcHRpb25zOjpzZXRfY2NfZW5hYmxlX2FyZW5hcyhib29sIHZhbHVlKSB7CisgIHNldF9oYXNfY2NfZW5hYmxlX2FyZW5hcygpOworICBjY19lbmFibGVfYXJlbmFzXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5jY19lbmFibGVfYXJlbmFzKQorfQorCisvLyBvcHRpb25hbCBzdHJpbmcgb2JqY19jbGFzc19wcmVmaXggPSAzNjsKK2Jvb2wgRmlsZU9wdGlvbnM6Omhhc19vYmpjX2NsYXNzX3ByZWZpeCgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMTAwMHUpICE9IDA7Cit9Cit2b2lkIEZpbGVPcHRpb25zOjpzZXRfaGFzX29iamNfY2xhc3NfcHJlZml4KCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDEwMDB1OworfQordm9pZCBGaWxlT3B0aW9uczo6Y2xlYXJfaGFzX29iamNfY2xhc3NfcHJlZml4KCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAxMDAwdTsKK30KK3ZvaWQgRmlsZU9wdGlvbnM6OmNsZWFyX29iamNfY2xhc3NfcHJlZml4KCkgeworICBvYmpjX2NsYXNzX3ByZWZpeF8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfb2JqY19jbGFzc19wcmVmaXgoKTsKK30KKyBjb25zdCA6OnN0ZDo6c3RyaW5nJiBGaWxlT3B0aW9uczo6b2JqY19jbGFzc19wcmVmaXgoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLm9iamNfY2xhc3NfcHJlZml4KQorICByZXR1cm4gb2JqY19jbGFzc19wcmVmaXhfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIEZpbGVPcHRpb25zOjpzZXRfb2JqY19jbGFzc19wcmVmaXgoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgc2V0X2hhc19vYmpjX2NsYXNzX3ByZWZpeCgpOworICBvYmpjX2NsYXNzX3ByZWZpeF8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMub2JqY19jbGFzc19wcmVmaXgpCit9Cisgdm9pZCBGaWxlT3B0aW9uczo6c2V0X29iamNfY2xhc3NfcHJlZml4KGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfb2JqY19jbGFzc19wcmVmaXgoKTsKKyAgb2JqY19jbGFzc19wcmVmaXhfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMub2JqY19jbGFzc19wcmVmaXgpCit9Cisgdm9pZCBGaWxlT3B0aW9uczo6c2V0X29iamNfY2xhc3NfcHJlZml4KGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX29iamNfY2xhc3NfcHJlZml4KCk7CisgIG9iamNfY2xhc3NfcHJlZml4Xy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMub2JqY19jbGFzc19wcmVmaXgpCit9CisgOjpzdGQ6OnN0cmluZyogRmlsZU9wdGlvbnM6Om11dGFibGVfb2JqY19jbGFzc19wcmVmaXgoKSB7CisgIHNldF9oYXNfb2JqY19jbGFzc19wcmVmaXgoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLm9iamNfY2xhc3NfcHJlZml4KQorICByZXR1cm4gb2JqY19jbGFzc19wcmVmaXhfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CisgOjpzdGQ6OnN0cmluZyogRmlsZU9wdGlvbnM6OnJlbGVhc2Vfb2JqY19jbGFzc19wcmVmaXgoKSB7CisgIGNsZWFyX2hhc19vYmpjX2NsYXNzX3ByZWZpeCgpOworICByZXR1cm4gb2JqY19jbGFzc19wcmVmaXhfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2FsbG9jYXRlZF9vYmpjX2NsYXNzX3ByZWZpeCg6OnN0ZDo6c3RyaW5nKiBvYmpjX2NsYXNzX3ByZWZpeCkgeworICBpZiAob2JqY19jbGFzc19wcmVmaXggIT0gTlVMTCkgeworICAgIHNldF9oYXNfb2JqY19jbGFzc19wcmVmaXgoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfb2JqY19jbGFzc19wcmVmaXgoKTsKKyAgfQorICBvYmpjX2NsYXNzX3ByZWZpeF8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIG9iamNfY2xhc3NfcHJlZml4KTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLm9iamNfY2xhc3NfcHJlZml4KQorfQorCisvLyBvcHRpb25hbCBzdHJpbmcgY3NoYXJwX25hbWVzcGFjZSA9IDM3OworYm9vbCBGaWxlT3B0aW9uczo6aGFzX2NzaGFycF9uYW1lc3BhY2UoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDIwMDB1KSAhPSAwOworfQordm9pZCBGaWxlT3B0aW9uczo6c2V0X2hhc19jc2hhcnBfbmFtZXNwYWNlKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDIwMDB1OworfQordm9pZCBGaWxlT3B0aW9uczo6Y2xlYXJfaGFzX2NzaGFycF9uYW1lc3BhY2UoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDIwMDB1OworfQordm9pZCBGaWxlT3B0aW9uczo6Y2xlYXJfY3NoYXJwX25hbWVzcGFjZSgpIHsKKyAgY3NoYXJwX25hbWVzcGFjZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfY3NoYXJwX25hbWVzcGFjZSgpOworfQorIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEZpbGVPcHRpb25zOjpjc2hhcnBfbmFtZXNwYWNlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5jc2hhcnBfbmFtZXNwYWNlKQorICByZXR1cm4gY3NoYXJwX25hbWVzcGFjZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9jc2hhcnBfbmFtZXNwYWNlKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfY3NoYXJwX25hbWVzcGFjZSgpOworICBjc2hhcnBfbmFtZXNwYWNlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5jc2hhcnBfbmFtZXNwYWNlKQorfQorIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9jc2hhcnBfbmFtZXNwYWNlKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfY3NoYXJwX25hbWVzcGFjZSgpOworICBjc2hhcnBfbmFtZXNwYWNlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmNzaGFycF9uYW1lc3BhY2UpCit9Cisgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2NzaGFycF9uYW1lc3BhY2UoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHNldF9oYXNfY3NoYXJwX25hbWVzcGFjZSgpOworICBjc2hhcnBfbmFtZXNwYWNlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuY3NoYXJwX25hbWVzcGFjZSkKK30KKyA6OnN0ZDo6c3RyaW5nKiBGaWxlT3B0aW9uczo6bXV0YWJsZV9jc2hhcnBfbmFtZXNwYWNlKCkgeworICBzZXRfaGFzX2NzaGFycF9uYW1lc3BhY2UoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmNzaGFycF9uYW1lc3BhY2UpCisgIHJldHVybiBjc2hhcnBfbmFtZXNwYWNlXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIDo6c3RkOjpzdHJpbmcqIEZpbGVPcHRpb25zOjpyZWxlYXNlX2NzaGFycF9uYW1lc3BhY2UoKSB7CisgIGNsZWFyX2hhc19jc2hhcnBfbmFtZXNwYWNlKCk7CisgIHJldHVybiBjc2hhcnBfbmFtZXNwYWNlXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9hbGxvY2F0ZWRfY3NoYXJwX25hbWVzcGFjZSg6OnN0ZDo6c3RyaW5nKiBjc2hhcnBfbmFtZXNwYWNlKSB7CisgIGlmIChjc2hhcnBfbmFtZXNwYWNlICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX2NzaGFycF9uYW1lc3BhY2UoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfY3NoYXJwX25hbWVzcGFjZSgpOworICB9CisgIGNzaGFycF9uYW1lc3BhY2VfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBjc2hhcnBfbmFtZXNwYWNlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmNzaGFycF9uYW1lc3BhY2UpCit9CisKKy8vIG9wdGlvbmFsIGJvb2wgamF2YW5hbm9fdXNlX2RlcHJlY2F0ZWRfcGFja2FnZSA9IDM4IFtkZXByZWNhdGVkID0gdHJ1ZV07Citib29sIEZpbGVPcHRpb25zOjpoYXNfamF2YW5hbm9fdXNlX2RlcHJlY2F0ZWRfcGFja2FnZSgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwNDAwMHUpICE9IDA7Cit9Cit2b2lkIEZpbGVPcHRpb25zOjpzZXRfaGFzX2phdmFuYW5vX3VzZV9kZXByZWNhdGVkX3BhY2thZ2UoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwNDAwMHU7Cit9Cit2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl9oYXNfamF2YW5hbm9fdXNlX2RlcHJlY2F0ZWRfcGFja2FnZSgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwNDAwMHU7Cit9Cit2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl9qYXZhbmFub191c2VfZGVwcmVjYXRlZF9wYWNrYWdlKCkgeworICBqYXZhbmFub191c2VfZGVwcmVjYXRlZF9wYWNrYWdlXyA9IGZhbHNlOworICBjbGVhcl9oYXNfamF2YW5hbm9fdXNlX2RlcHJlY2F0ZWRfcGFja2FnZSgpOworfQorIGJvb2wgRmlsZU9wdGlvbnM6OmphdmFuYW5vX3VzZV9kZXByZWNhdGVkX3BhY2thZ2UoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmphdmFuYW5vX3VzZV9kZXByZWNhdGVkX3BhY2thZ2UpCisgIHJldHVybiBqYXZhbmFub191c2VfZGVwcmVjYXRlZF9wYWNrYWdlXzsKK30KKyB2b2lkIEZpbGVPcHRpb25zOjpzZXRfamF2YW5hbm9fdXNlX2RlcHJlY2F0ZWRfcGFja2FnZShib29sIHZhbHVlKSB7CisgIHNldF9oYXNfamF2YW5hbm9fdXNlX2RlcHJlY2F0ZWRfcGFja2FnZSgpOworICBqYXZhbmFub191c2VfZGVwcmVjYXRlZF9wYWNrYWdlXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5qYXZhbmFub191c2VfZGVwcmVjYXRlZF9wYWNrYWdlKQorfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CitpbnQgRmlsZU9wdGlvbnM6OnVuaW50ZXJwcmV0ZWRfb3B0aW9uX3NpemUoKSBjb25zdCB7CisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl8uc2l6ZSgpOworfQordm9pZCBGaWxlT3B0aW9uczo6Y2xlYXJfdW5pbnRlcnByZXRlZF9vcHRpb24oKSB7CisgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5DbGVhcigpOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uJiBGaWxlT3B0aW9uczo6dW5pbnRlcnByZXRlZF9vcHRpb24oaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLkdldChpbmRleCk7Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24qIEZpbGVPcHRpb25zOjptdXRhYmxlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl8uTXV0YWJsZShpbmRleCk7Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24qIEZpbGVPcHRpb25zOjphZGRfdW5pbnRlcnByZXRlZF9vcHRpb24oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLkFkZCgpOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24gPioKK0ZpbGVPcHRpb25zOjptdXRhYmxlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuICZ1bmludGVycHJldGVkX29wdGlvbl87Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiA+JgorRmlsZU9wdGlvbnM6OnVuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl87Cit9CisKKyNlbmRpZiAgLy8gUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworI2lmICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCitjb25zdCBpbnQgTWVzc2FnZU9wdGlvbnM6OmtNZXNzYWdlU2V0V2lyZUZvcm1hdEZpZWxkTnVtYmVyOworY29uc3QgaW50IE1lc3NhZ2VPcHRpb25zOjprTm9TdGFuZGFyZERlc2NyaXB0b3JBY2Nlc3NvckZpZWxkTnVtYmVyOworY29uc3QgaW50IE1lc3NhZ2VPcHRpb25zOjprRGVwcmVjYXRlZEZpZWxkTnVtYmVyOworY29uc3QgaW50IE1lc3NhZ2VPcHRpb25zOjprTWFwRW50cnlGaWVsZE51bWJlcjsKK2NvbnN0IGludCBNZXNzYWdlT3B0aW9uczo6a1VuaW50ZXJwcmV0ZWRPcHRpb25GaWVsZE51bWJlcjsKKyNlbmRpZiAgLy8gIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKKworTWVzc2FnZU9wdGlvbnM6Ok1lc3NhZ2VPcHRpb25zKCkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucykKK30KKwordm9pZCBNZXNzYWdlT3B0aW9uczo6SW5pdEFzRGVmYXVsdEluc3RhbmNlKCkgeworfQorCitNZXNzYWdlT3B0aW9uczo6TWVzc2FnZU9wdGlvbnMoY29uc3QgTWVzc2FnZU9wdGlvbnMmIGZyb20pCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksCisgICAgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29weV9jb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMpCit9CisKK3ZvaWQgTWVzc2FnZU9wdGlvbnM6OlNoYXJlZEN0b3IoKSB7CisgIF9jYWNoZWRfc2l6ZV8gPSAwOworICBtZXNzYWdlX3NldF93aXJlX2Zvcm1hdF8gPSBmYWxzZTsKKyAgbm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3Nvcl8gPSBmYWxzZTsKKyAgZGVwcmVjYXRlZF8gPSBmYWxzZTsKKyAgbWFwX2VudHJ5XyA9IGZhbHNlOworICA6Om1lbXNldChfaGFzX2JpdHNfLCAwLCBzaXplb2YoX2hhc19iaXRzXykpOworfQorCitNZXNzYWdlT3B0aW9uczo6fk1lc3NhZ2VPcHRpb25zKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZGVzdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMpCisgIFNoYXJlZER0b3IoKTsKK30KKwordm9pZCBNZXNzYWdlT3B0aW9uczo6U2hhcmVkRHRvcigpIHsKKyAgaWYgKHRoaXMgIT0gZGVmYXVsdF9pbnN0YW5jZV8pIHsKKyAgfQorfQorCit2b2lkIE1lc3NhZ2VPcHRpb25zOjpTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdCB7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSBzaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogTWVzc2FnZU9wdGlvbnM6OmRlc2NyaXB0b3IoKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICByZXR1cm4gTWVzc2FnZU9wdGlvbnNfZGVzY3JpcHRvcl87Cit9CisKK2NvbnN0IE1lc3NhZ2VPcHRpb25zJiBNZXNzYWdlT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZSgpIHsKKyAgaWYgKGRlZmF1bHRfaW5zdGFuY2VfID09IE5VTEwpIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgcmV0dXJuICpkZWZhdWx0X2luc3RhbmNlXzsKK30KKworTWVzc2FnZU9wdGlvbnMqIE1lc3NhZ2VPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlXyA9IE5VTEw7CisKK01lc3NhZ2VPcHRpb25zKiBNZXNzYWdlT3B0aW9uczo6TmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdCB7CisgIE1lc3NhZ2VPcHRpb25zKiBuID0gbmV3IE1lc3NhZ2VPcHRpb25zOworICBpZiAoYXJlbmEgIT0gTlVMTCkgeworICAgIGFyZW5hLT5Pd24obik7CisgIH0KKyAgcmV0dXJuIG47Cit9CisKK3ZvaWQgTWVzc2FnZU9wdGlvbnM6OkNsZWFyKCkgeworICBfZXh0ZW5zaW9uc18uQ2xlYXIoKTsKKyNkZWZpbmUgWlJfSEVMUEVSXyhmKSByZWludGVycHJldF9jYXN0PGNoYXIqPihcCisgICZyZWludGVycHJldF9jYXN0PE1lc3NhZ2VPcHRpb25zKj4oMTYpLT5mKQorCisjZGVmaW5lIFpSXyhmaXJzdCwgbGFzdCkgZG8ge1wKKyAgOjptZW1zZXQoJmZpcnN0LCAwLFwKKyAgICAgICAgICAgWlJfSEVMUEVSXyhsYXN0KSAtIFpSX0hFTFBFUl8oZmlyc3QpICsgc2l6ZW9mKGxhc3QpKTtcCit9IHdoaWxlICgwKQorCisgIFpSXyhtZXNzYWdlX3NldF93aXJlX2Zvcm1hdF8sIG1hcF9lbnRyeV8pOworCisjdW5kZWYgWlJfSEVMUEVSXworI3VuZGVmIFpSXworCisgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5DbGVhcigpOworICA6Om1lbXNldChfaGFzX2JpdHNfLCAwLCBzaXplb2YoX2hhc19iaXRzXykpOworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkNsZWFyKCk7CisgIH0KK30KKworYm9vbCBNZXNzYWdlT3B0aW9uczo6TWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KSB7CisjZGVmaW5lIERPXyhFWFBSRVNTSU9OKSBpZiAoIShFWFBSRVNTSU9OKSkgZ290byBmYWlsdXJlCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIHRhZzsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucykKKyAgZm9yICg7OykgeworICAgIDo6c3RkOjpwYWlyPCA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiwgYm9vbD4gcCA9IGlucHV0LT5SZWFkVGFnV2l0aEN1dG9mZigxNjM4Myk7CisgICAgdGFnID0gcC5maXJzdDsKKyAgICBpZiAoIXAuc2Vjb25kKSBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgIHN3aXRjaCAoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ0ZpZWxkTnVtYmVyKHRhZykpIHsKKyAgICAgIC8vIG9wdGlvbmFsIGJvb2wgbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQgPSAxIFtkZWZhdWx0ID0gZmFsc2VdOworICAgICAgY2FzZSAxOiB7CisgICAgICAgIGlmICh0YWcgPT0gOCkgeworICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgYm9vbCwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfQk9PTD4oCisgICAgICAgICAgICAgICAgIGlucHV0LCAmbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXRfKSkpOworICAgICAgICAgIHNldF9oYXNfbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDE2KSkgZ290byBwYXJzZV9ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgYm9vbCBub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yID0gMiBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgICAgIGNhc2UgMjogeworICAgICAgICBpZiAodGFnID09IDE2KSB7CisgICAgICAgICBwYXJzZV9ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yOgorICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgYm9vbCwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfQk9PTD4oCisgICAgICAgICAgICAgICAgIGlucHV0LCAmbm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3Nvcl8pKSk7CisgICAgICAgICAgc2V0X2hhc19ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygyNCkpIGdvdG8gcGFyc2VfZGVwcmVjYXRlZDsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIGJvb2wgZGVwcmVjYXRlZCA9IDMgW2RlZmF1bHQgPSBmYWxzZV07CisgICAgICBjYXNlIDM6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAyNCkgeworICAgICAgICAgcGFyc2VfZGVwcmVjYXRlZDoKKyAgICAgICAgICBET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPAorICAgICAgICAgICAgICAgICAgIGJvb2wsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0JPT0w+KAorICAgICAgICAgICAgICAgICBpbnB1dCwgJmRlcHJlY2F0ZWRfKSkpOworICAgICAgICAgIHNldF9oYXNfZGVwcmVjYXRlZCgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNTYpKSBnb3RvIHBhcnNlX21hcF9lbnRyeTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIGJvb2wgbWFwX2VudHJ5ID0gNzsKKyAgICAgIGNhc2UgNzogeworICAgICAgICBpZiAodGFnID09IDU2KSB7CisgICAgICAgICBwYXJzZV9tYXBfZW50cnk6CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICBib29sLCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9CT09MPigKKyAgICAgICAgICAgICAgICAgaW5wdXQsICZtYXBfZW50cnlfKSkpOworICAgICAgICAgIHNldF9oYXNfbWFwX2VudHJ5KCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg3OTk0KSkgZ290byBwYXJzZV91bmludGVycHJldGVkX29wdGlvbjsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiB1bmludGVycHJldGVkX29wdGlvbiA9IDk5OTsKKyAgICAgIGNhc2UgOTk5OiB7CisgICAgICAgIGlmICh0YWcgPT0gNzk5NCkgeworICAgICAgICAgcGFyc2VfdW5pbnRlcnByZXRlZF9vcHRpb246CisgICAgICAgICAgRE9fKGlucHV0LT5JbmNyZW1lbnRSZWN1cnNpb25EZXB0aCgpKTsKKyAgICAgICAgIHBhcnNlX2xvb3BfdW5pbnRlcnByZXRlZF9vcHRpb246CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkTWVzc2FnZU5vVmlydHVhbE5vUmVjdXJzaW9uRGVwdGgoCisgICAgICAgICAgICAgICAgaW5wdXQsIGFkZF91bmludGVycHJldGVkX29wdGlvbigpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg3OTk0KSkgZ290byBwYXJzZV9sb29wX3VuaW50ZXJwcmV0ZWRfb3B0aW9uOworICAgICAgICBpbnB1dC0+VW5zYWZlRGVjcmVtZW50UmVjdXJzaW9uRGVwdGgoKTsKKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RBdEVuZCgpKSBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBkZWZhdWx0OiB7CisgICAgICBoYW5kbGVfdW51c3VhbDoKKyAgICAgICAgaWYgKHRhZyA9PSAwIHx8CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnV2lyZVR5cGUodGFnKSA9PQorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0VORF9HUk9VUCkgeworICAgICAgICAgIGdvdG8gc3VjY2VzczsKKyAgICAgICAgfQorICAgICAgICBpZiAoKDgwMDB1IDw9IHRhZykpIHsKKyAgICAgICAgICBET18oX2V4dGVuc2lvbnNfLlBhcnNlRmllbGQodGFnLCBpbnB1dCwgZGVmYXVsdF9pbnN0YW5jZV8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSkpOworICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTa2lwRmllbGQoCisgICAgICAgICAgICAgIGlucHV0LCB0YWcsIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSkpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KK3N1Y2Nlc3M6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdWNjZXNzOmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucykKKyAgcmV0dXJuIHRydWU7CitmYWlsdXJlOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2VfZmFpbHVyZTpnb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMpCisgIHJldHVybiBmYWxzZTsKKyN1bmRlZiBET18KK30KKwordm9pZCBNZXNzYWdlT3B0aW9uczo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9zdGFydDpnb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMpCisgIC8vIG9wdGlvbmFsIGJvb2wgbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQgPSAxIFtkZWZhdWx0ID0gZmFsc2VdOworICBpZiAoaGFzX21lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCb29sKDEsIHRoaXMtPm1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBib29sIG5vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3IgPSAyIFtkZWZhdWx0ID0gZmFsc2VdOworICBpZiAoaGFzX25vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3IoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2woMiwgdGhpcy0+bm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvcigpLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgYm9vbCBkZXByZWNhdGVkID0gMyBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgaWYgKGhhc19kZXByZWNhdGVkKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCb29sKDMsIHRoaXMtPmRlcHJlY2F0ZWQoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGJvb2wgbWFwX2VudHJ5ID0gNzsKKyAgaWYgKGhhc19tYXBfZW50cnkoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2woNywgdGhpcy0+bWFwX2VudHJ5KCksIG91dHB1dCk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CisgIGZvciAodW5zaWduZWQgaW50IGkgPSAwLCBuID0gdGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb25fc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlTWVzc2FnZU1heWJlVG9BcnJheSgKKyAgICAgIDk5OSwgdGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb24oaSksIG91dHB1dCk7CisgIH0KKworICAvLyBFeHRlbnNpb24gcmFuZ2UgWzEwMDAsIDUzNjg3MDkxMikKKyAgX2V4dGVuc2lvbnNfLlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICAgIDEwMDAsIDUzNjg3MDkxMiwgb3V0cHV0KTsKKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTZXJpYWxpemVVbmtub3duRmllbGRzKAorICAgICAgICB1bmtub3duX2ZpZWxkcygpLCBvdXRwdXQpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfZW5kOmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucykKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogTWVzc2FnZU9wdGlvbnM6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogdGFyZ2V0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zKQorICAvLyBvcHRpb25hbCBib29sIG1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0ID0gMSBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgaWYgKGhhc19tZXNzYWdlX3NldF93aXJlX2Zvcm1hdCgpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlQm9vbFRvQXJyYXkoMSwgdGhpcy0+bWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGJvb2wgbm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvciA9IDIgW2RlZmF1bHQgPSBmYWxzZV07CisgIGlmIChoYXNfbm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvcigpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlQm9vbFRvQXJyYXkoMiwgdGhpcy0+bm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvcigpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgYm9vbCBkZXByZWNhdGVkID0gMyBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgaWYgKGhhc19kZXByZWNhdGVkKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCb29sVG9BcnJheSgzLCB0aGlzLT5kZXByZWNhdGVkKCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBib29sIG1hcF9lbnRyeSA9IDc7CisgIGlmIChoYXNfbWFwX2VudHJ5KCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCb29sVG9BcnJheSg3LCB0aGlzLT5tYXBfZW50cnkoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiB1bmludGVycHJldGVkX29wdGlvbiA9IDk5OTsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT51bmludGVycHJldGVkX29wdGlvbl9zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6CisgICAgICBXcml0ZU1lc3NhZ2VOb1ZpcnR1YWxUb0FycmF5KAorICAgICAgICA5OTksIHRoaXMtPnVuaW50ZXJwcmV0ZWRfb3B0aW9uKGkpLCB0YXJnZXQpOworICB9CisKKyAgLy8gRXh0ZW5zaW9uIHJhbmdlIFsxMDAwLCA1MzY4NzA5MTIpCisgIHRhcmdldCA9IF9leHRlbnNpb25zXy5TZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KAorICAgICAgMTAwMCwgNTM2ODcwOTEyLCB0YXJnZXQpOworCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25GaWVsZHNUb0FycmF5KAorICAgICAgICB1bmtub3duX2ZpZWxkcygpLCB0YXJnZXQpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfZW5kOmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucykKKyAgcmV0dXJuIHRhcmdldDsKK30KKworaW50IE1lc3NhZ2VPcHRpb25zOjpCeXRlU2l6ZSgpIGNvbnN0IHsKKyAgaW50IHRvdGFsX3NpemUgPSAwOworCisgIGlmIChfaGFzX2JpdHNfWzAgLyAzMl0gJiAxNXUpIHsKKyAgICAvLyBvcHRpb25hbCBib29sIG1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0ID0gMSBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgICBpZiAoaGFzX21lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArIDE7CisgICAgfQorCisgICAgLy8gb3B0aW9uYWwgYm9vbCBub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yID0gMiBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgICBpZiAoaGFzX25vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3IoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsgMTsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCBib29sIGRlcHJlY2F0ZWQgPSAzIFtkZWZhdWx0ID0gZmFsc2VdOworICAgIGlmIChoYXNfZGVwcmVjYXRlZCgpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKyAxOworICAgIH0KKworICAgIC8vIG9wdGlvbmFsIGJvb2wgbWFwX2VudHJ5ID0gNzsKKyAgICBpZiAoaGFzX21hcF9lbnRyeSgpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKyAxOworICAgIH0KKworICB9CisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiB1bmludGVycHJldGVkX29wdGlvbiA9IDk5OTsKKyAgdG90YWxfc2l6ZSArPSAyICogdGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb25fc2l6ZSgpOworICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPnVuaW50ZXJwcmV0ZWRfb3B0aW9uX3NpemUoKTsgaSsrKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1lc3NhZ2VTaXplTm9WaXJ0dWFsKAorICAgICAgICB0aGlzLT51bmludGVycHJldGVkX29wdGlvbihpKSk7CisgIH0KKworICB0b3RhbF9zaXplICs9IF9leHRlbnNpb25zXy5CeXRlU2l6ZSgpOworCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHRvdGFsX3NpemUgKz0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OkNvbXB1dGVVbmtub3duRmllbGRzU2l6ZSgKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSk7CisgIH0KKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHRvdGFsX3NpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworICByZXR1cm4gdG90YWxfc2l6ZTsKK30KKwordm9pZCBNZXNzYWdlT3B0aW9uczo6TWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBjb25zdCBNZXNzYWdlT3B0aW9ucyogc291cmNlID0gCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpEeW5hbWljQ2FzdFRvR2VuZXJhdGVkPGNvbnN0IE1lc3NhZ2VPcHRpb25zPigKKyAgICAgICAgICAmZnJvbSk7CisgIGlmIChzb3VyY2UgPT0gTlVMTCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlJlZmxlY3Rpb25PcHM6Ok1lcmdlKGZyb20sIHRoaXMpOworICB9IGVsc2UgeworICAgIE1lcmdlRnJvbSgqc291cmNlKTsKKyAgfQorfQorCit2b2lkIE1lc3NhZ2VPcHRpb25zOjpNZXJnZUZyb20oY29uc3QgTWVzc2FnZU9wdGlvbnMmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgdW5pbnRlcnByZXRlZF9vcHRpb25fLk1lcmdlRnJvbShmcm9tLnVuaW50ZXJwcmV0ZWRfb3B0aW9uXyk7CisgIGlmIChmcm9tLl9oYXNfYml0c19bMCAvIDMyXSAmICgweGZmdSA8PCAoMCAlIDMyKSkpIHsKKyAgICBpZiAoZnJvbS5oYXNfbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQoKSkgeworICAgICAgc2V0X21lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KGZyb20ubWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQoKSk7CisgICAgfQorICAgIGlmIChmcm9tLmhhc19ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yKCkpIHsKKyAgICAgIHNldF9ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yKGZyb20ubm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvcigpKTsKKyAgICB9CisgICAgaWYgKGZyb20uaGFzX2RlcHJlY2F0ZWQoKSkgeworICAgICAgc2V0X2RlcHJlY2F0ZWQoZnJvbS5kZXByZWNhdGVkKCkpOworICAgIH0KKyAgICBpZiAoZnJvbS5oYXNfbWFwX2VudHJ5KCkpIHsKKyAgICAgIHNldF9tYXBfZW50cnkoZnJvbS5tYXBfZW50cnkoKSk7CisgICAgfQorICB9CisgIF9leHRlbnNpb25zXy5NZXJnZUZyb20oZnJvbS5fZXh0ZW5zaW9uc18pOworICBpZiAoZnJvbS5faW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+TWVyZ2VGcm9tKGZyb20udW5rbm93bl9maWVsZHMoKSk7CisgIH0KK30KKwordm9pZCBNZXNzYWdlT3B0aW9uczo6Q29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKwordm9pZCBNZXNzYWdlT3B0aW9uczo6Q29weUZyb20oY29uc3QgTWVzc2FnZU9wdGlvbnMmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCitib29sIE1lc3NhZ2VPcHRpb25zOjpJc0luaXRpYWxpemVkKCkgY29uc3QgeworCisgIGlmICghOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QWxsQXJlSW5pdGlhbGl6ZWQodGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb24oKSkpIHJldHVybiBmYWxzZTsKKworICBpZiAoIV9leHRlbnNpb25zXy5Jc0luaXRpYWxpemVkKCkpIHJldHVybiBmYWxzZTsgIHJldHVybiB0cnVlOworfQorCit2b2lkIE1lc3NhZ2VPcHRpb25zOjpTd2FwKE1lc3NhZ2VPcHRpb25zKiBvdGhlcikgeworICBpZiAob3RoZXIgPT0gdGhpcykgcmV0dXJuOworICBJbnRlcm5hbFN3YXAob3RoZXIpOworfQordm9pZCBNZXNzYWdlT3B0aW9uczo6SW50ZXJuYWxTd2FwKE1lc3NhZ2VPcHRpb25zKiBvdGhlcikgeworICBzdGQ6OnN3YXAobWVzc2FnZV9zZXRfd2lyZV9mb3JtYXRfLCBvdGhlci0+bWVzc2FnZV9zZXRfd2lyZV9mb3JtYXRfKTsKKyAgc3RkOjpzd2FwKG5vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3JfLCBvdGhlci0+bm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3Nvcl8pOworICBzdGQ6OnN3YXAoZGVwcmVjYXRlZF8sIG90aGVyLT5kZXByZWNhdGVkXyk7CisgIHN0ZDo6c3dhcChtYXBfZW50cnlfLCBvdGhlci0+bWFwX2VudHJ5Xyk7CisgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5VbnNhZmVBcmVuYVN3YXAoJm90aGVyLT51bmludGVycHJldGVkX29wdGlvbl8pOworICBzdGQ6OnN3YXAoX2hhc19iaXRzX1swXSwgb3RoZXItPl9oYXNfYml0c19bMF0pOworICBfaW50ZXJuYWxfbWV0YWRhdGFfLlN3YXAoJm90aGVyLT5faW50ZXJuYWxfbWV0YWRhdGFfKTsKKyAgc3RkOjpzd2FwKF9jYWNoZWRfc2l6ZV8sIG90aGVyLT5fY2FjaGVkX3NpemVfKTsKKyAgX2V4dGVuc2lvbnNfLlN3YXAoJm90aGVyLT5fZXh0ZW5zaW9uc18pOworfQorCis6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIE1lc3NhZ2VPcHRpb25zOjpHZXRNZXRhZGF0YSgpIGNvbnN0IHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgbWV0YWRhdGE7CisgIG1ldGFkYXRhLmRlc2NyaXB0b3IgPSBNZXNzYWdlT3B0aW9uc19kZXNjcmlwdG9yXzsKKyAgbWV0YWRhdGEucmVmbGVjdGlvbiA9IE1lc3NhZ2VPcHRpb25zX3JlZmxlY3Rpb25fOworICByZXR1cm4gbWV0YWRhdGE7Cit9CisKKyNpZiBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKy8vIE1lc3NhZ2VPcHRpb25zCisKKy8vIG9wdGlvbmFsIGJvb2wgbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQgPSAxIFtkZWZhdWx0ID0gZmFsc2VdOworYm9vbCBNZXNzYWdlT3B0aW9uczo6aGFzX21lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAxdSkgIT0gMDsKK30KK3ZvaWQgTWVzc2FnZU9wdGlvbnM6OnNldF9oYXNfbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMXU7Cit9Cit2b2lkIE1lc3NhZ2VPcHRpb25zOjpjbGVhcl9oYXNfbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDF1OworfQordm9pZCBNZXNzYWdlT3B0aW9uczo6Y2xlYXJfbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQoKSB7CisgIG1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0XyA9IGZhbHNlOworICBjbGVhcl9oYXNfbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQoKTsKK30KKyBib29sIE1lc3NhZ2VPcHRpb25zOjptZXNzYWdlX3NldF93aXJlX2Zvcm1hdCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMubWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQpCisgIHJldHVybiBtZXNzYWdlX3NldF93aXJlX2Zvcm1hdF87Cit9Cisgdm9pZCBNZXNzYWdlT3B0aW9uczo6c2V0X21lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KGJvb2wgdmFsdWUpIHsKKyAgc2V0X2hhc19tZXNzYWdlX3NldF93aXJlX2Zvcm1hdCgpOworICBtZXNzYWdlX3NldF93aXJlX2Zvcm1hdF8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMubWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQpCit9CisKKy8vIG9wdGlvbmFsIGJvb2wgbm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvciA9IDIgW2RlZmF1bHQgPSBmYWxzZV07Citib29sIE1lc3NhZ2VPcHRpb25zOjpoYXNfbm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvcigpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMnUpICE9IDA7Cit9Cit2b2lkIE1lc3NhZ2VPcHRpb25zOjpzZXRfaGFzX25vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3IoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMnU7Cit9Cit2b2lkIE1lc3NhZ2VPcHRpb25zOjpjbGVhcl9oYXNfbm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvcigpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMnU7Cit9Cit2b2lkIE1lc3NhZ2VPcHRpb25zOjpjbGVhcl9ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yKCkgeworICBub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yXyA9IGZhbHNlOworICBjbGVhcl9oYXNfbm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvcigpOworfQorIGJvb2wgTWVzc2FnZU9wdGlvbnM6Om5vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3IoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zLm5vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3IpCisgIHJldHVybiBub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yXzsKK30KKyB2b2lkIE1lc3NhZ2VPcHRpb25zOjpzZXRfbm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3Nvcihib29sIHZhbHVlKSB7CisgIHNldF9oYXNfbm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvcigpOworICBub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucy5ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yKQorfQorCisvLyBvcHRpb25hbCBib29sIGRlcHJlY2F0ZWQgPSAzIFtkZWZhdWx0ID0gZmFsc2VdOworYm9vbCBNZXNzYWdlT3B0aW9uczo6aGFzX2RlcHJlY2F0ZWQoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDR1KSAhPSAwOworfQordm9pZCBNZXNzYWdlT3B0aW9uczo6c2V0X2hhc19kZXByZWNhdGVkKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDR1OworfQordm9pZCBNZXNzYWdlT3B0aW9uczo6Y2xlYXJfaGFzX2RlcHJlY2F0ZWQoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDR1OworfQordm9pZCBNZXNzYWdlT3B0aW9uczo6Y2xlYXJfZGVwcmVjYXRlZCgpIHsKKyAgZGVwcmVjYXRlZF8gPSBmYWxzZTsKKyAgY2xlYXJfaGFzX2RlcHJlY2F0ZWQoKTsKK30KKyBib29sIE1lc3NhZ2VPcHRpb25zOjpkZXByZWNhdGVkKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucy5kZXByZWNhdGVkKQorICByZXR1cm4gZGVwcmVjYXRlZF87Cit9Cisgdm9pZCBNZXNzYWdlT3B0aW9uczo6c2V0X2RlcHJlY2F0ZWQoYm9vbCB2YWx1ZSkgeworICBzZXRfaGFzX2RlcHJlY2F0ZWQoKTsKKyAgZGVwcmVjYXRlZF8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMuZGVwcmVjYXRlZCkKK30KKworLy8gb3B0aW9uYWwgYm9vbCBtYXBfZW50cnkgPSA3OworYm9vbCBNZXNzYWdlT3B0aW9uczo6aGFzX21hcF9lbnRyeSgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwOHUpICE9IDA7Cit9Cit2b2lkIE1lc3NhZ2VPcHRpb25zOjpzZXRfaGFzX21hcF9lbnRyeSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDA4dTsKK30KK3ZvaWQgTWVzc2FnZU9wdGlvbnM6OmNsZWFyX2hhc19tYXBfZW50cnkoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDh1OworfQordm9pZCBNZXNzYWdlT3B0aW9uczo6Y2xlYXJfbWFwX2VudHJ5KCkgeworICBtYXBfZW50cnlfID0gZmFsc2U7CisgIGNsZWFyX2hhc19tYXBfZW50cnkoKTsKK30KKyBib29sIE1lc3NhZ2VPcHRpb25zOjptYXBfZW50cnkoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zLm1hcF9lbnRyeSkKKyAgcmV0dXJuIG1hcF9lbnRyeV87Cit9Cisgdm9pZCBNZXNzYWdlT3B0aW9uczo6c2V0X21hcF9lbnRyeShib29sIHZhbHVlKSB7CisgIHNldF9oYXNfbWFwX2VudHJ5KCk7CisgIG1hcF9lbnRyeV8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMubWFwX2VudHJ5KQorfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CitpbnQgTWVzc2FnZU9wdGlvbnM6OnVuaW50ZXJwcmV0ZWRfb3B0aW9uX3NpemUoKSBjb25zdCB7CisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl8uc2l6ZSgpOworfQordm9pZCBNZXNzYWdlT3B0aW9uczo6Y2xlYXJfdW5pbnRlcnByZXRlZF9vcHRpb24oKSB7CisgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5DbGVhcigpOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uJiBNZXNzYWdlT3B0aW9uczo6dW5pbnRlcnByZXRlZF9vcHRpb24oaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLkdldChpbmRleCk7Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24qIE1lc3NhZ2VPcHRpb25zOjptdXRhYmxlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl8uTXV0YWJsZShpbmRleCk7Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24qIE1lc3NhZ2VPcHRpb25zOjphZGRfdW5pbnRlcnByZXRlZF9vcHRpb24oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLkFkZCgpOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24gPioKK01lc3NhZ2VPcHRpb25zOjptdXRhYmxlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuICZ1bmludGVycHJldGVkX29wdGlvbl87Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiA+JgorTWVzc2FnZU9wdGlvbnM6OnVuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl87Cit9CisKKyNlbmRpZiAgLy8gUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvciogRmllbGRPcHRpb25zX0NUeXBlX2Rlc2NyaXB0b3IoKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICByZXR1cm4gRmllbGRPcHRpb25zX0NUeXBlX2Rlc2NyaXB0b3JfOworfQorYm9vbCBGaWVsZE9wdGlvbnNfQ1R5cGVfSXNWYWxpZChpbnQgdmFsdWUpIHsKKyAgc3dpdGNoKHZhbHVlKSB7CisgICAgY2FzZSAwOgorICAgIGNhc2UgMToKKyAgICBjYXNlIDI6CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICBkZWZhdWx0OgorICAgICAgcmV0dXJuIGZhbHNlOworICB9Cit9CisKKyNpZiAhZGVmaW5lZChfTVNDX1ZFUikgfHwgX01TQ19WRVIgPj0gMTkwMAorY29uc3QgRmllbGRPcHRpb25zX0NUeXBlIEZpZWxkT3B0aW9uczo6U1RSSU5HOworY29uc3QgRmllbGRPcHRpb25zX0NUeXBlIEZpZWxkT3B0aW9uczo6Q09SRDsKK2NvbnN0IEZpZWxkT3B0aW9uc19DVHlwZSBGaWVsZE9wdGlvbnM6OlNUUklOR19QSUVDRTsKK2NvbnN0IEZpZWxkT3B0aW9uc19DVHlwZSBGaWVsZE9wdGlvbnM6OkNUeXBlX01JTjsKK2NvbnN0IEZpZWxkT3B0aW9uc19DVHlwZSBGaWVsZE9wdGlvbnM6OkNUeXBlX01BWDsKK2NvbnN0IGludCBGaWVsZE9wdGlvbnM6OkNUeXBlX0FSUkFZU0laRTsKKyNlbmRpZiAgLy8gIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bURlc2NyaXB0b3IqIEZpZWxkT3B0aW9uc19KU1R5cGVfZGVzY3JpcHRvcigpIHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIHJldHVybiBGaWVsZE9wdGlvbnNfSlNUeXBlX2Rlc2NyaXB0b3JfOworfQorYm9vbCBGaWVsZE9wdGlvbnNfSlNUeXBlX0lzVmFsaWQoaW50IHZhbHVlKSB7CisgIHN3aXRjaCh2YWx1ZSkgeworICAgIGNhc2UgMDoKKyAgICBjYXNlIDE6CisgICAgY2FzZSAyOgorICAgICAgcmV0dXJuIHRydWU7CisgICAgZGVmYXVsdDoKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgfQorfQorCisjaWYgIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKK2NvbnN0IEZpZWxkT3B0aW9uc19KU1R5cGUgRmllbGRPcHRpb25zOjpKU19OT1JNQUw7Citjb25zdCBGaWVsZE9wdGlvbnNfSlNUeXBlIEZpZWxkT3B0aW9uczo6SlNfU1RSSU5HOworY29uc3QgRmllbGRPcHRpb25zX0pTVHlwZSBGaWVsZE9wdGlvbnM6OkpTX05VTUJFUjsKK2NvbnN0IEZpZWxkT3B0aW9uc19KU1R5cGUgRmllbGRPcHRpb25zOjpKU1R5cGVfTUlOOworY29uc3QgRmllbGRPcHRpb25zX0pTVHlwZSBGaWVsZE9wdGlvbnM6OkpTVHlwZV9NQVg7Citjb25zdCBpbnQgRmllbGRPcHRpb25zOjpKU1R5cGVfQVJSQVlTSVpFOworI2VuZGlmICAvLyAhZGVmaW5lZChfTVNDX1ZFUikgfHwgX01TQ19WRVIgPj0gMTkwMAorI2lmICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCitjb25zdCBpbnQgRmllbGRPcHRpb25zOjprQ3R5cGVGaWVsZE51bWJlcjsKK2NvbnN0IGludCBGaWVsZE9wdGlvbnM6OmtQYWNrZWRGaWVsZE51bWJlcjsKK2NvbnN0IGludCBGaWVsZE9wdGlvbnM6OmtKc3R5cGVGaWVsZE51bWJlcjsKK2NvbnN0IGludCBGaWVsZE9wdGlvbnM6OmtMYXp5RmllbGROdW1iZXI7Citjb25zdCBpbnQgRmllbGRPcHRpb25zOjprRGVwcmVjYXRlZEZpZWxkTnVtYmVyOworY29uc3QgaW50IEZpZWxkT3B0aW9uczo6a1dlYWtGaWVsZE51bWJlcjsKK2NvbnN0IGludCBGaWVsZE9wdGlvbnM6OmtVbmludGVycHJldGVkT3B0aW9uRmllbGROdW1iZXI7CisjZW5kaWYgIC8vICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCisKK0ZpZWxkT3B0aW9uczo6RmllbGRPcHRpb25zKCkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMpCit9CisKK3ZvaWQgRmllbGRPcHRpb25zOjpJbml0QXNEZWZhdWx0SW5zdGFuY2UoKSB7Cit9CisKK0ZpZWxkT3B0aW9uczo6RmllbGRPcHRpb25zKGNvbnN0IEZpZWxkT3B0aW9ucyYgZnJvbSkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwKKyAgICBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICBNZXJnZUZyb20oZnJvbSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb3B5X2NvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMpCit9CisKK3ZvaWQgRmllbGRPcHRpb25zOjpTaGFyZWRDdG9yKCkgeworICBfY2FjaGVkX3NpemVfID0gMDsKKyAgY3R5cGVfID0gMDsKKyAgcGFja2VkXyA9IGZhbHNlOworICBqc3R5cGVfID0gMDsKKyAgbGF6eV8gPSBmYWxzZTsKKyAgZGVwcmVjYXRlZF8gPSBmYWxzZTsKKyAgd2Vha18gPSBmYWxzZTsKKyAgOjptZW1zZXQoX2hhc19iaXRzXywgMCwgc2l6ZW9mKF9oYXNfYml0c18pKTsKK30KKworRmllbGRPcHRpb25zOjp+RmllbGRPcHRpb25zKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZGVzdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zKQorICBTaGFyZWREdG9yKCk7Cit9CisKK3ZvaWQgRmllbGRPcHRpb25zOjpTaGFyZWREdG9yKCkgeworICBpZiAodGhpcyAhPSBkZWZhdWx0X2luc3RhbmNlXykgeworICB9Cit9CisKK3ZvaWQgRmllbGRPcHRpb25zOjpTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdCB7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSBzaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogRmllbGRPcHRpb25zOjpkZXNjcmlwdG9yKCkgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgcmV0dXJuIEZpZWxkT3B0aW9uc19kZXNjcmlwdG9yXzsKK30KKworY29uc3QgRmllbGRPcHRpb25zJiBGaWVsZE9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2UoKSB7CisgIGlmIChkZWZhdWx0X2luc3RhbmNlXyA9PSBOVUxMKSBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIHJldHVybiAqZGVmYXVsdF9pbnN0YW5jZV87Cit9CisKK0ZpZWxkT3B0aW9ucyogRmllbGRPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlXyA9IE5VTEw7CisKK0ZpZWxkT3B0aW9ucyogRmllbGRPcHRpb25zOjpOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0IHsKKyAgRmllbGRPcHRpb25zKiBuID0gbmV3IEZpZWxkT3B0aW9uczsKKyAgaWYgKGFyZW5hICE9IE5VTEwpIHsKKyAgICBhcmVuYS0+T3duKG4pOworICB9CisgIHJldHVybiBuOworfQorCit2b2lkIEZpZWxkT3B0aW9uczo6Q2xlYXIoKSB7CisgIF9leHRlbnNpb25zXy5DbGVhcigpOworI2RlZmluZSBaUl9IRUxQRVJfKGYpIHJlaW50ZXJwcmV0X2Nhc3Q8Y2hhcio+KFwKKyAgJnJlaW50ZXJwcmV0X2Nhc3Q8RmllbGRPcHRpb25zKj4oMTYpLT5mKQorCisjZGVmaW5lIFpSXyhmaXJzdCwgbGFzdCkgZG8ge1wKKyAgOjptZW1zZXQoJmZpcnN0LCAwLFwKKyAgICAgICAgICAgWlJfSEVMUEVSXyhsYXN0KSAtIFpSX0hFTFBFUl8oZmlyc3QpICsgc2l6ZW9mKGxhc3QpKTtcCit9IHdoaWxlICgwKQorCisgIGlmIChfaGFzX2JpdHNfWzAgLyAzMl0gJiA2M3UpIHsKKyAgICBaUl8oY3R5cGVfLCBqc3R5cGVfKTsKKyAgICBaUl8ocGFja2VkXywgd2Vha18pOworICB9CisKKyN1bmRlZiBaUl9IRUxQRVJfCisjdW5kZWYgWlJfCisKKyAgdW5pbnRlcnByZXRlZF9vcHRpb25fLkNsZWFyKCk7CisgIDo6bWVtc2V0KF9oYXNfYml0c18sIDAsIHNpemVvZihfaGFzX2JpdHNfKSk7CisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+Q2xlYXIoKTsKKyAgfQorfQorCitib29sIEZpZWxkT3B0aW9uczo6TWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KSB7CisjZGVmaW5lIERPXyhFWFBSRVNTSU9OKSBpZiAoIShFWFBSRVNTSU9OKSkgZ290byBmYWlsdXJlCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIHRhZzsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMpCisgIGZvciAoOzspIHsKKyAgICA6OnN0ZDo6cGFpcjwgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIsIGJvb2w+IHAgPSBpbnB1dC0+UmVhZFRhZ1dpdGhDdXRvZmYoMTYzODMpOworICAgIHRhZyA9IHAuZmlyc3Q7CisgICAgaWYgKCFwLnNlY29uZCkgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICBzd2l0Y2ggKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdGaWVsZE51bWJlcih0YWcpKSB7CisgICAgICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5DVHlwZSBjdHlwZSA9IDEgW2RlZmF1bHQgPSBTVFJJTkddOworICAgICAgY2FzZSAxOiB7CisgICAgICAgIGlmICh0YWcgPT0gOCkgeworICAgICAgICAgIGludCB2YWx1ZTsKKyAgICAgICAgICBET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPAorICAgICAgICAgICAgICAgICAgIGludCwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfRU5VTT4oCisgICAgICAgICAgICAgICAgIGlucHV0LCAmdmFsdWUpKSk7CisgICAgICAgICAgaWYgKDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGRPcHRpb25zX0NUeXBlX0lzVmFsaWQodmFsdWUpKSB7CisgICAgICAgICAgICBzZXRfY3R5cGUoc3RhdGljX2Nhc3Q8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGRPcHRpb25zX0NUeXBlID4odmFsdWUpKTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5BZGRWYXJpbnQoMSwgdmFsdWUpOworICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDE2KSkgZ290byBwYXJzZV9wYWNrZWQ7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCBib29sIHBhY2tlZCA9IDI7CisgICAgICBjYXNlIDI6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAxNikgeworICAgICAgICAgcGFyc2VfcGFja2VkOgorICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgYm9vbCwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfQk9PTD4oCisgICAgICAgICAgICAgICAgIGlucHV0LCAmcGFja2VkXykpKTsKKyAgICAgICAgICBzZXRfaGFzX3BhY2tlZCgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMjQpKSBnb3RvIHBhcnNlX2RlcHJlY2F0ZWQ7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCBib29sIGRlcHJlY2F0ZWQgPSAzIFtkZWZhdWx0ID0gZmFsc2VdOworICAgICAgY2FzZSAzOiB7CisgICAgICAgIGlmICh0YWcgPT0gMjQpIHsKKyAgICAgICAgIHBhcnNlX2RlcHJlY2F0ZWQ6CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICBib29sLCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9CT09MPigKKyAgICAgICAgICAgICAgICAgaW5wdXQsICZkZXByZWNhdGVkXykpKTsKKyAgICAgICAgICBzZXRfaGFzX2RlcHJlY2F0ZWQoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDQwKSkgZ290byBwYXJzZV9sYXp5OworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgYm9vbCBsYXp5ID0gNSBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgICAgIGNhc2UgNTogeworICAgICAgICBpZiAodGFnID09IDQwKSB7CisgICAgICAgICBwYXJzZV9sYXp5OgorICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgYm9vbCwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfQk9PTD4oCisgICAgICAgICAgICAgICAgIGlucHV0LCAmbGF6eV8pKSk7CisgICAgICAgICAgc2V0X2hhc19sYXp5KCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg0OCkpIGdvdG8gcGFyc2VfanN0eXBlOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuSlNUeXBlIGpzdHlwZSA9IDYgW2RlZmF1bHQgPSBKU19OT1JNQUxdOworICAgICAgY2FzZSA2OiB7CisgICAgICAgIGlmICh0YWcgPT0gNDgpIHsKKyAgICAgICAgIHBhcnNlX2pzdHlwZToKKyAgICAgICAgICBpbnQgdmFsdWU7CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICBpbnQsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0VOVU0+KAorICAgICAgICAgICAgICAgICBpbnB1dCwgJnZhbHVlKSkpOworICAgICAgICAgIGlmICg6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkT3B0aW9uc19KU1R5cGVfSXNWYWxpZCh2YWx1ZSkpIHsKKyAgICAgICAgICAgIHNldF9qc3R5cGUoc3RhdGljX2Nhc3Q8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGRPcHRpb25zX0pTVHlwZSA+KHZhbHVlKSk7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+QWRkVmFyaW50KDYsIHZhbHVlKTsKKyAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg4MCkpIGdvdG8gcGFyc2Vfd2VhazsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIGJvb2wgd2VhayA9IDEwIFtkZWZhdWx0ID0gZmFsc2VdOworICAgICAgY2FzZSAxMDogeworICAgICAgICBpZiAodGFnID09IDgwKSB7CisgICAgICAgICBwYXJzZV93ZWFrOgorICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgYm9vbCwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfQk9PTD4oCisgICAgICAgICAgICAgICAgIGlucHV0LCAmd2Vha18pKSk7CisgICAgICAgICAgc2V0X2hhc193ZWFrKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg3OTk0KSkgZ290byBwYXJzZV91bmludGVycHJldGVkX29wdGlvbjsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiB1bmludGVycHJldGVkX29wdGlvbiA9IDk5OTsKKyAgICAgIGNhc2UgOTk5OiB7CisgICAgICAgIGlmICh0YWcgPT0gNzk5NCkgeworICAgICAgICAgcGFyc2VfdW5pbnRlcnByZXRlZF9vcHRpb246CisgICAgICAgICAgRE9fKGlucHV0LT5JbmNyZW1lbnRSZWN1cnNpb25EZXB0aCgpKTsKKyAgICAgICAgIHBhcnNlX2xvb3BfdW5pbnRlcnByZXRlZF9vcHRpb246CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkTWVzc2FnZU5vVmlydHVhbE5vUmVjdXJzaW9uRGVwdGgoCisgICAgICAgICAgICAgICAgaW5wdXQsIGFkZF91bmludGVycHJldGVkX29wdGlvbigpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg3OTk0KSkgZ290byBwYXJzZV9sb29wX3VuaW50ZXJwcmV0ZWRfb3B0aW9uOworICAgICAgICBpbnB1dC0+VW5zYWZlRGVjcmVtZW50UmVjdXJzaW9uRGVwdGgoKTsKKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RBdEVuZCgpKSBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBkZWZhdWx0OiB7CisgICAgICBoYW5kbGVfdW51c3VhbDoKKyAgICAgICAgaWYgKHRhZyA9PSAwIHx8CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnV2lyZVR5cGUodGFnKSA9PQorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0VORF9HUk9VUCkgeworICAgICAgICAgIGdvdG8gc3VjY2VzczsKKyAgICAgICAgfQorICAgICAgICBpZiAoKDgwMDB1IDw9IHRhZykpIHsKKyAgICAgICAgICBET18oX2V4dGVuc2lvbnNfLlBhcnNlRmllbGQodGFnLCBpbnB1dCwgZGVmYXVsdF9pbnN0YW5jZV8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSkpOworICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTa2lwRmllbGQoCisgICAgICAgICAgICAgIGlucHV0LCB0YWcsIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSkpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KK3N1Y2Nlc3M6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdWNjZXNzOmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMpCisgIHJldHVybiB0cnVlOworZmFpbHVyZToKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX2ZhaWx1cmU6Z29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucykKKyAgcmV0dXJuIGZhbHNlOworI3VuZGVmIERPXworfQorCit2b2lkIEZpZWxkT3B0aW9uczo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9zdGFydDpnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zKQorICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5DVHlwZSBjdHlwZSA9IDEgW2RlZmF1bHQgPSBTVFJJTkddOworICBpZiAoaGFzX2N0eXBlKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVFbnVtKAorICAgICAgMSwgdGhpcy0+Y3R5cGUoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGJvb2wgcGFja2VkID0gMjsKKyAgaWYgKGhhc19wYWNrZWQoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2woMiwgdGhpcy0+cGFja2VkKCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBib29sIGRlcHJlY2F0ZWQgPSAzIFtkZWZhdWx0ID0gZmFsc2VdOworICBpZiAoaGFzX2RlcHJlY2F0ZWQoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2woMywgdGhpcy0+ZGVwcmVjYXRlZCgpLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgYm9vbCBsYXp5ID0gNSBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgaWYgKGhhc19sYXp5KCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCb29sKDUsIHRoaXMtPmxhenkoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLkpTVHlwZSBqc3R5cGUgPSA2IFtkZWZhdWx0ID0gSlNfTk9STUFMXTsKKyAgaWYgKGhhc19qc3R5cGUoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUVudW0oCisgICAgICA2LCB0aGlzLT5qc3R5cGUoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGJvb2wgd2VhayA9IDEwIFtkZWZhdWx0ID0gZmFsc2VdOworICBpZiAoaGFzX3dlYWsoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2woMTAsIHRoaXMtPndlYWsoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiB1bmludGVycHJldGVkX29wdGlvbiA9IDk5OTsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT51bmludGVycHJldGVkX29wdGlvbl9zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgOTk5LCB0aGlzLT51bmludGVycHJldGVkX29wdGlvbihpKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIEV4dGVuc2lvbiByYW5nZSBbMTAwMCwgNTM2ODcwOTEyKQorICBfZXh0ZW5zaW9uc18uU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgICAgMTAwMCwgNTM2ODcwOTEyLCBvdXRwdXQpOworCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25GaWVsZHMoCisgICAgICAgIHVua25vd25fZmllbGRzKCksIG91dHB1dCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9lbmQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucykKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogRmllbGRPcHRpb25zOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIHRhcmdldCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMpCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLkNUeXBlIGN0eXBlID0gMSBbZGVmYXVsdCA9IFNUUklOR107CisgIGlmIChoYXNfY3R5cGUoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUVudW1Ub0FycmF5KAorICAgICAgMSwgdGhpcy0+Y3R5cGUoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGJvb2wgcGFja2VkID0gMjsKKyAgaWYgKGhhc19wYWNrZWQoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2xUb0FycmF5KDIsIHRoaXMtPnBhY2tlZCgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgYm9vbCBkZXByZWNhdGVkID0gMyBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgaWYgKGhhc19kZXByZWNhdGVkKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCb29sVG9BcnJheSgzLCB0aGlzLT5kZXByZWNhdGVkKCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBib29sIGxhenkgPSA1IFtkZWZhdWx0ID0gZmFsc2VdOworICBpZiAoaGFzX2xhenkoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2xUb0FycmF5KDUsIHRoaXMtPmxhenkoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLkpTVHlwZSBqc3R5cGUgPSA2IFtkZWZhdWx0ID0gSlNfTk9STUFMXTsKKyAgaWYgKGhhc19qc3R5cGUoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUVudW1Ub0FycmF5KAorICAgICAgNiwgdGhpcy0+anN0eXBlKCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBib29sIHdlYWsgPSAxMCBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgaWYgKGhhc193ZWFrKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCb29sVG9BcnJheSgxMCwgdGhpcy0+d2VhaygpLCB0YXJnZXQpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIHVuaW50ZXJwcmV0ZWRfb3B0aW9uID0gOTk5OworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPnVuaW50ZXJwcmV0ZWRfb3B0aW9uX3NpemUoKTsgaSA8IG47IGkrKykgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjoKKyAgICAgIFdyaXRlTWVzc2FnZU5vVmlydHVhbFRvQXJyYXkoCisgICAgICAgIDk5OSwgdGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb24oaSksIHRhcmdldCk7CisgIH0KKworICAvLyBFeHRlbnNpb24gcmFuZ2UgWzEwMDAsIDUzNjg3MDkxMikKKyAgdGFyZ2V0ID0gX2V4dGVuc2lvbnNfLlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoCisgICAgICAxMDAwLCA1MzY4NzA5MTIsIHRhcmdldCk7CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bkZpZWxkc1RvQXJyYXkoCisgICAgICAgIHVua25vd25fZmllbGRzKCksIHRhcmdldCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9lbmQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucykKKyAgcmV0dXJuIHRhcmdldDsKK30KKworaW50IEZpZWxkT3B0aW9uczo6Qnl0ZVNpemUoKSBjb25zdCB7CisgIGludCB0b3RhbF9zaXplID0gMDsKKworICBpZiAoX2hhc19iaXRzX1swIC8gMzJdICYgNjN1KSB7CisgICAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuQ1R5cGUgY3R5cGUgPSAxIFtkZWZhdWx0ID0gU1RSSU5HXTsKKyAgICBpZiAoaGFzX2N0eXBlKCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpFbnVtU2l6ZSh0aGlzLT5jdHlwZSgpKTsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCBib29sIHBhY2tlZCA9IDI7CisgICAgaWYgKGhhc19wYWNrZWQoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsgMTsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5KU1R5cGUganN0eXBlID0gNiBbZGVmYXVsdCA9IEpTX05PUk1BTF07CisgICAgaWYgKGhhc19qc3R5cGUoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkVudW1TaXplKHRoaXMtPmpzdHlwZSgpKTsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCBib29sIGxhenkgPSA1IFtkZWZhdWx0ID0gZmFsc2VdOworICAgIGlmIChoYXNfbGF6eSgpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKyAxOworICAgIH0KKworICAgIC8vIG9wdGlvbmFsIGJvb2wgZGVwcmVjYXRlZCA9IDMgW2RlZmF1bHQgPSBmYWxzZV07CisgICAgaWYgKGhhc19kZXByZWNhdGVkKCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArIDE7CisgICAgfQorCisgICAgLy8gb3B0aW9uYWwgYm9vbCB3ZWFrID0gMTAgW2RlZmF1bHQgPSBmYWxzZV07CisgICAgaWYgKGhhc193ZWFrKCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArIDE7CisgICAgfQorCisgIH0KKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIHVuaW50ZXJwcmV0ZWRfb3B0aW9uID0gOTk5OworICB0b3RhbF9zaXplICs9IDIgKiB0aGlzLT51bmludGVycHJldGVkX29wdGlvbl9zaXplKCk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb25fc2l6ZSgpOyBpKyspIHsKKyAgICB0b3RhbF9zaXplICs9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6TWVzc2FnZVNpemVOb1ZpcnR1YWwoCisgICAgICAgIHRoaXMtPnVuaW50ZXJwcmV0ZWRfb3B0aW9uKGkpKTsKKyAgfQorCisgIHRvdGFsX3NpemUgKz0gX2V4dGVuc2lvbnNfLkJ5dGVTaXplKCk7CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6Q29tcHV0ZVVua25vd25GaWVsZHNTaXplKAorICAgICAgICB1bmtub3duX2ZpZWxkcygpKTsKKyAgfQorICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gdG90YWxfc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7CisgIHJldHVybiB0b3RhbF9zaXplOworfQorCit2b2lkIEZpZWxkT3B0aW9uczo6TWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBjb25zdCBGaWVsZE9wdGlvbnMqIHNvdXJjZSA9IAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RHluYW1pY0Nhc3RUb0dlbmVyYXRlZDxjb25zdCBGaWVsZE9wdGlvbnM+KAorICAgICAgICAgICZmcm9tKTsKKyAgaWYgKHNvdXJjZSA9PSBOVUxMKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6UmVmbGVjdGlvbk9wczo6TWVyZ2UoZnJvbSwgdGhpcyk7CisgIH0gZWxzZSB7CisgICAgTWVyZ2VGcm9tKCpzb3VyY2UpOworICB9Cit9CisKK3ZvaWQgRmllbGRPcHRpb25zOjpNZXJnZUZyb20oY29uc3QgRmllbGRPcHRpb25zJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5NZXJnZUZyb20oZnJvbS51bmludGVycHJldGVkX29wdGlvbl8pOworICBpZiAoZnJvbS5faGFzX2JpdHNfWzAgLyAzMl0gJiAoMHhmZnUgPDwgKDAgJSAzMikpKSB7CisgICAgaWYgKGZyb20uaGFzX2N0eXBlKCkpIHsKKyAgICAgIHNldF9jdHlwZShmcm9tLmN0eXBlKCkpOworICAgIH0KKyAgICBpZiAoZnJvbS5oYXNfcGFja2VkKCkpIHsKKyAgICAgIHNldF9wYWNrZWQoZnJvbS5wYWNrZWQoKSk7CisgICAgfQorICAgIGlmIChmcm9tLmhhc19qc3R5cGUoKSkgeworICAgICAgc2V0X2pzdHlwZShmcm9tLmpzdHlwZSgpKTsKKyAgICB9CisgICAgaWYgKGZyb20uaGFzX2xhenkoKSkgeworICAgICAgc2V0X2xhenkoZnJvbS5sYXp5KCkpOworICAgIH0KKyAgICBpZiAoZnJvbS5oYXNfZGVwcmVjYXRlZCgpKSB7CisgICAgICBzZXRfZGVwcmVjYXRlZChmcm9tLmRlcHJlY2F0ZWQoKSk7CisgICAgfQorICAgIGlmIChmcm9tLmhhc193ZWFrKCkpIHsKKyAgICAgIHNldF93ZWFrKGZyb20ud2VhaygpKTsKKyAgICB9CisgIH0KKyAgX2V4dGVuc2lvbnNfLk1lcmdlRnJvbShmcm9tLl9leHRlbnNpb25zXyk7CisgIGlmIChmcm9tLl9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5NZXJnZUZyb20oZnJvbS51bmtub3duX2ZpZWxkcygpKTsKKyAgfQorfQorCit2b2lkIEZpZWxkT3B0aW9uczo6Q29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKwordm9pZCBGaWVsZE9wdGlvbnM6OkNvcHlGcm9tKGNvbnN0IEZpZWxkT3B0aW9ucyYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK2Jvb2wgRmllbGRPcHRpb25zOjpJc0luaXRpYWxpemVkKCkgY29uc3QgeworCisgIGlmICghOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QWxsQXJlSW5pdGlhbGl6ZWQodGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb24oKSkpIHJldHVybiBmYWxzZTsKKworICBpZiAoIV9leHRlbnNpb25zXy5Jc0luaXRpYWxpemVkKCkpIHJldHVybiBmYWxzZTsgIHJldHVybiB0cnVlOworfQorCit2b2lkIEZpZWxkT3B0aW9uczo6U3dhcChGaWVsZE9wdGlvbnMqIG90aGVyKSB7CisgIGlmIChvdGhlciA9PSB0aGlzKSByZXR1cm47CisgIEludGVybmFsU3dhcChvdGhlcik7Cit9Cit2b2lkIEZpZWxkT3B0aW9uczo6SW50ZXJuYWxTd2FwKEZpZWxkT3B0aW9ucyogb3RoZXIpIHsKKyAgc3RkOjpzd2FwKGN0eXBlXywgb3RoZXItPmN0eXBlXyk7CisgIHN0ZDo6c3dhcChwYWNrZWRfLCBvdGhlci0+cGFja2VkXyk7CisgIHN0ZDo6c3dhcChqc3R5cGVfLCBvdGhlci0+anN0eXBlXyk7CisgIHN0ZDo6c3dhcChsYXp5Xywgb3RoZXItPmxhenlfKTsKKyAgc3RkOjpzd2FwKGRlcHJlY2F0ZWRfLCBvdGhlci0+ZGVwcmVjYXRlZF8pOworICBzdGQ6OnN3YXAod2Vha18sIG90aGVyLT53ZWFrXyk7CisgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5VbnNhZmVBcmVuYVN3YXAoJm90aGVyLT51bmludGVycHJldGVkX29wdGlvbl8pOworICBzdGQ6OnN3YXAoX2hhc19iaXRzX1swXSwgb3RoZXItPl9oYXNfYml0c19bMF0pOworICBfaW50ZXJuYWxfbWV0YWRhdGFfLlN3YXAoJm90aGVyLT5faW50ZXJuYWxfbWV0YWRhdGFfKTsKKyAgc3RkOjpzd2FwKF9jYWNoZWRfc2l6ZV8sIG90aGVyLT5fY2FjaGVkX3NpemVfKTsKKyAgX2V4dGVuc2lvbnNfLlN3YXAoJm90aGVyLT5fZXh0ZW5zaW9uc18pOworfQorCis6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEZpZWxkT3B0aW9uczo6R2V0TWV0YWRhdGEoKSBjb25zdCB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIG1ldGFkYXRhOworICBtZXRhZGF0YS5kZXNjcmlwdG9yID0gRmllbGRPcHRpb25zX2Rlc2NyaXB0b3JfOworICBtZXRhZGF0YS5yZWZsZWN0aW9uID0gRmllbGRPcHRpb25zX3JlZmxlY3Rpb25fOworICByZXR1cm4gbWV0YWRhdGE7Cit9CisKKyNpZiBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKy8vIEZpZWxkT3B0aW9ucworCisvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5DVHlwZSBjdHlwZSA9IDEgW2RlZmF1bHQgPSBTVFJJTkddOworYm9vbCBGaWVsZE9wdGlvbnM6Omhhc19jdHlwZSgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMXUpICE9IDA7Cit9Cit2b2lkIEZpZWxkT3B0aW9uczo6c2V0X2hhc19jdHlwZSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAxdTsKK30KK3ZvaWQgRmllbGRPcHRpb25zOjpjbGVhcl9oYXNfY3R5cGUoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDF1OworfQordm9pZCBGaWVsZE9wdGlvbnM6OmNsZWFyX2N0eXBlKCkgeworICBjdHlwZV8gPSAwOworICBjbGVhcl9oYXNfY3R5cGUoKTsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkT3B0aW9uc19DVHlwZSBGaWVsZE9wdGlvbnM6OmN0eXBlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuY3R5cGUpCisgIHJldHVybiBzdGF0aWNfY2FzdDwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZE9wdGlvbnNfQ1R5cGUgPihjdHlwZV8pOworfQorIHZvaWQgRmllbGRPcHRpb25zOjpzZXRfY3R5cGUoOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZE9wdGlvbnNfQ1R5cGUgdmFsdWUpIHsKKyAgYXNzZXJ0KDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGRPcHRpb25zX0NUeXBlX0lzVmFsaWQodmFsdWUpKTsKKyAgc2V0X2hhc19jdHlwZSgpOworICBjdHlwZV8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLmN0eXBlKQorfQorCisvLyBvcHRpb25hbCBib29sIHBhY2tlZCA9IDI7Citib29sIEZpZWxkT3B0aW9uczo6aGFzX3BhY2tlZCgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMnUpICE9IDA7Cit9Cit2b2lkIEZpZWxkT3B0aW9uczo6c2V0X2hhc19wYWNrZWQoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMnU7Cit9Cit2b2lkIEZpZWxkT3B0aW9uczo6Y2xlYXJfaGFzX3BhY2tlZCgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMnU7Cit9Cit2b2lkIEZpZWxkT3B0aW9uczo6Y2xlYXJfcGFja2VkKCkgeworICBwYWNrZWRfID0gZmFsc2U7CisgIGNsZWFyX2hhc19wYWNrZWQoKTsKK30KKyBib29sIEZpZWxkT3B0aW9uczo6cGFja2VkKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMucGFja2VkKQorICByZXR1cm4gcGFja2VkXzsKK30KKyB2b2lkIEZpZWxkT3B0aW9uczo6c2V0X3BhY2tlZChib29sIHZhbHVlKSB7CisgIHNldF9oYXNfcGFja2VkKCk7CisgIHBhY2tlZF8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLnBhY2tlZCkKK30KKworLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuSlNUeXBlIGpzdHlwZSA9IDYgW2RlZmF1bHQgPSBKU19OT1JNQUxdOworYm9vbCBGaWVsZE9wdGlvbnM6Omhhc19qc3R5cGUoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDR1KSAhPSAwOworfQordm9pZCBGaWVsZE9wdGlvbnM6OnNldF9oYXNfanN0eXBlKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDR1OworfQordm9pZCBGaWVsZE9wdGlvbnM6OmNsZWFyX2hhc19qc3R5cGUoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDR1OworfQordm9pZCBGaWVsZE9wdGlvbnM6OmNsZWFyX2pzdHlwZSgpIHsKKyAganN0eXBlXyA9IDA7CisgIGNsZWFyX2hhc19qc3R5cGUoKTsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkT3B0aW9uc19KU1R5cGUgRmllbGRPcHRpb25zOjpqc3R5cGUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5qc3R5cGUpCisgIHJldHVybiBzdGF0aWNfY2FzdDwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZE9wdGlvbnNfSlNUeXBlID4oanN0eXBlXyk7Cit9Cisgdm9pZCBGaWVsZE9wdGlvbnM6OnNldF9qc3R5cGUoOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZE9wdGlvbnNfSlNUeXBlIHZhbHVlKSB7CisgIGFzc2VydCg6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkT3B0aW9uc19KU1R5cGVfSXNWYWxpZCh2YWx1ZSkpOworICBzZXRfaGFzX2pzdHlwZSgpOworICBqc3R5cGVfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5qc3R5cGUpCit9CisKKy8vIG9wdGlvbmFsIGJvb2wgbGF6eSA9IDUgW2RlZmF1bHQgPSBmYWxzZV07Citib29sIEZpZWxkT3B0aW9uczo6aGFzX2xhenkoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDh1KSAhPSAwOworfQordm9pZCBGaWVsZE9wdGlvbnM6OnNldF9oYXNfbGF6eSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDA4dTsKK30KK3ZvaWQgRmllbGRPcHRpb25zOjpjbGVhcl9oYXNfbGF6eSgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwOHU7Cit9Cit2b2lkIEZpZWxkT3B0aW9uczo6Y2xlYXJfbGF6eSgpIHsKKyAgbGF6eV8gPSBmYWxzZTsKKyAgY2xlYXJfaGFzX2xhenkoKTsKK30KKyBib29sIEZpZWxkT3B0aW9uczo6bGF6eSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLmxhenkpCisgIHJldHVybiBsYXp5XzsKK30KKyB2b2lkIEZpZWxkT3B0aW9uczo6c2V0X2xhenkoYm9vbCB2YWx1ZSkgeworICBzZXRfaGFzX2xhenkoKTsKKyAgbGF6eV8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLmxhenkpCit9CisKKy8vIG9wdGlvbmFsIGJvb2wgZGVwcmVjYXRlZCA9IDMgW2RlZmF1bHQgPSBmYWxzZV07Citib29sIEZpZWxkT3B0aW9uczo6aGFzX2RlcHJlY2F0ZWQoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMTB1KSAhPSAwOworfQordm9pZCBGaWVsZE9wdGlvbnM6OnNldF9oYXNfZGVwcmVjYXRlZCgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDEwdTsKK30KK3ZvaWQgRmllbGRPcHRpb25zOjpjbGVhcl9oYXNfZGVwcmVjYXRlZCgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAxMHU7Cit9Cit2b2lkIEZpZWxkT3B0aW9uczo6Y2xlYXJfZGVwcmVjYXRlZCgpIHsKKyAgZGVwcmVjYXRlZF8gPSBmYWxzZTsKKyAgY2xlYXJfaGFzX2RlcHJlY2F0ZWQoKTsKK30KKyBib29sIEZpZWxkT3B0aW9uczo6ZGVwcmVjYXRlZCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLmRlcHJlY2F0ZWQpCisgIHJldHVybiBkZXByZWNhdGVkXzsKK30KKyB2b2lkIEZpZWxkT3B0aW9uczo6c2V0X2RlcHJlY2F0ZWQoYm9vbCB2YWx1ZSkgeworICBzZXRfaGFzX2RlcHJlY2F0ZWQoKTsKKyAgZGVwcmVjYXRlZF8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLmRlcHJlY2F0ZWQpCit9CisKKy8vIG9wdGlvbmFsIGJvb2wgd2VhayA9IDEwIFtkZWZhdWx0ID0gZmFsc2VdOworYm9vbCBGaWVsZE9wdGlvbnM6Omhhc193ZWFrKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDIwdSkgIT0gMDsKK30KK3ZvaWQgRmllbGRPcHRpb25zOjpzZXRfaGFzX3dlYWsoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAyMHU7Cit9Cit2b2lkIEZpZWxkT3B0aW9uczo6Y2xlYXJfaGFzX3dlYWsoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMjB1OworfQordm9pZCBGaWVsZE9wdGlvbnM6OmNsZWFyX3dlYWsoKSB7CisgIHdlYWtfID0gZmFsc2U7CisgIGNsZWFyX2hhc193ZWFrKCk7Cit9CisgYm9vbCBGaWVsZE9wdGlvbnM6OndlYWsoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy53ZWFrKQorICByZXR1cm4gd2Vha187Cit9Cisgdm9pZCBGaWVsZE9wdGlvbnM6OnNldF93ZWFrKGJvb2wgdmFsdWUpIHsKKyAgc2V0X2hhc193ZWFrKCk7CisgIHdlYWtfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy53ZWFrKQorfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CitpbnQgRmllbGRPcHRpb25zOjp1bmludGVycHJldGVkX29wdGlvbl9zaXplKCkgY29uc3QgeworICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLnNpemUoKTsKK30KK3ZvaWQgRmllbGRPcHRpb25zOjpjbGVhcl91bmludGVycHJldGVkX29wdGlvbigpIHsKKyAgdW5pbnRlcnByZXRlZF9vcHRpb25fLkNsZWFyKCk7Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24mIEZpZWxkT3B0aW9uczo6dW5pbnRlcnByZXRlZF9vcHRpb24oaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5HZXQoaW5kZXgpOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uKiBGaWVsZE9wdGlvbnM6Om11dGFibGVfdW5pbnRlcnByZXRlZF9vcHRpb24oaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl8uTXV0YWJsZShpbmRleCk7Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24qIEZpZWxkT3B0aW9uczo6YWRkX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl8uQWRkKCk7Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiA+KgorRmllbGRPcHRpb25zOjptdXRhYmxlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiAmdW5pbnRlcnByZXRlZF9vcHRpb25fOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24gPiYKK0ZpZWxkT3B0aW9uczo6dW5pbnRlcnByZXRlZF9vcHRpb24oKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl87Cit9CisKKyNlbmRpZiAgLy8gUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworI2lmICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCitjb25zdCBpbnQgRW51bU9wdGlvbnM6OmtBbGxvd0FsaWFzRmllbGROdW1iZXI7Citjb25zdCBpbnQgRW51bU9wdGlvbnM6OmtEZXByZWNhdGVkRmllbGROdW1iZXI7Citjb25zdCBpbnQgRW51bU9wdGlvbnM6OmtVbmludGVycHJldGVkT3B0aW9uRmllbGROdW1iZXI7CisjZW5kaWYgIC8vICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCisKK0VudW1PcHRpb25zOjpFbnVtT3B0aW9ucygpCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgeworICBTaGFyZWRDdG9yKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnMpCit9CisKK3ZvaWQgRW51bU9wdGlvbnM6OkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpIHsKK30KKworRW51bU9wdGlvbnM6OkVudW1PcHRpb25zKGNvbnN0IEVudW1PcHRpb25zJiBmcm9tKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpLAorICAgIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgeworICBTaGFyZWRDdG9yKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvcHlfY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zKQorfQorCit2b2lkIEVudW1PcHRpb25zOjpTaGFyZWRDdG9yKCkgeworICBfY2FjaGVkX3NpemVfID0gMDsKKyAgYWxsb3dfYWxpYXNfID0gZmFsc2U7CisgIGRlcHJlY2F0ZWRfID0gZmFsc2U7CisgIDo6bWVtc2V0KF9oYXNfYml0c18sIDAsIHNpemVvZihfaGFzX2JpdHNfKSk7Cit9CisKK0VudW1PcHRpb25zOjp+RW51bU9wdGlvbnMoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChkZXN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucykKKyAgU2hhcmVkRHRvcigpOworfQorCit2b2lkIEVudW1PcHRpb25zOjpTaGFyZWREdG9yKCkgeworICBpZiAodGhpcyAhPSBkZWZhdWx0X2luc3RhbmNlXykgeworICB9Cit9CisKK3ZvaWQgRW51bU9wdGlvbnM6OlNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0IHsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHNpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBFbnVtT3B0aW9uczo6ZGVzY3JpcHRvcigpIHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIHJldHVybiBFbnVtT3B0aW9uc19kZXNjcmlwdG9yXzsKK30KKworY29uc3QgRW51bU9wdGlvbnMmIEVudW1PcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlKCkgeworICBpZiAoZGVmYXVsdF9pbnN0YW5jZV8gPT0gTlVMTCkgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICByZXR1cm4gKmRlZmF1bHRfaW5zdGFuY2VfOworfQorCitFbnVtT3B0aW9ucyogRW51bU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2VfID0gTlVMTDsKKworRW51bU9wdGlvbnMqIEVudW1PcHRpb25zOjpOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0IHsKKyAgRW51bU9wdGlvbnMqIG4gPSBuZXcgRW51bU9wdGlvbnM7CisgIGlmIChhcmVuYSAhPSBOVUxMKSB7CisgICAgYXJlbmEtPk93bihuKTsKKyAgfQorICByZXR1cm4gbjsKK30KKwordm9pZCBFbnVtT3B0aW9uczo6Q2xlYXIoKSB7CisgIF9leHRlbnNpb25zXy5DbGVhcigpOworI2RlZmluZSBaUl9IRUxQRVJfKGYpIHJlaW50ZXJwcmV0X2Nhc3Q8Y2hhcio+KFwKKyAgJnJlaW50ZXJwcmV0X2Nhc3Q8RW51bU9wdGlvbnMqPigxNiktPmYpCisKKyNkZWZpbmUgWlJfKGZpcnN0LCBsYXN0KSBkbyB7XAorICA6Om1lbXNldCgmZmlyc3QsIDAsXAorICAgICAgICAgICBaUl9IRUxQRVJfKGxhc3QpIC0gWlJfSEVMUEVSXyhmaXJzdCkgKyBzaXplb2YobGFzdCkpO1wKK30gd2hpbGUgKDApCisKKyAgWlJfKGFsbG93X2FsaWFzXywgZGVwcmVjYXRlZF8pOworCisjdW5kZWYgWlJfSEVMUEVSXworI3VuZGVmIFpSXworCisgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5DbGVhcigpOworICA6Om1lbXNldChfaGFzX2JpdHNfLCAwLCBzaXplb2YoX2hhc19iaXRzXykpOworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkNsZWFyKCk7CisgIH0KK30KKworYm9vbCBFbnVtT3B0aW9uczo6TWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KSB7CisjZGVmaW5lIERPXyhFWFBSRVNTSU9OKSBpZiAoIShFWFBSRVNTSU9OKSkgZ290byBmYWlsdXJlCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIHRhZzsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucykKKyAgZm9yICg7OykgeworICAgIDo6c3RkOjpwYWlyPCA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiwgYm9vbD4gcCA9IGlucHV0LT5SZWFkVGFnV2l0aEN1dG9mZigxNjM4Myk7CisgICAgdGFnID0gcC5maXJzdDsKKyAgICBpZiAoIXAuc2Vjb25kKSBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgIHN3aXRjaCAoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ0ZpZWxkTnVtYmVyKHRhZykpIHsKKyAgICAgIC8vIG9wdGlvbmFsIGJvb2wgYWxsb3dfYWxpYXMgPSAyOworICAgICAgY2FzZSAyOiB7CisgICAgICAgIGlmICh0YWcgPT0gMTYpIHsKKyAgICAgICAgICBET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPAorICAgICAgICAgICAgICAgICAgIGJvb2wsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0JPT0w+KAorICAgICAgICAgICAgICAgICBpbnB1dCwgJmFsbG93X2FsaWFzXykpKTsKKyAgICAgICAgICBzZXRfaGFzX2FsbG93X2FsaWFzKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygyNCkpIGdvdG8gcGFyc2VfZGVwcmVjYXRlZDsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIGJvb2wgZGVwcmVjYXRlZCA9IDMgW2RlZmF1bHQgPSBmYWxzZV07CisgICAgICBjYXNlIDM6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAyNCkgeworICAgICAgICAgcGFyc2VfZGVwcmVjYXRlZDoKKyAgICAgICAgICBET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPAorICAgICAgICAgICAgICAgICAgIGJvb2wsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0JPT0w+KAorICAgICAgICAgICAgICAgICBpbnB1dCwgJmRlcHJlY2F0ZWRfKSkpOworICAgICAgICAgIHNldF9oYXNfZGVwcmVjYXRlZCgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNzk5NCkpIGdvdG8gcGFyc2VfdW5pbnRlcnByZXRlZF9vcHRpb247CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CisgICAgICBjYXNlIDk5OTogeworICAgICAgICBpZiAodGFnID09IDc5OTQpIHsKKyAgICAgICAgIHBhcnNlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uOgorICAgICAgICAgIERPXyhpbnB1dC0+SW5jcmVtZW50UmVjdXJzaW9uRGVwdGgoKSk7CisgICAgICAgICBwYXJzZV9sb29wX3VuaW50ZXJwcmV0ZWRfb3B0aW9uOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZE1lc3NhZ2VOb1ZpcnR1YWxOb1JlY3Vyc2lvbkRlcHRoKAorICAgICAgICAgICAgICAgIGlucHV0LCBhZGRfdW5pbnRlcnByZXRlZF9vcHRpb24oKSkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNzk5NCkpIGdvdG8gcGFyc2VfbG9vcF91bmludGVycHJldGVkX29wdGlvbjsKKyAgICAgICAgaW5wdXQtPlVuc2FmZURlY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCk7CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0QXRFbmQoKSkgZ290byBzdWNjZXNzOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgZGVmYXVsdDogeworICAgICAgaGFuZGxlX3VudXN1YWw6CisgICAgICAgIGlmICh0YWcgPT0gMCB8fAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ1dpcmVUeXBlKHRhZykgPT0KKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVApIHsKKyAgICAgICAgICBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCg4MDAwdSA8PSB0YWcpKSB7CisgICAgICAgICAgRE9fKF9leHRlbnNpb25zXy5QYXJzZUZpZWxkKHRhZywgaW5wdXQsIGRlZmF1bHRfaW5zdGFuY2VfLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkpKTsKKyAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2tpcEZpZWxkKAorICAgICAgICAgICAgICBpbnB1dCwgdGFnLCBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CitzdWNjZXNzOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3VjY2Vzczpnb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnMpCisgIHJldHVybiB0cnVlOworZmFpbHVyZToKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX2ZhaWx1cmU6Z29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zKQorICByZXR1cm4gZmFsc2U7CisjdW5kZWYgRE9fCit9CisKK3ZvaWQgRW51bU9wdGlvbnM6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zKQorICAvLyBvcHRpb25hbCBib29sIGFsbG93X2FsaWFzID0gMjsKKyAgaWYgKGhhc19hbGxvd19hbGlhcygpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlQm9vbCgyLCB0aGlzLT5hbGxvd19hbGlhcygpLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgYm9vbCBkZXByZWNhdGVkID0gMyBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgaWYgKGhhc19kZXByZWNhdGVkKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCb29sKDMsIHRoaXMtPmRlcHJlY2F0ZWQoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiB1bmludGVycHJldGVkX29wdGlvbiA9IDk5OTsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT51bmludGVycHJldGVkX29wdGlvbl9zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgOTk5LCB0aGlzLT51bmludGVycHJldGVkX29wdGlvbihpKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIEV4dGVuc2lvbiByYW5nZSBbMTAwMCwgNTM2ODcwOTEyKQorICBfZXh0ZW5zaW9uc18uU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgICAgMTAwMCwgNTM2ODcwOTEyLCBvdXRwdXQpOworCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25GaWVsZHMoCisgICAgICAgIHVua25vd25fZmllbGRzKCksIG91dHB1dCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9lbmQ6Z29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zKQorfQorCis6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBFbnVtT3B0aW9uczo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiB0YXJnZXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9zdGFydDpnb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnMpCisgIC8vIG9wdGlvbmFsIGJvb2wgYWxsb3dfYWxpYXMgPSAyOworICBpZiAoaGFzX2FsbG93X2FsaWFzKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCb29sVG9BcnJheSgyLCB0aGlzLT5hbGxvd19hbGlhcygpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgYm9vbCBkZXByZWNhdGVkID0gMyBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgaWYgKGhhc19kZXByZWNhdGVkKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCb29sVG9BcnJheSgzLCB0aGlzLT5kZXByZWNhdGVkKCksIHRhcmdldCk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CisgIGZvciAodW5zaWduZWQgaW50IGkgPSAwLCBuID0gdGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb25fc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OgorICAgICAgV3JpdGVNZXNzYWdlTm9WaXJ0dWFsVG9BcnJheSgKKyAgICAgICAgOTk5LCB0aGlzLT51bmludGVycHJldGVkX29wdGlvbihpKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIEV4dGVuc2lvbiByYW5nZSBbMTAwMCwgNTM2ODcwOTEyKQorICB0YXJnZXQgPSBfZXh0ZW5zaW9uc18uU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICAgIDEwMDAsIDUzNjg3MDkxMiwgdGFyZ2V0KTsKKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTZXJpYWxpemVVbmtub3duRmllbGRzVG9BcnJheSgKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSwgdGFyZ2V0KTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X2VuZDpnb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnMpCisgIHJldHVybiB0YXJnZXQ7Cit9CisKK2ludCBFbnVtT3B0aW9uczo6Qnl0ZVNpemUoKSBjb25zdCB7CisgIGludCB0b3RhbF9zaXplID0gMDsKKworICBpZiAoX2hhc19iaXRzX1swIC8gMzJdICYgM3UpIHsKKyAgICAvLyBvcHRpb25hbCBib29sIGFsbG93X2FsaWFzID0gMjsKKyAgICBpZiAoaGFzX2FsbG93X2FsaWFzKCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArIDE7CisgICAgfQorCisgICAgLy8gb3B0aW9uYWwgYm9vbCBkZXByZWNhdGVkID0gMyBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgICBpZiAoaGFzX2RlcHJlY2F0ZWQoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsgMTsKKyAgICB9CisKKyAgfQorICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CisgIHRvdGFsX3NpemUgKz0gMiAqIHRoaXMtPnVuaW50ZXJwcmV0ZWRfb3B0aW9uX3NpemUoKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT51bmludGVycHJldGVkX29wdGlvbl9zaXplKCk7IGkrKykgeworICAgIHRvdGFsX3NpemUgKz0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpNZXNzYWdlU2l6ZU5vVmlydHVhbCgKKyAgICAgICAgdGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb24oaSkpOworICB9CisKKyAgdG90YWxfc2l6ZSArPSBfZXh0ZW5zaW9uc18uQnl0ZVNpemUoKTsKKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICB0b3RhbF9zaXplICs9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpDb21wdXRlVW5rbm93bkZpZWxkc1NpemUoCisgICAgICAgIHVua25vd25fZmllbGRzKCkpOworICB9CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSB0b3RhbF9zaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKKyAgcmV0dXJuIHRvdGFsX3NpemU7Cit9CisKK3ZvaWQgRW51bU9wdGlvbnM6Ok1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgY29uc3QgRW51bU9wdGlvbnMqIHNvdXJjZSA9IAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RHluYW1pY0Nhc3RUb0dlbmVyYXRlZDxjb25zdCBFbnVtT3B0aW9ucz4oCisgICAgICAgICAgJmZyb20pOworICBpZiAoc291cmNlID09IE5VTEwpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpSZWZsZWN0aW9uT3BzOjpNZXJnZShmcm9tLCB0aGlzKTsKKyAgfSBlbHNlIHsKKyAgICBNZXJnZUZyb20oKnNvdXJjZSk7CisgIH0KK30KKwordm9pZCBFbnVtT3B0aW9uczo6TWVyZ2VGcm9tKGNvbnN0IEVudW1PcHRpb25zJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5NZXJnZUZyb20oZnJvbS51bmludGVycHJldGVkX29wdGlvbl8pOworICBpZiAoZnJvbS5faGFzX2JpdHNfWzAgLyAzMl0gJiAoMHhmZnUgPDwgKDAgJSAzMikpKSB7CisgICAgaWYgKGZyb20uaGFzX2FsbG93X2FsaWFzKCkpIHsKKyAgICAgIHNldF9hbGxvd19hbGlhcyhmcm9tLmFsbG93X2FsaWFzKCkpOworICAgIH0KKyAgICBpZiAoZnJvbS5oYXNfZGVwcmVjYXRlZCgpKSB7CisgICAgICBzZXRfZGVwcmVjYXRlZChmcm9tLmRlcHJlY2F0ZWQoKSk7CisgICAgfQorICB9CisgIF9leHRlbnNpb25zXy5NZXJnZUZyb20oZnJvbS5fZXh0ZW5zaW9uc18pOworICBpZiAoZnJvbS5faW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+TWVyZ2VGcm9tKGZyb20udW5rbm93bl9maWVsZHMoKSk7CisgIH0KK30KKwordm9pZCBFbnVtT3B0aW9uczo6Q29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKwordm9pZCBFbnVtT3B0aW9uczo6Q29weUZyb20oY29uc3QgRW51bU9wdGlvbnMmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCitib29sIEVudW1PcHRpb25zOjpJc0luaXRpYWxpemVkKCkgY29uc3QgeworCisgIGlmICghOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QWxsQXJlSW5pdGlhbGl6ZWQodGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb24oKSkpIHJldHVybiBmYWxzZTsKKworICBpZiAoIV9leHRlbnNpb25zXy5Jc0luaXRpYWxpemVkKCkpIHJldHVybiBmYWxzZTsgIHJldHVybiB0cnVlOworfQorCit2b2lkIEVudW1PcHRpb25zOjpTd2FwKEVudW1PcHRpb25zKiBvdGhlcikgeworICBpZiAob3RoZXIgPT0gdGhpcykgcmV0dXJuOworICBJbnRlcm5hbFN3YXAob3RoZXIpOworfQordm9pZCBFbnVtT3B0aW9uczo6SW50ZXJuYWxTd2FwKEVudW1PcHRpb25zKiBvdGhlcikgeworICBzdGQ6OnN3YXAoYWxsb3dfYWxpYXNfLCBvdGhlci0+YWxsb3dfYWxpYXNfKTsKKyAgc3RkOjpzd2FwKGRlcHJlY2F0ZWRfLCBvdGhlci0+ZGVwcmVjYXRlZF8pOworICB1bmludGVycHJldGVkX29wdGlvbl8uVW5zYWZlQXJlbmFTd2FwKCZvdGhlci0+dW5pbnRlcnByZXRlZF9vcHRpb25fKTsKKyAgc3RkOjpzd2FwKF9oYXNfYml0c19bMF0sIG90aGVyLT5faGFzX2JpdHNfWzBdKTsKKyAgX2ludGVybmFsX21ldGFkYXRhXy5Td2FwKCZvdGhlci0+X2ludGVybmFsX21ldGFkYXRhXyk7CisgIHN0ZDo6c3dhcChfY2FjaGVkX3NpemVfLCBvdGhlci0+X2NhY2hlZF9zaXplXyk7CisgIF9leHRlbnNpb25zXy5Td2FwKCZvdGhlci0+X2V4dGVuc2lvbnNfKTsKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBFbnVtT3B0aW9uczo6R2V0TWV0YWRhdGEoKSBjb25zdCB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIG1ldGFkYXRhOworICBtZXRhZGF0YS5kZXNjcmlwdG9yID0gRW51bU9wdGlvbnNfZGVzY3JpcHRvcl87CisgIG1ldGFkYXRhLnJlZmxlY3Rpb24gPSBFbnVtT3B0aW9uc19yZWZsZWN0aW9uXzsKKyAgcmV0dXJuIG1ldGFkYXRhOworfQorCisjaWYgUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisvLyBFbnVtT3B0aW9ucworCisvLyBvcHRpb25hbCBib29sIGFsbG93X2FsaWFzID0gMjsKK2Jvb2wgRW51bU9wdGlvbnM6Omhhc19hbGxvd19hbGlhcygpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMXUpICE9IDA7Cit9Cit2b2lkIEVudW1PcHRpb25zOjpzZXRfaGFzX2FsbG93X2FsaWFzKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDF1OworfQordm9pZCBFbnVtT3B0aW9uczo6Y2xlYXJfaGFzX2FsbG93X2FsaWFzKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAxdTsKK30KK3ZvaWQgRW51bU9wdGlvbnM6OmNsZWFyX2FsbG93X2FsaWFzKCkgeworICBhbGxvd19hbGlhc18gPSBmYWxzZTsKKyAgY2xlYXJfaGFzX2FsbG93X2FsaWFzKCk7Cit9CisgYm9vbCBFbnVtT3B0aW9uczo6YWxsb3dfYWxpYXMoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zLmFsbG93X2FsaWFzKQorICByZXR1cm4gYWxsb3dfYWxpYXNfOworfQorIHZvaWQgRW51bU9wdGlvbnM6OnNldF9hbGxvd19hbGlhcyhib29sIHZhbHVlKSB7CisgIHNldF9oYXNfYWxsb3dfYWxpYXMoKTsKKyAgYWxsb3dfYWxpYXNfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zLmFsbG93X2FsaWFzKQorfQorCisvLyBvcHRpb25hbCBib29sIGRlcHJlY2F0ZWQgPSAzIFtkZWZhdWx0ID0gZmFsc2VdOworYm9vbCBFbnVtT3B0aW9uczo6aGFzX2RlcHJlY2F0ZWQoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDJ1KSAhPSAwOworfQordm9pZCBFbnVtT3B0aW9uczo6c2V0X2hhc19kZXByZWNhdGVkKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDJ1OworfQordm9pZCBFbnVtT3B0aW9uczo6Y2xlYXJfaGFzX2RlcHJlY2F0ZWQoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDJ1OworfQordm9pZCBFbnVtT3B0aW9uczo6Y2xlYXJfZGVwcmVjYXRlZCgpIHsKKyAgZGVwcmVjYXRlZF8gPSBmYWxzZTsKKyAgY2xlYXJfaGFzX2RlcHJlY2F0ZWQoKTsKK30KKyBib29sIEVudW1PcHRpb25zOjpkZXByZWNhdGVkKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucy5kZXByZWNhdGVkKQorICByZXR1cm4gZGVwcmVjYXRlZF87Cit9Cisgdm9pZCBFbnVtT3B0aW9uczo6c2V0X2RlcHJlY2F0ZWQoYm9vbCB2YWx1ZSkgeworICBzZXRfaGFzX2RlcHJlY2F0ZWQoKTsKKyAgZGVwcmVjYXRlZF8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnMuZGVwcmVjYXRlZCkKK30KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIHVuaW50ZXJwcmV0ZWRfb3B0aW9uID0gOTk5OworaW50IEVudW1PcHRpb25zOjp1bmludGVycHJldGVkX29wdGlvbl9zaXplKCkgY29uc3QgeworICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLnNpemUoKTsKK30KK3ZvaWQgRW51bU9wdGlvbnM6OmNsZWFyX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgeworICB1bmludGVycHJldGVkX29wdGlvbl8uQ2xlYXIoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiYgRW51bU9wdGlvbnM6OnVuaW50ZXJwcmV0ZWRfb3B0aW9uKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5HZXQoaW5kZXgpOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uKiBFbnVtT3B0aW9uczo6bXV0YWJsZV91bmludGVycHJldGVkX29wdGlvbihpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLk11dGFibGUoaW5kZXgpOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uKiBFbnVtT3B0aW9uczo6YWRkX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5BZGQoKTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uID4qCitFbnVtT3B0aW9uczo6bXV0YWJsZV91bmludGVycHJldGVkX29wdGlvbigpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiAmdW5pbnRlcnByZXRlZF9vcHRpb25fOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24gPiYKK0VudW1PcHRpb25zOjp1bmludGVycHJldGVkX29wdGlvbigpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fOworfQorCisjZW5kaWYgIC8vIFBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKyNpZiAhZGVmaW5lZChfTVNDX1ZFUikgfHwgX01TQ19WRVIgPj0gMTkwMAorY29uc3QgaW50IEVudW1WYWx1ZU9wdGlvbnM6OmtEZXByZWNhdGVkRmllbGROdW1iZXI7Citjb25zdCBpbnQgRW51bVZhbHVlT3B0aW9uczo6a1VuaW50ZXJwcmV0ZWRPcHRpb25GaWVsZE51bWJlcjsKKyNlbmRpZiAgLy8gIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKKworRW51bVZhbHVlT3B0aW9uczo6RW51bVZhbHVlT3B0aW9ucygpCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgeworICBTaGFyZWRDdG9yKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlT3B0aW9ucykKK30KKwordm9pZCBFbnVtVmFsdWVPcHRpb25zOjpJbml0QXNEZWZhdWx0SW5zdGFuY2UoKSB7Cit9CisKK0VudW1WYWx1ZU9wdGlvbnM6OkVudW1WYWx1ZU9wdGlvbnMoY29uc3QgRW51bVZhbHVlT3B0aW9ucyYgZnJvbSkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwKKyAgICBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICBNZXJnZUZyb20oZnJvbSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb3B5X2NvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVPcHRpb25zKQorfQorCit2b2lkIEVudW1WYWx1ZU9wdGlvbnM6OlNoYXJlZEN0b3IoKSB7CisgIF9jYWNoZWRfc2l6ZV8gPSAwOworICBkZXByZWNhdGVkXyA9IGZhbHNlOworICA6Om1lbXNldChfaGFzX2JpdHNfLCAwLCBzaXplb2YoX2hhc19iaXRzXykpOworfQorCitFbnVtVmFsdWVPcHRpb25zOjp+RW51bVZhbHVlT3B0aW9ucygpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGRlc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnMpCisgIFNoYXJlZER0b3IoKTsKK30KKwordm9pZCBFbnVtVmFsdWVPcHRpb25zOjpTaGFyZWREdG9yKCkgeworICBpZiAodGhpcyAhPSBkZWZhdWx0X2luc3RhbmNlXykgeworICB9Cit9CisKK3ZvaWQgRW51bVZhbHVlT3B0aW9uczo6U2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3QgeworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIEVudW1WYWx1ZU9wdGlvbnM6OmRlc2NyaXB0b3IoKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICByZXR1cm4gRW51bVZhbHVlT3B0aW9uc19kZXNjcmlwdG9yXzsKK30KKworY29uc3QgRW51bVZhbHVlT3B0aW9ucyYgRW51bVZhbHVlT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZSgpIHsKKyAgaWYgKGRlZmF1bHRfaW5zdGFuY2VfID09IE5VTEwpIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgcmV0dXJuICpkZWZhdWx0X2luc3RhbmNlXzsKK30KKworRW51bVZhbHVlT3B0aW9ucyogRW51bVZhbHVlT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBOVUxMOworCitFbnVtVmFsdWVPcHRpb25zKiBFbnVtVmFsdWVPcHRpb25zOjpOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0IHsKKyAgRW51bVZhbHVlT3B0aW9ucyogbiA9IG5ldyBFbnVtVmFsdWVPcHRpb25zOworICBpZiAoYXJlbmEgIT0gTlVMTCkgeworICAgIGFyZW5hLT5Pd24obik7CisgIH0KKyAgcmV0dXJuIG47Cit9CisKK3ZvaWQgRW51bVZhbHVlT3B0aW9uczo6Q2xlYXIoKSB7CisgIF9leHRlbnNpb25zXy5DbGVhcigpOworICBkZXByZWNhdGVkXyA9IGZhbHNlOworICB1bmludGVycHJldGVkX29wdGlvbl8uQ2xlYXIoKTsKKyAgOjptZW1zZXQoX2hhc19iaXRzXywgMCwgc2l6ZW9mKF9oYXNfYml0c18pKTsKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5DbGVhcigpOworICB9Cit9CisKK2Jvb2wgRW51bVZhbHVlT3B0aW9uczo6TWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KSB7CisjZGVmaW5lIERPXyhFWFBSRVNTSU9OKSBpZiAoIShFWFBSRVNTSU9OKSkgZ290byBmYWlsdXJlCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIHRhZzsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVPcHRpb25zKQorICBmb3IgKDs7KSB7CisgICAgOjpzdGQ6OnBhaXI8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyLCBib29sPiBwID0gaW5wdXQtPlJlYWRUYWdXaXRoQ3V0b2ZmKDE2MzgzKTsKKyAgICB0YWcgPSBwLmZpcnN0OworICAgIGlmICghcC5zZWNvbmQpIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgc3dpdGNoICg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnRmllbGROdW1iZXIodGFnKSkgeworICAgICAgLy8gb3B0aW9uYWwgYm9vbCBkZXByZWNhdGVkID0gMSBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgICAgIGNhc2UgMTogeworICAgICAgICBpZiAodGFnID09IDgpIHsKKyAgICAgICAgICBET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPAorICAgICAgICAgICAgICAgICAgIGJvb2wsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0JPT0w+KAorICAgICAgICAgICAgICAgICBpbnB1dCwgJmRlcHJlY2F0ZWRfKSkpOworICAgICAgICAgIHNldF9oYXNfZGVwcmVjYXRlZCgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNzk5NCkpIGdvdG8gcGFyc2VfdW5pbnRlcnByZXRlZF9vcHRpb247CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CisgICAgICBjYXNlIDk5OTogeworICAgICAgICBpZiAodGFnID09IDc5OTQpIHsKKyAgICAgICAgIHBhcnNlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uOgorICAgICAgICAgIERPXyhpbnB1dC0+SW5jcmVtZW50UmVjdXJzaW9uRGVwdGgoKSk7CisgICAgICAgICBwYXJzZV9sb29wX3VuaW50ZXJwcmV0ZWRfb3B0aW9uOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZE1lc3NhZ2VOb1ZpcnR1YWxOb1JlY3Vyc2lvbkRlcHRoKAorICAgICAgICAgICAgICAgIGlucHV0LCBhZGRfdW5pbnRlcnByZXRlZF9vcHRpb24oKSkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNzk5NCkpIGdvdG8gcGFyc2VfbG9vcF91bmludGVycHJldGVkX29wdGlvbjsKKyAgICAgICAgaW5wdXQtPlVuc2FmZURlY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCk7CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0QXRFbmQoKSkgZ290byBzdWNjZXNzOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgZGVmYXVsdDogeworICAgICAgaGFuZGxlX3VudXN1YWw6CisgICAgICAgIGlmICh0YWcgPT0gMCB8fAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ1dpcmVUeXBlKHRhZykgPT0KKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVApIHsKKyAgICAgICAgICBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCg4MDAwdSA8PSB0YWcpKSB7CisgICAgICAgICAgRE9fKF9leHRlbnNpb25zXy5QYXJzZUZpZWxkKHRhZywgaW5wdXQsIGRlZmF1bHRfaW5zdGFuY2VfLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkpKTsKKyAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2tpcEZpZWxkKAorICAgICAgICAgICAgICBpbnB1dCwgdGFnLCBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CitzdWNjZXNzOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3VjY2Vzczpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlT3B0aW9ucykKKyAgcmV0dXJuIHRydWU7CitmYWlsdXJlOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2VfZmFpbHVyZTpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlT3B0aW9ucykKKyAgcmV0dXJuIGZhbHNlOworI3VuZGVmIERPXworfQorCit2b2lkIEVudW1WYWx1ZU9wdGlvbnM6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnMpCisgIC8vIG9wdGlvbmFsIGJvb2wgZGVwcmVjYXRlZCA9IDEgW2RlZmF1bHQgPSBmYWxzZV07CisgIGlmIChoYXNfZGVwcmVjYXRlZCgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlQm9vbCgxLCB0aGlzLT5kZXByZWNhdGVkKCksIG91dHB1dCk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CisgIGZvciAodW5zaWduZWQgaW50IGkgPSAwLCBuID0gdGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb25fc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlTWVzc2FnZU1heWJlVG9BcnJheSgKKyAgICAgIDk5OSwgdGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb24oaSksIG91dHB1dCk7CisgIH0KKworICAvLyBFeHRlbnNpb24gcmFuZ2UgWzEwMDAsIDUzNjg3MDkxMikKKyAgX2V4dGVuc2lvbnNfLlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICAgIDEwMDAsIDUzNjg3MDkxMiwgb3V0cHV0KTsKKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTZXJpYWxpemVVbmtub3duRmllbGRzKAorICAgICAgICB1bmtub3duX2ZpZWxkcygpLCBvdXRwdXQpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfZW5kOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVPcHRpb25zKQorfQorCis6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBFbnVtVmFsdWVPcHRpb25zOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIHRhcmdldCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVPcHRpb25zKQorICAvLyBvcHRpb25hbCBib29sIGRlcHJlY2F0ZWQgPSAxIFtkZWZhdWx0ID0gZmFsc2VdOworICBpZiAoaGFzX2RlcHJlY2F0ZWQoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2xUb0FycmF5KDEsIHRoaXMtPmRlcHJlY2F0ZWQoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiB1bmludGVycHJldGVkX29wdGlvbiA9IDk5OTsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT51bmludGVycHJldGVkX29wdGlvbl9zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6CisgICAgICBXcml0ZU1lc3NhZ2VOb1ZpcnR1YWxUb0FycmF5KAorICAgICAgICA5OTksIHRoaXMtPnVuaW50ZXJwcmV0ZWRfb3B0aW9uKGkpLCB0YXJnZXQpOworICB9CisKKyAgLy8gRXh0ZW5zaW9uIHJhbmdlIFsxMDAwLCA1MzY4NzA5MTIpCisgIHRhcmdldCA9IF9leHRlbnNpb25zXy5TZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KAorICAgICAgMTAwMCwgNTM2ODcwOTEyLCB0YXJnZXQpOworCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25GaWVsZHNUb0FycmF5KAorICAgICAgICB1bmtub3duX2ZpZWxkcygpLCB0YXJnZXQpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfZW5kOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVPcHRpb25zKQorICByZXR1cm4gdGFyZ2V0OworfQorCitpbnQgRW51bVZhbHVlT3B0aW9uczo6Qnl0ZVNpemUoKSBjb25zdCB7CisgIGludCB0b3RhbF9zaXplID0gMDsKKworICAvLyBvcHRpb25hbCBib29sIGRlcHJlY2F0ZWQgPSAxIFtkZWZhdWx0ID0gZmFsc2VdOworICBpZiAoaGFzX2RlcHJlY2F0ZWQoKSkgeworICAgIHRvdGFsX3NpemUgKz0gMSArIDE7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CisgIHRvdGFsX3NpemUgKz0gMiAqIHRoaXMtPnVuaW50ZXJwcmV0ZWRfb3B0aW9uX3NpemUoKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT51bmludGVycHJldGVkX29wdGlvbl9zaXplKCk7IGkrKykgeworICAgIHRvdGFsX3NpemUgKz0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpNZXNzYWdlU2l6ZU5vVmlydHVhbCgKKyAgICAgICAgdGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb24oaSkpOworICB9CisKKyAgdG90YWxfc2l6ZSArPSBfZXh0ZW5zaW9uc18uQnl0ZVNpemUoKTsKKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICB0b3RhbF9zaXplICs9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpDb21wdXRlVW5rbm93bkZpZWxkc1NpemUoCisgICAgICAgIHVua25vd25fZmllbGRzKCkpOworICB9CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSB0b3RhbF9zaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKKyAgcmV0dXJuIHRvdGFsX3NpemU7Cit9CisKK3ZvaWQgRW51bVZhbHVlT3B0aW9uczo6TWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBjb25zdCBFbnVtVmFsdWVPcHRpb25zKiBzb3VyY2UgPSAKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkR5bmFtaWNDYXN0VG9HZW5lcmF0ZWQ8Y29uc3QgRW51bVZhbHVlT3B0aW9ucz4oCisgICAgICAgICAgJmZyb20pOworICBpZiAoc291cmNlID09IE5VTEwpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpSZWZsZWN0aW9uT3BzOjpNZXJnZShmcm9tLCB0aGlzKTsKKyAgfSBlbHNlIHsKKyAgICBNZXJnZUZyb20oKnNvdXJjZSk7CisgIH0KK30KKwordm9pZCBFbnVtVmFsdWVPcHRpb25zOjpNZXJnZUZyb20oY29uc3QgRW51bVZhbHVlT3B0aW9ucyYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICB1bmludGVycHJldGVkX29wdGlvbl8uTWVyZ2VGcm9tKGZyb20udW5pbnRlcnByZXRlZF9vcHRpb25fKTsKKyAgaWYgKGZyb20uX2hhc19iaXRzX1swIC8gMzJdICYgKDB4ZmZ1IDw8ICgwICUgMzIpKSkgeworICAgIGlmIChmcm9tLmhhc19kZXByZWNhdGVkKCkpIHsKKyAgICAgIHNldF9kZXByZWNhdGVkKGZyb20uZGVwcmVjYXRlZCgpKTsKKyAgICB9CisgIH0KKyAgX2V4dGVuc2lvbnNfLk1lcmdlRnJvbShmcm9tLl9leHRlbnNpb25zXyk7CisgIGlmIChmcm9tLl9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5NZXJnZUZyb20oZnJvbS51bmtub3duX2ZpZWxkcygpKTsKKyAgfQorfQorCit2b2lkIEVudW1WYWx1ZU9wdGlvbnM6OkNvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK3ZvaWQgRW51bVZhbHVlT3B0aW9uczo6Q29weUZyb20oY29uc3QgRW51bVZhbHVlT3B0aW9ucyYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK2Jvb2wgRW51bVZhbHVlT3B0aW9uczo6SXNJbml0aWFsaXplZCgpIGNvbnN0IHsKKworICBpZiAoITo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFsbEFyZUluaXRpYWxpemVkKHRoaXMtPnVuaW50ZXJwcmV0ZWRfb3B0aW9uKCkpKSByZXR1cm4gZmFsc2U7CisKKyAgaWYgKCFfZXh0ZW5zaW9uc18uSXNJbml0aWFsaXplZCgpKSByZXR1cm4gZmFsc2U7ICByZXR1cm4gdHJ1ZTsKK30KKwordm9pZCBFbnVtVmFsdWVPcHRpb25zOjpTd2FwKEVudW1WYWx1ZU9wdGlvbnMqIG90aGVyKSB7CisgIGlmIChvdGhlciA9PSB0aGlzKSByZXR1cm47CisgIEludGVybmFsU3dhcChvdGhlcik7Cit9Cit2b2lkIEVudW1WYWx1ZU9wdGlvbnM6OkludGVybmFsU3dhcChFbnVtVmFsdWVPcHRpb25zKiBvdGhlcikgeworICBzdGQ6OnN3YXAoZGVwcmVjYXRlZF8sIG90aGVyLT5kZXByZWNhdGVkXyk7CisgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5VbnNhZmVBcmVuYVN3YXAoJm90aGVyLT51bmludGVycHJldGVkX29wdGlvbl8pOworICBzdGQ6OnN3YXAoX2hhc19iaXRzX1swXSwgb3RoZXItPl9oYXNfYml0c19bMF0pOworICBfaW50ZXJuYWxfbWV0YWRhdGFfLlN3YXAoJm90aGVyLT5faW50ZXJuYWxfbWV0YWRhdGFfKTsKKyAgc3RkOjpzd2FwKF9jYWNoZWRfc2l6ZV8sIG90aGVyLT5fY2FjaGVkX3NpemVfKTsKKyAgX2V4dGVuc2lvbnNfLlN3YXAoJm90aGVyLT5fZXh0ZW5zaW9uc18pOworfQorCis6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEVudW1WYWx1ZU9wdGlvbnM6OkdldE1ldGFkYXRhKCkgY29uc3QgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBtZXRhZGF0YTsKKyAgbWV0YWRhdGEuZGVzY3JpcHRvciA9IEVudW1WYWx1ZU9wdGlvbnNfZGVzY3JpcHRvcl87CisgIG1ldGFkYXRhLnJlZmxlY3Rpb24gPSBFbnVtVmFsdWVPcHRpb25zX3JlZmxlY3Rpb25fOworICByZXR1cm4gbWV0YWRhdGE7Cit9CisKKyNpZiBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKy8vIEVudW1WYWx1ZU9wdGlvbnMKKworLy8gb3B0aW9uYWwgYm9vbCBkZXByZWNhdGVkID0gMSBbZGVmYXVsdCA9IGZhbHNlXTsKK2Jvb2wgRW51bVZhbHVlT3B0aW9uczo6aGFzX2RlcHJlY2F0ZWQoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDF1KSAhPSAwOworfQordm9pZCBFbnVtVmFsdWVPcHRpb25zOjpzZXRfaGFzX2RlcHJlY2F0ZWQoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMXU7Cit9Cit2b2lkIEVudW1WYWx1ZU9wdGlvbnM6OmNsZWFyX2hhc19kZXByZWNhdGVkKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAxdTsKK30KK3ZvaWQgRW51bVZhbHVlT3B0aW9uczo6Y2xlYXJfZGVwcmVjYXRlZCgpIHsKKyAgZGVwcmVjYXRlZF8gPSBmYWxzZTsKKyAgY2xlYXJfaGFzX2RlcHJlY2F0ZWQoKTsKK30KKyBib29sIEVudW1WYWx1ZU9wdGlvbnM6OmRlcHJlY2F0ZWQoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnMuZGVwcmVjYXRlZCkKKyAgcmV0dXJuIGRlcHJlY2F0ZWRfOworfQorIHZvaWQgRW51bVZhbHVlT3B0aW9uczo6c2V0X2RlcHJlY2F0ZWQoYm9vbCB2YWx1ZSkgeworICBzZXRfaGFzX2RlcHJlY2F0ZWQoKTsKKyAgZGVwcmVjYXRlZF8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlT3B0aW9ucy5kZXByZWNhdGVkKQorfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CitpbnQgRW51bVZhbHVlT3B0aW9uczo6dW5pbnRlcnByZXRlZF9vcHRpb25fc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5zaXplKCk7Cit9Cit2b2lkIEVudW1WYWx1ZU9wdGlvbnM6OmNsZWFyX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgeworICB1bmludGVycHJldGVkX29wdGlvbl8uQ2xlYXIoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiYgRW51bVZhbHVlT3B0aW9uczo6dW5pbnRlcnByZXRlZF9vcHRpb24oaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl8uR2V0KGluZGV4KTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiogRW51bVZhbHVlT3B0aW9uczo6bXV0YWJsZV91bmludGVycHJldGVkX29wdGlvbihpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl8uTXV0YWJsZShpbmRleCk7Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24qIEVudW1WYWx1ZU9wdGlvbnM6OmFkZF91bmludGVycHJldGVkX29wdGlvbigpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5BZGQoKTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uID4qCitFbnVtVmFsdWVPcHRpb25zOjptdXRhYmxlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVPcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gJnVuaW50ZXJwcmV0ZWRfb3B0aW9uXzsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uID4mCitFbnVtVmFsdWVPcHRpb25zOjp1bmludGVycHJldGVkX29wdGlvbigpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl87Cit9CisKKyNlbmRpZiAgLy8gUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworI2lmICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCitjb25zdCBpbnQgU2VydmljZU9wdGlvbnM6OmtEZXByZWNhdGVkRmllbGROdW1iZXI7Citjb25zdCBpbnQgU2VydmljZU9wdGlvbnM6OmtVbmludGVycHJldGVkT3B0aW9uRmllbGROdW1iZXI7CisjZW5kaWYgIC8vICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCisKK1NlcnZpY2VPcHRpb25zOjpTZXJ2aWNlT3B0aW9ucygpCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgeworICBTaGFyZWRDdG9yKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuU2VydmljZU9wdGlvbnMpCit9CisKK3ZvaWQgU2VydmljZU9wdGlvbnM6OkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpIHsKK30KKworU2VydmljZU9wdGlvbnM6OlNlcnZpY2VPcHRpb25zKGNvbnN0IFNlcnZpY2VPcHRpb25zJiBmcm9tKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpLAorICAgIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgeworICBTaGFyZWRDdG9yKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvcHlfY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zKQorfQorCit2b2lkIFNlcnZpY2VPcHRpb25zOjpTaGFyZWRDdG9yKCkgeworICBfY2FjaGVkX3NpemVfID0gMDsKKyAgZGVwcmVjYXRlZF8gPSBmYWxzZTsKKyAgOjptZW1zZXQoX2hhc19iaXRzXywgMCwgc2l6ZW9mKF9oYXNfYml0c18pKTsKK30KKworU2VydmljZU9wdGlvbnM6On5TZXJ2aWNlT3B0aW9ucygpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGRlc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zKQorICBTaGFyZWREdG9yKCk7Cit9CisKK3ZvaWQgU2VydmljZU9wdGlvbnM6OlNoYXJlZER0b3IoKSB7CisgIGlmICh0aGlzICE9IGRlZmF1bHRfaW5zdGFuY2VfKSB7CisgIH0KK30KKwordm9pZCBTZXJ2aWNlT3B0aW9uczo6U2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3QgeworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIFNlcnZpY2VPcHRpb25zOjpkZXNjcmlwdG9yKCkgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgcmV0dXJuIFNlcnZpY2VPcHRpb25zX2Rlc2NyaXB0b3JfOworfQorCitjb25zdCBTZXJ2aWNlT3B0aW9ucyYgU2VydmljZU9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2UoKSB7CisgIGlmIChkZWZhdWx0X2luc3RhbmNlXyA9PSBOVUxMKSBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIHJldHVybiAqZGVmYXVsdF9pbnN0YW5jZV87Cit9CisKK1NlcnZpY2VPcHRpb25zKiBTZXJ2aWNlT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBOVUxMOworCitTZXJ2aWNlT3B0aW9ucyogU2VydmljZU9wdGlvbnM6Ok5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3QgeworICBTZXJ2aWNlT3B0aW9ucyogbiA9IG5ldyBTZXJ2aWNlT3B0aW9uczsKKyAgaWYgKGFyZW5hICE9IE5VTEwpIHsKKyAgICBhcmVuYS0+T3duKG4pOworICB9CisgIHJldHVybiBuOworfQorCit2b2lkIFNlcnZpY2VPcHRpb25zOjpDbGVhcigpIHsKKyAgX2V4dGVuc2lvbnNfLkNsZWFyKCk7CisgIGRlcHJlY2F0ZWRfID0gZmFsc2U7CisgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5DbGVhcigpOworICA6Om1lbXNldChfaGFzX2JpdHNfLCAwLCBzaXplb2YoX2hhc19iaXRzXykpOworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkNsZWFyKCk7CisgIH0KK30KKworYm9vbCBTZXJ2aWNlT3B0aW9uczo6TWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KSB7CisjZGVmaW5lIERPXyhFWFBSRVNTSU9OKSBpZiAoIShFWFBSRVNTSU9OKSkgZ290byBmYWlsdXJlCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIHRhZzsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlT3B0aW9ucykKKyAgZm9yICg7OykgeworICAgIDo6c3RkOjpwYWlyPCA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiwgYm9vbD4gcCA9IGlucHV0LT5SZWFkVGFnV2l0aEN1dG9mZigxNjM4Myk7CisgICAgdGFnID0gcC5maXJzdDsKKyAgICBpZiAoIXAuc2Vjb25kKSBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgIHN3aXRjaCAoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ0ZpZWxkTnVtYmVyKHRhZykpIHsKKyAgICAgIC8vIG9wdGlvbmFsIGJvb2wgZGVwcmVjYXRlZCA9IDMzIFtkZWZhdWx0ID0gZmFsc2VdOworICAgICAgY2FzZSAzMzogeworICAgICAgICBpZiAodGFnID09IDI2NCkgeworICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgYm9vbCwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfQk9PTD4oCisgICAgICAgICAgICAgICAgIGlucHV0LCAmZGVwcmVjYXRlZF8pKSk7CisgICAgICAgICAgc2V0X2hhc19kZXByZWNhdGVkKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg3OTk0KSkgZ290byBwYXJzZV91bmludGVycHJldGVkX29wdGlvbjsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiB1bmludGVycHJldGVkX29wdGlvbiA9IDk5OTsKKyAgICAgIGNhc2UgOTk5OiB7CisgICAgICAgIGlmICh0YWcgPT0gNzk5NCkgeworICAgICAgICAgcGFyc2VfdW5pbnRlcnByZXRlZF9vcHRpb246CisgICAgICAgICAgRE9fKGlucHV0LT5JbmNyZW1lbnRSZWN1cnNpb25EZXB0aCgpKTsKKyAgICAgICAgIHBhcnNlX2xvb3BfdW5pbnRlcnByZXRlZF9vcHRpb246CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkTWVzc2FnZU5vVmlydHVhbE5vUmVjdXJzaW9uRGVwdGgoCisgICAgICAgICAgICAgICAgaW5wdXQsIGFkZF91bmludGVycHJldGVkX29wdGlvbigpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg3OTk0KSkgZ290byBwYXJzZV9sb29wX3VuaW50ZXJwcmV0ZWRfb3B0aW9uOworICAgICAgICBpbnB1dC0+VW5zYWZlRGVjcmVtZW50UmVjdXJzaW9uRGVwdGgoKTsKKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RBdEVuZCgpKSBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBkZWZhdWx0OiB7CisgICAgICBoYW5kbGVfdW51c3VhbDoKKyAgICAgICAgaWYgKHRhZyA9PSAwIHx8CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnV2lyZVR5cGUodGFnKSA9PQorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0VORF9HUk9VUCkgeworICAgICAgICAgIGdvdG8gc3VjY2VzczsKKyAgICAgICAgfQorICAgICAgICBpZiAoKDgwMDB1IDw9IHRhZykpIHsKKyAgICAgICAgICBET18oX2V4dGVuc2lvbnNfLlBhcnNlRmllbGQodGFnLCBpbnB1dCwgZGVmYXVsdF9pbnN0YW5jZV8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSkpOworICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTa2lwRmllbGQoCisgICAgICAgICAgICAgIGlucHV0LCB0YWcsIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSkpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KK3N1Y2Nlc3M6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdWNjZXNzOmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlT3B0aW9ucykKKyAgcmV0dXJuIHRydWU7CitmYWlsdXJlOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2VfZmFpbHVyZTpnb29nbGUucHJvdG9idWYuU2VydmljZU9wdGlvbnMpCisgIHJldHVybiBmYWxzZTsKKyN1bmRlZiBET18KK30KKwordm9pZCBTZXJ2aWNlT3B0aW9uczo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9zdGFydDpnb29nbGUucHJvdG9idWYuU2VydmljZU9wdGlvbnMpCisgIC8vIG9wdGlvbmFsIGJvb2wgZGVwcmVjYXRlZCA9IDMzIFtkZWZhdWx0ID0gZmFsc2VdOworICBpZiAoaGFzX2RlcHJlY2F0ZWQoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2woMzMsIHRoaXMtPmRlcHJlY2F0ZWQoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiB1bmludGVycHJldGVkX29wdGlvbiA9IDk5OTsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT51bmludGVycHJldGVkX29wdGlvbl9zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgOTk5LCB0aGlzLT51bmludGVycHJldGVkX29wdGlvbihpKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIEV4dGVuc2lvbiByYW5nZSBbMTAwMCwgNTM2ODcwOTEyKQorICBfZXh0ZW5zaW9uc18uU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgICAgMTAwMCwgNTM2ODcwOTEyLCBvdXRwdXQpOworCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25GaWVsZHMoCisgICAgICAgIHVua25vd25fZmllbGRzKCksIG91dHB1dCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9lbmQ6Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zKQorfQorCis6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBTZXJ2aWNlT3B0aW9uczo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiB0YXJnZXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9zdGFydDpnb29nbGUucHJvdG9idWYuU2VydmljZU9wdGlvbnMpCisgIC8vIG9wdGlvbmFsIGJvb2wgZGVwcmVjYXRlZCA9IDMzIFtkZWZhdWx0ID0gZmFsc2VdOworICBpZiAoaGFzX2RlcHJlY2F0ZWQoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2xUb0FycmF5KDMzLCB0aGlzLT5kZXByZWNhdGVkKCksIHRhcmdldCk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CisgIGZvciAodW5zaWduZWQgaW50IGkgPSAwLCBuID0gdGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb25fc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OgorICAgICAgV3JpdGVNZXNzYWdlTm9WaXJ0dWFsVG9BcnJheSgKKyAgICAgICAgOTk5LCB0aGlzLT51bmludGVycHJldGVkX29wdGlvbihpKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIEV4dGVuc2lvbiByYW5nZSBbMTAwMCwgNTM2ODcwOTEyKQorICB0YXJnZXQgPSBfZXh0ZW5zaW9uc18uU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICAgIDEwMDAsIDUzNjg3MDkxMiwgdGFyZ2V0KTsKKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTZXJpYWxpemVVbmtub3duRmllbGRzVG9BcnJheSgKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSwgdGFyZ2V0KTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X2VuZDpnb29nbGUucHJvdG9idWYuU2VydmljZU9wdGlvbnMpCisgIHJldHVybiB0YXJnZXQ7Cit9CisKK2ludCBTZXJ2aWNlT3B0aW9uczo6Qnl0ZVNpemUoKSBjb25zdCB7CisgIGludCB0b3RhbF9zaXplID0gMDsKKworICAvLyBvcHRpb25hbCBib29sIGRlcHJlY2F0ZWQgPSAzMyBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgaWYgKGhhc19kZXByZWNhdGVkKCkpIHsKKyAgICB0b3RhbF9zaXplICs9IDIgKyAxOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIHVuaW50ZXJwcmV0ZWRfb3B0aW9uID0gOTk5OworICB0b3RhbF9zaXplICs9IDIgKiB0aGlzLT51bmludGVycHJldGVkX29wdGlvbl9zaXplKCk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb25fc2l6ZSgpOyBpKyspIHsKKyAgICB0b3RhbF9zaXplICs9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6TWVzc2FnZVNpemVOb1ZpcnR1YWwoCisgICAgICAgIHRoaXMtPnVuaW50ZXJwcmV0ZWRfb3B0aW9uKGkpKTsKKyAgfQorCisgIHRvdGFsX3NpemUgKz0gX2V4dGVuc2lvbnNfLkJ5dGVTaXplKCk7CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6Q29tcHV0ZVVua25vd25GaWVsZHNTaXplKAorICAgICAgICB1bmtub3duX2ZpZWxkcygpKTsKKyAgfQorICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gdG90YWxfc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7CisgIHJldHVybiB0b3RhbF9zaXplOworfQorCit2b2lkIFNlcnZpY2VPcHRpb25zOjpNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGNvbnN0IFNlcnZpY2VPcHRpb25zKiBzb3VyY2UgPSAKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkR5bmFtaWNDYXN0VG9HZW5lcmF0ZWQ8Y29uc3QgU2VydmljZU9wdGlvbnM+KAorICAgICAgICAgICZmcm9tKTsKKyAgaWYgKHNvdXJjZSA9PSBOVUxMKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6UmVmbGVjdGlvbk9wczo6TWVyZ2UoZnJvbSwgdGhpcyk7CisgIH0gZWxzZSB7CisgICAgTWVyZ2VGcm9tKCpzb3VyY2UpOworICB9Cit9CisKK3ZvaWQgU2VydmljZU9wdGlvbnM6Ok1lcmdlRnJvbShjb25zdCBTZXJ2aWNlT3B0aW9ucyYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICB1bmludGVycHJldGVkX29wdGlvbl8uTWVyZ2VGcm9tKGZyb20udW5pbnRlcnByZXRlZF9vcHRpb25fKTsKKyAgaWYgKGZyb20uX2hhc19iaXRzX1swIC8gMzJdICYgKDB4ZmZ1IDw8ICgwICUgMzIpKSkgeworICAgIGlmIChmcm9tLmhhc19kZXByZWNhdGVkKCkpIHsKKyAgICAgIHNldF9kZXByZWNhdGVkKGZyb20uZGVwcmVjYXRlZCgpKTsKKyAgICB9CisgIH0KKyAgX2V4dGVuc2lvbnNfLk1lcmdlRnJvbShmcm9tLl9leHRlbnNpb25zXyk7CisgIGlmIChmcm9tLl9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5NZXJnZUZyb20oZnJvbS51bmtub3duX2ZpZWxkcygpKTsKKyAgfQorfQorCit2b2lkIFNlcnZpY2VPcHRpb25zOjpDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCit2b2lkIFNlcnZpY2VPcHRpb25zOjpDb3B5RnJvbShjb25zdCBTZXJ2aWNlT3B0aW9ucyYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK2Jvb2wgU2VydmljZU9wdGlvbnM6OklzSW5pdGlhbGl6ZWQoKSBjb25zdCB7CisKKyAgaWYgKCE6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBbGxBcmVJbml0aWFsaXplZCh0aGlzLT51bmludGVycHJldGVkX29wdGlvbigpKSkgcmV0dXJuIGZhbHNlOworCisgIGlmICghX2V4dGVuc2lvbnNfLklzSW5pdGlhbGl6ZWQoKSkgcmV0dXJuIGZhbHNlOyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgU2VydmljZU9wdGlvbnM6OlN3YXAoU2VydmljZU9wdGlvbnMqIG90aGVyKSB7CisgIGlmIChvdGhlciA9PSB0aGlzKSByZXR1cm47CisgIEludGVybmFsU3dhcChvdGhlcik7Cit9Cit2b2lkIFNlcnZpY2VPcHRpb25zOjpJbnRlcm5hbFN3YXAoU2VydmljZU9wdGlvbnMqIG90aGVyKSB7CisgIHN0ZDo6c3dhcChkZXByZWNhdGVkXywgb3RoZXItPmRlcHJlY2F0ZWRfKTsKKyAgdW5pbnRlcnByZXRlZF9vcHRpb25fLlVuc2FmZUFyZW5hU3dhcCgmb3RoZXItPnVuaW50ZXJwcmV0ZWRfb3B0aW9uXyk7CisgIHN0ZDo6c3dhcChfaGFzX2JpdHNfWzBdLCBvdGhlci0+X2hhc19iaXRzX1swXSk7CisgIF9pbnRlcm5hbF9tZXRhZGF0YV8uU3dhcCgmb3RoZXItPl9pbnRlcm5hbF9tZXRhZGF0YV8pOworICBzdGQ6OnN3YXAoX2NhY2hlZF9zaXplXywgb3RoZXItPl9jYWNoZWRfc2l6ZV8pOworICBfZXh0ZW5zaW9uc18uU3dhcCgmb3RoZXItPl9leHRlbnNpb25zXyk7Cit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgU2VydmljZU9wdGlvbnM6OkdldE1ldGFkYXRhKCkgY29uc3QgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBtZXRhZGF0YTsKKyAgbWV0YWRhdGEuZGVzY3JpcHRvciA9IFNlcnZpY2VPcHRpb25zX2Rlc2NyaXB0b3JfOworICBtZXRhZGF0YS5yZWZsZWN0aW9uID0gU2VydmljZU9wdGlvbnNfcmVmbGVjdGlvbl87CisgIHJldHVybiBtZXRhZGF0YTsKK30KKworI2lmIFBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworLy8gU2VydmljZU9wdGlvbnMKKworLy8gb3B0aW9uYWwgYm9vbCBkZXByZWNhdGVkID0gMzMgW2RlZmF1bHQgPSBmYWxzZV07Citib29sIFNlcnZpY2VPcHRpb25zOjpoYXNfZGVwcmVjYXRlZCgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMXUpICE9IDA7Cit9Cit2b2lkIFNlcnZpY2VPcHRpb25zOjpzZXRfaGFzX2RlcHJlY2F0ZWQoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMXU7Cit9Cit2b2lkIFNlcnZpY2VPcHRpb25zOjpjbGVhcl9oYXNfZGVwcmVjYXRlZCgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMXU7Cit9Cit2b2lkIFNlcnZpY2VPcHRpb25zOjpjbGVhcl9kZXByZWNhdGVkKCkgeworICBkZXByZWNhdGVkXyA9IGZhbHNlOworICBjbGVhcl9oYXNfZGVwcmVjYXRlZCgpOworfQorIGJvb2wgU2VydmljZU9wdGlvbnM6OmRlcHJlY2F0ZWQoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zLmRlcHJlY2F0ZWQpCisgIHJldHVybiBkZXByZWNhdGVkXzsKK30KKyB2b2lkIFNlcnZpY2VPcHRpb25zOjpzZXRfZGVwcmVjYXRlZChib29sIHZhbHVlKSB7CisgIHNldF9oYXNfZGVwcmVjYXRlZCgpOworICBkZXByZWNhdGVkXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlT3B0aW9ucy5kZXByZWNhdGVkKQorfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CitpbnQgU2VydmljZU9wdGlvbnM6OnVuaW50ZXJwcmV0ZWRfb3B0aW9uX3NpemUoKSBjb25zdCB7CisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl8uc2l6ZSgpOworfQordm9pZCBTZXJ2aWNlT3B0aW9uczo6Y2xlYXJfdW5pbnRlcnByZXRlZF9vcHRpb24oKSB7CisgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5DbGVhcigpOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uJiBTZXJ2aWNlT3B0aW9uczo6dW5pbnRlcnByZXRlZF9vcHRpb24oaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLkdldChpbmRleCk7Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24qIFNlcnZpY2VPcHRpb25zOjptdXRhYmxlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuU2VydmljZU9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl8uTXV0YWJsZShpbmRleCk7Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24qIFNlcnZpY2VPcHRpb25zOjphZGRfdW5pbnRlcnByZXRlZF9vcHRpb24oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLkFkZCgpOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24gPioKK1NlcnZpY2VPcHRpb25zOjptdXRhYmxlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuICZ1bmludGVycHJldGVkX29wdGlvbl87Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiA+JgorU2VydmljZU9wdGlvbnM6OnVuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuU2VydmljZU9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl87Cit9CisKKyNlbmRpZiAgLy8gUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworI2lmICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCitjb25zdCBpbnQgTWV0aG9kT3B0aW9uczo6a0RlcHJlY2F0ZWRGaWVsZE51bWJlcjsKK2NvbnN0IGludCBNZXRob2RPcHRpb25zOjprVW5pbnRlcnByZXRlZE9wdGlvbkZpZWxkTnVtYmVyOworI2VuZGlmICAvLyAhZGVmaW5lZChfTVNDX1ZFUikgfHwgX01TQ19WRVIgPj0gMTkwMAorCitNZXRob2RPcHRpb25zOjpNZXRob2RPcHRpb25zKCkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zKQorfQorCit2b2lkIE1ldGhvZE9wdGlvbnM6OkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpIHsKK30KKworTWV0aG9kT3B0aW9uczo6TWV0aG9kT3B0aW9ucyhjb25zdCBNZXRob2RPcHRpb25zJiBmcm9tKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpLAorICAgIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgeworICBTaGFyZWRDdG9yKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvcHlfY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMpCit9CisKK3ZvaWQgTWV0aG9kT3B0aW9uczo6U2hhcmVkQ3RvcigpIHsKKyAgX2NhY2hlZF9zaXplXyA9IDA7CisgIGRlcHJlY2F0ZWRfID0gZmFsc2U7CisgIDo6bWVtc2V0KF9oYXNfYml0c18sIDAsIHNpemVvZihfaGFzX2JpdHNfKSk7Cit9CisKK01ldGhvZE9wdGlvbnM6On5NZXRob2RPcHRpb25zKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZGVzdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucykKKyAgU2hhcmVkRHRvcigpOworfQorCit2b2lkIE1ldGhvZE9wdGlvbnM6OlNoYXJlZER0b3IoKSB7CisgIGlmICh0aGlzICE9IGRlZmF1bHRfaW5zdGFuY2VfKSB7CisgIH0KK30KKwordm9pZCBNZXRob2RPcHRpb25zOjpTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdCB7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSBzaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogTWV0aG9kT3B0aW9uczo6ZGVzY3JpcHRvcigpIHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIHJldHVybiBNZXRob2RPcHRpb25zX2Rlc2NyaXB0b3JfOworfQorCitjb25zdCBNZXRob2RPcHRpb25zJiBNZXRob2RPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlKCkgeworICBpZiAoZGVmYXVsdF9pbnN0YW5jZV8gPT0gTlVMTCkgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICByZXR1cm4gKmRlZmF1bHRfaW5zdGFuY2VfOworfQorCitNZXRob2RPcHRpb25zKiBNZXRob2RPcHRpb25zOjpkZWZhdWx0X2luc3RhbmNlXyA9IE5VTEw7CisKK01ldGhvZE9wdGlvbnMqIE1ldGhvZE9wdGlvbnM6Ok5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3QgeworICBNZXRob2RPcHRpb25zKiBuID0gbmV3IE1ldGhvZE9wdGlvbnM7CisgIGlmIChhcmVuYSAhPSBOVUxMKSB7CisgICAgYXJlbmEtPk93bihuKTsKKyAgfQorICByZXR1cm4gbjsKK30KKwordm9pZCBNZXRob2RPcHRpb25zOjpDbGVhcigpIHsKKyAgX2V4dGVuc2lvbnNfLkNsZWFyKCk7CisgIGRlcHJlY2F0ZWRfID0gZmFsc2U7CisgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5DbGVhcigpOworICA6Om1lbXNldChfaGFzX2JpdHNfLCAwLCBzaXplb2YoX2hhc19iaXRzXykpOworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkNsZWFyKCk7CisgIH0KK30KKworYm9vbCBNZXRob2RPcHRpb25zOjpNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyNkZWZpbmUgRE9fKEVYUFJFU1NJT04pIGlmICghKEVYUFJFU1NJT04pKSBnb3RvIGZhaWx1cmUKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgdGFnOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMpCisgIGZvciAoOzspIHsKKyAgICA6OnN0ZDo6cGFpcjwgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIsIGJvb2w+IHAgPSBpbnB1dC0+UmVhZFRhZ1dpdGhDdXRvZmYoMTYzODMpOworICAgIHRhZyA9IHAuZmlyc3Q7CisgICAgaWYgKCFwLnNlY29uZCkgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICBzd2l0Y2ggKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdGaWVsZE51bWJlcih0YWcpKSB7CisgICAgICAvLyBvcHRpb25hbCBib29sIGRlcHJlY2F0ZWQgPSAzMyBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgICAgIGNhc2UgMzM6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAyNjQpIHsKKyAgICAgICAgICBET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPAorICAgICAgICAgICAgICAgICAgIGJvb2wsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0JPT0w+KAorICAgICAgICAgICAgICAgICBpbnB1dCwgJmRlcHJlY2F0ZWRfKSkpOworICAgICAgICAgIHNldF9oYXNfZGVwcmVjYXRlZCgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNzk5NCkpIGdvdG8gcGFyc2VfdW5pbnRlcnByZXRlZF9vcHRpb247CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CisgICAgICBjYXNlIDk5OTogeworICAgICAgICBpZiAodGFnID09IDc5OTQpIHsKKyAgICAgICAgIHBhcnNlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uOgorICAgICAgICAgIERPXyhpbnB1dC0+SW5jcmVtZW50UmVjdXJzaW9uRGVwdGgoKSk7CisgICAgICAgICBwYXJzZV9sb29wX3VuaW50ZXJwcmV0ZWRfb3B0aW9uOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZE1lc3NhZ2VOb1ZpcnR1YWxOb1JlY3Vyc2lvbkRlcHRoKAorICAgICAgICAgICAgICAgIGlucHV0LCBhZGRfdW5pbnRlcnByZXRlZF9vcHRpb24oKSkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNzk5NCkpIGdvdG8gcGFyc2VfbG9vcF91bmludGVycHJldGVkX29wdGlvbjsKKyAgICAgICAgaW5wdXQtPlVuc2FmZURlY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCk7CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0QXRFbmQoKSkgZ290byBzdWNjZXNzOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgZGVmYXVsdDogeworICAgICAgaGFuZGxlX3VudXN1YWw6CisgICAgICAgIGlmICh0YWcgPT0gMCB8fAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ1dpcmVUeXBlKHRhZykgPT0KKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVApIHsKKyAgICAgICAgICBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCg4MDAwdSA8PSB0YWcpKSB7CisgICAgICAgICAgRE9fKF9leHRlbnNpb25zXy5QYXJzZUZpZWxkKHRhZywgaW5wdXQsIGRlZmF1bHRfaW5zdGFuY2VfLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkpKTsKKyAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2tpcEZpZWxkKAorICAgICAgICAgICAgICBpbnB1dCwgdGFnLCBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CitzdWNjZXNzOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3VjY2Vzczpnb29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucykKKyAgcmV0dXJuIHRydWU7CitmYWlsdXJlOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2VfZmFpbHVyZTpnb29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucykKKyAgcmV0dXJuIGZhbHNlOworI3VuZGVmIERPXworfQorCit2b2lkIE1ldGhvZE9wdGlvbnM6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMpCisgIC8vIG9wdGlvbmFsIGJvb2wgZGVwcmVjYXRlZCA9IDMzIFtkZWZhdWx0ID0gZmFsc2VdOworICBpZiAoaGFzX2RlcHJlY2F0ZWQoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2woMzMsIHRoaXMtPmRlcHJlY2F0ZWQoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiB1bmludGVycHJldGVkX29wdGlvbiA9IDk5OTsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT51bmludGVycHJldGVkX29wdGlvbl9zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgOTk5LCB0aGlzLT51bmludGVycHJldGVkX29wdGlvbihpKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIEV4dGVuc2lvbiByYW5nZSBbMTAwMCwgNTM2ODcwOTEyKQorICBfZXh0ZW5zaW9uc18uU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgICAgMTAwMCwgNTM2ODcwOTEyLCBvdXRwdXQpOworCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25GaWVsZHMoCisgICAgICAgIHVua25vd25fZmllbGRzKCksIG91dHB1dCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9lbmQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMpCit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIE1ldGhvZE9wdGlvbnM6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogdGFyZ2V0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMpCisgIC8vIG9wdGlvbmFsIGJvb2wgZGVwcmVjYXRlZCA9IDMzIFtkZWZhdWx0ID0gZmFsc2VdOworICBpZiAoaGFzX2RlcHJlY2F0ZWQoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2xUb0FycmF5KDMzLCB0aGlzLT5kZXByZWNhdGVkKCksIHRhcmdldCk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CisgIGZvciAodW5zaWduZWQgaW50IGkgPSAwLCBuID0gdGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb25fc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OgorICAgICAgV3JpdGVNZXNzYWdlTm9WaXJ0dWFsVG9BcnJheSgKKyAgICAgICAgOTk5LCB0aGlzLT51bmludGVycHJldGVkX29wdGlvbihpKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIEV4dGVuc2lvbiByYW5nZSBbMTAwMCwgNTM2ODcwOTEyKQorICB0YXJnZXQgPSBfZXh0ZW5zaW9uc18uU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICAgIDEwMDAsIDUzNjg3MDkxMiwgdGFyZ2V0KTsKKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTZXJpYWxpemVVbmtub3duRmllbGRzVG9BcnJheSgKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSwgdGFyZ2V0KTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X2VuZDpnb29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucykKKyAgcmV0dXJuIHRhcmdldDsKK30KKworaW50IE1ldGhvZE9wdGlvbnM6OkJ5dGVTaXplKCkgY29uc3QgeworICBpbnQgdG90YWxfc2l6ZSA9IDA7CisKKyAgLy8gb3B0aW9uYWwgYm9vbCBkZXByZWNhdGVkID0gMzMgW2RlZmF1bHQgPSBmYWxzZV07CisgIGlmIChoYXNfZGVwcmVjYXRlZCgpKSB7CisgICAgdG90YWxfc2l6ZSArPSAyICsgMTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiB1bmludGVycHJldGVkX29wdGlvbiA9IDk5OTsKKyAgdG90YWxfc2l6ZSArPSAyICogdGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb25fc2l6ZSgpOworICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPnVuaW50ZXJwcmV0ZWRfb3B0aW9uX3NpemUoKTsgaSsrKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1lc3NhZ2VTaXplTm9WaXJ0dWFsKAorICAgICAgICB0aGlzLT51bmludGVycHJldGVkX29wdGlvbihpKSk7CisgIH0KKworICB0b3RhbF9zaXplICs9IF9leHRlbnNpb25zXy5CeXRlU2l6ZSgpOworCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHRvdGFsX3NpemUgKz0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OkNvbXB1dGVVbmtub3duRmllbGRzU2l6ZSgKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSk7CisgIH0KKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHRvdGFsX3NpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworICByZXR1cm4gdG90YWxfc2l6ZTsKK30KKwordm9pZCBNZXRob2RPcHRpb25zOjpNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGNvbnN0IE1ldGhvZE9wdGlvbnMqIHNvdXJjZSA9IAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RHluYW1pY0Nhc3RUb0dlbmVyYXRlZDxjb25zdCBNZXRob2RPcHRpb25zPigKKyAgICAgICAgICAmZnJvbSk7CisgIGlmIChzb3VyY2UgPT0gTlVMTCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlJlZmxlY3Rpb25PcHM6Ok1lcmdlKGZyb20sIHRoaXMpOworICB9IGVsc2UgeworICAgIE1lcmdlRnJvbSgqc291cmNlKTsKKyAgfQorfQorCit2b2lkIE1ldGhvZE9wdGlvbnM6Ok1lcmdlRnJvbShjb25zdCBNZXRob2RPcHRpb25zJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5NZXJnZUZyb20oZnJvbS51bmludGVycHJldGVkX29wdGlvbl8pOworICBpZiAoZnJvbS5faGFzX2JpdHNfWzAgLyAzMl0gJiAoMHhmZnUgPDwgKDAgJSAzMikpKSB7CisgICAgaWYgKGZyb20uaGFzX2RlcHJlY2F0ZWQoKSkgeworICAgICAgc2V0X2RlcHJlY2F0ZWQoZnJvbS5kZXByZWNhdGVkKCkpOworICAgIH0KKyAgfQorICBfZXh0ZW5zaW9uc18uTWVyZ2VGcm9tKGZyb20uX2V4dGVuc2lvbnNfKTsKKyAgaWYgKGZyb20uX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPk1lcmdlRnJvbShmcm9tLnVua25vd25fZmllbGRzKCkpOworICB9Cit9CisKK3ZvaWQgTWV0aG9kT3B0aW9uczo6Q29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKwordm9pZCBNZXRob2RPcHRpb25zOjpDb3B5RnJvbShjb25zdCBNZXRob2RPcHRpb25zJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKworYm9vbCBNZXRob2RPcHRpb25zOjpJc0luaXRpYWxpemVkKCkgY29uc3QgeworCisgIGlmICghOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QWxsQXJlSW5pdGlhbGl6ZWQodGhpcy0+dW5pbnRlcnByZXRlZF9vcHRpb24oKSkpIHJldHVybiBmYWxzZTsKKworICBpZiAoIV9leHRlbnNpb25zXy5Jc0luaXRpYWxpemVkKCkpIHJldHVybiBmYWxzZTsgIHJldHVybiB0cnVlOworfQorCit2b2lkIE1ldGhvZE9wdGlvbnM6OlN3YXAoTWV0aG9kT3B0aW9ucyogb3RoZXIpIHsKKyAgaWYgKG90aGVyID09IHRoaXMpIHJldHVybjsKKyAgSW50ZXJuYWxTd2FwKG90aGVyKTsKK30KK3ZvaWQgTWV0aG9kT3B0aW9uczo6SW50ZXJuYWxTd2FwKE1ldGhvZE9wdGlvbnMqIG90aGVyKSB7CisgIHN0ZDo6c3dhcChkZXByZWNhdGVkXywgb3RoZXItPmRlcHJlY2F0ZWRfKTsKKyAgdW5pbnRlcnByZXRlZF9vcHRpb25fLlVuc2FmZUFyZW5hU3dhcCgmb3RoZXItPnVuaW50ZXJwcmV0ZWRfb3B0aW9uXyk7CisgIHN0ZDo6c3dhcChfaGFzX2JpdHNfWzBdLCBvdGhlci0+X2hhc19iaXRzX1swXSk7CisgIF9pbnRlcm5hbF9tZXRhZGF0YV8uU3dhcCgmb3RoZXItPl9pbnRlcm5hbF9tZXRhZGF0YV8pOworICBzdGQ6OnN3YXAoX2NhY2hlZF9zaXplXywgb3RoZXItPl9jYWNoZWRfc2l6ZV8pOworICBfZXh0ZW5zaW9uc18uU3dhcCgmb3RoZXItPl9leHRlbnNpb25zXyk7Cit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgTWV0aG9kT3B0aW9uczo6R2V0TWV0YWRhdGEoKSBjb25zdCB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIG1ldGFkYXRhOworICBtZXRhZGF0YS5kZXNjcmlwdG9yID0gTWV0aG9kT3B0aW9uc19kZXNjcmlwdG9yXzsKKyAgbWV0YWRhdGEucmVmbGVjdGlvbiA9IE1ldGhvZE9wdGlvbnNfcmVmbGVjdGlvbl87CisgIHJldHVybiBtZXRhZGF0YTsKK30KKworI2lmIFBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworLy8gTWV0aG9kT3B0aW9ucworCisvLyBvcHRpb25hbCBib29sIGRlcHJlY2F0ZWQgPSAzMyBbZGVmYXVsdCA9IGZhbHNlXTsKK2Jvb2wgTWV0aG9kT3B0aW9uczo6aGFzX2RlcHJlY2F0ZWQoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDF1KSAhPSAwOworfQordm9pZCBNZXRob2RPcHRpb25zOjpzZXRfaGFzX2RlcHJlY2F0ZWQoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMXU7Cit9Cit2b2lkIE1ldGhvZE9wdGlvbnM6OmNsZWFyX2hhc19kZXByZWNhdGVkKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAxdTsKK30KK3ZvaWQgTWV0aG9kT3B0aW9uczo6Y2xlYXJfZGVwcmVjYXRlZCgpIHsKKyAgZGVwcmVjYXRlZF8gPSBmYWxzZTsKKyAgY2xlYXJfaGFzX2RlcHJlY2F0ZWQoKTsKK30KKyBib29sIE1ldGhvZE9wdGlvbnM6OmRlcHJlY2F0ZWQoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMuZGVwcmVjYXRlZCkKKyAgcmV0dXJuIGRlcHJlY2F0ZWRfOworfQorIHZvaWQgTWV0aG9kT3B0aW9uczo6c2V0X2RlcHJlY2F0ZWQoYm9vbCB2YWx1ZSkgeworICBzZXRfaGFzX2RlcHJlY2F0ZWQoKTsKKyAgZGVwcmVjYXRlZF8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucy5kZXByZWNhdGVkKQorfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CitpbnQgTWV0aG9kT3B0aW9uczo6dW5pbnRlcnByZXRlZF9vcHRpb25fc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5zaXplKCk7Cit9Cit2b2lkIE1ldGhvZE9wdGlvbnM6OmNsZWFyX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgeworICB1bmludGVycHJldGVkX29wdGlvbl8uQ2xlYXIoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiYgTWV0aG9kT3B0aW9uczo6dW5pbnRlcnByZXRlZF9vcHRpb24oaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl8uR2V0KGluZGV4KTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiogTWV0aG9kT3B0aW9uczo6bXV0YWJsZV91bmludGVycHJldGVkX29wdGlvbihpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl8uTXV0YWJsZShpbmRleCk7Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24qIE1ldGhvZE9wdGlvbnM6OmFkZF91bmludGVycHJldGVkX29wdGlvbigpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5BZGQoKTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uID4qCitNZXRob2RPcHRpb25zOjptdXRhYmxlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gJnVuaW50ZXJwcmV0ZWRfb3B0aW9uXzsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uID4mCitNZXRob2RPcHRpb25zOjp1bmludGVycHJldGVkX29wdGlvbigpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl87Cit9CisKKyNlbmRpZiAgLy8gUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworI2lmICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCitjb25zdCBpbnQgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6a05hbWVQYXJ0RmllbGROdW1iZXI7Citjb25zdCBpbnQgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6a0lzRXh0ZW5zaW9uRmllbGROdW1iZXI7CisjZW5kaWYgIC8vICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCisKK1VuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQ6OlVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQoKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpLCBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uTmFtZVBhcnQpCit9CisKK3ZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6SW5pdEFzRGVmYXVsdEluc3RhbmNlKCkgeworfQorCitVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0KGNvbnN0IFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQmIGZyb20pCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksCisgICAgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29weV9jb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5OYW1lUGFydCkKK30KKwordm9pZCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpTaGFyZWRDdG9yKCkgeworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZygpOworICBfY2FjaGVkX3NpemVfID0gMDsKKyAgbmFtZV9wYXJ0Xy5VbnNhZmVTZXREZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGlzX2V4dGVuc2lvbl8gPSBmYWxzZTsKKyAgOjptZW1zZXQoX2hhc19iaXRzXywgMCwgc2l6ZW9mKF9oYXNfYml0c18pKTsKK30KKworVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6flVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChkZXN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLk5hbWVQYXJ0KQorICBTaGFyZWREdG9yKCk7Cit9CisKK3ZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6U2hhcmVkRHRvcigpIHsKKyAgbmFtZV9wYXJ0Xy5EZXN0cm95Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBpZiAodGhpcyAhPSBkZWZhdWx0X2luc3RhbmNlXykgeworICB9Cit9CisKK3ZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6U2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3QgeworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQ6OmRlc2NyaXB0b3IoKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICByZXR1cm4gVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydF9kZXNjcmlwdG9yXzsKK30KKworY29uc3QgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydCYgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6ZGVmYXVsdF9pbnN0YW5jZSgpIHsKKyAgaWYgKGRlZmF1bHRfaW5zdGFuY2VfID09IE5VTEwpIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgcmV0dXJuICpkZWZhdWx0X2luc3RhbmNlXzsKK30KKworVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydCogVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBOVUxMOworCitVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0KiBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0IHsKKyAgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydCogbiA9IG5ldyBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OworICBpZiAoYXJlbmEgIT0gTlVMTCkgeworICAgIGFyZW5hLT5Pd24obik7CisgIH0KKyAgcmV0dXJuIG47Cit9CisKK3ZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6Q2xlYXIoKSB7CisgIGlmIChfaGFzX2JpdHNfWzAgLyAzMl0gJiAzdSkgeworICAgIGlmIChoYXNfbmFtZV9wYXJ0KCkpIHsKKyAgICAgIG5hbWVfcGFydF8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICAgIH0KKyAgICBpc19leHRlbnNpb25fID0gZmFsc2U7CisgIH0KKyAgOjptZW1zZXQoX2hhc19iaXRzXywgMCwgc2l6ZW9mKF9oYXNfYml0c18pKTsKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5DbGVhcigpOworICB9Cit9CisKK2Jvb2wgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6TWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KSB7CisjZGVmaW5lIERPXyhFWFBSRVNTSU9OKSBpZiAoIShFWFBSRVNTSU9OKSkgZ290byBmYWlsdXJlCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIHRhZzsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLk5hbWVQYXJ0KQorICBmb3IgKDs7KSB7CisgICAgOjpzdGQ6OnBhaXI8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyLCBib29sPiBwID0gaW5wdXQtPlJlYWRUYWdXaXRoQ3V0b2ZmKDEyNyk7CisgICAgdGFnID0gcC5maXJzdDsKKyAgICBpZiAoIXAuc2Vjb25kKSBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgIHN3aXRjaCAoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ0ZpZWxkTnVtYmVyKHRhZykpIHsKKyAgICAgIC8vIHJlcXVpcmVkIHN0cmluZyBuYW1lX3BhcnQgPSAxOworICAgICAgY2FzZSAxOiB7CisgICAgICAgIGlmICh0YWcgPT0gMTApIHsKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoCisgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPm11dGFibGVfbmFtZV9wYXJ0KCkpKTsKKyAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgICAgICAgIHRoaXMtPm5hbWVfcGFydCgpLmRhdGEoKSwgdGhpcy0+bmFtZV9wYXJ0KCkubGVuZ3RoKCksCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpQQVJTRSwKKyAgICAgICAgICAgICJnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5OYW1lUGFydC5uYW1lX3BhcnQiKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDE2KSkgZ290byBwYXJzZV9pc19leHRlbnNpb247CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyByZXF1aXJlZCBib29sIGlzX2V4dGVuc2lvbiA9IDI7CisgICAgICBjYXNlIDI6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAxNikgeworICAgICAgICAgcGFyc2VfaXNfZXh0ZW5zaW9uOgorICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgYm9vbCwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfQk9PTD4oCisgICAgICAgICAgICAgICAgIGlucHV0LCAmaXNfZXh0ZW5zaW9uXykpKTsKKyAgICAgICAgICBzZXRfaGFzX2lzX2V4dGVuc2lvbigpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RBdEVuZCgpKSBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBkZWZhdWx0OiB7CisgICAgICBoYW5kbGVfdW51c3VhbDoKKyAgICAgICAgaWYgKHRhZyA9PSAwIHx8CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnV2lyZVR5cGUodGFnKSA9PQorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0VORF9HUk9VUCkgeworICAgICAgICAgIGdvdG8gc3VjY2VzczsKKyAgICAgICAgfQorICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2tpcEZpZWxkKAorICAgICAgICAgICAgICBpbnB1dCwgdGFnLCBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CitzdWNjZXNzOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3VjY2Vzczpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5OYW1lUGFydCkKKyAgcmV0dXJuIHRydWU7CitmYWlsdXJlOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2VfZmFpbHVyZTpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5OYW1lUGFydCkKKyAgcmV0dXJuIGZhbHNlOworI3VuZGVmIERPXworfQorCit2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQ6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uTmFtZVBhcnQpCisgIC8vIHJlcXVpcmVkIHN0cmluZyBuYW1lX3BhcnQgPSAxOworICBpZiAoaGFzX25hbWVfcGFydCgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5uYW1lX3BhcnQoKS5kYXRhKCksIHRoaXMtPm5hbWVfcGFydCgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLk5hbWVQYXJ0Lm5hbWVfcGFydCIpOworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ01heWJlQWxpYXNlZCgKKyAgICAgIDEsIHRoaXMtPm5hbWVfcGFydCgpLCBvdXRwdXQpOworICB9CisKKyAgLy8gcmVxdWlyZWQgYm9vbCBpc19leHRlbnNpb24gPSAyOworICBpZiAoaGFzX2lzX2V4dGVuc2lvbigpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlQm9vbCgyLCB0aGlzLT5pc19leHRlbnNpb24oKSwgb3V0cHV0KTsKKyAgfQorCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25GaWVsZHMoCisgICAgICAgIHVua25vd25fZmllbGRzKCksIG91dHB1dCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9lbmQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uTmFtZVBhcnQpCit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQ6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogdGFyZ2V0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uTmFtZVBhcnQpCisgIC8vIHJlcXVpcmVkIHN0cmluZyBuYW1lX3BhcnQgPSAxOworICBpZiAoaGFzX25hbWVfcGFydCgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5uYW1lX3BhcnQoKS5kYXRhKCksIHRoaXMtPm5hbWVfcGFydCgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLk5hbWVQYXJ0Lm5hbWVfcGFydCIpOworICAgIHRhcmdldCA9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdUb0FycmF5KAorICAgICAgICAxLCB0aGlzLT5uYW1lX3BhcnQoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIHJlcXVpcmVkIGJvb2wgaXNfZXh0ZW5zaW9uID0gMjsKKyAgaWYgKGhhc19pc19leHRlbnNpb24oKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2xUb0FycmF5KDIsIHRoaXMtPmlzX2V4dGVuc2lvbigpLCB0YXJnZXQpOworICB9CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bkZpZWxkc1RvQXJyYXkoCisgICAgICAgIHVua25vd25fZmllbGRzKCksIHRhcmdldCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9lbmQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uTmFtZVBhcnQpCisgIHJldHVybiB0YXJnZXQ7Cit9CisKK2ludCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpSZXF1aXJlZEZpZWxkc0J5dGVTaXplRmFsbGJhY2soKSBjb25zdCB7CisgIGludCB0b3RhbF9zaXplID0gMDsKKworICBpZiAoaGFzX25hbWVfcGFydCgpKSB7CisgICAgLy8gcmVxdWlyZWQgc3RyaW5nIG5hbWVfcGFydCA9IDE7CisgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTdHJpbmdTaXplKAorICAgICAgICB0aGlzLT5uYW1lX3BhcnQoKSk7CisgIH0KKworICBpZiAoaGFzX2lzX2V4dGVuc2lvbigpKSB7CisgICAgLy8gcmVxdWlyZWQgYm9vbCBpc19leHRlbnNpb24gPSAyOworICAgIHRvdGFsX3NpemUgKz0gMSArIDE7CisgIH0KKworICByZXR1cm4gdG90YWxfc2l6ZTsKK30KK2ludCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpCeXRlU2l6ZSgpIGNvbnN0IHsKKyAgaW50IHRvdGFsX3NpemUgPSAwOworCisgIGlmICgoKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAzKSBeIDB4MDAwMDAwMDMpID09IDApIHsgIC8vIEFsbCByZXF1aXJlZCBmaWVsZHMgYXJlIHByZXNlbnQuCisgICAgLy8gcmVxdWlyZWQgc3RyaW5nIG5hbWVfcGFydCA9IDE7CisgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTdHJpbmdTaXplKAorICAgICAgICB0aGlzLT5uYW1lX3BhcnQoKSk7CisKKyAgICAvLyByZXF1aXJlZCBib29sIGlzX2V4dGVuc2lvbiA9IDI7CisgICAgdG90YWxfc2l6ZSArPSAxICsgMTsKKworICB9IGVsc2UgeworICAgIHRvdGFsX3NpemUgKz0gUmVxdWlyZWRGaWVsZHNCeXRlU2l6ZUZhbGxiYWNrKCk7CisgIH0KKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6Q29tcHV0ZVVua25vd25GaWVsZHNTaXplKAorICAgICAgICB1bmtub3duX2ZpZWxkcygpKTsKKyAgfQorICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gdG90YWxfc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7CisgIHJldHVybiB0b3RhbF9zaXplOworfQorCit2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQ6Ok1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgY29uc3QgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydCogc291cmNlID0gCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpEeW5hbWljQ2FzdFRvR2VuZXJhdGVkPGNvbnN0IFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQ+KAorICAgICAgICAgICZmcm9tKTsKKyAgaWYgKHNvdXJjZSA9PSBOVUxMKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6UmVmbGVjdGlvbk9wczo6TWVyZ2UoZnJvbSwgdGhpcyk7CisgIH0gZWxzZSB7CisgICAgTWVyZ2VGcm9tKCpzb3VyY2UpOworICB9Cit9CisKK3ZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6TWVyZ2VGcm9tKGNvbnN0IFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgaWYgKGZyb20uX2hhc19iaXRzX1swIC8gMzJdICYgKDB4ZmZ1IDw8ICgwICUgMzIpKSkgeworICAgIGlmIChmcm9tLmhhc19uYW1lX3BhcnQoKSkgeworICAgICAgc2V0X2hhc19uYW1lX3BhcnQoKTsKKyAgICAgIG5hbWVfcGFydF8uQXNzaWduV2l0aERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBmcm9tLm5hbWVfcGFydF8pOworICAgIH0KKyAgICBpZiAoZnJvbS5oYXNfaXNfZXh0ZW5zaW9uKCkpIHsKKyAgICAgIHNldF9pc19leHRlbnNpb24oZnJvbS5pc19leHRlbnNpb24oKSk7CisgICAgfQorICB9CisgIGlmIChmcm9tLl9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5NZXJnZUZyb20oZnJvbS51bmtub3duX2ZpZWxkcygpKTsKKyAgfQorfQorCit2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQ6OkNvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK3ZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6Q29weUZyb20oY29uc3QgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydCYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK2Jvb2wgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6SXNJbml0aWFsaXplZCgpIGNvbnN0IHsKKyAgaWYgKChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMykgIT0gMHgwMDAwMDAwMykgcmV0dXJuIGZhbHNlOworCisgIHJldHVybiB0cnVlOworfQorCit2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQ6OlN3YXAoVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydCogb3RoZXIpIHsKKyAgaWYgKG90aGVyID09IHRoaXMpIHJldHVybjsKKyAgSW50ZXJuYWxTd2FwKG90aGVyKTsKK30KK3ZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6SW50ZXJuYWxTd2FwKFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQqIG90aGVyKSB7CisgIG5hbWVfcGFydF8uU3dhcCgmb3RoZXItPm5hbWVfcGFydF8pOworICBzdGQ6OnN3YXAoaXNfZXh0ZW5zaW9uXywgb3RoZXItPmlzX2V4dGVuc2lvbl8pOworICBzdGQ6OnN3YXAoX2hhc19iaXRzX1swXSwgb3RoZXItPl9oYXNfYml0c19bMF0pOworICBfaW50ZXJuYWxfbWV0YWRhdGFfLlN3YXAoJm90aGVyLT5faW50ZXJuYWxfbWV0YWRhdGFfKTsKKyAgc3RkOjpzd2FwKF9jYWNoZWRfc2l6ZV8sIG90aGVyLT5fY2FjaGVkX3NpemVfKTsKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpHZXRNZXRhZGF0YSgpIGNvbnN0IHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgbWV0YWRhdGE7CisgIG1ldGFkYXRhLmRlc2NyaXB0b3IgPSBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0X2Rlc2NyaXB0b3JfOworICBtZXRhZGF0YS5yZWZsZWN0aW9uID0gVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydF9yZWZsZWN0aW9uXzsKKyAgcmV0dXJuIG1ldGFkYXRhOworfQorCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworI2lmICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCitjb25zdCBpbnQgVW5pbnRlcnByZXRlZE9wdGlvbjo6a05hbWVGaWVsZE51bWJlcjsKK2NvbnN0IGludCBVbmludGVycHJldGVkT3B0aW9uOjprSWRlbnRpZmllclZhbHVlRmllbGROdW1iZXI7Citjb25zdCBpbnQgVW5pbnRlcnByZXRlZE9wdGlvbjo6a1Bvc2l0aXZlSW50VmFsdWVGaWVsZE51bWJlcjsKK2NvbnN0IGludCBVbmludGVycHJldGVkT3B0aW9uOjprTmVnYXRpdmVJbnRWYWx1ZUZpZWxkTnVtYmVyOworY29uc3QgaW50IFVuaW50ZXJwcmV0ZWRPcHRpb246OmtEb3VibGVWYWx1ZUZpZWxkTnVtYmVyOworY29uc3QgaW50IFVuaW50ZXJwcmV0ZWRPcHRpb246OmtTdHJpbmdWYWx1ZUZpZWxkTnVtYmVyOworY29uc3QgaW50IFVuaW50ZXJwcmV0ZWRPcHRpb246OmtBZ2dyZWdhdGVWYWx1ZUZpZWxkTnVtYmVyOworI2VuZGlmICAvLyAhZGVmaW5lZChfTVNDX1ZFUikgfHwgX01TQ19WRVIgPj0gMTkwMAorCitVbmludGVycHJldGVkT3B0aW9uOjpVbmludGVycHJldGVkT3B0aW9uKCkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKQorfQorCit2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpIHsKK30KKworVW5pbnRlcnByZXRlZE9wdGlvbjo6VW5pbnRlcnByZXRlZE9wdGlvbihjb25zdCBVbmludGVycHJldGVkT3B0aW9uJiBmcm9tKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpLAorICAgIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgeworICBTaGFyZWRDdG9yKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvcHlfY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24pCit9CisKK3ZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6U2hhcmVkQ3RvcigpIHsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmcoKTsKKyAgX2NhY2hlZF9zaXplXyA9IDA7CisgIGlkZW50aWZpZXJfdmFsdWVfLlVuc2FmZVNldERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgcG9zaXRpdmVfaW50X3ZhbHVlXyA9IEdPT0dMRV9VTE9OR0xPTkcoMCk7CisgIG5lZ2F0aXZlX2ludF92YWx1ZV8gPSBHT09HTEVfTE9OR0xPTkcoMCk7CisgIGRvdWJsZV92YWx1ZV8gPSAwOworICBzdHJpbmdfdmFsdWVfLlVuc2FmZVNldERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgYWdncmVnYXRlX3ZhbHVlXy5VbnNhZmVTZXREZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIDo6bWVtc2V0KF9oYXNfYml0c18sIDAsIHNpemVvZihfaGFzX2JpdHNfKSk7Cit9CisKK1VuaW50ZXJwcmV0ZWRPcHRpb246On5VbmludGVycHJldGVkT3B0aW9uKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZGVzdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbikKKyAgU2hhcmVkRHRvcigpOworfQorCit2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OlNoYXJlZER0b3IoKSB7CisgIGlkZW50aWZpZXJfdmFsdWVfLkRlc3Ryb3lOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIHN0cmluZ192YWx1ZV8uRGVzdHJveU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgYWdncmVnYXRlX3ZhbHVlXy5EZXN0cm95Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBpZiAodGhpcyAhPSBkZWZhdWx0X2luc3RhbmNlXykgeworICB9Cit9CisKK3ZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6U2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3QgeworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIFVuaW50ZXJwcmV0ZWRPcHRpb246OmRlc2NyaXB0b3IoKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICByZXR1cm4gVW5pbnRlcnByZXRlZE9wdGlvbl9kZXNjcmlwdG9yXzsKK30KKworY29uc3QgVW5pbnRlcnByZXRlZE9wdGlvbiYgVW5pbnRlcnByZXRlZE9wdGlvbjo6ZGVmYXVsdF9pbnN0YW5jZSgpIHsKKyAgaWYgKGRlZmF1bHRfaW5zdGFuY2VfID09IE5VTEwpIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgcmV0dXJuICpkZWZhdWx0X2luc3RhbmNlXzsKK30KKworVW5pbnRlcnByZXRlZE9wdGlvbiogVW5pbnRlcnByZXRlZE9wdGlvbjo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBOVUxMOworCitVbmludGVycHJldGVkT3B0aW9uKiBVbmludGVycHJldGVkT3B0aW9uOjpOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0IHsKKyAgVW5pbnRlcnByZXRlZE9wdGlvbiogbiA9IG5ldyBVbmludGVycHJldGVkT3B0aW9uOworICBpZiAoYXJlbmEgIT0gTlVMTCkgeworICAgIGFyZW5hLT5Pd24obik7CisgIH0KKyAgcmV0dXJuIG47Cit9CisKK3ZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6Q2xlYXIoKSB7CisjZGVmaW5lIFpSX0hFTFBFUl8oZikgcmVpbnRlcnByZXRfY2FzdDxjaGFyKj4oXAorICAmcmVpbnRlcnByZXRfY2FzdDxVbmludGVycHJldGVkT3B0aW9uKj4oMTYpLT5mKQorCisjZGVmaW5lIFpSXyhmaXJzdCwgbGFzdCkgZG8ge1wKKyAgOjptZW1zZXQoJmZpcnN0LCAwLFwKKyAgICAgICAgICAgWlJfSEVMUEVSXyhsYXN0KSAtIFpSX0hFTFBFUl8oZmlyc3QpICsgc2l6ZW9mKGxhc3QpKTtcCit9IHdoaWxlICgwKQorCisgIGlmIChfaGFzX2JpdHNfWzAgLyAzMl0gJiAxMjZ1KSB7CisgICAgWlJfKHBvc2l0aXZlX2ludF92YWx1ZV8sIGRvdWJsZV92YWx1ZV8pOworICAgIGlmIChoYXNfaWRlbnRpZmllcl92YWx1ZSgpKSB7CisgICAgICBpZGVudGlmaWVyX3ZhbHVlXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgICAgfQorICAgIGlmIChoYXNfc3RyaW5nX3ZhbHVlKCkpIHsKKyAgICAgIHN0cmluZ192YWx1ZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICAgIH0KKyAgICBpZiAoaGFzX2FnZ3JlZ2F0ZV92YWx1ZSgpKSB7CisgICAgICBhZ2dyZWdhdGVfdmFsdWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgICB9CisgIH0KKworI3VuZGVmIFpSX0hFTFBFUl8KKyN1bmRlZiBaUl8KKworICBuYW1lXy5DbGVhcigpOworICA6Om1lbXNldChfaGFzX2JpdHNfLCAwLCBzaXplb2YoX2hhc19iaXRzXykpOworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkNsZWFyKCk7CisgIH0KK30KKworYm9vbCBVbmludGVycHJldGVkT3B0aW9uOjpNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyNkZWZpbmUgRE9fKEVYUFJFU1NJT04pIGlmICghKEVYUFJFU1NJT04pKSBnb3RvIGZhaWx1cmUKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgdGFnOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24pCisgIGZvciAoOzspIHsKKyAgICA6OnN0ZDo6cGFpcjwgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIsIGJvb2w+IHAgPSBpbnB1dC0+UmVhZFRhZ1dpdGhDdXRvZmYoMTI3KTsKKyAgICB0YWcgPSBwLmZpcnN0OworICAgIGlmICghcC5zZWNvbmQpIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgc3dpdGNoICg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnRmllbGROdW1iZXIodGFnKSkgeworICAgICAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLk5hbWVQYXJ0IG5hbWUgPSAyOworICAgICAgY2FzZSAyOiB7CisgICAgICAgIGlmICh0YWcgPT0gMTgpIHsKKyAgICAgICAgICBET18oaW5wdXQtPkluY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCkpOworICAgICAgICAgcGFyc2VfbG9vcF9uYW1lOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZE1lc3NhZ2VOb1ZpcnR1YWxOb1JlY3Vyc2lvbkRlcHRoKAorICAgICAgICAgICAgICAgIGlucHV0LCBhZGRfbmFtZSgpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygxOCkpIGdvdG8gcGFyc2VfbG9vcF9uYW1lOworICAgICAgICBpbnB1dC0+VW5zYWZlRGVjcmVtZW50UmVjdXJzaW9uRGVwdGgoKTsKKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMjYpKSBnb3RvIHBhcnNlX2lkZW50aWZpZXJfdmFsdWU7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCBzdHJpbmcgaWRlbnRpZmllcl92YWx1ZSA9IDM7CisgICAgICBjYXNlIDM6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAyNikgeworICAgICAgICAgcGFyc2VfaWRlbnRpZmllcl92YWx1ZToKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoCisgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPm11dGFibGVfaWRlbnRpZmllcl92YWx1ZSgpKSk7CisgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICAgICAgICB0aGlzLT5pZGVudGlmaWVyX3ZhbHVlKCkuZGF0YSgpLCB0aGlzLT5pZGVudGlmaWVyX3ZhbHVlKCkubGVuZ3RoKCksCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpQQVJTRSwKKyAgICAgICAgICAgICJnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5pZGVudGlmaWVyX3ZhbHVlIik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygzMikpIGdvdG8gcGFyc2VfcG9zaXRpdmVfaW50X3ZhbHVlOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgdWludDY0IHBvc2l0aXZlX2ludF92YWx1ZSA9IDQ7CisgICAgICBjYXNlIDQ6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAzMikgeworICAgICAgICAgcGFyc2VfcG9zaXRpdmVfaW50X3ZhbHVlOgorICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50NjQsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX1VJTlQ2ND4oCisgICAgICAgICAgICAgICAgIGlucHV0LCAmcG9zaXRpdmVfaW50X3ZhbHVlXykpKTsKKyAgICAgICAgICBzZXRfaGFzX3Bvc2l0aXZlX2ludF92YWx1ZSgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNDApKSBnb3RvIHBhcnNlX25lZ2F0aXZlX2ludF92YWx1ZTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIGludDY0IG5lZ2F0aXZlX2ludF92YWx1ZSA9IDU7CisgICAgICBjYXNlIDU6IHsKKyAgICAgICAgaWYgKHRhZyA9PSA0MCkgeworICAgICAgICAgcGFyc2VfbmVnYXRpdmVfaW50X3ZhbHVlOgorICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnQ2NCwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfSU5UNjQ+KAorICAgICAgICAgICAgICAgICBpbnB1dCwgJm5lZ2F0aXZlX2ludF92YWx1ZV8pKSk7CisgICAgICAgICAgc2V0X2hhc19uZWdhdGl2ZV9pbnRfdmFsdWUoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDQ5KSkgZ290byBwYXJzZV9kb3VibGVfdmFsdWU7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCBkb3VibGUgZG91YmxlX3ZhbHVlID0gNjsKKyAgICAgIGNhc2UgNjogeworICAgICAgICBpZiAodGFnID09IDQ5KSB7CisgICAgICAgICBwYXJzZV9kb3VibGVfdmFsdWU6CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICBkb3VibGUsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0RPVUJMRT4oCisgICAgICAgICAgICAgICAgIGlucHV0LCAmZG91YmxlX3ZhbHVlXykpKTsKKyAgICAgICAgICBzZXRfaGFzX2RvdWJsZV92YWx1ZSgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNTgpKSBnb3RvIHBhcnNlX3N0cmluZ192YWx1ZTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIGJ5dGVzIHN0cmluZ192YWx1ZSA9IDc7CisgICAgICBjYXNlIDc6IHsKKyAgICAgICAgaWYgKHRhZyA9PSA1OCkgeworICAgICAgICAgcGFyc2Vfc3RyaW5nX3ZhbHVlOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZEJ5dGVzKAorICAgICAgICAgICAgICAgIGlucHV0LCB0aGlzLT5tdXRhYmxlX3N0cmluZ192YWx1ZSgpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg2NikpIGdvdG8gcGFyc2VfYWdncmVnYXRlX3ZhbHVlOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgc3RyaW5nIGFnZ3JlZ2F0ZV92YWx1ZSA9IDg7CisgICAgICBjYXNlIDg6IHsKKyAgICAgICAgaWYgKHRhZyA9PSA2NikgeworICAgICAgICAgcGFyc2VfYWdncmVnYXRlX3ZhbHVlOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFN0cmluZygKKyAgICAgICAgICAgICAgICBpbnB1dCwgdGhpcy0+bXV0YWJsZV9hZ2dyZWdhdGVfdmFsdWUoKSkpOworICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgICAgICAgdGhpcy0+YWdncmVnYXRlX3ZhbHVlKCkuZGF0YSgpLCB0aGlzLT5hZ2dyZWdhdGVfdmFsdWUoKS5sZW5ndGgoKSwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlBBUlNFLAorICAgICAgICAgICAgImdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLmFnZ3JlZ2F0ZV92YWx1ZSIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RBdEVuZCgpKSBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBkZWZhdWx0OiB7CisgICAgICBoYW5kbGVfdW51c3VhbDoKKyAgICAgICAgaWYgKHRhZyA9PSAwIHx8CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnV2lyZVR5cGUodGFnKSA9PQorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0VORF9HUk9VUCkgeworICAgICAgICAgIGdvdG8gc3VjY2VzczsKKyAgICAgICAgfQorICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2tpcEZpZWxkKAorICAgICAgICAgICAgICBpbnB1dCwgdGFnLCBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CitzdWNjZXNzOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3VjY2Vzczpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbikKKyAgcmV0dXJuIHRydWU7CitmYWlsdXJlOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2VfZmFpbHVyZTpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbikKKyAgcmV0dXJuIGZhbHNlOworI3VuZGVmIERPXworfQorCit2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24pCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5OYW1lUGFydCBuYW1lID0gMjsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT5uYW1lX3NpemUoKTsgaSA8IG47IGkrKykgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZU1lc3NhZ2VNYXliZVRvQXJyYXkoCisgICAgICAyLCB0aGlzLT5uYW1lKGkpLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIGlkZW50aWZpZXJfdmFsdWUgPSAzOworICBpZiAoaGFzX2lkZW50aWZpZXJfdmFsdWUoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+aWRlbnRpZmllcl92YWx1ZSgpLmRhdGEoKSwgdGhpcy0+aWRlbnRpZmllcl92YWx1ZSgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLmlkZW50aWZpZXJfdmFsdWUiKTsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdNYXliZUFsaWFzZWQoCisgICAgICAzLCB0aGlzLT5pZGVudGlmaWVyX3ZhbHVlKCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCB1aW50NjQgcG9zaXRpdmVfaW50X3ZhbHVlID0gNDsKKyAgaWYgKGhhc19wb3NpdGl2ZV9pbnRfdmFsdWUoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVVJbnQ2NCg0LCB0aGlzLT5wb3NpdGl2ZV9pbnRfdmFsdWUoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGludDY0IG5lZ2F0aXZlX2ludF92YWx1ZSA9IDU7CisgIGlmIChoYXNfbmVnYXRpdmVfaW50X3ZhbHVlKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVJbnQ2NCg1LCB0aGlzLT5uZWdhdGl2ZV9pbnRfdmFsdWUoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGRvdWJsZSBkb3VibGVfdmFsdWUgPSA2OworICBpZiAoaGFzX2RvdWJsZV92YWx1ZSgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlRG91YmxlKDYsIHRoaXMtPmRvdWJsZV92YWx1ZSgpLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgYnl0ZXMgc3RyaW5nX3ZhbHVlID0gNzsKKyAgaWYgKGhhc19zdHJpbmdfdmFsdWUoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJ5dGVzTWF5YmVBbGlhc2VkKAorICAgICAgNywgdGhpcy0+c3RyaW5nX3ZhbHVlKCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgYWdncmVnYXRlX3ZhbHVlID0gODsKKyAgaWYgKGhhc19hZ2dyZWdhdGVfdmFsdWUoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+YWdncmVnYXRlX3ZhbHVlKCkuZGF0YSgpLCB0aGlzLT5hZ2dyZWdhdGVfdmFsdWUoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5hZ2dyZWdhdGVfdmFsdWUiKTsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdNYXliZUFsaWFzZWQoCisgICAgICA4LCB0aGlzLT5hZ2dyZWdhdGVfdmFsdWUoKSwgb3V0cHV0KTsKKyAgfQorCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25GaWVsZHMoCisgICAgICAgIHVua25vd25fZmllbGRzKCksIG91dHB1dCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9lbmQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24pCit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIFVuaW50ZXJwcmV0ZWRPcHRpb246OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogdGFyZ2V0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24pCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5OYW1lUGFydCBuYW1lID0gMjsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT5uYW1lX3NpemUoKTsgaSA8IG47IGkrKykgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjoKKyAgICAgIFdyaXRlTWVzc2FnZU5vVmlydHVhbFRvQXJyYXkoCisgICAgICAgIDIsIHRoaXMtPm5hbWUoaSksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgaWRlbnRpZmllcl92YWx1ZSA9IDM7CisgIGlmIChoYXNfaWRlbnRpZmllcl92YWx1ZSgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5pZGVudGlmaWVyX3ZhbHVlKCkuZGF0YSgpLCB0aGlzLT5pZGVudGlmaWVyX3ZhbHVlKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uaWRlbnRpZmllcl92YWx1ZSIpOworICAgIHRhcmdldCA9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdUb0FycmF5KAorICAgICAgICAzLCB0aGlzLT5pZGVudGlmaWVyX3ZhbHVlKCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCB1aW50NjQgcG9zaXRpdmVfaW50X3ZhbHVlID0gNDsKKyAgaWYgKGhhc19wb3NpdGl2ZV9pbnRfdmFsdWUoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVVJbnQ2NFRvQXJyYXkoNCwgdGhpcy0+cG9zaXRpdmVfaW50X3ZhbHVlKCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBpbnQ2NCBuZWdhdGl2ZV9pbnRfdmFsdWUgPSA1OworICBpZiAoaGFzX25lZ2F0aXZlX2ludF92YWx1ZSgpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlSW50NjRUb0FycmF5KDUsIHRoaXMtPm5lZ2F0aXZlX2ludF92YWx1ZSgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgZG91YmxlIGRvdWJsZV92YWx1ZSA9IDY7CisgIGlmIChoYXNfZG91YmxlX3ZhbHVlKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVEb3VibGVUb0FycmF5KDYsIHRoaXMtPmRvdWJsZV92YWx1ZSgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgYnl0ZXMgc3RyaW5nX3ZhbHVlID0gNzsKKyAgaWYgKGhhc19zdHJpbmdfdmFsdWUoKSkgeworICAgIHRhcmdldCA9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCeXRlc1RvQXJyYXkoCisgICAgICAgIDcsIHRoaXMtPnN0cmluZ192YWx1ZSgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIGFnZ3JlZ2F0ZV92YWx1ZSA9IDg7CisgIGlmIChoYXNfYWdncmVnYXRlX3ZhbHVlKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgIHRoaXMtPmFnZ3JlZ2F0ZV92YWx1ZSgpLmRhdGEoKSwgdGhpcy0+YWdncmVnYXRlX3ZhbHVlKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uYWdncmVnYXRlX3ZhbHVlIik7CisgICAgdGFyZ2V0ID0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ1RvQXJyYXkoCisgICAgICAgIDgsIHRoaXMtPmFnZ3JlZ2F0ZV92YWx1ZSgpLCB0YXJnZXQpOworICB9CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bkZpZWxkc1RvQXJyYXkoCisgICAgICAgIHVua25vd25fZmllbGRzKCksIHRhcmdldCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9lbmQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24pCisgIHJldHVybiB0YXJnZXQ7Cit9CisKK2ludCBVbmludGVycHJldGVkT3B0aW9uOjpCeXRlU2l6ZSgpIGNvbnN0IHsKKyAgaW50IHRvdGFsX3NpemUgPSAwOworCisgIGlmIChfaGFzX2JpdHNfWzEgLyAzMl0gJiAxMjZ1KSB7CisgICAgLy8gb3B0aW9uYWwgc3RyaW5nIGlkZW50aWZpZXJfdmFsdWUgPSAzOworICAgIGlmIChoYXNfaWRlbnRpZmllcl92YWx1ZSgpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U3RyaW5nU2l6ZSgKKyAgICAgICAgICB0aGlzLT5pZGVudGlmaWVyX3ZhbHVlKCkpOworICAgIH0KKworICAgIC8vIG9wdGlvbmFsIHVpbnQ2NCBwb3NpdGl2ZV9pbnRfdmFsdWUgPSA0OworICAgIGlmIChoYXNfcG9zaXRpdmVfaW50X3ZhbHVlKCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpVSW50NjRTaXplKAorICAgICAgICAgIHRoaXMtPnBvc2l0aXZlX2ludF92YWx1ZSgpKTsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCBpbnQ2NCBuZWdhdGl2ZV9pbnRfdmFsdWUgPSA1OworICAgIGlmIChoYXNfbmVnYXRpdmVfaW50X3ZhbHVlKCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpJbnQ2NFNpemUoCisgICAgICAgICAgdGhpcy0+bmVnYXRpdmVfaW50X3ZhbHVlKCkpOworICAgIH0KKworICAgIC8vIG9wdGlvbmFsIGRvdWJsZSBkb3VibGVfdmFsdWUgPSA2OworICAgIGlmIChoYXNfZG91YmxlX3ZhbHVlKCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArIDg7CisgICAgfQorCisgICAgLy8gb3B0aW9uYWwgYnl0ZXMgc3RyaW5nX3ZhbHVlID0gNzsKKyAgICBpZiAoaGFzX3N0cmluZ192YWx1ZSgpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6Qnl0ZXNTaXplKAorICAgICAgICAgIHRoaXMtPnN0cmluZ192YWx1ZSgpKTsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCBzdHJpbmcgYWdncmVnYXRlX3ZhbHVlID0gODsKKyAgICBpZiAoaGFzX2FnZ3JlZ2F0ZV92YWx1ZSgpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U3RyaW5nU2l6ZSgKKyAgICAgICAgICB0aGlzLT5hZ2dyZWdhdGVfdmFsdWUoKSk7CisgICAgfQorCisgIH0KKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLk5hbWVQYXJ0IG5hbWUgPSAyOworICB0b3RhbF9zaXplICs9IDEgKiB0aGlzLT5uYW1lX3NpemUoKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT5uYW1lX3NpemUoKTsgaSsrKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1lc3NhZ2VTaXplTm9WaXJ0dWFsKAorICAgICAgICB0aGlzLT5uYW1lKGkpKTsKKyAgfQorCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHRvdGFsX3NpemUgKz0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OkNvbXB1dGVVbmtub3duRmllbGRzU2l6ZSgKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSk7CisgIH0KKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHRvdGFsX3NpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworICByZXR1cm4gdG90YWxfc2l6ZTsKK30KKwordm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGNvbnN0IFVuaW50ZXJwcmV0ZWRPcHRpb24qIHNvdXJjZSA9IAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RHluYW1pY0Nhc3RUb0dlbmVyYXRlZDxjb25zdCBVbmludGVycHJldGVkT3B0aW9uPigKKyAgICAgICAgICAmZnJvbSk7CisgIGlmIChzb3VyY2UgPT0gTlVMTCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlJlZmxlY3Rpb25PcHM6Ok1lcmdlKGZyb20sIHRoaXMpOworICB9IGVsc2UgeworICAgIE1lcmdlRnJvbSgqc291cmNlKTsKKyAgfQorfQorCit2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246Ok1lcmdlRnJvbShjb25zdCBVbmludGVycHJldGVkT3B0aW9uJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIG5hbWVfLk1lcmdlRnJvbShmcm9tLm5hbWVfKTsKKyAgaWYgKGZyb20uX2hhc19iaXRzX1sxIC8gMzJdICYgKDB4ZmZ1IDw8ICgxICUgMzIpKSkgeworICAgIGlmIChmcm9tLmhhc19pZGVudGlmaWVyX3ZhbHVlKCkpIHsKKyAgICAgIHNldF9oYXNfaWRlbnRpZmllcl92YWx1ZSgpOworICAgICAgaWRlbnRpZmllcl92YWx1ZV8uQXNzaWduV2l0aERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBmcm9tLmlkZW50aWZpZXJfdmFsdWVfKTsKKyAgICB9CisgICAgaWYgKGZyb20uaGFzX3Bvc2l0aXZlX2ludF92YWx1ZSgpKSB7CisgICAgICBzZXRfcG9zaXRpdmVfaW50X3ZhbHVlKGZyb20ucG9zaXRpdmVfaW50X3ZhbHVlKCkpOworICAgIH0KKyAgICBpZiAoZnJvbS5oYXNfbmVnYXRpdmVfaW50X3ZhbHVlKCkpIHsKKyAgICAgIHNldF9uZWdhdGl2ZV9pbnRfdmFsdWUoZnJvbS5uZWdhdGl2ZV9pbnRfdmFsdWUoKSk7CisgICAgfQorICAgIGlmIChmcm9tLmhhc19kb3VibGVfdmFsdWUoKSkgeworICAgICAgc2V0X2RvdWJsZV92YWx1ZShmcm9tLmRvdWJsZV92YWx1ZSgpKTsKKyAgICB9CisgICAgaWYgKGZyb20uaGFzX3N0cmluZ192YWx1ZSgpKSB7CisgICAgICBzZXRfaGFzX3N0cmluZ192YWx1ZSgpOworICAgICAgc3RyaW5nX3ZhbHVlXy5Bc3NpZ25XaXRoRGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGZyb20uc3RyaW5nX3ZhbHVlXyk7CisgICAgfQorICAgIGlmIChmcm9tLmhhc19hZ2dyZWdhdGVfdmFsdWUoKSkgeworICAgICAgc2V0X2hhc19hZ2dyZWdhdGVfdmFsdWUoKTsKKyAgICAgIGFnZ3JlZ2F0ZV92YWx1ZV8uQXNzaWduV2l0aERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBmcm9tLmFnZ3JlZ2F0ZV92YWx1ZV8pOworICAgIH0KKyAgfQorICBpZiAoZnJvbS5faW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+TWVyZ2VGcm9tKGZyb20udW5rbm93bl9maWVsZHMoKSk7CisgIH0KK30KKwordm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCit2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OkNvcHlGcm9tKGNvbnN0IFVuaW50ZXJwcmV0ZWRPcHRpb24mIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCitib29sIFVuaW50ZXJwcmV0ZWRPcHRpb246OklzSW5pdGlhbGl6ZWQoKSBjb25zdCB7CisKKyAgaWYgKCE6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBbGxBcmVJbml0aWFsaXplZCh0aGlzLT5uYW1lKCkpKSByZXR1cm4gZmFsc2U7CisgIHJldHVybiB0cnVlOworfQorCit2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OlN3YXAoVW5pbnRlcnByZXRlZE9wdGlvbiogb3RoZXIpIHsKKyAgaWYgKG90aGVyID09IHRoaXMpIHJldHVybjsKKyAgSW50ZXJuYWxTd2FwKG90aGVyKTsKK30KK3ZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6SW50ZXJuYWxTd2FwKFVuaW50ZXJwcmV0ZWRPcHRpb24qIG90aGVyKSB7CisgIG5hbWVfLlVuc2FmZUFyZW5hU3dhcCgmb3RoZXItPm5hbWVfKTsKKyAgaWRlbnRpZmllcl92YWx1ZV8uU3dhcCgmb3RoZXItPmlkZW50aWZpZXJfdmFsdWVfKTsKKyAgc3RkOjpzd2FwKHBvc2l0aXZlX2ludF92YWx1ZV8sIG90aGVyLT5wb3NpdGl2ZV9pbnRfdmFsdWVfKTsKKyAgc3RkOjpzd2FwKG5lZ2F0aXZlX2ludF92YWx1ZV8sIG90aGVyLT5uZWdhdGl2ZV9pbnRfdmFsdWVfKTsKKyAgc3RkOjpzd2FwKGRvdWJsZV92YWx1ZV8sIG90aGVyLT5kb3VibGVfdmFsdWVfKTsKKyAgc3RyaW5nX3ZhbHVlXy5Td2FwKCZvdGhlci0+c3RyaW5nX3ZhbHVlXyk7CisgIGFnZ3JlZ2F0ZV92YWx1ZV8uU3dhcCgmb3RoZXItPmFnZ3JlZ2F0ZV92YWx1ZV8pOworICBzdGQ6OnN3YXAoX2hhc19iaXRzX1swXSwgb3RoZXItPl9oYXNfYml0c19bMF0pOworICBfaW50ZXJuYWxfbWV0YWRhdGFfLlN3YXAoJm90aGVyLT5faW50ZXJuYWxfbWV0YWRhdGFfKTsKKyAgc3RkOjpzd2FwKF9jYWNoZWRfc2l6ZV8sIG90aGVyLT5fY2FjaGVkX3NpemVfKTsKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBVbmludGVycHJldGVkT3B0aW9uOjpHZXRNZXRhZGF0YSgpIGNvbnN0IHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgbWV0YWRhdGE7CisgIG1ldGFkYXRhLmRlc2NyaXB0b3IgPSBVbmludGVycHJldGVkT3B0aW9uX2Rlc2NyaXB0b3JfOworICBtZXRhZGF0YS5yZWZsZWN0aW9uID0gVW5pbnRlcnByZXRlZE9wdGlvbl9yZWZsZWN0aW9uXzsKKyAgcmV0dXJuIG1ldGFkYXRhOworfQorCisjaWYgUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisvLyBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0CisKKy8vIHJlcXVpcmVkIHN0cmluZyBuYW1lX3BhcnQgPSAxOworYm9vbCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpoYXNfbmFtZV9wYXJ0KCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAxdSkgIT0gMDsKK30KK3ZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6c2V0X2hhc19uYW1lX3BhcnQoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMXU7Cit9Cit2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQ6OmNsZWFyX2hhc19uYW1lX3BhcnQoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDF1OworfQordm9pZCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpjbGVhcl9uYW1lX3BhcnQoKSB7CisgIG5hbWVfcGFydF8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfbmFtZV9wYXJ0KCk7Cit9CisgY29uc3QgOjpzdGQ6OnN0cmluZyYgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6bmFtZV9wYXJ0KCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLk5hbWVQYXJ0Lm5hbWVfcGFydCkKKyAgcmV0dXJuIG5hbWVfcGFydF8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6c2V0X25hbWVfcGFydChjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBzZXRfaGFzX25hbWVfcGFydCgpOworICBuYW1lX3BhcnRfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uTmFtZVBhcnQubmFtZV9wYXJ0KQorfQorIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6c2V0X25hbWVfcGFydChjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX25hbWVfcGFydCgpOworICBuYW1lX3BhcnRfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5OYW1lUGFydC5uYW1lX3BhcnQpCit9Cisgdm9pZCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpzZXRfbmFtZV9wYXJ0KGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX25hbWVfcGFydCgpOworICBuYW1lX3BhcnRfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLk5hbWVQYXJ0Lm5hbWVfcGFydCkKK30KKyA6OnN0ZDo6c3RyaW5nKiBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjptdXRhYmxlX25hbWVfcGFydCgpIHsKKyAgc2V0X2hhc19uYW1lX3BhcnQoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uTmFtZVBhcnQubmFtZV9wYXJ0KQorICByZXR1cm4gbmFtZV9wYXJ0Xy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIDo6c3RkOjpzdHJpbmcqIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQ6OnJlbGVhc2VfbmFtZV9wYXJ0KCkgeworICBjbGVhcl9oYXNfbmFtZV9wYXJ0KCk7CisgIHJldHVybiBuYW1lX3BhcnRfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpzZXRfYWxsb2NhdGVkX25hbWVfcGFydCg6OnN0ZDo6c3RyaW5nKiBuYW1lX3BhcnQpIHsKKyAgaWYgKG5hbWVfcGFydCAhPSBOVUxMKSB7CisgICAgc2V0X2hhc19uYW1lX3BhcnQoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfbmFtZV9wYXJ0KCk7CisgIH0KKyAgbmFtZV9wYXJ0Xy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgbmFtZV9wYXJ0KTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uTmFtZVBhcnQubmFtZV9wYXJ0KQorfQorCisvLyByZXF1aXJlZCBib29sIGlzX2V4dGVuc2lvbiA9IDI7Citib29sIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQ6Omhhc19pc19leHRlbnNpb24oKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDJ1KSAhPSAwOworfQordm9pZCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpzZXRfaGFzX2lzX2V4dGVuc2lvbigpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAydTsKK30KK3ZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6Y2xlYXJfaGFzX2lzX2V4dGVuc2lvbigpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMnU7Cit9Cit2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQ6OmNsZWFyX2lzX2V4dGVuc2lvbigpIHsKKyAgaXNfZXh0ZW5zaW9uXyA9IGZhbHNlOworICBjbGVhcl9oYXNfaXNfZXh0ZW5zaW9uKCk7Cit9CisgYm9vbCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0Ojppc19leHRlbnNpb24oKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uTmFtZVBhcnQuaXNfZXh0ZW5zaW9uKQorICByZXR1cm4gaXNfZXh0ZW5zaW9uXzsKK30KKyB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQ6OnNldF9pc19leHRlbnNpb24oYm9vbCB2YWx1ZSkgeworICBzZXRfaGFzX2lzX2V4dGVuc2lvbigpOworICBpc19leHRlbnNpb25fID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uTmFtZVBhcnQuaXNfZXh0ZW5zaW9uKQorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIFVuaW50ZXJwcmV0ZWRPcHRpb24KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLk5hbWVQYXJ0IG5hbWUgPSAyOworaW50IFVuaW50ZXJwcmV0ZWRPcHRpb246Om5hbWVfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIG5hbWVfLnNpemUoKTsKK30KK3ZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6Y2xlYXJfbmFtZSgpIHsKKyAgbmFtZV8uQ2xlYXIoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydCYgVW5pbnRlcnByZXRlZE9wdGlvbjo6bmFtZShpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5uYW1lKQorICByZXR1cm4gbmFtZV8uR2V0KGluZGV4KTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydCogVW5pbnRlcnByZXRlZE9wdGlvbjo6bXV0YWJsZV9uYW1lKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5uYW1lKQorICByZXR1cm4gbmFtZV8uTXV0YWJsZShpbmRleCk7Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQqIFVuaW50ZXJwcmV0ZWRPcHRpb246OmFkZF9uYW1lKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLm5hbWUpCisgIHJldHVybiBuYW1lXy5BZGQoKTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0ID4qCitVbmludGVycHJldGVkT3B0aW9uOjptdXRhYmxlX25hbWUoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24ubmFtZSkKKyAgcmV0dXJuICZuYW1lXzsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0ID4mCitVbmludGVycHJldGVkT3B0aW9uOjpuYW1lKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5uYW1lKQorICByZXR1cm4gbmFtZV87Cit9CisKKy8vIG9wdGlvbmFsIHN0cmluZyBpZGVudGlmaWVyX3ZhbHVlID0gMzsKK2Jvb2wgVW5pbnRlcnByZXRlZE9wdGlvbjo6aGFzX2lkZW50aWZpZXJfdmFsdWUoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDJ1KSAhPSAwOworfQordm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpzZXRfaGFzX2lkZW50aWZpZXJfdmFsdWUoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMnU7Cit9Cit2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OmNsZWFyX2hhc19pZGVudGlmaWVyX3ZhbHVlKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAydTsKK30KK3ZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6Y2xlYXJfaWRlbnRpZmllcl92YWx1ZSgpIHsKKyAgaWRlbnRpZmllcl92YWx1ZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfaWRlbnRpZmllcl92YWx1ZSgpOworfQorIGNvbnN0IDo6c3RkOjpzdHJpbmcmIFVuaW50ZXJwcmV0ZWRPcHRpb246OmlkZW50aWZpZXJfdmFsdWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uaWRlbnRpZmllcl92YWx1ZSkKKyAgcmV0dXJuIGlkZW50aWZpZXJfdmFsdWVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OnNldF9pZGVudGlmaWVyX3ZhbHVlKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfaWRlbnRpZmllcl92YWx1ZSgpOworICBpZGVudGlmaWVyX3ZhbHVlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLmlkZW50aWZpZXJfdmFsdWUpCit9Cisgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpzZXRfaWRlbnRpZmllcl92YWx1ZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX2lkZW50aWZpZXJfdmFsdWUoKTsKKyAgaWRlbnRpZmllcl92YWx1ZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLmlkZW50aWZpZXJfdmFsdWUpCit9Cisgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpzZXRfaWRlbnRpZmllcl92YWx1ZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19pZGVudGlmaWVyX3ZhbHVlKCk7CisgIGlkZW50aWZpZXJfdmFsdWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLmlkZW50aWZpZXJfdmFsdWUpCit9CisgOjpzdGQ6OnN0cmluZyogVW5pbnRlcnByZXRlZE9wdGlvbjo6bXV0YWJsZV9pZGVudGlmaWVyX3ZhbHVlKCkgeworICBzZXRfaGFzX2lkZW50aWZpZXJfdmFsdWUoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uaWRlbnRpZmllcl92YWx1ZSkKKyAgcmV0dXJuIGlkZW50aWZpZXJfdmFsdWVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CisgOjpzdGQ6OnN0cmluZyogVW5pbnRlcnByZXRlZE9wdGlvbjo6cmVsZWFzZV9pZGVudGlmaWVyX3ZhbHVlKCkgeworICBjbGVhcl9oYXNfaWRlbnRpZmllcl92YWx1ZSgpOworICByZXR1cm4gaWRlbnRpZmllcl92YWx1ZV8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OnNldF9hbGxvY2F0ZWRfaWRlbnRpZmllcl92YWx1ZSg6OnN0ZDo6c3RyaW5nKiBpZGVudGlmaWVyX3ZhbHVlKSB7CisgIGlmIChpZGVudGlmaWVyX3ZhbHVlICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX2lkZW50aWZpZXJfdmFsdWUoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfaWRlbnRpZmllcl92YWx1ZSgpOworICB9CisgIGlkZW50aWZpZXJfdmFsdWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBpZGVudGlmaWVyX3ZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uaWRlbnRpZmllcl92YWx1ZSkKK30KKworLy8gb3B0aW9uYWwgdWludDY0IHBvc2l0aXZlX2ludF92YWx1ZSA9IDQ7Citib29sIFVuaW50ZXJwcmV0ZWRPcHRpb246Omhhc19wb3NpdGl2ZV9pbnRfdmFsdWUoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDR1KSAhPSAwOworfQordm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpzZXRfaGFzX3Bvc2l0aXZlX2ludF92YWx1ZSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDA0dTsKK30KK3ZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6Y2xlYXJfaGFzX3Bvc2l0aXZlX2ludF92YWx1ZSgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwNHU7Cit9Cit2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OmNsZWFyX3Bvc2l0aXZlX2ludF92YWx1ZSgpIHsKKyAgcG9zaXRpdmVfaW50X3ZhbHVlXyA9IEdPT0dMRV9VTE9OR0xPTkcoMCk7CisgIGNsZWFyX2hhc19wb3NpdGl2ZV9pbnRfdmFsdWUoKTsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ2NCBVbmludGVycHJldGVkT3B0aW9uOjpwb3NpdGl2ZV9pbnRfdmFsdWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24ucG9zaXRpdmVfaW50X3ZhbHVlKQorICByZXR1cm4gcG9zaXRpdmVfaW50X3ZhbHVlXzsKK30KKyB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OnNldF9wb3NpdGl2ZV9pbnRfdmFsdWUoOjpnb29nbGU6OnByb3RvYnVmOjp1aW50NjQgdmFsdWUpIHsKKyAgc2V0X2hhc19wb3NpdGl2ZV9pbnRfdmFsdWUoKTsKKyAgcG9zaXRpdmVfaW50X3ZhbHVlXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLnBvc2l0aXZlX2ludF92YWx1ZSkKK30KKworLy8gb3B0aW9uYWwgaW50NjQgbmVnYXRpdmVfaW50X3ZhbHVlID0gNTsKK2Jvb2wgVW5pbnRlcnByZXRlZE9wdGlvbjo6aGFzX25lZ2F0aXZlX2ludF92YWx1ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwOHUpICE9IDA7Cit9Cit2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OnNldF9oYXNfbmVnYXRpdmVfaW50X3ZhbHVlKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDh1OworfQordm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpjbGVhcl9oYXNfbmVnYXRpdmVfaW50X3ZhbHVlKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDA4dTsKK30KK3ZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6Y2xlYXJfbmVnYXRpdmVfaW50X3ZhbHVlKCkgeworICBuZWdhdGl2ZV9pbnRfdmFsdWVfID0gR09PR0xFX0xPTkdMT05HKDApOworICBjbGVhcl9oYXNfbmVnYXRpdmVfaW50X3ZhbHVlKCk7Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjppbnQ2NCBVbmludGVycHJldGVkT3B0aW9uOjpuZWdhdGl2ZV9pbnRfdmFsdWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24ubmVnYXRpdmVfaW50X3ZhbHVlKQorICByZXR1cm4gbmVnYXRpdmVfaW50X3ZhbHVlXzsKK30KKyB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OnNldF9uZWdhdGl2ZV9pbnRfdmFsdWUoOjpnb29nbGU6OnByb3RvYnVmOjppbnQ2NCB2YWx1ZSkgeworICBzZXRfaGFzX25lZ2F0aXZlX2ludF92YWx1ZSgpOworICBuZWdhdGl2ZV9pbnRfdmFsdWVfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24ubmVnYXRpdmVfaW50X3ZhbHVlKQorfQorCisvLyBvcHRpb25hbCBkb3VibGUgZG91YmxlX3ZhbHVlID0gNjsKK2Jvb2wgVW5pbnRlcnByZXRlZE9wdGlvbjo6aGFzX2RvdWJsZV92YWx1ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAxMHUpICE9IDA7Cit9Cit2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OnNldF9oYXNfZG91YmxlX3ZhbHVlKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMTB1OworfQordm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpjbGVhcl9oYXNfZG91YmxlX3ZhbHVlKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDEwdTsKK30KK3ZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6Y2xlYXJfZG91YmxlX3ZhbHVlKCkgeworICBkb3VibGVfdmFsdWVfID0gMDsKKyAgY2xlYXJfaGFzX2RvdWJsZV92YWx1ZSgpOworfQorIGRvdWJsZSBVbmludGVycHJldGVkT3B0aW9uOjpkb3VibGVfdmFsdWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uZG91YmxlX3ZhbHVlKQorICByZXR1cm4gZG91YmxlX3ZhbHVlXzsKK30KKyB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OnNldF9kb3VibGVfdmFsdWUoZG91YmxlIHZhbHVlKSB7CisgIHNldF9oYXNfZG91YmxlX3ZhbHVlKCk7CisgIGRvdWJsZV92YWx1ZV8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5kb3VibGVfdmFsdWUpCit9CisKKy8vIG9wdGlvbmFsIGJ5dGVzIHN0cmluZ192YWx1ZSA9IDc7Citib29sIFVuaW50ZXJwcmV0ZWRPcHRpb246Omhhc19zdHJpbmdfdmFsdWUoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMjB1KSAhPSAwOworfQordm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpzZXRfaGFzX3N0cmluZ192YWx1ZSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDIwdTsKK30KK3ZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6Y2xlYXJfaGFzX3N0cmluZ192YWx1ZSgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAyMHU7Cit9Cit2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OmNsZWFyX3N0cmluZ192YWx1ZSgpIHsKKyAgc3RyaW5nX3ZhbHVlXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGNsZWFyX2hhc19zdHJpbmdfdmFsdWUoKTsKK30KKyBjb25zdCA6OnN0ZDo6c3RyaW5nJiBVbmludGVycHJldGVkT3B0aW9uOjpzdHJpbmdfdmFsdWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uc3RyaW5nX3ZhbHVlKQorICByZXR1cm4gc3RyaW5nX3ZhbHVlXy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpzZXRfc3RyaW5nX3ZhbHVlKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfc3RyaW5nX3ZhbHVlKCk7CisgIHN0cmluZ192YWx1ZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5zdHJpbmdfdmFsdWUpCit9Cisgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpzZXRfc3RyaW5nX3ZhbHVlKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfc3RyaW5nX3ZhbHVlKCk7CisgIHN0cmluZ192YWx1ZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLnN0cmluZ192YWx1ZSkKK30KKyB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OnNldF9zdHJpbmdfdmFsdWUoY29uc3Qgdm9pZCogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHNldF9oYXNfc3RyaW5nX3ZhbHVlKCk7CisgIHN0cmluZ192YWx1ZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uc3RyaW5nX3ZhbHVlKQorfQorIDo6c3RkOjpzdHJpbmcqIFVuaW50ZXJwcmV0ZWRPcHRpb246Om11dGFibGVfc3RyaW5nX3ZhbHVlKCkgeworICBzZXRfaGFzX3N0cmluZ192YWx1ZSgpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5zdHJpbmdfdmFsdWUpCisgIHJldHVybiBzdHJpbmdfdmFsdWVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CisgOjpzdGQ6OnN0cmluZyogVW5pbnRlcnByZXRlZE9wdGlvbjo6cmVsZWFzZV9zdHJpbmdfdmFsdWUoKSB7CisgIGNsZWFyX2hhc19zdHJpbmdfdmFsdWUoKTsKKyAgcmV0dXJuIHN0cmluZ192YWx1ZV8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OnNldF9hbGxvY2F0ZWRfc3RyaW5nX3ZhbHVlKDo6c3RkOjpzdHJpbmcqIHN0cmluZ192YWx1ZSkgeworICBpZiAoc3RyaW5nX3ZhbHVlICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX3N0cmluZ192YWx1ZSgpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19zdHJpbmdfdmFsdWUoKTsKKyAgfQorICBzdHJpbmdfdmFsdWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBzdHJpbmdfdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5zdHJpbmdfdmFsdWUpCit9CisKKy8vIG9wdGlvbmFsIHN0cmluZyBhZ2dyZWdhdGVfdmFsdWUgPSA4OworYm9vbCBVbmludGVycHJldGVkT3B0aW9uOjpoYXNfYWdncmVnYXRlX3ZhbHVlKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDQwdSkgIT0gMDsKK30KK3ZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6c2V0X2hhc19hZ2dyZWdhdGVfdmFsdWUoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDA0MHU7Cit9Cit2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OmNsZWFyX2hhc19hZ2dyZWdhdGVfdmFsdWUoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwNDB1OworfQordm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpjbGVhcl9hZ2dyZWdhdGVfdmFsdWUoKSB7CisgIGFnZ3JlZ2F0ZV92YWx1ZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfYWdncmVnYXRlX3ZhbHVlKCk7Cit9CisgY29uc3QgOjpzdGQ6OnN0cmluZyYgVW5pbnRlcnByZXRlZE9wdGlvbjo6YWdncmVnYXRlX3ZhbHVlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLmFnZ3JlZ2F0ZV92YWx1ZSkKKyAgcmV0dXJuIGFnZ3JlZ2F0ZV92YWx1ZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6c2V0X2FnZ3JlZ2F0ZV92YWx1ZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBzZXRfaGFzX2FnZ3JlZ2F0ZV92YWx1ZSgpOworICBhZ2dyZWdhdGVfdmFsdWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uYWdncmVnYXRlX3ZhbHVlKQorfQorIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6c2V0X2FnZ3JlZ2F0ZV92YWx1ZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX2FnZ3JlZ2F0ZV92YWx1ZSgpOworICBhZ2dyZWdhdGVfdmFsdWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5hZ2dyZWdhdGVfdmFsdWUpCit9Cisgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpzZXRfYWdncmVnYXRlX3ZhbHVlKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX2FnZ3JlZ2F0ZV92YWx1ZSgpOworICBhZ2dyZWdhdGVfdmFsdWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLmFnZ3JlZ2F0ZV92YWx1ZSkKK30KKyA6OnN0ZDo6c3RyaW5nKiBVbmludGVycHJldGVkT3B0aW9uOjptdXRhYmxlX2FnZ3JlZ2F0ZV92YWx1ZSgpIHsKKyAgc2V0X2hhc19hZ2dyZWdhdGVfdmFsdWUoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uYWdncmVnYXRlX3ZhbHVlKQorICByZXR1cm4gYWdncmVnYXRlX3ZhbHVlXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIDo6c3RkOjpzdHJpbmcqIFVuaW50ZXJwcmV0ZWRPcHRpb246OnJlbGVhc2VfYWdncmVnYXRlX3ZhbHVlKCkgeworICBjbGVhcl9oYXNfYWdncmVnYXRlX3ZhbHVlKCk7CisgIHJldHVybiBhZ2dyZWdhdGVfdmFsdWVfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpzZXRfYWxsb2NhdGVkX2FnZ3JlZ2F0ZV92YWx1ZSg6OnN0ZDo6c3RyaW5nKiBhZ2dyZWdhdGVfdmFsdWUpIHsKKyAgaWYgKGFnZ3JlZ2F0ZV92YWx1ZSAhPSBOVUxMKSB7CisgICAgc2V0X2hhc19hZ2dyZWdhdGVfdmFsdWUoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfYWdncmVnYXRlX3ZhbHVlKCk7CisgIH0KKyAgYWdncmVnYXRlX3ZhbHVlXy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgYWdncmVnYXRlX3ZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uYWdncmVnYXRlX3ZhbHVlKQorfQorCisjZW5kaWYgIC8vIFBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKyNpZiAhZGVmaW5lZChfTVNDX1ZFUikgfHwgX01TQ19WRVIgPj0gMTkwMAorY29uc3QgaW50IFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjprUGF0aEZpZWxkTnVtYmVyOworY29uc3QgaW50IFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjprU3BhbkZpZWxkTnVtYmVyOworY29uc3QgaW50IFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjprTGVhZGluZ0NvbW1lbnRzRmllbGROdW1iZXI7Citjb25zdCBpbnQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OmtUcmFpbGluZ0NvbW1lbnRzRmllbGROdW1iZXI7Citjb25zdCBpbnQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OmtMZWFkaW5nRGV0YWNoZWRDb21tZW50c0ZpZWxkTnVtYmVyOworI2VuZGlmICAvLyAhZGVmaW5lZChfTVNDX1ZFUikgfHwgX01TQ19WRVIgPj0gMTkwMAorCitTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6U291cmNlQ29kZUluZm9fTG9jYXRpb24oKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpLCBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uKQorfQorCit2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpJbml0QXNEZWZhdWx0SW5zdGFuY2UoKSB7Cit9CisKK1NvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbihjb25zdCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbiYgZnJvbSkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwKKyAgICBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICBNZXJnZUZyb20oZnJvbSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb3B5X2NvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbikKK30KKwordm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6U2hhcmVkQ3RvcigpIHsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmcoKTsKKyAgX2NhY2hlZF9zaXplXyA9IDA7CisgIGxlYWRpbmdfY29tbWVudHNfLlVuc2FmZVNldERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgdHJhaWxpbmdfY29tbWVudHNfLlVuc2FmZVNldERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgOjptZW1zZXQoX2hhc19iaXRzXywgMCwgc2l6ZW9mKF9oYXNfYml0c18pKTsKK30KKworU291cmNlQ29kZUluZm9fTG9jYXRpb246On5Tb3VyY2VDb2RlSW5mb19Mb2NhdGlvbigpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGRlc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uKQorICBTaGFyZWREdG9yKCk7Cit9CisKK3ZvaWQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OlNoYXJlZER0b3IoKSB7CisgIGxlYWRpbmdfY29tbWVudHNfLkRlc3Ryb3lOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIHRyYWlsaW5nX2NvbW1lbnRzXy5EZXN0cm95Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBpZiAodGhpcyAhPSBkZWZhdWx0X2luc3RhbmNlXykgeworICB9Cit9CisKK3ZvaWQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OlNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0IHsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHNpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6ZGVzY3JpcHRvcigpIHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIHJldHVybiBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbl9kZXNjcmlwdG9yXzsKK30KKworY29uc3QgU291cmNlQ29kZUluZm9fTG9jYXRpb24mIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpkZWZhdWx0X2luc3RhbmNlKCkgeworICBpZiAoZGVmYXVsdF9pbnN0YW5jZV8gPT0gTlVMTCkgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICByZXR1cm4gKmRlZmF1bHRfaW5zdGFuY2VfOworfQorCitTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbiogU291cmNlQ29kZUluZm9fTG9jYXRpb246OmRlZmF1bHRfaW5zdGFuY2VfID0gTlVMTDsKKworU291cmNlQ29kZUluZm9fTG9jYXRpb24qIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0IHsKKyAgU291cmNlQ29kZUluZm9fTG9jYXRpb24qIG4gPSBuZXcgU291cmNlQ29kZUluZm9fTG9jYXRpb247CisgIGlmIChhcmVuYSAhPSBOVUxMKSB7CisgICAgYXJlbmEtPk93bihuKTsKKyAgfQorICByZXR1cm4gbjsKK30KKwordm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6Q2xlYXIoKSB7CisgIGlmIChfaGFzX2JpdHNfWzAgLyAzMl0gJiAxMnUpIHsKKyAgICBpZiAoaGFzX2xlYWRpbmdfY29tbWVudHMoKSkgeworICAgICAgbGVhZGluZ19jb21tZW50c18uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICAgIH0KKyAgICBpZiAoaGFzX3RyYWlsaW5nX2NvbW1lbnRzKCkpIHsKKyAgICAgIHRyYWlsaW5nX2NvbW1lbnRzXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgICAgfQorICB9CisgIHBhdGhfLkNsZWFyKCk7CisgIHNwYW5fLkNsZWFyKCk7CisgIGxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHNfLkNsZWFyKCk7CisgIDo6bWVtc2V0KF9oYXNfYml0c18sIDAsIHNpemVvZihfaGFzX2JpdHNfKSk7CisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+Q2xlYXIoKTsKKyAgfQorfQorCitib29sIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyNkZWZpbmUgRE9fKEVYUFJFU1NJT04pIGlmICghKEVYUFJFU1NJT04pKSBnb3RvIGZhaWx1cmUKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgdGFnOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uKQorICBmb3IgKDs7KSB7CisgICAgOjpzdGQ6OnBhaXI8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyLCBib29sPiBwID0gaW5wdXQtPlJlYWRUYWdXaXRoQ3V0b2ZmKDEyNyk7CisgICAgdGFnID0gcC5maXJzdDsKKyAgICBpZiAoIXAuc2Vjb25kKSBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgIHN3aXRjaCAoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ0ZpZWxkTnVtYmVyKHRhZykpIHsKKyAgICAgIC8vIHJlcGVhdGVkIGludDMyIHBhdGggPSAxIFtwYWNrZWQgPSB0cnVlXTsKKyAgICAgIGNhc2UgMTogeworICAgICAgICBpZiAodGFnID09IDEwKSB7CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFBhY2tlZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyLCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9JTlQzMj4oCisgICAgICAgICAgICAgICAgIGlucHV0LCB0aGlzLT5tdXRhYmxlX3BhdGgoKSkpKTsKKyAgICAgICAgfSBlbHNlIGlmICh0YWcgPT0gOCkgeworICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRSZXBlYXRlZFByaW1pdGl2ZU5vSW5saW5lPAorICAgICAgICAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0lOVDMyPigKKyAgICAgICAgICAgICAgICAgMSwgMTAsIGlucHV0LCB0aGlzLT5tdXRhYmxlX3BhdGgoKSkpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDE4KSkgZ290byBwYXJzZV9zcGFuOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gcmVwZWF0ZWQgaW50MzIgc3BhbiA9IDIgW3BhY2tlZCA9IHRydWVdOworICAgICAgY2FzZSAyOiB7CisgICAgICAgIGlmICh0YWcgPT0gMTgpIHsKKyAgICAgICAgIHBhcnNlX3NwYW46CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFBhY2tlZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyLCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9JTlQzMj4oCisgICAgICAgICAgICAgICAgIGlucHV0LCB0aGlzLT5tdXRhYmxlX3NwYW4oKSkpKTsKKyAgICAgICAgfSBlbHNlIGlmICh0YWcgPT0gMTYpIHsKKyAgICAgICAgICBET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUmVwZWF0ZWRQcmltaXRpdmVOb0lubGluZTwKKyAgICAgICAgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyLCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9JTlQzMj4oCisgICAgICAgICAgICAgICAgIDEsIDE4LCBpbnB1dCwgdGhpcy0+bXV0YWJsZV9zcGFuKCkpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygyNikpIGdvdG8gcGFyc2VfbGVhZGluZ19jb21tZW50czsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIHN0cmluZyBsZWFkaW5nX2NvbW1lbnRzID0gMzsKKyAgICAgIGNhc2UgMzogeworICAgICAgICBpZiAodGFnID09IDI2KSB7CisgICAgICAgICBwYXJzZV9sZWFkaW5nX2NvbW1lbnRzOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFN0cmluZygKKyAgICAgICAgICAgICAgICBpbnB1dCwgdGhpcy0+bXV0YWJsZV9sZWFkaW5nX2NvbW1lbnRzKCkpKTsKKyAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgICAgICAgIHRoaXMtPmxlYWRpbmdfY29tbWVudHMoKS5kYXRhKCksIHRoaXMtPmxlYWRpbmdfY29tbWVudHMoKS5sZW5ndGgoKSwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlBBUlNFLAorICAgICAgICAgICAgImdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5sZWFkaW5nX2NvbW1lbnRzIik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygzNCkpIGdvdG8gcGFyc2VfdHJhaWxpbmdfY29tbWVudHM7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCBzdHJpbmcgdHJhaWxpbmdfY29tbWVudHMgPSA0OworICAgICAgY2FzZSA0OiB7CisgICAgICAgIGlmICh0YWcgPT0gMzQpIHsKKyAgICAgICAgIHBhcnNlX3RyYWlsaW5nX2NvbW1lbnRzOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFN0cmluZygKKyAgICAgICAgICAgICAgICBpbnB1dCwgdGhpcy0+bXV0YWJsZV90cmFpbGluZ19jb21tZW50cygpKSk7CisgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICAgICAgICB0aGlzLT50cmFpbGluZ19jb21tZW50cygpLmRhdGEoKSwgdGhpcy0+dHJhaWxpbmdfY29tbWVudHMoKS5sZW5ndGgoKSwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlBBUlNFLAorICAgICAgICAgICAgImdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi50cmFpbGluZ19jb21tZW50cyIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNTApKSBnb3RvIHBhcnNlX2xlYWRpbmdfZGV0YWNoZWRfY29tbWVudHM7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyByZXBlYXRlZCBzdHJpbmcgbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyA9IDY7CisgICAgICBjYXNlIDY6IHsKKyAgICAgICAgaWYgKHRhZyA9PSA1MCkgeworICAgICAgICAgcGFyc2VfbGVhZGluZ19kZXRhY2hlZF9jb21tZW50czoKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoCisgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPmFkZF9sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKCkpKTsKKyAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgICAgICAgIHRoaXMtPmxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHModGhpcy0+bGVhZGluZ19kZXRhY2hlZF9jb21tZW50c19zaXplKCkgLSAxKS5kYXRhKCksCisgICAgICAgICAgICB0aGlzLT5sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKHRoaXMtPmxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHNfc2l6ZSgpIC0gMSkubGVuZ3RoKCksCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpQQVJTRSwKKyAgICAgICAgICAgICJnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ubGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNTApKSBnb3RvIHBhcnNlX2xlYWRpbmdfZGV0YWNoZWRfY29tbWVudHM7CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0QXRFbmQoKSkgZ290byBzdWNjZXNzOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgZGVmYXVsdDogeworICAgICAgaGFuZGxlX3VudXN1YWw6CisgICAgICAgIGlmICh0YWcgPT0gMCB8fAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ1dpcmVUeXBlKHRhZykgPT0KKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVApIHsKKyAgICAgICAgICBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIH0KKyAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNraXBGaWVsZCgKKyAgICAgICAgICAgICAgaW5wdXQsIHRhZywgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpKSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgfQorc3VjY2VzczoKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N1Y2Nlc3M6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uKQorICByZXR1cm4gdHJ1ZTsKK2ZhaWx1cmU6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9mYWlsdXJlOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbikKKyAgcmV0dXJuIGZhbHNlOworI3VuZGVmIERPXworfQorCit2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbikKKyAgLy8gcmVwZWF0ZWQgaW50MzIgcGF0aCA9IDEgW3BhY2tlZCA9IHRydWVdOworICBpZiAodGhpcy0+cGF0aF9zaXplKCkgPiAwKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlVGFnKDEsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVELCBvdXRwdXQpOworICAgIG91dHB1dC0+V3JpdGVWYXJpbnQzMihfcGF0aF9jYWNoZWRfYnl0ZV9zaXplXyk7CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT5wYXRoX3NpemUoKTsgaSsrKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlSW50MzJOb1RhZygKKyAgICAgIHRoaXMtPnBhdGgoaSksIG91dHB1dCk7CisgIH0KKworICAvLyByZXBlYXRlZCBpbnQzMiBzcGFuID0gMiBbcGFja2VkID0gdHJ1ZV07CisgIGlmICh0aGlzLT5zcGFuX3NpemUoKSA+IDApIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVUYWcoMiwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQsIG91dHB1dCk7CisgICAgb3V0cHV0LT5Xcml0ZVZhcmludDMyKF9zcGFuX2NhY2hlZF9ieXRlX3NpemVfKTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPnNwYW5fc2l6ZSgpOyBpKyspIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVJbnQzMk5vVGFnKAorICAgICAgdGhpcy0+c3BhbihpKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIHN0cmluZyBsZWFkaW5nX2NvbW1lbnRzID0gMzsKKyAgaWYgKGhhc19sZWFkaW5nX2NvbW1lbnRzKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgIHRoaXMtPmxlYWRpbmdfY29tbWVudHMoKS5kYXRhKCksIHRoaXMtPmxlYWRpbmdfY29tbWVudHMoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ubGVhZGluZ19jb21tZW50cyIpOworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ01heWJlQWxpYXNlZCgKKyAgICAgIDMsIHRoaXMtPmxlYWRpbmdfY29tbWVudHMoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIHN0cmluZyB0cmFpbGluZ19jb21tZW50cyA9IDQ7CisgIGlmIChoYXNfdHJhaWxpbmdfY29tbWVudHMoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgdGhpcy0+dHJhaWxpbmdfY29tbWVudHMoKS5kYXRhKCksIHRoaXMtPnRyYWlsaW5nX2NvbW1lbnRzKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLnRyYWlsaW5nX2NvbW1lbnRzIik7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nTWF5YmVBbGlhc2VkKAorICAgICAgNCwgdGhpcy0+dHJhaWxpbmdfY29tbWVudHMoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIHN0cmluZyBsZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzID0gNjsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT5sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzX3NpemUoKTsgaSsrKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKGkpLmRhdGEoKSwgdGhpcy0+bGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyhpKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ubGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyIpOworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZygKKyAgICAgIDYsIHRoaXMtPmxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMoaSksIG91dHB1dCk7CisgIH0KKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTZXJpYWxpemVVbmtub3duRmllbGRzKAorICAgICAgICB1bmtub3duX2ZpZWxkcygpLCBvdXRwdXQpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfZW5kOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbikKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogU291cmNlQ29kZUluZm9fTG9jYXRpb246OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogdGFyZ2V0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uKQorICAvLyByZXBlYXRlZCBpbnQzMiBwYXRoID0gMSBbcGFja2VkID0gdHJ1ZV07CisgIGlmICh0aGlzLT5wYXRoX3NpemUoKSA+IDApIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVUYWdUb0FycmF5KAorICAgICAgMSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVELAorICAgICAgdGFyZ2V0KTsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVWYXJpbnQzMlRvQXJyYXkoCisgICAgICBfcGF0aF9jYWNoZWRfYnl0ZV9zaXplXywgdGFyZ2V0KTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPnBhdGhfc2l6ZSgpOyBpKyspIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6CisgICAgICBXcml0ZUludDMyTm9UYWdUb0FycmF5KHRoaXMtPnBhdGgoaSksIHRhcmdldCk7CisgIH0KKworICAvLyByZXBlYXRlZCBpbnQzMiBzcGFuID0gMiBbcGFja2VkID0gdHJ1ZV07CisgIGlmICh0aGlzLT5zcGFuX3NpemUoKSA+IDApIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVUYWdUb0FycmF5KAorICAgICAgMiwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVELAorICAgICAgdGFyZ2V0KTsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVWYXJpbnQzMlRvQXJyYXkoCisgICAgICBfc3Bhbl9jYWNoZWRfYnl0ZV9zaXplXywgdGFyZ2V0KTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPnNwYW5fc2l6ZSgpOyBpKyspIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6CisgICAgICBXcml0ZUludDMyTm9UYWdUb0FycmF5KHRoaXMtPnNwYW4oaSksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgbGVhZGluZ19jb21tZW50cyA9IDM7CisgIGlmIChoYXNfbGVhZGluZ19jb21tZW50cygpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5sZWFkaW5nX2NvbW1lbnRzKCkuZGF0YSgpLCB0aGlzLT5sZWFkaW5nX2NvbW1lbnRzKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLmxlYWRpbmdfY29tbWVudHMiKTsKKyAgICB0YXJnZXQgPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nVG9BcnJheSgKKyAgICAgICAgMywgdGhpcy0+bGVhZGluZ19jb21tZW50cygpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIHRyYWlsaW5nX2NvbW1lbnRzID0gNDsKKyAgaWYgKGhhc190cmFpbGluZ19jb21tZW50cygpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT50cmFpbGluZ19jb21tZW50cygpLmRhdGEoKSwgdGhpcy0+dHJhaWxpbmdfY29tbWVudHMoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24udHJhaWxpbmdfY29tbWVudHMiKTsKKyAgICB0YXJnZXQgPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nVG9BcnJheSgKKyAgICAgICAgNCwgdGhpcy0+dHJhaWxpbmdfY29tbWVudHMoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIHN0cmluZyBsZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzID0gNjsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT5sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzX3NpemUoKTsgaSsrKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKGkpLmRhdGEoKSwgdGhpcy0+bGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyhpKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ubGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyIpOworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjoKKyAgICAgIFdyaXRlU3RyaW5nVG9BcnJheSg2LCB0aGlzLT5sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKGkpLCB0YXJnZXQpOworICB9CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bkZpZWxkc1RvQXJyYXkoCisgICAgICAgIHVua25vd25fZmllbGRzKCksIHRhcmdldCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9lbmQ6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uKQorICByZXR1cm4gdGFyZ2V0OworfQorCitpbnQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OkJ5dGVTaXplKCkgY29uc3QgeworICBpbnQgdG90YWxfc2l6ZSA9IDA7CisKKyAgaWYgKF9oYXNfYml0c19bMiAvIDMyXSAmIDEydSkgeworICAgIC8vIG9wdGlvbmFsIHN0cmluZyBsZWFkaW5nX2NvbW1lbnRzID0gMzsKKyAgICBpZiAoaGFzX2xlYWRpbmdfY29tbWVudHMoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlN0cmluZ1NpemUoCisgICAgICAgICAgdGhpcy0+bGVhZGluZ19jb21tZW50cygpKTsKKyAgICB9CisKKyAgICAvLyBvcHRpb25hbCBzdHJpbmcgdHJhaWxpbmdfY29tbWVudHMgPSA0OworICAgIGlmIChoYXNfdHJhaWxpbmdfY29tbWVudHMoKSkgeworICAgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlN0cmluZ1NpemUoCisgICAgICAgICAgdGhpcy0+dHJhaWxpbmdfY29tbWVudHMoKSk7CisgICAgfQorCisgIH0KKyAgLy8gcmVwZWF0ZWQgaW50MzIgcGF0aCA9IDEgW3BhY2tlZCA9IHRydWVdOworICB7CisgICAgaW50IGRhdGFfc2l6ZSA9IDA7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT5wYXRoX3NpemUoKTsgaSsrKSB7CisgICAgICBkYXRhX3NpemUgKz0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OgorICAgICAgICBJbnQzMlNpemUodGhpcy0+cGF0aChpKSk7CisgICAgfQorICAgIGlmIChkYXRhX3NpemUgPiAwKSB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6SW50MzJTaXplKGRhdGFfc2l6ZSk7CisgICAgfQorICAgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgICAgX3BhdGhfY2FjaGVkX2J5dGVfc2l6ZV8gPSBkYXRhX3NpemU7CisgICAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7CisgICAgdG90YWxfc2l6ZSArPSBkYXRhX3NpemU7CisgIH0KKworICAvLyByZXBlYXRlZCBpbnQzMiBzcGFuID0gMiBbcGFja2VkID0gdHJ1ZV07CisgIHsKKyAgICBpbnQgZGF0YV9zaXplID0gMDsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPnNwYW5fc2l6ZSgpOyBpKyspIHsKKyAgICAgIGRhdGFfc2l6ZSArPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6CisgICAgICAgIEludDMyU2l6ZSh0aGlzLT5zcGFuKGkpKTsKKyAgICB9CisgICAgaWYgKGRhdGFfc2l6ZSA+IDApIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpJbnQzMlNpemUoZGF0YV9zaXplKTsKKyAgICB9CisgICAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgICBfc3Bhbl9jYWNoZWRfYnl0ZV9zaXplXyA9IGRhdGFfc2l6ZTsKKyAgICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKKyAgICB0b3RhbF9zaXplICs9IGRhdGFfc2l6ZTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIHN0cmluZyBsZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzID0gNjsKKyAgdG90YWxfc2l6ZSArPSAxICogdGhpcy0+bGVhZGluZ19kZXRhY2hlZF9jb21tZW50c19zaXplKCk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+bGVhZGluZ19kZXRhY2hlZF9jb21tZW50c19zaXplKCk7IGkrKykgeworICAgIHRvdGFsX3NpemUgKz0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlN0cmluZ1NpemUoCisgICAgICB0aGlzLT5sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKGkpKTsKKyAgfQorCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHRvdGFsX3NpemUgKz0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OkNvbXB1dGVVbmtub3duRmllbGRzU2l6ZSgKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSk7CisgIH0KKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHRvdGFsX3NpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworICByZXR1cm4gdG90YWxfc2l6ZTsKK30KKwordm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6TWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBjb25zdCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbiogc291cmNlID0gCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpEeW5hbWljQ2FzdFRvR2VuZXJhdGVkPGNvbnN0IFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uPigKKyAgICAgICAgICAmZnJvbSk7CisgIGlmIChzb3VyY2UgPT0gTlVMTCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlJlZmxlY3Rpb25PcHM6Ok1lcmdlKGZyb20sIHRoaXMpOworICB9IGVsc2UgeworICAgIE1lcmdlRnJvbSgqc291cmNlKTsKKyAgfQorfQorCit2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpNZXJnZUZyb20oY29uc3QgU291cmNlQ29kZUluZm9fTG9jYXRpb24mIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgcGF0aF8uTWVyZ2VGcm9tKGZyb20ucGF0aF8pOworICBzcGFuXy5NZXJnZUZyb20oZnJvbS5zcGFuXyk7CisgIGxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHNfLk1lcmdlRnJvbShmcm9tLmxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHNfKTsKKyAgaWYgKGZyb20uX2hhc19iaXRzX1syIC8gMzJdICYgKDB4ZmZ1IDw8ICgyICUgMzIpKSkgeworICAgIGlmIChmcm9tLmhhc19sZWFkaW5nX2NvbW1lbnRzKCkpIHsKKyAgICAgIHNldF9oYXNfbGVhZGluZ19jb21tZW50cygpOworICAgICAgbGVhZGluZ19jb21tZW50c18uQXNzaWduV2l0aERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBmcm9tLmxlYWRpbmdfY29tbWVudHNfKTsKKyAgICB9CisgICAgaWYgKGZyb20uaGFzX3RyYWlsaW5nX2NvbW1lbnRzKCkpIHsKKyAgICAgIHNldF9oYXNfdHJhaWxpbmdfY29tbWVudHMoKTsKKyAgICAgIHRyYWlsaW5nX2NvbW1lbnRzXy5Bc3NpZ25XaXRoRGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGZyb20udHJhaWxpbmdfY29tbWVudHNfKTsKKyAgICB9CisgIH0KKyAgaWYgKGZyb20uX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPk1lcmdlRnJvbShmcm9tLnVua25vd25fZmllbGRzKCkpOworICB9Cit9CisKK3ZvaWQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OkNvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK3ZvaWQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OkNvcHlGcm9tKGNvbnN0IFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKworYm9vbCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6SXNJbml0aWFsaXplZCgpIGNvbnN0IHsKKworICByZXR1cm4gdHJ1ZTsKK30KKwordm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6U3dhcChTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbiogb3RoZXIpIHsKKyAgaWYgKG90aGVyID09IHRoaXMpIHJldHVybjsKKyAgSW50ZXJuYWxTd2FwKG90aGVyKTsKK30KK3ZvaWQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OkludGVybmFsU3dhcChTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbiogb3RoZXIpIHsKKyAgcGF0aF8uVW5zYWZlQXJlbmFTd2FwKCZvdGhlci0+cGF0aF8pOworICBzcGFuXy5VbnNhZmVBcmVuYVN3YXAoJm90aGVyLT5zcGFuXyk7CisgIGxlYWRpbmdfY29tbWVudHNfLlN3YXAoJm90aGVyLT5sZWFkaW5nX2NvbW1lbnRzXyk7CisgIHRyYWlsaW5nX2NvbW1lbnRzXy5Td2FwKCZvdGhlci0+dHJhaWxpbmdfY29tbWVudHNfKTsKKyAgbGVhZGluZ19kZXRhY2hlZF9jb21tZW50c18uVW5zYWZlQXJlbmFTd2FwKCZvdGhlci0+bGVhZGluZ19kZXRhY2hlZF9jb21tZW50c18pOworICBzdGQ6OnN3YXAoX2hhc19iaXRzX1swXSwgb3RoZXItPl9oYXNfYml0c19bMF0pOworICBfaW50ZXJuYWxfbWV0YWRhdGFfLlN3YXAoJm90aGVyLT5faW50ZXJuYWxfbWV0YWRhdGFfKTsKKyAgc3RkOjpzd2FwKF9jYWNoZWRfc2l6ZV8sIG90aGVyLT5fY2FjaGVkX3NpemVfKTsKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6R2V0TWV0YWRhdGEoKSBjb25zdCB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIG1ldGFkYXRhOworICBtZXRhZGF0YS5kZXNjcmlwdG9yID0gU291cmNlQ29kZUluZm9fTG9jYXRpb25fZGVzY3JpcHRvcl87CisgIG1ldGFkYXRhLnJlZmxlY3Rpb24gPSBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbl9yZWZsZWN0aW9uXzsKKyAgcmV0dXJuIG1ldGFkYXRhOworfQorCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworI2lmICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCitjb25zdCBpbnQgU291cmNlQ29kZUluZm86OmtMb2NhdGlvbkZpZWxkTnVtYmVyOworI2VuZGlmICAvLyAhZGVmaW5lZChfTVNDX1ZFUikgfHwgX01TQ19WRVIgPj0gMTkwMAorCitTb3VyY2VDb2RlSW5mbzo6U291cmNlQ29kZUluZm8oKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpLCBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvKQorfQorCit2b2lkIFNvdXJjZUNvZGVJbmZvOjpJbml0QXNEZWZhdWx0SW5zdGFuY2UoKSB7Cit9CisKK1NvdXJjZUNvZGVJbmZvOjpTb3VyY2VDb2RlSW5mbyhjb25zdCBTb3VyY2VDb2RlSW5mbyYgZnJvbSkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwKKyAgICBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICBNZXJnZUZyb20oZnJvbSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb3B5X2NvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mbykKK30KKwordm9pZCBTb3VyY2VDb2RlSW5mbzo6U2hhcmVkQ3RvcigpIHsKKyAgX2NhY2hlZF9zaXplXyA9IDA7CisgIDo6bWVtc2V0KF9oYXNfYml0c18sIDAsIHNpemVvZihfaGFzX2JpdHNfKSk7Cit9CisKK1NvdXJjZUNvZGVJbmZvOjp+U291cmNlQ29kZUluZm8oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChkZXN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mbykKKyAgU2hhcmVkRHRvcigpOworfQorCit2b2lkIFNvdXJjZUNvZGVJbmZvOjpTaGFyZWREdG9yKCkgeworICBpZiAodGhpcyAhPSBkZWZhdWx0X2luc3RhbmNlXykgeworICB9Cit9CisKK3ZvaWQgU291cmNlQ29kZUluZm86OlNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0IHsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHNpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBTb3VyY2VDb2RlSW5mbzo6ZGVzY3JpcHRvcigpIHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIHJldHVybiBTb3VyY2VDb2RlSW5mb19kZXNjcmlwdG9yXzsKK30KKworY29uc3QgU291cmNlQ29kZUluZm8mIFNvdXJjZUNvZGVJbmZvOjpkZWZhdWx0X2luc3RhbmNlKCkgeworICBpZiAoZGVmYXVsdF9pbnN0YW5jZV8gPT0gTlVMTCkgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICByZXR1cm4gKmRlZmF1bHRfaW5zdGFuY2VfOworfQorCitTb3VyY2VDb2RlSW5mbyogU291cmNlQ29kZUluZm86OmRlZmF1bHRfaW5zdGFuY2VfID0gTlVMTDsKKworU291cmNlQ29kZUluZm8qIFNvdXJjZUNvZGVJbmZvOjpOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0IHsKKyAgU291cmNlQ29kZUluZm8qIG4gPSBuZXcgU291cmNlQ29kZUluZm87CisgIGlmIChhcmVuYSAhPSBOVUxMKSB7CisgICAgYXJlbmEtPk93bihuKTsKKyAgfQorICByZXR1cm4gbjsKK30KKwordm9pZCBTb3VyY2VDb2RlSW5mbzo6Q2xlYXIoKSB7CisgIGxvY2F0aW9uXy5DbGVhcigpOworICA6Om1lbXNldChfaGFzX2JpdHNfLCAwLCBzaXplb2YoX2hhc19iaXRzXykpOworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkNsZWFyKCk7CisgIH0KK30KKworYm9vbCBTb3VyY2VDb2RlSW5mbzo6TWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KSB7CisjZGVmaW5lIERPXyhFWFBSRVNTSU9OKSBpZiAoIShFWFBSRVNTSU9OKSkgZ290byBmYWlsdXJlCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIHRhZzsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mbykKKyAgZm9yICg7OykgeworICAgIDo6c3RkOjpwYWlyPCA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiwgYm9vbD4gcCA9IGlucHV0LT5SZWFkVGFnV2l0aEN1dG9mZigxMjcpOworICAgIHRhZyA9IHAuZmlyc3Q7CisgICAgaWYgKCFwLnNlY29uZCkgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICBzd2l0Y2ggKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdGaWVsZE51bWJlcih0YWcpKSB7CisgICAgICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uIGxvY2F0aW9uID0gMTsKKyAgICAgIGNhc2UgMTogeworICAgICAgICBpZiAodGFnID09IDEwKSB7CisgICAgICAgICAgRE9fKGlucHV0LT5JbmNyZW1lbnRSZWN1cnNpb25EZXB0aCgpKTsKKyAgICAgICAgIHBhcnNlX2xvb3BfbG9jYXRpb246CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkTWVzc2FnZU5vVmlydHVhbE5vUmVjdXJzaW9uRGVwdGgoCisgICAgICAgICAgICAgICAgaW5wdXQsIGFkZF9sb2NhdGlvbigpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygxMCkpIGdvdG8gcGFyc2VfbG9vcF9sb2NhdGlvbjsKKyAgICAgICAgaW5wdXQtPlVuc2FmZURlY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCk7CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0QXRFbmQoKSkgZ290byBzdWNjZXNzOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgZGVmYXVsdDogeworICAgICAgaGFuZGxlX3VudXN1YWw6CisgICAgICAgIGlmICh0YWcgPT0gMCB8fAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ1dpcmVUeXBlKHRhZykgPT0KKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVApIHsKKyAgICAgICAgICBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIH0KKyAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNraXBGaWVsZCgKKyAgICAgICAgICAgICAgaW5wdXQsIHRhZywgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpKSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgfQorc3VjY2VzczoKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N1Y2Nlc3M6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvKQorICByZXR1cm4gdHJ1ZTsKK2ZhaWx1cmU6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9mYWlsdXJlOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mbykKKyAgcmV0dXJuIGZhbHNlOworI3VuZGVmIERPXworfQorCit2b2lkIFNvdXJjZUNvZGVJbmZvOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mbykKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbiBsb2NhdGlvbiA9IDE7CisgIGZvciAodW5zaWduZWQgaW50IGkgPSAwLCBuID0gdGhpcy0+bG9jYXRpb25fc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlTWVzc2FnZU1heWJlVG9BcnJheSgKKyAgICAgIDEsIHRoaXMtPmxvY2F0aW9uKGkpLCBvdXRwdXQpOworICB9CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bkZpZWxkcygKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSwgb3V0cHV0KTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX2VuZDpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8pCit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIFNvdXJjZUNvZGVJbmZvOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIHRhcmdldCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mbykKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbiBsb2NhdGlvbiA9IDE7CisgIGZvciAodW5zaWduZWQgaW50IGkgPSAwLCBuID0gdGhpcy0+bG9jYXRpb25fc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OgorICAgICAgV3JpdGVNZXNzYWdlTm9WaXJ0dWFsVG9BcnJheSgKKyAgICAgICAgMSwgdGhpcy0+bG9jYXRpb24oaSksIHRhcmdldCk7CisgIH0KKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTZXJpYWxpemVVbmtub3duRmllbGRzVG9BcnJheSgKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSwgdGFyZ2V0KTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X2VuZDpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8pCisgIHJldHVybiB0YXJnZXQ7Cit9CisKK2ludCBTb3VyY2VDb2RlSW5mbzo6Qnl0ZVNpemUoKSBjb25zdCB7CisgIGludCB0b3RhbF9zaXplID0gMDsKKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uIGxvY2F0aW9uID0gMTsKKyAgdG90YWxfc2l6ZSArPSAxICogdGhpcy0+bG9jYXRpb25fc2l6ZSgpOworICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPmxvY2F0aW9uX3NpemUoKTsgaSsrKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1lc3NhZ2VTaXplTm9WaXJ0dWFsKAorICAgICAgICB0aGlzLT5sb2NhdGlvbihpKSk7CisgIH0KKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICB0b3RhbF9zaXplICs9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpDb21wdXRlVW5rbm93bkZpZWxkc1NpemUoCisgICAgICAgIHVua25vd25fZmllbGRzKCkpOworICB9CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSB0b3RhbF9zaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKKyAgcmV0dXJuIHRvdGFsX3NpemU7Cit9CisKK3ZvaWQgU291cmNlQ29kZUluZm86Ok1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgY29uc3QgU291cmNlQ29kZUluZm8qIHNvdXJjZSA9IAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RHluYW1pY0Nhc3RUb0dlbmVyYXRlZDxjb25zdCBTb3VyY2VDb2RlSW5mbz4oCisgICAgICAgICAgJmZyb20pOworICBpZiAoc291cmNlID09IE5VTEwpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpSZWZsZWN0aW9uT3BzOjpNZXJnZShmcm9tLCB0aGlzKTsKKyAgfSBlbHNlIHsKKyAgICBNZXJnZUZyb20oKnNvdXJjZSk7CisgIH0KK30KKwordm9pZCBTb3VyY2VDb2RlSW5mbzo6TWVyZ2VGcm9tKGNvbnN0IFNvdXJjZUNvZGVJbmZvJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGxvY2F0aW9uXy5NZXJnZUZyb20oZnJvbS5sb2NhdGlvbl8pOworICBpZiAoZnJvbS5faW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+TWVyZ2VGcm9tKGZyb20udW5rbm93bl9maWVsZHMoKSk7CisgIH0KK30KKwordm9pZCBTb3VyY2VDb2RlSW5mbzo6Q29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKwordm9pZCBTb3VyY2VDb2RlSW5mbzo6Q29weUZyb20oY29uc3QgU291cmNlQ29kZUluZm8mIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCitib29sIFNvdXJjZUNvZGVJbmZvOjpJc0luaXRpYWxpemVkKCkgY29uc3QgeworCisgIHJldHVybiB0cnVlOworfQorCit2b2lkIFNvdXJjZUNvZGVJbmZvOjpTd2FwKFNvdXJjZUNvZGVJbmZvKiBvdGhlcikgeworICBpZiAob3RoZXIgPT0gdGhpcykgcmV0dXJuOworICBJbnRlcm5hbFN3YXAob3RoZXIpOworfQordm9pZCBTb3VyY2VDb2RlSW5mbzo6SW50ZXJuYWxTd2FwKFNvdXJjZUNvZGVJbmZvKiBvdGhlcikgeworICBsb2NhdGlvbl8uVW5zYWZlQXJlbmFTd2FwKCZvdGhlci0+bG9jYXRpb25fKTsKKyAgc3RkOjpzd2FwKF9oYXNfYml0c19bMF0sIG90aGVyLT5faGFzX2JpdHNfWzBdKTsKKyAgX2ludGVybmFsX21ldGFkYXRhXy5Td2FwKCZvdGhlci0+X2ludGVybmFsX21ldGFkYXRhXyk7CisgIHN0ZDo6c3dhcChfY2FjaGVkX3NpemVfLCBvdGhlci0+X2NhY2hlZF9zaXplXyk7Cit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgU291cmNlQ29kZUluZm86OkdldE1ldGFkYXRhKCkgY29uc3QgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBtZXRhZGF0YTsKKyAgbWV0YWRhdGEuZGVzY3JpcHRvciA9IFNvdXJjZUNvZGVJbmZvX2Rlc2NyaXB0b3JfOworICBtZXRhZGF0YS5yZWZsZWN0aW9uID0gU291cmNlQ29kZUluZm9fcmVmbGVjdGlvbl87CisgIHJldHVybiBtZXRhZGF0YTsKK30KKworI2lmIFBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworLy8gU291cmNlQ29kZUluZm9fTG9jYXRpb24KKworLy8gcmVwZWF0ZWQgaW50MzIgcGF0aCA9IDEgW3BhY2tlZCA9IHRydWVdOworaW50IFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpwYXRoX3NpemUoKSBjb25zdCB7CisgIHJldHVybiBwYXRoXy5zaXplKCk7Cit9Cit2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpjbGVhcl9wYXRoKCkgeworICBwYXRoXy5DbGVhcigpOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgU291cmNlQ29kZUluZm9fTG9jYXRpb246OnBhdGgoaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLnBhdGgpCisgIHJldHVybiBwYXRoXy5HZXQoaW5kZXgpOworfQorIHZvaWQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OnNldF9wYXRoKGludCBpbmRleCwgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiB2YWx1ZSkgeworICBwYXRoXy5TZXQoaW5kZXgsIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ucGF0aCkKK30KKyB2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjphZGRfcGF0aCg6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKSB7CisgIHBhdGhfLkFkZCh2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLnBhdGgpCit9CisgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZEZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyID4mCitTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6cGF0aCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLnBhdGgpCisgIHJldHVybiBwYXRoXzsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgPioKK1NvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjptdXRhYmxlX3BhdGgoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLnBhdGgpCisgIHJldHVybiAmcGF0aF87Cit9CisKKy8vIHJlcGVhdGVkIGludDMyIHNwYW4gPSAyIFtwYWNrZWQgPSB0cnVlXTsKK2ludCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6c3Bhbl9zaXplKCkgY29uc3QgeworICByZXR1cm4gc3Bhbl8uc2l6ZSgpOworfQordm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6Y2xlYXJfc3BhbigpIHsKKyAgc3Bhbl8uQ2xlYXIoKTsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpzcGFuKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5zcGFuKQorICByZXR1cm4gc3Bhbl8uR2V0KGluZGV4KTsKK30KKyB2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpzZXRfc3BhbihpbnQgaW5kZXgsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgdmFsdWUpIHsKKyAgc3Bhbl8uU2V0KGluZGV4LCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLnNwYW4pCit9Cisgdm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6YWRkX3NwYW4oOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiB2YWx1ZSkgeworICBzcGFuXy5BZGQodmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5zcGFuKQorfQorIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiA+JgorU291cmNlQ29kZUluZm9fTG9jYXRpb246OnNwYW4oKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5zcGFuKQorICByZXR1cm4gc3Bhbl87Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZEZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyID4qCitTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6bXV0YWJsZV9zcGFuKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5zcGFuKQorICByZXR1cm4gJnNwYW5fOworfQorCisvLyBvcHRpb25hbCBzdHJpbmcgbGVhZGluZ19jb21tZW50cyA9IDM7Citib29sIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpoYXNfbGVhZGluZ19jb21tZW50cygpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwNHUpICE9IDA7Cit9Cit2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpzZXRfaGFzX2xlYWRpbmdfY29tbWVudHMoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwNHU7Cit9Cit2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpjbGVhcl9oYXNfbGVhZGluZ19jb21tZW50cygpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwNHU7Cit9Cit2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpjbGVhcl9sZWFkaW5nX2NvbW1lbnRzKCkgeworICBsZWFkaW5nX2NvbW1lbnRzXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGNsZWFyX2hhc19sZWFkaW5nX2NvbW1lbnRzKCk7Cit9CisgY29uc3QgOjpzdGQ6OnN0cmluZyYgU291cmNlQ29kZUluZm9fTG9jYXRpb246OmxlYWRpbmdfY29tbWVudHMoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLmxlYWRpbmdfY29tbWVudHMpCisgIHJldHVybiBsZWFkaW5nX2NvbW1lbnRzXy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6c2V0X2xlYWRpbmdfY29tbWVudHMoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgc2V0X2hhc19sZWFkaW5nX2NvbW1lbnRzKCk7CisgIGxlYWRpbmdfY29tbWVudHNfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLmxlYWRpbmdfY29tbWVudHMpCit9Cisgdm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6c2V0X2xlYWRpbmdfY29tbWVudHMoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgc2V0X2hhc19sZWFkaW5nX2NvbW1lbnRzKCk7CisgIGxlYWRpbmdfY29tbWVudHNfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ubGVhZGluZ19jb21tZW50cykKK30KKyB2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpzZXRfbGVhZGluZ19jb21tZW50cyhjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19sZWFkaW5nX2NvbW1lbnRzKCk7CisgIGxlYWRpbmdfY29tbWVudHNfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5sZWFkaW5nX2NvbW1lbnRzKQorfQorIDo6c3RkOjpzdHJpbmcqIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjptdXRhYmxlX2xlYWRpbmdfY29tbWVudHMoKSB7CisgIHNldF9oYXNfbGVhZGluZ19jb21tZW50cygpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ubGVhZGluZ19jb21tZW50cykKKyAgcmV0dXJuIGxlYWRpbmdfY29tbWVudHNfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CisgOjpzdGQ6OnN0cmluZyogU291cmNlQ29kZUluZm9fTG9jYXRpb246OnJlbGVhc2VfbGVhZGluZ19jb21tZW50cygpIHsKKyAgY2xlYXJfaGFzX2xlYWRpbmdfY29tbWVudHMoKTsKKyAgcmV0dXJuIGxlYWRpbmdfY29tbWVudHNfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6c2V0X2FsbG9jYXRlZF9sZWFkaW5nX2NvbW1lbnRzKDo6c3RkOjpzdHJpbmcqIGxlYWRpbmdfY29tbWVudHMpIHsKKyAgaWYgKGxlYWRpbmdfY29tbWVudHMgIT0gTlVMTCkgeworICAgIHNldF9oYXNfbGVhZGluZ19jb21tZW50cygpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19sZWFkaW5nX2NvbW1lbnRzKCk7CisgIH0KKyAgbGVhZGluZ19jb21tZW50c18uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGxlYWRpbmdfY29tbWVudHMpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ubGVhZGluZ19jb21tZW50cykKK30KKworLy8gb3B0aW9uYWwgc3RyaW5nIHRyYWlsaW5nX2NvbW1lbnRzID0gNDsKK2Jvb2wgU291cmNlQ29kZUluZm9fTG9jYXRpb246Omhhc190cmFpbGluZ19jb21tZW50cygpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwOHUpICE9IDA7Cit9Cit2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpzZXRfaGFzX3RyYWlsaW5nX2NvbW1lbnRzKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDh1OworfQordm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6Y2xlYXJfaGFzX3RyYWlsaW5nX2NvbW1lbnRzKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDA4dTsKK30KK3ZvaWQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OmNsZWFyX3RyYWlsaW5nX2NvbW1lbnRzKCkgeworICB0cmFpbGluZ19jb21tZW50c18uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfdHJhaWxpbmdfY29tbWVudHMoKTsKK30KKyBjb25zdCA6OnN0ZDo6c3RyaW5nJiBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6dHJhaWxpbmdfY29tbWVudHMoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLnRyYWlsaW5nX2NvbW1lbnRzKQorICByZXR1cm4gdHJhaWxpbmdfY29tbWVudHNfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpzZXRfdHJhaWxpbmdfY29tbWVudHMoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgc2V0X2hhc190cmFpbGluZ19jb21tZW50cygpOworICB0cmFpbGluZ19jb21tZW50c18uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24udHJhaWxpbmdfY29tbWVudHMpCit9Cisgdm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6c2V0X3RyYWlsaW5nX2NvbW1lbnRzKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfdHJhaWxpbmdfY29tbWVudHMoKTsKKyAgdHJhaWxpbmdfY29tbWVudHNfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24udHJhaWxpbmdfY29tbWVudHMpCit9Cisgdm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6c2V0X3RyYWlsaW5nX2NvbW1lbnRzKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX3RyYWlsaW5nX2NvbW1lbnRzKCk7CisgIHRyYWlsaW5nX2NvbW1lbnRzXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24udHJhaWxpbmdfY29tbWVudHMpCit9CisgOjpzdGQ6OnN0cmluZyogU291cmNlQ29kZUluZm9fTG9jYXRpb246Om11dGFibGVfdHJhaWxpbmdfY29tbWVudHMoKSB7CisgIHNldF9oYXNfdHJhaWxpbmdfY29tbWVudHMoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLnRyYWlsaW5nX2NvbW1lbnRzKQorICByZXR1cm4gdHJhaWxpbmdfY29tbWVudHNfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CisgOjpzdGQ6OnN0cmluZyogU291cmNlQ29kZUluZm9fTG9jYXRpb246OnJlbGVhc2VfdHJhaWxpbmdfY29tbWVudHMoKSB7CisgIGNsZWFyX2hhc190cmFpbGluZ19jb21tZW50cygpOworICByZXR1cm4gdHJhaWxpbmdfY29tbWVudHNfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6c2V0X2FsbG9jYXRlZF90cmFpbGluZ19jb21tZW50cyg6OnN0ZDo6c3RyaW5nKiB0cmFpbGluZ19jb21tZW50cykgeworICBpZiAodHJhaWxpbmdfY29tbWVudHMgIT0gTlVMTCkgeworICAgIHNldF9oYXNfdHJhaWxpbmdfY29tbWVudHMoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfdHJhaWxpbmdfY29tbWVudHMoKTsKKyAgfQorICB0cmFpbGluZ19jb21tZW50c18uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHRyYWlsaW5nX2NvbW1lbnRzKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLnRyYWlsaW5nX2NvbW1lbnRzKQorfQorCisvLyByZXBlYXRlZCBzdHJpbmcgbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyA9IDY7CitpbnQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OmxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHNfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIGxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHNfLnNpemUoKTsKK30KK3ZvaWQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OmNsZWFyX2xlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMoKSB7CisgIGxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHNfLkNsZWFyKCk7Cit9CisgY29uc3QgOjpzdGQ6OnN0cmluZyYgU291cmNlQ29kZUluZm9fTG9jYXRpb246OmxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMoaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLmxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMpCisgIHJldHVybiBsZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzXy5HZXQoaW5kZXgpOworfQorIDo6c3RkOjpzdHJpbmcqIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjptdXRhYmxlX2xlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMoaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKQorICByZXR1cm4gbGVhZGluZ19kZXRhY2hlZF9jb21tZW50c18uTXV0YWJsZShpbmRleCk7Cit9Cisgdm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6c2V0X2xlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMoaW50IGluZGV4LCBjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKQorICBsZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzXy5NdXRhYmxlKGluZGV4KS0+YXNzaWduKHZhbHVlKTsKK30KKyB2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpzZXRfbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyhpbnQgaW5kZXgsIGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIGxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHNfLk11dGFibGUoaW5kZXgpLT5hc3NpZ24odmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLmxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMpCit9Cisgdm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6c2V0X2xlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMoaW50IGluZGV4LCBjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgbGVhZGluZ19kZXRhY2hlZF9jb21tZW50c18uTXV0YWJsZShpbmRleCktPmFzc2lnbigKKyAgICByZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLmxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMpCit9CisgOjpzdGQ6OnN0cmluZyogU291cmNlQ29kZUluZm9fTG9jYXRpb246OmFkZF9sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKCkgeworICByZXR1cm4gbGVhZGluZ19kZXRhY2hlZF9jb21tZW50c18uQWRkKCk7Cit9Cisgdm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6YWRkX2xlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgbGVhZGluZ19kZXRhY2hlZF9jb21tZW50c18uQWRkKCktPmFzc2lnbih2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLmxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMpCit9Cisgdm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6YWRkX2xlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgbGVhZGluZ19kZXRhY2hlZF9jb21tZW50c18uQWRkKCktPmFzc2lnbih2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGRfY2hhcjpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ubGVhZGluZ19kZXRhY2hlZF9jb21tZW50cykKK30KKyB2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjphZGRfbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyhjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgbGVhZGluZ19kZXRhY2hlZF9jb21tZW50c18uQWRkKCktPmFzc2lnbihyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkX3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLmxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMpCit9CisgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6OnN0ZDo6c3RyaW5nPiYKK1NvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpsZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ubGVhZGluZ19kZXRhY2hlZF9jb21tZW50cykKKyAgcmV0dXJuIGxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHNfOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpzdGQ6OnN0cmluZz4qCitTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6bXV0YWJsZV9sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKQorICByZXR1cm4gJmxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHNfOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIFNvdXJjZUNvZGVJbmZvCisKKy8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24gbG9jYXRpb24gPSAxOworaW50IFNvdXJjZUNvZGVJbmZvOjpsb2NhdGlvbl9zaXplKCkgY29uc3QgeworICByZXR1cm4gbG9jYXRpb25fLnNpemUoKTsKK30KK3ZvaWQgU291cmNlQ29kZUluZm86OmNsZWFyX2xvY2F0aW9uKCkgeworICBsb2NhdGlvbl8uQ2xlYXIoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29kZUluZm9fTG9jYXRpb24mIFNvdXJjZUNvZGVJbmZvOjpsb2NhdGlvbihpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8ubG9jYXRpb24pCisgIHJldHVybiBsb2NhdGlvbl8uR2V0KGluZGV4KTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29kZUluZm9fTG9jYXRpb24qIFNvdXJjZUNvZGVJbmZvOjptdXRhYmxlX2xvY2F0aW9uKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8ubG9jYXRpb24pCisgIHJldHVybiBsb2NhdGlvbl8uTXV0YWJsZShpbmRleCk7Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uKiBTb3VyY2VDb2RlSW5mbzo6YWRkX2xvY2F0aW9uKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5sb2NhdGlvbikKKyAgcmV0dXJuIGxvY2F0aW9uXy5BZGQoKTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbiA+KgorU291cmNlQ29kZUluZm86Om11dGFibGVfbG9jYXRpb24oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLmxvY2F0aW9uKQorICByZXR1cm4gJmxvY2F0aW9uXzsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbiA+JgorU291cmNlQ29kZUluZm86OmxvY2F0aW9uKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8ubG9jYXRpb24pCisgIHJldHVybiBsb2NhdGlvbl87Cit9CisKKyNlbmRpZiAgLy8gUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworI2lmICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCitjb25zdCBpbnQgR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbjo6a1BhdGhGaWVsZE51bWJlcjsKK2NvbnN0IGludCBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uOjprU291cmNlRmlsZUZpZWxkTnVtYmVyOworY29uc3QgaW50IEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb246OmtCZWdpbkZpZWxkTnVtYmVyOworY29uc3QgaW50IEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb246OmtFbmRGaWVsZE51bWJlcjsKKyNlbmRpZiAgLy8gIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKKworR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbjo6R2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbigpCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgeworICBTaGFyZWRDdG9yKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8uQW5ub3RhdGlvbikKK30KKwordm9pZCBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uOjpJbml0QXNEZWZhdWx0SW5zdGFuY2UoKSB7Cit9CisKK0dlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb246OkdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb24oY29uc3QgR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbiYgZnJvbSkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwKKyAgICBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICBNZXJnZUZyb20oZnJvbSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb3B5X2NvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRDb2RlSW5mby5Bbm5vdGF0aW9uKQorfQorCit2b2lkIEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb246OlNoYXJlZEN0b3IoKSB7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSAwOworICBzb3VyY2VfZmlsZV8uVW5zYWZlU2V0RGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBiZWdpbl8gPSAwOworICBlbmRfID0gMDsKKyAgOjptZW1zZXQoX2hhc19iaXRzXywgMCwgc2l6ZW9mKF9oYXNfYml0c18pKTsKK30KKworR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbjo6fkdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb24oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChkZXN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRDb2RlSW5mby5Bbm5vdGF0aW9uKQorICBTaGFyZWREdG9yKCk7Cit9CisKK3ZvaWQgR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbjo6U2hhcmVkRHRvcigpIHsKKyAgc291cmNlX2ZpbGVfLkRlc3Ryb3lOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGlmICh0aGlzICE9IGRlZmF1bHRfaW5zdGFuY2VfKSB7CisgIH0KK30KKwordm9pZCBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uOjpTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdCB7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSBzaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbjo6ZGVzY3JpcHRvcigpIHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIHJldHVybiBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uX2Rlc2NyaXB0b3JfOworfQorCitjb25zdCBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uJiBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uOjpkZWZhdWx0X2luc3RhbmNlKCkgeworICBpZiAoZGVmYXVsdF9pbnN0YW5jZV8gPT0gTlVMTCkgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICByZXR1cm4gKmRlZmF1bHRfaW5zdGFuY2VfOworfQorCitHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uKiBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uOjpkZWZhdWx0X2luc3RhbmNlXyA9IE5VTEw7CisKK0dlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb24qIEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb246Ok5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3QgeworICBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uKiBuID0gbmV3IEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb247CisgIGlmIChhcmVuYSAhPSBOVUxMKSB7CisgICAgYXJlbmEtPk93bihuKTsKKyAgfQorICByZXR1cm4gbjsKK30KKwordm9pZCBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uOjpDbGVhcigpIHsKKyNkZWZpbmUgWlJfSEVMUEVSXyhmKSByZWludGVycHJldF9jYXN0PGNoYXIqPihcCisgICZyZWludGVycHJldF9jYXN0PEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb24qPigxNiktPmYpCisKKyNkZWZpbmUgWlJfKGZpcnN0LCBsYXN0KSBkbyB7XAorICA6Om1lbXNldCgmZmlyc3QsIDAsXAorICAgICAgICAgICBaUl9IRUxQRVJfKGxhc3QpIC0gWlJfSEVMUEVSXyhmaXJzdCkgKyBzaXplb2YobGFzdCkpO1wKK30gd2hpbGUgKDApCisKKyAgaWYgKF9oYXNfYml0c19bMCAvIDMyXSAmIDE0dSkgeworICAgIFpSXyhiZWdpbl8sIGVuZF8pOworICAgIGlmIChoYXNfc291cmNlX2ZpbGUoKSkgeworICAgICAgc291cmNlX2ZpbGVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgICB9CisgIH0KKworI3VuZGVmIFpSX0hFTFBFUl8KKyN1bmRlZiBaUl8KKworICBwYXRoXy5DbGVhcigpOworICA6Om1lbXNldChfaGFzX2JpdHNfLCAwLCBzaXplb2YoX2hhc19iaXRzXykpOworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkNsZWFyKCk7CisgIH0KK30KKworYm9vbCBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uOjpNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyNkZWZpbmUgRE9fKEVYUFJFU1NJT04pIGlmICghKEVYUFJFU1NJT04pKSBnb3RvIGZhaWx1cmUKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgdGFnOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZENvZGVJbmZvLkFubm90YXRpb24pCisgIGZvciAoOzspIHsKKyAgICA6OnN0ZDo6cGFpcjwgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIsIGJvb2w+IHAgPSBpbnB1dC0+UmVhZFRhZ1dpdGhDdXRvZmYoMTI3KTsKKyAgICB0YWcgPSBwLmZpcnN0OworICAgIGlmICghcC5zZWNvbmQpIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgc3dpdGNoICg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnRmllbGROdW1iZXIodGFnKSkgeworICAgICAgLy8gcmVwZWF0ZWQgaW50MzIgcGF0aCA9IDEgW3BhY2tlZCA9IHRydWVdOworICAgICAgY2FzZSAxOiB7CisgICAgICAgIGlmICh0YWcgPT0gMTApIHsKKyAgICAgICAgICBET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUGFja2VkUHJpbWl0aXZlPAorICAgICAgICAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0lOVDMyPigKKyAgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPm11dGFibGVfcGF0aCgpKSkpOworICAgICAgICB9IGVsc2UgaWYgKHRhZyA9PSA4KSB7CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFJlcGVhdGVkUHJpbWl0aXZlTm9JbmxpbmU8CisgICAgICAgICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfSU5UMzI+KAorICAgICAgICAgICAgICAgICAxLCAxMCwgaW5wdXQsIHRoaXMtPm11dGFibGVfcGF0aCgpKSkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMTgpKSBnb3RvIHBhcnNlX3NvdXJjZV9maWxlOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgc3RyaW5nIHNvdXJjZV9maWxlID0gMjsKKyAgICAgIGNhc2UgMjogeworICAgICAgICBpZiAodGFnID09IDE4KSB7CisgICAgICAgICBwYXJzZV9zb3VyY2VfZmlsZToKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoCisgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPm11dGFibGVfc291cmNlX2ZpbGUoKSkpOworICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlZlcmlmeVVURjhTdHJpbmdOYW1lZEZpZWxkKAorICAgICAgICAgICAgdGhpcy0+c291cmNlX2ZpbGUoKS5kYXRhKCksIHRoaXMtPnNvdXJjZV9maWxlKCkubGVuZ3RoKCksCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpQQVJTRSwKKyAgICAgICAgICAgICJnb29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8uQW5ub3RhdGlvbi5zb3VyY2VfZmlsZSIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMjQpKSBnb3RvIHBhcnNlX2JlZ2luOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgaW50MzIgYmVnaW4gPSAzOworICAgICAgY2FzZSAzOiB7CisgICAgICAgIGlmICh0YWcgPT0gMjQpIHsKKyAgICAgICAgIHBhcnNlX2JlZ2luOgorICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfSU5UMzI+KAorICAgICAgICAgICAgICAgICBpbnB1dCwgJmJlZ2luXykpKTsKKyAgICAgICAgICBzZXRfaGFzX2JlZ2luKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygzMikpIGdvdG8gcGFyc2VfZW5kOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgaW50MzIgZW5kID0gNDsKKyAgICAgIGNhc2UgNDogeworICAgICAgICBpZiAodGFnID09IDMyKSB7CisgICAgICAgICBwYXJzZV9lbmQ6CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyLCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9JTlQzMj4oCisgICAgICAgICAgICAgICAgIGlucHV0LCAmZW5kXykpKTsKKyAgICAgICAgICBzZXRfaGFzX2VuZCgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RBdEVuZCgpKSBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBkZWZhdWx0OiB7CisgICAgICBoYW5kbGVfdW51c3VhbDoKKyAgICAgICAgaWYgKHRhZyA9PSAwIHx8CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnV2lyZVR5cGUodGFnKSA9PQorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0VORF9HUk9VUCkgeworICAgICAgICAgIGdvdG8gc3VjY2VzczsKKyAgICAgICAgfQorICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2tpcEZpZWxkKAorICAgICAgICAgICAgICBpbnB1dCwgdGFnLCBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CitzdWNjZXNzOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3VjY2Vzczpnb29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8uQW5ub3RhdGlvbikKKyAgcmV0dXJuIHRydWU7CitmYWlsdXJlOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2VfZmFpbHVyZTpnb29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8uQW5ub3RhdGlvbikKKyAgcmV0dXJuIGZhbHNlOworI3VuZGVmIERPXworfQorCit2b2lkIEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb246OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZENvZGVJbmZvLkFubm90YXRpb24pCisgIC8vIHJlcGVhdGVkIGludDMyIHBhdGggPSAxIFtwYWNrZWQgPSB0cnVlXTsKKyAgaWYgKHRoaXMtPnBhdGhfc2l6ZSgpID4gMCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVRhZygxLCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCwgb3V0cHV0KTsKKyAgICBvdXRwdXQtPldyaXRlVmFyaW50MzIoX3BhdGhfY2FjaGVkX2J5dGVfc2l6ZV8pOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+cGF0aF9zaXplKCk7IGkrKykgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUludDMyTm9UYWcoCisgICAgICB0aGlzLT5wYXRoKGkpLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIHNvdXJjZV9maWxlID0gMjsKKyAgaWYgKGhhc19zb3VyY2VfZmlsZSgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoCisgICAgICB0aGlzLT5zb3VyY2VfZmlsZSgpLmRhdGEoKSwgdGhpcy0+c291cmNlX2ZpbGUoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8uQW5ub3RhdGlvbi5zb3VyY2VfZmlsZSIpOworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ01heWJlQWxpYXNlZCgKKyAgICAgIDIsIHRoaXMtPnNvdXJjZV9maWxlKCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBpbnQzMiBiZWdpbiA9IDM7CisgIGlmIChoYXNfYmVnaW4oKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUludDMyKDMsIHRoaXMtPmJlZ2luKCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBpbnQzMiBlbmQgPSA0OworICBpZiAoaGFzX2VuZCgpKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlSW50MzIoNCwgdGhpcy0+ZW5kKCksIG91dHB1dCk7CisgIH0KKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTZXJpYWxpemVVbmtub3duRmllbGRzKAorICAgICAgICB1bmtub3duX2ZpZWxkcygpLCBvdXRwdXQpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfZW5kOmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRDb2RlSW5mby5Bbm5vdGF0aW9uKQorfQorCis6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIHRhcmdldCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRDb2RlSW5mby5Bbm5vdGF0aW9uKQorICAvLyByZXBlYXRlZCBpbnQzMiBwYXRoID0gMSBbcGFja2VkID0gdHJ1ZV07CisgIGlmICh0aGlzLT5wYXRoX3NpemUoKSA+IDApIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVUYWdUb0FycmF5KAorICAgICAgMSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVELAorICAgICAgdGFyZ2V0KTsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVWYXJpbnQzMlRvQXJyYXkoCisgICAgICBfcGF0aF9jYWNoZWRfYnl0ZV9zaXplXywgdGFyZ2V0KTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPnBhdGhfc2l6ZSgpOyBpKyspIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6CisgICAgICBXcml0ZUludDMyTm9UYWdUb0FycmF5KHRoaXMtPnBhdGgoaSksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgc291cmNlX2ZpbGUgPSAyOworICBpZiAoaGFzX3NvdXJjZV9maWxlKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICAgIHRoaXMtPnNvdXJjZV9maWxlKCkuZGF0YSgpLCB0aGlzLT5zb3VyY2VfZmlsZSgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRDb2RlSW5mby5Bbm5vdGF0aW9uLnNvdXJjZV9maWxlIik7CisgICAgdGFyZ2V0ID0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ1RvQXJyYXkoCisgICAgICAgIDIsIHRoaXMtPnNvdXJjZV9maWxlKCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBpbnQzMiBiZWdpbiA9IDM7CisgIGlmIChoYXNfYmVnaW4oKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUludDMyVG9BcnJheSgzLCB0aGlzLT5iZWdpbigpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgaW50MzIgZW5kID0gNDsKKyAgaWYgKGhhc19lbmQoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUludDMyVG9BcnJheSg0LCB0aGlzLT5lbmQoKSwgdGFyZ2V0KTsKKyAgfQorCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25GaWVsZHNUb0FycmF5KAorICAgICAgICB1bmtub3duX2ZpZWxkcygpLCB0YXJnZXQpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfZW5kOmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRDb2RlSW5mby5Bbm5vdGF0aW9uKQorICByZXR1cm4gdGFyZ2V0OworfQorCitpbnQgR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbjo6Qnl0ZVNpemUoKSBjb25zdCB7CisgIGludCB0b3RhbF9zaXplID0gMDsKKworICBpZiAoX2hhc19iaXRzX1sxIC8gMzJdICYgMTR1KSB7CisgICAgLy8gb3B0aW9uYWwgc3RyaW5nIHNvdXJjZV9maWxlID0gMjsKKyAgICBpZiAoaGFzX3NvdXJjZV9maWxlKCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTdHJpbmdTaXplKAorICAgICAgICAgIHRoaXMtPnNvdXJjZV9maWxlKCkpOworICAgIH0KKworICAgIC8vIG9wdGlvbmFsIGludDMyIGJlZ2luID0gMzsKKyAgICBpZiAoaGFzX2JlZ2luKCkpIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpJbnQzMlNpemUoCisgICAgICAgICAgdGhpcy0+YmVnaW4oKSk7CisgICAgfQorCisgICAgLy8gb3B0aW9uYWwgaW50MzIgZW5kID0gNDsKKyAgICBpZiAoaGFzX2VuZCgpKSB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6SW50MzJTaXplKAorICAgICAgICAgIHRoaXMtPmVuZCgpKTsKKyAgICB9CisKKyAgfQorICAvLyByZXBlYXRlZCBpbnQzMiBwYXRoID0gMSBbcGFja2VkID0gdHJ1ZV07CisgIHsKKyAgICBpbnQgZGF0YV9zaXplID0gMDsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPnBhdGhfc2l6ZSgpOyBpKyspIHsKKyAgICAgIGRhdGFfc2l6ZSArPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6CisgICAgICAgIEludDMyU2l6ZSh0aGlzLT5wYXRoKGkpKTsKKyAgICB9CisgICAgaWYgKGRhdGFfc2l6ZSA+IDApIHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpJbnQzMlNpemUoZGF0YV9zaXplKTsKKyAgICB9CisgICAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgICBfcGF0aF9jYWNoZWRfYnl0ZV9zaXplXyA9IGRhdGFfc2l6ZTsKKyAgICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKKyAgICB0b3RhbF9zaXplICs9IGRhdGFfc2l6ZTsKKyAgfQorCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIHRvdGFsX3NpemUgKz0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OkNvbXB1dGVVbmtub3duRmllbGRzU2l6ZSgKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSk7CisgIH0KKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHRvdGFsX3NpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworICByZXR1cm4gdG90YWxfc2l6ZTsKK30KKwordm9pZCBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uOjpNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGNvbnN0IEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb24qIHNvdXJjZSA9IAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RHluYW1pY0Nhc3RUb0dlbmVyYXRlZDxjb25zdCBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uPigKKyAgICAgICAgICAmZnJvbSk7CisgIGlmIChzb3VyY2UgPT0gTlVMTCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlJlZmxlY3Rpb25PcHM6Ok1lcmdlKGZyb20sIHRoaXMpOworICB9IGVsc2UgeworICAgIE1lcmdlRnJvbSgqc291cmNlKTsKKyAgfQorfQorCit2b2lkIEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb246Ok1lcmdlRnJvbShjb25zdCBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIHBhdGhfLk1lcmdlRnJvbShmcm9tLnBhdGhfKTsKKyAgaWYgKGZyb20uX2hhc19iaXRzX1sxIC8gMzJdICYgKDB4ZmZ1IDw8ICgxICUgMzIpKSkgeworICAgIGlmIChmcm9tLmhhc19zb3VyY2VfZmlsZSgpKSB7CisgICAgICBzZXRfaGFzX3NvdXJjZV9maWxlKCk7CisgICAgICBzb3VyY2VfZmlsZV8uQXNzaWduV2l0aERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBmcm9tLnNvdXJjZV9maWxlXyk7CisgICAgfQorICAgIGlmIChmcm9tLmhhc19iZWdpbigpKSB7CisgICAgICBzZXRfYmVnaW4oZnJvbS5iZWdpbigpKTsKKyAgICB9CisgICAgaWYgKGZyb20uaGFzX2VuZCgpKSB7CisgICAgICBzZXRfZW5kKGZyb20uZW5kKCkpOworICAgIH0KKyAgfQorICBpZiAoZnJvbS5faW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+TWVyZ2VGcm9tKGZyb20udW5rbm93bl9maWVsZHMoKSk7CisgIH0KK30KKwordm9pZCBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uOjpDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCit2b2lkIEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb246OkNvcHlGcm9tKGNvbnN0IEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb24mIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCitib29sIEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb246OklzSW5pdGlhbGl6ZWQoKSBjb25zdCB7CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbjo6U3dhcChHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uKiBvdGhlcikgeworICBpZiAob3RoZXIgPT0gdGhpcykgcmV0dXJuOworICBJbnRlcm5hbFN3YXAob3RoZXIpOworfQordm9pZCBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uOjpJbnRlcm5hbFN3YXAoR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbiogb3RoZXIpIHsKKyAgcGF0aF8uVW5zYWZlQXJlbmFTd2FwKCZvdGhlci0+cGF0aF8pOworICBzb3VyY2VfZmlsZV8uU3dhcCgmb3RoZXItPnNvdXJjZV9maWxlXyk7CisgIHN0ZDo6c3dhcChiZWdpbl8sIG90aGVyLT5iZWdpbl8pOworICBzdGQ6OnN3YXAoZW5kXywgb3RoZXItPmVuZF8pOworICBzdGQ6OnN3YXAoX2hhc19iaXRzX1swXSwgb3RoZXItPl9oYXNfYml0c19bMF0pOworICBfaW50ZXJuYWxfbWV0YWRhdGFfLlN3YXAoJm90aGVyLT5faW50ZXJuYWxfbWV0YWRhdGFfKTsKKyAgc3RkOjpzd2FwKF9jYWNoZWRfc2l6ZV8sIG90aGVyLT5fY2FjaGVkX3NpemVfKTsKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uOjpHZXRNZXRhZGF0YSgpIGNvbnN0IHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgbWV0YWRhdGE7CisgIG1ldGFkYXRhLmRlc2NyaXB0b3IgPSBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uX2Rlc2NyaXB0b3JfOworICBtZXRhZGF0YS5yZWZsZWN0aW9uID0gR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbl9yZWZsZWN0aW9uXzsKKyAgcmV0dXJuIG1ldGFkYXRhOworfQorCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworI2lmICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCitjb25zdCBpbnQgR2VuZXJhdGVkQ29kZUluZm86OmtBbm5vdGF0aW9uRmllbGROdW1iZXI7CisjZW5kaWYgIC8vICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCisKK0dlbmVyYXRlZENvZGVJbmZvOjpHZW5lcmF0ZWRDb2RlSW5mbygpCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgeworICBTaGFyZWRDdG9yKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8pCit9CisKK3ZvaWQgR2VuZXJhdGVkQ29kZUluZm86OkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpIHsKK30KKworR2VuZXJhdGVkQ29kZUluZm86OkdlbmVyYXRlZENvZGVJbmZvKGNvbnN0IEdlbmVyYXRlZENvZGVJbmZvJiBmcm9tKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpLAorICAgIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgeworICBTaGFyZWRDdG9yKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvcHlfY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZENvZGVJbmZvKQorfQorCit2b2lkIEdlbmVyYXRlZENvZGVJbmZvOjpTaGFyZWRDdG9yKCkgeworICBfY2FjaGVkX3NpemVfID0gMDsKKyAgOjptZW1zZXQoX2hhc19iaXRzXywgMCwgc2l6ZW9mKF9oYXNfYml0c18pKTsKK30KKworR2VuZXJhdGVkQ29kZUluZm86On5HZW5lcmF0ZWRDb2RlSW5mbygpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGRlc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZENvZGVJbmZvKQorICBTaGFyZWREdG9yKCk7Cit9CisKK3ZvaWQgR2VuZXJhdGVkQ29kZUluZm86OlNoYXJlZER0b3IoKSB7CisgIGlmICh0aGlzICE9IGRlZmF1bHRfaW5zdGFuY2VfKSB7CisgIH0KK30KKwordm9pZCBHZW5lcmF0ZWRDb2RlSW5mbzo6U2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3QgeworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIEdlbmVyYXRlZENvZGVJbmZvOjpkZXNjcmlwdG9yKCkgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgcmV0dXJuIEdlbmVyYXRlZENvZGVJbmZvX2Rlc2NyaXB0b3JfOworfQorCitjb25zdCBHZW5lcmF0ZWRDb2RlSW5mbyYgR2VuZXJhdGVkQ29kZUluZm86OmRlZmF1bHRfaW5zdGFuY2UoKSB7CisgIGlmIChkZWZhdWx0X2luc3RhbmNlXyA9PSBOVUxMKSBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIHJldHVybiAqZGVmYXVsdF9pbnN0YW5jZV87Cit9CisKK0dlbmVyYXRlZENvZGVJbmZvKiBHZW5lcmF0ZWRDb2RlSW5mbzo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBOVUxMOworCitHZW5lcmF0ZWRDb2RlSW5mbyogR2VuZXJhdGVkQ29kZUluZm86Ok5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3QgeworICBHZW5lcmF0ZWRDb2RlSW5mbyogbiA9IG5ldyBHZW5lcmF0ZWRDb2RlSW5mbzsKKyAgaWYgKGFyZW5hICE9IE5VTEwpIHsKKyAgICBhcmVuYS0+T3duKG4pOworICB9CisgIHJldHVybiBuOworfQorCit2b2lkIEdlbmVyYXRlZENvZGVJbmZvOjpDbGVhcigpIHsKKyAgYW5ub3RhdGlvbl8uQ2xlYXIoKTsKKyAgOjptZW1zZXQoX2hhc19iaXRzXywgMCwgc2l6ZW9mKF9oYXNfYml0c18pKTsKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5DbGVhcigpOworICB9Cit9CisKK2Jvb2wgR2VuZXJhdGVkQ29kZUluZm86Ok1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCkgeworI2RlZmluZSBET18oRVhQUkVTU0lPTikgaWYgKCEoRVhQUkVTU0lPTikpIGdvdG8gZmFpbHVyZQorICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiB0YWc7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdGFydDpnb29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8pCisgIGZvciAoOzspIHsKKyAgICA6OnN0ZDo6cGFpcjwgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIsIGJvb2w+IHAgPSBpbnB1dC0+UmVhZFRhZ1dpdGhDdXRvZmYoMTI3KTsKKyAgICB0YWcgPSBwLmZpcnN0OworICAgIGlmICghcC5zZWNvbmQpIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgc3dpdGNoICg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnRmllbGROdW1iZXIodGFnKSkgeworICAgICAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRDb2RlSW5mby5Bbm5vdGF0aW9uIGFubm90YXRpb24gPSAxOworICAgICAgY2FzZSAxOiB7CisgICAgICAgIGlmICh0YWcgPT0gMTApIHsKKyAgICAgICAgICBET18oaW5wdXQtPkluY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCkpOworICAgICAgICAgcGFyc2VfbG9vcF9hbm5vdGF0aW9uOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZE1lc3NhZ2VOb1ZpcnR1YWxOb1JlY3Vyc2lvbkRlcHRoKAorICAgICAgICAgICAgICAgIGlucHV0LCBhZGRfYW5ub3RhdGlvbigpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygxMCkpIGdvdG8gcGFyc2VfbG9vcF9hbm5vdGF0aW9uOworICAgICAgICBpbnB1dC0+VW5zYWZlRGVjcmVtZW50UmVjdXJzaW9uRGVwdGgoKTsKKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RBdEVuZCgpKSBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBkZWZhdWx0OiB7CisgICAgICBoYW5kbGVfdW51c3VhbDoKKyAgICAgICAgaWYgKHRhZyA9PSAwIHx8CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnV2lyZVR5cGUodGFnKSA9PQorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0VORF9HUk9VUCkgeworICAgICAgICAgIGdvdG8gc3VjY2VzczsKKyAgICAgICAgfQorICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6U2tpcEZpZWxkKAorICAgICAgICAgICAgICBpbnB1dCwgdGFnLCBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CitzdWNjZXNzOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3VjY2Vzczpnb29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8pCisgIHJldHVybiB0cnVlOworZmFpbHVyZToKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX2ZhaWx1cmU6Z29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZENvZGVJbmZvKQorICByZXR1cm4gZmFsc2U7CisjdW5kZWYgRE9fCit9CisKK3ZvaWQgR2VuZXJhdGVkQ29kZUluZm86OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZENvZGVJbmZvKQorICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZENvZGVJbmZvLkFubm90YXRpb24gYW5ub3RhdGlvbiA9IDE7CisgIGZvciAodW5zaWduZWQgaW50IGkgPSAwLCBuID0gdGhpcy0+YW5ub3RhdGlvbl9zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgMSwgdGhpcy0+YW5ub3RhdGlvbihpKSwgb3V0cHV0KTsKKyAgfQorCisgIGlmIChfaW50ZXJuYWxfbWV0YWRhdGFfLmhhdmVfdW5rbm93bl9maWVsZHMoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25GaWVsZHMoCisgICAgICAgIHVua25vd25fZmllbGRzKCksIG91dHB1dCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9lbmQ6Z29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZENvZGVJbmZvKQorfQorCis6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBHZW5lcmF0ZWRDb2RlSW5mbzo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiB0YXJnZXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9zdGFydDpnb29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8pCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8uQW5ub3RhdGlvbiBhbm5vdGF0aW9uID0gMTsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT5hbm5vdGF0aW9uX3NpemUoKTsgaSA8IG47IGkrKykgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjoKKyAgICAgIFdyaXRlTWVzc2FnZU5vVmlydHVhbFRvQXJyYXkoCisgICAgICAgIDEsIHRoaXMtPmFubm90YXRpb24oaSksIHRhcmdldCk7CisgIH0KKworICBpZiAoX2ludGVybmFsX21ldGFkYXRhXy5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0OjpTZXJpYWxpemVVbmtub3duRmllbGRzVG9BcnJheSgKKyAgICAgICAgdW5rbm93bl9maWVsZHMoKSwgdGFyZ2V0KTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X2VuZDpnb29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8pCisgIHJldHVybiB0YXJnZXQ7Cit9CisKK2ludCBHZW5lcmF0ZWRDb2RlSW5mbzo6Qnl0ZVNpemUoKSBjb25zdCB7CisgIGludCB0b3RhbF9zaXplID0gMDsKKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZENvZGVJbmZvLkFubm90YXRpb24gYW5ub3RhdGlvbiA9IDE7CisgIHRvdGFsX3NpemUgKz0gMSAqIHRoaXMtPmFubm90YXRpb25fc2l6ZSgpOworICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPmFubm90YXRpb25fc2l6ZSgpOyBpKyspIHsKKyAgICB0b3RhbF9zaXplICs9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6TWVzc2FnZVNpemVOb1ZpcnR1YWwoCisgICAgICAgIHRoaXMtPmFubm90YXRpb24oaSkpOworICB9CisKKyAgaWYgKF9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdDo6Q29tcHV0ZVVua25vd25GaWVsZHNTaXplKAorICAgICAgICB1bmtub3duX2ZpZWxkcygpKTsKKyAgfQorICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gdG90YWxfc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7CisgIHJldHVybiB0b3RhbF9zaXplOworfQorCit2b2lkIEdlbmVyYXRlZENvZGVJbmZvOjpNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGNvbnN0IEdlbmVyYXRlZENvZGVJbmZvKiBzb3VyY2UgPSAKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkR5bmFtaWNDYXN0VG9HZW5lcmF0ZWQ8Y29uc3QgR2VuZXJhdGVkQ29kZUluZm8+KAorICAgICAgICAgICZmcm9tKTsKKyAgaWYgKHNvdXJjZSA9PSBOVUxMKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6UmVmbGVjdGlvbk9wczo6TWVyZ2UoZnJvbSwgdGhpcyk7CisgIH0gZWxzZSB7CisgICAgTWVyZ2VGcm9tKCpzb3VyY2UpOworICB9Cit9CisKK3ZvaWQgR2VuZXJhdGVkQ29kZUluZm86Ok1lcmdlRnJvbShjb25zdCBHZW5lcmF0ZWRDb2RlSW5mbyYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBhbm5vdGF0aW9uXy5NZXJnZUZyb20oZnJvbS5hbm5vdGF0aW9uXyk7CisgIGlmIChmcm9tLl9pbnRlcm5hbF9tZXRhZGF0YV8uaGF2ZV91bmtub3duX2ZpZWxkcygpKSB7CisgICAgbXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5NZXJnZUZyb20oZnJvbS51bmtub3duX2ZpZWxkcygpKTsKKyAgfQorfQorCit2b2lkIEdlbmVyYXRlZENvZGVJbmZvOjpDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCit2b2lkIEdlbmVyYXRlZENvZGVJbmZvOjpDb3B5RnJvbShjb25zdCBHZW5lcmF0ZWRDb2RlSW5mbyYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK2Jvb2wgR2VuZXJhdGVkQ29kZUluZm86OklzSW5pdGlhbGl6ZWQoKSBjb25zdCB7CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgR2VuZXJhdGVkQ29kZUluZm86OlN3YXAoR2VuZXJhdGVkQ29kZUluZm8qIG90aGVyKSB7CisgIGlmIChvdGhlciA9PSB0aGlzKSByZXR1cm47CisgIEludGVybmFsU3dhcChvdGhlcik7Cit9Cit2b2lkIEdlbmVyYXRlZENvZGVJbmZvOjpJbnRlcm5hbFN3YXAoR2VuZXJhdGVkQ29kZUluZm8qIG90aGVyKSB7CisgIGFubm90YXRpb25fLlVuc2FmZUFyZW5hU3dhcCgmb3RoZXItPmFubm90YXRpb25fKTsKKyAgc3RkOjpzd2FwKF9oYXNfYml0c19bMF0sIG90aGVyLT5faGFzX2JpdHNfWzBdKTsKKyAgX2ludGVybmFsX21ldGFkYXRhXy5Td2FwKCZvdGhlci0+X2ludGVybmFsX21ldGFkYXRhXyk7CisgIHN0ZDo6c3dhcChfY2FjaGVkX3NpemVfLCBvdGhlci0+X2NhY2hlZF9zaXplXyk7Cit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgR2VuZXJhdGVkQ29kZUluZm86OkdldE1ldGFkYXRhKCkgY29uc3QgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBtZXRhZGF0YTsKKyAgbWV0YWRhdGEuZGVzY3JpcHRvciA9IEdlbmVyYXRlZENvZGVJbmZvX2Rlc2NyaXB0b3JfOworICBtZXRhZGF0YS5yZWZsZWN0aW9uID0gR2VuZXJhdGVkQ29kZUluZm9fcmVmbGVjdGlvbl87CisgIHJldHVybiBtZXRhZGF0YTsKK30KKworI2lmIFBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworLy8gR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbgorCisvLyByZXBlYXRlZCBpbnQzMiBwYXRoID0gMSBbcGFja2VkID0gdHJ1ZV07CitpbnQgR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbjo6cGF0aF9zaXplKCkgY29uc3QgeworICByZXR1cm4gcGF0aF8uc2l6ZSgpOworfQordm9pZCBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uOjpjbGVhcl9wYXRoKCkgeworICBwYXRoXy5DbGVhcigpOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbjo6cGF0aChpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8uQW5ub3RhdGlvbi5wYXRoKQorICByZXR1cm4gcGF0aF8uR2V0KGluZGV4KTsKK30KKyB2b2lkIEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb246OnNldF9wYXRoKGludCBpbmRleCwgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiB2YWx1ZSkgeworICBwYXRoXy5TZXQoaW5kZXgsIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8uQW5ub3RhdGlvbi5wYXRoKQorfQorIHZvaWQgR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbjo6YWRkX3BhdGgoOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiB2YWx1ZSkgeworICBwYXRoXy5BZGQodmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRDb2RlSW5mby5Bbm5vdGF0aW9uLnBhdGgpCit9CisgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZEZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyID4mCitHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uOjpwYXRoKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8uQW5ub3RhdGlvbi5wYXRoKQorICByZXR1cm4gcGF0aF87Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZEZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyID4qCitHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uOjptdXRhYmxlX3BhdGgoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZENvZGVJbmZvLkFubm90YXRpb24ucGF0aCkKKyAgcmV0dXJuICZwYXRoXzsKK30KKworLy8gb3B0aW9uYWwgc3RyaW5nIHNvdXJjZV9maWxlID0gMjsKK2Jvb2wgR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbjo6aGFzX3NvdXJjZV9maWxlKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAydSkgIT0gMDsKK30KK3ZvaWQgR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbjo6c2V0X2hhc19zb3VyY2VfZmlsZSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAydTsKK30KK3ZvaWQgR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbjo6Y2xlYXJfaGFzX3NvdXJjZV9maWxlKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAydTsKK30KK3ZvaWQgR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbjo6Y2xlYXJfc291cmNlX2ZpbGUoKSB7CisgIHNvdXJjZV9maWxlXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGNsZWFyX2hhc19zb3VyY2VfZmlsZSgpOworfQorIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb246OnNvdXJjZV9maWxlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRDb2RlSW5mby5Bbm5vdGF0aW9uLnNvdXJjZV9maWxlKQorICByZXR1cm4gc291cmNlX2ZpbGVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb246OnNldF9zb3VyY2VfZmlsZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBzZXRfaGFzX3NvdXJjZV9maWxlKCk7CisgIHNvdXJjZV9maWxlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRDb2RlSW5mby5Bbm5vdGF0aW9uLnNvdXJjZV9maWxlKQorfQorIHZvaWQgR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbjo6c2V0X3NvdXJjZV9maWxlKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfc291cmNlX2ZpbGUoKTsKKyAgc291cmNlX2ZpbGVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8uQW5ub3RhdGlvbi5zb3VyY2VfZmlsZSkKK30KKyB2b2lkIEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb246OnNldF9zb3VyY2VfZmlsZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19zb3VyY2VfZmlsZSgpOworICBzb3VyY2VfZmlsZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZENvZGVJbmZvLkFubm90YXRpb24uc291cmNlX2ZpbGUpCit9CisgOjpzdGQ6OnN0cmluZyogR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbjo6bXV0YWJsZV9zb3VyY2VfZmlsZSgpIHsKKyAgc2V0X2hhc19zb3VyY2VfZmlsZSgpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8uQW5ub3RhdGlvbi5zb3VyY2VfZmlsZSkKKyAgcmV0dXJuIHNvdXJjZV9maWxlXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIDo6c3RkOjpzdHJpbmcqIEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb246OnJlbGVhc2Vfc291cmNlX2ZpbGUoKSB7CisgIGNsZWFyX2hhc19zb3VyY2VfZmlsZSgpOworICByZXR1cm4gc291cmNlX2ZpbGVfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uOjpzZXRfYWxsb2NhdGVkX3NvdXJjZV9maWxlKDo6c3RkOjpzdHJpbmcqIHNvdXJjZV9maWxlKSB7CisgIGlmIChzb3VyY2VfZmlsZSAhPSBOVUxMKSB7CisgICAgc2V0X2hhc19zb3VyY2VfZmlsZSgpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19zb3VyY2VfZmlsZSgpOworICB9CisgIHNvdXJjZV9maWxlXy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgc291cmNlX2ZpbGUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8uQW5ub3RhdGlvbi5zb3VyY2VfZmlsZSkKK30KKworLy8gb3B0aW9uYWwgaW50MzIgYmVnaW4gPSAzOworYm9vbCBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uOjpoYXNfYmVnaW4oKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDR1KSAhPSAwOworfQordm9pZCBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uOjpzZXRfaGFzX2JlZ2luKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDR1OworfQordm9pZCBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uOjpjbGVhcl9oYXNfYmVnaW4oKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDR1OworfQordm9pZCBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uOjpjbGVhcl9iZWdpbigpIHsKKyAgYmVnaW5fID0gMDsKKyAgY2xlYXJfaGFzX2JlZ2luKCk7Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uOjpiZWdpbigpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8uQW5ub3RhdGlvbi5iZWdpbikKKyAgcmV0dXJuIGJlZ2luXzsKK30KKyB2b2lkIEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb246OnNldF9iZWdpbig6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKSB7CisgIHNldF9oYXNfYmVnaW4oKTsKKyAgYmVnaW5fID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZENvZGVJbmZvLkFubm90YXRpb24uYmVnaW4pCit9CisKKy8vIG9wdGlvbmFsIGludDMyIGVuZCA9IDQ7Citib29sIEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb246Omhhc19lbmQoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDh1KSAhPSAwOworfQordm9pZCBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uOjpzZXRfaGFzX2VuZCgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDA4dTsKK30KK3ZvaWQgR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbjo6Y2xlYXJfaGFzX2VuZCgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwOHU7Cit9Cit2b2lkIEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb246OmNsZWFyX2VuZCgpIHsKKyAgZW5kXyA9IDA7CisgIGNsZWFyX2hhc19lbmQoKTsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb246OmVuZCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8uQW5ub3RhdGlvbi5lbmQpCisgIHJldHVybiBlbmRfOworfQorIHZvaWQgR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbjo6c2V0X2VuZCg6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKSB7CisgIHNldF9oYXNfZW5kKCk7CisgIGVuZF8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8uQW5ub3RhdGlvbi5lbmQpCit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gR2VuZXJhdGVkQ29kZUluZm8KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRDb2RlSW5mby5Bbm5vdGF0aW9uIGFubm90YXRpb24gPSAxOworaW50IEdlbmVyYXRlZENvZGVJbmZvOjphbm5vdGF0aW9uX3NpemUoKSBjb25zdCB7CisgIHJldHVybiBhbm5vdGF0aW9uXy5zaXplKCk7Cit9Cit2b2lkIEdlbmVyYXRlZENvZGVJbmZvOjpjbGVhcl9hbm5vdGF0aW9uKCkgeworICBhbm5vdGF0aW9uXy5DbGVhcigpOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uJiBHZW5lcmF0ZWRDb2RlSW5mbzo6YW5ub3RhdGlvbihpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8uYW5ub3RhdGlvbikKKyAgcmV0dXJuIGFubm90YXRpb25fLkdldChpbmRleCk7Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6OkdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb24qIEdlbmVyYXRlZENvZGVJbmZvOjptdXRhYmxlX2Fubm90YXRpb24oaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRDb2RlSW5mby5hbm5vdGF0aW9uKQorICByZXR1cm4gYW5ub3RhdGlvbl8uTXV0YWJsZShpbmRleCk7Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6OkdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb24qIEdlbmVyYXRlZENvZGVJbmZvOjphZGRfYW5ub3RhdGlvbigpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8uYW5ub3RhdGlvbikKKyAgcmV0dXJuIGFubm90YXRpb25fLkFkZCgpOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb24gPioKK0dlbmVyYXRlZENvZGVJbmZvOjptdXRhYmxlX2Fubm90YXRpb24oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZENvZGVJbmZvLmFubm90YXRpb24pCisgIHJldHVybiAmYW5ub3RhdGlvbl87Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6R2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbiA+JgorR2VuZXJhdGVkQ29kZUluZm86OmFubm90YXRpb24oKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRDb2RlSW5mby5hbm5vdGF0aW9uKQorICByZXR1cm4gYW5ub3RhdGlvbl87Cit9CisKKyNlbmRpZiAgLy8gUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisKKy8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChuYW1lc3BhY2Vfc2NvcGUpCisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZ2xvYmFsX3Njb3BlKQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZmUwN2JmCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmgKQEAgLTAsMCArMSw3Njc5IEBACisvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQorLy8gc291cmNlOiBnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90bworCisjaWZuZGVmIFBST1RPQlVGX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvX19JTkNMVURFRAorI2RlZmluZSBQUk9UT0JVRl9nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90b19fSU5DTFVERUQKKworI2luY2x1ZGUgPHN0cmluZz4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKworI2lmIEdPT0dMRV9QUk9UT0JVRl9WRVJTSU9OIDwgMzAwMDAwMAorI2Vycm9yIFRoaXMgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IGEgbmV3ZXIgdmVyc2lvbiBvZiBwcm90b2Mgd2hpY2ggaXMKKyNlcnJvciBpbmNvbXBhdGlibGUgd2l0aCB5b3VyIFByb3RvY29sIEJ1ZmZlciBoZWFkZXJzLiAgUGxlYXNlIHVwZGF0ZQorI2Vycm9yIHlvdXIgaGVhZGVycy4KKyNlbmRpZgorI2lmIDMwMDAwMDAgPCBHT09HTEVfUFJPVE9CVUZfTUlOX1BST1RPQ19WRVJTSU9OCisjZXJyb3IgVGhpcyBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgYW4gb2xkZXIgdmVyc2lvbiBvZiBwcm90b2Mgd2hpY2ggaXMKKyNlcnJvciBpbmNvbXBhdGlibGUgd2l0aCB5b3VyIFByb3RvY29sIEJ1ZmZlciBoZWFkZXJzLiAgUGxlYXNlCisjZXJyb3IgcmVnZW5lcmF0ZSB0aGlzIGZpbGUgd2l0aCBhIG5ld2VyIHZlcnNpb24gb2YgcHJvdG9jLgorI2VuZGlmCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvYXJlbmEuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvYXJlbmFzdHJpbmcuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX21lc3NhZ2VfdXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tZXRhZGF0YS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tZXNzYWdlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3JlcGVhdGVkX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2V4dGVuc2lvbl9zZXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX2VudW1fcmVmbGVjdGlvbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bmtub3duX2ZpZWxkX3NldC5oPgorLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGluY2x1ZGVzKQorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKKy8vIEludGVybmFsIGltcGxlbWVudGF0aW9uIGRldGFpbCAtLSBkbyBub3QgY2FsbCB0aGVzZS4KK3ZvaWQgTElCUFJPVE9CVUZfRVhQT1JUIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKK3ZvaWQgcHJvdG9idWZfQXNzaWduRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOwordm9pZCBwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKworY2xhc3MgRGVzY3JpcHRvclByb3RvOworY2xhc3MgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOworY2xhc3MgRGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2U7CitjbGFzcyBFbnVtRGVzY3JpcHRvclByb3RvOworY2xhc3MgRW51bU9wdGlvbnM7CitjbGFzcyBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG87CitjbGFzcyBFbnVtVmFsdWVPcHRpb25zOworY2xhc3MgRmllbGREZXNjcmlwdG9yUHJvdG87CitjbGFzcyBGaWVsZE9wdGlvbnM7CitjbGFzcyBGaWxlRGVzY3JpcHRvclByb3RvOworY2xhc3MgRmlsZURlc2NyaXB0b3JTZXQ7CitjbGFzcyBGaWxlT3B0aW9uczsKK2NsYXNzIEdlbmVyYXRlZENvZGVJbmZvOworY2xhc3MgR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbjsKK2NsYXNzIE1lc3NhZ2VPcHRpb25zOworY2xhc3MgTWV0aG9kRGVzY3JpcHRvclByb3RvOworY2xhc3MgTWV0aG9kT3B0aW9uczsKK2NsYXNzIE9uZW9mRGVzY3JpcHRvclByb3RvOworY2xhc3MgU2VydmljZURlc2NyaXB0b3JQcm90bzsKK2NsYXNzIFNlcnZpY2VPcHRpb25zOworY2xhc3MgU291cmNlQ29kZUluZm87CitjbGFzcyBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjsKK2NsYXNzIFVuaW50ZXJwcmV0ZWRPcHRpb247CitjbGFzcyBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OworCitlbnVtIEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGUgeworICBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX1RZUEVfRE9VQkxFID0gMSwKKyAgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9UWVBFX0ZMT0FUID0gMiwKKyAgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9UWVBFX0lOVDY0ID0gMywKKyAgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9UWVBFX1VJTlQ2NCA9IDQsCisgIEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfVFlQRV9JTlQzMiA9IDUsCisgIEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfVFlQRV9GSVhFRDY0ID0gNiwKKyAgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9UWVBFX0ZJWEVEMzIgPSA3LAorICBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX1RZUEVfQk9PTCA9IDgsCisgIEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfVFlQRV9TVFJJTkcgPSA5LAorICBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX1RZUEVfR1JPVVAgPSAxMCwKKyAgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9UWVBFX01FU1NBR0UgPSAxMSwKKyAgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9UWVBFX0JZVEVTID0gMTIsCisgIEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfVFlQRV9VSU5UMzIgPSAxMywKKyAgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9UWVBFX0VOVU0gPSAxNCwKKyAgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9UWVBFX1NGSVhFRDMyID0gMTUsCisgIEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfVFlQRV9TRklYRUQ2NCA9IDE2LAorICBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX1RZUEVfU0lOVDMyID0gMTcsCisgIEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfVFlQRV9TSU5UNjQgPSAxOAorfTsKK0xJQlBST1RPQlVGX0VYUE9SVCBib29sIEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfSXNWYWxpZChpbnQgdmFsdWUpOworY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZSBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX1R5cGVfTUlOID0gRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9UWVBFX0RPVUJMRTsKK2NvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGUgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9UeXBlX01BWCA9IEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfVFlQRV9TSU5UNjQ7Citjb25zdCBpbnQgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9UeXBlX0FSUkFZU0laRSA9IEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfVHlwZV9NQVggKyAxOworCitMSUJQUk9UT0JVRl9FWFBPUlQgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvciogRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9kZXNjcmlwdG9yKCk7CitpbmxpbmUgY29uc3QgOjpzdGQ6OnN0cmluZyYgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9OYW1lKEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGUgdmFsdWUpIHsKKyAgcmV0dXJuIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6Ok5hbWVPZkVudW0oCisgICAgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9kZXNjcmlwdG9yKCksIHZhbHVlKTsKK30KK2lubGluZSBib29sIEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfUGFyc2UoCisgICAgY29uc3QgOjpzdGQ6OnN0cmluZyYgbmFtZSwgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZSogdmFsdWUpIHsKKyAgcmV0dXJuIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlBhcnNlTmFtZWRFbnVtPEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGU+KAorICAgIEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfZGVzY3JpcHRvcigpLCBuYW1lLCB2YWx1ZSk7Cit9CitlbnVtIEZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsIHsKKyAgRmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWxfTEFCRUxfT1BUSU9OQUwgPSAxLAorICBGaWVsZERlc2NyaXB0b3JQcm90b19MYWJlbF9MQUJFTF9SRVFVSVJFRCA9IDIsCisgIEZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsX0xBQkVMX1JFUEVBVEVEID0gMworfTsKK0xJQlBST1RPQlVGX0VYUE9SVCBib29sIEZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsX0lzVmFsaWQoaW50IHZhbHVlKTsKK2NvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsIEZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsX0xhYmVsX01JTiA9IEZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsX0xBQkVMX09QVElPTkFMOworY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWwgRmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWxfTGFiZWxfTUFYID0gRmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWxfTEFCRUxfUkVQRUFURUQ7Citjb25zdCBpbnQgRmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWxfTGFiZWxfQVJSQVlTSVpFID0gRmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWxfTGFiZWxfTUFYICsgMTsKKworTElCUFJPVE9CVUZfRVhQT1JUIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bURlc2NyaXB0b3IqIEZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsX2Rlc2NyaXB0b3IoKTsKK2lubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBGaWVsZERlc2NyaXB0b3JQcm90b19MYWJlbF9OYW1lKEZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsIHZhbHVlKSB7CisgIHJldHVybiA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpOYW1lT2ZFbnVtKAorICAgIEZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsX2Rlc2NyaXB0b3IoKSwgdmFsdWUpOworfQoraW5saW5lIGJvb2wgRmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWxfUGFyc2UoCisgICAgY29uc3QgOjpzdGQ6OnN0cmluZyYgbmFtZSwgRmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWwqIHZhbHVlKSB7CisgIHJldHVybiA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpQYXJzZU5hbWVkRW51bTxGaWVsZERlc2NyaXB0b3JQcm90b19MYWJlbD4oCisgICAgRmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWxfZGVzY3JpcHRvcigpLCBuYW1lLCB2YWx1ZSk7Cit9CitlbnVtIEZpbGVPcHRpb25zX09wdGltaXplTW9kZSB7CisgIEZpbGVPcHRpb25zX09wdGltaXplTW9kZV9TUEVFRCA9IDEsCisgIEZpbGVPcHRpb25zX09wdGltaXplTW9kZV9DT0RFX1NJWkUgPSAyLAorICBGaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGVfTElURV9SVU5USU1FID0gMworfTsKK0xJQlBST1RPQlVGX0VYUE9SVCBib29sIEZpbGVPcHRpb25zX09wdGltaXplTW9kZV9Jc1ZhbGlkKGludCB2YWx1ZSk7Citjb25zdCBGaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGUgRmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlX09wdGltaXplTW9kZV9NSU4gPSBGaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGVfU1BFRUQ7Citjb25zdCBGaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGUgRmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlX09wdGltaXplTW9kZV9NQVggPSBGaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGVfTElURV9SVU5USU1FOworY29uc3QgaW50IEZpbGVPcHRpb25zX09wdGltaXplTW9kZV9PcHRpbWl6ZU1vZGVfQVJSQVlTSVpFID0gRmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlX09wdGltaXplTW9kZV9NQVggKyAxOworCitMSUJQUk9UT0JVRl9FWFBPUlQgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvciogRmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlX2Rlc2NyaXB0b3IoKTsKK2lubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBGaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGVfTmFtZShGaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGUgdmFsdWUpIHsKKyAgcmV0dXJuIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6Ok5hbWVPZkVudW0oCisgICAgRmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlX2Rlc2NyaXB0b3IoKSwgdmFsdWUpOworfQoraW5saW5lIGJvb2wgRmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlX1BhcnNlKAorICAgIGNvbnN0IDo6c3RkOjpzdHJpbmcmIG5hbWUsIEZpbGVPcHRpb25zX09wdGltaXplTW9kZSogdmFsdWUpIHsKKyAgcmV0dXJuIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlBhcnNlTmFtZWRFbnVtPEZpbGVPcHRpb25zX09wdGltaXplTW9kZT4oCisgICAgRmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlX2Rlc2NyaXB0b3IoKSwgbmFtZSwgdmFsdWUpOworfQorZW51bSBGaWVsZE9wdGlvbnNfQ1R5cGUgeworICBGaWVsZE9wdGlvbnNfQ1R5cGVfU1RSSU5HID0gMCwKKyAgRmllbGRPcHRpb25zX0NUeXBlX0NPUkQgPSAxLAorICBGaWVsZE9wdGlvbnNfQ1R5cGVfU1RSSU5HX1BJRUNFID0gMgorfTsKK0xJQlBST1RPQlVGX0VYUE9SVCBib29sIEZpZWxkT3B0aW9uc19DVHlwZV9Jc1ZhbGlkKGludCB2YWx1ZSk7Citjb25zdCBGaWVsZE9wdGlvbnNfQ1R5cGUgRmllbGRPcHRpb25zX0NUeXBlX0NUeXBlX01JTiA9IEZpZWxkT3B0aW9uc19DVHlwZV9TVFJJTkc7Citjb25zdCBGaWVsZE9wdGlvbnNfQ1R5cGUgRmllbGRPcHRpb25zX0NUeXBlX0NUeXBlX01BWCA9IEZpZWxkT3B0aW9uc19DVHlwZV9TVFJJTkdfUElFQ0U7Citjb25zdCBpbnQgRmllbGRPcHRpb25zX0NUeXBlX0NUeXBlX0FSUkFZU0laRSA9IEZpZWxkT3B0aW9uc19DVHlwZV9DVHlwZV9NQVggKyAxOworCitMSUJQUk9UT0JVRl9FWFBPUlQgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvciogRmllbGRPcHRpb25zX0NUeXBlX2Rlc2NyaXB0b3IoKTsKK2lubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBGaWVsZE9wdGlvbnNfQ1R5cGVfTmFtZShGaWVsZE9wdGlvbnNfQ1R5cGUgdmFsdWUpIHsKKyAgcmV0dXJuIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6Ok5hbWVPZkVudW0oCisgICAgRmllbGRPcHRpb25zX0NUeXBlX2Rlc2NyaXB0b3IoKSwgdmFsdWUpOworfQoraW5saW5lIGJvb2wgRmllbGRPcHRpb25zX0NUeXBlX1BhcnNlKAorICAgIGNvbnN0IDo6c3RkOjpzdHJpbmcmIG5hbWUsIEZpZWxkT3B0aW9uc19DVHlwZSogdmFsdWUpIHsKKyAgcmV0dXJuIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlBhcnNlTmFtZWRFbnVtPEZpZWxkT3B0aW9uc19DVHlwZT4oCisgICAgRmllbGRPcHRpb25zX0NUeXBlX2Rlc2NyaXB0b3IoKSwgbmFtZSwgdmFsdWUpOworfQorZW51bSBGaWVsZE9wdGlvbnNfSlNUeXBlIHsKKyAgRmllbGRPcHRpb25zX0pTVHlwZV9KU19OT1JNQUwgPSAwLAorICBGaWVsZE9wdGlvbnNfSlNUeXBlX0pTX1NUUklORyA9IDEsCisgIEZpZWxkT3B0aW9uc19KU1R5cGVfSlNfTlVNQkVSID0gMgorfTsKK0xJQlBST1RPQlVGX0VYUE9SVCBib29sIEZpZWxkT3B0aW9uc19KU1R5cGVfSXNWYWxpZChpbnQgdmFsdWUpOworY29uc3QgRmllbGRPcHRpb25zX0pTVHlwZSBGaWVsZE9wdGlvbnNfSlNUeXBlX0pTVHlwZV9NSU4gPSBGaWVsZE9wdGlvbnNfSlNUeXBlX0pTX05PUk1BTDsKK2NvbnN0IEZpZWxkT3B0aW9uc19KU1R5cGUgRmllbGRPcHRpb25zX0pTVHlwZV9KU1R5cGVfTUFYID0gRmllbGRPcHRpb25zX0pTVHlwZV9KU19OVU1CRVI7Citjb25zdCBpbnQgRmllbGRPcHRpb25zX0pTVHlwZV9KU1R5cGVfQVJSQVlTSVpFID0gRmllbGRPcHRpb25zX0pTVHlwZV9KU1R5cGVfTUFYICsgMTsKKworTElCUFJPVE9CVUZfRVhQT1JUIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bURlc2NyaXB0b3IqIEZpZWxkT3B0aW9uc19KU1R5cGVfZGVzY3JpcHRvcigpOworaW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEZpZWxkT3B0aW9uc19KU1R5cGVfTmFtZShGaWVsZE9wdGlvbnNfSlNUeXBlIHZhbHVlKSB7CisgIHJldHVybiA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpOYW1lT2ZFbnVtKAorICAgIEZpZWxkT3B0aW9uc19KU1R5cGVfZGVzY3JpcHRvcigpLCB2YWx1ZSk7Cit9CitpbmxpbmUgYm9vbCBGaWVsZE9wdGlvbnNfSlNUeXBlX1BhcnNlKAorICAgIGNvbnN0IDo6c3RkOjpzdHJpbmcmIG5hbWUsIEZpZWxkT3B0aW9uc19KU1R5cGUqIHZhbHVlKSB7CisgIHJldHVybiA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpQYXJzZU5hbWVkRW51bTxGaWVsZE9wdGlvbnNfSlNUeXBlPigKKyAgICBGaWVsZE9wdGlvbnNfSlNUeXBlX2Rlc2NyaXB0b3IoKSwgbmFtZSwgdmFsdWUpOworfQorLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgRmlsZURlc2NyaXB0b3JTZXQgOiBwdWJsaWMgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlIHsKKyBwdWJsaWM6CisgIEZpbGVEZXNjcmlwdG9yU2V0KCk7CisgIHZpcnR1YWwgfkZpbGVEZXNjcmlwdG9yU2V0KCk7CisKKyAgRmlsZURlc2NyaXB0b3JTZXQoY29uc3QgRmlsZURlc2NyaXB0b3JTZXQmIGZyb20pOworCisgIGlubGluZSBGaWxlRGVzY3JpcHRvclNldCYgb3BlcmF0b3I9KGNvbnN0IEZpbGVEZXNjcmlwdG9yU2V0JiBmcm9tKSB7CisgICAgQ29weUZyb20oZnJvbSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgaW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcygpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy51bmtub3duX2ZpZWxkcygpOworICB9CisKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5rbm93bkZpZWxkU2V0KiBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLm11dGFibGVfdW5rbm93bl9maWVsZHMoKTsKKyAgfQorCisgIHN0YXRpYyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIGRlc2NyaXB0b3IoKTsKKyAgc3RhdGljIGNvbnN0IEZpbGVEZXNjcmlwdG9yU2V0JiBkZWZhdWx0X2luc3RhbmNlKCk7CisKKyAgdm9pZCBTd2FwKEZpbGVEZXNjcmlwdG9yU2V0KiBvdGhlcik7CisKKyAgLy8gaW1wbGVtZW50cyBNZXNzYWdlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBpbmxpbmUgRmlsZURlc2NyaXB0b3JTZXQqIE5ldygpIGNvbnN0IHsgcmV0dXJuIE5ldyhOVUxMKTsgfQorCisgIEZpbGVEZXNjcmlwdG9yU2V0KiBOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0OworICB2b2lkIENvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgQ29weUZyb20oY29uc3QgRmlsZURlc2NyaXB0b3JTZXQmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCBGaWxlRGVzY3JpcHRvclNldCYgZnJvbSk7CisgIHZvaWQgQ2xlYXIoKTsKKyAgYm9vbCBJc0luaXRpYWxpemVkKCkgY29uc3Q7CisKKyAgaW50IEJ5dGVTaXplKCkgY29uc3Q7CisgIGJvb2wgTWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpOworICB2b2lkIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIG91dHB1dCkgY29uc3Q7CisgIGludCBHZXRDYWNoZWRTaXplKCkgY29uc3QgeyByZXR1cm4gX2NhY2hlZF9zaXplXzsgfQorICBwcml2YXRlOgorICB2b2lkIFNoYXJlZEN0b3IoKTsKKyAgdm9pZCBTaGFyZWREdG9yKCk7CisgIHZvaWQgU2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3Q7CisgIHZvaWQgSW50ZXJuYWxTd2FwKEZpbGVEZXNjcmlwdG9yU2V0KiBvdGhlcik7CisgIHByaXZhdGU6CisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYU5vVmlydHVhbCgpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5hcmVuYSgpOworICB9CisgIGlubGluZSB2b2lkKiBNYXliZUFyZW5hUHRyKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnJhd19hcmVuYV9wdHIoKTsKKyAgfQorICBwdWJsaWM6CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBHZXRNZXRhZGF0YSgpIGNvbnN0OworCisgIC8vIG5lc3RlZCB0eXBlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gYWNjZXNzb3JzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZSA9IDE7CisgIGludCBmaWxlX3NpemUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9maWxlKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga0ZpbGVGaWVsZE51bWJlciA9IDE7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZURlc2NyaXB0b3JQcm90byYgZmlsZShpbnQgaW5kZXgpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVEZXNjcmlwdG9yUHJvdG8qIG11dGFibGVfZmlsZShpbnQgaW5kZXgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVEZXNjcmlwdG9yUHJvdG8qIGFkZF9maWxlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlRGVzY3JpcHRvclByb3RvID4qCisgICAgICBtdXRhYmxlX2ZpbGUoKTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVEZXNjcmlwdG9yUHJvdG8gPiYKKyAgICAgIGZpbGUoKSBjb25zdDsKKworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yU2V0KQorIHByaXZhdGU6CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6SW50ZXJuYWxNZXRhZGF0YVdpdGhBcmVuYSBfaW50ZXJuYWxfbWV0YWRhdGFfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiBfaGFzX2JpdHNfWzFdOworICBtdXRhYmxlIGludCBfY2FjaGVkX3NpemVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZURlc2NyaXB0b3JQcm90byA+IGZpbGVfOworICBmcmllbmQgdm9pZCBMSUJQUk9UT0JVRl9FWFBPUlQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworCisgIHZvaWQgSW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIHN0YXRpYyBGaWxlRGVzY3JpcHRvclNldCogZGVmYXVsdF9pbnN0YW5jZV87Cit9OworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgRmlsZURlc2NyaXB0b3JQcm90byA6IHB1YmxpYyA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UgeworIHB1YmxpYzoKKyAgRmlsZURlc2NyaXB0b3JQcm90bygpOworICB2aXJ0dWFsIH5GaWxlRGVzY3JpcHRvclByb3RvKCk7CisKKyAgRmlsZURlc2NyaXB0b3JQcm90byhjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvJiBmcm9tKTsKKworICBpbmxpbmUgRmlsZURlc2NyaXB0b3JQcm90byYgb3BlcmF0b3I9KGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8mIGZyb20pIHsKKyAgICBDb3B5RnJvbShmcm9tKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworICBpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpVbmtub3duRmllbGRTZXQmIHVua25vd25fZmllbGRzKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnVua25vd25fZmllbGRzKCk7CisgIH0KKworICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpVbmtub3duRmllbGRTZXQqIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ubXV0YWJsZV91bmtub3duX2ZpZWxkcygpOworICB9CisKKyAgc3RhdGljIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogZGVzY3JpcHRvcigpOworICBzdGF0aWMgY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byYgZGVmYXVsdF9pbnN0YW5jZSgpOworCisgIHZvaWQgU3dhcChGaWxlRGVzY3JpcHRvclByb3RvKiBvdGhlcik7CisKKyAgLy8gaW1wbGVtZW50cyBNZXNzYWdlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBpbmxpbmUgRmlsZURlc2NyaXB0b3JQcm90byogTmV3KCkgY29uc3QgeyByZXR1cm4gTmV3KE5VTEwpOyB9CisKKyAgRmlsZURlc2NyaXB0b3JQcm90byogTmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdDsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIENvcHlGcm9tKGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8mIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvJiBmcm9tKTsKKyAgdm9pZCBDbGVhcigpOworICBib29sIElzSW5pdGlhbGl6ZWQoKSBjb25zdDsKKworICBpbnQgQnl0ZVNpemUoKSBjb25zdDsKKyAgYm9vbCBNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCk7CisgIHZvaWQgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogb3V0cHV0KSBjb25zdDsKKyAgaW50IEdldENhY2hlZFNpemUoKSBjb25zdCB7IHJldHVybiBfY2FjaGVkX3NpemVfOyB9CisgIHByaXZhdGU6CisgIHZvaWQgU2hhcmVkQ3RvcigpOworICB2b2lkIFNoYXJlZER0b3IoKTsKKyAgdm9pZCBTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdDsKKyAgdm9pZCBJbnRlcm5hbFN3YXAoRmlsZURlc2NyaXB0b3JQcm90byogb3RoZXIpOworICBwcml2YXRlOgorICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogR2V0QXJlbmFOb1ZpcnR1YWwoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8uYXJlbmEoKTsKKyAgfQorICBpbmxpbmUgdm9pZCogTWF5YmVBcmVuYVB0cigpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5yYXdfYXJlbmFfcHRyKCk7CisgIH0KKyAgcHVibGljOgorCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgR2V0TWV0YWRhdGEoKSBjb25zdDsKKworICAvLyBuZXN0ZWQgdHlwZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIGFjY2Vzc29ycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICBib29sIGhhc19uYW1lKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfbmFtZSgpOworICBzdGF0aWMgY29uc3QgaW50IGtOYW1lRmllbGROdW1iZXIgPSAxOworICBjb25zdCA6OnN0ZDo6c3RyaW5nJiBuYW1lKCkgY29uc3Q7CisgIHZvaWQgc2V0X25hbWUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpOworICB2b2lkIHNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlKTsKKyAgdm9pZCBzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpOworICA6OnN0ZDo6c3RyaW5nKiBtdXRhYmxlX25hbWUoKTsKKyAgOjpzdGQ6OnN0cmluZyogcmVsZWFzZV9uYW1lKCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF9uYW1lKDo6c3RkOjpzdHJpbmcqIG5hbWUpOworCisgIC8vIG9wdGlvbmFsIHN0cmluZyBwYWNrYWdlID0gMjsKKyAgYm9vbCBoYXNfcGFja2FnZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX3BhY2thZ2UoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrUGFja2FnZUZpZWxkTnVtYmVyID0gMjsKKyAgY29uc3QgOjpzdGQ6OnN0cmluZyYgcGFja2FnZSgpIGNvbnN0OworICB2b2lkIHNldF9wYWNrYWdlKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKTsKKyAgdm9pZCBzZXRfcGFja2FnZShjb25zdCBjaGFyKiB2YWx1ZSk7CisgIHZvaWQgc2V0X3BhY2thZ2UoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKTsKKyAgOjpzdGQ6OnN0cmluZyogbXV0YWJsZV9wYWNrYWdlKCk7CisgIDo6c3RkOjpzdHJpbmcqIHJlbGVhc2VfcGFja2FnZSgpOworICB2b2lkIHNldF9hbGxvY2F0ZWRfcGFja2FnZSg6OnN0ZDo6c3RyaW5nKiBwYWNrYWdlKTsKKworICAvLyByZXBlYXRlZCBzdHJpbmcgZGVwZW5kZW5jeSA9IDM7CisgIGludCBkZXBlbmRlbmN5X3NpemUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9kZXBlbmRlbmN5KCk7CisgIHN0YXRpYyBjb25zdCBpbnQga0RlcGVuZGVuY3lGaWVsZE51bWJlciA9IDM7CisgIGNvbnN0IDo6c3RkOjpzdHJpbmcmIGRlcGVuZGVuY3koaW50IGluZGV4KSBjb25zdDsKKyAgOjpzdGQ6OnN0cmluZyogbXV0YWJsZV9kZXBlbmRlbmN5KGludCBpbmRleCk7CisgIHZvaWQgc2V0X2RlcGVuZGVuY3koaW50IGluZGV4LCBjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X2RlcGVuZGVuY3koaW50IGluZGV4LCBjb25zdCBjaGFyKiB2YWx1ZSk7CisgIHZvaWQgc2V0X2RlcGVuZGVuY3koaW50IGluZGV4LCBjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpOworICA6OnN0ZDo6c3RyaW5nKiBhZGRfZGVwZW5kZW5jeSgpOworICB2b2lkIGFkZF9kZXBlbmRlbmN5KGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKTsKKyAgdm9pZCBhZGRfZGVwZW5kZW5jeShjb25zdCBjaGFyKiB2YWx1ZSk7CisgIHZvaWQgYWRkX2RlcGVuZGVuY3koY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6OnN0ZDo6c3RyaW5nPiYgZGVwZW5kZW5jeSgpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6c3RkOjpzdHJpbmc+KiBtdXRhYmxlX2RlcGVuZGVuY3koKTsKKworICAvLyByZXBlYXRlZCBpbnQzMiBwdWJsaWNfZGVwZW5kZW5jeSA9IDEwOworICBpbnQgcHVibGljX2RlcGVuZGVuY3lfc2l6ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX3B1YmxpY19kZXBlbmRlbmN5KCk7CisgIHN0YXRpYyBjb25zdCBpbnQga1B1YmxpY0RlcGVuZGVuY3lGaWVsZE51bWJlciA9IDEwOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHB1YmxpY19kZXBlbmRlbmN5KGludCBpbmRleCkgY29uc3Q7CisgIHZvaWQgc2V0X3B1YmxpY19kZXBlbmRlbmN5KGludCBpbmRleCwgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiB2YWx1ZSk7CisgIHZvaWQgYWRkX3B1YmxpY19kZXBlbmRlbmN5KDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgdmFsdWUpOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgPiYKKyAgICAgIHB1YmxpY19kZXBlbmRlbmN5KCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiA+KgorICAgICAgbXV0YWJsZV9wdWJsaWNfZGVwZW5kZW5jeSgpOworCisgIC8vIHJlcGVhdGVkIGludDMyIHdlYWtfZGVwZW5kZW5jeSA9IDExOworICBpbnQgd2Vha19kZXBlbmRlbmN5X3NpemUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl93ZWFrX2RlcGVuZGVuY3koKTsKKyAgc3RhdGljIGNvbnN0IGludCBrV2Vha0RlcGVuZGVuY3lGaWVsZE51bWJlciA9IDExOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHdlYWtfZGVwZW5kZW5jeShpbnQgaW5kZXgpIGNvbnN0OworICB2b2lkIHNldF93ZWFrX2RlcGVuZGVuY3koaW50IGluZGV4LCA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKTsKKyAgdm9pZCBhZGRfd2Vha19kZXBlbmRlbmN5KDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgdmFsdWUpOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgPiYKKyAgICAgIHdlYWtfZGVwZW5kZW5jeSgpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgPioKKyAgICAgIG11dGFibGVfd2Vha19kZXBlbmRlbmN5KCk7CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8gbWVzc2FnZV90eXBlID0gNDsKKyAgaW50IG1lc3NhZ2VfdHlwZV9zaXplKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfbWVzc2FnZV90eXBlKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga01lc3NhZ2VUeXBlRmllbGROdW1iZXIgPSA0OworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQcm90byYgbWVzc2FnZV90eXBlKGludCBpbmRleCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclByb3RvKiBtdXRhYmxlX21lc3NhZ2VfdHlwZShpbnQgaW5kZXgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQcm90byogYWRkX21lc3NhZ2VfdHlwZSgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclByb3RvID4qCisgICAgICBtdXRhYmxlX21lc3NhZ2VfdHlwZSgpOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclByb3RvID4mCisgICAgICBtZXNzYWdlX3R5cGUoKSBjb25zdDsKKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8gZW51bV90eXBlID0gNTsKKyAgaW50IGVudW1fdHlwZV9zaXplKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfZW51bV90eXBlKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga0VudW1UeXBlRmllbGROdW1iZXIgPSA1OworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yUHJvdG8mIGVudW1fdHlwZShpbnQgaW5kZXgpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yUHJvdG8qIG11dGFibGVfZW51bV90eXBlKGludCBpbmRleCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bURlc2NyaXB0b3JQcm90byogYWRkX2VudW1fdHlwZSgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bURlc2NyaXB0b3JQcm90byA+KgorICAgICAgbXV0YWJsZV9lbnVtX3R5cGUoKTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yUHJvdG8gPiYKKyAgICAgIGVudW1fdHlwZSgpIGNvbnN0OworCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuU2VydmljZURlc2NyaXB0b3JQcm90byBzZXJ2aWNlID0gNjsKKyAgaW50IHNlcnZpY2Vfc2l6ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX3NlcnZpY2UoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrU2VydmljZUZpZWxkTnVtYmVyID0gNjsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpTZXJ2aWNlRGVzY3JpcHRvclByb3RvJiBzZXJ2aWNlKGludCBpbmRleCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6U2VydmljZURlc2NyaXB0b3JQcm90byogbXV0YWJsZV9zZXJ2aWNlKGludCBpbmRleCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6U2VydmljZURlc2NyaXB0b3JQcm90byogYWRkX3NlcnZpY2UoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8gPioKKyAgICAgIG11dGFibGVfc2VydmljZSgpOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6U2VydmljZURlc2NyaXB0b3JQcm90byA+JgorICAgICAgc2VydmljZSgpIGNvbnN0OworCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8gZXh0ZW5zaW9uID0gNzsKKyAgaW50IGV4dGVuc2lvbl9zaXplKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfZXh0ZW5zaW9uKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga0V4dGVuc2lvbkZpZWxkTnVtYmVyID0gNzsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90byYgZXh0ZW5zaW9uKGludCBpbmRleCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG8qIG11dGFibGVfZXh0ZW5zaW9uKGludCBpbmRleCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG8qIGFkZF9leHRlbnNpb24oKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvID4qCisgICAgICBtdXRhYmxlX2V4dGVuc2lvbigpOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG8gPiYKKyAgICAgIGV4dGVuc2lvbigpIGNvbnN0OworCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMgb3B0aW9ucyA9IDg7CisgIGJvb2wgaGFzX29wdGlvbnMoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9vcHRpb25zKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga09wdGlvbnNGaWVsZE51bWJlciA9IDg7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZU9wdGlvbnMmIG9wdGlvbnMoKSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlT3B0aW9ucyogbXV0YWJsZV9vcHRpb25zKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZU9wdGlvbnMqIHJlbGVhc2Vfb3B0aW9ucygpOworICB2b2lkIHNldF9hbGxvY2F0ZWRfb3B0aW9ucyg6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVPcHRpb25zKiBvcHRpb25zKTsKKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvIHNvdXJjZV9jb2RlX2luZm8gPSA5OworICBib29sIGhhc19zb3VyY2VfY29kZV9pbmZvKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfc291cmNlX2NvZGVfaW5mbygpOworICBzdGF0aWMgY29uc3QgaW50IGtTb3VyY2VDb2RlSW5mb0ZpZWxkTnVtYmVyID0gOTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb2RlSW5mbyYgc291cmNlX2NvZGVfaW5mbygpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvZGVJbmZvKiBtdXRhYmxlX3NvdXJjZV9jb2RlX2luZm8oKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb2RlSW5mbyogcmVsZWFzZV9zb3VyY2VfY29kZV9pbmZvKCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF9zb3VyY2VfY29kZV9pbmZvKDo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29kZUluZm8qIHNvdXJjZV9jb2RlX2luZm8pOworCisgIC8vIG9wdGlvbmFsIHN0cmluZyBzeW50YXggPSAxMjsKKyAgYm9vbCBoYXNfc3ludGF4KCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfc3ludGF4KCk7CisgIHN0YXRpYyBjb25zdCBpbnQga1N5bnRheEZpZWxkTnVtYmVyID0gMTI7CisgIGNvbnN0IDo6c3RkOjpzdHJpbmcmIHN5bnRheCgpIGNvbnN0OworICB2b2lkIHNldF9zeW50YXgoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpOworICB2b2lkIHNldF9zeW50YXgoY29uc3QgY2hhciogdmFsdWUpOworICB2b2lkIHNldF9zeW50YXgoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKTsKKyAgOjpzdGQ6OnN0cmluZyogbXV0YWJsZV9zeW50YXgoKTsKKyAgOjpzdGQ6OnN0cmluZyogcmVsZWFzZV9zeW50YXgoKTsKKyAgdm9pZCBzZXRfYWxsb2NhdGVkX3N5bnRheCg6OnN0ZDo6c3RyaW5nKiBzeW50YXgpOworCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90bykKKyBwcml2YXRlOgorICBpbmxpbmUgdm9pZCBzZXRfaGFzX25hbWUoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX25hbWUoKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19wYWNrYWdlKCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc19wYWNrYWdlKCk7CisgIGlubGluZSB2b2lkIHNldF9oYXNfb3B0aW9ucygpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfb3B0aW9ucygpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX3NvdXJjZV9jb2RlX2luZm8oKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX3NvdXJjZV9jb2RlX2luZm8oKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19zeW50YXgoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX3N5bnRheCgpOworCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEgX2ludGVybmFsX21ldGFkYXRhXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgX2hhc19iaXRzX1sxXTsKKyAgbXV0YWJsZSBpbnQgX2NhY2hlZF9zaXplXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QXJlbmFTdHJpbmdQdHIgbmFtZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFyZW5hU3RyaW5nUHRyIHBhY2thZ2VfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6c3RkOjpzdHJpbmc+IGRlcGVuZGVuY3lfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgPiBwdWJsaWNfZGVwZW5kZW5jeV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiA+IHdlYWtfZGVwZW5kZW5jeV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG8gPiBtZXNzYWdlX3R5cGVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bURlc2NyaXB0b3JQcm90byA+IGVudW1fdHlwZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpTZXJ2aWNlRGVzY3JpcHRvclByb3RvID4gc2VydmljZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90byA+IGV4dGVuc2lvbl87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZU9wdGlvbnMqIG9wdGlvbnNfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvZGVJbmZvKiBzb3VyY2VfY29kZV9pbmZvXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QXJlbmFTdHJpbmdQdHIgc3ludGF4XzsKKyAgZnJpZW5kIHZvaWQgTElCUFJPVE9CVUZfRVhQT1JUIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfQXNzaWduRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKworICB2b2lkIEluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICBzdGF0aWMgRmlsZURlc2NyaXB0b3JQcm90byogZGVmYXVsdF9pbnN0YW5jZV87Cit9OworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlIDogcHVibGljIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSB7CisgcHVibGljOgorICBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UoKTsKKyAgdmlydHVhbCB+RGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlKCk7CisKKyAgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlKGNvbnN0IERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZSYgZnJvbSk7CisKKyAgaW5saW5lIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZSYgb3BlcmF0b3I9KGNvbnN0IERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZSYgZnJvbSkgeworICAgIENvcHlGcm9tKGZyb20pOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIGlubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlVua25vd25GaWVsZFNldCYgdW5rbm93bl9maWVsZHMoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8udW5rbm93bl9maWVsZHMoKTsKKyAgfQorCisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlVua25vd25GaWVsZFNldCogbXV0YWJsZV91bmtub3duX2ZpZWxkcygpIHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5tdXRhYmxlX3Vua25vd25fZmllbGRzKCk7CisgIH0KKworICBzdGF0aWMgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKCk7CisgIHN0YXRpYyBjb25zdCBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UmIGRlZmF1bHRfaW5zdGFuY2UoKTsKKworICB2b2lkIFN3YXAoRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlKiBvdGhlcik7CisKKyAgLy8gaW1wbGVtZW50cyBNZXNzYWdlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBpbmxpbmUgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlKiBOZXcoKSBjb25zdCB7IHJldHVybiBOZXcoTlVMTCk7IH0KKworICBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UqIE5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3Q7CisgIHZvaWQgQ29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UmIGZyb20pOworICB2b2lkIENsZWFyKCk7CisgIGJvb2wgSXNJbml0aWFsaXplZCgpIGNvbnN0OworCisgIGludCBCeXRlU2l6ZSgpIGNvbnN0OworICBib29sIE1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KTsKKyAgdm9pZCBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSg6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBvdXRwdXQpIGNvbnN0OworICBpbnQgR2V0Q2FjaGVkU2l6ZSgpIGNvbnN0IHsgcmV0dXJuIF9jYWNoZWRfc2l6ZV87IH0KKyAgcHJpdmF0ZToKKyAgdm9pZCBTaGFyZWRDdG9yKCk7CisgIHZvaWQgU2hhcmVkRHRvcigpOworICB2b2lkIFNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0OworICB2b2lkIEludGVybmFsU3dhcChEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UqIG90aGVyKTsKKyAgcHJpdmF0ZToKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hTm9WaXJ0dWFsKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLmFyZW5hKCk7CisgIH0KKyAgaW5saW5lIHZvaWQqIE1heWJlQXJlbmFQdHIoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ucmF3X2FyZW5hX3B0cigpOworICB9CisgIHB1YmxpYzoKKworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEdldE1ldGFkYXRhKCkgY29uc3Q7CisKKyAgLy8gbmVzdGVkIHR5cGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBhY2Nlc3NvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIG9wdGlvbmFsIGludDMyIHN0YXJ0ID0gMTsKKyAgYm9vbCBoYXNfc3RhcnQoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9zdGFydCgpOworICBzdGF0aWMgY29uc3QgaW50IGtTdGFydEZpZWxkTnVtYmVyID0gMTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiBzdGFydCgpIGNvbnN0OworICB2b2lkIHNldF9zdGFydCg6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKTsKKworICAvLyBvcHRpb25hbCBpbnQzMiBlbmQgPSAyOworICBib29sIGhhc19lbmQoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9lbmQoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrRW5kRmllbGROdW1iZXIgPSAyOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIGVuZCgpIGNvbnN0OworICB2b2lkIHNldF9lbmQoOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiB2YWx1ZSk7CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uRXh0ZW5zaW9uUmFuZ2UpCisgcHJpdmF0ZToKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19zdGFydCgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfc3RhcnQoKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19lbmQoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX2VuZCgpOworCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEgX2ludGVybmFsX21ldGFkYXRhXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgX2hhc19iaXRzX1sxXTsKKyAgbXV0YWJsZSBpbnQgX2NhY2hlZF9zaXplXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiBzdGFydF87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgZW5kXzsKKyAgZnJpZW5kIHZvaWQgTElCUFJPVE9CVUZfRVhQT1JUIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfQXNzaWduRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKworICB2b2lkIEluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICBzdGF0aWMgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlKiBkZWZhdWx0X2luc3RhbmNlXzsKK307CisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZSA6IHB1YmxpYyA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UgeworIHB1YmxpYzoKKyAgRGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2UoKTsKKyAgdmlydHVhbCB+RGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2UoKTsKKworICBEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZShjb25zdCBEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZSYgZnJvbSk7CisKKyAgaW5saW5lIERlc2NyaXB0b3JQcm90b19SZXNlcnZlZFJhbmdlJiBvcGVyYXRvcj0oY29uc3QgRGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2UmIGZyb20pIHsKKyAgICBDb3B5RnJvbShmcm9tKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworICBpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpVbmtub3duRmllbGRTZXQmIHVua25vd25fZmllbGRzKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnVua25vd25fZmllbGRzKCk7CisgIH0KKworICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpVbmtub3duRmllbGRTZXQqIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ubXV0YWJsZV91bmtub3duX2ZpZWxkcygpOworICB9CisKKyAgc3RhdGljIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogZGVzY3JpcHRvcigpOworICBzdGF0aWMgY29uc3QgRGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2UmIGRlZmF1bHRfaW5zdGFuY2UoKTsKKworICB2b2lkIFN3YXAoRGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2UqIG90aGVyKTsKKworICAvLyBpbXBsZW1lbnRzIE1lc3NhZ2UgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIGlubGluZSBEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZSogTmV3KCkgY29uc3QgeyByZXR1cm4gTmV3KE5VTEwpOyB9CisKKyAgRGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2UqIE5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3Q7CisgIHZvaWQgQ29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCBEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZSYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IERlc2NyaXB0b3JQcm90b19SZXNlcnZlZFJhbmdlJiBmcm9tKTsKKyAgdm9pZCBDbGVhcigpOworICBib29sIElzSW5pdGlhbGl6ZWQoKSBjb25zdDsKKworICBpbnQgQnl0ZVNpemUoKSBjb25zdDsKKyAgYm9vbCBNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCk7CisgIHZvaWQgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogb3V0cHV0KSBjb25zdDsKKyAgaW50IEdldENhY2hlZFNpemUoKSBjb25zdCB7IHJldHVybiBfY2FjaGVkX3NpemVfOyB9CisgIHByaXZhdGU6CisgIHZvaWQgU2hhcmVkQ3RvcigpOworICB2b2lkIFNoYXJlZER0b3IoKTsKKyAgdm9pZCBTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdDsKKyAgdm9pZCBJbnRlcm5hbFN3YXAoRGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2UqIG90aGVyKTsKKyAgcHJpdmF0ZToKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hTm9WaXJ0dWFsKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLmFyZW5hKCk7CisgIH0KKyAgaW5saW5lIHZvaWQqIE1heWJlQXJlbmFQdHIoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ucmF3X2FyZW5hX3B0cigpOworICB9CisgIHB1YmxpYzoKKworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEdldE1ldGFkYXRhKCkgY29uc3Q7CisKKyAgLy8gbmVzdGVkIHR5cGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBhY2Nlc3NvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIG9wdGlvbmFsIGludDMyIHN0YXJ0ID0gMTsKKyAgYm9vbCBoYXNfc3RhcnQoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9zdGFydCgpOworICBzdGF0aWMgY29uc3QgaW50IGtTdGFydEZpZWxkTnVtYmVyID0gMTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiBzdGFydCgpIGNvbnN0OworICB2b2lkIHNldF9zdGFydCg6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKTsKKworICAvLyBvcHRpb25hbCBpbnQzMiBlbmQgPSAyOworICBib29sIGhhc19lbmQoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9lbmQoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrRW5kRmllbGROdW1iZXIgPSAyOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIGVuZCgpIGNvbnN0OworICB2b2lkIHNldF9lbmQoOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiB2YWx1ZSk7CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uUmVzZXJ2ZWRSYW5nZSkKKyBwcml2YXRlOgorICBpbmxpbmUgdm9pZCBzZXRfaGFzX3N0YXJ0KCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc19zdGFydCgpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX2VuZCgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfZW5kKCk7CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6SW50ZXJuYWxNZXRhZGF0YVdpdGhBcmVuYSBfaW50ZXJuYWxfbWV0YWRhdGFfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiBfaGFzX2JpdHNfWzFdOworICBtdXRhYmxlIGludCBfY2FjaGVkX3NpemVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHN0YXJ0XzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiBlbmRfOworICBmcmllbmQgdm9pZCBMSUJQUk9UT0JVRl9FWFBPUlQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworCisgIHZvaWQgSW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIHN0YXRpYyBEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZSogZGVmYXVsdF9pbnN0YW5jZV87Cit9OworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgRGVzY3JpcHRvclByb3RvIDogcHVibGljIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSB7CisgcHVibGljOgorICBEZXNjcmlwdG9yUHJvdG8oKTsKKyAgdmlydHVhbCB+RGVzY3JpcHRvclByb3RvKCk7CisKKyAgRGVzY3JpcHRvclByb3RvKGNvbnN0IERlc2NyaXB0b3JQcm90byYgZnJvbSk7CisKKyAgaW5saW5lIERlc2NyaXB0b3JQcm90byYgb3BlcmF0b3I9KGNvbnN0IERlc2NyaXB0b3JQcm90byYgZnJvbSkgeworICAgIENvcHlGcm9tKGZyb20pOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIGlubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlVua25vd25GaWVsZFNldCYgdW5rbm93bl9maWVsZHMoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8udW5rbm93bl9maWVsZHMoKTsKKyAgfQorCisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlVua25vd25GaWVsZFNldCogbXV0YWJsZV91bmtub3duX2ZpZWxkcygpIHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5tdXRhYmxlX3Vua25vd25fZmllbGRzKCk7CisgIH0KKworICBzdGF0aWMgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKCk7CisgIHN0YXRpYyBjb25zdCBEZXNjcmlwdG9yUHJvdG8mIGRlZmF1bHRfaW5zdGFuY2UoKTsKKworICB2b2lkIFN3YXAoRGVzY3JpcHRvclByb3RvKiBvdGhlcik7CisKKyAgLy8gaW1wbGVtZW50cyBNZXNzYWdlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBpbmxpbmUgRGVzY3JpcHRvclByb3RvKiBOZXcoKSBjb25zdCB7IHJldHVybiBOZXcoTlVMTCk7IH0KKworICBEZXNjcmlwdG9yUHJvdG8qIE5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3Q7CisgIHZvaWQgQ29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCBEZXNjcmlwdG9yUHJvdG8mIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCBEZXNjcmlwdG9yUHJvdG8mIGZyb20pOworICB2b2lkIENsZWFyKCk7CisgIGJvb2wgSXNJbml0aWFsaXplZCgpIGNvbnN0OworCisgIGludCBCeXRlU2l6ZSgpIGNvbnN0OworICBib29sIE1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KTsKKyAgdm9pZCBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSg6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBvdXRwdXQpIGNvbnN0OworICBpbnQgR2V0Q2FjaGVkU2l6ZSgpIGNvbnN0IHsgcmV0dXJuIF9jYWNoZWRfc2l6ZV87IH0KKyAgcHJpdmF0ZToKKyAgdm9pZCBTaGFyZWRDdG9yKCk7CisgIHZvaWQgU2hhcmVkRHRvcigpOworICB2b2lkIFNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0OworICB2b2lkIEludGVybmFsU3dhcChEZXNjcmlwdG9yUHJvdG8qIG90aGVyKTsKKyAgcHJpdmF0ZToKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hTm9WaXJ0dWFsKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLmFyZW5hKCk7CisgIH0KKyAgaW5saW5lIHZvaWQqIE1heWJlQXJlbmFQdHIoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ucmF3X2FyZW5hX3B0cigpOworICB9CisgIHB1YmxpYzoKKworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEdldE1ldGFkYXRhKCkgY29uc3Q7CisKKyAgLy8gbmVzdGVkIHR5cGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICB0eXBlZGVmIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZSBFeHRlbnNpb25SYW5nZTsKKyAgdHlwZWRlZiBEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZSBSZXNlcnZlZFJhbmdlOworCisgIC8vIGFjY2Vzc29ycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICBib29sIGhhc19uYW1lKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfbmFtZSgpOworICBzdGF0aWMgY29uc3QgaW50IGtOYW1lRmllbGROdW1iZXIgPSAxOworICBjb25zdCA6OnN0ZDo6c3RyaW5nJiBuYW1lKCkgY29uc3Q7CisgIHZvaWQgc2V0X25hbWUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpOworICB2b2lkIHNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlKTsKKyAgdm9pZCBzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpOworICA6OnN0ZDo6c3RyaW5nKiBtdXRhYmxlX25hbWUoKTsKKyAgOjpzdGQ6OnN0cmluZyogcmVsZWFzZV9uYW1lKCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF9uYW1lKDo6c3RkOjpzdHJpbmcqIG5hbWUpOworCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8gZmllbGQgPSAyOworICBpbnQgZmllbGRfc2l6ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX2ZpZWxkKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga0ZpZWxkRmllbGROdW1iZXIgPSAyOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvJiBmaWVsZChpbnQgaW5kZXgpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvKiBtdXRhYmxlX2ZpZWxkKGludCBpbmRleCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG8qIGFkZF9maWVsZCgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG8gPioKKyAgICAgIG11dGFibGVfZmllbGQoKTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvID4mCisgICAgICBmaWVsZCgpIGNvbnN0OworCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8gZXh0ZW5zaW9uID0gNjsKKyAgaW50IGV4dGVuc2lvbl9zaXplKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfZXh0ZW5zaW9uKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga0V4dGVuc2lvbkZpZWxkTnVtYmVyID0gNjsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90byYgZXh0ZW5zaW9uKGludCBpbmRleCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG8qIG11dGFibGVfZXh0ZW5zaW9uKGludCBpbmRleCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG8qIGFkZF9leHRlbnNpb24oKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvID4qCisgICAgICBtdXRhYmxlX2V4dGVuc2lvbigpOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG8gPiYKKyAgICAgIGV4dGVuc2lvbigpIGNvbnN0OworCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvIG5lc3RlZF90eXBlID0gMzsKKyAgaW50IG5lc3RlZF90eXBlX3NpemUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9uZXN0ZWRfdHlwZSgpOworICBzdGF0aWMgY29uc3QgaW50IGtOZXN0ZWRUeXBlRmllbGROdW1iZXIgPSAzOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQcm90byYgbmVzdGVkX3R5cGUoaW50IGluZGV4KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG8qIG11dGFibGVfbmVzdGVkX3R5cGUoaW50IGluZGV4KTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG8qIGFkZF9uZXN0ZWRfdHlwZSgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclByb3RvID4qCisgICAgICBtdXRhYmxlX25lc3RlZF90eXBlKCk7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG8gPiYKKyAgICAgIG5lc3RlZF90eXBlKCkgY29uc3Q7CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvIGVudW1fdHlwZSA9IDQ7CisgIGludCBlbnVtX3R5cGVfc2l6ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX2VudW1fdHlwZSgpOworICBzdGF0aWMgY29uc3QgaW50IGtFbnVtVHlwZUZpZWxkTnVtYmVyID0gNDsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvclByb3RvJiBlbnVtX3R5cGUoaW50IGluZGV4KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvclByb3RvKiBtdXRhYmxlX2VudW1fdHlwZShpbnQgaW5kZXgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yUHJvdG8qIGFkZF9lbnVtX3R5cGUoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yUHJvdG8gPioKKyAgICAgIG11dGFibGVfZW51bV90eXBlKCk7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvclByb3RvID4mCisgICAgICBlbnVtX3R5cGUoKSBjb25zdDsKKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5FeHRlbnNpb25SYW5nZSBleHRlbnNpb25fcmFuZ2UgPSA1OworICBpbnQgZXh0ZW5zaW9uX3JhbmdlX3NpemUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9leHRlbnNpb25fcmFuZ2UoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrRXh0ZW5zaW9uUmFuZ2VGaWVsZE51bWJlciA9IDU7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlJiBleHRlbnNpb25fcmFuZ2UoaW50IGluZGV4KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UqIG11dGFibGVfZXh0ZW5zaW9uX3JhbmdlKGludCBpbmRleCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlKiBhZGRfZXh0ZW5zaW9uX3JhbmdlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UgPioKKyAgICAgIG11dGFibGVfZXh0ZW5zaW9uX3JhbmdlKCk7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UgPiYKKyAgICAgIGV4dGVuc2lvbl9yYW5nZSgpIGNvbnN0OworCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuT25lb2ZEZXNjcmlwdG9yUHJvdG8gb25lb2ZfZGVjbCA9IDg7CisgIGludCBvbmVvZl9kZWNsX3NpemUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9vbmVvZl9kZWNsKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga09uZW9mRGVjbEZpZWxkTnVtYmVyID0gODsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpPbmVvZkRlc2NyaXB0b3JQcm90byYgb25lb2ZfZGVjbChpbnQgaW5kZXgpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok9uZW9mRGVzY3JpcHRvclByb3RvKiBtdXRhYmxlX29uZW9mX2RlY2woaW50IGluZGV4KTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpPbmVvZkRlc2NyaXB0b3JQcm90byogYWRkX29uZW9mX2RlY2woKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok9uZW9mRGVzY3JpcHRvclByb3RvID4qCisgICAgICBtdXRhYmxlX29uZW9mX2RlY2woKTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok9uZW9mRGVzY3JpcHRvclByb3RvID4mCisgICAgICBvbmVvZl9kZWNsKCkgY29uc3Q7CisKKyAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucyBvcHRpb25zID0gNzsKKyAgYm9vbCBoYXNfb3B0aW9ucygpIGNvbnN0OworICB2b2lkIGNsZWFyX29wdGlvbnMoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrT3B0aW9uc0ZpZWxkTnVtYmVyID0gNzsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlT3B0aW9ucyYgb3B0aW9ucygpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VPcHRpb25zKiBtdXRhYmxlX29wdGlvbnMoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlT3B0aW9ucyogcmVsZWFzZV9vcHRpb25zKCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF9vcHRpb25zKDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZU9wdGlvbnMqIG9wdGlvbnMpOworCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLlJlc2VydmVkUmFuZ2UgcmVzZXJ2ZWRfcmFuZ2UgPSA5OworICBpbnQgcmVzZXJ2ZWRfcmFuZ2Vfc2l6ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX3Jlc2VydmVkX3JhbmdlKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga1Jlc2VydmVkUmFuZ2VGaWVsZE51bWJlciA9IDk7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2UmIHJlc2VydmVkX3JhbmdlKGludCBpbmRleCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2UqIG11dGFibGVfcmVzZXJ2ZWRfcmFuZ2UoaW50IGluZGV4KTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZSogYWRkX3Jlc2VydmVkX3JhbmdlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZSA+KgorICAgICAgbXV0YWJsZV9yZXNlcnZlZF9yYW5nZSgpOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2UgPiYKKyAgICAgIHJlc2VydmVkX3JhbmdlKCkgY29uc3Q7CisKKyAgLy8gcmVwZWF0ZWQgc3RyaW5nIHJlc2VydmVkX25hbWUgPSAxMDsKKyAgaW50IHJlc2VydmVkX25hbWVfc2l6ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX3Jlc2VydmVkX25hbWUoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrUmVzZXJ2ZWROYW1lRmllbGROdW1iZXIgPSAxMDsKKyAgY29uc3QgOjpzdGQ6OnN0cmluZyYgcmVzZXJ2ZWRfbmFtZShpbnQgaW5kZXgpIGNvbnN0OworICA6OnN0ZDo6c3RyaW5nKiBtdXRhYmxlX3Jlc2VydmVkX25hbWUoaW50IGluZGV4KTsKKyAgdm9pZCBzZXRfcmVzZXJ2ZWRfbmFtZShpbnQgaW5kZXgsIGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKTsKKyAgdm9pZCBzZXRfcmVzZXJ2ZWRfbmFtZShpbnQgaW5kZXgsIGNvbnN0IGNoYXIqIHZhbHVlKTsKKyAgdm9pZCBzZXRfcmVzZXJ2ZWRfbmFtZShpbnQgaW5kZXgsIGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIDo6c3RkOjpzdHJpbmcqIGFkZF9yZXNlcnZlZF9uYW1lKCk7CisgIHZvaWQgYWRkX3Jlc2VydmVkX25hbWUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpOworICB2b2lkIGFkZF9yZXNlcnZlZF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlKTsKKyAgdm9pZCBhZGRfcmVzZXJ2ZWRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6c3RkOjpzdHJpbmc+JiByZXNlcnZlZF9uYW1lKCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpzdGQ6OnN0cmluZz4qIG11dGFibGVfcmVzZXJ2ZWRfbmFtZSgpOworCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvKQorIHByaXZhdGU6CisgIGlubGluZSB2b2lkIHNldF9oYXNfbmFtZSgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfbmFtZSgpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX29wdGlvbnMoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX29wdGlvbnMoKTsKKworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpJbnRlcm5hbE1ldGFkYXRhV2l0aEFyZW5hIF9pbnRlcm5hbF9tZXRhZGF0YV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIF9oYXNfYml0c19bMV07CisgIG11dGFibGUgaW50IF9jYWNoZWRfc2l6ZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFyZW5hU3RyaW5nUHRyIG5hbWVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG8gPiBmaWVsZF87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90byA+IGV4dGVuc2lvbl87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG8gPiBuZXN0ZWRfdHlwZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvclByb3RvID4gZW51bV90eXBlXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZSA+IGV4dGVuc2lvbl9yYW5nZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpPbmVvZkRlc2NyaXB0b3JQcm90byA+IG9uZW9mX2RlY2xfOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VPcHRpb25zKiBvcHRpb25zXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQcm90b19SZXNlcnZlZFJhbmdlID4gcmVzZXJ2ZWRfcmFuZ2VfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6c3RkOjpzdHJpbmc+IHJlc2VydmVkX25hbWVfOworICBmcmllbmQgdm9pZCBMSUJQUk9UT0JVRl9FWFBPUlQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworCisgIHZvaWQgSW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIHN0YXRpYyBEZXNjcmlwdG9yUHJvdG8qIGRlZmF1bHRfaW5zdGFuY2VfOworfTsKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEZpZWxkRGVzY3JpcHRvclByb3RvIDogcHVibGljIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSB7CisgcHVibGljOgorICBGaWVsZERlc2NyaXB0b3JQcm90bygpOworICB2aXJ0dWFsIH5GaWVsZERlc2NyaXB0b3JQcm90bygpOworCisgIEZpZWxkRGVzY3JpcHRvclByb3RvKGNvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvJiBmcm9tKTsKKworICBpbmxpbmUgRmllbGREZXNjcmlwdG9yUHJvdG8mIG9wZXJhdG9yPShjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90byYgZnJvbSkgeworICAgIENvcHlGcm9tKGZyb20pOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIGlubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlVua25vd25GaWVsZFNldCYgdW5rbm93bl9maWVsZHMoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8udW5rbm93bl9maWVsZHMoKTsKKyAgfQorCisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlVua25vd25GaWVsZFNldCogbXV0YWJsZV91bmtub3duX2ZpZWxkcygpIHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5tdXRhYmxlX3Vua25vd25fZmllbGRzKCk7CisgIH0KKworICBzdGF0aWMgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKCk7CisgIHN0YXRpYyBjb25zdCBGaWVsZERlc2NyaXB0b3JQcm90byYgZGVmYXVsdF9pbnN0YW5jZSgpOworCisgIHZvaWQgU3dhcChGaWVsZERlc2NyaXB0b3JQcm90byogb3RoZXIpOworCisgIC8vIGltcGxlbWVudHMgTWVzc2FnZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgaW5saW5lIEZpZWxkRGVzY3JpcHRvclByb3RvKiBOZXcoKSBjb25zdCB7IHJldHVybiBOZXcoTlVMTCk7IH0KKworICBGaWVsZERlc2NyaXB0b3JQcm90byogTmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdDsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIENvcHlGcm9tKGNvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG8mIGZyb20pOworICB2b2lkIENsZWFyKCk7CisgIGJvb2wgSXNJbml0aWFsaXplZCgpIGNvbnN0OworCisgIGludCBCeXRlU2l6ZSgpIGNvbnN0OworICBib29sIE1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KTsKKyAgdm9pZCBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSg6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBvdXRwdXQpIGNvbnN0OworICBpbnQgR2V0Q2FjaGVkU2l6ZSgpIGNvbnN0IHsgcmV0dXJuIF9jYWNoZWRfc2l6ZV87IH0KKyAgcHJpdmF0ZToKKyAgdm9pZCBTaGFyZWRDdG9yKCk7CisgIHZvaWQgU2hhcmVkRHRvcigpOworICB2b2lkIFNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0OworICB2b2lkIEludGVybmFsU3dhcChGaWVsZERlc2NyaXB0b3JQcm90byogb3RoZXIpOworICBwcml2YXRlOgorICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogR2V0QXJlbmFOb1ZpcnR1YWwoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8uYXJlbmEoKTsKKyAgfQorICBpbmxpbmUgdm9pZCogTWF5YmVBcmVuYVB0cigpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5yYXdfYXJlbmFfcHRyKCk7CisgIH0KKyAgcHVibGljOgorCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgR2V0TWV0YWRhdGEoKSBjb25zdDsKKworICAvLyBuZXN0ZWQgdHlwZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIHR5cGVkZWYgRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZSBUeXBlOworICBzdGF0aWMgY29uc3QgVHlwZSBUWVBFX0RPVUJMRSA9IEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfVFlQRV9ET1VCTEU7CisgIHN0YXRpYyBjb25zdCBUeXBlIFRZUEVfRkxPQVQgPSBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX1RZUEVfRkxPQVQ7CisgIHN0YXRpYyBjb25zdCBUeXBlIFRZUEVfSU5UNjQgPSBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX1RZUEVfSU5UNjQ7CisgIHN0YXRpYyBjb25zdCBUeXBlIFRZUEVfVUlOVDY0ID0gRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9UWVBFX1VJTlQ2NDsKKyAgc3RhdGljIGNvbnN0IFR5cGUgVFlQRV9JTlQzMiA9IEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfVFlQRV9JTlQzMjsKKyAgc3RhdGljIGNvbnN0IFR5cGUgVFlQRV9GSVhFRDY0ID0gRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9UWVBFX0ZJWEVENjQ7CisgIHN0YXRpYyBjb25zdCBUeXBlIFRZUEVfRklYRUQzMiA9IEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfVFlQRV9GSVhFRDMyOworICBzdGF0aWMgY29uc3QgVHlwZSBUWVBFX0JPT0wgPSBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX1RZUEVfQk9PTDsKKyAgc3RhdGljIGNvbnN0IFR5cGUgVFlQRV9TVFJJTkcgPSBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX1RZUEVfU1RSSU5HOworICBzdGF0aWMgY29uc3QgVHlwZSBUWVBFX0dST1VQID0gRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9UWVBFX0dST1VQOworICBzdGF0aWMgY29uc3QgVHlwZSBUWVBFX01FU1NBR0UgPSBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX1RZUEVfTUVTU0FHRTsKKyAgc3RhdGljIGNvbnN0IFR5cGUgVFlQRV9CWVRFUyA9IEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfVFlQRV9CWVRFUzsKKyAgc3RhdGljIGNvbnN0IFR5cGUgVFlQRV9VSU5UMzIgPSBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX1RZUEVfVUlOVDMyOworICBzdGF0aWMgY29uc3QgVHlwZSBUWVBFX0VOVU0gPSBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX1RZUEVfRU5VTTsKKyAgc3RhdGljIGNvbnN0IFR5cGUgVFlQRV9TRklYRUQzMiA9IEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfVFlQRV9TRklYRUQzMjsKKyAgc3RhdGljIGNvbnN0IFR5cGUgVFlQRV9TRklYRUQ2NCA9IEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfVFlQRV9TRklYRUQ2NDsKKyAgc3RhdGljIGNvbnN0IFR5cGUgVFlQRV9TSU5UMzIgPSBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX1RZUEVfU0lOVDMyOworICBzdGF0aWMgY29uc3QgVHlwZSBUWVBFX1NJTlQ2NCA9IEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfVFlQRV9TSU5UNjQ7CisgIHN0YXRpYyBpbmxpbmUgYm9vbCBUeXBlX0lzVmFsaWQoaW50IHZhbHVlKSB7CisgICAgcmV0dXJuIEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfSXNWYWxpZCh2YWx1ZSk7CisgIH0KKyAgc3RhdGljIGNvbnN0IFR5cGUgVHlwZV9NSU4gPQorICAgIEZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfVHlwZV9NSU47CisgIHN0YXRpYyBjb25zdCBUeXBlIFR5cGVfTUFYID0KKyAgICBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX1R5cGVfTUFYOworICBzdGF0aWMgY29uc3QgaW50IFR5cGVfQVJSQVlTSVpFID0KKyAgICBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX1R5cGVfQVJSQVlTSVpFOworICBzdGF0aWMgaW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bURlc2NyaXB0b3IqCisgIFR5cGVfZGVzY3JpcHRvcigpIHsKKyAgICByZXR1cm4gRmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZV9kZXNjcmlwdG9yKCk7CisgIH0KKyAgc3RhdGljIGlubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBUeXBlX05hbWUoVHlwZSB2YWx1ZSkgeworICAgIHJldHVybiBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX05hbWUodmFsdWUpOworICB9CisgIHN0YXRpYyBpbmxpbmUgYm9vbCBUeXBlX1BhcnNlKGNvbnN0IDo6c3RkOjpzdHJpbmcmIG5hbWUsCisgICAgICBUeXBlKiB2YWx1ZSkgeworICAgIHJldHVybiBGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX1BhcnNlKG5hbWUsIHZhbHVlKTsKKyAgfQorCisgIHR5cGVkZWYgRmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWwgTGFiZWw7CisgIHN0YXRpYyBjb25zdCBMYWJlbCBMQUJFTF9PUFRJT05BTCA9IEZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsX0xBQkVMX09QVElPTkFMOworICBzdGF0aWMgY29uc3QgTGFiZWwgTEFCRUxfUkVRVUlSRUQgPSBGaWVsZERlc2NyaXB0b3JQcm90b19MYWJlbF9MQUJFTF9SRVFVSVJFRDsKKyAgc3RhdGljIGNvbnN0IExhYmVsIExBQkVMX1JFUEVBVEVEID0gRmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWxfTEFCRUxfUkVQRUFURUQ7CisgIHN0YXRpYyBpbmxpbmUgYm9vbCBMYWJlbF9Jc1ZhbGlkKGludCB2YWx1ZSkgeworICAgIHJldHVybiBGaWVsZERlc2NyaXB0b3JQcm90b19MYWJlbF9Jc1ZhbGlkKHZhbHVlKTsKKyAgfQorICBzdGF0aWMgY29uc3QgTGFiZWwgTGFiZWxfTUlOID0KKyAgICBGaWVsZERlc2NyaXB0b3JQcm90b19MYWJlbF9MYWJlbF9NSU47CisgIHN0YXRpYyBjb25zdCBMYWJlbCBMYWJlbF9NQVggPQorICAgIEZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsX0xhYmVsX01BWDsKKyAgc3RhdGljIGNvbnN0IGludCBMYWJlbF9BUlJBWVNJWkUgPQorICAgIEZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsX0xhYmVsX0FSUkFZU0laRTsKKyAgc3RhdGljIGlubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yKgorICBMYWJlbF9kZXNjcmlwdG9yKCkgeworICAgIHJldHVybiBGaWVsZERlc2NyaXB0b3JQcm90b19MYWJlbF9kZXNjcmlwdG9yKCk7CisgIH0KKyAgc3RhdGljIGlubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBMYWJlbF9OYW1lKExhYmVsIHZhbHVlKSB7CisgICAgcmV0dXJuIEZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsX05hbWUodmFsdWUpOworICB9CisgIHN0YXRpYyBpbmxpbmUgYm9vbCBMYWJlbF9QYXJzZShjb25zdCA6OnN0ZDo6c3RyaW5nJiBuYW1lLAorICAgICAgTGFiZWwqIHZhbHVlKSB7CisgICAgcmV0dXJuIEZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsX1BhcnNlKG5hbWUsIHZhbHVlKTsKKyAgfQorCisgIC8vIGFjY2Vzc29ycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICBib29sIGhhc19uYW1lKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfbmFtZSgpOworICBzdGF0aWMgY29uc3QgaW50IGtOYW1lRmllbGROdW1iZXIgPSAxOworICBjb25zdCA6OnN0ZDo6c3RyaW5nJiBuYW1lKCkgY29uc3Q7CisgIHZvaWQgc2V0X25hbWUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpOworICB2b2lkIHNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlKTsKKyAgdm9pZCBzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpOworICA6OnN0ZDo6c3RyaW5nKiBtdXRhYmxlX25hbWUoKTsKKyAgOjpzdGQ6OnN0cmluZyogcmVsZWFzZV9uYW1lKCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF9uYW1lKDo6c3RkOjpzdHJpbmcqIG5hbWUpOworCisgIC8vIG9wdGlvbmFsIGludDMyIG51bWJlciA9IDM7CisgIGJvb2wgaGFzX251bWJlcigpIGNvbnN0OworICB2b2lkIGNsZWFyX251bWJlcigpOworICBzdGF0aWMgY29uc3QgaW50IGtOdW1iZXJGaWVsZE51bWJlciA9IDM7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgbnVtYmVyKCkgY29uc3Q7CisgIHZvaWQgc2V0X251bWJlcig6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKTsKKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLkxhYmVsIGxhYmVsID0gNDsKKyAgYm9vbCBoYXNfbGFiZWwoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9sYWJlbCgpOworICBzdGF0aWMgY29uc3QgaW50IGtMYWJlbEZpZWxkTnVtYmVyID0gNDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90b19MYWJlbCBsYWJlbCgpIGNvbnN0OworICB2b2lkIHNldF9sYWJlbCg6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsIHZhbHVlKTsKKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLlR5cGUgdHlwZSA9IDU7CisgIGJvb2wgaGFzX3R5cGUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl90eXBlKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga1R5cGVGaWVsZE51bWJlciA9IDU7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZSB0eXBlKCkgY29uc3Q7CisgIHZvaWQgc2V0X3R5cGUoOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlIHZhbHVlKTsKKworICAvLyBvcHRpb25hbCBzdHJpbmcgdHlwZV9uYW1lID0gNjsKKyAgYm9vbCBoYXNfdHlwZV9uYW1lKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfdHlwZV9uYW1lKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga1R5cGVOYW1lRmllbGROdW1iZXIgPSA2OworICBjb25zdCA6OnN0ZDo6c3RyaW5nJiB0eXBlX25hbWUoKSBjb25zdDsKKyAgdm9pZCBzZXRfdHlwZV9uYW1lKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKTsKKyAgdm9pZCBzZXRfdHlwZV9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlKTsKKyAgdm9pZCBzZXRfdHlwZV9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIDo6c3RkOjpzdHJpbmcqIG11dGFibGVfdHlwZV9uYW1lKCk7CisgIDo6c3RkOjpzdHJpbmcqIHJlbGVhc2VfdHlwZV9uYW1lKCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF90eXBlX25hbWUoOjpzdGQ6OnN0cmluZyogdHlwZV9uYW1lKTsKKworICAvLyBvcHRpb25hbCBzdHJpbmcgZXh0ZW5kZWUgPSAyOworICBib29sIGhhc19leHRlbmRlZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX2V4dGVuZGVlKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga0V4dGVuZGVlRmllbGROdW1iZXIgPSAyOworICBjb25zdCA6OnN0ZDo6c3RyaW5nJiBleHRlbmRlZSgpIGNvbnN0OworICB2b2lkIHNldF9leHRlbmRlZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X2V4dGVuZGVlKGNvbnN0IGNoYXIqIHZhbHVlKTsKKyAgdm9pZCBzZXRfZXh0ZW5kZWUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKTsKKyAgOjpzdGQ6OnN0cmluZyogbXV0YWJsZV9leHRlbmRlZSgpOworICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlX2V4dGVuZGVlKCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF9leHRlbmRlZSg6OnN0ZDo6c3RyaW5nKiBleHRlbmRlZSk7CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIGRlZmF1bHRfdmFsdWUgPSA3OworICBib29sIGhhc19kZWZhdWx0X3ZhbHVlKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfZGVmYXVsdF92YWx1ZSgpOworICBzdGF0aWMgY29uc3QgaW50IGtEZWZhdWx0VmFsdWVGaWVsZE51bWJlciA9IDc7CisgIGNvbnN0IDo6c3RkOjpzdHJpbmcmIGRlZmF1bHRfdmFsdWUoKSBjb25zdDsKKyAgdm9pZCBzZXRfZGVmYXVsdF92YWx1ZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X2RlZmF1bHRfdmFsdWUoY29uc3QgY2hhciogdmFsdWUpOworICB2b2lkIHNldF9kZWZhdWx0X3ZhbHVlKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIDo6c3RkOjpzdHJpbmcqIG11dGFibGVfZGVmYXVsdF92YWx1ZSgpOworICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlX2RlZmF1bHRfdmFsdWUoKTsKKyAgdm9pZCBzZXRfYWxsb2NhdGVkX2RlZmF1bHRfdmFsdWUoOjpzdGQ6OnN0cmluZyogZGVmYXVsdF92YWx1ZSk7CisKKyAgLy8gb3B0aW9uYWwgaW50MzIgb25lb2ZfaW5kZXggPSA5OworICBib29sIGhhc19vbmVvZl9pbmRleCgpIGNvbnN0OworICB2b2lkIGNsZWFyX29uZW9mX2luZGV4KCk7CisgIHN0YXRpYyBjb25zdCBpbnQga09uZW9mSW5kZXhGaWVsZE51bWJlciA9IDk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgb25lb2ZfaW5kZXgoKSBjb25zdDsKKyAgdm9pZCBzZXRfb25lb2ZfaW5kZXgoOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiB2YWx1ZSk7CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIGpzb25fbmFtZSA9IDEwOworICBib29sIGhhc19qc29uX25hbWUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9qc29uX25hbWUoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrSnNvbk5hbWVGaWVsZE51bWJlciA9IDEwOworICBjb25zdCA6OnN0ZDo6c3RyaW5nJiBqc29uX25hbWUoKSBjb25zdDsKKyAgdm9pZCBzZXRfanNvbl9uYW1lKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKTsKKyAgdm9pZCBzZXRfanNvbl9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlKTsKKyAgdm9pZCBzZXRfanNvbl9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIDo6c3RkOjpzdHJpbmcqIG11dGFibGVfanNvbl9uYW1lKCk7CisgIDo6c3RkOjpzdHJpbmcqIHJlbGVhc2VfanNvbl9uYW1lKCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF9qc29uX25hbWUoOjpzdGQ6OnN0cmluZyoganNvbl9uYW1lKTsKKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucyBvcHRpb25zID0gODsKKyAgYm9vbCBoYXNfb3B0aW9ucygpIGNvbnN0OworICB2b2lkIGNsZWFyX29wdGlvbnMoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrT3B0aW9uc0ZpZWxkTnVtYmVyID0gODsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZE9wdGlvbnMmIG9wdGlvbnMoKSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZE9wdGlvbnMqIG11dGFibGVfb3B0aW9ucygpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkT3B0aW9ucyogcmVsZWFzZV9vcHRpb25zKCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF9vcHRpb25zKDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGRPcHRpb25zKiBvcHRpb25zKTsKKworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvKQorIHByaXZhdGU6CisgIGlubGluZSB2b2lkIHNldF9oYXNfbmFtZSgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfbmFtZSgpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX251bWJlcigpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfbnVtYmVyKCk7CisgIGlubGluZSB2b2lkIHNldF9oYXNfbGFiZWwoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX2xhYmVsKCk7CisgIGlubGluZSB2b2lkIHNldF9oYXNfdHlwZSgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfdHlwZSgpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX3R5cGVfbmFtZSgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfdHlwZV9uYW1lKCk7CisgIGlubGluZSB2b2lkIHNldF9oYXNfZXh0ZW5kZWUoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX2V4dGVuZGVlKCk7CisgIGlubGluZSB2b2lkIHNldF9oYXNfZGVmYXVsdF92YWx1ZSgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfZGVmYXVsdF92YWx1ZSgpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX29uZW9mX2luZGV4KCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc19vbmVvZl9pbmRleCgpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX2pzb25fbmFtZSgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfanNvbl9uYW1lKCk7CisgIGlubGluZSB2b2lkIHNldF9oYXNfb3B0aW9ucygpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfb3B0aW9ucygpOworCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEgX2ludGVybmFsX21ldGFkYXRhXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgX2hhc19iaXRzX1sxXTsKKyAgbXV0YWJsZSBpbnQgX2NhY2hlZF9zaXplXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QXJlbmFTdHJpbmdQdHIgbmFtZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgbnVtYmVyXzsKKyAgaW50IGxhYmVsXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QXJlbmFTdHJpbmdQdHIgdHlwZV9uYW1lXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QXJlbmFTdHJpbmdQdHIgZXh0ZW5kZWVfOworICBpbnQgdHlwZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgb25lb2ZfaW5kZXhfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBcmVuYVN0cmluZ1B0ciBkZWZhdWx0X3ZhbHVlXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QXJlbmFTdHJpbmdQdHIganNvbl9uYW1lXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZE9wdGlvbnMqIG9wdGlvbnNfOworICBmcmllbmQgdm9pZCBMSUJQUk9UT0JVRl9FWFBPUlQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworCisgIHZvaWQgSW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIHN0YXRpYyBGaWVsZERlc2NyaXB0b3JQcm90byogZGVmYXVsdF9pbnN0YW5jZV87Cit9OworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgT25lb2ZEZXNjcmlwdG9yUHJvdG8gOiBwdWJsaWMgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlIHsKKyBwdWJsaWM6CisgIE9uZW9mRGVzY3JpcHRvclByb3RvKCk7CisgIHZpcnR1YWwgfk9uZW9mRGVzY3JpcHRvclByb3RvKCk7CisKKyAgT25lb2ZEZXNjcmlwdG9yUHJvdG8oY29uc3QgT25lb2ZEZXNjcmlwdG9yUHJvdG8mIGZyb20pOworCisgIGlubGluZSBPbmVvZkRlc2NyaXB0b3JQcm90byYgb3BlcmF0b3I9KGNvbnN0IE9uZW9mRGVzY3JpcHRvclByb3RvJiBmcm9tKSB7CisgICAgQ29weUZyb20oZnJvbSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgaW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcygpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy51bmtub3duX2ZpZWxkcygpOworICB9CisKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5rbm93bkZpZWxkU2V0KiBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLm11dGFibGVfdW5rbm93bl9maWVsZHMoKTsKKyAgfQorCisgIHN0YXRpYyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIGRlc2NyaXB0b3IoKTsKKyAgc3RhdGljIGNvbnN0IE9uZW9mRGVzY3JpcHRvclByb3RvJiBkZWZhdWx0X2luc3RhbmNlKCk7CisKKyAgdm9pZCBTd2FwKE9uZW9mRGVzY3JpcHRvclByb3RvKiBvdGhlcik7CisKKyAgLy8gaW1wbGVtZW50cyBNZXNzYWdlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBpbmxpbmUgT25lb2ZEZXNjcmlwdG9yUHJvdG8qIE5ldygpIGNvbnN0IHsgcmV0dXJuIE5ldyhOVUxMKTsgfQorCisgIE9uZW9mRGVzY3JpcHRvclByb3RvKiBOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0OworICB2b2lkIENvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgQ29weUZyb20oY29uc3QgT25lb2ZEZXNjcmlwdG9yUHJvdG8mIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCBPbmVvZkRlc2NyaXB0b3JQcm90byYgZnJvbSk7CisgIHZvaWQgQ2xlYXIoKTsKKyAgYm9vbCBJc0luaXRpYWxpemVkKCkgY29uc3Q7CisKKyAgaW50IEJ5dGVTaXplKCkgY29uc3Q7CisgIGJvb2wgTWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpOworICB2b2lkIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIG91dHB1dCkgY29uc3Q7CisgIGludCBHZXRDYWNoZWRTaXplKCkgY29uc3QgeyByZXR1cm4gX2NhY2hlZF9zaXplXzsgfQorICBwcml2YXRlOgorICB2b2lkIFNoYXJlZEN0b3IoKTsKKyAgdm9pZCBTaGFyZWREdG9yKCk7CisgIHZvaWQgU2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3Q7CisgIHZvaWQgSW50ZXJuYWxTd2FwKE9uZW9mRGVzY3JpcHRvclByb3RvKiBvdGhlcik7CisgIHByaXZhdGU6CisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYU5vVmlydHVhbCgpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5hcmVuYSgpOworICB9CisgIGlubGluZSB2b2lkKiBNYXliZUFyZW5hUHRyKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnJhd19hcmVuYV9wdHIoKTsKKyAgfQorICBwdWJsaWM6CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBHZXRNZXRhZGF0YSgpIGNvbnN0OworCisgIC8vIG5lc3RlZCB0eXBlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gYWNjZXNzb3JzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgIGJvb2wgaGFzX25hbWUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9uYW1lKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga05hbWVGaWVsZE51bWJlciA9IDE7CisgIGNvbnN0IDo6c3RkOjpzdHJpbmcmIG5hbWUoKSBjb25zdDsKKyAgdm9pZCBzZXRfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUpOworICB2b2lkIHNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIDo6c3RkOjpzdHJpbmcqIG11dGFibGVfbmFtZSgpOworICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlX25hbWUoKTsKKyAgdm9pZCBzZXRfYWxsb2NhdGVkX25hbWUoOjpzdGQ6OnN0cmluZyogbmFtZSk7CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmdvb2dsZS5wcm90b2J1Zi5PbmVvZkRlc2NyaXB0b3JQcm90bykKKyBwcml2YXRlOgorICBpbmxpbmUgdm9pZCBzZXRfaGFzX25hbWUoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX25hbWUoKTsKKworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpJbnRlcm5hbE1ldGFkYXRhV2l0aEFyZW5hIF9pbnRlcm5hbF9tZXRhZGF0YV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIF9oYXNfYml0c19bMV07CisgIG11dGFibGUgaW50IF9jYWNoZWRfc2l6ZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFyZW5hU3RyaW5nUHRyIG5hbWVfOworICBmcmllbmQgdm9pZCBMSUJQUk9UT0JVRl9FWFBPUlQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworCisgIHZvaWQgSW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIHN0YXRpYyBPbmVvZkRlc2NyaXB0b3JQcm90byogZGVmYXVsdF9pbnN0YW5jZV87Cit9OworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgRW51bURlc2NyaXB0b3JQcm90byA6IHB1YmxpYyA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UgeworIHB1YmxpYzoKKyAgRW51bURlc2NyaXB0b3JQcm90bygpOworICB2aXJ0dWFsIH5FbnVtRGVzY3JpcHRvclByb3RvKCk7CisKKyAgRW51bURlc2NyaXB0b3JQcm90byhjb25zdCBFbnVtRGVzY3JpcHRvclByb3RvJiBmcm9tKTsKKworICBpbmxpbmUgRW51bURlc2NyaXB0b3JQcm90byYgb3BlcmF0b3I9KGNvbnN0IEVudW1EZXNjcmlwdG9yUHJvdG8mIGZyb20pIHsKKyAgICBDb3B5RnJvbShmcm9tKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworICBpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpVbmtub3duRmllbGRTZXQmIHVua25vd25fZmllbGRzKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnVua25vd25fZmllbGRzKCk7CisgIH0KKworICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpVbmtub3duRmllbGRTZXQqIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ubXV0YWJsZV91bmtub3duX2ZpZWxkcygpOworICB9CisKKyAgc3RhdGljIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogZGVzY3JpcHRvcigpOworICBzdGF0aWMgY29uc3QgRW51bURlc2NyaXB0b3JQcm90byYgZGVmYXVsdF9pbnN0YW5jZSgpOworCisgIHZvaWQgU3dhcChFbnVtRGVzY3JpcHRvclByb3RvKiBvdGhlcik7CisKKyAgLy8gaW1wbGVtZW50cyBNZXNzYWdlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBpbmxpbmUgRW51bURlc2NyaXB0b3JQcm90byogTmV3KCkgY29uc3QgeyByZXR1cm4gTmV3KE5VTEwpOyB9CisKKyAgRW51bURlc2NyaXB0b3JQcm90byogTmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdDsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIENvcHlGcm9tKGNvbnN0IEVudW1EZXNjcmlwdG9yUHJvdG8mIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCBFbnVtRGVzY3JpcHRvclByb3RvJiBmcm9tKTsKKyAgdm9pZCBDbGVhcigpOworICBib29sIElzSW5pdGlhbGl6ZWQoKSBjb25zdDsKKworICBpbnQgQnl0ZVNpemUoKSBjb25zdDsKKyAgYm9vbCBNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCk7CisgIHZvaWQgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogb3V0cHV0KSBjb25zdDsKKyAgaW50IEdldENhY2hlZFNpemUoKSBjb25zdCB7IHJldHVybiBfY2FjaGVkX3NpemVfOyB9CisgIHByaXZhdGU6CisgIHZvaWQgU2hhcmVkQ3RvcigpOworICB2b2lkIFNoYXJlZER0b3IoKTsKKyAgdm9pZCBTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdDsKKyAgdm9pZCBJbnRlcm5hbFN3YXAoRW51bURlc2NyaXB0b3JQcm90byogb3RoZXIpOworICBwcml2YXRlOgorICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogR2V0QXJlbmFOb1ZpcnR1YWwoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8uYXJlbmEoKTsKKyAgfQorICBpbmxpbmUgdm9pZCogTWF5YmVBcmVuYVB0cigpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5yYXdfYXJlbmFfcHRyKCk7CisgIH0KKyAgcHVibGljOgorCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgR2V0TWV0YWRhdGEoKSBjb25zdDsKKworICAvLyBuZXN0ZWQgdHlwZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIGFjY2Vzc29ycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICBib29sIGhhc19uYW1lKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfbmFtZSgpOworICBzdGF0aWMgY29uc3QgaW50IGtOYW1lRmllbGROdW1iZXIgPSAxOworICBjb25zdCA6OnN0ZDo6c3RyaW5nJiBuYW1lKCkgY29uc3Q7CisgIHZvaWQgc2V0X25hbWUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpOworICB2b2lkIHNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlKTsKKyAgdm9pZCBzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpOworICA6OnN0ZDo6c3RyaW5nKiBtdXRhYmxlX25hbWUoKTsKKyAgOjpzdGQ6OnN0cmluZyogcmVsZWFzZV9uYW1lKCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF9uYW1lKDo6c3RkOjpzdHJpbmcqIG5hbWUpOworCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRW51bVZhbHVlRGVzY3JpcHRvclByb3RvIHZhbHVlID0gMjsKKyAgaW50IHZhbHVlX3NpemUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl92YWx1ZSgpOworICBzdGF0aWMgY29uc3QgaW50IGtWYWx1ZUZpZWxkTnVtYmVyID0gMjsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8mIHZhbHVlKGludCBpbmRleCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlRGVzY3JpcHRvclByb3RvKiBtdXRhYmxlX3ZhbHVlKGludCBpbmRleCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlRGVzY3JpcHRvclByb3RvKiBhZGRfdmFsdWUoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZURlc2NyaXB0b3JQcm90byA+KgorICAgICAgbXV0YWJsZV92YWx1ZSgpOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlRGVzY3JpcHRvclByb3RvID4mCisgICAgICB2YWx1ZSgpIGNvbnN0OworCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnMgb3B0aW9ucyA9IDM7CisgIGJvb2wgaGFzX29wdGlvbnMoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9vcHRpb25zKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga09wdGlvbnNGaWVsZE51bWJlciA9IDM7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bU9wdGlvbnMmIG9wdGlvbnMoKSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtT3B0aW9ucyogbXV0YWJsZV9vcHRpb25zKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bU9wdGlvbnMqIHJlbGVhc2Vfb3B0aW9ucygpOworICB2b2lkIHNldF9hbGxvY2F0ZWRfb3B0aW9ucyg6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1PcHRpb25zKiBvcHRpb25zKTsKKworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6Z29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8pCisgcHJpdmF0ZToKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19uYW1lKCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc19uYW1lKCk7CisgIGlubGluZSB2b2lkIHNldF9oYXNfb3B0aW9ucygpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfb3B0aW9ucygpOworCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEgX2ludGVybmFsX21ldGFkYXRhXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgX2hhc19iaXRzX1sxXTsKKyAgbXV0YWJsZSBpbnQgX2NhY2hlZF9zaXplXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QXJlbmFTdHJpbmdQdHIgbmFtZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8gPiB2YWx1ZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bU9wdGlvbnMqIG9wdGlvbnNfOworICBmcmllbmQgdm9pZCBMSUJQUk9UT0JVRl9FWFBPUlQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworCisgIHZvaWQgSW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIHN0YXRpYyBFbnVtRGVzY3JpcHRvclByb3RvKiBkZWZhdWx0X2luc3RhbmNlXzsKK307CisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8gOiBwdWJsaWMgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlIHsKKyBwdWJsaWM6CisgIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bygpOworICB2aXJ0dWFsIH5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8oKTsKKworICBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8oY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvJiBmcm9tKTsKKworICBpbmxpbmUgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvJiBvcGVyYXRvcj0oY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvJiBmcm9tKSB7CisgICAgQ29weUZyb20oZnJvbSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgaW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcygpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy51bmtub3duX2ZpZWxkcygpOworICB9CisKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5rbm93bkZpZWxkU2V0KiBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLm11dGFibGVfdW5rbm93bl9maWVsZHMoKTsKKyAgfQorCisgIHN0YXRpYyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIGRlc2NyaXB0b3IoKTsKKyAgc3RhdGljIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3JQcm90byYgZGVmYXVsdF9pbnN0YW5jZSgpOworCisgIHZvaWQgU3dhcChFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8qIG90aGVyKTsKKworICAvLyBpbXBsZW1lbnRzIE1lc3NhZ2UgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIGlubGluZSBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8qIE5ldygpIGNvbnN0IHsgcmV0dXJuIE5ldyhOVUxMKTsgfQorCisgIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90byogTmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdDsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIENvcHlGcm9tKGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3JQcm90byYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3JQcm90byYgZnJvbSk7CisgIHZvaWQgQ2xlYXIoKTsKKyAgYm9vbCBJc0luaXRpYWxpemVkKCkgY29uc3Q7CisKKyAgaW50IEJ5dGVTaXplKCkgY29uc3Q7CisgIGJvb2wgTWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpOworICB2b2lkIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIG91dHB1dCkgY29uc3Q7CisgIGludCBHZXRDYWNoZWRTaXplKCkgY29uc3QgeyByZXR1cm4gX2NhY2hlZF9zaXplXzsgfQorICBwcml2YXRlOgorICB2b2lkIFNoYXJlZEN0b3IoKTsKKyAgdm9pZCBTaGFyZWREdG9yKCk7CisgIHZvaWQgU2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3Q7CisgIHZvaWQgSW50ZXJuYWxTd2FwKEVudW1WYWx1ZURlc2NyaXB0b3JQcm90byogb3RoZXIpOworICBwcml2YXRlOgorICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogR2V0QXJlbmFOb1ZpcnR1YWwoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8uYXJlbmEoKTsKKyAgfQorICBpbmxpbmUgdm9pZCogTWF5YmVBcmVuYVB0cigpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5yYXdfYXJlbmFfcHRyKCk7CisgIH0KKyAgcHVibGljOgorCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgR2V0TWV0YWRhdGEoKSBjb25zdDsKKworICAvLyBuZXN0ZWQgdHlwZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIGFjY2Vzc29ycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICBib29sIGhhc19uYW1lKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfbmFtZSgpOworICBzdGF0aWMgY29uc3QgaW50IGtOYW1lRmllbGROdW1iZXIgPSAxOworICBjb25zdCA6OnN0ZDo6c3RyaW5nJiBuYW1lKCkgY29uc3Q7CisgIHZvaWQgc2V0X25hbWUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpOworICB2b2lkIHNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlKTsKKyAgdm9pZCBzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpOworICA6OnN0ZDo6c3RyaW5nKiBtdXRhYmxlX25hbWUoKTsKKyAgOjpzdGQ6OnN0cmluZyogcmVsZWFzZV9uYW1lKCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF9uYW1lKDo6c3RkOjpzdHJpbmcqIG5hbWUpOworCisgIC8vIG9wdGlvbmFsIGludDMyIG51bWJlciA9IDI7CisgIGJvb2wgaGFzX251bWJlcigpIGNvbnN0OworICB2b2lkIGNsZWFyX251bWJlcigpOworICBzdGF0aWMgY29uc3QgaW50IGtOdW1iZXJGaWVsZE51bWJlciA9IDI7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgbnVtYmVyKCkgY29uc3Q7CisgIHZvaWQgc2V0X251bWJlcig6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKTsKKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnMgb3B0aW9ucyA9IDM7CisgIGJvb2wgaGFzX29wdGlvbnMoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9vcHRpb25zKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga09wdGlvbnNGaWVsZE51bWJlciA9IDM7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlT3B0aW9ucyYgb3B0aW9ucygpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZU9wdGlvbnMqIG11dGFibGVfb3B0aW9ucygpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZU9wdGlvbnMqIHJlbGVhc2Vfb3B0aW9ucygpOworICB2b2lkIHNldF9hbGxvY2F0ZWRfb3B0aW9ucyg6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZU9wdGlvbnMqIG9wdGlvbnMpOworCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlRGVzY3JpcHRvclByb3RvKQorIHByaXZhdGU6CisgIGlubGluZSB2b2lkIHNldF9oYXNfbmFtZSgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfbmFtZSgpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX251bWJlcigpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfbnVtYmVyKCk7CisgIGlubGluZSB2b2lkIHNldF9oYXNfb3B0aW9ucygpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfb3B0aW9ucygpOworCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEgX2ludGVybmFsX21ldGFkYXRhXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgX2hhc19iaXRzX1sxXTsKKyAgbXV0YWJsZSBpbnQgX2NhY2hlZF9zaXplXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QXJlbmFTdHJpbmdQdHIgbmFtZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlT3B0aW9ucyogb3B0aW9uc187CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgbnVtYmVyXzsKKyAgZnJpZW5kIHZvaWQgTElCUFJPVE9CVUZfRVhQT1JUIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfQXNzaWduRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKworICB2b2lkIEluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICBzdGF0aWMgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvKiBkZWZhdWx0X2luc3RhbmNlXzsKK307CisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvIDogcHVibGljIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSB7CisgcHVibGljOgorICBTZXJ2aWNlRGVzY3JpcHRvclByb3RvKCk7CisgIHZpcnR1YWwgflNlcnZpY2VEZXNjcmlwdG9yUHJvdG8oKTsKKworICBTZXJ2aWNlRGVzY3JpcHRvclByb3RvKGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yUHJvdG8mIGZyb20pOworCisgIGlubGluZSBTZXJ2aWNlRGVzY3JpcHRvclByb3RvJiBvcGVyYXRvcj0oY29uc3QgU2VydmljZURlc2NyaXB0b3JQcm90byYgZnJvbSkgeworICAgIENvcHlGcm9tKGZyb20pOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIGlubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlVua25vd25GaWVsZFNldCYgdW5rbm93bl9maWVsZHMoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8udW5rbm93bl9maWVsZHMoKTsKKyAgfQorCisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlVua25vd25GaWVsZFNldCogbXV0YWJsZV91bmtub3duX2ZpZWxkcygpIHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5tdXRhYmxlX3Vua25vd25fZmllbGRzKCk7CisgIH0KKworICBzdGF0aWMgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKCk7CisgIHN0YXRpYyBjb25zdCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvJiBkZWZhdWx0X2luc3RhbmNlKCk7CisKKyAgdm9pZCBTd2FwKFNlcnZpY2VEZXNjcmlwdG9yUHJvdG8qIG90aGVyKTsKKworICAvLyBpbXBsZW1lbnRzIE1lc3NhZ2UgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIGlubGluZSBTZXJ2aWNlRGVzY3JpcHRvclByb3RvKiBOZXcoKSBjb25zdCB7IHJldHVybiBOZXcoTlVMTCk7IH0KKworICBTZXJ2aWNlRGVzY3JpcHRvclByb3RvKiBOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0OworICB2b2lkIENvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgQ29weUZyb20oY29uc3QgU2VydmljZURlc2NyaXB0b3JQcm90byYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yUHJvdG8mIGZyb20pOworICB2b2lkIENsZWFyKCk7CisgIGJvb2wgSXNJbml0aWFsaXplZCgpIGNvbnN0OworCisgIGludCBCeXRlU2l6ZSgpIGNvbnN0OworICBib29sIE1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KTsKKyAgdm9pZCBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSg6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBvdXRwdXQpIGNvbnN0OworICBpbnQgR2V0Q2FjaGVkU2l6ZSgpIGNvbnN0IHsgcmV0dXJuIF9jYWNoZWRfc2l6ZV87IH0KKyAgcHJpdmF0ZToKKyAgdm9pZCBTaGFyZWRDdG9yKCk7CisgIHZvaWQgU2hhcmVkRHRvcigpOworICB2b2lkIFNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0OworICB2b2lkIEludGVybmFsU3dhcChTZXJ2aWNlRGVzY3JpcHRvclByb3RvKiBvdGhlcik7CisgIHByaXZhdGU6CisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYU5vVmlydHVhbCgpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5hcmVuYSgpOworICB9CisgIGlubGluZSB2b2lkKiBNYXliZUFyZW5hUHRyKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnJhd19hcmVuYV9wdHIoKTsKKyAgfQorICBwdWJsaWM6CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBHZXRNZXRhZGF0YSgpIGNvbnN0OworCisgIC8vIG5lc3RlZCB0eXBlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gYWNjZXNzb3JzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgIGJvb2wgaGFzX25hbWUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9uYW1lKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga05hbWVGaWVsZE51bWJlciA9IDE7CisgIGNvbnN0IDo6c3RkOjpzdHJpbmcmIG5hbWUoKSBjb25zdDsKKyAgdm9pZCBzZXRfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUpOworICB2b2lkIHNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIDo6c3RkOjpzdHJpbmcqIG11dGFibGVfbmFtZSgpOworICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlX25hbWUoKTsKKyAgdm9pZCBzZXRfYWxsb2NhdGVkX25hbWUoOjpzdGQ6OnN0cmluZyogbmFtZSk7CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8gbWV0aG9kID0gMjsKKyAgaW50IG1ldGhvZF9zaXplKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfbWV0aG9kKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga01ldGhvZEZpZWxkTnVtYmVyID0gMjsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRob2REZXNjcmlwdG9yUHJvdG8mIG1ldGhvZChpbnQgaW5kZXgpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGhvZERlc2NyaXB0b3JQcm90byogbXV0YWJsZV9tZXRob2QoaW50IGluZGV4KTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRob2REZXNjcmlwdG9yUHJvdG8qIGFkZF9tZXRob2QoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGhvZERlc2NyaXB0b3JQcm90byA+KgorICAgICAgbXV0YWJsZV9tZXRob2QoKTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGhvZERlc2NyaXB0b3JQcm90byA+JgorICAgICAgbWV0aG9kKCkgY29uc3Q7CisKKyAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlT3B0aW9ucyBvcHRpb25zID0gMzsKKyAgYm9vbCBoYXNfb3B0aW9ucygpIGNvbnN0OworICB2b2lkIGNsZWFyX29wdGlvbnMoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrT3B0aW9uc0ZpZWxkTnVtYmVyID0gMzsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpTZXJ2aWNlT3B0aW9ucyYgb3B0aW9ucygpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OlNlcnZpY2VPcHRpb25zKiBtdXRhYmxlX29wdGlvbnMoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpTZXJ2aWNlT3B0aW9ucyogcmVsZWFzZV9vcHRpb25zKCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF9vcHRpb25zKDo6Z29vZ2xlOjpwcm90b2J1Zjo6U2VydmljZU9wdGlvbnMqIG9wdGlvbnMpOworCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpnb29nbGUucHJvdG9idWYuU2VydmljZURlc2NyaXB0b3JQcm90bykKKyBwcml2YXRlOgorICBpbmxpbmUgdm9pZCBzZXRfaGFzX25hbWUoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX25hbWUoKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19vcHRpb25zKCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc19vcHRpb25zKCk7CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6SW50ZXJuYWxNZXRhZGF0YVdpdGhBcmVuYSBfaW50ZXJuYWxfbWV0YWRhdGFfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiBfaGFzX2JpdHNfWzFdOworICBtdXRhYmxlIGludCBfY2FjaGVkX3NpemVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBcmVuYVN0cmluZ1B0ciBuYW1lXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGhvZERlc2NyaXB0b3JQcm90byA+IG1ldGhvZF87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6U2VydmljZU9wdGlvbnMqIG9wdGlvbnNfOworICBmcmllbmQgdm9pZCBMSUJQUk9UT0JVRl9FWFBPUlQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworCisgIHZvaWQgSW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIHN0YXRpYyBTZXJ2aWNlRGVzY3JpcHRvclByb3RvKiBkZWZhdWx0X2luc3RhbmNlXzsKK307CisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBNZXRob2REZXNjcmlwdG9yUHJvdG8gOiBwdWJsaWMgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlIHsKKyBwdWJsaWM6CisgIE1ldGhvZERlc2NyaXB0b3JQcm90bygpOworICB2aXJ0dWFsIH5NZXRob2REZXNjcmlwdG9yUHJvdG8oKTsKKworICBNZXRob2REZXNjcmlwdG9yUHJvdG8oY29uc3QgTWV0aG9kRGVzY3JpcHRvclByb3RvJiBmcm9tKTsKKworICBpbmxpbmUgTWV0aG9kRGVzY3JpcHRvclByb3RvJiBvcGVyYXRvcj0oY29uc3QgTWV0aG9kRGVzY3JpcHRvclByb3RvJiBmcm9tKSB7CisgICAgQ29weUZyb20oZnJvbSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgaW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcygpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy51bmtub3duX2ZpZWxkcygpOworICB9CisKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5rbm93bkZpZWxkU2V0KiBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLm11dGFibGVfdW5rbm93bl9maWVsZHMoKTsKKyAgfQorCisgIHN0YXRpYyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIGRlc2NyaXB0b3IoKTsKKyAgc3RhdGljIGNvbnN0IE1ldGhvZERlc2NyaXB0b3JQcm90byYgZGVmYXVsdF9pbnN0YW5jZSgpOworCisgIHZvaWQgU3dhcChNZXRob2REZXNjcmlwdG9yUHJvdG8qIG90aGVyKTsKKworICAvLyBpbXBsZW1lbnRzIE1lc3NhZ2UgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIGlubGluZSBNZXRob2REZXNjcmlwdG9yUHJvdG8qIE5ldygpIGNvbnN0IHsgcmV0dXJuIE5ldyhOVUxMKTsgfQorCisgIE1ldGhvZERlc2NyaXB0b3JQcm90byogTmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdDsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIENvcHlGcm9tKGNvbnN0IE1ldGhvZERlc2NyaXB0b3JQcm90byYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IE1ldGhvZERlc2NyaXB0b3JQcm90byYgZnJvbSk7CisgIHZvaWQgQ2xlYXIoKTsKKyAgYm9vbCBJc0luaXRpYWxpemVkKCkgY29uc3Q7CisKKyAgaW50IEJ5dGVTaXplKCkgY29uc3Q7CisgIGJvb2wgTWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpOworICB2b2lkIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIG91dHB1dCkgY29uc3Q7CisgIGludCBHZXRDYWNoZWRTaXplKCkgY29uc3QgeyByZXR1cm4gX2NhY2hlZF9zaXplXzsgfQorICBwcml2YXRlOgorICB2b2lkIFNoYXJlZEN0b3IoKTsKKyAgdm9pZCBTaGFyZWREdG9yKCk7CisgIHZvaWQgU2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3Q7CisgIHZvaWQgSW50ZXJuYWxTd2FwKE1ldGhvZERlc2NyaXB0b3JQcm90byogb3RoZXIpOworICBwcml2YXRlOgorICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogR2V0QXJlbmFOb1ZpcnR1YWwoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8uYXJlbmEoKTsKKyAgfQorICBpbmxpbmUgdm9pZCogTWF5YmVBcmVuYVB0cigpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5yYXdfYXJlbmFfcHRyKCk7CisgIH0KKyAgcHVibGljOgorCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgR2V0TWV0YWRhdGEoKSBjb25zdDsKKworICAvLyBuZXN0ZWQgdHlwZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIGFjY2Vzc29ycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICBib29sIGhhc19uYW1lKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfbmFtZSgpOworICBzdGF0aWMgY29uc3QgaW50IGtOYW1lRmllbGROdW1iZXIgPSAxOworICBjb25zdCA6OnN0ZDo6c3RyaW5nJiBuYW1lKCkgY29uc3Q7CisgIHZvaWQgc2V0X25hbWUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpOworICB2b2lkIHNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlKTsKKyAgdm9pZCBzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpOworICA6OnN0ZDo6c3RyaW5nKiBtdXRhYmxlX25hbWUoKTsKKyAgOjpzdGQ6OnN0cmluZyogcmVsZWFzZV9uYW1lKCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF9uYW1lKDo6c3RkOjpzdHJpbmcqIG5hbWUpOworCisgIC8vIG9wdGlvbmFsIHN0cmluZyBpbnB1dF90eXBlID0gMjsKKyAgYm9vbCBoYXNfaW5wdXRfdHlwZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX2lucHV0X3R5cGUoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrSW5wdXRUeXBlRmllbGROdW1iZXIgPSAyOworICBjb25zdCA6OnN0ZDo6c3RyaW5nJiBpbnB1dF90eXBlKCkgY29uc3Q7CisgIHZvaWQgc2V0X2lucHV0X3R5cGUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpOworICB2b2lkIHNldF9pbnB1dF90eXBlKGNvbnN0IGNoYXIqIHZhbHVlKTsKKyAgdm9pZCBzZXRfaW5wdXRfdHlwZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpOworICA6OnN0ZDo6c3RyaW5nKiBtdXRhYmxlX2lucHV0X3R5cGUoKTsKKyAgOjpzdGQ6OnN0cmluZyogcmVsZWFzZV9pbnB1dF90eXBlKCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF9pbnB1dF90eXBlKDo6c3RkOjpzdHJpbmcqIGlucHV0X3R5cGUpOworCisgIC8vIG9wdGlvbmFsIHN0cmluZyBvdXRwdXRfdHlwZSA9IDM7CisgIGJvb2wgaGFzX291dHB1dF90eXBlKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfb3V0cHV0X3R5cGUoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrT3V0cHV0VHlwZUZpZWxkTnVtYmVyID0gMzsKKyAgY29uc3QgOjpzdGQ6OnN0cmluZyYgb3V0cHV0X3R5cGUoKSBjb25zdDsKKyAgdm9pZCBzZXRfb3V0cHV0X3R5cGUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpOworICB2b2lkIHNldF9vdXRwdXRfdHlwZShjb25zdCBjaGFyKiB2YWx1ZSk7CisgIHZvaWQgc2V0X291dHB1dF90eXBlKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIDo6c3RkOjpzdHJpbmcqIG11dGFibGVfb3V0cHV0X3R5cGUoKTsKKyAgOjpzdGQ6OnN0cmluZyogcmVsZWFzZV9vdXRwdXRfdHlwZSgpOworICB2b2lkIHNldF9hbGxvY2F0ZWRfb3V0cHV0X3R5cGUoOjpzdGQ6OnN0cmluZyogb3V0cHV0X3R5cGUpOworCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucyBvcHRpb25zID0gNDsKKyAgYm9vbCBoYXNfb3B0aW9ucygpIGNvbnN0OworICB2b2lkIGNsZWFyX29wdGlvbnMoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrT3B0aW9uc0ZpZWxkTnVtYmVyID0gNDsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRob2RPcHRpb25zJiBvcHRpb25zKCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0aG9kT3B0aW9ucyogbXV0YWJsZV9vcHRpb25zKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0aG9kT3B0aW9ucyogcmVsZWFzZV9vcHRpb25zKCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF9vcHRpb25zKDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0aG9kT3B0aW9ucyogb3B0aW9ucyk7CisKKyAgLy8gb3B0aW9uYWwgYm9vbCBjbGllbnRfc3RyZWFtaW5nID0gNSBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgYm9vbCBoYXNfY2xpZW50X3N0cmVhbWluZygpIGNvbnN0OworICB2b2lkIGNsZWFyX2NsaWVudF9zdHJlYW1pbmcoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrQ2xpZW50U3RyZWFtaW5nRmllbGROdW1iZXIgPSA1OworICBib29sIGNsaWVudF9zdHJlYW1pbmcoKSBjb25zdDsKKyAgdm9pZCBzZXRfY2xpZW50X3N0cmVhbWluZyhib29sIHZhbHVlKTsKKworICAvLyBvcHRpb25hbCBib29sIHNlcnZlcl9zdHJlYW1pbmcgPSA2IFtkZWZhdWx0ID0gZmFsc2VdOworICBib29sIGhhc19zZXJ2ZXJfc3RyZWFtaW5nKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfc2VydmVyX3N0cmVhbWluZygpOworICBzdGF0aWMgY29uc3QgaW50IGtTZXJ2ZXJTdHJlYW1pbmdGaWVsZE51bWJlciA9IDY7CisgIGJvb2wgc2VydmVyX3N0cmVhbWluZygpIGNvbnN0OworICB2b2lkIHNldF9zZXJ2ZXJfc3RyZWFtaW5nKGJvb2wgdmFsdWUpOworCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvKQorIHByaXZhdGU6CisgIGlubGluZSB2b2lkIHNldF9oYXNfbmFtZSgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfbmFtZSgpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX2lucHV0X3R5cGUoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX2lucHV0X3R5cGUoKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19vdXRwdXRfdHlwZSgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfb3V0cHV0X3R5cGUoKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19vcHRpb25zKCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc19vcHRpb25zKCk7CisgIGlubGluZSB2b2lkIHNldF9oYXNfY2xpZW50X3N0cmVhbWluZygpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfY2xpZW50X3N0cmVhbWluZygpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX3NlcnZlcl9zdHJlYW1pbmcoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX3NlcnZlcl9zdHJlYW1pbmcoKTsKKworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpJbnRlcm5hbE1ldGFkYXRhV2l0aEFyZW5hIF9pbnRlcm5hbF9tZXRhZGF0YV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIF9oYXNfYml0c19bMV07CisgIG11dGFibGUgaW50IF9jYWNoZWRfc2l6ZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFyZW5hU3RyaW5nUHRyIG5hbWVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBcmVuYVN0cmluZ1B0ciBpbnB1dF90eXBlXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QXJlbmFTdHJpbmdQdHIgb3V0cHV0X3R5cGVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGhvZE9wdGlvbnMqIG9wdGlvbnNfOworICBib29sIGNsaWVudF9zdHJlYW1pbmdfOworICBib29sIHNlcnZlcl9zdHJlYW1pbmdfOworICBmcmllbmQgdm9pZCBMSUJQUk9UT0JVRl9FWFBPUlQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworCisgIHZvaWQgSW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIHN0YXRpYyBNZXRob2REZXNjcmlwdG9yUHJvdG8qIGRlZmF1bHRfaW5zdGFuY2VfOworfTsKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEZpbGVPcHRpb25zIDogcHVibGljIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSB7CisgcHVibGljOgorICBGaWxlT3B0aW9ucygpOworICB2aXJ0dWFsIH5GaWxlT3B0aW9ucygpOworCisgIEZpbGVPcHRpb25zKGNvbnN0IEZpbGVPcHRpb25zJiBmcm9tKTsKKworICBpbmxpbmUgRmlsZU9wdGlvbnMmIG9wZXJhdG9yPShjb25zdCBGaWxlT3B0aW9ucyYgZnJvbSkgeworICAgIENvcHlGcm9tKGZyb20pOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIGlubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlVua25vd25GaWVsZFNldCYgdW5rbm93bl9maWVsZHMoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8udW5rbm93bl9maWVsZHMoKTsKKyAgfQorCisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlVua25vd25GaWVsZFNldCogbXV0YWJsZV91bmtub3duX2ZpZWxkcygpIHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5tdXRhYmxlX3Vua25vd25fZmllbGRzKCk7CisgIH0KKworICBzdGF0aWMgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKCk7CisgIHN0YXRpYyBjb25zdCBGaWxlT3B0aW9ucyYgZGVmYXVsdF9pbnN0YW5jZSgpOworCisgIHZvaWQgU3dhcChGaWxlT3B0aW9ucyogb3RoZXIpOworCisgIC8vIGltcGxlbWVudHMgTWVzc2FnZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgaW5saW5lIEZpbGVPcHRpb25zKiBOZXcoKSBjb25zdCB7IHJldHVybiBOZXcoTlVMTCk7IH0KKworICBGaWxlT3B0aW9ucyogTmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdDsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIENvcHlGcm9tKGNvbnN0IEZpbGVPcHRpb25zJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgRmlsZU9wdGlvbnMmIGZyb20pOworICB2b2lkIENsZWFyKCk7CisgIGJvb2wgSXNJbml0aWFsaXplZCgpIGNvbnN0OworCisgIGludCBCeXRlU2l6ZSgpIGNvbnN0OworICBib29sIE1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KTsKKyAgdm9pZCBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSg6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBvdXRwdXQpIGNvbnN0OworICBpbnQgR2V0Q2FjaGVkU2l6ZSgpIGNvbnN0IHsgcmV0dXJuIF9jYWNoZWRfc2l6ZV87IH0KKyAgcHJpdmF0ZToKKyAgdm9pZCBTaGFyZWRDdG9yKCk7CisgIHZvaWQgU2hhcmVkRHRvcigpOworICB2b2lkIFNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0OworICB2b2lkIEludGVybmFsU3dhcChGaWxlT3B0aW9ucyogb3RoZXIpOworICBwcml2YXRlOgorICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogR2V0QXJlbmFOb1ZpcnR1YWwoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8uYXJlbmEoKTsKKyAgfQorICBpbmxpbmUgdm9pZCogTWF5YmVBcmVuYVB0cigpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5yYXdfYXJlbmFfcHRyKCk7CisgIH0KKyAgcHVibGljOgorCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgR2V0TWV0YWRhdGEoKSBjb25zdDsKKworICAvLyBuZXN0ZWQgdHlwZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIHR5cGVkZWYgRmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlIE9wdGltaXplTW9kZTsKKyAgc3RhdGljIGNvbnN0IE9wdGltaXplTW9kZSBTUEVFRCA9IEZpbGVPcHRpb25zX09wdGltaXplTW9kZV9TUEVFRDsKKyAgc3RhdGljIGNvbnN0IE9wdGltaXplTW9kZSBDT0RFX1NJWkUgPSBGaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGVfQ09ERV9TSVpFOworICBzdGF0aWMgY29uc3QgT3B0aW1pemVNb2RlIExJVEVfUlVOVElNRSA9IEZpbGVPcHRpb25zX09wdGltaXplTW9kZV9MSVRFX1JVTlRJTUU7CisgIHN0YXRpYyBpbmxpbmUgYm9vbCBPcHRpbWl6ZU1vZGVfSXNWYWxpZChpbnQgdmFsdWUpIHsKKyAgICByZXR1cm4gRmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlX0lzVmFsaWQodmFsdWUpOworICB9CisgIHN0YXRpYyBjb25zdCBPcHRpbWl6ZU1vZGUgT3B0aW1pemVNb2RlX01JTiA9CisgICAgRmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlX09wdGltaXplTW9kZV9NSU47CisgIHN0YXRpYyBjb25zdCBPcHRpbWl6ZU1vZGUgT3B0aW1pemVNb2RlX01BWCA9CisgICAgRmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlX09wdGltaXplTW9kZV9NQVg7CisgIHN0YXRpYyBjb25zdCBpbnQgT3B0aW1pemVNb2RlX0FSUkFZU0laRSA9CisgICAgRmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlX09wdGltaXplTW9kZV9BUlJBWVNJWkU7CisgIHN0YXRpYyBpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvcioKKyAgT3B0aW1pemVNb2RlX2Rlc2NyaXB0b3IoKSB7CisgICAgcmV0dXJuIEZpbGVPcHRpb25zX09wdGltaXplTW9kZV9kZXNjcmlwdG9yKCk7CisgIH0KKyAgc3RhdGljIGlubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBPcHRpbWl6ZU1vZGVfTmFtZShPcHRpbWl6ZU1vZGUgdmFsdWUpIHsKKyAgICByZXR1cm4gRmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlX05hbWUodmFsdWUpOworICB9CisgIHN0YXRpYyBpbmxpbmUgYm9vbCBPcHRpbWl6ZU1vZGVfUGFyc2UoY29uc3QgOjpzdGQ6OnN0cmluZyYgbmFtZSwKKyAgICAgIE9wdGltaXplTW9kZSogdmFsdWUpIHsKKyAgICByZXR1cm4gRmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlX1BhcnNlKG5hbWUsIHZhbHVlKTsKKyAgfQorCisgIC8vIGFjY2Vzc29ycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIGphdmFfcGFja2FnZSA9IDE7CisgIGJvb2wgaGFzX2phdmFfcGFja2FnZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX2phdmFfcGFja2FnZSgpOworICBzdGF0aWMgY29uc3QgaW50IGtKYXZhUGFja2FnZUZpZWxkTnVtYmVyID0gMTsKKyAgY29uc3QgOjpzdGQ6OnN0cmluZyYgamF2YV9wYWNrYWdlKCkgY29uc3Q7CisgIHZvaWQgc2V0X2phdmFfcGFja2FnZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X2phdmFfcGFja2FnZShjb25zdCBjaGFyKiB2YWx1ZSk7CisgIHZvaWQgc2V0X2phdmFfcGFja2FnZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpOworICA6OnN0ZDo6c3RyaW5nKiBtdXRhYmxlX2phdmFfcGFja2FnZSgpOworICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlX2phdmFfcGFja2FnZSgpOworICB2b2lkIHNldF9hbGxvY2F0ZWRfamF2YV9wYWNrYWdlKDo6c3RkOjpzdHJpbmcqIGphdmFfcGFja2FnZSk7CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIGphdmFfb3V0ZXJfY2xhc3NuYW1lID0gODsKKyAgYm9vbCBoYXNfamF2YV9vdXRlcl9jbGFzc25hbWUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9qYXZhX291dGVyX2NsYXNzbmFtZSgpOworICBzdGF0aWMgY29uc3QgaW50IGtKYXZhT3V0ZXJDbGFzc25hbWVGaWVsZE51bWJlciA9IDg7CisgIGNvbnN0IDo6c3RkOjpzdHJpbmcmIGphdmFfb3V0ZXJfY2xhc3NuYW1lKCkgY29uc3Q7CisgIHZvaWQgc2V0X2phdmFfb3V0ZXJfY2xhc3NuYW1lKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKTsKKyAgdm9pZCBzZXRfamF2YV9vdXRlcl9jbGFzc25hbWUoY29uc3QgY2hhciogdmFsdWUpOworICB2b2lkIHNldF9qYXZhX291dGVyX2NsYXNzbmFtZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpOworICA6OnN0ZDo6c3RyaW5nKiBtdXRhYmxlX2phdmFfb3V0ZXJfY2xhc3NuYW1lKCk7CisgIDo6c3RkOjpzdHJpbmcqIHJlbGVhc2VfamF2YV9vdXRlcl9jbGFzc25hbWUoKTsKKyAgdm9pZCBzZXRfYWxsb2NhdGVkX2phdmFfb3V0ZXJfY2xhc3NuYW1lKDo6c3RkOjpzdHJpbmcqIGphdmFfb3V0ZXJfY2xhc3NuYW1lKTsKKworICAvLyBvcHRpb25hbCBib29sIGphdmFfbXVsdGlwbGVfZmlsZXMgPSAxMCBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgYm9vbCBoYXNfamF2YV9tdWx0aXBsZV9maWxlcygpIGNvbnN0OworICB2b2lkIGNsZWFyX2phdmFfbXVsdGlwbGVfZmlsZXMoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrSmF2YU11bHRpcGxlRmlsZXNGaWVsZE51bWJlciA9IDEwOworICBib29sIGphdmFfbXVsdGlwbGVfZmlsZXMoKSBjb25zdDsKKyAgdm9pZCBzZXRfamF2YV9tdWx0aXBsZV9maWxlcyhib29sIHZhbHVlKTsKKworICAvLyBvcHRpb25hbCBib29sIGphdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoID0gMjAgW2RlZmF1bHQgPSBmYWxzZV07CisgIGJvb2wgaGFzX2phdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2goKTsKKyAgc3RhdGljIGNvbnN0IGludCBrSmF2YUdlbmVyYXRlRXF1YWxzQW5kSGFzaEZpZWxkTnVtYmVyID0gMjA7CisgIGJvb2wgamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2goKSBjb25zdDsKKyAgdm9pZCBzZXRfamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2goYm9vbCB2YWx1ZSk7CisKKyAgLy8gb3B0aW9uYWwgYm9vbCBqYXZhX3N0cmluZ19jaGVja191dGY4ID0gMjcgW2RlZmF1bHQgPSBmYWxzZV07CisgIGJvb2wgaGFzX2phdmFfc3RyaW5nX2NoZWNrX3V0ZjgoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9qYXZhX3N0cmluZ19jaGVja191dGY4KCk7CisgIHN0YXRpYyBjb25zdCBpbnQga0phdmFTdHJpbmdDaGVja1V0ZjhGaWVsZE51bWJlciA9IDI3OworICBib29sIGphdmFfc3RyaW5nX2NoZWNrX3V0ZjgoKSBjb25zdDsKKyAgdm9pZCBzZXRfamF2YV9zdHJpbmdfY2hlY2tfdXRmOChib29sIHZhbHVlKTsKKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLk9wdGltaXplTW9kZSBvcHRpbWl6ZV9mb3IgPSA5IFtkZWZhdWx0ID0gU1BFRURdOworICBib29sIGhhc19vcHRpbWl6ZV9mb3IoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9vcHRpbWl6ZV9mb3IoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrT3B0aW1pemVGb3JGaWVsZE51bWJlciA9IDk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlIG9wdGltaXplX2ZvcigpIGNvbnN0OworICB2b2lkIHNldF9vcHRpbWl6ZV9mb3IoOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGUgdmFsdWUpOworCisgIC8vIG9wdGlvbmFsIHN0cmluZyBnb19wYWNrYWdlID0gMTE7CisgIGJvb2wgaGFzX2dvX3BhY2thZ2UoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9nb19wYWNrYWdlKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga0dvUGFja2FnZUZpZWxkTnVtYmVyID0gMTE7CisgIGNvbnN0IDo6c3RkOjpzdHJpbmcmIGdvX3BhY2thZ2UoKSBjb25zdDsKKyAgdm9pZCBzZXRfZ29fcGFja2FnZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X2dvX3BhY2thZ2UoY29uc3QgY2hhciogdmFsdWUpOworICB2b2lkIHNldF9nb19wYWNrYWdlKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIDo6c3RkOjpzdHJpbmcqIG11dGFibGVfZ29fcGFja2FnZSgpOworICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlX2dvX3BhY2thZ2UoKTsKKyAgdm9pZCBzZXRfYWxsb2NhdGVkX2dvX3BhY2thZ2UoOjpzdGQ6OnN0cmluZyogZ29fcGFja2FnZSk7CisKKyAgLy8gb3B0aW9uYWwgYm9vbCBjY19nZW5lcmljX3NlcnZpY2VzID0gMTYgW2RlZmF1bHQgPSBmYWxzZV07CisgIGJvb2wgaGFzX2NjX2dlbmVyaWNfc2VydmljZXMoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9jY19nZW5lcmljX3NlcnZpY2VzKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga0NjR2VuZXJpY1NlcnZpY2VzRmllbGROdW1iZXIgPSAxNjsKKyAgYm9vbCBjY19nZW5lcmljX3NlcnZpY2VzKCkgY29uc3Q7CisgIHZvaWQgc2V0X2NjX2dlbmVyaWNfc2VydmljZXMoYm9vbCB2YWx1ZSk7CisKKyAgLy8gb3B0aW9uYWwgYm9vbCBqYXZhX2dlbmVyaWNfc2VydmljZXMgPSAxNyBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgYm9vbCBoYXNfamF2YV9nZW5lcmljX3NlcnZpY2VzKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfamF2YV9nZW5lcmljX3NlcnZpY2VzKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga0phdmFHZW5lcmljU2VydmljZXNGaWVsZE51bWJlciA9IDE3OworICBib29sIGphdmFfZ2VuZXJpY19zZXJ2aWNlcygpIGNvbnN0OworICB2b2lkIHNldF9qYXZhX2dlbmVyaWNfc2VydmljZXMoYm9vbCB2YWx1ZSk7CisKKyAgLy8gb3B0aW9uYWwgYm9vbCBweV9nZW5lcmljX3NlcnZpY2VzID0gMTggW2RlZmF1bHQgPSBmYWxzZV07CisgIGJvb2wgaGFzX3B5X2dlbmVyaWNfc2VydmljZXMoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9weV9nZW5lcmljX3NlcnZpY2VzKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga1B5R2VuZXJpY1NlcnZpY2VzRmllbGROdW1iZXIgPSAxODsKKyAgYm9vbCBweV9nZW5lcmljX3NlcnZpY2VzKCkgY29uc3Q7CisgIHZvaWQgc2V0X3B5X2dlbmVyaWNfc2VydmljZXMoYm9vbCB2YWx1ZSk7CisKKyAgLy8gb3B0aW9uYWwgYm9vbCBkZXByZWNhdGVkID0gMjMgW2RlZmF1bHQgPSBmYWxzZV07CisgIGJvb2wgaGFzX2RlcHJlY2F0ZWQoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9kZXByZWNhdGVkKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga0RlcHJlY2F0ZWRGaWVsZE51bWJlciA9IDIzOworICBib29sIGRlcHJlY2F0ZWQoKSBjb25zdDsKKyAgdm9pZCBzZXRfZGVwcmVjYXRlZChib29sIHZhbHVlKTsKKworICAvLyBvcHRpb25hbCBib29sIGNjX2VuYWJsZV9hcmVuYXMgPSAzMSBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgYm9vbCBoYXNfY2NfZW5hYmxlX2FyZW5hcygpIGNvbnN0OworICB2b2lkIGNsZWFyX2NjX2VuYWJsZV9hcmVuYXMoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrQ2NFbmFibGVBcmVuYXNGaWVsZE51bWJlciA9IDMxOworICBib29sIGNjX2VuYWJsZV9hcmVuYXMoKSBjb25zdDsKKyAgdm9pZCBzZXRfY2NfZW5hYmxlX2FyZW5hcyhib29sIHZhbHVlKTsKKworICAvLyBvcHRpb25hbCBzdHJpbmcgb2JqY19jbGFzc19wcmVmaXggPSAzNjsKKyAgYm9vbCBoYXNfb2JqY19jbGFzc19wcmVmaXgoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9vYmpjX2NsYXNzX3ByZWZpeCgpOworICBzdGF0aWMgY29uc3QgaW50IGtPYmpjQ2xhc3NQcmVmaXhGaWVsZE51bWJlciA9IDM2OworICBjb25zdCA6OnN0ZDo6c3RyaW5nJiBvYmpjX2NsYXNzX3ByZWZpeCgpIGNvbnN0OworICB2b2lkIHNldF9vYmpjX2NsYXNzX3ByZWZpeChjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X29iamNfY2xhc3NfcHJlZml4KGNvbnN0IGNoYXIqIHZhbHVlKTsKKyAgdm9pZCBzZXRfb2JqY19jbGFzc19wcmVmaXgoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKTsKKyAgOjpzdGQ6OnN0cmluZyogbXV0YWJsZV9vYmpjX2NsYXNzX3ByZWZpeCgpOworICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlX29iamNfY2xhc3NfcHJlZml4KCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF9vYmpjX2NsYXNzX3ByZWZpeCg6OnN0ZDo6c3RyaW5nKiBvYmpjX2NsYXNzX3ByZWZpeCk7CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIGNzaGFycF9uYW1lc3BhY2UgPSAzNzsKKyAgYm9vbCBoYXNfY3NoYXJwX25hbWVzcGFjZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX2NzaGFycF9uYW1lc3BhY2UoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrQ3NoYXJwTmFtZXNwYWNlRmllbGROdW1iZXIgPSAzNzsKKyAgY29uc3QgOjpzdGQ6OnN0cmluZyYgY3NoYXJwX25hbWVzcGFjZSgpIGNvbnN0OworICB2b2lkIHNldF9jc2hhcnBfbmFtZXNwYWNlKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKTsKKyAgdm9pZCBzZXRfY3NoYXJwX25hbWVzcGFjZShjb25zdCBjaGFyKiB2YWx1ZSk7CisgIHZvaWQgc2V0X2NzaGFycF9uYW1lc3BhY2UoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKTsKKyAgOjpzdGQ6OnN0cmluZyogbXV0YWJsZV9jc2hhcnBfbmFtZXNwYWNlKCk7CisgIDo6c3RkOjpzdHJpbmcqIHJlbGVhc2VfY3NoYXJwX25hbWVzcGFjZSgpOworICB2b2lkIHNldF9hbGxvY2F0ZWRfY3NoYXJwX25hbWVzcGFjZSg6OnN0ZDo6c3RyaW5nKiBjc2hhcnBfbmFtZXNwYWNlKTsKKworICAvLyBvcHRpb25hbCBib29sIGphdmFuYW5vX3VzZV9kZXByZWNhdGVkX3BhY2thZ2UgPSAzOCBbZGVwcmVjYXRlZCA9IHRydWVdOworICBib29sIGhhc19qYXZhbmFub191c2VfZGVwcmVjYXRlZF9wYWNrYWdlKCkgY29uc3QgUFJPVE9CVUZfREVQUkVDQVRFRDsKKyAgdm9pZCBjbGVhcl9qYXZhbmFub191c2VfZGVwcmVjYXRlZF9wYWNrYWdlKCkgUFJPVE9CVUZfREVQUkVDQVRFRDsKKyAgc3RhdGljIGNvbnN0IGludCBrSmF2YW5hbm9Vc2VEZXByZWNhdGVkUGFja2FnZUZpZWxkTnVtYmVyID0gMzg7CisgIGJvb2wgamF2YW5hbm9fdXNlX2RlcHJlY2F0ZWRfcGFja2FnZSgpIGNvbnN0IFBST1RPQlVGX0RFUFJFQ0FURUQ7CisgIHZvaWQgc2V0X2phdmFuYW5vX3VzZV9kZXByZWNhdGVkX3BhY2thZ2UoYm9vbCB2YWx1ZSkgUFJPVE9CVUZfREVQUkVDQVRFRDsKKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CisgIGludCB1bmludGVycHJldGVkX29wdGlvbl9zaXplKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfdW5pbnRlcnByZXRlZF9vcHRpb24oKTsKKyAgc3RhdGljIGNvbnN0IGludCBrVW5pbnRlcnByZXRlZE9wdGlvbkZpZWxkTnVtYmVyID0gOTk5OworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24mIHVuaW50ZXJwcmV0ZWRfb3B0aW9uKGludCBpbmRleCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiogbXV0YWJsZV91bmludGVycHJldGVkX29wdGlvbihpbnQgaW5kZXgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24qIGFkZF91bmludGVycHJldGVkX29wdGlvbigpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiA+KgorICAgICAgbXV0YWJsZV91bmludGVycHJldGVkX29wdGlvbigpOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiA+JgorICAgICAgdW5pbnRlcnByZXRlZF9vcHRpb24oKSBjb25zdDsKKworICBHT09HTEVfUFJPVE9CVUZfRVhURU5TSU9OX0FDQ0VTU09SUyhGaWxlT3B0aW9ucykKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucykKKyBwcml2YXRlOgorICBpbmxpbmUgdm9pZCBzZXRfaGFzX2phdmFfcGFja2FnZSgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfamF2YV9wYWNrYWdlKCk7CisgIGlubGluZSB2b2lkIHNldF9oYXNfamF2YV9vdXRlcl9jbGFzc25hbWUoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX2phdmFfb3V0ZXJfY2xhc3NuYW1lKCk7CisgIGlubGluZSB2b2lkIHNldF9oYXNfamF2YV9tdWx0aXBsZV9maWxlcygpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfamF2YV9tdWx0aXBsZV9maWxlcygpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX2phdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoKCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc19qYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaCgpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX2phdmFfc3RyaW5nX2NoZWNrX3V0ZjgoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX2phdmFfc3RyaW5nX2NoZWNrX3V0ZjgoKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19vcHRpbWl6ZV9mb3IoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX29wdGltaXplX2ZvcigpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX2dvX3BhY2thZ2UoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX2dvX3BhY2thZ2UoKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19jY19nZW5lcmljX3NlcnZpY2VzKCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc19jY19nZW5lcmljX3NlcnZpY2VzKCk7CisgIGlubGluZSB2b2lkIHNldF9oYXNfamF2YV9nZW5lcmljX3NlcnZpY2VzKCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc19qYXZhX2dlbmVyaWNfc2VydmljZXMoKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19weV9nZW5lcmljX3NlcnZpY2VzKCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc19weV9nZW5lcmljX3NlcnZpY2VzKCk7CisgIGlubGluZSB2b2lkIHNldF9oYXNfZGVwcmVjYXRlZCgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfZGVwcmVjYXRlZCgpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX2NjX2VuYWJsZV9hcmVuYXMoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX2NjX2VuYWJsZV9hcmVuYXMoKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19vYmpjX2NsYXNzX3ByZWZpeCgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfb2JqY19jbGFzc19wcmVmaXgoKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19jc2hhcnBfbmFtZXNwYWNlKCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc19jc2hhcnBfbmFtZXNwYWNlKCk7CisgIGlubGluZSB2b2lkIHNldF9oYXNfamF2YW5hbm9fdXNlX2RlcHJlY2F0ZWRfcGFja2FnZSgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfamF2YW5hbm9fdXNlX2RlcHJlY2F0ZWRfcGFja2FnZSgpOworCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkV4dGVuc2lvblNldCBfZXh0ZW5zaW9uc187CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6SW50ZXJuYWxNZXRhZGF0YVdpdGhBcmVuYSBfaW50ZXJuYWxfbWV0YWRhdGFfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiBfaGFzX2JpdHNfWzFdOworICBtdXRhYmxlIGludCBfY2FjaGVkX3NpemVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBcmVuYVN0cmluZ1B0ciBqYXZhX3BhY2thZ2VfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBcmVuYVN0cmluZ1B0ciBqYXZhX291dGVyX2NsYXNzbmFtZV87CisgIGJvb2wgamF2YV9tdWx0aXBsZV9maWxlc187CisgIGJvb2wgamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2hfOworICBib29sIGphdmFfc3RyaW5nX2NoZWNrX3V0ZjhfOworICBib29sIGNjX2dlbmVyaWNfc2VydmljZXNfOworICBpbnQgb3B0aW1pemVfZm9yXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QXJlbmFTdHJpbmdQdHIgZ29fcGFja2FnZV87CisgIGJvb2wgamF2YV9nZW5lcmljX3NlcnZpY2VzXzsKKyAgYm9vbCBweV9nZW5lcmljX3NlcnZpY2VzXzsKKyAgYm9vbCBkZXByZWNhdGVkXzsKKyAgYm9vbCBjY19lbmFibGVfYXJlbmFzXzsKKyAgYm9vbCBqYXZhbmFub191c2VfZGVwcmVjYXRlZF9wYWNrYWdlXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QXJlbmFTdHJpbmdQdHIgb2JqY19jbGFzc19wcmVmaXhfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBcmVuYVN0cmluZ1B0ciBjc2hhcnBfbmFtZXNwYWNlXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24gPiB1bmludGVycHJldGVkX29wdGlvbl87CisgIGZyaWVuZCB2b2lkIExJQlBST1RPQlVGX0VYUE9SVCBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfU2h1dGRvd25GaWxlX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisKKyAgdm9pZCBJbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgc3RhdGljIEZpbGVPcHRpb25zKiBkZWZhdWx0X2luc3RhbmNlXzsKK307CisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBNZXNzYWdlT3B0aW9ucyA6IHB1YmxpYyA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UgeworIHB1YmxpYzoKKyAgTWVzc2FnZU9wdGlvbnMoKTsKKyAgdmlydHVhbCB+TWVzc2FnZU9wdGlvbnMoKTsKKworICBNZXNzYWdlT3B0aW9ucyhjb25zdCBNZXNzYWdlT3B0aW9ucyYgZnJvbSk7CisKKyAgaW5saW5lIE1lc3NhZ2VPcHRpb25zJiBvcGVyYXRvcj0oY29uc3QgTWVzc2FnZU9wdGlvbnMmIGZyb20pIHsKKyAgICBDb3B5RnJvbShmcm9tKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworICBpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpVbmtub3duRmllbGRTZXQmIHVua25vd25fZmllbGRzKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnVua25vd25fZmllbGRzKCk7CisgIH0KKworICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpVbmtub3duRmllbGRTZXQqIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ubXV0YWJsZV91bmtub3duX2ZpZWxkcygpOworICB9CisKKyAgc3RhdGljIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogZGVzY3JpcHRvcigpOworICBzdGF0aWMgY29uc3QgTWVzc2FnZU9wdGlvbnMmIGRlZmF1bHRfaW5zdGFuY2UoKTsKKworICB2b2lkIFN3YXAoTWVzc2FnZU9wdGlvbnMqIG90aGVyKTsKKworICAvLyBpbXBsZW1lbnRzIE1lc3NhZ2UgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIGlubGluZSBNZXNzYWdlT3B0aW9ucyogTmV3KCkgY29uc3QgeyByZXR1cm4gTmV3KE5VTEwpOyB9CisKKyAgTWVzc2FnZU9wdGlvbnMqIE5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3Q7CisgIHZvaWQgQ29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCBNZXNzYWdlT3B0aW9ucyYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IE1lc3NhZ2VPcHRpb25zJiBmcm9tKTsKKyAgdm9pZCBDbGVhcigpOworICBib29sIElzSW5pdGlhbGl6ZWQoKSBjb25zdDsKKworICBpbnQgQnl0ZVNpemUoKSBjb25zdDsKKyAgYm9vbCBNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCk7CisgIHZvaWQgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogb3V0cHV0KSBjb25zdDsKKyAgaW50IEdldENhY2hlZFNpemUoKSBjb25zdCB7IHJldHVybiBfY2FjaGVkX3NpemVfOyB9CisgIHByaXZhdGU6CisgIHZvaWQgU2hhcmVkQ3RvcigpOworICB2b2lkIFNoYXJlZER0b3IoKTsKKyAgdm9pZCBTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdDsKKyAgdm9pZCBJbnRlcm5hbFN3YXAoTWVzc2FnZU9wdGlvbnMqIG90aGVyKTsKKyAgcHJpdmF0ZToKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hTm9WaXJ0dWFsKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLmFyZW5hKCk7CisgIH0KKyAgaW5saW5lIHZvaWQqIE1heWJlQXJlbmFQdHIoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ucmF3X2FyZW5hX3B0cigpOworICB9CisgIHB1YmxpYzoKKworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEdldE1ldGFkYXRhKCkgY29uc3Q7CisKKyAgLy8gbmVzdGVkIHR5cGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBhY2Nlc3NvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIG9wdGlvbmFsIGJvb2wgbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQgPSAxIFtkZWZhdWx0ID0gZmFsc2VdOworICBib29sIGhhc19tZXNzYWdlX3NldF93aXJlX2Zvcm1hdCgpIGNvbnN0OworICB2b2lkIGNsZWFyX21lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KCk7CisgIHN0YXRpYyBjb25zdCBpbnQga01lc3NhZ2VTZXRXaXJlRm9ybWF0RmllbGROdW1iZXIgPSAxOworICBib29sIG1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KCkgY29uc3Q7CisgIHZvaWQgc2V0X21lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KGJvb2wgdmFsdWUpOworCisgIC8vIG9wdGlvbmFsIGJvb2wgbm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvciA9IDIgW2RlZmF1bHQgPSBmYWxzZV07CisgIGJvb2wgaGFzX25vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3IoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga05vU3RhbmRhcmREZXNjcmlwdG9yQWNjZXNzb3JGaWVsZE51bWJlciA9IDI7CisgIGJvb2wgbm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvcigpIGNvbnN0OworICB2b2lkIHNldF9ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yKGJvb2wgdmFsdWUpOworCisgIC8vIG9wdGlvbmFsIGJvb2wgZGVwcmVjYXRlZCA9IDMgW2RlZmF1bHQgPSBmYWxzZV07CisgIGJvb2wgaGFzX2RlcHJlY2F0ZWQoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9kZXByZWNhdGVkKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga0RlcHJlY2F0ZWRGaWVsZE51bWJlciA9IDM7CisgIGJvb2wgZGVwcmVjYXRlZCgpIGNvbnN0OworICB2b2lkIHNldF9kZXByZWNhdGVkKGJvb2wgdmFsdWUpOworCisgIC8vIG9wdGlvbmFsIGJvb2wgbWFwX2VudHJ5ID0gNzsKKyAgYm9vbCBoYXNfbWFwX2VudHJ5KCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfbWFwX2VudHJ5KCk7CisgIHN0YXRpYyBjb25zdCBpbnQga01hcEVudHJ5RmllbGROdW1iZXIgPSA3OworICBib29sIG1hcF9lbnRyeSgpIGNvbnN0OworICB2b2lkIHNldF9tYXBfZW50cnkoYm9vbCB2YWx1ZSk7CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIHVuaW50ZXJwcmV0ZWRfb3B0aW9uID0gOTk5OworICBpbnQgdW5pbnRlcnByZXRlZF9vcHRpb25fc2l6ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga1VuaW50ZXJwcmV0ZWRPcHRpb25GaWVsZE51bWJlciA9IDk5OTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uJiB1bmludGVycHJldGVkX29wdGlvbihpbnQgaW5kZXgpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24qIG11dGFibGVfdW5pbnRlcnByZXRlZF9vcHRpb24oaW50IGluZGV4KTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uKiBhZGRfdW5pbnRlcnByZXRlZF9vcHRpb24oKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24gPioKKyAgICAgIG11dGFibGVfdW5pbnRlcnByZXRlZF9vcHRpb24oKTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24gPiYKKyAgICAgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgY29uc3Q7CisKKyAgR09PR0xFX1BST1RPQlVGX0VYVEVOU0lPTl9BQ0NFU1NPUlMoTWVzc2FnZU9wdGlvbnMpCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpnb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMpCisgcHJpdmF0ZToKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19tZXNzYWdlX3NldF93aXJlX2Zvcm1hdCgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQoKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yKCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc19ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yKCk7CisgIGlubGluZSB2b2lkIHNldF9oYXNfZGVwcmVjYXRlZCgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfZGVwcmVjYXRlZCgpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX21hcF9lbnRyeSgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfbWFwX2VudHJ5KCk7CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RXh0ZW5zaW9uU2V0IF9leHRlbnNpb25zXzsKKworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpJbnRlcm5hbE1ldGFkYXRhV2l0aEFyZW5hIF9pbnRlcm5hbF9tZXRhZGF0YV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIF9oYXNfYml0c19bMV07CisgIG11dGFibGUgaW50IF9jYWNoZWRfc2l6ZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uID4gdW5pbnRlcnByZXRlZF9vcHRpb25fOworICBib29sIG1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0XzsKKyAgYm9vbCBub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yXzsKKyAgYm9vbCBkZXByZWNhdGVkXzsKKyAgYm9vbCBtYXBfZW50cnlfOworICBmcmllbmQgdm9pZCBMSUJQUk9UT0JVRl9FWFBPUlQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworCisgIHZvaWQgSW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIHN0YXRpYyBNZXNzYWdlT3B0aW9ucyogZGVmYXVsdF9pbnN0YW5jZV87Cit9OworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgRmllbGRPcHRpb25zIDogcHVibGljIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSB7CisgcHVibGljOgorICBGaWVsZE9wdGlvbnMoKTsKKyAgdmlydHVhbCB+RmllbGRPcHRpb25zKCk7CisKKyAgRmllbGRPcHRpb25zKGNvbnN0IEZpZWxkT3B0aW9ucyYgZnJvbSk7CisKKyAgaW5saW5lIEZpZWxkT3B0aW9ucyYgb3BlcmF0b3I9KGNvbnN0IEZpZWxkT3B0aW9ucyYgZnJvbSkgeworICAgIENvcHlGcm9tKGZyb20pOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIGlubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlVua25vd25GaWVsZFNldCYgdW5rbm93bl9maWVsZHMoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8udW5rbm93bl9maWVsZHMoKTsKKyAgfQorCisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlVua25vd25GaWVsZFNldCogbXV0YWJsZV91bmtub3duX2ZpZWxkcygpIHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5tdXRhYmxlX3Vua25vd25fZmllbGRzKCk7CisgIH0KKworICBzdGF0aWMgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKCk7CisgIHN0YXRpYyBjb25zdCBGaWVsZE9wdGlvbnMmIGRlZmF1bHRfaW5zdGFuY2UoKTsKKworICB2b2lkIFN3YXAoRmllbGRPcHRpb25zKiBvdGhlcik7CisKKyAgLy8gaW1wbGVtZW50cyBNZXNzYWdlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBpbmxpbmUgRmllbGRPcHRpb25zKiBOZXcoKSBjb25zdCB7IHJldHVybiBOZXcoTlVMTCk7IH0KKworICBGaWVsZE9wdGlvbnMqIE5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3Q7CisgIHZvaWQgQ29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCBGaWVsZE9wdGlvbnMmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCBGaWVsZE9wdGlvbnMmIGZyb20pOworICB2b2lkIENsZWFyKCk7CisgIGJvb2wgSXNJbml0aWFsaXplZCgpIGNvbnN0OworCisgIGludCBCeXRlU2l6ZSgpIGNvbnN0OworICBib29sIE1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KTsKKyAgdm9pZCBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSg6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBvdXRwdXQpIGNvbnN0OworICBpbnQgR2V0Q2FjaGVkU2l6ZSgpIGNvbnN0IHsgcmV0dXJuIF9jYWNoZWRfc2l6ZV87IH0KKyAgcHJpdmF0ZToKKyAgdm9pZCBTaGFyZWRDdG9yKCk7CisgIHZvaWQgU2hhcmVkRHRvcigpOworICB2b2lkIFNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0OworICB2b2lkIEludGVybmFsU3dhcChGaWVsZE9wdGlvbnMqIG90aGVyKTsKKyAgcHJpdmF0ZToKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hTm9WaXJ0dWFsKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLmFyZW5hKCk7CisgIH0KKyAgaW5saW5lIHZvaWQqIE1heWJlQXJlbmFQdHIoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ucmF3X2FyZW5hX3B0cigpOworICB9CisgIHB1YmxpYzoKKworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEdldE1ldGFkYXRhKCkgY29uc3Q7CisKKyAgLy8gbmVzdGVkIHR5cGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICB0eXBlZGVmIEZpZWxkT3B0aW9uc19DVHlwZSBDVHlwZTsKKyAgc3RhdGljIGNvbnN0IENUeXBlIFNUUklORyA9IEZpZWxkT3B0aW9uc19DVHlwZV9TVFJJTkc7CisgIHN0YXRpYyBjb25zdCBDVHlwZSBDT1JEID0gRmllbGRPcHRpb25zX0NUeXBlX0NPUkQ7CisgIHN0YXRpYyBjb25zdCBDVHlwZSBTVFJJTkdfUElFQ0UgPSBGaWVsZE9wdGlvbnNfQ1R5cGVfU1RSSU5HX1BJRUNFOworICBzdGF0aWMgaW5saW5lIGJvb2wgQ1R5cGVfSXNWYWxpZChpbnQgdmFsdWUpIHsKKyAgICByZXR1cm4gRmllbGRPcHRpb25zX0NUeXBlX0lzVmFsaWQodmFsdWUpOworICB9CisgIHN0YXRpYyBjb25zdCBDVHlwZSBDVHlwZV9NSU4gPQorICAgIEZpZWxkT3B0aW9uc19DVHlwZV9DVHlwZV9NSU47CisgIHN0YXRpYyBjb25zdCBDVHlwZSBDVHlwZV9NQVggPQorICAgIEZpZWxkT3B0aW9uc19DVHlwZV9DVHlwZV9NQVg7CisgIHN0YXRpYyBjb25zdCBpbnQgQ1R5cGVfQVJSQVlTSVpFID0KKyAgICBGaWVsZE9wdGlvbnNfQ1R5cGVfQ1R5cGVfQVJSQVlTSVpFOworICBzdGF0aWMgaW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bURlc2NyaXB0b3IqCisgIENUeXBlX2Rlc2NyaXB0b3IoKSB7CisgICAgcmV0dXJuIEZpZWxkT3B0aW9uc19DVHlwZV9kZXNjcmlwdG9yKCk7CisgIH0KKyAgc3RhdGljIGlubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBDVHlwZV9OYW1lKENUeXBlIHZhbHVlKSB7CisgICAgcmV0dXJuIEZpZWxkT3B0aW9uc19DVHlwZV9OYW1lKHZhbHVlKTsKKyAgfQorICBzdGF0aWMgaW5saW5lIGJvb2wgQ1R5cGVfUGFyc2UoY29uc3QgOjpzdGQ6OnN0cmluZyYgbmFtZSwKKyAgICAgIENUeXBlKiB2YWx1ZSkgeworICAgIHJldHVybiBGaWVsZE9wdGlvbnNfQ1R5cGVfUGFyc2UobmFtZSwgdmFsdWUpOworICB9CisKKyAgdHlwZWRlZiBGaWVsZE9wdGlvbnNfSlNUeXBlIEpTVHlwZTsKKyAgc3RhdGljIGNvbnN0IEpTVHlwZSBKU19OT1JNQUwgPSBGaWVsZE9wdGlvbnNfSlNUeXBlX0pTX05PUk1BTDsKKyAgc3RhdGljIGNvbnN0IEpTVHlwZSBKU19TVFJJTkcgPSBGaWVsZE9wdGlvbnNfSlNUeXBlX0pTX1NUUklORzsKKyAgc3RhdGljIGNvbnN0IEpTVHlwZSBKU19OVU1CRVIgPSBGaWVsZE9wdGlvbnNfSlNUeXBlX0pTX05VTUJFUjsKKyAgc3RhdGljIGlubGluZSBib29sIEpTVHlwZV9Jc1ZhbGlkKGludCB2YWx1ZSkgeworICAgIHJldHVybiBGaWVsZE9wdGlvbnNfSlNUeXBlX0lzVmFsaWQodmFsdWUpOworICB9CisgIHN0YXRpYyBjb25zdCBKU1R5cGUgSlNUeXBlX01JTiA9CisgICAgRmllbGRPcHRpb25zX0pTVHlwZV9KU1R5cGVfTUlOOworICBzdGF0aWMgY29uc3QgSlNUeXBlIEpTVHlwZV9NQVggPQorICAgIEZpZWxkT3B0aW9uc19KU1R5cGVfSlNUeXBlX01BWDsKKyAgc3RhdGljIGNvbnN0IGludCBKU1R5cGVfQVJSQVlTSVpFID0KKyAgICBGaWVsZE9wdGlvbnNfSlNUeXBlX0pTVHlwZV9BUlJBWVNJWkU7CisgIHN0YXRpYyBpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvcioKKyAgSlNUeXBlX2Rlc2NyaXB0b3IoKSB7CisgICAgcmV0dXJuIEZpZWxkT3B0aW9uc19KU1R5cGVfZGVzY3JpcHRvcigpOworICB9CisgIHN0YXRpYyBpbmxpbmUgY29uc3QgOjpzdGQ6OnN0cmluZyYgSlNUeXBlX05hbWUoSlNUeXBlIHZhbHVlKSB7CisgICAgcmV0dXJuIEZpZWxkT3B0aW9uc19KU1R5cGVfTmFtZSh2YWx1ZSk7CisgIH0KKyAgc3RhdGljIGlubGluZSBib29sIEpTVHlwZV9QYXJzZShjb25zdCA6OnN0ZDo6c3RyaW5nJiBuYW1lLAorICAgICAgSlNUeXBlKiB2YWx1ZSkgeworICAgIHJldHVybiBGaWVsZE9wdGlvbnNfSlNUeXBlX1BhcnNlKG5hbWUsIHZhbHVlKTsKKyAgfQorCisgIC8vIGFjY2Vzc29ycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuQ1R5cGUgY3R5cGUgPSAxIFtkZWZhdWx0ID0gU1RSSU5HXTsKKyAgYm9vbCBoYXNfY3R5cGUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9jdHlwZSgpOworICBzdGF0aWMgY29uc3QgaW50IGtDdHlwZUZpZWxkTnVtYmVyID0gMTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZE9wdGlvbnNfQ1R5cGUgY3R5cGUoKSBjb25zdDsKKyAgdm9pZCBzZXRfY3R5cGUoOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZE9wdGlvbnNfQ1R5cGUgdmFsdWUpOworCisgIC8vIG9wdGlvbmFsIGJvb2wgcGFja2VkID0gMjsKKyAgYm9vbCBoYXNfcGFja2VkKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfcGFja2VkKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga1BhY2tlZEZpZWxkTnVtYmVyID0gMjsKKyAgYm9vbCBwYWNrZWQoKSBjb25zdDsKKyAgdm9pZCBzZXRfcGFja2VkKGJvb2wgdmFsdWUpOworCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLkpTVHlwZSBqc3R5cGUgPSA2IFtkZWZhdWx0ID0gSlNfTk9STUFMXTsKKyAgYm9vbCBoYXNfanN0eXBlKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfanN0eXBlKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga0pzdHlwZUZpZWxkTnVtYmVyID0gNjsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZE9wdGlvbnNfSlNUeXBlIGpzdHlwZSgpIGNvbnN0OworICB2b2lkIHNldF9qc3R5cGUoOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZE9wdGlvbnNfSlNUeXBlIHZhbHVlKTsKKworICAvLyBvcHRpb25hbCBib29sIGxhenkgPSA1IFtkZWZhdWx0ID0gZmFsc2VdOworICBib29sIGhhc19sYXp5KCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfbGF6eSgpOworICBzdGF0aWMgY29uc3QgaW50IGtMYXp5RmllbGROdW1iZXIgPSA1OworICBib29sIGxhenkoKSBjb25zdDsKKyAgdm9pZCBzZXRfbGF6eShib29sIHZhbHVlKTsKKworICAvLyBvcHRpb25hbCBib29sIGRlcHJlY2F0ZWQgPSAzIFtkZWZhdWx0ID0gZmFsc2VdOworICBib29sIGhhc19kZXByZWNhdGVkKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfZGVwcmVjYXRlZCgpOworICBzdGF0aWMgY29uc3QgaW50IGtEZXByZWNhdGVkRmllbGROdW1iZXIgPSAzOworICBib29sIGRlcHJlY2F0ZWQoKSBjb25zdDsKKyAgdm9pZCBzZXRfZGVwcmVjYXRlZChib29sIHZhbHVlKTsKKworICAvLyBvcHRpb25hbCBib29sIHdlYWsgPSAxMCBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgYm9vbCBoYXNfd2VhaygpIGNvbnN0OworICB2b2lkIGNsZWFyX3dlYWsoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrV2Vha0ZpZWxkTnVtYmVyID0gMTA7CisgIGJvb2wgd2VhaygpIGNvbnN0OworICB2b2lkIHNldF93ZWFrKGJvb2wgdmFsdWUpOworCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiB1bmludGVycHJldGVkX29wdGlvbiA9IDk5OTsKKyAgaW50IHVuaW50ZXJwcmV0ZWRfb3B0aW9uX3NpemUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl91bmludGVycHJldGVkX29wdGlvbigpOworICBzdGF0aWMgY29uc3QgaW50IGtVbmludGVycHJldGVkT3B0aW9uRmllbGROdW1iZXIgPSA5OTk7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiYgdW5pbnRlcnByZXRlZF9vcHRpb24oaW50IGluZGV4KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uKiBtdXRhYmxlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKGludCBpbmRleCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiogYWRkX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uID4qCisgICAgICBtdXRhYmxlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCk7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uID4mCisgICAgICB1bmludGVycHJldGVkX29wdGlvbigpIGNvbnN0OworCisgIEdPT0dMRV9QUk9UT0JVRl9FWFRFTlNJT05fQUNDRVNTT1JTKEZpZWxkT3B0aW9ucykKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMpCisgcHJpdmF0ZToKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19jdHlwZSgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfY3R5cGUoKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19wYWNrZWQoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX3BhY2tlZCgpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX2pzdHlwZSgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfanN0eXBlKCk7CisgIGlubGluZSB2b2lkIHNldF9oYXNfbGF6eSgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfbGF6eSgpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX2RlcHJlY2F0ZWQoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX2RlcHJlY2F0ZWQoKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc193ZWFrKCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc193ZWFrKCk7CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RXh0ZW5zaW9uU2V0IF9leHRlbnNpb25zXzsKKworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpJbnRlcm5hbE1ldGFkYXRhV2l0aEFyZW5hIF9pbnRlcm5hbF9tZXRhZGF0YV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIF9oYXNfYml0c19bMV07CisgIG11dGFibGUgaW50IF9jYWNoZWRfc2l6ZV87CisgIGludCBjdHlwZV87CisgIGludCBqc3R5cGVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiA+IHVuaW50ZXJwcmV0ZWRfb3B0aW9uXzsKKyAgYm9vbCBwYWNrZWRfOworICBib29sIGxhenlfOworICBib29sIGRlcHJlY2F0ZWRfOworICBib29sIHdlYWtfOworICBmcmllbmQgdm9pZCBMSUJQUk9UT0JVRl9FWFBPUlQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworCisgIHZvaWQgSW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIHN0YXRpYyBGaWVsZE9wdGlvbnMqIGRlZmF1bHRfaW5zdGFuY2VfOworfTsKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEVudW1PcHRpb25zIDogcHVibGljIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSB7CisgcHVibGljOgorICBFbnVtT3B0aW9ucygpOworICB2aXJ0dWFsIH5FbnVtT3B0aW9ucygpOworCisgIEVudW1PcHRpb25zKGNvbnN0IEVudW1PcHRpb25zJiBmcm9tKTsKKworICBpbmxpbmUgRW51bU9wdGlvbnMmIG9wZXJhdG9yPShjb25zdCBFbnVtT3B0aW9ucyYgZnJvbSkgeworICAgIENvcHlGcm9tKGZyb20pOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIGlubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlVua25vd25GaWVsZFNldCYgdW5rbm93bl9maWVsZHMoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8udW5rbm93bl9maWVsZHMoKTsKKyAgfQorCisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlVua25vd25GaWVsZFNldCogbXV0YWJsZV91bmtub3duX2ZpZWxkcygpIHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5tdXRhYmxlX3Vua25vd25fZmllbGRzKCk7CisgIH0KKworICBzdGF0aWMgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKCk7CisgIHN0YXRpYyBjb25zdCBFbnVtT3B0aW9ucyYgZGVmYXVsdF9pbnN0YW5jZSgpOworCisgIHZvaWQgU3dhcChFbnVtT3B0aW9ucyogb3RoZXIpOworCisgIC8vIGltcGxlbWVudHMgTWVzc2FnZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgaW5saW5lIEVudW1PcHRpb25zKiBOZXcoKSBjb25zdCB7IHJldHVybiBOZXcoTlVMTCk7IH0KKworICBFbnVtT3B0aW9ucyogTmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdDsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIENvcHlGcm9tKGNvbnN0IEVudW1PcHRpb25zJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgRW51bU9wdGlvbnMmIGZyb20pOworICB2b2lkIENsZWFyKCk7CisgIGJvb2wgSXNJbml0aWFsaXplZCgpIGNvbnN0OworCisgIGludCBCeXRlU2l6ZSgpIGNvbnN0OworICBib29sIE1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KTsKKyAgdm9pZCBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSg6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBvdXRwdXQpIGNvbnN0OworICBpbnQgR2V0Q2FjaGVkU2l6ZSgpIGNvbnN0IHsgcmV0dXJuIF9jYWNoZWRfc2l6ZV87IH0KKyAgcHJpdmF0ZToKKyAgdm9pZCBTaGFyZWRDdG9yKCk7CisgIHZvaWQgU2hhcmVkRHRvcigpOworICB2b2lkIFNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0OworICB2b2lkIEludGVybmFsU3dhcChFbnVtT3B0aW9ucyogb3RoZXIpOworICBwcml2YXRlOgorICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogR2V0QXJlbmFOb1ZpcnR1YWwoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8uYXJlbmEoKTsKKyAgfQorICBpbmxpbmUgdm9pZCogTWF5YmVBcmVuYVB0cigpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5yYXdfYXJlbmFfcHRyKCk7CisgIH0KKyAgcHVibGljOgorCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgR2V0TWV0YWRhdGEoKSBjb25zdDsKKworICAvLyBuZXN0ZWQgdHlwZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIGFjY2Vzc29ycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gb3B0aW9uYWwgYm9vbCBhbGxvd19hbGlhcyA9IDI7CisgIGJvb2wgaGFzX2FsbG93X2FsaWFzKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfYWxsb3dfYWxpYXMoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrQWxsb3dBbGlhc0ZpZWxkTnVtYmVyID0gMjsKKyAgYm9vbCBhbGxvd19hbGlhcygpIGNvbnN0OworICB2b2lkIHNldF9hbGxvd19hbGlhcyhib29sIHZhbHVlKTsKKworICAvLyBvcHRpb25hbCBib29sIGRlcHJlY2F0ZWQgPSAzIFtkZWZhdWx0ID0gZmFsc2VdOworICBib29sIGhhc19kZXByZWNhdGVkKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfZGVwcmVjYXRlZCgpOworICBzdGF0aWMgY29uc3QgaW50IGtEZXByZWNhdGVkRmllbGROdW1iZXIgPSAzOworICBib29sIGRlcHJlY2F0ZWQoKSBjb25zdDsKKyAgdm9pZCBzZXRfZGVwcmVjYXRlZChib29sIHZhbHVlKTsKKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CisgIGludCB1bmludGVycHJldGVkX29wdGlvbl9zaXplKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfdW5pbnRlcnByZXRlZF9vcHRpb24oKTsKKyAgc3RhdGljIGNvbnN0IGludCBrVW5pbnRlcnByZXRlZE9wdGlvbkZpZWxkTnVtYmVyID0gOTk5OworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24mIHVuaW50ZXJwcmV0ZWRfb3B0aW9uKGludCBpbmRleCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiogbXV0YWJsZV91bmludGVycHJldGVkX29wdGlvbihpbnQgaW5kZXgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24qIGFkZF91bmludGVycHJldGVkX29wdGlvbigpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiA+KgorICAgICAgbXV0YWJsZV91bmludGVycHJldGVkX29wdGlvbigpOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiA+JgorICAgICAgdW5pbnRlcnByZXRlZF9vcHRpb24oKSBjb25zdDsKKworICBHT09HTEVfUFJPVE9CVUZfRVhURU5TSU9OX0FDQ0VTU09SUyhFbnVtT3B0aW9ucykKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucykKKyBwcml2YXRlOgorICBpbmxpbmUgdm9pZCBzZXRfaGFzX2FsbG93X2FsaWFzKCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc19hbGxvd19hbGlhcygpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX2RlcHJlY2F0ZWQoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX2RlcHJlY2F0ZWQoKTsKKworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpFeHRlbnNpb25TZXQgX2V4dGVuc2lvbnNfOworCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEgX2ludGVybmFsX21ldGFkYXRhXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgX2hhc19iaXRzX1sxXTsKKyAgbXV0YWJsZSBpbnQgX2NhY2hlZF9zaXplXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24gPiB1bmludGVycHJldGVkX29wdGlvbl87CisgIGJvb2wgYWxsb3dfYWxpYXNfOworICBib29sIGRlcHJlY2F0ZWRfOworICBmcmllbmQgdm9pZCBMSUJQUk9UT0JVRl9FWFBPUlQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworCisgIHZvaWQgSW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIHN0YXRpYyBFbnVtT3B0aW9ucyogZGVmYXVsdF9pbnN0YW5jZV87Cit9OworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgRW51bVZhbHVlT3B0aW9ucyA6IHB1YmxpYyA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UgeworIHB1YmxpYzoKKyAgRW51bVZhbHVlT3B0aW9ucygpOworICB2aXJ0dWFsIH5FbnVtVmFsdWVPcHRpb25zKCk7CisKKyAgRW51bVZhbHVlT3B0aW9ucyhjb25zdCBFbnVtVmFsdWVPcHRpb25zJiBmcm9tKTsKKworICBpbmxpbmUgRW51bVZhbHVlT3B0aW9ucyYgb3BlcmF0b3I9KGNvbnN0IEVudW1WYWx1ZU9wdGlvbnMmIGZyb20pIHsKKyAgICBDb3B5RnJvbShmcm9tKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworICBpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpVbmtub3duRmllbGRTZXQmIHVua25vd25fZmllbGRzKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnVua25vd25fZmllbGRzKCk7CisgIH0KKworICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpVbmtub3duRmllbGRTZXQqIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ubXV0YWJsZV91bmtub3duX2ZpZWxkcygpOworICB9CisKKyAgc3RhdGljIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogZGVzY3JpcHRvcigpOworICBzdGF0aWMgY29uc3QgRW51bVZhbHVlT3B0aW9ucyYgZGVmYXVsdF9pbnN0YW5jZSgpOworCisgIHZvaWQgU3dhcChFbnVtVmFsdWVPcHRpb25zKiBvdGhlcik7CisKKyAgLy8gaW1wbGVtZW50cyBNZXNzYWdlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBpbmxpbmUgRW51bVZhbHVlT3B0aW9ucyogTmV3KCkgY29uc3QgeyByZXR1cm4gTmV3KE5VTEwpOyB9CisKKyAgRW51bVZhbHVlT3B0aW9ucyogTmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdDsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIENvcHlGcm9tKGNvbnN0IEVudW1WYWx1ZU9wdGlvbnMmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCBFbnVtVmFsdWVPcHRpb25zJiBmcm9tKTsKKyAgdm9pZCBDbGVhcigpOworICBib29sIElzSW5pdGlhbGl6ZWQoKSBjb25zdDsKKworICBpbnQgQnl0ZVNpemUoKSBjb25zdDsKKyAgYm9vbCBNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCk7CisgIHZvaWQgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogb3V0cHV0KSBjb25zdDsKKyAgaW50IEdldENhY2hlZFNpemUoKSBjb25zdCB7IHJldHVybiBfY2FjaGVkX3NpemVfOyB9CisgIHByaXZhdGU6CisgIHZvaWQgU2hhcmVkQ3RvcigpOworICB2b2lkIFNoYXJlZER0b3IoKTsKKyAgdm9pZCBTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdDsKKyAgdm9pZCBJbnRlcm5hbFN3YXAoRW51bVZhbHVlT3B0aW9ucyogb3RoZXIpOworICBwcml2YXRlOgorICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogR2V0QXJlbmFOb1ZpcnR1YWwoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8uYXJlbmEoKTsKKyAgfQorICBpbmxpbmUgdm9pZCogTWF5YmVBcmVuYVB0cigpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5yYXdfYXJlbmFfcHRyKCk7CisgIH0KKyAgcHVibGljOgorCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgR2V0TWV0YWRhdGEoKSBjb25zdDsKKworICAvLyBuZXN0ZWQgdHlwZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIGFjY2Vzc29ycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gb3B0aW9uYWwgYm9vbCBkZXByZWNhdGVkID0gMSBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgYm9vbCBoYXNfZGVwcmVjYXRlZCgpIGNvbnN0OworICB2b2lkIGNsZWFyX2RlcHJlY2F0ZWQoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrRGVwcmVjYXRlZEZpZWxkTnVtYmVyID0gMTsKKyAgYm9vbCBkZXByZWNhdGVkKCkgY29uc3Q7CisgIHZvaWQgc2V0X2RlcHJlY2F0ZWQoYm9vbCB2YWx1ZSk7CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIHVuaW50ZXJwcmV0ZWRfb3B0aW9uID0gOTk5OworICBpbnQgdW5pbnRlcnByZXRlZF9vcHRpb25fc2l6ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga1VuaW50ZXJwcmV0ZWRPcHRpb25GaWVsZE51bWJlciA9IDk5OTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uJiB1bmludGVycHJldGVkX29wdGlvbihpbnQgaW5kZXgpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24qIG11dGFibGVfdW5pbnRlcnByZXRlZF9vcHRpb24oaW50IGluZGV4KTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uKiBhZGRfdW5pbnRlcnByZXRlZF9vcHRpb24oKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24gPioKKyAgICAgIG11dGFibGVfdW5pbnRlcnByZXRlZF9vcHRpb24oKTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24gPiYKKyAgICAgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgY29uc3Q7CisKKyAgR09PR0xFX1BST1RPQlVGX0VYVEVOU0lPTl9BQ0NFU1NPUlMoRW51bVZhbHVlT3B0aW9ucykKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVPcHRpb25zKQorIHByaXZhdGU6CisgIGlubGluZSB2b2lkIHNldF9oYXNfZGVwcmVjYXRlZCgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfZGVwcmVjYXRlZCgpOworCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkV4dGVuc2lvblNldCBfZXh0ZW5zaW9uc187CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6SW50ZXJuYWxNZXRhZGF0YVdpdGhBcmVuYSBfaW50ZXJuYWxfbWV0YWRhdGFfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiBfaGFzX2JpdHNfWzFdOworICBtdXRhYmxlIGludCBfY2FjaGVkX3NpemVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiA+IHVuaW50ZXJwcmV0ZWRfb3B0aW9uXzsKKyAgYm9vbCBkZXByZWNhdGVkXzsKKyAgZnJpZW5kIHZvaWQgTElCUFJPVE9CVUZfRVhQT1JUIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfQXNzaWduRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKworICB2b2lkIEluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICBzdGF0aWMgRW51bVZhbHVlT3B0aW9ucyogZGVmYXVsdF9pbnN0YW5jZV87Cit9OworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgU2VydmljZU9wdGlvbnMgOiBwdWJsaWMgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlIHsKKyBwdWJsaWM6CisgIFNlcnZpY2VPcHRpb25zKCk7CisgIHZpcnR1YWwgflNlcnZpY2VPcHRpb25zKCk7CisKKyAgU2VydmljZU9wdGlvbnMoY29uc3QgU2VydmljZU9wdGlvbnMmIGZyb20pOworCisgIGlubGluZSBTZXJ2aWNlT3B0aW9ucyYgb3BlcmF0b3I9KGNvbnN0IFNlcnZpY2VPcHRpb25zJiBmcm9tKSB7CisgICAgQ29weUZyb20oZnJvbSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgaW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcygpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy51bmtub3duX2ZpZWxkcygpOworICB9CisKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5rbm93bkZpZWxkU2V0KiBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLm11dGFibGVfdW5rbm93bl9maWVsZHMoKTsKKyAgfQorCisgIHN0YXRpYyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIGRlc2NyaXB0b3IoKTsKKyAgc3RhdGljIGNvbnN0IFNlcnZpY2VPcHRpb25zJiBkZWZhdWx0X2luc3RhbmNlKCk7CisKKyAgdm9pZCBTd2FwKFNlcnZpY2VPcHRpb25zKiBvdGhlcik7CisKKyAgLy8gaW1wbGVtZW50cyBNZXNzYWdlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBpbmxpbmUgU2VydmljZU9wdGlvbnMqIE5ldygpIGNvbnN0IHsgcmV0dXJuIE5ldyhOVUxMKTsgfQorCisgIFNlcnZpY2VPcHRpb25zKiBOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0OworICB2b2lkIENvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgQ29weUZyb20oY29uc3QgU2VydmljZU9wdGlvbnMmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCBTZXJ2aWNlT3B0aW9ucyYgZnJvbSk7CisgIHZvaWQgQ2xlYXIoKTsKKyAgYm9vbCBJc0luaXRpYWxpemVkKCkgY29uc3Q7CisKKyAgaW50IEJ5dGVTaXplKCkgY29uc3Q7CisgIGJvb2wgTWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpOworICB2b2lkIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIG91dHB1dCkgY29uc3Q7CisgIGludCBHZXRDYWNoZWRTaXplKCkgY29uc3QgeyByZXR1cm4gX2NhY2hlZF9zaXplXzsgfQorICBwcml2YXRlOgorICB2b2lkIFNoYXJlZEN0b3IoKTsKKyAgdm9pZCBTaGFyZWREdG9yKCk7CisgIHZvaWQgU2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3Q7CisgIHZvaWQgSW50ZXJuYWxTd2FwKFNlcnZpY2VPcHRpb25zKiBvdGhlcik7CisgIHByaXZhdGU6CisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYU5vVmlydHVhbCgpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5hcmVuYSgpOworICB9CisgIGlubGluZSB2b2lkKiBNYXliZUFyZW5hUHRyKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnJhd19hcmVuYV9wdHIoKTsKKyAgfQorICBwdWJsaWM6CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBHZXRNZXRhZGF0YSgpIGNvbnN0OworCisgIC8vIG5lc3RlZCB0eXBlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gYWNjZXNzb3JzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBvcHRpb25hbCBib29sIGRlcHJlY2F0ZWQgPSAzMyBbZGVmYXVsdCA9IGZhbHNlXTsKKyAgYm9vbCBoYXNfZGVwcmVjYXRlZCgpIGNvbnN0OworICB2b2lkIGNsZWFyX2RlcHJlY2F0ZWQoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrRGVwcmVjYXRlZEZpZWxkTnVtYmVyID0gMzM7CisgIGJvb2wgZGVwcmVjYXRlZCgpIGNvbnN0OworICB2b2lkIHNldF9kZXByZWNhdGVkKGJvb2wgdmFsdWUpOworCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiB1bmludGVycHJldGVkX29wdGlvbiA9IDk5OTsKKyAgaW50IHVuaW50ZXJwcmV0ZWRfb3B0aW9uX3NpemUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl91bmludGVycHJldGVkX29wdGlvbigpOworICBzdGF0aWMgY29uc3QgaW50IGtVbmludGVycHJldGVkT3B0aW9uRmllbGROdW1iZXIgPSA5OTk7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiYgdW5pbnRlcnByZXRlZF9vcHRpb24oaW50IGluZGV4KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uKiBtdXRhYmxlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKGludCBpbmRleCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiogYWRkX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uID4qCisgICAgICBtdXRhYmxlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCk7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uID4mCisgICAgICB1bmludGVycHJldGVkX29wdGlvbigpIGNvbnN0OworCisgIEdPT0dMRV9QUk9UT0JVRl9FWFRFTlNJT05fQUNDRVNTT1JTKFNlcnZpY2VPcHRpb25zKQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zKQorIHByaXZhdGU6CisgIGlubGluZSB2b2lkIHNldF9oYXNfZGVwcmVjYXRlZCgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfZGVwcmVjYXRlZCgpOworCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkV4dGVuc2lvblNldCBfZXh0ZW5zaW9uc187CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6SW50ZXJuYWxNZXRhZGF0YVdpdGhBcmVuYSBfaW50ZXJuYWxfbWV0YWRhdGFfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiBfaGFzX2JpdHNfWzFdOworICBtdXRhYmxlIGludCBfY2FjaGVkX3NpemVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiA+IHVuaW50ZXJwcmV0ZWRfb3B0aW9uXzsKKyAgYm9vbCBkZXByZWNhdGVkXzsKKyAgZnJpZW5kIHZvaWQgTElCUFJPVE9CVUZfRVhQT1JUIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfQXNzaWduRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKworICB2b2lkIEluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICBzdGF0aWMgU2VydmljZU9wdGlvbnMqIGRlZmF1bHRfaW5zdGFuY2VfOworfTsKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIE1ldGhvZE9wdGlvbnMgOiBwdWJsaWMgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlIHsKKyBwdWJsaWM6CisgIE1ldGhvZE9wdGlvbnMoKTsKKyAgdmlydHVhbCB+TWV0aG9kT3B0aW9ucygpOworCisgIE1ldGhvZE9wdGlvbnMoY29uc3QgTWV0aG9kT3B0aW9ucyYgZnJvbSk7CisKKyAgaW5saW5lIE1ldGhvZE9wdGlvbnMmIG9wZXJhdG9yPShjb25zdCBNZXRob2RPcHRpb25zJiBmcm9tKSB7CisgICAgQ29weUZyb20oZnJvbSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgaW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcygpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy51bmtub3duX2ZpZWxkcygpOworICB9CisKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5rbm93bkZpZWxkU2V0KiBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLm11dGFibGVfdW5rbm93bl9maWVsZHMoKTsKKyAgfQorCisgIHN0YXRpYyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIGRlc2NyaXB0b3IoKTsKKyAgc3RhdGljIGNvbnN0IE1ldGhvZE9wdGlvbnMmIGRlZmF1bHRfaW5zdGFuY2UoKTsKKworICB2b2lkIFN3YXAoTWV0aG9kT3B0aW9ucyogb3RoZXIpOworCisgIC8vIGltcGxlbWVudHMgTWVzc2FnZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgaW5saW5lIE1ldGhvZE9wdGlvbnMqIE5ldygpIGNvbnN0IHsgcmV0dXJuIE5ldyhOVUxMKTsgfQorCisgIE1ldGhvZE9wdGlvbnMqIE5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3Q7CisgIHZvaWQgQ29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCBNZXRob2RPcHRpb25zJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgTWV0aG9kT3B0aW9ucyYgZnJvbSk7CisgIHZvaWQgQ2xlYXIoKTsKKyAgYm9vbCBJc0luaXRpYWxpemVkKCkgY29uc3Q7CisKKyAgaW50IEJ5dGVTaXplKCkgY29uc3Q7CisgIGJvb2wgTWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpOworICB2b2lkIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIG91dHB1dCkgY29uc3Q7CisgIGludCBHZXRDYWNoZWRTaXplKCkgY29uc3QgeyByZXR1cm4gX2NhY2hlZF9zaXplXzsgfQorICBwcml2YXRlOgorICB2b2lkIFNoYXJlZEN0b3IoKTsKKyAgdm9pZCBTaGFyZWREdG9yKCk7CisgIHZvaWQgU2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3Q7CisgIHZvaWQgSW50ZXJuYWxTd2FwKE1ldGhvZE9wdGlvbnMqIG90aGVyKTsKKyAgcHJpdmF0ZToKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hTm9WaXJ0dWFsKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLmFyZW5hKCk7CisgIH0KKyAgaW5saW5lIHZvaWQqIE1heWJlQXJlbmFQdHIoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ucmF3X2FyZW5hX3B0cigpOworICB9CisgIHB1YmxpYzoKKworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEdldE1ldGFkYXRhKCkgY29uc3Q7CisKKyAgLy8gbmVzdGVkIHR5cGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBhY2Nlc3NvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIG9wdGlvbmFsIGJvb2wgZGVwcmVjYXRlZCA9IDMzIFtkZWZhdWx0ID0gZmFsc2VdOworICBib29sIGhhc19kZXByZWNhdGVkKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfZGVwcmVjYXRlZCgpOworICBzdGF0aWMgY29uc3QgaW50IGtEZXByZWNhdGVkRmllbGROdW1iZXIgPSAzMzsKKyAgYm9vbCBkZXByZWNhdGVkKCkgY29uc3Q7CisgIHZvaWQgc2V0X2RlcHJlY2F0ZWQoYm9vbCB2YWx1ZSk7CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIHVuaW50ZXJwcmV0ZWRfb3B0aW9uID0gOTk5OworICBpbnQgdW5pbnRlcnByZXRlZF9vcHRpb25fc2l6ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga1VuaW50ZXJwcmV0ZWRPcHRpb25GaWVsZE51bWJlciA9IDk5OTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uJiB1bmludGVycHJldGVkX29wdGlvbihpbnQgaW5kZXgpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24qIG11dGFibGVfdW5pbnRlcnByZXRlZF9vcHRpb24oaW50IGluZGV4KTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uKiBhZGRfdW5pbnRlcnByZXRlZF9vcHRpb24oKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24gPioKKyAgICAgIG11dGFibGVfdW5pbnRlcnByZXRlZF9vcHRpb24oKTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24gPiYKKyAgICAgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgY29uc3Q7CisKKyAgR09PR0xFX1BST1RPQlVGX0VYVEVOU0lPTl9BQ0NFU1NPUlMoTWV0aG9kT3B0aW9ucykKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zKQorIHByaXZhdGU6CisgIGlubGluZSB2b2lkIHNldF9oYXNfZGVwcmVjYXRlZCgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfZGVwcmVjYXRlZCgpOworCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkV4dGVuc2lvblNldCBfZXh0ZW5zaW9uc187CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6SW50ZXJuYWxNZXRhZGF0YVdpdGhBcmVuYSBfaW50ZXJuYWxfbWV0YWRhdGFfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiBfaGFzX2JpdHNfWzFdOworICBtdXRhYmxlIGludCBfY2FjaGVkX3NpemVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiA+IHVuaW50ZXJwcmV0ZWRfb3B0aW9uXzsKKyAgYm9vbCBkZXByZWNhdGVkXzsKKyAgZnJpZW5kIHZvaWQgTElCUFJPVE9CVUZfRVhQT1JUIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfQXNzaWduRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKworICB2b2lkIEluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICBzdGF0aWMgTWV0aG9kT3B0aW9ucyogZGVmYXVsdF9pbnN0YW5jZV87Cit9OworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydCA6IHB1YmxpYyA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UgeworIHB1YmxpYzoKKyAgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydCgpOworICB2aXJ0dWFsIH5VbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0KCk7CisKKyAgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydChjb25zdCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0JiBmcm9tKTsKKworICBpbmxpbmUgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydCYgb3BlcmF0b3I9KGNvbnN0IFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQmIGZyb20pIHsKKyAgICBDb3B5RnJvbShmcm9tKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworICBpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpVbmtub3duRmllbGRTZXQmIHVua25vd25fZmllbGRzKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnVua25vd25fZmllbGRzKCk7CisgIH0KKworICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpVbmtub3duRmllbGRTZXQqIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ubXV0YWJsZV91bmtub3duX2ZpZWxkcygpOworICB9CisKKyAgc3RhdGljIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogZGVzY3JpcHRvcigpOworICBzdGF0aWMgY29uc3QgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydCYgZGVmYXVsdF9pbnN0YW5jZSgpOworCisgIHZvaWQgU3dhcChVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0KiBvdGhlcik7CisKKyAgLy8gaW1wbGVtZW50cyBNZXNzYWdlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBpbmxpbmUgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydCogTmV3KCkgY29uc3QgeyByZXR1cm4gTmV3KE5VTEwpOyB9CisKKyAgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydCogTmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdDsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIENvcHlGcm9tKGNvbnN0IFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0JiBmcm9tKTsKKyAgdm9pZCBDbGVhcigpOworICBib29sIElzSW5pdGlhbGl6ZWQoKSBjb25zdDsKKworICBpbnQgQnl0ZVNpemUoKSBjb25zdDsKKyAgYm9vbCBNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCk7CisgIHZvaWQgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogb3V0cHV0KSBjb25zdDsKKyAgaW50IEdldENhY2hlZFNpemUoKSBjb25zdCB7IHJldHVybiBfY2FjaGVkX3NpemVfOyB9CisgIHByaXZhdGU6CisgIHZvaWQgU2hhcmVkQ3RvcigpOworICB2b2lkIFNoYXJlZER0b3IoKTsKKyAgdm9pZCBTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdDsKKyAgdm9pZCBJbnRlcm5hbFN3YXAoVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydCogb3RoZXIpOworICBwcml2YXRlOgorICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogR2V0QXJlbmFOb1ZpcnR1YWwoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8uYXJlbmEoKTsKKyAgfQorICBpbmxpbmUgdm9pZCogTWF5YmVBcmVuYVB0cigpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5yYXdfYXJlbmFfcHRyKCk7CisgIH0KKyAgcHVibGljOgorCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgR2V0TWV0YWRhdGEoKSBjb25zdDsKKworICAvLyBuZXN0ZWQgdHlwZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIGFjY2Vzc29ycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gcmVxdWlyZWQgc3RyaW5nIG5hbWVfcGFydCA9IDE7CisgIGJvb2wgaGFzX25hbWVfcGFydCgpIGNvbnN0OworICB2b2lkIGNsZWFyX25hbWVfcGFydCgpOworICBzdGF0aWMgY29uc3QgaW50IGtOYW1lUGFydEZpZWxkTnVtYmVyID0gMTsKKyAgY29uc3QgOjpzdGQ6OnN0cmluZyYgbmFtZV9wYXJ0KCkgY29uc3Q7CisgIHZvaWQgc2V0X25hbWVfcGFydChjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X25hbWVfcGFydChjb25zdCBjaGFyKiB2YWx1ZSk7CisgIHZvaWQgc2V0X25hbWVfcGFydChjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpOworICA6OnN0ZDo6c3RyaW5nKiBtdXRhYmxlX25hbWVfcGFydCgpOworICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlX25hbWVfcGFydCgpOworICB2b2lkIHNldF9hbGxvY2F0ZWRfbmFtZV9wYXJ0KDo6c3RkOjpzdHJpbmcqIG5hbWVfcGFydCk7CisKKyAgLy8gcmVxdWlyZWQgYm9vbCBpc19leHRlbnNpb24gPSAyOworICBib29sIGhhc19pc19leHRlbnNpb24oKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9pc19leHRlbnNpb24oKTsKKyAgc3RhdGljIGNvbnN0IGludCBrSXNFeHRlbnNpb25GaWVsZE51bWJlciA9IDI7CisgIGJvb2wgaXNfZXh0ZW5zaW9uKCkgY29uc3Q7CisgIHZvaWQgc2V0X2lzX2V4dGVuc2lvbihib29sIHZhbHVlKTsKKworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uTmFtZVBhcnQpCisgcHJpdmF0ZToKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19uYW1lX3BhcnQoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX25hbWVfcGFydCgpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX2lzX2V4dGVuc2lvbigpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfaXNfZXh0ZW5zaW9uKCk7CisKKyAgLy8gaGVscGVyIGZvciBCeXRlU2l6ZSgpCisgIGludCBSZXF1aXJlZEZpZWxkc0J5dGVTaXplRmFsbGJhY2soKSBjb25zdDsKKworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpJbnRlcm5hbE1ldGFkYXRhV2l0aEFyZW5hIF9pbnRlcm5hbF9tZXRhZGF0YV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIF9oYXNfYml0c19bMV07CisgIG11dGFibGUgaW50IF9jYWNoZWRfc2l6ZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFyZW5hU3RyaW5nUHRyIG5hbWVfcGFydF87CisgIGJvb2wgaXNfZXh0ZW5zaW9uXzsKKyAgZnJpZW5kIHZvaWQgTElCUFJPVE9CVUZfRVhQT1JUIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfQXNzaWduRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKworICB2b2lkIEluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICBzdGF0aWMgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydCogZGVmYXVsdF9pbnN0YW5jZV87Cit9OworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgVW5pbnRlcnByZXRlZE9wdGlvbiA6IHB1YmxpYyA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UgeworIHB1YmxpYzoKKyAgVW5pbnRlcnByZXRlZE9wdGlvbigpOworICB2aXJ0dWFsIH5VbmludGVycHJldGVkT3B0aW9uKCk7CisKKyAgVW5pbnRlcnByZXRlZE9wdGlvbihjb25zdCBVbmludGVycHJldGVkT3B0aW9uJiBmcm9tKTsKKworICBpbmxpbmUgVW5pbnRlcnByZXRlZE9wdGlvbiYgb3BlcmF0b3I9KGNvbnN0IFVuaW50ZXJwcmV0ZWRPcHRpb24mIGZyb20pIHsKKyAgICBDb3B5RnJvbShmcm9tKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworICBpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpVbmtub3duRmllbGRTZXQmIHVua25vd25fZmllbGRzKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnVua25vd25fZmllbGRzKCk7CisgIH0KKworICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpVbmtub3duRmllbGRTZXQqIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ubXV0YWJsZV91bmtub3duX2ZpZWxkcygpOworICB9CisKKyAgc3RhdGljIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogZGVzY3JpcHRvcigpOworICBzdGF0aWMgY29uc3QgVW5pbnRlcnByZXRlZE9wdGlvbiYgZGVmYXVsdF9pbnN0YW5jZSgpOworCisgIHZvaWQgU3dhcChVbmludGVycHJldGVkT3B0aW9uKiBvdGhlcik7CisKKyAgLy8gaW1wbGVtZW50cyBNZXNzYWdlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBpbmxpbmUgVW5pbnRlcnByZXRlZE9wdGlvbiogTmV3KCkgY29uc3QgeyByZXR1cm4gTmV3KE5VTEwpOyB9CisKKyAgVW5pbnRlcnByZXRlZE9wdGlvbiogTmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdDsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIENvcHlGcm9tKGNvbnN0IFVuaW50ZXJwcmV0ZWRPcHRpb24mIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCBVbmludGVycHJldGVkT3B0aW9uJiBmcm9tKTsKKyAgdm9pZCBDbGVhcigpOworICBib29sIElzSW5pdGlhbGl6ZWQoKSBjb25zdDsKKworICBpbnQgQnl0ZVNpemUoKSBjb25zdDsKKyAgYm9vbCBNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCk7CisgIHZvaWQgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogb3V0cHV0KSBjb25zdDsKKyAgaW50IEdldENhY2hlZFNpemUoKSBjb25zdCB7IHJldHVybiBfY2FjaGVkX3NpemVfOyB9CisgIHByaXZhdGU6CisgIHZvaWQgU2hhcmVkQ3RvcigpOworICB2b2lkIFNoYXJlZER0b3IoKTsKKyAgdm9pZCBTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdDsKKyAgdm9pZCBJbnRlcm5hbFN3YXAoVW5pbnRlcnByZXRlZE9wdGlvbiogb3RoZXIpOworICBwcml2YXRlOgorICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogR2V0QXJlbmFOb1ZpcnR1YWwoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8uYXJlbmEoKTsKKyAgfQorICBpbmxpbmUgdm9pZCogTWF5YmVBcmVuYVB0cigpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5yYXdfYXJlbmFfcHRyKCk7CisgIH0KKyAgcHVibGljOgorCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgR2V0TWV0YWRhdGEoKSBjb25zdDsKKworICAvLyBuZXN0ZWQgdHlwZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIHR5cGVkZWYgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydCBOYW1lUGFydDsKKworICAvLyBhY2Nlc3NvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5OYW1lUGFydCBuYW1lID0gMjsKKyAgaW50IG5hbWVfc2l6ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX25hbWUoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrTmFtZUZpZWxkTnVtYmVyID0gMjsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0JiBuYW1lKGludCBpbmRleCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydCogbXV0YWJsZV9uYW1lKGludCBpbmRleCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydCogYWRkX25hbWUoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQgPioKKyAgICAgIG11dGFibGVfbmFtZSgpOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydCA+JgorICAgICAgbmFtZSgpIGNvbnN0OworCisgIC8vIG9wdGlvbmFsIHN0cmluZyBpZGVudGlmaWVyX3ZhbHVlID0gMzsKKyAgYm9vbCBoYXNfaWRlbnRpZmllcl92YWx1ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX2lkZW50aWZpZXJfdmFsdWUoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrSWRlbnRpZmllclZhbHVlRmllbGROdW1iZXIgPSAzOworICBjb25zdCA6OnN0ZDo6c3RyaW5nJiBpZGVudGlmaWVyX3ZhbHVlKCkgY29uc3Q7CisgIHZvaWQgc2V0X2lkZW50aWZpZXJfdmFsdWUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpOworICB2b2lkIHNldF9pZGVudGlmaWVyX3ZhbHVlKGNvbnN0IGNoYXIqIHZhbHVlKTsKKyAgdm9pZCBzZXRfaWRlbnRpZmllcl92YWx1ZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpOworICA6OnN0ZDo6c3RyaW5nKiBtdXRhYmxlX2lkZW50aWZpZXJfdmFsdWUoKTsKKyAgOjpzdGQ6OnN0cmluZyogcmVsZWFzZV9pZGVudGlmaWVyX3ZhbHVlKCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF9pZGVudGlmaWVyX3ZhbHVlKDo6c3RkOjpzdHJpbmcqIGlkZW50aWZpZXJfdmFsdWUpOworCisgIC8vIG9wdGlvbmFsIHVpbnQ2NCBwb3NpdGl2ZV9pbnRfdmFsdWUgPSA0OworICBib29sIGhhc19wb3NpdGl2ZV9pbnRfdmFsdWUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9wb3NpdGl2ZV9pbnRfdmFsdWUoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrUG9zaXRpdmVJbnRWYWx1ZUZpZWxkTnVtYmVyID0gNDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50NjQgcG9zaXRpdmVfaW50X3ZhbHVlKCkgY29uc3Q7CisgIHZvaWQgc2V0X3Bvc2l0aXZlX2ludF92YWx1ZSg6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ2NCB2YWx1ZSk7CisKKyAgLy8gb3B0aW9uYWwgaW50NjQgbmVnYXRpdmVfaW50X3ZhbHVlID0gNTsKKyAgYm9vbCBoYXNfbmVnYXRpdmVfaW50X3ZhbHVlKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfbmVnYXRpdmVfaW50X3ZhbHVlKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga05lZ2F0aXZlSW50VmFsdWVGaWVsZE51bWJlciA9IDU7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50NjQgbmVnYXRpdmVfaW50X3ZhbHVlKCkgY29uc3Q7CisgIHZvaWQgc2V0X25lZ2F0aXZlX2ludF92YWx1ZSg6Omdvb2dsZTo6cHJvdG9idWY6OmludDY0IHZhbHVlKTsKKworICAvLyBvcHRpb25hbCBkb3VibGUgZG91YmxlX3ZhbHVlID0gNjsKKyAgYm9vbCBoYXNfZG91YmxlX3ZhbHVlKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfZG91YmxlX3ZhbHVlKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga0RvdWJsZVZhbHVlRmllbGROdW1iZXIgPSA2OworICBkb3VibGUgZG91YmxlX3ZhbHVlKCkgY29uc3Q7CisgIHZvaWQgc2V0X2RvdWJsZV92YWx1ZShkb3VibGUgdmFsdWUpOworCisgIC8vIG9wdGlvbmFsIGJ5dGVzIHN0cmluZ192YWx1ZSA9IDc7CisgIGJvb2wgaGFzX3N0cmluZ192YWx1ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX3N0cmluZ192YWx1ZSgpOworICBzdGF0aWMgY29uc3QgaW50IGtTdHJpbmdWYWx1ZUZpZWxkTnVtYmVyID0gNzsKKyAgY29uc3QgOjpzdGQ6OnN0cmluZyYgc3RyaW5nX3ZhbHVlKCkgY29uc3Q7CisgIHZvaWQgc2V0X3N0cmluZ192YWx1ZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X3N0cmluZ192YWx1ZShjb25zdCBjaGFyKiB2YWx1ZSk7CisgIHZvaWQgc2V0X3N0cmluZ192YWx1ZShjb25zdCB2b2lkKiB2YWx1ZSwgc2l6ZV90IHNpemUpOworICA6OnN0ZDo6c3RyaW5nKiBtdXRhYmxlX3N0cmluZ192YWx1ZSgpOworICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlX3N0cmluZ192YWx1ZSgpOworICB2b2lkIHNldF9hbGxvY2F0ZWRfc3RyaW5nX3ZhbHVlKDo6c3RkOjpzdHJpbmcqIHN0cmluZ192YWx1ZSk7CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIGFnZ3JlZ2F0ZV92YWx1ZSA9IDg7CisgIGJvb2wgaGFzX2FnZ3JlZ2F0ZV92YWx1ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX2FnZ3JlZ2F0ZV92YWx1ZSgpOworICBzdGF0aWMgY29uc3QgaW50IGtBZ2dyZWdhdGVWYWx1ZUZpZWxkTnVtYmVyID0gODsKKyAgY29uc3QgOjpzdGQ6OnN0cmluZyYgYWdncmVnYXRlX3ZhbHVlKCkgY29uc3Q7CisgIHZvaWQgc2V0X2FnZ3JlZ2F0ZV92YWx1ZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X2FnZ3JlZ2F0ZV92YWx1ZShjb25zdCBjaGFyKiB2YWx1ZSk7CisgIHZvaWQgc2V0X2FnZ3JlZ2F0ZV92YWx1ZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpOworICA6OnN0ZDo6c3RyaW5nKiBtdXRhYmxlX2FnZ3JlZ2F0ZV92YWx1ZSgpOworICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlX2FnZ3JlZ2F0ZV92YWx1ZSgpOworICB2b2lkIHNldF9hbGxvY2F0ZWRfYWdncmVnYXRlX3ZhbHVlKDo6c3RkOjpzdHJpbmcqIGFnZ3JlZ2F0ZV92YWx1ZSk7CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKQorIHByaXZhdGU6CisgIGlubGluZSB2b2lkIHNldF9oYXNfaWRlbnRpZmllcl92YWx1ZSgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfaWRlbnRpZmllcl92YWx1ZSgpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX3Bvc2l0aXZlX2ludF92YWx1ZSgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfcG9zaXRpdmVfaW50X3ZhbHVlKCk7CisgIGlubGluZSB2b2lkIHNldF9oYXNfbmVnYXRpdmVfaW50X3ZhbHVlKCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc19uZWdhdGl2ZV9pbnRfdmFsdWUoKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19kb3VibGVfdmFsdWUoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX2RvdWJsZV92YWx1ZSgpOworICBpbmxpbmUgdm9pZCBzZXRfaGFzX3N0cmluZ192YWx1ZSgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfc3RyaW5nX3ZhbHVlKCk7CisgIGlubGluZSB2b2lkIHNldF9oYXNfYWdncmVnYXRlX3ZhbHVlKCk7CisgIGlubGluZSB2b2lkIGNsZWFyX2hhc19hZ2dyZWdhdGVfdmFsdWUoKTsKKworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpJbnRlcm5hbE1ldGFkYXRhV2l0aEFyZW5hIF9pbnRlcm5hbF9tZXRhZGF0YV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIF9oYXNfYml0c19bMV07CisgIG11dGFibGUgaW50IF9jYWNoZWRfc2l6ZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0ID4gbmFtZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFyZW5hU3RyaW5nUHRyIGlkZW50aWZpZXJfdmFsdWVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ2NCBwb3NpdGl2ZV9pbnRfdmFsdWVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludDY0IG5lZ2F0aXZlX2ludF92YWx1ZV87CisgIGRvdWJsZSBkb3VibGVfdmFsdWVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBcmVuYVN0cmluZ1B0ciBzdHJpbmdfdmFsdWVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBcmVuYVN0cmluZ1B0ciBhZ2dyZWdhdGVfdmFsdWVfOworICBmcmllbmQgdm9pZCBMSUJQUk9UT0JVRl9FWFBPUlQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworCisgIHZvaWQgSW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIHN0YXRpYyBVbmludGVycHJldGVkT3B0aW9uKiBkZWZhdWx0X2luc3RhbmNlXzsKK307CisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbiA6IHB1YmxpYyA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UgeworIHB1YmxpYzoKKyAgU291cmNlQ29kZUluZm9fTG9jYXRpb24oKTsKKyAgdmlydHVhbCB+U291cmNlQ29kZUluZm9fTG9jYXRpb24oKTsKKworICBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbihjb25zdCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbiYgZnJvbSk7CisKKyAgaW5saW5lIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uJiBvcGVyYXRvcj0oY29uc3QgU291cmNlQ29kZUluZm9fTG9jYXRpb24mIGZyb20pIHsKKyAgICBDb3B5RnJvbShmcm9tKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworICBpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpVbmtub3duRmllbGRTZXQmIHVua25vd25fZmllbGRzKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnVua25vd25fZmllbGRzKCk7CisgIH0KKworICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpVbmtub3duRmllbGRTZXQqIG11dGFibGVfdW5rbm93bl9maWVsZHMoKSB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ubXV0YWJsZV91bmtub3duX2ZpZWxkcygpOworICB9CisKKyAgc3RhdGljIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogZGVzY3JpcHRvcigpOworICBzdGF0aWMgY29uc3QgU291cmNlQ29kZUluZm9fTG9jYXRpb24mIGRlZmF1bHRfaW5zdGFuY2UoKTsKKworICB2b2lkIFN3YXAoU291cmNlQ29kZUluZm9fTG9jYXRpb24qIG90aGVyKTsKKworICAvLyBpbXBsZW1lbnRzIE1lc3NhZ2UgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIGlubGluZSBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbiogTmV3KCkgY29uc3QgeyByZXR1cm4gTmV3KE5VTEwpOyB9CisKKyAgU291cmNlQ29kZUluZm9fTG9jYXRpb24qIE5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3Q7CisgIHZvaWQgQ29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbiYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uJiBmcm9tKTsKKyAgdm9pZCBDbGVhcigpOworICBib29sIElzSW5pdGlhbGl6ZWQoKSBjb25zdDsKKworICBpbnQgQnl0ZVNpemUoKSBjb25zdDsKKyAgYm9vbCBNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCk7CisgIHZvaWQgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogb3V0cHV0KSBjb25zdDsKKyAgaW50IEdldENhY2hlZFNpemUoKSBjb25zdCB7IHJldHVybiBfY2FjaGVkX3NpemVfOyB9CisgIHByaXZhdGU6CisgIHZvaWQgU2hhcmVkQ3RvcigpOworICB2b2lkIFNoYXJlZER0b3IoKTsKKyAgdm9pZCBTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdDsKKyAgdm9pZCBJbnRlcm5hbFN3YXAoU291cmNlQ29kZUluZm9fTG9jYXRpb24qIG90aGVyKTsKKyAgcHJpdmF0ZToKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hTm9WaXJ0dWFsKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLmFyZW5hKCk7CisgIH0KKyAgaW5saW5lIHZvaWQqIE1heWJlQXJlbmFQdHIoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ucmF3X2FyZW5hX3B0cigpOworICB9CisgIHB1YmxpYzoKKworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEdldE1ldGFkYXRhKCkgY29uc3Q7CisKKyAgLy8gbmVzdGVkIHR5cGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBhY2Nlc3NvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIHJlcGVhdGVkIGludDMyIHBhdGggPSAxIFtwYWNrZWQgPSB0cnVlXTsKKyAgaW50IHBhdGhfc2l6ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX3BhdGgoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrUGF0aEZpZWxkTnVtYmVyID0gMTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiBwYXRoKGludCBpbmRleCkgY29uc3Q7CisgIHZvaWQgc2V0X3BhdGgoaW50IGluZGV4LCA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKTsKKyAgdm9pZCBhZGRfcGF0aCg6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZEZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyID4mCisgICAgICBwYXRoKCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiA+KgorICAgICAgbXV0YWJsZV9wYXRoKCk7CisKKyAgLy8gcmVwZWF0ZWQgaW50MzIgc3BhbiA9IDIgW3BhY2tlZCA9IHRydWVdOworICBpbnQgc3Bhbl9zaXplKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfc3BhbigpOworICBzdGF0aWMgY29uc3QgaW50IGtTcGFuRmllbGROdW1iZXIgPSAyOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHNwYW4oaW50IGluZGV4KSBjb25zdDsKKyAgdm9pZCBzZXRfc3BhbihpbnQgaW5kZXgsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgdmFsdWUpOworICB2b2lkIGFkZF9zcGFuKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgdmFsdWUpOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgPiYKKyAgICAgIHNwYW4oKSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZEZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyID4qCisgICAgICBtdXRhYmxlX3NwYW4oKTsKKworICAvLyBvcHRpb25hbCBzdHJpbmcgbGVhZGluZ19jb21tZW50cyA9IDM7CisgIGJvb2wgaGFzX2xlYWRpbmdfY29tbWVudHMoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9sZWFkaW5nX2NvbW1lbnRzKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga0xlYWRpbmdDb21tZW50c0ZpZWxkTnVtYmVyID0gMzsKKyAgY29uc3QgOjpzdGQ6OnN0cmluZyYgbGVhZGluZ19jb21tZW50cygpIGNvbnN0OworICB2b2lkIHNldF9sZWFkaW5nX2NvbW1lbnRzKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKTsKKyAgdm9pZCBzZXRfbGVhZGluZ19jb21tZW50cyhjb25zdCBjaGFyKiB2YWx1ZSk7CisgIHZvaWQgc2V0X2xlYWRpbmdfY29tbWVudHMoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKTsKKyAgOjpzdGQ6OnN0cmluZyogbXV0YWJsZV9sZWFkaW5nX2NvbW1lbnRzKCk7CisgIDo6c3RkOjpzdHJpbmcqIHJlbGVhc2VfbGVhZGluZ19jb21tZW50cygpOworICB2b2lkIHNldF9hbGxvY2F0ZWRfbGVhZGluZ19jb21tZW50cyg6OnN0ZDo6c3RyaW5nKiBsZWFkaW5nX2NvbW1lbnRzKTsKKworICAvLyBvcHRpb25hbCBzdHJpbmcgdHJhaWxpbmdfY29tbWVudHMgPSA0OworICBib29sIGhhc190cmFpbGluZ19jb21tZW50cygpIGNvbnN0OworICB2b2lkIGNsZWFyX3RyYWlsaW5nX2NvbW1lbnRzKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga1RyYWlsaW5nQ29tbWVudHNGaWVsZE51bWJlciA9IDQ7CisgIGNvbnN0IDo6c3RkOjpzdHJpbmcmIHRyYWlsaW5nX2NvbW1lbnRzKCkgY29uc3Q7CisgIHZvaWQgc2V0X3RyYWlsaW5nX2NvbW1lbnRzKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKTsKKyAgdm9pZCBzZXRfdHJhaWxpbmdfY29tbWVudHMoY29uc3QgY2hhciogdmFsdWUpOworICB2b2lkIHNldF90cmFpbGluZ19jb21tZW50cyhjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpOworICA6OnN0ZDo6c3RyaW5nKiBtdXRhYmxlX3RyYWlsaW5nX2NvbW1lbnRzKCk7CisgIDo6c3RkOjpzdHJpbmcqIHJlbGVhc2VfdHJhaWxpbmdfY29tbWVudHMoKTsKKyAgdm9pZCBzZXRfYWxsb2NhdGVkX3RyYWlsaW5nX2NvbW1lbnRzKDo6c3RkOjpzdHJpbmcqIHRyYWlsaW5nX2NvbW1lbnRzKTsKKworICAvLyByZXBlYXRlZCBzdHJpbmcgbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyA9IDY7CisgIGludCBsZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzX3NpemUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga0xlYWRpbmdEZXRhY2hlZENvbW1lbnRzRmllbGROdW1iZXIgPSA2OworICBjb25zdCA6OnN0ZDo6c3RyaW5nJiBsZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKGludCBpbmRleCkgY29uc3Q7CisgIDo6c3RkOjpzdHJpbmcqIG11dGFibGVfbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyhpbnQgaW5kZXgpOworICB2b2lkIHNldF9sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKGludCBpbmRleCwgY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpOworICB2b2lkIHNldF9sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKGludCBpbmRleCwgY29uc3QgY2hhciogdmFsdWUpOworICB2b2lkIHNldF9sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKGludCBpbmRleCwgY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKTsKKyAgOjpzdGQ6OnN0cmluZyogYWRkX2xlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMoKTsKKyAgdm9pZCBhZGRfbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyhjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgYWRkX2xlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMoY29uc3QgY2hhciogdmFsdWUpOworICB2b2lkIGFkZF9sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpzdGQ6OnN0cmluZz4mIGxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMoKSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6OnN0ZDo6c3RyaW5nPiogbXV0YWJsZV9sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKCk7CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbikKKyBwcml2YXRlOgorICBpbmxpbmUgdm9pZCBzZXRfaGFzX2xlYWRpbmdfY29tbWVudHMoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX2xlYWRpbmdfY29tbWVudHMoKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc190cmFpbGluZ19jb21tZW50cygpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfdHJhaWxpbmdfY29tbWVudHMoKTsKKworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpJbnRlcm5hbE1ldGFkYXRhV2l0aEFyZW5hIF9pbnRlcm5hbF9tZXRhZGF0YV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIF9oYXNfYml0c19bMV07CisgIG11dGFibGUgaW50IF9jYWNoZWRfc2l6ZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiA+IHBhdGhfOworICBtdXRhYmxlIGludCBfcGF0aF9jYWNoZWRfYnl0ZV9zaXplXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZEZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyID4gc3Bhbl87CisgIG11dGFibGUgaW50IF9zcGFuX2NhY2hlZF9ieXRlX3NpemVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBcmVuYVN0cmluZ1B0ciBsZWFkaW5nX2NvbW1lbnRzXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QXJlbmFTdHJpbmdQdHIgdHJhaWxpbmdfY29tbWVudHNfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6c3RkOjpzdHJpbmc+IGxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHNfOworICBmcmllbmQgdm9pZCBMSUJQUk9UT0JVRl9FWFBPUlQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworCisgIHZvaWQgSW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIHN0YXRpYyBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbiogZGVmYXVsdF9pbnN0YW5jZV87Cit9OworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgU291cmNlQ29kZUluZm8gOiBwdWJsaWMgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlIHsKKyBwdWJsaWM6CisgIFNvdXJjZUNvZGVJbmZvKCk7CisgIHZpcnR1YWwgflNvdXJjZUNvZGVJbmZvKCk7CisKKyAgU291cmNlQ29kZUluZm8oY29uc3QgU291cmNlQ29kZUluZm8mIGZyb20pOworCisgIGlubGluZSBTb3VyY2VDb2RlSW5mbyYgb3BlcmF0b3I9KGNvbnN0IFNvdXJjZUNvZGVJbmZvJiBmcm9tKSB7CisgICAgQ29weUZyb20oZnJvbSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgaW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcygpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy51bmtub3duX2ZpZWxkcygpOworICB9CisKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5rbm93bkZpZWxkU2V0KiBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLm11dGFibGVfdW5rbm93bl9maWVsZHMoKTsKKyAgfQorCisgIHN0YXRpYyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIGRlc2NyaXB0b3IoKTsKKyAgc3RhdGljIGNvbnN0IFNvdXJjZUNvZGVJbmZvJiBkZWZhdWx0X2luc3RhbmNlKCk7CisKKyAgdm9pZCBTd2FwKFNvdXJjZUNvZGVJbmZvKiBvdGhlcik7CisKKyAgLy8gaW1wbGVtZW50cyBNZXNzYWdlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBpbmxpbmUgU291cmNlQ29kZUluZm8qIE5ldygpIGNvbnN0IHsgcmV0dXJuIE5ldyhOVUxMKTsgfQorCisgIFNvdXJjZUNvZGVJbmZvKiBOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0OworICB2b2lkIENvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgQ29weUZyb20oY29uc3QgU291cmNlQ29kZUluZm8mIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCBTb3VyY2VDb2RlSW5mbyYgZnJvbSk7CisgIHZvaWQgQ2xlYXIoKTsKKyAgYm9vbCBJc0luaXRpYWxpemVkKCkgY29uc3Q7CisKKyAgaW50IEJ5dGVTaXplKCkgY29uc3Q7CisgIGJvb2wgTWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpOworICB2b2lkIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIG91dHB1dCkgY29uc3Q7CisgIGludCBHZXRDYWNoZWRTaXplKCkgY29uc3QgeyByZXR1cm4gX2NhY2hlZF9zaXplXzsgfQorICBwcml2YXRlOgorICB2b2lkIFNoYXJlZEN0b3IoKTsKKyAgdm9pZCBTaGFyZWREdG9yKCk7CisgIHZvaWQgU2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3Q7CisgIHZvaWQgSW50ZXJuYWxTd2FwKFNvdXJjZUNvZGVJbmZvKiBvdGhlcik7CisgIHByaXZhdGU6CisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYU5vVmlydHVhbCgpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5hcmVuYSgpOworICB9CisgIGlubGluZSB2b2lkKiBNYXliZUFyZW5hUHRyKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnJhd19hcmVuYV9wdHIoKTsKKyAgfQorICBwdWJsaWM6CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBHZXRNZXRhZGF0YSgpIGNvbnN0OworCisgIC8vIG5lc3RlZCB0eXBlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgdHlwZWRlZiBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbiBMb2NhdGlvbjsKKworICAvLyBhY2Nlc3NvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24gbG9jYXRpb24gPSAxOworICBpbnQgbG9jYXRpb25fc2l6ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX2xvY2F0aW9uKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga0xvY2F0aW9uRmllbGROdW1iZXIgPSAxOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uJiBsb2NhdGlvbihpbnQgaW5kZXgpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uKiBtdXRhYmxlX2xvY2F0aW9uKGludCBpbmRleCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29kZUluZm9fTG9jYXRpb24qIGFkZF9sb2NhdGlvbigpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29kZUluZm9fTG9jYXRpb24gPioKKyAgICAgIG11dGFibGVfbG9jYXRpb24oKTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uID4mCisgICAgICBsb2NhdGlvbigpIGNvbnN0OworCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8pCisgcHJpdmF0ZToKKworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpJbnRlcm5hbE1ldGFkYXRhV2l0aEFyZW5hIF9pbnRlcm5hbF9tZXRhZGF0YV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIF9oYXNfYml0c19bMV07CisgIG11dGFibGUgaW50IF9jYWNoZWRfc2l6ZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbiA+IGxvY2F0aW9uXzsKKyAgZnJpZW5kIHZvaWQgTElCUFJPVE9CVUZfRVhQT1JUIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfQXNzaWduRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKworICB2b2lkIEluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICBzdGF0aWMgU291cmNlQ29kZUluZm8qIGRlZmF1bHRfaW5zdGFuY2VfOworfTsKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb24gOiBwdWJsaWMgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlIHsKKyBwdWJsaWM6CisgIEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb24oKTsKKyAgdmlydHVhbCB+R2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbigpOworCisgIEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb24oY29uc3QgR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbiYgZnJvbSk7CisKKyAgaW5saW5lIEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb24mIG9wZXJhdG9yPShjb25zdCBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uJiBmcm9tKSB7CisgICAgQ29weUZyb20oZnJvbSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgaW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcygpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy51bmtub3duX2ZpZWxkcygpOworICB9CisKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5rbm93bkZpZWxkU2V0KiBtdXRhYmxlX3Vua25vd25fZmllbGRzKCkgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLm11dGFibGVfdW5rbm93bl9maWVsZHMoKTsKKyAgfQorCisgIHN0YXRpYyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIGRlc2NyaXB0b3IoKTsKKyAgc3RhdGljIGNvbnN0IEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb24mIGRlZmF1bHRfaW5zdGFuY2UoKTsKKworICB2b2lkIFN3YXAoR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbiogb3RoZXIpOworCisgIC8vIGltcGxlbWVudHMgTWVzc2FnZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgaW5saW5lIEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb24qIE5ldygpIGNvbnN0IHsgcmV0dXJuIE5ldyhOVUxMKTsgfQorCisgIEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb24qIE5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3Q7CisgIHZvaWQgQ29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbiYgZnJvbSk7CisgIHZvaWQgQ2xlYXIoKTsKKyAgYm9vbCBJc0luaXRpYWxpemVkKCkgY29uc3Q7CisKKyAgaW50IEJ5dGVTaXplKCkgY29uc3Q7CisgIGJvb2wgTWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpOworICB2b2lkIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIG91dHB1dCkgY29uc3Q7CisgIGludCBHZXRDYWNoZWRTaXplKCkgY29uc3QgeyByZXR1cm4gX2NhY2hlZF9zaXplXzsgfQorICBwcml2YXRlOgorICB2b2lkIFNoYXJlZEN0b3IoKTsKKyAgdm9pZCBTaGFyZWREdG9yKCk7CisgIHZvaWQgU2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3Q7CisgIHZvaWQgSW50ZXJuYWxTd2FwKEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb24qIG90aGVyKTsKKyAgcHJpdmF0ZToKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hTm9WaXJ0dWFsKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLmFyZW5hKCk7CisgIH0KKyAgaW5saW5lIHZvaWQqIE1heWJlQXJlbmFQdHIoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ucmF3X2FyZW5hX3B0cigpOworICB9CisgIHB1YmxpYzoKKworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEdldE1ldGFkYXRhKCkgY29uc3Q7CisKKyAgLy8gbmVzdGVkIHR5cGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBhY2Nlc3NvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIHJlcGVhdGVkIGludDMyIHBhdGggPSAxIFtwYWNrZWQgPSB0cnVlXTsKKyAgaW50IHBhdGhfc2l6ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX3BhdGgoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrUGF0aEZpZWxkTnVtYmVyID0gMTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiBwYXRoKGludCBpbmRleCkgY29uc3Q7CisgIHZvaWQgc2V0X3BhdGgoaW50IGluZGV4LCA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKTsKKyAgdm9pZCBhZGRfcGF0aCg6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZEZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyID4mCisgICAgICBwYXRoKCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiA+KgorICAgICAgbXV0YWJsZV9wYXRoKCk7CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIHNvdXJjZV9maWxlID0gMjsKKyAgYm9vbCBoYXNfc291cmNlX2ZpbGUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9zb3VyY2VfZmlsZSgpOworICBzdGF0aWMgY29uc3QgaW50IGtTb3VyY2VGaWxlRmllbGROdW1iZXIgPSAyOworICBjb25zdCA6OnN0ZDo6c3RyaW5nJiBzb3VyY2VfZmlsZSgpIGNvbnN0OworICB2b2lkIHNldF9zb3VyY2VfZmlsZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X3NvdXJjZV9maWxlKGNvbnN0IGNoYXIqIHZhbHVlKTsKKyAgdm9pZCBzZXRfc291cmNlX2ZpbGUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKTsKKyAgOjpzdGQ6OnN0cmluZyogbXV0YWJsZV9zb3VyY2VfZmlsZSgpOworICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlX3NvdXJjZV9maWxlKCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF9zb3VyY2VfZmlsZSg6OnN0ZDo6c3RyaW5nKiBzb3VyY2VfZmlsZSk7CisKKyAgLy8gb3B0aW9uYWwgaW50MzIgYmVnaW4gPSAzOworICBib29sIGhhc19iZWdpbigpIGNvbnN0OworICB2b2lkIGNsZWFyX2JlZ2luKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga0JlZ2luRmllbGROdW1iZXIgPSAzOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIGJlZ2luKCkgY29uc3Q7CisgIHZvaWQgc2V0X2JlZ2luKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgdmFsdWUpOworCisgIC8vIG9wdGlvbmFsIGludDMyIGVuZCA9IDQ7CisgIGJvb2wgaGFzX2VuZCgpIGNvbnN0OworICB2b2lkIGNsZWFyX2VuZCgpOworICBzdGF0aWMgY29uc3QgaW50IGtFbmRGaWVsZE51bWJlciA9IDQ7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgZW5kKCkgY29uc3Q7CisgIHZvaWQgc2V0X2VuZCg6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKTsKKworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6Z29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZENvZGVJbmZvLkFubm90YXRpb24pCisgcHJpdmF0ZToKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19zb3VyY2VfZmlsZSgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfc291cmNlX2ZpbGUoKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19iZWdpbigpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfYmVnaW4oKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19lbmQoKTsKKyAgaW5saW5lIHZvaWQgY2xlYXJfaGFzX2VuZCgpOworCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEgX2ludGVybmFsX21ldGFkYXRhXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgX2hhc19iaXRzX1sxXTsKKyAgbXV0YWJsZSBpbnQgX2NhY2hlZF9zaXplXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZEZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyID4gcGF0aF87CisgIG11dGFibGUgaW50IF9wYXRoX2NhY2hlZF9ieXRlX3NpemVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBcmVuYVN0cmluZ1B0ciBzb3VyY2VfZmlsZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgYmVnaW5fOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIGVuZF87CisgIGZyaWVuZCB2b2lkIExJQlBST1RPQlVGX0VYUE9SVCBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfU2h1dGRvd25GaWxlX2dvb2dsZV8yZnByb3RvYnVmXzJmZGVzY3JpcHRvcl8yZXByb3RvKCk7CisKKyAgdm9pZCBJbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgc3RhdGljIEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb24qIGRlZmF1bHRfaW5zdGFuY2VfOworfTsKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEdlbmVyYXRlZENvZGVJbmZvIDogcHVibGljIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSB7CisgcHVibGljOgorICBHZW5lcmF0ZWRDb2RlSW5mbygpOworICB2aXJ0dWFsIH5HZW5lcmF0ZWRDb2RlSW5mbygpOworCisgIEdlbmVyYXRlZENvZGVJbmZvKGNvbnN0IEdlbmVyYXRlZENvZGVJbmZvJiBmcm9tKTsKKworICBpbmxpbmUgR2VuZXJhdGVkQ29kZUluZm8mIG9wZXJhdG9yPShjb25zdCBHZW5lcmF0ZWRDb2RlSW5mbyYgZnJvbSkgeworICAgIENvcHlGcm9tKGZyb20pOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIGlubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlVua25vd25GaWVsZFNldCYgdW5rbm93bl9maWVsZHMoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8udW5rbm93bl9maWVsZHMoKTsKKyAgfQorCisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlVua25vd25GaWVsZFNldCogbXV0YWJsZV91bmtub3duX2ZpZWxkcygpIHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5tdXRhYmxlX3Vua25vd25fZmllbGRzKCk7CisgIH0KKworICBzdGF0aWMgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKCk7CisgIHN0YXRpYyBjb25zdCBHZW5lcmF0ZWRDb2RlSW5mbyYgZGVmYXVsdF9pbnN0YW5jZSgpOworCisgIHZvaWQgU3dhcChHZW5lcmF0ZWRDb2RlSW5mbyogb3RoZXIpOworCisgIC8vIGltcGxlbWVudHMgTWVzc2FnZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgaW5saW5lIEdlbmVyYXRlZENvZGVJbmZvKiBOZXcoKSBjb25zdCB7IHJldHVybiBOZXcoTlVMTCk7IH0KKworICBHZW5lcmF0ZWRDb2RlSW5mbyogTmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdDsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIENvcHlGcm9tKGNvbnN0IEdlbmVyYXRlZENvZGVJbmZvJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgR2VuZXJhdGVkQ29kZUluZm8mIGZyb20pOworICB2b2lkIENsZWFyKCk7CisgIGJvb2wgSXNJbml0aWFsaXplZCgpIGNvbnN0OworCisgIGludCBCeXRlU2l6ZSgpIGNvbnN0OworICBib29sIE1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KTsKKyAgdm9pZCBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSg6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBvdXRwdXQpIGNvbnN0OworICBpbnQgR2V0Q2FjaGVkU2l6ZSgpIGNvbnN0IHsgcmV0dXJuIF9jYWNoZWRfc2l6ZV87IH0KKyAgcHJpdmF0ZToKKyAgdm9pZCBTaGFyZWRDdG9yKCk7CisgIHZvaWQgU2hhcmVkRHRvcigpOworICB2b2lkIFNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0OworICB2b2lkIEludGVybmFsU3dhcChHZW5lcmF0ZWRDb2RlSW5mbyogb3RoZXIpOworICBwcml2YXRlOgorICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogR2V0QXJlbmFOb1ZpcnR1YWwoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8uYXJlbmEoKTsKKyAgfQorICBpbmxpbmUgdm9pZCogTWF5YmVBcmVuYVB0cigpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5yYXdfYXJlbmFfcHRyKCk7CisgIH0KKyAgcHVibGljOgorCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgR2V0TWV0YWRhdGEoKSBjb25zdDsKKworICAvLyBuZXN0ZWQgdHlwZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIHR5cGVkZWYgR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbiBBbm5vdGF0aW9uOworCisgIC8vIGFjY2Vzc29ycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRDb2RlSW5mby5Bbm5vdGF0aW9uIGFubm90YXRpb24gPSAxOworICBpbnQgYW5ub3RhdGlvbl9zaXplKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfYW5ub3RhdGlvbigpOworICBzdGF0aWMgY29uc3QgaW50IGtBbm5vdGF0aW9uRmllbGROdW1iZXIgPSAxOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb24mIGFubm90YXRpb24oaW50IGluZGV4KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uKiBtdXRhYmxlX2Fubm90YXRpb24oaW50IGluZGV4KTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uKiBhZGRfYW5ub3RhdGlvbigpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6R2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbiA+KgorICAgICAgbXV0YWJsZV9hbm5vdGF0aW9uKCk7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uID4mCisgICAgICBhbm5vdGF0aW9uKCkgY29uc3Q7CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRDb2RlSW5mbykKKyBwcml2YXRlOgorCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEgX2ludGVybmFsX21ldGFkYXRhXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgX2hhc19iaXRzX1sxXTsKKyAgbXV0YWJsZSBpbnQgX2NhY2hlZF9zaXplXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb24gPiBhbm5vdGF0aW9uXzsKKyAgZnJpZW5kIHZvaWQgTElCUFJPVE9CVUZfRVhQT1JUIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfQXNzaWduRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmRlc2NyaXB0b3JfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG8oKTsKKworICB2b2lkIEluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICBzdGF0aWMgR2VuZXJhdGVkQ29kZUluZm8qIGRlZmF1bHRfaW5zdGFuY2VfOworfTsKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKyNpZiAhUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisvLyBGaWxlRGVzY3JpcHRvclNldAorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZSA9IDE7CitpbmxpbmUgaW50IEZpbGVEZXNjcmlwdG9yU2V0OjpmaWxlX3NpemUoKSBjb25zdCB7CisgIHJldHVybiBmaWxlXy5zaXplKCk7Cit9CitpbmxpbmUgdm9pZCBGaWxlRGVzY3JpcHRvclNldDo6Y2xlYXJfZmlsZSgpIHsKKyAgZmlsZV8uQ2xlYXIoKTsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVEZXNjcmlwdG9yUHJvdG8mIEZpbGVEZXNjcmlwdG9yU2V0OjpmaWxlKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclNldC5maWxlKQorICByZXR1cm4gZmlsZV8uR2V0KGluZGV4KTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVEZXNjcmlwdG9yUHJvdG8qIEZpbGVEZXNjcmlwdG9yU2V0OjptdXRhYmxlX2ZpbGUoaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclNldC5maWxlKQorICByZXR1cm4gZmlsZV8uTXV0YWJsZShpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlRGVzY3JpcHRvclByb3RvKiBGaWxlRGVzY3JpcHRvclNldDo6YWRkX2ZpbGUoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yU2V0LmZpbGUpCisgIHJldHVybiBmaWxlXy5BZGQoKTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZURlc2NyaXB0b3JQcm90byA+KgorRmlsZURlc2NyaXB0b3JTZXQ6Om11dGFibGVfZmlsZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JTZXQuZmlsZSkKKyAgcmV0dXJuICZmaWxlXzsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZURlc2NyaXB0b3JQcm90byA+JgorRmlsZURlc2NyaXB0b3JTZXQ6OmZpbGUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclNldC5maWxlKQorICByZXR1cm4gZmlsZV87Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gRmlsZURlc2NyaXB0b3JQcm90bworCisvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CitpbmxpbmUgYm9vbCBGaWxlRGVzY3JpcHRvclByb3RvOjpoYXNfbmFtZSgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMXUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX25hbWUoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMXU7Cit9CitpbmxpbmUgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfbmFtZSgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMXU7Cit9CitpbmxpbmUgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9uYW1lKCkgeworICBuYW1lXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGNsZWFyX2hhc19uYW1lKCk7Cit9CitpbmxpbmUgY29uc3QgOjpzdGQ6OnN0cmluZyYgRmlsZURlc2NyaXB0b3JQcm90bzo6bmFtZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5uYW1lKQorICByZXR1cm4gbmFtZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6c2V0X25hbWUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KK2lubGluZSB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OnNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfbmFtZSgpOworICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KK2lubGluZSB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OnNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBGaWxlRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX25hbWUoKSB7CisgIHNldF9oYXNfbmFtZSgpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5uYW1lKQorICByZXR1cm4gbmFtZV8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBGaWxlRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX25hbWUoKSB7CisgIGNsZWFyX2hhc19uYW1lKCk7CisgIHJldHVybiBuYW1lXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6c2V0X2FsbG9jYXRlZF9uYW1lKDo6c3RkOjpzdHJpbmcqIG5hbWUpIHsKKyAgaWYgKG5hbWUgIT0gTlVMTCkgeworICAgIHNldF9oYXNfbmFtZSgpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19uYW1lKCk7CisgIH0KKyAgbmFtZV8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIG5hbWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5uYW1lKQorfQorCisvLyBvcHRpb25hbCBzdHJpbmcgcGFja2FnZSA9IDI7CitpbmxpbmUgYm9vbCBGaWxlRGVzY3JpcHRvclByb3RvOjpoYXNfcGFja2FnZSgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMnUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX3BhY2thZ2UoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMnU7Cit9CitpbmxpbmUgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfcGFja2FnZSgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMnU7Cit9CitpbmxpbmUgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9wYWNrYWdlKCkgeworICBwYWNrYWdlXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGNsZWFyX2hhc19wYWNrYWdlKCk7Cit9CitpbmxpbmUgY29uc3QgOjpzdGQ6OnN0cmluZyYgRmlsZURlc2NyaXB0b3JQcm90bzo6cGFja2FnZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5wYWNrYWdlKQorICByZXR1cm4gcGFja2FnZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6c2V0X3BhY2thZ2UoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgc2V0X2hhc19wYWNrYWdlKCk7CisgIHBhY2thZ2VfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ucGFja2FnZSkKK30KK2lubGluZSB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OnNldF9wYWNrYWdlKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfcGFja2FnZSgpOworICBwYWNrYWdlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ucGFja2FnZSkKK30KK2lubGluZSB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OnNldF9wYWNrYWdlKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX3BhY2thZ2UoKTsKKyAgcGFja2FnZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ucGFja2FnZSkKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBGaWxlRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX3BhY2thZ2UoKSB7CisgIHNldF9oYXNfcGFja2FnZSgpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5wYWNrYWdlKQorICByZXR1cm4gcGFja2FnZV8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBGaWxlRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX3BhY2thZ2UoKSB7CisgIGNsZWFyX2hhc19wYWNrYWdlKCk7CisgIHJldHVybiBwYWNrYWdlXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6c2V0X2FsbG9jYXRlZF9wYWNrYWdlKDo6c3RkOjpzdHJpbmcqIHBhY2thZ2UpIHsKKyAgaWYgKHBhY2thZ2UgIT0gTlVMTCkgeworICAgIHNldF9oYXNfcGFja2FnZSgpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19wYWNrYWdlKCk7CisgIH0KKyAgcGFja2FnZV8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHBhY2thZ2UpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5wYWNrYWdlKQorfQorCisvLyByZXBlYXRlZCBzdHJpbmcgZGVwZW5kZW5jeSA9IDM7CitpbmxpbmUgaW50IEZpbGVEZXNjcmlwdG9yUHJvdG86OmRlcGVuZGVuY3lfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIGRlcGVuZGVuY3lfLnNpemUoKTsKK30KK2lubGluZSB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OmNsZWFyX2RlcGVuZGVuY3koKSB7CisgIGRlcGVuZGVuY3lfLkNsZWFyKCk7Cit9CitpbmxpbmUgY29uc3QgOjpzdGQ6OnN0cmluZyYgRmlsZURlc2NyaXB0b3JQcm90bzo6ZGVwZW5kZW5jeShpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5kZXBlbmRlbmN5KQorICByZXR1cm4gZGVwZW5kZW5jeV8uR2V0KGluZGV4KTsKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBGaWxlRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX2RlcGVuZGVuY3koaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLmRlcGVuZGVuY3kpCisgIHJldHVybiBkZXBlbmRlbmN5Xy5NdXRhYmxlKGluZGV4KTsKK30KK2lubGluZSB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OnNldF9kZXBlbmRlbmN5KGludCBpbmRleCwgY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5kZXBlbmRlbmN5KQorICBkZXBlbmRlbmN5Xy5NdXRhYmxlKGluZGV4KS0+YXNzaWduKHZhbHVlKTsKK30KK2lubGluZSB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OnNldF9kZXBlbmRlbmN5KGludCBpbmRleCwgY29uc3QgY2hhciogdmFsdWUpIHsKKyAgZGVwZW5kZW5jeV8uTXV0YWJsZShpbmRleCktPmFzc2lnbih2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5kZXBlbmRlbmN5KQorfQoraW5saW5lIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6c2V0X2RlcGVuZGVuY3koaW50IGluZGV4LCBjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgZGVwZW5kZW5jeV8uTXV0YWJsZShpbmRleCktPmFzc2lnbigKKyAgICByZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uZGVwZW5kZW5jeSkKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBGaWxlRGVzY3JpcHRvclByb3RvOjphZGRfZGVwZW5kZW5jeSgpIHsKKyAgcmV0dXJuIGRlcGVuZGVuY3lfLkFkZCgpOworfQoraW5saW5lIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6YWRkX2RlcGVuZGVuY3koY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgZGVwZW5kZW5jeV8uQWRkKCktPmFzc2lnbih2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uZGVwZW5kZW5jeSkKK30KK2lubGluZSB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OmFkZF9kZXBlbmRlbmN5KGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIGRlcGVuZGVuY3lfLkFkZCgpLT5hc3NpZ24odmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkX2NoYXI6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uZGVwZW5kZW5jeSkKK30KK2lubGluZSB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OmFkZF9kZXBlbmRlbmN5KGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBkZXBlbmRlbmN5Xy5BZGQoKS0+YXNzaWduKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5kZXBlbmRlbmN5KQorfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpzdGQ6OnN0cmluZz4mCitGaWxlRGVzY3JpcHRvclByb3RvOjpkZXBlbmRlbmN5KCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5kZXBlbmRlbmN5KQorICByZXR1cm4gZGVwZW5kZW5jeV87Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6OnN0ZDo6c3RyaW5nPioKK0ZpbGVEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfZGVwZW5kZW5jeSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5kZXBlbmRlbmN5KQorICByZXR1cm4gJmRlcGVuZGVuY3lfOworfQorCisvLyByZXBlYXRlZCBpbnQzMiBwdWJsaWNfZGVwZW5kZW5jeSA9IDEwOworaW5saW5lIGludCBGaWxlRGVzY3JpcHRvclByb3RvOjpwdWJsaWNfZGVwZW5kZW5jeV9zaXplKCkgY29uc3QgeworICByZXR1cm4gcHVibGljX2RlcGVuZGVuY3lfLnNpemUoKTsKK30KK2lubGluZSB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OmNsZWFyX3B1YmxpY19kZXBlbmRlbmN5KCkgeworICBwdWJsaWNfZGVwZW5kZW5jeV8uQ2xlYXIoKTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIEZpbGVEZXNjcmlwdG9yUHJvdG86OnB1YmxpY19kZXBlbmRlbmN5KGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLnB1YmxpY19kZXBlbmRlbmN5KQorICByZXR1cm4gcHVibGljX2RlcGVuZGVuY3lfLkdldChpbmRleCk7Cit9CitpbmxpbmUgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpzZXRfcHVibGljX2RlcGVuZGVuY3koaW50IGluZGV4LCA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKSB7CisgIHB1YmxpY19kZXBlbmRlbmN5Xy5TZXQoaW5kZXgsIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5wdWJsaWNfZGVwZW5kZW5jeSkKK30KK2lubGluZSB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OmFkZF9wdWJsaWNfZGVwZW5kZW5jeSg6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKSB7CisgIHB1YmxpY19kZXBlbmRlbmN5Xy5BZGQodmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLnB1YmxpY19kZXBlbmRlbmN5KQorfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiA+JgorRmlsZURlc2NyaXB0b3JQcm90bzo6cHVibGljX2RlcGVuZGVuY3koKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLnB1YmxpY19kZXBlbmRlbmN5KQorICByZXR1cm4gcHVibGljX2RlcGVuZGVuY3lfOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiA+KgorRmlsZURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9wdWJsaWNfZGVwZW5kZW5jeSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5wdWJsaWNfZGVwZW5kZW5jeSkKKyAgcmV0dXJuICZwdWJsaWNfZGVwZW5kZW5jeV87Cit9CisKKy8vIHJlcGVhdGVkIGludDMyIHdlYWtfZGVwZW5kZW5jeSA9IDExOworaW5saW5lIGludCBGaWxlRGVzY3JpcHRvclByb3RvOjp3ZWFrX2RlcGVuZGVuY3lfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIHdlYWtfZGVwZW5kZW5jeV8uc2l6ZSgpOworfQoraW5saW5lIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6Y2xlYXJfd2Vha19kZXBlbmRlbmN5KCkgeworICB3ZWFrX2RlcGVuZGVuY3lfLkNsZWFyKCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiBGaWxlRGVzY3JpcHRvclByb3RvOjp3ZWFrX2RlcGVuZGVuY3koaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ud2Vha19kZXBlbmRlbmN5KQorICByZXR1cm4gd2Vha19kZXBlbmRlbmN5Xy5HZXQoaW5kZXgpOworfQoraW5saW5lIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6c2V0X3dlYWtfZGVwZW5kZW5jeShpbnQgaW5kZXgsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgdmFsdWUpIHsKKyAgd2Vha19kZXBlbmRlbmN5Xy5TZXQoaW5kZXgsIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by53ZWFrX2RlcGVuZGVuY3kpCit9CitpbmxpbmUgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjphZGRfd2Vha19kZXBlbmRlbmN5KDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgdmFsdWUpIHsKKyAgd2Vha19kZXBlbmRlbmN5Xy5BZGQodmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLndlYWtfZGVwZW5kZW5jeSkKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgPiYKK0ZpbGVEZXNjcmlwdG9yUHJvdG86OndlYWtfZGVwZW5kZW5jeSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ud2Vha19kZXBlbmRlbmN5KQorICByZXR1cm4gd2Vha19kZXBlbmRlbmN5XzsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgPioKK0ZpbGVEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfd2Vha19kZXBlbmRlbmN5KCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLndlYWtfZGVwZW5kZW5jeSkKKyAgcmV0dXJuICZ3ZWFrX2RlcGVuZGVuY3lfOworfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90byBtZXNzYWdlX3R5cGUgPSA0OworaW5saW5lIGludCBGaWxlRGVzY3JpcHRvclByb3RvOjptZXNzYWdlX3R5cGVfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIG1lc3NhZ2VfdHlwZV8uc2l6ZSgpOworfQoraW5saW5lIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6Y2xlYXJfbWVzc2FnZV90eXBlKCkgeworICBtZXNzYWdlX3R5cGVfLkNsZWFyKCk7Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG8mIEZpbGVEZXNjcmlwdG9yUHJvdG86Om1lc3NhZ2VfdHlwZShpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5tZXNzYWdlX3R5cGUpCisgIHJldHVybiBtZXNzYWdlX3R5cGVfLkdldChpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG8qIEZpbGVEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfbWVzc2FnZV90eXBlKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5tZXNzYWdlX3R5cGUpCisgIHJldHVybiBtZXNzYWdlX3R5cGVfLk11dGFibGUoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclByb3RvKiBGaWxlRGVzY3JpcHRvclByb3RvOjphZGRfbWVzc2FnZV90eXBlKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLm1lc3NhZ2VfdHlwZSkKKyAgcmV0dXJuIG1lc3NhZ2VfdHlwZV8uQWRkKCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQcm90byA+KgorRmlsZURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9tZXNzYWdlX3R5cGUoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ubWVzc2FnZV90eXBlKQorICByZXR1cm4gJm1lc3NhZ2VfdHlwZV87Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQcm90byA+JgorRmlsZURlc2NyaXB0b3JQcm90bzo6bWVzc2FnZV90eXBlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5tZXNzYWdlX3R5cGUpCisgIHJldHVybiBtZXNzYWdlX3R5cGVfOworfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8gZW51bV90eXBlID0gNTsKK2lubGluZSBpbnQgRmlsZURlc2NyaXB0b3JQcm90bzo6ZW51bV90eXBlX3NpemUoKSBjb25zdCB7CisgIHJldHVybiBlbnVtX3R5cGVfLnNpemUoKTsKK30KK2lubGluZSB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OmNsZWFyX2VudW1fdHlwZSgpIHsKKyAgZW51bV90eXBlXy5DbGVhcigpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bURlc2NyaXB0b3JQcm90byYgRmlsZURlc2NyaXB0b3JQcm90bzo6ZW51bV90eXBlKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLmVudW1fdHlwZSkKKyAgcmV0dXJuIGVudW1fdHlwZV8uR2V0KGluZGV4KTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yUHJvdG8qIEZpbGVEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfZW51bV90eXBlKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5lbnVtX3R5cGUpCisgIHJldHVybiBlbnVtX3R5cGVfLk11dGFibGUoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bURlc2NyaXB0b3JQcm90byogRmlsZURlc2NyaXB0b3JQcm90bzo6YWRkX2VudW1fdHlwZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5lbnVtX3R5cGUpCisgIHJldHVybiBlbnVtX3R5cGVfLkFkZCgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvclByb3RvID4qCitGaWxlRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX2VudW1fdHlwZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5lbnVtX3R5cGUpCisgIHJldHVybiAmZW51bV90eXBlXzsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bURlc2NyaXB0b3JQcm90byA+JgorRmlsZURlc2NyaXB0b3JQcm90bzo6ZW51bV90eXBlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5lbnVtX3R5cGUpCisgIHJldHVybiBlbnVtX3R5cGVfOworfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8gc2VydmljZSA9IDY7CitpbmxpbmUgaW50IEZpbGVEZXNjcmlwdG9yUHJvdG86OnNlcnZpY2Vfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIHNlcnZpY2VfLnNpemUoKTsKK30KK2lubGluZSB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OmNsZWFyX3NlcnZpY2UoKSB7CisgIHNlcnZpY2VfLkNsZWFyKCk7Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpTZXJ2aWNlRGVzY3JpcHRvclByb3RvJiBGaWxlRGVzY3JpcHRvclByb3RvOjpzZXJ2aWNlKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLnNlcnZpY2UpCisgIHJldHVybiBzZXJ2aWNlXy5HZXQoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6U2VydmljZURlc2NyaXB0b3JQcm90byogRmlsZURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9zZXJ2aWNlKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5zZXJ2aWNlKQorICByZXR1cm4gc2VydmljZV8uTXV0YWJsZShpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpTZXJ2aWNlRGVzY3JpcHRvclByb3RvKiBGaWxlRGVzY3JpcHRvclByb3RvOjphZGRfc2VydmljZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5zZXJ2aWNlKQorICByZXR1cm4gc2VydmljZV8uQWRkKCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8gPioKK0ZpbGVEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfc2VydmljZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5zZXJ2aWNlKQorICByZXR1cm4gJnNlcnZpY2VfOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpTZXJ2aWNlRGVzY3JpcHRvclByb3RvID4mCitGaWxlRGVzY3JpcHRvclByb3RvOjpzZXJ2aWNlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5zZXJ2aWNlKQorICByZXR1cm4gc2VydmljZV87Cit9CisKKy8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8gZXh0ZW5zaW9uID0gNzsKK2lubGluZSBpbnQgRmlsZURlc2NyaXB0b3JQcm90bzo6ZXh0ZW5zaW9uX3NpemUoKSBjb25zdCB7CisgIHJldHVybiBleHRlbnNpb25fLnNpemUoKTsKK30KK2lubGluZSB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OmNsZWFyX2V4dGVuc2lvbigpIHsKKyAgZXh0ZW5zaW9uXy5DbGVhcigpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG8mIEZpbGVEZXNjcmlwdG9yUHJvdG86OmV4dGVuc2lvbihpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5leHRlbnNpb24pCisgIHJldHVybiBleHRlbnNpb25fLkdldChpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90byogRmlsZURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9leHRlbnNpb24oaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLmV4dGVuc2lvbikKKyAgcmV0dXJuIGV4dGVuc2lvbl8uTXV0YWJsZShpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90byogRmlsZURlc2NyaXB0b3JQcm90bzo6YWRkX2V4dGVuc2lvbigpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5leHRlbnNpb24pCisgIHJldHVybiBleHRlbnNpb25fLkFkZCgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90byA+KgorRmlsZURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9leHRlbnNpb24oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uZXh0ZW5zaW9uKQorICByZXR1cm4gJmV4dGVuc2lvbl87Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvID4mCitGaWxlRGVzY3JpcHRvclByb3RvOjpleHRlbnNpb24oKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLmV4dGVuc2lvbikKKyAgcmV0dXJuIGV4dGVuc2lvbl87Cit9CisKKy8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMgb3B0aW9ucyA9IDg7CitpbmxpbmUgYm9vbCBGaWxlRGVzY3JpcHRvclByb3RvOjpoYXNfb3B0aW9ucygpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDIwMHUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX29wdGlvbnMoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDIwMHU7Cit9CitpbmxpbmUgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfb3B0aW9ucygpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDIwMHU7Cit9CitpbmxpbmUgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9vcHRpb25zKCkgeworICBpZiAob3B0aW9uc18gIT0gTlVMTCkgb3B0aW9uc18tPjo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZU9wdGlvbnM6OkNsZWFyKCk7CisgIGNsZWFyX2hhc19vcHRpb25zKCk7Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlT3B0aW9ucyYgRmlsZURlc2NyaXB0b3JQcm90bzo6b3B0aW9ucygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5vcHRpb25zKQorICByZXR1cm4gb3B0aW9uc18gIT0gTlVMTCA/ICpvcHRpb25zXyA6ICpkZWZhdWx0X2luc3RhbmNlXy0+b3B0aW9uc187Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlT3B0aW9ucyogRmlsZURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9vcHRpb25zKCkgeworICBzZXRfaGFzX29wdGlvbnMoKTsKKyAgaWYgKG9wdGlvbnNfID09IE5VTEwpIHsKKyAgICBvcHRpb25zXyA9IG5ldyA6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVPcHRpb25zOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLm9wdGlvbnMpCisgIHJldHVybiBvcHRpb25zXzsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVPcHRpb25zKiBGaWxlRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX29wdGlvbnMoKSB7CisgIGNsZWFyX2hhc19vcHRpb25zKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZU9wdGlvbnMqIHRlbXAgPSBvcHRpb25zXzsKKyAgb3B0aW9uc18gPSBOVUxMOworICByZXR1cm4gdGVtcDsKK30KK2lubGluZSB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OnNldF9hbGxvY2F0ZWRfb3B0aW9ucyg6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVPcHRpb25zKiBvcHRpb25zKSB7CisgIGRlbGV0ZSBvcHRpb25zXzsKKyAgb3B0aW9uc18gPSBvcHRpb25zOworICBpZiAob3B0aW9ucykgeworICAgIHNldF9oYXNfb3B0aW9ucygpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19vcHRpb25zKCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8ub3B0aW9ucykKK30KKworLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mbyBzb3VyY2VfY29kZV9pbmZvID0gOTsKK2lubGluZSBib29sIEZpbGVEZXNjcmlwdG9yUHJvdG86Omhhc19zb3VyY2VfY29kZV9pbmZvKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwNDAwdSkgIT0gMDsKK30KK2lubGluZSB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OnNldF9oYXNfc291cmNlX2NvZGVfaW5mbygpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwNDAwdTsKK30KK2lubGluZSB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OmNsZWFyX2hhc19zb3VyY2VfY29kZV9pbmZvKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwNDAwdTsKK30KK2lubGluZSB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OmNsZWFyX3NvdXJjZV9jb2RlX2luZm8oKSB7CisgIGlmIChzb3VyY2VfY29kZV9pbmZvXyAhPSBOVUxMKSBzb3VyY2VfY29kZV9pbmZvXy0+Ojpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb2RlSW5mbzo6Q2xlYXIoKTsKKyAgY2xlYXJfaGFzX3NvdXJjZV9jb2RlX2luZm8oKTsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvZGVJbmZvJiBGaWxlRGVzY3JpcHRvclByb3RvOjpzb3VyY2VfY29kZV9pbmZvKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLnNvdXJjZV9jb2RlX2luZm8pCisgIHJldHVybiBzb3VyY2VfY29kZV9pbmZvXyAhPSBOVUxMID8gKnNvdXJjZV9jb2RlX2luZm9fIDogKmRlZmF1bHRfaW5zdGFuY2VfLT5zb3VyY2VfY29kZV9pbmZvXzsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvZGVJbmZvKiBGaWxlRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX3NvdXJjZV9jb2RlX2luZm8oKSB7CisgIHNldF9oYXNfc291cmNlX2NvZGVfaW5mbygpOworICBpZiAoc291cmNlX2NvZGVfaW5mb18gPT0gTlVMTCkgeworICAgIHNvdXJjZV9jb2RlX2luZm9fID0gbmV3IDo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29kZUluZm87CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uc291cmNlX2NvZGVfaW5mbykKKyAgcmV0dXJuIHNvdXJjZV9jb2RlX2luZm9fOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29kZUluZm8qIEZpbGVEZXNjcmlwdG9yUHJvdG86OnJlbGVhc2Vfc291cmNlX2NvZGVfaW5mbygpIHsKKyAgY2xlYXJfaGFzX3NvdXJjZV9jb2RlX2luZm8oKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb2RlSW5mbyogdGVtcCA9IHNvdXJjZV9jb2RlX2luZm9fOworICBzb3VyY2VfY29kZV9pbmZvXyA9IE5VTEw7CisgIHJldHVybiB0ZW1wOworfQoraW5saW5lIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6c2V0X2FsbG9jYXRlZF9zb3VyY2VfY29kZV9pbmZvKDo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29kZUluZm8qIHNvdXJjZV9jb2RlX2luZm8pIHsKKyAgZGVsZXRlIHNvdXJjZV9jb2RlX2luZm9fOworICBzb3VyY2VfY29kZV9pbmZvXyA9IHNvdXJjZV9jb2RlX2luZm87CisgIGlmIChzb3VyY2VfY29kZV9pbmZvKSB7CisgICAgc2V0X2hhc19zb3VyY2VfY29kZV9pbmZvKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX3NvdXJjZV9jb2RlX2luZm8oKTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5zb3VyY2VfY29kZV9pbmZvKQorfQorCisvLyBvcHRpb25hbCBzdHJpbmcgc3ludGF4ID0gMTI7CitpbmxpbmUgYm9vbCBGaWxlRGVzY3JpcHRvclByb3RvOjpoYXNfc3ludGF4KCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwODAwdSkgIT0gMDsKK30KK2lubGluZSB2b2lkIEZpbGVEZXNjcmlwdG9yUHJvdG86OnNldF9oYXNfc3ludGF4KCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDA4MDB1OworfQoraW5saW5lIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX3N5bnRheCgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDgwMHU7Cit9CitpbmxpbmUgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9zeW50YXgoKSB7CisgIHN5bnRheF8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfc3ludGF4KCk7Cit9CitpbmxpbmUgY29uc3QgOjpzdGQ6OnN0cmluZyYgRmlsZURlc2NyaXB0b3JQcm90bzo6c3ludGF4KCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLnN5bnRheCkKKyAgcmV0dXJuIHN5bnRheF8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6c2V0X3N5bnRheChjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBzZXRfaGFzX3N5bnRheCgpOworICBzeW50YXhfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uc3ludGF4KQorfQoraW5saW5lIHZvaWQgRmlsZURlc2NyaXB0b3JQcm90bzo6c2V0X3N5bnRheChjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX3N5bnRheCgpOworICBzeW50YXhfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90by5zeW50YXgpCit9CitpbmxpbmUgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpzZXRfc3ludGF4KGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX3N5bnRheCgpOworICBzeW50YXhfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvLnN5bnRheCkKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBGaWxlRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX3N5bnRheCgpIHsKKyAgc2V0X2hhc19zeW50YXgoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uc3ludGF4KQorICByZXR1cm4gc3ludGF4Xy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIEZpbGVEZXNjcmlwdG9yUHJvdG86OnJlbGVhc2Vfc3ludGF4KCkgeworICBjbGVhcl9oYXNfc3ludGF4KCk7CisgIHJldHVybiBzeW50YXhfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBGaWxlRGVzY3JpcHRvclByb3RvOjpzZXRfYWxsb2NhdGVkX3N5bnRheCg6OnN0ZDo6c3RyaW5nKiBzeW50YXgpIHsKKyAgaWYgKHN5bnRheCAhPSBOVUxMKSB7CisgICAgc2V0X2hhc19zeW50YXgoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfc3ludGF4KCk7CisgIH0KKyAgc3ludGF4Xy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgc3ludGF4KTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8uc3ludGF4KQorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZQorCisvLyBvcHRpb25hbCBpbnQzMiBzdGFydCA9IDE7CitpbmxpbmUgYm9vbCBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6Omhhc19zdGFydCgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMXUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6OnNldF9oYXNfc3RhcnQoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMXU7Cit9CitpbmxpbmUgdm9pZCBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6OmNsZWFyX2hhc19zdGFydCgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMXU7Cit9CitpbmxpbmUgdm9pZCBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6OmNsZWFyX3N0YXJ0KCkgeworICBzdGFydF8gPSAwOworICBjbGVhcl9oYXNfc3RhcnQoKTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZTo6c3RhcnQoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5FeHRlbnNpb25SYW5nZS5zdGFydCkKKyAgcmV0dXJuIHN0YXJ0XzsKK30KK2lubGluZSB2b2lkIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZTo6c2V0X3N0YXJ0KDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgdmFsdWUpIHsKKyAgc2V0X2hhc19zdGFydCgpOworICBzdGFydF8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLkV4dGVuc2lvblJhbmdlLnN0YXJ0KQorfQorCisvLyBvcHRpb25hbCBpbnQzMiBlbmQgPSAyOworaW5saW5lIGJvb2wgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOjpoYXNfZW5kKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAydSkgIT0gMDsKK30KK2lubGluZSB2b2lkIERlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZTo6c2V0X2hhc19lbmQoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMnU7Cit9CitpbmxpbmUgdm9pZCBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6OmNsZWFyX2hhc19lbmQoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDJ1OworfQoraW5saW5lIHZvaWQgRGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlOjpjbGVhcl9lbmQoKSB7CisgIGVuZF8gPSAwOworICBjbGVhcl9oYXNfZW5kKCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6OmVuZCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLkV4dGVuc2lvblJhbmdlLmVuZCkKKyAgcmV0dXJuIGVuZF87Cit9CitpbmxpbmUgdm9pZCBEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2U6OnNldF9lbmQoOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiB2YWx1ZSkgeworICBzZXRfaGFzX2VuZCgpOworICBlbmRfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5FeHRlbnNpb25SYW5nZS5lbmQpCit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gRGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2UKKworLy8gb3B0aW9uYWwgaW50MzIgc3RhcnQgPSAxOworaW5saW5lIGJvb2wgRGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2U6Omhhc19zdGFydCgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMXUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZTo6c2V0X2hhc19zdGFydCgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAxdTsKK30KK2lubGluZSB2b2lkIERlc2NyaXB0b3JQcm90b19SZXNlcnZlZFJhbmdlOjpjbGVhcl9oYXNfc3RhcnQoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDF1OworfQoraW5saW5lIHZvaWQgRGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2U6OmNsZWFyX3N0YXJ0KCkgeworICBzdGFydF8gPSAwOworICBjbGVhcl9oYXNfc3RhcnQoKTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIERlc2NyaXB0b3JQcm90b19SZXNlcnZlZFJhbmdlOjpzdGFydCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLlJlc2VydmVkUmFuZ2Uuc3RhcnQpCisgIHJldHVybiBzdGFydF87Cit9CitpbmxpbmUgdm9pZCBEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZTo6c2V0X3N0YXJ0KDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgdmFsdWUpIHsKKyAgc2V0X2hhc19zdGFydCgpOworICBzdGFydF8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLlJlc2VydmVkUmFuZ2Uuc3RhcnQpCit9CisKKy8vIG9wdGlvbmFsIGludDMyIGVuZCA9IDI7CitpbmxpbmUgYm9vbCBEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZTo6aGFzX2VuZCgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMnUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZTo6c2V0X2hhc19lbmQoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMnU7Cit9CitpbmxpbmUgdm9pZCBEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZTo6Y2xlYXJfaGFzX2VuZCgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMnU7Cit9CitpbmxpbmUgdm9pZCBEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZTo6Y2xlYXJfZW5kKCkgeworICBlbmRfID0gMDsKKyAgY2xlYXJfaGFzX2VuZCgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgRGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2U6OmVuZCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLlJlc2VydmVkUmFuZ2UuZW5kKQorICByZXR1cm4gZW5kXzsKK30KK2lubGluZSB2b2lkIERlc2NyaXB0b3JQcm90b19SZXNlcnZlZFJhbmdlOjpzZXRfZW5kKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgdmFsdWUpIHsKKyAgc2V0X2hhc19lbmQoKTsKKyAgZW5kXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uUmVzZXJ2ZWRSYW5nZS5lbmQpCit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gRGVzY3JpcHRvclByb3RvCisKKy8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKK2lubGluZSBib29sIERlc2NyaXB0b3JQcm90bzo6aGFzX25hbWUoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDF1KSAhPSAwOworfQoraW5saW5lIHZvaWQgRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX25hbWUoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMXU7Cit9CitpbmxpbmUgdm9pZCBEZXNjcmlwdG9yUHJvdG86OmNsZWFyX2hhc19uYW1lKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAxdTsKK30KK2lubGluZSB2b2lkIERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfbmFtZSgpIHsKKyAgbmFtZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfbmFtZSgpOworfQoraW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIERlc2NyaXB0b3JQcm90bzo6bmFtZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLm5hbWUpCisgIHJldHVybiBuYW1lXy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBEZXNjcmlwdG9yUHJvdG86OnNldF9uYW1lKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfbmFtZSgpOworICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KK2lubGluZSB2b2lkIERlc2NyaXB0b3JQcm90bzo6c2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLm5hbWUpCit9CitpbmxpbmUgdm9pZCBEZXNjcmlwdG9yUHJvdG86OnNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5uYW1lKQorfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIERlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9uYW1lKCkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5uYW1lKQorICByZXR1cm4gbmFtZV8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBEZXNjcmlwdG9yUHJvdG86OnJlbGVhc2VfbmFtZSgpIHsKKyAgY2xlYXJfaGFzX25hbWUoKTsKKyAgcmV0dXJuIG5hbWVfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBEZXNjcmlwdG9yUHJvdG86OnNldF9hbGxvY2F0ZWRfbmFtZSg6OnN0ZDo6c3RyaW5nKiBuYW1lKSB7CisgIGlmIChuYW1lICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX25hbWUoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfbmFtZSgpOworICB9CisgIG5hbWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBuYW1lKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5uYW1lKQorfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvIGZpZWxkID0gMjsKK2lubGluZSBpbnQgRGVzY3JpcHRvclByb3RvOjpmaWVsZF9zaXplKCkgY29uc3QgeworICByZXR1cm4gZmllbGRfLnNpemUoKTsKK30KK2lubGluZSB2b2lkIERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfZmllbGQoKSB7CisgIGZpZWxkXy5DbGVhcigpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG8mIERlc2NyaXB0b3JQcm90bzo6ZmllbGQoaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5maWVsZCkKKyAgcmV0dXJuIGZpZWxkXy5HZXQoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG8qIERlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9maWVsZChpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5maWVsZCkKKyAgcmV0dXJuIGZpZWxkXy5NdXRhYmxlKGluZGV4KTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvKiBEZXNjcmlwdG9yUHJvdG86OmFkZF9maWVsZCgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLmZpZWxkKQorICByZXR1cm4gZmllbGRfLkFkZCgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90byA+KgorRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX2ZpZWxkKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uZmllbGQpCisgIHJldHVybiAmZmllbGRfOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90byA+JgorRGVzY3JpcHRvclByb3RvOjpmaWVsZCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5maWVsZCkKKyAgcmV0dXJuIGZpZWxkXzsKK30KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90byBleHRlbnNpb24gPSA2OworaW5saW5lIGludCBEZXNjcmlwdG9yUHJvdG86OmV4dGVuc2lvbl9zaXplKCkgY29uc3QgeworICByZXR1cm4gZXh0ZW5zaW9uXy5zaXplKCk7Cit9CitpbmxpbmUgdm9pZCBEZXNjcmlwdG9yUHJvdG86OmNsZWFyX2V4dGVuc2lvbigpIHsKKyAgZXh0ZW5zaW9uXy5DbGVhcigpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG8mIERlc2NyaXB0b3JQcm90bzo6ZXh0ZW5zaW9uKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uZXh0ZW5zaW9uKQorICByZXR1cm4gZXh0ZW5zaW9uXy5HZXQoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG8qIERlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9leHRlbnNpb24oaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uZXh0ZW5zaW9uKQorICByZXR1cm4gZXh0ZW5zaW9uXy5NdXRhYmxlKGluZGV4KTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvKiBEZXNjcmlwdG9yUHJvdG86OmFkZF9leHRlbnNpb24oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5leHRlbnNpb24pCisgIHJldHVybiBleHRlbnNpb25fLkFkZCgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90byA+KgorRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX2V4dGVuc2lvbigpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLmV4dGVuc2lvbikKKyAgcmV0dXJuICZleHRlbnNpb25fOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90byA+JgorRGVzY3JpcHRvclByb3RvOjpleHRlbnNpb24oKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uZXh0ZW5zaW9uKQorICByZXR1cm4gZXh0ZW5zaW9uXzsKK30KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8gbmVzdGVkX3R5cGUgPSAzOworaW5saW5lIGludCBEZXNjcmlwdG9yUHJvdG86Om5lc3RlZF90eXBlX3NpemUoKSBjb25zdCB7CisgIHJldHVybiBuZXN0ZWRfdHlwZV8uc2l6ZSgpOworfQoraW5saW5lIHZvaWQgRGVzY3JpcHRvclByb3RvOjpjbGVhcl9uZXN0ZWRfdHlwZSgpIHsKKyAgbmVzdGVkX3R5cGVfLkNsZWFyKCk7Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG8mIERlc2NyaXB0b3JQcm90bzo6bmVzdGVkX3R5cGUoaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5uZXN0ZWRfdHlwZSkKKyAgcmV0dXJuIG5lc3RlZF90eXBlXy5HZXQoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclByb3RvKiBEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfbmVzdGVkX3R5cGUoaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ubmVzdGVkX3R5cGUpCisgIHJldHVybiBuZXN0ZWRfdHlwZV8uTXV0YWJsZShpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG8qIERlc2NyaXB0b3JQcm90bzo6YWRkX25lc3RlZF90eXBlKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ubmVzdGVkX3R5cGUpCisgIHJldHVybiBuZXN0ZWRfdHlwZV8uQWRkKCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQcm90byA+KgorRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX25lc3RlZF90eXBlKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ubmVzdGVkX3R5cGUpCisgIHJldHVybiAmbmVzdGVkX3R5cGVfOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG8gPiYKK0Rlc2NyaXB0b3JQcm90bzo6bmVzdGVkX3R5cGUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ubmVzdGVkX3R5cGUpCisgIHJldHVybiBuZXN0ZWRfdHlwZV87Cit9CisKKy8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRW51bURlc2NyaXB0b3JQcm90byBlbnVtX3R5cGUgPSA0OworaW5saW5lIGludCBEZXNjcmlwdG9yUHJvdG86OmVudW1fdHlwZV9zaXplKCkgY29uc3QgeworICByZXR1cm4gZW51bV90eXBlXy5zaXplKCk7Cit9CitpbmxpbmUgdm9pZCBEZXNjcmlwdG9yUHJvdG86OmNsZWFyX2VudW1fdHlwZSgpIHsKKyAgZW51bV90eXBlXy5DbGVhcigpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bURlc2NyaXB0b3JQcm90byYgRGVzY3JpcHRvclByb3RvOjplbnVtX3R5cGUoaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5lbnVtX3R5cGUpCisgIHJldHVybiBlbnVtX3R5cGVfLkdldChpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvclByb3RvKiBEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfZW51bV90eXBlKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLmVudW1fdHlwZSkKKyAgcmV0dXJuIGVudW1fdHlwZV8uTXV0YWJsZShpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvclByb3RvKiBEZXNjcmlwdG9yUHJvdG86OmFkZF9lbnVtX3R5cGUoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5lbnVtX3R5cGUpCisgIHJldHVybiBlbnVtX3R5cGVfLkFkZCgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvclByb3RvID4qCitEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfZW51bV90eXBlKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uZW51bV90eXBlKQorICByZXR1cm4gJmVudW1fdHlwZV87Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yUHJvdG8gPiYKK0Rlc2NyaXB0b3JQcm90bzo6ZW51bV90eXBlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLmVudW1fdHlwZSkKKyAgcmV0dXJuIGVudW1fdHlwZV87Cit9CisKKy8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLkV4dGVuc2lvblJhbmdlIGV4dGVuc2lvbl9yYW5nZSA9IDU7CitpbmxpbmUgaW50IERlc2NyaXB0b3JQcm90bzo6ZXh0ZW5zaW9uX3JhbmdlX3NpemUoKSBjb25zdCB7CisgIHJldHVybiBleHRlbnNpb25fcmFuZ2VfLnNpemUoKTsKK30KK2lubGluZSB2b2lkIERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfZXh0ZW5zaW9uX3JhbmdlKCkgeworICBleHRlbnNpb25fcmFuZ2VfLkNsZWFyKCk7Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UmIERlc2NyaXB0b3JQcm90bzo6ZXh0ZW5zaW9uX3JhbmdlKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uZXh0ZW5zaW9uX3JhbmdlKQorICByZXR1cm4gZXh0ZW5zaW9uX3JhbmdlXy5HZXQoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclByb3RvX0V4dGVuc2lvblJhbmdlKiBEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfZXh0ZW5zaW9uX3JhbmdlKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLmV4dGVuc2lvbl9yYW5nZSkKKyAgcmV0dXJuIGV4dGVuc2lvbl9yYW5nZV8uTXV0YWJsZShpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UqIERlc2NyaXB0b3JQcm90bzo6YWRkX2V4dGVuc2lvbl9yYW5nZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLmV4dGVuc2lvbl9yYW5nZSkKKyAgcmV0dXJuIGV4dGVuc2lvbl9yYW5nZV8uQWRkKCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQcm90b19FeHRlbnNpb25SYW5nZSA+KgorRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX2V4dGVuc2lvbl9yYW5nZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLmV4dGVuc2lvbl9yYW5nZSkKKyAgcmV0dXJuICZleHRlbnNpb25fcmFuZ2VfOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG9fRXh0ZW5zaW9uUmFuZ2UgPiYKK0Rlc2NyaXB0b3JQcm90bzo6ZXh0ZW5zaW9uX3JhbmdlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLmV4dGVuc2lvbl9yYW5nZSkKKyAgcmV0dXJuIGV4dGVuc2lvbl9yYW5nZV87Cit9CisKKy8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuT25lb2ZEZXNjcmlwdG9yUHJvdG8gb25lb2ZfZGVjbCA9IDg7CitpbmxpbmUgaW50IERlc2NyaXB0b3JQcm90bzo6b25lb2ZfZGVjbF9zaXplKCkgY29uc3QgeworICByZXR1cm4gb25lb2ZfZGVjbF8uc2l6ZSgpOworfQoraW5saW5lIHZvaWQgRGVzY3JpcHRvclByb3RvOjpjbGVhcl9vbmVvZl9kZWNsKCkgeworICBvbmVvZl9kZWNsXy5DbGVhcigpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6T25lb2ZEZXNjcmlwdG9yUHJvdG8mIERlc2NyaXB0b3JQcm90bzo6b25lb2ZfZGVjbChpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLm9uZW9mX2RlY2wpCisgIHJldHVybiBvbmVvZl9kZWNsXy5HZXQoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6T25lb2ZEZXNjcmlwdG9yUHJvdG8qIERlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9vbmVvZl9kZWNsKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLm9uZW9mX2RlY2wpCisgIHJldHVybiBvbmVvZl9kZWNsXy5NdXRhYmxlKGluZGV4KTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6Ok9uZW9mRGVzY3JpcHRvclByb3RvKiBEZXNjcmlwdG9yUHJvdG86OmFkZF9vbmVvZl9kZWNsKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ub25lb2ZfZGVjbCkKKyAgcmV0dXJuIG9uZW9mX2RlY2xfLkFkZCgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpPbmVvZkRlc2NyaXB0b3JQcm90byA+KgorRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX29uZW9mX2RlY2woKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5vbmVvZl9kZWNsKQorICByZXR1cm4gJm9uZW9mX2RlY2xfOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpPbmVvZkRlc2NyaXB0b3JQcm90byA+JgorRGVzY3JpcHRvclByb3RvOjpvbmVvZl9kZWNsKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLm9uZW9mX2RlY2wpCisgIHJldHVybiBvbmVvZl9kZWNsXzsKK30KKworLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucyBvcHRpb25zID0gNzsKK2lubGluZSBib29sIERlc2NyaXB0b3JQcm90bzo6aGFzX29wdGlvbnMoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwODB1KSAhPSAwOworfQoraW5saW5lIHZvaWQgRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX29wdGlvbnMoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDA4MHU7Cit9CitpbmxpbmUgdm9pZCBEZXNjcmlwdG9yUHJvdG86OmNsZWFyX2hhc19vcHRpb25zKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDgwdTsKK30KK2lubGluZSB2b2lkIERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfb3B0aW9ucygpIHsKKyAgaWYgKG9wdGlvbnNfICE9IE5VTEwpIG9wdGlvbnNfLT46Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VPcHRpb25zOjpDbGVhcigpOworICBjbGVhcl9oYXNfb3B0aW9ucygpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZU9wdGlvbnMmIERlc2NyaXB0b3JQcm90bzo6b3B0aW9ucygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLm9wdGlvbnMpCisgIHJldHVybiBvcHRpb25zXyAhPSBOVUxMID8gKm9wdGlvbnNfIDogKmRlZmF1bHRfaW5zdGFuY2VfLT5vcHRpb25zXzsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VPcHRpb25zKiBEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfb3B0aW9ucygpIHsKKyAgc2V0X2hhc19vcHRpb25zKCk7CisgIGlmIChvcHRpb25zXyA9PSBOVUxMKSB7CisgICAgb3B0aW9uc18gPSBuZXcgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlT3B0aW9uczsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLm9wdGlvbnMpCisgIHJldHVybiBvcHRpb25zXzsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VPcHRpb25zKiBEZXNjcmlwdG9yUHJvdG86OnJlbGVhc2Vfb3B0aW9ucygpIHsKKyAgY2xlYXJfaGFzX29wdGlvbnMoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlT3B0aW9ucyogdGVtcCA9IG9wdGlvbnNfOworICBvcHRpb25zXyA9IE5VTEw7CisgIHJldHVybiB0ZW1wOworfQoraW5saW5lIHZvaWQgRGVzY3JpcHRvclByb3RvOjpzZXRfYWxsb2NhdGVkX29wdGlvbnMoOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlT3B0aW9ucyogb3B0aW9ucykgeworICBkZWxldGUgb3B0aW9uc187CisgIG9wdGlvbnNfID0gb3B0aW9uczsKKyAgaWYgKG9wdGlvbnMpIHsKKyAgICBzZXRfaGFzX29wdGlvbnMoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfb3B0aW9ucygpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ub3B0aW9ucykKK30KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uUmVzZXJ2ZWRSYW5nZSByZXNlcnZlZF9yYW5nZSA9IDk7CitpbmxpbmUgaW50IERlc2NyaXB0b3JQcm90bzo6cmVzZXJ2ZWRfcmFuZ2Vfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIHJlc2VydmVkX3JhbmdlXy5zaXplKCk7Cit9CitpbmxpbmUgdm9pZCBEZXNjcmlwdG9yUHJvdG86OmNsZWFyX3Jlc2VydmVkX3JhbmdlKCkgeworICByZXNlcnZlZF9yYW5nZV8uQ2xlYXIoKTsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQcm90b19SZXNlcnZlZFJhbmdlJiBEZXNjcmlwdG9yUHJvdG86OnJlc2VydmVkX3JhbmdlKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ucmVzZXJ2ZWRfcmFuZ2UpCisgIHJldHVybiByZXNlcnZlZF9yYW5nZV8uR2V0KGluZGV4KTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQcm90b19SZXNlcnZlZFJhbmdlKiBEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfcmVzZXJ2ZWRfcmFuZ2UoaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ucmVzZXJ2ZWRfcmFuZ2UpCisgIHJldHVybiByZXNlcnZlZF9yYW5nZV8uTXV0YWJsZShpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUHJvdG9fUmVzZXJ2ZWRSYW5nZSogRGVzY3JpcHRvclByb3RvOjphZGRfcmVzZXJ2ZWRfcmFuZ2UoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5yZXNlcnZlZF9yYW5nZSkKKyAgcmV0dXJuIHJlc2VydmVkX3JhbmdlXy5BZGQoKTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2UgPioKK0Rlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9yZXNlcnZlZF9yYW5nZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLnJlc2VydmVkX3JhbmdlKQorICByZXR1cm4gJnJlc2VydmVkX3JhbmdlXzsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclByb3RvX1Jlc2VydmVkUmFuZ2UgPiYKK0Rlc2NyaXB0b3JQcm90bzo6cmVzZXJ2ZWRfcmFuZ2UoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ucmVzZXJ2ZWRfcmFuZ2UpCisgIHJldHVybiByZXNlcnZlZF9yYW5nZV87Cit9CisKKy8vIHJlcGVhdGVkIHN0cmluZyByZXNlcnZlZF9uYW1lID0gMTA7CitpbmxpbmUgaW50IERlc2NyaXB0b3JQcm90bzo6cmVzZXJ2ZWRfbmFtZV9zaXplKCkgY29uc3QgeworICByZXR1cm4gcmVzZXJ2ZWRfbmFtZV8uc2l6ZSgpOworfQoraW5saW5lIHZvaWQgRGVzY3JpcHRvclByb3RvOjpjbGVhcl9yZXNlcnZlZF9uYW1lKCkgeworICByZXNlcnZlZF9uYW1lXy5DbGVhcigpOworfQoraW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIERlc2NyaXB0b3JQcm90bzo6cmVzZXJ2ZWRfbmFtZShpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLnJlc2VydmVkX25hbWUpCisgIHJldHVybiByZXNlcnZlZF9uYW1lXy5HZXQoaW5kZXgpOworfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIERlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9yZXNlcnZlZF9uYW1lKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLnJlc2VydmVkX25hbWUpCisgIHJldHVybiByZXNlcnZlZF9uYW1lXy5NdXRhYmxlKGluZGV4KTsKK30KK2lubGluZSB2b2lkIERlc2NyaXB0b3JQcm90bzo6c2V0X3Jlc2VydmVkX25hbWUoaW50IGluZGV4LCBjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ucmVzZXJ2ZWRfbmFtZSkKKyAgcmVzZXJ2ZWRfbmFtZV8uTXV0YWJsZShpbmRleCktPmFzc2lnbih2YWx1ZSk7Cit9CitpbmxpbmUgdm9pZCBEZXNjcmlwdG9yUHJvdG86OnNldF9yZXNlcnZlZF9uYW1lKGludCBpbmRleCwgY29uc3QgY2hhciogdmFsdWUpIHsKKyAgcmVzZXJ2ZWRfbmFtZV8uTXV0YWJsZShpbmRleCktPmFzc2lnbih2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLnJlc2VydmVkX25hbWUpCit9CitpbmxpbmUgdm9pZCBEZXNjcmlwdG9yUHJvdG86OnNldF9yZXNlcnZlZF9uYW1lKGludCBpbmRleCwgY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHJlc2VydmVkX25hbWVfLk11dGFibGUoaW5kZXgpLT5hc3NpZ24oCisgICAgcmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ucmVzZXJ2ZWRfbmFtZSkKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBEZXNjcmlwdG9yUHJvdG86OmFkZF9yZXNlcnZlZF9uYW1lKCkgeworICByZXR1cm4gcmVzZXJ2ZWRfbmFtZV8uQWRkKCk7Cit9CitpbmxpbmUgdm9pZCBEZXNjcmlwdG9yUHJvdG86OmFkZF9yZXNlcnZlZF9uYW1lKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHJlc2VydmVkX25hbWVfLkFkZCgpLT5hc3NpZ24odmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ucmVzZXJ2ZWRfbmFtZSkKK30KK2lubGluZSB2b2lkIERlc2NyaXB0b3JQcm90bzo6YWRkX3Jlc2VydmVkX25hbWUoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgcmVzZXJ2ZWRfbmFtZV8uQWRkKCktPmFzc2lnbih2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGRfY2hhcjpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLnJlc2VydmVkX25hbWUpCit9CitpbmxpbmUgdm9pZCBEZXNjcmlwdG9yUHJvdG86OmFkZF9yZXNlcnZlZF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICByZXNlcnZlZF9uYW1lXy5BZGQoKS0+YXNzaWduKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvLnJlc2VydmVkX25hbWUpCit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6OnN0ZDo6c3RyaW5nPiYKK0Rlc2NyaXB0b3JQcm90bzo6cmVzZXJ2ZWRfbmFtZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5yZXNlcnZlZF9uYW1lKQorICByZXR1cm4gcmVzZXJ2ZWRfbmFtZV87Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6OnN0ZDo6c3RyaW5nPioKK0Rlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9yZXNlcnZlZF9uYW1lKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8ucmVzZXJ2ZWRfbmFtZSkKKyAgcmV0dXJuICZyZXNlcnZlZF9uYW1lXzsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBGaWVsZERlc2NyaXB0b3JQcm90bworCisvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CitpbmxpbmUgYm9vbCBGaWVsZERlc2NyaXB0b3JQcm90bzo6aGFzX25hbWUoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDF1KSAhPSAwOworfQoraW5saW5lIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9oYXNfbmFtZSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAxdTsKK30KK2lubGluZSB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfbmFtZSgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMXU7Cit9CitpbmxpbmUgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfbmFtZSgpIHsKKyAgbmFtZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfbmFtZSgpOworfQoraW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEZpZWxkRGVzY3JpcHRvclByb3RvOjpuYW1lKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5uYW1lKQorICByZXR1cm4gbmFtZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9uYW1lKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfbmFtZSgpOworICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5uYW1lKQorfQoraW5saW5lIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfbmFtZSgpOworICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLm5hbWUpCit9CitpbmxpbmUgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6c2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHNldF9oYXNfbmFtZSgpOworICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBGaWVsZERlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9uYW1lKCkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLm5hbWUpCisgIHJldHVybiBuYW1lXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIEZpZWxkRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX25hbWUoKSB7CisgIGNsZWFyX2hhc19uYW1lKCk7CisgIHJldHVybiBuYW1lXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9hbGxvY2F0ZWRfbmFtZSg6OnN0ZDo6c3RyaW5nKiBuYW1lKSB7CisgIGlmIChuYW1lICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX25hbWUoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfbmFtZSgpOworICB9CisgIG5hbWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBuYW1lKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLm5hbWUpCit9CisKKy8vIG9wdGlvbmFsIGludDMyIG51bWJlciA9IDM7CitpbmxpbmUgYm9vbCBGaWVsZERlc2NyaXB0b3JQcm90bzo6aGFzX251bWJlcigpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMnUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19udW1iZXIoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMnU7Cit9CitpbmxpbmUgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX251bWJlcigpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMnU7Cit9CitpbmxpbmUgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfbnVtYmVyKCkgeworICBudW1iZXJfID0gMDsKKyAgY2xlYXJfaGFzX251bWJlcigpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgRmllbGREZXNjcmlwdG9yUHJvdG86Om51bWJlcigpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8ubnVtYmVyKQorICByZXR1cm4gbnVtYmVyXzsKK30KK2lubGluZSB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpzZXRfbnVtYmVyKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgdmFsdWUpIHsKKyAgc2V0X2hhc19udW1iZXIoKTsKKyAgbnVtYmVyXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5udW1iZXIpCit9CisKKy8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uTGFiZWwgbGFiZWwgPSA0OworaW5saW5lIGJvb2wgRmllbGREZXNjcmlwdG9yUHJvdG86Omhhc19sYWJlbCgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwNHUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19sYWJlbCgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDA0dTsKK30KK2lubGluZSB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfbGFiZWwoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDR1OworfQoraW5saW5lIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OmNsZWFyX2xhYmVsKCkgeworICBsYWJlbF8gPSAxOworICBjbGVhcl9oYXNfbGFiZWwoKTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvX0xhYmVsIEZpZWxkRGVzY3JpcHRvclByb3RvOjpsYWJlbCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8ubGFiZWwpCisgIHJldHVybiBzdGF0aWNfY2FzdDwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90b19MYWJlbCA+KGxhYmVsXyk7Cit9CitpbmxpbmUgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6c2V0X2xhYmVsKDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWwgdmFsdWUpIHsKKyAgYXNzZXJ0KDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWxfSXNWYWxpZCh2YWx1ZSkpOworICBzZXRfaGFzX2xhYmVsKCk7CisgIGxhYmVsXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5sYWJlbCkKK30KKworLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5UeXBlIHR5cGUgPSA1OworaW5saW5lIGJvb2wgRmllbGREZXNjcmlwdG9yUHJvdG86Omhhc190eXBlKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDA4dSkgIT0gMDsKK30KK2lubGluZSB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX3R5cGUoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwOHU7Cit9CitpbmxpbmUgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX3R5cGUoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDh1OworfQoraW5saW5lIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OmNsZWFyX3R5cGUoKSB7CisgIHR5cGVfID0gMTsKKyAgY2xlYXJfaGFzX3R5cGUoKTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGUgRmllbGREZXNjcmlwdG9yUHJvdG86OnR5cGUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLnR5cGUpCisgIHJldHVybiBzdGF0aWNfY2FzdDwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlID4odHlwZV8pOworfQoraW5saW5lIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF90eXBlKDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZSB2YWx1ZSkgeworICBhc3NlcnQoOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90b19UeXBlX0lzVmFsaWQodmFsdWUpKTsKKyAgc2V0X2hhc190eXBlKCk7CisgIHR5cGVfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLnR5cGUpCit9CisKKy8vIG9wdGlvbmFsIHN0cmluZyB0eXBlX25hbWUgPSA2OworaW5saW5lIGJvb2wgRmllbGREZXNjcmlwdG9yUHJvdG86Omhhc190eXBlX25hbWUoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMTB1KSAhPSAwOworfQoraW5saW5lIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9oYXNfdHlwZV9uYW1lKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMTB1OworfQoraW5saW5lIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OmNsZWFyX2hhc190eXBlX25hbWUoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMTB1OworfQoraW5saW5lIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OmNsZWFyX3R5cGVfbmFtZSgpIHsKKyAgdHlwZV9uYW1lXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGNsZWFyX2hhc190eXBlX25hbWUoKTsKK30KK2lubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBGaWVsZERlc2NyaXB0b3JQcm90bzo6dHlwZV9uYW1lKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by50eXBlX25hbWUpCisgIHJldHVybiB0eXBlX25hbWVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpzZXRfdHlwZV9uYW1lKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfdHlwZV9uYW1lKCk7CisgIHR5cGVfbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8udHlwZV9uYW1lKQorfQoraW5saW5lIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF90eXBlX25hbWUoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgc2V0X2hhc190eXBlX25hbWUoKTsKKyAgdHlwZV9uYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLnR5cGVfbmFtZSkKK30KK2lubGluZSB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpzZXRfdHlwZV9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX3R5cGVfbmFtZSgpOworICB0eXBlX25hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by50eXBlX25hbWUpCit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogRmllbGREZXNjcmlwdG9yUHJvdG86Om11dGFibGVfdHlwZV9uYW1lKCkgeworICBzZXRfaGFzX3R5cGVfbmFtZSgpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8udHlwZV9uYW1lKQorICByZXR1cm4gdHlwZV9uYW1lXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIEZpZWxkRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX3R5cGVfbmFtZSgpIHsKKyAgY2xlYXJfaGFzX3R5cGVfbmFtZSgpOworICByZXR1cm4gdHlwZV9uYW1lXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9hbGxvY2F0ZWRfdHlwZV9uYW1lKDo6c3RkOjpzdHJpbmcqIHR5cGVfbmFtZSkgeworICBpZiAodHlwZV9uYW1lICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX3R5cGVfbmFtZSgpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc190eXBlX25hbWUoKTsKKyAgfQorICB0eXBlX25hbWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB0eXBlX25hbWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8udHlwZV9uYW1lKQorfQorCisvLyBvcHRpb25hbCBzdHJpbmcgZXh0ZW5kZWUgPSAyOworaW5saW5lIGJvb2wgRmllbGREZXNjcmlwdG9yUHJvdG86Omhhc19leHRlbmRlZSgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAyMHUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19leHRlbmRlZSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDIwdTsKK30KK2lubGluZSB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfZXh0ZW5kZWUoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMjB1OworfQoraW5saW5lIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OmNsZWFyX2V4dGVuZGVlKCkgeworICBleHRlbmRlZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfZXh0ZW5kZWUoKTsKK30KK2lubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBGaWVsZERlc2NyaXB0b3JQcm90bzo6ZXh0ZW5kZWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLmV4dGVuZGVlKQorICByZXR1cm4gZXh0ZW5kZWVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpzZXRfZXh0ZW5kZWUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgc2V0X2hhc19leHRlbmRlZSgpOworICBleHRlbmRlZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uZXh0ZW5kZWUpCit9CitpbmxpbmUgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6c2V0X2V4dGVuZGVlKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfZXh0ZW5kZWUoKTsKKyAgZXh0ZW5kZWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uZXh0ZW5kZWUpCit9CitpbmxpbmUgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6c2V0X2V4dGVuZGVlKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX2V4dGVuZGVlKCk7CisgIGV4dGVuZGVlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uZXh0ZW5kZWUpCit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogRmllbGREZXNjcmlwdG9yUHJvdG86Om11dGFibGVfZXh0ZW5kZWUoKSB7CisgIHNldF9oYXNfZXh0ZW5kZWUoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLmV4dGVuZGVlKQorICByZXR1cm4gZXh0ZW5kZWVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogRmllbGREZXNjcmlwdG9yUHJvdG86OnJlbGVhc2VfZXh0ZW5kZWUoKSB7CisgIGNsZWFyX2hhc19leHRlbmRlZSgpOworICByZXR1cm4gZXh0ZW5kZWVfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6c2V0X2FsbG9jYXRlZF9leHRlbmRlZSg6OnN0ZDo6c3RyaW5nKiBleHRlbmRlZSkgeworICBpZiAoZXh0ZW5kZWUgIT0gTlVMTCkgeworICAgIHNldF9oYXNfZXh0ZW5kZWUoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfZXh0ZW5kZWUoKTsKKyAgfQorICBleHRlbmRlZV8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGV4dGVuZGVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLmV4dGVuZGVlKQorfQorCisvLyBvcHRpb25hbCBzdHJpbmcgZGVmYXVsdF92YWx1ZSA9IDc7CitpbmxpbmUgYm9vbCBGaWVsZERlc2NyaXB0b3JQcm90bzo6aGFzX2RlZmF1bHRfdmFsdWUoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwNDB1KSAhPSAwOworfQoraW5saW5lIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9oYXNfZGVmYXVsdF92YWx1ZSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDQwdTsKK30KK2lubGluZSB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfZGVmYXVsdF92YWx1ZSgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDA0MHU7Cit9CitpbmxpbmUgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfZGVmYXVsdF92YWx1ZSgpIHsKKyAgZGVmYXVsdF92YWx1ZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfZGVmYXVsdF92YWx1ZSgpOworfQoraW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEZpZWxkRGVzY3JpcHRvclByb3RvOjpkZWZhdWx0X3ZhbHVlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5kZWZhdWx0X3ZhbHVlKQorICByZXR1cm4gZGVmYXVsdF92YWx1ZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9kZWZhdWx0X3ZhbHVlKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfZGVmYXVsdF92YWx1ZSgpOworICBkZWZhdWx0X3ZhbHVlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5kZWZhdWx0X3ZhbHVlKQorfQoraW5saW5lIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9kZWZhdWx0X3ZhbHVlKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfZGVmYXVsdF92YWx1ZSgpOworICBkZWZhdWx0X3ZhbHVlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLmRlZmF1bHRfdmFsdWUpCit9CitpbmxpbmUgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6c2V0X2RlZmF1bHRfdmFsdWUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHNldF9oYXNfZGVmYXVsdF92YWx1ZSgpOworICBkZWZhdWx0X3ZhbHVlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uZGVmYXVsdF92YWx1ZSkKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBGaWVsZERlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9kZWZhdWx0X3ZhbHVlKCkgeworICBzZXRfaGFzX2RlZmF1bHRfdmFsdWUoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLmRlZmF1bHRfdmFsdWUpCisgIHJldHVybiBkZWZhdWx0X3ZhbHVlXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIEZpZWxkRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX2RlZmF1bHRfdmFsdWUoKSB7CisgIGNsZWFyX2hhc19kZWZhdWx0X3ZhbHVlKCk7CisgIHJldHVybiBkZWZhdWx0X3ZhbHVlXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9hbGxvY2F0ZWRfZGVmYXVsdF92YWx1ZSg6OnN0ZDo6c3RyaW5nKiBkZWZhdWx0X3ZhbHVlKSB7CisgIGlmIChkZWZhdWx0X3ZhbHVlICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX2RlZmF1bHRfdmFsdWUoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfZGVmYXVsdF92YWx1ZSgpOworICB9CisgIGRlZmF1bHRfdmFsdWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBkZWZhdWx0X3ZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLmRlZmF1bHRfdmFsdWUpCit9CisKKy8vIG9wdGlvbmFsIGludDMyIG9uZW9mX2luZGV4ID0gOTsKK2lubGluZSBib29sIEZpZWxkRGVzY3JpcHRvclByb3RvOjpoYXNfb25lb2ZfaW5kZXgoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwODB1KSAhPSAwOworfQoraW5saW5lIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9oYXNfb25lb2ZfaW5kZXgoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDA4MHU7Cit9CitpbmxpbmUgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX29uZW9mX2luZGV4KCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDgwdTsKK30KK2lubGluZSB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpjbGVhcl9vbmVvZl9pbmRleCgpIHsKKyAgb25lb2ZfaW5kZXhfID0gMDsKKyAgY2xlYXJfaGFzX29uZW9mX2luZGV4KCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiBGaWVsZERlc2NyaXB0b3JQcm90bzo6b25lb2ZfaW5kZXgoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLm9uZW9mX2luZGV4KQorICByZXR1cm4gb25lb2ZfaW5kZXhfOworfQoraW5saW5lIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9vbmVvZl9pbmRleCg6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKSB7CisgIHNldF9oYXNfb25lb2ZfaW5kZXgoKTsKKyAgb25lb2ZfaW5kZXhfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLm9uZW9mX2luZGV4KQorfQorCisvLyBvcHRpb25hbCBzdHJpbmcganNvbl9uYW1lID0gMTA7CitpbmxpbmUgYm9vbCBGaWVsZERlc2NyaXB0b3JQcm90bzo6aGFzX2pzb25fbmFtZSgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDEwMHUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19qc29uX25hbWUoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDEwMHU7Cit9CitpbmxpbmUgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX2pzb25fbmFtZSgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDEwMHU7Cit9CitpbmxpbmUgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfanNvbl9uYW1lKCkgeworICBqc29uX25hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX2pzb25fbmFtZSgpOworfQoraW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEZpZWxkRGVzY3JpcHRvclByb3RvOjpqc29uX25hbWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLmpzb25fbmFtZSkKKyAgcmV0dXJuIGpzb25fbmFtZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9qc29uX25hbWUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgc2V0X2hhc19qc29uX25hbWUoKTsKKyAganNvbl9uYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5qc29uX25hbWUpCit9CitpbmxpbmUgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6c2V0X2pzb25fbmFtZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX2pzb25fbmFtZSgpOworICBqc29uX25hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uanNvbl9uYW1lKQorfQoraW5saW5lIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OnNldF9qc29uX25hbWUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHNldF9oYXNfanNvbl9uYW1lKCk7CisgIGpzb25fbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLmpzb25fbmFtZSkKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBGaWVsZERlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9qc29uX25hbWUoKSB7CisgIHNldF9oYXNfanNvbl9uYW1lKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5qc29uX25hbWUpCisgIHJldHVybiBqc29uX25hbWVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogRmllbGREZXNjcmlwdG9yUHJvdG86OnJlbGVhc2VfanNvbl9uYW1lKCkgeworICBjbGVhcl9oYXNfanNvbl9uYW1lKCk7CisgIHJldHVybiBqc29uX25hbWVfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6c2V0X2FsbG9jYXRlZF9qc29uX25hbWUoOjpzdGQ6OnN0cmluZyoganNvbl9uYW1lKSB7CisgIGlmIChqc29uX25hbWUgIT0gTlVMTCkgeworICAgIHNldF9oYXNfanNvbl9uYW1lKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX2pzb25fbmFtZSgpOworICB9CisgIGpzb25fbmFtZV8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGpzb25fbmFtZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5qc29uX25hbWUpCit9CisKKy8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zIG9wdGlvbnMgPSA4OworaW5saW5lIGJvb2wgRmllbGREZXNjcmlwdG9yUHJvdG86Omhhc19vcHRpb25zKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMjAwdSkgIT0gMDsKK30KK2lubGluZSB2b2lkIEZpZWxkRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX29wdGlvbnMoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDIwMHU7Cit9CitpbmxpbmUgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX29wdGlvbnMoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAyMDB1OworfQoraW5saW5lIHZvaWQgRmllbGREZXNjcmlwdG9yUHJvdG86OmNsZWFyX29wdGlvbnMoKSB7CisgIGlmIChvcHRpb25zXyAhPSBOVUxMKSBvcHRpb25zXy0+Ojpnb29nbGU6OnByb3RvYnVmOjpGaWVsZE9wdGlvbnM6OkNsZWFyKCk7CisgIGNsZWFyX2hhc19vcHRpb25zKCk7Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZE9wdGlvbnMmIEZpZWxkRGVzY3JpcHRvclByb3RvOjpvcHRpb25zKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5vcHRpb25zKQorICByZXR1cm4gb3B0aW9uc18gIT0gTlVMTCA/ICpvcHRpb25zXyA6ICpkZWZhdWx0X2luc3RhbmNlXy0+b3B0aW9uc187Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZE9wdGlvbnMqIEZpZWxkRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX29wdGlvbnMoKSB7CisgIHNldF9oYXNfb3B0aW9ucygpOworICBpZiAob3B0aW9uc18gPT0gTlVMTCkgeworICAgIG9wdGlvbnNfID0gbmV3IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGRPcHRpb25zOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5vcHRpb25zKQorICByZXR1cm4gb3B0aW9uc187Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZE9wdGlvbnMqIEZpZWxkRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX29wdGlvbnMoKSB7CisgIGNsZWFyX2hhc19vcHRpb25zKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGRPcHRpb25zKiB0ZW1wID0gb3B0aW9uc187CisgIG9wdGlvbnNfID0gTlVMTDsKKyAgcmV0dXJuIHRlbXA7Cit9CitpbmxpbmUgdm9pZCBGaWVsZERlc2NyaXB0b3JQcm90bzo6c2V0X2FsbG9jYXRlZF9vcHRpb25zKDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGRPcHRpb25zKiBvcHRpb25zKSB7CisgIGRlbGV0ZSBvcHRpb25zXzsKKyAgb3B0aW9uc18gPSBvcHRpb25zOworICBpZiAob3B0aW9ucykgeworICAgIHNldF9oYXNfb3B0aW9ucygpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19vcHRpb25zKCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLm9wdGlvbnMpCit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gT25lb2ZEZXNjcmlwdG9yUHJvdG8KKworLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworaW5saW5lIGJvb2wgT25lb2ZEZXNjcmlwdG9yUHJvdG86Omhhc19uYW1lKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAxdSkgIT0gMDsKK30KK2lubGluZSB2b2lkIE9uZW9mRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX25hbWUoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMXU7Cit9CitpbmxpbmUgdm9pZCBPbmVvZkRlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX25hbWUoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDF1OworfQoraW5saW5lIHZvaWQgT25lb2ZEZXNjcmlwdG9yUHJvdG86OmNsZWFyX25hbWUoKSB7CisgIG5hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX25hbWUoKTsKK30KK2lubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBPbmVvZkRlc2NyaXB0b3JQcm90bzo6bmFtZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuT25lb2ZEZXNjcmlwdG9yUHJvdG8ubmFtZSkKKyAgcmV0dXJuIG5hbWVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIE9uZW9mRGVzY3JpcHRvclByb3RvOjpzZXRfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuT25lb2ZEZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KK2lubGluZSB2b2lkIE9uZW9mRGVzY3JpcHRvclByb3RvOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5PbmVvZkRlc2NyaXB0b3JQcm90by5uYW1lKQorfQoraW5saW5lIHZvaWQgT25lb2ZEZXNjcmlwdG9yUHJvdG86OnNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLk9uZW9mRGVzY3JpcHRvclByb3RvLm5hbWUpCit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogT25lb2ZEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfbmFtZSgpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5PbmVvZkRlc2NyaXB0b3JQcm90by5uYW1lKQorICByZXR1cm4gbmFtZV8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBPbmVvZkRlc2NyaXB0b3JQcm90bzo6cmVsZWFzZV9uYW1lKCkgeworICBjbGVhcl9oYXNfbmFtZSgpOworICByZXR1cm4gbmFtZV8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIE9uZW9mRGVzY3JpcHRvclByb3RvOjpzZXRfYWxsb2NhdGVkX25hbWUoOjpzdGQ6OnN0cmluZyogbmFtZSkgeworICBpZiAobmFtZSAhPSBOVUxMKSB7CisgICAgc2V0X2hhc19uYW1lKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX25hbWUoKTsKKyAgfQorICBuYW1lXy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgbmFtZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5PbmVvZkRlc2NyaXB0b3JQcm90by5uYW1lKQorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIEVudW1EZXNjcmlwdG9yUHJvdG8KKworLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworaW5saW5lIGJvb2wgRW51bURlc2NyaXB0b3JQcm90bzo6aGFzX25hbWUoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDF1KSAhPSAwOworfQoraW5saW5lIHZvaWQgRW51bURlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19uYW1lKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDF1OworfQoraW5saW5lIHZvaWQgRW51bURlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX25hbWUoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDF1OworfQoraW5saW5lIHZvaWQgRW51bURlc2NyaXB0b3JQcm90bzo6Y2xlYXJfbmFtZSgpIHsKKyAgbmFtZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfbmFtZSgpOworfQoraW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEVudW1EZXNjcmlwdG9yUHJvdG86Om5hbWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8ubmFtZSkKKyAgcmV0dXJuIG5hbWVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIEVudW1EZXNjcmlwdG9yUHJvdG86OnNldF9uYW1lKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfbmFtZSgpOworICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvLm5hbWUpCit9CitpbmxpbmUgdm9pZCBFbnVtRGVzY3JpcHRvclByb3RvOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvLm5hbWUpCit9CitpbmxpbmUgdm9pZCBFbnVtRGVzY3JpcHRvclByb3RvOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvLm5hbWUpCit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogRW51bURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9uYW1lKCkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8ubmFtZSkKKyAgcmV0dXJuIG5hbWVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogRW51bURlc2NyaXB0b3JQcm90bzo6cmVsZWFzZV9uYW1lKCkgeworICBjbGVhcl9oYXNfbmFtZSgpOworICByZXR1cm4gbmFtZV8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIEVudW1EZXNjcmlwdG9yUHJvdG86OnNldF9hbGxvY2F0ZWRfbmFtZSg6OnN0ZDo6c3RyaW5nKiBuYW1lKSB7CisgIGlmIChuYW1lICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX25hbWUoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfbmFtZSgpOworICB9CisgIG5hbWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBuYW1lKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8gdmFsdWUgPSAyOworaW5saW5lIGludCBFbnVtRGVzY3JpcHRvclByb3RvOjp2YWx1ZV9zaXplKCkgY29uc3QgeworICByZXR1cm4gdmFsdWVfLnNpemUoKTsKK30KK2lubGluZSB2b2lkIEVudW1EZXNjcmlwdG9yUHJvdG86OmNsZWFyX3ZhbHVlKCkgeworICB2YWx1ZV8uQ2xlYXIoKTsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZURlc2NyaXB0b3JQcm90byYgRW51bURlc2NyaXB0b3JQcm90bzo6dmFsdWUoaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8udmFsdWUpCisgIHJldHVybiB2YWx1ZV8uR2V0KGluZGV4KTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZURlc2NyaXB0b3JQcm90byogRW51bURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV92YWx1ZShpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8udmFsdWUpCisgIHJldHVybiB2YWx1ZV8uTXV0YWJsZShpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8qIEVudW1EZXNjcmlwdG9yUHJvdG86OmFkZF92YWx1ZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuRW51bURlc2NyaXB0b3JQcm90by52YWx1ZSkKKyAgcmV0dXJuIHZhbHVlXy5BZGQoKTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlRGVzY3JpcHRvclByb3RvID4qCitFbnVtRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX3ZhbHVlKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvLnZhbHVlKQorICByZXR1cm4gJnZhbHVlXzsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlRGVzY3JpcHRvclByb3RvID4mCitFbnVtRGVzY3JpcHRvclByb3RvOjp2YWx1ZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8udmFsdWUpCisgIHJldHVybiB2YWx1ZV87Cit9CisKKy8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnMgb3B0aW9ucyA9IDM7CitpbmxpbmUgYm9vbCBFbnVtRGVzY3JpcHRvclByb3RvOjpoYXNfb3B0aW9ucygpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwNHUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBFbnVtRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX29wdGlvbnMoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwNHU7Cit9CitpbmxpbmUgdm9pZCBFbnVtRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfb3B0aW9ucygpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwNHU7Cit9CitpbmxpbmUgdm9pZCBFbnVtRGVzY3JpcHRvclByb3RvOjpjbGVhcl9vcHRpb25zKCkgeworICBpZiAob3B0aW9uc18gIT0gTlVMTCkgb3B0aW9uc18tPjo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bU9wdGlvbnM6OkNsZWFyKCk7CisgIGNsZWFyX2hhc19vcHRpb25zKCk7Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtT3B0aW9ucyYgRW51bURlc2NyaXB0b3JQcm90bzo6b3B0aW9ucygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRW51bURlc2NyaXB0b3JQcm90by5vcHRpb25zKQorICByZXR1cm4gb3B0aW9uc18gIT0gTlVMTCA/ICpvcHRpb25zXyA6ICpkZWZhdWx0X2luc3RhbmNlXy0+b3B0aW9uc187Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtT3B0aW9ucyogRW51bURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9vcHRpb25zKCkgeworICBzZXRfaGFzX29wdGlvbnMoKTsKKyAgaWYgKG9wdGlvbnNfID09IE5VTEwpIHsKKyAgICBvcHRpb25zXyA9IG5ldyA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1PcHRpb25zOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvLm9wdGlvbnMpCisgIHJldHVybiBvcHRpb25zXzsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1PcHRpb25zKiBFbnVtRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX29wdGlvbnMoKSB7CisgIGNsZWFyX2hhc19vcHRpb25zKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bU9wdGlvbnMqIHRlbXAgPSBvcHRpb25zXzsKKyAgb3B0aW9uc18gPSBOVUxMOworICByZXR1cm4gdGVtcDsKK30KK2lubGluZSB2b2lkIEVudW1EZXNjcmlwdG9yUHJvdG86OnNldF9hbGxvY2F0ZWRfb3B0aW9ucyg6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1PcHRpb25zKiBvcHRpb25zKSB7CisgIGRlbGV0ZSBvcHRpb25zXzsKKyAgb3B0aW9uc18gPSBvcHRpb25zOworICBpZiAob3B0aW9ucykgeworICAgIHNldF9oYXNfb3B0aW9ucygpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19vcHRpb25zKCk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8ub3B0aW9ucykKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8KKworLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworaW5saW5lIGJvb2wgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpoYXNfbmFtZSgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMXUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86OnNldF9oYXNfbmFtZSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAxdTsKK30KK2lubGluZSB2b2lkIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX25hbWUoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDF1OworfQoraW5saW5lIHZvaWQgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9uYW1lKCkgeworICBuYW1lXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGNsZWFyX2hhc19uYW1lKCk7Cit9CitpbmxpbmUgY29uc3QgOjpzdGQ6OnN0cmluZyYgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpuYW1lKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8ubmFtZSkKKyAgcmV0dXJuIG5hbWVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6c2V0X25hbWUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZURlc2NyaXB0b3JQcm90by5uYW1lKQorfQoraW5saW5lIHZvaWQgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KK2lubGluZSB2b2lkIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6c2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHNldF9oYXNfbmFtZSgpOworICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlRGVzY3JpcHRvclByb3RvLm5hbWUpCit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX25hbWUoKSB7CisgIHNldF9oYXNfbmFtZSgpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlRGVzY3JpcHRvclByb3RvLm5hbWUpCisgIHJldHVybiBuYW1lXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6cmVsZWFzZV9uYW1lKCkgeworICBjbGVhcl9oYXNfbmFtZSgpOworICByZXR1cm4gbmFtZV8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6c2V0X2FsbG9jYXRlZF9uYW1lKDo6c3RkOjpzdHJpbmcqIG5hbWUpIHsKKyAgaWYgKG5hbWUgIT0gTlVMTCkgeworICAgIHNldF9oYXNfbmFtZSgpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19uYW1lKCk7CisgIH0KKyAgbmFtZV8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIG5hbWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlRGVzY3JpcHRvclByb3RvLm5hbWUpCit9CisKKy8vIG9wdGlvbmFsIGludDMyIG51bWJlciA9IDI7CitpbmxpbmUgYm9vbCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86Omhhc19udW1iZXIoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDJ1KSAhPSAwOworfQoraW5saW5lIHZvaWQgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX251bWJlcigpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAydTsKK30KK2lubGluZSB2b2lkIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX251bWJlcigpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMnU7Cit9CitpbmxpbmUgdm9pZCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86OmNsZWFyX251bWJlcigpIHsKKyAgbnVtYmVyXyA9IDA7CisgIGNsZWFyX2hhc19udW1iZXIoKTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6bnVtYmVyKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8ubnVtYmVyKQorICByZXR1cm4gbnVtYmVyXzsKK30KK2lubGluZSB2b2lkIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6c2V0X251bWJlcig6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKSB7CisgIHNldF9oYXNfbnVtYmVyKCk7CisgIG51bWJlcl8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlRGVzY3JpcHRvclByb3RvLm51bWJlcikKK30KKworLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVPcHRpb25zIG9wdGlvbnMgPSAzOworaW5saW5lIGJvb2wgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpoYXNfb3B0aW9ucygpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwNHUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86OnNldF9oYXNfb3B0aW9ucygpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDA0dTsKK30KK2lubGluZSB2b2lkIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX29wdGlvbnMoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDR1OworfQoraW5saW5lIHZvaWQgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9vcHRpb25zKCkgeworICBpZiAob3B0aW9uc18gIT0gTlVMTCkgb3B0aW9uc18tPjo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlT3B0aW9uczo6Q2xlYXIoKTsKKyAgY2xlYXJfaGFzX29wdGlvbnMoKTsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZU9wdGlvbnMmIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6b3B0aW9ucygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlRGVzY3JpcHRvclByb3RvLm9wdGlvbnMpCisgIHJldHVybiBvcHRpb25zXyAhPSBOVUxMID8gKm9wdGlvbnNfIDogKmRlZmF1bHRfaW5zdGFuY2VfLT5vcHRpb25zXzsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZU9wdGlvbnMqIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9vcHRpb25zKCkgeworICBzZXRfaGFzX29wdGlvbnMoKTsKKyAgaWYgKG9wdGlvbnNfID09IE5VTEwpIHsKKyAgICBvcHRpb25zXyA9IG5ldyA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZU9wdGlvbnM7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZURlc2NyaXB0b3JQcm90by5vcHRpb25zKQorICByZXR1cm4gb3B0aW9uc187Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtVmFsdWVPcHRpb25zKiBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86OnJlbGVhc2Vfb3B0aW9ucygpIHsKKyAgY2xlYXJfaGFzX29wdGlvbnMoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtVmFsdWVPcHRpb25zKiB0ZW1wID0gb3B0aW9uc187CisgIG9wdGlvbnNfID0gTlVMTDsKKyAgcmV0dXJuIHRlbXA7Cit9CitpbmxpbmUgdm9pZCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG86OnNldF9hbGxvY2F0ZWRfb3B0aW9ucyg6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZU9wdGlvbnMqIG9wdGlvbnMpIHsKKyAgZGVsZXRlIG9wdGlvbnNfOworICBvcHRpb25zXyA9IG9wdGlvbnM7CisgIGlmIChvcHRpb25zKSB7CisgICAgc2V0X2hhc19vcHRpb25zKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX29wdGlvbnMoKTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlRGVzY3JpcHRvclByb3RvLm9wdGlvbnMpCit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gU2VydmljZURlc2NyaXB0b3JQcm90bworCisvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CitpbmxpbmUgYm9vbCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpoYXNfbmFtZSgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMXUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX25hbWUoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMXU7Cit9CitpbmxpbmUgdm9pZCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfbmFtZSgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMXU7Cit9CitpbmxpbmUgdm9pZCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpjbGVhcl9uYW1lKCkgeworICBuYW1lXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGNsZWFyX2hhc19uYW1lKCk7Cit9CitpbmxpbmUgY29uc3QgOjpzdGQ6OnN0cmluZyYgU2VydmljZURlc2NyaXB0b3JQcm90bzo6bmFtZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuU2VydmljZURlc2NyaXB0b3JQcm90by5uYW1lKQorICByZXR1cm4gbmFtZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgU2VydmljZURlc2NyaXB0b3JQcm90bzo6c2V0X25hbWUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KK2lubGluZSB2b2lkIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86OnNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfbmFtZSgpOworICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KK2lubGluZSB2b2lkIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86OnNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX25hbWUoKSB7CisgIHNldF9oYXNfbmFtZSgpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuU2VydmljZURlc2NyaXB0b3JQcm90by5uYW1lKQorICByZXR1cm4gbmFtZV8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX25hbWUoKSB7CisgIGNsZWFyX2hhc19uYW1lKCk7CisgIHJldHVybiBuYW1lXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgU2VydmljZURlc2NyaXB0b3JQcm90bzo6c2V0X2FsbG9jYXRlZF9uYW1lKDo6c3RkOjpzdHJpbmcqIG5hbWUpIHsKKyAgaWYgKG5hbWUgIT0gTlVMTCkgeworICAgIHNldF9oYXNfbmFtZSgpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19uYW1lKCk7CisgIH0KKyAgbmFtZV8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIG5hbWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuU2VydmljZURlc2NyaXB0b3JQcm90by5uYW1lKQorfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90byBtZXRob2QgPSAyOworaW5saW5lIGludCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjptZXRob2Rfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIG1ldGhvZF8uc2l6ZSgpOworfQoraW5saW5lIHZvaWQgU2VydmljZURlc2NyaXB0b3JQcm90bzo6Y2xlYXJfbWV0aG9kKCkgeworICBtZXRob2RfLkNsZWFyKCk7Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRob2REZXNjcmlwdG9yUHJvdG8mIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86Om1ldGhvZChpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuU2VydmljZURlc2NyaXB0b3JQcm90by5tZXRob2QpCisgIHJldHVybiBtZXRob2RfLkdldChpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRob2REZXNjcmlwdG9yUHJvdG8qIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfbWV0aG9kKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuU2VydmljZURlc2NyaXB0b3JQcm90by5tZXRob2QpCisgIHJldHVybiBtZXRob2RfLk11dGFibGUoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0aG9kRGVzY3JpcHRvclByb3RvKiBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjphZGRfbWV0aG9kKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvLm1ldGhvZCkKKyAgcmV0dXJuIG1ldGhvZF8uQWRkKCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGhvZERlc2NyaXB0b3JQcm90byA+KgorU2VydmljZURlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9tZXRob2QoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8ubWV0aG9kKQorICByZXR1cm4gJm1ldGhvZF87Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGhvZERlc2NyaXB0b3JQcm90byA+JgorU2VydmljZURlc2NyaXB0b3JQcm90bzo6bWV0aG9kKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuU2VydmljZURlc2NyaXB0b3JQcm90by5tZXRob2QpCisgIHJldHVybiBtZXRob2RfOworfQorCisvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zIG9wdGlvbnMgPSAzOworaW5saW5lIGJvb2wgU2VydmljZURlc2NyaXB0b3JQcm90bzo6aGFzX29wdGlvbnMoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDR1KSAhPSAwOworfQoraW5saW5lIHZvaWQgU2VydmljZURlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19vcHRpb25zKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDR1OworfQoraW5saW5lIHZvaWQgU2VydmljZURlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX29wdGlvbnMoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDR1OworfQoraW5saW5lIHZvaWQgU2VydmljZURlc2NyaXB0b3JQcm90bzo6Y2xlYXJfb3B0aW9ucygpIHsKKyAgaWYgKG9wdGlvbnNfICE9IE5VTEwpIG9wdGlvbnNfLT46Omdvb2dsZTo6cHJvdG9idWY6OlNlcnZpY2VPcHRpb25zOjpDbGVhcigpOworICBjbGVhcl9oYXNfb3B0aW9ucygpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6U2VydmljZU9wdGlvbnMmIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86Om9wdGlvbnMoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8ub3B0aW9ucykKKyAgcmV0dXJuIG9wdGlvbnNfICE9IE5VTEwgPyAqb3B0aW9uc18gOiAqZGVmYXVsdF9pbnN0YW5jZV8tPm9wdGlvbnNfOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6U2VydmljZU9wdGlvbnMqIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG86Om11dGFibGVfb3B0aW9ucygpIHsKKyAgc2V0X2hhc19vcHRpb25zKCk7CisgIGlmIChvcHRpb25zXyA9PSBOVUxMKSB7CisgICAgb3B0aW9uc18gPSBuZXcgOjpnb29nbGU6OnByb3RvYnVmOjpTZXJ2aWNlT3B0aW9uczsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuU2VydmljZURlc2NyaXB0b3JQcm90by5vcHRpb25zKQorICByZXR1cm4gb3B0aW9uc187Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpTZXJ2aWNlT3B0aW9ucyogU2VydmljZURlc2NyaXB0b3JQcm90bzo6cmVsZWFzZV9vcHRpb25zKCkgeworICBjbGVhcl9oYXNfb3B0aW9ucygpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlNlcnZpY2VPcHRpb25zKiB0ZW1wID0gb3B0aW9uc187CisgIG9wdGlvbnNfID0gTlVMTDsKKyAgcmV0dXJuIHRlbXA7Cit9CitpbmxpbmUgdm9pZCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvOjpzZXRfYWxsb2NhdGVkX29wdGlvbnMoOjpnb29nbGU6OnByb3RvYnVmOjpTZXJ2aWNlT3B0aW9ucyogb3B0aW9ucykgeworICBkZWxldGUgb3B0aW9uc187CisgIG9wdGlvbnNfID0gb3B0aW9uczsKKyAgaWYgKG9wdGlvbnMpIHsKKyAgICBzZXRfaGFzX29wdGlvbnMoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfb3B0aW9ucygpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvLm9wdGlvbnMpCit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gTWV0aG9kRGVzY3JpcHRvclByb3RvCisKKy8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKK2lubGluZSBib29sIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6aGFzX25hbWUoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDF1KSAhPSAwOworfQoraW5saW5lIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX25hbWUoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMXU7Cit9CitpbmxpbmUgdm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OmNsZWFyX2hhc19uYW1lKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAxdTsKK30KK2lubGluZSB2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfbmFtZSgpIHsKKyAgbmFtZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfbmFtZSgpOworfQoraW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6bmFtZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvLm5hbWUpCisgIHJldHVybiBuYW1lXy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OnNldF9uYW1lKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfbmFtZSgpOworICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8ubmFtZSkKK30KK2lubGluZSB2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6c2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgc2V0X2hhc19uYW1lKCk7CisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvLm5hbWUpCit9CitpbmxpbmUgdm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OnNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90by5uYW1lKQorfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9uYW1lKCkgeworICBzZXRfaGFzX25hbWUoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90by5uYW1lKQorICByZXR1cm4gbmFtZV8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBNZXRob2REZXNjcmlwdG9yUHJvdG86OnJlbGVhc2VfbmFtZSgpIHsKKyAgY2xlYXJfaGFzX25hbWUoKTsKKyAgcmV0dXJuIG5hbWVfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OnNldF9hbGxvY2F0ZWRfbmFtZSg6OnN0ZDo6c3RyaW5nKiBuYW1lKSB7CisgIGlmIChuYW1lICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX25hbWUoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfbmFtZSgpOworICB9CisgIG5hbWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBuYW1lKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90by5uYW1lKQorfQorCisvLyBvcHRpb25hbCBzdHJpbmcgaW5wdXRfdHlwZSA9IDI7CitpbmxpbmUgYm9vbCBNZXRob2REZXNjcmlwdG9yUHJvdG86Omhhc19pbnB1dF90eXBlKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAydSkgIT0gMDsKK30KK2lubGluZSB2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19pbnB1dF90eXBlKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDJ1OworfQoraW5saW5lIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfaW5wdXRfdHlwZSgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMnU7Cit9CitpbmxpbmUgdm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OmNsZWFyX2lucHV0X3R5cGUoKSB7CisgIGlucHV0X3R5cGVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX2lucHV0X3R5cGUoKTsKK30KK2lubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBNZXRob2REZXNjcmlwdG9yUHJvdG86OmlucHV0X3R5cGUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90by5pbnB1dF90eXBlKQorICByZXR1cm4gaW5wdXRfdHlwZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpzZXRfaW5wdXRfdHlwZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBzZXRfaGFzX2lucHV0X3R5cGUoKTsKKyAgaW5wdXRfdHlwZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvLmlucHV0X3R5cGUpCit9CitpbmxpbmUgdm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OnNldF9pbnB1dF90eXBlKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfaW5wdXRfdHlwZSgpOworICBpbnB1dF90eXBlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90by5pbnB1dF90eXBlKQorfQoraW5saW5lIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpzZXRfaW5wdXRfdHlwZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19pbnB1dF90eXBlKCk7CisgIGlucHV0X3R5cGVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8uaW5wdXRfdHlwZSkKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBNZXRob2REZXNjcmlwdG9yUHJvdG86Om11dGFibGVfaW5wdXRfdHlwZSgpIHsKKyAgc2V0X2hhc19pbnB1dF90eXBlKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8uaW5wdXRfdHlwZSkKKyAgcmV0dXJuIGlucHV0X3R5cGVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogTWV0aG9kRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX2lucHV0X3R5cGUoKSB7CisgIGNsZWFyX2hhc19pbnB1dF90eXBlKCk7CisgIHJldHVybiBpbnB1dF90eXBlXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpzZXRfYWxsb2NhdGVkX2lucHV0X3R5cGUoOjpzdGQ6OnN0cmluZyogaW5wdXRfdHlwZSkgeworICBpZiAoaW5wdXRfdHlwZSAhPSBOVUxMKSB7CisgICAgc2V0X2hhc19pbnB1dF90eXBlKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX2lucHV0X3R5cGUoKTsKKyAgfQorICBpbnB1dF90eXBlXy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgaW5wdXRfdHlwZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8uaW5wdXRfdHlwZSkKK30KKworLy8gb3B0aW9uYWwgc3RyaW5nIG91dHB1dF90eXBlID0gMzsKK2lubGluZSBib29sIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6aGFzX291dHB1dF90eXBlKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDA0dSkgIT0gMDsKK30KK2lubGluZSB2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19vdXRwdXRfdHlwZSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDA0dTsKK30KK2lubGluZSB2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfaGFzX291dHB1dF90eXBlKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDA0dTsKK30KK2lubGluZSB2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfb3V0cHV0X3R5cGUoKSB7CisgIG91dHB1dF90eXBlXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGNsZWFyX2hhc19vdXRwdXRfdHlwZSgpOworfQoraW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6b3V0cHV0X3R5cGUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90by5vdXRwdXRfdHlwZSkKKyAgcmV0dXJuIG91dHB1dF90eXBlXy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OnNldF9vdXRwdXRfdHlwZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBzZXRfaGFzX291dHB1dF90eXBlKCk7CisgIG91dHB1dF90eXBlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8ub3V0cHV0X3R5cGUpCit9CitpbmxpbmUgdm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OnNldF9vdXRwdXRfdHlwZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX291dHB1dF90eXBlKCk7CisgIG91dHB1dF90eXBlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90by5vdXRwdXRfdHlwZSkKK30KK2lubGluZSB2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6c2V0X291dHB1dF90eXBlKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX291dHB1dF90eXBlKCk7CisgIG91dHB1dF90eXBlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvLm91dHB1dF90eXBlKQorfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6bXV0YWJsZV9vdXRwdXRfdHlwZSgpIHsKKyAgc2V0X2hhc19vdXRwdXRfdHlwZSgpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvLm91dHB1dF90eXBlKQorICByZXR1cm4gb3V0cHV0X3R5cGVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogTWV0aG9kRGVzY3JpcHRvclByb3RvOjpyZWxlYXNlX291dHB1dF90eXBlKCkgeworICBjbGVhcl9oYXNfb3V0cHV0X3R5cGUoKTsKKyAgcmV0dXJuIG91dHB1dF90eXBlXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpzZXRfYWxsb2NhdGVkX291dHB1dF90eXBlKDo6c3RkOjpzdHJpbmcqIG91dHB1dF90eXBlKSB7CisgIGlmIChvdXRwdXRfdHlwZSAhPSBOVUxMKSB7CisgICAgc2V0X2hhc19vdXRwdXRfdHlwZSgpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19vdXRwdXRfdHlwZSgpOworICB9CisgIG91dHB1dF90eXBlXy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgb3V0cHV0X3R5cGUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvLm91dHB1dF90eXBlKQorfQorCisvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMgb3B0aW9ucyA9IDQ7CitpbmxpbmUgYm9vbCBNZXRob2REZXNjcmlwdG9yUHJvdG86Omhhc19vcHRpb25zKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDA4dSkgIT0gMDsKK30KK2lubGluZSB2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19vcHRpb25zKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDh1OworfQoraW5saW5lIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfb3B0aW9ucygpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwOHU7Cit9CitpbmxpbmUgdm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OmNsZWFyX29wdGlvbnMoKSB7CisgIGlmIChvcHRpb25zXyAhPSBOVUxMKSBvcHRpb25zXy0+Ojpnb29nbGU6OnByb3RvYnVmOjpNZXRob2RPcHRpb25zOjpDbGVhcigpOworICBjbGVhcl9oYXNfb3B0aW9ucygpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0aG9kT3B0aW9ucyYgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpvcHRpb25zKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8ub3B0aW9ucykKKyAgcmV0dXJuIG9wdGlvbnNfICE9IE5VTEwgPyAqb3B0aW9uc18gOiAqZGVmYXVsdF9pbnN0YW5jZV8tPm9wdGlvbnNfOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0aG9kT3B0aW9ucyogTWV0aG9kRGVzY3JpcHRvclByb3RvOjptdXRhYmxlX29wdGlvbnMoKSB7CisgIHNldF9oYXNfb3B0aW9ucygpOworICBpZiAob3B0aW9uc18gPT0gTlVMTCkgeworICAgIG9wdGlvbnNfID0gbmV3IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0aG9kT3B0aW9uczsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvLm9wdGlvbnMpCisgIHJldHVybiBvcHRpb25zXzsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGhvZE9wdGlvbnMqIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6cmVsZWFzZV9vcHRpb25zKCkgeworICBjbGVhcl9oYXNfb3B0aW9ucygpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGhvZE9wdGlvbnMqIHRlbXAgPSBvcHRpb25zXzsKKyAgb3B0aW9uc18gPSBOVUxMOworICByZXR1cm4gdGVtcDsKK30KK2lubGluZSB2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6c2V0X2FsbG9jYXRlZF9vcHRpb25zKDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0aG9kT3B0aW9ucyogb3B0aW9ucykgeworICBkZWxldGUgb3B0aW9uc187CisgIG9wdGlvbnNfID0gb3B0aW9uczsKKyAgaWYgKG9wdGlvbnMpIHsKKyAgICBzZXRfaGFzX29wdGlvbnMoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfb3B0aW9ucygpOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8ub3B0aW9ucykKK30KKworLy8gb3B0aW9uYWwgYm9vbCBjbGllbnRfc3RyZWFtaW5nID0gNSBbZGVmYXVsdCA9IGZhbHNlXTsKK2lubGluZSBib29sIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6aGFzX2NsaWVudF9zdHJlYW1pbmcoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMTB1KSAhPSAwOworfQoraW5saW5lIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpzZXRfaGFzX2NsaWVudF9zdHJlYW1pbmcoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAxMHU7Cit9CitpbmxpbmUgdm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OmNsZWFyX2hhc19jbGllbnRfc3RyZWFtaW5nKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDEwdTsKK30KK2lubGluZSB2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6Y2xlYXJfY2xpZW50X3N0cmVhbWluZygpIHsKKyAgY2xpZW50X3N0cmVhbWluZ18gPSBmYWxzZTsKKyAgY2xlYXJfaGFzX2NsaWVudF9zdHJlYW1pbmcoKTsKK30KK2lubGluZSBib29sIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6Y2xpZW50X3N0cmVhbWluZygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvLmNsaWVudF9zdHJlYW1pbmcpCisgIHJldHVybiBjbGllbnRfc3RyZWFtaW5nXzsKK30KK2lubGluZSB2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6c2V0X2NsaWVudF9zdHJlYW1pbmcoYm9vbCB2YWx1ZSkgeworICBzZXRfaGFzX2NsaWVudF9zdHJlYW1pbmcoKTsKKyAgY2xpZW50X3N0cmVhbWluZ18gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvLmNsaWVudF9zdHJlYW1pbmcpCit9CisKKy8vIG9wdGlvbmFsIGJvb2wgc2VydmVyX3N0cmVhbWluZyA9IDYgW2RlZmF1bHQgPSBmYWxzZV07CitpbmxpbmUgYm9vbCBNZXRob2REZXNjcmlwdG9yUHJvdG86Omhhc19zZXJ2ZXJfc3RyZWFtaW5nKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDIwdSkgIT0gMDsKK30KK2lubGluZSB2b2lkIE1ldGhvZERlc2NyaXB0b3JQcm90bzo6c2V0X2hhc19zZXJ2ZXJfc3RyZWFtaW5nKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMjB1OworfQoraW5saW5lIHZvaWQgTWV0aG9kRGVzY3JpcHRvclByb3RvOjpjbGVhcl9oYXNfc2VydmVyX3N0cmVhbWluZygpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAyMHU7Cit9CitpbmxpbmUgdm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OmNsZWFyX3NlcnZlcl9zdHJlYW1pbmcoKSB7CisgIHNlcnZlcl9zdHJlYW1pbmdfID0gZmFsc2U7CisgIGNsZWFyX2hhc19zZXJ2ZXJfc3RyZWFtaW5nKCk7Cit9CitpbmxpbmUgYm9vbCBNZXRob2REZXNjcmlwdG9yUHJvdG86OnNlcnZlcl9zdHJlYW1pbmcoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90by5zZXJ2ZXJfc3RyZWFtaW5nKQorICByZXR1cm4gc2VydmVyX3N0cmVhbWluZ187Cit9CitpbmxpbmUgdm9pZCBNZXRob2REZXNjcmlwdG9yUHJvdG86OnNldF9zZXJ2ZXJfc3RyZWFtaW5nKGJvb2wgdmFsdWUpIHsKKyAgc2V0X2hhc19zZXJ2ZXJfc3RyZWFtaW5nKCk7CisgIHNlcnZlcl9zdHJlYW1pbmdfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90by5zZXJ2ZXJfc3RyZWFtaW5nKQorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIEZpbGVPcHRpb25zCisKKy8vIG9wdGlvbmFsIHN0cmluZyBqYXZhX3BhY2thZ2UgPSAxOworaW5saW5lIGJvb2wgRmlsZU9wdGlvbnM6Omhhc19qYXZhX3BhY2thZ2UoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDF1KSAhPSAwOworfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9oYXNfamF2YV9wYWNrYWdlKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDF1OworfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OmNsZWFyX2hhc19qYXZhX3BhY2thZ2UoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDF1OworfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OmNsZWFyX2phdmFfcGFja2FnZSgpIHsKKyAgamF2YV9wYWNrYWdlXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGNsZWFyX2hhc19qYXZhX3BhY2thZ2UoKTsKK30KK2lubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBGaWxlT3B0aW9uczo6amF2YV9wYWNrYWdlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5qYXZhX3BhY2thZ2UpCisgIHJldHVybiBqYXZhX3BhY2thZ2VfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpzZXRfamF2YV9wYWNrYWdlKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfamF2YV9wYWNrYWdlKCk7CisgIGphdmFfcGFja2FnZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuamF2YV9wYWNrYWdlKQorfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9qYXZhX3BhY2thZ2UoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgc2V0X2hhc19qYXZhX3BhY2thZ2UoKTsKKyAgamF2YV9wYWNrYWdlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmphdmFfcGFja2FnZSkKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpzZXRfamF2YV9wYWNrYWdlKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX2phdmFfcGFja2FnZSgpOworICBqYXZhX3BhY2thZ2VfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5qYXZhX3BhY2thZ2UpCit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogRmlsZU9wdGlvbnM6Om11dGFibGVfamF2YV9wYWNrYWdlKCkgeworICBzZXRfaGFzX2phdmFfcGFja2FnZSgpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuamF2YV9wYWNrYWdlKQorICByZXR1cm4gamF2YV9wYWNrYWdlXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIEZpbGVPcHRpb25zOjpyZWxlYXNlX2phdmFfcGFja2FnZSgpIHsKKyAgY2xlYXJfaGFzX2phdmFfcGFja2FnZSgpOworICByZXR1cm4gamF2YV9wYWNrYWdlXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9hbGxvY2F0ZWRfamF2YV9wYWNrYWdlKDo6c3RkOjpzdHJpbmcqIGphdmFfcGFja2FnZSkgeworICBpZiAoamF2YV9wYWNrYWdlICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX2phdmFfcGFja2FnZSgpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19qYXZhX3BhY2thZ2UoKTsKKyAgfQorICBqYXZhX3BhY2thZ2VfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBqYXZhX3BhY2thZ2UpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuamF2YV9wYWNrYWdlKQorfQorCisvLyBvcHRpb25hbCBzdHJpbmcgamF2YV9vdXRlcl9jbGFzc25hbWUgPSA4OworaW5saW5lIGJvb2wgRmlsZU9wdGlvbnM6Omhhc19qYXZhX291dGVyX2NsYXNzbmFtZSgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMnUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2hhc19qYXZhX291dGVyX2NsYXNzbmFtZSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAydTsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl9oYXNfamF2YV9vdXRlcl9jbGFzc25hbWUoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDJ1OworfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OmNsZWFyX2phdmFfb3V0ZXJfY2xhc3NuYW1lKCkgeworICBqYXZhX291dGVyX2NsYXNzbmFtZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfamF2YV9vdXRlcl9jbGFzc25hbWUoKTsKK30KK2lubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBGaWxlT3B0aW9uczo6amF2YV9vdXRlcl9jbGFzc25hbWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmphdmFfb3V0ZXJfY2xhc3NuYW1lKQorICByZXR1cm4gamF2YV9vdXRlcl9jbGFzc25hbWVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpzZXRfamF2YV9vdXRlcl9jbGFzc25hbWUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgc2V0X2hhc19qYXZhX291dGVyX2NsYXNzbmFtZSgpOworICBqYXZhX291dGVyX2NsYXNzbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuamF2YV9vdXRlcl9jbGFzc25hbWUpCit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2phdmFfb3V0ZXJfY2xhc3NuYW1lKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfamF2YV9vdXRlcl9jbGFzc25hbWUoKTsKKyAgamF2YV9vdXRlcl9jbGFzc25hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuamF2YV9vdXRlcl9jbGFzc25hbWUpCit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2phdmFfb3V0ZXJfY2xhc3NuYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX2phdmFfb3V0ZXJfY2xhc3NuYW1lKCk7CisgIGphdmFfb3V0ZXJfY2xhc3NuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuamF2YV9vdXRlcl9jbGFzc25hbWUpCit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogRmlsZU9wdGlvbnM6Om11dGFibGVfamF2YV9vdXRlcl9jbGFzc25hbWUoKSB7CisgIHNldF9oYXNfamF2YV9vdXRlcl9jbGFzc25hbWUoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmphdmFfb3V0ZXJfY2xhc3NuYW1lKQorICByZXR1cm4gamF2YV9vdXRlcl9jbGFzc25hbWVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogRmlsZU9wdGlvbnM6OnJlbGVhc2VfamF2YV9vdXRlcl9jbGFzc25hbWUoKSB7CisgIGNsZWFyX2hhc19qYXZhX291dGVyX2NsYXNzbmFtZSgpOworICByZXR1cm4gamF2YV9vdXRlcl9jbGFzc25hbWVfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2FsbG9jYXRlZF9qYXZhX291dGVyX2NsYXNzbmFtZSg6OnN0ZDo6c3RyaW5nKiBqYXZhX291dGVyX2NsYXNzbmFtZSkgeworICBpZiAoamF2YV9vdXRlcl9jbGFzc25hbWUgIT0gTlVMTCkgeworICAgIHNldF9oYXNfamF2YV9vdXRlcl9jbGFzc25hbWUoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfamF2YV9vdXRlcl9jbGFzc25hbWUoKTsKKyAgfQorICBqYXZhX291dGVyX2NsYXNzbmFtZV8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGphdmFfb3V0ZXJfY2xhc3NuYW1lKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmphdmFfb3V0ZXJfY2xhc3NuYW1lKQorfQorCisvLyBvcHRpb25hbCBib29sIGphdmFfbXVsdGlwbGVfZmlsZXMgPSAxMCBbZGVmYXVsdCA9IGZhbHNlXTsKK2lubGluZSBib29sIEZpbGVPcHRpb25zOjpoYXNfamF2YV9tdWx0aXBsZV9maWxlcygpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwNHUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2hhc19qYXZhX211bHRpcGxlX2ZpbGVzKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDR1OworfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OmNsZWFyX2hhc19qYXZhX211bHRpcGxlX2ZpbGVzKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDA0dTsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl9qYXZhX211bHRpcGxlX2ZpbGVzKCkgeworICBqYXZhX211bHRpcGxlX2ZpbGVzXyA9IGZhbHNlOworICBjbGVhcl9oYXNfamF2YV9tdWx0aXBsZV9maWxlcygpOworfQoraW5saW5lIGJvb2wgRmlsZU9wdGlvbnM6OmphdmFfbXVsdGlwbGVfZmlsZXMoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmphdmFfbXVsdGlwbGVfZmlsZXMpCisgIHJldHVybiBqYXZhX211bHRpcGxlX2ZpbGVzXzsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpzZXRfamF2YV9tdWx0aXBsZV9maWxlcyhib29sIHZhbHVlKSB7CisgIHNldF9oYXNfamF2YV9tdWx0aXBsZV9maWxlcygpOworICBqYXZhX211bHRpcGxlX2ZpbGVzXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5qYXZhX211bHRpcGxlX2ZpbGVzKQorfQorCisvLyBvcHRpb25hbCBib29sIGphdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoID0gMjAgW2RlZmF1bHQgPSBmYWxzZV07CitpbmxpbmUgYm9vbCBGaWxlT3B0aW9uczo6aGFzX2phdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDA4dSkgIT0gMDsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpzZXRfaGFzX2phdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDh1OworfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OmNsZWFyX2hhc19qYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaCgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwOHU7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6Y2xlYXJfamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2goKSB7CisgIGphdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoXyA9IGZhbHNlOworICBjbGVhcl9oYXNfamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2goKTsKK30KK2lubGluZSBib29sIEZpbGVPcHRpb25zOjpqYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2gpCisgIHJldHVybiBqYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaF87Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2phdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoKGJvb2wgdmFsdWUpIHsKKyAgc2V0X2hhc19qYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaCgpOworICBqYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaF8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2gpCit9CisKKy8vIG9wdGlvbmFsIGJvb2wgamF2YV9zdHJpbmdfY2hlY2tfdXRmOCA9IDI3IFtkZWZhdWx0ID0gZmFsc2VdOworaW5saW5lIGJvb2wgRmlsZU9wdGlvbnM6Omhhc19qYXZhX3N0cmluZ19jaGVja191dGY4KCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDEwdSkgIT0gMDsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpzZXRfaGFzX2phdmFfc3RyaW5nX2NoZWNrX3V0ZjgoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAxMHU7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6Y2xlYXJfaGFzX2phdmFfc3RyaW5nX2NoZWNrX3V0ZjgoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMTB1OworfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OmNsZWFyX2phdmFfc3RyaW5nX2NoZWNrX3V0ZjgoKSB7CisgIGphdmFfc3RyaW5nX2NoZWNrX3V0ZjhfID0gZmFsc2U7CisgIGNsZWFyX2hhc19qYXZhX3N0cmluZ19jaGVja191dGY4KCk7Cit9CitpbmxpbmUgYm9vbCBGaWxlT3B0aW9uczo6amF2YV9zdHJpbmdfY2hlY2tfdXRmOCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuamF2YV9zdHJpbmdfY2hlY2tfdXRmOCkKKyAgcmV0dXJuIGphdmFfc3RyaW5nX2NoZWNrX3V0ZjhfOworfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9qYXZhX3N0cmluZ19jaGVja191dGY4KGJvb2wgdmFsdWUpIHsKKyAgc2V0X2hhc19qYXZhX3N0cmluZ19jaGVja191dGY4KCk7CisgIGphdmFfc3RyaW5nX2NoZWNrX3V0ZjhfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmphdmFfc3RyaW5nX2NoZWNrX3V0ZjgpCit9CisKKy8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuT3B0aW1pemVNb2RlIG9wdGltaXplX2ZvciA9IDkgW2RlZmF1bHQgPSBTUEVFRF07CitpbmxpbmUgYm9vbCBGaWxlT3B0aW9uczo6aGFzX29wdGltaXplX2ZvcigpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAyMHUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2hhc19vcHRpbWl6ZV9mb3IoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAyMHU7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6Y2xlYXJfaGFzX29wdGltaXplX2ZvcigpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAyMHU7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6Y2xlYXJfb3B0aW1pemVfZm9yKCkgeworICBvcHRpbWl6ZV9mb3JfID0gMTsKKyAgY2xlYXJfaGFzX29wdGltaXplX2ZvcigpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlIEZpbGVPcHRpb25zOjpvcHRpbWl6ZV9mb3IoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLm9wdGltaXplX2ZvcikKKyAgcmV0dXJuIHN0YXRpY19jYXN0PCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVPcHRpb25zX09wdGltaXplTW9kZSA+KG9wdGltaXplX2Zvcl8pOworfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9vcHRpbWl6ZV9mb3IoOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGUgdmFsdWUpIHsKKyAgYXNzZXJ0KDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlX0lzVmFsaWQodmFsdWUpKTsKKyAgc2V0X2hhc19vcHRpbWl6ZV9mb3IoKTsKKyAgb3B0aW1pemVfZm9yXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5vcHRpbWl6ZV9mb3IpCit9CisKKy8vIG9wdGlvbmFsIHN0cmluZyBnb19wYWNrYWdlID0gMTE7CitpbmxpbmUgYm9vbCBGaWxlT3B0aW9uczo6aGFzX2dvX3BhY2thZ2UoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwNDB1KSAhPSAwOworfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9oYXNfZ29fcGFja2FnZSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDQwdTsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl9oYXNfZ29fcGFja2FnZSgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDA0MHU7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6Y2xlYXJfZ29fcGFja2FnZSgpIHsKKyAgZ29fcGFja2FnZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfZ29fcGFja2FnZSgpOworfQoraW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEZpbGVPcHRpb25zOjpnb19wYWNrYWdlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5nb19wYWNrYWdlKQorICByZXR1cm4gZ29fcGFja2FnZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9nb19wYWNrYWdlKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfZ29fcGFja2FnZSgpOworICBnb19wYWNrYWdlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5nb19wYWNrYWdlKQorfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9nb19wYWNrYWdlKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfZ29fcGFja2FnZSgpOworICBnb19wYWNrYWdlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmdvX3BhY2thZ2UpCit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2dvX3BhY2thZ2UoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHNldF9oYXNfZ29fcGFja2FnZSgpOworICBnb19wYWNrYWdlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuZ29fcGFja2FnZSkKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBGaWxlT3B0aW9uczo6bXV0YWJsZV9nb19wYWNrYWdlKCkgeworICBzZXRfaGFzX2dvX3BhY2thZ2UoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmdvX3BhY2thZ2UpCisgIHJldHVybiBnb19wYWNrYWdlXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIEZpbGVPcHRpb25zOjpyZWxlYXNlX2dvX3BhY2thZ2UoKSB7CisgIGNsZWFyX2hhc19nb19wYWNrYWdlKCk7CisgIHJldHVybiBnb19wYWNrYWdlXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9hbGxvY2F0ZWRfZ29fcGFja2FnZSg6OnN0ZDo6c3RyaW5nKiBnb19wYWNrYWdlKSB7CisgIGlmIChnb19wYWNrYWdlICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX2dvX3BhY2thZ2UoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfZ29fcGFja2FnZSgpOworICB9CisgIGdvX3BhY2thZ2VfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBnb19wYWNrYWdlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmdvX3BhY2thZ2UpCit9CisKKy8vIG9wdGlvbmFsIGJvb2wgY2NfZ2VuZXJpY19zZXJ2aWNlcyA9IDE2IFtkZWZhdWx0ID0gZmFsc2VdOworaW5saW5lIGJvb2wgRmlsZU9wdGlvbnM6Omhhc19jY19nZW5lcmljX3NlcnZpY2VzKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDgwdSkgIT0gMDsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpzZXRfaGFzX2NjX2dlbmVyaWNfc2VydmljZXMoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDA4MHU7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6Y2xlYXJfaGFzX2NjX2dlbmVyaWNfc2VydmljZXMoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwODB1OworfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OmNsZWFyX2NjX2dlbmVyaWNfc2VydmljZXMoKSB7CisgIGNjX2dlbmVyaWNfc2VydmljZXNfID0gZmFsc2U7CisgIGNsZWFyX2hhc19jY19nZW5lcmljX3NlcnZpY2VzKCk7Cit9CitpbmxpbmUgYm9vbCBGaWxlT3B0aW9uczo6Y2NfZ2VuZXJpY19zZXJ2aWNlcygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuY2NfZ2VuZXJpY19zZXJ2aWNlcykKKyAgcmV0dXJuIGNjX2dlbmVyaWNfc2VydmljZXNfOworfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9jY19nZW5lcmljX3NlcnZpY2VzKGJvb2wgdmFsdWUpIHsKKyAgc2V0X2hhc19jY19nZW5lcmljX3NlcnZpY2VzKCk7CisgIGNjX2dlbmVyaWNfc2VydmljZXNfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmNjX2dlbmVyaWNfc2VydmljZXMpCit9CisKKy8vIG9wdGlvbmFsIGJvb2wgamF2YV9nZW5lcmljX3NlcnZpY2VzID0gMTcgW2RlZmF1bHQgPSBmYWxzZV07CitpbmxpbmUgYm9vbCBGaWxlT3B0aW9uczo6aGFzX2phdmFfZ2VuZXJpY19zZXJ2aWNlcygpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDEwMHUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2hhc19qYXZhX2dlbmVyaWNfc2VydmljZXMoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDEwMHU7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6Y2xlYXJfaGFzX2phdmFfZ2VuZXJpY19zZXJ2aWNlcygpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDEwMHU7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6Y2xlYXJfamF2YV9nZW5lcmljX3NlcnZpY2VzKCkgeworICBqYXZhX2dlbmVyaWNfc2VydmljZXNfID0gZmFsc2U7CisgIGNsZWFyX2hhc19qYXZhX2dlbmVyaWNfc2VydmljZXMoKTsKK30KK2lubGluZSBib29sIEZpbGVPcHRpb25zOjpqYXZhX2dlbmVyaWNfc2VydmljZXMoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmphdmFfZ2VuZXJpY19zZXJ2aWNlcykKKyAgcmV0dXJuIGphdmFfZ2VuZXJpY19zZXJ2aWNlc187Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2phdmFfZ2VuZXJpY19zZXJ2aWNlcyhib29sIHZhbHVlKSB7CisgIHNldF9oYXNfamF2YV9nZW5lcmljX3NlcnZpY2VzKCk7CisgIGphdmFfZ2VuZXJpY19zZXJ2aWNlc18gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuamF2YV9nZW5lcmljX3NlcnZpY2VzKQorfQorCisvLyBvcHRpb25hbCBib29sIHB5X2dlbmVyaWNfc2VydmljZXMgPSAxOCBbZGVmYXVsdCA9IGZhbHNlXTsKK2lubGluZSBib29sIEZpbGVPcHRpb25zOjpoYXNfcHlfZ2VuZXJpY19zZXJ2aWNlcygpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDIwMHUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2hhc19weV9nZW5lcmljX3NlcnZpY2VzKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAyMDB1OworfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OmNsZWFyX2hhc19weV9nZW5lcmljX3NlcnZpY2VzKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMjAwdTsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl9weV9nZW5lcmljX3NlcnZpY2VzKCkgeworICBweV9nZW5lcmljX3NlcnZpY2VzXyA9IGZhbHNlOworICBjbGVhcl9oYXNfcHlfZ2VuZXJpY19zZXJ2aWNlcygpOworfQoraW5saW5lIGJvb2wgRmlsZU9wdGlvbnM6OnB5X2dlbmVyaWNfc2VydmljZXMoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLnB5X2dlbmVyaWNfc2VydmljZXMpCisgIHJldHVybiBweV9nZW5lcmljX3NlcnZpY2VzXzsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpzZXRfcHlfZ2VuZXJpY19zZXJ2aWNlcyhib29sIHZhbHVlKSB7CisgIHNldF9oYXNfcHlfZ2VuZXJpY19zZXJ2aWNlcygpOworICBweV9nZW5lcmljX3NlcnZpY2VzXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5weV9nZW5lcmljX3NlcnZpY2VzKQorfQorCisvLyBvcHRpb25hbCBib29sIGRlcHJlY2F0ZWQgPSAyMyBbZGVmYXVsdCA9IGZhbHNlXTsKK2lubGluZSBib29sIEZpbGVPcHRpb25zOjpoYXNfZGVwcmVjYXRlZCgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDQwMHUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2hhc19kZXByZWNhdGVkKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDA0MDB1OworfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OmNsZWFyX2hhc19kZXByZWNhdGVkKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwNDAwdTsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl9kZXByZWNhdGVkKCkgeworICBkZXByZWNhdGVkXyA9IGZhbHNlOworICBjbGVhcl9oYXNfZGVwcmVjYXRlZCgpOworfQoraW5saW5lIGJvb2wgRmlsZU9wdGlvbnM6OmRlcHJlY2F0ZWQoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmRlcHJlY2F0ZWQpCisgIHJldHVybiBkZXByZWNhdGVkXzsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpzZXRfZGVwcmVjYXRlZChib29sIHZhbHVlKSB7CisgIHNldF9oYXNfZGVwcmVjYXRlZCgpOworICBkZXByZWNhdGVkXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5kZXByZWNhdGVkKQorfQorCisvLyBvcHRpb25hbCBib29sIGNjX2VuYWJsZV9hcmVuYXMgPSAzMSBbZGVmYXVsdCA9IGZhbHNlXTsKK2lubGluZSBib29sIEZpbGVPcHRpb25zOjpoYXNfY2NfZW5hYmxlX2FyZW5hcygpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDgwMHUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2hhc19jY19lbmFibGVfYXJlbmFzKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDA4MDB1OworfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OmNsZWFyX2hhc19jY19lbmFibGVfYXJlbmFzKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwODAwdTsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl9jY19lbmFibGVfYXJlbmFzKCkgeworICBjY19lbmFibGVfYXJlbmFzXyA9IGZhbHNlOworICBjbGVhcl9oYXNfY2NfZW5hYmxlX2FyZW5hcygpOworfQoraW5saW5lIGJvb2wgRmlsZU9wdGlvbnM6OmNjX2VuYWJsZV9hcmVuYXMoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmNjX2VuYWJsZV9hcmVuYXMpCisgIHJldHVybiBjY19lbmFibGVfYXJlbmFzXzsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpzZXRfY2NfZW5hYmxlX2FyZW5hcyhib29sIHZhbHVlKSB7CisgIHNldF9oYXNfY2NfZW5hYmxlX2FyZW5hcygpOworICBjY19lbmFibGVfYXJlbmFzXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5jY19lbmFibGVfYXJlbmFzKQorfQorCisvLyBvcHRpb25hbCBzdHJpbmcgb2JqY19jbGFzc19wcmVmaXggPSAzNjsKK2lubGluZSBib29sIEZpbGVPcHRpb25zOjpoYXNfb2JqY19jbGFzc19wcmVmaXgoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDEwMDB1KSAhPSAwOworfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9oYXNfb2JqY19jbGFzc19wcmVmaXgoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMTAwMHU7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6Y2xlYXJfaGFzX29iamNfY2xhc3NfcHJlZml4KCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAxMDAwdTsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl9vYmpjX2NsYXNzX3ByZWZpeCgpIHsKKyAgb2JqY19jbGFzc19wcmVmaXhfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX29iamNfY2xhc3NfcHJlZml4KCk7Cit9CitpbmxpbmUgY29uc3QgOjpzdGQ6OnN0cmluZyYgRmlsZU9wdGlvbnM6Om9iamNfY2xhc3NfcHJlZml4KCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5vYmpjX2NsYXNzX3ByZWZpeCkKKyAgcmV0dXJuIG9iamNfY2xhc3NfcHJlZml4Xy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6c2V0X29iamNfY2xhc3NfcHJlZml4KGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfb2JqY19jbGFzc19wcmVmaXgoKTsKKyAgb2JqY19jbGFzc19wcmVmaXhfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLm9iamNfY2xhc3NfcHJlZml4KQorfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9vYmpjX2NsYXNzX3ByZWZpeChjb25zdCBjaGFyKiB2YWx1ZSkgeworICBzZXRfaGFzX29iamNfY2xhc3NfcHJlZml4KCk7CisgIG9iamNfY2xhc3NfcHJlZml4Xy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLm9iamNfY2xhc3NfcHJlZml4KQorfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9vYmpjX2NsYXNzX3ByZWZpeChjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19vYmpjX2NsYXNzX3ByZWZpeCgpOworICBvYmpjX2NsYXNzX3ByZWZpeF8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLm9iamNfY2xhc3NfcHJlZml4KQorfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIEZpbGVPcHRpb25zOjptdXRhYmxlX29iamNfY2xhc3NfcHJlZml4KCkgeworICBzZXRfaGFzX29iamNfY2xhc3NfcHJlZml4KCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5vYmpjX2NsYXNzX3ByZWZpeCkKKyAgcmV0dXJuIG9iamNfY2xhc3NfcHJlZml4Xy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIEZpbGVPcHRpb25zOjpyZWxlYXNlX29iamNfY2xhc3NfcHJlZml4KCkgeworICBjbGVhcl9oYXNfb2JqY19jbGFzc19wcmVmaXgoKTsKKyAgcmV0dXJuIG9iamNfY2xhc3NfcHJlZml4Xy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OnNldF9hbGxvY2F0ZWRfb2JqY19jbGFzc19wcmVmaXgoOjpzdGQ6OnN0cmluZyogb2JqY19jbGFzc19wcmVmaXgpIHsKKyAgaWYgKG9iamNfY2xhc3NfcHJlZml4ICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX29iamNfY2xhc3NfcHJlZml4KCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX29iamNfY2xhc3NfcHJlZml4KCk7CisgIH0KKyAgb2JqY19jbGFzc19wcmVmaXhfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBvYmpjX2NsYXNzX3ByZWZpeCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5vYmpjX2NsYXNzX3ByZWZpeCkKK30KKworLy8gb3B0aW9uYWwgc3RyaW5nIGNzaGFycF9uYW1lc3BhY2UgPSAzNzsKK2lubGluZSBib29sIEZpbGVPcHRpb25zOjpoYXNfY3NoYXJwX25hbWVzcGFjZSgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMjAwMHUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2hhc19jc2hhcnBfbmFtZXNwYWNlKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDIwMDB1OworfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OmNsZWFyX2hhc19jc2hhcnBfbmFtZXNwYWNlKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAyMDAwdTsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl9jc2hhcnBfbmFtZXNwYWNlKCkgeworICBjc2hhcnBfbmFtZXNwYWNlXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGNsZWFyX2hhc19jc2hhcnBfbmFtZXNwYWNlKCk7Cit9CitpbmxpbmUgY29uc3QgOjpzdGQ6OnN0cmluZyYgRmlsZU9wdGlvbnM6OmNzaGFycF9uYW1lc3BhY2UoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmNzaGFycF9uYW1lc3BhY2UpCisgIHJldHVybiBjc2hhcnBfbmFtZXNwYWNlXy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2NzaGFycF9uYW1lc3BhY2UoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgc2V0X2hhc19jc2hhcnBfbmFtZXNwYWNlKCk7CisgIGNzaGFycF9uYW1lc3BhY2VfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmNzaGFycF9uYW1lc3BhY2UpCit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2NzaGFycF9uYW1lc3BhY2UoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgc2V0X2hhc19jc2hhcnBfbmFtZXNwYWNlKCk7CisgIGNzaGFycF9uYW1lc3BhY2VfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuY3NoYXJwX25hbWVzcGFjZSkKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpzZXRfY3NoYXJwX25hbWVzcGFjZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19jc2hhcnBfbmFtZXNwYWNlKCk7CisgIGNzaGFycF9uYW1lc3BhY2VfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5jc2hhcnBfbmFtZXNwYWNlKQorfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIEZpbGVPcHRpb25zOjptdXRhYmxlX2NzaGFycF9uYW1lc3BhY2UoKSB7CisgIHNldF9oYXNfY3NoYXJwX25hbWVzcGFjZSgpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuY3NoYXJwX25hbWVzcGFjZSkKKyAgcmV0dXJuIGNzaGFycF9uYW1lc3BhY2VfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogRmlsZU9wdGlvbnM6OnJlbGVhc2VfY3NoYXJwX25hbWVzcGFjZSgpIHsKKyAgY2xlYXJfaGFzX2NzaGFycF9uYW1lc3BhY2UoKTsKKyAgcmV0dXJuIGNzaGFycF9uYW1lc3BhY2VfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2FsbG9jYXRlZF9jc2hhcnBfbmFtZXNwYWNlKDo6c3RkOjpzdHJpbmcqIGNzaGFycF9uYW1lc3BhY2UpIHsKKyAgaWYgKGNzaGFycF9uYW1lc3BhY2UgIT0gTlVMTCkgeworICAgIHNldF9oYXNfY3NoYXJwX25hbWVzcGFjZSgpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19jc2hhcnBfbmFtZXNwYWNlKCk7CisgIH0KKyAgY3NoYXJwX25hbWVzcGFjZV8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGNzaGFycF9uYW1lc3BhY2UpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuY3NoYXJwX25hbWVzcGFjZSkKK30KKworLy8gb3B0aW9uYWwgYm9vbCBqYXZhbmFub191c2VfZGVwcmVjYXRlZF9wYWNrYWdlID0gMzggW2RlcHJlY2F0ZWQgPSB0cnVlXTsKK2lubGluZSBib29sIEZpbGVPcHRpb25zOjpoYXNfamF2YW5hbm9fdXNlX2RlcHJlY2F0ZWRfcGFja2FnZSgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwNDAwMHUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBGaWxlT3B0aW9uczo6c2V0X2hhc19qYXZhbmFub191c2VfZGVwcmVjYXRlZF9wYWNrYWdlKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDQwMDB1OworfQoraW5saW5lIHZvaWQgRmlsZU9wdGlvbnM6OmNsZWFyX2hhc19qYXZhbmFub191c2VfZGVwcmVjYXRlZF9wYWNrYWdlKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDA0MDAwdTsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl9qYXZhbmFub191c2VfZGVwcmVjYXRlZF9wYWNrYWdlKCkgeworICBqYXZhbmFub191c2VfZGVwcmVjYXRlZF9wYWNrYWdlXyA9IGZhbHNlOworICBjbGVhcl9oYXNfamF2YW5hbm9fdXNlX2RlcHJlY2F0ZWRfcGFja2FnZSgpOworfQoraW5saW5lIGJvb2wgRmlsZU9wdGlvbnM6OmphdmFuYW5vX3VzZV9kZXByZWNhdGVkX3BhY2thZ2UoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLmphdmFuYW5vX3VzZV9kZXByZWNhdGVkX3BhY2thZ2UpCisgIHJldHVybiBqYXZhbmFub191c2VfZGVwcmVjYXRlZF9wYWNrYWdlXzsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpzZXRfamF2YW5hbm9fdXNlX2RlcHJlY2F0ZWRfcGFja2FnZShib29sIHZhbHVlKSB7CisgIHNldF9oYXNfamF2YW5hbm9fdXNlX2RlcHJlY2F0ZWRfcGFja2FnZSgpOworICBqYXZhbmFub191c2VfZGVwcmVjYXRlZF9wYWNrYWdlXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5qYXZhbmFub191c2VfZGVwcmVjYXRlZF9wYWNrYWdlKQorfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CitpbmxpbmUgaW50IEZpbGVPcHRpb25zOjp1bmludGVycHJldGVkX29wdGlvbl9zaXplKCkgY29uc3QgeworICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLnNpemUoKTsKK30KK2lubGluZSB2b2lkIEZpbGVPcHRpb25zOjpjbGVhcl91bmludGVycHJldGVkX29wdGlvbigpIHsKKyAgdW5pbnRlcnByZXRlZF9vcHRpb25fLkNsZWFyKCk7Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uJiBGaWxlT3B0aW9uczo6dW5pbnRlcnByZXRlZF9vcHRpb24oaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLkdldChpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uKiBGaWxlT3B0aW9uczo6bXV0YWJsZV91bmludGVycHJldGVkX29wdGlvbihpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLk11dGFibGUoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiogRmlsZU9wdGlvbnM6OmFkZF91bmludGVycHJldGVkX29wdGlvbigpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl8uQWRkKCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24gPioKK0ZpbGVPcHRpb25zOjptdXRhYmxlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuICZ1bmludGVycHJldGVkX29wdGlvbl87Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24gPiYKK0ZpbGVPcHRpb25zOjp1bmludGVycHJldGVkX29wdGlvbigpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIE1lc3NhZ2VPcHRpb25zCisKKy8vIG9wdGlvbmFsIGJvb2wgbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQgPSAxIFtkZWZhdWx0ID0gZmFsc2VdOworaW5saW5lIGJvb2wgTWVzc2FnZU9wdGlvbnM6Omhhc19tZXNzYWdlX3NldF93aXJlX2Zvcm1hdCgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMXUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBNZXNzYWdlT3B0aW9uczo6c2V0X2hhc19tZXNzYWdlX3NldF93aXJlX2Zvcm1hdCgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAxdTsKK30KK2lubGluZSB2b2lkIE1lc3NhZ2VPcHRpb25zOjpjbGVhcl9oYXNfbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDF1OworfQoraW5saW5lIHZvaWQgTWVzc2FnZU9wdGlvbnM6OmNsZWFyX21lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KCkgeworICBtZXNzYWdlX3NldF93aXJlX2Zvcm1hdF8gPSBmYWxzZTsKKyAgY2xlYXJfaGFzX21lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KCk7Cit9CitpbmxpbmUgYm9vbCBNZXNzYWdlT3B0aW9uczo6bWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zLm1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KQorICByZXR1cm4gbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXRfOworfQoraW5saW5lIHZvaWQgTWVzc2FnZU9wdGlvbnM6OnNldF9tZXNzYWdlX3NldF93aXJlX2Zvcm1hdChib29sIHZhbHVlKSB7CisgIHNldF9oYXNfbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQoKTsKKyAgbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXRfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zLm1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KQorfQorCisvLyBvcHRpb25hbCBib29sIG5vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3IgPSAyIFtkZWZhdWx0ID0gZmFsc2VdOworaW5saW5lIGJvb2wgTWVzc2FnZU9wdGlvbnM6Omhhc19ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAydSkgIT0gMDsKK30KK2lubGluZSB2b2lkIE1lc3NhZ2VPcHRpb25zOjpzZXRfaGFzX25vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3IoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMnU7Cit9CitpbmxpbmUgdm9pZCBNZXNzYWdlT3B0aW9uczo6Y2xlYXJfaGFzX25vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3IoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDJ1OworfQoraW5saW5lIHZvaWQgTWVzc2FnZU9wdGlvbnM6OmNsZWFyX25vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3IoKSB7CisgIG5vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3JfID0gZmFsc2U7CisgIGNsZWFyX2hhc19ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yKCk7Cit9CitpbmxpbmUgYm9vbCBNZXNzYWdlT3B0aW9uczo6bm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvcigpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMubm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvcikKKyAgcmV0dXJuIG5vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3JfOworfQoraW5saW5lIHZvaWQgTWVzc2FnZU9wdGlvbnM6OnNldF9ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yKGJvb2wgdmFsdWUpIHsKKyAgc2V0X2hhc19ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yKCk7CisgIG5vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3JfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zLm5vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3IpCit9CisKKy8vIG9wdGlvbmFsIGJvb2wgZGVwcmVjYXRlZCA9IDMgW2RlZmF1bHQgPSBmYWxzZV07CitpbmxpbmUgYm9vbCBNZXNzYWdlT3B0aW9uczo6aGFzX2RlcHJlY2F0ZWQoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDR1KSAhPSAwOworfQoraW5saW5lIHZvaWQgTWVzc2FnZU9wdGlvbnM6OnNldF9oYXNfZGVwcmVjYXRlZCgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDA0dTsKK30KK2lubGluZSB2b2lkIE1lc3NhZ2VPcHRpb25zOjpjbGVhcl9oYXNfZGVwcmVjYXRlZCgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwNHU7Cit9CitpbmxpbmUgdm9pZCBNZXNzYWdlT3B0aW9uczo6Y2xlYXJfZGVwcmVjYXRlZCgpIHsKKyAgZGVwcmVjYXRlZF8gPSBmYWxzZTsKKyAgY2xlYXJfaGFzX2RlcHJlY2F0ZWQoKTsKK30KK2lubGluZSBib29sIE1lc3NhZ2VPcHRpb25zOjpkZXByZWNhdGVkKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucy5kZXByZWNhdGVkKQorICByZXR1cm4gZGVwcmVjYXRlZF87Cit9CitpbmxpbmUgdm9pZCBNZXNzYWdlT3B0aW9uczo6c2V0X2RlcHJlY2F0ZWQoYm9vbCB2YWx1ZSkgeworICBzZXRfaGFzX2RlcHJlY2F0ZWQoKTsKKyAgZGVwcmVjYXRlZF8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMuZGVwcmVjYXRlZCkKK30KKworLy8gb3B0aW9uYWwgYm9vbCBtYXBfZW50cnkgPSA3OworaW5saW5lIGJvb2wgTWVzc2FnZU9wdGlvbnM6Omhhc19tYXBfZW50cnkoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDh1KSAhPSAwOworfQoraW5saW5lIHZvaWQgTWVzc2FnZU9wdGlvbnM6OnNldF9oYXNfbWFwX2VudHJ5KCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDh1OworfQoraW5saW5lIHZvaWQgTWVzc2FnZU9wdGlvbnM6OmNsZWFyX2hhc19tYXBfZW50cnkoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDh1OworfQoraW5saW5lIHZvaWQgTWVzc2FnZU9wdGlvbnM6OmNsZWFyX21hcF9lbnRyeSgpIHsKKyAgbWFwX2VudHJ5XyA9IGZhbHNlOworICBjbGVhcl9oYXNfbWFwX2VudHJ5KCk7Cit9CitpbmxpbmUgYm9vbCBNZXNzYWdlT3B0aW9uczo6bWFwX2VudHJ5KCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucy5tYXBfZW50cnkpCisgIHJldHVybiBtYXBfZW50cnlfOworfQoraW5saW5lIHZvaWQgTWVzc2FnZU9wdGlvbnM6OnNldF9tYXBfZW50cnkoYm9vbCB2YWx1ZSkgeworICBzZXRfaGFzX21hcF9lbnRyeSgpOworICBtYXBfZW50cnlfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zLm1hcF9lbnRyeSkKK30KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIHVuaW50ZXJwcmV0ZWRfb3B0aW9uID0gOTk5OworaW5saW5lIGludCBNZXNzYWdlT3B0aW9uczo6dW5pbnRlcnByZXRlZF9vcHRpb25fc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5zaXplKCk7Cit9CitpbmxpbmUgdm9pZCBNZXNzYWdlT3B0aW9uczo6Y2xlYXJfdW5pbnRlcnByZXRlZF9vcHRpb24oKSB7CisgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5DbGVhcigpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiYgTWVzc2FnZU9wdGlvbnM6OnVuaW50ZXJwcmV0ZWRfb3B0aW9uKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5HZXQoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiogTWVzc2FnZU9wdGlvbnM6Om11dGFibGVfdW5pbnRlcnByZXRlZF9vcHRpb24oaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5NdXRhYmxlKGluZGV4KTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24qIE1lc3NhZ2VPcHRpb25zOjphZGRfdW5pbnRlcnByZXRlZF9vcHRpb24oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLkFkZCgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uID4qCitNZXNzYWdlT3B0aW9uczo6bXV0YWJsZV91bmludGVycHJldGVkX29wdGlvbigpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiAmdW5pbnRlcnByZXRlZF9vcHRpb25fOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uID4mCitNZXNzYWdlT3B0aW9uczo6dW5pbnRlcnByZXRlZF9vcHRpb24oKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXzsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBGaWVsZE9wdGlvbnMKKworLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuQ1R5cGUgY3R5cGUgPSAxIFtkZWZhdWx0ID0gU1RSSU5HXTsKK2lubGluZSBib29sIEZpZWxkT3B0aW9uczo6aGFzX2N0eXBlKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAxdSkgIT0gMDsKK30KK2lubGluZSB2b2lkIEZpZWxkT3B0aW9uczo6c2V0X2hhc19jdHlwZSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAxdTsKK30KK2lubGluZSB2b2lkIEZpZWxkT3B0aW9uczo6Y2xlYXJfaGFzX2N0eXBlKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAxdTsKK30KK2lubGluZSB2b2lkIEZpZWxkT3B0aW9uczo6Y2xlYXJfY3R5cGUoKSB7CisgIGN0eXBlXyA9IDA7CisgIGNsZWFyX2hhc19jdHlwZSgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGRPcHRpb25zX0NUeXBlIEZpZWxkT3B0aW9uczo6Y3R5cGUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5jdHlwZSkKKyAgcmV0dXJuIHN0YXRpY19jYXN0PCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkT3B0aW9uc19DVHlwZSA+KGN0eXBlXyk7Cit9CitpbmxpbmUgdm9pZCBGaWVsZE9wdGlvbnM6OnNldF9jdHlwZSg6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkT3B0aW9uc19DVHlwZSB2YWx1ZSkgeworICBhc3NlcnQoOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZE9wdGlvbnNfQ1R5cGVfSXNWYWxpZCh2YWx1ZSkpOworICBzZXRfaGFzX2N0eXBlKCk7CisgIGN0eXBlXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuY3R5cGUpCit9CisKKy8vIG9wdGlvbmFsIGJvb2wgcGFja2VkID0gMjsKK2lubGluZSBib29sIEZpZWxkT3B0aW9uczo6aGFzX3BhY2tlZCgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMnUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBGaWVsZE9wdGlvbnM6OnNldF9oYXNfcGFja2VkKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDJ1OworfQoraW5saW5lIHZvaWQgRmllbGRPcHRpb25zOjpjbGVhcl9oYXNfcGFja2VkKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAydTsKK30KK2lubGluZSB2b2lkIEZpZWxkT3B0aW9uczo6Y2xlYXJfcGFja2VkKCkgeworICBwYWNrZWRfID0gZmFsc2U7CisgIGNsZWFyX2hhc19wYWNrZWQoKTsKK30KK2lubGluZSBib29sIEZpZWxkT3B0aW9uczo6cGFja2VkKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMucGFja2VkKQorICByZXR1cm4gcGFja2VkXzsKK30KK2lubGluZSB2b2lkIEZpZWxkT3B0aW9uczo6c2V0X3BhY2tlZChib29sIHZhbHVlKSB7CisgIHNldF9oYXNfcGFja2VkKCk7CisgIHBhY2tlZF8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLnBhY2tlZCkKK30KKworLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuSlNUeXBlIGpzdHlwZSA9IDYgW2RlZmF1bHQgPSBKU19OT1JNQUxdOworaW5saW5lIGJvb2wgRmllbGRPcHRpb25zOjpoYXNfanN0eXBlKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDA0dSkgIT0gMDsKK30KK2lubGluZSB2b2lkIEZpZWxkT3B0aW9uczo6c2V0X2hhc19qc3R5cGUoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwNHU7Cit9CitpbmxpbmUgdm9pZCBGaWVsZE9wdGlvbnM6OmNsZWFyX2hhc19qc3R5cGUoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDR1OworfQoraW5saW5lIHZvaWQgRmllbGRPcHRpb25zOjpjbGVhcl9qc3R5cGUoKSB7CisgIGpzdHlwZV8gPSAwOworICBjbGVhcl9oYXNfanN0eXBlKCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZE9wdGlvbnNfSlNUeXBlIEZpZWxkT3B0aW9uczo6anN0eXBlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuanN0eXBlKQorICByZXR1cm4gc3RhdGljX2Nhc3Q8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGRPcHRpb25zX0pTVHlwZSA+KGpzdHlwZV8pOworfQoraW5saW5lIHZvaWQgRmllbGRPcHRpb25zOjpzZXRfanN0eXBlKDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGRPcHRpb25zX0pTVHlwZSB2YWx1ZSkgeworICBhc3NlcnQoOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZE9wdGlvbnNfSlNUeXBlX0lzVmFsaWQodmFsdWUpKTsKKyAgc2V0X2hhc19qc3R5cGUoKTsKKyAganN0eXBlXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuanN0eXBlKQorfQorCisvLyBvcHRpb25hbCBib29sIGxhenkgPSA1IFtkZWZhdWx0ID0gZmFsc2VdOworaW5saW5lIGJvb2wgRmllbGRPcHRpb25zOjpoYXNfbGF6eSgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwOHUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBGaWVsZE9wdGlvbnM6OnNldF9oYXNfbGF6eSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDA4dTsKK30KK2lubGluZSB2b2lkIEZpZWxkT3B0aW9uczo6Y2xlYXJfaGFzX2xhenkoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDh1OworfQoraW5saW5lIHZvaWQgRmllbGRPcHRpb25zOjpjbGVhcl9sYXp5KCkgeworICBsYXp5XyA9IGZhbHNlOworICBjbGVhcl9oYXNfbGF6eSgpOworfQoraW5saW5lIGJvb2wgRmllbGRPcHRpb25zOjpsYXp5KCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMubGF6eSkKKyAgcmV0dXJuIGxhenlfOworfQoraW5saW5lIHZvaWQgRmllbGRPcHRpb25zOjpzZXRfbGF6eShib29sIHZhbHVlKSB7CisgIHNldF9oYXNfbGF6eSgpOworICBsYXp5XyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMubGF6eSkKK30KKworLy8gb3B0aW9uYWwgYm9vbCBkZXByZWNhdGVkID0gMyBbZGVmYXVsdCA9IGZhbHNlXTsKK2lubGluZSBib29sIEZpZWxkT3B0aW9uczo6aGFzX2RlcHJlY2F0ZWQoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMTB1KSAhPSAwOworfQoraW5saW5lIHZvaWQgRmllbGRPcHRpb25zOjpzZXRfaGFzX2RlcHJlY2F0ZWQoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAxMHU7Cit9CitpbmxpbmUgdm9pZCBGaWVsZE9wdGlvbnM6OmNsZWFyX2hhc19kZXByZWNhdGVkKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDEwdTsKK30KK2lubGluZSB2b2lkIEZpZWxkT3B0aW9uczo6Y2xlYXJfZGVwcmVjYXRlZCgpIHsKKyAgZGVwcmVjYXRlZF8gPSBmYWxzZTsKKyAgY2xlYXJfaGFzX2RlcHJlY2F0ZWQoKTsKK30KK2lubGluZSBib29sIEZpZWxkT3B0aW9uczo6ZGVwcmVjYXRlZCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLmRlcHJlY2F0ZWQpCisgIHJldHVybiBkZXByZWNhdGVkXzsKK30KK2lubGluZSB2b2lkIEZpZWxkT3B0aW9uczo6c2V0X2RlcHJlY2F0ZWQoYm9vbCB2YWx1ZSkgeworICBzZXRfaGFzX2RlcHJlY2F0ZWQoKTsKKyAgZGVwcmVjYXRlZF8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLmRlcHJlY2F0ZWQpCit9CisKKy8vIG9wdGlvbmFsIGJvb2wgd2VhayA9IDEwIFtkZWZhdWx0ID0gZmFsc2VdOworaW5saW5lIGJvb2wgRmllbGRPcHRpb25zOjpoYXNfd2VhaygpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAyMHUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBGaWVsZE9wdGlvbnM6OnNldF9oYXNfd2VhaygpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDIwdTsKK30KK2lubGluZSB2b2lkIEZpZWxkT3B0aW9uczo6Y2xlYXJfaGFzX3dlYWsoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMjB1OworfQoraW5saW5lIHZvaWQgRmllbGRPcHRpb25zOjpjbGVhcl93ZWFrKCkgeworICB3ZWFrXyA9IGZhbHNlOworICBjbGVhcl9oYXNfd2VhaygpOworfQoraW5saW5lIGJvb2wgRmllbGRPcHRpb25zOjp3ZWFrKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMud2VhaykKKyAgcmV0dXJuIHdlYWtfOworfQoraW5saW5lIHZvaWQgRmllbGRPcHRpb25zOjpzZXRfd2Vhayhib29sIHZhbHVlKSB7CisgIHNldF9oYXNfd2VhaygpOworICB3ZWFrXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMud2VhaykKK30KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIHVuaW50ZXJwcmV0ZWRfb3B0aW9uID0gOTk5OworaW5saW5lIGludCBGaWVsZE9wdGlvbnM6OnVuaW50ZXJwcmV0ZWRfb3B0aW9uX3NpemUoKSBjb25zdCB7CisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl8uc2l6ZSgpOworfQoraW5saW5lIHZvaWQgRmllbGRPcHRpb25zOjpjbGVhcl91bmludGVycHJldGVkX29wdGlvbigpIHsKKyAgdW5pbnRlcnByZXRlZF9vcHRpb25fLkNsZWFyKCk7Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uJiBGaWVsZE9wdGlvbnM6OnVuaW50ZXJwcmV0ZWRfb3B0aW9uKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl8uR2V0KGluZGV4KTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24qIEZpZWxkT3B0aW9uczo6bXV0YWJsZV91bmludGVycHJldGVkX29wdGlvbihpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5NdXRhYmxlKGluZGV4KTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24qIEZpZWxkT3B0aW9uczo6YWRkX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl8uQWRkKCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24gPioKK0ZpZWxkT3B0aW9uczo6bXV0YWJsZV91bmludGVycHJldGVkX29wdGlvbigpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gJnVuaW50ZXJwcmV0ZWRfb3B0aW9uXzsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiA+JgorRmllbGRPcHRpb25zOjp1bmludGVycHJldGVkX29wdGlvbigpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXzsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBFbnVtT3B0aW9ucworCisvLyBvcHRpb25hbCBib29sIGFsbG93X2FsaWFzID0gMjsKK2lubGluZSBib29sIEVudW1PcHRpb25zOjpoYXNfYWxsb3dfYWxpYXMoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDF1KSAhPSAwOworfQoraW5saW5lIHZvaWQgRW51bU9wdGlvbnM6OnNldF9oYXNfYWxsb3dfYWxpYXMoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMXU7Cit9CitpbmxpbmUgdm9pZCBFbnVtT3B0aW9uczo6Y2xlYXJfaGFzX2FsbG93X2FsaWFzKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAxdTsKK30KK2lubGluZSB2b2lkIEVudW1PcHRpb25zOjpjbGVhcl9hbGxvd19hbGlhcygpIHsKKyAgYWxsb3dfYWxpYXNfID0gZmFsc2U7CisgIGNsZWFyX2hhc19hbGxvd19hbGlhcygpOworfQoraW5saW5lIGJvb2wgRW51bU9wdGlvbnM6OmFsbG93X2FsaWFzKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucy5hbGxvd19hbGlhcykKKyAgcmV0dXJuIGFsbG93X2FsaWFzXzsKK30KK2lubGluZSB2b2lkIEVudW1PcHRpb25zOjpzZXRfYWxsb3dfYWxpYXMoYm9vbCB2YWx1ZSkgeworICBzZXRfaGFzX2FsbG93X2FsaWFzKCk7CisgIGFsbG93X2FsaWFzXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucy5hbGxvd19hbGlhcykKK30KKworLy8gb3B0aW9uYWwgYm9vbCBkZXByZWNhdGVkID0gMyBbZGVmYXVsdCA9IGZhbHNlXTsKK2lubGluZSBib29sIEVudW1PcHRpb25zOjpoYXNfZGVwcmVjYXRlZCgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMnUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBFbnVtT3B0aW9uczo6c2V0X2hhc19kZXByZWNhdGVkKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDJ1OworfQoraW5saW5lIHZvaWQgRW51bU9wdGlvbnM6OmNsZWFyX2hhc19kZXByZWNhdGVkKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAydTsKK30KK2lubGluZSB2b2lkIEVudW1PcHRpb25zOjpjbGVhcl9kZXByZWNhdGVkKCkgeworICBkZXByZWNhdGVkXyA9IGZhbHNlOworICBjbGVhcl9oYXNfZGVwcmVjYXRlZCgpOworfQoraW5saW5lIGJvb2wgRW51bU9wdGlvbnM6OmRlcHJlY2F0ZWQoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zLmRlcHJlY2F0ZWQpCisgIHJldHVybiBkZXByZWNhdGVkXzsKK30KK2lubGluZSB2b2lkIEVudW1PcHRpb25zOjpzZXRfZGVwcmVjYXRlZChib29sIHZhbHVlKSB7CisgIHNldF9oYXNfZGVwcmVjYXRlZCgpOworICBkZXByZWNhdGVkXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucy5kZXByZWNhdGVkKQorfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CitpbmxpbmUgaW50IEVudW1PcHRpb25zOjp1bmludGVycHJldGVkX29wdGlvbl9zaXplKCkgY29uc3QgeworICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLnNpemUoKTsKK30KK2lubGluZSB2b2lkIEVudW1PcHRpb25zOjpjbGVhcl91bmludGVycHJldGVkX29wdGlvbigpIHsKKyAgdW5pbnRlcnByZXRlZF9vcHRpb25fLkNsZWFyKCk7Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uJiBFbnVtT3B0aW9uczo6dW5pbnRlcnByZXRlZF9vcHRpb24oaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLkdldChpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uKiBFbnVtT3B0aW9uczo6bXV0YWJsZV91bmludGVycHJldGVkX29wdGlvbihpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLk11dGFibGUoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiogRW51bU9wdGlvbnM6OmFkZF91bmludGVycHJldGVkX29wdGlvbigpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl8uQWRkKCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24gPioKK0VudW1PcHRpb25zOjptdXRhYmxlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuICZ1bmludGVycHJldGVkX29wdGlvbl87Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24gPiYKK0VudW1PcHRpb25zOjp1bmludGVycHJldGVkX29wdGlvbigpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIEVudW1WYWx1ZU9wdGlvbnMKKworLy8gb3B0aW9uYWwgYm9vbCBkZXByZWNhdGVkID0gMSBbZGVmYXVsdCA9IGZhbHNlXTsKK2lubGluZSBib29sIEVudW1WYWx1ZU9wdGlvbnM6Omhhc19kZXByZWNhdGVkKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAxdSkgIT0gMDsKK30KK2lubGluZSB2b2lkIEVudW1WYWx1ZU9wdGlvbnM6OnNldF9oYXNfZGVwcmVjYXRlZCgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAxdTsKK30KK2lubGluZSB2b2lkIEVudW1WYWx1ZU9wdGlvbnM6OmNsZWFyX2hhc19kZXByZWNhdGVkKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAxdTsKK30KK2lubGluZSB2b2lkIEVudW1WYWx1ZU9wdGlvbnM6OmNsZWFyX2RlcHJlY2F0ZWQoKSB7CisgIGRlcHJlY2F0ZWRfID0gZmFsc2U7CisgIGNsZWFyX2hhc19kZXByZWNhdGVkKCk7Cit9CitpbmxpbmUgYm9vbCBFbnVtVmFsdWVPcHRpb25zOjpkZXByZWNhdGVkKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVPcHRpb25zLmRlcHJlY2F0ZWQpCisgIHJldHVybiBkZXByZWNhdGVkXzsKK30KK2lubGluZSB2b2lkIEVudW1WYWx1ZU9wdGlvbnM6OnNldF9kZXByZWNhdGVkKGJvb2wgdmFsdWUpIHsKKyAgc2V0X2hhc19kZXByZWNhdGVkKCk7CisgIGRlcHJlY2F0ZWRfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnMuZGVwcmVjYXRlZCkKK30KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIHVuaW50ZXJwcmV0ZWRfb3B0aW9uID0gOTk5OworaW5saW5lIGludCBFbnVtVmFsdWVPcHRpb25zOjp1bmludGVycHJldGVkX29wdGlvbl9zaXplKCkgY29uc3QgeworICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLnNpemUoKTsKK30KK2lubGluZSB2b2lkIEVudW1WYWx1ZU9wdGlvbnM6OmNsZWFyX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgeworICB1bmludGVycHJldGVkX29wdGlvbl8uQ2xlYXIoKTsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24mIEVudW1WYWx1ZU9wdGlvbnM6OnVuaW50ZXJwcmV0ZWRfb3B0aW9uKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVPcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLkdldChpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uKiBFbnVtVmFsdWVPcHRpb25zOjptdXRhYmxlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5NdXRhYmxlKGluZGV4KTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24qIEVudW1WYWx1ZU9wdGlvbnM6OmFkZF91bmludGVycHJldGVkX29wdGlvbigpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5BZGQoKTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiA+KgorRW51bVZhbHVlT3B0aW9uczo6bXV0YWJsZV91bmludGVycHJldGVkX29wdGlvbigpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuICZ1bmludGVycHJldGVkX29wdGlvbl87Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24gPiYKK0VudW1WYWx1ZU9wdGlvbnM6OnVuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXzsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBTZXJ2aWNlT3B0aW9ucworCisvLyBvcHRpb25hbCBib29sIGRlcHJlY2F0ZWQgPSAzMyBbZGVmYXVsdCA9IGZhbHNlXTsKK2lubGluZSBib29sIFNlcnZpY2VPcHRpb25zOjpoYXNfZGVwcmVjYXRlZCgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMXUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBTZXJ2aWNlT3B0aW9uczo6c2V0X2hhc19kZXByZWNhdGVkKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDF1OworfQoraW5saW5lIHZvaWQgU2VydmljZU9wdGlvbnM6OmNsZWFyX2hhc19kZXByZWNhdGVkKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAxdTsKK30KK2lubGluZSB2b2lkIFNlcnZpY2VPcHRpb25zOjpjbGVhcl9kZXByZWNhdGVkKCkgeworICBkZXByZWNhdGVkXyA9IGZhbHNlOworICBjbGVhcl9oYXNfZGVwcmVjYXRlZCgpOworfQoraW5saW5lIGJvb2wgU2VydmljZU9wdGlvbnM6OmRlcHJlY2F0ZWQoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zLmRlcHJlY2F0ZWQpCisgIHJldHVybiBkZXByZWNhdGVkXzsKK30KK2lubGluZSB2b2lkIFNlcnZpY2VPcHRpb25zOjpzZXRfZGVwcmVjYXRlZChib29sIHZhbHVlKSB7CisgIHNldF9oYXNfZGVwcmVjYXRlZCgpOworICBkZXByZWNhdGVkXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlT3B0aW9ucy5kZXByZWNhdGVkKQorfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CitpbmxpbmUgaW50IFNlcnZpY2VPcHRpb25zOjp1bmludGVycHJldGVkX29wdGlvbl9zaXplKCkgY29uc3QgeworICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLnNpemUoKTsKK30KK2lubGluZSB2b2lkIFNlcnZpY2VPcHRpb25zOjpjbGVhcl91bmludGVycHJldGVkX29wdGlvbigpIHsKKyAgdW5pbnRlcnByZXRlZF9vcHRpb25fLkNsZWFyKCk7Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uJiBTZXJ2aWNlT3B0aW9uczo6dW5pbnRlcnByZXRlZF9vcHRpb24oaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLkdldChpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uKiBTZXJ2aWNlT3B0aW9uczo6bXV0YWJsZV91bmludGVycHJldGVkX29wdGlvbihpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fLk11dGFibGUoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiogU2VydmljZU9wdGlvbnM6OmFkZF91bmludGVycHJldGVkX29wdGlvbigpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuU2VydmljZU9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl8uQWRkKCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24gPioKK1NlcnZpY2VPcHRpb25zOjptdXRhYmxlX3VuaW50ZXJwcmV0ZWRfb3B0aW9uKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuICZ1bmludGVycHJldGVkX29wdGlvbl87Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24gPiYKK1NlcnZpY2VPcHRpb25zOjp1bmludGVycHJldGVkX29wdGlvbigpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zLnVuaW50ZXJwcmV0ZWRfb3B0aW9uKQorICByZXR1cm4gdW5pbnRlcnByZXRlZF9vcHRpb25fOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIE1ldGhvZE9wdGlvbnMKKworLy8gb3B0aW9uYWwgYm9vbCBkZXByZWNhdGVkID0gMzMgW2RlZmF1bHQgPSBmYWxzZV07CitpbmxpbmUgYm9vbCBNZXRob2RPcHRpb25zOjpoYXNfZGVwcmVjYXRlZCgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMXUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBNZXRob2RPcHRpb25zOjpzZXRfaGFzX2RlcHJlY2F0ZWQoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMXU7Cit9CitpbmxpbmUgdm9pZCBNZXRob2RPcHRpb25zOjpjbGVhcl9oYXNfZGVwcmVjYXRlZCgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMXU7Cit9CitpbmxpbmUgdm9pZCBNZXRob2RPcHRpb25zOjpjbGVhcl9kZXByZWNhdGVkKCkgeworICBkZXByZWNhdGVkXyA9IGZhbHNlOworICBjbGVhcl9oYXNfZGVwcmVjYXRlZCgpOworfQoraW5saW5lIGJvb2wgTWV0aG9kT3B0aW9uczo6ZGVwcmVjYXRlZCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucy5kZXByZWNhdGVkKQorICByZXR1cm4gZGVwcmVjYXRlZF87Cit9CitpbmxpbmUgdm9pZCBNZXRob2RPcHRpb25zOjpzZXRfZGVwcmVjYXRlZChib29sIHZhbHVlKSB7CisgIHNldF9oYXNfZGVwcmVjYXRlZCgpOworICBkZXByZWNhdGVkXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zLmRlcHJlY2F0ZWQpCit9CisKKy8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiB1bmludGVycHJldGVkX29wdGlvbiA9IDk5OTsKK2lubGluZSBpbnQgTWV0aG9kT3B0aW9uczo6dW5pbnRlcnByZXRlZF9vcHRpb25fc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5zaXplKCk7Cit9CitpbmxpbmUgdm9pZCBNZXRob2RPcHRpb25zOjpjbGVhcl91bmludGVycHJldGVkX29wdGlvbigpIHsKKyAgdW5pbnRlcnByZXRlZF9vcHRpb25fLkNsZWFyKCk7Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uJiBNZXRob2RPcHRpb25zOjp1bmludGVycHJldGVkX29wdGlvbihpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucy51bmludGVycHJldGVkX29wdGlvbikKKyAgcmV0dXJuIHVuaW50ZXJwcmV0ZWRfb3B0aW9uXy5HZXQoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbiogTWV0aG9kT3B0aW9uczo6bXV0YWJsZV91bmludGVycHJldGVkX29wdGlvbihpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl8uTXV0YWJsZShpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uKiBNZXRob2RPcHRpb25zOjphZGRfdW5pbnRlcnByZXRlZF9vcHRpb24oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl8uQWRkKCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb24gPioKK01ldGhvZE9wdGlvbnM6Om11dGFibGVfdW5pbnRlcnByZXRlZF9vcHRpb24oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiAmdW5pbnRlcnByZXRlZF9vcHRpb25fOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uID4mCitNZXRob2RPcHRpb25zOjp1bmludGVycHJldGVkX29wdGlvbigpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMudW5pbnRlcnByZXRlZF9vcHRpb24pCisgIHJldHVybiB1bmludGVycHJldGVkX29wdGlvbl87Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydAorCisvLyByZXF1aXJlZCBzdHJpbmcgbmFtZV9wYXJ0ID0gMTsKK2lubGluZSBib29sIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQ6Omhhc19uYW1lX3BhcnQoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDF1KSAhPSAwOworfQoraW5saW5lIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6c2V0X2hhc19uYW1lX3BhcnQoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMXU7Cit9CitpbmxpbmUgdm9pZCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpjbGVhcl9oYXNfbmFtZV9wYXJ0KCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAxdTsKK30KK2lubGluZSB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQ6OmNsZWFyX25hbWVfcGFydCgpIHsKKyAgbmFtZV9wYXJ0Xy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGNsZWFyX2hhc19uYW1lX3BhcnQoKTsKK30KK2lubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpuYW1lX3BhcnQoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uTmFtZVBhcnQubmFtZV9wYXJ0KQorICByZXR1cm4gbmFtZV9wYXJ0Xy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpzZXRfbmFtZV9wYXJ0KGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfbmFtZV9wYXJ0KCk7CisgIG5hbWVfcGFydF8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5OYW1lUGFydC5uYW1lX3BhcnQpCit9CitpbmxpbmUgdm9pZCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpzZXRfbmFtZV9wYXJ0KGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfbmFtZV9wYXJ0KCk7CisgIG5hbWVfcGFydF8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLk5hbWVQYXJ0Lm5hbWVfcGFydCkKK30KK2lubGluZSB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQ6OnNldF9uYW1lX3BhcnQoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHNldF9oYXNfbmFtZV9wYXJ0KCk7CisgIG5hbWVfcGFydF8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uTmFtZVBhcnQubmFtZV9wYXJ0KQorfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQ6Om11dGFibGVfbmFtZV9wYXJ0KCkgeworICBzZXRfaGFzX25hbWVfcGFydCgpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5OYW1lUGFydC5uYW1lX3BhcnQpCisgIHJldHVybiBuYW1lX3BhcnRfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6cmVsZWFzZV9uYW1lX3BhcnQoKSB7CisgIGNsZWFyX2hhc19uYW1lX3BhcnQoKTsKKyAgcmV0dXJuIG5hbWVfcGFydF8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQ6OnNldF9hbGxvY2F0ZWRfbmFtZV9wYXJ0KDo6c3RkOjpzdHJpbmcqIG5hbWVfcGFydCkgeworICBpZiAobmFtZV9wYXJ0ICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX25hbWVfcGFydCgpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19uYW1lX3BhcnQoKTsKKyAgfQorICBuYW1lX3BhcnRfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBuYW1lX3BhcnQpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5OYW1lUGFydC5uYW1lX3BhcnQpCit9CisKKy8vIHJlcXVpcmVkIGJvb2wgaXNfZXh0ZW5zaW9uID0gMjsKK2lubGluZSBib29sIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQ6Omhhc19pc19leHRlbnNpb24oKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDJ1KSAhPSAwOworfQoraW5saW5lIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydDo6c2V0X2hhc19pc19leHRlbnNpb24oKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMnU7Cit9CitpbmxpbmUgdm9pZCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0OjpjbGVhcl9oYXNfaXNfZXh0ZW5zaW9uKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDAydTsKK30KK2lubGluZSB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQ6OmNsZWFyX2lzX2V4dGVuc2lvbigpIHsKKyAgaXNfZXh0ZW5zaW9uXyA9IGZhbHNlOworICBjbGVhcl9oYXNfaXNfZXh0ZW5zaW9uKCk7Cit9CitpbmxpbmUgYm9vbCBVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0Ojppc19leHRlbnNpb24oKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uTmFtZVBhcnQuaXNfZXh0ZW5zaW9uKQorICByZXR1cm4gaXNfZXh0ZW5zaW9uXzsKK30KK2lubGluZSB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQ6OnNldF9pc19leHRlbnNpb24oYm9vbCB2YWx1ZSkgeworICBzZXRfaGFzX2lzX2V4dGVuc2lvbigpOworICBpc19leHRlbnNpb25fID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uTmFtZVBhcnQuaXNfZXh0ZW5zaW9uKQorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIFVuaW50ZXJwcmV0ZWRPcHRpb24KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLk5hbWVQYXJ0IG5hbWUgPSAyOworaW5saW5lIGludCBVbmludGVycHJldGVkT3B0aW9uOjpuYW1lX3NpemUoKSBjb25zdCB7CisgIHJldHVybiBuYW1lXy5zaXplKCk7Cit9CitpbmxpbmUgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpjbGVhcl9uYW1lKCkgeworICBuYW1lXy5DbGVhcigpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydCYgVW5pbnRlcnByZXRlZE9wdGlvbjo6bmFtZShpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5uYW1lKQorICByZXR1cm4gbmFtZV8uR2V0KGluZGV4KTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlVuaW50ZXJwcmV0ZWRPcHRpb25fTmFtZVBhcnQqIFVuaW50ZXJwcmV0ZWRPcHRpb246Om11dGFibGVfbmFtZShpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24ubmFtZSkKKyAgcmV0dXJuIG5hbWVfLk11dGFibGUoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydCogVW5pbnRlcnByZXRlZE9wdGlvbjo6YWRkX25hbWUoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24ubmFtZSkKKyAgcmV0dXJuIG5hbWVfLkFkZCgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpVbmludGVycHJldGVkT3B0aW9uX05hbWVQYXJ0ID4qCitVbmludGVycHJldGVkT3B0aW9uOjptdXRhYmxlX25hbWUoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24ubmFtZSkKKyAgcmV0dXJuICZuYW1lXzsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VW5pbnRlcnByZXRlZE9wdGlvbl9OYW1lUGFydCA+JgorVW5pbnRlcnByZXRlZE9wdGlvbjo6bmFtZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24ubmFtZSkKKyAgcmV0dXJuIG5hbWVfOworfQorCisvLyBvcHRpb25hbCBzdHJpbmcgaWRlbnRpZmllcl92YWx1ZSA9IDM7CitpbmxpbmUgYm9vbCBVbmludGVycHJldGVkT3B0aW9uOjpoYXNfaWRlbnRpZmllcl92YWx1ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMnUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpzZXRfaGFzX2lkZW50aWZpZXJfdmFsdWUoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMnU7Cit9CitpbmxpbmUgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpjbGVhcl9oYXNfaWRlbnRpZmllcl92YWx1ZSgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMnU7Cit9CitpbmxpbmUgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpjbGVhcl9pZGVudGlmaWVyX3ZhbHVlKCkgeworICBpZGVudGlmaWVyX3ZhbHVlXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGNsZWFyX2hhc19pZGVudGlmaWVyX3ZhbHVlKCk7Cit9CitpbmxpbmUgY29uc3QgOjpzdGQ6OnN0cmluZyYgVW5pbnRlcnByZXRlZE9wdGlvbjo6aWRlbnRpZmllcl92YWx1ZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5pZGVudGlmaWVyX3ZhbHVlKQorICByZXR1cm4gaWRlbnRpZmllcl92YWx1ZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6c2V0X2lkZW50aWZpZXJfdmFsdWUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgc2V0X2hhc19pZGVudGlmaWVyX3ZhbHVlKCk7CisgIGlkZW50aWZpZXJfdmFsdWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uaWRlbnRpZmllcl92YWx1ZSkKK30KK2lubGluZSB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OnNldF9pZGVudGlmaWVyX3ZhbHVlKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfaWRlbnRpZmllcl92YWx1ZSgpOworICBpZGVudGlmaWVyX3ZhbHVlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uaWRlbnRpZmllcl92YWx1ZSkKK30KK2lubGluZSB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OnNldF9pZGVudGlmaWVyX3ZhbHVlKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX2lkZW50aWZpZXJfdmFsdWUoKTsKKyAgaWRlbnRpZmllcl92YWx1ZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uaWRlbnRpZmllcl92YWx1ZSkKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBVbmludGVycHJldGVkT3B0aW9uOjptdXRhYmxlX2lkZW50aWZpZXJfdmFsdWUoKSB7CisgIHNldF9oYXNfaWRlbnRpZmllcl92YWx1ZSgpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5pZGVudGlmaWVyX3ZhbHVlKQorICByZXR1cm4gaWRlbnRpZmllcl92YWx1ZV8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBVbmludGVycHJldGVkT3B0aW9uOjpyZWxlYXNlX2lkZW50aWZpZXJfdmFsdWUoKSB7CisgIGNsZWFyX2hhc19pZGVudGlmaWVyX3ZhbHVlKCk7CisgIHJldHVybiBpZGVudGlmaWVyX3ZhbHVlXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6c2V0X2FsbG9jYXRlZF9pZGVudGlmaWVyX3ZhbHVlKDo6c3RkOjpzdHJpbmcqIGlkZW50aWZpZXJfdmFsdWUpIHsKKyAgaWYgKGlkZW50aWZpZXJfdmFsdWUgIT0gTlVMTCkgeworICAgIHNldF9oYXNfaWRlbnRpZmllcl92YWx1ZSgpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19pZGVudGlmaWVyX3ZhbHVlKCk7CisgIH0KKyAgaWRlbnRpZmllcl92YWx1ZV8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGlkZW50aWZpZXJfdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5pZGVudGlmaWVyX3ZhbHVlKQorfQorCisvLyBvcHRpb25hbCB1aW50NjQgcG9zaXRpdmVfaW50X3ZhbHVlID0gNDsKK2lubGluZSBib29sIFVuaW50ZXJwcmV0ZWRPcHRpb246Omhhc19wb3NpdGl2ZV9pbnRfdmFsdWUoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDR1KSAhPSAwOworfQoraW5saW5lIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6c2V0X2hhc19wb3NpdGl2ZV9pbnRfdmFsdWUoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwNHU7Cit9CitpbmxpbmUgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpjbGVhcl9oYXNfcG9zaXRpdmVfaW50X3ZhbHVlKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDA0dTsKK30KK2lubGluZSB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OmNsZWFyX3Bvc2l0aXZlX2ludF92YWx1ZSgpIHsKKyAgcG9zaXRpdmVfaW50X3ZhbHVlXyA9IEdPT0dMRV9VTE9OR0xPTkcoMCk7CisgIGNsZWFyX2hhc19wb3NpdGl2ZV9pbnRfdmFsdWUoKTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ2NCBVbmludGVycHJldGVkT3B0aW9uOjpwb3NpdGl2ZV9pbnRfdmFsdWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24ucG9zaXRpdmVfaW50X3ZhbHVlKQorICByZXR1cm4gcG9zaXRpdmVfaW50X3ZhbHVlXzsKK30KK2lubGluZSB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OnNldF9wb3NpdGl2ZV9pbnRfdmFsdWUoOjpnb29nbGU6OnByb3RvYnVmOjp1aW50NjQgdmFsdWUpIHsKKyAgc2V0X2hhc19wb3NpdGl2ZV9pbnRfdmFsdWUoKTsKKyAgcG9zaXRpdmVfaW50X3ZhbHVlXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLnBvc2l0aXZlX2ludF92YWx1ZSkKK30KKworLy8gb3B0aW9uYWwgaW50NjQgbmVnYXRpdmVfaW50X3ZhbHVlID0gNTsKK2lubGluZSBib29sIFVuaW50ZXJwcmV0ZWRPcHRpb246Omhhc19uZWdhdGl2ZV9pbnRfdmFsdWUoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDh1KSAhPSAwOworfQoraW5saW5lIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6c2V0X2hhc19uZWdhdGl2ZV9pbnRfdmFsdWUoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwOHU7Cit9CitpbmxpbmUgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpjbGVhcl9oYXNfbmVnYXRpdmVfaW50X3ZhbHVlKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDA4dTsKK30KK2lubGluZSB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OmNsZWFyX25lZ2F0aXZlX2ludF92YWx1ZSgpIHsKKyAgbmVnYXRpdmVfaW50X3ZhbHVlXyA9IEdPT0dMRV9MT05HTE9ORygwKTsKKyAgY2xlYXJfaGFzX25lZ2F0aXZlX2ludF92YWx1ZSgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50NjQgVW5pbnRlcnByZXRlZE9wdGlvbjo6bmVnYXRpdmVfaW50X3ZhbHVlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLm5lZ2F0aXZlX2ludF92YWx1ZSkKKyAgcmV0dXJuIG5lZ2F0aXZlX2ludF92YWx1ZV87Cit9CitpbmxpbmUgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpzZXRfbmVnYXRpdmVfaW50X3ZhbHVlKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50NjQgdmFsdWUpIHsKKyAgc2V0X2hhc19uZWdhdGl2ZV9pbnRfdmFsdWUoKTsKKyAgbmVnYXRpdmVfaW50X3ZhbHVlXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLm5lZ2F0aXZlX2ludF92YWx1ZSkKK30KKworLy8gb3B0aW9uYWwgZG91YmxlIGRvdWJsZV92YWx1ZSA9IDY7CitpbmxpbmUgYm9vbCBVbmludGVycHJldGVkT3B0aW9uOjpoYXNfZG91YmxlX3ZhbHVlKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDEwdSkgIT0gMDsKK30KK2lubGluZSB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OnNldF9oYXNfZG91YmxlX3ZhbHVlKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMTB1OworfQoraW5saW5lIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6Y2xlYXJfaGFzX2RvdWJsZV92YWx1ZSgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAxMHU7Cit9CitpbmxpbmUgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpjbGVhcl9kb3VibGVfdmFsdWUoKSB7CisgIGRvdWJsZV92YWx1ZV8gPSAwOworICBjbGVhcl9oYXNfZG91YmxlX3ZhbHVlKCk7Cit9CitpbmxpbmUgZG91YmxlIFVuaW50ZXJwcmV0ZWRPcHRpb246OmRvdWJsZV92YWx1ZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5kb3VibGVfdmFsdWUpCisgIHJldHVybiBkb3VibGVfdmFsdWVfOworfQoraW5saW5lIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6c2V0X2RvdWJsZV92YWx1ZShkb3VibGUgdmFsdWUpIHsKKyAgc2V0X2hhc19kb3VibGVfdmFsdWUoKTsKKyAgZG91YmxlX3ZhbHVlXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLmRvdWJsZV92YWx1ZSkKK30KKworLy8gb3B0aW9uYWwgYnl0ZXMgc3RyaW5nX3ZhbHVlID0gNzsKK2lubGluZSBib29sIFVuaW50ZXJwcmV0ZWRPcHRpb246Omhhc19zdHJpbmdfdmFsdWUoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMjB1KSAhPSAwOworfQoraW5saW5lIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6c2V0X2hhc19zdHJpbmdfdmFsdWUoKSB7CisgIF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAyMHU7Cit9CitpbmxpbmUgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpjbGVhcl9oYXNfc3RyaW5nX3ZhbHVlKCkgeworICBfaGFzX2JpdHNfWzBdICY9IH4weDAwMDAwMDIwdTsKK30KK2lubGluZSB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OmNsZWFyX3N0cmluZ192YWx1ZSgpIHsKKyAgc3RyaW5nX3ZhbHVlXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGNsZWFyX2hhc19zdHJpbmdfdmFsdWUoKTsKK30KK2lubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBVbmludGVycHJldGVkT3B0aW9uOjpzdHJpbmdfdmFsdWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uc3RyaW5nX3ZhbHVlKQorICByZXR1cm4gc3RyaW5nX3ZhbHVlXy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpzZXRfc3RyaW5nX3ZhbHVlKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfc3RyaW5nX3ZhbHVlKCk7CisgIHN0cmluZ192YWx1ZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5zdHJpbmdfdmFsdWUpCit9CitpbmxpbmUgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpzZXRfc3RyaW5nX3ZhbHVlKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfc3RyaW5nX3ZhbHVlKCk7CisgIHN0cmluZ192YWx1ZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLnN0cmluZ192YWx1ZSkKK30KK2lubGluZSB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OnNldF9zdHJpbmdfdmFsdWUoY29uc3Qgdm9pZCogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHNldF9oYXNfc3RyaW5nX3ZhbHVlKCk7CisgIHN0cmluZ192YWx1ZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uc3RyaW5nX3ZhbHVlKQorfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIFVuaW50ZXJwcmV0ZWRPcHRpb246Om11dGFibGVfc3RyaW5nX3ZhbHVlKCkgeworICBzZXRfaGFzX3N0cmluZ192YWx1ZSgpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5zdHJpbmdfdmFsdWUpCisgIHJldHVybiBzdHJpbmdfdmFsdWVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogVW5pbnRlcnByZXRlZE9wdGlvbjo6cmVsZWFzZV9zdHJpbmdfdmFsdWUoKSB7CisgIGNsZWFyX2hhc19zdHJpbmdfdmFsdWUoKTsKKyAgcmV0dXJuIHN0cmluZ192YWx1ZV8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OnNldF9hbGxvY2F0ZWRfc3RyaW5nX3ZhbHVlKDo6c3RkOjpzdHJpbmcqIHN0cmluZ192YWx1ZSkgeworICBpZiAoc3RyaW5nX3ZhbHVlICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX3N0cmluZ192YWx1ZSgpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc19zdHJpbmdfdmFsdWUoKTsKKyAgfQorICBzdHJpbmdfdmFsdWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBzdHJpbmdfdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5zdHJpbmdfdmFsdWUpCit9CisKKy8vIG9wdGlvbmFsIHN0cmluZyBhZ2dyZWdhdGVfdmFsdWUgPSA4OworaW5saW5lIGJvb2wgVW5pbnRlcnByZXRlZE9wdGlvbjo6aGFzX2FnZ3JlZ2F0ZV92YWx1ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDA0MHUpICE9IDA7Cit9CitpbmxpbmUgdm9pZCBVbmludGVycHJldGVkT3B0aW9uOjpzZXRfaGFzX2FnZ3JlZ2F0ZV92YWx1ZSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDQwdTsKK30KK2lubGluZSB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OmNsZWFyX2hhc19hZ2dyZWdhdGVfdmFsdWUoKSB7CisgIF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwNDB1OworfQoraW5saW5lIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6Y2xlYXJfYWdncmVnYXRlX3ZhbHVlKCkgeworICBhZ2dyZWdhdGVfdmFsdWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX2FnZ3JlZ2F0ZV92YWx1ZSgpOworfQoraW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIFVuaW50ZXJwcmV0ZWRPcHRpb246OmFnZ3JlZ2F0ZV92YWx1ZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5hZ2dyZWdhdGVfdmFsdWUpCisgIHJldHVybiBhZ2dyZWdhdGVfdmFsdWVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OnNldF9hZ2dyZWdhdGVfdmFsdWUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgc2V0X2hhc19hZ2dyZWdhdGVfdmFsdWUoKTsKKyAgYWdncmVnYXRlX3ZhbHVlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLmFnZ3JlZ2F0ZV92YWx1ZSkKK30KK2lubGluZSB2b2lkIFVuaW50ZXJwcmV0ZWRPcHRpb246OnNldF9hZ2dyZWdhdGVfdmFsdWUoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgc2V0X2hhc19hZ2dyZWdhdGVfdmFsdWUoKTsKKyAgYWdncmVnYXRlX3ZhbHVlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uYWdncmVnYXRlX3ZhbHVlKQorfQoraW5saW5lIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6c2V0X2FnZ3JlZ2F0ZV92YWx1ZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgc2V0X2hhc19hZ2dyZWdhdGVfdmFsdWUoKTsKKyAgYWdncmVnYXRlX3ZhbHVlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5hZ2dyZWdhdGVfdmFsdWUpCit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogVW5pbnRlcnByZXRlZE9wdGlvbjo6bXV0YWJsZV9hZ2dyZWdhdGVfdmFsdWUoKSB7CisgIHNldF9oYXNfYWdncmVnYXRlX3ZhbHVlKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLmFnZ3JlZ2F0ZV92YWx1ZSkKKyAgcmV0dXJuIGFnZ3JlZ2F0ZV92YWx1ZV8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBVbmludGVycHJldGVkT3B0aW9uOjpyZWxlYXNlX2FnZ3JlZ2F0ZV92YWx1ZSgpIHsKKyAgY2xlYXJfaGFzX2FnZ3JlZ2F0ZV92YWx1ZSgpOworICByZXR1cm4gYWdncmVnYXRlX3ZhbHVlXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgVW5pbnRlcnByZXRlZE9wdGlvbjo6c2V0X2FsbG9jYXRlZF9hZ2dyZWdhdGVfdmFsdWUoOjpzdGQ6OnN0cmluZyogYWdncmVnYXRlX3ZhbHVlKSB7CisgIGlmIChhZ2dyZWdhdGVfdmFsdWUgIT0gTlVMTCkgeworICAgIHNldF9oYXNfYWdncmVnYXRlX3ZhbHVlKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX2FnZ3JlZ2F0ZV92YWx1ZSgpOworICB9CisgIGFnZ3JlZ2F0ZV92YWx1ZV8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGFnZ3JlZ2F0ZV92YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLmFnZ3JlZ2F0ZV92YWx1ZSkKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbgorCisvLyByZXBlYXRlZCBpbnQzMiBwYXRoID0gMSBbcGFja2VkID0gdHJ1ZV07CitpbmxpbmUgaW50IFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpwYXRoX3NpemUoKSBjb25zdCB7CisgIHJldHVybiBwYXRoXy5zaXplKCk7Cit9CitpbmxpbmUgdm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6Y2xlYXJfcGF0aCgpIHsKKyAgcGF0aF8uQ2xlYXIoKTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpwYXRoKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5wYXRoKQorICByZXR1cm4gcGF0aF8uR2V0KGluZGV4KTsKK30KK2lubGluZSB2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpzZXRfcGF0aChpbnQgaW5kZXgsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgdmFsdWUpIHsKKyAgcGF0aF8uU2V0KGluZGV4LCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLnBhdGgpCit9CitpbmxpbmUgdm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6YWRkX3BhdGgoOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiB2YWx1ZSkgeworICBwYXRoXy5BZGQodmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5wYXRoKQorfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiA+JgorU291cmNlQ29kZUluZm9fTG9jYXRpb246OnBhdGgoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5wYXRoKQorICByZXR1cm4gcGF0aF87Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZEZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyID4qCitTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6bXV0YWJsZV9wYXRoKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5wYXRoKQorICByZXR1cm4gJnBhdGhfOworfQorCisvLyByZXBlYXRlZCBpbnQzMiBzcGFuID0gMiBbcGFja2VkID0gdHJ1ZV07CitpbmxpbmUgaW50IFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpzcGFuX3NpemUoKSBjb25zdCB7CisgIHJldHVybiBzcGFuXy5zaXplKCk7Cit9CitpbmxpbmUgdm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6Y2xlYXJfc3BhbigpIHsKKyAgc3Bhbl8uQ2xlYXIoKTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpzcGFuKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5zcGFuKQorICByZXR1cm4gc3Bhbl8uR2V0KGluZGV4KTsKK30KK2lubGluZSB2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpzZXRfc3BhbihpbnQgaW5kZXgsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgdmFsdWUpIHsKKyAgc3Bhbl8uU2V0KGluZGV4LCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLnNwYW4pCit9CitpbmxpbmUgdm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6YWRkX3NwYW4oOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiB2YWx1ZSkgeworICBzcGFuXy5BZGQodmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5zcGFuKQorfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiA+JgorU291cmNlQ29kZUluZm9fTG9jYXRpb246OnNwYW4oKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5zcGFuKQorICByZXR1cm4gc3Bhbl87Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZEZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyID4qCitTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6bXV0YWJsZV9zcGFuKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5zcGFuKQorICByZXR1cm4gJnNwYW5fOworfQorCisvLyBvcHRpb25hbCBzdHJpbmcgbGVhZGluZ19jb21tZW50cyA9IDM7CitpbmxpbmUgYm9vbCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6aGFzX2xlYWRpbmdfY29tbWVudHMoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDR1KSAhPSAwOworfQoraW5saW5lIHZvaWQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OnNldF9oYXNfbGVhZGluZ19jb21tZW50cygpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDA0dTsKK30KK2lubGluZSB2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpjbGVhcl9oYXNfbGVhZGluZ19jb21tZW50cygpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwNHU7Cit9CitpbmxpbmUgdm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6Y2xlYXJfbGVhZGluZ19jb21tZW50cygpIHsKKyAgbGVhZGluZ19jb21tZW50c18uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBjbGVhcl9oYXNfbGVhZGluZ19jb21tZW50cygpOworfQoraW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpsZWFkaW5nX2NvbW1lbnRzKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5sZWFkaW5nX2NvbW1lbnRzKQorICByZXR1cm4gbGVhZGluZ19jb21tZW50c18uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OnNldF9sZWFkaW5nX2NvbW1lbnRzKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfbGVhZGluZ19jb21tZW50cygpOworICBsZWFkaW5nX2NvbW1lbnRzXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5sZWFkaW5nX2NvbW1lbnRzKQorfQoraW5saW5lIHZvaWQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OnNldF9sZWFkaW5nX2NvbW1lbnRzKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHNldF9oYXNfbGVhZGluZ19jb21tZW50cygpOworICBsZWFkaW5nX2NvbW1lbnRzXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLmxlYWRpbmdfY29tbWVudHMpCit9CitpbmxpbmUgdm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6c2V0X2xlYWRpbmdfY29tbWVudHMoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHNldF9oYXNfbGVhZGluZ19jb21tZW50cygpOworICBsZWFkaW5nX2NvbW1lbnRzXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ubGVhZGluZ19jb21tZW50cykKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6bXV0YWJsZV9sZWFkaW5nX2NvbW1lbnRzKCkgeworICBzZXRfaGFzX2xlYWRpbmdfY29tbWVudHMoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLmxlYWRpbmdfY29tbWVudHMpCisgIHJldHVybiBsZWFkaW5nX2NvbW1lbnRzXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpyZWxlYXNlX2xlYWRpbmdfY29tbWVudHMoKSB7CisgIGNsZWFyX2hhc19sZWFkaW5nX2NvbW1lbnRzKCk7CisgIHJldHVybiBsZWFkaW5nX2NvbW1lbnRzXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OnNldF9hbGxvY2F0ZWRfbGVhZGluZ19jb21tZW50cyg6OnN0ZDo6c3RyaW5nKiBsZWFkaW5nX2NvbW1lbnRzKSB7CisgIGlmIChsZWFkaW5nX2NvbW1lbnRzICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX2xlYWRpbmdfY29tbWVudHMoKTsKKyAgfSBlbHNlIHsKKyAgICBjbGVhcl9oYXNfbGVhZGluZ19jb21tZW50cygpOworICB9CisgIGxlYWRpbmdfY29tbWVudHNfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBsZWFkaW5nX2NvbW1lbnRzKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLmxlYWRpbmdfY29tbWVudHMpCit9CisKKy8vIG9wdGlvbmFsIHN0cmluZyB0cmFpbGluZ19jb21tZW50cyA9IDQ7CitpbmxpbmUgYm9vbCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6aGFzX3RyYWlsaW5nX2NvbW1lbnRzKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDA4dSkgIT0gMDsKK30KK2lubGluZSB2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpzZXRfaGFzX3RyYWlsaW5nX2NvbW1lbnRzKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDh1OworfQoraW5saW5lIHZvaWQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OmNsZWFyX2hhc190cmFpbGluZ19jb21tZW50cygpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwOHU7Cit9CitpbmxpbmUgdm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6Y2xlYXJfdHJhaWxpbmdfY29tbWVudHMoKSB7CisgIHRyYWlsaW5nX2NvbW1lbnRzXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGNsZWFyX2hhc190cmFpbGluZ19jb21tZW50cygpOworfQoraW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjp0cmFpbGluZ19jb21tZW50cygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24udHJhaWxpbmdfY29tbWVudHMpCisgIHJldHVybiB0cmFpbGluZ19jb21tZW50c18uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OnNldF90cmFpbGluZ19jb21tZW50cyhjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBzZXRfaGFzX3RyYWlsaW5nX2NvbW1lbnRzKCk7CisgIHRyYWlsaW5nX2NvbW1lbnRzXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi50cmFpbGluZ19jb21tZW50cykKK30KK2lubGluZSB2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpzZXRfdHJhaWxpbmdfY29tbWVudHMoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgc2V0X2hhc190cmFpbGluZ19jb21tZW50cygpOworICB0cmFpbGluZ19jb21tZW50c18uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi50cmFpbGluZ19jb21tZW50cykKK30KK2lubGluZSB2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpzZXRfdHJhaWxpbmdfY29tbWVudHMoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIHNldF9oYXNfdHJhaWxpbmdfY29tbWVudHMoKTsKKyAgdHJhaWxpbmdfY29tbWVudHNfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi50cmFpbGluZ19jb21tZW50cykKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6bXV0YWJsZV90cmFpbGluZ19jb21tZW50cygpIHsKKyAgc2V0X2hhc190cmFpbGluZ19jb21tZW50cygpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24udHJhaWxpbmdfY29tbWVudHMpCisgIHJldHVybiB0cmFpbGluZ19jb21tZW50c18uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6cmVsZWFzZV90cmFpbGluZ19jb21tZW50cygpIHsKKyAgY2xlYXJfaGFzX3RyYWlsaW5nX2NvbW1lbnRzKCk7CisgIHJldHVybiB0cmFpbGluZ19jb21tZW50c18uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpzZXRfYWxsb2NhdGVkX3RyYWlsaW5nX2NvbW1lbnRzKDo6c3RkOjpzdHJpbmcqIHRyYWlsaW5nX2NvbW1lbnRzKSB7CisgIGlmICh0cmFpbGluZ19jb21tZW50cyAhPSBOVUxMKSB7CisgICAgc2V0X2hhc190cmFpbGluZ19jb21tZW50cygpOworICB9IGVsc2UgeworICAgIGNsZWFyX2hhc190cmFpbGluZ19jb21tZW50cygpOworICB9CisgIHRyYWlsaW5nX2NvbW1lbnRzXy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdHJhaWxpbmdfY29tbWVudHMpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24udHJhaWxpbmdfY29tbWVudHMpCit9CisKKy8vIHJlcGVhdGVkIHN0cmluZyBsZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzID0gNjsKK2lubGluZSBpbnQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OmxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHNfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIGxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHNfLnNpemUoKTsKK30KK2lubGluZSB2b2lkIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpjbGVhcl9sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKCkgeworICBsZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzXy5DbGVhcigpOworfQoraW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjpsZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKQorICByZXR1cm4gbGVhZGluZ19kZXRhY2hlZF9jb21tZW50c18uR2V0KGluZGV4KTsKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6bXV0YWJsZV9sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ubGVhZGluZ19kZXRhY2hlZF9jb21tZW50cykKKyAgcmV0dXJuIGxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHNfLk11dGFibGUoaW5kZXgpOworfQoraW5saW5lIHZvaWQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OnNldF9sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKGludCBpbmRleCwgY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ubGVhZGluZ19kZXRhY2hlZF9jb21tZW50cykKKyAgbGVhZGluZ19kZXRhY2hlZF9jb21tZW50c18uTXV0YWJsZShpbmRleCktPmFzc2lnbih2YWx1ZSk7Cit9CitpbmxpbmUgdm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6c2V0X2xlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMoaW50IGluZGV4LCBjb25zdCBjaGFyKiB2YWx1ZSkgeworICBsZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzXy5NdXRhYmxlKGluZGV4KS0+YXNzaWduKHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKQorfQoraW5saW5lIHZvaWQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OnNldF9sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKGludCBpbmRleCwgY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIGxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHNfLk11dGFibGUoaW5kZXgpLT5hc3NpZ24oCisgICAgcmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKQorfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uOjphZGRfbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cygpIHsKKyAgcmV0dXJuIGxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHNfLkFkZCgpOworfQoraW5saW5lIHZvaWQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OmFkZF9sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIGxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHNfLkFkZCgpLT5hc3NpZ24odmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKQorfQoraW5saW5lIHZvaWQgU291cmNlQ29kZUluZm9fTG9jYXRpb246OmFkZF9sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIGxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHNfLkFkZCgpLT5hc3NpZ24odmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkX2NoYXI6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLmxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMpCit9CitpbmxpbmUgdm9pZCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6YWRkX2xlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIGxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHNfLkFkZCgpLT5hc3NpZ24ocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbi5sZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzKQorfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpzdGQ6OnN0cmluZz4mCitTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbjo6bGVhZGluZ19kZXRhY2hlZF9jb21tZW50cygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLmxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMpCisgIHJldHVybiBsZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzXzsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6c3RkOjpzdHJpbmc+KgorU291cmNlQ29kZUluZm9fTG9jYXRpb246Om11dGFibGVfbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cygpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ubGVhZGluZ19kZXRhY2hlZF9jb21tZW50cykKKyAgcmV0dXJuICZsZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzXzsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBTb3VyY2VDb2RlSW5mbworCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uIGxvY2F0aW9uID0gMTsKK2lubGluZSBpbnQgU291cmNlQ29kZUluZm86OmxvY2F0aW9uX3NpemUoKSBjb25zdCB7CisgIHJldHVybiBsb2NhdGlvbl8uc2l6ZSgpOworfQoraW5saW5lIHZvaWQgU291cmNlQ29kZUluZm86OmNsZWFyX2xvY2F0aW9uKCkgeworICBsb2NhdGlvbl8uQ2xlYXIoKTsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uJiBTb3VyY2VDb2RlSW5mbzo6bG9jYXRpb24oaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLmxvY2F0aW9uKQorICByZXR1cm4gbG9jYXRpb25fLkdldChpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbiogU291cmNlQ29kZUluZm86Om11dGFibGVfbG9jYXRpb24oaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5sb2NhdGlvbikKKyAgcmV0dXJuIGxvY2F0aW9uXy5NdXRhYmxlKGluZGV4KTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uKiBTb3VyY2VDb2RlSW5mbzo6YWRkX2xvY2F0aW9uKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5sb2NhdGlvbikKKyAgcmV0dXJuIGxvY2F0aW9uXy5BZGQoKTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29kZUluZm9fTG9jYXRpb24gPioKK1NvdXJjZUNvZGVJbmZvOjptdXRhYmxlX2xvY2F0aW9uKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5sb2NhdGlvbikKKyAgcmV0dXJuICZsb2NhdGlvbl87Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uID4mCitTb3VyY2VDb2RlSW5mbzo6bG9jYXRpb24oKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5sb2NhdGlvbikKKyAgcmV0dXJuIGxvY2F0aW9uXzsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uCisKKy8vIHJlcGVhdGVkIGludDMyIHBhdGggPSAxIFtwYWNrZWQgPSB0cnVlXTsKK2lubGluZSBpbnQgR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbjo6cGF0aF9zaXplKCkgY29uc3QgeworICByZXR1cm4gcGF0aF8uc2l6ZSgpOworfQoraW5saW5lIHZvaWQgR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbjo6Y2xlYXJfcGF0aCgpIHsKKyAgcGF0aF8uQ2xlYXIoKTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb246OnBhdGgoaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZENvZGVJbmZvLkFubm90YXRpb24ucGF0aCkKKyAgcmV0dXJuIHBhdGhfLkdldChpbmRleCk7Cit9CitpbmxpbmUgdm9pZCBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uOjpzZXRfcGF0aChpbnQgaW5kZXgsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgdmFsdWUpIHsKKyAgcGF0aF8uU2V0KGluZGV4LCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZENvZGVJbmZvLkFubm90YXRpb24ucGF0aCkKK30KK2lubGluZSB2b2lkIEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb246OmFkZF9wYXRoKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgdmFsdWUpIHsKKyAgcGF0aF8uQWRkKHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8uQW5ub3RhdGlvbi5wYXRoKQorfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiA+JgorR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbjo6cGF0aCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZENvZGVJbmZvLkFubm90YXRpb24ucGF0aCkKKyAgcmV0dXJuIHBhdGhfOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiA+KgorR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbjo6bXV0YWJsZV9wYXRoKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRDb2RlSW5mby5Bbm5vdGF0aW9uLnBhdGgpCisgIHJldHVybiAmcGF0aF87Cit9CisKKy8vIG9wdGlvbmFsIHN0cmluZyBzb3VyY2VfZmlsZSA9IDI7CitpbmxpbmUgYm9vbCBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uOjpoYXNfc291cmNlX2ZpbGUoKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDJ1KSAhPSAwOworfQoraW5saW5lIHZvaWQgR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbjo6c2V0X2hhc19zb3VyY2VfZmlsZSgpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAydTsKK30KK2lubGluZSB2b2lkIEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb246OmNsZWFyX2hhc19zb3VyY2VfZmlsZSgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwMnU7Cit9CitpbmxpbmUgdm9pZCBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uOjpjbGVhcl9zb3VyY2VfZmlsZSgpIHsKKyAgc291cmNlX2ZpbGVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgY2xlYXJfaGFzX3NvdXJjZV9maWxlKCk7Cit9CitpbmxpbmUgY29uc3QgOjpzdGQ6OnN0cmluZyYgR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbjo6c291cmNlX2ZpbGUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZENvZGVJbmZvLkFubm90YXRpb24uc291cmNlX2ZpbGUpCisgIHJldHVybiBzb3VyY2VfZmlsZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbjo6c2V0X3NvdXJjZV9maWxlKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHNldF9oYXNfc291cmNlX2ZpbGUoKTsKKyAgc291cmNlX2ZpbGVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZENvZGVJbmZvLkFubm90YXRpb24uc291cmNlX2ZpbGUpCit9CitpbmxpbmUgdm9pZCBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uOjpzZXRfc291cmNlX2ZpbGUoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgc2V0X2hhc19zb3VyY2VfZmlsZSgpOworICBzb3VyY2VfZmlsZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRDb2RlSW5mby5Bbm5vdGF0aW9uLnNvdXJjZV9maWxlKQorfQoraW5saW5lIHZvaWQgR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbjo6c2V0X3NvdXJjZV9maWxlKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBzZXRfaGFzX3NvdXJjZV9maWxlKCk7CisgIHNvdXJjZV9maWxlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8uQW5ub3RhdGlvbi5zb3VyY2VfZmlsZSkKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uOjptdXRhYmxlX3NvdXJjZV9maWxlKCkgeworICBzZXRfaGFzX3NvdXJjZV9maWxlKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRDb2RlSW5mby5Bbm5vdGF0aW9uLnNvdXJjZV9maWxlKQorICByZXR1cm4gc291cmNlX2ZpbGVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbjo6cmVsZWFzZV9zb3VyY2VfZmlsZSgpIHsKKyAgY2xlYXJfaGFzX3NvdXJjZV9maWxlKCk7CisgIHJldHVybiBzb3VyY2VfZmlsZV8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb246OnNldF9hbGxvY2F0ZWRfc291cmNlX2ZpbGUoOjpzdGQ6OnN0cmluZyogc291cmNlX2ZpbGUpIHsKKyAgaWYgKHNvdXJjZV9maWxlICE9IE5VTEwpIHsKKyAgICBzZXRfaGFzX3NvdXJjZV9maWxlKCk7CisgIH0gZWxzZSB7CisgICAgY2xlYXJfaGFzX3NvdXJjZV9maWxlKCk7CisgIH0KKyAgc291cmNlX2ZpbGVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBzb3VyY2VfZmlsZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRDb2RlSW5mby5Bbm5vdGF0aW9uLnNvdXJjZV9maWxlKQorfQorCisvLyBvcHRpb25hbCBpbnQzMiBiZWdpbiA9IDM7CitpbmxpbmUgYm9vbCBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uOjpoYXNfYmVnaW4oKSBjb25zdCB7CisgIHJldHVybiAoX2hhc19iaXRzX1swXSAmIDB4MDAwMDAwMDR1KSAhPSAwOworfQoraW5saW5lIHZvaWQgR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbjo6c2V0X2hhc19iZWdpbigpIHsKKyAgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDA0dTsKK30KK2lubGluZSB2b2lkIEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb246OmNsZWFyX2hhc19iZWdpbigpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwNHU7Cit9CitpbmxpbmUgdm9pZCBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uOjpjbGVhcl9iZWdpbigpIHsKKyAgYmVnaW5fID0gMDsKKyAgY2xlYXJfaGFzX2JlZ2luKCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uOjpiZWdpbigpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8uQW5ub3RhdGlvbi5iZWdpbikKKyAgcmV0dXJuIGJlZ2luXzsKK30KK2lubGluZSB2b2lkIEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb246OnNldF9iZWdpbig6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKSB7CisgIHNldF9oYXNfYmVnaW4oKTsKKyAgYmVnaW5fID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZENvZGVJbmZvLkFubm90YXRpb24uYmVnaW4pCit9CisKKy8vIG9wdGlvbmFsIGludDMyIGVuZCA9IDQ7CitpbmxpbmUgYm9vbCBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uOjpoYXNfZW5kKCkgY29uc3QgeworICByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDA4dSkgIT0gMDsKK30KK2lubGluZSB2b2lkIEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb246OnNldF9oYXNfZW5kKCkgeworICBfaGFzX2JpdHNfWzBdIHw9IDB4MDAwMDAwMDh1OworfQoraW5saW5lIHZvaWQgR2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbjo6Y2xlYXJfaGFzX2VuZCgpIHsKKyAgX2hhc19iaXRzX1swXSAmPSB+MHgwMDAwMDAwOHU7Cit9CitpbmxpbmUgdm9pZCBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uOjpjbGVhcl9lbmQoKSB7CisgIGVuZF8gPSAwOworICBjbGVhcl9oYXNfZW5kKCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiBHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uOjplbmQoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZENvZGVJbmZvLkFubm90YXRpb24uZW5kKQorICByZXR1cm4gZW5kXzsKK30KK2lubGluZSB2b2lkIEdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb246OnNldF9lbmQoOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiB2YWx1ZSkgeworICBzZXRfaGFzX2VuZCgpOworICBlbmRfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZENvZGVJbmZvLkFubm90YXRpb24uZW5kKQorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIEdlbmVyYXRlZENvZGVJbmZvCisKKy8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8uQW5ub3RhdGlvbiBhbm5vdGF0aW9uID0gMTsKK2lubGluZSBpbnQgR2VuZXJhdGVkQ29kZUluZm86OmFubm90YXRpb25fc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIGFubm90YXRpb25fLnNpemUoKTsKK30KK2lubGluZSB2b2lkIEdlbmVyYXRlZENvZGVJbmZvOjpjbGVhcl9hbm5vdGF0aW9uKCkgeworICBhbm5vdGF0aW9uXy5DbGVhcigpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6R2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbiYgR2VuZXJhdGVkQ29kZUluZm86OmFubm90YXRpb24oaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZENvZGVJbmZvLmFubm90YXRpb24pCisgIHJldHVybiBhbm5vdGF0aW9uXy5HZXQoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6R2VuZXJhdGVkQ29kZUluZm9fQW5ub3RhdGlvbiogR2VuZXJhdGVkQ29kZUluZm86Om11dGFibGVfYW5ub3RhdGlvbihpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZENvZGVJbmZvLmFubm90YXRpb24pCisgIHJldHVybiBhbm5vdGF0aW9uXy5NdXRhYmxlKGluZGV4KTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkdlbmVyYXRlZENvZGVJbmZvX0Fubm90YXRpb24qIEdlbmVyYXRlZENvZGVJbmZvOjphZGRfYW5ub3RhdGlvbigpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8uYW5ub3RhdGlvbikKKyAgcmV0dXJuIGFubm90YXRpb25fLkFkZCgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uID4qCitHZW5lcmF0ZWRDb2RlSW5mbzo6bXV0YWJsZV9hbm5vdGF0aW9uKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRDb2RlSW5mby5hbm5vdGF0aW9uKQorICByZXR1cm4gJmFubm90YXRpb25fOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpHZW5lcmF0ZWRDb2RlSW5mb19Bbm5vdGF0aW9uID4mCitHZW5lcmF0ZWRDb2RlSW5mbzo6YW5ub3RhdGlvbigpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZENvZGVJbmZvLmFubm90YXRpb24pCisgIHJldHVybiBhbm5vdGF0aW9uXzsKK30KKworI2VuZGlmICAvLyAhUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworCisvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobmFtZXNwYWNlX3Njb3BlKQorCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI2lmbmRlZiBTV0lHCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKK3RlbXBsYXRlIDw+IHN0cnVjdCBpc19wcm90b19lbnVtPCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGU+IDogOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6dHJ1ZV90eXBlIHt9OwordGVtcGxhdGUgPD4KK2lubGluZSBjb25zdCBFbnVtRGVzY3JpcHRvciogR2V0RW51bURlc2NyaXB0b3I8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG9fVHlwZT4oKSB7CisgIHJldHVybiA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvclByb3RvX1R5cGVfZGVzY3JpcHRvcigpOworfQordGVtcGxhdGUgPD4gc3RydWN0IGlzX3Byb3RvX2VudW08IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWw+IDogOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6dHJ1ZV90eXBlIHt9OwordGVtcGxhdGUgPD4KK2lubGluZSBjb25zdCBFbnVtRGVzY3JpcHRvciogR2V0RW51bURlc2NyaXB0b3I8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yUHJvdG9fTGFiZWw+KCkgeworICByZXR1cm4gOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3JQcm90b19MYWJlbF9kZXNjcmlwdG9yKCk7Cit9Cit0ZW1wbGF0ZSA8PiBzdHJ1Y3QgaXNfcHJvdG9fZW51bTwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlT3B0aW9uc19PcHRpbWl6ZU1vZGU+IDogOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6dHJ1ZV90eXBlIHt9OwordGVtcGxhdGUgPD4KK2lubGluZSBjb25zdCBFbnVtRGVzY3JpcHRvciogR2V0RW51bURlc2NyaXB0b3I8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlPigpIHsKKyAgcmV0dXJuIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZU9wdGlvbnNfT3B0aW1pemVNb2RlX2Rlc2NyaXB0b3IoKTsKK30KK3RlbXBsYXRlIDw+IHN0cnVjdCBpc19wcm90b19lbnVtPCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkT3B0aW9uc19DVHlwZT4gOiA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjp0cnVlX3R5cGUge307Cit0ZW1wbGF0ZSA8PgoraW5saW5lIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBHZXRFbnVtRGVzY3JpcHRvcjwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZE9wdGlvbnNfQ1R5cGU+KCkgeworICByZXR1cm4gOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZE9wdGlvbnNfQ1R5cGVfZGVzY3JpcHRvcigpOworfQordGVtcGxhdGUgPD4gc3RydWN0IGlzX3Byb3RvX2VudW08IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGRPcHRpb25zX0pTVHlwZT4gOiA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjp0cnVlX3R5cGUge307Cit0ZW1wbGF0ZSA8PgoraW5saW5lIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBHZXRFbnVtRGVzY3JpcHRvcjwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZE9wdGlvbnNfSlNUeXBlPigpIHsKKyAgcmV0dXJuIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGRPcHRpb25zX0pTVHlwZV9kZXNjcmlwdG9yKCk7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBTV0lHCisKKy8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChnbG9iYWxfc2NvcGUpCisKKyNlbmRpZiAgLy8gUFJPVE9CVUZfZ29vZ2xlXzJmcHJvdG9idWZfMmZkZXNjcmlwdG9yXzJlcHJvdG9fX0lOQ0xVREVECmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8gYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2U2NjRkNQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90bwpAQCAtMCwwICsxLDgwNSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorLy8KKy8vIFRoZSBtZXNzYWdlcyBpbiB0aGlzIGZpbGUgZGVzY3JpYmUgdGhlIGRlZmluaXRpb25zIGZvdW5kIGluIC5wcm90byBmaWxlcy4KKy8vIEEgdmFsaWQgLnByb3RvIGZpbGUgY2FuIGJlIHRyYW5zbGF0ZWQgZGlyZWN0bHkgdG8gYSBGaWxlRGVzY3JpcHRvclByb3RvCisvLyB3aXRob3V0IGFueSBvdGhlciBpbmZvcm1hdGlvbiAoZS5nLiB3aXRob3V0IHJlYWRpbmcgaXRzIGltcG9ydHMpLgorCisKK3N5bnRheCA9ICJwcm90bzIiOworCitwYWNrYWdlIGdvb2dsZS5wcm90b2J1ZjsKK29wdGlvbiBnb19wYWNrYWdlID0gImRlc2NyaXB0b3IiOworb3B0aW9uIGphdmFfcGFja2FnZSA9ICJjb20uZ29vZ2xlLnByb3RvYnVmIjsKK29wdGlvbiBqYXZhX291dGVyX2NsYXNzbmFtZSA9ICJEZXNjcmlwdG9yUHJvdG9zIjsKK29wdGlvbiBjc2hhcnBfbmFtZXNwYWNlID0gIkdvb2dsZS5Qcm90b2J1Zi5SZWZsZWN0aW9uIjsKK29wdGlvbiBvYmpjX2NsYXNzX3ByZWZpeCA9ICJHUEIiOworCisvLyBkZXNjcmlwdG9yLnByb3RvIG11c3QgYmUgb3B0aW1pemVkIGZvciBzcGVlZCBiZWNhdXNlIHJlZmxlY3Rpb24tYmFzZWQKKy8vIGFsZ29yaXRobXMgZG9uJ3Qgd29yayBkdXJpbmcgYm9vdHN0cmFwcGluZy4KK29wdGlvbiBvcHRpbWl6ZV9mb3IgPSBTUEVFRDsKKworLy8gVGhlIHByb3RvY29sIGNvbXBpbGVyIGNhbiBvdXRwdXQgYSBGaWxlRGVzY3JpcHRvclNldCBjb250YWluaW5nIHRoZSAucHJvdG8KKy8vIGZpbGVzIGl0IHBhcnNlcy4KK21lc3NhZ2UgRmlsZURlc2NyaXB0b3JTZXQgeworICByZXBlYXRlZCBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGUgPSAxOworfQorCisvLyBEZXNjcmliZXMgYSBjb21wbGV0ZSAucHJvdG8gZmlsZS4KK21lc3NhZ2UgRmlsZURlc2NyaXB0b3JQcm90byB7CisgIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsgICAgICAgLy8gZmlsZSBuYW1lLCByZWxhdGl2ZSB0byByb290IG9mIHNvdXJjZSB0cmVlCisgIG9wdGlvbmFsIHN0cmluZyBwYWNrYWdlID0gMjsgICAgLy8gZS5nLiAiZm9vIiwgImZvby5iYXIiLCBldGMuCisKKyAgLy8gTmFtZXMgb2YgZmlsZXMgaW1wb3J0ZWQgYnkgdGhpcyBmaWxlLgorICByZXBlYXRlZCBzdHJpbmcgZGVwZW5kZW5jeSA9IDM7CisgIC8vIEluZGV4ZXMgb2YgdGhlIHB1YmxpYyBpbXBvcnRlZCBmaWxlcyBpbiB0aGUgZGVwZW5kZW5jeSBsaXN0IGFib3ZlLgorICByZXBlYXRlZCBpbnQzMiBwdWJsaWNfZGVwZW5kZW5jeSA9IDEwOworICAvLyBJbmRleGVzIG9mIHRoZSB3ZWFrIGltcG9ydGVkIGZpbGVzIGluIHRoZSBkZXBlbmRlbmN5IGxpc3QuCisgIC8vIEZvciBHb29nbGUtaW50ZXJuYWwgbWlncmF0aW9uIG9ubHkuIERvIG5vdCB1c2UuCisgIHJlcGVhdGVkIGludDMyIHdlYWtfZGVwZW5kZW5jeSA9IDExOworCisgIC8vIEFsbCB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgaW4gdGhpcyBmaWxlLgorICByZXBlYXRlZCBEZXNjcmlwdG9yUHJvdG8gbWVzc2FnZV90eXBlID0gNDsKKyAgcmVwZWF0ZWQgRW51bURlc2NyaXB0b3JQcm90byBlbnVtX3R5cGUgPSA1OworICByZXBlYXRlZCBTZXJ2aWNlRGVzY3JpcHRvclByb3RvIHNlcnZpY2UgPSA2OworICByZXBlYXRlZCBGaWVsZERlc2NyaXB0b3JQcm90byBleHRlbnNpb24gPSA3OworCisgIG9wdGlvbmFsIEZpbGVPcHRpb25zIG9wdGlvbnMgPSA4OworCisgIC8vIFRoaXMgZmllbGQgY29udGFpbnMgb3B0aW9uYWwgaW5mb3JtYXRpb24gYWJvdXQgdGhlIG9yaWdpbmFsIHNvdXJjZSBjb2RlLgorICAvLyBZb3UgbWF5IHNhZmVseSByZW1vdmUgdGhpcyBlbnRpcmUgZmllbGQgd2l0aG91dCBoYXJtaW5nIHJ1bnRpbWUKKyAgLy8gZnVuY3Rpb25hbGl0eSBvZiB0aGUgZGVzY3JpcHRvcnMgLS0gdGhlIGluZm9ybWF0aW9uIGlzIG5lZWRlZCBvbmx5IGJ5CisgIC8vIGRldmVsb3BtZW50IHRvb2xzLgorICBvcHRpb25hbCBTb3VyY2VDb2RlSW5mbyBzb3VyY2VfY29kZV9pbmZvID0gOTsKKworICAvLyBUaGUgc3ludGF4IG9mIHRoZSBwcm90byBmaWxlLgorICAvLyBUaGUgc3VwcG9ydGVkIHZhbHVlcyBhcmUgInByb3RvMiIgYW5kICJwcm90bzMiLgorICBvcHRpb25hbCBzdHJpbmcgc3ludGF4ID0gMTI7Cit9CisKKy8vIERlc2NyaWJlcyBhIG1lc3NhZ2UgdHlwZS4KK21lc3NhZ2UgRGVzY3JpcHRvclByb3RvIHsKKyAgb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworCisgIHJlcGVhdGVkIEZpZWxkRGVzY3JpcHRvclByb3RvIGZpZWxkID0gMjsKKyAgcmVwZWF0ZWQgRmllbGREZXNjcmlwdG9yUHJvdG8gZXh0ZW5zaW9uID0gNjsKKworICByZXBlYXRlZCBEZXNjcmlwdG9yUHJvdG8gbmVzdGVkX3R5cGUgPSAzOworICByZXBlYXRlZCBFbnVtRGVzY3JpcHRvclByb3RvIGVudW1fdHlwZSA9IDQ7CisKKyAgbWVzc2FnZSBFeHRlbnNpb25SYW5nZSB7CisgICAgb3B0aW9uYWwgaW50MzIgc3RhcnQgPSAxOworICAgIG9wdGlvbmFsIGludDMyIGVuZCA9IDI7CisgIH0KKyAgcmVwZWF0ZWQgRXh0ZW5zaW9uUmFuZ2UgZXh0ZW5zaW9uX3JhbmdlID0gNTsKKworICByZXBlYXRlZCBPbmVvZkRlc2NyaXB0b3JQcm90byBvbmVvZl9kZWNsID0gODsKKworICBvcHRpb25hbCBNZXNzYWdlT3B0aW9ucyBvcHRpb25zID0gNzsKKworICAvLyBSYW5nZSBvZiByZXNlcnZlZCB0YWcgbnVtYmVycy4gUmVzZXJ2ZWQgdGFnIG51bWJlcnMgbWF5IG5vdCBiZSB1c2VkIGJ5CisgIC8vIGZpZWxkcyBvciBleHRlbnNpb24gcmFuZ2VzIGluIHRoZSBzYW1lIG1lc3NhZ2UuIFJlc2VydmVkIHJhbmdlcyBtYXkKKyAgLy8gbm90IG92ZXJsYXAuCisgIG1lc3NhZ2UgUmVzZXJ2ZWRSYW5nZSB7CisgICAgb3B0aW9uYWwgaW50MzIgc3RhcnQgPSAxOyAvLyBJbmNsdXNpdmUuCisgICAgb3B0aW9uYWwgaW50MzIgZW5kID0gMjsgICAvLyBFeGNsdXNpdmUuCisgIH0KKyAgcmVwZWF0ZWQgUmVzZXJ2ZWRSYW5nZSByZXNlcnZlZF9yYW5nZSA9IDk7CisgIC8vIFJlc2VydmVkIGZpZWxkIG5hbWVzLCB3aGljaCBtYXkgbm90IGJlIHVzZWQgYnkgZmllbGRzIGluIHRoZSBzYW1lIG1lc3NhZ2UuCisgIC8vIEEgZ2l2ZW4gbmFtZSBtYXkgb25seSBiZSByZXNlcnZlZCBvbmNlLgorICByZXBlYXRlZCBzdHJpbmcgcmVzZXJ2ZWRfbmFtZSA9IDEwOworfQorCisvLyBEZXNjcmliZXMgYSBmaWVsZCB3aXRoaW4gYSBtZXNzYWdlLgorbWVzc2FnZSBGaWVsZERlc2NyaXB0b3JQcm90byB7CisgIGVudW0gVHlwZSB7CisgICAgLy8gMCBpcyByZXNlcnZlZCBmb3IgZXJyb3JzLgorICAgIC8vIE9yZGVyIGlzIHdlaXJkIGZvciBoaXN0b3JpY2FsIHJlYXNvbnMuCisgICAgVFlQRV9ET1VCTEUgICAgICAgICA9IDE7CisgICAgVFlQRV9GTE9BVCAgICAgICAgICA9IDI7CisgICAgLy8gTm90IFppZ1phZyBlbmNvZGVkLiAgTmVnYXRpdmUgbnVtYmVycyB0YWtlIDEwIGJ5dGVzLiAgVXNlIFRZUEVfU0lOVDY0IGlmCisgICAgLy8gbmVnYXRpdmUgdmFsdWVzIGFyZSBsaWtlbHkuCisgICAgVFlQRV9JTlQ2NCAgICAgICAgICA9IDM7CisgICAgVFlQRV9VSU5UNjQgICAgICAgICA9IDQ7CisgICAgLy8gTm90IFppZ1phZyBlbmNvZGVkLiAgTmVnYXRpdmUgbnVtYmVycyB0YWtlIDEwIGJ5dGVzLiAgVXNlIFRZUEVfU0lOVDMyIGlmCisgICAgLy8gbmVnYXRpdmUgdmFsdWVzIGFyZSBsaWtlbHkuCisgICAgVFlQRV9JTlQzMiAgICAgICAgICA9IDU7CisgICAgVFlQRV9GSVhFRDY0ICAgICAgICA9IDY7CisgICAgVFlQRV9GSVhFRDMyICAgICAgICA9IDc7CisgICAgVFlQRV9CT09MICAgICAgICAgICA9IDg7CisgICAgVFlQRV9TVFJJTkcgICAgICAgICA9IDk7CisgICAgVFlQRV9HUk9VUCAgICAgICAgICA9IDEwOyAgLy8gVGFnLWRlbGltaXRlZCBhZ2dyZWdhdGUuCisgICAgVFlQRV9NRVNTQUdFICAgICAgICA9IDExOyAgLy8gTGVuZ3RoLWRlbGltaXRlZCBhZ2dyZWdhdGUuCisKKyAgICAvLyBOZXcgaW4gdmVyc2lvbiAyLgorICAgIFRZUEVfQllURVMgICAgICAgICAgPSAxMjsKKyAgICBUWVBFX1VJTlQzMiAgICAgICAgID0gMTM7CisgICAgVFlQRV9FTlVNICAgICAgICAgICA9IDE0OworICAgIFRZUEVfU0ZJWEVEMzIgICAgICAgPSAxNTsKKyAgICBUWVBFX1NGSVhFRDY0ICAgICAgID0gMTY7CisgICAgVFlQRV9TSU5UMzIgICAgICAgICA9IDE3OyAgLy8gVXNlcyBaaWdaYWcgZW5jb2RpbmcuCisgICAgVFlQRV9TSU5UNjQgICAgICAgICA9IDE4OyAgLy8gVXNlcyBaaWdaYWcgZW5jb2RpbmcuCisgIH07CisKKyAgZW51bSBMYWJlbCB7CisgICAgLy8gMCBpcyByZXNlcnZlZCBmb3IgZXJyb3JzCisgICAgTEFCRUxfT1BUSU9OQUwgICAgICA9IDE7CisgICAgTEFCRUxfUkVRVUlSRUQgICAgICA9IDI7CisgICAgTEFCRUxfUkVQRUFURUQgICAgICA9IDM7CisgICAgLy8gVE9ETyhzYW5qYXkpOiBTaG91bGQgd2UgYWRkIExBQkVMX01BUD8KKyAgfTsKKworICBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgIG9wdGlvbmFsIGludDMyIG51bWJlciA9IDM7CisgIG9wdGlvbmFsIExhYmVsIGxhYmVsID0gNDsKKworICAvLyBJZiB0eXBlX25hbWUgaXMgc2V0LCB0aGlzIG5lZWQgbm90IGJlIHNldC4gIElmIGJvdGggdGhpcyBhbmQgdHlwZV9uYW1lCisgIC8vIGFyZSBzZXQsIHRoaXMgbXVzdCBiZSBvbmUgb2YgVFlQRV9FTlVNLCBUWVBFX01FU1NBR0Ugb3IgVFlQRV9HUk9VUC4KKyAgb3B0aW9uYWwgVHlwZSB0eXBlID0gNTsKKworICAvLyBGb3IgbWVzc2FnZSBhbmQgZW51bSB0eXBlcywgdGhpcyBpcyB0aGUgbmFtZSBvZiB0aGUgdHlwZS4gIElmIHRoZSBuYW1lCisgIC8vIHN0YXJ0cyB3aXRoIGEgJy4nLCBpdCBpcyBmdWxseS1xdWFsaWZpZWQuICBPdGhlcndpc2UsIEMrKy1saWtlIHNjb3BpbmcKKyAgLy8gcnVsZXMgYXJlIHVzZWQgdG8gZmluZCB0aGUgdHlwZSAoaS5lLiBmaXJzdCB0aGUgbmVzdGVkIHR5cGVzIHdpdGhpbiB0aGlzCisgIC8vIG1lc3NhZ2UgYXJlIHNlYXJjaGVkLCB0aGVuIHdpdGhpbiB0aGUgcGFyZW50LCBvbiB1cCB0byB0aGUgcm9vdAorICAvLyBuYW1lc3BhY2UpLgorICBvcHRpb25hbCBzdHJpbmcgdHlwZV9uYW1lID0gNjsKKworICAvLyBGb3IgZXh0ZW5zaW9ucywgdGhpcyBpcyB0aGUgbmFtZSBvZiB0aGUgdHlwZSBiZWluZyBleHRlbmRlZC4gIEl0IGlzCisgIC8vIHJlc29sdmVkIGluIHRoZSBzYW1lIG1hbm5lciBhcyB0eXBlX25hbWUuCisgIG9wdGlvbmFsIHN0cmluZyBleHRlbmRlZSA9IDI7CisKKyAgLy8gRm9yIG51bWVyaWMgdHlwZXMsIGNvbnRhaW5zIHRoZSBvcmlnaW5hbCB0ZXh0IHJlcHJlc2VudGF0aW9uIG9mIHRoZSB2YWx1ZS4KKyAgLy8gRm9yIGJvb2xlYW5zLCAidHJ1ZSIgb3IgImZhbHNlIi4KKyAgLy8gRm9yIHN0cmluZ3MsIGNvbnRhaW5zIHRoZSBkZWZhdWx0IHRleHQgY29udGVudHMgKG5vdCBlc2NhcGVkIGluIGFueSB3YXkpLgorICAvLyBGb3IgYnl0ZXMsIGNvbnRhaW5zIHRoZSBDIGVzY2FwZWQgdmFsdWUuICBBbGwgYnl0ZXMgPj0gMTI4IGFyZSBlc2NhcGVkLgorICAvLyBUT0RPKGtlbnRvbik6ICBCYXNlLTY0IGVuY29kZT8KKyAgb3B0aW9uYWwgc3RyaW5nIGRlZmF1bHRfdmFsdWUgPSA3OworCisgIC8vIElmIHNldCwgZ2l2ZXMgdGhlIGluZGV4IG9mIGEgb25lb2YgaW4gdGhlIGNvbnRhaW5pbmcgdHlwZSdzIG9uZW9mX2RlY2wKKyAgLy8gbGlzdC4gIFRoaXMgZmllbGQgaXMgYSBtZW1iZXIgb2YgdGhhdCBvbmVvZi4KKyAgb3B0aW9uYWwgaW50MzIgb25lb2ZfaW5kZXggPSA5OworCisgIC8vIEpTT04gbmFtZSBvZiB0aGlzIGZpZWxkLiBUaGUgdmFsdWUgaXMgc2V0IGJ5IHByb3RvY29sIGNvbXBpbGVyLiBJZiB0aGUKKyAgLy8gdXNlciBoYXMgc2V0IGEgImpzb25fbmFtZSIgb3B0aW9uIG9uIHRoaXMgZmllbGQsIHRoYXQgb3B0aW9uJ3MgdmFsdWUKKyAgLy8gd2lsbCBiZSB1c2VkLiBPdGhlcndpc2UsIGl0J3MgZGVkdWNlZCBmcm9tIHRoZSBmaWVsZCdzIG5hbWUgYnkgY29udmVydGluZworICAvLyBpdCB0byBjYW1lbENhc2UuCisgIG9wdGlvbmFsIHN0cmluZyBqc29uX25hbWUgPSAxMDsKKworICBvcHRpb25hbCBGaWVsZE9wdGlvbnMgb3B0aW9ucyA9IDg7Cit9CisKKy8vIERlc2NyaWJlcyBhIG9uZW9mLgorbWVzc2FnZSBPbmVvZkRlc2NyaXB0b3JQcm90byB7CisgIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKK30KKworLy8gRGVzY3JpYmVzIGFuIGVudW0gdHlwZS4KK21lc3NhZ2UgRW51bURlc2NyaXB0b3JQcm90byB7CisgIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKKworICByZXBlYXRlZCBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8gdmFsdWUgPSAyOworCisgIG9wdGlvbmFsIEVudW1PcHRpb25zIG9wdGlvbnMgPSAzOworfQorCisvLyBEZXNjcmliZXMgYSB2YWx1ZSB3aXRoaW4gYW4gZW51bS4KK21lc3NhZ2UgRW51bVZhbHVlRGVzY3JpcHRvclByb3RvIHsKKyAgb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICBvcHRpb25hbCBpbnQzMiBudW1iZXIgPSAyOworCisgIG9wdGlvbmFsIEVudW1WYWx1ZU9wdGlvbnMgb3B0aW9ucyA9IDM7Cit9CisKKy8vIERlc2NyaWJlcyBhIHNlcnZpY2UuCittZXNzYWdlIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG8geworICBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgIHJlcGVhdGVkIE1ldGhvZERlc2NyaXB0b3JQcm90byBtZXRob2QgPSAyOworCisgIG9wdGlvbmFsIFNlcnZpY2VPcHRpb25zIG9wdGlvbnMgPSAzOworfQorCisvLyBEZXNjcmliZXMgYSBtZXRob2Qgb2YgYSBzZXJ2aWNlLgorbWVzc2FnZSBNZXRob2REZXNjcmlwdG9yUHJvdG8geworICBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisKKyAgLy8gSW5wdXQgYW5kIG91dHB1dCB0eXBlIG5hbWVzLiAgVGhlc2UgYXJlIHJlc29sdmVkIGluIHRoZSBzYW1lIHdheSBhcworICAvLyBGaWVsZERlc2NyaXB0b3JQcm90by50eXBlX25hbWUsIGJ1dCBtdXN0IHJlZmVyIHRvIGEgbWVzc2FnZSB0eXBlLgorICBvcHRpb25hbCBzdHJpbmcgaW5wdXRfdHlwZSA9IDI7CisgIG9wdGlvbmFsIHN0cmluZyBvdXRwdXRfdHlwZSA9IDM7CisKKyAgb3B0aW9uYWwgTWV0aG9kT3B0aW9ucyBvcHRpb25zID0gNDsKKworICAvLyBJZGVudGlmaWVzIGlmIGNsaWVudCBzdHJlYW1zIG11bHRpcGxlIGNsaWVudCBtZXNzYWdlcworICBvcHRpb25hbCBib29sIGNsaWVudF9zdHJlYW1pbmcgPSA1IFtkZWZhdWx0PWZhbHNlXTsKKyAgLy8gSWRlbnRpZmllcyBpZiBzZXJ2ZXIgc3RyZWFtcyBtdWx0aXBsZSBzZXJ2ZXIgbWVzc2FnZXMKKyAgb3B0aW9uYWwgYm9vbCBzZXJ2ZXJfc3RyZWFtaW5nID0gNiBbZGVmYXVsdD1mYWxzZV07Cit9CisKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorLy8gT3B0aW9ucworCisvLyBFYWNoIG9mIHRoZSBkZWZpbml0aW9ucyBhYm92ZSBtYXkgaGF2ZSAib3B0aW9ucyIgYXR0YWNoZWQuICBUaGVzZSBhcmUKKy8vIGp1c3QgYW5ub3RhdGlvbnMgd2hpY2ggbWF5IGNhdXNlIGNvZGUgdG8gYmUgZ2VuZXJhdGVkIHNsaWdodGx5IGRpZmZlcmVudGx5CisvLyBvciBtYXkgY29udGFpbiBoaW50cyBmb3IgY29kZSB0aGF0IG1hbmlwdWxhdGVzIHByb3RvY29sIG1lc3NhZ2VzLgorLy8KKy8vIENsaWVudHMgbWF5IGRlZmluZSBjdXN0b20gb3B0aW9ucyBhcyBleHRlbnNpb25zIG9mIHRoZSAqT3B0aW9ucyBtZXNzYWdlcy4KKy8vIFRoZXNlIGV4dGVuc2lvbnMgbWF5IG5vdCB5ZXQgYmUga25vd24gYXQgcGFyc2luZyB0aW1lLCBzbyB0aGUgcGFyc2VyIGNhbm5vdAorLy8gc3RvcmUgdGhlIHZhbHVlcyBpbiB0aGVtLiAgSW5zdGVhZCBpdCBzdG9yZXMgdGhlbSBpbiBhIGZpZWxkIGluIHRoZSAqT3B0aW9ucworLy8gbWVzc2FnZSBjYWxsZWQgdW5pbnRlcnByZXRlZF9vcHRpb24uIFRoaXMgZmllbGQgbXVzdCBoYXZlIHRoZSBzYW1lIG5hbWUKKy8vIGFjcm9zcyBhbGwgKk9wdGlvbnMgbWVzc2FnZXMuIFdlIHRoZW4gdXNlIHRoaXMgZmllbGQgdG8gcG9wdWxhdGUgdGhlCisvLyBleHRlbnNpb25zIHdoZW4gd2UgYnVpbGQgYSBkZXNjcmlwdG9yLCBhdCB3aGljaCBwb2ludCBhbGwgcHJvdG9zIGhhdmUgYmVlbgorLy8gcGFyc2VkIGFuZCBzbyBhbGwgZXh0ZW5zaW9ucyBhcmUga25vd24uCisvLworLy8gRXh0ZW5zaW9uIG51bWJlcnMgZm9yIGN1c3RvbSBvcHRpb25zIG1heSBiZSBjaG9zZW4gYXMgZm9sbG93czoKKy8vICogRm9yIG9wdGlvbnMgd2hpY2ggd2lsbCBvbmx5IGJlIHVzZWQgd2l0aGluIGEgc2luZ2xlIGFwcGxpY2F0aW9uIG9yCisvLyAgIG9yZ2FuaXphdGlvbiwgb3IgZm9yIGV4cGVyaW1lbnRhbCBvcHRpb25zLCB1c2UgZmllbGQgbnVtYmVycyA1MDAwMAorLy8gICB0aHJvdWdoIDk5OTk5LiAgSXQgaXMgdXAgdG8geW91IHRvIGVuc3VyZSB0aGF0IHlvdSBkbyBub3QgdXNlIHRoZQorLy8gICBzYW1lIG51bWJlciBmb3IgbXVsdGlwbGUgb3B0aW9ucy4KKy8vICogRm9yIG9wdGlvbnMgd2hpY2ggd2lsbCBiZSBwdWJsaXNoZWQgYW5kIHVzZWQgcHVibGljbHkgYnkgbXVsdGlwbGUKKy8vICAgaW5kZXBlbmRlbnQgZW50aXRpZXMsIGUtbWFpbCBwcm90b2J1Zi1nbG9iYWwtZXh0ZW5zaW9uLXJlZ2lzdHJ5QGdvb2dsZS5jb20KKy8vICAgdG8gcmVzZXJ2ZSBleHRlbnNpb24gbnVtYmVycy4gU2ltcGx5IHByb3ZpZGUgeW91ciBwcm9qZWN0IG5hbWUgKGUuZy4KKy8vICAgT2JqZWN0aXZlLUMgcGx1Z2luKSBhbmQgeW91ciBwcm9qZWN0IHdlYnNpdGUgKGlmIGF2YWlsYWJsZSkgLS0gdGhlcmUncyBubworLy8gICBuZWVkIHRvIGV4cGxhaW4gaG93IHlvdSBpbnRlbmQgdG8gdXNlIHRoZW0uIFVzdWFsbHkgeW91IG9ubHkgbmVlZCBvbmUKKy8vICAgZXh0ZW5zaW9uIG51bWJlci4gWW91IGNhbiBkZWNsYXJlIG11bHRpcGxlIG9wdGlvbnMgd2l0aCBvbmx5IG9uZSBleHRlbnNpb24KKy8vICAgbnVtYmVyIGJ5IHB1dHRpbmcgdGhlbSBpbiBhIHN1Yi1tZXNzYWdlLiBTZWUgdGhlIEN1c3RvbSBPcHRpb25zIHNlY3Rpb24gb2YKKy8vICAgdGhlIGRvY3MgZm9yIGV4YW1wbGVzOgorLy8gICBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzL2RvY3MvcHJvdG8jb3B0aW9ucworLy8gICBJZiB0aGlzIHR1cm5zIG91dCB0byBiZSBwb3B1bGFyLCBhIHdlYiBzZXJ2aWNlIHdpbGwgYmUgc2V0IHVwCisvLyAgIHRvIGF1dG9tYXRpY2FsbHkgYXNzaWduIG9wdGlvbiBudW1iZXJzLgorCisKK21lc3NhZ2UgRmlsZU9wdGlvbnMgeworCisgIC8vIFNldHMgdGhlIEphdmEgcGFja2FnZSB3aGVyZSBjbGFzc2VzIGdlbmVyYXRlZCBmcm9tIHRoaXMgLnByb3RvIHdpbGwgYmUKKyAgLy8gcGxhY2VkLiAgQnkgZGVmYXVsdCwgdGhlIHByb3RvIHBhY2thZ2UgaXMgdXNlZCwgYnV0IHRoaXMgaXMgb2Z0ZW4KKyAgLy8gaW5hcHByb3ByaWF0ZSBiZWNhdXNlIHByb3RvIHBhY2thZ2VzIGRvIG5vdCBub3JtYWxseSBzdGFydCB3aXRoIGJhY2t3YXJkcworICAvLyBkb21haW4gbmFtZXMuCisgIG9wdGlvbmFsIHN0cmluZyBqYXZhX3BhY2thZ2UgPSAxOworCisKKyAgLy8gSWYgc2V0LCBhbGwgdGhlIGNsYXNzZXMgZnJvbSB0aGUgLnByb3RvIGZpbGUgYXJlIHdyYXBwZWQgaW4gYSBzaW5nbGUKKyAgLy8gb3V0ZXIgY2xhc3Mgd2l0aCB0aGUgZ2l2ZW4gbmFtZS4gIFRoaXMgYXBwbGllcyB0byBib3RoIFByb3RvMQorICAvLyAoZXF1aXZhbGVudCB0byB0aGUgb2xkICItLW9uZV9qYXZhX2ZpbGUiIG9wdGlvbikgYW5kIFByb3RvMiAod2hlcmUKKyAgLy8gYSAucHJvdG8gYWx3YXlzIHRyYW5zbGF0ZXMgdG8gYSBzaW5nbGUgY2xhc3MsIGJ1dCB5b3UgbWF5IHdhbnQgdG8KKyAgLy8gZXhwbGljaXRseSBjaG9vc2UgdGhlIGNsYXNzIG5hbWUpLgorICBvcHRpb25hbCBzdHJpbmcgamF2YV9vdXRlcl9jbGFzc25hbWUgPSA4OworCisgIC8vIElmIHNldCB0cnVlLCB0aGVuIHRoZSBKYXZhIGNvZGUgZ2VuZXJhdG9yIHdpbGwgZ2VuZXJhdGUgYSBzZXBhcmF0ZSAuamF2YQorICAvLyBmaWxlIGZvciBlYWNoIHRvcC1sZXZlbCBtZXNzYWdlLCBlbnVtLCBhbmQgc2VydmljZSBkZWZpbmVkIGluIHRoZSAucHJvdG8KKyAgLy8gZmlsZS4gIFRodXMsIHRoZXNlIHR5cGVzIHdpbGwgKm5vdCogYmUgbmVzdGVkIGluc2lkZSB0aGUgb3V0ZXIgY2xhc3MKKyAgLy8gbmFtZWQgYnkgamF2YV9vdXRlcl9jbGFzc25hbWUuICBIb3dldmVyLCB0aGUgb3V0ZXIgY2xhc3Mgd2lsbCBzdGlsbCBiZQorICAvLyBnZW5lcmF0ZWQgdG8gY29udGFpbiB0aGUgZmlsZSdzIGdldERlc2NyaXB0b3IoKSBtZXRob2QgYXMgd2VsbCBhcyBhbnkKKyAgLy8gdG9wLWxldmVsIGV4dGVuc2lvbnMgZGVmaW5lZCBpbiB0aGUgZmlsZS4KKyAgb3B0aW9uYWwgYm9vbCBqYXZhX211bHRpcGxlX2ZpbGVzID0gMTAgW2RlZmF1bHQ9ZmFsc2VdOworCisgIC8vIElmIHNldCB0cnVlLCB0aGVuIHRoZSBKYXZhIGNvZGUgZ2VuZXJhdG9yIHdpbGwgZ2VuZXJhdGUgZXF1YWxzKCkgYW5kCisgIC8vIGhhc2hDb2RlKCkgbWV0aG9kcyBmb3IgYWxsIG1lc3NhZ2VzIGRlZmluZWQgaW4gdGhlIC5wcm90byBmaWxlLgorICAvLyBUaGlzIGluY3JlYXNlcyBnZW5lcmF0ZWQgY29kZSBzaXplLCBwb3RlbnRpYWxseSBzdWJzdGFudGlhbGx5IGZvciBsYXJnZQorICAvLyBwcm90b3MsIHdoaWNoIG1heSBoYXJtIGEgbWVtb3J5LWNvbnN0cmFpbmVkIGFwcGxpY2F0aW9uLgorICAvLyAtIEluIHRoZSBmdWxsIHJ1bnRpbWUgdGhpcyBpcyBhIHNwZWVkIG9wdGltaXphdGlvbiwgYXMgdGhlCisgIC8vIEFic3RyYWN0TWVzc2FnZSBiYXNlIGNsYXNzIGluY2x1ZGVzIHJlZmxlY3Rpb24tYmFzZWQgaW1wbGVtZW50YXRpb25zIG9mCisgIC8vIHRoZXNlIG1ldGhvZHMuCisgIC8vIC0gSW4gdGhlIGxpdGUgcnVudGltZSwgc2V0dGluZyB0aGlzIG9wdGlvbiBjaGFuZ2VzIHRoZSBzZW1hbnRpY3Mgb2YKKyAgLy8gZXF1YWxzKCkgYW5kIGhhc2hDb2RlKCkgdG8gbW9yZSBjbG9zZWx5IG1hdGNoIHRob3NlIG9mIHRoZSBmdWxsIHJ1bnRpbWU7CisgIC8vIHRoZSBnZW5lcmF0ZWQgbWV0aG9kcyBjb21wdXRlIHRoZWlyIHJlc3VsdHMgYmFzZWQgb24gZmllbGQgdmFsdWVzIHJhdGhlcgorICAvLyB0aGFuIG9iamVjdCBpZGVudGl0eS4gKEltcGxlbWVudGF0aW9ucyBzaG91bGQgbm90IGFzc3VtZSB0aGF0IGhhc2hjb2RlcworICAvLyB3aWxsIGJlIGNvbnNpc3RlbnQgYWNyb3NzIHJ1bnRpbWVzIG9yIHZlcnNpb25zIG9mIHRoZSBwcm90b2NvbCBjb21waWxlci4pCisgIG9wdGlvbmFsIGJvb2wgamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2ggPSAyMCBbZGVmYXVsdD1mYWxzZV07CisKKyAgLy8gSWYgc2V0IHRydWUsIHRoZW4gdGhlIEphdmEyIGNvZGUgZ2VuZXJhdG9yIHdpbGwgZ2VuZXJhdGUgY29kZSB0aGF0CisgIC8vIHRocm93cyBhbiBleGNlcHRpb24gd2hlbmV2ZXIgYW4gYXR0ZW1wdCBpcyBtYWRlIHRvIGFzc2lnbiBhIG5vbi1VVEYtOAorICAvLyBieXRlIHNlcXVlbmNlIHRvIGEgc3RyaW5nIGZpZWxkLgorICAvLyBNZXNzYWdlIHJlZmxlY3Rpb24gd2lsbCBkbyB0aGUgc2FtZS4KKyAgLy8gSG93ZXZlciwgYW4gZXh0ZW5zaW9uIGZpZWxkIHN0aWxsIGFjY2VwdHMgbm9uLVVURi04IGJ5dGUgc2VxdWVuY2VzLgorICAvLyBUaGlzIG9wdGlvbiBoYXMgbm8gZWZmZWN0IG9uIHdoZW4gdXNlZCB3aXRoIHRoZSBsaXRlIHJ1bnRpbWUuCisgIG9wdGlvbmFsIGJvb2wgamF2YV9zdHJpbmdfY2hlY2tfdXRmOCA9IDI3IFtkZWZhdWx0PWZhbHNlXTsKKworCisgIC8vIEdlbmVyYXRlZCBjbGFzc2VzIGNhbiBiZSBvcHRpbWl6ZWQgZm9yIHNwZWVkIG9yIGNvZGUgc2l6ZS4KKyAgZW51bSBPcHRpbWl6ZU1vZGUgeworICAgIFNQRUVEID0gMTsgICAgICAgIC8vIEdlbmVyYXRlIGNvbXBsZXRlIGNvZGUgZm9yIHBhcnNpbmcsIHNlcmlhbGl6YXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgLy8gZXRjLgorICAgIENPREVfU0laRSA9IDI7ICAgIC8vIFVzZSBSZWZsZWN0aW9uT3BzIHRvIGltcGxlbWVudCB0aGVzZSBtZXRob2RzLgorICAgIExJVEVfUlVOVElNRSA9IDM7IC8vIEdlbmVyYXRlIGNvZGUgdXNpbmcgTWVzc2FnZUxpdGUgYW5kIHRoZSBsaXRlIHJ1bnRpbWUuCisgIH0KKyAgb3B0aW9uYWwgT3B0aW1pemVNb2RlIG9wdGltaXplX2ZvciA9IDkgW2RlZmF1bHQ9U1BFRURdOworCisgIC8vIFNldHMgdGhlIEdvIHBhY2thZ2Ugd2hlcmUgc3RydWN0cyBnZW5lcmF0ZWQgZnJvbSB0aGlzIC5wcm90byB3aWxsIGJlCisgIC8vIHBsYWNlZC4gSWYgb21pdHRlZCwgdGhlIEdvIHBhY2thZ2Ugd2lsbCBiZSBkZXJpdmVkIGZyb20gdGhlIGZvbGxvd2luZzoKKyAgLy8gICAtIFRoZSBiYXNlbmFtZSBvZiB0aGUgcGFja2FnZSBpbXBvcnQgcGF0aCwgaWYgcHJvdmlkZWQuCisgIC8vICAgLSBPdGhlcndpc2UsIHRoZSBwYWNrYWdlIHN0YXRlbWVudCBpbiB0aGUgLnByb3RvIGZpbGUsIGlmIHByZXNlbnQuCisgIC8vICAgLSBPdGhlcndpc2UsIHRoZSBiYXNlbmFtZSBvZiB0aGUgLnByb3RvIGZpbGUsIHdpdGhvdXQgZXh0ZW5zaW9uLgorICBvcHRpb25hbCBzdHJpbmcgZ29fcGFja2FnZSA9IDExOworCisKKworICAvLyBTaG91bGQgZ2VuZXJpYyBzZXJ2aWNlcyBiZSBnZW5lcmF0ZWQgaW4gZWFjaCBsYW5ndWFnZT8gICJHZW5lcmljIiBzZXJ2aWNlcworICAvLyBhcmUgbm90IHNwZWNpZmljIHRvIGFueSBwYXJ0aWN1bGFyIFJQQyBzeXN0ZW0uICBUaGV5IGFyZSBnZW5lcmF0ZWQgYnkgdGhlCisgIC8vIG1haW4gY29kZSBnZW5lcmF0b3JzIGluIGVhY2ggbGFuZ3VhZ2UgKHdpdGhvdXQgYWRkaXRpb25hbCBwbHVnaW5zKS4KKyAgLy8gR2VuZXJpYyBzZXJ2aWNlcyB3ZXJlIHRoZSBvbmx5IGtpbmQgb2Ygc2VydmljZSBnZW5lcmF0aW9uIHN1cHBvcnRlZCBieQorICAvLyBlYXJseSB2ZXJzaW9ucyBvZiBnb29nbGUucHJvdG9idWYuCisgIC8vCisgIC8vIEdlbmVyaWMgc2VydmljZXMgYXJlIG5vdyBjb25zaWRlcmVkIGRlcHJlY2F0ZWQgaW4gZmF2b3Igb2YgdXNpbmcgcGx1Z2lucworICAvLyB0aGF0IGdlbmVyYXRlIGNvZGUgc3BlY2lmaWMgdG8geW91ciBwYXJ0aWN1bGFyIFJQQyBzeXN0ZW0uICBUaGVyZWZvcmUsCisgIC8vIHRoZXNlIGRlZmF1bHQgdG8gZmFsc2UuICBPbGQgY29kZSB3aGljaCBkZXBlbmRzIG9uIGdlbmVyaWMgc2VydmljZXMgc2hvdWxkCisgIC8vIGV4cGxpY2l0bHkgc2V0IHRoZW0gdG8gdHJ1ZS4KKyAgb3B0aW9uYWwgYm9vbCBjY19nZW5lcmljX3NlcnZpY2VzID0gMTYgW2RlZmF1bHQ9ZmFsc2VdOworICBvcHRpb25hbCBib29sIGphdmFfZ2VuZXJpY19zZXJ2aWNlcyA9IDE3IFtkZWZhdWx0PWZhbHNlXTsKKyAgb3B0aW9uYWwgYm9vbCBweV9nZW5lcmljX3NlcnZpY2VzID0gMTggW2RlZmF1bHQ9ZmFsc2VdOworCisgIC8vIElzIHRoaXMgZmlsZSBkZXByZWNhdGVkPworICAvLyBEZXBlbmRpbmcgb24gdGhlIHRhcmdldCBwbGF0Zm9ybSwgdGhpcyBjYW4gZW1pdCBEZXByZWNhdGVkIGFubm90YXRpb25zCisgIC8vIGZvciBldmVyeXRoaW5nIGluIHRoZSBmaWxlLCBvciBpdCB3aWxsIGJlIGNvbXBsZXRlbHkgaWdub3JlZDsgaW4gdGhlIHZlcnkKKyAgLy8gbGVhc3QsIHRoaXMgaXMgYSBmb3JtYWxpemF0aW9uIGZvciBkZXByZWNhdGluZyBmaWxlcy4KKyAgb3B0aW9uYWwgYm9vbCBkZXByZWNhdGVkID0gMjMgW2RlZmF1bHQ9ZmFsc2VdOworCisgIC8vIEVuYWJsZXMgdGhlIHVzZSBvZiBhcmVuYXMgZm9yIHRoZSBwcm90byBtZXNzYWdlcyBpbiB0aGlzIGZpbGUuIFRoaXMgYXBwbGllcworICAvLyBvbmx5IHRvIGdlbmVyYXRlZCBjbGFzc2VzIGZvciBDKysuCisgIG9wdGlvbmFsIGJvb2wgY2NfZW5hYmxlX2FyZW5hcyA9IDMxIFtkZWZhdWx0PWZhbHNlXTsKKworCisgIC8vIFNldHMgdGhlIG9iamVjdGl2ZSBjIGNsYXNzIHByZWZpeCB3aGljaCBpcyBwcmVwZW5kZWQgdG8gYWxsIG9iamVjdGl2ZSBjCisgIC8vIGdlbmVyYXRlZCBjbGFzc2VzIGZyb20gdGhpcyAucHJvdG8uIFRoZXJlIGlzIG5vIGRlZmF1bHQuCisgIG9wdGlvbmFsIHN0cmluZyBvYmpjX2NsYXNzX3ByZWZpeCA9IDM2OworCisgIC8vIE5hbWVzcGFjZSBmb3IgZ2VuZXJhdGVkIGNsYXNzZXM7IGRlZmF1bHRzIHRvIHRoZSBwYWNrYWdlLgorICBvcHRpb25hbCBzdHJpbmcgY3NoYXJwX25hbWVzcGFjZSA9IDM3OworCisgIC8vIFdoZXRoZXIgdGhlIG5hbm8gcHJvdG8gY29tcGlsZXIgc2hvdWxkIGdlbmVyYXRlIGluIHRoZSBkZXByZWNhdGVkIG5vbi1uYW5vCisgIC8vIHN1ZmZpeGVkIHBhY2thZ2UuCisgIG9wdGlvbmFsIGJvb2wgamF2YW5hbm9fdXNlX2RlcHJlY2F0ZWRfcGFja2FnZSA9IDM4IFtkZXByZWNhdGVkID0gdHJ1ZV07CisKKyAgLy8gVGhlIHBhcnNlciBzdG9yZXMgb3B0aW9ucyBpdCBkb2Vzbid0IHJlY29nbml6ZSBoZXJlLiBTZWUgYWJvdmUuCisgIHJlcGVhdGVkIFVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CisKKyAgLy8gQ2xpZW50cyBjYW4gZGVmaW5lIGN1c3RvbSBvcHRpb25zIGluIGV4dGVuc2lvbnMgb2YgdGhpcyBtZXNzYWdlLiBTZWUgYWJvdmUuCisgIGV4dGVuc2lvbnMgMTAwMCB0byBtYXg7Cit9CisKK21lc3NhZ2UgTWVzc2FnZU9wdGlvbnMgeworICAvLyBTZXQgdHJ1ZSB0byB1c2UgdGhlIG9sZCBwcm90bzEgTWVzc2FnZVNldCB3aXJlIGZvcm1hdCBmb3IgZXh0ZW5zaW9ucy4KKyAgLy8gVGhpcyBpcyBwcm92aWRlZCBmb3IgYmFja3dhcmRzLWNvbXBhdGliaWxpdHkgd2l0aCB0aGUgTWVzc2FnZVNldCB3aXJlCisgIC8vIGZvcm1hdC4gIFlvdSBzaG91bGQgbm90IHVzZSB0aGlzIGZvciBhbnkgb3RoZXIgcmVhc29uOiAgSXQncyBsZXNzCisgIC8vIGVmZmljaWVudCwgaGFzIGZld2VyIGZlYXR1cmVzLCBhbmQgaXMgbW9yZSBjb21wbGljYXRlZC4KKyAgLy8KKyAgLy8gVGhlIG1lc3NhZ2UgbXVzdCBiZSBkZWZpbmVkIGV4YWN0bHkgYXMgZm9sbG93czoKKyAgLy8gICBtZXNzYWdlIEZvbyB7CisgIC8vICAgICBvcHRpb24gbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQgPSB0cnVlOworICAvLyAgICAgZXh0ZW5zaW9ucyA0IHRvIG1heDsKKyAgLy8gICB9CisgIC8vIE5vdGUgdGhhdCB0aGUgbWVzc2FnZSBjYW5ub3QgaGF2ZSBhbnkgZGVmaW5lZCBmaWVsZHM7IE1lc3NhZ2VTZXRzIG9ubHkKKyAgLy8gaGF2ZSBleHRlbnNpb25zLgorICAvLworICAvLyBBbGwgZXh0ZW5zaW9ucyBvZiB5b3VyIHR5cGUgbXVzdCBiZSBzaW5ndWxhciBtZXNzYWdlczsgZS5nLiB0aGV5IGNhbm5vdAorICAvLyBiZSBpbnQzMnMsIGVudW1zLCBvciByZXBlYXRlZCBtZXNzYWdlcy4KKyAgLy8KKyAgLy8gQmVjYXVzZSB0aGlzIGlzIGFuIG9wdGlvbiwgdGhlIGFib3ZlIHR3byByZXN0cmljdGlvbnMgYXJlIG5vdCBlbmZvcmNlZCBieQorICAvLyB0aGUgcHJvdG9jb2wgY29tcGlsZXIuCisgIG9wdGlvbmFsIGJvb2wgbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQgPSAxIFtkZWZhdWx0PWZhbHNlXTsKKworICAvLyBEaXNhYmxlcyB0aGUgZ2VuZXJhdGlvbiBvZiB0aGUgc3RhbmRhcmQgImRlc2NyaXB0b3IoKSIgYWNjZXNzb3IsIHdoaWNoIGNhbgorICAvLyBjb25mbGljdCB3aXRoIGEgZmllbGQgb2YgdGhlIHNhbWUgbmFtZS4gIFRoaXMgaXMgbWVhbnQgdG8gbWFrZSBtaWdyYXRpb24KKyAgLy8gZnJvbSBwcm90bzEgZWFzaWVyOyBuZXcgY29kZSBzaG91bGQgYXZvaWQgZmllbGRzIG5hbWVkICJkZXNjcmlwdG9yIi4KKyAgb3B0aW9uYWwgYm9vbCBub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yID0gMiBbZGVmYXVsdD1mYWxzZV07CisKKyAgLy8gSXMgdGhpcyBtZXNzYWdlIGRlcHJlY2F0ZWQ/CisgIC8vIERlcGVuZGluZyBvbiB0aGUgdGFyZ2V0IHBsYXRmb3JtLCB0aGlzIGNhbiBlbWl0IERlcHJlY2F0ZWQgYW5ub3RhdGlvbnMKKyAgLy8gZm9yIHRoZSBtZXNzYWdlLCBvciBpdCB3aWxsIGJlIGNvbXBsZXRlbHkgaWdub3JlZDsgaW4gdGhlIHZlcnkgbGVhc3QsCisgIC8vIHRoaXMgaXMgYSBmb3JtYWxpemF0aW9uIGZvciBkZXByZWNhdGluZyBtZXNzYWdlcy4KKyAgb3B0aW9uYWwgYm9vbCBkZXByZWNhdGVkID0gMyBbZGVmYXVsdD1mYWxzZV07CisKKyAgLy8gV2hldGhlciB0aGUgbWVzc2FnZSBpcyBhbiBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBtYXAgZW50cnkgdHlwZSBmb3IgdGhlCisgIC8vIG1hcHMgZmllbGQuCisgIC8vCisgIC8vIEZvciBtYXBzIGZpZWxkczoKKyAgLy8gICAgIG1hcDxLZXlUeXBlLCBWYWx1ZVR5cGU+IG1hcF9maWVsZCA9IDE7CisgIC8vIFRoZSBwYXJzZWQgZGVzY3JpcHRvciBsb29rcyBsaWtlOgorICAvLyAgICAgbWVzc2FnZSBNYXBGaWVsZEVudHJ5IHsKKyAgLy8gICAgICAgICBvcHRpb24gbWFwX2VudHJ5ID0gdHJ1ZTsKKyAgLy8gICAgICAgICBvcHRpb25hbCBLZXlUeXBlIGtleSA9IDE7CisgIC8vICAgICAgICAgb3B0aW9uYWwgVmFsdWVUeXBlIHZhbHVlID0gMjsKKyAgLy8gICAgIH0KKyAgLy8gICAgIHJlcGVhdGVkIE1hcEZpZWxkRW50cnkgbWFwX2ZpZWxkID0gMTsKKyAgLy8KKyAgLy8gSW1wbGVtZW50YXRpb25zIG1heSBjaG9vc2Ugbm90IHRvIGdlbmVyYXRlIHRoZSBtYXBfZW50cnk9dHJ1ZSBtZXNzYWdlLCBidXQKKyAgLy8gdXNlIGEgbmF0aXZlIG1hcCBpbiB0aGUgdGFyZ2V0IGxhbmd1YWdlIHRvIGhvbGQgdGhlIGtleXMgYW5kIHZhbHVlcy4KKyAgLy8gVGhlIHJlZmxlY3Rpb24gQVBJcyBpbiBzdWNoIGltcGxlbWVudGlvbnMgc3RpbGwgbmVlZCB0byB3b3JrIGFzCisgIC8vIGlmIHRoZSBmaWVsZCBpcyBhIHJlcGVhdGVkIG1lc3NhZ2UgZmllbGQuCisgIC8vCisgIC8vIE5PVEU6IERvIG5vdCBzZXQgdGhlIG9wdGlvbiBpbiAucHJvdG8gZmlsZXMuIEFsd2F5cyB1c2UgdGhlIG1hcHMgc3ludGF4CisgIC8vIGluc3RlYWQuIFRoZSBvcHRpb24gc2hvdWxkIG9ubHkgYmUgaW1wbGljaXRseSBzZXQgYnkgdGhlIHByb3RvIGNvbXBpbGVyCisgIC8vIHBhcnNlci4KKyAgb3B0aW9uYWwgYm9vbCBtYXBfZW50cnkgPSA3OworCisgIC8vIFRoZSBwYXJzZXIgc3RvcmVzIG9wdGlvbnMgaXQgZG9lc24ndCByZWNvZ25pemUgaGVyZS4gU2VlIGFib3ZlLgorICByZXBlYXRlZCBVbmludGVycHJldGVkT3B0aW9uIHVuaW50ZXJwcmV0ZWRfb3B0aW9uID0gOTk5OworCisgIC8vIENsaWVudHMgY2FuIGRlZmluZSBjdXN0b20gb3B0aW9ucyBpbiBleHRlbnNpb25zIG9mIHRoaXMgbWVzc2FnZS4gU2VlIGFib3ZlLgorICBleHRlbnNpb25zIDEwMDAgdG8gbWF4OworfQorCittZXNzYWdlIEZpZWxkT3B0aW9ucyB7CisgIC8vIFRoZSBjdHlwZSBvcHRpb24gaW5zdHJ1Y3RzIHRoZSBDKysgY29kZSBnZW5lcmF0b3IgdG8gdXNlIGEgZGlmZmVyZW50CisgIC8vIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBmaWVsZCB0aGFuIGl0IG5vcm1hbGx5IHdvdWxkLiAgU2VlIHRoZSBzcGVjaWZpYworICAvLyBvcHRpb25zIGJlbG93LiAgVGhpcyBvcHRpb24gaXMgbm90IHlldCBpbXBsZW1lbnRlZCBpbiB0aGUgb3BlbiBzb3VyY2UKKyAgLy8gcmVsZWFzZSAtLSBzb3JyeSwgd2UnbGwgdHJ5IHRvIGluY2x1ZGUgaXQgaW4gYSBmdXR1cmUgdmVyc2lvbiEKKyAgb3B0aW9uYWwgQ1R5cGUgY3R5cGUgPSAxIFtkZWZhdWx0ID0gU1RSSU5HXTsKKyAgZW51bSBDVHlwZSB7CisgICAgLy8gRGVmYXVsdCBtb2RlLgorICAgIFNUUklORyA9IDA7CisKKyAgICBDT1JEID0gMTsKKworICAgIFNUUklOR19QSUVDRSA9IDI7CisgIH0KKyAgLy8gVGhlIHBhY2tlZCBvcHRpb24gY2FuIGJlIGVuYWJsZWQgZm9yIHJlcGVhdGVkIHByaW1pdGl2ZSBmaWVsZHMgdG8gZW5hYmxlCisgIC8vIGEgbW9yZSBlZmZpY2llbnQgcmVwcmVzZW50YXRpb24gb24gdGhlIHdpcmUuIFJhdGhlciB0aGFuIHJlcGVhdGVkbHkKKyAgLy8gd3JpdGluZyB0aGUgdGFnIGFuZCB0eXBlIGZvciBlYWNoIGVsZW1lbnQsIHRoZSBlbnRpcmUgYXJyYXkgaXMgZW5jb2RlZCBhcworICAvLyBhIHNpbmdsZSBsZW5ndGgtZGVsaW1pdGVkIGJsb2IuIEluIHByb3RvMywgb25seSBleHBsaWNpdCBzZXR0aW5nIGl0IHRvCisgIC8vIGZhbHNlIHdpbGwgYXZvaWQgdXNpbmcgcGFja2VkIGVuY29kaW5nLgorICBvcHRpb25hbCBib29sIHBhY2tlZCA9IDI7CisKKworICAvLyBUaGUganN0eXBlIG9wdGlvbiBkZXRlcm1pbmVzIHRoZSBKYXZhU2NyaXB0IHR5cGUgdXNlZCBmb3IgdmFsdWVzIG9mIHRoZQorICAvLyBmaWVsZC4gIFRoZSBvcHRpb24gaXMgcGVybWl0dGVkIG9ubHkgZm9yIDY0IGJpdCBpbnRlZ3JhbCBhbmQgZml4ZWQgdHlwZXMKKyAgLy8gKGludDY0LCB1aW50NjQsIHNpbnQ2NCwgZml4ZWQ2NCwgc2ZpeGVkNjQpLiAgQnkgZGVmYXVsdCB0aGVzZSB0eXBlcyBhcmUKKyAgLy8gcmVwcmVzZW50ZWQgYXMgSmF2YVNjcmlwdCBzdHJpbmdzLiAgVGhpcyBhdm9pZHMgbG9zcyBvZiBwcmVjaXNpb24gdGhhdCBjYW4KKyAgLy8gaGFwcGVuIHdoZW4gYSBsYXJnZSB2YWx1ZSBpcyBjb252ZXJ0ZWQgdG8gYSBmbG9hdGluZyBwb2ludCBKYXZhU2NyaXB0CisgIC8vIG51bWJlcnMuICBTcGVjaWZ5aW5nIEpTX05VTUJFUiBmb3IgdGhlIGpzdHlwZSBjYXVzZXMgdGhlIGdlbmVyYXRlZAorICAvLyBKYXZhU2NyaXB0IGNvZGUgdG8gdXNlIHRoZSBKYXZhU2NyaXB0ICJudW1iZXIiIHR5cGUgaW5zdGVhZCBvZiBzdHJpbmdzLgorICAvLyBUaGlzIG9wdGlvbiBpcyBhbiBlbnVtIHRvIHBlcm1pdCBhZGRpdGlvbmFsIHR5cGVzIHRvIGJlIGFkZGVkLAorICAvLyBlLmcuIGdvb2cubWF0aC5JbnRlZ2VyLgorICBvcHRpb25hbCBKU1R5cGUganN0eXBlID0gNiBbZGVmYXVsdCA9IEpTX05PUk1BTF07CisgIGVudW0gSlNUeXBlIHsKKyAgICAvLyBVc2UgdGhlIGRlZmF1bHQgdHlwZS4KKyAgICBKU19OT1JNQUwgPSAwOworCisgICAgLy8gVXNlIEphdmFTY3JpcHQgc3RyaW5ncy4KKyAgICBKU19TVFJJTkcgPSAxOworCisgICAgLy8gVXNlIEphdmFTY3JpcHQgbnVtYmVycy4KKyAgICBKU19OVU1CRVIgPSAyOworICB9CisKKyAgLy8gU2hvdWxkIHRoaXMgZmllbGQgYmUgcGFyc2VkIGxhemlseT8gIExhenkgYXBwbGllcyBvbmx5IHRvIG1lc3NhZ2UtdHlwZQorICAvLyBmaWVsZHMuICBJdCBtZWFucyB0aGF0IHdoZW4gdGhlIG91dGVyIG1lc3NhZ2UgaXMgaW5pdGlhbGx5IHBhcnNlZCwgdGhlCisgIC8vIGlubmVyIG1lc3NhZ2UncyBjb250ZW50cyB3aWxsIG5vdCBiZSBwYXJzZWQgYnV0IGluc3RlYWQgc3RvcmVkIGluIGVuY29kZWQKKyAgLy8gZm9ybS4gIFRoZSBpbm5lciBtZXNzYWdlIHdpbGwgYWN0dWFsbHkgYmUgcGFyc2VkIHdoZW4gaXQgaXMgZmlyc3QgYWNjZXNzZWQuCisgIC8vCisgIC8vIFRoaXMgaXMgb25seSBhIGhpbnQuICBJbXBsZW1lbnRhdGlvbnMgYXJlIGZyZWUgdG8gY2hvb3NlIHdoZXRoZXIgdG8gdXNlCisgIC8vIGVhZ2VyIG9yIGxhenkgcGFyc2luZyByZWdhcmRsZXNzIG9mIHRoZSB2YWx1ZSBvZiB0aGlzIG9wdGlvbi4gIEhvd2V2ZXIsCisgIC8vIHNldHRpbmcgdGhpcyBvcHRpb24gdHJ1ZSBzdWdnZXN0cyB0aGF0IHRoZSBwcm90b2NvbCBhdXRob3IgYmVsaWV2ZXMgdGhhdAorICAvLyB1c2luZyBsYXp5IHBhcnNpbmcgb24gdGhpcyBmaWVsZCBpcyB3b3J0aCB0aGUgYWRkaXRpb25hbCBib29ra2VlcGluZworICAvLyBvdmVyaGVhZCB0eXBpY2FsbHkgbmVlZGVkIHRvIGltcGxlbWVudCBpdC4KKyAgLy8KKyAgLy8gVGhpcyBvcHRpb24gZG9lcyBub3QgYWZmZWN0IHRoZSBwdWJsaWMgaW50ZXJmYWNlIG9mIGFueSBnZW5lcmF0ZWQgY29kZTsKKyAgLy8gYWxsIG1ldGhvZCBzaWduYXR1cmVzIHJlbWFpbiB0aGUgc2FtZS4gIEZ1cnRoZXJtb3JlLCB0aHJlYWQtc2FmZXR5IG9mIHRoZQorICAvLyBpbnRlcmZhY2UgaXMgbm90IGFmZmVjdGVkIGJ5IHRoaXMgb3B0aW9uOyBjb25zdCBtZXRob2RzIHJlbWFpbiBzYWZlIHRvCisgIC8vIGNhbGwgZnJvbSBtdWx0aXBsZSB0aHJlYWRzIGNvbmN1cnJlbnRseSwgd2hpbGUgbm9uLWNvbnN0IG1ldGhvZHMgY29udGludWUKKyAgLy8gdG8gcmVxdWlyZSBleGNsdXNpdmUgYWNjZXNzLgorICAvLworICAvLworICAvLyBOb3RlIHRoYXQgaW1wbGVtZW50YXRpb25zIG1heSBjaG9vc2Ugbm90IHRvIGNoZWNrIHJlcXVpcmVkIGZpZWxkcyB3aXRoaW4KKyAgLy8gYSBsYXp5IHN1Yi1tZXNzYWdlLiAgVGhhdCBpcywgY2FsbGluZyBJc0luaXRpYWxpemVkKCkgb24gdGhlIG91dGhlciBtZXNzYWdlCisgIC8vIG1heSByZXR1cm4gdHJ1ZSBldmVuIGlmIHRoZSBpbm5lciBtZXNzYWdlIGhhcyBtaXNzaW5nIHJlcXVpcmVkIGZpZWxkcy4KKyAgLy8gVGhpcyBpcyBuZWNlc3NhcnkgYmVjYXVzZSBvdGhlcndpc2UgdGhlIGlubmVyIG1lc3NhZ2Ugd291bGQgaGF2ZSB0byBiZQorICAvLyBwYXJzZWQgaW4gb3JkZXIgdG8gcGVyZm9ybSB0aGUgY2hlY2ssIGRlZmVhdGluZyB0aGUgcHVycG9zZSBvZiBsYXp5CisgIC8vIHBhcnNpbmcuICBBbiBpbXBsZW1lbnRhdGlvbiB3aGljaCBjaG9vc2VzIG5vdCB0byBjaGVjayByZXF1aXJlZCBmaWVsZHMKKyAgLy8gbXVzdCBiZSBjb25zaXN0ZW50IGFib3V0IGl0LiAgVGhhdCBpcywgZm9yIGFueSBwYXJ0aWN1bGFyIHN1Yi1tZXNzYWdlLCB0aGUKKyAgLy8gaW1wbGVtZW50YXRpb24gbXVzdCBlaXRoZXIgKmFsd2F5cyogY2hlY2sgaXRzIHJlcXVpcmVkIGZpZWxkcywgb3IgKm5ldmVyKgorICAvLyBjaGVjayBpdHMgcmVxdWlyZWQgZmllbGRzLCByZWdhcmRsZXNzIG9mIHdoZXRoZXIgb3Igbm90IHRoZSBtZXNzYWdlIGhhcworICAvLyBiZWVuIHBhcnNlZC4KKyAgb3B0aW9uYWwgYm9vbCBsYXp5ID0gNSBbZGVmYXVsdD1mYWxzZV07CisKKyAgLy8gSXMgdGhpcyBmaWVsZCBkZXByZWNhdGVkPworICAvLyBEZXBlbmRpbmcgb24gdGhlIHRhcmdldCBwbGF0Zm9ybSwgdGhpcyBjYW4gZW1pdCBEZXByZWNhdGVkIGFubm90YXRpb25zCisgIC8vIGZvciBhY2Nlc3NvcnMsIG9yIGl0IHdpbGwgYmUgY29tcGxldGVseSBpZ25vcmVkOyBpbiB0aGUgdmVyeSBsZWFzdCwgdGhpcworICAvLyBpcyBhIGZvcm1hbGl6YXRpb24gZm9yIGRlcHJlY2F0aW5nIGZpZWxkcy4KKyAgb3B0aW9uYWwgYm9vbCBkZXByZWNhdGVkID0gMyBbZGVmYXVsdD1mYWxzZV07CisKKyAgLy8gRm9yIEdvb2dsZS1pbnRlcm5hbCBtaWdyYXRpb24gb25seS4gRG8gbm90IHVzZS4KKyAgb3B0aW9uYWwgYm9vbCB3ZWFrID0gMTAgW2RlZmF1bHQ9ZmFsc2VdOworCisKKyAgLy8gVGhlIHBhcnNlciBzdG9yZXMgb3B0aW9ucyBpdCBkb2Vzbid0IHJlY29nbml6ZSBoZXJlLiBTZWUgYWJvdmUuCisgIHJlcGVhdGVkIFVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CisKKyAgLy8gQ2xpZW50cyBjYW4gZGVmaW5lIGN1c3RvbSBvcHRpb25zIGluIGV4dGVuc2lvbnMgb2YgdGhpcyBtZXNzYWdlLiBTZWUgYWJvdmUuCisgIGV4dGVuc2lvbnMgMTAwMCB0byBtYXg7Cit9CisKK21lc3NhZ2UgRW51bU9wdGlvbnMgeworCisgIC8vIFNldCB0aGlzIG9wdGlvbiB0byB0cnVlIHRvIGFsbG93IG1hcHBpbmcgZGlmZmVyZW50IHRhZyBuYW1lcyB0byB0aGUgc2FtZQorICAvLyB2YWx1ZS4KKyAgb3B0aW9uYWwgYm9vbCBhbGxvd19hbGlhcyA9IDI7CisKKyAgLy8gSXMgdGhpcyBlbnVtIGRlcHJlY2F0ZWQ/CisgIC8vIERlcGVuZGluZyBvbiB0aGUgdGFyZ2V0IHBsYXRmb3JtLCB0aGlzIGNhbiBlbWl0IERlcHJlY2F0ZWQgYW5ub3RhdGlvbnMKKyAgLy8gZm9yIHRoZSBlbnVtLCBvciBpdCB3aWxsIGJlIGNvbXBsZXRlbHkgaWdub3JlZDsgaW4gdGhlIHZlcnkgbGVhc3QsIHRoaXMKKyAgLy8gaXMgYSBmb3JtYWxpemF0aW9uIGZvciBkZXByZWNhdGluZyBlbnVtcy4KKyAgb3B0aW9uYWwgYm9vbCBkZXByZWNhdGVkID0gMyBbZGVmYXVsdD1mYWxzZV07CisKKyAgLy8gVGhlIHBhcnNlciBzdG9yZXMgb3B0aW9ucyBpdCBkb2Vzbid0IHJlY29nbml6ZSBoZXJlLiBTZWUgYWJvdmUuCisgIHJlcGVhdGVkIFVuaW50ZXJwcmV0ZWRPcHRpb24gdW5pbnRlcnByZXRlZF9vcHRpb24gPSA5OTk7CisKKyAgLy8gQ2xpZW50cyBjYW4gZGVmaW5lIGN1c3RvbSBvcHRpb25zIGluIGV4dGVuc2lvbnMgb2YgdGhpcyBtZXNzYWdlLiBTZWUgYWJvdmUuCisgIGV4dGVuc2lvbnMgMTAwMCB0byBtYXg7Cit9CisKK21lc3NhZ2UgRW51bVZhbHVlT3B0aW9ucyB7CisgIC8vIElzIHRoaXMgZW51bSB2YWx1ZSBkZXByZWNhdGVkPworICAvLyBEZXBlbmRpbmcgb24gdGhlIHRhcmdldCBwbGF0Zm9ybSwgdGhpcyBjYW4gZW1pdCBEZXByZWNhdGVkIGFubm90YXRpb25zCisgIC8vIGZvciB0aGUgZW51bSB2YWx1ZSwgb3IgaXQgd2lsbCBiZSBjb21wbGV0ZWx5IGlnbm9yZWQ7IGluIHRoZSB2ZXJ5IGxlYXN0LAorICAvLyB0aGlzIGlzIGEgZm9ybWFsaXphdGlvbiBmb3IgZGVwcmVjYXRpbmcgZW51bSB2YWx1ZXMuCisgIG9wdGlvbmFsIGJvb2wgZGVwcmVjYXRlZCA9IDEgW2RlZmF1bHQ9ZmFsc2VdOworCisgIC8vIFRoZSBwYXJzZXIgc3RvcmVzIG9wdGlvbnMgaXQgZG9lc24ndCByZWNvZ25pemUgaGVyZS4gU2VlIGFib3ZlLgorICByZXBlYXRlZCBVbmludGVycHJldGVkT3B0aW9uIHVuaW50ZXJwcmV0ZWRfb3B0aW9uID0gOTk5OworCisgIC8vIENsaWVudHMgY2FuIGRlZmluZSBjdXN0b20gb3B0aW9ucyBpbiBleHRlbnNpb25zIG9mIHRoaXMgbWVzc2FnZS4gU2VlIGFib3ZlLgorICBleHRlbnNpb25zIDEwMDAgdG8gbWF4OworfQorCittZXNzYWdlIFNlcnZpY2VPcHRpb25zIHsKKworICAvLyBOb3RlOiAgRmllbGQgbnVtYmVycyAxIHRocm91Z2ggMzIgYXJlIHJlc2VydmVkIGZvciBHb29nbGUncyBpbnRlcm5hbCBSUEMKKyAgLy8gICBmcmFtZXdvcmsuICBXZSBhcG9sb2dpemUgZm9yIGhvYXJkaW5nIHRoZXNlIG51bWJlcnMgdG8gb3Vyc2VsdmVzLCBidXQKKyAgLy8gICB3ZSB3ZXJlIGFscmVhZHkgdXNpbmcgdGhlbSBsb25nIGJlZm9yZSB3ZSBkZWNpZGVkIHRvIHJlbGVhc2UgUHJvdG9jb2wKKyAgLy8gICBCdWZmZXJzLgorCisgIC8vIElzIHRoaXMgc2VydmljZSBkZXByZWNhdGVkPworICAvLyBEZXBlbmRpbmcgb24gdGhlIHRhcmdldCBwbGF0Zm9ybSwgdGhpcyBjYW4gZW1pdCBEZXByZWNhdGVkIGFubm90YXRpb25zCisgIC8vIGZvciB0aGUgc2VydmljZSwgb3IgaXQgd2lsbCBiZSBjb21wbGV0ZWx5IGlnbm9yZWQ7IGluIHRoZSB2ZXJ5IGxlYXN0LAorICAvLyB0aGlzIGlzIGEgZm9ybWFsaXphdGlvbiBmb3IgZGVwcmVjYXRpbmcgc2VydmljZXMuCisgIG9wdGlvbmFsIGJvb2wgZGVwcmVjYXRlZCA9IDMzIFtkZWZhdWx0PWZhbHNlXTsKKworICAvLyBUaGUgcGFyc2VyIHN0b3JlcyBvcHRpb25zIGl0IGRvZXNuJ3QgcmVjb2duaXplIGhlcmUuIFNlZSBhYm92ZS4KKyAgcmVwZWF0ZWQgVW5pbnRlcnByZXRlZE9wdGlvbiB1bmludGVycHJldGVkX29wdGlvbiA9IDk5OTsKKworICAvLyBDbGllbnRzIGNhbiBkZWZpbmUgY3VzdG9tIG9wdGlvbnMgaW4gZXh0ZW5zaW9ucyBvZiB0aGlzIG1lc3NhZ2UuIFNlZSBhYm92ZS4KKyAgZXh0ZW5zaW9ucyAxMDAwIHRvIG1heDsKK30KKworbWVzc2FnZSBNZXRob2RPcHRpb25zIHsKKworICAvLyBOb3RlOiAgRmllbGQgbnVtYmVycyAxIHRocm91Z2ggMzIgYXJlIHJlc2VydmVkIGZvciBHb29nbGUncyBpbnRlcm5hbCBSUEMKKyAgLy8gICBmcmFtZXdvcmsuICBXZSBhcG9sb2dpemUgZm9yIGhvYXJkaW5nIHRoZXNlIG51bWJlcnMgdG8gb3Vyc2VsdmVzLCBidXQKKyAgLy8gICB3ZSB3ZXJlIGFscmVhZHkgdXNpbmcgdGhlbSBsb25nIGJlZm9yZSB3ZSBkZWNpZGVkIHRvIHJlbGVhc2UgUHJvdG9jb2wKKyAgLy8gICBCdWZmZXJzLgorCisgIC8vIElzIHRoaXMgbWV0aG9kIGRlcHJlY2F0ZWQ/CisgIC8vIERlcGVuZGluZyBvbiB0aGUgdGFyZ2V0IHBsYXRmb3JtLCB0aGlzIGNhbiBlbWl0IERlcHJlY2F0ZWQgYW5ub3RhdGlvbnMKKyAgLy8gZm9yIHRoZSBtZXRob2QsIG9yIGl0IHdpbGwgYmUgY29tcGxldGVseSBpZ25vcmVkOyBpbiB0aGUgdmVyeSBsZWFzdCwKKyAgLy8gdGhpcyBpcyBhIGZvcm1hbGl6YXRpb24gZm9yIGRlcHJlY2F0aW5nIG1ldGhvZHMuCisgIG9wdGlvbmFsIGJvb2wgZGVwcmVjYXRlZCA9IDMzIFtkZWZhdWx0PWZhbHNlXTsKKworICAvLyBUaGUgcGFyc2VyIHN0b3JlcyBvcHRpb25zIGl0IGRvZXNuJ3QgcmVjb2duaXplIGhlcmUuIFNlZSBhYm92ZS4KKyAgcmVwZWF0ZWQgVW5pbnRlcnByZXRlZE9wdGlvbiB1bmludGVycHJldGVkX29wdGlvbiA9IDk5OTsKKworICAvLyBDbGllbnRzIGNhbiBkZWZpbmUgY3VzdG9tIG9wdGlvbnMgaW4gZXh0ZW5zaW9ucyBvZiB0aGlzIG1lc3NhZ2UuIFNlZSBhYm92ZS4KKyAgZXh0ZW5zaW9ucyAxMDAwIHRvIG1heDsKK30KKworCisvLyBBIG1lc3NhZ2UgcmVwcmVzZW50aW5nIGEgb3B0aW9uIHRoZSBwYXJzZXIgZG9lcyBub3QgcmVjb2duaXplLiBUaGlzIG9ubHkKKy8vIGFwcGVhcnMgaW4gb3B0aW9ucyBwcm90b3MgY3JlYXRlZCBieSB0aGUgY29tcGlsZXI6OlBhcnNlciBjbGFzcy4KKy8vIERlc2NyaXB0b3JQb29sIHJlc29sdmVzIHRoZXNlIHdoZW4gYnVpbGRpbmcgRGVzY3JpcHRvciBvYmplY3RzLiBUaGVyZWZvcmUsCisvLyBvcHRpb25zIHByb3RvcyBpbiBkZXNjcmlwdG9yIG9iamVjdHMgKGUuZy4gcmV0dXJuZWQgYnkgRGVzY3JpcHRvcjo6b3B0aW9ucygpLAorLy8gb3IgcHJvZHVjZWQgYnkgRGVzY3JpcHRvcjo6Q29weVRvKCkpIHdpbGwgbmV2ZXIgaGF2ZSBVbmludGVycHJldGVkT3B0aW9ucworLy8gaW4gdGhlbS4KK21lc3NhZ2UgVW5pbnRlcnByZXRlZE9wdGlvbiB7CisgIC8vIFRoZSBuYW1lIG9mIHRoZSB1bmludGVycHJldGVkIG9wdGlvbi4gIEVhY2ggc3RyaW5nIHJlcHJlc2VudHMgYSBzZWdtZW50IGluCisgIC8vIGEgZG90LXNlcGFyYXRlZCBuYW1lLiAgaXNfZXh0ZW5zaW9uIGlzIHRydWUgaWZmIGEgc2VnbWVudCByZXByZXNlbnRzIGFuCisgIC8vIGV4dGVuc2lvbiAoZGVub3RlZCB3aXRoIHBhcmVudGhlc2VzIGluIG9wdGlvbnMgc3BlY3MgaW4gLnByb3RvIGZpbGVzKS4KKyAgLy8gRS5nLix7IFsiZm9vIiwgZmFsc2VdLCBbImJhci5iYXoiLCB0cnVlXSwgWyJxdXgiLCBmYWxzZV0gfSByZXByZXNlbnRzCisgIC8vICJmb28uKGJhci5iYXopLnF1eCIuCisgIG1lc3NhZ2UgTmFtZVBhcnQgeworICAgIHJlcXVpcmVkIHN0cmluZyBuYW1lX3BhcnQgPSAxOworICAgIHJlcXVpcmVkIGJvb2wgaXNfZXh0ZW5zaW9uID0gMjsKKyAgfQorICByZXBlYXRlZCBOYW1lUGFydCBuYW1lID0gMjsKKworICAvLyBUaGUgdmFsdWUgb2YgdGhlIHVuaW50ZXJwcmV0ZWQgb3B0aW9uLCBpbiB3aGF0ZXZlciB0eXBlIHRoZSB0b2tlbml6ZXIKKyAgLy8gaWRlbnRpZmllZCBpdCBhcyBkdXJpbmcgcGFyc2luZy4gRXhhY3RseSBvbmUgb2YgdGhlc2Ugc2hvdWxkIGJlIHNldC4KKyAgb3B0aW9uYWwgc3RyaW5nIGlkZW50aWZpZXJfdmFsdWUgPSAzOworICBvcHRpb25hbCB1aW50NjQgcG9zaXRpdmVfaW50X3ZhbHVlID0gNDsKKyAgb3B0aW9uYWwgaW50NjQgbmVnYXRpdmVfaW50X3ZhbHVlID0gNTsKKyAgb3B0aW9uYWwgZG91YmxlIGRvdWJsZV92YWx1ZSA9IDY7CisgIG9wdGlvbmFsIGJ5dGVzIHN0cmluZ192YWx1ZSA9IDc7CisgIG9wdGlvbmFsIHN0cmluZyBhZ2dyZWdhdGVfdmFsdWUgPSA4OworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisvLyBPcHRpb25hbCBzb3VyY2UgY29kZSBpbmZvCisKKy8vIEVuY2Fwc3VsYXRlcyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgb3JpZ2luYWwgc291cmNlIGZpbGUgZnJvbSB3aGljaCBhCisvLyBGaWxlRGVzY3JpcHRvclByb3RvIHdhcyBnZW5lcmF0ZWQuCittZXNzYWdlIFNvdXJjZUNvZGVJbmZvIHsKKyAgLy8gQSBMb2NhdGlvbiBpZGVudGlmaWVzIGEgcGllY2Ugb2Ygc291cmNlIGNvZGUgaW4gYSAucHJvdG8gZmlsZSB3aGljaAorICAvLyBjb3JyZXNwb25kcyB0byBhIHBhcnRpY3VsYXIgZGVmaW5pdGlvbi4gIFRoaXMgaW5mb3JtYXRpb24gaXMgaW50ZW5kZWQKKyAgLy8gdG8gYmUgdXNlZnVsIHRvIElERXMsIGNvZGUgaW5kZXhlcnMsIGRvY3VtZW50YXRpb24gZ2VuZXJhdG9ycywgYW5kIHNpbWlsYXIKKyAgLy8gdG9vbHMuCisgIC8vCisgIC8vIEZvciBleGFtcGxlLCBzYXkgd2UgaGF2ZSBhIGZpbGUgbGlrZToKKyAgLy8gICBtZXNzYWdlIEZvbyB7CisgIC8vICAgICBvcHRpb25hbCBzdHJpbmcgZm9vID0gMTsKKyAgLy8gICB9CisgIC8vIExldCdzIGxvb2sgYXQganVzdCB0aGUgZmllbGQgZGVmaW5pdGlvbjoKKyAgLy8gICBvcHRpb25hbCBzdHJpbmcgZm9vID0gMTsKKyAgLy8gICBeICAgICAgIF5eICAgICBeXiAgXiAgXl5eCisgIC8vICAgYSAgICAgICBiYyAgICAgZGUgIGYgIGdoaQorICAvLyBXZSBoYXZlIHRoZSBmb2xsb3dpbmcgbG9jYXRpb25zOgorICAvLyAgIHNwYW4gICBwYXRoICAgICAgICAgICAgICAgcmVwcmVzZW50cworICAvLyAgIFthLGkpICBbIDQsIDAsIDIsIDAgXSAgICAgVGhlIHdob2xlIGZpZWxkIGRlZmluaXRpb24uCisgIC8vICAgW2EsYikgIFsgNCwgMCwgMiwgMCwgNCBdICBUaGUgbGFiZWwgKG9wdGlvbmFsKS4KKyAgLy8gICBbYyxkKSAgWyA0LCAwLCAyLCAwLCA1IF0gIFRoZSB0eXBlIChzdHJpbmcpLgorICAvLyAgIFtlLGYpICBbIDQsIDAsIDIsIDAsIDEgXSAgVGhlIG5hbWUgKGZvbykuCisgIC8vICAgW2csaCkgIFsgNCwgMCwgMiwgMCwgMyBdICBUaGUgbnVtYmVyICgxKS4KKyAgLy8KKyAgLy8gTm90ZXM6CisgIC8vIC0gQSBsb2NhdGlvbiBtYXkgcmVmZXIgdG8gYSByZXBlYXRlZCBmaWVsZCBpdHNlbGYgKGkuZS4gbm90IHRvIGFueQorICAvLyAgIHBhcnRpY3VsYXIgaW5kZXggd2l0aGluIGl0KS4gIFRoaXMgaXMgdXNlZCB3aGVuZXZlciBhIHNldCBvZiBlbGVtZW50cyBhcmUKKyAgLy8gICBsb2dpY2FsbHkgZW5jbG9zZWQgaW4gYSBzaW5nbGUgY29kZSBzZWdtZW50LiAgRm9yIGV4YW1wbGUsIGFuIGVudGlyZQorICAvLyAgIGV4dGVuZCBibG9jayAocG9zc2libHkgY29udGFpbmluZyBtdWx0aXBsZSBleHRlbnNpb24gZGVmaW5pdGlvbnMpIHdpbGwKKyAgLy8gICBoYXZlIGFuIG91dGVyIGxvY2F0aW9uIHdob3NlIHBhdGggcmVmZXJzIHRvIHRoZSAiZXh0ZW5zaW9ucyIgcmVwZWF0ZWQKKyAgLy8gICBmaWVsZCB3aXRob3V0IGFuIGluZGV4LgorICAvLyAtIE11bHRpcGxlIGxvY2F0aW9ucyBtYXkgaGF2ZSB0aGUgc2FtZSBwYXRoLiAgVGhpcyBoYXBwZW5zIHdoZW4gYSBzaW5nbGUKKyAgLy8gICBsb2dpY2FsIGRlY2xhcmF0aW9uIGlzIHNwcmVhZCBvdXQgYWNyb3NzIG11bHRpcGxlIHBsYWNlcy4gIFRoZSBtb3N0CisgIC8vICAgb2J2aW91cyBleGFtcGxlIGlzIHRoZSAiZXh0ZW5kIiBibG9jayBhZ2FpbiAtLSB0aGVyZSBtYXkgYmUgbXVsdGlwbGUKKyAgLy8gICBleHRlbmQgYmxvY2tzIGluIHRoZSBzYW1lIHNjb3BlLCBlYWNoIG9mIHdoaWNoIHdpbGwgaGF2ZSB0aGUgc2FtZSBwYXRoLgorICAvLyAtIEEgbG9jYXRpb24ncyBzcGFuIGlzIG5vdCBhbHdheXMgYSBzdWJzZXQgb2YgaXRzIHBhcmVudCdzIHNwYW4uICBGb3IKKyAgLy8gICBleGFtcGxlLCB0aGUgImV4dGVuZGVlIiBvZiBhbiBleHRlbnNpb24gZGVjbGFyYXRpb24gYXBwZWFycyBhdCB0aGUKKyAgLy8gICBiZWdpbm5pbmcgb2YgdGhlICJleHRlbmQiIGJsb2NrIGFuZCBpcyBzaGFyZWQgYnkgYWxsIGV4dGVuc2lvbnMgd2l0aGluCisgIC8vICAgdGhlIGJsb2NrLgorICAvLyAtIEp1c3QgYmVjYXVzZSBhIGxvY2F0aW9uJ3Mgc3BhbiBpcyBhIHN1YnNldCBvZiBzb21lIG90aGVyIGxvY2F0aW9uJ3Mgc3BhbgorICAvLyAgIGRvZXMgbm90IG1lYW4gdGhhdCBpdCBpcyBhIGRlc2NlbmRlbnQuICBGb3IgZXhhbXBsZSwgYSAiZ3JvdXAiIGRlZmluZXMKKyAgLy8gICBib3RoIGEgdHlwZSBhbmQgYSBmaWVsZCBpbiBhIHNpbmdsZSBkZWNsYXJhdGlvbi4gIFRodXMsIHRoZSBsb2NhdGlvbnMKKyAgLy8gICBjb3JyZXNwb25kaW5nIHRvIHRoZSB0eXBlIGFuZCBmaWVsZCBhbmQgdGhlaXIgY29tcG9uZW50cyB3aWxsIG92ZXJsYXAuCisgIC8vIC0gQ29kZSB3aGljaCB0cmllcyB0byBpbnRlcnByZXQgbG9jYXRpb25zIHNob3VsZCBwcm9iYWJseSBiZSBkZXNpZ25lZCB0bworICAvLyAgIGlnbm9yZSB0aG9zZSB0aGF0IGl0IGRvZXNuJ3QgdW5kZXJzdGFuZCwgYXMgbW9yZSB0eXBlcyBvZiBsb2NhdGlvbnMgY291bGQKKyAgLy8gICBiZSByZWNvcmRlZCBpbiB0aGUgZnV0dXJlLgorICByZXBlYXRlZCBMb2NhdGlvbiBsb2NhdGlvbiA9IDE7CisgIG1lc3NhZ2UgTG9jYXRpb24geworICAgIC8vIElkZW50aWZpZXMgd2hpY2ggcGFydCBvZiB0aGUgRmlsZURlc2NyaXB0b3JQcm90byB3YXMgZGVmaW5lZCBhdCB0aGlzCisgICAgLy8gbG9jYXRpb24uCisgICAgLy8KKyAgICAvLyBFYWNoIGVsZW1lbnQgaXMgYSBmaWVsZCBudW1iZXIgb3IgYW4gaW5kZXguICBUaGV5IGZvcm0gYSBwYXRoIGZyb20KKyAgICAvLyB0aGUgcm9vdCBGaWxlRGVzY3JpcHRvclByb3RvIHRvIHRoZSBwbGFjZSB3aGVyZSB0aGUgZGVmaW5pdGlvbi4gIEZvcgorICAgIC8vIGV4YW1wbGUsIHRoaXMgcGF0aDoKKyAgICAvLyAgIFsgNCwgMywgMiwgNywgMSBdCisgICAgLy8gcmVmZXJzIHRvOgorICAgIC8vICAgZmlsZS5tZXNzYWdlX3R5cGUoMykgIC8vIDQsIDMKKyAgICAvLyAgICAgICAuZmllbGQoNykgICAgICAgICAvLyAyLCA3CisgICAgLy8gICAgICAgLm5hbWUoKSAgICAgICAgICAgLy8gMQorICAgIC8vIFRoaXMgaXMgYmVjYXVzZSBGaWxlRGVzY3JpcHRvclByb3RvLm1lc3NhZ2VfdHlwZSBoYXMgZmllbGQgbnVtYmVyIDQ6CisgICAgLy8gICByZXBlYXRlZCBEZXNjcmlwdG9yUHJvdG8gbWVzc2FnZV90eXBlID0gNDsKKyAgICAvLyBhbmQgRGVzY3JpcHRvclByb3RvLmZpZWxkIGhhcyBmaWVsZCBudW1iZXIgMjoKKyAgICAvLyAgIHJlcGVhdGVkIEZpZWxkRGVzY3JpcHRvclByb3RvIGZpZWxkID0gMjsKKyAgICAvLyBhbmQgRmllbGREZXNjcmlwdG9yUHJvdG8ubmFtZSBoYXMgZmllbGQgbnVtYmVyIDE6CisgICAgLy8gICBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgICAgLy8KKyAgICAvLyBUaHVzLCB0aGUgYWJvdmUgcGF0aCBnaXZlcyB0aGUgbG9jYXRpb24gb2YgYSBmaWVsZCBuYW1lLiAgSWYgd2UgcmVtb3ZlZAorICAgIC8vIHRoZSBsYXN0IGVsZW1lbnQ6CisgICAgLy8gICBbIDQsIDMsIDIsIDcgXQorICAgIC8vIHRoaXMgcGF0aCByZWZlcnMgdG8gdGhlIHdob2xlIGZpZWxkIGRlY2xhcmF0aW9uIChmcm9tIHRoZSBiZWdpbm5pbmcKKyAgICAvLyBvZiB0aGUgbGFiZWwgdG8gdGhlIHRlcm1pbmF0aW5nIHNlbWljb2xvbikuCisgICAgcmVwZWF0ZWQgaW50MzIgcGF0aCA9IDEgW3BhY2tlZD10cnVlXTsKKworICAgIC8vIEFsd2F5cyBoYXMgZXhhY3RseSB0aHJlZSBvciBmb3VyIGVsZW1lbnRzOiBzdGFydCBsaW5lLCBzdGFydCBjb2x1bW4sCisgICAgLy8gZW5kIGxpbmUgKG9wdGlvbmFsLCBvdGhlcndpc2UgYXNzdW1lZCBzYW1lIGFzIHN0YXJ0IGxpbmUpLCBlbmQgY29sdW1uLgorICAgIC8vIFRoZXNlIGFyZSBwYWNrZWQgaW50byBhIHNpbmdsZSBmaWVsZCBmb3IgZWZmaWNpZW5jeS4gIE5vdGUgdGhhdCBsaW5lCisgICAgLy8gYW5kIGNvbHVtbiBudW1iZXJzIGFyZSB6ZXJvLWJhc2VkIC0tIHR5cGljYWxseSB5b3Ugd2lsbCB3YW50IHRvIGFkZAorICAgIC8vIDEgdG8gZWFjaCBiZWZvcmUgZGlzcGxheWluZyB0byBhIHVzZXIuCisgICAgcmVwZWF0ZWQgaW50MzIgc3BhbiA9IDIgW3BhY2tlZD10cnVlXTsKKworICAgIC8vIElmIHRoaXMgU291cmNlQ29kZUluZm8gcmVwcmVzZW50cyBhIGNvbXBsZXRlIGRlY2xhcmF0aW9uLCB0aGVzZSBhcmUgYW55CisgICAgLy8gY29tbWVudHMgYXBwZWFyaW5nIGJlZm9yZSBhbmQgYWZ0ZXIgdGhlIGRlY2xhcmF0aW9uIHdoaWNoIGFwcGVhciB0byBiZQorICAgIC8vIGF0dGFjaGVkIHRvIHRoZSBkZWNsYXJhdGlvbi4KKyAgICAvLworICAgIC8vIEEgc2VyaWVzIG9mIGxpbmUgY29tbWVudHMgYXBwZWFyaW5nIG9uIGNvbnNlY3V0aXZlIGxpbmVzLCB3aXRoIG5vIG90aGVyCisgICAgLy8gdG9rZW5zIGFwcGVhcmluZyBvbiB0aG9zZSBsaW5lcywgd2lsbCBiZSB0cmVhdGVkIGFzIGEgc2luZ2xlIGNvbW1lbnQuCisgICAgLy8KKyAgICAvLyBsZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzIHdpbGwga2VlcCBwYXJhZ3JhcGhzIG9mIGNvbW1lbnRzIHRoYXQgYXBwZWFyCisgICAgLy8gYmVmb3JlIChidXQgbm90IGNvbm5lY3RlZCB0bykgdGhlIGN1cnJlbnQgZWxlbWVudC4gRWFjaCBwYXJhZ3JhcGgsCisgICAgLy8gc2VwYXJhdGVkIGJ5IGVtcHR5IGxpbmVzLCB3aWxsIGJlIG9uZSBjb21tZW50IGVsZW1lbnQgaW4gdGhlIHJlcGVhdGVkCisgICAgLy8gZmllbGQuCisgICAgLy8KKyAgICAvLyBPbmx5IHRoZSBjb21tZW50IGNvbnRlbnQgaXMgcHJvdmlkZWQ7IGNvbW1lbnQgbWFya2VycyAoZS5nLiAvLykgYXJlCisgICAgLy8gc3RyaXBwZWQgb3V0LiAgRm9yIGJsb2NrIGNvbW1lbnRzLCBsZWFkaW5nIHdoaXRlc3BhY2UgYW5kIGFuIGFzdGVyaXNrCisgICAgLy8gd2lsbCBiZSBzdHJpcHBlZCBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgZWFjaCBsaW5lIG90aGVyIHRoYW4gdGhlIGZpcnN0LgorICAgIC8vIE5ld2xpbmVzIGFyZSBpbmNsdWRlZCBpbiB0aGUgb3V0cHV0LgorICAgIC8vCisgICAgLy8gRXhhbXBsZXM6CisgICAgLy8KKyAgICAvLyAgIG9wdGlvbmFsIGludDMyIGZvbyA9IDE7ICAvLyBDb21tZW50IGF0dGFjaGVkIHRvIGZvby4KKyAgICAvLyAgIC8vIENvbW1lbnQgYXR0YWNoZWQgdG8gYmFyLgorICAgIC8vICAgb3B0aW9uYWwgaW50MzIgYmFyID0gMjsKKyAgICAvLworICAgIC8vICAgb3B0aW9uYWwgc3RyaW5nIGJheiA9IDM7CisgICAgLy8gICAvLyBDb21tZW50IGF0dGFjaGVkIHRvIGJhei4KKyAgICAvLyAgIC8vIEFub3RoZXIgbGluZSBhdHRhY2hlZCB0byBiYXouCisgICAgLy8KKyAgICAvLyAgIC8vIENvbW1lbnQgYXR0YWNoZWQgdG8gcXV4LgorICAgIC8vICAgLy8KKyAgICAvLyAgIC8vIEFub3RoZXIgbGluZSBhdHRhY2hlZCB0byBxdXguCisgICAgLy8gICBvcHRpb25hbCBkb3VibGUgcXV4ID0gNDsKKyAgICAvLworICAgIC8vICAgLy8gRGV0YWNoZWQgY29tbWVudCBmb3IgY29yZ2UuIFRoaXMgaXMgbm90IGxlYWRpbmcgb3IgdHJhaWxpbmcgY29tbWVudHMKKyAgICAvLyAgIC8vIHRvIHF1eCBvciBjb3JnZSBiZWNhdXNlIHRoZXJlIGFyZSBibGFuayBsaW5lcyBzZXBhcmF0aW5nIGl0IGZyb20KKyAgICAvLyAgIC8vIGJvdGguCisgICAgLy8KKyAgICAvLyAgIC8vIERldGFjaGVkIGNvbW1lbnQgZm9yIGNvcmdlIHBhcmFncmFwaCAyLgorICAgIC8vCisgICAgLy8gICBvcHRpb25hbCBzdHJpbmcgY29yZ2UgPSA1OworICAgIC8vICAgLyogQmxvY2sgY29tbWVudCBhdHRhY2hlZAorICAgIC8vICAgICogdG8gY29yZ2UuICBMZWFkaW5nIGFzdGVyaXNrcworICAgIC8vICAgICogd2lsbCBiZSByZW1vdmVkLiAqLworICAgIC8vICAgLyogQmxvY2sgY29tbWVudCBhdHRhY2hlZCB0bworICAgIC8vICAgICogZ3JhdWx0LiAqLworICAgIC8vICAgb3B0aW9uYWwgaW50MzIgZ3JhdWx0ID0gNjsKKyAgICAvLworICAgIC8vICAgLy8gaWdub3JlZCBkZXRhY2hlZCBjb21tZW50cy4KKyAgICBvcHRpb25hbCBzdHJpbmcgbGVhZGluZ19jb21tZW50cyA9IDM7CisgICAgb3B0aW9uYWwgc3RyaW5nIHRyYWlsaW5nX2NvbW1lbnRzID0gNDsKKyAgICByZXBlYXRlZCBzdHJpbmcgbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyA9IDY7CisgIH0KK30KKworLy8gRGVzY3JpYmVzIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBnZW5lcmF0ZWQgY29kZSBhbmQgaXRzIG9yaWdpbmFsIHNvdXJjZQorLy8gZmlsZS4gQSBHZW5lcmF0ZWRDb2RlSW5mbyBtZXNzYWdlIGlzIGFzc29jaWF0ZWQgd2l0aCBvbmx5IG9uZSBnZW5lcmF0ZWQKKy8vIHNvdXJjZSBmaWxlLCBidXQgbWF5IGNvbnRhaW4gcmVmZXJlbmNlcyB0byBkaWZmZXJlbnQgc291cmNlIC5wcm90byBmaWxlcy4KK21lc3NhZ2UgR2VuZXJhdGVkQ29kZUluZm8geworICAvLyBBbiBBbm5vdGF0aW9uIGNvbm5lY3RzIHNvbWUgc3BhbiBvZiB0ZXh0IGluIGdlbmVyYXRlZCBjb2RlIHRvIGFuIGVsZW1lbnQKKyAgLy8gb2YgaXRzIGdlbmVyYXRpbmcgLnByb3RvIGZpbGUuCisgIHJlcGVhdGVkIEFubm90YXRpb24gYW5ub3RhdGlvbiA9IDE7CisgIG1lc3NhZ2UgQW5ub3RhdGlvbiB7CisgICAgLy8gSWRlbnRpZmllcyB0aGUgZWxlbWVudCBpbiB0aGUgb3JpZ2luYWwgc291cmNlIC5wcm90byBmaWxlLiBUaGlzIGZpZWxkCisgICAgLy8gaXMgZm9ybWF0dGVkIHRoZSBzYW1lIGFzIFNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLnBhdGguCisgICAgcmVwZWF0ZWQgaW50MzIgcGF0aCA9IDEgW3BhY2tlZD10cnVlXTsKKworICAgIC8vIElkZW50aWZpZXMgdGhlIGZpbGVzeXN0ZW0gcGF0aCB0byB0aGUgb3JpZ2luYWwgc291cmNlIC5wcm90by4KKyAgICBvcHRpb25hbCBzdHJpbmcgc291cmNlX2ZpbGUgPSAyOworCisgICAgLy8gSWRlbnRpZmllcyB0aGUgc3RhcnRpbmcgb2Zmc2V0IGluIGJ5dGVzIGluIHRoZSBnZW5lcmF0ZWQgY29kZQorICAgIC8vIHRoYXQgcmVsYXRlcyB0byB0aGUgaWRlbnRpZmllZCBvYmplY3QuCisgICAgb3B0aW9uYWwgaW50MzIgYmVnaW4gPSAzOworCisgICAgLy8gSWRlbnRpZmllcyB0aGUgZW5kaW5nIG9mZnNldCBpbiBieXRlcyBpbiB0aGUgZ2VuZXJhdGVkIGNvZGUgdGhhdAorICAgIC8vIHJlbGF0ZXMgdG8gdGhlIGlkZW50aWZpZWQgb2Zmc2V0LiBUaGUgZW5kIG9mZnNldCBzaG91bGQgYmUgb25lIHBhc3QKKyAgICAvLyB0aGUgbGFzdCByZWxldmFudCBieXRlIChzbyB0aGUgbGVuZ3RoIG9mIHRoZSB0ZXh0ID0gZW5kIC0gYmVnaW4pLgorICAgIG9wdGlvbmFsIGludDMyIGVuZCA9IDQ7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvcl9kYXRhYmFzZS5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvcl9kYXRhYmFzZS5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMTE3YzAyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yX2RhdGFiYXNlLmNjCkBAIC0wLDAgKzEsNTQzIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvcl9kYXRhYmFzZS5oPgorCisjaW5jbHVkZSA8c2V0PgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZV9pbmwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdGxfdXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9tYXBfdXRpbC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKK0Rlc2NyaXB0b3JEYXRhYmFzZTo6fkRlc2NyaXB0b3JEYXRhYmFzZSgpIHt9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKwordGVtcGxhdGUgPHR5cGVuYW1lIFZhbHVlPgorYm9vbCBTaW1wbGVEZXNjcmlwdG9yRGF0YWJhc2U6OkRlc2NyaXB0b3JJbmRleDxWYWx1ZT46OkFkZEZpbGUoCisgICAgY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byYgZmlsZSwKKyAgICBWYWx1ZSB2YWx1ZSkgeworICBpZiAoIUluc2VydElmTm90UHJlc2VudCgmYnlfbmFtZV8sIGZpbGUubmFtZSgpLCB2YWx1ZSkpIHsKKyAgICBHT09HTEVfTE9HKEVSUk9SKSA8PCAiRmlsZSBhbHJlYWR5IGV4aXN0cyBpbiBkYXRhYmFzZTogIiA8PCBmaWxlLm5hbWUoKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLyBXZSBtdXN0IGJlIGNhcmVmdWwgaGVyZSAtLSBjYWxsaW5nIGZpbGUucGFja2FnZSgpIGlmIGZpbGUuaGFzX3BhY2thZ2UoKSBpcworICAvLyBmYWxzZSBjb3VsZCBhY2Nlc3MgYW4gdW5pbml0aWFsaXplZCBzdGF0aWMtc3RvcmFnZSB2YXJpYWJsZSBpZiB3ZSBhcmUgYmVpbmcKKyAgLy8gcnVuIGF0IHN0YXJ0dXAgdGltZS4KKyAgc3RyaW5nIHBhdGggPSBmaWxlLmhhc19wYWNrYWdlKCkgPyBmaWxlLnBhY2thZ2UoKSA6IHN0cmluZygpOworICBpZiAoIXBhdGguZW1wdHkoKSkgcGF0aCArPSAnLic7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlLm1lc3NhZ2VfdHlwZV9zaXplKCk7IGkrKykgeworICAgIGlmICghQWRkU3ltYm9sKHBhdGggKyBmaWxlLm1lc3NhZ2VfdHlwZShpKS5uYW1lKCksIHZhbHVlKSkgcmV0dXJuIGZhbHNlOworICAgIGlmICghQWRkTmVzdGVkRXh0ZW5zaW9ucyhmaWxlLm1lc3NhZ2VfdHlwZShpKSwgdmFsdWUpKSByZXR1cm4gZmFsc2U7CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlLmVudW1fdHlwZV9zaXplKCk7IGkrKykgeworICAgIGlmICghQWRkU3ltYm9sKHBhdGggKyBmaWxlLmVudW1fdHlwZShpKS5uYW1lKCksIHZhbHVlKSkgcmV0dXJuIGZhbHNlOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZS5leHRlbnNpb25fc2l6ZSgpOyBpKyspIHsKKyAgICBpZiAoIUFkZFN5bWJvbChwYXRoICsgZmlsZS5leHRlbnNpb24oaSkubmFtZSgpLCB2YWx1ZSkpIHJldHVybiBmYWxzZTsKKyAgICBpZiAoIUFkZEV4dGVuc2lvbihmaWxlLmV4dGVuc2lvbihpKSwgdmFsdWUpKSByZXR1cm4gZmFsc2U7CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlLnNlcnZpY2Vfc2l6ZSgpOyBpKyspIHsKKyAgICBpZiAoIUFkZFN5bWJvbChwYXRoICsgZmlsZS5zZXJ2aWNlKGkpLm5hbWUoKSwgdmFsdWUpKSByZXR1cm4gZmFsc2U7CisgIH0KKworICByZXR1cm4gdHJ1ZTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIFZhbHVlPgorYm9vbCBTaW1wbGVEZXNjcmlwdG9yRGF0YWJhc2U6OkRlc2NyaXB0b3JJbmRleDxWYWx1ZT46OkFkZFN5bWJvbCgKKyAgICBjb25zdCBzdHJpbmcmIG5hbWUsIFZhbHVlIHZhbHVlKSB7CisgIC8vIFdlIG5lZWQgdG8gbWFrZSBzdXJlIG5vdCB0byB2aW9sYXRlIG91ciBtYXAgaW52YXJpYW50LgorCisgIC8vIElmIHRoZSBzeW1ib2wgbmFtZSBpcyBpbnZhbGlkIGl0IGNvdWxkIGJyZWFrIG91ciBsb29rdXAgYWxnb3JpdGhtICh3aGljaAorICAvLyByZWxpZXMgb24gdGhlIGZhY3QgdGhhdCAnLicgc29ydHMgYmVmb3JlIGFsbCBvdGhlciBjaGFyYWN0ZXJzIHRoYXQgYXJlCisgIC8vIHZhbGlkIGluIHN5bWJvbCBuYW1lcykuCisgIGlmICghVmFsaWRhdGVTeW1ib2xOYW1lKG5hbWUpKSB7CisgICAgR09PR0xFX0xPRyhFUlJPUikgPDwgIkludmFsaWQgc3ltYm9sIG5hbWU6ICIgPDwgbmFtZTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLyBUcnkgdG8gbG9vayB1cCB0aGUgc3ltYm9sIHRvIG1ha2Ugc3VyZSBhIHN1cGVyLXN5bWJvbCBkb2Vzbid0IGFscmVhZHkKKyAgLy8gZXhpc3QuCisgIHR5cGVuYW1lIG1hcDxzdHJpbmcsIFZhbHVlPjo6aXRlcmF0b3IgaXRlciA9IEZpbmRMYXN0TGVzc09yRXF1YWwobmFtZSk7CisKKyAgaWYgKGl0ZXIgPT0gYnlfc3ltYm9sXy5lbmQoKSkgeworICAgIC8vIEFwcGFyZW50bHkgdGhlIG1hcCBpcyBjdXJyZW50bHkgZW1wdHkuICBKdXN0IGluc2VydCBhbmQgYmUgZG9uZSB3aXRoIGl0LgorICAgIGJ5X3N5bWJvbF8uaW5zZXJ0KHR5cGVuYW1lIG1hcDxzdHJpbmcsIFZhbHVlPjo6dmFsdWVfdHlwZShuYW1lLCB2YWx1ZSkpOworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgaWYgKElzU3ViU3ltYm9sKGl0ZXItPmZpcnN0LCBuYW1lKSkgeworICAgIEdPT0dMRV9MT0coRVJST1IpIDw8ICJTeW1ib2wgbmFtZSBcIiIgPDwgbmFtZSA8PCAiXCIgY29uZmxpY3RzIHdpdGggdGhlIGV4aXN0aW5nICIKKyAgICAgICAgICAgICAgICAgICJzeW1ib2wgXCIiIDw8IGl0ZXItPmZpcnN0IDw8ICJcIi4iOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vIE9LLCB0aGF0IHdvcmtlZC4gIE5vdyB3ZSBoYXZlIHRvIG1ha2Ugc3VyZSB0aGF0IG5vIHN5bWJvbCBpbiB0aGUgbWFwIGlzCisgIC8vIGEgc3ViLXN5bWJvbCBvZiB0aGUgb25lIHdlIGFyZSBpbnNlcnRpbmcuICBUaGUgb25seSBzeW1ib2wgd2hpY2ggY291bGQKKyAgLy8gYmUgc28gaXMgdGhlIGZpcnN0IHN5bWJvbCB0aGF0IGlzIGdyZWF0ZXIgdGhhbiB0aGUgbmV3IHN5bWJvbC4gIFNpbmNlCisgIC8vIHxpdGVyfCBwb2ludHMgYXQgdGhlIGxhc3Qgc3ltYm9sIHRoYXQgaXMgbGVzcyB0aGFuIG9yIGVxdWFsLCB3ZSBqdXN0IGhhdmUKKyAgLy8gdG8gaW5jcmVtZW50IGl0LgorICArK2l0ZXI7CisKKyAgaWYgKGl0ZXIgIT0gYnlfc3ltYm9sXy5lbmQoKSAmJiBJc1N1YlN5bWJvbChuYW1lLCBpdGVyLT5maXJzdCkpIHsKKyAgICBHT09HTEVfTE9HKEVSUk9SKSA8PCAiU3ltYm9sIG5hbWUgXCIiIDw8IG5hbWUgPDwgIlwiIGNvbmZsaWN0cyB3aXRoIHRoZSBleGlzdGluZyAiCisgICAgICAgICAgICAgICAgICAic3ltYm9sIFwiIiA8PCBpdGVyLT5maXJzdCA8PCAiXCIuIjsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLyBPSywgbm8gY29uZmxpY3RzLgorCisgIC8vIEluc2VydCB0aGUgbmV3IHN5bWJvbCB1c2luZyB0aGUgaXRlcmF0b3IgYXMgYSBoaW50LCB0aGUgbmV3IGVudHJ5IHdpbGwKKyAgLy8gYXBwZWFyIGltbWVkaWF0ZWx5IGJlZm9yZSB0aGUgb25lIHRoZSBpdGVyYXRvciBpcyBwb2ludGluZyBhdC4KKyAgYnlfc3ltYm9sXy5pbnNlcnQoaXRlciwgdHlwZW5hbWUgbWFwPHN0cmluZywgVmFsdWU+Ojp2YWx1ZV90eXBlKG5hbWUsIHZhbHVlKSk7CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBWYWx1ZT4KK2Jvb2wgU2ltcGxlRGVzY3JpcHRvckRhdGFiYXNlOjpEZXNjcmlwdG9ySW5kZXg8VmFsdWU+OjpBZGROZXN0ZWRFeHRlbnNpb25zKAorICAgIGNvbnN0IERlc2NyaXB0b3JQcm90byYgbWVzc2FnZV90eXBlLAorICAgIFZhbHVlIHZhbHVlKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgbWVzc2FnZV90eXBlLm5lc3RlZF90eXBlX3NpemUoKTsgaSsrKSB7CisgICAgaWYgKCFBZGROZXN0ZWRFeHRlbnNpb25zKG1lc3NhZ2VfdHlwZS5uZXN0ZWRfdHlwZShpKSwgdmFsdWUpKSByZXR1cm4gZmFsc2U7CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZXNzYWdlX3R5cGUuZXh0ZW5zaW9uX3NpemUoKTsgaSsrKSB7CisgICAgaWYgKCFBZGRFeHRlbnNpb24obWVzc2FnZV90eXBlLmV4dGVuc2lvbihpKSwgdmFsdWUpKSByZXR1cm4gZmFsc2U7CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBWYWx1ZT4KK2Jvb2wgU2ltcGxlRGVzY3JpcHRvckRhdGFiYXNlOjpEZXNjcmlwdG9ySW5kZXg8VmFsdWU+OjpBZGRFeHRlbnNpb24oCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yUHJvdG8mIGZpZWxkLAorICAgIFZhbHVlIHZhbHVlKSB7CisgIGlmICghZmllbGQuZXh0ZW5kZWUoKS5lbXB0eSgpICYmIGZpZWxkLmV4dGVuZGVlKClbMF0gPT0gJy4nKSB7CisgICAgLy8gVGhlIGV4dGVuc2lvbiBpcyBmdWxseS1xdWFsaWZpZWQuICBXZSBjYW4gdXNlIGl0IGFzIGEgbG9va3VwIGtleSBpbgorICAgIC8vIHRoZSBieV9zeW1ib2xfIHRhYmxlLgorICAgIGlmICghSW5zZXJ0SWZOb3RQcmVzZW50KAorICAgICAgICAgICAgJmJ5X2V4dGVuc2lvbl8sCisgICAgICAgICAgICBzdGQ6Om1ha2VfcGFpcihmaWVsZC5leHRlbmRlZSgpLnN1YnN0cigxKSwgZmllbGQubnVtYmVyKCkpLAorICAgICAgICAgICAgdmFsdWUpKSB7CisgICAgICBHT09HTEVfTE9HKEVSUk9SKSA8PCAiRXh0ZW5zaW9uIGNvbmZsaWN0cyB3aXRoIGV4dGVuc2lvbiBhbHJlYWR5IGluIGRhdGFiYXNlOiAiCisgICAgICAgICAgICAgICAgICAgICJleHRlbmQgIiA8PCBmaWVsZC5leHRlbmRlZSgpIDw8ICIgeyAiCisgICAgICAgICAgICAgICAgIDw8IGZpZWxkLm5hbWUoKSA8PCAiID0gIiA8PCBmaWVsZC5udW1iZXIoKSA8PCAiIH0iOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICAvLyBOb3QgZnVsbHktcXVhbGlmaWVkLiAgV2UgY2FuJ3QgcmVhbGx5IGRvIGFueXRoaW5nIGhlcmUsIHVuZm9ydHVuYXRlbHkuCisgICAgLy8gV2UgZG9uJ3QgY29uc2lkZXIgdGhpcyBhbiBlcnJvciwgdGhvdWdoLCBiZWNhdXNlIHRoZSBkZXNjcmlwdG9yIGlzCisgICAgLy8gdmFsaWQuCisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBWYWx1ZT4KK1ZhbHVlIFNpbXBsZURlc2NyaXB0b3JEYXRhYmFzZTo6RGVzY3JpcHRvckluZGV4PFZhbHVlPjo6RmluZEZpbGUoCisgICAgY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSkgeworICByZXR1cm4gRmluZFdpdGhEZWZhdWx0KGJ5X25hbWVfLCBmaWxlbmFtZSwgVmFsdWUoKSk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBWYWx1ZT4KK1ZhbHVlIFNpbXBsZURlc2NyaXB0b3JEYXRhYmFzZTo6RGVzY3JpcHRvckluZGV4PFZhbHVlPjo6RmluZFN5bWJvbCgKKyAgICBjb25zdCBzdHJpbmcmIG5hbWUpIHsKKyAgdHlwZW5hbWUgbWFwPHN0cmluZywgVmFsdWU+OjppdGVyYXRvciBpdGVyID0gRmluZExhc3RMZXNzT3JFcXVhbChuYW1lKTsKKworICByZXR1cm4gKGl0ZXIgIT0gYnlfc3ltYm9sXy5lbmQoKSAmJiBJc1N1YlN5bWJvbChpdGVyLT5maXJzdCwgbmFtZSkpID8KKyAgICAgICAgIGl0ZXItPnNlY29uZCA6IFZhbHVlKCk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBWYWx1ZT4KK1ZhbHVlIFNpbXBsZURlc2NyaXB0b3JEYXRhYmFzZTo6RGVzY3JpcHRvckluZGV4PFZhbHVlPjo6RmluZEV4dGVuc2lvbigKKyAgICBjb25zdCBzdHJpbmcmIGNvbnRhaW5pbmdfdHlwZSwKKyAgICBpbnQgZmllbGRfbnVtYmVyKSB7CisgIHJldHVybiBGaW5kV2l0aERlZmF1bHQoCisgICAgICBieV9leHRlbnNpb25fLCBzdGQ6Om1ha2VfcGFpcihjb250YWluaW5nX3R5cGUsIGZpZWxkX251bWJlciksIFZhbHVlKCkpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVmFsdWU+Citib29sIFNpbXBsZURlc2NyaXB0b3JEYXRhYmFzZTo6RGVzY3JpcHRvckluZGV4PFZhbHVlPjo6RmluZEFsbEV4dGVuc2lvbk51bWJlcnMoCisgICAgY29uc3Qgc3RyaW5nJiBjb250YWluaW5nX3R5cGUsCisgICAgdmVjdG9yPGludD4qIG91dHB1dCkgeworICB0eXBlbmFtZSBtYXA8cGFpcjxzdHJpbmcsIGludD4sIFZhbHVlPjo6Y29uc3RfaXRlcmF0b3IgaXQgPQorICAgICAgYnlfZXh0ZW5zaW9uXy5sb3dlcl9ib3VuZChzdGQ6Om1ha2VfcGFpcihjb250YWluaW5nX3R5cGUsIDApKTsKKyAgYm9vbCBzdWNjZXNzID0gZmFsc2U7CisKKyAgZm9yICg7IGl0ICE9IGJ5X2V4dGVuc2lvbl8uZW5kKCkgJiYgaXQtPmZpcnN0LmZpcnN0ID09IGNvbnRhaW5pbmdfdHlwZTsKKyAgICAgICArK2l0KSB7CisgICAgb3V0cHV0LT5wdXNoX2JhY2soaXQtPmZpcnN0LnNlY29uZCk7CisgICAgc3VjY2VzcyA9IHRydWU7CisgIH0KKworICByZXR1cm4gc3VjY2VzczsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIFZhbHVlPgordHlwZW5hbWUgbWFwPHN0cmluZywgVmFsdWU+OjppdGVyYXRvcgorU2ltcGxlRGVzY3JpcHRvckRhdGFiYXNlOjpEZXNjcmlwdG9ySW5kZXg8VmFsdWU+OjpGaW5kTGFzdExlc3NPckVxdWFsKAorICAgIGNvbnN0IHN0cmluZyYgbmFtZSkgeworICAvLyBGaW5kIHRoZSBsYXN0IGtleSBpbiB0aGUgbWFwIHdoaWNoIHNvcnRzIGxlc3MgdGhhbiBvciBlcXVhbCB0byB0aGUKKyAgLy8gc3ltYm9sIG5hbWUuICBTaW5jZSB1cHBlcl9ib3VuZCgpIHJldHVybnMgdGhlICpmaXJzdCoga2V5IHRoYXQgc29ydHMKKyAgLy8gKmdyZWF0ZXIqIHRoYW4gdGhlIGlucHV0LCB3ZSB3YW50IHRoZSBlbGVtZW50IGltbWVkaWF0ZWx5IGJlZm9yZSB0aGF0LgorICB0eXBlbmFtZSBtYXA8c3RyaW5nLCBWYWx1ZT46Oml0ZXJhdG9yIGl0ZXIgPSBieV9zeW1ib2xfLnVwcGVyX2JvdW5kKG5hbWUpOworICBpZiAoaXRlciAhPSBieV9zeW1ib2xfLmJlZ2luKCkpIC0taXRlcjsKKyAgcmV0dXJuIGl0ZXI7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBWYWx1ZT4KK2Jvb2wgU2ltcGxlRGVzY3JpcHRvckRhdGFiYXNlOjpEZXNjcmlwdG9ySW5kZXg8VmFsdWU+OjpJc1N1YlN5bWJvbCgKKyAgICBjb25zdCBzdHJpbmcmIHN1Yl9zeW1ib2wsIGNvbnN0IHN0cmluZyYgc3VwZXJfc3ltYm9sKSB7CisgIHJldHVybiBzdWJfc3ltYm9sID09IHN1cGVyX3N5bWJvbCB8fAorICAgICAgICAgKEhhc1ByZWZpeFN0cmluZyhzdXBlcl9zeW1ib2wsIHN1Yl9zeW1ib2wpICYmCisgICAgICAgICAgICAgc3VwZXJfc3ltYm9sW3N1Yl9zeW1ib2wuc2l6ZSgpXSA9PSAnLicpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVmFsdWU+Citib29sIFNpbXBsZURlc2NyaXB0b3JEYXRhYmFzZTo6RGVzY3JpcHRvckluZGV4PFZhbHVlPjo6VmFsaWRhdGVTeW1ib2xOYW1lKAorICAgIGNvbnN0IHN0cmluZyYgbmFtZSkgeworICBmb3IgKGludCBpID0gMDsgaSA8IG5hbWUuc2l6ZSgpOyBpKyspIHsKKyAgICAvLyBJIGRvbid0IHRydXN0IGN0eXBlLmggZHVlIHRvIGxvY2FsZXMuICA6KAorICAgIGlmIChuYW1lW2ldICE9ICcuJyAmJiBuYW1lW2ldICE9ICdfJyAmJgorICAgICAgICAobmFtZVtpXSA8ICcwJyB8fCBuYW1lW2ldID4gJzknKSAmJgorICAgICAgICAobmFtZVtpXSA8ICdBJyB8fCBuYW1lW2ldID4gJ1onKSAmJgorICAgICAgICAobmFtZVtpXSA8ICdhJyB8fCBuYW1lW2ldID4gJ3onKSkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgfQorICByZXR1cm4gdHJ1ZTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitTaW1wbGVEZXNjcmlwdG9yRGF0YWJhc2U6OlNpbXBsZURlc2NyaXB0b3JEYXRhYmFzZSgpIHt9CitTaW1wbGVEZXNjcmlwdG9yRGF0YWJhc2U6On5TaW1wbGVEZXNjcmlwdG9yRGF0YWJhc2UoKSB7CisgIFNUTERlbGV0ZUVsZW1lbnRzKCZmaWxlc190b19kZWxldGVfKTsKK30KKworYm9vbCBTaW1wbGVEZXNjcmlwdG9yRGF0YWJhc2U6OkFkZChjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvJiBmaWxlKSB7CisgIEZpbGVEZXNjcmlwdG9yUHJvdG8qIG5ld19maWxlID0gbmV3IEZpbGVEZXNjcmlwdG9yUHJvdG87CisgIG5ld19maWxlLT5Db3B5RnJvbShmaWxlKTsKKyAgcmV0dXJuIEFkZEFuZE93bihuZXdfZmlsZSk7Cit9CisKK2Jvb2wgU2ltcGxlRGVzY3JpcHRvckRhdGFiYXNlOjpBZGRBbmRPd24oY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byogZmlsZSkgeworICBmaWxlc190b19kZWxldGVfLnB1c2hfYmFjayhmaWxlKTsKKyAgcmV0dXJuIGluZGV4Xy5BZGRGaWxlKCpmaWxlLCBmaWxlKTsKK30KKworYm9vbCBTaW1wbGVEZXNjcmlwdG9yRGF0YWJhc2U6OkZpbmRGaWxlQnlOYW1lKAorICAgIGNvbnN0IHN0cmluZyYgZmlsZW5hbWUsCisgICAgRmlsZURlc2NyaXB0b3JQcm90byogb3V0cHV0KSB7CisgIHJldHVybiBNYXliZUNvcHkoaW5kZXhfLkZpbmRGaWxlKGZpbGVuYW1lKSwgb3V0cHV0KTsKK30KKworYm9vbCBTaW1wbGVEZXNjcmlwdG9yRGF0YWJhc2U6OkZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbCgKKyAgICBjb25zdCBzdHJpbmcmIHN5bWJvbF9uYW1lLAorICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8qIG91dHB1dCkgeworICByZXR1cm4gTWF5YmVDb3B5KGluZGV4Xy5GaW5kU3ltYm9sKHN5bWJvbF9uYW1lKSwgb3V0cHV0KTsKK30KKworYm9vbCBTaW1wbGVEZXNjcmlwdG9yRGF0YWJhc2U6OkZpbmRGaWxlQ29udGFpbmluZ0V4dGVuc2lvbigKKyAgICBjb25zdCBzdHJpbmcmIGNvbnRhaW5pbmdfdHlwZSwKKyAgICBpbnQgZmllbGRfbnVtYmVyLAorICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8qIG91dHB1dCkgeworICByZXR1cm4gTWF5YmVDb3B5KGluZGV4Xy5GaW5kRXh0ZW5zaW9uKGNvbnRhaW5pbmdfdHlwZSwgZmllbGRfbnVtYmVyKSwgb3V0cHV0KTsKK30KKworYm9vbCBTaW1wbGVEZXNjcmlwdG9yRGF0YWJhc2U6OkZpbmRBbGxFeHRlbnNpb25OdW1iZXJzKAorICAgIGNvbnN0IHN0cmluZyYgZXh0ZW5kZWVfdHlwZSwKKyAgICB2ZWN0b3I8aW50Piogb3V0cHV0KSB7CisgIHJldHVybiBpbmRleF8uRmluZEFsbEV4dGVuc2lvbk51bWJlcnMoZXh0ZW5kZWVfdHlwZSwgb3V0cHV0KTsKK30KKworCitib29sIFNpbXBsZURlc2NyaXB0b3JEYXRhYmFzZTo6TWF5YmVDb3B5KGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8qIGZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8qIG91dHB1dCkgeworICBpZiAoZmlsZSA9PSBOVUxMKSByZXR1cm4gZmFsc2U7CisgIG91dHB1dC0+Q29weUZyb20oKmZpbGUpOworICByZXR1cm4gdHJ1ZTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitFbmNvZGVkRGVzY3JpcHRvckRhdGFiYXNlOjpFbmNvZGVkRGVzY3JpcHRvckRhdGFiYXNlKCkge30KK0VuY29kZWREZXNjcmlwdG9yRGF0YWJhc2U6On5FbmNvZGVkRGVzY3JpcHRvckRhdGFiYXNlKCkgeworICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVzX3RvX2RlbGV0ZV8uc2l6ZSgpOyBpKyspIHsKKyAgICBvcGVyYXRvciBkZWxldGUoZmlsZXNfdG9fZGVsZXRlX1tpXSk7CisgIH0KK30KKworYm9vbCBFbmNvZGVkRGVzY3JpcHRvckRhdGFiYXNlOjpBZGQoCisgICAgY29uc3Qgdm9pZCogZW5jb2RlZF9maWxlX2Rlc2NyaXB0b3IsIGludCBzaXplKSB7CisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZTsKKyAgaWYgKGZpbGUuUGFyc2VGcm9tQXJyYXkoZW5jb2RlZF9maWxlX2Rlc2NyaXB0b3IsIHNpemUpKSB7CisgICAgcmV0dXJuIGluZGV4Xy5BZGRGaWxlKGZpbGUsIHN0ZDo6bWFrZV9wYWlyKGVuY29kZWRfZmlsZV9kZXNjcmlwdG9yLCBzaXplKSk7CisgIH0gZWxzZSB7CisgICAgR09PR0xFX0xPRyhFUlJPUikgPDwgIkludmFsaWQgZmlsZSBkZXNjcmlwdG9yIGRhdGEgcGFzc2VkIHRvICIKKyAgICAgICAgICAgICAgICAgICJFbmNvZGVkRGVzY3JpcHRvckRhdGFiYXNlOjpBZGQoKS4iOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorfQorCitib29sIEVuY29kZWREZXNjcmlwdG9yRGF0YWJhc2U6OkFkZENvcHkoCisgICAgY29uc3Qgdm9pZCogZW5jb2RlZF9maWxlX2Rlc2NyaXB0b3IsIGludCBzaXplKSB7CisgIHZvaWQqIGNvcHkgPSBvcGVyYXRvciBuZXcoc2l6ZSk7CisgIG1lbWNweShjb3B5LCBlbmNvZGVkX2ZpbGVfZGVzY3JpcHRvciwgc2l6ZSk7CisgIGZpbGVzX3RvX2RlbGV0ZV8ucHVzaF9iYWNrKGNvcHkpOworICByZXR1cm4gQWRkKGNvcHksIHNpemUpOworfQorCitib29sIEVuY29kZWREZXNjcmlwdG9yRGF0YWJhc2U6OkZpbmRGaWxlQnlOYW1lKAorICAgIGNvbnN0IHN0cmluZyYgZmlsZW5hbWUsCisgICAgRmlsZURlc2NyaXB0b3JQcm90byogb3V0cHV0KSB7CisgIHJldHVybiBNYXliZVBhcnNlKGluZGV4Xy5GaW5kRmlsZShmaWxlbmFtZSksIG91dHB1dCk7Cit9CisKK2Jvb2wgRW5jb2RlZERlc2NyaXB0b3JEYXRhYmFzZTo6RmluZEZpbGVDb250YWluaW5nU3ltYm9sKAorICAgIGNvbnN0IHN0cmluZyYgc3ltYm9sX25hbWUsCisgICAgRmlsZURlc2NyaXB0b3JQcm90byogb3V0cHV0KSB7CisgIHJldHVybiBNYXliZVBhcnNlKGluZGV4Xy5GaW5kU3ltYm9sKHN5bWJvbF9uYW1lKSwgb3V0cHV0KTsKK30KKworYm9vbCBFbmNvZGVkRGVzY3JpcHRvckRhdGFiYXNlOjpGaW5kTmFtZU9mRmlsZUNvbnRhaW5pbmdTeW1ib2woCisgICAgY29uc3Qgc3RyaW5nJiBzeW1ib2xfbmFtZSwKKyAgICBzdHJpbmcqIG91dHB1dCkgeworICBwYWlyPGNvbnN0IHZvaWQqLCBpbnQ+IGVuY29kZWRfZmlsZSA9IGluZGV4Xy5GaW5kU3ltYm9sKHN5bWJvbF9uYW1lKTsKKyAgaWYgKGVuY29kZWRfZmlsZS5maXJzdCA9PSBOVUxMKSByZXR1cm4gZmFsc2U7CisKKyAgLy8gT3B0aW1pemF0aW9uOiAgVGhlIG5hbWUgc2hvdWxkIGJlIHRoZSBmaXJzdCBmaWVsZCBpbiB0aGUgZW5jb2RlZCBtZXNzYWdlLgorICAvLyAgIFRyeSB0byBqdXN0IHJlYWQgaXQgZGlyZWN0bHkuCisgIGlvOjpDb2RlZElucHV0U3RyZWFtIGlucHV0KHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgdWludDgqPihlbmNvZGVkX2ZpbGUuZmlyc3QpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmNvZGVkX2ZpbGUuc2Vjb25kKTsKKworICBjb25zdCB1aW50MzIga05hbWVUYWcgPSBpbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1ha2VUYWcoCisgICAgICBGaWxlRGVzY3JpcHRvclByb3RvOjprTmFtZUZpZWxkTnVtYmVyLAorICAgICAgaW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVEKTsKKworICBpZiAoaW5wdXQuUmVhZFRhZygpID09IGtOYW1lVGFnKSB7CisgICAgLy8gU3VjY2VzcyEKKyAgICByZXR1cm4gaW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkU3RyaW5nKCZpbnB1dCwgb3V0cHV0KTsKKyAgfSBlbHNlIHsKKyAgICAvLyBTbG93IHBhdGguICBQYXJzZSB3aG9sZSBtZXNzYWdlLgorICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZV9wcm90bzsKKyAgICBpZiAoIWZpbGVfcHJvdG8uUGFyc2VGcm9tQXJyYXkoZW5jb2RlZF9maWxlLmZpcnN0LCBlbmNvZGVkX2ZpbGUuc2Vjb25kKSkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICAqb3V0cHV0ID0gZmlsZV9wcm90by5uYW1lKCk7CisgICAgcmV0dXJuIHRydWU7CisgIH0KK30KKworYm9vbCBFbmNvZGVkRGVzY3JpcHRvckRhdGFiYXNlOjpGaW5kRmlsZUNvbnRhaW5pbmdFeHRlbnNpb24oCisgICAgY29uc3Qgc3RyaW5nJiBjb250YWluaW5nX3R5cGUsCisgICAgaW50IGZpZWxkX251bWJlciwKKyAgICBGaWxlRGVzY3JpcHRvclByb3RvKiBvdXRwdXQpIHsKKyAgcmV0dXJuIE1heWJlUGFyc2UoaW5kZXhfLkZpbmRFeHRlbnNpb24oY29udGFpbmluZ190eXBlLCBmaWVsZF9udW1iZXIpLAorICAgICAgICAgICAgICAgICAgICBvdXRwdXQpOworfQorCitib29sIEVuY29kZWREZXNjcmlwdG9yRGF0YWJhc2U6OkZpbmRBbGxFeHRlbnNpb25OdW1iZXJzKAorICAgIGNvbnN0IHN0cmluZyYgZXh0ZW5kZWVfdHlwZSwKKyAgICB2ZWN0b3I8aW50Piogb3V0cHV0KSB7CisgIHJldHVybiBpbmRleF8uRmluZEFsbEV4dGVuc2lvbk51bWJlcnMoZXh0ZW5kZWVfdHlwZSwgb3V0cHV0KTsKK30KKworYm9vbCBFbmNvZGVkRGVzY3JpcHRvckRhdGFiYXNlOjpNYXliZVBhcnNlKAorICAgIHBhaXI8Y29uc3Qgdm9pZCosIGludD4gZW5jb2RlZF9maWxlLAorICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8qIG91dHB1dCkgeworICBpZiAoZW5jb2RlZF9maWxlLmZpcnN0ID09IE5VTEwpIHJldHVybiBmYWxzZTsKKyAgcmV0dXJuIG91dHB1dC0+UGFyc2VGcm9tQXJyYXkoZW5jb2RlZF9maWxlLmZpcnN0LCBlbmNvZGVkX2ZpbGUuc2Vjb25kKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitEZXNjcmlwdG9yUG9vbERhdGFiYXNlOjpEZXNjcmlwdG9yUG9vbERhdGFiYXNlKGNvbnN0IERlc2NyaXB0b3JQb29sJiBwb29sKQorICA6IHBvb2xfKHBvb2wpIHt9CitEZXNjcmlwdG9yUG9vbERhdGFiYXNlOjp+RGVzY3JpcHRvclBvb2xEYXRhYmFzZSgpIHt9CisKK2Jvb2wgRGVzY3JpcHRvclBvb2xEYXRhYmFzZTo6RmluZEZpbGVCeU5hbWUoCisgICAgY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSwKKyAgICBGaWxlRGVzY3JpcHRvclByb3RvKiBvdXRwdXQpIHsKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUgPSBwb29sXy5GaW5kRmlsZUJ5TmFtZShmaWxlbmFtZSk7CisgIGlmIChmaWxlID09IE5VTEwpIHJldHVybiBmYWxzZTsKKyAgb3V0cHV0LT5DbGVhcigpOworICBmaWxlLT5Db3B5VG8ob3V0cHV0KTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgRGVzY3JpcHRvclBvb2xEYXRhYmFzZTo6RmluZEZpbGVDb250YWluaW5nU3ltYm9sKAorICAgIGNvbnN0IHN0cmluZyYgc3ltYm9sX25hbWUsCisgICAgRmlsZURlc2NyaXB0b3JQcm90byogb3V0cHV0KSB7CisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlID0gcG9vbF8uRmluZEZpbGVDb250YWluaW5nU3ltYm9sKHN5bWJvbF9uYW1lKTsKKyAgaWYgKGZpbGUgPT0gTlVMTCkgcmV0dXJuIGZhbHNlOworICBvdXRwdXQtPkNsZWFyKCk7CisgIGZpbGUtPkNvcHlUbyhvdXRwdXQpOworICByZXR1cm4gdHJ1ZTsKK30KKworYm9vbCBEZXNjcmlwdG9yUG9vbERhdGFiYXNlOjpGaW5kRmlsZUNvbnRhaW5pbmdFeHRlbnNpb24oCisgICAgY29uc3Qgc3RyaW5nJiBjb250YWluaW5nX3R5cGUsCisgICAgaW50IGZpZWxkX251bWJlciwKKyAgICBGaWxlRGVzY3JpcHRvclByb3RvKiBvdXRwdXQpIHsKKyAgY29uc3QgRGVzY3JpcHRvciogZXh0ZW5kZWUgPSBwb29sXy5GaW5kTWVzc2FnZVR5cGVCeU5hbWUoY29udGFpbmluZ190eXBlKTsKKyAgaWYgKGV4dGVuZGVlID09IE5VTEwpIHJldHVybiBmYWxzZTsKKworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGV4dGVuc2lvbiA9CisgICAgcG9vbF8uRmluZEV4dGVuc2lvbkJ5TnVtYmVyKGV4dGVuZGVlLCBmaWVsZF9udW1iZXIpOworICBpZiAoZXh0ZW5zaW9uID09IE5VTEwpIHJldHVybiBmYWxzZTsKKworICBvdXRwdXQtPkNsZWFyKCk7CisgIGV4dGVuc2lvbi0+ZmlsZSgpLT5Db3B5VG8ob3V0cHV0KTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgRGVzY3JpcHRvclBvb2xEYXRhYmFzZTo6RmluZEFsbEV4dGVuc2lvbk51bWJlcnMoCisgICAgY29uc3Qgc3RyaW5nJiBleHRlbmRlZV90eXBlLAorICAgIHZlY3RvcjxpbnQ+KiBvdXRwdXQpIHsKKyAgY29uc3QgRGVzY3JpcHRvciogZXh0ZW5kZWUgPSBwb29sXy5GaW5kTWVzc2FnZVR5cGVCeU5hbWUoZXh0ZW5kZWVfdHlwZSk7CisgIGlmIChleHRlbmRlZSA9PSBOVUxMKSByZXR1cm4gZmFsc2U7CisKKyAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+IGV4dGVuc2lvbnM7CisgIHBvb2xfLkZpbmRBbGxFeHRlbnNpb25zKGV4dGVuZGVlLCAmZXh0ZW5zaW9ucyk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBleHRlbnNpb25zLnNpemUoKTsgKytpKSB7CisgICAgb3V0cHV0LT5wdXNoX2JhY2soZXh0ZW5zaW9uc1tpXS0+bnVtYmVyKCkpOworICB9CisKKyAgcmV0dXJuIHRydWU7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworTWVyZ2VkRGVzY3JpcHRvckRhdGFiYXNlOjpNZXJnZWREZXNjcmlwdG9yRGF0YWJhc2UoCisgICAgRGVzY3JpcHRvckRhdGFiYXNlKiBzb3VyY2UxLAorICAgIERlc2NyaXB0b3JEYXRhYmFzZSogc291cmNlMikgeworICBzb3VyY2VzXy5wdXNoX2JhY2soc291cmNlMSk7CisgIHNvdXJjZXNfLnB1c2hfYmFjayhzb3VyY2UyKTsKK30KK01lcmdlZERlc2NyaXB0b3JEYXRhYmFzZTo6TWVyZ2VkRGVzY3JpcHRvckRhdGFiYXNlKAorICAgIGNvbnN0IHZlY3RvcjxEZXNjcmlwdG9yRGF0YWJhc2UqPiYgc291cmNlcykKKyAgOiBzb3VyY2VzXyhzb3VyY2VzKSB7fQorTWVyZ2VkRGVzY3JpcHRvckRhdGFiYXNlOjp+TWVyZ2VkRGVzY3JpcHRvckRhdGFiYXNlKCkge30KKworYm9vbCBNZXJnZWREZXNjcmlwdG9yRGF0YWJhc2U6OkZpbmRGaWxlQnlOYW1lKAorICAgIGNvbnN0IHN0cmluZyYgZmlsZW5hbWUsCisgICAgRmlsZURlc2NyaXB0b3JQcm90byogb3V0cHV0KSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgc291cmNlc18uc2l6ZSgpOyBpKyspIHsKKyAgICBpZiAoc291cmNlc19baV0tPkZpbmRGaWxlQnlOYW1lKGZpbGVuYW1lLCBvdXRwdXQpKSB7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIGZhbHNlOworfQorCitib29sIE1lcmdlZERlc2NyaXB0b3JEYXRhYmFzZTo6RmluZEZpbGVDb250YWluaW5nU3ltYm9sKAorICAgIGNvbnN0IHN0cmluZyYgc3ltYm9sX25hbWUsCisgICAgRmlsZURlc2NyaXB0b3JQcm90byogb3V0cHV0KSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgc291cmNlc18uc2l6ZSgpOyBpKyspIHsKKyAgICBpZiAoc291cmNlc19baV0tPkZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbChzeW1ib2xfbmFtZSwgb3V0cHV0KSkgeworICAgICAgLy8gVGhlIHN5bWJvbCB3YXMgZm91bmQgaW4gc291cmNlIGkuICBIb3dldmVyLCBpZiBvbmUgb2YgdGhlIHByZXZpb3VzCisgICAgICAvLyBzb3VyY2VzIGRlZmluZXMgYSBmaWxlIHdpdGggdGhlIHNhbWUgbmFtZSAod2hpY2ggcHJlc3VtYWJseSBkb2Vzbid0CisgICAgICAvLyBjb250YWluIHRoZSBzeW1ib2wsIHNpbmNlIGl0IHdhc24ndCBmb3VuZCBpbiB0aGF0IHNvdXJjZSksIHRoZW4gd2UKKyAgICAgIC8vIG11c3QgaGlkZSBpdCBmcm9tIHRoZSBjYWxsZXIuCisgICAgICBGaWxlRGVzY3JpcHRvclByb3RvIHRlbXA7CisgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGk7IGorKykgeworICAgICAgICBpZiAoc291cmNlc19bal0tPkZpbmRGaWxlQnlOYW1lKG91dHB1dC0+bmFtZSgpLCAmdGVtcCkpIHsKKyAgICAgICAgICAvLyBGb3VuZCBjb25mbGljdGluZyBmaWxlIGluIGEgcHJldmlvdXMgc291cmNlLgorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICB9CisgIHJldHVybiBmYWxzZTsKK30KKworYm9vbCBNZXJnZWREZXNjcmlwdG9yRGF0YWJhc2U6OkZpbmRGaWxlQ29udGFpbmluZ0V4dGVuc2lvbigKKyAgICBjb25zdCBzdHJpbmcmIGNvbnRhaW5pbmdfdHlwZSwKKyAgICBpbnQgZmllbGRfbnVtYmVyLAorICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8qIG91dHB1dCkgeworICBmb3IgKGludCBpID0gMDsgaSA8IHNvdXJjZXNfLnNpemUoKTsgaSsrKSB7CisgICAgaWYgKHNvdXJjZXNfW2ldLT5GaW5kRmlsZUNvbnRhaW5pbmdFeHRlbnNpb24oCisgICAgICAgICAgY29udGFpbmluZ190eXBlLCBmaWVsZF9udW1iZXIsIG91dHB1dCkpIHsKKyAgICAgIC8vIFRoZSBzeW1ib2wgd2FzIGZvdW5kIGluIHNvdXJjZSBpLiAgSG93ZXZlciwgaWYgb25lIG9mIHRoZSBwcmV2aW91cworICAgICAgLy8gc291cmNlcyBkZWZpbmVzIGEgZmlsZSB3aXRoIHRoZSBzYW1lIG5hbWUgKHdoaWNoIHByZXN1bWFibHkgZG9lc24ndAorICAgICAgLy8gY29udGFpbiB0aGUgc3ltYm9sLCBzaW5jZSBpdCB3YXNuJ3QgZm91bmQgaW4gdGhhdCBzb3VyY2UpLCB0aGVuIHdlCisgICAgICAvLyBtdXN0IGhpZGUgaXQgZnJvbSB0aGUgY2FsbGVyLgorICAgICAgRmlsZURlc2NyaXB0b3JQcm90byB0ZW1wOworICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBpOyBqKyspIHsKKyAgICAgICAgaWYgKHNvdXJjZXNfW2pdLT5GaW5kRmlsZUJ5TmFtZShvdXRwdXQtPm5hbWUoKSwgJnRlbXApKSB7CisgICAgICAgICAgLy8gRm91bmQgY29uZmxpY3RpbmcgZmlsZSBpbiBhIHByZXZpb3VzIHNvdXJjZS4KKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgfQorICByZXR1cm4gZmFsc2U7Cit9CisKK2Jvb2wgTWVyZ2VkRGVzY3JpcHRvckRhdGFiYXNlOjpGaW5kQWxsRXh0ZW5zaW9uTnVtYmVycygKKyAgICBjb25zdCBzdHJpbmcmIGV4dGVuZGVlX3R5cGUsCisgICAgdmVjdG9yPGludD4qIG91dHB1dCkgeworICBzZXQ8aW50PiBtZXJnZWRfcmVzdWx0czsKKyAgdmVjdG9yPGludD4gcmVzdWx0czsKKyAgYm9vbCBzdWNjZXNzID0gZmFsc2U7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBzb3VyY2VzXy5zaXplKCk7IGkrKykgeworICAgIGlmIChzb3VyY2VzX1tpXS0+RmluZEFsbEV4dGVuc2lvbk51bWJlcnMoZXh0ZW5kZWVfdHlwZSwgJnJlc3VsdHMpKSB7CisgICAgICBzdGQ6OmNvcHkoCisgICAgICAgICAgcmVzdWx0cy5iZWdpbigpLCByZXN1bHRzLmVuZCgpLAorICAgICAgICAgIGluc2VydF9pdGVyYXRvcjxzZXQ8aW50PiA+KG1lcmdlZF9yZXN1bHRzLCBtZXJnZWRfcmVzdWx0cy5iZWdpbigpKSk7CisgICAgICBzdWNjZXNzID0gdHJ1ZTsKKyAgICB9CisgICAgcmVzdWx0cy5jbGVhcigpOworICB9CisKKyAgc3RkOjpjb3B5KG1lcmdlZF9yZXN1bHRzLmJlZ2luKCksIG1lcmdlZF9yZXN1bHRzLmVuZCgpLAorICAgICAgICAgICAgaW5zZXJ0X2l0ZXJhdG9yPHZlY3RvcjxpbnQ+ID4oKm91dHB1dCwgb3V0cHV0LT5lbmQoKSkpOworCisgIHJldHVybiBzdWNjZXNzOworfQorCisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yX2RhdGFiYXNlLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3JfZGF0YWJhc2UuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NjAwMmQ1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yX2RhdGFiYXNlLmgKQEAgLTAsMCArMSwzNjkgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBJbnRlcmZhY2UgZm9yIG1hbmlwdWxhdGluZyBkYXRhYmFzZXMgb2YgZGVzY3JpcHRvcnMuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0RFU0NSSVBUT1JfREFUQUJBU0VfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9ERVNDUklQVE9SX0RBVEFCQVNFX0hfXworCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDx1dGlsaXR5PgorI2luY2x1ZGUgPHZlY3Rvcj4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCisvLyBEZWZpbmVkIGluIHRoaXMgZmlsZS4KK2NsYXNzIERlc2NyaXB0b3JEYXRhYmFzZTsKK2NsYXNzIFNpbXBsZURlc2NyaXB0b3JEYXRhYmFzZTsKK2NsYXNzIEVuY29kZWREZXNjcmlwdG9yRGF0YWJhc2U7CitjbGFzcyBEZXNjcmlwdG9yUG9vbERhdGFiYXNlOworY2xhc3MgTWVyZ2VkRGVzY3JpcHRvckRhdGFiYXNlOworCisvLyBBYnN0cmFjdCBpbnRlcmZhY2UgZm9yIGEgZGF0YWJhc2Ugb2YgZGVzY3JpcHRvcnMuCisvLworLy8gVGhpcyBpcyB1c2VmdWwgaWYgeW91IHdhbnQgdG8gY3JlYXRlIGEgRGVzY3JpcHRvclBvb2wgd2hpY2ggbG9hZHMKKy8vIGRlc2NyaXB0b3JzIG9uLWRlbWFuZCBmcm9tIHNvbWUgc29ydCBvZiBsYXJnZSBkYXRhYmFzZS4gIElmIHRoZSBkYXRhYmFzZQorLy8gaXMgbGFyZ2UsIGl0IG1heSBiZSBpbmVmZmljaWVudCB0byBlbnVtZXJhdGUgZXZlcnkgLnByb3RvIGZpbGUgaW5zaWRlIGl0CisvLyBjYWxsaW5nIERlc2NyaXB0b3JQb29sOjpCdWlsZEZpbGUoKSBmb3IgZWFjaCBvbmUuICBJbnN0ZWFkLCBhIERlc2NyaXB0b3JQb29sCisvLyBjYW4gYmUgY3JlYXRlZCB3aGljaCB3cmFwcyBhIERlc2NyaXB0b3JEYXRhYmFzZSBhbmQgb25seSBidWlsZHMgcGFydGljdWxhcgorLy8gZGVzY3JpcHRvcnMgd2hlbiB0aGV5IGFyZSBuZWVkZWQuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgRGVzY3JpcHRvckRhdGFiYXNlIHsKKyBwdWJsaWM6CisgIGlubGluZSBEZXNjcmlwdG9yRGF0YWJhc2UoKSB7fQorICB2aXJ0dWFsIH5EZXNjcmlwdG9yRGF0YWJhc2UoKTsKKworICAvLyBGaW5kIGEgZmlsZSBieSBmaWxlIG5hbWUuICBGaWxscyBpbiBpbiAqb3V0cHV0IGFuZCByZXR1cm5zIHRydWUgaWYgZm91bmQuCisgIC8vIE90aGVyd2lzZSwgcmV0dXJucyBmYWxzZSwgbGVhdmluZyB0aGUgY29udGVudHMgb2YgKm91dHB1dCB1bmRlZmluZWQuCisgIHZpcnR1YWwgYm9vbCBGaW5kRmlsZUJ5TmFtZShjb25zdCBzdHJpbmcmIGZpbGVuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmlsZURlc2NyaXB0b3JQcm90byogb3V0cHV0KSA9IDA7CisKKyAgLy8gRmluZCB0aGUgZmlsZSB0aGF0IGRlY2xhcmVzIHRoZSBnaXZlbiBmdWxseS1xdWFsaWZpZWQgc3ltYm9sIG5hbWUuCisgIC8vIElmIGZvdW5kLCBmaWxscyBpbiAqb3V0cHV0IGFuZCByZXR1cm5zIHRydWUsIG90aGVyd2lzZSByZXR1cm5zIGZhbHNlCisgIC8vIGFuZCBsZWF2ZXMgKm91dHB1dCB1bmRlZmluZWQuCisgIHZpcnR1YWwgYm9vbCBGaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2woY29uc3Qgc3RyaW5nJiBzeW1ib2xfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlRGVzY3JpcHRvclByb3RvKiBvdXRwdXQpID0gMDsKKworICAvLyBGaW5kIHRoZSBmaWxlIHdoaWNoIGRlZmluZXMgYW4gZXh0ZW5zaW9uIGV4dGVuZGluZyB0aGUgZ2l2ZW4gbWVzc2FnZSB0eXBlCisgIC8vIHdpdGggdGhlIGdpdmVuIGZpZWxkIG51bWJlci4gIElmIGZvdW5kLCBmaWxscyBpbiAqb3V0cHV0IGFuZCByZXR1cm5zIHRydWUsCisgIC8vIG90aGVyd2lzZSByZXR1cm5zIGZhbHNlIGFuZCBsZWF2ZXMgKm91dHB1dCB1bmRlZmluZWQuICBjb250YWluaW5nX3R5cGUKKyAgLy8gbXVzdCBiZSBhIGZ1bGx5LXF1YWxpZmllZCB0eXBlIG5hbWUuCisgIHZpcnR1YWwgYm9vbCBGaW5kRmlsZUNvbnRhaW5pbmdFeHRlbnNpb24oY29uc3Qgc3RyaW5nJiBjb250YWluaW5nX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlRGVzY3JpcHRvclByb3RvKiBvdXRwdXQpID0gMDsKKworICAvLyBGaW5kcyB0aGUgdGFnIG51bWJlcnMgdXNlZCBieSBhbGwga25vd24gZXh0ZW5zaW9ucyBvZgorICAvLyBleHRlbmRlZV90eXBlLCBhbmQgYXBwZW5kcyB0aGVtIHRvIG91dHB1dCBpbiBhbiB1bmRlZmluZWQKKyAgLy8gb3JkZXIuIFRoaXMgbWV0aG9kIGlzIGJlc3QtZWZmb3J0OiBpdCdzIG5vdCBndWFyYW50ZWVkIHRoYXQgdGhlCisgIC8vIGRhdGFiYXNlIHdpbGwgZmluZCBhbGwgZXh0ZW5zaW9ucywgYW5kIGl0J3Mgbm90IGd1YXJhbnRlZWQgdGhhdAorICAvLyBGaW5kRmlsZUNvbnRhaW5pbmdFeHRlbnNpb24gd2lsbCByZXR1cm4gdHJ1ZSBvbiBhbGwgb2YgdGhlIGZvdW5kCisgIC8vIG51bWJlcnMuIFJldHVybnMgdHJ1ZSBpZiB0aGUgc2VhcmNoIHdhcyBzdWNjZXNzZnVsLCBvdGhlcndpc2UKKyAgLy8gcmV0dXJucyBmYWxzZSBhbmQgbGVhdmVzIG91dHB1dCB1bmNoYW5nZWQuCisgIC8vCisgIC8vIFRoaXMgbWV0aG9kIGhhcyBhIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gdGhhdCBhbHdheXMgcmV0dXJucworICAvLyBmYWxzZS4KKyAgdmlydHVhbCBib29sIEZpbmRBbGxFeHRlbnNpb25OdW1iZXJzKGNvbnN0IHN0cmluZyYgLyogZXh0ZW5kZWVfdHlwZSAqLywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlY3RvcjxpbnQ+KiAvKiBvdXRwdXQgKi8pIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKERlc2NyaXB0b3JEYXRhYmFzZSk7Cit9OworCisvLyBBIERlc2NyaXB0b3JEYXRhYmFzZSBpbnRvIHdoaWNoIHlvdSBjYW4gaW5zZXJ0IGZpbGVzIG1hbnVhbGx5LgorLy8KKy8vIEZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbCgpIGlzIGZ1bGx5LWltcGxlbWVudGVkLiAgV2hlbiB5b3UgYWRkIGEgZmlsZSwgaXRzCisvLyBzeW1ib2xzIHdpbGwgYmUgaW5kZXhlZCBmb3IgdGhpcyBwdXJwb3NlLiAgTm90ZSB0aGF0IHRoZSBpbXBsZW1lbnRhdGlvbgorLy8gbWF5IHJldHVybiBmYWxzZSBwb3NpdGl2ZXMsIGJ1dCBvbmx5IGlmIGl0IGlzbid0IHBvc3NpYmxlIGZvciB0aGUgc3ltYm9sCisvLyB0byBiZSBkZWZpbmVkIGluIGFueSBvdGhlciBmaWxlLiAgSW4gcGFydGljdWxhciwgaWYgYSBmaWxlIGRlZmluZXMgYSBzeW1ib2wKKy8vICJGb28iLCB0aGVuIHNlYXJjaGluZyBmb3IgIkZvby5bYW55dGhpbmddIiB3aWxsIG1hdGNoIHRoYXQgZmlsZS4gIFRoaXMgd2F5LAorLy8gdGhlIGRhdGFiYXNlIGRvZXMgbm90IG5lZWQgdG8gYWdncmVzc2l2ZWx5IGluZGV4IGFsbCBjaGlsZHJlbiBvZiBhIHN5bWJvbC4KKy8vCisvLyBGaW5kRmlsZUNvbnRhaW5pbmdFeHRlbnNpb24oKSBpcyBtb3N0bHktaW1wbGVtZW50ZWQuICBJdCB3b3JrcyBpZiBhbmQgb25seQorLy8gaWYgdGhlIG9yaWdpbmFsIEZpZWxkRGVzY3JpcHRvclByb3RvIGRlZmluaW5nIHRoZSBleHRlbnNpb24gaGFzIGEKKy8vIGZ1bGx5LXF1YWxpZmllZCB0eXBlIG5hbWUgaW4gaXRzICJleHRlbmRlZSIgZmllbGQgKGkuZS4gc3RhcnRzIHdpdGggYSAnLicpLgorLy8gSWYgdGhlIGV4dGVuZGVlIGlzIGEgcmVsYXRpdmUgbmFtZSwgU2ltcGxlRGVzY3JpcHRvckRhdGFiYXNlIHdpbGwgbm90CisvLyBhdHRlbXB0IHRvIHJlc29sdmUgdGhlIHR5cGUsIHNvIGl0IHdpbGwgbm90IGtub3cgd2hhdCB0eXBlIHRoZSBleHRlbnNpb24gaXMKKy8vIGV4dGVuZGluZy4gIFRoZXJlZm9yZSwgY2FsbGluZyBGaW5kRmlsZUNvbnRhaW5pbmdFeHRlbnNpb24oKSB3aXRoIHRoZQorLy8gZXh0ZW5zaW9uJ3MgY29udGFpbmluZyB0eXBlIHdpbGwgbmV2ZXIgYWN0dWFsbHkgZmluZCB0aGF0IGV4dGVuc2lvbi4gIE5vdGUKKy8vIHRoYXQgdGhpcyBpcyBhbiB1bmxpa2VseSBwcm9ibGVtLCBhcyBhbGwgRmlsZURlc2NyaXB0b3JQcm90b3MgY3JlYXRlZCBieSB0aGUKKy8vIHByb3RvY29sIGNvbXBpbGVyIChhcyB3ZWxsIGFzIG9uZXMgY3JlYXRlZCBieSBjYWxsaW5nCisvLyBGaWxlRGVzY3JpcHRvcjo6Q29weVRvKCkpIHdpbGwgYWx3YXlzIHVzZSBmdWxseS1xdWFsaWZpZWQgbmFtZXMgZm9yIGFsbAorLy8gdHlwZXMuICBZb3Ugb25seSBuZWVkIHRvIHdvcnJ5IGlmIHlvdSBhcmUgY29uc3RydWN0aW5nIEZpbGVEZXNjcmlwdG9yUHJvdG9zCisvLyB5b3Vyc2VsZiwgb3IgYXJlIGNhbGxpbmcgY29tcGlsZXI6OlBhcnNlciBkaXJlY3RseS4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBTaW1wbGVEZXNjcmlwdG9yRGF0YWJhc2UgOiBwdWJsaWMgRGVzY3JpcHRvckRhdGFiYXNlIHsKKyBwdWJsaWM6CisgIFNpbXBsZURlc2NyaXB0b3JEYXRhYmFzZSgpOworICB+U2ltcGxlRGVzY3JpcHRvckRhdGFiYXNlKCk7CisKKyAgLy8gQWRkcyB0aGUgRmlsZURlc2NyaXB0b3JQcm90byB0byB0aGUgZGF0YWJhc2UsIG1ha2luZyBhIGNvcHkuICBUaGUgb2JqZWN0CisgIC8vIGNhbiBiZSBkZWxldGVkIGFmdGVyIEFkZCgpIHJldHVybnMuICBSZXR1cm5zIGZhbHNlIGlmIHRoZSBmaWxlIGNvbmZsaWN0ZWQKKyAgLy8gd2l0aCBhIGZpbGUgYWxyZWFkeSBpbiB0aGUgZGF0YWJhc2UsIGluIHdoaWNoIGNhc2UgYW4gZXJyb3Igd2lsbCBoYXZlCisgIC8vIGJlZW4gd3JpdHRlbiB0byBHT09HTEVfTE9HKEVSUk9SKS4KKyAgYm9vbCBBZGQoY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byYgZmlsZSk7CisKKyAgLy8gQWRkcyB0aGUgRmlsZURlc2NyaXB0b3JQcm90byB0byB0aGUgZGF0YWJhc2UgYW5kIHRha2VzIG93bmVyc2hpcCBvZiBpdC4KKyAgYm9vbCBBZGRBbmRPd24oY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byogZmlsZSk7CisKKyAgLy8gaW1wbGVtZW50cyBEZXNjcmlwdG9yRGF0YWJhc2UgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgYm9vbCBGaW5kRmlsZUJ5TmFtZShjb25zdCBzdHJpbmcmIGZpbGVuYW1lLAorICAgICAgICAgICAgICAgICAgICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8qIG91dHB1dCk7CisgIGJvb2wgRmluZEZpbGVDb250YWluaW5nU3ltYm9sKGNvbnN0IHN0cmluZyYgc3ltYm9sX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8qIG91dHB1dCk7CisgIGJvb2wgRmluZEZpbGVDb250YWluaW5nRXh0ZW5zaW9uKGNvbnN0IHN0cmluZyYgY29udGFpbmluZ190eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZmllbGRfbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlRGVzY3JpcHRvclByb3RvKiBvdXRwdXQpOworICBib29sIEZpbmRBbGxFeHRlbnNpb25OdW1iZXJzKGNvbnN0IHN0cmluZyYgZXh0ZW5kZWVfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWN0b3I8aW50Piogb3V0cHV0KTsKKworIHByaXZhdGU6CisgIC8vIFNvIHRoYXQgaXQgY2FuIHVzZSBEZXNjcmlwdG9ySW5kZXguCisgIGZyaWVuZCBjbGFzcyBFbmNvZGVkRGVzY3JpcHRvckRhdGFiYXNlOworCisgIC8vIEFuIGluZGV4IG1hcHBpbmcgZmlsZSBuYW1lcywgc3ltYm9sIG5hbWVzLCBhbmQgZXh0ZW5zaW9uIG51bWJlcnMgdG8KKyAgLy8gc29tZSBzb3J0IG9mIHZhbHVlcy4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFZhbHVlPgorICBjbGFzcyBEZXNjcmlwdG9ySW5kZXggeworICAgcHVibGljOgorICAgIC8vIEhlbHBlcnMgdG8gcmVjdXJzaXZlbHkgYWRkIHBhcnRpY3VsYXIgZGVzY3JpcHRvcnMgYW5kIGFsbCB0aGVpciBjb250ZW50cworICAgIC8vIHRvIHRoZSBpbmRleC4KKyAgICBib29sIEFkZEZpbGUoY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byYgZmlsZSwKKyAgICAgICAgICAgICAgICAgVmFsdWUgdmFsdWUpOworICAgIGJvb2wgQWRkU3ltYm9sKGNvbnN0IHN0cmluZyYgbmFtZSwgVmFsdWUgdmFsdWUpOworICAgIGJvb2wgQWRkTmVzdGVkRXh0ZW5zaW9ucyhjb25zdCBEZXNjcmlwdG9yUHJvdG8mIG1lc3NhZ2VfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmFsdWUgdmFsdWUpOworICAgIGJvb2wgQWRkRXh0ZW5zaW9uKGNvbnN0IEZpZWxkRGVzY3JpcHRvclByb3RvJiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICBWYWx1ZSB2YWx1ZSk7CisKKyAgICBWYWx1ZSBGaW5kRmlsZShjb25zdCBzdHJpbmcmIGZpbGVuYW1lKTsKKyAgICBWYWx1ZSBGaW5kU3ltYm9sKGNvbnN0IHN0cmluZyYgbmFtZSk7CisgICAgVmFsdWUgRmluZEV4dGVuc2lvbihjb25zdCBzdHJpbmcmIGNvbnRhaW5pbmdfdHlwZSwgaW50IGZpZWxkX251bWJlcik7CisgICAgYm9vbCBGaW5kQWxsRXh0ZW5zaW9uTnVtYmVycyhjb25zdCBzdHJpbmcmIGNvbnRhaW5pbmdfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlY3RvcjxpbnQ+KiBvdXRwdXQpOworCisgICBwcml2YXRlOgorICAgIG1hcDxzdHJpbmcsIFZhbHVlPiBieV9uYW1lXzsKKyAgICBtYXA8c3RyaW5nLCBWYWx1ZT4gYnlfc3ltYm9sXzsKKyAgICBtYXA8cGFpcjxzdHJpbmcsIGludD4sIFZhbHVlPiBieV9leHRlbnNpb25fOworCisgICAgLy8gSW52YXJpYW50OiAgVGhlIGJ5X3N5bWJvbF8gbWFwIGRvZXMgbm90IGNvbnRhaW4gYW55IHN5bWJvbHMgd2hpY2ggYXJlCisgICAgLy8gcHJlZml4ZXMgb2Ygb3RoZXIgc3ltYm9scyBpbiB0aGUgbWFwLiAgRm9yIGV4YW1wbGUsICJmb28uYmFyIiBpcyBhCisgICAgLy8gcHJlZml4IG9mICJmb28uYmFyLmJheiIgKGJ1dCBpcyBub3QgYSBwcmVmaXggb2YgImZvby5iYXJiYXoiKS4KKyAgICAvLworICAgIC8vIFRoaXMgaW52YXJpYW50IGlzIGltcG9ydGFudCBiZWNhdXNlIGl0IG1lYW5zIHRoYXQgZ2l2ZW4gYSBzeW1ib2wgbmFtZSwKKyAgICAvLyB3ZSBjYW4gZmluZCBhIGtleSBpbiB0aGUgbWFwIHdoaWNoIGlzIGEgcHJlZml4IG9mIHRoZSBzeW1ib2wgaW4gTyhsZyBuKQorICAgIC8vIHRpbWUsIGFuZCB3ZSBrbm93IHRoYXQgdGhlcmUgaXMgYXQgbW9zdCBvbmUgc3VjaCBrZXkuCisgICAgLy8KKyAgICAvLyBUaGUgcHJlZml4IGxvb2t1cCBhbGdvcml0aG0gd29ya3MgbGlrZSBzbzoKKyAgICAvLyAxKSBGaW5kIHRoZSBsYXN0IGtleSBpbiB0aGUgbWFwIHdoaWNoIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0byB0aGUKKyAgICAvLyAgICBzZWFyY2gga2V5LgorICAgIC8vIDIpIElmIHRoZSBmb3VuZCBrZXkgaXMgYSBwcmVmaXggb2YgdGhlIHNlYXJjaCBrZXksIHRoZW4gcmV0dXJuIGl0LgorICAgIC8vICAgIE90aGVyd2lzZSwgdGhlcmUgaXMgbm8gbWF0Y2guCisgICAgLy8KKyAgICAvLyBJIGFtIHN1cmUgdGhpcyBhbGdvcml0aG0gaGFzIGJlZW4gZGVzY3JpYmVkIGVsc2V3aGVyZSwgYnV0IHNpbmNlIEkKKyAgICAvLyB3YXNuJ3QgYWJsZSB0byBmaW5kIGl0IHF1aWNrbHkgSSB3aWxsIGluc3RlYWQgcHJvdmUgdGhhdCBpdCB3b3JrcworICAgIC8vIG15c2VsZi4gIFRoZSBrZXkgdG8gdGhlIGFsZ29yaXRobSBpcyB0aGF0IGlmIGEgbWF0Y2ggZXhpc3RzLCBzdGVwICgxKQorICAgIC8vIHdpbGwgZmluZCBpdC4gIFByb29mOgorICAgIC8vIDEpIERlZmluZSB0aGUgInNlYXJjaCBrZXkiIHRvIGJlIHRoZSBrZXkgd2UgYXJlIGxvb2tpbmcgZm9yLCB0aGUgImZvdW5kCisgICAgLy8gICAga2V5IiB0byBiZSB0aGUga2V5IGZvdW5kIGluIHN0ZXAgKDEpLCBhbmQgdGhlICJtYXRjaCBrZXkiIHRvIGJlIHRoZQorICAgIC8vICAgIGtleSB3aGljaCBhY3R1YWxseSBtYXRjaGVzIHRoZSBzZXJhY2gga2V5IChpLmUuIHRoZSBrZXkgd2UncmUgdHJ5aW5nCisgICAgLy8gICAgdG8gZmluZCkuCisgICAgLy8gMikgVGhlIGZvdW5kIGtleSBtdXN0IGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byB0aGUgc2VhcmNoIGtleSBieQorICAgIC8vICAgIGRlZmluaXRpb24uCisgICAgLy8gMykgVGhlIG1hdGNoIGtleSBtdXN0IGFsc28gYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHRoZSBzZWFyY2gga2V5CisgICAgLy8gICAgKGJlY2F1c2UgaXQgaXMgYSBwcmVmaXgpLgorICAgIC8vIDQpIFRoZSBtYXRjaCBrZXkgY2Fubm90IGJlIGdyZWF0ZXIgdGhhbiB0aGUgZm91bmQga2V5LCBiZWNhdXNlIGlmIGl0CisgICAgLy8gICAgd2VyZSwgdGhlbiBzdGVwICgxKSBvZiB0aGUgYWxnb3JpdGhtIHdvdWxkIGhhdmUgcmV0dXJuZWQgdGhlIG1hdGNoCisgICAgLy8gICAga2V5IGluc3RlYWQgKHNpbmNlIGl0IGZpbmRzIHRoZSAqZ3JlYXRlc3QqIGtleSB3aGljaCBpcyBsZXNzIHRoYW4gb3IKKyAgICAvLyAgICBlcXVhbCB0byB0aGUgc2VhcmNoIGtleSkuCisgICAgLy8gNSkgVGhlcmVmb3JlLCB0aGUgZm91bmQga2V5IG11c3QgYmUgYmV0d2VlbiB0aGUgbWF0Y2gga2V5IGFuZCB0aGUgc2VhcmNoCisgICAgLy8gICAga2V5LCBpbmNsdXNpdmUuCisgICAgLy8gNikgU2luY2UgdGhlIHNlYXJjaCBrZXkgbXVzdCBiZSBhIHN1Yi1zeW1ib2wgb2YgdGhlIG1hdGNoIGtleSwgaWYgaXQgaXMKKyAgICAvLyAgICBub3QgZXF1YWwgdG8gdGhlIG1hdGNoIGtleSwgdGhlbiBzZWFyY2hfa2V5W21hdGNoX2tleS5zaXplKCldIG11c3QKKyAgICAvLyAgICBiZSAnLicuCisgICAgLy8gNykgU2luY2UgJy4nIHNvcnRzIGJlZm9yZSBhbnkgb3RoZXIgY2hhcmFjdGVyIHRoYXQgaXMgdmFsaWQgaW4gYSBzeW1ib2wKKyAgICAvLyAgICBuYW1lLCB0aGVuIGlmIHRoZSBmb3VuZCBrZXkgaXMgbm90IGVxdWFsIHRvIHRoZSBtYXRjaCBrZXksIHRoZW4KKyAgICAvLyAgICBmb3VuZF9rZXlbbWF0Y2hfa2V5LnNpemUoKV0gbXVzdCBhbHNvIGJlICcuJywgYmVjYXVzZSBhbnkgb3RoZXIgdmFsdWUKKyAgICAvLyAgICB3b3VsZCBtYWtlIGl0IHNvcnQgYWZ0ZXIgdGhlIHNlYXJjaCBrZXkuCisgICAgLy8gOCkgVGhlcmVmb3JlLCBpZiB0aGUgZm91bmQga2V5IGlzIG5vdCBlcXVhbCB0byB0aGUgbWF0Y2gga2V5LCB0aGVuIHRoZQorICAgIC8vICAgIGZvdW5kIGtleSBtdXN0IGJlIGEgc3ViLXN5bWJvbCBvZiB0aGUgbWF0Y2gga2V5LiAgSG93ZXZlciwgdGhpcyB3b3VsZAorICAgIC8vICAgIGNvbnRyYWRpY3Qgb3VyIG1hcCBpbnZhcmlhbnQgd2hpY2ggc2F5cyB0aGF0IG5vIHN5bWJvbCBpbiB0aGUgbWFwIGlzCisgICAgLy8gICAgYSBzdWItc3ltYm9sIG9mIGFueSBvdGhlci4KKyAgICAvLyA5KSBUaGVyZWZvcmUsIHRoZSBmb3VuZCBrZXkgbXVzdCBtYXRjaCB0aGUgbWF0Y2gga2V5LgorICAgIC8vCisgICAgLy8gVGhlIGFib3ZlIHByb29mIGFzc3VtZXMgdGhlIG1hdGNoIGtleSBleGlzdHMuICBJbiB0aGUgY2FzZSB0aGF0IHRoZQorICAgIC8vIG1hdGNoIGtleSBkb2VzIG5vdCBleGlzdCwgdGhlbiBzdGVwICgxKSB3aWxsIHJldHVybiBzb21lIG90aGVyIHN5bWJvbC4KKyAgICAvLyBUaGF0IHN5bWJvbCBjYW5ub3QgYmUgYSBzdXBlci1zeW1ib2wgb2YgdGhlIHNlYXJjaCBrZXkgc2luY2UgaWYgaXQgd2VyZSwKKyAgICAvLyB0aGVuIGl0IHdvdWxkIGJlIGEgbWF0Y2gsIGFuZCB3ZSdyZSBhc3N1bWluZyB0aGUgbWF0Y2gga2V5IGRvZXNuJ3QgZXhpc3QuCisgICAgLy8gVGhlcmVmb3JlLCBzdGVwIDIgd2lsbCBjb3JyZWN0bHkgcmV0dXJuIG5vIG1hdGNoLgorCisgICAgLy8gRmluZCB0aGUgbGFzdCBlbnRyeSBpbiB0aGUgYnlfc3ltYm9sXyBtYXAgd2hvc2Uga2V5IGlzIGxlc3MgdGhhbiBvcgorICAgIC8vIGVxdWFsIHRvIHRoZSBnaXZlbiBuYW1lLgorICAgIHR5cGVuYW1lIG1hcDxzdHJpbmcsIFZhbHVlPjo6aXRlcmF0b3IgRmluZExhc3RMZXNzT3JFcXVhbCgKKyAgICAgICAgY29uc3Qgc3RyaW5nJiBuYW1lKTsKKworICAgIC8vIFRydWUgaWYgZWl0aGVyIHRoZSBhcmd1bWVudHMgYXJlIGVxdWFsIG9yIHN1cGVyX3N5bWJvbCBpZGVudGlmaWVzIGEKKyAgICAvLyBwYXJlbnQgc3ltYm9sIG9mIHN1Yl9zeW1ib2wgKGUuZy4gImZvby5iYXIiIGlzIGEgcGFyZW50IG9mCisgICAgLy8gImZvby5iYXIuYmF6IiwgYnV0IG5vdCBhIHBhcmVudCBvZiAiZm9vLmJhcmJheiIpLgorICAgIGJvb2wgSXNTdWJTeW1ib2woY29uc3Qgc3RyaW5nJiBzdWJfc3ltYm9sLCBjb25zdCBzdHJpbmcmIHN1cGVyX3N5bWJvbCk7CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgYW5kIG9ubHkgaWYgYWxsIGNoYXJhY3RlcnMgaW4gdGhlIG5hbWUgYXJlIGFscGhhbnVtZXJpY3MsCisgICAgLy8gdW5kZXJzY29yZXMsIG9yIHBlcmlvZHMuCisgICAgYm9vbCBWYWxpZGF0ZVN5bWJvbE5hbWUoY29uc3Qgc3RyaW5nJiBuYW1lKTsKKyAgfTsKKworCisgIERlc2NyaXB0b3JJbmRleDxjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvKj4gaW5kZXhfOworICB2ZWN0b3I8Y29uc3QgRmlsZURlc2NyaXB0b3JQcm90byo+IGZpbGVzX3RvX2RlbGV0ZV87CisKKyAgLy8gSWYgZmlsZSBpcyBub24tTlVMTCwgY29weSBpdCBpbnRvICpvdXRwdXQgYW5kIHJldHVybiB0cnVlLCBvdGhlcndpc2UKKyAgLy8gcmV0dXJuIGZhbHNlLgorICBib29sIE1heWJlQ29weShjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvKiBmaWxlLAorICAgICAgICAgICAgICAgICBGaWxlRGVzY3JpcHRvclByb3RvKiBvdXRwdXQpOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhTaW1wbGVEZXNjcmlwdG9yRGF0YWJhc2UpOworfTsKKworLy8gVmVyeSBzaW1pbGFyIHRvIFNpbXBsZURlc2NyaXB0b3JEYXRhYmFzZSwgYnV0IHN0b3JlcyBhbGwgdGhlIGRlc2NyaXB0b3JzCisvLyBhcyByYXcgYnl0ZXMgYW5kIGdlbmVyYWxseSB0cmllcyB0byB1c2UgYXMgbGl0dGxlIG1lbW9yeSBhcyBwb3NzaWJsZS4KKy8vCisvLyBUaGUgc2FtZSBjYXZlYXRzIHJlZ2FyZGluZyBGaW5kRmlsZUNvbnRhaW5pbmdFeHRlbnNpb24oKSBhcHBseSBhcyB3aXRoCisvLyBTaW1wbGVEZXNjcmlwdG9yRGF0YWJhc2UuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgRW5jb2RlZERlc2NyaXB0b3JEYXRhYmFzZSA6IHB1YmxpYyBEZXNjcmlwdG9yRGF0YWJhc2UgeworIHB1YmxpYzoKKyAgRW5jb2RlZERlc2NyaXB0b3JEYXRhYmFzZSgpOworICB+RW5jb2RlZERlc2NyaXB0b3JEYXRhYmFzZSgpOworCisgIC8vIEFkZHMgdGhlIEZpbGVEZXNjcmlwdG9yUHJvdG8gdG8gdGhlIGRhdGFiYXNlLiAgVGhlIGRlc2NyaXB0b3IgaXMgcHJvdmlkZWQKKyAgLy8gaW4gZW5jb2RlZCBmb3JtLiAgVGhlIGRhdGFiYXNlIGRvZXMgbm90IG1ha2UgYSBjb3B5IG9mIHRoZSBieXRlcywgbm9yCisgIC8vIGRvZXMgaXQgdGFrZSBvd25lcnNoaXA7IGl0J3MgdXAgdG8gdGhlIGNhbGxlciB0byBtYWtlIHN1cmUgdGhlIGJ5dGVzCisgIC8vIHJlbWFpbiB2YWxpZCBmb3IgdGhlIGxpZmUgb2YgdGhlIGRhdGFiYXNlLiAgUmV0dXJucyBmYWxzZSBhbmQgbG9ncyBhbiBlcnJvcgorICAvLyBpZiB0aGUgYnl0ZXMgYXJlIG5vdCBhIHZhbGlkIEZpbGVEZXNjcmlwdG9yUHJvdG8gb3IgaWYgdGhlIGZpbGUgY29uZmxpY3RlZAorICAvLyB3aXRoIGEgZmlsZSBhbHJlYWR5IGluIHRoZSBkYXRhYmFzZS4KKyAgYm9vbCBBZGQoY29uc3Qgdm9pZCogZW5jb2RlZF9maWxlX2Rlc2NyaXB0b3IsIGludCBzaXplKTsKKworICAvLyBMaWtlIEFkZCgpLCBidXQgbWFrZXMgYSBjb3B5IG9mIHRoZSBkYXRhLCBzbyB0aGF0IHRoZSBjYWxsZXIgZG9lcyBub3QKKyAgLy8gbmVlZCB0byBrZWVwIGl0IGFyb3VuZC4KKyAgYm9vbCBBZGRDb3B5KGNvbnN0IHZvaWQqIGVuY29kZWRfZmlsZV9kZXNjcmlwdG9yLCBpbnQgc2l6ZSk7CisKKyAgLy8gTGlrZSBGaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2wgYnV0IHJldHVybnMgb25seSB0aGUgbmFtZSBvZiB0aGUgZmlsZS4KKyAgYm9vbCBGaW5kTmFtZU9mRmlsZUNvbnRhaW5pbmdTeW1ib2woY29uc3Qgc3RyaW5nJiBzeW1ib2xfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nKiBvdXRwdXQpOworCisgIC8vIGltcGxlbWVudHMgRGVzY3JpcHRvckRhdGFiYXNlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIGJvb2wgRmluZEZpbGVCeU5hbWUoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICBGaWxlRGVzY3JpcHRvclByb3RvKiBvdXRwdXQpOworICBib29sIEZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbChjb25zdCBzdHJpbmcmIHN5bWJvbF9uYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlRGVzY3JpcHRvclByb3RvKiBvdXRwdXQpOworICBib29sIEZpbmRGaWxlQ29udGFpbmluZ0V4dGVuc2lvbihjb25zdCBzdHJpbmcmIGNvbnRhaW5pbmdfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmlsZURlc2NyaXB0b3JQcm90byogb3V0cHV0KTsKKyAgYm9vbCBGaW5kQWxsRXh0ZW5zaW9uTnVtYmVycyhjb25zdCBzdHJpbmcmIGV4dGVuZGVlX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjdG9yPGludD4qIG91dHB1dCk7CisKKyBwcml2YXRlOgorICBTaW1wbGVEZXNjcmlwdG9yRGF0YWJhc2U6OkRlc2NyaXB0b3JJbmRleDxwYWlyPGNvbnN0IHZvaWQqLCBpbnQ+ID4gaW5kZXhfOworICB2ZWN0b3I8dm9pZCo+IGZpbGVzX3RvX2RlbGV0ZV87CisKKyAgLy8gSWYgZW5jb2RlZF9maWxlLmZpcnN0IGlzIG5vbi1OVUxMLCBwYXJzZSB0aGUgZGF0YSBpbnRvICpvdXRwdXQgYW5kIHJldHVybgorICAvLyB0cnVlLCBvdGhlcndpc2UgcmV0dXJuIGZhbHNlLgorICBib29sIE1heWJlUGFyc2UocGFpcjxjb25zdCB2b2lkKiwgaW50PiBlbmNvZGVkX2ZpbGUsCisgICAgICAgICAgICAgICAgICBGaWxlRGVzY3JpcHRvclByb3RvKiBvdXRwdXQpOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhFbmNvZGVkRGVzY3JpcHRvckRhdGFiYXNlKTsKK307CisKKy8vIEEgRGVzY3JpcHRvckRhdGFiYXNlIHRoYXQgZmV0Y2hlcyBmaWxlcyBmcm9tIGEgZ2l2ZW4gcG9vbC4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBEZXNjcmlwdG9yUG9vbERhdGFiYXNlIDogcHVibGljIERlc2NyaXB0b3JEYXRhYmFzZSB7CisgcHVibGljOgorICBleHBsaWNpdCBEZXNjcmlwdG9yUG9vbERhdGFiYXNlKGNvbnN0IERlc2NyaXB0b3JQb29sJiBwb29sKTsKKyAgfkRlc2NyaXB0b3JQb29sRGF0YWJhc2UoKTsKKworICAvLyBpbXBsZW1lbnRzIERlc2NyaXB0b3JEYXRhYmFzZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICBib29sIEZpbmRGaWxlQnlOYW1lKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgRmlsZURlc2NyaXB0b3JQcm90byogb3V0cHV0KTsKKyAgYm9vbCBGaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2woY29uc3Qgc3RyaW5nJiBzeW1ib2xfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmlsZURlc2NyaXB0b3JQcm90byogb3V0cHV0KTsKKyAgYm9vbCBGaW5kRmlsZUNvbnRhaW5pbmdFeHRlbnNpb24oY29uc3Qgc3RyaW5nJiBjb250YWluaW5nX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBmaWVsZF9udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8qIG91dHB1dCk7CisgIGJvb2wgRmluZEFsbEV4dGVuc2lvbk51bWJlcnMoY29uc3Qgc3RyaW5nJiBleHRlbmRlZV90eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlY3RvcjxpbnQ+KiBvdXRwdXQpOworCisgcHJpdmF0ZToKKyAgY29uc3QgRGVzY3JpcHRvclBvb2wmIHBvb2xfOworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoRGVzY3JpcHRvclBvb2xEYXRhYmFzZSk7Cit9OworCisvLyBBIERlc2NyaXB0b3JEYXRhYmFzZSB0aGF0IHdyYXBzIHR3byBvciBtb3JlIG90aGVycy4gIEl0IGZpcnN0IHNlYXJjaGVzIHRoZQorLy8gZmlyc3QgZGF0YWJhc2UgYW5kLCBpZiB0aGF0IGZhaWxzLCB0cmllcyB0aGUgc2Vjb25kLCBhbmQgc28gb24uCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgTWVyZ2VkRGVzY3JpcHRvckRhdGFiYXNlIDogcHVibGljIERlc2NyaXB0b3JEYXRhYmFzZSB7CisgcHVibGljOgorICAvLyBNZXJnZSBqdXN0IHR3byBkYXRhYmFzZXMuICBUaGUgc291cmNlcyByZW1haW4gcHJvcGVydHkgb2YgdGhlIGNhbGxlci4KKyAgTWVyZ2VkRGVzY3JpcHRvckRhdGFiYXNlKERlc2NyaXB0b3JEYXRhYmFzZSogc291cmNlMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIERlc2NyaXB0b3JEYXRhYmFzZSogc291cmNlMik7CisgIC8vIE1lcmdlIG1vcmUgdGhhbiB0d28gZGF0YWJhc2VzLiAgVGhlIHNvdXJjZXMgcmVtYWluIHByb3BlcnR5IG9mIHRoZSBjYWxsZXIuCisgIC8vIFRoZSB2ZWN0b3IgbWF5IGJlIGRlbGV0ZWQgYWZ0ZXIgdGhlIGNvbnN0cnVjdG9yIHJldHVybnMgYnV0IHRoZQorICAvLyBEZXNjcmlwdG9yRGF0YWJhc2VzIG5lZWQgdG8gc3RpY2sgYXJvdW5kLgorICBleHBsaWNpdCBNZXJnZWREZXNjcmlwdG9yRGF0YWJhc2UoY29uc3QgdmVjdG9yPERlc2NyaXB0b3JEYXRhYmFzZSo+JiBzb3VyY2VzKTsKKyAgfk1lcmdlZERlc2NyaXB0b3JEYXRhYmFzZSgpOworCisgIC8vIGltcGxlbWVudHMgRGVzY3JpcHRvckRhdGFiYXNlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIGJvb2wgRmluZEZpbGVCeU5hbWUoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICBGaWxlRGVzY3JpcHRvclByb3RvKiBvdXRwdXQpOworICBib29sIEZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbChjb25zdCBzdHJpbmcmIHN5bWJvbF9uYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlRGVzY3JpcHRvclByb3RvKiBvdXRwdXQpOworICBib29sIEZpbmRGaWxlQ29udGFpbmluZ0V4dGVuc2lvbihjb25zdCBzdHJpbmcmIGNvbnRhaW5pbmdfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmlsZURlc2NyaXB0b3JQcm90byogb3V0cHV0KTsKKyAgLy8gTWVyZ2VzIHRoZSByZXN1bHRzIG9mIGNhbGxpbmcgYWxsIGRhdGFiYXNlcy4gUmV0dXJucyB0cnVlIGlmZiBhbnkKKyAgLy8gb2YgdGhlIGRhdGFiYXNlcyByZXR1cm5lZCB0cnVlLgorICBib29sIEZpbmRBbGxFeHRlbnNpb25OdW1iZXJzKGNvbnN0IHN0cmluZyYgZXh0ZW5kZWVfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWN0b3I8aW50Piogb3V0cHV0KTsKKworCisgcHJpdmF0ZToKKyAgdmVjdG9yPERlc2NyaXB0b3JEYXRhYmFzZSo+IHNvdXJjZXNfOworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoTWVyZ2VkRGVzY3JpcHRvckRhdGFiYXNlKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9ERVNDUklQVE9SX0RBVEFCQVNFX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yX2RhdGFiYXNlX3VuaXR0ZXN0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yX2RhdGFiYXNlX3VuaXR0ZXN0LmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFmYzM4MTYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3JfZGF0YWJhc2VfdW5pdHRlc3QuY2MKQEAgLTAsMCArMSw3NTQgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBUaGlzIGZpbGUgbWFrZXMgZXh0ZW5zaXZlIHVzZSBvZiBSRkMgMzA5Mi4gIDopCisKKyNpbmNsdWRlIDxhbGdvcml0aG0+CisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3JfZGF0YWJhc2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3RleHRfZm9ybWF0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9sb2dnaW5nLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zY29wZWRfcHRyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZ29vZ2xldGVzdC5oPgorI2luY2x1ZGUgPGd0ZXN0L2d0ZXN0Lmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSB7CisKK3N0YXRpYyB2b2lkIEFkZFRvRGF0YWJhc2UoU2ltcGxlRGVzY3JpcHRvckRhdGFiYXNlKiBkYXRhYmFzZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogZmlsZV90ZXh0KSB7CisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZV9wcm90bzsKKyAgRVhQRUNUX1RSVUUoVGV4dEZvcm1hdDo6UGFyc2VGcm9tU3RyaW5nKGZpbGVfdGV4dCwgJmZpbGVfcHJvdG8pKTsKKyAgZGF0YWJhc2UtPkFkZChmaWxlX3Byb3RvKTsKK30KKworc3RhdGljIHZvaWQgRXhwZWN0Q29udGFpbnNUeXBlKGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8mIHByb3RvLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgdHlwZV9uYW1lKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgcHJvdG8ubWVzc2FnZV90eXBlX3NpemUoKTsgaSsrKSB7CisgICAgaWYgKHByb3RvLm1lc3NhZ2VfdHlwZShpKS5uYW1lKCkgPT0gdHlwZV9uYW1lKSByZXR1cm47CisgIH0KKyAgQUREX0ZBSUxVUkUoKSA8PCAiXCIiIDw8IHByb3RvLm5hbWUoKQorICAgICAgICAgICAgICAgIDw8ICJcIiBkaWQgbm90IGNvbnRhaW4gZXhwZWN0ZWQgdHlwZSBcIiIKKyAgICAgICAgICAgICAgICA8PCB0eXBlX25hbWUgPDwgIlwiLiI7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworI2lmIEdURVNUX0hBU19QQVJBTV9URVNUCisKKy8vIFNpbXBsZURlc2NyaXB0b3JEYXRhYmFzZSwgRW5jb2RlZERlc2NyaXB0b3JEYXRhYmFzZSwgYW5kCisvLyBEZXNjcmlwdG9yUG9vbERhdGFiYXNlIGNhbGwgZm9yIHZlcnkgc2ltaWxhciB0ZXN0cy4gIEluc3RlYWQgb2Ygd3JpdGluZworLy8gdGhyZWUgbmVhcmx5LWlkZW50aWNhbCBzZXRzIG9mIHRlc3RzLCB3ZSB1c2UgcGFyYW1ldGVyaXplZCB0ZXN0cyB0byBhcHBseQorLy8gdGhlIHNhbWUgY29kZSB0byBhbGwgdGhyZWUuCisKKy8vIFRoZSBwYXJhbWV0ZXJpemVkIHRlc3QgcnVucyBhZ2FpbnN0IGEgRGVzY3JpcHRhckRhdGFiYXNlVGVzdENhc2UuICBXZSBoYXZlCisvLyBpbXBsZW1lbnRhdGlvbnMgZm9yIGVhY2ggb2YgdGhlIHRocmVlIGNsYXNzZXMgd2Ugd2FudCB0byB0ZXN0LgorY2xhc3MgRGVzY3JpcHRvckRhdGFiYXNlVGVzdENhc2UgeworIHB1YmxpYzoKKyAgdmlydHVhbCB+RGVzY3JpcHRvckRhdGFiYXNlVGVzdENhc2UoKSB7fQorCisgIHZpcnR1YWwgRGVzY3JpcHRvckRhdGFiYXNlKiBHZXREYXRhYmFzZSgpID0gMDsKKyAgdmlydHVhbCBib29sIEFkZFRvRGF0YWJhc2UoY29uc3QgRmlsZURlc2NyaXB0b3JQcm90byYgZmlsZSkgPSAwOworfTsKKworLy8gRmFjdG9yeSBmdW5jdGlvbiB0eXBlLgordHlwZWRlZiBEZXNjcmlwdG9yRGF0YWJhc2VUZXN0Q2FzZSogRGVzY3JpcHRvckRhdGFiYXNlVGVzdENhc2VGYWN0b3J5KCk7CisKKy8vIFNwZWNpYWxpemF0aW9uIGZvciBTaW1wbGVEZXNjcmlwdG9yRGF0YWJhc2UuCitjbGFzcyBTaW1wbGVEZXNjcmlwdG9yRGF0YWJhc2VUZXN0Q2FzZSA6IHB1YmxpYyBEZXNjcmlwdG9yRGF0YWJhc2VUZXN0Q2FzZSB7CisgcHVibGljOgorICBzdGF0aWMgRGVzY3JpcHRvckRhdGFiYXNlVGVzdENhc2UqIE5ldygpIHsKKyAgICByZXR1cm4gbmV3IFNpbXBsZURlc2NyaXB0b3JEYXRhYmFzZVRlc3RDYXNlOworICB9CisKKyAgdmlydHVhbCB+U2ltcGxlRGVzY3JpcHRvckRhdGFiYXNlVGVzdENhc2UoKSB7fQorCisgIHZpcnR1YWwgRGVzY3JpcHRvckRhdGFiYXNlKiBHZXREYXRhYmFzZSgpIHsKKyAgICByZXR1cm4gJmRhdGFiYXNlXzsKKyAgfQorICB2aXJ0dWFsIGJvb2wgQWRkVG9EYXRhYmFzZShjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvJiBmaWxlKSB7CisgICAgcmV0dXJuIGRhdGFiYXNlXy5BZGQoZmlsZSk7CisgIH0KKworIHByaXZhdGU6CisgIFNpbXBsZURlc2NyaXB0b3JEYXRhYmFzZSBkYXRhYmFzZV87Cit9OworCisvLyBTcGVjaWFsaXphdGlvbiBmb3IgRW5jb2RlZERlc2NyaXB0b3JEYXRhYmFzZS4KK2NsYXNzIEVuY29kZWREZXNjcmlwdG9yRGF0YWJhc2VUZXN0Q2FzZSA6IHB1YmxpYyBEZXNjcmlwdG9yRGF0YWJhc2VUZXN0Q2FzZSB7CisgcHVibGljOgorICBzdGF0aWMgRGVzY3JpcHRvckRhdGFiYXNlVGVzdENhc2UqIE5ldygpIHsKKyAgICByZXR1cm4gbmV3IEVuY29kZWREZXNjcmlwdG9yRGF0YWJhc2VUZXN0Q2FzZTsKKyAgfQorCisgIHZpcnR1YWwgfkVuY29kZWREZXNjcmlwdG9yRGF0YWJhc2VUZXN0Q2FzZSgpIHt9CisKKyAgdmlydHVhbCBEZXNjcmlwdG9yRGF0YWJhc2UqIEdldERhdGFiYXNlKCkgeworICAgIHJldHVybiAmZGF0YWJhc2VfOworICB9CisgIHZpcnR1YWwgYm9vbCBBZGRUb0RhdGFiYXNlKGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8mIGZpbGUpIHsKKyAgICBzdHJpbmcgZGF0YTsKKyAgICBmaWxlLlNlcmlhbGl6ZVRvU3RyaW5nKCZkYXRhKTsKKyAgICByZXR1cm4gZGF0YWJhc2VfLkFkZENvcHkoZGF0YS5kYXRhKCksIGRhdGEuc2l6ZSgpKTsKKyAgfQorCisgcHJpdmF0ZToKKyAgRW5jb2RlZERlc2NyaXB0b3JEYXRhYmFzZSBkYXRhYmFzZV87Cit9OworCisvLyBTcGVjaWFsaXphdGlvbiBmb3IgRGVzY3JpcHRvclBvb2xEYXRhYmFzZS4KK2NsYXNzIERlc2NyaXB0b3JQb29sRGF0YWJhc2VUZXN0Q2FzZSA6IHB1YmxpYyBEZXNjcmlwdG9yRGF0YWJhc2VUZXN0Q2FzZSB7CisgcHVibGljOgorICBzdGF0aWMgRGVzY3JpcHRvckRhdGFiYXNlVGVzdENhc2UqIE5ldygpIHsKKyAgICByZXR1cm4gbmV3IEVuY29kZWREZXNjcmlwdG9yRGF0YWJhc2VUZXN0Q2FzZTsKKyAgfQorCisgIERlc2NyaXB0b3JQb29sRGF0YWJhc2VUZXN0Q2FzZSgpIDogZGF0YWJhc2VfKHBvb2xfKSB7fQorICB2aXJ0dWFsIH5EZXNjcmlwdG9yUG9vbERhdGFiYXNlVGVzdENhc2UoKSB7fQorCisgIHZpcnR1YWwgRGVzY3JpcHRvckRhdGFiYXNlKiBHZXREYXRhYmFzZSgpIHsKKyAgICByZXR1cm4gJmRhdGFiYXNlXzsKKyAgfQorICB2aXJ0dWFsIGJvb2wgQWRkVG9EYXRhYmFzZShjb25zdCBGaWxlRGVzY3JpcHRvclByb3RvJiBmaWxlKSB7CisgICAgcmV0dXJuIHBvb2xfLkJ1aWxkRmlsZShmaWxlKTsKKyAgfQorCisgcHJpdmF0ZToKKyAgRGVzY3JpcHRvclBvb2wgcG9vbF87CisgIERlc2NyaXB0b3JQb29sRGF0YWJhc2UgZGF0YWJhc2VfOworfTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBEZXNjcmlwdG9yRGF0YWJhc2VUZXN0CisgICAgOiBwdWJsaWMgdGVzdGluZzo6VGVzdFdpdGhQYXJhbTxEZXNjcmlwdG9yRGF0YWJhc2VUZXN0Q2FzZUZhY3RvcnkqPiB7CisgcHJvdGVjdGVkOgorICB2aXJ0dWFsIHZvaWQgU2V0VXAoKSB7CisgICAgdGVzdF9jYXNlXy5yZXNldChHZXRQYXJhbSgpKCkpOworICAgIGRhdGFiYXNlXyA9IHRlc3RfY2FzZV8tPkdldERhdGFiYXNlKCk7CisgIH0KKworICB2b2lkIEFkZFRvRGF0YWJhc2UoY29uc3QgY2hhciogZmlsZV9kZXNjcmlwdG9yX3RleHQpIHsKKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGVfcHJvdG87CisgICAgRVhQRUNUX1RSVUUoVGV4dEZvcm1hdDo6UGFyc2VGcm9tU3RyaW5nKGZpbGVfZGVzY3JpcHRvcl90ZXh0LCAmZmlsZV9wcm90bykpOworICAgIEVYUEVDVF9UUlVFKHRlc3RfY2FzZV8tPkFkZFRvRGF0YWJhc2UoZmlsZV9wcm90bykpOworICB9CisKKyAgdm9pZCBBZGRUb0RhdGFiYXNlV2l0aEVycm9yKGNvbnN0IGNoYXIqIGZpbGVfZGVzY3JpcHRvcl90ZXh0KSB7CisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICAgIEVYUEVDVF9UUlVFKFRleHRGb3JtYXQ6OlBhcnNlRnJvbVN0cmluZyhmaWxlX2Rlc2NyaXB0b3JfdGV4dCwgJmZpbGVfcHJvdG8pKTsKKyAgICBFWFBFQ1RfRkFMU0UodGVzdF9jYXNlXy0+QWRkVG9EYXRhYmFzZShmaWxlX3Byb3RvKSk7CisgIH0KKworICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPERlc2NyaXB0b3JEYXRhYmFzZVRlc3RDYXNlPiB0ZXN0X2Nhc2VfOworICBEZXNjcmlwdG9yRGF0YWJhc2UqIGRhdGFiYXNlXzsKK307CisKK1RFU1RfUChEZXNjcmlwdG9yRGF0YWJhc2VUZXN0LCBGaW5kRmlsZUJ5TmFtZSkgeworICBBZGRUb0RhdGFiYXNlKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsgbmFtZTpcIkZvb1wiIH0iKTsKKyAgQWRkVG9EYXRhYmFzZSgKKyAgICAibmFtZTogXCJiYXIucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IG5hbWU6XCJCYXJcIiB9Iik7CisKKyAgeworICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZTsKKyAgICBFWFBFQ1RfVFJVRShkYXRhYmFzZV8tPkZpbmRGaWxlQnlOYW1lKCJmb28ucHJvdG8iLCAmZmlsZSkpOworICAgIEVYUEVDVF9FUSgiZm9vLnByb3RvIiwgZmlsZS5uYW1lKCkpOworICAgIEV4cGVjdENvbnRhaW5zVHlwZShmaWxlLCAiRm9vIik7CisgIH0KKworICB7CisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlOworICAgIEVYUEVDVF9UUlVFKGRhdGFiYXNlXy0+RmluZEZpbGVCeU5hbWUoImJhci5wcm90byIsICZmaWxlKSk7CisgICAgRVhQRUNUX0VRKCJiYXIucHJvdG8iLCBmaWxlLm5hbWUoKSk7CisgICAgRXhwZWN0Q29udGFpbnNUeXBlKGZpbGUsICJCYXIiKTsKKyAgfQorCisgIHsKKyAgICAvLyBGYWlscyB0byBmaW5kIHVuZGVmaW5lZCBmaWxlcy4KKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGU7CisgICAgRVhQRUNUX0ZBTFNFKGRhdGFiYXNlXy0+RmluZEZpbGVCeU5hbWUoImJhei5wcm90byIsICZmaWxlKSk7CisgIH0KK30KKworVEVTVF9QKERlc2NyaXB0b3JEYXRhYmFzZVRlc3QsIEZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbCkgeworICBBZGRUb0RhdGFiYXNlKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsgIgorICAgICIgIG5hbWU6IFwiRm9vXCIgIgorICAgICIgIGZpZWxkIHsgbmFtZTpcInF1eFwiIH0iCisgICAgIiAgbmVzdGVkX3R5cGUgeyBuYW1lOiBcIkdyYXVsdFwiIH0gIgorICAgICIgIGVudW1fdHlwZSB7IG5hbWU6IFwiR2FycGx5XCIgfSAiCisgICAgIn0gIgorICAgICJlbnVtX3R5cGUgeyAiCisgICAgIiAgbmFtZTogXCJXYWxkb1wiICIKKyAgICAiICB2YWx1ZSB7IG5hbWU6XCJGUkVEXCIgfSAiCisgICAgIn0gIgorICAgICJleHRlbnNpb24geyBuYW1lOiBcInBsdWdoXCIgfSAiCisgICAgInNlcnZpY2UgeyAiCisgICAgIiAgbmFtZTogXCJYeXp6eVwiICIKKyAgICAiICBtZXRob2QgeyBuYW1lOiBcIlRodWRcIiB9ICIKKyAgICAifSIKKyAgICApOworICBBZGRUb0RhdGFiYXNlKAorICAgICJuYW1lOiBcImJhci5wcm90b1wiICIKKyAgICAicGFja2FnZTogXCJjb3JnZVwiICIKKyAgICAibWVzc2FnZV90eXBlIHsgbmFtZTogXCJCYXJcIiB9Iik7CisKKyAgeworICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZTsKKyAgICBFWFBFQ1RfVFJVRShkYXRhYmFzZV8tPkZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbCgiRm9vIiwgJmZpbGUpKTsKKyAgICBFWFBFQ1RfRVEoImZvby5wcm90byIsIGZpbGUubmFtZSgpKTsKKyAgfQorCisgIHsKKyAgICAvLyBDYW4gZmluZCBmaWVsZHMuCisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlOworICAgIEVYUEVDVF9UUlVFKGRhdGFiYXNlXy0+RmluZEZpbGVDb250YWluaW5nU3ltYm9sKCJGb28ucXV4IiwgJmZpbGUpKTsKKyAgICBFWFBFQ1RfRVEoImZvby5wcm90byIsIGZpbGUubmFtZSgpKTsKKyAgfQorCisgIHsKKyAgICAvLyBDYW4gZmluZCBuZXN0ZWQgdHlwZXMuCisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlOworICAgIEVYUEVDVF9UUlVFKGRhdGFiYXNlXy0+RmluZEZpbGVDb250YWluaW5nU3ltYm9sKCJGb28uR3JhdWx0IiwgJmZpbGUpKTsKKyAgICBFWFBFQ1RfRVEoImZvby5wcm90byIsIGZpbGUubmFtZSgpKTsKKyAgfQorCisgIHsKKyAgICAvLyBDYW4gZmluZCBuZXN0ZWQgZW51bXMuCisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlOworICAgIEVYUEVDVF9UUlVFKGRhdGFiYXNlXy0+RmluZEZpbGVDb250YWluaW5nU3ltYm9sKCJGb28uR2FycGx5IiwgJmZpbGUpKTsKKyAgICBFWFBFQ1RfRVEoImZvby5wcm90byIsIGZpbGUubmFtZSgpKTsKKyAgfQorCisgIHsKKyAgICAvLyBDYW4gZmluZCBlbnVtIHR5cGVzLgorICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZTsKKyAgICBFWFBFQ1RfVFJVRShkYXRhYmFzZV8tPkZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbCgiV2FsZG8iLCAmZmlsZSkpOworICAgIEVYUEVDVF9FUSgiZm9vLnByb3RvIiwgZmlsZS5uYW1lKCkpOworICB9CisKKyAgeworICAgIC8vIENhbiBmaW5kIGVudW0gdmFsdWVzLgorICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZTsKKyAgICBFWFBFQ1RfVFJVRShkYXRhYmFzZV8tPkZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbCgiV2FsZG8uRlJFRCIsICZmaWxlKSk7CisgICAgRVhQRUNUX0VRKCJmb28ucHJvdG8iLCBmaWxlLm5hbWUoKSk7CisgIH0KKworICB7CisgICAgLy8gQ2FuIGZpbmQgZXh0ZW5zaW9ucy4KKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGU7CisgICAgRVhQRUNUX1RSVUUoZGF0YWJhc2VfLT5GaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2woInBsdWdoIiwgJmZpbGUpKTsKKyAgICBFWFBFQ1RfRVEoImZvby5wcm90byIsIGZpbGUubmFtZSgpKTsKKyAgfQorCisgIHsKKyAgICAvLyBDYW4gZmluZCBzZXJ2aWNlcy4KKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGU7CisgICAgRVhQRUNUX1RSVUUoZGF0YWJhc2VfLT5GaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2woIlh5enp5IiwgJmZpbGUpKTsKKyAgICBFWFBFQ1RfRVEoImZvby5wcm90byIsIGZpbGUubmFtZSgpKTsKKyAgfQorCisgIHsKKyAgICAvLyBDYW4gZmluZCBtZXRob2RzLgorICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZTsKKyAgICBFWFBFQ1RfVFJVRShkYXRhYmFzZV8tPkZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbCgiWHl6enkuVGh1ZCIsICZmaWxlKSk7CisgICAgRVhQRUNUX0VRKCJmb28ucHJvdG8iLCBmaWxlLm5hbWUoKSk7CisgIH0KKworICB7CisgICAgLy8gQ2FuIGZpbmQgdGhpbmdzIGluIHBhY2thZ2VzLgorICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZTsKKyAgICBFWFBFQ1RfVFJVRShkYXRhYmFzZV8tPkZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbCgiY29yZ2UuQmFyIiwgJmZpbGUpKTsKKyAgICBFWFBFQ1RfRVEoImJhci5wcm90byIsIGZpbGUubmFtZSgpKTsKKyAgfQorCisgIHsKKyAgICAvLyBGYWlscyB0byBmaW5kIHVuZGVmaW5lZCBzeW1ib2xzLgorICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZTsKKyAgICBFWFBFQ1RfRkFMU0UoZGF0YWJhc2VfLT5GaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2woIkJheiIsICZmaWxlKSk7CisgIH0KKworICB7CisgICAgLy8gTmFtZXMgbXVzdCBiZSBmdWxseS1xdWFsaWZpZWQuCisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlOworICAgIEVYUEVDVF9GQUxTRShkYXRhYmFzZV8tPkZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbCgiQmFyIiwgJmZpbGUpKTsKKyAgfQorfQorCitURVNUX1AoRGVzY3JpcHRvckRhdGFiYXNlVGVzdCwgRmluZEZpbGVDb250YWluaW5nRXh0ZW5zaW9uKSB7CisgIEFkZFRvRGF0YWJhc2UoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyAiCisgICAgIiAgbmFtZTogXCJGb29cIiAiCisgICAgIiAgZXh0ZW5zaW9uX3JhbmdlIHsgc3RhcnQ6IDEgZW5kOiAxMDAwIH0gIgorICAgICIgIGV4dGVuc2lvbiB7IG5hbWU6XCJxdXhcIiBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgbnVtYmVyOjUgIgorICAgICIgICAgICAgICAgICAgIGV4dGVuZGVlOiBcIi5Gb29cIiB9IgorICAgICJ9Iik7CisgIEFkZFRvRGF0YWJhc2UoCisgICAgIm5hbWU6IFwiYmFyLnByb3RvXCIgIgorICAgICJwYWNrYWdlOiBcImNvcmdlXCIgIgorICAgICJkZXBlbmRlbmN5OiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsgIgorICAgICIgIG5hbWU6IFwiQmFyXCIgIgorICAgICIgIGV4dGVuc2lvbl9yYW5nZSB7IHN0YXJ0OiAxIGVuZDogMTAwMCB9ICIKKyAgICAifSAiCisgICAgImV4dGVuc2lvbiB7IG5hbWU6XCJncmF1bHRcIiBleHRlbmRlZTogXCIuRm9vXCIgICAgICAgbnVtYmVyOjMyIH0gIgorICAgICJleHRlbnNpb24geyBuYW1lOlwiZ2FycGx5XCIgZXh0ZW5kZWU6IFwiLmNvcmdlLkJhclwiIG51bWJlcjo3MCB9ICIKKyAgICAiZXh0ZW5zaW9uIHsgbmFtZTpcIndhbGRvXCIgIGV4dGVuZGVlOiBcIkJhclwiICAgICAgICBudW1iZXI6NTYgfSAiKTsKKworICB7CisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlOworICAgIEVYUEVDVF9UUlVFKGRhdGFiYXNlXy0+RmluZEZpbGVDb250YWluaW5nRXh0ZW5zaW9uKCJGb28iLCA1LCAmZmlsZSkpOworICAgIEVYUEVDVF9FUSgiZm9vLnByb3RvIiwgZmlsZS5uYW1lKCkpOworICB9CisKKyAgeworICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZTsKKyAgICBFWFBFQ1RfVFJVRShkYXRhYmFzZV8tPkZpbmRGaWxlQ29udGFpbmluZ0V4dGVuc2lvbigiRm9vIiwgMzIsICZmaWxlKSk7CisgICAgRVhQRUNUX0VRKCJiYXIucHJvdG8iLCBmaWxlLm5hbWUoKSk7CisgIH0KKworICB7CisgICAgLy8gQ2FuIGZpbmQgZXh0ZW5zaW9ucyBmb3IgcXVhbGlmaWVkIHR5cGUgbmFtZXMuCisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlOworICAgIEVYUEVDVF9UUlVFKGRhdGFiYXNlXy0+RmluZEZpbGVDb250YWluaW5nRXh0ZW5zaW9uKCJjb3JnZS5CYXIiLCA3MCwgJmZpbGUpKTsKKyAgICBFWFBFQ1RfRVEoImJhci5wcm90byIsIGZpbGUubmFtZSgpKTsKKyAgfQorCisgIHsKKyAgICAvLyBDYW4ndCBmaW5kIGV4dGVuc2lvbnMgd2hvc2UgZXh0ZW5kZWUgd2FzIG5vdCBmdWxseS1xdWFsaWZpZWQgaW4gdGhlCisgICAgLy8gRmlsZURlc2NyaXB0b3JQcm90by4KKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGU7CisgICAgRVhQRUNUX0ZBTFNFKGRhdGFiYXNlXy0+RmluZEZpbGVDb250YWluaW5nRXh0ZW5zaW9uKCJCYXIiLCA1NiwgJmZpbGUpKTsKKyAgICBFWFBFQ1RfRkFMU0UoCisgICAgICAgIGRhdGFiYXNlXy0+RmluZEZpbGVDb250YWluaW5nRXh0ZW5zaW9uKCJjb3JnZS5CYXIiLCA1NiwgJmZpbGUpKTsKKyAgfQorCisgIHsKKyAgICAvLyBDYW4ndCBmaW5kIG5vbi1leGlzdGVudCBleHRlbnNpb24gbnVtYmVycy4KKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGU7CisgICAgRVhQRUNUX0ZBTFNFKGRhdGFiYXNlXy0+RmluZEZpbGVDb250YWluaW5nRXh0ZW5zaW9uKCJGb28iLCAxMiwgJmZpbGUpKTsKKyAgfQorCisgIHsKKyAgICAvLyBDYW4ndCBmaW5kIGV4dGVuc2lvbnMgZm9yIG5vbi1leGlzdGVudCB0eXBlcy4KKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGU7CisgICAgRVhQRUNUX0ZBTFNFKAorICAgICAgICBkYXRhYmFzZV8tPkZpbmRGaWxlQ29udGFpbmluZ0V4dGVuc2lvbigiTm9TdWNoVHlwZSIsIDUsICZmaWxlKSk7CisgIH0KKworICB7CisgICAgLy8gQ2FuJ3QgZmluZCBleHRlbnNpb25zIGZvciB1bnF1YWxpZmllZCB0eXBlIG5hbWVzLgorICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZTsKKyAgICBFWFBFQ1RfRkFMU0UoZGF0YWJhc2VfLT5GaW5kRmlsZUNvbnRhaW5pbmdFeHRlbnNpb24oIkJhciIsIDcwLCAmZmlsZSkpOworICB9Cit9CisKK1RFU1RfUChEZXNjcmlwdG9yRGF0YWJhc2VUZXN0LCBGaW5kQWxsRXh0ZW5zaW9uTnVtYmVycykgeworICBBZGRUb0RhdGFiYXNlKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsgIgorICAgICIgIG5hbWU6IFwiRm9vXCIgIgorICAgICIgIGV4dGVuc2lvbl9yYW5nZSB7IHN0YXJ0OiAxIGVuZDogMTAwMCB9ICIKKyAgICAiICBleHRlbnNpb24geyBuYW1lOlwicXV4XCIgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZTpUWVBFX0lOVDMyIG51bWJlcjo1ICIKKyAgICAiICAgICAgICAgICAgICBleHRlbmRlZTogXCIuRm9vXCIgfSIKKyAgICAifSIpOworICBBZGRUb0RhdGFiYXNlKAorICAgICJuYW1lOiBcImJhci5wcm90b1wiICIKKyAgICAicGFja2FnZTogXCJjb3JnZVwiICIKKyAgICAiZGVwZW5kZW5jeTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7ICIKKyAgICAiICBuYW1lOiBcIkJhclwiICIKKyAgICAiICBleHRlbnNpb25fcmFuZ2UgeyBzdGFydDogMSBlbmQ6IDEwMDAgfSAiCisgICAgIn0gIgorICAgICJleHRlbnNpb24geyBuYW1lOlwiZ3JhdWx0XCIgZXh0ZW5kZWU6IFwiLkZvb1wiICAgICAgIG51bWJlcjozMiB9ICIKKyAgICAiZXh0ZW5zaW9uIHsgbmFtZTpcImdhcnBseVwiIGV4dGVuZGVlOiBcIi5jb3JnZS5CYXJcIiBudW1iZXI6NzAgfSAiCisgICAgImV4dGVuc2lvbiB7IG5hbWU6XCJ3YWxkb1wiICBleHRlbmRlZTogXCJCYXJcIiAgICAgICAgbnVtYmVyOjU2IH0gIik7CisKKyAgeworICAgIHZlY3RvcjxpbnQ+IG51bWJlcnM7CisgICAgRVhQRUNUX1RSVUUoZGF0YWJhc2VfLT5GaW5kQWxsRXh0ZW5zaW9uTnVtYmVycygiRm9vIiwgJm51bWJlcnMpKTsKKyAgICBBU1NFUlRfRVEoMiwgbnVtYmVycy5zaXplKCkpOworICAgIHN0ZDo6c29ydChudW1iZXJzLmJlZ2luKCksIG51bWJlcnMuZW5kKCkpOworICAgIEVYUEVDVF9FUSg1LCBudW1iZXJzWzBdKTsKKyAgICBFWFBFQ1RfRVEoMzIsIG51bWJlcnNbMV0pOworICB9CisKKyAgeworICAgIHZlY3RvcjxpbnQ+IG51bWJlcnM7CisgICAgRVhQRUNUX1RSVUUoZGF0YWJhc2VfLT5GaW5kQWxsRXh0ZW5zaW9uTnVtYmVycygiY29yZ2UuQmFyIiwgJm51bWJlcnMpKTsKKyAgICAvLyBOb3RlOiB3b24ndCBmaW5kIGV4dGVuc2lvbiA1NiBkdWUgdG8gdGhlIG5hbWUgbm90IGJlaW5nIGZ1bGx5IHF1YWxpZmllZC4KKyAgICBBU1NFUlRfRVEoMSwgbnVtYmVycy5zaXplKCkpOworICAgIEVYUEVDVF9FUSg3MCwgbnVtYmVyc1swXSk7CisgIH0KKworICB7CisgICAgLy8gQ2FuJ3QgZmluZCBleHRlbnNpb25zIGZvciBub24tZXhpc3RlbnQgdHlwZXMuCisgICAgdmVjdG9yPGludD4gbnVtYmVyczsKKyAgICBFWFBFQ1RfRkFMU0UoZGF0YWJhc2VfLT5GaW5kQWxsRXh0ZW5zaW9uTnVtYmVycygiTm9TdWNoVHlwZSIsICZudW1iZXJzKSk7CisgIH0KKworICB7CisgICAgLy8gQ2FuJ3QgZmluZCBleHRlbnNpb25zIGZvciB1bnF1YWxpZmllZCB0eXBlcy4KKyAgICB2ZWN0b3I8aW50PiBudW1iZXJzOworICAgIEVYUEVDVF9GQUxTRShkYXRhYmFzZV8tPkZpbmRBbGxFeHRlbnNpb25OdW1iZXJzKCJCYXIiLCAmbnVtYmVycykpOworICB9Cit9CisKK1RFU1RfUChEZXNjcmlwdG9yRGF0YWJhc2VUZXN0LCBDb25mbGljdGluZ0ZpbGVFcnJvcikgeworICBBZGRUb0RhdGFiYXNlKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsgIgorICAgICIgIG5hbWU6IFwiRm9vXCIgIgorICAgICJ9Iik7CisgIEFkZFRvRGF0YWJhc2VXaXRoRXJyb3IoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyAiCisgICAgIiAgbmFtZTogXCJCYXJcIiAiCisgICAgIn0iKTsKK30KKworVEVTVF9QKERlc2NyaXB0b3JEYXRhYmFzZVRlc3QsIENvbmZsaWN0aW5nVHlwZUVycm9yKSB7CisgIEFkZFRvRGF0YWJhc2UoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyAiCisgICAgIiAgbmFtZTogXCJGb29cIiAiCisgICAgIn0iKTsKKyAgQWRkVG9EYXRhYmFzZVdpdGhFcnJvcigKKyAgICAibmFtZTogXCJiYXIucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7ICIKKyAgICAiICBuYW1lOiBcIkZvb1wiICIKKyAgICAifSIpOworfQorCitURVNUX1AoRGVzY3JpcHRvckRhdGFiYXNlVGVzdCwgQ29uZmxpY3RpbmdFeHRlbnNpb25FcnJvcikgeworICBBZGRUb0RhdGFiYXNlKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAiZXh0ZW5zaW9uIHsgbmFtZTpcImZvb1wiIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiBudW1iZXI6NSAiCisgICAgIiAgICAgICAgICAgIGV4dGVuZGVlOiBcIi5Gb29cIiB9Iik7CisgIEFkZFRvRGF0YWJhc2VXaXRoRXJyb3IoCisgICAgIm5hbWU6IFwiYmFyLnByb3RvXCIgIgorICAgICJleHRlbnNpb24geyBuYW1lOlwiYmFyXCIgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZTpUWVBFX0lOVDMyIG51bWJlcjo1ICIKKyAgICAiICAgICAgICAgICAgZXh0ZW5kZWU6IFwiLkZvb1wiIH0iKTsKK30KKworSU5TVEFOVElBVEVfVEVTVF9DQVNFX1AoU2ltcGxlLCBEZXNjcmlwdG9yRGF0YWJhc2VUZXN0LAorICAgIHRlc3Rpbmc6OlZhbHVlcygmU2ltcGxlRGVzY3JpcHRvckRhdGFiYXNlVGVzdENhc2U6Ok5ldykpOworSU5TVEFOVElBVEVfVEVTVF9DQVNFX1AoTWVtb3J5Q29uc2VydmluZywgRGVzY3JpcHRvckRhdGFiYXNlVGVzdCwKKyAgICB0ZXN0aW5nOjpWYWx1ZXMoJkVuY29kZWREZXNjcmlwdG9yRGF0YWJhc2VUZXN0Q2FzZTo6TmV3KSk7CitJTlNUQU5USUFURV9URVNUX0NBU0VfUChQb29sLCBEZXNjcmlwdG9yRGF0YWJhc2VUZXN0LAorICAgIHRlc3Rpbmc6OlZhbHVlcygmRGVzY3JpcHRvclBvb2xEYXRhYmFzZVRlc3RDYXNlOjpOZXcpKTsKKworI2VuZGlmICAvLyBHVEVTVF9IQVNfUEFSQU1fVEVTVAorCitURVNUKEVuY29kZWREZXNjcmlwdG9yRGF0YWJhc2VFeHRyYVRlc3QsIEZpbmROYW1lT2ZGaWxlQ29udGFpbmluZ1N5bWJvbCkgeworICAvLyBDcmVhdGUgdHdvIGZpbGVzLCBvbmUgb2Ygd2hpY2ggaXMgaW4gdHdvIHBhcnRzLgorICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGUxLCBmaWxlMmEsIGZpbGUyYjsKKyAgZmlsZTEuc2V0X25hbWUoImZvby5wcm90byIpOworICBmaWxlMS5zZXRfcGFja2FnZSgiZm9vIik7CisgIGZpbGUxLmFkZF9tZXNzYWdlX3R5cGUoKS0+c2V0X25hbWUoIkZvbyIpOworICBmaWxlMmEuc2V0X25hbWUoImJhci5wcm90byIpOworICBmaWxlMmIuc2V0X3BhY2thZ2UoImJhciIpOworICBmaWxlMmIuYWRkX21lc3NhZ2VfdHlwZSgpLT5zZXRfbmFtZSgiQmFyIik7CisKKyAgLy8gTm9ybWFsIHNlcmlhbGl6YXRpb24gYWxsb3dzIG91ciBvcHRpbWl6YXRpb24gdG8ga2ljayBpbi4KKyAgc3RyaW5nIGRhdGExID0gZmlsZTEuU2VyaWFsaXplQXNTdHJpbmcoKTsKKworICAvLyBGb3JjZSBvdXQtb2Ytb3JkZXIgc2VyaWFsaXphdGlvbiB0byB0ZXN0IHNsb3cgcGF0aC4KKyAgc3RyaW5nIGRhdGEyID0gZmlsZTJiLlNlcmlhbGl6ZUFzU3RyaW5nKCkgKyBmaWxlMmEuU2VyaWFsaXplQXNTdHJpbmcoKTsKKworICAvLyBDcmVhdGUgRW5jb2RlZERlc2NyaXB0b3JEYXRhYmFzZSBjb250YWluaW5nIGJvdGggZmlsZXMuCisgIEVuY29kZWREZXNjcmlwdG9yRGF0YWJhc2UgZGI7CisgIGRiLkFkZChkYXRhMS5kYXRhKCksIGRhdGExLnNpemUoKSk7CisgIGRiLkFkZChkYXRhMi5kYXRhKCksIGRhdGEyLnNpemUoKSk7CisKKyAgLy8gVGVzdCEKKyAgc3RyaW5nIGZpbGVuYW1lOworICBFWFBFQ1RfVFJVRShkYi5GaW5kTmFtZU9mRmlsZUNvbnRhaW5pbmdTeW1ib2woImZvby5Gb28iLCAmZmlsZW5hbWUpKTsKKyAgRVhQRUNUX0VRKCJmb28ucHJvdG8iLCBmaWxlbmFtZSk7CisgIEVYUEVDVF9UUlVFKGRiLkZpbmROYW1lT2ZGaWxlQ29udGFpbmluZ1N5bWJvbCgiZm9vLkZvby5CbGFoIiwgJmZpbGVuYW1lKSk7CisgIEVYUEVDVF9FUSgiZm9vLnByb3RvIiwgZmlsZW5hbWUpOworICBFWFBFQ1RfVFJVRShkYi5GaW5kTmFtZU9mRmlsZUNvbnRhaW5pbmdTeW1ib2woImJhci5CYXIiLCAmZmlsZW5hbWUpKTsKKyAgRVhQRUNUX0VRKCJiYXIucHJvdG8iLCBmaWxlbmFtZSk7CisgIEVYUEVDVF9GQUxTRShkYi5GaW5kTmFtZU9mRmlsZUNvbnRhaW5pbmdTeW1ib2woImZvbyIsICZmaWxlbmFtZSkpOworICBFWFBFQ1RfRkFMU0UoZGIuRmluZE5hbWVPZkZpbGVDb250YWluaW5nU3ltYm9sKCJiYXIiLCAmZmlsZW5hbWUpKTsKKyAgRVhQRUNUX0ZBTFNFKGRiLkZpbmROYW1lT2ZGaWxlQ29udGFpbmluZ1N5bWJvbCgiYmF6LkJheiIsICZmaWxlbmFtZSkpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK2NsYXNzIE1lcmdlZERlc2NyaXB0b3JEYXRhYmFzZVRlc3QgOiBwdWJsaWMgdGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICBNZXJnZWREZXNjcmlwdG9yRGF0YWJhc2VUZXN0KCkKKyAgICA6IGZvcndhcmRfbWVyZ2VkXygmZGF0YWJhc2UxXywgJmRhdGFiYXNlMl8pLAorICAgICAgcmV2ZXJzZV9tZXJnZWRfKCZkYXRhYmFzZTJfLCAmZGF0YWJhc2UxXykge30KKworICB2aXJ0dWFsIHZvaWQgU2V0VXAoKSB7CisgICAgQWRkVG9EYXRhYmFzZSgmZGF0YWJhc2UxXywKKyAgICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAgICJtZXNzYWdlX3R5cGUgeyBuYW1lOlwiRm9vXCIgZXh0ZW5zaW9uX3JhbmdlIHsgc3RhcnQ6IDEgZW5kOiAxMDAgfSB9ICIKKyAgICAgICJleHRlbnNpb24geyBuYW1lOlwiZm9vX2V4dFwiIGV4dGVuZGVlOiBcIi5Gb29cIiBudW1iZXI6MyAiCisgICAgICAiICAgICAgICAgICAgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZTpUWVBFX0lOVDMyIH0gIik7CisgICAgQWRkVG9EYXRhYmFzZSgmZGF0YWJhc2UyXywKKyAgICAgICJuYW1lOiBcImJhci5wcm90b1wiICIKKyAgICAgICJtZXNzYWdlX3R5cGUgeyBuYW1lOlwiQmFyXCIgZXh0ZW5zaW9uX3JhbmdlIHsgc3RhcnQ6IDEgZW5kOiAxMDAgfSB9ICIKKyAgICAgICJleHRlbnNpb24geyBuYW1lOlwiYmFyX2V4dFwiIGV4dGVuZGVlOiBcIi5CYXJcIiBudW1iZXI6NSAiCisgICAgICAiICAgICAgICAgICAgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZTpUWVBFX0lOVDMyIH0gIik7CisKKyAgICAvLyBiYXoucHJvdG8gZXhpc3RzIGluIGJvdGggcG9vbHMsIHdpdGggZGlmZmVyZW50IGRlZmluaXRpb25zLgorICAgIEFkZFRvRGF0YWJhc2UoJmRhdGFiYXNlMV8sCisgICAgICAibmFtZTogXCJiYXoucHJvdG9cIiAiCisgICAgICAibWVzc2FnZV90eXBlIHsgbmFtZTpcIkJhelwiIGV4dGVuc2lvbl9yYW5nZSB7IHN0YXJ0OiAxIGVuZDogMTAwIH0gfSAiCisgICAgICAibWVzc2FnZV90eXBlIHsgbmFtZTpcIkZyb21Qb29sMVwiIH0gIgorICAgICAgImV4dGVuc2lvbiB7IG5hbWU6XCJiYXpfZXh0XCIgZXh0ZW5kZWU6IFwiLkJhelwiIG51bWJlcjoxMiAiCisgICAgICAiICAgICAgICAgICAgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZTpUWVBFX0lOVDMyIH0gIgorICAgICAgImV4dGVuc2lvbiB7IG5hbWU6XCJkYXRhYmFzZTFfb25seV9leHRcIiBleHRlbmRlZTogXCIuQmF6XCIgbnVtYmVyOjEzICIKKyAgICAgICIgICAgICAgICAgICBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgfSAiKTsKKyAgICBBZGRUb0RhdGFiYXNlKCZkYXRhYmFzZTJfLAorICAgICAgIm5hbWU6IFwiYmF6LnByb3RvXCIgIgorICAgICAgIm1lc3NhZ2VfdHlwZSB7IG5hbWU6XCJCYXpcIiBleHRlbnNpb25fcmFuZ2UgeyBzdGFydDogMSBlbmQ6IDEwMCB9IH0gIgorICAgICAgIm1lc3NhZ2VfdHlwZSB7IG5hbWU6XCJGcm9tUG9vbDJcIiB9ICIKKyAgICAgICJleHRlbnNpb24geyBuYW1lOlwiYmF6X2V4dFwiIGV4dGVuZGVlOiBcIi5CYXpcIiBudW1iZXI6MTIgIgorICAgICAgIiAgICAgICAgICAgIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiB9ICIpOworICB9CisKKyAgU2ltcGxlRGVzY3JpcHRvckRhdGFiYXNlIGRhdGFiYXNlMV87CisgIFNpbXBsZURlc2NyaXB0b3JEYXRhYmFzZSBkYXRhYmFzZTJfOworCisgIE1lcmdlZERlc2NyaXB0b3JEYXRhYmFzZSBmb3J3YXJkX21lcmdlZF87CisgIE1lcmdlZERlc2NyaXB0b3JEYXRhYmFzZSByZXZlcnNlX21lcmdlZF87Cit9OworCitURVNUX0YoTWVyZ2VkRGVzY3JpcHRvckRhdGFiYXNlVGVzdCwgRmluZEZpbGVCeU5hbWUpIHsKKyAgeworICAgIC8vIENhbiBmaW5kIGZpbGUgdGhhdCBpcyBvbmx5IGluIGRhdGFiYXNlMV8uCisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlOworICAgIEVYUEVDVF9UUlVFKGZvcndhcmRfbWVyZ2VkXy5GaW5kRmlsZUJ5TmFtZSgiZm9vLnByb3RvIiwgJmZpbGUpKTsKKyAgICBFWFBFQ1RfRVEoImZvby5wcm90byIsIGZpbGUubmFtZSgpKTsKKyAgICBFeHBlY3RDb250YWluc1R5cGUoZmlsZSwgIkZvbyIpOworICB9CisKKyAgeworICAgIC8vIENhbiBmaW5kIGZpbGUgdGhhdCBpcyBvbmx5IGluIGRhdGFiYXNlMl8uCisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlOworICAgIEVYUEVDVF9UUlVFKGZvcndhcmRfbWVyZ2VkXy5GaW5kRmlsZUJ5TmFtZSgiYmFyLnByb3RvIiwgJmZpbGUpKTsKKyAgICBFWFBFQ1RfRVEoImJhci5wcm90byIsIGZpbGUubmFtZSgpKTsKKyAgICBFeHBlY3RDb250YWluc1R5cGUoZmlsZSwgIkJhciIpOworICB9CisKKyAgeworICAgIC8vIEluIGZvcndhcmRfbWVyZ2VkXywgZGF0YWJhc2UxXydzIGJhei5wcm90byB0YWtlcyBwcmVjZWRlbmNlLgorICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZTsKKyAgICBFWFBFQ1RfVFJVRShmb3J3YXJkX21lcmdlZF8uRmluZEZpbGVCeU5hbWUoImJhei5wcm90byIsICZmaWxlKSk7CisgICAgRVhQRUNUX0VRKCJiYXoucHJvdG8iLCBmaWxlLm5hbWUoKSk7CisgICAgRXhwZWN0Q29udGFpbnNUeXBlKGZpbGUsICJGcm9tUG9vbDEiKTsKKyAgfQorCisgIHsKKyAgICAvLyBJbiByZXZlcnNlX21lcmdlZF8sIGRhdGFiYXNlMl8ncyBiYXoucHJvdG8gdGFrZXMgcHJlY2VkZW5jZS4KKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGU7CisgICAgRVhQRUNUX1RSVUUocmV2ZXJzZV9tZXJnZWRfLkZpbmRGaWxlQnlOYW1lKCJiYXoucHJvdG8iLCAmZmlsZSkpOworICAgIEVYUEVDVF9FUSgiYmF6LnByb3RvIiwgZmlsZS5uYW1lKCkpOworICAgIEV4cGVjdENvbnRhaW5zVHlwZShmaWxlLCAiRnJvbVBvb2wyIik7CisgIH0KKworICB7CisgICAgLy8gQ2FuJ3QgZmluZCBub24tZXhpc3RlbnQgZmlsZS4KKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGU7CisgICAgRVhQRUNUX0ZBTFNFKGZvcndhcmRfbWVyZ2VkXy5GaW5kRmlsZUJ5TmFtZSgibm9fc3VjaC5wcm90byIsICZmaWxlKSk7CisgIH0KK30KKworVEVTVF9GKE1lcmdlZERlc2NyaXB0b3JEYXRhYmFzZVRlc3QsIEZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbCkgeworICB7CisgICAgLy8gQ2FuIGZpbmQgZmlsZSB0aGF0IGlzIG9ubHkgaW4gZGF0YWJhc2UxXy4KKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGU7CisgICAgRVhQRUNUX1RSVUUoZm9yd2FyZF9tZXJnZWRfLkZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbCgiRm9vIiwgJmZpbGUpKTsKKyAgICBFWFBFQ1RfRVEoImZvby5wcm90byIsIGZpbGUubmFtZSgpKTsKKyAgICBFeHBlY3RDb250YWluc1R5cGUoZmlsZSwgIkZvbyIpOworICB9CisKKyAgeworICAgIC8vIENhbiBmaW5kIGZpbGUgdGhhdCBpcyBvbmx5IGluIGRhdGFiYXNlMl8uCisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlOworICAgIEVYUEVDVF9UUlVFKGZvcndhcmRfbWVyZ2VkXy5GaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2woIkJhciIsICZmaWxlKSk7CisgICAgRVhQRUNUX0VRKCJiYXIucHJvdG8iLCBmaWxlLm5hbWUoKSk7CisgICAgRXhwZWN0Q29udGFpbnNUeXBlKGZpbGUsICJCYXIiKTsKKyAgfQorCisgIHsKKyAgICAvLyBJbiBmb3J3YXJkX21lcmdlZF8sIGRhdGFiYXNlMV8ncyBiYXoucHJvdG8gdGFrZXMgcHJlY2VkZW5jZS4KKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGU7CisgICAgRVhQRUNUX1RSVUUoZm9yd2FyZF9tZXJnZWRfLkZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbCgiQmF6IiwgJmZpbGUpKTsKKyAgICBFWFBFQ1RfRVEoImJhei5wcm90byIsIGZpbGUubmFtZSgpKTsKKyAgICBFeHBlY3RDb250YWluc1R5cGUoZmlsZSwgIkZyb21Qb29sMSIpOworICB9CisKKyAgeworICAgIC8vIEluIHJldmVyc2VfbWVyZ2VkXywgZGF0YWJhc2UyXydzIGJhei5wcm90byB0YWtlcyBwcmVjZWRlbmNlLgorICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZTsKKyAgICBFWFBFQ1RfVFJVRShyZXZlcnNlX21lcmdlZF8uRmluZEZpbGVDb250YWluaW5nU3ltYm9sKCJCYXoiLCAmZmlsZSkpOworICAgIEVYUEVDVF9FUSgiYmF6LnByb3RvIiwgZmlsZS5uYW1lKCkpOworICAgIEV4cGVjdENvbnRhaW5zVHlwZShmaWxlLCAiRnJvbVBvb2wyIik7CisgIH0KKworICB7CisgICAgLy8gRnJvbVBvb2wxIG9ubHkgc2hvd3MgdXAgaW4gZm9yd2FyZF9tZXJnZWRfIGJlY2F1c2UgaXQgaXMgbWFza2VkIGJ5CisgICAgLy8gZGF0YWJhc2UyXydzIGJhei5wcm90byBpbiByZXZlcnNlX21lcmdlZF8uCisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlOworICAgIEVYUEVDVF9UUlVFKGZvcndhcmRfbWVyZ2VkXy5GaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2woIkZyb21Qb29sMSIsICZmaWxlKSk7CisgICAgRVhQRUNUX0ZBTFNFKHJldmVyc2VfbWVyZ2VkXy5GaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2woIkZyb21Qb29sMSIsICZmaWxlKSk7CisgIH0KKworICB7CisgICAgLy8gQ2FuJ3QgZmluZCBub24tZXhpc3RlbnQgc3ltYm9sLgorICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZTsKKyAgICBFWFBFQ1RfRkFMU0UoCisgICAgICBmb3J3YXJkX21lcmdlZF8uRmluZEZpbGVDb250YWluaW5nU3ltYm9sKCJOb1N1Y2hUeXBlIiwgJmZpbGUpKTsKKyAgfQorfQorCitURVNUX0YoTWVyZ2VkRGVzY3JpcHRvckRhdGFiYXNlVGVzdCwgRmluZEZpbGVDb250YWluaW5nRXh0ZW5zaW9uKSB7CisgIHsKKyAgICAvLyBDYW4gZmluZCBmaWxlIHRoYXQgaXMgb25seSBpbiBkYXRhYmFzZTFfLgorICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZTsKKyAgICBFWFBFQ1RfVFJVRSgKKyAgICAgIGZvcndhcmRfbWVyZ2VkXy5GaW5kRmlsZUNvbnRhaW5pbmdFeHRlbnNpb24oIkZvbyIsIDMsICZmaWxlKSk7CisgICAgRVhQRUNUX0VRKCJmb28ucHJvdG8iLCBmaWxlLm5hbWUoKSk7CisgICAgRXhwZWN0Q29udGFpbnNUeXBlKGZpbGUsICJGb28iKTsKKyAgfQorCisgIHsKKyAgICAvLyBDYW4gZmluZCBmaWxlIHRoYXQgaXMgb25seSBpbiBkYXRhYmFzZTJfLgorICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZTsKKyAgICBFWFBFQ1RfVFJVRSgKKyAgICAgIGZvcndhcmRfbWVyZ2VkXy5GaW5kRmlsZUNvbnRhaW5pbmdFeHRlbnNpb24oIkJhciIsIDUsICZmaWxlKSk7CisgICAgRVhQRUNUX0VRKCJiYXIucHJvdG8iLCBmaWxlLm5hbWUoKSk7CisgICAgRXhwZWN0Q29udGFpbnNUeXBlKGZpbGUsICJCYXIiKTsKKyAgfQorCisgIHsKKyAgICAvLyBJbiBmb3J3YXJkX21lcmdlZF8sIGRhdGFiYXNlMV8ncyBiYXoucHJvdG8gdGFrZXMgcHJlY2VkZW5jZS4KKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGU7CisgICAgRVhQRUNUX1RSVUUoCisgICAgICBmb3J3YXJkX21lcmdlZF8uRmluZEZpbGVDb250YWluaW5nRXh0ZW5zaW9uKCJCYXoiLCAxMiwgJmZpbGUpKTsKKyAgICBFWFBFQ1RfRVEoImJhei5wcm90byIsIGZpbGUubmFtZSgpKTsKKyAgICBFeHBlY3RDb250YWluc1R5cGUoZmlsZSwgIkZyb21Qb29sMSIpOworICB9CisKKyAgeworICAgIC8vIEluIHJldmVyc2VfbWVyZ2VkXywgZGF0YWJhc2UyXydzIGJhei5wcm90byB0YWtlcyBwcmVjZWRlbmNlLgorICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZTsKKyAgICBFWFBFQ1RfVFJVRSgKKyAgICAgIHJldmVyc2VfbWVyZ2VkXy5GaW5kRmlsZUNvbnRhaW5pbmdFeHRlbnNpb24oIkJheiIsIDEyLCAmZmlsZSkpOworICAgIEVYUEVDVF9FUSgiYmF6LnByb3RvIiwgZmlsZS5uYW1lKCkpOworICAgIEV4cGVjdENvbnRhaW5zVHlwZShmaWxlLCAiRnJvbVBvb2wyIik7CisgIH0KKworICB7CisgICAgLy8gQmF6J3MgZXh0ZW5zaW9uIDEzIG9ubHkgc2hvd3MgdXAgaW4gZm9yd2FyZF9tZXJnZWRfIGJlY2F1c2UgaXQgaXMKKyAgICAvLyBtYXNrZWQgYnkgZGF0YWJhc2UyXydzIGJhei5wcm90byBpbiByZXZlcnNlX21lcmdlZF8uCisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlOworICAgIEVYUEVDVF9UUlVFKGZvcndhcmRfbWVyZ2VkXy5GaW5kRmlsZUNvbnRhaW5pbmdFeHRlbnNpb24oIkJheiIsIDEzLCAmZmlsZSkpOworICAgIEVYUEVDVF9GQUxTRShyZXZlcnNlX21lcmdlZF8uRmluZEZpbGVDb250YWluaW5nRXh0ZW5zaW9uKCJCYXoiLCAxMywgJmZpbGUpKTsKKyAgfQorCisgIHsKKyAgICAvLyBDYW4ndCBmaW5kIG5vbi1leGlzdGVudCBleHRlbnNpb24uCisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlOworICAgIEVYUEVDVF9GQUxTRSgKKyAgICAgIGZvcndhcmRfbWVyZ2VkXy5GaW5kRmlsZUNvbnRhaW5pbmdFeHRlbnNpb24oIkZvbyIsIDYsICZmaWxlKSk7CisgIH0KK30KKworVEVTVF9GKE1lcmdlZERlc2NyaXB0b3JEYXRhYmFzZVRlc3QsIEZpbmRBbGxFeHRlbnNpb25OdW1iZXJzKSB7CisgIHsKKyAgICAvLyBNZXNzYWdlIG9ubHkgaGFzIGV4dGVuc2lvbiBpbiBkYXRhYmFzZTFfCisgICAgdmVjdG9yPGludD4gbnVtYmVyczsKKyAgICBFWFBFQ1RfVFJVRShmb3J3YXJkX21lcmdlZF8uRmluZEFsbEV4dGVuc2lvbk51bWJlcnMoIkZvbyIsICZudW1iZXJzKSk7CisgICAgQVNTRVJUX0VRKDEsIG51bWJlcnMuc2l6ZSgpKTsKKyAgICBFWFBFQ1RfRVEoMywgbnVtYmVyc1swXSk7CisgIH0KKworICB7CisgICAgLy8gTWVzc2FnZSBvbmx5IGhhcyBleHRlbnNpb24gaW4gZGF0YWJhc2UyXworICAgIHZlY3RvcjxpbnQ+IG51bWJlcnM7CisgICAgRVhQRUNUX1RSVUUoZm9yd2FyZF9tZXJnZWRfLkZpbmRBbGxFeHRlbnNpb25OdW1iZXJzKCJCYXIiLCAmbnVtYmVycykpOworICAgIEFTU0VSVF9FUSgxLCBudW1iZXJzLnNpemUoKSk7CisgICAgRVhQRUNUX0VRKDUsIG51bWJlcnNbMF0pOworICB9CisKKyAgeworICAgIC8vIE1lcmdlIHJlc3VsdHMgZnJvbSB0aGUgdHdvIGRhdGFiYXNlcy4KKyAgICB2ZWN0b3I8aW50PiBudW1iZXJzOworICAgIEVYUEVDVF9UUlVFKGZvcndhcmRfbWVyZ2VkXy5GaW5kQWxsRXh0ZW5zaW9uTnVtYmVycygiQmF6IiwgJm51bWJlcnMpKTsKKyAgICBBU1NFUlRfRVEoMiwgbnVtYmVycy5zaXplKCkpOworICAgIHN0ZDo6c29ydChudW1iZXJzLmJlZ2luKCksIG51bWJlcnMuZW5kKCkpOworICAgIEVYUEVDVF9FUSgxMiwgbnVtYmVyc1swXSk7CisgICAgRVhQRUNUX0VRKDEzLCBudW1iZXJzWzFdKTsKKyAgfQorCisgIHsKKyAgICB2ZWN0b3I8aW50PiBudW1iZXJzOworICAgIEVYUEVDVF9UUlVFKHJldmVyc2VfbWVyZ2VkXy5GaW5kQWxsRXh0ZW5zaW9uTnVtYmVycygiQmF6IiwgJm51bWJlcnMpKTsKKyAgICBBU1NFUlRfRVEoMiwgbnVtYmVycy5zaXplKCkpOworICAgIHN0ZDo6c29ydChudW1iZXJzLmJlZ2luKCksIG51bWJlcnMuZW5kKCkpOworICAgIEVYUEVDVF9FUSgxMiwgbnVtYmVyc1swXSk7CisgICAgRVhQRUNUX0VRKDEzLCBudW1iZXJzWzFdKTsKKyAgfQorCisgIHsKKyAgICAvLyBDYW4ndCBmaW5kIGV4dGVuc2lvbnMgZm9yIGEgbm9uLWV4aXN0ZW50IG1lc3NhZ2UuCisgICAgdmVjdG9yPGludD4gbnVtYmVyczsKKyAgICBFWFBFQ1RfRkFMU0UocmV2ZXJzZV9tZXJnZWRfLkZpbmRBbGxFeHRlbnNpb25OdW1iZXJzKCJCbGFoIiwgJm51bWJlcnMpKTsKKyAgfQorfQorCit9ICAvLyBhbm9ueW1vdXMgbmFtZXNwYWNlCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvcl91bml0dGVzdC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvcl91bml0dGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iZThlMGI3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yX3VuaXR0ZXN0LmNjCkBAIC0wLDAgKzEsNjYyNCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorLy8KKy8vIFRoaXMgZmlsZSBtYWtlcyBleHRlbnNpdmUgdXNlIG9mIFJGQyAzMDkyLiAgOikKKworI2luY2x1ZGUgPG1lbW9yeT4KKyNpZm5kZWYgX1NIQVJFRF9QVFJfSAorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaGFyZWRfcHRyLmg+CisjZW5kaWYKKyNpbmNsdWRlIDx2ZWN0b3I+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvaW1wb3J0ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfY3VzdG9tX29wdGlvbnMucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbV9pbXBsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yX2RhdGFiYXNlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2R5bmFtaWNfbWVzc2FnZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXh0X2Zvcm1hdC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N1YnN0aXR1dGUuaD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbG9nZ2luZy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zY29wZWRfcHRyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZ29vZ2xldGVzdC5oPgorI2luY2x1ZGUgPGd0ZXN0L2d0ZXN0Lmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworLy8gQ2FuJ3QgdXNlIGFuIGFub255bW91cyBuYW1lc3BhY2UgaGVyZSBkdWUgdG8gYnJva2VubmVzcyBvZiBUcnU2NCBjb21waWxlci4KK25hbWVzcGFjZSBkZXNjcmlwdG9yX3VuaXR0ZXN0IHsKKworLy8gU29tZSBoZWxwZXJzIHRvIG1ha2UgYXNzZW1ibGluZyBkZXNjcmlwdG9ycyBmYXN0ZXIuCitEZXNjcmlwdG9yUHJvdG8qIEFkZE1lc3NhZ2UoRmlsZURlc2NyaXB0b3JQcm90byogZmlsZSwgY29uc3Qgc3RyaW5nJiBuYW1lKSB7CisgIERlc2NyaXB0b3JQcm90byogcmVzdWx0ID0gZmlsZS0+YWRkX21lc3NhZ2VfdHlwZSgpOworICByZXN1bHQtPnNldF9uYW1lKG5hbWUpOworICByZXR1cm4gcmVzdWx0OworfQorCitEZXNjcmlwdG9yUHJvdG8qIEFkZE5lc3RlZE1lc3NhZ2UoRGVzY3JpcHRvclByb3RvKiBwYXJlbnQsIGNvbnN0IHN0cmluZyYgbmFtZSkgeworICBEZXNjcmlwdG9yUHJvdG8qIHJlc3VsdCA9IHBhcmVudC0+YWRkX25lc3RlZF90eXBlKCk7CisgIHJlc3VsdC0+c2V0X25hbWUobmFtZSk7CisgIHJldHVybiByZXN1bHQ7Cit9CisKK0VudW1EZXNjcmlwdG9yUHJvdG8qIEFkZEVudW0oRmlsZURlc2NyaXB0b3JQcm90byogZmlsZSwgY29uc3Qgc3RyaW5nJiBuYW1lKSB7CisgIEVudW1EZXNjcmlwdG9yUHJvdG8qIHJlc3VsdCA9IGZpbGUtPmFkZF9lbnVtX3R5cGUoKTsKKyAgcmVzdWx0LT5zZXRfbmFtZShuYW1lKTsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworRW51bURlc2NyaXB0b3JQcm90byogQWRkTmVzdGVkRW51bShEZXNjcmlwdG9yUHJvdG8qIHBhcmVudCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBuYW1lKSB7CisgIEVudW1EZXNjcmlwdG9yUHJvdG8qIHJlc3VsdCA9IHBhcmVudC0+YWRkX2VudW1fdHlwZSgpOworICByZXN1bHQtPnNldF9uYW1lKG5hbWUpOworICByZXR1cm4gcmVzdWx0OworfQorCitTZXJ2aWNlRGVzY3JpcHRvclByb3RvKiBBZGRTZXJ2aWNlKEZpbGVEZXNjcmlwdG9yUHJvdG8qIGZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgbmFtZSkgeworICBTZXJ2aWNlRGVzY3JpcHRvclByb3RvKiByZXN1bHQgPSBmaWxlLT5hZGRfc2VydmljZSgpOworICByZXN1bHQtPnNldF9uYW1lKG5hbWUpOworICByZXR1cm4gcmVzdWx0OworfQorCitGaWVsZERlc2NyaXB0b3JQcm90byogQWRkRmllbGQoRGVzY3JpcHRvclByb3RvKiBwYXJlbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBuYW1lLCBpbnQgbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpMYWJlbCBsYWJlbCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6VHlwZSB0eXBlKSB7CisgIEZpZWxkRGVzY3JpcHRvclByb3RvKiByZXN1bHQgPSBwYXJlbnQtPmFkZF9maWVsZCgpOworICByZXN1bHQtPnNldF9uYW1lKG5hbWUpOworICByZXN1bHQtPnNldF9udW1iZXIobnVtYmVyKTsKKyAgcmVzdWx0LT5zZXRfbGFiZWwobGFiZWwpOworICByZXN1bHQtPnNldF90eXBlKHR5cGUpOworICByZXR1cm4gcmVzdWx0OworfQorCitGaWVsZERlc2NyaXB0b3JQcm90byogQWRkRXh0ZW5zaW9uKEZpbGVEZXNjcmlwdG9yUHJvdG8qIGZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgZXh0ZW5kZWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgbmFtZSwgaW50IG51bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OkxhYmVsIGxhYmVsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6VHlwZSB0eXBlKSB7CisgIEZpZWxkRGVzY3JpcHRvclByb3RvKiByZXN1bHQgPSBmaWxlLT5hZGRfZXh0ZW5zaW9uKCk7CisgIHJlc3VsdC0+c2V0X25hbWUobmFtZSk7CisgIHJlc3VsdC0+c2V0X251bWJlcihudW1iZXIpOworICByZXN1bHQtPnNldF9sYWJlbChsYWJlbCk7CisgIHJlc3VsdC0+c2V0X3R5cGUodHlwZSk7CisgIHJlc3VsdC0+c2V0X2V4dGVuZGVlKGV4dGVuZGVlKTsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworRmllbGREZXNjcmlwdG9yUHJvdG8qIEFkZE5lc3RlZEV4dGVuc2lvbihEZXNjcmlwdG9yUHJvdG8qIHBhcmVudCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBleHRlbmRlZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBuYW1lLCBpbnQgbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6TGFiZWwgbGFiZWwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUeXBlIHR5cGUpIHsKKyAgRmllbGREZXNjcmlwdG9yUHJvdG8qIHJlc3VsdCA9IHBhcmVudC0+YWRkX2V4dGVuc2lvbigpOworICByZXN1bHQtPnNldF9uYW1lKG5hbWUpOworICByZXN1bHQtPnNldF9udW1iZXIobnVtYmVyKTsKKyAgcmVzdWx0LT5zZXRfbGFiZWwobGFiZWwpOworICByZXN1bHQtPnNldF90eXBlKHR5cGUpOworICByZXN1bHQtPnNldF9leHRlbmRlZShleHRlbmRlZSk7CisgIHJldHVybiByZXN1bHQ7Cit9CisKK0Rlc2NyaXB0b3JQcm90bzo6RXh0ZW5zaW9uUmFuZ2UqIEFkZEV4dGVuc2lvblJhbmdlKERlc2NyaXB0b3JQcm90byogcGFyZW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHN0YXJ0LCBpbnQgZW5kKSB7CisgIERlc2NyaXB0b3JQcm90bzo6RXh0ZW5zaW9uUmFuZ2UqIHJlc3VsdCA9IHBhcmVudC0+YWRkX2V4dGVuc2lvbl9yYW5nZSgpOworICByZXN1bHQtPnNldF9zdGFydChzdGFydCk7CisgIHJlc3VsdC0+c2V0X2VuZChlbmQpOworICByZXR1cm4gcmVzdWx0OworfQorCitEZXNjcmlwdG9yUHJvdG86OlJlc2VydmVkUmFuZ2UqIEFkZFJlc2VydmVkUmFuZ2UoRGVzY3JpcHRvclByb3RvKiBwYXJlbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHN0YXJ0LCBpbnQgZW5kKSB7CisgIERlc2NyaXB0b3JQcm90bzo6UmVzZXJ2ZWRSYW5nZSogcmVzdWx0ID0gcGFyZW50LT5hZGRfcmVzZXJ2ZWRfcmFuZ2UoKTsKKyAgcmVzdWx0LT5zZXRfc3RhcnQoc3RhcnQpOworICByZXN1bHQtPnNldF9lbmQoZW5kKTsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworRW51bVZhbHVlRGVzY3JpcHRvclByb3RvKiBBZGRFbnVtVmFsdWUoRW51bURlc2NyaXB0b3JQcm90byogZW51bV9wcm90bywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgbmFtZSwgaW50IG51bWJlcikgeworICBFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8qIHJlc3VsdCA9IGVudW1fcHJvdG8tPmFkZF92YWx1ZSgpOworICByZXN1bHQtPnNldF9uYW1lKG5hbWUpOworICByZXN1bHQtPnNldF9udW1iZXIobnVtYmVyKTsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworTWV0aG9kRGVzY3JpcHRvclByb3RvKiBBZGRNZXRob2QoU2VydmljZURlc2NyaXB0b3JQcm90byogc2VydmljZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgaW5wdXRfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgb3V0cHV0X3R5cGUpIHsKKyAgTWV0aG9kRGVzY3JpcHRvclByb3RvKiByZXN1bHQgPSBzZXJ2aWNlLT5hZGRfbWV0aG9kKCk7CisgIHJlc3VsdC0+c2V0X25hbWUobmFtZSk7CisgIHJlc3VsdC0+c2V0X2lucHV0X3R5cGUoaW5wdXRfdHlwZSk7CisgIHJlc3VsdC0+c2V0X291dHB1dF90eXBlKG91dHB1dF90eXBlKTsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworLy8gRW1wdHkgZW51bXMgdGVjaG5pY2FsbHkgYXJlbid0IGFsbG93ZWQuICBXZSBuZWVkIHRvIGluc2VydCBhIGR1bW15IHZhbHVlCisvLyBpbnRvIHRoZW0uCit2b2lkIEFkZEVtcHR5RW51bShGaWxlRGVzY3JpcHRvclByb3RvKiBmaWxlLCBjb25zdCBzdHJpbmcmIG5hbWUpIHsKKyAgQWRkRW51bVZhbHVlKEFkZEVudW0oZmlsZSwgbmFtZSksIG5hbWUgKyAiX0RVTU1ZIiwgMSk7Cit9CisKK2NsYXNzIE1vY2tFcnJvckNvbGxlY3RvciA6IHB1YmxpYyBEZXNjcmlwdG9yUG9vbDo6RXJyb3JDb2xsZWN0b3IgeworIHB1YmxpYzoKKyAgTW9ja0Vycm9yQ29sbGVjdG9yKCkge30KKyAgfk1vY2tFcnJvckNvbGxlY3RvcigpIHt9CisKKyAgc3RyaW5nIHRleHRfOworICBzdHJpbmcgd2FybmluZ190ZXh0XzsKKworICAvLyBpbXBsZW1lbnRzIEVycm9yQ29sbGVjdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICB2b2lkIEFkZEVycm9yKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUsCisgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBlbGVtZW50X25hbWUsIGNvbnN0IE1lc3NhZ2UqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgRXJyb3JMb2NhdGlvbiBsb2NhdGlvbiwgY29uc3Qgc3RyaW5nJiBtZXNzYWdlKSB7CisgICAgY29uc3QgY2hhciogbG9jYXRpb25fbmFtZSA9IE5VTEw7CisgICAgc3dpdGNoIChsb2NhdGlvbikgeworICAgICAgY2FzZSBOQU1FICAgICAgICAgOiBsb2NhdGlvbl9uYW1lID0gIk5BTUUiICAgICAgICAgOyBicmVhazsKKyAgICAgIGNhc2UgTlVNQkVSICAgICAgIDogbG9jYXRpb25fbmFtZSA9ICJOVU1CRVIiICAgICAgIDsgYnJlYWs7CisgICAgICBjYXNlIFRZUEUgICAgICAgICA6IGxvY2F0aW9uX25hbWUgPSAiVFlQRSIgICAgICAgICA7IGJyZWFrOworICAgICAgY2FzZSBFWFRFTkRFRSAgICAgOiBsb2NhdGlvbl9uYW1lID0gIkVYVEVOREVFIiAgICAgOyBicmVhazsKKyAgICAgIGNhc2UgREVGQVVMVF9WQUxVRTogbG9jYXRpb25fbmFtZSA9ICJERUZBVUxUX1ZBTFVFIjsgYnJlYWs7CisgICAgICBjYXNlIE9QVElPTl9OQU1FICA6IGxvY2F0aW9uX25hbWUgPSAiT1BUSU9OX05BTUUiICA7IGJyZWFrOworICAgICAgY2FzZSBPUFRJT05fVkFMVUUgOiBsb2NhdGlvbl9uYW1lID0gIk9QVElPTl9WQUxVRSIgOyBicmVhazsKKyAgICAgIGNhc2UgSU5QVVRfVFlQRSAgIDogbG9jYXRpb25fbmFtZSA9ICJJTlBVVF9UWVBFIiAgIDsgYnJlYWs7CisgICAgICBjYXNlIE9VVFBVVF9UWVBFICA6IGxvY2F0aW9uX25hbWUgPSAiT1VUUFVUX1RZUEUiICA7IGJyZWFrOworICAgICAgY2FzZSBPVEhFUiAgICAgICAgOiBsb2NhdGlvbl9uYW1lID0gIk9USEVSIiAgICAgICAgOyBicmVhazsKKyAgICB9CisKKyAgICBzdHJpbmdzOjpTdWJzdGl0dXRlQW5kQXBwZW5kKAorICAgICAgJnRleHRfLCAiJDA6ICQxOiAkMjogJDNcbiIsCisgICAgICBmaWxlbmFtZSwgZWxlbWVudF9uYW1lLCBsb2NhdGlvbl9uYW1lLCBtZXNzYWdlKTsKKyAgfQorCisgIC8vIGltcGxlbWVudHMgRXJyb3JDb2xsZWN0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIHZvaWQgQWRkV2FybmluZyhjb25zdCBzdHJpbmcmIGZpbGVuYW1lLCBjb25zdCBzdHJpbmcmIGVsZW1lbnRfbmFtZSwKKyAgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2UqIGRlc2NyaXB0b3IsIEVycm9yTG9jYXRpb24gbG9jYXRpb24sCisgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIG1lc3NhZ2UpIHsKKyAgICBjb25zdCBjaGFyKiBsb2NhdGlvbl9uYW1lID0gTlVMTDsKKyAgICBzd2l0Y2ggKGxvY2F0aW9uKSB7CisgICAgICBjYXNlIE5BTUUgICAgICAgICA6IGxvY2F0aW9uX25hbWUgPSAiTkFNRSIgICAgICAgICA7IGJyZWFrOworICAgICAgY2FzZSBOVU1CRVIgICAgICAgOiBsb2NhdGlvbl9uYW1lID0gIk5VTUJFUiIgICAgICAgOyBicmVhazsKKyAgICAgIGNhc2UgVFlQRSAgICAgICAgIDogbG9jYXRpb25fbmFtZSA9ICJUWVBFIiAgICAgICAgIDsgYnJlYWs7CisgICAgICBjYXNlIEVYVEVOREVFICAgICA6IGxvY2F0aW9uX25hbWUgPSAiRVhURU5ERUUiICAgICA7IGJyZWFrOworICAgICAgY2FzZSBERUZBVUxUX1ZBTFVFOiBsb2NhdGlvbl9uYW1lID0gIkRFRkFVTFRfVkFMVUUiOyBicmVhazsKKyAgICAgIGNhc2UgT1BUSU9OX05BTUUgIDogbG9jYXRpb25fbmFtZSA9ICJPUFRJT05fTkFNRSIgIDsgYnJlYWs7CisgICAgICBjYXNlIE9QVElPTl9WQUxVRSA6IGxvY2F0aW9uX25hbWUgPSAiT1BUSU9OX1ZBTFVFIiA7IGJyZWFrOworICAgICAgY2FzZSBJTlBVVF9UWVBFICAgOiBsb2NhdGlvbl9uYW1lID0gIklOUFVUX1RZUEUiICAgOyBicmVhazsKKyAgICAgIGNhc2UgT1VUUFVUX1RZUEUgIDogbG9jYXRpb25fbmFtZSA9ICJPVVRQVVRfVFlQRSIgIDsgYnJlYWs7CisgICAgICBjYXNlIE9USEVSICAgICAgICA6IGxvY2F0aW9uX25hbWUgPSAiT1RIRVIiICAgICAgICA7IGJyZWFrOworICAgIH0KKworICAgIHN0cmluZ3M6OlN1YnN0aXR1dGVBbmRBcHBlbmQoCisgICAgICAmd2FybmluZ190ZXh0XywgIiQwOiAkMTogJDI6ICQzXG4iLAorICAgICAgZmlsZW5hbWUsIGVsZW1lbnRfbmFtZSwgbG9jYXRpb25fbmFtZSwgbWVzc2FnZSk7CisgIH0KK307CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworLy8gVGVzdCBzaW1wbGUgZmlsZXMuCitjbGFzcyBGaWxlRGVzY3JpcHRvclRlc3QgOiBwdWJsaWMgdGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICB2aXJ0dWFsIHZvaWQgU2V0VXAoKSB7CisgICAgLy8gQnVpbGQgZGVzY3JpcHRvcnMgZm9yIHRoZSBmb2xsb3dpbmcgZGVmaW5pdGlvbnM6CisgICAgLy8KKyAgICAvLyAgIC8vIGluICJmb28ucHJvdG8iCisgICAgLy8gICBtZXNzYWdlIEZvb01lc3NhZ2UgeyBleHRlbnNpb25zIDE7IH0KKyAgICAvLyAgIGVudW0gRm9vRW51bSB7Rk9PX0VOVU1fVkFMVUUgPSAxO30KKyAgICAvLyAgIHNlcnZpY2UgRm9vU2VydmljZSB7fQorICAgIC8vICAgZXh0ZW5kIEZvb01lc3NhZ2UgeyBvcHRpb25hbCBpbnQzMiBmb29fZXh0ZW5zaW9uID0gMTsgfQorICAgIC8vCisgICAgLy8gICAvLyBpbiAiYmFyLnByb3RvIgorICAgIC8vICAgcGFja2FnZSBiYXJfcGFja2FnZTsKKyAgICAvLyAgIG1lc3NhZ2UgQmFyTWVzc2FnZSB7IGV4dGVuc2lvbnMgMTsgfQorICAgIC8vICAgZW51bSBCYXJFbnVtIHtCQVJfRU5VTV9WQUxVRSA9IDE7fQorICAgIC8vICAgc2VydmljZSBCYXJTZXJ2aWNlIHt9CisgICAgLy8gICBleHRlbmQgQmFyTWVzc2FnZSB7IG9wdGlvbmFsIGludDMyIGJhcl9leHRlbnNpb24gPSAxOyB9CisgICAgLy8KKyAgICAvLyBBbHNvLCB3ZSBoYXZlIGFuIGVtcHR5IGZpbGUgImJhei5wcm90byIuICBUaGlzIGZpbGUncyBwdXJwb3NlIGlzIHRvCisgICAgLy8gbWFrZSBzdXJlIHRoYXQgZXZlbiB0aG91Z2ggaXQgaGFzIHRoZSBzYW1lIHBhY2thZ2UgYXMgZm9vLnByb3RvLAorICAgIC8vIHNlYXJjaGluZyBpdCBmb3IgbWVtYmVycyBvZiBmb28ucHJvdG8gd29uJ3Qgd29yay4KKworICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZm9vX2ZpbGU7CisgICAgZm9vX2ZpbGUuc2V0X25hbWUoImZvby5wcm90byIpOworICAgIEFkZEV4dGVuc2lvblJhbmdlKEFkZE1lc3NhZ2UoJmZvb19maWxlLCAiRm9vTWVzc2FnZSIpLCAxLCAyKTsKKyAgICBBZGRFbnVtVmFsdWUoQWRkRW51bSgmZm9vX2ZpbGUsICJGb29FbnVtIiksICJGT09fRU5VTV9WQUxVRSIsIDEpOworICAgIEFkZFNlcnZpY2UoJmZvb19maWxlLCAiRm9vU2VydmljZSIpOworICAgIEFkZEV4dGVuc2lvbigmZm9vX2ZpbGUsICJGb29NZXNzYWdlIiwgImZvb19leHRlbnNpb24iLCAxLAorICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfT1BUSU9OQUwsCisgICAgICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0lOVDMyKTsKKworICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gYmFyX2ZpbGU7CisgICAgYmFyX2ZpbGUuc2V0X25hbWUoImJhci5wcm90byIpOworICAgIGJhcl9maWxlLnNldF9wYWNrYWdlKCJiYXJfcGFja2FnZSIpOworICAgIGJhcl9maWxlLmFkZF9kZXBlbmRlbmN5KCJmb28ucHJvdG8iKTsKKyAgICBBZGRFeHRlbnNpb25SYW5nZShBZGRNZXNzYWdlKCZiYXJfZmlsZSwgIkJhck1lc3NhZ2UiKSwgMSwgMik7CisgICAgQWRkRW51bVZhbHVlKEFkZEVudW0oJmJhcl9maWxlLCAiQmFyRW51bSIpLCAiQkFSX0VOVU1fVkFMVUUiLCAxKTsKKyAgICBBZGRTZXJ2aWNlKCZiYXJfZmlsZSwgIkJhclNlcnZpY2UiKTsKKyAgICBBZGRFeHRlbnNpb24oJmJhcl9maWxlLCAiYmFyX3BhY2thZ2UuQmFyTWVzc2FnZSIsICJiYXJfZXh0ZW5zaW9uIiwgMSwKKyAgICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX09QVElPTkFMLAorICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9JTlQzMik7CisKKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGJhel9maWxlOworICAgIGJhel9maWxlLnNldF9uYW1lKCJiYXoucHJvdG8iKTsKKworICAgIC8vIEJ1aWxkIHRoZSBkZXNjcmlwdG9ycyBhbmQgZ2V0IHRoZSBwb2ludGVycy4KKyAgICBmb29fZmlsZV8gPSBwb29sXy5CdWlsZEZpbGUoZm9vX2ZpbGUpOworICAgIEFTU0VSVF9UUlVFKGZvb19maWxlXyAhPSBOVUxMKTsKKworICAgIGJhcl9maWxlXyA9IHBvb2xfLkJ1aWxkRmlsZShiYXJfZmlsZSk7CisgICAgQVNTRVJUX1RSVUUoYmFyX2ZpbGVfICE9IE5VTEwpOworCisgICAgYmF6X2ZpbGVfID0gcG9vbF8uQnVpbGRGaWxlKGJhel9maWxlKTsKKyAgICBBU1NFUlRfVFJVRShiYXpfZmlsZV8gIT0gTlVMTCk7CisKKyAgICBBU1NFUlRfRVEoMSwgZm9vX2ZpbGVfLT5tZXNzYWdlX3R5cGVfY291bnQoKSk7CisgICAgZm9vX21lc3NhZ2VfID0gZm9vX2ZpbGVfLT5tZXNzYWdlX3R5cGUoMCk7CisgICAgQVNTRVJUX0VRKDEsIGZvb19maWxlXy0+ZW51bV90eXBlX2NvdW50KCkpOworICAgIGZvb19lbnVtXyA9IGZvb19maWxlXy0+ZW51bV90eXBlKDApOworICAgIEFTU0VSVF9FUSgxLCBmb29fZW51bV8tPnZhbHVlX2NvdW50KCkpOworICAgIGZvb19lbnVtX3ZhbHVlXyA9IGZvb19lbnVtXy0+dmFsdWUoMCk7CisgICAgQVNTRVJUX0VRKDEsIGZvb19maWxlXy0+c2VydmljZV9jb3VudCgpKTsKKyAgICBmb29fc2VydmljZV8gPSBmb29fZmlsZV8tPnNlcnZpY2UoMCk7CisgICAgQVNTRVJUX0VRKDEsIGZvb19maWxlXy0+ZXh0ZW5zaW9uX2NvdW50KCkpOworICAgIGZvb19leHRlbnNpb25fID0gZm9vX2ZpbGVfLT5leHRlbnNpb24oMCk7CisKKyAgICBBU1NFUlRfRVEoMSwgYmFyX2ZpbGVfLT5tZXNzYWdlX3R5cGVfY291bnQoKSk7CisgICAgYmFyX21lc3NhZ2VfID0gYmFyX2ZpbGVfLT5tZXNzYWdlX3R5cGUoMCk7CisgICAgQVNTRVJUX0VRKDEsIGJhcl9maWxlXy0+ZW51bV90eXBlX2NvdW50KCkpOworICAgIGJhcl9lbnVtXyA9IGJhcl9maWxlXy0+ZW51bV90eXBlKDApOworICAgIEFTU0VSVF9FUSgxLCBiYXJfZW51bV8tPnZhbHVlX2NvdW50KCkpOworICAgIGJhcl9lbnVtX3ZhbHVlXyA9IGJhcl9lbnVtXy0+dmFsdWUoMCk7CisgICAgQVNTRVJUX0VRKDEsIGJhcl9maWxlXy0+c2VydmljZV9jb3VudCgpKTsKKyAgICBiYXJfc2VydmljZV8gPSBiYXJfZmlsZV8tPnNlcnZpY2UoMCk7CisgICAgQVNTRVJUX0VRKDEsIGJhcl9maWxlXy0+ZXh0ZW5zaW9uX2NvdW50KCkpOworICAgIGJhcl9leHRlbnNpb25fID0gYmFyX2ZpbGVfLT5leHRlbnNpb24oMCk7CisgIH0KKworICBEZXNjcmlwdG9yUG9vbCBwb29sXzsKKworICBjb25zdCBGaWxlRGVzY3JpcHRvciogZm9vX2ZpbGVfOworICBjb25zdCBGaWxlRGVzY3JpcHRvciogYmFyX2ZpbGVfOworICBjb25zdCBGaWxlRGVzY3JpcHRvciogYmF6X2ZpbGVfOworCisgIGNvbnN0IERlc2NyaXB0b3IqICAgICAgICAgIGZvb19tZXNzYWdlXzsKKyAgY29uc3QgRW51bURlc2NyaXB0b3IqICAgICAgZm9vX2VudW1fOworICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBmb29fZW51bV92YWx1ZV87CisgIGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yKiAgIGZvb19zZXJ2aWNlXzsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiAgICAgZm9vX2V4dGVuc2lvbl87CisKKyAgY29uc3QgRGVzY3JpcHRvciogICAgICAgICAgYmFyX21lc3NhZ2VfOworICBjb25zdCBFbnVtRGVzY3JpcHRvciogICAgICBiYXJfZW51bV87CisgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIGJhcl9lbnVtX3ZhbHVlXzsKKyAgY29uc3QgU2VydmljZURlc2NyaXB0b3IqICAgYmFyX3NlcnZpY2VfOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqICAgICBiYXJfZXh0ZW5zaW9uXzsKK307CisKK1RFU1RfRihGaWxlRGVzY3JpcHRvclRlc3QsIE5hbWUpIHsKKyAgRVhQRUNUX0VRKCJmb28ucHJvdG8iLCBmb29fZmlsZV8tPm5hbWUoKSk7CisgIEVYUEVDVF9FUSgiYmFyLnByb3RvIiwgYmFyX2ZpbGVfLT5uYW1lKCkpOworICBFWFBFQ1RfRVEoImJhei5wcm90byIsIGJhel9maWxlXy0+bmFtZSgpKTsKK30KKworVEVTVF9GKEZpbGVEZXNjcmlwdG9yVGVzdCwgUGFja2FnZSkgeworICBFWFBFQ1RfRVEoIiIsIGZvb19maWxlXy0+cGFja2FnZSgpKTsKKyAgRVhQRUNUX0VRKCJiYXJfcGFja2FnZSIsIGJhcl9maWxlXy0+cGFja2FnZSgpKTsKK30KKworVEVTVF9GKEZpbGVEZXNjcmlwdG9yVGVzdCwgRGVwZW5kZW5jaWVzKSB7CisgIEVYUEVDVF9FUSgwLCBmb29fZmlsZV8tPmRlcGVuZGVuY3lfY291bnQoKSk7CisgIEVYUEVDVF9FUSgxLCBiYXJfZmlsZV8tPmRlcGVuZGVuY3lfY291bnQoKSk7CisgIEVYUEVDVF9FUShmb29fZmlsZV8sIGJhcl9maWxlXy0+ZGVwZW5kZW5jeSgwKSk7Cit9CisKK1RFU1RfRihGaWxlRGVzY3JpcHRvclRlc3QsIEZpbmRNZXNzYWdlVHlwZUJ5TmFtZSkgeworICBFWFBFQ1RfRVEoZm9vX21lc3NhZ2VfLCBmb29fZmlsZV8tPkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgiRm9vTWVzc2FnZSIpKTsKKyAgRVhQRUNUX0VRKGJhcl9tZXNzYWdlXywgYmFyX2ZpbGVfLT5GaW5kTWVzc2FnZVR5cGVCeU5hbWUoIkJhck1lc3NhZ2UiKSk7CisKKyAgRVhQRUNUX1RSVUUoZm9vX2ZpbGVfLT5GaW5kTWVzc2FnZVR5cGVCeU5hbWUoIkJhck1lc3NhZ2UiKSA9PSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUoYmFyX2ZpbGVfLT5GaW5kTWVzc2FnZVR5cGVCeU5hbWUoIkZvb01lc3NhZ2UiKSA9PSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUoYmF6X2ZpbGVfLT5GaW5kTWVzc2FnZVR5cGVCeU5hbWUoIkZvb01lc3NhZ2UiKSA9PSBOVUxMKTsKKworICBFWFBFQ1RfVFJVRShmb29fZmlsZV8tPkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgiTm9TdWNoTWVzc2FnZSIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShmb29fZmlsZV8tPkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgiRm9vRW51bSIpID09IE5VTEwpOworfQorCitURVNUX0YoRmlsZURlc2NyaXB0b3JUZXN0LCBGaW5kRW51bVR5cGVCeU5hbWUpIHsKKyAgRVhQRUNUX0VRKGZvb19lbnVtXywgZm9vX2ZpbGVfLT5GaW5kRW51bVR5cGVCeU5hbWUoIkZvb0VudW0iKSk7CisgIEVYUEVDVF9FUShiYXJfZW51bV8sIGJhcl9maWxlXy0+RmluZEVudW1UeXBlQnlOYW1lKCJCYXJFbnVtIikpOworCisgIEVYUEVDVF9UUlVFKGZvb19maWxlXy0+RmluZEVudW1UeXBlQnlOYW1lKCJCYXJFbnVtIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKGJhcl9maWxlXy0+RmluZEVudW1UeXBlQnlOYW1lKCJGb29FbnVtIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKGJhel9maWxlXy0+RmluZEVudW1UeXBlQnlOYW1lKCJGb29FbnVtIikgPT0gTlVMTCk7CisKKyAgRVhQRUNUX1RSVUUoZm9vX2ZpbGVfLT5GaW5kRW51bVR5cGVCeU5hbWUoIk5vU3VjaEVudW0iKSA9PSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUoZm9vX2ZpbGVfLT5GaW5kRW51bVR5cGVCeU5hbWUoIkZvb01lc3NhZ2UiKSA9PSBOVUxMKTsKK30KKworVEVTVF9GKEZpbGVEZXNjcmlwdG9yVGVzdCwgRmluZEVudW1WYWx1ZUJ5TmFtZSkgeworICBFWFBFQ1RfRVEoZm9vX2VudW1fdmFsdWVfLCBmb29fZmlsZV8tPkZpbmRFbnVtVmFsdWVCeU5hbWUoIkZPT19FTlVNX1ZBTFVFIikpOworICBFWFBFQ1RfRVEoYmFyX2VudW1fdmFsdWVfLCBiYXJfZmlsZV8tPkZpbmRFbnVtVmFsdWVCeU5hbWUoIkJBUl9FTlVNX1ZBTFVFIikpOworCisgIEVYUEVDVF9UUlVFKGZvb19maWxlXy0+RmluZEVudW1WYWx1ZUJ5TmFtZSgiQkFSX0VOVU1fVkFMVUUiKSA9PSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUoYmFyX2ZpbGVfLT5GaW5kRW51bVZhbHVlQnlOYW1lKCJGT09fRU5VTV9WQUxVRSIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShiYXpfZmlsZV8tPkZpbmRFbnVtVmFsdWVCeU5hbWUoIkZPT19FTlVNX1ZBTFVFIikgPT0gTlVMTCk7CisKKyAgRVhQRUNUX1RSVUUoZm9vX2ZpbGVfLT5GaW5kRW51bVZhbHVlQnlOYW1lKCJOT19TVUNIX1ZBTFVFIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKGZvb19maWxlXy0+RmluZEVudW1WYWx1ZUJ5TmFtZSgiRm9vTWVzc2FnZSIpID09IE5VTEwpOworfQorCitURVNUX0YoRmlsZURlc2NyaXB0b3JUZXN0LCBGaW5kU2VydmljZUJ5TmFtZSkgeworICBFWFBFQ1RfRVEoZm9vX3NlcnZpY2VfLCBmb29fZmlsZV8tPkZpbmRTZXJ2aWNlQnlOYW1lKCJGb29TZXJ2aWNlIikpOworICBFWFBFQ1RfRVEoYmFyX3NlcnZpY2VfLCBiYXJfZmlsZV8tPkZpbmRTZXJ2aWNlQnlOYW1lKCJCYXJTZXJ2aWNlIikpOworCisgIEVYUEVDVF9UUlVFKGZvb19maWxlXy0+RmluZFNlcnZpY2VCeU5hbWUoIkJhclNlcnZpY2UiKSA9PSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUoYmFyX2ZpbGVfLT5GaW5kU2VydmljZUJ5TmFtZSgiRm9vU2VydmljZSIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShiYXpfZmlsZV8tPkZpbmRTZXJ2aWNlQnlOYW1lKCJGb29TZXJ2aWNlIikgPT0gTlVMTCk7CisKKyAgRVhQRUNUX1RSVUUoZm9vX2ZpbGVfLT5GaW5kU2VydmljZUJ5TmFtZSgiTm9TdWNoU2VydmljZSIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShmb29fZmlsZV8tPkZpbmRTZXJ2aWNlQnlOYW1lKCJGb29NZXNzYWdlIikgPT0gTlVMTCk7Cit9CisKK1RFU1RfRihGaWxlRGVzY3JpcHRvclRlc3QsIEZpbmRFeHRlbnNpb25CeU5hbWUpIHsKKyAgRVhQRUNUX0VRKGZvb19leHRlbnNpb25fLCBmb29fZmlsZV8tPkZpbmRFeHRlbnNpb25CeU5hbWUoImZvb19leHRlbnNpb24iKSk7CisgIEVYUEVDVF9FUShiYXJfZXh0ZW5zaW9uXywgYmFyX2ZpbGVfLT5GaW5kRXh0ZW5zaW9uQnlOYW1lKCJiYXJfZXh0ZW5zaW9uIikpOworCisgIEVYUEVDVF9UUlVFKGZvb19maWxlXy0+RmluZEV4dGVuc2lvbkJ5TmFtZSgiYmFyX2V4dGVuc2lvbiIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShiYXJfZmlsZV8tPkZpbmRFeHRlbnNpb25CeU5hbWUoImZvb19leHRlbnNpb24iKSA9PSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUoYmF6X2ZpbGVfLT5GaW5kRXh0ZW5zaW9uQnlOYW1lKCJmb29fZXh0ZW5zaW9uIikgPT0gTlVMTCk7CisKKyAgRVhQRUNUX1RSVUUoZm9vX2ZpbGVfLT5GaW5kRXh0ZW5zaW9uQnlOYW1lKCJub19zdWNoX2V4dGVuc2lvbiIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShmb29fZmlsZV8tPkZpbmRFeHRlbnNpb25CeU5hbWUoIkZvb01lc3NhZ2UiKSA9PSBOVUxMKTsKK30KKworVEVTVF9GKEZpbGVEZXNjcmlwdG9yVGVzdCwgRmluZEV4dGVuc2lvbkJ5TnVtYmVyKSB7CisgIEVYUEVDVF9FUShmb29fZXh0ZW5zaW9uXywgcG9vbF8uRmluZEV4dGVuc2lvbkJ5TnVtYmVyKGZvb19tZXNzYWdlXywgMSkpOworICBFWFBFQ1RfRVEoYmFyX2V4dGVuc2lvbl8sIHBvb2xfLkZpbmRFeHRlbnNpb25CeU51bWJlcihiYXJfbWVzc2FnZV8sIDEpKTsKKworICBFWFBFQ1RfVFJVRShwb29sXy5GaW5kRXh0ZW5zaW9uQnlOdW1iZXIoZm9vX21lc3NhZ2VfLCAyKSA9PSBOVUxMKTsKK30KKworVEVTVF9GKEZpbGVEZXNjcmlwdG9yVGVzdCwgQnVpbGRBZ2FpbikgeworICAvLyBUZXN0IHRoYXQgaWYgdGUgY2FsbCBCdWlsZEZpbGUgYWdhaW4gb24gdGhlIHNhbWUgaW5wdXQgd2UgZ2V0IHRoZSBzYW1lCisgIC8vIEZpbGVEZXNjcmlwdG9yIGJhY2suCisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZTsKKyAgZm9vX2ZpbGVfLT5Db3B5VG8oJmZpbGUpOworICBFWFBFQ1RfRVEoZm9vX2ZpbGVfLCBwb29sXy5CdWlsZEZpbGUoZmlsZSkpOworCisgIC8vIEJ1dCBpZiB3ZSBjaGFuZ2UgdGhlIGZpbGUgdGhlbiBpdCB3b24ndCB3b3JrLgorICBmaWxlLnNldF9wYWNrYWdlKCJzb21lLm90aGVyLnBhY2thZ2UiKTsKKyAgRVhQRUNUX1RSVUUocG9vbF8uQnVpbGRGaWxlKGZpbGUpID09IE5VTEwpOworfQorCitURVNUX0YoRmlsZURlc2NyaXB0b3JUZXN0LCBCdWlsZEFnYWluV2l0aFN5bnRheCkgeworICAvLyBUZXN0IHRoYXQgaWYgdGUgY2FsbCBCdWlsZEZpbGUgYWdhaW4gb24gdGhlIHNhbWUgaW5wdXQgd2UgZ2V0IHRoZSBzYW1lCisgIC8vIEZpbGVEZXNjcmlwdG9yIGJhY2sgZXZlbiBpZiBzeW50YXggcGFyYW0gaXMgc3BlY2lmaWVkLgorICBGaWxlRGVzY3JpcHRvclByb3RvIHByb3RvX3N5bnRheDI7CisgIHByb3RvX3N5bnRheDIuc2V0X25hbWUoImZvb19zeW50YXgyIik7CisgIHByb3RvX3N5bnRheDIuc2V0X3N5bnRheCgicHJvdG8yIik7CisKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIHByb3RvMl9kZXNjcmlwdG9yID0gcG9vbF8uQnVpbGRGaWxlKHByb3RvX3N5bnRheDIpOworICBFWFBFQ1RfVFJVRShwcm90bzJfZGVzY3JpcHRvciAhPSBOVUxMKTsKKyAgRVhQRUNUX0VRKHByb3RvMl9kZXNjcmlwdG9yLCBwb29sXy5CdWlsZEZpbGUocHJvdG9fc3ludGF4MikpOworCisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gaW1wbGljaXRfcHJvdG8yOworICBpbXBsaWNpdF9wcm90bzIuc2V0X25hbWUoImZvb19pbXBsaWNpdF9zeW50YXgyIik7CisKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGltcGxpY2l0X3Byb3RvMl9kZXNjcmlwdG9yID0KKyAgICAgIHBvb2xfLkJ1aWxkRmlsZShpbXBsaWNpdF9wcm90bzIpOworICBFWFBFQ1RfVFJVRShpbXBsaWNpdF9wcm90bzJfZGVzY3JpcHRvciAhPSBOVUxMKTsKKyAgLy8gV2UgZ2V0IHRoZSBzYW1lIEZpbGVEZXNjcmlwdG9yIGJhY2sgaWYgc3ludGF4IHBhcmFtIGlzIGV4cGxpY2l0bHkKKyAgLy8gc3BlY2lmaWVkLgorICBpbXBsaWNpdF9wcm90bzIuc2V0X3N5bnRheCgicHJvdG8yIik7CisgIEVYUEVDVF9FUShpbXBsaWNpdF9wcm90bzJfZGVzY3JpcHRvciwgcG9vbF8uQnVpbGRGaWxlKGltcGxpY2l0X3Byb3RvMikpOworCisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gcHJvdG9fc3ludGF4MzsKKyAgcHJvdG9fc3ludGF4My5zZXRfbmFtZSgiZm9vX3N5bnRheDMiKTsKKyAgcHJvdG9fc3ludGF4My5zZXRfc3ludGF4KCJwcm90bzMiKTsKKworICBjb25zdCBGaWxlRGVzY3JpcHRvciogcHJvdG8zX2Rlc2NyaXB0b3IgPSBwb29sXy5CdWlsZEZpbGUocHJvdG9fc3ludGF4Myk7CisgIEVYUEVDVF9UUlVFKHByb3RvM19kZXNjcmlwdG9yICE9IE5VTEwpOworICBFWFBFQ1RfRVEocHJvdG8zX2Rlc2NyaXB0b3IsIHBvb2xfLkJ1aWxkRmlsZShwcm90b19zeW50YXgzKSk7Cit9CisKK1RFU1RfRihGaWxlRGVzY3JpcHRvclRlc3QsIFN5bnRheCkgeworICBGaWxlRGVzY3JpcHRvclByb3RvIHByb3RvOworICBwcm90by5zZXRfbmFtZSgiZm9vIik7CisgIC8vIEVuYWJsZSB0aGUgdGVzdCB3aGVuIHdlIGFsc28gcG9wdWxhdGUgdGhlIHN5bnRheCBmb3IgcHJvdG8yLgorI2lmIDAKKyAgeworICAgIHByb3RvLnNldF9zeW50YXgoInByb3RvMiIpOworICAgIERlc2NyaXB0b3JQb29sIHBvb2w7CisgICAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUgPSBwb29sLkJ1aWxkRmlsZShwcm90byk7CisgICAgRVhQRUNUX1RSVUUoZmlsZSAhPSBOVUxMKTsKKyAgICBFWFBFQ1RfRVEoRmlsZURlc2NyaXB0b3I6OlNZTlRBWF9QUk9UTzIsIGZpbGUtPnN5bnRheCgpKTsKKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIG90aGVyOworICAgIGZpbGUtPkNvcHlUbygmb3RoZXIpOworICAgIEVYUEVDVF9FUSgicHJvdG8yIiwgb3RoZXIuc3ludGF4KCkpOworICB9CisjZW5kaWYKKyAgeworICAgIHByb3RvLnNldF9zeW50YXgoInByb3RvMyIpOworICAgIERlc2NyaXB0b3JQb29sIHBvb2w7CisgICAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUgPSBwb29sLkJ1aWxkRmlsZShwcm90byk7CisgICAgRVhQRUNUX1RSVUUoZmlsZSAhPSBOVUxMKTsKKyAgICBFWFBFQ1RfRVEoRmlsZURlc2NyaXB0b3I6OlNZTlRBWF9QUk9UTzMsIGZpbGUtPnN5bnRheCgpKTsKKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIG90aGVyOworICAgIGZpbGUtPkNvcHlUbygmb3RoZXIpOworICAgIEVYUEVDVF9FUSgicHJvdG8zIiwgb3RoZXIuc3ludGF4KCkpOworICB9Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworLy8gVGVzdCBzaW1wbGUgZmxhdCBtZXNzYWdlcyBhbmQgZmllbGRzLgorY2xhc3MgRGVzY3JpcHRvclRlc3QgOiBwdWJsaWMgdGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICB2aXJ0dWFsIHZvaWQgU2V0VXAoKSB7CisgICAgLy8gQnVpbGQgZGVzY3JpcHRvcnMgZm9yIHRoZSBmb2xsb3dpbmcgZGVmaW5pdGlvbnM6CisgICAgLy8KKyAgICAvLyAgIC8vIGluICJmb28ucHJvdG8iCisgICAgLy8gICBtZXNzYWdlIFRlc3RGb3JlaWduIHt9CisgICAgLy8gICBlbnVtIFRlc3RFbnVtIHt9CisgICAgLy8KKyAgICAvLyAgIG1lc3NhZ2UgVGVzdE1lc3NhZ2UgeworICAgIC8vICAgICByZXF1aXJlZCBzdHJpbmcgICAgICBmb28gPSAxOworICAgIC8vICAgICBvcHRpb25hbCBUZXN0RW51bSAgICBiYXIgPSA2OworICAgIC8vICAgICByZXBlYXRlZCBUZXN0Rm9yZWlnbiBiYXogPSA1MDAwMDAwMDA7CisgICAgLy8gICAgIG9wdGlvbmFsIGdyb3VwICAgICAgIHF1eCA9IDE1IHt9CisgICAgLy8gICB9CisgICAgLy8KKyAgICAvLyAgIC8vIGluICJiYXIucHJvdG8iCisgICAgLy8gICBwYWNrYWdlIGNvcmdlLmdyYXVsdDsKKyAgICAvLyAgIG1lc3NhZ2UgVGVzdE1lc3NhZ2UyIHsKKyAgICAvLyAgICAgcmVxdWlyZWQgc3RyaW5nIGZvbyA9IDE7CisgICAgLy8gICAgIHJlcXVpcmVkIHN0cmluZyBiYXIgPSAyOworICAgIC8vICAgICByZXF1aXJlZCBzdHJpbmcgcXV1eCA9IDY7CisgICAgLy8gICB9CisgICAgLy8KKyAgICAvLyAgIC8vIGluICJtYXAucHJvdG8iCisgICAgLy8gICBtZXNzYWdlIFRlc3RNZXNzYWdlMyB7CisgICAgLy8gICAgIG1hcDxpbnQzMiwgaW50MzI+IG1hcF9pbnQzMl9pbnQzMiA9IDE7CisgICAgLy8gICB9CisgICAgLy8KKyAgICAvLyAgIC8vIGluICJqc29uLnByb3RvIgorICAgIC8vICAgbWVzc2FnZSBUZXN0TWVzc2FnZTQgeworICAgIC8vICAgICBvcHRpb25hbCBpbnQzMiBmaWVsZF9uYW1lMSA9IDE7CisgICAgLy8gICAgIG9wdGlvbmFsIGludDMyIGZpZWxkTmFtZTIgPSAyOworICAgIC8vICAgICBvcHRpb25hbCBpbnQzMiBGaWVsZE5hbWUzID0gMzsKKyAgICAvLyAgICAgb3B0aW9uYWwgaW50MzIgX2ZpZWxkX25hbWU0ID0gNDsKKyAgICAvLyAgICAgb3B0aW9uYWwgaW50MzIgRklFTERfTkFNRTUgPSA1OworICAgIC8vICAgICBvcHRpb25hbCBpbnQzMiBmaWVsZF9uYW1lNiA9IDYgW2pzb25fbmFtZSA9ICJAdHlwZSJdOworICAgIC8vICAgfQorICAgIC8vCisgICAgLy8gV2UgY2hlYXQgYW5kIHVzZSBUZXN0Rm9yZWlnbiBhcyB0aGUgdHlwZSBmb3IgcXV4IHJhdGhlciB0aGFuIGNyZWF0ZQorICAgIC8vIGFuIGFjdHVhbCBuZXN0ZWQgdHlwZS4KKyAgICAvLworICAgIC8vIFNpbmNlIGFsbCBwcmltaXRpdmUgdHlwZXMgKGluY2x1ZGluZyBzdHJpbmcpIHVzZSB0aGUgc2FtZSBidWlsZGluZworICAgIC8vIGNvZGUsIHRoZXJlJ3Mgbm8gbmVlZCB0byB0ZXN0IGVhY2ggb25lIGluZGl2aWR1YWxseS4KKyAgICAvLworICAgIC8vIFRlc3RNZXNzYWdlMiBpcyBwcmltYXJpbHkgaGVyZSB0byB0ZXN0IEZpbmRGaWVsZEJ5TmFtZSBhbmQgZnJpZW5kcy4KKyAgICAvLyBBbGwgbWVzc2FnZXMgY3JlYXRlZCBmcm9tIHRoZSBzYW1lIERlc2NyaXB0b3JQb29sIHNoYXJlIHRoZSBzYW1lIGxvb2t1cAorICAgIC8vIHRhYmxlLCBzbyB3ZSBuZWVkIHRvIGluc3VyZSB0aGF0IHRoZXkgZG9uJ3QgaW50ZXJmZXJlLgorCisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmb29fZmlsZTsKKyAgICBmb29fZmlsZS5zZXRfbmFtZSgiZm9vLnByb3RvIik7CisgICAgQWRkTWVzc2FnZSgmZm9vX2ZpbGUsICJUZXN0Rm9yZWlnbiIpOworICAgIEFkZEVtcHR5RW51bSgmZm9vX2ZpbGUsICJUZXN0RW51bSIpOworCisgICAgRGVzY3JpcHRvclByb3RvKiBtZXNzYWdlID0gQWRkTWVzc2FnZSgmZm9vX2ZpbGUsICJUZXN0TWVzc2FnZSIpOworICAgIEFkZEZpZWxkKG1lc3NhZ2UsICJmb28iLCAxLAorICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpMQUJFTF9SRVFVSVJFRCwKKyAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9TVFJJTkcpOworICAgIEFkZEZpZWxkKG1lc3NhZ2UsICJiYXIiLCA2LAorICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpMQUJFTF9PUFRJT05BTCwKKyAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9FTlVNKQorICAgICAgLT5zZXRfdHlwZV9uYW1lKCJUZXN0RW51bSIpOworICAgIEFkZEZpZWxkKG1lc3NhZ2UsICJiYXoiLCA1MDAwMDAwMDAsCisgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX1JFUEVBVEVELAorICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX01FU1NBR0UpCisgICAgICAtPnNldF90eXBlX25hbWUoIlRlc3RGb3JlaWduIik7CisgICAgQWRkRmllbGQobWVzc2FnZSwgInF1eCIsIDE1LAorICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpMQUJFTF9PUFRJT05BTCwKKyAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9HUk9VUCkKKyAgICAgIC0+c2V0X3R5cGVfbmFtZSgiVGVzdEZvcmVpZ24iKTsKKworICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gYmFyX2ZpbGU7CisgICAgYmFyX2ZpbGUuc2V0X25hbWUoImJhci5wcm90byIpOworICAgIGJhcl9maWxlLnNldF9wYWNrYWdlKCJjb3JnZS5ncmF1bHQiKTsKKworICAgIERlc2NyaXB0b3JQcm90byogbWVzc2FnZTIgPSBBZGRNZXNzYWdlKCZiYXJfZmlsZSwgIlRlc3RNZXNzYWdlMiIpOworICAgIEFkZEZpZWxkKG1lc3NhZ2UyLCAiZm9vIiwgMSwKKyAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfUkVRVUlSRUQsCisgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfU1RSSU5HKTsKKyAgICBBZGRGaWVsZChtZXNzYWdlMiwgImJhciIsIDIsCisgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX1JFUVVJUkVELAorICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX1NUUklORyk7CisgICAgQWRkRmllbGQobWVzc2FnZTIsICJxdXV4IiwgNiwKKyAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfUkVRVUlSRUQsCisgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfU1RSSU5HKTsKKworICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gbWFwX2ZpbGU7CisgICAgbWFwX2ZpbGUuc2V0X25hbWUoIm1hcC5wcm90byIpOworICAgIERlc2NyaXB0b3JQcm90byogbWVzc2FnZTMgPSBBZGRNZXNzYWdlKCZtYXBfZmlsZSwgIlRlc3RNZXNzYWdlMyIpOworCisgICAgRGVzY3JpcHRvclByb3RvKiBlbnRyeSA9IEFkZE5lc3RlZE1lc3NhZ2UobWVzc2FnZTMsICJNYXBJbnQzMkludDMyRW50cnkiKTsKKyAgICBBZGRGaWVsZChlbnRyeSwgImtleSIsIDEsCisgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX09QVElPTkFMLAorICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0lOVDMyKTsKKyAgICBBZGRGaWVsZChlbnRyeSwgInZhbHVlIiwgMiwKKyAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfT1BUSU9OQUwsCisgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfSU5UMzIpOworICAgIGVudHJ5LT5tdXRhYmxlX29wdGlvbnMoKS0+c2V0X21hcF9lbnRyeSh0cnVlKTsKKworICAgIEFkZEZpZWxkKG1lc3NhZ2UzLCAibWFwX2ludDMyX2ludDMyIiwgMSwKKyAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfUkVQRUFURUQsCisgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfTUVTU0FHRSkKKyAgICAgICAgLT5zZXRfdHlwZV9uYW1lKCJNYXBJbnQzMkludDMyRW50cnkiKTsKKworICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8ganNvbl9maWxlOworICAgIGpzb25fZmlsZS5zZXRfbmFtZSgianNvbi5wcm90byIpOworICAgIGpzb25fZmlsZS5zZXRfc3ludGF4KCJwcm90bzMiKTsKKyAgICBEZXNjcmlwdG9yUHJvdG8qIG1lc3NhZ2U0ID0gQWRkTWVzc2FnZSgmanNvbl9maWxlLCAiVGVzdE1lc3NhZ2U0Iik7CisgICAgQWRkRmllbGQobWVzc2FnZTQsICJmaWVsZF9uYW1lMSIsIDEsCisgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX09QVElPTkFMLAorICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0lOVDMyKTsKKyAgICBBZGRGaWVsZChtZXNzYWdlNCwgImZpZWxkTmFtZTIiLCAyLAorICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpMQUJFTF9PUFRJT05BTCwKKyAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9JTlQzMik7CisgICAgQWRkRmllbGQobWVzc2FnZTQsICJGaWVsZE5hbWUzIiwgMywKKyAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfT1BUSU9OQUwsCisgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfSU5UMzIpOworICAgIEFkZEZpZWxkKG1lc3NhZ2U0LCAiX2ZpZWxkX25hbWU0IiwgNCwKKyAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfT1BUSU9OQUwsCisgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfSU5UMzIpOworICAgIEFkZEZpZWxkKG1lc3NhZ2U0LCAiRklFTERfTkFNRTUiLCA1LAorICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpMQUJFTF9PUFRJT05BTCwKKyAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9JTlQzMik7CisgICAgQWRkRmllbGQobWVzc2FnZTQsICJmaWVsZF9uYW1lNiIsIDYsCisgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX09QVElPTkFMLAorICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0lOVDMyKQorICAgICAgICAtPnNldF9qc29uX25hbWUoIkB0eXBlIik7CisKKyAgICAvLyBCdWlsZCB0aGUgZGVzY3JpcHRvcnMgYW5kIGdldCB0aGUgcG9pbnRlcnMuCisgICAgZm9vX2ZpbGVfID0gcG9vbF8uQnVpbGRGaWxlKGZvb19maWxlKTsKKyAgICBBU1NFUlRfVFJVRShmb29fZmlsZV8gIT0gTlVMTCk7CisKKyAgICBiYXJfZmlsZV8gPSBwb29sXy5CdWlsZEZpbGUoYmFyX2ZpbGUpOworICAgIEFTU0VSVF9UUlVFKGJhcl9maWxlXyAhPSBOVUxMKTsKKworICAgIG1hcF9maWxlXyA9IHBvb2xfLkJ1aWxkRmlsZShtYXBfZmlsZSk7CisgICAgQVNTRVJUX1RSVUUobWFwX2ZpbGVfICE9IE5VTEwpOworCisgICAganNvbl9maWxlXyA9IHBvb2xfLkJ1aWxkRmlsZShqc29uX2ZpbGUpOworICAgIEFTU0VSVF9UUlVFKGpzb25fZmlsZV8gIT0gTlVMTCk7CisKKyAgICBBU1NFUlRfRVEoMSwgZm9vX2ZpbGVfLT5lbnVtX3R5cGVfY291bnQoKSk7CisgICAgZW51bV8gPSBmb29fZmlsZV8tPmVudW1fdHlwZSgwKTsKKworICAgIEFTU0VSVF9FUSgyLCBmb29fZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpKTsKKyAgICBmb3JlaWduXyA9IGZvb19maWxlXy0+bWVzc2FnZV90eXBlKDApOworICAgIG1lc3NhZ2VfID0gZm9vX2ZpbGVfLT5tZXNzYWdlX3R5cGUoMSk7CisKKyAgICBBU1NFUlRfRVEoNCwgbWVzc2FnZV8tPmZpZWxkX2NvdW50KCkpOworICAgIGZvb18gPSBtZXNzYWdlXy0+ZmllbGQoMCk7CisgICAgYmFyXyA9IG1lc3NhZ2VfLT5maWVsZCgxKTsKKyAgICBiYXpfID0gbWVzc2FnZV8tPmZpZWxkKDIpOworICAgIHF1eF8gPSBtZXNzYWdlXy0+ZmllbGQoMyk7CisKKyAgICBBU1NFUlRfRVEoMSwgYmFyX2ZpbGVfLT5tZXNzYWdlX3R5cGVfY291bnQoKSk7CisgICAgbWVzc2FnZTJfID0gYmFyX2ZpbGVfLT5tZXNzYWdlX3R5cGUoMCk7CisKKyAgICBBU1NFUlRfRVEoMywgbWVzc2FnZTJfLT5maWVsZF9jb3VudCgpKTsKKyAgICBmb28yXyAgPSBtZXNzYWdlMl8tPmZpZWxkKDApOworICAgIGJhcjJfICA9IG1lc3NhZ2UyXy0+ZmllbGQoMSk7CisgICAgcXV1eDJfID0gbWVzc2FnZTJfLT5maWVsZCgyKTsKKworICAgIEFTU0VSVF9FUSgxLCBtYXBfZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpKTsKKyAgICBtZXNzYWdlM18gPSBtYXBfZmlsZV8tPm1lc3NhZ2VfdHlwZSgwKTsKKworICAgIEFTU0VSVF9FUSgxLCBtZXNzYWdlM18tPmZpZWxkX2NvdW50KCkpOworICAgIG1hcF8gID0gbWVzc2FnZTNfLT5maWVsZCgwKTsKKworICAgIEFTU0VSVF9FUSgxLCBqc29uX2ZpbGVfLT5tZXNzYWdlX3R5cGVfY291bnQoKSk7CisgICAgbWVzc2FnZTRfID0ganNvbl9maWxlXy0+bWVzc2FnZV90eXBlKDApOworICB9CisKKyAgdm9pZCBDb3B5V2l0aEpzb25OYW1lKGNvbnN0IERlc2NyaXB0b3IqIG1lc3NhZ2UsIERlc2NyaXB0b3JQcm90byogcHJvdG8pIHsKKyAgICBtZXNzYWdlLT5Db3B5VG8ocHJvdG8pOworICAgIG1lc3NhZ2UtPkNvcHlKc29uTmFtZVRvKHByb3RvKTsKKyAgfQorCisgIERlc2NyaXB0b3JQb29sIHBvb2xfOworCisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmb29fZmlsZV87CisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBiYXJfZmlsZV87CisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBtYXBfZmlsZV87CisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBqc29uX2ZpbGVfOworCisgIGNvbnN0IERlc2NyaXB0b3IqIG1lc3NhZ2VfOworICBjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlMl87CisgIGNvbnN0IERlc2NyaXB0b3IqIG1lc3NhZ2UzXzsKKyAgY29uc3QgRGVzY3JpcHRvciogbWVzc2FnZTRfOworICBjb25zdCBEZXNjcmlwdG9yKiBmb3JlaWduXzsKKyAgY29uc3QgRW51bURlc2NyaXB0b3IqIGVudW1fOworCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZm9vXzsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBiYXJfOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGJhel87CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogcXV4XzsKKworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZvbzJfOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGJhcjJfOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHF1dXgyXzsKKworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIG1hcF87Cit9OworCitURVNUX0YoRGVzY3JpcHRvclRlc3QsIE5hbWUpIHsKKyAgRVhQRUNUX0VRKCJUZXN0TWVzc2FnZSIsIG1lc3NhZ2VfLT5uYW1lKCkpOworICBFWFBFQ1RfRVEoIlRlc3RNZXNzYWdlIiwgbWVzc2FnZV8tPmZ1bGxfbmFtZSgpKTsKKyAgRVhQRUNUX0VRKGZvb19maWxlXywgbWVzc2FnZV8tPmZpbGUoKSk7CisKKyAgRVhQRUNUX0VRKCJUZXN0TWVzc2FnZTIiLCBtZXNzYWdlMl8tPm5hbWUoKSk7CisgIEVYUEVDVF9FUSgiY29yZ2UuZ3JhdWx0LlRlc3RNZXNzYWdlMiIsIG1lc3NhZ2UyXy0+ZnVsbF9uYW1lKCkpOworICBFWFBFQ1RfRVEoYmFyX2ZpbGVfLCBtZXNzYWdlMl8tPmZpbGUoKSk7Cit9CisKK1RFU1RfRihEZXNjcmlwdG9yVGVzdCwgQ29udGFpbmluZ1R5cGUpIHsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZV8tPmNvbnRhaW5pbmdfdHlwZSgpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlMl8tPmNvbnRhaW5pbmdfdHlwZSgpID09IE5VTEwpOworfQorCitURVNUX0YoRGVzY3JpcHRvclRlc3QsIEZpZWxkc0J5SW5kZXgpIHsKKyAgQVNTRVJUX0VRKDQsIG1lc3NhZ2VfLT5maWVsZF9jb3VudCgpKTsKKyAgRVhQRUNUX0VRKGZvb18sIG1lc3NhZ2VfLT5maWVsZCgwKSk7CisgIEVYUEVDVF9FUShiYXJfLCBtZXNzYWdlXy0+ZmllbGQoMSkpOworICBFWFBFQ1RfRVEoYmF6XywgbWVzc2FnZV8tPmZpZWxkKDIpKTsKKyAgRVhQRUNUX0VRKHF1eF8sIG1lc3NhZ2VfLT5maWVsZCgzKSk7Cit9CisKK1RFU1RfRihEZXNjcmlwdG9yVGVzdCwgRmluZEZpZWxkQnlOYW1lKSB7CisgIC8vIEFsbCBtZXNzYWdlcyBpbiB0aGUgc2FtZSBEZXNjcmlwdG9yUG9vbCBzaGFyZSBhIHNpbmdsZSBsb29rdXAgdGFibGUgZm9yCisgIC8vIGZpZWxkcy4gIFNvLCBpbiBhZGRpdGlvbiB0byB0ZXN0aW5nIHRoYXQgRmluZEZpZWxkQnlOYW1lIGZpbmRzIHRoZSBmaWVsZHMKKyAgLy8gb2YgdGhlIG1lc3NhZ2UsIHdlIG5lZWQgdG8gdGVzdCB0aGF0IGl0IGRvZXMgKm5vdCogZmluZCB0aGUgZmllbGRzIG9mCisgIC8vICpvdGhlciogbWVzc2FnZXMuCisKKyAgRVhQRUNUX0VRKGZvb18sIG1lc3NhZ2VfLT5GaW5kRmllbGRCeU5hbWUoImZvbyIpKTsKKyAgRVhQRUNUX0VRKGJhcl8sIG1lc3NhZ2VfLT5GaW5kRmllbGRCeU5hbWUoImJhciIpKTsKKyAgRVhQRUNUX0VRKGJhel8sIG1lc3NhZ2VfLT5GaW5kRmllbGRCeU5hbWUoImJheiIpKTsKKyAgRVhQRUNUX0VRKHF1eF8sIG1lc3NhZ2VfLT5GaW5kRmllbGRCeU5hbWUoInF1eCIpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZV8tPkZpbmRGaWVsZEJ5TmFtZSgibm9fc3VjaF9maWVsZCIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlXy0+RmluZEZpZWxkQnlOYW1lKCJxdXV4IikgPT0gTlVMTCk7CisKKyAgRVhQRUNUX0VRKGZvbzJfICwgbWVzc2FnZTJfLT5GaW5kRmllbGRCeU5hbWUoImZvbyIgKSk7CisgIEVYUEVDVF9FUShiYXIyXyAsIG1lc3NhZ2UyXy0+RmluZEZpZWxkQnlOYW1lKCJiYXIiICkpOworICBFWFBFQ1RfRVEocXV1eDJfLCBtZXNzYWdlMl8tPkZpbmRGaWVsZEJ5TmFtZSgicXV1eCIpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZTJfLT5GaW5kRmllbGRCeU5hbWUoImJheiIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlMl8tPkZpbmRGaWVsZEJ5TmFtZSgicXV4IikgPT0gTlVMTCk7Cit9CisKK1RFU1RfRihEZXNjcmlwdG9yVGVzdCwgRmluZEZpZWxkQnlOdW1iZXIpIHsKKyAgRVhQRUNUX0VRKGZvb18sIG1lc3NhZ2VfLT5GaW5kRmllbGRCeU51bWJlcigxKSk7CisgIEVYUEVDVF9FUShiYXJfLCBtZXNzYWdlXy0+RmluZEZpZWxkQnlOdW1iZXIoNikpOworICBFWFBFQ1RfRVEoYmF6XywgbWVzc2FnZV8tPkZpbmRGaWVsZEJ5TnVtYmVyKDUwMDAwMDAwMCkpOworICBFWFBFQ1RfRVEocXV4XywgbWVzc2FnZV8tPkZpbmRGaWVsZEJ5TnVtYmVyKDE1KSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2VfLT5GaW5kRmllbGRCeU51bWJlcig4Mzc1OTIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlXy0+RmluZEZpZWxkQnlOdW1iZXIoMikgPT0gTlVMTCk7CisKKyAgRVhQRUNUX0VRKGZvbzJfICwgbWVzc2FnZTJfLT5GaW5kRmllbGRCeU51bWJlcigxKSk7CisgIEVYUEVDVF9FUShiYXIyXyAsIG1lc3NhZ2UyXy0+RmluZEZpZWxkQnlOdW1iZXIoMikpOworICBFWFBFQ1RfRVEocXV1eDJfLCBtZXNzYWdlMl8tPkZpbmRGaWVsZEJ5TnVtYmVyKDYpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZTJfLT5GaW5kRmllbGRCeU51bWJlcigxNSkgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UyXy0+RmluZEZpZWxkQnlOdW1iZXIoNTAwMDAwMDAwKSA9PSBOVUxMKTsKK30KKworVEVTVF9GKERlc2NyaXB0b3JUZXN0LCBGaWVsZE5hbWUpIHsKKyAgRVhQRUNUX0VRKCJmb28iLCBmb29fLT5uYW1lKCkpOworICBFWFBFQ1RfRVEoImJhciIsIGJhcl8tPm5hbWUoKSk7CisgIEVYUEVDVF9FUSgiYmF6IiwgYmF6Xy0+bmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJxdXgiLCBxdXhfLT5uYW1lKCkpOworfQorCitURVNUX0YoRGVzY3JpcHRvclRlc3QsIEZpZWxkRnVsbE5hbWUpIHsKKyAgRVhQRUNUX0VRKCJUZXN0TWVzc2FnZS5mb28iLCBmb29fLT5mdWxsX25hbWUoKSk7CisgIEVYUEVDVF9FUSgiVGVzdE1lc3NhZ2UuYmFyIiwgYmFyXy0+ZnVsbF9uYW1lKCkpOworICBFWFBFQ1RfRVEoIlRlc3RNZXNzYWdlLmJheiIsIGJhel8tPmZ1bGxfbmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJUZXN0TWVzc2FnZS5xdXgiLCBxdXhfLT5mdWxsX25hbWUoKSk7CisKKyAgRVhQRUNUX0VRKCJjb3JnZS5ncmF1bHQuVGVzdE1lc3NhZ2UyLmZvbyIsIGZvbzJfLT5mdWxsX25hbWUoKSk7CisgIEVYUEVDVF9FUSgiY29yZ2UuZ3JhdWx0LlRlc3RNZXNzYWdlMi5iYXIiLCBiYXIyXy0+ZnVsbF9uYW1lKCkpOworICBFWFBFQ1RfRVEoImNvcmdlLmdyYXVsdC5UZXN0TWVzc2FnZTIucXV1eCIsIHF1dXgyXy0+ZnVsbF9uYW1lKCkpOworfQorCitURVNUX0YoRGVzY3JpcHRvclRlc3QsIEZpZWxkSnNvbk5hbWUpIHsKKyAgRVhQRUNUX0VRKCJmaWVsZE5hbWUxIiwgbWVzc2FnZTRfLT5maWVsZCgwKS0+anNvbl9uYW1lKCkpOworICBFWFBFQ1RfRVEoImZpZWxkTmFtZTIiLCBtZXNzYWdlNF8tPmZpZWxkKDEpLT5qc29uX25hbWUoKSk7CisgIEVYUEVDVF9FUSgiZmllbGROYW1lMyIsIG1lc3NhZ2U0Xy0+ZmllbGQoMiktPmpzb25fbmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJmaWVsZE5hbWU0IiwgbWVzc2FnZTRfLT5maWVsZCgzKS0+anNvbl9uYW1lKCkpOworICBFWFBFQ1RfRVEoImZJRUxETkFNRTUiLCBtZXNzYWdlNF8tPmZpZWxkKDQpLT5qc29uX25hbWUoKSk7CisgIEVYUEVDVF9FUSgiQHR5cGUiLCBtZXNzYWdlNF8tPmZpZWxkKDUpLT5qc29uX25hbWUoKSk7CisKKyAgRGVzY3JpcHRvclByb3RvIHByb3RvOworICBtZXNzYWdlNF8tPkNvcHlUbygmcHJvdG8pOworICBBU1NFUlRfRVEoNiwgcHJvdG8uZmllbGRfc2l6ZSgpKTsKKyAgRVhQRUNUX0ZBTFNFKHByb3RvLmZpZWxkKDApLmhhc19qc29uX25hbWUoKSk7CisgIEVYUEVDVF9GQUxTRShwcm90by5maWVsZCgxKS5oYXNfanNvbl9uYW1lKCkpOworICBFWFBFQ1RfRkFMU0UocHJvdG8uZmllbGQoMikuaGFzX2pzb25fbmFtZSgpKTsKKyAgRVhQRUNUX0ZBTFNFKHByb3RvLmZpZWxkKDMpLmhhc19qc29uX25hbWUoKSk7CisgIEVYUEVDVF9GQUxTRShwcm90by5maWVsZCg0KS5oYXNfanNvbl9uYW1lKCkpOworICBFWFBFQ1RfRVEoIkB0eXBlIiwgcHJvdG8uZmllbGQoNSkuanNvbl9uYW1lKCkpOworCisgIHByb3RvLkNsZWFyKCk7CisgIENvcHlXaXRoSnNvbk5hbWUobWVzc2FnZTRfLCAmcHJvdG8pOworICBBU1NFUlRfRVEoNiwgcHJvdG8uZmllbGRfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKCJmaWVsZE5hbWUxIiwgcHJvdG8uZmllbGQoMCkuanNvbl9uYW1lKCkpOworICBFWFBFQ1RfRVEoImZpZWxkTmFtZTIiLCBwcm90by5maWVsZCgxKS5qc29uX25hbWUoKSk7CisgIEVYUEVDVF9FUSgiZmllbGROYW1lMyIsIHByb3RvLmZpZWxkKDIpLmpzb25fbmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJmaWVsZE5hbWU0IiwgcHJvdG8uZmllbGQoMykuanNvbl9uYW1lKCkpOworICBFWFBFQ1RfRVEoImZJRUxETkFNRTUiLCBwcm90by5maWVsZCg0KS5qc29uX25hbWUoKSk7CisgIEVYUEVDVF9FUSgiQHR5cGUiLCBwcm90by5maWVsZCg1KS5qc29uX25hbWUoKSk7Cit9CisKK1RFU1RfRihEZXNjcmlwdG9yVGVzdCwgRmllbGRGaWxlKSB7CisgIEVYUEVDVF9FUShmb29fZmlsZV8sIGZvb18tPmZpbGUoKSk7CisgIEVYUEVDVF9FUShmb29fZmlsZV8sIGJhcl8tPmZpbGUoKSk7CisgIEVYUEVDVF9FUShmb29fZmlsZV8sIGJhel8tPmZpbGUoKSk7CisgIEVYUEVDVF9FUShmb29fZmlsZV8sIHF1eF8tPmZpbGUoKSk7CisKKyAgRVhQRUNUX0VRKGJhcl9maWxlXywgZm9vMl8tPmZpbGUoKSk7CisgIEVYUEVDVF9FUShiYXJfZmlsZV8sIGJhcjJfLT5maWxlKCkpOworICBFWFBFQ1RfRVEoYmFyX2ZpbGVfLCBxdXV4Ml8tPmZpbGUoKSk7Cit9CisKK1RFU1RfRihEZXNjcmlwdG9yVGVzdCwgRmllbGRJbmRleCkgeworICBFWFBFQ1RfRVEoMCwgZm9vXy0+aW5kZXgoKSk7CisgIEVYUEVDVF9FUSgxLCBiYXJfLT5pbmRleCgpKTsKKyAgRVhQRUNUX0VRKDIsIGJhel8tPmluZGV4KCkpOworICBFWFBFQ1RfRVEoMywgcXV4Xy0+aW5kZXgoKSk7Cit9CisKK1RFU1RfRihEZXNjcmlwdG9yVGVzdCwgRmllbGROdW1iZXIpIHsKKyAgRVhQRUNUX0VRKCAgICAgICAgMSwgZm9vXy0+bnVtYmVyKCkpOworICBFWFBFQ1RfRVEoICAgICAgICA2LCBiYXJfLT5udW1iZXIoKSk7CisgIEVYUEVDVF9FUSg1MDAwMDAwMDAsIGJhel8tPm51bWJlcigpKTsKKyAgRVhQRUNUX0VRKCAgICAgICAxNSwgcXV4Xy0+bnVtYmVyKCkpOworfQorCitURVNUX0YoRGVzY3JpcHRvclRlc3QsIEZpZWxkVHlwZSkgeworICBFWFBFQ1RfRVEoRmllbGREZXNjcmlwdG9yOjpUWVBFX1NUUklORyAsIGZvb18tPnR5cGUoKSk7CisgIEVYUEVDVF9FUShGaWVsZERlc2NyaXB0b3I6OlRZUEVfRU5VTSAgICwgYmFyXy0+dHlwZSgpKTsKKyAgRVhQRUNUX0VRKEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9NRVNTQUdFLCBiYXpfLT50eXBlKCkpOworICBFWFBFQ1RfRVEoRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQICAsIHF1eF8tPnR5cGUoKSk7Cit9CisKK1RFU1RfRihEZXNjcmlwdG9yVGVzdCwgRmllbGRMYWJlbCkgeworICBFWFBFQ1RfRVEoRmllbGREZXNjcmlwdG9yOjpMQUJFTF9SRVFVSVJFRCwgZm9vXy0+bGFiZWwoKSk7CisgIEVYUEVDVF9FUShGaWVsZERlc2NyaXB0b3I6OkxBQkVMX09QVElPTkFMLCBiYXJfLT5sYWJlbCgpKTsKKyAgRVhQRUNUX0VRKEZpZWxkRGVzY3JpcHRvcjo6TEFCRUxfUkVQRUFURUQsIGJhel8tPmxhYmVsKCkpOworICBFWFBFQ1RfRVEoRmllbGREZXNjcmlwdG9yOjpMQUJFTF9PUFRJT05BTCwgcXV4Xy0+bGFiZWwoKSk7CisKKyAgRVhQRUNUX1RSVUUgKGZvb18tPmlzX3JlcXVpcmVkKCkpOworICBFWFBFQ1RfRkFMU0UoZm9vXy0+aXNfb3B0aW9uYWwoKSk7CisgIEVYUEVDVF9GQUxTRShmb29fLT5pc19yZXBlYXRlZCgpKTsKKworICBFWFBFQ1RfRkFMU0UoYmFyXy0+aXNfcmVxdWlyZWQoKSk7CisgIEVYUEVDVF9UUlVFIChiYXJfLT5pc19vcHRpb25hbCgpKTsKKyAgRVhQRUNUX0ZBTFNFKGJhcl8tPmlzX3JlcGVhdGVkKCkpOworCisgIEVYUEVDVF9GQUxTRShiYXpfLT5pc19yZXF1aXJlZCgpKTsKKyAgRVhQRUNUX0ZBTFNFKGJhel8tPmlzX29wdGlvbmFsKCkpOworICBFWFBFQ1RfVFJVRSAoYmF6Xy0+aXNfcmVwZWF0ZWQoKSk7Cit9CisKK1RFU1RfRihEZXNjcmlwdG9yVGVzdCwgSXNNYXApIHsKKyAgRVhQRUNUX1RSVUUobWFwXy0+aXNfbWFwKCkpOworICBFWFBFQ1RfRkFMU0UoYmF6Xy0+aXNfbWFwKCkpOworICBFWFBFQ1RfVFJVRShtYXBfLT5tZXNzYWdlX3R5cGUoKS0+b3B0aW9ucygpLm1hcF9lbnRyeSgpKTsKK30KKworVEVTVF9GKERlc2NyaXB0b3JUZXN0LCBGaWVsZEhhc0RlZmF1bHQpIHsKKyAgRVhQRUNUX0ZBTFNFKGZvb18tPmhhc19kZWZhdWx0X3ZhbHVlKCkpOworICBFWFBFQ1RfRkFMU0UoYmFyXy0+aGFzX2RlZmF1bHRfdmFsdWUoKSk7CisgIEVYUEVDVF9GQUxTRShiYXpfLT5oYXNfZGVmYXVsdF92YWx1ZSgpKTsKKyAgRVhQRUNUX0ZBTFNFKHF1eF8tPmhhc19kZWZhdWx0X3ZhbHVlKCkpOworfQorCitURVNUX0YoRGVzY3JpcHRvclRlc3QsIEZpZWxkQ29udGFpbmluZ1R5cGUpIHsKKyAgRVhQRUNUX0VRKG1lc3NhZ2VfLCBmb29fLT5jb250YWluaW5nX3R5cGUoKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlXywgYmFyXy0+Y29udGFpbmluZ190eXBlKCkpOworICBFWFBFQ1RfRVEobWVzc2FnZV8sIGJhel8tPmNvbnRhaW5pbmdfdHlwZSgpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2VfLCBxdXhfLT5jb250YWluaW5nX3R5cGUoKSk7CisKKyAgRVhQRUNUX0VRKG1lc3NhZ2UyXywgZm9vMl8gLT5jb250YWluaW5nX3R5cGUoKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlMl8sIGJhcjJfIC0+Y29udGFpbmluZ190eXBlKCkpOworICBFWFBFQ1RfRVEobWVzc2FnZTJfLCBxdXV4Ml8tPmNvbnRhaW5pbmdfdHlwZSgpKTsKK30KKworVEVTVF9GKERlc2NyaXB0b3JUZXN0LCBGaWVsZE1lc3NhZ2VUeXBlKSB7CisgIEVYUEVDVF9UUlVFKGZvb18tPm1lc3NhZ2VfdHlwZSgpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShiYXJfLT5tZXNzYWdlX3R5cGUoKSA9PSBOVUxMKTsKKworICBFWFBFQ1RfRVEoZm9yZWlnbl8sIGJhel8tPm1lc3NhZ2VfdHlwZSgpKTsKKyAgRVhQRUNUX0VRKGZvcmVpZ25fLCBxdXhfLT5tZXNzYWdlX3R5cGUoKSk7Cit9CisKK1RFU1RfRihEZXNjcmlwdG9yVGVzdCwgRmllbGRFbnVtVHlwZSkgeworICBFWFBFQ1RfVFJVRShmb29fLT5lbnVtX3R5cGUoKSA9PSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUoYmF6Xy0+ZW51bV90eXBlKCkgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKHF1eF8tPmVudW1fdHlwZSgpID09IE5VTEwpOworCisgIEVYUEVDVF9FUShlbnVtXywgYmFyXy0+ZW51bV90eXBlKCkpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKy8vIFRlc3Qgc2ltcGxlIGZsYXQgbWVzc2FnZXMgYW5kIGZpZWxkcy4KK2NsYXNzIE9uZW9mRGVzY3JpcHRvclRlc3QgOiBwdWJsaWMgdGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICB2aXJ0dWFsIHZvaWQgU2V0VXAoKSB7CisgICAgLy8gQnVpbGQgZGVzY3JpcHRvcnMgZm9yIHRoZSBmb2xsb3dpbmcgZGVmaW5pdGlvbnM6CisgICAgLy8KKyAgICAvLyAgIHBhY2thZ2UgZ2FycGx5OworICAgIC8vICAgbWVzc2FnZSBUZXN0T25lb2YgeworICAgIC8vICAgICBvcHRpb25hbCBpbnQzMiBhID0gMTsKKyAgICAvLyAgICAgb25lb2YgZm9vIHsKKyAgICAvLyAgICAgICBzdHJpbmcgYiA9IDI7CisgICAgLy8gICAgICAgVGVzdE9uZW9mIGMgPSAzOworICAgIC8vICAgICB9CisgICAgLy8gICAgIG9uZW9mIGJhciB7CisgICAgLy8gICAgICAgZmxvYXQgZCA9IDQ7CisgICAgLy8gICAgIH0KKyAgICAvLyAgIH0KKworICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gYmF6X2ZpbGU7CisgICAgYmF6X2ZpbGUuc2V0X25hbWUoImJhei5wcm90byIpOworICAgIGJhel9maWxlLnNldF9wYWNrYWdlKCJnYXJwbHkiKTsKKworICAgIERlc2NyaXB0b3JQcm90byogb25lb2ZfbWVzc2FnZSA9IEFkZE1lc3NhZ2UoJmJhel9maWxlLCAiVGVzdE9uZW9mIik7CisgICAgb25lb2ZfbWVzc2FnZS0+YWRkX29uZW9mX2RlY2woKS0+c2V0X25hbWUoImZvbyIpOworICAgIG9uZW9mX21lc3NhZ2UtPmFkZF9vbmVvZl9kZWNsKCktPnNldF9uYW1lKCJiYXIiKTsKKworICAgIEFkZEZpZWxkKG9uZW9mX21lc3NhZ2UsICJhIiwgMSwKKyAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfT1BUSU9OQUwsCisgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfSU5UMzIpOworICAgIEFkZEZpZWxkKG9uZW9mX21lc3NhZ2UsICJiIiwgMiwKKyAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfT1BUSU9OQUwsCisgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfU1RSSU5HKTsKKyAgICBvbmVvZl9tZXNzYWdlLT5tdXRhYmxlX2ZpZWxkKDEpLT5zZXRfb25lb2ZfaW5kZXgoMCk7CisgICAgQWRkRmllbGQob25lb2ZfbWVzc2FnZSwgImMiLCAzLAorICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpMQUJFTF9PUFRJT05BTCwKKyAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9NRVNTQUdFKTsKKyAgICBvbmVvZl9tZXNzYWdlLT5tdXRhYmxlX2ZpZWxkKDIpLT5zZXRfb25lb2ZfaW5kZXgoMCk7CisgICAgb25lb2ZfbWVzc2FnZS0+bXV0YWJsZV9maWVsZCgyKS0+c2V0X3R5cGVfbmFtZSgiVGVzdE9uZW9mIik7CisKKyAgICBBZGRGaWVsZChvbmVvZl9tZXNzYWdlLCAiZCIsIDQsCisgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX09QVElPTkFMLAorICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0ZMT0FUKTsKKyAgICBvbmVvZl9tZXNzYWdlLT5tdXRhYmxlX2ZpZWxkKDMpLT5zZXRfb25lb2ZfaW5kZXgoMSk7CisKKyAgICAvLyBCdWlsZCB0aGUgZGVzY3JpcHRvcnMgYW5kIGdldCB0aGUgcG9pbnRlcnMuCisgICAgYmF6X2ZpbGVfID0gcG9vbF8uQnVpbGRGaWxlKGJhel9maWxlKTsKKyAgICBBU1NFUlRfVFJVRShiYXpfZmlsZV8gIT0gTlVMTCk7CisKKyAgICBBU1NFUlRfRVEoMSwgYmF6X2ZpbGVfLT5tZXNzYWdlX3R5cGVfY291bnQoKSk7CisgICAgb25lb2ZfbWVzc2FnZV8gPSBiYXpfZmlsZV8tPm1lc3NhZ2VfdHlwZSgwKTsKKworICAgIEFTU0VSVF9FUSgyLCBvbmVvZl9tZXNzYWdlXy0+b25lb2ZfZGVjbF9jb3VudCgpKTsKKyAgICBvbmVvZl8gPSBvbmVvZl9tZXNzYWdlXy0+b25lb2ZfZGVjbCgwKTsKKyAgICBvbmVvZjJfID0gb25lb2ZfbWVzc2FnZV8tPm9uZW9mX2RlY2woMSk7CisKKyAgICBBU1NFUlRfRVEoNCwgb25lb2ZfbWVzc2FnZV8tPmZpZWxkX2NvdW50KCkpOworICAgIGFfID0gb25lb2ZfbWVzc2FnZV8tPmZpZWxkKDApOworICAgIGJfID0gb25lb2ZfbWVzc2FnZV8tPmZpZWxkKDEpOworICAgIGNfID0gb25lb2ZfbWVzc2FnZV8tPmZpZWxkKDIpOworICAgIGRfID0gb25lb2ZfbWVzc2FnZV8tPmZpZWxkKDMpOworICB9CisKKyAgRGVzY3JpcHRvclBvb2wgcG9vbF87CisKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGJhel9maWxlXzsKKworICBjb25zdCBEZXNjcmlwdG9yKiBvbmVvZl9tZXNzYWdlXzsKKworICBjb25zdCBPbmVvZkRlc2NyaXB0b3IqIG9uZW9mXzsKKyAgY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBvbmVvZjJfOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGFfOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGJfOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGNfOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRfOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGVfOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZfOworfTsKKworVEVTVF9GKE9uZW9mRGVzY3JpcHRvclRlc3QsIE5vcm1hbCkgeworICBFWFBFQ1RfRVEoImZvbyIsIG9uZW9mXy0+bmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJnYXJwbHkuVGVzdE9uZW9mLmZvbyIsIG9uZW9mXy0+ZnVsbF9uYW1lKCkpOworICBFWFBFQ1RfRVEoMCwgb25lb2ZfLT5pbmRleCgpKTsKKyAgQVNTRVJUX0VRKDIsIG9uZW9mXy0+ZmllbGRfY291bnQoKSk7CisgIEVYUEVDVF9FUShiXywgb25lb2ZfLT5maWVsZCgwKSk7CisgIEVYUEVDVF9FUShjXywgb25lb2ZfLT5maWVsZCgxKSk7CisgIEVYUEVDVF9UUlVFKGFfLT5jb250YWluaW5nX29uZW9mKCkgPT0gTlVMTCk7CisgIEVYUEVDVF9FUShvbmVvZl8sIGJfLT5jb250YWluaW5nX29uZW9mKCkpOworICBFWFBFQ1RfRVEob25lb2ZfLCBjXy0+Y29udGFpbmluZ19vbmVvZigpKTsKK30KKworVEVTVF9GKE9uZW9mRGVzY3JpcHRvclRlc3QsIEZpbmRCeU5hbWUpIHsKKyAgRVhQRUNUX0VRKG9uZW9mXywgb25lb2ZfbWVzc2FnZV8tPkZpbmRPbmVvZkJ5TmFtZSgiZm9vIikpOworICBFWFBFQ1RfRVEob25lb2YyXywgb25lb2ZfbWVzc2FnZV8tPkZpbmRPbmVvZkJ5TmFtZSgiYmFyIikpOworICBFWFBFQ1RfVFJVRShvbmVvZl9tZXNzYWdlXy0+RmluZE9uZW9mQnlOYW1lKCJub19zdWNoX29uZW9mIikgPT0gTlVMTCk7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworY2xhc3MgU3R5bGl6ZWRGaWVsZE5hbWVzVGVzdCA6IHB1YmxpYyB0ZXN0aW5nOjpUZXN0IHsKKyBwcm90ZWN0ZWQ6CisgIHZvaWQgU2V0VXAoKSB7CisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlOworICAgIGZpbGUuc2V0X25hbWUoImZvby5wcm90byIpOworCisgICAgQWRkRXh0ZW5zaW9uUmFuZ2UoQWRkTWVzc2FnZSgmZmlsZSwgIkV4dGVuZGFibGVNZXNzYWdlIiksIDEsIDEwMDApOworCisgICAgRGVzY3JpcHRvclByb3RvKiBtZXNzYWdlID0gQWRkTWVzc2FnZSgmZmlsZSwgIlRlc3RNZXNzYWdlIik7CisgICAgQWRkRmllbGQobWVzc2FnZSwgImZvb19mb28iLCAxLAorICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpMQUJFTF9PUFRJT05BTCwKKyAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9JTlQzMik7CisgICAgQWRkRmllbGQobWVzc2FnZSwgIkZvb0JhciIsIDIsCisgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX09QVElPTkFMLAorICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0lOVDMyKTsKKyAgICBBZGRGaWVsZChtZXNzYWdlLCAiZm9vQmF6IiwgMywKKyAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfT1BUSU9OQUwsCisgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfSU5UMzIpOworICAgIEFkZEZpZWxkKG1lc3NhZ2UsICJmb29Gb28iLCA0LCAgLy8gQ2FtZWwtY2FzZSBjb25mbGljdCB3aXRoIGZvb19mb28uCisgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX09QVElPTkFMLAorICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0lOVDMyKTsKKyAgICBBZGRGaWVsZChtZXNzYWdlLCAiZm9vYmFyIiwgNSwgIC8vIExvd2VyLWNhc2UgY29uZmxpY3Qgd2l0aCBGb29CYXIuCisgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX09QVElPTkFMLAorICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0lOVDMyKTsKKworICAgIEFkZE5lc3RlZEV4dGVuc2lvbihtZXNzYWdlLCAiRXh0ZW5kYWJsZU1lc3NhZ2UiLCAiYmFyX2ZvbyIsIDEsCisgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpMQUJFTF9PUFRJT05BTCwKKyAgICAgICAgICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfSU5UMzIpOworICAgIEFkZE5lc3RlZEV4dGVuc2lvbihtZXNzYWdlLCAiRXh0ZW5kYWJsZU1lc3NhZ2UiLCAiQmFyQmFyIiwgMiwKKyAgICAgICAgICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX09QVElPTkFMLAorICAgICAgICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9JTlQzMik7CisgICAgQWRkTmVzdGVkRXh0ZW5zaW9uKG1lc3NhZ2UsICJFeHRlbmRhYmxlTWVzc2FnZSIsICJCYXJCYXoiLCAzLAorICAgICAgICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfT1BUSU9OQUwsCisgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0lOVDMyKTsKKyAgICBBZGROZXN0ZWRFeHRlbnNpb24obWVzc2FnZSwgIkV4dGVuZGFibGVNZXNzYWdlIiwgImJhckZvbyIsIDQsICAvLyBDb25mbGljdAorICAgICAgICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfT1BUSU9OQUwsCisgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0lOVDMyKTsKKyAgICBBZGROZXN0ZWRFeHRlbnNpb24obWVzc2FnZSwgIkV4dGVuZGFibGVNZXNzYWdlIiwgImJhcmJhciIsIDUsICAvLyBDb25mbGljdAorICAgICAgICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfT1BUSU9OQUwsCisgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0lOVDMyKTsKKworICAgIEFkZEV4dGVuc2lvbigmZmlsZSwgIkV4dGVuZGFibGVNZXNzYWdlIiwgImJhel9mb28iLCAxMSwKKyAgICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX09QVElPTkFMLAorICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9JTlQzMik7CisgICAgQWRkRXh0ZW5zaW9uKCZmaWxlLCAiRXh0ZW5kYWJsZU1lc3NhZ2UiLCAiQmF6QmFyIiwgMTIsCisgICAgICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpMQUJFTF9PUFRJT05BTCwKKyAgICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfSU5UMzIpOworICAgIEFkZEV4dGVuc2lvbigmZmlsZSwgIkV4dGVuZGFibGVNZXNzYWdlIiwgIkJhekJheiIsIDEzLAorICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfT1BUSU9OQUwsCisgICAgICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0lOVDMyKTsKKyAgICBBZGRFeHRlbnNpb24oJmZpbGUsICJFeHRlbmRhYmxlTWVzc2FnZSIsICJiYXpGb28iLCAxNCwgIC8vIENvbmZsaWN0CisgICAgICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpMQUJFTF9PUFRJT05BTCwKKyAgICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfSU5UMzIpOworICAgIEFkZEV4dGVuc2lvbigmZmlsZSwgIkV4dGVuZGFibGVNZXNzYWdlIiwgImJhemJhciIsIDE1LCAgLy8gQ29uZmxpY3QKKyAgICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX09QVElPTkFMLAorICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9JTlQzMik7CisKKyAgICBmaWxlXyA9IHBvb2xfLkJ1aWxkRmlsZShmaWxlKTsKKyAgICBBU1NFUlRfVFJVRShmaWxlXyAhPSBOVUxMKTsKKyAgICBBU1NFUlRfRVEoMiwgZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpKTsKKyAgICBtZXNzYWdlXyA9IGZpbGVfLT5tZXNzYWdlX3R5cGUoMSk7CisgICAgQVNTRVJUX0VRKCJUZXN0TWVzc2FnZSIsIG1lc3NhZ2VfLT5uYW1lKCkpOworICAgIEFTU0VSVF9FUSg1LCBtZXNzYWdlXy0+ZmllbGRfY291bnQoKSk7CisgICAgQVNTRVJUX0VRKDUsIG1lc3NhZ2VfLT5leHRlbnNpb25fY291bnQoKSk7CisgICAgQVNTRVJUX0VRKDUsIGZpbGVfLT5leHRlbnNpb25fY291bnQoKSk7CisgIH0KKworICBEZXNjcmlwdG9yUG9vbCBwb29sXzsKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGVfOworICBjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlXzsKK307CisKK1RFU1RfRihTdHlsaXplZEZpZWxkTmFtZXNUZXN0LCBMb3dlcmNhc2VOYW1lKSB7CisgIEVYUEVDVF9FUSgiZm9vX2ZvbyIsIG1lc3NhZ2VfLT5maWVsZCgwKS0+bG93ZXJjYXNlX25hbWUoKSk7CisgIEVYUEVDVF9FUSgiZm9vYmFyIiAsIG1lc3NhZ2VfLT5maWVsZCgxKS0+bG93ZXJjYXNlX25hbWUoKSk7CisgIEVYUEVDVF9FUSgiZm9vYmF6IiAsIG1lc3NhZ2VfLT5maWVsZCgyKS0+bG93ZXJjYXNlX25hbWUoKSk7CisgIEVYUEVDVF9FUSgiZm9vZm9vIiAsIG1lc3NhZ2VfLT5maWVsZCgzKS0+bG93ZXJjYXNlX25hbWUoKSk7CisgIEVYUEVDVF9FUSgiZm9vYmFyIiAsIG1lc3NhZ2VfLT5maWVsZCg0KS0+bG93ZXJjYXNlX25hbWUoKSk7CisKKyAgRVhQRUNUX0VRKCJiYXJfZm9vIiwgbWVzc2FnZV8tPmV4dGVuc2lvbigwKS0+bG93ZXJjYXNlX25hbWUoKSk7CisgIEVYUEVDVF9FUSgiYmFyYmFyIiAsIG1lc3NhZ2VfLT5leHRlbnNpb24oMSktPmxvd2VyY2FzZV9uYW1lKCkpOworICBFWFBFQ1RfRVEoImJhcmJheiIgLCBtZXNzYWdlXy0+ZXh0ZW5zaW9uKDIpLT5sb3dlcmNhc2VfbmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJiYXJmb28iICwgbWVzc2FnZV8tPmV4dGVuc2lvbigzKS0+bG93ZXJjYXNlX25hbWUoKSk7CisgIEVYUEVDVF9FUSgiYmFyYmFyIiAsIG1lc3NhZ2VfLT5leHRlbnNpb24oNCktPmxvd2VyY2FzZV9uYW1lKCkpOworCisgIEVYUEVDVF9FUSgiYmF6X2ZvbyIsIGZpbGVfLT5leHRlbnNpb24oMCktPmxvd2VyY2FzZV9uYW1lKCkpOworICBFWFBFQ1RfRVEoImJhemJhciIgLCBmaWxlXy0+ZXh0ZW5zaW9uKDEpLT5sb3dlcmNhc2VfbmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJiYXpiYXoiICwgZmlsZV8tPmV4dGVuc2lvbigyKS0+bG93ZXJjYXNlX25hbWUoKSk7CisgIEVYUEVDVF9FUSgiYmF6Zm9vIiAsIGZpbGVfLT5leHRlbnNpb24oMyktPmxvd2VyY2FzZV9uYW1lKCkpOworICBFWFBFQ1RfRVEoImJhemJhciIgLCBmaWxlXy0+ZXh0ZW5zaW9uKDQpLT5sb3dlcmNhc2VfbmFtZSgpKTsKK30KKworVEVTVF9GKFN0eWxpemVkRmllbGROYW1lc1Rlc3QsIENhbWVsY2FzZU5hbWUpIHsKKyAgRVhQRUNUX0VRKCJmb29Gb28iLCBtZXNzYWdlXy0+ZmllbGQoMCktPmNhbWVsY2FzZV9uYW1lKCkpOworICBFWFBFQ1RfRVEoImZvb0JhciIsIG1lc3NhZ2VfLT5maWVsZCgxKS0+Y2FtZWxjYXNlX25hbWUoKSk7CisgIEVYUEVDVF9FUSgiZm9vQmF6IiwgbWVzc2FnZV8tPmZpZWxkKDIpLT5jYW1lbGNhc2VfbmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJmb29Gb28iLCBtZXNzYWdlXy0+ZmllbGQoMyktPmNhbWVsY2FzZV9uYW1lKCkpOworICBFWFBFQ1RfRVEoImZvb2JhciIsIG1lc3NhZ2VfLT5maWVsZCg0KS0+Y2FtZWxjYXNlX25hbWUoKSk7CisKKyAgRVhQRUNUX0VRKCJiYXJGb28iLCBtZXNzYWdlXy0+ZXh0ZW5zaW9uKDApLT5jYW1lbGNhc2VfbmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJiYXJCYXIiLCBtZXNzYWdlXy0+ZXh0ZW5zaW9uKDEpLT5jYW1lbGNhc2VfbmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJiYXJCYXoiLCBtZXNzYWdlXy0+ZXh0ZW5zaW9uKDIpLT5jYW1lbGNhc2VfbmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJiYXJGb28iLCBtZXNzYWdlXy0+ZXh0ZW5zaW9uKDMpLT5jYW1lbGNhc2VfbmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJiYXJiYXIiLCBtZXNzYWdlXy0+ZXh0ZW5zaW9uKDQpLT5jYW1lbGNhc2VfbmFtZSgpKTsKKworICBFWFBFQ1RfRVEoImJhekZvbyIsIGZpbGVfLT5leHRlbnNpb24oMCktPmNhbWVsY2FzZV9uYW1lKCkpOworICBFWFBFQ1RfRVEoImJhekJhciIsIGZpbGVfLT5leHRlbnNpb24oMSktPmNhbWVsY2FzZV9uYW1lKCkpOworICBFWFBFQ1RfRVEoImJhekJheiIsIGZpbGVfLT5leHRlbnNpb24oMiktPmNhbWVsY2FzZV9uYW1lKCkpOworICBFWFBFQ1RfRVEoImJhekZvbyIsIGZpbGVfLT5leHRlbnNpb24oMyktPmNhbWVsY2FzZV9uYW1lKCkpOworICBFWFBFQ1RfRVEoImJhemJhciIsIGZpbGVfLT5leHRlbnNpb24oNCktPmNhbWVsY2FzZV9uYW1lKCkpOworfQorCitURVNUX0YoU3R5bGl6ZWRGaWVsZE5hbWVzVGVzdCwgRmluZEJ5TG93ZXJjYXNlTmFtZSkgeworICBFWFBFQ1RfRVEobWVzc2FnZV8tPmZpZWxkKDApLAorICAgICAgICAgICAgbWVzc2FnZV8tPkZpbmRGaWVsZEJ5TG93ZXJjYXNlTmFtZSgiZm9vX2ZvbyIpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2VfLT5maWVsZCgxKSwKKyAgICAgICAgICAgIG1lc3NhZ2VfLT5GaW5kRmllbGRCeUxvd2VyY2FzZU5hbWUoImZvb2JhciIpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2VfLT5maWVsZCgyKSwKKyAgICAgICAgICAgIG1lc3NhZ2VfLT5GaW5kRmllbGRCeUxvd2VyY2FzZU5hbWUoImZvb2JheiIpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZV8tPkZpbmRGaWVsZEJ5TG93ZXJjYXNlTmFtZSgiRm9vQmFyIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2VfLT5GaW5kRmllbGRCeUxvd2VyY2FzZU5hbWUoImZvb0JheiIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlXy0+RmluZEZpZWxkQnlMb3dlcmNhc2VOYW1lKCJiYXJfZm9vIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2VfLT5GaW5kRmllbGRCeUxvd2VyY2FzZU5hbWUoIm5vc3VjaGZpZWxkIikgPT0gTlVMTCk7CisKKyAgRVhQRUNUX0VRKG1lc3NhZ2VfLT5leHRlbnNpb24oMCksCisgICAgICAgICAgICBtZXNzYWdlXy0+RmluZEV4dGVuc2lvbkJ5TG93ZXJjYXNlTmFtZSgiYmFyX2ZvbyIpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2VfLT5leHRlbnNpb24oMSksCisgICAgICAgICAgICBtZXNzYWdlXy0+RmluZEV4dGVuc2lvbkJ5TG93ZXJjYXNlTmFtZSgiYmFyYmFyIikpOworICBFWFBFQ1RfRVEobWVzc2FnZV8tPmV4dGVuc2lvbigyKSwKKyAgICAgICAgICAgIG1lc3NhZ2VfLT5GaW5kRXh0ZW5zaW9uQnlMb3dlcmNhc2VOYW1lKCJiYXJiYXoiKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2VfLT5GaW5kRXh0ZW5zaW9uQnlMb3dlcmNhc2VOYW1lKCJCYXJCYXIiKSA9PSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZV8tPkZpbmRFeHRlbnNpb25CeUxvd2VyY2FzZU5hbWUoImJhckJheiIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlXy0+RmluZEV4dGVuc2lvbkJ5TG93ZXJjYXNlTmFtZSgiZm9vX2ZvbyIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlXy0+RmluZEV4dGVuc2lvbkJ5TG93ZXJjYXNlTmFtZSgibm9zdWNoZmllbGQiKSA9PSBOVUxMKTsKKworICBFWFBFQ1RfRVEoZmlsZV8tPmV4dGVuc2lvbigwKSwKKyAgICAgICAgICAgIGZpbGVfLT5GaW5kRXh0ZW5zaW9uQnlMb3dlcmNhc2VOYW1lKCJiYXpfZm9vIikpOworICBFWFBFQ1RfRVEoZmlsZV8tPmV4dGVuc2lvbigxKSwKKyAgICAgICAgICAgIGZpbGVfLT5GaW5kRXh0ZW5zaW9uQnlMb3dlcmNhc2VOYW1lKCJiYXpiYXIiKSk7CisgIEVYUEVDVF9FUShmaWxlXy0+ZXh0ZW5zaW9uKDIpLAorICAgICAgICAgICAgZmlsZV8tPkZpbmRFeHRlbnNpb25CeUxvd2VyY2FzZU5hbWUoImJhemJheiIpKTsKKyAgRVhQRUNUX1RSVUUoZmlsZV8tPkZpbmRFeHRlbnNpb25CeUxvd2VyY2FzZU5hbWUoIkJhekJhciIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShmaWxlXy0+RmluZEV4dGVuc2lvbkJ5TG93ZXJjYXNlTmFtZSgiYmF6QmF6IikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKGZpbGVfLT5GaW5kRXh0ZW5zaW9uQnlMb3dlcmNhc2VOYW1lKCJub3N1Y2hmaWVsZCIpID09IE5VTEwpOworfQorCitURVNUX0YoU3R5bGl6ZWRGaWVsZE5hbWVzVGVzdCwgRmluZEJ5Q2FtZWxjYXNlTmFtZSkgeworICBFWFBFQ1RfRVEobWVzc2FnZV8tPmZpZWxkKDApLAorICAgICAgICAgICAgbWVzc2FnZV8tPkZpbmRGaWVsZEJ5Q2FtZWxjYXNlTmFtZSgiZm9vRm9vIikpOworICBFWFBFQ1RfRVEobWVzc2FnZV8tPmZpZWxkKDEpLAorICAgICAgICAgICAgbWVzc2FnZV8tPkZpbmRGaWVsZEJ5Q2FtZWxjYXNlTmFtZSgiZm9vQmFyIikpOworICBFWFBFQ1RfRVEobWVzc2FnZV8tPmZpZWxkKDIpLAorICAgICAgICAgICAgbWVzc2FnZV8tPkZpbmRGaWVsZEJ5Q2FtZWxjYXNlTmFtZSgiZm9vQmF6IikpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlXy0+RmluZEZpZWxkQnlDYW1lbGNhc2VOYW1lKCJmb29fZm9vIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2VfLT5GaW5kRmllbGRCeUNhbWVsY2FzZU5hbWUoIkZvb0JhciIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlXy0+RmluZEZpZWxkQnlDYW1lbGNhc2VOYW1lKCJiYXJGb28iKSA9PSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZV8tPkZpbmRGaWVsZEJ5Q2FtZWxjYXNlTmFtZSgibm9zdWNoZmllbGQiKSA9PSBOVUxMKTsKKworICBFWFBFQ1RfRVEobWVzc2FnZV8tPmV4dGVuc2lvbigwKSwKKyAgICAgICAgICAgIG1lc3NhZ2VfLT5GaW5kRXh0ZW5zaW9uQnlDYW1lbGNhc2VOYW1lKCJiYXJGb28iKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlXy0+ZXh0ZW5zaW9uKDEpLAorICAgICAgICAgICAgbWVzc2FnZV8tPkZpbmRFeHRlbnNpb25CeUNhbWVsY2FzZU5hbWUoImJhckJhciIpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2VfLT5leHRlbnNpb24oMiksCisgICAgICAgICAgICBtZXNzYWdlXy0+RmluZEV4dGVuc2lvbkJ5Q2FtZWxjYXNlTmFtZSgiYmFyQmF6IikpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlXy0+RmluZEV4dGVuc2lvbkJ5Q2FtZWxjYXNlTmFtZSgiYmFyX2ZvbyIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlXy0+RmluZEV4dGVuc2lvbkJ5Q2FtZWxjYXNlTmFtZSgiQmFyQmFyIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2VfLT5GaW5kRXh0ZW5zaW9uQnlDYW1lbGNhc2VOYW1lKCJmb29Gb28iKSA9PSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZV8tPkZpbmRFeHRlbnNpb25CeUNhbWVsY2FzZU5hbWUoIm5vc3VjaGZpZWxkIikgPT0gTlVMTCk7CisKKyAgRVhQRUNUX0VRKGZpbGVfLT5leHRlbnNpb24oMCksCisgICAgICAgICAgICBmaWxlXy0+RmluZEV4dGVuc2lvbkJ5Q2FtZWxjYXNlTmFtZSgiYmF6Rm9vIikpOworICBFWFBFQ1RfRVEoZmlsZV8tPmV4dGVuc2lvbigxKSwKKyAgICAgICAgICAgIGZpbGVfLT5GaW5kRXh0ZW5zaW9uQnlDYW1lbGNhc2VOYW1lKCJiYXpCYXIiKSk7CisgIEVYUEVDVF9FUShmaWxlXy0+ZXh0ZW5zaW9uKDIpLAorICAgICAgICAgICAgZmlsZV8tPkZpbmRFeHRlbnNpb25CeUNhbWVsY2FzZU5hbWUoImJhekJheiIpKTsKKyAgRVhQRUNUX1RSVUUoZmlsZV8tPkZpbmRFeHRlbnNpb25CeUNhbWVsY2FzZU5hbWUoImJhel9mb28iKSA9PSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUoZmlsZV8tPkZpbmRFeHRlbnNpb25CeUNhbWVsY2FzZU5hbWUoIkJhekJhciIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShmaWxlXy0+RmluZEV4dGVuc2lvbkJ5Q2FtZWxjYXNlTmFtZSgibm9zdWNoZmllbGQiKSA9PSBOVUxMKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisvLyBUZXN0IGVudW0gZGVzY3JpcHRvcnMuCitjbGFzcyBFbnVtRGVzY3JpcHRvclRlc3QgOiBwdWJsaWMgdGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICB2aXJ0dWFsIHZvaWQgU2V0VXAoKSB7CisgICAgLy8gQnVpbGQgZGVzY3JpcHRvcnMgZm9yIHRoZSBmb2xsb3dpbmcgZGVmaW5pdGlvbnM6CisgICAgLy8KKyAgICAvLyAgIC8vIGluICJmb28ucHJvdG8iCisgICAgLy8gICBlbnVtIFRlc3RFbnVtIHsKKyAgICAvLyAgICAgRk9PID0gMTsKKyAgICAvLyAgICAgQkFSID0gMjsKKyAgICAvLyAgIH0KKyAgICAvLworICAgIC8vICAgLy8gaW4gImJhci5wcm90byIKKyAgICAvLyAgIHBhY2thZ2UgY29yZ2UuZ3JhdWx0OworICAgIC8vICAgZW51bSBUZXN0RW51bTIgeworICAgIC8vICAgICBGT08gPSAxOworICAgIC8vICAgICBCQVogPSAzOworICAgIC8vICAgfQorICAgIC8vCisgICAgLy8gVGVzdEVudW0yIGlzIHByaW1hcmlseSBoZXJlIHRvIHRlc3QgRmluZFZhbHVlQnlOYW1lIGFuZCBmcmllbmRzLgorICAgIC8vIEFsbCBlbnVtcyBjcmVhdGVkIGZyb20gdGhlIHNhbWUgRGVzY3JpcHRvclBvb2wgc2hhcmUgdGhlIHNhbWUgbG9va3VwCisgICAgLy8gdGFibGUsIHNvIHdlIG5lZWQgdG8gaW5zdXJlIHRoYXQgdGhleSBkb24ndCBpbnRlcmZlcmUuCisKKyAgICAvLyBUZXN0RW51bQorICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZm9vX2ZpbGU7CisgICAgZm9vX2ZpbGUuc2V0X25hbWUoImZvby5wcm90byIpOworCisgICAgRW51bURlc2NyaXB0b3JQcm90byogZW51bV9wcm90byA9IEFkZEVudW0oJmZvb19maWxlLCAiVGVzdEVudW0iKTsKKyAgICBBZGRFbnVtVmFsdWUoZW51bV9wcm90bywgIkZPTyIsIDEpOworICAgIEFkZEVudW1WYWx1ZShlbnVtX3Byb3RvLCAiQkFSIiwgMik7CisKKyAgICAvLyBUZXN0RW51bTIKKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGJhcl9maWxlOworICAgIGJhcl9maWxlLnNldF9uYW1lKCJiYXIucHJvdG8iKTsKKyAgICBiYXJfZmlsZS5zZXRfcGFja2FnZSgiY29yZ2UuZ3JhdWx0Iik7CisKKyAgICBFbnVtRGVzY3JpcHRvclByb3RvKiBlbnVtMl9wcm90byA9IEFkZEVudW0oJmJhcl9maWxlLCAiVGVzdEVudW0yIik7CisgICAgQWRkRW51bVZhbHVlKGVudW0yX3Byb3RvLCAiRk9PIiwgMSk7CisgICAgQWRkRW51bVZhbHVlKGVudW0yX3Byb3RvLCAiQkFaIiwgMyk7CisKKyAgICAvLyBCdWlsZCB0aGUgZGVzY3JpcHRvcnMgYW5kIGdldCB0aGUgcG9pbnRlcnMuCisgICAgZm9vX2ZpbGVfID0gcG9vbF8uQnVpbGRGaWxlKGZvb19maWxlKTsKKyAgICBBU1NFUlRfVFJVRShmb29fZmlsZV8gIT0gTlVMTCk7CisKKyAgICBiYXJfZmlsZV8gPSBwb29sXy5CdWlsZEZpbGUoYmFyX2ZpbGUpOworICAgIEFTU0VSVF9UUlVFKGJhcl9maWxlXyAhPSBOVUxMKTsKKworICAgIEFTU0VSVF9FUSgxLCBmb29fZmlsZV8tPmVudW1fdHlwZV9jb3VudCgpKTsKKyAgICBlbnVtXyA9IGZvb19maWxlXy0+ZW51bV90eXBlKDApOworCisgICAgQVNTRVJUX0VRKDIsIGVudW1fLT52YWx1ZV9jb3VudCgpKTsKKyAgICBmb29fID0gZW51bV8tPnZhbHVlKDApOworICAgIGJhcl8gPSBlbnVtXy0+dmFsdWUoMSk7CisKKyAgICBBU1NFUlRfRVEoMSwgYmFyX2ZpbGVfLT5lbnVtX3R5cGVfY291bnQoKSk7CisgICAgZW51bTJfID0gYmFyX2ZpbGVfLT5lbnVtX3R5cGUoMCk7CisKKyAgICBBU1NFUlRfRVEoMiwgZW51bTJfLT52YWx1ZV9jb3VudCgpKTsKKyAgICBmb28yXyA9IGVudW0yXy0+dmFsdWUoMCk7CisgICAgYmF6Ml8gPSBlbnVtMl8tPnZhbHVlKDEpOworICB9CisKKyAgRGVzY3JpcHRvclBvb2wgcG9vbF87CisKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZvb19maWxlXzsKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGJhcl9maWxlXzsKKworICBjb25zdCBFbnVtRGVzY3JpcHRvciogZW51bV87CisgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBlbnVtMl87CisKKyAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogZm9vXzsKKyAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogYmFyXzsKKworICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBmb28yXzsKKyAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogYmF6Ml87Cit9OworCitURVNUX0YoRW51bURlc2NyaXB0b3JUZXN0LCBOYW1lKSB7CisgIEVYUEVDVF9FUSgiVGVzdEVudW0iLCBlbnVtXy0+bmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJUZXN0RW51bSIsIGVudW1fLT5mdWxsX25hbWUoKSk7CisgIEVYUEVDVF9FUShmb29fZmlsZV8sIGVudW1fLT5maWxlKCkpOworCisgIEVYUEVDVF9FUSgiVGVzdEVudW0yIiwgZW51bTJfLT5uYW1lKCkpOworICBFWFBFQ1RfRVEoImNvcmdlLmdyYXVsdC5UZXN0RW51bTIiLCBlbnVtMl8tPmZ1bGxfbmFtZSgpKTsKKyAgRVhQRUNUX0VRKGJhcl9maWxlXywgZW51bTJfLT5maWxlKCkpOworfQorCitURVNUX0YoRW51bURlc2NyaXB0b3JUZXN0LCBDb250YWluaW5nVHlwZSkgeworICBFWFBFQ1RfVFJVRShlbnVtXy0+Y29udGFpbmluZ190eXBlKCkgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKGVudW0yXy0+Y29udGFpbmluZ190eXBlKCkgPT0gTlVMTCk7Cit9CisKK1RFU1RfRihFbnVtRGVzY3JpcHRvclRlc3QsIFZhbHVlc0J5SW5kZXgpIHsKKyAgQVNTRVJUX0VRKDIsIGVudW1fLT52YWx1ZV9jb3VudCgpKTsKKyAgRVhQRUNUX0VRKGZvb18sIGVudW1fLT52YWx1ZSgwKSk7CisgIEVYUEVDVF9FUShiYXJfLCBlbnVtXy0+dmFsdWUoMSkpOworfQorCitURVNUX0YoRW51bURlc2NyaXB0b3JUZXN0LCBGaW5kVmFsdWVCeU5hbWUpIHsKKyAgRVhQRUNUX0VRKGZvb18gLCBlbnVtXyAtPkZpbmRWYWx1ZUJ5TmFtZSgiRk9PIikpOworICBFWFBFQ1RfRVEoYmFyXyAsIGVudW1fIC0+RmluZFZhbHVlQnlOYW1lKCJCQVIiKSk7CisgIEVYUEVDVF9FUShmb28yXywgZW51bTJfLT5GaW5kVmFsdWVCeU5hbWUoIkZPTyIpKTsKKyAgRVhQRUNUX0VRKGJhejJfLCBlbnVtMl8tPkZpbmRWYWx1ZUJ5TmFtZSgiQkFaIikpOworCisgIEVYUEVDVF9UUlVFKGVudW1fIC0+RmluZFZhbHVlQnlOYW1lKCJOT19TVUNIX1ZBTFVFIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKGVudW1fIC0+RmluZFZhbHVlQnlOYW1lKCJCQVoiICAgICAgICAgICkgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKGVudW0yXy0+RmluZFZhbHVlQnlOYW1lKCJCQVIiICAgICAgICAgICkgPT0gTlVMTCk7Cit9CisKK1RFU1RfRihFbnVtRGVzY3JpcHRvclRlc3QsIEZpbmRWYWx1ZUJ5TnVtYmVyKSB7CisgIEVYUEVDVF9FUShmb29fICwgZW51bV8gLT5GaW5kVmFsdWVCeU51bWJlcigxKSk7CisgIEVYUEVDVF9FUShiYXJfICwgZW51bV8gLT5GaW5kVmFsdWVCeU51bWJlcigyKSk7CisgIEVYUEVDVF9FUShmb28yXywgZW51bTJfLT5GaW5kVmFsdWVCeU51bWJlcigxKSk7CisgIEVYUEVDVF9FUShiYXoyXywgZW51bTJfLT5GaW5kVmFsdWVCeU51bWJlcigzKSk7CisKKyAgRVhQRUNUX1RSVUUoZW51bV8gLT5GaW5kVmFsdWVCeU51bWJlcig0MTYpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShlbnVtXyAtPkZpbmRWYWx1ZUJ5TnVtYmVyKDMpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShlbnVtMl8tPkZpbmRWYWx1ZUJ5TnVtYmVyKDIpID09IE5VTEwpOworfQorCitURVNUX0YoRW51bURlc2NyaXB0b3JUZXN0LCBWYWx1ZU5hbWUpIHsKKyAgRVhQRUNUX0VRKCJGT08iLCBmb29fLT5uYW1lKCkpOworICBFWFBFQ1RfRVEoIkJBUiIsIGJhcl8tPm5hbWUoKSk7Cit9CisKK1RFU1RfRihFbnVtRGVzY3JpcHRvclRlc3QsIFZhbHVlRnVsbE5hbWUpIHsKKyAgRVhQRUNUX0VRKCJGT08iLCBmb29fLT5mdWxsX25hbWUoKSk7CisgIEVYUEVDVF9FUSgiQkFSIiwgYmFyXy0+ZnVsbF9uYW1lKCkpOworICBFWFBFQ1RfRVEoImNvcmdlLmdyYXVsdC5GT08iLCBmb28yXy0+ZnVsbF9uYW1lKCkpOworICBFWFBFQ1RfRVEoImNvcmdlLmdyYXVsdC5CQVoiLCBiYXoyXy0+ZnVsbF9uYW1lKCkpOworfQorCitURVNUX0YoRW51bURlc2NyaXB0b3JUZXN0LCBWYWx1ZUluZGV4KSB7CisgIEVYUEVDVF9FUSgwLCBmb29fLT5pbmRleCgpKTsKKyAgRVhQRUNUX0VRKDEsIGJhcl8tPmluZGV4KCkpOworfQorCitURVNUX0YoRW51bURlc2NyaXB0b3JUZXN0LCBWYWx1ZU51bWJlcikgeworICBFWFBFQ1RfRVEoMSwgZm9vXy0+bnVtYmVyKCkpOworICBFWFBFQ1RfRVEoMiwgYmFyXy0+bnVtYmVyKCkpOworfQorCitURVNUX0YoRW51bURlc2NyaXB0b3JUZXN0LCBWYWx1ZVR5cGUpIHsKKyAgRVhQRUNUX0VRKGVudW1fICwgZm9vXyAtPnR5cGUoKSk7CisgIEVYUEVDVF9FUShlbnVtXyAsIGJhcl8gLT50eXBlKCkpOworICBFWFBFQ1RfRVEoZW51bTJfLCBmb28yXy0+dHlwZSgpKTsKKyAgRVhQRUNUX0VRKGVudW0yXywgYmF6Ml8tPnR5cGUoKSk7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworLy8gVGVzdCBzZXJ2aWNlIGRlc2NyaXB0b3JzLgorY2xhc3MgU2VydmljZURlc2NyaXB0b3JUZXN0IDogcHVibGljIHRlc3Rpbmc6OlRlc3QgeworIHByb3RlY3RlZDoKKyAgdmlydHVhbCB2b2lkIFNldFVwKCkgeworICAgIC8vIEJ1aWxkIGRlc2NyaXB0b3JzIGZvciB0aGUgZm9sbG93aW5nIG1lc3NhZ2VzIGFuZCBzZXJ2aWNlOgorICAgIC8vICAgIC8vIGluICJmb28ucHJvdG8iCisgICAgLy8gICAgbWVzc2FnZSBGb29SZXF1ZXN0ICB7fQorICAgIC8vICAgIG1lc3NhZ2UgRm9vUmVzcG9uc2Uge30KKyAgICAvLyAgICBtZXNzYWdlIEJhclJlcXVlc3QgIHt9CisgICAgLy8gICAgbWVzc2FnZSBCYXJSZXNwb25zZSB7fQorICAgIC8vICAgIG1lc3NhZ2UgQmF6UmVxdWVzdCAge30KKyAgICAvLyAgICBtZXNzYWdlIEJhelJlc3BvbnNlIHt9CisgICAgLy8KKyAgICAvLyAgICBzZXJ2aWNlIFRlc3RTZXJ2aWNlIHsKKyAgICAvLyAgICAgIHJwYyBGb28oRm9vUmVxdWVzdCkgcmV0dXJucyAoRm9vUmVzcG9uc2UpOworICAgIC8vICAgICAgcnBjIEJhcihCYXJSZXF1ZXN0KSByZXR1cm5zIChCYXJSZXNwb25zZSk7CisgICAgLy8gICAgfQorICAgIC8vCisgICAgLy8gICAgLy8gaW4gImJhci5wcm90byIKKyAgICAvLyAgICBwYWNrYWdlIGNvcmdlLmdyYXVsdAorICAgIC8vICAgIHNlcnZpY2UgVGVzdFNlcnZpY2UyIHsKKyAgICAvLyAgICAgIHJwYyBGb28oRm9vUmVxdWVzdCkgcmV0dXJucyAoRm9vUmVzcG9uc2UpOworICAgIC8vICAgICAgcnBjIEJheihCYXpSZXF1ZXN0KSByZXR1cm5zIChCYXpSZXNwb25zZSk7CisgICAgLy8gICAgfQorCisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmb29fZmlsZTsKKyAgICBmb29fZmlsZS5zZXRfbmFtZSgiZm9vLnByb3RvIik7CisKKyAgICBBZGRNZXNzYWdlKCZmb29fZmlsZSwgIkZvb1JlcXVlc3QiKTsKKyAgICBBZGRNZXNzYWdlKCZmb29fZmlsZSwgIkZvb1Jlc3BvbnNlIik7CisgICAgQWRkTWVzc2FnZSgmZm9vX2ZpbGUsICJCYXJSZXF1ZXN0Iik7CisgICAgQWRkTWVzc2FnZSgmZm9vX2ZpbGUsICJCYXJSZXNwb25zZSIpOworICAgIEFkZE1lc3NhZ2UoJmZvb19maWxlLCAiQmF6UmVxdWVzdCIpOworICAgIEFkZE1lc3NhZ2UoJmZvb19maWxlLCAiQmF6UmVzcG9uc2UiKTsKKworICAgIFNlcnZpY2VEZXNjcmlwdG9yUHJvdG8qIHNlcnZpY2UgPSBBZGRTZXJ2aWNlKCZmb29fZmlsZSwgIlRlc3RTZXJ2aWNlIik7CisgICAgQWRkTWV0aG9kKHNlcnZpY2UsICJGb28iLCAiRm9vUmVxdWVzdCIsICJGb29SZXNwb25zZSIpOworICAgIEFkZE1ldGhvZChzZXJ2aWNlLCAiQmFyIiwgIkJhclJlcXVlc3QiLCAiQmFyUmVzcG9uc2UiKTsKKworICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gYmFyX2ZpbGU7CisgICAgYmFyX2ZpbGUuc2V0X25hbWUoImJhci5wcm90byIpOworICAgIGJhcl9maWxlLnNldF9wYWNrYWdlKCJjb3JnZS5ncmF1bHQiKTsKKyAgICBiYXJfZmlsZS5hZGRfZGVwZW5kZW5jeSgiZm9vLnByb3RvIik7CisKKyAgICBTZXJ2aWNlRGVzY3JpcHRvclByb3RvKiBzZXJ2aWNlMiA9IEFkZFNlcnZpY2UoJmJhcl9maWxlLCAiVGVzdFNlcnZpY2UyIik7CisgICAgQWRkTWV0aG9kKHNlcnZpY2UyLCAiRm9vIiwgIkZvb1JlcXVlc3QiLCAiRm9vUmVzcG9uc2UiKTsKKyAgICBBZGRNZXRob2Qoc2VydmljZTIsICJCYXoiLCAiQmF6UmVxdWVzdCIsICJCYXpSZXNwb25zZSIpOworCisgICAgLy8gQnVpbGQgdGhlIGRlc2NyaXB0b3JzIGFuZCBnZXQgdGhlIHBvaW50ZXJzLgorICAgIGZvb19maWxlXyA9IHBvb2xfLkJ1aWxkRmlsZShmb29fZmlsZSk7CisgICAgQVNTRVJUX1RSVUUoZm9vX2ZpbGVfICE9IE5VTEwpOworCisgICAgYmFyX2ZpbGVfID0gcG9vbF8uQnVpbGRGaWxlKGJhcl9maWxlKTsKKyAgICBBU1NFUlRfVFJVRShiYXJfZmlsZV8gIT0gTlVMTCk7CisKKyAgICBBU1NFUlRfRVEoNiwgZm9vX2ZpbGVfLT5tZXNzYWdlX3R5cGVfY291bnQoKSk7CisgICAgZm9vX3JlcXVlc3RfICA9IGZvb19maWxlXy0+bWVzc2FnZV90eXBlKDApOworICAgIGZvb19yZXNwb25zZV8gPSBmb29fZmlsZV8tPm1lc3NhZ2VfdHlwZSgxKTsKKyAgICBiYXJfcmVxdWVzdF8gID0gZm9vX2ZpbGVfLT5tZXNzYWdlX3R5cGUoMik7CisgICAgYmFyX3Jlc3BvbnNlXyA9IGZvb19maWxlXy0+bWVzc2FnZV90eXBlKDMpOworICAgIGJhel9yZXF1ZXN0XyAgPSBmb29fZmlsZV8tPm1lc3NhZ2VfdHlwZSg0KTsKKyAgICBiYXpfcmVzcG9uc2VfID0gZm9vX2ZpbGVfLT5tZXNzYWdlX3R5cGUoNSk7CisKKyAgICBBU1NFUlRfRVEoMSwgZm9vX2ZpbGVfLT5zZXJ2aWNlX2NvdW50KCkpOworICAgIHNlcnZpY2VfID0gZm9vX2ZpbGVfLT5zZXJ2aWNlKDApOworCisgICAgQVNTRVJUX0VRKDIsIHNlcnZpY2VfLT5tZXRob2RfY291bnQoKSk7CisgICAgZm9vXyA9IHNlcnZpY2VfLT5tZXRob2QoMCk7CisgICAgYmFyXyA9IHNlcnZpY2VfLT5tZXRob2QoMSk7CisKKyAgICBBU1NFUlRfRVEoMSwgYmFyX2ZpbGVfLT5zZXJ2aWNlX2NvdW50KCkpOworICAgIHNlcnZpY2UyXyA9IGJhcl9maWxlXy0+c2VydmljZSgwKTsKKworICAgIEFTU0VSVF9FUSgyLCBzZXJ2aWNlMl8tPm1ldGhvZF9jb3VudCgpKTsKKyAgICBmb28yXyA9IHNlcnZpY2UyXy0+bWV0aG9kKDApOworICAgIGJhejJfID0gc2VydmljZTJfLT5tZXRob2QoMSk7CisgIH0KKworICBEZXNjcmlwdG9yUG9vbCBwb29sXzsKKworICBjb25zdCBGaWxlRGVzY3JpcHRvciogZm9vX2ZpbGVfOworICBjb25zdCBGaWxlRGVzY3JpcHRvciogYmFyX2ZpbGVfOworCisgIGNvbnN0IERlc2NyaXB0b3IqIGZvb19yZXF1ZXN0XzsKKyAgY29uc3QgRGVzY3JpcHRvciogZm9vX3Jlc3BvbnNlXzsKKyAgY29uc3QgRGVzY3JpcHRvciogYmFyX3JlcXVlc3RfOworICBjb25zdCBEZXNjcmlwdG9yKiBiYXJfcmVzcG9uc2VfOworICBjb25zdCBEZXNjcmlwdG9yKiBiYXpfcmVxdWVzdF87CisgIGNvbnN0IERlc2NyaXB0b3IqIGJhel9yZXNwb25zZV87CisKKyAgY29uc3QgU2VydmljZURlc2NyaXB0b3IqIHNlcnZpY2VfOworICBjb25zdCBTZXJ2aWNlRGVzY3JpcHRvciogc2VydmljZTJfOworCisgIGNvbnN0IE1ldGhvZERlc2NyaXB0b3IqIGZvb187CisgIGNvbnN0IE1ldGhvZERlc2NyaXB0b3IqIGJhcl87CisKKyAgY29uc3QgTWV0aG9kRGVzY3JpcHRvciogZm9vMl87CisgIGNvbnN0IE1ldGhvZERlc2NyaXB0b3IqIGJhejJfOworfTsKKworVEVTVF9GKFNlcnZpY2VEZXNjcmlwdG9yVGVzdCwgTmFtZSkgeworICBFWFBFQ1RfRVEoIlRlc3RTZXJ2aWNlIiwgc2VydmljZV8tPm5hbWUoKSk7CisgIEVYUEVDVF9FUSgiVGVzdFNlcnZpY2UiLCBzZXJ2aWNlXy0+ZnVsbF9uYW1lKCkpOworICBFWFBFQ1RfRVEoZm9vX2ZpbGVfLCBzZXJ2aWNlXy0+ZmlsZSgpKTsKKworICBFWFBFQ1RfRVEoIlRlc3RTZXJ2aWNlMiIsIHNlcnZpY2UyXy0+bmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJjb3JnZS5ncmF1bHQuVGVzdFNlcnZpY2UyIiwgc2VydmljZTJfLT5mdWxsX25hbWUoKSk7CisgIEVYUEVDVF9FUShiYXJfZmlsZV8sIHNlcnZpY2UyXy0+ZmlsZSgpKTsKK30KKworVEVTVF9GKFNlcnZpY2VEZXNjcmlwdG9yVGVzdCwgTWV0aG9kc0J5SW5kZXgpIHsKKyAgQVNTRVJUX0VRKDIsIHNlcnZpY2VfLT5tZXRob2RfY291bnQoKSk7CisgIEVYUEVDVF9FUShmb29fLCBzZXJ2aWNlXy0+bWV0aG9kKDApKTsKKyAgRVhQRUNUX0VRKGJhcl8sIHNlcnZpY2VfLT5tZXRob2QoMSkpOworfQorCitURVNUX0YoU2VydmljZURlc2NyaXB0b3JUZXN0LCBGaW5kTWV0aG9kQnlOYW1lKSB7CisgIEVYUEVDVF9FUShmb29fICwgc2VydmljZV8gLT5GaW5kTWV0aG9kQnlOYW1lKCJGb28iKSk7CisgIEVYUEVDVF9FUShiYXJfICwgc2VydmljZV8gLT5GaW5kTWV0aG9kQnlOYW1lKCJCYXIiKSk7CisgIEVYUEVDVF9FUShmb28yXywgc2VydmljZTJfLT5GaW5kTWV0aG9kQnlOYW1lKCJGb28iKSk7CisgIEVYUEVDVF9FUShiYXoyXywgc2VydmljZTJfLT5GaW5kTWV0aG9kQnlOYW1lKCJCYXoiKSk7CisKKyAgRVhQRUNUX1RSVUUoc2VydmljZV8gLT5GaW5kTWV0aG9kQnlOYW1lKCJOb1N1Y2hNZXRob2QiKSA9PSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUoc2VydmljZV8gLT5GaW5kTWV0aG9kQnlOYW1lKCJCYXoiICAgICAgICAgKSA9PSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUoc2VydmljZTJfLT5GaW5kTWV0aG9kQnlOYW1lKCJCYXIiICAgICAgICAgKSA9PSBOVUxMKTsKK30KKworVEVTVF9GKFNlcnZpY2VEZXNjcmlwdG9yVGVzdCwgTWV0aG9kTmFtZSkgeworICBFWFBFQ1RfRVEoIkZvbyIsIGZvb18tPm5hbWUoKSk7CisgIEVYUEVDVF9FUSgiQmFyIiwgYmFyXy0+bmFtZSgpKTsKK30KKworVEVTVF9GKFNlcnZpY2VEZXNjcmlwdG9yVGVzdCwgTWV0aG9kRnVsbE5hbWUpIHsKKyAgRVhQRUNUX0VRKCJUZXN0U2VydmljZS5Gb28iLCBmb29fLT5mdWxsX25hbWUoKSk7CisgIEVYUEVDVF9FUSgiVGVzdFNlcnZpY2UuQmFyIiwgYmFyXy0+ZnVsbF9uYW1lKCkpOworICBFWFBFQ1RfRVEoImNvcmdlLmdyYXVsdC5UZXN0U2VydmljZTIuRm9vIiwgZm9vMl8tPmZ1bGxfbmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJjb3JnZS5ncmF1bHQuVGVzdFNlcnZpY2UyLkJheiIsIGJhejJfLT5mdWxsX25hbWUoKSk7Cit9CisKK1RFU1RfRihTZXJ2aWNlRGVzY3JpcHRvclRlc3QsIE1ldGhvZEluZGV4KSB7CisgIEVYUEVDVF9FUSgwLCBmb29fLT5pbmRleCgpKTsKKyAgRVhQRUNUX0VRKDEsIGJhcl8tPmluZGV4KCkpOworfQorCitURVNUX0YoU2VydmljZURlc2NyaXB0b3JUZXN0LCBNZXRob2RQYXJlbnQpIHsKKyAgRVhQRUNUX0VRKHNlcnZpY2VfLCBmb29fLT5zZXJ2aWNlKCkpOworICBFWFBFQ1RfRVEoc2VydmljZV8sIGJhcl8tPnNlcnZpY2UoKSk7Cit9CisKK1RFU1RfRihTZXJ2aWNlRGVzY3JpcHRvclRlc3QsIE1ldGhvZElucHV0VHlwZSkgeworICBFWFBFQ1RfRVEoZm9vX3JlcXVlc3RfLCBmb29fLT5pbnB1dF90eXBlKCkpOworICBFWFBFQ1RfRVEoYmFyX3JlcXVlc3RfLCBiYXJfLT5pbnB1dF90eXBlKCkpOworfQorCitURVNUX0YoU2VydmljZURlc2NyaXB0b3JUZXN0LCBNZXRob2RPdXRwdXRUeXBlKSB7CisgIEVYUEVDVF9FUShmb29fcmVzcG9uc2VfLCBmb29fLT5vdXRwdXRfdHlwZSgpKTsKKyAgRVhQRUNUX0VRKGJhcl9yZXNwb25zZV8sIGJhcl8tPm91dHB1dF90eXBlKCkpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKy8vIFRlc3QgbmVzdGVkIHR5cGVzLgorY2xhc3MgTmVzdGVkRGVzY3JpcHRvclRlc3QgOiBwdWJsaWMgdGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICB2aXJ0dWFsIHZvaWQgU2V0VXAoKSB7CisgICAgLy8gQnVpbGQgZGVzY3JpcHRvcnMgZm9yIHRoZSBmb2xsb3dpbmcgZGVmaW5pdGlvbnM6CisgICAgLy8KKyAgICAvLyAgIC8vIGluICJmb28ucHJvdG8iCisgICAgLy8gICBtZXNzYWdlIFRlc3RNZXNzYWdlIHsKKyAgICAvLyAgICAgbWVzc2FnZSBGb28ge30KKyAgICAvLyAgICAgbWVzc2FnZSBCYXIge30KKyAgICAvLyAgICAgZW51bSBCYXogeyBBID0gMTsgfQorICAgIC8vICAgICBlbnVtIFF1eCB7IEIgPSAxOyB9CisgICAgLy8gICB9CisgICAgLy8KKyAgICAvLyAgIC8vIGluICJiYXIucHJvdG8iCisgICAgLy8gICBwYWNrYWdlIGNvcmdlLmdyYXVsdDsKKyAgICAvLyAgIG1lc3NhZ2UgVGVzdE1lc3NhZ2UyIHsKKyAgICAvLyAgICAgbWVzc2FnZSBGb28ge30KKyAgICAvLyAgICAgbWVzc2FnZSBCYXoge30KKyAgICAvLyAgICAgZW51bSBRdXggIHsgQSA9IDE7IH0KKyAgICAvLyAgICAgZW51bSBRdXV4IHsgQyA9IDE7IH0KKyAgICAvLyAgIH0KKyAgICAvLworICAgIC8vIFRlc3RNZXNzYWdlMiBpcyBwcmltYXJpbHkgaGVyZSB0byB0ZXN0IEZpbmROZXN0ZWRUeXBlQnlOYW1lIGFuZCBmcmllbmRzLgorICAgIC8vIEFsbCBtZXNzYWdlcyBjcmVhdGVkIGZyb20gdGhlIHNhbWUgRGVzY3JpcHRvclBvb2wgc2hhcmUgdGhlIHNhbWUgbG9va3VwCisgICAgLy8gdGFibGUsIHNvIHdlIG5lZWQgdG8gaW5zdXJlIHRoYXQgdGhleSBkb24ndCBpbnRlcmZlcmUuCisgICAgLy8KKyAgICAvLyBXZSBhZGQgZW51bSB2YWx1ZXMgdG8gdGhlIGVudW1zIGluIG9yZGVyIHRvIHRlc3Qgc2VhcmNoaW5nIGZvciBlbnVtCisgICAgLy8gdmFsdWVzIGFjcm9zcyBhIG1lc3NhZ2UncyBzY29wZS4KKworICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZm9vX2ZpbGU7CisgICAgZm9vX2ZpbGUuc2V0X25hbWUoImZvby5wcm90byIpOworCisgICAgRGVzY3JpcHRvclByb3RvKiBtZXNzYWdlID0gQWRkTWVzc2FnZSgmZm9vX2ZpbGUsICJUZXN0TWVzc2FnZSIpOworICAgIEFkZE5lc3RlZE1lc3NhZ2UobWVzc2FnZSwgIkZvbyIpOworICAgIEFkZE5lc3RlZE1lc3NhZ2UobWVzc2FnZSwgIkJhciIpOworICAgIEVudW1EZXNjcmlwdG9yUHJvdG8qIGJheiA9IEFkZE5lc3RlZEVudW0obWVzc2FnZSwgIkJheiIpOworICAgIEFkZEVudW1WYWx1ZShiYXosICJBIiwgMSk7CisgICAgRW51bURlc2NyaXB0b3JQcm90byogcXV4ID0gQWRkTmVzdGVkRW51bShtZXNzYWdlLCAiUXV4Iik7CisgICAgQWRkRW51bVZhbHVlKHF1eCwgIkIiLCAxKTsKKworICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gYmFyX2ZpbGU7CisgICAgYmFyX2ZpbGUuc2V0X25hbWUoImJhci5wcm90byIpOworICAgIGJhcl9maWxlLnNldF9wYWNrYWdlKCJjb3JnZS5ncmF1bHQiKTsKKworICAgIERlc2NyaXB0b3JQcm90byogbWVzc2FnZTIgPSBBZGRNZXNzYWdlKCZiYXJfZmlsZSwgIlRlc3RNZXNzYWdlMiIpOworICAgIEFkZE5lc3RlZE1lc3NhZ2UobWVzc2FnZTIsICJGb28iKTsKKyAgICBBZGROZXN0ZWRNZXNzYWdlKG1lc3NhZ2UyLCAiQmF6Iik7CisgICAgRW51bURlc2NyaXB0b3JQcm90byogcXV4MiA9IEFkZE5lc3RlZEVudW0obWVzc2FnZTIsICJRdXgiKTsKKyAgICBBZGRFbnVtVmFsdWUocXV4MiwgIkEiLCAxKTsKKyAgICBFbnVtRGVzY3JpcHRvclByb3RvKiBxdXV4MiA9IEFkZE5lc3RlZEVudW0obWVzc2FnZTIsICJRdXV4Iik7CisgICAgQWRkRW51bVZhbHVlKHF1dXgyLCAiQyIsIDEpOworCisgICAgLy8gQnVpbGQgdGhlIGRlc2NyaXB0b3JzIGFuZCBnZXQgdGhlIHBvaW50ZXJzLgorICAgIGZvb19maWxlXyA9IHBvb2xfLkJ1aWxkRmlsZShmb29fZmlsZSk7CisgICAgQVNTRVJUX1RSVUUoZm9vX2ZpbGVfICE9IE5VTEwpOworCisgICAgYmFyX2ZpbGVfID0gcG9vbF8uQnVpbGRGaWxlKGJhcl9maWxlKTsKKyAgICBBU1NFUlRfVFJVRShiYXJfZmlsZV8gIT0gTlVMTCk7CisKKyAgICBBU1NFUlRfRVEoMSwgZm9vX2ZpbGVfLT5tZXNzYWdlX3R5cGVfY291bnQoKSk7CisgICAgbWVzc2FnZV8gPSBmb29fZmlsZV8tPm1lc3NhZ2VfdHlwZSgwKTsKKworICAgIEFTU0VSVF9FUSgyLCBtZXNzYWdlXy0+bmVzdGVkX3R5cGVfY291bnQoKSk7CisgICAgZm9vXyA9IG1lc3NhZ2VfLT5uZXN0ZWRfdHlwZSgwKTsKKyAgICBiYXJfID0gbWVzc2FnZV8tPm5lc3RlZF90eXBlKDEpOworCisgICAgQVNTRVJUX0VRKDIsIG1lc3NhZ2VfLT5lbnVtX3R5cGVfY291bnQoKSk7CisgICAgYmF6XyA9IG1lc3NhZ2VfLT5lbnVtX3R5cGUoMCk7CisgICAgcXV4XyA9IG1lc3NhZ2VfLT5lbnVtX3R5cGUoMSk7CisKKyAgICBBU1NFUlRfRVEoMSwgYmF6Xy0+dmFsdWVfY291bnQoKSk7CisgICAgYV8gPSBiYXpfLT52YWx1ZSgwKTsKKyAgICBBU1NFUlRfRVEoMSwgcXV4Xy0+dmFsdWVfY291bnQoKSk7CisgICAgYl8gPSBxdXhfLT52YWx1ZSgwKTsKKworICAgIEFTU0VSVF9FUSgxLCBiYXJfZmlsZV8tPm1lc3NhZ2VfdHlwZV9jb3VudCgpKTsKKyAgICBtZXNzYWdlMl8gPSBiYXJfZmlsZV8tPm1lc3NhZ2VfdHlwZSgwKTsKKworICAgIEFTU0VSVF9FUSgyLCBtZXNzYWdlMl8tPm5lc3RlZF90eXBlX2NvdW50KCkpOworICAgIGZvbzJfID0gbWVzc2FnZTJfLT5uZXN0ZWRfdHlwZSgwKTsKKyAgICBiYXoyXyA9IG1lc3NhZ2UyXy0+bmVzdGVkX3R5cGUoMSk7CisKKyAgICBBU1NFUlRfRVEoMiwgbWVzc2FnZTJfLT5lbnVtX3R5cGVfY291bnQoKSk7CisgICAgcXV4Ml8gPSBtZXNzYWdlMl8tPmVudW1fdHlwZSgwKTsKKyAgICBxdXV4Ml8gPSBtZXNzYWdlMl8tPmVudW1fdHlwZSgxKTsKKworICAgIEFTU0VSVF9FUSgxLCBxdXgyXy0+dmFsdWVfY291bnQoKSk7CisgICAgYTJfID0gcXV4Ml8tPnZhbHVlKDApOworICAgIEFTU0VSVF9FUSgxLCBxdXV4Ml8tPnZhbHVlX2NvdW50KCkpOworICAgIGMyXyA9IHF1dXgyXy0+dmFsdWUoMCk7CisgIH0KKworICBEZXNjcmlwdG9yUG9vbCBwb29sXzsKKworICBjb25zdCBGaWxlRGVzY3JpcHRvciogZm9vX2ZpbGVfOworICBjb25zdCBGaWxlRGVzY3JpcHRvciogYmFyX2ZpbGVfOworCisgIGNvbnN0IERlc2NyaXB0b3IqIG1lc3NhZ2VfOworICBjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlMl87CisKKyAgY29uc3QgRGVzY3JpcHRvciogZm9vXzsKKyAgY29uc3QgRGVzY3JpcHRvciogYmFyXzsKKyAgY29uc3QgRW51bURlc2NyaXB0b3IqIGJhel87CisgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBxdXhfOworICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBhXzsKKyAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogYl87CisKKyAgY29uc3QgRGVzY3JpcHRvciogZm9vMl87CisgIGNvbnN0IERlc2NyaXB0b3IqIGJhejJfOworICBjb25zdCBFbnVtRGVzY3JpcHRvciogcXV4Ml87CisgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBxdXV4Ml87CisgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIGEyXzsKKyAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogYzJfOworfTsKKworVEVTVF9GKE5lc3RlZERlc2NyaXB0b3JUZXN0LCBNZXNzYWdlTmFtZSkgeworICBFWFBFQ1RfRVEoIkZvbyIsIGZvb18gLT5uYW1lKCkpOworICBFWFBFQ1RfRVEoIkJhciIsIGJhcl8gLT5uYW1lKCkpOworICBFWFBFQ1RfRVEoIkZvbyIsIGZvbzJfLT5uYW1lKCkpOworICBFWFBFQ1RfRVEoIkJheiIsIGJhejJfLT5uYW1lKCkpOworCisgIEVYUEVDVF9FUSgiVGVzdE1lc3NhZ2UuRm9vIiwgZm9vXy0+ZnVsbF9uYW1lKCkpOworICBFWFBFQ1RfRVEoIlRlc3RNZXNzYWdlLkJhciIsIGJhcl8tPmZ1bGxfbmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJjb3JnZS5ncmF1bHQuVGVzdE1lc3NhZ2UyLkZvbyIsIGZvbzJfLT5mdWxsX25hbWUoKSk7CisgIEVYUEVDVF9FUSgiY29yZ2UuZ3JhdWx0LlRlc3RNZXNzYWdlMi5CYXoiLCBiYXoyXy0+ZnVsbF9uYW1lKCkpOworfQorCitURVNUX0YoTmVzdGVkRGVzY3JpcHRvclRlc3QsIE1lc3NhZ2VDb250YWluaW5nVHlwZSkgeworICBFWFBFQ1RfRVEobWVzc2FnZV8gLCBmb29fIC0+Y29udGFpbmluZ190eXBlKCkpOworICBFWFBFQ1RfRVEobWVzc2FnZV8gLCBiYXJfIC0+Y29udGFpbmluZ190eXBlKCkpOworICBFWFBFQ1RfRVEobWVzc2FnZTJfLCBmb28yXy0+Y29udGFpbmluZ190eXBlKCkpOworICBFWFBFQ1RfRVEobWVzc2FnZTJfLCBiYXoyXy0+Y29udGFpbmluZ190eXBlKCkpOworfQorCitURVNUX0YoTmVzdGVkRGVzY3JpcHRvclRlc3QsIE5lc3RlZE1lc3NhZ2VzQnlJbmRleCkgeworICBBU1NFUlRfRVEoMiwgbWVzc2FnZV8tPm5lc3RlZF90eXBlX2NvdW50KCkpOworICBFWFBFQ1RfRVEoZm9vXywgbWVzc2FnZV8tPm5lc3RlZF90eXBlKDApKTsKKyAgRVhQRUNUX0VRKGJhcl8sIG1lc3NhZ2VfLT5uZXN0ZWRfdHlwZSgxKSk7Cit9CisKK1RFU1RfRihOZXN0ZWREZXNjcmlwdG9yVGVzdCwgRmluZEZpZWxkQnlOYW1lRG9lc250RmluZE5lc3RlZFR5cGVzKSB7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2VfLT5GaW5kRmllbGRCeU5hbWUoIkZvbyIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlXy0+RmluZEZpZWxkQnlOYW1lKCJRdXgiKSA9PSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZV8tPkZpbmRFeHRlbnNpb25CeU5hbWUoIkZvbyIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlXy0+RmluZEV4dGVuc2lvbkJ5TmFtZSgiUXV4IikgPT0gTlVMTCk7Cit9CisKK1RFU1RfRihOZXN0ZWREZXNjcmlwdG9yVGVzdCwgRmluZE5lc3RlZFR5cGVCeU5hbWUpIHsKKyAgRVhQRUNUX0VRKGZvb18gLCBtZXNzYWdlXyAtPkZpbmROZXN0ZWRUeXBlQnlOYW1lKCJGb28iKSk7CisgIEVYUEVDVF9FUShiYXJfICwgbWVzc2FnZV8gLT5GaW5kTmVzdGVkVHlwZUJ5TmFtZSgiQmFyIikpOworICBFWFBFQ1RfRVEoZm9vMl8sIG1lc3NhZ2UyXy0+RmluZE5lc3RlZFR5cGVCeU5hbWUoIkZvbyIpKTsKKyAgRVhQRUNUX0VRKGJhejJfLCBtZXNzYWdlMl8tPkZpbmROZXN0ZWRUeXBlQnlOYW1lKCJCYXoiKSk7CisKKyAgRVhQRUNUX1RSVUUobWVzc2FnZV8gLT5GaW5kTmVzdGVkVHlwZUJ5TmFtZSgiTm9TdWNoVHlwZSIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlXyAtPkZpbmROZXN0ZWRUeXBlQnlOYW1lKCJCYXoiICAgICAgICkgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UyXy0+RmluZE5lc3RlZFR5cGVCeU5hbWUoIkJhciIgICAgICAgKSA9PSBOVUxMKTsKKworICBFWFBFQ1RfVFJVRShtZXNzYWdlXy0+RmluZE5lc3RlZFR5cGVCeU5hbWUoIlF1eCIpID09IE5VTEwpOworfQorCitURVNUX0YoTmVzdGVkRGVzY3JpcHRvclRlc3QsIEVudW1OYW1lKSB7CisgIEVYUEVDVF9FUSgiQmF6IiAsIGJhel8gLT5uYW1lKCkpOworICBFWFBFQ1RfRVEoIlF1eCIgLCBxdXhfIC0+bmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJRdXgiICwgcXV4Ml8tPm5hbWUoKSk7CisgIEVYUEVDVF9FUSgiUXV1eCIsIHF1dXgyXy0+bmFtZSgpKTsKKworICBFWFBFQ1RfRVEoIlRlc3RNZXNzYWdlLkJheiIsIGJhel8tPmZ1bGxfbmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJUZXN0TWVzc2FnZS5RdXgiLCBxdXhfLT5mdWxsX25hbWUoKSk7CisgIEVYUEVDVF9FUSgiY29yZ2UuZ3JhdWx0LlRlc3RNZXNzYWdlMi5RdXgiICwgcXV4Ml8gLT5mdWxsX25hbWUoKSk7CisgIEVYUEVDVF9FUSgiY29yZ2UuZ3JhdWx0LlRlc3RNZXNzYWdlMi5RdXV4IiwgcXV1eDJfLT5mdWxsX25hbWUoKSk7Cit9CisKK1RFU1RfRihOZXN0ZWREZXNjcmlwdG9yVGVzdCwgRW51bUNvbnRhaW5pbmdUeXBlKSB7CisgIEVYUEVDVF9FUShtZXNzYWdlXyAsIGJhel8gIC0+Y29udGFpbmluZ190eXBlKCkpOworICBFWFBFQ1RfRVEobWVzc2FnZV8gLCBxdXhfICAtPmNvbnRhaW5pbmdfdHlwZSgpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UyXywgcXV4Ml8gLT5jb250YWluaW5nX3R5cGUoKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlMl8sIHF1dXgyXy0+Y29udGFpbmluZ190eXBlKCkpOworfQorCitURVNUX0YoTmVzdGVkRGVzY3JpcHRvclRlc3QsIE5lc3RlZEVudW1zQnlJbmRleCkgeworICBBU1NFUlRfRVEoMiwgbWVzc2FnZV8tPm5lc3RlZF90eXBlX2NvdW50KCkpOworICBFWFBFQ1RfRVEoZm9vXywgbWVzc2FnZV8tPm5lc3RlZF90eXBlKDApKTsKKyAgRVhQRUNUX0VRKGJhcl8sIG1lc3NhZ2VfLT5uZXN0ZWRfdHlwZSgxKSk7Cit9CisKK1RFU1RfRihOZXN0ZWREZXNjcmlwdG9yVGVzdCwgRmluZEVudW1UeXBlQnlOYW1lKSB7CisgIEVYUEVDVF9FUShiYXpfICAsIG1lc3NhZ2VfIC0+RmluZEVudW1UeXBlQnlOYW1lKCJCYXoiICkpOworICBFWFBFQ1RfRVEocXV4XyAgLCBtZXNzYWdlXyAtPkZpbmRFbnVtVHlwZUJ5TmFtZSgiUXV4IiApKTsKKyAgRVhQRUNUX0VRKHF1eDJfICwgbWVzc2FnZTJfLT5GaW5kRW51bVR5cGVCeU5hbWUoIlF1eCIgKSk7CisgIEVYUEVDVF9FUShxdXV4Ml8sIG1lc3NhZ2UyXy0+RmluZEVudW1UeXBlQnlOYW1lKCJRdXV4IikpOworCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2VfIC0+RmluZEVudW1UeXBlQnlOYW1lKCJOb1N1Y2hUeXBlIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2VfIC0+RmluZEVudW1UeXBlQnlOYW1lKCJRdXV4IiAgICAgICkgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UyXy0+RmluZEVudW1UeXBlQnlOYW1lKCJCYXoiICAgICAgICkgPT0gTlVMTCk7CisKKyAgRVhQRUNUX1RSVUUobWVzc2FnZV8tPkZpbmRFbnVtVHlwZUJ5TmFtZSgiRm9vIikgPT0gTlVMTCk7Cit9CisKK1RFU1RfRihOZXN0ZWREZXNjcmlwdG9yVGVzdCwgRmluZEVudW1WYWx1ZUJ5TmFtZSkgeworICBFWFBFQ1RfRVEoYV8gLCBtZXNzYWdlXyAtPkZpbmRFbnVtVmFsdWVCeU5hbWUoIkEiKSk7CisgIEVYUEVDVF9FUShiXyAsIG1lc3NhZ2VfIC0+RmluZEVudW1WYWx1ZUJ5TmFtZSgiQiIpKTsKKyAgRVhQRUNUX0VRKGEyXywgbWVzc2FnZTJfLT5GaW5kRW51bVZhbHVlQnlOYW1lKCJBIikpOworICBFWFBFQ1RfRVEoYzJfLCBtZXNzYWdlMl8tPkZpbmRFbnVtVmFsdWVCeU5hbWUoIkMiKSk7CisKKyAgRVhQRUNUX1RSVUUobWVzc2FnZV8gLT5GaW5kRW51bVZhbHVlQnlOYW1lKCJOT19TVUNIX1ZBTFVFIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2VfIC0+RmluZEVudW1WYWx1ZUJ5TmFtZSgiQyIgICAgICAgICAgICApID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlMl8tPkZpbmRFbnVtVmFsdWVCeU5hbWUoIkIiICAgICAgICAgICAgKSA9PSBOVUxMKTsKKworICBFWFBFQ1RfVFJVRShtZXNzYWdlXy0+RmluZEVudW1WYWx1ZUJ5TmFtZSgiRm9vIikgPT0gTlVMTCk7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworLy8gVGVzdCBleHRlbnNpb25zLgorY2xhc3MgRXh0ZW5zaW9uRGVzY3JpcHRvclRlc3QgOiBwdWJsaWMgdGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICB2aXJ0dWFsIHZvaWQgU2V0VXAoKSB7CisgICAgLy8gQnVpbGQgZGVzY3JpcHRvcnMgZm9yIHRoZSBmb2xsb3dpbmcgZGVmaW5pdGlvbnM6CisgICAgLy8KKyAgICAvLyAgIGVudW0gQmF6IHt9CisgICAgLy8gICBtZXNzYWdlIFF1eCB7fQorICAgIC8vCisgICAgLy8gICBtZXNzYWdlIEZvbyB7CisgICAgLy8gICAgIGV4dGVuc2lvbnMgMTAgdG8gMTk7CisgICAgLy8gICAgIGV4dGVuc2lvbnMgMzAgdG8gMzk7CisgICAgLy8gICB9CisgICAgLy8gICBleHRlbmRzIEZvbyB3aXRoIG9wdGlvbmFsIGludDMyIGZvb19pbnQzMiA9IDEwOworICAgIC8vICAgZXh0ZW5kcyBGb28gd2l0aCByZXBlYXRlZCBUZXN0RW51bSBmb29fZW51bSA9IDE5OworICAgIC8vICAgbWVzc2FnZSBCYXIgeworICAgIC8vICAgICBleHRlbmRzIEZvbyB3aXRoIG9wdGlvbmFsIFF1eCBmb29fbWVzc2FnZSA9IDMwOworICAgIC8vICAgICAvLyAodXNpbmcgUXV4IGFzIHRoZSBncm91cCB0eXBlKQorICAgIC8vICAgICBleHRlbmRzIEZvbyB3aXRoIHJlcGVhdGVkIGdyb3VwIGZvb19ncm91cCA9IDM5OworICAgIC8vICAgfQorCisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmb29fZmlsZTsKKyAgICBmb29fZmlsZS5zZXRfbmFtZSgiZm9vLnByb3RvIik7CisKKyAgICBBZGRFbXB0eUVudW0oJmZvb19maWxlLCAiQmF6Iik7CisgICAgQWRkTWVzc2FnZSgmZm9vX2ZpbGUsICJRdXgiKTsKKworICAgIERlc2NyaXB0b3JQcm90byogZm9vID0gQWRkTWVzc2FnZSgmZm9vX2ZpbGUsICJGb28iKTsKKyAgICBBZGRFeHRlbnNpb25SYW5nZShmb28sIDEwLCAyMCk7CisgICAgQWRkRXh0ZW5zaW9uUmFuZ2UoZm9vLCAzMCwgNDApOworCisgICAgQWRkRXh0ZW5zaW9uKCZmb29fZmlsZSwgIkZvbyIsICJmb29faW50MzIiLCAxMCwKKyAgICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX09QVElPTkFMLAorICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9JTlQzMik7CisgICAgQWRkRXh0ZW5zaW9uKCZmb29fZmlsZSwgIkZvbyIsICJmb29fZW51bSIsIDE5LAorICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfUkVQRUFURUQsCisgICAgICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0VOVU0pCisgICAgICAtPnNldF90eXBlX25hbWUoIkJheiIpOworCisgICAgRGVzY3JpcHRvclByb3RvKiBiYXIgPSBBZGRNZXNzYWdlKCZmb29fZmlsZSwgIkJhciIpOworICAgIEFkZE5lc3RlZEV4dGVuc2lvbihiYXIsICJGb28iLCAiZm9vX21lc3NhZ2UiLCAzMCwKKyAgICAgICAgICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX09QVElPTkFMLAorICAgICAgICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9NRVNTQUdFKQorICAgICAgLT5zZXRfdHlwZV9uYW1lKCJRdXgiKTsKKyAgICBBZGROZXN0ZWRFeHRlbnNpb24oYmFyLCAiRm9vIiwgImZvb19ncm91cCIsIDM5LAorICAgICAgICAgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfUkVQRUFURUQsCisgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0dST1VQKQorICAgICAgLT5zZXRfdHlwZV9uYW1lKCJRdXgiKTsKKworICAgIC8vIEJ1aWxkIHRoZSBkZXNjcmlwdG9ycyBhbmQgZ2V0IHRoZSBwb2ludGVycy4KKyAgICBmb29fZmlsZV8gPSBwb29sXy5CdWlsZEZpbGUoZm9vX2ZpbGUpOworICAgIEFTU0VSVF9UUlVFKGZvb19maWxlXyAhPSBOVUxMKTsKKworICAgIEFTU0VSVF9FUSgxLCBmb29fZmlsZV8tPmVudW1fdHlwZV9jb3VudCgpKTsKKyAgICBiYXpfID0gZm9vX2ZpbGVfLT5lbnVtX3R5cGUoMCk7CisKKyAgICBBU1NFUlRfRVEoMywgZm9vX2ZpbGVfLT5tZXNzYWdlX3R5cGVfY291bnQoKSk7CisgICAgcXV4XyA9IGZvb19maWxlXy0+bWVzc2FnZV90eXBlKDApOworICAgIGZvb18gPSBmb29fZmlsZV8tPm1lc3NhZ2VfdHlwZSgxKTsKKyAgICBiYXJfID0gZm9vX2ZpbGVfLT5tZXNzYWdlX3R5cGUoMik7CisgIH0KKworICBEZXNjcmlwdG9yUG9vbCBwb29sXzsKKworICBjb25zdCBGaWxlRGVzY3JpcHRvciogZm9vX2ZpbGVfOworCisgIGNvbnN0IERlc2NyaXB0b3IqIGZvb187CisgIGNvbnN0IERlc2NyaXB0b3IqIGJhcl87CisgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBiYXpfOworICBjb25zdCBEZXNjcmlwdG9yKiBxdXhfOworfTsKKworVEVTVF9GKEV4dGVuc2lvbkRlc2NyaXB0b3JUZXN0LCBFeHRlbnNpb25SYW5nZXMpIHsKKyAgRVhQRUNUX0VRKDAsIGJhcl8tPmV4dGVuc2lvbl9yYW5nZV9jb3VudCgpKTsKKyAgQVNTRVJUX0VRKDIsIGZvb18tPmV4dGVuc2lvbl9yYW5nZV9jb3VudCgpKTsKKworICBFWFBFQ1RfRVEoMTAsIGZvb18tPmV4dGVuc2lvbl9yYW5nZSgwKS0+c3RhcnQpOworICBFWFBFQ1RfRVEoMzAsIGZvb18tPmV4dGVuc2lvbl9yYW5nZSgxKS0+c3RhcnQpOworCisgIEVYUEVDVF9FUSgyMCwgZm9vXy0+ZXh0ZW5zaW9uX3JhbmdlKDApLT5lbmQpOworICBFWFBFQ1RfRVEoNDAsIGZvb18tPmV4dGVuc2lvbl9yYW5nZSgxKS0+ZW5kKTsKK307CisKK1RFU1RfRihFeHRlbnNpb25EZXNjcmlwdG9yVGVzdCwgRXh0ZW5zaW9ucykgeworICBFWFBFQ1RfRVEoMCwgZm9vXy0+ZXh0ZW5zaW9uX2NvdW50KCkpOworICBBU1NFUlRfRVEoMiwgZm9vX2ZpbGVfLT5leHRlbnNpb25fY291bnQoKSk7CisgIEFTU0VSVF9FUSgyLCBiYXJfLT5leHRlbnNpb25fY291bnQoKSk7CisKKyAgRVhQRUNUX1RSVUUoZm9vX2ZpbGVfLT5leHRlbnNpb24oMCktPmlzX2V4dGVuc2lvbigpKTsKKyAgRVhQRUNUX1RSVUUoZm9vX2ZpbGVfLT5leHRlbnNpb24oMSktPmlzX2V4dGVuc2lvbigpKTsKKyAgRVhQRUNUX1RSVUUoYmFyXy0+ZXh0ZW5zaW9uKDApLT5pc19leHRlbnNpb24oKSk7CisgIEVYUEVDVF9UUlVFKGJhcl8tPmV4dGVuc2lvbigxKS0+aXNfZXh0ZW5zaW9uKCkpOworCisgIEVYUEVDVF9FUSgiZm9vX2ludDMyIiAgLCBmb29fZmlsZV8tPmV4dGVuc2lvbigwKS0+bmFtZSgpKTsKKyAgRVhQRUNUX0VRKCJmb29fZW51bSIgICAsIGZvb19maWxlXy0+ZXh0ZW5zaW9uKDEpLT5uYW1lKCkpOworICBFWFBFQ1RfRVEoImZvb19tZXNzYWdlIiwgYmFyXy0+ZXh0ZW5zaW9uKDApLT5uYW1lKCkpOworICBFWFBFQ1RfRVEoImZvb19ncm91cCIgICwgYmFyXy0+ZXh0ZW5zaW9uKDEpLT5uYW1lKCkpOworCisgIEVYUEVDVF9FUSgxMCwgZm9vX2ZpbGVfLT5leHRlbnNpb24oMCktPm51bWJlcigpKTsKKyAgRVhQRUNUX0VRKDE5LCBmb29fZmlsZV8tPmV4dGVuc2lvbigxKS0+bnVtYmVyKCkpOworICBFWFBFQ1RfRVEoMzAsIGJhcl8tPmV4dGVuc2lvbigwKS0+bnVtYmVyKCkpOworICBFWFBFQ1RfRVEoMzksIGJhcl8tPmV4dGVuc2lvbigxKS0+bnVtYmVyKCkpOworCisgIEVYUEVDVF9FUShGaWVsZERlc2NyaXB0b3I6OlRZUEVfSU5UMzIgICwgZm9vX2ZpbGVfLT5leHRlbnNpb24oMCktPnR5cGUoKSk7CisgIEVYUEVDVF9FUShGaWVsZERlc2NyaXB0b3I6OlRZUEVfRU5VTSAgICwgZm9vX2ZpbGVfLT5leHRlbnNpb24oMSktPnR5cGUoKSk7CisgIEVYUEVDVF9FUShGaWVsZERlc2NyaXB0b3I6OlRZUEVfTUVTU0FHRSwgYmFyXy0+ZXh0ZW5zaW9uKDApLT50eXBlKCkpOworICBFWFBFQ1RfRVEoRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQICAsIGJhcl8tPmV4dGVuc2lvbigxKS0+dHlwZSgpKTsKKworICBFWFBFQ1RfRVEoYmF6XywgZm9vX2ZpbGVfLT5leHRlbnNpb24oMSktPmVudW1fdHlwZSgpKTsKKyAgRVhQRUNUX0VRKHF1eF8sIGJhcl8tPmV4dGVuc2lvbigwKS0+bWVzc2FnZV90eXBlKCkpOworICBFWFBFQ1RfRVEocXV4XywgYmFyXy0+ZXh0ZW5zaW9uKDEpLT5tZXNzYWdlX3R5cGUoKSk7CisKKyAgRVhQRUNUX0VRKEZpZWxkRGVzY3JpcHRvcjo6TEFCRUxfT1BUSU9OQUwsIGZvb19maWxlXy0+ZXh0ZW5zaW9uKDApLT5sYWJlbCgpKTsKKyAgRVhQRUNUX0VRKEZpZWxkRGVzY3JpcHRvcjo6TEFCRUxfUkVQRUFURUQsIGZvb19maWxlXy0+ZXh0ZW5zaW9uKDEpLT5sYWJlbCgpKTsKKyAgRVhQRUNUX0VRKEZpZWxkRGVzY3JpcHRvcjo6TEFCRUxfT1BUSU9OQUwsIGJhcl8tPmV4dGVuc2lvbigwKS0+bGFiZWwoKSk7CisgIEVYUEVDVF9FUShGaWVsZERlc2NyaXB0b3I6OkxBQkVMX1JFUEVBVEVELCBiYXJfLT5leHRlbnNpb24oMSktPmxhYmVsKCkpOworCisgIEVYUEVDVF9FUShmb29fLCBmb29fZmlsZV8tPmV4dGVuc2lvbigwKS0+Y29udGFpbmluZ190eXBlKCkpOworICBFWFBFQ1RfRVEoZm9vXywgZm9vX2ZpbGVfLT5leHRlbnNpb24oMSktPmNvbnRhaW5pbmdfdHlwZSgpKTsKKyAgRVhQRUNUX0VRKGZvb18sIGJhcl8tPmV4dGVuc2lvbigwKS0+Y29udGFpbmluZ190eXBlKCkpOworICBFWFBFQ1RfRVEoZm9vXywgYmFyXy0+ZXh0ZW5zaW9uKDEpLT5jb250YWluaW5nX3R5cGUoKSk7CisKKyAgRVhQRUNUX1RSVUUoZm9vX2ZpbGVfLT5leHRlbnNpb24oMCktPmV4dGVuc2lvbl9zY29wZSgpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShmb29fZmlsZV8tPmV4dGVuc2lvbigxKS0+ZXh0ZW5zaW9uX3Njb3BlKCkgPT0gTlVMTCk7CisgIEVYUEVDVF9FUShiYXJfLCBiYXJfLT5leHRlbnNpb24oMCktPmV4dGVuc2lvbl9zY29wZSgpKTsKKyAgRVhQRUNUX0VRKGJhcl8sIGJhcl8tPmV4dGVuc2lvbigxKS0+ZXh0ZW5zaW9uX3Njb3BlKCkpOworfTsKKworVEVTVF9GKEV4dGVuc2lvbkRlc2NyaXB0b3JUZXN0LCBJc0V4dGVuc2lvbk51bWJlcikgeworICBFWFBFQ1RfRkFMU0UoZm9vXy0+SXNFeHRlbnNpb25OdW1iZXIoIDkpKTsKKyAgRVhQRUNUX1RSVUUgKGZvb18tPklzRXh0ZW5zaW9uTnVtYmVyKDEwKSk7CisgIEVYUEVDVF9UUlVFIChmb29fLT5Jc0V4dGVuc2lvbk51bWJlcigxOSkpOworICBFWFBFQ1RfRkFMU0UoZm9vXy0+SXNFeHRlbnNpb25OdW1iZXIoMjApKTsKKyAgRVhQRUNUX0ZBTFNFKGZvb18tPklzRXh0ZW5zaW9uTnVtYmVyKDI5KSk7CisgIEVYUEVDVF9UUlVFIChmb29fLT5Jc0V4dGVuc2lvbk51bWJlcigzMCkpOworICBFWFBFQ1RfVFJVRSAoZm9vXy0+SXNFeHRlbnNpb25OdW1iZXIoMzkpKTsKKyAgRVhQRUNUX0ZBTFNFKGZvb18tPklzRXh0ZW5zaW9uTnVtYmVyKDQwKSk7Cit9CisKK1RFU1RfRihFeHRlbnNpb25EZXNjcmlwdG9yVGVzdCwgRmluZEV4dGVuc2lvbkJ5TmFtZSkgeworICAvLyBOb3RlIHRoYXQgRmlsZURlc2NyaXB0b3I6OkZpbmRFeHRlbnNpb25CeU5hbWUoKSBpcyB0ZXN0ZWQgYnkKKyAgLy8gRmlsZURlc2NyaXB0b3JUZXN0LgorICBBU1NFUlRfRVEoMiwgYmFyXy0+ZXh0ZW5zaW9uX2NvdW50KCkpOworCisgIEVYUEVDVF9FUShiYXJfLT5leHRlbnNpb24oMCksIGJhcl8tPkZpbmRFeHRlbnNpb25CeU5hbWUoImZvb19tZXNzYWdlIikpOworICBFWFBFQ1RfRVEoYmFyXy0+ZXh0ZW5zaW9uKDEpLCBiYXJfLT5GaW5kRXh0ZW5zaW9uQnlOYW1lKCJmb29fZ3JvdXAiICApKTsKKworICBFWFBFQ1RfVFJVRShiYXJfLT5GaW5kRXh0ZW5zaW9uQnlOYW1lKCJub19zdWNoX2V4dGVuc2lvbiIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShmb29fLT5GaW5kRXh0ZW5zaW9uQnlOYW1lKCJmb29faW50MzIiKSA9PSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUoZm9vXy0+RmluZEV4dGVuc2lvbkJ5TmFtZSgiZm9vX21lc3NhZ2UiKSA9PSBOVUxMKTsKK30KKworVEVTVF9GKEV4dGVuc2lvbkRlc2NyaXB0b3JUZXN0LCBGaW5kQWxsRXh0ZW5zaW9ucykgeworICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4gZXh0ZW5zaW9uczsKKyAgcG9vbF8uRmluZEFsbEV4dGVuc2lvbnMoZm9vXywgJmV4dGVuc2lvbnMpOworICBBU1NFUlRfRVEoNCwgZXh0ZW5zaW9ucy5zaXplKCkpOworICBFWFBFQ1RfRVEoMTAsIGV4dGVuc2lvbnNbMF0tPm51bWJlcigpKTsKKyAgRVhQRUNUX0VRKDE5LCBleHRlbnNpb25zWzFdLT5udW1iZXIoKSk7CisgIEVYUEVDVF9FUSgzMCwgZXh0ZW5zaW9uc1syXS0+bnVtYmVyKCkpOworICBFWFBFQ1RfRVEoMzksIGV4dGVuc2lvbnNbM10tPm51bWJlcigpKTsKK30KKworVEVTVF9GKEV4dGVuc2lvbkRlc2NyaXB0b3JUZXN0LCBEdXBsaWNhdGVGaWVsZE51bWJlcikgeworICBEZXNjcmlwdG9yUG9vbCBwb29sOworICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGVfcHJvdG87CisgIC8vIEFkZCAiZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8iLgorICBGaWxlRGVzY3JpcHRvclByb3RvOjpkZXNjcmlwdG9yKCktPmZpbGUoKS0+Q29weVRvKCZmaWxlX3Byb3RvKTsKKyAgQVNTRVJUX1RSVUUocG9vbC5CdWlsZEZpbGUoZmlsZV9wcm90bykgIT0gTlVMTCk7CisgIC8vIEFkZCAiZm9vLnByb3RvIjoKKyAgLy8gICBpbXBvcnQgImdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvIjsKKyAgLy8gICBleHRlbmQgZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucyB7CisgIC8vICAgICBvcHRpb25hbCBpbnQzMiBvcHRpb24xID0gMTAwMDsKKyAgLy8gICB9CisgIGZpbGVfcHJvdG8uQ2xlYXIoKTsKKyAgZmlsZV9wcm90by5zZXRfbmFtZSgiZm9vLnByb3RvIik7CisgIGZpbGVfcHJvdG8uYWRkX2RlcGVuZGVuY3koImdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvIik7CisgIEFkZEV4dGVuc2lvbigmZmlsZV9wcm90bywgImdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMiLCAib3B0aW9uMSIsIDEwMDAsCisgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfT1BUSU9OQUwsCisgICAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9JTlQzMik7CisgIEFTU0VSVF9UUlVFKHBvb2wuQnVpbGRGaWxlKGZpbGVfcHJvdG8pICE9IE5VTEwpOworICAvLyBBZGQgImJhci5wcm90byI6CisgIC8vICAgaW1wb3J0ICJnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90byI7CisgIC8vICAgZXh0ZW5kIGdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMgeworICAvLyAgICAgb3B0aW9uYWwgaW50MzIgb3B0aW9uMiA9IDEwMDA7CisgIC8vICAgfQorICBmaWxlX3Byb3RvLkNsZWFyKCk7CisgIGZpbGVfcHJvdG8uc2V0X25hbWUoImJhci5wcm90byIpOworICBmaWxlX3Byb3RvLmFkZF9kZXBlbmRlbmN5KCJnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90byIpOworICBBZGRFeHRlbnNpb24oJmZpbGVfcHJvdG8sICJnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zIiwgIm9wdGlvbjIiLCAxMDAwLAorICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX09QVElPTkFMLAorICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfSU5UMzIpOworICAvLyBDdXJyZW50bHkgd2Ugb25seSBnZW5lcmF0ZSBhIHdhcm5pbmcgZm9yIGNvbmZsaWN0aW5nIGV4dGVuc2lvbiBudW1iZXJzLgorICAvLyBUT0RPKHhpYW9mZW5nKTogQ2hhbmdlIGl0IHRvIGFuIGVycm9yLgorICBBU1NFUlRfVFJVRShwb29sLkJ1aWxkRmlsZShmaWxlX3Byb3RvKSAhPSBOVUxMKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisvLyBUZXN0IHJlc2VydmVkIGZpZWxkcy4KK2NsYXNzIFJlc2VydmVkRGVzY3JpcHRvclRlc3QgOiBwdWJsaWMgdGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICB2aXJ0dWFsIHZvaWQgU2V0VXAoKSB7CisgICAgLy8gQnVpbGQgZGVzY3JpcHRvcnMgZm9yIHRoZSBmb2xsb3dpbmcgZGVmaW5pdGlvbnM6CisgICAgLy8KKyAgICAvLyAgIG1lc3NhZ2UgRm9vIHsKKyAgICAvLyAgICAgcmVzZXJ2ZWQgMiwgOSB0byAxMSwgMTU7CisgICAgLy8gICAgIHJlc2VydmVkICJmb28iLCAiYmFyIjsKKyAgICAvLyAgIH0KKworICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZm9vX2ZpbGU7CisgICAgZm9vX2ZpbGUuc2V0X25hbWUoImZvby5wcm90byIpOworCisgICAgRGVzY3JpcHRvclByb3RvKiBmb28gPSBBZGRNZXNzYWdlKCZmb29fZmlsZSwgIkZvbyIpOworICAgIEFkZFJlc2VydmVkUmFuZ2UoZm9vLCAyLCAzKTsKKyAgICBBZGRSZXNlcnZlZFJhbmdlKGZvbywgOSwgMTIpOworICAgIEFkZFJlc2VydmVkUmFuZ2UoZm9vLCAxNSwgMTYpOworCisgICAgZm9vLT5hZGRfcmVzZXJ2ZWRfbmFtZSgiZm9vIik7CisgICAgZm9vLT5hZGRfcmVzZXJ2ZWRfbmFtZSgiYmFyIik7CisKKyAgICAvLyBCdWlsZCB0aGUgZGVzY3JpcHRvcnMgYW5kIGdldCB0aGUgcG9pbnRlcnMuCisgICAgZm9vX2ZpbGVfID0gcG9vbF8uQnVpbGRGaWxlKGZvb19maWxlKTsKKyAgICBBU1NFUlRfVFJVRShmb29fZmlsZV8gIT0gTlVMTCk7CisKKyAgICBBU1NFUlRfRVEoMSwgZm9vX2ZpbGVfLT5tZXNzYWdlX3R5cGVfY291bnQoKSk7CisgICAgZm9vXyA9IGZvb19maWxlXy0+bWVzc2FnZV90eXBlKDApOworICB9CisKKyAgRGVzY3JpcHRvclBvb2wgcG9vbF87CisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmb29fZmlsZV87CisgIGNvbnN0IERlc2NyaXB0b3IqIGZvb187Cit9OworCitURVNUX0YoUmVzZXJ2ZWREZXNjcmlwdG9yVGVzdCwgUmVzZXJ2ZWRSYW5nZXMpIHsKKyAgQVNTRVJUX0VRKDMsIGZvb18tPnJlc2VydmVkX3JhbmdlX2NvdW50KCkpOworCisgIEVYUEVDVF9FUSgyLCBmb29fLT5yZXNlcnZlZF9yYW5nZSgwKS0+c3RhcnQpOworICBFWFBFQ1RfRVEoMywgZm9vXy0+cmVzZXJ2ZWRfcmFuZ2UoMCktPmVuZCk7CisKKyAgRVhQRUNUX0VRKDksIGZvb18tPnJlc2VydmVkX3JhbmdlKDEpLT5zdGFydCk7CisgIEVYUEVDVF9FUSgxMiwgZm9vXy0+cmVzZXJ2ZWRfcmFuZ2UoMSktPmVuZCk7CisKKyAgRVhQRUNUX0VRKDE1LCBmb29fLT5yZXNlcnZlZF9yYW5nZSgyKS0+c3RhcnQpOworICBFWFBFQ1RfRVEoMTYsIGZvb18tPnJlc2VydmVkX3JhbmdlKDIpLT5lbmQpOworfTsKKworVEVTVF9GKFJlc2VydmVkRGVzY3JpcHRvclRlc3QsIElzUmVzZXJ2ZWROdW1iZXIpIHsKKyAgRVhQRUNUX0ZBTFNFKGZvb18tPklzUmVzZXJ2ZWROdW1iZXIoMSkpOworICBFWFBFQ1RfVFJVRSAoZm9vXy0+SXNSZXNlcnZlZE51bWJlcigyKSk7CisgIEVYUEVDVF9GQUxTRShmb29fLT5Jc1Jlc2VydmVkTnVtYmVyKDMpKTsKKyAgRVhQRUNUX0ZBTFNFKGZvb18tPklzUmVzZXJ2ZWROdW1iZXIoOCkpOworICBFWFBFQ1RfVFJVRSAoZm9vXy0+SXNSZXNlcnZlZE51bWJlcig5KSk7CisgIEVYUEVDVF9UUlVFIChmb29fLT5Jc1Jlc2VydmVkTnVtYmVyKDEwKSk7CisgIEVYUEVDVF9UUlVFIChmb29fLT5Jc1Jlc2VydmVkTnVtYmVyKDExKSk7CisgIEVYUEVDVF9GQUxTRShmb29fLT5Jc1Jlc2VydmVkTnVtYmVyKDEyKSk7CisgIEVYUEVDVF9GQUxTRShmb29fLT5Jc1Jlc2VydmVkTnVtYmVyKDEzKSk7CisgIEVYUEVDVF9GQUxTRShmb29fLT5Jc1Jlc2VydmVkTnVtYmVyKDE0KSk7CisgIEVYUEVDVF9UUlVFIChmb29fLT5Jc1Jlc2VydmVkTnVtYmVyKDE1KSk7CisgIEVYUEVDVF9GQUxTRShmb29fLT5Jc1Jlc2VydmVkTnVtYmVyKDE2KSk7Cit9OworCitURVNUX0YoUmVzZXJ2ZWREZXNjcmlwdG9yVGVzdCwgUmVzZXJ2ZWROYW1lcykgeworICBBU1NFUlRfRVEoMiwgZm9vXy0+cmVzZXJ2ZWRfbmFtZV9jb3VudCgpKTsKKworICBFWFBFQ1RfRVEoImZvbyIsIGZvb18tPnJlc2VydmVkX25hbWUoMCkpOworICBFWFBFQ1RfRVEoImJhciIsIGZvb18tPnJlc2VydmVkX25hbWUoMSkpOworfTsKKworVEVTVF9GKFJlc2VydmVkRGVzY3JpcHRvclRlc3QsIElzUmVzZXJ2ZWROYW1lKSB7CisgIEVYUEVDVF9UUlVFIChmb29fLT5Jc1Jlc2VydmVkTmFtZSgiZm9vIikpOworICBFWFBFQ1RfVFJVRSAoZm9vXy0+SXNSZXNlcnZlZE5hbWUoImJhciIpKTsKKyAgRVhQRUNUX0ZBTFNFKGZvb18tPklzUmVzZXJ2ZWROYW1lKCJiYXoiKSk7Cit9OworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK2NsYXNzIE1pc2NUZXN0IDogcHVibGljIHRlc3Rpbmc6OlRlc3QgeworIHByb3RlY3RlZDoKKyAgLy8gRnVuY3Rpb24gd2hpY2ggbWFrZXMgYSBmaWVsZCBkZXNjcmlwdG9yIG9mIHRoZSBnaXZlbiB0eXBlLgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIEdldEZpZWxkRGVzY3JpcHRvck9mVHlwZShGaWVsZERlc2NyaXB0b3I6OlR5cGUgdHlwZSkgeworICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZV9wcm90bzsKKyAgICBmaWxlX3Byb3RvLnNldF9uYW1lKCJmb28ucHJvdG8iKTsKKyAgICBBZGRFbXB0eUVudW0oJmZpbGVfcHJvdG8sICJEdW1teUVudW0iKTsKKworICAgIERlc2NyaXB0b3JQcm90byogbWVzc2FnZSA9IEFkZE1lc3NhZ2UoJmZpbGVfcHJvdG8sICJUZXN0TWVzc2FnZSIpOworICAgIEZpZWxkRGVzY3JpcHRvclByb3RvKiBmaWVsZCA9CisgICAgICBBZGRGaWVsZChtZXNzYWdlLCAiZm9vIiwgMSwgRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX09QVElPTkFMLAorICAgICAgICAgICAgICAgc3RhdGljX2Nhc3Q8RmllbGREZXNjcmlwdG9yUHJvdG86OlR5cGU+KHN0YXRpY19jYXN0PGludD4odHlwZSkpKTsKKworICAgIGlmICh0eXBlID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9NRVNTQUdFIHx8CisgICAgICAgIHR5cGUgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQKSB7CisgICAgICBmaWVsZC0+c2V0X3R5cGVfbmFtZSgiVGVzdE1lc3NhZ2UiKTsKKyAgICB9IGVsc2UgaWYgKHR5cGUgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX0VOVU0pIHsKKyAgICAgIGZpZWxkLT5zZXRfdHlwZV9uYW1lKCJEdW1teUVudW0iKTsKKyAgICB9CisKKyAgICAvLyBCdWlsZCB0aGUgZGVzY3JpcHRvcnMgYW5kIGdldCB0aGUgcG9pbnRlcnMuCisgICAgcG9vbF8ucmVzZXQobmV3IERlc2NyaXB0b3JQb29sKCkpOworICAgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlID0gcG9vbF8tPkJ1aWxkRmlsZShmaWxlX3Byb3RvKTsKKworICAgIGlmIChmaWxlICE9IE5VTEwgJiYKKyAgICAgICAgZmlsZS0+bWVzc2FnZV90eXBlX2NvdW50KCkgPT0gMSAmJgorICAgICAgICBmaWxlLT5tZXNzYWdlX3R5cGUoMCktPmZpZWxkX2NvdW50KCkgPT0gMSkgeworICAgICAgcmV0dXJuIGZpbGUtPm1lc3NhZ2VfdHlwZSgwKS0+ZmllbGQoMCk7CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgfQorCisgIGNvbnN0IGNoYXIqIEdldFR5cGVOYW1lRm9yRmllbGRUeXBlKEZpZWxkRGVzY3JpcHRvcjo6VHlwZSB0eXBlKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IEdldEZpZWxkRGVzY3JpcHRvck9mVHlwZSh0eXBlKTsKKyAgICByZXR1cm4gZmllbGQgIT0gTlVMTCA/IGZpZWxkLT50eXBlX25hbWUoKSA6ICIiOworICB9CisKKyAgRmllbGREZXNjcmlwdG9yOjpDcHBUeXBlIEdldENwcFR5cGVGb3JGaWVsZFR5cGUoRmllbGREZXNjcmlwdG9yOjpUeXBlIHR5cGUpIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gR2V0RmllbGREZXNjcmlwdG9yT2ZUeXBlKHR5cGUpOworICAgIHJldHVybiBmaWVsZCAhPSBOVUxMID8gZmllbGQtPmNwcF90eXBlKCkgOgorICAgICAgICBzdGF0aWNfY2FzdDxGaWVsZERlc2NyaXB0b3I6OkNwcFR5cGU+KDApOworICB9CisKKyAgY29uc3QgY2hhciogR2V0Q3BwVHlwZU5hbWVGb3JGaWVsZFR5cGUoRmllbGREZXNjcmlwdG9yOjpUeXBlIHR5cGUpIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gR2V0RmllbGREZXNjcmlwdG9yT2ZUeXBlKHR5cGUpOworICAgIHJldHVybiBmaWVsZCAhPSBOVUxMID8gZmllbGQtPmNwcF90eXBlX25hbWUoKSA6ICIiOworICB9CisKKyAgY29uc3QgRGVzY3JpcHRvciogR2V0TWVzc2FnZURlc2NyaXB0b3JGb3JGaWVsZFR5cGUoCisgICAgICBGaWVsZERlc2NyaXB0b3I6OlR5cGUgdHlwZSkgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBHZXRGaWVsZERlc2NyaXB0b3JPZlR5cGUodHlwZSk7CisgICAgcmV0dXJuIGZpZWxkICE9IE5VTEwgPyBmaWVsZC0+bWVzc2FnZV90eXBlKCkgOiBOVUxMOworICB9CisKKyAgY29uc3QgRW51bURlc2NyaXB0b3IqIEdldEVudW1EZXNjcmlwdG9yRm9yRmllbGRUeXBlKAorICAgIEZpZWxkRGVzY3JpcHRvcjo6VHlwZSB0eXBlKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IEdldEZpZWxkRGVzY3JpcHRvck9mVHlwZSh0eXBlKTsKKyAgICByZXR1cm4gZmllbGQgIT0gTlVMTCA/IGZpZWxkLT5lbnVtX3R5cGUoKSA6IE5VTEw7CisgIH0KKworICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPERlc2NyaXB0b3JQb29sPiBwb29sXzsKK307CisKK1RFU1RfRihNaXNjVGVzdCwgVHlwZU5hbWVzKSB7CisgIC8vIFRlc3QgdGhhdCBjb3JyZWN0IHR5cGUgbmFtZXMgYXJlIHJldHVybmVkLgorCisgIHR5cGVkZWYgRmllbGREZXNjcmlwdG9yIEZEOyAgLy8gYXZvaWQgdWdseSBsaW5lIHdyYXBwaW5nCisKKyAgRVhQRUNUX1NUUkVRKCJkb3VibGUiICAsIEdldFR5cGVOYW1lRm9yRmllbGRUeXBlKEZEOjpUWVBFX0RPVUJMRSAgKSk7CisgIEVYUEVDVF9TVFJFUSgiZmxvYXQiICAgLCBHZXRUeXBlTmFtZUZvckZpZWxkVHlwZShGRDo6VFlQRV9GTE9BVCAgICkpOworICBFWFBFQ1RfU1RSRVEoImludDY0IiAgICwgR2V0VHlwZU5hbWVGb3JGaWVsZFR5cGUoRkQ6OlRZUEVfSU5UNjQgICApKTsKKyAgRVhQRUNUX1NUUkVRKCJ1aW50NjQiICAsIEdldFR5cGVOYW1lRm9yRmllbGRUeXBlKEZEOjpUWVBFX1VJTlQ2NCAgKSk7CisgIEVYUEVDVF9TVFJFUSgiaW50MzIiICAgLCBHZXRUeXBlTmFtZUZvckZpZWxkVHlwZShGRDo6VFlQRV9JTlQzMiAgICkpOworICBFWFBFQ1RfU1RSRVEoImZpeGVkNjQiICwgR2V0VHlwZU5hbWVGb3JGaWVsZFR5cGUoRkQ6OlRZUEVfRklYRUQ2NCApKTsKKyAgRVhQRUNUX1NUUkVRKCJmaXhlZDMyIiAsIEdldFR5cGVOYW1lRm9yRmllbGRUeXBlKEZEOjpUWVBFX0ZJWEVEMzIgKSk7CisgIEVYUEVDVF9TVFJFUSgiYm9vbCIgICAgLCBHZXRUeXBlTmFtZUZvckZpZWxkVHlwZShGRDo6VFlQRV9CT09MICAgICkpOworICBFWFBFQ1RfU1RSRVEoInN0cmluZyIgICwgR2V0VHlwZU5hbWVGb3JGaWVsZFR5cGUoRkQ6OlRZUEVfU1RSSU5HICApKTsKKyAgRVhQRUNUX1NUUkVRKCJncm91cCIgICAsIEdldFR5cGVOYW1lRm9yRmllbGRUeXBlKEZEOjpUWVBFX0dST1VQICAgKSk7CisgIEVYUEVDVF9TVFJFUSgibWVzc2FnZSIgLCBHZXRUeXBlTmFtZUZvckZpZWxkVHlwZShGRDo6VFlQRV9NRVNTQUdFICkpOworICBFWFBFQ1RfU1RSRVEoImJ5dGVzIiAgICwgR2V0VHlwZU5hbWVGb3JGaWVsZFR5cGUoRkQ6OlRZUEVfQllURVMgICApKTsKKyAgRVhQRUNUX1NUUkVRKCJ1aW50MzIiICAsIEdldFR5cGVOYW1lRm9yRmllbGRUeXBlKEZEOjpUWVBFX1VJTlQzMiAgKSk7CisgIEVYUEVDVF9TVFJFUSgiZW51bSIgICAgLCBHZXRUeXBlTmFtZUZvckZpZWxkVHlwZShGRDo6VFlQRV9FTlVNICAgICkpOworICBFWFBFQ1RfU1RSRVEoInNmaXhlZDMyIiwgR2V0VHlwZU5hbWVGb3JGaWVsZFR5cGUoRkQ6OlRZUEVfU0ZJWEVEMzIpKTsKKyAgRVhQRUNUX1NUUkVRKCJzZml4ZWQ2NCIsIEdldFR5cGVOYW1lRm9yRmllbGRUeXBlKEZEOjpUWVBFX1NGSVhFRDY0KSk7CisgIEVYUEVDVF9TVFJFUSgic2ludDMyIiAgLCBHZXRUeXBlTmFtZUZvckZpZWxkVHlwZShGRDo6VFlQRV9TSU5UMzIgICkpOworICBFWFBFQ1RfU1RSRVEoInNpbnQ2NCIgICwgR2V0VHlwZU5hbWVGb3JGaWVsZFR5cGUoRkQ6OlRZUEVfU0lOVDY0ICApKTsKK30KKworVEVTVF9GKE1pc2NUZXN0LCBTdGF0aWNUeXBlTmFtZXMpIHsKKyAgLy8gVGVzdCB0aGF0IGNvcnJlY3QgdHlwZSBuYW1lcyBhcmUgcmV0dXJuZWQuCisKKyAgdHlwZWRlZiBGaWVsZERlc2NyaXB0b3IgRkQ7ICAvLyBhdm9pZCB1Z2x5IGxpbmUgd3JhcHBpbmcKKworICBFWFBFQ1RfU1RSRVEoImRvdWJsZSIgICwgRkQ6OlR5cGVOYW1lKEZEOjpUWVBFX0RPVUJMRSAgKSk7CisgIEVYUEVDVF9TVFJFUSgiZmxvYXQiICAgLCBGRDo6VHlwZU5hbWUoRkQ6OlRZUEVfRkxPQVQgICApKTsKKyAgRVhQRUNUX1NUUkVRKCJpbnQ2NCIgICAsIEZEOjpUeXBlTmFtZShGRDo6VFlQRV9JTlQ2NCAgICkpOworICBFWFBFQ1RfU1RSRVEoInVpbnQ2NCIgICwgRkQ6OlR5cGVOYW1lKEZEOjpUWVBFX1VJTlQ2NCAgKSk7CisgIEVYUEVDVF9TVFJFUSgiaW50MzIiICAgLCBGRDo6VHlwZU5hbWUoRkQ6OlRZUEVfSU5UMzIgICApKTsKKyAgRVhQRUNUX1NUUkVRKCJmaXhlZDY0IiAsIEZEOjpUeXBlTmFtZShGRDo6VFlQRV9GSVhFRDY0ICkpOworICBFWFBFQ1RfU1RSRVEoImZpeGVkMzIiICwgRkQ6OlR5cGVOYW1lKEZEOjpUWVBFX0ZJWEVEMzIgKSk7CisgIEVYUEVDVF9TVFJFUSgiYm9vbCIgICAgLCBGRDo6VHlwZU5hbWUoRkQ6OlRZUEVfQk9PTCAgICApKTsKKyAgRVhQRUNUX1NUUkVRKCJzdHJpbmciICAsIEZEOjpUeXBlTmFtZShGRDo6VFlQRV9TVFJJTkcgICkpOworICBFWFBFQ1RfU1RSRVEoImdyb3VwIiAgICwgRkQ6OlR5cGVOYW1lKEZEOjpUWVBFX0dST1VQICAgKSk7CisgIEVYUEVDVF9TVFJFUSgibWVzc2FnZSIgLCBGRDo6VHlwZU5hbWUoRkQ6OlRZUEVfTUVTU0FHRSApKTsKKyAgRVhQRUNUX1NUUkVRKCJieXRlcyIgICAsIEZEOjpUeXBlTmFtZShGRDo6VFlQRV9CWVRFUyAgICkpOworICBFWFBFQ1RfU1RSRVEoInVpbnQzMiIgICwgRkQ6OlR5cGVOYW1lKEZEOjpUWVBFX1VJTlQzMiAgKSk7CisgIEVYUEVDVF9TVFJFUSgiZW51bSIgICAgLCBGRDo6VHlwZU5hbWUoRkQ6OlRZUEVfRU5VTSAgICApKTsKKyAgRVhQRUNUX1NUUkVRKCJzZml4ZWQzMiIsIEZEOjpUeXBlTmFtZShGRDo6VFlQRV9TRklYRUQzMikpOworICBFWFBFQ1RfU1RSRVEoInNmaXhlZDY0IiwgRkQ6OlR5cGVOYW1lKEZEOjpUWVBFX1NGSVhFRDY0KSk7CisgIEVYUEVDVF9TVFJFUSgic2ludDMyIiAgLCBGRDo6VHlwZU5hbWUoRkQ6OlRZUEVfU0lOVDMyICApKTsKKyAgRVhQRUNUX1NUUkVRKCJzaW50NjQiICAsIEZEOjpUeXBlTmFtZShGRDo6VFlQRV9TSU5UNjQgICkpOworfQorCitURVNUX0YoTWlzY1Rlc3QsIENwcFR5cGVzKSB7CisgIC8vIFRlc3QgdGhhdCBDUFAgdHlwZXMgYXJlIGFzc2lnbmVkIGNvcnJlY3RseS4KKworICB0eXBlZGVmIEZpZWxkRGVzY3JpcHRvciBGRDsgIC8vIGF2b2lkIHVnbHkgbGluZSB3cmFwcGluZworCisgIEVYUEVDVF9FUShGRDo6Q1BQVFlQRV9ET1VCTEUgLCBHZXRDcHBUeXBlRm9yRmllbGRUeXBlKEZEOjpUWVBFX0RPVUJMRSAgKSk7CisgIEVYUEVDVF9FUShGRDo6Q1BQVFlQRV9GTE9BVCAgLCBHZXRDcHBUeXBlRm9yRmllbGRUeXBlKEZEOjpUWVBFX0ZMT0FUICAgKSk7CisgIEVYUEVDVF9FUShGRDo6Q1BQVFlQRV9JTlQ2NCAgLCBHZXRDcHBUeXBlRm9yRmllbGRUeXBlKEZEOjpUWVBFX0lOVDY0ICAgKSk7CisgIEVYUEVDVF9FUShGRDo6Q1BQVFlQRV9VSU5UNjQgLCBHZXRDcHBUeXBlRm9yRmllbGRUeXBlKEZEOjpUWVBFX1VJTlQ2NCAgKSk7CisgIEVYUEVDVF9FUShGRDo6Q1BQVFlQRV9JTlQzMiAgLCBHZXRDcHBUeXBlRm9yRmllbGRUeXBlKEZEOjpUWVBFX0lOVDMyICAgKSk7CisgIEVYUEVDVF9FUShGRDo6Q1BQVFlQRV9VSU5UNjQgLCBHZXRDcHBUeXBlRm9yRmllbGRUeXBlKEZEOjpUWVBFX0ZJWEVENjQgKSk7CisgIEVYUEVDVF9FUShGRDo6Q1BQVFlQRV9VSU5UMzIgLCBHZXRDcHBUeXBlRm9yRmllbGRUeXBlKEZEOjpUWVBFX0ZJWEVEMzIgKSk7CisgIEVYUEVDVF9FUShGRDo6Q1BQVFlQRV9CT09MICAgLCBHZXRDcHBUeXBlRm9yRmllbGRUeXBlKEZEOjpUWVBFX0JPT0wgICAgKSk7CisgIEVYUEVDVF9FUShGRDo6Q1BQVFlQRV9TVFJJTkcgLCBHZXRDcHBUeXBlRm9yRmllbGRUeXBlKEZEOjpUWVBFX1NUUklORyAgKSk7CisgIEVYUEVDVF9FUShGRDo6Q1BQVFlQRV9NRVNTQUdFLCBHZXRDcHBUeXBlRm9yRmllbGRUeXBlKEZEOjpUWVBFX0dST1VQICAgKSk7CisgIEVYUEVDVF9FUShGRDo6Q1BQVFlQRV9NRVNTQUdFLCBHZXRDcHBUeXBlRm9yRmllbGRUeXBlKEZEOjpUWVBFX01FU1NBR0UgKSk7CisgIEVYUEVDVF9FUShGRDo6Q1BQVFlQRV9TVFJJTkcgLCBHZXRDcHBUeXBlRm9yRmllbGRUeXBlKEZEOjpUWVBFX0JZVEVTICAgKSk7CisgIEVYUEVDVF9FUShGRDo6Q1BQVFlQRV9VSU5UMzIgLCBHZXRDcHBUeXBlRm9yRmllbGRUeXBlKEZEOjpUWVBFX1VJTlQzMiAgKSk7CisgIEVYUEVDVF9FUShGRDo6Q1BQVFlQRV9FTlVNICAgLCBHZXRDcHBUeXBlRm9yRmllbGRUeXBlKEZEOjpUWVBFX0VOVU0gICAgKSk7CisgIEVYUEVDVF9FUShGRDo6Q1BQVFlQRV9JTlQzMiAgLCBHZXRDcHBUeXBlRm9yRmllbGRUeXBlKEZEOjpUWVBFX1NGSVhFRDMyKSk7CisgIEVYUEVDVF9FUShGRDo6Q1BQVFlQRV9JTlQ2NCAgLCBHZXRDcHBUeXBlRm9yRmllbGRUeXBlKEZEOjpUWVBFX1NGSVhFRDY0KSk7CisgIEVYUEVDVF9FUShGRDo6Q1BQVFlQRV9JTlQzMiAgLCBHZXRDcHBUeXBlRm9yRmllbGRUeXBlKEZEOjpUWVBFX1NJTlQzMiAgKSk7CisgIEVYUEVDVF9FUShGRDo6Q1BQVFlQRV9JTlQ2NCAgLCBHZXRDcHBUeXBlRm9yRmllbGRUeXBlKEZEOjpUWVBFX1NJTlQ2NCAgKSk7Cit9CisKK1RFU1RfRihNaXNjVGVzdCwgQ3BwVHlwZU5hbWVzKSB7CisgIC8vIFRlc3QgdGhhdCBjb3JyZWN0IENQUCB0eXBlIG5hbWVzIGFyZSByZXR1cm5lZC4KKworICB0eXBlZGVmIEZpZWxkRGVzY3JpcHRvciBGRDsgIC8vIGF2b2lkIHVnbHkgbGluZSB3cmFwcGluZworCisgIEVYUEVDVF9TVFJFUSgiZG91YmxlIiAsIEdldENwcFR5cGVOYW1lRm9yRmllbGRUeXBlKEZEOjpUWVBFX0RPVUJMRSAgKSk7CisgIEVYUEVDVF9TVFJFUSgiZmxvYXQiICAsIEdldENwcFR5cGVOYW1lRm9yRmllbGRUeXBlKEZEOjpUWVBFX0ZMT0FUICAgKSk7CisgIEVYUEVDVF9TVFJFUSgiaW50NjQiICAsIEdldENwcFR5cGVOYW1lRm9yRmllbGRUeXBlKEZEOjpUWVBFX0lOVDY0ICAgKSk7CisgIEVYUEVDVF9TVFJFUSgidWludDY0IiAsIEdldENwcFR5cGVOYW1lRm9yRmllbGRUeXBlKEZEOjpUWVBFX1VJTlQ2NCAgKSk7CisgIEVYUEVDVF9TVFJFUSgiaW50MzIiICAsIEdldENwcFR5cGVOYW1lRm9yRmllbGRUeXBlKEZEOjpUWVBFX0lOVDMyICAgKSk7CisgIEVYUEVDVF9TVFJFUSgidWludDY0IiAsIEdldENwcFR5cGVOYW1lRm9yRmllbGRUeXBlKEZEOjpUWVBFX0ZJWEVENjQgKSk7CisgIEVYUEVDVF9TVFJFUSgidWludDMyIiAsIEdldENwcFR5cGVOYW1lRm9yRmllbGRUeXBlKEZEOjpUWVBFX0ZJWEVEMzIgKSk7CisgIEVYUEVDVF9TVFJFUSgiYm9vbCIgICAsIEdldENwcFR5cGVOYW1lRm9yRmllbGRUeXBlKEZEOjpUWVBFX0JPT0wgICAgKSk7CisgIEVYUEVDVF9TVFJFUSgic3RyaW5nIiAsIEdldENwcFR5cGVOYW1lRm9yRmllbGRUeXBlKEZEOjpUWVBFX1NUUklORyAgKSk7CisgIEVYUEVDVF9TVFJFUSgibWVzc2FnZSIsIEdldENwcFR5cGVOYW1lRm9yRmllbGRUeXBlKEZEOjpUWVBFX0dST1VQICAgKSk7CisgIEVYUEVDVF9TVFJFUSgibWVzc2FnZSIsIEdldENwcFR5cGVOYW1lRm9yRmllbGRUeXBlKEZEOjpUWVBFX01FU1NBR0UgKSk7CisgIEVYUEVDVF9TVFJFUSgic3RyaW5nIiAsIEdldENwcFR5cGVOYW1lRm9yRmllbGRUeXBlKEZEOjpUWVBFX0JZVEVTICAgKSk7CisgIEVYUEVDVF9TVFJFUSgidWludDMyIiAsIEdldENwcFR5cGVOYW1lRm9yRmllbGRUeXBlKEZEOjpUWVBFX1VJTlQzMiAgKSk7CisgIEVYUEVDVF9TVFJFUSgiZW51bSIgICAsIEdldENwcFR5cGVOYW1lRm9yRmllbGRUeXBlKEZEOjpUWVBFX0VOVU0gICAgKSk7CisgIEVYUEVDVF9TVFJFUSgiaW50MzIiICAsIEdldENwcFR5cGVOYW1lRm9yRmllbGRUeXBlKEZEOjpUWVBFX1NGSVhFRDMyKSk7CisgIEVYUEVDVF9TVFJFUSgiaW50NjQiICAsIEdldENwcFR5cGVOYW1lRm9yRmllbGRUeXBlKEZEOjpUWVBFX1NGSVhFRDY0KSk7CisgIEVYUEVDVF9TVFJFUSgiaW50MzIiICAsIEdldENwcFR5cGVOYW1lRm9yRmllbGRUeXBlKEZEOjpUWVBFX1NJTlQzMiAgKSk7CisgIEVYUEVDVF9TVFJFUSgiaW50NjQiICAsIEdldENwcFR5cGVOYW1lRm9yRmllbGRUeXBlKEZEOjpUWVBFX1NJTlQ2NCAgKSk7Cit9CisKK1RFU1RfRihNaXNjVGVzdCwgU3RhdGljQ3BwVHlwZU5hbWVzKSB7CisgIC8vIFRlc3QgdGhhdCBjb3JyZWN0IENQUCB0eXBlIG5hbWVzIGFyZSByZXR1cm5lZC4KKworICB0eXBlZGVmIEZpZWxkRGVzY3JpcHRvciBGRDsgIC8vIGF2b2lkIHVnbHkgbGluZSB3cmFwcGluZworCisgIEVYUEVDVF9TVFJFUSgiaW50MzIiICAsIEZEOjpDcHBUeXBlTmFtZShGRDo6Q1BQVFlQRV9JTlQzMiAgKSk7CisgIEVYUEVDVF9TVFJFUSgiaW50NjQiICAsIEZEOjpDcHBUeXBlTmFtZShGRDo6Q1BQVFlQRV9JTlQ2NCAgKSk7CisgIEVYUEVDVF9TVFJFUSgidWludDMyIiAsIEZEOjpDcHBUeXBlTmFtZShGRDo6Q1BQVFlQRV9VSU5UMzIgKSk7CisgIEVYUEVDVF9TVFJFUSgidWludDY0IiAsIEZEOjpDcHBUeXBlTmFtZShGRDo6Q1BQVFlQRV9VSU5UNjQgKSk7CisgIEVYUEVDVF9TVFJFUSgiZG91YmxlIiAsIEZEOjpDcHBUeXBlTmFtZShGRDo6Q1BQVFlQRV9ET1VCTEUgKSk7CisgIEVYUEVDVF9TVFJFUSgiZmxvYXQiICAsIEZEOjpDcHBUeXBlTmFtZShGRDo6Q1BQVFlQRV9GTE9BVCAgKSk7CisgIEVYUEVDVF9TVFJFUSgiYm9vbCIgICAsIEZEOjpDcHBUeXBlTmFtZShGRDo6Q1BQVFlQRV9CT09MICAgKSk7CisgIEVYUEVDVF9TVFJFUSgiZW51bSIgICAsIEZEOjpDcHBUeXBlTmFtZShGRDo6Q1BQVFlQRV9FTlVNICAgKSk7CisgIEVYUEVDVF9TVFJFUSgic3RyaW5nIiAsIEZEOjpDcHBUeXBlTmFtZShGRDo6Q1BQVFlQRV9TVFJJTkcgKSk7CisgIEVYUEVDVF9TVFJFUSgibWVzc2FnZSIsIEZEOjpDcHBUeXBlTmFtZShGRDo6Q1BQVFlQRV9NRVNTQUdFKSk7Cit9CisKK1RFU1RfRihNaXNjVGVzdCwgTWVzc2FnZVR5cGUpIHsKKyAgLy8gVGVzdCB0aGF0IG1lc3NhZ2VfdHlwZSgpIGlzIE5VTEwgZm9yIG5vbi1hZ2dyZWdhdGUgZmllbGRzCisKKyAgdHlwZWRlZiBGaWVsZERlc2NyaXB0b3IgRkQ7ICAvLyBhdm9pZCB1Z2x5IGxpbmUgd3JhcHBpbmcKKworICBFWFBFQ1RfVFJVRShOVUxMID09IEdldE1lc3NhZ2VEZXNjcmlwdG9yRm9yRmllbGRUeXBlKEZEOjpUWVBFX0RPVUJMRSAgKSk7CisgIEVYUEVDVF9UUlVFKE5VTEwgPT0gR2V0TWVzc2FnZURlc2NyaXB0b3JGb3JGaWVsZFR5cGUoRkQ6OlRZUEVfRkxPQVQgICApKTsKKyAgRVhQRUNUX1RSVUUoTlVMTCA9PSBHZXRNZXNzYWdlRGVzY3JpcHRvckZvckZpZWxkVHlwZShGRDo6VFlQRV9JTlQ2NCAgICkpOworICBFWFBFQ1RfVFJVRShOVUxMID09IEdldE1lc3NhZ2VEZXNjcmlwdG9yRm9yRmllbGRUeXBlKEZEOjpUWVBFX1VJTlQ2NCAgKSk7CisgIEVYUEVDVF9UUlVFKE5VTEwgPT0gR2V0TWVzc2FnZURlc2NyaXB0b3JGb3JGaWVsZFR5cGUoRkQ6OlRZUEVfSU5UMzIgICApKTsKKyAgRVhQRUNUX1RSVUUoTlVMTCA9PSBHZXRNZXNzYWdlRGVzY3JpcHRvckZvckZpZWxkVHlwZShGRDo6VFlQRV9GSVhFRDY0ICkpOworICBFWFBFQ1RfVFJVRShOVUxMID09IEdldE1lc3NhZ2VEZXNjcmlwdG9yRm9yRmllbGRUeXBlKEZEOjpUWVBFX0ZJWEVEMzIgKSk7CisgIEVYUEVDVF9UUlVFKE5VTEwgPT0gR2V0TWVzc2FnZURlc2NyaXB0b3JGb3JGaWVsZFR5cGUoRkQ6OlRZUEVfQk9PTCAgICApKTsKKyAgRVhQRUNUX1RSVUUoTlVMTCA9PSBHZXRNZXNzYWdlRGVzY3JpcHRvckZvckZpZWxkVHlwZShGRDo6VFlQRV9TVFJJTkcgICkpOworICBFWFBFQ1RfVFJVRShOVUxMICE9IEdldE1lc3NhZ2VEZXNjcmlwdG9yRm9yRmllbGRUeXBlKEZEOjpUWVBFX0dST1VQICAgKSk7CisgIEVYUEVDVF9UUlVFKE5VTEwgIT0gR2V0TWVzc2FnZURlc2NyaXB0b3JGb3JGaWVsZFR5cGUoRkQ6OlRZUEVfTUVTU0FHRSApKTsKKyAgRVhQRUNUX1RSVUUoTlVMTCA9PSBHZXRNZXNzYWdlRGVzY3JpcHRvckZvckZpZWxkVHlwZShGRDo6VFlQRV9CWVRFUyAgICkpOworICBFWFBFQ1RfVFJVRShOVUxMID09IEdldE1lc3NhZ2VEZXNjcmlwdG9yRm9yRmllbGRUeXBlKEZEOjpUWVBFX1VJTlQzMiAgKSk7CisgIEVYUEVDVF9UUlVFKE5VTEwgPT0gR2V0TWVzc2FnZURlc2NyaXB0b3JGb3JGaWVsZFR5cGUoRkQ6OlRZUEVfRU5VTSAgICApKTsKKyAgRVhQRUNUX1RSVUUoTlVMTCA9PSBHZXRNZXNzYWdlRGVzY3JpcHRvckZvckZpZWxkVHlwZShGRDo6VFlQRV9TRklYRUQzMikpOworICBFWFBFQ1RfVFJVRShOVUxMID09IEdldE1lc3NhZ2VEZXNjcmlwdG9yRm9yRmllbGRUeXBlKEZEOjpUWVBFX1NGSVhFRDY0KSk7CisgIEVYUEVDVF9UUlVFKE5VTEwgPT0gR2V0TWVzc2FnZURlc2NyaXB0b3JGb3JGaWVsZFR5cGUoRkQ6OlRZUEVfU0lOVDMyICApKTsKKyAgRVhQRUNUX1RSVUUoTlVMTCA9PSBHZXRNZXNzYWdlRGVzY3JpcHRvckZvckZpZWxkVHlwZShGRDo6VFlQRV9TSU5UNjQgICkpOworfQorCitURVNUX0YoTWlzY1Rlc3QsIEVudW1UeXBlKSB7CisgIC8vIFRlc3QgdGhhdCBlbnVtX3R5cGUoKSBpcyBOVUxMIGZvciBub24tZW51bSBmaWVsZHMKKworICB0eXBlZGVmIEZpZWxkRGVzY3JpcHRvciBGRDsgIC8vIGF2b2lkIHVnbHkgbGluZSB3cmFwcGluZworCisgIEVYUEVDVF9UUlVFKE5VTEwgPT0gR2V0RW51bURlc2NyaXB0b3JGb3JGaWVsZFR5cGUoRkQ6OlRZUEVfRE9VQkxFICApKTsKKyAgRVhQRUNUX1RSVUUoTlVMTCA9PSBHZXRFbnVtRGVzY3JpcHRvckZvckZpZWxkVHlwZShGRDo6VFlQRV9GTE9BVCAgICkpOworICBFWFBFQ1RfVFJVRShOVUxMID09IEdldEVudW1EZXNjcmlwdG9yRm9yRmllbGRUeXBlKEZEOjpUWVBFX0lOVDY0ICAgKSk7CisgIEVYUEVDVF9UUlVFKE5VTEwgPT0gR2V0RW51bURlc2NyaXB0b3JGb3JGaWVsZFR5cGUoRkQ6OlRZUEVfVUlOVDY0ICApKTsKKyAgRVhQRUNUX1RSVUUoTlVMTCA9PSBHZXRFbnVtRGVzY3JpcHRvckZvckZpZWxkVHlwZShGRDo6VFlQRV9JTlQzMiAgICkpOworICBFWFBFQ1RfVFJVRShOVUxMID09IEdldEVudW1EZXNjcmlwdG9yRm9yRmllbGRUeXBlKEZEOjpUWVBFX0ZJWEVENjQgKSk7CisgIEVYUEVDVF9UUlVFKE5VTEwgPT0gR2V0RW51bURlc2NyaXB0b3JGb3JGaWVsZFR5cGUoRkQ6OlRZUEVfRklYRUQzMiApKTsKKyAgRVhQRUNUX1RSVUUoTlVMTCA9PSBHZXRFbnVtRGVzY3JpcHRvckZvckZpZWxkVHlwZShGRDo6VFlQRV9CT09MICAgICkpOworICBFWFBFQ1RfVFJVRShOVUxMID09IEdldEVudW1EZXNjcmlwdG9yRm9yRmllbGRUeXBlKEZEOjpUWVBFX1NUUklORyAgKSk7CisgIEVYUEVDVF9UUlVFKE5VTEwgPT0gR2V0RW51bURlc2NyaXB0b3JGb3JGaWVsZFR5cGUoRkQ6OlRZUEVfR1JPVVAgICApKTsKKyAgRVhQRUNUX1RSVUUoTlVMTCA9PSBHZXRFbnVtRGVzY3JpcHRvckZvckZpZWxkVHlwZShGRDo6VFlQRV9NRVNTQUdFICkpOworICBFWFBFQ1RfVFJVRShOVUxMID09IEdldEVudW1EZXNjcmlwdG9yRm9yRmllbGRUeXBlKEZEOjpUWVBFX0JZVEVTICAgKSk7CisgIEVYUEVDVF9UUlVFKE5VTEwgPT0gR2V0RW51bURlc2NyaXB0b3JGb3JGaWVsZFR5cGUoRkQ6OlRZUEVfVUlOVDMyICApKTsKKyAgRVhQRUNUX1RSVUUoTlVMTCAhPSBHZXRFbnVtRGVzY3JpcHRvckZvckZpZWxkVHlwZShGRDo6VFlQRV9FTlVNICAgICkpOworICBFWFBFQ1RfVFJVRShOVUxMID09IEdldEVudW1EZXNjcmlwdG9yRm9yRmllbGRUeXBlKEZEOjpUWVBFX1NGSVhFRDMyKSk7CisgIEVYUEVDVF9UUlVFKE5VTEwgPT0gR2V0RW51bURlc2NyaXB0b3JGb3JGaWVsZFR5cGUoRkQ6OlRZUEVfU0ZJWEVENjQpKTsKKyAgRVhQRUNUX1RSVUUoTlVMTCA9PSBHZXRFbnVtRGVzY3JpcHRvckZvckZpZWxkVHlwZShGRDo6VFlQRV9TSU5UMzIgICkpOworICBFWFBFQ1RfVFJVRShOVUxMID09IEdldEVudW1EZXNjcmlwdG9yRm9yRmllbGRUeXBlKEZEOjpUWVBFX1NJTlQ2NCAgKSk7Cit9CisKKworVEVTVF9GKE1pc2NUZXN0LCBEZWZhdWx0VmFsdWVzKSB7CisgIC8vIFRlc3QgdGhhdCBzZXR0aW5nIGRlZmF1bHQgdmFsdWVzIHdvcmtzLgorICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGVfcHJvdG87CisgIGZpbGVfcHJvdG8uc2V0X25hbWUoImZvby5wcm90byIpOworCisgIEVudW1EZXNjcmlwdG9yUHJvdG8qIGVudW1fdHlwZV9wcm90byA9IEFkZEVudW0oJmZpbGVfcHJvdG8sICJEdW1teUVudW0iKTsKKyAgQWRkRW51bVZhbHVlKGVudW1fdHlwZV9wcm90bywgIkEiLCAxKTsKKyAgQWRkRW51bVZhbHVlKGVudW1fdHlwZV9wcm90bywgIkIiLCAyKTsKKworICBEZXNjcmlwdG9yUHJvdG8qIG1lc3NhZ2VfcHJvdG8gPSBBZGRNZXNzYWdlKCZmaWxlX3Byb3RvLCAiVGVzdE1lc3NhZ2UiKTsKKworICB0eXBlZGVmIEZpZWxkRGVzY3JpcHRvclByb3RvIEZEOyAgLy8gYXZvaWQgdWdseSBsaW5lIHdyYXBwaW5nCisgIGNvbnN0IEZEOjpMYWJlbCBsYWJlbCA9IEZEOjpMQUJFTF9PUFRJT05BTDsKKworICAvLyBDcmVhdGUgZmllbGRzIG9mIGV2ZXJ5IENQUCB0eXBlIHdpdGggZGVmYXVsdCB2YWx1ZXMuCisgIEFkZEZpZWxkKG1lc3NhZ2VfcHJvdG8sICJpbnQzMiIgLCAxLCBsYWJlbCwgRkQ6OlRZUEVfSU5UMzIgKQorICAgIC0+c2V0X2RlZmF1bHRfdmFsdWUoIi0xIik7CisgIEFkZEZpZWxkKG1lc3NhZ2VfcHJvdG8sICJpbnQ2NCIgLCAyLCBsYWJlbCwgRkQ6OlRZUEVfSU5UNjQgKQorICAgIC0+c2V0X2RlZmF1bHRfdmFsdWUoIi0xMDAwMDAwMDAwMDAwIik7CisgIEFkZEZpZWxkKG1lc3NhZ2VfcHJvdG8sICJ1aW50MzIiLCAzLCBsYWJlbCwgRkQ6OlRZUEVfVUlOVDMyKQorICAgIC0+c2V0X2RlZmF1bHRfdmFsdWUoIjQyIik7CisgIEFkZEZpZWxkKG1lc3NhZ2VfcHJvdG8sICJ1aW50NjQiLCA0LCBsYWJlbCwgRkQ6OlRZUEVfVUlOVDY0KQorICAgIC0+c2V0X2RlZmF1bHRfdmFsdWUoIjIwMDAwMDAwMDAwMDAiKTsKKyAgQWRkRmllbGQobWVzc2FnZV9wcm90bywgImZsb2F0IiAsIDUsIGxhYmVsLCBGRDo6VFlQRV9GTE9BVCApCisgICAgLT5zZXRfZGVmYXVsdF92YWx1ZSgiNC41Iik7CisgIEFkZEZpZWxkKG1lc3NhZ2VfcHJvdG8sICJkb3VibGUiLCA2LCBsYWJlbCwgRkQ6OlRZUEVfRE9VQkxFKQorICAgIC0+c2V0X2RlZmF1bHRfdmFsdWUoIjEwZTEwMCIpOworICBBZGRGaWVsZChtZXNzYWdlX3Byb3RvLCAiYm9vbCIgICwgNywgbGFiZWwsIEZEOjpUWVBFX0JPT0wgICkKKyAgICAtPnNldF9kZWZhdWx0X3ZhbHVlKCJ0cnVlIik7CisgIEFkZEZpZWxkKG1lc3NhZ2VfcHJvdG8sICJzdHJpbmciLCA4LCBsYWJlbCwgRkQ6OlRZUEVfU1RSSU5HKQorICAgIC0+c2V0X2RlZmF1bHRfdmFsdWUoImhlbGxvIik7CisgIEFkZEZpZWxkKG1lc3NhZ2VfcHJvdG8sICJkYXRhIiAgLCA5LCBsYWJlbCwgRkQ6OlRZUEVfQllURVMgKQorICAgIC0+c2V0X2RlZmF1bHRfdmFsdWUoIlxcMDAxXFwwMDJcXDAwMyIpOworCisgIEZpZWxkRGVzY3JpcHRvclByb3RvKiBlbnVtX2ZpZWxkID0KKyAgICBBZGRGaWVsZChtZXNzYWdlX3Byb3RvLCAiZW51bSIsIDEwLCBsYWJlbCwgRkQ6OlRZUEVfRU5VTSk7CisgIGVudW1fZmllbGQtPnNldF90eXBlX25hbWUoIkR1bW15RW51bSIpOworICBlbnVtX2ZpZWxkLT5zZXRfZGVmYXVsdF92YWx1ZSgiQiIpOworCisgIC8vIFN0cmluZ3MgYXJlIGFsbG93ZWQgdG8gaGF2ZSBlbXB0eSBkZWZhdWx0cy4gIChBdCBvbmUgcG9pbnQsIGR1ZSB0bworICAvLyBhIGJ1ZywgZW1wdHkgZGVmYXVsdHMgZm9yIHN0cmluZ3Mgd2VyZSByZWplY3RlZC4gIE9vcHMuKQorICBBZGRGaWVsZChtZXNzYWdlX3Byb3RvLCAiZW1wdHlfc3RyaW5nIiwgMTEsIGxhYmVsLCBGRDo6VFlQRV9TVFJJTkcpCisgICAgLT5zZXRfZGVmYXVsdF92YWx1ZSgiIik7CisKKyAgLy8gQWRkIGEgc2Vjb25kIHNldCBvZiBmaWVsZHMgd2l0aCBpbXBsaWNpdCBkZWZhbHV0IHZhbHVlcy4KKyAgQWRkRmllbGQobWVzc2FnZV9wcm90bywgImltcGxpY2l0X2ludDMyIiAsIDIxLCBsYWJlbCwgRkQ6OlRZUEVfSU5UMzIgKTsKKyAgQWRkRmllbGQobWVzc2FnZV9wcm90bywgImltcGxpY2l0X2ludDY0IiAsIDIyLCBsYWJlbCwgRkQ6OlRZUEVfSU5UNjQgKTsKKyAgQWRkRmllbGQobWVzc2FnZV9wcm90bywgImltcGxpY2l0X3VpbnQzMiIsIDIzLCBsYWJlbCwgRkQ6OlRZUEVfVUlOVDMyKTsKKyAgQWRkRmllbGQobWVzc2FnZV9wcm90bywgImltcGxpY2l0X3VpbnQ2NCIsIDI0LCBsYWJlbCwgRkQ6OlRZUEVfVUlOVDY0KTsKKyAgQWRkRmllbGQobWVzc2FnZV9wcm90bywgImltcGxpY2l0X2Zsb2F0IiAsIDI1LCBsYWJlbCwgRkQ6OlRZUEVfRkxPQVQgKTsKKyAgQWRkRmllbGQobWVzc2FnZV9wcm90bywgImltcGxpY2l0X2RvdWJsZSIsIDI2LCBsYWJlbCwgRkQ6OlRZUEVfRE9VQkxFKTsKKyAgQWRkRmllbGQobWVzc2FnZV9wcm90bywgImltcGxpY2l0X2Jvb2wiICAsIDI3LCBsYWJlbCwgRkQ6OlRZUEVfQk9PTCAgKTsKKyAgQWRkRmllbGQobWVzc2FnZV9wcm90bywgImltcGxpY2l0X3N0cmluZyIsIDI4LCBsYWJlbCwgRkQ6OlRZUEVfU1RSSU5HKTsKKyAgQWRkRmllbGQobWVzc2FnZV9wcm90bywgImltcGxpY2l0X2RhdGEiICAsIDI5LCBsYWJlbCwgRkQ6OlRZUEVfQllURVMgKTsKKyAgQWRkRmllbGQobWVzc2FnZV9wcm90bywgImltcGxpY2l0X2VudW0iICAsIDMwLCBsYWJlbCwgRkQ6OlRZUEVfRU5VTSkKKyAgICAtPnNldF90eXBlX25hbWUoIkR1bW15RW51bSIpOworCisgIC8vIEJ1aWxkIGl0LgorICBEZXNjcmlwdG9yUG9vbCBwb29sOworICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSA9IHBvb2wuQnVpbGRGaWxlKGZpbGVfcHJvdG8pOworICBBU1NFUlRfVFJVRShmaWxlICE9IE5VTEwpOworCisgIEFTU0VSVF9FUSgxLCBmaWxlLT5lbnVtX3R5cGVfY291bnQoKSk7CisgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBlbnVtX3R5cGUgPSBmaWxlLT5lbnVtX3R5cGUoMCk7CisgIEFTU0VSVF9FUSgyLCBlbnVtX3R5cGUtPnZhbHVlX2NvdW50KCkpOworICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBlbnVtX3ZhbHVlX2EgPSBlbnVtX3R5cGUtPnZhbHVlKDApOworICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBlbnVtX3ZhbHVlX2IgPSBlbnVtX3R5cGUtPnZhbHVlKDEpOworCisgIEFTU0VSVF9FUSgxLCBmaWxlLT5tZXNzYWdlX3R5cGVfY291bnQoKSk7CisgIGNvbnN0IERlc2NyaXB0b3IqIG1lc3NhZ2UgPSBmaWxlLT5tZXNzYWdlX3R5cGUoMCk7CisKKyAgQVNTRVJUX0VRKDIxLCBtZXNzYWdlLT5maWVsZF9jb3VudCgpKTsKKworICAvLyBDaGVjayB0aGUgZGVmYXVsdCB2YWx1ZXMuCisgIEFTU0VSVF9UUlVFKG1lc3NhZ2UtPmZpZWxkKDApLT5oYXNfZGVmYXVsdF92YWx1ZSgpKTsKKyAgQVNTRVJUX1RSVUUobWVzc2FnZS0+ZmllbGQoMSktPmhhc19kZWZhdWx0X3ZhbHVlKCkpOworICBBU1NFUlRfVFJVRShtZXNzYWdlLT5maWVsZCgyKS0+aGFzX2RlZmF1bHRfdmFsdWUoKSk7CisgIEFTU0VSVF9UUlVFKG1lc3NhZ2UtPmZpZWxkKDMpLT5oYXNfZGVmYXVsdF92YWx1ZSgpKTsKKyAgQVNTRVJUX1RSVUUobWVzc2FnZS0+ZmllbGQoNCktPmhhc19kZWZhdWx0X3ZhbHVlKCkpOworICBBU1NFUlRfVFJVRShtZXNzYWdlLT5maWVsZCg1KS0+aGFzX2RlZmF1bHRfdmFsdWUoKSk7CisgIEFTU0VSVF9UUlVFKG1lc3NhZ2UtPmZpZWxkKDYpLT5oYXNfZGVmYXVsdF92YWx1ZSgpKTsKKyAgQVNTRVJUX1RSVUUobWVzc2FnZS0+ZmllbGQoNyktPmhhc19kZWZhdWx0X3ZhbHVlKCkpOworICBBU1NFUlRfVFJVRShtZXNzYWdlLT5maWVsZCg4KS0+aGFzX2RlZmF1bHRfdmFsdWUoKSk7CisgIEFTU0VSVF9UUlVFKG1lc3NhZ2UtPmZpZWxkKDkpLT5oYXNfZGVmYXVsdF92YWx1ZSgpKTsKKyAgQVNTRVJUX1RSVUUobWVzc2FnZS0+ZmllbGQoMTApLT5oYXNfZGVmYXVsdF92YWx1ZSgpKTsKKworICBFWFBFQ1RfRVEoLTEgICAgICAgICAgICAgICwgbWVzc2FnZS0+ZmllbGQoMCktPmRlZmF1bHRfdmFsdWVfaW50MzIgKCkpOworICBFWFBFQ1RfRVEoLUdPT0dMRV9VTE9OR0xPTkcoMTAwMDAwMDAwMDAwMCksCisgICAgICAgICAgICBtZXNzYWdlLT5maWVsZCgxKS0+ZGVmYXVsdF92YWx1ZV9pbnQ2NCAoKSk7CisgIEVYUEVDVF9FUSg0MiAgICAgICAgICAgICAgLCBtZXNzYWdlLT5maWVsZCgyKS0+ZGVmYXVsdF92YWx1ZV91aW50MzIoKSk7CisgIEVYUEVDVF9FUShHT09HTEVfVUxPTkdMT05HKDIwMDAwMDAwMDAwMDApLAorICAgICAgICAgICAgbWVzc2FnZS0+ZmllbGQoMyktPmRlZmF1bHRfdmFsdWVfdWludDY0KCkpOworICBFWFBFQ1RfRVEoNC41ICAgICAgICAgICAgICwgbWVzc2FnZS0+ZmllbGQoNCktPmRlZmF1bHRfdmFsdWVfZmxvYXQgKCkpOworICBFWFBFQ1RfRVEoMTBlMTAwICAgICAgICAgICwgbWVzc2FnZS0+ZmllbGQoNSktPmRlZmF1bHRfdmFsdWVfZG91YmxlKCkpOworICBFWFBFQ1RfVFJVRSggICAgICAgICAgICAgICAgbWVzc2FnZS0+ZmllbGQoNiktPmRlZmF1bHRfdmFsdWVfYm9vbCAgKCkpOworICBFWFBFQ1RfRVEoImhlbGxvIiAgICAgICAgICwgbWVzc2FnZS0+ZmllbGQoNyktPmRlZmF1bHRfdmFsdWVfc3RyaW5nKCkpOworICBFWFBFQ1RfRVEoIlwwMDFcMDAyXDAwMyIgICwgbWVzc2FnZS0+ZmllbGQoOCktPmRlZmF1bHRfdmFsdWVfc3RyaW5nKCkpOworICBFWFBFQ1RfRVEoZW51bV92YWx1ZV9iICAgICwgbWVzc2FnZS0+ZmllbGQoOSktPmRlZmF1bHRfdmFsdWVfZW51bSAgKCkpOworICBFWFBFQ1RfRVEoIiIgICAgICAgICAgICAgICwgbWVzc2FnZS0+ZmllbGQoMTApLT5kZWZhdWx0X3ZhbHVlX3N0cmluZygpKTsKKworICBBU1NFUlRfRkFMU0UobWVzc2FnZS0+ZmllbGQoMTEpLT5oYXNfZGVmYXVsdF92YWx1ZSgpKTsKKyAgQVNTRVJUX0ZBTFNFKG1lc3NhZ2UtPmZpZWxkKDEyKS0+aGFzX2RlZmF1bHRfdmFsdWUoKSk7CisgIEFTU0VSVF9GQUxTRShtZXNzYWdlLT5maWVsZCgxMyktPmhhc19kZWZhdWx0X3ZhbHVlKCkpOworICBBU1NFUlRfRkFMU0UobWVzc2FnZS0+ZmllbGQoMTQpLT5oYXNfZGVmYXVsdF92YWx1ZSgpKTsKKyAgQVNTRVJUX0ZBTFNFKG1lc3NhZ2UtPmZpZWxkKDE1KS0+aGFzX2RlZmF1bHRfdmFsdWUoKSk7CisgIEFTU0VSVF9GQUxTRShtZXNzYWdlLT5maWVsZCgxNiktPmhhc19kZWZhdWx0X3ZhbHVlKCkpOworICBBU1NFUlRfRkFMU0UobWVzc2FnZS0+ZmllbGQoMTcpLT5oYXNfZGVmYXVsdF92YWx1ZSgpKTsKKyAgQVNTRVJUX0ZBTFNFKG1lc3NhZ2UtPmZpZWxkKDE4KS0+aGFzX2RlZmF1bHRfdmFsdWUoKSk7CisgIEFTU0VSVF9GQUxTRShtZXNzYWdlLT5maWVsZCgxOSktPmhhc19kZWZhdWx0X3ZhbHVlKCkpOworICBBU1NFUlRfRkFMU0UobWVzc2FnZS0+ZmllbGQoMjApLT5oYXNfZGVmYXVsdF92YWx1ZSgpKTsKKworICBFWFBFQ1RfRVEoMCAgICAsIG1lc3NhZ2UtPmZpZWxkKDExKS0+ZGVmYXVsdF92YWx1ZV9pbnQzMiAoKSk7CisgIEVYUEVDVF9FUSgwICAgICwgbWVzc2FnZS0+ZmllbGQoMTIpLT5kZWZhdWx0X3ZhbHVlX2ludDY0ICgpKTsKKyAgRVhQRUNUX0VRKDAgICAgLCBtZXNzYWdlLT5maWVsZCgxMyktPmRlZmF1bHRfdmFsdWVfdWludDMyKCkpOworICBFWFBFQ1RfRVEoMCAgICAsIG1lc3NhZ2UtPmZpZWxkKDE0KS0+ZGVmYXVsdF92YWx1ZV91aW50NjQoKSk7CisgIEVYUEVDVF9FUSgwLjBmICwgbWVzc2FnZS0+ZmllbGQoMTUpLT5kZWZhdWx0X3ZhbHVlX2Zsb2F0ICgpKTsKKyAgRVhQRUNUX0VRKDAuMCAgLCBtZXNzYWdlLT5maWVsZCgxNiktPmRlZmF1bHRfdmFsdWVfZG91YmxlKCkpOworICBFWFBFQ1RfRkFMU0UoICAgIG1lc3NhZ2UtPmZpZWxkKDE3KS0+ZGVmYXVsdF92YWx1ZV9ib29sICAoKSk7CisgIEVYUEVDVF9FUSgiIiAgICwgbWVzc2FnZS0+ZmllbGQoMTgpLT5kZWZhdWx0X3ZhbHVlX3N0cmluZygpKTsKKyAgRVhQRUNUX0VRKCIiICAgLCBtZXNzYWdlLT5maWVsZCgxOSktPmRlZmF1bHRfdmFsdWVfc3RyaW5nKCkpOworICBFWFBFQ1RfRVEoZW51bV92YWx1ZV9hLCBtZXNzYWdlLT5maWVsZCgyMCktPmRlZmF1bHRfdmFsdWVfZW51bSgpKTsKK30KKworVEVTVF9GKE1pc2NUZXN0LCBGaWVsZE9wdGlvbnMpIHsKKyAgLy8gVHJ5IHNldHRpbmcgZmllbGQgb3B0aW9ucy4KKworICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGVfcHJvdG87CisgIGZpbGVfcHJvdG8uc2V0X25hbWUoImZvby5wcm90byIpOworCisgIERlc2NyaXB0b3JQcm90byogbWVzc2FnZV9wcm90byA9IEFkZE1lc3NhZ2UoJmZpbGVfcHJvdG8sICJUZXN0TWVzc2FnZSIpOworICBBZGRGaWVsZChtZXNzYWdlX3Byb3RvLCAiZm9vIiwgMSwKKyAgICAgICAgICAgRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX09QVElPTkFMLAorICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9JTlQzMik7CisgIEZpZWxkRGVzY3JpcHRvclByb3RvKiBiYXJfcHJvdG8gPQorICAgIEFkZEZpZWxkKG1lc3NhZ2VfcHJvdG8sICJiYXIiLCAyLAorICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpMQUJFTF9PUFRJT05BTCwKKyAgICAgICAgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9JTlQzMik7CisKKyAgRmllbGRPcHRpb25zKiBvcHRpb25zID0gYmFyX3Byb3RvLT5tdXRhYmxlX29wdGlvbnMoKTsKKyAgb3B0aW9ucy0+c2V0X2N0eXBlKEZpZWxkT3B0aW9uczo6Q09SRCk7CisKKyAgLy8gQnVpbGQgdGhlIGRlc2NyaXB0b3JzIGFuZCBnZXQgdGhlIHBvaW50ZXJzLgorICBEZXNjcmlwdG9yUG9vbCBwb29sOworICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSA9IHBvb2wuQnVpbGRGaWxlKGZpbGVfcHJvdG8pOworICBBU1NFUlRfVFJVRShmaWxlICE9IE5VTEwpOworCisgIEFTU0VSVF9FUSgxLCBmaWxlLT5tZXNzYWdlX3R5cGVfY291bnQoKSk7CisgIGNvbnN0IERlc2NyaXB0b3IqIG1lc3NhZ2UgPSBmaWxlLT5tZXNzYWdlX3R5cGUoMCk7CisKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UtPmZpZWxkX2NvdW50KCkpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZvbyA9IG1lc3NhZ2UtPmZpZWxkKDApOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGJhciA9IG1lc3NhZ2UtPmZpZWxkKDEpOworCisgIC8vICJmb28iIGhhZCBubyBvcHRpb25zIHNldCwgc28gaXQgc2hvdWxkIHJldHVybiB0aGUgZGVmYXVsdCBvcHRpb25zLgorICBFWFBFQ1RfRVEoJkZpZWxkT3B0aW9uczo6ZGVmYXVsdF9pbnN0YW5jZSgpLCAmZm9vLT5vcHRpb25zKCkpOworCisgIC8vICJiYXIiIGhhZCBvcHRpb25zIHNldC4KKyAgRVhQRUNUX05FKCZGaWVsZE9wdGlvbnM6OmRlZmF1bHRfaW5zdGFuY2UoKSwgb3B0aW9ucyk7CisgIEVYUEVDVF9UUlVFKGJhci0+b3B0aW9ucygpLmhhc19jdHlwZSgpKTsKKyAgRVhQRUNUX0VRKEZpZWxkT3B0aW9uczo6Q09SRCwgYmFyLT5vcHRpb25zKCkuY3R5cGUoKSk7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KK2VudW0gRGVzY3JpcHRvclBvb2xNb2RlIHsKKyAgTk9fREFUQUJBU0UsCisgIEZBTExCQUNLX0RBVEFCQVNFCit9OworCitjbGFzcyBBbGxvd1Vua25vd25EZXBlbmRlbmNpZXNUZXN0CisgICAgOiBwdWJsaWMgdGVzdGluZzo6VGVzdFdpdGhQYXJhbTxEZXNjcmlwdG9yUG9vbE1vZGU+IHsKKyBwcm90ZWN0ZWQ6CisgIERlc2NyaXB0b3JQb29sTW9kZSBtb2RlKCkgeworICAgIHJldHVybiBHZXRQYXJhbSgpOworICAgfQorCisgIHZpcnR1YWwgdm9pZCBTZXRVcCgpIHsKKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZvb19wcm90bywgYmFyX3Byb3RvOworCisgICAgc3dpdGNoIChtb2RlKCkpIHsKKyAgICAgIGNhc2UgTk9fREFUQUJBU0U6CisgICAgICAgIHBvb2xfLnJlc2V0KG5ldyBEZXNjcmlwdG9yUG9vbCk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBGQUxMQkFDS19EQVRBQkFTRToKKyAgICAgICAgcG9vbF8ucmVzZXQobmV3IERlc2NyaXB0b3JQb29sKCZkYl8pKTsKKyAgICAgICAgYnJlYWs7CisgICAgfQorCisgICAgcG9vbF8tPkFsbG93VW5rbm93bkRlcGVuZGVuY2llcygpOworCisgICAgQVNTRVJUX1RSVUUoVGV4dEZvcm1hdDo6UGFyc2VGcm9tU3RyaW5nKAorICAgICAgIm5hbWU6ICdmb28ucHJvdG8nIgorICAgICAgImRlcGVuZGVuY3k6ICdiYXIucHJvdG8nIgorICAgICAgImRlcGVuZGVuY3k6ICdiYXoucHJvdG8nIgorICAgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICAgIiAgbmFtZTogJ0ZvbyciCisgICAgICAiICBmaWVsZCB7IG5hbWU6J2JhcicgbnVtYmVyOjEgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZV9uYW1lOidCYXInIH0iCisgICAgICAiICBmaWVsZCB7IG5hbWU6J2JheicgbnVtYmVyOjIgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZV9uYW1lOidCYXonIH0iCisgICAgICAiICBmaWVsZCB7IG5hbWU6J3F1eCcgbnVtYmVyOjMgbGFiZWw6TEFCRUxfT1BUSU9OQUwiCisgICAgICAiICAgIHR5cGVfbmFtZTogJy5jb3JnZS5RdXgnIgorICAgICAgIiAgICB0eXBlOiBUWVBFX0VOVU0iCisgICAgICAiICAgIG9wdGlvbnMgeyIKKyAgICAgICIgICAgICB1bmludGVycHJldGVkX29wdGlvbiB7IgorICAgICAgIiAgICAgICAgbmFtZSB7IgorICAgICAgIiAgICAgICAgICBuYW1lX3BhcnQ6ICdncmF1bHQnIgorICAgICAgIiAgICAgICAgICBpc19leHRlbnNpb246IHRydWUiCisgICAgICAiICAgICAgICB9IgorICAgICAgIiAgICAgICAgcG9zaXRpdmVfaW50X3ZhbHVlOiAxMjM0IgorICAgICAgIiAgICAgIH0iCisgICAgICAiICAgIH0iCisgICAgICAiICB9IgorICAgICAgIn0iLAorICAgICAgJmZvb19wcm90bykpOworICAgIEFTU0VSVF9UUlVFKFRleHRGb3JtYXQ6OlBhcnNlRnJvbVN0cmluZygKKyAgICAgICJuYW1lOiAnYmFyLnByb3RvJyIKKyAgICAgICJtZXNzYWdlX3R5cGUgeyBuYW1lOiAnQmFyJyB9IiwKKyAgICAgICZiYXJfcHJvdG8pKTsKKworICAgIC8vIENvbGxlY3QgcG9pbnRlcnMgdG8gc3R1ZmYuCisgICAgYmFyX2ZpbGVfID0gQnVpbGRGaWxlKGJhcl9wcm90byk7CisgICAgQVNTRVJUX1RSVUUoYmFyX2ZpbGVfICE9IE5VTEwpOworCisgICAgQVNTRVJUX0VRKDEsIGJhcl9maWxlXy0+bWVzc2FnZV90eXBlX2NvdW50KCkpOworICAgIGJhcl90eXBlXyA9IGJhcl9maWxlXy0+bWVzc2FnZV90eXBlKDApOworCisgICAgZm9vX2ZpbGVfID0gQnVpbGRGaWxlKGZvb19wcm90byk7CisgICAgQVNTRVJUX1RSVUUoZm9vX2ZpbGVfICE9IE5VTEwpOworCisgICAgQVNTRVJUX0VRKDEsIGZvb19maWxlXy0+bWVzc2FnZV90eXBlX2NvdW50KCkpOworICAgIGZvb190eXBlXyA9IGZvb19maWxlXy0+bWVzc2FnZV90eXBlKDApOworCisgICAgQVNTRVJUX0VRKDMsIGZvb190eXBlXy0+ZmllbGRfY291bnQoKSk7CisgICAgYmFyX2ZpZWxkXyA9IGZvb190eXBlXy0+ZmllbGQoMCk7CisgICAgYmF6X2ZpZWxkXyA9IGZvb190eXBlXy0+ZmllbGQoMSk7CisgICAgcXV4X2ZpZWxkXyA9IGZvb190eXBlXy0+ZmllbGQoMik7CisgIH0KKworICBjb25zdCBGaWxlRGVzY3JpcHRvciogQnVpbGRGaWxlKGNvbnN0IEZpbGVEZXNjcmlwdG9yUHJvdG8mIHByb3RvKSB7CisgICAgc3dpdGNoIChtb2RlKCkpIHsKKyAgICAgIGNhc2UgTk9fREFUQUJBU0U6CisgICAgICAgIHJldHVybiBwb29sXy0+QnVpbGRGaWxlKHByb3RvKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIEZBTExCQUNLX0RBVEFCQVNFOiB7CisgICAgICAgIEVYUEVDVF9UUlVFKGRiXy5BZGQocHJvdG8pKTsKKyAgICAgICAgcmV0dXJuIHBvb2xfLT5GaW5kRmlsZUJ5TmFtZShwcm90by5uYW1lKCkpOworICAgICAgfQorICAgIH0KKyAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ2FuJ3QgZ2V0IGhlcmUuIjsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorCisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBiYXJfZmlsZV87CisgIGNvbnN0IERlc2NyaXB0b3IqIGJhcl90eXBlXzsKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZvb19maWxlXzsKKyAgY29uc3QgRGVzY3JpcHRvciogZm9vX3R5cGVfOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGJhcl9maWVsZF87CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogYmF6X2ZpZWxkXzsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBxdXhfZmllbGRfOworCisgIFNpbXBsZURlc2NyaXB0b3JEYXRhYmFzZSBkYl87ICAgICAgICAvLyB1c2VkIGlmIGluIEZBTExCQUNLX0RBVEFCQVNFIG1vZGUuCisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8RGVzY3JpcHRvclBvb2w+IHBvb2xfOworfTsKKworVEVTVF9QKEFsbG93VW5rbm93bkRlcGVuZGVuY2llc1Rlc3QsIFBsYWNlaG9sZGVyRmlsZSkgeworICBBU1NFUlRfRVEoMiwgZm9vX2ZpbGVfLT5kZXBlbmRlbmN5X2NvdW50KCkpOworICBFWFBFQ1RfRVEoYmFyX2ZpbGVfLCBmb29fZmlsZV8tPmRlcGVuZGVuY3koMCkpOworICBFWFBFQ1RfRkFMU0UoYmFyX2ZpbGVfLT5pc19wbGFjZWhvbGRlcigpKTsKKworICBjb25zdCBGaWxlRGVzY3JpcHRvciogYmF6X2ZpbGUgPSBmb29fZmlsZV8tPmRlcGVuZGVuY3koMSk7CisgIEVYUEVDVF9FUSgiYmF6LnByb3RvIiwgYmF6X2ZpbGUtPm5hbWUoKSk7CisgIEVYUEVDVF9FUSgwLCBiYXpfZmlsZS0+bWVzc2FnZV90eXBlX2NvdW50KCkpOworICBFWFBFQ1RfVFJVRShiYXpfZmlsZS0+aXNfcGxhY2Vob2xkZXIoKSk7CisKKyAgLy8gUGxhY2Vob2xkZXIgZmlsZXMgc2hvdWxkIG5vdCBiZSBmaW5kYWJsZS4KKyAgRVhQRUNUX0VRKGJhcl9maWxlXywgcG9vbF8tPkZpbmRGaWxlQnlOYW1lKGJhcl9maWxlXy0+bmFtZSgpKSk7CisgIEVYUEVDVF9UUlVFKHBvb2xfLT5GaW5kRmlsZUJ5TmFtZShiYXpfZmlsZS0+bmFtZSgpKSA9PSBOVUxMKTsKKworICAvLyBDb3B5KlRvIHNob3VsZCBub3QgY3Jhc2ggZm9yIHBsYWNlaG9sZGVyIGZpbGVzLgorICBGaWxlRGVzY3JpcHRvclByb3RvIGJhel9maWxlX3Byb3RvOworICBiYXpfZmlsZS0+Q29weVRvKCZiYXpfZmlsZV9wcm90byk7CisgIGJhel9maWxlLT5Db3B5U291cmNlQ29kZUluZm9UbygmYmF6X2ZpbGVfcHJvdG8pOworICBFWFBFQ1RfRkFMU0UoYmF6X2ZpbGVfcHJvdG8uaGFzX3NvdXJjZV9jb2RlX2luZm8oKSk7Cit9CisKK1RFU1RfUChBbGxvd1Vua25vd25EZXBlbmRlbmNpZXNUZXN0LCBQbGFjZWhvbGRlclR5cGVzKSB7CisgIEFTU0VSVF9FUShGaWVsZERlc2NyaXB0b3I6OlRZUEVfTUVTU0FHRSwgYmFyX2ZpZWxkXy0+dHlwZSgpKTsKKyAgRVhQRUNUX0VRKGJhcl90eXBlXywgYmFyX2ZpZWxkXy0+bWVzc2FnZV90eXBlKCkpOworICBFWFBFQ1RfRkFMU0UoYmFyX3R5cGVfLT5pc19wbGFjZWhvbGRlcigpKTsKKworICBBU1NFUlRfRVEoRmllbGREZXNjcmlwdG9yOjpUWVBFX01FU1NBR0UsIGJhel9maWVsZF8tPnR5cGUoKSk7CisgIGNvbnN0IERlc2NyaXB0b3IqIGJhel90eXBlID0gYmF6X2ZpZWxkXy0+bWVzc2FnZV90eXBlKCk7CisgIEVYUEVDVF9FUSgiQmF6IiwgYmF6X3R5cGUtPm5hbWUoKSk7CisgIEVYUEVDVF9FUSgiQmF6IiwgYmF6X3R5cGUtPmZ1bGxfbmFtZSgpKTsKKyAgRVhQRUNUX0VRKDAsIGJhel90eXBlLT5leHRlbnNpb25fcmFuZ2VfY291bnQoKSk7CisgIEVYUEVDVF9UUlVFKGJhel90eXBlLT5pc19wbGFjZWhvbGRlcigpKTsKKworICBBU1NFUlRfRVEoRmllbGREZXNjcmlwdG9yOjpUWVBFX0VOVU0sIHF1eF9maWVsZF8tPnR5cGUoKSk7CisgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBxdXhfdHlwZSA9IHF1eF9maWVsZF8tPmVudW1fdHlwZSgpOworICBFWFBFQ1RfRVEoIlF1eCIsIHF1eF90eXBlLT5uYW1lKCkpOworICBFWFBFQ1RfRVEoImNvcmdlLlF1eCIsIHF1eF90eXBlLT5mdWxsX25hbWUoKSk7CisgIEVYUEVDVF9UUlVFKHF1eF90eXBlLT5pc19wbGFjZWhvbGRlcigpKTsKKworICAvLyBQbGFjZWhvbGRlciB0eXBlcyBzaG91bGQgbm90IGJlIGZpbmRhYmxlLgorICBFWFBFQ1RfRVEoYmFyX3R5cGVfLCBwb29sXy0+RmluZE1lc3NhZ2VUeXBlQnlOYW1lKGJhcl90eXBlXy0+ZnVsbF9uYW1lKCkpKTsKKyAgRVhQRUNUX1RSVUUocG9vbF8tPkZpbmRNZXNzYWdlVHlwZUJ5TmFtZShiYXpfdHlwZS0+ZnVsbF9uYW1lKCkpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShwb29sXy0+RmluZEVudW1UeXBlQnlOYW1lKHF1eF90eXBlLT5mdWxsX25hbWUoKSkgPT0gTlVMTCk7Cit9CisKK1RFU1RfUChBbGxvd1Vua25vd25EZXBlbmRlbmNpZXNUZXN0LCBDb3B5VG8pIHsKKyAgLy8gRmllbGREZXNjcmlwdG9yOjpDb3B5VG8oKSBzaG91bGQgd3JpdGUgbm9uLWZ1bGx5LXF1YWxpZmllZCB0eXBlIG5hbWVzCisgIC8vIGZvciBwbGFjZWhvbGRlciB0eXBlcyB3aGljaCB3ZXJlIG5vdCBvcmlnaW5hbGx5IGZ1bGx5LXF1YWxpZmllZC4KKyAgRmllbGREZXNjcmlwdG9yUHJvdG8gcHJvdG87CisKKyAgLy8gQmFyIGlzIG5vdCBhIHBsYWNlaG9sZGVyLCBzbyBpdCBpcyBmdWxseS1xdWFsaWZpZWQuCisgIGJhcl9maWVsZF8tPkNvcHlUbygmcHJvdG8pOworICBFWFBFQ1RfRVEoIi5CYXIiLCBwcm90by50eXBlX25hbWUoKSk7CisgIEVYUEVDVF9FUShGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9NRVNTQUdFLCBwcm90by50eXBlKCkpOworCisgIC8vIEJheiBpcyBhbiB1bnF1YWxpZmllZCBwbGFjZWhvbGRlci4KKyAgcHJvdG8uQ2xlYXIoKTsKKyAgYmF6X2ZpZWxkXy0+Q29weVRvKCZwcm90byk7CisgIEVYUEVDVF9FUSgiQmF6IiwgcHJvdG8udHlwZV9uYW1lKCkpOworICBFWFBFQ1RfRkFMU0UocHJvdG8uaGFzX3R5cGUoKSk7CisKKyAgLy8gUXV4IGlzIGEgZnVsbHktcXVhbGlmaWVkIHBsYWNlaG9sZGVyLgorICBwcm90by5DbGVhcigpOworICBxdXhfZmllbGRfLT5Db3B5VG8oJnByb3RvKTsKKyAgRVhQRUNUX0VRKCIuY29yZ2UuUXV4IiwgcHJvdG8udHlwZV9uYW1lKCkpOworICBFWFBFQ1RfRVEoRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfRU5VTSwgcHJvdG8udHlwZSgpKTsKK30KKworVEVTVF9QKEFsbG93VW5rbm93bkRlcGVuZGVuY2llc1Rlc3QsIEN1c3RvbU9wdGlvbnMpIHsKKyAgLy8gUXV4IHNob3VsZCBzdGlsbCBoYXZlIHRoZSB1bmludGVycHJldGVkIG9wdGlvbiBhdHRhY2hlZC4KKyAgQVNTRVJUX0VRKDEsIHF1eF9maWVsZF8tPm9wdGlvbnMoKS51bmludGVycHJldGVkX29wdGlvbl9zaXplKCkpOworICBjb25zdCBVbmludGVycHJldGVkT3B0aW9uJiBvcHRpb24gPQorICAgIHF1eF9maWVsZF8tPm9wdGlvbnMoKS51bmludGVycHJldGVkX29wdGlvbigwKTsKKyAgQVNTRVJUX0VRKDEsIG9wdGlvbi5uYW1lX3NpemUoKSk7CisgIEVYUEVDVF9FUSgiZ3JhdWx0Iiwgb3B0aW9uLm5hbWUoMCkubmFtZV9wYXJ0KCkpOworfQorCitURVNUX1AoQWxsb3dVbmtub3duRGVwZW5kZW5jaWVzVGVzdCwgVW5rbm93bkV4dGVuZGVlKSB7CisgIC8vIFRlc3QgdGhhdCB3ZSBjYW4gZXh0ZW5kIGFuIHVua25vd24gdHlwZS4gIFRoaXMgaXMgc2xpZ2h0bHkgdHJpY2t5IGJlY2F1c2UKKyAgLy8gaXQgbWVhbnMgdGhhdCB0aGUgcGxhY2Vob2xkZXIgdHlwZSBtdXN0IGhhdmUgYW4gZXh0ZW5zaW9uIHJhbmdlLgorCisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZXh0ZW5zaW9uX3Byb3RvOworCisgIEFTU0VSVF9UUlVFKFRleHRGb3JtYXQ6OlBhcnNlRnJvbVN0cmluZygKKyAgICAibmFtZTogJ2V4dGVuc2lvbi5wcm90byciCisgICAgImV4dGVuc2lvbiB7IGV4dGVuZGVlOiAnVW5rbm93blR5cGUnIG5hbWU6J3NvbWVfZXh0ZW5zaW9uJyBudW1iZXI6MTIzIgorICAgICIgICAgICAgICAgICBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgfSIsCisgICAgJmV4dGVuc2lvbl9wcm90bykpOworICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSA9IEJ1aWxkRmlsZShleHRlbnNpb25fcHJvdG8pOworCisgIEFTU0VSVF9UUlVFKGZpbGUgIT0gTlVMTCk7CisKKyAgQVNTRVJUX0VRKDEsIGZpbGUtPmV4dGVuc2lvbl9jb3VudCgpKTsKKyAgY29uc3QgRGVzY3JpcHRvciogZXh0ZW5kZWUgPSBmaWxlLT5leHRlbnNpb24oMCktPmNvbnRhaW5pbmdfdHlwZSgpOworICBFWFBFQ1RfRVEoIlVua25vd25UeXBlIiwgZXh0ZW5kZWUtPm5hbWUoKSk7CisgIEVYUEVDVF9UUlVFKGV4dGVuZGVlLT5pc19wbGFjZWhvbGRlcigpKTsKKyAgQVNTRVJUX0VRKDEsIGV4dGVuZGVlLT5leHRlbnNpb25fcmFuZ2VfY291bnQoKSk7CisgIEVYUEVDVF9FUSgxLCBleHRlbmRlZS0+ZXh0ZW5zaW9uX3JhbmdlKDApLT5zdGFydCk7CisgIEVYUEVDVF9FUShGaWVsZERlc2NyaXB0b3I6OmtNYXhOdW1iZXIgKyAxLCBleHRlbmRlZS0+ZXh0ZW5zaW9uX3JhbmdlKDApLT5lbmQpOworfQorCitURVNUX1AoQWxsb3dVbmtub3duRGVwZW5kZW5jaWVzVGVzdCwgQ3VzdG9tT3B0aW9uKSB7CisgIC8vIFRlc3QgdGhhdCB3ZSBjYW4gdXNlIGEgY3VzdG9tIG9wdGlvbiB3aXRob3V0IGhhdmluZyBwYXJzZWQKKyAgLy8gZGVzY3JpcHRvci5wcm90by4KKworICBGaWxlRGVzY3JpcHRvclByb3RvIG9wdGlvbl9wcm90bzsKKworICBBU1NFUlRfVFJVRShUZXh0Rm9ybWF0OjpQYXJzZUZyb21TdHJpbmcoCisgICAgIm5hbWU6IFwidW5rbm93bl9jdXN0b21fb3B0aW9ucy5wcm90b1wiICIKKyAgICAiZGVwZW5kZW5jeTogXCJnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90b1wiICIKKyAgICAiZXh0ZW5zaW9uIHsgIgorICAgICIgIGV4dGVuZGVlOiBcImdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9uc1wiICIKKyAgICAiICBuYW1lOiBcInNvbWVfb3B0aW9uXCIgIgorICAgICIgIG51bWJlcjogMTIzNDU2ICIKKyAgICAiICBsYWJlbDogTEFCRUxfT1BUSU9OQUwgIgorICAgICIgIHR5cGU6IFRZUEVfSU5UMzIgIgorICAgICJ9ICIKKyAgICAib3B0aW9ucyB7ICIKKyAgICAiICB1bmludGVycHJldGVkX29wdGlvbiB7ICIKKyAgICAiICAgIG5hbWUgeyAiCisgICAgIiAgICAgIG5hbWVfcGFydDogXCJzb21lX29wdGlvblwiICIKKyAgICAiICAgICAgaXNfZXh0ZW5zaW9uOiB0cnVlICIKKyAgICAiICAgIH0gIgorICAgICIgICAgcG9zaXRpdmVfaW50X3ZhbHVlOiAxMjM0ICIKKyAgICAiICB9ICIKKyAgICAiICB1bmludGVycHJldGVkX29wdGlvbiB7ICIKKyAgICAiICAgIG5hbWUgeyAiCisgICAgIiAgICAgIG5hbWVfcGFydDogXCJ1bmtub3duX29wdGlvblwiICIKKyAgICAiICAgICAgaXNfZXh0ZW5zaW9uOiB0cnVlICIKKyAgICAiICAgIH0gIgorICAgICIgICAgcG9zaXRpdmVfaW50X3ZhbHVlOiAxMjM0ICIKKyAgICAiICB9ICIKKyAgICAiICB1bmludGVycHJldGVkX29wdGlvbiB7ICIKKyAgICAiICAgIG5hbWUgeyAiCisgICAgIiAgICAgIG5hbWVfcGFydDogXCJvcHRpbWl6ZV9mb3JcIiAiCisgICAgIiAgICAgIGlzX2V4dGVuc2lvbjogZmFsc2UgIgorICAgICIgICAgfSAiCisgICAgIiAgICBpZGVudGlmaWVyX3ZhbHVlOiBcIlNQRUVEXCIgIgorICAgICIgIH0gIgorICAgICJ9IiwKKyAgICAmb3B0aW9uX3Byb3RvKSk7CisKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUgPSBCdWlsZEZpbGUob3B0aW9uX3Byb3RvKTsKKyAgQVNTRVJUX1RSVUUoZmlsZSAhPSBOVUxMKTsKKworICAvLyBWZXJpZnkgdGhhdCBubyBleHRlbnNpb24gb3B0aW9ucyB3ZXJlIHNldCwgYnV0IHRoZXkgd2VyZSBsZWZ0IGFzCisgIC8vIHVuaW50ZXJwcmV0ZWRfb3B0aW9ucy4KKyAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+IGZpZWxkczsKKyAgZmlsZS0+b3B0aW9ucygpLkdldFJlZmxlY3Rpb24oKS0+TGlzdEZpZWxkcyhmaWxlLT5vcHRpb25zKCksICZmaWVsZHMpOworICBBU1NFUlRfRVEoMiwgZmllbGRzLnNpemUoKSk7CisgIEVYUEVDVF9UUlVFKGZpbGUtPm9wdGlvbnMoKS5oYXNfb3B0aW1pemVfZm9yKCkpOworICBFWFBFQ1RfRVEoMiwgZmlsZS0+b3B0aW9ucygpLnVuaW50ZXJwcmV0ZWRfb3B0aW9uX3NpemUoKSk7Cit9CisKK1RFU1RfUChBbGxvd1Vua25vd25EZXBlbmRlbmNpZXNUZXN0LAorICAgICAgIFVuZGVjbGFyZWREZXBlbmRlbmN5VHJpZ2dlcnNCdWlsZE9mRGVwZW5kZW5jeSkgeworICAvLyBDcmF6eSBjYXNlOiBzdXBwb3NlIGZvby5wcm90byByZWZlcnMgdG8gYSBzeW1ib2wgd2l0aG91dCBkZWNsYXJpbmcgdGhlCisgIC8vIGRlcGVuZGVuY3kgdGhhdCBmaW5kcyBpdC4gSW4gdGhlIGV2ZW50IHRoYXQgdGhlIHBvb2wgaXMgYmFja2VkIGJ5IGEKKyAgLy8gRGVzY3JpcHRvckRhdGFiYXNlLCB0aGUgcG9vbCB3aWxsIGF0dGVtcHQgdG8gZmluZCB0aGUgc3ltYm9sIGluIHRoZQorICAvLyBkYXRhYmFzZS4gSWYgc3VjY2Vzc2Z1bCwgaXQgd2lsbCBidWlsZCB0aGUgdW5kZWNsYXJlZCBkZXBlbmRlbmN5IHRvIHZlcmlmeQorICAvLyB0aGF0IHRoZSBmaWxlIGRvZXMgaW5kZWVkIGNvbnRhaW4gdGhlIHN5bWJvbC4gSWYgdGhhdCBmaWxlIGZhaWxzIHRvIGJ1aWxkLAorICAvLyB0aGVuIGl0cyBkZXNjcmlwdG9ycyBtdXN0IGJlIHJvbGxlZCBiYWNrLiBIb3dldmVyLCB3ZSBzdGlsbCB3YW50IGZvby5wcm90bworICAvLyB0byBidWlsZCBzdWNjZXNzZnVsbHksIHNpbmNlIHdlIGFyZSBhbGxvd2luZyB1bmtub3duIGRlcGVuZGVuY2llcy4KKworICBGaWxlRGVzY3JpcHRvclByb3RvIHVuZGVjbGFyZWRfZGVwX3Byb3RvOworICAvLyBXZSBtYWtlIHRoaXMgZmlsZSBmYWlsIHRvIGJ1aWxkIGJ5IGdpdmluZyBpdCB0d28gZmllbGRzIHdpdGggdGFnIDEuCisgIEFTU0VSVF9UUlVFKFRleHRGb3JtYXQ6OlBhcnNlRnJvbVN0cmluZygKKyAgICAibmFtZTogXCJpbnZhbGlkX2ZpbGVfYXNfdW5kZWNsYXJlZF9kZXAucHJvdG9cIiAiCisgICAgInBhY2thZ2U6IFwidW5kZWNsYXJlZFwiICIKKyAgICAibWVzc2FnZV90eXBlOiB7ICAiCisgICAgIiAgbmFtZTogXCJRdXV4XCIgICIKKyAgICAiICBmaWVsZCB7ICIKKyAgICAiICAgIG5hbWU6J3F1eCcgbnVtYmVyOjEgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZTogVFlQRV9JTlQzMiAiCisgICAgIiAgfSIKKyAgICAiICBmaWVsZCB7ICIKKyAgICAiICAgIG5hbWU6J3F1dXgnIG51bWJlcjoxIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6IFRZUEVfSU5UNjQgIgorICAgICIgIH0iCisgICAgIn0iLAorICAgICZ1bmRlY2xhcmVkX2RlcF9wcm90bykpOworICAvLyBXZSBjYW4ndCB1c2UgdGhlIEJ1aWxkRmlsZSgpIGhlbHBlciBiZWNhdXNlIHdlIGRvbid0IGFjdHVhbGx5IHdhbnQgdG8gYnVpbGQKKyAgLy8gaXQgaW50byB0aGUgZGVzY3JpcHRvciBwb29sIGluIHRoZSBmYWxsYmFjayBkYXRhYmFzZSBjYXNlOiBpdCBqdXN0IG5lZWRzIHRvCisgIC8vIGJlIHNpdHRpbmcgaW4gdGhlIGRhdGFiYXNlIHNvIHRoYXQgaXQgZ2V0cyBidWlsdCBkdXJpbmcgdGhlIGJ1aWxkaW5nIG9mCisgIC8vIHRlc3QucHJvdG8gYmVsb3cuCisgIHN3aXRjaCAobW9kZSgpKSB7CisgICAgY2FzZSBOT19EQVRBQkFTRTogeworICAgICAgQVNTRVJUX1RSVUUocG9vbF8tPkJ1aWxkRmlsZSh1bmRlY2xhcmVkX2RlcF9wcm90bykgPT0gTlVMTCk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBGQUxMQkFDS19EQVRBQkFTRTogeworICAgICAgQVNTRVJUX1RSVUUoZGJfLkFkZCh1bmRlY2xhcmVkX2RlcF9wcm90bykpOworICAgIH0KKyAgfQorCisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gdGVzdF9wcm90bzsKKyAgQVNTRVJUX1RSVUUoVGV4dEZvcm1hdDo6UGFyc2VGcm9tU3RyaW5nKAorICAgICJuYW1lOiBcInRlc3QucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZTogeyAiCisgICAgIiAgbmFtZTogXCJDb3JnZVwiICIKKyAgICAiICBmaWVsZCB7ICIKKyAgICAiICAgIG5hbWU6J3F1dXgnIG51bWJlcjoxIGxhYmVsOiBMQUJFTF9PUFRJT05BTCAiCisgICAgIiAgICB0eXBlX25hbWU6J3VuZGVjbGFyZWQuUXV1eCcgdHlwZTogVFlQRV9NRVNTQUdFICIKKyAgICAiICB9IgorICAgICJ9IiwKKyAgICAmdGVzdF9wcm90bykpOworCisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlID0gQnVpbGRGaWxlKHRlc3RfcHJvdG8pOworICBBU1NFUlRfVFJVRShmaWxlICE9IE5VTEwpOworICBHT09HTEVfTE9HKElORk8pIDw8IGZpbGUtPkRlYnVnU3RyaW5nKCk7CisKKyAgRVhQRUNUX0VRKDAsIGZpbGUtPmRlcGVuZGVuY3lfY291bnQoKSk7CisgIEFTU0VSVF9FUSgxLCBmaWxlLT5tZXNzYWdlX3R5cGVfY291bnQoKSk7CisgIGNvbnN0IERlc2NyaXB0b3IqIGNvcmdlX2Rlc2MgPSBmaWxlLT5tZXNzYWdlX3R5cGUoMCk7CisgIEFTU0VSVF9FUSgiQ29yZ2UiLCBjb3JnZV9kZXNjLT5uYW1lKCkpOworICBBU1NFUlRfRVEoMSwgY29yZ2VfZGVzYy0+ZmllbGRfY291bnQoKSk7CisgIEVYUEVDVF9GQUxTRShjb3JnZV9kZXNjLT5pc19wbGFjZWhvbGRlcigpKTsKKworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHF1dXhfZmllbGQgPSBjb3JnZV9kZXNjLT5maWVsZCgwKTsKKyAgQVNTRVJUX0VRKEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9NRVNTQUdFLCBxdXV4X2ZpZWxkLT50eXBlKCkpOworICBBU1NFUlRfRVEoIlF1dXgiLCBxdXV4X2ZpZWxkLT5tZXNzYWdlX3R5cGUoKS0+bmFtZSgpKTsKKyAgQVNTRVJUX0VRKCJ1bmRlY2xhcmVkLlF1dXgiLCBxdXV4X2ZpZWxkLT5tZXNzYWdlX3R5cGUoKS0+ZnVsbF9uYW1lKCkpOworICBFWFBFQ1RfVFJVRShxdXV4X2ZpZWxkLT5tZXNzYWdlX3R5cGUoKS0+aXNfcGxhY2Vob2xkZXIoKSk7CisgIC8vIFRoZSBwbGFjZSBob2xkZXIgdHlwZSBzaG91bGQgbm90IGJlIGZpbmRhYmxlLgorICBBU1NFUlRfVFJVRShwb29sXy0+RmluZE1lc3NhZ2VUeXBlQnlOYW1lKCJ1bmRlY2xhcmVkLlF1dXgiKSA9PSBOVUxMKTsKK30KKworSU5TVEFOVElBVEVfVEVTVF9DQVNFX1AoRGF0YWJhc2VTb3VyY2UsCisgICAgICAgICAgICAgICAgICAgICAgICBBbGxvd1Vua25vd25EZXBlbmRlbmNpZXNUZXN0LAorICAgICAgICAgICAgICAgICAgICAgICAgdGVzdGluZzo6VmFsdWVzKE5PX0RBVEFCQVNFLCBGQUxMQkFDS19EQVRBQkFTRSkpOworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK1RFU1QoQ3VzdG9tT3B0aW9ucywgT3B0aW9uTG9jYXRpb25zKSB7CisgIGNvbnN0IERlc2NyaXB0b3IqIG1lc3NhZ2UgPQorICAgICAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnM6OmRlc2NyaXB0b3IoKTsKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUgPSBtZXNzYWdlLT5maWxlKCk7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBtZXNzYWdlLT5GaW5kRmllbGRCeU5hbWUoImZpZWxkMSIpOworICBjb25zdCBFbnVtRGVzY3JpcHRvciogZW5tID0gbWVzc2FnZS0+RmluZEVudW1UeXBlQnlOYW1lKCJBbkVudW0iKTsKKyAgLy8gVE9ETyhiZW5qeSk6IFN1cHBvcnQgRW51bVZhbHVlIG9wdGlvbnMsIG9uY2UgdGhlIGNvbXBpbGVyIGRvZXMuCisgIGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yKiBzZXJ2aWNlID0KKyAgICAgIGZpbGUtPkZpbmRTZXJ2aWNlQnlOYW1lKCJUZXN0U2VydmljZVdpdGhDdXN0b21PcHRpb25zIik7CisgIGNvbnN0IE1ldGhvZERlc2NyaXB0b3IqIG1ldGhvZCA9IHNlcnZpY2UtPkZpbmRNZXRob2RCeU5hbWUoIkZvbyIpOworCisgIEVYUEVDVF9FUShHT09HTEVfTE9OR0xPTkcoOTg3NjU0MzIxMCksCisgICAgICAgICAgICBmaWxlLT5vcHRpb25zKCkuR2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0OjpmaWxlX29wdDEpKTsKKyAgRVhQRUNUX0VRKC01NiwKKyAgICAgICAgICAgIG1lc3NhZ2UtPm9wdGlvbnMoKS5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6Om1lc3NhZ2Vfb3B0MSkpOworICBFWFBFQ1RfRVEoR09PR0xFX0xPTkdMT05HKDg3NjU0MzIxMDkpLAorICAgICAgICAgICAgZmllbGQtPm9wdGlvbnMoKS5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OmZpZWxkX29wdDEpKTsKKyAgRVhQRUNUX0VRKDQyLCAgLy8gQ2hlY2sgdGhhdCB3ZSBnZXQgdGhlIGRlZmF1bHQgZm9yIGFuIG9wdGlvbiB3ZSBkb24ndCBzZXQuCisgICAgICAgICAgICBmaWVsZC0+b3B0aW9ucygpLkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6ZmllbGRfb3B0MikpOworICBFWFBFQ1RfRVEoLTc4OSwKKyAgICAgICAgICAgIGVubS0+b3B0aW9ucygpLkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6ZW51bV9vcHQxKSk7CisgIEVYUEVDVF9FUSgxMjMsCisgICAgICAgICAgICBlbm0tPnZhbHVlKDEpLT5vcHRpb25zKCkuR2V0RXh0ZW5zaW9uKAorICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdDo6ZW51bV92YWx1ZV9vcHQxKSk7CisgIEVYUEVDVF9FUShHT09HTEVfTE9OR0xPTkcoLTk4NzY1NDMyMTApLAorICAgICAgICAgICAgc2VydmljZS0+b3B0aW9ucygpLkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6c2VydmljZV9vcHQxKSk7CisgIEVYUEVDVF9FUShwcm90b2J1Zl91bml0dGVzdDo6TUVUSE9ET1BUMV9WQUwyLAorICAgICAgICAgICAgbWV0aG9kLT5vcHRpb25zKCkuR2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0OjptZXRob2Rfb3B0MSkpOworCisgIC8vIFNlZSB0aGF0IHRoZSByZWd1bGFyIG9wdGlvbnMgd2VudCB0aHJvdWdoIHVuc2NhdGhlZC4KKyAgRVhQRUNUX1RSVUUobWVzc2FnZS0+b3B0aW9ucygpLmhhc19tZXNzYWdlX3NldF93aXJlX2Zvcm1hdCgpKTsKKyAgRVhQRUNUX0VRKEZpZWxkT3B0aW9uczo6Q09SRCwgZmllbGQtPm9wdGlvbnMoKS5jdHlwZSgpKTsKK30KKworVEVTVChDdXN0b21PcHRpb25zLCBPcHRpb25UeXBlcykgeworICBjb25zdCBNZXNzYWdlT3B0aW9ucyogb3B0aW9ucyA9IE5VTEw7CisKKyAgb3B0aW9ucyA9CisgICAgICAmcHJvdG9idWZfdW5pdHRlc3Q6OkN1c3RvbU9wdGlvbk1pbkludGVnZXJWYWx1ZXM6OmRlc2NyaXB0b3IoKS0+b3B0aW9ucygpOworICBFWFBFQ1RfRVEoZmFsc2UgICAgLCBvcHRpb25zLT5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OmJvb2xfb3B0KSk7CisgIEVYUEVDVF9FUShraW50MzJtaW4sIG9wdGlvbnMtPkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6aW50MzJfb3B0KSk7CisgIEVYUEVDVF9FUShraW50NjRtaW4sIG9wdGlvbnMtPkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6aW50NjRfb3B0KSk7CisgIEVYUEVDVF9FUSgwICAgICAgICAsIG9wdGlvbnMtPkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6dWludDMyX29wdCkpOworICBFWFBFQ1RfRVEoMCAgICAgICAgLCBvcHRpb25zLT5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OnVpbnQ2NF9vcHQpKTsKKyAgRVhQRUNUX0VRKGtpbnQzMm1pbiwgb3B0aW9ucy0+R2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0OjpzaW50MzJfb3B0KSk7CisgIEVYUEVDVF9FUShraW50NjRtaW4sIG9wdGlvbnMtPkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6c2ludDY0X29wdCkpOworICBFWFBFQ1RfRVEoMCAgICAgICAgLCBvcHRpb25zLT5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OmZpeGVkMzJfb3B0KSk7CisgIEVYUEVDVF9FUSgwICAgICAgICAsIG9wdGlvbnMtPkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6Zml4ZWQ2NF9vcHQpKTsKKyAgRVhQRUNUX0VRKGtpbnQzMm1pbiwgb3B0aW9ucy0+R2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0OjpzZml4ZWQzMl9vcHQpKTsKKyAgRVhQRUNUX0VRKGtpbnQ2NG1pbiwgb3B0aW9ucy0+R2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0OjpzZml4ZWQ2NF9vcHQpKTsKKworICBvcHRpb25zID0KKyAgICAgICZwcm90b2J1Zl91bml0dGVzdDo6Q3VzdG9tT3B0aW9uTWF4SW50ZWdlclZhbHVlczo6ZGVzY3JpcHRvcigpLT5vcHRpb25zKCk7CisgIEVYUEVDVF9FUSh0cnVlICAgICAgLCBvcHRpb25zLT5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OmJvb2xfb3B0KSk7CisgIEVYUEVDVF9FUShraW50MzJtYXggLCBvcHRpb25zLT5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OmludDMyX29wdCkpOworICBFWFBFQ1RfRVEoa2ludDY0bWF4ICwgb3B0aW9ucy0+R2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0OjppbnQ2NF9vcHQpKTsKKyAgRVhQRUNUX0VRKGt1aW50MzJtYXgsIG9wdGlvbnMtPkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6dWludDMyX29wdCkpOworICBFWFBFQ1RfRVEoa3VpbnQ2NG1heCwgb3B0aW9ucy0+R2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0Ojp1aW50NjRfb3B0KSk7CisgIEVYUEVDVF9FUShraW50MzJtYXggLCBvcHRpb25zLT5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OnNpbnQzMl9vcHQpKTsKKyAgRVhQRUNUX0VRKGtpbnQ2NG1heCAsIG9wdGlvbnMtPkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6c2ludDY0X29wdCkpOworICBFWFBFQ1RfRVEoa3VpbnQzMm1heCwgb3B0aW9ucy0+R2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0OjpmaXhlZDMyX29wdCkpOworICBFWFBFQ1RfRVEoa3VpbnQ2NG1heCwgb3B0aW9ucy0+R2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0OjpmaXhlZDY0X29wdCkpOworICBFWFBFQ1RfRVEoa2ludDMybWF4ICwgb3B0aW9ucy0+R2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0OjpzZml4ZWQzMl9vcHQpKTsKKyAgRVhQRUNUX0VRKGtpbnQ2NG1heCAsIG9wdGlvbnMtPkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6c2ZpeGVkNjRfb3B0KSk7CisKKyAgb3B0aW9ucyA9CisgICAgICAmcHJvdG9idWZfdW5pdHRlc3Q6OkN1c3RvbU9wdGlvbk90aGVyVmFsdWVzOjpkZXNjcmlwdG9yKCktPm9wdGlvbnMoKTsKKyAgRVhQRUNUX0VRKC0xMDAsIG9wdGlvbnMtPkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6aW50MzJfb3B0KSk7CisgIEVYUEVDVF9GTE9BVF9FUSgxMi4zNDU2Nzg5LAorICAgICAgICAgICAgICAgICAgb3B0aW9ucy0+R2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0OjpmbG9hdF9vcHQpKTsKKyAgRVhQRUNUX0RPVUJMRV9FUSgxLjIzNDU2Nzg5MDEyMzQ1Njc4OSwKKyAgICAgICAgICAgICAgICAgICBvcHRpb25zLT5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OmRvdWJsZV9vcHQpKTsKKyAgRVhQRUNUX0VRKCJIZWxsbywgXCJXb3JsZFwiIiwKKyAgICAgICAgICAgIG9wdGlvbnMtPkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6c3RyaW5nX29wdCkpOworCisgIEVYUEVDVF9FUShzdHJpbmcoIkhlbGxvXDBXb3JsZCIsIDExKSwKKyAgICAgICAgICAgIG9wdGlvbnMtPkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6Ynl0ZXNfb3B0KSk7CisKKyAgRVhQRUNUX0VRKHByb3RvYnVmX3VuaXR0ZXN0OjpEdW1teU1lc3NhZ2VDb250YWluaW5nRW51bTo6VEVTVF9PUFRJT05fRU5VTV9UWVBFMiwKKyAgICAgICAgICAgIG9wdGlvbnMtPkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6ZW51bV9vcHQpKTsKKworICBvcHRpb25zID0KKyAgICAgICZwcm90b2J1Zl91bml0dGVzdDo6U2V0dGluZ1JlYWxzRnJvbVBvc2l0aXZlSW50czo6ZGVzY3JpcHRvcigpLT5vcHRpb25zKCk7CisgIEVYUEVDVF9GTE9BVF9FUSgxMiwgb3B0aW9ucy0+R2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0OjpmbG9hdF9vcHQpKTsKKyAgRVhQRUNUX0RPVUJMRV9FUSgxNTQsIG9wdGlvbnMtPkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6ZG91YmxlX29wdCkpOworCisgIG9wdGlvbnMgPQorICAgICAgJnByb3RvYnVmX3VuaXR0ZXN0OjpTZXR0aW5nUmVhbHNGcm9tTmVnYXRpdmVJbnRzOjpkZXNjcmlwdG9yKCktPm9wdGlvbnMoKTsKKyAgRVhQRUNUX0ZMT0FUX0VRKC0xMiwgb3B0aW9ucy0+R2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0OjpmbG9hdF9vcHQpKTsKKyAgRVhQRUNUX0RPVUJMRV9FUSgtMTU0LCBvcHRpb25zLT5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OmRvdWJsZV9vcHQpKTsKK30KKworVEVTVChDdXN0b21PcHRpb25zLCBDb21wbGV4RXh0ZW5zaW9uT3B0aW9ucykgeworICBjb25zdCBNZXNzYWdlT3B0aW9ucyogb3B0aW9ucyA9CisgICAgICAmcHJvdG9idWZfdW5pdHRlc3Q6OlZhcmlvdXNDb21wbGV4T3B0aW9uczo6ZGVzY3JpcHRvcigpLT5vcHRpb25zKCk7CisgIEVYUEVDVF9FUShvcHRpb25zLT5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OmNvbXBsZXhfb3B0MSkuZm9vKCksIDQyKTsKKyAgRVhQRUNUX0VRKG9wdGlvbnMtPkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6Y29tcGxleF9vcHQxKS4KKyAgICAgICAgICAgIEdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6cXV1eCksIDMyNCk7CisgIEVYUEVDVF9FUShvcHRpb25zLT5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OmNvbXBsZXhfb3B0MSkuCisgICAgICAgICAgICBHZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OmNvcmdlKS5xdXgoKSwgODc2KTsKKyAgRVhQRUNUX0VRKG9wdGlvbnMtPkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6Y29tcGxleF9vcHQyKS5iYXooKSwgOTg3KTsKKyAgRVhQRUNUX0VRKG9wdGlvbnMtPkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6Y29tcGxleF9vcHQyKS4KKyAgICAgICAgICAgIEdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6Z3JhdWx0KSwgNjU0KTsKKyAgRVhQRUNUX0VRKG9wdGlvbnMtPkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6Y29tcGxleF9vcHQyKS5iYXIoKS5mb28oKSwKKyAgICAgICAgICAgIDc0Myk7CisgIEVYUEVDVF9FUShvcHRpb25zLT5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OmNvbXBsZXhfb3B0MikuYmFyKCkuCisgICAgICAgICAgICBHZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OnF1dXgpLCAxOTk5KTsKKyAgRVhQRUNUX0VRKG9wdGlvbnMtPkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6Y29tcGxleF9vcHQyKS5iYXIoKS4KKyAgICAgICAgICAgIEdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6Y29yZ2UpLnF1eCgpLCAyMDA4KTsKKyAgRVhQRUNUX0VRKG9wdGlvbnMtPkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6Y29tcGxleF9vcHQyKS4KKyAgICAgICAgICAgIEdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6Z2FycGx5KS5mb28oKSwgNzQxKTsKKyAgRVhQRUNUX0VRKG9wdGlvbnMtPkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6Y29tcGxleF9vcHQyKS4KKyAgICAgICAgICAgIEdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6Z2FycGx5KS4KKyAgICAgICAgICAgIEdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6cXV1eCksIDE5OTgpOworICBFWFBFQ1RfRVEob3B0aW9ucy0+R2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0Ojpjb21wbGV4X29wdDIpLgorICAgICAgICAgICAgR2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0OjpnYXJwbHkpLgorICAgICAgICAgICAgR2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0Ojpjb3JnZSkucXV4KCksIDIxMjEpOworICBFWFBFQ1RfRVEob3B0aW9ucy0+R2V0RXh0ZW5zaW9uKAorICAgICAgcHJvdG9idWZfdW5pdHRlc3Q6OkNvbXBsZXhPcHRpb25UeXBlMjo6Q29tcGxleE9wdGlvblR5cGU0Ojpjb21wbGV4X29wdDQpLgorICAgICAgICAgICAgd2FsZG8oKSwgMTk3MSk7CisgIEVYUEVDVF9FUShvcHRpb25zLT5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OmNvbXBsZXhfb3B0MikuCisgICAgICAgICAgICBmcmVkKCkud2FsZG8oKSwgMzIxKTsKKyAgRVhQRUNUX0VRKDksIG9wdGlvbnMtPkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6Y29tcGxleF9vcHQzKS5xdXgoKSk7CisgIEVYUEVDVF9FUSgyMiwgb3B0aW9ucy0+R2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0Ojpjb21wbGV4X29wdDMpLgorICAgICAgICAgICAgICAgIGNvbXBsZXhvcHRpb250eXBlNSgpLnBsdWdoKCkpOworICBFWFBFQ1RfRVEoMjQsIG9wdGlvbnMtPkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6Y29tcGxleG9wdDYpLnh5enp5KCkpOworfQorCitURVNUKEN1c3RvbU9wdGlvbnMsIE9wdGlvbnNGcm9tT3RoZXJGaWxlKSB7CisgIC8vIFRlc3QgdGhhdCB0byB1c2UgYSBjdXN0b20gb3B0aW9uLCB3ZSBvbmx5IG5lZWQgdG8gaW1wb3J0IHRoZSBmaWxlCisgIC8vIGRlZmluaW5nIHRoZSBvcHRpb247IHdlIGRvIG5vdCBhbHNvIGhhdmUgdG8gaW1wb3J0IGRlc2NyaXB0b3IucHJvdG8uCisgIERlc2NyaXB0b3JQb29sIHBvb2w7CisKKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICBGaWxlRGVzY3JpcHRvclByb3RvOjpkZXNjcmlwdG9yKCktPmZpbGUoKS0+Q29weVRvKCZmaWxlX3Byb3RvKTsKKyAgQVNTRVJUX1RSVUUocG9vbC5CdWlsZEZpbGUoZmlsZV9wcm90bykgIT0gTlVMTCk7CisKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnM6OmRlc2NyaXB0b3IoKQorICAgIC0+ZmlsZSgpLT5Db3B5VG8oJmZpbGVfcHJvdG8pOworICBBU1NFUlRfVFJVRShwb29sLkJ1aWxkRmlsZShmaWxlX3Byb3RvKSAhPSBOVUxMKTsKKworICBBU1NFUlRfVFJVRShUZXh0Rm9ybWF0OjpQYXJzZUZyb21TdHJpbmcoCisgICAgIm5hbWU6IFwiY3VzdG9tX29wdGlvbnNfaW1wb3J0LnByb3RvXCIgIgorICAgICJwYWNrYWdlOiBcInByb3RvYnVmX3VuaXR0ZXN0XCIgIgorICAgICJkZXBlbmRlbmN5OiBcImdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9jdXN0b21fb3B0aW9ucy5wcm90b1wiICIKKyAgICAib3B0aW9ucyB7ICIKKyAgICAiICB1bmludGVycHJldGVkX29wdGlvbiB7ICIKKyAgICAiICAgIG5hbWUgeyAiCisgICAgIiAgICAgIG5hbWVfcGFydDogXCJmaWxlX29wdDFcIiAiCisgICAgIiAgICAgIGlzX2V4dGVuc2lvbjogdHJ1ZSAiCisgICAgIiAgICB9ICIKKyAgICAiICAgIHBvc2l0aXZlX2ludF92YWx1ZTogMTIzNCAiCisgICAgIiAgfSAiCisgICAgLy8gVGVzdCBhIG5vbi1leHRlbnNpb24gb3B0aW9uIHRvby4gIChBdCBvbmUgcG9pbnQgdGhpcyBmYWlsZWQgZHVlIHRvIGEKKyAgICAvLyBidWcuKQorICAgICIgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uIHsgIgorICAgICIgICAgbmFtZSB7ICIKKyAgICAiICAgICAgbmFtZV9wYXJ0OiBcImphdmFfcGFja2FnZVwiICIKKyAgICAiICAgICAgaXNfZXh0ZW5zaW9uOiBmYWxzZSAiCisgICAgIiAgICB9ICIKKyAgICAiICAgIHN0cmluZ192YWx1ZTogXCJmb29cIiAiCisgICAgIiAgfSAiCisgICAgLy8gVGVzdCB0aGF0IGVudW0tdHlwZWQgb3B0aW9ucyBzdGlsbCB3b3JrIHRvby4gIChBdCBvbmUgcG9pbnQgdGhpcyBhbHNvCisgICAgLy8gZmFpbGVkIGR1ZSB0byBhIGJ1Zy4pCisgICAgIiAgdW5pbnRlcnByZXRlZF9vcHRpb24geyAiCisgICAgIiAgICBuYW1lIHsgIgorICAgICIgICAgICBuYW1lX3BhcnQ6IFwib3B0aW1pemVfZm9yXCIgIgorICAgICIgICAgICBpc19leHRlbnNpb246IGZhbHNlICIKKyAgICAiICAgIH0gIgorICAgICIgICAgaWRlbnRpZmllcl92YWx1ZTogXCJTUEVFRFwiICIKKyAgICAiICB9ICIKKyAgICAifSIKKyAgICAsCisgICAgJmZpbGVfcHJvdG8pKTsKKworICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSA9IHBvb2wuQnVpbGRGaWxlKGZpbGVfcHJvdG8pOworICBBU1NFUlRfVFJVRShmaWxlICE9IE5VTEwpOworICBFWFBFQ1RfRVEoMTIzNCwgZmlsZS0+b3B0aW9ucygpLkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6ZmlsZV9vcHQxKSk7CisgIEVYUEVDVF9UUlVFKGZpbGUtPm9wdGlvbnMoKS5oYXNfamF2YV9wYWNrYWdlKCkpOworICBFWFBFQ1RfRVEoImZvbyIsIGZpbGUtPm9wdGlvbnMoKS5qYXZhX3BhY2thZ2UoKSk7CisgIEVYUEVDVF9UUlVFKGZpbGUtPm9wdGlvbnMoKS5oYXNfb3B0aW1pemVfZm9yKCkpOworICBFWFBFQ1RfRVEoRmlsZU9wdGlvbnM6OlNQRUVELCBmaWxlLT5vcHRpb25zKCkub3B0aW1pemVfZm9yKCkpOworfQorCitURVNUKEN1c3RvbU9wdGlvbnMsIE1lc3NhZ2VPcHRpb25UaHJlZUZpZWxkc1NldCkgeworICAvLyBUaGlzIHRlc3RzIGEgYnVnIHdoaWNoIHByZXZpb3VzbHkgZXhpc3RlZCBpbiBjdXN0b20gb3B0aW9ucyBwYXJzaW5nLiAgVGhlCisgIC8vIGJ1ZyBvY2N1cnJlZCB3aGVuIHlvdSBkZWZpbmVkIGEgY3VzdG9tIG9wdGlvbiB3aXRoIG1lc3NhZ2UgdHlwZSBhbmQgdGhlbgorICAvLyBzZXQgdGhyZWUgZmllbGRzIG9mIHRoYXQgb3B0aW9uIG9uIGEgc2luZ2xlIGRlZmluaXRpb24gKHNlZSB0aGUgZXhhbXBsZQorICAvLyBiZWxvdykuICBUaGUgYnVnIGlzIGEgYml0IGhhcmQgdG8gZXhwbGFpbiwgc28gY2hlY2sgdGhlIGNoYW5nZSBoaXN0b3J5IGlmCisgIC8vIHlvdSB3YW50IHRvIGtub3cgbW9yZS4KKyAgRGVzY3JpcHRvclBvb2wgcG9vbDsKKworICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGVfcHJvdG87CisgIEZpbGVEZXNjcmlwdG9yUHJvdG86OmRlc2NyaXB0b3IoKS0+ZmlsZSgpLT5Db3B5VG8oJmZpbGVfcHJvdG8pOworICBBU1NFUlRfVFJVRShwb29sLkJ1aWxkRmlsZShmaWxlX3Byb3RvKSAhPSBOVUxMKTsKKworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9uczo6ZGVzY3JpcHRvcigpCisgICAgLT5maWxlKCktPkNvcHlUbygmZmlsZV9wcm90byk7CisgIEFTU0VSVF9UUlVFKHBvb2wuQnVpbGRGaWxlKGZpbGVfcHJvdG8pICE9IE5VTEwpOworCisgIC8vIFRoZSBmb2xsb3dpbmcgcmVwcmVzZW50cyB0aGUgZGVmaW5pdGlvbjoKKyAgLy8KKyAgLy8gICBpbXBvcnQgImdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9jdXN0b21fb3B0aW9ucy5wcm90byIKKyAgLy8gICBwYWNrYWdlIHByb3RvYnVmX3VuaXR0ZXN0OworICAvLyAgIG1lc3NhZ2UgRm9vIHsKKyAgLy8gICAgIG9wdGlvbiAoY29tcGxleF9vcHQxKS5mb28gID0gMTIzNDsKKyAgLy8gICAgIG9wdGlvbiAoY29tcGxleF9vcHQxKS5mb28yID0gMTIzNDsKKyAgLy8gICAgIG9wdGlvbiAoY29tcGxleF9vcHQxKS5mb28zID0gMTIzNDsKKyAgLy8gICB9CisgIEFTU0VSVF9UUlVFKFRleHRGb3JtYXQ6OlBhcnNlRnJvbVN0cmluZygKKyAgICAibmFtZTogXCJjdXN0b21fb3B0aW9uc19pbXBvcnQucHJvdG9cIiAiCisgICAgInBhY2thZ2U6IFwicHJvdG9idWZfdW5pdHRlc3RcIiAiCisgICAgImRlcGVuZGVuY3k6IFwiZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2N1c3RvbV9vcHRpb25zLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyAiCisgICAgIiAgbmFtZTogXCJGb29cIiAiCisgICAgIiAgb3B0aW9ucyB7ICIKKyAgICAiICAgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uIHsgIgorICAgICIgICAgICBuYW1lIHsgIgorICAgICIgICAgICAgIG5hbWVfcGFydDogXCJjb21wbGV4X29wdDFcIiAiCisgICAgIiAgICAgICAgaXNfZXh0ZW5zaW9uOiB0cnVlICIKKyAgICAiICAgICAgfSAiCisgICAgIiAgICAgIG5hbWUgeyAiCisgICAgIiAgICAgICAgbmFtZV9wYXJ0OiBcImZvb1wiICIKKyAgICAiICAgICAgICBpc19leHRlbnNpb246IGZhbHNlICIKKyAgICAiICAgICAgfSAiCisgICAgIiAgICAgIHBvc2l0aXZlX2ludF92YWx1ZTogMTIzNCAiCisgICAgIiAgICB9ICIKKyAgICAiICAgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uIHsgIgorICAgICIgICAgICBuYW1lIHsgIgorICAgICIgICAgICAgIG5hbWVfcGFydDogXCJjb21wbGV4X29wdDFcIiAiCisgICAgIiAgICAgICAgaXNfZXh0ZW5zaW9uOiB0cnVlICIKKyAgICAiICAgICAgfSAiCisgICAgIiAgICAgIG5hbWUgeyAiCisgICAgIiAgICAgICAgbmFtZV9wYXJ0OiBcImZvbzJcIiAiCisgICAgIiAgICAgICAgaXNfZXh0ZW5zaW9uOiBmYWxzZSAiCisgICAgIiAgICAgIH0gIgorICAgICIgICAgICBwb3NpdGl2ZV9pbnRfdmFsdWU6IDEyMzQgIgorICAgICIgICAgfSAiCisgICAgIiAgICB1bmludGVycHJldGVkX29wdGlvbiB7ICIKKyAgICAiICAgICAgbmFtZSB7ICIKKyAgICAiICAgICAgICBuYW1lX3BhcnQ6IFwiY29tcGxleF9vcHQxXCIgIgorICAgICIgICAgICAgIGlzX2V4dGVuc2lvbjogdHJ1ZSAiCisgICAgIiAgICAgIH0gIgorICAgICIgICAgICBuYW1lIHsgIgorICAgICIgICAgICAgIG5hbWVfcGFydDogXCJmb28zXCIgIgorICAgICIgICAgICAgIGlzX2V4dGVuc2lvbjogZmFsc2UgIgorICAgICIgICAgICB9ICIKKyAgICAiICAgICAgcG9zaXRpdmVfaW50X3ZhbHVlOiAxMjM0ICIKKyAgICAiICAgIH0gIgorICAgICIgIH0gIgorICAgICJ9IiwKKyAgICAmZmlsZV9wcm90bykpOworCisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlID0gcG9vbC5CdWlsZEZpbGUoZmlsZV9wcm90byk7CisgIEFTU0VSVF9UUlVFKGZpbGUgIT0gTlVMTCk7CisgIEFTU0VSVF9FUSgxLCBmaWxlLT5tZXNzYWdlX3R5cGVfY291bnQoKSk7CisKKyAgY29uc3QgTWVzc2FnZU9wdGlvbnMmIG9wdGlvbnMgPSBmaWxlLT5tZXNzYWdlX3R5cGUoMCktPm9wdGlvbnMoKTsKKyAgRVhQRUNUX0VRKDEyMzQsIG9wdGlvbnMuR2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0Ojpjb21wbGV4X29wdDEpLmZvbygpKTsKK30KKworVEVTVChDdXN0b21PcHRpb25zLCBNZXNzYWdlT3B0aW9uUmVwZWF0ZWRMZWFmRmllbGRTZXQpIHsKKyAgLy8gVGhpcyB0ZXN0IHZlcmlmaWVzIHRoYXQgcmVwZWF0ZWQgZmllbGRzIGluIGN1c3RvbSBvcHRpb25zIGNhbiBiZQorICAvLyBnaXZlbiBtdWx0aXBsZSB2YWx1ZXMgYnkgcmVwZWF0aW5nIHRoZSBvcHRpb24gd2l0aCBhIGRpZmZlcmVudCB2YWx1ZS4KKyAgLy8gVGhpcyB0ZXN0IGNoZWNrcyByZXBlYXRlZCBsZWFmIHZhbHVlcy4gRWFjaCByZXBlYXRlZCBjdXN0b20gdmFsdWUKKyAgLy8gYXBwZWFycyBpbiBhIGRpZmZlcmVudCB1bmludGVycHJldGVkX29wdGlvbiwgd2hpY2ggd2lsbCBiZSBjb25jYXRlbmF0ZWQKKyAgLy8gd2hlbiB0aGV5IGFyZSBtZXJnZWQgaW50byB0aGUgZmluYWwgb3B0aW9uIHZhbHVlLgorICBEZXNjcmlwdG9yUG9vbCBwb29sOworCisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZV9wcm90bzsKKyAgRmlsZURlc2NyaXB0b3JQcm90bzo6ZGVzY3JpcHRvcigpLT5maWxlKCktPkNvcHlUbygmZmlsZV9wcm90byk7CisgIEFTU0VSVF9UUlVFKHBvb2wuQnVpbGRGaWxlKGZpbGVfcHJvdG8pICE9IE5VTEwpOworCisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zOjpkZXNjcmlwdG9yKCkKKyAgICAtPmZpbGUoKS0+Q29weVRvKCZmaWxlX3Byb3RvKTsKKyAgQVNTRVJUX1RSVUUocG9vbC5CdWlsZEZpbGUoZmlsZV9wcm90bykgIT0gTlVMTCk7CisKKyAgLy8gVGhlIGZvbGxvd2luZyByZXByZXNlbnRzIHRoZSBkZWZpbml0aW9uOgorICAvLworICAvLyAgIGltcG9ydCAiZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2N1c3RvbV9vcHRpb25zLnByb3RvIgorICAvLyAgIHBhY2thZ2UgcHJvdG9idWZfdW5pdHRlc3Q7CisgIC8vICAgbWVzc2FnZSBGb28geworICAvLyAgICAgb3B0aW9uIChjb21wbGV4X29wdDEpLmZvbzQgPSAxMjsKKyAgLy8gICAgIG9wdGlvbiAoY29tcGxleF9vcHQxKS5mb280ID0gMzQ7CisgIC8vICAgICBvcHRpb24gKGNvbXBsZXhfb3B0MSkuZm9vNCA9IDU2OworICAvLyAgIH0KKyAgQVNTRVJUX1RSVUUoVGV4dEZvcm1hdDo6UGFyc2VGcm9tU3RyaW5nKAorICAgICJuYW1lOiBcImN1c3RvbV9vcHRpb25zX2ltcG9ydC5wcm90b1wiICIKKyAgICAicGFja2FnZTogXCJwcm90b2J1Zl91bml0dGVzdFwiICIKKyAgICAiZGVwZW5kZW5jeTogXCJnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfY3VzdG9tX29wdGlvbnMucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7ICIKKyAgICAiICBuYW1lOiBcIkZvb1wiICIKKyAgICAiICBvcHRpb25zIHsgIgorICAgICIgICAgdW5pbnRlcnByZXRlZF9vcHRpb24geyAiCisgICAgIiAgICAgIG5hbWUgeyAiCisgICAgIiAgICAgICAgbmFtZV9wYXJ0OiBcImNvbXBsZXhfb3B0MVwiICIKKyAgICAiICAgICAgICBpc19leHRlbnNpb246IHRydWUgIgorICAgICIgICAgICB9ICIKKyAgICAiICAgICAgbmFtZSB7ICIKKyAgICAiICAgICAgICBuYW1lX3BhcnQ6IFwiZm9vNFwiICIKKyAgICAiICAgICAgICBpc19leHRlbnNpb246IGZhbHNlICIKKyAgICAiICAgICAgfSAiCisgICAgIiAgICAgIHBvc2l0aXZlX2ludF92YWx1ZTogMTIgIgorICAgICIgICAgfSAiCisgICAgIiAgICB1bmludGVycHJldGVkX29wdGlvbiB7ICIKKyAgICAiICAgICAgbmFtZSB7ICIKKyAgICAiICAgICAgICBuYW1lX3BhcnQ6IFwiY29tcGxleF9vcHQxXCIgIgorICAgICIgICAgICAgIGlzX2V4dGVuc2lvbjogdHJ1ZSAiCisgICAgIiAgICAgIH0gIgorICAgICIgICAgICBuYW1lIHsgIgorICAgICIgICAgICAgIG5hbWVfcGFydDogXCJmb280XCIgIgorICAgICIgICAgICAgIGlzX2V4dGVuc2lvbjogZmFsc2UgIgorICAgICIgICAgICB9ICIKKyAgICAiICAgICAgcG9zaXRpdmVfaW50X3ZhbHVlOiAzNCAiCisgICAgIiAgICB9ICIKKyAgICAiICAgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uIHsgIgorICAgICIgICAgICBuYW1lIHsgIgorICAgICIgICAgICAgIG5hbWVfcGFydDogXCJjb21wbGV4X29wdDFcIiAiCisgICAgIiAgICAgICAgaXNfZXh0ZW5zaW9uOiB0cnVlICIKKyAgICAiICAgICAgfSAiCisgICAgIiAgICAgIG5hbWUgeyAiCisgICAgIiAgICAgICAgbmFtZV9wYXJ0OiBcImZvbzRcIiAiCisgICAgIiAgICAgICAgaXNfZXh0ZW5zaW9uOiBmYWxzZSAiCisgICAgIiAgICAgIH0gIgorICAgICIgICAgICBwb3NpdGl2ZV9pbnRfdmFsdWU6IDU2ICIKKyAgICAiICAgIH0gIgorICAgICIgIH0gIgorICAgICJ9IiwKKyAgICAmZmlsZV9wcm90bykpOworCisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlID0gcG9vbC5CdWlsZEZpbGUoZmlsZV9wcm90byk7CisgIEFTU0VSVF9UUlVFKGZpbGUgIT0gTlVMTCk7CisgIEFTU0VSVF9FUSgxLCBmaWxlLT5tZXNzYWdlX3R5cGVfY291bnQoKSk7CisKKyAgY29uc3QgTWVzc2FnZU9wdGlvbnMmIG9wdGlvbnMgPSBmaWxlLT5tZXNzYWdlX3R5cGUoMCktPm9wdGlvbnMoKTsKKyAgRVhQRUNUX0VRKDMsIG9wdGlvbnMuR2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0Ojpjb21wbGV4X29wdDEpLmZvbzRfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEyLCBvcHRpb25zLkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6Y29tcGxleF9vcHQxKS5mb280KDApKTsKKyAgRVhQRUNUX0VRKDM0LCBvcHRpb25zLkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6Y29tcGxleF9vcHQxKS5mb280KDEpKTsKKyAgRVhQRUNUX0VRKDU2LCBvcHRpb25zLkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6Y29tcGxleF9vcHQxKS5mb280KDIpKTsKK30KKworVEVTVChDdXN0b21PcHRpb25zLCBNZXNzYWdlT3B0aW9uUmVwZWF0ZWRNc2dGaWVsZFNldCkgeworICAvLyBUaGlzIHRlc3QgdmVyaWZpZXMgdGhhdCByZXBlYXRlZCBmaWVsZHMgaW4gY3VzdG9tIG9wdGlvbnMgY2FuIGJlCisgIC8vIGdpdmVuIG11bHRpcGxlIHZhbHVlcyBieSByZXBlYXRpbmcgdGhlIG9wdGlvbiB3aXRoIGEgZGlmZmVyZW50IHZhbHVlLgorICAvLyBUaGlzIHRlc3QgY2hlY2tzIHJlcGVhdGVkIG1lc3NhZ2UgdmFsdWVzLiBFYWNoIHJlcGVhdGVkIGN1c3RvbSB2YWx1ZQorICAvLyBhcHBlYXJzIGluIGEgZGlmZmVyZW50IHVuaW50ZXJwcmV0ZWRfb3B0aW9uLCB3aGljaCB3aWxsIGJlIGNvbmNhdGVuYXRlZAorICAvLyB3aGVuIHRoZXkgYXJlIG1lcmdlZCBpbnRvIHRoZSBmaW5hbCBvcHRpb24gdmFsdWUuCisgIERlc2NyaXB0b3JQb29sIHBvb2w7CisKKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICBGaWxlRGVzY3JpcHRvclByb3RvOjpkZXNjcmlwdG9yKCktPmZpbGUoKS0+Q29weVRvKCZmaWxlX3Byb3RvKTsKKyAgQVNTRVJUX1RSVUUocG9vbC5CdWlsZEZpbGUoZmlsZV9wcm90bykgIT0gTlVMTCk7CisKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnM6OmRlc2NyaXB0b3IoKQorICAgIC0+ZmlsZSgpLT5Db3B5VG8oJmZpbGVfcHJvdG8pOworICBBU1NFUlRfVFJVRShwb29sLkJ1aWxkRmlsZShmaWxlX3Byb3RvKSAhPSBOVUxMKTsKKworICAvLyBUaGUgZm9sbG93aW5nIHJlcHJlc2VudHMgdGhlIGRlZmluaXRpb246CisgIC8vCisgIC8vICAgaW1wb3J0ICJnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfY3VzdG9tX29wdGlvbnMucHJvdG8iCisgIC8vICAgcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdDsKKyAgLy8gICBtZXNzYWdlIEZvbyB7CisgIC8vICAgICBvcHRpb24gKGNvbXBsZXhfb3B0MikuYmFybmV5ID0ge3dhbGRvOiAxfTsKKyAgLy8gICAgIG9wdGlvbiAoY29tcGxleF9vcHQyKS5iYXJuZXkgPSB7d2FsZG86IDEwfTsKKyAgLy8gICAgIG9wdGlvbiAoY29tcGxleF9vcHQyKS5iYXJuZXkgPSB7d2FsZG86IDEwMH07CisgIC8vICAgfQorICBBU1NFUlRfVFJVRShUZXh0Rm9ybWF0OjpQYXJzZUZyb21TdHJpbmcoCisgICAgIm5hbWU6IFwiY3VzdG9tX29wdGlvbnNfaW1wb3J0LnByb3RvXCIgIgorICAgICJwYWNrYWdlOiBcInByb3RvYnVmX3VuaXR0ZXN0XCIgIgorICAgICJkZXBlbmRlbmN5OiBcImdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9jdXN0b21fb3B0aW9ucy5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsgIgorICAgICIgIG5hbWU6IFwiRm9vXCIgIgorICAgICIgIG9wdGlvbnMgeyAiCisgICAgIiAgICB1bmludGVycHJldGVkX29wdGlvbiB7ICIKKyAgICAiICAgICAgbmFtZSB7ICIKKyAgICAiICAgICAgICBuYW1lX3BhcnQ6IFwiY29tcGxleF9vcHQyXCIgIgorICAgICIgICAgICAgIGlzX2V4dGVuc2lvbjogdHJ1ZSAiCisgICAgIiAgICAgIH0gIgorICAgICIgICAgICBuYW1lIHsgIgorICAgICIgICAgICAgIG5hbWVfcGFydDogXCJiYXJuZXlcIiAiCisgICAgIiAgICAgICAgaXNfZXh0ZW5zaW9uOiBmYWxzZSAiCisgICAgIiAgICAgIH0gIgorICAgICIgICAgICBhZ2dyZWdhdGVfdmFsdWU6IFwid2FsZG86IDFcIiAiCisgICAgIiAgICB9ICIKKyAgICAiICAgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uIHsgIgorICAgICIgICAgICBuYW1lIHsgIgorICAgICIgICAgICAgIG5hbWVfcGFydDogXCJjb21wbGV4X29wdDJcIiAiCisgICAgIiAgICAgICAgaXNfZXh0ZW5zaW9uOiB0cnVlICIKKyAgICAiICAgICAgfSAiCisgICAgIiAgICAgIG5hbWUgeyAiCisgICAgIiAgICAgICAgbmFtZV9wYXJ0OiBcImJhcm5leVwiICIKKyAgICAiICAgICAgICBpc19leHRlbnNpb246IGZhbHNlICIKKyAgICAiICAgICAgfSAiCisgICAgIiAgICAgIGFnZ3JlZ2F0ZV92YWx1ZTogXCJ3YWxkbzogMTBcIiAiCisgICAgIiAgICB9ICIKKyAgICAiICAgIHVuaW50ZXJwcmV0ZWRfb3B0aW9uIHsgIgorICAgICIgICAgICBuYW1lIHsgIgorICAgICIgICAgICAgIG5hbWVfcGFydDogXCJjb21wbGV4X29wdDJcIiAiCisgICAgIiAgICAgICAgaXNfZXh0ZW5zaW9uOiB0cnVlICIKKyAgICAiICAgICAgfSAiCisgICAgIiAgICAgIG5hbWUgeyAiCisgICAgIiAgICAgICAgbmFtZV9wYXJ0OiBcImJhcm5leVwiICIKKyAgICAiICAgICAgICBpc19leHRlbnNpb246IGZhbHNlICIKKyAgICAiICAgICAgfSAiCisgICAgIiAgICAgIGFnZ3JlZ2F0ZV92YWx1ZTogXCJ3YWxkbzogMTAwXCIgIgorICAgICIgICAgfSAiCisgICAgIiAgfSAiCisgICAgIn0iLAorICAgICZmaWxlX3Byb3RvKSk7CisKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUgPSBwb29sLkJ1aWxkRmlsZShmaWxlX3Byb3RvKTsKKyAgQVNTRVJUX1RSVUUoZmlsZSAhPSBOVUxMKTsKKyAgQVNTRVJUX0VRKDEsIGZpbGUtPm1lc3NhZ2VfdHlwZV9jb3VudCgpKTsKKworICBjb25zdCBNZXNzYWdlT3B0aW9ucyYgb3B0aW9ucyA9IGZpbGUtPm1lc3NhZ2VfdHlwZSgwKS0+b3B0aW9ucygpOworICBFWFBFQ1RfRVEoMywgb3B0aW9ucy5HZXRFeHRlbnNpb24oCisgICAgICBwcm90b2J1Zl91bml0dGVzdDo6Y29tcGxleF9vcHQyKS5iYXJuZXlfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEsb3B0aW9ucy5HZXRFeHRlbnNpb24oCisgICAgICBwcm90b2J1Zl91bml0dGVzdDo6Y29tcGxleF9vcHQyKS5iYXJuZXkoMCkud2FsZG8oKSk7CisgIEVYUEVDVF9FUSgxMCwgb3B0aW9ucy5HZXRFeHRlbnNpb24oCisgICAgICBwcm90b2J1Zl91bml0dGVzdDo6Y29tcGxleF9vcHQyKS5iYXJuZXkoMSkud2FsZG8oKSk7CisgIEVYUEVDVF9FUSgxMDAsIG9wdGlvbnMuR2V0RXh0ZW5zaW9uKAorICAgICAgcHJvdG9idWZfdW5pdHRlc3Q6OmNvbXBsZXhfb3B0MikuYmFybmV5KDIpLndhbGRvKCkpOworfQorCisvLyBDaGVjayB0aGF0IGFnZ3JlZ2F0ZSBvcHRpb25zIHdlcmUgcGFyc2VkIGFuZCBzYXZlZCBjb3JyZWN0bHkgaW4KKy8vIHRoZSBhcHByb3ByaWF0ZSBkZXNjcmlwdG9ycy4KK1RFU1QoQ3VzdG9tT3B0aW9ucywgQWdncmVnYXRlT3B0aW9ucykgeworICBjb25zdCBEZXNjcmlwdG9yKiBtc2cgPSBwcm90b2J1Zl91bml0dGVzdDo6QWdncmVnYXRlTWVzc2FnZTo6ZGVzY3JpcHRvcigpOworICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSA9IG1zZy0+ZmlsZSgpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gbXNnLT5GaW5kRmllbGRCeU5hbWUoImZpZWxkbmFtZSIpOworICBjb25zdCBFbnVtRGVzY3JpcHRvciogZW51bWQgPSBmaWxlLT5GaW5kRW51bVR5cGVCeU5hbWUoIkFnZ3JlZ2F0ZUVudW0iKTsKKyAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogZW51bXYgPSBlbnVtZC0+RmluZFZhbHVlQnlOYW1lKCJWQUxVRSIpOworICBjb25zdCBTZXJ2aWNlRGVzY3JpcHRvciogc2VydmljZSA9IGZpbGUtPkZpbmRTZXJ2aWNlQnlOYW1lKAorICAgICAgIkFnZ3JlZ2F0ZVNlcnZpY2UiKTsKKyAgY29uc3QgTWV0aG9kRGVzY3JpcHRvciogbWV0aG9kID0gc2VydmljZS0+RmluZE1ldGhvZEJ5TmFtZSgiTWV0aG9kIik7CisKKyAgLy8gVGVzdHMgZm9yIHRoZSBkaWZmZXJlbnQgdHlwZXMgb2YgZGF0YSBlbWJlZGRlZCBpbiBmaWxlb3B0CisgIGNvbnN0IHByb3RvYnVmX3VuaXR0ZXN0OjpBZ2dyZWdhdGUmIGZpbGVfb3B0aW9ucyA9CisgICAgICBmaWxlLT5vcHRpb25zKCkuR2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0OjpmaWxlb3B0KTsKKyAgRVhQRUNUX0VRKDEwMCwgZmlsZV9vcHRpb25zLmkoKSk7CisgIEVYUEVDVF9FUSgiRmlsZUFubm90YXRpb24iLCBmaWxlX29wdGlvbnMucygpKTsKKyAgRVhQRUNUX0VRKCJOZXN0ZWRGaWxlQW5ub3RhdGlvbiIsIGZpbGVfb3B0aW9ucy5zdWIoKS5zKCkpOworICBFWFBFQ1RfRVEoIkZpbGVFeHRlbnNpb25Bbm5vdGF0aW9uIiwKKyAgICAgICAgICAgIGZpbGVfb3B0aW9ucy5maWxlKCkuR2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0OjpmaWxlb3B0KS5zKCkpOworICBFWFBFQ1RfRVEoIkVtYmVkZGVkTWVzc2FnZVNldEVsZW1lbnQiLAorICAgICAgICAgICAgZmlsZV9vcHRpb25zLm1zZXQoKS5HZXRFeHRlbnNpb24oCisgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3Q6OkFnZ3JlZ2F0ZU1lc3NhZ2VTZXRFbGVtZW50CisgICAgICAgICAgICAgICAgOjptZXNzYWdlX3NldF9leHRlbnNpb24pLnMoKSk7CisKKyAgLy8gU2ltcGxlIHRlc3RzIGZvciBhbGwgdGhlIG90aGVyIHR5cGVzIG9mIGFubm90YXRpb25zCisgIEVYUEVDVF9FUSgiTWVzc2FnZUFubm90YXRpb24iLAorICAgICAgICAgICAgbXNnLT5vcHRpb25zKCkuR2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0Ojptc2dvcHQpLnMoKSk7CisgIEVYUEVDVF9FUSgiRmllbGRBbm5vdGF0aW9uIiwKKyAgICAgICAgICAgIGZpZWxkLT5vcHRpb25zKCkuR2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0OjpmaWVsZG9wdCkucygpKTsKKyAgRVhQRUNUX0VRKCJFbnVtQW5ub3RhdGlvbiIsCisgICAgICAgICAgICBlbnVtZC0+b3B0aW9ucygpLkdldEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdDo6ZW51bW9wdCkucygpKTsKKyAgRVhQRUNUX0VRKCJFbnVtVmFsdWVBbm5vdGF0aW9uIiwKKyAgICAgICAgICAgIGVudW12LT5vcHRpb25zKCkuR2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0OjplbnVtdmFsb3B0KS5zKCkpOworICBFWFBFQ1RfRVEoIlNlcnZpY2VBbm5vdGF0aW9uIiwKKyAgICAgICAgICAgIHNlcnZpY2UtPm9wdGlvbnMoKS5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OnNlcnZpY2VvcHQpLnMoKSk7CisgIEVYUEVDVF9FUSgiTWV0aG9kQW5ub3RhdGlvbiIsCisgICAgICAgICAgICBtZXRob2QtPm9wdGlvbnMoKS5HZXRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6Om1ldGhvZG9wdCkucygpKTsKK30KKworVEVTVChDdXN0b21PcHRpb25zLCBVbnVzZWRJbXBvcnRXYXJuaW5nKSB7CisgIERlc2NyaXB0b3JQb29sIHBvb2w7CisKKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICBGaWxlRGVzY3JpcHRvclByb3RvOjpkZXNjcmlwdG9yKCktPmZpbGUoKS0+Q29weVRvKCZmaWxlX3Byb3RvKTsKKyAgQVNTRVJUX1RSVUUocG9vbC5CdWlsZEZpbGUoZmlsZV9wcm90bykgIT0gTlVMTCk7CisKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnM6OmRlc2NyaXB0b3IoKQorICAgICAgLT5maWxlKCktPkNvcHlUbygmZmlsZV9wcm90byk7CisgIEFTU0VSVF9UUlVFKHBvb2wuQnVpbGRGaWxlKGZpbGVfcHJvdG8pICE9IE5VTEwpOworCisgIHBvb2wuQWRkVW51c2VkSW1wb3J0VHJhY2tGaWxlKCJjdXN0b21fb3B0aW9uc19pbXBvcnQucHJvdG8iKTsKKyAgQVNTRVJUX1RSVUUoVGV4dEZvcm1hdDo6UGFyc2VGcm9tU3RyaW5nKAorICAgICJuYW1lOiBcImN1c3RvbV9vcHRpb25zX2ltcG9ydC5wcm90b1wiICIKKyAgICAicGFja2FnZTogXCJwcm90b2J1Zl91bml0dGVzdFwiICIKKyAgICAiZGVwZW5kZW5jeTogXCJnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfY3VzdG9tX29wdGlvbnMucHJvdG9cIiAiLAorICAgICZmaWxlX3Byb3RvKSk7CisKKyAgTW9ja0Vycm9yQ29sbGVjdG9yIGVycm9yX2NvbGxlY3RvcjsKKyAgRVhQRUNUX1RSVUUocG9vbC5CdWlsZEZpbGVDb2xsZWN0aW5nRXJyb3JzKGZpbGVfcHJvdG8sICZlcnJvcl9jb2xsZWN0b3IpKTsKKyAgRVhQRUNUX0VRKCIiLCBlcnJvcl9jb2xsZWN0b3Iud2FybmluZ190ZXh0Xyk7Cit9CisKKy8vIFZlcmlmaWVzIHRoYXQgcHJvdG8gZmlsZXMgY2FuIGNvcnJlY3RseSBiZSBwYXJzZWQsIGV2ZW4gaWYgdGhlCisvLyBjdXN0b20gb3B0aW9ucyBkZWZpbmVkIGluIHRoZSBmaWxlIGFyZSBpbmNvbXBhdGlibGUgd2l0aCB0aG9zZQorLy8gY29tcGlsZWQgaW4gdGhlIGJpbmFyeS4gU2VlIGh0dHA6Ly9iLzE5Mjc2MjUwLgorVEVTVChDdXN0b21PcHRpb25zLCBPcHRpb25zV2l0aFJlcXVpcmVkRW51bXMpIHsKKyAgRGVzY3JpcHRvclBvb2wgcG9vbDsKKworICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGVfcHJvdG87CisgIE1lc3NhZ2VPcHRpb25zOjpkZXNjcmlwdG9yKCktPmZpbGUoKS0+Q29weVRvKCZmaWxlX3Byb3RvKTsKKyAgQVNTRVJUX1RSVUUocG9vbC5CdWlsZEZpbGUoZmlsZV9wcm90bykgIT0gTlVMTCk7CisKKyAgLy8gQ3JlYXRlIGEgbmV3IGZpbGUgZGVzY3JpcHRvciBwcm90byBjb250YWluaW5nIGEgc3Vic2V0IG9mIHRoZQorICAvLyBtZXNzYWdlcyBkZWZpbmVkIGluIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9jdXN0b21fb3B0aW9ucy5wcm90by4KKyAgZmlsZV9wcm90by5DbGVhcigpOworICBmaWxlX3Byb3RvLnNldF9uYW1lKCJ1bml0dGVzdF9jdXN0b21fb3B0aW9ucy5wcm90byIpOworICBmaWxlX3Byb3RvLnNldF9wYWNrYWdlKCJwcm90b2J1Zl91bml0dGVzdCIpOworICBmaWxlX3Byb3RvLmFkZF9kZXBlbmRlbmN5KCJnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90byIpOworCisgIC8vIEFkZCB0aGUgInJlcXVpcmVkX2VudW1fb3B0IiBleHRlbnNpb24uCisgIEZpZWxkRGVzY3JpcHRvclByb3RvKiBleHRlbnNpb24gPSBmaWxlX3Byb3RvLmFkZF9leHRlbnNpb24oKTsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6Ok9sZE9wdGlvblR5cGU6OmRlc2NyaXB0b3IoKS0+ZmlsZSgpCisgICAgICAtPkZpbmRFeHRlbnNpb25CeU5hbWUoInJlcXVpcmVkX2VudW1fb3B0IiktPkNvcHlUbyhleHRlbnNpb24pOworCisgIC8vIEFkZCBhIHRlc3QgbWVzc2FnZSB0aGF0IHVzZXMgdGhlICJyZXF1aXJlZF9lbnVtX29wdCIgb3B0aW9uLgorICBEZXNjcmlwdG9yUHJvdG8qIHRlc3RfbWVzc2FnZV90eXBlID0gZmlsZV9wcm90by5hZGRfbWVzc2FnZV90eXBlKCk7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0TWVzc2FnZVdpdGhSZXF1aXJlZEVudW1PcHRpb246OmRlc2NyaXB0b3IoKQorICAgICAgLT5Db3B5VG8odGVzdF9tZXNzYWdlX3R5cGUpOworCisgIC8vIEluc3RydWN0IHRoZSBleHRlbnNpb24gdG8gdXNlIE5ld09wdGlvblR5cGUgaW5zdGVhZCBvZgorICAvLyBPbGRPcHRpb25UeXBlLCBhbmQgYWRkIHRoZSBkZXNjcmlwdG9yIG9mIE5ld09wdGlvblR5cGUuCisgIGV4dGVuc2lvbi0+c2V0X3R5cGVfbmFtZSgiLnByb3RvYnVmX3VuaXR0ZXN0Lk5ld09wdGlvblR5cGUiKTsKKyAgRGVzY3JpcHRvclByb3RvKiBuZXdfb3B0aW9uX3R5cGUgPSBmaWxlX3Byb3RvLmFkZF9tZXNzYWdlX3R5cGUoKTsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6Ok5ld09wdGlvblR5cGU6OmRlc2NyaXB0b3IoKQorICAgICAgLT5Db3B5VG8obmV3X29wdGlvbl90eXBlKTsKKworICAvLyBSZXBsYWNlIHRoZSB2YWx1ZSBvZiB0aGUgInJlcXVpcmVkX2VudW1fb3B0IiBvcHRpb24gdXNlZCBpbiB0aGUKKyAgLy8gdGVzdCBtZXNzYWdlIHdpdGggYW4gZW51bSB2YWx1ZSB0aGF0IG9ubHkgZXhpc3RzIGluIE5ld09wdGlvblR5cGUuCisgIEFTU0VSVF9UUlVFKFRleHRGb3JtYXQ6OlBhcnNlRnJvbVN0cmluZygKKyAgICAgICJ1bmludGVycHJldGVkX29wdGlvbiB7ICIKKyAgICAgICIgIG5hbWUgeyAiCisgICAgICAiICAgIG5hbWVfcGFydDogJ3JlcXVpcmVkX2VudW1fb3B0JyAiCisgICAgICAiICAgIGlzX2V4dGVuc2lvbjogdHJ1ZSAiCisgICAgICAiICB9ICIKKyAgICAgICIgIGFnZ3JlZ2F0ZV92YWx1ZTogJ3ZhbHVlOiBORVdfVkFMVUUnICIKKyAgICAgICJ9IiwKKyAgICAgIHRlc3RfbWVzc2FnZV90eXBlLT5tdXRhYmxlX29wdGlvbnMoKSkpOworCisgIC8vIEFkZCB0aGUgZmlsZSBkZXNjcmlwdG9yIHRvIHRoZSBwb29sLgorICBBU1NFUlRfVFJVRShwb29sLkJ1aWxkRmlsZShmaWxlX3Byb3RvKSAhPSBOVUxMKTsKKworICAvLyBGaW5kIHRoZSB0ZXN0IG1lc3NhZ2UuCisgIGNvbnN0IERlc2NyaXB0b3IqIHRlc3RfbWVzc2FnZSA9IHBvb2wuRmluZE1lc3NhZ2VUeXBlQnlOYW1lKAorICAgICAgInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlV2l0aFJlcXVpcmVkRW51bU9wdGlvbiIpOworICBBU1NFUlRfVFJVRSh0ZXN0X21lc3NhZ2UgIT0gTlVMTCk7CisKKyAgY29uc3QgTWVzc2FnZU9wdGlvbnMmIG9wdGlvbnMgPSB0ZXN0X21lc3NhZ2UtPm9wdGlvbnMoKTsKKyAgLy8gRXh0cmFjdCB0aGUgInJlcXVpcmVkX2VudW1fb3B0IiBvcHRpb24uIFNpbmNlIHRoZSBiaW5hcnkgZG9lcyBub3QKKyAgLy8ga25vdyB0aGF0IHRoZSBleHRlbnNpb24gd2FzIHVwZGF0ZWQsIHRoaXMgd2lsbCBzdGlsbCByZXR1cm4gYW4KKyAgLy8gT2xkT3B0aW9uVHlwZSBtZXNzYWdlLgorICBBU1NFUlRfVFJVRSgKKyAgICAgIG9wdGlvbnMuSGFzRXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0OjpyZXF1aXJlZF9lbnVtX29wdCkpOworICBjb25zdCBwcm90b2J1Zl91bml0dGVzdDo6T2xkT3B0aW9uVHlwZSYgb2xkX2VudW1fb3B0ID0KKyAgICAgIG9wdGlvbnMuR2V0RXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0OjpyZXF1aXJlZF9lbnVtX29wdCk7CisKKyAgLy8gQ29uZmlybSB0aGF0IHRoZSByZXF1aXJlZCBlbnVtIGZpZWxkIGlzIG1pc3NpbmcuCisgIEVYUEVDVF9GQUxTRShvbGRfZW51bV9vcHQuSXNJbml0aWFsaXplZCgpKTsKKyAgRVhQRUNUX0ZBTFNFKG9sZF9lbnVtX29wdC5oYXNfdmFsdWUoKSk7CisKKyAgc3RyaW5nIGJ1ZjsKKyAgLy8gVmVyaWZ5IHRoYXQgdGhlIHJlcXVpcmVkIGVudW0gZmllbGQgZG9lcyBzaG93IHVwIHdoZW4gdGhlIG9wdGlvbgorICAvLyBpcyByZS1wYXJzZWQgYXMgYSBOZXdPcHRpb25UeXBlIG1lc3NhZ2U7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpOZXdPcHRpb25UeXBlIG5ld19lbnVtX29wdDsKKyAgRVhQRUNUX1RSVUUob2xkX2VudW1fb3B0LkFwcGVuZFBhcnRpYWxUb1N0cmluZygmYnVmKSk7CisgIEVYUEVDVF9UUlVFKG5ld19lbnVtX29wdC5QYXJzZUZyb21TdHJpbmcoYnVmKSk7CisgIEVYUEVDVF9FUShwcm90b2J1Zl91bml0dGVzdDo6TmV3T3B0aW9uVHlwZTo6TkVXX1ZBTFVFLCBuZXdfZW51bV9vcHQudmFsdWUoKSk7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworY2xhc3MgVmFsaWRhdGlvbkVycm9yVGVzdCA6IHB1YmxpYyB0ZXN0aW5nOjpUZXN0IHsKKyBwcm90ZWN0ZWQ6CisgIC8vIFBhcnNlIGZpbGVfdGV4dCBhcyBhIEZpbGVEZXNjcmlwdG9yUHJvdG8gaW4gdGV4dCBmb3JtYXQgYW5kIGFkZCBpdAorICAvLyB0byB0aGUgRGVzY3JpcHRvclBvb2wuICBFeHBlY3Qgbm8gZXJyb3JzLgorICBjb25zdCBGaWxlRGVzY3JpcHRvciogQnVpbGRGaWxlKGNvbnN0IHN0cmluZyYgZmlsZV90ZXh0KSB7CisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICAgIEVYUEVDVF9UUlVFKFRleHRGb3JtYXQ6OlBhcnNlRnJvbVN0cmluZyhmaWxlX3RleHQsICZmaWxlX3Byb3RvKSk7CisgICAgcmV0dXJuIEdPT0dMRV9DSEVDS19OT1ROVUxMKHBvb2xfLkJ1aWxkRmlsZShmaWxlX3Byb3RvKSk7CisgIH0KKworICAvLyBQYXJzZSBmaWxlX3RleHQgYXMgYSBGaWxlRGVzY3JpcHRvclByb3RvIGluIHRleHQgZm9ybWF0IGFuZCBhZGQgaXQKKyAgLy8gdG8gdGhlIERlc2NyaXB0b3JQb29sLiAgRXhwZWN0IGVycm9ycyB0byBiZSBwcm9kdWNlZCB3aGljaCBtYXRjaCB0aGUKKyAgLy8gZ2l2ZW4gZXJyb3IgdGV4dC4KKyAgdm9pZCBCdWlsZEZpbGVXaXRoRXJyb3JzKGNvbnN0IHN0cmluZyYgZmlsZV90ZXh0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBleHBlY3RlZF9lcnJvcnMpIHsKKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGVfcHJvdG87CisgICAgQVNTRVJUX1RSVUUoVGV4dEZvcm1hdDo6UGFyc2VGcm9tU3RyaW5nKGZpbGVfdGV4dCwgJmZpbGVfcHJvdG8pKTsKKworICAgIE1vY2tFcnJvckNvbGxlY3RvciBlcnJvcl9jb2xsZWN0b3I7CisgICAgRVhQRUNUX1RSVUUoCisgICAgICBwb29sXy5CdWlsZEZpbGVDb2xsZWN0aW5nRXJyb3JzKGZpbGVfcHJvdG8sICZlcnJvcl9jb2xsZWN0b3IpID09IE5VTEwpOworICAgIEVYUEVDVF9FUShleHBlY3RlZF9lcnJvcnMsIGVycm9yX2NvbGxlY3Rvci50ZXh0Xyk7CisgIH0KKworICAvLyBQYXJzZSBmaWxlX3RleHQgYXMgYSBGaWxlRGVzY3JpcHRvclByb3RvIGluIHRleHQgZm9ybWF0IGFuZCBhZGQgaXQKKyAgLy8gdG8gdGhlIERlc2NyaXB0b3JQb29sLiAgRXhwZWN0IGVycm9ycyB0byBiZSBwcm9kdWNlZCB3aGljaCBtYXRjaCB0aGUKKyAgLy8gZ2l2ZW4gd2FybmluZyB0ZXh0LgorICB2b2lkIEJ1aWxkRmlsZVdpdGhXYXJuaW5ncyhjb25zdCBzdHJpbmcmIGZpbGVfdGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBleHBlY3RlZF93YXJuaW5ncykgeworICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZV9wcm90bzsKKyAgICBBU1NFUlRfVFJVRShUZXh0Rm9ybWF0OjpQYXJzZUZyb21TdHJpbmcoZmlsZV90ZXh0LCAmZmlsZV9wcm90bykpOworCisgICAgTW9ja0Vycm9yQ29sbGVjdG9yIGVycm9yX2NvbGxlY3RvcjsKKyAgICBFWFBFQ1RfVFJVRShwb29sXy5CdWlsZEZpbGVDb2xsZWN0aW5nRXJyb3JzKGZpbGVfcHJvdG8sICZlcnJvcl9jb2xsZWN0b3IpKTsKKyAgICBFWFBFQ1RfRVEoZXhwZWN0ZWRfd2FybmluZ3MsIGVycm9yX2NvbGxlY3Rvci53YXJuaW5nX3RleHRfKTsKKyAgfQorCisgIC8vIEJ1aWxkcyBzb21lIGFscmVhZHktcGFyc2VkIGZpbGUgaW4gb3VyIHRlc3QgcG9vbC4KKyAgdm9pZCBCdWlsZEZpbGVJblRlc3RQb29sKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKSB7CisgICAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICAgIGZpbGUtPkNvcHlUbygmZmlsZV9wcm90byk7CisgICAgQVNTRVJUX1RSVUUocG9vbF8uQnVpbGRGaWxlKGZpbGVfcHJvdG8pICE9IE5VTEwpOworICB9CisKKyAgLy8gQnVpbGQgZGVzY3JpcHRvci5wcm90byBpbiBvdXIgdGVzdCBwb29sLiBUaGlzIGFsbG93cyB1cyB0byBleHRlbmQgaXQgaW4KKyAgLy8gdGhlIHRlc3QgcG9vbCwgc28gd2UgY2FuIHRlc3QgY3VzdG9tIG9wdGlvbnMuCisgIHZvaWQgQnVpbGREZXNjcmlwdG9yTWVzc2FnZXNJblRlc3RQb29sKCkgeworICAgIEJ1aWxkRmlsZUluVGVzdFBvb2woRGVzY3JpcHRvclByb3RvOjpkZXNjcmlwdG9yKCktPmZpbGUoKSk7CisgIH0KKworICBEZXNjcmlwdG9yUG9vbCBwb29sXzsKK307CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBBbHJlYWR5RGVmaW5lZCkgeworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsgbmFtZTogXCJGb29cIiB9IgorICAgICJtZXNzYWdlX3R5cGUgeyBuYW1lOiBcIkZvb1wiIH0iLAorCisgICAgImZvby5wcm90bzogRm9vOiBOQU1FOiBcIkZvb1wiIGlzIGFscmVhZHkgZGVmaW5lZC5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgQWxyZWFkeURlZmluZWRJblBhY2thZ2UpIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgInBhY2thZ2U6IFwiZm9vLmJhclwiICIKKyAgICAibWVzc2FnZV90eXBlIHsgbmFtZTogXCJGb29cIiB9IgorICAgICJtZXNzYWdlX3R5cGUgeyBuYW1lOiBcIkZvb1wiIH0iLAorCisgICAgImZvby5wcm90bzogZm9vLmJhci5Gb286IE5BTUU6IFwiRm9vXCIgaXMgYWxyZWFkeSBkZWZpbmVkIGluICIKKyAgICAgICJcImZvby5iYXJcIi5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgQWxyZWFkeURlZmluZWRJbk90aGVyRmlsZSkgeworICBCdWlsZEZpbGUoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyBuYW1lOiBcIkZvb1wiIH0iKTsKKworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImJhci5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsgbmFtZTogXCJGb29cIiB9IiwKKworICAgICJiYXIucHJvdG86IEZvbzogTkFNRTogXCJGb29cIiBpcyBhbHJlYWR5IGRlZmluZWQgaW4gZmlsZSAiCisgICAgICAiXCJmb28ucHJvdG9cIi5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgUGFja2FnZUFscmVhZHlEZWZpbmVkKSB7CisgIEJ1aWxkRmlsZSgKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IG5hbWU6IFwiZm9vXCIgfSIpOworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImJhci5wcm90b1wiICIKKyAgICAicGFja2FnZTogXCJmb28uYmFyXCIiLAorCisgICAgImJhci5wcm90bzogZm9vOiBOQU1FOiBcImZvb1wiIGlzIGFscmVhZHkgZGVmaW5lZCAoYXMgc29tZXRoaW5nIG90aGVyICIKKyAgICAgICJ0aGFuIGEgcGFja2FnZSkgaW4gZmlsZSBcImZvby5wcm90b1wiLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBFbnVtVmFsdWVBbHJlYWR5RGVmaW5lZEluUGFyZW50KSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJlbnVtX3R5cGUgeyBuYW1lOiBcIkZvb1wiIHZhbHVlIHsgbmFtZTogXCJGT09cIiBudW1iZXI6IDEgfSB9ICIKKyAgICAiZW51bV90eXBlIHsgbmFtZTogXCJCYXJcIiB2YWx1ZSB7IG5hbWU6IFwiRk9PXCIgbnVtYmVyOiAxIH0gfSAiLAorCisgICAgImZvby5wcm90bzogRk9POiBOQU1FOiBcIkZPT1wiIGlzIGFscmVhZHkgZGVmaW5lZC5cbiIKKyAgICAiZm9vLnByb3RvOiBGT086IE5BTUU6IE5vdGUgdGhhdCBlbnVtIHZhbHVlcyB1c2UgQysrIHNjb3BpbmcgcnVsZXMsICIKKyAgICAgICJtZWFuaW5nIHRoYXQgZW51bSB2YWx1ZXMgYXJlIHNpYmxpbmdzIG9mIHRoZWlyIHR5cGUsIG5vdCBjaGlsZHJlbiBvZiAiCisgICAgICAiaXQuICBUaGVyZWZvcmUsIFwiRk9PXCIgbXVzdCBiZSB1bmlxdWUgd2l0aGluIHRoZSBnbG9iYWwgc2NvcGUsIG5vdCAiCisgICAgICAianVzdCB3aXRoaW4gXCJCYXJcIi5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgRW51bVZhbHVlQWxyZWFkeURlZmluZWRJblBhcmVudE5vbkdsb2JhbCkgeworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAicGFja2FnZTogXCJwa2dcIiAiCisgICAgImVudW1fdHlwZSB7IG5hbWU6IFwiRm9vXCIgdmFsdWUgeyBuYW1lOiBcIkZPT1wiIG51bWJlcjogMSB9IH0gIgorICAgICJlbnVtX3R5cGUgeyBuYW1lOiBcIkJhclwiIHZhbHVlIHsgbmFtZTogXCJGT09cIiBudW1iZXI6IDEgfSB9ICIsCisKKyAgICAiZm9vLnByb3RvOiBwa2cuRk9POiBOQU1FOiBcIkZPT1wiIGlzIGFscmVhZHkgZGVmaW5lZCBpbiBcInBrZ1wiLlxuIgorICAgICJmb28ucHJvdG86IHBrZy5GT086IE5BTUU6IE5vdGUgdGhhdCBlbnVtIHZhbHVlcyB1c2UgQysrIHNjb3BpbmcgcnVsZXMsICIKKyAgICAgICJtZWFuaW5nIHRoYXQgZW51bSB2YWx1ZXMgYXJlIHNpYmxpbmdzIG9mIHRoZWlyIHR5cGUsIG5vdCBjaGlsZHJlbiBvZiAiCisgICAgICAiaXQuICBUaGVyZWZvcmUsIFwiRk9PXCIgbXVzdCBiZSB1bmlxdWUgd2l0aGluIFwicGtnXCIsIG5vdCBqdXN0IHdpdGhpbiAiCisgICAgICAiXCJCYXJcIi5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgTWlzc2luZ05hbWUpIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IH0iLAorCisgICAgImZvby5wcm90bzogOiBOQU1FOiBNaXNzaW5nIG5hbWUuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIEludmFsaWROYW1lKSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyBuYW1lOiBcIiRcIiB9IiwKKworICAgICJmb28ucHJvdG86ICQ6IE5BTUU6IFwiJFwiIGlzIG5vdCBhIHZhbGlkIGlkZW50aWZpZXIuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIEludmFsaWRQYWNrYWdlTmFtZSkgeworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAicGFja2FnZTogXCJmb28uJFwiIiwKKworICAgICJmb28ucHJvdG86IGZvby4kOiBOQU1FOiBcIiRcIiBpcyBub3QgYSB2YWxpZCBpZGVudGlmaWVyLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBNaXNzaW5nRmlsZU5hbWUpIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAiIiwKKworICAgICI6IDogT1RIRVI6IE1pc3NpbmcgZmllbGQ6IEZpbGVEZXNjcmlwdG9yUHJvdG8ubmFtZS5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgRHVwZURlcGVuZGVuY3kpIHsKKyAgQnVpbGRGaWxlKCJuYW1lOiBcImZvby5wcm90b1wiIik7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiYmFyLnByb3RvXCIgIgorICAgICJkZXBlbmRlbmN5OiBcImZvby5wcm90b1wiICIKKyAgICAiZGVwZW5kZW5jeTogXCJmb28ucHJvdG9cIiAiLAorCisgICAgImJhci5wcm90bzogYmFyLnByb3RvOiBPVEhFUjogSW1wb3J0IFwiZm9vLnByb3RvXCIgd2FzIGxpc3RlZCB0d2ljZS5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgVW5rbm93bkRlcGVuZGVuY3kpIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJiYXIucHJvdG9cIiAiCisgICAgImRlcGVuZGVuY3k6IFwiZm9vLnByb3RvXCIgIiwKKworICAgICJiYXIucHJvdG86IGJhci5wcm90bzogT1RIRVI6IEltcG9ydCBcImZvby5wcm90b1wiIGhhcyBub3QgYmVlbiBsb2FkZWQuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIEludmFsaWRQdWJsaWNEZXBlbmRlbmN5SW5kZXgpIHsKKyAgQnVpbGRGaWxlKCJuYW1lOiBcImZvby5wcm90b1wiIik7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiYmFyLnByb3RvXCIgIgorICAgICJkZXBlbmRlbmN5OiBcImZvby5wcm90b1wiICIKKyAgICAicHVibGljX2RlcGVuZGVuY3k6IDEiLAorICAgICJiYXIucHJvdG86IGJhci5wcm90bzogT1RIRVI6IEludmFsaWQgcHVibGljIGRlcGVuZGVuY3kgaW5kZXguXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIEZvcmVpZ25VbmltcG9ydGVkUGFja2FnZU5vQ3Jhc2gpIHsKKyAgLy8gVXNlZCB0byBjcmFzaDogIElmIHdlIGRlcGVuZCBvbiBhIG5vbi1leGlzdGVudCBmaWxlIGFuZCB0aGVuIHJlZmVyIHRvIGEKKyAgLy8gcGFja2FnZSBkZWZpbmVkIGluIGEgZmlsZSB0aGF0IHdlIGRpZG4ndCBpbXBvcnQsIGFuZCB0aGF0IHBhY2thZ2UgaXMKKyAgLy8gbmVzdGVkIHdpdGhpbiBhIHBhcmVudCBwYWNrYWdlIHdoaWNoIHRoaXMgZmlsZSBpcyBhbHNvIGluLCBhbmQgd2UgZG9uJ3QKKyAgLy8gaW5jbHVkZSB0aGF0IHBhcmVudCBwYWNrYWdlIGluIHRoZSBuYW1lIChpLmUuIHdlIGRvIGEgcmVsYXRpdmUgbG9va3VwKS4uLgorICAvLyBZZXMsIHJlYWxseS4KKyAgQnVpbGRGaWxlKAorICAgICJuYW1lOiAnZm9vLnByb3RvJyAiCisgICAgInBhY2thZ2U6ICdvdXRlci5mb28nICIpOworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiAnYmFyLnByb3RvJyAiCisgICAgImRlcGVuZGVuY3k6ICdiYXoucHJvdG8nICIKKyAgICAicGFja2FnZTogJ291dGVyLmJhcicgIgorICAgICJtZXNzYWdlX3R5cGUgeyAiCisgICAgIiAgbmFtZTogJ0JhcicgIgorICAgICIgIGZpZWxkIHsgbmFtZTonYmFyJyBudW1iZXI6MSBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlX25hbWU6J2Zvby5Gb28nIH0iCisgICAgIn0iLAorCisgICAgImJhci5wcm90bzogYmFyLnByb3RvOiBPVEhFUjogSW1wb3J0IFwiYmF6LnByb3RvXCIgaGFzIG5vdCBiZWVuIGxvYWRlZC5cbiIKKyAgICAiYmFyLnByb3RvOiBvdXRlci5iYXIuQmFyLmJhcjogVFlQRTogXCJvdXRlci5mb29cIiBzZWVtcyB0byBiZSBkZWZpbmVkIGluICIKKyAgICAgICJcImZvby5wcm90b1wiLCB3aGljaCBpcyBub3QgaW1wb3J0ZWQgYnkgXCJiYXIucHJvdG9cIi4gIFRvIHVzZSBpdCBoZXJlLCAiCisgICAgICAicGxlYXNlIGFkZCB0aGUgbmVjZXNzYXJ5IGltcG9ydC5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgRHVwZUZpbGUpIHsKKyAgQnVpbGRGaWxlKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsgbmFtZTogXCJGb29cIiB9Iik7CisgIC8vIE5vdGU6ICBXZSBzaG91bGQgKm5vdCogZ2V0IHJlZHVuZGFudCBlcnJvcnMgYWJvdXQgIkZvbyIgYWxyZWFkeSBiZWluZworICAvLyAgIGRlZmluZWQuCisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyBuYW1lOiBcIkZvb1wiIH0gIgorICAgIC8vIEFkZCBhbm90aGVyIHR5cGUgc28gdGhhdCB0aGUgZmlsZXMgYXJlbid0IGlkZW50aWNhbCAoaW4gd2hpY2ggY2FzZSB0aGVyZQorICAgIC8vIHdvdWxkIGJlIG5vIGVycm9yKS4KKyAgICAiZW51bV90eXBlIHsgbmFtZTogXCJCYXJcIiB9IiwKKworICAgICJmb28ucHJvdG86IGZvby5wcm90bzogT1RIRVI6IEEgZmlsZSB3aXRoIHRoaXMgbmFtZSBpcyBhbHJlYWR5IGluIHRoZSAiCisgICAgICAicG9vbC5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgRmllbGRJbkV4dGVuc2lvblJhbmdlKSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIkZvb1wiIgorICAgICIgIGZpZWxkIHsgbmFtZTogXCJmb29cIiBudW1iZXI6ICA5IGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiB9IgorICAgICIgIGZpZWxkIHsgbmFtZTogXCJiYXJcIiBudW1iZXI6IDEwIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiB9IgorICAgICIgIGZpZWxkIHsgbmFtZTogXCJiYXpcIiBudW1iZXI6IDE5IGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiB9IgorICAgICIgIGZpZWxkIHsgbmFtZTogXCJxdXhcIiBudW1iZXI6IDIwIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiB9IgorICAgICIgIGV4dGVuc2lvbl9yYW5nZSB7IHN0YXJ0OiAxMCBlbmQ6IDIwIH0iCisgICAgIn0iLAorCisgICAgImZvby5wcm90bzogRm9vLmJhcjogTlVNQkVSOiBFeHRlbnNpb24gcmFuZ2UgMTAgdG8gMTkgaW5jbHVkZXMgZmllbGQgIgorICAgICAgIlwiYmFyXCIgKDEwKS5cbiIKKyAgICAiZm9vLnByb3RvOiBGb28uYmF6OiBOVU1CRVI6IEV4dGVuc2lvbiByYW5nZSAxMCB0byAxOSBpbmNsdWRlcyBmaWVsZCAiCisgICAgICAiXCJiYXpcIiAoMTkpLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBPdmVybGFwcGluZ0V4dGVuc2lvblJhbmdlcykgeworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJGb29cIiIKKyAgICAiICBleHRlbnNpb25fcmFuZ2UgeyBzdGFydDogMTAgZW5kOiAyMCB9IgorICAgICIgIGV4dGVuc2lvbl9yYW5nZSB7IHN0YXJ0OiAyMCBlbmQ6IDMwIH0iCisgICAgIiAgZXh0ZW5zaW9uX3JhbmdlIHsgc3RhcnQ6IDE5IGVuZDogMjEgfSIKKyAgICAifSIsCisKKyAgICAiZm9vLnByb3RvOiBGb286IE5VTUJFUjogRXh0ZW5zaW9uIHJhbmdlIDE5IHRvIDIwIG92ZXJsYXBzIHdpdGggIgorICAgICAgImFscmVhZHktZGVmaW5lZCByYW5nZSAxMCB0byAxOS5cbiIKKyAgICAiZm9vLnByb3RvOiBGb286IE5VTUJFUjogRXh0ZW5zaW9uIHJhbmdlIDE5IHRvIDIwIG92ZXJsYXBzIHdpdGggIgorICAgICAgImFscmVhZHktZGVmaW5lZCByYW5nZSAyMCB0byAyOS5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgUmVzZXJ2ZWRGaWVsZEVycm9yKSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIkZvb1wiIgorICAgICIgIGZpZWxkIHsgbmFtZTogXCJmb29cIiBudW1iZXI6IDE1IGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiB9IgorICAgICIgIHJlc2VydmVkX3JhbmdlIHsgc3RhcnQ6IDEwIGVuZDogMjAgfSIKKyAgICAifSIsCisKKyAgICAiZm9vLnByb3RvOiBGb28uZm9vOiBOVU1CRVI6IEZpZWxkIFwiZm9vXCIgdXNlcyByZXNlcnZlZCBudW1iZXIgMTUuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIFJlc2VydmVkRXh0ZW5zaW9uUmFuZ2VFcnJvcikgeworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJGb29cIiIKKyAgICAiICBleHRlbnNpb25fcmFuZ2UgeyBzdGFydDogMTAgZW5kOiAyMCB9IgorICAgICIgIHJlc2VydmVkX3JhbmdlIHsgc3RhcnQ6IDUgZW5kOiAxNSB9IgorICAgICJ9IiwKKworICAgICJmb28ucHJvdG86IEZvbzogTlVNQkVSOiBFeHRlbnNpb24gcmFuZ2UgMTAgdG8gMTkiCisgICAgIiBvdmVybGFwcyB3aXRoIHJlc2VydmVkIHJhbmdlIDUgdG8gMTQuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIFJlc2VydmVkRXh0ZW5zaW9uUmFuZ2VBZGphY2VudCkgeworICBCdWlsZEZpbGUoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIkZvb1wiIgorICAgICIgIGV4dGVuc2lvbl9yYW5nZSB7IHN0YXJ0OiAxMCBlbmQ6IDIwIH0iCisgICAgIiAgcmVzZXJ2ZWRfcmFuZ2UgeyBzdGFydDogNSBlbmQ6IDEwIH0iCisgICAgIn0iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIFJlc2VydmVkUmFuZ2VPdmVybGFwKSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIkZvb1wiIgorICAgICIgIHJlc2VydmVkX3JhbmdlIHsgc3RhcnQ6IDEwIGVuZDogMjAgfSIKKyAgICAiICByZXNlcnZlZF9yYW5nZSB7IHN0YXJ0OiA1IGVuZDogMTUgfSIKKyAgICAifSIsCisKKyAgICAiZm9vLnByb3RvOiBGb286IE5VTUJFUjogUmVzZXJ2ZWQgcmFuZ2UgNSB0byAxNCIKKyAgICAiIG92ZXJsYXBzIHdpdGggYWxyZWFkeS1kZWZpbmVkIHJhbmdlIDEwIHRvIDE5LlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBSZXNlcnZlZE5hbWVFcnJvcikgeworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJGb29cIiIKKyAgICAiICBmaWVsZCB7IG5hbWU6IFwiZm9vXCIgbnVtYmVyOiAxNSBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgfSIKKyAgICAiICBmaWVsZCB7IG5hbWU6IFwiYmFyXCIgbnVtYmVyOiAxNiBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgfSIKKyAgICAiICBmaWVsZCB7IG5hbWU6IFwiYmF6XCIgbnVtYmVyOiAxNyBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgfSIKKyAgICAiICByZXNlcnZlZF9uYW1lOiBcImZvb1wiIgorICAgICIgIHJlc2VydmVkX25hbWU6IFwiYmFyXCIiCisgICAgIn0iLAorCisgICAgImZvby5wcm90bzogRm9vLmZvbzogTkFNRTogRmllbGQgbmFtZSBcImZvb1wiIGlzIHJlc2VydmVkLlxuIgorICAgICJmb28ucHJvdG86IEZvby5iYXI6IE5BTUU6IEZpZWxkIG5hbWUgXCJiYXJcIiBpcyByZXNlcnZlZC5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgUmVzZXJ2ZWROYW1lUmVkdW5kYW50KSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIkZvb1wiIgorICAgICIgIHJlc2VydmVkX25hbWU6IFwiZm9vXCIiCisgICAgIiAgcmVzZXJ2ZWRfbmFtZTogXCJmb29cIiIKKyAgICAifSIsCisKKyAgICAiZm9vLnByb3RvOiBmb286IE5BTUU6IEZpZWxkIG5hbWUgXCJmb29cIiBpcyByZXNlcnZlZCBtdWx0aXBsZSB0aW1lcy5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgUmVzZXJ2ZWRGaWVsZHNEZWJ1Z1N0cmluZykgeworICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSA9IEJ1aWxkRmlsZSgKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiRm9vXCIiCisgICAgIiAgcmVzZXJ2ZWRfbmFtZTogXCJmb29cIiIKKyAgICAiICByZXNlcnZlZF9uYW1lOiBcImJhclwiIgorICAgICIgIHJlc2VydmVkX3JhbmdlIHsgc3RhcnQ6IDUgZW5kOiA2IH0iCisgICAgIiAgcmVzZXJ2ZWRfcmFuZ2UgeyBzdGFydDogMTAgZW5kOiAyMCB9IgorICAgICJ9Iik7CisKKyAgQVNTRVJUX0VRKAorICAgICJzeW50YXggPSBcInByb3RvMlwiO1xuXG4iCisgICAgIm1lc3NhZ2UgRm9vIHtcbiIKKyAgICAiICByZXNlcnZlZCA1LCAxMCB0byAxOTtcbiIKKyAgICAiICByZXNlcnZlZCBcImZvb1wiLCBcImJhclwiO1xuIgorICAgICJ9XG5cbiIsCisgICAgZmlsZS0+RGVidWdTdHJpbmcoKSk7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBJbnZhbGlkRGVmYXVsdHMpIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiRm9vXCIiCisKKyAgICAvLyBJbnZhbGlkIG51bWJlci4KKyAgICAiICBmaWVsZCB7IG5hbWU6IFwiZm9vXCIgbnVtYmVyOiAxIGxhYmVsOiBMQUJFTF9PUFRJT05BTCB0eXBlOiBUWVBFX0lOVDMyIgorICAgICIgICAgICAgICAgZGVmYXVsdF92YWx1ZTogXCJhYmNcIiB9IgorCisgICAgLy8gRW1wdHkgZGVmYXVsdCB2YWx1ZS4KKyAgICAiICBmaWVsZCB7IG5hbWU6IFwiYmFyXCIgbnVtYmVyOiAyIGxhYmVsOiBMQUJFTF9PUFRJT05BTCB0eXBlOiBUWVBFX0lOVDMyIgorICAgICIgICAgICAgICAgZGVmYXVsdF92YWx1ZTogXCJcIiB9IgorCisgICAgLy8gSW52YWxpZCBib29sZWFuLgorICAgICIgIGZpZWxkIHsgbmFtZTogXCJiYXpcIiBudW1iZXI6IDMgbGFiZWw6IExBQkVMX09QVElPTkFMIHR5cGU6IFRZUEVfQk9PTCIKKyAgICAiICAgICAgICAgIGRlZmF1bHRfdmFsdWU6IFwiYWJjXCIgfSIKKworICAgIC8vIE1lc3NhZ2VzIGNhbid0IGhhdmUgZGVmYXVsdHMuCisgICAgIiAgZmllbGQgeyBuYW1lOiBcInF1eFwiIG51bWJlcjogNCBsYWJlbDogTEFCRUxfT1BUSU9OQUwgdHlwZTogVFlQRV9NRVNTQUdFIgorICAgICIgICAgICAgICAgZGVmYXVsdF92YWx1ZTogXCJhYmNcIiB0eXBlX25hbWU6IFwiRm9vXCIgfSIKKworICAgIC8vIFNhbWUgdGhpbmcsIGJ1dCB3ZSBkb24ndCBrbm93IHRoYXQgdGhpcyBmaWVsZCBoYXMgbWVzc2FnZSB0eXBlIHVudGlsCisgICAgLy8gd2UgbG9vayB1cCB0aGUgdHlwZSBuYW1lLgorICAgICIgIGZpZWxkIHsgbmFtZTogXCJxdXV4XCIgbnVtYmVyOiA1IGxhYmVsOiBMQUJFTF9PUFRJT05BTCIKKyAgICAiICAgICAgICAgIGRlZmF1bHRfdmFsdWU6IFwiYWJjXCIgdHlwZV9uYW1lOiBcIkZvb1wiIH0iCisKKyAgICAvLyBSZXBlYXRlZHMgY2FuJ3QgaGF2ZSBkZWZhdWx0cy4KKyAgICAiICBmaWVsZCB7IG5hbWU6IFwiY29yZ2VcIiBudW1iZXI6IDYgbGFiZWw6IExBQkVMX1JFUEVBVEVEIHR5cGU6IFRZUEVfSU5UMzIiCisgICAgIiAgICAgICAgICBkZWZhdWx0X3ZhbHVlOiBcIjFcIiB9IgorICAgICJ9IiwKKworICAgICJmb28ucHJvdG86IEZvby5mb286IERFRkFVTFRfVkFMVUU6IENvdWxkbid0IHBhcnNlIGRlZmF1bHQgdmFsdWUgXCJhYmNcIi5cbiIKKyAgICAiZm9vLnByb3RvOiBGb28uYmFyOiBERUZBVUxUX1ZBTFVFOiBDb3VsZG4ndCBwYXJzZSBkZWZhdWx0IHZhbHVlIFwiXCIuXG4iCisgICAgImZvby5wcm90bzogRm9vLmJhejogREVGQVVMVF9WQUxVRTogQm9vbGVhbiBkZWZhdWx0IG11c3QgYmUgdHJ1ZSBvciAiCisgICAgICAiZmFsc2UuXG4iCisgICAgImZvby5wcm90bzogRm9vLnF1eDogREVGQVVMVF9WQUxVRTogTWVzc2FnZXMgY2FuJ3QgaGF2ZSBkZWZhdWx0IHZhbHVlcy5cbiIKKyAgICAiZm9vLnByb3RvOiBGb28uY29yZ2U6IERFRkFVTFRfVkFMVUU6IFJlcGVhdGVkIGZpZWxkcyBjYW4ndCBoYXZlIGRlZmF1bHQgIgorICAgICAgInZhbHVlcy5cbiIKKyAgICAvLyBUaGlzIGVuZHMgdXAgYmVpbmcgcmVwb3J0ZWQgbGF0ZXIgYmVjYXVzZSB0aGUgZXJyb3IgaXMgZGV0ZWN0ZWQgYXQKKyAgICAvLyBjcm9zcy1saW5raW5nIHRpbWUuCisgICAgImZvby5wcm90bzogRm9vLnF1dXg6IERFRkFVTFRfVkFMVUU6IE1lc3NhZ2VzIGNhbid0IGhhdmUgZGVmYXVsdCAiCisgICAgICAidmFsdWVzLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBOZWdhdGl2ZUZpZWxkTnVtYmVyKSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIkZvb1wiIgorICAgICIgIGZpZWxkIHsgbmFtZTogXCJmb29cIiBudW1iZXI6IC0xIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiB9IgorICAgICJ9IiwKKworICAgICJmb28ucHJvdG86IEZvby5mb286IE5VTUJFUjogRmllbGQgbnVtYmVycyBtdXN0IGJlIHBvc2l0aXZlIGludGVnZXJzLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBIdWdlRmllbGROdW1iZXIpIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiRm9vXCIiCisgICAgIiAgZmllbGQgeyBuYW1lOiBcImZvb1wiIG51bWJlcjogMHg3MDAwMDAwMCAiCisgICAgIiAgICAgICAgICBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgfSIKKyAgICAifSIsCisKKyAgICAiZm9vLnByb3RvOiBGb28uZm9vOiBOVU1CRVI6IEZpZWxkIG51bWJlcnMgY2Fubm90IGJlIGdyZWF0ZXIgdGhhbiAiCisgICAgICAiNTM2ODcwOTExLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBSZXNlcnZlZEZpZWxkTnVtYmVyKSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIkZvb1wiIgorICAgICIgIGZpZWxkIHtuYW1lOlwiZm9vXCIgbnVtYmVyOiAxODk5OSBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgfSIKKyAgICAiICBmaWVsZCB7bmFtZTpcImJhclwiIG51bWJlcjogMTkwMDAgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZTpUWVBFX0lOVDMyIH0iCisgICAgIiAgZmllbGQge25hbWU6XCJiYXpcIiBudW1iZXI6IDE5OTk5IGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiB9IgorICAgICIgIGZpZWxkIHtuYW1lOlwicXV4XCIgbnVtYmVyOiAyMDAwMCBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgfSIKKyAgICAifSIsCisKKyAgICAiZm9vLnByb3RvOiBGb28uYmFyOiBOVU1CRVI6IEZpZWxkIG51bWJlcnMgMTkwMDAgdGhyb3VnaCAxOTk5OSBhcmUgIgorICAgICAgInJlc2VydmVkIGZvciB0aGUgcHJvdG9jb2wgYnVmZmVyIGxpYnJhcnkgaW1wbGVtZW50YXRpb24uXG4iCisgICAgImZvby5wcm90bzogRm9vLmJhejogTlVNQkVSOiBGaWVsZCBudW1iZXJzIDE5MDAwIHRocm91Z2ggMTk5OTkgYXJlICIKKyAgICAgICJyZXNlcnZlZCBmb3IgdGhlIHByb3RvY29sIGJ1ZmZlciBsaWJyYXJ5IGltcGxlbWVudGF0aW9uLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBFeHRlbnNpb25NaXNzaW5nRXh0ZW5kZWUpIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiRm9vXCIiCisgICAgIiAgZXh0ZW5zaW9uIHsgbmFtZTogXCJmb29cIiBudW1iZXI6IDEgbGFiZWw6IExBQkVMX09QVElPTkFMIgorICAgICIgICAgICAgICAgICAgIHR5cGVfbmFtZTogXCJGb29cIiB9IgorICAgICJ9IiwKKworICAgICJmb28ucHJvdG86IEZvby5mb286IEVYVEVOREVFOiBGaWVsZERlc2NyaXB0b3JQcm90by5leHRlbmRlZSBub3Qgc2V0IGZvciAiCisgICAgICAiZXh0ZW5zaW9uIGZpZWxkLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBOb25FeHRlbnNpb25XaXRoRXh0ZW5kZWUpIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiQmFyXCIiCisgICAgIiAgZXh0ZW5zaW9uX3JhbmdlIHsgc3RhcnQ6IDEgZW5kOiAyIH0iCisgICAgIn0iCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiRm9vXCIiCisgICAgIiAgZmllbGQgeyBuYW1lOiBcImZvb1wiIG51bWJlcjogMSBsYWJlbDogTEFCRUxfT1BUSU9OQUwiCisgICAgIiAgICAgICAgICB0eXBlX25hbWU6IFwiRm9vXCIgZXh0ZW5kZWU6IFwiQmFyXCIgfSIKKyAgICAifSIsCisKKyAgICAiZm9vLnByb3RvOiBGb28uZm9vOiBFWFRFTkRFRTogRmllbGREZXNjcmlwdG9yUHJvdG8uZXh0ZW5kZWUgc2V0IGZvciAiCisgICAgICAibm9uLWV4dGVuc2lvbiBmaWVsZC5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgRmllbGRPbmVvZkluZGV4VG9vTGFyZ2UpIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiRm9vXCIiCisgICAgIiAgZmllbGQgeyBuYW1lOlwiZm9vXCIgbnVtYmVyOjEgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZTpUWVBFX0lOVDMyICIKKyAgICAiICAgICAgICAgIG9uZW9mX2luZGV4OiAxIH0iCisgICAgIiAgZmllbGQgeyBuYW1lOlwiZHVtbXlcIiBudW1iZXI6MiBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgIgorICAgICIgICAgICAgICAgb25lb2ZfaW5kZXg6IDAgfSIKKyAgICAiICBvbmVvZl9kZWNsIHsgbmFtZTpcImJhclwiIH0iCisgICAgIn0iLAorCisgICAgImZvby5wcm90bzogRm9vLmZvbzogT1RIRVI6IEZpZWxkRGVzY3JpcHRvclByb3RvLm9uZW9mX2luZGV4IDEgaXMgb3V0IG9mICIKKyAgICAgICJyYW5nZSBmb3IgdHlwZSBcIkZvb1wiLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBGaWVsZE9uZW9mSW5kZXhOZWdhdGl2ZSkgeworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJGb29cIiIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJmb29cIiBudW1iZXI6MSBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgIgorICAgICIgICAgICAgICAgb25lb2ZfaW5kZXg6IC0xIH0iCisgICAgIiAgZmllbGQgeyBuYW1lOlwiZHVtbXlcIiBudW1iZXI6MiBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgIgorICAgICIgICAgICAgICAgb25lb2ZfaW5kZXg6IDAgfSIKKyAgICAiICBvbmVvZl9kZWNsIHsgbmFtZTpcImJhclwiIH0iCisgICAgIn0iLAorCisgICAgImZvby5wcm90bzogRm9vLmZvbzogT1RIRVI6IEZpZWxkRGVzY3JpcHRvclByb3RvLm9uZW9mX2luZGV4IC0xIGlzIG91dCBvZiAiCisgICAgICAicmFuZ2UgZm9yIHR5cGUgXCJGb29cIi5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgT25lb2ZGaWVsZHNDb25zZWN1dGl2ZURlZmluaXRpb24pIHsKKyAgLy8gRmllbGRzIGJlbG9uZ2luZyB0byB0aGUgc2FtZSBvbmVvZiBtdXN0IGJlIGRlZmluZWQgY29uc2VjdXRpdmVseS4KKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAgICIgIG5hbWU6IFwiRm9vXCIiCisgICAgICAiICBmaWVsZCB7IG5hbWU6XCJmb28xXCIgbnVtYmVyOiAxIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiAiCisgICAgICAiICAgICAgICAgIG9uZW9mX2luZGV4OiAwIH0iCisgICAgICAiICBmaWVsZCB7IG5hbWU6XCJiYXJcIiBudW1iZXI6IDIgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZTpUWVBFX0lOVDMyIH0iCisgICAgICAiICBmaWVsZCB7IG5hbWU6XCJmb28yXCIgbnVtYmVyOiAzIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiAiCisgICAgICAiICAgICAgICAgIG9uZW9mX2luZGV4OiAwIH0iCisgICAgICAiICBvbmVvZl9kZWNsIHsgbmFtZTpcImZvb3NcIiB9IgorICAgICAgIn0iLAorCisgICAgICAiZm9vLnByb3RvOiBGb28uYmFyOiBPVEhFUjogRmllbGRzIGluIHRoZSBzYW1lIG9uZW9mIG11c3QgYmUgZGVmaW5lZCAiCisgICAgICAiY29uc2VjdXRpdmVseS4gXCJiYXJcIiBjYW5ub3QgYmUgZGVmaW5lZCBiZWZvcmUgdGhlIGNvbXBsZXRpb24gb2YgdGhlICIKKyAgICAgICJcImZvb3NcIiBvbmVvZiBkZWZpbml0aW9uLlxuIik7CisKKyAgLy8gUHJldmVudCBpbnRlcmxlYXZlZCBmaWVsZHMsIHdoaWNoIGJlbG9uZyB0byBkaWZmZXJlbnQgb25lb2ZzLgorICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICAgIm5hbWU6IFwiZm9vMi5wcm90b1wiICIKKyAgICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAgICIgIG5hbWU6IFwiRm9vMlwiIgorICAgICAgIiAgZmllbGQgeyBuYW1lOlwiZm9vMVwiIG51bWJlcjogMSBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgIgorICAgICAgIiAgICAgICAgICBvbmVvZl9pbmRleDogMCB9IgorICAgICAgIiAgZmllbGQgeyBuYW1lOlwiYmFyMVwiIG51bWJlcjogMiBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgIgorICAgICAgIiAgICAgICAgICBvbmVvZl9pbmRleDogMSB9IgorICAgICAgIiAgZmllbGQgeyBuYW1lOlwiZm9vMlwiIG51bWJlcjogMyBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgIgorICAgICAgIiAgICAgICAgICBvbmVvZl9pbmRleDogMCB9IgorICAgICAgIiAgZmllbGQgeyBuYW1lOlwiYmFyMlwiIG51bWJlcjogNCBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgIgorICAgICAgIiAgICAgICAgICBvbmVvZl9pbmRleDogMSB9IgorICAgICAgIiAgb25lb2ZfZGVjbCB7IG5hbWU6XCJmb29zXCIgfSIKKyAgICAgICIgIG9uZW9mX2RlY2wgeyBuYW1lOlwiYmFyc1wiIH0iCisgICAgICAifSIsCisgICAgICAiZm9vMi5wcm90bzogRm9vMi5iYXIxOiBPVEhFUjogRmllbGRzIGluIHRoZSBzYW1lIG9uZW9mIG11c3QgYmUgZGVmaW5lZCAiCisgICAgICAiY29uc2VjdXRpdmVseS4gXCJiYXIxXCIgY2Fubm90IGJlIGRlZmluZWQgYmVmb3JlIHRoZSBjb21wbGV0aW9uIG9mIHRoZSAiCisgICAgICAiXCJmb29zXCIgb25lb2YgZGVmaW5pdGlvbi5cbiIKKyAgICAgICJmb28yLnByb3RvOiBGb28yLmZvbzI6IE9USEVSOiBGaWVsZHMgaW4gdGhlIHNhbWUgb25lb2YgbXVzdCBiZSBkZWZpbmVkICIKKyAgICAgICJjb25zZWN1dGl2ZWx5LiBcImZvbzJcIiBjYW5ub3QgYmUgZGVmaW5lZCBiZWZvcmUgdGhlIGNvbXBsZXRpb24gb2YgdGhlICIKKyAgICAgICJcImJhcnNcIiBvbmVvZiBkZWZpbml0aW9uLlxuIik7CisKKyAgLy8gQW5vdGhlciBjYXNlIGZvciBub3JtYWwgZmllbGRzIGFuZCBkaWZmZXJlbnQgb25lb2YgZmllbGRzIGludGVybGVhdmUuCisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgICAibmFtZTogXCJmb28zLnByb3RvXCIgIgorICAgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICAgIiAgbmFtZTogXCJGb28zXCIiCisgICAgICAiICBmaWVsZCB7IG5hbWU6XCJmb28xXCIgbnVtYmVyOiAxIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiAiCisgICAgICAiICAgICAgICAgIG9uZW9mX2luZGV4OiAwIH0iCisgICAgICAiICBmaWVsZCB7IG5hbWU6XCJiYXIxXCIgbnVtYmVyOiAyIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiAiCisgICAgICAiICAgICAgICAgIG9uZW9mX2luZGV4OiAxIH0iCisgICAgICAiICBmaWVsZCB7IG5hbWU6XCJiYXpcIiBudW1iZXI6IDMgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZTpUWVBFX0lOVDMyIH0iCisgICAgICAiICBmaWVsZCB7IG5hbWU6XCJmb28yXCIgbnVtYmVyOiA0IGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiAiCisgICAgICAiICAgICAgICAgIG9uZW9mX2luZGV4OiAwIH0iCisgICAgICAiICBvbmVvZl9kZWNsIHsgbmFtZTpcImZvb3NcIiB9IgorICAgICAgIiAgb25lb2ZfZGVjbCB7IG5hbWU6XCJiYXJzXCIgfSIKKyAgICAgICJ9IiwKKyAgICAgICJmb28zLnByb3RvOiBGb28zLmJhejogT1RIRVI6IEZpZWxkcyBpbiB0aGUgc2FtZSBvbmVvZiBtdXN0IGJlIGRlZmluZWQgIgorICAgICAgImNvbnNlY3V0aXZlbHkuIFwiYmF6XCIgY2Fubm90IGJlIGRlZmluZWQgYmVmb3JlIHRoZSBjb21wbGV0aW9uIG9mIHRoZSAiCisgICAgICAiXCJmb29zXCIgb25lb2YgZGVmaW5pdGlvbi5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgRmllbGROdW1iZXJDb25mbGljdCkgeworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJGb29cIiIKKyAgICAiICBmaWVsZCB7IG5hbWU6IFwiZm9vXCIgbnVtYmVyOiAxIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiB9IgorICAgICIgIGZpZWxkIHsgbmFtZTogXCJiYXJcIiBudW1iZXI6IDEgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZTpUWVBFX0lOVDMyIH0iCisgICAgIn0iLAorCisgICAgImZvby5wcm90bzogRm9vLmJhcjogTlVNQkVSOiBGaWVsZCBudW1iZXIgMSBoYXMgYWxyZWFkeSBiZWVuIHVzZWQgaW4gIgorICAgICAgIlwiRm9vXCIgYnkgZmllbGQgXCJmb29cIi5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgQmFkTWVzc2FnZVNldEV4dGVuc2lvblR5cGUpIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiTWVzc2FnZVNldFwiIgorICAgICIgIG9wdGlvbnMgeyBtZXNzYWdlX3NldF93aXJlX2Zvcm1hdDogdHJ1ZSB9IgorICAgICIgIGV4dGVuc2lvbl9yYW5nZSB7IHN0YXJ0OiA0IGVuZDogNSB9IgorICAgICJ9IgorICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIkZvb1wiIgorICAgICIgIGV4dGVuc2lvbiB7IG5hbWU6XCJmb29cIiBudW1iZXI6NCBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIiCisgICAgIiAgICAgICAgICAgICAgZXh0ZW5kZWU6IFwiTWVzc2FnZVNldFwiIH0iCisgICAgIn0iLAorCisgICAgImZvby5wcm90bzogRm9vLmZvbzogVFlQRTogRXh0ZW5zaW9ucyBvZiBNZXNzYWdlU2V0cyBtdXN0IGJlIG9wdGlvbmFsICIKKyAgICAgICJtZXNzYWdlcy5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgQmFkTWVzc2FnZVNldEV4dGVuc2lvbkxhYmVsKSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIk1lc3NhZ2VTZXRcIiIKKyAgICAiICBvcHRpb25zIHsgbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQ6IHRydWUgfSIKKyAgICAiICBleHRlbnNpb25fcmFuZ2UgeyBzdGFydDogNCBlbmQ6IDUgfSIKKyAgICAifSIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJGb29cIiIKKyAgICAiICBleHRlbnNpb24geyBuYW1lOlwiZm9vXCIgbnVtYmVyOjQgbGFiZWw6TEFCRUxfUkVQRUFURUQgdHlwZTpUWVBFX01FU1NBR0UiCisgICAgIiAgICAgICAgICAgICAgdHlwZV9uYW1lOiBcIkZvb1wiIGV4dGVuZGVlOiBcIk1lc3NhZ2VTZXRcIiB9IgorICAgICJ9IiwKKworICAgICJmb28ucHJvdG86IEZvby5mb286IFRZUEU6IEV4dGVuc2lvbnMgb2YgTWVzc2FnZVNldHMgbXVzdCBiZSBvcHRpb25hbCAiCisgICAgICAibWVzc2FnZXMuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIEZpZWxkSW5NZXNzYWdlU2V0KSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIkZvb1wiIgorICAgICIgIG9wdGlvbnMgeyBtZXNzYWdlX3NldF93aXJlX2Zvcm1hdDogdHJ1ZSB9IgorICAgICIgIGZpZWxkIHsgbmFtZTogXCJmb29cIiBudW1iZXI6IDEgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZTpUWVBFX0lOVDMyIH0iCisgICAgIn0iLAorCisgICAgImZvby5wcm90bzogRm9vLmZvbzogTkFNRTogTWVzc2FnZVNldHMgY2Fubm90IGhhdmUgZmllbGRzLCBvbmx5ICIKKyAgICAgICJleHRlbnNpb25zLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBOZWdhdGl2ZUV4dGVuc2lvblJhbmdlTnVtYmVyKSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIkZvb1wiIgorICAgICIgIGV4dGVuc2lvbl9yYW5nZSB7IHN0YXJ0OiAtMTAgZW5kOiAtMSB9IgorICAgICJ9IiwKKworICAgICJmb28ucHJvdG86IEZvbzogTlVNQkVSOiBFeHRlbnNpb24gbnVtYmVycyBtdXN0IGJlIHBvc2l0aXZlIGludGVnZXJzLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBIdWdlRXh0ZW5zaW9uUmFuZ2VOdW1iZXIpIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiRm9vXCIiCisgICAgIiAgZXh0ZW5zaW9uX3JhbmdlIHsgc3RhcnQ6IDEgZW5kOiAweDcwMDAwMDAwIH0iCisgICAgIn0iLAorCisgICAgImZvby5wcm90bzogRm9vOiBOVU1CRVI6IEV4dGVuc2lvbiBudW1iZXJzIGNhbm5vdCBiZSBncmVhdGVyIHRoYW4gIgorICAgICAgIjUzNjg3MDkxMS5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgRXh0ZW5zaW9uUmFuZ2VFbmRCZWZvcmVTdGFydCkgeworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJGb29cIiIKKyAgICAiICBleHRlbnNpb25fcmFuZ2UgeyBzdGFydDogMTAgZW5kOiAxMCB9IgorICAgICIgIGV4dGVuc2lvbl9yYW5nZSB7IHN0YXJ0OiAxMCBlbmQ6IDUgfSIKKyAgICAifSIsCisKKyAgICAiZm9vLnByb3RvOiBGb286IE5VTUJFUjogRXh0ZW5zaW9uIHJhbmdlIGVuZCBudW1iZXIgbXVzdCBiZSBncmVhdGVyIHRoYW4gIgorICAgICAgInN0YXJ0IG51bWJlci5cbiIKKyAgICAiZm9vLnByb3RvOiBGb286IE5VTUJFUjogRXh0ZW5zaW9uIHJhbmdlIGVuZCBudW1iZXIgbXVzdCBiZSBncmVhdGVyIHRoYW4gIgorICAgICAgInN0YXJ0IG51bWJlci5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgRW1wdHlFbnVtKSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJlbnVtX3R5cGUgeyBuYW1lOiBcIkZvb1wiIH0iCisgICAgLy8gQWxzbyB1c2UgdGhlIGVtcHR5IGVudW0gaW4gYSBtZXNzYWdlIHRvIG1ha2Ugc3VyZSB0aGVyZSBhcmUgbm8gY3Jhc2hlcworICAgIC8vIGR1cmluZyB2YWxpZGF0aW9uIChwb3NzaWJsZSBpZiB0aGUgY29kZSBhdHRlbXB0cyB0byBkZXJpdmUgYSBkZWZhdWx0CisgICAgLy8gdmFsdWUgZm9yIHRoZSBmaWVsZCkuCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiQmFyXCIiCisgICAgIiAgZmllbGQgeyBuYW1lOiBcImZvb1wiIG51bWJlcjogMSBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlX25hbWU6XCJGb29cIiB9IgorICAgICIgIGZpZWxkIHsgbmFtZTogXCJiYXJcIiBudW1iZXI6IDIgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZV9uYW1lOlwiRm9vXCIgIgorICAgICIgICAgICAgICAgZGVmYXVsdF92YWx1ZTogXCJOT19TVUNIX1ZBTFVFXCIgfSIKKyAgICAifSIsCisKKyAgICAiZm9vLnByb3RvOiBGb286IE5BTUU6IEVudW1zIG11c3QgY29udGFpbiBhdCBsZWFzdCBvbmUgdmFsdWUuXG4iCisgICAgImZvby5wcm90bzogQmFyLmJhcjogREVGQVVMVF9WQUxVRTogRW51bSB0eXBlIFwiRm9vXCIgaGFzIG5vIHZhbHVlIG5hbWVkICIKKyAgICAgICJcIk5PX1NVQ0hfVkFMVUVcIi5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgVW5kZWZpbmVkRXh0ZW5kZWUpIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiRm9vXCIiCisgICAgIiAgZXh0ZW5zaW9uIHsgbmFtZTpcImZvb1wiIG51bWJlcjoxIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiIKKyAgICAiICAgICAgICAgICAgICBleHRlbmRlZTogXCJCYXJcIiB9IgorICAgICJ9IiwKKworICAgICJmb28ucHJvdG86IEZvby5mb286IEVYVEVOREVFOiBcIkJhclwiIGlzIG5vdCBkZWZpbmVkLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBOb25NZXNzYWdlRXh0ZW5kZWUpIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgImVudW1fdHlwZSB7IG5hbWU6IFwiQmFyXCIgdmFsdWUgeyBuYW1lOlwiRFVNTVlcIiBudW1iZXI6MCB9IH0iCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiRm9vXCIiCisgICAgIiAgZXh0ZW5zaW9uIHsgbmFtZTpcImZvb1wiIG51bWJlcjoxIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiIKKyAgICAiICAgICAgICAgICAgICBleHRlbmRlZTogXCJCYXJcIiB9IgorICAgICJ9IiwKKworICAgICJmb28ucHJvdG86IEZvby5mb286IEVYVEVOREVFOiBcIkJhclwiIGlzIG5vdCBhIG1lc3NhZ2UgdHlwZS5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgTm90QW5FeHRlbnNpb25OdW1iZXIpIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiQmFyXCIiCisgICAgIn0iCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiRm9vXCIiCisgICAgIiAgZXh0ZW5zaW9uIHsgbmFtZTpcImZvb1wiIG51bWJlcjoxIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiIKKyAgICAiICAgICAgICAgICAgICBleHRlbmRlZTogXCJCYXJcIiB9IgorICAgICJ9IiwKKworICAgICJmb28ucHJvdG86IEZvby5mb286IE5VTUJFUjogXCJCYXJcIiBkb2VzIG5vdCBkZWNsYXJlIDEgYXMgYW4gZXh0ZW5zaW9uICIKKyAgICAgICJudW1iZXIuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIFJlcXVpcmVkRXh0ZW5zaW9uKSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIkJhclwiIgorICAgICIgIGV4dGVuc2lvbl9yYW5nZSB7IHN0YXJ0OiAxMDAwIGVuZDogMTAwMDAgfSIKKyAgICAifSIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJGb29cIiIKKyAgICAiICBleHRlbnNpb24geyIKKyAgICAiICAgIG5hbWU6XCJmb29cIiIKKyAgICAiICAgIG51bWJlcjoxMDAwIgorICAgICIgICAgbGFiZWw6TEFCRUxfUkVRVUlSRUQiCisgICAgIiAgICB0eXBlOlRZUEVfSU5UMzIiCisgICAgIiAgICBleHRlbmRlZTogXCJCYXJcIiIKKyAgICAiICB9IgorICAgICJ9IiwKKworICAgICJmb28ucHJvdG86IEZvby5mb286IFRZUEU6IE1lc3NhZ2UgZXh0ZW5zaW9ucyBjYW5ub3QgaGF2ZSByZXF1aXJlZCAiCisgICAgImZpZWxkcy5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgVW5kZWZpbmVkRmllbGRUeXBlKSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIkZvb1wiIgorICAgICIgIGZpZWxkIHsgbmFtZTpcImZvb1wiIG51bWJlcjoxIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGVfbmFtZTpcIkJhclwiIH0iCisgICAgIn0iLAorCisgICAgImZvby5wcm90bzogRm9vLmZvbzogVFlQRTogXCJCYXJcIiBpcyBub3QgZGVmaW5lZC5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgVW5kZWZpbmVkRmllbGRUeXBlV2l0aERlZmF1bHQpIHsKKyAgLy8gU2VlIGIvMTI1MzM1ODIuIFByZXZpb3VzbHkgdGhpcyBmYWlsZWQgYmVjYXVzZSB0aGUgZGVmYXVsdCB2YWx1ZSB3YXMgbm90CisgIC8vIGFjY2VwdGVkIGJ5IHRoZSBwYXJzZXIsIHdoaWNoIGFzc3VtZWQgYW4gZW51bSB0eXBlLCBsZWFkaW5nIHRvIGFuIHVuY2xlYXIKKyAgLy8gZXJyb3IgbWVzc2FnZS4gV2Ugd2FudCB0aGlzIGlucHV0IHRvIHlpZWxkIGEgdmFsaWRhdGlvbiBlcnJvciBpbnN0ZWFkLAorICAvLyBzaW5jZSB0aGUgdW5rbm93biB0eXBlIGlzIHRoZSBwcmltYXJ5IHByb2JsZW0uCisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIkZvb1wiIgorICAgICIgIGZpZWxkIHsgbmFtZTpcImZvb1wiIG51bWJlcjoxIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGVfbmFtZTpcImludFwiICIKKyAgICAiICAgICAgICAgIGRlZmF1bHRfdmFsdWU6XCIxXCIgfSIKKyAgICAifSIsCisKKyAgICAiZm9vLnByb3RvOiBGb28uZm9vOiBUWVBFOiBcImludFwiIGlzIG5vdCBkZWZpbmVkLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBVbmRlZmluZWROZXN0ZWRGaWVsZFR5cGUpIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiRm9vXCIiCisgICAgIiAgbmVzdGVkX3R5cGUgeyBuYW1lOlwiQmF6XCIgfSIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJmb29cIiBudW1iZXI6MSIKKyAgICAiICAgICAgICAgIGxhYmVsOkxBQkVMX09QVElPTkFMIgorICAgICIgICAgICAgICAgdHlwZV9uYW1lOlwiRm9vLkJhei5CYXJcIiB9IgorICAgICJ9IiwKKworICAgICJmb28ucHJvdG86IEZvby5mb286IFRZUEU6IFwiRm9vLkJhei5CYXJcIiBpcyBub3QgZGVmaW5lZC5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgRmllbGRUeXBlRGVmaW5lZEluVW5kZWNsYXJlZERlcGVuZGVuY3kpIHsKKyAgQnVpbGRGaWxlKAorICAgICJuYW1lOiBcImJhci5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsgbmFtZTogXCJCYXJcIiB9ICIpOworCisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIkZvb1wiIgorICAgICIgIGZpZWxkIHsgbmFtZTpcImZvb1wiIG51bWJlcjoxIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGVfbmFtZTpcIkJhclwiIH0iCisgICAgIn0iLAorICAgICJmb28ucHJvdG86IEZvby5mb286IFRZUEU6IFwiQmFyXCIgc2VlbXMgdG8gYmUgZGVmaW5lZCBpbiBcImJhci5wcm90b1wiLCAiCisgICAgICAid2hpY2ggaXMgbm90IGltcG9ydGVkIGJ5IFwiZm9vLnByb3RvXCIuICBUbyB1c2UgaXQgaGVyZSwgcGxlYXNlIGFkZCB0aGUgIgorICAgICAgIm5lY2Vzc2FyeSBpbXBvcnQuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIEZpZWxkVHlwZURlZmluZWRJbkluZGlyZWN0RGVwZW5kZW5jeSkgeworICAvLyBUZXN0IGZvciBoaWRkZW4gZGVwZW5kZW5jaWVzLgorICAvLworICAvLyAvLyBiYXIucHJvdG8KKyAgLy8gbWVzc2FnZSBCYXJ7fQorICAvLworICAvLyAvLyBmb3J3YXJkLnByb3RvCisgIC8vIGltcG9ydCAiYmFyLnByb3RvIgorICAvLworICAvLyAvLyBmb28ucHJvdG8KKyAgLy8gaW1wb3J0ICJmb3J3YXJkLnByb3RvIgorICAvLyBtZXNzYWdlIEZvbyB7CisgIC8vICAgb3B0aW9uYWwgQmFyIGZvbyA9IDE7ICAvLyBFcnJvciwgbmVlZHMgdG8gaW1wb3J0IGJhci5wcm90byBleHBsaWNpdGx5LgorICAvLyB9CisgIC8vCisgIEJ1aWxkRmlsZSgKKyAgICAibmFtZTogXCJiYXIucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IG5hbWU6IFwiQmFyXCIgfSIpOworCisgIEJ1aWxkRmlsZSgKKyAgICAibmFtZTogXCJmb3J3YXJkLnByb3RvXCIiCisgICAgImRlcGVuZGVuY3k6IFwiYmFyLnByb3RvXCIiKTsKKworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAiZGVwZW5kZW5jeTogXCJmb3J3YXJkLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIkZvb1wiIgorICAgICIgIGZpZWxkIHsgbmFtZTpcImZvb1wiIG51bWJlcjoxIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGVfbmFtZTpcIkJhclwiIH0iCisgICAgIn0iLAorICAgICJmb28ucHJvdG86IEZvby5mb286IFRZUEU6IFwiQmFyXCIgc2VlbXMgdG8gYmUgZGVmaW5lZCBpbiBcImJhci5wcm90b1wiLCAiCisgICAgICAid2hpY2ggaXMgbm90IGltcG9ydGVkIGJ5IFwiZm9vLnByb3RvXCIuICBUbyB1c2UgaXQgaGVyZSwgcGxlYXNlIGFkZCB0aGUgIgorICAgICAgIm5lY2Vzc2FyeSBpbXBvcnQuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIEZpZWxkVHlwZURlZmluZWRJblB1YmxpY0RlcGVuZGVuY3kpIHsKKyAgLy8gVGVzdCBmb3IgcHVibGljIGRlcGVuZGVuY2llcy4KKyAgLy8KKyAgLy8gLy8gYmFyLnByb3RvCisgIC8vIG1lc3NhZ2UgQmFye30KKyAgLy8KKyAgLy8gLy8gZm9yd2FyZC5wcm90bworICAvLyBpbXBvcnQgcHVibGljICJiYXIucHJvdG8iCisgIC8vCisgIC8vIC8vIGZvby5wcm90bworICAvLyBpbXBvcnQgImZvcndhcmQucHJvdG8iCisgIC8vIG1lc3NhZ2UgRm9vIHsKKyAgLy8gICBvcHRpb25hbCBCYXIgZm9vID0gMTsgIC8vIENvcnJlY3QuICJiYXIucHJvdG8iIGlzIHB1YmxpYyBpbXBvcnRlZCBpbnRvCisgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBmb3J3YXJkLnByb3RvLCBzbyB3aGVuICJmb28ucHJvdG8iIGltcG9ydHMKKyAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgIC8vICJmb3J3YXJkLnByb3RvIiwgaXQgaW1wb3J0cyAiYmFyLnByb3RvIiB0b28uCisgIC8vIH0KKyAgLy8KKyAgQnVpbGRGaWxlKAorICAgICJuYW1lOiBcImJhci5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsgbmFtZTogXCJCYXJcIiB9Iik7CisKKyAgQnVpbGRGaWxlKAorICAgICJuYW1lOiBcImZvcndhcmQucHJvdG9cIiIKKyAgICAiZGVwZW5kZW5jeTogXCJiYXIucHJvdG9cIiAiCisgICAgInB1YmxpY19kZXBlbmRlbmN5OiAwIik7CisKKyAgQnVpbGRGaWxlKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAiZGVwZW5kZW5jeTogXCJmb3J3YXJkLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIkZvb1wiIgorICAgICIgIGZpZWxkIHsgbmFtZTpcImZvb1wiIG51bWJlcjoxIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGVfbmFtZTpcIkJhclwiIH0iCisgICAgIn0iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIEZpZWxkVHlwZURlZmluZWRJblRyYW5zaXRpdmVQdWJsaWNEZXBlbmRlbmN5KSB7CisgIC8vIFRlc3QgZm9yIHB1YmxpYyBkZXBlbmRlbmNpZXMuCisgIC8vCisgIC8vIC8vIGJhci5wcm90bworICAvLyBtZXNzYWdlIEJhcnt9CisgIC8vCisgIC8vIC8vIGZvcndhcmQucHJvdG8KKyAgLy8gaW1wb3J0IHB1YmxpYyAiYmFyLnByb3RvIgorICAvLworICAvLyAvLyBmb3J3YXJkMi5wcm90bworICAvLyBpbXBvcnQgcHVibGljICJmb3J3YXJkLnByb3RvIgorICAvLworICAvLyAvLyBmb28ucHJvdG8KKyAgLy8gaW1wb3J0ICJmb3J3YXJkMi5wcm90byIKKyAgLy8gbWVzc2FnZSBGb28geworICAvLyAgIG9wdGlvbmFsIEJhciBmb28gPSAxOyAgLy8gQ29ycmVjdCwgcHVibGljIGltcG9ydHMgYXJlIHRyYW5zaXRpdmUuCisgIC8vIH0KKyAgLy8KKyAgQnVpbGRGaWxlKAorICAgICJuYW1lOiBcImJhci5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsgbmFtZTogXCJCYXJcIiB9Iik7CisKKyAgQnVpbGRGaWxlKAorICAgICJuYW1lOiBcImZvcndhcmQucHJvdG9cIiIKKyAgICAiZGVwZW5kZW5jeTogXCJiYXIucHJvdG9cIiAiCisgICAgInB1YmxpY19kZXBlbmRlbmN5OiAwIik7CisKKyAgQnVpbGRGaWxlKAorICAgICJuYW1lOiBcImZvcndhcmQyLnByb3RvXCIiCisgICAgImRlcGVuZGVuY3k6IFwiZm9yd2FyZC5wcm90b1wiICIKKyAgICAicHVibGljX2RlcGVuZGVuY3k6IDAiKTsKKworICBCdWlsZEZpbGUoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJkZXBlbmRlbmN5OiBcImZvcndhcmQyLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIkZvb1wiIgorICAgICIgIGZpZWxkIHsgbmFtZTpcImZvb1wiIG51bWJlcjoxIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGVfbmFtZTpcIkJhclwiIH0iCisgICAgIn0iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsCisgICAgICAgRmllbGRUeXBlRGVmaW5lZEluUHJpdmF0ZURlcGVuZGVuY3lPZlB1YmxpY0RlcGVuZGVuY3kpIHsKKyAgLy8gVGVzdCBmb3IgcHVibGljIGRlcGVuZGVuY2llcy4KKyAgLy8KKyAgLy8gLy8gYmFyLnByb3RvCisgIC8vIG1lc3NhZ2UgQmFye30KKyAgLy8KKyAgLy8gLy8gZm9yd2FyZC5wcm90bworICAvLyBpbXBvcnQgImJhci5wcm90byIKKyAgLy8KKyAgLy8gLy8gZm9yd2FyZDIucHJvdG8KKyAgLy8gaW1wb3J0IHB1YmxpYyAiZm9yd2FyZC5wcm90byIKKyAgLy8KKyAgLy8gLy8gZm9vLnByb3RvCisgIC8vIGltcG9ydCAiZm9yd2FyZDIucHJvdG8iCisgIC8vIG1lc3NhZ2UgRm9vIHsKKyAgLy8gICBvcHRpb25hbCBCYXIgZm9vID0gMTsgIC8vIEVycm9yLCB0aGUgImJhci5wcm90byIgaXMgbm90IHB1YmxpYyBpbXBvcnRlZAorICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaW50byAiZm9yd2FyZC5wcm90byIsIHNvIHdpbGwgbm90IGJlIGltcG9ydGVkCisgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpbnRvIGVpdGhlciAiZm9yd2FyZDIucHJvdG8iIG9yICJmb28ucHJvdG8iLgorICAvLyB9CisgIC8vCisgIEJ1aWxkRmlsZSgKKyAgICAibmFtZTogXCJiYXIucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IG5hbWU6IFwiQmFyXCIgfSIpOworCisgIEJ1aWxkRmlsZSgKKyAgICAibmFtZTogXCJmb3J3YXJkLnByb3RvXCIiCisgICAgImRlcGVuZGVuY3k6IFwiYmFyLnByb3RvXCIiKTsKKworICBCdWlsZEZpbGUoCisgICAgIm5hbWU6IFwiZm9yd2FyZDIucHJvdG9cIiIKKyAgICAiZGVwZW5kZW5jeTogXCJmb3J3YXJkLnByb3RvXCIgIgorICAgICJwdWJsaWNfZGVwZW5kZW5jeTogMCIpOworCisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJkZXBlbmRlbmN5OiBcImZvcndhcmQyLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIkZvb1wiIgorICAgICIgIGZpZWxkIHsgbmFtZTpcImZvb1wiIG51bWJlcjoxIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGVfbmFtZTpcIkJhclwiIH0iCisgICAgIn0iLAorICAgICJmb28ucHJvdG86IEZvby5mb286IFRZUEU6IFwiQmFyXCIgc2VlbXMgdG8gYmUgZGVmaW5lZCBpbiBcImJhci5wcm90b1wiLCAiCisgICAgICAid2hpY2ggaXMgbm90IGltcG9ydGVkIGJ5IFwiZm9vLnByb3RvXCIuICBUbyB1c2UgaXQgaGVyZSwgcGxlYXNlIGFkZCB0aGUgIgorICAgICAgIm5lY2Vzc2FyeSBpbXBvcnQuXG4iKTsKK30KKworCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgU2VhcmNoTW9zdExvY2FsRmlyc3QpIHsKKyAgLy8gVGhlIGZvbGxvd2luZyBzaG91bGQgcHJvZHVjZSBhbiBlcnJvciB0aGF0IEJhci5CYXogaXMgcmVzb2x2ZWQgYnV0CisgIC8vIG5vdCBkZWZpbmVkOgorICAvLyAgIG1lc3NhZ2UgQmFyIHsgbWVzc2FnZSBCYXoge30gfQorICAvLyAgIG1lc3NhZ2UgRm9vIHsKKyAgLy8gICAgIG1lc3NhZ2UgQmFyIHsKKyAgLy8gICAgICAgLy8gUGxhY2luZyAibWVzc2FnZSBCYXp7fSIgaGVyZSwgb3IgcmVtb3ZpbmcgRm9vLkJhciBhbHRvZ2V0aGVyLAorICAvLyAgICAgICAvLyB3b3VsZCBmaXggdGhlIGVycm9yLgorICAvLyAgICAgfQorICAvLyAgICAgb3B0aW9uYWwgQmFyLkJheiBiYXogPSAxOworICAvLyAgIH0KKyAgLy8gQW4gb25lIHBvaW50IHRoZSBsb29rdXAgY29kZSBpbmNvcnJlY3RseSBkaWQgbm90IHByb2R1Y2UgYW4gZXJyb3IgaW4gdGhpcworICAvLyBjYXNlLCBiZWNhdXNlIHdoZW4gbG9va2luZyBmb3IgQmFyLkJheiwgaXQgd291bGQgdHJ5ICJGb28uQmFyLkJheiIgZmlyc3QsCisgIC8vIGZhaWwsIGFuZCB0ZW4gdHJ5ICJCYXIuQmF6IiBhbmQgc3VjY2VlZCwgZXZlbiB0aG91Z2ggIkJhciIgc2hvdWxkIGFjdHVhbGx5CisgIC8vIHJlZmVyIHRvIHRoZSBpbm5lciBCYXIsIG5vdCB0aGUgb3V0ZXIgb25lLgorICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJCYXJcIiIKKyAgICAiICBuZXN0ZWRfdHlwZSB7IG5hbWU6IFwiQmF6XCIgfSIKKyAgICAifSIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJGb29cIiIKKyAgICAiICBuZXN0ZWRfdHlwZSB7IG5hbWU6IFwiQmFyXCIgfSIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJiYXpcIiBudW1iZXI6MSBsYWJlbDpMQUJFTF9PUFRJT05BTCIKKyAgICAiICAgICAgICAgIHR5cGVfbmFtZTpcIkJhci5CYXpcIiB9IgorICAgICJ9IiwKKworICAgICJmb28ucHJvdG86IEZvby5iYXo6IFRZUEU6IFwiQmFyLkJhelwiIGlzIHJlc29sdmVkIHRvIFwiRm9vLkJhci5CYXpcIiwiCisgICAgIiB3aGljaCBpcyBub3QgZGVmaW5lZC4gVGhlIGlubmVybW9zdCBzY29wZSBpcyBzZWFyY2hlZCBmaXJzdCBpbiBuYW1lICIKKyAgICAicmVzb2x1dGlvbi4gQ29uc2lkZXIgdXNpbmcgYSBsZWFkaW5nICcuJyhpLmUuLCBcIi5CYXIuQmF6XCIpIHRvIHN0YXJ0ICIKKyAgICAiZnJvbSB0aGUgb3V0ZXJtb3N0IHNjb3BlLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBTZWFyY2hNb3N0TG9jYWxGaXJzdDIpIHsKKyAgLy8gVGhpcyB0ZXN0IHdvdWxkIGZpbmQgdGhlIG1vc3QgbG9jYWwgIkJhciIgZmlyc3QsIGFuZCBkb2VzLCBidXQKKyAgLy8gcHJvY2VlZHMgdG8gZmluZCB0aGUgb3V0ZXIgb25lIGJlY2F1c2UgdGhlIGlubmVyIG9uZSdzIG5vdCBhbgorICAvLyBhZ2dyZWdhdGUuCisgIEJ1aWxkRmlsZSgKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiQmFyXCIiCisgICAgIiAgbmVzdGVkX3R5cGUgeyBuYW1lOiBcIkJhelwiIH0iCisgICAgIn0iCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiRm9vXCIiCisgICAgIiAgZmllbGQgeyBuYW1lOiBcIkJhclwiIG51bWJlcjoxIHR5cGU6VFlQRV9CWVRFUyB9ICIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJiYXpcIiBudW1iZXI6MiBsYWJlbDpMQUJFTF9PUFRJT05BTCIKKyAgICAiICAgICAgICAgIHR5cGVfbmFtZTpcIkJhci5CYXpcIiB9IgorICAgICJ9Iik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBQYWNrYWdlT3JpZ2luYWxseURlY2xhcmVkSW5UcmFuc2l0aXZlRGVwZW5kZW50KSB7CisgIC8vIEltYWdpbmUgd2UgaGF2ZSB0aGUgZm9sbG93aW5nOgorICAvLworICAvLyBmb28ucHJvdG86CisgIC8vICAgcGFja2FnZSBmb28uYmFyOworICAvLyBiYXIucHJvdG86CisgIC8vICAgcGFja2FnZSBmb28uYmFyOworICAvLyAgIGltcG9ydCAiZm9vLnByb3RvIjsKKyAgLy8gICBtZXNzYWdlIEJhciB7fQorICAvLyBiYXoucHJvdG86CisgIC8vICAgcGFja2FnZSBmb287CisgIC8vICAgaW1wb3J0ICJiYXIucHJvdG8iCisgIC8vICAgbWVzc2FnZSBCYXogeyBvcHRpb25hbCBiYXIuQmFyIHF1eCA9IDE7IH0KKyAgLy8KKyAgLy8gV2hlbiB2YWxpZGF0aW5nIGJhei5wcm90bywgd2Ugd2lsbCBsb29rIHVwICJiYXIuQmFyIi4gIEFzIHBhcnQgb2YgdGhpcworICAvLyBsb29rdXAsIHdlIGZpcnN0IGxvb2t1cCAiYmFyIiB0aGVuIHRyeSB0byBmaW5kICJCYXIiIHdpdGhpbiBpdC4gICJiYXIiCisgIC8vIHNob3VsZCByZXNvbHZlIHRvICJmb28uYmFyIi4gIE5vdGUsIHRob3VnaCwgdGhhdCAiZm9vLmJhciIgd2FzIG9yaWdpbmFsbHkKKyAgLy8gZGVmaW5lZCBpbiBmb28ucHJvdG8sIHdoaWNoIGlzIG5vdCBhIGRpcmVjdCBkZXBlbmRlbmN5IG9mIGJhei5wcm90by4gIFRoZQorICAvLyBpbXBsZW1lbnRhdGlvbiBvZiBGaW5kU3ltYm9sKCkgbm9ybWFsbHkgb25seSByZXR1cm5zIHN5bWJvbHMgaW4gZGlyZWN0CisgIC8vIGRlcGVuZGVuY2llcywgbm90IGluZGlyZWN0IG9uZXMuICBUaGlzIHRlc3QgaW5zdXJlcyB0aGF0IHRoaXMgZG9lcyBub3QKKyAgLy8gcHJldmVudCBpdCBmcm9tIGZpbmRpbmcgImZvby5iYXIiLgorCisgIEJ1aWxkRmlsZSgKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgInBhY2thZ2U6IFwiZm9vLmJhclwiICIpOworICBCdWlsZEZpbGUoCisgICAgIm5hbWU6IFwiYmFyLnByb3RvXCIgIgorICAgICJwYWNrYWdlOiBcImZvby5iYXJcIiAiCisgICAgImRlcGVuZGVuY3k6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyBuYW1lOiBcIkJhclwiIH0iKTsKKyAgQnVpbGRGaWxlKAorICAgICJuYW1lOiBcImJhei5wcm90b1wiICIKKyAgICAicGFja2FnZTogXCJmb29cIiAiCisgICAgImRlcGVuZGVuY3k6IFwiYmFyLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyAiCisgICAgIiAgbmFtZTogXCJCYXpcIiAiCisgICAgIiAgZmllbGQgeyBuYW1lOlwicXV4XCIgbnVtYmVyOjEgbGFiZWw6TEFCRUxfT1BUSU9OQUwgIgorICAgICIgICAgICAgICAgdHlwZV9uYW1lOlwiYmFyLkJhclwiIH0iCisgICAgIn0iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIEZpZWxkVHlwZU5vdEFUeXBlKSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIkZvb1wiIgorICAgICIgIGZpZWxkIHsgbmFtZTpcImZvb1wiIG51bWJlcjoxIGxhYmVsOkxBQkVMX09QVElPTkFMICIKKyAgICAiICAgICAgICAgIHR5cGVfbmFtZTpcIi5Gb28uYmFyXCIgfSIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJiYXJcIiBudW1iZXI6MiBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgfSIKKyAgICAifSIsCisKKyAgICAiZm9vLnByb3RvOiBGb28uZm9vOiBUWVBFOiBcIi5Gb28uYmFyXCIgaXMgbm90IGEgdHlwZS5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgUmVsYXRpdmVGaWVsZFR5cGVOb3RBVHlwZSkgeworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmVzdGVkX3R5cGUgeyIKKyAgICAiICAgIG5hbWU6IFwiQmFyXCIiCisgICAgIiAgICBmaWVsZCB7IG5hbWU6XCJCYXpcIiBudW1iZXI6MiBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgfSIKKyAgICAiICB9IgorICAgICIgIG5hbWU6IFwiRm9vXCIiCisgICAgIiAgZmllbGQgeyBuYW1lOlwiZm9vXCIgbnVtYmVyOjEgbGFiZWw6TEFCRUxfT1BUSU9OQUwgIgorICAgICIgICAgICAgICAgdHlwZV9uYW1lOlwiQmFyLkJhelwiIH0iCisgICAgIn0iLAorICAgICJmb28ucHJvdG86IEZvby5mb286IFRZUEU6IFwiQmFyLkJhelwiIGlzIG5vdCBhIHR5cGUuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIEZpZWxkVHlwZU1heUJlSXRzTmFtZSkgeworICBCdWlsZEZpbGUoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIkJhclwiIgorICAgICJ9IgorICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIkZvb1wiIgorICAgICIgIGZpZWxkIHsgbmFtZTpcIkJhclwiIG51bWJlcjoxIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGVfbmFtZTpcIkJhclwiIH0iCisgICAgIn0iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIEVudW1GaWVsZFR5cGVJc01lc3NhZ2UpIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IG5hbWU6IFwiQmFyXCIgfSAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiRm9vXCIiCisgICAgIiAgZmllbGQgeyBuYW1lOlwiZm9vXCIgbnVtYmVyOjEgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZTpUWVBFX0VOVU0iCisgICAgIiAgICAgICAgICB0eXBlX25hbWU6XCJCYXJcIiB9IgorICAgICJ9IiwKKworICAgICJmb28ucHJvdG86IEZvby5mb286IFRZUEU6IFwiQmFyXCIgaXMgbm90IGFuIGVudW0gdHlwZS5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgTWVzc2FnZUZpZWxkVHlwZUlzRW51bSkgeworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAiZW51bV90eXBlIHsgbmFtZTogXCJCYXJcIiB2YWx1ZSB7IG5hbWU6XCJEVU1NWVwiIG51bWJlcjowIH0gfSAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiRm9vXCIiCisgICAgIiAgZmllbGQgeyBuYW1lOlwiZm9vXCIgbnVtYmVyOjEgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZTpUWVBFX01FU1NBR0UiCisgICAgIiAgICAgICAgICB0eXBlX25hbWU6XCJCYXJcIiB9IgorICAgICJ9IiwKKworICAgICJmb28ucHJvdG86IEZvby5mb286IFRZUEU6IFwiQmFyXCIgaXMgbm90IGEgbWVzc2FnZSB0eXBlLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBCYWRFbnVtRGVmYXVsdFZhbHVlKSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJlbnVtX3R5cGUgeyBuYW1lOiBcIkJhclwiIHZhbHVlIHsgbmFtZTpcIkRVTU1ZXCIgbnVtYmVyOjAgfSB9ICIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJGb29cIiIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJmb29cIiBudW1iZXI6MSBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlX25hbWU6XCJCYXJcIiIKKyAgICAiICAgICAgICAgIGRlZmF1bHRfdmFsdWU6XCJOT19TVUNIX1ZBTFVFXCIgfSIKKyAgICAifSIsCisKKyAgICAiZm9vLnByb3RvOiBGb28uZm9vOiBERUZBVUxUX1ZBTFVFOiBFbnVtIHR5cGUgXCJCYXJcIiBoYXMgbm8gdmFsdWUgbmFtZWQgIgorICAgICAgIlwiTk9fU1VDSF9WQUxVRVwiLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBFbnVtRGVmYXVsdFZhbHVlSXNJbnRlZ2VyKSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJlbnVtX3R5cGUgeyBuYW1lOiBcIkJhclwiIHZhbHVlIHsgbmFtZTpcIkRVTU1ZXCIgbnVtYmVyOjAgfSB9ICIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJGb29cIiIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJmb29cIiBudW1iZXI6MSBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlX25hbWU6XCJCYXJcIiIKKyAgICAiICAgICAgICAgIGRlZmF1bHRfdmFsdWU6XCIwXCIgfSIKKyAgICAifSIsCisKKyAgICAiZm9vLnByb3RvOiBGb28uZm9vOiBERUZBVUxUX1ZBTFVFOiBEZWZhdWx0IHZhbHVlIGZvciBhbiBlbnVtIGZpZWxkIG11c3QgIgorICAgICJiZSBhbiBpZGVudGlmaWVyLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBQcmltaXRpdmVXaXRoVHlwZU5hbWUpIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiRm9vXCIiCisgICAgIiAgZmllbGQgeyBuYW1lOlwiZm9vXCIgbnVtYmVyOjEgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZTpUWVBFX0lOVDMyIgorICAgICIgICAgICAgICAgdHlwZV9uYW1lOlwiRm9vXCIgfSIKKyAgICAifSIsCisKKyAgICAiZm9vLnByb3RvOiBGb28uZm9vOiBUWVBFOiBGaWVsZCB3aXRoIHByaW1pdGl2ZSB0eXBlIGhhcyB0eXBlX25hbWUuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIE5vblByaW1pdGl2ZVdpdGhvdXRUeXBlTmFtZSkgeworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJGb29cIiIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJmb29cIiBudW1iZXI6MSBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfTUVTU0FHRSB9IgorICAgICJ9IiwKKworICAgICJmb28ucHJvdG86IEZvby5mb286IFRZUEU6IEZpZWxkIHdpdGggbWVzc2FnZSBvciBlbnVtIHR5cGUgbWlzc2luZyAiCisgICAgICAidHlwZV9uYW1lLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBPbmVvZldpdGhOb0ZpZWxkcykgeworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJGb29cIiIKKyAgICAiICBvbmVvZl9kZWNsIHsgbmFtZTpcImJhclwiIH0iCisgICAgIn0iLAorCisgICAgImZvby5wcm90bzogRm9vLmJhcjogTkFNRTogT25lb2YgbXVzdCBoYXZlIGF0IGxlYXN0IG9uZSBmaWVsZC5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgT25lb2ZMYWJlbE1pc21hdGNoKSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIkZvb1wiIgorICAgICIgIGZpZWxkIHsgbmFtZTpcImZvb1wiIG51bWJlcjoxIGxhYmVsOkxBQkVMX1JFUEVBVEVEIHR5cGU6VFlQRV9JTlQzMiAiCisgICAgIiAgICAgICAgICBvbmVvZl9pbmRleDowIH0iCisgICAgIiAgb25lb2ZfZGVjbCB7IG5hbWU6XCJiYXJcIiB9IgorICAgICJ9IiwKKworICAgICJmb28ucHJvdG86IEZvby5mb286IE5BTUU6IEZpZWxkcyBvZiBvbmVvZnMgbXVzdCB0aGVtc2VsdmVzIGhhdmUgbGFiZWwgIgorICAgICAgIkxBQkVMX09QVElPTkFMLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBJbnB1dFR5cGVOb3REZWZpbmVkKSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyBuYW1lOiBcIkZvb1wiIH0gIgorICAgICJzZXJ2aWNlIHsiCisgICAgIiAgbmFtZTogXCJUZXN0U2VydmljZVwiIgorICAgICIgIG1ldGhvZCB7IG5hbWU6IFwiQVwiIGlucHV0X3R5cGU6IFwiQmFyXCIgb3V0cHV0X3R5cGU6IFwiRm9vXCIgfSIKKyAgICAifSIsCisKKyAgICAiZm9vLnByb3RvOiBUZXN0U2VydmljZS5BOiBJTlBVVF9UWVBFOiBcIkJhclwiIGlzIG5vdCBkZWZpbmVkLlxuIgorICAgICk7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBJbnB1dFR5cGVOb3RBTWVzc2FnZSkgeworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsgbmFtZTogXCJGb29cIiB9ICIKKyAgICAiZW51bV90eXBlIHsgbmFtZTogXCJCYXJcIiB2YWx1ZSB7IG5hbWU6XCJEVU1NWVwiIG51bWJlcjowIH0gfSAiCisgICAgInNlcnZpY2UgeyIKKyAgICAiICBuYW1lOiBcIlRlc3RTZXJ2aWNlXCIiCisgICAgIiAgbWV0aG9kIHsgbmFtZTogXCJBXCIgaW5wdXRfdHlwZTogXCJCYXJcIiBvdXRwdXRfdHlwZTogXCJGb29cIiB9IgorICAgICJ9IiwKKworICAgICJmb28ucHJvdG86IFRlc3RTZXJ2aWNlLkE6IElOUFVUX1RZUEU6IFwiQmFyXCIgaXMgbm90IGEgbWVzc2FnZSB0eXBlLlxuIgorICAgICk7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBPdXRwdXRUeXBlTm90RGVmaW5lZCkgeworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsgbmFtZTogXCJGb29cIiB9ICIKKyAgICAic2VydmljZSB7IgorICAgICIgIG5hbWU6IFwiVGVzdFNlcnZpY2VcIiIKKyAgICAiICBtZXRob2QgeyBuYW1lOiBcIkFcIiBpbnB1dF90eXBlOiBcIkZvb1wiIG91dHB1dF90eXBlOiBcIkJhclwiIH0iCisgICAgIn0iLAorCisgICAgImZvby5wcm90bzogVGVzdFNlcnZpY2UuQTogT1VUUFVUX1RZUEU6IFwiQmFyXCIgaXMgbm90IGRlZmluZWQuXG4iCisgICAgKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIE91dHB1dFR5cGVOb3RBTWVzc2FnZSkgeworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsgbmFtZTogXCJGb29cIiB9ICIKKyAgICAiZW51bV90eXBlIHsgbmFtZTogXCJCYXJcIiB2YWx1ZSB7IG5hbWU6XCJEVU1NWVwiIG51bWJlcjowIH0gfSAiCisgICAgInNlcnZpY2UgeyIKKyAgICAiICBuYW1lOiBcIlRlc3RTZXJ2aWNlXCIiCisgICAgIiAgbWV0aG9kIHsgbmFtZTogXCJBXCIgaW5wdXRfdHlwZTogXCJGb29cIiBvdXRwdXRfdHlwZTogXCJCYXJcIiB9IgorICAgICJ9IiwKKworICAgICJmb28ucHJvdG86IFRlc3RTZXJ2aWNlLkE6IE9VVFBVVF9UWVBFOiBcIkJhclwiIGlzIG5vdCBhIG1lc3NhZ2UgdHlwZS5cbiIKKyAgICApOworfQorCisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBJbGxlZ2FsUGFja2VkRmllbGQpIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7XG4iCisgICAgIiAgbmFtZTogXCJGb29cIiIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJwYWNrZWRfc3RyaW5nXCIgbnVtYmVyOjEgbGFiZWw6TEFCRUxfUkVQRUFURUQgIgorICAgICIgICAgICAgICAgdHlwZTpUWVBFX1NUUklORyAiCisgICAgIiAgICAgICAgICBvcHRpb25zIHsgdW5pbnRlcnByZXRlZF9vcHRpb24geyIKKyAgICAiICAgICAgICAgICAgbmFtZSB7IG5hbWVfcGFydDogXCJwYWNrZWRcIiBpc19leHRlbnNpb246IGZhbHNlIH0iCisgICAgIiAgICAgICAgICAgIGlkZW50aWZpZXJfdmFsdWU6IFwidHJ1ZVwiIH19fVxuIgorICAgICIgIGZpZWxkIHsgbmFtZTpcInBhY2tlZF9tZXNzYWdlXCIgbnVtYmVyOjMgbGFiZWw6TEFCRUxfUkVQRUFURUQgIgorICAgICIgICAgICAgICAgdHlwZV9uYW1lOiBcIkZvb1wiIgorICAgICIgICAgICAgICAgb3B0aW9ucyB7IHVuaW50ZXJwcmV0ZWRfb3B0aW9uIHsiCisgICAgIiAgICAgICAgICAgIG5hbWUgeyBuYW1lX3BhcnQ6IFwicGFja2VkXCIgaXNfZXh0ZW5zaW9uOiBmYWxzZSB9IgorICAgICIgICAgICAgICAgICBpZGVudGlmaWVyX3ZhbHVlOiBcInRydWVcIiB9fX1cbiIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJvcHRpb25hbF9pbnQzMlwiIG51bWJlcjogNCBsYWJlbDogTEFCRUxfT1BUSU9OQUwgIgorICAgICIgICAgICAgICAgdHlwZTpUWVBFX0lOVDMyICIKKyAgICAiICAgICAgICAgIG9wdGlvbnMgeyB1bmludGVycHJldGVkX29wdGlvbiB7IgorICAgICIgICAgICAgICAgICBuYW1lIHsgbmFtZV9wYXJ0OiBcInBhY2tlZFwiIGlzX2V4dGVuc2lvbjogZmFsc2UgfSIKKyAgICAiICAgICAgICAgICAgaWRlbnRpZmllcl92YWx1ZTogXCJ0cnVlXCIgfX19XG4iCisgICAgIn0iLAorCisgICAgImZvby5wcm90bzogRm9vLnBhY2tlZF9zdHJpbmc6IFRZUEU6IFtwYWNrZWQgPSB0cnVlXSBjYW4gb25seSBiZSAiCisgICAgICAgICJzcGVjaWZpZWQgZm9yIHJlcGVhdGVkIHByaW1pdGl2ZSBmaWVsZHMuXG4iCisgICAgImZvby5wcm90bzogRm9vLnBhY2tlZF9tZXNzYWdlOiBUWVBFOiBbcGFja2VkID0gdHJ1ZV0gY2FuIG9ubHkgYmUgIgorICAgICAgICAic3BlY2lmaWVkIGZvciByZXBlYXRlZCBwcmltaXRpdmUgZmllbGRzLlxuIgorICAgICJmb28ucHJvdG86IEZvby5vcHRpb25hbF9pbnQzMjogVFlQRTogW3BhY2tlZCA9IHRydWVdIGNhbiBvbmx5IGJlICIKKyAgICAgICAgInNwZWNpZmllZCBmb3IgcmVwZWF0ZWQgcHJpbWl0aXZlIGZpZWxkcy5cbiIKKyAgICAgICAgKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIE9wdGlvbldyb25nVHlwZSkgeworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAibWVzc2FnZV90eXBlIHsgIgorICAgICIgIG5hbWU6IFwiVGVzdE1lc3NhZ2VcIiAiCisgICAgIiAgZmllbGQgeyBuYW1lOlwiZm9vXCIgbnVtYmVyOjEgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZTpUWVBFX1NUUklORyAiCisgICAgIiAgICAgICAgICBvcHRpb25zIHsgdW5pbnRlcnByZXRlZF9vcHRpb24geyBuYW1lIHsgbmFtZV9wYXJ0OiBcImN0eXBlXCIgIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzX2V4dGVuc2lvbjogZmFsc2UgfSIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aXZlX2ludF92YWx1ZTogMSB9IgorICAgICIgICAgICAgICAgfSIKKyAgICAiICB9IgorICAgICJ9XG4iLAorCisgICAgImZvby5wcm90bzogVGVzdE1lc3NhZ2UuZm9vOiBPUFRJT05fVkFMVUU6IFZhbHVlIG11c3QgYmUgaWRlbnRpZmllciBmb3IgIgorICAgICJlbnVtLXZhbHVlZCBvcHRpb24gXCJnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLmN0eXBlXCIuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIE9wdGlvbkV4dGVuZHNBdG9taWNUeXBlKSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyAiCisgICAgIiAgbmFtZTogXCJUZXN0TWVzc2FnZVwiICIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJmb29cIiBudW1iZXI6MSBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfU1RSSU5HICIKKyAgICAiICAgICAgICAgIG9wdGlvbnMgeyB1bmludGVycHJldGVkX29wdGlvbiB7IG5hbWUgeyBuYW1lX3BhcnQ6IFwiY3R5cGVcIiAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNfZXh0ZW5zaW9uOiBmYWxzZSB9IgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSB7IG5hbWVfcGFydDogXCJmb29cIiAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNfZXh0ZW5zaW9uOiB0cnVlIH0iCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3NpdGl2ZV9pbnRfdmFsdWU6IDEgfSIKKyAgICAiICAgICAgICAgIH0iCisgICAgIiAgfSIKKyAgICAifVxuIiwKKworICAgICJmb28ucHJvdG86IFRlc3RNZXNzYWdlLmZvbzogT1BUSU9OX05BTUU6IE9wdGlvbiBcImN0eXBlXCIgaXMgYW4gIgorICAgICJhdG9taWMgdHlwZSwgbm90IGEgbWVzc2FnZS5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgRHVwT3B0aW9uKSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyAiCisgICAgIiAgbmFtZTogXCJUZXN0TWVzc2FnZVwiICIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJmb29cIiBudW1iZXI6MSBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfVUlOVDMyICIKKyAgICAiICAgICAgICAgIG9wdGlvbnMgeyB1bmludGVycHJldGVkX29wdGlvbiB7IG5hbWUgeyBuYW1lX3BhcnQ6IFwiY3R5cGVcIiAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNfZXh0ZW5zaW9uOiBmYWxzZSB9IgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWRlbnRpZmllcl92YWx1ZTogXCJDT1JEXCIgfSIKKyAgICAiICAgICAgICAgICAgICAgICAgICB1bmludGVycHJldGVkX29wdGlvbiB7IG5hbWUgeyBuYW1lX3BhcnQ6IFwiY3R5cGVcIiAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNfZXh0ZW5zaW9uOiBmYWxzZSB9IgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWRlbnRpZmllcl92YWx1ZTogXCJDT1JEXCIgfSIKKyAgICAiICAgICAgICAgIH0iCisgICAgIiAgfSIKKyAgICAifVxuIiwKKworICAgICJmb28ucHJvdG86IFRlc3RNZXNzYWdlLmZvbzogT1BUSU9OX05BTUU6IE9wdGlvbiBcImN0eXBlXCIgd2FzICIKKyAgICAiYWxyZWFkeSBzZXQuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIEludmFsaWRPcHRpb25OYW1lKSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyAiCisgICAgIiAgbmFtZTogXCJUZXN0TWVzc2FnZVwiICIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJmb29cIiBudW1iZXI6MSBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfQk9PTCAiCisgICAgIiAgICAgICAgICBvcHRpb25zIHsgdW5pbnRlcnByZXRlZF9vcHRpb24geyAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICBuYW1lIHsgbmFtZV9wYXJ0OiBcInVuaW50ZXJwcmV0ZWRfb3B0aW9uXCIgIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzX2V4dGVuc2lvbjogZmFsc2UgfSIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aXZlX2ludF92YWx1ZTogMSAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgfSIKKyAgICAiICAgICAgICAgIH0iCisgICAgIiAgfSIKKyAgICAifVxuIiwKKworICAgICJmb28ucHJvdG86IFRlc3RNZXNzYWdlLmZvbzogT1BUSU9OX05BTUU6IE9wdGlvbiBtdXN0IG5vdCB1c2UgIgorICAgICJyZXNlcnZlZCBuYW1lIFwidW5pbnRlcnByZXRlZF9vcHRpb25cIi5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgUmVwZWF0ZWRNZXNzYWdlT3B0aW9uKSB7CisgIEJ1aWxkRGVzY3JpcHRvck1lc3NhZ2VzSW5UZXN0UG9vbCgpOworCisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJkZXBlbmRlbmN5OiBcImdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGU6IHsgbmFtZTogXCJCYXJcIiBmaWVsZDogeyAiCisgICAgIiAgbmFtZTogXCJmb29cIiBudW1iZXI6IDEgbGFiZWw6IExBQkVMX09QVElPTkFMIHR5cGU6IFRZUEVfSU5UMzIgfSAiCisgICAgIn0gIgorICAgICJleHRlbnNpb24geyBuYW1lOiBcImJhclwiIG51bWJlcjogNzY3Mjc1NyBsYWJlbDogTEFCRUxfUkVQRUFURUQgIgorICAgICIgICAgICAgICAgICB0eXBlOiBUWVBFX01FU1NBR0UgdHlwZV9uYW1lOiBcIkJhclwiICIKKyAgICAiICAgICAgICAgICAgZXh0ZW5kZWU6IFwiZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zXCIgfSIKKyAgICAib3B0aW9ucyB7IHVuaW50ZXJwcmV0ZWRfb3B0aW9uIHsgbmFtZSB7IG5hbWVfcGFydDogXCJiYXJcIiAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc19leHRlbnNpb246IHRydWUgfSAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgeyBuYW1lX3BhcnQ6IFwiZm9vXCIgIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNfZXh0ZW5zaW9uOiBmYWxzZSB9ICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zaXRpdmVfaW50X3ZhbHVlOiAxIH0gfSIsCisKKyAgICAiZm9vLnByb3RvOiBmb28ucHJvdG86IE9QVElPTl9OQU1FOiBPcHRpb24gZmllbGQgXCIoYmFyKVwiIGlzIGEgIgorICAgICJyZXBlYXRlZCBtZXNzYWdlLiBSZXBlYXRlZCBtZXNzYWdlIG9wdGlvbnMgbXVzdCBiZSBpbml0aWFsaXplZCAiCisgICAgInVzaW5nIGFuIGFnZ3JlZ2F0ZSB2YWx1ZS5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgUmVzb2x2ZVVuZGVmaW5lZE9wdGlvbikgeworICAvLyBUaGUgZm9sbG93aW5nIHNob3VsZCBwcm9kdWNlIGFuIGVyb3IgdGhhdCBiYXouYmFyIGlzIHJlc29sdmVkIGJ1dCBub3QKKyAgLy8gZGVmaW5lZC4KKyAgLy8gZm9vLnByb3RvOgorICAvLyAgIHBhY2thZ2UgYmF6CisgIC8vICAgaW1wb3J0IGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvCisgIC8vICAgbWVzc2FnZSBCYXIgeyBvcHRpb25hbCBpbnQzMiBmb28gPSAxOyB9CisgIC8vICAgZXh0ZW5kIEZpbGVPcHRpb25zIHsgb3B0aW9uYWwgQmFyIGJhciA9IDc2NzI3NTc7IH0KKyAgLy8KKyAgLy8gcXV4LnByb3RvOgorICAvLyAgIHBhY2thZ2UgcXV4LmJhegorICAvLyAgIG9wdGlvbiAoYmF6LmJhcikuZm9vID0gMTsKKyAgLy8KKyAgLy8gQWx0aG91Z2ggImJhei5iYXIiIGlzIGFscmVhZHkgZGVmaW5lZCwgdGhlIGxvb2t1cCBjb2RlIHdpbGwgdHJ5CisgIC8vICJxdXguYmF6LmJhciIsIHNpbmNlIGl0J3MgdGhlIG1hdGNoIGZyb20gdGhlIGlubmVybW9zdCBzY29wZSwgd2hpY2ggd2lsbAorICAvLyBjYXVzZSBhIHN5bWJvbCBub3QgZGVmaW5lZCBlcnJvci4KKyAgQnVpbGREZXNjcmlwdG9yTWVzc2FnZXNJblRlc3RQb29sKCk7CisKKyAgQnVpbGRGaWxlKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAicGFja2FnZTogXCJiYXpcIiAiCisgICAgImRlcGVuZGVuY3k6IFwiZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZTogeyBuYW1lOiBcIkJhclwiIGZpZWxkOiB7ICIKKyAgICAiICBuYW1lOiBcImZvb1wiIG51bWJlcjogMSBsYWJlbDogTEFCRUxfT1BUSU9OQUwgdHlwZTogVFlQRV9JTlQzMiB9ICIKKyAgICAifSAiCisgICAgImV4dGVuc2lvbiB7IG5hbWU6IFwiYmFyXCIgbnVtYmVyOiA3NjcyNzU3IGxhYmVsOiBMQUJFTF9PUFRJT05BTCAiCisgICAgIiAgICAgICAgICAgIHR5cGU6IFRZUEVfTUVTU0FHRSB0eXBlX25hbWU6IFwiQmFyXCIgIgorICAgICIgICAgICAgICAgICBleHRlbmRlZTogXCJnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnNcIiB9Iik7CisKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJxdXgucHJvdG9cIiAiCisgICAgInBhY2thZ2U6IFwicXV4LmJhelwiICIKKyAgICAib3B0aW9ucyB7IHVuaW50ZXJwcmV0ZWRfb3B0aW9uIHsgbmFtZSB7IG5hbWVfcGFydDogXCJiYXouYmFyXCIgIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNfZXh0ZW5zaW9uOiB0cnVlIH0gIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lIHsgbmFtZV9wYXJ0OiBcImZvb1wiICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzX2V4dGVuc2lvbjogZmFsc2UgfSAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aXZlX2ludF92YWx1ZTogMSB9IH0iLAorCisgICAgInF1eC5wcm90bzogcXV4LnByb3RvOiBPUFRJT05fTkFNRTogT3B0aW9uIFwiKGJhei5iYXIpXCIgaXMgcmVzb2x2ZWQgdG8gIgorICAgICJcIihxdXguYmF6LmJhcilcIiwiCisgICAgIiB3aGljaCBpcyBub3QgZGVmaW5lZC4gVGhlIGlubmVybW9zdCBzY29wZSBpcyBzZWFyY2hlZCBmaXJzdCBpbiBuYW1lICIKKyAgICAicmVzb2x1dGlvbi4gQ29uc2lkZXIgdXNpbmcgYSBsZWFkaW5nICcuJyhpLmUuLCBcIiguYmF6LmJhcilcIikgdG8gc3RhcnQgIgorICAgICJmcm9tIHRoZSBvdXRlcm1vc3Qgc2NvcGUuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIFVua25vd25PcHRpb24pIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJxdXgucHJvdG9cIiAiCisgICAgInBhY2thZ2U6IFwicXV4LmJhelwiICIKKyAgICAib3B0aW9ucyB7IHVuaW50ZXJwcmV0ZWRfb3B0aW9uIHsgbmFtZSB7IG5hbWVfcGFydDogXCJiYWF6LmJhclwiICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzX2V4dGVuc2lvbjogdHJ1ZSB9ICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSB7IG5hbWVfcGFydDogXCJmb29cIiAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc19leHRlbnNpb246IGZhbHNlIH0gIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3NpdGl2ZV9pbnRfdmFsdWU6IDEgfSB9IiwKKworICAgICJxdXgucHJvdG86IHF1eC5wcm90bzogT1BUSU9OX05BTUU6IE9wdGlvbiBcIihiYWF6LmJhcilcIiB1bmtub3duLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBDdXN0b21PcHRpb25Db25mbGljdGluZ0ZpZWxkTnVtYmVyKSB7CisgIEJ1aWxkRGVzY3JpcHRvck1lc3NhZ2VzSW5UZXN0UG9vbCgpOworCisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJkZXBlbmRlbmN5OiBcImdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvXCIgIgorICAgICJleHRlbnNpb24geyBuYW1lOiBcImZvbzFcIiBudW1iZXI6IDc2NzI3NTcgbGFiZWw6IExBQkVMX09QVElPTkFMICIKKyAgICAiICAgICAgICAgICAgdHlwZTogVFlQRV9JTlQzMiBleHRlbmRlZTogXCJnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zXCIgfSIKKyAgICAiZXh0ZW5zaW9uIHsgbmFtZTogXCJmb28yXCIgbnVtYmVyOiA3NjcyNzU3IGxhYmVsOiBMQUJFTF9PUFRJT05BTCAiCisgICAgIiAgICAgICAgICAgIHR5cGU6IFRZUEVfSU5UMzIgZXh0ZW5kZWU6IFwiZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9uc1wiIH0iLAorCisgICAgImZvby5wcm90bzogZm9vMjogTlVNQkVSOiBFeHRlbnNpb24gbnVtYmVyIDc2NzI3NTcgaGFzIGFscmVhZHkgYmVlbiB1c2VkICIKKyAgICAiaW4gXCJnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zXCIgYnkgZXh0ZW5zaW9uIFwiZm9vMVwiLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBJbnQzMk9wdGlvblZhbHVlT3V0T2ZQb3NpdGl2ZVJhbmdlKSB7CisgIEJ1aWxkRGVzY3JpcHRvck1lc3NhZ2VzSW5UZXN0UG9vbCgpOworCisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJkZXBlbmRlbmN5OiBcImdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvXCIgIgorICAgICJleHRlbnNpb24geyBuYW1lOiBcImZvb1wiIG51bWJlcjogNzY3Mjc1NyBsYWJlbDogTEFCRUxfT1BUSU9OQUwgIgorICAgICIgICAgICAgICAgICB0eXBlOiBUWVBFX0lOVDMyIGV4dGVuZGVlOiBcImdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9uc1wiIH0iCisgICAgIm9wdGlvbnMgeyB1bmludGVycHJldGVkX29wdGlvbiB7IG5hbWUgeyBuYW1lX3BhcnQ6IFwiZm9vXCIgIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNfZXh0ZW5zaW9uOiB0cnVlIH0gIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3NpdGl2ZV9pbnRfdmFsdWU6IDB4ODAwMDAwMDAgfSAiCisgICAgIn0iLAorCisgICAgImZvby5wcm90bzogZm9vLnByb3RvOiBPUFRJT05fVkFMVUU6IFZhbHVlIG91dCBvZiByYW5nZSAiCisgICAgImZvciBpbnQzMiBvcHRpb24gXCJmb29cIi5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgSW50MzJPcHRpb25WYWx1ZU91dE9mTmVnYXRpdmVSYW5nZSkgeworICBCdWlsZERlc2NyaXB0b3JNZXNzYWdlc0luVGVzdFBvb2woKTsKKworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAiZGVwZW5kZW5jeTogXCJnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90b1wiICIKKyAgICAiZXh0ZW5zaW9uIHsgbmFtZTogXCJmb29cIiBudW1iZXI6IDc2NzI3NTcgbGFiZWw6IExBQkVMX09QVElPTkFMICIKKyAgICAiICAgICAgICAgICAgdHlwZTogVFlQRV9JTlQzMiBleHRlbmRlZTogXCJnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnNcIiB9IgorICAgICJvcHRpb25zIHsgdW5pbnRlcnByZXRlZF9vcHRpb24geyBuYW1lIHsgbmFtZV9wYXJ0OiBcImZvb1wiICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzX2V4dGVuc2lvbjogdHJ1ZSB9ICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmVnYXRpdmVfaW50X3ZhbHVlOiAtMHg4MDAwMDAwMSB9ICIKKyAgICAifSIsCisKKyAgICAiZm9vLnByb3RvOiBmb28ucHJvdG86IE9QVElPTl9WQUxVRTogVmFsdWUgb3V0IG9mIHJhbmdlICIKKyAgICAiZm9yIGludDMyIG9wdGlvbiBcImZvb1wiLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBJbnQzMk9wdGlvblZhbHVlSXNOb3RQb3NpdGl2ZUludCkgeworICBCdWlsZERlc2NyaXB0b3JNZXNzYWdlc0luVGVzdFBvb2woKTsKKworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAiZGVwZW5kZW5jeTogXCJnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90b1wiICIKKyAgICAiZXh0ZW5zaW9uIHsgbmFtZTogXCJmb29cIiBudW1iZXI6IDc2NzI3NTcgbGFiZWw6IExBQkVMX09QVElPTkFMICIKKyAgICAiICAgICAgICAgICAgdHlwZTogVFlQRV9JTlQzMiBleHRlbmRlZTogXCJnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnNcIiB9IgorICAgICJvcHRpb25zIHsgdW5pbnRlcnByZXRlZF9vcHRpb24geyBuYW1lIHsgbmFtZV9wYXJ0OiBcImZvb1wiICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzX2V4dGVuc2lvbjogdHJ1ZSB9ICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nX3ZhbHVlOiBcIjVcIiB9IH0iLAorCisgICAgImZvby5wcm90bzogZm9vLnByb3RvOiBPUFRJT05fVkFMVUU6IFZhbHVlIG11c3QgYmUgaW50ZWdlciAiCisgICAgImZvciBpbnQzMiBvcHRpb24gXCJmb29cIi5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgSW50NjRPcHRpb25WYWx1ZU91dE9mUmFuZ2UpIHsKKyAgQnVpbGREZXNjcmlwdG9yTWVzc2FnZXNJblRlc3RQb29sKCk7CisKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgImRlcGVuZGVuY3k6IFwiZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG9cIiAiCisgICAgImV4dGVuc2lvbiB7IG5hbWU6IFwiZm9vXCIgbnVtYmVyOiA3NjcyNzU3IGxhYmVsOiBMQUJFTF9PUFRJT05BTCAiCisgICAgIiAgICAgICAgICAgIHR5cGU6IFRZUEVfSU5UNjQgZXh0ZW5kZWU6IFwiZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zXCIgfSIKKyAgICAib3B0aW9ucyB7IHVuaW50ZXJwcmV0ZWRfb3B0aW9uIHsgbmFtZSB7IG5hbWVfcGFydDogXCJmb29cIiAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc19leHRlbnNpb246IHRydWUgfSAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aXZlX2ludF92YWx1ZTogMHg4MDAwMDAwMDAwMDAwMDAwIH0gIgorICAgICJ9IiwKKworICAgICJmb28ucHJvdG86IGZvby5wcm90bzogT1BUSU9OX1ZBTFVFOiBWYWx1ZSBvdXQgb2YgcmFuZ2UgIgorICAgICJmb3IgaW50NjQgb3B0aW9uIFwiZm9vXCIuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIEludDY0T3B0aW9uVmFsdWVJc05vdFBvc2l0aXZlSW50KSB7CisgIEJ1aWxkRGVzY3JpcHRvck1lc3NhZ2VzSW5UZXN0UG9vbCgpOworCisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJkZXBlbmRlbmN5OiBcImdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvXCIgIgorICAgICJleHRlbnNpb24geyBuYW1lOiBcImZvb1wiIG51bWJlcjogNzY3Mjc1NyBsYWJlbDogTEFCRUxfT1BUSU9OQUwgIgorICAgICIgICAgICAgICAgICB0eXBlOiBUWVBFX0lOVDY0IGV4dGVuZGVlOiBcImdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9uc1wiIH0iCisgICAgIm9wdGlvbnMgeyB1bmludGVycHJldGVkX29wdGlvbiB7IG5hbWUgeyBuYW1lX3BhcnQ6IFwiZm9vXCIgIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNfZXh0ZW5zaW9uOiB0cnVlIH0gIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZGVudGlmaWVyX3ZhbHVlOiBcIjVcIiB9IH0iLAorCisgICAgImZvby5wcm90bzogZm9vLnByb3RvOiBPUFRJT05fVkFMVUU6IFZhbHVlIG11c3QgYmUgaW50ZWdlciAiCisgICAgImZvciBpbnQ2NCBvcHRpb24gXCJmb29cIi5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgVUludDMyT3B0aW9uVmFsdWVPdXRPZlJhbmdlKSB7CisgIEJ1aWxkRGVzY3JpcHRvck1lc3NhZ2VzSW5UZXN0UG9vbCgpOworCisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJkZXBlbmRlbmN5OiBcImdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvXCIgIgorICAgICJleHRlbnNpb24geyBuYW1lOiBcImZvb1wiIG51bWJlcjogNzY3Mjc1NyBsYWJlbDogTEFCRUxfT1BUSU9OQUwgIgorICAgICIgICAgICAgICAgICB0eXBlOiBUWVBFX1VJTlQzMiBleHRlbmRlZTogXCJnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnNcIiB9IgorICAgICJvcHRpb25zIHsgdW5pbnRlcnByZXRlZF9vcHRpb24geyBuYW1lIHsgbmFtZV9wYXJ0OiBcImZvb1wiICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzX2V4dGVuc2lvbjogdHJ1ZSB9ICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zaXRpdmVfaW50X3ZhbHVlOiAweDEwMDAwMDAwMCB9IH0iLAorCisgICAgImZvby5wcm90bzogZm9vLnByb3RvOiBPUFRJT05fVkFMVUU6IFZhbHVlIG91dCBvZiByYW5nZSAiCisgICAgImZvciB1aW50MzIgb3B0aW9uIFwiZm9vXCIuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIFVJbnQzMk9wdGlvblZhbHVlSXNOb3RQb3NpdGl2ZUludCkgeworICBCdWlsZERlc2NyaXB0b3JNZXNzYWdlc0luVGVzdFBvb2woKTsKKworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAiZGVwZW5kZW5jeTogXCJnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90b1wiICIKKyAgICAiZXh0ZW5zaW9uIHsgbmFtZTogXCJmb29cIiBudW1iZXI6IDc2NzI3NTcgbGFiZWw6IExBQkVMX09QVElPTkFMICIKKyAgICAiICAgICAgICAgICAgdHlwZTogVFlQRV9VSU5UMzIgZXh0ZW5kZWU6IFwiZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zXCIgfSIKKyAgICAib3B0aW9ucyB7IHVuaW50ZXJwcmV0ZWRfb3B0aW9uIHsgbmFtZSB7IG5hbWVfcGFydDogXCJmb29cIiAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc19leHRlbnNpb246IHRydWUgfSAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvdWJsZV92YWx1ZTogLTUuNiB9IH0iLAorCisgICAgImZvby5wcm90bzogZm9vLnByb3RvOiBPUFRJT05fVkFMVUU6IFZhbHVlIG11c3QgYmUgbm9uLW5lZ2F0aXZlIGludGVnZXIgIgorICAgICJmb3IgdWludDMyIG9wdGlvbiBcImZvb1wiLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBVSW50NjRPcHRpb25WYWx1ZUlzTm90UG9zaXRpdmVJbnQpIHsKKyAgQnVpbGREZXNjcmlwdG9yTWVzc2FnZXNJblRlc3RQb29sKCk7CisKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgImRlcGVuZGVuY3k6IFwiZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG9cIiAiCisgICAgImV4dGVuc2lvbiB7IG5hbWU6IFwiZm9vXCIgbnVtYmVyOiA3NjcyNzU3IGxhYmVsOiBMQUJFTF9PUFRJT05BTCAiCisgICAgIiAgICAgICAgICAgIHR5cGU6IFRZUEVfVUlOVDY0IGV4dGVuZGVlOiBcImdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9uc1wiIH0iCisgICAgIm9wdGlvbnMgeyB1bmludGVycHJldGVkX29wdGlvbiB7IG5hbWUgeyBuYW1lX3BhcnQ6IFwiZm9vXCIgIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNfZXh0ZW5zaW9uOiB0cnVlIH0gIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZWdhdGl2ZV9pbnRfdmFsdWU6IC01IH0gfSIsCisKKyAgICAiZm9vLnByb3RvOiBmb28ucHJvdG86IE9QVElPTl9WQUxVRTogVmFsdWUgbXVzdCBiZSBub24tbmVnYXRpdmUgaW50ZWdlciAiCisgICAgImZvciB1aW50NjQgb3B0aW9uIFwiZm9vXCIuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIEZsb2F0T3B0aW9uVmFsdWVJc05vdE51bWJlcikgeworICBCdWlsZERlc2NyaXB0b3JNZXNzYWdlc0luVGVzdFBvb2woKTsKKworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAiZGVwZW5kZW5jeTogXCJnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90b1wiICIKKyAgICAiZXh0ZW5zaW9uIHsgbmFtZTogXCJmb29cIiBudW1iZXI6IDc2NzI3NTcgbGFiZWw6IExBQkVMX09QVElPTkFMICIKKyAgICAiICAgICAgICAgICAgdHlwZTogVFlQRV9GTE9BVCBleHRlbmRlZTogXCJnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnNcIiB9IgorICAgICJvcHRpb25zIHsgdW5pbnRlcnByZXRlZF9vcHRpb24geyBuYW1lIHsgbmFtZV9wYXJ0OiBcImZvb1wiICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzX2V4dGVuc2lvbjogdHJ1ZSB9ICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nX3ZhbHVlOiBcImJhclwiIH0gfSIsCisKKyAgICAiZm9vLnByb3RvOiBmb28ucHJvdG86IE9QVElPTl9WQUxVRTogVmFsdWUgbXVzdCBiZSBudW1iZXIgIgorICAgICJmb3IgZmxvYXQgb3B0aW9uIFwiZm9vXCIuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIERvdWJsZU9wdGlvblZhbHVlSXNOb3ROdW1iZXIpIHsKKyAgQnVpbGREZXNjcmlwdG9yTWVzc2FnZXNJblRlc3RQb29sKCk7CisKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgImRlcGVuZGVuY3k6IFwiZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG9cIiAiCisgICAgImV4dGVuc2lvbiB7IG5hbWU6IFwiZm9vXCIgbnVtYmVyOiA3NjcyNzU3IGxhYmVsOiBMQUJFTF9PUFRJT05BTCAiCisgICAgIiAgICAgICAgICAgIHR5cGU6IFRZUEVfRE9VQkxFIGV4dGVuZGVlOiBcImdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9uc1wiIH0iCisgICAgIm9wdGlvbnMgeyB1bmludGVycHJldGVkX29wdGlvbiB7IG5hbWUgeyBuYW1lX3BhcnQ6IFwiZm9vXCIgIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNfZXh0ZW5zaW9uOiB0cnVlIH0gIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmdfdmFsdWU6IFwiYmFyXCIgfSB9IiwKKworICAgICJmb28ucHJvdG86IGZvby5wcm90bzogT1BUSU9OX1ZBTFVFOiBWYWx1ZSBtdXN0IGJlIG51bWJlciAiCisgICAgImZvciBkb3VibGUgb3B0aW9uIFwiZm9vXCIuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIEJvb2xPcHRpb25WYWx1ZUlzTm90VHJ1ZU9yRmFsc2UpIHsKKyAgQnVpbGREZXNjcmlwdG9yTWVzc2FnZXNJblRlc3RQb29sKCk7CisKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgImRlcGVuZGVuY3k6IFwiZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG9cIiAiCisgICAgImV4dGVuc2lvbiB7IG5hbWU6IFwiZm9vXCIgbnVtYmVyOiA3NjcyNzU3IGxhYmVsOiBMQUJFTF9PUFRJT05BTCAiCisgICAgIiAgICAgICAgICAgIHR5cGU6IFRZUEVfQk9PTCBleHRlbmRlZTogXCJnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnNcIiB9IgorICAgICJvcHRpb25zIHsgdW5pbnRlcnByZXRlZF9vcHRpb24geyBuYW1lIHsgbmFtZV9wYXJ0OiBcImZvb1wiICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzX2V4dGVuc2lvbjogdHJ1ZSB9ICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWRlbnRpZmllcl92YWx1ZTogXCJiYXJcIiB9IH0iLAorCisgICAgImZvby5wcm90bzogZm9vLnByb3RvOiBPUFRJT05fVkFMVUU6IFZhbHVlIG11c3QgYmUgXCJ0cnVlXCIgb3IgXCJmYWxzZVwiICIKKyAgICAiZm9yIGJvb2xlYW4gb3B0aW9uIFwiZm9vXCIuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIEVudW1PcHRpb25WYWx1ZUlzTm90SWRlbnRpZmllcikgeworICBCdWlsZERlc2NyaXB0b3JNZXNzYWdlc0luVGVzdFBvb2woKTsKKworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAiZGVwZW5kZW5jeTogXCJnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90b1wiICIKKyAgICAiZW51bV90eXBlIHsgbmFtZTogXCJGb29FbnVtXCIgdmFsdWUgeyBuYW1lOiBcIkJBUlwiIG51bWJlcjogMSB9ICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgeyBuYW1lOiBcIkJBWlwiIG51bWJlcjogMiB9IH0iCisgICAgImV4dGVuc2lvbiB7IG5hbWU6IFwiZm9vXCIgbnVtYmVyOiA3NjcyNzU3IGxhYmVsOiBMQUJFTF9PUFRJT05BTCAiCisgICAgIiAgICAgICAgICAgIHR5cGU6IFRZUEVfRU5VTSB0eXBlX25hbWU6IFwiRm9vRW51bVwiICIKKyAgICAiICAgICAgICAgICAgZXh0ZW5kZWU6IFwiZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zXCIgfSIKKyAgICAib3B0aW9ucyB7IHVuaW50ZXJwcmV0ZWRfb3B0aW9uIHsgbmFtZSB7IG5hbWVfcGFydDogXCJmb29cIiAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc19leHRlbnNpb246IHRydWUgfSAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ192YWx1ZTogXCJRVVVYXCIgfSB9IiwKKworICAgICJmb28ucHJvdG86IGZvby5wcm90bzogT1BUSU9OX1ZBTFVFOiBWYWx1ZSBtdXN0IGJlIGlkZW50aWZpZXIgZm9yICIKKyAgICAiZW51bS12YWx1ZWQgb3B0aW9uIFwiZm9vXCIuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIEVudW1PcHRpb25WYWx1ZUlzTm90RW51bVZhbHVlTmFtZSkgeworICBCdWlsZERlc2NyaXB0b3JNZXNzYWdlc0luVGVzdFBvb2woKTsKKworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAiZGVwZW5kZW5jeTogXCJnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90b1wiICIKKyAgICAiZW51bV90eXBlIHsgbmFtZTogXCJGb29FbnVtXCIgdmFsdWUgeyBuYW1lOiBcIkJBUlwiIG51bWJlcjogMSB9ICIKKyAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgeyBuYW1lOiBcIkJBWlwiIG51bWJlcjogMiB9IH0iCisgICAgImV4dGVuc2lvbiB7IG5hbWU6IFwiZm9vXCIgbnVtYmVyOiA3NjcyNzU3IGxhYmVsOiBMQUJFTF9PUFRJT05BTCAiCisgICAgIiAgICAgICAgICAgIHR5cGU6IFRZUEVfRU5VTSB0eXBlX25hbWU6IFwiRm9vRW51bVwiICIKKyAgICAiICAgICAgICAgICAgZXh0ZW5kZWU6IFwiZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zXCIgfSIKKyAgICAib3B0aW9ucyB7IHVuaW50ZXJwcmV0ZWRfb3B0aW9uIHsgbmFtZSB7IG5hbWVfcGFydDogXCJmb29cIiAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc19leHRlbnNpb246IHRydWUgfSAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkZW50aWZpZXJfdmFsdWU6IFwiUVVVWFwiIH0gfSIsCisKKyAgICAiZm9vLnByb3RvOiBmb28ucHJvdG86IE9QVElPTl9WQUxVRTogRW51bSB0eXBlIFwiRm9vRW51bVwiIGhhcyBubyB2YWx1ZSAiCisgICAgIm5hbWVkIFwiUVVVWFwiIGZvciBvcHRpb24gXCJmb29cIi5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgRW51bU9wdGlvblZhbHVlSXNTaWJsaW5nRW51bVZhbHVlTmFtZSkgeworICBCdWlsZERlc2NyaXB0b3JNZXNzYWdlc0luVGVzdFBvb2woKTsKKworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAiZGVwZW5kZW5jeTogXCJnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90b1wiICIKKyAgICAiZW51bV90eXBlIHsgbmFtZTogXCJGb29FbnVtMVwiIHZhbHVlIHsgbmFtZTogXCJCQVJcIiBudW1iZXI6IDEgfSAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSB7IG5hbWU6IFwiQkFaXCIgbnVtYmVyOiAyIH0gfSIKKyAgICAiZW51bV90eXBlIHsgbmFtZTogXCJGb29FbnVtMlwiIHZhbHVlIHsgbmFtZTogXCJRVVhcIiBudW1iZXI6IDEgfSAiCisgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSB7IG5hbWU6IFwiUVVVWFwiIG51bWJlcjogMiB9IH0iCisgICAgImV4dGVuc2lvbiB7IG5hbWU6IFwiZm9vXCIgbnVtYmVyOiA3NjcyNzU3IGxhYmVsOiBMQUJFTF9PUFRJT05BTCAiCisgICAgIiAgICAgICAgICAgIHR5cGU6IFRZUEVfRU5VTSB0eXBlX25hbWU6IFwiRm9vRW51bTFcIiAiCisgICAgIiAgICAgICAgICAgIGV4dGVuZGVlOiBcImdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9uc1wiIH0iCisgICAgIm9wdGlvbnMgeyB1bmludGVycHJldGVkX29wdGlvbiB7IG5hbWUgeyBuYW1lX3BhcnQ6IFwiZm9vXCIgIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNfZXh0ZW5zaW9uOiB0cnVlIH0gIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZGVudGlmaWVyX3ZhbHVlOiBcIlFVVVhcIiB9IH0iLAorCisgICAgImZvby5wcm90bzogZm9vLnByb3RvOiBPUFRJT05fVkFMVUU6IEVudW0gdHlwZSBcIkZvb0VudW0xXCIgaGFzIG5vIHZhbHVlICIKKyAgICAibmFtZWQgXCJRVVVYXCIgZm9yIG9wdGlvbiBcImZvb1wiLiBUaGlzIGFwcGVhcnMgdG8gYmUgYSB2YWx1ZSBmcm9tIGEgIgorICAgICJzaWJsaW5nIHR5cGUuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIFN0cmluZ09wdGlvblZhbHVlSXNOb3RTdHJpbmcpIHsKKyAgQnVpbGREZXNjcmlwdG9yTWVzc2FnZXNJblRlc3RQb29sKCk7CisKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgImRlcGVuZGVuY3k6IFwiZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG9cIiAiCisgICAgImV4dGVuc2lvbiB7IG5hbWU6IFwiZm9vXCIgbnVtYmVyOiA3NjcyNzU3IGxhYmVsOiBMQUJFTF9PUFRJT05BTCAiCisgICAgIiAgICAgICAgICAgIHR5cGU6IFRZUEVfU1RSSU5HIGV4dGVuZGVlOiBcImdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9uc1wiIH0iCisgICAgIm9wdGlvbnMgeyB1bmludGVycHJldGVkX29wdGlvbiB7IG5hbWUgeyBuYW1lX3BhcnQ6IFwiZm9vXCIgIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNfZXh0ZW5zaW9uOiB0cnVlIH0gIgorICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZGVudGlmaWVyX3ZhbHVlOiBcIlFVVVhcIiB9IH0iLAorCisgICAgImZvby5wcm90bzogZm9vLnByb3RvOiBPUFRJT05fVkFMVUU6IFZhbHVlIG11c3QgYmUgcXVvdGVkIHN0cmluZyBmb3IgIgorICAgICJzdHJpbmcgb3B0aW9uIFwiZm9vXCIuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIER1cGxpY2F0ZUV4dGVuc2lvbkZpZWxkTnVtYmVyKSB7CisgIEJ1aWxkRGVzY3JpcHRvck1lc3NhZ2VzSW5UZXN0UG9vbCgpOworCisgIEJ1aWxkRmlsZSgKKyAgICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAgICJkZXBlbmRlbmN5OiBcImdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvXCIgIgorICAgICAgImV4dGVuc2lvbiB7IG5hbWU6IFwib3B0aW9uMVwiIG51bWJlcjogMTAwMCBsYWJlbDogTEFCRUxfT1BUSU9OQUwgIgorICAgICAgIiAgICAgICAgICAgIHR5cGU6IFRZUEVfSU5UMzIgZXh0ZW5kZWU6IFwiZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zXCIgfSIpOworCisgIEJ1aWxkRmlsZVdpdGhXYXJuaW5ncygKKyAgICAgICJuYW1lOiBcImJhci5wcm90b1wiICIKKyAgICAgICJkZXBlbmRlbmN5OiBcImdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvXCIgIgorICAgICAgImV4dGVuc2lvbiB7IG5hbWU6IFwib3B0aW9uMlwiIG51bWJlcjogMTAwMCBsYWJlbDogTEFCRUxfT1BUSU9OQUwgIgorICAgICAgIiAgICAgICAgICAgIHR5cGU6IFRZUEVfSU5UMzIgZXh0ZW5kZWU6IFwiZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zXCIgfSIsCisgICAgICAiYmFyLnByb3RvOiBvcHRpb24yOiBOVU1CRVI6IEV4dGVuc2lvbiBudW1iZXIgMTAwMCBoYXMgYWxyZWFkeSBiZWVuIHVzZWQgIgorICAgICAgImluIFwiZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zXCIgYnkgZXh0ZW5zaW9uIFwib3B0aW9uMVwiIGRlZmluZWQgaW4gIgorICAgICAgImZvby5wcm90by5cbiIpOworfQorCisvLyBIZWxwZXIgZnVuY3Rpb24gZm9yIHRlc3RzIHRoYXQgY2hlY2sgZm9yIGFnZ3JlZ2F0ZSB2YWx1ZSBwYXJzaW5nCisvLyBlcnJvcnMuICBUaGUgInZhbHVlIiBhcmd1bWVudCBpcyBlbWJlZGRlZCBpbnNpZGUgdGhlCisvLyAidW5pbnRlcnByZXRlZF9vcHRpb24iIHBvcnRpb24gb2YgdGhlIHJlc3VsdC4KK3N0YXRpYyBzdHJpbmcgRW1iZWRBZ2dyZWdhdGVWYWx1ZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICByZXR1cm4gc3RyaW5nczo6U3Vic3RpdHV0ZSgKKyAgICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAgICJkZXBlbmRlbmN5OiBcImdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvXCIgIgorICAgICAgIm1lc3NhZ2VfdHlwZSB7IG5hbWU6IFwiRm9vXCIgfSAiCisgICAgICAiZXh0ZW5zaW9uIHsgbmFtZTogXCJmb29cIiBudW1iZXI6IDc2NzI3NTcgbGFiZWw6IExBQkVMX09QVElPTkFMICIKKyAgICAgICIgICAgICAgICAgICB0eXBlOiBUWVBFX01FU1NBR0UgdHlwZV9uYW1lOiBcIkZvb1wiICIKKyAgICAgICIgICAgICAgICAgICBleHRlbmRlZTogXCJnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnNcIiB9IgorICAgICAgIm9wdGlvbnMgeyB1bmludGVycHJldGVkX29wdGlvbiB7IG5hbWUgeyBuYW1lX3BhcnQ6IFwiZm9vXCIgIgorICAgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc19leHRlbnNpb246IHRydWUgfSAiCisgICAgICAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJDAgfSB9IiwKKyAgICAgIHZhbHVlKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIEFnZ3JlZ2F0ZVZhbHVlTm90Rm91bmQpIHsKKyAgQnVpbGREZXNjcmlwdG9yTWVzc2FnZXNJblRlc3RQb29sKCk7CisKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAgIEVtYmVkQWdncmVnYXRlVmFsdWUoInN0cmluZ192YWx1ZTogXCJcIiIpLAorICAgICAgImZvby5wcm90bzogZm9vLnByb3RvOiBPUFRJT05fVkFMVUU6IE9wdGlvbiBcImZvb1wiIGlzIGEgbWVzc2FnZS4gIgorICAgICAgIlRvIHNldCB0aGUgZW50aXJlIG1lc3NhZ2UsIHVzZSBzeW50YXggbGlrZSAiCisgICAgICAiXCJmb28gPSB7IDxwcm90byB0ZXh0IGZvcm1hdD4gfVwiLiBUbyBzZXQgZmllbGRzIHdpdGhpbiBpdCwgdXNlICIKKyAgICAgICJzeW50YXggbGlrZSBcImZvby5mb28gPSB2YWx1ZVwiLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBBZ2dyZWdhdGVWYWx1ZVBhcnNlRXJyb3IpIHsKKyAgQnVpbGREZXNjcmlwdG9yTWVzc2FnZXNJblRlc3RQb29sKCk7CisKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAgIEVtYmVkQWdncmVnYXRlVmFsdWUoImFnZ3JlZ2F0ZV92YWx1ZTogXCIxKzJcIiIpLAorICAgICAgImZvby5wcm90bzogZm9vLnByb3RvOiBPUFRJT05fVkFMVUU6IEVycm9yIHdoaWxlIHBhcnNpbmcgb3B0aW9uICIKKyAgICAgICJ2YWx1ZSBmb3IgXCJmb29cIjogRXhwZWN0ZWQgaWRlbnRpZmllci5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgQWdncmVnYXRlVmFsdWVVbmtub3duRmllbGRzKSB7CisgIEJ1aWxkRGVzY3JpcHRvck1lc3NhZ2VzSW5UZXN0UG9vbCgpOworCisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgICBFbWJlZEFnZ3JlZ2F0ZVZhbHVlKCJhZ2dyZWdhdGVfdmFsdWU6IFwieDoxMDBcIiIpLAorICAgICAgImZvby5wcm90bzogZm9vLnByb3RvOiBPUFRJT05fVkFMVUU6IEVycm9yIHdoaWxlIHBhcnNpbmcgb3B0aW9uICIKKyAgICAgICJ2YWx1ZSBmb3IgXCJmb29cIjogTWVzc2FnZSB0eXBlIFwiRm9vXCIgaGFzIG5vIGZpZWxkIG5hbWVkIFwieFwiLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBOb3RMaXRlSW1wb3J0c0xpdGUpIHsKKyAgQnVpbGRGaWxlKAorICAgICJuYW1lOiBcImJhci5wcm90b1wiICIKKyAgICAib3B0aW9ucyB7IG9wdGltaXplX2ZvcjogTElURV9SVU5USU1FIH0gIik7CisKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgImRlcGVuZGVuY3k6IFwiYmFyLnByb3RvXCIgIiwKKworICAgICJmb28ucHJvdG86IGZvby5wcm90bzogT1RIRVI6IEZpbGVzIHRoYXQgZG8gbm90IHVzZSBvcHRpbWl6ZV9mb3IgPSAiCisgICAgICAiTElURV9SVU5USU1FIGNhbm5vdCBpbXBvcnQgZmlsZXMgd2hpY2ggZG8gdXNlIHRoaXMgb3B0aW9uLiAgVGhpcyBmaWxlICIKKyAgICAgICJpcyBub3QgbGl0ZSwgYnV0IGl0IGltcG9ydHMgXCJiYXIucHJvdG9cIiB3aGljaCBpcy5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgTGl0ZUV4dGVuZHNOb3RMaXRlKSB7CisgIEJ1aWxkRmlsZSgKKyAgICAibmFtZTogXCJiYXIucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZTogeyIKKyAgICAiICBuYW1lOiBcIkJhclwiIgorICAgICIgIGV4dGVuc2lvbl9yYW5nZSB7IHN0YXJ0OiAxIGVuZDogMTAwMCB9IgorICAgICJ9Iik7CisKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgImRlcGVuZGVuY3k6IFwiYmFyLnByb3RvXCIgIgorICAgICJvcHRpb25zIHsgb3B0aW1pemVfZm9yOiBMSVRFX1JVTlRJTUUgfSAiCisgICAgImV4dGVuc2lvbiB7IG5hbWU6IFwiZXh0XCIgbnVtYmVyOiAxMjMgbGFiZWw6IExBQkVMX09QVElPTkFMICIKKyAgICAiICAgICAgICAgICAgdHlwZTogVFlQRV9JTlQzMiBleHRlbmRlZTogXCJCYXJcIiB9IiwKKworICAgICJmb28ucHJvdG86IGV4dDogRVhURU5ERUU6IEV4dGVuc2lvbnMgdG8gbm9uLWxpdGUgdHlwZXMgY2FuIG9ubHkgYmUgIgorICAgICAgImRlY2xhcmVkIGluIG5vbi1saXRlIGZpbGVzLiAgTm90ZSB0aGF0IHlvdSBjYW5ub3QgZXh0ZW5kIGEgbm9uLWxpdGUgIgorICAgICAgInR5cGUgdG8gY29udGFpbiBhIGxpdGUgdHlwZSwgYnV0IHRoZSByZXZlcnNlIGlzIGFsbG93ZWQuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIE5vTGl0ZVNlcnZpY2VzKSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJvcHRpb25zIHsiCisgICAgIiAgb3B0aW1pemVfZm9yOiBMSVRFX1JVTlRJTUUiCisgICAgIiAgY2NfZ2VuZXJpY19zZXJ2aWNlczogdHJ1ZSIKKyAgICAiICBqYXZhX2dlbmVyaWNfc2VydmljZXM6IHRydWUiCisgICAgIn0gIgorICAgICJzZXJ2aWNlIHsgbmFtZTogXCJGb29cIiB9IiwKKworICAgICJmb28ucHJvdG86IEZvbzogTkFNRTogRmlsZXMgd2l0aCBvcHRpbWl6ZV9mb3IgPSBMSVRFX1JVTlRJTUUgY2Fubm90ICIKKyAgICAiZGVmaW5lIHNlcnZpY2VzIHVubGVzcyB5b3Ugc2V0IGJvdGggb3B0aW9ucyBjY19nZW5lcmljX3NlcnZpY2VzIGFuZCAiCisgICAgImphdmFfZ2VuZXJpY19zZXZpY2VzIHRvIGZhbHNlLlxuIik7CisKKyAgQnVpbGRGaWxlKAorICAgICJuYW1lOiBcImJhci5wcm90b1wiICIKKyAgICAib3B0aW9ucyB7IgorICAgICIgIG9wdGltaXplX2ZvcjogTElURV9SVU5USU1FIgorICAgICIgIGNjX2dlbmVyaWNfc2VydmljZXM6IGZhbHNlIgorICAgICIgIGphdmFfZ2VuZXJpY19zZXJ2aWNlczogZmFsc2UiCisgICAgIn0gIgorICAgICJzZXJ2aWNlIHsgbmFtZTogXCJCYXJcIiB9Iik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBSb2xsYmFja0FmdGVyRXJyb3IpIHsKKyAgLy8gQnVpbGQgYSBmaWxlIHdoaWNoIGNvbnRhaW5zIGV2ZXJ5IGtpbmQgb2YgY29uc3RydWN0IGJ1dCByZWZlcmVuY2VzIGFuCisgIC8vIHVuZGVmaW5lZCB0eXBlLiAgQWxsIHRoZXNlIGNvbnN0cnVjdHMgd2lsbCBiZSBhZGRlZCB0byB0aGUgc3ltYm9sIHRhYmxlCisgIC8vIGJlZm9yZSB0aGUgdW5kZWZpbmVkIHR5cGUgZXJyb3IgaXMgbm90aWNlZC4gIFRoZSBEZXNjcmlwdG9yUG9vbCB3aWxsIHRoZW4KKyAgLy8gaGF2ZSB0byByb2xsIGV2ZXJ5dGhpbmcgYmFjay4KKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiVGVzdE1lc3NhZ2VcIiIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJmb29cIiBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgbnVtYmVyOjEgfSIKKyAgICAifSAiCisgICAgImVudW1fdHlwZSB7IgorICAgICIgIG5hbWU6IFwiVGVzdEVudW1cIiIKKyAgICAiICB2YWx1ZSB7IG5hbWU6XCJCQVJcIiBudW1iZXI6MSB9IgorICAgICJ9ICIKKyAgICAic2VydmljZSB7IgorICAgICIgIG5hbWU6IFwiVGVzdFNlcnZpY2VcIiIKKyAgICAiICBtZXRob2QgeyIKKyAgICAiICAgIG5hbWU6IFwiQmF6XCIiCisgICAgIiAgICBpbnB1dF90eXBlOiBcIk5vU3VjaFR5cGVcIiIgICAgLy8gZXJyb3IKKyAgICAiICAgIG91dHB1dF90eXBlOiBcIlRlc3RNZXNzYWdlXCIiCisgICAgIiAgfSIKKyAgICAifSIsCisKKyAgICAiZm9vLnByb3RvOiBUZXN0U2VydmljZS5CYXo6IElOUFVUX1RZUEU6IFwiTm9TdWNoVHlwZVwiIGlzIG5vdCBkZWZpbmVkLlxuIgorICAgICk7CisKKyAgLy8gTWFrZSBzdXJlIHRoYXQgaWYgd2UgYnVpbGQgdGhlIHNhbWUgZmlsZSBhZ2FpbiB3aXRoIHRoZSBlcnJvciBmaXhlZCwKKyAgLy8gaXQgd29ya3MuICBJZiB0aGUgYWJvdmUgcm9sbGJhY2sgd2FzIGluY29tcGxldGUsIHRoZW4gc29tZSBzeW1ib2xzIHdpbGwKKyAgLy8gYmUgbGVmdCBkZWZpbmVkLCBhbmQgdGhpcyBzZWNvbmQgYXR0ZW1wdCB3aWxsIGZhaWwgc2luY2UgaXQgdHJpZXMgdG8KKyAgLy8gcmUtZGVmaW5lIHRoZSBzYW1lIHN5bWJvbHMuCisgIEJ1aWxkRmlsZSgKKyAgICAibmFtZTogXCJmb28ucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiVGVzdE1lc3NhZ2VcIiIKKyAgICAiICBmaWVsZCB7IG5hbWU6XCJmb29cIiBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgbnVtYmVyOjEgfSIKKyAgICAifSAiCisgICAgImVudW1fdHlwZSB7IgorICAgICIgIG5hbWU6IFwiVGVzdEVudW1cIiIKKyAgICAiICB2YWx1ZSB7IG5hbWU6XCJCQVJcIiBudW1iZXI6MSB9IgorICAgICJ9ICIKKyAgICAic2VydmljZSB7IgorICAgICIgIG5hbWU6IFwiVGVzdFNlcnZpY2VcIiIKKyAgICAiICBtZXRob2QgeyBuYW1lOlwiQmF6XCIiCisgICAgIiAgICAgICAgICAgaW5wdXRfdHlwZTpcIlRlc3RNZXNzYWdlXCIiCisgICAgIiAgICAgICAgICAgb3V0cHV0X3R5cGU6XCJUZXN0TWVzc2FnZVwiIH0iCisgICAgIn0iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIEVycm9yc1JlcG9ydGVkVG9Mb2dFcnJvcikgeworICAvLyBUZXN0IHRoYXQgZXJyb3JzIGFyZSByZXBvcnRlZCB0byBHT09HTEVfTE9HKEVSUk9SKSBpZiBubyBlcnJvciBjb2xsZWN0b3IgaXMKKyAgLy8gcHJvdmlkZWQuCisKKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICBBU1NFUlRfVFJVRShUZXh0Rm9ybWF0OjpQYXJzZUZyb21TdHJpbmcoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyBuYW1lOiBcIkZvb1wiIH0gIgorICAgICJtZXNzYWdlX3R5cGUgeyBuYW1lOiBcIkZvb1wiIH0gIiwKKyAgICAmZmlsZV9wcm90bykpOworCisgIHZlY3RvcjxzdHJpbmc+IGVycm9yczsKKworICB7CisgICAgU2NvcGVkTWVtb3J5TG9nIGxvZzsKKyAgICBFWFBFQ1RfVFJVRShwb29sXy5CdWlsZEZpbGUoZmlsZV9wcm90bykgPT0gTlVMTCk7CisgICAgZXJyb3JzID0gbG9nLkdldE1lc3NhZ2VzKEVSUk9SKTsKKyAgfQorCisgIEFTU0VSVF9FUSgyLCBlcnJvcnMuc2l6ZSgpKTsKKworICBFWFBFQ1RfRVEoIkludmFsaWQgcHJvdG8gZGVzY3JpcHRvciBmb3IgZmlsZSBcImZvby5wcm90b1wiOiIsIGVycm9yc1swXSk7CisgIEVYUEVDVF9FUSgiICBGb286IFwiRm9vXCIgaXMgYWxyZWFkeSBkZWZpbmVkLiIsIGVycm9yc1sxXSk7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBEaXNhbGxvd0VudW1BbGlhcykgeworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAiZW51bV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJCYXJcIiIKKyAgICAiICB2YWx1ZSB7IG5hbWU6XCJFTlVNX0FcIiBudW1iZXI6MCB9IgorICAgICIgIHZhbHVlIHsgbmFtZTpcIkVOVU1fQlwiIG51bWJlcjowIH0iCisgICAgIn0iLAorICAgICJmb28ucHJvdG86IEJhcjogTlVNQkVSOiAiCisgICAgIlwiRU5VTV9CXCIgdXNlcyB0aGUgc2FtZSBlbnVtIHZhbHVlIGFzIFwiRU5VTV9BXCIuICIKKyAgICAiSWYgdGhpcyBpcyBpbnRlbmRlZCwgc2V0ICdvcHRpb24gYWxsb3dfYWxpYXMgPSB0cnVlOycgdG8gdGhlIGVudW0gIgorICAgICJkZWZpbml0aW9uLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBBbGxvd0VudW1BbGlhcykgeworICBCdWlsZEZpbGUoCisgICAgIm5hbWU6IFwiZm9vLnByb3RvXCIgIgorICAgICJlbnVtX3R5cGUgeyIKKyAgICAiICBuYW1lOiBcIkJhclwiIgorICAgICIgIHZhbHVlIHsgbmFtZTpcIkVOVU1fQVwiIG51bWJlcjowIH0iCisgICAgIiAgdmFsdWUgeyBuYW1lOlwiRU5VTV9CXCIgbnVtYmVyOjAgfSIKKyAgICAiICBvcHRpb25zIHsgYWxsb3dfYWxpYXM6IHRydWUgfSIKKyAgICAifSIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgVW51c2VkSW1wb3J0V2FybmluZykgeworICBwb29sXy5BZGRVbnVzZWRJbXBvcnRUcmFja0ZpbGUoImJhci5wcm90byIpOworICBCdWlsZEZpbGUoCisgICAgIm5hbWU6IFwiYmFyLnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyBuYW1lOiBcIkJhclwiIH0iKTsKKworICBwb29sXy5BZGRVbnVzZWRJbXBvcnRUcmFja0ZpbGUoImJhc2UucHJvdG8iKTsKKyAgQnVpbGRGaWxlKAorICAgICJuYW1lOiBcImJhc2UucHJvdG9cIiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IG5hbWU6IFwiQmFzZVwiIH0iKTsKKworICBwb29sXy5BZGRVbnVzZWRJbXBvcnRUcmFja0ZpbGUoImJhei5wcm90byIpOworICBCdWlsZEZpbGUoCisgICAgIm5hbWU6IFwiYmF6LnByb3RvXCIgIgorICAgICJtZXNzYWdlX3R5cGUgeyBuYW1lOiBcIkJhelwiIH0iKTsKKworICBwb29sXy5BZGRVbnVzZWRJbXBvcnRUcmFja0ZpbGUoInB1YmxpYy5wcm90byIpOworICBCdWlsZEZpbGUoCisgICAgIm5hbWU6IFwicHVibGljLnByb3RvXCIgIgorICAgICJkZXBlbmRlbmN5OiBcImJhci5wcm90b1wiIgorICAgICJwdWJsaWNfZGVwZW5kZW5jeTogMCIpOworCisgIC8vIC8vIGZvcndhcmQucHJvdG8KKyAgLy8gaW1wb3J0ICJiYXNlLnByb3RvIiAgICAgICAvLyBObyB3YXJuaW5nOiBCYXNlIG1lc3NhZ2UgaXMgdXNlZC4KKyAgLy8gaW1wb3J0ICJiYXIucHJvdG8iICAgICAgICAvLyBXaWxsIGxvZyBhIHdhcm5pbmcuCisgIC8vIGltcG9ydCBwdWJsaWMgImJhei5wcm90byIgLy8gTm8gd2FybmluZzogRG8gbm90IHRyYWNrIGltcG9ydCBwdWJsaWMuCisgIC8vIGltcG9ydCAicHVibGljLnByb3RvIiAgICAgLy8gTm8gd2FybmluZzogcHVibGljLnByb3RvIGhhcyBpbXBvcnQgcHVibGljLgorICAvLyBtZXNzYWdlIEZvcndhcmQgeworICAvLyAgIG9wdGlvbmFsIEJhc2UgYmFzZSA9IDE7CisgIC8vIH0KKyAgLy8KKyAgcG9vbF8uQWRkVW51c2VkSW1wb3J0VHJhY2tGaWxlKCJmb3J3YXJkLnByb3RvIik7CisgIEJ1aWxkRmlsZVdpdGhXYXJuaW5ncygKKyAgICAibmFtZTogXCJmb3J3YXJkLnByb3RvXCIiCisgICAgImRlcGVuZGVuY3k6IFwiYmFzZS5wcm90b1wiIgorICAgICJkZXBlbmRlbmN5OiBcImJhci5wcm90b1wiIgorICAgICJkZXBlbmRlbmN5OiBcImJhei5wcm90b1wiIgorICAgICJkZXBlbmRlbmN5OiBcInB1YmxpYy5wcm90b1wiIgorICAgICJwdWJsaWNfZGVwZW5kZW5jeTogMiAiCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6IFwiRm9yd2FyZFwiIgorICAgICIgIGZpZWxkIHsgbmFtZTpcImJhc2VcIiBudW1iZXI6MSBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlX25hbWU6XCJCYXNlXCIgfSIKKyAgICAifSIsCisgICAgImZvcndhcmQucHJvdG86IGJhci5wcm90bzogT1RIRVI6IEltcG9ydCBiYXIucHJvdG8gYnV0IG5vdCB1c2VkLlxuIik7Cit9CisKK25hbWVzcGFjZSB7Cit2b2lkIEZpbGxWYWxpZE1hcEVudHJ5KEZpbGVEZXNjcmlwdG9yUHJvdG8qIGZpbGVfcHJvdG8pIHsKKyAgQVNTRVJUX1RSVUUoVGV4dEZvcm1hdDo6UGFyc2VGcm9tU3RyaW5nKAorICAgICAgIm5hbWU6ICdmb28ucHJvdG8nICIKKyAgICAgICJtZXNzYWdlX3R5cGUgeyAiCisgICAgICAiICBuYW1lOiAnRm9vJyAiCisgICAgICAiICBmaWVsZCB7ICIKKyAgICAgICIgICAgbmFtZTogJ2Zvb19tYXAnIG51bWJlcjogMSBsYWJlbDpMQUJFTF9SRVBFQVRFRCAiCisgICAgICAiICAgIHR5cGVfbmFtZTogJ0Zvb01hcEVudHJ5JyAiCisgICAgICAiICB9ICIKKyAgICAgICIgIG5lc3RlZF90eXBlIHsgIgorICAgICAgIiAgICBuYW1lOiAnRm9vTWFwRW50cnknICIKKyAgICAgICIgICAgb3B0aW9ucyB7ICBtYXBfZW50cnk6IHRydWUgfSAiCisgICAgICAiICAgIGZpZWxkIHsgIgorICAgICAgIiAgICAgIG5hbWU6ICdrZXknIG51bWJlcjogMSB0eXBlOlRZUEVfSU5UMzIgbGFiZWw6TEFCRUxfT1BUSU9OQUwgIgorICAgICAgIiAgICB9ICIKKyAgICAgICIgICAgZmllbGQgeyAiCisgICAgICAiICAgICAgbmFtZTogJ3ZhbHVlJyBudW1iZXI6IDIgdHlwZTpUWVBFX0lOVDMyIGxhYmVsOkxBQkVMX09QVElPTkFMICIKKyAgICAgICIgICAgfSAiCisgICAgICAiICB9ICIKKyAgICAgICJ9ICIKKyAgICAgICJtZXNzYWdlX3R5cGUgeyAiCisgICAgICAiICBuYW1lOiAnQmFyJyAiCisgICAgICAiICBleHRlbnNpb25fcmFuZ2UgeyBzdGFydDogMSBlbmQ6IDEwIH0iCisgICAgICAifSAiLAorICAgICAgZmlsZV9wcm90bykpOworfQorc3RhdGljIGNvbnN0IGNoYXIqIGtNYXBFbnRyeUVycm9yTWVzc2FnZSA9CisgICAgImZvby5wcm90bzogRm9vLmZvb19tYXA6IE9USEVSOiBtYXBfZW50cnkgc2hvdWxkIG5vdCBiZSBzZXQgZXhwbGljaXRseS4gIgorICAgICJVc2UgbWFwPEtleVR5cGUsIFZhbHVlVHlwZT4gaW5zdGVhZC5cbiI7CitzdGF0aWMgY29uc3QgY2hhcioga01hcEVudHJ5S2V5VHlwZUVycm9yTWVzc2FnZSA9CisgICAgImZvby5wcm90bzogRm9vLmZvb19tYXA6IFRZUEU6IEtleSBpbiBtYXAgZmllbGRzIGNhbm5vdCBiZSBmbG9hdC9kb3VibGUsICIKKyAgICAiYnl0ZXMgb3IgbWVzc2FnZSB0eXBlcy5cbiI7CisKK30gIC8vIG5hbWVzcGFjZQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgTWFwRW50cnlCYXNlKSB7CisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZV9wcm90bzsKKyAgRmlsbFZhbGlkTWFwRW50cnkoJmZpbGVfcHJvdG8pOworICBCdWlsZEZpbGUoZmlsZV9wcm90by5EZWJ1Z1N0cmluZygpKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIE1hcEVudHJ5RXh0ZW5zaW9uUmFuZ2UpIHsKKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICBGaWxsVmFsaWRNYXBFbnRyeSgmZmlsZV9wcm90byk7CisgIFRleHRGb3JtYXQ6Ok1lcmdlRnJvbVN0cmluZygKKyAgICAgICJleHRlbnNpb25fcmFuZ2UgeyAiCisgICAgICAiICBzdGFydDogMTAgZW5kOiAyMCAiCisgICAgICAifSAiLAorICAgICAgZmlsZV9wcm90by5tdXRhYmxlX21lc3NhZ2VfdHlwZSgwKS0+bXV0YWJsZV9uZXN0ZWRfdHlwZSgwKSk7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoZmlsZV9wcm90by5EZWJ1Z1N0cmluZygpLCBrTWFwRW50cnlFcnJvck1lc3NhZ2UpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgTWFwRW50cnlFeHRlbnNpb24pIHsKKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICBGaWxsVmFsaWRNYXBFbnRyeSgmZmlsZV9wcm90byk7CisgIFRleHRGb3JtYXQ6Ok1lcmdlRnJvbVN0cmluZygKKyAgICAgICJleHRlbnNpb24geyAiCisgICAgICAiICBuYW1lOiAnZm9vX2V4dCcgZXh0ZW5kZWU6ICcuQmFyJyBudW1iZXI6IDUiCisgICAgICAifSAiLAorICAgICAgZmlsZV9wcm90by5tdXRhYmxlX21lc3NhZ2VfdHlwZSgwKS0+bXV0YWJsZV9uZXN0ZWRfdHlwZSgwKSk7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoZmlsZV9wcm90by5EZWJ1Z1N0cmluZygpLCBrTWFwRW50cnlFcnJvck1lc3NhZ2UpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgTWFwRW50cnlOZXN0ZWRUeXBlKSB7CisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZV9wcm90bzsKKyAgRmlsbFZhbGlkTWFwRW50cnkoJmZpbGVfcHJvdG8pOworICBUZXh0Rm9ybWF0OjpNZXJnZUZyb21TdHJpbmcoCisgICAgICAibmVzdGVkX3R5cGUgeyAiCisgICAgICAiICBuYW1lOiAnQmFyJyAiCisgICAgICAifSAiLAorICAgICAgZmlsZV9wcm90by5tdXRhYmxlX21lc3NhZ2VfdHlwZSgwKS0+bXV0YWJsZV9uZXN0ZWRfdHlwZSgwKSk7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoZmlsZV9wcm90by5EZWJ1Z1N0cmluZygpLCBrTWFwRW50cnlFcnJvck1lc3NhZ2UpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgTWFwRW50cnlFbnVtVHlwZXMpIHsKKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICBGaWxsVmFsaWRNYXBFbnRyeSgmZmlsZV9wcm90byk7CisgIFRleHRGb3JtYXQ6Ok1lcmdlRnJvbVN0cmluZygKKyAgICAgICJlbnVtX3R5cGUgeyAiCisgICAgICAiICBuYW1lOiAnQmFyRW51bScgIgorICAgICAgIiAgdmFsdWUgeyBuYW1lOiAnQkFSX0JBUicgbnVtYmVyOjAgfSAiCisgICAgICAifSAiLAorICAgICAgZmlsZV9wcm90by5tdXRhYmxlX21lc3NhZ2VfdHlwZSgwKS0+bXV0YWJsZV9uZXN0ZWRfdHlwZSgwKSk7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoZmlsZV9wcm90by5EZWJ1Z1N0cmluZygpLCBrTWFwRW50cnlFcnJvck1lc3NhZ2UpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgTWFwRW50cnlFeHRyYUZpZWxkKSB7CisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZV9wcm90bzsKKyAgRmlsbFZhbGlkTWFwRW50cnkoJmZpbGVfcHJvdG8pOworICBUZXh0Rm9ybWF0OjpNZXJnZUZyb21TdHJpbmcoCisgICAgICAiZmllbGQgeyAiCisgICAgICAiICBuYW1lOiAnb3RoZXJfZmllbGQnICIKKyAgICAgICIgIGxhYmVsOiBMQUJFTF9PUFRJT05BTCAiCisgICAgICAiICB0eXBlOiBUWVBFX0lOVDMyICIKKyAgICAgICIgIG51bWJlcjogMyAiCisgICAgICAifSAiLAorICAgICAgZmlsZV9wcm90by5tdXRhYmxlX21lc3NhZ2VfdHlwZSgwKS0+bXV0YWJsZV9uZXN0ZWRfdHlwZSgwKSk7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoZmlsZV9wcm90by5EZWJ1Z1N0cmluZygpLCBrTWFwRW50cnlFcnJvck1lc3NhZ2UpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgTWFwRW50cnlNZXNzYWdlTmFtZSkgeworICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGVfcHJvdG87CisgIEZpbGxWYWxpZE1hcEVudHJ5KCZmaWxlX3Byb3RvKTsKKyAgZmlsZV9wcm90by5tdXRhYmxlX21lc3NhZ2VfdHlwZSgwKS0+bXV0YWJsZV9uZXN0ZWRfdHlwZSgwKS0+c2V0X25hbWUoCisgICAgICAiT3RoZXJNYXBFbnRyeSIpOworICBmaWxlX3Byb3RvLm11dGFibGVfbWVzc2FnZV90eXBlKDApLT5tdXRhYmxlX2ZpZWxkKDApLT5zZXRfdHlwZV9uYW1lKAorICAgICAgIk90aGVyTWFwRW50cnkiKTsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycyhmaWxlX3Byb3RvLkRlYnVnU3RyaW5nKCksIGtNYXBFbnRyeUVycm9yTWVzc2FnZSk7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBNYXBFbnRyeU5vbmVSZXBlYXRlZE1hcEVudHJ5KSB7CisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZV9wcm90bzsKKyAgRmlsbFZhbGlkTWFwRW50cnkoJmZpbGVfcHJvdG8pOworICBmaWxlX3Byb3RvLm11dGFibGVfbWVzc2FnZV90eXBlKDApLT5tdXRhYmxlX2ZpZWxkKDApLT5zZXRfbGFiZWwoCisgICAgICBGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfT1BUSU9OQUwpOworICBCdWlsZEZpbGVXaXRoRXJyb3JzKGZpbGVfcHJvdG8uRGVidWdTdHJpbmcoKSwga01hcEVudHJ5RXJyb3JNZXNzYWdlKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIE1hcEVudHJ5RGlmZmVyZW50Q29udGFpbmluZ1R5cGUpIHsKKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICBGaWxsVmFsaWRNYXBFbnRyeSgmZmlsZV9wcm90byk7CisgIC8vIE1vdmUgdGhlIG5lc3RlZCBNYXBFbnRyeSBtZXNzYWdlIGludG8gdGhlIHRvcCBsZXZlbCwgd2hpY2ggc2hvdWxkIG5vdCBwYXNzCisgIC8vIHRoZSB2YWxpZGF0aW9uLgorICBmaWxlX3Byb3RvLm11dGFibGVfbWVzc2FnZV90eXBlKCktPkFkZEFsbG9jYXRlZCgKKyAgICAgIGZpbGVfcHJvdG8ubXV0YWJsZV9tZXNzYWdlX3R5cGUoMCktPm11dGFibGVfbmVzdGVkX3R5cGUoKS0+UmVsZWFzZUxhc3QoKSk7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoZmlsZV9wcm90by5EZWJ1Z1N0cmluZygpLCBrTWFwRW50cnlFcnJvck1lc3NhZ2UpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgTWFwRW50cnlLZXlOYW1lKSB7CisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZV9wcm90bzsKKyAgRmlsbFZhbGlkTWFwRW50cnkoJmZpbGVfcHJvdG8pOworICBGaWVsZERlc2NyaXB0b3JQcm90byoga2V5ID0gZmlsZV9wcm90by5tdXRhYmxlX21lc3NhZ2VfdHlwZSgwKQorICAgICAgLT5tdXRhYmxlX25lc3RlZF90eXBlKDApCisgICAgICAtPm11dGFibGVfZmllbGQoMCk7CisgIGtleS0+c2V0X25hbWUoIktleSIpOworICBCdWlsZEZpbGVXaXRoRXJyb3JzKGZpbGVfcHJvdG8uRGVidWdTdHJpbmcoKSwga01hcEVudHJ5RXJyb3JNZXNzYWdlKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIE1hcEVudHJ5S2V5TGFiZWwpIHsKKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICBGaWxsVmFsaWRNYXBFbnRyeSgmZmlsZV9wcm90byk7CisgIEZpZWxkRGVzY3JpcHRvclByb3RvKiBrZXkgPSBmaWxlX3Byb3RvLm11dGFibGVfbWVzc2FnZV90eXBlKDApCisgICAgICAtPm11dGFibGVfbmVzdGVkX3R5cGUoMCkKKyAgICAgIC0+bXV0YWJsZV9maWVsZCgwKTsKKyAga2V5LT5zZXRfbGFiZWwoRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX1JFUVVJUkVEKTsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycyhmaWxlX3Byb3RvLkRlYnVnU3RyaW5nKCksIGtNYXBFbnRyeUVycm9yTWVzc2FnZSk7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBNYXBFbnRyeUtleU51bWJlcikgeworICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGVfcHJvdG87CisgIEZpbGxWYWxpZE1hcEVudHJ5KCZmaWxlX3Byb3RvKTsKKyAgRmllbGREZXNjcmlwdG9yUHJvdG8qIGtleSA9IGZpbGVfcHJvdG8ubXV0YWJsZV9tZXNzYWdlX3R5cGUoMCkKKyAgICAgIC0+bXV0YWJsZV9uZXN0ZWRfdHlwZSgwKQorICAgICAgLT5tdXRhYmxlX2ZpZWxkKDApOworICBrZXktPnNldF9udW1iZXIoMyk7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoZmlsZV9wcm90by5EZWJ1Z1N0cmluZygpLCBrTWFwRW50cnlFcnJvck1lc3NhZ2UpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgTWFwRW50cnlWYWx1ZU5hbWUpIHsKKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICBGaWxsVmFsaWRNYXBFbnRyeSgmZmlsZV9wcm90byk7CisgIEZpZWxkRGVzY3JpcHRvclByb3RvKiB2YWx1ZSA9IGZpbGVfcHJvdG8ubXV0YWJsZV9tZXNzYWdlX3R5cGUoMCkKKyAgICAgIC0+bXV0YWJsZV9uZXN0ZWRfdHlwZSgwKQorICAgICAgLT5tdXRhYmxlX2ZpZWxkKDEpOworICB2YWx1ZS0+c2V0X25hbWUoIlZhbHVlIik7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoZmlsZV9wcm90by5EZWJ1Z1N0cmluZygpLCBrTWFwRW50cnlFcnJvck1lc3NhZ2UpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgTWFwRW50cnlWYWx1ZUxhYmVsKSB7CisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZV9wcm90bzsKKyAgRmlsbFZhbGlkTWFwRW50cnkoJmZpbGVfcHJvdG8pOworICBGaWVsZERlc2NyaXB0b3JQcm90byogdmFsdWUgPSBmaWxlX3Byb3RvLm11dGFibGVfbWVzc2FnZV90eXBlKDApCisgICAgICAtPm11dGFibGVfbmVzdGVkX3R5cGUoMCkKKyAgICAgIC0+bXV0YWJsZV9maWVsZCgxKTsKKyAgdmFsdWUtPnNldF9sYWJlbChGaWVsZERlc2NyaXB0b3JQcm90bzo6TEFCRUxfUkVRVUlSRUQpOworICBCdWlsZEZpbGVXaXRoRXJyb3JzKGZpbGVfcHJvdG8uRGVidWdTdHJpbmcoKSwga01hcEVudHJ5RXJyb3JNZXNzYWdlKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIE1hcEVudHJ5VmFsdWVOdW1iZXIpIHsKKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICBGaWxsVmFsaWRNYXBFbnRyeSgmZmlsZV9wcm90byk7CisgIEZpZWxkRGVzY3JpcHRvclByb3RvKiB2YWx1ZSA9IGZpbGVfcHJvdG8ubXV0YWJsZV9tZXNzYWdlX3R5cGUoMCkKKyAgICAgIC0+bXV0YWJsZV9uZXN0ZWRfdHlwZSgwKQorICAgICAgLT5tdXRhYmxlX2ZpZWxkKDEpOworICB2YWx1ZS0+c2V0X251bWJlcigzKTsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycyhmaWxlX3Byb3RvLkRlYnVnU3RyaW5nKCksIGtNYXBFbnRyeUVycm9yTWVzc2FnZSk7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBNYXBFbnRyeUtleVR5cGVGbG9hdCkgeworICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGVfcHJvdG87CisgIEZpbGxWYWxpZE1hcEVudHJ5KCZmaWxlX3Byb3RvKTsKKyAgRmllbGREZXNjcmlwdG9yUHJvdG8qIGtleSA9IGZpbGVfcHJvdG8ubXV0YWJsZV9tZXNzYWdlX3R5cGUoMCkKKyAgICAgIC0+bXV0YWJsZV9uZXN0ZWRfdHlwZSgwKQorICAgICAgLT5tdXRhYmxlX2ZpZWxkKDApOworICBrZXktPnNldF90eXBlKEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0ZMT0FUKTsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycyhmaWxlX3Byb3RvLkRlYnVnU3RyaW5nKCksIGtNYXBFbnRyeUtleVR5cGVFcnJvck1lc3NhZ2UpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgTWFwRW50cnlLZXlUeXBlRG91YmxlKSB7CisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZV9wcm90bzsKKyAgRmlsbFZhbGlkTWFwRW50cnkoJmZpbGVfcHJvdG8pOworICBGaWVsZERlc2NyaXB0b3JQcm90byoga2V5ID0gZmlsZV9wcm90by5tdXRhYmxlX21lc3NhZ2VfdHlwZSgwKQorICAgICAgLT5tdXRhYmxlX25lc3RlZF90eXBlKDApCisgICAgICAtPm11dGFibGVfZmllbGQoMCk7CisgIGtleS0+c2V0X3R5cGUoRmllbGREZXNjcmlwdG9yUHJvdG86OlRZUEVfRE9VQkxFKTsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycyhmaWxlX3Byb3RvLkRlYnVnU3RyaW5nKCksIGtNYXBFbnRyeUtleVR5cGVFcnJvck1lc3NhZ2UpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgTWFwRW50cnlLZXlUeXBlQnl0ZXMpIHsKKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICBGaWxsVmFsaWRNYXBFbnRyeSgmZmlsZV9wcm90byk7CisgIEZpZWxkRGVzY3JpcHRvclByb3RvKiBrZXkgPSBmaWxlX3Byb3RvLm11dGFibGVfbWVzc2FnZV90eXBlKDApCisgICAgICAtPm11dGFibGVfbmVzdGVkX3R5cGUoMCkKKyAgICAgIC0+bXV0YWJsZV9maWVsZCgwKTsKKyAga2V5LT5zZXRfdHlwZShGaWVsZERlc2NyaXB0b3JQcm90bzo6VFlQRV9CWVRFUyk7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoZmlsZV9wcm90by5EZWJ1Z1N0cmluZygpLCBrTWFwRW50cnlLZXlUeXBlRXJyb3JNZXNzYWdlKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIE1hcEVudHJ5S2V5VHlwZUVudW0pIHsKKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX3Byb3RvOworICBGaWxsVmFsaWRNYXBFbnRyeSgmZmlsZV9wcm90byk7CisgIEZpZWxkRGVzY3JpcHRvclByb3RvKiBrZXkgPSBmaWxlX3Byb3RvLm11dGFibGVfbWVzc2FnZV90eXBlKDApCisgICAgICAtPm11dGFibGVfbmVzdGVkX3R5cGUoMCkKKyAgICAgIC0+bXV0YWJsZV9maWVsZCgwKTsKKyAga2V5LT5jbGVhcl90eXBlKCk7CisgIGtleS0+c2V0X3R5cGVfbmFtZSgiQmFyRW51bSIpOworICBFbnVtRGVzY3JpcHRvclByb3RvKiBlbnVtX3Byb3RvID0gZmlsZV9wcm90by5hZGRfZW51bV90eXBlKCk7CisgIGVudW1fcHJvdG8tPnNldF9uYW1lKCJCYXJFbnVtIik7CisgIEVudW1WYWx1ZURlc2NyaXB0b3JQcm90byogZW51bV92YWx1ZV9wcm90byA9IGVudW1fcHJvdG8tPmFkZF92YWx1ZSgpOworICBlbnVtX3ZhbHVlX3Byb3RvLT5zZXRfbmFtZSgiQkFSX1ZBTFVFMCIpOworICBlbnVtX3ZhbHVlX3Byb3RvLT5zZXRfbnVtYmVyKDApOworICBCdWlsZEZpbGVXaXRoRXJyb3JzKGZpbGVfcHJvdG8uRGVidWdTdHJpbmcoKSwKKyAgICAgICAgICAgICAgICAgICAgICAiZm9vLnByb3RvOiBGb28uZm9vX21hcDogVFlQRTogS2V5IGluIG1hcCBmaWVsZHMgY2Fubm90ICIKKyAgICAgICAgICAgICAgICAgICAgICAiYmUgZW51bSB0eXBlcy5cbiIpOworICAvLyBFbnVtIGtleXMgYXJlIG5vdCBhbGxvd2VkIGluIHByb3RvMyBhcyB3ZWxsLgorICAvLyBHZXQgcmlkIG9mIGV4dGVuc2lvbnMgZm9yIHByb3RvMyB0byBtYWtlIGl0IHByb3RvMyBjb21wYXRpYmxlLgorICBmaWxlX3Byb3RvLm11dGFibGVfbWVzc2FnZV90eXBlKCktPlJlbW92ZUxhc3QoKTsKKyAgZmlsZV9wcm90by5zZXRfc3ludGF4KCJwcm90bzMiKTsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycyhmaWxlX3Byb3RvLkRlYnVnU3RyaW5nKCksCisgICAgICAgICAgICAgICAgICAgICAgImZvby5wcm90bzogRm9vLmZvb19tYXA6IFRZUEU6IEtleSBpbiBtYXAgZmllbGRzIGNhbm5vdCAiCisgICAgICAgICAgICAgICAgICAgICAgImJlIGVudW0gdHlwZXMuXG4iKTsKK30KKworCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgTWFwRW50cnlLZXlUeXBlTWVzc2FnZSkgeworICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGVfcHJvdG87CisgIEZpbGxWYWxpZE1hcEVudHJ5KCZmaWxlX3Byb3RvKTsKKyAgRmllbGREZXNjcmlwdG9yUHJvdG8qIGtleSA9IGZpbGVfcHJvdG8ubXV0YWJsZV9tZXNzYWdlX3R5cGUoMCkKKyAgICAgIC0+bXV0YWJsZV9uZXN0ZWRfdHlwZSgwKQorICAgICAgLT5tdXRhYmxlX2ZpZWxkKDApOworICBrZXktPmNsZWFyX3R5cGUoKTsKKyAga2V5LT5zZXRfdHlwZV9uYW1lKCIuQmFyIik7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoZmlsZV9wcm90by5EZWJ1Z1N0cmluZygpLCBrTWFwRW50cnlLZXlUeXBlRXJyb3JNZXNzYWdlKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIE1hcEVudHJ5Q29uZmxpY3RzV2l0aEZpZWxkKSB7CisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZV9wcm90bzsKKyAgRmlsbFZhbGlkTWFwRW50cnkoJmZpbGVfcHJvdG8pOworICBUZXh0Rm9ybWF0OjpNZXJnZUZyb21TdHJpbmcoCisgICAgICAiZmllbGQgeyAiCisgICAgICAiICBuYW1lOiAnRm9vTWFwRW50cnknICIKKyAgICAgICIgIHR5cGU6IFRZUEVfSU5UMzIgIgorICAgICAgIiAgbGFiZWw6IExBQkVMX09QVElPTkFMICIKKyAgICAgICIgIG51bWJlcjogMTAwICIKKyAgICAgICJ9IiwKKyAgICAgIGZpbGVfcHJvdG8ubXV0YWJsZV9tZXNzYWdlX3R5cGUoMCkpOworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICAgZmlsZV9wcm90by5EZWJ1Z1N0cmluZygpLAorICAgICAgImZvby5wcm90bzogRm9vLkZvb01hcEVudHJ5OiBOQU1FOiBcIkZvb01hcEVudHJ5XCIgaXMgYWxyZWFkeSBkZWZpbmVkIGluICIKKyAgICAgICJcIkZvb1wiLlxuIgorICAgICAgImZvby5wcm90bzogRm9vLmZvb19tYXA6IFRZUEU6IFwiRm9vTWFwRW50cnlcIiBpcyBub3QgZGVmaW5lZC5cbiIKKyAgICAgICJmb28ucHJvdG86IEZvbzogTkFNRTogRXhwYW5kZWQgbWFwIGVudHJ5IHR5cGUgRm9vTWFwRW50cnkgY29uZmxpY3RzICIKKyAgICAgICJ3aXRoIGFuIGV4aXN0aW5nIGZpZWxkLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBNYXBFbnRyeUNvbmZsaWN0c1dpdGhNZXNzYWdlKSB7CisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZV9wcm90bzsKKyAgRmlsbFZhbGlkTWFwRW50cnkoJmZpbGVfcHJvdG8pOworICBUZXh0Rm9ybWF0OjpNZXJnZUZyb21TdHJpbmcoCisgICAgICAibmVzdGVkX3R5cGUgeyAiCisgICAgICAiICBuYW1lOiAnRm9vTWFwRW50cnknICIKKyAgICAgICJ9IiwKKyAgICAgIGZpbGVfcHJvdG8ubXV0YWJsZV9tZXNzYWdlX3R5cGUoMCkpOworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICAgZmlsZV9wcm90by5EZWJ1Z1N0cmluZygpLAorICAgICAgImZvby5wcm90bzogRm9vLkZvb01hcEVudHJ5OiBOQU1FOiBcIkZvb01hcEVudHJ5XCIgaXMgYWxyZWFkeSBkZWZpbmVkIGluICIKKyAgICAgICJcIkZvb1wiLlxuIgorICAgICAgImZvby5wcm90bzogRm9vOiBOQU1FOiBFeHBhbmRlZCBtYXAgZW50cnkgdHlwZSBGb29NYXBFbnRyeSBjb25mbGljdHMgIgorICAgICAgIndpdGggYW4gZXhpc3RpbmcgbmVzdGVkIG1lc3NhZ2UgdHlwZS5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgTWFwRW50cnlDb25mbGljdHNXaXRoRW51bSkgeworICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGVfcHJvdG87CisgIEZpbGxWYWxpZE1hcEVudHJ5KCZmaWxlX3Byb3RvKTsKKyAgVGV4dEZvcm1hdDo6TWVyZ2VGcm9tU3RyaW5nKAorICAgICAgImVudW1fdHlwZSB7ICIKKyAgICAgICIgIG5hbWU6ICdGb29NYXBFbnRyeScgIgorICAgICAgIiAgdmFsdWUgeyBuYW1lOiAnRU5UUllfRk9PJyBudW1iZXI6IDAgfSIKKyAgICAgICJ9IiwKKyAgICAgIGZpbGVfcHJvdG8ubXV0YWJsZV9tZXNzYWdlX3R5cGUoMCkpOworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICAgZmlsZV9wcm90by5EZWJ1Z1N0cmluZygpLAorICAgICAgImZvby5wcm90bzogRm9vLkZvb01hcEVudHJ5OiBOQU1FOiBcIkZvb01hcEVudHJ5XCIgaXMgYWxyZWFkeSBkZWZpbmVkIGluICIKKyAgICAgICJcIkZvb1wiLlxuIgorICAgICAgImZvby5wcm90bzogRm9vOiBOQU1FOiBFeHBhbmRlZCBtYXAgZW50cnkgdHlwZSBGb29NYXBFbnRyeSBjb25mbGljdHMgIgorICAgICAgIndpdGggYW4gZXhpc3RpbmcgZW51bSB0eXBlLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBNYXBFbnRyeUNvbmZsaWN0c1dpdGhPbmVvZikgeworICBGaWxlRGVzY3JpcHRvclByb3RvIGZpbGVfcHJvdG87CisgIEZpbGxWYWxpZE1hcEVudHJ5KCZmaWxlX3Byb3RvKTsKKyAgVGV4dEZvcm1hdDo6TWVyZ2VGcm9tU3RyaW5nKAorICAgICAgIm9uZW9mX2RlY2wgeyAiCisgICAgICAiICBuYW1lOiAnRm9vTWFwRW50cnknICIKKyAgICAgICJ9IgorICAgICAgImZpZWxkIHsgIgorICAgICAgIiAgbmFtZTogJ2ludF9maWVsZCcgIgorICAgICAgIiAgdHlwZTogVFlQRV9JTlQzMiAiCisgICAgICAiICBsYWJlbDogTEFCRUxfT1BUSU9OQUwgIgorICAgICAgIiAgb25lb2ZfaW5kZXg6IDAgIgorICAgICAgIiAgbnVtYmVyOiAxMDAgIgorICAgICAgIn0gIiwKKyAgICAgIGZpbGVfcHJvdG8ubXV0YWJsZV9tZXNzYWdlX3R5cGUoMCkpOworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICAgZmlsZV9wcm90by5EZWJ1Z1N0cmluZygpLAorICAgICAgImZvby5wcm90bzogRm9vLkZvb01hcEVudHJ5OiBOQU1FOiBcIkZvb01hcEVudHJ5XCIgaXMgYWxyZWFkeSBkZWZpbmVkIGluICIKKyAgICAgICJcIkZvb1wiLlxuIgorICAgICAgImZvby5wcm90bzogRm9vLmZvb19tYXA6IFRZUEU6IFwiRm9vTWFwRW50cnlcIiBpcyBub3QgZGVmaW5lZC5cbiIKKyAgICAgICJmb28ucHJvdG86IEZvbzogTkFNRTogRXhwYW5kZWQgbWFwIGVudHJ5IHR5cGUgRm9vTWFwRW50cnkgY29uZmxpY3RzICIKKyAgICAgICJ3aXRoIGFuIGV4aXN0aW5nIG9uZW9mIHR5cGUuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIE1hcEVudHJ5VXNlc05vbmVaZXJvRW51bURlZmF1bHRWYWx1ZSkgeworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICJuYW1lOiBcImZvby5wcm90b1wiICIKKyAgICAiZW51bV90eXBlIHsiCisgICAgIiAgbmFtZTogXCJCYXJcIiIKKyAgICAiICB2YWx1ZSB7IG5hbWU6XCJFTlVNX0FcIiBudW1iZXI6MSB9IgorICAgICIgIHZhbHVlIHsgbmFtZTpcIkVOVU1fQlwiIG51bWJlcjoyIH0iCisgICAgIn0iCisgICAgIm1lc3NhZ2VfdHlwZSB7IgorICAgICIgIG5hbWU6ICdGb28nICIKKyAgICAiICBmaWVsZCB7ICIKKyAgICAiICAgIG5hbWU6ICdmb29fbWFwJyBudW1iZXI6IDEgbGFiZWw6TEFCRUxfUkVQRUFURUQgIgorICAgICIgICAgdHlwZV9uYW1lOiAnRm9vTWFwRW50cnknICIKKyAgICAiICB9ICIKKyAgICAiICBuZXN0ZWRfdHlwZSB7ICIKKyAgICAiICAgIG5hbWU6ICdGb29NYXBFbnRyeScgIgorICAgICIgICAgb3B0aW9ucyB7ICBtYXBfZW50cnk6IHRydWUgfSAiCisgICAgIiAgICBmaWVsZCB7ICIKKyAgICAiICAgICAgbmFtZTogJ2tleScgbnVtYmVyOiAxIHR5cGU6VFlQRV9JTlQzMiBsYWJlbDpMQUJFTF9PUFRJT05BTCAiCisgICAgIiAgICB9ICIKKyAgICAiICAgIGZpZWxkIHsgIgorICAgICIgICAgICBuYW1lOiAndmFsdWUnIG51bWJlcjogMiB0eXBlX25hbWU6XCJCYXJcIiBsYWJlbDpMQUJFTF9PUFRJT05BTCAiCisgICAgIiAgICB9ICIKKyAgICAiICB9ICIKKyAgICAifSIsCisgICAgImZvby5wcm90bzogRm9vLmZvb19tYXA6ICIKKyAgICAiVFlQRTogRW51bSB2YWx1ZSBpbiBtYXAgbXVzdCBkZWZpbmUgMCBhcyB0aGUgZmlyc3QgdmFsdWUuXG4iKTsKK30KKworVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIFByb3RvM1JlcXVpcmVkRmllbGRzKSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgICAibmFtZTogJ2Zvby5wcm90bycgIgorICAgICAgInN5bnRheDogJ3Byb3RvMycgIgorICAgICAgIm1lc3NhZ2VfdHlwZSB7ICIKKyAgICAgICIgIG5hbWU6ICdGb28nICIKKyAgICAgICIgIGZpZWxkIHsgbmFtZTonZm9vJyBudW1iZXI6MSBsYWJlbDpMQUJFTF9SRVFVSVJFRCB0eXBlOlRZUEVfSU5UMzIgfSAiCisgICAgICAifSIsCisgICAgICAiZm9vLnByb3RvOiBGb28uZm9vOiBPVEhFUjogUmVxdWlyZWQgZmllbGRzIGFyZSBub3QgYWxsb3dlZCBpbiAiCisgICAgICAicHJvdG8zLlxuIik7CisKKyAgLy8gYXBwbGllZCB0byBuZXN0ZWQgdHlwZXMgYXMgd2VsbC4KKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAgICJuYW1lOiAnZm9vLnByb3RvJyAiCisgICAgICAic3ludGF4OiAncHJvdG8zJyAiCisgICAgICAibWVzc2FnZV90eXBlIHsgIgorICAgICAgIiAgbmFtZTogJ0ZvbycgIgorICAgICAgIiAgbmVzdGVkX3R5cGUgeyAiCisgICAgICAiICAgIG5hbWUgOiAnQmFyJyAiCisgICAgICAiICAgIGZpZWxkIHsgbmFtZTonYmFyJyBudW1iZXI6MSBsYWJlbDpMQUJFTF9SRVFVSVJFRCB0eXBlOlRZUEVfSU5UMzIgfSAiCisgICAgICAiICB9ICIKKyAgICAgICJ9IiwKKyAgICAgICJmb28ucHJvdG86IEZvby5CYXIuYmFyOiBPVEhFUjogUmVxdWlyZWQgZmllbGRzIGFyZSBub3QgYWxsb3dlZCBpbiAiCisgICAgICAicHJvdG8zLlxuIik7CisKKyAgLy8gb3B0aW9uYWwgYW5kIHJlcGVhdGVkIGZpZWxkcyBhcmUgT0suCisgIEJ1aWxkRmlsZSgKKyAgICAgICJuYW1lOiAnZm9vLnByb3RvJyAiCisgICAgICAic3ludGF4OiAncHJvdG8zJyAiCisgICAgICAibWVzc2FnZV90eXBlIHsgIgorICAgICAgIiAgbmFtZTogJ0ZvbycgIgorICAgICAgIiAgZmllbGQgeyBuYW1lOidmb28nIG51bWJlcjoxIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiB9ICIKKyAgICAgICIgIGZpZWxkIHsgbmFtZTonYmFyJyBudW1iZXI6MiBsYWJlbDpMQUJFTF9SRVBFQVRFRCB0eXBlOlRZUEVfSU5UMzIgfSAiCisgICAgICAifSIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgVmFsaWRhdGVQcm90bzNEZWZhdWx0VmFsdWUpIHsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAgICJuYW1lOiAnZm9vLnByb3RvJyAiCisgICAgICAic3ludGF4OiAncHJvdG8zJyAiCisgICAgICAibWVzc2FnZV90eXBlIHsgIgorICAgICAgIiAgbmFtZTogJ0ZvbycgIgorICAgICAgIiAgZmllbGQgeyBuYW1lOidmb28nIG51bWJlcjoxIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiAiCisgICAgICAiICAgICAgICAgIGRlZmF1bHRfdmFsdWU6ICcxJyB9IgorICAgICAgIn0iLAorICAgICAgImZvby5wcm90bzogRm9vLmZvbzogT1RIRVI6IEV4cGxpY2l0IGRlZmF1bHQgdmFsdWVzIGFyZSBub3QgYWxsb3dlZCBpbiAiCisgICAgICAicHJvdG8zLlxuIik7CisKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAgICJuYW1lOiAnZm9vLnByb3RvJyAiCisgICAgICAic3ludGF4OiAncHJvdG8zJyAiCisgICAgICAibWVzc2FnZV90eXBlIHsgIgorICAgICAgIiAgbmFtZTogJ0ZvbycgIgorICAgICAgIiAgbmVzdGVkX3R5cGUgeyAiCisgICAgICAiICAgIG5hbWUgOiAnQmFyJyAiCisgICAgICAiICAgIGZpZWxkIHsgbmFtZTonYmFyJyBudW1iZXI6MSBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgIgorICAgICAgIiAgICAgICAgICAgIGRlZmF1bHRfdmFsdWU6ICcxJyB9IgorICAgICAgIiAgfSAiCisgICAgICAifSIsCisgICAgICAiZm9vLnByb3RvOiBGb28uQmFyLmJhcjogT1RIRVI6IEV4cGxpY2l0IGRlZmF1bHQgdmFsdWVzIGFyZSBub3QgYWxsb3dlZCAiCisgICAgICAiaW4gcHJvdG8zLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBWYWxpZGF0ZVByb3RvM0V4dGVuc2lvblJhbmdlKSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgICAibmFtZTogJ2Zvby5wcm90bycgIgorICAgICAgInN5bnRheDogJ3Byb3RvMycgIgorICAgICAgIm1lc3NhZ2VfdHlwZSB7ICIKKyAgICAgICIgIG5hbWU6ICdGb28nICIKKyAgICAgICIgIGZpZWxkIHsgbmFtZTonZm9vJyBudW1iZXI6MSBsYWJlbDpMQUJFTF9PUFRJT05BTCB0eXBlOlRZUEVfSU5UMzIgfSAiCisgICAgICAiICBleHRlbnNpb25fcmFuZ2UgeyBzdGFydDoxMCBlbmQ6MTAwIH0gIgorICAgICAgIn0iLAorICAgICAgImZvby5wcm90bzogRm9vOiBPVEhFUjogRXh0ZW5zaW9uIHJhbmdlcyBhcmUgbm90IGFsbG93ZWQgaW4gIgorICAgICAgInByb3RvMy5cbiIpOworCisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgICAibmFtZTogJ2Zvby5wcm90bycgIgorICAgICAgInN5bnRheDogJ3Byb3RvMycgIgorICAgICAgIm1lc3NhZ2VfdHlwZSB7ICIKKyAgICAgICIgIG5hbWU6ICdGb28nICIKKyAgICAgICIgIG5lc3RlZF90eXBlIHsgIgorICAgICAgIiAgICBuYW1lIDogJ0JhcicgIgorICAgICAgIiAgICBmaWVsZCB7IG5hbWU6J2JhcicgbnVtYmVyOjEgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZTpUWVBFX0lOVDMyIH0gIgorICAgICAgIiAgICBleHRlbnNpb25fcmFuZ2UgeyBzdGFydDoxMCBlbmQ6MTAwIH0gIgorICAgICAgIiAgfSAiCisgICAgICAifSIsCisgICAgICAiZm9vLnByb3RvOiBGb28uQmFyOiBPVEhFUjogRXh0ZW5zaW9uIHJhbmdlcyBhcmUgbm90IGFsbG93ZWQgaW4gIgorICAgICAgInByb3RvMy5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgVmFsaWRhdGVQcm90bzNNZXNzYWdlU2V0V2lyZUZvcm1hdCkgeworICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICAgIm5hbWU6ICdmb28ucHJvdG8nICIKKyAgICAgICJzeW50YXg6ICdwcm90bzMnICIKKyAgICAgICJtZXNzYWdlX3R5cGUgeyAiCisgICAgICAiICBuYW1lOiAnRm9vJyAiCisgICAgICAiICBvcHRpb25zIHsgbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQ6IHRydWUgfSAiCisgICAgICAifSIsCisgICAgICAiZm9vLnByb3RvOiBGb286IE9USEVSOiBNZXNzYWdlU2V0IGlzIG5vdCBzdXBwb3J0ZWQgIgorICAgICAgImluIHByb3RvMy5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgVmFsaWRhdGVQcm90bzNFbnVtKSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgICAibmFtZTogJ2Zvby5wcm90bycgIgorICAgICAgInN5bnRheDogJ3Byb3RvMycgIgorICAgICAgImVudW1fdHlwZSB7ICIKKyAgICAgICIgIG5hbWU6ICdGb29FbnVtJyAiCisgICAgICAiICB2YWx1ZSB7IG5hbWU6ICdGT09fRk9PJyBudW1iZXI6MSB9ICIKKyAgICAgICJ9IiwKKyAgICAgICJmb28ucHJvdG86IEZvb0VudW06IE9USEVSOiBUaGUgZmlyc3QgZW51bSB2YWx1ZSBtdXN0IGJlICIKKyAgICAgICJ6ZXJvIGluIHByb3RvMy5cbiIpOworCisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgICAibmFtZTogJ2Zvby5wcm90bycgIgorICAgICAgInN5bnRheDogJ3Byb3RvMycgIgorICAgICAgIm1lc3NhZ2VfdHlwZSB7ICIKKyAgICAgICIgIG5hbWU6ICdGb28nICIKKyAgICAgICIgIGVudW1fdHlwZSB7ICIKKyAgICAgICIgICAgbmFtZTogJ0Zvb0VudW0nICIKKyAgICAgICIgICAgdmFsdWUgeyBuYW1lOiAnRk9PX0ZPTycgbnVtYmVyOjEgfSAiCisgICAgICAiICB9ICIKKyAgICAgICJ9IiwKKyAgICAgICJmb28ucHJvdG86IEZvby5Gb29FbnVtOiBPVEhFUjogVGhlIGZpcnN0IGVudW0gdmFsdWUgbXVzdCBiZSAiCisgICAgICAiemVybyBpbiBwcm90bzMuXG4iKTsKKworICAvLyB2YWxpZCBjYXNlLgorICBCdWlsZEZpbGUoCisgICAgICAibmFtZTogJ2Zvby5wcm90bycgIgorICAgICAgInN5bnRheDogJ3Byb3RvMycgIgorICAgICAgImVudW1fdHlwZSB7ICIKKyAgICAgICIgIG5hbWU6ICdGb29FbnVtJyAiCisgICAgICAiICB2YWx1ZSB7IG5hbWU6ICdGT09fRk9PJyBudW1iZXI6MCB9ICIKKyAgICAgICJ9Iik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBWYWxpZGF0ZVByb3RvM0xpdGVSdW50aW1lKSB7CisgIC8vIExpdGUgcnVudGltZSBpcyBub3Qgc3VwcG9ydGVkIGluIHByb3RvMy4KKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAgICJuYW1lOiAnZm9vLnByb3RvJyAiCisgICAgICAic3ludGF4OiAncHJvdG8zJyAiCisgICAgICAib3B0aW9ucyB7ICIKKyAgICAgICIgIG9wdGltaXplX2ZvcjogTElURV9SVU5USU1FICIKKyAgICAgICJ9ICIsCisgICAgICAiZm9vLnByb3RvOiBmb28ucHJvdG86IE9USEVSOiBMaXRlIHJ1bnRpbWUgaXMgbm90IHN1cHBvcnRlZCAiCisgICAgICAiaW4gcHJvdG8zLlxuIik7Cit9CisKK1RFU1RfRihWYWxpZGF0aW9uRXJyb3JUZXN0LCBWYWxpZGF0ZVByb3RvM0dyb3VwKSB7CisgIEJ1aWxkRmlsZVdpdGhFcnJvcnMoCisgICAgICAibmFtZTogJ2Zvby5wcm90bycgIgorICAgICAgInN5bnRheDogJ3Byb3RvMycgIgorICAgICAgIm1lc3NhZ2VfdHlwZSB7ICIKKyAgICAgICIgIG5hbWU6ICdGb28nICIKKyAgICAgICIgIG5lc3RlZF90eXBlIHsgIgorICAgICAgIiAgICBuYW1lOiAnRm9vR3JvdXAnICIKKyAgICAgICIgIH0gIgorICAgICAgIiAgZmllbGQgeyBuYW1lOidmb29fZ3JvdXAnIG51bWJlcjogMSBsYWJlbDpMQUJFTF9PUFRJT05BTCAiCisgICAgICAiICAgICAgICAgIHR5cGU6IFRZUEVfR1JPVVAgdHlwZV9uYW1lOidGb29Hcm91cCcgfSAiCisgICAgICAifSIsCisgICAgICAiZm9vLnByb3RvOiBGb28uZm9vX2dyb3VwOiBUWVBFOiBHcm91cHMgYXJlIG5vdCBzdXBwb3J0ZWQgaW4gcHJvdG8zICIKKyAgICAgICJzeW50YXguXG4iKTsKK30KKworCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgVmFsaWRhdGVQcm90bzNFbnVtRnJvbVByb3RvMikgeworICAvLyBEZWZpbmUgYW4gZW51bSBpbiBhIHByb3RvMiBmaWxlLgorICBCdWlsZEZpbGUoCisgICAgICAibmFtZTogJ2Zvby5wcm90bycgIgorICAgICAgInBhY2thZ2U6ICdmb28nICIKKyAgICAgICJzeW50YXg6ICdwcm90bzInICIKKyAgICAgICJlbnVtX3R5cGUgeyAiCisgICAgICAiICBuYW1lOiAnRm9vRW51bScgIgorICAgICAgIiAgdmFsdWUgeyBuYW1lOiAnREVGQVVMVF9PUFRJT04nIG51bWJlcjowIH0gIgorICAgICAgIn0iKTsKKworICAvLyBOb3cgdHJ5IHRvIHJlZmVyIHRvIGl0LiAoQWxsIHRlc3RzIGluIHRoZSBmaXh0dXJlIHVzZSB0aGUgc2FtZSBwb29sLCBzbyB3ZQorICAvLyBjYW4gcmVmZXIgdG8gdGhlIGVudW0gYWJvdmUgaW4gdGhpcyBkZWZpbml0aW9uLikKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAgICJuYW1lOiAnYmFyLnByb3RvJyAiCisgICAgICAiZGVwZW5kZW5jeTogJ2Zvby5wcm90bycgIgorICAgICAgInN5bnRheDogJ3Byb3RvMycgIgorICAgICAgIm1lc3NhZ2VfdHlwZSB7ICIKKyAgICAgICIgIG5hbWU6ICdGb28nICIKKyAgICAgICIgICAgZmllbGQgeyBuYW1lOidiYXInIG51bWJlcjoxIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9FTlVNICIKKyAgICAgICIgICAgICAgICAgICB0eXBlX25hbWU6ICdmb28uRm9vRW51bScgfSIKKyAgICAgICJ9IiwKKyAgICAgICJiYXIucHJvdG86IEZvby5iYXI6IFRZUEU6IEVudW0gdHlwZSBcImZvby5Gb29FbnVtXCIgaXMgbm90IGEgcHJvdG8zICIKKyAgICAgICJlbnVtLCBidXQgaXMgdXNlZCBpbiBcIkZvb1wiIHdoaWNoIGlzIGEgcHJvdG8zIG1lc3NhZ2UgdHlwZS5cbiIpOworfQorCitURVNUX0YoVmFsaWRhdGlvbkVycm9yVGVzdCwgVmFsaWRhdGVQcm90bzNFeHRlbnNpb24pIHsKKyAgLy8gVmFsaWQgZm9yIG9wdGlvbnMuCisgIERlc2NyaXB0b3JQb29sIHBvb2w7CisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZV9wcm90bzsKKyAgLy8gQWRkICJnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90byIuCisgIEZpbGVEZXNjcmlwdG9yUHJvdG86OmRlc2NyaXB0b3IoKS0+ZmlsZSgpLT5Db3B5VG8oJmZpbGVfcHJvdG8pOworICBBU1NFUlRfVFJVRShwb29sLkJ1aWxkRmlsZShmaWxlX3Byb3RvKSAhPSBOVUxMKTsKKyAgLy8gQWRkICJmb28ucHJvdG8iOgorICAvLyAgIGltcG9ydCAiZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8iOworICAvLyAgIGV4dGVuZCBnb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zIHsKKyAgLy8gICAgIG9wdGlvbmFsIGludDMyIG9wdGlvbjEgPSAxMDAwOworICAvLyAgIH0KKyAgZmlsZV9wcm90by5DbGVhcigpOworICBmaWxlX3Byb3RvLnNldF9uYW1lKCJmb28ucHJvdG8iKTsKKyAgZmlsZV9wcm90by5zZXRfc3ludGF4KCJwcm90bzMiKTsKKyAgZmlsZV9wcm90by5hZGRfZGVwZW5kZW5jeSgiZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8iKTsKKyAgQWRkRXh0ZW5zaW9uKCZmaWxlX3Byb3RvLCAiZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucyIsICJvcHRpb24xIiwgMTAwMCwKKyAgICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpMQUJFTF9PUFRJT05BTCwKKyAgICAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX0lOVDMyKTsKKyAgQVNTRVJUX1RSVUUocG9vbC5CdWlsZEZpbGUoZmlsZV9wcm90bykgIT0gTlVMTCk7CisKKyAgLy8gQ29weSBhbmQgY2hhbmdlIHRoZSBwYWNrYWdlIG9mIHRoZSBkZXNjcmlwdG9yLnByb3RvCisgIEJ1aWxkRmlsZSgKKyAgICAgICJuYW1lOiAnZ29vZ2xlLnByb3RvYnVmLnByb3RvJyAiCisgICAgICAic3ludGF4OiAncHJvdG8yJyAiCisgICAgICAibWVzc2FnZV90eXBlIHsgIgorICAgICAgIiAgbmFtZTogJ0NvbnRhaW5lcicgZXh0ZW5zaW9uX3JhbmdlIHsgc3RhcnQ6IDEgZW5kOiAxMDAwIH0gIgorICAgICAgIn0iKTsKKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAgICJuYW1lOiAnYmFyLnByb3RvJyAiCisgICAgICAic3ludGF4OiAncHJvdG8zJyAiCisgICAgICAiZGVwZW5kZW5jeTogJ2dvb2dsZS5wcm90b2J1Zi5wcm90bycgIgorICAgICAgImV4dGVuc2lvbiB7ICIKKyAgICAgICIgIG5hbWU6ICdiYXInIG51bWJlcjogMSBsYWJlbDogTEFCRUxfT1BUSU9OQUwgdHlwZTogVFlQRV9JTlQzMiAiCisgICAgICAiICBleHRlbmRlZTogJ0NvbnRhaW5lcicgIgorICAgICAgIn0iLAorICAgICAgImJhci5wcm90bzogYmFyOiBPVEhFUjogRXh0ZW5zaW9ucyBpbiBwcm90bzMgYXJlIG9ubHkgYWxsb3dlZCBmb3IgIgorICAgICAgImRlZmluaW5nIG9wdGlvbnMuXG4iKTsKK30KKworLy8gVGVzdCB0aGF0IGZpZWxkIG5hbWVzIHRoYXQgbWF5IGNvbmZsaWN0IGluIEpTT04gaXMgbm90IGFsbG93ZWQgYnkgcHJvdG9jLgorVEVTVF9GKFZhbGlkYXRpb25FcnJvclRlc3QsIFZhbGlkYXRlUHJvdG8zSnNvbk5hbWUpIHsKKyAgLy8gVGhlIGNvbXBhcmlzb24gaXMgY2FzZS1pbnNlbnNpdGl2ZS4KKyAgQnVpbGRGaWxlV2l0aEVycm9ycygKKyAgICAgICJuYW1lOiAnZm9vLnByb3RvJyAiCisgICAgICAic3ludGF4OiAncHJvdG8zJyAiCisgICAgICAibWVzc2FnZV90eXBlIHsiCisgICAgICAiICBuYW1lOiAnRm9vJyIKKyAgICAgICIgIGZpZWxkIHsgbmFtZTonbmFtZScgbnVtYmVyOjEgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZTpUWVBFX0lOVDMyIH0iCisgICAgICAiICBmaWVsZCB7IG5hbWU6J05hbWUnIG51bWJlcjoyIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiB9IgorICAgICAgIn0iLAorICAgICAgImZvby5wcm90bzogRm9vOiBPVEhFUjogVGhlIEpTT04gY2FtY2VsLWNhc2UgbmFtZSBvZiBmaWVsZCBcIk5hbWVcIiAiCisgICAgICAiY29uZmxpY3RzIHdpdGggZmllbGQgXCJuYW1lXCIuIFRoaXMgaXMgbm90IGFsbG93ZWQgaW4gcHJvdG8zLlxuIik7CisgIC8vIFVuZGVyc2NvcmVzIGFyZSBpZ25vcmVkLgorICBCdWlsZEZpbGVXaXRoRXJyb3JzKAorICAgICAgIm5hbWU6ICdmb28ucHJvdG8nICIKKyAgICAgICJzeW50YXg6ICdwcm90bzMnICIKKyAgICAgICJtZXNzYWdlX3R5cGUgeyIKKyAgICAgICIgIG5hbWU6ICdGb28nIgorICAgICAgIiAgZmllbGQgeyBuYW1lOidhYicgbnVtYmVyOjEgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZTpUWVBFX0lOVDMyIH0iCisgICAgICAiICBmaWVsZCB7IG5hbWU6J19hX19iXycgbnVtYmVyOjIgbGFiZWw6TEFCRUxfT1BUSU9OQUwgdHlwZTpUWVBFX0lOVDMyIH0iCisgICAgICAifSIsCisgICAgICAiZm9vLnByb3RvOiBGb286IE9USEVSOiBUaGUgSlNPTiBjYW1jZWwtY2FzZSBuYW1lIG9mIGZpZWxkIFwiX2FfX2JfXCIgIgorICAgICAgImNvbmZsaWN0cyB3aXRoIGZpZWxkIFwiYWJcIi4gVGhpcyBpcyBub3QgYWxsb3dlZCBpbiBwcm90bzMuXG4iKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorLy8gRGVzY3JpcHRvckRhdGFiYXNlCisKK3N0YXRpYyB2b2lkIEFkZFRvRGF0YWJhc2UoU2ltcGxlRGVzY3JpcHRvckRhdGFiYXNlKiBkYXRhYmFzZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogZmlsZV90ZXh0KSB7CisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZV9wcm90bzsKKyAgRVhQRUNUX1RSVUUoVGV4dEZvcm1hdDo6UGFyc2VGcm9tU3RyaW5nKGZpbGVfdGV4dCwgJmZpbGVfcHJvdG8pKTsKKyAgZGF0YWJhc2UtPkFkZChmaWxlX3Byb3RvKTsKK30KKworY2xhc3MgRGF0YWJhc2VCYWNrZWRQb29sVGVzdCA6IHB1YmxpYyB0ZXN0aW5nOjpUZXN0IHsKKyBwcm90ZWN0ZWQ6CisgIERhdGFiYXNlQmFja2VkUG9vbFRlc3QoKSB7fQorCisgIFNpbXBsZURlc2NyaXB0b3JEYXRhYmFzZSBkYXRhYmFzZV87CisKKyAgdmlydHVhbCB2b2lkIFNldFVwKCkgeworICAgIEFkZFRvRGF0YWJhc2UoJmRhdGFiYXNlXywKKyAgICAgICJuYW1lOiAnZm9vLnByb3RvJyAiCisgICAgICAibWVzc2FnZV90eXBlIHsgbmFtZTonRm9vJyBleHRlbnNpb25fcmFuZ2UgeyBzdGFydDogMSBlbmQ6IDEwMCB9IH0gIgorICAgICAgImVudW1fdHlwZSB7IG5hbWU6J1Rlc3RFbnVtJyB2YWx1ZSB7IG5hbWU6J0RVTU1ZJyBudW1iZXI6MCB9IH0gIgorICAgICAgInNlcnZpY2UgeyBuYW1lOidUZXN0U2VydmljZScgfSAiKTsKKyAgICBBZGRUb0RhdGFiYXNlKCZkYXRhYmFzZV8sCisgICAgICAibmFtZTogJ2Jhci5wcm90bycgIgorICAgICAgImRlcGVuZGVuY3k6ICdmb28ucHJvdG8nICIKKyAgICAgICJtZXNzYWdlX3R5cGUgeyBuYW1lOidCYXInIH0gIgorICAgICAgImV4dGVuc2lvbiB7IG5hbWU6J2Zvb19leHQnIGV4dGVuZGVlOiAnLkZvbycgbnVtYmVyOjUgIgorICAgICAgIiAgICAgICAgICAgIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGU6VFlQRV9JTlQzMiB9ICIpOworICAgIC8vIEJheiBoYXMgYW4gdW5kZWNsYXJlZCBkZXBlbmRlbmN5IG9uIEZvby4KKyAgICBBZGRUb0RhdGFiYXNlKCZkYXRhYmFzZV8sCisgICAgICAibmFtZTogJ2Jhei5wcm90bycgIgorICAgICAgIm1lc3NhZ2VfdHlwZSB7ICIKKyAgICAgICIgIG5hbWU6J0JheicgIgorICAgICAgIiAgZmllbGQgeyBuYW1lOidmb28nIG51bWJlcjoxIGxhYmVsOkxBQkVMX09QVElPTkFMIHR5cGVfbmFtZTonRm9vJyB9ICIKKyAgICAgICJ9Iik7CisgIH0KKworICAvLyBXZSBjYW4ndCBpbmplY3QgYSBmaWxlIGNvbnRhaW5pbmcgZXJyb3JzIGludG8gYSBEZXNjcmlwdG9yUG9vbCwgc28gd2UKKyAgLy8gbmVlZCBhbiBhY3R1YWwgbW9jayBEZXNjcmlwdG9yRGF0YWJhc2UgdG8gdGVzdCBlcnJvcnMuCisgIGNsYXNzIEVycm9yRGVzY3JpcHRvckRhdGFiYXNlIDogcHVibGljIERlc2NyaXB0b3JEYXRhYmFzZSB7CisgICBwdWJsaWM6CisgICAgRXJyb3JEZXNjcmlwdG9yRGF0YWJhc2UoKSB7fQorICAgIH5FcnJvckRlc2NyaXB0b3JEYXRhYmFzZSgpIHt9CisKKyAgICAvLyBpbXBsZW1lbnRzIERlc2NyaXB0b3JEYXRhYmFzZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICBib29sIEZpbmRGaWxlQnlOYW1lKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICBGaWxlRGVzY3JpcHRvclByb3RvKiBvdXRwdXQpIHsKKyAgICAgIC8vIGVycm9yLnByb3RvIGFuZCBlcnJvcjIucHJvdG8gY3ljbGljYWxseSBpbXBvcnQgZWFjaCBvdGhlci4KKyAgICAgIGlmIChmaWxlbmFtZSA9PSAiZXJyb3IucHJvdG8iKSB7CisgICAgICAgIG91dHB1dC0+Q2xlYXIoKTsKKyAgICAgICAgb3V0cHV0LT5zZXRfbmFtZSgiZXJyb3IucHJvdG8iKTsKKyAgICAgICAgb3V0cHV0LT5hZGRfZGVwZW5kZW5jeSgiZXJyb3IyLnByb3RvIik7CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgfSBlbHNlIGlmIChmaWxlbmFtZSA9PSAiZXJyb3IyLnByb3RvIikgeworICAgICAgICBvdXRwdXQtPkNsZWFyKCk7CisgICAgICAgIG91dHB1dC0+c2V0X25hbWUoImVycm9yMi5wcm90byIpOworICAgICAgICBvdXRwdXQtPmFkZF9kZXBlbmRlbmN5KCJlcnJvci5wcm90byIpOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICB9CisgICAgYm9vbCBGaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2woY29uc3Qgc3RyaW5nJiBzeW1ib2xfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlRGVzY3JpcHRvclByb3RvKiBvdXRwdXQpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgYm9vbCBGaW5kRmlsZUNvbnRhaW5pbmdFeHRlbnNpb24oY29uc3Qgc3RyaW5nJiBjb250YWluaW5nX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlRGVzY3JpcHRvclByb3RvKiBvdXRwdXQpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH07CisKKyAgLy8gQSBEZXNjcmlwdG9yRGF0YWJhc2UgdGhhdCBjb3VudHMgaG93IG1hbnkgdGltZXMgZWFjaCBtZXRob2QgaGFzIGJlZW4KKyAgLy8gY2FsbGVkIGFuZCBmb3J3YXJkcyB0byBzb21lIG90aGVyIERlc2NyaXB0b3JEYXRhYmFzZS4KKyAgY2xhc3MgQ2FsbENvdW50aW5nRGF0YWJhc2UgOiBwdWJsaWMgRGVzY3JpcHRvckRhdGFiYXNlIHsKKyAgIHB1YmxpYzoKKyAgICBDYWxsQ291bnRpbmdEYXRhYmFzZShEZXNjcmlwdG9yRGF0YWJhc2UqIHdyYXBwZWRfZGIpCisgICAgICA6IHdyYXBwZWRfZGJfKHdyYXBwZWRfZGIpIHsKKyAgICAgIENsZWFyKCk7CisgICAgfQorICAgIH5DYWxsQ291bnRpbmdEYXRhYmFzZSgpIHt9CisKKyAgICBEZXNjcmlwdG9yRGF0YWJhc2UqIHdyYXBwZWRfZGJfOworCisgICAgaW50IGNhbGxfY291bnRfOworCisgICAgdm9pZCBDbGVhcigpIHsKKyAgICAgIGNhbGxfY291bnRfID0gMDsKKyAgICB9CisKKyAgICAvLyBpbXBsZW1lbnRzIERlc2NyaXB0b3JEYXRhYmFzZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICBib29sIEZpbmRGaWxlQnlOYW1lKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICBGaWxlRGVzY3JpcHRvclByb3RvKiBvdXRwdXQpIHsKKyAgICAgICsrY2FsbF9jb3VudF87CisgICAgICByZXR1cm4gd3JhcHBlZF9kYl8tPkZpbmRGaWxlQnlOYW1lKGZpbGVuYW1lLCBvdXRwdXQpOworICAgIH0KKyAgICBib29sIEZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbChjb25zdCBzdHJpbmcmIHN5bWJvbF9uYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8qIG91dHB1dCkgeworICAgICAgKytjYWxsX2NvdW50XzsKKyAgICAgIHJldHVybiB3cmFwcGVkX2RiXy0+RmluZEZpbGVDb250YWluaW5nU3ltYm9sKHN5bWJvbF9uYW1lLCBvdXRwdXQpOworICAgIH0KKyAgICBib29sIEZpbmRGaWxlQ29udGFpbmluZ0V4dGVuc2lvbihjb25zdCBzdHJpbmcmIGNvbnRhaW5pbmdfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZmllbGRfbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8qIG91dHB1dCkgeworICAgICAgKytjYWxsX2NvdW50XzsKKyAgICAgIHJldHVybiB3cmFwcGVkX2RiXy0+RmluZEZpbGVDb250YWluaW5nRXh0ZW5zaW9uKAorICAgICAgICBjb250YWluaW5nX3R5cGUsIGZpZWxkX251bWJlciwgb3V0cHV0KTsKKyAgICB9CisgIH07CisKKyAgLy8gQSBEZXNjcmlwdG9yRGF0YWJhc2Ugd2hpY2ggZmFsc2VseSBhbHdheXMgcmV0dXJucyBmb28ucHJvdG8gd2hlbiBzZWFyY2hpbmcKKyAgLy8gZm9yIGFueSBzeW1ib2wgb3IgZXh0ZW5zaW9uIG51bWJlci4gIFRoaXMgc2hvdWxkbid0IGNhdXNlIHRoZQorICAvLyBEZXNjcmlwdG9yUG9vbCB0byByZWxvYWQgZm9vLnByb3RvIGlmIGl0IGlzIGFscmVhZHkgbG9hZGVkLgorICBjbGFzcyBGYWxzZVBvc2l0aXZlRGF0YWJhc2UgOiBwdWJsaWMgRGVzY3JpcHRvckRhdGFiYXNlIHsKKyAgIHB1YmxpYzoKKyAgICBGYWxzZVBvc2l0aXZlRGF0YWJhc2UoRGVzY3JpcHRvckRhdGFiYXNlKiB3cmFwcGVkX2RiKQorICAgICAgOiB3cmFwcGVkX2RiXyh3cmFwcGVkX2RiKSB7fQorICAgIH5GYWxzZVBvc2l0aXZlRGF0YWJhc2UoKSB7fQorCisgICAgRGVzY3JpcHRvckRhdGFiYXNlKiB3cmFwcGVkX2RiXzsKKworICAgIC8vIGltcGxlbWVudHMgRGVzY3JpcHRvckRhdGFiYXNlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAgIGJvb2wgRmluZEZpbGVCeU5hbWUoY29uc3Qgc3RyaW5nJiBmaWxlbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8qIG91dHB1dCkgeworICAgICAgcmV0dXJuIHdyYXBwZWRfZGJfLT5GaW5kRmlsZUJ5TmFtZShmaWxlbmFtZSwgb3V0cHV0KTsKKyAgICB9CisgICAgYm9vbCBGaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2woY29uc3Qgc3RyaW5nJiBzeW1ib2xfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlRGVzY3JpcHRvclByb3RvKiBvdXRwdXQpIHsKKyAgICAgIHJldHVybiBGaW5kRmlsZUJ5TmFtZSgiZm9vLnByb3RvIiwgb3V0cHV0KTsKKyAgICB9CisgICAgYm9vbCBGaW5kRmlsZUNvbnRhaW5pbmdFeHRlbnNpb24oY29uc3Qgc3RyaW5nJiBjb250YWluaW5nX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlRGVzY3JpcHRvclByb3RvKiBvdXRwdXQpIHsKKyAgICAgIHJldHVybiBGaW5kRmlsZUJ5TmFtZSgiZm9vLnByb3RvIiwgb3V0cHV0KTsKKyAgICB9CisgIH07Cit9OworCitURVNUX0YoRGF0YWJhc2VCYWNrZWRQb29sVGVzdCwgRmluZEZpbGVCeU5hbWUpIHsKKyAgRGVzY3JpcHRvclBvb2wgcG9vbCgmZGF0YWJhc2VfKTsKKworICBjb25zdCBGaWxlRGVzY3JpcHRvciogZm9vID0gcG9vbC5GaW5kRmlsZUJ5TmFtZSgiZm9vLnByb3RvIik7CisgIEFTU0VSVF9UUlVFKGZvbyAhPSBOVUxMKTsKKyAgRVhQRUNUX0VRKCJmb28ucHJvdG8iLCBmb28tPm5hbWUoKSk7CisgIEFTU0VSVF9FUSgxLCBmb28tPm1lc3NhZ2VfdHlwZV9jb3VudCgpKTsKKyAgRVhQRUNUX0VRKCJGb28iLCBmb28tPm1lc3NhZ2VfdHlwZSgwKS0+bmFtZSgpKTsKKworICBFWFBFQ1RfRVEoZm9vLCBwb29sLkZpbmRGaWxlQnlOYW1lKCJmb28ucHJvdG8iKSk7CisKKyAgRVhQRUNUX1RSVUUocG9vbC5GaW5kRmlsZUJ5TmFtZSgibm9fc3VjaF9maWxlLnByb3RvIikgPT0gTlVMTCk7Cit9CisKK1RFU1RfRihEYXRhYmFzZUJhY2tlZFBvb2xUZXN0LCBGaW5kRGVwZW5kZW5jeUJlZm9yZURlcGVuZGVudCkgeworICBEZXNjcmlwdG9yUG9vbCBwb29sKCZkYXRhYmFzZV8pOworCisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmb28gPSBwb29sLkZpbmRGaWxlQnlOYW1lKCJmb28ucHJvdG8iKTsKKyAgQVNTRVJUX1RSVUUoZm9vICE9IE5VTEwpOworICBFWFBFQ1RfRVEoImZvby5wcm90byIsIGZvby0+bmFtZSgpKTsKKyAgQVNTRVJUX0VRKDEsIGZvby0+bWVzc2FnZV90eXBlX2NvdW50KCkpOworICBFWFBFQ1RfRVEoIkZvbyIsIGZvby0+bWVzc2FnZV90eXBlKDApLT5uYW1lKCkpOworCisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBiYXIgPSBwb29sLkZpbmRGaWxlQnlOYW1lKCJiYXIucHJvdG8iKTsKKyAgQVNTRVJUX1RSVUUoYmFyICE9IE5VTEwpOworICBFWFBFQ1RfRVEoImJhci5wcm90byIsIGJhci0+bmFtZSgpKTsKKyAgQVNTRVJUX0VRKDEsIGJhci0+bWVzc2FnZV90eXBlX2NvdW50KCkpOworICBFWFBFQ1RfRVEoIkJhciIsIGJhci0+bWVzc2FnZV90eXBlKDApLT5uYW1lKCkpOworCisgIEFTU0VSVF9FUSgxLCBiYXItPmRlcGVuZGVuY3lfY291bnQoKSk7CisgIEVYUEVDVF9FUShmb28sIGJhci0+ZGVwZW5kZW5jeSgwKSk7Cit9CisKK1RFU1RfRihEYXRhYmFzZUJhY2tlZFBvb2xUZXN0LCBGaW5kRGVwZW5kZW50QmVmb3JlRGVwZW5kZW5jeSkgeworICBEZXNjcmlwdG9yUG9vbCBwb29sKCZkYXRhYmFzZV8pOworCisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBiYXIgPSBwb29sLkZpbmRGaWxlQnlOYW1lKCJiYXIucHJvdG8iKTsKKyAgQVNTRVJUX1RSVUUoYmFyICE9IE5VTEwpOworICBFWFBFQ1RfRVEoImJhci5wcm90byIsIGJhci0+bmFtZSgpKTsKKyAgQVNTRVJUX0VRKDEsIGJhci0+bWVzc2FnZV90eXBlX2NvdW50KCkpOworICBBU1NFUlRfRVEoIkJhciIsIGJhci0+bWVzc2FnZV90eXBlKDApLT5uYW1lKCkpOworCisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmb28gPSBwb29sLkZpbmRGaWxlQnlOYW1lKCJmb28ucHJvdG8iKTsKKyAgQVNTRVJUX1RSVUUoZm9vICE9IE5VTEwpOworICBFWFBFQ1RfRVEoImZvby5wcm90byIsIGZvby0+bmFtZSgpKTsKKyAgQVNTRVJUX0VRKDEsIGZvby0+bWVzc2FnZV90eXBlX2NvdW50KCkpOworICBBU1NFUlRfRVEoIkZvbyIsIGZvby0+bWVzc2FnZV90eXBlKDApLT5uYW1lKCkpOworCisgIEFTU0VSVF9FUSgxLCBiYXItPmRlcGVuZGVuY3lfY291bnQoKSk7CisgIEVYUEVDVF9FUShmb28sIGJhci0+ZGVwZW5kZW5jeSgwKSk7Cit9CisKK1RFU1RfRihEYXRhYmFzZUJhY2tlZFBvb2xUZXN0LCBGaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2wpIHsKKyAgRGVzY3JpcHRvclBvb2wgcG9vbCgmZGF0YWJhc2VfKTsKKworICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSA9IHBvb2wuRmluZEZpbGVDb250YWluaW5nU3ltYm9sKCJGb28iKTsKKyAgQVNTRVJUX1RSVUUoZmlsZSAhPSBOVUxMKTsKKyAgRVhQRUNUX0VRKCJmb28ucHJvdG8iLCBmaWxlLT5uYW1lKCkpOworICBFWFBFQ1RfRVEoZmlsZSwgcG9vbC5GaW5kRmlsZUJ5TmFtZSgiZm9vLnByb3RvIikpOworCisgIEVYUEVDVF9UUlVFKHBvb2wuRmluZEZpbGVDb250YWluaW5nU3ltYm9sKCJOb1N1Y2hTeW1ib2wiKSA9PSBOVUxMKTsKK30KKworVEVTVF9GKERhdGFiYXNlQmFja2VkUG9vbFRlc3QsIEZpbmRNZXNzYWdlVHlwZUJ5TmFtZSkgeworICBEZXNjcmlwdG9yUG9vbCBwb29sKCZkYXRhYmFzZV8pOworCisgIGNvbnN0IERlc2NyaXB0b3IqIHR5cGUgPSBwb29sLkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgiRm9vIik7CisgIEFTU0VSVF9UUlVFKHR5cGUgIT0gTlVMTCk7CisgIEVYUEVDVF9FUSgiRm9vIiwgdHlwZS0+bmFtZSgpKTsKKyAgRVhQRUNUX0VRKHR5cGUtPmZpbGUoKSwgcG9vbC5GaW5kRmlsZUJ5TmFtZSgiZm9vLnByb3RvIikpOworCisgIEVYUEVDVF9UUlVFKHBvb2wuRmluZE1lc3NhZ2VUeXBlQnlOYW1lKCJOb1N1Y2hUeXBlIikgPT0gTlVMTCk7Cit9CisKK1RFU1RfRihEYXRhYmFzZUJhY2tlZFBvb2xUZXN0LCBGaW5kRXh0ZW5zaW9uQnlOdW1iZXIpIHsKKyAgRGVzY3JpcHRvclBvb2wgcG9vbCgmZGF0YWJhc2VfKTsKKworICBjb25zdCBEZXNjcmlwdG9yKiBmb28gPSBwb29sLkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgiRm9vIik7CisgIEFTU0VSVF9UUlVFKGZvbyAhPSBOVUxMKTsKKworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGV4dGVuc2lvbiA9IHBvb2wuRmluZEV4dGVuc2lvbkJ5TnVtYmVyKGZvbywgNSk7CisgIEFTU0VSVF9UUlVFKGV4dGVuc2lvbiAhPSBOVUxMKTsKKyAgRVhQRUNUX0VRKCJmb29fZXh0IiwgZXh0ZW5zaW9uLT5uYW1lKCkpOworICBFWFBFQ1RfRVEoZXh0ZW5zaW9uLT5maWxlKCksIHBvb2wuRmluZEZpbGVCeU5hbWUoImJhci5wcm90byIpKTsKKworICBFWFBFQ1RfVFJVRShwb29sLkZpbmRFeHRlbnNpb25CeU51bWJlcihmb28sIDEyKSA9PSBOVUxMKTsKK30KKworVEVTVF9GKERhdGFiYXNlQmFja2VkUG9vbFRlc3QsIEZpbmRBbGxFeHRlbnNpb25zKSB7CisgIERlc2NyaXB0b3JQb29sIHBvb2woJmRhdGFiYXNlXyk7CisKKyAgY29uc3QgRGVzY3JpcHRvciogZm9vID0gcG9vbC5GaW5kTWVzc2FnZVR5cGVCeU5hbWUoIkZvbyIpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgMjsgKytpKSB7CisgICAgLy8gUmVwZWF0IHRoZSBsb29rdXAgdHdpY2UsIHRvIGNoZWNrIHRoYXQgd2UgZ2V0IGNvbnNpc3RlbnQKKyAgICAvLyByZXN1bHRzIGRlc3BpdGUgdGhlIGZhbGxiYWNrIGRhdGFiYXNlIGxvb2t1cCBtdXRhdGluZyB0aGUgcG9vbC4KKyAgICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4gZXh0ZW5zaW9uczsKKyAgICBwb29sLkZpbmRBbGxFeHRlbnNpb25zKGZvbywgJmV4dGVuc2lvbnMpOworICAgIEFTU0VSVF9FUSgxLCBleHRlbnNpb25zLnNpemUoKSk7CisgICAgRVhQRUNUX0VRKDUsIGV4dGVuc2lvbnNbMF0tPm51bWJlcigpKTsKKyAgfQorfQorCitURVNUX0YoRGF0YWJhc2VCYWNrZWRQb29sVGVzdCwgRXJyb3JXaXRob3V0RXJyb3JDb2xsZWN0b3IpIHsKKyAgRXJyb3JEZXNjcmlwdG9yRGF0YWJhc2UgZXJyb3JfZGF0YWJhc2U7CisgIERlc2NyaXB0b3JQb29sIHBvb2woJmVycm9yX2RhdGFiYXNlKTsKKworICB2ZWN0b3I8c3RyaW5nPiBlcnJvcnM7CisKKyAgeworICAgIFNjb3BlZE1lbW9yeUxvZyBsb2c7CisgICAgRVhQRUNUX1RSVUUocG9vbC5GaW5kRmlsZUJ5TmFtZSgiZXJyb3IucHJvdG8iKSA9PSBOVUxMKTsKKyAgICBlcnJvcnMgPSBsb2cuR2V0TWVzc2FnZXMoRVJST1IpOworICB9CisKKyAgRVhQRUNUX0ZBTFNFKGVycm9ycy5lbXB0eSgpKTsKK30KKworVEVTVF9GKERhdGFiYXNlQmFja2VkUG9vbFRlc3QsIEVycm9yV2l0aEVycm9yQ29sbGVjdG9yKSB7CisgIEVycm9yRGVzY3JpcHRvckRhdGFiYXNlIGVycm9yX2RhdGFiYXNlOworICBNb2NrRXJyb3JDb2xsZWN0b3IgZXJyb3JfY29sbGVjdG9yOworICBEZXNjcmlwdG9yUG9vbCBwb29sKCZlcnJvcl9kYXRhYmFzZSwgJmVycm9yX2NvbGxlY3Rvcik7CisKKyAgRVhQRUNUX1RSVUUocG9vbC5GaW5kRmlsZUJ5TmFtZSgiZXJyb3IucHJvdG8iKSA9PSBOVUxMKTsKKyAgRVhQRUNUX0VRKAorICAgICJlcnJvci5wcm90bzogZXJyb3IucHJvdG86IE9USEVSOiBGaWxlIHJlY3Vyc2l2ZWx5IGltcG9ydHMgaXRzZWxmOiAiCisgICAgICAiZXJyb3IucHJvdG8gLT4gZXJyb3IyLnByb3RvIC0+IGVycm9yLnByb3RvXG4iCisgICAgImVycm9yMi5wcm90bzogZXJyb3IyLnByb3RvOiBPVEhFUjogSW1wb3J0IFwiZXJyb3IucHJvdG9cIiB3YXMgbm90ICIKKyAgICAgICJmb3VuZCBvciBoYWQgZXJyb3JzLlxuIgorICAgICJlcnJvci5wcm90bzogZXJyb3IucHJvdG86IE9USEVSOiBJbXBvcnQgXCJlcnJvcjIucHJvdG9cIiB3YXMgbm90ICIKKyAgICAgICJmb3VuZCBvciBoYWQgZXJyb3JzLlxuIiwKKyAgICBlcnJvcl9jb2xsZWN0b3IudGV4dF8pOworfQorCitURVNUX0YoRGF0YWJhc2VCYWNrZWRQb29sVGVzdCwgVW5kZWNsYXJlZERlcGVuZGVuY3lPblVuYnVpbHRUeXBlKSB7CisgIC8vIENoZWNrIHRoYXQgd2UgZmluZCBhbmQgcmVwb3J0IHVuZGVjbGFyZWQgZGVwZW5kZW5jaWVzIG9uIHR5cGVzIHRoYXQgZXhpc3QKKyAgLy8gaW4gdGhlIGRlc2NyaXB0b3IgZGF0YWJhc2UgYnV0IHRoYXQgaGF2ZSBub3Qgbm90IGJlZW4gYnVpbHQgeWV0LgorICBNb2NrRXJyb3JDb2xsZWN0b3IgZXJyb3JfY29sbGVjdG9yOworICBEZXNjcmlwdG9yUG9vbCBwb29sKCZkYXRhYmFzZV8sICZlcnJvcl9jb2xsZWN0b3IpOworICBFWFBFQ1RfVFJVRShwb29sLkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgiQmF6IikgPT0gTlVMTCk7CisgIEVYUEVDVF9FUSgKKyAgICAiYmF6LnByb3RvOiBCYXouZm9vOiBUWVBFOiBcIkZvb1wiIHNlZW1zIHRvIGJlIGRlZmluZWQgaW4gXCJmb28ucHJvdG9cIiwgIgorICAgICJ3aGljaCBpcyBub3QgaW1wb3J0ZWQgYnkgXCJiYXoucHJvdG9cIi4gIFRvIHVzZSBpdCBoZXJlLCBwbGVhc2UgYWRkICIKKyAgICAidGhlIG5lY2Vzc2FyeSBpbXBvcnQuXG4iLAorICAgIGVycm9yX2NvbGxlY3Rvci50ZXh0Xyk7Cit9CisKK1RFU1RfRihEYXRhYmFzZUJhY2tlZFBvb2xUZXN0LCBSb2xsYmFja0FmdGVyRXJyb3IpIHsKKyAgLy8gTWFrZSBzdXJlIHRoYXQgYWxsIHRyYWNlcyBvZiBiYWQgdHlwZXMgYXJlIHJlbW92ZWQgZnJvbSB0aGUgcG9vbC4gVGhpcyB1c2VkCisgIC8vIHRvIGJlIGIvNDUyOTQzNiwgZHVlIHRvIHRoZSBmYWN0IHRoYXQgYSBzeW1ib2wgcmVzb2x1dGlvbiBmYWlsdXJlIGNvdWxkCisgIC8vIHBvdGVudGlhbGx5IGNhdXNlIGFub3RoZXIgZmlsZSB0byBiZSByZWN1cnNpdmVseSBidWlsdCwgd2hpY2ggd291bGQgdHJpZ2dlcgorICAvLyBhIGNoZWNrcG9pbnQgX3Bhc3RfIHBvc3NpYmx5IGludmFsaWQgc3ltYm9scy4KKyAgLy8gQmF6IGlzIGRlZmluZWQgaW4gdGhlIGRhdGFiYXNlLCBidXQgdGhlIGZpbGUgaXMgaW52YWxpZCBiZWNhdXNlIGl0IGlzCisgIC8vIG1pc3NpbmcgYSBuZWNlc3NhcnkgaW1wb3J0LgorICBEZXNjcmlwdG9yUG9vbCBwb29sKCZkYXRhYmFzZV8pOworICBFWFBFQ1RfVFJVRShwb29sLkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgiQmF6IikgPT0gTlVMTCk7CisgIC8vIE1ha2Ugc3VyZSB0aGF0IHNlYXJjaGluZyBhZ2FpbiBmb3IgdGhlIGZpbGUgb3IgdGhlIHR5cGUgZmFpbHMuCisgIEVYUEVDVF9UUlVFKHBvb2wuRmluZEZpbGVCeU5hbWUoImJhei5wcm90byIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShwb29sLkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgiQmF6IikgPT0gTlVMTCk7Cit9CisKK1RFU1RfRihEYXRhYmFzZUJhY2tlZFBvb2xUZXN0LCBVbml0dGVzdFByb3RvKSB7CisgIC8vIFRyeSB0byBsb2FkIGFsbCBvZiB1bml0dGVzdC5wcm90byBmcm9tIGEgRGVzY3JpcHRvckRhdGFiYXNlLiAgVGhpcyBzaG91bGQKKyAgLy8gdGhvcm91Z2hseSB0ZXN0IGFsbCBwYXRocyB0aHJvdWdoIERlc2NyaXB0b3JCdWlsZGVyIHRvIGluc3VyZSB0aGF0IHRoZXJlCisgIC8vIGFyZSBubyBkZWFkbG9ja2luZyBwcm9ibGVtcyB3aGVuIHBvb2xfLT5tdXRleF8gaXMgbm9uLU5VTEwuCisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBvcmlnaW5hbF9maWxlID0KKyAgICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpkZXNjcmlwdG9yKCktPmZpbGUoKTsKKworICBEZXNjcmlwdG9yUG9vbERhdGFiYXNlIGRhdGFiYXNlKCpEZXNjcmlwdG9yUG9vbDo6Z2VuZXJhdGVkX3Bvb2woKSk7CisgIERlc2NyaXB0b3JQb29sIHBvb2woJmRhdGFiYXNlKTsKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGVfZnJvbV9kYXRhYmFzZSA9CisgICAgcG9vbC5GaW5kRmlsZUJ5TmFtZShvcmlnaW5hbF9maWxlLT5uYW1lKCkpOworCisgIEFTU0VSVF9UUlVFKGZpbGVfZnJvbV9kYXRhYmFzZSAhPSBOVUxMKTsKKworICBGaWxlRGVzY3JpcHRvclByb3RvIG9yaWdpbmFsX2ZpbGVfcHJvdG87CisgIG9yaWdpbmFsX2ZpbGUtPkNvcHlUbygmb3JpZ2luYWxfZmlsZV9wcm90byk7CisKKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX2Zyb21fZGF0YWJhc2VfcHJvdG87CisgIGZpbGVfZnJvbV9kYXRhYmFzZS0+Q29weVRvKCZmaWxlX2Zyb21fZGF0YWJhc2VfcHJvdG8pOworCisgIEVYUEVDVF9FUShvcmlnaW5hbF9maWxlX3Byb3RvLkRlYnVnU3RyaW5nKCksCisgICAgICAgICAgICBmaWxlX2Zyb21fZGF0YWJhc2VfcHJvdG8uRGVidWdTdHJpbmcoKSk7CisKKyAgLy8gQWxzbyB2ZXJpZnkgdGhhdCBDb3B5VG8oKSBkaWQgbm90IG9taXQgYW55IGluZm9ybWF0aW9uLgorICBFWFBFQ1RfRVEob3JpZ2luYWxfZmlsZS0+RGVidWdTdHJpbmcoKSwKKyAgICAgICAgICAgIGZpbGVfZnJvbV9kYXRhYmFzZS0+RGVidWdTdHJpbmcoKSk7Cit9CisKK1RFU1RfRihEYXRhYmFzZUJhY2tlZFBvb2xUZXN0LCBEb2VzbnRSZXRyeURiVW5uZWNlc3NhcmlseSkgeworICAvLyBTZWFyY2hpbmcgZm9yIGEgY2hpbGQgb2YgYW4gZXhpc3RpbmcgZGVzY3JpcHRvciBzaG91bGQgbmV2ZXIgZmFsbCBiYWNrCisgIC8vIHRvIHRoZSBEZXNjcmlwdG9yRGF0YWJhc2UgZXZlbiBpZiBpdCBpc24ndCBmb3VuZCwgYmVjYXVzZSB3ZSBrbm93IGFsbAorICAvLyBjaGlsZHJlbiBhcmUgYWxyZWFkeSBsb2FkZWQuCisgIENhbGxDb3VudGluZ0RhdGFiYXNlIGNhbGxfY291bnRlcigmZGF0YWJhc2VfKTsKKyAgRGVzY3JpcHRvclBvb2wgcG9vbCgmY2FsbF9jb3VudGVyKTsKKworICBjb25zdCBGaWxlRGVzY3JpcHRvciogZmlsZSA9IHBvb2wuRmluZEZpbGVCeU5hbWUoImZvby5wcm90byIpOworICBBU1NFUlRfVFJVRShmaWxlICE9IE5VTEwpOworICBjb25zdCBEZXNjcmlwdG9yKiBmb28gPSBwb29sLkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgiRm9vIik7CisgIEFTU0VSVF9UUlVFKGZvbyAhPSBOVUxMKTsKKyAgY29uc3QgRW51bURlc2NyaXB0b3IqIHRlc3RfZW51bSA9IHBvb2wuRmluZEVudW1UeXBlQnlOYW1lKCJUZXN0RW51bSIpOworICBBU1NFUlRfVFJVRSh0ZXN0X2VudW0gIT0gTlVMTCk7CisgIGNvbnN0IFNlcnZpY2VEZXNjcmlwdG9yKiB0ZXN0X3NlcnZpY2UgPSBwb29sLkZpbmRTZXJ2aWNlQnlOYW1lKCJUZXN0U2VydmljZSIpOworICBBU1NFUlRfVFJVRSh0ZXN0X3NlcnZpY2UgIT0gTlVMTCk7CisKKyAgRVhQRUNUX05FKDAsIGNhbGxfY291bnRlci5jYWxsX2NvdW50Xyk7CisgIGNhbGxfY291bnRlci5DbGVhcigpOworCisgIEVYUEVDVF9UUlVFKGZvby0+RmluZEZpZWxkQnlOYW1lKCJub19zdWNoX2ZpZWxkIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKGZvby0+RmluZEV4dGVuc2lvbkJ5TmFtZSgibm9fc3VjaF9leHRlbnNpb24iKSA9PSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUoZm9vLT5GaW5kTmVzdGVkVHlwZUJ5TmFtZSgiTm9TdWNoTWVzc2FnZVR5cGUiKSA9PSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUoZm9vLT5GaW5kRW51bVR5cGVCeU5hbWUoIk5vU3VjaEVudW1UeXBlIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKGZvby0+RmluZEVudW1WYWx1ZUJ5TmFtZSgiTk9fU1VDSF9WQUxVRSIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRSh0ZXN0X2VudW0tPkZpbmRWYWx1ZUJ5TmFtZSgiTk9fU1VDSF9WQUxVRSIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRSh0ZXN0X3NlcnZpY2UtPkZpbmRNZXRob2RCeU5hbWUoIk5vU3VjaE1ldGhvZCIpID09IE5VTEwpOworCisgIEVYUEVDVF9UUlVFKGZpbGUtPkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgiTm9TdWNoTWVzc2FnZVR5cGUiKSA9PSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUoZmlsZS0+RmluZEVudW1UeXBlQnlOYW1lKCJOb1N1Y2hFbnVtVHlwZSIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShmaWxlLT5GaW5kRW51bVZhbHVlQnlOYW1lKCJOT19TVUNIX1ZBTFVFIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKGZpbGUtPkZpbmRTZXJ2aWNlQnlOYW1lKCJOT19TVUNIX1ZBTFVFIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKGZpbGUtPkZpbmRFeHRlbnNpb25CeU5hbWUoIm5vX3N1Y2hfZXh0ZW5zaW9uIikgPT0gTlVMTCk7CisKKyAgRVhQRUNUX1RSVUUocG9vbC5GaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2woIkZvby5uby5zdWNoLmZpZWxkIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKHBvb2wuRmluZEZpbGVDb250YWluaW5nU3ltYm9sKCJGb28ubm9fc3VjaF9maWVsZCIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShwb29sLkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgiRm9vLk5vU3VjaE1lc3NhZ2VUeXBlIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKHBvb2wuRmluZEZpZWxkQnlOYW1lKCJGb28ubm9fc3VjaF9maWVsZCIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShwb29sLkZpbmRFeHRlbnNpb25CeU5hbWUoIkZvby5ub19zdWNoX2V4dGVuc2lvbiIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShwb29sLkZpbmRFbnVtVHlwZUJ5TmFtZSgiRm9vLk5vU3VjaEVudW1UeXBlIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKHBvb2wuRmluZEVudW1WYWx1ZUJ5TmFtZSgiRm9vLk5PX1NVQ0hfVkFMVUUiKSA9PSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUocG9vbC5GaW5kTWV0aG9kQnlOYW1lKCJUZXN0U2VydmljZS5Ob1N1Y2hNZXRob2QiKSA9PSBOVUxMKTsKKworICBFWFBFQ1RfRVEoMCwgY2FsbF9jb3VudGVyLmNhbGxfY291bnRfKTsKK30KKworVEVTVF9GKERhdGFiYXNlQmFja2VkUG9vbFRlc3QsIERvZXNudFJlbG9hZEZpbGVzVW5jZXNlc3NhcmlseSkgeworICAvLyBJZiBGaW5kRmlsZUNvbnRhaW5pbmdTeW1ib2woKSBvciBGaW5kRmlsZUNvbnRhaW5pbmdFeHRlbnNpb24oKSByZXR1cm4gYQorICAvLyBmaWxlIHRoYXQgaXMgYWxyZWFkeSBpbiB0aGUgRGVzY3JpcHRvclBvb2wsIGl0IHNob3VsZCBub3QgYXR0ZW1wdCB0bworICAvLyByZWxvYWQgdGhlIGZpbGUuCisgIEZhbHNlUG9zaXRpdmVEYXRhYmFzZSBmYWxzZV9wb3NpdGl2ZV9kYXRhYmFzZSgmZGF0YWJhc2VfKTsKKyAgTW9ja0Vycm9yQ29sbGVjdG9yIGVycm9yX2NvbGxlY3RvcjsKKyAgRGVzY3JpcHRvclBvb2wgcG9vbCgmZmFsc2VfcG9zaXRpdmVfZGF0YWJhc2UsICZlcnJvcl9jb2xsZWN0b3IpOworCisgIC8vIEZpcnN0IG1ha2Ugc3VyZSBmb28ucHJvdG8gaXMgbG9hZGVkLgorICBjb25zdCBEZXNjcmlwdG9yKiBmb28gPSBwb29sLkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgiRm9vIik7CisgIEFTU0VSVF9UUlVFKGZvbyAhPSBOVUxMKTsKKworICAvLyBUcnkgaW5kdWNpbmcgZmFsc2UgcG9zaXRpdmVzLgorICBFWFBFQ1RfVFJVRShwb29sLkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgiTm9TdWNoU3ltYm9sIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKHBvb2wuRmluZEV4dGVuc2lvbkJ5TnVtYmVyKGZvbywgMjIpID09IE5VTEwpOworCisgIC8vIE5vIGVycm9ycyBzaG91bGQgaGF2ZSBiZWVuIHJlcG9ydGVkLiAgKElmIGZvby5wcm90byB3YXMgaW5jb3JyZWN0bHkKKyAgLy8gbG9hZGVkIG11bHRpcGxlIHRpbWVzLCBlcnJvcnMgd291bGQgaGF2ZSBiZWVuIHJlcG9ydGVkLikKKyAgRVhQRUNUX0VRKCIiLCBlcnJvcl9jb2xsZWN0b3IudGV4dF8pOworfQorCisvLyBEZXNjcmlwdG9yRGF0YWJhc2UgdGhhdCBhdHRlbXB0cyB0byBpbmR1Y2UgZXhwb25lbnRpYWxseS1iYWQgcGVyZm9ybWFuY2UKKy8vIGluIERlc2NyaXB0b3JQb29sLiBGb3IgZXZlcnkgcG9zaXRpdmUgTiwgdGhlIGRhdGFiYXNlIGNvbnRhaW5zIGEgZmlsZQorLy8gZmlsZU4ucHJvdG8sIHdoaWNoIGRlZmluZXMgYSBtZXNzYWdlIE1lc3NhZ2VOLCB3aGljaCBjb250YWlucyBmaWVsZHMgb2YKKy8vIHR5cGUgTWVzc2FnZUsgZm9yIGFsbCBLIGluIFswLE4pLiBNZXNzYWdlMCBpcyBub3QgZGVmaW5lZCBhbnl3aGVyZQorLy8gKGZpbGUwLnByb3RvIGV4aXN0cywgYnV0IGlzIGVtcHR5KSwgc28gZXZlcnkgb3RoZXIgZmlsZSBhbmQgbWVzc2FnZSB0eXBlCisvLyB3aWxsIGZhaWwgdG8gYnVpbGQuCisvLworLy8gSWYgdGhlIERlc2NyaXB0b3JQb29sIGlzIG5vdCBjYXJlZnVsIHRvIG1lbW9pemUgZXJyb3JzLCBhbiBhdHRlbXB0IHRvCisvLyBidWlsZCBhIGRlc2NyaXB0b3IgZm9yIE1lc3NhZ2VOIGNhbiByZXF1aXJlIE8oMl5OKSB0aW1lLgorY2xhc3MgRXhwb25lbnRpYWxFcnJvckRhdGFiYXNlIDogcHVibGljIERlc2NyaXB0b3JEYXRhYmFzZSB7CisgcHVibGljOgorICBFeHBvbmVudGlhbEVycm9yRGF0YWJhc2UoKSB7fQorICB+RXhwb25lbnRpYWxFcnJvckRhdGFiYXNlKCkge30KKworICAvLyBpbXBsZW1lbnRzIERlc2NyaXB0b3JEYXRhYmFzZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgYm9vbCBGaW5kRmlsZUJ5TmFtZShjb25zdCBzdHJpbmcmIGZpbGVuYW1lLAorICAgICAgICAgICAgICAgICAgICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8qIG91dHB1dCkgeworICAgIGludCBmaWxlX251bSA9IC0xOworICAgIEZ1bGxNYXRjaChmaWxlbmFtZSwgImZpbGUiLCAiLnByb3RvIiwgJmZpbGVfbnVtKTsKKyAgICBpZiAoZmlsZV9udW0gPiAtMSkgeworICAgICAgcmV0dXJuIFBvcHVsYXRlRmlsZShmaWxlX251bSwgb3V0cHV0KTsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgfQorICBib29sIEZpbmRGaWxlQ29udGFpbmluZ1N5bWJvbChjb25zdCBzdHJpbmcmIHN5bWJvbF9uYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlRGVzY3JpcHRvclByb3RvKiBvdXRwdXQpIHsKKyAgICBpbnQgZmlsZV9udW0gPSAtMTsKKyAgICBGdWxsTWF0Y2goc3ltYm9sX25hbWUsICJNZXNzYWdlIiwgIiIsICZmaWxlX251bSk7CisgICAgaWYgKGZpbGVfbnVtID4gMCkgeworICAgICAgcmV0dXJuIFBvcHVsYXRlRmlsZShmaWxlX251bSwgb3V0cHV0KTsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgfQorICBib29sIEZpbmRGaWxlQ29udGFpbmluZ0V4dGVuc2lvbihjb25zdCBzdHJpbmcmIGNvbnRhaW5pbmdfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmlsZURlc2NyaXB0b3JQcm90byogb3V0cHV0KSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyBwcml2YXRlOgorICB2b2lkIEZ1bGxNYXRjaChjb25zdCBzdHJpbmcmIG5hbWUsCisgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgYmVnaW5fd2l0aCwKKyAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBlbmRfd2l0aCwKKyAgICAgICAgICAgICAgICAgaW50KiBmaWxlX251bSkgeworICAgIGludCBiZWdpbl9zaXplID0gYmVnaW5fd2l0aC5zaXplKCk7CisgICAgaW50IGVuZF9zaXplID0gZW5kX3dpdGguc2l6ZSgpOworICAgIGlmIChuYW1lLnN1YnN0cigwLCBiZWdpbl9zaXplKSAhPSBiZWdpbl93aXRoIHx8CisgICAgICAgIG5hbWUuc3Vic3RyKG5hbWUuc2l6ZSgpLSBlbmRfc2l6ZSwgZW5kX3NpemUpICE9IGVuZF93aXRoKSB7CisgICAgICByZXR1cm47CisgICAgfQorICAgIHNhZmVfc3RydG8zMihuYW1lLnN1YnN0cihiZWdpbl9zaXplLCBuYW1lLnNpemUoKSAtIGVuZF9zaXplIC0gYmVnaW5fc2l6ZSksCisgICAgICAgICAgICAgICAgIGZpbGVfbnVtKTsKKyAgfQorCisgIGJvb2wgUG9wdWxhdGVGaWxlKGludCBmaWxlX251bSwgRmlsZURlc2NyaXB0b3JQcm90byogb3V0cHV0KSB7CisgICAgdXNpbmcgc3RyaW5nczo6U3Vic3RpdHV0ZTsKKyAgICBHT09HTEVfQ0hFQ0tfR0UoZmlsZV9udW0sIDApOworICAgIG91dHB1dC0+Q2xlYXIoKTsKKyAgICBvdXRwdXQtPnNldF9uYW1lKFN1YnN0aXR1dGUoImZpbGUkMC5wcm90byIsIGZpbGVfbnVtKSk7CisgICAgLy8gZmlsZTAucHJvdG8gZG9lc24ndCBkZWZpbmUgTWVzc2FnZTAKKyAgICBpZiAoZmlsZV9udW0gPiAwKSB7CisgICAgICBEZXNjcmlwdG9yUHJvdG8qIG1lc3NhZ2UgPSBvdXRwdXQtPmFkZF9tZXNzYWdlX3R5cGUoKTsKKyAgICAgIG1lc3NhZ2UtPnNldF9uYW1lKFN1YnN0aXR1dGUoIk1lc3NhZ2UkMCIsIGZpbGVfbnVtKSk7CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVfbnVtOyArK2kpIHsKKyAgICAgICAgb3V0cHV0LT5hZGRfZGVwZW5kZW5jeShTdWJzdGl0dXRlKCJmaWxlJDAucHJvdG8iLCBpKSk7CisgICAgICAgIEZpZWxkRGVzY3JpcHRvclByb3RvKiBmaWVsZCA9IG1lc3NhZ2UtPmFkZF9maWVsZCgpOworICAgICAgICBmaWVsZC0+c2V0X25hbWUoU3Vic3RpdHV0ZSgiZmllbGQkMCIsIGkpKTsKKyAgICAgICAgZmllbGQtPnNldF9udW1iZXIoaSk7CisgICAgICAgIGZpZWxkLT5zZXRfbGFiZWwoRmllbGREZXNjcmlwdG9yUHJvdG86OkxBQkVMX09QVElPTkFMKTsKKyAgICAgICAgZmllbGQtPnNldF90eXBlKEZpZWxkRGVzY3JpcHRvclByb3RvOjpUWVBFX01FU1NBR0UpOworICAgICAgICBmaWVsZC0+c2V0X3R5cGVfbmFtZShTdWJzdGl0dXRlKCJNZXNzYWdlJDAiLCBpKSk7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiB0cnVlOworICB9Cit9OworCitURVNUX0YoRGF0YWJhc2VCYWNrZWRQb29sVGVzdCwgRG9lc250UmVsb2FkS25vd25CYWRGaWxlcykgeworICBFeHBvbmVudGlhbEVycm9yRGF0YWJhc2UgZXJyb3JfZGF0YWJhc2U7CisgIERlc2NyaXB0b3JQb29sIHBvb2woJmVycm9yX2RhdGFiYXNlKTsKKworICBHT09HTEVfTE9HKElORk8pIDw8ICJBIHRpbWVvdXQgaW4gdGhpcyB0ZXN0IHByb2JhYmx5IGluZGljYXRlcyBhIHJlYWwgYnVnLiI7CisKKyAgRVhQRUNUX1RSVUUocG9vbC5GaW5kRmlsZUJ5TmFtZSgiZmlsZTQwLnByb3RvIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKHBvb2wuRmluZE1lc3NhZ2VUeXBlQnlOYW1lKCJNZXNzYWdlNDAiKSA9PSBOVUxMKTsKK30KKworVEVTVF9GKERhdGFiYXNlQmFja2VkUG9vbFRlc3QsIERvZXNudEZhbGxiYWNrT25Xcm9uZ1R5cGUpIHsKKyAgLy8gSWYgYSBsb29rdXAgZmluZHMgYSBzeW1ib2wgb2YgdGhlIHdyb25nIHR5cGUgKGUuZy4gd2UgcGFzcyBhIHR5cGUgbmFtZQorICAvLyB0byBGaW5kRmllbGRCeU5hbWUoKSksIHdlIHNob3VsZCBmYWlsIGZhc3QsIHdpdGhvdXQgY2hlY2tpbmcgdGhlIGZhbGxiYWNrCisgIC8vIGRhdGFiYXNlLgorICBDYWxsQ291bnRpbmdEYXRhYmFzZSBjYWxsX2NvdW50ZXIoJmRhdGFiYXNlXyk7CisgIERlc2NyaXB0b3JQb29sIHBvb2woJmNhbGxfY291bnRlcik7CisKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUgPSBwb29sLkZpbmRGaWxlQnlOYW1lKCJmb28ucHJvdG8iKTsKKyAgQVNTRVJUX1RSVUUoZmlsZSAhPSBOVUxMKTsKKyAgY29uc3QgRGVzY3JpcHRvciogZm9vID0gcG9vbC5GaW5kTWVzc2FnZVR5cGVCeU5hbWUoIkZvbyIpOworICBBU1NFUlRfVFJVRShmb28gIT0gTlVMTCk7CisgIGNvbnN0IEVudW1EZXNjcmlwdG9yKiB0ZXN0X2VudW0gPSBwb29sLkZpbmRFbnVtVHlwZUJ5TmFtZSgiVGVzdEVudW0iKTsKKyAgQVNTRVJUX1RSVUUodGVzdF9lbnVtICE9IE5VTEwpOworCisgIEVYUEVDVF9ORSgwLCBjYWxsX2NvdW50ZXIuY2FsbF9jb3VudF8pOworICBjYWxsX2NvdW50ZXIuQ2xlYXIoKTsKKworICBFWFBFQ1RfVFJVRShwb29sLkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgiVGVzdEVudW0iKSA9PSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUocG9vbC5GaW5kRmllbGRCeU5hbWUoIkZvbyIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShwb29sLkZpbmRFeHRlbnNpb25CeU5hbWUoIkZvbyIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShwb29sLkZpbmRFbnVtVHlwZUJ5TmFtZSgiRm9vIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKHBvb2wuRmluZEVudW1WYWx1ZUJ5TmFtZSgiRm9vIikgPT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKHBvb2wuRmluZFNlcnZpY2VCeU5hbWUoIkZvbyIpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShwb29sLkZpbmRNZXRob2RCeU5hbWUoIkZvbyIpID09IE5VTEwpOworCisgIEVYUEVDVF9FUSgwLCBjYWxsX2NvdW50ZXIuY2FsbF9jb3VudF8pOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK2NsYXNzIEFib3J0aW5nRXJyb3JDb2xsZWN0b3IgOiBwdWJsaWMgRGVzY3JpcHRvclBvb2w6OkVycm9yQ29sbGVjdG9yIHsKKyBwdWJsaWM6CisgIEFib3J0aW5nRXJyb3JDb2xsZWN0b3IoKSB7fQorCisgIHZpcnR1YWwgdm9pZCBBZGRFcnJvcigKKyAgICAgIGNvbnN0IHN0cmluZyAmZmlsZW5hbWUsCisgICAgICBjb25zdCBzdHJpbmcgJmVsZW1lbnRfbmFtZSwKKyAgICAgIGNvbnN0IE1lc3NhZ2UgKm1lc3NhZ2UsCisgICAgICBFcnJvckxvY2F0aW9uIGxvY2F0aW9uLAorICAgICAgY29uc3Qgc3RyaW5nICZlcnJvcl9tZXNzYWdlKSB7CisgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkFkZEVycm9yKCkgY2FsbGVkIHVuZXhwZWN0ZWRseTogIiA8PCBmaWxlbmFtZSA8PCAiIFsiCisgICAgICAgICAgICAgICA8PCBlbGVtZW50X25hbWUgPDwgIl06ICIgPDwgZXJyb3JfbWVzc2FnZTsKKyAgfQorIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhBYm9ydGluZ0Vycm9yQ29sbGVjdG9yKTsKK307CisKKy8vIEEgc291cmNlIHRyZWUgY29udGFpbmluZyBvbmx5IG9uZSBmaWxlLgorY2xhc3MgU2luZ2xldG9uU291cmNlVHJlZSA6IHB1YmxpYyBjb21waWxlcjo6U291cmNlVHJlZSB7CisgcHVibGljOgorICBTaW5nbGV0b25Tb3VyY2VUcmVlKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUsIGNvbnN0IHN0cmluZyYgY29udGVudHMpCisgICAgICA6IGZpbGVuYW1lXyhmaWxlbmFtZSksIGNvbnRlbnRzXyhjb250ZW50cykge30KKworICB2aXJ0dWFsIGlvOjpaZXJvQ29weUlucHV0U3RyZWFtKiBPcGVuKGNvbnN0IHN0cmluZyYgZmlsZW5hbWUpIHsKKyAgICByZXR1cm4gZmlsZW5hbWUgPT0gZmlsZW5hbWVfID8KKyAgICAgICAgbmV3IGlvOjpBcnJheUlucHV0U3RyZWFtKGNvbnRlbnRzXy5kYXRhKCksIGNvbnRlbnRzXy5zaXplKCkpIDogTlVMTDsKKyAgfQorCisgcHJpdmF0ZToKKyAgY29uc3Qgc3RyaW5nIGZpbGVuYW1lXzsKKyAgY29uc3Qgc3RyaW5nIGNvbnRlbnRzXzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoU2luZ2xldG9uU291cmNlVHJlZSk7Cit9OworCitjb25zdCBjaGFyICpjb25zdCBrU291cmNlTG9jYXRpb25UZXN0SW5wdXQgPQorICAic3ludGF4ID0gXCJwcm90bzJcIjtcbiIKKyAgIm1lc3NhZ2UgQSB7XG4iCisgICIgIG9wdGlvbmFsIGludDMyIGEgPSAxO1xuIgorICAiICBtZXNzYWdlIEIge1xuIgorICAiICAgIHJlcXVpcmVkIGRvdWJsZSBiID0gMTtcbiIKKyAgIiAgfVxuIgorICAifVxuIgorICAiZW51bSBJbmRlY2lzaW9uIHtcbiIKKyAgIiAgWUVTICAgPSAxO1xuIgorICAiICBOTyAgICA9IDI7XG4iCisgICIgIE1BWUJFID0gMztcbiIKKyAgIn1cbiIKKyAgInNlcnZpY2UgUyB7XG4iCisgICIgIHJwYyBNZXRob2QoQSkgcmV0dXJucyAoQS5CKTtcbiIKKyAgLy8gUHV0IGFuIGVtcHR5IGxpbmUgaGVyZSB0byBtYWtlIHRoZSBzb3VyY2UgbG9jYXRpb24gcmFuZ2UgbWF0Y2guCisgICJcbiIKKyAgIn1cbiIKKyAgIm1lc3NhZ2UgTWVzc2FnZVdpdGhFeHRlbnNpb25zIHtcbiIKKyAgIiAgZXh0ZW5zaW9ucyAxMDAwIHRvIG1heDtcbiIKKyAgIn1cbiIKKyAgImV4dGVuZCBNZXNzYWdlV2l0aEV4dGVuc2lvbnMge1xuIgorICAiICBvcHRpb25hbCBpbnQzMiBpbnQzMl9leHRlbnNpb24gPSAxMDAxO1xuIgorICAifVxuIgorICAibWVzc2FnZSBDIHtcbiIKKyAgIiAgZXh0ZW5kIE1lc3NhZ2VXaXRoRXh0ZW5zaW9ucyB7XG4iCisgICIgICAgb3B0aW9uYWwgQyBtZXNzYWdlX2V4dGVuc2lvbiA9IDEwMDI7XG4iCisgICIgIH1cbiIKKyAgIn1cbiI7CisKK2NsYXNzIFNvdXJjZUxvY2F0aW9uVGVzdCA6IHB1YmxpYyB0ZXN0aW5nOjpUZXN0IHsKKyBwdWJsaWM6CisgIFNvdXJjZUxvY2F0aW9uVGVzdCgpCisgICAgICA6IHNvdXJjZV90cmVlXygiL3Rlc3QvdGVzdC5wcm90byIsIGtTb3VyY2VMb2NhdGlvblRlc3RJbnB1dCksCisgICAgICAgIGRiXygmc291cmNlX3RyZWVfKSwKKyAgICAgICAgcG9vbF8oJmRiXywgJmNvbGxlY3Rvcl8pIHt9CisKKyAgc3RhdGljIHN0cmluZyBQcmludFNvdXJjZUxvY2F0aW9uKGNvbnN0IFNvdXJjZUxvY2F0aW9uICZsb2MpIHsKKyAgICByZXR1cm4gc3RyaW5nczo6U3Vic3RpdHV0ZSgiJDA6JDEtJDI6JDMiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEgKyBsb2Muc3RhcnRfbGluZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxICsgbG9jLnN0YXJ0X2NvbHVtbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxICsgbG9jLmVuZF9saW5lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEgKyBsb2MuZW5kX2NvbHVtbik7CisgIH0KKworIHByaXZhdGU6CisgIEFib3J0aW5nRXJyb3JDb2xsZWN0b3IgY29sbGVjdG9yXzsKKyAgU2luZ2xldG9uU291cmNlVHJlZSBzb3VyY2VfdHJlZV87CisgIGNvbXBpbGVyOjpTb3VyY2VUcmVlRGVzY3JpcHRvckRhdGFiYXNlIGRiXzsKKworIHByb3RlY3RlZDoKKyAgRGVzY3JpcHRvclBvb2wgcG9vbF87Cit9OworCisvLyBUT0RPKGFkb25vdmFuKTogaW1wbGVtZW50IHN1cHBvcnQgZm9yIG9wdGlvbiBmaWVsZHMgYW5kIGZvcgorLy8gc3VicGFydHMgb2YgZGVjbGFyYXRpb25zLgorCitURVNUX0YoU291cmNlTG9jYXRpb25UZXN0LCBHZXRTb3VyY2VMb2NhdGlvbikgeworICBTb3VyY2VMb2NhdGlvbiBsb2M7CisKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IgKmZpbGVfZGVzYyA9CisgICAgICBHT09HTEVfQ0hFQ0tfTk9UTlVMTChwb29sXy5GaW5kRmlsZUJ5TmFtZSgiL3Rlc3QvdGVzdC5wcm90byIpKTsKKworICBjb25zdCBEZXNjcmlwdG9yICphX2Rlc2MgPSBmaWxlX2Rlc2MtPkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgiQSIpOworICBFWFBFQ1RfVFJVRShhX2Rlc2MtPkdldFNvdXJjZUxvY2F0aW9uKCZsb2MpKTsKKyAgRVhQRUNUX0VRKCIyOjEtNzoyIiwgUHJpbnRTb3VyY2VMb2NhdGlvbihsb2MpKTsKKworICBjb25zdCBEZXNjcmlwdG9yICphX2JfZGVzYyA9IGFfZGVzYy0+RmluZE5lc3RlZFR5cGVCeU5hbWUoIkIiKTsKKyAgRVhQRUNUX1RSVUUoYV9iX2Rlc2MtPkdldFNvdXJjZUxvY2F0aW9uKCZsb2MpKTsKKyAgRVhQRUNUX0VRKCI0OjMtNjo0IiwgUHJpbnRTb3VyY2VMb2NhdGlvbihsb2MpKTsKKworICBjb25zdCBFbnVtRGVzY3JpcHRvciAqZV9kZXNjID0gZmlsZV9kZXNjLT5GaW5kRW51bVR5cGVCeU5hbWUoIkluZGVjaXNpb24iKTsKKyAgRVhQRUNUX1RSVUUoZV9kZXNjLT5HZXRTb3VyY2VMb2NhdGlvbigmbG9jKSk7CisgIEVYUEVDVF9FUSgiODoxLTEyOjIiLCBQcmludFNvdXJjZUxvY2F0aW9uKGxvYykpOworCisgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IgKnllc19kZXNjID0gZV9kZXNjLT5GaW5kVmFsdWVCeU5hbWUoIllFUyIpOworICBFWFBFQ1RfVFJVRSh5ZXNfZGVzYy0+R2V0U291cmNlTG9jYXRpb24oJmxvYykpOworICBFWFBFQ1RfRVEoIjk6My05OjEzIiwgUHJpbnRTb3VyY2VMb2NhdGlvbihsb2MpKTsKKworICBjb25zdCBTZXJ2aWNlRGVzY3JpcHRvciAqc19kZXNjID0gZmlsZV9kZXNjLT5GaW5kU2VydmljZUJ5TmFtZSgiUyIpOworICBFWFBFQ1RfVFJVRShzX2Rlc2MtPkdldFNvdXJjZUxvY2F0aW9uKCZsb2MpKTsKKyAgRVhQRUNUX0VRKCIxMzoxLTE2OjIiLCBQcmludFNvdXJjZUxvY2F0aW9uKGxvYykpOworCisgIGNvbnN0IE1ldGhvZERlc2NyaXB0b3IgKm1fZGVzYyA9IHNfZGVzYy0+RmluZE1ldGhvZEJ5TmFtZSgiTWV0aG9kIik7CisgIEVYUEVDVF9UUlVFKG1fZGVzYy0+R2V0U291cmNlTG9jYXRpb24oJmxvYykpOworICBFWFBFQ1RfRVEoIjE0OjMtMTQ6MzEiLCBQcmludFNvdXJjZUxvY2F0aW9uKGxvYykpOworCit9CisKK1RFU1RfRihTb3VyY2VMb2NhdGlvblRlc3QsIEV4dGVuc2lvblNvdXJjZUxvY2F0aW9uKSB7CisgIFNvdXJjZUxvY2F0aW9uIGxvYzsKKworICBjb25zdCBGaWxlRGVzY3JpcHRvciAqZmlsZV9kZXNjID0KKyAgICAgIEdPT0dMRV9DSEVDS19OT1ROVUxMKHBvb2xfLkZpbmRGaWxlQnlOYW1lKCIvdGVzdC90ZXN0LnByb3RvIikpOworCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciAqaW50MzJfZXh0ZW5zaW9uX2Rlc2MgPQorICAgICAgZmlsZV9kZXNjLT5GaW5kRXh0ZW5zaW9uQnlOYW1lKCJpbnQzMl9leHRlbnNpb24iKTsKKyAgRVhQRUNUX1RSVUUoaW50MzJfZXh0ZW5zaW9uX2Rlc2MtPkdldFNvdXJjZUxvY2F0aW9uKCZsb2MpKTsKKyAgRVhQRUNUX0VRKCIyMTozLTIxOjQxIiwgUHJpbnRTb3VyY2VMb2NhdGlvbihsb2MpKTsKKworICBjb25zdCBEZXNjcmlwdG9yICpjX2Rlc2MgPSBmaWxlX2Rlc2MtPkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgiQyIpOworICBFWFBFQ1RfVFJVRShjX2Rlc2MtPkdldFNvdXJjZUxvY2F0aW9uKCZsb2MpKTsKKyAgRVhQRUNUX0VRKCIyMzoxLTI3OjIiLCBQcmludFNvdXJjZUxvY2F0aW9uKGxvYykpOworCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciAqbWVzc2FnZV9leHRlbnNpb25fZGVzYyA9CisgICAgICBjX2Rlc2MtPkZpbmRFeHRlbnNpb25CeU5hbWUoIm1lc3NhZ2VfZXh0ZW5zaW9uIik7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2VfZXh0ZW5zaW9uX2Rlc2MtPkdldFNvdXJjZUxvY2F0aW9uKCZsb2MpKTsKKyAgRVhQRUNUX0VRKCIyNTo1LTI1OjQxIiwgUHJpbnRTb3VyY2VMb2NhdGlvbihsb2MpKTsKK30KKworLy8gTWlzc2luZyBTb3VyY2VDb2RlSW5mbyBkb2Vzbid0IGNhdXNlIGNyYXNoOgorVEVTVF9GKFNvdXJjZUxvY2F0aW9uVGVzdCwgR2V0U291cmNlTG9jYXRpb25fTWlzc2luZ1NvdXJjZUNvZGVJbmZvKSB7CisgIFNvdXJjZUxvY2F0aW9uIGxvYzsKKworICBjb25zdCBGaWxlRGVzY3JpcHRvciAqZmlsZV9kZXNjID0KKyAgICAgIEdPT0dMRV9DSEVDS19OT1ROVUxMKHBvb2xfLkZpbmRGaWxlQnlOYW1lKCIvdGVzdC90ZXN0LnByb3RvIikpOworCisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gcHJvdG87CisgIGZpbGVfZGVzYy0+Q29weVRvKCZwcm90byk7ICAvLyBOb3RlLCB0aGlzIGRpc2NhcmRzIHRoZSBTb3VyY2VDb2RlSW5mby4KKyAgRVhQRUNUX0ZBTFNFKHByb3RvLmhhc19zb3VyY2VfY29kZV9pbmZvKCkpOworCisgIERlc2NyaXB0b3JQb29sIGJhZDFfcG9vbCgmcG9vbF8pOworICBjb25zdCBGaWxlRGVzY3JpcHRvciogYmFkMV9maWxlX2Rlc2MgPQorICAgICAgR09PR0xFX0NIRUNLX05PVE5VTEwoYmFkMV9wb29sLkJ1aWxkRmlsZShwcm90bykpOworICBjb25zdCBEZXNjcmlwdG9yICpiYWQxX2FfZGVzYyA9IGJhZDFfZmlsZV9kZXNjLT5GaW5kTWVzc2FnZVR5cGVCeU5hbWUoIkEiKTsKKyAgRVhQRUNUX0ZBTFNFKGJhZDFfYV9kZXNjLT5HZXRTb3VyY2VMb2NhdGlvbigmbG9jKSk7Cit9CisKKy8vIENvcnJ1cHQgU291cmNlQ29kZUluZm8gZG9lc24ndCBjYXVzZSBjcmFzaDoKK1RFU1RfRihTb3VyY2VMb2NhdGlvblRlc3QsIEdldFNvdXJjZUxvY2F0aW9uX0JvZ3VzU291cmNlQ29kZUluZm8pIHsKKyAgU291cmNlTG9jYXRpb24gbG9jOworCisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yICpmaWxlX2Rlc2MgPQorICAgICAgR09PR0xFX0NIRUNLX05PVE5VTEwocG9vbF8uRmluZEZpbGVCeU5hbWUoIi90ZXN0L3Rlc3QucHJvdG8iKSk7CisKKyAgRmlsZURlc2NyaXB0b3JQcm90byBwcm90bzsKKyAgZmlsZV9kZXNjLT5Db3B5VG8oJnByb3RvKTsgIC8vIE5vdGUsIHRoaXMgZGlzY2FyZHMgdGhlIFNvdXJjZUNvZGVJbmZvLgorICBFWFBFQ1RfRkFMU0UocHJvdG8uaGFzX3NvdXJjZV9jb2RlX2luZm8oKSk7CisgIFNvdXJjZUNvZGVJbmZvX0xvY2F0aW9uICpsb2NfbXNnID0KKyAgICAgIHByb3RvLm11dGFibGVfc291cmNlX2NvZGVfaW5mbygpLT5hZGRfbG9jYXRpb24oKTsKKyAgbG9jX21zZy0+YWRkX3BhdGgoMSk7CisgIGxvY19tc2ctPmFkZF9wYXRoKDIpOworICBsb2NfbXNnLT5hZGRfcGF0aCgzKTsKKyAgbG9jX21zZy0+YWRkX3NwYW4oNCk7CisgIGxvY19tc2ctPmFkZF9zcGFuKDUpOworICBsb2NfbXNnLT5hZGRfc3Bhbig2KTsKKworICBEZXNjcmlwdG9yUG9vbCBiYWQyX3Bvb2woJnBvb2xfKTsKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGJhZDJfZmlsZV9kZXNjID0KKyAgICAgIEdPT0dMRV9DSEVDS19OT1ROVUxMKGJhZDJfcG9vbC5CdWlsZEZpbGUocHJvdG8pKTsKKyAgY29uc3QgRGVzY3JpcHRvciAqYmFkMl9hX2Rlc2MgPSBiYWQyX2ZpbGVfZGVzYy0+RmluZE1lc3NhZ2VUeXBlQnlOYW1lKCJBIik7CisgIEVYUEVDVF9GQUxTRShiYWQyX2FfZGVzYy0+R2V0U291cmNlTG9jYXRpb24oJmxvYykpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK2NvbnN0IGNoYXIqIGNvbnN0IGtDb3B5U291cmNlQ29kZUluZm9Ub1Rlc3RJbnB1dCA9CisgICJzeW50YXggPSBcInByb3RvMlwiO1xuIgorICAibWVzc2FnZSBGb28ge31cbiI7CisKKy8vIFJlcXVpcmVkIHNpbmNlIHNvdXJjZSBjb2RlIGluZm9ybWF0aW9uIGlzIG5vdCBwcmVzZXJ2ZWQgYnkKKy8vIEZpbGVEZXNjcmlwdG9yVGVzdC4KK2NsYXNzIENvcHlTb3VyY2VDb2RlSW5mb1RvVGVzdCA6IHB1YmxpYyB0ZXN0aW5nOjpUZXN0IHsKKyBwdWJsaWM6CisgIENvcHlTb3VyY2VDb2RlSW5mb1RvVGVzdCgpCisgICAgICA6IHNvdXJjZV90cmVlXygiL3Rlc3QvdGVzdC5wcm90byIsIGtDb3B5U291cmNlQ29kZUluZm9Ub1Rlc3RJbnB1dCksCisgICAgICAgIGRiXygmc291cmNlX3RyZWVfKSwKKyAgICAgICAgcG9vbF8oJmRiXywgJmNvbGxlY3Rvcl8pIHt9CisKKyBwcml2YXRlOgorICBBYm9ydGluZ0Vycm9yQ29sbGVjdG9yIGNvbGxlY3Rvcl87CisgIFNpbmdsZXRvblNvdXJjZVRyZWUgc291cmNlX3RyZWVfOworICBjb21waWxlcjo6U291cmNlVHJlZURlc2NyaXB0b3JEYXRhYmFzZSBkYl87CisKKyBwcm90ZWN0ZWQ6CisgIERlc2NyaXB0b3JQb29sIHBvb2xfOworfTsKKworVEVTVF9GKENvcHlTb3VyY2VDb2RlSW5mb1RvVGVzdCwgQ29weVRvX0RvZXNOb3RDb3B5U291cmNlQ29kZUluZm8pIHsKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGVfZGVzYyA9CisgICAgICBHT09HTEVfQ0hFQ0tfTk9UTlVMTChwb29sXy5GaW5kRmlsZUJ5TmFtZSgiL3Rlc3QvdGVzdC5wcm90byIpKTsKKyAgRmlsZURlc2NyaXB0b3JQcm90byBmaWxlX2Rlc2NfcHJvdG87CisgIEFTU0VSVF9GQUxTRShmaWxlX2Rlc2NfcHJvdG8uaGFzX3NvdXJjZV9jb2RlX2luZm8oKSk7CisKKyAgZmlsZV9kZXNjLT5Db3B5VG8oJmZpbGVfZGVzY19wcm90byk7CisgIEVYUEVDVF9GQUxTRShmaWxlX2Rlc2NfcHJvdG8uaGFzX3NvdXJjZV9jb2RlX2luZm8oKSk7Cit9CisKK1RFU1RfRihDb3B5U291cmNlQ29kZUluZm9Ub1Rlc3QsIENvcHlTb3VyY2VDb2RlSW5mb1RvKSB7CisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlX2Rlc2MgPQorICAgICAgR09PR0xFX0NIRUNLX05PVE5VTEwocG9vbF8uRmluZEZpbGVCeU5hbWUoIi90ZXN0L3Rlc3QucHJvdG8iKSk7CisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZV9kZXNjX3Byb3RvOworICBBU1NFUlRfRkFMU0UoZmlsZV9kZXNjX3Byb3RvLmhhc19zb3VyY2VfY29kZV9pbmZvKCkpOworCisgIGZpbGVfZGVzYy0+Q29weVNvdXJjZUNvZGVJbmZvVG8oJmZpbGVfZGVzY19wcm90byk7CisgIGNvbnN0IFNvdXJjZUNvZGVJbmZvJiBpbmZvID0gZmlsZV9kZXNjX3Byb3RvLnNvdXJjZV9jb2RlX2luZm8oKTsKKyAgQVNTRVJUX0VRKDQsIGluZm8ubG9jYXRpb25fc2l6ZSgpKTsKKyAgLy8gR2V0IHRoZSBGb28gbWVzc2FnZSBsb2NhdGlvbgorICBjb25zdCBTb3VyY2VDb2RlSW5mb19Mb2NhdGlvbiYgZm9vX2xvY2F0aW9uID0gaW5mby5sb2NhdGlvbigyKTsKKyAgQVNTRVJUX0VRKDIsIGZvb19sb2NhdGlvbi5wYXRoX3NpemUoKSk7CisgIEVYUEVDVF9FUShGaWxlRGVzY3JpcHRvclByb3RvOjprTWVzc2FnZVR5cGVGaWVsZE51bWJlciwgZm9vX2xvY2F0aW9uLnBhdGgoMCkpOworICBFWFBFQ1RfRVEoMCwgZm9vX2xvY2F0aW9uLnBhdGgoMSkpOyAgICAgIC8vIEZvbyBpcyB0aGUgZmlyc3QgbWVzc2FnZSBkZWZpbmVkCisgIEFTU0VSVF9FUSgzLCBmb29fbG9jYXRpb24uc3Bhbl9zaXplKCkpOyAgLy8gRm9vIHNwYW5zIG9uZSBsaW5lCisgIEVYUEVDVF9FUSgxLCBmb29fbG9jYXRpb24uc3BhbigwKSk7ICAgICAgLy8gRm9vIGlzIGRlY2xhcmVkIG9uIGxpbmUgMQorICBFWFBFQ1RfRVEoMCwgZm9vX2xvY2F0aW9uLnNwYW4oMSkpOyAgICAgIC8vIEZvbyBzdGFydHMgYXQgY29sdW1uIDAKKyAgRVhQRUNUX0VRKDE0LCBmb29fbG9jYXRpb24uc3BhbigyKSk7ICAgICAvLyBGb28gZW5kcyBvbiBjb2x1bW4gMTQKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisKK30gIC8vIG5hbWVzcGFjZSBkZXNjcmlwdG9yX3VuaXR0ZXN0Cit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvZHJvcF91bmtub3duX2ZpZWxkc190ZXN0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9kcm9wX3Vua25vd25fZmllbGRzX3Rlc3QuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmYxNmRjNQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvZHJvcF91bmtub3duX2ZpZWxkc190ZXN0LmNjCkBAIC0wLDAgKzEsODggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2Ryb3BfdW5rbm93bl9maWVsZHMucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZHluYW1pY19tZXNzYWdlLmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7Cit1c2luZyB1bml0dGVzdF9kcm9wX3Vua25vd25fZmllbGRzOjpGb287Cit1c2luZyB1bml0dGVzdF9kcm9wX3Vua25vd25fZmllbGRzOjpGb29XaXRoRXh0cmFGaWVsZHM7CisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKK1RFU1QoRHJvcFVua25vd25GaWVsZHNUZXN0LCBHZW5lcmF0ZWRNZXNzYWdlKSB7CisgIEZvb1dpdGhFeHRyYUZpZWxkcyBmb29fd2l0aF9leHRyYV9maWVsZHM7CisgIGZvb193aXRoX2V4dHJhX2ZpZWxkcy5zZXRfaW50MzJfdmFsdWUoMSk7CisgIGZvb193aXRoX2V4dHJhX2ZpZWxkcy5zZXRfZW51bV92YWx1ZShGb29XaXRoRXh0cmFGaWVsZHM6OlFVWCk7CisgIGZvb193aXRoX2V4dHJhX2ZpZWxkcy5zZXRfZXh0cmFfaW50MzJfdmFsdWUoMik7CisKKyAgRm9vIGZvbzsKKyAgQVNTRVJUX1RSVUUoZm9vLlBhcnNlRnJvbVN0cmluZyhmb29fd2l0aF9leHRyYV9maWVsZHMuU2VyaWFsaXplQXNTdHJpbmcoKSkpOworICBFWFBFQ1RfRVEoMSwgZm9vLmludDMyX3ZhbHVlKCkpOworICBFWFBFQ1RfRVEoc3RhdGljX2Nhc3Q8aW50PihGb29XaXRoRXh0cmFGaWVsZHM6OlFVWCksCisgICAgICAgICAgICBzdGF0aWNfY2FzdDxpbnQ+KGZvby5lbnVtX3ZhbHVlKCkpKTsKKyAgLy8gV2UgZG9uJ3QgZ2VuZXJhdGUgdW5rbm93biBmaWVsZCBhY2Nlc3NvcnMgYnV0IHRoZSBVbmtub3duRmllbGRTZXQgaXMKKyAgLy8gc3RpbGwgZXhwb3NlZCB0aHJvdWdoIHJlZmxlY3Rpb24gQVBJLgorICBFWFBFQ1RfVFJVRShmb28uR2V0UmVmbGVjdGlvbigpLT5HZXRVbmtub3duRmllbGRzKGZvbykuZW1wdHkoKSk7CisKKyAgQVNTRVJUX1RSVUUoZm9vX3dpdGhfZXh0cmFfZmllbGRzLlBhcnNlRnJvbVN0cmluZyhmb28uU2VyaWFsaXplQXNTdHJpbmcoKSkpOworICBFWFBFQ1RfRVEoMSwgZm9vX3dpdGhfZXh0cmFfZmllbGRzLmludDMyX3ZhbHVlKCkpOworICBFWFBFQ1RfRVEoRm9vV2l0aEV4dHJhRmllbGRzOjpRVVgsIGZvb193aXRoX2V4dHJhX2ZpZWxkcy5lbnVtX3ZhbHVlKCkpOworICAvLyBUaGUgImV4dHJhX2ludDMyX3ZhbHVlIiBmaWVsZCBzaG91bGQgYmUgbG9zdC4KKyAgRVhQRUNUX0VRKDAsIGZvb193aXRoX2V4dHJhX2ZpZWxkcy5leHRyYV9pbnQzMl92YWx1ZSgpKTsKK30KKworVEVTVChEcm9wVW5rbm93bkZpZWxkc1Rlc3QsIER5bmFtaWNNZXNzYWdlKSB7CisgIEZvb1dpdGhFeHRyYUZpZWxkcyBmb29fd2l0aF9leHRyYV9maWVsZHM7CisgIGZvb193aXRoX2V4dHJhX2ZpZWxkcy5zZXRfaW50MzJfdmFsdWUoMSk7CisgIGZvb193aXRoX2V4dHJhX2ZpZWxkcy5zZXRfZW51bV92YWx1ZShGb29XaXRoRXh0cmFGaWVsZHM6OlFVWCk7CisgIGZvb193aXRoX2V4dHJhX2ZpZWxkcy5zZXRfZXh0cmFfaW50MzJfdmFsdWUoMik7CisKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6RHluYW1pY01lc3NhZ2VGYWN0b3J5IGZhY3Rvcnk7CisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZT4gZm9vKAorICAgICAgZmFjdG9yeS5HZXRQcm90b3R5cGUoRm9vOjpkZXNjcmlwdG9yKCkpLT5OZXcoKSk7CisgIEFTU0VSVF9UUlVFKGZvby0+UGFyc2VGcm9tU3RyaW5nKGZvb193aXRoX2V4dHJhX2ZpZWxkcy5TZXJpYWxpemVBc1N0cmluZygpKSk7CisgIEVYUEVDVF9UUlVFKGZvby0+R2V0UmVmbGVjdGlvbigpLT5HZXRVbmtub3duRmllbGRzKCpmb28pLmVtcHR5KCkpOworCisgIEFTU0VSVF9UUlVFKGZvb193aXRoX2V4dHJhX2ZpZWxkcy5QYXJzZUZyb21TdHJpbmcoZm9vLT5TZXJpYWxpemVBc1N0cmluZygpKSk7CisgIEVYUEVDVF9FUSgxLCBmb29fd2l0aF9leHRyYV9maWVsZHMuaW50MzJfdmFsdWUoKSk7CisgIEVYUEVDVF9FUShGb29XaXRoRXh0cmFGaWVsZHM6OlFVWCwgZm9vX3dpdGhfZXh0cmFfZmllbGRzLmVudW1fdmFsdWUoKSk7CisgIC8vIFRoZSAiZXh0cmFfaW50MzJfdmFsdWUiIGZpZWxkIHNob3VsZCBiZSBsb3N0LgorICBFWFBFQ1RfRVEoMCwgZm9vX3dpdGhfZXh0cmFfZmllbGRzLmV4dHJhX2ludDMyX3ZhbHVlKCkpOworfQorCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvZHVyYXRpb24ucGIuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2R1cmF0aW9uLnBiLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIzMjU5NDQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2R1cmF0aW9uLnBiLmNjCkBAIC0wLDAgKzEsNDA4IEBACisvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQorLy8gc291cmNlOiBnb29nbGUvcHJvdG9idWYvZHVyYXRpb24ucHJvdG8KKworI2RlZmluZSBJTlRFUk5BTF9TVVBQUkVTU19QUk9UT0JVRl9GSUVMRF9ERVBSRUNBVElPTgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kdXJhdGlvbi5wYi5oPgorCisjaW5jbHVkZSA8YWxnb3JpdGhtPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9wb3J0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL29uY2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0X2xpdGVfaW5sLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX21lc3NhZ2VfcmVmbGVjdGlvbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9yZWZsZWN0aW9uX29wcy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdC5oPgorLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGluY2x1ZGVzKQorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKK25hbWVzcGFjZSB7CisKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogRHVyYXRpb25fZGVzY3JpcHRvcl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24qCisgIER1cmF0aW9uX3JlZmxlY3Rpb25fID0gTlVMTDsKKworfSAgLy8gbmFtZXNwYWNlCisKKwordm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZHVyYXRpb25fMmVwcm90bygpIHsKKyAgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmR1cmF0aW9uXzJlcHJvdG8oKTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlRGVzY3JpcHRvciogZmlsZSA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUG9vbDo6Z2VuZXJhdGVkX3Bvb2woKS0+RmluZEZpbGVCeU5hbWUoCisgICAgICAiZ29vZ2xlL3Byb3RvYnVmL2R1cmF0aW9uLnByb3RvIik7CisgIEdPT0dMRV9DSEVDSyhmaWxlICE9IE5VTEwpOworICBEdXJhdGlvbl9kZXNjcmlwdG9yXyA9IGZpbGUtPm1lc3NhZ2VfdHlwZSgwKTsKKyAgc3RhdGljIGNvbnN0IGludCBEdXJhdGlvbl9vZmZzZXRzX1syXSA9IHsKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKER1cmF0aW9uLCBzZWNvbmRzXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChEdXJhdGlvbiwgbmFub3NfKSwKKyAgfTsKKyAgRHVyYXRpb25fcmVmbGVjdGlvbl8gPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpOZXdHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbigKKyAgICAgIER1cmF0aW9uX2Rlc2NyaXB0b3JfLAorICAgICAgRHVyYXRpb246OmRlZmF1bHRfaW5zdGFuY2VfLAorICAgICAgRHVyYXRpb25fb2Zmc2V0c18sCisgICAgICAtMSwKKyAgICAgIC0xLAorICAgICAgLTEsCisgICAgICBzaXplb2YoRHVyYXRpb24pLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChEdXJhdGlvbiwgX2ludGVybmFsX21ldGFkYXRhXyksCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKER1cmF0aW9uLCBfaXNfZGVmYXVsdF9pbnN0YW5jZV8pKTsKK30KKworbmFtZXNwYWNlIHsKKworR09PR0xFX1BST1RPQlVGX0RFQ0xBUkVfT05DRShwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc19vbmNlXyk7CitpbmxpbmUgdm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKSB7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6R29vZ2xlT25jZUluaXQoJnByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzX29uY2VfLAorICAgICAgICAgICAgICAgICAmcHJvdG9idWZfQXNzaWduRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmR1cmF0aW9uXzJlcHJvdG8pOworfQorCit2b2lkIHByb3RvYnVmX1JlZ2lzdGVyVHlwZXMoY29uc3QgOjpzdGQ6OnN0cmluZyYpIHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZUZhY3Rvcnk6OkludGVybmFsUmVnaXN0ZXJHZW5lcmF0ZWRNZXNzYWdlKAorICAgICAgRHVyYXRpb25fZGVzY3JpcHRvcl8sICZEdXJhdGlvbjo6ZGVmYXVsdF9pbnN0YW5jZSgpKTsKK30KKworfSAgLy8gbmFtZXNwYWNlCisKK3ZvaWQgcHJvdG9idWZfU2h1dGRvd25GaWxlX2dvb2dsZV8yZnByb3RvYnVmXzJmZHVyYXRpb25fMmVwcm90bygpIHsKKyAgZGVsZXRlIER1cmF0aW9uOjpkZWZhdWx0X2luc3RhbmNlXzsKKyAgZGVsZXRlIER1cmF0aW9uX3JlZmxlY3Rpb25fOworfQorCit2b2lkIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZkdXJhdGlvbl8yZXByb3RvKCkgeworICBzdGF0aWMgYm9vbCBhbHJlYWR5X2hlcmUgPSBmYWxzZTsKKyAgaWYgKGFscmVhZHlfaGVyZSkgcmV0dXJuOworICBhbHJlYWR5X2hlcmUgPSB0cnVlOworICBHT09HTEVfUFJPVE9CVUZfVkVSSUZZX1ZFUlNJT047CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUG9vbDo6SW50ZXJuYWxBZGRHZW5lcmF0ZWRGaWxlKAorICAgICJcblwwMzZnb29nbGUvcHJvdG9idWYvZHVyYXRpb24ucHJvdG9cMDIyXDAxN2dvb2dsZSIKKyAgICAiLnByb3RvYnVmXCIqXG5cMDEwRHVyYXRpb25cMDIyXDAxN1xuXDAwN3NlY29uZHNcMDMwXDAwMSBcMDAxKFwwMDNcMDIyXHIiCisgICAgIlxuXDAwNW5hbm9zXDAzMFwwMDIgXDAwMShcMDA1QlBcblwwMjNjb20uZ29vZ2xlLnByb3RvYnVmQlxyRHUiCisgICAgInJhdGlvblByb3RvUFwwMDFcMjQwXDAwMVwwMDFcMjQyXDAwMlwwMDNHUEJcMjUyXDAwMlwwMzZHb29nbGUuUHJvdG9idWYiCisgICAgIi5XZWxsS25vd25UeXBlc2JcMDA2cHJvdG8zIiwgMTgzKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZEZpbGUoCisgICAgImdvb2dsZS9wcm90b2J1Zi9kdXJhdGlvbi5wcm90byIsICZwcm90b2J1Zl9SZWdpc3RlclR5cGVzKTsKKyAgRHVyYXRpb246OmRlZmF1bHRfaW5zdGFuY2VfID0gbmV3IER1cmF0aW9uKCk7CisgIER1cmF0aW9uOjpkZWZhdWx0X2luc3RhbmNlXy0+SW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6Ok9uU2h1dGRvd24oJnByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZmR1cmF0aW9uXzJlcHJvdG8pOworfQorCisvLyBGb3JjZSBBZGREZXNjcmlwdG9ycygpIHRvIGJlIGNhbGxlZCBhdCBzdGF0aWMgaW5pdGlhbGl6YXRpb24gdGltZS4KK3N0cnVjdCBTdGF0aWNEZXNjcmlwdG9ySW5pdGlhbGl6ZXJfZ29vZ2xlXzJmcHJvdG9idWZfMmZkdXJhdGlvbl8yZXByb3RvIHsKKyAgU3RhdGljRGVzY3JpcHRvckluaXRpYWxpemVyX2dvb2dsZV8yZnByb3RvYnVmXzJmZHVyYXRpb25fMmVwcm90bygpIHsKKyAgICBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZHVyYXRpb25fMmVwcm90bygpOworICB9Cit9IHN0YXRpY19kZXNjcmlwdG9yX2luaXRpYWxpemVyX2dvb2dsZV8yZnByb3RvYnVmXzJmZHVyYXRpb25fMmVwcm90b187CisKK25hbWVzcGFjZSB7CisKK3N0YXRpYyB2b2lkIE1lcmdlRnJvbUZhaWwoaW50IGxpbmUpIEdPT0dMRV9BVFRSSUJVVEVfQ09MRDsKK3N0YXRpYyB2b2lkIE1lcmdlRnJvbUZhaWwoaW50IGxpbmUpIHsKKyAgR09PR0xFX0NIRUNLKGZhbHNlKSA8PCBfX0ZJTEVfXyA8PCAiOiIgPDwgbGluZTsKK30KKworfSAgLy8gbmFtZXNwYWNlCisKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisjaWYgIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKK2NvbnN0IGludCBEdXJhdGlvbjo6a1NlY29uZHNGaWVsZE51bWJlcjsKK2NvbnN0IGludCBEdXJhdGlvbjo6a05hbm9zRmllbGROdW1iZXI7CisjZW5kaWYgIC8vICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCisKK0R1cmF0aW9uOjpEdXJhdGlvbigpCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgeworICBTaGFyZWRDdG9yKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuRHVyYXRpb24pCit9CisKK3ZvaWQgRHVyYXRpb246OkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpIHsKKyAgX2lzX2RlZmF1bHRfaW5zdGFuY2VfID0gdHJ1ZTsKK30KKworRHVyYXRpb246OkR1cmF0aW9uKGNvbnN0IER1cmF0aW9uJiBmcm9tKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpLAorICAgIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgeworICBTaGFyZWRDdG9yKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvcHlfY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uKQorfQorCit2b2lkIER1cmF0aW9uOjpTaGFyZWRDdG9yKCkgeworICAgIF9pc19kZWZhdWx0X2luc3RhbmNlXyA9IGZhbHNlOworICBfY2FjaGVkX3NpemVfID0gMDsKKyAgc2Vjb25kc18gPSBHT09HTEVfTE9OR0xPTkcoMCk7CisgIG5hbm9zXyA9IDA7Cit9CisKK0R1cmF0aW9uOjp+RHVyYXRpb24oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChkZXN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbikKKyAgU2hhcmVkRHRvcigpOworfQorCit2b2lkIER1cmF0aW9uOjpTaGFyZWREdG9yKCkgeworICBpZiAodGhpcyAhPSBkZWZhdWx0X2luc3RhbmNlXykgeworICB9Cit9CisKK3ZvaWQgRHVyYXRpb246OlNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0IHsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHNpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBEdXJhdGlvbjo6ZGVzY3JpcHRvcigpIHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIHJldHVybiBEdXJhdGlvbl9kZXNjcmlwdG9yXzsKK30KKworY29uc3QgRHVyYXRpb24mIER1cmF0aW9uOjpkZWZhdWx0X2luc3RhbmNlKCkgeworICBpZiAoZGVmYXVsdF9pbnN0YW5jZV8gPT0gTlVMTCkgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmR1cmF0aW9uXzJlcHJvdG8oKTsKKyAgcmV0dXJuICpkZWZhdWx0X2luc3RhbmNlXzsKK30KKworRHVyYXRpb24qIER1cmF0aW9uOjpkZWZhdWx0X2luc3RhbmNlXyA9IE5VTEw7CisKK0R1cmF0aW9uKiBEdXJhdGlvbjo6TmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdCB7CisgIER1cmF0aW9uKiBuID0gbmV3IER1cmF0aW9uOworICBpZiAoYXJlbmEgIT0gTlVMTCkgeworICAgIGFyZW5hLT5Pd24obik7CisgIH0KKyAgcmV0dXJuIG47Cit9CisKK3ZvaWQgRHVyYXRpb246OkNsZWFyKCkgeworI2RlZmluZSBaUl9IRUxQRVJfKGYpIHJlaW50ZXJwcmV0X2Nhc3Q8Y2hhcio+KFwKKyAgJnJlaW50ZXJwcmV0X2Nhc3Q8RHVyYXRpb24qPigxNiktPmYpCisKKyNkZWZpbmUgWlJfKGZpcnN0LCBsYXN0KSBkbyB7XAorICA6Om1lbXNldCgmZmlyc3QsIDAsXAorICAgICAgICAgICBaUl9IRUxQRVJfKGxhc3QpIC0gWlJfSEVMUEVSXyhmaXJzdCkgKyBzaXplb2YobGFzdCkpO1wKK30gd2hpbGUgKDApCisKKyAgWlJfKHNlY29uZHNfLCBuYW5vc18pOworCisjdW5kZWYgWlJfSEVMUEVSXworI3VuZGVmIFpSXworCit9CisKK2Jvb2wgRHVyYXRpb246Ok1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCkgeworI2RlZmluZSBET18oRVhQUkVTU0lPTikgaWYgKCEoRVhQUkVTU0lPTikpIGdvdG8gZmFpbHVyZQorICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiB0YWc7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdGFydDpnb29nbGUucHJvdG9idWYuRHVyYXRpb24pCisgIGZvciAoOzspIHsKKyAgICA6OnN0ZDo6cGFpcjwgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIsIGJvb2w+IHAgPSBpbnB1dC0+UmVhZFRhZ1dpdGhDdXRvZmYoMTI3KTsKKyAgICB0YWcgPSBwLmZpcnN0OworICAgIGlmICghcC5zZWNvbmQpIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgc3dpdGNoICg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnRmllbGROdW1iZXIodGFnKSkgeworICAgICAgLy8gb3B0aW9uYWwgaW50NjQgc2Vjb25kcyA9IDE7CisgICAgICBjYXNlIDE6IHsKKyAgICAgICAgaWYgKHRhZyA9PSA4KSB7CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludDY0LCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9JTlQ2ND4oCisgICAgICAgICAgICAgICAgIGlucHV0LCAmc2Vjb25kc18pKSk7CisKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDE2KSkgZ290byBwYXJzZV9uYW5vczsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIGludDMyIG5hbm9zID0gMjsKKyAgICAgIGNhc2UgMjogeworICAgICAgICBpZiAodGFnID09IDE2KSB7CisgICAgICAgICBwYXJzZV9uYW5vczoKKyAgICAgICAgICBET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPAorICAgICAgICAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0lOVDMyPigKKyAgICAgICAgICAgICAgICAgaW5wdXQsICZuYW5vc18pKSk7CisKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0QXRFbmQoKSkgZ290byBzdWNjZXNzOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgZGVmYXVsdDogeworICAgICAgaGFuZGxlX3VudXN1YWw6CisgICAgICAgIGlmICh0YWcgPT0gMCB8fAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ1dpcmVUeXBlKHRhZykgPT0KKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVApIHsKKyAgICAgICAgICBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIH0KKyAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTa2lwRmllbGQoaW5wdXQsIHRhZykpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KK3N1Y2Nlc3M6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdWNjZXNzOmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbikKKyAgcmV0dXJuIHRydWU7CitmYWlsdXJlOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2VfZmFpbHVyZTpnb29nbGUucHJvdG9idWYuRHVyYXRpb24pCisgIHJldHVybiBmYWxzZTsKKyN1bmRlZiBET18KK30KKwordm9pZCBEdXJhdGlvbjo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9zdGFydDpnb29nbGUucHJvdG9idWYuRHVyYXRpb24pCisgIC8vIG9wdGlvbmFsIGludDY0IHNlY29uZHMgPSAxOworICBpZiAodGhpcy0+c2Vjb25kcygpICE9IDApIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVJbnQ2NCgxLCB0aGlzLT5zZWNvbmRzKCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBpbnQzMiBuYW5vcyA9IDI7CisgIGlmICh0aGlzLT5uYW5vcygpICE9IDApIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVJbnQzMigyLCB0aGlzLT5uYW5vcygpLCBvdXRwdXQpOworICB9CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9lbmQ6Z29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uKQorfQorCis6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBEdXJhdGlvbjo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiB0YXJnZXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9zdGFydDpnb29nbGUucHJvdG9idWYuRHVyYXRpb24pCisgIC8vIG9wdGlvbmFsIGludDY0IHNlY29uZHMgPSAxOworICBpZiAodGhpcy0+c2Vjb25kcygpICE9IDApIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVJbnQ2NFRvQXJyYXkoMSwgdGhpcy0+c2Vjb25kcygpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgaW50MzIgbmFub3MgPSAyOworICBpZiAodGhpcy0+bmFub3MoKSAhPSAwKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlSW50MzJUb0FycmF5KDIsIHRoaXMtPm5hbm9zKCksIHRhcmdldCk7CisgIH0KKworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X2VuZDpnb29nbGUucHJvdG9idWYuRHVyYXRpb24pCisgIHJldHVybiB0YXJnZXQ7Cit9CisKK2ludCBEdXJhdGlvbjo6Qnl0ZVNpemUoKSBjb25zdCB7CisgIGludCB0b3RhbF9zaXplID0gMDsKKworICAvLyBvcHRpb25hbCBpbnQ2NCBzZWNvbmRzID0gMTsKKyAgaWYgKHRoaXMtPnNlY29uZHMoKSAhPSAwKSB7CisgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpJbnQ2NFNpemUoCisgICAgICAgIHRoaXMtPnNlY29uZHMoKSk7CisgIH0KKworICAvLyBvcHRpb25hbCBpbnQzMiBuYW5vcyA9IDI7CisgIGlmICh0aGlzLT5uYW5vcygpICE9IDApIHsKKyAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkludDMyU2l6ZSgKKyAgICAgICAgdGhpcy0+bmFub3MoKSk7CisgIH0KKworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gdG90YWxfc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7CisgIHJldHVybiB0b3RhbF9zaXplOworfQorCit2b2lkIER1cmF0aW9uOjpNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGNvbnN0IER1cmF0aW9uKiBzb3VyY2UgPSAKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkR5bmFtaWNDYXN0VG9HZW5lcmF0ZWQ8Y29uc3QgRHVyYXRpb24+KAorICAgICAgICAgICZmcm9tKTsKKyAgaWYgKHNvdXJjZSA9PSBOVUxMKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6UmVmbGVjdGlvbk9wczo6TWVyZ2UoZnJvbSwgdGhpcyk7CisgIH0gZWxzZSB7CisgICAgTWVyZ2VGcm9tKCpzb3VyY2UpOworICB9Cit9CisKK3ZvaWQgRHVyYXRpb246Ok1lcmdlRnJvbShjb25zdCBEdXJhdGlvbiYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBpZiAoZnJvbS5zZWNvbmRzKCkgIT0gMCkgeworICAgIHNldF9zZWNvbmRzKGZyb20uc2Vjb25kcygpKTsKKyAgfQorICBpZiAoZnJvbS5uYW5vcygpICE9IDApIHsKKyAgICBzZXRfbmFub3MoZnJvbS5uYW5vcygpKTsKKyAgfQorfQorCit2b2lkIER1cmF0aW9uOjpDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCit2b2lkIER1cmF0aW9uOjpDb3B5RnJvbShjb25zdCBEdXJhdGlvbiYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK2Jvb2wgRHVyYXRpb246OklzSW5pdGlhbGl6ZWQoKSBjb25zdCB7CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgRHVyYXRpb246OlN3YXAoRHVyYXRpb24qIG90aGVyKSB7CisgIGlmIChvdGhlciA9PSB0aGlzKSByZXR1cm47CisgIEludGVybmFsU3dhcChvdGhlcik7Cit9Cit2b2lkIER1cmF0aW9uOjpJbnRlcm5hbFN3YXAoRHVyYXRpb24qIG90aGVyKSB7CisgIHN0ZDo6c3dhcChzZWNvbmRzXywgb3RoZXItPnNlY29uZHNfKTsKKyAgc3RkOjpzd2FwKG5hbm9zXywgb3RoZXItPm5hbm9zXyk7CisgIF9pbnRlcm5hbF9tZXRhZGF0YV8uU3dhcCgmb3RoZXItPl9pbnRlcm5hbF9tZXRhZGF0YV8pOworICBzdGQ6OnN3YXAoX2NhY2hlZF9zaXplXywgb3RoZXItPl9jYWNoZWRfc2l6ZV8pOworfQorCis6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIER1cmF0aW9uOjpHZXRNZXRhZGF0YSgpIGNvbnN0IHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgbWV0YWRhdGE7CisgIG1ldGFkYXRhLmRlc2NyaXB0b3IgPSBEdXJhdGlvbl9kZXNjcmlwdG9yXzsKKyAgbWV0YWRhdGEucmVmbGVjdGlvbiA9IER1cmF0aW9uX3JlZmxlY3Rpb25fOworICByZXR1cm4gbWV0YWRhdGE7Cit9CisKKyNpZiBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKy8vIER1cmF0aW9uCisKKy8vIG9wdGlvbmFsIGludDY0IHNlY29uZHMgPSAxOwordm9pZCBEdXJhdGlvbjo6Y2xlYXJfc2Vjb25kcygpIHsKKyAgc2Vjb25kc18gPSBHT09HTEVfTE9OR0xPTkcoMCk7Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjppbnQ2NCBEdXJhdGlvbjo6c2Vjb25kcygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRHVyYXRpb24uc2Vjb25kcykKKyAgcmV0dXJuIHNlY29uZHNfOworfQorIHZvaWQgRHVyYXRpb246OnNldF9zZWNvbmRzKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50NjQgdmFsdWUpIHsKKyAgCisgIHNlY29uZHNfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uLnNlY29uZHMpCit9CisKKy8vIG9wdGlvbmFsIGludDMyIG5hbm9zID0gMjsKK3ZvaWQgRHVyYXRpb246OmNsZWFyX25hbm9zKCkgeworICBuYW5vc18gPSAwOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgRHVyYXRpb246Om5hbm9zKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbi5uYW5vcykKKyAgcmV0dXJuIG5hbm9zXzsKK30KKyB2b2lkIER1cmF0aW9uOjpzZXRfbmFub3MoOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiB2YWx1ZSkgeworICAKKyAgbmFub3NfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uLm5hbm9zKQorfQorCisjZW5kaWYgIC8vIFBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworCisvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobmFtZXNwYWNlX3Njb3BlKQorCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGdsb2JhbF9zY29wZSkKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvZHVyYXRpb24ucGIuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvZHVyYXRpb24ucGIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMTVhNTJjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9kdXJhdGlvbi5wYi5oCkBAIC0wLDAgKzEsMTcyIEBACisvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQorLy8gc291cmNlOiBnb29nbGUvcHJvdG9idWYvZHVyYXRpb24ucHJvdG8KKworI2lmbmRlZiBQUk9UT0JVRl9nb29nbGVfMmZwcm90b2J1Zl8yZmR1cmF0aW9uXzJlcHJvdG9fX0lOQ0xVREVECisjZGVmaW5lIFBST1RPQlVGX2dvb2dsZV8yZnByb3RvYnVmXzJmZHVyYXRpb25fMmVwcm90b19fSU5DTFVERUQKKworI2luY2x1ZGUgPHN0cmluZz4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKworI2lmIEdPT0dMRV9QUk9UT0JVRl9WRVJTSU9OIDwgMzAwMDAwMAorI2Vycm9yIFRoaXMgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IGEgbmV3ZXIgdmVyc2lvbiBvZiBwcm90b2Mgd2hpY2ggaXMKKyNlcnJvciBpbmNvbXBhdGlibGUgd2l0aCB5b3VyIFByb3RvY29sIEJ1ZmZlciBoZWFkZXJzLiAgUGxlYXNlIHVwZGF0ZQorI2Vycm9yIHlvdXIgaGVhZGVycy4KKyNlbmRpZgorI2lmIDMwMDAwMDAgPCBHT09HTEVfUFJPVE9CVUZfTUlOX1BST1RPQ19WRVJTSU9OCisjZXJyb3IgVGhpcyBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgYW4gb2xkZXIgdmVyc2lvbiBvZiBwcm90b2Mgd2hpY2ggaXMKKyNlcnJvciBpbmNvbXBhdGlibGUgd2l0aCB5b3VyIFByb3RvY29sIEJ1ZmZlciBoZWFkZXJzLiAgUGxlYXNlCisjZXJyb3IgcmVnZW5lcmF0ZSB0aGlzIGZpbGUgd2l0aCBhIG5ld2VyIHZlcnNpb24gb2YgcHJvdG9jLgorI2VuZGlmCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvYXJlbmEuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvYXJlbmFzdHJpbmcuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX21lc3NhZ2VfdXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tZXRhZGF0YS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tZXNzYWdlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3JlcGVhdGVkX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2V4dGVuc2lvbl9zZXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdW5rbm93bl9maWVsZF9zZXQuaD4KKy8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbmNsdWRlcykKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCisvLyBJbnRlcm5hbCBpbXBsZW1lbnRhdGlvbiBkZXRhaWwgLS0gZG8gbm90IGNhbGwgdGhlc2UuCit2b2lkIExJQlBST1RPQlVGX0VYUE9SVCBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZHVyYXRpb25fMmVwcm90bygpOwordm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZHVyYXRpb25fMmVwcm90bygpOwordm9pZCBwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZkdXJhdGlvbl8yZXByb3RvKCk7CisKK2NsYXNzIER1cmF0aW9uOworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBEdXJhdGlvbiA6IHB1YmxpYyA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UgeworIHB1YmxpYzoKKyAgRHVyYXRpb24oKTsKKyAgdmlydHVhbCB+RHVyYXRpb24oKTsKKworICBEdXJhdGlvbihjb25zdCBEdXJhdGlvbiYgZnJvbSk7CisKKyAgaW5saW5lIER1cmF0aW9uJiBvcGVyYXRvcj0oY29uc3QgRHVyYXRpb24mIGZyb20pIHsKKyAgICBDb3B5RnJvbShmcm9tKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworICBzdGF0aWMgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKCk7CisgIHN0YXRpYyBjb25zdCBEdXJhdGlvbiYgZGVmYXVsdF9pbnN0YW5jZSgpOworCisgIHZvaWQgU3dhcChEdXJhdGlvbiogb3RoZXIpOworCisgIC8vIGltcGxlbWVudHMgTWVzc2FnZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgaW5saW5lIER1cmF0aW9uKiBOZXcoKSBjb25zdCB7IHJldHVybiBOZXcoTlVMTCk7IH0KKworICBEdXJhdGlvbiogTmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdDsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIENvcHlGcm9tKGNvbnN0IER1cmF0aW9uJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgRHVyYXRpb24mIGZyb20pOworICB2b2lkIENsZWFyKCk7CisgIGJvb2wgSXNJbml0aWFsaXplZCgpIGNvbnN0OworCisgIGludCBCeXRlU2l6ZSgpIGNvbnN0OworICBib29sIE1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KTsKKyAgdm9pZCBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSg6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBvdXRwdXQpIGNvbnN0OworICBpbnQgR2V0Q2FjaGVkU2l6ZSgpIGNvbnN0IHsgcmV0dXJuIF9jYWNoZWRfc2l6ZV87IH0KKyAgcHJpdmF0ZToKKyAgdm9pZCBTaGFyZWRDdG9yKCk7CisgIHZvaWQgU2hhcmVkRHRvcigpOworICB2b2lkIFNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0OworICB2b2lkIEludGVybmFsU3dhcChEdXJhdGlvbiogb3RoZXIpOworICBwcml2YXRlOgorICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogR2V0QXJlbmFOb1ZpcnR1YWwoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8uYXJlbmEoKTsKKyAgfQorICBpbmxpbmUgdm9pZCogTWF5YmVBcmVuYVB0cigpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5yYXdfYXJlbmFfcHRyKCk7CisgIH0KKyAgcHVibGljOgorCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgR2V0TWV0YWRhdGEoKSBjb25zdDsKKworICAvLyBuZXN0ZWQgdHlwZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIGFjY2Vzc29ycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gb3B0aW9uYWwgaW50NjQgc2Vjb25kcyA9IDE7CisgIHZvaWQgY2xlYXJfc2Vjb25kcygpOworICBzdGF0aWMgY29uc3QgaW50IGtTZWNvbmRzRmllbGROdW1iZXIgPSAxOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludDY0IHNlY29uZHMoKSBjb25zdDsKKyAgdm9pZCBzZXRfc2Vjb25kcyg6Omdvb2dsZTo6cHJvdG9idWY6OmludDY0IHZhbHVlKTsKKworICAvLyBvcHRpb25hbCBpbnQzMiBuYW5vcyA9IDI7CisgIHZvaWQgY2xlYXJfbmFub3MoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrTmFub3NGaWVsZE51bWJlciA9IDI7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgbmFub3MoKSBjb25zdDsKKyAgdm9pZCBzZXRfbmFub3MoOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiB2YWx1ZSk7CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbikKKyBwcml2YXRlOgorCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEgX2ludGVybmFsX21ldGFkYXRhXzsKKyAgYm9vbCBfaXNfZGVmYXVsdF9pbnN0YW5jZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50NjQgc2Vjb25kc187CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgbmFub3NfOworICBtdXRhYmxlIGludCBfY2FjaGVkX3NpemVfOworICBmcmllbmQgdm9pZCBMSUJQUk9UT0JVRl9FWFBPUlQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmR1cmF0aW9uXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfQXNzaWduRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmR1cmF0aW9uXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfU2h1dGRvd25GaWxlX2dvb2dsZV8yZnByb3RvYnVmXzJmZHVyYXRpb25fMmVwcm90bygpOworCisgIHZvaWQgSW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIHN0YXRpYyBEdXJhdGlvbiogZGVmYXVsdF9pbnN0YW5jZV87Cit9OworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworI2lmICFQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKy8vIER1cmF0aW9uCisKKy8vIG9wdGlvbmFsIGludDY0IHNlY29uZHMgPSAxOworaW5saW5lIHZvaWQgRHVyYXRpb246OmNsZWFyX3NlY29uZHMoKSB7CisgIHNlY29uZHNfID0gR09PR0xFX0xPTkdMT05HKDApOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50NjQgRHVyYXRpb246OnNlY29uZHMoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uLnNlY29uZHMpCisgIHJldHVybiBzZWNvbmRzXzsKK30KK2lubGluZSB2b2lkIER1cmF0aW9uOjpzZXRfc2Vjb25kcyg6Omdvb2dsZTo6cHJvdG9idWY6OmludDY0IHZhbHVlKSB7CisgIAorICBzZWNvbmRzXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbi5zZWNvbmRzKQorfQorCisvLyBvcHRpb25hbCBpbnQzMiBuYW5vcyA9IDI7CitpbmxpbmUgdm9pZCBEdXJhdGlvbjo6Y2xlYXJfbmFub3MoKSB7CisgIG5hbm9zXyA9IDA7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiBEdXJhdGlvbjo6bmFub3MoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uLm5hbm9zKQorICByZXR1cm4gbmFub3NfOworfQoraW5saW5lIHZvaWQgRHVyYXRpb246OnNldF9uYW5vcyg6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKSB7CisgIAorICBuYW5vc18gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRHVyYXRpb24ubmFub3MpCit9CisKKyNlbmRpZiAgLy8gIVBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworCisvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobmFtZXNwYWNlX3Njb3BlKQorCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGdsb2JhbF9zY29wZSkKKworI2VuZGlmICAvLyBQUk9UT0JVRl9nb29nbGVfMmZwcm90b2J1Zl8yZmR1cmF0aW9uXzJlcHJvdG9fX0lOQ0xVREVECmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2R1cmF0aW9uLnByb3RvIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9kdXJhdGlvbi5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43OGJjYzc0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9kdXJhdGlvbi5wcm90bwpAQCAtMCwwICsxLDk2IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworc3ludGF4ID0gInByb3RvMyI7CisKK3BhY2thZ2UgZ29vZ2xlLnByb3RvYnVmOworCitvcHRpb24gY3NoYXJwX25hbWVzcGFjZSA9ICJHb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlwZXMiOworb3B0aW9uIGphdmFfcGFja2FnZSA9ICJjb20uZ29vZ2xlLnByb3RvYnVmIjsKK29wdGlvbiBqYXZhX291dGVyX2NsYXNzbmFtZSA9ICJEdXJhdGlvblByb3RvIjsKK29wdGlvbiBqYXZhX211bHRpcGxlX2ZpbGVzID0gdHJ1ZTsKK29wdGlvbiBqYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaCA9IHRydWU7CitvcHRpb24gb2JqY19jbGFzc19wcmVmaXggPSAiR1BCIjsKKworLy8gQSBEdXJhdGlvbiByZXByZXNlbnRzIGEgc2lnbmVkLCBmaXhlZC1sZW5ndGggc3BhbiBvZiB0aW1lIHJlcHJlc2VudGVkCisvLyBhcyBhIGNvdW50IG9mIHNlY29uZHMgYW5kIGZyYWN0aW9ucyBvZiBzZWNvbmRzIGF0IG5hbm9zZWNvbmQKKy8vIHJlc29sdXRpb24uIEl0IGlzIGluZGVwZW5kZW50IG9mIGFueSBjYWxlbmRhciBhbmQgY29uY2VwdHMgbGlrZSAiZGF5IgorLy8gb3IgIm1vbnRoIi4gSXQgaXMgcmVsYXRlZCB0byBUaW1lc3RhbXAgaW4gdGhhdCB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuCisvLyB0d28gVGltZXN0YW1wIHZhbHVlcyBpcyBhIER1cmF0aW9uIGFuZCBpdCBjYW4gYmUgYWRkZWQgb3Igc3VidHJhY3RlZAorLy8gZnJvbSBhIFRpbWVzdGFtcC4gUmFuZ2UgaXMgYXBwcm94aW1hdGVseSArLTEwLDAwMCB5ZWFycy4KKy8vCisvLyBFeGFtcGxlIDE6IENvbXB1dGUgRHVyYXRpb24gZnJvbSB0d28gVGltZXN0YW1wcyBpbiBwc2V1ZG8gY29kZS4KKy8vCisvLyAgICAgVGltZXN0YW1wIHN0YXJ0ID0gLi4uOworLy8gICAgIFRpbWVzdGFtcCBlbmQgPSAuLi47CisvLyAgICAgRHVyYXRpb24gZHVyYXRpb24gPSAuLi47CisvLworLy8gICAgIGR1cmF0aW9uLnNlY29uZHMgPSBlbmQuc2Vjb25kcyAtIHN0YXJ0LnNlY29uZHM7CisvLyAgICAgZHVyYXRpb24ubmFub3MgPSBlbmQubmFub3MgLSBzdGFydC5uYW5vczsKKy8vCisvLyAgICAgaWYgKGR1cmF0aW9uLnNlY29uZHMgPCAwICYmIGR1cmF0aW9uLm5hbm9zID4gMCkgeworLy8gICAgICAgZHVyYXRpb24uc2Vjb25kcyArPSAxOworLy8gICAgICAgZHVyYXRpb24ubmFub3MgLT0gMTAwMDAwMDAwMDsKKy8vICAgICB9IGVsc2UgaWYgKGR1cmF0aW9ucy5zZWNvbmRzID4gMCAmJiBkdXJhdGlvbi5uYW5vcyA8IDApIHsKKy8vICAgICAgIGR1cmF0aW9uLnNlY29uZHMgLT0gMTsKKy8vICAgICAgIGR1cmF0aW9uLm5hbm9zICs9IDEwMDAwMDAwMDA7CisvLyAgICAgfQorLy8KKy8vIEV4YW1wbGUgMjogQ29tcHV0ZSBUaW1lc3RhbXAgZnJvbSBUaW1lc3RhbXAgKyBEdXJhdGlvbiBpbiBwc2V1ZG8gY29kZS4KKy8vCisvLyAgICAgVGltZXN0YW1wIHN0YXJ0ID0gLi4uOworLy8gICAgIER1cmF0aW9uIGR1cmF0aW9uID0gLi4uOworLy8gICAgIFRpbWVzdGFtcCBlbmQgPSAuLi47CisvLworLy8gICAgIGVuZC5zZWNvbmRzID0gc3RhcnQuc2Vjb25kcyArIGR1cmF0aW9uLnNlY29uZHM7CisvLyAgICAgZW5kLm5hbm9zID0gc3RhcnQubmFub3MgKyBkdXJhdGlvbi5uYW5vczsKKy8vCisvLyAgICAgaWYgKGVuZC5uYW5vcyA8IDApIHsKKy8vICAgICAgIGVuZC5zZWNvbmRzIC09IDE7CisvLyAgICAgICBlbmQubmFub3MgKz0gMTAwMDAwMDAwMDsKKy8vICAgICB9IGVsc2UgaWYgKGVuZC5uYW5vcyA+PSAxMDAwMDAwMDAwKSB7CisvLyAgICAgICBlbmQuc2Vjb25kcyArPSAxOworLy8gICAgICAgZW5kLm5hbm9zIC09IDEwMDAwMDAwMDA7CisvLyAgICAgfQorLy8KK21lc3NhZ2UgRHVyYXRpb24geworCisgIC8vIFNpZ25lZCBzZWNvbmRzIG9mIHRoZSBzcGFuIG9mIHRpbWUuIE11c3QgYmUgZnJvbSAtMzE1LDU3NiwwMDAsMDAwCisgIC8vIHRvICszMTUsNTc2LDAwMCwwMDAgaW5jbHVzaXZlLgorICBpbnQ2NCBzZWNvbmRzID0gMTsKKworICAvLyBTaWduZWQgZnJhY3Rpb25zIG9mIGEgc2Vjb25kIGF0IG5hbm9zZWNvbmQgcmVzb2x1dGlvbiBvZiB0aGUgc3BhbgorICAvLyBvZiB0aW1lLiBEdXJhdGlvbnMgbGVzcyB0aGFuIG9uZSBzZWNvbmQgYXJlIHJlcHJlc2VudGVkIHdpdGggYSAwCisgIC8vIGBzZWNvbmRzYCBmaWVsZCBhbmQgYSBwb3NpdGl2ZSBvciBuZWdhdGl2ZSBgbmFub3NgIGZpZWxkLiBGb3IgZHVyYXRpb25zCisgIC8vIG9mIG9uZSBzZWNvbmQgb3IgbW9yZSwgYSBub24temVybyB2YWx1ZSBmb3IgdGhlIGBuYW5vc2AgZmllbGQgbXVzdCBiZQorICAvLyBvZiB0aGUgc2FtZSBzaWduIGFzIHRoZSBgc2Vjb25kc2AgZmllbGQuIE11c3QgYmUgZnJvbSAtOTk5LDk5OSw5OTkKKyAgLy8gdG8gKzk5OSw5OTksOTk5IGluY2x1c2l2ZS4KKyAgaW50MzIgbmFub3MgPSAyOworfQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9keW5hbWljX21lc3NhZ2UuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2R5bmFtaWNfbWVzc2FnZS5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ZDY4OWFjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9keW5hbWljX21lc3NhZ2UuY2MKQEAgLTAsMCArMSw4NjIgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBEeW5hbWljTWVzc2FnZSBpcyBpbXBsZW1lbnRlZCBieSBjb25zdHJ1Y3RpbmcgYSBkYXRhIHN0cnVjdHVyZSB3aGljaAorLy8gaGFzIHJvdWdobHkgdGhlIHNhbWUgbWVtb3J5IGxheW91dCBhcyBhIGdlbmVyYXRlZCBtZXNzYWdlIHdvdWxkIGhhdmUuCisvLyBUaGVuLCB3ZSB1c2UgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24gdG8gaW1wbGVtZW50IG91ciByZWZsZWN0aW9uCisvLyBpbnRlcmZhY2UuICBBbGwgdGhlIG90aGVyIG9wZXJhdGlvbnMgd2UgbmVlZCB0byBpbXBsZW1lbnQgKGUuZy4KKy8vIHBhcnNpbmcsIGNvcHlpbmcsIGV0Yy4pIGFyZSBhbHJlYWR5IGltcGxlbWVudGVkIGluIHRlcm1zIG9mCisvLyBSZWZsZWN0aW9uLCBzbyB0aGUgcmVzdCBpcyBlYXN5LgorLy8KKy8vIFRoZSB1cCBzaWRlIG9mIHRoaXMgc3RyYXRlZ3kgaXMgdGhhdCBpdCdzIHZlcnkgZWZmaWNpZW50LiAgV2UgZG9uJ3QKKy8vIG5lZWQgdG8gdXNlIGhhc2hfbWFwcyBvciBnZW5lcmljIHJlcHJlc2VudGF0aW9ucyBvZiBmaWVsZHMuICBUaGUKKy8vIGRvd24gc2lkZSBpcyB0aGF0IHRoaXMgaXMgYSBsb3ctbGV2ZWwgbWVtb3J5IG1hbmFnZW1lbnQgaGFjayB3aGljaAorLy8gY2FuIGJlIHRyaWNreSB0byBnZXQgcmlnaHQuCisvLworLy8gQXMgbWVudGlvbmVkIGluIHRoZSBoZWFkZXIsIHdlIG9ubHkgZXhwb3NlIGEgRHluYW1pY01lc3NhZ2VGYWN0b3J5CisvLyBwdWJsaWNseSwgbm90IHRoZSBEeW5hbWljTWVzc2FnZSBjbGFzcyBpdHNlbGYuICBUaGlzIGlzIGJlY2F1c2UKKy8vIEdlbmVyaWNNZXNzYWdlUmVmbGVjdGlvbiB3YW50cyB0byBoYXZlIGEgcG9pbnRlciB0byBhICJkZWZhdWx0IgorLy8gY29weSBvZiB0aGUgY2xhc3MsIHdpdGggYWxsIGZpZWxkcyBpbml0aWFsaXplZCB0byB0aGVpciBkZWZhdWx0CisvLyB2YWx1ZXMuICBXZSBvbmx5IHdhbnQgdG8gY29uc3RydWN0IG9uZSBvZiB0aGVzZSBwZXIgbWVzc2FnZSB0eXBlLAorLy8gc28gRHluYW1pY01lc3NhZ2VGYWN0b3J5IHN0b3JlcyBhIGNhY2hlIG9mIGRlZmF1bHQgbWVzc2FnZXMgZm9yCisvLyBlYWNoIHR5cGUgaXQgc2VlcyAoZWFjaCB1bmlxdWUgRGVzY3JpcHRvciBwb2ludGVyKS4gIFRoZSBjb2RlCisvLyByZWZlcnMgdG8gdGhlICJkZWZhdWx0IiBjb3B5IG9mIHRoZSBjbGFzcyBhcyB0aGUgInByb3RvdHlwZSIuCisvLworLy8gTm90ZSBvbiBtZW1vcnkgYWxsb2NhdGlvbjogIFRoaXMgbW9kdWxlIG9mdGVuIGNhbGxzICJvcGVyYXRvciBuZXcoKSIKKy8vIHRvIGFsbG9jYXRlIHVudHlwZWQgbWVtb3J5LCByYXRoZXIgdGhhbiBjYWxsaW5nIHNvbWV0aGluZyBsaWtlCisvLyAibmV3IHVpbnQ4W10iLiAgVGhpcyBpcyBiZWNhdXNlICJvcGVyYXRvciBuZXcoKSIgbWVhbnMgIkdpdmUgbWUgc29tZQorLy8gc3BhY2Ugd2hpY2ggSSBjYW4gdXNlIGFzIEkgcGxlYXNlLiIgd2hpbGUgIm5ldyB1aW50OFtdIiBtZWFucyAiR2l2ZQorLy8gbWUgYW4gYXJyYXkgb2YgOC1iaXQgaW50ZWdlcnMuIi4gIEluIHByYWN0aWNlLCB0aGUgbGF0ZXIgbWF5IHJldHVybgorLy8gYSBwb2ludGVyIHRoYXQgaXMgbm90IGFsaWduZWQgY29ycmVjdGx5IGZvciBnZW5lcmFsIHVzZS4gIEkgYmVsaWV2ZQorLy8gSXRlbSA4IG9mICJNb3JlIEVmZmVjdGl2ZSBDKysiIGRpc2N1c3NlcyB0aGlzIGluIG1vcmUgZGV0YWlsLCB0aG91Z2gKKy8vIEkgZG9uJ3QgaGF2ZSB0aGUgYm9vayBvbiBtZSByaWdodCBub3cgc28gSSdtIG5vdCBzdXJlLgorCisjaW5jbHVkZSA8YWxnb3JpdGhtPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9oYXNoLmg+CisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zY29wZWRfcHRyLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZHluYW1pY19tZXNzYWdlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfbWVzc2FnZV91dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9tZXNzYWdlX3JlZmxlY3Rpb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvYXJlbmFzdHJpbmcuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWFwX2ZpZWxkX2lubC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9yZWZsZWN0aW9uX29wcy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9yZXBlYXRlZF9maWVsZC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tYXBfdHlwZV9oYW5kbGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2V4dGVuc2lvbl9zZXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWFwX2ZpZWxkLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKwordXNpbmcgaW50ZXJuYWw6OldpcmVGb3JtYXQ7Cit1c2luZyBpbnRlcm5hbDo6RXh0ZW5zaW9uU2V0OwordXNpbmcgaW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOwordXNpbmcgaW50ZXJuYWw6Ok1hcEZpZWxkOwordXNpbmcgaW50ZXJuYWw6OkR5bmFtaWNNYXBGaWVsZDsKKworCit1c2luZyBpbnRlcm5hbDo6QXJlbmFTdHJpbmdQdHI7CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKy8vIFNvbWUgaGVscGVyIHRhYmxlcyBhbmQgZnVuY3Rpb25zLi4uCisKK25hbWVzcGFjZSB7CisKK2Jvb2wgSXNNYXBGaWVsZEluQXBpKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgcmV0dXJuIGZpZWxkLT5pc19tYXAoKTsKK30KKworLy8gQ29tcHV0ZSB0aGUgYnl0ZSBzaXplIG9mIHRoZSBpbi1tZW1vcnkgcmVwcmVzZW50YXRpb24gb2YgdGhlIGZpZWxkLgoraW50IEZpZWxkU3BhY2VVc2VkKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgdHlwZWRlZiBGaWVsZERlc2NyaXB0b3IgRkQ7ICAvLyBhdm9pZCBsaW5lIHdyYXBwaW5nCisgIGlmIChmaWVsZC0+bGFiZWwoKSA9PSBGRDo6TEFCRUxfUkVQRUFURUQpIHsKKyAgICBzd2l0Y2ggKGZpZWxkLT5jcHBfdHlwZSgpKSB7CisgICAgICBjYXNlIEZEOjpDUFBUWVBFX0lOVDMyICA6IHJldHVybiBzaXplb2YoUmVwZWF0ZWRGaWVsZDxpbnQzMiAgID4pOworICAgICAgY2FzZSBGRDo6Q1BQVFlQRV9JTlQ2NCAgOiByZXR1cm4gc2l6ZW9mKFJlcGVhdGVkRmllbGQ8aW50NjQgICA+KTsKKyAgICAgIGNhc2UgRkQ6OkNQUFRZUEVfVUlOVDMyIDogcmV0dXJuIHNpemVvZihSZXBlYXRlZEZpZWxkPHVpbnQzMiAgPik7CisgICAgICBjYXNlIEZEOjpDUFBUWVBFX1VJTlQ2NCA6IHJldHVybiBzaXplb2YoUmVwZWF0ZWRGaWVsZDx1aW50NjQgID4pOworICAgICAgY2FzZSBGRDo6Q1BQVFlQRV9ET1VCTEUgOiByZXR1cm4gc2l6ZW9mKFJlcGVhdGVkRmllbGQ8ZG91YmxlICA+KTsKKyAgICAgIGNhc2UgRkQ6OkNQUFRZUEVfRkxPQVQgIDogcmV0dXJuIHNpemVvZihSZXBlYXRlZEZpZWxkPGZsb2F0ICAgPik7CisgICAgICBjYXNlIEZEOjpDUFBUWVBFX0JPT0wgICA6IHJldHVybiBzaXplb2YoUmVwZWF0ZWRGaWVsZDxib29sICAgID4pOworICAgICAgY2FzZSBGRDo6Q1BQVFlQRV9FTlVNICAgOiByZXR1cm4gc2l6ZW9mKFJlcGVhdGVkRmllbGQ8aW50ICAgICA+KTsKKyAgICAgIGNhc2UgRkQ6OkNQUFRZUEVfTUVTU0FHRToKKyAgICAgICAgaWYgKElzTWFwRmllbGRJbkFwaShmaWVsZCkpIHsKKyAgICAgICAgICByZXR1cm4gc2l6ZW9mKER5bmFtaWNNYXBGaWVsZCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgcmV0dXJuIHNpemVvZihSZXBlYXRlZFB0ckZpZWxkPE1lc3NhZ2U+KTsKKyAgICAgICAgfQorCisgICAgICBjYXNlIEZEOjpDUFBUWVBFX1NUUklORzoKKyAgICAgICAgc3dpdGNoIChmaWVsZC0+b3B0aW9ucygpLmN0eXBlKCkpIHsKKyAgICAgICAgICBkZWZhdWx0OiAgLy8gVE9ETyhrZW50b24pOiAgU3VwcG9ydCBvdGhlciBzdHJpbmcgcmVwcy4KKyAgICAgICAgICBjYXNlIEZpZWxkT3B0aW9uczo6U1RSSU5HOgorICAgICAgICAgICAgcmV0dXJuIHNpemVvZihSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4pOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICBzd2l0Y2ggKGZpZWxkLT5jcHBfdHlwZSgpKSB7CisgICAgICBjYXNlIEZEOjpDUFBUWVBFX0lOVDMyICA6IHJldHVybiBzaXplb2YoaW50MzIgICApOworICAgICAgY2FzZSBGRDo6Q1BQVFlQRV9JTlQ2NCAgOiByZXR1cm4gc2l6ZW9mKGludDY0ICAgKTsKKyAgICAgIGNhc2UgRkQ6OkNQUFRZUEVfVUlOVDMyIDogcmV0dXJuIHNpemVvZih1aW50MzIgICk7CisgICAgICBjYXNlIEZEOjpDUFBUWVBFX1VJTlQ2NCA6IHJldHVybiBzaXplb2YodWludDY0ICApOworICAgICAgY2FzZSBGRDo6Q1BQVFlQRV9ET1VCTEUgOiByZXR1cm4gc2l6ZW9mKGRvdWJsZSAgKTsKKyAgICAgIGNhc2UgRkQ6OkNQUFRZUEVfRkxPQVQgIDogcmV0dXJuIHNpemVvZihmbG9hdCAgICk7CisgICAgICBjYXNlIEZEOjpDUFBUWVBFX0JPT0wgICA6IHJldHVybiBzaXplb2YoYm9vbCAgICApOworICAgICAgY2FzZSBGRDo6Q1BQVFlQRV9FTlVNICAgOiByZXR1cm4gc2l6ZW9mKGludCAgICAgKTsKKworICAgICAgY2FzZSBGRDo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgICByZXR1cm4gc2l6ZW9mKE1lc3NhZ2UqKTsKKworICAgICAgY2FzZSBGRDo6Q1BQVFlQRV9TVFJJTkc6CisgICAgICAgIHN3aXRjaCAoZmllbGQtPm9wdGlvbnMoKS5jdHlwZSgpKSB7CisgICAgICAgICAgZGVmYXVsdDogIC8vIFRPRE8oa2VudG9uKTogIFN1cHBvcnQgb3RoZXIgc3RyaW5nIHJlcHMuCisgICAgICAgICAgY2FzZSBGaWVsZE9wdGlvbnM6OlNUUklORzoKKyAgICAgICAgICAgIHJldHVybiBzaXplb2YoQXJlbmFTdHJpbmdQdHIpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgIH0KKyAgfQorCisgIEdPT0dMRV9MT0coREZBVEFMKSA8PCAiQ2FuJ3QgZ2V0IGhlcmUuIjsKKyAgcmV0dXJuIDA7Cit9CisKKy8vIENvbXB1dGUgdGhlIGJ5dGUgc2l6ZSBvZiBpbi1tZW1vcnkgcmVwcmVzZW50YXRpb24gb2YgdGhlIG9uZW9mIGZpZWxkcworLy8gaW4gZGVmYXVsdCBvbmVvZiBpbnN0YW5jZS4KK2ludCBPbmVvZkZpZWxkU3BhY2VVc2VkKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgdHlwZWRlZiBGaWVsZERlc2NyaXB0b3IgRkQ7ICAvLyBhdm9pZCBsaW5lIHdyYXBwaW5nCisgIHN3aXRjaCAoZmllbGQtPmNwcF90eXBlKCkpIHsKKyAgICBjYXNlIEZEOjpDUFBUWVBFX0lOVDMyICA6IHJldHVybiBzaXplb2YoaW50MzIgICApOworICAgIGNhc2UgRkQ6OkNQUFRZUEVfSU5UNjQgIDogcmV0dXJuIHNpemVvZihpbnQ2NCAgICk7CisgICAgY2FzZSBGRDo6Q1BQVFlQRV9VSU5UMzIgOiByZXR1cm4gc2l6ZW9mKHVpbnQzMiAgKTsKKyAgICBjYXNlIEZEOjpDUFBUWVBFX1VJTlQ2NCA6IHJldHVybiBzaXplb2YodWludDY0ICApOworICAgIGNhc2UgRkQ6OkNQUFRZUEVfRE9VQkxFIDogcmV0dXJuIHNpemVvZihkb3VibGUgICk7CisgICAgY2FzZSBGRDo6Q1BQVFlQRV9GTE9BVCAgOiByZXR1cm4gc2l6ZW9mKGZsb2F0ICAgKTsKKyAgICBjYXNlIEZEOjpDUFBUWVBFX0JPT0wgICA6IHJldHVybiBzaXplb2YoYm9vbCAgICApOworICAgIGNhc2UgRkQ6OkNQUFRZUEVfRU5VTSAgIDogcmV0dXJuIHNpemVvZihpbnQgICAgICk7CisKKyAgICBjYXNlIEZEOjpDUFBUWVBFX01FU1NBR0U6CisgICAgICByZXR1cm4gc2l6ZW9mKE1lc3NhZ2UqKTsKKworICAgIGNhc2UgRkQ6OkNQUFRZUEVfU1RSSU5HOgorICAgICAgc3dpdGNoIChmaWVsZC0+b3B0aW9ucygpLmN0eXBlKCkpIHsKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgY2FzZSBGaWVsZE9wdGlvbnM6OlNUUklORzoKKyAgICAgICAgICByZXR1cm4gc2l6ZW9mKEFyZW5hU3RyaW5nUHRyKTsKKyAgICAgIH0KKyAgICAgIGJyZWFrOworICB9CisKKyAgR09PR0xFX0xPRyhERkFUQUwpIDw8ICJDYW4ndCBnZXQgaGVyZS4iOworICByZXR1cm4gMDsKK30KKworaW5saW5lIGludCBEaXZpZGVSb3VuZGluZ1VwKGludCBpLCBpbnQgaikgeworICByZXR1cm4gKGkgKyAoaiAtIDEpKSAvIGo7Cit9CisKK3N0YXRpYyBjb25zdCBpbnQga1NhZmVBbGlnbm1lbnQgPSBzaXplb2YodWludDY0KTsKK3N0YXRpYyBjb25zdCBpbnQga01heE9uZW9mVW5pb25TaXplID0gc2l6ZW9mKHVpbnQ2NCk7CisKK2lubGluZSBpbnQgQWxpZ25UbyhpbnQgb2Zmc2V0LCBpbnQgYWxpZ25tZW50KSB7CisgIHJldHVybiBEaXZpZGVSb3VuZGluZ1VwKG9mZnNldCwgYWxpZ25tZW50KSAqIGFsaWdubWVudDsKK30KKworLy8gUm91bmRzIHRoZSBnaXZlbiBieXRlIG9mZnNldCB1cCB0byB0aGUgbmV4dCBvZmZzZXQgYWxpZ25lZCBzdWNoIHRoYXQgYW55CisvLyB0eXBlIG1heSBiZSBzdG9yZWQgYXQgaXQuCitpbmxpbmUgaW50IEFsaWduT2Zmc2V0KGludCBvZmZzZXQpIHsKKyAgcmV0dXJuIEFsaWduVG8ob2Zmc2V0LCBrU2FmZUFsaWdubWVudCk7Cit9CisKKyNkZWZpbmUgYml0c2l6ZW9mKFQpIChzaXplb2YoVCkgKiA4KQorCit9ICAvLyBuYW1lc3BhY2UKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitjbGFzcyBEeW5hbWljTWVzc2FnZSA6IHB1YmxpYyBNZXNzYWdlIHsKKyBwdWJsaWM6CisgIHN0cnVjdCBUeXBlSW5mbyB7CisgICAgaW50IHNpemU7CisgICAgaW50IGhhc19iaXRzX29mZnNldDsKKyAgICBpbnQgb25lb2ZfY2FzZV9vZmZzZXQ7CisgICAgaW50IHVua25vd25fZmllbGRzX29mZnNldDsKKyAgICBpbnQgZXh0ZW5zaW9uc19vZmZzZXQ7CisgICAgaW50IGlzX2RlZmF1bHRfaW5zdGFuY2Vfb2Zmc2V0OworCisgICAgLy8gTm90IG93bmVkIGJ5IHRoZSBUeXBlSW5mby4KKyAgICBEeW5hbWljTWVzc2FnZUZhY3RvcnkqIGZhY3Rvcnk7ICAvLyBUaGUgZmFjdG9yeSB0aGF0IGNyZWF0ZWQgdGhpcyBvYmplY3QuCisgICAgY29uc3QgRGVzY3JpcHRvclBvb2wqIHBvb2w7ICAgICAgLy8gVGhlIGZhY3RvcnkncyBEZXNjcmlwdG9yUG9vbC4KKyAgICBjb25zdCBEZXNjcmlwdG9yKiB0eXBlOyAgICAgICAgICAvLyBUeXBlIG9mIHRoaXMgRHluYW1pY01lc3NhZ2UuCisKKyAgICAvLyBXYXJuaW5nOiAgVGhlIG9yZGVyIGluIHdoaWNoIHRoZSBmb2xsb3dpbmcgcG9pbnRlcnMgYXJlIGRlZmluZWQgaXMKKyAgICAvLyAgIGltcG9ydGFudCAodGhlIHByb3RvdHlwZSBtdXN0IGJlIGRlbGV0ZWQgKmJlZm9yZSogdGhlIG9mZnNldHMpLgorICAgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9hcnJheTxpbnQ+IG9mZnNldHM7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxjb25zdCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbj4gcmVmbGVjdGlvbjsKKyAgICAvLyBEb24ndCB1c2UgYSBzY29wZWRfcHRyIHRvIGhvbGQgdGhlIHByb3RvdHlwZTogdGhlIGRlc3RydWN0b3IgZm9yCisgICAgLy8gRHluYW1pY01lc3NhZ2UgbmVlZHMgdG8ga25vdyB3aGV0aGVyIGl0IGlzIHRoZSBwcm90b3R5cGUsIGFuZCBkb2VzIHNvIGJ5CisgICAgLy8gbG9va2luZyBiYWNrIGF0IHRoaXMgZmllbGQuIFRoaXMgd291bGQgYXNzdW1lIGRldGFpbHMgYWJvdXQgdGhlCisgICAgLy8gaW1wbGVtZW50YXRpb24gb2Ygc2NvcGVkX3B0ci4KKyAgICBjb25zdCBEeW5hbWljTWVzc2FnZSogcHJvdG90eXBlOworICAgIHZvaWQqIGRlZmF1bHRfb25lb2ZfaW5zdGFuY2U7CisKKyAgICBUeXBlSW5mbygpIDogcHJvdG90eXBlKE5VTEwpLCBkZWZhdWx0X29uZW9mX2luc3RhbmNlKE5VTEwpIHt9CisKKyAgICB+VHlwZUluZm8oKSB7CisgICAgICBkZWxldGUgcHJvdG90eXBlOworICAgICAgb3BlcmF0b3IgZGVsZXRlKGRlZmF1bHRfb25lb2ZfaW5zdGFuY2UpOworICAgIH0KKyAgfTsKKworICBEeW5hbWljTWVzc2FnZShjb25zdCBUeXBlSW5mbyogdHlwZV9pbmZvKTsKKyAgfkR5bmFtaWNNZXNzYWdlKCk7CisKKyAgLy8gQ2FsbGVkIG9uIHRoZSBwcm90b3R5cGUgYWZ0ZXIgY29uc3RydWN0aW9uIHRvIGluaXRpYWxpemUgbWVzc2FnZSBmaWVsZHMuCisgIHZvaWQgQ3Jvc3NMaW5rUHJvdG90eXBlcygpOworCisgIC8vIGltcGxlbWVudHMgTWVzc2FnZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgTWVzc2FnZSogTmV3KCkgY29uc3Q7CisgIE1lc3NhZ2UqIE5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hKCkgY29uc3QgeyByZXR1cm4gTlVMTDsgfTsKKworICBpbnQgR2V0Q2FjaGVkU2l6ZSgpIGNvbnN0OworICB2b2lkIFNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0OworCisgIE1ldGFkYXRhIEdldE1ldGFkYXRhKCkgY29uc3Q7CisKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhEeW5hbWljTWVzc2FnZSk7CisgIER5bmFtaWNNZXNzYWdlKGNvbnN0IFR5cGVJbmZvKiB0eXBlX2luZm8sIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKTsKKyAgdm9pZCBTaGFyZWRDdG9yKCk7CisKKyAgaW5saW5lIGJvb2wgaXNfcHJvdG90eXBlKCkgY29uc3QgeworICAgIHJldHVybiB0eXBlX2luZm9fLT5wcm90b3R5cGUgPT0gdGhpcyB8fAorICAgICAgICAgICAvLyBJZiB0eXBlX2luZm9fLT5wcm90b3R5cGUgaXMgTlVMTCwgdGhlbiB3ZSBtdXN0IGJlIGNvbnN0cnVjdGluZworICAgICAgICAgICAvLyB0aGUgcHJvdG90eXBlIG5vdywgd2hpY2ggbWVhbnMgd2UgbXVzdCBiZSB0aGUgcHJvdG90eXBlLgorICAgICAgICAgICB0eXBlX2luZm9fLT5wcm90b3R5cGUgPT0gTlVMTDsKKyAgfQorCisgIGlubGluZSB2b2lkKiBPZmZzZXRUb1BvaW50ZXIoaW50IG9mZnNldCkgeworICAgIHJldHVybiByZWludGVycHJldF9jYXN0PHVpbnQ4Kj4odGhpcykgKyBvZmZzZXQ7CisgIH0KKyAgaW5saW5lIGNvbnN0IHZvaWQqIE9mZnNldFRvUG9pbnRlcihpbnQgb2Zmc2V0KSBjb25zdCB7CisgICAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgdWludDgqPih0aGlzKSArIG9mZnNldDsKKyAgfQorCisgIGNvbnN0IFR5cGVJbmZvKiB0eXBlX2luZm9fOworICAvLyBUT0RPKGtlbnRvbik6ICBNYWtlIHRoaXMgYW4gYXRvbWljPGludD4gd2hlbiBDKysgc3VwcG9ydHMgaXQuCisgIG11dGFibGUgaW50IGNhY2hlZF9ieXRlX3NpemVfOworfTsKKworRHluYW1pY01lc3NhZ2U6OkR5bmFtaWNNZXNzYWdlKGNvbnN0IFR5cGVJbmZvKiB0eXBlX2luZm8pCisgIDogdHlwZV9pbmZvXyh0eXBlX2luZm8pLAorICAgIGNhY2hlZF9ieXRlX3NpemVfKDApIHsKKyAgU2hhcmVkQ3RvcigpOworfQorCitEeW5hbWljTWVzc2FnZTo6RHluYW1pY01lc3NhZ2UoY29uc3QgVHlwZUluZm8qIHR5cGVfaW5mbywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkKKyAgOiB0eXBlX2luZm9fKHR5cGVfaW5mbyksCisgICAgY2FjaGVkX2J5dGVfc2l6ZV8oMCkgeworICBTaGFyZWRDdG9yKCk7Cit9CisKK3ZvaWQgRHluYW1pY01lc3NhZ2U6OlNoYXJlZEN0b3IoKSB7CisgIC8vIFdlIG5lZWQgdG8gY2FsbCBjb25zdHJ1Y3RvcnMgZm9yIHZhcmlvdXMgZmllbGRzIG1hbnVhbGx5IGFuZCBzZXQKKyAgLy8gZGVmYXVsdCB2YWx1ZXMgd2hlcmUgYXBwcm9wcmlhdGUuICBXZSB1c2UgcGxhY2VtZW50IG5ldyB0byBjYWxsCisgIC8vIGNvbnN0cnVjdG9ycy4gIElmIHlvdSBoYXZlbid0IGhlYXJkIG9mIHBsYWNlbWVudCBuZXcsIEkgc3VnZ2VzdCBHb29nbGluZworICAvLyBpdCBub3cuICBXZSB1c2UgcGxhY2VtZW50IG5ldyBldmVuIGZvciBwcmltaXRpdmUgdHlwZXMgdGhhdCBkb24ndCBoYXZlCisgIC8vIGNvbnN0cnVjdG9ycyBmb3IgY29uc2lzdGVuY3kuICAoSW4gdGhlb3J5LCBwbGFjZW1lbnQgbmV3IHNob3VsZCBiZSB1c2VkCisgIC8vIGFueSB0aW1lIHlvdSBhcmUgdHJ5aW5nIHRvIGNvbnZlcnQgdW50eXBlZCBtZW1vcnkgdG8gdHlwZWQgbWVtb3J5LCB0aG91Z2gKKyAgLy8gaW4gcHJhY3RpY2UgdGhhdCdzIG5vdCBzdHJpY3RseSBuZWNlc3NhcnkgZm9yIHR5cGVzIHRoYXQgZG9uJ3QgaGF2ZSBhCisgIC8vIGNvbnN0cnVjdG9yLikKKworICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yID0gdHlwZV9pbmZvXy0+dHlwZTsKKworICAvLyBJbml0aWFsaXplIG9uZW9mIGNhc2VzLgorICBmb3IgKGludCBpID0gMCA7IGkgPCBkZXNjcmlwdG9yLT5vbmVvZl9kZWNsX2NvdW50KCk7ICsraSkgeworICAgIG5ldyhPZmZzZXRUb1BvaW50ZXIodHlwZV9pbmZvXy0+b25lb2ZfY2FzZV9vZmZzZXQgKyBzaXplb2YodWludDMyKSAqIGkpKQorICAgICAgICB1aW50MzIoMCk7CisgIH0KKworICBpZiAodHlwZV9pbmZvXy0+aXNfZGVmYXVsdF9pbnN0YW5jZV9vZmZzZXQgIT0gLTEpIHsKKyAgICAqcmVpbnRlcnByZXRfY2FzdDxib29sKj4oCisgICAgICAgIE9mZnNldFRvUG9pbnRlcih0eXBlX2luZm9fLT5pc19kZWZhdWx0X2luc3RhbmNlX29mZnNldCkpID0gZmFsc2U7CisgIH0KKworICBuZXcoT2Zmc2V0VG9Qb2ludGVyKHR5cGVfaW5mb18tPnVua25vd25fZmllbGRzX29mZnNldCkpIFVua25vd25GaWVsZFNldDsKKworICBpZiAodHlwZV9pbmZvXy0+ZXh0ZW5zaW9uc19vZmZzZXQgIT0gLTEpIHsKKyAgICBuZXcoT2Zmc2V0VG9Qb2ludGVyKHR5cGVfaW5mb18tPmV4dGVuc2lvbnNfb2Zmc2V0KSkgRXh0ZW5zaW9uU2V0OworICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvci0+ZmllbGQoaSk7CisgICAgdm9pZCogZmllbGRfcHRyID0gT2Zmc2V0VG9Qb2ludGVyKHR5cGVfaW5mb18tPm9mZnNldHNbaV0pOworICAgIGlmIChmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpKSB7CisgICAgICBjb250aW51ZTsKKyAgICB9CisgICAgc3dpdGNoIChmaWVsZC0+Y3BwX3R5cGUoKSkgeworI2RlZmluZSBIQU5ETEVfVFlQRShDUFBUWVBFLCBUWVBFKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV8jI0NQUFRZUEU6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgaWYgKCFmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgIG5ldyhmaWVsZF9wdHIpIFRZUEUoZmllbGQtPmRlZmF1bHRfdmFsdWVfIyNUWVBFKCkpOyAgICAgICAgICAgICAgICBcCisgICAgICAgIH0gZWxzZSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICBuZXcoZmllbGRfcHRyKSBSZXBlYXRlZEZpZWxkPFRZUEU+KCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGJyZWFrOworCisgICAgICBIQU5ETEVfVFlQRShJTlQzMiAsIGludDMyICk7CisgICAgICBIQU5ETEVfVFlQRShJTlQ2NCAsIGludDY0ICk7CisgICAgICBIQU5ETEVfVFlQRShVSU5UMzIsIHVpbnQzMik7CisgICAgICBIQU5ETEVfVFlQRShVSU5UNjQsIHVpbnQ2NCk7CisgICAgICBIQU5ETEVfVFlQRShET1VCTEUsIGRvdWJsZSk7CisgICAgICBIQU5ETEVfVFlQRShGTE9BVCAsIGZsb2F0ICk7CisgICAgICBIQU5ETEVfVFlQRShCT09MICAsIGJvb2wgICk7CisjdW5kZWYgSEFORExFX1RZUEUKKworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRU5VTToKKyAgICAgICAgaWYgKCFmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgeworICAgICAgICAgIG5ldyhmaWVsZF9wdHIpIGludChmaWVsZC0+ZGVmYXVsdF92YWx1ZV9lbnVtKCktPm51bWJlcigpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBuZXcoZmllbGRfcHRyKSBSZXBlYXRlZEZpZWxkPGludD4oKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HOgorICAgICAgICBzd2l0Y2ggKGZpZWxkLT5vcHRpb25zKCkuY3R5cGUoKSkgeworICAgICAgICAgIGRlZmF1bHQ6ICAvLyBUT0RPKGtlbnRvbik6ICBTdXBwb3J0IG90aGVyIHN0cmluZyByZXBzLgorICAgICAgICAgIGNhc2UgRmllbGRPcHRpb25zOjpTVFJJTkc6CisgICAgICAgICAgICBpZiAoIWZpZWxkLT5pc19yZXBlYXRlZCgpKSB7CisgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyogZGVmYXVsdF92YWx1ZTsKKyAgICAgICAgICAgICAgaWYgKGlzX3Byb3RvdHlwZSgpKSB7CisgICAgICAgICAgICAgICAgZGVmYXVsdF92YWx1ZSA9ICZmaWVsZC0+ZGVmYXVsdF92YWx1ZV9zdHJpbmcoKTsKKyAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBkZWZhdWx0X3ZhbHVlID0KKyAgICAgICAgICAgICAgICAgICYocmVpbnRlcnByZXRfY2FzdDxjb25zdCBBcmVuYVN0cmluZ1B0cio+KAorICAgICAgICAgICAgICAgICAgICB0eXBlX2luZm9fLT5wcm90b3R5cGUtPk9mZnNldFRvUG9pbnRlcigKKyAgICAgICAgICAgICAgICAgICAgICB0eXBlX2luZm9fLT5vZmZzZXRzW2ldKSktPkdldChOVUxMKSk7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgQXJlbmFTdHJpbmdQdHIqIGFzcCA9IG5ldyhmaWVsZF9wdHIpIEFyZW5hU3RyaW5nUHRyKCk7CisgICAgICAgICAgICAgIGFzcC0+VW5zYWZlU2V0RGVmYXVsdChkZWZhdWx0X3ZhbHVlKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgIG5ldyhmaWVsZF9wdHIpIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPigpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U6IHsKKyAgICAgICAgaWYgKCFmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgeworICAgICAgICAgIG5ldyhmaWVsZF9wdHIpIE1lc3NhZ2UqKE5VTEwpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGlmIChJc01hcEZpZWxkSW5BcGkoZmllbGQpKSB7CisgICAgICAgICAgICBuZXcgKGZpZWxkX3B0cikgRHluYW1pY01hcEZpZWxkKAorICAgICAgICAgICAgICAgIHR5cGVfaW5mb18tPmZhY3RvcnktPkdldFByb3RvdHlwZU5vTG9jayhmaWVsZC0+bWVzc2FnZV90eXBlKCkpKTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgbmV3IChmaWVsZF9wdHIpIFJlcGVhdGVkUHRyRmllbGQ8TWVzc2FnZT4oKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9Cit9CisKK0R5bmFtaWNNZXNzYWdlOjp+RHluYW1pY01lc3NhZ2UoKSB7CisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSB0eXBlX2luZm9fLT50eXBlOworCisgIHJlaW50ZXJwcmV0X2Nhc3Q8VW5rbm93bkZpZWxkU2V0Kj4oCisgICAgT2Zmc2V0VG9Qb2ludGVyKHR5cGVfaW5mb18tPnVua25vd25fZmllbGRzX29mZnNldCkpLT5+VW5rbm93bkZpZWxkU2V0KCk7CisKKyAgaWYgKHR5cGVfaW5mb18tPmV4dGVuc2lvbnNfb2Zmc2V0ICE9IC0xKSB7CisgICAgcmVpbnRlcnByZXRfY2FzdDxFeHRlbnNpb25TZXQqPigKKyAgICAgIE9mZnNldFRvUG9pbnRlcih0eXBlX2luZm9fLT5leHRlbnNpb25zX29mZnNldCkpLT5+RXh0ZW5zaW9uU2V0KCk7CisgIH0KKworICAvLyBXZSBuZWVkIHRvIG1hbnVhbGx5IHJ1biB0aGUgZGVzdHJ1Y3RvcnMgZm9yIHJlcGVhdGVkIGZpZWxkcyBhbmQgc3RyaW5ncywKKyAgLy8ganVzdCBhcyB3ZSByYW4gdGhlaXIgY29uc3RydWN0b3JzIGluIHRoZSBEeW5hbWljTWVzc2FnZSBjb25zdHJ1Y3Rvci4KKyAgLy8gV2UgYWxzbyBuZWVkIHRvIG1hbnVhbGx5IGRlbGV0ZSBvbmVvZiBmaWVsZHMgaWYgaXQgaXMgc2V0IGFuZCBpcyBzdHJpbmcKKyAgLy8gb3IgbWVzc2FnZS4KKyAgLy8gQWRkaXRpb25hbGx5LCBpZiBhbnkgc2luZ3VsYXIgZW1iZWRkZWQgbWVzc2FnZXMgaGF2ZSBiZWVuIGFsbG9jYXRlZCwgd2UKKyAgLy8gbmVlZCB0byBkZWxldGUgdGhlbSwgVU5MRVNTIHdlIGFyZSB0aGUgcHJvdG90eXBlIG1lc3NhZ2Ugb2YgdGhpcyB0eXBlLAorICAvLyBpbiB3aGljaCBjYXNlIGFueSBlbWJlZGRlZCBtZXNzYWdlcyBhcmUgb3RoZXIgcHJvdG90eXBlcyBhbmQgc2hvdWxkbid0CisgIC8vIGJlIHRvdWNoZWQuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvci0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3ItPmZpZWxkKGkpOworICAgIGlmIChmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpKSB7CisgICAgICB2b2lkKiBmaWVsZF9wdHIgPSBPZmZzZXRUb1BvaW50ZXIoCisgICAgICAgICAgdHlwZV9pbmZvXy0+b25lb2ZfY2FzZV9vZmZzZXQKKyAgICAgICAgICArIHNpemVvZih1aW50MzIpICogZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKS0+aW5kZXgoKSk7CisgICAgICBpZiAoKihyZWludGVycHJldF9jYXN0PGNvbnN0IHVpbnQzMio+KGZpZWxkX3B0cikpID09CisgICAgICAgICAgZmllbGQtPm51bWJlcigpKSB7CisgICAgICAgIGZpZWxkX3B0ciA9IE9mZnNldFRvUG9pbnRlcih0eXBlX2luZm9fLT5vZmZzZXRzWworICAgICAgICAgICAgZGVzY3JpcHRvci0+ZmllbGRfY291bnQoKSArIGZpZWxkLT5jb250YWluaW5nX29uZW9mKCktPmluZGV4KCldKTsKKyAgICAgICAgaWYgKGZpZWxkLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9TVFJJTkcpIHsKKyAgICAgICAgICBzd2l0Y2ggKGZpZWxkLT5vcHRpb25zKCkuY3R5cGUoKSkgeworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIGNhc2UgRmllbGRPcHRpb25zOjpTVFJJTkc6IHsKKyAgICAgICAgICAgICAgY29uc3QgOjpzdGQ6OnN0cmluZyogZGVmYXVsdF92YWx1ZSA9CisgICAgICAgICAgICAgICAgICAmKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgQXJlbmFTdHJpbmdQdHIqPigKKyAgICAgICAgICAgICAgICAgICAgICB0eXBlX2luZm9fLT5wcm90b3R5cGUtPk9mZnNldFRvUG9pbnRlcigKKyAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZV9pbmZvXy0+b2Zmc2V0c1tpXSkpLT5HZXQoTlVMTCkpOworICAgICAgICAgICAgICByZWludGVycHJldF9jYXN0PEFyZW5hU3RyaW5nUHRyKj4oZmllbGRfcHRyKS0+RGVzdHJveSgKKyAgICAgICAgICAgICAgICAgIGRlZmF1bHRfdmFsdWUsIE5VTEwpOworICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSBpZiAoZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UpIHsKKyAgICAgICAgICAgIGRlbGV0ZSAqcmVpbnRlcnByZXRfY2FzdDxNZXNzYWdlKio+KGZpZWxkX3B0cik7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIGNvbnRpbnVlOworICAgIH0KKyAgICB2b2lkKiBmaWVsZF9wdHIgPSBPZmZzZXRUb1BvaW50ZXIodHlwZV9pbmZvXy0+b2Zmc2V0c1tpXSk7CisKKyAgICBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkpIHsKKyAgICAgIHN3aXRjaCAoZmllbGQtPmNwcF90eXBlKCkpIHsKKyNkZWZpbmUgSEFORExFX1RZUEUoVVBQRVJDQVNFLCBMT1dFUkNBU0UpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfIyNVUFBFUkNBU0UgOiAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICByZWludGVycHJldF9jYXN0PFJlcGVhdGVkRmllbGQ8TE9XRVJDQVNFPio+KGZpZWxkX3B0cikgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgLT5+UmVwZWF0ZWRGaWVsZDxMT1dFUkNBU0U+KCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICBicmVhaworCisgICAgICAgIEhBTkRMRV9UWVBFKCBJTlQzMiwgIGludDMyKTsKKyAgICAgICAgSEFORExFX1RZUEUoIElOVDY0LCAgaW50NjQpOworICAgICAgICBIQU5ETEVfVFlQRShVSU5UMzIsIHVpbnQzMik7CisgICAgICAgIEhBTkRMRV9UWVBFKFVJTlQ2NCwgdWludDY0KTsKKyAgICAgICAgSEFORExFX1RZUEUoRE9VQkxFLCBkb3VibGUpOworICAgICAgICBIQU5ETEVfVFlQRSggRkxPQVQsICBmbG9hdCk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgQk9PTCwgICBib29sKTsKKyAgICAgICAgSEFORExFX1RZUEUoICBFTlVNLCAgICBpbnQpOworI3VuZGVmIEhBTkRMRV9UWVBFCisKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HOgorICAgICAgICAgIHN3aXRjaCAoZmllbGQtPm9wdGlvbnMoKS5jdHlwZSgpKSB7CisgICAgICAgICAgICBkZWZhdWx0OiAgLy8gVE9ETyhrZW50b24pOiAgU3VwcG9ydCBvdGhlciBzdHJpbmcgcmVwcy4KKyAgICAgICAgICAgIGNhc2UgRmllbGRPcHRpb25zOjpTVFJJTkc6CisgICAgICAgICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8UmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+Kj4oZmllbGRfcHRyKQorICAgICAgICAgICAgICAgICAgLT5+UmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+KCk7CisgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIH0KKyAgICAgICAgICBicmVhazsKKworICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgICAgIGlmIChJc01hcEZpZWxkSW5BcGkoZmllbGQpKSB7CisgICAgICAgICAgICByZWludGVycHJldF9jYXN0PER5bmFtaWNNYXBGaWVsZCo+KGZpZWxkX3B0ciktPn5EeW5hbWljTWFwRmllbGQoKTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmVpbnRlcnByZXRfY2FzdDxSZXBlYXRlZFB0ckZpZWxkPE1lc3NhZ2U+Kj4oZmllbGRfcHRyKQorICAgICAgICAgICAgICAgIC0+flJlcGVhdGVkUHRyRmllbGQ8TWVzc2FnZT4oKTsKKyAgICAgICAgICB9CisgICAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICB9IGVsc2UgaWYgKGZpZWxkLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9TVFJJTkcpIHsKKyAgICAgIHN3aXRjaCAoZmllbGQtPm9wdGlvbnMoKS5jdHlwZSgpKSB7CisgICAgICAgIGRlZmF1bHQ6ICAvLyBUT0RPKGtlbnRvbik6ICBTdXBwb3J0IG90aGVyIHN0cmluZyByZXBzLgorICAgICAgICBjYXNlIEZpZWxkT3B0aW9uczo6U1RSSU5HOiB7CisgICAgICAgICAgY29uc3QgOjpzdGQ6OnN0cmluZyogZGVmYXVsdF92YWx1ZSA9CisgICAgICAgICAgICAgICYocmVpbnRlcnByZXRfY2FzdDxjb25zdCBBcmVuYVN0cmluZ1B0cio+KAorICAgICAgICAgICAgICAgICAgdHlwZV9pbmZvXy0+cHJvdG90eXBlLT5PZmZzZXRUb1BvaW50ZXIoCisgICAgICAgICAgICAgICAgICAgICAgdHlwZV9pbmZvXy0+b2Zmc2V0c1tpXSkpLT5HZXQoTlVMTCkpOworICAgICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8QXJlbmFTdHJpbmdQdHIqPihmaWVsZF9wdHIpLT5EZXN0cm95KAorICAgICAgICAgICAgICBkZWZhdWx0X3ZhbHVlLCBOVUxMKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0gZWxzZSBpZiAoZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UpIHsKKyAgICAgIGlmICghaXNfcHJvdG90eXBlKCkpIHsKKyAgICAgICAgTWVzc2FnZSogbWVzc2FnZSA9ICpyZWludGVycHJldF9jYXN0PE1lc3NhZ2UqKj4oZmllbGRfcHRyKTsKKyAgICAgICAgaWYgKG1lc3NhZ2UgIT0gTlVMTCkgeworICAgICAgICAgIGRlbGV0ZSBtZXNzYWdlOworICAgICAgICB9CisgICAgICB9CisgICAgfQorICB9Cit9CisKK3ZvaWQgRHluYW1pY01lc3NhZ2U6OkNyb3NzTGlua1Byb3RvdHlwZXMoKSB7CisgIC8vIFRoaXMgc2hvdWxkIG9ubHkgYmUgY2FsbGVkIG9uIHRoZSBwcm90b3R5cGUgbWVzc2FnZS4KKyAgR09PR0xFX0NIRUNLKGlzX3Byb3RvdHlwZSgpKTsKKworICBEeW5hbWljTWVzc2FnZUZhY3RvcnkqIGZhY3RvcnkgPSB0eXBlX2luZm9fLT5mYWN0b3J5OworICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yID0gdHlwZV9pbmZvXy0+dHlwZTsKKworICAvLyBDcm9zcy1saW5rIGRlZmF1bHQgbWVzc2FnZXMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvci0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3ItPmZpZWxkKGkpOworICAgIHZvaWQqIGZpZWxkX3B0ciA9IE9mZnNldFRvUG9pbnRlcih0eXBlX2luZm9fLT5vZmZzZXRzW2ldKTsKKyAgICBpZiAoZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSkgeworICAgICAgZmllbGRfcHRyID0gcmVpbnRlcnByZXRfY2FzdDx1aW50OCo+KAorICAgICAgICAgIHR5cGVfaW5mb18tPmRlZmF1bHRfb25lb2ZfaW5zdGFuY2UpICsgdHlwZV9pbmZvXy0+b2Zmc2V0c1tpXTsKKyAgICB9CisKKyAgICBpZiAoZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UgJiYKKyAgICAgICAgIWZpZWxkLT5pc19yZXBlYXRlZCgpKSB7CisgICAgICAvLyBGb3IgZmllbGRzIHdpdGggbWVzc2FnZSB0eXBlcywgd2UgbmVlZCB0byBjcm9zcy1saW5rIHdpdGggdGhlCisgICAgICAvLyBwcm90b3R5cGUgZm9yIHRoZSBmaWVsZCdzIHR5cGUuCisgICAgICAvLyBGb3Igc2luZ3VsYXIgZmllbGRzLCB0aGUgZmllbGQgaXMganVzdCBhIHBvaW50ZXIgd2hpY2ggc2hvdWxkCisgICAgICAvLyBwb2ludCB0byB0aGUgcHJvdG90eXBlLgorICAgICAgKnJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgTWVzc2FnZSoqPihmaWVsZF9wdHIpID0KKyAgICAgICAgZmFjdG9yeS0+R2V0UHJvdG90eXBlTm9Mb2NrKGZpZWxkLT5tZXNzYWdlX3R5cGUoKSk7CisgICAgfQorICB9CisKKyAgLy8gU2V0IGFzIHRoZSBkZWZhdWx0IGluc3RhbmNlIC0tIHRoaXMgYWZmZWN0cyBmaWVsZC1wcmVzZW5jZSBzZW1hbnRpY3MgZm9yCisgIC8vIHByb3RvMy4KKyAgaWYgKHR5cGVfaW5mb18tPmlzX2RlZmF1bHRfaW5zdGFuY2Vfb2Zmc2V0ICE9IC0xKSB7CisgICAgdm9pZCogaXNfZGVmYXVsdF9pbnN0YW5jZV9wdHIgPQorICAgICAgICBPZmZzZXRUb1BvaW50ZXIodHlwZV9pbmZvXy0+aXNfZGVmYXVsdF9pbnN0YW5jZV9vZmZzZXQpOworICAgICpyZWludGVycHJldF9jYXN0PGJvb2wqPihpc19kZWZhdWx0X2luc3RhbmNlX3B0cikgPSB0cnVlOworICB9Cit9CisKK01lc3NhZ2UqIER5bmFtaWNNZXNzYWdlOjpOZXcoKSBjb25zdCB7CisgIHZvaWQqIG5ld19iYXNlID0gb3BlcmF0b3IgbmV3KHR5cGVfaW5mb18tPnNpemUpOworICBtZW1zZXQobmV3X2Jhc2UsIDAsIHR5cGVfaW5mb18tPnNpemUpOworICByZXR1cm4gbmV3KG5ld19iYXNlKSBEeW5hbWljTWVzc2FnZSh0eXBlX2luZm9fKTsKK30KKworTWVzc2FnZSogRHluYW1pY01lc3NhZ2U6Ok5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3QgeworICBpZiAoYXJlbmEgIT0gTlVMTCkgeworICAgIE1lc3NhZ2UqIG1lc3NhZ2UgPSBOZXcoKTsKKyAgICBhcmVuYS0+T3duKG1lc3NhZ2UpOworICAgIHJldHVybiBtZXNzYWdlOworICB9IGVsc2UgeworICAgIHJldHVybiBOZXcoKTsKKyAgfQorfQorCitpbnQgRHluYW1pY01lc3NhZ2U6OkdldENhY2hlZFNpemUoKSBjb25zdCB7CisgIHJldHVybiBjYWNoZWRfYnl0ZV9zaXplXzsKK30KKwordm9pZCBEeW5hbWljTWVzc2FnZTo6U2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3QgeworICAvLyBUaGlzIGlzIHRoZW9yZXRpY2FsbHkgbm90IHRocmVhZC1jb21wYXRpYmxlLCBidXQgaW4gcHJhY3RpY2UgaXQgd29ya3MKKyAgLy8gYmVjYXVzZSBpZiBtdWx0aXBsZSB0aHJlYWRzIHdyaXRlIHRoaXMgc2ltdWx0YW5lb3VzbHksIHRoZXkgd2lsbCBiZQorICAvLyB3cml0aW5nIHRoZSBleGFjdCBzYW1lIHZhbHVlLgorICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBjYWNoZWRfYnl0ZV9zaXplXyA9IHNpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworfQorCitNZXRhZGF0YSBEeW5hbWljTWVzc2FnZTo6R2V0TWV0YWRhdGEoKSBjb25zdCB7CisgIE1ldGFkYXRhIG1ldGFkYXRhOworICBtZXRhZGF0YS5kZXNjcmlwdG9yID0gdHlwZV9pbmZvXy0+dHlwZTsKKyAgbWV0YWRhdGEucmVmbGVjdGlvbiA9IHR5cGVfaW5mb18tPnJlZmxlY3Rpb24uZ2V0KCk7CisgIHJldHVybiBtZXRhZGF0YTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitzdHJ1Y3QgRHluYW1pY01lc3NhZ2VGYWN0b3J5OjpQcm90b3R5cGVNYXAgeworICB0eXBlZGVmIGhhc2hfbWFwPGNvbnN0IERlc2NyaXB0b3IqLCBjb25zdCBEeW5hbWljTWVzc2FnZTo6VHlwZUluZm8qPiBNYXA7CisgIE1hcCBtYXBfOworfTsKKworRHluYW1pY01lc3NhZ2VGYWN0b3J5OjpEeW5hbWljTWVzc2FnZUZhY3RvcnkoKQorICA6IHBvb2xfKE5VTEwpLCBkZWxlZ2F0ZV90b19nZW5lcmF0ZWRfZmFjdG9yeV8oZmFsc2UpLAorICAgIHByb3RvdHlwZXNfKG5ldyBQcm90b3R5cGVNYXApIHsKK30KKworRHluYW1pY01lc3NhZ2VGYWN0b3J5OjpEeW5hbWljTWVzc2FnZUZhY3RvcnkoY29uc3QgRGVzY3JpcHRvclBvb2wqIHBvb2wpCisgIDogcG9vbF8ocG9vbCksIGRlbGVnYXRlX3RvX2dlbmVyYXRlZF9mYWN0b3J5XyhmYWxzZSksCisgICAgcHJvdG90eXBlc18obmV3IFByb3RvdHlwZU1hcCkgeworfQorCitEeW5hbWljTWVzc2FnZUZhY3Rvcnk6On5EeW5hbWljTWVzc2FnZUZhY3RvcnkoKSB7CisgIGZvciAoUHJvdG90eXBlTWFwOjpNYXA6Oml0ZXJhdG9yIGl0ZXIgPSBwcm90b3R5cGVzXy0+bWFwXy5iZWdpbigpOworICAgICAgIGl0ZXIgIT0gcHJvdG90eXBlc18tPm1hcF8uZW5kKCk7ICsraXRlcikgeworICAgIERlbGV0ZURlZmF1bHRPbmVvZkluc3RhbmNlKGl0ZXItPnNlY29uZC0+dHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVyLT5zZWNvbmQtPm9mZnNldHMuZ2V0KCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlci0+c2Vjb25kLT5kZWZhdWx0X29uZW9mX2luc3RhbmNlKTsKKyAgICBkZWxldGUgaXRlci0+c2Vjb25kOworICB9Cit9CisKK2NvbnN0IE1lc3NhZ2UqIER5bmFtaWNNZXNzYWdlRmFjdG9yeTo6R2V0UHJvdG90eXBlKGNvbnN0IERlc2NyaXB0b3IqIHR5cGUpIHsKKyAgTXV0ZXhMb2NrIGxvY2soJnByb3RvdHlwZXNfbXV0ZXhfKTsKKyAgcmV0dXJuIEdldFByb3RvdHlwZU5vTG9jayh0eXBlKTsKK30KKworY29uc3QgTWVzc2FnZSogRHluYW1pY01lc3NhZ2VGYWN0b3J5OjpHZXRQcm90b3R5cGVOb0xvY2soCisgICAgY29uc3QgRGVzY3JpcHRvciogdHlwZSkgeworICBpZiAoZGVsZWdhdGVfdG9fZ2VuZXJhdGVkX2ZhY3RvcnlfICYmCisgICAgICB0eXBlLT5maWxlKCktPnBvb2woKSA9PSBEZXNjcmlwdG9yUG9vbDo6Z2VuZXJhdGVkX3Bvb2woKSkgeworICAgIHJldHVybiBNZXNzYWdlRmFjdG9yeTo6Z2VuZXJhdGVkX2ZhY3RvcnkoKS0+R2V0UHJvdG90eXBlKHR5cGUpOworICB9CisKKyAgY29uc3QgRHluYW1pY01lc3NhZ2U6OlR5cGVJbmZvKiogdGFyZ2V0ID0gJnByb3RvdHlwZXNfLT5tYXBfW3R5cGVdOworICBpZiAoKnRhcmdldCAhPSBOVUxMKSB7CisgICAgLy8gQWxyZWFkeSBleGlzdHMuCisgICAgcmV0dXJuICgqdGFyZ2V0KS0+cHJvdG90eXBlOworICB9CisKKyAgRHluYW1pY01lc3NhZ2U6OlR5cGVJbmZvKiB0eXBlX2luZm8gPSBuZXcgRHluYW1pY01lc3NhZ2U6OlR5cGVJbmZvOworICAqdGFyZ2V0ID0gdHlwZV9pbmZvOworCisgIHR5cGVfaW5mby0+dHlwZSA9IHR5cGU7CisgIHR5cGVfaW5mby0+cG9vbCA9IChwb29sXyA9PSBOVUxMKSA/IHR5cGUtPmZpbGUoKS0+cG9vbCgpIDogcG9vbF87CisgIHR5cGVfaW5mby0+ZmFjdG9yeSA9IHRoaXM7CisKKyAgLy8gV2UgbmVlZCB0byBjb25zdHJ1Y3QgYWxsIHRoZSBzdHJ1Y3R1cmVzIHBhc3NlZCB0bworICAvLyBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbidzIGNvbnN0cnVjdG9yLiAgVGhpcyBpbmNsdWRlczoKKyAgLy8gLSBBIGJsb2NrIG9mIG1lbW9yeSB0aGF0IGNvbnRhaW5zIHNwYWNlIGZvciBhbGwgdGhlIG1lc3NhZ2UncyBmaWVsZHMuCisgIC8vIC0gQW4gYXJyYXkgb2YgaW50ZWdlcnMgaW5kaWNhdGluZyB0aGUgYnl0ZSBvZmZzZXQgb2YgZWFjaCBmaWVsZCB3aXRoaW4KKyAgLy8gICB0aGlzIGJsb2NrLgorICAvLyAtIEEgYmlnIGJpdGZpZWxkIGNvbnRhaW5pbmcgYSBiaXQgZm9yIGVhY2ggZmllbGQgaW5kaWNhdGluZyB3aGV0aGVyCisgIC8vICAgb3Igbm90IHRoYXQgZmllbGQgaXMgc2V0LgorCisgIC8vIENvbXB1dGUgc2l6ZSBhbmQgb2Zmc2V0cy4KKyAgaW50KiBvZmZzZXRzID0gbmV3IGludFt0eXBlLT5maWVsZF9jb3VudCgpICsgdHlwZS0+b25lb2ZfZGVjbF9jb3VudCgpXTsKKyAgdHlwZV9pbmZvLT5vZmZzZXRzLnJlc2V0KG9mZnNldHMpOworCisgIC8vIERlY2lkZSBhbGwgZmllbGQgb2Zmc2V0cyBieSBwYWNraW5nIGluIG9yZGVyLgorICAvLyBXZSBwbGFjZSB0aGUgRHluYW1pY01lc3NhZ2Ugb2JqZWN0IGl0c2VsZiBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBhbGxvY2F0ZWQKKyAgLy8gc3BhY2UuCisgIGludCBzaXplID0gc2l6ZW9mKER5bmFtaWNNZXNzYWdlKTsKKyAgc2l6ZSA9IEFsaWduT2Zmc2V0KHNpemUpOworCisgIC8vIE5leHQgdGhlIGhhc19iaXRzLCB3aGljaCBpcyBhbiBhcnJheSBvZiB1aW50MzJzLgorICBpZiAodHlwZS0+ZmlsZSgpLT5zeW50YXgoKSA9PSBGaWxlRGVzY3JpcHRvcjo6U1lOVEFYX1BST1RPMykgeworICAgIHR5cGVfaW5mby0+aGFzX2JpdHNfb2Zmc2V0ID0gLTE7CisgIH0gZWxzZSB7CisgICAgdHlwZV9pbmZvLT5oYXNfYml0c19vZmZzZXQgPSBzaXplOworICAgIGludCBoYXNfYml0c19hcnJheV9zaXplID0KKyAgICAgIERpdmlkZVJvdW5kaW5nVXAodHlwZS0+ZmllbGRfY291bnQoKSwgYml0c2l6ZW9mKHVpbnQzMikpOworICAgIHNpemUgKz0gaGFzX2JpdHNfYXJyYXlfc2l6ZSAqIHNpemVvZih1aW50MzIpOworICAgIHNpemUgPSBBbGlnbk9mZnNldChzaXplKTsKKyAgfQorCisgIC8vIFRoZSBpc19kZWZhdWx0X2luc3RhbmNlIG1lbWJlciwgaWYgYW55LgorICBpZiAodHlwZS0+ZmlsZSgpLT5zeW50YXgoKSA9PSBGaWxlRGVzY3JpcHRvcjo6U1lOVEFYX1BST1RPMykgeworICAgIHR5cGVfaW5mby0+aXNfZGVmYXVsdF9pbnN0YW5jZV9vZmZzZXQgPSBzaXplOworICAgIHNpemUgKz0gc2l6ZW9mKGJvb2wpOworICAgIHNpemUgPSBBbGlnbk9mZnNldChzaXplKTsKKyAgfSBlbHNlIHsKKyAgICB0eXBlX2luZm8tPmlzX2RlZmF1bHRfaW5zdGFuY2Vfb2Zmc2V0ID0gLTE7CisgIH0KKworICAvLyBUaGUgb25lb2ZfY2FzZSwgaWYgYW55LiBJdCBpcyBhbiBhcnJheSBvZiB1aW50MzJzLgorICBpZiAodHlwZS0+b25lb2ZfZGVjbF9jb3VudCgpID4gMCkgeworICAgIHR5cGVfaW5mby0+b25lb2ZfY2FzZV9vZmZzZXQgPSBzaXplOworICAgIHNpemUgKz0gdHlwZS0+b25lb2ZfZGVjbF9jb3VudCgpICogc2l6ZW9mKHVpbnQzMik7CisgICAgc2l6ZSA9IEFsaWduT2Zmc2V0KHNpemUpOworICB9CisKKyAgLy8gVGhlIEV4dGVuc2lvblNldCwgaWYgYW55LgorICBpZiAodHlwZS0+ZXh0ZW5zaW9uX3JhbmdlX2NvdW50KCkgPiAwKSB7CisgICAgdHlwZV9pbmZvLT5leHRlbnNpb25zX29mZnNldCA9IHNpemU7CisgICAgc2l6ZSArPSBzaXplb2YoRXh0ZW5zaW9uU2V0KTsKKyAgICBzaXplID0gQWxpZ25PZmZzZXQoc2l6ZSk7CisgIH0gZWxzZSB7CisgICAgLy8gTm8gZXh0ZW5zaW9ucy4KKyAgICB0eXBlX2luZm8tPmV4dGVuc2lvbnNfb2Zmc2V0ID0gLTE7CisgIH0KKworICAvLyBBbGwgdGhlIGZpZWxkcy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0eXBlLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICAvLyBNYWtlIHN1cmUgZmllbGQgaXMgYWxpZ25lZCB0byBhdm9pZCBidXMgZXJyb3JzLgorICAgIC8vIE9uZW9mIGZpZWxkcyBkbyBub3QgdXNlIGFueSBzcGFjZS4KKyAgICBpZiAoIXR5cGUtPmZpZWxkKGkpLT5jb250YWluaW5nX29uZW9mKCkpIHsKKyAgICAgIGludCBmaWVsZF9zaXplID0gRmllbGRTcGFjZVVzZWQodHlwZS0+ZmllbGQoaSkpOworICAgICAgc2l6ZSA9IEFsaWduVG8oc2l6ZSwgbWluKGtTYWZlQWxpZ25tZW50LCBmaWVsZF9zaXplKSk7CisgICAgICBvZmZzZXRzW2ldID0gc2l6ZTsKKyAgICAgIHNpemUgKz0gZmllbGRfc2l6ZTsKKyAgICB9CisgIH0KKworICAvLyBUaGUgb25lb2ZzLgorICBmb3IgKGludCBpID0gMDsgaSA8IHR5cGUtPm9uZW9mX2RlY2xfY291bnQoKTsgaSsrKSB7CisgICAgc2l6ZSA9IEFsaWduVG8oc2l6ZSwga1NhZmVBbGlnbm1lbnQpOworICAgIG9mZnNldHNbdHlwZS0+ZmllbGRfY291bnQoKSArIGldID0gc2l6ZTsKKyAgICBzaXplICs9IGtNYXhPbmVvZlVuaW9uU2l6ZTsKKyAgfQorCisgIC8vIEFkZCB0aGUgVW5rbm93bkZpZWxkU2V0IHRvIHRoZSBlbmQuCisgIHNpemUgPSBBbGlnbk9mZnNldChzaXplKTsKKyAgdHlwZV9pbmZvLT51bmtub3duX2ZpZWxkc19vZmZzZXQgPSBzaXplOworICBzaXplICs9IHNpemVvZihVbmtub3duRmllbGRTZXQpOworCisgIC8vIEFsaWduIHRoZSBmaW5hbCBzaXplIHRvIG1ha2Ugc3VyZSBubyBjbGV2ZXIgYWxsb2NhdG9ycyB0aGluayB0aGF0CisgIC8vIGFsaWdubWVudCBpcyBub3QgbmVjZXNzYXJ5LgorICBzaXplID0gQWxpZ25PZmZzZXQoc2l6ZSk7CisgIHR5cGVfaW5mby0+c2l6ZSA9IHNpemU7CisKKyAgLy8gQWxsb2NhdGUgdGhlIHByb3RvdHlwZS4KKyAgdm9pZCogYmFzZSA9IG9wZXJhdG9yIG5ldyhzaXplKTsKKyAgbWVtc2V0KGJhc2UsIDAsIHNpemUpOworICAvLyBUaGUgcHJvdG90eXBlIGluIHR5cGVfaW5mbyBoYXMgdG8gYmUgc2V0IGJlZm9yZSBjcmVhdGluZyB0aGUgcHJvdG90eXBlCisgIC8vIGluc3RhbmNlIG9uIG1lbW9yeS4gZS5nLiwgbWVzc2FnZSBGb28geyBtYXA8aW50MzIsIEZvbz4gYSA9IDE7IH0uIFdoZW4KKyAgLy8gY3JlYXRpbmcgcHJvdG90eXBlIGZvciBGb28sIHByb3RvdHlwZSBvZiB0aGUgbWFwIGVudHJ5IHdpbGwgYWxzbyBiZQorICAvLyBjcmVhdGVkLCB3aGljaCBuZWVkcyB0aGUgYWRkcmVzcyBvZiB0aGUgcHJvdG90eXBlIG9mIEZvbyAodGhlIHZhbHVlIGluCisgIC8vIG1hcCkuIFRvIGJyZWFrIHRoZSBjeWNsaWMgZGVwZW5kZW5jeSwgd2UgaGF2ZSB0byBhc3NnaW4gdGhlIGFkZHJlc3Mgb2YKKyAgLy8gcHJvdG90eXBlIGludG8gdHlwZV9pbmZvIGZpcnN0LgorICB0eXBlX2luZm8tPnByb3RvdHlwZSA9IHN0YXRpY19jYXN0PER5bmFtaWNNZXNzYWdlKj4oYmFzZSk7CisgIER5bmFtaWNNZXNzYWdlKiBwcm90b3R5cGUgPSBuZXcoYmFzZSkgRHluYW1pY01lc3NhZ2UodHlwZV9pbmZvKTsKKworICAvLyBDb25zdHJ1Y3QgdGhlIHJlZmxlY3Rpb24gb2JqZWN0LgorICBpZiAodHlwZS0+b25lb2ZfZGVjbF9jb3VudCgpID4gMCkgeworICAgIC8vIENvbXB1dGUgdGhlIHNpemUgb2YgZGVmYXVsdCBvbmVvZiBpbnN0YW5jZSBhbmQgb2Zmc2V0cyBvZiBkZWZhdWx0CisgICAgLy8gb25lb2YgZmllbGRzLgorICAgIGludCBvbmVvZl9zaXplID0gMDsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHR5cGUtPm9uZW9mX2RlY2xfY291bnQoKTsgaSsrKSB7CisgICAgICBmb3IgKGludCBqID0gMDsgaiA8IHR5cGUtPm9uZW9mX2RlY2woaSktPmZpZWxkX2NvdW50KCk7IGorKykgeworICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gdHlwZS0+b25lb2ZfZGVjbChpKS0+ZmllbGQoaik7CisgICAgICAgIGludCBmaWVsZF9zaXplID0gT25lb2ZGaWVsZFNwYWNlVXNlZChmaWVsZCk7CisgICAgICAgIG9uZW9mX3NpemUgPSBBbGlnblRvKG9uZW9mX3NpemUsIG1pbihrU2FmZUFsaWdubWVudCwgZmllbGRfc2l6ZSkpOworICAgICAgICBvZmZzZXRzW2ZpZWxkLT5pbmRleCgpXSA9IG9uZW9mX3NpemU7CisgICAgICAgIG9uZW9mX3NpemUgKz0gZmllbGRfc2l6ZTsKKyAgICAgIH0KKyAgICB9CisgICAgLy8gQ29uc3RydWN0IGRlZmF1bHQgb25lb2YgaW5zdGFuY2UuCisgICAgdHlwZV9pbmZvLT5kZWZhdWx0X29uZW9mX2luc3RhbmNlID0gOjpvcGVyYXRvciBuZXcob25lb2Zfc2l6ZSk7CisgICAgQ29uc3RydWN0RGVmYXVsdE9uZW9mSW5zdGFuY2UodHlwZV9pbmZvLT50eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVfaW5mby0+b2Zmc2V0cy5nZXQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlX2luZm8tPmRlZmF1bHRfb25lb2ZfaW5zdGFuY2UpOworICAgIHR5cGVfaW5mby0+cmVmbGVjdGlvbi5yZXNldCgKKyAgICAgICAgbmV3IEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKAorICAgICAgICAgICAgdHlwZV9pbmZvLT50eXBlLAorICAgICAgICAgICAgdHlwZV9pbmZvLT5wcm90b3R5cGUsCisgICAgICAgICAgICB0eXBlX2luZm8tPm9mZnNldHMuZ2V0KCksCisgICAgICAgICAgICB0eXBlX2luZm8tPmhhc19iaXRzX29mZnNldCwKKyAgICAgICAgICAgIHR5cGVfaW5mby0+dW5rbm93bl9maWVsZHNfb2Zmc2V0LAorICAgICAgICAgICAgdHlwZV9pbmZvLT5leHRlbnNpb25zX29mZnNldCwKKyAgICAgICAgICAgIHR5cGVfaW5mby0+ZGVmYXVsdF9vbmVvZl9pbnN0YW5jZSwKKyAgICAgICAgICAgIHR5cGVfaW5mby0+b25lb2ZfY2FzZV9vZmZzZXQsCisgICAgICAgICAgICB0eXBlX2luZm8tPnBvb2wsCisgICAgICAgICAgICB0aGlzLAorICAgICAgICAgICAgdHlwZV9pbmZvLT5zaXplLAorICAgICAgICAgICAgLTEgLyogYXJlbmFfb2Zmc2V0ICovLAorICAgICAgICAgICAgdHlwZV9pbmZvLT5pc19kZWZhdWx0X2luc3RhbmNlX29mZnNldCkpOworICB9IGVsc2UgeworICAgIHR5cGVfaW5mby0+cmVmbGVjdGlvbi5yZXNldCgKKyAgICAgICAgbmV3IEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKAorICAgICAgICAgICAgdHlwZV9pbmZvLT50eXBlLAorICAgICAgICAgICAgdHlwZV9pbmZvLT5wcm90b3R5cGUsCisgICAgICAgICAgICB0eXBlX2luZm8tPm9mZnNldHMuZ2V0KCksCisgICAgICAgICAgICB0eXBlX2luZm8tPmhhc19iaXRzX29mZnNldCwKKyAgICAgICAgICAgIHR5cGVfaW5mby0+dW5rbm93bl9maWVsZHNfb2Zmc2V0LAorICAgICAgICAgICAgdHlwZV9pbmZvLT5leHRlbnNpb25zX29mZnNldCwKKyAgICAgICAgICAgIHR5cGVfaW5mby0+cG9vbCwKKyAgICAgICAgICAgIHRoaXMsCisgICAgICAgICAgICB0eXBlX2luZm8tPnNpemUsCisgICAgICAgICAgICAtMSAvKiBhcmVuYV9vZmZzZXQgKi8sCisgICAgICAgICAgICB0eXBlX2luZm8tPmlzX2RlZmF1bHRfaW5zdGFuY2Vfb2Zmc2V0KSk7CisgIH0KKyAgLy8gQ3Jvc3MgbGluayBwcm90b3R5cGVzLgorICBwcm90b3R5cGUtPkNyb3NzTGlua1Byb3RvdHlwZXMoKTsKKworICByZXR1cm4gcHJvdG90eXBlOworfQorCit2b2lkIER5bmFtaWNNZXNzYWdlRmFjdG9yeTo6Q29uc3RydWN0RGVmYXVsdE9uZW9mSW5zdGFuY2UoCisgICAgY29uc3QgRGVzY3JpcHRvciogdHlwZSwKKyAgICBjb25zdCBpbnQgb2Zmc2V0c1tdLAorICAgIHZvaWQqIGRlZmF1bHRfb25lb2ZfaW5zdGFuY2UpIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0eXBlLT5vbmVvZl9kZWNsX2NvdW50KCk7IGkrKykgeworICAgIGZvciAoaW50IGogPSAwOyBqIDwgdHlwZS0+b25lb2ZfZGVjbChpKS0+ZmllbGRfY291bnQoKTsgaisrKSB7CisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gdHlwZS0+b25lb2ZfZGVjbChpKS0+ZmllbGQoaik7CisgICAgICB2b2lkKiBmaWVsZF9wdHIgPSByZWludGVycHJldF9jYXN0PHVpbnQ4Kj4oCisgICAgICAgICAgZGVmYXVsdF9vbmVvZl9pbnN0YW5jZSkgKyBvZmZzZXRzW2ZpZWxkLT5pbmRleCgpXTsKKyAgICAgIHN3aXRjaCAoZmllbGQtPmNwcF90eXBlKCkpIHsKKyNkZWZpbmUgSEFORExFX1RZUEUoQ1BQVFlQRSwgVFlQRSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfIyNDUFBUWVBFOiAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICBuZXcoZmllbGRfcHRyKSBUWVBFKGZpZWxkLT5kZWZhdWx0X3ZhbHVlXyMjVFlQRSgpKTsgICAgICAgICAgIFwKKyAgICAgICAgICBicmVhazsKKworICAgICAgICBIQU5ETEVfVFlQRShJTlQzMiAsIGludDMyICk7CisgICAgICAgIEhBTkRMRV9UWVBFKElOVDY0ICwgaW50NjQgKTsKKyAgICAgICAgSEFORExFX1RZUEUoVUlOVDMyLCB1aW50MzIpOworICAgICAgICBIQU5ETEVfVFlQRShVSU5UNjQsIHVpbnQ2NCk7CisgICAgICAgIEhBTkRMRV9UWVBFKERPVUJMRSwgZG91YmxlKTsKKyAgICAgICAgSEFORExFX1RZUEUoRkxPQVQgLCBmbG9hdCApOworICAgICAgICBIQU5ETEVfVFlQRShCT09MICAsIGJvb2wgICk7CisjdW5kZWYgSEFORExFX1RZUEUKKworICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9FTlVNOgorICAgICAgICAgIG5ldyhmaWVsZF9wdHIpIGludChmaWVsZC0+ZGVmYXVsdF92YWx1ZV9lbnVtKCktPm51bWJlcigpKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HOgorICAgICAgICAgIHN3aXRjaCAoZmllbGQtPm9wdGlvbnMoKS5jdHlwZSgpKSB7CisgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgY2FzZSBGaWVsZE9wdGlvbnM6OlNUUklORzoKKyAgICAgICAgICAgICAgQXJlbmFTdHJpbmdQdHIqIGFzcCA9IG5ldyAoZmllbGRfcHRyKSBBcmVuYVN0cmluZ1B0cigpOworICAgICAgICAgICAgICBhc3AtPlVuc2FmZVNldERlZmF1bHQoJmZpZWxkLT5kZWZhdWx0X3ZhbHVlX3N0cmluZygpKTsKKyAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgfQorICAgICAgICAgIGJyZWFrOworCisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U6IHsKKyAgICAgICAgICBuZXcoZmllbGRfcHRyKSBNZXNzYWdlKihOVUxMKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgfQorfQorCit2b2lkIER5bmFtaWNNZXNzYWdlRmFjdG9yeTo6RGVsZXRlRGVmYXVsdE9uZW9mSW5zdGFuY2UoCisgICAgY29uc3QgRGVzY3JpcHRvciogdHlwZSwKKyAgICBjb25zdCBpbnQgb2Zmc2V0c1tdLAorICAgIHZvaWQqIGRlZmF1bHRfb25lb2ZfaW5zdGFuY2UpIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0eXBlLT5vbmVvZl9kZWNsX2NvdW50KCk7IGkrKykgeworICAgIGZvciAoaW50IGogPSAwOyBqIDwgdHlwZS0+b25lb2ZfZGVjbChpKS0+ZmllbGRfY291bnQoKTsgaisrKSB7CisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gdHlwZS0+b25lb2ZfZGVjbChpKS0+ZmllbGQoaik7CisgICAgICBpZiAoZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORykgeworICAgICAgICBzd2l0Y2ggKGZpZWxkLT5vcHRpb25zKCkuY3R5cGUoKSkgeworICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgY2FzZSBGaWVsZE9wdGlvbnM6OlNUUklORzoKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICB9CisgICAgfQorICB9Cit9CisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9keW5hbWljX21lc3NhZ2UuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvZHluYW1pY19tZXNzYWdlLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjc0Y2Q3ZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvZHluYW1pY19tZXNzYWdlLmgKQEAgLTAsMCArMSwxNTIgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBEZWZpbmVzIGFuIGltcGxlbWVudGF0aW9uIG9mIE1lc3NhZ2Ugd2hpY2ggY2FuIGVtdWxhdGUgdHlwZXMgd2hpY2ggYXJlIG5vdAorLy8ga25vd24gYXQgY29tcGlsZS10aW1lLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9EWU5BTUlDX01FU1NBR0VfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9EWU5BTUlDX01FU1NBR0VfSF9fCisKKyNpbmNsdWRlIDxtZW1vcnk+CisjaWZuZGVmIF9TSEFSRURfUFRSX0gKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc2hhcmVkX3B0ci5oPgorI2VuZGlmCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWVzc2FnZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbXV0ZXguaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCisvLyBEZWZpbmVkIGluIG90aGVyIGZpbGVzLgorY2xhc3MgRGVzY3JpcHRvcjsgICAgICAgIC8vIGRlc2NyaXB0b3IuaAorY2xhc3MgRGVzY3JpcHRvclBvb2w7ICAgIC8vIGRlc2NyaXB0b3IuaAorCisvLyBDb25zdHJ1Y3RzIGltcGxlbWVudGF0aW9ucyBvZiBNZXNzYWdlIHdoaWNoIGNhbiBlbXVsYXRlIHR5cGVzIHdoaWNoIGFyZSBub3QKKy8vIGtub3duIGF0IGNvbXBpbGUtdGltZS4KKy8vCisvLyBTb21ldGltZXMgeW91IHdhbnQgdG8gYmUgYWJsZSB0byBtYW5pcHVsYXRlIHByb3RvY29sIHR5cGVzIHRoYXQgeW91IGRvbid0CisvLyBrbm93IGFib3V0IGF0IGNvbXBpbGUgdGltZS4gIEl0IHdvdWxkIGJlIG5pY2UgdG8gYmUgYWJsZSB0byBjb25zdHJ1Y3QKKy8vIGEgTWVzc2FnZSBvYmplY3Qgd2hpY2ggaW1wbGVtZW50cyB0aGUgbWVzc2FnZSB0eXBlIGdpdmVuIGJ5IGFueSBhcmJpdHJhcnkKKy8vIERlc2NyaXB0b3IuICBEeW5hbWljTWVzc2FnZSBwcm92aWRlcyB0aGlzLgorLy8KKy8vIEFzIGl0IHR1cm5zIG91dCwgYSBEeW5hbWljTWVzc2FnZSBuZWVkcyB0byBjb25zdHJ1Y3QgZXh0cmEKKy8vIGluZm9ybWF0aW9uIGFib3V0IGl0cyB0eXBlIGluIG9yZGVyIHRvIG9wZXJhdGUuICBNb3N0IG9mIHRoaXMgaW5mb3JtYXRpb24KKy8vIGNhbiBiZSBzaGFyZWQgYmV0d2VlbiBhbGwgRHluYW1pY01lc3NhZ2VzIG9mIHRoZSBzYW1lIHR5cGUuICBCdXQsIGNhY2hpbmcKKy8vIHRoaXMgaW5mb3JtYXRpb24gaW4gc29tZSBzb3J0IG9mIGdsb2JhbCBtYXAgd291bGQgYmUgYSBiYWQgaWRlYSwgc2luY2UKKy8vIHRoZSBjYWNoZWQgaW5mb3JtYXRpb24gZm9yIGEgcGFydGljdWxhciBkZXNjcmlwdG9yIGNvdWxkIG91dGxpdmUgdGhlCisvLyBkZXNjcmlwdG9yIGl0c2VsZi4gIFRvIGF2b2lkIHRoaXMgcHJvYmxlbSwgRHluYW1pY01lc3NhZ2VGYWN0b3J5CisvLyBlbmNhcHN1bGF0ZXMgdGhpcyAiY2FjaGUiLiAgQWxsIER5bmFtaWNNZXNzYWdlcyBvZiB0aGUgc2FtZSB0eXBlIGNyZWF0ZWQKKy8vIGZyb20gdGhlIHNhbWUgZmFjdG9yeSB3aWxsIHNoYXJlIHRoZSBzYW1lIHN1cHBvcnQgZGF0YS4gIEFueSBEZXNjcmlwdG9ycworLy8gdXNlZCB3aXRoIGEgcGFydGljdWxhciBmYWN0b3J5IG11c3Qgb3V0bGl2ZSB0aGUgZmFjdG9yeS4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBEeW5hbWljTWVzc2FnZUZhY3RvcnkgOiBwdWJsaWMgTWVzc2FnZUZhY3RvcnkgeworIHB1YmxpYzoKKyAgLy8gQ29uc3RydWN0IGEgRHluYW1pY01lc3NhZ2VGYWN0b3J5IHRoYXQgd2lsbCBzZWFyY2ggZm9yIGV4dGVuc2lvbnMgaW4KKyAgLy8gdGhlIERlc2NyaXB0b3JQb29sIGluIHdoaWNoIHRoZSBleHRlbmRlZSBpcyBkZWZpbmVkLgorICBEeW5hbWljTWVzc2FnZUZhY3RvcnkoKTsKKworICAvLyBDb25zdHJ1Y3QgYSBEeW5hbWljTWVzc2FnZUZhY3RvcnkgdGhhdCB3aWxsIHNlYXJjaCBmb3IgZXh0ZW5zaW9ucyBpbgorICAvLyB0aGUgZ2l2ZW4gRGVzY3JpcHRvclBvb2wuCisgIC8vCisgIC8vIERFUFJFQ0FURUQ6ICBVc2UgQ29kZWRJbnB1dFN0cmVhbTo6U2V0RXh0ZW5zaW9uUmVnaXN0cnkoKSB0byB0ZWxsIHRoZQorICAvLyAgIHBhcnNlciB0byBsb29rIGZvciBleHRlbnNpb25zIGluIGFuIGFsdGVybmF0ZSBwb29sLiAgSG93ZXZlciwgbm90ZSB0aGF0CisgIC8vICAgdGhpcyBpcyBhbG1vc3QgbmV2ZXIgd2hhdCB5b3Ugd2FudCB0byBkby4gIEFsbW9zdCBhbGwgdXNlcnMgc2hvdWxkIHVzZQorICAvLyAgIHRoZSB6ZXJvLWFyZyBjb25zdHJ1Y3Rvci4KKyAgRHluYW1pY01lc3NhZ2VGYWN0b3J5KGNvbnN0IERlc2NyaXB0b3JQb29sKiBwb29sKTsKKworICB+RHluYW1pY01lc3NhZ2VGYWN0b3J5KCk7CisKKyAgLy8gQ2FsbCB0aGlzIHRvIHRlbGwgdGhlIER5bmFtaWNNZXNzYWdlRmFjdG9yeSB0aGF0IGlmIGl0IGlzIGdpdmVuIGEKKyAgLy8gRGVzY3JpcHRvciBkIGZvciB3aGljaDoKKyAgLy8gICBkLT5maWxlKCktPnBvb2woKSA9PSBEZXNjcmlwdG9yUG9vbDo6Z2VuZXJhdGVkX3Bvb2woKSwKKyAgLy8gdGhlbiBpdCBzaG91bGQgZGVsZWdhdGUgdG8gTWVzc2FnZUZhY3Rvcnk6OmdlbmVyYXRlZF9mYWN0b3J5KCkgaW5zdGVhZAorICAvLyBvZiBjb25zdHJ1Y3RpbmcgYSBkeW5hbWljIGltcGxlbWVudGF0aW9uIG9mIHRoZSBtZXNzYWdlLiAgSW4gdGhlb3J5IHRoZXJlCisgIC8vIGlzIG5vIGRvd24gc2lkZSB0byBkb2luZyB0aGlzLCBzbyBpdCBtYXkgYmVjb21lIHRoZSBkZWZhdWx0IGluIHRoZSBmdXR1cmUuCisgIHZvaWQgU2V0RGVsZWdhdGVUb0dlbmVyYXRlZEZhY3RvcnkoYm9vbCBlbmFibGUpIHsKKyAgICBkZWxlZ2F0ZV90b19nZW5lcmF0ZWRfZmFjdG9yeV8gPSBlbmFibGU7CisgIH0KKworICAvLyBpbXBsZW1lbnRzIE1lc3NhZ2VGYWN0b3J5IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIEdpdmVuIGEgRGVzY3JpcHRvciwgY29uc3RydWN0cyB0aGUgZGVmYXVsdCAocHJvdG90eXBlKSBNZXNzYWdlIG9mIHRoYXQKKyAgLy8gdHlwZS4gIFlvdSBjYW4gdGhlbiBjYWxsIHRoYXQgbWVzc2FnZSdzIE5ldygpIG1ldGhvZCB0byBjb25zdHJ1Y3QgYQorICAvLyBtdXRhYmxlIG1lc3NhZ2Ugb2YgdGhhdCB0eXBlLgorICAvLworICAvLyBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIHdpdGggdGhlIHNhbWUgRGVzY3JpcHRvciByZXR1cm5zIHRoZSBzYW1lCisgIC8vIG9iamVjdC4gIFRoZSByZXR1cm5lZCBvYmplY3QgcmVtYWlucyBwcm9wZXJ0eSBvZiB0aGUgZmFjdG9yeSBhbmQgd2lsbAorICAvLyBiZSBkZXN0cm95ZWQgd2hlbiB0aGUgZmFjdG9yeSBpcyBkZXN0cm95ZWQuICBBbHNvLCBhbnkgb2JqZWN0cyBjcmVhdGVkCisgIC8vIGJ5IGNhbGxpbmcgdGhlIHByb3RvdHlwZSdzIE5ldygpIG1ldGhvZCBzaGFyZSBzb21lIGRhdGEgd2l0aCB0aGUKKyAgLy8gcHJvdG90eXBlLCBzbyB0aGVzZSBtdXN0IGJlIGRlc3Ryb3llZCBiZWZvcmUgdGhlIER5bmFtaWNNZXNzYWdlRmFjdG9yeQorICAvLyBpcyBkZXN0cm95ZWQuCisgIC8vCisgIC8vIFRoZSBnaXZlbiBkZXNjcmlwdG9yIG11c3Qgb3V0bGl2ZSB0aGUgcmV0dXJuZWQgbWVzc2FnZSwgYW5kIGhlbmNlIG11c3QKKyAgLy8gb3V0bGl2ZSB0aGUgRHluYW1pY01lc3NhZ2VGYWN0b3J5LgorICAvLworICAvLyBUaGUgbWV0aG9kIGlzIHRocmVhZC1zYWZlLgorICBjb25zdCBNZXNzYWdlKiBHZXRQcm90b3R5cGUoY29uc3QgRGVzY3JpcHRvciogdHlwZSk7CisKKyBwcml2YXRlOgorICBjb25zdCBEZXNjcmlwdG9yUG9vbCogcG9vbF87CisgIGJvb2wgZGVsZWdhdGVfdG9fZ2VuZXJhdGVkX2ZhY3RvcnlfOworCisgIC8vIFRoaXMgc3RydWN0IGp1c3QgY29udGFpbnMgYSBoYXNoX21hcC4gIFdlIGNhbid0ICNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvaGFzaC5oPiBmcm9tCisgIC8vIHRoaXMgaGVhZGVyIGR1ZSB0byBoYWNrcyBuZWVkZWQgZm9yIGhhc2hfbWFwIHBvcnRhYmlsaXR5IGluIHRoZSBvcGVuIHNvdXJjZQorICAvLyByZWxlYXNlLiAgTmFtZWx5LCBzdHVicy9oYXNoLmgsIHdoaWNoIGRlZmluZXMgaGFzaF9tYXAgcG9ydGFibHksIGlzIG5vdCBhCisgIC8vIHB1YmxpYyBoZWFkZXIgKGZvciBnb29kIHJlYXNvbiksIGJ1dCBkeW5hbWljX21lc3NhZ2UuaCBpcywgYW5kIHB1YmxpYworICAvLyBoZWFkZXJzIG1heSBvbmx5ICNpbmNsdWRlIG90aGVyIHB1YmxpYyBoZWFkZXJzLgorICBzdHJ1Y3QgUHJvdG90eXBlTWFwOworICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPFByb3RvdHlwZU1hcD4gcHJvdG90eXBlc187CisgIG11dGFibGUgTXV0ZXggcHJvdG90eXBlc19tdXRleF87CisKKyAgZnJpZW5kIGNsYXNzIER5bmFtaWNNZXNzYWdlOworICBjb25zdCBNZXNzYWdlKiBHZXRQcm90b3R5cGVOb0xvY2soY29uc3QgRGVzY3JpcHRvciogdHlwZSk7CisKKyAgLy8gQ29uc3RydWN0IGRlZmF1bHQgb25lb2YgaW5zdGFuY2UgZm9yIHJlZmxlY3Rpb24gdXNhZ2UgaWYgb25lb2YKKyAgLy8gaXMgZGVmaW5lZC4KKyAgc3RhdGljIHZvaWQgQ29uc3RydWN0RGVmYXVsdE9uZW9mSW5zdGFuY2UoY29uc3QgRGVzY3JpcHRvciogdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW50IG9mZnNldHNbXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCogZGVmYXVsdF9vbmVvZl9pbnN0YW5jZSk7CisgIC8vIERlbGV0ZSBkZWZhdWx0IG9uZW9mIGluc3RhbmNlLiBDYWxsZWQgYnkgfkR5bmFtaWNNZXNzYWdlRmFjdG9yeS4KKyAgc3RhdGljIHZvaWQgRGVsZXRlRGVmYXVsdE9uZW9mSW5zdGFuY2UoY29uc3QgRGVzY3JpcHRvciogdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW50IG9mZnNldHNbXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCogZGVmYXVsdF9vbmVvZl9pbnN0YW5jZSk7CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKER5bmFtaWNNZXNzYWdlRmFjdG9yeSk7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfRFlOQU1JQ19NRVNTQUdFX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9keW5hbWljX21lc3NhZ2VfdW5pdHRlc3QuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2R5bmFtaWNfbWVzc2FnZV91bml0dGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MGU0MzdkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9keW5hbWljX21lc3NhZ2VfdW5pdHRlc3QuY2MKQEAgLTAsMCArMSwyOTIgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBTaW5jZSB0aGUgcmVmbGVjdGlvbiBpbnRlcmZhY2UgZm9yIER5bmFtaWNNZXNzYWdlIGlzIGltcGxlbWVudGVkIGJ5CisvLyBHZW5lcmljTWVzc2FnZVJlZmxlY3Rpb24sIHRoZSBvbmx5IHRoaW5nIHdlIHJlYWxseSBoYXZlIHRvIHRlc3QgaXMKKy8vIHRoYXQgRHluYW1pY01lc3NhZ2UgY29ycmVjdGx5IHNldHMgdXAgdGhlIGluZm9ybWF0aW9uIHRoYXQKKy8vIEdlbmVyaWNNZXNzYWdlUmVmbGVjdGlvbiBuZWVkcyB0byB1c2UuICBTbywgd2UgZm9jdXMgb24gdGhhdCBpbiB0aGlzCisvLyB0ZXN0LiAgT3RoZXIgdGVzdHMsIHN1Y2ggYXMgZ2VuZXJpY19tZXNzYWdlX3JlZmxlY3Rpb25fdW5pdHRlc3QgYW5kCisvLyByZWZsZWN0aW9uX29wc191bml0dGVzdCwgY292ZXIgdGhlIHJlc3Qgb2YgdGhlIGZ1bmN0aW9uYWxpdHkgdXNlZCBieQorLy8gRHluYW1pY01lc3NhZ2UuCisKKyNpbmNsdWRlIDxtZW1vcnk+CisjaWZuZGVmIF9TSEFSRURfUFRSX0gKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc2hhcmVkX3B0ci5oPgorI2VuZGlmCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc2NvcGVkX3B0ci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZHluYW1pY19tZXNzYWdlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXN0X3V0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fZmllbGRfcHJlc2VuY2UucGIuaD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9sb2dnaW5nLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZ29vZ2xldGVzdC5oPgorI2luY2x1ZGUgPGd0ZXN0L2d0ZXN0Lmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworY2xhc3MgRHluYW1pY01lc3NhZ2VUZXN0IDogcHVibGljIHRlc3Rpbmc6OlRlc3QgeworIHByb3RlY3RlZDoKKyAgRGVzY3JpcHRvclBvb2wgcG9vbF87CisgIER5bmFtaWNNZXNzYWdlRmFjdG9yeSBmYWN0b3J5XzsKKyAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcl87CisgIGNvbnN0IE1lc3NhZ2UqIHByb3RvdHlwZV87CisgIGNvbnN0IERlc2NyaXB0b3IqIGV4dGVuc2lvbnNfZGVzY3JpcHRvcl87CisgIGNvbnN0IE1lc3NhZ2UqIGV4dGVuc2lvbnNfcHJvdG90eXBlXzsKKyAgY29uc3QgRGVzY3JpcHRvciogcGFja2VkX2Rlc2NyaXB0b3JfOworICBjb25zdCBNZXNzYWdlKiBwYWNrZWRfcHJvdG90eXBlXzsKKyAgY29uc3QgRGVzY3JpcHRvciogb25lb2ZfZGVzY3JpcHRvcl87CisgIGNvbnN0IE1lc3NhZ2UqIG9uZW9mX3Byb3RvdHlwZV87CisgIGNvbnN0IERlc2NyaXB0b3IqIHByb3RvM19kZXNjcmlwdG9yXzsKKyAgY29uc3QgTWVzc2FnZSogcHJvdG8zX3Byb3RvdHlwZV87CisKKyAgRHluYW1pY01lc3NhZ2VUZXN0KCk6IGZhY3RvcnlfKCZwb29sXykge30KKworICB2aXJ0dWFsIHZvaWQgU2V0VXAoKSB7CisgICAgLy8gV2Ugd2FudCB0byBtYWtlIHN1cmUgdGhhdCBEeW5hbWljTWVzc2FnZSB3b3JrcyAocGFydGljdWxhcmx5IHdpdGgKKyAgICAvLyBleHRlbnNpb25zKSBldmVuIGlmIHdlIHVzZSBkZXNjcmlwdG9ycyB0aGF0IGFyZSAqbm90KiBmcm9tIGNvbXBpbGVkLWluCisgICAgLy8gdHlwZXMsIHNvIHdlIG1ha2UgY29waWVzIG9mIHRoZSBkZXNjcmlwdG9ycyBmb3IgdW5pdHRlc3QucHJvdG8gYW5kCisgICAgLy8gdW5pdHRlc3RfaW1wb3J0LnByb3RvLgorICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gdW5pdHRlc3RfZmlsZTsKKyAgICBGaWxlRGVzY3JpcHRvclByb3RvIHVuaXR0ZXN0X2ltcG9ydF9maWxlOworICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gdW5pdHRlc3RfaW1wb3J0X3B1YmxpY19maWxlOworICAgIEZpbGVEZXNjcmlwdG9yUHJvdG8gdW5pdHRlc3Rfbm9fZmllbGRfcHJlc2VuY2VfZmlsZTsKKworICAgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OmRlc2NyaXB0b3IoKS0+ZmlsZSgpLT5Db3B5VG8oJnVuaXR0ZXN0X2ZpbGUpOworICAgIHVuaXR0ZXN0X2ltcG9ydDo6SW1wb3J0TWVzc2FnZTo6ZGVzY3JpcHRvcigpLT5maWxlKCktPkNvcHlUbygKKyAgICAgICZ1bml0dGVzdF9pbXBvcnRfZmlsZSk7CisgICAgdW5pdHRlc3RfaW1wb3J0OjpQdWJsaWNJbXBvcnRNZXNzYWdlOjpkZXNjcmlwdG9yKCktPmZpbGUoKS0+Q29weVRvKAorICAgICAgJnVuaXR0ZXN0X2ltcG9ydF9wdWJsaWNfZmlsZSk7CisgICAgcHJvdG8yX25vZmllbGRwcmVzZW5jZV91bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpkZXNjcmlwdG9yKCktPgorICAgICAgICBmaWxlKCktPkNvcHlUbygmdW5pdHRlc3Rfbm9fZmllbGRfcHJlc2VuY2VfZmlsZSk7CisKKyAgICBBU1NFUlRfVFJVRShwb29sXy5CdWlsZEZpbGUodW5pdHRlc3RfaW1wb3J0X3B1YmxpY19maWxlKSAhPSBOVUxMKTsKKyAgICBBU1NFUlRfVFJVRShwb29sXy5CdWlsZEZpbGUodW5pdHRlc3RfaW1wb3J0X2ZpbGUpICE9IE5VTEwpOworICAgIEFTU0VSVF9UUlVFKHBvb2xfLkJ1aWxkRmlsZSh1bml0dGVzdF9maWxlKSAhPSBOVUxMKTsKKyAgICBBU1NFUlRfVFJVRShwb29sXy5CdWlsZEZpbGUodW5pdHRlc3Rfbm9fZmllbGRfcHJlc2VuY2VfZmlsZSkgIT0gTlVMTCk7CisKKyAgICBkZXNjcmlwdG9yXyA9IHBvb2xfLkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgicHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIik7CisgICAgQVNTRVJUX1RSVUUoZGVzY3JpcHRvcl8gIT0gTlVMTCk7CisgICAgcHJvdG90eXBlXyA9IGZhY3RvcnlfLkdldFByb3RvdHlwZShkZXNjcmlwdG9yXyk7CisKKyAgICBleHRlbnNpb25zX2Rlc2NyaXB0b3JfID0KKyAgICAgIHBvb2xfLkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgicHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMiKTsKKyAgICBBU1NFUlRfVFJVRShleHRlbnNpb25zX2Rlc2NyaXB0b3JfICE9IE5VTEwpOworICAgIGV4dGVuc2lvbnNfcHJvdG90eXBlXyA9IGZhY3RvcnlfLkdldFByb3RvdHlwZShleHRlbnNpb25zX2Rlc2NyaXB0b3JfKTsKKworICAgIHBhY2tlZF9kZXNjcmlwdG9yXyA9CisgICAgICBwb29sXy5GaW5kTWVzc2FnZVR5cGVCeU5hbWUoInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYWNrZWRUeXBlcyIpOworICAgIEFTU0VSVF9UUlVFKHBhY2tlZF9kZXNjcmlwdG9yXyAhPSBOVUxMKTsKKyAgICBwYWNrZWRfcHJvdG90eXBlXyA9IGZhY3RvcnlfLkdldFByb3RvdHlwZShwYWNrZWRfZGVzY3JpcHRvcl8pOworCisgICAgb25lb2ZfZGVzY3JpcHRvcl8gPQorICAgICAgcG9vbF8uRmluZE1lc3NhZ2VUeXBlQnlOYW1lKCJwcm90b2J1Zl91bml0dGVzdC5UZXN0T25lb2YyIik7CisgICAgQVNTRVJUX1RSVUUob25lb2ZfZGVzY3JpcHRvcl8gIT0gTlVMTCk7CisgICAgb25lb2ZfcHJvdG90eXBlXyA9IGZhY3RvcnlfLkdldFByb3RvdHlwZShvbmVvZl9kZXNjcmlwdG9yXyk7CisKKyAgICBwcm90bzNfZGVzY3JpcHRvcl8gPQorICAgICAgcG9vbF8uRmluZE1lc3NhZ2VUeXBlQnlOYW1lKAorICAgICAgICAgICJwcm90bzJfbm9maWVsZHByZXNlbmNlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyIpOworICAgIEFTU0VSVF9UUlVFKHByb3RvM19kZXNjcmlwdG9yXyAhPSBOVUxMKTsKKyAgICBwcm90bzNfcHJvdG90eXBlXyA9IGZhY3RvcnlfLkdldFByb3RvdHlwZShwcm90bzNfZGVzY3JpcHRvcl8pOworICB9Cit9OworCitURVNUX0YoRHluYW1pY01lc3NhZ2VUZXN0LCBEZXNjcmlwdG9yKSB7CisgIC8vIENoZWNrIHRoYXQgdGhlIGRlc2NyaXB0b3Igb24gdGhlIER5bmFtaWNNZXNzYWdlIG1hdGNoZXMgdGhlIGRlc2NyaXB0b3IKKyAgLy8gcGFzc2VkIHRvIEdldFByb3RvdHlwZSgpLgorICBFWFBFQ1RfRVEocHJvdG90eXBlXy0+R2V0RGVzY3JpcHRvcigpLCBkZXNjcmlwdG9yXyk7Cit9CisKK1RFU1RfRihEeW5hbWljTWVzc2FnZVRlc3QsIE9uZVByb3RvdHlwZSkgeworICAvLyBDaGVjayB0aGF0IHJlcXVlc3RpbmcgdGhlIHNhbWUgcHJvdG90eXBlIHR3aWNlIHByb2R1Y2VzIHRoZSBzYW1lIG9iamVjdC4KKyAgRVhQRUNUX0VRKHByb3RvdHlwZV8sIGZhY3RvcnlfLkdldFByb3RvdHlwZShkZXNjcmlwdG9yXykpOworfQorCitURVNUX0YoRHluYW1pY01lc3NhZ2VUZXN0LCBEZWZhdWx0cykgeworICAvLyBDaGVjayB0aGF0IGFsbCBkZWZhdWx0IHZhbHVlcyBhcmUgc2V0IGNvcnJlY3RseSBpbiB0aGUgaW5pdGlhbCBtZXNzYWdlLgorICBUZXN0VXRpbDo6UmVmbGVjdGlvblRlc3RlciByZWZsZWN0aW9uX3Rlc3RlcihkZXNjcmlwdG9yXyk7CisgIHJlZmxlY3Rpb25fdGVzdGVyLkV4cGVjdENsZWFyVmlhUmVmbGVjdGlvbigqcHJvdG90eXBlXyk7Cit9CisKK1RFU1RfRihEeW5hbWljTWVzc2FnZVRlc3QsIEluZGVwZW5kZW50T2Zmc2V0cykgeworICAvLyBDaGVjayB0aGF0IGFsbCBmaWVsZHMgaGF2ZSBpbmRlcGVuZGVudCBvZmZzZXRzIGJ5IHNldHRpbmcgZWFjaAorICAvLyBvbmUgdG8gYSB1bmlxdWUgdmFsdWUgdGhlbiBjaGVja2luZyB0aGF0IHRoZXkgYWxsIHN0aWxsIGhhdmUgdGhvc2UKKyAgLy8gdW5pcXVlIHZhbHVlcyAoaS5lLiB0aGV5IGRvbid0IHN0b21wIGVhY2ggb3RoZXIpLgorICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPE1lc3NhZ2U+IG1lc3NhZ2UocHJvdG90eXBlXy0+TmV3KCkpOworICBUZXN0VXRpbDo6UmVmbGVjdGlvblRlc3RlciByZWZsZWN0aW9uX3Rlc3RlcihkZXNjcmlwdG9yXyk7CisKKyAgcmVmbGVjdGlvbl90ZXN0ZXIuU2V0QWxsRmllbGRzVmlhUmVmbGVjdGlvbihtZXNzYWdlLmdldCgpKTsKKyAgcmVmbGVjdGlvbl90ZXN0ZXIuRXhwZWN0QWxsRmllbGRzU2V0VmlhUmVmbGVjdGlvbigqbWVzc2FnZSk7Cit9CisKK1RFU1RfRihEeW5hbWljTWVzc2FnZVRlc3QsIEV4dGVuc2lvbnMpIHsKKyAgLy8gQ2hlY2sgdGhhdCBleHRlbnNpb25zIHdvcmsuCisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8TWVzc2FnZT4gbWVzc2FnZShleHRlbnNpb25zX3Byb3RvdHlwZV8tPk5ldygpKTsKKyAgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXIgcmVmbGVjdGlvbl90ZXN0ZXIoZXh0ZW5zaW9uc19kZXNjcmlwdG9yXyk7CisKKyAgcmVmbGVjdGlvbl90ZXN0ZXIuU2V0QWxsRmllbGRzVmlhUmVmbGVjdGlvbihtZXNzYWdlLmdldCgpKTsKKyAgcmVmbGVjdGlvbl90ZXN0ZXIuRXhwZWN0QWxsRmllbGRzU2V0VmlhUmVmbGVjdGlvbigqbWVzc2FnZSk7Cit9CisKK1RFU1RfRihEeW5hbWljTWVzc2FnZVRlc3QsIFBhY2tlZEZpZWxkcykgeworICAvLyBDaGVjayB0aGF0IHBhY2tlZCBmaWVsZHMgd29yayBwcm9wZXJseS4KKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxNZXNzYWdlPiBtZXNzYWdlKHBhY2tlZF9wcm90b3R5cGVfLT5OZXcoKSk7CisgIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyIHJlZmxlY3Rpb25fdGVzdGVyKHBhY2tlZF9kZXNjcmlwdG9yXyk7CisKKyAgcmVmbGVjdGlvbl90ZXN0ZXIuU2V0UGFja2VkRmllbGRzVmlhUmVmbGVjdGlvbihtZXNzYWdlLmdldCgpKTsKKyAgcmVmbGVjdGlvbl90ZXN0ZXIuRXhwZWN0UGFja2VkRmllbGRzU2V0VmlhUmVmbGVjdGlvbigqbWVzc2FnZSk7Cit9CisKK1RFU1RfRihEeW5hbWljTWVzc2FnZVRlc3QsIE9uZW9mKSB7CisgIC8vIENoZWNrIHRoYXQgb25lb2YgZmllbGRzIHdvcmsgcHJvcGVybHkuCisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8TWVzc2FnZT4gbWVzc2FnZShvbmVvZl9wcm90b3R5cGVfLT5OZXcoKSk7CisKKyAgLy8gQ2hlY2sgZGVmYXVsdCB2YWx1ZXMuCisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBtZXNzYWdlLT5HZXREZXNjcmlwdG9yKCk7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5HZXRJbnQzMigKKyAgICAgICptZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImZvb19pbnQiKSkpOworICBFWFBFQ1RfRVEoIiIsIHJlZmxlY3Rpb24tPkdldFN0cmluZygKKyAgICAgICptZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImZvb19zdHJpbmciKSkpOworICBFWFBFQ1RfRVEoIiIsIHJlZmxlY3Rpb24tPkdldFN0cmluZygKKyAgICAgICptZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImZvb19jb3JkIikpKTsKKyAgRVhQRUNUX0VRKCIiLCByZWZsZWN0aW9uLT5HZXRTdHJpbmcoCisgICAgICAqbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJmb29fc3RyaW5nX3BpZWNlIikpKTsKKyAgRVhQRUNUX0VRKCIiLCByZWZsZWN0aW9uLT5HZXRTdHJpbmcoCisgICAgICAqbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJmb29fYnl0ZXMiKSkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RPbmVvZjI6OkZPTywgcmVmbGVjdGlvbi0+R2V0RW51bSgKKyAgICAgICptZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImZvb19lbnVtIikpLT5udW1iZXIoKSk7CisgIGNvbnN0IERlc2NyaXB0b3IqIG5lc3RlZF9kZXNjcmlwdG9yOworICBjb25zdCBNZXNzYWdlKiBuZXN0ZWRfcHJvdG90eXBlOworICBuZXN0ZWRfZGVzY3JpcHRvciA9CisgICAgICBwb29sXy5GaW5kTWVzc2FnZVR5cGVCeU5hbWUoInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZSIpOworICBuZXN0ZWRfcHJvdG90eXBlID0gZmFjdG9yeV8uR2V0UHJvdG90eXBlKG5lc3RlZF9kZXNjcmlwdG9yKTsKKyAgRVhQRUNUX0VRKG5lc3RlZF9wcm90b3R5cGUsCisgICAgICAgICAgICAmcmVmbGVjdGlvbi0+R2V0TWVzc2FnZSgKKyAgICAgICAgICAgICAgICAqbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJmb29fbWVzc2FnZSIpKSk7CisgIGNvbnN0IERlc2NyaXB0b3IqIGZvb2dyb3VwX2Rlc2NyaXB0b3I7CisgIGNvbnN0IE1lc3NhZ2UqIGZvb2dyb3VwX3Byb3RvdHlwZTsKKyAgZm9vZ3JvdXBfZGVzY3JpcHRvciA9CisgICAgICBwb29sXy5GaW5kTWVzc2FnZVR5cGVCeU5hbWUoInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZjIuRm9vR3JvdXAiKTsKKyAgZm9vZ3JvdXBfcHJvdG90eXBlID0gZmFjdG9yeV8uR2V0UHJvdG90eXBlKGZvb2dyb3VwX2Rlc2NyaXB0b3IpOworICBFWFBFQ1RfRVEoZm9vZ3JvdXBfcHJvdG90eXBlLAorICAgICAgICAgICAgJnJlZmxlY3Rpb24tPkdldE1lc3NhZ2UoCisgICAgICAgICAgICAgICAgKm1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgiZm9vZ3JvdXAiKSkpOworICBFWFBFQ1RfTkUoZm9vZ3JvdXBfcHJvdG90eXBlLAorICAgICAgICAgICAgJnJlZmxlY3Rpb24tPkdldE1lc3NhZ2UoCisgICAgICAgICAgICAgICAgKm1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgiZm9vX2xhenlfbWVzc2FnZSIpKSk7CisgIEVYUEVDVF9FUSg1LCByZWZsZWN0aW9uLT5HZXRJbnQzMigKKyAgICAgICptZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImJhcl9pbnQiKSkpOworICBFWFBFQ1RfRVEoIlNUUklORyIsIHJlZmxlY3Rpb24tPkdldFN0cmluZygKKyAgICAgICptZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImJhcl9zdHJpbmciKSkpOworICBFWFBFQ1RfRVEoIkNPUkQiLCByZWZsZWN0aW9uLT5HZXRTdHJpbmcoCisgICAgICAqbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJiYXJfY29yZCIpKSk7CisgIEVYUEVDVF9FUSgiU1BJRUNFIiwgcmVmbGVjdGlvbi0+R2V0U3RyaW5nKAorICAgICAgKm1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgiYmFyX3N0cmluZ19waWVjZSIpKSk7CisgIEVYUEVDVF9FUSgiQllURVMiLCByZWZsZWN0aW9uLT5HZXRTdHJpbmcoCisgICAgICAqbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJiYXJfYnl0ZXMiKSkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RPbmVvZjI6OkJBUiwgcmVmbGVjdGlvbi0+R2V0RW51bSgKKyAgICAgICptZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImJhcl9lbnVtIikpLT5udW1iZXIoKSk7CisKKyAgLy8gQ2hlY2sgc2V0IGZ1bmN0aW9ucy4KKyAgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXIgcmVmbGVjdGlvbl90ZXN0ZXIob25lb2ZfZGVzY3JpcHRvcl8pOworICByZWZsZWN0aW9uX3Rlc3Rlci5TZXRPbmVvZlZpYVJlZmxlY3Rpb24obWVzc2FnZS5nZXQoKSk7CisgIHJlZmxlY3Rpb25fdGVzdGVyLkV4cGVjdE9uZW9mU2V0VmlhUmVmbGVjdGlvbigqbWVzc2FnZSk7Cit9CisKK1RFU1RfRihEeW5hbWljTWVzc2FnZVRlc3QsIFNwYWNlVXNlZCkgeworICAvLyBUZXN0IHRoYXQgU3BhY2VVc2VkKCkgd29ya3MgcHJvcGVybHkKKworICAvLyBTaW5jZSB3ZSBzaGFyZSB0aGUgaW1wbGVtZW50YXRpb24gd2l0aCBnZW5lcmF0ZWQgbWVzc2FnZXMsIHdlIGRvbid0IG5lZWQKKyAgLy8gdG8gdGVzdCB2ZXJ5IG11Y2ggaGVyZS4gIEp1c3QgbWFrZSBzdXJlIGl0IGFwcGVhcnMgdG8gYmUgd29ya2luZy4KKworICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPE1lc3NhZ2U+IG1lc3NhZ2UocHJvdG90eXBlXy0+TmV3KCkpOworICBUZXN0VXRpbDo6UmVmbGVjdGlvblRlc3RlciByZWZsZWN0aW9uX3Rlc3RlcihkZXNjcmlwdG9yXyk7CisKKyAgaW50IGluaXRpYWxfc3BhY2VfdXNlZCA9IG1lc3NhZ2UtPlNwYWNlVXNlZCgpOworCisgIHJlZmxlY3Rpb25fdGVzdGVyLlNldEFsbEZpZWxkc1ZpYVJlZmxlY3Rpb24obWVzc2FnZS5nZXQoKSk7CisgIEVYUEVDVF9MVChpbml0aWFsX3NwYWNlX3VzZWQsIG1lc3NhZ2UtPlNwYWNlVXNlZCgpKTsKK30KKworVEVTVF9GKER5bmFtaWNNZXNzYWdlVGVzdCwgQXJlbmEpIHsKKyAgQXJlbmEgYXJlbmE7CisgIE1lc3NhZ2UqIG1lc3NhZ2UgPSBwcm90b3R5cGVfLT5OZXcoJmFyZW5hKTsKKyAgKHZvaWQpbWVzc2FnZTsgIC8vIGF2b2lkIHVudXNlZC12YXJpYWJsZSBlcnJvci4KKyAgLy8gUmV0dXJuIHdpdGhvdXQgZnJlZWluZzogc2hvdWxkIG5vdCBsZWFrLgorfQorCitURVNUX0YoRHluYW1pY01lc3NhZ2VUZXN0LCBQcm90bzMpIHsKKyAgTWVzc2FnZSogbWVzc2FnZSA9IHByb3RvM19wcm90b3R5cGVfLT5OZXcoKTsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbCA9IG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKTsKKyAgY29uc3QgRGVzY3JpcHRvciogZGVzYyA9IG1lc3NhZ2UtPkdldERlc2NyaXB0b3IoKTsKKworICAvLyBKdXN0IHRlc3QgYSBzaW5nbGUgcHJpbXRpdmUgYW5kIHNpbmdsZSBtZXNzYWdlIGZpZWxkIGhlcmUgdG8gbWFrZSBzdXJlIHdlCisgIC8vIGFyZSBnZXR0aW5nIHRoZSBuby1maWVsZC1wcmVzZW5jZSBzZW1hbnRpY3MgZWxzZXdoZXJlLiBEeW5hbWljTWVzc2FnZSB1c2VzCisgIC8vIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uIHVuZGVyIHRoZSBob29kLCBzbyB0aGUgcmVzdCBzaG91bGQgYmUgZmluZSBhcworICAvLyBsb25nIGFzIEdNUiByZWNvZ25pemVzIHRoYXQgd2UncmUgdXNpbmcgYSBwcm90bzMgbWVzc2FnZS4KKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBvcHRpb25hbF9pbnQzMiA9CisgICAgICBkZXNjLT5GaW5kRmllbGRCeU5hbWUoIm9wdGlvbmFsX2ludDMyIik7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogb3B0aW9uYWxfbXNnID0KKyAgICAgIGRlc2MtPkZpbmRGaWVsZEJ5TmFtZSgib3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UiKTsKKyAgRVhQRUNUX1RSVUUob3B0aW9uYWxfaW50MzIgIT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKG9wdGlvbmFsX21zZyAhPSBOVUxMKTsKKworICBFWFBFQ1RfRVEoZmFsc2UsIHJlZmwtPkhhc0ZpZWxkKCptZXNzYWdlLCBvcHRpb25hbF9pbnQzMikpOworICByZWZsLT5TZXRJbnQzMihtZXNzYWdlLCBvcHRpb25hbF9pbnQzMiwgNDIpOworICBFWFBFQ1RfRVEodHJ1ZSwgcmVmbC0+SGFzRmllbGQoKm1lc3NhZ2UsIG9wdGlvbmFsX2ludDMyKSk7CisgIHJlZmwtPlNldEludDMyKG1lc3NhZ2UsIG9wdGlvbmFsX2ludDMyLCAwKTsKKyAgRVhQRUNUX0VRKGZhbHNlLCByZWZsLT5IYXNGaWVsZCgqbWVzc2FnZSwgb3B0aW9uYWxfaW50MzIpKTsKKworICBFWFBFQ1RfRVEoZmFsc2UsIHJlZmwtPkhhc0ZpZWxkKCptZXNzYWdlLCBvcHRpb25hbF9tc2cpKTsKKyAgcmVmbC0+TXV0YWJsZU1lc3NhZ2UobWVzc2FnZSwgb3B0aW9uYWxfbXNnKTsKKyAgRVhQRUNUX0VRKHRydWUsIHJlZmwtPkhhc0ZpZWxkKCptZXNzYWdlLCBvcHRpb25hbF9tc2cpKTsKKyAgZGVsZXRlIHJlZmwtPlJlbGVhc2VNZXNzYWdlKG1lc3NhZ2UsIG9wdGlvbmFsX21zZyk7CisgIEVYUEVDVF9FUShmYWxzZSwgcmVmbC0+SGFzRmllbGQoKm1lc3NhZ2UsIG9wdGlvbmFsX21zZykpOworCisgIC8vIEFsc28gZW5zdXJlIHRoYXQgdGhlIGRlZmF1bHQgaW5zdGFuY2UgaGFuZGxlcyBmaWVsZCBwcmVzZW5jZSBwcm9wZXJseS4KKyAgRVhQRUNUX0VRKGZhbHNlLCByZWZsLT5IYXNGaWVsZCgqcHJvdG8zX3Byb3RvdHlwZV8sIG9wdGlvbmFsX21zZykpOworCisgIGRlbGV0ZSBtZXNzYWdlOworfQorCisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9lbXB0eS5wYi5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvZW1wdHkucGIuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjJlZWM3OAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvZW1wdHkucGIuY2MKQEAgLTAsMCArMSwzMTAgQEAKKy8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCisvLyBzb3VyY2U6IGdvb2dsZS9wcm90b2J1Zi9lbXB0eS5wcm90bworCisjZGVmaW5lIElOVEVSTkFMX1NVUFBSRVNTX1BST1RPQlVGX0ZJRUxEX0RFUFJFQ0FUSU9OCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2VtcHR5LnBiLmg+CisKKyNpbmNsdWRlIDxhbGdvcml0aG0+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3BvcnQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvb25jZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZV9pbmwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfbWVzc2FnZV9yZWZsZWN0aW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3JlZmxlY3Rpb25fb3BzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0Lmg+CisvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW5jbHVkZXMpCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworbmFtZXNwYWNlIHsKKworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBFbXB0eV9kZXNjcmlwdG9yXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbioKKyAgRW1wdHlfcmVmbGVjdGlvbl8gPSBOVUxMOworCit9ICAvLyBuYW1lc3BhY2UKKworCit2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZlbXB0eV8yZXByb3RvKCkgeworICBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZW1wdHlfMmVwcm90bygpOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVEZXNjcmlwdG9yKiBmaWxlID0KKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQb29sOjpnZW5lcmF0ZWRfcG9vbCgpLT5GaW5kRmlsZUJ5TmFtZSgKKyAgICAgICJnb29nbGUvcHJvdG9idWYvZW1wdHkucHJvdG8iKTsKKyAgR09PR0xFX0NIRUNLKGZpbGUgIT0gTlVMTCk7CisgIEVtcHR5X2Rlc2NyaXB0b3JfID0gZmlsZS0+bWVzc2FnZV90eXBlKDApOworICBzdGF0aWMgY29uc3QgaW50IEVtcHR5X29mZnNldHNfWzFdID0geworICB9OworICBFbXB0eV9yZWZsZWN0aW9uXyA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok5ld0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKAorICAgICAgRW1wdHlfZGVzY3JpcHRvcl8sCisgICAgICBFbXB0eTo6ZGVmYXVsdF9pbnN0YW5jZV8sCisgICAgICBFbXB0eV9vZmZzZXRzXywKKyAgICAgIC0xLAorICAgICAgLTEsCisgICAgICAtMSwKKyAgICAgIHNpemVvZihFbXB0eSksCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEVtcHR5LCBfaW50ZXJuYWxfbWV0YWRhdGFfKSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRW1wdHksIF9pc19kZWZhdWx0X2luc3RhbmNlXykpOworfQorCituYW1lc3BhY2UgeworCitHT09HTEVfUFJPVE9CVUZfREVDTEFSRV9PTkNFKHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzX29uY2VfKTsKK2lubGluZSB2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpIHsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpHb29nbGVPbmNlSW5pdCgmcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNfb25jZV8sCisgICAgICAgICAgICAgICAgICZwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZW1wdHlfMmVwcm90byk7Cit9CisKK3ZvaWQgcHJvdG9idWZfUmVnaXN0ZXJUeXBlcyhjb25zdCA6OnN0ZDo6c3RyaW5nJikgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZE1lc3NhZ2UoCisgICAgICBFbXB0eV9kZXNjcmlwdG9yXywgJkVtcHR5OjpkZWZhdWx0X2luc3RhbmNlKCkpOworfQorCit9ICAvLyBuYW1lc3BhY2UKKwordm9pZCBwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZlbXB0eV8yZXByb3RvKCkgeworICBkZWxldGUgRW1wdHk6OmRlZmF1bHRfaW5zdGFuY2VfOworICBkZWxldGUgRW1wdHlfcmVmbGVjdGlvbl87Cit9CisKK3ZvaWQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmVtcHR5XzJlcHJvdG8oKSB7CisgIHN0YXRpYyBib29sIGFscmVhZHlfaGVyZSA9IGZhbHNlOworICBpZiAoYWxyZWFkeV9oZXJlKSByZXR1cm47CisgIGFscmVhZHlfaGVyZSA9IHRydWU7CisgIEdPT0dMRV9QUk9UT0JVRl9WRVJJRllfVkVSU0lPTjsKKworICA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQb29sOjpJbnRlcm5hbEFkZEdlbmVyYXRlZEZpbGUoCisgICAgIlxuXDAzM2dvb2dsZS9wcm90b2J1Zi9lbXB0eS5wcm90b1wwMjJcMDE3Z29vZ2xlLnByIgorICAgICJvdG9idWZcIlwwMDdcblwwMDVFbXB0eUJQXG5cMDIzY29tLmdvb2dsZS5wcm90b2J1ZkJcbiIKKyAgICAiRW1wdHlQcm90b1BcMDAxXDI0MFwwMDFcMDAxXDM3MFwwMDFcMDAxXDI0MlwwMDJcMDAzR1BCXDI1MlwwMDJcMDM2R29vZ2xlLlByb3RvYiIKKyAgICAidWYuV2VsbEtub3duVHlwZXNiXDAwNnByb3RvMyIsIDE0NSk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZUZhY3Rvcnk6OkludGVybmFsUmVnaXN0ZXJHZW5lcmF0ZWRGaWxlKAorICAgICJnb29nbGUvcHJvdG9idWYvZW1wdHkucHJvdG8iLCAmcHJvdG9idWZfUmVnaXN0ZXJUeXBlcyk7CisgIEVtcHR5OjpkZWZhdWx0X2luc3RhbmNlXyA9IG5ldyBFbXB0eSgpOworICBFbXB0eTo6ZGVmYXVsdF9pbnN0YW5jZV8tPkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpPblNodXRkb3duKCZwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZlbXB0eV8yZXByb3RvKTsKK30KKworLy8gRm9yY2UgQWRkRGVzY3JpcHRvcnMoKSB0byBiZSBjYWxsZWQgYXQgc3RhdGljIGluaXRpYWxpemF0aW9uIHRpbWUuCitzdHJ1Y3QgU3RhdGljRGVzY3JpcHRvckluaXRpYWxpemVyX2dvb2dsZV8yZnByb3RvYnVmXzJmZW1wdHlfMmVwcm90byB7CisgIFN0YXRpY0Rlc2NyaXB0b3JJbml0aWFsaXplcl9nb29nbGVfMmZwcm90b2J1Zl8yZmVtcHR5XzJlcHJvdG8oKSB7CisgICAgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmVtcHR5XzJlcHJvdG8oKTsKKyAgfQorfSBzdGF0aWNfZGVzY3JpcHRvcl9pbml0aWFsaXplcl9nb29nbGVfMmZwcm90b2J1Zl8yZmVtcHR5XzJlcHJvdG9fOworCituYW1lc3BhY2UgeworCitzdGF0aWMgdm9pZCBNZXJnZUZyb21GYWlsKGludCBsaW5lKSBHT09HTEVfQVRUUklCVVRFX0NPTEQ7CitzdGF0aWMgdm9pZCBNZXJnZUZyb21GYWlsKGludCBsaW5lKSB7CisgIEdPT0dMRV9DSEVDSyhmYWxzZSkgPDwgX19GSUxFX18gPDwgIjoiIDw8IGxpbmU7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworI2lmICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCisjZW5kaWYgIC8vICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCisKK0VtcHR5OjpFbXB0eSgpCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgeworICBTaGFyZWRDdG9yKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuRW1wdHkpCit9CisKK0VtcHR5OjpFbXB0eSg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwKKyAgX2ludGVybmFsX21ldGFkYXRhXyhhcmVuYSkgeworICBTaGFyZWRDdG9yKCk7CisgIFJlZ2lzdGVyQXJlbmFEdG9yKGFyZW5hKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGFyZW5hX2NvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5FbXB0eSkKK30KKwordm9pZCBFbXB0eTo6SW5pdEFzRGVmYXVsdEluc3RhbmNlKCkgeworICBfaXNfZGVmYXVsdF9pbnN0YW5jZV8gPSB0cnVlOworfQorCitFbXB0eTo6RW1wdHkoY29uc3QgRW1wdHkmIGZyb20pCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksCisgICAgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29weV9jb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuRW1wdHkpCit9CisKK3ZvaWQgRW1wdHk6OlNoYXJlZEN0b3IoKSB7CisgICAgX2lzX2RlZmF1bHRfaW5zdGFuY2VfID0gZmFsc2U7CisgIF9jYWNoZWRfc2l6ZV8gPSAwOworfQorCitFbXB0eTo6fkVtcHR5KCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZGVzdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuRW1wdHkpCisgIFNoYXJlZER0b3IoKTsKK30KKwordm9pZCBFbXB0eTo6U2hhcmVkRHRvcigpIHsKKyAgaWYgKEdldEFyZW5hTm9WaXJ0dWFsKCkgIT0gTlVMTCkgeworICAgIHJldHVybjsKKyAgfQorCisgIGlmICh0aGlzICE9IGRlZmF1bHRfaW5zdGFuY2VfKSB7CisgIH0KK30KKwordm9pZCBFbXB0eTo6QXJlbmFEdG9yKHZvaWQqIG9iamVjdCkgeworICBFbXB0eSogX3RoaXMgPSByZWludGVycHJldF9jYXN0PCBFbXB0eSogPihvYmplY3QpOworICAodm9pZClfdGhpczsKK30KK3ZvaWQgRW1wdHk6OlJlZ2lzdGVyQXJlbmFEdG9yKDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSB7Cit9Cit2b2lkIEVtcHR5OjpTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdCB7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSBzaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogRW1wdHk6OmRlc2NyaXB0b3IoKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICByZXR1cm4gRW1wdHlfZGVzY3JpcHRvcl87Cit9CisKK2NvbnN0IEVtcHR5JiBFbXB0eTo6ZGVmYXVsdF9pbnN0YW5jZSgpIHsKKyAgaWYgKGRlZmF1bHRfaW5zdGFuY2VfID09IE5VTEwpIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZlbXB0eV8yZXByb3RvKCk7CisgIHJldHVybiAqZGVmYXVsdF9pbnN0YW5jZV87Cit9CisKK0VtcHR5KiBFbXB0eTo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBOVUxMOworCitFbXB0eSogRW1wdHk6Ok5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3QgeworICByZXR1cm4gOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYTo6Q3JlYXRlTWVzc2FnZTxFbXB0eT4oYXJlbmEpOworfQorCit2b2lkIEVtcHR5OjpDbGVhcigpIHsKK30KKworYm9vbCBFbXB0eTo6TWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KSB7CisjZGVmaW5lIERPXyhFWFBSRVNTSU9OKSBpZiAoIShFWFBSRVNTSU9OKSkgZ290byBmYWlsdXJlCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIHRhZzsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5FbXB0eSkKKyAgZm9yICg7OykgeworICAgIDo6c3RkOjpwYWlyPCA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiwgYm9vbD4gcCA9IGlucHV0LT5SZWFkVGFnV2l0aEN1dG9mZigxMjcpOworICAgIHRhZyA9IHAuZmlyc3Q7CisgICAgaWYgKCFwLnNlY29uZCkgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgaGFuZGxlX3VudXN1YWw6CisgICAgaWYgKHRhZyA9PSAwIHx8CisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdXaXJlVHlwZSh0YWcpID09CisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVApIHsKKyAgICAgIGdvdG8gc3VjY2VzczsKKyAgICB9CisgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTa2lwRmllbGQoaW5wdXQsIHRhZykpOworICB9CitzdWNjZXNzOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3VjY2Vzczpnb29nbGUucHJvdG9idWYuRW1wdHkpCisgIHJldHVybiB0cnVlOworZmFpbHVyZToKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX2ZhaWx1cmU6Z29vZ2xlLnByb3RvYnVmLkVtcHR5KQorICByZXR1cm4gZmFsc2U7CisjdW5kZWYgRE9fCit9CisKK3ZvaWQgRW1wdHk6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkVtcHR5KQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX2VuZDpnb29nbGUucHJvdG9idWYuRW1wdHkpCit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIEVtcHR5OjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIHRhcmdldCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5FbXB0eSkKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9lbmQ6Z29vZ2xlLnByb3RvYnVmLkVtcHR5KQorICByZXR1cm4gdGFyZ2V0OworfQorCitpbnQgRW1wdHk6OkJ5dGVTaXplKCkgY29uc3QgeworICBpbnQgdG90YWxfc2l6ZSA9IDA7CisKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHRvdGFsX3NpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworICByZXR1cm4gdG90YWxfc2l6ZTsKK30KKwordm9pZCBFbXB0eTo6TWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBjb25zdCBFbXB0eSogc291cmNlID0gCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpEeW5hbWljQ2FzdFRvR2VuZXJhdGVkPGNvbnN0IEVtcHR5PigKKyAgICAgICAgICAmZnJvbSk7CisgIGlmIChzb3VyY2UgPT0gTlVMTCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlJlZmxlY3Rpb25PcHM6Ok1lcmdlKGZyb20sIHRoaXMpOworICB9IGVsc2UgeworICAgIE1lcmdlRnJvbSgqc291cmNlKTsKKyAgfQorfQorCit2b2lkIEVtcHR5OjpNZXJnZUZyb20oY29uc3QgRW1wdHkmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKK30KKwordm9pZCBFbXB0eTo6Q29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKwordm9pZCBFbXB0eTo6Q29weUZyb20oY29uc3QgRW1wdHkmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCitib29sIEVtcHR5OjpJc0luaXRpYWxpemVkKCkgY29uc3QgeworCisgIHJldHVybiB0cnVlOworfQorCit2b2lkIEVtcHR5OjpTd2FwKEVtcHR5KiBvdGhlcikgeworICBpZiAob3RoZXIgPT0gdGhpcykgcmV0dXJuOworICBpZiAoR2V0QXJlbmFOb1ZpcnR1YWwoKSA9PSBvdGhlci0+R2V0QXJlbmFOb1ZpcnR1YWwoKSkgeworICAgIEludGVybmFsU3dhcChvdGhlcik7CisgIH0gZWxzZSB7CisgICAgRW1wdHkgdGVtcDsKKyAgICB0ZW1wLk1lcmdlRnJvbSgqdGhpcyk7CisgICAgQ29weUZyb20oKm90aGVyKTsKKyAgICBvdGhlci0+Q29weUZyb20odGVtcCk7CisgIH0KK30KK3ZvaWQgRW1wdHk6OlVuc2FmZUFyZW5hU3dhcChFbXB0eSogb3RoZXIpIHsKKyAgaWYgKG90aGVyID09IHRoaXMpIHJldHVybjsKKyAgR09PR0xFX0RDSEVDSyhHZXRBcmVuYU5vVmlydHVhbCgpID09IG90aGVyLT5HZXRBcmVuYU5vVmlydHVhbCgpKTsKKyAgSW50ZXJuYWxTd2FwKG90aGVyKTsKK30KK3ZvaWQgRW1wdHk6OkludGVybmFsU3dhcChFbXB0eSogb3RoZXIpIHsKKyAgX2ludGVybmFsX21ldGFkYXRhXy5Td2FwKCZvdGhlci0+X2ludGVybmFsX21ldGFkYXRhXyk7CisgIHN0ZDo6c3dhcChfY2FjaGVkX3NpemVfLCBvdGhlci0+X2NhY2hlZF9zaXplXyk7Cit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgRW1wdHk6OkdldE1ldGFkYXRhKCkgY29uc3QgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBtZXRhZGF0YTsKKyAgbWV0YWRhdGEuZGVzY3JpcHRvciA9IEVtcHR5X2Rlc2NyaXB0b3JfOworICBtZXRhZGF0YS5yZWZsZWN0aW9uID0gRW1wdHlfcmVmbGVjdGlvbl87CisgIHJldHVybiBtZXRhZGF0YTsKK30KKworI2lmIFBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworLy8gRW1wdHkKKworI2VuZGlmICAvLyBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKworLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG5hbWVzcGFjZV9zY29wZSkKKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKy8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChnbG9iYWxfc2NvcGUpCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2VtcHR5LnBiLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2VtcHR5LnBiLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODY4MDA5ZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvZW1wdHkucGIuaApAQCAtMCwwICsxLDE0MyBAQAorLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCEKKy8vIHNvdXJjZTogZ29vZ2xlL3Byb3RvYnVmL2VtcHR5LnByb3RvCisKKyNpZm5kZWYgUFJPVE9CVUZfZ29vZ2xlXzJmcHJvdG9idWZfMmZlbXB0eV8yZXByb3RvX19JTkNMVURFRAorI2RlZmluZSBQUk9UT0JVRl9nb29nbGVfMmZwcm90b2J1Zl8yZmVtcHR5XzJlcHJvdG9fX0lOQ0xVREVECisKKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisKKyNpZiBHT09HTEVfUFJPVE9CVUZfVkVSU0lPTiA8IDMwMDAwMDAKKyNlcnJvciBUaGlzIGZpbGUgd2FzIGdlbmVyYXRlZCBieSBhIG5ld2VyIHZlcnNpb24gb2YgcHJvdG9jIHdoaWNoIGlzCisjZXJyb3IgaW5jb21wYXRpYmxlIHdpdGggeW91ciBQcm90b2NvbCBCdWZmZXIgaGVhZGVycy4gIFBsZWFzZSB1cGRhdGUKKyNlcnJvciB5b3VyIGhlYWRlcnMuCisjZW5kaWYKKyNpZiAzMDAwMDAwIDwgR09PR0xFX1BST1RPQlVGX01JTl9QUk9UT0NfVkVSU0lPTgorI2Vycm9yIFRoaXMgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IGFuIG9sZGVyIHZlcnNpb24gb2YgcHJvdG9jIHdoaWNoIGlzCisjZXJyb3IgaW5jb21wYXRpYmxlIHdpdGggeW91ciBQcm90b2NvbCBCdWZmZXIgaGVhZGVycy4gIFBsZWFzZQorI2Vycm9yIHJlZ2VuZXJhdGUgdGhpcyBmaWxlIHdpdGggYSBuZXdlciB2ZXJzaW9uIG9mIHByb3RvYy4KKyNlbmRpZgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2FyZW5hLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2FyZW5hc3RyaW5nLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9tZXNzYWdlX3V0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWV0YWRhdGEuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWVzc2FnZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9yZXBlYXRlZF9maWVsZC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9leHRlbnNpb25fc2V0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Vua25vd25fZmllbGRfc2V0Lmg+CisvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW5jbHVkZXMpCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworLy8gSW50ZXJuYWwgaW1wbGVtZW50YXRpb24gZGV0YWlsIC0tIGRvIG5vdCBjYWxsIHRoZXNlLgordm9pZCBMSUJQUk9UT0JVRl9FWFBPUlQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmVtcHR5XzJlcHJvdG8oKTsKK3ZvaWQgcHJvdG9idWZfQXNzaWduRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmVtcHR5XzJlcHJvdG8oKTsKK3ZvaWQgcHJvdG9idWZfU2h1dGRvd25GaWxlX2dvb2dsZV8yZnByb3RvYnVmXzJmZW1wdHlfMmVwcm90bygpOworCitjbGFzcyBFbXB0eTsKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgRW1wdHkgOiBwdWJsaWMgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlIHsKKyBwdWJsaWM6CisgIEVtcHR5KCk7CisgIHZpcnR1YWwgfkVtcHR5KCk7CisKKyAgRW1wdHkoY29uc3QgRW1wdHkmIGZyb20pOworCisgIGlubGluZSBFbXB0eSYgb3BlcmF0b3I9KGNvbnN0IEVtcHR5JiBmcm9tKSB7CisgICAgQ29weUZyb20oZnJvbSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hKCkgY29uc3QgeyByZXR1cm4gR2V0QXJlbmFOb1ZpcnR1YWwoKTsgfQorICBpbmxpbmUgdm9pZCogR2V0TWF5YmVBcmVuYVBvaW50ZXIoKSBjb25zdCB7CisgICAgcmV0dXJuIE1heWJlQXJlbmFQdHIoKTsKKyAgfQorICBzdGF0aWMgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKCk7CisgIHN0YXRpYyBjb25zdCBFbXB0eSYgZGVmYXVsdF9pbnN0YW5jZSgpOworCisgIHZvaWQgVW5zYWZlQXJlbmFTd2FwKEVtcHR5KiBvdGhlcik7CisgIHZvaWQgU3dhcChFbXB0eSogb3RoZXIpOworCisgIC8vIGltcGxlbWVudHMgTWVzc2FnZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgaW5saW5lIEVtcHR5KiBOZXcoKSBjb25zdCB7IHJldHVybiBOZXcoTlVMTCk7IH0KKworICBFbXB0eSogTmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdDsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIENvcHlGcm9tKGNvbnN0IEVtcHR5JiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgRW1wdHkmIGZyb20pOworICB2b2lkIENsZWFyKCk7CisgIGJvb2wgSXNJbml0aWFsaXplZCgpIGNvbnN0OworCisgIGludCBCeXRlU2l6ZSgpIGNvbnN0OworICBib29sIE1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KTsKKyAgdm9pZCBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSg6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBvdXRwdXQpIGNvbnN0OworICBpbnQgR2V0Q2FjaGVkU2l6ZSgpIGNvbnN0IHsgcmV0dXJuIF9jYWNoZWRfc2l6ZV87IH0KKyAgcHJpdmF0ZToKKyAgdm9pZCBTaGFyZWRDdG9yKCk7CisgIHZvaWQgU2hhcmVkRHRvcigpOworICB2b2lkIFNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0OworICB2b2lkIEludGVybmFsU3dhcChFbXB0eSogb3RoZXIpOworICBwcm90ZWN0ZWQ6CisgIGV4cGxpY2l0IEVtcHR5KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKTsKKyAgcHJpdmF0ZToKKyAgc3RhdGljIHZvaWQgQXJlbmFEdG9yKHZvaWQqIG9iamVjdCk7CisgIGlubGluZSB2b2lkIFJlZ2lzdGVyQXJlbmFEdG9yKDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKTsKKyAgcHJpdmF0ZToKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hTm9WaXJ0dWFsKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLmFyZW5hKCk7CisgIH0KKyAgaW5saW5lIHZvaWQqIE1heWJlQXJlbmFQdHIoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ucmF3X2FyZW5hX3B0cigpOworICB9CisgIHB1YmxpYzoKKworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEdldE1ldGFkYXRhKCkgY29uc3Q7CisKKyAgLy8gbmVzdGVkIHR5cGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBhY2Nlc3NvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpnb29nbGUucHJvdG9idWYuRW1wdHkpCisgcHJpdmF0ZToKKworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpJbnRlcm5hbE1ldGFkYXRhV2l0aEFyZW5hIF9pbnRlcm5hbF9tZXRhZGF0YV87CisgIGZyaWVuZCBjbGFzcyA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hOworICB0eXBlZGVmIHZvaWQgSW50ZXJuYWxBcmVuYUNvbnN0cnVjdGFibGVfOworICB0eXBlZGVmIHZvaWQgRGVzdHJ1Y3RvclNraXBwYWJsZV87CisgIGJvb2wgX2lzX2RlZmF1bHRfaW5zdGFuY2VfOworICBtdXRhYmxlIGludCBfY2FjaGVkX3NpemVfOworICBmcmllbmQgdm9pZCBMSUJQUk9UT0JVRl9FWFBPUlQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmVtcHR5XzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfQXNzaWduRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmVtcHR5XzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfU2h1dGRvd25GaWxlX2dvb2dsZV8yZnByb3RvYnVmXzJmZW1wdHlfMmVwcm90bygpOworCisgIHZvaWQgSW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIHN0YXRpYyBFbXB0eSogZGVmYXVsdF9pbnN0YW5jZV87Cit9OworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworI2lmICFQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKy8vIEVtcHR5CisKKyNlbmRpZiAgLy8gIVBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworCisvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobmFtZXNwYWNlX3Njb3BlKQorCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGdsb2JhbF9zY29wZSkKKworI2VuZGlmICAvLyBQUk9UT0JVRl9nb29nbGVfMmZwcm90b2J1Zl8yZmVtcHR5XzJlcHJvdG9fX0lOQ0xVREVECmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2VtcHR5LnByb3RvIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9lbXB0eS5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iOTZkYWYyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9lbXB0eS5wcm90bwpAQCAtMCwwICsxLDUyIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworc3ludGF4ID0gInByb3RvMyI7CisKK3BhY2thZ2UgZ29vZ2xlLnByb3RvYnVmOworCitvcHRpb24gY3NoYXJwX25hbWVzcGFjZSA9ICJHb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlwZXMiOworb3B0aW9uIGphdmFfcGFja2FnZSA9ICJjb20uZ29vZ2xlLnByb3RvYnVmIjsKK29wdGlvbiBqYXZhX291dGVyX2NsYXNzbmFtZSA9ICJFbXB0eVByb3RvIjsKK29wdGlvbiBqYXZhX211bHRpcGxlX2ZpbGVzID0gdHJ1ZTsKK29wdGlvbiBqYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaCA9IHRydWU7CitvcHRpb24gb2JqY19jbGFzc19wcmVmaXggPSAiR1BCIjsKK29wdGlvbiBjY19lbmFibGVfYXJlbmFzID0gdHJ1ZTsKKworLy8gQSBnZW5lcmljIGVtcHR5IG1lc3NhZ2UgdGhhdCB5b3UgY2FuIHJlLXVzZSB0byBhdm9pZCBkZWZpbmluZyBkdXBsaWNhdGVkCisvLyBlbXB0eSBtZXNzYWdlcyBpbiB5b3VyIEFQSXMuIEEgdHlwaWNhbCBleGFtcGxlIGlzIHRvIHVzZSBpdCBhcyB0aGUgcmVxdWVzdAorLy8gb3IgdGhlIHJlc3BvbnNlIHR5cGUgb2YgYW4gQVBJIG1ldGhvZC4gRm9yIGluc3RhbmNlOgorLy8KKy8vICAgICBzZXJ2aWNlIEZvbyB7CisvLyAgICAgICBycGMgQmFyKGdvb2dsZS5wcm90b2J1Zi5FbXB0eSkgcmV0dXJucyAoZ29vZ2xlLnByb3RvYnVmLkVtcHR5KTsKKy8vICAgICB9CisvLworLy8gVGhlIEpTT04gcmVwcmVzZW50YXRpb24gZm9yIGBFbXB0eWAgaXMgZW1wdHkgSlNPTiBvYmplY3QgYHt9YC4KK21lc3NhZ2UgRW1wdHkge30KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvZXh0ZW5zaW9uX3NldC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvZXh0ZW5zaW9uX3NldC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45YWZiMjM2Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9leHRlbnNpb25fc2V0LmNjCkBAIC0wLDAgKzEsMTgxNSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2hhc2guaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL29uY2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZXh0ZW5zaW9uX3NldC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tZXNzYWdlX2xpdGUuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0X2xpdGVfaW5sLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3JlcGVhdGVkX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL21hcF91dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKK25hbWVzcGFjZSB7CisKK2lubGluZSBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIHJlYWxfdHlwZShGaWVsZFR5cGUgdHlwZSkgeworICBHT09HTEVfRENIRUNLKHR5cGUgPiAwICYmIHR5cGUgPD0gV2lyZUZvcm1hdExpdGU6Ok1BWF9GSUVMRF9UWVBFKTsKKyAgcmV0dXJuIHN0YXRpY19jYXN0PFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGU+KHR5cGUpOworfQorCitpbmxpbmUgV2lyZUZvcm1hdExpdGU6OkNwcFR5cGUgY3BwX3R5cGUoRmllbGRUeXBlIHR5cGUpIHsKKyAgcmV0dXJuIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGVUb0NwcFR5cGUocmVhbF90eXBlKHR5cGUpKTsKK30KKworaW5saW5lIGJvb2wgaXNfcGFja2FibGUoV2lyZUZvcm1hdExpdGU6OldpcmVUeXBlIHR5cGUpIHsKKyAgc3dpdGNoICh0eXBlKSB7CisgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfVkFSSU5UOgorICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0ZJWEVENjQ6CisgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRklYRUQzMjoKKyAgICAgIHJldHVybiB0cnVlOworICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQ6CisgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfU1RBUlRfR1JPVVA6CisgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRU5EX0dST1VQOgorICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgLy8gRG8gbm90IGFkZCBhIGRlZmF1bHQgc3RhdGVtZW50LiBMZXQgdGhlIGNvbXBpbGVyIGNvbXBsYWluIHdoZW4gc29tZW9uZQorICAgIC8vIGFkZHMgYSBuZXcgd2lyZSB0eXBlLgorICB9CisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJjYW4ndCByZWFjaCBoZXJlLiI7CisgIHJldHVybiBmYWxzZTsKK30KKworLy8gUmVnaXN0cnkgc3R1ZmYuCit0eXBlZGVmIGhhc2hfbWFwPHBhaXI8Y29uc3QgTWVzc2FnZUxpdGUqLCBpbnQ+LAorICAgICAgICAgICAgICAgICBFeHRlbnNpb25JbmZvPiBFeHRlbnNpb25SZWdpc3RyeTsKK0V4dGVuc2lvblJlZ2lzdHJ5KiByZWdpc3RyeV8gPSBOVUxMOworR09PR0xFX1BST1RPQlVGX0RFQ0xBUkVfT05DRShyZWdpc3RyeV9pbml0Xyk7CisKK3ZvaWQgRGVsZXRlUmVnaXN0cnkoKSB7CisgIGRlbGV0ZSByZWdpc3RyeV87CisgIHJlZ2lzdHJ5XyA9IE5VTEw7Cit9CisKK3ZvaWQgSW5pdFJlZ2lzdHJ5KCkgeworICByZWdpc3RyeV8gPSBuZXcgRXh0ZW5zaW9uUmVnaXN0cnk7CisgIE9uU2h1dGRvd24oJkRlbGV0ZVJlZ2lzdHJ5KTsKK30KKworLy8gVGhpcyBmdW5jdGlvbiBpcyBvbmx5IGNhbGxlZCBhdCBzdGFydHVwLCBzbyB0aGVyZSBpcyBubyBuZWVkIGZvciB0aHJlYWQtCisvLyBzYWZldHkuCit2b2lkIFJlZ2lzdGVyKGNvbnN0IE1lc3NhZ2VMaXRlKiBjb250YWluaW5nX3R5cGUsCisgICAgICAgICAgICAgIGludCBudW1iZXIsIEV4dGVuc2lvbkluZm8gaW5mbykgeworICA6Omdvb2dsZTo6cHJvdG9idWY6Okdvb2dsZU9uY2VJbml0KCZyZWdpc3RyeV9pbml0XywgJkluaXRSZWdpc3RyeSk7CisKKyAgaWYgKCFJbnNlcnRJZk5vdFByZXNlbnQocmVnaXN0cnlfLCBzdGQ6Om1ha2VfcGFpcihjb250YWluaW5nX3R5cGUsIG51bWJlciksCisgICAgICAgICAgICAgICAgICAgICAgICAgIGluZm8pKSB7CisgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIk11bHRpcGxlIGV4dGVuc2lvbiByZWdpc3RyYXRpb25zIGZvciB0eXBlIFwiIgorICAgICAgICAgICAgICAgPDwgY29udGFpbmluZ190eXBlLT5HZXRUeXBlTmFtZSgpCisgICAgICAgICAgICAgICA8PCAiXCIsIGZpZWxkIG51bWJlciAiIDw8IG51bWJlciA8PCAiLiI7CisgIH0KK30KKworY29uc3QgRXh0ZW5zaW9uSW5mbyogRmluZFJlZ2lzdGVyZWRFeHRlbnNpb24oCisgICAgY29uc3QgTWVzc2FnZUxpdGUqIGNvbnRhaW5pbmdfdHlwZSwgaW50IG51bWJlcikgeworICByZXR1cm4gKHJlZ2lzdHJ5XyA9PSBOVUxMKQorICAgICAgICAgICAgID8gTlVMTAorICAgICAgICAgICAgIDogRmluZE9yTnVsbCgqcmVnaXN0cnlfLCBzdGQ6Om1ha2VfcGFpcihjb250YWluaW5nX3R5cGUsIG51bWJlcikpOworfQorCit9ICAvLyBuYW1lc3BhY2UKKworRXh0ZW5zaW9uRmluZGVyOjp+RXh0ZW5zaW9uRmluZGVyKCkge30KKworYm9vbCBHZW5lcmF0ZWRFeHRlbnNpb25GaW5kZXI6OkZpbmQoaW50IG51bWJlciwgRXh0ZW5zaW9uSW5mbyogb3V0cHV0KSB7CisgIGNvbnN0IEV4dGVuc2lvbkluZm8qIGV4dGVuc2lvbiA9CisgICAgICBGaW5kUmVnaXN0ZXJlZEV4dGVuc2lvbihjb250YWluaW5nX3R5cGVfLCBudW1iZXIpOworICBpZiAoZXh0ZW5zaW9uID09IE5VTEwpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0gZWxzZSB7CisgICAgKm91dHB1dCA9ICpleHRlbnNpb247CisgICAgcmV0dXJuIHRydWU7CisgIH0KK30KKwordm9pZCBFeHRlbnNpb25TZXQ6OlJlZ2lzdGVyRXh0ZW5zaW9uKGNvbnN0IE1lc3NhZ2VMaXRlKiBjb250YWluaW5nX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG51bWJlciwgRmllbGRUeXBlIHR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc19yZXBlYXRlZCwgYm9vbCBpc19wYWNrZWQpIHsKKyAgR09PR0xFX0NIRUNLX05FKHR5cGUsIFdpcmVGb3JtYXRMaXRlOjpUWVBFX0VOVU0pOworICBHT09HTEVfQ0hFQ0tfTkUodHlwZSwgV2lyZUZvcm1hdExpdGU6OlRZUEVfTUVTU0FHRSk7CisgIEdPT0dMRV9DSEVDS19ORSh0eXBlLCBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9HUk9VUCk7CisgIEV4dGVuc2lvbkluZm8gaW5mbyh0eXBlLCBpc19yZXBlYXRlZCwgaXNfcGFja2VkKTsKKyAgUmVnaXN0ZXIoY29udGFpbmluZ190eXBlLCBudW1iZXIsIGluZm8pOworfQorCitzdGF0aWMgYm9vbCBDYWxsTm9BcmdWYWxpZGl0eUZ1bmMoY29uc3Qgdm9pZCogYXJnLCBpbnQgbnVtYmVyKSB7CisgIC8vIE5vdGU6ICBNdXN0IHVzZSBDLXN0eWxlIGNhc3QgaGVyZSByYXRoZXIgdGhhbiByZWludGVycHJldF9jYXN0IGJlY2F1c2UKKyAgLy8gICB0aGUgQysrIHN0YW5kYXJkIGF0IG9uZSBwb2ludCBkaWQgbm90IGFsbG93IGNhc3RzIGJldHdlZW4gZnVuY3Rpb24gYW5kCisgIC8vICAgZGF0YSBwb2ludGVycyBhbmQgc29tZSBjb21waWxlcnMgZW5mb3JjZSB0aGlzIGZvciBDKystc3R5bGUgY2FzdHMuICBObworICAvLyAgIGNvbXBpbGVyIGVuZm9yY2VzIGl0IGZvciBDLXN0eWxlIGNhc3RzIHNpbmNlIGxvdHMgb2YgQy1zdHlsZSBjb2RlIGhhcworICAvLyAgIHJlbGllZCBvbiB0aGVzZSBraW5kcyBvZiBjYXN0cyBmb3IgYSBsb25nIHRpbWUsIGRlc3BpdGUgYmVpbmcKKyAgLy8gICB0ZWNobmljYWxseSB1bmRlZmluZWQuICBTZWU6CisgIC8vICAgICBodHRwOi8vd3d3Lm9wZW4tc3RkLm9yZy9qdGMxL3NjMjIvd2cyMS9kb2NzL2N3Z19kZWZlY3RzLmh0bWwjMTk1CisgIC8vIEFsc28gbm90ZTogIFNvbWUgY29tcGlsZXJzIGRvIG5vdCBhbGxvdyBmdW5jdGlvbiBwb2ludGVycyB0byBiZSAiY29uc3QiLgorICAvLyAgIFdoaWNoIG1ha2VzIHNlbnNlLCBJIHN1cHBvc2UsIGJlY2F1c2UgaXQncyBtZWFuaW5nbGVzcy4KKyAgcmV0dXJuICgoRW51bVZhbGlkaXR5RnVuYyopYXJnKShudW1iZXIpOworfQorCit2b2lkIEV4dGVuc2lvblNldDo6UmVnaXN0ZXJFbnVtRXh0ZW5zaW9uKGNvbnN0IE1lc3NhZ2VMaXRlKiBjb250YWluaW5nX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBudW1iZXIsIEZpZWxkVHlwZSB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGlzX3JlcGVhdGVkLCBib29sIGlzX3BhY2tlZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRW51bVZhbGlkaXR5RnVuYyogaXNfdmFsaWQpIHsKKyAgR09PR0xFX0NIRUNLX0VRKHR5cGUsIFdpcmVGb3JtYXRMaXRlOjpUWVBFX0VOVU0pOworICBFeHRlbnNpb25JbmZvIGluZm8odHlwZSwgaXNfcmVwZWF0ZWQsIGlzX3BhY2tlZCk7CisgIGluZm8uZW51bV92YWxpZGl0eV9jaGVjay5mdW5jID0gQ2FsbE5vQXJnVmFsaWRpdHlGdW5jOworICAvLyBTZWUgY29tbWVudCBpbiBDYWxsTm9BcmdWYWxpZGl0eUZ1bmMoKSBhYm91dCB3aHkgd2UgdXNlIGEgYy1zdHlsZSBjYXN0LgorICBpbmZvLmVudW1fdmFsaWRpdHlfY2hlY2suYXJnID0gKHZvaWQqKWlzX3ZhbGlkOworICBSZWdpc3Rlcihjb250YWluaW5nX3R5cGUsIG51bWJlciwgaW5mbyk7Cit9CisKK3ZvaWQgRXh0ZW5zaW9uU2V0OjpSZWdpc3Rlck1lc3NhZ2VFeHRlbnNpb24oY29uc3QgTWVzc2FnZUxpdGUqIGNvbnRhaW5pbmdfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG51bWJlciwgRmllbGRUeXBlIHR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaXNfcmVwZWF0ZWQsIGJvb2wgaXNfcGFja2VkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNZXNzYWdlTGl0ZSogcHJvdG90eXBlKSB7CisgIEdPT0dMRV9DSEVDSyh0eXBlID09IFdpcmVGb3JtYXRMaXRlOjpUWVBFX01FU1NBR0UgfHwKKyAgICAgICAgdHlwZSA9PSBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9HUk9VUCk7CisgIEV4dGVuc2lvbkluZm8gaW5mbyh0eXBlLCBpc19yZXBlYXRlZCwgaXNfcGFja2VkKTsKKyAgaW5mby5tZXNzYWdlX3Byb3RvdHlwZSA9IHByb3RvdHlwZTsKKyAgUmVnaXN0ZXIoY29udGFpbmluZ190eXBlLCBudW1iZXIsIGluZm8pOworfQorCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKy8vIENvbnN0cnVjdG9ycyBhbmQgYmFzaWMgbWV0aG9kcy4KKworRXh0ZW5zaW9uU2V0OjpFeHRlbnNpb25TZXQoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIDogYXJlbmFfKGFyZW5hKSB7CisgIGlmIChhcmVuYV8gIT0gTlVMTCkgeworICAgIGFyZW5hXy0+T3duRGVzdHJ1Y3RvcigmZXh0ZW5zaW9uc18pOworICB9Cit9CisKK0V4dGVuc2lvblNldDo6RXh0ZW5zaW9uU2V0KCkgOiBhcmVuYV8oTlVMTCkge30KKworRXh0ZW5zaW9uU2V0Ojp+RXh0ZW5zaW9uU2V0KCkgeworICAvLyBEZWxldGVzIGFsbCBhbGxvY2F0ZWQgZXh0ZW5zaW9ucy4KKyAgaWYgKGFyZW5hXyA9PSBOVUxMKSB7CisgICAgZm9yIChtYXA8aW50LCBFeHRlbnNpb24+OjppdGVyYXRvciBpdGVyID0gZXh0ZW5zaW9uc18uYmVnaW4oKTsKKyAgICAgICAgIGl0ZXIgIT0gZXh0ZW5zaW9uc18uZW5kKCk7ICsraXRlcikgeworICAgICAgaXRlci0+c2Vjb25kLkZyZWUoKTsKKyAgICB9CisgIH0KK30KKworLy8gRGVmaW5lZCBpbiBleHRlbnNpb25fc2V0X2hlYXZ5LmNjLgorLy8gdm9pZCBFeHRlbnNpb25TZXQ6OkFwcGVuZFRvTGlzdChjb25zdCBEZXNjcmlwdG9yKiBjb250YWluaW5nX3R5cGUsCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlc2NyaXB0b3JQb29sKiBwb29sLAorLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4qIG91dHB1dCkgY29uc3QKKworYm9vbCBFeHRlbnNpb25TZXQ6OkhhcyhpbnQgbnVtYmVyKSBjb25zdCB7CisgIG1hcDxpbnQsIEV4dGVuc2lvbj46OmNvbnN0X2l0ZXJhdG9yIGl0ZXIgPSBleHRlbnNpb25zXy5maW5kKG51bWJlcik7CisgIGlmIChpdGVyID09IGV4dGVuc2lvbnNfLmVuZCgpKSByZXR1cm4gZmFsc2U7CisgIEdPT0dMRV9EQ0hFQ0soIWl0ZXItPnNlY29uZC5pc19yZXBlYXRlZCk7CisgIHJldHVybiAhaXRlci0+c2Vjb25kLmlzX2NsZWFyZWQ7Cit9CisKK2ludCBFeHRlbnNpb25TZXQ6Ok51bUV4dGVuc2lvbnMoKSBjb25zdCB7CisgIGludCByZXN1bHQgPSAwOworICBmb3IgKG1hcDxpbnQsIEV4dGVuc2lvbj46OmNvbnN0X2l0ZXJhdG9yIGl0ZXIgPSBleHRlbnNpb25zXy5iZWdpbigpOworICAgICAgIGl0ZXIgIT0gZXh0ZW5zaW9uc18uZW5kKCk7ICsraXRlcikgeworICAgIGlmICghaXRlci0+c2Vjb25kLmlzX2NsZWFyZWQpIHsKKyAgICAgICsrcmVzdWx0OworICAgIH0KKyAgfQorICByZXR1cm4gcmVzdWx0OworfQorCitpbnQgRXh0ZW5zaW9uU2V0OjpFeHRlbnNpb25TaXplKGludCBudW1iZXIpIGNvbnN0IHsKKyAgbWFwPGludCwgRXh0ZW5zaW9uPjo6Y29uc3RfaXRlcmF0b3IgaXRlciA9IGV4dGVuc2lvbnNfLmZpbmQobnVtYmVyKTsKKyAgaWYgKGl0ZXIgPT0gZXh0ZW5zaW9uc18uZW5kKCkpIHJldHVybiBmYWxzZTsKKyAgcmV0dXJuIGl0ZXItPnNlY29uZC5HZXRTaXplKCk7Cit9CisKK0ZpZWxkVHlwZSBFeHRlbnNpb25TZXQ6OkV4dGVuc2lvblR5cGUoaW50IG51bWJlcikgY29uc3QgeworICBtYXA8aW50LCBFeHRlbnNpb24+Ojpjb25zdF9pdGVyYXRvciBpdGVyID0gZXh0ZW5zaW9uc18uZmluZChudW1iZXIpOworICBpZiAoaXRlciA9PSBleHRlbnNpb25zXy5lbmQoKSkgeworICAgIEdPT0dMRV9MT0coREZBVEFMKSA8PCAiRG9uJ3QgbG9va3VwIGV4dGVuc2lvbiB0eXBlcyBpZiB0aGV5IGFyZW4ndCBwcmVzZW50ICgxKS4gIjsKKyAgICByZXR1cm4gMDsKKyAgfQorICBpZiAoaXRlci0+c2Vjb25kLmlzX2NsZWFyZWQpIHsKKyAgICBHT09HTEVfTE9HKERGQVRBTCkgPDwgIkRvbid0IGxvb2t1cCBleHRlbnNpb24gdHlwZXMgaWYgdGhleSBhcmVuJ3QgcHJlc2VudCAoMikuICI7CisgIH0KKyAgcmV0dXJuIGl0ZXItPnNlY29uZC50eXBlOworfQorCit2b2lkIEV4dGVuc2lvblNldDo6Q2xlYXJFeHRlbnNpb24oaW50IG51bWJlcikgeworICBtYXA8aW50LCBFeHRlbnNpb24+OjppdGVyYXRvciBpdGVyID0gZXh0ZW5zaW9uc18uZmluZChudW1iZXIpOworICBpZiAoaXRlciA9PSBleHRlbnNpb25zXy5lbmQoKSkgcmV0dXJuOworICBpdGVyLT5zZWNvbmQuQ2xlYXIoKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorLy8gRmllbGQgYWNjZXNzb3JzCisKK25hbWVzcGFjZSB7CisKK2VudW0gQ2FyZGluYWxpdHkgeworICBSRVBFQVRFRCwKKyAgT1BUSU9OQUwKK307CisKK30gIC8vIG5hbWVzcGFjZQorCisjZGVmaW5lIEdPT0dMRV9EQ0hFQ0tfVFlQRShFWFRFTlNJT04sIExBQkVMLCBDUFBUWVBFKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBHT09HTEVfRENIRUNLX0VRKChFWFRFTlNJT04pLmlzX3JlcGVhdGVkID8gUkVQRUFURUQgOiBPUFRJT05BTCwgTEFCRUwpOyAgICAgICAgIFwKKyAgR09PR0xFX0RDSEVDS19FUShjcHBfdHlwZSgoRVhURU5TSU9OKS50eXBlKSwgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfIyNDUFBUWVBFKQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBQcmltaXRpdmVzCisKKyNkZWZpbmUgUFJJTUlUSVZFX0FDQ0VTU09SUyhVUFBFUkNBU0UsIExPV0VSQ0FTRSwgQ0FNRUxDQVNFKSAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorTE9XRVJDQVNFIEV4dGVuc2lvblNldDo6R2V0IyNDQU1FTENBU0UoaW50IG51bWJlciwgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPV0VSQ0FTRSBkZWZhdWx0X3ZhbHVlKSBjb25zdCB7ICAgICAgICBcCisgIG1hcDxpbnQsIEV4dGVuc2lvbj46OmNvbnN0X2l0ZXJhdG9yIGl0ZXIgPSBleHRlbnNpb25zXy5maW5kKG51bWJlcik7ICAgICAgICAgXAorICBpZiAoaXRlciA9PSBleHRlbnNpb25zXy5lbmQoKSB8fCBpdGVyLT5zZWNvbmQuaXNfY2xlYXJlZCkgeyAgICAgICAgICAgICAgICAgIFwKKyAgICByZXR1cm4gZGVmYXVsdF92YWx1ZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIH0gZWxzZSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIEdPT0dMRV9EQ0hFQ0tfVFlQRShpdGVyLT5zZWNvbmQsIE9QVElPTkFMLCBVUFBFUkNBU0UpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgcmV0dXJuIGl0ZXItPnNlY29uZC5MT1dFUkNBU0UjI192YWx1ZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKK30gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAordm9pZCBFeHRlbnNpb25TZXQ6OlNldCMjQ0FNRUxDQVNFKGludCBudW1iZXIsIEZpZWxkVHlwZSB0eXBlLCAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT1dFUkNBU0UgdmFsdWUsICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7ICAgICAgICAgXAorICBFeHRlbnNpb24qIGV4dGVuc2lvbjsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgaWYgKE1heWJlTmV3RXh0ZW5zaW9uKG51bWJlciwgZGVzY3JpcHRvciwgJmV4dGVuc2lvbikpIHsgICAgICAgICAgICAgICAgICAgICBcCisgICAgZXh0ZW5zaW9uLT50eXBlID0gdHlwZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIEdPT0dMRV9EQ0hFQ0tfRVEoY3BwX3R5cGUoZXh0ZW5zaW9uLT50eXBlKSwgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfIyNVUFBFUkNBU0UpOyBcCisgICAgZXh0ZW5zaW9uLT5pc19yZXBlYXRlZCA9IGZhbHNlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9IGVsc2UgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBHT09HTEVfRENIRUNLX1RZUEUoKmV4dGVuc2lvbiwgT1BUSU9OQUwsIFVQUEVSQ0FTRSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZXh0ZW5zaW9uLT5pc19jbGVhcmVkID0gZmFsc2U7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGV4dGVuc2lvbi0+TE9XRVJDQVNFIyNfdmFsdWUgPSB2YWx1ZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCitMT1dFUkNBU0UgRXh0ZW5zaW9uU2V0OjpHZXRSZXBlYXRlZCMjQ0FNRUxDQVNFKGludCBudW1iZXIsIGludCBpbmRleCkgY29uc3QgeyAgXAorICBtYXA8aW50LCBFeHRlbnNpb24+Ojpjb25zdF9pdGVyYXRvciBpdGVyID0gZXh0ZW5zaW9uc18uZmluZChudW1iZXIpOyAgICAgICAgIFwKKyAgR09PR0xFX0NIRUNLKGl0ZXIgIT0gZXh0ZW5zaW9uc18uZW5kKCkpIDw8ICJJbmRleCBvdXQtb2YtYm91bmRzIChmaWVsZCBpcyBlbXB0eSkuIjsgXAorICBHT09HTEVfRENIRUNLX1RZUEUoaXRlci0+c2Vjb25kLCBSRVBFQVRFRCwgVVBQRVJDQVNFKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHJldHVybiBpdGVyLT5zZWNvbmQucmVwZWF0ZWRfIyNMT1dFUkNBU0UjI192YWx1ZS0+R2V0KGluZGV4KTsgICAgICAgICAgICAgICAgXAorfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCit2b2lkIEV4dGVuc2lvblNldDo6U2V0UmVwZWF0ZWQjI0NBTUVMQ0FTRSggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGludCBudW1iZXIsIGludCBpbmRleCwgTE9XRVJDQVNFIHZhbHVlKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgbWFwPGludCwgRXh0ZW5zaW9uPjo6aXRlcmF0b3IgaXRlciA9IGV4dGVuc2lvbnNfLmZpbmQobnVtYmVyKTsgICAgICAgICAgICAgICBcCisgIEdPT0dMRV9DSEVDSyhpdGVyICE9IGV4dGVuc2lvbnNfLmVuZCgpKSA8PCAiSW5kZXggb3V0LW9mLWJvdW5kcyAoZmllbGQgaXMgZW1wdHkpLiI7IFwKKyAgR09PR0xFX0RDSEVDS19UWVBFKGl0ZXItPnNlY29uZCwgUkVQRUFURUQsIFVQUEVSQ0FTRSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBpdGVyLT5zZWNvbmQucmVwZWF0ZWRfIyNMT1dFUkNBU0UjI192YWx1ZS0+U2V0KGluZGV4LCB2YWx1ZSk7ICAgICAgICAgICAgICAgIFwKK30gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAordm9pZCBFeHRlbnNpb25TZXQ6OkFkZCMjQ0FNRUxDQVNFKGludCBudW1iZXIsIEZpZWxkVHlwZSB0eXBlLCAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIHBhY2tlZCwgTE9XRVJDQVNFIHZhbHVlLCAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7ICAgICAgICAgXAorICBFeHRlbnNpb24qIGV4dGVuc2lvbjsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgaWYgKE1heWJlTmV3RXh0ZW5zaW9uKG51bWJlciwgZGVzY3JpcHRvciwgJmV4dGVuc2lvbikpIHsgICAgICAgICAgICAgICAgICAgICBcCisgICAgZXh0ZW5zaW9uLT50eXBlID0gdHlwZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIEdPT0dMRV9EQ0hFQ0tfRVEoY3BwX3R5cGUoZXh0ZW5zaW9uLT50eXBlKSwgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfIyNVUFBFUkNBU0UpOyBcCisgICAgZXh0ZW5zaW9uLT5pc19yZXBlYXRlZCA9IHRydWU7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGV4dGVuc2lvbi0+aXNfcGFja2VkID0gcGFja2VkOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBleHRlbnNpb24tPnJlcGVhdGVkXyMjTE9XRVJDQVNFIyNfdmFsdWUgPSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxSZXBlYXRlZEZpZWxkPExPV0VSQ0FTRT4gPihhcmVuYV8pOyAgICAgICAgICAgICAgICAgXAorICB9IGVsc2UgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBHT09HTEVfRENIRUNLX1RZUEUoKmV4dGVuc2lvbiwgUkVQRUFURUQsIFVQUEVSQ0FTRSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIEdPT0dMRV9EQ0hFQ0tfRVEoZXh0ZW5zaW9uLT5pc19wYWNrZWQsIHBhY2tlZCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBleHRlbnNpb24tPnJlcGVhdGVkXyMjTE9XRVJDQVNFIyNfdmFsdWUtPkFkZCh2YWx1ZSk7ICAgICAgICAgICAgICAgICAgICAgICAgIFwKK30KKworUFJJTUlUSVZFX0FDQ0VTU09SUyggSU5UMzIsICBpbnQzMiwgIEludDMyKQorUFJJTUlUSVZFX0FDQ0VTU09SUyggSU5UNjQsICBpbnQ2NCwgIEludDY0KQorUFJJTUlUSVZFX0FDQ0VTU09SUyhVSU5UMzIsIHVpbnQzMiwgVUludDMyKQorUFJJTUlUSVZFX0FDQ0VTU09SUyhVSU5UNjQsIHVpbnQ2NCwgVUludDY0KQorUFJJTUlUSVZFX0FDQ0VTU09SUyggRkxPQVQsICBmbG9hdCwgIEZsb2F0KQorUFJJTUlUSVZFX0FDQ0VTU09SUyhET1VCTEUsIGRvdWJsZSwgRG91YmxlKQorUFJJTUlUSVZFX0FDQ0VTU09SUyggIEJPT0wsICAgYm9vbCwgICBCb29sKQorCisjdW5kZWYgUFJJTUlUSVZFX0FDQ0VTU09SUworCitjb25zdCB2b2lkKiBFeHRlbnNpb25TZXQ6OkdldFJhd1JlcGVhdGVkRmllbGQoaW50IG51bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2b2lkKiBkZWZhdWx0X3ZhbHVlKSBjb25zdCB7CisgIG1hcDxpbnQsIEV4dGVuc2lvbj46OmNvbnN0X2l0ZXJhdG9yIGl0ZXIgPSBleHRlbnNpb25zXy5maW5kKG51bWJlcik7CisgIGlmIChpdGVyID09IGV4dGVuc2lvbnNfLmVuZCgpKSB7CisgICAgcmV0dXJuIGRlZmF1bHRfdmFsdWU7CisgIH0KKyAgLy8gV2UgYXNzdW1lIHRoYXQgYWxsIHRoZSBSZXBlYXRlZEZpZWxkPD4qIHBvaW50ZXJzIGhhdmUgdGhlIHNhbWUKKyAgLy8gc2l6ZSBhbmQgYWxpZ25tZW50IHdpdGhpbiB0aGUgYW5vbnltb3VzIHVuaW9uIGluIEV4dGVuc2lvbi4KKyAgcmV0dXJuIGl0ZXItPnNlY29uZC5yZXBlYXRlZF9pbnQzMl92YWx1ZTsKK30KKwordm9pZCogRXh0ZW5zaW9uU2V0OjpNdXRhYmxlUmF3UmVwZWF0ZWRGaWVsZChpbnQgbnVtYmVyLCBGaWVsZFR5cGUgZmllbGRfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBwYWNrZWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzYykgeworICBFeHRlbnNpb24qIGV4dGVuc2lvbjsKKworICAvLyBXZSBpbnN0YW50aWF0ZSBhbiBlbXB0eSBSZXBlYXRlZHssUHRyfUZpZWxkIGlmIG9uZSBkb2Vzbid0IGV4aXN0IGZvciB0aGlzCisgIC8vIGV4dGVuc2lvbi4KKyAgaWYgKE1heWJlTmV3RXh0ZW5zaW9uKG51bWJlciwgZGVzYywgJmV4dGVuc2lvbikpIHsKKyAgICBleHRlbnNpb24tPmlzX3JlcGVhdGVkID0gdHJ1ZTsKKyAgICBleHRlbnNpb24tPnR5cGUgPSBmaWVsZF90eXBlOworICAgIGV4dGVuc2lvbi0+aXNfcGFja2VkID0gcGFja2VkOworCisgICAgc3dpdGNoIChXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlVG9DcHBUeXBlKAorICAgICAgICBzdGF0aWNfY2FzdDxXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlPihmaWVsZF90eXBlKSkpIHsKKyAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfSU5UMzI6CisgICAgICAgIGV4dGVuc2lvbi0+cmVwZWF0ZWRfaW50MzJfdmFsdWUgPQorICAgICAgICAgICAgQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8UmVwZWF0ZWRGaWVsZDxpbnQzMj4gPihhcmVuYV8pOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfSU5UNjQ6CisgICAgICAgIGV4dGVuc2lvbi0+cmVwZWF0ZWRfaW50NjRfdmFsdWUgPQorICAgICAgICAgICAgQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8UmVwZWF0ZWRGaWVsZDxpbnQ2ND4gPihhcmVuYV8pOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfVUlOVDMyOgorICAgICAgICBleHRlbnNpb24tPnJlcGVhdGVkX3VpbnQzMl92YWx1ZSA9CisgICAgICAgICAgICBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxSZXBlYXRlZEZpZWxkPHVpbnQzMj4gPihhcmVuYV8pOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfVUlOVDY0OgorICAgICAgICBleHRlbnNpb24tPnJlcGVhdGVkX3VpbnQ2NF92YWx1ZSA9CisgICAgICAgICAgICBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxSZXBlYXRlZEZpZWxkPHVpbnQ2ND4gPihhcmVuYV8pOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfRE9VQkxFOgorICAgICAgICBleHRlbnNpb24tPnJlcGVhdGVkX2RvdWJsZV92YWx1ZSA9CisgICAgICAgICAgICBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxSZXBlYXRlZEZpZWxkPGRvdWJsZT4gPihhcmVuYV8pOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfRkxPQVQ6CisgICAgICAgIGV4dGVuc2lvbi0+cmVwZWF0ZWRfZmxvYXRfdmFsdWUgPQorICAgICAgICAgICAgQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8UmVwZWF0ZWRGaWVsZDxmbG9hdD4gPihhcmVuYV8pOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfQk9PTDoKKyAgICAgICAgZXh0ZW5zaW9uLT5yZXBlYXRlZF9ib29sX3ZhbHVlID0KKyAgICAgICAgICAgIEFyZW5hOjpDcmVhdGVNZXNzYWdlPFJlcGVhdGVkRmllbGQ8Ym9vbD4gPihhcmVuYV8pOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfRU5VTToKKyAgICAgICAgZXh0ZW5zaW9uLT5yZXBlYXRlZF9lbnVtX3ZhbHVlID0KKyAgICAgICAgICAgIEFyZW5hOjpDcmVhdGVNZXNzYWdlPFJlcGVhdGVkRmllbGQ8aW50PiA+KGFyZW5hXyk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV9TVFJJTkc6CisgICAgICAgIGV4dGVuc2lvbi0+cmVwZWF0ZWRfc3RyaW5nX3ZhbHVlID0KKyAgICAgICAgICAgIEFyZW5hOjpDcmVhdGVNZXNzYWdlPFJlcGVhdGVkUHRyRmllbGQ8IDo6c3RkOjpzdHJpbmc+ID4oYXJlbmFfKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpDUFBUWVBFX01FU1NBR0U6CisgICAgICAgIGV4dGVuc2lvbi0+cmVwZWF0ZWRfbWVzc2FnZV92YWx1ZSA9CisgICAgICAgICAgICBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxSZXBlYXRlZFB0ckZpZWxkPE1lc3NhZ2VMaXRlPiA+KGFyZW5hXyk7CisgICAgICAgIGJyZWFrOworICAgIH0KKyAgfQorCisgIC8vIFdlIGFzc3VtZSB0aGF0IGFsbCB0aGUgUmVwZWF0ZWRGaWVsZDw+KiBwb2ludGVycyBoYXZlIHRoZSBzYW1lCisgIC8vIHNpemUgYW5kIGFsaWdubWVudCB3aXRoaW4gdGhlIGFub255bW91cyB1bmlvbiBpbiBFeHRlbnNpb24uCisgIHJldHVybiBleHRlbnNpb24tPnJlcGVhdGVkX2ludDMyX3ZhbHVlOworfQorCisvLyBDb21wYXRpYmxlIHZlcnNpb24gdXNpbmcgb2xkIGNhbGwgc2lnbmF0dXJlLiBEb2VzIG5vdCBjcmVhdGUgZXh0ZW5zaW9ucyB3aGVuCisvLyB0aGUgZG9uJ3QgYWxyZWFkeSBleGlzdDsgaW5zdGVhZCwganVzdCBHT09HTEVfQ0hFQ0stZmFpbHMuCit2b2lkKiBFeHRlbnNpb25TZXQ6Ok11dGFibGVSYXdSZXBlYXRlZEZpZWxkKGludCBudW1iZXIpIHsKKyAgbWFwPGludCwgRXh0ZW5zaW9uPjo6aXRlcmF0b3IgaXRlciA9IGV4dGVuc2lvbnNfLmZpbmQobnVtYmVyKTsKKyAgR09PR0xFX0NIRUNLKGl0ZXIgPT0gZXh0ZW5zaW9uc18uZW5kKCkpIDw8ICJFeHRlbnNpb24gbm90IGZvdW5kLiI7CisgIC8vIFdlIGFzc3VtZSB0aGF0IGFsbCB0aGUgUmVwZWF0ZWRGaWVsZDw+KiBwb2ludGVycyBoYXZlIHRoZSBzYW1lCisgIC8vIHNpemUgYW5kIGFsaWdubWVudCB3aXRoaW4gdGhlIGFub255bW91cyB1bmlvbiBpbiBFeHRlbnNpb24uCisgIHJldHVybiBpdGVyLT5zZWNvbmQucmVwZWF0ZWRfaW50MzJfdmFsdWU7Cit9CisKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gRW51bXMKKworaW50IEV4dGVuc2lvblNldDo6R2V0RW51bShpbnQgbnVtYmVyLCBpbnQgZGVmYXVsdF92YWx1ZSkgY29uc3QgeworICBtYXA8aW50LCBFeHRlbnNpb24+Ojpjb25zdF9pdGVyYXRvciBpdGVyID0gZXh0ZW5zaW9uc18uZmluZChudW1iZXIpOworICBpZiAoaXRlciA9PSBleHRlbnNpb25zXy5lbmQoKSB8fCBpdGVyLT5zZWNvbmQuaXNfY2xlYXJlZCkgeworICAgIC8vIE5vdCBwcmVzZW50LiAgUmV0dXJuIHRoZSBkZWZhdWx0IHZhbHVlLgorICAgIHJldHVybiBkZWZhdWx0X3ZhbHVlOworICB9IGVsc2UgeworICAgIEdPT0dMRV9EQ0hFQ0tfVFlQRShpdGVyLT5zZWNvbmQsIE9QVElPTkFMLCBFTlVNKTsKKyAgICByZXR1cm4gaXRlci0+c2Vjb25kLmVudW1fdmFsdWU7CisgIH0KK30KKwordm9pZCBFeHRlbnNpb25TZXQ6OlNldEVudW0oaW50IG51bWJlciwgRmllbGRUeXBlIHR5cGUsIGludCB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBFeHRlbnNpb24qIGV4dGVuc2lvbjsKKyAgaWYgKE1heWJlTmV3RXh0ZW5zaW9uKG51bWJlciwgZGVzY3JpcHRvciwgJmV4dGVuc2lvbikpIHsKKyAgICBleHRlbnNpb24tPnR5cGUgPSB0eXBlOworICAgIEdPT0dMRV9EQ0hFQ0tfRVEoY3BwX3R5cGUoZXh0ZW5zaW9uLT50eXBlKSwgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfRU5VTSk7CisgICAgZXh0ZW5zaW9uLT5pc19yZXBlYXRlZCA9IGZhbHNlOworICB9IGVsc2UgeworICAgIEdPT0dMRV9EQ0hFQ0tfVFlQRSgqZXh0ZW5zaW9uLCBPUFRJT05BTCwgRU5VTSk7CisgIH0KKyAgZXh0ZW5zaW9uLT5pc19jbGVhcmVkID0gZmFsc2U7CisgIGV4dGVuc2lvbi0+ZW51bV92YWx1ZSA9IHZhbHVlOworfQorCitpbnQgRXh0ZW5zaW9uU2V0OjpHZXRSZXBlYXRlZEVudW0oaW50IG51bWJlciwgaW50IGluZGV4KSBjb25zdCB7CisgIG1hcDxpbnQsIEV4dGVuc2lvbj46OmNvbnN0X2l0ZXJhdG9yIGl0ZXIgPSBleHRlbnNpb25zXy5maW5kKG51bWJlcik7CisgIEdPT0dMRV9DSEVDSyhpdGVyICE9IGV4dGVuc2lvbnNfLmVuZCgpKSA8PCAiSW5kZXggb3V0LW9mLWJvdW5kcyAoZmllbGQgaXMgZW1wdHkpLiI7CisgIEdPT0dMRV9EQ0hFQ0tfVFlQRShpdGVyLT5zZWNvbmQsIFJFUEVBVEVELCBFTlVNKTsKKyAgcmV0dXJuIGl0ZXItPnNlY29uZC5yZXBlYXRlZF9lbnVtX3ZhbHVlLT5HZXQoaW5kZXgpOworfQorCit2b2lkIEV4dGVuc2lvblNldDo6U2V0UmVwZWF0ZWRFbnVtKGludCBudW1iZXIsIGludCBpbmRleCwgaW50IHZhbHVlKSB7CisgIG1hcDxpbnQsIEV4dGVuc2lvbj46Oml0ZXJhdG9yIGl0ZXIgPSBleHRlbnNpb25zXy5maW5kKG51bWJlcik7CisgIEdPT0dMRV9DSEVDSyhpdGVyICE9IGV4dGVuc2lvbnNfLmVuZCgpKSA8PCAiSW5kZXggb3V0LW9mLWJvdW5kcyAoZmllbGQgaXMgZW1wdHkpLiI7CisgIEdPT0dMRV9EQ0hFQ0tfVFlQRShpdGVyLT5zZWNvbmQsIFJFUEVBVEVELCBFTlVNKTsKKyAgaXRlci0+c2Vjb25kLnJlcGVhdGVkX2VudW1fdmFsdWUtPlNldChpbmRleCwgdmFsdWUpOworfQorCit2b2lkIEV4dGVuc2lvblNldDo6QWRkRW51bShpbnQgbnVtYmVyLCBGaWVsZFR5cGUgdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgcGFja2VkLCBpbnQgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgRXh0ZW5zaW9uKiBleHRlbnNpb247CisgIGlmIChNYXliZU5ld0V4dGVuc2lvbihudW1iZXIsIGRlc2NyaXB0b3IsICZleHRlbnNpb24pKSB7CisgICAgZXh0ZW5zaW9uLT50eXBlID0gdHlwZTsKKyAgICBHT09HTEVfRENIRUNLX0VRKGNwcF90eXBlKGV4dGVuc2lvbi0+dHlwZSksIFdpcmVGb3JtYXRMaXRlOjpDUFBUWVBFX0VOVU0pOworICAgIGV4dGVuc2lvbi0+aXNfcmVwZWF0ZWQgPSB0cnVlOworICAgIGV4dGVuc2lvbi0+aXNfcGFja2VkID0gcGFja2VkOworICAgIGV4dGVuc2lvbi0+cmVwZWF0ZWRfZW51bV92YWx1ZSA9CisgICAgICAgIEFyZW5hOjpDcmVhdGVNZXNzYWdlPFJlcGVhdGVkRmllbGQ8aW50PiA+KGFyZW5hXyk7CisgIH0gZWxzZSB7CisgICAgR09PR0xFX0RDSEVDS19UWVBFKCpleHRlbnNpb24sIFJFUEVBVEVELCBFTlVNKTsKKyAgICBHT09HTEVfRENIRUNLX0VRKGV4dGVuc2lvbi0+aXNfcGFja2VkLCBwYWNrZWQpOworICB9CisgIGV4dGVuc2lvbi0+cmVwZWF0ZWRfZW51bV92YWx1ZS0+QWRkKHZhbHVlKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gU3RyaW5ncworCitjb25zdCBzdHJpbmcmIEV4dGVuc2lvblNldDo6R2V0U3RyaW5nKGludCBudW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgZGVmYXVsdF92YWx1ZSkgY29uc3QgeworICBtYXA8aW50LCBFeHRlbnNpb24+Ojpjb25zdF9pdGVyYXRvciBpdGVyID0gZXh0ZW5zaW9uc18uZmluZChudW1iZXIpOworICBpZiAoaXRlciA9PSBleHRlbnNpb25zXy5lbmQoKSB8fCBpdGVyLT5zZWNvbmQuaXNfY2xlYXJlZCkgeworICAgIC8vIE5vdCBwcmVzZW50LiAgUmV0dXJuIHRoZSBkZWZhdWx0IHZhbHVlLgorICAgIHJldHVybiBkZWZhdWx0X3ZhbHVlOworICB9IGVsc2UgeworICAgIEdPT0dMRV9EQ0hFQ0tfVFlQRShpdGVyLT5zZWNvbmQsIE9QVElPTkFMLCBTVFJJTkcpOworICAgIHJldHVybiAqaXRlci0+c2Vjb25kLnN0cmluZ192YWx1ZTsKKyAgfQorfQorCitzdHJpbmcqIEV4dGVuc2lvblNldDo6TXV0YWJsZVN0cmluZyhpbnQgbnVtYmVyLCBGaWVsZFR5cGUgdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBFeHRlbnNpb24qIGV4dGVuc2lvbjsKKyAgaWYgKE1heWJlTmV3RXh0ZW5zaW9uKG51bWJlciwgZGVzY3JpcHRvciwgJmV4dGVuc2lvbikpIHsKKyAgICBleHRlbnNpb24tPnR5cGUgPSB0eXBlOworICAgIEdPT0dMRV9EQ0hFQ0tfRVEoY3BwX3R5cGUoZXh0ZW5zaW9uLT50eXBlKSwgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfU1RSSU5HKTsKKyAgICBleHRlbnNpb24tPmlzX3JlcGVhdGVkID0gZmFsc2U7CisgICAgZXh0ZW5zaW9uLT5zdHJpbmdfdmFsdWUgPSBBcmVuYTo6Q3JlYXRlPHN0cmluZz4oYXJlbmFfKTsKKyAgfSBlbHNlIHsKKyAgICBHT09HTEVfRENIRUNLX1RZUEUoKmV4dGVuc2lvbiwgT1BUSU9OQUwsIFNUUklORyk7CisgIH0KKyAgZXh0ZW5zaW9uLT5pc19jbGVhcmVkID0gZmFsc2U7CisgIHJldHVybiBleHRlbnNpb24tPnN0cmluZ192YWx1ZTsKK30KKworY29uc3Qgc3RyaW5nJiBFeHRlbnNpb25TZXQ6OkdldFJlcGVhdGVkU3RyaW5nKGludCBudW1iZXIsIGludCBpbmRleCkgY29uc3QgeworICBtYXA8aW50LCBFeHRlbnNpb24+Ojpjb25zdF9pdGVyYXRvciBpdGVyID0gZXh0ZW5zaW9uc18uZmluZChudW1iZXIpOworICBHT09HTEVfQ0hFQ0soaXRlciAhPSBleHRlbnNpb25zXy5lbmQoKSkgPDwgIkluZGV4IG91dC1vZi1ib3VuZHMgKGZpZWxkIGlzIGVtcHR5KS4iOworICBHT09HTEVfRENIRUNLX1RZUEUoaXRlci0+c2Vjb25kLCBSRVBFQVRFRCwgU1RSSU5HKTsKKyAgcmV0dXJuIGl0ZXItPnNlY29uZC5yZXBlYXRlZF9zdHJpbmdfdmFsdWUtPkdldChpbmRleCk7Cit9CisKK3N0cmluZyogRXh0ZW5zaW9uU2V0OjpNdXRhYmxlUmVwZWF0ZWRTdHJpbmcoaW50IG51bWJlciwgaW50IGluZGV4KSB7CisgIG1hcDxpbnQsIEV4dGVuc2lvbj46Oml0ZXJhdG9yIGl0ZXIgPSBleHRlbnNpb25zXy5maW5kKG51bWJlcik7CisgIEdPT0dMRV9DSEVDSyhpdGVyICE9IGV4dGVuc2lvbnNfLmVuZCgpKSA8PCAiSW5kZXggb3V0LW9mLWJvdW5kcyAoZmllbGQgaXMgZW1wdHkpLiI7CisgIEdPT0dMRV9EQ0hFQ0tfVFlQRShpdGVyLT5zZWNvbmQsIFJFUEVBVEVELCBTVFJJTkcpOworICByZXR1cm4gaXRlci0+c2Vjb25kLnJlcGVhdGVkX3N0cmluZ192YWx1ZS0+TXV0YWJsZShpbmRleCk7Cit9CisKK3N0cmluZyogRXh0ZW5zaW9uU2V0OjpBZGRTdHJpbmcoaW50IG51bWJlciwgRmllbGRUeXBlIHR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICBFeHRlbnNpb24qIGV4dGVuc2lvbjsKKyAgaWYgKE1heWJlTmV3RXh0ZW5zaW9uKG51bWJlciwgZGVzY3JpcHRvciwgJmV4dGVuc2lvbikpIHsKKyAgICBleHRlbnNpb24tPnR5cGUgPSB0eXBlOworICAgIEdPT0dMRV9EQ0hFQ0tfRVEoY3BwX3R5cGUoZXh0ZW5zaW9uLT50eXBlKSwgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfU1RSSU5HKTsKKyAgICBleHRlbnNpb24tPmlzX3JlcGVhdGVkID0gdHJ1ZTsKKyAgICBleHRlbnNpb24tPmlzX3BhY2tlZCA9IGZhbHNlOworICAgIGV4dGVuc2lvbi0+cmVwZWF0ZWRfc3RyaW5nX3ZhbHVlID0KKyAgICAgICAgQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8UmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+ID4oYXJlbmFfKTsKKyAgfSBlbHNlIHsKKyAgICBHT09HTEVfRENIRUNLX1RZUEUoKmV4dGVuc2lvbiwgUkVQRUFURUQsIFNUUklORyk7CisgIH0KKyAgcmV0dXJuIGV4dGVuc2lvbi0+cmVwZWF0ZWRfc3RyaW5nX3ZhbHVlLT5BZGQoKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gTWVzc2FnZXMKKworY29uc3QgTWVzc2FnZUxpdGUmIEV4dGVuc2lvblNldDo6R2V0TWVzc2FnZSgKKyAgICBpbnQgbnVtYmVyLCBjb25zdCBNZXNzYWdlTGl0ZSYgZGVmYXVsdF92YWx1ZSkgY29uc3QgeworICBtYXA8aW50LCBFeHRlbnNpb24+Ojpjb25zdF9pdGVyYXRvciBpdGVyID0gZXh0ZW5zaW9uc18uZmluZChudW1iZXIpOworICBpZiAoaXRlciA9PSBleHRlbnNpb25zXy5lbmQoKSkgeworICAgIC8vIE5vdCBwcmVzZW50LiAgUmV0dXJuIHRoZSBkZWZhdWx0IHZhbHVlLgorICAgIHJldHVybiBkZWZhdWx0X3ZhbHVlOworICB9IGVsc2UgeworICAgIEdPT0dMRV9EQ0hFQ0tfVFlQRShpdGVyLT5zZWNvbmQsIE9QVElPTkFMLCBNRVNTQUdFKTsKKyAgICBpZiAoaXRlci0+c2Vjb25kLmlzX2xhenkpIHsKKyAgICAgIHJldHVybiBpdGVyLT5zZWNvbmQubGF6eW1lc3NhZ2VfdmFsdWUtPkdldE1lc3NhZ2UoZGVmYXVsdF92YWx1ZSk7CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiAqaXRlci0+c2Vjb25kLm1lc3NhZ2VfdmFsdWU7CisgICAgfQorICB9Cit9CisKKy8vIERlZmluZWQgaW4gZXh0ZW5zaW9uX3NldF9oZWF2eS5jYy4KKy8vIGNvbnN0IE1lc3NhZ2VMaXRlJiBFeHRlbnNpb25TZXQ6OkdldE1lc3NhZ2UoaW50IG51bWJlciwKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVzY3JpcHRvciogbWVzc2FnZV90eXBlLAorLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlRmFjdG9yeSogZmFjdG9yeSkgY29uc3QKKworTWVzc2FnZUxpdGUqIEV4dGVuc2lvblNldDo6TXV0YWJsZU1lc3NhZ2UoaW50IG51bWJlciwgRmllbGRUeXBlIHR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNZXNzYWdlTGl0ZSYgcHJvdG90eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIEV4dGVuc2lvbiogZXh0ZW5zaW9uOworICBpZiAoTWF5YmVOZXdFeHRlbnNpb24obnVtYmVyLCBkZXNjcmlwdG9yLCAmZXh0ZW5zaW9uKSkgeworICAgIGV4dGVuc2lvbi0+dHlwZSA9IHR5cGU7CisgICAgR09PR0xFX0RDSEVDS19FUShjcHBfdHlwZShleHRlbnNpb24tPnR5cGUpLCBXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV9NRVNTQUdFKTsKKyAgICBleHRlbnNpb24tPmlzX3JlcGVhdGVkID0gZmFsc2U7CisgICAgZXh0ZW5zaW9uLT5pc19sYXp5ID0gZmFsc2U7CisgICAgZXh0ZW5zaW9uLT5tZXNzYWdlX3ZhbHVlID0gcHJvdG90eXBlLk5ldyhhcmVuYV8pOworICAgIGV4dGVuc2lvbi0+aXNfY2xlYXJlZCA9IGZhbHNlOworICAgIHJldHVybiBleHRlbnNpb24tPm1lc3NhZ2VfdmFsdWU7CisgIH0gZWxzZSB7CisgICAgR09PR0xFX0RDSEVDS19UWVBFKCpleHRlbnNpb24sIE9QVElPTkFMLCBNRVNTQUdFKTsKKyAgICBleHRlbnNpb24tPmlzX2NsZWFyZWQgPSBmYWxzZTsKKyAgICBpZiAoZXh0ZW5zaW9uLT5pc19sYXp5KSB7CisgICAgICByZXR1cm4gZXh0ZW5zaW9uLT5sYXp5bWVzc2FnZV92YWx1ZS0+TXV0YWJsZU1lc3NhZ2UocHJvdG90eXBlKTsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIGV4dGVuc2lvbi0+bWVzc2FnZV92YWx1ZTsKKyAgICB9CisgIH0KK30KKworLy8gRGVmaW5lZCBpbiBleHRlbnNpb25fc2V0X2hlYXZ5LmNjLgorLy8gTWVzc2FnZUxpdGUqIEV4dGVuc2lvblNldDo6TXV0YWJsZU1lc3NhZ2UoaW50IG51bWJlciwgRmllbGRUeXBlIHR5cGUsCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlX3R5cGUsCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlRmFjdG9yeSogZmFjdG9yeSkKKwordm9pZCBFeHRlbnNpb25TZXQ6OlNldEFsbG9jYXRlZE1lc3NhZ2UoaW50IG51bWJlciwgRmllbGRUeXBlIHR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlTGl0ZSogbWVzc2FnZSkgeworICBpZiAobWVzc2FnZSA9PSBOVUxMKSB7CisgICAgQ2xlYXJFeHRlbnNpb24obnVtYmVyKTsKKyAgICByZXR1cm47CisgIH0KKyAgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogbWVzc2FnZV9hcmVuYSA9IG1lc3NhZ2UtPkdldEFyZW5hKCk7CisgIEV4dGVuc2lvbiogZXh0ZW5zaW9uOworICBpZiAoTWF5YmVOZXdFeHRlbnNpb24obnVtYmVyLCBkZXNjcmlwdG9yLCAmZXh0ZW5zaW9uKSkgeworICAgIGV4dGVuc2lvbi0+dHlwZSA9IHR5cGU7CisgICAgR09PR0xFX0RDSEVDS19FUShjcHBfdHlwZShleHRlbnNpb24tPnR5cGUpLCBXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV9NRVNTQUdFKTsKKyAgICBleHRlbnNpb24tPmlzX3JlcGVhdGVkID0gZmFsc2U7CisgICAgZXh0ZW5zaW9uLT5pc19sYXp5ID0gZmFsc2U7CisgICAgaWYgKG1lc3NhZ2VfYXJlbmEgPT0gYXJlbmFfKSB7CisgICAgICBleHRlbnNpb24tPm1lc3NhZ2VfdmFsdWUgPSBtZXNzYWdlOworICAgIH0gZWxzZSBpZiAobWVzc2FnZV9hcmVuYSA9PSBOVUxMKSB7CisgICAgICBleHRlbnNpb24tPm1lc3NhZ2VfdmFsdWUgPSBtZXNzYWdlOworICAgICAgYXJlbmFfLT5Pd24obWVzc2FnZSk7ICAvLyBub3QgTlVMTCBiZWNhdXNlIG5vdCBlcXVhbCB0byBtZXNzYWdlX2FyZW5hCisgICAgfSBlbHNlIHsKKyAgICAgIGV4dGVuc2lvbi0+bWVzc2FnZV92YWx1ZSA9IG1lc3NhZ2UtPk5ldyhhcmVuYV8pOworICAgICAgZXh0ZW5zaW9uLT5tZXNzYWdlX3ZhbHVlLT5DaGVja1R5cGVBbmRNZXJnZUZyb20oKm1lc3NhZ2UpOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICBHT09HTEVfRENIRUNLX1RZUEUoKmV4dGVuc2lvbiwgT1BUSU9OQUwsIE1FU1NBR0UpOworICAgIGlmIChleHRlbnNpb24tPmlzX2xhenkpIHsKKyAgICAgIGV4dGVuc2lvbi0+bGF6eW1lc3NhZ2VfdmFsdWUtPlNldEFsbG9jYXRlZE1lc3NhZ2UobWVzc2FnZSk7CisgICAgfSBlbHNlIHsKKyAgICAgIGlmIChhcmVuYV8gPT0gTlVMTCkgeworICAgICAgICBkZWxldGUgZXh0ZW5zaW9uLT5tZXNzYWdlX3ZhbHVlOworICAgICAgfQorICAgICAgaWYgKG1lc3NhZ2VfYXJlbmEgPT0gYXJlbmFfKSB7CisgICAgICAgIGV4dGVuc2lvbi0+bWVzc2FnZV92YWx1ZSA9IG1lc3NhZ2U7CisgICAgICB9IGVsc2UgaWYgKG1lc3NhZ2VfYXJlbmEgPT0gTlVMTCkgeworICAgICAgICBleHRlbnNpb24tPm1lc3NhZ2VfdmFsdWUgPSBtZXNzYWdlOworICAgICAgICBhcmVuYV8tPk93bihtZXNzYWdlKTsgIC8vIG5vdCBOVUxMIGJlY2F1c2Ugbm90IGVxdWFsIHRvIG1lc3NhZ2VfYXJlbmEKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGV4dGVuc2lvbi0+bWVzc2FnZV92YWx1ZSA9IG1lc3NhZ2UtPk5ldyhhcmVuYV8pOworICAgICAgICBleHRlbnNpb24tPm1lc3NhZ2VfdmFsdWUtPkNoZWNrVHlwZUFuZE1lcmdlRnJvbSgqbWVzc2FnZSk7CisgICAgICB9CisgICAgfQorICB9CisgIGV4dGVuc2lvbi0+aXNfY2xlYXJlZCA9IGZhbHNlOworfQorCit2b2lkIEV4dGVuc2lvblNldDo6VW5zYWZlQXJlbmFTZXRBbGxvY2F0ZWRNZXNzYWdlKAorICAgIGludCBudW1iZXIsIEZpZWxkVHlwZSB0eXBlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgTWVzc2FnZUxpdGUqIG1lc3NhZ2UpIHsKKyAgaWYgKG1lc3NhZ2UgPT0gTlVMTCkgeworICAgIENsZWFyRXh0ZW5zaW9uKG51bWJlcik7CisgICAgcmV0dXJuOworICB9CisgIEV4dGVuc2lvbiogZXh0ZW5zaW9uOworICBpZiAoTWF5YmVOZXdFeHRlbnNpb24obnVtYmVyLCBkZXNjcmlwdG9yLCAmZXh0ZW5zaW9uKSkgeworICAgIGV4dGVuc2lvbi0+dHlwZSA9IHR5cGU7CisgICAgR09PR0xFX0RDSEVDS19FUShjcHBfdHlwZShleHRlbnNpb24tPnR5cGUpLCBXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV9NRVNTQUdFKTsKKyAgICBleHRlbnNpb24tPmlzX3JlcGVhdGVkID0gZmFsc2U7CisgICAgZXh0ZW5zaW9uLT5pc19sYXp5ID0gZmFsc2U7CisgICAgZXh0ZW5zaW9uLT5tZXNzYWdlX3ZhbHVlID0gbWVzc2FnZTsKKyAgfSBlbHNlIHsKKyAgICBHT09HTEVfRENIRUNLX1RZUEUoKmV4dGVuc2lvbiwgT1BUSU9OQUwsIE1FU1NBR0UpOworICAgIGlmIChleHRlbnNpb24tPmlzX2xhenkpIHsKKyAgICAgIGV4dGVuc2lvbi0+bGF6eW1lc3NhZ2VfdmFsdWUtPlVuc2FmZUFyZW5hU2V0QWxsb2NhdGVkTWVzc2FnZShtZXNzYWdlKTsKKyAgICB9IGVsc2UgeworICAgICAgaWYgKGFyZW5hXyA9PSBOVUxMKSB7CisgICAgICAgIGRlbGV0ZSBleHRlbnNpb24tPm1lc3NhZ2VfdmFsdWU7CisgICAgICB9CisgICAgICBleHRlbnNpb24tPm1lc3NhZ2VfdmFsdWUgPSBtZXNzYWdlOworICAgIH0KKyAgfQorICBleHRlbnNpb24tPmlzX2NsZWFyZWQgPSBmYWxzZTsKK30KKworCitNZXNzYWdlTGl0ZSogRXh0ZW5zaW9uU2V0OjpSZWxlYXNlTWVzc2FnZShpbnQgbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZUxpdGUmIHByb3RvdHlwZSkgeworICBtYXA8aW50LCBFeHRlbnNpb24+OjppdGVyYXRvciBpdGVyID0gZXh0ZW5zaW9uc18uZmluZChudW1iZXIpOworICBpZiAoaXRlciA9PSBleHRlbnNpb25zXy5lbmQoKSkgeworICAgIC8vIE5vdCBwcmVzZW50LiAgUmV0dXJuIE5VTEwuCisgICAgcmV0dXJuIE5VTEw7CisgIH0gZWxzZSB7CisgICAgR09PR0xFX0RDSEVDS19UWVBFKGl0ZXItPnNlY29uZCwgT1BUSU9OQUwsIE1FU1NBR0UpOworICAgIE1lc3NhZ2VMaXRlKiByZXQgPSBOVUxMOworICAgIGlmIChpdGVyLT5zZWNvbmQuaXNfbGF6eSkgeworICAgICAgcmV0ID0gaXRlci0+c2Vjb25kLmxhenltZXNzYWdlX3ZhbHVlLT5SZWxlYXNlTWVzc2FnZShwcm90b3R5cGUpOworICAgICAgaWYgKGFyZW5hXyA9PSBOVUxMKSB7CisgICAgICAgIGRlbGV0ZSBpdGVyLT5zZWNvbmQubGF6eW1lc3NhZ2VfdmFsdWU7CisgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgIGlmIChhcmVuYV8gPT0gTlVMTCkgeworICAgICAgICByZXQgPSBpdGVyLT5zZWNvbmQubWVzc2FnZV92YWx1ZTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIC8vIFJlbGVhc2VNZXNzYWdlKCkgYWx3YXlzIHJldHVybnMgYSBoZWFwLWFsbG9jYXRlZCBtZXNzYWdlLCBhbmQgd2UgYXJlCisgICAgICAgIC8vIG9uIGFuIGFyZW5hLCBzbyB3ZSBuZWVkIHRvIG1ha2UgYSBjb3B5IG9mIHRoaXMgbWVzc2FnZSB0byByZXR1cm4uCisgICAgICAgIHJldCA9IChpdGVyLT5zZWNvbmQubWVzc2FnZV92YWx1ZSktPk5ldygpOworICAgICAgICByZXQtPkNoZWNrVHlwZUFuZE1lcmdlRnJvbSgqaXRlci0+c2Vjb25kLm1lc3NhZ2VfdmFsdWUpOworICAgICAgfQorICAgIH0KKyAgICBleHRlbnNpb25zXy5lcmFzZShudW1iZXIpOworICAgIHJldHVybiByZXQ7CisgIH0KK30KKworTWVzc2FnZUxpdGUqIEV4dGVuc2lvblNldDo6VW5zYWZlQXJlbmFSZWxlYXNlTWVzc2FnZSgKKyAgICBpbnQgbnVtYmVyLCBjb25zdCBNZXNzYWdlTGl0ZSYgcHJvdG90eXBlKSB7CisgIG1hcDxpbnQsIEV4dGVuc2lvbj46Oml0ZXJhdG9yIGl0ZXIgPSBleHRlbnNpb25zXy5maW5kKG51bWJlcik7CisgIGlmIChpdGVyID09IGV4dGVuc2lvbnNfLmVuZCgpKSB7CisgICAgLy8gTm90IHByZXNlbnQuICBSZXR1cm4gTlVMTC4KKyAgICByZXR1cm4gTlVMTDsKKyAgfSBlbHNlIHsKKyAgICBHT09HTEVfRENIRUNLX1RZUEUoaXRlci0+c2Vjb25kLCBPUFRJT05BTCwgTUVTU0FHRSk7CisgICAgTWVzc2FnZUxpdGUqIHJldCA9IE5VTEw7CisgICAgaWYgKGl0ZXItPnNlY29uZC5pc19sYXp5KSB7CisgICAgICByZXQgPQorICAgICAgICBpdGVyLT5zZWNvbmQubGF6eW1lc3NhZ2VfdmFsdWUtPlVuc2FmZUFyZW5hUmVsZWFzZU1lc3NhZ2UocHJvdG90eXBlKTsKKyAgICAgIGlmIChhcmVuYV8gPT0gTlVMTCkgeworICAgICAgICBkZWxldGUgaXRlci0+c2Vjb25kLmxhenltZXNzYWdlX3ZhbHVlOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICByZXQgPSBpdGVyLT5zZWNvbmQubWVzc2FnZV92YWx1ZTsKKyAgICB9CisgICAgZXh0ZW5zaW9uc18uZXJhc2UobnVtYmVyKTsKKyAgICByZXR1cm4gcmV0OworICB9Cit9CisKKy8vIERlZmluZWQgaW4gZXh0ZW5zaW9uX3NldF9oZWF2eS5jYy4KKy8vIE1lc3NhZ2VMaXRlKiBFeHRlbnNpb25TZXQ6OlJlbGVhc2VNZXNzYWdlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VGYWN0b3J5KiBmYWN0b3J5KTsKKworY29uc3QgTWVzc2FnZUxpdGUmIEV4dGVuc2lvblNldDo6R2V0UmVwZWF0ZWRNZXNzYWdlKAorICAgIGludCBudW1iZXIsIGludCBpbmRleCkgY29uc3QgeworICBtYXA8aW50LCBFeHRlbnNpb24+Ojpjb25zdF9pdGVyYXRvciBpdGVyID0gZXh0ZW5zaW9uc18uZmluZChudW1iZXIpOworICBHT09HTEVfQ0hFQ0soaXRlciAhPSBleHRlbnNpb25zXy5lbmQoKSkgPDwgIkluZGV4IG91dC1vZi1ib3VuZHMgKGZpZWxkIGlzIGVtcHR5KS4iOworICBHT09HTEVfRENIRUNLX1RZUEUoaXRlci0+c2Vjb25kLCBSRVBFQVRFRCwgTUVTU0FHRSk7CisgIHJldHVybiBpdGVyLT5zZWNvbmQucmVwZWF0ZWRfbWVzc2FnZV92YWx1ZS0+R2V0KGluZGV4KTsKK30KKworTWVzc2FnZUxpdGUqIEV4dGVuc2lvblNldDo6TXV0YWJsZVJlcGVhdGVkTWVzc2FnZShpbnQgbnVtYmVyLCBpbnQgaW5kZXgpIHsKKyAgbWFwPGludCwgRXh0ZW5zaW9uPjo6aXRlcmF0b3IgaXRlciA9IGV4dGVuc2lvbnNfLmZpbmQobnVtYmVyKTsKKyAgR09PR0xFX0NIRUNLKGl0ZXIgIT0gZXh0ZW5zaW9uc18uZW5kKCkpIDw8ICJJbmRleCBvdXQtb2YtYm91bmRzIChmaWVsZCBpcyBlbXB0eSkuIjsKKyAgR09PR0xFX0RDSEVDS19UWVBFKGl0ZXItPnNlY29uZCwgUkVQRUFURUQsIE1FU1NBR0UpOworICByZXR1cm4gaXRlci0+c2Vjb25kLnJlcGVhdGVkX21lc3NhZ2VfdmFsdWUtPk11dGFibGUoaW5kZXgpOworfQorCitNZXNzYWdlTGl0ZSogRXh0ZW5zaW9uU2V0OjpBZGRNZXNzYWdlKGludCBudW1iZXIsIEZpZWxkVHlwZSB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNZXNzYWdlTGl0ZSYgcHJvdG90eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgRXh0ZW5zaW9uKiBleHRlbnNpb247CisgIGlmIChNYXliZU5ld0V4dGVuc2lvbihudW1iZXIsIGRlc2NyaXB0b3IsICZleHRlbnNpb24pKSB7CisgICAgZXh0ZW5zaW9uLT50eXBlID0gdHlwZTsKKyAgICBHT09HTEVfRENIRUNLX0VRKGNwcF90eXBlKGV4dGVuc2lvbi0+dHlwZSksIFdpcmVGb3JtYXRMaXRlOjpDUFBUWVBFX01FU1NBR0UpOworICAgIGV4dGVuc2lvbi0+aXNfcmVwZWF0ZWQgPSB0cnVlOworICAgIGV4dGVuc2lvbi0+cmVwZWF0ZWRfbWVzc2FnZV92YWx1ZSA9CisgICAgICAgIEFyZW5hOjpDcmVhdGVNZXNzYWdlPFJlcGVhdGVkUHRyRmllbGQ8TWVzc2FnZUxpdGU+ID4oYXJlbmFfKTsKKyAgfSBlbHNlIHsKKyAgICBHT09HTEVfRENIRUNLX1RZUEUoKmV4dGVuc2lvbiwgUkVQRUFURUQsIE1FU1NBR0UpOworICB9CisKKyAgLy8gUmVwZWF0ZWRQdHJGaWVsZDxNZXNzYWdlTGl0ZT4gZG9lcyBub3Qga25vdyBob3cgdG8gQWRkKCkgc2luY2UgaXQgY2Fubm90CisgIC8vIGFsbG9jYXRlIGFuIGFic3RyYWN0IG9iamVjdCwgc28gd2UgaGF2ZSB0byBiZSB0cmlja3kuCisgIE1lc3NhZ2VMaXRlKiByZXN1bHQgPSBleHRlbnNpb24tPnJlcGVhdGVkX21lc3NhZ2VfdmFsdWUKKyAgICAgIC0+QWRkRnJvbUNsZWFyZWQ8R2VuZXJpY1R5cGVIYW5kbGVyPE1lc3NhZ2VMaXRlPiA+KCk7CisgIGlmIChyZXN1bHQgPT0gTlVMTCkgeworICAgIHJlc3VsdCA9IHByb3RvdHlwZS5OZXcoYXJlbmFfKTsKKyAgICBleHRlbnNpb24tPnJlcGVhdGVkX21lc3NhZ2VfdmFsdWUtPkFkZEFsbG9jYXRlZChyZXN1bHQpOworICB9CisgIHJldHVybiByZXN1bHQ7Cit9CisKKy8vIERlZmluZWQgaW4gZXh0ZW5zaW9uX3NldF9oZWF2eS5jYy4KKy8vIE1lc3NhZ2VMaXRlKiBFeHRlbnNpb25TZXQ6OkFkZE1lc3NhZ2UoaW50IG51bWJlciwgRmllbGRUeXBlIHR5cGUsCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlc2NyaXB0b3IqIG1lc3NhZ2VfdHlwZSwKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUZhY3RvcnkqIGZhY3RvcnkpCisKKyN1bmRlZiBHT09HTEVfRENIRUNLX1RZUEUKKwordm9pZCBFeHRlbnNpb25TZXQ6OlJlbW92ZUxhc3QoaW50IG51bWJlcikgeworICBtYXA8aW50LCBFeHRlbnNpb24+OjppdGVyYXRvciBpdGVyID0gZXh0ZW5zaW9uc18uZmluZChudW1iZXIpOworICBHT09HTEVfQ0hFQ0soaXRlciAhPSBleHRlbnNpb25zXy5lbmQoKSkgPDwgIkluZGV4IG91dC1vZi1ib3VuZHMgKGZpZWxkIGlzIGVtcHR5KS4iOworCisgIEV4dGVuc2lvbiogZXh0ZW5zaW9uID0gJml0ZXItPnNlY29uZDsKKyAgR09PR0xFX0RDSEVDSyhleHRlbnNpb24tPmlzX3JlcGVhdGVkKTsKKworICBzd2l0Y2goY3BwX3R5cGUoZXh0ZW5zaW9uLT50eXBlKSkgeworICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfSU5UMzI6CisgICAgICBleHRlbnNpb24tPnJlcGVhdGVkX2ludDMyX3ZhbHVlLT5SZW1vdmVMYXN0KCk7CisgICAgICBicmVhazsKKyAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpDUFBUWVBFX0lOVDY0OgorICAgICAgZXh0ZW5zaW9uLT5yZXBlYXRlZF9pbnQ2NF92YWx1ZS0+UmVtb3ZlTGFzdCgpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV9VSU5UMzI6CisgICAgICBleHRlbnNpb24tPnJlcGVhdGVkX3VpbnQzMl92YWx1ZS0+UmVtb3ZlTGFzdCgpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV9VSU5UNjQ6CisgICAgICBleHRlbnNpb24tPnJlcGVhdGVkX3VpbnQ2NF92YWx1ZS0+UmVtb3ZlTGFzdCgpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV9GTE9BVDoKKyAgICAgIGV4dGVuc2lvbi0+cmVwZWF0ZWRfZmxvYXRfdmFsdWUtPlJlbW92ZUxhc3QoKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfRE9VQkxFOgorICAgICAgZXh0ZW5zaW9uLT5yZXBlYXRlZF9kb3VibGVfdmFsdWUtPlJlbW92ZUxhc3QoKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfQk9PTDoKKyAgICAgIGV4dGVuc2lvbi0+cmVwZWF0ZWRfYm9vbF92YWx1ZS0+UmVtb3ZlTGFzdCgpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV9FTlVNOgorICAgICAgZXh0ZW5zaW9uLT5yZXBlYXRlZF9lbnVtX3ZhbHVlLT5SZW1vdmVMYXN0KCk7CisgICAgICBicmVhazsKKyAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpDUFBUWVBFX1NUUklORzoKKyAgICAgIGV4dGVuc2lvbi0+cmVwZWF0ZWRfc3RyaW5nX3ZhbHVlLT5SZW1vdmVMYXN0KCk7CisgICAgICBicmVhazsKKyAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpDUFBUWVBFX01FU1NBR0U6CisgICAgICBleHRlbnNpb24tPnJlcGVhdGVkX21lc3NhZ2VfdmFsdWUtPlJlbW92ZUxhc3QoKTsKKyAgICAgIGJyZWFrOworICB9Cit9CisKK01lc3NhZ2VMaXRlKiBFeHRlbnNpb25TZXQ6OlJlbGVhc2VMYXN0KGludCBudW1iZXIpIHsKKyAgbWFwPGludCwgRXh0ZW5zaW9uPjo6aXRlcmF0b3IgaXRlciA9IGV4dGVuc2lvbnNfLmZpbmQobnVtYmVyKTsKKyAgR09PR0xFX0NIRUNLKGl0ZXIgIT0gZXh0ZW5zaW9uc18uZW5kKCkpIDw8ICJJbmRleCBvdXQtb2YtYm91bmRzIChmaWVsZCBpcyBlbXB0eSkuIjsKKworICBFeHRlbnNpb24qIGV4dGVuc2lvbiA9ICZpdGVyLT5zZWNvbmQ7CisgIEdPT0dMRV9EQ0hFQ0soZXh0ZW5zaW9uLT5pc19yZXBlYXRlZCk7CisgIEdPT0dMRV9EQ0hFQ0soY3BwX3R5cGUoZXh0ZW5zaW9uLT50eXBlKSA9PSBXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV9NRVNTQUdFKTsKKyAgcmV0dXJuIGV4dGVuc2lvbi0+cmVwZWF0ZWRfbWVzc2FnZV92YWx1ZS0+UmVsZWFzZUxhc3QoKTsKK30KKwordm9pZCBFeHRlbnNpb25TZXQ6OlN3YXBFbGVtZW50cyhpbnQgbnVtYmVyLCBpbnQgaW5kZXgxLCBpbnQgaW5kZXgyKSB7CisgIG1hcDxpbnQsIEV4dGVuc2lvbj46Oml0ZXJhdG9yIGl0ZXIgPSBleHRlbnNpb25zXy5maW5kKG51bWJlcik7CisgIEdPT0dMRV9DSEVDSyhpdGVyICE9IGV4dGVuc2lvbnNfLmVuZCgpKSA8PCAiSW5kZXggb3V0LW9mLWJvdW5kcyAoZmllbGQgaXMgZW1wdHkpLiI7CisKKyAgRXh0ZW5zaW9uKiBleHRlbnNpb24gPSAmaXRlci0+c2Vjb25kOworICBHT09HTEVfRENIRUNLKGV4dGVuc2lvbi0+aXNfcmVwZWF0ZWQpOworCisgIHN3aXRjaChjcHBfdHlwZShleHRlbnNpb24tPnR5cGUpKSB7CisgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV9JTlQzMjoKKyAgICAgIGV4dGVuc2lvbi0+cmVwZWF0ZWRfaW50MzJfdmFsdWUtPlN3YXBFbGVtZW50cyhpbmRleDEsIGluZGV4Mik7CisgICAgICBicmVhazsKKyAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpDUFBUWVBFX0lOVDY0OgorICAgICAgZXh0ZW5zaW9uLT5yZXBlYXRlZF9pbnQ2NF92YWx1ZS0+U3dhcEVsZW1lbnRzKGluZGV4MSwgaW5kZXgyKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfVUlOVDMyOgorICAgICAgZXh0ZW5zaW9uLT5yZXBlYXRlZF91aW50MzJfdmFsdWUtPlN3YXBFbGVtZW50cyhpbmRleDEsIGluZGV4Mik7CisgICAgICBicmVhazsKKyAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpDUFBUWVBFX1VJTlQ2NDoKKyAgICAgIGV4dGVuc2lvbi0+cmVwZWF0ZWRfdWludDY0X3ZhbHVlLT5Td2FwRWxlbWVudHMoaW5kZXgxLCBpbmRleDIpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV9GTE9BVDoKKyAgICAgIGV4dGVuc2lvbi0+cmVwZWF0ZWRfZmxvYXRfdmFsdWUtPlN3YXBFbGVtZW50cyhpbmRleDEsIGluZGV4Mik7CisgICAgICBicmVhazsKKyAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpDUFBUWVBFX0RPVUJMRToKKyAgICAgIGV4dGVuc2lvbi0+cmVwZWF0ZWRfZG91YmxlX3ZhbHVlLT5Td2FwRWxlbWVudHMoaW5kZXgxLCBpbmRleDIpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV9CT09MOgorICAgICAgZXh0ZW5zaW9uLT5yZXBlYXRlZF9ib29sX3ZhbHVlLT5Td2FwRWxlbWVudHMoaW5kZXgxLCBpbmRleDIpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV9FTlVNOgorICAgICAgZXh0ZW5zaW9uLT5yZXBlYXRlZF9lbnVtX3ZhbHVlLT5Td2FwRWxlbWVudHMoaW5kZXgxLCBpbmRleDIpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV9TVFJJTkc6CisgICAgICBleHRlbnNpb24tPnJlcGVhdGVkX3N0cmluZ192YWx1ZS0+U3dhcEVsZW1lbnRzKGluZGV4MSwgaW5kZXgyKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfTUVTU0FHRToKKyAgICAgIGV4dGVuc2lvbi0+cmVwZWF0ZWRfbWVzc2FnZV92YWx1ZS0+U3dhcEVsZW1lbnRzKGluZGV4MSwgaW5kZXgyKTsKKyAgICAgIGJyZWFrOworICB9Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKwordm9pZCBFeHRlbnNpb25TZXQ6OkNsZWFyKCkgeworICBmb3IgKG1hcDxpbnQsIEV4dGVuc2lvbj46Oml0ZXJhdG9yIGl0ZXIgPSBleHRlbnNpb25zXy5iZWdpbigpOworICAgICAgIGl0ZXIgIT0gZXh0ZW5zaW9uc18uZW5kKCk7ICsraXRlcikgeworICAgIGl0ZXItPnNlY29uZC5DbGVhcigpOworICB9Cit9CisKK3ZvaWQgRXh0ZW5zaW9uU2V0OjpNZXJnZUZyb20oY29uc3QgRXh0ZW5zaW9uU2V0JiBvdGhlcikgeworICBmb3IgKG1hcDxpbnQsIEV4dGVuc2lvbj46OmNvbnN0X2l0ZXJhdG9yIGl0ZXIgPSBvdGhlci5leHRlbnNpb25zXy5iZWdpbigpOworICAgICAgIGl0ZXIgIT0gb3RoZXIuZXh0ZW5zaW9uc18uZW5kKCk7ICsraXRlcikgeworICAgIGNvbnN0IEV4dGVuc2lvbiYgb3RoZXJfZXh0ZW5zaW9uID0gaXRlci0+c2Vjb25kOworICAgIEludGVybmFsRXh0ZW5zaW9uTWVyZ2VGcm9tKGl0ZXItPmZpcnN0LCBvdGhlcl9leHRlbnNpb24pOworICB9Cit9CisKK3ZvaWQgRXh0ZW5zaW9uU2V0OjpJbnRlcm5hbEV4dGVuc2lvbk1lcmdlRnJvbSgKKyAgaW50IG51bWJlciwgY29uc3QgRXh0ZW5zaW9uJiBvdGhlcl9leHRlbnNpb24pIHsKKyAgaWYgKG90aGVyX2V4dGVuc2lvbi5pc19yZXBlYXRlZCkgeworICAgIEV4dGVuc2lvbiogZXh0ZW5zaW9uOworICAgIGJvb2wgaXNfbmV3ID0gTWF5YmVOZXdFeHRlbnNpb24obnVtYmVyLCBvdGhlcl9leHRlbnNpb24uZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZleHRlbnNpb24pOworICAgIGlmIChpc19uZXcpIHsKKyAgICAgIC8vIEV4dGVuc2lvbiBkaWQgbm90IGFscmVhZHkgZXhpc3QgaW4gc2V0LgorICAgICAgZXh0ZW5zaW9uLT50eXBlID0gb3RoZXJfZXh0ZW5zaW9uLnR5cGU7CisgICAgICBleHRlbnNpb24tPmlzX3BhY2tlZCA9IG90aGVyX2V4dGVuc2lvbi5pc19wYWNrZWQ7CisgICAgICBleHRlbnNpb24tPmlzX3JlcGVhdGVkID0gdHJ1ZTsKKyAgICB9IGVsc2UgeworICAgICAgR09PR0xFX0RDSEVDS19FUShleHRlbnNpb24tPnR5cGUsIG90aGVyX2V4dGVuc2lvbi50eXBlKTsKKyAgICAgIEdPT0dMRV9EQ0hFQ0tfRVEoZXh0ZW5zaW9uLT5pc19wYWNrZWQsIG90aGVyX2V4dGVuc2lvbi5pc19wYWNrZWQpOworICAgICAgR09PR0xFX0RDSEVDSyhleHRlbnNpb24tPmlzX3JlcGVhdGVkKTsKKyAgICB9CisKKyAgICBzd2l0Y2ggKGNwcF90eXBlKG90aGVyX2V4dGVuc2lvbi50eXBlKSkgeworI2RlZmluZSBIQU5ETEVfVFlQRShVUFBFUkNBU0UsIExPV0VSQ0FTRSwgUkVQRUFURURfVFlQRSkgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfIyNVUFBFUkNBU0U6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGlmIChpc19uZXcpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgIGV4dGVuc2lvbi0+cmVwZWF0ZWRfIyNMT1dFUkNBU0UjI192YWx1ZSA9ICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgIEFyZW5hOjpDcmVhdGVNZXNzYWdlPFJFUEVBVEVEX1RZUEUgPihhcmVuYV8pOyAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBleHRlbnNpb24tPnJlcGVhdGVkXyMjTE9XRVJDQVNFIyNfdmFsdWUtPk1lcmdlRnJvbSggICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAqb3RoZXJfZXh0ZW5zaW9uLnJlcGVhdGVkXyMjTE9XRVJDQVNFIyNfdmFsdWUpOyAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGJyZWFrOworCisgICAgICBIQU5ETEVfVFlQRSggIElOVDMyLCAgIGludDMyLCBSZXBlYXRlZEZpZWxkICAgPCAgaW50MzI+KTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgSU5UNjQsICAgaW50NjQsIFJlcGVhdGVkRmllbGQgICA8ICBpbnQ2ND4pOworICAgICAgSEFORExFX1RZUEUoIFVJTlQzMiwgIHVpbnQzMiwgUmVwZWF0ZWRGaWVsZCAgIDwgdWludDMyPik7CisgICAgICBIQU5ETEVfVFlQRSggVUlOVDY0LCAgdWludDY0LCBSZXBlYXRlZEZpZWxkICAgPCB1aW50NjQ+KTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgRkxPQVQsICAgZmxvYXQsIFJlcGVhdGVkRmllbGQgICA8ICBmbG9hdD4pOworICAgICAgSEFORExFX1RZUEUoIERPVUJMRSwgIGRvdWJsZSwgUmVwZWF0ZWRGaWVsZCAgIDwgZG91YmxlPik7CisgICAgICBIQU5ETEVfVFlQRSggICBCT09MLCAgICBib29sLCBSZXBlYXRlZEZpZWxkICAgPCAgIGJvb2w+KTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgIEVOVU0sICAgIGVudW0sIFJlcGVhdGVkRmllbGQgICA8ICAgIGludD4pOworICAgICAgSEFORExFX1RZUEUoIFNUUklORywgIHN0cmluZywgUmVwZWF0ZWRQdHJGaWVsZDwgc3RyaW5nPik7CisjdW5kZWYgSEFORExFX1RZUEUKKworICAgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgICBpZiAoaXNfbmV3KSB7CisgICAgICAgICAgZXh0ZW5zaW9uLT5yZXBlYXRlZF9tZXNzYWdlX3ZhbHVlID0KKyAgICAgICAgICAgICAgQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8UmVwZWF0ZWRQdHJGaWVsZDxNZXNzYWdlTGl0ZT4gPihhcmVuYV8pOworICAgICAgICB9CisgICAgICAgIC8vIFdlIGNhbid0IGNhbGwgUmVwZWF0ZWRQdHJGaWVsZDxNZXNzYWdlTGl0ZT46Ok1lcmdlRnJvbSgpIGJlY2F1c2UKKyAgICAgICAgLy8gaXQgd291bGQgYXR0ZW1wdCB0byBhbGxvY2F0ZSBuZXcgb2JqZWN0cy4KKyAgICAgICAgUmVwZWF0ZWRQdHJGaWVsZDxNZXNzYWdlTGl0ZT4qIG90aGVyX3JlcGVhdGVkX21lc3NhZ2UgPQorICAgICAgICAgICAgb3RoZXJfZXh0ZW5zaW9uLnJlcGVhdGVkX21lc3NhZ2VfdmFsdWU7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgb3RoZXJfcmVwZWF0ZWRfbWVzc2FnZS0+c2l6ZSgpOyBpKyspIHsKKyAgICAgICAgICBjb25zdCBNZXNzYWdlTGl0ZSYgb3RoZXJfbWVzc2FnZSA9IG90aGVyX3JlcGVhdGVkX21lc3NhZ2UtPkdldChpKTsKKyAgICAgICAgICBNZXNzYWdlTGl0ZSogdGFyZ2V0ID0gZXh0ZW5zaW9uLT5yZXBlYXRlZF9tZXNzYWdlX3ZhbHVlCisgICAgICAgICAgICAgICAgICAgLT5BZGRGcm9tQ2xlYXJlZDxHZW5lcmljVHlwZUhhbmRsZXI8TWVzc2FnZUxpdGU+ID4oKTsKKyAgICAgICAgICBpZiAodGFyZ2V0ID09IE5VTEwpIHsKKyAgICAgICAgICAgIHRhcmdldCA9IG90aGVyX21lc3NhZ2UuTmV3KGFyZW5hXyk7CisgICAgICAgICAgICBleHRlbnNpb24tPnJlcGVhdGVkX21lc3NhZ2VfdmFsdWUtPkFkZEFsbG9jYXRlZCh0YXJnZXQpOworICAgICAgICAgIH0KKyAgICAgICAgICB0YXJnZXQtPkNoZWNrVHlwZUFuZE1lcmdlRnJvbShvdGhlcl9tZXNzYWdlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgaWYgKCFvdGhlcl9leHRlbnNpb24uaXNfY2xlYXJlZCkgeworICAgICAgc3dpdGNoIChjcHBfdHlwZShvdGhlcl9leHRlbnNpb24udHlwZSkpIHsKKyNkZWZpbmUgSEFORExFX1RZUEUoVVBQRVJDQVNFLCBMT1dFUkNBU0UsIENBTUVMQ0FTRSkgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV8jI1VQUEVSQ0FTRTogICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICBTZXQjI0NBTUVMQ0FTRShudW1iZXIsIG90aGVyX2V4dGVuc2lvbi50eXBlLCAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICBvdGhlcl9leHRlbnNpb24uTE9XRVJDQVNFIyNfdmFsdWUsICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICBvdGhlcl9leHRlbnNpb24uZGVzY3JpcHRvcik7ICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICBicmVhazsKKworICAgICAgICBIQU5ETEVfVFlQRSggSU5UMzIsICBpbnQzMiwgIEludDMyKTsKKyAgICAgICAgSEFORExFX1RZUEUoIElOVDY0LCAgaW50NjQsICBJbnQ2NCk7CisgICAgICAgIEhBTkRMRV9UWVBFKFVJTlQzMiwgdWludDMyLCBVSW50MzIpOworICAgICAgICBIQU5ETEVfVFlQRShVSU5UNjQsIHVpbnQ2NCwgVUludDY0KTsKKyAgICAgICAgSEFORExFX1RZUEUoIEZMT0FULCAgZmxvYXQsICBGbG9hdCk7CisgICAgICAgIEhBTkRMRV9UWVBFKERPVUJMRSwgZG91YmxlLCBEb3VibGUpOworICAgICAgICBIQU5ETEVfVFlQRSggIEJPT0wsICAgYm9vbCwgICBCb29sKTsKKyAgICAgICAgSEFORExFX1RZUEUoICBFTlVNLCAgIGVudW0sICAgRW51bSk7CisjdW5kZWYgSEFORExFX1RZUEUKKyAgICAgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV9TVFJJTkc6CisgICAgICAgICAgU2V0U3RyaW5nKG51bWJlciwgb3RoZXJfZXh0ZW5zaW9uLnR5cGUsCisgICAgICAgICAgICAgICAgICAgICpvdGhlcl9leHRlbnNpb24uc3RyaW5nX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICBvdGhlcl9leHRlbnNpb24uZGVzY3JpcHRvcik7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfTUVTU0FHRTogeworICAgICAgICAgIEV4dGVuc2lvbiogZXh0ZW5zaW9uOworICAgICAgICAgIGJvb2wgaXNfbmV3ID0gTWF5YmVOZXdFeHRlbnNpb24obnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3RoZXJfZXh0ZW5zaW9uLmRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZXh0ZW5zaW9uKTsKKyAgICAgICAgICBpZiAoaXNfbmV3KSB7CisgICAgICAgICAgICBleHRlbnNpb24tPnR5cGUgPSBvdGhlcl9leHRlbnNpb24udHlwZTsKKyAgICAgICAgICAgIGV4dGVuc2lvbi0+aXNfcGFja2VkID0gb3RoZXJfZXh0ZW5zaW9uLmlzX3BhY2tlZDsKKyAgICAgICAgICAgIGV4dGVuc2lvbi0+aXNfcmVwZWF0ZWQgPSBmYWxzZTsKKyAgICAgICAgICAgIGlmIChvdGhlcl9leHRlbnNpb24uaXNfbGF6eSkgeworICAgICAgICAgICAgICBleHRlbnNpb24tPmlzX2xhenkgPSB0cnVlOworICAgICAgICAgICAgICBleHRlbnNpb24tPmxhenltZXNzYWdlX3ZhbHVlID0KKyAgICAgICAgICAgICAgICAgIG90aGVyX2V4dGVuc2lvbi5sYXp5bWVzc2FnZV92YWx1ZS0+TmV3KGFyZW5hXyk7CisgICAgICAgICAgICAgIGV4dGVuc2lvbi0+bGF6eW1lc3NhZ2VfdmFsdWUtPk1lcmdlRnJvbSgKKyAgICAgICAgICAgICAgICAgICpvdGhlcl9leHRlbnNpb24ubGF6eW1lc3NhZ2VfdmFsdWUpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgZXh0ZW5zaW9uLT5pc19sYXp5ID0gZmFsc2U7CisgICAgICAgICAgICAgIGV4dGVuc2lvbi0+bWVzc2FnZV92YWx1ZSA9CisgICAgICAgICAgICAgICAgICBvdGhlcl9leHRlbnNpb24ubWVzc2FnZV92YWx1ZS0+TmV3KGFyZW5hXyk7CisgICAgICAgICAgICAgIGV4dGVuc2lvbi0+bWVzc2FnZV92YWx1ZS0+Q2hlY2tUeXBlQW5kTWVyZ2VGcm9tKAorICAgICAgICAgICAgICAgICAgKm90aGVyX2V4dGVuc2lvbi5tZXNzYWdlX3ZhbHVlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgR09PR0xFX0RDSEVDS19FUShleHRlbnNpb24tPnR5cGUsIG90aGVyX2V4dGVuc2lvbi50eXBlKTsKKyAgICAgICAgICAgIEdPT0dMRV9EQ0hFQ0tfRVEoZXh0ZW5zaW9uLT5pc19wYWNrZWQsb3RoZXJfZXh0ZW5zaW9uLmlzX3BhY2tlZCk7CisgICAgICAgICAgICBHT09HTEVfRENIRUNLKCFleHRlbnNpb24tPmlzX3JlcGVhdGVkKTsKKyAgICAgICAgICAgIGlmIChvdGhlcl9leHRlbnNpb24uaXNfbGF6eSkgeworICAgICAgICAgICAgICBpZiAoZXh0ZW5zaW9uLT5pc19sYXp5KSB7CisgICAgICAgICAgICAgICAgZXh0ZW5zaW9uLT5sYXp5bWVzc2FnZV92YWx1ZS0+TWVyZ2VGcm9tKAorICAgICAgICAgICAgICAgICAgICAqb3RoZXJfZXh0ZW5zaW9uLmxhenltZXNzYWdlX3ZhbHVlKTsKKyAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBleHRlbnNpb24tPm1lc3NhZ2VfdmFsdWUtPkNoZWNrVHlwZUFuZE1lcmdlRnJvbSgKKyAgICAgICAgICAgICAgICAgICAgb3RoZXJfZXh0ZW5zaW9uLmxhenltZXNzYWdlX3ZhbHVlLT5HZXRNZXNzYWdlKAorICAgICAgICAgICAgICAgICAgICAgICAgKmV4dGVuc2lvbi0+bWVzc2FnZV92YWx1ZSkpOworICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICBpZiAoZXh0ZW5zaW9uLT5pc19sYXp5KSB7CisgICAgICAgICAgICAgICAgZXh0ZW5zaW9uLT5sYXp5bWVzc2FnZV92YWx1ZS0+TXV0YWJsZU1lc3NhZ2UoCisgICAgICAgICAgICAgICAgICAgICpvdGhlcl9leHRlbnNpb24ubWVzc2FnZV92YWx1ZSktPkNoZWNrVHlwZUFuZE1lcmdlRnJvbSgKKyAgICAgICAgICAgICAgICAgICAgICAgICpvdGhlcl9leHRlbnNpb24ubWVzc2FnZV92YWx1ZSk7CisgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgZXh0ZW5zaW9uLT5tZXNzYWdlX3ZhbHVlLT5DaGVja1R5cGVBbmRNZXJnZUZyb20oCisgICAgICAgICAgICAgICAgICAgICpvdGhlcl9leHRlbnNpb24ubWVzc2FnZV92YWx1ZSk7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9CisgICAgICAgICAgZXh0ZW5zaW9uLT5pc19jbGVhcmVkID0gZmFsc2U7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgIH0KK30KKwordm9pZCBFeHRlbnNpb25TZXQ6OlN3YXAoRXh0ZW5zaW9uU2V0KiB4KSB7CisgIGlmIChHZXRBcmVuYU5vVmlydHVhbCgpID09IHgtPkdldEFyZW5hTm9WaXJ0dWFsKCkpIHsKKyAgICBleHRlbnNpb25zXy5zd2FwKHgtPmV4dGVuc2lvbnNfKTsKKyAgfSBlbHNlIHsKKyAgICAvLyBUT0RPKGNmYWxsaW4sIHJvaGFuYW5pbCk6IFdlIG1heWJlIGFibGUgdG8gb3B0aW1pemUgYSBjYXNlIHdoZXJlIHdlIGFyZQorICAgIC8vIHN3YXBwaW5nIGZyb20gaGVhcCB0byBhcmVuYS1hbGxvY2F0ZWQgZXh0ZW5zaW9uIHNldCwgYnkganVzdCBPd24oKSdpbmcKKyAgICAvLyB0aGUgZXh0ZW5zaW9ucy4KKyAgICBFeHRlbnNpb25TZXQgZXh0ZW5zaW9uX3NldDsKKyAgICBleHRlbnNpb25fc2V0Lk1lcmdlRnJvbSgqeCk7CisgICAgeC0+Q2xlYXIoKTsKKyAgICB4LT5NZXJnZUZyb20oKnRoaXMpOworICAgIENsZWFyKCk7CisgICAgTWVyZ2VGcm9tKGV4dGVuc2lvbl9zZXQpOworICB9Cit9CisKK3ZvaWQgRXh0ZW5zaW9uU2V0OjpTd2FwRXh0ZW5zaW9uKEV4dGVuc2lvblNldCogb3RoZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbnVtYmVyKSB7CisgIGlmICh0aGlzID09IG90aGVyKSByZXR1cm47CisgIG1hcDxpbnQsIEV4dGVuc2lvbj46Oml0ZXJhdG9yIHRoaXNfaXRlciA9IGV4dGVuc2lvbnNfLmZpbmQobnVtYmVyKTsKKyAgbWFwPGludCwgRXh0ZW5zaW9uPjo6aXRlcmF0b3Igb3RoZXJfaXRlciA9IG90aGVyLT5leHRlbnNpb25zXy5maW5kKG51bWJlcik7CisKKyAgaWYgKHRoaXNfaXRlciA9PSBleHRlbnNpb25zXy5lbmQoKSAmJgorICAgICAgb3RoZXJfaXRlciA9PSBvdGhlci0+ZXh0ZW5zaW9uc18uZW5kKCkpIHsKKyAgICByZXR1cm47CisgIH0KKworICBpZiAodGhpc19pdGVyICE9IGV4dGVuc2lvbnNfLmVuZCgpICYmCisgICAgICBvdGhlcl9pdGVyICE9IG90aGVyLT5leHRlbnNpb25zXy5lbmQoKSkgeworICAgIGlmIChHZXRBcmVuYU5vVmlydHVhbCgpID09IG90aGVyLT5HZXRBcmVuYU5vVmlydHVhbCgpKSB7CisgICAgICB1c2luZyBzdGQ6OnN3YXA7CisgICAgICBzd2FwKHRoaXNfaXRlci0+c2Vjb25kLCBvdGhlcl9pdGVyLT5zZWNvbmQpOworICAgIH0gZWxzZSB7CisgICAgICAvLyBUT0RPKGNmYWxsaW4sIHJvaGFuYW5pbCk6IFdlIGNvdWxkIGZ1cnRoZXIgb3B0aW1pemUgdGhlc2UgY2FzZXMsCisgICAgICAvLyBlc3BlY2lhbGx5IGF2b2lkIGNyZWF0aW9uIG9mIEV4dGVuc2lvblNldCwgYW5kIG1vdmUgTWVyZ2VGcm9tIGxvZ2ljCisgICAgICAvLyBpbnRvIEV4dGVuc2lvbnMgaXRzZWxmICh3aGljaCB0YWtlcyBhcmVuYSBhcyBhbiBhcmd1bWVudCkuCisgICAgICAvLyBXZSBkbyBpdCB0aGlzIHdheSB0byByZXVzZSB0aGUgY29weS1hY3Jvc3MtYXJlbmFzIGxvZ2ljIGFscmVhZHkKKyAgICAgIC8vIGltcGxlbWVudGVkIGluIEV4dGVuc2lvblNldCdzIE1lcmdlRnJvbS4KKyAgICAgIEV4dGVuc2lvblNldCB0ZW1wOworICAgICAgdGVtcC5JbnRlcm5hbEV4dGVuc2lvbk1lcmdlRnJvbShudW1iZXIsIG90aGVyX2l0ZXItPnNlY29uZCk7CisgICAgICBtYXA8aW50LCBFeHRlbnNpb24+OjppdGVyYXRvciB0ZW1wX2l0ZXIgPSB0ZW1wLmV4dGVuc2lvbnNfLmZpbmQobnVtYmVyKTsKKyAgICAgIG90aGVyX2l0ZXItPnNlY29uZC5DbGVhcigpOworICAgICAgb3RoZXItPkludGVybmFsRXh0ZW5zaW9uTWVyZ2VGcm9tKG51bWJlciwgdGhpc19pdGVyLT5zZWNvbmQpOworICAgICAgdGhpc19pdGVyLT5zZWNvbmQuQ2xlYXIoKTsKKyAgICAgIEludGVybmFsRXh0ZW5zaW9uTWVyZ2VGcm9tKG51bWJlciwgdGVtcF9pdGVyLT5zZWNvbmQpOworICAgIH0KKyAgICByZXR1cm47CisgIH0KKworICBpZiAodGhpc19pdGVyID09IGV4dGVuc2lvbnNfLmVuZCgpKSB7CisgICAgaWYgKEdldEFyZW5hTm9WaXJ0dWFsKCkgPT0gb3RoZXItPkdldEFyZW5hTm9WaXJ0dWFsKCkpIHsKKyAgICAgIGV4dGVuc2lvbnNfLmluc2VydChzdGQ6Om1ha2VfcGFpcihudW1iZXIsIG90aGVyX2l0ZXItPnNlY29uZCkpOworICAgIH0gZWxzZSB7CisgICAgICBJbnRlcm5hbEV4dGVuc2lvbk1lcmdlRnJvbShudW1iZXIsIG90aGVyX2l0ZXItPnNlY29uZCk7CisgICAgfQorICAgIG90aGVyLT5leHRlbnNpb25zXy5lcmFzZShudW1iZXIpOworICAgIHJldHVybjsKKyAgfQorCisgIGlmIChvdGhlcl9pdGVyID09IG90aGVyLT5leHRlbnNpb25zXy5lbmQoKSkgeworICAgIGlmIChHZXRBcmVuYU5vVmlydHVhbCgpID09IG90aGVyLT5HZXRBcmVuYU5vVmlydHVhbCgpKSB7CisgICAgICBvdGhlci0+ZXh0ZW5zaW9uc18uaW5zZXJ0KHN0ZDo6bWFrZV9wYWlyKG51bWJlciwgdGhpc19pdGVyLT5zZWNvbmQpKTsKKyAgICB9IGVsc2UgeworICAgICAgb3RoZXItPkludGVybmFsRXh0ZW5zaW9uTWVyZ2VGcm9tKG51bWJlciwgdGhpc19pdGVyLT5zZWNvbmQpOworICAgIH0KKyAgICBleHRlbnNpb25zXy5lcmFzZShudW1iZXIpOworICAgIHJldHVybjsKKyAgfQorfQorCitib29sIEV4dGVuc2lvblNldDo6SXNJbml0aWFsaXplZCgpIGNvbnN0IHsKKyAgLy8gRXh0ZW5zaW9ucyBhcmUgbmV2ZXIgcmVxdWlyZWQuICBIb3dldmVyLCB3ZSBuZWVkIHRvIGNoZWNrIHRoYXQgYWxsCisgIC8vIGVtYmVkZGVkIG1lc3NhZ2VzIGFyZSBpbml0aWFsaXplZC4KKyAgZm9yIChtYXA8aW50LCBFeHRlbnNpb24+Ojpjb25zdF9pdGVyYXRvciBpdGVyID0gZXh0ZW5zaW9uc18uYmVnaW4oKTsKKyAgICAgICBpdGVyICE9IGV4dGVuc2lvbnNfLmVuZCgpOyArK2l0ZXIpIHsKKyAgICBjb25zdCBFeHRlbnNpb24mIGV4dGVuc2lvbiA9IGl0ZXItPnNlY29uZDsKKyAgICBpZiAoY3BwX3R5cGUoZXh0ZW5zaW9uLnR5cGUpID09IFdpcmVGb3JtYXRMaXRlOjpDUFBUWVBFX01FU1NBR0UpIHsKKyAgICAgIGlmIChleHRlbnNpb24uaXNfcmVwZWF0ZWQpIHsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBleHRlbnNpb24ucmVwZWF0ZWRfbWVzc2FnZV92YWx1ZS0+c2l6ZSgpOyBpKyspIHsKKyAgICAgICAgICBpZiAoIWV4dGVuc2lvbi5yZXBlYXRlZF9tZXNzYWdlX3ZhbHVlLT5HZXQoaSkuSXNJbml0aWFsaXplZCgpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9IGVsc2UgeworICAgICAgICBpZiAoIWV4dGVuc2lvbi5pc19jbGVhcmVkKSB7CisgICAgICAgICAgaWYgKGV4dGVuc2lvbi5pc19sYXp5KSB7CisgICAgICAgICAgICBpZiAoIWV4dGVuc2lvbi5sYXp5bWVzc2FnZV92YWx1ZS0+SXNJbml0aWFsaXplZCgpKSByZXR1cm4gZmFsc2U7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGlmICghZXh0ZW5zaW9uLm1lc3NhZ2VfdmFsdWUtPklzSW5pdGlhbGl6ZWQoKSkgcmV0dXJuIGZhbHNlOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgfQorCisgIHJldHVybiB0cnVlOworfQorCitib29sIEV4dGVuc2lvblNldDo6RmluZEV4dGVuc2lvbkluZm9Gcm9tVGFnKAorICAgIHVpbnQzMiB0YWcsIEV4dGVuc2lvbkZpbmRlciogZXh0ZW5zaW9uX2ZpbmRlciwgaW50KiBmaWVsZF9udW1iZXIsCisgICAgRXh0ZW5zaW9uSW5mbyogZXh0ZW5zaW9uLCBib29sKiB3YXNfcGFja2VkX29uX3dpcmUpIHsKKyAgKmZpZWxkX251bWJlciA9IFdpcmVGb3JtYXRMaXRlOjpHZXRUYWdGaWVsZE51bWJlcih0YWcpOworICBXaXJlRm9ybWF0TGl0ZTo6V2lyZVR5cGUgd2lyZV90eXBlID0gV2lyZUZvcm1hdExpdGU6OkdldFRhZ1dpcmVUeXBlKHRhZyk7CisgIHJldHVybiBGaW5kRXh0ZW5zaW9uSW5mb0Zyb21GaWVsZE51bWJlcih3aXJlX3R5cGUsICpmaWVsZF9udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25fZmluZGVyLCBleHRlbnNpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3YXNfcGFja2VkX29uX3dpcmUpOworfQorCitib29sIEV4dGVuc2lvblNldDo6RmluZEV4dGVuc2lvbkluZm9Gcm9tRmllbGROdW1iZXIoCisgICAgaW50IHdpcmVfdHlwZSwgaW50IGZpZWxkX251bWJlciwgRXh0ZW5zaW9uRmluZGVyKiBleHRlbnNpb25fZmluZGVyLAorICAgIEV4dGVuc2lvbkluZm8qIGV4dGVuc2lvbiwgYm9vbCogd2FzX3BhY2tlZF9vbl93aXJlKSB7CisgIGlmICghZXh0ZW5zaW9uX2ZpbmRlci0+RmluZChmaWVsZF9udW1iZXIsIGV4dGVuc2lvbikpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBXaXJlRm9ybWF0TGl0ZTo6V2lyZVR5cGUgZXhwZWN0ZWRfd2lyZV90eXBlID0KKyAgICAgIFdpcmVGb3JtYXRMaXRlOjpXaXJlVHlwZUZvckZpZWxkVHlwZShyZWFsX3R5cGUoZXh0ZW5zaW9uLT50eXBlKSk7CisKKyAgLy8gQ2hlY2sgaWYgdGhpcyBpcyBhIHBhY2tlZCBmaWVsZC4KKyAgKndhc19wYWNrZWRfb25fd2lyZSA9IGZhbHNlOworICBpZiAoZXh0ZW5zaW9uLT5pc19yZXBlYXRlZCAmJgorICAgICAgd2lyZV90eXBlID09IFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVEICYmCisgICAgICBpc19wYWNrYWJsZShleHBlY3RlZF93aXJlX3R5cGUpKSB7CisgICAgKndhc19wYWNrZWRfb25fd2lyZSA9IHRydWU7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKyAgLy8gT3RoZXJ3aXNlIHRoZSB3aXJlIHR5cGUgbXVzdCBtYXRjaC4KKyAgcmV0dXJuIGV4cGVjdGVkX3dpcmVfdHlwZSA9PSB3aXJlX3R5cGU7Cit9CisKK2Jvb2wgRXh0ZW5zaW9uU2V0OjpQYXJzZUZpZWxkKHVpbnQzMiB0YWcsIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4dGVuc2lvbkZpbmRlciogZXh0ZW5zaW9uX2ZpbmRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkU2tpcHBlciogZmllbGRfc2tpcHBlcikgeworICBpbnQgbnVtYmVyOworICBib29sIHdhc19wYWNrZWRfb25fd2lyZTsKKyAgRXh0ZW5zaW9uSW5mbyBleHRlbnNpb247CisgIGlmICghRmluZEV4dGVuc2lvbkluZm9Gcm9tVGFnKAorICAgICAgdGFnLCBleHRlbnNpb25fZmluZGVyLCAmbnVtYmVyLCAmZXh0ZW5zaW9uLCAmd2FzX3BhY2tlZF9vbl93aXJlKSkgeworICAgIHJldHVybiBmaWVsZF9za2lwcGVyLT5Ta2lwRmllbGQoaW5wdXQsIHRhZyk7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIFBhcnNlRmllbGRXaXRoRXh0ZW5zaW9uSW5mbygKKyAgICAgICAgbnVtYmVyLCB3YXNfcGFja2VkX29uX3dpcmUsIGV4dGVuc2lvbiwgaW5wdXQsIGZpZWxkX3NraXBwZXIpOworICB9Cit9CisKK2Jvb2wgRXh0ZW5zaW9uU2V0OjpQYXJzZUZpZWxkV2l0aEV4dGVuc2lvbkluZm8oCisgICAgaW50IG51bWJlciwgYm9vbCB3YXNfcGFja2VkX29uX3dpcmUsIGNvbnN0IEV4dGVuc2lvbkluZm8mIGV4dGVuc2lvbiwKKyAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsCisgICAgRmllbGRTa2lwcGVyKiBmaWVsZF9za2lwcGVyKSB7CisgIC8vIEV4cGxpY2l0bHkgbm90IHJlYWQgZXh0ZW5zaW9uLmlzX3BhY2tlZCwgaW5zdGVhZCBjaGVjayB3aGV0aGVyIHRoZSBmaWVsZAorICAvLyB3YXMgZW5jb2RlZCBpbiBwYWNrZWQgZm9ybSBvbiB0aGUgd2lyZS4KKyAgaWYgKHdhc19wYWNrZWRfb25fd2lyZSkgeworICAgIHVpbnQzMiBzaXplOworICAgIGlmICghaW5wdXQtPlJlYWRWYXJpbnQzMigmc2l6ZSkpIHJldHVybiBmYWxzZTsKKyAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbTo6TGltaXQgbGltaXQgPSBpbnB1dC0+UHVzaExpbWl0KHNpemUpOworCisgICAgc3dpdGNoIChleHRlbnNpb24udHlwZSkgeworI2RlZmluZSBIQU5ETEVfVFlQRShVUFBFUkNBU0UsIENQUF9DQU1FTENBU0UsIENQUF9MT1dFUkNBU0UpICAgICAgICBcCisgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpUWVBFXyMjVVBQRVJDQVNFOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICB3aGlsZSAoaW5wdXQtPkJ5dGVzVW50aWxMaW1pdCgpID4gMCkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICBDUFBfTE9XRVJDQVNFIHZhbHVlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgaWYgKCFXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgQ1BQX0xPV0VSQ0FTRSwgV2lyZUZvcm1hdExpdGU6OlRZUEVfIyNVUFBFUkNBU0U+KCAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICBpbnB1dCwgJnZhbHVlKSkgcmV0dXJuIGZhbHNlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgQWRkIyNDUFBfQ0FNRUxDQVNFKG51bWJlciwgV2lyZUZvcm1hdExpdGU6OlRZUEVfIyNVUFBFUkNBU0UsICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb24uaXNfcGFja2VkLCB2YWx1ZSwgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uLmRlc2NyaXB0b3IpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBicmVhaworCisgICAgICBIQU5ETEVfVFlQRSggICBJTlQzMiwgIEludDMyLCAgIGludDMyKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgIElOVDY0LCAgSW50NjQsICAgaW50NjQpOworICAgICAgSEFORExFX1RZUEUoICBVSU5UMzIsIFVJbnQzMiwgIHVpbnQzMik7CisgICAgICBIQU5ETEVfVFlQRSggIFVJTlQ2NCwgVUludDY0LCAgdWludDY0KTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgU0lOVDMyLCAgSW50MzIsICAgaW50MzIpOworICAgICAgSEFORExFX1RZUEUoICBTSU5UNjQsICBJbnQ2NCwgICBpbnQ2NCk7CisgICAgICBIQU5ETEVfVFlQRSggRklYRUQzMiwgVUludDMyLCAgdWludDMyKTsKKyAgICAgIEhBTkRMRV9UWVBFKCBGSVhFRDY0LCBVSW50NjQsICB1aW50NjQpOworICAgICAgSEFORExFX1RZUEUoU0ZJWEVEMzIsICBJbnQzMiwgICBpbnQzMik7CisgICAgICBIQU5ETEVfVFlQRShTRklYRUQ2NCwgIEludDY0LCAgIGludDY0KTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgIEZMT0FULCAgRmxvYXQsICAgZmxvYXQpOworICAgICAgSEFORExFX1RZUEUoICBET1VCTEUsIERvdWJsZSwgIGRvdWJsZSk7CisgICAgICBIQU5ETEVfVFlQRSggICAgQk9PTCwgICBCb29sLCAgICBib29sKTsKKyN1bmRlZiBIQU5ETEVfVFlQRQorCisgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpUWVBFX0VOVU06CisgICAgICAgIHdoaWxlIChpbnB1dC0+Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CisgICAgICAgICAgaW50IHZhbHVlOworICAgICAgICAgIGlmICghV2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8aW50LCBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9FTlVNPigKKyAgICAgICAgICAgICAgICAgIGlucHV0LCAmdmFsdWUpKSByZXR1cm4gZmFsc2U7CisgICAgICAgICAgaWYgKGV4dGVuc2lvbi5lbnVtX3ZhbGlkaXR5X2NoZWNrLmZ1bmMoCisgICAgICAgICAgICAgICAgICBleHRlbnNpb24uZW51bV92YWxpZGl0eV9jaGVjay5hcmcsIHZhbHVlKSkgeworICAgICAgICAgICAgQWRkRW51bShudW1iZXIsIFdpcmVGb3JtYXRMaXRlOjpUWVBFX0VOVU0sIGV4dGVuc2lvbi5pc19wYWNrZWQsCisgICAgICAgICAgICAgICAgICAgIHZhbHVlLCBleHRlbnNpb24uZGVzY3JpcHRvcik7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vIEludmFsaWQgdmFsdWUuICBUcmVhdCBhcyB1bmtub3duLgorICAgICAgICAgICAgZmllbGRfc2tpcHBlci0+U2tpcFVua25vd25FbnVtKG51bWJlciwgdmFsdWUpOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9TVFJJTkc6CisgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpUWVBFX0JZVEVTOgorICAgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9HUk9VUDoKKyAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OlRZUEVfTUVTU0FHRToKKyAgICAgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIk5vbi1wcmltaXRpdmUgdHlwZXMgY2FuJ3QgYmUgcGFja2VkLiI7CisgICAgICAgIGJyZWFrOworICAgIH0KKworICAgIGlucHV0LT5Qb3BMaW1pdChsaW1pdCk7CisgIH0gZWxzZSB7CisgICAgc3dpdGNoIChleHRlbnNpb24udHlwZSkgeworI2RlZmluZSBIQU5ETEVfVFlQRShVUFBFUkNBU0UsIENQUF9DQU1FTENBU0UsIENQUF9MT1dFUkNBU0UpICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OlRZUEVfIyNVUFBFUkNBU0U6IHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIENQUF9MT1dFUkNBU0UgdmFsdWU7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBpZiAoIVdpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICBDUFBfTE9XRVJDQVNFLCBXaXJlRm9ybWF0TGl0ZTo6VFlQRV8jI1VQUEVSQ0FTRT4oICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICBpbnB1dCwgJnZhbHVlKSkgcmV0dXJuIGZhbHNlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBpZiAoZXh0ZW5zaW9uLmlzX3JlcGVhdGVkKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICBBZGQjI0NQUF9DQU1FTENBU0UobnVtYmVyLCBXaXJlRm9ybWF0TGl0ZTo6VFlQRV8jI1VQUEVSQ0FTRSwgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbi5pc19wYWNrZWQsIHZhbHVlLCAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb24uZGVzY3JpcHRvcik7ICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgfSBlbHNlIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgU2V0IyNDUFBfQ0FNRUxDQVNFKG51bWJlciwgV2lyZUZvcm1hdExpdGU6OlRZUEVfIyNVUFBFUkNBU0UsIHZhbHVlLCAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb24uZGVzY3JpcHRvcik7ICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICB9IGJyZWFrCisKKyAgICAgIEhBTkRMRV9UWVBFKCAgIElOVDMyLCAgSW50MzIsICAgaW50MzIpOworICAgICAgSEFORExFX1RZUEUoICAgSU5UNjQsICBJbnQ2NCwgICBpbnQ2NCk7CisgICAgICBIQU5ETEVfVFlQRSggIFVJTlQzMiwgVUludDMyLCAgdWludDMyKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgVUlOVDY0LCBVSW50NjQsICB1aW50NjQpOworICAgICAgSEFORExFX1RZUEUoICBTSU5UMzIsICBJbnQzMiwgICBpbnQzMik7CisgICAgICBIQU5ETEVfVFlQRSggIFNJTlQ2NCwgIEludDY0LCAgIGludDY0KTsKKyAgICAgIEhBTkRMRV9UWVBFKCBGSVhFRDMyLCBVSW50MzIsICB1aW50MzIpOworICAgICAgSEFORExFX1RZUEUoIEZJWEVENjQsIFVJbnQ2NCwgIHVpbnQ2NCk7CisgICAgICBIQU5ETEVfVFlQRShTRklYRUQzMiwgIEludDMyLCAgIGludDMyKTsKKyAgICAgIEhBTkRMRV9UWVBFKFNGSVhFRDY0LCAgSW50NjQsICAgaW50NjQpOworICAgICAgSEFORExFX1RZUEUoICAgRkxPQVQsICBGbG9hdCwgICBmbG9hdCk7CisgICAgICBIQU5ETEVfVFlQRSggIERPVUJMRSwgRG91YmxlLCAgZG91YmxlKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgICBCT09MLCAgIEJvb2wsICAgIGJvb2wpOworI3VuZGVmIEhBTkRMRV9UWVBFCisKKyAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OlRZUEVfRU5VTTogeworICAgICAgICBpbnQgdmFsdWU7CisgICAgICAgIGlmICghV2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8aW50LCBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9FTlVNPigKKyAgICAgICAgICAgICAgICBpbnB1dCwgJnZhbHVlKSkgcmV0dXJuIGZhbHNlOworCisgICAgICAgIGlmICghZXh0ZW5zaW9uLmVudW1fdmFsaWRpdHlfY2hlY2suZnVuYygKKyAgICAgICAgICAgICAgICBleHRlbnNpb24uZW51bV92YWxpZGl0eV9jaGVjay5hcmcsIHZhbHVlKSkgeworICAgICAgICAgIC8vIEludmFsaWQgdmFsdWUuICBUcmVhdCBhcyB1bmtub3duLgorICAgICAgICAgIGZpZWxkX3NraXBwZXItPlNraXBVbmtub3duRW51bShudW1iZXIsIHZhbHVlKTsKKyAgICAgICAgfSBlbHNlIGlmIChleHRlbnNpb24uaXNfcmVwZWF0ZWQpIHsKKyAgICAgICAgICBBZGRFbnVtKG51bWJlciwgV2lyZUZvcm1hdExpdGU6OlRZUEVfRU5VTSwgZXh0ZW5zaW9uLmlzX3BhY2tlZCwgdmFsdWUsCisgICAgICAgICAgICAgICAgICBleHRlbnNpb24uZGVzY3JpcHRvcik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgU2V0RW51bShudW1iZXIsIFdpcmVGb3JtYXRMaXRlOjpUWVBFX0VOVU0sIHZhbHVlLAorICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uLmRlc2NyaXB0b3IpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpUWVBFX1NUUklORzogIHsKKyAgICAgICAgc3RyaW5nKiB2YWx1ZSA9IGV4dGVuc2lvbi5pc19yZXBlYXRlZCA/CisgICAgICAgICAgQWRkU3RyaW5nKG51bWJlciwgV2lyZUZvcm1hdExpdGU6OlRZUEVfU1RSSU5HLCBleHRlbnNpb24uZGVzY3JpcHRvcikgOgorICAgICAgICAgIE11dGFibGVTdHJpbmcobnVtYmVyLCBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9TVFJJTkcsCisgICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb24uZGVzY3JpcHRvcik7CisgICAgICAgIGlmICghV2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoaW5wdXQsIHZhbHVlKSkgcmV0dXJuIGZhbHNlOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9CWVRFUzogIHsKKyAgICAgICAgc3RyaW5nKiB2YWx1ZSA9IGV4dGVuc2lvbi5pc19yZXBlYXRlZCA/CisgICAgICAgICAgQWRkU3RyaW5nKG51bWJlciwgV2lyZUZvcm1hdExpdGU6OlRZUEVfQllURVMsIGV4dGVuc2lvbi5kZXNjcmlwdG9yKSA6CisgICAgICAgICAgTXV0YWJsZVN0cmluZyhudW1iZXIsIFdpcmVGb3JtYXRMaXRlOjpUWVBFX0JZVEVTLAorICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uLmRlc2NyaXB0b3IpOworICAgICAgICBpZiAoIVdpcmVGb3JtYXRMaXRlOjpSZWFkQnl0ZXMoaW5wdXQsIHZhbHVlKSkgcmV0dXJuIGZhbHNlOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9HUk9VUDogeworICAgICAgICBNZXNzYWdlTGl0ZSogdmFsdWUgPSBleHRlbnNpb24uaXNfcmVwZWF0ZWQgPworICAgICAgICAgICAgQWRkTWVzc2FnZShudW1iZXIsIFdpcmVGb3JtYXRMaXRlOjpUWVBFX0dST1VQLAorICAgICAgICAgICAgICAgICAgICAgICAqZXh0ZW5zaW9uLm1lc3NhZ2VfcHJvdG90eXBlLCBleHRlbnNpb24uZGVzY3JpcHRvcikgOgorICAgICAgICAgICAgTXV0YWJsZU1lc3NhZ2UobnVtYmVyLCBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9HUk9VUCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICpleHRlbnNpb24ubWVzc2FnZV9wcm90b3R5cGUsIGV4dGVuc2lvbi5kZXNjcmlwdG9yKTsKKyAgICAgICAgaWYgKCFXaXJlRm9ybWF0TGl0ZTo6UmVhZEdyb3VwKG51bWJlciwgaW5wdXQsIHZhbHVlKSkgcmV0dXJuIGZhbHNlOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9NRVNTQUdFOiB7CisgICAgICAgIE1lc3NhZ2VMaXRlKiB2YWx1ZSA9IGV4dGVuc2lvbi5pc19yZXBlYXRlZCA/CisgICAgICAgICAgICBBZGRNZXNzYWdlKG51bWJlciwgV2lyZUZvcm1hdExpdGU6OlRZUEVfTUVTU0FHRSwKKyAgICAgICAgICAgICAgICAgICAgICAgKmV4dGVuc2lvbi5tZXNzYWdlX3Byb3RvdHlwZSwgZXh0ZW5zaW9uLmRlc2NyaXB0b3IpIDoKKyAgICAgICAgICAgIE11dGFibGVNZXNzYWdlKG51bWJlciwgV2lyZUZvcm1hdExpdGU6OlRZUEVfTUVTU0FHRSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICpleHRlbnNpb24ubWVzc2FnZV9wcm90b3R5cGUsIGV4dGVuc2lvbi5kZXNjcmlwdG9yKTsKKyAgICAgICAgaWYgKCFXaXJlRm9ybWF0TGl0ZTo6UmVhZE1lc3NhZ2UoaW5wdXQsIHZhbHVlKSkgcmV0dXJuIGZhbHNlOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICByZXR1cm4gdHJ1ZTsKK30KKworYm9vbCBFeHRlbnNpb25TZXQ6OlBhcnNlRmllbGQodWludDMyIHRhZywgaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZUxpdGUqIGNvbnRhaW5pbmdfdHlwZSkgeworICBGaWVsZFNraXBwZXIgc2tpcHBlcjsKKyAgR2VuZXJhdGVkRXh0ZW5zaW9uRmluZGVyIGZpbmRlcihjb250YWluaW5nX3R5cGUpOworICByZXR1cm4gUGFyc2VGaWVsZCh0YWcsIGlucHV0LCAmZmluZGVyLCAmc2tpcHBlcik7Cit9CisKK2Jvb2wgRXh0ZW5zaW9uU2V0OjpQYXJzZUZpZWxkKHVpbnQzMiB0YWcsIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2VMaXRlKiBjb250YWluaW5nX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIHVua25vd25fZmllbGRzKSB7CisgIENvZGVkT3V0cHV0U3RyZWFtRmllbGRTa2lwcGVyIHNraXBwZXIodW5rbm93bl9maWVsZHMpOworICBHZW5lcmF0ZWRFeHRlbnNpb25GaW5kZXIgZmluZGVyKGNvbnRhaW5pbmdfdHlwZSk7CisgIHJldHVybiBQYXJzZUZpZWxkKHRhZywgaW5wdXQsICZmaW5kZXIsICZza2lwcGVyKTsKK30KKworLy8gRGVmaW5lZCBpbiBleHRlbnNpb25fc2V0X2hlYXZ5LmNjLgorLy8gYm9vbCBFeHRlbnNpb25TZXQ6OlBhcnNlRmllbGQodWludDMyIHRhZywgaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZUxpdGUqIGNvbnRhaW5pbmdfdHlwZSwKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVua25vd25GaWVsZFNldCogdW5rbm93bl9maWVsZHMpCisKKy8vIERlZmluZWQgaW4gZXh0ZW5zaW9uX3NldF9oZWF2eS5jYy4KKy8vIGJvb2wgRXh0ZW5zaW9uU2V0OjpQYXJzZU1lc3NhZ2VTZXQoaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNZXNzYWdlTGl0ZSogY29udGFpbmluZ190eXBlLAorLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVbmtub3duRmllbGRTZXQqIHVua25vd25fZmllbGRzKTsKKwordm9pZCBFeHRlbnNpb25TZXQ6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICBpbnQgc3RhcnRfZmllbGRfbnVtYmVyLCBpbnQgZW5kX2ZpZWxkX251bWJlciwKKyAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3QgeworICBtYXA8aW50LCBFeHRlbnNpb24+Ojpjb25zdF9pdGVyYXRvciBpdGVyOworICBmb3IgKGl0ZXIgPSBleHRlbnNpb25zXy5sb3dlcl9ib3VuZChzdGFydF9maWVsZF9udW1iZXIpOworICAgICAgIGl0ZXIgIT0gZXh0ZW5zaW9uc18uZW5kKCkgJiYgaXRlci0+Zmlyc3QgPCBlbmRfZmllbGRfbnVtYmVyOworICAgICAgICsraXRlcikgeworICAgIGl0ZXItPnNlY29uZC5TZXJpYWxpemVGaWVsZFdpdGhDYWNoZWRTaXplcyhpdGVyLT5maXJzdCwgb3V0cHV0KTsKKyAgfQorfQorCitpbnQgRXh0ZW5zaW9uU2V0OjpCeXRlU2l6ZSgpIGNvbnN0IHsKKyAgaW50IHRvdGFsX3NpemUgPSAwOworCisgIGZvciAobWFwPGludCwgRXh0ZW5zaW9uPjo6Y29uc3RfaXRlcmF0b3IgaXRlciA9IGV4dGVuc2lvbnNfLmJlZ2luKCk7CisgICAgICAgaXRlciAhPSBleHRlbnNpb25zXy5lbmQoKTsgKytpdGVyKSB7CisgICAgdG90YWxfc2l6ZSArPSBpdGVyLT5zZWNvbmQuQnl0ZVNpemUoaXRlci0+Zmlyc3QpOworICB9CisKKyAgcmV0dXJuIHRvdGFsX3NpemU7Cit9CisKKy8vIERlZmluZWQgaW4gZXh0ZW5zaW9uX3NldF9oZWF2eS5jYy4KKy8vIGludCBFeHRlbnNpb25TZXQ6OlNwYWNlVXNlZEV4Y2x1ZGluZ1NlbGYoKSBjb25zdAorCitib29sIEV4dGVuc2lvblNldDo6TWF5YmVOZXdFeHRlbnNpb24oaW50IG51bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXh0ZW5zaW9uKiogcmVzdWx0KSB7CisgIHBhaXI8bWFwPGludCwgRXh0ZW5zaW9uPjo6aXRlcmF0b3IsIGJvb2w+IGluc2VydF9yZXN1bHQgPQorICAgICAgZXh0ZW5zaW9uc18uaW5zZXJ0KHN0ZDo6bWFrZV9wYWlyKG51bWJlciwgRXh0ZW5zaW9uKCkpKTsKKyAgKnJlc3VsdCA9ICZpbnNlcnRfcmVzdWx0LmZpcnN0LT5zZWNvbmQ7CisgICgqcmVzdWx0KS0+ZGVzY3JpcHRvciA9IGRlc2NyaXB0b3I7CisgIHJldHVybiBpbnNlcnRfcmVzdWx0LnNlY29uZDsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorLy8gTWV0aG9kcyBvZiBFeHRlbnNpb25TZXQ6OkV4dGVuc2lvbgorCit2b2lkIEV4dGVuc2lvblNldDo6RXh0ZW5zaW9uOjpDbGVhcigpIHsKKyAgaWYgKGlzX3JlcGVhdGVkKSB7CisgICAgc3dpdGNoIChjcHBfdHlwZSh0eXBlKSkgeworI2RlZmluZSBIQU5ETEVfVFlQRShVUFBFUkNBU0UsIExPV0VSQ0FTRSkgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfIyNVUFBFUkNBU0U6ICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIHJlcGVhdGVkXyMjTE9XRVJDQVNFIyNfdmFsdWUtPkNsZWFyKCk7ICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBicmVhaworCisgICAgICBIQU5ETEVfVFlQRSggIElOVDMyLCAgIGludDMyKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgSU5UNjQsICAgaW50NjQpOworICAgICAgSEFORExFX1RZUEUoIFVJTlQzMiwgIHVpbnQzMik7CisgICAgICBIQU5ETEVfVFlQRSggVUlOVDY0LCAgdWludDY0KTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgRkxPQVQsICAgZmxvYXQpOworICAgICAgSEFORExFX1RZUEUoIERPVUJMRSwgIGRvdWJsZSk7CisgICAgICBIQU5ETEVfVFlQRSggICBCT09MLCAgICBib29sKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgIEVOVU0sICAgIGVudW0pOworICAgICAgSEFORExFX1RZUEUoIFNUUklORywgIHN0cmluZyk7CisgICAgICBIQU5ETEVfVFlQRShNRVNTQUdFLCBtZXNzYWdlKTsKKyN1bmRlZiBIQU5ETEVfVFlQRQorICAgIH0KKyAgfSBlbHNlIHsKKyAgICBpZiAoIWlzX2NsZWFyZWQpIHsKKyAgICAgIHN3aXRjaCAoY3BwX3R5cGUodHlwZSkpIHsKKyAgICAgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV9TVFJJTkc6CisgICAgICAgICAgc3RyaW5nX3ZhbHVlLT5jbGVhcigpOworICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpDUFBUWVBFX01FU1NBR0U6CisgICAgICAgICAgaWYgKGlzX2xhenkpIHsKKyAgICAgICAgICAgIGxhenltZXNzYWdlX3ZhbHVlLT5DbGVhcigpOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBtZXNzYWdlX3ZhbHVlLT5DbGVhcigpOworICAgICAgICAgIH0KKyAgICAgICAgICBicmVhazsKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAvLyBObyBuZWVkIHRvIGRvIGFueXRoaW5nLiAgR2V0KigpIHdpbGwgcmV0dXJuIHRoZSBkZWZhdWx0IHZhbHVlCisgICAgICAgICAgLy8gYXMgbG9uZyBhcyBpc19jbGVhcmVkIGlzIHRydWUgYW5kIFNldCooKSB3aWxsIG92ZXJ3cml0ZSB0aGUKKyAgICAgICAgICAvLyBwcmV2aW91cyB2YWx1ZS4KKyAgICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgaXNfY2xlYXJlZCA9IHRydWU7CisgICAgfQorICB9Cit9CisKK3ZvaWQgRXh0ZW5zaW9uU2V0OjpFeHRlbnNpb246OlNlcmlhbGl6ZUZpZWxkV2l0aENhY2hlZFNpemVzKAorICAgIGludCBudW1iZXIsCisgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0IHsKKyAgaWYgKGlzX3JlcGVhdGVkKSB7CisgICAgaWYgKGlzX3BhY2tlZCkgeworICAgICAgaWYgKGNhY2hlZF9zaXplID09IDApIHJldHVybjsKKworICAgICAgV2lyZUZvcm1hdExpdGU6OldyaXRlVGFnKG51bWJlciwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCwgb3V0cHV0KTsKKyAgICAgIG91dHB1dC0+V3JpdGVWYXJpbnQzMihjYWNoZWRfc2l6ZSk7CisKKyAgICAgIHN3aXRjaCAocmVhbF90eXBlKHR5cGUpKSB7CisjZGVmaW5lIEhBTkRMRV9UWVBFKFVQUEVSQ0FTRSwgQ0FNRUxDQVNFLCBMT1dFUkNBU0UpICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpUWVBFXyMjVVBQRVJDQVNFOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkXyMjTE9XRVJDQVNFIyNfdmFsdWUtPnNpemUoKTsgaSsrKSB7ICBcCisgICAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6V3JpdGUjI0NBTUVMQ0FTRSMjTm9UYWcoICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICByZXBlYXRlZF8jI0xPV0VSQ0FTRSMjX3ZhbHVlLT5HZXQoaSksIG91dHB1dCk7ICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgYnJlYWsKKworICAgICAgICBIQU5ETEVfVFlQRSggICBJTlQzMiwgICAgSW50MzIsICAgaW50MzIpOworICAgICAgICBIQU5ETEVfVFlQRSggICBJTlQ2NCwgICAgSW50NjQsICAgaW50NjQpOworICAgICAgICBIQU5ETEVfVFlQRSggIFVJTlQzMiwgICBVSW50MzIsICB1aW50MzIpOworICAgICAgICBIQU5ETEVfVFlQRSggIFVJTlQ2NCwgICBVSW50NjQsICB1aW50NjQpOworICAgICAgICBIQU5ETEVfVFlQRSggIFNJTlQzMiwgICBTSW50MzIsICAgaW50MzIpOworICAgICAgICBIQU5ETEVfVFlQRSggIFNJTlQ2NCwgICBTSW50NjQsICAgaW50NjQpOworICAgICAgICBIQU5ETEVfVFlQRSggRklYRUQzMiwgIEZpeGVkMzIsICB1aW50MzIpOworICAgICAgICBIQU5ETEVfVFlQRSggRklYRUQ2NCwgIEZpeGVkNjQsICB1aW50NjQpOworICAgICAgICBIQU5ETEVfVFlQRShTRklYRUQzMiwgU0ZpeGVkMzIsICAgaW50MzIpOworICAgICAgICBIQU5ETEVfVFlQRShTRklYRUQ2NCwgU0ZpeGVkNjQsICAgaW50NjQpOworICAgICAgICBIQU5ETEVfVFlQRSggICBGTE9BVCwgICAgRmxvYXQsICAgZmxvYXQpOworICAgICAgICBIQU5ETEVfVFlQRSggIERPVUJMRSwgICBEb3VibGUsICBkb3VibGUpOworICAgICAgICBIQU5ETEVfVFlQRSggICAgQk9PTCwgICAgIEJvb2wsICAgIGJvb2wpOworICAgICAgICBIQU5ETEVfVFlQRSggICAgRU5VTSwgICAgIEVudW0sICAgIGVudW0pOworI3VuZGVmIEhBTkRMRV9UWVBFCisKKyAgICAgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9TVFJJTkc6CisgICAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OlRZUEVfQllURVM6CisgICAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OlRZUEVfR1JPVVA6CisgICAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OlRZUEVfTUVTU0FHRToKKyAgICAgICAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiTm9uLXByaW1pdGl2ZSB0eXBlcyBjYW4ndCBiZSBwYWNrZWQuIjsKKyAgICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgc3dpdGNoIChyZWFsX3R5cGUodHlwZSkpIHsKKyNkZWZpbmUgSEFORExFX1RZUEUoVVBQRVJDQVNFLCBDQU1FTENBU0UsIExPV0VSQ0FTRSkgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OlRZUEVfIyNVUFBFUkNBU0U6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRfIyNMT1dFUkNBU0UjI192YWx1ZS0+c2l6ZSgpOyBpKyspIHsgIFwKKyAgICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpXcml0ZSMjQ0FNRUxDQVNFKG51bWJlciwgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgIHJlcGVhdGVkXyMjTE9XRVJDQVNFIyNfdmFsdWUtPkdldChpKSwgb3V0cHV0KTsgICAgICAgICAgICAgICAgXAorICAgICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICBicmVhaworCisgICAgICAgIEhBTkRMRV9UWVBFKCAgIElOVDMyLCAgICBJbnQzMiwgICBpbnQzMik7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgIElOVDY0LCAgICBJbnQ2NCwgICBpbnQ2NCk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgVUlOVDMyLCAgIFVJbnQzMiwgIHVpbnQzMik7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgVUlOVDY0LCAgIFVJbnQ2NCwgIHVpbnQ2NCk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgU0lOVDMyLCAgIFNJbnQzMiwgICBpbnQzMik7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgU0lOVDY0LCAgIFNJbnQ2NCwgICBpbnQ2NCk7CisgICAgICAgIEhBTkRMRV9UWVBFKCBGSVhFRDMyLCAgRml4ZWQzMiwgIHVpbnQzMik7CisgICAgICAgIEhBTkRMRV9UWVBFKCBGSVhFRDY0LCAgRml4ZWQ2NCwgIHVpbnQ2NCk7CisgICAgICAgIEhBTkRMRV9UWVBFKFNGSVhFRDMyLCBTRml4ZWQzMiwgICBpbnQzMik7CisgICAgICAgIEhBTkRMRV9UWVBFKFNGSVhFRDY0LCBTRml4ZWQ2NCwgICBpbnQ2NCk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgIEZMT0FULCAgICBGbG9hdCwgICBmbG9hdCk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgRE9VQkxFLCAgIERvdWJsZSwgIGRvdWJsZSk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgICBCT09MLCAgICAgQm9vbCwgICAgYm9vbCk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgU1RSSU5HLCAgIFN0cmluZywgIHN0cmluZyk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgIEJZVEVTLCAgICBCeXRlcywgIHN0cmluZyk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgICBFTlVNLCAgICAgRW51bSwgICAgZW51bSk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgIEdST1VQLCAgICBHcm91cCwgbWVzc2FnZSk7CisgICAgICAgIEhBTkRMRV9UWVBFKCBNRVNTQUdFLCAgTWVzc2FnZSwgbWVzc2FnZSk7CisjdW5kZWYgSEFORExFX1RZUEUKKyAgICAgIH0KKyAgICB9CisgIH0gZWxzZSBpZiAoIWlzX2NsZWFyZWQpIHsKKyAgICBzd2l0Y2ggKHJlYWxfdHlwZSh0eXBlKSkgeworI2RlZmluZSBIQU5ETEVfVFlQRShVUFBFUkNBU0UsIENBTUVMQ0FTRSwgVkFMVUUpICAgICAgICAgICAgICAgICBcCisgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpUWVBFXyMjVVBQRVJDQVNFOiAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgV2lyZUZvcm1hdExpdGU6OldyaXRlIyNDQU1FTENBU0UobnVtYmVyLCBWQUxVRSwgb3V0cHV0KTsgXAorICAgICAgICBicmVhaworCisgICAgICBIQU5ETEVfVFlQRSggICBJTlQzMiwgICAgSW50MzIsICAgIGludDMyX3ZhbHVlKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgIElOVDY0LCAgICBJbnQ2NCwgICAgaW50NjRfdmFsdWUpOworICAgICAgSEFORExFX1RZUEUoICBVSU5UMzIsICAgVUludDMyLCAgIHVpbnQzMl92YWx1ZSk7CisgICAgICBIQU5ETEVfVFlQRSggIFVJTlQ2NCwgICBVSW50NjQsICAgdWludDY0X3ZhbHVlKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgU0lOVDMyLCAgIFNJbnQzMiwgICAgaW50MzJfdmFsdWUpOworICAgICAgSEFORExFX1RZUEUoICBTSU5UNjQsICAgU0ludDY0LCAgICBpbnQ2NF92YWx1ZSk7CisgICAgICBIQU5ETEVfVFlQRSggRklYRUQzMiwgIEZpeGVkMzIsICAgdWludDMyX3ZhbHVlKTsKKyAgICAgIEhBTkRMRV9UWVBFKCBGSVhFRDY0LCAgRml4ZWQ2NCwgICB1aW50NjRfdmFsdWUpOworICAgICAgSEFORExFX1RZUEUoU0ZJWEVEMzIsIFNGaXhlZDMyLCAgICBpbnQzMl92YWx1ZSk7CisgICAgICBIQU5ETEVfVFlQRShTRklYRUQ2NCwgU0ZpeGVkNjQsICAgIGludDY0X3ZhbHVlKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgIEZMT0FULCAgICBGbG9hdCwgICAgZmxvYXRfdmFsdWUpOworICAgICAgSEFORExFX1RZUEUoICBET1VCTEUsICAgRG91YmxlLCAgIGRvdWJsZV92YWx1ZSk7CisgICAgICBIQU5ETEVfVFlQRSggICAgQk9PTCwgICAgIEJvb2wsICAgICBib29sX3ZhbHVlKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgU1RSSU5HLCAgIFN0cmluZywgICpzdHJpbmdfdmFsdWUpOworICAgICAgSEFORExFX1RZUEUoICAgQllURVMsICAgIEJ5dGVzLCAgKnN0cmluZ192YWx1ZSk7CisgICAgICBIQU5ETEVfVFlQRSggICAgRU5VTSwgICAgIEVudW0sICAgICBlbnVtX3ZhbHVlKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgIEdST1VQLCAgICBHcm91cCwgKm1lc3NhZ2VfdmFsdWUpOworI3VuZGVmIEhBTkRMRV9UWVBFCisgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpUWVBFX01FU1NBR0U6CisgICAgICAgIGlmIChpc19sYXp5KSB7CisgICAgICAgICAgbGF6eW1lc3NhZ2VfdmFsdWUtPldyaXRlTWVzc2FnZShudW1iZXIsIG91dHB1dCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OldyaXRlTWVzc2FnZShudW1iZXIsICptZXNzYWdlX3ZhbHVlLCBvdXRwdXQpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgIH0KKyAgfQorfQorCitpbnQgRXh0ZW5zaW9uU2V0OjpFeHRlbnNpb246OkJ5dGVTaXplKGludCBudW1iZXIpIGNvbnN0IHsKKyAgaW50IHJlc3VsdCA9IDA7CisKKyAgaWYgKGlzX3JlcGVhdGVkKSB7CisgICAgaWYgKGlzX3BhY2tlZCkgeworICAgICAgc3dpdGNoIChyZWFsX3R5cGUodHlwZSkpIHsKKyNkZWZpbmUgSEFORExFX1RZUEUoVVBQRVJDQVNFLCBDQU1FTENBU0UsIExPV0VSQ0FTRSkgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OlRZUEVfIyNVUFBFUkNBU0U6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRfIyNMT1dFUkNBU0UjI192YWx1ZS0+c2l6ZSgpOyBpKyspIHsgIFwKKyAgICAgICAgICAgIHJlc3VsdCArPSBXaXJlRm9ybWF0TGl0ZTo6Q0FNRUxDQVNFIyNTaXplKCAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgIHJlcGVhdGVkXyMjTE9XRVJDQVNFIyNfdmFsdWUtPkdldChpKSk7ICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICBicmVhaworCisgICAgICAgIEhBTkRMRV9UWVBFKCAgIElOVDMyLCAgICBJbnQzMiwgICBpbnQzMik7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgIElOVDY0LCAgICBJbnQ2NCwgICBpbnQ2NCk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgVUlOVDMyLCAgIFVJbnQzMiwgIHVpbnQzMik7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgVUlOVDY0LCAgIFVJbnQ2NCwgIHVpbnQ2NCk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgU0lOVDMyLCAgIFNJbnQzMiwgICBpbnQzMik7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgU0lOVDY0LCAgIFNJbnQ2NCwgICBpbnQ2NCk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgICBFTlVNLCAgICAgRW51bSwgICAgZW51bSk7CisjdW5kZWYgSEFORExFX1RZUEUKKworICAgICAgICAvLyBTdHVmZiB3aXRoIGZpeGVkIHNpemUuCisjZGVmaW5lIEhBTkRMRV9UWVBFKFVQUEVSQ0FTRSwgQ0FNRUxDQVNFLCBMT1dFUkNBU0UpICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpUWVBFXyMjVVBQRVJDQVNFOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICByZXN1bHQgKz0gV2lyZUZvcm1hdExpdGU6OmsjI0NBTUVMQ0FTRSMjU2l6ZSAqICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgIHJlcGVhdGVkXyMjTE9XRVJDQVNFIyNfdmFsdWUtPnNpemUoKTsgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgIGJyZWFrCisgICAgICAgIEhBTkRMRV9UWVBFKCBGSVhFRDMyLCAgRml4ZWQzMiwgdWludDMyKTsKKyAgICAgICAgSEFORExFX1RZUEUoIEZJWEVENjQsICBGaXhlZDY0LCB1aW50NjQpOworICAgICAgICBIQU5ETEVfVFlQRShTRklYRUQzMiwgU0ZpeGVkMzIsICBpbnQzMik7CisgICAgICAgIEhBTkRMRV9UWVBFKFNGSVhFRDY0LCBTRml4ZWQ2NCwgIGludDY0KTsKKyAgICAgICAgSEFORExFX1RZUEUoICAgRkxPQVQsICAgIEZsb2F0LCAgZmxvYXQpOworICAgICAgICBIQU5ETEVfVFlQRSggIERPVUJMRSwgICBEb3VibGUsIGRvdWJsZSk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgICBCT09MLCAgICAgQm9vbCwgICBib29sKTsKKyN1bmRlZiBIQU5ETEVfVFlQRQorCisgICAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OlRZUEVfU1RSSU5HOgorICAgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpUWVBFX0JZVEVTOgorICAgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpUWVBFX0dST1VQOgorICAgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpUWVBFX01FU1NBR0U6CisgICAgICAgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIk5vbi1wcmltaXRpdmUgdHlwZXMgY2FuJ3QgYmUgcGFja2VkLiI7CisgICAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGNhY2hlZF9zaXplID0gcmVzdWx0OworICAgICAgaWYgKHJlc3VsdCA+IDApIHsKKyAgICAgICAgcmVzdWx0ICs9IGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6VmFyaW50U2l6ZTMyKHJlc3VsdCk7CisgICAgICAgIHJlc3VsdCArPSBpbzo6Q29kZWRPdXRwdXRTdHJlYW06OlZhcmludFNpemUzMigKKyAgICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpNYWtlVGFnKG51bWJlciwKKyAgICAgICAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCkpOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICBpbnQgdGFnX3NpemUgPSBXaXJlRm9ybWF0TGl0ZTo6VGFnU2l6ZShudW1iZXIsIHJlYWxfdHlwZSh0eXBlKSk7CisKKyAgICAgIHN3aXRjaCAocmVhbF90eXBlKHR5cGUpKSB7CisjZGVmaW5lIEhBTkRMRV9UWVBFKFVQUEVSQ0FTRSwgQ0FNRUxDQVNFLCBMT1dFUkNBU0UpICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpUWVBFXyMjVVBQRVJDQVNFOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICByZXN1bHQgKz0gdGFnX3NpemUgKiByZXBlYXRlZF8jI0xPV0VSQ0FTRSMjX3ZhbHVlLT5zaXplKCk7ICAgICAgICBcCisgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZF8jI0xPV0VSQ0FTRSMjX3ZhbHVlLT5zaXplKCk7IGkrKykgeyAgXAorICAgICAgICAgICAgcmVzdWx0ICs9IFdpcmVGb3JtYXRMaXRlOjpDQU1FTENBU0UjI1NpemUoICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgcmVwZWF0ZWRfIyNMT1dFUkNBU0UjI192YWx1ZS0+R2V0KGkpKTsgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgIGJyZWFrCisKKyAgICAgICAgSEFORExFX1RZUEUoICAgSU5UMzIsICAgIEludDMyLCAgIGludDMyKTsKKyAgICAgICAgSEFORExFX1RZUEUoICAgSU5UNjQsICAgIEludDY0LCAgIGludDY0KTsKKyAgICAgICAgSEFORExFX1RZUEUoICBVSU5UMzIsICAgVUludDMyLCAgdWludDMyKTsKKyAgICAgICAgSEFORExFX1RZUEUoICBVSU5UNjQsICAgVUludDY0LCAgdWludDY0KTsKKyAgICAgICAgSEFORExFX1RZUEUoICBTSU5UMzIsICAgU0ludDMyLCAgIGludDMyKTsKKyAgICAgICAgSEFORExFX1RZUEUoICBTSU5UNjQsICAgU0ludDY0LCAgIGludDY0KTsKKyAgICAgICAgSEFORExFX1RZUEUoICBTVFJJTkcsICAgU3RyaW5nLCAgc3RyaW5nKTsKKyAgICAgICAgSEFORExFX1RZUEUoICAgQllURVMsICAgIEJ5dGVzLCAgc3RyaW5nKTsKKyAgICAgICAgSEFORExFX1RZUEUoICAgIEVOVU0sICAgICBFbnVtLCAgICBlbnVtKTsKKyAgICAgICAgSEFORExFX1RZUEUoICAgR1JPVVAsICAgIEdyb3VwLCBtZXNzYWdlKTsKKyAgICAgICAgSEFORExFX1RZUEUoIE1FU1NBR0UsICBNZXNzYWdlLCBtZXNzYWdlKTsKKyN1bmRlZiBIQU5ETEVfVFlQRQorCisgICAgICAgIC8vIFN0dWZmIHdpdGggZml4ZWQgc2l6ZS4KKyNkZWZpbmUgSEFORExFX1RZUEUoVVBQRVJDQVNFLCBDQU1FTENBU0UsIExPV0VSQ0FTRSkgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OlRZUEVfIyNVUFBFUkNBU0U6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgIHJlc3VsdCArPSAodGFnX3NpemUgKyBXaXJlRm9ybWF0TGl0ZTo6ayMjQ0FNRUxDQVNFIyNTaXplKSAqICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRfIyNMT1dFUkNBU0UjI192YWx1ZS0+c2l6ZSgpOyAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgYnJlYWsKKyAgICAgICAgSEFORExFX1RZUEUoIEZJWEVEMzIsICBGaXhlZDMyLCB1aW50MzIpOworICAgICAgICBIQU5ETEVfVFlQRSggRklYRUQ2NCwgIEZpeGVkNjQsIHVpbnQ2NCk7CisgICAgICAgIEhBTkRMRV9UWVBFKFNGSVhFRDMyLCBTRml4ZWQzMiwgIGludDMyKTsKKyAgICAgICAgSEFORExFX1RZUEUoU0ZJWEVENjQsIFNGaXhlZDY0LCAgaW50NjQpOworICAgICAgICBIQU5ETEVfVFlQRSggICBGTE9BVCwgICAgRmxvYXQsICBmbG9hdCk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgRE9VQkxFLCAgIERvdWJsZSwgZG91YmxlKTsKKyAgICAgICAgSEFORExFX1RZUEUoICAgIEJPT0wsICAgICBCb29sLCAgIGJvb2wpOworI3VuZGVmIEhBTkRMRV9UWVBFCisgICAgICB9CisgICAgfQorICB9IGVsc2UgaWYgKCFpc19jbGVhcmVkKSB7CisgICAgcmVzdWx0ICs9IFdpcmVGb3JtYXRMaXRlOjpUYWdTaXplKG51bWJlciwgcmVhbF90eXBlKHR5cGUpKTsKKyAgICBzd2l0Y2ggKHJlYWxfdHlwZSh0eXBlKSkgeworI2RlZmluZSBIQU5ETEVfVFlQRShVUFBFUkNBU0UsIENBTUVMQ0FTRSwgTE9XRVJDQVNFKSAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpUWVBFXyMjVVBQRVJDQVNFOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgcmVzdWx0ICs9IFdpcmVGb3JtYXRMaXRlOjpDQU1FTENBU0UjI1NpemUoTE9XRVJDQVNFKTsgICAgICAgICAgICAgXAorICAgICAgICBicmVhaworCisgICAgICBIQU5ETEVfVFlQRSggICBJTlQzMiwgICAgSW50MzIsICAgIGludDMyX3ZhbHVlKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgIElOVDY0LCAgICBJbnQ2NCwgICAgaW50NjRfdmFsdWUpOworICAgICAgSEFORExFX1RZUEUoICBVSU5UMzIsICAgVUludDMyLCAgIHVpbnQzMl92YWx1ZSk7CisgICAgICBIQU5ETEVfVFlQRSggIFVJTlQ2NCwgICBVSW50NjQsICAgdWludDY0X3ZhbHVlKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgU0lOVDMyLCAgIFNJbnQzMiwgICAgaW50MzJfdmFsdWUpOworICAgICAgSEFORExFX1RZUEUoICBTSU5UNjQsICAgU0ludDY0LCAgICBpbnQ2NF92YWx1ZSk7CisgICAgICBIQU5ETEVfVFlQRSggIFNUUklORywgICBTdHJpbmcsICAqc3RyaW5nX3ZhbHVlKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgIEJZVEVTLCAgICBCeXRlcywgICpzdHJpbmdfdmFsdWUpOworICAgICAgSEFORExFX1RZUEUoICAgIEVOVU0sICAgICBFbnVtLCAgICAgZW51bV92YWx1ZSk7CisgICAgICBIQU5ETEVfVFlQRSggICBHUk9VUCwgICAgR3JvdXAsICptZXNzYWdlX3ZhbHVlKTsKKyN1bmRlZiBIQU5ETEVfVFlQRQorICAgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9NRVNTQUdFOiB7CisgICAgICAgIGlmIChpc19sYXp5KSB7CisgICAgICAgICAgaW50IHNpemUgPSBsYXp5bWVzc2FnZV92YWx1ZS0+Qnl0ZVNpemUoKTsKKyAgICAgICAgICByZXN1bHQgKz0gaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpWYXJpbnRTaXplMzIoc2l6ZSkgKyBzaXplOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHJlc3VsdCArPSBXaXJlRm9ybWF0TGl0ZTo6TWVzc2FnZVNpemUoKm1lc3NhZ2VfdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBTdHVmZiB3aXRoIGZpeGVkIHNpemUuCisjZGVmaW5lIEhBTkRMRV9UWVBFKFVQUEVSQ0FTRSwgQ0FNRUxDQVNFKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OlRZUEVfIyNVUFBFUkNBU0U6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICByZXN1bHQgKz0gV2lyZUZvcm1hdExpdGU6OmsjI0NBTUVMQ0FTRSMjU2l6ZTsgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGJyZWFrCisgICAgICBIQU5ETEVfVFlQRSggRklYRUQzMiwgIEZpeGVkMzIpOworICAgICAgSEFORExFX1RZUEUoIEZJWEVENjQsICBGaXhlZDY0KTsKKyAgICAgIEhBTkRMRV9UWVBFKFNGSVhFRDMyLCBTRml4ZWQzMik7CisgICAgICBIQU5ETEVfVFlQRShTRklYRUQ2NCwgU0ZpeGVkNjQpOworICAgICAgSEFORExFX1RZUEUoICAgRkxPQVQsICAgIEZsb2F0KTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgRE9VQkxFLCAgIERvdWJsZSk7CisgICAgICBIQU5ETEVfVFlQRSggICAgQk9PTCwgICAgIEJvb2wpOworI3VuZGVmIEhBTkRMRV9UWVBFCisgICAgfQorICB9CisKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworaW50IEV4dGVuc2lvblNldDo6RXh0ZW5zaW9uOjpHZXRTaXplKCkgY29uc3QgeworICBHT09HTEVfRENIRUNLKGlzX3JlcGVhdGVkKTsKKyAgc3dpdGNoIChjcHBfdHlwZSh0eXBlKSkgeworI2RlZmluZSBIQU5ETEVfVFlQRShVUFBFUkNBU0UsIExPV0VSQ0FTRSkgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV8jI1VQUEVSQ0FTRTogICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIHJldHVybiByZXBlYXRlZF8jI0xPV0VSQ0FTRSMjX3ZhbHVlLT5zaXplKCkKKworICAgIEhBTkRMRV9UWVBFKCAgSU5UMzIsICAgaW50MzIpOworICAgIEhBTkRMRV9UWVBFKCAgSU5UNjQsICAgaW50NjQpOworICAgIEhBTkRMRV9UWVBFKCBVSU5UMzIsICB1aW50MzIpOworICAgIEhBTkRMRV9UWVBFKCBVSU5UNjQsICB1aW50NjQpOworICAgIEhBTkRMRV9UWVBFKCAgRkxPQVQsICAgZmxvYXQpOworICAgIEhBTkRMRV9UWVBFKCBET1VCTEUsICBkb3VibGUpOworICAgIEhBTkRMRV9UWVBFKCAgIEJPT0wsICAgIGJvb2wpOworICAgIEhBTkRMRV9UWVBFKCAgIEVOVU0sICAgIGVudW0pOworICAgIEhBTkRMRV9UWVBFKCBTVFJJTkcsICBzdHJpbmcpOworICAgIEhBTkRMRV9UWVBFKE1FU1NBR0UsIG1lc3NhZ2UpOworI3VuZGVmIEhBTkRMRV9UWVBFCisgIH0KKworICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ2FuJ3QgZ2V0IGhlcmUuIjsKKyAgcmV0dXJuIDA7Cit9CisKKy8vIFRoaXMgZnVuY3Rpb24gZGVsZXRlcyBhbGwgYWxsb2NhdGVkIG9iamVjdHMuIFRoaXMgZnVuY3Rpb24gc2hvdWxkIGJlIG9ubHkKKy8vIGNhbGxlZCBpZiB0aGUgRXh0ZW5zaW9uIHdhcyBjcmVhdGVkIHdpdGggYW4gYXJlbmEuCit2b2lkIEV4dGVuc2lvblNldDo6RXh0ZW5zaW9uOjpGcmVlKCkgeworICBpZiAoaXNfcmVwZWF0ZWQpIHsKKyAgICBzd2l0Y2ggKGNwcF90eXBlKHR5cGUpKSB7CisjZGVmaW5lIEhBTkRMRV9UWVBFKFVQUEVSQ0FTRSwgTE9XRVJDQVNFKSAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6Q1BQVFlQRV8jI1VQUEVSQ0FTRTogICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgZGVsZXRlIHJlcGVhdGVkXyMjTE9XRVJDQVNFIyNfdmFsdWU7ICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGJyZWFrCisKKyAgICAgIEhBTkRMRV9UWVBFKCAgSU5UMzIsICAgaW50MzIpOworICAgICAgSEFORExFX1RZUEUoICBJTlQ2NCwgICBpbnQ2NCk7CisgICAgICBIQU5ETEVfVFlQRSggVUlOVDMyLCAgdWludDMyKTsKKyAgICAgIEhBTkRMRV9UWVBFKCBVSU5UNjQsICB1aW50NjQpOworICAgICAgSEFORExFX1RZUEUoICBGTE9BVCwgICBmbG9hdCk7CisgICAgICBIQU5ETEVfVFlQRSggRE9VQkxFLCAgZG91YmxlKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgIEJPT0wsICAgIGJvb2wpOworICAgICAgSEFORExFX1RZUEUoICAgRU5VTSwgICAgZW51bSk7CisgICAgICBIQU5ETEVfVFlQRSggU1RSSU5HLCAgc3RyaW5nKTsKKyAgICAgIEhBTkRMRV9UWVBFKE1FU1NBR0UsIG1lc3NhZ2UpOworI3VuZGVmIEhBTkRMRV9UWVBFCisgICAgfQorICB9IGVsc2UgeworICAgIHN3aXRjaCAoY3BwX3R5cGUodHlwZSkpIHsKKyAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfU1RSSU5HOgorICAgICAgICBkZWxldGUgc3RyaW5nX3ZhbHVlOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OkNQUFRZUEVfTUVTU0FHRToKKyAgICAgICAgaWYgKGlzX2xhenkpIHsKKyAgICAgICAgICBkZWxldGUgbGF6eW1lc3NhZ2VfdmFsdWU7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZGVsZXRlIG1lc3NhZ2VfdmFsdWU7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgICBkZWZhdWx0OgorICAgICAgICBicmVhazsKKyAgICB9CisgIH0KK30KKworLy8gRGVmaW5lZCBpbiBleHRlbnNpb25fc2V0X2hlYXZ5LmNjLgorLy8gaW50IEV4dGVuc2lvblNldDo6RXh0ZW5zaW9uOjpTcGFjZVVzZWRFeGNsdWRpbmdTZWxmKCkgY29uc3QKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisvLyBEZWZhdWx0IHJlcGVhdGVkIGZpZWxkIGluc3RhbmNlcyBmb3IgaXRlcmF0b3ItY29tcGF0aWJsZSBhY2Nlc3NvcnMKKworR09PR0xFX1BST1RPQlVGX0RFQ0xBUkVfT05DRShyZXBlYXRlZF9wcmltaXRpdmVfZ2VuZXJpY190eXBlX3RyYWl0c19vbmNlX2luaXRfKTsKK0dPT0dMRV9QUk9UT0JVRl9ERUNMQVJFX09OQ0UocmVwZWF0ZWRfc3RyaW5nX3R5cGVfdHJhaXRzX29uY2VfaW5pdF8pOworR09PR0xFX1BST1RPQlVGX0RFQ0xBUkVfT05DRShyZXBlYXRlZF9tZXNzYWdlX2dlbmVyaWNfdHlwZV90cmFpdHNfb25jZV9pbml0Xyk7CisKK3ZvaWQgUmVwZWF0ZWRQcmltaXRpdmVHZW5lcmljVHlwZVRyYWl0czo6SW5pdGlhbGl6ZURlZmF1bHRSZXBlYXRlZEZpZWxkcygpIHsKKyAgZGVmYXVsdF9yZXBlYXRlZF9maWVsZF9pbnQzMl8gPSBuZXcgUmVwZWF0ZWRGaWVsZDxpbnQzMj47CisgIGRlZmF1bHRfcmVwZWF0ZWRfZmllbGRfaW50NjRfID0gbmV3IFJlcGVhdGVkRmllbGQ8aW50NjQ+OworICBkZWZhdWx0X3JlcGVhdGVkX2ZpZWxkX3VpbnQzMl8gPSBuZXcgUmVwZWF0ZWRGaWVsZDx1aW50MzI+OworICBkZWZhdWx0X3JlcGVhdGVkX2ZpZWxkX3VpbnQ2NF8gPSBuZXcgUmVwZWF0ZWRGaWVsZDx1aW50NjQ+OworICBkZWZhdWx0X3JlcGVhdGVkX2ZpZWxkX2RvdWJsZV8gPSBuZXcgUmVwZWF0ZWRGaWVsZDxkb3VibGU+OworICBkZWZhdWx0X3JlcGVhdGVkX2ZpZWxkX2Zsb2F0XyA9IG5ldyBSZXBlYXRlZEZpZWxkPGZsb2F0PjsKKyAgZGVmYXVsdF9yZXBlYXRlZF9maWVsZF9ib29sXyA9IG5ldyBSZXBlYXRlZEZpZWxkPGJvb2w+OworICBPblNodXRkb3duKCZEZXN0cm95RGVmYXVsdFJlcGVhdGVkRmllbGRzKTsKK30KKwordm9pZCBSZXBlYXRlZFByaW1pdGl2ZUdlbmVyaWNUeXBlVHJhaXRzOjpEZXN0cm95RGVmYXVsdFJlcGVhdGVkRmllbGRzKCkgeworICBkZWxldGUgZGVmYXVsdF9yZXBlYXRlZF9maWVsZF9pbnQzMl87CisgIGRlbGV0ZSBkZWZhdWx0X3JlcGVhdGVkX2ZpZWxkX2ludDY0XzsKKyAgZGVsZXRlIGRlZmF1bHRfcmVwZWF0ZWRfZmllbGRfdWludDMyXzsKKyAgZGVsZXRlIGRlZmF1bHRfcmVwZWF0ZWRfZmllbGRfdWludDY0XzsKKyAgZGVsZXRlIGRlZmF1bHRfcmVwZWF0ZWRfZmllbGRfZG91YmxlXzsKKyAgZGVsZXRlIGRlZmF1bHRfcmVwZWF0ZWRfZmllbGRfZmxvYXRfOworICBkZWxldGUgZGVmYXVsdF9yZXBlYXRlZF9maWVsZF9ib29sXzsKK30KKwordm9pZCBSZXBlYXRlZFN0cmluZ1R5cGVUcmFpdHM6OkluaXRpYWxpemVEZWZhdWx0UmVwZWF0ZWRGaWVsZHMoKSB7CisgIGRlZmF1bHRfcmVwZWF0ZWRfZmllbGRfID0gbmV3IFJlcGVhdGVkRmllbGRUeXBlOworICBPblNodXRkb3duKCZEZXN0cm95RGVmYXVsdFJlcGVhdGVkRmllbGRzKTsKK30KKwordm9pZCBSZXBlYXRlZFN0cmluZ1R5cGVUcmFpdHM6OkRlc3Ryb3lEZWZhdWx0UmVwZWF0ZWRGaWVsZHMoKSB7CisgIGRlbGV0ZSBkZWZhdWx0X3JlcGVhdGVkX2ZpZWxkXzsKK30KKwordm9pZCBSZXBlYXRlZE1lc3NhZ2VHZW5lcmljVHlwZVRyYWl0czo6SW5pdGlhbGl6ZURlZmF1bHRSZXBlYXRlZEZpZWxkcygpIHsKKyAgZGVmYXVsdF9yZXBlYXRlZF9maWVsZF8gPSBuZXcgUmVwZWF0ZWRGaWVsZFR5cGU7CisgIE9uU2h1dGRvd24oJkRlc3Ryb3lEZWZhdWx0UmVwZWF0ZWRGaWVsZHMpOworfQorCit2b2lkIFJlcGVhdGVkTWVzc2FnZUdlbmVyaWNUeXBlVHJhaXRzOjpEZXN0cm95RGVmYXVsdFJlcGVhdGVkRmllbGRzKCkgeworICBkZWxldGUgZGVmYXVsdF9yZXBlYXRlZF9maWVsZF87Cit9CisKK2NvbnN0IFJlcGVhdGVkRmllbGQ8aW50MzI+KgorUmVwZWF0ZWRQcmltaXRpdmVHZW5lcmljVHlwZVRyYWl0czo6ZGVmYXVsdF9yZXBlYXRlZF9maWVsZF9pbnQzMl8gPSBOVUxMOworY29uc3QgUmVwZWF0ZWRGaWVsZDxpbnQ2ND4qCitSZXBlYXRlZFByaW1pdGl2ZUdlbmVyaWNUeXBlVHJhaXRzOjpkZWZhdWx0X3JlcGVhdGVkX2ZpZWxkX2ludDY0XyA9IE5VTEw7Citjb25zdCBSZXBlYXRlZEZpZWxkPHVpbnQzMj4qCitSZXBlYXRlZFByaW1pdGl2ZUdlbmVyaWNUeXBlVHJhaXRzOjpkZWZhdWx0X3JlcGVhdGVkX2ZpZWxkX3VpbnQzMl8gPSBOVUxMOworY29uc3QgUmVwZWF0ZWRGaWVsZDx1aW50NjQ+KgorUmVwZWF0ZWRQcmltaXRpdmVHZW5lcmljVHlwZVRyYWl0czo6ZGVmYXVsdF9yZXBlYXRlZF9maWVsZF91aW50NjRfID0gTlVMTDsKK2NvbnN0IFJlcGVhdGVkRmllbGQ8ZG91YmxlPioKK1JlcGVhdGVkUHJpbWl0aXZlR2VuZXJpY1R5cGVUcmFpdHM6OmRlZmF1bHRfcmVwZWF0ZWRfZmllbGRfZG91YmxlXyA9IE5VTEw7Citjb25zdCBSZXBlYXRlZEZpZWxkPGZsb2F0PioKK1JlcGVhdGVkUHJpbWl0aXZlR2VuZXJpY1R5cGVUcmFpdHM6OmRlZmF1bHRfcmVwZWF0ZWRfZmllbGRfZmxvYXRfID0gTlVMTDsKK2NvbnN0IFJlcGVhdGVkRmllbGQ8Ym9vbD4qCitSZXBlYXRlZFByaW1pdGl2ZUdlbmVyaWNUeXBlVHJhaXRzOjpkZWZhdWx0X3JlcGVhdGVkX2ZpZWxkX2Jvb2xfID0gTlVMTDsKK2NvbnN0IFJlcGVhdGVkU3RyaW5nVHlwZVRyYWl0czo6UmVwZWF0ZWRGaWVsZFR5cGUqCitSZXBlYXRlZFN0cmluZ1R5cGVUcmFpdHM6OmRlZmF1bHRfcmVwZWF0ZWRfZmllbGRfID0gTlVMTDsKK2NvbnN0IFJlcGVhdGVkTWVzc2FnZUdlbmVyaWNUeXBlVHJhaXRzOjpSZXBlYXRlZEZpZWxkVHlwZSoKK1JlcGVhdGVkTWVzc2FnZUdlbmVyaWNUeXBlVHJhaXRzOjpkZWZhdWx0X3JlcGVhdGVkX2ZpZWxkXyA9IE5VTEw7CisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2V4dGVuc2lvbl9zZXQuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvZXh0ZW5zaW9uX3NldC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJjYTE3OWIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2V4dGVuc2lvbl9zZXQuaApAQCAtMCwwICsxLDEyNjYgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBUaGlzIGhlYWRlciBpcyBsb2dpY2FsbHkgaW50ZXJuYWwsIGJ1dCBpcyBtYWRlIHB1YmxpYyBiZWNhdXNlIGl0IGlzIHVzZWQKKy8vIGZyb20gcHJvdG9jb2wtY29tcGlsZXItZ2VuZXJhdGVkIGNvZGUsIHdoaWNoIG1heSByZXNpZGUgaW4gb3RoZXIgY29tcG9uZW50cy4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfRVhURU5TSU9OX1NFVF9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0VYVEVOU0lPTl9TRVRfSF9fCisKKyNpbmNsdWRlIDx2ZWN0b3I+CisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHV0aWxpdHk+CisjaW5jbHVkZSA8c3RyaW5nPgorCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2xvZ2dpbmcuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvb25jZS5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3JlcGVhdGVkX2ZpZWxkLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworCituYW1lc3BhY2UgcHJvdG9idWYgeworICBjbGFzcyBBcmVuYTsKKyAgY2xhc3MgRGVzY3JpcHRvcjsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBkZXNjcmlwdG9yLmgKKyAgY2xhc3MgRmllbGREZXNjcmlwdG9yOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBkZXNjcmlwdG9yLmgKKyAgY2xhc3MgRGVzY3JpcHRvclBvb2w7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBkZXNjcmlwdG9yLmgKKyAgY2xhc3MgTWVzc2FnZUxpdGU7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBtZXNzYWdlX2xpdGUuaAorICBjbGFzcyBNZXNzYWdlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1lc3NhZ2UuaAorICBjbGFzcyBNZXNzYWdlRmFjdG9yeTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1lc3NhZ2UuaAorICBjbGFzcyBVbmtub3duRmllbGRTZXQ7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHVua25vd25fZmllbGRfc2V0LmgKKyAgbmFtZXNwYWNlIGlvIHsKKyAgICBjbGFzcyBDb2RlZElucHV0U3RyZWFtOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvZGVkX3N0cmVhbS5oCisgICAgY2xhc3MgQ29kZWRPdXRwdXRTdHJlYW07ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjb2RlZF9zdHJlYW0uaAorICB9CisgIG5hbWVzcGFjZSBpbnRlcm5hbCB7CisgICAgY2xhc3MgRmllbGRTa2lwcGVyOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB3aXJlX2Zvcm1hdF9saXRlLmgKKyAgfQorfQorCituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKworLy8gVXNlZCB0byBzdG9yZSB2YWx1ZXMgb2YgdHlwZSBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIHdpdGhvdXQgaGF2aW5nIHRvCisvLyAjaW5jbHVkZSB3aXJlX2Zvcm1hdF9saXRlLmguICBBbHNvLCBlbnN1cmVzIHRoYXQgd2UgdXNlIG9ubHkgb25lIGJ5dGUgdG8KKy8vIHN0b3JlIHRoZXNlIHZhbHVlcywgd2hpY2ggaXMgaW1wb3J0YW50IHRvIGtlZXAgdGhlIGxheW91dCBvZgorLy8gRXh0ZW5zaW9uU2V0OjpFeHRlbnNpb24gc21hbGwuCit0eXBlZGVmIHVpbnQ4IEZpZWxkVHlwZTsKKworLy8gQSBmdW5jdGlvbiB3aGljaCwgZ2l2ZW4gYW4gaW50ZWdlciB2YWx1ZSwgcmV0dXJucyB0cnVlIGlmIHRoZSBudW1iZXIKKy8vIG1hdGNoZXMgb25lIG9mIHRoZSBkZWZpbmVkIHZhbHVlcyBmb3IgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSB0eXBlLiAgVGhpcworLy8gaXMgdXNlZCB3aXRoIFJlZ2lzdGVyRW51bUV4dGVuc2lvbiwgYmVsb3cuCit0eXBlZGVmIGJvb2wgRW51bVZhbGlkaXR5RnVuYyhpbnQgbnVtYmVyKTsKKworLy8gVmVyc2lvbiBvZiB0aGUgYWJvdmUgd2hpY2ggdGFrZXMgYW4gYXJndW1lbnQuICBUaGlzIGlzIG5lZWRlZCB0byBkZWFsIHdpdGgKKy8vIGV4dGVuc2lvbnMgdGhhdCBhcmUgbm90IGNvbXBpbGVkIGluLgordHlwZWRlZiBib29sIEVudW1WYWxpZGl0eUZ1bmNXaXRoQXJnKGNvbnN0IHZvaWQqIGFyZywgaW50IG51bWJlcik7CisKKy8vIEluZm9ybWF0aW9uIGFib3V0IGEgcmVnaXN0ZXJlZCBleHRlbnNpb24uCitzdHJ1Y3QgRXh0ZW5zaW9uSW5mbyB7CisgIGlubGluZSBFeHRlbnNpb25JbmZvKCkge30KKyAgaW5saW5lIEV4dGVuc2lvbkluZm8oRmllbGRUeXBlIHR5cGVfcGFyYW0sIGJvb2wgaXNyZXBlYXRlZCwgYm9vbCBpc3BhY2tlZCkKKyAgICAgIDogdHlwZSh0eXBlX3BhcmFtKSwgaXNfcmVwZWF0ZWQoaXNyZXBlYXRlZCksIGlzX3BhY2tlZChpc3BhY2tlZCksCisgICAgICAgIGRlc2NyaXB0b3IoTlVMTCkge30KKworICBGaWVsZFR5cGUgdHlwZTsKKyAgYm9vbCBpc19yZXBlYXRlZDsKKyAgYm9vbCBpc19wYWNrZWQ7CisKKyAgc3RydWN0IEVudW1WYWxpZGl0eUNoZWNrIHsKKyAgICBFbnVtVmFsaWRpdHlGdW5jV2l0aEFyZyogZnVuYzsKKyAgICBjb25zdCB2b2lkKiBhcmc7CisgIH07CisKKyAgdW5pb24geworICAgIEVudW1WYWxpZGl0eUNoZWNrIGVudW1fdmFsaWRpdHlfY2hlY2s7CisgICAgY29uc3QgTWVzc2FnZUxpdGUqIG1lc3NhZ2VfcHJvdG90eXBlOworICB9OworCisgIC8vIFRoZSBkZXNjcmlwdG9yIGZvciB0aGlzIGV4dGVuc2lvbiwgaWYgb25lIGV4aXN0cyBhbmQgaXMga25vd24uICBNYXkgYmUKKyAgLy8gTlVMTC4gIE11c3Qgbm90IGJlIE5VTEwgaWYgdGhlIGRlc2NyaXB0b3IgZm9yIHRoZSBleHRlbnNpb24gZG9lcyBub3QKKyAgLy8gbGl2ZSBpbiB0aGUgc2FtZSBwb29sIGFzIHRoZSBkZXNjcmlwdG9yIGZvciB0aGUgY29udGFpbmluZyB0eXBlLgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3I7Cit9OworCisvLyBBYnN0cmFjdCBpbnRlcmZhY2UgZm9yIGFuIG9iamVjdCB3aGljaCBsb29rcyB1cCBleHRlbnNpb24gZGVmaW5pdGlvbnMuICBVc2VkCisvLyB3aGVuIHBhcnNpbmcuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgRXh0ZW5zaW9uRmluZGVyIHsKKyBwdWJsaWM6CisgIHZpcnR1YWwgfkV4dGVuc2lvbkZpbmRlcigpOworCisgIC8vIEZpbmQgdGhlIGV4dGVuc2lvbiB3aXRoIHRoZSBnaXZlbiBjb250YWluaW5nIHR5cGUgYW5kIG51bWJlci4KKyAgdmlydHVhbCBib29sIEZpbmQoaW50IG51bWJlciwgRXh0ZW5zaW9uSW5mbyogb3V0cHV0KSA9IDA7Cit9OworCisvLyBJbXBsZW1lbnRhdGlvbiBvZiBFeHRlbnNpb25GaW5kZXIgd2hpY2ggZmluZHMgZXh0ZW5zaW9ucyBkZWZpbmVkIGluIC5wcm90bworLy8gZmlsZXMgd2hpY2ggaGF2ZSBiZWVuIGNvbXBpbGVkIGludG8gdGhlIGJpbmFyeS4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBHZW5lcmF0ZWRFeHRlbnNpb25GaW5kZXIgOiBwdWJsaWMgRXh0ZW5zaW9uRmluZGVyIHsKKyBwdWJsaWM6CisgIEdlbmVyYXRlZEV4dGVuc2lvbkZpbmRlcihjb25zdCBNZXNzYWdlTGl0ZSogY29udGFpbmluZ190eXBlKQorICAgICAgOiBjb250YWluaW5nX3R5cGVfKGNvbnRhaW5pbmdfdHlwZSkge30KKyAgdmlydHVhbCB+R2VuZXJhdGVkRXh0ZW5zaW9uRmluZGVyKCkge30KKworICAvLyBSZXR1cm5zIHRydWUgYW5kIGZpbGxzIGluICpvdXRwdXQgaWYgZm91bmQsIG90aGVyd2lzZSByZXR1cm5zIGZhbHNlLgorICB2aXJ0dWFsIGJvb2wgRmluZChpbnQgbnVtYmVyLCBFeHRlbnNpb25JbmZvKiBvdXRwdXQpOworCisgcHJpdmF0ZToKKyAgY29uc3QgTWVzc2FnZUxpdGUqIGNvbnRhaW5pbmdfdHlwZV87Cit9OworCisvLyBBIEZpZWxkU2tpcHBlciB1c2VkIGZvciBwYXJzaW5nIE1lc3NhZ2VTZXQuCitjbGFzcyBNZXNzYWdlU2V0RmllbGRTa2lwcGVyOworCisvLyBOb3RlOiAgZXh0ZW5zaW9uX3NldF9oZWF2eS5jYyBkZWZpbmVzIERlc2NyaXB0b3JQb29sRXh0ZW5zaW9uRmluZGVyIGZvcgorLy8gZmluZGluZyBleHRlbnNpb25zIGZyb20gYSBEZXNjcmlwdG9yUG9vbC4KKworLy8gVGhpcyBpcyBhbiBpbnRlcm5hbCBoZWxwZXIgY2xhc3MgaW50ZW5kZWQgZm9yIHVzZSB3aXRoaW4gdGhlIHByb3RvY29sIGJ1ZmZlcgorLy8gbGlicmFyeSBhbmQgZ2VuZXJhdGVkIGNsYXNzZXMuICBDbGllbnRzIHNob3VsZCBub3QgdXNlIGl0IGRpcmVjdGx5LiAgSW5zdGVhZCwKKy8vIHVzZSB0aGUgZ2VuZXJhdGVkIGFjY2Vzc29ycyBzdWNoIGFzIEdldEV4dGVuc2lvbigpIG9mIHRoZSBjbGFzcyBiZWluZworLy8gZXh0ZW5kZWQuCisvLworLy8gVGhpcyBjbGFzcyBtYW5hZ2VzIGV4dGVuc2lvbnMgZm9yIGEgcHJvdG9jb2wgbWVzc2FnZSBvYmplY3QuICBUaGUKKy8vIG1lc3NhZ2UncyBIYXNFeHRlbnNpb24oKSwgR2V0RXh0ZW5zaW9uKCksIE11dGFibGVFeHRlbnNpb24oKSwgYW5kCisvLyBDbGVhckV4dGVuc2lvbigpIG1ldGhvZHMgYXJlIGp1c3QgdGhpbiB3cmFwcGVycyBhcm91bmQgdGhlIGVtYmVkZGVkCisvLyBFeHRlbnNpb25TZXQuICBXaGVuIHBhcnNpbmcsIGlmIGEgdGFnIG51bWJlciBpcyBlbmNvdW50ZXJlZCB3aGljaCBpcworLy8gaW5zaWRlIG9uZSBvZiB0aGUgbWVzc2FnZSB0eXBlJ3MgZXh0ZW5zaW9uIHJhbmdlcywgdGhlIHRhZyBpcyBwYXNzZWQKKy8vIG9mZiB0byB0aGUgRXh0ZW5zaW9uU2V0IGZvciBwYXJzaW5nLiAgRXRjLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEV4dGVuc2lvblNldCB7CisgcHVibGljOgorICBFeHRlbnNpb25TZXQoKTsKKyAgZXhwbGljaXQgRXh0ZW5zaW9uU2V0KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKTsKKyAgfkV4dGVuc2lvblNldCgpOworCisgIC8vIFRoZXNlIGFyZSBjYWxsZWQgYXQgc3RhcnR1cCBieSBwcm90b2NvbC1jb21waWxlci1nZW5lcmF0ZWQgY29kZSB0bworICAvLyByZWdpc3RlciBrbm93biBleHRlbnNpb25zLiAgVGhlIHJlZ2lzdHJhdGlvbnMgYXJlIHVzZWQgYnkgUGFyc2VGaWVsZCgpCisgIC8vIHRvIGxvb2sgdXAgZXh0ZW5zaW9ucyBmb3IgcGFyc2VkIGZpZWxkIG51bWJlcnMuICBOb3RlIHRoYXQgZHluYW1pYyBwYXJzaW5nCisgIC8vIGRvZXMgbm90IHVzZSBQYXJzZUZpZWxkKCk7IG9ubHkgcHJvdG9jb2wtY29tcGlsZXItZ2VuZXJhdGVkIHBhcnNpbmcKKyAgLy8gbWV0aG9kcyBkby4KKyAgc3RhdGljIHZvaWQgUmVnaXN0ZXJFeHRlbnNpb24oY29uc3QgTWVzc2FnZUxpdGUqIGNvbnRhaW5pbmdfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG51bWJlciwgRmllbGRUeXBlIHR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaXNfcmVwZWF0ZWQsIGJvb2wgaXNfcGFja2VkKTsKKyAgc3RhdGljIHZvaWQgUmVnaXN0ZXJFbnVtRXh0ZW5zaW9uKGNvbnN0IE1lc3NhZ2VMaXRlKiBjb250YWluaW5nX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbnVtYmVyLCBGaWVsZFR5cGUgdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaXNfcmVwZWF0ZWQsIGJvb2wgaXNfcGFja2VkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRW51bVZhbGlkaXR5RnVuYyogaXNfdmFsaWQpOworICBzdGF0aWMgdm9pZCBSZWdpc3Rlck1lc3NhZ2VFeHRlbnNpb24oY29uc3QgTWVzc2FnZUxpdGUqIGNvbnRhaW5pbmdfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBudW1iZXIsIEZpZWxkVHlwZSB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc19yZXBlYXRlZCwgYm9vbCBpc19wYWNrZWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNZXNzYWdlTGl0ZSogcHJvdG90eXBlKTsKKworICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisgIC8vIEFkZCBhbGwgZmllbGRzIHdoaWNoIGFyZSBjdXJyZW50bHkgcHJlc2VudCB0byB0aGUgZ2l2ZW4gdmVjdG9yLiAgVGhpcworICAvLyBpcyB1c2VmdWwgdG8gaW1wbGVtZW50IFJlZmxlY3Rpb246Okxpc3RGaWVsZHMoKS4KKyAgdm9pZCBBcHBlbmRUb0xpc3QoY29uc3QgRGVzY3JpcHRvciogY29udGFpbmluZ190eXBlLAorICAgICAgICAgICAgICAgICAgICBjb25zdCBEZXNjcmlwdG9yUG9vbCogcG9vbCwKKyAgICAgICAgICAgICAgICAgICAgc3RkOjp2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4qIG91dHB1dCkgY29uc3Q7CisKKyAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyAgLy8gQWNjZXNzb3JzCisgIC8vCisgIC8vIEdlbmVyYXRlZCBtZXNzYWdlIGNsYXNzZXMgaW5jbHVkZSB0eXBlLXNhZmUgdGVtcGxhdGVkIHdyYXBwZXJzIGFyb3VuZAorICAvLyB0aGVzZSBtZXRob2RzLiAgR2VuZXJhbGx5IHlvdSBzaG91bGQgdXNlIHRob3NlIHJhdGhlciB0aGFuIGNhbGwgdGhlc2UKKyAgLy8gZGlyZWN0bHksIHVubGVzcyB5b3UgYXJlIGRvaW5nIGxvdy1sZXZlbCBtZW1vcnkgbWFuYWdlbWVudC4KKyAgLy8KKyAgLy8gV2hlbiBjYWxsaW5nIGFueSBvZiB0aGVzZSBhY2Nlc3NvcnMsIHRoZSBleHRlbnNpb24gbnVtYmVyIHJlcXVlc3RlZAorICAvLyBNVVNUIGV4aXN0IGluIHRoZSBEZXNjcmlwdG9yUG9vbCBwcm92aWRlZCB0byB0aGUgY29uc3RydWN0b3IuICBPdGhlcndpc2UsCisgIC8vIHRoZSBtZXRob2Qgd2lsbCBmYWlsIGFuIGFzc2VydC4gIE5vcm1hbGx5LCB0aG91Z2gsIHlvdSB3b3VsZCBub3QgY2FsbAorICAvLyB0aGVzZSBkaXJlY3RseTsgeW91IHdvdWxkIGVpdGhlciBjYWxsIHRoZSBnZW5lcmF0ZWQgYWNjZXNzb3JzIG9mIHlvdXIKKyAgLy8gbWVzc2FnZSBjbGFzcyAoZS5nLiBHZXRFeHRlbnNpb24oKSkgb3IgeW91IHdvdWxkIGNhbGwgdGhlIGFjY2Vzc29ycworICAvLyBvZiB0aGUgcmVmbGVjdGlvbiBpbnRlcmZhY2UuICBJbiBib3RoIGNhc2VzLCBpdCBpcyBpbXBvc3NpYmxlIHRvCisgIC8vIHRyaWdnZXIgdGhpcyBhc3NlcnQgZmFpbHVyZTogIHRoZSBnZW5lcmF0ZWQgYWNjZXNzb3JzIG9ubHkgYWNjZXB0CisgIC8vIGxpbmtlZC1pbiBleHRlbnNpb24gdHlwZXMgYXMgcGFyYW1ldGVycywgd2hpbGUgdGhlIFJlZmxlY3Rpb24gaW50ZXJmYWNlCisgIC8vIHJlcXVpcmVzIHlvdSB0byBwcm92aWRlIHRoZSBGaWVsZERlc2NyaXB0b3IgZGVzY3JpYmluZyB0aGUgZXh0ZW5zaW9uLgorICAvLworICAvLyBXaGVuIGNhbGxpbmcgYW55IG9mIHRoZXNlIGFjY2Vzc29ycywgYSBwcm90b2NvbC1jb21waWxlci1nZW5lcmF0ZWQKKyAgLy8gaW1wbGVtZW50YXRpb24gb2YgdGhlIGV4dGVuc2lvbiBjb3JyZXNwb25kaW5nIHRvIHRoZSBudW1iZXIgTVVTVAorICAvLyBiZSBsaW5rZWQgaW4sIGFuZCB0aGUgRmllbGREZXNjcmlwdG9yIHVzZWQgdG8gcmVmZXIgdG8gaXQgTVVTVCBiZQorICAvLyB0aGUgb25lIGdlbmVyYXRlZCBieSB0aGF0IGxpbmtlZC1pbiBjb2RlLiAgT3RoZXJ3aXNlLCB0aGUgbWV0aG9kIHdpbGwKKyAgLy8gZGllIG9uIGFuIGFzc2VydCBmYWlsdXJlLiAgVGhlIG1lc3NhZ2Ugb2JqZWN0cyByZXR1cm5lZCBieSB0aGUgbWVzc2FnZQorICAvLyBhY2Nlc3NvcnMgYXJlIGd1YXJhbnRlZWQgdG8gYmUgb2YgdGhlIGNvcnJlY3QgbGlua2VkLWluIHR5cGUuCisgIC8vCisgIC8vIFRoZXNlIG1ldGhvZHMgcHJldHR5IG11Y2ggbWF0Y2ggUmVmbGVjdGlvbiBleGNlcHQgdGhhdDoKKyAgLy8gLSBUaGV5J3JlIG5vdCB2aXJ0dWFsLgorICAvLyAtIFRoZXkgaWRlbnRpZnkgZmllbGRzIGJ5IG51bWJlciByYXRoZXIgdGhhbiBGaWVsZERlc2NyaXB0b3JzLgorICAvLyAtIFRoZXkgaWRlbnRpZnkgZW51bSB2YWx1ZXMgdXNpbmcgaW50ZWdlcnMgcmF0aGVyIHRoYW4gZGVzY3JpcHRvcnMuCisgIC8vIC0gU3RyaW5ncyBwcm92aWRlIE11dGFibGUoKSBpbiBhZGRpdGlvbiB0byBTZXQoKSBhY2Nlc3NvcnMuCisKKyAgYm9vbCBIYXMoaW50IG51bWJlcikgY29uc3Q7CisgIGludCBFeHRlbnNpb25TaXplKGludCBudW1iZXIpIGNvbnN0OyAgIC8vIFNpemUgb2YgYSByZXBlYXRlZCBleHRlbnNpb24uCisgIGludCBOdW1FeHRlbnNpb25zKCkgY29uc3Q7ICAvLyBUaGUgbnVtYmVyIG9mIGV4dGVuc2lvbnMKKyAgRmllbGRUeXBlIEV4dGVuc2lvblR5cGUoaW50IG51bWJlcikgY29uc3Q7CisgIHZvaWQgQ2xlYXJFeHRlbnNpb24oaW50IG51bWJlcik7CisKKyAgLy8gc2luZ3VsYXIgZmllbGRzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBpbnQzMiAgR2V0SW50MzIgKGludCBudW1iZXIsIGludDMyICBkZWZhdWx0X3ZhbHVlKSBjb25zdDsKKyAgaW50NjQgIEdldEludDY0IChpbnQgbnVtYmVyLCBpbnQ2NCAgZGVmYXVsdF92YWx1ZSkgY29uc3Q7CisgIHVpbnQzMiBHZXRVSW50MzIoaW50IG51bWJlciwgdWludDMyIGRlZmF1bHRfdmFsdWUpIGNvbnN0OworICB1aW50NjQgR2V0VUludDY0KGludCBudW1iZXIsIHVpbnQ2NCBkZWZhdWx0X3ZhbHVlKSBjb25zdDsKKyAgZmxvYXQgIEdldEZsb2F0IChpbnQgbnVtYmVyLCBmbG9hdCAgZGVmYXVsdF92YWx1ZSkgY29uc3Q7CisgIGRvdWJsZSBHZXREb3VibGUoaW50IG51bWJlciwgZG91YmxlIGRlZmF1bHRfdmFsdWUpIGNvbnN0OworICBib29sICAgR2V0Qm9vbCAgKGludCBudW1iZXIsIGJvb2wgICBkZWZhdWx0X3ZhbHVlKSBjb25zdDsKKyAgaW50ICAgIEdldEVudW0gIChpbnQgbnVtYmVyLCBpbnQgICAgZGVmYXVsdF92YWx1ZSkgY29uc3Q7CisgIGNvbnN0IHN0cmluZyAmIEdldFN0cmluZyAoaW50IG51bWJlciwgY29uc3Qgc3RyaW5nJiAgZGVmYXVsdF92YWx1ZSkgY29uc3Q7CisgIGNvbnN0IE1lc3NhZ2VMaXRlJiBHZXRNZXNzYWdlKGludCBudW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2VMaXRlJiBkZWZhdWx0X3ZhbHVlKSBjb25zdDsKKyAgY29uc3QgTWVzc2FnZUxpdGUmIEdldE1lc3NhZ2UoaW50IG51bWJlciwgY29uc3QgRGVzY3JpcHRvciogbWVzc2FnZV90eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlRmFjdG9yeSogZmFjdG9yeSkgY29uc3Q7CisKKyAgLy8gfGRlc2NyaXB0b3J8IG1heSBiZSBOVUxMIHNvIGxvbmcgYXMgaXQgaXMga25vd24gdGhhdCB0aGUgZGVzY3JpcHRvciBmb3IKKyAgLy8gdGhlIGV4dGVuc2lvbiBsaXZlcyBpbiB0aGUgc2FtZSBwb29sIGFzIHRoZSBkZXNjcmlwdG9yIGZvciB0aGUgY29udGFpbmluZworICAvLyB0eXBlLgorI2RlZmluZSBkZXNjIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciAgLy8gYXZvaWQgbGluZSB3cmFwcGluZworICB2b2lkIFNldEludDMyIChpbnQgbnVtYmVyLCBGaWVsZFR5cGUgdHlwZSwgaW50MzIgIHZhbHVlLCBkZXNjKTsKKyAgdm9pZCBTZXRJbnQ2NCAoaW50IG51bWJlciwgRmllbGRUeXBlIHR5cGUsIGludDY0ICB2YWx1ZSwgZGVzYyk7CisgIHZvaWQgU2V0VUludDMyKGludCBudW1iZXIsIEZpZWxkVHlwZSB0eXBlLCB1aW50MzIgdmFsdWUsIGRlc2MpOworICB2b2lkIFNldFVJbnQ2NChpbnQgbnVtYmVyLCBGaWVsZFR5cGUgdHlwZSwgdWludDY0IHZhbHVlLCBkZXNjKTsKKyAgdm9pZCBTZXRGbG9hdCAoaW50IG51bWJlciwgRmllbGRUeXBlIHR5cGUsIGZsb2F0ICB2YWx1ZSwgZGVzYyk7CisgIHZvaWQgU2V0RG91YmxlKGludCBudW1iZXIsIEZpZWxkVHlwZSB0eXBlLCBkb3VibGUgdmFsdWUsIGRlc2MpOworICB2b2lkIFNldEJvb2wgIChpbnQgbnVtYmVyLCBGaWVsZFR5cGUgdHlwZSwgYm9vbCAgIHZhbHVlLCBkZXNjKTsKKyAgdm9pZCBTZXRFbnVtICAoaW50IG51bWJlciwgRmllbGRUeXBlIHR5cGUsIGludCAgICB2YWx1ZSwgZGVzYyk7CisgIHZvaWQgU2V0U3RyaW5nKGludCBudW1iZXIsIEZpZWxkVHlwZSB0eXBlLCBjb25zdCBzdHJpbmcmIHZhbHVlLCBkZXNjKTsKKyAgc3RyaW5nICogTXV0YWJsZVN0cmluZyAoaW50IG51bWJlciwgRmllbGRUeXBlIHR5cGUsIGRlc2MpOworICBNZXNzYWdlTGl0ZSogTXV0YWJsZU1lc3NhZ2UoaW50IG51bWJlciwgRmllbGRUeXBlIHR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNZXNzYWdlTGl0ZSYgcHJvdG90eXBlLCBkZXNjKTsKKyAgTWVzc2FnZUxpdGUqIE11dGFibGVNZXNzYWdlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVjc3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VGYWN0b3J5KiBmYWN0b3J5KTsKKyAgLy8gQWRkcyB0aGUgZ2l2ZW4gbWVzc2FnZSB0byB0aGUgRXh0ZW5zaW9uU2V0LCB0YWtpbmcgb3duZXJzaGlwIG9mIHRoZQorICAvLyBtZXNzYWdlIG9iamVjdC4gRXhpc3RpbmcgbWVzc2FnZSB3aXRoIHRoZSBzYW1lIG51bWJlciB3aWxsIGJlIGRlbGV0ZWQuCisgIC8vIElmICJtZXNzYWdlIiBpcyBOVUxMLCB0aGlzIGlzIGVxdWl2YWxlbnQgdG8gIkNsZWFyRXh0ZW5zaW9uKG51bWJlcikiLgorICB2b2lkIFNldEFsbG9jYXRlZE1lc3NhZ2UoaW50IG51bWJlciwgRmllbGRUeXBlIHR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlTGl0ZSogbWVzc2FnZSk7CisgIHZvaWQgVW5zYWZlQXJlbmFTZXRBbGxvY2F0ZWRNZXNzYWdlKGludCBudW1iZXIsIEZpZWxkVHlwZSB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VMaXRlKiBtZXNzYWdlKTsKKyAgTWVzc2FnZUxpdGUqIFJlbGVhc2VNZXNzYWdlKGludCBudW1iZXIsIGNvbnN0IE1lc3NhZ2VMaXRlJiBwcm90b3R5cGUpOworICBNZXNzYWdlTGl0ZSogVW5zYWZlQXJlbmFSZWxlYXNlTWVzc2FnZSgKKyAgICAgIGludCBudW1iZXIsIGNvbnN0IE1lc3NhZ2VMaXRlJiBwcm90b3R5cGUpOworCisgIE1lc3NhZ2VMaXRlKiBSZWxlYXNlTWVzc2FnZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlRmFjdG9yeSogZmFjdG9yeSk7CisjdW5kZWYgZGVzYworICA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYU5vVmlydHVhbCgpIGNvbnN0IHsgcmV0dXJuIGFyZW5hXzsgfQorCisgIC8vIHJlcGVhdGVkIGZpZWxkcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gRmV0Y2hlcyBhIFJlcGVhdGVkRmllbGQgZXh0ZW5zaW9uIGJ5IG51bWJlcjsgcmV0dXJucyB8ZGVmYXVsdF92YWx1ZXwKKyAgLy8gaWYgbm8gc3VjaCBleHRlbnNpb24gZXhpc3RzLiBVc2VyIHNob3VsZCBub3QgdG91Y2ggdGhpcyBkaXJlY3RseTsgaXQgaXMKKyAgLy8gdXNlZCBieSB0aGUgR2V0UmVwZWF0ZWRFeHRlbnNpb24oKSBtZXRob2QuCisgIGNvbnN0IHZvaWQqIEdldFJhd1JlcGVhdGVkRmllbGQoaW50IG51bWJlciwgY29uc3Qgdm9pZCogZGVmYXVsdF92YWx1ZSkgY29uc3Q7CisgIC8vIEZldGNoZXMgYSBtdXRhYmxlIHZlcnNpb24gb2YgYSBSZXBlYXRlZEZpZWxkIGV4dGVuc2lvbiBieSBudW1iZXIsCisgIC8vIGluc3RhbnRpYXRpbmcgb25lIGlmIG5vbmUgZXhpc3RzLiBTaW1pbGFyIHRvIGFib3ZlLCB1c2VyIHNob3VsZCBub3QgdXNlCisgIC8vIHRoaXMgZGlyZWN0bHk7IGl0IHVuZGVybGllcyBNdXRhYmxlUmVwZWF0ZWRFeHRlbnNpb24oKS4KKyAgdm9pZCogTXV0YWJsZVJhd1JlcGVhdGVkRmllbGQoaW50IG51bWJlciwgRmllbGRUeXBlIGZpZWxkX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgcGFja2VkLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2MpOworCisgIC8vIFRoaXMgaXMgYW4gb3ZlcmxvYWQgb2YgTXV0YWJsZVJhd1JlcGVhdGVkRmllbGQgdG8gbWFpbnRhaW4gY29tcGF0aWJpbGl0eQorICAvLyB3aXRoIG9sZCBjb2RlIHVzaW5nIGEgcHJldmlvdXMgQVBJLiBUaGlzIHZlcnNpb24gb2YKKyAgLy8gTXV0YWJsZVJhd1JlcGVhdGVkRmllbGQoKSB3aWxsIEdPT0dMRV9DSEVDSy1mYWlsIG9uIGEgbWlzc2luZyBleHRlbnNpb24uCisgIC8vIChFLmcuOiBib3JnL2NsaWVudHMvaW50ZXJuYWwvcHJvdG8xL3Byb3RvMl9yZWZsZWN0aW9uLmNjLikKKyAgdm9pZCogTXV0YWJsZVJhd1JlcGVhdGVkRmllbGQoaW50IG51bWJlcik7CisKKyAgaW50MzIgIEdldFJlcGVhdGVkSW50MzIgKGludCBudW1iZXIsIGludCBpbmRleCkgY29uc3Q7CisgIGludDY0ICBHZXRSZXBlYXRlZEludDY0IChpbnQgbnVtYmVyLCBpbnQgaW5kZXgpIGNvbnN0OworICB1aW50MzIgR2V0UmVwZWF0ZWRVSW50MzIoaW50IG51bWJlciwgaW50IGluZGV4KSBjb25zdDsKKyAgdWludDY0IEdldFJlcGVhdGVkVUludDY0KGludCBudW1iZXIsIGludCBpbmRleCkgY29uc3Q7CisgIGZsb2F0ICBHZXRSZXBlYXRlZEZsb2F0IChpbnQgbnVtYmVyLCBpbnQgaW5kZXgpIGNvbnN0OworICBkb3VibGUgR2V0UmVwZWF0ZWREb3VibGUoaW50IG51bWJlciwgaW50IGluZGV4KSBjb25zdDsKKyAgYm9vbCAgIEdldFJlcGVhdGVkQm9vbCAgKGludCBudW1iZXIsIGludCBpbmRleCkgY29uc3Q7CisgIGludCAgICBHZXRSZXBlYXRlZEVudW0gIChpbnQgbnVtYmVyLCBpbnQgaW5kZXgpIGNvbnN0OworICBjb25zdCBzdHJpbmcgJiBHZXRSZXBlYXRlZFN0cmluZyAoaW50IG51bWJlciwgaW50IGluZGV4KSBjb25zdDsKKyAgY29uc3QgTWVzc2FnZUxpdGUmIEdldFJlcGVhdGVkTWVzc2FnZShpbnQgbnVtYmVyLCBpbnQgaW5kZXgpIGNvbnN0OworCisgIHZvaWQgU2V0UmVwZWF0ZWRJbnQzMiAoaW50IG51bWJlciwgaW50IGluZGV4LCBpbnQzMiAgdmFsdWUpOworICB2b2lkIFNldFJlcGVhdGVkSW50NjQgKGludCBudW1iZXIsIGludCBpbmRleCwgaW50NjQgIHZhbHVlKTsKKyAgdm9pZCBTZXRSZXBlYXRlZFVJbnQzMihpbnQgbnVtYmVyLCBpbnQgaW5kZXgsIHVpbnQzMiB2YWx1ZSk7CisgIHZvaWQgU2V0UmVwZWF0ZWRVSW50NjQoaW50IG51bWJlciwgaW50IGluZGV4LCB1aW50NjQgdmFsdWUpOworICB2b2lkIFNldFJlcGVhdGVkRmxvYXQgKGludCBudW1iZXIsIGludCBpbmRleCwgZmxvYXQgIHZhbHVlKTsKKyAgdm9pZCBTZXRSZXBlYXRlZERvdWJsZShpbnQgbnVtYmVyLCBpbnQgaW5kZXgsIGRvdWJsZSB2YWx1ZSk7CisgIHZvaWQgU2V0UmVwZWF0ZWRCb29sICAoaW50IG51bWJlciwgaW50IGluZGV4LCBib29sICAgdmFsdWUpOworICB2b2lkIFNldFJlcGVhdGVkRW51bSAgKGludCBudW1iZXIsIGludCBpbmRleCwgaW50ICAgIHZhbHVlKTsKKyAgdm9pZCBTZXRSZXBlYXRlZFN0cmluZyhpbnQgbnVtYmVyLCBpbnQgaW5kZXgsIGNvbnN0IHN0cmluZyYgdmFsdWUpOworICBzdHJpbmcgKiBNdXRhYmxlUmVwZWF0ZWRTdHJpbmcgKGludCBudW1iZXIsIGludCBpbmRleCk7CisgIE1lc3NhZ2VMaXRlKiBNdXRhYmxlUmVwZWF0ZWRNZXNzYWdlKGludCBudW1iZXIsIGludCBpbmRleCk7CisKKyNkZWZpbmUgZGVzYyBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgIC8vIGF2b2lkIGxpbmUgd3JhcHBpbmcKKyAgdm9pZCBBZGRJbnQzMiAoaW50IG51bWJlciwgRmllbGRUeXBlIHR5cGUsIGJvb2wgcGFja2VkLCBpbnQzMiAgdmFsdWUsIGRlc2MpOworICB2b2lkIEFkZEludDY0IChpbnQgbnVtYmVyLCBGaWVsZFR5cGUgdHlwZSwgYm9vbCBwYWNrZWQsIGludDY0ICB2YWx1ZSwgZGVzYyk7CisgIHZvaWQgQWRkVUludDMyKGludCBudW1iZXIsIEZpZWxkVHlwZSB0eXBlLCBib29sIHBhY2tlZCwgdWludDMyIHZhbHVlLCBkZXNjKTsKKyAgdm9pZCBBZGRVSW50NjQoaW50IG51bWJlciwgRmllbGRUeXBlIHR5cGUsIGJvb2wgcGFja2VkLCB1aW50NjQgdmFsdWUsIGRlc2MpOworICB2b2lkIEFkZEZsb2F0IChpbnQgbnVtYmVyLCBGaWVsZFR5cGUgdHlwZSwgYm9vbCBwYWNrZWQsIGZsb2F0ICB2YWx1ZSwgZGVzYyk7CisgIHZvaWQgQWRkRG91YmxlKGludCBudW1iZXIsIEZpZWxkVHlwZSB0eXBlLCBib29sIHBhY2tlZCwgZG91YmxlIHZhbHVlLCBkZXNjKTsKKyAgdm9pZCBBZGRCb29sICAoaW50IG51bWJlciwgRmllbGRUeXBlIHR5cGUsIGJvb2wgcGFja2VkLCBib29sICAgdmFsdWUsIGRlc2MpOworICB2b2lkIEFkZEVudW0gIChpbnQgbnVtYmVyLCBGaWVsZFR5cGUgdHlwZSwgYm9vbCBwYWNrZWQsIGludCAgICB2YWx1ZSwgZGVzYyk7CisgIHZvaWQgQWRkU3RyaW5nKGludCBudW1iZXIsIEZpZWxkVHlwZSB0eXBlLCBjb25zdCBzdHJpbmcmIHZhbHVlLCBkZXNjKTsKKyAgc3RyaW5nICogQWRkU3RyaW5nIChpbnQgbnVtYmVyLCBGaWVsZFR5cGUgdHlwZSwgZGVzYyk7CisgIE1lc3NhZ2VMaXRlKiBBZGRNZXNzYWdlKGludCBudW1iZXIsIEZpZWxkVHlwZSB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNZXNzYWdlTGl0ZSYgcHJvdG90eXBlLCBkZXNjKTsKKyAgTWVzc2FnZUxpdGUqIEFkZE1lc3NhZ2UoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlRmFjdG9yeSogZmFjdG9yeSk7CisgIHZvaWQgQWRkQWxsb2NhdGVkTWVzc2FnZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlTGl0ZSogbmV3X2VudHJ5KTsKKyN1bmRlZiBkZXNjCisKKyAgdm9pZCBSZW1vdmVMYXN0KGludCBudW1iZXIpOworICBNZXNzYWdlTGl0ZSogUmVsZWFzZUxhc3QoaW50IG51bWJlcik7CisgIHZvaWQgU3dhcEVsZW1lbnRzKGludCBudW1iZXIsIGludCBpbmRleDEsIGludCBpbmRleDIpOworCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8vIFRPRE8oa2VudG9uKTogIEhhcmRjb3JlIG1lbW9yeSBtYW5hZ2VtZW50IGFjY2Vzc29ycworCisgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgIC8vIGNvbnZlbmllbmNlIG1ldGhvZHMgZm9yIGltcGxlbWVudGluZyBtZXRob2RzIG9mIE1lc3NhZ2UKKyAgLy8KKyAgLy8gVGhlc2UgY291bGQgYWxsIGJlIGltcGxlbWVudGVkIGluIHRlcm1zIG9mIHRoZSBvdGhlciBtZXRob2RzIG9mIHRoaXMKKyAgLy8gY2xhc3MsIGJ1dCBwcm92aWRpbmcgdGhlbSBoZXJlIGhlbHBzIGtlZXAgdGhlIGdlbmVyYXRlZCBjb2RlIHNpemUgZG93bi4KKworICB2b2lkIENsZWFyKCk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IEV4dGVuc2lvblNldCYgb3RoZXIpOworICB2b2lkIFN3YXAoRXh0ZW5zaW9uU2V0KiBvdGhlcik7CisgIHZvaWQgU3dhcEV4dGVuc2lvbihFeHRlbnNpb25TZXQqIG90aGVyLCBpbnQgbnVtYmVyKTsKKyAgYm9vbCBJc0luaXRpYWxpemVkKCkgY29uc3Q7CisKKyAgLy8gUGFyc2VzIGEgc2luZ2xlIGV4dGVuc2lvbiBmcm9tIHRoZSBpbnB1dC4gVGhlIGlucHV0IHNob3VsZCBzdGFydCBvdXQKKyAgLy8gcG9zaXRpb25lZCBpbW1lZGlhdGVseSBhZnRlciB0aGUgdGFnLgorICBib29sIFBhcnNlRmllbGQodWludDMyIHRhZywgaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgRXh0ZW5zaW9uRmluZGVyKiBleHRlbnNpb25fZmluZGVyLAorICAgICAgICAgICAgICAgICAgRmllbGRTa2lwcGVyKiBmaWVsZF9za2lwcGVyKTsKKworICAvLyBTcGVjaWZpYyB2ZXJzaW9ucyBmb3IgbGl0ZSBvciBmdWxsIG1lc3NhZ2VzIChjb25zdHJ1Y3RzIHRoZSBhcHByb3ByaWF0ZQorICAvLyBGaWVsZFNraXBwZXIgYXV0b21hdGljYWxseSkuICB8Y29udGFpbmluZ190eXBlfCBpcyB0aGUgZGVmYXVsdAorICAvLyBpbnN0YW5jZSBmb3IgdGhlIGNvbnRhaW5pbmcgbWVzc2FnZTsgaXQgaXMgdXNlZCBvbmx5IHRvIGxvb2sgdXAgdGhlCisgIC8vIGV4dGVuc2lvbiBieSBudW1iZXIuICBTZWUgUmVnaXN0ZXJFeHRlbnNpb24oKSwgYWJvdmUuICBVbmxpa2UgdGhlIG90aGVyCisgIC8vIG1ldGhvZHMgb2YgRXh0ZW5zaW9uU2V0LCB0aGlzIG9ubHkgd29ya3MgZm9yIGdlbmVyYXRlZCBtZXNzYWdlIHR5cGVzIC0tCisgIC8vIGl0IGxvb2tzIHVwIGV4dGVuc2lvbnMgcmVnaXN0ZXJlZCB1c2luZyBSZWdpc3RlckV4dGVuc2lvbigpLgorICBib29sIFBhcnNlRmllbGQodWludDMyIHRhZywgaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZUxpdGUqIGNvbnRhaW5pbmdfdHlwZSk7CisgIGJvb2wgUGFyc2VGaWVsZCh1aW50MzIgdGFnLCBpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsCisgICAgICAgICAgICAgICAgICBjb25zdCBNZXNzYWdlKiBjb250YWluaW5nX3R5cGUsCisgICAgICAgICAgICAgICAgICBVbmtub3duRmllbGRTZXQqIHVua25vd25fZmllbGRzKTsKKyAgYm9vbCBQYXJzZUZpZWxkKHVpbnQzMiB0YWcsIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2VMaXRlKiBjb250YWluaW5nX3R5cGUsCisgICAgICAgICAgICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIHVua25vd25fZmllbGRzKTsKKworICAvLyBQYXJzZSBhbiBlbnRpcmUgbWVzc2FnZSBpbiBNZXNzYWdlU2V0IGZvcm1hdC4gIFN1Y2ggbWVzc2FnZXMgaGF2ZSBubworICAvLyBmaWVsZHMsIG9ubHkgZXh0ZW5zaW9ucy4KKyAgYm9vbCBQYXJzZU1lc3NhZ2VTZXQoaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICBFeHRlbnNpb25GaW5kZXIqIGV4dGVuc2lvbl9maW5kZXIsCisgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VTZXRGaWVsZFNraXBwZXIqIGZpZWxkX3NraXBwZXIpOworCisgIC8vIFNwZWNpZmljIHZlcnNpb25zIGZvciBsaXRlIG9yIGZ1bGwgbWVzc2FnZXMgKGNvbnN0cnVjdHMgdGhlIGFwcHJvcHJpYXRlCisgIC8vIEZpZWxkU2tpcHBlciBhdXRvbWF0aWNhbGx5KS4KKyAgYm9vbCBQYXJzZU1lc3NhZ2VTZXQoaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNZXNzYWdlTGl0ZSogY29udGFpbmluZ190eXBlKTsKKyAgYm9vbCBQYXJzZU1lc3NhZ2VTZXQoaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNZXNzYWdlKiBjb250YWluaW5nX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgIFVua25vd25GaWVsZFNldCogdW5rbm93bl9maWVsZHMpOworCisgIC8vIFdyaXRlIGFsbCBleHRlbnNpb24gZmllbGRzIHdpdGggZmllbGQgbnVtYmVycyBpbiB0aGUgcmFuZ2UKKyAgLy8gICBbc3RhcnRfZmllbGRfbnVtYmVyLCBlbmRfZmllbGRfbnVtYmVyKQorICAvLyB0byB0aGUgb3V0cHV0IHN0cmVhbSwgdXNpbmcgdGhlIGNhY2hlZCBzaXplcyBjb21wdXRlZCB3aGVuIEJ5dGVTaXplKCkgd2FzCisgIC8vIGxhc3QgY2FsbGVkLiAgTm90ZSB0aGF0IHRoZSByYW5nZSBib3VuZHMgYXJlIGluY2x1c2l2ZS1leGNsdXNpdmUuCisgIHZvaWQgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKGludCBzdGFydF9maWVsZF9udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBlbmRfZmllbGRfbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3Q7CisKKyAgLy8gU2FtZSBhcyBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMsIGJ1dCB3aXRob3V0IGFueSBib3VuZHMgY2hlY2tpbmcuCisgIC8vIFRoZSBjYWxsZXIgbXVzdCBlbnN1cmUgdGhhdCB0YXJnZXQgaGFzIHN1ZmZpY2llbnQgY2FwYWNpdHkgZm9yIHRoZQorICAvLyBzZXJpYWxpemVkIGV4dGVuc2lvbnMuCisgIC8vCisgIC8vIFJldHVybnMgYSBwb2ludGVyIHBhc3QgdGhlIGxhc3Qgd3JpdHRlbiBieXRlLgorICB1aW50OCogU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheShpbnQgc3RhcnRfZmllbGRfbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZW5kX2ZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDgqIHRhcmdldCkgY29uc3Q7CisKKyAgLy8gTGlrZSBhYm92ZSBidXQgc2VyaWFsaXplcyBpbiBNZXNzYWdlU2V0IGZvcm1hdC4KKyAgdm9pZCBTZXJpYWxpemVNZXNzYWdlU2V0V2l0aENhY2hlZFNpemVzKGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgdWludDgqIFNlcmlhbGl6ZU1lc3NhZ2VTZXRXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KHVpbnQ4KiB0YXJnZXQpIGNvbnN0OworCisgIC8vIFJldHVybnMgdGhlIHRvdGFsIHNlcmlhbGl6ZWQgc2l6ZSBvZiBhbGwgdGhlIGV4dGVuc2lvbnMuCisgIGludCBCeXRlU2l6ZSgpIGNvbnN0OworCisgIC8vIExpa2UgQnl0ZVNpemUoKSBidXQgdXNlcyBNZXNzYWdlU2V0IGZvcm1hdC4KKyAgaW50IE1lc3NhZ2VTZXRCeXRlU2l6ZSgpIGNvbnN0OworCisgIC8vIFJldHVybnMgKGFuIGVzdGltYXRlIG9mKSB0aGUgdG90YWwgbnVtYmVyIG9mIGJ5dGVzIHVzZWQgZm9yIHN0b3JpbmcgdGhlCisgIC8vIGV4dGVuc2lvbnMgaW4gbWVtb3J5LCBleGNsdWRpbmcgc2l6ZW9mKCp0aGlzKS4gIElmIHRoZSBFeHRlbnNpb25TZXQgaXMKKyAgLy8gZm9yIGEgbGl0ZSBtZXNzYWdlIChhbmQgdGh1cyBwb3NzaWJseSBjb250YWlucyBsaXRlIG1lc3NhZ2VzKSwgdGhlIHJlc3VsdHMKKyAgLy8gYXJlIHVuZGVmaW5lZCAobWlnaHQgd29yaywgbWlnaHQgY3Jhc2gsIG1pZ2h0IGNvcnJ1cHQgZGF0YSwgbWlnaHQgbm90IGV2ZW4KKyAgLy8gYmUgbGlua2VkIGluKS4gIEl0J3MgdXAgdG8gdGhlIHByb3RvY29sIGNvbXBpbGVyIHRvIGF2b2lkIGNhbGxpbmcgdGhpcyBvbgorICAvLyBzdWNoIEV4dGVuc2lvblNldHMgKGVhc3kgZW5vdWdoIHNpbmNlIGxpdGUgbWVzc2FnZXMgZG9uJ3QgaW1wbGVtZW50CisgIC8vIFNwYWNlVXNlZCgpKS4KKyAgaW50IFNwYWNlVXNlZEV4Y2x1ZGluZ1NlbGYoKSBjb25zdDsKKworIHByaXZhdGU6CisKKyAgLy8gSW50ZXJmYWNlIG9mIGEgbGF6aWx5IHBhcnNlZCBzaW5ndWxhciBtZXNzYWdlIGV4dGVuc2lvbi4KKyAgY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIExhenlNZXNzYWdlRXh0ZW5zaW9uIHsKKyAgIHB1YmxpYzoKKyAgICBMYXp5TWVzc2FnZUV4dGVuc2lvbigpIHt9CisgICAgdmlydHVhbCB+TGF6eU1lc3NhZ2VFeHRlbnNpb24oKSB7fQorCisgICAgdmlydHVhbCBMYXp5TWVzc2FnZUV4dGVuc2lvbiogTmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdCA9IDA7CisgICAgdmlydHVhbCBjb25zdCBNZXNzYWdlTGl0ZSYgR2V0TWVzc2FnZSgKKyAgICAgICAgY29uc3QgTWVzc2FnZUxpdGUmIHByb3RvdHlwZSkgY29uc3QgPSAwOworICAgIHZpcnR1YWwgTWVzc2FnZUxpdGUqIE11dGFibGVNZXNzYWdlKGNvbnN0IE1lc3NhZ2VMaXRlJiBwcm90b3R5cGUpID0gMDsKKyAgICB2aXJ0dWFsIHZvaWQgU2V0QWxsb2NhdGVkTWVzc2FnZShNZXNzYWdlTGl0ZSAqbWVzc2FnZSkgPSAwOworICAgIHZpcnR1YWwgdm9pZCBVbnNhZmVBcmVuYVNldEFsbG9jYXRlZE1lc3NhZ2UoTWVzc2FnZUxpdGUgKm1lc3NhZ2UpID0gMDsKKyAgICB2aXJ0dWFsIE1lc3NhZ2VMaXRlKiBSZWxlYXNlTWVzc2FnZShjb25zdCBNZXNzYWdlTGl0ZSYgcHJvdG90eXBlKSA9IDA7CisgICAgdmlydHVhbCBNZXNzYWdlTGl0ZSogVW5zYWZlQXJlbmFSZWxlYXNlTWVzc2FnZSgKKyAgICAgICAgY29uc3QgTWVzc2FnZUxpdGUmIHByb3RvdHlwZSkgPSAwOworCisgICAgdmlydHVhbCBib29sIElzSW5pdGlhbGl6ZWQoKSBjb25zdCA9IDA7CisgICAgdmlydHVhbCBpbnQgQnl0ZVNpemUoKSBjb25zdCA9IDA7CisgICAgdmlydHVhbCBpbnQgU3BhY2VVc2VkKCkgY29uc3QgPSAwOworCisgICAgdmlydHVhbCB2b2lkIE1lcmdlRnJvbShjb25zdCBMYXp5TWVzc2FnZUV4dGVuc2lvbiYgb3RoZXIpID0gMDsKKyAgICB2aXJ0dWFsIHZvaWQgQ2xlYXIoKSA9IDA7CisKKyAgICB2aXJ0dWFsIGJvb2wgUmVhZE1lc3NhZ2UoY29uc3QgTWVzc2FnZUxpdGUmIHByb3RvdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KSA9IDA7CisgICAgdmlydHVhbCB2b2lkIFdyaXRlTWVzc2FnZShpbnQgbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0ID0gMDsKKyAgICB2aXJ0dWFsIHVpbnQ4KiBXcml0ZU1lc3NhZ2VUb0FycmF5KGludCBudW1iZXIsIHVpbnQ4KiB0YXJnZXQpIGNvbnN0ID0gMDsKKyAgIHByaXZhdGU6CisgICAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKExhenlNZXNzYWdlRXh0ZW5zaW9uKTsKKyAgfTsKKyAgc3RydWN0IEV4dGVuc2lvbiB7CisgICAgLy8gVGhlIG9yZGVyIG9mIHRoZXNlIGZpZWxkcyBwYWNrcyBFeHRlbnNpb24gaW50byAyNCBieXRlcyB3aGVuIHVzaW5nIDgKKyAgICAvLyBieXRlIGFsaWdubWVudC4gQ29uc2lkZXIgdGhpcyB3aGVuIGFkZGluZyBvciByZW1vdmluZyBmaWVsZHMgaGVyZS4KKyAgICB1bmlvbiB7CisgICAgICBpbnQzMiAgICAgICAgICAgICAgICAgaW50MzJfdmFsdWU7CisgICAgICBpbnQ2NCAgICAgICAgICAgICAgICAgaW50NjRfdmFsdWU7CisgICAgICB1aW50MzIgICAgICAgICAgICAgICAgdWludDMyX3ZhbHVlOworICAgICAgdWludDY0ICAgICAgICAgICAgICAgIHVpbnQ2NF92YWx1ZTsKKyAgICAgIGZsb2F0ICAgICAgICAgICAgICAgICBmbG9hdF92YWx1ZTsKKyAgICAgIGRvdWJsZSAgICAgICAgICAgICAgICBkb3VibGVfdmFsdWU7CisgICAgICBib29sICAgICAgICAgICAgICAgICAgYm9vbF92YWx1ZTsKKyAgICAgIGludCAgICAgICAgICAgICAgICAgICBlbnVtX3ZhbHVlOworICAgICAgc3RyaW5nKiAgICAgICAgICAgICAgIHN0cmluZ192YWx1ZTsKKyAgICAgIE1lc3NhZ2VMaXRlKiAgICAgICAgICBtZXNzYWdlX3ZhbHVlOworICAgICAgTGF6eU1lc3NhZ2VFeHRlbnNpb24qIGxhenltZXNzYWdlX3ZhbHVlOworCisgICAgICBSZXBlYXRlZEZpZWxkICAgPGludDMyICAgICAgPiogcmVwZWF0ZWRfaW50MzJfdmFsdWU7CisgICAgICBSZXBlYXRlZEZpZWxkICAgPGludDY0ICAgICAgPiogcmVwZWF0ZWRfaW50NjRfdmFsdWU7CisgICAgICBSZXBlYXRlZEZpZWxkICAgPHVpbnQzMiAgICAgPiogcmVwZWF0ZWRfdWludDMyX3ZhbHVlOworICAgICAgUmVwZWF0ZWRGaWVsZCAgIDx1aW50NjQgICAgID4qIHJlcGVhdGVkX3VpbnQ2NF92YWx1ZTsKKyAgICAgIFJlcGVhdGVkRmllbGQgICA8ZmxvYXQgICAgICA+KiByZXBlYXRlZF9mbG9hdF92YWx1ZTsKKyAgICAgIFJlcGVhdGVkRmllbGQgICA8ZG91YmxlICAgICA+KiByZXBlYXRlZF9kb3VibGVfdmFsdWU7CisgICAgICBSZXBlYXRlZEZpZWxkICAgPGJvb2wgICAgICAgPiogcmVwZWF0ZWRfYm9vbF92YWx1ZTsKKyAgICAgIFJlcGVhdGVkRmllbGQgICA8aW50ICAgICAgICA+KiByZXBlYXRlZF9lbnVtX3ZhbHVlOworICAgICAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmcgICAgID4qIHJlcGVhdGVkX3N0cmluZ192YWx1ZTsKKyAgICAgIFJlcGVhdGVkUHRyRmllbGQ8TWVzc2FnZUxpdGU+KiByZXBlYXRlZF9tZXNzYWdlX3ZhbHVlOworICAgIH07CisKKyAgICBGaWVsZFR5cGUgdHlwZTsKKyAgICBib29sIGlzX3JlcGVhdGVkOworCisgICAgLy8gRm9yIHNpbmd1bGFyIHR5cGVzLCBpbmRpY2F0ZXMgaWYgdGhlIGV4dGVuc2lvbiBpcyAiY2xlYXJlZCIuICBUaGlzCisgICAgLy8gaGFwcGVucyB3aGVuIGFuIGV4dGVuc2lvbiBpcyBzZXQgYW5kIHRoZW4gbGF0ZXIgY2xlYXJlZCBieSB0aGUgY2FsbGVyLgorICAgIC8vIFdlIHdhbnQgdG8ga2VlcCB0aGUgRXh0ZW5zaW9uIG9iamVjdCBhcm91bmQgZm9yIHJldXNlLCBzbyBpbnN0ZWFkIG9mCisgICAgLy8gcmVtb3ZpbmcgaXQgZnJvbSB0aGUgbWFwLCB3ZSBqdXN0IHNldCBpc19jbGVhcmVkID0gdHJ1ZS4gIFRoaXMgaGFzIG5vCisgICAgLy8gbWVhbmluZyBmb3IgcmVwZWF0ZWQgdHlwZXM7IGZvciB0aG9zZSwgdGhlIHNpemUgb2YgdGhlIFJlcGVhdGVkRmllbGQKKyAgICAvLyBzaW1wbHkgYmVjb21lcyB6ZXJvIHdoZW4gY2xlYXJlZC4KKyAgICBib29sIGlzX2NsZWFyZWQgOiA0OworCisgICAgLy8gRm9yIHNpbmd1bGFyIG1lc3NhZ2UgdHlwZXMsIGluZGljYXRlcyB3aGV0aGVyIGxhenkgcGFyc2luZyBpcyBlbmFibGVkCisgICAgLy8gZm9yIHRoaXMgZXh0ZW5zaW9uLiBUaGlzIGZpZWxkIGlzIG9ubHkgdmFsaWQgd2hlbiB0eXBlID09IFRZUEVfTUVTU0FHRQorICAgIC8vIGFuZCAhaXNfcmVwZWF0ZWQgYmVjYXVzZSB3ZSBvbmx5IHN1cHBvcnQgbGF6eSBwYXJzaW5nIGZvciBzaW5ndWxhcgorICAgIC8vIG1lc3NhZ2UgdHlwZXMgY3VycmVudGx5LiBJZiBpc19sYXp5ID0gdHJ1ZSwgdGhlIGV4dGVuc2lvbiBpcyBzdG9yZWQgaW4KKyAgICAvLyBsYXp5bWVzc2FnZV92YWx1ZS4gT3RoZXJ3aXNlLCB0aGUgZXh0ZW5zaW9uIHdpbGwgYmUgbWVzc2FnZV92YWx1ZS4KKyAgICBib29sIGlzX2xhenkgOiA0OworCisgICAgLy8gRm9yIHJlcGVhdGVkIHR5cGVzLCB0aGlzIGluZGljYXRlcyBpZiB0aGUgW3BhY2tlZD10cnVlXSBvcHRpb24gaXMgc2V0LgorICAgIGJvb2wgaXNfcGFja2VkOworCisgICAgLy8gRm9yIHBhY2tlZCBmaWVsZHMsIHRoZSBzaXplIG9mIHRoZSBwYWNrZWQgZGF0YSBpcyByZWNvcmRlZCBoZXJlIHdoZW4KKyAgICAvLyBCeXRlU2l6ZSgpIGlzIGNhbGxlZCB0aGVuIHVzZWQgZHVyaW5nIHNlcmlhbGl6YXRpb24uCisgICAgLy8gVE9ETyhrZW50b24pOiAgVXNlIGF0b21pYzxpbnQ+IHdoZW4gQysrIHN1cHBvcnRzIGl0LgorICAgIG11dGFibGUgaW50IGNhY2hlZF9zaXplOworCisgICAgLy8gVGhlIGRlc2NyaXB0b3IgZm9yIHRoaXMgZXh0ZW5zaW9uLCBpZiBvbmUgZXhpc3RzIGFuZCBpcyBrbm93bi4gIE1heSBiZQorICAgIC8vIE5VTEwuICBNdXN0IG5vdCBiZSBOVUxMIGlmIHRoZSBkZXNjcmlwdG9yIGZvciB0aGUgZXh0ZW5zaW9uIGRvZXMgbm90CisgICAgLy8gbGl2ZSBpbiB0aGUgc2FtZSBwb29sIGFzIHRoZSBkZXNjcmlwdG9yIGZvciB0aGUgY29udGFpbmluZyB0eXBlLgorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvcjsKKworICAgIC8vIFNvbWUgaGVscGVyIG1ldGhvZHMgZm9yIG9wZXJhdGlvbnMgb24gYSBzaW5nbGUgRXh0ZW5zaW9uLgorICAgIHZvaWQgU2VyaWFsaXplRmllbGRXaXRoQ2FjaGVkU2l6ZXMoCisgICAgICAgIGludCBudW1iZXIsCisgICAgICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgICB1aW50OCogU2VyaWFsaXplRmllbGRXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KAorICAgICAgICBpbnQgbnVtYmVyLAorICAgICAgICB1aW50OCogdGFyZ2V0KSBjb25zdDsKKyAgICB2b2lkIFNlcmlhbGl6ZU1lc3NhZ2VTZXRJdGVtV2l0aENhY2hlZFNpemVzKAorICAgICAgICBpbnQgbnVtYmVyLAorICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3Q7CisgICAgdWludDgqIFNlcmlhbGl6ZU1lc3NhZ2VTZXRJdGVtV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICAgICAgaW50IG51bWJlciwKKyAgICAgICAgdWludDgqIHRhcmdldCkgY29uc3Q7CisgICAgaW50IEJ5dGVTaXplKGludCBudW1iZXIpIGNvbnN0OworICAgIGludCBNZXNzYWdlU2V0SXRlbUJ5dGVTaXplKGludCBudW1iZXIpIGNvbnN0OworICAgIHZvaWQgQ2xlYXIoKTsKKyAgICBpbnQgR2V0U2l6ZSgpIGNvbnN0OworICAgIHZvaWQgRnJlZSgpOworICAgIGludCBTcGFjZVVzZWRFeGNsdWRpbmdTZWxmKCkgY29uc3Q7CisgIH07CisKKworICAvLyBNZXJnZXMgZXhpc3RpbmcgRXh0ZW5zaW9uIGZyb20gb3RoZXJfZXh0ZW5zaW9uCisgIHZvaWQgSW50ZXJuYWxFeHRlbnNpb25NZXJnZUZyb20oaW50IG51bWJlciwgY29uc3QgRXh0ZW5zaW9uJiBvdGhlcl9leHRlbnNpb24pOworCisgIC8vIFJldHVybnMgdHJ1ZSBhbmQgZmlsbHMgZmllbGRfbnVtYmVyIGFuZCBleHRlbnNpb24gaWYgZXh0ZW5zaW9uIGlzIGZvdW5kLgorICAvLyBOb3RlIHRvIHN1cHBvcnQgcGFja2VkIHJlcGVhdGVkIGZpZWxkIGNvbXBhdGliaWxpdHksIGl0IGFsc28gZmlsbHMgd2hldGhlcgorICAvLyB0aGUgdGFnIG9uIHdpcmUgaXMgcGFja2VkLCB3aGljaCBjYW4gYmUgZGlmZmVyZW50IGZyb20KKyAgLy8gZXh0ZW5zaW9uLT5pc19wYWNrZWQgKHdoZXRoZXIgcGFja2VkPXRydWUgaXMgc3BlY2lmaWVkKS4KKyAgYm9vbCBGaW5kRXh0ZW5zaW9uSW5mb0Zyb21UYWcodWludDMyIHRhZywgRXh0ZW5zaW9uRmluZGVyKiBleHRlbnNpb25fZmluZGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQqIGZpZWxkX251bWJlciwgRXh0ZW5zaW9uSW5mbyogZXh0ZW5zaW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sKiB3YXNfcGFja2VkX29uX3dpcmUpOworCisgIC8vIFJldHVybnMgdHJ1ZSBhbmQgZmlsbHMgZXh0ZW5zaW9uIGlmIGV4dGVuc2lvbiBpcyBmb3VuZC4KKyAgLy8gTm90ZSB0byBzdXBwb3J0IHBhY2tlZCByZXBlYXRlZCBmaWVsZCBjb21wYXRpYmlsaXR5LCBpdCBhbHNvIGZpbGxzIHdoZXRoZXIKKyAgLy8gdGhlIHRhZyBvbiB3aXJlIGlzIHBhY2tlZCwgd2hpY2ggY2FuIGJlIGRpZmZlcmVudCBmcm9tCisgIC8vIGV4dGVuc2lvbi0+aXNfcGFja2VkICh3aGV0aGVyIHBhY2tlZD10cnVlIGlzIHNwZWNpZmllZCkuCisgIGJvb2wgRmluZEV4dGVuc2lvbkluZm9Gcm9tRmllbGROdW1iZXIoaW50IHdpcmVfdHlwZSwgaW50IGZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeHRlbnNpb25GaW5kZXIqIGV4dGVuc2lvbl9maW5kZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXh0ZW5zaW9uSW5mbyogZXh0ZW5zaW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wqIHdhc19wYWNrZWRfb25fd2lyZSk7CisKKyAgLy8gUGFyc2VzIGEgc2luZ2xlIGV4dGVuc2lvbiBmcm9tIHRoZSBpbnB1dC4gVGhlIGlucHV0IHNob3VsZCBzdGFydCBvdXQKKyAgLy8gcG9zaXRpb25lZCBpbW1lZGlhdGVseSBhZnRlciB0aGUgd2lyZSB0YWcuIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBpbgorICAvLyBQYXJzZUZpZWxkKCkgYWZ0ZXIgZmllbGQgbnVtYmVyIGFuZCB3YXNfcGFja2VkX29uX3dpcmUgaXMgZXh0cmFjdGVkIGZyb20KKyAgLy8gdGhlIHdpcmUgdGFnIGFuZCBFeHRlbnNpb25JbmZvIGlzIGZvdW5kIGJ5IHRoZSBmaWVsZCBudW1iZXIuCisgIGJvb2wgUGFyc2VGaWVsZFdpdGhFeHRlbnNpb25JbmZvKGludCBmaWVsZF9udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgd2FzX3BhY2tlZF9vbl93aXJlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBFeHRlbnNpb25JbmZvJiBleHRlbnNpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmllbGRTa2lwcGVyKiBmaWVsZF9za2lwcGVyKTsKKworICAvLyBMaWtlIFBhcnNlRmllbGQoKSwgYnV0IHRoaXMgbWV0aG9kIG1heSBwYXJzZSBzaW5ndWxhciBtZXNzYWdlIGV4dGVuc2lvbnMKKyAgLy8gbGF6aWx5IGRlcGVuZGluZyBvbiB0aGUgdmFsdWUgb2YgRkxBR1NfZWFnZXJseV9wYXJzZV9tZXNzYWdlX3NldHMuCisgIGJvb2wgUGFyc2VGaWVsZE1heWJlTGF6aWx5KGludCB3aXJlX3R5cGUsIGludCBmaWVsZF9udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXh0ZW5zaW9uRmluZGVyKiBleHRlbnNpb25fZmluZGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlU2V0RmllbGRTa2lwcGVyKiBmaWVsZF9za2lwcGVyKTsKKworICAvLyBHZXRzIHRoZSBleHRlbnNpb24gd2l0aCB0aGUgZ2l2ZW4gbnVtYmVyLCBjcmVhdGluZyBpdCBpZiBpdCBkb2VzIG5vdAorICAvLyBhbHJlYWR5IGV4aXN0LiAgUmV0dXJucyB0cnVlIGlmIHRoZSBleHRlbnNpb24gZGlkIG5vdCBhbHJlYWR5IGV4aXN0LgorICBib29sIE1heWJlTmV3RXh0ZW5zaW9uKGludCBudW1iZXIsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICBFeHRlbnNpb24qKiByZXN1bHQpOworCisgIC8vIEdldHMgdGhlIHJlcGVhdGVkIGV4dGVuc2lvbiBmb3IgdGhlIGdpdmVuIGRlc2NyaXB0b3IsIGNyZWF0aW5nIGl0IGlmCisgIC8vIGl0IGRvZXMgbm90IGV4aXN0LgorICBFeHRlbnNpb24qIE1heWJlTmV3UmVwZWF0ZWRFeHRlbnNpb24oY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yKTsKKworICAvLyBQYXJzZSBhIHNpbmdsZSBNZXNzYWdlU2V0IGl0ZW0gLS0gY2FsbGVkIGp1c3QgYWZ0ZXIgdGhlIGl0ZW0gZ3JvdXAgc3RhcnQKKyAgLy8gdGFnIGhhcyBiZWVuIHJlYWQuCisgIGJvb2wgUGFyc2VNZXNzYWdlU2V0SXRlbShpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBFeHRlbnNpb25GaW5kZXIqIGV4dGVuc2lvbl9maW5kZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlU2V0RmllbGRTa2lwcGVyKiBmaWVsZF9za2lwcGVyKTsKKworICAvLyBIYWNrOiAgUmVwZWF0ZWRQdHJGaWVsZEJhc2UgZGVjbGFyZXMgRXh0ZW5zaW9uU2V0IGFzIGEgZnJpZW5kLiAgVGhpcworICAvLyAgIGZyaWVuZHNoaXAgc2hvdWxkIGF1dG9tYXRpY2FsbHkgZXh0ZW5kIHRvIEV4dGVuc2lvblNldDo6RXh0ZW5zaW9uLCBidXQKKyAgLy8gICB1bmZvcnR1bmF0ZWx5IHNvbWUgb2xkZXIgY29tcGlsZXJzIChlLmcuIEdDQyAzLjQuNCkgZG8gbm90IGltcGxlbWVudCB0aGlzCisgIC8vICAgY29ycmVjdGx5LiAgU28sIHdlIG11c3QgcHJvdmlkZSBoZWxwZXJzIGZvciBjYWxsaW5nIG1ldGhvZHMgb2YgdGhhdAorICAvLyAgIGNsYXNzLgorCisgIC8vIERlZmluZWQgaW4gZXh0ZW5zaW9uX3NldF9oZWF2eS5jYy4KKyAgc3RhdGljIGlubGluZSBpbnQgUmVwZWF0ZWRNZXNzYWdlX1NwYWNlVXNlZEV4Y2x1ZGluZ1NlbGYoCisgICAgICBSZXBlYXRlZFB0ckZpZWxkQmFzZSogZmllbGQpOworCisgIC8vIFRoZSBFeHRlbnNpb24gc3RydWN0IGlzIHNtYWxsIGVub3VnaCB0byBiZSBwYXNzZWQgYnkgdmFsdWUsIHNvIHdlIHVzZSBpdAorICAvLyBkaXJlY3RseSBhcyB0aGUgdmFsdWUgdHlwZSBpbiB0aGUgbWFwIHJhdGhlciB0aGFuIHVzZSBwb2ludGVycy4gIFdlIHVzZQorICAvLyBhIG1hcCByYXRoZXIgdGhhbiBoYXNoX21hcCBoZXJlIGJlY2F1c2Ugd2UgZXhwZWN0IG1vc3QgRXh0ZW5zaW9uU2V0cyB3aWxsCisgIC8vIG9ubHkgY29udGFpbiBhIHNtYWxsIG51bWJlciBvZiBleHRlbnNpb25zIHdoZXJlYXMgaGFzaF9tYXAgaXMgb3B0aW1pemVkCisgIC8vIGZvciAxMDAgZWxlbWVudHMgb3IgbW9yZS4gIEFsc28sIHdlIHdhbnQgQXBwZW5kVG9MaXN0KCkgdG8gb3JkZXIgZmllbGRzCisgIC8vIGJ5IGZpZWxkIG51bWJlci4KKyAgc3RkOjptYXA8aW50LCBFeHRlbnNpb24+IGV4dGVuc2lvbnNfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYV87CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhFeHRlbnNpb25TZXQpOworfTsKKworLy8gVGhlc2UgYXJlIGp1c3QgZm9yIGNvbnZlbmllbmNlLi4uCitpbmxpbmUgdm9pZCBFeHRlbnNpb25TZXQ6OlNldFN0cmluZyhpbnQgbnVtYmVyLCBGaWVsZFR5cGUgdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgTXV0YWJsZVN0cmluZyhudW1iZXIsIHR5cGUsIGRlc2NyaXB0b3IpLT5hc3NpZ24odmFsdWUpOworfQoraW5saW5lIHZvaWQgRXh0ZW5zaW9uU2V0OjpTZXRSZXBlYXRlZFN0cmluZyhpbnQgbnVtYmVyLCBpbnQgaW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgdmFsdWUpIHsKKyAgTXV0YWJsZVJlcGVhdGVkU3RyaW5nKG51bWJlciwgaW5kZXgpLT5hc3NpZ24odmFsdWUpOworfQoraW5saW5lIHZvaWQgRXh0ZW5zaW9uU2V0OjpBZGRTdHJpbmcoaW50IG51bWJlciwgRmllbGRUeXBlIHR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIEFkZFN0cmluZyhudW1iZXIsIHR5cGUsIGRlc2NyaXB0b3IpLT5hc3NpZ24odmFsdWUpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisvLyBHbHVlIGZvciBnZW5lcmF0ZWQgZXh0ZW5zaW9uIGFjY2Vzc29ycworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBUZW1wbGF0ZSBtYWdpYworCisvLyBGaXJzdCB3ZSBoYXZlIGEgc2V0IG9mIGNsYXNzZXMgcmVwcmVzZW50aW5nICJ0eXBlIHRyYWl0cyIgZm9yIGRpZmZlcmVudAorLy8gZmllbGQgdHlwZXMuICBBIHR5cGUgdHJhaXRzIGNsYXNzIGtub3dzIGhvdyB0byBpbXBsZW1lbnQgYmFzaWMgYWNjZXNzb3JzCisvLyBmb3IgZXh0ZW5zaW9ucyBvZiBhIHBhcnRpY3VsYXIgdHlwZSBnaXZlbiBhbiBFeHRlbnNpb25TZXQuICBUaGUgc2lnbmF0dXJlCisvLyBmb3IgYSB0eXBlIHRyYWl0cyBjbGFzcyBsb29rcyBsaWtlIHRoaXM6CisvLworLy8gICBjbGFzcyBUeXBlVHJhaXRzIHsKKy8vICAgIHB1YmxpYzoKKy8vICAgICB0eXBlZGVmID8gQ29uc3RUeXBlOworLy8gICAgIHR5cGVkZWYgPyBNdXRhYmxlVHlwZTsKKy8vICAgICAvLyBUeXBlVHJhaXRzIGZvciBzaW5ndWxhciBmaWVsZHMgYW5kIHJlcGVhdGVkIGZpZWxkcyB3aWxsIGRlZmluZSB0aGUKKy8vICAgICAvLyBzeW1ib2wgIlNpbmd1bGFyIiBvciAiUmVwZWF0ZWQiIHJlc3BlY3RpdmVseS4gVGhlc2UgdHdvIHN5bWJvbHMgd2lsbAorLy8gICAgIC8vIGJlIHVzZWQgaW4gZXh0ZW5zaW9uIGFjY2Vzc29ycyB0byBkaXN0aW5ndWlzaCBiZXR3ZWVuIHNpbmd1bGFyCisvLyAgICAgLy8gZXh0ZW5zaW9ucyBhbmQgcmVwZWF0ZWQgZXh0ZW5zaW9ucy4gSWYgdGhlIFR5cGVUcmFpdHMgZm9yIHRoZSBwYXNzZWQKKy8vICAgICAvLyBpbiBleHRlbnNpb24gZG9lc24ndCBoYXZlIHRoZSBleHBlY3RlZCBzeW1ib2wgZGVmaW5lZCwgaXQgbWVhbnMgdGhlCisvLyAgICAgLy8gdXNlciBpcyBwYXNzaW5nIGEgcmVwZWF0ZWQgZXh0ZW5zaW9uIHRvIGEgc2luZ3VsYXIgYWNjZXNzb3IsIG9yIHRoZQorLy8gICAgIC8vIG9wcG9zaXRlLiBJbiB0aGF0IGNhc2UgdGhlIEMrKyBjb21waWxlciB3aWxsIGdlbmVyYXRlIGFuIGVycm9yCisvLyAgICAgLy8gbWVzc2FnZSAibm8gbWF0Y2hpbmcgbWVtYmVyIGZ1bmN0aW9uIiB0byBpbmZvcm0gdGhlIHVzZXIuCisvLyAgICAgdHlwZWRlZiA/IFNpbmd1bGFyCisvLyAgICAgdHlwZWRlZiA/IFJlcGVhdGVkCisvLworLy8gICAgIHN0YXRpYyBpbmxpbmUgQ29uc3RUeXBlIEdldChpbnQgbnVtYmVyLCBjb25zdCBFeHRlbnNpb25TZXQmIHNldCk7CisvLyAgICAgc3RhdGljIGlubGluZSB2b2lkIFNldChpbnQgbnVtYmVyLCBDb25zdFR5cGUgdmFsdWUsIEV4dGVuc2lvblNldCogc2V0KTsKKy8vICAgICBzdGF0aWMgaW5saW5lIE11dGFibGVUeXBlIE11dGFibGUoaW50IG51bWJlciwgRXh0ZW5zaW9uU2V0KiBzZXQpOworLy8KKy8vICAgICAvLyBWYXJpYW50cyBmb3IgcmVwZWF0ZWQgZmllbGRzLgorLy8gICAgIHN0YXRpYyBpbmxpbmUgQ29uc3RUeXBlIEdldChpbnQgbnVtYmVyLCBjb25zdCBFeHRlbnNpb25TZXQmIHNldCwKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGluZGV4KTsKKy8vICAgICBzdGF0aWMgaW5saW5lIHZvaWQgU2V0KGludCBudW1iZXIsIGludCBpbmRleCwKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnN0VHlwZSB2YWx1ZSwgRXh0ZW5zaW9uU2V0KiBzZXQpOworLy8gICAgIHN0YXRpYyBpbmxpbmUgTXV0YWJsZVR5cGUgTXV0YWJsZShpbnQgbnVtYmVyLCBpbnQgaW5kZXgsCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4dGVuc2lvblNldCogc2V0KTsKKy8vICAgICBzdGF0aWMgaW5saW5lIHZvaWQgQWRkKGludCBudW1iZXIsIENvbnN0VHlwZSB2YWx1ZSwgRXh0ZW5zaW9uU2V0KiBzZXQpOworLy8gICAgIHN0YXRpYyBpbmxpbmUgTXV0YWJsZVR5cGUgQWRkKGludCBudW1iZXIsIEV4dGVuc2lvblNldCogc2V0KTsKKy8vICAgfTsKKy8vCisvLyBOb3QgYWxsIG9mIHRoZXNlIG1ldGhvZHMgbWFrZSBzZW5zZSBmb3IgYWxsIGZpZWxkIHR5cGVzLiAgRm9yIGV4YW1wbGUsIHRoZQorLy8gIk11dGFibGUiIG1ldGhvZHMgb25seSBtYWtlIHNlbnNlIGZvciBzdHJpbmdzIGFuZCBtZXNzYWdlcywgYW5kIHRoZQorLy8gcmVwZWF0ZWQgbWV0aG9kcyBvbmx5IG1ha2Ugc2Vuc2UgZm9yIHJlcGVhdGVkIHR5cGVzLiAgU28sIGVhY2ggdHlwZQorLy8gdHJhaXRzIGNsYXNzIGltcGxlbWVudHMgb25seSB0aGUgc2V0IG9mIG1ldGhvZHMgZnJvbSB0aGlzIHNpZ25hdHVyZSB0aGF0IGl0CisvLyBhY3R1YWxseSBzdXBwb3J0cy4gIFRoaXMgd2lsbCBjYXVzZSBhIGNvbXBpbGVyIGVycm9yIGlmIHRoZSB1c2VyIHRyaWVzIHRvCisvLyBhY2Nlc3MgYW4gZXh0ZW5zaW9uIHVzaW5nIGEgbWV0aG9kIHRoYXQgZG9lc24ndCBtYWtlIHNlbnNlIGZvciBpdHMgdHlwZS4KKy8vIEZvciBleGFtcGxlLCBpZiAiZm9vIiBpcyBhbiBleHRlbnNpb24gb2YgdHlwZSAib3B0aW9uYWwgaW50MzIiLCB0aGVuIGlmIHlvdQorLy8gdHJ5IHRvIHdyaXRlIGNvZGUgbGlrZToKKy8vICAgbXlfbWVzc2FnZS5NdXRhYmxlRXh0ZW5zaW9uKGZvbykKKy8vIHlvdSB3aWxsIGdldCBhIGNvbXBpbGUgZXJyb3IgYmVjYXVzZSBQcmltaXRpdmVUeXBlVHJhaXRzPGludDMyPiBkb2VzIG5vdAorLy8gaGF2ZSBhICJNdXRhYmxlKCkiIG1ldGhvZC4KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gUHJpbWl0aXZlVHlwZVRyYWl0cworCisvLyBTaW5jZSB0aGUgRXh0ZW5zaW9uU2V0IGhhcyBkaWZmZXJlbnQgbWV0aG9kcyBmb3IgZWFjaCBwcmltaXRpdmUgdHlwZSwKKy8vIHdlIG11c3QgZXhwbGljaXRseSBkZWZpbmUgdGhlIG1ldGhvZHMgb2YgdGhlIHR5cGUgdHJhaXRzIGNsYXNzIGZvciBlYWNoCisvLyBrbm93biB0eXBlLgordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+CitjbGFzcyBQcmltaXRpdmVUeXBlVHJhaXRzIHsKKyBwdWJsaWM6CisgIHR5cGVkZWYgVHlwZSBDb25zdFR5cGU7CisgIHR5cGVkZWYgVHlwZSBNdXRhYmxlVHlwZTsKKyAgdHlwZWRlZiBQcmltaXRpdmVUeXBlVHJhaXRzPFR5cGU+IFNpbmd1bGFyOworCisgIHN0YXRpYyBpbmxpbmUgQ29uc3RUeXBlIEdldChpbnQgbnVtYmVyLCBjb25zdCBFeHRlbnNpb25TZXQmIHNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnN0VHlwZSBkZWZhdWx0X3ZhbHVlKTsKKyAgc3RhdGljIGlubGluZSB2b2lkIFNldChpbnQgbnVtYmVyLCBGaWVsZFR5cGUgZmllbGRfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdFR5cGUgdmFsdWUsIEV4dGVuc2lvblNldCogc2V0KTsKK307CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBUeXBlPgorY2xhc3MgUmVwZWF0ZWRQcmltaXRpdmVUeXBlVHJhaXRzIHsKKyBwdWJsaWM6CisgIHR5cGVkZWYgVHlwZSBDb25zdFR5cGU7CisgIHR5cGVkZWYgVHlwZSBNdXRhYmxlVHlwZTsKKyAgdHlwZWRlZiBSZXBlYXRlZFByaW1pdGl2ZVR5cGVUcmFpdHM8VHlwZT4gUmVwZWF0ZWQ7CisKKyAgdHlwZWRlZiBSZXBlYXRlZEZpZWxkPFR5cGU+IFJlcGVhdGVkRmllbGRUeXBlOworCisgIHN0YXRpYyBpbmxpbmUgVHlwZSBHZXQoaW50IG51bWJlciwgY29uc3QgRXh0ZW5zaW9uU2V0JiBzZXQsIGludCBpbmRleCk7CisgIHN0YXRpYyBpbmxpbmUgdm9pZCBTZXQoaW50IG51bWJlciwgaW50IGluZGV4LCBUeXBlIHZhbHVlLCBFeHRlbnNpb25TZXQqIHNldCk7CisgIHN0YXRpYyBpbmxpbmUgdm9pZCBBZGQoaW50IG51bWJlciwgRmllbGRUeXBlIGZpZWxkX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc19wYWNrZWQsIFR5cGUgdmFsdWUsIEV4dGVuc2lvblNldCogc2V0KTsKKworICBzdGF0aWMgaW5saW5lIGNvbnN0IFJlcGVhdGVkRmllbGQ8Q29uc3RUeXBlPiYKKyAgICAgIEdldFJlcGVhdGVkKGludCBudW1iZXIsIGNvbnN0IEV4dGVuc2lvblNldCYgc2V0KTsKKyAgc3RhdGljIGlubGluZSBSZXBlYXRlZEZpZWxkPFR5cGU+KgorICAgICAgTXV0YWJsZVJlcGVhdGVkKGludCBudW1iZXIsIEZpZWxkVHlwZSBmaWVsZF90eXBlLAorICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaXNfcGFja2VkLCBFeHRlbnNpb25TZXQqIHNldCk7CisKKyAgc3RhdGljIGNvbnN0IFJlcGVhdGVkRmllbGRUeXBlKiBHZXREZWZhdWx0UmVwZWF0ZWRGaWVsZCgpOworfTsKKworTElCUFJPVE9CVUZfRVhQT1JUIGV4dGVybiBQcm90b2J1Zk9uY2VUeXBlIHJlcGVhdGVkX3ByaW1pdGl2ZV9nZW5lcmljX3R5cGVfdHJhaXRzX29uY2VfaW5pdF87CisKK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBSZXBlYXRlZFByaW1pdGl2ZUdlbmVyaWNUeXBlVHJhaXRzIHsKKyBwcml2YXRlOgorICB0ZW1wbGF0ZTx0eXBlbmFtZSBUeXBlPiBmcmllbmQgY2xhc3MgUmVwZWF0ZWRQcmltaXRpdmVUeXBlVHJhaXRzOworICBzdGF0aWMgdm9pZCBJbml0aWFsaXplRGVmYXVsdFJlcGVhdGVkRmllbGRzKCk7CisgIHN0YXRpYyB2b2lkIERlc3Ryb3lEZWZhdWx0UmVwZWF0ZWRGaWVsZHMoKTsKKyAgc3RhdGljIGNvbnN0IFJlcGVhdGVkRmllbGQ8aW50MzI+KiBkZWZhdWx0X3JlcGVhdGVkX2ZpZWxkX2ludDMyXzsKKyAgc3RhdGljIGNvbnN0IFJlcGVhdGVkRmllbGQ8aW50NjQ+KiBkZWZhdWx0X3JlcGVhdGVkX2ZpZWxkX2ludDY0XzsKKyAgc3RhdGljIGNvbnN0IFJlcGVhdGVkRmllbGQ8dWludDMyPiogZGVmYXVsdF9yZXBlYXRlZF9maWVsZF91aW50MzJfOworICBzdGF0aWMgY29uc3QgUmVwZWF0ZWRGaWVsZDx1aW50NjQ+KiBkZWZhdWx0X3JlcGVhdGVkX2ZpZWxkX3VpbnQ2NF87CisgIHN0YXRpYyBjb25zdCBSZXBlYXRlZEZpZWxkPGRvdWJsZT4qIGRlZmF1bHRfcmVwZWF0ZWRfZmllbGRfZG91YmxlXzsKKyAgc3RhdGljIGNvbnN0IFJlcGVhdGVkRmllbGQ8ZmxvYXQ+KiBkZWZhdWx0X3JlcGVhdGVkX2ZpZWxkX2Zsb2F0XzsKKyAgc3RhdGljIGNvbnN0IFJlcGVhdGVkRmllbGQ8Ym9vbD4qIGRlZmF1bHRfcmVwZWF0ZWRfZmllbGRfYm9vbF87Cit9OworCisjZGVmaW5lIFBST1RPQlVGX0RFRklORV9QUklNSVRJVkVfVFlQRShUWVBFLCBNRVRIT0QpICAgICAgICAgICAgICAgICAgICAgICBcCit0ZW1wbGF0ZTw+IGlubGluZSBUWVBFIFByaW1pdGl2ZVR5cGVUcmFpdHM8VFlQRT46OkdldCggICAgICAgICAgICAgICAgICAgICBcCisgICAgaW50IG51bWJlciwgY29uc3QgRXh0ZW5zaW9uU2V0JiBzZXQsIFRZUEUgZGVmYXVsdF92YWx1ZSkgeyAgICAgICAgICAgICBcCisgIHJldHVybiBzZXQuR2V0IyNNRVRIT0QobnVtYmVyLCBkZWZhdWx0X3ZhbHVlKTsgICAgICAgICAgICAgICAgICAgICAgICAgICBcCit9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCit0ZW1wbGF0ZTw+IGlubGluZSB2b2lkIFByaW1pdGl2ZVR5cGVUcmFpdHM8VFlQRT46OlNldCggICAgICAgICAgICAgICAgICAgICBcCisgICAgaW50IG51bWJlciwgRmllbGRUeXBlIGZpZWxkX3R5cGUsIFRZUEUgdmFsdWUsIEV4dGVuc2lvblNldCogc2V0KSB7ICAgICBcCisgIHNldC0+U2V0IyNNRVRIT0QobnVtYmVyLCBmaWVsZF90eXBlLCB2YWx1ZSwgTlVMTCk7ICAgICAgICAgICAgICAgICAgICAgICBcCit9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCit0ZW1wbGF0ZTw+IGlubGluZSBUWVBFIFJlcGVhdGVkUHJpbWl0aXZlVHlwZVRyYWl0czxUWVBFPjo6R2V0KCAgICAgICAgICAgICBcCisgICAgaW50IG51bWJlciwgY29uc3QgRXh0ZW5zaW9uU2V0JiBzZXQsIGludCBpbmRleCkgeyAgICAgICAgICAgICAgICAgICAgICBcCisgIHJldHVybiBzZXQuR2V0UmVwZWF0ZWQjI01FVEhPRChudW1iZXIsIGluZGV4KTsgICAgICAgICAgICAgICAgICAgICAgICAgICBcCit9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCit0ZW1wbGF0ZTw+IGlubGluZSB2b2lkIFJlcGVhdGVkUHJpbWl0aXZlVHlwZVRyYWl0czxUWVBFPjo6U2V0KCAgICAgICAgICAgICBcCisgICAgaW50IG51bWJlciwgaW50IGluZGV4LCBUWVBFIHZhbHVlLCBFeHRlbnNpb25TZXQqIHNldCkgeyAgICAgICAgICAgICAgICBcCisgIHNldC0+U2V0UmVwZWF0ZWQjI01FVEhPRChudW1iZXIsIGluZGV4LCB2YWx1ZSk7ICAgICAgICAgICAgICAgICAgICAgICAgICBcCit9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCit0ZW1wbGF0ZTw+IGlubGluZSB2b2lkIFJlcGVhdGVkUHJpbWl0aXZlVHlwZVRyYWl0czxUWVBFPjo6QWRkKCAgICAgICAgICAgICBcCisgICAgaW50IG51bWJlciwgRmllbGRUeXBlIGZpZWxkX3R5cGUsIGJvb2wgaXNfcGFja2VkLCAgICAgICAgICAgICAgICAgICAgICBcCisgICAgVFlQRSB2YWx1ZSwgRXh0ZW5zaW9uU2V0KiBzZXQpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHNldC0+QWRkIyNNRVRIT0QobnVtYmVyLCBmaWVsZF90eXBlLCBpc19wYWNrZWQsIHZhbHVlLCBOVUxMKTsgICAgICAgICAgICBcCit9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCit0ZW1wbGF0ZTw+IGlubGluZSBjb25zdCBSZXBlYXRlZEZpZWxkPFRZUEU+KiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgUmVwZWF0ZWRQcmltaXRpdmVUeXBlVHJhaXRzPFRZUEU+OjpHZXREZWZhdWx0UmVwZWF0ZWRGaWVsZCgpIHsgICAgICAgICBcCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6R29vZ2xlT25jZUluaXQoICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICZyZXBlYXRlZF9wcmltaXRpdmVfZ2VuZXJpY190eXBlX3RyYWl0c19vbmNlX2luaXRfLCAgICAgICAgICAgICAgICAgIFwKKyAgICAgICZSZXBlYXRlZFByaW1pdGl2ZUdlbmVyaWNUeXBlVHJhaXRzOjpJbml0aWFsaXplRGVmYXVsdFJlcGVhdGVkRmllbGRzKTsgXAorICByZXR1cm4gUmVwZWF0ZWRQcmltaXRpdmVHZW5lcmljVHlwZVRyYWl0czo6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgZGVmYXVsdF9yZXBlYXRlZF9maWVsZF8jI1RZUEUjI187ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAordGVtcGxhdGU8PiBpbmxpbmUgY29uc3QgUmVwZWF0ZWRGaWVsZDxUWVBFPiYgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIFJlcGVhdGVkUHJpbWl0aXZlVHlwZVRyYWl0czxUWVBFPjo6R2V0UmVwZWF0ZWQoaW50IG51bWJlciwgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBFeHRlbnNpb25TZXQmIHNldCkgeyAgXAorICByZXR1cm4gKnJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgUmVwZWF0ZWRGaWVsZDxUWVBFPio+KCAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldC5HZXRSYXdSZXBlYXRlZEZpZWxkKCAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudW1iZXIsIEdldERlZmF1bHRSZXBlYXRlZEZpZWxkKCkpKTsgICAgICAgXAorfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAordGVtcGxhdGU8PiBpbmxpbmUgUmVwZWF0ZWRGaWVsZDxUWVBFPiogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIFJlcGVhdGVkUHJpbWl0aXZlVHlwZVRyYWl0czxUWVBFPjo6TXV0YWJsZVJlcGVhdGVkKGludCBudW1iZXIsICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmllbGRUeXBlIGZpZWxkX3R5cGUsICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc19wYWNrZWQsICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXh0ZW5zaW9uU2V0KiBzZXQpIHsgICAgXAorICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxSZXBlYXRlZEZpZWxkPFRZUEU+Kj4oICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgc2V0LT5NdXRhYmxlUmF3UmVwZWF0ZWRGaWVsZChudW1iZXIsIGZpZWxkX3R5cGUsIGlzX3BhY2tlZCwgTlVMTCkpOyAgXAorfQorCitQUk9UT0JVRl9ERUZJTkVfUFJJTUlUSVZFX1RZUEUoIGludDMyLCAgSW50MzIpCitQUk9UT0JVRl9ERUZJTkVfUFJJTUlUSVZFX1RZUEUoIGludDY0LCAgSW50NjQpCitQUk9UT0JVRl9ERUZJTkVfUFJJTUlUSVZFX1RZUEUodWludDMyLCBVSW50MzIpCitQUk9UT0JVRl9ERUZJTkVfUFJJTUlUSVZFX1RZUEUodWludDY0LCBVSW50NjQpCitQUk9UT0JVRl9ERUZJTkVfUFJJTUlUSVZFX1RZUEUoIGZsb2F0LCAgRmxvYXQpCitQUk9UT0JVRl9ERUZJTkVfUFJJTUlUSVZFX1RZUEUoZG91YmxlLCBEb3VibGUpCitQUk9UT0JVRl9ERUZJTkVfUFJJTUlUSVZFX1RZUEUoICBib29sLCAgIEJvb2wpCisKKyN1bmRlZiBQUk9UT0JVRl9ERUZJTkVfUFJJTUlUSVZFX1RZUEUKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gU3RyaW5nVHlwZVRyYWl0cworCisvLyBTdHJpbmdzIHN1cHBvcnQgYm90aCBTZXQoKSBhbmQgTXV0YWJsZSgpLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFN0cmluZ1R5cGVUcmFpdHMgeworIHB1YmxpYzoKKyAgdHlwZWRlZiBjb25zdCBzdHJpbmcmIENvbnN0VHlwZTsKKyAgdHlwZWRlZiBzdHJpbmcqIE11dGFibGVUeXBlOworICB0eXBlZGVmIFN0cmluZ1R5cGVUcmFpdHMgU2luZ3VsYXI7CisKKyAgc3RhdGljIGlubGluZSBjb25zdCBzdHJpbmcmIEdldChpbnQgbnVtYmVyLCBjb25zdCBFeHRlbnNpb25TZXQmIHNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdFR5cGUgZGVmYXVsdF92YWx1ZSkgeworICAgIHJldHVybiBzZXQuR2V0U3RyaW5nKG51bWJlciwgZGVmYXVsdF92YWx1ZSk7CisgIH0KKyAgc3RhdGljIGlubGluZSB2b2lkIFNldChpbnQgbnVtYmVyLCBGaWVsZFR5cGUgZmllbGRfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHZhbHVlLCBFeHRlbnNpb25TZXQqIHNldCkgeworICAgIHNldC0+U2V0U3RyaW5nKG51bWJlciwgZmllbGRfdHlwZSwgdmFsdWUsIE5VTEwpOworICB9CisgIHN0YXRpYyBpbmxpbmUgc3RyaW5nKiBNdXRhYmxlKGludCBudW1iZXIsIEZpZWxkVHlwZSBmaWVsZF90eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeHRlbnNpb25TZXQqIHNldCkgeworICAgIHJldHVybiBzZXQtPk11dGFibGVTdHJpbmcobnVtYmVyLCBmaWVsZF90eXBlLCBOVUxMKTsKKyAgfQorfTsKKworTElCUFJPVE9CVUZfRVhQT1JUIGV4dGVybiBQcm90b2J1Zk9uY2VUeXBlIHJlcGVhdGVkX3N0cmluZ190eXBlX3RyYWl0c19vbmNlX2luaXRfOworCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgUmVwZWF0ZWRTdHJpbmdUeXBlVHJhaXRzIHsKKyBwdWJsaWM6CisgIHR5cGVkZWYgY29uc3Qgc3RyaW5nJiBDb25zdFR5cGU7CisgIHR5cGVkZWYgc3RyaW5nKiBNdXRhYmxlVHlwZTsKKyAgdHlwZWRlZiBSZXBlYXRlZFN0cmluZ1R5cGVUcmFpdHMgUmVwZWF0ZWQ7CisKKyAgdHlwZWRlZiBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4gUmVwZWF0ZWRGaWVsZFR5cGU7CisKKyAgc3RhdGljIGlubGluZSBjb25zdCBzdHJpbmcmIEdldChpbnQgbnVtYmVyLCBjb25zdCBFeHRlbnNpb25TZXQmIHNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXgpIHsKKyAgICByZXR1cm4gc2V0LkdldFJlcGVhdGVkU3RyaW5nKG51bWJlciwgaW5kZXgpOworICB9CisgIHN0YXRpYyBpbmxpbmUgdm9pZCBTZXQoaW50IG51bWJlciwgaW50IGluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgdmFsdWUsIEV4dGVuc2lvblNldCogc2V0KSB7CisgICAgc2V0LT5TZXRSZXBlYXRlZFN0cmluZyhudW1iZXIsIGluZGV4LCB2YWx1ZSk7CisgIH0KKyAgc3RhdGljIGlubGluZSBzdHJpbmcqIE11dGFibGUoaW50IG51bWJlciwgaW50IGluZGV4LCBFeHRlbnNpb25TZXQqIHNldCkgeworICAgIHJldHVybiBzZXQtPk11dGFibGVSZXBlYXRlZFN0cmluZyhudW1iZXIsIGluZGV4KTsKKyAgfQorICBzdGF0aWMgaW5saW5lIHZvaWQgQWRkKGludCBudW1iZXIsIEZpZWxkVHlwZSBmaWVsZF90eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgLyppc19wYWNrZWQqLywgY29uc3Qgc3RyaW5nJiB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBFeHRlbnNpb25TZXQqIHNldCkgeworICAgIHNldC0+QWRkU3RyaW5nKG51bWJlciwgZmllbGRfdHlwZSwgdmFsdWUsIE5VTEwpOworICB9CisgIHN0YXRpYyBpbmxpbmUgc3RyaW5nKiBBZGQoaW50IG51bWJlciwgRmllbGRUeXBlIGZpZWxkX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXh0ZW5zaW9uU2V0KiBzZXQpIHsKKyAgICByZXR1cm4gc2V0LT5BZGRTdHJpbmcobnVtYmVyLCBmaWVsZF90eXBlLCBOVUxMKTsKKyAgfQorICBzdGF0aWMgaW5saW5lIGNvbnN0IFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPiYKKyAgICAgIEdldFJlcGVhdGVkKGludCBudW1iZXIsIGNvbnN0IEV4dGVuc2lvblNldCYgc2V0KSB7CisgICAgcmV0dXJuICpyZWludGVycHJldF9jYXN0PGNvbnN0IFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPio+KAorICAgICAgICBzZXQuR2V0UmF3UmVwZWF0ZWRGaWVsZChudW1iZXIsIEdldERlZmF1bHRSZXBlYXRlZEZpZWxkKCkpKTsKKyAgfQorCisgIHN0YXRpYyBpbmxpbmUgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+KgorICAgICAgTXV0YWJsZVJlcGVhdGVkKGludCBudW1iZXIsIEZpZWxkVHlwZSBmaWVsZF90eXBlLAorICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaXNfcGFja2VkLCBFeHRlbnNpb25TZXQqIHNldCkgeworICAgIHJldHVybiByZWludGVycHJldF9jYXN0PFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPio+KAorICAgICAgICBzZXQtPk11dGFibGVSYXdSZXBlYXRlZEZpZWxkKG51bWJlciwgZmllbGRfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc19wYWNrZWQsIE5VTEwpKTsKKyAgfQorCisgIHN0YXRpYyBjb25zdCBSZXBlYXRlZEZpZWxkVHlwZSogR2V0RGVmYXVsdFJlcGVhdGVkRmllbGQoKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjpHb29nbGVPbmNlSW5pdCgmcmVwZWF0ZWRfc3RyaW5nX3R5cGVfdHJhaXRzX29uY2VfaW5pdF8sCisgICAgICAgICAgICAgICAgICAgJkluaXRpYWxpemVEZWZhdWx0UmVwZWF0ZWRGaWVsZHMpOworICAgIHJldHVybiBkZWZhdWx0X3JlcGVhdGVkX2ZpZWxkXzsKKyAgfQorCisgcHJpdmF0ZToKKyAgc3RhdGljIHZvaWQgSW5pdGlhbGl6ZURlZmF1bHRSZXBlYXRlZEZpZWxkcygpOworICBzdGF0aWMgdm9pZCBEZXN0cm95RGVmYXVsdFJlcGVhdGVkRmllbGRzKCk7CisgIHN0YXRpYyBjb25zdCBSZXBlYXRlZEZpZWxkVHlwZSAqZGVmYXVsdF9yZXBlYXRlZF9maWVsZF87Cit9OworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBFbnVtVHlwZVRyYWl0cworCisvLyBFeHRlbnNpb25TZXQgcmVwcmVzZW50cyBlbnVtcyB1c2luZyBpbnRlZ2VycyBpbnRlcm5hbGx5LCBzbyB3ZSBoYXZlIHRvCisvLyBzdGF0aWNfY2FzdCBhcm91bmQuCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZSwgYm9vbCBJc1ZhbGlkKGludCk+CitjbGFzcyBFbnVtVHlwZVRyYWl0cyB7CisgcHVibGljOgorICB0eXBlZGVmIFR5cGUgQ29uc3RUeXBlOworICB0eXBlZGVmIFR5cGUgTXV0YWJsZVR5cGU7CisgIHR5cGVkZWYgRW51bVR5cGVUcmFpdHM8VHlwZSwgSXNWYWxpZD4gU2luZ3VsYXI7CisKKyAgc3RhdGljIGlubGluZSBDb25zdFR5cGUgR2V0KGludCBudW1iZXIsIGNvbnN0IEV4dGVuc2lvblNldCYgc2V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uc3RUeXBlIGRlZmF1bHRfdmFsdWUpIHsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8VHlwZT4oc2V0LkdldEVudW0obnVtYmVyLCBkZWZhdWx0X3ZhbHVlKSk7CisgIH0KKyAgc3RhdGljIGlubGluZSB2b2lkIFNldChpbnQgbnVtYmVyLCBGaWVsZFR5cGUgZmllbGRfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdFR5cGUgdmFsdWUsIEV4dGVuc2lvblNldCogc2V0KSB7CisgICAgR09PR0xFX0RDSEVDSyhJc1ZhbGlkKHZhbHVlKSk7CisgICAgc2V0LT5TZXRFbnVtKG51bWJlciwgZmllbGRfdHlwZSwgdmFsdWUsIE5VTEwpOworICB9Cit9OworCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZSwgYm9vbCBJc1ZhbGlkKGludCk+CitjbGFzcyBSZXBlYXRlZEVudW1UeXBlVHJhaXRzIHsKKyBwdWJsaWM6CisgIHR5cGVkZWYgVHlwZSBDb25zdFR5cGU7CisgIHR5cGVkZWYgVHlwZSBNdXRhYmxlVHlwZTsKKyAgdHlwZWRlZiBSZXBlYXRlZEVudW1UeXBlVHJhaXRzPFR5cGUsIElzVmFsaWQ+IFJlcGVhdGVkOworCisgIHR5cGVkZWYgUmVwZWF0ZWRGaWVsZDxUeXBlPiBSZXBlYXRlZEZpZWxkVHlwZTsKKworICBzdGF0aWMgaW5saW5lIENvbnN0VHlwZSBHZXQoaW50IG51bWJlciwgY29uc3QgRXh0ZW5zaW9uU2V0JiBzZXQsIGludCBpbmRleCkgeworICAgIHJldHVybiBzdGF0aWNfY2FzdDxUeXBlPihzZXQuR2V0UmVwZWF0ZWRFbnVtKG51bWJlciwgaW5kZXgpKTsKKyAgfQorICBzdGF0aWMgaW5saW5lIHZvaWQgU2V0KGludCBudW1iZXIsIGludCBpbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdFR5cGUgdmFsdWUsIEV4dGVuc2lvblNldCogc2V0KSB7CisgICAgR09PR0xFX0RDSEVDSyhJc1ZhbGlkKHZhbHVlKSk7CisgICAgc2V0LT5TZXRSZXBlYXRlZEVudW0obnVtYmVyLCBpbmRleCwgdmFsdWUpOworICB9CisgIHN0YXRpYyBpbmxpbmUgdm9pZCBBZGQoaW50IG51bWJlciwgRmllbGRUeXBlIGZpZWxkX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc19wYWNrZWQsIENvbnN0VHlwZSB2YWx1ZSwgRXh0ZW5zaW9uU2V0KiBzZXQpIHsKKyAgICBHT09HTEVfRENIRUNLKElzVmFsaWQodmFsdWUpKTsKKyAgICBzZXQtPkFkZEVudW0obnVtYmVyLCBmaWVsZF90eXBlLCBpc19wYWNrZWQsIHZhbHVlLCBOVUxMKTsKKyAgfQorICBzdGF0aWMgaW5saW5lIGNvbnN0IFJlcGVhdGVkRmllbGQ8VHlwZT4mIEdldFJlcGVhdGVkKGludCBudW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRXh0ZW5zaW9uU2V0JgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldCkgeworICAgIC8vIEhhY2s6IHRoZSBgRXh0ZW5zaW9uYCBzdHJ1Y3Qgc3RvcmVzIGEgUmVwZWF0ZWRGaWVsZDxpbnQ+IGZvciBlbnVtcy4KKyAgICAvLyBSZXBlYXRlZEZpZWxkPGludD4gY2Fubm90IGltcGxpY2l0bHkgY29udmVydCB0byBSZXBlYXRlZEZpZWxkPEVudW1UeXBlPgorICAgIC8vIHNvIHdlIG5lZWQgdG8gZG8gc29tZSBjYXN0aW5nIG1hZ2ljLiBTZWUgbWVzc2FnZS5oIGZvciBzaW1pbGFyCisgICAgLy8gY29udG9ydGlvbnMgZm9yIG5vbi1leHRlbnNpb24gZmllbGRzLgorICAgIHJldHVybiAqcmVpbnRlcnByZXRfY2FzdDxjb25zdCBSZXBlYXRlZEZpZWxkPFR5cGU+Kj4oCisgICAgICAgIHNldC5HZXRSYXdSZXBlYXRlZEZpZWxkKG51bWJlciwgR2V0RGVmYXVsdFJlcGVhdGVkRmllbGQoKSkpOworICB9CisKKyAgc3RhdGljIGlubGluZSBSZXBlYXRlZEZpZWxkPFR5cGU+KiBNdXRhYmxlUmVwZWF0ZWQoaW50IG51bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmllbGRUeXBlIGZpZWxkX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaXNfcGFja2VkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeHRlbnNpb25TZXQqIHNldCkgeworICAgIHJldHVybiByZWludGVycHJldF9jYXN0PFJlcGVhdGVkRmllbGQ8VHlwZT4qPigKKyAgICAgICAgc2V0LT5NdXRhYmxlUmF3UmVwZWF0ZWRGaWVsZChudW1iZXIsIGZpZWxkX3R5cGUsIGlzX3BhY2tlZCwgTlVMTCkpOworICB9CisKKyAgc3RhdGljIGNvbnN0IFJlcGVhdGVkRmllbGRUeXBlKiBHZXREZWZhdWx0UmVwZWF0ZWRGaWVsZCgpIHsKKyAgICAvLyBIYWNrOiBhcyBub3RlZCBhYm92ZSwgcmVwZWF0ZWQgZW51bSBmaWVsZHMgYXJlIGludGVybmFsbHkgc3RvcmVkIGFzIGEKKyAgICAvLyBSZXBlYXRlZEZpZWxkPGludD4uIFdlIG5lZWQgdG8gYmUgYWJsZSB0byBpbnN0YW50aWF0ZSBnbG9iYWwgc3RhdGljCisgICAgLy8gb2JqZWN0cyB0byByZXR1cm4gYXMgZGVmYXVsdCAoZW1wdHkpIHJlcGVhdGVkIGZpZWxkcyBvbiBub24tZXhpc3RlbnQKKyAgICAvLyBleHRlbnNpb25zLiBXZSB3b3VsZCBub3QgYmUgYWJsZSB0byBrbm93IGEtcHJpb3JpIGFsbCBvZiB0aGUgZW51bSB0eXBlcworICAgIC8vICh2YWx1ZXMgb2YgfFR5cGV8KSB0byBpbnN0YW50aWF0ZSBhbGwgb2YgdGhlc2UsIHNvIHdlIGp1c3QgcmUtdXNlIGludDMyJ3MKKyAgICAvLyBkZWZhdWx0IHJlcGVhdGVkIGZpZWxkIG9iamVjdC4KKyAgICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxjb25zdCBSZXBlYXRlZEZpZWxkPFR5cGU+Kj4oCisgICAgICAgIFJlcGVhdGVkUHJpbWl0aXZlVHlwZVRyYWl0czxpbnQzMj46OkdldERlZmF1bHRSZXBlYXRlZEZpZWxkKCkpOworICB9Cit9OworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBNZXNzYWdlVHlwZVRyYWl0cworCisvLyBFeHRlbnNpb25TZXQgZ3VhcmFudGVlcyB0aGF0IHdoZW4gbWFuaXB1bGF0aW5nIGV4dGVuc2lvbnMgd2l0aCBtZXNzYWdlCisvLyB0eXBlcywgdGhlIGltcGxlbWVudGF0aW9uIHVzZWQgd2lsbCBiZSB0aGUgY29tcGlsZWQtaW4gY2xhc3MgcmVwcmVzZW50aW5nCisvLyB0aGF0IHR5cGUuICBTbywgd2UgY2FuIHN0YXRpY19jYXN0IGRvd24gdG8gdGhlIGV4YWN0IHR5cGUgd2UgZXhwZWN0LgordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+CitjbGFzcyBNZXNzYWdlVHlwZVRyYWl0cyB7CisgcHVibGljOgorICB0eXBlZGVmIGNvbnN0IFR5cGUmIENvbnN0VHlwZTsKKyAgdHlwZWRlZiBUeXBlKiBNdXRhYmxlVHlwZTsKKyAgdHlwZWRlZiBNZXNzYWdlVHlwZVRyYWl0czxUeXBlPiBTaW5ndWxhcjsKKworICBzdGF0aWMgaW5saW5lIENvbnN0VHlwZSBHZXQoaW50IG51bWJlciwgY29uc3QgRXh0ZW5zaW9uU2V0JiBzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdFR5cGUgZGVmYXVsdF92YWx1ZSkgeworICAgIHJldHVybiBzdGF0aWNfY2FzdDxjb25zdCBUeXBlJj4oCisgICAgICAgIHNldC5HZXRNZXNzYWdlKG51bWJlciwgZGVmYXVsdF92YWx1ZSkpOworICB9CisgIHN0YXRpYyBpbmxpbmUgTXV0YWJsZVR5cGUgTXV0YWJsZShpbnQgbnVtYmVyLCBGaWVsZFR5cGUgZmllbGRfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4dGVuc2lvblNldCogc2V0KSB7CisgICAgcmV0dXJuIHN0YXRpY19jYXN0PFR5cGUqPigKKyAgICAgIHNldC0+TXV0YWJsZU1lc3NhZ2UobnVtYmVyLCBmaWVsZF90eXBlLCBUeXBlOjpkZWZhdWx0X2luc3RhbmNlKCksIE5VTEwpKTsKKyAgfQorICBzdGF0aWMgaW5saW5lIHZvaWQgU2V0QWxsb2NhdGVkKGludCBudW1iZXIsIEZpZWxkVHlwZSBmaWVsZF90eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE11dGFibGVUeXBlIG1lc3NhZ2UsIEV4dGVuc2lvblNldCogc2V0KSB7CisgICAgc2V0LT5TZXRBbGxvY2F0ZWRNZXNzYWdlKG51bWJlciwgZmllbGRfdHlwZSwgTlVMTCwgbWVzc2FnZSk7CisgIH0KKyAgc3RhdGljIGlubGluZSBNdXRhYmxlVHlwZSBSZWxlYXNlKGludCBudW1iZXIsIEZpZWxkVHlwZSAvKiBmaWVsZF90eXBlICovLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXh0ZW5zaW9uU2V0KiBzZXQpIHsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8VHlwZSo+KHNldC0+UmVsZWFzZU1lc3NhZ2UoCisgICAgICAgIG51bWJlciwgVHlwZTo6ZGVmYXVsdF9pbnN0YW5jZSgpKSk7CisgIH0KK307CisKKy8vIGZvcndhcmQgZGVjbGFyYXRpb24KK2NsYXNzIFJlcGVhdGVkTWVzc2FnZUdlbmVyaWNUeXBlVHJhaXRzOworCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4KK2NsYXNzIFJlcGVhdGVkTWVzc2FnZVR5cGVUcmFpdHMgeworIHB1YmxpYzoKKyAgdHlwZWRlZiBjb25zdCBUeXBlJiBDb25zdFR5cGU7CisgIHR5cGVkZWYgVHlwZSogTXV0YWJsZVR5cGU7CisgIHR5cGVkZWYgUmVwZWF0ZWRNZXNzYWdlVHlwZVRyYWl0czxUeXBlPiBSZXBlYXRlZDsKKworICB0eXBlZGVmIFJlcGVhdGVkUHRyRmllbGQ8VHlwZT4gUmVwZWF0ZWRGaWVsZFR5cGU7CisKKyAgc3RhdGljIGlubGluZSBDb25zdFR5cGUgR2V0KGludCBudW1iZXIsIGNvbnN0IEV4dGVuc2lvblNldCYgc2V0LCBpbnQgaW5kZXgpIHsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8Y29uc3QgVHlwZSY+KHNldC5HZXRSZXBlYXRlZE1lc3NhZ2UobnVtYmVyLCBpbmRleCkpOworICB9CisgIHN0YXRpYyBpbmxpbmUgTXV0YWJsZVR5cGUgTXV0YWJsZShpbnQgbnVtYmVyLCBpbnQgaW5kZXgsIEV4dGVuc2lvblNldCogc2V0KSB7CisgICAgcmV0dXJuIHN0YXRpY19jYXN0PFR5cGUqPihzZXQtPk11dGFibGVSZXBlYXRlZE1lc3NhZ2UobnVtYmVyLCBpbmRleCkpOworICB9CisgIHN0YXRpYyBpbmxpbmUgTXV0YWJsZVR5cGUgQWRkKGludCBudW1iZXIsIEZpZWxkVHlwZSBmaWVsZF90eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeHRlbnNpb25TZXQqIHNldCkgeworICAgIHJldHVybiBzdGF0aWNfY2FzdDxUeXBlKj4oCisgICAgICAgIHNldC0+QWRkTWVzc2FnZShudW1iZXIsIGZpZWxkX3R5cGUsIFR5cGU6OmRlZmF1bHRfaW5zdGFuY2UoKSwgTlVMTCkpOworICB9CisgIHN0YXRpYyBpbmxpbmUgY29uc3QgUmVwZWF0ZWRQdHJGaWVsZDxUeXBlPiYgR2V0UmVwZWF0ZWQoaW50IG51bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBFeHRlbnNpb25TZXQmCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0KSB7CisgICAgLy8gU2VlIG5vdGVzIGFib3ZlIGluIFJlcGVhdGVkRW51bVR5cGVUcmFpdHM6OkdldFJlcGVhdGVkKCk6IHNhbWUKKyAgICAvLyBjYXN0aW5nIGhhY2sgYXBwbGllcyBoZXJlLCBiZWNhdXNlIGEgUmVwZWF0ZWRQdHJGaWVsZDxNZXNzYWdlTGl0ZT4KKyAgICAvLyBjYW5ub3QgbmF0dXJhbGx5IGJlY29tZSBhIFJlcGVhdGVkUHRyVHlwZTxUeXBlPiBldmVuIHRob3VnaCBUeXBlIGlzCisgICAgLy8gcHJlc3VtYWJseSBhIG1lc3NhZ2UuIGdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UgZ29lcyB0aHJvdWdoIHNpbWlsYXIgY29udG9ydGlvbnMKKyAgICAvLyB3aXRoIGEgcmVpbnRlcnByZXRfY2FzdDw+LgorICAgIHJldHVybiAqcmVpbnRlcnByZXRfY2FzdDxjb25zdCBSZXBlYXRlZFB0ckZpZWxkPFR5cGU+Kj4oCisgICAgICAgIHNldC5HZXRSYXdSZXBlYXRlZEZpZWxkKG51bWJlciwgR2V0RGVmYXVsdFJlcGVhdGVkRmllbGQoKSkpOworICB9CisgIHN0YXRpYyBpbmxpbmUgUmVwZWF0ZWRQdHJGaWVsZDxUeXBlPiogTXV0YWJsZVJlcGVhdGVkKGludCBudW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkVHlwZSBmaWVsZF90eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGlzX3BhY2tlZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXh0ZW5zaW9uU2V0KiBzZXQpIHsKKyAgICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxSZXBlYXRlZFB0ckZpZWxkPFR5cGU+Kj4oCisgICAgICAgIHNldC0+TXV0YWJsZVJhd1JlcGVhdGVkRmllbGQobnVtYmVyLCBmaWVsZF90eXBlLCBpc19wYWNrZWQsIE5VTEwpKTsKKyAgfQorCisgIHN0YXRpYyBjb25zdCBSZXBlYXRlZEZpZWxkVHlwZSogR2V0RGVmYXVsdFJlcGVhdGVkRmllbGQoKTsKK307CisKK0xJQlBST1RPQlVGX0VYUE9SVCBleHRlcm4gUHJvdG9idWZPbmNlVHlwZSByZXBlYXRlZF9tZXNzYWdlX2dlbmVyaWNfdHlwZV90cmFpdHNfb25jZV9pbml0XzsKKworLy8gVGhpcyBjbGFzcyBleGlzdHMgb25seSB0byBob2xkIGEgZ2VuZXJpYyBkZWZhdWx0IGVtcHR5IHJlcGVhdGVkIGZpZWxkIGZvciBhbGwKKy8vIG1lc3NhZ2UtdHlwZSByZXBlYXRlZCBmaWVsZCBleHRlbnNpb25zLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFJlcGVhdGVkTWVzc2FnZUdlbmVyaWNUeXBlVHJhaXRzIHsKKyBwdWJsaWM6CisgIHR5cGVkZWYgUmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlTGl0ZSo+IFJlcGVhdGVkRmllbGRUeXBlOworIHByaXZhdGU6CisgIHRlbXBsYXRlPHR5cGVuYW1lIFR5cGU+IGZyaWVuZCBjbGFzcyBSZXBlYXRlZE1lc3NhZ2VUeXBlVHJhaXRzOworICBzdGF0aWMgdm9pZCBJbml0aWFsaXplRGVmYXVsdFJlcGVhdGVkRmllbGRzKCk7CisgIHN0YXRpYyB2b2lkIERlc3Ryb3lEZWZhdWx0UmVwZWF0ZWRGaWVsZHMoKTsKKyAgc3RhdGljIGNvbnN0IFJlcGVhdGVkRmllbGRUeXBlKiBkZWZhdWx0X3JlcGVhdGVkX2ZpZWxkXzsKK307CisKK3RlbXBsYXRlPHR5cGVuYW1lIFR5cGU+IGlubGluZQorICAgIGNvbnN0IHR5cGVuYW1lIFJlcGVhdGVkTWVzc2FnZVR5cGVUcmFpdHM8VHlwZT46OlJlcGVhdGVkRmllbGRUeXBlKgorICAgIFJlcGVhdGVkTWVzc2FnZVR5cGVUcmFpdHM8VHlwZT46OkdldERlZmF1bHRSZXBlYXRlZEZpZWxkKCkgeworICA6Omdvb2dsZTo6cHJvdG9idWY6Okdvb2dsZU9uY2VJbml0KAorICAgICAgJnJlcGVhdGVkX21lc3NhZ2VfZ2VuZXJpY190eXBlX3RyYWl0c19vbmNlX2luaXRfLAorICAgICAgJlJlcGVhdGVkTWVzc2FnZUdlbmVyaWNUeXBlVHJhaXRzOjpJbml0aWFsaXplRGVmYXVsdFJlcGVhdGVkRmllbGRzKTsKKyAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgUmVwZWF0ZWRGaWVsZFR5cGUqPigKKyAgICAgIFJlcGVhdGVkTWVzc2FnZUdlbmVyaWNUeXBlVHJhaXRzOjpkZWZhdWx0X3JlcGVhdGVkX2ZpZWxkXyk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIEV4dGVuc2lvbklkZW50aWZpZXIKKworLy8gVGhpcyBpcyB0aGUgdHlwZSBvZiBhY3R1YWwgZXh0ZW5zaW9uIG9iamVjdHMuICBFLmcuIGlmIHlvdSBoYXZlOgorLy8gICBleHRlbmRzIEZvbyB3aXRoIG9wdGlvbmFsIGludDMyIGJhciA9IDEyMzQ7CisvLyB0aGVuICJiYXIiIHdpbGwgYmUgZGVmaW5lZCBpbiBDKysgYXM6CisvLyAgIEV4dGVuc2lvbklkZW50aWZpZXI8Rm9vLCBQcmltaXRpdmVUeXBlVHJhaXRzPGludDMyPiwgMSwgZmFsc2U+IGJhcigxMjM0KTsKKy8vCisvLyBOb3RlIHRoYXQgd2UgY291bGQsIGluIHRoZW9yeSwgc3VwcGx5IHRoZSBmaWVsZCBudW1iZXIgYXMgYSB0ZW1wbGF0ZQorLy8gcGFyYW1ldGVyLCBhbmQgdGh1cyBtYWtlIGFuIGluc3RhbmNlIG9mIEV4dGVuc2lvbklkZW50aWZpZXIgaGF2ZSBubworLy8gYWN0dWFsIGNvbnRlbnRzLiAgSG93ZXZlciwgaWYgd2UgZGlkIHRoYXQsIHRoZW4gdXNpbmcgYXQgZXh0ZW5zaW9uCisvLyBpZGVudGlmaWVyIHdvdWxkIG5vdCBuZWNlc3NhcmlseSBjYXVzZSB0aGUgY29tcGlsZXIgdG8gb3V0cHV0IGFueSBzb3J0CisvLyBvZiByZWZlcmVuY2UgdG8gYW55IHNpbXBsZSBkZWZpbmVkIGluIHRoZSBleHRlbnNpb24ncyAucGIubyBmaWxlLiAgU29tZQorLy8gbGlua2VycyB3aWxsIGFjdHVhbGx5IGRyb3Agb2JqZWN0IGZpbGVzIHRoYXQgYXJlIG5vdCBleHBsaWNpdGx5IHJlZmVyZW5jZWQsCisvLyBidXQgdGhhdCB3b3VsZCBiZSBiYWQgYmVjYXVzZSBpdCB3b3VsZCBjYXVzZSB0aGlzIGV4dGVuc2lvbiB0byBub3QgYmUKKy8vIHJlZ2lzdGVyZWQgYXQgc3RhdGljIGluaXRpYWxpemF0aW9uLCBhbmQgdGhlcmVmb3JlIHVzaW5nIGl0IHdvdWxkIGNyYXNoLgorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRXh0ZW5kZWVUeXBlLCB0eXBlbmFtZSBUeXBlVHJhaXRzVHlwZSwKKyAgICAgICAgICBGaWVsZFR5cGUgZmllbGRfdHlwZSwgYm9vbCBpc19wYWNrZWQ+CitjbGFzcyBFeHRlbnNpb25JZGVudGlmaWVyIHsKKyBwdWJsaWM6CisgIHR5cGVkZWYgVHlwZVRyYWl0c1R5cGUgVHlwZVRyYWl0czsKKyAgdHlwZWRlZiBFeHRlbmRlZVR5cGUgRXh0ZW5kZWU7CisKKyAgRXh0ZW5zaW9uSWRlbnRpZmllcihpbnQgbnVtYmVyLCB0eXBlbmFtZSBUeXBlVHJhaXRzOjpDb25zdFR5cGUgZGVmYXVsdF92YWx1ZSkKKyAgICAgIDogbnVtYmVyXyhudW1iZXIpLCBkZWZhdWx0X3ZhbHVlXyhkZWZhdWx0X3ZhbHVlKSB7fQorICBpbmxpbmUgaW50IG51bWJlcigpIGNvbnN0IHsgcmV0dXJuIG51bWJlcl87IH0KKyAgdHlwZW5hbWUgVHlwZVRyYWl0czo6Q29uc3RUeXBlIGRlZmF1bHRfdmFsdWUoKSBjb25zdCB7CisgICAgcmV0dXJuIGRlZmF1bHRfdmFsdWVfOworICB9CisKKyBwcml2YXRlOgorICBjb25zdCBpbnQgbnVtYmVyXzsKKyAgdHlwZW5hbWUgVHlwZVRyYWl0czo6Q29uc3RUeXBlIGRlZmF1bHRfdmFsdWVfOworfTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gR2VuZXJhdGVkIGFjY2Vzc29ycworCisvLyBUaGlzIG1hY3JvIHNob3VsZCBiZSBleHBhbmRlZCBpbiB0aGUgY29udGV4dCBvZiBhIGdlbmVyYXRlZCB0eXBlIHdoaWNoCisvLyBoYXMgZXh0ZW5zaW9ucy4KKy8vCisvLyBXZSB1c2UgIl9wcm90b19UeXBlVHJhaXRzIiBhcyBhIHR5cGUgbmFtZSBiZWxvdyBiZWNhdXNlICJUeXBlVHJhaXRzIgorLy8gY2F1c2VzIHByb2JsZW1zIGlmIHRoZSBjbGFzcyBoYXMgYSBuZXN0ZWQgbWVzc2FnZSBvciBlbnVtIHR5cGUgd2l0aCB0aGF0CisvLyBuYW1lIGFuZCAiX1R5cGVUcmFpdHMiIGlzIHRlY2huaWNhbGx5IHJlc2VydmVkIGZvciB0aGUgQysrIGxpYnJhcnkgc2luY2UKKy8vIGl0IHN0YXJ0cyB3aXRoIGFuIHVuZGVyc2NvcmUgZm9sbG93ZWQgYnkgYSBjYXBpdGFsIGxldHRlci4KKy8vCisvLyBGb3Igc2ltaWxhciByZWFzb24sIHdlIHVzZSAiX2ZpZWxkX3R5cGUiIGFuZCAiX2lzX3BhY2tlZCIgYXMgcGFyYW1ldGVyIG5hbWVzCisvLyBiZWxvdywgc28gdGhhdCAiZmllbGRfdHlwZSIgYW5kICJpc19wYWNrZWQiIGNhbiBiZSB1c2VkIGFzIGZpZWxkIG5hbWVzLgorI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfRVhURU5TSU9OX0FDQ0VTU09SUyhDTEFTU05BTUUpICAgICAgICAgICAgICAgICAgICAgICAgXAorICAvKiBIYXMsIFNpemUsIENsZWFyICovICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgX3Byb3RvX1R5cGVUcmFpdHMsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RmllbGRUeXBlIF9maWVsZF90eXBlLCAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgIGJvb2wgX2lzX3BhY2tlZD4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgaW5saW5lIGJvb2wgSGFzRXh0ZW5zaW9uKCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkV4dGVuc2lvbklkZW50aWZpZXI8ICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIENMQVNTTkFNRSwgX3Byb3RvX1R5cGVUcmFpdHMsIF9maWVsZF90eXBlLCBfaXNfcGFja2VkPiYgaWQpIGNvbnN0IHsgICBcCisgICAgcmV0dXJuIF9leHRlbnNpb25zXy5IYXMoaWQubnVtYmVyKCkpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBfcHJvdG9fVHlwZVRyYWl0cywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpGaWVsZFR5cGUgX2ZpZWxkX3R5cGUsICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgYm9vbCBfaXNfcGFja2VkPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBpbmxpbmUgdm9pZCBDbGVhckV4dGVuc2lvbiggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RXh0ZW5zaW9uSWRlbnRpZmllcjwgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgQ0xBU1NOQU1FLCBfcHJvdG9fVHlwZVRyYWl0cywgX2ZpZWxkX3R5cGUsIF9pc19wYWNrZWQ+JiBpZCkgeyAgICAgICAgIFwKKyAgICBfZXh0ZW5zaW9uc18uQ2xlYXJFeHRlbnNpb24oaWQubnVtYmVyKCkpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIF9wcm90b19UeXBlVHJhaXRzLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkZpZWxkVHlwZSBfZmllbGRfdHlwZSwgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICBib29sIF9pc19wYWNrZWQ+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGlubGluZSBpbnQgRXh0ZW5zaW9uU2l6ZSggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpFeHRlbnNpb25JZGVudGlmaWVyPCAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBDTEFTU05BTUUsIF9wcm90b19UeXBlVHJhaXRzLCBfZmllbGRfdHlwZSwgX2lzX3BhY2tlZD4mIGlkKSBjb25zdCB7ICAgXAorICAgIHJldHVybiBfZXh0ZW5zaW9uc18uRXh0ZW5zaW9uU2l6ZShpZC5udW1iZXIoKSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAvKiBTaW5ndWxhciBhY2Nlc3NvcnMgKi8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgX3Byb3RvX1R5cGVUcmFpdHMsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RmllbGRUeXBlIF9maWVsZF90eXBlLCAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgIGJvb2wgX2lzX3BhY2tlZD4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgaW5saW5lIHR5cGVuYW1lIF9wcm90b19UeXBlVHJhaXRzOjpTaW5ndWxhcjo6Q29uc3RUeXBlIEdldEV4dGVuc2lvbiggICAgICAgIFwKKyAgICAgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkV4dGVuc2lvbklkZW50aWZpZXI8ICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIENMQVNTTkFNRSwgX3Byb3RvX1R5cGVUcmFpdHMsIF9maWVsZF90eXBlLCBfaXNfcGFja2VkPiYgaWQpIGNvbnN0IHsgICBcCisgICAgcmV0dXJuIF9wcm90b19UeXBlVHJhaXRzOjpHZXQoaWQubnVtYmVyKCksIF9leHRlbnNpb25zXywgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWQuZGVmYXVsdF92YWx1ZSgpKTsgICAgICAgICAgICAgICAgICAgICAgICBcCisgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBfcHJvdG9fVHlwZVRyYWl0cywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpGaWVsZFR5cGUgX2ZpZWxkX3R5cGUsICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgYm9vbCBfaXNfcGFja2VkPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBpbmxpbmUgdHlwZW5hbWUgX3Byb3RvX1R5cGVUcmFpdHM6OlNpbmd1bGFyOjpNdXRhYmxlVHlwZSBNdXRhYmxlRXh0ZW5zaW9uKCAgXAorICAgICAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RXh0ZW5zaW9uSWRlbnRpZmllcjwgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgQ0xBU1NOQU1FLCBfcHJvdG9fVHlwZVRyYWl0cywgX2ZpZWxkX3R5cGUsIF9pc19wYWNrZWQ+JiBpZCkgeyAgICAgICAgIFwKKyAgICByZXR1cm4gX3Byb3RvX1R5cGVUcmFpdHM6Ok11dGFibGUoaWQubnVtYmVyKCksIF9maWVsZF90eXBlLCAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJl9leHRlbnNpb25zXyk7ICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIF9wcm90b19UeXBlVHJhaXRzLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkZpZWxkVHlwZSBfZmllbGRfdHlwZSwgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICBib29sIF9pc19wYWNrZWQ+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGlubGluZSB2b2lkIFNldEV4dGVuc2lvbiggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpFeHRlbnNpb25JZGVudGlmaWVyPCAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBDTEFTU05BTUUsIF9wcm90b19UeXBlVHJhaXRzLCBfZmllbGRfdHlwZSwgX2lzX3BhY2tlZD4mIGlkLCAgICAgICAgICAgXAorICAgICAgdHlwZW5hbWUgX3Byb3RvX1R5cGVUcmFpdHM6OlNpbmd1bGFyOjpDb25zdFR5cGUgdmFsdWUpIHsgICAgICAgICAgICAgICAgXAorICAgIF9wcm90b19UeXBlVHJhaXRzOjpTZXQoaWQubnVtYmVyKCksIF9maWVsZF90eXBlLCB2YWx1ZSwgJl9leHRlbnNpb25zXyk7ICAgXAorICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgX3Byb3RvX1R5cGVUcmFpdHMsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RmllbGRUeXBlIF9maWVsZF90eXBlLCAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgIGJvb2wgX2lzX3BhY2tlZD4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgaW5saW5lIHZvaWQgU2V0QWxsb2NhdGVkRXh0ZW5zaW9uKCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkV4dGVuc2lvbklkZW50aWZpZXI8ICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIENMQVNTTkFNRSwgX3Byb3RvX1R5cGVUcmFpdHMsIF9maWVsZF90eXBlLCBfaXNfcGFja2VkPiYgaWQsICAgICAgICAgICBcCisgICAgICB0eXBlbmFtZSBfcHJvdG9fVHlwZVRyYWl0czo6U2luZ3VsYXI6Ok11dGFibGVUeXBlIHZhbHVlKSB7ICAgICAgICAgICAgICBcCisgICAgX3Byb3RvX1R5cGVUcmFpdHM6OlNldEFsbG9jYXRlZChpZC5udW1iZXIoKSwgX2ZpZWxkX3R5cGUsICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSwgJl9leHRlbnNpb25zXyk7ICAgICAgICAgICAgICAgICAgICBcCisgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBfcHJvdG9fVHlwZVRyYWl0cywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpGaWVsZFR5cGUgX2ZpZWxkX3R5cGUsICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgYm9vbCBfaXNfcGFja2VkPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBpbmxpbmUgdHlwZW5hbWUgX3Byb3RvX1R5cGVUcmFpdHM6OlNpbmd1bGFyOjpNdXRhYmxlVHlwZSBSZWxlYXNlRXh0ZW5zaW9uKCAgXAorICAgICAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RXh0ZW5zaW9uSWRlbnRpZmllcjwgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgQ0xBU1NOQU1FLCBfcHJvdG9fVHlwZVRyYWl0cywgX2ZpZWxkX3R5cGUsIF9pc19wYWNrZWQ+JiBpZCkgeyAgICAgICAgIFwKKyAgICByZXR1cm4gX3Byb3RvX1R5cGVUcmFpdHM6OlJlbGVhc2UoaWQubnVtYmVyKCksIF9maWVsZF90eXBlLCAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJl9leHRlbnNpb25zXyk7ICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgLyogUmVwZWF0ZWQgYWNjZXNzb3JzICovICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIF9wcm90b19UeXBlVHJhaXRzLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkZpZWxkVHlwZSBfZmllbGRfdHlwZSwgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICBib29sIF9pc19wYWNrZWQ+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGlubGluZSB0eXBlbmFtZSBfcHJvdG9fVHlwZVRyYWl0czo6UmVwZWF0ZWQ6OkNvbnN0VHlwZSBHZXRFeHRlbnNpb24oICAgICAgICBcCisgICAgICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpFeHRlbnNpb25JZGVudGlmaWVyPCAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBDTEFTU05BTUUsIF9wcm90b19UeXBlVHJhaXRzLCBfZmllbGRfdHlwZSwgX2lzX3BhY2tlZD4mIGlkLCAgICAgICAgICAgXAorICAgICAgaW50IGluZGV4KSBjb25zdCB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIHJldHVybiBfcHJvdG9fVHlwZVRyYWl0czo6R2V0KGlkLm51bWJlcigpLCBfZXh0ZW5zaW9uc18sIGluZGV4KTsgICAgICAgICAgXAorICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgX3Byb3RvX1R5cGVUcmFpdHMsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RmllbGRUeXBlIF9maWVsZF90eXBlLCAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgIGJvb2wgX2lzX3BhY2tlZD4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgaW5saW5lIHR5cGVuYW1lIF9wcm90b19UeXBlVHJhaXRzOjpSZXBlYXRlZDo6TXV0YWJsZVR5cGUgTXV0YWJsZUV4dGVuc2lvbiggIFwKKyAgICAgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkV4dGVuc2lvbklkZW50aWZpZXI8ICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIENMQVNTTkFNRSwgX3Byb3RvX1R5cGVUcmFpdHMsIF9maWVsZF90eXBlLCBfaXNfcGFja2VkPiYgaWQsICAgICAgICAgICBcCisgICAgICBpbnQgaW5kZXgpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgcmV0dXJuIF9wcm90b19UeXBlVHJhaXRzOjpNdXRhYmxlKGlkLm51bWJlcigpLCBpbmRleCwgJl9leHRlbnNpb25zXyk7ICAgICBcCisgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBfcHJvdG9fVHlwZVRyYWl0cywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpGaWVsZFR5cGUgX2ZpZWxkX3R5cGUsICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgYm9vbCBfaXNfcGFja2VkPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBpbmxpbmUgdm9pZCBTZXRFeHRlbnNpb24oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RXh0ZW5zaW9uSWRlbnRpZmllcjwgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgQ0xBU1NOQU1FLCBfcHJvdG9fVHlwZVRyYWl0cywgX2ZpZWxkX3R5cGUsIF9pc19wYWNrZWQ+JiBpZCwgICAgICAgICAgIFwKKyAgICAgIGludCBpbmRleCwgdHlwZW5hbWUgX3Byb3RvX1R5cGVUcmFpdHM6OlJlcGVhdGVkOjpDb25zdFR5cGUgdmFsdWUpIHsgICAgIFwKKyAgICBfcHJvdG9fVHlwZVRyYWl0czo6U2V0KGlkLm51bWJlcigpLCBpbmRleCwgdmFsdWUsICZfZXh0ZW5zaW9uc18pOyAgICAgICAgIFwKKyAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIF9wcm90b19UeXBlVHJhaXRzLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkZpZWxkVHlwZSBfZmllbGRfdHlwZSwgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICBib29sIF9pc19wYWNrZWQ+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGlubGluZSB0eXBlbmFtZSBfcHJvdG9fVHlwZVRyYWl0czo6UmVwZWF0ZWQ6Ok11dGFibGVUeXBlIEFkZEV4dGVuc2lvbiggICAgICBcCisgICAgICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpFeHRlbnNpb25JZGVudGlmaWVyPCAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBDTEFTU05BTUUsIF9wcm90b19UeXBlVHJhaXRzLCBfZmllbGRfdHlwZSwgX2lzX3BhY2tlZD4mIGlkKSB7ICAgICAgICAgXAorICAgIHJldHVybiBfcHJvdG9fVHlwZVRyYWl0czo6QWRkKGlkLm51bWJlcigpLCBfZmllbGRfdHlwZSwgJl9leHRlbnNpb25zXyk7ICAgXAorICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgX3Byb3RvX1R5cGVUcmFpdHMsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RmllbGRUeXBlIF9maWVsZF90eXBlLCAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgIGJvb2wgX2lzX3BhY2tlZD4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgaW5saW5lIHZvaWQgQWRkRXh0ZW5zaW9uKCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkV4dGVuc2lvbklkZW50aWZpZXI8ICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIENMQVNTTkFNRSwgX3Byb3RvX1R5cGVUcmFpdHMsIF9maWVsZF90eXBlLCBfaXNfcGFja2VkPiYgaWQsICAgICAgICAgICBcCisgICAgICB0eXBlbmFtZSBfcHJvdG9fVHlwZVRyYWl0czo6UmVwZWF0ZWQ6OkNvbnN0VHlwZSB2YWx1ZSkgeyAgICAgICAgICAgICAgICBcCisgICAgX3Byb3RvX1R5cGVUcmFpdHM6OkFkZChpZC5udW1iZXIoKSwgX2ZpZWxkX3R5cGUsIF9pc19wYWNrZWQsICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSwgJl9leHRlbnNpb25zXyk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBfcHJvdG9fVHlwZVRyYWl0cywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpGaWVsZFR5cGUgX2ZpZWxkX3R5cGUsICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgYm9vbCBfaXNfcGFja2VkPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBpbmxpbmUgY29uc3QgdHlwZW5hbWUgX3Byb3RvX1R5cGVUcmFpdHM6OlJlcGVhdGVkOjpSZXBlYXRlZEZpZWxkVHlwZSYgICAgICAgXAorICAgICAgR2V0UmVwZWF0ZWRFeHRlbnNpb24oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkV4dGVuc2lvbklkZW50aWZpZXI8ICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgIENMQVNTTkFNRSwgX3Byb3RvX1R5cGVUcmFpdHMsIF9maWVsZF90eXBlLCAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgIF9pc19wYWNrZWQ+JiBpZCkgY29uc3QgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICByZXR1cm4gX3Byb3RvX1R5cGVUcmFpdHM6OkdldFJlcGVhdGVkKGlkLm51bWJlcigpLCBfZXh0ZW5zaW9uc18pOyAgICAgICAgIFwKKyAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIF9wcm90b19UeXBlVHJhaXRzLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkZpZWxkVHlwZSBfZmllbGRfdHlwZSwgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICBib29sIF9pc19wYWNrZWQ+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGlubGluZSB0eXBlbmFtZSBfcHJvdG9fVHlwZVRyYWl0czo6UmVwZWF0ZWQ6OlJlcGVhdGVkRmllbGRUeXBlKiAgICAgICAgICAgICBcCisgICAgICBNdXRhYmxlUmVwZWF0ZWRFeHRlbnNpb24oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RXh0ZW5zaW9uSWRlbnRpZmllcjwgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICBDTEFTU05BTUUsIF9wcm90b19UeXBlVHJhaXRzLCBfZmllbGRfdHlwZSwgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICBfaXNfcGFja2VkPiYgaWQpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIHJldHVybiBfcHJvdG9fVHlwZVRyYWl0czo6TXV0YWJsZVJlcGVhdGVkKGlkLm51bWJlcigpLCBfZmllbGRfdHlwZSwgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9pc19wYWNrZWQsICZfZXh0ZW5zaW9uc18pOyAgICAgXAorICB9CisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0VYVEVOU0lPTl9TRVRfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2V4dGVuc2lvbl9zZXRfaGVhdnkuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2V4dGVuc2lvbl9zZXRfaGVhdnkuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODJlM2UwOQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvZXh0ZW5zaW9uX3NldF9oZWF2eS5jYwpAQCAtMCwwICsxLDc1NCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorLy8KKy8vIENvbnRhaW5zIG1ldGhvZHMgZGVmaW5lZCBpbiBleHRlbnNpb25fc2V0Lmggd2hpY2ggY2Fubm90IGJlIHBhcnQgb2YgdGhlCisvLyBsaXRlIGxpYnJhcnkgYmVjYXVzZSB0aGV5IHVzZSBkZXNjcmlwdG9ycyBvciByZWZsZWN0aW9uLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbF9saXRlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZXh0ZW5zaW9uX3NldC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tZXNzYWdlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3JlcGVhdGVkX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0X2xpdGVfaW5sLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworCituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKworLy8gQSBGaWVsZFNraXBwZXIgdXNlZCB0byBzdG9yZSB1bmtub3duIE1lc3NhZ2VTZXQgZmllbGRzIGludG8gVW5rbm93bkZpZWxkU2V0LgorY2xhc3MgTWVzc2FnZVNldEZpZWxkU2tpcHBlcgorICAgIDogcHVibGljIFVua25vd25GaWVsZFNldEZpZWxkU2tpcHBlciB7CisgcHVibGljOgorICBleHBsaWNpdCBNZXNzYWdlU2V0RmllbGRTa2lwcGVyKFVua25vd25GaWVsZFNldCogdW5rbm93bl9maWVsZHMpCisgICAgICA6IFVua25vd25GaWVsZFNldEZpZWxkU2tpcHBlcih1bmtub3duX2ZpZWxkcykge30KKyAgdmlydHVhbCB+TWVzc2FnZVNldEZpZWxkU2tpcHBlcigpIHt9CisKKyAgdmlydHVhbCBib29sIFNraXBNZXNzYWdlU2V0RmllbGQoaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZmllbGRfbnVtYmVyKTsKK307Citib29sIE1lc3NhZ2VTZXRGaWVsZFNraXBwZXI6OlNraXBNZXNzYWdlU2V0RmllbGQoCisgICAgaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LCBpbnQgZmllbGRfbnVtYmVyKSB7CisgIHVpbnQzMiBsZW5ndGg7CisgIGlmICghaW5wdXQtPlJlYWRWYXJpbnQzMigmbGVuZ3RoKSkgcmV0dXJuIGZhbHNlOworICBpZiAodW5rbm93bl9maWVsZHNfID09IE5VTEwpIHsKKyAgICByZXR1cm4gaW5wdXQtPlNraXAobGVuZ3RoKTsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gaW5wdXQtPlJlYWRTdHJpbmcoCisgICAgICAgIHVua25vd25fZmllbGRzXy0+QWRkTGVuZ3RoRGVsaW1pdGVkKGZpZWxkX251bWJlciksIGxlbmd0aCk7CisgIH0KK30KKworCisvLyBJbXBsZW1lbnRhdGlvbiBvZiBFeHRlbnNpb25GaW5kZXIgd2hpY2ggZmluZHMgZXh0ZW5zaW9ucyBpbiBhIGdpdmVuCisvLyBEZXNjcmlwdG9yUG9vbCwgdXNpbmcgdGhlIGdpdmVuIE1lc3NhZ2VGYWN0b3J5IHRvIGNvbnN0cnVjdCBzdWItb2JqZWN0cy4KKy8vIFRoaXMgY2xhc3MgaXMgaW1wbGVtZW50ZWQgaW4gZXh0ZW5zaW9uX3NldF9oZWF2eS5jYy4KK2NsYXNzIERlc2NyaXB0b3JQb29sRXh0ZW5zaW9uRmluZGVyIDogcHVibGljIEV4dGVuc2lvbkZpbmRlciB7CisgcHVibGljOgorICBEZXNjcmlwdG9yUG9vbEV4dGVuc2lvbkZpbmRlcihjb25zdCBEZXNjcmlwdG9yUG9vbCogcG9vbCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUZhY3RvcnkqIGZhY3RvcnksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlc2NyaXB0b3IqIGNvbnRhaW5pbmdfdHlwZSkKKyAgICAgIDogcG9vbF8ocG9vbCksIGZhY3RvcnlfKGZhY3RvcnkpLCBjb250YWluaW5nX3R5cGVfKGNvbnRhaW5pbmdfdHlwZSkge30KKyAgdmlydHVhbCB+RGVzY3JpcHRvclBvb2xFeHRlbnNpb25GaW5kZXIoKSB7fQorCisgIHZpcnR1YWwgYm9vbCBGaW5kKGludCBudW1iZXIsIEV4dGVuc2lvbkluZm8qIG91dHB1dCk7CisKKyBwcml2YXRlOgorICBjb25zdCBEZXNjcmlwdG9yUG9vbCogcG9vbF87CisgIE1lc3NhZ2VGYWN0b3J5KiBmYWN0b3J5XzsKKyAgY29uc3QgRGVzY3JpcHRvciogY29udGFpbmluZ190eXBlXzsKK307CisKK3ZvaWQgRXh0ZW5zaW9uU2V0OjpBcHBlbmRUb0xpc3QoCisgICAgY29uc3QgRGVzY3JpcHRvciogY29udGFpbmluZ190eXBlLAorICAgIGNvbnN0IERlc2NyaXB0b3JQb29sKiBwb29sLAorICAgIHN0ZDo6dmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+KiBvdXRwdXQpIGNvbnN0IHsKKyAgZm9yIChtYXA8aW50LCBFeHRlbnNpb24+Ojpjb25zdF9pdGVyYXRvciBpdGVyID0gZXh0ZW5zaW9uc18uYmVnaW4oKTsKKyAgICAgICBpdGVyICE9IGV4dGVuc2lvbnNfLmVuZCgpOyArK2l0ZXIpIHsKKyAgICBib29sIGhhcyA9IGZhbHNlOworICAgIGlmIChpdGVyLT5zZWNvbmQuaXNfcmVwZWF0ZWQpIHsKKyAgICAgIGhhcyA9IGl0ZXItPnNlY29uZC5HZXRTaXplKCkgPiAwOworICAgIH0gZWxzZSB7CisgICAgICBoYXMgPSAhaXRlci0+c2Vjb25kLmlzX2NsZWFyZWQ7CisgICAgfQorCisgICAgaWYgKGhhcykgeworICAgICAgLy8gVE9ETyhrZW50b24pOiBMb29raW5nIHVwIGVhY2ggZmllbGQgYnkgbnVtYmVyIGlzIHNvbWV3aGF0IHVuZm9ydHVuYXRlLgorICAgICAgLy8gICBJcyB0aGVyZSBhIGJldHRlciB3YXk/ICBUaGUgcHJvYmxlbSBpcyB0aGF0IGRlc2NyaXB0b3JzIGFyZSBsYXppbHktCisgICAgICAvLyAgIGluaXRpYWxpemVkLCBzbyB0aGV5IG1pZ2h0IG5vdCBldmVuIGJlIGNvbnN0cnVjdGVkIHVudGlsCisgICAgICAvLyAgIEFwcGVuZFRvTGlzdCgpIGlzIGNhbGxlZC4KKworICAgICAgaWYgKGl0ZXItPnNlY29uZC5kZXNjcmlwdG9yID09IE5VTEwpIHsKKyAgICAgICAgb3V0cHV0LT5wdXNoX2JhY2socG9vbC0+RmluZEV4dGVuc2lvbkJ5TnVtYmVyKAorICAgICAgICAgICAgY29udGFpbmluZ190eXBlLCBpdGVyLT5maXJzdCkpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgb3V0cHV0LT5wdXNoX2JhY2soaXRlci0+c2Vjb25kLmRlc2NyaXB0b3IpOworICAgICAgfQorICAgIH0KKyAgfQorfQorCitpbmxpbmUgRmllbGREZXNjcmlwdG9yOjpUeXBlIHJlYWxfdHlwZShGaWVsZFR5cGUgdHlwZSkgeworICBHT09HTEVfRENIRUNLKHR5cGUgPiAwICYmIHR5cGUgPD0gRmllbGREZXNjcmlwdG9yOjpNQVhfVFlQRSk7CisgIHJldHVybiBzdGF0aWNfY2FzdDxGaWVsZERlc2NyaXB0b3I6OlR5cGU+KHR5cGUpOworfQorCitpbmxpbmUgRmllbGREZXNjcmlwdG9yOjpDcHBUeXBlIGNwcF90eXBlKEZpZWxkVHlwZSB0eXBlKSB7CisgIHJldHVybiBGaWVsZERlc2NyaXB0b3I6OlR5cGVUb0NwcFR5cGUoCisgICAgICBzdGF0aWNfY2FzdDxGaWVsZERlc2NyaXB0b3I6OlR5cGU+KHR5cGUpKTsKK30KKworaW5saW5lIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUgZmllbGRfdHlwZShGaWVsZFR5cGUgdHlwZSkgeworICBHT09HTEVfRENIRUNLKHR5cGUgPiAwICYmIHR5cGUgPD0gV2lyZUZvcm1hdExpdGU6Ok1BWF9GSUVMRF9UWVBFKTsKKyAgcmV0dXJuIHN0YXRpY19jYXN0PFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGU+KHR5cGUpOworfQorCisjZGVmaW5lIEdPT0dMRV9EQ0hFQ0tfVFlQRShFWFRFTlNJT04sIExBQkVMLCBDUFBUWVBFKSAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIEdPT0dMRV9EQ0hFQ0tfRVEoKEVYVEVOU0lPTikuaXNfcmVwZWF0ZWQgPyBGaWVsZERlc2NyaXB0b3I6OkxBQkVMX1JFUEVBVEVEICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBGaWVsZERlc2NyaXB0b3I6OkxBQkVMX09QVElPTkFMLCAgICAgIFwKKyAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvcjo6TEFCRUxfIyNMQUJFTCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBHT09HTEVfRENIRUNLX0VRKGNwcF90eXBlKChFWFRFTlNJT04pLnR5cGUpLCBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfIyNDUFBUWVBFKQorCitjb25zdCBNZXNzYWdlTGl0ZSYgRXh0ZW5zaW9uU2V0OjpHZXRNZXNzYWdlKGludCBudW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlc2NyaXB0b3IqIG1lc3NhZ2VfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUZhY3RvcnkqIGZhY3RvcnkpIGNvbnN0IHsKKyAgbWFwPGludCwgRXh0ZW5zaW9uPjo6Y29uc3RfaXRlcmF0b3IgaXRlciA9IGV4dGVuc2lvbnNfLmZpbmQobnVtYmVyKTsKKyAgaWYgKGl0ZXIgPT0gZXh0ZW5zaW9uc18uZW5kKCkgfHwgaXRlci0+c2Vjb25kLmlzX2NsZWFyZWQpIHsKKyAgICAvLyBOb3QgcHJlc2VudC4gIFJldHVybiB0aGUgZGVmYXVsdCB2YWx1ZS4KKyAgICByZXR1cm4gKmZhY3RvcnktPkdldFByb3RvdHlwZShtZXNzYWdlX3R5cGUpOworICB9IGVsc2UgeworICAgIEdPT0dMRV9EQ0hFQ0tfVFlQRShpdGVyLT5zZWNvbmQsIE9QVElPTkFMLCBNRVNTQUdFKTsKKyAgICBpZiAoaXRlci0+c2Vjb25kLmlzX2xhenkpIHsKKyAgICAgIHJldHVybiBpdGVyLT5zZWNvbmQubGF6eW1lc3NhZ2VfdmFsdWUtPkdldE1lc3NhZ2UoCisgICAgICAgICAgKmZhY3RvcnktPkdldFByb3RvdHlwZShtZXNzYWdlX3R5cGUpKTsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuICppdGVyLT5zZWNvbmQubWVzc2FnZV92YWx1ZTsKKyAgICB9CisgIH0KK30KKworTWVzc2FnZUxpdGUqIEV4dGVuc2lvblNldDo6TXV0YWJsZU1lc3NhZ2UoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUZhY3RvcnkqIGZhY3RvcnkpIHsKKyAgRXh0ZW5zaW9uKiBleHRlbnNpb247CisgIGlmIChNYXliZU5ld0V4dGVuc2lvbihkZXNjcmlwdG9yLT5udW1iZXIoKSwgZGVzY3JpcHRvciwgJmV4dGVuc2lvbikpIHsKKyAgICBleHRlbnNpb24tPnR5cGUgPSBkZXNjcmlwdG9yLT50eXBlKCk7CisgICAgR09PR0xFX0RDSEVDS19FUShjcHBfdHlwZShleHRlbnNpb24tPnR5cGUpLCBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSk7CisgICAgZXh0ZW5zaW9uLT5pc19yZXBlYXRlZCA9IGZhbHNlOworICAgIGV4dGVuc2lvbi0+aXNfcGFja2VkID0gZmFsc2U7CisgICAgY29uc3QgTWVzc2FnZUxpdGUqIHByb3RvdHlwZSA9CisgICAgICAgIGZhY3RvcnktPkdldFByb3RvdHlwZShkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKSk7CisgICAgZXh0ZW5zaW9uLT5pc19sYXp5ID0gZmFsc2U7CisgICAgZXh0ZW5zaW9uLT5tZXNzYWdlX3ZhbHVlID0gcHJvdG90eXBlLT5OZXcoYXJlbmFfKTsKKyAgICBleHRlbnNpb24tPmlzX2NsZWFyZWQgPSBmYWxzZTsKKyAgICByZXR1cm4gZXh0ZW5zaW9uLT5tZXNzYWdlX3ZhbHVlOworICB9IGVsc2UgeworICAgIEdPT0dMRV9EQ0hFQ0tfVFlQRSgqZXh0ZW5zaW9uLCBPUFRJT05BTCwgTUVTU0FHRSk7CisgICAgZXh0ZW5zaW9uLT5pc19jbGVhcmVkID0gZmFsc2U7CisgICAgaWYgKGV4dGVuc2lvbi0+aXNfbGF6eSkgeworICAgICAgcmV0dXJuIGV4dGVuc2lvbi0+bGF6eW1lc3NhZ2VfdmFsdWUtPk11dGFibGVNZXNzYWdlKAorICAgICAgICAgICpmYWN0b3J5LT5HZXRQcm90b3R5cGUoZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCkpKTsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIGV4dGVuc2lvbi0+bWVzc2FnZV92YWx1ZTsKKyAgICB9CisgIH0KK30KKworTWVzc2FnZUxpdGUqIEV4dGVuc2lvblNldDo6UmVsZWFzZU1lc3NhZ2UoY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUZhY3RvcnkqIGZhY3RvcnkpIHsKKyAgbWFwPGludCwgRXh0ZW5zaW9uPjo6aXRlcmF0b3IgaXRlciA9IGV4dGVuc2lvbnNfLmZpbmQoZGVzY3JpcHRvci0+bnVtYmVyKCkpOworICBpZiAoaXRlciA9PSBleHRlbnNpb25zXy5lbmQoKSkgeworICAgIC8vIE5vdCBwcmVzZW50LiAgUmV0dXJuIE5VTEwuCisgICAgcmV0dXJuIE5VTEw7CisgIH0gZWxzZSB7CisgICAgR09PR0xFX0RDSEVDS19UWVBFKGl0ZXItPnNlY29uZCwgT1BUSU9OQUwsIE1FU1NBR0UpOworICAgIE1lc3NhZ2VMaXRlKiByZXQgPSBOVUxMOworICAgIGlmIChpdGVyLT5zZWNvbmQuaXNfbGF6eSkgeworICAgICAgcmV0ID0gaXRlci0+c2Vjb25kLmxhenltZXNzYWdlX3ZhbHVlLT5SZWxlYXNlTWVzc2FnZSgKKyAgICAgICAgICAqZmFjdG9yeS0+R2V0UHJvdG90eXBlKGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpKSk7CisgICAgICBpZiAoYXJlbmFfID09IE5VTEwpIHsKKyAgICAgICAgZGVsZXRlIGl0ZXItPnNlY29uZC5sYXp5bWVzc2FnZV92YWx1ZTsKKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgaWYgKGFyZW5hXyAhPSBOVUxMKSB7CisgICAgICAgIHJldCA9IChpdGVyLT5zZWNvbmQubWVzc2FnZV92YWx1ZSktPk5ldygpOworICAgICAgICByZXQtPkNoZWNrVHlwZUFuZE1lcmdlRnJvbSgqKGl0ZXItPnNlY29uZC5tZXNzYWdlX3ZhbHVlKSk7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXQgPSBpdGVyLT5zZWNvbmQubWVzc2FnZV92YWx1ZTsKKyAgICAgIH0KKyAgICB9CisgICAgZXh0ZW5zaW9uc18uZXJhc2UoZGVzY3JpcHRvci0+bnVtYmVyKCkpOworICAgIHJldHVybiByZXQ7CisgIH0KK30KKworRXh0ZW5zaW9uU2V0OjpFeHRlbnNpb24qIEV4dGVuc2lvblNldDo6TWF5YmVOZXdSZXBlYXRlZEV4dGVuc2lvbihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgRXh0ZW5zaW9uKiBleHRlbnNpb247CisgIGlmIChNYXliZU5ld0V4dGVuc2lvbihkZXNjcmlwdG9yLT5udW1iZXIoKSwgZGVzY3JpcHRvciwgJmV4dGVuc2lvbikpIHsKKyAgICBleHRlbnNpb24tPnR5cGUgPSBkZXNjcmlwdG9yLT50eXBlKCk7CisgICAgR09PR0xFX0RDSEVDS19FUShjcHBfdHlwZShleHRlbnNpb24tPnR5cGUpLCBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSk7CisgICAgZXh0ZW5zaW9uLT5pc19yZXBlYXRlZCA9IHRydWU7CisgICAgZXh0ZW5zaW9uLT5yZXBlYXRlZF9tZXNzYWdlX3ZhbHVlID0KKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYTo6Q3JlYXRlTWVzc2FnZTxSZXBlYXRlZFB0ckZpZWxkPE1lc3NhZ2VMaXRlPiA+KGFyZW5hXyk7CisgIH0gZWxzZSB7CisgICAgR09PR0xFX0RDSEVDS19UWVBFKCpleHRlbnNpb24sIFJFUEVBVEVELCBNRVNTQUdFKTsKKyAgfQorICByZXR1cm4gZXh0ZW5zaW9uOworfQorCitNZXNzYWdlTGl0ZSogRXh0ZW5zaW9uU2V0OjpBZGRNZXNzYWdlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUZhY3RvcnkqIGZhY3RvcnkpIHsKKyAgRXh0ZW5zaW9uKiBleHRlbnNpb24gPSBNYXliZU5ld1JlcGVhdGVkRXh0ZW5zaW9uKGRlc2NyaXB0b3IpOworCisgIC8vIFJlcGVhdGVkUHRyRmllbGQ8TWVzc2FnZT4gZG9lcyBub3Qga25vdyBob3cgdG8gQWRkKCkgc2luY2UgaXQgY2Fubm90CisgIC8vIGFsbG9jYXRlIGFuIGFic3RyYWN0IG9iamVjdCwgc28gd2UgaGF2ZSB0byBiZSB0cmlja3kuCisgIE1lc3NhZ2VMaXRlKiByZXN1bHQgPSBleHRlbnNpb24tPnJlcGVhdGVkX21lc3NhZ2VfdmFsdWUKKyAgICAgIC0+QWRkRnJvbUNsZWFyZWQ8R2VuZXJpY1R5cGVIYW5kbGVyPE1lc3NhZ2VMaXRlPiA+KCk7CisgIGlmIChyZXN1bHQgPT0gTlVMTCkgeworICAgIGNvbnN0IE1lc3NhZ2VMaXRlKiBwcm90b3R5cGU7CisgICAgaWYgKGV4dGVuc2lvbi0+cmVwZWF0ZWRfbWVzc2FnZV92YWx1ZS0+c2l6ZSgpID09IDApIHsKKyAgICAgIHByb3RvdHlwZSA9IGZhY3RvcnktPkdldFByb3RvdHlwZShkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKSk7CisgICAgICBHT09HTEVfQ0hFQ0socHJvdG90eXBlICE9IE5VTEwpOworICAgIH0gZWxzZSB7CisgICAgICBwcm90b3R5cGUgPSAmZXh0ZW5zaW9uLT5yZXBlYXRlZF9tZXNzYWdlX3ZhbHVlLT5HZXQoMCk7CisgICAgfQorICAgIHJlc3VsdCA9IHByb3RvdHlwZS0+TmV3KGFyZW5hXyk7CisgICAgZXh0ZW5zaW9uLT5yZXBlYXRlZF9tZXNzYWdlX3ZhbHVlLT5BZGRBbGxvY2F0ZWQocmVzdWx0KTsKKyAgfQorICByZXR1cm4gcmVzdWx0OworfQorCit2b2lkIEV4dGVuc2lvblNldDo6QWRkQWxsb2NhdGVkTWVzc2FnZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlTGl0ZSogbmV3X2VudHJ5KSB7CisgIEV4dGVuc2lvbiogZXh0ZW5zaW9uID0gTWF5YmVOZXdSZXBlYXRlZEV4dGVuc2lvbihkZXNjcmlwdG9yKTsKKworICBleHRlbnNpb24tPnJlcGVhdGVkX21lc3NhZ2VfdmFsdWUtPkFkZEFsbG9jYXRlZChuZXdfZW50cnkpOworfQorCitzdGF0aWMgYm9vbCBWYWxpZGF0ZUVudW1Vc2luZ0Rlc2NyaXB0b3IoY29uc3Qgdm9pZCogYXJnLCBpbnQgbnVtYmVyKSB7CisgIHJldHVybiByZWludGVycHJldF9jYXN0PGNvbnN0IEVudW1EZXNjcmlwdG9yKj4oYXJnKQorICAgICAgLT5GaW5kVmFsdWVCeU51bWJlcihudW1iZXIpICE9IE5VTEw7Cit9CisKK2Jvb2wgRGVzY3JpcHRvclBvb2xFeHRlbnNpb25GaW5kZXI6OkZpbmQoaW50IG51bWJlciwgRXh0ZW5zaW9uSW5mbyogb3V0cHV0KSB7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZXh0ZW5zaW9uID0KKyAgICAgIHBvb2xfLT5GaW5kRXh0ZW5zaW9uQnlOdW1iZXIoY29udGFpbmluZ190eXBlXywgbnVtYmVyKTsKKyAgaWYgKGV4dGVuc2lvbiA9PSBOVUxMKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9IGVsc2UgeworICAgIG91dHB1dC0+dHlwZSA9IGV4dGVuc2lvbi0+dHlwZSgpOworICAgIG91dHB1dC0+aXNfcmVwZWF0ZWQgPSBleHRlbnNpb24tPmlzX3JlcGVhdGVkKCk7CisgICAgb3V0cHV0LT5pc19wYWNrZWQgPSBleHRlbnNpb24tPm9wdGlvbnMoKS5wYWNrZWQoKTsKKyAgICBvdXRwdXQtPmRlc2NyaXB0b3IgPSBleHRlbnNpb247CisgICAgaWYgKGV4dGVuc2lvbi0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSkgeworICAgICAgb3V0cHV0LT5tZXNzYWdlX3Byb3RvdHlwZSA9CisgICAgICAgICAgZmFjdG9yeV8tPkdldFByb3RvdHlwZShleHRlbnNpb24tPm1lc3NhZ2VfdHlwZSgpKTsKKyAgICAgIEdPT0dMRV9DSEVDSyhvdXRwdXQtPm1lc3NhZ2VfcHJvdG90eXBlICE9IE5VTEwpCisgICAgICAgICAgPDwgIkV4dGVuc2lvbiBmYWN0b3J5J3MgR2V0UHJvdG90eXBlKCkgcmV0dXJuZWQgTlVMTCBmb3IgZXh0ZW5zaW9uOiAiCisgICAgICAgICAgPDwgZXh0ZW5zaW9uLT5mdWxsX25hbWUoKTsKKyAgICB9IGVsc2UgaWYgKGV4dGVuc2lvbi0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRU5VTSkgeworICAgICAgb3V0cHV0LT5lbnVtX3ZhbGlkaXR5X2NoZWNrLmZ1bmMgPSBWYWxpZGF0ZUVudW1Vc2luZ0Rlc2NyaXB0b3I7CisgICAgICBvdXRwdXQtPmVudW1fdmFsaWRpdHlfY2hlY2suYXJnID0gZXh0ZW5zaW9uLT5lbnVtX3R5cGUoKTsKKyAgICB9CisKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorfQorCitib29sIEV4dGVuc2lvblNldDo6UGFyc2VGaWVsZCh1aW50MzIgdGFnLCBpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNZXNzYWdlKiBjb250YWluaW5nX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVbmtub3duRmllbGRTZXQqIHVua25vd25fZmllbGRzKSB7CisgIFVua25vd25GaWVsZFNldEZpZWxkU2tpcHBlciBza2lwcGVyKHVua25vd25fZmllbGRzKTsKKyAgaWYgKGlucHV0LT5HZXRFeHRlbnNpb25Qb29sKCkgPT0gTlVMTCkgeworICAgIEdlbmVyYXRlZEV4dGVuc2lvbkZpbmRlciBmaW5kZXIoY29udGFpbmluZ190eXBlKTsKKyAgICByZXR1cm4gUGFyc2VGaWVsZCh0YWcsIGlucHV0LCAmZmluZGVyLCAmc2tpcHBlcik7CisgIH0gZWxzZSB7CisgICAgRGVzY3JpcHRvclBvb2xFeHRlbnNpb25GaW5kZXIgZmluZGVyKGlucHV0LT5HZXRFeHRlbnNpb25Qb29sKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0LT5HZXRFeHRlbnNpb25GYWN0b3J5KCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRhaW5pbmdfdHlwZS0+R2V0RGVzY3JpcHRvcigpKTsKKyAgICByZXR1cm4gUGFyc2VGaWVsZCh0YWcsIGlucHV0LCAmZmluZGVyLCAmc2tpcHBlcik7CisgIH0KK30KKworYm9vbCBFeHRlbnNpb25TZXQ6OlBhcnNlTWVzc2FnZVNldChpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2UqIGNvbnRhaW5pbmdfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVW5rbm93bkZpZWxkU2V0KiB1bmtub3duX2ZpZWxkcykgeworICBNZXNzYWdlU2V0RmllbGRTa2lwcGVyIHNraXBwZXIodW5rbm93bl9maWVsZHMpOworICBpZiAoaW5wdXQtPkdldEV4dGVuc2lvblBvb2woKSA9PSBOVUxMKSB7CisgICAgR2VuZXJhdGVkRXh0ZW5zaW9uRmluZGVyIGZpbmRlcihjb250YWluaW5nX3R5cGUpOworICAgIHJldHVybiBQYXJzZU1lc3NhZ2VTZXQoaW5wdXQsICZmaW5kZXIsICZza2lwcGVyKTsKKyAgfSBlbHNlIHsKKyAgICBEZXNjcmlwdG9yUG9vbEV4dGVuc2lvbkZpbmRlciBmaW5kZXIoaW5wdXQtPkdldEV4dGVuc2lvblBvb2woKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQtPkdldEV4dGVuc2lvbkZhY3RvcnkoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGFpbmluZ190eXBlLT5HZXREZXNjcmlwdG9yKCkpOworICAgIHJldHVybiBQYXJzZU1lc3NhZ2VTZXQoaW5wdXQsICZmaW5kZXIsICZza2lwcGVyKTsKKyAgfQorfQorCitpbnQgRXh0ZW5zaW9uU2V0OjpTcGFjZVVzZWRFeGNsdWRpbmdTZWxmKCkgY29uc3QgeworICBpbnQgdG90YWxfc2l6ZSA9CisgICAgICBleHRlbnNpb25zXy5zaXplKCkgKiBzaXplb2YobWFwPGludCwgRXh0ZW5zaW9uPjo6dmFsdWVfdHlwZSk7CisgIGZvciAobWFwPGludCwgRXh0ZW5zaW9uPjo6Y29uc3RfaXRlcmF0b3IgaXRlciA9IGV4dGVuc2lvbnNfLmJlZ2luKCksCisgICAgICAgZW5kID0gZXh0ZW5zaW9uc18uZW5kKCk7CisgICAgICAgaXRlciAhPSBlbmQ7CisgICAgICAgKytpdGVyKSB7CisgICAgdG90YWxfc2l6ZSArPSBpdGVyLT5zZWNvbmQuU3BhY2VVc2VkRXhjbHVkaW5nU2VsZigpOworICB9CisgIHJldHVybiB0b3RhbF9zaXplOworfQorCitpbmxpbmUgaW50IEV4dGVuc2lvblNldDo6UmVwZWF0ZWRNZXNzYWdlX1NwYWNlVXNlZEV4Y2x1ZGluZ1NlbGYoCisgICAgUmVwZWF0ZWRQdHJGaWVsZEJhc2UqIGZpZWxkKSB7CisgIHJldHVybiBmaWVsZC0+U3BhY2VVc2VkRXhjbHVkaW5nU2VsZjxHZW5lcmljVHlwZUhhbmRsZXI8TWVzc2FnZT4gPigpOworfQorCitpbnQgRXh0ZW5zaW9uU2V0OjpFeHRlbnNpb246OlNwYWNlVXNlZEV4Y2x1ZGluZ1NlbGYoKSBjb25zdCB7CisgIGludCB0b3RhbF9zaXplID0gMDsKKyAgaWYgKGlzX3JlcGVhdGVkKSB7CisgICAgc3dpdGNoIChjcHBfdHlwZSh0eXBlKSkgeworI2RlZmluZSBIQU5ETEVfVFlQRShVUFBFUkNBU0UsIExPV0VSQ0FTRSkgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFXyMjVVBQRVJDQVNFOiAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIHRvdGFsX3NpemUgKz0gc2l6ZW9mKCpyZXBlYXRlZF8jI0xPV0VSQ0FTRSMjX3ZhbHVlKSArICAgICAgXAorICAgICAgICAgICAgcmVwZWF0ZWRfIyNMT1dFUkNBU0UjI192YWx1ZS0+U3BhY2VVc2VkRXhjbHVkaW5nU2VsZigpO1wKKyAgICAgICAgYnJlYWsKKworICAgICAgSEFORExFX1RZUEUoICBJTlQzMiwgICBpbnQzMik7CisgICAgICBIQU5ETEVfVFlQRSggIElOVDY0LCAgIGludDY0KTsKKyAgICAgIEhBTkRMRV9UWVBFKCBVSU5UMzIsICB1aW50MzIpOworICAgICAgSEFORExFX1RZUEUoIFVJTlQ2NCwgIHVpbnQ2NCk7CisgICAgICBIQU5ETEVfVFlQRSggIEZMT0FULCAgIGZsb2F0KTsKKyAgICAgIEhBTkRMRV9UWVBFKCBET1VCTEUsICBkb3VibGUpOworICAgICAgSEFORExFX1RZUEUoICAgQk9PTCwgICAgYm9vbCk7CisgICAgICBIQU5ETEVfVFlQRSggICBFTlVNLCAgICBlbnVtKTsKKyAgICAgIEhBTkRMRV9UWVBFKCBTVFJJTkcsICBzdHJpbmcpOworI3VuZGVmIEhBTkRMRV9UWVBFCisKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U6CisgICAgICAgIC8vIHJlcGVhdGVkX21lc3NhZ2VfdmFsdWUgaXMgYWN0dWFsbHkgYSBSZXBlYXRlZFB0ckZpZWxkPE1lc3NhZ2VMaXRlPiwKKyAgICAgICAgLy8gYnV0IE1lc3NhZ2VMaXRlIGhhcyBubyBTcGFjZVVzZWQoKSwgc28gd2UgbXVzdCBkaXJlY3RseSBjYWxsCisgICAgICAgIC8vIFJlcGVhdGVkUHRyRmllbGRCYXNlOjpTcGFjZVVzZWRFeGNsdWRpbmdTZWxmKCkgd2l0aCBhIGRpZmZlcmVudCB0eXBlCisgICAgICAgIC8vIGhhbmRsZXIuCisgICAgICAgIHRvdGFsX3NpemUgKz0gc2l6ZW9mKCpyZXBlYXRlZF9tZXNzYWdlX3ZhbHVlKSArCisgICAgICAgICAgICBSZXBlYXRlZE1lc3NhZ2VfU3BhY2VVc2VkRXhjbHVkaW5nU2VsZihyZXBlYXRlZF9tZXNzYWdlX3ZhbHVlKTsKKyAgICAgICAgYnJlYWs7CisgICAgfQorICB9IGVsc2UgeworICAgIHN3aXRjaCAoY3BwX3R5cGUodHlwZSkpIHsKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORzoKKyAgICAgICAgdG90YWxfc2l6ZSArPSBzaXplb2YoKnN0cmluZ192YWx1ZSkgKworICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1NwYWNlVXNlZEV4Y2x1ZGluZ1NlbGYoKnN0cmluZ192YWx1ZSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRToKKyAgICAgICAgaWYgKGlzX2xhenkpIHsKKyAgICAgICAgICB0b3RhbF9zaXplICs9IGxhenltZXNzYWdlX3ZhbHVlLT5TcGFjZVVzZWQoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICB0b3RhbF9zaXplICs9IGRvd25fY2FzdDxNZXNzYWdlKj4obWVzc2FnZV92YWx1ZSktPlNwYWNlVXNlZCgpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgLy8gTm8gZXh0cmEgc3RvcmFnZSBjb3N0cyBmb3IgcHJpbWl0aXZlIHR5cGVzLgorICAgICAgICBicmVhazsKKyAgICB9CisgIH0KKyAgcmV0dXJuIHRvdGFsX3NpemU7Cit9CisKKy8vIFRoZSBTZXJpYWxpemUqVG9BcnJheSBtZXRob2RzIGFyZSBvbmx5IG5lZWRlZCBpbiB0aGUgaGVhdnkgbGlicmFyeSwgYXMKKy8vIHRoZSBsaXRlIGxpYnJhcnkgb25seSBnZW5lcmF0ZXMgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzLgordWludDgqIEV4dGVuc2lvblNldDo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICBpbnQgc3RhcnRfZmllbGRfbnVtYmVyLCBpbnQgZW5kX2ZpZWxkX251bWJlciwKKyAgICB1aW50OCogdGFyZ2V0KSBjb25zdCB7CisgIG1hcDxpbnQsIEV4dGVuc2lvbj46OmNvbnN0X2l0ZXJhdG9yIGl0ZXI7CisgIGZvciAoaXRlciA9IGV4dGVuc2lvbnNfLmxvd2VyX2JvdW5kKHN0YXJ0X2ZpZWxkX251bWJlcik7CisgICAgICAgaXRlciAhPSBleHRlbnNpb25zXy5lbmQoKSAmJiBpdGVyLT5maXJzdCA8IGVuZF9maWVsZF9udW1iZXI7CisgICAgICAgKytpdGVyKSB7CisgICAgdGFyZ2V0ID0gaXRlci0+c2Vjb25kLlNlcmlhbGl6ZUZpZWxkV2l0aENhY2hlZFNpemVzVG9BcnJheShpdGVyLT5maXJzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldCk7CisgIH0KKyAgcmV0dXJuIHRhcmdldDsKK30KKwordWludDgqIEV4dGVuc2lvblNldDo6U2VyaWFsaXplTWVzc2FnZVNldFdpdGhDYWNoZWRTaXplc1RvQXJyYXkoCisgICAgdWludDgqIHRhcmdldCkgY29uc3QgeworICBtYXA8aW50LCBFeHRlbnNpb24+Ojpjb25zdF9pdGVyYXRvciBpdGVyOworICBmb3IgKGl0ZXIgPSBleHRlbnNpb25zXy5iZWdpbigpOyBpdGVyICE9IGV4dGVuc2lvbnNfLmVuZCgpOyArK2l0ZXIpIHsKKyAgICB0YXJnZXQgPSBpdGVyLT5zZWNvbmQuU2VyaWFsaXplTWVzc2FnZVNldEl0ZW1XaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KAorICAgICAgICBpdGVyLT5maXJzdCwgdGFyZ2V0KTsKKyAgfQorICByZXR1cm4gdGFyZ2V0OworfQorCit1aW50OCogRXh0ZW5zaW9uU2V0OjpFeHRlbnNpb246OlNlcmlhbGl6ZUZpZWxkV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICBpbnQgbnVtYmVyLCB1aW50OCogdGFyZ2V0KSBjb25zdCB7CisgIGlmIChpc19yZXBlYXRlZCkgeworICAgIGlmIChpc19wYWNrZWQpIHsKKyAgICAgIGlmIChjYWNoZWRfc2l6ZSA9PSAwKSByZXR1cm4gdGFyZ2V0OworCisgICAgICB0YXJnZXQgPSBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVUYWdUb0FycmF5KG51bWJlciwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCwgdGFyZ2V0KTsKKyAgICAgIHRhcmdldCA9IFdpcmVGb3JtYXRMaXRlOjpXcml0ZUludDMyTm9UYWdUb0FycmF5KGNhY2hlZF9zaXplLCB0YXJnZXQpOworCisgICAgICBzd2l0Y2ggKHJlYWxfdHlwZSh0eXBlKSkgeworI2RlZmluZSBIQU5ETEVfVFlQRShVUFBFUkNBU0UsIENBTUVMQ0FTRSwgTE9XRVJDQVNFKSAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfIyNVUFBFUkNBU0U6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZF8jI0xPV0VSQ0FTRSMjX3ZhbHVlLT5zaXplKCk7IGkrKykgeyAgXAorICAgICAgICAgICAgdGFyZ2V0ID0gV2lyZUZvcm1hdExpdGU6OldyaXRlIyNDQU1FTENBU0UjI05vVGFnVG9BcnJheSggICAgICAgIFwKKyAgICAgICAgICAgICAgcmVwZWF0ZWRfIyNMT1dFUkNBU0UjI192YWx1ZS0+R2V0KGkpLCB0YXJnZXQpOyAgICAgICAgICAgICAgICBcCisgICAgICAgICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgIGJyZWFrCisKKyAgICAgICAgSEFORExFX1RZUEUoICAgSU5UMzIsICAgIEludDMyLCAgIGludDMyKTsKKyAgICAgICAgSEFORExFX1RZUEUoICAgSU5UNjQsICAgIEludDY0LCAgIGludDY0KTsKKyAgICAgICAgSEFORExFX1RZUEUoICBVSU5UMzIsICAgVUludDMyLCAgdWludDMyKTsKKyAgICAgICAgSEFORExFX1RZUEUoICBVSU5UNjQsICAgVUludDY0LCAgdWludDY0KTsKKyAgICAgICAgSEFORExFX1RZUEUoICBTSU5UMzIsICAgU0ludDMyLCAgIGludDMyKTsKKyAgICAgICAgSEFORExFX1RZUEUoICBTSU5UNjQsICAgU0ludDY0LCAgIGludDY0KTsKKyAgICAgICAgSEFORExFX1RZUEUoIEZJWEVEMzIsICBGaXhlZDMyLCAgdWludDMyKTsKKyAgICAgICAgSEFORExFX1RZUEUoIEZJWEVENjQsICBGaXhlZDY0LCAgdWludDY0KTsKKyAgICAgICAgSEFORExFX1RZUEUoU0ZJWEVEMzIsIFNGaXhlZDMyLCAgIGludDMyKTsKKyAgICAgICAgSEFORExFX1RZUEUoU0ZJWEVENjQsIFNGaXhlZDY0LCAgIGludDY0KTsKKyAgICAgICAgSEFORExFX1RZUEUoICAgRkxPQVQsICAgIEZsb2F0LCAgIGZsb2F0KTsKKyAgICAgICAgSEFORExFX1RZUEUoICBET1VCTEUsICAgRG91YmxlLCAgZG91YmxlKTsKKyAgICAgICAgSEFORExFX1RZUEUoICAgIEJPT0wsICAgICBCb29sLCAgICBib29sKTsKKyAgICAgICAgSEFORExFX1RZUEUoICAgIEVOVU0sICAgICBFbnVtLCAgICBlbnVtKTsKKyN1bmRlZiBIQU5ETEVfVFlQRQorCisgICAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OlRZUEVfU1RSSU5HOgorICAgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpUWVBFX0JZVEVTOgorICAgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpUWVBFX0dST1VQOgorICAgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpUWVBFX01FU1NBR0U6CisgICAgICAgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIk5vbi1wcmltaXRpdmUgdHlwZXMgY2FuJ3QgYmUgcGFja2VkLiI7CisgICAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgIHN3aXRjaCAocmVhbF90eXBlKHR5cGUpKSB7CisjZGVmaW5lIEhBTkRMRV9UWVBFKFVQUEVSQ0FTRSwgQ0FNRUxDQVNFLCBMT1dFUkNBU0UpICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV8jI1VQUEVSQ0FTRTogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkXyMjTE9XRVJDQVNFIyNfdmFsdWUtPnNpemUoKTsgaSsrKSB7ICBcCisgICAgICAgICAgICB0YXJnZXQgPSBXaXJlRm9ybWF0TGl0ZTo6V3JpdGUjI0NBTUVMQ0FTRSMjVG9BcnJheShudW1iZXIsICAgICAgXAorICAgICAgICAgICAgICByZXBlYXRlZF8jI0xPV0VSQ0FTRSMjX3ZhbHVlLT5HZXQoaSksIHRhcmdldCk7ICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgYnJlYWsKKworICAgICAgICBIQU5ETEVfVFlQRSggICBJTlQzMiwgICAgSW50MzIsICAgaW50MzIpOworICAgICAgICBIQU5ETEVfVFlQRSggICBJTlQ2NCwgICAgSW50NjQsICAgaW50NjQpOworICAgICAgICBIQU5ETEVfVFlQRSggIFVJTlQzMiwgICBVSW50MzIsICB1aW50MzIpOworICAgICAgICBIQU5ETEVfVFlQRSggIFVJTlQ2NCwgICBVSW50NjQsICB1aW50NjQpOworICAgICAgICBIQU5ETEVfVFlQRSggIFNJTlQzMiwgICBTSW50MzIsICAgaW50MzIpOworICAgICAgICBIQU5ETEVfVFlQRSggIFNJTlQ2NCwgICBTSW50NjQsICAgaW50NjQpOworICAgICAgICBIQU5ETEVfVFlQRSggRklYRUQzMiwgIEZpeGVkMzIsICB1aW50MzIpOworICAgICAgICBIQU5ETEVfVFlQRSggRklYRUQ2NCwgIEZpeGVkNjQsICB1aW50NjQpOworICAgICAgICBIQU5ETEVfVFlQRShTRklYRUQzMiwgU0ZpeGVkMzIsICAgaW50MzIpOworICAgICAgICBIQU5ETEVfVFlQRShTRklYRUQ2NCwgU0ZpeGVkNjQsICAgaW50NjQpOworICAgICAgICBIQU5ETEVfVFlQRSggICBGTE9BVCwgICAgRmxvYXQsICAgZmxvYXQpOworICAgICAgICBIQU5ETEVfVFlQRSggIERPVUJMRSwgICBEb3VibGUsICBkb3VibGUpOworICAgICAgICBIQU5ETEVfVFlQRSggICAgQk9PTCwgICAgIEJvb2wsICAgIGJvb2wpOworICAgICAgICBIQU5ETEVfVFlQRSggIFNUUklORywgICBTdHJpbmcsICBzdHJpbmcpOworICAgICAgICBIQU5ETEVfVFlQRSggICBCWVRFUywgICAgQnl0ZXMsICBzdHJpbmcpOworICAgICAgICBIQU5ETEVfVFlQRSggICAgRU5VTSwgICAgIEVudW0sICAgIGVudW0pOworICAgICAgICBIQU5ETEVfVFlQRSggICBHUk9VUCwgICAgR3JvdXAsIG1lc3NhZ2UpOworICAgICAgICBIQU5ETEVfVFlQRSggTUVTU0FHRSwgIE1lc3NhZ2UsIG1lc3NhZ2UpOworI3VuZGVmIEhBTkRMRV9UWVBFCisgICAgICB9CisgICAgfQorICB9IGVsc2UgaWYgKCFpc19jbGVhcmVkKSB7CisgICAgc3dpdGNoIChyZWFsX3R5cGUodHlwZSkpIHsKKyNkZWZpbmUgSEFORExFX1RZUEUoVVBQRVJDQVNFLCBDQU1FTENBU0UsIFZBTFVFKSAgICAgICAgICAgICAgICAgXAorICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfIyNVUFBFUkNBU0U6ICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIHRhcmdldCA9IFdpcmVGb3JtYXRMaXRlOjpXcml0ZSMjQ0FNRUxDQVNFIyNUb0FycmF5KCAgICAgIFwKKyAgICAgICAgICAgIG51bWJlciwgVkFMVUUsIHRhcmdldCk7IFwKKyAgICAgICAgYnJlYWsKKworICAgICAgSEFORExFX1RZUEUoICAgSU5UMzIsICAgIEludDMyLCAgICBpbnQzMl92YWx1ZSk7CisgICAgICBIQU5ETEVfVFlQRSggICBJTlQ2NCwgICAgSW50NjQsICAgIGludDY0X3ZhbHVlKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgVUlOVDMyLCAgIFVJbnQzMiwgICB1aW50MzJfdmFsdWUpOworICAgICAgSEFORExFX1RZUEUoICBVSU5UNjQsICAgVUludDY0LCAgIHVpbnQ2NF92YWx1ZSk7CisgICAgICBIQU5ETEVfVFlQRSggIFNJTlQzMiwgICBTSW50MzIsICAgIGludDMyX3ZhbHVlKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgU0lOVDY0LCAgIFNJbnQ2NCwgICAgaW50NjRfdmFsdWUpOworICAgICAgSEFORExFX1RZUEUoIEZJWEVEMzIsICBGaXhlZDMyLCAgIHVpbnQzMl92YWx1ZSk7CisgICAgICBIQU5ETEVfVFlQRSggRklYRUQ2NCwgIEZpeGVkNjQsICAgdWludDY0X3ZhbHVlKTsKKyAgICAgIEhBTkRMRV9UWVBFKFNGSVhFRDMyLCBTRml4ZWQzMiwgICAgaW50MzJfdmFsdWUpOworICAgICAgSEFORExFX1RZUEUoU0ZJWEVENjQsIFNGaXhlZDY0LCAgICBpbnQ2NF92YWx1ZSk7CisgICAgICBIQU5ETEVfVFlQRSggICBGTE9BVCwgICAgRmxvYXQsICAgIGZsb2F0X3ZhbHVlKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgRE9VQkxFLCAgIERvdWJsZSwgICBkb3VibGVfdmFsdWUpOworICAgICAgSEFORExFX1RZUEUoICAgIEJPT0wsICAgICBCb29sLCAgICAgYm9vbF92YWx1ZSk7CisgICAgICBIQU5ETEVfVFlQRSggIFNUUklORywgICBTdHJpbmcsICAqc3RyaW5nX3ZhbHVlKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgIEJZVEVTLCAgICBCeXRlcywgICpzdHJpbmdfdmFsdWUpOworICAgICAgSEFORExFX1RZUEUoICAgIEVOVU0sICAgICBFbnVtLCAgICAgZW51bV92YWx1ZSk7CisgICAgICBIQU5ETEVfVFlQRSggICBHUk9VUCwgICAgR3JvdXAsICptZXNzYWdlX3ZhbHVlKTsKKyN1bmRlZiBIQU5ETEVfVFlQRQorICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfTUVTU0FHRToKKyAgICAgICAgaWYgKGlzX2xhenkpIHsKKyAgICAgICAgICB0YXJnZXQgPSBsYXp5bWVzc2FnZV92YWx1ZS0+V3JpdGVNZXNzYWdlVG9BcnJheShudW1iZXIsIHRhcmdldCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgdGFyZ2V0ID0gV2lyZUZvcm1hdExpdGU6OldyaXRlTWVzc2FnZVRvQXJyYXkoCisgICAgICAgICAgICAgIG51bWJlciwgKm1lc3NhZ2VfdmFsdWUsIHRhcmdldCk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgfQorICB9CisgIHJldHVybiB0YXJnZXQ7Cit9CisKK3VpbnQ4KiBFeHRlbnNpb25TZXQ6OkV4dGVuc2lvbjo6U2VyaWFsaXplTWVzc2FnZVNldEl0ZW1XaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KAorICAgIGludCBudW1iZXIsCisgICAgdWludDgqIHRhcmdldCkgY29uc3QgeworICBpZiAodHlwZSAhPSBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9NRVNTQUdFIHx8IGlzX3JlcGVhdGVkKSB7CisgICAgLy8gTm90IGEgdmFsaWQgTWVzc2FnZVNldCBleHRlbnNpb24sIGJ1dCBzZXJpYWxpemUgaXQgdGhlIG5vcm1hbCB3YXkuCisgICAgR09PR0xFX0xPRyhXQVJOSU5HKSA8PCAiSW52YWxpZCBtZXNzYWdlIHNldCBleHRlbnNpb24uIjsKKyAgICByZXR1cm4gU2VyaWFsaXplRmllbGRXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KG51bWJlciwgdGFyZ2V0KTsKKyAgfQorCisgIGlmIChpc19jbGVhcmVkKSByZXR1cm4gdGFyZ2V0OworCisgIC8vIFN0YXJ0IGdyb3VwLgorICB0YXJnZXQgPSBpbzo6Q29kZWRPdXRwdXRTdHJlYW06OldyaXRlVGFnVG9BcnJheSgKKyAgICAgIFdpcmVGb3JtYXRMaXRlOjprTWVzc2FnZVNldEl0ZW1TdGFydFRhZywgdGFyZ2V0KTsKKyAgLy8gV3JpdGUgdHlwZSBJRC4KKyAgdGFyZ2V0ID0gV2lyZUZvcm1hdExpdGU6OldyaXRlVUludDMyVG9BcnJheSgKKyAgICAgIFdpcmVGb3JtYXRMaXRlOjprTWVzc2FnZVNldFR5cGVJZE51bWJlciwgbnVtYmVyLCB0YXJnZXQpOworICAvLyBXcml0ZSBtZXNzYWdlLgorICBpZiAoaXNfbGF6eSkgeworICAgIHRhcmdldCA9IGxhenltZXNzYWdlX3ZhbHVlLT5Xcml0ZU1lc3NhZ2VUb0FycmF5KAorICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6a01lc3NhZ2VTZXRNZXNzYWdlTnVtYmVyLCB0YXJnZXQpOworICB9IGVsc2UgeworICAgIHRhcmdldCA9IFdpcmVGb3JtYXRMaXRlOjpXcml0ZU1lc3NhZ2VUb0FycmF5KAorICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6a01lc3NhZ2VTZXRNZXNzYWdlTnVtYmVyLCAqbWVzc2FnZV92YWx1ZSwgdGFyZ2V0KTsKKyAgfQorICAvLyBFbmQgZ3JvdXAuCisgIHRhcmdldCA9IGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVUYWdUb0FycmF5KAorICAgICAgV2lyZUZvcm1hdExpdGU6OmtNZXNzYWdlU2V0SXRlbUVuZFRhZywgdGFyZ2V0KTsKKyAgcmV0dXJuIHRhcmdldDsKK30KKworCitib29sIEV4dGVuc2lvblNldDo6UGFyc2VGaWVsZE1heWJlTGF6aWx5KAorICAgIGludCB3aXJlX3R5cGUsIGludCBmaWVsZF9udW1iZXIsIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICBFeHRlbnNpb25GaW5kZXIqIGV4dGVuc2lvbl9maW5kZXIsCisgICAgTWVzc2FnZVNldEZpZWxkU2tpcHBlciogZmllbGRfc2tpcHBlcikgeworICByZXR1cm4gUGFyc2VGaWVsZChXaXJlRm9ybWF0TGl0ZTo6TWFrZVRhZygKKyAgICAgIGZpZWxkX251bWJlciwgc3RhdGljX2Nhc3Q8V2lyZUZvcm1hdExpdGU6OldpcmVUeXBlPih3aXJlX3R5cGUpKSwKKyAgICAgICAgICAgICAgICAgICAgaW5wdXQsIGV4dGVuc2lvbl9maW5kZXIsIGZpZWxkX3NraXBwZXIpOworfQorCitib29sIEV4dGVuc2lvblNldDo6UGFyc2VNZXNzYWdlU2V0KGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXh0ZW5zaW9uRmluZGVyKiBleHRlbnNpb25fZmluZGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlU2V0RmllbGRTa2lwcGVyKiBmaWVsZF9za2lwcGVyKSB7CisgIHdoaWxlICh0cnVlKSB7CisgICAgY29uc3QgdWludDMyIHRhZyA9IGlucHV0LT5SZWFkVGFnKCk7CisgICAgc3dpdGNoICh0YWcpIHsKKyAgICAgIGNhc2UgMDoKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjprTWVzc2FnZVNldEl0ZW1TdGFydFRhZzoKKyAgICAgICAgaWYgKCFQYXJzZU1lc3NhZ2VTZXRJdGVtKGlucHV0LCBleHRlbnNpb25fZmluZGVyLCBmaWVsZF9za2lwcGVyKSkgeworICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIGlmICghUGFyc2VGaWVsZCh0YWcsIGlucHV0LCBleHRlbnNpb25fZmluZGVyLCBmaWVsZF9za2lwcGVyKSkgeworICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICB9CisgIH0KK30KKworYm9vbCBFeHRlbnNpb25TZXQ6OlBhcnNlTWVzc2FnZVNldChpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2VMaXRlKiBjb250YWluaW5nX3R5cGUpIHsKKyAgTWVzc2FnZVNldEZpZWxkU2tpcHBlciBza2lwcGVyKE5VTEwpOworICBHZW5lcmF0ZWRFeHRlbnNpb25GaW5kZXIgZmluZGVyKGNvbnRhaW5pbmdfdHlwZSk7CisgIHJldHVybiBQYXJzZU1lc3NhZ2VTZXQoaW5wdXQsICZmaW5kZXIsICZza2lwcGVyKTsKK30KKworYm9vbCBFeHRlbnNpb25TZXQ6OlBhcnNlTWVzc2FnZVNldEl0ZW0oaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXh0ZW5zaW9uRmluZGVyKiBleHRlbnNpb25fZmluZGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZVNldEZpZWxkU2tpcHBlciogZmllbGRfc2tpcHBlcikgeworICAvLyBUT0RPKGtlbnRvbik6ICBJdCB3b3VsZCBiZSBuaWNlIHRvIHNoYXJlIGNvZGUgYmV0d2VlbiB0aGlzIGFuZAorICAvLyBXaXJlRm9ybWF0TGl0ZTo6UGFyc2VBbmRNZXJnZU1lc3NhZ2VTZXRJdGVtKCksIGJ1dCBJIHRoaW5rIHRoZQorICAvLyBkaWZmZXJlbmNlcyB3b3VsZCBiZSBoYXJkIHRvIGZhY3RvciBvdXQuCisKKyAgLy8gVGhpcyBtZXRob2QgcGFyc2VzIGEgZ3JvdXAgd2hpY2ggc2hvdWxkIGNvbnRhaW4gdHdvIGZpZWxkczoKKyAgLy8gICByZXF1aXJlZCBpbnQzMiB0eXBlX2lkID0gMjsKKyAgLy8gICByZXF1aXJlZCBkYXRhIG1lc3NhZ2UgPSAzOworCisgIHVpbnQzMiBsYXN0X3R5cGVfaWQgPSAwOworCisgIC8vIElmIHdlIHNlZSBtZXNzYWdlIGRhdGEgYmVmb3JlIHRoZSB0eXBlX2lkLCB3ZSdsbCBhcHBlbmQgaXQgdG8gdGhpcyBzbworICAvLyB3ZSBjYW4gcGFyc2UgaXQgbGF0ZXIuCisgIHN0cmluZyBtZXNzYWdlX2RhdGE7CisKKyAgd2hpbGUgKHRydWUpIHsKKyAgICBjb25zdCB1aW50MzIgdGFnID0gaW5wdXQtPlJlYWRUYWcoKTsKKyAgICBpZiAodGFnID09IDApIHJldHVybiBmYWxzZTsKKworICAgIHN3aXRjaCAodGFnKSB7CisgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjprTWVzc2FnZVNldFR5cGVJZFRhZzogeworICAgICAgICB1aW50MzIgdHlwZV9pZDsKKyAgICAgICAgaWYgKCFpbnB1dC0+UmVhZFZhcmludDMyKCZ0eXBlX2lkKSkgcmV0dXJuIGZhbHNlOworICAgICAgICBsYXN0X3R5cGVfaWQgPSB0eXBlX2lkOworCisgICAgICAgIGlmICghbWVzc2FnZV9kYXRhLmVtcHR5KCkpIHsKKyAgICAgICAgICAvLyBXZSBzYXcgc29tZSBtZXNzYWdlIGRhdGEgYmVmb3JlIHRoZSB0eXBlX2lkLiAgSGF2ZSB0byBwYXJzZSBpdAorICAgICAgICAgIC8vIG5vdy4KKyAgICAgICAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSBzdWJfaW5wdXQoCisgICAgICAgICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgdWludDgqPihtZXNzYWdlX2RhdGEuZGF0YSgpKSwKKyAgICAgICAgICAgICAgbWVzc2FnZV9kYXRhLnNpemUoKSk7CisgICAgICAgICAgaWYgKCFQYXJzZUZpZWxkTWF5YmVMYXppbHkoV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFzdF90eXBlX2lkLCAmc3ViX2lucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbl9maW5kZXIsIGZpZWxkX3NraXBwZXIpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgfQorICAgICAgICAgIG1lc3NhZ2VfZGF0YS5jbGVhcigpOworICAgICAgICB9CisKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OmtNZXNzYWdlU2V0TWVzc2FnZVRhZzogeworICAgICAgICBpZiAobGFzdF90eXBlX2lkID09IDApIHsKKyAgICAgICAgICAvLyBXZSBoYXZlbid0IHNlZW4gYSB0eXBlX2lkIHlldC4gIEFwcGVuZCB0aGlzIGRhdGEgdG8gbWVzc2FnZV9kYXRhLgorICAgICAgICAgIHN0cmluZyB0ZW1wOworICAgICAgICAgIHVpbnQzMiBsZW5ndGg7CisgICAgICAgICAgaWYgKCFpbnB1dC0+UmVhZFZhcmludDMyKCZsZW5ndGgpKSByZXR1cm4gZmFsc2U7CisgICAgICAgICAgaWYgKCFpbnB1dC0+UmVhZFN0cmluZygmdGVtcCwgbGVuZ3RoKSkgcmV0dXJuIGZhbHNlOworICAgICAgICAgIGlvOjpTdHJpbmdPdXRwdXRTdHJlYW0gb3V0cHV0X3N0cmVhbSgmbWVzc2FnZV9kYXRhKTsKKyAgICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0gY29kZWRfb3V0cHV0KCZvdXRwdXRfc3RyZWFtKTsKKyAgICAgICAgICBjb2RlZF9vdXRwdXQuV3JpdGVWYXJpbnQzMihsZW5ndGgpOworICAgICAgICAgIGNvZGVkX291dHB1dC5Xcml0ZVN0cmluZyh0ZW1wKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAvLyBBbHJlYWR5IHNhdyB0eXBlX2lkLCBzbyB3ZSBjYW4gcGFyc2UgdGhpcyBkaXJlY3RseS4KKyAgICAgICAgICBpZiAoIVBhcnNlRmllbGRNYXliZUxhemlseShXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXN0X3R5cGVfaWQsIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbl9maW5kZXIsIGZpZWxkX3NraXBwZXIpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OmtNZXNzYWdlU2V0SXRlbUVuZFRhZzogeworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0KKworICAgICAgZGVmYXVsdDogeworICAgICAgICBpZiAoIWZpZWxkX3NraXBwZXItPlNraXBGaWVsZChpbnB1dCwgdGFnKSkgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgIH0KKyAgfQorfQorCit2b2lkIEV4dGVuc2lvblNldDo6RXh0ZW5zaW9uOjpTZXJpYWxpemVNZXNzYWdlU2V0SXRlbVdpdGhDYWNoZWRTaXplcygKKyAgICBpbnQgbnVtYmVyLAorICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIGlmICh0eXBlICE9IFdpcmVGb3JtYXRMaXRlOjpUWVBFX01FU1NBR0UgfHwgaXNfcmVwZWF0ZWQpIHsKKyAgICAvLyBOb3QgYSB2YWxpZCBNZXNzYWdlU2V0IGV4dGVuc2lvbiwgYnV0IHNlcmlhbGl6ZSBpdCB0aGUgbm9ybWFsIHdheS4KKyAgICBTZXJpYWxpemVGaWVsZFdpdGhDYWNoZWRTaXplcyhudW1iZXIsIG91dHB1dCk7CisgICAgcmV0dXJuOworICB9CisKKyAgaWYgKGlzX2NsZWFyZWQpIHJldHVybjsKKworICAvLyBTdGFydCBncm91cC4KKyAgb3V0cHV0LT5Xcml0ZVRhZyhXaXJlRm9ybWF0TGl0ZTo6a01lc3NhZ2VTZXRJdGVtU3RhcnRUYWcpOworCisgIC8vIFdyaXRlIHR5cGUgSUQuCisgIFdpcmVGb3JtYXRMaXRlOjpXcml0ZVVJbnQzMihXaXJlRm9ybWF0TGl0ZTo6a01lc3NhZ2VTZXRUeXBlSWROdW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXQpOworICAvLyBXcml0ZSBtZXNzYWdlLgorICBpZiAoaXNfbGF6eSkgeworICAgIGxhenltZXNzYWdlX3ZhbHVlLT5Xcml0ZU1lc3NhZ2UoCisgICAgICAgIFdpcmVGb3JtYXRMaXRlOjprTWVzc2FnZVNldE1lc3NhZ2VOdW1iZXIsIG91dHB1dCk7CisgIH0gZWxzZSB7CisgICAgV2lyZUZvcm1hdExpdGU6OldyaXRlTWVzc2FnZU1heWJlVG9BcnJheSgKKyAgICAgICAgV2lyZUZvcm1hdExpdGU6OmtNZXNzYWdlU2V0TWVzc2FnZU51bWJlciwKKyAgICAgICAgKm1lc3NhZ2VfdmFsdWUsCisgICAgICAgIG91dHB1dCk7CisgIH0KKworICAvLyBFbmQgZ3JvdXAuCisgIG91dHB1dC0+V3JpdGVUYWcoV2lyZUZvcm1hdExpdGU6OmtNZXNzYWdlU2V0SXRlbUVuZFRhZyk7Cit9CisKK2ludCBFeHRlbnNpb25TZXQ6OkV4dGVuc2lvbjo6TWVzc2FnZVNldEl0ZW1CeXRlU2l6ZShpbnQgbnVtYmVyKSBjb25zdCB7CisgIGlmICh0eXBlICE9IFdpcmVGb3JtYXRMaXRlOjpUWVBFX01FU1NBR0UgfHwgaXNfcmVwZWF0ZWQpIHsKKyAgICAvLyBOb3QgYSB2YWxpZCBNZXNzYWdlU2V0IGV4dGVuc2lvbiwgYnV0IGNvbXB1dGUgdGhlIGJ5dGUgc2l6ZSBmb3IgaXQgdGhlCisgICAgLy8gbm9ybWFsIHdheS4KKyAgICByZXR1cm4gQnl0ZVNpemUobnVtYmVyKTsKKyAgfQorCisgIGlmIChpc19jbGVhcmVkKSByZXR1cm4gMDsKKworICBpbnQgb3VyX3NpemUgPSBXaXJlRm9ybWF0TGl0ZTo6a01lc3NhZ2VTZXRJdGVtVGFnc1NpemU7CisKKyAgLy8gdHlwZV9pZAorICBvdXJfc2l6ZSArPSBpbzo6Q29kZWRPdXRwdXRTdHJlYW06OlZhcmludFNpemUzMihudW1iZXIpOworCisgIC8vIG1lc3NhZ2UKKyAgaW50IG1lc3NhZ2Vfc2l6ZSA9IDA7CisgIGlmIChpc19sYXp5KSB7CisgICAgbWVzc2FnZV9zaXplID0gbGF6eW1lc3NhZ2VfdmFsdWUtPkJ5dGVTaXplKCk7CisgIH0gZWxzZSB7CisgICAgbWVzc2FnZV9zaXplID0gbWVzc2FnZV92YWx1ZS0+Qnl0ZVNpemUoKTsKKyAgfQorCisgIG91cl9zaXplICs9IGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6VmFyaW50U2l6ZTMyKG1lc3NhZ2Vfc2l6ZSk7CisgIG91cl9zaXplICs9IG1lc3NhZ2Vfc2l6ZTsKKworICByZXR1cm4gb3VyX3NpemU7Cit9CisKK3ZvaWQgRXh0ZW5zaW9uU2V0OjpTZXJpYWxpemVNZXNzYWdlU2V0V2l0aENhY2hlZFNpemVzKAorICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIGZvciAobWFwPGludCwgRXh0ZW5zaW9uPjo6Y29uc3RfaXRlcmF0b3IgaXRlciA9IGV4dGVuc2lvbnNfLmJlZ2luKCk7CisgICAgICAgaXRlciAhPSBleHRlbnNpb25zXy5lbmQoKTsgKytpdGVyKSB7CisgICAgaXRlci0+c2Vjb25kLlNlcmlhbGl6ZU1lc3NhZ2VTZXRJdGVtV2l0aENhY2hlZFNpemVzKGl0ZXItPmZpcnN0LCBvdXRwdXQpOworICB9Cit9CisKK2ludCBFeHRlbnNpb25TZXQ6Ok1lc3NhZ2VTZXRCeXRlU2l6ZSgpIGNvbnN0IHsKKyAgaW50IHRvdGFsX3NpemUgPSAwOworCisgIGZvciAobWFwPGludCwgRXh0ZW5zaW9uPjo6Y29uc3RfaXRlcmF0b3IgaXRlciA9IGV4dGVuc2lvbnNfLmJlZ2luKCk7CisgICAgICAgaXRlciAhPSBleHRlbnNpb25zXy5lbmQoKTsgKytpdGVyKSB7CisgICAgdG90YWxfc2l6ZSArPSBpdGVyLT5zZWNvbmQuTWVzc2FnZVNldEl0ZW1CeXRlU2l6ZShpdGVyLT5maXJzdCk7CisgIH0KKworICByZXR1cm4gdG90YWxfc2l6ZTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvZXh0ZW5zaW9uX3NldF91bml0dGVzdC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvZXh0ZW5zaW9uX3NldF91bml0dGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNDBmY2JjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9leHRlbnNpb25fc2V0X3VuaXR0ZXN0LmNjCkBAIC0wLDAgKzEsMTIwNyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2V4dGVuc2lvbl9zZXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfbXNldC5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXN0X3V0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9hcmVuYS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2R5bmFtaWNfbWVzc2FnZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbV9pbXBsLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbG9nZ2luZy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2dvb2dsZXRlc3QuaD4KKyNpbmNsdWRlIDxndGVzdC9ndGVzdC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdGxfdXRpbC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKKworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7CituYW1lc3BhY2UgeworCisvLyBUaGlzIHRlc3QgY2xvc2VseSBtaXJyb3JzIGdvb2dsZS9wcm90b2J1Zi9jb21waWxlci9jcHAvdW5pdHRlc3QuY2MKKy8vIGV4Y2VwdCB0aGF0IGl0IHVzZXMgZXh0ZW5zaW9ucyByYXRoZXIgdGhhbiByZWd1bGFyIGZpZWxkcy4KKworVEVTVChFeHRlbnNpb25TZXRUZXN0LCBEZWZhdWx0cykgeworICAvLyBDaGVjayB0aGF0IGFsbCBkZWZhdWx0IHZhbHVlcyBhcmUgc2V0IGNvcnJlY3RseSBpbiB0aGUgaW5pdGlhbCBtZXNzYWdlLgorICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTsKKworICBUZXN0VXRpbDo6RXhwZWN0RXh0ZW5zaW9uc0NsZWFyKG1lc3NhZ2UpOworCisgIC8vIE1lc3NhZ2VzIHNob3VsZCByZXR1cm4gcG9pbnRlcnMgdG8gZGVmYXVsdCBpbnN0YW5jZXMgdW50aWwgZmlyc3QgdXNlLgorICAvLyAoVGhpcyBpcyBub3QgY2hlY2tlZCBieSBFeHBlY3RDbGVhcigpIHNpbmNlIGl0IGlzIG5vdCBhY3R1YWxseSB0cnVlIGFmdGVyCisgIC8vIHRoZSBmaWVsZHMgaGF2ZSBiZWVuIHNldCBhbmQgdGhlbiBjbGVhcmVkLikKKyAgRVhQRUNUX0VRKCZ1bml0dGVzdDo6T3B0aW9uYWxHcm91cF9leHRlbnNpb246OmRlZmF1bHRfaW5zdGFuY2UoKSwKKyAgICAgICAgICAgICZtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxncm91cF9leHRlbnNpb24pKTsKKyAgRVhQRUNUX0VRKCZ1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlOjpkZWZhdWx0X2luc3RhbmNlKCksCisgICAgICAgICAgICAmbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbikpOworICBFWFBFQ1RfRVEoJnVuaXR0ZXN0OjpGb3JlaWduTWVzc2FnZTo6ZGVmYXVsdF9pbnN0YW5jZSgpLAorICAgICAgICAgICAgJm1lc3NhZ2UuR2V0RXh0ZW5zaW9uKAorICAgICAgICAgICAgICB1bml0dGVzdDo6b3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbikpOworICBFWFBFQ1RfRVEoJnVuaXR0ZXN0X2ltcG9ydDo6SW1wb3J0TWVzc2FnZTo6ZGVmYXVsdF9pbnN0YW5jZSgpLAorICAgICAgICAgICAgJm1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb24pKTsKK30KKworVEVTVChFeHRlbnNpb25TZXRUZXN0LCBBY2Nlc3NvcnMpIHsKKyAgLy8gU2V0IGV2ZXJ5IGZpZWxkIHRvIGEgdW5pcXVlIHZhbHVlIHRoZW4gZ28gYmFjayBhbmQgY2hlY2sgYWxsIHRob3NlCisgIC8vIHZhbHVlcy4KKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2U7CisKKyAgVGVzdFV0aWw6OlNldEFsbEV4dGVuc2lvbnMoJm1lc3NhZ2UpOworICBUZXN0VXRpbDo6RXhwZWN0QWxsRXh0ZW5zaW9uc1NldChtZXNzYWdlKTsKKworICBUZXN0VXRpbDo6TW9kaWZ5UmVwZWF0ZWRFeHRlbnNpb25zKCZtZXNzYWdlKTsKKyAgVGVzdFV0aWw6OkV4cGVjdFJlcGVhdGVkRXh0ZW5zaW9uc01vZGlmaWVkKG1lc3NhZ2UpOworfQorCitURVNUKEV4dGVuc2lvblNldFRlc3QsIENsZWFyKSB7CisgIC8vIFNldCBldmVyeSBmaWVsZCB0byBhIHVuaXF1ZSB2YWx1ZSwgY2xlYXIgdGhlIG1lc3NhZ2UsIHRoZW4gY2hlY2sgdGhhdAorICAvLyBpdCBpcyBjbGVhcmVkLgorICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTsKKworICBUZXN0VXRpbDo6U2V0QWxsRXh0ZW5zaW9ucygmbWVzc2FnZSk7CisgIG1lc3NhZ2UuQ2xlYXIoKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEV4dGVuc2lvbnNDbGVhcihtZXNzYWdlKTsKKworICAvLyBVbmxpa2Ugd2l0aCB0aGUgZGVmYXVsdHMgdGVzdCwgd2UgZG8gTk9UIGV4cGVjdCB0aGF0IHJlcXVlc3RpbmcgZW1iZWRkZWQKKyAgLy8gbWVzc2FnZXMgd2lsbCByZXR1cm4gYSBwb2ludGVyIHRvIHRoZSBkZWZhdWx0IGluc3RhbmNlLiAgSW5zdGVhZCwgdGhleQorICAvLyBzaG91bGQgcmV0dXJuIHRoZSBvYmplY3RzIHRoYXQgd2VyZSBjcmVhdGVkIHdoZW4gbXV0YWJsZV9ibGFoKCkgd2FzCisgIC8vIGNhbGxlZC4KKyAgRVhQRUNUX05FKCZ1bml0dGVzdDo6T3B0aW9uYWxHcm91cF9leHRlbnNpb246OmRlZmF1bHRfaW5zdGFuY2UoKSwKKyAgICAgICAgICAgICZtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxncm91cF9leHRlbnNpb24pKTsKKyAgRVhQRUNUX05FKCZ1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlOjpkZWZhdWx0X2luc3RhbmNlKCksCisgICAgICAgICAgICAmbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbikpOworICBFWFBFQ1RfTkUoJnVuaXR0ZXN0OjpGb3JlaWduTWVzc2FnZTo6ZGVmYXVsdF9pbnN0YW5jZSgpLAorICAgICAgICAgICAgJm1lc3NhZ2UuR2V0RXh0ZW5zaW9uKAorICAgICAgICAgICAgICB1bml0dGVzdDo6b3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbikpOworICBFWFBFQ1RfTkUoJnVuaXR0ZXN0X2ltcG9ydDo6SW1wb3J0TWVzc2FnZTo6ZGVmYXVsdF9pbnN0YW5jZSgpLAorICAgICAgICAgICAgJm1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb24pKTsKKworICAvLyBNYWtlIHN1cmUgc2V0dGluZyBzdHVmZiBhZ2FpbiBhZnRlciBjbGVhcmluZyB3b3Jrcy4gIChUaGlzIHRha2VzIHNsaWdodGx5CisgIC8vIGRpZmZlcmVudCBjb2RlIHBhdGhzIHNpbmNlIHRoZSBvYmplY3RzIGFyZSByZXVzZWQuKQorICBUZXN0VXRpbDo6U2V0QWxsRXh0ZW5zaW9ucygmbWVzc2FnZSk7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxFeHRlbnNpb25zU2V0KG1lc3NhZ2UpOworfQorCitURVNUKEV4dGVuc2lvblNldFRlc3QsIENsZWFyT25lRmllbGQpIHsKKyAgLy8gU2V0IGV2ZXJ5IGZpZWxkIHRvIGEgdW5pcXVlIHZhbHVlLCB0aGVuIGNsZWFyIG9uZSB2YWx1ZSBhbmQgaW5zdXJlIHRoYXQKKyAgLy8gb25seSB0aGF0IG9uZSB2YWx1ZSBpcyBjbGVhcmVkLgorICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTsKKworICBUZXN0VXRpbDo6U2V0QWxsRXh0ZW5zaW9ucygmbWVzc2FnZSk7CisgIGludDY0IG9yaWdpbmFsX3ZhbHVlID0KKyAgICBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW50NjRfZXh0ZW5zaW9uKTsKKworICAvLyBDbGVhciB0aGUgZmllbGQgYW5kIG1ha2Ugc3VyZSBpdCBzaG93cyB1cCBhcyBjbGVhcmVkLgorICBtZXNzYWdlLkNsZWFyRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbnQ2NF9leHRlbnNpb24pOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ludDY0X2V4dGVuc2lvbikpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ludDY0X2V4dGVuc2lvbikpOworCisgIC8vIE90aGVyIGFkamFjZW50IGZpZWxkcyBzaG91bGQgbm90IGJlIGNsZWFyZWQuCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbnQzMl9leHRlbnNpb24pKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3VpbnQzMl9leHRlbnNpb24pKTsKKworICAvLyBNYWtlIHN1cmUgaWYgd2Ugc2V0IGl0IGFnYWluLCB0aGVuIGFsbCBmaWVsZHMgYXJlIHNldC4KKyAgbWVzc2FnZS5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ludDY0X2V4dGVuc2lvbiwgb3JpZ2luYWxfdmFsdWUpOworICBUZXN0VXRpbDo6RXhwZWN0QWxsRXh0ZW5zaW9uc1NldChtZXNzYWdlKTsKK30KKworVEVTVChFeHRlbnNpb25TZXRUZXN0LCBTZXRBbGxvY2F0ZWRFeHRlbnNpb24pIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2U7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbigKKyAgICAgIHVuaXR0ZXN0OjpvcHRpb25hbF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uKSk7CisgIC8vIEFkZCBhIGV4dGVuc2lvbiB1c2luZyBTZXRBbGxvY2F0ZWRFeHRlbnNpb24KKyAgdW5pdHRlc3Q6OkZvcmVpZ25NZXNzYWdlKiBmb3JlaWduX21lc3NhZ2UgPSBuZXcgdW5pdHRlc3Q6OkZvcmVpZ25NZXNzYWdlKCk7CisgIG1lc3NhZ2UuU2V0QWxsb2NhdGVkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JlaWduX21lc3NhZ2UpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbigKKyAgICAgIHVuaXR0ZXN0OjpvcHRpb25hbF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9FUShmb3JlaWduX21lc3NhZ2UsCisgICAgICAgICAgICBtZXNzYWdlLk11dGFibGVFeHRlbnNpb24oCisgICAgICAgICAgICAgICAgdW5pdHRlc3Q6Om9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb24pKTsKKyAgRVhQRUNUX0VRKGZvcmVpZ25fbWVzc2FnZSwKKyAgICAgICAgICAgICZtZXNzYWdlLkdldEV4dGVuc2lvbigKKyAgICAgICAgICAgICAgICB1bml0dGVzdDo6b3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbikpOworCisgIC8vIFNldEFsbG9jYXRlZEV4dGVuc2lvbiBzaG91bGQgZGVsZXRlIHRoZSBwcmV2aW91c2x5IGV4aXN0aW5nIGV4dGVuc2lvbi4KKyAgLy8gKFdlIHJlcGx5IG9uIHVuaXR0ZXN0IHRvIGNoZWNrIG1lbW9yeSBsZWFrcyBmb3IgdGhpcyBjYXNlKQorICBtZXNzYWdlLlNldEFsbG9jYXRlZEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IHVuaXR0ZXN0OjpGb3JlaWduTWVzc2FnZSgpKTsKKworICAvLyBTZXRBbGxvY2F0ZWRFeHRlbnNpb24gd2l0aCBhIE5VTEwgcGFyYW1ldGVyIGlzIGVxdWl2YWxlbnQgdG8gQ2xlYXJFeHRlbmlvbi4KKyAgbWVzc2FnZS5TZXRBbGxvY2F0ZWRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24oCisgICAgICB1bml0dGVzdDo6b3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbikpOworfQorCitURVNUKEV4dGVuc2lvblNldFRlc3QsIFJlbGVhc2VFeHRlbnNpb24pIHsKKyAgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3Q6OlRlc3RNZXNzYWdlU2V0IG1lc3NhZ2U7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbigKKyAgICAgIHVuaXR0ZXN0OjpUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjE6Om1lc3NhZ2Vfc2V0X2V4dGVuc2lvbikpOworICAvLyBBZGQgYSBleHRlbnNpb24gdXNpbmcgU2V0QWxsb2NhdGVkRXh0ZW5zaW9uCisgIHVuaXR0ZXN0OjpUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjEqIGV4dGVuc2lvbiA9CisgICAgICBuZXcgdW5pdHRlc3Q6OlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMSgpOworICBtZXNzYWdlLlNldEFsbG9jYXRlZEV4dGVuc2lvbigKKyAgICAgIHVuaXR0ZXN0OjpUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjE6Om1lc3NhZ2Vfc2V0X2V4dGVuc2lvbiwKKyAgICAgIGV4dGVuc2lvbik7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKAorICAgICAgdW5pdHRlc3Q6OlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMTo6bWVzc2FnZV9zZXRfZXh0ZW5zaW9uKSk7CisgIC8vIFJlbGVhc2UgdGhlIGV4dGVuc2lvbiB1c2luZyBSZWxlYXNlRXh0ZW5zaW9uCisgIHVuaXR0ZXN0OjpUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjEqIHJlbGVhc2VkX2V4dGVuc2lvbiA9CisgICAgICBtZXNzYWdlLlJlbGVhc2VFeHRlbnNpb24oCisgICAgICAgICAgdW5pdHRlc3Q6OlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMTo6bWVzc2FnZV9zZXRfZXh0ZW5zaW9uKTsKKyAgRVhQRUNUX0VRKGV4dGVuc2lvbiwgcmVsZWFzZWRfZXh0ZW5zaW9uKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKAorICAgICAgdW5pdHRlc3Q6OlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMTo6bWVzc2FnZV9zZXRfZXh0ZW5zaW9uKSk7CisgIC8vIFJlbGVhc2VFeHRlbnNpb24gd2lsbCByZXR1cm4gdGhlIHVuZGVybHlpbmcgb2JqZWN0IGV2ZW4gYWZ0ZXIKKyAgLy8gQ2xlYXJFeHRlbnNpb24gaXMgY2FsbGVkLgorICBtZXNzYWdlLlNldEFsbG9jYXRlZEV4dGVuc2lvbigKKyAgICAgIHVuaXR0ZXN0OjpUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjE6Om1lc3NhZ2Vfc2V0X2V4dGVuc2lvbiwKKyAgICAgIGV4dGVuc2lvbik7CisgIG1lc3NhZ2UuQ2xlYXJFeHRlbnNpb24oCisgICAgICB1bml0dGVzdDo6VGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xOjptZXNzYWdlX3NldF9leHRlbnNpb24pOworICByZWxlYXNlZF9leHRlbnNpb24gPSBtZXNzYWdlLlJlbGVhc2VFeHRlbnNpb24oCisgICAgICB1bml0dGVzdDo6VGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xOjptZXNzYWdlX3NldF9leHRlbnNpb24pOworICBFWFBFQ1RfVFJVRShyZWxlYXNlZF9leHRlbnNpb24gIT0gTlVMTCk7CisgIGRlbGV0ZSByZWxlYXNlZF9leHRlbnNpb247Cit9CisKKworVEVTVChFeHRlbnNpb25TZXRUZXN0LCBDb3B5RnJvbSkgeworICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTEsIG1lc3NhZ2UyOworCisgIFRlc3RVdGlsOjpTZXRBbGxFeHRlbnNpb25zKCZtZXNzYWdlMSk7CisgIG1lc3NhZ2UyLkNvcHlGcm9tKG1lc3NhZ2UxKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEV4dGVuc2lvbnNTZXQobWVzc2FnZTIpOworICBtZXNzYWdlMi5Db3B5RnJvbShtZXNzYWdlMSk7ICAvLyBleGVyY2lzZSBjb3B5IHdoZW4gZmllbGRzIGFscmVhZHkgZXhpc3QKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEV4dGVuc2lvbnNTZXQobWVzc2FnZTIpOworfQorCitURVNUKEV4dGVuc2lvU2V0VGVzdCwgQ29weUZyb21QYWNrZWQpIHsKKyAgdW5pdHRlc3Q6OlRlc3RQYWNrZWRFeHRlbnNpb25zIG1lc3NhZ2UxLCBtZXNzYWdlMjsKKworICBUZXN0VXRpbDo6U2V0UGFja2VkRXh0ZW5zaW9ucygmbWVzc2FnZTEpOworICBtZXNzYWdlMi5Db3B5RnJvbShtZXNzYWdlMSk7CisgIFRlc3RVdGlsOjpFeHBlY3RQYWNrZWRFeHRlbnNpb25zU2V0KG1lc3NhZ2UyKTsKKyAgbWVzc2FnZTIuQ29weUZyb20obWVzc2FnZTEpOyAgLy8gZXhlcmNpc2UgY29weSB3aGVuIGZpZWxkcyBhbHJlYWR5IGV4aXN0CisgIFRlc3RVdGlsOjpFeHBlY3RQYWNrZWRFeHRlbnNpb25zU2V0KG1lc3NhZ2UyKTsKK30KKworVEVTVChFeHRlbnNpb25TZXRUZXN0LCBDb3B5RnJvbVVwY2FzdGVkKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyBtZXNzYWdlMSwgbWVzc2FnZTI7CisgIGNvbnN0IE1lc3NhZ2UmIHVwY2FzdGVkX21lc3NhZ2UgPSBtZXNzYWdlMTsKKworICBUZXN0VXRpbDo6U2V0QWxsRXh0ZW5zaW9ucygmbWVzc2FnZTEpOworICBtZXNzYWdlMi5Db3B5RnJvbSh1cGNhc3RlZF9tZXNzYWdlKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEV4dGVuc2lvbnNTZXQobWVzc2FnZTIpOworICAvLyBleGVyY2lzZSBjb3B5IHdoZW4gZmllbGRzIGFscmVhZHkgZXhpc3QKKyAgbWVzc2FnZTIuQ29weUZyb20odXBjYXN0ZWRfbWVzc2FnZSk7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxFeHRlbnNpb25zU2V0KG1lc3NhZ2UyKTsKK30KKworVEVTVChFeHRlbnNpb25TZXRUZXN0LCBTd2FwV2l0aEVtcHR5KSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyBtZXNzYWdlMSwgbWVzc2FnZTI7CisgIFRlc3RVdGlsOjpTZXRBbGxFeHRlbnNpb25zKCZtZXNzYWdlMSk7CisKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEV4dGVuc2lvbnNTZXQobWVzc2FnZTEpOworICBUZXN0VXRpbDo6RXhwZWN0RXh0ZW5zaW9uc0NsZWFyKG1lc3NhZ2UyKTsKKyAgbWVzc2FnZTEuU3dhcCgmbWVzc2FnZTIpOworICBUZXN0VXRpbDo6RXhwZWN0QWxsRXh0ZW5zaW9uc1NldChtZXNzYWdlMik7CisgIFRlc3RVdGlsOjpFeHBlY3RFeHRlbnNpb25zQ2xlYXIobWVzc2FnZTEpOworfQorCitURVNUKEV4dGVuc2lvblNldFRlc3QsIFN3YXBXaXRoU2VsZikgeworICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTsKKyAgVGVzdFV0aWw6OlNldEFsbEV4dGVuc2lvbnMoJm1lc3NhZ2UpOworCisgIFRlc3RVdGlsOjpFeHBlY3RBbGxFeHRlbnNpb25zU2V0KG1lc3NhZ2UpOworICBtZXNzYWdlLlN3YXAoJm1lc3NhZ2UpOworICBUZXN0VXRpbDo6RXhwZWN0QWxsRXh0ZW5zaW9uc1NldChtZXNzYWdlKTsKK30KKworVEVTVChFeHRlbnNpb25TZXRUZXN0LCBTd2FwRXh0ZW5zaW9uKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyBtZXNzYWdlMTsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2UyOworCisgIFRlc3RVdGlsOjpTZXRBbGxFeHRlbnNpb25zKCZtZXNzYWdlMSk7CisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBmaWVsZHM7CisKKyAgLy8gU3dhcCBlbXB0eSBmaWVsZHMuCisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlMS5HZXRSZWZsZWN0aW9uKCk7CisgIHJlZmxlY3Rpb24tPlN3YXBGaWVsZHMoJm1lc3NhZ2UxLCAmbWVzc2FnZTIsIGZpZWxkcyk7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxFeHRlbnNpb25zU2V0KG1lc3NhZ2UxKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEV4dGVuc2lvbnNDbGVhcihtZXNzYWdlMik7CisKKyAgLy8gU3dhcCB0d28gZXh0ZW5zaW9ucy4KKyAgZmllbGRzLnB1c2hfYmFjaygKKyAgICAgIHJlZmxlY3Rpb24tPkZpbmRLbm93bkV4dGVuc2lvbkJ5TnVtYmVyKDEyKSk7CisgIGZpZWxkcy5wdXNoX2JhY2soCisgICAgICByZWZsZWN0aW9uLT5GaW5kS25vd25FeHRlbnNpb25CeU51bWJlcigyNSkpOworICByZWZsZWN0aW9uLT5Td2FwRmllbGRzKCZtZXNzYWdlMSwgJm1lc3NhZ2UyLCBmaWVsZHMpOworCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UxLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW50MzJfZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlMS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2RvdWJsZV9leHRlbnNpb24pKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UxLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfY29yZF9leHRlbnNpb24pKTsKKworICBFWFBFQ1RfRkFMU0UobWVzc2FnZTIuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbnQzMl9leHRlbnNpb24pKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZTIuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9kb3VibGVfZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UyLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfY29yZF9leHRlbnNpb24pKTsKK30KKworVEVTVChFeHRlbnNpb25TZXRUZXN0LCBTd2FwRXh0ZW5zaW9uV2l0aEVtcHR5KSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyBtZXNzYWdlMTsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2UyOworICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTM7CisKKyAgVGVzdFV0aWw6OlNldEFsbEV4dGVuc2lvbnMoJm1lc3NhZ2UzKTsKKworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZTMuR2V0UmVmbGVjdGlvbigpOworICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4gZmllbGRzOworICByZWZsZWN0aW9uLT5MaXN0RmllbGRzKG1lc3NhZ2UzLCAmZmllbGRzKTsKKworICByZWZsZWN0aW9uLT5Td2FwRmllbGRzKCZtZXNzYWdlMSwgJm1lc3NhZ2UyLCBmaWVsZHMpOworCisgIFRlc3RVdGlsOjpFeHBlY3RFeHRlbnNpb25zQ2xlYXIobWVzc2FnZTEpOworICBUZXN0VXRpbDo6RXhwZWN0RXh0ZW5zaW9uc0NsZWFyKG1lc3NhZ2UyKTsKK30KKworVEVTVChFeHRlbnNpb25TZXRUZXN0LCBTd2FwRXh0ZW5zaW9uQm90aEZ1bGwpIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2UxOworICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTI7CisKKyAgVGVzdFV0aWw6OlNldEFsbEV4dGVuc2lvbnMoJm1lc3NhZ2UxKTsKKyAgVGVzdFV0aWw6OlNldEFsbEV4dGVuc2lvbnMoJm1lc3NhZ2UyKTsKKworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZTEuR2V0UmVmbGVjdGlvbigpOworICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4gZmllbGRzOworICByZWZsZWN0aW9uLT5MaXN0RmllbGRzKG1lc3NhZ2UxLCAmZmllbGRzKTsKKworICByZWZsZWN0aW9uLT5Td2FwRmllbGRzKCZtZXNzYWdlMSwgJm1lc3NhZ2UyLCBmaWVsZHMpOworCisgIFRlc3RVdGlsOjpFeHBlY3RBbGxFeHRlbnNpb25zU2V0KG1lc3NhZ2UxKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEV4dGVuc2lvbnNTZXQobWVzc2FnZTIpOworfQorCitURVNUKEV4dGVuc2lvblNldFRlc3QsIEFyZW5hU2V0QWxsRXh0ZW5zaW9uKSB7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEgYXJlbmExOworICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMqIG1lc3NhZ2UxID0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmE6OkNyZWF0ZU1lc3NhZ2U8dW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zPigmYXJlbmExKTsKKyAgVGVzdFV0aWw6OlNldEFsbEV4dGVuc2lvbnMobWVzc2FnZTEpOworICBUZXN0VXRpbDo6RXhwZWN0QWxsRXh0ZW5zaW9uc1NldCgqbWVzc2FnZTEpOworfQorCitURVNUKEV4dGVuc2lvblNldFRlc3QsIEFyZW5hQ29weUNvbnN0cnVjdG9yKSB7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEgYXJlbmExOworICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMqIG1lc3NhZ2UxID0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmE6OkNyZWF0ZU1lc3NhZ2U8dW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zPigmYXJlbmExKTsKKyAgVGVzdFV0aWw6OlNldEFsbEV4dGVuc2lvbnMobWVzc2FnZTEpOworICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTIoKm1lc3NhZ2UxKTsKKyAgYXJlbmExLlJlc2V0KCk7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxFeHRlbnNpb25zU2V0KG1lc3NhZ2UyKTsKK30KKworVEVTVChFeHRlbnNpb25TZXRUZXN0LCBBcmVuYU1lcmdlRnJvbSkgeworICA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hIGFyZW5hMTsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zKiBtZXNzYWdlMSA9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hOjpDcmVhdGVNZXNzYWdlPHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucz4oJmFyZW5hMSk7CisgIFRlc3RVdGlsOjpTZXRBbGxFeHRlbnNpb25zKG1lc3NhZ2UxKTsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2UyOworICBtZXNzYWdlMi5NZXJnZUZyb20oKm1lc3NhZ2UxKTsKKyAgYXJlbmExLlJlc2V0KCk7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxFeHRlbnNpb25zU2V0KG1lc3NhZ2UyKTsKK30KKworVEVTVChFeHRlbnNpb25TZXRUZXN0LCBBcmVuYVNldEFsbG9jYXRlZE1lc3NhZ2VBbmRSZWxlYXNlKSB7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEgYXJlbmE7CisgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyogbWVzc2FnZSA9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hOjpDcmVhdGVNZXNzYWdlPHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucz4oJmFyZW5hKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UtPkhhc0V4dGVuc2lvbigKKyAgICAgIHVuaXR0ZXN0OjpvcHRpb25hbF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uKSk7CisgIC8vIEFkZCBhIGV4dGVuc2lvbiB1c2luZyBTZXRBbGxvY2F0ZWRFeHRlbnNpb24KKyAgdW5pdHRlc3Q6OkZvcmVpZ25NZXNzYWdlKiBmb3JlaWduX21lc3NhZ2UgPSBuZXcgdW5pdHRlc3Q6OkZvcmVpZ25NZXNzYWdlKCk7CisgIG1lc3NhZ2UtPlNldEFsbG9jYXRlZEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcmVpZ25fbWVzc2FnZSk7CisgIC8vIGZvcmVpZ25fbWVzc2FnZSBpcyBub3cgb3duZWQgYnkgdGhlIGFyZW5hLgorICBFWFBFQ1RfRVEoZm9yZWlnbl9tZXNzYWdlLAorICAgICAgICAgICAgbWVzc2FnZS0+TXV0YWJsZUV4dGVuc2lvbigKKyAgICAgICAgICAgICAgICB1bml0dGVzdDo6b3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbikpOworCisgIC8vIFVuZGVybHlpbmcgbWVzc2FnZSBpcyBjb3BpZWQsIGFuZCByZXR1cm5lZC4KKyAgdW5pdHRlc3Q6OkZvcmVpZ25NZXNzYWdlKiByZWxlYXNlZF9tZXNzYWdlID0gbWVzc2FnZS0+UmVsZWFzZUV4dGVuc2lvbigKKyAgICAgIHVuaXR0ZXN0OjpvcHRpb25hbF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uKTsKKyAgZGVsZXRlIHJlbGVhc2VkX21lc3NhZ2U7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLT5IYXNFeHRlbnNpb24oCisgICAgICB1bml0dGVzdDo6b3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbikpOworfQorCitURVNUKEV4dGVuc2lvblNldFRlc3QsIFN3YXBFeHRlbnNpb25Cb3RoRnVsbFdpdGhBcmVuYSkgeworICA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hIGFyZW5hMTsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxnb29nbGU6OnByb3RvYnVmOjpBcmVuYT4gYXJlbmEyKG5ldyA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKCkpOworCisgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyogbWVzc2FnZTEgPQorICAgICAgQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8dW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zPigmYXJlbmExKTsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zKiBtZXNzYWdlMiA9CisgICAgICBBcmVuYTo6Q3JlYXRlTWVzc2FnZTx1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnM+KGFyZW5hMi5nZXQoKSk7CisKKyAgVGVzdFV0aWw6OlNldEFsbEV4dGVuc2lvbnMobWVzc2FnZTEpOworICBUZXN0VXRpbDo6U2V0QWxsRXh0ZW5zaW9ucyhtZXNzYWdlMik7CisgIG1lc3NhZ2UxLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ludDMyX2V4dGVuc2lvbiwgMSk7CisgIG1lc3NhZ2UyLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ludDMyX2V4dGVuc2lvbiwgMik7CisgIG1lc3NhZ2UxLT5Td2FwKG1lc3NhZ2UyKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UxLT5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ludDMyX2V4dGVuc2lvbikpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZTItPkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW50MzJfZXh0ZW5zaW9uKSk7CisgIC8vIFJlLXNldCB0aGUgb3JpZ2luYWwgdmFsdWVzIHNvIEV4cGVjdEFsbEV4dGVuc2lvbnNTZXQgaXMgaGFwcHkuCisgIG1lc3NhZ2UxLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ludDMyX2V4dGVuc2lvbiwgMTAxKTsKKyAgbWVzc2FnZTItPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW50MzJfZXh0ZW5zaW9uLCAxMDEpOworICBUZXN0VXRpbDo6RXhwZWN0QWxsRXh0ZW5zaW9uc1NldCgqbWVzc2FnZTEpOworICBUZXN0VXRpbDo6RXhwZWN0QWxsRXh0ZW5zaW9uc1NldCgqbWVzc2FnZTIpOworICBhcmVuYTIucmVzZXQoTlVMTCk7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxFeHRlbnNpb25zU2V0KCptZXNzYWdlMSk7CisgIC8vIFRlc3QgY29ybmVyIGNhc2VzLCB3aGVuIG9uZSBpcyBlbXB0eSBhbmQgb3RoZXIgaXMgbm90LgorICA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hIGFyZW5hMywgYXJlbmE0OworCisgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyogbWVzc2FnZTMgPQorICAgICAgQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8dW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zPigmYXJlbmEzKTsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zKiBtZXNzYWdlNCA9CisgICAgICBBcmVuYTo6Q3JlYXRlTWVzc2FnZTx1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnM+KCZhcmVuYTQpOworICBUZXN0VXRpbDo6U2V0QWxsRXh0ZW5zaW9ucyhtZXNzYWdlMyk7CisgIG1lc3NhZ2UzLT5Td2FwKG1lc3NhZ2U0KTsKKyAgYXJlbmEzLlJlc2V0KCk7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxFeHRlbnNpb25zU2V0KCptZXNzYWdlNCk7Cit9CisKK1RFU1QoRXh0ZW5zaW9uU2V0VGVzdCwgU3dhcEZpZWxkc09mRXh0ZW5zaW9uQm90aEZ1bGxXaXRoQXJlbmEpIHsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEgYXJlbmExOworICBnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEyID0gbmV3IDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEoKTsKKworICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMqIG1lc3NhZ2UxID0KKyAgICAgIEFyZW5hOjpDcmVhdGVNZXNzYWdlPHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucz4oJmFyZW5hMSk7CisgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyogbWVzc2FnZTIgPQorICAgICAgQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8dW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zPihhcmVuYTIpOworCisgIFRlc3RVdGlsOjpTZXRBbGxFeHRlbnNpb25zKG1lc3NhZ2UxKTsKKyAgVGVzdFV0aWw6OlNldEFsbEV4dGVuc2lvbnMobWVzc2FnZTIpOworCisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlMS0+R2V0UmVmbGVjdGlvbigpOworICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4gZmllbGRzOworICByZWZsZWN0aW9uLT5MaXN0RmllbGRzKCptZXNzYWdlMSwgJmZpZWxkcyk7CisgIHJlZmxlY3Rpb24tPlN3YXBGaWVsZHMobWVzc2FnZTEsIG1lc3NhZ2UyLCBmaWVsZHMpOworICBUZXN0VXRpbDo6RXhwZWN0QWxsRXh0ZW5zaW9uc1NldCgqbWVzc2FnZTEpOworICBUZXN0VXRpbDo6RXhwZWN0QWxsRXh0ZW5zaW9uc1NldCgqbWVzc2FnZTIpOworICBkZWxldGUgYXJlbmEyOworICBUZXN0VXRpbDo6RXhwZWN0QWxsRXh0ZW5zaW9uc1NldCgqbWVzc2FnZTEpOworfQorCitURVNUKEV4dGVuc2lvblNldFRlc3QsIFN3YXBFeHRlbnNpb25XaXRoU2VsZikgeworICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTE7CisKKyAgVGVzdFV0aWw6OlNldEFsbEV4dGVuc2lvbnMoJm1lc3NhZ2UxKTsKKworICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4gZmllbGRzOworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZTEuR2V0UmVmbGVjdGlvbigpOworICByZWZsZWN0aW9uLT5MaXN0RmllbGRzKG1lc3NhZ2UxLCAmZmllbGRzKTsKKyAgcmVmbGVjdGlvbi0+U3dhcEZpZWxkcygmbWVzc2FnZTEsICZtZXNzYWdlMSwgZmllbGRzKTsKKworICBUZXN0VXRpbDo6RXhwZWN0QWxsRXh0ZW5zaW9uc1NldChtZXNzYWdlMSk7Cit9CisKK1RFU1QoRXh0ZW5zaW9uU2V0VGVzdCwgU2VyaWFsaXphdGlvblRvQXJyYXkpIHsKKyAgLy8gU2VyaWFsaXplIGFzIFRlc3RBbGxFeHRlbnNpb25zIGFuZCBwYXJzZSBhcyBUZXN0QWxsVHlwZXMgdG8gaW5zdXJlIHdpcmUKKyAgLy8gY29tcGF0aWJpbGl0eSBvZiBleHRlbnNpb25zLgorICAvLworICAvLyBUaGlzIGNoZWNrcyBzZXJpYWxpemF0aW9uIHRvIGEgZmxhdCBhcnJheSBieSBleHBsaWNpdGx5IHJlc2VydmluZyBzcGFjZSBpbgorICAvLyB0aGUgc3RyaW5nIGFuZCBjYWxsaW5nIHRoZSBnZW5lcmF0ZWQgbWVzc2FnZSdzCisgIC8vIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkuCisgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyBzb3VyY2U7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgZGVzdGluYXRpb247CisgIFRlc3RVdGlsOjpTZXRBbGxFeHRlbnNpb25zKCZzb3VyY2UpOworICBpbnQgc2l6ZSA9IHNvdXJjZS5CeXRlU2l6ZSgpOworICBzdHJpbmcgZGF0YTsKKyAgZGF0YS5yZXNpemUoc2l6ZSk7CisgIHVpbnQ4KiB0YXJnZXQgPSByZWludGVycHJldF9jYXN0PHVpbnQ4Kj4oc3RyaW5nX2FzX2FycmF5KCZkYXRhKSk7CisgIHVpbnQ4KiBlbmQgPSBzb3VyY2UuU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSh0YXJnZXQpOworICBFWFBFQ1RfRVEoc2l6ZSwgZW5kIC0gdGFyZ2V0KTsKKyAgRVhQRUNUX1RSVUUoZGVzdGluYXRpb24uUGFyc2VGcm9tU3RyaW5nKGRhdGEpKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEZpZWxkc1NldChkZXN0aW5hdGlvbik7Cit9CisKK1RFU1QoRXh0ZW5zaW9uU2V0VGVzdCwgU2VyaWFsaXphdGlvblRvU3RyZWFtKSB7CisgIC8vIFNlcmlhbGl6ZSBhcyBUZXN0QWxsRXh0ZW5zaW9ucyBhbmQgcGFyc2UgYXMgVGVzdEFsbFR5cGVzIHRvIGluc3VyZSB3aXJlCisgIC8vIGNvbXBhdGliaWxpdHkgb2YgZXh0ZW5zaW9ucy4KKyAgLy8KKyAgLy8gVGhpcyBjaGVja3Mgc2VyaWFsaXphdGlvbiB0byBhbiBvdXRwdXQgc3RyZWFtIGJ5IGNyZWF0aW5nIGFuIGFycmF5IG91dHB1dAorICAvLyBzdHJlYW0gdGhhdCBjYW4gb25seSBidWZmZXIgMSBieXRlIGF0IGEgdGltZSAtIHRoaXMgcHJldmVudHMgdGhlIG1lc3NhZ2UKKyAgLy8gZnJvbSBldmVyIGp1bXBpbmcgdG8gdGhlIGZhc3QgcGF0aCwgZW5zdXJpbmcgdGhhdCBzZXJpYWxpemF0aW9uIGhhcHBlbnMgdmlhCisgIC8vIHRoZSBDb2RlZE91dHB1dFN0cmVhbS4KKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIHNvdXJjZTsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBkZXN0aW5hdGlvbjsKKyAgVGVzdFV0aWw6OlNldEFsbEV4dGVuc2lvbnMoJnNvdXJjZSk7CisgIGludCBzaXplID0gc291cmNlLkJ5dGVTaXplKCk7CisgIHN0cmluZyBkYXRhOworICBkYXRhLnJlc2l6ZShzaXplKTsKKyAgeworICAgIGlvOjpBcnJheU91dHB1dFN0cmVhbSBhcnJheV9zdHJlYW0oc3RyaW5nX2FzX2FycmF5KCZkYXRhKSwgc2l6ZSwgMSk7CisgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dF9zdHJlYW0oJmFycmF5X3N0cmVhbSk7CisgICAgc291cmNlLlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygmb3V0cHV0X3N0cmVhbSk7CisgICAgQVNTRVJUX0ZBTFNFKG91dHB1dF9zdHJlYW0uSGFkRXJyb3IoKSk7CisgIH0KKyAgRVhQRUNUX1RSVUUoZGVzdGluYXRpb24uUGFyc2VGcm9tU3RyaW5nKGRhdGEpKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEZpZWxkc1NldChkZXN0aW5hdGlvbik7Cit9CisKK1RFU1QoRXh0ZW5zaW9uU2V0VGVzdCwgUGFja2VkU2VyaWFsaXphdGlvblRvQXJyYXkpIHsKKyAgLy8gU2VyaWFsaXplIGFzIFRlc3RQYWNrZWRFeHRlbnNpb25zIGFuZCBwYXJzZSBhcyBUZXN0UGFja2VkVHlwZXMgdG8gaW5zdXJlCisgIC8vIHdpcmUgY29tcGF0aWJpbGl0eSBvZiBleHRlbnNpb25zLgorICAvLworICAvLyBUaGlzIGNoZWNrcyBzZXJpYWxpemF0aW9uIHRvIGEgZmxhdCBhcnJheSBieSBleHBsaWNpdGx5IHJlc2VydmluZyBzcGFjZSBpbgorICAvLyB0aGUgc3RyaW5nIGFuZCBjYWxsaW5nIHRoZSBnZW5lcmF0ZWQgbWVzc2FnZSdzCisgIC8vIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkuCisgIHVuaXR0ZXN0OjpUZXN0UGFja2VkRXh0ZW5zaW9ucyBzb3VyY2U7CisgIHVuaXR0ZXN0OjpUZXN0UGFja2VkVHlwZXMgZGVzdGluYXRpb247CisgIFRlc3RVdGlsOjpTZXRQYWNrZWRFeHRlbnNpb25zKCZzb3VyY2UpOworICBpbnQgc2l6ZSA9IHNvdXJjZS5CeXRlU2l6ZSgpOworICBzdHJpbmcgZGF0YTsKKyAgZGF0YS5yZXNpemUoc2l6ZSk7CisgIHVpbnQ4KiB0YXJnZXQgPSByZWludGVycHJldF9jYXN0PHVpbnQ4Kj4oc3RyaW5nX2FzX2FycmF5KCZkYXRhKSk7CisgIHVpbnQ4KiBlbmQgPSBzb3VyY2UuU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSh0YXJnZXQpOworICBFWFBFQ1RfRVEoc2l6ZSwgZW5kIC0gdGFyZ2V0KTsKKyAgRVhQRUNUX1RSVUUoZGVzdGluYXRpb24uUGFyc2VGcm9tU3RyaW5nKGRhdGEpKTsKKyAgVGVzdFV0aWw6OkV4cGVjdFBhY2tlZEZpZWxkc1NldChkZXN0aW5hdGlvbik7Cit9CisKK1RFU1QoRXh0ZW5zaW9uU2V0VGVzdCwgUGFja2VkU2VyaWFsaXphdGlvblRvU3RyZWFtKSB7CisgIC8vIFNlcmlhbGl6ZSBhcyBUZXN0UGFja2VkRXh0ZW5zaW9ucyBhbmQgcGFyc2UgYXMgVGVzdFBhY2tlZFR5cGVzIHRvIGluc3VyZQorICAvLyB3aXJlIGNvbXBhdGliaWxpdHkgb2YgZXh0ZW5zaW9ucy4KKyAgLy8KKyAgLy8gVGhpcyBjaGVja3Mgc2VyaWFsaXphdGlvbiB0byBhbiBvdXRwdXQgc3RyZWFtIGJ5IGNyZWF0aW5nIGFuIGFycmF5IG91dHB1dAorICAvLyBzdHJlYW0gdGhhdCBjYW4gb25seSBidWZmZXIgMSBieXRlIGF0IGEgdGltZSAtIHRoaXMgcHJldmVudHMgdGhlIG1lc3NhZ2UKKyAgLy8gZnJvbSBldmVyIGp1bXBpbmcgdG8gdGhlIGZhc3QgcGF0aCwgZW5zdXJpbmcgdGhhdCBzZXJpYWxpemF0aW9uIGhhcHBlbnMgdmlhCisgIC8vIHRoZSBDb2RlZE91dHB1dFN0cmVhbS4KKyAgdW5pdHRlc3Q6OlRlc3RQYWNrZWRFeHRlbnNpb25zIHNvdXJjZTsKKyAgdW5pdHRlc3Q6OlRlc3RQYWNrZWRUeXBlcyBkZXN0aW5hdGlvbjsKKyAgVGVzdFV0aWw6OlNldFBhY2tlZEV4dGVuc2lvbnMoJnNvdXJjZSk7CisgIGludCBzaXplID0gc291cmNlLkJ5dGVTaXplKCk7CisgIHN0cmluZyBkYXRhOworICBkYXRhLnJlc2l6ZShzaXplKTsKKyAgeworICAgIGlvOjpBcnJheU91dHB1dFN0cmVhbSBhcnJheV9zdHJlYW0oc3RyaW5nX2FzX2FycmF5KCZkYXRhKSwgc2l6ZSwgMSk7CisgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dF9zdHJlYW0oJmFycmF5X3N0cmVhbSk7CisgICAgc291cmNlLlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygmb3V0cHV0X3N0cmVhbSk7CisgICAgQVNTRVJUX0ZBTFNFKG91dHB1dF9zdHJlYW0uSGFkRXJyb3IoKSk7CisgIH0KKyAgRVhQRUNUX1RSVUUoZGVzdGluYXRpb24uUGFyc2VGcm9tU3RyaW5nKGRhdGEpKTsKKyAgVGVzdFV0aWw6OkV4cGVjdFBhY2tlZEZpZWxkc1NldChkZXN0aW5hdGlvbik7Cit9CisKK1RFU1QoRXh0ZW5zaW9uU2V0VGVzdCwgUGFyc2luZykgeworICAvLyBTZXJpYWxpemUgYXMgVGVzdEFsbFR5cGVzIGFuZCBwYXJzZSBhcyBUZXN0QWxsRXh0ZW5zaW9ucy4KKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBzb3VyY2U7CisgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyBkZXN0aW5hdGlvbjsKKyAgc3RyaW5nIGRhdGE7CisKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmc291cmNlKTsKKyAgc291cmNlLlNlcmlhbGl6ZVRvU3RyaW5nKCZkYXRhKTsKKyAgRVhQRUNUX1RSVUUoZGVzdGluYXRpb24uUGFyc2VGcm9tU3RyaW5nKGRhdGEpKTsKKyAgVGVzdFV0aWw6OlNldE9uZW9mRmllbGRzKCZkZXN0aW5hdGlvbik7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxFeHRlbnNpb25zU2V0KGRlc3RpbmF0aW9uKTsKK30KKworVEVTVChFeHRlbnNpb25TZXRUZXN0LCBQYWNrZWRQYXJzaW5nKSB7CisgIC8vIFNlcmlhbGl6ZSBhcyBUZXN0UGFja2VkVHlwZXMgYW5kIHBhcnNlIGFzIFRlc3RQYWNrZWRFeHRlbnNpb25zLgorICB1bml0dGVzdDo6VGVzdFBhY2tlZFR5cGVzIHNvdXJjZTsKKyAgdW5pdHRlc3Q6OlRlc3RQYWNrZWRFeHRlbnNpb25zIGRlc3RpbmF0aW9uOworICBzdHJpbmcgZGF0YTsKKworICBUZXN0VXRpbDo6U2V0UGFja2VkRmllbGRzKCZzb3VyY2UpOworICBzb3VyY2UuU2VyaWFsaXplVG9TdHJpbmcoJmRhdGEpOworICBFWFBFQ1RfVFJVRShkZXN0aW5hdGlvbi5QYXJzZUZyb21TdHJpbmcoZGF0YSkpOworICBUZXN0VXRpbDo6RXhwZWN0UGFja2VkRXh0ZW5zaW9uc1NldChkZXN0aW5hdGlvbik7Cit9CisKK1RFU1QoRXh0ZW5zaW9uU2V0VGVzdCwgUGFja2VkVG9VbnBhY2tlZFBhcnNpbmcpIHsKKyAgdW5pdHRlc3Q6OlRlc3RQYWNrZWRUeXBlcyBzb3VyY2U7CisgIHVuaXR0ZXN0OjpUZXN0VW5wYWNrZWRFeHRlbnNpb25zIGRlc3RpbmF0aW9uOworICBzdHJpbmcgZGF0YTsKKworICBUZXN0VXRpbDo6U2V0UGFja2VkRmllbGRzKCZzb3VyY2UpOworICBzb3VyY2UuU2VyaWFsaXplVG9TdHJpbmcoJmRhdGEpOworICBFWFBFQ1RfVFJVRShkZXN0aW5hdGlvbi5QYXJzZUZyb21TdHJpbmcoZGF0YSkpOworICBUZXN0VXRpbDo6RXhwZWN0VW5wYWNrZWRFeHRlbnNpb25zU2V0KGRlc3RpbmF0aW9uKTsKKworICAvLyBSZXNlcmlhbGl6ZQorICB1bml0dGVzdDo6VGVzdFVucGFja2VkVHlwZXMgdW5wYWNrZWQ7CisgIFRlc3RVdGlsOjpTZXRVbnBhY2tlZEZpZWxkcygmdW5wYWNrZWQpOworICBFWFBFQ1RfVFJVRSh1bnBhY2tlZC5TZXJpYWxpemVBc1N0cmluZygpID09IGRlc3RpbmF0aW9uLlNlcmlhbGl6ZUFzU3RyaW5nKCkpOworCisgIC8vIE1ha2Ugc3VyZSB3ZSBjYW4gYWRkIGV4dGVuc2lvbnMuCisgIGRlc3RpbmF0aW9uLkFkZEV4dGVuc2lvbih1bml0dGVzdDo6dW5wYWNrZWRfaW50MzJfZXh0ZW5zaW9uLCAxKTsKKyAgZGVzdGluYXRpb24uQWRkRXh0ZW5zaW9uKHVuaXR0ZXN0Ojp1bnBhY2tlZF9lbnVtX2V4dGVuc2lvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpGT1JFSUdOX0JBUik7Cit9CisKK1RFU1QoRXh0ZW5zaW9uU2V0VGVzdCwgVW5wYWNrZWRUb1BhY2tlZFBhcnNpbmcpIHsKKyAgdW5pdHRlc3Q6OlRlc3RVbnBhY2tlZFR5cGVzIHNvdXJjZTsKKyAgdW5pdHRlc3Q6OlRlc3RQYWNrZWRFeHRlbnNpb25zIGRlc3RpbmF0aW9uOworICBzdHJpbmcgZGF0YTsKKworICBUZXN0VXRpbDo6U2V0VW5wYWNrZWRGaWVsZHMoJnNvdXJjZSk7CisgIHNvdXJjZS5TZXJpYWxpemVUb1N0cmluZygmZGF0YSk7CisgIEVYUEVDVF9UUlVFKGRlc3RpbmF0aW9uLlBhcnNlRnJvbVN0cmluZyhkYXRhKSk7CisgIFRlc3RVdGlsOjpFeHBlY3RQYWNrZWRFeHRlbnNpb25zU2V0KGRlc3RpbmF0aW9uKTsKKworICAvLyBSZXNlcmlhbGl6ZQorICB1bml0dGVzdDo6VGVzdFBhY2tlZFR5cGVzIHBhY2tlZDsKKyAgVGVzdFV0aWw6OlNldFBhY2tlZEZpZWxkcygmcGFja2VkKTsKKyAgRVhQRUNUX1RSVUUocGFja2VkLlNlcmlhbGl6ZUFzU3RyaW5nKCkgPT0gZGVzdGluYXRpb24uU2VyaWFsaXplQXNTdHJpbmcoKSk7CisKKyAgLy8gTWFrZSBzdXJlIHdlIGNhbiBhZGQgZXh0ZW5zaW9ucy4KKyAgZGVzdGluYXRpb24uQWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfaW50MzJfZXh0ZW5zaW9uLCAxKTsKKyAgZGVzdGluYXRpb24uQWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZW51bV9leHRlbnNpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdDo6Rk9SRUlHTl9CQVIpOworfQorCitURVNUKEV4dGVuc2lvblNldFRlc3QsIElzSW5pdGlhbGl6ZWQpIHsKKyAgLy8gVGVzdCB0aGF0IElzSW5pdGlhbGl6ZWQoKSByZXR1cm5zIGZhbHNlIGlmIHJlcXVpcmVkIGZpZWxkcyBpbiBuZXN0ZWQKKyAgLy8gZXh0ZW5zaW9ucyBhcmUgbWlzc2luZy4KKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2U7CisKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5Jc0luaXRpYWxpemVkKCkpOworCisgIG1lc3NhZ2UuTXV0YWJsZUV4dGVuc2lvbih1bml0dGVzdDo6VGVzdFJlcXVpcmVkOjpzaW5nbGUpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5Jc0luaXRpYWxpemVkKCkpOworCisgIG1lc3NhZ2UuTXV0YWJsZUV4dGVuc2lvbih1bml0dGVzdDo6VGVzdFJlcXVpcmVkOjpzaW5nbGUpLT5zZXRfYSgxKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSXNJbml0aWFsaXplZCgpKTsKKyAgbWVzc2FnZS5NdXRhYmxlRXh0ZW5zaW9uKHVuaXR0ZXN0OjpUZXN0UmVxdWlyZWQ6OnNpbmdsZSktPnNldF9iKDIpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5Jc0luaXRpYWxpemVkKCkpOworICBtZXNzYWdlLk11dGFibGVFeHRlbnNpb24odW5pdHRlc3Q6OlRlc3RSZXF1aXJlZDo6c2luZ2xlKS0+c2V0X2MoMyk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSXNJbml0aWFsaXplZCgpKTsKKworICBtZXNzYWdlLkFkZEV4dGVuc2lvbih1bml0dGVzdDo6VGVzdFJlcXVpcmVkOjptdWx0aSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLklzSW5pdGlhbGl6ZWQoKSk7CisKKyAgbWVzc2FnZS5NdXRhYmxlRXh0ZW5zaW9uKHVuaXR0ZXN0OjpUZXN0UmVxdWlyZWQ6Om11bHRpLCAwKS0+c2V0X2EoMSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLklzSW5pdGlhbGl6ZWQoKSk7CisgIG1lc3NhZ2UuTXV0YWJsZUV4dGVuc2lvbih1bml0dGVzdDo6VGVzdFJlcXVpcmVkOjptdWx0aSwgMCktPnNldF9iKDIpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5Jc0luaXRpYWxpemVkKCkpOworICBtZXNzYWdlLk11dGFibGVFeHRlbnNpb24odW5pdHRlc3Q6OlRlc3RSZXF1aXJlZDo6bXVsdGksIDApLT5zZXRfYygzKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5Jc0luaXRpYWxpemVkKCkpOworfQorCitURVNUKEV4dGVuc2lvblNldFRlc3QsIE11dGFibGVTdHJpbmcpIHsKKyAgLy8gVGVzdCB0aGUgbXV0YWJsZSBzdHJpbmcgYWNjZXNzb3JzLgorICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTsKKworICBtZXNzYWdlLk11dGFibGVFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3N0cmluZ19leHRlbnNpb24pLT5hc3NpZ24oImZvbyIpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc3RyaW5nX2V4dGVuc2lvbikpOworICBFWFBFQ1RfRVEoImZvbyIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9zdHJpbmdfZXh0ZW5zaW9uKSk7CisKKyAgbWVzc2FnZS5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb24pLT5hc3NpZ24oImJhciIpOworICBBU1NFUlRfRVEoMSwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9zdHJpbmdfZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9FUSgiYmFyIiwKKyAgICAgICAgICAgIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zdHJpbmdfZXh0ZW5zaW9uLCAwKSk7Cit9CisKK1RFU1QoRXh0ZW5zaW9uU2V0VGVzdCwgU3BhY2VVc2VkRXhjbHVkaW5nU2VsZikgeworICAvLyBTY2FsYXIgcHJpbWl0aXZlIGV4dGVuc2lvbnMgc2hvdWxkIGluY3JlYXNlIHRoZSBleHRlbnNpb24gc2V0IHNpemUgYnkgYQorICAvLyBtaW5pbXVtIG9mIHRoZSBzaXplIG9mIHRoZSBwcmltaXRpdmUgdHlwZS4KKyNkZWZpbmUgVEVTVF9TQ0FMQVJfRVhURU5TSU9OU19TUEFDRV9VU0VEKHR5cGUsIHZhbHVlKSAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZG8geyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBjb25zdCBpbnQgYmFzZV9zaXplID0gbWVzc2FnZS5TcGFjZVVzZWQoKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBtZXNzYWdlLlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfIyN0eXBlIyNfZXh0ZW5zaW9uLCB2YWx1ZSk7ICAgICAgIFwKKyAgICBpbnQgbWluX2V4cGVjdGVkX3NpemUgPSBiYXNlX3NpemUgKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgc2l6ZW9mKG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF8jI3R5cGUjI19leHRlbnNpb24pKTsgIFwKKyAgICBFWFBFQ1RfTEUobWluX2V4cGVjdGVkX3NpemUsIG1lc3NhZ2UuU3BhY2VVc2VkKCkpOyAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgfSB3aGlsZSAoMCkKKworICBURVNUX1NDQUxBUl9FWFRFTlNJT05TX1NQQUNFX1VTRUQoaW50MzIgICAsIDEwMSk7CisgIFRFU1RfU0NBTEFSX0VYVEVOU0lPTlNfU1BBQ0VfVVNFRChpbnQ2NCAgICwgMTAyKTsKKyAgVEVTVF9TQ0FMQVJfRVhURU5TSU9OU19TUEFDRV9VU0VEKHVpbnQzMiAgLCAxMDMpOworICBURVNUX1NDQUxBUl9FWFRFTlNJT05TX1NQQUNFX1VTRUQodWludDY0ICAsIDEwNCk7CisgIFRFU1RfU0NBTEFSX0VYVEVOU0lPTlNfU1BBQ0VfVVNFRChzaW50MzIgICwgMTA1KTsKKyAgVEVTVF9TQ0FMQVJfRVhURU5TSU9OU19TUEFDRV9VU0VEKHNpbnQ2NCAgLCAxMDYpOworICBURVNUX1NDQUxBUl9FWFRFTlNJT05TX1NQQUNFX1VTRUQoZml4ZWQzMiAsIDEwNyk7CisgIFRFU1RfU0NBTEFSX0VYVEVOU0lPTlNfU1BBQ0VfVVNFRChmaXhlZDY0ICwgMTA4KTsKKyAgVEVTVF9TQ0FMQVJfRVhURU5TSU9OU19TUEFDRV9VU0VEKHNmaXhlZDMyLCAxMDkpOworICBURVNUX1NDQUxBUl9FWFRFTlNJT05TX1NQQUNFX1VTRUQoc2ZpeGVkNjQsIDExMCk7CisgIFRFU1RfU0NBTEFSX0VYVEVOU0lPTlNfU1BBQ0VfVVNFRChmbG9hdCAgICwgMTExKTsKKyAgVEVTVF9TQ0FMQVJfRVhURU5TSU9OU19TUEFDRV9VU0VEKGRvdWJsZSAgLCAxMTIpOworICBURVNUX1NDQUxBUl9FWFRFTlNJT05TX1NQQUNFX1VTRUQoYm9vbCAgICAsIHRydWUpOworI3VuZGVmIFRFU1RfU0NBTEFSX0VYVEVOU0lPTlNfU1BBQ0VfVVNFRAorICB7CisgICAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2U7CisgICAgY29uc3QgaW50IGJhc2Vfc2l6ZSA9IG1lc3NhZ2UuU3BhY2VVc2VkKCk7CisgICAgbWVzc2FnZS5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX25lc3RlZF9lbnVtX2V4dGVuc2lvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpGT08pOworICAgIGludCBtaW5fZXhwZWN0ZWRfc2l6ZSA9IGJhc2Vfc2l6ZSArCisgICAgICAgIHNpemVvZihtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfbmVzdGVkX2VudW1fZXh0ZW5zaW9uKSk7CisgICAgRVhQRUNUX0xFKG1pbl9leHBlY3RlZF9zaXplLCBtZXNzYWdlLlNwYWNlVXNlZCgpKTsKKyAgfQorICB7CisgICAgLy8gU3RyaW5ncyBtYXkgY2F1c2UgZXh0cmEgYWxsb2NhdGlvbnMgZGVwZW5kaW5nIG9uIHRoZWlyIGxlbmd0aDsgZW5zdXJlCisgICAgLy8gdGhhdCBnZXRzIGluY2x1ZGVkIGFzIHdlbGwuCisgICAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2U7CisgICAgY29uc3QgaW50IGJhc2Vfc2l6ZSA9IG1lc3NhZ2UuU3BhY2VVc2VkKCk7CisgICAgY29uc3Qgc3RyaW5nIHMoInRoaXMgaXMgYSBmYWlybHkgbGFyZ2Ugc3RyaW5nIHRoYXQgd2lsbCBjYXVzZSBzb21lICIKKyAgICAgICAgICAgICAgICAgICAiYWxsb2NhdGlvbiBpbiBvcmRlciB0byBzdG9yZSBpdCBpbiB0aGUgZXh0ZW5zaW9uIik7CisgICAgbWVzc2FnZS5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3N0cmluZ19leHRlbnNpb24sIHMpOworICAgIGludCBtaW5fZXhwZWN0ZWRfc2l6ZSA9IGJhc2Vfc2l6ZSArIHMubGVuZ3RoKCk7CisgICAgRVhQRUNUX0xFKG1pbl9leHBlY3RlZF9zaXplLCBtZXNzYWdlLlNwYWNlVXNlZCgpKTsKKyAgfQorICB7CisgICAgLy8gTWVzc2FnZXMgYWxzbyBoYXZlIGFkZGl0aW9uYWwgYWxsb2NhdGlvbiB0aGF0IG5lZWQgdG8gYmUgY291bnRlZC4KKyAgICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTsKKyAgICBjb25zdCBpbnQgYmFzZV9zaXplID0gbWVzc2FnZS5TcGFjZVVzZWQoKTsKKyAgICB1bml0dGVzdDo6Rm9yZWlnbk1lc3NhZ2UgZm9yZWlnbjsKKyAgICBmb3JlaWduLnNldF9jKDQyKTsKKyAgICBtZXNzYWdlLk11dGFibGVFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb24pLT4KKyAgICAgICAgQ29weUZyb20oZm9yZWlnbik7CisgICAgaW50IG1pbl9leHBlY3RlZF9zaXplID0gYmFzZV9zaXplICsgZm9yZWlnbi5TcGFjZVVzZWQoKTsKKyAgICBFWFBFQ1RfTEUobWluX2V4cGVjdGVkX3NpemUsIG1lc3NhZ2UuU3BhY2VVc2VkKCkpOworICB9CisKKyAgLy8gUmVwZWF0ZWQgcHJpbWl0aXZlIGV4dGVuc2lvbnMgd2lsbCBpbmNyZWFzZSBzcGFjZSB1c2VkIGJ5IGF0IGxlYXN0IGEKKyAgLy8gUmVwZWF0ZWRGaWVsZDxUPiwgYW5kIHdpbGwgY2F1c2UgYWRkaXRpb25hbCBhbGxvY2F0aW9ucyB3aGVuIHRoZSBhcnJheQorICAvLyBnZXRzIHRvbyBiaWcgZm9yIHRoZSBpbml0aWFsIHNwYWNlLgorICAvLyBUaGlzIG1hY3JvOgorICAvLyAgIC0gQWRkcyBhIHZhbHVlIHRvIHRoZSByZXBlYXRlZCBleHRlbnNpb24sIHRoZW4gY2xlYXJzIGl0LCBlc3RhYmxpc2hpbmcKKyAgLy8gICAgIHRoZSBiYXNlIHNpemUuCisgIC8vICAgLSBBZGRzIGEgc21hbGwgbnVtYmVyIG9mIHZhbHVlcywgdGVzdGluZyB0aGF0IGl0IGRvZXNuJ3QgaW5jcmVhc2UgdGhlCisgIC8vICAgICBTcGFjZVVzZWQoKQorICAvLyAgIC0gQWRkcyBhIGxhcmdlIG51bWJlciBvZiB2YWx1ZXMgKHJlcXVpcmluZyBhbGxvY2F0aW9uIGluIHRoZSByZXBlYXRlZAorICAvLyAgICAgZmllbGQpLCBhbmQgZW5zdXJlcyB0aGF0IHRoYXQgYWxsb2NhdGlvbiBpcyBpbmNsdWRlZCBpbiBTcGFjZVVzZWQoKQorI2RlZmluZSBURVNUX1JFUEVBVEVEX0VYVEVOU0lPTlNfU1BBQ0VfVVNFRCh0eXBlLCBjcHB0eXBlLCB2YWx1ZSkgICAgICAgICAgICAgIFwKKyAgZG8geyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2U7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGNvbnN0IGludCBiYXNlX3NpemUgPSBtZXNzYWdlLlNwYWNlVXNlZCgpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBpbnQgbWluX2V4cGVjdGVkX3NpemUgPSBzaXplb2YoUmVwZWF0ZWRGaWVsZDxjcHB0eXBlPikgKyBiYXNlX3NpemU7ICAgICAgICBcCisgICAgbWVzc2FnZS5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkXyMjdHlwZSMjX2V4dGVuc2lvbiwgdmFsdWUpOyAgICAgICAgXAorICAgIG1lc3NhZ2UuQ2xlYXJFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkXyMjdHlwZSMjX2V4dGVuc2lvbik7ICAgICAgICAgICAgIFwKKyAgICBjb25zdCBpbnQgZW1wdHlfcmVwZWF0ZWRfZmllbGRfc2l6ZSA9IG1lc3NhZ2UuU3BhY2VVc2VkKCk7ICAgICAgICAgICAgICAgICBcCisgICAgRVhQRUNUX0xFKG1pbl9leHBlY3RlZF9zaXplLCBlbXB0eV9yZXBlYXRlZF9maWVsZF9zaXplKSA8PCAjdHlwZTsgICAgICAgICAgXAorICAgIG1lc3NhZ2UuQWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF8jI3R5cGUjI19leHRlbnNpb24sIHZhbHVlKTsgICAgICAgIFwKKyAgICBtZXNzYWdlLkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfIyN0eXBlIyNfZXh0ZW5zaW9uLCB2YWx1ZSk7ICAgICAgICBcCisgICAgRVhQRUNUX0VRKGVtcHR5X3JlcGVhdGVkX2ZpZWxkX3NpemUsIG1lc3NhZ2UuU3BhY2VVc2VkKCkpIDw8ICN0eXBlOyAgICAgICAgXAorICAgIG1lc3NhZ2UuQ2xlYXJFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkXyMjdHlwZSMjX2V4dGVuc2lvbik7ICAgICAgICAgICAgIFwKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IDE2OyArK2kpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICBtZXNzYWdlLkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfIyN0eXBlIyNfZXh0ZW5zaW9uLCB2YWx1ZSk7ICAgICAgXAorICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBpbnQgZXhwZWN0ZWRfc2l6ZSA9IHNpemVvZihjcHB0eXBlKSAqICgxNiAtICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGtNaW5SZXBlYXRlZEZpZWxkQWxsb2NhdGlvblNpemUpICsgZW1wdHlfcmVwZWF0ZWRfZmllbGRfc2l6ZTsgICAgICAgICAgXAorICAgIEVYUEVDVF9FUShleHBlY3RlZF9zaXplLCBtZXNzYWdlLlNwYWNlVXNlZCgpKSA8PCAjdHlwZTsgICAgICAgICAgICAgICAgICAgIFwKKyAgfSB3aGlsZSAoMCkKKworICBURVNUX1JFUEVBVEVEX0VYVEVOU0lPTlNfU1BBQ0VfVVNFRChpbnQzMiAgICwgaW50MzIgLCAxMDEpOworICBURVNUX1JFUEVBVEVEX0VYVEVOU0lPTlNfU1BBQ0VfVVNFRChpbnQ2NCAgICwgaW50NjQgLCAxMDIpOworICBURVNUX1JFUEVBVEVEX0VYVEVOU0lPTlNfU1BBQ0VfVVNFRCh1aW50MzIgICwgdWludDMyLCAxMDMpOworICBURVNUX1JFUEVBVEVEX0VYVEVOU0lPTlNfU1BBQ0VfVVNFRCh1aW50NjQgICwgdWludDY0LCAxMDQpOworICBURVNUX1JFUEVBVEVEX0VYVEVOU0lPTlNfU1BBQ0VfVVNFRChzaW50MzIgICwgaW50MzIgLCAxMDUpOworICBURVNUX1JFUEVBVEVEX0VYVEVOU0lPTlNfU1BBQ0VfVVNFRChzaW50NjQgICwgaW50NjQgLCAxMDYpOworICBURVNUX1JFUEVBVEVEX0VYVEVOU0lPTlNfU1BBQ0VfVVNFRChmaXhlZDMyICwgdWludDMyLCAxMDcpOworICBURVNUX1JFUEVBVEVEX0VYVEVOU0lPTlNfU1BBQ0VfVVNFRChmaXhlZDY0ICwgdWludDY0LCAxMDgpOworICBURVNUX1JFUEVBVEVEX0VYVEVOU0lPTlNfU1BBQ0VfVVNFRChzZml4ZWQzMiwgaW50MzIgLCAxMDkpOworICBURVNUX1JFUEVBVEVEX0VYVEVOU0lPTlNfU1BBQ0VfVVNFRChzZml4ZWQ2NCwgaW50NjQgLCAxMTApOworICBURVNUX1JFUEVBVEVEX0VYVEVOU0lPTlNfU1BBQ0VfVVNFRChmbG9hdCAgICwgZmxvYXQgLCAxMTEpOworICBURVNUX1JFUEVBVEVEX0VYVEVOU0lPTlNfU1BBQ0VfVVNFRChkb3VibGUgICwgZG91YmxlLCAxMTIpOworICBURVNUX1JFUEVBVEVEX0VYVEVOU0lPTlNfU1BBQ0VfVVNFRChib29sICAgICwgYm9vbCAgLCB0cnVlKTsKKyAgVEVTVF9SRVBFQVRFRF9FWFRFTlNJT05TX1NQQUNFX1VTRUQobmVzdGVkX2VudW0sIGludCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6Rk9PKTsKKyN1bmRlZiBURVNUX1JFUEVBVEVEX0VYVEVOU0lPTlNfU1BBQ0VfVVNFRAorICAvLyBSZXBlYXRlZCBzdHJpbmdzCisgIHsKKyAgICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTsKKyAgICBjb25zdCBpbnQgYmFzZV9zaXplID0gbWVzc2FnZS5TcGFjZVVzZWQoKTsKKyAgICBpbnQgbWluX2V4cGVjdGVkX3NpemUgPSBzaXplb2YoUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+KSArIGJhc2Vfc2l6ZTsKKyAgICBjb25zdCBzdHJpbmcgdmFsdWUoMjU2LCAneCcpOworICAgIC8vIE9uY2UgaXRlbXMgYXJlIGFsbG9jYXRlZCwgdGhleSBtYXkgc3RpY2sgYXJvdW5kIGV2ZW4gd2hlbiBjbGVhcmVkIHNvCisgICAgLy8gd2l0aG91dCB0aGUgaGFyZGNvcmUgbWVtb3J5IG1hbmFnZW1lbnQgYWNjZXNzb3JzIHRoZXJlIGlzbid0IGEgbm90aW9uIG9mCisgICAgLy8gdGhlIGVtcHR5IHJlcGVhdGVkIGZpZWxkIG1lbW9yeSB1c2FnZSBhcyB0aGVyZSBpcyB3aXRoIHByaW1pdGl2ZSB0eXBlcy4KKyAgICBmb3IgKGludCBpID0gMDsgaSA8IDE2OyArK2kpIHsKKyAgICAgIG1lc3NhZ2UuQWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zdHJpbmdfZXh0ZW5zaW9uLCB2YWx1ZSk7CisgICAgfQorICAgIG1pbl9leHBlY3RlZF9zaXplICs9IChzaXplb2YodmFsdWUpICsgdmFsdWUuc2l6ZSgpKSAqCisgICAgICAgICgxNiAtIGtNaW5SZXBlYXRlZEZpZWxkQWxsb2NhdGlvblNpemUpOworICAgIEVYUEVDVF9MRShtaW5fZXhwZWN0ZWRfc2l6ZSwgbWVzc2FnZS5TcGFjZVVzZWQoKSk7CisgIH0KKyAgLy8gUmVwZWF0ZWQgbWVzc2FnZXMKKyAgeworICAgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyBtZXNzYWdlOworICAgIGNvbnN0IGludCBiYXNlX3NpemUgPSBtZXNzYWdlLlNwYWNlVXNlZCgpOworICAgIGludCBtaW5fZXhwZWN0ZWRfc2l6ZSA9IHNpemVvZihSZXBlYXRlZFB0ckZpZWxkPHVuaXR0ZXN0OjpGb3JlaWduTWVzc2FnZT4pICsKKyAgICAgICAgYmFzZV9zaXplOworICAgIHVuaXR0ZXN0OjpGb3JlaWduTWVzc2FnZSBwcm90b3R5cGU7CisgICAgcHJvdG90eXBlLnNldF9jKDIpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTY7ICsraSkgeworICAgICAgbWVzc2FnZS5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb24pLT4KKyAgICAgICAgICBDb3B5RnJvbShwcm90b3R5cGUpOworICAgIH0KKyAgICBtaW5fZXhwZWN0ZWRfc2l6ZSArPQorICAgICAgICAoMTYgLSBrTWluUmVwZWF0ZWRGaWVsZEFsbG9jYXRpb25TaXplKSAqIHByb3RvdHlwZS5TcGFjZVVzZWQoKTsKKyAgICBFWFBFQ1RfTEUobWluX2V4cGVjdGVkX3NpemUsIG1lc3NhZ2UuU3BhY2VVc2VkKCkpOworICB9Cit9CisKKy8vIE4uQi46IFdlIGRvIG5vdCB0ZXN0IHJhbmdlLWJhc2VkIGZvciBoZXJlIGJlY2F1c2Ugd2UgcmVtYWluIEMrKzAzIGNvbXBhdGlibGUuCit0ZW1wbGF0ZTx0eXBlbmFtZSBULCB0eXBlbmFtZSBNLCB0eXBlbmFtZSBJRD4KK2lubGluZSBUIFN1bUFsbEV4dGVuc2lvbnMoY29uc3QgTSYgbWVzc2FnZSwgSUQgZXh0ZW5zaW9uLCBUIHplcm8pIHsKKyAgVCBzdW0gPSB6ZXJvOworICB0eXBlbmFtZSBSZXBlYXRlZEZpZWxkPFQ+Ojpjb25zdF9pdGVyYXRvciBpdGVyID0KKyAgICAgIG1lc3NhZ2UuR2V0UmVwZWF0ZWRFeHRlbnNpb24oZXh0ZW5zaW9uKS5iZWdpbigpOworICB0eXBlbmFtZSBSZXBlYXRlZEZpZWxkPFQ+Ojpjb25zdF9pdGVyYXRvciBlbmQgPQorICAgICAgbWVzc2FnZS5HZXRSZXBlYXRlZEV4dGVuc2lvbihleHRlbnNpb24pLmVuZCgpOworICBmb3IgKDsgaXRlciAhPSBlbmQ7ICsraXRlcikgeworICAgIHN1bSArPSAqaXRlcjsKKyAgfQorICByZXR1cm4gc3VtOworfQorCit0ZW1wbGF0ZTx0eXBlbmFtZSBULCB0eXBlbmFtZSBNLCB0eXBlbmFtZSBJRD4KK2lubGluZSB2b2lkIEluY0FsbEV4dGVuc2lvbnMoTSogbWVzc2FnZSwgSUQgZXh0ZW5zaW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICBUIHZhbCkgeworICB0eXBlbmFtZSBSZXBlYXRlZEZpZWxkPFQ+OjppdGVyYXRvciBpdGVyID0KKyAgICAgIG1lc3NhZ2UtPk11dGFibGVSZXBlYXRlZEV4dGVuc2lvbihleHRlbnNpb24pLT5iZWdpbigpOworICB0eXBlbmFtZSBSZXBlYXRlZEZpZWxkPFQ+OjppdGVyYXRvciBlbmQgID0KKyAgICAgIG1lc3NhZ2UtPk11dGFibGVSZXBlYXRlZEV4dGVuc2lvbihleHRlbnNpb24pLT5lbmQoKTsKKyAgZm9yICg7IGl0ZXIgIT0gZW5kOyArK2l0ZXIpIHsKKyAgICAqaXRlciArPSB2YWw7CisgIH0KK30KKworVEVTVChFeHRlbnNpb25TZXRUZXN0LCBSZXBlYXRlZEZpZWxkcykgeworICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTsKKworICAvLyBUZXN0IGVtcHR5IHJlcGVhdGVkLWZpZWxkIGNhc2UgKGIvMTI5MjYxNjMpCisgIEFTU0VSVF9FUSgwLCBtZXNzYWdlLkdldFJlcGVhdGVkRXh0ZW5zaW9uKAorICAgICAgdW5pdHRlc3Q6OnJlcGVhdGVkX2ludDMyX2V4dGVuc2lvbikuc2l6ZSgpKTsKKyAgQVNTRVJUX0VRKDAsIG1lc3NhZ2UuR2V0UmVwZWF0ZWRFeHRlbnNpb24oCisgICAgICB1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uKS5zaXplKCkpOworICBBU1NFUlRfRVEoMCwgbWVzc2FnZS5HZXRSZXBlYXRlZEV4dGVuc2lvbigKKyAgICAgIHVuaXR0ZXN0OjpyZXBlYXRlZF9zdHJpbmdfZXh0ZW5zaW9uKS5zaXplKCkpOworICBBU1NFUlRfRVEoMCwgbWVzc2FnZS5HZXRSZXBlYXRlZEV4dGVuc2lvbigKKyAgICAgIHVuaXR0ZXN0OjpyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb24pLnNpemUoKSk7CisKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6TmVzdGVkTWVzc2FnZSBuZXN0ZWRfbWVzc2FnZTsKKyAgbmVzdGVkX21lc3NhZ2Uuc2V0X2JiKDQyKTsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6TmVzdGVkRW51bSBuZXN0ZWRfZW51bSA9CisgICAgICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpOZXN0ZWRFbnVtX01JTjsKKworICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyArK2kpIHsKKyAgICBtZXNzYWdlLkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9uLCAxKTsKKyAgICBtZXNzYWdlLkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW50NjRfZXh0ZW5zaW9uLCAyKTsKKyAgICBtZXNzYWdlLkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfdWludDMyX2V4dGVuc2lvbiwgMyk7CisgICAgbWVzc2FnZS5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3VpbnQ2NF9leHRlbnNpb24sIDQpOworICAgIG1lc3NhZ2UuQWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50MzJfZXh0ZW5zaW9uLCA1KTsKKyAgICBtZXNzYWdlLkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ludDY0X2V4dGVuc2lvbiwgNik7CisgICAgbWVzc2FnZS5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkMzJfZXh0ZW5zaW9uLCA3KTsKKyAgICBtZXNzYWdlLkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZml4ZWQ2NF9leHRlbnNpb24sIDgpOworICAgIG1lc3NhZ2UuQWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zZml4ZWQzMl9leHRlbnNpb24sIDcpOworICAgIG1lc3NhZ2UuQWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zZml4ZWQ2NF9leHRlbnNpb24sIDgpOworICAgIG1lc3NhZ2UuQWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9mbG9hdF9leHRlbnNpb24sIDkuMCk7CisgICAgbWVzc2FnZS5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2RvdWJsZV9leHRlbnNpb24sIDEwLjApOworICAgIG1lc3NhZ2UuQWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9ib29sX2V4dGVuc2lvbiwgdHJ1ZSk7CisgICAgbWVzc2FnZS5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9lbnVtX2V4dGVuc2lvbiwgbmVzdGVkX2VudW0pOworICAgIG1lc3NhZ2UuQWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zdHJpbmdfZXh0ZW5zaW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgIDo6c3RkOjpzdHJpbmcoInRlc3QiKSk7CisgICAgbWVzc2FnZS5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2J5dGVzX2V4dGVuc2lvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICA6OnN0ZDo6c3RyaW5nKCJ0ZXN0XHhGRiIpKTsKKyAgICBtZXNzYWdlLkFkZEV4dGVuc2lvbigKKyAgICAgICAgdW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiktPkNvcHlGcm9tKG5lc3RlZF9tZXNzYWdlKTsKKyAgICBtZXNzYWdlLkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgIG5lc3RlZF9lbnVtKTsKKyAgfQorCisgIEFTU0VSVF9FUSgxMCwgU3VtQWxsRXh0ZW5zaW9uczxpbnQzMj4oCisgICAgICBtZXNzYWdlLCB1bml0dGVzdDo6cmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9uLCAwKSk7CisgIEluY0FsbEV4dGVuc2lvbnM8aW50MzI+KAorICAgICAgJm1lc3NhZ2UsIHVuaXR0ZXN0OjpyZXBlYXRlZF9pbnQzMl9leHRlbnNpb24sIDEpOworICBBU1NFUlRfRVEoMjAsIFN1bUFsbEV4dGVuc2lvbnM8aW50MzI+KAorICAgICAgbWVzc2FnZSwgdW5pdHRlc3Q6OnJlcGVhdGVkX2ludDMyX2V4dGVuc2lvbiwgMCkpOworCisgIEFTU0VSVF9FUSgyMCwgU3VtQWxsRXh0ZW5zaW9uczxpbnQ2ND4oCisgICAgICBtZXNzYWdlLCB1bml0dGVzdDo6cmVwZWF0ZWRfaW50NjRfZXh0ZW5zaW9uLCAwKSk7CisgIEluY0FsbEV4dGVuc2lvbnM8aW50NjQ+KAorICAgICAgJm1lc3NhZ2UsIHVuaXR0ZXN0OjpyZXBlYXRlZF9pbnQ2NF9leHRlbnNpb24sIDEpOworICBBU1NFUlRfRVEoMzAsIFN1bUFsbEV4dGVuc2lvbnM8aW50NjQ+KAorICAgICAgbWVzc2FnZSwgdW5pdHRlc3Q6OnJlcGVhdGVkX2ludDY0X2V4dGVuc2lvbiwgMCkpOworCisgIEFTU0VSVF9FUSgzMCwgU3VtQWxsRXh0ZW5zaW9uczx1aW50MzI+KAorICAgICAgbWVzc2FnZSwgdW5pdHRlc3Q6OnJlcGVhdGVkX3VpbnQzMl9leHRlbnNpb24sIDApKTsKKyAgSW5jQWxsRXh0ZW5zaW9uczx1aW50MzI+KAorICAgICAgJm1lc3NhZ2UsIHVuaXR0ZXN0OjpyZXBlYXRlZF91aW50MzJfZXh0ZW5zaW9uLCAxKTsKKyAgQVNTRVJUX0VRKDQwLCBTdW1BbGxFeHRlbnNpb25zPHVpbnQzMj4oCisgICAgICBtZXNzYWdlLCB1bml0dGVzdDo6cmVwZWF0ZWRfdWludDMyX2V4dGVuc2lvbiwgMCkpOworCisgIEFTU0VSVF9FUSg0MCwgU3VtQWxsRXh0ZW5zaW9uczx1aW50NjQ+KAorICAgICAgbWVzc2FnZSwgdW5pdHRlc3Q6OnJlcGVhdGVkX3VpbnQ2NF9leHRlbnNpb24sIDApKTsKKyAgSW5jQWxsRXh0ZW5zaW9uczx1aW50NjQ+KAorICAgICAgJm1lc3NhZ2UsIHVuaXR0ZXN0OjpyZXBlYXRlZF91aW50NjRfZXh0ZW5zaW9uLCAxKTsKKyAgQVNTRVJUX0VRKDUwLCBTdW1BbGxFeHRlbnNpb25zPHVpbnQ2ND4oCisgICAgICBtZXNzYWdlLCB1bml0dGVzdDo6cmVwZWF0ZWRfdWludDY0X2V4dGVuc2lvbiwgMCkpOworCisgIEFTU0VSVF9FUSg1MCwgU3VtQWxsRXh0ZW5zaW9uczxpbnQzMj4oCisgICAgICBtZXNzYWdlLCB1bml0dGVzdDo6cmVwZWF0ZWRfc2ludDMyX2V4dGVuc2lvbiwgMCkpOworICBJbmNBbGxFeHRlbnNpb25zPGludDMyPigKKyAgICAgICZtZXNzYWdlLCB1bml0dGVzdDo6cmVwZWF0ZWRfc2ludDMyX2V4dGVuc2lvbiwgMSk7CisgIEFTU0VSVF9FUSg2MCwgU3VtQWxsRXh0ZW5zaW9uczxpbnQzMj4oCisgICAgICBtZXNzYWdlLCB1bml0dGVzdDo6cmVwZWF0ZWRfc2ludDMyX2V4dGVuc2lvbiwgMCkpOworCisgIEFTU0VSVF9FUSg2MCwgU3VtQWxsRXh0ZW5zaW9uczxpbnQ2ND4oCisgICAgICBtZXNzYWdlLCB1bml0dGVzdDo6cmVwZWF0ZWRfc2ludDY0X2V4dGVuc2lvbiwgMCkpOworICBJbmNBbGxFeHRlbnNpb25zPGludDY0PigKKyAgICAgICZtZXNzYWdlLCB1bml0dGVzdDo6cmVwZWF0ZWRfc2ludDY0X2V4dGVuc2lvbiwgMSk7CisgIEFTU0VSVF9FUSg3MCwgU3VtQWxsRXh0ZW5zaW9uczxpbnQ2ND4oCisgICAgICBtZXNzYWdlLCB1bml0dGVzdDo6cmVwZWF0ZWRfc2ludDY0X2V4dGVuc2lvbiwgMCkpOworCisgIEFTU0VSVF9FUSg3MCwgU3VtQWxsRXh0ZW5zaW9uczx1aW50MzI+KAorICAgICAgbWVzc2FnZSwgdW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkMzJfZXh0ZW5zaW9uLCAwKSk7CisgIEluY0FsbEV4dGVuc2lvbnM8dWludDMyPigKKyAgICAgICZtZXNzYWdlLCB1bml0dGVzdDo6cmVwZWF0ZWRfZml4ZWQzMl9leHRlbnNpb24sIDEpOworICBBU1NFUlRfRVEoODAsIFN1bUFsbEV4dGVuc2lvbnM8dWludDMyPigKKyAgICAgIG1lc3NhZ2UsIHVuaXR0ZXN0OjpyZXBlYXRlZF9maXhlZDMyX2V4dGVuc2lvbiwgMCkpOworCisgIEFTU0VSVF9FUSg4MCwgU3VtQWxsRXh0ZW5zaW9uczx1aW50NjQ+KAorICAgICAgbWVzc2FnZSwgdW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkNjRfZXh0ZW5zaW9uLCAwKSk7CisgIEluY0FsbEV4dGVuc2lvbnM8dWludDY0PigKKyAgICAgICZtZXNzYWdlLCB1bml0dGVzdDo6cmVwZWF0ZWRfZml4ZWQ2NF9leHRlbnNpb24sIDEpOworICBBU1NFUlRfRVEoOTAsIFN1bUFsbEV4dGVuc2lvbnM8dWludDY0PigKKyAgICAgIG1lc3NhZ2UsIHVuaXR0ZXN0OjpyZXBlYXRlZF9maXhlZDY0X2V4dGVuc2lvbiwgMCkpOworCisgIC8vIFVzdWFsbHksIGZsb2F0aW5nLXBvaW50IGFyaXRobWV0aWMgY2Fubm90IGJlIHRydXN0ZWQgdG8gYmUgZXhhY3QsIHNvIGl0IGlzCisgIC8vIGEgQmFkIElkZWEgdG8gYXNzZXJ0IGVxdWFsaXR5IGluIGEgdGVzdCBsaWtlIHRoaXMuIEhvd2V2ZXIsIHdlJ3JlIGRlYWxpbmcKKyAgLy8gd2l0aCBpbnRlZ2VycyB3aXRoIGEgc21hbGwgbnVtYmVyIG9mIHNpZ25pZmljYW50IG1hbnRpc3NhIGJpdHMsIHNvIHdlCisgIC8vIHNob3VsZCBhY3R1YWxseSBoYXZlIGV4YWN0IHByZWNpc2lvbiBoZXJlLgorICBBU1NFUlRfRVEoOTAsIFN1bUFsbEV4dGVuc2lvbnM8ZmxvYXQ+KAorICAgICAgbWVzc2FnZSwgdW5pdHRlc3Q6OnJlcGVhdGVkX2Zsb2F0X2V4dGVuc2lvbiwgMCkpOworICBJbmNBbGxFeHRlbnNpb25zPGZsb2F0PigKKyAgICAgICZtZXNzYWdlLCB1bml0dGVzdDo6cmVwZWF0ZWRfZmxvYXRfZXh0ZW5zaW9uLCAxKTsKKyAgQVNTRVJUX0VRKDEwMCwgU3VtQWxsRXh0ZW5zaW9uczxmbG9hdD4oCisgICAgICBtZXNzYWdlLCB1bml0dGVzdDo6cmVwZWF0ZWRfZmxvYXRfZXh0ZW5zaW9uLCAwKSk7CisKKyAgQVNTRVJUX0VRKDEwMCwgU3VtQWxsRXh0ZW5zaW9uczxkb3VibGU+KAorICAgICAgbWVzc2FnZSwgdW5pdHRlc3Q6OnJlcGVhdGVkX2RvdWJsZV9leHRlbnNpb24sIDApKTsKKyAgSW5jQWxsRXh0ZW5zaW9uczxkb3VibGU+KAorICAgICAgJm1lc3NhZ2UsIHVuaXR0ZXN0OjpyZXBlYXRlZF9kb3VibGVfZXh0ZW5zaW9uLCAxKTsKKyAgQVNTRVJUX0VRKDExMCwgU3VtQWxsRXh0ZW5zaW9uczxkb3VibGU+KAorICAgICAgbWVzc2FnZSwgdW5pdHRlc3Q6OnJlcGVhdGVkX2RvdWJsZV9leHRlbnNpb24sIDApKTsKKworICBSZXBlYXRlZFB0ckZpZWxkPCA6OnN0ZDo6c3RyaW5nPjo6aXRlcmF0b3Igc3RyaW5nX2l0ZXI7CisgIFJlcGVhdGVkUHRyRmllbGQ8IDo6c3RkOjpzdHJpbmc+OjppdGVyYXRvciBzdHJpbmdfZW5kOworICBmb3IgKHN0cmluZ19pdGVyID0gbWVzc2FnZS5NdXRhYmxlUmVwZWF0ZWRFeHRlbnNpb24oCisgICAgICAgICAgdW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb24pLT5iZWdpbigpLAorICAgICAgIHN0cmluZ19lbmQgID0gbWVzc2FnZS5NdXRhYmxlUmVwZWF0ZWRFeHRlbnNpb24oCisgICAgICAgICAgIHVuaXR0ZXN0OjpyZXBlYXRlZF9zdHJpbmdfZXh0ZW5zaW9uKS0+ZW5kKCk7CisgICAgICAgc3RyaW5nX2l0ZXIgIT0gc3RyaW5nX2VuZDsgKytzdHJpbmdfaXRlcikgeworICAgICpzdHJpbmdfaXRlciArPSAidGVzdCI7CisgIH0KKyAgUmVwZWF0ZWRQdHJGaWVsZDwgOjpzdGQ6OnN0cmluZz46OmNvbnN0X2l0ZXJhdG9yIHN0cmluZ19jb25zdF9pdGVyOworICBSZXBlYXRlZFB0ckZpZWxkPCA6OnN0ZDo6c3RyaW5nPjo6Y29uc3RfaXRlcmF0b3Igc3RyaW5nX2NvbnN0X2VuZDsKKyAgZm9yIChzdHJpbmdfY29uc3RfaXRlciA9IG1lc3NhZ2UuR2V0UmVwZWF0ZWRFeHRlbnNpb24oCisgICAgICAgICAgIHVuaXR0ZXN0OjpyZXBlYXRlZF9zdHJpbmdfZXh0ZW5zaW9uKS5iZWdpbigpLAorICAgICAgIHN0cmluZ19jb25zdF9lbmQgID0gbWVzc2FnZS5HZXRSZXBlYXRlZEV4dGVuc2lvbigKKyAgICAgICAgICAgdW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb24pLmVuZCgpOworICAgICAgIHN0cmluZ19pdGVyICE9IHN0cmluZ19lbmQ7ICsrc3RyaW5nX2l0ZXIpIHsKKyAgICBBU1NFUlRfVFJVRSgqc3RyaW5nX2l0ZXIgPT0gInRlc3R0ZXN0Iik7CisgIH0KKworICBSZXBlYXRlZEZpZWxkPHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXNfTmVzdGVkRW51bT46Oml0ZXJhdG9yIGVudW1faXRlcjsKKyAgUmVwZWF0ZWRGaWVsZDx1bml0dGVzdDo6VGVzdEFsbFR5cGVzX05lc3RlZEVudW0+OjppdGVyYXRvciBlbnVtX2VuZDsKKyAgZm9yIChlbnVtX2l0ZXIgPSBtZXNzYWdlLk11dGFibGVSZXBlYXRlZEV4dGVuc2lvbigKKyAgICAgICAgICAgdW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9lbnVtX2V4dGVuc2lvbiktPmJlZ2luKCksCisgICAgICAgZW51bV9lbmQgID0gbWVzc2FnZS5NdXRhYmxlUmVwZWF0ZWRFeHRlbnNpb24oCisgICAgICAgICAgIHVuaXR0ZXN0OjpyZXBlYXRlZF9uZXN0ZWRfZW51bV9leHRlbnNpb24pLT5lbmQoKTsKKyAgICAgICBlbnVtX2l0ZXIgIT0gZW51bV9lbmQ7ICsrZW51bV9pdGVyKSB7CisgICAgKmVudW1faXRlciA9IHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5lc3RlZEVudW1fTUFYOworICB9CisgIFJlcGVhdGVkRmllbGQ8dW5pdHRlc3Q6OlRlc3RBbGxUeXBlc19OZXN0ZWRFbnVtPjo6Y29uc3RfaXRlcmF0b3IKKyAgICAgIGVudW1fY29uc3RfaXRlcjsKKyAgUmVwZWF0ZWRGaWVsZDx1bml0dGVzdDo6VGVzdEFsbFR5cGVzX05lc3RlZEVudW0+Ojpjb25zdF9pdGVyYXRvcgorICAgICAgZW51bV9jb25zdF9lbmQ7CisgIGZvciAoZW51bV9jb25zdF9pdGVyID0gbWVzc2FnZS5HZXRSZXBlYXRlZEV4dGVuc2lvbigKKyAgICAgICAgICAgdW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9lbnVtX2V4dGVuc2lvbikuYmVnaW4oKSwKKyAgICAgICBlbnVtX2NvbnN0X2VuZCAgPSBtZXNzYWdlLkdldFJlcGVhdGVkRXh0ZW5zaW9uKAorICAgICAgICAgICB1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uKS5lbmQoKTsKKyAgICAgICBlbnVtX2l0ZXIgIT0gZW51bV9lbmQ7ICsrZW51bV9pdGVyKSB7CisgICAgQVNTRVJUX0VRKCplbnVtX2NvbnN0X2l0ZXIsIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5lc3RlZEVudW1fTUFYKTsKKyAgfQorCisgIFJlcGVhdGVkUHRyRmllbGQ8dW5pdHRlc3Q6OlRlc3RBbGxUeXBlc19OZXN0ZWRNZXNzYWdlPjo6aXRlcmF0b3IKKyAgICAgIG1zZ19pdGVyOworICBSZXBlYXRlZFB0ckZpZWxkPHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXNfTmVzdGVkTWVzc2FnZT46Oml0ZXJhdG9yCisgICAgICBtc2dfZW5kOworICBmb3IgKG1zZ19pdGVyID0gbWVzc2FnZS5NdXRhYmxlUmVwZWF0ZWRFeHRlbnNpb24oCisgICAgICAgICAgIHVuaXR0ZXN0OjpyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb24pLT5iZWdpbigpLAorICAgICAgIG1zZ19lbmQgID0gbWVzc2FnZS5NdXRhYmxlUmVwZWF0ZWRFeHRlbnNpb24oCisgICAgICAgICAgIHVuaXR0ZXN0OjpyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb24pLT5lbmQoKTsKKyAgICAgICBtc2dfaXRlciAhPSBtc2dfZW5kOyArK21zZ19pdGVyKSB7CisgICAgbXNnX2l0ZXItPnNldF9iYigxMjM0KTsKKyAgfQorICBSZXBlYXRlZFB0ckZpZWxkPHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXNfTmVzdGVkTWVzc2FnZT46OgorICAgICAgY29uc3RfaXRlcmF0b3IgbXNnX2NvbnN0X2l0ZXI7CisgIFJlcGVhdGVkUHRyRmllbGQ8dW5pdHRlc3Q6OlRlc3RBbGxUeXBlc19OZXN0ZWRNZXNzYWdlPjo6CisgICAgICBjb25zdF9pdGVyYXRvciBtc2dfY29uc3RfZW5kOworICBmb3IgKG1zZ19jb25zdF9pdGVyID0gbWVzc2FnZS5HZXRSZXBlYXRlZEV4dGVuc2lvbigKKyAgICAgICAgICAgdW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbikuYmVnaW4oKSwKKyAgICAgICBtc2dfY29uc3RfZW5kICA9IG1lc3NhZ2UuR2V0UmVwZWF0ZWRFeHRlbnNpb24oCisgICAgICAgICAgIHVuaXR0ZXN0OjpyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb24pLmVuZCgpOworICAgICAgIG1zZ19jb25zdF9pdGVyICE9IG1zZ19jb25zdF9lbmQ7ICsrbXNnX2NvbnN0X2l0ZXIpIHsKKyAgICBBU1NFUlRfRVEobXNnX2NvbnN0X2l0ZXItPmJiKCksIDEyMzQpOworICB9CisKKyAgLy8gVGVzdCByYW5nZS1iYXNlZCBmb3IgYXMgd2VsbCwgYnV0IG9ubHkgaWYgY29tcGlsZWQgYXMgQysrMTEuCisjaWYgX19jcGx1c3BsdXMgPj0gMjAxMTAzTAorICAvLyBUZXN0IG9uZSBwcmltaXRpdmUgZmllbGQuCisgIGZvciAoYXV0byYgeCA6ICptZXNzYWdlLk11dGFibGVSZXBlYXRlZEV4dGVuc2lvbigKKyAgICAgICAgICB1bml0dGVzdDo6cmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9uKSkgeworICAgIHggPSA0MzIxOworICB9CisgIGZvciAoY29uc3QgYXV0byYgeCA6IG1lc3NhZ2UuR2V0UmVwZWF0ZWRFeHRlbnNpb24oCisgICAgICAgICAgdW5pdHRlc3Q6OnJlcGVhdGVkX2ludDMyX2V4dGVuc2lvbikpIHsKKyAgICBBU1NFUlRfRVEoeCwgNDMyMSk7CisgIH0KKyAgLy8gVGVzdCBvbmUgc3RyaW5nIGZpZWxkLgorICBmb3IgKGF1dG8mIHggOiAqbWVzc2FnZS5NdXRhYmxlUmVwZWF0ZWRFeHRlbnNpb24oCisgICAgICAgICAgdW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb24pKSB7CisgICAgeCA9ICJ0ZXN0X3JhbmdlX2Jhc2VkX2ZvciI7CisgIH0KKyAgZm9yIChjb25zdCBhdXRvJiB4IDogbWVzc2FnZS5HZXRSZXBlYXRlZEV4dGVuc2lvbigKKyAgICAgICAgICB1bml0dGVzdDo6cmVwZWF0ZWRfc3RyaW5nX2V4dGVuc2lvbikpIHsKKyAgICBBU1NFUlRfVFJVRSh4ID09ICJ0ZXN0X3JhbmdlX2Jhc2VkX2ZvciIpOworICB9CisgIC8vIFRlc3Qgb25lIG1lc3NhZ2UgZmllbGQuCisgIGZvciAoYXV0byYgeCA6ICptZXNzYWdlLk11dGFibGVSZXBlYXRlZEV4dGVuc2lvbigKKyAgICAgICAgICB1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uKSkgeworICAgIHguc2V0X2JiKDQzMjEpOworICB9CisgIGZvciAoY29uc3QgYXV0byYgeCA6ICptZXNzYWdlLk11dGFibGVSZXBlYXRlZEV4dGVuc2lvbigKKyAgICAgICAgICB1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uKSkgeworICAgIEFTU0VSVF9FUSh4LmJiKCksIDQzMjEpOworICB9CisjZW5kaWYKK30KKworLy8gRnJvbSBiLzEyOTI2MTYzCitURVNUKEV4dGVuc2lvblNldFRlc3QsIEFic2VudEV4dGVuc2lvbikgeworICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTsKKyAgbWVzc2FnZS5NdXRhYmxlUmVwZWF0ZWRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbikKKyAgICAgIC0+QWRkKCktPnNldF9iYigxMjMpOworICBBU1NFUlRfRVEoMSwgbWVzc2FnZS5FeHRlbnNpb25TaXplKAorICAgICAgdW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbikpOworICBFWFBFQ1RfRVEoCisgICAgICAxMjMsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKAorICAgICAgICAgIHVuaXR0ZXN0OjpyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb24sIDApLmJiKCkpOworfQorCisjaWZkZWYgUFJPVE9CVUZfSEFTX0RFQVRIX1RFU1QKKworVEVTVChFeHRlbnNpb25TZXRUZXN0LCBJbnZhbGlkRW51bURlYXRoKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyBtZXNzYWdlOworICBFWFBFQ1RfREVCVUdfREVBVEgoCisgICAgbWVzc2FnZS5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ZvcmVpZ25fZW51bV9leHRlbnNpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGljX2Nhc3Q8dW5pdHRlc3Q6OkZvcmVpZ25FbnVtPig1MykpLAorICAgICJJc1ZhbGlkIik7Cit9CisKKyNlbmRpZiAgLy8gUFJPVE9CVUZfSEFTX0RFQVRIX1RFU1QKKworVEVTVChFeHRlbnNpb25TZXRUZXN0LCBEeW5hbWljRXh0ZW5zaW9ucykgeworICAvLyBUZXN0IGFkZGluZyBhIGR5bmFtaWMgZXh0ZW5zaW9uIHRvIGEgY29tcGlsZWQtaW4gbWVzc2FnZSBvYmplY3QuCisKKyAgRmlsZURlc2NyaXB0b3JQcm90byBkeW5hbWljX3Byb3RvOworICBkeW5hbWljX3Byb3RvLnNldF9uYW1lKCJkeW5hbWljX2V4dGVuc2lvbnNfdGVzdC5wcm90byIpOworICBkeW5hbWljX3Byb3RvLmFkZF9kZXBlbmRlbmN5KAorICAgICAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zOjpkZXNjcmlwdG9yKCktPmZpbGUoKS0+bmFtZSgpKTsKKyAgZHluYW1pY19wcm90by5zZXRfcGFja2FnZSgiZHluYW1pY19leHRlbnNpb25zIik7CisKKyAgLy8gQ29weSB0aGUgZmllbGRzIGFuZCBuZXN0ZWQgdHlwZXMgZnJvbSBUZXN0RHluYW1pY0V4dGVuc2lvbnMgaW50byBvdXIgbmV3CisgIC8vIHByb3RvLCBjb252ZXJ0aW5nIHRoZSBmaWVsZHMgaW50byBleHRlbnNpb25zLgorICBjb25zdCBEZXNjcmlwdG9yKiB0ZW1wbGF0ZV9kZXNjcmlwdG9yID0KKyAgICAgIHVuaXR0ZXN0OjpUZXN0RHluYW1pY0V4dGVuc2lvbnM6OmRlc2NyaXB0b3IoKTsKKyAgRGVzY3JpcHRvclByb3RvIHRlbXBsYXRlX2Rlc2NyaXB0b3JfcHJvdG87CisgIHRlbXBsYXRlX2Rlc2NyaXB0b3ItPkNvcHlUbygmdGVtcGxhdGVfZGVzY3JpcHRvcl9wcm90byk7CisgIGR5bmFtaWNfcHJvdG8ubXV0YWJsZV9tZXNzYWdlX3R5cGUoKS0+TWVyZ2VGcm9tKAorICAgICAgdGVtcGxhdGVfZGVzY3JpcHRvcl9wcm90by5uZXN0ZWRfdHlwZSgpKTsKKyAgZHluYW1pY19wcm90by5tdXRhYmxlX2VudW1fdHlwZSgpLT5NZXJnZUZyb20oCisgICAgICB0ZW1wbGF0ZV9kZXNjcmlwdG9yX3Byb3RvLmVudW1fdHlwZSgpKTsKKyAgZHluYW1pY19wcm90by5tdXRhYmxlX2V4dGVuc2lvbigpLT5NZXJnZUZyb20oCisgICAgICB0ZW1wbGF0ZV9kZXNjcmlwdG9yX3Byb3RvLmZpZWxkKCkpOworCisgIC8vIEZvciBlYWNoIGV4dGVuc2lvbiB0aGF0IHdlIGFkZGVkLi4uCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZHluYW1pY19wcm90by5leHRlbnNpb25fc2l6ZSgpOyBpKyspIHsKKyAgICAvLyBTZXQgaXRzIGV4dGVuZGVlIHRvIFRlc3RBbGxFeHRlbnNpb25zLgorICAgIEZpZWxkRGVzY3JpcHRvclByb3RvKiBleHRlbnNpb24gPSBkeW5hbWljX3Byb3RvLm11dGFibGVfZXh0ZW5zaW9uKGkpOworICAgIGV4dGVuc2lvbi0+c2V0X2V4dGVuZGVlKAorICAgICAgICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnM6OmRlc2NyaXB0b3IoKS0+ZnVsbF9uYW1lKCkpOworCisgICAgLy8gSWYgdGhlIGZpZWxkIHJlZmVycyB0byBvbmUgb2YgdGhlIHR5cGVzIG5lc3RlZCBpbiBUZXN0RHluYW1pY0V4dGVuc2lvbnMsCisgICAgLy8gbWFrZSBpdCByZWZlciB0byB0aGUgdHlwZSBpbiBvdXIgZHluYW1pYyBwcm90byBpbnN0ZWFkLgorICAgIHN0cmluZyBwcmVmaXggPSAiLiIgKyB0ZW1wbGF0ZV9kZXNjcmlwdG9yLT5mdWxsX25hbWUoKSArICIuIjsKKyAgICBpZiAoZXh0ZW5zaW9uLT5oYXNfdHlwZV9uYW1lKCkpIHsKKyAgICAgIHN0cmluZyogdHlwZV9uYW1lID0gZXh0ZW5zaW9uLT5tdXRhYmxlX3R5cGVfbmFtZSgpOworICAgICAgaWYgKEhhc1ByZWZpeFN0cmluZygqdHlwZV9uYW1lLCBwcmVmaXgpKSB7CisgICAgICAgIHR5cGVfbmFtZS0+cmVwbGFjZSgwLCBwcmVmaXguc2l6ZSgpLCAiLmR5bmFtaWNfZXh0ZW5zaW9ucy4iKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvLyBOb3cgYnVpbGQgdGhlIGZpbGUsIHVzaW5nIHRoZSBnZW5lcmF0ZWQgcG9vbCBhcyBhbiB1bmRlcmxheS4KKyAgRGVzY3JpcHRvclBvb2wgZHluYW1pY19wb29sKERlc2NyaXB0b3JQb29sOjpnZW5lcmF0ZWRfcG9vbCgpKTsKKyAgY29uc3QgRmlsZURlc2NyaXB0b3IqIGZpbGUgPSBkeW5hbWljX3Bvb2wuQnVpbGRGaWxlKGR5bmFtaWNfcHJvdG8pOworICBBU1NFUlRfVFJVRShmaWxlICE9IE5VTEwpOworICBEeW5hbWljTWVzc2FnZUZhY3RvcnkgZHluYW1pY19mYWN0b3J5KCZkeW5hbWljX3Bvb2wpOworICBkeW5hbWljX2ZhY3RvcnkuU2V0RGVsZWdhdGVUb0dlbmVyYXRlZEZhY3RvcnkodHJ1ZSk7CisKKyAgLy8gQ29uc3RydWN0IGEgbWVzc2FnZSB0aGF0IHdlIGNhbiBwYXJzZSB3aXRoIHRoZSBleHRlbnNpb25zIHdlIGRlZmluZWQuCisgIC8vIFNpbmNlIHRoZSBleHRlbnNpb25zIHdlcmUgYmFzZWQgb2ZmIG9mIHRoZSBmaWVsZHMgb2YgVGVzdER5bmFtaWNFeHRlbnNpb25zLAorICAvLyB3ZSBjYW4gdXNlIHRoYXQgbWVzc2FnZSB0byBjcmVhdGUgdGhpcyB0ZXN0IG1lc3NhZ2UuCisgIHN0cmluZyBkYXRhOworICB7CisgICAgdW5pdHRlc3Q6OlRlc3REeW5hbWljRXh0ZW5zaW9ucyBtZXNzYWdlOworICAgIG1lc3NhZ2Uuc2V0X3NjYWxhcl9leHRlbnNpb24oMTIzKTsKKyAgICBtZXNzYWdlLnNldF9lbnVtX2V4dGVuc2lvbih1bml0dGVzdDo6Rk9SRUlHTl9CQVIpOworICAgIG1lc3NhZ2Uuc2V0X2R5bmFtaWNfZW51bV9leHRlbnNpb24oCisgICAgICAgIHVuaXR0ZXN0OjpUZXN0RHluYW1pY0V4dGVuc2lvbnM6OkRZTkFNSUNfQkFaKTsKKyAgICBtZXNzYWdlLm11dGFibGVfbWVzc2FnZV9leHRlbnNpb24oKS0+c2V0X2MoNDU2KTsKKyAgICBtZXNzYWdlLm11dGFibGVfZHluYW1pY19tZXNzYWdlX2V4dGVuc2lvbigpLT5zZXRfZHluYW1pY19maWVsZCg3ODkpOworICAgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX2V4dGVuc2lvbigiZm9vIik7CisgICAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZXh0ZW5zaW9uKCJiYXIiKTsKKyAgICBtZXNzYWdlLmFkZF9wYWNrZWRfZXh0ZW5zaW9uKDEyKTsKKyAgICBtZXNzYWdlLmFkZF9wYWNrZWRfZXh0ZW5zaW9uKC0zNCk7CisgICAgbWVzc2FnZS5hZGRfcGFja2VkX2V4dGVuc2lvbig1Nik7CisgICAgbWVzc2FnZS5hZGRfcGFja2VkX2V4dGVuc2lvbigtNzgpOworCisgICAgLy8gQWxzbyBhZGQgc29tZSB1bmtub3duIGZpZWxkcy4KKworICAgIC8vIEFuIHVua25vd24gZW51bSB2YWx1ZSAoZm9yIGEga25vd24gZmllbGQpLgorICAgIG1lc3NhZ2UubXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5BZGRWYXJpbnQoCisgICAgICB1bml0dGVzdDo6VGVzdER5bmFtaWNFeHRlbnNpb25zOjprRHluYW1pY0VudW1FeHRlbnNpb25GaWVsZE51bWJlciwKKyAgICAgIDEyMzQ1KTsKKyAgICAvLyBBIHJlZ3VsYXIgdW5rbm93biBmaWVsZC4KKyAgICBtZXNzYWdlLm11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+QWRkTGVuZ3RoRGVsaW1pdGVkKDU0MzIxLCAidW5rbm93biIpOworCisgICAgbWVzc2FnZS5TZXJpYWxpemVUb1N0cmluZygmZGF0YSk7CisgIH0KKworICAvLyBOb3cgd2UgY2FuIHBhcnNlIHRoaXMgdXNpbmcgb3VyIGR5bmFtaWMgZXh0ZW5zaW9uIGRlZmluaXRpb25zLi4uCisgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyBtZXNzYWdlOworICB7CisgICAgaW86OkFycmF5SW5wdXRTdHJlYW0gcmF3X2lucHV0KGRhdGEuZGF0YSgpLCBkYXRhLnNpemUoKSk7CisgICAgaW86OkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQoJnJhd19pbnB1dCk7CisgICAgaW5wdXQuU2V0RXh0ZW5zaW9uUmVnaXN0cnkoJmR5bmFtaWNfcG9vbCwgJmR5bmFtaWNfZmFjdG9yeSk7CisgICAgQVNTRVJUX1RSVUUobWVzc2FnZS5QYXJzZUZyb21Db2RlZFN0cmVhbSgmaW5wdXQpKTsKKyAgICBBU1NFUlRfVFJVRShpbnB1dC5Db25zdW1lZEVudGlyZU1lc3NhZ2UoKSk7CisgIH0KKworICAvLyBDYW4gd2UgcHJpbnQgaXQ/CisgIEVYUEVDVF9FUSgKKyAgICAiW2R5bmFtaWNfZXh0ZW5zaW9ucy5zY2FsYXJfZXh0ZW5zaW9uXTogMTIzXG4iCisgICAgIltkeW5hbWljX2V4dGVuc2lvbnMuZW51bV9leHRlbnNpb25dOiBGT1JFSUdOX0JBUlxuIgorICAgICJbZHluYW1pY19leHRlbnNpb25zLmR5bmFtaWNfZW51bV9leHRlbnNpb25dOiBEWU5BTUlDX0JBWlxuIgorICAgICJbZHluYW1pY19leHRlbnNpb25zLm1lc3NhZ2VfZXh0ZW5zaW9uXSB7XG4iCisgICAgIiAgYzogNDU2XG4iCisgICAgIn1cbiIKKyAgICAiW2R5bmFtaWNfZXh0ZW5zaW9ucy5keW5hbWljX21lc3NhZ2VfZXh0ZW5zaW9uXSB7XG4iCisgICAgIiAgZHluYW1pY19maWVsZDogNzg5XG4iCisgICAgIn1cbiIKKyAgICAiW2R5bmFtaWNfZXh0ZW5zaW9ucy5yZXBlYXRlZF9leHRlbnNpb25dOiBcImZvb1wiXG4iCisgICAgIltkeW5hbWljX2V4dGVuc2lvbnMucmVwZWF0ZWRfZXh0ZW5zaW9uXTogXCJiYXJcIlxuIgorICAgICJbZHluYW1pY19leHRlbnNpb25zLnBhY2tlZF9leHRlbnNpb25dOiAxMlxuIgorICAgICJbZHluYW1pY19leHRlbnNpb25zLnBhY2tlZF9leHRlbnNpb25dOiAtMzRcbiIKKyAgICAiW2R5bmFtaWNfZXh0ZW5zaW9ucy5wYWNrZWRfZXh0ZW5zaW9uXTogNTZcbiIKKyAgICAiW2R5bmFtaWNfZXh0ZW5zaW9ucy5wYWNrZWRfZXh0ZW5zaW9uXTogLTc4XG4iCisgICAgIjIwMDI6IDEyMzQ1XG4iCisgICAgIjU0MzIxOiBcInVua25vd25cIlxuIiwKKyAgICBtZXNzYWdlLkRlYnVnU3RyaW5nKCkpOworCisgIC8vIENhbiB3ZSBzZXJpYWxpemUgaXQ/CisgIC8vIChEb24ndCB1c2UgRVhQRUNUX0VRIGJlY2F1c2Ugd2UgZG9uJ3Qgd2FudCB0byBkdW1wIHJhdyBiaW5hcnkgZGF0YSB0byB0aGUKKyAgLy8gdGVybWluYWwgb24gZmFpbHVyZS4pCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuU2VyaWFsaXplQXNTdHJpbmcoKSA9PSBkYXRhKTsKKworICAvLyBXaGF0IGlmIHdlIHBhcnNlIHVzaW5nIHRoZSByZWZsZWN0aW9uLWJhc2VkIHBhcnNlcj8KKyAgeworICAgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyBtZXNzYWdlMjsKKyAgICBpbzo6QXJyYXlJbnB1dFN0cmVhbSByYXdfaW5wdXQoZGF0YS5kYXRhKCksIGRhdGEuc2l6ZSgpKTsKKyAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSBpbnB1dCgmcmF3X2lucHV0KTsKKyAgICBpbnB1dC5TZXRFeHRlbnNpb25SZWdpc3RyeSgmZHluYW1pY19wb29sLCAmZHluYW1pY19mYWN0b3J5KTsKKyAgICBBU1NFUlRfVFJVRShXaXJlRm9ybWF0OjpQYXJzZUFuZE1lcmdlUGFydGlhbCgmaW5wdXQsICZtZXNzYWdlMikpOworICAgIEFTU0VSVF9UUlVFKGlucHV0LkNvbnN1bWVkRW50aXJlTWVzc2FnZSgpKTsKKyAgICBFWFBFQ1RfRVEobWVzc2FnZS5EZWJ1Z1N0cmluZygpLCBtZXNzYWdlMi5EZWJ1Z1N0cmluZygpKTsKKyAgfQorCisgIC8vIEFyZSB0aGUgZW1iZWRkZWQgZ2VuZXJhdGVkIHR5cGVzIGFjdHVhbGx5IHVzaW5nIHRoZSBnZW5lcmF0ZWQgb2JqZWN0cz8KKyAgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogbWVzc2FnZV9leHRlbnNpb24gPQorICAgICAgICBmaWxlLT5GaW5kRXh0ZW5zaW9uQnlOYW1lKCJtZXNzYWdlX2V4dGVuc2lvbiIpOworICAgIEFTU0VSVF9UUlVFKG1lc3NhZ2VfZXh0ZW5zaW9uICE9IE5VTEwpOworICAgIGNvbnN0IE1lc3NhZ2UmIHN1Yl9tZXNzYWdlID0KKyAgICAgICAgbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPkdldE1lc3NhZ2UobWVzc2FnZSwgbWVzc2FnZV9leHRlbnNpb24pOworICAgIGNvbnN0IHVuaXR0ZXN0OjpGb3JlaWduTWVzc2FnZSogdHlwZWRfc3ViX21lc3NhZ2UgPQorI2lmZGVmIEdPT0dMRV9QUk9UT0JVRl9OT19SVFRJCisgICAgICAgIHN0YXRpY19jYXN0PGNvbnN0IHVuaXR0ZXN0OjpGb3JlaWduTWVzc2FnZSo+KCZzdWJfbWVzc2FnZSk7CisjZWxzZQorICAgICAgICBkeW5hbWljX2Nhc3Q8Y29uc3QgdW5pdHRlc3Q6OkZvcmVpZ25NZXNzYWdlKj4oJnN1Yl9tZXNzYWdlKTsKKyNlbmRpZgorICAgIEFTU0VSVF9UUlVFKHR5cGVkX3N1Yl9tZXNzYWdlICE9IE5VTEwpOworICAgIEVYUEVDVF9FUSg0NTYsIHR5cGVkX3N1Yl9tZXNzYWdlLT5jKCkpOworICB9CisKKyAgLy8gV2hhdCBkb2VzIEdldE1lc3NhZ2UoKSByZXR1cm4gZm9yIHRoZSBlbWJlZGRlZCBkeW5hbWljIHR5cGUgaWYgaXQgaXNuJ3QKKyAgLy8gcHJlc2VudD8KKyAgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZHluYW1pY19tZXNzYWdlX2V4dGVuc2lvbiA9CisgICAgICAgIGZpbGUtPkZpbmRFeHRlbnNpb25CeU5hbWUoImR5bmFtaWNfbWVzc2FnZV9leHRlbnNpb24iKTsKKyAgICBBU1NFUlRfVFJVRShkeW5hbWljX21lc3NhZ2VfZXh0ZW5zaW9uICE9IE5VTEwpOworICAgIGNvbnN0IE1lc3NhZ2UmIHBhcmVudCA9IHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9uczo6ZGVmYXVsdF9pbnN0YW5jZSgpOworICAgIGNvbnN0IE1lc3NhZ2UmIHN1Yl9tZXNzYWdlID0KKyAgICAgICAgcGFyZW50LkdldFJlZmxlY3Rpb24oKS0+R2V0TWVzc2FnZShwYXJlbnQsIGR5bmFtaWNfbWVzc2FnZV9leHRlbnNpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmR5bmFtaWNfZmFjdG9yeSk7CisgICAgY29uc3QgTWVzc2FnZSogcHJvdG90eXBlID0KKyAgICAgICAgZHluYW1pY19mYWN0b3J5LkdldFByb3RvdHlwZShkeW5hbWljX21lc3NhZ2VfZXh0ZW5zaW9uLT5tZXNzYWdlX3R5cGUoKSk7CisgICAgRVhQRUNUX0VRKHByb3RvdHlwZSwgJnN1Yl9tZXNzYWdlKTsKKyAgfQorfQorCit9ICAvLyBuYW1lc3BhY2UKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2ZpZWxkX21hc2sucGIuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2ZpZWxkX21hc2sucGIuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDFhNmNlNQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvZmllbGRfbWFzay5wYi5jYwpAQCAtMCwwICsxLDM5NiBAQAorLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCEKKy8vIHNvdXJjZTogZ29vZ2xlL3Byb3RvYnVmL2ZpZWxkX21hc2sucHJvdG8KKworI2RlZmluZSBJTlRFUk5BTF9TVVBQUkVTU19QUk9UT0JVRl9GSUVMRF9ERVBSRUNBVElPTgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9maWVsZF9tYXNrLnBiLmg+CisKKyNpbmNsdWRlIDxhbGdvcml0aG0+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3BvcnQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvb25jZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZV9pbmwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfbWVzc2FnZV9yZWZsZWN0aW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3JlZmxlY3Rpb25fb3BzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0Lmg+CisvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW5jbHVkZXMpCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworbmFtZXNwYWNlIHsKKworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBGaWVsZE1hc2tfZGVzY3JpcHRvcl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24qCisgIEZpZWxkTWFza19yZWZsZWN0aW9uXyA9IE5VTEw7CisKK30gIC8vIG5hbWVzcGFjZQorCisKK3ZvaWQgcHJvdG9idWZfQXNzaWduRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmZpZWxkXzVmbWFza18yZXByb3RvKCkgeworICBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZmllbGRfNWZtYXNrXzJlcHJvdG8oKTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlRGVzY3JpcHRvciogZmlsZSA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUG9vbDo6Z2VuZXJhdGVkX3Bvb2woKS0+RmluZEZpbGVCeU5hbWUoCisgICAgICAiZ29vZ2xlL3Byb3RvYnVmL2ZpZWxkX21hc2sucHJvdG8iKTsKKyAgR09PR0xFX0NIRUNLKGZpbGUgIT0gTlVMTCk7CisgIEZpZWxkTWFza19kZXNjcmlwdG9yXyA9IGZpbGUtPm1lc3NhZ2VfdHlwZSgwKTsKKyAgc3RhdGljIGNvbnN0IGludCBGaWVsZE1hc2tfb2Zmc2V0c19bMV0gPSB7CisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWVsZE1hc2ssIHBhdGhzXyksCisgIH07CisgIEZpZWxkTWFza19yZWZsZWN0aW9uXyA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok5ld0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKAorICAgICAgRmllbGRNYXNrX2Rlc2NyaXB0b3JfLAorICAgICAgRmllbGRNYXNrOjpkZWZhdWx0X2luc3RhbmNlXywKKyAgICAgIEZpZWxkTWFza19vZmZzZXRzXywKKyAgICAgIC0xLAorICAgICAgLTEsCisgICAgICAtMSwKKyAgICAgIHNpemVvZihGaWVsZE1hc2spLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWVsZE1hc2ssIF9pbnRlcm5hbF9tZXRhZGF0YV8pLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWVsZE1hc2ssIF9pc19kZWZhdWx0X2luc3RhbmNlXykpOworfQorCituYW1lc3BhY2UgeworCitHT09HTEVfUFJPVE9CVUZfREVDTEFSRV9PTkNFKHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzX29uY2VfKTsKK2lubGluZSB2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpIHsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpHb29nbGVPbmNlSW5pdCgmcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNfb25jZV8sCisgICAgICAgICAgICAgICAgICZwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZmllbGRfNWZtYXNrXzJlcHJvdG8pOworfQorCit2b2lkIHByb3RvYnVmX1JlZ2lzdGVyVHlwZXMoY29uc3QgOjpzdGQ6OnN0cmluZyYpIHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZUZhY3Rvcnk6OkludGVybmFsUmVnaXN0ZXJHZW5lcmF0ZWRNZXNzYWdlKAorICAgICAgRmllbGRNYXNrX2Rlc2NyaXB0b3JfLCAmRmllbGRNYXNrOjpkZWZhdWx0X2luc3RhbmNlKCkpOworfQorCit9ICAvLyBuYW1lc3BhY2UKKwordm9pZCBwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZmaWVsZF81Zm1hc2tfMmVwcm90bygpIHsKKyAgZGVsZXRlIEZpZWxkTWFzazo6ZGVmYXVsdF9pbnN0YW5jZV87CisgIGRlbGV0ZSBGaWVsZE1hc2tfcmVmbGVjdGlvbl87Cit9CisKK3ZvaWQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmZpZWxkXzVmbWFza18yZXByb3RvKCkgeworICBzdGF0aWMgYm9vbCBhbHJlYWR5X2hlcmUgPSBmYWxzZTsKKyAgaWYgKGFscmVhZHlfaGVyZSkgcmV0dXJuOworICBhbHJlYWR5X2hlcmUgPSB0cnVlOworICBHT09HTEVfUFJPVE9CVUZfVkVSSUZZX1ZFUlNJT047CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUG9vbDo6SW50ZXJuYWxBZGRHZW5lcmF0ZWRGaWxlKAorICAgICJcbiBnb29nbGUvcHJvdG9idWYvZmllbGRfbWFzay5wcm90b1wwMjJcMDE3Z29vZyIKKyAgICAibGUucHJvdG9idWZcIlwwMzJcblx0RmllbGRNYXNrXDAyMlxyXG5cMDA1cGF0aHNcMDMwXDAwMSBcMDAzKFx0QiIKKyAgICAiUVxuXDAyM2NvbS5nb29nbGUucHJvdG9idWZCXDAxNkZpZWxkTWFza1Byb3RvUFwwMDEiCisgICAgIlwyNDBcMDAxXDAwMVwyNDJcMDAyXDAwM0dQQlwyNTJcMDAyXDAzNkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXAiCisgICAgImVzYlwwMDZwcm90bzMiLCAxNzApOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VGYWN0b3J5OjpJbnRlcm5hbFJlZ2lzdGVyR2VuZXJhdGVkRmlsZSgKKyAgICAiZ29vZ2xlL3Byb3RvYnVmL2ZpZWxkX21hc2sucHJvdG8iLCAmcHJvdG9idWZfUmVnaXN0ZXJUeXBlcyk7CisgIEZpZWxkTWFzazo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBuZXcgRmllbGRNYXNrKCk7CisgIEZpZWxkTWFzazo6ZGVmYXVsdF9pbnN0YW5jZV8tPkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpPblNodXRkb3duKCZwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZmaWVsZF81Zm1hc2tfMmVwcm90byk7Cit9CisKKy8vIEZvcmNlIEFkZERlc2NyaXB0b3JzKCkgdG8gYmUgY2FsbGVkIGF0IHN0YXRpYyBpbml0aWFsaXphdGlvbiB0aW1lLgorc3RydWN0IFN0YXRpY0Rlc2NyaXB0b3JJbml0aWFsaXplcl9nb29nbGVfMmZwcm90b2J1Zl8yZmZpZWxkXzVmbWFza18yZXByb3RvIHsKKyAgU3RhdGljRGVzY3JpcHRvckluaXRpYWxpemVyX2dvb2dsZV8yZnByb3RvYnVmXzJmZmllbGRfNWZtYXNrXzJlcHJvdG8oKSB7CisgICAgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmZpZWxkXzVmbWFza18yZXByb3RvKCk7CisgIH0KK30gc3RhdGljX2Rlc2NyaXB0b3JfaW5pdGlhbGl6ZXJfZ29vZ2xlXzJmcHJvdG9idWZfMmZmaWVsZF81Zm1hc2tfMmVwcm90b187CisKK25hbWVzcGFjZSB7CisKK3N0YXRpYyB2b2lkIE1lcmdlRnJvbUZhaWwoaW50IGxpbmUpIEdPT0dMRV9BVFRSSUJVVEVfQ09MRDsKK3N0YXRpYyB2b2lkIE1lcmdlRnJvbUZhaWwoaW50IGxpbmUpIHsKKyAgR09PR0xFX0NIRUNLKGZhbHNlKSA8PCBfX0ZJTEVfXyA8PCAiOiIgPDwgbGluZTsKK30KKworfSAgLy8gbmFtZXNwYWNlCisKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisjaWYgIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKK2NvbnN0IGludCBGaWVsZE1hc2s6OmtQYXRoc0ZpZWxkTnVtYmVyOworI2VuZGlmICAvLyAhZGVmaW5lZChfTVNDX1ZFUikgfHwgX01TQ19WRVIgPj0gMTkwMAorCitGaWVsZE1hc2s6OkZpZWxkTWFzaygpCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgeworICBTaGFyZWRDdG9yKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuRmllbGRNYXNrKQorfQorCit2b2lkIEZpZWxkTWFzazo6SW5pdEFzRGVmYXVsdEluc3RhbmNlKCkgeworICBfaXNfZGVmYXVsdF9pbnN0YW5jZV8gPSB0cnVlOworfQorCitGaWVsZE1hc2s6OkZpZWxkTWFzayhjb25zdCBGaWVsZE1hc2smIGZyb20pCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksCisgICAgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29weV9jb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuRmllbGRNYXNrKQorfQorCit2b2lkIEZpZWxkTWFzazo6U2hhcmVkQ3RvcigpIHsKKyAgICBfaXNfZGVmYXVsdF9pbnN0YW5jZV8gPSBmYWxzZTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmcoKTsKKyAgX2NhY2hlZF9zaXplXyA9IDA7Cit9CisKK0ZpZWxkTWFzazo6fkZpZWxkTWFzaygpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGRlc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzaykKKyAgU2hhcmVkRHRvcigpOworfQorCit2b2lkIEZpZWxkTWFzazo6U2hhcmVkRHRvcigpIHsKKyAgaWYgKHRoaXMgIT0gZGVmYXVsdF9pbnN0YW5jZV8pIHsKKyAgfQorfQorCit2b2lkIEZpZWxkTWFzazo6U2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3QgeworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIEZpZWxkTWFzazo6ZGVzY3JpcHRvcigpIHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIHJldHVybiBGaWVsZE1hc2tfZGVzY3JpcHRvcl87Cit9CisKK2NvbnN0IEZpZWxkTWFzayYgRmllbGRNYXNrOjpkZWZhdWx0X2luc3RhbmNlKCkgeworICBpZiAoZGVmYXVsdF9pbnN0YW5jZV8gPT0gTlVMTCkgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmZpZWxkXzVmbWFza18yZXByb3RvKCk7CisgIHJldHVybiAqZGVmYXVsdF9pbnN0YW5jZV87Cit9CisKK0ZpZWxkTWFzayogRmllbGRNYXNrOjpkZWZhdWx0X2luc3RhbmNlXyA9IE5VTEw7CisKK0ZpZWxkTWFzayogRmllbGRNYXNrOjpOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0IHsKKyAgRmllbGRNYXNrKiBuID0gbmV3IEZpZWxkTWFzazsKKyAgaWYgKGFyZW5hICE9IE5VTEwpIHsKKyAgICBhcmVuYS0+T3duKG4pOworICB9CisgIHJldHVybiBuOworfQorCit2b2lkIEZpZWxkTWFzazo6Q2xlYXIoKSB7CisgIHBhdGhzXy5DbGVhcigpOworfQorCitib29sIEZpZWxkTWFzazo6TWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KSB7CisjZGVmaW5lIERPXyhFWFBSRVNTSU9OKSBpZiAoIShFWFBSRVNTSU9OKSkgZ290byBmYWlsdXJlCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIHRhZzsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2spCisgIGZvciAoOzspIHsKKyAgICA6OnN0ZDo6cGFpcjwgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIsIGJvb2w+IHAgPSBpbnB1dC0+UmVhZFRhZ1dpdGhDdXRvZmYoMTI3KTsKKyAgICB0YWcgPSBwLmZpcnN0OworICAgIGlmICghcC5zZWNvbmQpIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgc3dpdGNoICg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnRmllbGROdW1iZXIodGFnKSkgeworICAgICAgLy8gcmVwZWF0ZWQgc3RyaW5nIHBhdGhzID0gMTsKKyAgICAgIGNhc2UgMTogeworICAgICAgICBpZiAodGFnID09IDEwKSB7CisgICAgICAgICBwYXJzZV9wYXRoczoKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoCisgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPmFkZF9wYXRocygpKSk7CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpWZXJpZnlVdGY4U3RyaW5nKAorICAgICAgICAgICAgdGhpcy0+cGF0aHModGhpcy0+cGF0aHNfc2l6ZSgpIC0gMSkuZGF0YSgpLAorICAgICAgICAgICAgdGhpcy0+cGF0aHModGhpcy0+cGF0aHNfc2l6ZSgpIC0gMSkubGVuZ3RoKCksCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UEFSU0UsCisgICAgICAgICAgICAiZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzay5wYXRocyIpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDEwKSkgZ290byBwYXJzZV9wYXRoczsKKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RBdEVuZCgpKSBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBkZWZhdWx0OiB7CisgICAgICBoYW5kbGVfdW51c3VhbDoKKyAgICAgICAgaWYgKHRhZyA9PSAwIHx8CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnV2lyZVR5cGUodGFnKSA9PQorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0VORF9HUk9VUCkgeworICAgICAgICAgIGdvdG8gc3VjY2VzczsKKyAgICAgICAgfQorICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlNraXBGaWVsZChpbnB1dCwgdGFnKSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgfQorc3VjY2VzczoKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N1Y2Nlc3M6Z29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzaykKKyAgcmV0dXJuIHRydWU7CitmYWlsdXJlOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2VfZmFpbHVyZTpnb29nbGUucHJvdG9idWYuRmllbGRNYXNrKQorICByZXR1cm4gZmFsc2U7CisjdW5kZWYgRE9fCit9CisKK3ZvaWQgRmllbGRNYXNrOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2spCisgIC8vIHJlcGVhdGVkIHN0cmluZyBwYXRocyA9IDE7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+cGF0aHNfc2l6ZSgpOyBpKyspIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VmVyaWZ5VXRmOFN0cmluZygKKyAgICAgIHRoaXMtPnBhdGhzKGkpLmRhdGEoKSwgdGhpcy0+cGF0aHMoaSkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2sucGF0aHMiKTsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmcoCisgICAgICAxLCB0aGlzLT5wYXRocyhpKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfZW5kOmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2spCit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIEZpZWxkTWFzazo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiB0YXJnZXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9zdGFydDpnb29nbGUucHJvdG9idWYuRmllbGRNYXNrKQorICAvLyByZXBlYXRlZCBzdHJpbmcgcGF0aHMgPSAxOworICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPnBhdGhzX3NpemUoKTsgaSsrKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlZlcmlmeVV0ZjhTdHJpbmcoCisgICAgICB0aGlzLT5wYXRocyhpKS5kYXRhKCksIHRoaXMtPnBhdGhzKGkpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuRmllbGRNYXNrLnBhdGhzIik7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OgorICAgICAgV3JpdGVTdHJpbmdUb0FycmF5KDEsIHRoaXMtPnBhdGhzKGkpLCB0YXJnZXQpOworICB9CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9lbmQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzaykKKyAgcmV0dXJuIHRhcmdldDsKK30KKworaW50IEZpZWxkTWFzazo6Qnl0ZVNpemUoKSBjb25zdCB7CisgIGludCB0b3RhbF9zaXplID0gMDsKKworICAvLyByZXBlYXRlZCBzdHJpbmcgcGF0aHMgPSAxOworICB0b3RhbF9zaXplICs9IDEgKiB0aGlzLT5wYXRoc19zaXplKCk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+cGF0aHNfc2l6ZSgpOyBpKyspIHsKKyAgICB0b3RhbF9zaXplICs9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTdHJpbmdTaXplKAorICAgICAgdGhpcy0+cGF0aHMoaSkpOworICB9CisKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHRvdGFsX3NpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworICByZXR1cm4gdG90YWxfc2l6ZTsKK30KKwordm9pZCBGaWVsZE1hc2s6Ok1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgY29uc3QgRmllbGRNYXNrKiBzb3VyY2UgPSAKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkR5bmFtaWNDYXN0VG9HZW5lcmF0ZWQ8Y29uc3QgRmllbGRNYXNrPigKKyAgICAgICAgICAmZnJvbSk7CisgIGlmIChzb3VyY2UgPT0gTlVMTCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlJlZmxlY3Rpb25PcHM6Ok1lcmdlKGZyb20sIHRoaXMpOworICB9IGVsc2UgeworICAgIE1lcmdlRnJvbSgqc291cmNlKTsKKyAgfQorfQorCit2b2lkIEZpZWxkTWFzazo6TWVyZ2VGcm9tKGNvbnN0IEZpZWxkTWFzayYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBwYXRoc18uTWVyZ2VGcm9tKGZyb20ucGF0aHNfKTsKK30KKwordm9pZCBGaWVsZE1hc2s6OkNvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK3ZvaWQgRmllbGRNYXNrOjpDb3B5RnJvbShjb25zdCBGaWVsZE1hc2smIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCitib29sIEZpZWxkTWFzazo6SXNJbml0aWFsaXplZCgpIGNvbnN0IHsKKworICByZXR1cm4gdHJ1ZTsKK30KKwordm9pZCBGaWVsZE1hc2s6OlN3YXAoRmllbGRNYXNrKiBvdGhlcikgeworICBpZiAob3RoZXIgPT0gdGhpcykgcmV0dXJuOworICBJbnRlcm5hbFN3YXAob3RoZXIpOworfQordm9pZCBGaWVsZE1hc2s6OkludGVybmFsU3dhcChGaWVsZE1hc2sqIG90aGVyKSB7CisgIHBhdGhzXy5VbnNhZmVBcmVuYVN3YXAoJm90aGVyLT5wYXRoc18pOworICBfaW50ZXJuYWxfbWV0YWRhdGFfLlN3YXAoJm90aGVyLT5faW50ZXJuYWxfbWV0YWRhdGFfKTsKKyAgc3RkOjpzd2FwKF9jYWNoZWRfc2l6ZV8sIG90aGVyLT5fY2FjaGVkX3NpemVfKTsKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBGaWVsZE1hc2s6OkdldE1ldGFkYXRhKCkgY29uc3QgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBtZXRhZGF0YTsKKyAgbWV0YWRhdGEuZGVzY3JpcHRvciA9IEZpZWxkTWFza19kZXNjcmlwdG9yXzsKKyAgbWV0YWRhdGEucmVmbGVjdGlvbiA9IEZpZWxkTWFza19yZWZsZWN0aW9uXzsKKyAgcmV0dXJuIG1ldGFkYXRhOworfQorCisjaWYgUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisvLyBGaWVsZE1hc2sKKworLy8gcmVwZWF0ZWQgc3RyaW5nIHBhdGhzID0gMTsKK2ludCBGaWVsZE1hc2s6OnBhdGhzX3NpemUoKSBjb25zdCB7CisgIHJldHVybiBwYXRoc18uc2l6ZSgpOworfQordm9pZCBGaWVsZE1hc2s6OmNsZWFyX3BhdGhzKCkgeworICBwYXRoc18uQ2xlYXIoKTsKK30KKyBjb25zdCA6OnN0ZDo6c3RyaW5nJiBGaWVsZE1hc2s6OnBhdGhzKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2sucGF0aHMpCisgIHJldHVybiBwYXRoc18uR2V0KGluZGV4KTsKK30KKyA6OnN0ZDo6c3RyaW5nKiBGaWVsZE1hc2s6Om11dGFibGVfcGF0aHMoaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2sucGF0aHMpCisgIHJldHVybiBwYXRoc18uTXV0YWJsZShpbmRleCk7Cit9Cisgdm9pZCBGaWVsZE1hc2s6OnNldF9wYXRocyhpbnQgaW5kZXgsIGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzay5wYXRocykKKyAgcGF0aHNfLk11dGFibGUoaW5kZXgpLT5hc3NpZ24odmFsdWUpOworfQorIHZvaWQgRmllbGRNYXNrOjpzZXRfcGF0aHMoaW50IGluZGV4LCBjb25zdCBjaGFyKiB2YWx1ZSkgeworICBwYXRoc18uTXV0YWJsZShpbmRleCktPmFzc2lnbih2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuRmllbGRNYXNrLnBhdGhzKQorfQorIHZvaWQgRmllbGRNYXNrOjpzZXRfcGF0aHMoaW50IGluZGV4LCBjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgcGF0aHNfLk11dGFibGUoaW5kZXgpLT5hc3NpZ24oCisgICAgcmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2sucGF0aHMpCit9CisgOjpzdGQ6OnN0cmluZyogRmllbGRNYXNrOjphZGRfcGF0aHMoKSB7CisgIHJldHVybiBwYXRoc18uQWRkKCk7Cit9Cisgdm9pZCBGaWVsZE1hc2s6OmFkZF9wYXRocyhjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBwYXRoc18uQWRkKCktPmFzc2lnbih2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzay5wYXRocykKK30KKyB2b2lkIEZpZWxkTWFzazo6YWRkX3BhdGhzKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHBhdGhzXy5BZGQoKS0+YXNzaWduKHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2sucGF0aHMpCit9Cisgdm9pZCBGaWVsZE1hc2s6OmFkZF9wYXRocyhjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgcGF0aHNfLkFkZCgpLT5hc3NpZ24ocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2sucGF0aHMpCit9CisgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6OnN0ZDo6c3RyaW5nPiYKK0ZpZWxkTWFzazo6cGF0aHMoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2sucGF0aHMpCisgIHJldHVybiBwYXRoc187Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6OnN0ZDo6c3RyaW5nPioKK0ZpZWxkTWFzazo6bXV0YWJsZV9wYXRocygpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuRmllbGRNYXNrLnBhdGhzKQorICByZXR1cm4gJnBhdGhzXzsKK30KKworI2VuZGlmICAvLyBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKworLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG5hbWVzcGFjZV9zY29wZSkKKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKy8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChnbG9iYWxfc2NvcGUpCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2ZpZWxkX21hc2sucGIuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvZmllbGRfbWFzay5wYi5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjcxODlmZDcKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2ZpZWxkX21hc2sucGIuaApAQCAtMCwwICsxLDIwMSBAQAorLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCEKKy8vIHNvdXJjZTogZ29vZ2xlL3Byb3RvYnVmL2ZpZWxkX21hc2sucHJvdG8KKworI2lmbmRlZiBQUk9UT0JVRl9nb29nbGVfMmZwcm90b2J1Zl8yZmZpZWxkXzVmbWFza18yZXByb3RvX19JTkNMVURFRAorI2RlZmluZSBQUk9UT0JVRl9nb29nbGVfMmZwcm90b2J1Zl8yZmZpZWxkXzVmbWFza18yZXByb3RvX19JTkNMVURFRAorCisjaW5jbHVkZSA8c3RyaW5nPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorCisjaWYgR09PR0xFX1BST1RPQlVGX1ZFUlNJT04gPCAzMDAwMDAwCisjZXJyb3IgVGhpcyBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgYSBuZXdlciB2ZXJzaW9uIG9mIHByb3RvYyB3aGljaCBpcworI2Vycm9yIGluY29tcGF0aWJsZSB3aXRoIHlvdXIgUHJvdG9jb2wgQnVmZmVyIGhlYWRlcnMuICBQbGVhc2UgdXBkYXRlCisjZXJyb3IgeW91ciBoZWFkZXJzLgorI2VuZGlmCisjaWYgMzAwMDAwMCA8IEdPT0dMRV9QUk9UT0JVRl9NSU5fUFJPVE9DX1ZFUlNJT04KKyNlcnJvciBUaGlzIGZpbGUgd2FzIGdlbmVyYXRlZCBieSBhbiBvbGRlciB2ZXJzaW9uIG9mIHByb3RvYyB3aGljaCBpcworI2Vycm9yIGluY29tcGF0aWJsZSB3aXRoIHlvdXIgUHJvdG9jb2wgQnVmZmVyIGhlYWRlcnMuICBQbGVhc2UKKyNlcnJvciByZWdlbmVyYXRlIHRoaXMgZmlsZSB3aXRoIGEgbmV3ZXIgdmVyc2lvbiBvZiBwcm90b2MuCisjZW5kaWYKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9hcmVuYS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9hcmVuYXN0cmluZy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfbWVzc2FnZV91dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21ldGFkYXRhLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21lc3NhZ2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcmVwZWF0ZWRfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZXh0ZW5zaW9uX3NldC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bmtub3duX2ZpZWxkX3NldC5oPgorLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGluY2x1ZGVzKQorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKKy8vIEludGVybmFsIGltcGxlbWVudGF0aW9uIGRldGFpbCAtLSBkbyBub3QgY2FsbCB0aGVzZS4KK3ZvaWQgTElCUFJPVE9CVUZfRVhQT1JUIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZmaWVsZF81Zm1hc2tfMmVwcm90bygpOwordm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmZmllbGRfNWZtYXNrXzJlcHJvdG8oKTsKK3ZvaWQgcHJvdG9idWZfU2h1dGRvd25GaWxlX2dvb2dsZV8yZnByb3RvYnVmXzJmZmllbGRfNWZtYXNrXzJlcHJvdG8oKTsKKworY2xhc3MgRmllbGRNYXNrOworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBGaWVsZE1hc2sgOiBwdWJsaWMgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlIHsKKyBwdWJsaWM6CisgIEZpZWxkTWFzaygpOworICB2aXJ0dWFsIH5GaWVsZE1hc2soKTsKKworICBGaWVsZE1hc2soY29uc3QgRmllbGRNYXNrJiBmcm9tKTsKKworICBpbmxpbmUgRmllbGRNYXNrJiBvcGVyYXRvcj0oY29uc3QgRmllbGRNYXNrJiBmcm9tKSB7CisgICAgQ29weUZyb20oZnJvbSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgc3RhdGljIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogZGVzY3JpcHRvcigpOworICBzdGF0aWMgY29uc3QgRmllbGRNYXNrJiBkZWZhdWx0X2luc3RhbmNlKCk7CisKKyAgdm9pZCBTd2FwKEZpZWxkTWFzayogb3RoZXIpOworCisgIC8vIGltcGxlbWVudHMgTWVzc2FnZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgaW5saW5lIEZpZWxkTWFzayogTmV3KCkgY29uc3QgeyByZXR1cm4gTmV3KE5VTEwpOyB9CisKKyAgRmllbGRNYXNrKiBOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0OworICB2b2lkIENvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgQ29weUZyb20oY29uc3QgRmllbGRNYXNrJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgRmllbGRNYXNrJiBmcm9tKTsKKyAgdm9pZCBDbGVhcigpOworICBib29sIElzSW5pdGlhbGl6ZWQoKSBjb25zdDsKKworICBpbnQgQnl0ZVNpemUoKSBjb25zdDsKKyAgYm9vbCBNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCk7CisgIHZvaWQgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogb3V0cHV0KSBjb25zdDsKKyAgaW50IEdldENhY2hlZFNpemUoKSBjb25zdCB7IHJldHVybiBfY2FjaGVkX3NpemVfOyB9CisgIHByaXZhdGU6CisgIHZvaWQgU2hhcmVkQ3RvcigpOworICB2b2lkIFNoYXJlZER0b3IoKTsKKyAgdm9pZCBTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdDsKKyAgdm9pZCBJbnRlcm5hbFN3YXAoRmllbGRNYXNrKiBvdGhlcik7CisgIHByaXZhdGU6CisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYU5vVmlydHVhbCgpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5hcmVuYSgpOworICB9CisgIGlubGluZSB2b2lkKiBNYXliZUFyZW5hUHRyKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnJhd19hcmVuYV9wdHIoKTsKKyAgfQorICBwdWJsaWM6CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBHZXRNZXRhZGF0YSgpIGNvbnN0OworCisgIC8vIG5lc3RlZCB0eXBlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gYWNjZXNzb3JzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyByZXBlYXRlZCBzdHJpbmcgcGF0aHMgPSAxOworICBpbnQgcGF0aHNfc2l6ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX3BhdGhzKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga1BhdGhzRmllbGROdW1iZXIgPSAxOworICBjb25zdCA6OnN0ZDo6c3RyaW5nJiBwYXRocyhpbnQgaW5kZXgpIGNvbnN0OworICA6OnN0ZDo6c3RyaW5nKiBtdXRhYmxlX3BhdGhzKGludCBpbmRleCk7CisgIHZvaWQgc2V0X3BhdGhzKGludCBpbmRleCwgY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpOworICB2b2lkIHNldF9wYXRocyhpbnQgaW5kZXgsIGNvbnN0IGNoYXIqIHZhbHVlKTsKKyAgdm9pZCBzZXRfcGF0aHMoaW50IGluZGV4LCBjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpOworICA6OnN0ZDo6c3RyaW5nKiBhZGRfcGF0aHMoKTsKKyAgdm9pZCBhZGRfcGF0aHMoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpOworICB2b2lkIGFkZF9wYXRocyhjb25zdCBjaGFyKiB2YWx1ZSk7CisgIHZvaWQgYWRkX3BhdGhzKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpzdGQ6OnN0cmluZz4mIHBhdGhzKCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpzdGQ6OnN0cmluZz4qIG11dGFibGVfcGF0aHMoKTsKKworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6Z29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzaykKKyBwcml2YXRlOgorCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEgX2ludGVybmFsX21ldGFkYXRhXzsKKyAgYm9vbCBfaXNfZGVmYXVsdF9pbnN0YW5jZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpzdGQ6OnN0cmluZz4gcGF0aHNfOworICBtdXRhYmxlIGludCBfY2FjaGVkX3NpemVfOworICBmcmllbmQgdm9pZCBMSUJQUk9UT0JVRl9FWFBPUlQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZmZpZWxkXzVmbWFza18yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZmaWVsZF81Zm1hc2tfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZmaWVsZF81Zm1hc2tfMmVwcm90bygpOworCisgIHZvaWQgSW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIHN0YXRpYyBGaWVsZE1hc2sqIGRlZmF1bHRfaW5zdGFuY2VfOworfTsKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKyNpZiAhUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisvLyBGaWVsZE1hc2sKKworLy8gcmVwZWF0ZWQgc3RyaW5nIHBhdGhzID0gMTsKK2lubGluZSBpbnQgRmllbGRNYXNrOjpwYXRoc19zaXplKCkgY29uc3QgeworICByZXR1cm4gcGF0aHNfLnNpemUoKTsKK30KK2lubGluZSB2b2lkIEZpZWxkTWFzazo6Y2xlYXJfcGF0aHMoKSB7CisgIHBhdGhzXy5DbGVhcigpOworfQoraW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEZpZWxkTWFzazo6cGF0aHMoaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzay5wYXRocykKKyAgcmV0dXJuIHBhdGhzXy5HZXQoaW5kZXgpOworfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIEZpZWxkTWFzazo6bXV0YWJsZV9wYXRocyhpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzay5wYXRocykKKyAgcmV0dXJuIHBhdGhzXy5NdXRhYmxlKGluZGV4KTsKK30KK2lubGluZSB2b2lkIEZpZWxkTWFzazo6c2V0X3BhdGhzKGludCBpbmRleCwgY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmllbGRNYXNrLnBhdGhzKQorICBwYXRoc18uTXV0YWJsZShpbmRleCktPmFzc2lnbih2YWx1ZSk7Cit9CitpbmxpbmUgdm9pZCBGaWVsZE1hc2s6OnNldF9wYXRocyhpbnQgaW5kZXgsIGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIHBhdGhzXy5NdXRhYmxlKGluZGV4KS0+YXNzaWduKHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2sucGF0aHMpCit9CitpbmxpbmUgdm9pZCBGaWVsZE1hc2s6OnNldF9wYXRocyhpbnQgaW5kZXgsIGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBwYXRoc18uTXV0YWJsZShpbmRleCktPmFzc2lnbigKKyAgICByZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzay5wYXRocykKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBGaWVsZE1hc2s6OmFkZF9wYXRocygpIHsKKyAgcmV0dXJuIHBhdGhzXy5BZGQoKTsKK30KK2lubGluZSB2b2lkIEZpZWxkTWFzazo6YWRkX3BhdGhzKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIHBhdGhzXy5BZGQoKS0+YXNzaWduKHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuRmllbGRNYXNrLnBhdGhzKQorfQoraW5saW5lIHZvaWQgRmllbGRNYXNrOjphZGRfcGF0aHMoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgcGF0aHNfLkFkZCgpLT5hc3NpZ24odmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkX2NoYXI6Z29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzay5wYXRocykKK30KK2lubGluZSB2b2lkIEZpZWxkTWFzazo6YWRkX3BhdGhzKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICBwYXRoc18uQWRkKCktPmFzc2lnbihyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkX3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzay5wYXRocykKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6c3RkOjpzdHJpbmc+JgorRmllbGRNYXNrOjpwYXRocygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzay5wYXRocykKKyAgcmV0dXJuIHBhdGhzXzsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6c3RkOjpzdHJpbmc+KgorRmllbGRNYXNrOjptdXRhYmxlX3BhdGhzKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2sucGF0aHMpCisgIHJldHVybiAmcGF0aHNfOworfQorCisjZW5kaWYgIC8vICFQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKworLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG5hbWVzcGFjZV9zY29wZSkKKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKy8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChnbG9iYWxfc2NvcGUpCisKKyNlbmRpZiAgLy8gUFJPVE9CVUZfZ29vZ2xlXzJmcHJvdG9idWZfMmZmaWVsZF81Zm1hc2tfMmVwcm90b19fSU5DTFVERUQKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvZmllbGRfbWFzay5wcm90byBiL3NyYy9nb29nbGUvcHJvdG9idWYvZmllbGRfbWFzay5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45MDhjOGE4Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9maWVsZF9tYXNrLnByb3RvCkBAIC0wLDAgKzEsMTY4IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworc3ludGF4ID0gInByb3RvMyI7CisKK3BhY2thZ2UgZ29vZ2xlLnByb3RvYnVmOworCitvcHRpb24gY3NoYXJwX25hbWVzcGFjZSA9ICJHb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlwZXMiOworb3B0aW9uIGphdmFfcGFja2FnZSA9ICJjb20uZ29vZ2xlLnByb3RvYnVmIjsKK29wdGlvbiBqYXZhX291dGVyX2NsYXNzbmFtZSA9ICJGaWVsZE1hc2tQcm90byI7CitvcHRpb24gamF2YV9tdWx0aXBsZV9maWxlcyA9IHRydWU7CitvcHRpb24gb2JqY19jbGFzc19wcmVmaXggPSAiR1BCIjsKK29wdGlvbiBqYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaCA9IHRydWU7CisKKy8vIGBGaWVsZE1hc2tgIHJlcHJlc2VudHMgYSBzZXQgb2Ygc3ltYm9saWMgZmllbGQgcGF0aHMsIGZvciBleGFtcGxlOgorLy8KKy8vICAgICBwYXRoczogImYuYSIKKy8vICAgICBwYXRoczogImYuYi5kIgorLy8KKy8vIEhlcmUgYGZgIHJlcHJlc2VudHMgYSBmaWVsZCBpbiBzb21lIHJvb3QgbWVzc2FnZSwgYGFgIGFuZCBgYmAKKy8vIGZpZWxkcyBpbiB0aGUgbWVzc2FnZSBmb3VuZCBpbiBgZmAsIGFuZCBgZGAgYSBmaWVsZCBmb3VuZCBpbiB0aGUKKy8vIG1lc3NhZ2UgaW4gYGYuYmAuCisvLworLy8gRmllbGQgbWFza3MgYXJlIHVzZWQgdG8gc3BlY2lmeSBhIHN1YnNldCBvZiBmaWVsZHMgdGhhdCBzaG91bGQgYmUKKy8vIHJldHVybmVkIGJ5IGEgZ2V0IG9wZXJhdGlvbiBvciBtb2RpZmllZCBieSBhbiB1cGRhdGUgb3BlcmF0aW9uLgorLy8gRmllbGQgbWFza3MgYWxzbyBoYXZlIGEgY3VzdG9tIEpTT04gZW5jb2RpbmcgKHNlZSBiZWxvdykuCisvLworLy8gIyBGaWVsZCBNYXNrcyBpbiBQcm9qZWN0aW9ucworLy8KKy8vIFdoZW4gdXNlZCBpbiB0aGUgY29udGV4dCBvZiBhIHByb2plY3Rpb24sIGEgcmVzcG9uc2UgbWVzc2FnZSBvcgorLy8gc3ViLW1lc3NhZ2UgaXMgZmlsdGVyZWQgYnkgdGhlIEFQSSB0byBvbmx5IGNvbnRhaW4gdGhvc2UgZmllbGRzIGFzCisvLyBzcGVjaWZpZWQgaW4gdGhlIG1hc2suIEZvciBleGFtcGxlLCBpZiB0aGUgbWFzayBpbiB0aGUgcHJldmlvdXMKKy8vIGV4YW1wbGUgaXMgYXBwbGllZCB0byBhIHJlc3BvbnNlIG1lc3NhZ2UgYXMgZm9sbG93czoKKy8vCisvLyAgICAgZiB7CisvLyAgICAgICBhIDogMjIKKy8vICAgICAgIGIgeworLy8gICAgICAgICBkIDogMQorLy8gICAgICAgICB4IDogMgorLy8gICAgICAgfQorLy8gICAgICAgeSA6IDEzCisvLyAgICAgfQorLy8gICAgIHo6IDgKKy8vCisvLyBUaGUgcmVzdWx0IHdpbGwgbm90IGNvbnRhaW4gc3BlY2lmaWMgdmFsdWVzIGZvciBmaWVsZHMgeCx5IGFuZCB6CisvLyAodGhlaXIgdmFsdWUgd2lsbCBiZSBzZXQgdG8gdGhlIGRlZmF1bHQsIGFuZCBvbWl0dGVkIGluIHByb3RvIHRleHQKKy8vIG91dHB1dCk6CisvLworLy8KKy8vICAgICBmIHsKKy8vICAgICAgIGEgOiAyMgorLy8gICAgICAgYiB7CisvLyAgICAgICAgIGQgOiAxCisvLyAgICAgICB9CisvLyAgICAgfQorLy8KKy8vIEEgcmVwZWF0ZWQgZmllbGQgaXMgbm90IGFsbG93ZWQgZXhjZXB0IGF0IHRoZSBsYXN0IHBvc2l0aW9uIG9mIGEKKy8vIGZpZWxkIG1hc2suCisvLworLy8gSWYgYSBGaWVsZE1hc2sgb2JqZWN0IGlzIG5vdCBwcmVzZW50IGluIGEgZ2V0IG9wZXJhdGlvbiwgdGhlCisvLyBvcGVyYXRpb24gYXBwbGllcyB0byBhbGwgZmllbGRzIChhcyBpZiBhIEZpZWxkTWFzayBvZiBhbGwgZmllbGRzCisvLyBoYWQgYmVlbiBzcGVjaWZpZWQpLgorLy8KKy8vIE5vdGUgdGhhdCBhIGZpZWxkIG1hc2sgZG9lcyBub3QgbmVjZXNzYXJpbHkgYXBwbGllcyB0byB0aGUKKy8vIHRvcC1sZXZlbCByZXNwb25zZSBtZXNzYWdlLiBJbiBjYXNlIG9mIGEgUkVTVCBnZXQgb3BlcmF0aW9uLCB0aGUKKy8vIGZpZWxkIG1hc2sgYXBwbGllcyBkaXJlY3RseSB0byB0aGUgcmVzcG9uc2UsIGJ1dCBpbiBjYXNlIG9mIGEgUkVTVAorLy8gbGlzdCBvcGVyYXRpb24sIHRoZSBtYXNrIGluc3RlYWQgYXBwbGllcyB0byBlYWNoIGluZGl2aWR1YWwgbWVzc2FnZQorLy8gaW4gdGhlIHJldHVybmVkIHJlc291cmNlIGxpc3QuIEluIGNhc2Ugb2YgYSBSRVNUIGN1c3RvbSBtZXRob2QsCisvLyBvdGhlciBkZWZpbml0aW9ucyBtYXkgYmUgdXNlZC4gV2hlcmUgdGhlIG1hc2sgYXBwbGllcyB3aWxsIGJlCisvLyBjbGVhcmx5IGRvY3VtZW50ZWQgdG9nZXRoZXIgd2l0aCBpdHMgZGVjbGFyYXRpb24gaW4gdGhlIEFQSS4gIEluCisvLyBhbnkgY2FzZSwgdGhlIGVmZmVjdCBvbiB0aGUgcmV0dXJuZWQgcmVzb3VyY2UvcmVzb3VyY2VzIGlzIHJlcXVpcmVkCisvLyBiZWhhdmlvciBmb3IgQVBJcy4KKy8vCisvLyAjIEZpZWxkIE1hc2tzIGluIFVwZGF0ZSBPcGVyYXRpb25zCisvLworLy8gQSBmaWVsZCBtYXNrIGluIHVwZGF0ZSBvcGVyYXRpb25zIHNwZWNpZmllcyB3aGljaCBmaWVsZHMgb2YgdGhlCisvLyB0YXJnZXRlZCByZXNvdXJjZSBhcmUgZ29pbmcgdG8gYmUgdXBkYXRlZC4gVGhlIEFQSSBpcyByZXF1aXJlZAorLy8gdG8gb25seSBjaGFuZ2UgdGhlIHZhbHVlcyBvZiB0aGUgZmllbGRzIGFzIHNwZWNpZmllZCBpbiB0aGUgbWFzaworLy8gYW5kIGxlYXZlIHRoZSBvdGhlcnMgdW50b3VjaGVkLiBJZiBhIHJlc291cmNlIGlzIHBhc3NlZCBpbiB0bworLy8gZGVzY3JpYmUgdGhlIHVwZGF0ZWQgdmFsdWVzLCB0aGUgQVBJIGlnbm9yZXMgdGhlIHZhbHVlcyBvZiBhbGwKKy8vIGZpZWxkcyBub3QgY292ZXJlZCBieSB0aGUgbWFzay4KKy8vCisvLyBJbiBvcmRlciB0byByZXNldCBhIGZpZWxkJ3MgdmFsdWUgdG8gdGhlIGRlZmF1bHQsIHRoZSBmaWVsZCBtdXN0CisvLyBiZSBpbiB0aGUgbWFzayBhbmQgc2V0IHRvIHRoZSBkZWZhdWx0IHZhbHVlIGluIHRoZSBwcm92aWRlZCByZXNvdXJjZS4KKy8vIEhlbmNlLCBpbiBvcmRlciB0byByZXNldCBhbGwgZmllbGRzIG9mIGEgcmVzb3VyY2UsIHByb3ZpZGUgYSBkZWZhdWx0CisvLyBpbnN0YW5jZSBvZiB0aGUgcmVzb3VyY2UgYW5kIHNldCBhbGwgZmllbGRzIGluIHRoZSBtYXNrLCBvciBkbworLy8gbm90IHByb3ZpZGUgYSBtYXNrIGFzIGRlc2NyaWJlZCBiZWxvdy4KKy8vCisvLyBJZiBhIGZpZWxkIG1hc2sgaXMgbm90IHByZXNlbnQgb24gdXBkYXRlLCB0aGUgb3BlcmF0aW9uIGFwcGxpZXMgdG8KKy8vIGFsbCBmaWVsZHMgKGFzIGlmIGEgZmllbGQgbWFzayBvZiBhbGwgZmllbGRzIGhhcyBiZWVuIHNwZWNpZmllZCkuCisvLyBOb3RlIHRoYXQgaW4gdGhlIHByZXNlbmNlIG9mIHNjaGVtYSBldm9sdXRpb24sIHRoaXMgbWF5IG1lYW4gdGhhdAorLy8gZmllbGRzIHRoZSBjbGllbnQgZG9lcyBub3Qga25vdyBhbmQgaGFzIHRoZXJlZm9yZSBub3QgZmlsbGVkIGludG8KKy8vIHRoZSByZXF1ZXN0IHdpbGwgYmUgcmVzZXQgdG8gdGhlaXIgZGVmYXVsdC4gSWYgdGhpcyBpcyB1bndhbnRlZAorLy8gYmVoYXZpb3IsIGEgc3BlY2lmaWMgc2VydmljZSBtYXkgcmVxdWlyZSBhIGNsaWVudCB0byBhbHdheXMgc3BlY2lmeQorLy8gYSBmaWVsZCBtYXNrLCBwcm9kdWNpbmcgYW4gZXJyb3IgaWYgbm90LgorLy8KKy8vIEFzIHdpdGggZ2V0IG9wZXJhdGlvbnMsIHRoZSBsb2NhdGlvbiBvZiB0aGUgcmVzb3VyY2Ugd2hpY2gKKy8vIGRlc2NyaWJlcyB0aGUgdXBkYXRlZCB2YWx1ZXMgaW4gdGhlIHJlcXVlc3QgbWVzc2FnZSBkZXBlbmRzIG9uIHRoZQorLy8gb3BlcmF0aW9uIGtpbmQuIEluIGFueSBjYXNlLCB0aGUgZWZmZWN0IG9mIHRoZSBmaWVsZCBtYXNrIGlzCisvLyByZXF1aXJlZCB0byBiZSBob25vcmVkIGJ5IHRoZSBBUEkuCisvLworLy8gIyMgQ29uc2lkZXJhdGlvbnMgZm9yIEhUVFAgUkVTVAorLy8KKy8vIFRoZSBIVFRQIGtpbmQgb2YgYW4gdXBkYXRlIG9wZXJhdGlvbiB3aGljaCB1c2VzIGEgZmllbGQgbWFzayBtdXN0CisvLyBiZSBzZXQgdG8gUEFUQ0ggaW5zdGVhZCBvZiBQVVQgaW4gb3JkZXIgdG8gc2F0aXNmeSBIVFRQIHNlbWFudGljcworLy8gKFBVVCBtdXN0IG9ubHkgYmUgdXNlZCBmb3IgZnVsbCB1cGRhdGVzKS4KKy8vCisvLyAjIEpTT04gRW5jb2Rpbmcgb2YgRmllbGQgTWFza3MKKy8vCisvLyBJbiBKU09OLCBhIGZpZWxkIG1hc2sgaXMgZW5jb2RlZCBhcyBhIHNpbmdsZSBzdHJpbmcgd2hlcmUgcGF0aHMgYXJlCisvLyBzZXBhcmF0ZWQgYnkgYSBjb21tYS4gRmllbGRzIG5hbWUgaW4gZWFjaCBwYXRoIGFyZSBjb252ZXJ0ZWQKKy8vIHRvL2Zyb20gbG93ZXItY2FtZWwgbmFtaW5nIGNvbnZlbnRpb25zLgorLy8KKy8vIEFzIGFuIGV4YW1wbGUsIGNvbnNpZGVyIHRoZSBmb2xsb3dpbmcgbWVzc2FnZSBkZWNsYXJhdGlvbnM6CisvLworLy8gICAgIG1lc3NhZ2UgUHJvZmlsZSB7CisvLyAgICAgICBVc2VyIHVzZXIgPSAxOworLy8gICAgICAgUGhvdG8gcGhvdG8gPSAyOworLy8gICAgIH0KKy8vICAgICBtZXNzYWdlIFVzZXIgeworLy8gICAgICAgc3RyaW5nIGRpc3BsYXlfbmFtZSA9IDE7CisvLyAgICAgICBzdHJpbmcgYWRkcmVzcyA9IDI7CisvLyAgICAgfQorLy8KKy8vIEluIHByb3RvIGEgZmllbGQgbWFzayBmb3IgYFByb2ZpbGVgIG1heSBsb29rIGFzIHN1Y2g6CisvLworLy8gICAgIG1hc2sgeworLy8gICAgICAgcGF0aHM6ICJ1c2VyLmRpc3BsYXlfbmFtZSIKKy8vICAgICAgIHBhdGhzOiAicGhvdG8iCisvLyAgICAgfQorLy8KKy8vIEluIEpTT04sIHRoZSBzYW1lIG1hc2sgaXMgcmVwcmVzZW50ZWQgYXMgYmVsb3c6CisvLworLy8gICAgIHsKKy8vICAgICAgIG1hc2s6ICJ1c2VyLmRpc3BsYXlOYW1lLHBob3RvIgorLy8gICAgIH0KKy8vCittZXNzYWdlIEZpZWxkTWFzayB7CisgIC8vIFRoZSBzZXQgb2YgZmllbGQgbWFzayBwYXRocy4KKyAgcmVwZWF0ZWQgc3RyaW5nIHBhdGhzID0gMTsKK30KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX2VudW1fcmVmbGVjdGlvbi5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfZW51bV9yZWZsZWN0aW9uLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmRjZGMyNwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX2VudW1fcmVmbGVjdGlvbi5oCkBAIC0wLDAgKzEsODggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGphc29uaEBnb29nbGUuY29tIChKYXNvbiBIc3VlaCkKKy8vCisvLyBUaGlzIGhlYWRlciBpcyBsb2dpY2FsbHkgaW50ZXJuYWwsIGJ1dCBpcyBtYWRlIHB1YmxpYyBiZWNhdXNlIGl0IGlzIHVzZWQKKy8vIGZyb20gcHJvdG9jb2wtY29tcGlsZXItZ2VuZXJhdGVkIGNvZGUsIHdoaWNoIG1heSByZXNpZGUgaW4gb3RoZXIgY29tcG9uZW50cy4KKy8vIEl0IHByb3ZpZGVzIHJlZmxlY3Rpb24gc3VwcG9ydCBmb3IgZ2VuZXJhdGVkIGVudW1zLCBhbmQgaXMgaW5jbHVkZWQgaW4KKy8vIGdlbmVyYXRlZCAucGIuaCBmaWxlcyBhbmQgc2hvdWxkIGhhdmUgbWluaW1hbCBkZXBlbmRlbmNpZXMuIFRoZSBtZXRob2RzIGFyZQorLy8gaW1wbGVtZW50ZWQgaW4gZ2VuZXJhdGVkX21lc3NhZ2VfcmVmbGVjdGlvbi5jYy4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX0VOVU1fUkVGTEVDVElPTl9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9FTlVNX1JFRkxFQ1RJT05fSF9fCisKKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvdGVtcGxhdGVfdXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfZW51bV91dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKyAgY2xhc3MgRW51bURlc2NyaXB0b3I7Cit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworLy8gUmV0dXJucyB0aGUgRW51bURlc2NyaXB0b3IgZm9yIGVudW0gdHlwZSBFLCB3aGljaCBtdXN0IGJlIGEKKy8vIHByb3RvLWRlY2xhcmVkIGVudW0gdHlwZS4gIENvZGUgZ2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBjb21waWxlcgorLy8gd2lsbCBpbmNsdWRlIHNwZWNpYWxpemF0aW9ucyBvZiB0aGlzIHRlbXBsYXRlIGZvciBlYWNoIGVudW0gdHlwZSBkZWNsYXJlZC4KK3RlbXBsYXRlIDx0eXBlbmFtZSBFPgorY29uc3QgRW51bURlc2NyaXB0b3IqIEdldEVudW1EZXNjcmlwdG9yKCk7CisKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKKy8vIEhlbHBlciBmb3IgRW51bVR5cGVfUGFyc2UgZnVuY3Rpb25zOiB0cnkgdG8gcGFyc2UgdGhlIHN0cmluZyAnbmFtZScgYXMgYW4KKy8vIGVudW0gbmFtZSBvZiB0aGUgZ2l2ZW4gdHlwZSwgcmV0dXJuaW5nIHRydWUgYW5kIGZpbGxpbmcgaW4gdmFsdWUgb24gc3VjY2VzcywKKy8vIG9yIHJldHVybmluZyBmYWxzZSBhbmQgbGVhdmluZyB2YWx1ZSB1bmNoYW5nZWQgb24gZmFpbHVyZS4KK0xJQlBST1RPQlVGX0VYUE9SVCBib29sIFBhcnNlTmFtZWRFbnVtKGNvbnN0IEVudW1EZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIG5hbWUsCisgICAgICAgICAgICAgICAgICAgIGludCogdmFsdWUpOworCit0ZW1wbGF0ZTx0eXBlbmFtZSBFbnVtVHlwZT4KK2Jvb2wgUGFyc2VOYW1lZEVudW0oY29uc3QgRW51bURlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgRW51bVR5cGUqIHZhbHVlKSB7CisgIGludCB0bXA7CisgIGlmICghUGFyc2VOYW1lZEVudW0oZGVzY3JpcHRvciwgbmFtZSwgJnRtcCkpIHJldHVybiBmYWxzZTsKKyAgKnZhbHVlID0gc3RhdGljX2Nhc3Q8RW51bVR5cGU+KHRtcCk7CisgIHJldHVybiB0cnVlOworfQorCisvLyBKdXN0IGEgd3JhcHBlciBhcm91bmQgcHJpbnRpbmcgdGhlIG5hbWUgb2YgYSB2YWx1ZS4gVGhlIG1haW4gcG9pbnQgb2YgdGhpcworLy8gZnVuY3Rpb24gaXMgbm90IHRvIGJlIGlubGluZWQsIHNvIHRoYXQgeW91IGNhbiBkbyB0aGlzIHdpdGhvdXQgaW5jbHVkaW5nCisvLyBkZXNjcmlwdG9yLmguCitMSUJQUk9UT0JVRl9FWFBPUlQgY29uc3Qgc3RyaW5nJiBOYW1lT2ZFbnVtKGNvbnN0IEVudW1EZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBpbnQgdmFsdWUpOworCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfRU5VTV9SRUZMRUNUSU9OX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfZW51bV91dGlsLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9lbnVtX3V0aWwuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNDI0MjA1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfZW51bV91dGlsLmgKQEAgLTAsMCArMSw0NiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9FTlVNX1VUSUxfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfRU5VTV9VVElMX0hfXworCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3RlbXBsYXRlX3V0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCisvLyBUaGlzIHR5cGUgdHJhaXQgY2FuIGJlIHVzZWQgdG8gY2F1c2UgdGVtcGxhdGVzIHRvIG9ubHkgbWF0Y2ggcHJvdG8yIGVudW0KKy8vIHR5cGVzLgordGVtcGxhdGUgPHR5cGVuYW1lIFQ+IHN0cnVjdCBpc19wcm90b19lbnVtIDogOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6ZmFsc2VfdHlwZSB7fTsKKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9FTlVNX1VUSUxfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9tZXNzYWdlX3JlZmxlY3Rpb24uY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9tZXNzYWdlX3JlZmxlY3Rpb24uY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWVlMDI0ZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX21lc3NhZ2VfcmVmbGVjdGlvbi5jYwpAQCAtMCwwICsxLDIyNzQgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2luY2x1ZGUgPGFsZ29yaXRobT4KKyNpbmNsdWRlIDxzZXQ+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbG9nZ2luZy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2V4dGVuc2lvbl9zZXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX21lc3NhZ2VfcmVmbGVjdGlvbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfbWVzc2FnZV91dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21hcF9maWVsZC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9yZXBlYXRlZF9maWVsZC5oPgorCisKKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0hBU19PTkVPRgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW50ZXJuYWwgeworCituYW1lc3BhY2UgeworYm9vbCBJc01hcEZpZWxkSW5BcGkoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICByZXR1cm4gZmllbGQtPmlzX21hcCgpOworfQorfSAgLy8gYW5vbnltb3VzIG5hbWVzcGFjZQorCitib29sIFBhcnNlTmFtZWRFbnVtKGNvbnN0IEVudW1EZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIG5hbWUsCisgICAgICAgICAgICAgICAgICAgIGludCogdmFsdWUpIHsKKyAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogZCA9IGRlc2NyaXB0b3ItPkZpbmRWYWx1ZUJ5TmFtZShuYW1lKTsKKyAgaWYgKGQgPT0gTlVMTCkgcmV0dXJuIGZhbHNlOworICAqdmFsdWUgPSBkLT5udW1iZXIoKTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK2NvbnN0IHN0cmluZyYgTmFtZU9mRW51bShjb25zdCBFbnVtRGVzY3JpcHRvciogZGVzY3JpcHRvciwgaW50IHZhbHVlKSB7CisgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIGQgPSBkZXNjcmlwdG9yLT5GaW5kVmFsdWVCeU51bWJlcih2YWx1ZSk7CisgIHJldHVybiAoZCA9PSBOVUxMID8gR2V0RW1wdHlTdHJpbmcoKSA6IGQtPm5hbWUoKSk7Cit9CisKK25hbWVzcGFjZSB7CitpbmxpbmUgYm9vbCBTdXBwb3J0c0FyZW5hcyhjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIHJldHVybiBkZXNjcmlwdG9yLT5maWxlKCktPm9wdGlvbnMoKS5jY19lbmFibGVfYXJlbmFzKCk7Cit9Cit9ICAvLyBhbm9ueW1vdXMgbmFtZXNwYWNlCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKy8vIEhlbHBlcnMgZm9yIHJlcG9ydGluZyB1c2FnZSBlcnJvcnMgKGUuZy4gdHJ5aW5nIHRvIHVzZSBHZXRJbnQzMigpIG9uCisvLyBhIHN0cmluZyBmaWVsZCkuCisKK25hbWVzcGFjZSB7CisKK3ZvaWQgUmVwb3J0UmVmbGVjdGlvblVzYWdlRXJyb3IoCisgICAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICBjb25zdCBjaGFyKiBtZXRob2QsIGNvbnN0IGNoYXIqIGRlc2NyaXB0aW9uKSB7CisgIEdPT0dMRV9MT0coRkFUQUwpCisgICAgPDwgIlByb3RvY29sIEJ1ZmZlciByZWZsZWN0aW9uIHVzYWdlIGVycm9yOlxuIgorICAgICAgICIgIE1ldGhvZCAgICAgIDogZ29vZ2xlOjpwcm90b2J1Zjo6UmVmbGVjdGlvbjo6IiA8PCBtZXRob2QgPDwgIlxuIgorICAgICAgICIgIE1lc3NhZ2UgdHlwZTogIiA8PCBkZXNjcmlwdG9yLT5mdWxsX25hbWUoKSA8PCAiXG4iCisgICAgICAgIiAgRmllbGQgICAgICAgOiAiIDw8IGZpZWxkLT5mdWxsX25hbWUoKSA8PCAiXG4iCisgICAgICAgIiAgUHJvYmxlbSAgICAgOiAiIDw8IGRlc2NyaXB0aW9uOworfQorCitjb25zdCBjaGFyKiBjcHB0eXBlX25hbWVzX1tGaWVsZERlc2NyaXB0b3I6Ok1BWF9DUFBUWVBFICsgMV0gPSB7CisgICJJTlZBTElEX0NQUFRZUEUiLAorICAiQ1BQVFlQRV9JTlQzMiIsCisgICJDUFBUWVBFX0lOVDY0IiwKKyAgIkNQUFRZUEVfVUlOVDMyIiwKKyAgIkNQUFRZUEVfVUlOVDY0IiwKKyAgIkNQUFRZUEVfRE9VQkxFIiwKKyAgIkNQUFRZUEVfRkxPQVQiLAorICAiQ1BQVFlQRV9CT09MIiwKKyAgIkNQUFRZUEVfRU5VTSIsCisgICJDUFBUWVBFX1NUUklORyIsCisgICJDUFBUWVBFX01FU1NBR0UiCit9OworCitzdGF0aWMgdm9pZCBSZXBvcnRSZWZsZWN0aW9uVXNhZ2VUeXBlRXJyb3IoCisgICAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICBjb25zdCBjaGFyKiBtZXRob2QsCisgICAgRmllbGREZXNjcmlwdG9yOjpDcHBUeXBlIGV4cGVjdGVkX3R5cGUpIHsKKyAgR09PR0xFX0xPRyhGQVRBTCkKKyAgICA8PCAiUHJvdG9jb2wgQnVmZmVyIHJlZmxlY3Rpb24gdXNhZ2UgZXJyb3I6XG4iCisgICAgICAgIiAgTWV0aG9kICAgICAgOiBnb29nbGU6OnByb3RvYnVmOjpSZWZsZWN0aW9uOjoiIDw8IG1ldGhvZCA8PCAiXG4iCisgICAgICAgIiAgTWVzc2FnZSB0eXBlOiAiIDw8IGRlc2NyaXB0b3ItPmZ1bGxfbmFtZSgpIDw8ICJcbiIKKyAgICAgICAiICBGaWVsZCAgICAgICA6ICIgPDwgZmllbGQtPmZ1bGxfbmFtZSgpIDw8ICJcbiIKKyAgICAgICAiICBQcm9ibGVtICAgICA6IEZpZWxkIGlzIG5vdCB0aGUgcmlnaHQgdHlwZSBmb3IgdGhpcyBtZXNzYWdlOlxuIgorICAgICAgICIgICAgRXhwZWN0ZWQgIDogIiA8PCBjcHB0eXBlX25hbWVzX1tleHBlY3RlZF90eXBlXSA8PCAiXG4iCisgICAgICAgIiAgICBGaWVsZCB0eXBlOiAiIDw8IGNwcHR5cGVfbmFtZXNfW2ZpZWxkLT5jcHBfdHlwZSgpXTsKK30KKworc3RhdGljIHZvaWQgUmVwb3J0UmVmbGVjdGlvblVzYWdlRW51bVR5cGVFcnJvcigKKyAgICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgIGNvbnN0IGNoYXIqIG1ldGhvZCwgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogdmFsdWUpIHsKKyAgR09PR0xFX0xPRyhGQVRBTCkKKyAgICA8PCAiUHJvdG9jb2wgQnVmZmVyIHJlZmxlY3Rpb24gdXNhZ2UgZXJyb3I6XG4iCisgICAgICAgIiAgTWV0aG9kICAgICAgOiBnb29nbGU6OnByb3RvYnVmOjpSZWZsZWN0aW9uOjoiIDw8IG1ldGhvZCA8PCAiXG4iCisgICAgICAgIiAgTWVzc2FnZSB0eXBlOiAiIDw8IGRlc2NyaXB0b3ItPmZ1bGxfbmFtZSgpIDw8ICJcbiIKKyAgICAgICAiICBGaWVsZCAgICAgICA6ICIgPDwgZmllbGQtPmZ1bGxfbmFtZSgpIDw8ICJcbiIKKyAgICAgICAiICBQcm9ibGVtICAgICA6IEVudW0gdmFsdWUgZGlkIG5vdCBtYXRjaCBmaWVsZCB0eXBlOlxuIgorICAgICAgICIgICAgRXhwZWN0ZWQgIDogIiA8PCBmaWVsZC0+ZW51bV90eXBlKCktPmZ1bGxfbmFtZSgpIDw8ICJcbiIKKyAgICAgICAiICAgIEFjdHVhbCAgICA6ICIgPDwgdmFsdWUtPmZ1bGxfbmFtZSgpOworfQorCisjZGVmaW5lIFVTQUdFX0NIRUNLKENPTkRJVElPTiwgTUVUSE9ELCBFUlJPUl9ERVNDUklQVElPTikgICAgICAgICAgICAgICAgICAgICAgXAorICBpZiAoIShDT05ESVRJT04pKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBSZXBvcnRSZWZsZWN0aW9uVXNhZ2VFcnJvcihkZXNjcmlwdG9yXywgZmllbGQsICNNRVRIT0QsIEVSUk9SX0RFU0NSSVBUSU9OKQorI2RlZmluZSBVU0FHRV9DSEVDS19FUShBLCBCLCBNRVRIT0QsIEVSUk9SX0RFU0NSSVBUSU9OKSAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgVVNBR0VfQ0hFQ0soKEEpID09IChCKSwgTUVUSE9ELCBFUlJPUl9ERVNDUklQVElPTikKKyNkZWZpbmUgVVNBR0VfQ0hFQ0tfTkUoQSwgQiwgTUVUSE9ELCBFUlJPUl9ERVNDUklQVElPTikgICAgICAgICAgICAgICAgICAgICAgICBcCisgIFVTQUdFX0NIRUNLKChBKSAhPSAoQiksIE1FVEhPRCwgRVJST1JfREVTQ1JJUFRJT04pCisKKyNkZWZpbmUgVVNBR0VfQ0hFQ0tfVFlQRShNRVRIT0QsIENQUFRZUEUpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGlmIChmaWVsZC0+Y3BwX3R5cGUoKSAhPSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfIyNDUFBUWVBFKSAgICAgICAgICAgICAgICAgXAorICAgIFJlcG9ydFJlZmxlY3Rpb25Vc2FnZVR5cGVFcnJvcihkZXNjcmlwdG9yXywgZmllbGQsICNNRVRIT0QsICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFXyMjQ1BQVFlQRSkKKworI2RlZmluZSBVU0FHRV9DSEVDS19FTlVNX1ZBTFVFKE1FVEhPRCkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgaWYgKHZhbHVlLT50eXBlKCkgIT0gZmllbGQtPmVudW1fdHlwZSgpKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgUmVwb3J0UmVmbGVjdGlvblVzYWdlRW51bVR5cGVFcnJvcihkZXNjcmlwdG9yXywgZmllbGQsICNNRVRIT0QsIHZhbHVlKQorCisjZGVmaW5lIFVTQUdFX0NIRUNLX01FU1NBR0VfVFlQRShNRVRIT0QpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBVU0FHRV9DSEVDS19FUShmaWVsZC0+Y29udGFpbmluZ190eXBlKCksIGRlc2NyaXB0b3JfLCAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgTUVUSE9ELCAiRmllbGQgZG9lcyBub3QgbWF0Y2ggbWVzc2FnZSB0eXBlLiIpOworI2RlZmluZSBVU0FHRV9DSEVDS19TSU5HVUxBUihNRVRIT0QpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgVVNBR0VfQ0hFQ0tfTkUoZmllbGQtPmxhYmVsKCksIEZpZWxkRGVzY3JpcHRvcjo6TEFCRUxfUkVQRUFURUQsIE1FVEhPRCwgICAgICBcCisgICAgICAgICAgICAgICAgICJGaWVsZCBpcyByZXBlYXRlZDsgdGhlIG1ldGhvZCByZXF1aXJlcyBhIHNpbmd1bGFyIGZpZWxkLiIpCisjZGVmaW5lIFVTQUdFX0NIRUNLX1JFUEVBVEVEKE1FVEhPRCkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBVU0FHRV9DSEVDS19FUShmaWVsZC0+bGFiZWwoKSwgRmllbGREZXNjcmlwdG9yOjpMQUJFTF9SRVBFQVRFRCwgTUVUSE9ELCAgICAgIFwKKyAgICAgICAgICAgICAgICAgIkZpZWxkIGlzIHNpbmd1bGFyOyB0aGUgbWV0aG9kIHJlcXVpcmVzIGEgcmVwZWF0ZWQgZmllbGQuIikKKworI2RlZmluZSBVU0FHRV9DSEVDS19BTEwoTUVUSE9ELCBMQUJFTCwgQ1BQVFlQRSkgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBVU0FHRV9DSEVDS19NRVNTQUdFX1RZUEUoTUVUSE9EKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgVVNBR0VfQ0hFQ0tfIyNMQUJFTChNRVRIT0QpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIFVTQUdFX0NIRUNLX1RZUEUoTUVUSE9ELCBDUFBUWVBFKQorCit9ICAvLyBuYW1lc3BhY2UKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24oCisgICAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICBjb25zdCBNZXNzYWdlKiBkZWZhdWx0X2luc3RhbmNlLAorICAgIGNvbnN0IGludCBvZmZzZXRzW10sCisgICAgaW50IGhhc19iaXRzX29mZnNldCwKKyAgICBpbnQgdW5rbm93bl9maWVsZHNfb2Zmc2V0LAorICAgIGludCBleHRlbnNpb25zX29mZnNldCwKKyAgICBjb25zdCBEZXNjcmlwdG9yUG9vbCogZGVzY3JpcHRvcl9wb29sLAorICAgIE1lc3NhZ2VGYWN0b3J5KiBmYWN0b3J5LAorICAgIGludCBvYmplY3Rfc2l6ZSwKKyAgICBpbnQgYXJlbmFfb2Zmc2V0LAorICAgIGludCBpc19kZWZhdWx0X2luc3RhbmNlX29mZnNldCkKKyAgOiBkZXNjcmlwdG9yXyAgICAgICAoZGVzY3JpcHRvciksCisgICAgZGVmYXVsdF9pbnN0YW5jZV8gKGRlZmF1bHRfaW5zdGFuY2UpLAorICAgIG9mZnNldHNfICAgICAgICAgIChvZmZzZXRzKSwKKyAgICBoYXNfYml0c19vZmZzZXRfICAoaGFzX2JpdHNfb2Zmc2V0KSwKKyAgICB1bmtub3duX2ZpZWxkc19vZmZzZXRfKHVua25vd25fZmllbGRzX29mZnNldCksCisgICAgZXh0ZW5zaW9uc19vZmZzZXRfKGV4dGVuc2lvbnNfb2Zmc2V0KSwKKyAgICBhcmVuYV9vZmZzZXRfICAgICAoYXJlbmFfb2Zmc2V0KSwKKyAgICBpc19kZWZhdWx0X2luc3RhbmNlX29mZnNldF8oaXNfZGVmYXVsdF9pbnN0YW5jZV9vZmZzZXQpLAorICAgIG9iamVjdF9zaXplXyAgICAgIChvYmplY3Rfc2l6ZSksCisgICAgZGVzY3JpcHRvcl9wb29sXyAgKChkZXNjcmlwdG9yX3Bvb2wgPT0gTlVMTCkgPworICAgICAgICAgICAgICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpnZW5lcmF0ZWRfcG9vbCgpIDoKKyAgICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdG9yX3Bvb2wpLAorICAgIG1lc3NhZ2VfZmFjdG9yeV8gIChmYWN0b3J5KSB7Cit9CisKK0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbigKKyAgICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgIGNvbnN0IE1lc3NhZ2UqIGRlZmF1bHRfaW5zdGFuY2UsCisgICAgY29uc3QgaW50IG9mZnNldHNbXSwKKyAgICBpbnQgaGFzX2JpdHNfb2Zmc2V0LAorICAgIGludCB1bmtub3duX2ZpZWxkc19vZmZzZXQsCisgICAgaW50IGV4dGVuc2lvbnNfb2Zmc2V0LAorICAgIGNvbnN0IHZvaWQqIGRlZmF1bHRfb25lb2ZfaW5zdGFuY2UsCisgICAgaW50IG9uZW9mX2Nhc2Vfb2Zmc2V0LAorICAgIGNvbnN0IERlc2NyaXB0b3JQb29sKiBkZXNjcmlwdG9yX3Bvb2wsCisgICAgTWVzc2FnZUZhY3RvcnkqIGZhY3RvcnksCisgICAgaW50IG9iamVjdF9zaXplLAorICAgIGludCBhcmVuYV9vZmZzZXQsCisgICAgaW50IGlzX2RlZmF1bHRfaW5zdGFuY2Vfb2Zmc2V0KQorICA6IGRlc2NyaXB0b3JfICAgICAgIChkZXNjcmlwdG9yKSwKKyAgICBkZWZhdWx0X2luc3RhbmNlXyAoZGVmYXVsdF9pbnN0YW5jZSksCisgICAgZGVmYXVsdF9vbmVvZl9pbnN0YW5jZV8gKGRlZmF1bHRfb25lb2ZfaW5zdGFuY2UpLAorICAgIG9mZnNldHNfICAgICAgICAgIChvZmZzZXRzKSwKKyAgICBoYXNfYml0c19vZmZzZXRfICAoaGFzX2JpdHNfb2Zmc2V0KSwKKyAgICBvbmVvZl9jYXNlX29mZnNldF8ob25lb2ZfY2FzZV9vZmZzZXQpLAorICAgIHVua25vd25fZmllbGRzX29mZnNldF8odW5rbm93bl9maWVsZHNfb2Zmc2V0KSwKKyAgICBleHRlbnNpb25zX29mZnNldF8oZXh0ZW5zaW9uc19vZmZzZXQpLAorICAgIGFyZW5hX29mZnNldF8gICAgIChhcmVuYV9vZmZzZXQpLAorICAgIGlzX2RlZmF1bHRfaW5zdGFuY2Vfb2Zmc2V0Xyhpc19kZWZhdWx0X2luc3RhbmNlX29mZnNldCksCisgICAgb2JqZWN0X3NpemVfICAgICAgKG9iamVjdF9zaXplKSwKKyAgICBkZXNjcmlwdG9yX3Bvb2xfICAoKGRlc2NyaXB0b3JfcG9vbCA9PSBOVUxMKSA/CisgICAgICAgICAgICAgICAgICAgICAgICAgRGVzY3JpcHRvclBvb2w6OmdlbmVyYXRlZF9wb29sKCkgOgorICAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0b3JfcG9vbCksCisgICAgbWVzc2FnZV9mYWN0b3J5XyAgKGZhY3RvcnkpIHsKK30KKworR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246On5HZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbigpIHt9CisKK25hbWVzcGFjZSB7CitVbmtub3duRmllbGRTZXQqIGVtcHR5X3Vua25vd25fZmllbGRfc2V0XyA9IE5VTEw7CitHT09HTEVfUFJPVE9CVUZfREVDTEFSRV9PTkNFKGVtcHR5X3Vua25vd25fZmllbGRfc2V0X29uY2VfKTsKKwordm9pZCBEZWxldGVFbXB0eVVua25vd25GaWVsZFNldCgpIHsKKyAgZGVsZXRlIGVtcHR5X3Vua25vd25fZmllbGRfc2V0XzsKKyAgZW1wdHlfdW5rbm93bl9maWVsZF9zZXRfID0gTlVMTDsKK30KKwordm9pZCBJbml0RW1wdHlVbmtub3duRmllbGRTZXQoKSB7CisgIGVtcHR5X3Vua25vd25fZmllbGRfc2V0XyA9IG5ldyBVbmtub3duRmllbGRTZXQ7CisgIGludGVybmFsOjpPblNodXRkb3duKCZEZWxldGVFbXB0eVVua25vd25GaWVsZFNldCk7Cit9CisKK2NvbnN0IFVua25vd25GaWVsZFNldCYgR2V0RW1wdHlVbmtub3duRmllbGRTZXQoKSB7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6R29vZ2xlT25jZUluaXQoJmVtcHR5X3Vua25vd25fZmllbGRfc2V0X29uY2VfLCAmSW5pdEVtcHR5VW5rbm93bkZpZWxkU2V0KTsKKyAgcmV0dXJuICplbXB0eV91bmtub3duX2ZpZWxkX3NldF87Cit9Cit9ICAvLyBuYW1lc3BhY2UKKworY29uc3QgVW5rbm93bkZpZWxkU2V0JiBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6R2V0VW5rbm93bkZpZWxkcygKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlKSBjb25zdCB7CisgIGlmIChkZXNjcmlwdG9yXy0+ZmlsZSgpLT5zeW50YXgoKSA9PSBGaWxlRGVzY3JpcHRvcjo6U1lOVEFYX1BST1RPMykgeworICAgIHJldHVybiBHZXRFbXB0eVVua25vd25GaWVsZFNldCgpOworICB9CisgIGlmICh1bmtub3duX2ZpZWxkc19vZmZzZXRfID09IGtVbmtub3duRmllbGRTZXRJbk1ldGFkYXRhKSB7CisgICAgcmV0dXJuIEdldEludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEobWVzc2FnZSkudW5rbm93bl9maWVsZHMoKTsKKyAgfQorICBjb25zdCB2b2lkKiBwdHIgPSByZWludGVycHJldF9jYXN0PGNvbnN0IHVpbnQ4Kj4oJm1lc3NhZ2UpICsKKyAgICAgICAgICAgICAgICAgICAgdW5rbm93bl9maWVsZHNfb2Zmc2V0XzsKKyAgcmV0dXJuICpyZWludGVycHJldF9jYXN0PGNvbnN0IFVua25vd25GaWVsZFNldCo+KHB0cik7Cit9CisKK1Vua25vd25GaWVsZFNldCogR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok11dGFibGVVbmtub3duRmllbGRzKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UpIGNvbnN0IHsKKyAgaWYgKHVua25vd25fZmllbGRzX29mZnNldF8gPT0ga1Vua25vd25GaWVsZFNldEluTWV0YWRhdGEpIHsKKyAgICByZXR1cm4gTXV0YWJsZUludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEobWVzc2FnZSktPgorICAgICAgICBtdXRhYmxlX3Vua25vd25fZmllbGRzKCk7CisgIH0KKyAgdm9pZCogcHRyID0gcmVpbnRlcnByZXRfY2FzdDx1aW50OCo+KG1lc3NhZ2UpICsgdW5rbm93bl9maWVsZHNfb2Zmc2V0XzsKKyAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8VW5rbm93bkZpZWxkU2V0Kj4ocHRyKTsKK30KKworaW50IEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpTcGFjZVVzZWQoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSkgY29uc3QgeworICAvLyBvYmplY3Rfc2l6ZV8gYWxyZWFkeSBpbmNsdWRlcyB0aGUgaW4tbWVtb3J5IHJlcHJlc2VudGF0aW9uIG9mIGVhY2ggZmllbGQKKyAgLy8gaW4gdGhlIG1lc3NhZ2UsIHNvIHdlIG9ubHkgbmVlZCB0byBhY2NvdW50IGZvciBhZGRpdGlvbmFsIG1lbW9yeSB1c2VkIGJ5CisgIC8vIHRoZSBmaWVsZHMuCisgIGludCB0b3RhbF9zaXplID0gb2JqZWN0X3NpemVfOworCisgIHRvdGFsX3NpemUgKz0gR2V0VW5rbm93bkZpZWxkcyhtZXNzYWdlKS5TcGFjZVVzZWRFeGNsdWRpbmdTZWxmKCk7CisKKyAgaWYgKGV4dGVuc2lvbnNfb2Zmc2V0XyAhPSAtMSkgeworICAgIHRvdGFsX3NpemUgKz0gR2V0RXh0ZW5zaW9uU2V0KG1lc3NhZ2UpLlNwYWNlVXNlZEV4Y2x1ZGluZ1NlbGYoKTsKKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBkZXNjcmlwdG9yXy0+ZmllbGQoaSk7CisKKyAgICBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkpIHsKKyAgICAgIHN3aXRjaCAoZmllbGQtPmNwcF90eXBlKCkpIHsKKyNkZWZpbmUgSEFORExFX1RZUEUoVVBQRVJDQVNFLCBMT1dFUkNBU0UpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfIyNVUFBFUkNBU0UgOiAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICB0b3RhbF9zaXplICs9IEdldFJhdzxSZXBlYXRlZEZpZWxkPExPV0VSQ0FTRT4gPihtZXNzYWdlLCBmaWVsZCkgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgLlNwYWNlVXNlZEV4Y2x1ZGluZ1NlbGYoKTsgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICBicmVhaworCisgICAgICAgIEhBTkRMRV9UWVBFKCBJTlQzMiwgIGludDMyKTsKKyAgICAgICAgSEFORExFX1RZUEUoIElOVDY0LCAgaW50NjQpOworICAgICAgICBIQU5ETEVfVFlQRShVSU5UMzIsIHVpbnQzMik7CisgICAgICAgIEhBTkRMRV9UWVBFKFVJTlQ2NCwgdWludDY0KTsKKyAgICAgICAgSEFORExFX1RZUEUoRE9VQkxFLCBkb3VibGUpOworICAgICAgICBIQU5ETEVfVFlQRSggRkxPQVQsICBmbG9hdCk7CisgICAgICAgIEhBTkRMRV9UWVBFKCAgQk9PTCwgICBib29sKTsKKyAgICAgICAgSEFORExFX1RZUEUoICBFTlVNLCAgICBpbnQpOworI3VuZGVmIEhBTkRMRV9UWVBFCisKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HOgorICAgICAgICAgIHN3aXRjaCAoZmllbGQtPm9wdGlvbnMoKS5jdHlwZSgpKSB7CisgICAgICAgICAgICBkZWZhdWx0OiAgLy8gVE9ETyhrZW50b24pOiAgU3VwcG9ydCBvdGhlciBzdHJpbmcgcmVwcy4KKyAgICAgICAgICAgIGNhc2UgRmllbGRPcHRpb25zOjpTVFJJTkc6CisgICAgICAgICAgICAgIHRvdGFsX3NpemUgKz0gR2V0UmF3PFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPiA+KG1lc3NhZ2UsIGZpZWxkKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLlNwYWNlVXNlZEV4Y2x1ZGluZ1NlbGYoKTsKKyAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgfQorICAgICAgICAgIGJyZWFrOworCisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U6CisgICAgICAgICAgaWYgKElzTWFwRmllbGRJbkFwaShmaWVsZCkpIHsKKyAgICAgICAgICAgIHRvdGFsX3NpemUgKz0KKyAgICAgICAgICAgICAgICBHZXRSYXc8TWFwRmllbGRCYXNlPihtZXNzYWdlLCBmaWVsZCkuU3BhY2VVc2VkRXhjbHVkaW5nU2VsZigpOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvLyBXZSBkb24ndCBrbm93IHdoaWNoIHN1YmNsYXNzIG9mIFJlcGVhdGVkUHRyRmllbGRCYXNlIHRoZSB0eXBlIGlzLAorICAgICAgICAgICAgLy8gc28gd2UgdXNlIFJlcGVhdGVkUHRyRmllbGRCYXNlIGRpcmVjdGx5LgorICAgICAgICAgICAgdG90YWxfc2l6ZSArPQorICAgICAgICAgICAgICAgIEdldFJhdzxSZXBlYXRlZFB0ckZpZWxkQmFzZT4obWVzc2FnZSwgZmllbGQpCisgICAgICAgICAgICAgICAgICAuU3BhY2VVc2VkRXhjbHVkaW5nU2VsZjxHZW5lcmljVHlwZUhhbmRsZXI8TWVzc2FnZT4gPigpOworICAgICAgICAgIH0KKworICAgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICBpZiAoZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSAmJiAhSGFzT25lb2ZGaWVsZChtZXNzYWdlLCBmaWVsZCkpIHsKKyAgICAgICAgY29udGludWU7CisgICAgICB9CisgICAgICBzd2l0Y2ggKGZpZWxkLT5jcHBfdHlwZSgpKSB7CisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0lOVDMyIDoKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UNjQgOgorICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9VSU5UMzI6CisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1VJTlQ2NDoKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRE9VQkxFOgorICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9GTE9BVCA6CisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0JPT0wgIDoKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRU5VTSAgOgorICAgICAgICAgIC8vIEZpZWxkIGlzIGlubGluZSwgc28gd2UndmUgYWxyZWFkeSBjb3VudGVkIGl0LgorICAgICAgICAgIGJyZWFrOworCisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORzogeworICAgICAgICAgIHN3aXRjaCAoZmllbGQtPm9wdGlvbnMoKS5jdHlwZSgpKSB7CisgICAgICAgICAgICBkZWZhdWx0OiAgLy8gVE9ETyhrZW50b24pOiAgU3VwcG9ydCBvdGhlciBzdHJpbmcgcmVwcy4KKyAgICAgICAgICAgIGNhc2UgRmllbGRPcHRpb25zOjpTVFJJTkc6IHsKKyAgICAgICAgICAgICAgLy8gSW5pdGlhbGx5LCB0aGUgc3RyaW5nIHBvaW50cyB0byB0aGUgZGVmYXVsdCB2YWx1ZSBzdG9yZWQgaW4KKyAgICAgICAgICAgICAgLy8gdGhlIHByb3RvdHlwZS4gT25seSBjb3VudCB0aGUgc3RyaW5nIGlmIGl0IGhhcyBiZWVuIGNoYW5nZWQKKyAgICAgICAgICAgICAgLy8gZnJvbSB0aGUgZGVmYXVsdCB2YWx1ZS4KKyAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nKiBkZWZhdWx0X3B0ciA9CisgICAgICAgICAgICAgICAgICAmRGVmYXVsdFJhdzxBcmVuYVN0cmluZ1B0cj4oZmllbGQpLkdldChOVUxMKTsKKyAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nKiBwdHIgPQorICAgICAgICAgICAgICAgICAgJkdldEZpZWxkPEFyZW5hU3RyaW5nUHRyPihtZXNzYWdlLCBmaWVsZCkuR2V0KGRlZmF1bHRfcHRyKTsKKworICAgICAgICAgICAgICBpZiAocHRyICE9IGRlZmF1bHRfcHRyKSB7CisgICAgICAgICAgICAgICAgLy8gc3RyaW5nIGZpZWxkcyBhcmUgcmVwcmVzZW50ZWQgYnkganVzdCBhIHBvaW50ZXIsIHNvIGFsc28KKyAgICAgICAgICAgICAgICAvLyBpbmNsdWRlIHNpemVvZihzdHJpbmcpIGFzIHdlbGwuCisgICAgICAgICAgICAgICAgdG90YWxfc2l6ZSArPSBzaXplb2YoKnB0cikgKyBTdHJpbmdTcGFjZVVzZWRFeGNsdWRpbmdTZWxmKCpwdHIpOworICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgIH0KKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorCisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U6CisgICAgICAgICAgaWYgKCZtZXNzYWdlID09IGRlZmF1bHRfaW5zdGFuY2VfKSB7CisgICAgICAgICAgICAvLyBGb3Igc2luZ3VsYXIgZmllbGRzLCB0aGUgcHJvdG90eXBlIGp1c3Qgc3RvcmVzIGEgcG9pbnRlciB0byB0aGUKKyAgICAgICAgICAgIC8vIGV4dGVybmFsIHR5cGUncyBwcm90b3R5cGUsIHNvIHRoZXJlIGlzIG5vIGV4dHJhIG1lbW9yeSB1c2FnZS4KKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgY29uc3QgTWVzc2FnZSogc3ViX21lc3NhZ2UgPSBHZXRSYXc8Y29uc3QgTWVzc2FnZSo+KG1lc3NhZ2UsIGZpZWxkKTsKKyAgICAgICAgICAgIGlmIChzdWJfbWVzc2FnZSAhPSBOVUxMKSB7CisgICAgICAgICAgICAgIHRvdGFsX3NpemUgKz0gc3ViX21lc3NhZ2UtPlNwYWNlVXNlZCgpOworICAgICAgICAgICAgfQorICAgICAgICAgIH0KKyAgICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICByZXR1cm4gdG90YWxfc2l6ZTsKK30KKwordm9pZCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6U3dhcEZpZWxkKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UxLAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UyLAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0IHsKKyAgaWYgKGZpZWxkLT5pc19yZXBlYXRlZCgpKSB7CisgICAgc3dpdGNoIChmaWVsZC0+Y3BwX3R5cGUoKSkgeworI2RlZmluZSBTV0FQX0FSUkFZUyhDUFBUWVBFLCBUWVBFKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfIyNDUFBUWVBFOiAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBNdXRhYmxlUmF3PFJlcGVhdGVkRmllbGQ8VFlQRT4gPihtZXNzYWdlMSwgZmllbGQpLT5Td2FwKCAgICAgICAgXAorICAgICAgICAgICAgTXV0YWJsZVJhdzxSZXBlYXRlZEZpZWxkPFRZUEU+ID4obWVzc2FnZTIsIGZpZWxkKSk7ICAgICAgICAgXAorICAgICAgICBicmVhazsKKworICAgICAgU1dBUF9BUlJBWVMoSU5UMzIgLCBpbnQzMiApOworICAgICAgU1dBUF9BUlJBWVMoSU5UNjQgLCBpbnQ2NCApOworICAgICAgU1dBUF9BUlJBWVMoVUlOVDMyLCB1aW50MzIpOworICAgICAgU1dBUF9BUlJBWVMoVUlOVDY0LCB1aW50NjQpOworICAgICAgU1dBUF9BUlJBWVMoRkxPQVQgLCBmbG9hdCApOworICAgICAgU1dBUF9BUlJBWVMoRE9VQkxFLCBkb3VibGUpOworICAgICAgU1dBUF9BUlJBWVMoQk9PTCAgLCBib29sICApOworICAgICAgU1dBUF9BUlJBWVMoRU5VTSAgLCBpbnQgICApOworI3VuZGVmIFNXQVBfQVJSQVlTCisKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORzoKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U6CisgICAgICAgIGlmIChJc01hcEZpZWxkSW5BcGkoZmllbGQpKSB7CisgICAgICAgICAgTXV0YWJsZVJhdzxNYXBGaWVsZEJhc2U+KG1lc3NhZ2UxLCBmaWVsZCktPgorICAgICAgICAgICAgTXV0YWJsZVJlcGVhdGVkRmllbGQoKS0+CisgICAgICAgICAgICAgIFN3YXA8R2VuZXJpY1R5cGVIYW5kbGVyPGdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2U+ID4oCisgICAgICAgICAgICAgICAgTXV0YWJsZVJhdzxNYXBGaWVsZEJhc2U+KG1lc3NhZ2UyLCBmaWVsZCktPgorICAgICAgICAgICAgICAgICAgTXV0YWJsZVJlcGVhdGVkRmllbGQoKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgTXV0YWJsZVJhdzxSZXBlYXRlZFB0ckZpZWxkQmFzZT4obWVzc2FnZTEsIGZpZWxkKS0+CisgICAgICAgICAgICBTd2FwPEdlbmVyaWNUeXBlSGFuZGxlcjxnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlPiA+KAorICAgICAgICAgICAgICBNdXRhYmxlUmF3PFJlcGVhdGVkUHRyRmllbGRCYXNlPihtZXNzYWdlMiwgZmllbGQpKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIlVuaW1wbGVtZW50ZWQgdHlwZTogIiA8PCBmaWVsZC0+Y3BwX3R5cGUoKTsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgc3dpdGNoIChmaWVsZC0+Y3BwX3R5cGUoKSkgeworI2RlZmluZSBTV0FQX1ZBTFVFUyhDUFBUWVBFLCBUWVBFKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfIyNDUFBUWVBFOiAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBzdGQ6OnN3YXAoKk11dGFibGVSYXc8VFlQRT4obWVzc2FnZTEsIGZpZWxkKSwgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgKk11dGFibGVSYXc8VFlQRT4obWVzc2FnZTIsIGZpZWxkKSk7ICAgICAgICAgICAgICAgICAgXAorICAgICAgICBicmVhazsKKworICAgICAgU1dBUF9WQUxVRVMoSU5UMzIgLCBpbnQzMiApOworICAgICAgU1dBUF9WQUxVRVMoSU5UNjQgLCBpbnQ2NCApOworICAgICAgU1dBUF9WQUxVRVMoVUlOVDMyLCB1aW50MzIpOworICAgICAgU1dBUF9WQUxVRVMoVUlOVDY0LCB1aW50NjQpOworICAgICAgU1dBUF9WQUxVRVMoRkxPQVQgLCBmbG9hdCApOworICAgICAgU1dBUF9WQUxVRVMoRE9VQkxFLCBkb3VibGUpOworICAgICAgU1dBUF9WQUxVRVMoQk9PTCAgLCBib29sICApOworICAgICAgU1dBUF9WQUxVRVMoRU5VTSAgLCBpbnQgICApOworI3VuZGVmIFNXQVBfVkFMVUVTCisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgICBzdGQ6OnN3YXAoKk11dGFibGVSYXc8TWVzc2FnZSo+KG1lc3NhZ2UxLCBmaWVsZCksCisgICAgICAgICAgICAgICAgICAqTXV0YWJsZVJhdzxNZXNzYWdlKj4obWVzc2FnZTIsIGZpZWxkKSk7CisgICAgICAgIGJyZWFrOworCisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9TVFJJTkc6CisgICAgICAgIHN3aXRjaCAoZmllbGQtPm9wdGlvbnMoKS5jdHlwZSgpKSB7CisgICAgICAgICAgZGVmYXVsdDogIC8vIFRPRE8oa2VudG9uKTogIFN1cHBvcnQgb3RoZXIgc3RyaW5nIHJlcHMuCisgICAgICAgICAgY2FzZSBGaWVsZE9wdGlvbnM6OlNUUklORzoKKyAgICAgICAgICAgIE11dGFibGVSYXc8QXJlbmFTdHJpbmdQdHI+KG1lc3NhZ2UxLCBmaWVsZCktPlN3YXAoCisgICAgICAgICAgICAgICAgTXV0YWJsZVJhdzxBcmVuYVN0cmluZ1B0cj4obWVzc2FnZTIsIGZpZWxkKSk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIlVuaW1wbGVtZW50ZWQgdHlwZTogIiA8PCBmaWVsZC0+Y3BwX3R5cGUoKTsKKyAgICB9CisgIH0KK30KKwordm9pZCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6U3dhcE9uZW9mRmllbGQoCisgICAgTWVzc2FnZSogbWVzc2FnZTEsCisgICAgTWVzc2FnZSogbWVzc2FnZTIsCisgICAgY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBvbmVvZl9kZXNjcmlwdG9yKSBjb25zdCB7CisgIHVpbnQzMiBvbmVvZl9jYXNlMSA9IEdldE9uZW9mQ2FzZSgqbWVzc2FnZTEsIG9uZW9mX2Rlc2NyaXB0b3IpOworICB1aW50MzIgb25lb2ZfY2FzZTIgPSBHZXRPbmVvZkNhc2UoKm1lc3NhZ2UyLCBvbmVvZl9kZXNjcmlwdG9yKTsKKworICBpbnQzMiB0ZW1wX2ludDMyOworICBpbnQ2NCB0ZW1wX2ludDY0OworICB1aW50MzIgdGVtcF91aW50MzI7CisgIHVpbnQ2NCB0ZW1wX3VpbnQ2NDsKKyAgZmxvYXQgdGVtcF9mbG9hdDsKKyAgZG91YmxlIHRlbXBfZG91YmxlOworICBib29sIHRlbXBfYm9vbDsKKyAgaW50IHRlbXBfaW50OworICBNZXNzYWdlKiB0ZW1wX21lc3NhZ2UgPSBOVUxMOworICBzdHJpbmcgdGVtcF9zdHJpbmc7CisKKyAgLy8gU3RvcmVzIG1lc3NhZ2UxJ3Mgb25lb2YgZmllbGQgdG8gYSB0ZW1wIHZhcmlhYmxlLgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkMSA9IE5VTEw7CisgIGlmIChvbmVvZl9jYXNlMSA+IDApIHsKKyAgICBmaWVsZDEgPSBkZXNjcmlwdG9yXy0+RmluZEZpZWxkQnlOdW1iZXIob25lb2ZfY2FzZTEpOworICAgIC8vb25lb2ZfZGVzY3JpcHRvci0+ZmllbGQob25lb2ZfY2FzZTEpOworICAgIHN3aXRjaCAoZmllbGQxLT5jcHBfdHlwZSgpKSB7CisjZGVmaW5lIEdFVF9URU1QX1ZBTFVFKENQUFRZUEUsIFRZUEUpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV8jI0NQUFRZUEU6ICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIHRlbXBfIyNUWVBFID0gR2V0RmllbGQ8VFlQRT4oKm1lc3NhZ2UxLCBmaWVsZDEpOyAgICAgICAgICAgICAgICBcCisgICAgICAgIGJyZWFrOworCisgICAgICBHRVRfVEVNUF9WQUxVRShJTlQzMiAsIGludDMyICk7CisgICAgICBHRVRfVEVNUF9WQUxVRShJTlQ2NCAsIGludDY0ICk7CisgICAgICBHRVRfVEVNUF9WQUxVRShVSU5UMzIsIHVpbnQzMik7CisgICAgICBHRVRfVEVNUF9WQUxVRShVSU5UNjQsIHVpbnQ2NCk7CisgICAgICBHRVRfVEVNUF9WQUxVRShGTE9BVCAsIGZsb2F0ICk7CisgICAgICBHRVRfVEVNUF9WQUxVRShET1VCTEUsIGRvdWJsZSk7CisgICAgICBHRVRfVEVNUF9WQUxVRShCT09MICAsIGJvb2wgICk7CisgICAgICBHRVRfVEVNUF9WQUxVRShFTlVNICAsIGludCAgICk7CisjdW5kZWYgR0VUX1RFTVBfVkFMVUUKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U6CisgICAgICAgIHRlbXBfbWVzc2FnZSA9IFJlbGVhc2VNZXNzYWdlKG1lc3NhZ2UxLCBmaWVsZDEpOworICAgICAgICBicmVhazsKKworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HOgorICAgICAgICB0ZW1wX3N0cmluZyA9IEdldFN0cmluZygqbWVzc2FnZTEsIGZpZWxkMSk7CisgICAgICAgIGJyZWFrOworCisgICAgICBkZWZhdWx0OgorICAgICAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiVW5pbXBsZW1lbnRlZCB0eXBlOiAiIDw8IGZpZWxkMS0+Y3BwX3R5cGUoKTsKKyAgICB9CisgIH0KKworICAvLyBTZXRzIG1lc3NhZ2UxJ3Mgb25lb2YgZmllbGQgZnJvbSB0aGUgbWVzc2FnZTIncyBvbmVvZiBmaWVsZC4KKyAgaWYgKG9uZW9mX2Nhc2UyID4gMCkgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQyID0KKyAgICAgICAgZGVzY3JpcHRvcl8tPkZpbmRGaWVsZEJ5TnVtYmVyKG9uZW9mX2Nhc2UyKTsKKyAgICBzd2l0Y2ggKGZpZWxkMi0+Y3BwX3R5cGUoKSkgeworI2RlZmluZSBTRVRfT05FT0ZfVkFMVUUxKENQUFRZUEUsIFRZUEUpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfIyNDUFBUWVBFOiAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBTZXRGaWVsZDxUWVBFPihtZXNzYWdlMSwgZmllbGQyLCBHZXRGaWVsZDxUWVBFPigqbWVzc2FnZTIsIGZpZWxkMikpOyBcCisgICAgICAgIGJyZWFrOworCisgICAgICBTRVRfT05FT0ZfVkFMVUUxKElOVDMyICwgaW50MzIgKTsKKyAgICAgIFNFVF9PTkVPRl9WQUxVRTEoSU5UNjQgLCBpbnQ2NCApOworICAgICAgU0VUX09ORU9GX1ZBTFVFMShVSU5UMzIsIHVpbnQzMik7CisgICAgICBTRVRfT05FT0ZfVkFMVUUxKFVJTlQ2NCwgdWludDY0KTsKKyAgICAgIFNFVF9PTkVPRl9WQUxVRTEoRkxPQVQgLCBmbG9hdCApOworICAgICAgU0VUX09ORU9GX1ZBTFVFMShET1VCTEUsIGRvdWJsZSk7CisgICAgICBTRVRfT05FT0ZfVkFMVUUxKEJPT0wgICwgYm9vbCAgKTsKKyAgICAgIFNFVF9PTkVPRl9WQUxVRTEoRU5VTSAgLCBpbnQgICApOworI3VuZGVmIFNFVF9PTkVPRl9WQUxVRTEKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U6CisgICAgICAgIFNldEFsbG9jYXRlZE1lc3NhZ2UobWVzc2FnZTEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVsZWFzZU1lc3NhZ2UobWVzc2FnZTIsIGZpZWxkMiksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGQyKTsKKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORzoKKyAgICAgICAgU2V0U3RyaW5nKG1lc3NhZ2UxLCBmaWVsZDIsIEdldFN0cmluZygqbWVzc2FnZTIsIGZpZWxkMikpOworICAgICAgICBicmVhazsKKworICAgICAgZGVmYXVsdDoKKyAgICAgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIlVuaW1wbGVtZW50ZWQgdHlwZTogIiA8PCBmaWVsZDItPmNwcF90eXBlKCk7CisgICAgfQorICB9IGVsc2UgeworICAgIENsZWFyT25lb2YobWVzc2FnZTEsIG9uZW9mX2Rlc2NyaXB0b3IpOworICB9CisKKyAgLy8gU2V0cyBtZXNzYWdlMidzIG9uZW9mIGZpZWxkIGZyb20gdGhlIHRlbXAgdmFyaWFibGUuCisgIGlmIChvbmVvZl9jYXNlMSA+IDApIHsKKyAgICBzd2l0Y2ggKGZpZWxkMS0+Y3BwX3R5cGUoKSkgeworI2RlZmluZSBTRVRfT05FT0ZfVkFMVUUyKENQUFRZUEUsIFRZUEUpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfIyNDUFBUWVBFOiAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBTZXRGaWVsZDxUWVBFPihtZXNzYWdlMiwgZmllbGQxLCB0ZW1wXyMjVFlQRSk7ICAgICAgICAgICAgICAgICAgXAorICAgICAgICBicmVhazsKKworICAgICAgU0VUX09ORU9GX1ZBTFVFMihJTlQzMiAsIGludDMyICk7CisgICAgICBTRVRfT05FT0ZfVkFMVUUyKElOVDY0ICwgaW50NjQgKTsKKyAgICAgIFNFVF9PTkVPRl9WQUxVRTIoVUlOVDMyLCB1aW50MzIpOworICAgICAgU0VUX09ORU9GX1ZBTFVFMihVSU5UNjQsIHVpbnQ2NCk7CisgICAgICBTRVRfT05FT0ZfVkFMVUUyKEZMT0FUICwgZmxvYXQgKTsKKyAgICAgIFNFVF9PTkVPRl9WQUxVRTIoRE9VQkxFLCBkb3VibGUpOworICAgICAgU0VUX09ORU9GX1ZBTFVFMihCT09MICAsIGJvb2wgICk7CisgICAgICBTRVRfT05FT0ZfVkFMVUUyKEVOVU0gICwgaW50ICAgKTsKKyN1bmRlZiBTRVRfT05FT0ZfVkFMVUUyCisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgICBTZXRBbGxvY2F0ZWRNZXNzYWdlKG1lc3NhZ2UyLCB0ZW1wX21lc3NhZ2UsIGZpZWxkMSk7CisgICAgICAgIGJyZWFrOworCisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9TVFJJTkc6CisgICAgICAgIFNldFN0cmluZyhtZXNzYWdlMiwgZmllbGQxLCB0ZW1wX3N0cmluZyk7CisgICAgICAgIGJyZWFrOworCisgICAgICBkZWZhdWx0OgorICAgICAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiVW5pbXBsZW1lbnRlZCB0eXBlOiAiIDw8IGZpZWxkMS0+Y3BwX3R5cGUoKTsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgQ2xlYXJPbmVvZihtZXNzYWdlMiwgb25lb2ZfZGVzY3JpcHRvcik7CisgIH0KK30KKwordm9pZCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6U3dhcCgKKyAgICBNZXNzYWdlKiBtZXNzYWdlMSwKKyAgICBNZXNzYWdlKiBtZXNzYWdlMikgY29uc3QgeworICBpZiAobWVzc2FnZTEgPT0gbWVzc2FnZTIpIHJldHVybjsKKworICAvLyBUT0RPKGtlbnRvbik6ICBPdGhlciBSZWZsZWN0aW9uIG1ldGhvZHMgc2hvdWxkIHByb2JhYmx5IGNoZWNrIHRoaXMgdG9vLgorICBHT09HTEVfQ0hFQ0tfRVEobWVzc2FnZTEtPkdldFJlZmxlY3Rpb24oKSwgdGhpcykKKyAgICA8PCAiRmlyc3QgYXJndW1lbnQgdG8gU3dhcCgpIChvZiB0eXBlIFwiIgorICAgIDw8IG1lc3NhZ2UxLT5HZXREZXNjcmlwdG9yKCktPmZ1bGxfbmFtZSgpCisgICAgPDwgIlwiKSBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHRoaXMgcmVmbGVjdGlvbiBvYmplY3QgKHdoaWNoIGlzIGZvciB0eXBlIFwiIgorICAgIDw8IGRlc2NyaXB0b3JfLT5mdWxsX25hbWUoKQorICAgIDw8ICJcIikuICBOb3RlIHRoYXQgdGhlIGV4YWN0IHNhbWUgY2xhc3MgaXMgcmVxdWlyZWQ7IG5vdCBqdXN0IHRoZSBzYW1lICIKKyAgICAgICAiZGVzY3JpcHRvci4iOworICBHT09HTEVfQ0hFQ0tfRVEobWVzc2FnZTItPkdldFJlZmxlY3Rpb24oKSwgdGhpcykKKyAgICA8PCAiU2Vjb25kIGFyZ3VtZW50IHRvIFN3YXAoKSAob2YgdHlwZSBcIiIKKyAgICA8PCBtZXNzYWdlMi0+R2V0RGVzY3JpcHRvcigpLT5mdWxsX25hbWUoKQorICAgIDw8ICJcIikgaXMgbm90IGNvbXBhdGlibGUgd2l0aCB0aGlzIHJlZmxlY3Rpb24gb2JqZWN0ICh3aGljaCBpcyBmb3IgdHlwZSBcIiIKKyAgICA8PCBkZXNjcmlwdG9yXy0+ZnVsbF9uYW1lKCkKKyAgICA8PCAiXCIpLiAgTm90ZSB0aGF0IHRoZSBleGFjdCBzYW1lIGNsYXNzIGlzIHJlcXVpcmVkOyBub3QganVzdCB0aGUgc2FtZSAiCisgICAgICAgImRlc2NyaXB0b3IuIjsKKworICAvLyBDaGVjayB0aGF0IGJvdGggbWVzc2FnZXMgYXJlIGluIHRoZSBzYW1lIGFyZW5hIChvciBib3RoIG9uIHRoZSBoZWFwKS4gV2UKKyAgLy8gbmVlZCB0byBjb3B5IGFsbCBkYXRhIGlmIG5vdCwgZHVlIHRvIG93bmVyc2hpcCBzZW1hbnRpY3MuCisgIGlmIChHZXRBcmVuYShtZXNzYWdlMSkgIT0gR2V0QXJlbmEobWVzc2FnZTIpKSB7CisgICAgLy8gU2xvdyBjb3B5IHBhdGguCisgICAgLy8gVXNlIG91ciBhcmVuYSBhcyB0ZW1wIHNwYWNlLCBpZiBhdmFpbGFibGUuCisgICAgTWVzc2FnZSogdGVtcCA9IG1lc3NhZ2UxLT5OZXcoR2V0QXJlbmEobWVzc2FnZTEpKTsKKyAgICB0ZW1wLT5NZXJnZUZyb20oKm1lc3NhZ2UxKTsKKyAgICBtZXNzYWdlMS0+Q29weUZyb20oKm1lc3NhZ2UyKTsKKyAgICBtZXNzYWdlMi0+Q29weUZyb20oKnRlbXApOworICAgIGlmIChHZXRBcmVuYShtZXNzYWdlMSkgPT0gTlVMTCkgeworICAgICAgZGVsZXRlIHRlbXA7CisgICAgfQorICAgIHJldHVybjsKKyAgfQorCisgIGlmIChoYXNfYml0c19vZmZzZXRfICE9IC0xKSB7CisgICAgdWludDMyKiBoYXNfYml0czEgPSBNdXRhYmxlSGFzQml0cyhtZXNzYWdlMSk7CisgICAgdWludDMyKiBoYXNfYml0czIgPSBNdXRhYmxlSGFzQml0cyhtZXNzYWdlMik7CisgICAgaW50IGhhc19iaXRzX3NpemUgPSAoZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCkgKyAzMSkgLyAzMjsKKworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaGFzX2JpdHNfc2l6ZTsgaSsrKSB7CisgICAgICBzdGQ6OnN3YXAoaGFzX2JpdHMxW2ldLCBoYXNfYml0czJbaV0pOworICAgIH0KKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBkZXNjcmlwdG9yXy0+ZmllbGQoaSk7CisgICAgaWYgKCFmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpKSB7CisgICAgICBTd2FwRmllbGQobWVzc2FnZTEsIG1lc3NhZ2UyLCBmaWVsZCk7CisgICAgfQorICB9CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+b25lb2ZfZGVjbF9jb3VudCgpOyBpKyspIHsKKyAgICBTd2FwT25lb2ZGaWVsZChtZXNzYWdlMSwgbWVzc2FnZTIsIGRlc2NyaXB0b3JfLT5vbmVvZl9kZWNsKGkpKTsKKyAgfQorCisgIGlmIChleHRlbnNpb25zX29mZnNldF8gIT0gLTEpIHsKKyAgICBNdXRhYmxlRXh0ZW5zaW9uU2V0KG1lc3NhZ2UxKS0+U3dhcChNdXRhYmxlRXh0ZW5zaW9uU2V0KG1lc3NhZ2UyKSk7CisgIH0KKworICBNdXRhYmxlVW5rbm93bkZpZWxkcyhtZXNzYWdlMSktPlN3YXAoTXV0YWJsZVVua25vd25GaWVsZHMobWVzc2FnZTIpKTsKK30KKwordm9pZCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6U3dhcEZpZWxkcygKKyAgICBNZXNzYWdlKiBtZXNzYWdlMSwKKyAgICBNZXNzYWdlKiBtZXNzYWdlMiwKKyAgICBjb25zdCB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4mIGZpZWxkcykgY29uc3QgeworICBpZiAobWVzc2FnZTEgPT0gbWVzc2FnZTIpIHJldHVybjsKKworICAvLyBUT0RPKGtlbnRvbik6ICBPdGhlciBSZWZsZWN0aW9uIG1ldGhvZHMgc2hvdWxkIHByb2JhYmx5IGNoZWNrIHRoaXMgdG9vLgorICBHT09HTEVfQ0hFQ0tfRVEobWVzc2FnZTEtPkdldFJlZmxlY3Rpb24oKSwgdGhpcykKKyAgICA8PCAiRmlyc3QgYXJndW1lbnQgdG8gU3dhcEZpZWxkcygpIChvZiB0eXBlIFwiIgorICAgIDw8IG1lc3NhZ2UxLT5HZXREZXNjcmlwdG9yKCktPmZ1bGxfbmFtZSgpCisgICAgPDwgIlwiKSBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHRoaXMgcmVmbGVjdGlvbiBvYmplY3QgKHdoaWNoIGlzIGZvciB0eXBlIFwiIgorICAgIDw8IGRlc2NyaXB0b3JfLT5mdWxsX25hbWUoKQorICAgIDw8ICJcIikuICBOb3RlIHRoYXQgdGhlIGV4YWN0IHNhbWUgY2xhc3MgaXMgcmVxdWlyZWQ7IG5vdCBqdXN0IHRoZSBzYW1lICIKKyAgICAgICAiZGVzY3JpcHRvci4iOworICBHT09HTEVfQ0hFQ0tfRVEobWVzc2FnZTItPkdldFJlZmxlY3Rpb24oKSwgdGhpcykKKyAgICA8PCAiU2Vjb25kIGFyZ3VtZW50IHRvIFN3YXBGaWVsZHMoKSAob2YgdHlwZSBcIiIKKyAgICA8PCBtZXNzYWdlMi0+R2V0RGVzY3JpcHRvcigpLT5mdWxsX25hbWUoKQorICAgIDw8ICJcIikgaXMgbm90IGNvbXBhdGlibGUgd2l0aCB0aGlzIHJlZmxlY3Rpb24gb2JqZWN0ICh3aGljaCBpcyBmb3IgdHlwZSBcIiIKKyAgICA8PCBkZXNjcmlwdG9yXy0+ZnVsbF9uYW1lKCkKKyAgICA8PCAiXCIpLiAgTm90ZSB0aGF0IHRoZSBleGFjdCBzYW1lIGNsYXNzIGlzIHJlcXVpcmVkOyBub3QganVzdCB0aGUgc2FtZSAiCisgICAgICAgImRlc2NyaXB0b3IuIjsKKworICBzdGQ6OnNldDxpbnQ+IHN3YXBwZWRfb25lb2Y7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZHMuc2l6ZSgpOyBpKyspIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZmllbGRzW2ldOworICAgIGlmIChmaWVsZC0+aXNfZXh0ZW5zaW9uKCkpIHsKKyAgICAgIE11dGFibGVFeHRlbnNpb25TZXQobWVzc2FnZTEpLT5Td2FwRXh0ZW5zaW9uKAorICAgICAgICAgIE11dGFibGVFeHRlbnNpb25TZXQobWVzc2FnZTIpLAorICAgICAgICAgIGZpZWxkLT5udW1iZXIoKSk7CisgICAgfSBlbHNlIHsKKyAgICAgIGlmIChmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpKSB7CisgICAgICAgIGludCBvbmVvZl9pbmRleCA9IGZpZWxkLT5jb250YWluaW5nX29uZW9mKCktPmluZGV4KCk7CisgICAgICAgIC8vIE9ubHkgc3dhcCB0aGUgb25lb2YgZmllbGQgb25jZS4KKyAgICAgICAgaWYgKHN3YXBwZWRfb25lb2YuZmluZChvbmVvZl9pbmRleCkgIT0gc3dhcHBlZF9vbmVvZi5lbmQoKSkgeworICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisgICAgICAgIHN3YXBwZWRfb25lb2YuaW5zZXJ0KG9uZW9mX2luZGV4KTsKKyAgICAgICAgU3dhcE9uZW9mRmllbGQobWVzc2FnZTEsIG1lc3NhZ2UyLCBmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIC8vIFN3YXAgaGFzIGJpdC4KKyAgICAgICAgU3dhcEJpdChtZXNzYWdlMSwgbWVzc2FnZTIsIGZpZWxkKTsKKyAgICAgICAgLy8gU3dhcCBmaWVsZC4KKyAgICAgICAgU3dhcEZpZWxkKG1lc3NhZ2UxLCBtZXNzYWdlMiwgZmllbGQpOworICAgICAgfQorICAgIH0KKyAgfQorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2Jvb2wgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Okhhc0ZpZWxkKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7CisgIFVTQUdFX0NIRUNLX01FU1NBR0VfVFlQRShIYXNGaWVsZCk7CisgIFVTQUdFX0NIRUNLX1NJTkdVTEFSKEhhc0ZpZWxkKTsKKworICBpZiAoZmllbGQtPmlzX2V4dGVuc2lvbigpKSB7CisgICAgcmV0dXJuIEdldEV4dGVuc2lvblNldChtZXNzYWdlKS5IYXMoZmllbGQtPm51bWJlcigpKTsKKyAgfSBlbHNlIHsKKyAgICBpZiAoZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSkgeworICAgICAgcmV0dXJuIEhhc09uZW9mRmllbGQobWVzc2FnZSwgZmllbGQpOworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gSGFzQml0KG1lc3NhZ2UsIGZpZWxkKTsKKyAgICB9CisgIH0KK30KKworaW50IEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpGaWVsZFNpemUoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0IHsKKyAgVVNBR0VfQ0hFQ0tfTUVTU0FHRV9UWVBFKEZpZWxkU2l6ZSk7CisgIFVTQUdFX0NIRUNLX1JFUEVBVEVEKEZpZWxkU2l6ZSk7CisKKyAgaWYgKGZpZWxkLT5pc19leHRlbnNpb24oKSkgeworICAgIHJldHVybiBHZXRFeHRlbnNpb25TZXQobWVzc2FnZSkuRXh0ZW5zaW9uU2l6ZShmaWVsZC0+bnVtYmVyKCkpOworICB9IGVsc2UgeworICAgIHN3aXRjaCAoZmllbGQtPmNwcF90eXBlKCkpIHsKKyNkZWZpbmUgSEFORExFX1RZUEUoVVBQRVJDQVNFLCBMT1dFUkNBU0UpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFXyMjVVBQRVJDQVNFIDogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgcmV0dXJuIEdldFJhdzxSZXBlYXRlZEZpZWxkPExPV0VSQ0FTRT4gPihtZXNzYWdlLCBmaWVsZCkuc2l6ZSgpCisKKyAgICAgIEhBTkRMRV9UWVBFKCBJTlQzMiwgIGludDMyKTsKKyAgICAgIEhBTkRMRV9UWVBFKCBJTlQ2NCwgIGludDY0KTsKKyAgICAgIEhBTkRMRV9UWVBFKFVJTlQzMiwgdWludDMyKTsKKyAgICAgIEhBTkRMRV9UWVBFKFVJTlQ2NCwgdWludDY0KTsKKyAgICAgIEhBTkRMRV9UWVBFKERPVUJMRSwgZG91YmxlKTsKKyAgICAgIEhBTkRMRV9UWVBFKCBGTE9BVCwgIGZsb2F0KTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgQk9PTCwgICBib29sKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgRU5VTSwgICAgaW50KTsKKyN1bmRlZiBIQU5ETEVfVFlQRQorCisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9TVFJJTkc6CisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgICBpZiAoSXNNYXBGaWVsZEluQXBpKGZpZWxkKSkgeworICAgICAgICAgIHJldHVybiBHZXRSYXc8TWFwRmllbGRCYXNlPihtZXNzYWdlLCBmaWVsZCkuR2V0UmVwZWF0ZWRGaWVsZCgpLnNpemUoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICByZXR1cm4gR2V0UmF3PFJlcGVhdGVkUHRyRmllbGRCYXNlPihtZXNzYWdlLCBmaWVsZCkuc2l6ZSgpOworICAgICAgICB9CisgICAgfQorCisgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkNhbid0IGdldCBoZXJlLiI7CisgICAgcmV0dXJuIDA7CisgIH0KK30KKwordm9pZCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6Q2xlYXJGaWVsZCgKKyAgICBNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7CisgIFVTQUdFX0NIRUNLX01FU1NBR0VfVFlQRShDbGVhckZpZWxkKTsKKworICBpZiAoZmllbGQtPmlzX2V4dGVuc2lvbigpKSB7CisgICAgTXV0YWJsZUV4dGVuc2lvblNldChtZXNzYWdlKS0+Q2xlYXJFeHRlbnNpb24oZmllbGQtPm51bWJlcigpKTsKKyAgfSBlbHNlIGlmICghZmllbGQtPmlzX3JlcGVhdGVkKCkpIHsKKyAgICBpZiAoZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSkgeworICAgICAgQ2xlYXJPbmVvZkZpZWxkKG1lc3NhZ2UsIGZpZWxkKTsKKyAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBpZiAoSGFzQml0KCptZXNzYWdlLCBmaWVsZCkpIHsKKyAgICAgIENsZWFyQml0KG1lc3NhZ2UsIGZpZWxkKTsKKworICAgICAgLy8gV2UgbmVlZCB0byBzZXQgdGhlIGZpZWxkIGJhY2sgdG8gaXRzIGRlZmF1bHQgdmFsdWUuCisgICAgICBzd2l0Y2ggKGZpZWxkLT5jcHBfdHlwZSgpKSB7CisjZGVmaW5lIENMRUFSX1RZUEUoQ1BQVFlQRSwgVFlQRSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfIyNDUFBUWVBFOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICpNdXRhYmxlUmF3PFRZUEU+KG1lc3NhZ2UsIGZpZWxkKSA9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICBmaWVsZC0+ZGVmYXVsdF92YWx1ZV8jI1RZUEUoKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICBicmVhazsKKworICAgICAgICBDTEVBUl9UWVBFKElOVDMyICwgaW50MzIgKTsKKyAgICAgICAgQ0xFQVJfVFlQRShJTlQ2NCAsIGludDY0ICk7CisgICAgICAgIENMRUFSX1RZUEUoVUlOVDMyLCB1aW50MzIpOworICAgICAgICBDTEVBUl9UWVBFKFVJTlQ2NCwgdWludDY0KTsKKyAgICAgICAgQ0xFQVJfVFlQRShGTE9BVCAsIGZsb2F0ICk7CisgICAgICAgIENMRUFSX1RZUEUoRE9VQkxFLCBkb3VibGUpOworICAgICAgICBDTEVBUl9UWVBFKEJPT0wgICwgYm9vbCAgKTsKKyN1bmRlZiBDTEVBUl9UWVBFCisKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRU5VTToKKyAgICAgICAgICAqTXV0YWJsZVJhdzxpbnQ+KG1lc3NhZ2UsIGZpZWxkKSA9CisgICAgICAgICAgICBmaWVsZC0+ZGVmYXVsdF92YWx1ZV9lbnVtKCktPm51bWJlcigpOworICAgICAgICAgIGJyZWFrOworCisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORzogeworICAgICAgICAgIHN3aXRjaCAoZmllbGQtPm9wdGlvbnMoKS5jdHlwZSgpKSB7CisgICAgICAgICAgICBkZWZhdWx0OiAgLy8gVE9ETyhrZW50b24pOiAgU3VwcG9ydCBvdGhlciBzdHJpbmcgcmVwcy4KKyAgICAgICAgICAgIGNhc2UgRmllbGRPcHRpb25zOjpTVFJJTkc6IHsKKyAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nKiBkZWZhdWx0X3B0ciA9CisgICAgICAgICAgICAgICAgICAmRGVmYXVsdFJhdzxBcmVuYVN0cmluZ1B0cj4oZmllbGQpLkdldChOVUxMKTsKKyAgICAgICAgICAgICAgTXV0YWJsZVJhdzxBcmVuYVN0cmluZ1B0cj4obWVzc2FnZSwgZmllbGQpLT5EZXN0cm95KGRlZmF1bHRfcHRyLAorICAgICAgICAgICAgICAgICAgR2V0QXJlbmEobWVzc2FnZSkpOworICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKworICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgICAgIGlmIChoYXNfYml0c19vZmZzZXRfID09IC0xKSB7CisgICAgICAgICAgICAvLyBQcm90bzMgZG9lcyBub3QgaGF2ZSBoYXMtYml0cyBhbmQgd2UgbmVlZCB0byBzZXQgYSBtZXNzYWdlIGZpZWxkCisgICAgICAgICAgICAvLyB0byBOVUxMIGluIG9yZGVyIHRvIGluZGljYXRlIGl0cyB1bi1wcmVzZW5jZS4KKyAgICAgICAgICAgIGlmIChHZXRBcmVuYShtZXNzYWdlKSA9PSBOVUxMKSB7CisgICAgICAgICAgICAgIGRlbGV0ZSAqTXV0YWJsZVJhdzxNZXNzYWdlKj4obWVzc2FnZSwgZmllbGQpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgKk11dGFibGVSYXc8TWVzc2FnZSo+KG1lc3NhZ2UsIGZpZWxkKSA9IE5VTEw7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICgqTXV0YWJsZVJhdzxNZXNzYWdlKj4obWVzc2FnZSwgZmllbGQpKS0+Q2xlYXIoKTsKKyAgICAgICAgICB9CisgICAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9IGVsc2UgeworICAgIHN3aXRjaCAoZmllbGQtPmNwcF90eXBlKCkpIHsKKyNkZWZpbmUgSEFORExFX1RZUEUoVVBQRVJDQVNFLCBMT1dFUkNBU0UpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFXyMjVVBQRVJDQVNFIDogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgTXV0YWJsZVJhdzxSZXBlYXRlZEZpZWxkPExPV0VSQ0FTRT4gPihtZXNzYWdlLCBmaWVsZCktPkNsZWFyKCk7ICAgICAgIFwKKyAgICAgICAgYnJlYWsKKworICAgICAgSEFORExFX1RZUEUoIElOVDMyLCAgaW50MzIpOworICAgICAgSEFORExFX1RZUEUoIElOVDY0LCAgaW50NjQpOworICAgICAgSEFORExFX1RZUEUoVUlOVDMyLCB1aW50MzIpOworICAgICAgSEFORExFX1RZUEUoVUlOVDY0LCB1aW50NjQpOworICAgICAgSEFORExFX1RZUEUoRE9VQkxFLCBkb3VibGUpOworICAgICAgSEFORExFX1RZUEUoIEZMT0FULCAgZmxvYXQpOworICAgICAgSEFORExFX1RZUEUoICBCT09MLCAgIGJvb2wpOworICAgICAgSEFORExFX1RZUEUoICBFTlVNLCAgICBpbnQpOworI3VuZGVmIEhBTkRMRV9UWVBFCisKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORzogeworICAgICAgICBzd2l0Y2ggKGZpZWxkLT5vcHRpb25zKCkuY3R5cGUoKSkgeworICAgICAgICAgIGRlZmF1bHQ6ICAvLyBUT0RPKGtlbnRvbik6ICBTdXBwb3J0IG90aGVyIHN0cmluZyByZXBzLgorICAgICAgICAgIGNhc2UgRmllbGRPcHRpb25zOjpTVFJJTkc6CisgICAgICAgICAgICBNdXRhYmxlUmF3PFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPiA+KG1lc3NhZ2UsIGZpZWxkKS0+Q2xlYXIoKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOiB7CisgICAgICAgIGlmIChJc01hcEZpZWxkSW5BcGkoZmllbGQpKSB7CisgICAgICAgICAgTXV0YWJsZVJhdzxNYXBGaWVsZEJhc2U+KG1lc3NhZ2UsIGZpZWxkKQorICAgICAgICAgICAgICAtPk11dGFibGVSZXBlYXRlZEZpZWxkKCkKKyAgICAgICAgICAgICAgLT5DbGVhcjxHZW5lcmljVHlwZUhhbmRsZXI8TWVzc2FnZT4gPigpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIC8vIFdlIGRvbid0IGtub3cgd2hpY2ggc3ViY2xhc3Mgb2YgUmVwZWF0ZWRQdHJGaWVsZEJhc2UgdGhlIHR5cGUgaXMsCisgICAgICAgICAgLy8gc28gd2UgdXNlIFJlcGVhdGVkUHRyRmllbGRCYXNlIGRpcmVjdGx5LgorICAgICAgICAgIE11dGFibGVSYXc8UmVwZWF0ZWRQdHJGaWVsZEJhc2U+KG1lc3NhZ2UsIGZpZWxkKQorICAgICAgICAgICAgICAtPkNsZWFyPEdlbmVyaWNUeXBlSGFuZGxlcjxNZXNzYWdlPiA+KCk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9Cit9CisKK3ZvaWQgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OlJlbW92ZUxhc3QoCisgICAgTWVzc2FnZSogbWVzc2FnZSwKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7CisgIFVTQUdFX0NIRUNLX01FU1NBR0VfVFlQRShSZW1vdmVMYXN0KTsKKyAgVVNBR0VfQ0hFQ0tfUkVQRUFURUQoUmVtb3ZlTGFzdCk7CisKKyAgaWYgKGZpZWxkLT5pc19leHRlbnNpb24oKSkgeworICAgIE11dGFibGVFeHRlbnNpb25TZXQobWVzc2FnZSktPlJlbW92ZUxhc3QoZmllbGQtPm51bWJlcigpKTsKKyAgfSBlbHNlIHsKKyAgICBzd2l0Y2ggKGZpZWxkLT5jcHBfdHlwZSgpKSB7CisjZGVmaW5lIEhBTkRMRV9UWVBFKFVQUEVSQ0FTRSwgTE9XRVJDQVNFKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV8jI1VQUEVSQ0FTRSA6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIE11dGFibGVSYXc8UmVwZWF0ZWRGaWVsZDxMT1dFUkNBU0U+ID4obWVzc2FnZSwgZmllbGQpLT5SZW1vdmVMYXN0KCk7ICBcCisgICAgICAgIGJyZWFrCisKKyAgICAgIEhBTkRMRV9UWVBFKCBJTlQzMiwgIGludDMyKTsKKyAgICAgIEhBTkRMRV9UWVBFKCBJTlQ2NCwgIGludDY0KTsKKyAgICAgIEhBTkRMRV9UWVBFKFVJTlQzMiwgdWludDMyKTsKKyAgICAgIEhBTkRMRV9UWVBFKFVJTlQ2NCwgdWludDY0KTsKKyAgICAgIEhBTkRMRV9UWVBFKERPVUJMRSwgZG91YmxlKTsKKyAgICAgIEhBTkRMRV9UWVBFKCBGTE9BVCwgIGZsb2F0KTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgQk9PTCwgICBib29sKTsKKyAgICAgIEhBTkRMRV9UWVBFKCAgRU5VTSwgICAgaW50KTsKKyN1bmRlZiBIQU5ETEVfVFlQRQorCisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9TVFJJTkc6CisgICAgICAgIHN3aXRjaCAoZmllbGQtPm9wdGlvbnMoKS5jdHlwZSgpKSB7CisgICAgICAgICAgZGVmYXVsdDogIC8vIFRPRE8oa2VudG9uKTogIFN1cHBvcnQgb3RoZXIgc3RyaW5nIHJlcHMuCisgICAgICAgICAgY2FzZSBGaWVsZE9wdGlvbnM6OlNUUklORzoKKyAgICAgICAgICAgIE11dGFibGVSYXc8UmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+ID4obWVzc2FnZSwgZmllbGQpLT5SZW1vdmVMYXN0KCk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRToKKyAgICAgICAgaWYgKElzTWFwRmllbGRJbkFwaShmaWVsZCkpIHsKKyAgICAgICAgICBNdXRhYmxlUmF3PE1hcEZpZWxkQmFzZT4obWVzc2FnZSwgZmllbGQpCisgICAgICAgICAgICAgIC0+TXV0YWJsZVJlcGVhdGVkRmllbGQoKQorICAgICAgICAgICAgICAtPlJlbW92ZUxhc3Q8R2VuZXJpY1R5cGVIYW5kbGVyPE1lc3NhZ2U+ID4oKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBNdXRhYmxlUmF3PFJlcGVhdGVkUHRyRmllbGRCYXNlPihtZXNzYWdlLCBmaWVsZCkKKyAgICAgICAgICAgIC0+UmVtb3ZlTGFzdDxHZW5lcmljVHlwZUhhbmRsZXI8TWVzc2FnZT4gPigpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgIH0KKyAgfQorfQorCitNZXNzYWdlKiBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6UmVsZWFzZUxhc3QoCisgICAgTWVzc2FnZSogbWVzc2FnZSwKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7CisgIFVTQUdFX0NIRUNLX0FMTChSZWxlYXNlTGFzdCwgUkVQRUFURUQsIE1FU1NBR0UpOworCisgIGlmIChmaWVsZC0+aXNfZXh0ZW5zaW9uKCkpIHsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8TWVzc2FnZSo+KAorICAgICAgICBNdXRhYmxlRXh0ZW5zaW9uU2V0KG1lc3NhZ2UpLT5SZWxlYXNlTGFzdChmaWVsZC0+bnVtYmVyKCkpKTsKKyAgfSBlbHNlIHsKKyAgICBpZiAoSXNNYXBGaWVsZEluQXBpKGZpZWxkKSkgeworICAgICAgcmV0dXJuIE11dGFibGVSYXc8TWFwRmllbGRCYXNlPihtZXNzYWdlLCBmaWVsZCkKKyAgICAgICAgICAtPk11dGFibGVSZXBlYXRlZEZpZWxkKCkKKyAgICAgICAgICAtPlJlbGVhc2VMYXN0PEdlbmVyaWNUeXBlSGFuZGxlcjxNZXNzYWdlPiA+KCk7CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiBNdXRhYmxlUmF3PFJlcGVhdGVkUHRyRmllbGRCYXNlPihtZXNzYWdlLCBmaWVsZCkKKyAgICAgICAgLT5SZWxlYXNlTGFzdDxHZW5lcmljVHlwZUhhbmRsZXI8TWVzc2FnZT4gPigpOworICAgIH0KKyAgfQorfQorCit2b2lkIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpTd2FwRWxlbWVudHMoCisgICAgTWVzc2FnZSogbWVzc2FnZSwKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgIGludCBpbmRleDEsCisgICAgaW50IGluZGV4MikgY29uc3QgeworICBVU0FHRV9DSEVDS19NRVNTQUdFX1RZUEUoU3dhcCk7CisgIFVTQUdFX0NIRUNLX1JFUEVBVEVEKFN3YXApOworCisgIGlmIChmaWVsZC0+aXNfZXh0ZW5zaW9uKCkpIHsKKyAgICBNdXRhYmxlRXh0ZW5zaW9uU2V0KG1lc3NhZ2UpLT5Td2FwRWxlbWVudHMoZmllbGQtPm51bWJlcigpLCBpbmRleDEsIGluZGV4Mik7CisgIH0gZWxzZSB7CisgICAgc3dpdGNoIChmaWVsZC0+Y3BwX3R5cGUoKSkgeworI2RlZmluZSBIQU5ETEVfVFlQRShVUFBFUkNBU0UsIExPV0VSQ0FTRSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfIyNVUFBFUkNBU0UgOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBNdXRhYmxlUmF3PFJlcGVhdGVkRmllbGQ8TE9XRVJDQVNFPiA+KG1lc3NhZ2UsIGZpZWxkKSAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgLT5Td2FwRWxlbWVudHMoaW5kZXgxLCBpbmRleDIpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBicmVhaworCisgICAgICBIQU5ETEVfVFlQRSggSU5UMzIsICBpbnQzMik7CisgICAgICBIQU5ETEVfVFlQRSggSU5UNjQsICBpbnQ2NCk7CisgICAgICBIQU5ETEVfVFlQRShVSU5UMzIsIHVpbnQzMik7CisgICAgICBIQU5ETEVfVFlQRShVSU5UNjQsIHVpbnQ2NCk7CisgICAgICBIQU5ETEVfVFlQRShET1VCTEUsIGRvdWJsZSk7CisgICAgICBIQU5ETEVfVFlQRSggRkxPQVQsICBmbG9hdCk7CisgICAgICBIQU5ETEVfVFlQRSggIEJPT0wsICAgYm9vbCk7CisgICAgICBIQU5ETEVfVFlQRSggIEVOVU0sICAgIGludCk7CisjdW5kZWYgSEFORExFX1RZUEUKKworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HOgorICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRToKKyAgICAgICAgaWYgKElzTWFwRmllbGRJbkFwaShmaWVsZCkpIHsKKyAgICAgICAgICBNdXRhYmxlUmF3PE1hcEZpZWxkQmFzZT4obWVzc2FnZSwgZmllbGQpCisgICAgICAgICAgICAgIC0+TXV0YWJsZVJlcGVhdGVkRmllbGQoKQorICAgICAgICAgICAgICAtPlN3YXBFbGVtZW50cyhpbmRleDEsIGluZGV4Mik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgTXV0YWJsZVJhdzxSZXBlYXRlZFB0ckZpZWxkQmFzZT4obWVzc2FnZSwgZmllbGQpCisgICAgICAgICAgICAtPlN3YXBFbGVtZW50cyhpbmRleDEsIGluZGV4Mik7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgfQorICB9Cit9CisKK25hbWVzcGFjZSB7CisvLyBDb21wYXJpc29uIGZ1bmN0b3IgZm9yIHNvcnRpbmcgRmllbGREZXNjcmlwdG9ycyBieSBmaWVsZCBudW1iZXIuCitzdHJ1Y3QgRmllbGROdW1iZXJTb3J0ZXIgeworICBib29sIG9wZXJhdG9yKCkoY29uc3QgRmllbGREZXNjcmlwdG9yKiBsZWZ0LAorICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiByaWdodCkgY29uc3QgeworICAgIHJldHVybiBsZWZ0LT5udW1iZXIoKSA8IHJpZ2h0LT5udW1iZXIoKTsKKyAgfQorfTsKK30gIC8vIG5hbWVzcGFjZQorCit2b2lkIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpMaXN0RmllbGRzKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+KiBvdXRwdXQpIGNvbnN0IHsKKyAgb3V0cHV0LT5jbGVhcigpOworCisgIC8vIE9wdGltaXphdGlvbjogIFRoZSBkZWZhdWx0IGluc3RhbmNlIG5ldmVyIGhhcyBhbnkgZmllbGRzIHNldC4KKyAgaWYgKCZtZXNzYWdlID09IGRlZmF1bHRfaW5zdGFuY2VfKSByZXR1cm47CisKKyAgb3V0cHV0LT5yZXNlcnZlKGRlc2NyaXB0b3JfLT5maWVsZF9jb3VudCgpKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yXy0+ZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3JfLT5maWVsZChpKTsKKyAgICBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkpIHsKKyAgICAgIGlmIChGaWVsZFNpemUobWVzc2FnZSwgZmllbGQpID4gMCkgeworICAgICAgICBvdXRwdXQtPnB1c2hfYmFjayhmaWVsZCk7CisgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgIGlmIChmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpKSB7CisgICAgICAgIGlmIChIYXNPbmVvZkZpZWxkKG1lc3NhZ2UsIGZpZWxkKSkgeworICAgICAgICAgIG91dHB1dC0+cHVzaF9iYWNrKGZpZWxkKTsKKyAgICAgICAgfQorICAgICAgfSBlbHNlIGlmIChIYXNCaXQobWVzc2FnZSwgZmllbGQpKSB7CisgICAgICAgIG91dHB1dC0+cHVzaF9iYWNrKGZpZWxkKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICBpZiAoZXh0ZW5zaW9uc19vZmZzZXRfICE9IC0xKSB7CisgICAgR2V0RXh0ZW5zaW9uU2V0KG1lc3NhZ2UpLkFwcGVuZFRvTGlzdChkZXNjcmlwdG9yXywgZGVzY3JpcHRvcl9wb29sXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dCk7CisgIH0KKworICAvLyBMaXN0RmllbGRzKCkgbXVzdCBzb3J0IG91dHB1dCBieSBmaWVsZCBudW1iZXIuCisgIHN0ZDo6c29ydChvdXRwdXQtPmJlZ2luKCksIG91dHB1dC0+ZW5kKCksIEZpZWxkTnVtYmVyU29ydGVyKCkpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyN1bmRlZiBERUZJTkVfUFJJTUlUSVZFX0FDQ0VTU09SUworI2RlZmluZSBERUZJTkVfUFJJTUlUSVZFX0FDQ0VTU09SUyhUWVBFTkFNRSwgVFlQRSwgUEFTU1RZUEUsIENQUFRZUEUpICAgICAgICBcCisgIFBBU1NUWVBFIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpHZXQjI1RZUEVOQU1FKCAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0IHsgICAgICAgICAgXAorICAgIFVTQUdFX0NIRUNLX0FMTChHZXQjI1RZUEVOQU1FLCBTSU5HVUxBUiwgQ1BQVFlQRSk7ICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgaWYgKGZpZWxkLT5pc19leHRlbnNpb24oKSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIHJldHVybiBHZXRFeHRlbnNpb25TZXQobWVzc2FnZSkuR2V0IyNUWVBFTkFNRSggICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBmaWVsZC0+bnVtYmVyKCksIGZpZWxkLT5kZWZhdWx0X3ZhbHVlXyMjUEFTU1RZUEUoKSk7ICAgICAgICAgICAgICAgICBcCisgICAgfSBlbHNlIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIHJldHVybiBHZXRGaWVsZDxUWVBFPihtZXNzYWdlLCBmaWVsZCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB2b2lkIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpTZXQjI1RZUEVOQU1FKCAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICBNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIFBBU1NUWVBFIHZhbHVlKSBjb25zdCB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIFVTQUdFX0NIRUNLX0FMTChTZXQjI1RZUEVOQU1FLCBTSU5HVUxBUiwgQ1BQVFlQRSk7ICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgaWYgKGZpZWxkLT5pc19leHRlbnNpb24oKSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIHJldHVybiBNdXRhYmxlRXh0ZW5zaW9uU2V0KG1lc3NhZ2UpLT5TZXQjI1RZUEVOQU1FKCAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBmaWVsZC0+bnVtYmVyKCksIGZpZWxkLT50eXBlKCksIHZhbHVlLCBmaWVsZCk7ICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgfSBlbHNlIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIFNldEZpZWxkPFRZUEU+KG1lc3NhZ2UsIGZpZWxkLCB2YWx1ZSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBQQVNTVFlQRSBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6R2V0UmVwZWF0ZWQjI1RZUEVOQU1FKCAgICAgICAgICAgICAgICBcCisgICAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGludCBpbmRleCkgY29uc3QgeyAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIFVTQUdFX0NIRUNLX0FMTChHZXRSZXBlYXRlZCMjVFlQRU5BTUUsIFJFUEVBVEVELCBDUFBUWVBFKTsgICAgICAgICAgICAgICBcCisgICAgaWYgKGZpZWxkLT5pc19leHRlbnNpb24oKSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIHJldHVybiBHZXRFeHRlbnNpb25TZXQobWVzc2FnZSkuR2V0UmVwZWF0ZWQjI1RZUEVOQU1FKCAgICAgICAgICAgICAgICAgXAorICAgICAgICBmaWVsZC0+bnVtYmVyKCksIGluZGV4KTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgfSBlbHNlIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIHJldHVybiBHZXRSZXBlYXRlZEZpZWxkPFRZUEU+KG1lc3NhZ2UsIGZpZWxkLCBpbmRleCk7ICAgICAgICAgICAgICAgICAgXAorICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB2b2lkIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpTZXRSZXBlYXRlZCMjVFlQRU5BTUUoICAgICAgICAgICAgICAgICAgICBcCisgICAgICBNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIGludCBpbmRleCwgUEFTU1RZUEUgdmFsdWUpIGNvbnN0IHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIFVTQUdFX0NIRUNLX0FMTChTZXRSZXBlYXRlZCMjVFlQRU5BTUUsIFJFUEVBVEVELCBDUFBUWVBFKTsgICAgICAgICAgICAgICBcCisgICAgaWYgKGZpZWxkLT5pc19leHRlbnNpb24oKSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIE11dGFibGVFeHRlbnNpb25TZXQobWVzc2FnZSktPlNldFJlcGVhdGVkIyNUWVBFTkFNRSggICAgICAgICAgICAgICAgICAgXAorICAgICAgICBmaWVsZC0+bnVtYmVyKCksIGluZGV4LCB2YWx1ZSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgfSBlbHNlIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIFNldFJlcGVhdGVkRmllbGQ8VFlQRT4obWVzc2FnZSwgZmllbGQsIGluZGV4LCB2YWx1ZSk7ICAgICAgICAgICAgICAgICAgXAorICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB2b2lkIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpBZGQjI1RZUEVOQU1FKCAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICBNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIFBBU1NUWVBFIHZhbHVlKSBjb25zdCB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIFVTQUdFX0NIRUNLX0FMTChBZGQjI1RZUEVOQU1FLCBSRVBFQVRFRCwgQ1BQVFlQRSk7ICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgaWYgKGZpZWxkLT5pc19leHRlbnNpb24oKSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIE11dGFibGVFeHRlbnNpb25TZXQobWVzc2FnZSktPkFkZCMjVFlQRU5BTUUoICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBmaWVsZC0+bnVtYmVyKCksIGZpZWxkLT50eXBlKCksIGZpZWxkLT5vcHRpb25zKCkucGFja2VkKCksIHZhbHVlLCAgICBcCisgICAgICAgIGZpZWxkKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICB9IGVsc2UgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgQWRkRmllbGQ8VFlQRT4obWVzc2FnZSwgZmllbGQsIHZhbHVlKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgfQorCitERUZJTkVfUFJJTUlUSVZFX0FDQ0VTU09SUyhJbnQzMiAsIGludDMyICwgaW50MzIgLCBJTlQzMiApCitERUZJTkVfUFJJTUlUSVZFX0FDQ0VTU09SUyhJbnQ2NCAsIGludDY0ICwgaW50NjQgLCBJTlQ2NCApCitERUZJTkVfUFJJTUlUSVZFX0FDQ0VTU09SUyhVSW50MzIsIHVpbnQzMiwgdWludDMyLCBVSU5UMzIpCitERUZJTkVfUFJJTUlUSVZFX0FDQ0VTU09SUyhVSW50NjQsIHVpbnQ2NCwgdWludDY0LCBVSU5UNjQpCitERUZJTkVfUFJJTUlUSVZFX0FDQ0VTU09SUyhGbG9hdCAsIGZsb2F0ICwgZmxvYXQgLCBGTE9BVCApCitERUZJTkVfUFJJTUlUSVZFX0FDQ0VTU09SUyhEb3VibGUsIGRvdWJsZSwgZG91YmxlLCBET1VCTEUpCitERUZJTkVfUFJJTUlUSVZFX0FDQ0VTU09SUyhCb29sICAsIGJvb2wgICwgYm9vbCAgLCBCT09MICApCisjdW5kZWYgREVGSU5FX1BSSU1JVElWRV9BQ0NFU1NPUlMKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitzdHJpbmcgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OkdldFN0cmluZygKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7CisgIFVTQUdFX0NIRUNLX0FMTChHZXRTdHJpbmcsIFNJTkdVTEFSLCBTVFJJTkcpOworICBpZiAoZmllbGQtPmlzX2V4dGVuc2lvbigpKSB7CisgICAgcmV0dXJuIEdldEV4dGVuc2lvblNldChtZXNzYWdlKS5HZXRTdHJpbmcoZmllbGQtPm51bWJlcigpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkLT5kZWZhdWx0X3ZhbHVlX3N0cmluZygpKTsKKyAgfSBlbHNlIHsKKyAgICBzd2l0Y2ggKGZpZWxkLT5vcHRpb25zKCkuY3R5cGUoKSkgeworICAgICAgZGVmYXVsdDogIC8vIFRPRE8oa2VudG9uKTogIFN1cHBvcnQgb3RoZXIgc3RyaW5nIHJlcHMuCisgICAgICBjYXNlIEZpZWxkT3B0aW9uczo6U1RSSU5HOiB7CisgICAgICAgIGNvbnN0IHN0cmluZyogZGVmYXVsdF9wdHIgPQorICAgICAgICAgICAgJkRlZmF1bHRSYXc8QXJlbmFTdHJpbmdQdHI+KGZpZWxkKS5HZXQoTlVMTCk7CisgICAgICAgIHJldHVybiBHZXRGaWVsZDxBcmVuYVN0cmluZ1B0cj4obWVzc2FnZSwgZmllbGQpLkdldChkZWZhdWx0X3B0cik7CisgICAgICB9CisgICAgfQorCisgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkNhbid0IGdldCBoZXJlLiI7CisgICAgcmV0dXJuIEdldEVtcHR5U3RyaW5nKCk7ICAvLyBNYWtlIGNvbXBpbGVyIGhhcHB5LgorICB9Cit9CisKK2NvbnN0IHN0cmluZyYgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OkdldFN0cmluZ1JlZmVyZW5jZSgKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIHN0cmluZyogc2NyYXRjaCkgY29uc3QgeworICBVU0FHRV9DSEVDS19BTEwoR2V0U3RyaW5nUmVmZXJlbmNlLCBTSU5HVUxBUiwgU1RSSU5HKTsKKyAgaWYgKGZpZWxkLT5pc19leHRlbnNpb24oKSkgeworICAgIHJldHVybiBHZXRFeHRlbnNpb25TZXQobWVzc2FnZSkuR2V0U3RyaW5nKGZpZWxkLT5udW1iZXIoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZC0+ZGVmYXVsdF92YWx1ZV9zdHJpbmcoKSk7CisgIH0gZWxzZSB7CisgICAgc3dpdGNoIChmaWVsZC0+b3B0aW9ucygpLmN0eXBlKCkpIHsKKyAgICAgIGRlZmF1bHQ6ICAvLyBUT0RPKGtlbnRvbik6ICBTdXBwb3J0IG90aGVyIHN0cmluZyByZXBzLgorICAgICAgY2FzZSBGaWVsZE9wdGlvbnM6OlNUUklORzogeworICAgICAgICBjb25zdCBzdHJpbmcqIGRlZmF1bHRfcHRyID0KKyAgICAgICAgICAgICZEZWZhdWx0UmF3PEFyZW5hU3RyaW5nUHRyPihmaWVsZCkuR2V0KE5VTEwpOworICAgICAgICByZXR1cm4gR2V0RmllbGQ8QXJlbmFTdHJpbmdQdHI+KG1lc3NhZ2UsIGZpZWxkKS5HZXQoZGVmYXVsdF9wdHIpOworICAgICAgfQorICAgIH0KKworICAgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJDYW4ndCBnZXQgaGVyZS4iOworICAgIHJldHVybiBHZXRFbXB0eVN0cmluZygpOyAgLy8gTWFrZSBjb21waWxlciBoYXBweS4KKyAgfQorfQorCisKK3ZvaWQgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OlNldFN0cmluZygKKyAgICBNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgIGNvbnN0IHN0cmluZyYgdmFsdWUpIGNvbnN0IHsKKyAgVVNBR0VfQ0hFQ0tfQUxMKFNldFN0cmluZywgU0lOR1VMQVIsIFNUUklORyk7CisgIGlmIChmaWVsZC0+aXNfZXh0ZW5zaW9uKCkpIHsKKyAgICByZXR1cm4gTXV0YWJsZUV4dGVuc2lvblNldChtZXNzYWdlKS0+U2V0U3RyaW5nKGZpZWxkLT5udW1iZXIoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkLT50eXBlKCksIHZhbHVlLCBmaWVsZCk7CisgIH0gZWxzZSB7CisgICAgc3dpdGNoIChmaWVsZC0+b3B0aW9ucygpLmN0eXBlKCkpIHsKKyAgICAgIGRlZmF1bHQ6ICAvLyBUT0RPKGtlbnRvbik6ICBTdXBwb3J0IG90aGVyIHN0cmluZyByZXBzLgorICAgICAgY2FzZSBGaWVsZE9wdGlvbnM6OlNUUklORzogeworICAgICAgICBjb25zdCBzdHJpbmcqIGRlZmF1bHRfcHRyID0KKyAgICAgICAgICAgICZEZWZhdWx0UmF3PEFyZW5hU3RyaW5nUHRyPihmaWVsZCkuR2V0KE5VTEwpOworICAgICAgICBpZiAoZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSAmJiAhSGFzT25lb2ZGaWVsZCgqbWVzc2FnZSwgZmllbGQpKSB7CisgICAgICAgICAgQ2xlYXJPbmVvZihtZXNzYWdlLCBmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpKTsKKyAgICAgICAgICBNdXRhYmxlRmllbGQ8QXJlbmFTdHJpbmdQdHI+KG1lc3NhZ2UsIGZpZWxkKS0+VW5zYWZlU2V0RGVmYXVsdCgKKyAgICAgICAgICAgICAgZGVmYXVsdF9wdHIpOworICAgICAgICB9CisgICAgICAgIE11dGFibGVGaWVsZDxBcmVuYVN0cmluZ1B0cj4obWVzc2FnZSwgZmllbGQpLT5TZXQoZGVmYXVsdF9wdHIsCisgICAgICAgICAgICB2YWx1ZSwgR2V0QXJlbmEobWVzc2FnZSkpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KK30KKworCitzdHJpbmcgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OkdldFJlcGVhdGVkU3RyaW5nKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGludCBpbmRleCkgY29uc3QgeworICBVU0FHRV9DSEVDS19BTEwoR2V0UmVwZWF0ZWRTdHJpbmcsIFJFUEVBVEVELCBTVFJJTkcpOworICBpZiAoZmllbGQtPmlzX2V4dGVuc2lvbigpKSB7CisgICAgcmV0dXJuIEdldEV4dGVuc2lvblNldChtZXNzYWdlKS5HZXRSZXBlYXRlZFN0cmluZyhmaWVsZC0+bnVtYmVyKCksIGluZGV4KTsKKyAgfSBlbHNlIHsKKyAgICBzd2l0Y2ggKGZpZWxkLT5vcHRpb25zKCkuY3R5cGUoKSkgeworICAgICAgZGVmYXVsdDogIC8vIFRPRE8oa2VudG9uKTogIFN1cHBvcnQgb3RoZXIgc3RyaW5nIHJlcHMuCisgICAgICBjYXNlIEZpZWxkT3B0aW9uczo6U1RSSU5HOgorICAgICAgICByZXR1cm4gR2V0UmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+KG1lc3NhZ2UsIGZpZWxkLCBpbmRleCk7CisgICAgfQorCisgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkNhbid0IGdldCBoZXJlLiI7CisgICAgcmV0dXJuIEdldEVtcHR5U3RyaW5nKCk7ICAvLyBNYWtlIGNvbXBpbGVyIGhhcHB5LgorICB9Cit9CisKK2NvbnN0IHN0cmluZyYgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OkdldFJlcGVhdGVkU3RyaW5nUmVmZXJlbmNlKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgaW50IGluZGV4LCBzdHJpbmcqIHNjcmF0Y2gpIGNvbnN0IHsKKyAgVVNBR0VfQ0hFQ0tfQUxMKEdldFJlcGVhdGVkU3RyaW5nUmVmZXJlbmNlLCBSRVBFQVRFRCwgU1RSSU5HKTsKKyAgaWYgKGZpZWxkLT5pc19leHRlbnNpb24oKSkgeworICAgIHJldHVybiBHZXRFeHRlbnNpb25TZXQobWVzc2FnZSkuR2V0UmVwZWF0ZWRTdHJpbmcoZmllbGQtPm51bWJlcigpLCBpbmRleCk7CisgIH0gZWxzZSB7CisgICAgc3dpdGNoIChmaWVsZC0+b3B0aW9ucygpLmN0eXBlKCkpIHsKKyAgICAgIGRlZmF1bHQ6ICAvLyBUT0RPKGtlbnRvbik6ICBTdXBwb3J0IG90aGVyIHN0cmluZyByZXBzLgorICAgICAgY2FzZSBGaWVsZE9wdGlvbnM6OlNUUklORzoKKyAgICAgICAgcmV0dXJuIEdldFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPihtZXNzYWdlLCBmaWVsZCwgaW5kZXgpOworICAgIH0KKworICAgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJDYW4ndCBnZXQgaGVyZS4iOworICAgIHJldHVybiBHZXRFbXB0eVN0cmluZygpOyAgLy8gTWFrZSBjb21waWxlciBoYXBweS4KKyAgfQorfQorCisKK3ZvaWQgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OlNldFJlcGVhdGVkU3RyaW5nKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgaW50IGluZGV4LCBjb25zdCBzdHJpbmcmIHZhbHVlKSBjb25zdCB7CisgIFVTQUdFX0NIRUNLX0FMTChTZXRSZXBlYXRlZFN0cmluZywgUkVQRUFURUQsIFNUUklORyk7CisgIGlmIChmaWVsZC0+aXNfZXh0ZW5zaW9uKCkpIHsKKyAgICBNdXRhYmxlRXh0ZW5zaW9uU2V0KG1lc3NhZ2UpLT5TZXRSZXBlYXRlZFN0cmluZygKKyAgICAgIGZpZWxkLT5udW1iZXIoKSwgaW5kZXgsIHZhbHVlKTsKKyAgfSBlbHNlIHsKKyAgICBzd2l0Y2ggKGZpZWxkLT5vcHRpb25zKCkuY3R5cGUoKSkgeworICAgICAgZGVmYXVsdDogIC8vIFRPRE8oa2VudG9uKTogIFN1cHBvcnQgb3RoZXIgc3RyaW5nIHJlcHMuCisgICAgICBjYXNlIEZpZWxkT3B0aW9uczo6U1RSSU5HOgorICAgICAgICAqTXV0YWJsZVJlcGVhdGVkRmllbGQ8c3RyaW5nPihtZXNzYWdlLCBmaWVsZCwgaW5kZXgpID0gdmFsdWU7CisgICAgICAgIGJyZWFrOworICAgIH0KKyAgfQorfQorCisKK3ZvaWQgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OkFkZFN0cmluZygKKyAgICBNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgIGNvbnN0IHN0cmluZyYgdmFsdWUpIGNvbnN0IHsKKyAgVVNBR0VfQ0hFQ0tfQUxMKEFkZFN0cmluZywgUkVQRUFURUQsIFNUUklORyk7CisgIGlmIChmaWVsZC0+aXNfZXh0ZW5zaW9uKCkpIHsKKyAgICBNdXRhYmxlRXh0ZW5zaW9uU2V0KG1lc3NhZ2UpLT5BZGRTdHJpbmcoZmllbGQtPm51bWJlcigpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZC0+dHlwZSgpLCB2YWx1ZSwgZmllbGQpOworICB9IGVsc2UgeworICAgIHN3aXRjaCAoZmllbGQtPm9wdGlvbnMoKS5jdHlwZSgpKSB7CisgICAgICBkZWZhdWx0OiAgLy8gVE9ETyhrZW50b24pOiAgU3VwcG9ydCBvdGhlciBzdHJpbmcgcmVwcy4KKyAgICAgIGNhc2UgRmllbGRPcHRpb25zOjpTVFJJTkc6CisgICAgICAgICpBZGRGaWVsZDxzdHJpbmc+KG1lc3NhZ2UsIGZpZWxkKSA9IHZhbHVlOworICAgICAgICBicmVhazsKKyAgICB9CisgIH0KK30KKworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2lubGluZSBib29sIENyZWF0ZVVua25vd25FbnVtVmFsdWVzKGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBmaWxlKSB7CisgIHJldHVybiBmaWxlLT5zeW50YXgoKSA9PSBGaWxlRGVzY3JpcHRvcjo6U1lOVEFYX1BST1RPMzsKK30KKworY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OkdldEVudW0oCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3QgeworICAvLyBVc2FnZSBjaGVja2VkIGJ5IEdldEVudW1WYWx1ZS4KKyAgaW50IHZhbHVlID0gR2V0RW51bVZhbHVlKG1lc3NhZ2UsIGZpZWxkKTsKKyAgcmV0dXJuIGZpZWxkLT5lbnVtX3R5cGUoKS0+RmluZFZhbHVlQnlOdW1iZXJDcmVhdGluZ0lmVW5rbm93bih2YWx1ZSk7Cit9CisKK2ludCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6R2V0RW51bVZhbHVlKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0IHsKKyAgVVNBR0VfQ0hFQ0tfQUxMKEdldEVudW1WYWx1ZSwgU0lOR1VMQVIsIEVOVU0pOworCisgIGludDMyIHZhbHVlOworICBpZiAoZmllbGQtPmlzX2V4dGVuc2lvbigpKSB7CisgICAgdmFsdWUgPSBHZXRFeHRlbnNpb25TZXQobWVzc2FnZSkuR2V0RW51bSgKKyAgICAgIGZpZWxkLT5udW1iZXIoKSwgZmllbGQtPmRlZmF1bHRfdmFsdWVfZW51bSgpLT5udW1iZXIoKSk7CisgIH0gZWxzZSB7CisgICAgdmFsdWUgPSBHZXRGaWVsZDxpbnQ+KG1lc3NhZ2UsIGZpZWxkKTsKKyAgfQorICByZXR1cm4gdmFsdWU7Cit9CisKK3ZvaWQgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OlNldEVudW0oCisgICAgTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiB2YWx1ZSkgY29uc3QgeworICAvLyBVc2FnZSBjaGVja2VkIGJ5IFNldEVudW1WYWx1ZS4KKyAgVVNBR0VfQ0hFQ0tfRU5VTV9WQUxVRShTZXRFbnVtKTsKKyAgU2V0RW51bVZhbHVlSW50ZXJuYWwobWVzc2FnZSwgZmllbGQsIHZhbHVlLT5udW1iZXIoKSk7Cit9CisKK3ZvaWQgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OlNldEVudW1WYWx1ZSgKKyAgICBNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgIGludCB2YWx1ZSkgY29uc3QgeworICBVU0FHRV9DSEVDS19BTEwoU2V0RW51bVZhbHVlLCBTSU5HVUxBUiwgRU5VTSk7CisgIGlmICghQ3JlYXRlVW5rbm93bkVudW1WYWx1ZXMoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICAvLyBDaGVjayB0aGF0IHRoZSB2YWx1ZSBpcyB2YWxpZCBpZiB3ZSBkb24ndCBzdXBwb3J0IGRpcmVjdCBzdG9yYWdlIG9mCisgICAgLy8gdW5rbm93biBlbnVtIHZhbHVlcy4KKyAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiB2YWx1ZV9kZXNjID0KKyAgICAgICAgZmllbGQtPmVudW1fdHlwZSgpLT5GaW5kVmFsdWVCeU51bWJlcih2YWx1ZSk7CisgICAgaWYgKHZhbHVlX2Rlc2MgPT0gTlVMTCkgeworICAgICAgR09PR0xFX0xPRyhERkFUQUwpIDw8ICJTZXRFbnVtVmFsdWUgYWNjZXB0cyBvbmx5IHZhbGlkIGludGVnZXIgdmFsdWVzOiB2YWx1ZSAiCisgICAgICAgICAgICAgICAgICA8PCB2YWx1ZSA8PCAiIHVuZXhwZWN0ZWQgZm9yIGZpZWxkICIgPDwgZmllbGQtPmZ1bGxfbmFtZSgpOworICAgICAgLy8gSW4gcHJvZHVjdGlvbiBidWlsZHMsIERGQVRBTCB3aWxsIG5vdCB0ZXJtaW5hdGUgdGhlIHByb2dyYW0sIHNvIHdlIGhhdmUKKyAgICAgIC8vIHRvIGRvIHNvbWV0aGluZyByZWFzb25hYmxlOiBqdXN0IHNldCB0aGUgZGVmYXVsdCB2YWx1ZS4KKyAgICAgIHZhbHVlID0gZmllbGQtPmRlZmF1bHRfdmFsdWVfZW51bSgpLT5udW1iZXIoKTsKKyAgICB9CisgIH0KKyAgU2V0RW51bVZhbHVlSW50ZXJuYWwobWVzc2FnZSwgZmllbGQsIHZhbHVlKTsKK30KKwordm9pZCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6U2V0RW51bVZhbHVlSW50ZXJuYWwoCisgICAgTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICBpbnQgdmFsdWUpIGNvbnN0IHsKKyAgaWYgKGZpZWxkLT5pc19leHRlbnNpb24oKSkgeworICAgIE11dGFibGVFeHRlbnNpb25TZXQobWVzc2FnZSktPlNldEVudW0oZmllbGQtPm51bWJlcigpLCBmaWVsZC0+dHlwZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUsIGZpZWxkKTsKKyAgfSBlbHNlIHsKKyAgICBTZXRGaWVsZDxpbnQ+KG1lc3NhZ2UsIGZpZWxkLCB2YWx1ZSk7CisgIH0KK30KKworY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OkdldFJlcGVhdGVkRW51bSgKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gVXNhZ2UgY2hlY2tlZCBieSBHZXRSZXBlYXRlZEVudW1WYWx1ZS4KKyAgaW50IHZhbHVlID0gR2V0UmVwZWF0ZWRFbnVtVmFsdWUobWVzc2FnZSwgZmllbGQsIGluZGV4KTsKKyAgcmV0dXJuIGZpZWxkLT5lbnVtX3R5cGUoKS0+RmluZFZhbHVlQnlOdW1iZXJDcmVhdGluZ0lmVW5rbm93bih2YWx1ZSk7Cit9CisKK2ludCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6R2V0UmVwZWF0ZWRFbnVtVmFsdWUoCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50IGluZGV4KSBjb25zdCB7CisgIFVTQUdFX0NIRUNLX0FMTChHZXRSZXBlYXRlZEVudW1WYWx1ZSwgUkVQRUFURUQsIEVOVU0pOworCisgIGludCB2YWx1ZTsKKyAgaWYgKGZpZWxkLT5pc19leHRlbnNpb24oKSkgeworICAgIHZhbHVlID0gR2V0RXh0ZW5zaW9uU2V0KG1lc3NhZ2UpLkdldFJlcGVhdGVkRW51bShmaWVsZC0+bnVtYmVyKCksIGluZGV4KTsKKyAgfSBlbHNlIHsKKyAgICB2YWx1ZSA9IEdldFJlcGVhdGVkRmllbGQ8aW50PihtZXNzYWdlLCBmaWVsZCwgaW5kZXgpOworICB9CisgIHJldHVybiB2YWx1ZTsKK30KKwordm9pZCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6U2V0UmVwZWF0ZWRFbnVtKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50IGluZGV4LAorICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIHZhbHVlKSBjb25zdCB7CisgIC8vIFVzYWdlIGNoZWNrZWQgYnkgU2V0UmVwZWF0ZWRFbnVtVmFsdWUuCisgIFVTQUdFX0NIRUNLX0VOVU1fVkFMVUUoU2V0UmVwZWF0ZWRFbnVtKTsKKyAgU2V0UmVwZWF0ZWRFbnVtVmFsdWVJbnRlcm5hbChtZXNzYWdlLCBmaWVsZCwgaW5kZXgsIHZhbHVlLT5udW1iZXIoKSk7Cit9CisKK3ZvaWQgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OlNldFJlcGVhdGVkRW51bVZhbHVlKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50IGluZGV4LAorICAgIGludCB2YWx1ZSkgY29uc3QgeworICBVU0FHRV9DSEVDS19BTEwoU2V0UmVwZWF0ZWRFbnVtLCBSRVBFQVRFRCwgRU5VTSk7CisgIGlmICghQ3JlYXRlVW5rbm93bkVudW1WYWx1ZXMoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICAvLyBDaGVjayB0aGF0IHRoZSB2YWx1ZSBpcyB2YWxpZCBpZiB3ZSBkb24ndCBzdXBwb3J0IGRpcmVjdCBzdG9yYWdlIG9mCisgICAgLy8gdW5rbm93biBlbnVtIHZhbHVlcy4KKyAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiB2YWx1ZV9kZXNjID0KKyAgICAgICAgZmllbGQtPmVudW1fdHlwZSgpLT5GaW5kVmFsdWVCeU51bWJlcih2YWx1ZSk7CisgICAgaWYgKHZhbHVlX2Rlc2MgPT0gTlVMTCkgeworICAgICAgR09PR0xFX0xPRyhERkFUQUwpIDw8ICJTZXRSZXBlYXRlZEVudW1WYWx1ZSBhY2NlcHRzIG9ubHkgdmFsaWQgaW50ZWdlciB2YWx1ZXM6ICIKKyAgICAgICAgICAgICAgICAgIDw8ICJ2YWx1ZSAiIDw8IHZhbHVlIDw8ICIgdW5leHBlY3RlZCBmb3IgZmllbGQgIgorICAgICAgICAgICAgICAgICAgPDwgZmllbGQtPmZ1bGxfbmFtZSgpOworICAgICAgLy8gSW4gcHJvZHVjdGlvbiBidWlsZHMsIERGQVRBTCB3aWxsIG5vdCB0ZXJtaW5hdGUgdGhlIHByb2dyYW0sIHNvIHdlIGhhdmUKKyAgICAgIC8vIHRvIGRvIHNvbWV0aGluZyByZWFzb25hYmxlOiBqdXN0IHNldCB0aGUgZGVmYXVsdCB2YWx1ZS4KKyAgICAgIHZhbHVlID0gZmllbGQtPmRlZmF1bHRfdmFsdWVfZW51bSgpLT5udW1iZXIoKTsKKyAgICB9CisgIH0KKyAgU2V0UmVwZWF0ZWRFbnVtVmFsdWVJbnRlcm5hbChtZXNzYWdlLCBmaWVsZCwgaW5kZXgsIHZhbHVlKTsKK30KKwordm9pZCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6U2V0UmVwZWF0ZWRFbnVtVmFsdWVJbnRlcm5hbCgKKyAgICBNZXNzYWdlKiBtZXNzYWdlLAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGludCBpbmRleCwKKyAgICBpbnQgdmFsdWUpIGNvbnN0IHsKKyAgaWYgKGZpZWxkLT5pc19leHRlbnNpb24oKSkgeworICAgIE11dGFibGVFeHRlbnNpb25TZXQobWVzc2FnZSktPlNldFJlcGVhdGVkRW51bSgKKyAgICAgIGZpZWxkLT5udW1iZXIoKSwgaW5kZXgsIHZhbHVlKTsKKyAgfSBlbHNlIHsKKyAgICBTZXRSZXBlYXRlZEZpZWxkPGludD4obWVzc2FnZSwgZmllbGQsIGluZGV4LCB2YWx1ZSk7CisgIH0KK30KKwordm9pZCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6QWRkRW51bSgKKyAgICBNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIHZhbHVlKSBjb25zdCB7CisgIC8vIFVzYWdlIGNoZWNrZWQgYnkgQWRkRW51bVZhbHVlLgorICBVU0FHRV9DSEVDS19FTlVNX1ZBTFVFKEFkZEVudW0pOworICBBZGRFbnVtVmFsdWVJbnRlcm5hbChtZXNzYWdlLCBmaWVsZCwgdmFsdWUtPm51bWJlcigpKTsKK30KKwordm9pZCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6QWRkRW51bVZhbHVlKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgaW50IHZhbHVlKSBjb25zdCB7CisgIFVTQUdFX0NIRUNLX0FMTChBZGRFbnVtLCBSRVBFQVRFRCwgRU5VTSk7CisgIGlmICghQ3JlYXRlVW5rbm93bkVudW1WYWx1ZXMoZGVzY3JpcHRvcl8tPmZpbGUoKSkpIHsKKyAgICAvLyBDaGVjayB0aGF0IHRoZSB2YWx1ZSBpcyB2YWxpZCBpZiB3ZSBkb24ndCBzdXBwb3J0IGRpcmVjdCBzdG9yYWdlIG9mCisgICAgLy8gdW5rbm93biBlbnVtIHZhbHVlcy4KKyAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiB2YWx1ZV9kZXNjID0KKyAgICAgICAgZmllbGQtPmVudW1fdHlwZSgpLT5GaW5kVmFsdWVCeU51bWJlcih2YWx1ZSk7CisgICAgaWYgKHZhbHVlX2Rlc2MgPT0gTlVMTCkgeworICAgICAgR09PR0xFX0xPRyhERkFUQUwpIDw8ICJBZGRFbnVtVmFsdWUgYWNjZXB0cyBvbmx5IHZhbGlkIGludGVnZXIgdmFsdWVzOiB2YWx1ZSAiCisgICAgICAgICAgICAgICAgICA8PCB2YWx1ZSA8PCAiIHVuZXhwZWN0ZWQgZm9yIGZpZWxkICIgPDwgZmllbGQtPmZ1bGxfbmFtZSgpOworICAgICAgLy8gSW4gcHJvZHVjdGlvbiBidWlsZHMsIERGQVRBTCB3aWxsIG5vdCB0ZXJtaW5hdGUgdGhlIHByb2dyYW0sIHNvIHdlIGhhdmUKKyAgICAgIC8vIHRvIGRvIHNvbWV0aGluZyByZWFzb25hYmxlOiBqdXN0IHNldCB0aGUgZGVmYXVsdCB2YWx1ZS4KKyAgICAgIHZhbHVlID0gZmllbGQtPmRlZmF1bHRfdmFsdWVfZW51bSgpLT5udW1iZXIoKTsKKyAgICB9CisgIH0KKyAgQWRkRW51bVZhbHVlSW50ZXJuYWwobWVzc2FnZSwgZmllbGQsIHZhbHVlKTsKK30KKwordm9pZCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6QWRkRW51bVZhbHVlSW50ZXJuYWwoCisgICAgTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICBpbnQgdmFsdWUpIGNvbnN0IHsKKyAgaWYgKGZpZWxkLT5pc19leHRlbnNpb24oKSkgeworICAgIE11dGFibGVFeHRlbnNpb25TZXQobWVzc2FnZSktPkFkZEVudW0oZmllbGQtPm51bWJlcigpLCBmaWVsZC0+dHlwZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGQtPm9wdGlvbnMoKS5wYWNrZWQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlLCBmaWVsZCk7CisgIH0gZWxzZSB7CisgICAgQWRkRmllbGQ8aW50PihtZXNzYWdlLCBmaWVsZCwgdmFsdWUpOworICB9Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY29uc3QgTWVzc2FnZSYgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OkdldE1lc3NhZ2UoCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICBNZXNzYWdlRmFjdG9yeSogZmFjdG9yeSkgY29uc3QgeworICBVU0FHRV9DSEVDS19BTEwoR2V0TWVzc2FnZSwgU0lOR1VMQVIsIE1FU1NBR0UpOworCisgIGlmIChmYWN0b3J5ID09IE5VTEwpIGZhY3RvcnkgPSBtZXNzYWdlX2ZhY3RvcnlfOworCisgIGlmIChmaWVsZC0+aXNfZXh0ZW5zaW9uKCkpIHsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8Y29uc3QgTWVzc2FnZSY+KAorICAgICAgICBHZXRFeHRlbnNpb25TZXQobWVzc2FnZSkuR2V0TWVzc2FnZSgKKyAgICAgICAgICBmaWVsZC0+bnVtYmVyKCksIGZpZWxkLT5tZXNzYWdlX3R5cGUoKSwgZmFjdG9yeSkpOworICB9IGVsc2UgeworICAgIGNvbnN0IE1lc3NhZ2UqIHJlc3VsdDsKKyAgICByZXN1bHQgPSBHZXRSYXc8Y29uc3QgTWVzc2FnZSo+KG1lc3NhZ2UsIGZpZWxkKTsKKyAgICBpZiAocmVzdWx0ID09IE5VTEwpIHsKKyAgICAgIHJlc3VsdCA9IERlZmF1bHRSYXc8Y29uc3QgTWVzc2FnZSo+KGZpZWxkKTsKKyAgICB9CisgICAgcmV0dXJuICpyZXN1bHQ7CisgIH0KK30KKworTWVzc2FnZSogR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok11dGFibGVNZXNzYWdlKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgTWVzc2FnZUZhY3RvcnkqIGZhY3RvcnkpIGNvbnN0IHsKKyAgVVNBR0VfQ0hFQ0tfQUxMKE11dGFibGVNZXNzYWdlLCBTSU5HVUxBUiwgTUVTU0FHRSk7CisKKyAgaWYgKGZhY3RvcnkgPT0gTlVMTCkgZmFjdG9yeSA9IG1lc3NhZ2VfZmFjdG9yeV87CisKKyAgaWYgKGZpZWxkLT5pc19leHRlbnNpb24oKSkgeworICAgIHJldHVybiBzdGF0aWNfY2FzdDxNZXNzYWdlKj4oCisgICAgICAgIE11dGFibGVFeHRlbnNpb25TZXQobWVzc2FnZSktPk11dGFibGVNZXNzYWdlKGZpZWxkLCBmYWN0b3J5KSk7CisgIH0gZWxzZSB7CisgICAgTWVzc2FnZSogcmVzdWx0OworICAgIE1lc3NhZ2UqKiByZXN1bHRfaG9sZGVyID0gTXV0YWJsZVJhdzxNZXNzYWdlKj4obWVzc2FnZSwgZmllbGQpOworCisgICAgaWYgKGZpZWxkLT5jb250YWluaW5nX29uZW9mKCkpIHsKKyAgICAgIGlmICghSGFzT25lb2ZGaWVsZCgqbWVzc2FnZSwgZmllbGQpKSB7CisgICAgICAgIENsZWFyT25lb2YobWVzc2FnZSwgZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSk7CisgICAgICAgIHJlc3VsdF9ob2xkZXIgPSBNdXRhYmxlRmllbGQ8TWVzc2FnZSo+KG1lc3NhZ2UsIGZpZWxkKTsKKyAgICAgICAgY29uc3QgTWVzc2FnZSogZGVmYXVsdF9tZXNzYWdlID0gRGVmYXVsdFJhdzxjb25zdCBNZXNzYWdlKj4oZmllbGQpOworICAgICAgICAqcmVzdWx0X2hvbGRlciA9IGRlZmF1bHRfbWVzc2FnZS0+TmV3KG1lc3NhZ2UtPkdldEFyZW5hKCkpOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICBTZXRCaXQobWVzc2FnZSwgZmllbGQpOworICAgIH0KKworICAgIGlmICgqcmVzdWx0X2hvbGRlciA9PSBOVUxMKSB7CisgICAgICBjb25zdCBNZXNzYWdlKiBkZWZhdWx0X21lc3NhZ2UgPSBEZWZhdWx0UmF3PGNvbnN0IE1lc3NhZ2UqPihmaWVsZCk7CisgICAgICAqcmVzdWx0X2hvbGRlciA9IGRlZmF1bHRfbWVzc2FnZS0+TmV3KG1lc3NhZ2UtPkdldEFyZW5hKCkpOworICAgIH0KKyAgICByZXN1bHQgPSAqcmVzdWx0X2hvbGRlcjsKKyAgICByZXR1cm4gcmVzdWx0OworICB9Cit9CisKK3ZvaWQgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OlVuc2FmZUFyZW5hU2V0QWxsb2NhdGVkTWVzc2FnZSgKKyAgICBNZXNzYWdlKiBtZXNzYWdlLAorICAgIE1lc3NhZ2UqIHN1Yl9tZXNzYWdlLAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0IHsKKyAgVVNBR0VfQ0hFQ0tfQUxMKFNldEFsbG9jYXRlZE1lc3NhZ2UsIFNJTkdVTEFSLCBNRVNTQUdFKTsKKworICBpZiAoZmllbGQtPmlzX2V4dGVuc2lvbigpKSB7CisgICAgTXV0YWJsZUV4dGVuc2lvblNldChtZXNzYWdlKS0+U2V0QWxsb2NhdGVkTWVzc2FnZSgKKyAgICAgICAgZmllbGQtPm51bWJlcigpLCBmaWVsZC0+dHlwZSgpLCBmaWVsZCwgc3ViX21lc3NhZ2UpOworICB9IGVsc2UgeworICAgIGlmIChmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpKSB7CisgICAgICBpZiAoc3ViX21lc3NhZ2UgPT0gTlVMTCkgeworICAgICAgICBDbGVhck9uZW9mKG1lc3NhZ2UsIGZpZWxkLT5jb250YWluaW5nX29uZW9mKCkpOworICAgICAgICByZXR1cm47CisgICAgICB9CisgICAgICAgIENsZWFyT25lb2YobWVzc2FnZSwgZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSk7CisgICAgICAgICpNdXRhYmxlUmF3PE1lc3NhZ2UqPihtZXNzYWdlLCBmaWVsZCkgPSBzdWJfbWVzc2FnZTsKKyAgICAgIFNldE9uZW9mQ2FzZShtZXNzYWdlLCBmaWVsZCk7CisgICAgICByZXR1cm47CisgICAgfQorCisgICAgaWYgKHN1Yl9tZXNzYWdlID09IE5VTEwpIHsKKyAgICAgIENsZWFyQml0KG1lc3NhZ2UsIGZpZWxkKTsKKyAgICB9IGVsc2UgeworICAgICAgU2V0Qml0KG1lc3NhZ2UsIGZpZWxkKTsKKyAgICB9CisgICAgTWVzc2FnZSoqIHN1Yl9tZXNzYWdlX2hvbGRlciA9IE11dGFibGVSYXc8TWVzc2FnZSo+KG1lc3NhZ2UsIGZpZWxkKTsKKyAgICBpZiAoR2V0QXJlbmEobWVzc2FnZSkgPT0gTlVMTCkgeworICAgICAgZGVsZXRlICpzdWJfbWVzc2FnZV9ob2xkZXI7CisgICAgfQorICAgICpzdWJfbWVzc2FnZV9ob2xkZXIgPSBzdWJfbWVzc2FnZTsKKyAgfQorfQorCit2b2lkIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpTZXRBbGxvY2F0ZWRNZXNzYWdlKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgTWVzc2FnZSogc3ViX21lc3NhZ2UsCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3QgeworICAvLyBJZiBtZXNzYWdlIGFuZCBzdWItbWVzc2FnZSBhcmUgaW4gZGlmZmVyZW50IG1lbW9yeSBvd25lcnNoaXAgZG9tYWlucworICAvLyAoZGlmZmVyZW50IGFyZW5hcywgb3Igb25lIGlzIG9uIGhlYXAgYW5kIG9uZSBpcyBub3QpLCB0aGVuIHdlIG1heSBuZWVkIHRvCisgIC8vIGRvIGEgY29weS4KKyAgaWYgKHN1Yl9tZXNzYWdlICE9IE5VTEwgJiYKKyAgICAgIHN1Yl9tZXNzYWdlLT5HZXRBcmVuYSgpICE9IG1lc3NhZ2UtPkdldEFyZW5hKCkpIHsKKyAgICBpZiAoc3ViX21lc3NhZ2UtPkdldEFyZW5hKCkgPT0gTlVMTCAmJiBtZXNzYWdlLT5HZXRBcmVuYSgpICE9IE5VTEwpIHsKKyAgICAgIC8vIENhc2UgMTogcGFyZW50IGlzIG9uIGFuIGFyZW5hIGFuZCBjaGlsZCBpcyBoZWFwLWFsbG9jYXRlZC4gV2UgY2FuIGFkZAorICAgICAgLy8gdGhlIGNoaWxkIHRvIHRoZSBhcmVuYSdzIE93bigpIGxpc3QgdG8gZnJlZSBvbiBhcmVuYSBkZXN0cnVjdGlvbiwgdGhlbgorICAgICAgLy8gc2V0IG91ciBwb2ludGVyLgorICAgICAgbWVzc2FnZS0+R2V0QXJlbmEoKS0+T3duKHN1Yl9tZXNzYWdlKTsKKyAgICAgIFVuc2FmZUFyZW5hU2V0QWxsb2NhdGVkTWVzc2FnZShtZXNzYWdlLCBzdWJfbWVzc2FnZSwgZmllbGQpOworICAgIH0gZWxzZSB7CisgICAgICAvLyBDYXNlIDI6IGFsbCBvdGhlciBjYXNlcy4gV2UgbmVlZCB0byBtYWtlIGEgY29weS4gTXV0YWJsZU1lc3NhZ2UoKSB3aWxsCisgICAgICAvLyBlaXRoZXIgZ2V0IHRoZSBleGlzdGluZyBtZXNzYWdlIG9iamVjdCwgb3IgaW5zdGFudGlhdGUgYSBuZXcgb25lIGFzCisgICAgICAvLyBhcHByb3ByaWF0ZSB3LnIudC4gb3VyIGFyZW5hLgorICAgICAgTWVzc2FnZSogc3ViX21lc3NhZ2VfY29weSA9IE11dGFibGVNZXNzYWdlKG1lc3NhZ2UsIGZpZWxkKTsKKyAgICAgIHN1Yl9tZXNzYWdlX2NvcHktPkNvcHlGcm9tKCpzdWJfbWVzc2FnZSk7CisgICAgfQorICB9IGVsc2UgeworICAgIC8vIFNhbWUgbWVtb3J5IG93bmVyc2hpcCBkb21haW5zLgorICAgIFVuc2FmZUFyZW5hU2V0QWxsb2NhdGVkTWVzc2FnZShtZXNzYWdlLCBzdWJfbWVzc2FnZSwgZmllbGQpOworICB9Cit9CisKK01lc3NhZ2UqIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpVbnNhZmVBcmVuYVJlbGVhc2VNZXNzYWdlKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICBNZXNzYWdlRmFjdG9yeSogZmFjdG9yeSkgY29uc3QgeworICBVU0FHRV9DSEVDS19BTEwoUmVsZWFzZU1lc3NhZ2UsIFNJTkdVTEFSLCBNRVNTQUdFKTsKKworICBpZiAoZmFjdG9yeSA9PSBOVUxMKSBmYWN0b3J5ID0gbWVzc2FnZV9mYWN0b3J5XzsKKworICBpZiAoZmllbGQtPmlzX2V4dGVuc2lvbigpKSB7CisgICAgcmV0dXJuIHN0YXRpY19jYXN0PE1lc3NhZ2UqPigKKyAgICAgICAgTXV0YWJsZUV4dGVuc2lvblNldChtZXNzYWdlKS0+UmVsZWFzZU1lc3NhZ2UoZmllbGQsIGZhY3RvcnkpKTsKKyAgfSBlbHNlIHsKKyAgICBDbGVhckJpdChtZXNzYWdlLCBmaWVsZCk7CisgICAgaWYgKGZpZWxkLT5jb250YWluaW5nX29uZW9mKCkpIHsKKyAgICAgIGlmIChIYXNPbmVvZkZpZWxkKCptZXNzYWdlLCBmaWVsZCkpIHsKKyAgICAgICAgKk11dGFibGVPbmVvZkNhc2UobWVzc2FnZSwgZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSkgPSAwOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICB9CisgICAgfQorICAgIE1lc3NhZ2UqKiByZXN1bHQgPSBNdXRhYmxlUmF3PE1lc3NhZ2UqPihtZXNzYWdlLCBmaWVsZCk7CisgICAgTWVzc2FnZSogcmV0ID0gKnJlc3VsdDsKKyAgICAqcmVzdWx0ID0gTlVMTDsKKyAgICByZXR1cm4gcmV0OworICB9Cit9CisKK01lc3NhZ2UqIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpSZWxlYXNlTWVzc2FnZSgKKyAgICBNZXNzYWdlKiBtZXNzYWdlLAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgTWVzc2FnZUZhY3RvcnkqIGZhY3RvcnkpIGNvbnN0IHsKKyAgTWVzc2FnZSogcmVsZWFzZWQgPSBVbnNhZmVBcmVuYVJlbGVhc2VNZXNzYWdlKG1lc3NhZ2UsIGZpZWxkLCBmYWN0b3J5KTsKKyAgaWYgKEdldEFyZW5hKG1lc3NhZ2UpICE9IE5VTEwgJiYgcmVsZWFzZWQgIT0gTlVMTCkgeworICAgIE1lc3NhZ2UqIGNvcHlfZnJvbV9hcmVuYSA9IHJlbGVhc2VkLT5OZXcoKTsKKyAgICBjb3B5X2Zyb21fYXJlbmEtPkNvcHlGcm9tKCpyZWxlYXNlZCk7CisgICAgcmVsZWFzZWQgPSBjb3B5X2Zyb21fYXJlbmE7CisgIH0KKyAgcmV0dXJuIHJlbGVhc2VkOworfQorCitjb25zdCBNZXNzYWdlJiBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6R2V0UmVwZWF0ZWRNZXNzYWdlKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGludCBpbmRleCkgY29uc3QgeworICBVU0FHRV9DSEVDS19BTEwoR2V0UmVwZWF0ZWRNZXNzYWdlLCBSRVBFQVRFRCwgTUVTU0FHRSk7CisKKyAgaWYgKGZpZWxkLT5pc19leHRlbnNpb24oKSkgeworICAgIHJldHVybiBzdGF0aWNfY2FzdDxjb25zdCBNZXNzYWdlJj4oCisgICAgICAgIEdldEV4dGVuc2lvblNldChtZXNzYWdlKS5HZXRSZXBlYXRlZE1lc3NhZ2UoZmllbGQtPm51bWJlcigpLCBpbmRleCkpOworICB9IGVsc2UgeworICAgIGlmIChJc01hcEZpZWxkSW5BcGkoZmllbGQpKSB7CisgICAgICByZXR1cm4gR2V0UmF3PE1hcEZpZWxkQmFzZT4obWVzc2FnZSwgZmllbGQpCisgICAgICAgICAgLkdldFJlcGVhdGVkRmllbGQoKQorICAgICAgICAgIC5HZXQ8R2VuZXJpY1R5cGVIYW5kbGVyPE1lc3NhZ2U+ID4oaW5kZXgpOworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gR2V0UmF3PFJlcGVhdGVkUHRyRmllbGRCYXNlPihtZXNzYWdlLCBmaWVsZCkKKyAgICAgICAgICAuR2V0PEdlbmVyaWNUeXBlSGFuZGxlcjxNZXNzYWdlPiA+KGluZGV4KTsKKyAgICB9CisgIH0KK30KKworTWVzc2FnZSogR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok11dGFibGVSZXBlYXRlZE1lc3NhZ2UoCisgICAgTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50IGluZGV4KSBjb25zdCB7CisgIFVTQUdFX0NIRUNLX0FMTChNdXRhYmxlUmVwZWF0ZWRNZXNzYWdlLCBSRVBFQVRFRCwgTUVTU0FHRSk7CisKKyAgaWYgKGZpZWxkLT5pc19leHRlbnNpb24oKSkgeworICAgIHJldHVybiBzdGF0aWNfY2FzdDxNZXNzYWdlKj4oCisgICAgICAgIE11dGFibGVFeHRlbnNpb25TZXQobWVzc2FnZSktPk11dGFibGVSZXBlYXRlZE1lc3NhZ2UoCisgICAgICAgICAgZmllbGQtPm51bWJlcigpLCBpbmRleCkpOworICB9IGVsc2UgeworICAgIGlmIChJc01hcEZpZWxkSW5BcGkoZmllbGQpKSB7CisgICAgICByZXR1cm4gTXV0YWJsZVJhdzxNYXBGaWVsZEJhc2U+KG1lc3NhZ2UsIGZpZWxkKQorICAgICAgICAgIC0+TXV0YWJsZVJlcGVhdGVkRmllbGQoKQorICAgICAgICAgIC0+TXV0YWJsZTxHZW5lcmljVHlwZUhhbmRsZXI8TWVzc2FnZT4gPihpbmRleCk7CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiBNdXRhYmxlUmF3PFJlcGVhdGVkUHRyRmllbGRCYXNlPihtZXNzYWdlLCBmaWVsZCkKKyAgICAgICAgLT5NdXRhYmxlPEdlbmVyaWNUeXBlSGFuZGxlcjxNZXNzYWdlPiA+KGluZGV4KTsKKyAgICB9CisgIH0KK30KKworTWVzc2FnZSogR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OkFkZE1lc3NhZ2UoCisgICAgTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICBNZXNzYWdlRmFjdG9yeSogZmFjdG9yeSkgY29uc3QgeworICBVU0FHRV9DSEVDS19BTEwoQWRkTWVzc2FnZSwgUkVQRUFURUQsIE1FU1NBR0UpOworCisgIGlmIChmYWN0b3J5ID09IE5VTEwpIGZhY3RvcnkgPSBtZXNzYWdlX2ZhY3RvcnlfOworCisgIGlmIChmaWVsZC0+aXNfZXh0ZW5zaW9uKCkpIHsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8TWVzc2FnZSo+KAorICAgICAgICBNdXRhYmxlRXh0ZW5zaW9uU2V0KG1lc3NhZ2UpLT5BZGRNZXNzYWdlKGZpZWxkLCBmYWN0b3J5KSk7CisgIH0gZWxzZSB7CisgICAgTWVzc2FnZSogcmVzdWx0ID0gTlVMTDsKKworICAgIC8vIFdlIGNhbid0IHVzZSBBZGRGaWVsZDxNZXNzYWdlPigpIGJlY2F1c2UgUmVwZWF0ZWRQdHJGaWVsZEJhc2UgZG9lc24ndAorICAgIC8vIGtub3cgaG93IHRvIGFsbG9jYXRlIG9uZS4KKyAgICBSZXBlYXRlZFB0ckZpZWxkQmFzZSogcmVwZWF0ZWQgPSBOVUxMOworICAgIGlmIChJc01hcEZpZWxkSW5BcGkoZmllbGQpKSB7CisgICAgICByZXBlYXRlZCA9CisgICAgICAgICAgTXV0YWJsZVJhdzxNYXBGaWVsZEJhc2U+KG1lc3NhZ2UsIGZpZWxkKS0+TXV0YWJsZVJlcGVhdGVkRmllbGQoKTsKKyAgICB9IGVsc2UgeworICAgICAgcmVwZWF0ZWQgPSBNdXRhYmxlUmF3PFJlcGVhdGVkUHRyRmllbGRCYXNlPihtZXNzYWdlLCBmaWVsZCk7CisgICAgfQorICAgIHJlc3VsdCA9IHJlcGVhdGVkLT5BZGRGcm9tQ2xlYXJlZDxHZW5lcmljVHlwZUhhbmRsZXI8TWVzc2FnZT4gPigpOworICAgIGlmIChyZXN1bHQgPT0gTlVMTCkgeworICAgICAgLy8gV2UgbXVzdCBhbGxvY2F0ZSBhIG5ldyBvYmplY3QuCisgICAgICBjb25zdCBNZXNzYWdlKiBwcm90b3R5cGU7CisgICAgICBpZiAocmVwZWF0ZWQtPnNpemUoKSA9PSAwKSB7CisgICAgICAgIHByb3RvdHlwZSA9IGZhY3RvcnktPkdldFByb3RvdHlwZShmaWVsZC0+bWVzc2FnZV90eXBlKCkpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcHJvdG90eXBlID0gJnJlcGVhdGVkLT5HZXQ8R2VuZXJpY1R5cGVIYW5kbGVyPE1lc3NhZ2U+ID4oMCk7CisgICAgICB9CisgICAgICByZXN1bHQgPSBwcm90b3R5cGUtPk5ldyhtZXNzYWdlLT5HZXRBcmVuYSgpKTsKKyAgICAgIC8vIFdlIGNhbiBndWFyYW50ZWUgaGVyZSB0aGF0IHJlcGVhdGVkIGFuZCByZXN1bHQgYXJlIGVpdGhlciBib3RoIGhlYXAKKyAgICAgIC8vIGFsbG9jYXRlZCBvciBhcmVuYSBvd25lZC4gU28gaXQgaXMgc2FmZSB0byBjYWxsIHRoZSB1bnNhZmUgdmVyc2lvbgorICAgICAgLy8gb2YgQWRkQWxsb2NhdGVkLgorICAgICAgcmVwZWF0ZWQtPlVuc2FmZUFyZW5hQWRkQWxsb2NhdGVkPEdlbmVyaWNUeXBlSGFuZGxlcjxNZXNzYWdlPiA+KHJlc3VsdCk7CisgICAgfQorCisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorfQorCit2b2lkIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpBZGRBbGxvY2F0ZWRNZXNzYWdlKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgTWVzc2FnZSogbmV3X2VudHJ5KSBjb25zdCB7CisgIFVTQUdFX0NIRUNLX0FMTChBZGRBbGxvY2F0ZWRNZXNzYWdlLCBSRVBFQVRFRCwgTUVTU0FHRSk7CisKKyAgaWYgKGZpZWxkLT5pc19leHRlbnNpb24oKSkgeworICAgIE11dGFibGVFeHRlbnNpb25TZXQobWVzc2FnZSktPkFkZEFsbG9jYXRlZE1lc3NhZ2UoZmllbGQsIG5ld19lbnRyeSk7CisgIH0gZWxzZSB7CisgICAgUmVwZWF0ZWRQdHJGaWVsZEJhc2UqIHJlcGVhdGVkID0gTlVMTDsKKyAgICBpZiAoSXNNYXBGaWVsZEluQXBpKGZpZWxkKSkgeworICAgICAgcmVwZWF0ZWQgPQorICAgICAgICAgIE11dGFibGVSYXc8TWFwRmllbGRCYXNlPihtZXNzYWdlLCBmaWVsZCktPk11dGFibGVSZXBlYXRlZEZpZWxkKCk7CisgICAgfSBlbHNlIHsKKyAgICAgIHJlcGVhdGVkID0gTXV0YWJsZVJhdzxSZXBlYXRlZFB0ckZpZWxkQmFzZT4obWVzc2FnZSwgZmllbGQpOworICAgIH0KKyAgICByZXBlYXRlZC0+QWRkQWxsb2NhdGVkPEdlbmVyaWNUeXBlSGFuZGxlcjxNZXNzYWdlPiA+KG5ld19lbnRyeSk7CisgIH0KK30KKwordm9pZCogR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok11dGFibGVSYXdSZXBlYXRlZEZpZWxkKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgRmllbGREZXNjcmlwdG9yOjpDcHBUeXBlIGNwcHR5cGUsCisgICAgaW50IGN0eXBlLCBjb25zdCBEZXNjcmlwdG9yKiBkZXNjKSBjb25zdCB7CisgIFVTQUdFX0NIRUNLX1JFUEVBVEVEKCJNdXRhYmxlUmF3UmVwZWF0ZWRGaWVsZCIpOworICBpZiAoZmllbGQtPmNwcF90eXBlKCkgIT0gY3BwdHlwZSkKKyAgICBSZXBvcnRSZWZsZWN0aW9uVXNhZ2VUeXBlRXJyb3IoZGVzY3JpcHRvcl8sCisgICAgICAgIGZpZWxkLCAiTXV0YWJsZVJhd1JlcGVhdGVkRmllbGQiLCBjcHB0eXBlKTsKKyAgaWYgKGN0eXBlID49IDApCisgICAgR09PR0xFX0NIRUNLX0VRKGZpZWxkLT5vcHRpb25zKCkuY3R5cGUoKSwgY3R5cGUpIDw8ICJzdWJ0eXBlIG1pc21hdGNoIjsKKyAgaWYgKGRlc2MgIT0gTlVMTCkKKyAgICBHT09HTEVfQ0hFQ0tfRVEoZmllbGQtPm1lc3NhZ2VfdHlwZSgpLCBkZXNjKSA8PCAid3Jvbmcgc3VibWVzc2FnZSB0eXBlIjsKKyAgaWYgKGZpZWxkLT5pc19leHRlbnNpb24oKSkgeworICAgIHJldHVybiBNdXRhYmxlRXh0ZW5zaW9uU2V0KG1lc3NhZ2UpLT5NdXRhYmxlUmF3UmVwZWF0ZWRGaWVsZCgKKyAgICAgICAgZmllbGQtPm51bWJlcigpLCBmaWVsZC0+dHlwZSgpLCBmaWVsZC0+aXNfcGFja2VkKCksIGZpZWxkKTsKKyAgfSBlbHNlIHsKKyAgICAvLyBUcmlnZ2VyIHRyYW5zZm9ybSBmb3IgTWFwRmllbGQKKyAgICBpZiAoSXNNYXBGaWVsZEluQXBpKGZpZWxkKSkgeworICAgICAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8TWFwRmllbGRCYXNlKj4ocmVpbnRlcnByZXRfY2FzdDx1aW50OCo+KG1lc3NhZ2UpICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldHNfW2ZpZWxkLT5pbmRleCgpXSkKKyAgICAgICAgICAtPk11dGFibGVSZXBlYXRlZEZpZWxkKCk7CisgICAgfQorICAgIHJldHVybiByZWludGVycHJldF9jYXN0PHVpbnQ4Kj4obWVzc2FnZSkgKyBvZmZzZXRzX1tmaWVsZC0+aW5kZXgoKV07CisgIH0KK30KKworY29uc3Qgdm9pZCogR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OkdldFJhd1JlcGVhdGVkRmllbGQoCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICBGaWVsZERlc2NyaXB0b3I6OkNwcFR5cGUgY3BwdHlwZSwKKyAgICBpbnQgY3R5cGUsIGNvbnN0IERlc2NyaXB0b3IqIGRlc2MpIGNvbnN0IHsKKyAgVVNBR0VfQ0hFQ0tfUkVQRUFURUQoIkdldFJhd1JlcGVhdGVkRmllbGQiKTsKKyAgaWYgKGZpZWxkLT5jcHBfdHlwZSgpICE9IGNwcHR5cGUpCisgICAgUmVwb3J0UmVmbGVjdGlvblVzYWdlVHlwZUVycm9yKGRlc2NyaXB0b3JfLAorICAgICAgICBmaWVsZCwgIkdldFJhd1JlcGVhdGVkRmllbGQiLCBjcHB0eXBlKTsKKyAgaWYgKGN0eXBlID49IDApCisgICAgR09PR0xFX0NIRUNLX0VRKGZpZWxkLT5vcHRpb25zKCkuY3R5cGUoKSwgY3R5cGUpIDw8ICJzdWJ0eXBlIG1pc21hdGNoIjsKKyAgaWYgKGRlc2MgIT0gTlVMTCkKKyAgICBHT09HTEVfQ0hFQ0tfRVEoZmllbGQtPm1lc3NhZ2VfdHlwZSgpLCBkZXNjKSA8PCAid3Jvbmcgc3VibWVzc2FnZSB0eXBlIjsKKyAgaWYgKGZpZWxkLT5pc19leHRlbnNpb24oKSkgeworICAgIC8vIFNob3VsZCB1c2UgZXh0ZW5zaW9uX3NldDo6R2V0UmF3UmVwZWF0ZWRGaWVsZC4gSG93ZXZlciwgdGhlIHJlcXVpcmVkCisgICAgLy8gcGFyYW1ldGVyICJkZWZhdWx0IHJlcGVhdGVkIHZhbHVlIiBpcyBub3QgdmVyeSBlYXN5IHRvIGdldCBoZXJlLgorICAgIC8vIE1hcCBpcyBub3Qgc3VwcG9ydGVkIGluIGV4dGVuc2lvbnMsIGl0IGlzIGFjY2VwdGFibGUgdG8gdXNlCisgICAgLy8gZXh0ZW5zaW9uX3NldDo6TXV0YWJsZVJhd1JlcGVhdGVkRmllbGQgd2hpY2ggZG9lcyBub3QgY2hhbmdlIHRoZSBtZXNzYWdlLgorICAgIHJldHVybiBNdXRhYmxlRXh0ZW5zaW9uU2V0KGNvbnN0X2Nhc3Q8TWVzc2FnZSo+KCZtZXNzYWdlKSkKKyAgICAgICAgLT5NdXRhYmxlUmF3UmVwZWF0ZWRGaWVsZCgKKyAgICAgICAgZmllbGQtPm51bWJlcigpLCBmaWVsZC0+dHlwZSgpLCBmaWVsZC0+aXNfcGFja2VkKCksIGZpZWxkKTsKKyAgfSBlbHNlIHsKKyAgICAvLyBUcmlnZ2VyIHRyYW5zZm9ybSBmb3IgTWFwRmllbGQKKyAgICBpZiAoSXNNYXBGaWVsZEluQXBpKGZpZWxkKSkgeworICAgICAgcmV0dXJuICYocmVpbnRlcnByZXRfY2FzdDxjb25zdCBNYXBGaWVsZEJhc2UqPigKKyAgICAgICAgICByZWludGVycHJldF9jYXN0PGNvbnN0IHVpbnQ4Kj4oJm1lc3NhZ2UpICsKKyAgICAgICAgICBvZmZzZXRzX1tmaWVsZC0+aW5kZXgoKV0pLT5HZXRSZXBlYXRlZEZpZWxkKCkpOworICAgIH0KKyAgICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxjb25zdCB1aW50OCo+KCZtZXNzYWdlKSArIG9mZnNldHNfW2ZpZWxkLT5pbmRleCgpXTsKKyAgfQorfQorCitjb25zdCBGaWVsZERlc2NyaXB0b3IqIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpHZXRPbmVvZkZpZWxkRGVzY3JpcHRvcigKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgIGNvbnN0IE9uZW9mRGVzY3JpcHRvciogb25lb2ZfZGVzY3JpcHRvcikgY29uc3QgeworICB1aW50MzIgZmllbGRfbnVtYmVyID0gR2V0T25lb2ZDYXNlKG1lc3NhZ2UsIG9uZW9mX2Rlc2NyaXB0b3IpOworICBpZiAoZmllbGRfbnVtYmVyID09IDApIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICByZXR1cm4gZGVzY3JpcHRvcl8tPkZpbmRGaWVsZEJ5TnVtYmVyKGZpZWxkX251bWJlcik7Cit9CisKK2Jvb2wgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OkNvbnRhaW5zTWFwS2V5KAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICBjb25zdCBNYXBLZXkmIGtleSkgY29uc3QgeworICBVU0FHRV9DSEVDSyhJc01hcEZpZWxkSW5BcGkoZmllbGQpLAorICAgICAgICAgICAgICAiTG9va3VwTWFwVmFsdWUiLAorICAgICAgICAgICAgICAiRmllbGQgaXMgbm90IGEgbWFwIGZpZWxkLiIpOworICByZXR1cm4gR2V0UmF3PE1hcEZpZWxkQmFzZT4obWVzc2FnZSwgZmllbGQpLkNvbnRhaW5zTWFwS2V5KGtleSk7Cit9CisKK2Jvb2wgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Okluc2VydE9yTG9va3VwTWFwVmFsdWUoCisgICAgTWVzc2FnZSogbWVzc2FnZSwKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgIGNvbnN0IE1hcEtleSYga2V5LAorICAgIE1hcFZhbHVlUmVmKiB2YWwpIGNvbnN0IHsKKyAgVVNBR0VfQ0hFQ0soSXNNYXBGaWVsZEluQXBpKGZpZWxkKSwKKyAgICAgICAgICAgICAgIkluc2VydE9yTG9va3VwTWFwVmFsdWUiLAorICAgICAgICAgICAgICAiRmllbGQgaXMgbm90IGEgbWFwIGZpZWxkLiIpOworICB2YWwtPlNldFR5cGUoZmllbGQtPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoInZhbHVlIiktPmNwcF90eXBlKCkpOworICByZXR1cm4gTXV0YWJsZVJhdzxNYXBGaWVsZEJhc2U+KG1lc3NhZ2UsIGZpZWxkKS0+SW5zZXJ0TWFwVmFsdWUoa2V5LCB2YWwpOworfQorCitib29sIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpEZWxldGVNYXBWYWx1ZSgKKyAgICBNZXNzYWdlKiBtZXNzYWdlLAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgY29uc3QgTWFwS2V5JiBrZXkpIGNvbnN0IHsKKyAgVVNBR0VfQ0hFQ0soSXNNYXBGaWVsZEluQXBpKGZpZWxkKSwKKyAgICAgICAgICAgICAgIkRlbGV0ZU1hcFZhbHVlIiwKKyAgICAgICAgICAgICAgIkZpZWxkIGlzIG5vdCBhIG1hcCBmaWVsZC4iKTsKKyAgcmV0dXJuIE11dGFibGVSYXc8TWFwRmllbGRCYXNlPihtZXNzYWdlLCBmaWVsZCktPkRlbGV0ZU1hcFZhbHVlKGtleSk7Cit9CisKK01hcEl0ZXJhdG9yIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpNYXBCZWdpbigKKyAgICBNZXNzYWdlKiBtZXNzYWdlLAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0IHsKKyAgVVNBR0VfQ0hFQ0soSXNNYXBGaWVsZEluQXBpKGZpZWxkKSwKKyAgICAgICAgICAgICAgIk1hcEJlZ2luIiwKKyAgICAgICAgICAgICAgIkZpZWxkIGlzIG5vdCBhIG1hcCBmaWVsZC4iKTsKKyAgTWFwSXRlcmF0b3IgaXRlcihtZXNzYWdlLCBmaWVsZCk7CisgIEdldFJhdzxNYXBGaWVsZEJhc2U+KCptZXNzYWdlLCBmaWVsZCkuTWFwQmVnaW4oJml0ZXIpOworICByZXR1cm4gaXRlcjsKK30KKworTWFwSXRlcmF0b3IgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok1hcEVuZCgKKyAgICBNZXNzYWdlKiBtZXNzYWdlLAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0IHsKKyAgVVNBR0VfQ0hFQ0soSXNNYXBGaWVsZEluQXBpKGZpZWxkKSwKKyAgICAgICAgICAgICAgIk1hcEVuZCIsCisgICAgICAgICAgICAgICJGaWVsZCBpcyBub3QgYSBtYXAgZmllbGQuIik7CisgIE1hcEl0ZXJhdG9yIGl0ZXIobWVzc2FnZSwgZmllbGQpOworICBHZXRSYXc8TWFwRmllbGRCYXNlPigqbWVzc2FnZSwgZmllbGQpLk1hcEVuZCgmaXRlcik7CisgIHJldHVybiBpdGVyOworfQorCitpbnQgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok1hcFNpemUoCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7CisgIFVTQUdFX0NIRUNLKElzTWFwRmllbGRJbkFwaShmaWVsZCksCisgICAgICAgICAgICAgICJNYXBTaXplIiwKKyAgICAgICAgICAgICAgIkZpZWxkIGlzIG5vdCBhIG1hcCBmaWVsZC4iKTsKKyAgcmV0dXJuIEdldFJhdzxNYXBGaWVsZEJhc2U+KG1lc3NhZ2UsIGZpZWxkKS5zaXplKCk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NvbnN0IEZpZWxkRGVzY3JpcHRvciogR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OkZpbmRLbm93bkV4dGVuc2lvbkJ5TmFtZSgKKyAgICBjb25zdCBzdHJpbmcmIG5hbWUpIGNvbnN0IHsKKyAgaWYgKGV4dGVuc2lvbnNfb2Zmc2V0XyA9PSAtMSkgcmV0dXJuIE5VTEw7CisKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiByZXN1bHQgPSBkZXNjcmlwdG9yX3Bvb2xfLT5GaW5kRXh0ZW5zaW9uQnlOYW1lKG5hbWUpOworICBpZiAocmVzdWx0ICE9IE5VTEwgJiYgcmVzdWx0LT5jb250YWluaW5nX3R5cGUoKSA9PSBkZXNjcmlwdG9yXykgeworICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworICBpZiAoZGVzY3JpcHRvcl8tPm9wdGlvbnMoKS5tZXNzYWdlX3NldF93aXJlX2Zvcm1hdCgpKSB7CisgICAgLy8gTWVzc2FnZVNldCBleHRlbnNpb25zIG1heSBiZSBpZGVudGlmaWVkIGJ5IHR5cGUgbmFtZS4KKyAgICBjb25zdCBEZXNjcmlwdG9yKiB0eXBlID0gZGVzY3JpcHRvcl9wb29sXy0+RmluZE1lc3NhZ2VUeXBlQnlOYW1lKG5hbWUpOworICAgIGlmICh0eXBlICE9IE5VTEwpIHsKKyAgICAgIC8vIExvb2sgZm9yIGEgbWF0Y2hpbmcgZXh0ZW5zaW9uIGluIHRoZSBmb3JlaWduIHR5cGUncyBzY29wZS4KKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdHlwZS0+ZXh0ZW5zaW9uX2NvdW50KCk7IGkrKykgeworICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGV4dGVuc2lvbiA9IHR5cGUtPmV4dGVuc2lvbihpKTsKKyAgICAgICAgaWYgKGV4dGVuc2lvbi0+Y29udGFpbmluZ190eXBlKCkgPT0gZGVzY3JpcHRvcl8gJiYKKyAgICAgICAgICAgIGV4dGVuc2lvbi0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9NRVNTQUdFICYmCisgICAgICAgICAgICBleHRlbnNpb24tPmlzX29wdGlvbmFsKCkgJiYKKyAgICAgICAgICAgIGV4dGVuc2lvbi0+bWVzc2FnZV90eXBlKCkgPT0gdHlwZSkgeworICAgICAgICAgIC8vIEZvdW5kIGl0LgorICAgICAgICAgIHJldHVybiBleHRlbnNpb247CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgIH0KKworICByZXR1cm4gTlVMTDsKK30KKworY29uc3QgRmllbGREZXNjcmlwdG9yKiBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6RmluZEtub3duRXh0ZW5zaW9uQnlOdW1iZXIoCisgICAgaW50IG51bWJlcikgY29uc3QgeworICBpZiAoZXh0ZW5zaW9uc19vZmZzZXRfID09IC0xKSByZXR1cm4gTlVMTDsKKyAgcmV0dXJuIGRlc2NyaXB0b3JfcG9vbF8tPkZpbmRFeHRlbnNpb25CeU51bWJlcihkZXNjcmlwdG9yXywgbnVtYmVyKTsKK30KKworYm9vbCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6U3VwcG9ydHNVbmtub3duRW51bVZhbHVlcygpIGNvbnN0IHsKKyAgcmV0dXJuIENyZWF0ZVVua25vd25FbnVtVmFsdWVzKGRlc2NyaXB0b3JfLT5maWxlKCkpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisvLyBTb21lIHByaXZhdGUgaGVscGVycy4KKworLy8gVGhlc2Ugc2ltcGxlIHRlbXBsYXRlIGFjY2Vzc29ycyBvYnRhaW4gcG9pbnRlcnMgKG9yIHJlZmVyZW5jZXMpIHRvCisvLyB0aGUgZ2l2ZW4gZmllbGQuCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4KK2lubGluZSBjb25zdCBUeXBlJiBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6R2V0UmF3KAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0IHsKKyAgaWYgKGZpZWxkLT5jb250YWluaW5nX29uZW9mKCkgJiYgIUhhc09uZW9mRmllbGQobWVzc2FnZSwgZmllbGQpKSB7CisgICAgcmV0dXJuIERlZmF1bHRSYXc8VHlwZT4oZmllbGQpOworICB9CisgIGludCBpbmRleCA9IGZpZWxkLT5jb250YWluaW5nX29uZW9mKCkgPworICAgICAgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCkgKyBmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpLT5pbmRleCgpIDoKKyAgICAgIGZpZWxkLT5pbmRleCgpOworICBjb25zdCB2b2lkKiBwdHIgPSByZWludGVycHJldF9jYXN0PGNvbnN0IHVpbnQ4Kj4oJm1lc3NhZ2UpICsKKyAgICAgIG9mZnNldHNfW2luZGV4XTsKKyAgcmV0dXJuICpyZWludGVycHJldF9jYXN0PGNvbnN0IFR5cGUqPihwdHIpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4KK2lubGluZSBUeXBlKiBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6TXV0YWJsZVJhdygKKyAgICBNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7CisgIGludCBpbmRleCA9IGZpZWxkLT5jb250YWluaW5nX29uZW9mKCkgPworICAgICAgZGVzY3JpcHRvcl8tPmZpZWxkX2NvdW50KCkgKyBmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpLT5pbmRleCgpIDoKKyAgICAgIGZpZWxkLT5pbmRleCgpOworICB2b2lkKiBwdHIgPSByZWludGVycHJldF9jYXN0PHVpbnQ4Kj4obWVzc2FnZSkgKyBvZmZzZXRzX1tpbmRleF07CisgIHJldHVybiByZWludGVycHJldF9jYXN0PFR5cGUqPihwdHIpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4KK2lubGluZSBjb25zdCBUeXBlJiBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6RGVmYXVsdFJhdygKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7CisgIGNvbnN0IHZvaWQqIHB0ciA9IGZpZWxkLT5jb250YWluaW5nX29uZW9mKCkgPworICAgICAgcmVpbnRlcnByZXRfY2FzdDxjb25zdCB1aW50OCo+KGRlZmF1bHRfb25lb2ZfaW5zdGFuY2VfKSArCisgICAgICBvZmZzZXRzX1tmaWVsZC0+aW5kZXgoKV0gOgorICAgICAgcmVpbnRlcnByZXRfY2FzdDxjb25zdCB1aW50OCo+KGRlZmF1bHRfaW5zdGFuY2VfKSArCisgICAgICBvZmZzZXRzX1tmaWVsZC0+aW5kZXgoKV07CisgIHJldHVybiAqcmVpbnRlcnByZXRfY2FzdDxjb25zdCBUeXBlKj4ocHRyKTsKK30KKworaW5saW5lIGNvbnN0IHVpbnQzMiogR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OkdldEhhc0JpdHMoCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSkgY29uc3QgeworICBpZiAoaGFzX2JpdHNfb2Zmc2V0XyA9PSAtMSkgeyAgLy8gcHJvdG8zIHdpdGggbm8gaGFzLWJpdHMuCisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgY29uc3Qgdm9pZCogcHRyID0gcmVpbnRlcnByZXRfY2FzdDxjb25zdCB1aW50OCo+KCZtZXNzYWdlKSArIGhhc19iaXRzX29mZnNldF87CisgIHJldHVybiByZWludGVycHJldF9jYXN0PGNvbnN0IHVpbnQzMio+KHB0cik7Cit9CitpbmxpbmUgdWludDMyKiBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6TXV0YWJsZUhhc0JpdHMoCisgICAgTWVzc2FnZSogbWVzc2FnZSkgY29uc3QgeworICBpZiAoaGFzX2JpdHNfb2Zmc2V0XyA9PSAtMSkgeworICAgIHJldHVybiBOVUxMOworICB9CisgIHZvaWQqIHB0ciA9IHJlaW50ZXJwcmV0X2Nhc3Q8dWludDgqPihtZXNzYWdlKSArIGhhc19iaXRzX29mZnNldF87CisgIHJldHVybiByZWludGVycHJldF9jYXN0PHVpbnQzMio+KHB0cik7Cit9CisKK2lubGluZSB1aW50MzIgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OkdldE9uZW9mQ2FzZSgKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgIGNvbnN0IE9uZW9mRGVzY3JpcHRvciogb25lb2ZfZGVzY3JpcHRvcikgY29uc3QgeworICBjb25zdCB2b2lkKiBwdHIgPSByZWludGVycHJldF9jYXN0PGNvbnN0IHVpbnQ4Kj4oJm1lc3NhZ2UpCisgICAgICArIG9uZW9mX2Nhc2Vfb2Zmc2V0XzsKKyAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgdWludDMyKj4ocHRyKVtvbmVvZl9kZXNjcmlwdG9yLT5pbmRleCgpXTsKK30KKworaW5saW5lIHVpbnQzMiogR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok11dGFibGVPbmVvZkNhc2UoCisgICAgTWVzc2FnZSogbWVzc2FnZSwKKyAgICBjb25zdCBPbmVvZkRlc2NyaXB0b3IqIG9uZW9mX2Rlc2NyaXB0b3IpIGNvbnN0IHsKKyAgdm9pZCogcHRyID0gcmVpbnRlcnByZXRfY2FzdDx1aW50OCo+KG1lc3NhZ2UpICsgb25lb2ZfY2FzZV9vZmZzZXRfOworICByZXR1cm4gJihyZWludGVycHJldF9jYXN0PHVpbnQzMio+KHB0cilbb25lb2ZfZGVzY3JpcHRvci0+aW5kZXgoKV0pOworfQorCitpbmxpbmUgY29uc3QgRXh0ZW5zaW9uU2V0JiBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6R2V0RXh0ZW5zaW9uU2V0KAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UpIGNvbnN0IHsKKyAgR09PR0xFX0RDSEVDS19ORShleHRlbnNpb25zX29mZnNldF8sIC0xKTsKKyAgY29uc3Qgdm9pZCogcHRyID0gcmVpbnRlcnByZXRfY2FzdDxjb25zdCB1aW50OCo+KCZtZXNzYWdlKSArCisgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbnNfb2Zmc2V0XzsKKyAgcmV0dXJuICpyZWludGVycHJldF9jYXN0PGNvbnN0IEV4dGVuc2lvblNldCo+KHB0cik7Cit9CitpbmxpbmUgRXh0ZW5zaW9uU2V0KiBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6TXV0YWJsZUV4dGVuc2lvblNldCgKKyAgICBNZXNzYWdlKiBtZXNzYWdlKSBjb25zdCB7CisgIEdPT0dMRV9EQ0hFQ0tfTkUoZXh0ZW5zaW9uc19vZmZzZXRfLCAtMSk7CisgIHZvaWQqIHB0ciA9IHJlaW50ZXJwcmV0X2Nhc3Q8dWludDgqPihtZXNzYWdlKSArIGV4dGVuc2lvbnNfb2Zmc2V0XzsKKyAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8RXh0ZW5zaW9uU2V0Kj4ocHRyKTsKK30KKworaW5saW5lIEFyZW5hKiBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6R2V0QXJlbmEoTWVzc2FnZSogbWVzc2FnZSkgY29uc3QgeworICBpZiAoYXJlbmFfb2Zmc2V0XyA9PSBrTm9BcmVuYVBvaW50ZXIpIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorCisgIGlmICh1bmtub3duX2ZpZWxkc19vZmZzZXRfID09IGtVbmtub3duRmllbGRTZXRJbk1ldGFkYXRhKSB7CisgICAgLy8gemVyby1vdmVyaGVhZCBhcmVuYSBwb2ludGVyIG92ZXJsb2FkaW5nIFVua25vd25GaWVsZHMKKyAgICByZXR1cm4gR2V0SW50ZXJuYWxNZXRhZGF0YVdpdGhBcmVuYSgqbWVzc2FnZSkuYXJlbmEoKTsKKyAgfQorCisgIC8vIEJhc2VsaW5lIGNhc2U6IG1lc3NhZ2UgY2xhc3MgaGFzIGEgZGVkaWNhdGVkIGFyZW5hIHBvaW50ZXIuCisgIHZvaWQqIHB0ciA9IHJlaW50ZXJwcmV0X2Nhc3Q8dWludDgqPihtZXNzYWdlKSArIGFyZW5hX29mZnNldF87CisgIHJldHVybiAqcmVpbnRlcnByZXRfY2FzdDxBcmVuYSoqPihwdHIpOworfQorCitpbmxpbmUgY29uc3QgSW50ZXJuYWxNZXRhZGF0YVdpdGhBcmVuYSYKK0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpHZXRJbnRlcm5hbE1ldGFkYXRhV2l0aEFyZW5hKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UpIGNvbnN0IHsKKyAgY29uc3Qgdm9pZCogcHRyID0gcmVpbnRlcnByZXRfY2FzdDxjb25zdCB1aW50OCo+KCZtZXNzYWdlKSArIGFyZW5hX29mZnNldF87CisgIHJldHVybiAqcmVpbnRlcnByZXRfY2FzdDxjb25zdCBJbnRlcm5hbE1ldGFkYXRhV2l0aEFyZW5hKj4ocHRyKTsKK30KKworaW5saW5lIEludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEqCitHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6TXV0YWJsZUludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEoCisgICAgTWVzc2FnZSogbWVzc2FnZSkgY29uc3QgeworICB2b2lkKiBwdHIgPSByZWludGVycHJldF9jYXN0PHVpbnQ4Kj4obWVzc2FnZSkgKyBhcmVuYV9vZmZzZXRfOworICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxJbnRlcm5hbE1ldGFkYXRhV2l0aEFyZW5hKj4ocHRyKTsKK30KKworaW5saW5lIGJvb2wKK0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpHZXRJc0RlZmF1bHRJbnN0YW5jZSgKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlKSBjb25zdCB7CisgIGlmIChpc19kZWZhdWx0X2luc3RhbmNlX29mZnNldF8gPT0ga0hhc05vRGVmYXVsdEluc3RhbmNlRmllbGQpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgY29uc3Qgdm9pZCogcHRyID0gcmVpbnRlcnByZXRfY2FzdDxjb25zdCB1aW50OCo+KCZtZXNzYWdlKSArCisgICAgICBpc19kZWZhdWx0X2luc3RhbmNlX29mZnNldF87CisgIHJldHVybiAqcmVpbnRlcnByZXRfY2FzdDxjb25zdCBib29sKj4ocHRyKTsKK30KKworLy8gU2ltcGxlIGFjY2Vzc29ycyBmb3IgbWFuaXB1bGF0aW5nIGhhc19iaXRzXy4KK2lubGluZSBib29sIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpIYXNCaXQoCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3QgeworICBpZiAoaGFzX2JpdHNfb2Zmc2V0XyA9PSAtMSkgeworICAgIC8vIHByb3RvMzogbm8gaGFzLWJpdHMuIEFsbCBmaWVsZHMgcHJlc2VudCBleGNlcHQgbWVzc2FnZXMsIHdoaWNoIGFyZQorICAgIC8vIHByZXNlbnQgb25seSBpZiB0aGVpciBtZXNzYWdlLWZpZWxkIHBvaW50ZXIgaXMgbm9uLU5VTEwuCisgICAgaWYgKGZpZWxkLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFKSB7CisgICAgICByZXR1cm4gIUdldElzRGVmYXVsdEluc3RhbmNlKG1lc3NhZ2UpICYmCisgICAgICAgICAgR2V0UmF3PGNvbnN0IE1lc3NhZ2UqPihtZXNzYWdlLCBmaWVsZCkgIT0gTlVMTDsKKyAgICB9IGVsc2UgeworICAgICAgLy8gTm9uLW1lc3NhZ2UgZmllbGQgKGFuZCBub24tb25lb2YsIHNpbmNlIHRoYXQgd2FzIGhhbmRsZWQgaW4gSGFzRmllbGQoKQorICAgICAgLy8gYmVmb3JlIGNhbGxpbmcgdXMpLCBhbmQgc2luZ3VsYXIgKGFnYWluLCBjaGVja2VkIGluIEhhc0ZpZWxkKS4gU28sIHRoaXMKKyAgICAgIC8vIGZpZWxkIG11c3QgYmUgYSBzY2FsYXIuCisKKyAgICAgIC8vIFNjYWxhciBwcmltaXRpdmUgKG51bWVyaWMgb3Igc3RyaW5nL2J5dGVzKSBmaWVsZHMgYXJlIHByZXNlbnQgaWYKKyAgICAgIC8vIHRoZWlyIHZhbHVlIGlzIG5vbi16ZXJvIChudW1lcmljKSBvciBub24tZW1wdHkgKHN0cmluZy9ieXRlcykuICBOLkIuOgorICAgICAgLy8gd2UgbXVzdCB1c2UgdGhpcyBkZWZpbml0aW9uIGhlcmUsIHJhdGhlciB0aGFuIHRoZSAic2NhbGFyIGZpZWxkcworICAgICAgLy8gYWx3YXlzIHByZXNlbnQiIGluIHRoZSBwcm90bzMgZG9jcywgYmVjYXVzZSBNZXJnZUZyb20oKSBzZW1hbnRpY3MKKyAgICAgIC8vIHJlcXVpcmUgcHJlc2VuY2UgYXMgInByZXNlbnQgb24gd2lyZSIsIGFuZCByZWZsZWN0aW9uLWJhc2VkIG1lcmdlCisgICAgICAvLyAod2hpY2ggdXNlcyBIYXNGaWVsZCgpKSBuZWVkcyB0byBiZSBjb25zaXN0ZW50IHdpdGggdGhpcy4KKyAgICAgIHN3aXRjaCAoZmllbGQtPmNwcF90eXBlKCkpIHsKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HOgorICAgICAgICAgIHN3aXRjaCAoZmllbGQtPm9wdGlvbnMoKS5jdHlwZSgpKSB7CisgICAgICAgICAgICBkZWZhdWx0OiB7CisgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyogZGVmYXVsdF9wdHIgPQorICAgICAgICAgICAgICAgICAgJkRlZmF1bHRSYXc8QXJlbmFTdHJpbmdQdHI+KGZpZWxkKS5HZXQoTlVMTCk7CisgICAgICAgICAgICAgIHJldHVybiBHZXRGaWVsZDxBcmVuYVN0cmluZ1B0cj4obWVzc2FnZSwgZmllbGQpLkdldCgKKyAgICAgICAgICAgICAgICAgIGRlZmF1bHRfcHRyKS5zaXplKCkgPiAwOworICAgICAgICAgICAgfQorICAgICAgICAgIH0KKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0JPT0w6CisgICAgICAgICAgcmV0dXJuIEdldFJhdzxib29sPihtZXNzYWdlLCBmaWVsZCkgIT0gZmFsc2U7CisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0lOVDMyOgorICAgICAgICAgIHJldHVybiBHZXRSYXc8aW50MzI+KG1lc3NhZ2UsIGZpZWxkKSAhPSAwOworICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9JTlQ2NDoKKyAgICAgICAgICByZXR1cm4gR2V0UmF3PGludDY0PihtZXNzYWdlLCBmaWVsZCkgIT0gMDsKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDMyOgorICAgICAgICAgIHJldHVybiBHZXRSYXc8dWludDMyPihtZXNzYWdlLCBmaWVsZCkgIT0gMDsKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDY0OgorICAgICAgICAgIHJldHVybiBHZXRSYXc8dWludDY0PihtZXNzYWdlLCBmaWVsZCkgIT0gMDsKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRkxPQVQ6CisgICAgICAgICAgcmV0dXJuIEdldFJhdzxmbG9hdD4obWVzc2FnZSwgZmllbGQpICE9IDAuMDsKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRE9VQkxFOgorICAgICAgICAgIHJldHVybiBHZXRSYXc8ZG91YmxlPihtZXNzYWdlLCBmaWVsZCkgIT0gMC4wOworICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9FTlVNOgorICAgICAgICAgIHJldHVybiBHZXRSYXc8aW50PihtZXNzYWdlLCBmaWVsZCkgIT0gMDsKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRToKKyAgICAgICAgICAvLyBoYW5kbGVkIGFib3ZlOyBhdm9pZCB3YXJuaW5nCisgICAgICAgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIlJlYWNoZWQgaW1wb3NzaWJsZSBjYXNlIGluIEhhc0JpdCgpLiI7CisgICAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CisgIHJldHVybiBHZXRIYXNCaXRzKG1lc3NhZ2UpW2ZpZWxkLT5pbmRleCgpIC8gMzJdICYKKyAgICAoMSA8PCAoZmllbGQtPmluZGV4KCkgJSAzMikpOworfQorCitpbmxpbmUgdm9pZCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6U2V0Qml0KAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0IHsKKyAgaWYgKGhhc19iaXRzX29mZnNldF8gPT0gLTEpIHsKKyAgICByZXR1cm47CisgIH0KKyAgTXV0YWJsZUhhc0JpdHMobWVzc2FnZSlbZmllbGQtPmluZGV4KCkgLyAzMl0gfD0gKDEgPDwgKGZpZWxkLT5pbmRleCgpICUgMzIpKTsKK30KKworaW5saW5lIHZvaWQgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OkNsZWFyQml0KAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0IHsKKyAgaWYgKGhhc19iaXRzX29mZnNldF8gPT0gLTEpIHsKKyAgICByZXR1cm47CisgIH0KKyAgTXV0YWJsZUhhc0JpdHMobWVzc2FnZSlbZmllbGQtPmluZGV4KCkgLyAzMl0gJj0gfigxIDw8IChmaWVsZC0+aW5kZXgoKSAlIDMyKSk7Cit9CisKK2lubGluZSB2b2lkIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpTd2FwQml0KAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UxLCBNZXNzYWdlKiBtZXNzYWdlMiwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3QgeworICBpZiAoaGFzX2JpdHNfb2Zmc2V0XyA9PSAtMSkgeworICAgIHJldHVybjsKKyAgfQorICBib29sIHRlbXBfaGFzX2JpdCA9IEhhc0JpdCgqbWVzc2FnZTEsIGZpZWxkKTsKKyAgaWYgKEhhc0JpdCgqbWVzc2FnZTIsIGZpZWxkKSkgeworICAgIFNldEJpdChtZXNzYWdlMSwgZmllbGQpOworICB9IGVsc2UgeworICAgIENsZWFyQml0KG1lc3NhZ2UxLCBmaWVsZCk7CisgIH0KKyAgaWYgKHRlbXBfaGFzX2JpdCkgeworICAgIFNldEJpdChtZXNzYWdlMiwgZmllbGQpOworICB9IGVsc2UgeworICAgIENsZWFyQml0KG1lc3NhZ2UyLCBmaWVsZCk7CisgIH0KK30KKworaW5saW5lIGJvb2wgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Okhhc09uZW9mKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsIGNvbnN0IE9uZW9mRGVzY3JpcHRvciogb25lb2ZfZGVzY3JpcHRvcikgY29uc3QgeworICByZXR1cm4gKEdldE9uZW9mQ2FzZShtZXNzYWdlLCBvbmVvZl9kZXNjcmlwdG9yKSA+IDApOworfQorCitpbmxpbmUgYm9vbCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6SGFzT25lb2ZGaWVsZCgKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7CisgIHJldHVybiAoR2V0T25lb2ZDYXNlKG1lc3NhZ2UsIGZpZWxkLT5jb250YWluaW5nX29uZW9mKCkpID09IGZpZWxkLT5udW1iZXIoKSk7Cit9CisKK2lubGluZSB2b2lkIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpTZXRPbmVvZkNhc2UoCisgICAgTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3QgeworICAqTXV0YWJsZU9uZW9mQ2FzZShtZXNzYWdlLCBmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpKSA9IGZpZWxkLT5udW1iZXIoKTsKK30KKworaW5saW5lIHZvaWQgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OkNsZWFyT25lb2ZGaWVsZCgKKyAgICBNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7CisgIGlmIChIYXNPbmVvZkZpZWxkKCptZXNzYWdlLCBmaWVsZCkpIHsKKyAgICBDbGVhck9uZW9mKG1lc3NhZ2UsIGZpZWxkLT5jb250YWluaW5nX29uZW9mKCkpOworICB9Cit9CisKK2lubGluZSB2b2lkIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpDbGVhck9uZW9mKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IE9uZW9mRGVzY3JpcHRvciogb25lb2ZfZGVzY3JpcHRvcikgY29uc3QgeworICAvLyBUT0RPKGppZWx1byk6IENvbnNpZGVyIHRvIGNhY2hlIHRoZSB1bnVzZWQgb2JqZWN0IGluc3RlYWQgb2YgZGVsZXRpbmcKKyAgLy8gaXQuIEl0IHdpbGwgYmUgbXVjaCBmYXN0ZXIgaWYgYW4gYXBsaWNhdGlvbiBzd2l0Y2hlcyBhIGxvdCBmcm9tCisgIC8vIGEgZmV3IG9uZW9mIGZpZWxkcy4gIFRpbWUvc3BhY2UgdHJhZGVvZmYKKyAgdWludDMyIG9uZW9mX2Nhc2UgPSBHZXRPbmVvZkNhc2UoKm1lc3NhZ2UsIG9uZW9mX2Rlc2NyaXB0b3IpOworICBpZiAob25lb2ZfY2FzZSA+IDApIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvcl8tPkZpbmRGaWVsZEJ5TnVtYmVyKG9uZW9mX2Nhc2UpOworICAgIGlmIChHZXRBcmVuYShtZXNzYWdlKSA9PSBOVUxMKSB7CisgICAgICBzd2l0Y2ggKGZpZWxkLT5jcHBfdHlwZSgpKSB7CisgICAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORzogeworICAgICAgICAgIHN3aXRjaCAoZmllbGQtPm9wdGlvbnMoKS5jdHlwZSgpKSB7CisgICAgICAgICAgICBkZWZhdWx0OiAgLy8gVE9ETyhrZW50b24pOiAgU3VwcG9ydCBvdGhlciBzdHJpbmcgcmVwcy4KKyAgICAgICAgICAgIGNhc2UgRmllbGRPcHRpb25zOjpTVFJJTkc6IHsKKyAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nKiBkZWZhdWx0X3B0ciA9CisgICAgICAgICAgICAgICAgICAmRGVmYXVsdFJhdzxBcmVuYVN0cmluZ1B0cj4oZmllbGQpLkdldChOVUxMKTsKKyAgICAgICAgICAgICAgTXV0YWJsZUZpZWxkPEFyZW5hU3RyaW5nUHRyPihtZXNzYWdlLCBmaWVsZCktPgorICAgICAgICAgICAgICAgICAgRGVzdHJveShkZWZhdWx0X3B0ciwgR2V0QXJlbmEobWVzc2FnZSkpOworICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKworICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgICAgIGRlbGV0ZSAqTXV0YWJsZVJhdzxNZXNzYWdlKj4obWVzc2FnZSwgZmllbGQpOworICAgICAgICAgIGJyZWFrOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKworICAgICpNdXRhYmxlT25lb2ZDYXNlKG1lc3NhZ2UsIG9uZW9mX2Rlc2NyaXB0b3IpID0gMDsKKyAgfQorfQorCisvLyBUZW1wbGF0ZSBpbXBsZW1lbnRhdGlvbnMgb2YgYmFzaWMgYWNjZXNzb3JzLiAgSW5saW5lIGJlY2F1c2UgZWFjaAorLy8gdGVtcGxhdGUgaW5zdGFuY2UgaXMgb25seSBjYWxsZWQgZnJvbSBvbmUgbG9jYXRpb24uICBUaGVzZSBhcmUKKy8vIHVzZWQgZm9yIGFsbCB0eXBlcyBleGNlcHQgbWVzc2FnZXMuCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4KK2lubGluZSBjb25zdCBUeXBlJiBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6R2V0RmllbGQoCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3QgeworICByZXR1cm4gR2V0UmF3PFR5cGU+KG1lc3NhZ2UsIGZpZWxkKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+CitpbmxpbmUgdm9pZCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6U2V0RmllbGQoCisgICAgTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgY29uc3QgVHlwZSYgdmFsdWUpIGNvbnN0IHsKKyAgaWYgKGZpZWxkLT5jb250YWluaW5nX29uZW9mKCkgJiYgIUhhc09uZW9mRmllbGQoKm1lc3NhZ2UsIGZpZWxkKSkgeworICAgIENsZWFyT25lb2YobWVzc2FnZSwgZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSk7CisgIH0KKyAgKk11dGFibGVSYXc8VHlwZT4obWVzc2FnZSwgZmllbGQpID0gdmFsdWU7CisgIGZpZWxkLT5jb250YWluaW5nX29uZW9mKCkgPworICAgICAgU2V0T25lb2ZDYXNlKG1lc3NhZ2UsIGZpZWxkKSA6IFNldEJpdChtZXNzYWdlLCBmaWVsZCk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBUeXBlPgoraW5saW5lIFR5cGUqIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpNdXRhYmxlRmllbGQoCisgICAgTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3QgeworICBmaWVsZC0+Y29udGFpbmluZ19vbmVvZigpID8KKyAgICAgIFNldE9uZW9mQ2FzZShtZXNzYWdlLCBmaWVsZCkgOiBTZXRCaXQobWVzc2FnZSwgZmllbGQpOworICByZXR1cm4gTXV0YWJsZVJhdzxUeXBlPihtZXNzYWdlLCBmaWVsZCk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBUeXBlPgoraW5saW5lIGNvbnN0IFR5cGUmIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpHZXRSZXBlYXRlZEZpZWxkKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGludCBpbmRleCkgY29uc3QgeworICByZXR1cm4gR2V0UmF3PFJlcGVhdGVkRmllbGQ8VHlwZT4gPihtZXNzYWdlLCBmaWVsZCkuR2V0KGluZGV4KTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+CitpbmxpbmUgY29uc3QgVHlwZSYgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OkdldFJlcGVhdGVkUHRyRmllbGQoCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50IGluZGV4KSBjb25zdCB7CisgIHJldHVybiBHZXRSYXc8UmVwZWF0ZWRQdHJGaWVsZDxUeXBlPiA+KG1lc3NhZ2UsIGZpZWxkKS5HZXQoaW5kZXgpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4KK2lubGluZSB2b2lkIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpTZXRSZXBlYXRlZEZpZWxkKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgaW50IGluZGV4LCBUeXBlIHZhbHVlKSBjb25zdCB7CisgIE11dGFibGVSYXc8UmVwZWF0ZWRGaWVsZDxUeXBlPiA+KG1lc3NhZ2UsIGZpZWxkKS0+U2V0KGluZGV4LCB2YWx1ZSk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBUeXBlPgoraW5saW5lIFR5cGUqIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpNdXRhYmxlUmVwZWF0ZWRGaWVsZCgKKyAgICBNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBpbnQgaW5kZXgpIGNvbnN0IHsKKyAgUmVwZWF0ZWRQdHJGaWVsZDxUeXBlPiogcmVwZWF0ZWQgPQorICAgIE11dGFibGVSYXc8UmVwZWF0ZWRQdHJGaWVsZDxUeXBlPiA+KG1lc3NhZ2UsIGZpZWxkKTsKKyAgcmV0dXJuIHJlcGVhdGVkLT5NdXRhYmxlKGluZGV4KTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+CitpbmxpbmUgdm9pZCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6QWRkRmllbGQoCisgICAgTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgY29uc3QgVHlwZSYgdmFsdWUpIGNvbnN0IHsKKyAgTXV0YWJsZVJhdzxSZXBlYXRlZEZpZWxkPFR5cGU+ID4obWVzc2FnZSwgZmllbGQpLT5BZGQodmFsdWUpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4KK2lubGluZSBUeXBlKiBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6QWRkRmllbGQoCisgICAgTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3QgeworICBSZXBlYXRlZFB0ckZpZWxkPFR5cGU+KiByZXBlYXRlZCA9CisgICAgTXV0YWJsZVJhdzxSZXBlYXRlZFB0ckZpZWxkPFR5cGU+ID4obWVzc2FnZSwgZmllbGQpOworICByZXR1cm4gcmVwZWF0ZWQtPkFkZCgpOworfQorCitNZXNzYWdlRmFjdG9yeSogR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OkdldE1lc3NhZ2VGYWN0b3J5KCkgY29uc3QgeworICByZXR1cm4gbWVzc2FnZV9mYWN0b3J5XzsKK30KKwordm9pZCogR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246OlJlcGVhdGVkRmllbGREYXRhKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgRmllbGREZXNjcmlwdG9yOjpDcHBUeXBlIGNwcF90eXBlLAorICAgIGNvbnN0IERlc2NyaXB0b3IqIG1lc3NhZ2VfdHlwZSkgY29uc3QgeworICBHT09HTEVfQ0hFQ0soZmllbGQtPmlzX3JlcGVhdGVkKCkpOworICBHT09HTEVfQ0hFQ0soZmllbGQtPmNwcF90eXBlKCkgPT0gY3BwX3R5cGUgfHwKKyAgICAgICAgKGZpZWxkLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9FTlVNICYmCisgICAgICAgICBjcHBfdHlwZSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UMzIpKQorICAgICAgPDwgIlRoZSB0eXBlIHBhcmFtZXRlciBUIGluIFJlcGVhdGVkRmllbGRSZWY8VD4gQVBJIGRvZXNuJ3QgbWF0Y2ggIgorICAgICAgPDwgInRoZSBhY3R1YWwgZmllbGQgdHlwZSAoZm9yIGVudW1zIFQgc2hvdWxkIGJlIHRoZSBnZW5lcmF0ZWQgZW51bSAiCisgICAgICA8PCAidHlwZSBvciBpbnQzMikuIjsKKyAgaWYgKG1lc3NhZ2VfdHlwZSAhPSBOVUxMKSB7CisgICAgR09PR0xFX0NIRUNLX0VRKG1lc3NhZ2VfdHlwZSwgZmllbGQtPm1lc3NhZ2VfdHlwZSgpKTsKKyAgfQorICBpZiAoZmllbGQtPmlzX2V4dGVuc2lvbigpKSB7CisgICAgcmV0dXJuIE11dGFibGVFeHRlbnNpb25TZXQobWVzc2FnZSktPk11dGFibGVSYXdSZXBlYXRlZEZpZWxkKAorICAgICAgICBmaWVsZC0+bnVtYmVyKCksIGZpZWxkLT50eXBlKCksIGZpZWxkLT5pc19wYWNrZWQoKSwgZmllbGQpOworICB9IGVsc2UgeworICAgIHJldHVybiByZWludGVycHJldF9jYXN0PHVpbnQ4Kj4obWVzc2FnZSkgKyBvZmZzZXRzX1tmaWVsZC0+aW5kZXgoKV07CisgIH0KK30KKworTWFwRmllbGRCYXNlKiBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6TWFwRGF0YSgKKyAgICBNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7CisgIFVTQUdFX0NIRUNLKElzTWFwRmllbGRJbkFwaShmaWVsZCksCisgICAgICAgICAgICAgICJHZXRNYXBEYXRhIiwKKyAgICAgICAgICAgICAgIkZpZWxkIGlzIG5vdCBhIG1hcCBmaWVsZC4iKTsKKyAgcmV0dXJuIE11dGFibGVSYXc8TWFwRmllbGRCYXNlPihtZXNzYWdlLCBmaWVsZCk7Cit9CisKK0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKgorR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok5ld0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKAorICAgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgY29uc3QgTWVzc2FnZSogZGVmYXVsdF9pbnN0YW5jZSwKKyAgICBjb25zdCBpbnQgb2Zmc2V0c1tdLAorICAgIGludCBoYXNfYml0c19vZmZzZXQsCisgICAgaW50IHVua25vd25fZmllbGRzX29mZnNldCwKKyAgICBpbnQgZXh0ZW5zaW9uc19vZmZzZXQsCisgICAgY29uc3Qgdm9pZCogZGVmYXVsdF9vbmVvZl9pbnN0YW5jZSwKKyAgICBpbnQgb25lb2ZfY2FzZV9vZmZzZXQsCisgICAgaW50IG9iamVjdF9zaXplLAorICAgIGludCBhcmVuYV9vZmZzZXQsCisgICAgaW50IGlzX2RlZmF1bHRfaW5zdGFuY2Vfb2Zmc2V0KSB7CisgIHJldHVybiBuZXcgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24oZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0X2luc3RhbmNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFzX2JpdHNfb2Zmc2V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVua25vd25fZmllbGRzX29mZnNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25zX29mZnNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0X29uZW9mX2luc3RhbmNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uZW9mX2Nhc2Vfb2Zmc2V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlc2NyaXB0b3JQb29sOjpnZW5lcmF0ZWRfcG9vbCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VGYWN0b3J5OjpnZW5lcmF0ZWRfZmFjdG9yeSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdF9zaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZW5hX29mZnNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc19kZWZhdWx0X2luc3RhbmNlX29mZnNldCk7Cit9CisKK0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKgorR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok5ld0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKAorICAgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgY29uc3QgTWVzc2FnZSogZGVmYXVsdF9pbnN0YW5jZSwKKyAgICBjb25zdCBpbnQgb2Zmc2V0c1tdLAorICAgIGludCBoYXNfYml0c19vZmZzZXQsCisgICAgaW50IHVua25vd25fZmllbGRzX29mZnNldCwKKyAgICBpbnQgZXh0ZW5zaW9uc19vZmZzZXQsCisgICAgaW50IG9iamVjdF9zaXplLAorICAgIGludCBhcmVuYV9vZmZzZXQsCisgICAgaW50IGlzX2RlZmF1bHRfaW5zdGFuY2Vfb2Zmc2V0KSB7CisgIHJldHVybiBuZXcgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24oZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0X2luc3RhbmNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFzX2JpdHNfb2Zmc2V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVua25vd25fZmllbGRzX29mZnNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25zX29mZnNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZXNjcmlwdG9yUG9vbDo6Z2VuZXJhdGVkX3Bvb2woKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlRmFjdG9yeTo6Z2VuZXJhdGVkX2ZhY3RvcnkoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3Rfc2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmVuYV9vZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNfZGVmYXVsdF9pbnN0YW5jZV9vZmZzZXQpOworfQorCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfbWVzc2FnZV9yZWZsZWN0aW9uLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9tZXNzYWdlX3JlZmxlY3Rpb24uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ZWY3ODcxCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfbWVzc2FnZV9yZWZsZWN0aW9uLmgKQEAgLTAsMCArMSw2NzMgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBUaGlzIGhlYWRlciBpcyBsb2dpY2FsbHkgaW50ZXJuYWwsIGJ1dCBpcyBtYWRlIHB1YmxpYyBiZWNhdXNlIGl0IGlzIHVzZWQKKy8vIGZyb20gcHJvdG9jb2wtY29tcGlsZXItZ2VuZXJhdGVkIGNvZGUsIHdoaWNoIG1heSByZXNpZGUgaW4gb3RoZXIgY29tcG9uZW50cy4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfUkVGTEVDVElPTl9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX1JFRkxFQ1RJT05fSF9fCisKKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8dmVjdG9yPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jYXN0cy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKy8vIFRPRE8oamFzb25oKTogUmVtb3ZlIHRoaXMgb25jZSB0aGUgY29tcGlsZXIgY2hhbmdlIHRvIGRpcmVjdGx5IGluY2x1ZGUgdGhpcworLy8gaXMgcmVsZWFzZWQgdG8gY29tcG9uZW50cy4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX2VudW1fcmVmbGVjdGlvbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tZXNzYWdlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21ldGFkYXRhLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Vua25vd25fZmllbGRfc2V0Lmg+CisKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgdXBiIHsKK25hbWVzcGFjZSBnb29nbGVfb3BlbnNvdXJjZSB7CitjbGFzcyBHTVJfSGFuZGxlcnM7Cit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlX29wZW5zb3VyY2UKK30gIC8vIG5hbWVzcGFjZSB1cGIKKworbmFtZXNwYWNlIHByb3RvYnVmIHsKK2NsYXNzIERlc2NyaXB0b3JQb29sOworY2xhc3MgTWFwS2V5OworY2xhc3MgTWFwVmFsdWVSZWY7Cit9CisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW50ZXJuYWwgeworY2xhc3MgRGVmYXVsdEVtcHR5T25lb2Y7CisKKy8vIERlZmluZWQgaW4gdGhpcyBmaWxlLgorY2xhc3MgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb247CisKKy8vIERlZmluZWQgaW4gb3RoZXIgZmlsZXMuCitjbGFzcyBFeHRlbnNpb25TZXQ7ICAgICAgICAgICAgIC8vIGV4dGVuc2lvbl9zZXQuaAorCisvLyBUSElTIENMQVNTIElTIE5PVCBJTlRFTkRFRCBGT1IgRElSRUNUIFVTRS4gIEl0IGlzIGludGVuZGVkIGZvciB1c2UKKy8vIGJ5IGdlbmVyYXRlZCBjb2RlLiAgVGhpcyBjbGFzcyBpcyBqdXN0IGEgYmlnIGhhY2sgdGhhdCByZWR1Y2VzIGNvZGUKKy8vIHNpemUuCisvLworLy8gQSBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbiBpcyBhbiBpbXBsZW1lbnRhdGlvbiBvZiBSZWZsZWN0aW9uCisvLyB3aGljaCBleHBlY3RzIGFsbCBmaWVsZHMgdG8gYmUgYmFja2VkIGJ5IHNpbXBsZSB2YXJpYWJsZXMgbG9jYXRlZCBpbgorLy8gbWVtb3J5LiAgVGhlIGxvY2F0aW9ucyBhcmUgZ2l2ZW4gdXNpbmcgYSBiYXNlIHBvaW50ZXIgYW5kIGEgc2V0IG9mCisvLyBvZmZzZXRzLgorLy8KKy8vIEl0IGlzIHJlcXVpcmVkIHRoYXQgdGhlIHVzZXIgcmVwcmVzZW50cyBmaWVsZHMgb2YgZWFjaCB0eXBlIGluIGEgc3RhbmRhcmQKKy8vIHdheSwgc28gdGhhdCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbiBjYW4gY2FzdCB0aGUgdm9pZCogcG9pbnRlciB0bworLy8gdGhlIGFwcHJvcHJpYXRlIHR5cGUuICBGb3IgcHJpbWl0aXZlIGZpZWxkcyBhbmQgc3RyaW5nIGZpZWxkcywgZWFjaCBmaWVsZAorLy8gc2hvdWxkIGJlIHJlcHJlc2VudGVkIHVzaW5nIHRoZSBvYnZpb3VzIEMrKyBwcmltaXRpdmUgdHlwZS4gIEVudW1zIGFuZAorLy8gTWVzc2FnZXMgYXJlIGRpZmZlcmVudDoKKy8vICAtIFNpbmd1bGFyIE1lc3NhZ2UgZmllbGRzIGFyZSBzdG9yZWQgYXMgYSBwb2ludGVyIHRvIGEgTWVzc2FnZS4gIFRoZXNlCisvLyAgICBzaG91bGQgc3RhcnQgb3V0IE5VTEwsIGV4Y2VwdCBmb3IgaW4gdGhlIGRlZmF1bHQgaW5zdGFuY2Ugd2hlcmUgdGhleQorLy8gICAgc2hvdWxkIHN0YXJ0IG91dCBwb2ludGluZyB0byBvdGhlciBkZWZhdWx0IGluc3RhbmNlcy4KKy8vICAtIEVudW0gZmllbGRzIGFyZSBzdG9yZWQgYXMgYW4gaW50LiAgVGhpcyBpbnQgbXVzdCBhbHdheXMgY29udGFpbgorLy8gICAgYSB2YWxpZCB2YWx1ZSwgc3VjaCB0aGF0IEVudW1EZXNjcmlwdG9yOjpGaW5kVmFsdWVCeU51bWJlcigpIHdvdWxkCisvLyAgICBub3QgcmV0dXJuIE5VTEwuCisvLyAgLSBSZXBlYXRlZCBmaWVsZHMgYXJlIHN0b3JlZCBhcyBSZXBlYXRlZEZpZWxkcyBvciBSZXBlYXRlZFB0ckZpZWxkcworLy8gICAgb2Ygd2hhdGV2ZXIgdHlwZSB0aGUgaW5kaXZpZHVhbCBmaWVsZCB3b3VsZCBiZS4gIFN0cmluZ3MgYW5kCisvLyAgICBNZXNzYWdlcyB1c2UgUmVwZWF0ZWRQdHJGaWVsZHMgd2hpbGUgZXZlcnl0aGluZyBlbHNlIHVzZXMKKy8vICAgIFJlcGVhdGVkRmllbGRzLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uIDogcHVibGljIFJlZmxlY3Rpb24geworIHB1YmxpYzoKKyAgLy8gQ29uc3RydWN0cyBhIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uLgorICAvLyBQYXJhbWV0ZXJzOgorICAvLyAgIGRlc2NyaXB0b3I6ICAgIFRoZSBkZXNjcmlwdG9yIGZvciB0aGUgbWVzc2FnZSB0eXBlIGJlaW5nIGltcGxlbWVudGVkLgorICAvLyAgIGRlZmF1bHRfaW5zdGFuY2U6ICBUaGUgZGVmYXVsdCBpbnN0YW5jZSBvZiB0aGUgbWVzc2FnZS4gIFRoaXMgaXMgb25seQorICAvLyAgICAgICAgICAgICAgICAgIHVzZWQgdG8gb2J0YWluIHBvaW50ZXJzIHRvIGRlZmF1bHQgaW5zdGFuY2VzIG9mIGVtYmVkZGVkCisgIC8vICAgICAgICAgICAgICAgICAgbWVzc2FnZXMsIHdoaWNoIEdldE1lc3NhZ2UoKSB3aWxsIHJldHVybiBpZiB0aGUgcGFydGljdWxhcgorICAvLyAgICAgICAgICAgICAgICAgIHN1Yi1tZXNzYWdlIGhhcyBub3QgYmVlbiBpbml0aWFsaXplZCB5ZXQuICAoVGh1cywgYWxsCisgIC8vICAgICAgICAgICAgICAgICAgZW1iZWRkZWQgbWVzc2FnZSBmaWVsZHMgKm11c3QqIGhhdmUgbm9uLU5VTEwgcG9pbnRlcnMKKyAgLy8gICAgICAgICAgICAgICAgICBpbiB0aGUgZGVmYXVsdCBpbnN0YW5jZS4pCisgIC8vICAgb2Zmc2V0czogICAgICAgQW4gYXJyYXkgb2YgaW50cyBnaXZpbmcgdGhlIGJ5dGUgb2Zmc2V0cywgcmVsYXRpdmUgdG8KKyAgLy8gICAgICAgICAgICAgICAgICB0aGUgc3RhcnQgb2YgdGhlIG1lc3NhZ2Ugb2JqZWN0LCBvZiBlYWNoIGZpZWxkLiAgVGhlc2UgY2FuCisgIC8vICAgICAgICAgICAgICAgICAgYmUgY29tcHV0ZWQgYXQgY29tcGlsZSB0aW1lIHVzaW5nIHRoZQorICAvLyAgICAgICAgICAgICAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoKSBtYWNybywgZGVmaW5lZAorICAvLyAgICAgICAgICAgICAgICAgIGJlbG93LgorICAvLyAgIGhhc19iaXRzX29mZnNldDogIE9mZnNldCBpbiB0aGUgbWVzc2FnZSBvZiBhbiBhcnJheSBvZiB1aW50MzJzIG9mIHNpemUKKyAgLy8gICAgICAgICAgICAgICAgICBkZXNjcmlwdG9yLT5maWVsZF9jb3VudCgpLzMyLCByb3VuZGVkIHVwLiAgVGhpcyBpcyBhCisgIC8vICAgICAgICAgICAgICAgICAgYml0ZmllbGQgd2hlcmUgZWFjaCBiaXQgaW5kaWNhdGVzIHdoZXRoZXIgb3Igbm90IHRoZQorICAvLyAgICAgICAgICAgICAgICAgIGNvcnJlc3BvbmRpbmcgZmllbGQgb2YgdGhlIG1lc3NhZ2UgaGFzIGJlZW4gaW5pdGlhbGl6ZWQuCisgIC8vICAgICAgICAgICAgICAgICAgVGhlIGJpdCBmb3IgZmllbGQgaW5kZXggaSBpcyBvYnRhaW5lZCBieSB0aGUgZXhwcmVzc2lvbjoKKyAgLy8gICAgICAgICAgICAgICAgICAgIGhhc19iaXRzW2kgLyAzMl0gJiAoMSA8PCAoaSAlIDMyKSkKKyAgLy8gICB1bmtub3duX2ZpZWxkc19vZmZzZXQ6ICBPZmZzZXQgaW4gdGhlIG1lc3NhZ2Ugb2YgdGhlIFVua25vd25GaWVsZFNldCBmb3IKKyAgLy8gICAgICAgICAgICAgICAgICB0aGUgbWVzc2FnZS4KKyAgLy8gICBleHRlbnNpb25zX29mZnNldDogIE9mZnNldCBpbiB0aGUgbWVzc2FnZSBvZiB0aGUgRXh0ZW5zaW9uU2V0IGZvciB0aGUKKyAgLy8gICAgICAgICAgICAgICAgICBtZXNzYWdlLCBvciAtMSBpZiB0aGUgbWVzc2FnZSB0eXBlIGhhcyBubyBleHRlbnNpb24KKyAgLy8gICAgICAgICAgICAgICAgICByYW5nZXMuCisgIC8vICAgcG9vbDogICAgICAgICAgRGVzY3JpcHRvclBvb2wgdG8gc2VhcmNoIGZvciBleHRlbnNpb24gZGVmaW5pdGlvbnMuICBPbmx5CisgIC8vICAgICAgICAgICAgICAgICAgdXNlZCBieSBGaW5kS25vd25FeHRlbnNpb25CeU5hbWUoKSBhbmQKKyAgLy8gICAgICAgICAgICAgICAgICBGaW5kS25vd25FeHRlbnNpb25CeU51bWJlcigpLgorICAvLyAgIGZhY3Rvcnk6ICAgICAgIE1lc3NhZ2VGYWN0b3J5IHRvIHVzZSB0byBjb25zdHJ1Y3QgZXh0ZW5zaW9uIG1lc3NhZ2VzLgorICAvLyAgIG9iamVjdF9zaXplOiAgIFRoZSBzaXplIG9mIGEgbWVzc2FnZSBvYmplY3Qgb2YgdGhpcyB0eXBlLCBhcyBtZWFzdXJlZAorICAvLyAgICAgICAgICAgICAgICAgIGJ5IHNpemVvZigpLgorICBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbihjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNZXNzYWdlKiBkZWZhdWx0X2luc3RhbmNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpbnQgb2Zmc2V0c1tdLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaGFzX2JpdHNfb2Zmc2V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgdW5rbm93bl9maWVsZHNfb2Zmc2V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZXh0ZW5zaW9uc19vZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlc2NyaXB0b3JQb29sKiBwb29sLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlRmFjdG9yeSogZmFjdG9yeSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG9iamVjdF9zaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYXJlbmFfb2Zmc2V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaXNfZGVmYXVsdF9pbnN0YW5jZV9vZmZzZXQgPSAtMSk7CisKKyAgLy8gU2ltaWxhciB3aXRoIHRoZSBjb25zdHJ1Y3Rpb24gYWJvdmUuIENhbGwgdGhpcyBjb25zdHJ1Y3Rpb24gaWYgdGhlCisgIC8vIG1lc3NhZ2UgaGFzIG9uZW9mIGRlZmluaXRpb24uCisgIC8vIFBhcmFtZXRlcnM6CisgIC8vICAgb2Zmc2V0czogICAgICAgQW4gYXJyYXkgb2YgaW50cyBnaXZpbmcgdGhlIGJ5dGUgb2Zmc2V0cy4KKyAgLy8gICAgICAgICAgICAgICAgICBGb3IgZWFjaCBvbmVvZiBmaWVsZCwgdGhlIG9mZnNldCBpcyByZWxhdGl2ZSB0byB0aGUKKyAgLy8gICAgICAgICAgICAgICAgICBkZWZhdWx0X29uZW9mX2luc3RhbmNlLiBUaGVzZSBjYW4gYmUgY29tcHV0ZWQgYXQgY29tcGlsZQorICAvLyAgICAgICAgICAgICAgICAgIHRpbWUgdXNpbmcgdGhlCisgIC8vICAgICAgICAgICAgICAgICAgUFJPVE8yX0dFTkVSQVRFRF9ERUZBVUxUX09ORU9GX0ZJRUxEX09GRlNFVCgpIG1hY3JvLgorICAvLyAgICAgICAgICAgICAgICAgIEZvciBlYWNoIG5vbmUgb25lb2YgZmllbGQsIHRoZSBvZmZzZXQgaXMgcmVsYXRlZCB0bworICAvLyAgICAgICAgICAgICAgICAgIHRoZSBzdGFydCBvZiB0aGUgbWVzc2FnZSBvYmplY3QuICBUaGVzZSBjYW4gYmUgY29tcHV0ZWQKKyAgLy8gICAgICAgICAgICAgICAgICBhdCBjb21waWxlIHRpbWUgdXNpbmcgdGhlCisgIC8vICAgICAgICAgICAgICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVCgpIG1hY3JvLgorICAvLyAgICAgICAgICAgICAgICAgIEJlc2lkZXMgb2Zmc2V0cyBmb3IgYWxsIGZpZWxkcywgdGhpcyBhcnJheSBhbHNvIGNvbnRhaW5zCisgIC8vICAgICAgICAgICAgICAgICAgb2Zmc2V0cyBmb3Igb25lb2YgdW5pb25zLiBUaGUgb2Zmc2V0IG9mIHRoZSBpLXRoIG9uZW9mCisgIC8vICAgICAgICAgICAgICAgICAgdW5pb24gaXMgb2Zmc2V0c1tkZXNjcmlwdG9yLT5maWVsZF9jb3VudCgpICsgaV0uCisgIC8vICAgZGVmYXVsdF9vbmVvZl9pbnN0YW5jZTogVGhlIGRlZmF1bHQgaW5zdGFuY2Ugb2YgdGhlIG9uZW9mcy4gSXQgaXMgYQorICAvLyAgICAgICAgICAgICAgICAgIHN0cnVjdCBob2xkaW5nIHRoZSBkZWZhdWx0IHZhbHVlIG9mIGFsbCBvbmVvZiBmaWVsZHMKKyAgLy8gICAgICAgICAgICAgICAgICBmb3IgdGhpcyBtZXNzYWdlLiBJdCBpcyBvbmx5IHVzZWQgdG8gb2J0YWluIHBvaW50ZXJzCisgIC8vICAgICAgICAgICAgICAgICAgdG8gZGVmYXVsdCBpbnN0YW5jZXMgb2Ygb25lb2YgZmllbGRzLCB3aGljaCBHZXQKKyAgLy8gICAgICAgICAgICAgICAgICBtZXRob2RzIHdpbGwgcmV0dXJuIGlmIHRoZSBmaWVsZCBpcyBub3Qgc2V0LgorICAvLyAgIG9uZW9mX2Nhc2Vfb2Zmc2V0OiAgT2Zmc2V0IGluIHRoZSBtZXNzYWdlIG9mIGFuIGFycmF5IG9mIHVpbnQzMnMgb2YKKyAgLy8gICAgICAgICAgICAgICAgICBzaXplIGRlc2NyaXB0b3ItPm9uZW9mX2RlY2xfY291bnQoKS4gIEVhY2ggdWludDMyCisgIC8vICAgICAgICAgICAgICAgICAgaW5kaWNhdGVzIHdoYXQgZmllbGQgaXMgc2V0IGZvciBlYWNoIG9uZW9mLgorICAvLyAgIG90aGVyIHBhcmFtZXRlcnMgYXJlIHRoZSBzYW1lIHdpdGggdGhlIGNvbnN0cnVjdGlvbiBhYm92ZS4KKyAgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24oY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZSogZGVmYXVsdF9pbnN0YW5jZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW50IG9mZnNldHNbXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGhhc19iaXRzX29mZnNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHVua25vd25fZmllbGRzX29mZnNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGV4dGVuc2lvbnNfb2Zmc2V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2b2lkKiBkZWZhdWx0X29uZW9mX2luc3RhbmNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgb25lb2ZfY2FzZV9vZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlc2NyaXB0b3JQb29sKiBwb29sLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlRmFjdG9yeSogZmFjdG9yeSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG9iamVjdF9zaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYXJlbmFfb2Zmc2V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaXNfZGVmYXVsdF9pbnN0YW5jZV9vZmZzZXQgPSAtMSk7CisgIH5HZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbigpOworCisgIC8vIFNob3J0ZXItdG8tY2FsbCBoZWxwZXJzIGZvciB0aGUgYWJvdmUgdHdvIGNvbnN0cnVjdGlvbnMgdGhhdCB3b3JrIGlmIHRoZQorICAvLyBwb29sIGFuZCBmYWN0b3J5IGFyZSB0aGUgdXN1YWwsIG5hbWVseSwgRGVzY3JpcHRvclBvb2w6OmdlbmVyYXRlZF9wb29sKCkKKyAgLy8gYW5kIE1lc3NhZ2VGYWN0b3J5OjpnZW5lcmF0ZWRfZmFjdG9yeSgpLgorCisgIHN0YXRpYyBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbiogTmV3R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24oCisgICAgICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgY29uc3QgTWVzc2FnZSogZGVmYXVsdF9pbnN0YW5jZSwKKyAgICAgIGNvbnN0IGludCBvZmZzZXRzW10sCisgICAgICBpbnQgaGFzX2JpdHNfb2Zmc2V0LAorICAgICAgaW50IHVua25vd25fZmllbGRzX29mZnNldCwKKyAgICAgIGludCBleHRlbnNpb25zX29mZnNldCwKKyAgICAgIGNvbnN0IHZvaWQqIGRlZmF1bHRfb25lb2ZfaW5zdGFuY2UsCisgICAgICBpbnQgb25lb2ZfY2FzZV9vZmZzZXQsCisgICAgICBpbnQgb2JqZWN0X3NpemUsCisgICAgICBpbnQgYXJlbmFfb2Zmc2V0LAorICAgICAgaW50IGlzX2RlZmF1bHRfaW5zdGFuY2Vfb2Zmc2V0ID0gLTEpOworCisgIHN0YXRpYyBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbiogTmV3R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24oCisgICAgICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgY29uc3QgTWVzc2FnZSogZGVmYXVsdF9pbnN0YW5jZSwKKyAgICAgIGNvbnN0IGludCBvZmZzZXRzW10sCisgICAgICBpbnQgaGFzX2JpdHNfb2Zmc2V0LAorICAgICAgaW50IHVua25vd25fZmllbGRzX29mZnNldCwKKyAgICAgIGludCBleHRlbnNpb25zX29mZnNldCwKKyAgICAgIGludCBvYmplY3Rfc2l6ZSwKKyAgICAgIGludCBhcmVuYV9vZmZzZXQsCisgICAgICBpbnQgaXNfZGVmYXVsdF9pbnN0YW5jZV9vZmZzZXQgPSAtMSk7CisKKyAgLy8gaW1wbGVtZW50cyBSZWZsZWN0aW9uIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBjb25zdCBVbmtub3duRmllbGRTZXQmIEdldFVua25vd25GaWVsZHMoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSkgY29uc3Q7CisgIFVua25vd25GaWVsZFNldCogTXV0YWJsZVVua25vd25GaWVsZHMoTWVzc2FnZSogbWVzc2FnZSkgY29uc3Q7CisKKyAgaW50IFNwYWNlVXNlZChjb25zdCBNZXNzYWdlJiBtZXNzYWdlKSBjb25zdDsKKworICBib29sIEhhc0ZpZWxkKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0OworICBpbnQgRmllbGRTaXplKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0OworICB2b2lkIENsZWFyRmllbGQoTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3Q7CisgIGJvb2wgSGFzT25lb2YoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICBjb25zdCBPbmVvZkRlc2NyaXB0b3IqIG9uZW9mX2Rlc2NyaXB0b3IpIGNvbnN0OworICB2b2lkIENsZWFyT25lb2YoTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBmaWVsZCkgY29uc3Q7CisgIHZvaWQgUmVtb3ZlTGFzdChNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdDsKKyAgTWVzc2FnZSogUmVsZWFzZUxhc3QoTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3Q7CisgIHZvaWQgU3dhcChNZXNzYWdlKiBtZXNzYWdlMSwgTWVzc2FnZSogbWVzc2FnZTIpIGNvbnN0OworICB2b2lkIFN3YXBGaWVsZHMoTWVzc2FnZSogbWVzc2FnZTEsIE1lc3NhZ2UqIG1lc3NhZ2UyLAorICAgICAgICAgICAgICAgICAgY29uc3QgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+JiBmaWVsZHMpIGNvbnN0OworICB2b2lkIFN3YXBFbGVtZW50cyhNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXgxLCBpbnQgaW5kZXgyKSBjb25zdDsKKyAgdm9pZCBMaXN0RmllbGRzKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4qIG91dHB1dCkgY29uc3Q7CisKKyAgaW50MzIgIEdldEludDMyIChjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0OworICBpbnQ2NCAgR2V0SW50NjQgKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3Q7CisgIHVpbnQzMiBHZXRVSW50MzIoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdDsKKyAgdWludDY0IEdldFVJbnQ2NChjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0OworICBmbG9hdCAgR2V0RmxvYXQgKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3Q7CisgIGRvdWJsZSBHZXREb3VibGUoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdDsKKyAgYm9vbCAgIEdldEJvb2wgIChjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0OworICBzdHJpbmcgR2V0U3RyaW5nKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3Q7CisgIGNvbnN0IHN0cmluZyYgR2V0U3RyaW5nUmVmZXJlbmNlKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyogc2NyYXRjaCkgY29uc3Q7CisgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIEdldEVudW0oY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdDsKKyAgaW50IEdldEVudW1WYWx1ZShjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0OworICBjb25zdCBNZXNzYWdlJiBHZXRNZXNzYWdlKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlRmFjdG9yeSogZmFjdG9yeSA9IE5VTEwpIGNvbnN0OworCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogR2V0T25lb2ZGaWVsZERlc2NyaXB0b3IoCisgICAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBvbmVvZl9kZXNjcmlwdG9yKSBjb25zdDsKKworIHByaXZhdGU6CisgIGJvb2wgQ29udGFpbnNNYXBLZXkoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1hcEtleSYga2V5KSBjb25zdDsKKyAgYm9vbCBJbnNlcnRPckxvb2t1cE1hcFZhbHVlKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWFwS2V5JiBrZXksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYXBWYWx1ZVJlZiogdmFsKSBjb25zdDsKKyAgYm9vbCBEZWxldGVNYXBWYWx1ZShNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWFwS2V5JiBrZXkpIGNvbnN0OworICBNYXBJdGVyYXRvciBNYXBCZWdpbigKKyAgICAgIE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdDsKKyAgTWFwSXRlcmF0b3IgTWFwRW5kKAorICAgICAgTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0OworICBpbnQgTWFwU2l6ZShjb25zdCBNZXNzYWdlJiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdDsKKworIHB1YmxpYzoKKyAgdm9pZCBTZXRJbnQzMiAoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50MzIgIHZhbHVlKSBjb25zdDsKKyAgdm9pZCBTZXRJbnQ2NCAoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50NjQgIHZhbHVlKSBjb25zdDsKKyAgdm9pZCBTZXRVSW50MzIoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgdWludDMyIHZhbHVlKSBjb25zdDsKKyAgdm9pZCBTZXRVSW50NjQoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgdWludDY0IHZhbHVlKSBjb25zdDsKKyAgdm9pZCBTZXRGbG9hdCAoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgZmxvYXQgIHZhbHVlKSBjb25zdDsKKyAgdm9pZCBTZXREb3VibGUoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgZG91YmxlIHZhbHVlKSBjb25zdDsKKyAgdm9pZCBTZXRCb29sICAoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgYm9vbCAgIHZhbHVlKSBjb25zdDsKKyAgdm9pZCBTZXRTdHJpbmcoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiB2YWx1ZSkgY29uc3Q7CisgIHZvaWQgU2V0RW51bSAgKE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIHZhbHVlKSBjb25zdDsKKyAgdm9pZCBTZXRFbnVtVmFsdWUoTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgaW50IHZhbHVlKSBjb25zdDsKKyAgTWVzc2FnZSogTXV0YWJsZU1lc3NhZ2UoTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUZhY3RvcnkqIGZhY3RvcnkgPSBOVUxMKSBjb25zdDsKKyAgdm9pZCBTZXRBbGxvY2F0ZWRNZXNzYWdlKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlKiBzdWJfbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0OworICBNZXNzYWdlKiBSZWxlYXNlTWVzc2FnZShNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlRmFjdG9yeSogZmFjdG9yeSA9IE5VTEwpIGNvbnN0OworCisgIGludDMyICBHZXRSZXBlYXRlZEludDMyIChjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50IGluZGV4KSBjb25zdDsKKyAgaW50NjQgIEdldFJlcGVhdGVkSW50NjQgKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBpbnQgaW5kZXgpIGNvbnN0OworICB1aW50MzIgR2V0UmVwZWF0ZWRVSW50MzIoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGludCBpbmRleCkgY29uc3Q7CisgIHVpbnQ2NCBHZXRSZXBlYXRlZFVJbnQ2NChjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50IGluZGV4KSBjb25zdDsKKyAgZmxvYXQgIEdldFJlcGVhdGVkRmxvYXQgKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBpbnQgaW5kZXgpIGNvbnN0OworICBkb3VibGUgR2V0UmVwZWF0ZWREb3VibGUoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGludCBpbmRleCkgY29uc3Q7CisgIGJvb2wgICBHZXRSZXBlYXRlZEJvb2wgIChjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50IGluZGV4KSBjb25zdDsKKyAgc3RyaW5nIEdldFJlcGVhdGVkU3RyaW5nKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBpbnQgaW5kZXgpIGNvbnN0OworICBjb25zdCBzdHJpbmcmIEdldFJlcGVhdGVkU3RyaW5nUmVmZXJlbmNlKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXgsIHN0cmluZyogc2NyYXRjaCkgY29uc3Q7CisgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIEdldFJlcGVhdGVkRW51bShjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCkgY29uc3Q7CisgIGludCBHZXRSZXBlYXRlZEVudW1WYWx1ZShjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCkgY29uc3Q7CisgIGNvbnN0IE1lc3NhZ2UmIEdldFJlcGVhdGVkTWVzc2FnZShjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCkgY29uc3Q7CisKKyAgLy8gU2V0IHRoZSB2YWx1ZSBvZiBhIGZpZWxkLgorICB2b2lkIFNldFJlcGVhdGVkSW50MzIgKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50IGluZGV4LCBpbnQzMiAgdmFsdWUpIGNvbnN0OworICB2b2lkIFNldFJlcGVhdGVkSW50NjQgKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50IGluZGV4LCBpbnQ2NCAgdmFsdWUpIGNvbnN0OworICB2b2lkIFNldFJlcGVhdGVkVUludDMyKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50IGluZGV4LCB1aW50MzIgdmFsdWUpIGNvbnN0OworICB2b2lkIFNldFJlcGVhdGVkVUludDY0KE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50IGluZGV4LCB1aW50NjQgdmFsdWUpIGNvbnN0OworICB2b2lkIFNldFJlcGVhdGVkRmxvYXQgKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50IGluZGV4LCBmbG9hdCAgdmFsdWUpIGNvbnN0OworICB2b2lkIFNldFJlcGVhdGVkRG91YmxlKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50IGluZGV4LCBkb3VibGUgdmFsdWUpIGNvbnN0OworICB2b2lkIFNldFJlcGVhdGVkQm9vbCAgKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50IGluZGV4LCBib29sICAgdmFsdWUpIGNvbnN0OworICB2b2lkIFNldFJlcGVhdGVkU3RyaW5nKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50IGluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgdmFsdWUpIGNvbnN0OworICB2b2lkIFNldFJlcGVhdGVkRW51bShNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXgsIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIHZhbHVlKSBjb25zdDsKKyAgdm9pZCBTZXRSZXBlYXRlZEVudW1WYWx1ZShNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSBjb25zdDsKKyAgLy8gR2V0IGEgbXV0YWJsZSBwb2ludGVyIHRvIGEgZmllbGQgd2l0aCBhIG1lc3NhZ2UgdHlwZS4KKyAgTWVzc2FnZSogTXV0YWJsZVJlcGVhdGVkTWVzc2FnZShNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGluZGV4KSBjb25zdDsKKworICB2b2lkIEFkZEludDMyIChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBpbnQzMiAgdmFsdWUpIGNvbnN0OworICB2b2lkIEFkZEludDY0IChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBpbnQ2NCAgdmFsdWUpIGNvbnN0OworICB2b2lkIEFkZFVJbnQzMihNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCB1aW50MzIgdmFsdWUpIGNvbnN0OworICB2b2lkIEFkZFVJbnQ2NChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCB1aW50NjQgdmFsdWUpIGNvbnN0OworICB2b2lkIEFkZEZsb2F0IChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBmbG9hdCAgdmFsdWUpIGNvbnN0OworICB2b2lkIEFkZERvdWJsZShNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBkb3VibGUgdmFsdWUpIGNvbnN0OworICB2b2lkIEFkZEJvb2wgIChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBib29sICAgdmFsdWUpIGNvbnN0OworICB2b2lkIEFkZFN0cmluZyhNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBjb25zdCBzdHJpbmcmIHZhbHVlKSBjb25zdDsKKyAgdm9pZCBBZGRFbnVtKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogdmFsdWUpIGNvbnN0OworICB2b2lkIEFkZEVudW1WYWx1ZShNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICBpbnQgdmFsdWUpIGNvbnN0OworICBNZXNzYWdlKiBBZGRNZXNzYWdlKE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUZhY3RvcnkqIGZhY3RvcnkgPSBOVUxMKSBjb25zdDsKKyAgdm9pZCBBZGRBbGxvY2F0ZWRNZXNzYWdlKAorICAgICAgTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgIE1lc3NhZ2UqIG5ld19lbnRyeSkgY29uc3Q7CisKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBGaW5kS25vd25FeHRlbnNpb25CeU5hbWUoY29uc3Qgc3RyaW5nJiBuYW1lKSBjb25zdDsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBGaW5kS25vd25FeHRlbnNpb25CeU51bWJlcihpbnQgbnVtYmVyKSBjb25zdDsKKworICBib29sIFN1cHBvcnRzVW5rbm93bkVudW1WYWx1ZXMoKSBjb25zdDsKKworICAvLyBUaGlzIHZhbHVlIGZvciBhcmVuYV9vZmZzZXRfIGluZGljYXRlcyB0aGF0IHRoZXJlIGlzIG5vIGFyZW5hIHBvaW50ZXIgaW4KKyAgLy8gdGhpcyBtZXNzYWdlIChlLmcuLCBvbGQgZ2VuZXJhdGVkIGNvZGUpLgorICBzdGF0aWMgY29uc3QgaW50IGtOb0FyZW5hUG9pbnRlciA9IC0xOworCisgIC8vIFRoaXMgdmFsdWUgZm9yIHVua25vd25fZmllbGRfb2Zmc2V0XyBpbmRpY2F0ZXMgdGhhdCB0aGVyZSBpcyBubworICAvLyBVbmtub3duRmllbGRTZXQgaW4gdGhpcyBtZXNzYWdlLCBhbmQgdGhhdCBpbnN0ZWFkLCB3ZSBhcmUgdXNpbmcgdGhlCisgIC8vIFplcm8tT3ZlcmhlYWQgQXJlbmEgUG9pbnRlciB0cmljay4gV2hlbiB0aGlzIGlzIHRoZSBjYXNlLCBhcmVuYV9vZmZzZXRfCisgIC8vIGFjdHVhbGx5IGluZGV4ZXMgdG8gYW4gSW50ZXJuYWxNZXRhZGF0YVdpdGhBcmVuYSBpbnN0YW5jZSwgd2hpY2ggY2FuIHJldHVybgorICAvLyBlaXRoZXIgYW4gYXJlbmEgcG9pbnRlciBvciBhbiBVbmtub3duRmllbGRTZXQgb3IgYm90aC4gSXQgaXMgbmV2ZXIgdGhlIGNhc2UKKyAgLy8gdGhhdCB1bmtub3duX2ZpZWxkX29mZnNldF8gPT0ga1Vua25vd25GaWVsZFNldEluTWV0YWRhdGEgJiYgYXJlbmFfb2Zmc2V0XworICAvLyA9PSBrTm9BcmVuYVBvaW50ZXIuCisgIHN0YXRpYyBjb25zdCBpbnQga1Vua25vd25GaWVsZFNldEluTWV0YWRhdGEgPSAtMTsKKworIHByb3RlY3RlZDoKKyAgdm9pZCogTXV0YWJsZVJhd1JlcGVhdGVkRmllbGQoCisgICAgICBNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBGaWVsZERlc2NyaXB0b3I6OkNwcFR5cGUsCisgICAgICBpbnQgY3R5cGUsIGNvbnN0IERlc2NyaXB0b3IqIGRlc2MpIGNvbnN0OworCisgIGNvbnN0IHZvaWQqIEdldFJhd1JlcGVhdGVkRmllbGQoCisgICAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgRmllbGREZXNjcmlwdG9yOjpDcHBUeXBlLCBpbnQgY3R5cGUsCisgICAgICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjKSBjb25zdDsKKworICB2aXJ0dWFsIE1lc3NhZ2VGYWN0b3J5KiBHZXRNZXNzYWdlRmFjdG9yeSgpIGNvbnN0OworCisgIHZpcnR1YWwgdm9pZCogUmVwZWF0ZWRGaWVsZERhdGEoCisgICAgICBNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgRmllbGREZXNjcmlwdG9yOjpDcHBUeXBlIGNwcF90eXBlLAorICAgICAgY29uc3QgRGVzY3JpcHRvciogbWVzc2FnZV90eXBlKSBjb25zdDsKKworIHByaXZhdGU6CisgIGZyaWVuZCBjbGFzcyBHZW5lcmF0ZWRNZXNzYWdlOworCisgIC8vIFRvIHBhcnNlIGRpcmVjdGx5IGludG8gYSBwcm90bzIgZ2VuZXJhdGVkIGNsYXNzLCB0aGUgY2xhc3MgR01SX0hhbmRsZXJzCisgIC8vIG5lZWRzIGFjY2VzcyB0byBtZW1iZXIgb2Zmc2V0cyBhbmQgaGFzYml0cy4KKyAgZnJpZW5kIGNsYXNzIHVwYjo6Z29vZ2xlX29wZW5zb3VyY2U6OkdNUl9IYW5kbGVyczsKKworICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgY29uc3QgTWVzc2FnZSogZGVmYXVsdF9pbnN0YW5jZV87CisgIGNvbnN0IHZvaWQqIGRlZmF1bHRfb25lb2ZfaW5zdGFuY2VfOworICBjb25zdCBpbnQqIG9mZnNldHNfOworCisgIGludCBoYXNfYml0c19vZmZzZXRfOworICBpbnQgb25lb2ZfY2FzZV9vZmZzZXRfOworICBpbnQgdW5rbm93bl9maWVsZHNfb2Zmc2V0XzsKKyAgaW50IGV4dGVuc2lvbnNfb2Zmc2V0XzsKKyAgaW50IGFyZW5hX29mZnNldF87CisgIGludCBpc19kZWZhdWx0X2luc3RhbmNlX29mZnNldF87CisgIGludCBvYmplY3Rfc2l6ZV87CisKKyAgc3RhdGljIGNvbnN0IGludCBrSGFzTm9EZWZhdWx0SW5zdGFuY2VGaWVsZCA9IC0xOworCisgIGNvbnN0IERlc2NyaXB0b3JQb29sKiBkZXNjcmlwdG9yX3Bvb2xfOworICBNZXNzYWdlRmFjdG9yeSogbWVzc2FnZV9mYWN0b3J5XzsKKworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4KKyAgaW5saW5lIGNvbnN0IFR5cGUmIEdldFJhdyhjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0OworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4KKyAgaW5saW5lIFR5cGUqIE11dGFibGVSYXcoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3Q7CisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUeXBlPgorICBpbmxpbmUgY29uc3QgVHlwZSYgRGVmYXVsdFJhdyhjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdDsKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+CisgIGlubGluZSBjb25zdCBUeXBlJiBEZWZhdWx0T25lb2ZSYXcoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3Q7CisKKyAgaW5saW5lIGNvbnN0IHVpbnQzMiogR2V0SGFzQml0cyhjb25zdCBNZXNzYWdlJiBtZXNzYWdlKSBjb25zdDsKKyAgaW5saW5lIHVpbnQzMiogTXV0YWJsZUhhc0JpdHMoTWVzc2FnZSogbWVzc2FnZSkgY29uc3Q7CisgIGlubGluZSB1aW50MzIgR2V0T25lb2ZDYXNlKAorICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgIGNvbnN0IE9uZW9mRGVzY3JpcHRvciogb25lb2ZfZGVzY3JpcHRvcikgY29uc3Q7CisgIGlubGluZSB1aW50MzIqIE11dGFibGVPbmVvZkNhc2UoCisgICAgICBNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgY29uc3QgT25lb2ZEZXNjcmlwdG9yKiBvbmVvZl9kZXNjcmlwdG9yKSBjb25zdDsKKyAgaW5saW5lIGNvbnN0IEV4dGVuc2lvblNldCYgR2V0RXh0ZW5zaW9uU2V0KGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UpIGNvbnN0OworICBpbmxpbmUgRXh0ZW5zaW9uU2V0KiBNdXRhYmxlRXh0ZW5zaW9uU2V0KE1lc3NhZ2UqIG1lc3NhZ2UpIGNvbnN0OworICBpbmxpbmUgQXJlbmEqIEdldEFyZW5hKE1lc3NhZ2UqIG1lc3NhZ2UpIGNvbnN0OworICBpbmxpbmUgY29uc3QgaW50ZXJuYWw6OkludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEmCisgICAgICBHZXRJbnRlcm5hbE1ldGFkYXRhV2l0aEFyZW5hKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UpIGNvbnN0OworICBpbmxpbmUgaW50ZXJuYWw6OkludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEqCisgICAgICBNdXRhYmxlSW50ZXJuYWxNZXRhZGF0YVdpdGhBcmVuYShNZXNzYWdlKiBtZXNzYWdlKSBjb25zdDsKKworICBpbmxpbmUgYm9vbCBHZXRJc0RlZmF1bHRJbnN0YW5jZShjb25zdCBNZXNzYWdlJiBtZXNzYWdlKSBjb25zdDsKKworICBpbmxpbmUgYm9vbCBIYXNCaXQoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0OworICBpbmxpbmUgdm9pZCBTZXRCaXQoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0OworICBpbmxpbmUgdm9pZCBDbGVhckJpdChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdDsKKyAgaW5saW5lIHZvaWQgU3dhcEJpdChNZXNzYWdlKiBtZXNzYWdlMSwKKyAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlKiBtZXNzYWdlMiwKKyAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdDsKKworICAvLyBUaGlzIGZ1bmN0aW9uIG9ubHkgc3dhcHMgdGhlIGZpZWxkLiBTaG91bGQgc3dhcCBjb3JyZXNwb25kaW5nIGhhc19iaXQKKyAgLy8gYmVmb3JlIG9yIGFmdGVyIHVzaW5nIHRoaXMgZnVuY3Rpb24uCisgIHZvaWQgU3dhcEZpZWxkKE1lc3NhZ2UqIG1lc3NhZ2UxLAorICAgICAgICAgICAgICAgICBNZXNzYWdlKiBtZXNzYWdlMiwKKyAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3Q7CisKKyAgdm9pZCBTd2FwT25lb2ZGaWVsZChNZXNzYWdlKiBtZXNzYWdlMSwKKyAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlKiBtZXNzYWdlMiwKKyAgICAgICAgICAgICAgICAgICAgICBjb25zdCBPbmVvZkRlc2NyaXB0b3IqIG9uZW9mX2Rlc2NyaXB0b3IpIGNvbnN0OworCisgIGlubGluZSBib29sIEhhc09uZW9mRmllbGQoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdDsKKyAgaW5saW5lIHZvaWQgU2V0T25lb2ZDYXNlKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdDsKKyAgaW5saW5lIHZvaWQgQ2xlYXJPbmVvZkZpZWxkKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdDsKKworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4KKyAgaW5saW5lIGNvbnN0IFR5cGUmIEdldEZpZWxkKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdDsKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+CisgIGlubGluZSB2b2lkIFNldEZpZWxkKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGNvbnN0IFR5cGUmIHZhbHVlKSBjb25zdDsKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+CisgIGlubGluZSBUeXBlKiBNdXRhYmxlRmllbGQoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdDsKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+CisgIGlubGluZSBjb25zdCBUeXBlJiBHZXRSZXBlYXRlZEZpZWxkKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCkgY29uc3Q7CisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUeXBlPgorICBpbmxpbmUgY29uc3QgVHlwZSYgR2V0UmVwZWF0ZWRQdHJGaWVsZChjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXgpIGNvbnN0OworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4KKyAgaW5saW5lIHZvaWQgU2V0UmVwZWF0ZWRGaWVsZChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGludCBpbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlIHZhbHVlKSBjb25zdDsKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+CisgIGlubGluZSBUeXBlKiBNdXRhYmxlUmVwZWF0ZWRGaWVsZChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCkgY29uc3Q7CisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUeXBlPgorICBpbmxpbmUgdm9pZCBBZGRGaWVsZChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBjb25zdCBUeXBlJiB2YWx1ZSkgY29uc3Q7CisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUeXBlPgorICBpbmxpbmUgVHlwZSogQWRkRmllbGQoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0OworCisgIGludCBHZXRFeHRlbnNpb25OdW1iZXJPckRpZShjb25zdCBEZXNjcmlwdG9yKiB0eXBlKSBjb25zdDsKKworICAvLyBJbnRlcm5hbCB2ZXJzaW9ucyBvZiBFbnVtVmFsdWUgQVBJIHBlcmZvcm0gbm8gY2hlY2tpbmcuIENhbGxlZCBhZnRlciBjaGVja3MKKyAgLy8gYnkgcHVibGljIG1ldGhvZHMuCisgIHZvaWQgU2V0RW51bVZhbHVlSW50ZXJuYWwoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCB2YWx1ZSkgY29uc3Q7CisgIHZvaWQgU2V0UmVwZWF0ZWRFbnVtVmFsdWVJbnRlcm5hbChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCB2YWx1ZSkgY29uc3Q7CisgIHZvaWQgQWRkRW51bVZhbHVlSW50ZXJuYWwoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCB2YWx1ZSkgY29uc3Q7CisKKworICBNZXNzYWdlKiBVbnNhZmVBcmVuYVJlbGVhc2VNZXNzYWdlKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlRmFjdG9yeSogZmFjdG9yeSA9IE5VTEwpIGNvbnN0OworCisgIHZvaWQgVW5zYWZlQXJlbmFTZXRBbGxvY2F0ZWRNZXNzYWdlKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UqIHN1Yl9tZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdDsKKworICBpbnRlcm5hbDo6TWFwRmllbGRCYXNlKiBNYXBEYXRhKAorICAgICAgTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3Q7CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKTsKK307CisKKy8vIFJldHVybnMgdGhlIG9mZnNldCBvZiB0aGUgZ2l2ZW4gZmllbGQgd2l0aGluIHRoZSBnaXZlbiBhZ2dyZWdhdGUgdHlwZS4KKy8vIFRoaXMgaXMgZXF1aXZhbGVudCB0byB0aGUgQU5TSSBDIG9mZnNldG9mKCkgbWFjcm8uICBIb3dldmVyLCBhY2NvcmRpbmcKKy8vIHRvIHRoZSBDKysgc3RhbmRhcmQsIG9mZnNldG9mKCkgb25seSB3b3JrcyBvbiBQT0QgdHlwZXMsIGFuZCBHQ0MKKy8vIGVuZm9yY2VzIHRoaXMgcmVxdWlyZW1lbnQgd2l0aCBhIHdhcm5pbmcuICBJbiBwcmFjdGljZSwgdGhpcyBydWxlIGlzCisvLyB1bm5lY2Vzc2FyaWx5IHN0cmljdDsgdGhlcmUgaXMgcHJvYmFibHkgbm8gY29tcGlsZXIgb3IgcGxhdGZvcm0gb24KKy8vIHdoaWNoIHRoZSBvZmZzZXRzIG9mIHRoZSBkaXJlY3QgZmllbGRzIG9mIGEgY2xhc3MgYXJlIG5vbi1jb25zdGFudC4KKy8vIEZpZWxkcyBpbmhlcml0ZWQgZnJvbSBzdXBlcmNsYXNzZXMgKmNhbiogaGF2ZSBub24tY29uc3RhbnQgb2Zmc2V0cywKKy8vIGJ1dCB0aGF0J3Mgbm90IHdoYXQgdGhpcyBtYWNybyB3aWxsIGJlIHVzZWQgZm9yLgorLy8KKy8vIE5vdGUgdGhhdCB3ZSBjYWxjdWxhdGUgcmVsYXRpdmUgdG8gdGhlIHBvaW50ZXIgdmFsdWUgMTYgaGVyZSBzaW5jZSBpZiB3ZQorLy8ganVzdCB1c2UgemVybywgR0NDIGNvbXBsYWlucyBhYm91dCBkZXJlZmVyZW5jaW5nIGEgTlVMTCBwb2ludGVyLiAgV2UKKy8vIGNob29zZSAxNiByYXRoZXIgdGhhbiBzb21lIG90aGVyIG51bWJlciBqdXN0IGluIGNhc2UgdGhlIGNvbXBpbGVyIHdvdWxkCisvLyBiZSBjb25mdXNlZCBieSBhbiB1bmFsaWduZWQgcG9pbnRlci4KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChUWVBFLCBGSUVMRCkgICAgXAorICBzdGF0aWNfY2FzdDxpbnQ+KCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICByZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPiggICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAmcmVpbnRlcnByZXRfY2FzdDxjb25zdCBUWVBFKj4oMTYpLT5GSUVMRCkgLSAgICAgICAgXAorICAgICAgcmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4oMTYpKQorCisjZGVmaW5lIFBST1RPMl9HRU5FUkFURURfREVGQVVMVF9PTkVPRl9GSUVMRF9PRkZTRVQoT05FT0YsIEZJRUxEKSAgICAgXAorICBzdGF0aWNfY2FzdDxpbnQ+KCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KCYoT05FT0YtPkZJRUxEKSkgICAgICAgICAgICAgICAgICBcCisgICAgICAtIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KE9ORU9GKSkKKworLy8gVGhlcmUgYXJlIHNvbWUgcGxhY2VzIGluIHByb3RvMiB3aGVyZSBkeW5hbWljX2Nhc3Qgd291bGQgYmUgdXNlZnVsIGFzIGFuCisvLyBvcHRpbWl6YXRpb24uICBGb3IgZXhhbXBsZSwgdGFrZSBNZXNzYWdlOjpNZXJnZUZyb20oY29uc3QgTWVzc2FnZSYgb3RoZXIpLgorLy8gRm9yIGEgZ2l2ZW4gZ2VuZXJhdGVkIG1lc3NhZ2UgRm9vTWVzc2FnZSwgd2UgZ2VuZXJhdGUgdGhlc2UgdHdvIG1ldGhvZHM6CisvLyAgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IEZvb01lc3NhZ2UmIG90aGVyKTsKKy8vICAgdm9pZCBNZXJnZUZyb20oY29uc3QgTWVzc2FnZSYgb3RoZXIpOworLy8gVGhlIGZvcm1lciBtZXRob2QgY2FuIGJlIGltcGxlbWVudGVkIGRpcmVjdGx5IGluIHRlcm1zIG9mIEZvb01lc3NhZ2UncworLy8gaW5saW5lIGFjY2Vzc29ycywgYnV0IHRoZSBsYXR0ZXIgbWV0aG9kIG11c3Qgd29yayB3aXRoIHRoZSByZWZsZWN0aW9uCisvLyBpbnRlcmZhY2UuICBIb3dldmVyLCBpZiB0aGUgcGFyYW1ldGVyIHRvIHRoZSBsYXR0ZXIgbWV0aG9kIGlzIGFjdHVhbGx5IG9mCisvLyB0eXBlIEZvb01lc3NhZ2UsIHRoZW4gd2UnZCBsaWtlIHRvIGJlIGFibGUgdG8ganVzdCBjYWxsIHRoZSBvdGhlciBtZXRob2QKKy8vIGFzIGFuIG9wdGltaXphdGlvbi4gIFNvLCB3ZSB1c2UgZHluYW1pY19jYXN0IHRvIGNoZWNrIHRoaXMuCisvLworLy8gVGhhdCBzYWlkLCBkeW5hbWljX2Nhc3QgcmVxdWlyZXMgUlRUSSwgd2hpY2ggbWFueSBwZW9wbGUgbGlrZSB0byBkaXNhYmxlCisvLyBmb3IgcGVyZm9ybWFuY2UgYW5kIGNvZGUgc2l6ZSByZWFzb25zLiAgV2hlbiBSVFRJIGlzIG5vdCBhdmFpbGFibGUsIHdlCisvLyBzdGlsbCBuZWVkIHRvIHByb2R1Y2UgY29ycmVjdCByZXN1bHRzLiAgU28sIGluIHRoaXMgY2FzZSB3ZSBoYXZlIHRvIGZhbGwKKy8vIGJhY2sgdG8gdXNpbmcgcmVmbGVjdGlvbiwgd2hpY2ggaXMgd2hhdCB3ZSB3b3VsZCBoYXZlIGRvbmUgYW55d2F5IGlmIHRoZQorLy8gb2JqZWN0cyB3ZXJlIG5vdCBvZiB0aGUgZXhhY3Qgc2FtZSBjbGFzcy4KKy8vCisvLyBkeW5hbWljX2Nhc3RfaWZfYXZhaWxhYmxlKCkgaW1wbGVtZW50cyB0aGlzIGxvZ2ljLiAgSWYgUlRUSSBpcworLy8gZW5hYmxlZCwgaXQgZG9lcyBhIGR5bmFtaWNfY2FzdC4gIElmIFJUVEkgaXMgZGlzYWJsZWQsIGl0IGp1c3QgcmV0dXJucworLy8gTlVMTC4KKy8vCisvLyBJZiB5b3UgbmVlZCB0byBjb21waWxlIHdpdGhvdXQgUlRUSSwgc2ltcGx5ICNkZWZpbmUgR09PR0xFX1BST1RPQlVGX05PX1JUVEkuCisvLyBPbiBNU1ZDLCB0aGlzIHNob3VsZCBiZSBkZXRlY3RlZCBhdXRvbWF0aWNhbGx5LgordGVtcGxhdGU8dHlwZW5hbWUgVG8sIHR5cGVuYW1lIEZyb20+CitpbmxpbmUgVG8gZHluYW1pY19jYXN0X2lmX2F2YWlsYWJsZShGcm9tIGZyb20pIHsKKyNpZiBkZWZpbmVkKEdPT0dMRV9QUk9UT0JVRl9OT19SVFRJKSB8fCAoZGVmaW5lZChfTVNDX1ZFUikmJiFkZWZpbmVkKF9DUFBSVFRJKSkKKyAgcmV0dXJuIE5VTEw7CisjZWxzZQorICByZXR1cm4gZHluYW1pY19jYXN0PFRvPihmcm9tKTsKKyNlbmRpZgorfQorCisvLyBUcmllcyB0byBkb3duY2FzdCB0aGlzIG1lc3NhZ2UgdG8gYSBnZW5lcmF0ZWQgbWVzc2FnZSB0eXBlLgorLy8gUmV0dXJucyBOVUxMIGlmIHRoaXMgY2xhc3MgaXMgbm90IGFuIGluc3RhbmNlIG9mIFQuCisvLworLy8gVGhpcyBpcyBsaWtlIGR5bmFtaWNfY2FzdF9pZl9hdmFpbGFibGUsIGV4Y2VwdCBpdCB3b3JrcyBldmVuIHdoZW4KKy8vIGR5bmFtaWNfY2FzdCBpcyBub3QgYXZhaWxhYmxlIGJ5IHVzaW5nIFJlZmxlY3Rpb24uICBIb3dldmVyIGl0IG9ubHkgd29ya3MKKy8vIHdpdGggTWVzc2FnZSBvYmplY3RzLgorLy8KKy8vIFRPRE8oaGFiZXJtYW4pOiBjYW4gd2UgcmVtb3ZlIGR5bmFtaWNfY2FzdF9pZl9hdmFpbGFibGUgaW4gZmF2b3Igb2YgdGhpcz8KK3RlbXBsYXRlIDx0eXBlbmFtZSBUPgorVCogRHluYW1pY0Nhc3RUb0dlbmVyYXRlZChjb25zdCBNZXNzYWdlKiBmcm9tKSB7CisgIC8vIENvbXBpbGUtdGltZSBhc3NlcnQgdGhhdCBUIGlzIGEgZ2VuZXJhdGVkIHR5cGUgdGhhdCBoYXMgYQorICAvLyBkZWZhdWx0X2luc3RhbmNlKCkgYWNjZXNzb3IsIGJ1dCBhdm9pZCBhY3R1YWxseSBjYWxsaW5nIGl0LgorICBjb25zdCBUJigqZ2V0X2RlZmF1bHRfaW5zdGFuY2UpKCkgPSAmVDo6ZGVmYXVsdF9pbnN0YW5jZTsKKyAgKHZvaWQpZ2V0X2RlZmF1bHRfaW5zdGFuY2U7CisKKyAgLy8gQ29tcGlsZS10aW1lIGFzc2VydCB0aGF0IFQgaXMgYSBzdWJjbGFzcyBvZiBnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlLgorICBjb25zdCBNZXNzYWdlKiB1bnVzZWQgPSBzdGF0aWNfY2FzdDxUKj4oTlVMTCk7CisgICh2b2lkKXVudXNlZDsKKworI2lmIGRlZmluZWQoR09PR0xFX1BST1RPQlVGX05PX1JUVEkpIHx8IFwKKyAgKGRlZmluZWQoX01TQ19WRVIpICYmICFkZWZpbmVkKF9DUFBSVFRJKSkKKyAgYm9vbCBvayA9ICZUOjpkZWZhdWx0X2luc3RhbmNlKCkgPT0KKyAgICAgICAgICAgIGZyb20tPkdldFJlZmxlY3Rpb24oKS0+R2V0TWVzc2FnZUZhY3RvcnkoKS0+R2V0UHJvdG90eXBlKAorICAgICAgICAgICAgICAgIGZyb20tPkdldERlc2NyaXB0b3IoKSk7CisgIHJldHVybiBvayA/IGRvd25fY2FzdDxUKj4oZnJvbSkgOiBOVUxMOworI2Vsc2UKKyAgcmV0dXJuIGR5bmFtaWNfY2FzdDxUKj4oZnJvbSk7CisjZW5kaWYKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIFQ+CitUKiBEeW5hbWljQ2FzdFRvR2VuZXJhdGVkKE1lc3NhZ2UqIGZyb20pIHsKKyAgY29uc3QgTWVzc2FnZSogbWVzc2FnZV9jb25zdCA9IGZyb207CisgIHJldHVybiBjb25zdF9jYXN0PFQqPihEeW5hbWljQ2FzdFRvR2VuZXJhdGVkPGNvbnN0IFQ+KG1lc3NhZ2VfY29uc3QpKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfUkVGTEVDVElPTl9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX21lc3NhZ2VfcmVmbGVjdGlvbl91bml0dGVzdC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX21lc3NhZ2VfcmVmbGVjdGlvbl91bml0dGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NWViZGVmCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfbWVzc2FnZV9yZWZsZWN0aW9uX3VuaXR0ZXN0LmNjCkBAIC0wLDAgKzEsODUyIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisvLworLy8gVG8gdGVzdCBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbiwgd2UgYWN0dWFsbHkgbGV0IHRoZSBwcm90b2NvbCBjb21waWxlcgorLy8gZ2VuZXJhdGUgYSBmdWxsIHByb3RvY29sIG1lc3NhZ2UgaW1wbGVtZW50YXRpb24gYW5kIHRoZW4gdGVzdCBpdHMKKy8vIHJlZmxlY3Rpb24gaW50ZXJmYWNlLiAgVGhpcyBpcyBtdWNoIGVhc2llciBhbmQgbW9yZSBtYWludGFpbmFibGUgdGhhbgorLy8gdHJ5aW5nIHRvIGNyZWF0ZSBvdXIgb3duIE1lc3NhZ2UgY2xhc3MgZm9yIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uCisvLyB0byB3cmFwLgorLy8KKy8vIFRoZSB0ZXN0cyBoZXJlIGNsb3NlbHkgbWlycm9yIHNvbWUgb2YgdGhlIHRlc3RzIGluCisvLyBjb21waWxlci9jcHAvdW5pdHRlc3QsIGV4Y2VwdCB1c2luZyB0aGUgcmVmbGVjdGlvbiBpbnRlcmZhY2UKKy8vIHJhdGhlciB0aGFuIGdlbmVyYXRlZCBhY2Nlc3NvcnMuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX21lc3NhZ2VfcmVmbGVjdGlvbi5oPgorI2luY2x1ZGUgPG1lbW9yeT4KKyNpZm5kZWYgX1NIQVJFRF9QVFJfSAorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaGFyZWRfcHRyLmg+CisjZW5kaWYKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RfdXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wYi5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2xvZ2dpbmcuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZ29vZ2xldGVzdC5oPgorI2luY2x1ZGUgPGd0ZXN0L2d0ZXN0Lmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworbmFtZXNwYWNlIHsKKworLy8gU2hvcnRoYW5kIHRvIGdldCBhIEZpZWxkRGVzY3JpcHRvciBmb3IgYSBmaWVsZCBvZiB1bml0dGVzdDo6VGVzdEFsbFR5cGVzLgorY29uc3QgRmllbGREZXNjcmlwdG9yKiBGKGNvbnN0IHN0cmluZyYgbmFtZSkgeworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHJlc3VsdCA9CisgICAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6ZGVzY3JpcHRvcigpLT5GaW5kRmllbGRCeU5hbWUobmFtZSk7CisgIEdPT0dMRV9DSEVDSyhyZXN1bHQgIT0gTlVMTCk7CisgIHJldHVybiByZXN1bHQ7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb25UZXN0LCBEZWZhdWx0cykgeworICAvLyBDaGVjayB0aGF0IGFsbCBkZWZhdWx0IHZhbHVlcyBhcmUgc2V0IGNvcnJlY3RseSBpbiB0aGUgaW5pdGlhbCBtZXNzYWdlLgorICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisgIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyIHJlZmxlY3Rpb25fdGVzdGVyKAorICAgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OmRlc2NyaXB0b3IoKSk7CisKKyAgcmVmbGVjdGlvbl90ZXN0ZXIuRXhwZWN0Q2xlYXJWaWFSZWZsZWN0aW9uKG1lc3NhZ2UpOworCisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKTsKKworICAvLyBNZXNzYWdlcyBzaG91bGQgcmV0dXJuIHBvaW50ZXJzIHRvIGRlZmF1bHQgaW5zdGFuY2VzIHVudGlsIGZpcnN0IHVzZS4KKyAgLy8gKFRoaXMgaXMgbm90IGNoZWNrZWQgYnkgRXhwZWN0Q2xlYXIoKSBzaW5jZSBpdCBpcyBub3QgYWN0dWFsbHkgdHJ1ZSBhZnRlcgorICAvLyB0aGUgZmllbGRzIGhhdmUgYmVlbiBzZXQgYW5kIHRoZW4gY2xlYXJlZC4pCisgIEVYUEVDVF9FUSgmdW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6T3B0aW9uYWxHcm91cDo6ZGVmYXVsdF9pbnN0YW5jZSgpLAorICAgICAgICAgICAgJnJlZmxlY3Rpb24tPkdldE1lc3NhZ2UobWVzc2FnZSwgRigib3B0aW9uYWxncm91cCIpKSk7CisgIEVYUEVDVF9FUSgmdW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6TmVzdGVkTWVzc2FnZTo6ZGVmYXVsdF9pbnN0YW5jZSgpLAorICAgICAgICAgICAgJnJlZmxlY3Rpb24tPkdldE1lc3NhZ2UobWVzc2FnZSwgRigib3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UiKSkpOworICBFWFBFQ1RfRVEoJnVuaXR0ZXN0OjpGb3JlaWduTWVzc2FnZTo6ZGVmYXVsdF9pbnN0YW5jZSgpLAorICAgICAgICAgICAgJnJlZmxlY3Rpb24tPkdldE1lc3NhZ2UobWVzc2FnZSwgRigib3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlIikpKTsKKyAgRVhQRUNUX0VRKCZ1bml0dGVzdF9pbXBvcnQ6OkltcG9ydE1lc3NhZ2U6OmRlZmF1bHRfaW5zdGFuY2UoKSwKKyAgICAgICAgICAgICZyZWZsZWN0aW9uLT5HZXRNZXNzYWdlKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlIikpKTsKK30KKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvblRlc3QsIEFjY2Vzc29ycykgeworICAvLyBTZXQgZXZlcnkgZmllbGQgdG8gYSB1bmlxdWUgdmFsdWUgdGhlbiBnbyBiYWNrIGFuZCBjaGVjayBhbGwgdGhvc2UKKyAgLy8gdmFsdWVzLgorICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisgIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyIHJlZmxlY3Rpb25fdGVzdGVyKAorICAgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OmRlc2NyaXB0b3IoKSk7CisKKyAgcmVmbGVjdGlvbl90ZXN0ZXIuU2V0QWxsRmllbGRzVmlhUmVmbGVjdGlvbigmbWVzc2FnZSk7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxGaWVsZHNTZXQobWVzc2FnZSk7CisgIHJlZmxlY3Rpb25fdGVzdGVyLkV4cGVjdEFsbEZpZWxkc1NldFZpYVJlZmxlY3Rpb24obWVzc2FnZSk7CisKKyAgcmVmbGVjdGlvbl90ZXN0ZXIuTW9kaWZ5UmVwZWF0ZWRGaWVsZHNWaWFSZWZsZWN0aW9uKCZtZXNzYWdlKTsKKyAgVGVzdFV0aWw6OkV4cGVjdFJlcGVhdGVkRmllbGRzTW9kaWZpZWQobWVzc2FnZSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb25UZXN0LCBHZXRTdHJpbmdSZWZlcmVuY2UpIHsKKyAgLy8gVGVzdCB0aGF0IEdldFN0cmluZ1JlZmVyZW5jZSgpIHJldHVybnMgdGhlIHVuZGVybHlpbmcgc3RyaW5nIHdoZW4gaXQgaXMKKyAgLy8gYSBub3JtYWwgc3RyaW5nIGZpZWxkLgorICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisgIG1lc3NhZ2Uuc2V0X29wdGlvbmFsX3N0cmluZygiZm9vIik7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX3N0cmluZygiZm9vIik7CisKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpOworICBzdHJpbmcgc2NyYXRjaDsKKworICBFWFBFQ1RfRVEoJm1lc3NhZ2Uub3B0aW9uYWxfc3RyaW5nKCksCisgICAgICAmcmVmbGVjdGlvbi0+R2V0U3RyaW5nUmVmZXJlbmNlKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX3N0cmluZyIpLCAmc2NyYXRjaCkpCisgICAgPDwgIkZvciBzaW1wbGUgc3RyaW5nIGZpZWxkcywgR2V0U3RyaW5nUmVmZXJlbmNlKCkgc2hvdWxkIHJldHVybiBhICIKKyAgICAgICAicmVmZXJlbmNlIHRvIHRoZSB1bmRlcmx5aW5nIHN0cmluZy4iOworICBFWFBFQ1RfRVEoJm1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nKDApLAorICAgICAgJnJlZmxlY3Rpb24tPkdldFJlcGVhdGVkU3RyaW5nUmVmZXJlbmNlKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3N0cmluZyIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsICZzY3JhdGNoKSkKKyAgICA8PCAiRm9yIHNpbXBsZSBzdHJpbmcgZmllbGRzLCBHZXRSZXBlYXRlZFN0cmluZ1JlZmVyZW5jZSgpIHNob3VsZCByZXR1cm4gIgorICAgICAgICJhIHJlZmVyZW5jZSB0byB0aGUgdW5kZXJseWluZyBzdHJpbmcuIjsKK30KKworCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uVGVzdCwgRGVmYXVsdHNBZnRlckNsZWFyKSB7CisgIC8vIENoZWNrIHRoYXQgYWZ0ZXIgc2V0dGluZyBhbGwgZmllbGRzIGFuZCB0aGVuIGNsZWFyaW5nLCBnZXR0aW5nIGFuCisgIC8vIGVtYmVkZGVkIG1lc3NhZ2UgZG9lcyBOT1QgcmV0dXJuIHRoZSBkZWZhdWx0IGluc3RhbmNlLgorICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisgIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyIHJlZmxlY3Rpb25fdGVzdGVyKAorICAgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OmRlc2NyaXB0b3IoKSk7CisKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbWVzc2FnZSk7CisgIG1lc3NhZ2UuQ2xlYXIoKTsKKworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCk7CisKKyAgRVhQRUNUX05FKCZ1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpPcHRpb25hbEdyb3VwOjpkZWZhdWx0X2luc3RhbmNlKCksCisgICAgICAgICAgICAmcmVmbGVjdGlvbi0+R2V0TWVzc2FnZShtZXNzYWdlLCBGKCJvcHRpb25hbGdyb3VwIikpKTsKKyAgRVhQRUNUX05FKCZ1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlOjpkZWZhdWx0X2luc3RhbmNlKCksCisgICAgICAgICAgICAmcmVmbGVjdGlvbi0+R2V0TWVzc2FnZShtZXNzYWdlLCBGKCJvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSIpKSk7CisgIEVYUEVDVF9ORSgmdW5pdHRlc3Q6OkZvcmVpZ25NZXNzYWdlOjpkZWZhdWx0X2luc3RhbmNlKCksCisgICAgICAgICAgICAmcmVmbGVjdGlvbi0+R2V0TWVzc2FnZShtZXNzYWdlLCBGKCJvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UiKSkpOworICBFWFBFQ1RfTkUoJnVuaXR0ZXN0X2ltcG9ydDo6SW1wb3J0TWVzc2FnZTo6ZGVmYXVsdF9pbnN0YW5jZSgpLAorICAgICAgICAgICAgJnJlZmxlY3Rpb24tPkdldE1lc3NhZ2UobWVzc2FnZSwgRigib3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UiKSkpOworfQorCisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb25UZXN0LCBTd2FwKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTE7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTI7CisKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbWVzc2FnZTEpOworCisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlMS5HZXRSZWZsZWN0aW9uKCk7CisgIHJlZmxlY3Rpb24tPlN3YXAoJm1lc3NhZ2UxLCAmbWVzc2FnZTIpOworCisgIFRlc3RVdGlsOjpFeHBlY3RDbGVhcihtZXNzYWdlMSk7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxGaWVsZHNTZXQobWVzc2FnZTIpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uVGVzdCwgU3dhcFdpdGhCb3RoU2V0KSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTE7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTI7CisKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbWVzc2FnZTEpOworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZtZXNzYWdlMik7CisgIFRlc3RVdGlsOjpNb2RpZnlSZXBlYXRlZEZpZWxkcygmbWVzc2FnZTIpOworCisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlMS5HZXRSZWZsZWN0aW9uKCk7CisgIHJlZmxlY3Rpb24tPlN3YXAoJm1lc3NhZ2UxLCAmbWVzc2FnZTIpOworCisgIFRlc3RVdGlsOjpFeHBlY3RSZXBlYXRlZEZpZWxkc01vZGlmaWVkKG1lc3NhZ2UxKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEZpZWxkc1NldChtZXNzYWdlMik7CisKKyAgbWVzc2FnZTEuc2V0X29wdGlvbmFsX2ludDMyKDUzMjgxOSk7CisKKyAgcmVmbGVjdGlvbi0+U3dhcCgmbWVzc2FnZTEsICZtZXNzYWdlMik7CisKKyAgRVhQRUNUX0VRKDUzMjgxOSwgbWVzc2FnZTIub3B0aW9uYWxfaW50MzIoKSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb25UZXN0LCBTd2FwRXh0ZW5zaW9ucykgeworICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTE7CisgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyBtZXNzYWdlMjsKKworICBUZXN0VXRpbDo6U2V0QWxsRXh0ZW5zaW9ucygmbWVzc2FnZTEpOworCisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlMS5HZXRSZWZsZWN0aW9uKCk7CisgIHJlZmxlY3Rpb24tPlN3YXAoJm1lc3NhZ2UxLCAmbWVzc2FnZTIpOworCisgIFRlc3RVdGlsOjpFeHBlY3RFeHRlbnNpb25zQ2xlYXIobWVzc2FnZTEpOworICBUZXN0VXRpbDo6RXhwZWN0QWxsRXh0ZW5zaW9uc1NldChtZXNzYWdlMik7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb25UZXN0LCBTd2FwVW5rbm93bikgeworICB1bml0dGVzdDo6VGVzdEVtcHR5TWVzc2FnZSBtZXNzYWdlMSwgbWVzc2FnZTI7CisKKyAgbWVzc2FnZTEubXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5BZGRWYXJpbnQoMTIzNCwgMSk7CisKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UxLnVua25vd25fZmllbGRzKCkuZmllbGRfY291bnQoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlMi51bmtub3duX2ZpZWxkcygpLmZpZWxkX2NvdW50KCkpOworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZTEuR2V0UmVmbGVjdGlvbigpOworICByZWZsZWN0aW9uLT5Td2FwKCZtZXNzYWdlMSwgJm1lc3NhZ2UyKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UxLnVua25vd25fZmllbGRzKCkuZmllbGRfY291bnQoKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlMi51bmtub3duX2ZpZWxkcygpLmZpZWxkX2NvdW50KCkpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uVGVzdCwgU3dhcEZpZWxkcykgeworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2UxLCBtZXNzYWdlMjsKKyAgbWVzc2FnZTEuc2V0X29wdGlvbmFsX2RvdWJsZSgxMi4zKTsKKyAgbWVzc2FnZTEubXV0YWJsZV9yZXBlYXRlZF9pbnQzMigpLT5BZGQoMTApOworICBtZXNzYWdlMS5tdXRhYmxlX3JlcGVhdGVkX2ludDMyKCktPkFkZCgyMCk7CisKKyAgbWVzc2FnZTIuc2V0X29wdGlvbmFsX3N0cmluZygiaGVsbG8iKTsKKyAgbWVzc2FnZTIubXV0YWJsZV9yZXBlYXRlZF9pbnQ2NCgpLT5BZGQoMzApOworCisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBmaWVsZHM7CisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBtZXNzYWdlMS5HZXREZXNjcmlwdG9yKCk7CisgIGZpZWxkcy5wdXNoX2JhY2soZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJvcHRpb25hbF9kb3VibGUiKSk7CisgIGZpZWxkcy5wdXNoX2JhY2soZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF9pbnQzMiIpKTsKKyAgZmllbGRzLnB1c2hfYmFjayhkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoIm9wdGlvbmFsX3N0cmluZyIpKTsKKyAgZmllbGRzLnB1c2hfYmFjayhkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoIm9wdGlvbmFsX3VpbnQ2NCIpKTsKKworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZTEuR2V0UmVmbGVjdGlvbigpOworICByZWZsZWN0aW9uLT5Td2FwRmllbGRzKCZtZXNzYWdlMSwgJm1lc3NhZ2UyLCBmaWVsZHMpOworCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlMS5oYXNfb3B0aW9uYWxfZG91YmxlKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZTEucmVwZWF0ZWRfaW50MzJfc2l6ZSgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZTEuaGFzX29wdGlvbmFsX3N0cmluZygpKTsKKyAgRVhQRUNUX0VRKCJoZWxsbyIsIG1lc3NhZ2UxLm9wdGlvbmFsX3N0cmluZygpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UxLnJlcGVhdGVkX2ludDY0X3NpemUoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlMS5oYXNfb3B0aW9uYWxfdWludDY0KCkpOworCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UyLmhhc19vcHRpb25hbF9kb3VibGUoKSk7CisgIEVYUEVDVF9FUSgxMi4zLCBtZXNzYWdlMi5vcHRpb25hbF9kb3VibGUoKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlMi5yZXBlYXRlZF9pbnQzMl9zaXplKCkpOworICBFWFBFQ1RfRVEoMTAsIG1lc3NhZ2UyLnJlcGVhdGVkX2ludDMyKDApKTsKKyAgRVhQRUNUX0VRKDIwLCBtZXNzYWdlMi5yZXBlYXRlZF9pbnQzMigxKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlMi5oYXNfb3B0aW9uYWxfc3RyaW5nKCkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZTIucmVwZWF0ZWRfaW50NjRfc2l6ZSgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UyLmhhc19vcHRpb25hbF91aW50NjQoKSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb25UZXN0LCBTd2FwRmllbGRzQWxsKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTE7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTI7CisKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbWVzc2FnZTIpOworCisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBmaWVsZHM7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlMS5HZXRSZWZsZWN0aW9uKCk7CisgIHJlZmxlY3Rpb24tPkxpc3RGaWVsZHMobWVzc2FnZTIsICZmaWVsZHMpOworICByZWZsZWN0aW9uLT5Td2FwRmllbGRzKCZtZXNzYWdlMSwgJm1lc3NhZ2UyLCBmaWVsZHMpOworCisgIFRlc3RVdGlsOjpFeHBlY3RBbGxGaWVsZHNTZXQobWVzc2FnZTEpOworICBUZXN0VXRpbDo6RXhwZWN0Q2xlYXIobWVzc2FnZTIpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uVGVzdCwgU3dhcEZpZWxkc0FsbEV4dGVuc2lvbikgeworICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTE7CisgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyBtZXNzYWdlMjsKKworICBUZXN0VXRpbDo6U2V0QWxsRXh0ZW5zaW9ucygmbWVzc2FnZTEpOworCisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBmaWVsZHM7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlMS5HZXRSZWZsZWN0aW9uKCk7CisgIHJlZmxlY3Rpb24tPkxpc3RGaWVsZHMobWVzc2FnZTEsICZmaWVsZHMpOworICByZWZsZWN0aW9uLT5Td2FwRmllbGRzKCZtZXNzYWdlMSwgJm1lc3NhZ2UyLCBmaWVsZHMpOworCisgIFRlc3RVdGlsOjpFeHBlY3RFeHRlbnNpb25zQ2xlYXIobWVzc2FnZTEpOworICBUZXN0VXRpbDo6RXhwZWN0QWxsRXh0ZW5zaW9uc1NldChtZXNzYWdlMik7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb25UZXN0LCBTd2FwT25lb2YpIHsKKyAgdW5pdHRlc3Q6OlRlc3RPbmVvZjIgbWVzc2FnZTEsIG1lc3NhZ2UyOworICBUZXN0VXRpbDo6U2V0T25lb2YxKCZtZXNzYWdlMSk7CisKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UxLkdldFJlZmxlY3Rpb24oKTsKKyAgcmVmbGVjdGlvbi0+U3dhcCgmbWVzc2FnZTEsICZtZXNzYWdlMik7CisKKyAgVGVzdFV0aWw6OkV4cGVjdE9uZW9mQ2xlYXIobWVzc2FnZTEpOworICBUZXN0VXRpbDo6RXhwZWN0T25lb2ZTZXQxKG1lc3NhZ2UyKTsKK30KKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvblRlc3QsIFN3YXBPbmVvZkJvdGhTZXQpIHsKKyAgdW5pdHRlc3Q6OlRlc3RPbmVvZjIgbWVzc2FnZTEsIG1lc3NhZ2UyOworICBUZXN0VXRpbDo6U2V0T25lb2YxKCZtZXNzYWdlMSk7CisgIFRlc3RVdGlsOjpTZXRPbmVvZjIoJm1lc3NhZ2UyKTsKKworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZTEuR2V0UmVmbGVjdGlvbigpOworICByZWZsZWN0aW9uLT5Td2FwKCZtZXNzYWdlMSwgJm1lc3NhZ2UyKTsKKworICBUZXN0VXRpbDo6RXhwZWN0T25lb2ZTZXQyKG1lc3NhZ2UxKTsKKyAgVGVzdFV0aWw6OkV4cGVjdE9uZW9mU2V0MShtZXNzYWdlMik7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb25UZXN0LCBTd2FwRmllbGRzT25lb2YpIHsKKyAgdW5pdHRlc3Q6OlRlc3RPbmVvZjIgbWVzc2FnZTEsIG1lc3NhZ2UyOworICBUZXN0VXRpbDo6U2V0T25lb2YxKCZtZXNzYWdlMSk7CisKKyAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+IGZpZWxkczsKKyAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciA9IG1lc3NhZ2UxLkdldERlc2NyaXB0b3IoKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBmaWVsZHMucHVzaF9iYWNrKGRlc2NyaXB0b3ItPmZpZWxkKGkpKTsKKyAgfQorICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZTEuR2V0UmVmbGVjdGlvbigpOworICByZWZsZWN0aW9uLT5Td2FwRmllbGRzKCZtZXNzYWdlMSwgJm1lc3NhZ2UyLCBmaWVsZHMpOworCisgIFRlc3RVdGlsOjpFeHBlY3RPbmVvZkNsZWFyKG1lc3NhZ2UxKTsKKyAgVGVzdFV0aWw6OkV4cGVjdE9uZW9mU2V0MShtZXNzYWdlMik7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb25UZXN0LCBSZW1vdmVMYXN0KSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKyAgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXIgcmVmbGVjdGlvbl90ZXN0ZXIoCisgICAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6ZGVzY3JpcHRvcigpKTsKKworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZtZXNzYWdlKTsKKworICByZWZsZWN0aW9uX3Rlc3Rlci5SZW1vdmVMYXN0UmVwZWF0ZWRzVmlhUmVmbGVjdGlvbigmbWVzc2FnZSk7CisKKyAgVGVzdFV0aWw6OkV4cGVjdExhc3RSZXBlYXRlZHNSZW1vdmVkKG1lc3NhZ2UpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uVGVzdCwgUmVtb3ZlTGFzdEV4dGVuc2lvbnMpIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2U7CisgIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyIHJlZmxlY3Rpb25fdGVzdGVyKAorICAgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9uczo6ZGVzY3JpcHRvcigpKTsKKworICBUZXN0VXRpbDo6U2V0QWxsRXh0ZW5zaW9ucygmbWVzc2FnZSk7CisKKyAgcmVmbGVjdGlvbl90ZXN0ZXIuUmVtb3ZlTGFzdFJlcGVhdGVkc1ZpYVJlZmxlY3Rpb24oJm1lc3NhZ2UpOworCisgIFRlc3RVdGlsOjpFeHBlY3RMYXN0UmVwZWF0ZWRFeHRlbnNpb25zUmVtb3ZlZChtZXNzYWdlKTsKK30KKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvblRlc3QsIFJlbGVhc2VMYXN0KSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKyAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciA9IG1lc3NhZ2UuR2V0RGVzY3JpcHRvcigpOworICBUZXN0VXRpbDo6UmVmbGVjdGlvblRlc3RlciByZWZsZWN0aW9uX3Rlc3RlcihkZXNjcmlwdG9yKTsKKworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZtZXNzYWdlKTsKKworICByZWZsZWN0aW9uX3Rlc3Rlci5SZWxlYXNlTGFzdFJlcGVhdGVkc1ZpYVJlZmxlY3Rpb24oJm1lc3NhZ2UsIGZhbHNlKTsKKworICBUZXN0VXRpbDo6RXhwZWN0TGFzdFJlcGVhdGVkc1JlbGVhc2VkKG1lc3NhZ2UpOworCisgIC8vIE5vdyB0ZXN0IHRoYXQgd2UgYWN0dWFsbHkgcmVsZWFzZSB0aGUgcmlnaHQgbWVzc2FnZS4KKyAgbWVzc2FnZS5DbGVhcigpOworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZtZXNzYWdlKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX3NpemUoKSk7CisgIGNvbnN0IHByb3RvYnVmX3VuaXR0ZXN0OjpGb3JlaWduTWVzc2FnZSogZXhwZWN0ZWQgPQorICAgICAgbWVzc2FnZS5tdXRhYmxlX3JlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSgxKTsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxNZXNzYWdlPiByZWxlYXNlZChtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+UmVsZWFzZUxhc3QoCisgICAgICAmbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UiKSkpOworICBFWFBFQ1RfRVEoZXhwZWN0ZWQsIHJlbGVhc2VkLmdldCgpKTsKK30KKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvblRlc3QsIFJlbGVhc2VMYXN0RXh0ZW5zaW9ucykgeworICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTsKKyAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciA9IG1lc3NhZ2UuR2V0RGVzY3JpcHRvcigpOworICBUZXN0VXRpbDo6UmVmbGVjdGlvblRlc3RlciByZWZsZWN0aW9uX3Rlc3RlcihkZXNjcmlwdG9yKTsKKworICBUZXN0VXRpbDo6U2V0QWxsRXh0ZW5zaW9ucygmbWVzc2FnZSk7CisKKyAgcmVmbGVjdGlvbl90ZXN0ZXIuUmVsZWFzZUxhc3RSZXBlYXRlZHNWaWFSZWZsZWN0aW9uKCZtZXNzYWdlLCB0cnVlKTsKKworICBUZXN0VXRpbDo6RXhwZWN0TGFzdFJlcGVhdGVkRXh0ZW5zaW9uc1JlbGVhc2VkKG1lc3NhZ2UpOworCisgIC8vIE5vdyB0ZXN0IHRoYXQgd2UgYWN0dWFsbHkgcmVsZWFzZSB0aGUgcmlnaHQgbWVzc2FnZS4KKyAgbWVzc2FnZS5DbGVhcigpOworICBUZXN0VXRpbDo6U2V0QWxsRXh0ZW5zaW9ucygmbWVzc2FnZSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUoCisgICAgICB1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbikpOworICBjb25zdCBwcm90b2J1Zl91bml0dGVzdDo6Rm9yZWlnbk1lc3NhZ2UqIGV4cGVjdGVkID0gbWVzc2FnZS5NdXRhYmxlRXh0ZW5zaW9uKAorICAgICAgdW5pdHRlc3Q6OnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb24sIDEpOworICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPE1lc3NhZ2U+IHJlbGVhc2VkKG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpLT5SZWxlYXNlTGFzdCgKKyAgICAgICZtZXNzYWdlLCBkZXNjcmlwdG9yLT5maWxlKCktPkZpbmRFeHRlbnNpb25CeU5hbWUoCisgICAgICAgICAgICAgICAgICAgICJyZXBlYXRlZF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uIikpKTsKKyAgRVhQRUNUX0VRKGV4cGVjdGVkLCByZWxlYXNlZC5nZXQoKSk7CisKK30KKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvblRlc3QsIFN3YXBSZXBlYXRlZEVsZW1lbnRzKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKyAgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXIgcmVmbGVjdGlvbl90ZXN0ZXIoCisgICAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6ZGVzY3JpcHRvcigpKTsKKworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZtZXNzYWdlKTsKKworICAvLyBTd2FwIGFuZCB0ZXN0IHRoYXQgZmllbGRzIGFyZSBhbGwgc3dhcHBlZC4KKyAgcmVmbGVjdGlvbl90ZXN0ZXIuU3dhcFJlcGVhdGVkc1ZpYVJlZmxlY3Rpb24oJm1lc3NhZ2UpOworICBUZXN0VXRpbDo6RXhwZWN0UmVwZWF0ZWRzU3dhcHBlZChtZXNzYWdlKTsKKworICAvLyBTd2FwIGJhY2sgYW5kIHRlc3QgdGhhdCBmaWVsZHMgYXJlIGFsbCBiYWNrIHRvIG9yaWdpbmFsIHZhbHVlcy4KKyAgcmVmbGVjdGlvbl90ZXN0ZXIuU3dhcFJlcGVhdGVkc1ZpYVJlZmxlY3Rpb24oJm1lc3NhZ2UpOworICBUZXN0VXRpbDo6RXhwZWN0QWxsRmllbGRzU2V0KG1lc3NhZ2UpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uVGVzdCwgU3dhcFJlcGVhdGVkRWxlbWVudHNFeHRlbnNpb24pIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2U7CisgIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyIHJlZmxlY3Rpb25fdGVzdGVyKAorICAgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9uczo6ZGVzY3JpcHRvcigpKTsKKworICBUZXN0VXRpbDo6U2V0QWxsRXh0ZW5zaW9ucygmbWVzc2FnZSk7CisKKyAgLy8gU3dhcCBhbmQgdGVzdCB0aGF0IGZpZWxkcyBhcmUgYWxsIHN3YXBwZWQuCisgIHJlZmxlY3Rpb25fdGVzdGVyLlN3YXBSZXBlYXRlZHNWaWFSZWZsZWN0aW9uKCZtZXNzYWdlKTsKKyAgVGVzdFV0aWw6OkV4cGVjdFJlcGVhdGVkRXh0ZW5zaW9uc1N3YXBwZWQobWVzc2FnZSk7CisKKyAgLy8gU3dhcCBiYWNrIGFuZCB0ZXN0IHRoYXQgZmllbGRzIGFyZSBhbGwgYmFjayB0byBvcmlnaW5hbCB2YWx1ZXMuCisgIHJlZmxlY3Rpb25fdGVzdGVyLlN3YXBSZXBlYXRlZHNWaWFSZWZsZWN0aW9uKCZtZXNzYWdlKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEV4dGVuc2lvbnNTZXQobWVzc2FnZSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb25UZXN0LCBFeHRlbnNpb25zKSB7CisgIC8vIFNldCBldmVyeSBleHRlbnNpb24gdG8gYSB1bmlxdWUgdmFsdWUgdGhlbiBnbyBiYWNrIGFuZCBjaGVjayBhbGwgdGhvc2UKKyAgLy8gdmFsdWVzLgorICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTsKKyAgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXIgcmVmbGVjdGlvbl90ZXN0ZXIoCisgICAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zOjpkZXNjcmlwdG9yKCkpOworCisgIHJlZmxlY3Rpb25fdGVzdGVyLlNldEFsbEZpZWxkc1ZpYVJlZmxlY3Rpb24oJm1lc3NhZ2UpOworICBUZXN0VXRpbDo6RXhwZWN0QWxsRXh0ZW5zaW9uc1NldChtZXNzYWdlKTsKKyAgcmVmbGVjdGlvbl90ZXN0ZXIuRXhwZWN0QWxsRmllbGRzU2V0VmlhUmVmbGVjdGlvbihtZXNzYWdlKTsKKworICByZWZsZWN0aW9uX3Rlc3Rlci5Nb2RpZnlSZXBlYXRlZEZpZWxkc1ZpYVJlZmxlY3Rpb24oJm1lc3NhZ2UpOworICBUZXN0VXRpbDo6RXhwZWN0UmVwZWF0ZWRFeHRlbnNpb25zTW9kaWZpZWQobWVzc2FnZSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb25UZXN0LCBGaW5kRXh0ZW5zaW9uVHlwZUJ5TnVtYmVyKSB7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPQorICAgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9uczo6ZGVmYXVsdF9pbnN0YW5jZSgpLkdldFJlZmxlY3Rpb24oKTsKKworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGV4dGVuc2lvbjEgPQorICAgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9uczo6ZGVzY3JpcHRvcigpLT5maWxlKCktPkZpbmRFeHRlbnNpb25CeU5hbWUoCisgICAgICAib3B0aW9uYWxfaW50MzJfZXh0ZW5zaW9uIik7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZXh0ZW5zaW9uMiA9CisgICAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zOjpkZXNjcmlwdG9yKCktPmZpbGUoKS0+RmluZEV4dGVuc2lvbkJ5TmFtZSgKKyAgICAgICJyZXBlYXRlZF9zdHJpbmdfZXh0ZW5zaW9uIik7CisKKyAgRVhQRUNUX0VRKGV4dGVuc2lvbjEsCisgICAgICAgICAgICByZWZsZWN0aW9uLT5GaW5kS25vd25FeHRlbnNpb25CeU51bWJlcihleHRlbnNpb24xLT5udW1iZXIoKSkpOworICBFWFBFQ1RfRVEoZXh0ZW5zaW9uMiwKKyAgICAgICAgICAgIHJlZmxlY3Rpb24tPkZpbmRLbm93bkV4dGVuc2lvbkJ5TnVtYmVyKGV4dGVuc2lvbjItPm51bWJlcigpKSk7CisKKyAgLy8gTm9uLWV4aXN0ZW50IGV4dGVuc2lvbi4KKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+RmluZEtub3duRXh0ZW5zaW9uQnlOdW1iZXIoNjIzNDEpID09IE5VTEwpOworCisgIC8vIEV4dGVuc2lvbnMgb2YgVGVzdEFsbEV4dGVuc2lvbnMgc2hvdWxkIG5vdCBzaG93IHVwIGFzIGV4dGVuc2lvbnMgb2YKKyAgLy8gb3RoZXIgdHlwZXMuCisgIEVYUEVDVF9UUlVFKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OmRlZmF1bHRfaW5zdGFuY2UoKS5HZXRSZWZsZWN0aW9uKCktPgorICAgICAgICAgICAgICBGaW5kS25vd25FeHRlbnNpb25CeU51bWJlcihleHRlbnNpb24xLT5udW1iZXIoKSkgPT0gTlVMTCk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb25UZXN0LCBGaW5kS25vd25FeHRlbnNpb25CeU5hbWUpIHsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9CisgICAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zOjpkZWZhdWx0X2luc3RhbmNlKCkuR2V0UmVmbGVjdGlvbigpOworCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZXh0ZW5zaW9uMSA9CisgICAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zOjpkZXNjcmlwdG9yKCktPmZpbGUoKS0+RmluZEV4dGVuc2lvbkJ5TmFtZSgKKyAgICAgICJvcHRpb25hbF9pbnQzMl9leHRlbnNpb24iKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBleHRlbnNpb24yID0KKyAgICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnM6OmRlc2NyaXB0b3IoKS0+ZmlsZSgpLT5GaW5kRXh0ZW5zaW9uQnlOYW1lKAorICAgICAgInJlcGVhdGVkX3N0cmluZ19leHRlbnNpb24iKTsKKworICBFWFBFQ1RfRVEoZXh0ZW5zaW9uMSwKKyAgICAgICAgICAgIHJlZmxlY3Rpb24tPkZpbmRLbm93bkV4dGVuc2lvbkJ5TmFtZShleHRlbnNpb24xLT5mdWxsX25hbWUoKSkpOworICBFWFBFQ1RfRVEoZXh0ZW5zaW9uMiwKKyAgICAgICAgICAgIHJlZmxlY3Rpb24tPkZpbmRLbm93bkV4dGVuc2lvbkJ5TmFtZShleHRlbnNpb24yLT5mdWxsX25hbWUoKSkpOworCisgIC8vIE5vbi1leGlzdGVudCBleHRlbnNpb24uCisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkZpbmRLbm93bkV4dGVuc2lvbkJ5TmFtZSgibm9fc3VjaF9leHQiKSA9PSBOVUxMKTsKKworICAvLyBFeHRlbnNpb25zIG9mIFRlc3RBbGxFeHRlbnNpb25zIHNob3VsZCBub3Qgc2hvdyB1cCBhcyBleHRlbnNpb25zIG9mCisgIC8vIG90aGVyIHR5cGVzLgorICBFWFBFQ1RfVFJVRSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpkZWZhdWx0X2luc3RhbmNlKCkuR2V0UmVmbGVjdGlvbigpLT4KKyAgICAgICAgICAgICAgRmluZEtub3duRXh0ZW5zaW9uQnlOYW1lKGV4dGVuc2lvbjEtPmZ1bGxfbmFtZSgpKSA9PSBOVUxMKTsKK30KKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvblRlc3QsIFNldEFsbG9jYXRlZE1lc3NhZ2VUZXN0KSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgZnJvbV9tZXNzYWdlMTsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBmcm9tX21lc3NhZ2UyOworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIHRvX21lc3NhZ2U7CisgIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyIHJlZmxlY3Rpb25fdGVzdGVyKAorICAgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OmRlc2NyaXB0b3IoKSk7CisgIHJlZmxlY3Rpb25fdGVzdGVyLlNldEFsbEZpZWxkc1ZpYVJlZmxlY3Rpb24oJmZyb21fbWVzc2FnZTEpOworICByZWZsZWN0aW9uX3Rlc3Rlci5TZXRBbGxGaWVsZHNWaWFSZWZsZWN0aW9uKCZmcm9tX21lc3NhZ2UyKTsKKworICAvLyBCZWZvcmUgbW92aW5nIGZpZWxkcywgd2UgZXhwZWN0IHRoZSBuZXN0ZWQgbWVzc2FnZXMgdG8gYmUgTlVMTC4KKyAgcmVmbGVjdGlvbl90ZXN0ZXIuRXhwZWN0TWVzc2FnZXNSZWxlYXNlZFZpYVJlZmxlY3Rpb24oCisgICAgICAmdG9fbWVzc2FnZSwgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXI6OklTX05VTEwpOworCisgIC8vIEFmdGVyIGZpZWxkcyBhcmUgbW92ZWQgd2Ugc2hvdWxkIGdldCBub24tTlVMTCByZWxlYXNlcy4KKyAgcmVmbGVjdGlvbl90ZXN0ZXIuU2V0QWxsb2NhdGVkT3B0aW9uYWxNZXNzYWdlRmllbGRzVG9NZXNzYWdlVmlhUmVmbGVjdGlvbigKKyAgICAgICZmcm9tX21lc3NhZ2UxLCAmdG9fbWVzc2FnZSk7CisgIHJlZmxlY3Rpb25fdGVzdGVyLkV4cGVjdE1lc3NhZ2VzUmVsZWFzZWRWaWFSZWZsZWN0aW9uKAorICAgICAgJnRvX21lc3NhZ2UsIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyOjpOT1RfTlVMTCk7CisKKyAgLy8gQW5vdGhlciBtb3ZlIHRvIG1ha2Ugc3VyZSB0aGF0IHdlIGNhbiBTZXRBbGxvY2F0ZWQgc2V2ZXJhbCB0aW1lcy4KKyAgcmVmbGVjdGlvbl90ZXN0ZXIuU2V0QWxsb2NhdGVkT3B0aW9uYWxNZXNzYWdlRmllbGRzVG9NZXNzYWdlVmlhUmVmbGVjdGlvbigKKyAgICAgICZmcm9tX21lc3NhZ2UyLCAmdG9fbWVzc2FnZSk7CisgIHJlZmxlY3Rpb25fdGVzdGVyLkV4cGVjdE1lc3NhZ2VzUmVsZWFzZWRWaWFSZWZsZWN0aW9uKAorICAgICAgJnRvX21lc3NhZ2UsIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyOjpOT1RfTlVMTCk7CisKKyAgLy8gQWZ0ZXIgU2V0QWxsb2NhdGVkT3B0aW9uYWxNZXNzYWdlRmllbGRzVG9OdWxsVmlhUmVmbGVjdGlvbigpIHdlIGV4cGVjdCB0aGUKKyAgLy8gcmVsZWFzZXMgdG8gYmUgTlVMTCBhZ2Fpbi4KKyAgcmVmbGVjdGlvbl90ZXN0ZXIuU2V0QWxsb2NhdGVkT3B0aW9uYWxNZXNzYWdlRmllbGRzVG9OdWxsVmlhUmVmbGVjdGlvbigKKyAgICAgICZ0b19tZXNzYWdlKTsKKyAgcmVmbGVjdGlvbl90ZXN0ZXIuRXhwZWN0TWVzc2FnZXNSZWxlYXNlZFZpYVJlZmxlY3Rpb24oCisgICAgICAmdG9fbWVzc2FnZSwgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXI6OklTX05VTEwpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uVGVzdCwgU2V0QWxsb2NhdGVkRXh0ZW5zaW9uTWVzc2FnZVRlc3QpIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIGZyb21fbWVzc2FnZTE7CisgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyBmcm9tX21lc3NhZ2UyOworICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgdG9fbWVzc2FnZTsKKyAgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXIgcmVmbGVjdGlvbl90ZXN0ZXIoCisgICAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zOjpkZXNjcmlwdG9yKCkpOworICByZWZsZWN0aW9uX3Rlc3Rlci5TZXRBbGxGaWVsZHNWaWFSZWZsZWN0aW9uKCZmcm9tX21lc3NhZ2UxKTsKKyAgcmVmbGVjdGlvbl90ZXN0ZXIuU2V0QWxsRmllbGRzVmlhUmVmbGVjdGlvbigmZnJvbV9tZXNzYWdlMik7CisKKyAgLy8gQmVmb3JlIG1vdmluZyBmaWVsZHMsIHdlIGV4cGVjdCB0aGUgbmVzdGVkIG1lc3NhZ2VzIHRvIGJlIE5VTEwuCisgIHJlZmxlY3Rpb25fdGVzdGVyLkV4cGVjdE1lc3NhZ2VzUmVsZWFzZWRWaWFSZWZsZWN0aW9uKAorICAgICAgJnRvX21lc3NhZ2UsIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyOjpJU19OVUxMKTsKKworICAvLyBBZnRlciBmaWVsZHMgYXJlIG1vdmVkIHdlIHNob3VsZCBnZXQgbm9uLU5VTEwgcmVsZWFzZXMuCisgIHJlZmxlY3Rpb25fdGVzdGVyLlNldEFsbG9jYXRlZE9wdGlvbmFsTWVzc2FnZUZpZWxkc1RvTWVzc2FnZVZpYVJlZmxlY3Rpb24oCisgICAgICAmZnJvbV9tZXNzYWdlMSwgJnRvX21lc3NhZ2UpOworICByZWZsZWN0aW9uX3Rlc3Rlci5FeHBlY3RNZXNzYWdlc1JlbGVhc2VkVmlhUmVmbGVjdGlvbigKKyAgICAgICZ0b19tZXNzYWdlLCBUZXN0VXRpbDo6UmVmbGVjdGlvblRlc3Rlcjo6Tk9UX05VTEwpOworCisgIC8vIEFub3RoZXIgbW92ZSB0byBtYWtlIHN1cmUgdGhhdCB3ZSBjYW4gU2V0QWxsb2NhdGVkIHNldmVyYWwgdGltZXMuCisgIHJlZmxlY3Rpb25fdGVzdGVyLlNldEFsbG9jYXRlZE9wdGlvbmFsTWVzc2FnZUZpZWxkc1RvTWVzc2FnZVZpYVJlZmxlY3Rpb24oCisgICAgICAmZnJvbV9tZXNzYWdlMiwgJnRvX21lc3NhZ2UpOworICByZWZsZWN0aW9uX3Rlc3Rlci5FeHBlY3RNZXNzYWdlc1JlbGVhc2VkVmlhUmVmbGVjdGlvbigKKyAgICAgICZ0b19tZXNzYWdlLCBUZXN0VXRpbDo6UmVmbGVjdGlvblRlc3Rlcjo6Tk9UX05VTEwpOworCisgIC8vIEFmdGVyIFNldEFsbG9jYXRlZE9wdGlvbmFsTWVzc2FnZUZpZWxkc1RvTnVsbFZpYVJlZmxlY3Rpb24oKSB3ZSBleHBlY3QgdGhlCisgIC8vIHJlbGVhc2VzIHRvIGJlIE5VTEwgYWdhaW4uCisgIHJlZmxlY3Rpb25fdGVzdGVyLlNldEFsbG9jYXRlZE9wdGlvbmFsTWVzc2FnZUZpZWxkc1RvTnVsbFZpYVJlZmxlY3Rpb24oCisgICAgICAmdG9fbWVzc2FnZSk7CisgIHJlZmxlY3Rpb25fdGVzdGVyLkV4cGVjdE1lc3NhZ2VzUmVsZWFzZWRWaWFSZWZsZWN0aW9uKAorICAgICAgJnRvX21lc3NhZ2UsIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyOjpJU19OVUxMKTsKK30KKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvblRlc3QsIEFkZFJlcGVhdGVkTWVzc2FnZSkgeworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpOworICBjb25zdCBSZWZsZWN0aW9uKiBuZXN0ZWRfcmVmbGVjdGlvbiA9CisgICAgICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlOjpkZWZhdWx0X2luc3RhbmNlKCkuR2V0UmVmbGVjdGlvbigpOworCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogbmVzdGVkX2JiID0KKyAgICAgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2U6OmRlc2NyaXB0b3IoKS0+RmluZEZpZWxkQnlOYW1lKAorICAgICAgICAgICJiYiIpOworCisgIE1lc3NhZ2UqIG5lc3RlZCA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UoCisgICAgICAmbWVzc2FnZSwgRigicmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UiKSk7CisgIG5lc3RlZF9yZWZsZWN0aW9uLT5TZXRJbnQzMihuZXN0ZWQsIG5lc3RlZF9iYiwgMTEpOworCisgIEVYUEVDVF9FUSgxMSwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSgwKS5iYigpKTsKK30KKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvblRlc3QsIE11dGFibGVSZXBlYXRlZE1lc3NhZ2UpIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlOworCisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKTsKKyAgY29uc3QgUmVmbGVjdGlvbiogbmVzdGVkX3JlZmxlY3Rpb24gPQorICAgICAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6TmVzdGVkTWVzc2FnZTo6ZGVmYXVsdF9pbnN0YW5jZSgpLkdldFJlZmxlY3Rpb24oKTsKKworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIG5lc3RlZF9iYiA9CisgICAgICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlOjpkZXNjcmlwdG9yKCktPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICAgICAiYmIiKTsKKworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSgpLT5zZXRfYmIoMTIpOworCisgIE1lc3NhZ2UqIG5lc3RlZCA9IHJlZmxlY3Rpb24tPk11dGFibGVSZXBlYXRlZE1lc3NhZ2UoCisgICAgICAmbWVzc2FnZSwgRigicmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UiKSwgMCk7CisgIEVYUEVDVF9FUSgxMiwgbmVzdGVkX3JlZmxlY3Rpb24tPkdldEludDMyKCpuZXN0ZWQsIG5lc3RlZF9iYikpOworICBuZXN0ZWRfcmVmbGVjdGlvbi0+U2V0SW50MzIobmVzdGVkLCBuZXN0ZWRfYmIsIDEzKTsKKyAgRVhQRUNUX0VRKDEzLCBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlKDApLmJiKCkpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uVGVzdCwgQWRkQWxsb2NhdGVkTWVzc2FnZSkgeworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpOworCisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2UqIG5lc3RlZCA9CisgICAgICBuZXcgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6TmVzdGVkTWVzc2FnZSgpOworICBuZXN0ZWQtPnNldF9iYigxMSk7CisgIHJlZmxlY3Rpb24tPkFkZEFsbG9jYXRlZE1lc3NhZ2UoJm1lc3NhZ2UsIEYoInJlcGVhdGVkX25lc3RlZF9tZXNzYWdlIiksIG5lc3RlZCk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX3NpemUoKSk7CisgIEVYUEVDVF9FUSgxMSwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSgwKS5iYigpKTsKK30KKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvblRlc3QsIExpc3RGaWVsZHNPbmVPZikgeworICB1bml0dGVzdDo6VGVzdE9uZW9mMiBtZXNzYWdlOworICBUZXN0VXRpbDo6U2V0T25lb2YxKCZtZXNzYWdlKTsKKworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCk7CisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBmaWVsZHM7CisgIHJlZmxlY3Rpb24tPkxpc3RGaWVsZHMobWVzc2FnZSwgJmZpZWxkcyk7CisgIEVYUEVDVF9FUSg0LCBmaWVsZHMuc2l6ZSgpKTsKK30KKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvblRlc3QsIE9uZW9mKSB7CisgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIG1lc3NhZ2U7CisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBtZXNzYWdlLkdldERlc2NyaXB0b3IoKTsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpOworCisgIC8vIENoZWNrIGRlZmF1bHQgdmFsdWVzLgorICBFWFBFQ1RfRVEoMCwgcmVmbGVjdGlvbi0+R2V0SW50MzIoCisgICAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImZvb19pbnQiKSkpOworICBFWFBFQ1RfRVEoIiIsIHJlZmxlY3Rpb24tPkdldFN0cmluZygKKyAgICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgiZm9vX3N0cmluZyIpKSk7CisgIEVYUEVDVF9FUSgiIiwgcmVmbGVjdGlvbi0+R2V0U3RyaW5nKAorICAgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJmb29fY29yZCIpKSk7CisgIEVYUEVDVF9FUSgiIiwgcmVmbGVjdGlvbi0+R2V0U3RyaW5nKAorICAgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJmb29fc3RyaW5nX3BpZWNlIikpKTsKKyAgRVhQRUNUX0VRKCIiLCByZWZsZWN0aW9uLT5HZXRTdHJpbmcoCisgICAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImZvb19ieXRlcyIpKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdE9uZW9mMjo6Rk9PLCByZWZsZWN0aW9uLT5HZXRFbnVtKAorICAgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJmb29fZW51bSIpKS0+bnVtYmVyKCkpOworICBFWFBFQ1RfRVEoJnVuaXR0ZXN0OjpUZXN0T25lb2YyOjpOZXN0ZWRNZXNzYWdlOjpkZWZhdWx0X2luc3RhbmNlKCksCisgICAgICAgICAgICAmcmVmbGVjdGlvbi0+R2V0TWVzc2FnZSgKKyAgICAgICAgICAgICAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImZvb19tZXNzYWdlIikpKTsKKyAgRVhQRUNUX0VRKCZ1bml0dGVzdDo6VGVzdE9uZW9mMjo6Rm9vR3JvdXA6OmRlZmF1bHRfaW5zdGFuY2UoKSwKKyAgICAgICAgICAgICZyZWZsZWN0aW9uLT5HZXRNZXNzYWdlKAorICAgICAgICAgICAgICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgiZm9vZ3JvdXAiKSkpOworICBFWFBFQ1RfTkUoJnVuaXR0ZXN0OjpUZXN0T25lb2YyOjpGb29Hcm91cDo6ZGVmYXVsdF9pbnN0YW5jZSgpLAorICAgICAgICAgICAgJnJlZmxlY3Rpb24tPkdldE1lc3NhZ2UoCisgICAgICAgICAgICAgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJmb29fbGF6eV9tZXNzYWdlIikpKTsKKyAgRVhQRUNUX0VRKDUsIHJlZmxlY3Rpb24tPkdldEludDMyKAorICAgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJiYXJfaW50IikpKTsKKyAgRVhQRUNUX0VRKCJTVFJJTkciLCByZWZsZWN0aW9uLT5HZXRTdHJpbmcoCisgICAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImJhcl9zdHJpbmciKSkpOworICBFWFBFQ1RfRVEoIkNPUkQiLCByZWZsZWN0aW9uLT5HZXRTdHJpbmcoCisgICAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImJhcl9jb3JkIikpKTsKKyAgRVhQRUNUX0VRKCJTUElFQ0UiLCByZWZsZWN0aW9uLT5HZXRTdHJpbmcoCisgICAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImJhcl9zdHJpbmdfcGllY2UiKSkpOworICBFWFBFQ1RfRVEoIkJZVEVTIiwgcmVmbGVjdGlvbi0+R2V0U3RyaW5nKAorICAgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJiYXJfYnl0ZXMiKSkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RPbmVvZjI6OkJBUiwgcmVmbGVjdGlvbi0+R2V0RW51bSgKKyAgICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgiYmFyX2VudW0iKSktPm51bWJlcigpKTsKKworICAvLyBDaGVjayBTZXQgZnVuY3Rpb25zLgorICByZWZsZWN0aW9uLT5TZXRJbnQzMigKKyAgICAgICZtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImZvb19pbnQiKSwgMTIzKTsKKyAgRVhQRUNUX0VRKDEyMywgcmVmbGVjdGlvbi0+R2V0SW50MzIoCisgICAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImZvb19pbnQiKSkpOworICByZWZsZWN0aW9uLT5TZXRTdHJpbmcoCisgICAgICAmbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJmb29fc3RyaW5nIiksICJhYmMiKTsKKyAgRVhQRUNUX0VRKCJhYmMiLCByZWZsZWN0aW9uLT5HZXRTdHJpbmcoCisgICAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImZvb19zdHJpbmciKSkpOworICByZWZsZWN0aW9uLT5TZXRTdHJpbmcoCisgICAgICAmbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJmb29fYnl0ZXMiKSwgImJ5dGVzIik7CisgIEVYUEVDVF9FUSgiYnl0ZXMiLCByZWZsZWN0aW9uLT5HZXRTdHJpbmcoCisgICAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImZvb19ieXRlcyIpKSk7CisgIHJlZmxlY3Rpb24tPlNldFN0cmluZygKKyAgICAgICZtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImJhcl9jb3JkIiksICJjaGFuZ2VfY29yZCIpOworICBFWFBFQ1RfRVEoImNoYW5nZV9jb3JkIiwgcmVmbGVjdGlvbi0+R2V0U3RyaW5nKAorICAgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJiYXJfY29yZCIpKSk7CisgIHJlZmxlY3Rpb24tPlNldFN0cmluZygKKyAgICAgICZtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImJhcl9zdHJpbmdfcGllY2UiKSwKKyAgICAgICJjaGFuZ2Vfc3BpZWNlIik7CisgIEVYUEVDVF9FUSgiY2hhbmdlX3NwaWVjZSIsIHJlZmxlY3Rpb24tPkdldFN0cmluZygKKyAgICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgiYmFyX3N0cmluZ19waWVjZSIpKSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb25UZXN0LCBTZXRBbGxvY2F0ZWRPbmVvZk1lc3NhZ2VUZXN0KSB7CisgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIGZyb21fbWVzc2FnZTE7CisgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIGZyb21fbWVzc2FnZTI7CisgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIHRvX21lc3NhZ2U7CisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSB1bml0dGVzdDo6VGVzdE9uZW9mMjo6ZGVzY3JpcHRvcigpOworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gdG9fbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCk7CisKKyAgTWVzc2FnZSogcmVsZWFzZWQgPSByZWZsZWN0aW9uLT5SZWxlYXNlTWVzc2FnZSgKKyAgICAgICZ0b19tZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImZvb19sYXp5X21lc3NhZ2UiKSk7CisgIEVYUEVDVF9UUlVFKHJlbGVhc2VkID09IE5VTEwpOworICByZWxlYXNlZCA9IHJlZmxlY3Rpb24tPlJlbGVhc2VNZXNzYWdlKAorICAgICAgJnRvX21lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgiZm9vX21lc3NhZ2UiKSk7CisgIEVYUEVDVF9UUlVFKHJlbGVhc2VkID09IE5VTEwpOworCisgIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyOjpTZXRPbmVvZlZpYVJlZmxlY3Rpb24oJmZyb21fbWVzc2FnZTEpOworICBUZXN0VXRpbDo6UmVmbGVjdGlvblRlc3Rlcjo6RXhwZWN0T25lb2ZTZXRWaWFSZWZsZWN0aW9uKGZyb21fbWVzc2FnZTEpOworCisgIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyOjoKKyAgICAgIFNldEFsbG9jYXRlZE9wdGlvbmFsTWVzc2FnZUZpZWxkc1RvTWVzc2FnZVZpYVJlZmxlY3Rpb24oCisgICAgICAgICAgJmZyb21fbWVzc2FnZTEsICZ0b19tZXNzYWdlKTsKKyAgY29uc3QgTWVzc2FnZSYgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5HZXRNZXNzYWdlKAorICAgICAgdG9fbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJmb29fbGF6eV9tZXNzYWdlIikpOworICByZWxlYXNlZCA9IHJlZmxlY3Rpb24tPlJlbGVhc2VNZXNzYWdlKAorICAgICAgJnRvX21lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgiZm9vX2xhenlfbWVzc2FnZSIpKTsKKyAgRVhQRUNUX1RSVUUocmVsZWFzZWQgIT0gTlVMTCk7CisgIEVYUEVDVF9FUSgmc3ViX21lc3NhZ2UsIHJlbGVhc2VkKTsKKyAgZGVsZXRlIHJlbGVhc2VkOworCisgIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyOjpTZXRPbmVvZlZpYVJlZmxlY3Rpb24oJmZyb21fbWVzc2FnZTIpOworCisgIHJlZmxlY3Rpb24tPk11dGFibGVNZXNzYWdlKAorICAgICAgJmZyb21fbWVzc2FnZTIsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgiZm9vX21lc3NhZ2UiKSk7CisKKyAgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXI6OgorICAgICAgU2V0QWxsb2NhdGVkT3B0aW9uYWxNZXNzYWdlRmllbGRzVG9NZXNzYWdlVmlhUmVmbGVjdGlvbigKKyAgICAgICAgICAmZnJvbV9tZXNzYWdlMiwgJnRvX21lc3NhZ2UpOworCisgIGNvbnN0IE1lc3NhZ2UmIHN1Yl9tZXNzYWdlMiA9IHJlZmxlY3Rpb24tPkdldE1lc3NhZ2UoCisgICAgICB0b19tZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImZvb19tZXNzYWdlIikpOworICByZWxlYXNlZCA9IHJlZmxlY3Rpb24tPlJlbGVhc2VNZXNzYWdlKAorICAgICAgJnRvX21lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgiZm9vX21lc3NhZ2UiKSk7CisgIEVYUEVDVF9UUlVFKHJlbGVhc2VkICE9IE5VTEwpOworICBFWFBFQ1RfRVEoJnN1Yl9tZXNzYWdlMiwgcmVsZWFzZWQpOworICBkZWxldGUgcmVsZWFzZWQ7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb25UZXN0LCBSZWxlYXNlTWVzc2FnZVRlc3QpIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlOworICBUZXN0VXRpbDo6UmVmbGVjdGlvblRlc3RlciByZWZsZWN0aW9uX3Rlc3RlcigKKyAgICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpkZXNjcmlwdG9yKCkpOworCisgIC8vIFdoZW4gbm90aGluZyBpcyBzZXQsIHdlIGV4cGVjdCBhbGwgcmVsZWFzZWQgbWVzc2FnZXMgdG8gYmUgTlVMTC4KKyAgcmVmbGVjdGlvbl90ZXN0ZXIuRXhwZWN0TWVzc2FnZXNSZWxlYXNlZFZpYVJlZmxlY3Rpb24oCisgICAgICAmbWVzc2FnZSwgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXI6OklTX05VTEwpOworCisgIC8vIEFmdGVyIGZpZWxkcyBhcmUgc2V0IHdlIHNob3VsZCBnZXQgbm9uLU5VTEwgcmVsZWFzZXMuCisgIHJlZmxlY3Rpb25fdGVzdGVyLlNldEFsbEZpZWxkc1ZpYVJlZmxlY3Rpb24oJm1lc3NhZ2UpOworICByZWZsZWN0aW9uX3Rlc3Rlci5FeHBlY3RNZXNzYWdlc1JlbGVhc2VkVmlhUmVmbGVjdGlvbigKKyAgICAgICZtZXNzYWdlLCBUZXN0VXRpbDo6UmVmbGVjdGlvblRlc3Rlcjo6Tk9UX05VTEwpOworCisgIC8vIEFmdGVyIENsZWFyKCkgd2UgbWF5IG9yIG1heSBub3QgZ2V0IGEgbWVzc2FnZSBmcm9tIFJlbGVhc2VNZXNzYWdlKCkuCisgIC8vIFRoaXMgaXMgaW1wbGVtZW50YXRpb24gc3BlY2lmaWMuCisgIHJlZmxlY3Rpb25fdGVzdGVyLlNldEFsbEZpZWxkc1ZpYVJlZmxlY3Rpb24oJm1lc3NhZ2UpOworICBtZXNzYWdlLkNsZWFyKCk7CisgIHJlZmxlY3Rpb25fdGVzdGVyLkV4cGVjdE1lc3NhZ2VzUmVsZWFzZWRWaWFSZWZsZWN0aW9uKAorICAgICAgJm1lc3NhZ2UsIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyOjpDQU5fQkVfTlVMTCk7CisKKyAgLy8gVGVzdCBhIGRpZmZlcmVudCBjb2RlIHBhdGggZm9yIHNldHRpbmcgYWZ0ZXIgcmVsZWFzaW5nLgorICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZtZXNzYWdlKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEZpZWxkc1NldChtZXNzYWdlKTsKK30KKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvblRlc3QsIFJlbGVhc2VFeHRlbnNpb25NZXNzYWdlVGVzdCkgeworICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTsKKyAgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXIgcmVmbGVjdGlvbl90ZXN0ZXIoCisgICAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zOjpkZXNjcmlwdG9yKCkpOworCisgIC8vIFdoZW4gbm90aGluZyBpcyBzZXQsIHdlIGV4cGVjdCBhbGwgcmVsZWFzZWQgbWVzc2FnZXMgdG8gYmUgTlVMTC4KKyAgcmVmbGVjdGlvbl90ZXN0ZXIuRXhwZWN0TWVzc2FnZXNSZWxlYXNlZFZpYVJlZmxlY3Rpb24oCisgICAgICAmbWVzc2FnZSwgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXI6OklTX05VTEwpOworCisgIC8vIEFmdGVyIGZpZWxkcyBhcmUgc2V0IHdlIHNob3VsZCBnZXQgbm9uLU5VTEwgcmVsZWFzZXMuCisgIHJlZmxlY3Rpb25fdGVzdGVyLlNldEFsbEZpZWxkc1ZpYVJlZmxlY3Rpb24oJm1lc3NhZ2UpOworICByZWZsZWN0aW9uX3Rlc3Rlci5FeHBlY3RNZXNzYWdlc1JlbGVhc2VkVmlhUmVmbGVjdGlvbigKKyAgICAgICZtZXNzYWdlLCBUZXN0VXRpbDo6UmVmbGVjdGlvblRlc3Rlcjo6Tk9UX05VTEwpOworCisgIC8vIEFmdGVyIENsZWFyKCkgd2UgbWF5IG9yIG1heSBub3QgZ2V0IGEgbWVzc2FnZSBmcm9tIFJlbGVhc2VNZXNzYWdlKCkuCisgIC8vIFRoaXMgaXMgaW1wbGVtZW50YXRpb24gc3BlY2lmaWMuCisgIHJlZmxlY3Rpb25fdGVzdGVyLlNldEFsbEZpZWxkc1ZpYVJlZmxlY3Rpb24oJm1lc3NhZ2UpOworICBtZXNzYWdlLkNsZWFyKCk7CisgIHJlZmxlY3Rpb25fdGVzdGVyLkV4cGVjdE1lc3NhZ2VzUmVsZWFzZWRWaWFSZWZsZWN0aW9uKAorICAgICAgJm1lc3NhZ2UsIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyOjpDQU5fQkVfTlVMTCk7CisKKyAgLy8gVGVzdCBhIGRpZmZlcmVudCBjb2RlIHBhdGggZm9yIHNldHRpbmcgYWZ0ZXIgcmVsZWFzaW5nLgorICBUZXN0VXRpbDo6U2V0QWxsRXh0ZW5zaW9ucygmbWVzc2FnZSk7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxFeHRlbnNpb25zU2V0KG1lc3NhZ2UpOworfQorCitURVNUKEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uVGVzdCwgUmVsZWFzZU9uZW9mTWVzc2FnZVRlc3QpIHsKKyAgdW5pdHRlc3Q6OlRlc3RPbmVvZjIgbWVzc2FnZTsKKyAgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXI6OlNldE9uZW9mVmlhUmVmbGVjdGlvbigmbWVzc2FnZSk7CisKKyAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciA9IHVuaXR0ZXN0OjpUZXN0T25lb2YyOjpkZXNjcmlwdG9yKCk7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKTsKKyAgY29uc3QgTWVzc2FnZSYgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5HZXRNZXNzYWdlKAorICAgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJmb29fbGF6eV9tZXNzYWdlIikpOworICBNZXNzYWdlKiByZWxlYXNlZCA9IHJlZmxlY3Rpb24tPlJlbGVhc2VNZXNzYWdlKAorICAgICAgJm1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgiZm9vX2xhenlfbWVzc2FnZSIpKTsKKworICBFWFBFQ1RfVFJVRShyZWxlYXNlZCAhPSBOVUxMKTsKKyAgRVhQRUNUX0VRKCZzdWJfbWVzc2FnZSwgcmVsZWFzZWQpOworICBkZWxldGUgcmVsZWFzZWQ7CisKKyAgcmVsZWFzZWQgPSByZWZsZWN0aW9uLT5SZWxlYXNlTWVzc2FnZSgKKyAgICAgICZtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImZvb19sYXp5X21lc3NhZ2UiKSk7CisgIEVYUEVDVF9UUlVFKHJlbGVhc2VkID09IE5VTEwpOworfQorCisjaWZkZWYgUFJPVE9CVUZfSEFTX0RFQVRIX1RFU1QKKworVEVTVChHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvblRlc3QsIFVzYWdlRXJyb3JzKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpOworICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yID0gbWVzc2FnZS5HZXREZXNjcmlwdG9yKCk7CisKKyNkZWZpbmUgZihOQU1FKSBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoTkFNRSkKKworICAvLyBUZXN0aW5nIGV2ZXJ5IHNpbmdsZSBmYWlsdXJlIG1vZGUgd291bGQgYmUgdG9vIG11Y2ggd29yay4gIExldCdzIGp1c3QKKyAgLy8gY2hlY2sgYSBmZXcuCisgIEVYUEVDVF9ERUFUSCgKKyAgICByZWZsZWN0aW9uLT5HZXRJbnQzMigKKyAgICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgib3B0aW9uYWxfaW50NjQiKSksCisgICAgIlByb3RvY29sIEJ1ZmZlciByZWZsZWN0aW9uIHVzYWdlIGVycm9yOlxuIgorICAgICIgIE1ldGhvZCAgICAgIDogZ29vZ2xlOjpwcm90b2J1Zjo6UmVmbGVjdGlvbjo6R2V0SW50MzJcbiIKKyAgICAiICBNZXNzYWdlIHR5cGU6IHByb3RvYnVmX3VuaXR0ZXN0XFwuVGVzdEFsbFR5cGVzXG4iCisgICAgIiAgRmllbGQgICAgICAgOiBwcm90b2J1Zl91bml0dGVzdFxcLlRlc3RBbGxUeXBlc1xcLm9wdGlvbmFsX2ludDY0XG4iCisgICAgIiAgUHJvYmxlbSAgICAgOiBGaWVsZCBpcyBub3QgdGhlIHJpZ2h0IHR5cGUgZm9yIHRoaXMgbWVzc2FnZTpcbiIKKyAgICAiICAgIEV4cGVjdGVkICA6IENQUFRZUEVfSU5UMzJcbiIKKyAgICAiICAgIEZpZWxkIHR5cGU6IENQUFRZUEVfSU5UNjQiKTsKKyAgRVhQRUNUX0RFQVRIKAorICAgIHJlZmxlY3Rpb24tPkdldEludDMyKAorICAgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF9pbnQzMiIpKSwKKyAgICAiUHJvdG9jb2wgQnVmZmVyIHJlZmxlY3Rpb24gdXNhZ2UgZXJyb3I6XG4iCisgICAgIiAgTWV0aG9kICAgICAgOiBnb29nbGU6OnByb3RvYnVmOjpSZWZsZWN0aW9uOjpHZXRJbnQzMlxuIgorICAgICIgIE1lc3NhZ2UgdHlwZTogcHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzXG4iCisgICAgIiAgRmllbGQgICAgICAgOiBwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMucmVwZWF0ZWRfaW50MzJcbiIKKyAgICAiICBQcm9ibGVtICAgICA6IEZpZWxkIGlzIHJlcGVhdGVkOyB0aGUgbWV0aG9kIHJlcXVpcmVzIGEgc2luZ3VsYXIgZmllbGQuIik7CisgIEVYUEVDVF9ERUFUSCgKKyAgICByZWZsZWN0aW9uLT5HZXRJbnQzMigKKyAgICAgIG1lc3NhZ2UsIHVuaXR0ZXN0OjpGb3JlaWduTWVzc2FnZTo6ZGVzY3JpcHRvcigpLT5GaW5kRmllbGRCeU5hbWUoImMiKSksCisgICAgIlByb3RvY29sIEJ1ZmZlciByZWZsZWN0aW9uIHVzYWdlIGVycm9yOlxuIgorICAgICIgIE1ldGhvZCAgICAgIDogZ29vZ2xlOjpwcm90b2J1Zjo6UmVmbGVjdGlvbjo6R2V0SW50MzJcbiIKKyAgICAiICBNZXNzYWdlIHR5cGU6IHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlc1xuIgorICAgICIgIEZpZWxkICAgICAgIDogcHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UuY1xuIgorICAgICIgIFByb2JsZW0gICAgIDogRmllbGQgZG9lcyBub3QgbWF0Y2ggbWVzc2FnZSB0eXBlLiIpOworICBFWFBFQ1RfREVBVEgoCisgICAgcmVmbGVjdGlvbi0+SGFzRmllbGQoCisgICAgICBtZXNzYWdlLCB1bml0dGVzdDo6Rm9yZWlnbk1lc3NhZ2U6OmRlc2NyaXB0b3IoKS0+RmluZEZpZWxkQnlOYW1lKCJjIikpLAorICAgICJQcm90b2NvbCBCdWZmZXIgcmVmbGVjdGlvbiB1c2FnZSBlcnJvcjpcbiIKKyAgICAiICBNZXRob2QgICAgICA6IGdvb2dsZTo6cHJvdG9idWY6OlJlZmxlY3Rpb246Okhhc0ZpZWxkXG4iCisgICAgIiAgTWVzc2FnZSB0eXBlOiBwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXNcbiIKKyAgICAiICBGaWVsZCAgICAgICA6IHByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlLmNcbiIKKyAgICAiICBQcm9ibGVtICAgICA6IEZpZWxkIGRvZXMgbm90IG1hdGNoIG1lc3NhZ2UgdHlwZS4iKTsKKworI3VuZGVmIGYKK30KKworI2VuZGlmICAvLyBQUk9UT0JVRl9IQVNfREVBVEhfVEVTVAorCisKK30gIC8vIG5hbWVzcGFjZQorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9tZXNzYWdlX3V0aWwuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9tZXNzYWdlX3V0aWwuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2I4MTNmOAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX21lc3NhZ2VfdXRpbC5jYwpAQCAtMCwwICsxLDc4IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX21lc3NhZ2VfdXRpbC5oPgorCisjaW5jbHVkZSA8bGltaXRzPgorCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKK2RvdWJsZSBJbmZpbml0eSgpIHsKKyAgcmV0dXJuIHN0ZDo6bnVtZXJpY19saW1pdHM8ZG91YmxlPjo6aW5maW5pdHkoKTsKK30KK2RvdWJsZSBOYU4oKSB7CisgIHJldHVybiBzdGQ6Om51bWVyaWNfbGltaXRzPGRvdWJsZT46OnF1aWV0X05hTigpOworfQorCitjb25zdCA6OnN0ZDo6c3RyaW5nKiBlbXB0eV9zdHJpbmdfOworR09PR0xFX1BST1RPQlVGX0RFQ0xBUkVfT05DRShlbXB0eV9zdHJpbmdfb25jZV9pbml0Xyk7CisKK3ZvaWQgRGVsZXRlRW1wdHlTdHJpbmcoKSB7CisgIGRlbGV0ZSBlbXB0eV9zdHJpbmdfOworfQorCit2b2lkIEluaXRFbXB0eVN0cmluZygpIHsKKyAgZW1wdHlfc3RyaW5nXyA9IG5ldyBzdHJpbmc7CisgIE9uU2h1dGRvd24oJkRlbGV0ZUVtcHR5U3RyaW5nKTsKK30KKworaW50IFN0cmluZ1NwYWNlVXNlZEV4Y2x1ZGluZ1NlbGYoY29uc3Qgc3RyaW5nJiBzdHIpIHsKKyAgY29uc3Qgdm9pZCogc3RhcnQgPSAmc3RyOworICBjb25zdCB2b2lkKiBlbmQgPSAmc3RyICsgMTsKKyAgaWYgKHN0YXJ0IDw9IHN0ci5kYXRhKCkgJiYgc3RyLmRhdGEoKSA8IGVuZCkgeworICAgIC8vIFRoZSBzdHJpbmcncyBkYXRhIGlzIHN0b3JlZCBpbnNpZGUgdGhlIHN0cmluZyBvYmplY3QgaXRzZWxmLgorICAgIHJldHVybiAwOworICB9IGVsc2UgeworICAgIHJldHVybiBzdHIuY2FwYWNpdHkoKTsKKyAgfQorfQorCisKKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX21lc3NhZ2VfdXRpbC5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfbWVzc2FnZV91dGlsLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzhjOGQ3ZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX21lc3NhZ2VfdXRpbC5oCkBAIC0wLDAgKzEsMTIwIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisvLworLy8gVGhpcyBmaWxlIGNvbnRhaW5zIG1pc2NlbGxhbmVvdXMgaGVscGVyIGNvZGUgdXNlZCBieSBnZW5lcmF0ZWQgY29kZSAtLQorLy8gaW5jbHVkaW5nIGxpdGUgdHlwZXMgLS0gYnV0IHdoaWNoIHNob3VsZCBub3QgYmUgdXNlZCBkaXJlY3RseSBieSB1c2Vycy4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfVVRJTF9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX1VUSUxfSF9fCisKKyNpbmNsdWRlIDxhc3NlcnQuaD4KKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvb25jZS5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorbmFtZXNwYWNlIGdvb2dsZSB7CisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKK2NsYXNzIEFyZW5hOworbmFtZXNwYWNlIGlvIHsgY2xhc3MgQ29kZWRJbnB1dFN0cmVhbTsgfQorCituYW1lc3BhY2UgaW50ZXJuYWwgeworCisKKy8vIEFubm90YXRpb24gZm9yIHRoZSBjb21waWxlciB0byBlbWl0IGEgZGVwcmVjYXRpb24gbWVzc2FnZSBpZiBhIGZpZWxkIG1hcmtlZAorLy8gd2l0aCBvcHRpb24gJ2RlcHJlY2F0ZWQ9dHJ1ZScgaXMgdXNlZCBpbiB0aGUgY29kZSwgb3IgZm9yIG90aGVyIHRoaW5ncyBpbgorLy8gZ2VuZXJhdGVkIGNvZGUgd2hpY2ggYXJlIGRlcHJlY2F0ZWQuCisvLworLy8gRm9yIGludGVybmFsIHVzZSBpbiB0aGUgcGIuY2MgZmlsZXMsIGRlcHJlY2F0aW9uIHdhcm5pbmdzIGFyZSBzdXBwcmVzc2VkCisvLyB0aGVyZS4KKyN1bmRlZiBERVBSRUNBVEVEX1BST1RPQlVGX0ZJRUxECisjZGVmaW5lIFBST1RPQlVGX0RFUFJFQ0FURUQKKworCisvLyBDb25zdGFudHMgZm9yIHNwZWNpYWwgZmxvYXRpbmcgcG9pbnQgdmFsdWVzLgorTElCUFJPVE9CVUZfRVhQT1JUIGRvdWJsZSBJbmZpbml0eSgpOworTElCUFJPVE9CVUZfRVhQT1JUIGRvdWJsZSBOYU4oKTsKKworLy8gVE9ETyhqaWVsdW8pOiBDaGFuZ2UgdG8gdGVtcGxhdGUuIFdlIGhhdmUgdHJpZWQgdG8gdXNlIHRlbXBsYXRlLAorLy8gYnV0IGl0IGNhdXNlcyBuZXQvcnBjL3B5dGhvbjpycGN1dGlsX3Rlc3QgZmFpbCAodGhlIGVtcHR5IHN0cmluZyB3aWxsCisvLyBpbml0IHR3aWNlKS4gSXQgbWF5IHJlbGF0ZWQgdG8gc3dpZy4gQ2hhbmdlIHRvIHRlbXBsYXRlIGFmdGVyIHdlCisvLyBmb3VuZCB0aGUgc29sdXRpb24uCisKKy8vIERlZmF1bHQgZW1wdHkgc3RyaW5nIG9iamVjdC4gRG9uJ3QgdXNlIHRoZSBwb2ludGVyIGRpcmVjdGx5LiBJbnN0ZWFkLCBjYWxsCisvLyBHZXRFbXB0eVN0cmluZygpIHRvIGdldCB0aGUgcmVmZXJlbmNlLgorTElCUFJPVE9CVUZfRVhQT1JUIGV4dGVybiBjb25zdCA6OnN0ZDo6c3RyaW5nKiBlbXB0eV9zdHJpbmdfOworTElCUFJPVE9CVUZfRVhQT1JUIGV4dGVybiBQcm90b2J1Zk9uY2VUeXBlIGVtcHR5X3N0cmluZ19vbmNlX2luaXRfOworTElCUFJPVE9CVUZfRVhQT1JUIHZvaWQgSW5pdEVtcHR5U3RyaW5nKCk7CisKKworTElCUFJPVE9CVUZfRVhQT1JUIGlubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSB7CisgIGFzc2VydChlbXB0eV9zdHJpbmdfICE9IE5VTEwpOworICByZXR1cm4gKmVtcHR5X3N0cmluZ187Cit9CitMSUJQUk9UT0JVRl9FWFBPUlQgaW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEdldEVtcHR5U3RyaW5nKCkgeworICA6Omdvb2dsZTo6cHJvdG9idWY6Okdvb2dsZU9uY2VJbml0KCZlbXB0eV9zdHJpbmdfb25jZV9pbml0XywgJkluaXRFbXB0eVN0cmluZyk7CisgIHJldHVybiBHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKTsKK30KKworTElCUFJPVE9CVUZfRVhQT1JUIGludCBTdHJpbmdTcGFjZVVzZWRFeGNsdWRpbmdTZWxmKGNvbnN0IHN0cmluZyYgc3RyKTsKKworCisvLyBUcnVlIGlmIElzSW5pdGlhbGl6ZWQoKSBpcyB0cnVlIGZvciBhbGwgZWxlbWVudHMgb2YgdC4gIFR5cGUgaXMgZXhwZWN0ZWQKKy8vIHRvIGJlIGEgUmVwZWF0ZWRQdHJGaWVsZDxzb21lIG1lc3NhZ2UgdHlwZT4uICBJdCdzIHVzZWZ1bCB0byBoYXZlIHRoaXMKKy8vIGhlbHBlciBoZXJlIHRvIGtlZXAgdGhlIHByb3RvYnVmIGNvbXBpbGVyIGZyb20gZXZlciBoYXZpbmcgdG8gZW1pdCBsb29wcyBpbgorLy8gSXNJbml0aWFsaXplZCgpIG1ldGhvZHMuICBXZSB3YW50IHRoZSBDKysgY29tcGlsZXIgdG8gaW5saW5lIHRoaXMgb3Igbm90CisvLyBhcyBpdCBzZWVzIGZpdC4KK3RlbXBsYXRlIDxjbGFzcyBUeXBlPiBib29sIEFsbEFyZUluaXRpYWxpemVkKGNvbnN0IFR5cGUmIHQpIHsKKyAgZm9yIChpbnQgaSA9IHQuc2l6ZSgpOyAtLWkgPj0gMDsgKSB7CisgICAgaWYgKCF0LkdldChpKS5Jc0luaXRpYWxpemVkKCkpIHJldHVybiBmYWxzZTsKKyAgfQorICByZXR1cm4gdHJ1ZTsKK30KKworY2xhc3MgQXJlbmFTdHJpbmc7CisKKy8vIFJlYWQgYSBsZW5ndGggKHZhcmludDMyKSwgZm9sbG93ZWQgYnkgYSBzdHJpbmcsIGZyb20gKmlucHV0LiAgUmV0dXJuIGEKKy8vIHBvaW50ZXIgdG8gYSBjb3B5IG9mIHRoZSBzdHJpbmcgdGhhdCByZXNpZGVzIGluICphcmVuYS4gIFJlcXVpcmVzIGJvdGgKKy8vIGFyZ3MgdG8gYmUgbm9uLU5VTEwuICBJZiBzb21ldGhpbmcgZ29lcyB3cm9uZyB3aGlsZSByZWFkaW5nIHRoZSBkYXRhCisvLyB0aGVuIE5VTEwgaXMgcmV0dXJuZWQgKGUuZy4sIGlucHV0IGRvZXMgbm90IHN0YXJ0IHdpdGggYSB2YWxpZCB2YXJpbnQpLgorQXJlbmFTdHJpbmcqIFJlYWRBcmVuYVN0cmluZyg6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpOworCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9VVElMX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW0uY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lM2EzNGQwCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW0uY2MKQEAgLTAsMCArMSw5MTcgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBUaGlzIGltcGxlbWVudGF0aW9uIGlzIGhlYXZpbHkgb3B0aW1pemVkIHRvIG1ha2UgcmVhZHMgYW5kIHdyaXRlcworLy8gb2Ygc21hbGwgdmFsdWVzIChlc3BlY2lhbGx5IHZhcmludHMpIGFzIGZhc3QgYXMgcG9zc2libGUuICBJbgorLy8gcGFydGljdWxhciwgd2Ugb3B0aW1pemUgZm9yIHRoZSBjb21tb24gY2FzZSB0aGF0IGEgcmVhZCBvciBhIHdyaXRlCisvLyB3aWxsIG5vdCBjcm9zcyB0aGUgZW5kIG9mIHRoZSBidWZmZXIsIHNpbmNlIHdlIGNhbiBhdm9pZCBhIGxvdAorLy8gb2YgYnJhbmNoaW5nIGluIHRoaXMgY2FzZS4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW1faW5sLmg+CisjaW5jbHVkZSA8YWxnb3JpdGhtPgorI2luY2x1ZGUgPHV0aWxpdHk+CisjaW5jbHVkZSA8bGltaXRzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvYXJlbmEuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbG9nZ2luZy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RsX3V0aWwuaD4KKworCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW8geworCituYW1lc3BhY2UgeworCitzdGF0aWMgY29uc3QgaW50IGtNYXhWYXJpbnRCeXRlcyA9IDEwOworc3RhdGljIGNvbnN0IGludCBrTWF4VmFyaW50MzJCeXRlcyA9IDU7CisKKworaW5saW5lIGJvb2wgTmV4dE5vbkVtcHR5KFplcm9Db3B5SW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQqKiBkYXRhLCBpbnQqIHNpemUpIHsKKyAgYm9vbCBzdWNjZXNzOworICBkbyB7CisgICAgc3VjY2VzcyA9IGlucHV0LT5OZXh0KGRhdGEsIHNpemUpOworICB9IHdoaWxlIChzdWNjZXNzICYmICpzaXplID09IDApOworICByZXR1cm4gc3VjY2VzczsKK30KKworfSAgLy8gbmFtZXNwYWNlCisKKy8vIENvZGVkSW5wdXRTdHJlYW0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworQ29kZWRJbnB1dFN0cmVhbTo6fkNvZGVkSW5wdXRTdHJlYW0oKSB7CisgIGlmIChpbnB1dF8gIT0gTlVMTCkgeworICAgIEJhY2tVcElucHV0VG9DdXJyZW50UG9zaXRpb24oKTsKKyAgfQorCisgIGlmICh0b3RhbF9ieXRlc193YXJuaW5nX3RocmVzaG9sZF8gPT0gLTIpIHsKKyAgICBHT09HTEVfTE9HKFdBUk5JTkcpIDw8ICJUaGUgdG90YWwgbnVtYmVyIG9mIGJ5dGVzIHJlYWQgd2FzICIgPDwgdG90YWxfYnl0ZXNfcmVhZF87CisgIH0KK30KKworLy8gU3RhdGljLgoraW50IENvZGVkSW5wdXRTdHJlYW06OmRlZmF1bHRfcmVjdXJzaW9uX2xpbWl0XyA9IDEwMDsKKworCit2b2lkIENvZGVkT3V0cHV0U3RyZWFtOjpFbmFibGVBbGlhc2luZyhib29sIGVuYWJsZWQpIHsKKyAgYWxpYXNpbmdfZW5hYmxlZF8gPSBlbmFibGVkICYmIG91dHB1dF8tPkFsbG93c0FsaWFzaW5nKCk7Cit9CisKK3ZvaWQgQ29kZWRJbnB1dFN0cmVhbTo6QmFja1VwSW5wdXRUb0N1cnJlbnRQb3NpdGlvbigpIHsKKyAgaW50IGJhY2t1cF9ieXRlcyA9IEJ1ZmZlclNpemUoKSArIGJ1ZmZlcl9zaXplX2FmdGVyX2xpbWl0XyArIG92ZXJmbG93X2J5dGVzXzsKKyAgaWYgKGJhY2t1cF9ieXRlcyA+IDApIHsKKyAgICBpbnB1dF8tPkJhY2tVcChiYWNrdXBfYnl0ZXMpOworCisgICAgLy8gdG90YWxfYnl0ZXNfcmVhZF8gZG9lc24ndCBpbmNsdWRlIG92ZXJmbG93X2J5dGVzXy4KKyAgICB0b3RhbF9ieXRlc19yZWFkXyAtPSBCdWZmZXJTaXplKCkgKyBidWZmZXJfc2l6ZV9hZnRlcl9saW1pdF87CisgICAgYnVmZmVyX2VuZF8gPSBidWZmZXJfOworICAgIGJ1ZmZlcl9zaXplX2FmdGVyX2xpbWl0XyA9IDA7CisgICAgb3ZlcmZsb3dfYnl0ZXNfID0gMDsKKyAgfQorfQorCitpbmxpbmUgdm9pZCBDb2RlZElucHV0U3RyZWFtOjpSZWNvbXB1dGVCdWZmZXJMaW1pdHMoKSB7CisgIGJ1ZmZlcl9lbmRfICs9IGJ1ZmZlcl9zaXplX2FmdGVyX2xpbWl0XzsKKyAgaW50IGNsb3Nlc3RfbGltaXQgPSBtaW4oY3VycmVudF9saW1pdF8sIHRvdGFsX2J5dGVzX2xpbWl0Xyk7CisgIGlmIChjbG9zZXN0X2xpbWl0IDwgdG90YWxfYnl0ZXNfcmVhZF8pIHsKKyAgICAvLyBUaGUgbGltaXQgcG9zaXRpb24gaXMgaW4gdGhlIGN1cnJlbnQgYnVmZmVyLiAgV2UgbXVzdCBhZGp1c3QKKyAgICAvLyB0aGUgYnVmZmVyIHNpemUgYWNjb3JkaW5nbHkuCisgICAgYnVmZmVyX3NpemVfYWZ0ZXJfbGltaXRfID0gdG90YWxfYnl0ZXNfcmVhZF8gLSBjbG9zZXN0X2xpbWl0OworICAgIGJ1ZmZlcl9lbmRfIC09IGJ1ZmZlcl9zaXplX2FmdGVyX2xpbWl0XzsKKyAgfSBlbHNlIHsKKyAgICBidWZmZXJfc2l6ZV9hZnRlcl9saW1pdF8gPSAwOworICB9Cit9CisKK0NvZGVkSW5wdXRTdHJlYW06OkxpbWl0IENvZGVkSW5wdXRTdHJlYW06OlB1c2hMaW1pdChpbnQgYnl0ZV9saW1pdCkgeworICAvLyBDdXJyZW50IHBvc2l0aW9uIHJlbGF0aXZlIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHN0cmVhbS4KKyAgaW50IGN1cnJlbnRfcG9zaXRpb24gPSBDdXJyZW50UG9zaXRpb24oKTsKKworICBMaW1pdCBvbGRfbGltaXQgPSBjdXJyZW50X2xpbWl0XzsKKworICAvLyBzZWN1cml0eTogYnl0ZV9saW1pdCBpcyBwb3NzaWJseSBldmlsLCBzbyBjaGVjayBmb3IgbmVnYXRpdmUgdmFsdWVzCisgIC8vIGFuZCBvdmVyZmxvdy4KKyAgaWYgKGJ5dGVfbGltaXQgPj0gMCAmJgorICAgICAgYnl0ZV9saW1pdCA8PSBJTlRfTUFYIC0gY3VycmVudF9wb3NpdGlvbikgeworICAgIGN1cnJlbnRfbGltaXRfID0gY3VycmVudF9wb3NpdGlvbiArIGJ5dGVfbGltaXQ7CisgIH0gZWxzZSB7CisgICAgLy8gTmVnYXRpdmUgb3Igb3ZlcmZsb3cuCisgICAgY3VycmVudF9saW1pdF8gPSBJTlRfTUFYOworICB9CisKKyAgLy8gV2UgbmVlZCB0byBlbmZvcmNlIGFsbCBsaW1pdHMsIG5vdCBqdXN0IHRoZSBuZXcgb25lLCBzbyBpZiB0aGUgcHJldmlvdXMKKyAgLy8gbGltaXQgd2FzIGJlZm9yZSB0aGUgbmV3IHJlcXVlc3RlZCBsaW1pdCwgd2UgY29udGludWUgdG8gZW5mb3JjZSB0aGUKKyAgLy8gcHJldmlvdXMgbGltaXQuCisgIGN1cnJlbnRfbGltaXRfID0gbWluKGN1cnJlbnRfbGltaXRfLCBvbGRfbGltaXQpOworCisgIFJlY29tcHV0ZUJ1ZmZlckxpbWl0cygpOworICByZXR1cm4gb2xkX2xpbWl0OworfQorCit2b2lkIENvZGVkSW5wdXRTdHJlYW06OlBvcExpbWl0KExpbWl0IGxpbWl0KSB7CisgIC8vIFRoZSBsaW1pdCBwYXNzZWQgaW4gaXMgYWN0dWFsbHkgdGhlICpvbGQqIGxpbWl0LCB3aGljaCB3ZSByZXR1cm5lZCBmcm9tCisgIC8vIFB1c2hMaW1pdCgpLgorICBjdXJyZW50X2xpbWl0XyA9IGxpbWl0OworICBSZWNvbXB1dGVCdWZmZXJMaW1pdHMoKTsKKworICAvLyBXZSBtYXkgbm8gbG9uZ2VyIGJlIGF0IGEgbGVnaXRpbWF0ZSBtZXNzYWdlIGVuZC4gIFJlYWRUYWcoKSBuZWVkcyB0byBiZQorICAvLyBjYWxsZWQgYWdhaW4gdG8gZmluZCBvdXQuCisgIGxlZ2l0aW1hdGVfbWVzc2FnZV9lbmRfID0gZmFsc2U7Cit9CisKK3N0ZDo6cGFpcjxDb2RlZElucHV0U3RyZWFtOjpMaW1pdCwgaW50PgorQ29kZWRJbnB1dFN0cmVhbTo6SW5jcmVtZW50UmVjdXJzaW9uRGVwdGhBbmRQdXNoTGltaXQoaW50IGJ5dGVfbGltaXQpIHsKKyAgcmV0dXJuIHN0ZDo6bWFrZV9wYWlyKFB1c2hMaW1pdChieXRlX2xpbWl0KSwgLS1yZWN1cnNpb25fYnVkZ2V0Xyk7Cit9CisKK0NvZGVkSW5wdXRTdHJlYW06OkxpbWl0IENvZGVkSW5wdXRTdHJlYW06OlJlYWRMZW5ndGhBbmRQdXNoTGltaXQoKSB7CisgIHVpbnQzMiBsZW5ndGg7CisgIHJldHVybiBQdXNoTGltaXQoUmVhZFZhcmludDMyKCZsZW5ndGgpID8gbGVuZ3RoIDogMCk7Cit9CisKK2Jvb2wgQ29kZWRJbnB1dFN0cmVhbTo6RGVjcmVtZW50UmVjdXJzaW9uRGVwdGhBbmRQb3BMaW1pdChMaW1pdCBsaW1pdCkgeworICBib29sIHJlc3VsdCA9IENvbnN1bWVkRW50aXJlTWVzc2FnZSgpOworICBQb3BMaW1pdChsaW1pdCk7CisgIEdPT0dMRV9EQ0hFQ0tfTFQocmVjdXJzaW9uX2J1ZGdldF8sIHJlY3Vyc2lvbl9saW1pdF8pOworICArK3JlY3Vyc2lvbl9idWRnZXRfOworICByZXR1cm4gcmVzdWx0OworfQorCitib29sIENvZGVkSW5wdXRTdHJlYW06OkNoZWNrRW50aXJlTWVzc2FnZUNvbnN1bWVkQW5kUG9wTGltaXQoTGltaXQgbGltaXQpIHsKKyAgYm9vbCByZXN1bHQgPSBDb25zdW1lZEVudGlyZU1lc3NhZ2UoKTsKKyAgUG9wTGltaXQobGltaXQpOworICByZXR1cm4gcmVzdWx0OworfQorCitpbnQgQ29kZWRJbnB1dFN0cmVhbTo6Qnl0ZXNVbnRpbExpbWl0KCkgY29uc3QgeworICBpZiAoY3VycmVudF9saW1pdF8gPT0gSU5UX01BWCkgcmV0dXJuIC0xOworICBpbnQgY3VycmVudF9wb3NpdGlvbiA9IEN1cnJlbnRQb3NpdGlvbigpOworCisgIHJldHVybiBjdXJyZW50X2xpbWl0XyAtIGN1cnJlbnRfcG9zaXRpb247Cit9CisKK3ZvaWQgQ29kZWRJbnB1dFN0cmVhbTo6U2V0VG90YWxCeXRlc0xpbWl0KAorICAgIGludCB0b3RhbF9ieXRlc19saW1pdCwgaW50IHdhcm5pbmdfdGhyZXNob2xkKSB7CisgIC8vIE1ha2Ugc3VyZSB0aGUgbGltaXQgaXNuJ3QgYWxyZWFkeSBwYXN0LCBzaW5jZSB0aGlzIGNvdWxkIGNvbmZ1c2Ugb3RoZXIKKyAgLy8gY29kZS4KKyAgaW50IGN1cnJlbnRfcG9zaXRpb24gPSBDdXJyZW50UG9zaXRpb24oKTsKKyAgdG90YWxfYnl0ZXNfbGltaXRfID0gbWF4KGN1cnJlbnRfcG9zaXRpb24sIHRvdGFsX2J5dGVzX2xpbWl0KTsKKyAgaWYgKHdhcm5pbmdfdGhyZXNob2xkID49IDApIHsKKyAgICB0b3RhbF9ieXRlc193YXJuaW5nX3RocmVzaG9sZF8gPSB3YXJuaW5nX3RocmVzaG9sZDsKKyAgfSBlbHNlIHsKKyAgICAvLyB3YXJuaW5nX3RocmVzaG9sZCBpcyBuZWdhdGl2ZQorICAgIHRvdGFsX2J5dGVzX3dhcm5pbmdfdGhyZXNob2xkXyA9IC0xOworICB9CisgIFJlY29tcHV0ZUJ1ZmZlckxpbWl0cygpOworfQorCitpbnQgQ29kZWRJbnB1dFN0cmVhbTo6Qnl0ZXNVbnRpbFRvdGFsQnl0ZXNMaW1pdCgpIGNvbnN0IHsKKyAgaWYgKHRvdGFsX2J5dGVzX2xpbWl0XyA9PSBJTlRfTUFYKSByZXR1cm4gLTE7CisgIHJldHVybiB0b3RhbF9ieXRlc19saW1pdF8gLSBDdXJyZW50UG9zaXRpb24oKTsKK30KKwordm9pZCBDb2RlZElucHV0U3RyZWFtOjpQcmludFRvdGFsQnl0ZXNMaW1pdEVycm9yKCkgeworICBHT09HTEVfTE9HKEVSUk9SKSA8PCAiQSBwcm90b2NvbCBtZXNzYWdlIHdhcyByZWplY3RlZCBiZWNhdXNlIGl0IHdhcyB0b28gIgorICAgICAgICAgICAgICAgICJiaWcgKG1vcmUgdGhhbiAiIDw8IHRvdGFsX2J5dGVzX2xpbWl0XworICAgICAgICAgICAgIDw8ICIgYnl0ZXMpLiAgVG8gaW5jcmVhc2UgdGhlIGxpbWl0IChvciB0byBkaXNhYmxlIHRoZXNlICIKKyAgICAgICAgICAgICAgICAid2FybmluZ3MpLCBzZWUgQ29kZWRJbnB1dFN0cmVhbTo6U2V0VG90YWxCeXRlc0xpbWl0KCkgIgorICAgICAgICAgICAgICAgICJpbiBnb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmguIjsKK30KKworYm9vbCBDb2RlZElucHV0U3RyZWFtOjpTa2lwKGludCBjb3VudCkgeworICBpZiAoY291bnQgPCAwKSByZXR1cm4gZmFsc2U7ICAvLyBzZWN1cml0eTogY291bnQgaXMgb2Z0ZW4gdXNlci1zdXBwbGllZAorCisgIGNvbnN0IGludCBvcmlnaW5hbF9idWZmZXJfc2l6ZSA9IEJ1ZmZlclNpemUoKTsKKworICBpZiAoY291bnQgPD0gb3JpZ2luYWxfYnVmZmVyX3NpemUpIHsKKyAgICAvLyBKdXN0IHNraXBwaW5nIHdpdGhpbiB0aGUgY3VycmVudCBidWZmZXIuICBFYXN5LgorICAgIEFkdmFuY2UoY291bnQpOworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgaWYgKGJ1ZmZlcl9zaXplX2FmdGVyX2xpbWl0XyA+IDApIHsKKyAgICAvLyBXZSBoaXQgYSBsaW1pdCBpbnNpZGUgdGhpcyBidWZmZXIuICBBZHZhbmNlIHRvIHRoZSBsaW1pdCBhbmQgZmFpbC4KKyAgICBBZHZhbmNlKG9yaWdpbmFsX2J1ZmZlcl9zaXplKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBjb3VudCAtPSBvcmlnaW5hbF9idWZmZXJfc2l6ZTsKKyAgYnVmZmVyXyA9IE5VTEw7CisgIGJ1ZmZlcl9lbmRfID0gYnVmZmVyXzsKKworICAvLyBNYWtlIHN1cmUgdGhpcyBza2lwIGRvZXNuJ3QgdHJ5IHRvIHNraXAgcGFzdCB0aGUgY3VycmVudCBsaW1pdC4KKyAgaW50IGNsb3Nlc3RfbGltaXQgPSBtaW4oY3VycmVudF9saW1pdF8sIHRvdGFsX2J5dGVzX2xpbWl0Xyk7CisgIGludCBieXRlc191bnRpbF9saW1pdCA9IGNsb3Nlc3RfbGltaXQgLSB0b3RhbF9ieXRlc19yZWFkXzsKKyAgaWYgKGJ5dGVzX3VudGlsX2xpbWl0IDwgY291bnQpIHsKKyAgICAvLyBXZSBoaXQgdGhlIGxpbWl0LiAgU2tpcCB1cCB0byBpdCB0aGVuIGZhaWwuCisgICAgaWYgKGJ5dGVzX3VudGlsX2xpbWl0ID4gMCkgeworICAgICAgdG90YWxfYnl0ZXNfcmVhZF8gPSBjbG9zZXN0X2xpbWl0OworICAgICAgaW5wdXRfLT5Ta2lwKGJ5dGVzX3VudGlsX2xpbWl0KTsKKyAgICB9CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgdG90YWxfYnl0ZXNfcmVhZF8gKz0gY291bnQ7CisgIHJldHVybiBpbnB1dF8tPlNraXAoY291bnQpOworfQorCitib29sIENvZGVkSW5wdXRTdHJlYW06OkdldERpcmVjdEJ1ZmZlclBvaW50ZXIoY29uc3Qgdm9pZCoqIGRhdGEsIGludCogc2l6ZSkgeworICBpZiAoQnVmZmVyU2l6ZSgpID09IDAgJiYgIVJlZnJlc2goKSkgcmV0dXJuIGZhbHNlOworCisgICpkYXRhID0gYnVmZmVyXzsKKyAgKnNpemUgPSBCdWZmZXJTaXplKCk7CisgIHJldHVybiB0cnVlOworfQorCitib29sIENvZGVkSW5wdXRTdHJlYW06OlJlYWRSYXcodm9pZCogYnVmZmVyLCBpbnQgc2l6ZSkgeworICByZXR1cm4gSW50ZXJuYWxSZWFkUmF3SW5saW5lKGJ1ZmZlciwgc2l6ZSk7Cit9CisKK2Jvb2wgQ29kZWRJbnB1dFN0cmVhbTo6UmVhZFN0cmluZyhzdHJpbmcqIGJ1ZmZlciwgaW50IHNpemUpIHsKKyAgaWYgKHNpemUgPCAwKSByZXR1cm4gZmFsc2U7ICAvLyBzZWN1cml0eTogc2l6ZSBpcyBvZnRlbiB1c2VyLXN1cHBsaWVkCisgIHJldHVybiBJbnRlcm5hbFJlYWRTdHJpbmdJbmxpbmUoYnVmZmVyLCBzaXplKTsKK30KKworYm9vbCBDb2RlZElucHV0U3RyZWFtOjpSZWFkU3RyaW5nRmFsbGJhY2soc3RyaW5nKiBidWZmZXIsIGludCBzaXplKSB7CisgIGlmICghYnVmZmVyLT5lbXB0eSgpKSB7CisgICAgYnVmZmVyLT5jbGVhcigpOworICB9CisKKyAgaW50IGNsb3Nlc3RfbGltaXQgPSBtaW4oY3VycmVudF9saW1pdF8sIHRvdGFsX2J5dGVzX2xpbWl0Xyk7CisgIGlmIChjbG9zZXN0X2xpbWl0ICE9IElOVF9NQVgpIHsKKyAgICBpbnQgYnl0ZXNfdG9fbGltaXQgPSBjbG9zZXN0X2xpbWl0IC0gQ3VycmVudFBvc2l0aW9uKCk7CisgICAgaWYgKGJ5dGVzX3RvX2xpbWl0ID4gMCAmJiBzaXplID4gMCAmJiBzaXplIDw9IGJ5dGVzX3RvX2xpbWl0KSB7CisgICAgICBidWZmZXItPnJlc2VydmUoc2l6ZSk7CisgICAgfQorICB9CisKKyAgaW50IGN1cnJlbnRfYnVmZmVyX3NpemU7CisgIHdoaWxlICgoY3VycmVudF9idWZmZXJfc2l6ZSA9IEJ1ZmZlclNpemUoKSkgPCBzaXplKSB7CisgICAgLy8gU29tZSBTVEwgaW1wbGVtZW50YXRpb25zICJoZWxwZnVsbHkiIGNyYXNoIG9uIGJ1ZmZlci0+YXBwZW5kKE5VTEwsIDApLgorICAgIGlmIChjdXJyZW50X2J1ZmZlcl9zaXplICE9IDApIHsKKyAgICAgIC8vIE5vdGU6ICBzdHJpbmcxLmFwcGVuZChzdHJpbmcyKSBpcyBPKHN0cmluZzIuc2l6ZSgpKSAoYXMgb3Bwb3NlZCB0bworICAgICAgLy8gICBPKHN0cmluZzEuc2l6ZSgpICsgc3RyaW5nMi5zaXplKCkpLCB3aGljaCB3b3VsZCBiZSBiYWQpLgorICAgICAgYnVmZmVyLT5hcHBlbmQocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4oYnVmZmVyXyksCisgICAgICAgICAgICAgICAgICAgICBjdXJyZW50X2J1ZmZlcl9zaXplKTsKKyAgICB9CisgICAgc2l6ZSAtPSBjdXJyZW50X2J1ZmZlcl9zaXplOworICAgIEFkdmFuY2UoY3VycmVudF9idWZmZXJfc2l6ZSk7CisgICAgaWYgKCFSZWZyZXNoKCkpIHJldHVybiBmYWxzZTsKKyAgfQorCisgIGJ1ZmZlci0+YXBwZW5kKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KGJ1ZmZlcl8pLCBzaXplKTsKKyAgQWR2YW5jZShzaXplKTsKKworICByZXR1cm4gdHJ1ZTsKK30KKworCitib29sIENvZGVkSW5wdXRTdHJlYW06OlJlYWRMaXR0bGVFbmRpYW4zMkZhbGxiYWNrKHVpbnQzMiogdmFsdWUpIHsKKyAgdWludDggYnl0ZXNbc2l6ZW9mKCp2YWx1ZSldOworCisgIGNvbnN0IHVpbnQ4KiBwdHI7CisgIGlmIChCdWZmZXJTaXplKCkgPj0gc2l6ZW9mKCp2YWx1ZSkpIHsKKyAgICAvLyBGYXN0IHBhdGg6ICBFbm91Z2ggYnl0ZXMgaW4gdGhlIGJ1ZmZlciB0byByZWFkIGRpcmVjdGx5LgorICAgIHB0ciA9IGJ1ZmZlcl87CisgICAgQWR2YW5jZShzaXplb2YoKnZhbHVlKSk7CisgIH0gZWxzZSB7CisgICAgLy8gU2xvdyBwYXRoOiAgSGFkIHRvIHJlYWQgcGFzdCB0aGUgZW5kIG9mIHRoZSBidWZmZXIuCisgICAgaWYgKCFSZWFkUmF3KGJ5dGVzLCBzaXplb2YoKnZhbHVlKSkpIHJldHVybiBmYWxzZTsKKyAgICBwdHIgPSBieXRlczsKKyAgfQorICBSZWFkTGl0dGxlRW5kaWFuMzJGcm9tQXJyYXkocHRyLCB2YWx1ZSk7CisgIHJldHVybiB0cnVlOworfQorCitib29sIENvZGVkSW5wdXRTdHJlYW06OlJlYWRMaXR0bGVFbmRpYW42NEZhbGxiYWNrKHVpbnQ2NCogdmFsdWUpIHsKKyAgdWludDggYnl0ZXNbc2l6ZW9mKCp2YWx1ZSldOworCisgIGNvbnN0IHVpbnQ4KiBwdHI7CisgIGlmIChCdWZmZXJTaXplKCkgPj0gc2l6ZW9mKCp2YWx1ZSkpIHsKKyAgICAvLyBGYXN0IHBhdGg6ICBFbm91Z2ggYnl0ZXMgaW4gdGhlIGJ1ZmZlciB0byByZWFkIGRpcmVjdGx5LgorICAgIHB0ciA9IGJ1ZmZlcl87CisgICAgQWR2YW5jZShzaXplb2YoKnZhbHVlKSk7CisgIH0gZWxzZSB7CisgICAgLy8gU2xvdyBwYXRoOiAgSGFkIHRvIHJlYWQgcGFzdCB0aGUgZW5kIG9mIHRoZSBidWZmZXIuCisgICAgaWYgKCFSZWFkUmF3KGJ5dGVzLCBzaXplb2YoKnZhbHVlKSkpIHJldHVybiBmYWxzZTsKKyAgICBwdHIgPSBieXRlczsKKyAgfQorICBSZWFkTGl0dGxlRW5kaWFuNjRGcm9tQXJyYXkocHRyLCB2YWx1ZSk7CisgIHJldHVybiB0cnVlOworfQorCituYW1lc3BhY2UgeworCisvLyBSZWFkIGEgdmFyaW50IGZyb20gdGhlIGdpdmVuIGJ1ZmZlciwgd3JpdGUgaXQgdG8gKnZhbHVlLCBhbmQgcmV0dXJuIGEgcGFpci4KKy8vIFRoZSBmaXJzdCBwYXJ0IG9mIHRoZSBwYWlyIGlzIHRydWUgaWZmIHRoZSByZWFkIHdhcyBzdWNjZXNzZnVsLiAgVGhlIHNlY29uZAorLy8gcGFydCBpcyBidWZmZXIgKyAobnVtYmVyIG9mIGJ5dGVzIHJlYWQpLiAgVGhpcyBmdW5jdGlvbiBpcyBhbHdheXMgaW5saW5lZCwKKy8vIHNvIHJldHVybmluZyBhIHBhaXIgaXMgY29zdGxlc3MuCitHT09HTEVfQVRUUklCVVRFX0FMV0FZU19JTkxJTkUgOjpzdGQ6OnBhaXI8Ym9vbCwgY29uc3QgdWludDgqPiBSZWFkVmFyaW50MzJGcm9tQXJyYXkoCisgICAgdWludDMyIGZpcnN0X2J5dGUsIGNvbnN0IHVpbnQ4KiBidWZmZXIsCisgICAgdWludDMyKiB2YWx1ZSk7CitpbmxpbmUgOjpzdGQ6OnBhaXI8Ym9vbCwgY29uc3QgdWludDgqPiBSZWFkVmFyaW50MzJGcm9tQXJyYXkoCisgICAgdWludDMyIGZpcnN0X2J5dGUsIGNvbnN0IHVpbnQ4KiBidWZmZXIsIHVpbnQzMiogdmFsdWUpIHsKKyAgLy8gRmFzdCBwYXRoOiAgV2UgaGF2ZSBlbm91Z2ggYnl0ZXMgbGVmdCBpbiB0aGUgYnVmZmVyIHRvIGd1YXJhbnRlZSB0aGF0CisgIC8vIHRoaXMgcmVhZCB3b24ndCBjcm9zcyB0aGUgZW5kLCBzbyB3ZSBjYW4gc2tpcCB0aGUgY2hlY2tzLgorICBHT09HTEVfRENIRUNLX0VRKCpidWZmZXIsIGZpcnN0X2J5dGUpOworICBHT09HTEVfRENIRUNLX0VRKGZpcnN0X2J5dGUgJiAweDgwLCAweDgwKSA8PCBmaXJzdF9ieXRlOworICBjb25zdCB1aW50OCogcHRyID0gYnVmZmVyOworICB1aW50MzIgYjsKKyAgdWludDMyIHJlc3VsdCA9IGZpcnN0X2J5dGUgLSAweDgwOworICArK3B0cjsgIC8vIFdlIGp1c3QgcHJvY2Vzc2VkIHRoZSBmaXJzdCBieXRlLiAgTW92ZSBvbiB0byB0aGUgc2Vjb25kLgorICBiID0gKihwdHIrKyk7IHJlc3VsdCArPSBiIDw8ICA3OyBpZiAoIShiICYgMHg4MCkpIGdvdG8gZG9uZTsKKyAgcmVzdWx0IC09IDB4ODAgPDwgNzsKKyAgYiA9ICoocHRyKyspOyByZXN1bHQgKz0gYiA8PCAxNDsgaWYgKCEoYiAmIDB4ODApKSBnb3RvIGRvbmU7CisgIHJlc3VsdCAtPSAweDgwIDw8IDE0OworICBiID0gKihwdHIrKyk7IHJlc3VsdCArPSBiIDw8IDIxOyBpZiAoIShiICYgMHg4MCkpIGdvdG8gZG9uZTsKKyAgcmVzdWx0IC09IDB4ODAgPDwgMjE7CisgIGIgPSAqKHB0cisrKTsgcmVzdWx0ICs9IGIgPDwgMjg7IGlmICghKGIgJiAweDgwKSkgZ290byBkb25lOworICAvLyAicmVzdWx0IC09IDB4ODAgPDwgMjgiIGlzIGlycmV2ZWxhbnQuCisKKyAgLy8gSWYgdGhlIGlucHV0IGlzIGxhcmdlciB0aGFuIDMyIGJpdHMsIHdlIHN0aWxsIG5lZWQgdG8gcmVhZCBpdCBhbGwKKyAgLy8gYW5kIGRpc2NhcmQgdGhlIGhpZ2gtb3JkZXIgYml0cy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBrTWF4VmFyaW50Qnl0ZXMgLSBrTWF4VmFyaW50MzJCeXRlczsgaSsrKSB7CisgICAgYiA9ICoocHRyKyspOyBpZiAoIShiICYgMHg4MCkpIGdvdG8gZG9uZTsKKyAgfQorCisgIC8vIFdlIGhhdmUgb3ZlcnJ1biB0aGUgbWF4aW11bSBzaXplIG9mIGEgdmFyaW50ICgxMCBieXRlcykuICBBc3N1bWUKKyAgLy8gdGhlIGRhdGEgaXMgY29ycnVwdC4KKyAgcmV0dXJuIHN0ZDo6bWFrZV9wYWlyKGZhbHNlLCBwdHIpOworCisgZG9uZToKKyAgKnZhbHVlID0gcmVzdWx0OworICByZXR1cm4gc3RkOjptYWtlX3BhaXIodHJ1ZSwgcHRyKTsKK30KKworfSAgLy8gbmFtZXNwYWNlCisKK2Jvb2wgQ29kZWRJbnB1dFN0cmVhbTo6UmVhZFZhcmludDMyU2xvdyh1aW50MzIqIHZhbHVlKSB7CisgIC8vIERpcmVjdGx5IGludm9rZSBSZWFkVmFyaW50NjRGYWxsYmFjaywgc2luY2Ugd2UgYWxyZWFkeSB0cmllZCB0byBvcHRpbWl6ZQorICAvLyBmb3Igb25lLWJ5dGUgdmFyaW50cy4KKyAgc3RkOjpwYWlyPHVpbnQ2NCwgYm9vbD4gcCA9IFJlYWRWYXJpbnQ2NEZhbGxiYWNrKCk7CisgICp2YWx1ZSA9IHN0YXRpY19jYXN0PHVpbnQzMj4ocC5maXJzdCk7CisgIHJldHVybiBwLnNlY29uZDsKK30KKworaW50NjQgQ29kZWRJbnB1dFN0cmVhbTo6UmVhZFZhcmludDMyRmFsbGJhY2sodWludDMyIGZpcnN0X2J5dGVfb3JfemVybykgeworICBpZiAoQnVmZmVyU2l6ZSgpID49IGtNYXhWYXJpbnRCeXRlcyB8fAorICAgICAgLy8gT3B0aW1pemF0aW9uOiAgV2UncmUgYWxzbyBzYWZlIGlmIHRoZSBidWZmZXIgaXMgbm9uLWVtcHR5IGFuZCBpdCBlbmRzCisgICAgICAvLyB3aXRoIGEgYnl0ZSB0aGF0IHdvdWxkIHRlcm1pbmF0ZSBhIHZhcmludC4KKyAgICAgIChidWZmZXJfZW5kXyA+IGJ1ZmZlcl8gJiYgIShidWZmZXJfZW5kX1stMV0gJiAweDgwKSkpIHsKKyAgICBHT09HTEVfRENIRUNLX05FKGZpcnN0X2J5dGVfb3JfemVybywgMCkKKyAgICAgICAgPDwgIkNhbGxlciBzaG91bGQgcHJvdmlkZSB1cyB3aXRoICpidWZmZXJfIHdoZW4gYnVmZmVyIGlzIG5vbi1lbXB0eSI7CisgICAgdWludDMyIHRlbXA7CisgICAgOjpzdGQ6OnBhaXI8Ym9vbCwgY29uc3QgdWludDgqPiBwID0KKyAgICAgICAgICBSZWFkVmFyaW50MzJGcm9tQXJyYXkoZmlyc3RfYnl0ZV9vcl96ZXJvLCBidWZmZXJfLCAmdGVtcCk7CisgICAgaWYgKCFwLmZpcnN0KSByZXR1cm4gLTE7CisgICAgYnVmZmVyXyA9IHAuc2Vjb25kOworICAgIHJldHVybiB0ZW1wOworICB9IGVsc2UgeworICAgIC8vIFJlYWxseSBzbG93IGNhc2U6IHdlIHdpbGwgaW5jdXIgdGhlIGNvc3Qgb2YgYW4gZXh0cmEgZnVuY3Rpb24gY2FsbCBoZXJlLAorICAgIC8vIGJ1dCBtb3ZpbmcgdGhpcyBvdXQgb2YgbGluZSByZWR1Y2VzIHRoZSBzaXplIG9mIHRoaXMgZnVuY3Rpb24sIHdoaWNoCisgICAgLy8gaW1wcm92ZXMgdGhlIGNvbW1vbiBjYXNlLiBJbiBtaWNybyBiZW5jaG1hcmtzLCB0aGlzIGlzIHdvcnRoIGFib3V0IDEwLTE1JQorICAgIHVpbnQzMiB0ZW1wOworICAgIHJldHVybiBSZWFkVmFyaW50MzJTbG93KCZ0ZW1wKSA/IHN0YXRpY19jYXN0PGludDY0Pih0ZW1wKSA6IC0xOworICB9Cit9CisKK3VpbnQzMiBDb2RlZElucHV0U3RyZWFtOjpSZWFkVGFnU2xvdygpIHsKKyAgaWYgKGJ1ZmZlcl8gPT0gYnVmZmVyX2VuZF8pIHsKKyAgICAvLyBDYWxsIHJlZnJlc2guCisgICAgaWYgKCFSZWZyZXNoKCkpIHsKKyAgICAgIC8vIFJlZnJlc2ggZmFpbGVkLiAgTWFrZSBzdXJlIHRoYXQgaXQgZmFpbGVkIGR1ZSB0byBFT0YsIG5vdCBiZWNhdXNlCisgICAgICAvLyB3ZSBoaXQgdG90YWxfYnl0ZXNfbGltaXRfLCB3aGljaCwgdW5saWtlIG5vcm1hbCBsaW1pdHMsIGlzIG5vdCBhCisgICAgICAvLyB2YWxpZCBwbGFjZSB0byBlbmQgYSBtZXNzYWdlLgorICAgICAgaW50IGN1cnJlbnRfcG9zaXRpb24gPSB0b3RhbF9ieXRlc19yZWFkXyAtIGJ1ZmZlcl9zaXplX2FmdGVyX2xpbWl0XzsKKyAgICAgIGlmIChjdXJyZW50X3Bvc2l0aW9uID49IHRvdGFsX2J5dGVzX2xpbWl0XykgeworICAgICAgICAvLyBIaXQgdG90YWxfYnl0ZXNfbGltaXRfLiAgQnV0IGlmIHdlIGFsc28gaGl0IHRoZSBub3JtYWwgbGltaXQsCisgICAgICAgIC8vIHdlJ3JlIHN0aWxsIE9LLgorICAgICAgICBsZWdpdGltYXRlX21lc3NhZ2VfZW5kXyA9IGN1cnJlbnRfbGltaXRfID09IHRvdGFsX2J5dGVzX2xpbWl0XzsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGxlZ2l0aW1hdGVfbWVzc2FnZV9lbmRfID0gdHJ1ZTsKKyAgICAgIH0KKyAgICAgIHJldHVybiAwOworICAgIH0KKyAgfQorCisgIC8vIEZvciB0aGUgc2xvdyBwYXRoLCBqdXN0IGRvIGEgNjQtYml0IHJlYWQuIFRyeSB0byBvcHRpbWl6ZSBmb3Igb25lLWJ5dGUgdGFncworICAvLyBhZ2Fpbiwgc2luY2Ugd2UgaGF2ZSBub3cgcmVmcmVzaGVkIHRoZSBidWZmZXIuCisgIHVpbnQ2NCByZXN1bHQgPSAwOworICBpZiAoIVJlYWRWYXJpbnQ2NCgmcmVzdWx0KSkgcmV0dXJuIDA7CisgIHJldHVybiBzdGF0aWNfY2FzdDx1aW50MzI+KHJlc3VsdCk7Cit9CisKK3VpbnQzMiBDb2RlZElucHV0U3RyZWFtOjpSZWFkVGFnRmFsbGJhY2sodWludDMyIGZpcnN0X2J5dGVfb3JfemVybykgeworICBjb25zdCBpbnQgYnVmX3NpemUgPSBCdWZmZXJTaXplKCk7CisgIGlmIChidWZfc2l6ZSA+PSBrTWF4VmFyaW50Qnl0ZXMgfHwKKyAgICAgIC8vIE9wdGltaXphdGlvbjogIFdlJ3JlIGFsc28gc2FmZSBpZiB0aGUgYnVmZmVyIGlzIG5vbi1lbXB0eSBhbmQgaXQgZW5kcworICAgICAgLy8gd2l0aCBhIGJ5dGUgdGhhdCB3b3VsZCB0ZXJtaW5hdGUgYSB2YXJpbnQuCisgICAgICAoYnVmX3NpemUgPiAwICYmICEoYnVmZmVyX2VuZF9bLTFdICYgMHg4MCkpKSB7CisgICAgR09PR0xFX0RDSEVDS19FUShmaXJzdF9ieXRlX29yX3plcm8sIGJ1ZmZlcl9bMF0pOworICAgIGlmIChmaXJzdF9ieXRlX29yX3plcm8gPT0gMCkgeworICAgICAgKytidWZmZXJfOworICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIHVpbnQzMiB0YWc7CisgICAgOjpzdGQ6OnBhaXI8Ym9vbCwgY29uc3QgdWludDgqPiBwID0KKyAgICAgICAgUmVhZFZhcmludDMyRnJvbUFycmF5KGZpcnN0X2J5dGVfb3JfemVybywgYnVmZmVyXywgJnRhZyk7CisgICAgaWYgKCFwLmZpcnN0KSB7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgYnVmZmVyXyA9IHAuc2Vjb25kOworICAgIHJldHVybiB0YWc7CisgIH0gZWxzZSB7CisgICAgLy8gV2UgYXJlIGNvbW1vbmx5IGF0IGEgbGltaXQgd2hlbiBhdHRlbXB0aW5nIHRvIHJlYWQgdGFncy4gVHJ5IHRvIHF1aWNrbHkKKyAgICAvLyBkZXRlY3QgdGhpcyBjYXNlIHdpdGhvdXQgbWFraW5nIGFub3RoZXIgZnVuY3Rpb24gY2FsbC4KKyAgICBpZiAoKGJ1Zl9zaXplID09IDApICYmCisgICAgICAgICgoYnVmZmVyX3NpemVfYWZ0ZXJfbGltaXRfID4gMCkgfHwKKyAgICAgICAgICh0b3RhbF9ieXRlc19yZWFkXyA9PSBjdXJyZW50X2xpbWl0XykpICYmCisgICAgICAgIC8vIE1ha2Ugc3VyZSB0aGF0IHRoZSBsaW1pdCB3ZSBoaXQgaXMgbm90IHRvdGFsX2J5dGVzX2xpbWl0Xywgc2luY2UKKyAgICAgICAgLy8gaW4gdGhhdCBjYXNlIHdlIHN0aWxsIG5lZWQgdG8gY2FsbCBSZWZyZXNoKCkgc28gdGhhdCBpdCBwcmludHMgYW4KKyAgICAgICAgLy8gZXJyb3IuCisgICAgICAgIHRvdGFsX2J5dGVzX3JlYWRfIC0gYnVmZmVyX3NpemVfYWZ0ZXJfbGltaXRfIDwgdG90YWxfYnl0ZXNfbGltaXRfKSB7CisgICAgICAvLyBXZSBoaXQgYSBieXRlIGxpbWl0LgorICAgICAgbGVnaXRpbWF0ZV9tZXNzYWdlX2VuZF8gPSB0cnVlOworICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIHJldHVybiBSZWFkVGFnU2xvdygpOworICB9Cit9CisKK2Jvb2wgQ29kZWRJbnB1dFN0cmVhbTo6UmVhZFZhcmludDY0U2xvdyh1aW50NjQqIHZhbHVlKSB7CisgIC8vIFNsb3cgcGF0aDogIFRoaXMgcmVhZCBtaWdodCBjcm9zcyB0aGUgZW5kIG9mIHRoZSBidWZmZXIsIHNvIHdlCisgIC8vIG5lZWQgdG8gY2hlY2sgYW5kIHJlZnJlc2ggdGhlIGJ1ZmZlciBpZiBhbmQgd2hlbiBpdCBkb2VzLgorCisgIHVpbnQ2NCByZXN1bHQgPSAwOworICBpbnQgY291bnQgPSAwOworICB1aW50MzIgYjsKKworICBkbyB7CisgICAgaWYgKGNvdW50ID09IGtNYXhWYXJpbnRCeXRlcykgcmV0dXJuIGZhbHNlOworICAgIHdoaWxlIChidWZmZXJfID09IGJ1ZmZlcl9lbmRfKSB7CisgICAgICBpZiAoIVJlZnJlc2goKSkgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBiID0gKmJ1ZmZlcl87CisgICAgcmVzdWx0IHw9IHN0YXRpY19jYXN0PHVpbnQ2ND4oYiAmIDB4N0YpIDw8ICg3ICogY291bnQpOworICAgIEFkdmFuY2UoMSk7CisgICAgKytjb3VudDsKKyAgfSB3aGlsZSAoYiAmIDB4ODApOworCisgICp2YWx1ZSA9IHJlc3VsdDsKKyAgcmV0dXJuIHRydWU7Cit9CisKK3N0ZDo6cGFpcjx1aW50NjQsIGJvb2w+IENvZGVkSW5wdXRTdHJlYW06OlJlYWRWYXJpbnQ2NEZhbGxiYWNrKCkgeworICBpZiAoQnVmZmVyU2l6ZSgpID49IGtNYXhWYXJpbnRCeXRlcyB8fAorICAgICAgLy8gT3B0aW1pemF0aW9uOiAgV2UncmUgYWxzbyBzYWZlIGlmIHRoZSBidWZmZXIgaXMgbm9uLWVtcHR5IGFuZCBpdCBlbmRzCisgICAgICAvLyB3aXRoIGEgYnl0ZSB0aGF0IHdvdWxkIHRlcm1pbmF0ZSBhIHZhcmludC4KKyAgICAgIChidWZmZXJfZW5kXyA+IGJ1ZmZlcl8gJiYgIShidWZmZXJfZW5kX1stMV0gJiAweDgwKSkpIHsKKyAgICAvLyBGYXN0IHBhdGg6ICBXZSBoYXZlIGVub3VnaCBieXRlcyBsZWZ0IGluIHRoZSBidWZmZXIgdG8gZ3VhcmFudGVlIHRoYXQKKyAgICAvLyB0aGlzIHJlYWQgd29uJ3QgY3Jvc3MgdGhlIGVuZCwgc28gd2UgY2FuIHNraXAgdGhlIGNoZWNrcy4KKworICAgIGNvbnN0IHVpbnQ4KiBwdHIgPSBidWZmZXJfOworICAgIHVpbnQzMiBiOworCisgICAgLy8gU3BsaXR0aW5nIGludG8gMzItYml0IHBpZWNlcyBnaXZlcyBiZXR0ZXIgcGVyZm9ybWFuY2Ugb24gMzItYml0CisgICAgLy8gcHJvY2Vzc29ycy4KKyAgICB1aW50MzIgcGFydDAgPSAwLCBwYXJ0MSA9IDAsIHBhcnQyID0gMDsKKworICAgIGIgPSAqKHB0cisrKTsgcGFydDAgID0gYiAgICAgIDsgaWYgKCEoYiAmIDB4ODApKSBnb3RvIGRvbmU7CisgICAgcGFydDAgLT0gMHg4MDsKKyAgICBiID0gKihwdHIrKyk7IHBhcnQwICs9IGIgPDwgIDc7IGlmICghKGIgJiAweDgwKSkgZ290byBkb25lOworICAgIHBhcnQwIC09IDB4ODAgPDwgNzsKKyAgICBiID0gKihwdHIrKyk7IHBhcnQwICs9IGIgPDwgMTQ7IGlmICghKGIgJiAweDgwKSkgZ290byBkb25lOworICAgIHBhcnQwIC09IDB4ODAgPDwgMTQ7CisgICAgYiA9ICoocHRyKyspOyBwYXJ0MCArPSBiIDw8IDIxOyBpZiAoIShiICYgMHg4MCkpIGdvdG8gZG9uZTsKKyAgICBwYXJ0MCAtPSAweDgwIDw8IDIxOworICAgIGIgPSAqKHB0cisrKTsgcGFydDEgID0gYiAgICAgIDsgaWYgKCEoYiAmIDB4ODApKSBnb3RvIGRvbmU7CisgICAgcGFydDEgLT0gMHg4MDsKKyAgICBiID0gKihwdHIrKyk7IHBhcnQxICs9IGIgPDwgIDc7IGlmICghKGIgJiAweDgwKSkgZ290byBkb25lOworICAgIHBhcnQxIC09IDB4ODAgPDwgNzsKKyAgICBiID0gKihwdHIrKyk7IHBhcnQxICs9IGIgPDwgMTQ7IGlmICghKGIgJiAweDgwKSkgZ290byBkb25lOworICAgIHBhcnQxIC09IDB4ODAgPDwgMTQ7CisgICAgYiA9ICoocHRyKyspOyBwYXJ0MSArPSBiIDw8IDIxOyBpZiAoIShiICYgMHg4MCkpIGdvdG8gZG9uZTsKKyAgICBwYXJ0MSAtPSAweDgwIDw8IDIxOworICAgIGIgPSAqKHB0cisrKTsgcGFydDIgID0gYiAgICAgIDsgaWYgKCEoYiAmIDB4ODApKSBnb3RvIGRvbmU7CisgICAgcGFydDIgLT0gMHg4MDsKKyAgICBiID0gKihwdHIrKyk7IHBhcnQyICs9IGIgPDwgIDc7IGlmICghKGIgJiAweDgwKSkgZ290byBkb25lOworICAgIC8vICJwYXJ0MiAtPSAweDgwIDw8IDciIGlzIGlycmVsZXZhbnQgYmVjYXVzZSAoMHg4MCA8PCA3KSA8PCA1NiBpcyAwLgorCisgICAgLy8gV2UgaGF2ZSBvdmVycnVuIHRoZSBtYXhpbXVtIHNpemUgb2YgYSB2YXJpbnQgKDEwIGJ5dGVzKS4gIFRoZSBkYXRhCisgICAgLy8gbXVzdCBiZSBjb3JydXB0LgorICAgIHJldHVybiBzdGQ6Om1ha2VfcGFpcigwLCBmYWxzZSk7CisKKyAgIGRvbmU6CisgICAgQWR2YW5jZShwdHIgLSBidWZmZXJfKTsKKyAgICByZXR1cm4gc3RkOjptYWtlX3BhaXIoKHN0YXRpY19jYXN0PHVpbnQ2ND4ocGFydDApKSB8CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc3RhdGljX2Nhc3Q8dWludDY0PihwYXJ0MSkgPDwgMjgpIHwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzdGF0aWNfY2FzdDx1aW50NjQ+KHBhcnQyKSA8PCA1NiksCisgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpOworICB9IGVsc2UgeworICAgIHVpbnQ2NCB0ZW1wOworICAgIGJvb2wgc3VjY2VzcyA9IFJlYWRWYXJpbnQ2NFNsb3coJnRlbXApOworICAgIHJldHVybiBzdGQ6Om1ha2VfcGFpcih0ZW1wLCBzdWNjZXNzKTsKKyAgfQorfQorCitib29sIENvZGVkSW5wdXRTdHJlYW06OlJlZnJlc2goKSB7CisgIEdPT0dMRV9EQ0hFQ0tfRVEoMCwgQnVmZmVyU2l6ZSgpKTsKKworICBpZiAoYnVmZmVyX3NpemVfYWZ0ZXJfbGltaXRfID4gMCB8fCBvdmVyZmxvd19ieXRlc18gPiAwIHx8CisgICAgICB0b3RhbF9ieXRlc19yZWFkXyA9PSBjdXJyZW50X2xpbWl0XykgeworICAgIC8vIFdlJ3ZlIGhpdCBhIGxpbWl0LiAgU3RvcC4KKyAgICBpbnQgY3VycmVudF9wb3NpdGlvbiA9IHRvdGFsX2J5dGVzX3JlYWRfIC0gYnVmZmVyX3NpemVfYWZ0ZXJfbGltaXRfOworCisgICAgaWYgKGN1cnJlbnRfcG9zaXRpb24gPj0gdG90YWxfYnl0ZXNfbGltaXRfICYmCisgICAgICAgIHRvdGFsX2J5dGVzX2xpbWl0XyAhPSBjdXJyZW50X2xpbWl0XykgeworICAgICAgLy8gSGl0IHRvdGFsX2J5dGVzX2xpbWl0Xy4KKyAgICAgIFByaW50VG90YWxCeXRlc0xpbWl0RXJyb3IoKTsKKyAgICB9CisKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBpZiAodG90YWxfYnl0ZXNfd2FybmluZ190aHJlc2hvbGRfID49IDAgJiYKKyAgICAgIHRvdGFsX2J5dGVzX3JlYWRfID49IHRvdGFsX2J5dGVzX3dhcm5pbmdfdGhyZXNob2xkXykgeworICAgICAgR09PR0xFX0xPRyhXQVJOSU5HKSA8PCAiUmVhZGluZyBkYW5nZXJvdXNseSBsYXJnZSBwcm90b2NvbCBtZXNzYWdlLiAgSWYgdGhlICIKKyAgICAgICAgICAgICAgICAgICAgICAibWVzc2FnZSB0dXJucyBvdXQgdG8gYmUgbGFyZ2VyIHRoYW4gIgorICAgICAgICAgICAgICAgICAgIDw8IHRvdGFsX2J5dGVzX2xpbWl0XyA8PCAiIGJ5dGVzLCBwYXJzaW5nIHdpbGwgYmUgaGFsdGVkICIKKyAgICAgICAgICAgICAgICAgICAgICAiZm9yIHNlY3VyaXR5IHJlYXNvbnMuICBUbyBpbmNyZWFzZSB0aGUgbGltaXQgKG9yIHRvICIKKyAgICAgICAgICAgICAgICAgICAgICAiZGlzYWJsZSB0aGVzZSB3YXJuaW5ncyksIHNlZSAiCisgICAgICAgICAgICAgICAgICAgICAgIkNvZGVkSW5wdXRTdHJlYW06OlNldFRvdGFsQnl0ZXNMaW1pdCgpIGluICIKKyAgICAgICAgICAgICAgICAgICAgICAiZ29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5oLiI7CisKKyAgICAvLyBEb24ndCB3YXJuIGFnYWluIGZvciB0aGlzIHN0cmVhbSwgYW5kIHByaW50IHRvdGFsIHNpemUgYXQgdGhlIGVuZC4KKyAgICB0b3RhbF9ieXRlc193YXJuaW5nX3RocmVzaG9sZF8gPSAtMjsKKyAgfQorCisgIGNvbnN0IHZvaWQqIHZvaWRfYnVmZmVyOworICBpbnQgYnVmZmVyX3NpemU7CisgIGlmIChOZXh0Tm9uRW1wdHkoaW5wdXRfLCAmdm9pZF9idWZmZXIsICZidWZmZXJfc2l6ZSkpIHsKKyAgICBidWZmZXJfID0gcmVpbnRlcnByZXRfY2FzdDxjb25zdCB1aW50OCo+KHZvaWRfYnVmZmVyKTsKKyAgICBidWZmZXJfZW5kXyA9IGJ1ZmZlcl8gKyBidWZmZXJfc2l6ZTsKKyAgICBHT09HTEVfQ0hFQ0tfR0UoYnVmZmVyX3NpemUsIDApOworCisgICAgaWYgKHRvdGFsX2J5dGVzX3JlYWRfIDw9IElOVF9NQVggLSBidWZmZXJfc2l6ZSkgeworICAgICAgdG90YWxfYnl0ZXNfcmVhZF8gKz0gYnVmZmVyX3NpemU7CisgICAgfSBlbHNlIHsKKyAgICAgIC8vIE92ZXJmbG93LiAgUmVzZXQgYnVmZmVyX2VuZF8gdG8gbm90IGluY2x1ZGUgdGhlIGJ5dGVzIGJleW9uZCBJTlRfTUFYLgorICAgICAgLy8gV2UgY2FuJ3QgZ2V0IHRoYXQgZmFyIGFueXdheSwgYmVjYXVzZSB0b3RhbF9ieXRlc19saW1pdF8gaXMgZ3VhcmFudGVlZAorICAgICAgLy8gdG8gYmUgbGVzcyB0aGFuIGl0LiAgV2UgbmVlZCB0byBrZWVwIHRyYWNrIG9mIHRoZSBudW1iZXIgb2YgYnl0ZXMKKyAgICAgIC8vIHdlIGRpc2NhcmRlZCwgdGhvdWdoLCBzbyB0aGF0IHdlIGNhbiBjYWxsIGlucHV0Xy0+QmFja1VwKCkgdG8gYmFjaworICAgICAgLy8gdXAgb3ZlciB0aGVtIG9uIGRlc3RydWN0aW9uLgorCisgICAgICAvLyBUaGUgZm9sbG93aW5nIGxpbmUgaXMgZXF1aXZhbGVudCB0bzoKKyAgICAgIC8vICAgb3ZlcmZsb3dfYnl0ZXNfID0gdG90YWxfYnl0ZXNfcmVhZF8gKyBidWZmZXJfc2l6ZSAtIElOVF9NQVg7CisgICAgICAvLyBleGNlcHQgdGhhdCBpdCBhdm9pZHMgb3ZlcmZsb3dzLiAgU2lnbmVkIGludGVnZXIgb3ZlcmZsb3cgaGFzCisgICAgICAvLyB1bmRlZmluZWQgcmVzdWx0cyBhY2NvcmRpbmcgdG8gdGhlIEMgc3RhbmRhcmQuCisgICAgICBvdmVyZmxvd19ieXRlc18gPSB0b3RhbF9ieXRlc19yZWFkXyAtIChJTlRfTUFYIC0gYnVmZmVyX3NpemUpOworICAgICAgYnVmZmVyX2VuZF8gLT0gb3ZlcmZsb3dfYnl0ZXNfOworICAgICAgdG90YWxfYnl0ZXNfcmVhZF8gPSBJTlRfTUFYOworICAgIH0KKworICAgIFJlY29tcHV0ZUJ1ZmZlckxpbWl0cygpOworICAgIHJldHVybiB0cnVlOworICB9IGVsc2UgeworICAgIGJ1ZmZlcl8gPSBOVUxMOworICAgIGJ1ZmZlcl9lbmRfID0gTlVMTDsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KK30KKworLy8gQ29kZWRPdXRwdXRTdHJlYW0gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitDb2RlZE91dHB1dFN0cmVhbTo6Q29kZWRPdXRwdXRTdHJlYW0oWmVyb0NvcHlPdXRwdXRTdHJlYW0qIG91dHB1dCkKKyAgOiBvdXRwdXRfKG91dHB1dCksCisgICAgYnVmZmVyXyhOVUxMKSwKKyAgICBidWZmZXJfc2l6ZV8oMCksCisgICAgdG90YWxfYnl0ZXNfKDApLAorICAgIGhhZF9lcnJvcl8oZmFsc2UpLAorICAgIGFsaWFzaW5nX2VuYWJsZWRfKGZhbHNlKSB7CisgIC8vIEVhZ2VybHkgUmVmcmVzaCgpIHNvIGJ1ZmZlciBzcGFjZSBpcyBpbW1lZGlhdGVseSBhdmFpbGFibGUuCisgIFJlZnJlc2goKTsKKyAgLy8gVGhlIFJlZnJlc2goKSBtYXkgaGF2ZSBmYWlsZWQuIElmIHRoZSBjbGllbnQgZG9lc24ndCB3cml0ZSBhbnkgZGF0YSwKKyAgLy8gdGhvdWdoLCBkb24ndCBjb25zaWRlciB0aGlzIGFuIGVycm9yLiBJZiB0aGUgY2xpZW50IGRvZXMgd3JpdGUgZGF0YSwgdGhlbgorICAvLyBhbm90aGVyIFJlZnJlc2goKSB3aWxsIGJlIGF0dGVtcHRlZCBhbmQgaXQgd2lsbCBzZXQgdGhlIGVycm9yIG9uY2UgYWdhaW4uCisgIGhhZF9lcnJvcl8gPSBmYWxzZTsKK30KKworQ29kZWRPdXRwdXRTdHJlYW06OkNvZGVkT3V0cHV0U3RyZWFtKFplcm9Db3B5T3V0cHV0U3RyZWFtKiBvdXRwdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBkb19lYWdlcl9yZWZyZXNoKQorICA6IG91dHB1dF8ob3V0cHV0KSwKKyAgICBidWZmZXJfKE5VTEwpLAorICAgIGJ1ZmZlcl9zaXplXygwKSwKKyAgICB0b3RhbF9ieXRlc18oMCksCisgICAgaGFkX2Vycm9yXyhmYWxzZSksCisgICAgYWxpYXNpbmdfZW5hYmxlZF8oZmFsc2UpIHsKKyAgaWYgKGRvX2VhZ2VyX3JlZnJlc2gpIHsKKyAgICAvLyBFYWdlcmx5IFJlZnJlc2goKSBzbyBidWZmZXIgc3BhY2UgaXMgaW1tZWRpYXRlbHkgYXZhaWxhYmxlLgorICAgIFJlZnJlc2goKTsKKyAgICAvLyBUaGUgUmVmcmVzaCgpIG1heSBoYXZlIGZhaWxlZC4gSWYgdGhlIGNsaWVudCBkb2Vzbid0IHdyaXRlIGFueSBkYXRhLAorICAgIC8vIHRob3VnaCwgZG9uJ3QgY29uc2lkZXIgdGhpcyBhbiBlcnJvci4gSWYgdGhlIGNsaWVudCBkb2VzIHdyaXRlIGRhdGEsIHRoZW4KKyAgICAvLyBhbm90aGVyIFJlZnJlc2goKSB3aWxsIGJlIGF0dGVtcHRlZCBhbmQgaXQgd2lsbCBzZXQgdGhlIGVycm9yIG9uY2UgYWdhaW4uCisgICAgaGFkX2Vycm9yXyA9IGZhbHNlOworICB9Cit9CisKK0NvZGVkT3V0cHV0U3RyZWFtOjp+Q29kZWRPdXRwdXRTdHJlYW0oKSB7CisgIFRyaW0oKTsKK30KKwordm9pZCBDb2RlZE91dHB1dFN0cmVhbTo6VHJpbSgpIHsKKyAgaWYgKGJ1ZmZlcl9zaXplXyA+IDApIHsKKyAgICBvdXRwdXRfLT5CYWNrVXAoYnVmZmVyX3NpemVfKTsKKyAgICB0b3RhbF9ieXRlc18gLT0gYnVmZmVyX3NpemVfOworICAgIGJ1ZmZlcl9zaXplXyA9IDA7CisgICAgYnVmZmVyXyA9IE5VTEw7CisgIH0KK30KKworYm9vbCBDb2RlZE91dHB1dFN0cmVhbTo6U2tpcChpbnQgY291bnQpIHsKKyAgaWYgKGNvdW50IDwgMCkgcmV0dXJuIGZhbHNlOworCisgIHdoaWxlIChjb3VudCA+IGJ1ZmZlcl9zaXplXykgeworICAgIGNvdW50IC09IGJ1ZmZlcl9zaXplXzsKKyAgICBpZiAoIVJlZnJlc2goKSkgcmV0dXJuIGZhbHNlOworICB9CisKKyAgQWR2YW5jZShjb3VudCk7CisgIHJldHVybiB0cnVlOworfQorCitib29sIENvZGVkT3V0cHV0U3RyZWFtOjpHZXREaXJlY3RCdWZmZXJQb2ludGVyKHZvaWQqKiBkYXRhLCBpbnQqIHNpemUpIHsKKyAgaWYgKGJ1ZmZlcl9zaXplXyA9PSAwICYmICFSZWZyZXNoKCkpIHJldHVybiBmYWxzZTsKKworICAqZGF0YSA9IGJ1ZmZlcl87CisgICpzaXplID0gYnVmZmVyX3NpemVfOworICByZXR1cm4gdHJ1ZTsKK30KKwordm9pZCBDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVSYXcoY29uc3Qgdm9pZCogZGF0YSwgaW50IHNpemUpIHsKKyAgd2hpbGUgKGJ1ZmZlcl9zaXplXyA8IHNpemUpIHsKKyAgICBtZW1jcHkoYnVmZmVyXywgZGF0YSwgYnVmZmVyX3NpemVfKTsKKyAgICBzaXplIC09IGJ1ZmZlcl9zaXplXzsKKyAgICBkYXRhID0gcmVpbnRlcnByZXRfY2FzdDxjb25zdCB1aW50OCo+KGRhdGEpICsgYnVmZmVyX3NpemVfOworICAgIGlmICghUmVmcmVzaCgpKSByZXR1cm47CisgIH0KKworICBtZW1jcHkoYnVmZmVyXywgZGF0YSwgc2l6ZSk7CisgIEFkdmFuY2Uoc2l6ZSk7Cit9CisKK3VpbnQ4KiBDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVSYXdUb0FycmF5KAorICAgIGNvbnN0IHZvaWQqIGRhdGEsIGludCBzaXplLCB1aW50OCogdGFyZ2V0KSB7CisgIG1lbWNweSh0YXJnZXQsIGRhdGEsIHNpemUpOworICByZXR1cm4gdGFyZ2V0ICsgc2l6ZTsKK30KKworCit2b2lkIENvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZUFsaWFzZWRSYXcoY29uc3Qgdm9pZCogZGF0YSwgaW50IHNpemUpIHsKKyAgaWYgKHNpemUgPCBidWZmZXJfc2l6ZV8KKyAgICAgICkgeworICAgIFdyaXRlUmF3KGRhdGEsIHNpemUpOworICB9IGVsc2UgeworICAgIFRyaW0oKTsKKworICAgIHRvdGFsX2J5dGVzXyArPSBzaXplOworICAgIGhhZF9lcnJvcl8gfD0gIW91dHB1dF8tPldyaXRlQWxpYXNlZFJhdyhkYXRhLCBzaXplKTsKKyAgfQorfQorCit2b2lkIENvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZUxpdHRsZUVuZGlhbjMyKHVpbnQzMiB2YWx1ZSkgeworICB1aW50OCBieXRlc1tzaXplb2YodmFsdWUpXTsKKworICBib29sIHVzZV9mYXN0ID0gYnVmZmVyX3NpemVfID49IHNpemVvZih2YWx1ZSk7CisgIHVpbnQ4KiBwdHIgPSB1c2VfZmFzdCA/IGJ1ZmZlcl8gOiBieXRlczsKKworICBXcml0ZUxpdHRsZUVuZGlhbjMyVG9BcnJheSh2YWx1ZSwgcHRyKTsKKworICBpZiAodXNlX2Zhc3QpIHsKKyAgICBBZHZhbmNlKHNpemVvZih2YWx1ZSkpOworICB9IGVsc2UgeworICAgIFdyaXRlUmF3KGJ5dGVzLCBzaXplb2YodmFsdWUpKTsKKyAgfQorfQorCit2b2lkIENvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZUxpdHRsZUVuZGlhbjY0KHVpbnQ2NCB2YWx1ZSkgeworICB1aW50OCBieXRlc1tzaXplb2YodmFsdWUpXTsKKworICBib29sIHVzZV9mYXN0ID0gYnVmZmVyX3NpemVfID49IHNpemVvZih2YWx1ZSk7CisgIHVpbnQ4KiBwdHIgPSB1c2VfZmFzdCA/IGJ1ZmZlcl8gOiBieXRlczsKKworICBXcml0ZUxpdHRsZUVuZGlhbjY0VG9BcnJheSh2YWx1ZSwgcHRyKTsKKworICBpZiAodXNlX2Zhc3QpIHsKKyAgICBBZHZhbmNlKHNpemVvZih2YWx1ZSkpOworICB9IGVsc2UgeworICAgIFdyaXRlUmF3KGJ5dGVzLCBzaXplb2YodmFsdWUpKTsKKyAgfQorfQorCit2b2lkIENvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZVZhcmludDMyU2xvd1BhdGgodWludDMyIHZhbHVlKSB7CisgIHVpbnQ4IGJ5dGVzW2tNYXhWYXJpbnQzMkJ5dGVzXTsKKyAgdWludDgqIHRhcmdldCA9ICZieXRlc1swXTsKKyAgdWludDgqIGVuZCA9IFdyaXRlVmFyaW50MzJUb0FycmF5KHZhbHVlLCB0YXJnZXQpOworICBpbnQgc2l6ZSA9IGVuZCAtIHRhcmdldDsKKyAgV3JpdGVSYXcoYnl0ZXMsIHNpemUpOworfQorCitpbmxpbmUgdWludDgqIENvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZVZhcmludDY0VG9BcnJheUlubGluZSgKKyAgICB1aW50NjQgdmFsdWUsIHVpbnQ4KiB0YXJnZXQpIHsKKyAgLy8gU3BsaXR0aW5nIGludG8gMzItYml0IHBpZWNlcyBnaXZlcyBiZXR0ZXIgcGVyZm9ybWFuY2Ugb24gMzItYml0CisgIC8vIHByb2Nlc3NvcnMuCisgIHVpbnQzMiBwYXJ0MCA9IHN0YXRpY19jYXN0PHVpbnQzMj4odmFsdWUgICAgICApOworICB1aW50MzIgcGFydDEgPSBzdGF0aWNfY2FzdDx1aW50MzI+KHZhbHVlID4+IDI4KTsKKyAgdWludDMyIHBhcnQyID0gc3RhdGljX2Nhc3Q8dWludDMyPih2YWx1ZSA+PiA1Nik7CisKKyAgaW50IHNpemU7CisKKyAgLy8gSGVyZSB3ZSBjYW4ndCByZWFsbHkgb3B0aW1pemUgZm9yIHNtYWxsIG51bWJlcnMsIHNpbmNlIHRoZSB2YWx1ZSBpcworICAvLyBzcGxpdCBpbnRvIHRocmVlIHBhcnRzLiAgQ2hla2luZyBmb3IgbnVtYmVycyA8IDEyOCwgZm9yIGluc3RhbmNlLAorICAvLyB3b3VsZCByZXF1aXJlIHRocmVlIGNvbXBhcmlzb25zLCBzaW5jZSB5b3UnZCBoYXZlIHRvIG1ha2Ugc3VyZSBwYXJ0MQorICAvLyBhbmQgcGFydDIgYXJlIHplcm8uICBIb3dldmVyLCBpZiB0aGUgY2FsbGVyIGlzIHVzaW5nIDY0LWJpdCBpbnRlZ2VycywKKyAgLy8gaXQgaXMgbGlrZWx5IHRoYXQgdGhleSBleHBlY3QgdGhlIG51bWJlcnMgdG8gb2Z0ZW4gYmUgdmVyeSBsYXJnZSwgc28KKyAgLy8gd2UgcHJvYmFibHkgZG9uJ3Qgd2FudCB0byBvcHRpbWl6ZSBmb3Igc21hbGwgbnVtYmVycyBhbnl3YXkuICBUaHVzLAorICAvLyB3ZSBlbmQgdXAgd2l0aCBhIGhhcmRjb2RlZCBiaW5hcnkgc2VhcmNoIHRyZWUuLi4KKyAgaWYgKHBhcnQyID09IDApIHsKKyAgICBpZiAocGFydDEgPT0gMCkgeworICAgICAgaWYgKHBhcnQwIDwgKDEgPDwgMTQpKSB7CisgICAgICAgIGlmIChwYXJ0MCA8ICgxIDw8IDcpKSB7CisgICAgICAgICAgc2l6ZSA9IDE7IGdvdG8gc2l6ZTE7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgc2l6ZSA9IDI7IGdvdG8gc2l6ZTI7CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGlmIChwYXJ0MCA8ICgxIDw8IDIxKSkgeworICAgICAgICAgIHNpemUgPSAzOyBnb3RvIHNpemUzOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNpemUgPSA0OyBnb3RvIHNpemU0OworICAgICAgICB9CisgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgIGlmIChwYXJ0MSA8ICgxIDw8IDE0KSkgeworICAgICAgICBpZiAocGFydDEgPCAoMSA8PCA3KSkgeworICAgICAgICAgIHNpemUgPSA1OyBnb3RvIHNpemU1OworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHNpemUgPSA2OyBnb3RvIHNpemU2OworICAgICAgICB9CisgICAgICB9IGVsc2UgeworICAgICAgICBpZiAocGFydDEgPCAoMSA8PCAyMSkpIHsKKyAgICAgICAgICBzaXplID0gNzsgZ290byBzaXplNzsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzaXplID0gODsgZ290byBzaXplODsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgfSBlbHNlIHsKKyAgICBpZiAocGFydDIgPCAoMSA8PCA3KSkgeworICAgICAgc2l6ZSA9IDk7IGdvdG8gc2l6ZTk7CisgICAgfSBlbHNlIHsKKyAgICAgIHNpemUgPSAxMDsgZ290byBzaXplMTA7CisgICAgfQorICB9CisKKyAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkNhbid0IGdldCBoZXJlLiI7CisKKyAgc2l6ZTEwOiB0YXJnZXRbOV0gPSBzdGF0aWNfY2FzdDx1aW50OD4oKHBhcnQyID4+ICA3KSB8IDB4ODApOworICBzaXplOSA6IHRhcmdldFs4XSA9IHN0YXRpY19jYXN0PHVpbnQ4PigocGFydDIgICAgICApIHwgMHg4MCk7CisgIHNpemU4IDogdGFyZ2V0WzddID0gc3RhdGljX2Nhc3Q8dWludDg+KChwYXJ0MSA+PiAyMSkgfCAweDgwKTsKKyAgc2l6ZTcgOiB0YXJnZXRbNl0gPSBzdGF0aWNfY2FzdDx1aW50OD4oKHBhcnQxID4+IDE0KSB8IDB4ODApOworICBzaXplNiA6IHRhcmdldFs1XSA9IHN0YXRpY19jYXN0PHVpbnQ4PigocGFydDEgPj4gIDcpIHwgMHg4MCk7CisgIHNpemU1IDogdGFyZ2V0WzRdID0gc3RhdGljX2Nhc3Q8dWludDg+KChwYXJ0MSAgICAgICkgfCAweDgwKTsKKyAgc2l6ZTQgOiB0YXJnZXRbM10gPSBzdGF0aWNfY2FzdDx1aW50OD4oKHBhcnQwID4+IDIxKSB8IDB4ODApOworICBzaXplMyA6IHRhcmdldFsyXSA9IHN0YXRpY19jYXN0PHVpbnQ4PigocGFydDAgPj4gMTQpIHwgMHg4MCk7CisgIHNpemUyIDogdGFyZ2V0WzFdID0gc3RhdGljX2Nhc3Q8dWludDg+KChwYXJ0MCA+PiAgNykgfCAweDgwKTsKKyAgc2l6ZTEgOiB0YXJnZXRbMF0gPSBzdGF0aWNfY2FzdDx1aW50OD4oKHBhcnQwICAgICAgKSB8IDB4ODApOworCisgIHRhcmdldFtzaXplLTFdICY9IDB4N0Y7CisgIHJldHVybiB0YXJnZXQgKyBzaXplOworfQorCit2b2lkIENvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZVZhcmludDY0KHVpbnQ2NCB2YWx1ZSkgeworICBpZiAoYnVmZmVyX3NpemVfID49IGtNYXhWYXJpbnRCeXRlcykgeworICAgIC8vIEZhc3QgcGF0aDogIFdlIGhhdmUgZW5vdWdoIGJ5dGVzIGxlZnQgaW4gdGhlIGJ1ZmZlciB0byBndWFyYW50ZWUgdGhhdAorICAgIC8vIHRoaXMgd3JpdGUgd29uJ3QgY3Jvc3MgdGhlIGVuZCwgc28gd2UgY2FuIHNraXAgdGhlIGNoZWNrcy4KKyAgICB1aW50OCogdGFyZ2V0ID0gYnVmZmVyXzsKKworICAgIHVpbnQ4KiBlbmQgPSBXcml0ZVZhcmludDY0VG9BcnJheUlubGluZSh2YWx1ZSwgdGFyZ2V0KTsKKyAgICBpbnQgc2l6ZSA9IGVuZCAtIHRhcmdldDsKKyAgICBBZHZhbmNlKHNpemUpOworICB9IGVsc2UgeworICAgIC8vIFNsb3cgcGF0aDogIFRoaXMgd3JpdGUgbWlnaHQgY3Jvc3MgdGhlIGVuZCBvZiB0aGUgYnVmZmVyLCBzbyB3ZQorICAgIC8vIGNvbXBvc2UgdGhlIGJ5dGVzIGZpcnN0IHRoZW4gdXNlIFdyaXRlUmF3KCkuCisgICAgdWludDggYnl0ZXNba01heFZhcmludEJ5dGVzXTsKKyAgICBpbnQgc2l6ZSA9IDA7CisgICAgd2hpbGUgKHZhbHVlID4gMHg3RikgeworICAgICAgYnl0ZXNbc2l6ZSsrXSA9IChzdGF0aWNfY2FzdDx1aW50OD4odmFsdWUpICYgMHg3RikgfCAweDgwOworICAgICAgdmFsdWUgPj49IDc7CisgICAgfQorICAgIGJ5dGVzW3NpemUrK10gPSBzdGF0aWNfY2FzdDx1aW50OD4odmFsdWUpICYgMHg3RjsKKyAgICBXcml0ZVJhdyhieXRlcywgc2l6ZSk7CisgIH0KK30KKwordWludDgqIENvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZVZhcmludDY0VG9BcnJheSgKKyAgICB1aW50NjQgdmFsdWUsIHVpbnQ4KiB0YXJnZXQpIHsKKyAgcmV0dXJuIFdyaXRlVmFyaW50NjRUb0FycmF5SW5saW5lKHZhbHVlLCB0YXJnZXQpOworfQorCitib29sIENvZGVkT3V0cHV0U3RyZWFtOjpSZWZyZXNoKCkgeworICB2b2lkKiB2b2lkX2J1ZmZlcjsKKyAgaWYgKG91dHB1dF8tPk5leHQoJnZvaWRfYnVmZmVyLCAmYnVmZmVyX3NpemVfKSkgeworICAgIGJ1ZmZlcl8gPSByZWludGVycHJldF9jYXN0PHVpbnQ4Kj4odm9pZF9idWZmZXIpOworICAgIHRvdGFsX2J5dGVzXyArPSBidWZmZXJfc2l6ZV87CisgICAgcmV0dXJuIHRydWU7CisgIH0gZWxzZSB7CisgICAgYnVmZmVyXyA9IE5VTEw7CisgICAgYnVmZmVyX3NpemVfID0gMDsKKyAgICBoYWRfZXJyb3JfID0gdHJ1ZTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KK30KKworaW50IENvZGVkT3V0cHV0U3RyZWFtOjpWYXJpbnRTaXplMzJGYWxsYmFjayh1aW50MzIgdmFsdWUpIHsKKyAgaWYgKHZhbHVlIDwgKDEgPDwgNykpIHsKKyAgICByZXR1cm4gMTsKKyAgfSBlbHNlIGlmICh2YWx1ZSA8ICgxIDw8IDE0KSkgeworICAgIHJldHVybiAyOworICB9IGVsc2UgaWYgKHZhbHVlIDwgKDEgPDwgMjEpKSB7CisgICAgcmV0dXJuIDM7CisgIH0gZWxzZSBpZiAodmFsdWUgPCAoMSA8PCAyOCkpIHsKKyAgICByZXR1cm4gNDsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gNTsKKyAgfQorfQorCitpbnQgQ29kZWRPdXRwdXRTdHJlYW06OlZhcmludFNpemU2NCh1aW50NjQgdmFsdWUpIHsKKyAgaWYgKHZhbHVlIDwgKDF1bGwgPDwgMzUpKSB7CisgICAgaWYgKHZhbHVlIDwgKDF1bGwgPDwgNykpIHsKKyAgICAgIHJldHVybiAxOworICAgIH0gZWxzZSBpZiAodmFsdWUgPCAoMXVsbCA8PCAxNCkpIHsKKyAgICAgIHJldHVybiAyOworICAgIH0gZWxzZSBpZiAodmFsdWUgPCAoMXVsbCA8PCAyMSkpIHsKKyAgICAgIHJldHVybiAzOworICAgIH0gZWxzZSBpZiAodmFsdWUgPCAoMXVsbCA8PCAyOCkpIHsKKyAgICAgIHJldHVybiA0OworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gNTsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgaWYgKHZhbHVlIDwgKDF1bGwgPDwgNDIpKSB7CisgICAgICByZXR1cm4gNjsKKyAgICB9IGVsc2UgaWYgKHZhbHVlIDwgKDF1bGwgPDwgNDkpKSB7CisgICAgICByZXR1cm4gNzsKKyAgICB9IGVsc2UgaWYgKHZhbHVlIDwgKDF1bGwgPDwgNTYpKSB7CisgICAgICByZXR1cm4gODsKKyAgICB9IGVsc2UgaWYgKHZhbHVlIDwgKDF1bGwgPDwgNjMpKSB7CisgICAgICByZXR1cm4gOTsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIDEwOworICAgIH0KKyAgfQorfQorCit1aW50OCogQ29kZWRPdXRwdXRTdHJlYW06OldyaXRlU3RyaW5nV2l0aFNpemVUb0FycmF5KGNvbnN0IHN0cmluZyYgc3RyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OCogdGFyZ2V0KSB7CisgIEdPT0dMRV9EQ0hFQ0tfTEUoc3RyLnNpemUoKSwga3VpbnQzMm1heCk7CisgIHRhcmdldCA9IFdyaXRlVmFyaW50MzJUb0FycmF5KHN0ci5zaXplKCksIHRhcmdldCk7CisgIHJldHVybiBXcml0ZVN0cmluZ1RvQXJyYXkoc3RyLCB0YXJnZXQpOworfQorCit9ICAvLyBuYW1lc3BhY2UgaW8KK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW0uaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTM3NzEwMAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmgKQEAgLTAsMCArMSwxMjk0IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisvLworLy8gVGhpcyBmaWxlIGNvbnRhaW5zIHRoZSBDb2RlZElucHV0U3RyZWFtIGFuZCBDb2RlZE91dHB1dFN0cmVhbSBjbGFzc2VzLAorLy8gd2hpY2ggd3JhcCBhIFplcm9Db3B5SW5wdXRTdHJlYW0gb3IgWmVyb0NvcHlPdXRwdXRTdHJlYW0sIHJlc3BlY3RpdmVseSwKKy8vIGFuZCBhbGxvdyB5b3UgdG8gcmVhZCBvciB3cml0ZSBpbmRpdmlkdWFsIHBpZWNlcyBvZiBkYXRhIGluIHZhcmlvdXMKKy8vIGZvcm1hdHMuICBJbiBwYXJ0aWN1bGFyLCB0aGVzZSBpbXBsZW1lbnQgdGhlIHZhcmludCBlbmNvZGluZyBmb3IKKy8vIGludGVnZXJzLCBhIHNpbXBsZSB2YXJpYWJsZS1sZW5ndGggZW5jb2RpbmcgaW4gd2hpY2ggc21hbGxlciBudW1iZXJzCisvLyB0YWtlIGZld2VyIGJ5dGVzLgorLy8KKy8vIFR5cGljYWxseSB0aGVzZSBjbGFzc2VzIHdpbGwgb25seSBiZSB1c2VkIGludGVybmFsbHkgYnkgdGhlIHByb3RvY29sCisvLyBidWZmZXIgbGlicmFyeSBpbiBvcmRlciB0byBlbmNvZGUgYW5kIGRlY29kZSBwcm90b2NvbCBidWZmZXJzLiAgQ2xpZW50cworLy8gb2YgdGhlIGxpYnJhcnkgb25seSBuZWVkIHRvIGtub3cgYWJvdXQgdGhpcyBjbGFzcyBpZiB0aGV5IHdpc2ggdG8gd3JpdGUKKy8vIGN1c3RvbSBtZXNzYWdlIHBhcnNpbmcgb3Igc2VyaWFsaXphdGlvbiBwcm9jZWR1cmVzLgorLy8KKy8vIENvZGVkT3V0cHV0U3RyZWFtIGV4YW1wbGU6CisvLyAgIC8vIFdyaXRlIHNvbWUgZGF0YSB0byAibXlmaWxlIi4gIEZpcnN0IHdlIHdyaXRlIGEgNC1ieXRlICJtYWdpYyBudW1iZXIiCisvLyAgIC8vIHRvIGlkZW50aWZ5IHRoZSBmaWxlIHR5cGUsIHRoZW4gd3JpdGUgYSBsZW5ndGgtZGVsaW1pdGVkIHN0cmluZy4gIFRoZQorLy8gICAvLyBzdHJpbmcgaXMgY29tcG9zZWQgb2YgYSB2YXJpbnQgZ2l2aW5nIHRoZSBsZW5ndGggZm9sbG93ZWQgYnkgdGhlIHJhdworLy8gICAvLyBieXRlcy4KKy8vICAgaW50IGZkID0gb3BlbigibXlmaWxlIiwgT19DUkVBVCB8IE9fV1JPTkxZKTsKKy8vICAgWmVyb0NvcHlPdXRwdXRTdHJlYW0qIHJhd19vdXRwdXQgPSBuZXcgRmlsZU91dHB1dFN0cmVhbShmZCk7CisvLyAgIENvZGVkT3V0cHV0U3RyZWFtKiBjb2RlZF9vdXRwdXQgPSBuZXcgQ29kZWRPdXRwdXRTdHJlYW0ocmF3X291dHB1dCk7CisvLworLy8gICBpbnQgbWFnaWNfbnVtYmVyID0gMTIzNDsKKy8vICAgY2hhciB0ZXh0W10gPSAiSGVsbG8gd29ybGQhIjsKKy8vICAgY29kZWRfb3V0cHV0LT5Xcml0ZUxpdHRsZUVuZGlhbjMyKG1hZ2ljX251bWJlcik7CisvLyAgIGNvZGVkX291dHB1dC0+V3JpdGVWYXJpbnQzMihzdHJsZW4odGV4dCkpOworLy8gICBjb2RlZF9vdXRwdXQtPldyaXRlUmF3KHRleHQsIHN0cmxlbih0ZXh0KSk7CisvLworLy8gICBkZWxldGUgY29kZWRfb3V0cHV0OworLy8gICBkZWxldGUgcmF3X291dHB1dDsKKy8vICAgY2xvc2UoZmQpOworLy8KKy8vIENvZGVkSW5wdXRTdHJlYW0gZXhhbXBsZToKKy8vICAgLy8gUmVhZCBhIGZpbGUgY3JlYXRlZCBieSB0aGUgYWJvdmUgY29kZS4KKy8vICAgaW50IGZkID0gb3BlbigibXlmaWxlIiwgT19SRE9OTFkpOworLy8gICBaZXJvQ29weUlucHV0U3RyZWFtKiByYXdfaW5wdXQgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGZkKTsKKy8vICAgQ29kZWRJbnB1dFN0cmVhbSBjb2RlZF9pbnB1dCA9IG5ldyBDb2RlZElucHV0U3RyZWFtKHJhd19pbnB1dCk7CisvLworLy8gICBjb2RlZF9pbnB1dC0+UmVhZExpdHRsZUVuZGlhbjMyKCZtYWdpY19udW1iZXIpOworLy8gICBpZiAobWFnaWNfbnVtYmVyICE9IDEyMzQpIHsKKy8vICAgICBjZXJyIDw8ICJGaWxlIG5vdCBpbiBleHBlY3RlZCBmb3JtYXQuIiA8PCBlbmRsOworLy8gICAgIHJldHVybjsKKy8vICAgfQorLy8KKy8vICAgdWludDMyIHNpemU7CisvLyAgIGNvZGVkX2lucHV0LT5SZWFkVmFyaW50MzIoJnNpemUpOworLy8KKy8vICAgY2hhciogdGV4dCA9IG5ldyBjaGFyW3NpemUgKyAxXTsKKy8vICAgY29kZWRfaW5wdXQtPlJlYWRSYXcoYnVmZmVyLCBzaXplKTsKKy8vICAgdGV4dFtzaXplXSA9ICdcMCc7CisvLworLy8gICBkZWxldGUgY29kZWRfaW5wdXQ7CisvLyAgIGRlbGV0ZSByYXdfaW5wdXQ7CisvLyAgIGNsb3NlKGZkKTsKKy8vCisvLyAgIGNvdXQgPDwgIlRleHQgaXM6ICIgPDwgdGV4dCA8PCBlbmRsOworLy8gICBkZWxldGUgW10gdGV4dDsKKy8vCisvLyBGb3IgdGhvc2Ugd2hvIGFyZSBpbnRlcmVzdGVkLCB2YXJpbnQgZW5jb2RpbmcgaXMgZGVmaW5lZCBhcyBmb2xsb3dzOgorLy8KKy8vIFRoZSBlbmNvZGluZyBvcGVyYXRlcyBvbiB1bnNpZ25lZCBpbnRlZ2VycyBvZiB1cCB0byA2NCBiaXRzIGluIGxlbmd0aC4KKy8vIEVhY2ggYnl0ZSBvZiB0aGUgZW5jb2RlZCB2YWx1ZSBoYXMgdGhlIGZvcm1hdDoKKy8vICogYml0cyAwLTY6IFNldmVuIGJpdHMgb2YgdGhlIG51bWJlciBiZWluZyBlbmNvZGVkLgorLy8gKiBiaXQgNzogWmVybyBpZiB0aGlzIGlzIHRoZSBsYXN0IGJ5dGUgaW4gdGhlIGVuY29kaW5nIChpbiB3aGljaAorLy8gICBjYXNlIGFsbCByZW1haW5pbmcgYml0cyBvZiB0aGUgbnVtYmVyIGFyZSB6ZXJvKSBvciAxIGlmCisvLyAgIG1vcmUgYnl0ZXMgZm9sbG93LgorLy8gVGhlIGZpcnN0IGJ5dGUgY29udGFpbnMgdGhlIGxlYXN0LXNpZ25pZmljYW50IDcgYml0cyBvZiB0aGUgbnVtYmVyLCB0aGUKKy8vIHNlY29uZCBieXRlIChpZiBwcmVzZW50KSBjb250YWlucyB0aGUgbmV4dC1sZWFzdC1zaWduaWZpY2FudCA3IGJpdHMsCisvLyBhbmQgc28gb24uICBTbywgdGhlIGJpbmFyeSBudW1iZXIgMTAxMTAwMDEwMTAxMSB3b3VsZCBiZSBlbmNvZGVkIGluIHR3bworLy8gYnl0ZXMgYXMgIjEwMTAxMDExIDAwMTAxMTAwIi4KKy8vCisvLyBJbiB0aGVvcnksIHZhcmludCBjb3VsZCBiZSB1c2VkIHRvIGVuY29kZSBpbnRlZ2VycyBvZiBhbnkgbGVuZ3RoLgorLy8gSG93ZXZlciwgZm9yIHByYWN0aWNhbGl0eSB3ZSBzZXQgYSBsaW1pdCBhdCA2NCBiaXRzLiAgVGhlIG1heGltdW0gZW5jb2RlZAorLy8gbGVuZ3RoIG9mIGEgbnVtYmVyIGlzIHRodXMgMTAgYnl0ZXMuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0lPX0NPREVEX1NUUkVBTV9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0lPX0NPREVEX1NUUkVBTV9IX18KKworI2luY2x1ZGUgPGFzc2VydC5oPgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDx1dGlsaXR5PgorI2lmZGVmIF9NU0NfVkVSCisgIC8vIEFzc3VtaW5nIHdpbmRvd3MgaXMgYWx3YXlzIGxpdHRsZS1lbmRpYW4uCisgICNpZiAhZGVmaW5lZChQUk9UT0JVRl9ESVNBQkxFX0xJVFRMRV9FTkRJQU5fT1BUX0ZPUl9URVNUKQorICAgICNkZWZpbmUgUFJPVE9CVUZfTElUVExFX0VORElBTiAxCisgICNlbmRpZgorICAjaWYgX01TQ19WRVIgPj0gMTMwMCAmJiAhZGVmaW5lZChfX0lOVEVMX0NPTVBJTEVSKQorICAgIC8vIElmIE1TVkMgaGFzICIvUlRDYyIgc2V0LCBpdCB3aWxsIGNvbXBsYWluIGFib3V0IHRydW5jYXRpbmcgY2FzdHMgYXQKKyAgICAvLyBydW50aW1lLiAgVGhpcyBmaWxlIGNvbnRhaW5zIHNvbWUgaW50ZW50aW9uYWwgdHJ1bmNhdGluZyBjYXN0cy4KKyAgICAjcHJhZ21hIHJ1bnRpbWVfY2hlY2tzKCJjIiwgb2ZmKQorICAjZW5kaWYKKyNlbHNlCisgICNpbmNsdWRlIDxzeXMvcGFyYW0uaD4gICAvLyBfX0JZVEVfT1JERVIKKyAgI2lmICgoZGVmaW5lZChfX0xJVFRMRV9FTkRJQU5fXykgJiYgIWRlZmluZWQoX19CSUdfRU5ESUFOX18pKSB8fCBcCisgICAgICAgICAoZGVmaW5lZChfX0JZVEVfT1JERVIpICYmIF9fQllURV9PUkRFUiA9PSBfX0xJVFRMRV9FTkRJQU4pKSAmJiBcCisgICAgICAhZGVmaW5lZChQUk9UT0JVRl9ESVNBQkxFX0xJVFRMRV9FTkRJQU5fT1BUX0ZPUl9URVNUKQorICAgICNkZWZpbmUgUFJPVE9CVUZfTElUVExFX0VORElBTiAxCisgICNlbmRpZgorI2VuZGlmCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKKworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworY2xhc3MgRGVzY3JpcHRvclBvb2w7CitjbGFzcyBNZXNzYWdlRmFjdG9yeTsKKworbmFtZXNwYWNlIGlvIHsKKworLy8gRGVmaW5lZCBpbiB0aGlzIGZpbGUuCitjbGFzcyBDb2RlZElucHV0U3RyZWFtOworY2xhc3MgQ29kZWRPdXRwdXRTdHJlYW07CisKKy8vIERlZmluZWQgaW4gb3RoZXIgZmlsZXMuCitjbGFzcyBaZXJvQ29weUlucHV0U3RyZWFtOyAgICAgICAgICAgLy8gemVyb19jb3B5X3N0cmVhbS5oCitjbGFzcyBaZXJvQ29weU91dHB1dFN0cmVhbTsgICAgICAgICAgLy8gemVyb19jb3B5X3N0cmVhbS5oCisKKy8vIENsYXNzIHdoaWNoIHJlYWRzIGFuZCBkZWNvZGVzIGJpbmFyeSBkYXRhIHdoaWNoIGlzIGNvbXBvc2VkIG9mIHZhcmludC0KKy8vIGVuY29kZWQgaW50ZWdlcnMgYW5kIGZpeGVkLXdpZHRoIHBpZWNlcy4gIFdyYXBzIGEgWmVyb0NvcHlJbnB1dFN0cmVhbS4KKy8vIE1vc3QgdXNlcnMgd2lsbCBub3QgbmVlZCB0byBkZWFsIHdpdGggQ29kZWRJbnB1dFN0cmVhbS4KKy8vCisvLyBNb3N0IG1ldGhvZHMgb2YgQ29kZWRJbnB1dFN0cmVhbSB0aGF0IHJldHVybiBhIGJvb2wgcmV0dXJuIGZhbHNlIGlmIGFuCisvLyB1bmRlcmx5aW5nIEkvTyBlcnJvciBvY2N1cnMgb3IgaWYgdGhlIGRhdGEgaXMgbWFsZm9ybWVkLiAgT25jZSBzdWNoIGEKKy8vIGZhaWx1cmUgb2NjdXJzLCB0aGUgQ29kZWRJbnB1dFN0cmVhbSBpcyBicm9rZW4gYW5kIGlzIG5vIGxvbmdlciB1c2VmdWwuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgQ29kZWRJbnB1dFN0cmVhbSB7CisgcHVibGljOgorICAvLyBDcmVhdGUgYSBDb2RlZElucHV0U3RyZWFtIHRoYXQgcmVhZHMgZnJvbSB0aGUgZ2l2ZW4gWmVyb0NvcHlJbnB1dFN0cmVhbS4KKyAgZXhwbGljaXQgQ29kZWRJbnB1dFN0cmVhbShaZXJvQ29weUlucHV0U3RyZWFtKiBpbnB1dCk7CisKKyAgLy8gQ3JlYXRlIGEgQ29kZWRJbnB1dFN0cmVhbSB0aGF0IHJlYWRzIGZyb20gdGhlIGdpdmVuIGZsYXQgYXJyYXkuICBUaGlzIGlzCisgIC8vIGZhc3RlciB0aGFuIHVzaW5nIGFuIEFycmF5SW5wdXRTdHJlYW0uICBQdXNoTGltaXQoc2l6ZSkgaXMgaW1wbGllZCBieQorICAvLyB0aGlzIGNvbnN0cnVjdG9yLgorICBleHBsaWNpdCBDb2RlZElucHV0U3RyZWFtKGNvbnN0IHVpbnQ4KiBidWZmZXIsIGludCBzaXplKTsKKworICAvLyBEZXN0cm95IHRoZSBDb2RlZElucHV0U3RyZWFtIGFuZCBwb3NpdGlvbiB0aGUgdW5kZXJseWluZworICAvLyBaZXJvQ29weUlucHV0U3RyZWFtIGF0IHRoZSBmaXJzdCB1bnJlYWQgYnl0ZS4gIElmIGFuIGVycm9yIG9jY3VycmVkIHdoaWxlCisgIC8vIHJlYWRpbmcgKGNhdXNpbmcgYSBtZXRob2QgdG8gcmV0dXJuIGZhbHNlKSwgdGhlbiB0aGUgZXhhY3QgcG9zaXRpb24gb2YKKyAgLy8gdGhlIGlucHV0IHN0cmVhbSBtYXkgYmUgYW55d2hlcmUgYmV0d2VlbiB0aGUgbGFzdCB2YWx1ZSB0aGF0IHdhcyByZWFkCisgIC8vIHN1Y2Nlc3NmdWxseSBhbmQgdGhlIHN0cmVhbSdzIGJ5dGUgbGltaXQuCisgIH5Db2RlZElucHV0U3RyZWFtKCk7CisKKyAgLy8gUmV0dXJuIHRydWUgaWYgdGhpcyBDb2RlZElucHV0U3RyZWFtIHJlYWRzIGZyb20gYSBmbGF0IGFycmF5IGluc3RlYWQgb2YKKyAgLy8gYSBaZXJvQ29weUlucHV0U3RyZWFtLgorICBpbmxpbmUgYm9vbCBJc0ZsYXQoKSBjb25zdDsKKworICAvLyBTa2lwcyBhIG51bWJlciBvZiBieXRlcy4gIFJldHVybnMgZmFsc2UgaWYgYW4gdW5kZXJseWluZyByZWFkIGVycm9yCisgIC8vIG9jY3Vycy4KKyAgYm9vbCBTa2lwKGludCBjb3VudCk7CisKKyAgLy8gU2V0cyAqZGF0YSB0byBwb2ludCBkaXJlY3RseSBhdCB0aGUgdW5yZWFkIHBhcnQgb2YgdGhlIENvZGVkSW5wdXRTdHJlYW0ncworICAvLyB1bmRlcmx5aW5nIGJ1ZmZlciwgYW5kICpzaXplIHRvIHRoZSBzaXplIG9mIHRoYXQgYnVmZmVyLCBidXQgZG9lcyBub3QKKyAgLy8gYWR2YW5jZSB0aGUgc3RyZWFtJ3MgY3VycmVudCBwb3NpdGlvbi4gIFRoaXMgd2lsbCBhbHdheXMgZWl0aGVyIHByb2R1Y2UKKyAgLy8gYSBub24tZW1wdHkgYnVmZmVyIG9yIHJldHVybiBmYWxzZS4gIElmIHRoZSBjYWxsZXIgY29uc3VtZXMgYW55IG9mCisgIC8vIHRoaXMgZGF0YSwgaXQgc2hvdWxkIHRoZW4gY2FsbCBTa2lwKCkgdG8gc2tpcCBvdmVyIHRoZSBjb25zdW1lZCBieXRlcy4KKyAgLy8gVGhpcyBtYXkgYmUgdXNlZnVsIGZvciBpbXBsZW1lbnRpbmcgZXh0ZXJuYWwgZmFzdCBwYXJzaW5nIHJvdXRpbmVzIGZvcgorICAvLyB0eXBlcyBvZiBkYXRhIG5vdCBjb3ZlcmVkIGJ5IHRoZSBDb2RlZElucHV0U3RyZWFtIGludGVyZmFjZS4KKyAgYm9vbCBHZXREaXJlY3RCdWZmZXJQb2ludGVyKGNvbnN0IHZvaWQqKiBkYXRhLCBpbnQqIHNpemUpOworCisgIC8vIExpa2UgR2V0RGlyZWN0QnVmZmVyUG9pbnRlciwgYnV0IHRoaXMgbWV0aG9kIGlzIGlubGluZWQsIGFuZCBkb2VzIG5vdAorICAvLyBhdHRlbXB0IHRvIFJlZnJlc2goKSBpZiB0aGUgYnVmZmVyIGlzIGN1cnJlbnRseSBlbXB0eS4KKyAgR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FIHZvaWQgR2V0RGlyZWN0QnVmZmVyUG9pbnRlcklubGluZShjb25zdCB2b2lkKiogZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCogc2l6ZSk7CisKKyAgLy8gUmVhZCByYXcgYnl0ZXMsIGNvcHlpbmcgdGhlbSBpbnRvIHRoZSBnaXZlbiBidWZmZXIuCisgIGJvb2wgUmVhZFJhdyh2b2lkKiBidWZmZXIsIGludCBzaXplKTsKKworICAvLyBMaWtlIHRoZSBhYm92ZSwgd2l0aCBpbmxpbmVkIG9wdGltaXphdGlvbnMuIFRoaXMgc2hvdWxkIG9ubHkgYmUgdXNlZAorICAvLyBieSB0aGUgcHJvdG9idWYgaW1wbGVtZW50YXRpb24uCisgIEdPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORSBib29sIEludGVybmFsUmVhZFJhd0lubGluZSh2b2lkKiBidWZmZXIsIGludCBzaXplKTsKKworICAvLyBMaWtlIFJlYWRSYXcsIGJ1dCByZWFkcyBpbnRvIGEgc3RyaW5nLgorICAvLworICAvLyBJbXBsZW1lbnRhdGlvbiBOb3RlOiAgUmVhZFN0cmluZygpIGdyb3dzIHRoZSBzdHJpbmcgZ3JhZHVhbGx5IGFzIGl0CisgIC8vIHJlYWRzIGluIHRoZSBkYXRhLCByYXRoZXIgdGhhbiBhbGxvY2F0aW5nIHRoZSBlbnRpcmUgcmVxdWVzdGVkIHNpemUKKyAgLy8gdXBmcm9udC4gIFRoaXMgcHJldmVudHMgZGVuaWFsLW9mLXNlcnZpY2UgYXR0YWNrcyBpbiB3aGljaCBhIGNsaWVudAorICAvLyBjb3VsZCBjbGFpbSB0aGF0IGEgc3RyaW5nIGlzIGdvaW5nIHRvIGJlIE1BWF9JTlQgYnl0ZXMgbG9uZyBpbiBvcmRlciB0bworICAvLyBjcmFzaCB0aGUgc2VydmVyIGJlY2F1c2UgaXQgY2FuJ3QgYWxsb2NhdGUgdGhpcyBtdWNoIHNwYWNlIGF0IG9uY2UuCisgIGJvb2wgUmVhZFN0cmluZyhzdHJpbmcqIGJ1ZmZlciwgaW50IHNpemUpOworICAvLyBMaWtlIHRoZSBhYm92ZSwgd2l0aCBpbmxpbmVkIG9wdGltaXphdGlvbnMuIFRoaXMgc2hvdWxkIG9ubHkgYmUgdXNlZAorICAvLyBieSB0aGUgcHJvdG9idWYgaW1wbGVtZW50YXRpb24uCisgIEdPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORSBib29sIEludGVybmFsUmVhZFN0cmluZ0lubGluZShzdHJpbmcqIGJ1ZmZlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHNpemUpOworCisKKyAgLy8gUmVhZCBhIDMyLWJpdCBsaXR0bGUtZW5kaWFuIGludGVnZXIuCisgIGJvb2wgUmVhZExpdHRsZUVuZGlhbjMyKHVpbnQzMiogdmFsdWUpOworICAvLyBSZWFkIGEgNjQtYml0IGxpdHRsZS1lbmRpYW4gaW50ZWdlci4KKyAgYm9vbCBSZWFkTGl0dGxlRW5kaWFuNjQodWludDY0KiB2YWx1ZSk7CisKKyAgLy8gVGhlc2UgbWV0aG9kcyByZWFkIGZyb20gYW4gZXh0ZXJuYWxseSBwcm92aWRlZCBidWZmZXIuIFRoZSBjYWxsZXIgaXMKKyAgLy8gcmVzcG9uc2libGUgZm9yIGVuc3VyaW5nIHRoYXQgdGhlIGJ1ZmZlciBoYXMgc3VmZmljaWVudCBzcGFjZS4KKyAgLy8gUmVhZCBhIDMyLWJpdCBsaXR0bGUtZW5kaWFuIGludGVnZXIuCisgIHN0YXRpYyBjb25zdCB1aW50OCogUmVhZExpdHRsZUVuZGlhbjMyRnJvbUFycmF5KGNvbnN0IHVpbnQ4KiBidWZmZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzIqIHZhbHVlKTsKKyAgLy8gUmVhZCBhIDY0LWJpdCBsaXR0bGUtZW5kaWFuIGludGVnZXIuCisgIHN0YXRpYyBjb25zdCB1aW50OCogUmVhZExpdHRsZUVuZGlhbjY0RnJvbUFycmF5KGNvbnN0IHVpbnQ4KiBidWZmZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50NjQqIHZhbHVlKTsKKworICAvLyBSZWFkIGFuIHVuc2lnbmVkIGludGVnZXIgd2l0aCBWYXJpbnQgZW5jb2RpbmcsIHRydW5jYXRpbmcgdG8gMzIgYml0cy4KKyAgLy8gUmVhZGluZyBhIDMyLWJpdCB2YWx1ZSBpcyBlcXVpdmFsZW50IHRvIHJlYWRpbmcgYSA2NC1iaXQgb25lIGFuZCBjYXN0aW5nCisgIC8vIGl0IHRvIHVpbnQzMiwgYnV0IG1heSBiZSBtb3JlIGVmZmljaWVudC4KKyAgYm9vbCBSZWFkVmFyaW50MzIodWludDMyKiB2YWx1ZSk7CisgIC8vIFJlYWQgYW4gdW5zaWduZWQgaW50ZWdlciB3aXRoIFZhcmludCBlbmNvZGluZy4KKyAgYm9vbCBSZWFkVmFyaW50NjQodWludDY0KiB2YWx1ZSk7CisKKyAgLy8gUmVhZCBhIHRhZy4gIFRoaXMgY2FsbHMgUmVhZFZhcmludDMyKCkgYW5kIHJldHVybnMgdGhlIHJlc3VsdCwgb3IgcmV0dXJucworICAvLyB6ZXJvICh3aGljaCBpcyBub3QgYSB2YWxpZCB0YWcpIGlmIFJlYWRWYXJpbnQzMigpIGZhaWxzLiAgQWxzbywgaXQgdXBkYXRlcworICAvLyB0aGUgbGFzdCB0YWcgdmFsdWUsIHdoaWNoIGNhbiBiZSBjaGVja2VkIHdpdGggTGFzdFRhZ1dhcygpLgorICAvLyBBbHdheXMgaW5saW5lIGJlY2F1c2UgdGhpcyBpcyBvbmx5IGNhbGxlZCBpbiBvbmUgcGxhY2UgcGVyIHBhcnNlIGxvb3AKKyAgLy8gYnV0IGl0IGlzIGNhbGxlZCBmb3IgZXZlcnkgaXRlcmF0aW9uIG9mIHNhaWQgbG9vcCwgc28gaXQgc2hvdWxkIGJlIGZhc3QuCisgIC8vIEdDQyBkb2Vzbid0IHdhbnQgdG8gaW5saW5lIHRoaXMgYnkgZGVmYXVsdC4KKyAgR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FIHVpbnQzMiBSZWFkVGFnKCk7CisKKyAgLy8gVGhpcyB1c3VhbGx5IGEgZmFzdGVyIGFsdGVybmF0aXZlIHRvIFJlYWRUYWcoKSB3aGVuIGN1dG9mZiBpcyBhIG1hbmlmZXN0CisgIC8vIGNvbnN0YW50LiAgSXQgZG9lcyBwYXJ0aWN1bGFybHkgd2VsbCBmb3IgY3V0b2ZmID49IDEyNy4gIFRoZSBmaXJzdCBwYXJ0CisgIC8vIG9mIHRoZSByZXR1cm4gdmFsdWUgaXMgdGhlIHRhZyB0aGF0IHdhcyByZWFkLCB0aG91Z2ggaXQgY2FuIGFsc28gYmUgMCBpbgorICAvLyB0aGUgY2FzZXMgd2hlcmUgUmVhZFRhZygpIHdvdWxkIHJldHVybiAwLiAgSWYgdGhlIHNlY29uZCBwYXJ0IGlzIHRydWUKKyAgLy8gdGhlbiB0aGUgdGFnIGlzIGtub3duIHRvIGJlIGluIFswLCBjdXRvZmZdLiAgSWYgbm90LCB0aGUgdGFnIGVpdGhlciBpcworICAvLyBhYm92ZSBjdXRvZmYgb3IgaXMgMC4gIChUaGVyZSdzIGludGVudGlvbmFsIHdpZ2dsZSByb29tIHdoZW4gdGFnIGlzIDAsCisgIC8vIGJlY2F1c2UgdGhhdCBjYW4gYXJpc2UgaW4gc2V2ZXJhbCB3YXlzLCBhbmQgZm9yIGJlc3QgcGVyZm9ybWFuY2Ugd2Ugd2FudAorICAvLyB0byBhdm9pZCBhbiBleHRyYSAiaXMgdGFnID09IDA/IiBjaGVjayBoZXJlLikKKyAgR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FIHN0ZDo6cGFpcjx1aW50MzIsIGJvb2w+IFJlYWRUYWdXaXRoQ3V0b2ZmKAorICAgICAgdWludDMyIGN1dG9mZik7CisKKyAgLy8gVXN1YWxseSByZXR1cm5zIHRydWUgaWYgY2FsbGluZyBSZWFkVmFyaW50MzIoKSBub3cgd291bGQgcHJvZHVjZSB0aGUgZ2l2ZW4KKyAgLy8gdmFsdWUuICBXaWxsIGFsd2F5cyByZXR1cm4gZmFsc2UgaWYgUmVhZFZhcmludDMyKCkgd291bGQgbm90IHJldHVybiB0aGUKKyAgLy8gZ2l2ZW4gdmFsdWUuICBJZiBFeHBlY3RUYWcoKSByZXR1cm5zIHRydWUsIGl0IGFsc28gYWR2YW5jZXMgcGFzdAorICAvLyB0aGUgdmFyaW50LiAgRm9yIGJlc3QgcGVyZm9ybWFuY2UsIHVzZSBhIGNvbXBpbGUtdGltZSBjb25zdGFudCBhcyB0aGUKKyAgLy8gcGFyYW1ldGVyLgorICAvLyBBbHdheXMgaW5saW5lIGJlY2F1c2UgdGhpcyBjb2xsYXBzZXMgdG8gYSBzbWFsbCBudW1iZXIgb2YgaW5zdHJ1Y3Rpb25zCisgIC8vIHdoZW4gZ2l2ZW4gYSBjb25zdGFudCBwYXJhbWV0ZXIsIGJ1dCBHQ0MgZG9lc24ndCB3YW50IHRvIGlubGluZSBieSBkZWZhdWx0LgorICBHT09HTEVfQVRUUklCVVRFX0FMV0FZU19JTkxJTkUgYm9vbCBFeHBlY3RUYWcodWludDMyIGV4cGVjdGVkKTsKKworICAvLyBMaWtlIGFib3ZlLCBleGNlcHQgdGhpcyByZWFkcyBmcm9tIHRoZSBzcGVjaWZpZWQgYnVmZmVyLiBUaGUgY2FsbGVyIGlzCisgIC8vIHJlc3BvbnNpYmxlIGZvciBlbnN1cmluZyB0aGF0IHRoZSBidWZmZXIgaXMgbGFyZ2UgZW5vdWdoIHRvIHJlYWQgYSB2YXJpbnQKKyAgLy8gb2YgdGhlIGV4cGVjdGVkIHNpemUuIEZvciBiZXN0IHBlcmZvcm1hbmNlLCB1c2UgYSBjb21waWxlLXRpbWUgY29uc3RhbnQgYXMKKyAgLy8gdGhlIGV4cGVjdGVkIHRhZyBwYXJhbWV0ZXIuCisgIC8vCisgIC8vIFJldHVybnMgYSBwb2ludGVyIGJleW9uZCB0aGUgZXhwZWN0ZWQgdGFnIGlmIGl0IHdhcyBmb3VuZCwgb3IgTlVMTCBpZiBpdAorICAvLyB3YXMgbm90LgorICBHT09HTEVfQVRUUklCVVRFX0FMV0FZU19JTkxJTkUgc3RhdGljIGNvbnN0IHVpbnQ4KiBFeHBlY3RUYWdGcm9tQXJyYXkoCisgICAgICBjb25zdCB1aW50OCogYnVmZmVyLAorICAgICAgdWludDMyIGV4cGVjdGVkKTsKKworICAvLyBVc3VhbGx5IHJldHVybnMgdHJ1ZSBpZiBubyBtb3JlIGJ5dGVzIGNhbiBiZSByZWFkLiAgQWx3YXlzIHJldHVybnMgZmFsc2UKKyAgLy8gaWYgbW9yZSBieXRlcyBjYW4gYmUgcmVhZC4gIElmIEV4cGVjdEF0RW5kKCkgcmV0dXJucyB0cnVlLCBhIHN1YnNlcXVlbnQKKyAgLy8gY2FsbCB0byBMYXN0VGFnV2FzKCkgd2lsbCBhY3QgYXMgaWYgUmVhZFRhZygpIGhhZCBiZWVuIGNhbGxlZCBhbmQgcmV0dXJuZWQKKyAgLy8gemVybywgYW5kIENvbnN1bWVkRW50aXJlTWVzc2FnZSgpIHdpbGwgcmV0dXJuIHRydWUuCisgIGJvb2wgRXhwZWN0QXRFbmQoKTsKKworICAvLyBJZiB0aGUgbGFzdCBjYWxsIHRvIFJlYWRUYWcoKSBvciBSZWFkVGFnV2l0aEN1dG9mZigpIHJldHVybmVkIHRoZQorICAvLyBnaXZlbiB2YWx1ZSwgcmV0dXJucyB0cnVlLiAgT3RoZXJ3aXNlLCByZXR1cm5zIGZhbHNlOworICAvLworICAvLyBUaGlzIGlzIG5lZWRlZCBiZWNhdXNlIHBhcnNlcnMgZm9yIHNvbWUgdHlwZXMgb2YgZW1iZWRkZWQgbWVzc2FnZXMKKyAgLy8gKHdpdGggZmllbGQgdHlwZSBUWVBFX0dST1VQKSBkb24ndCBhY3R1YWxseSBrbm93IHRoYXQgdGhleSd2ZSByZWFjaGVkIHRoZQorICAvLyBlbmQgb2YgYSBtZXNzYWdlIHVudGlsIHRoZXkgc2VlIGFuIEVOREdST1VQIHRhZywgd2hpY2ggd2FzIGFjdHVhbGx5IHBhcnQKKyAgLy8gb2YgdGhlIGVuY2xvc2luZyBtZXNzYWdlLiAgVGhlIGVuY2xvc2luZyBtZXNzYWdlIHdvdWxkIGxpa2UgdG8gY2hlY2sgdGhhdAorICAvLyB0YWcgdG8gbWFrZSBzdXJlIGl0IGhhZCB0aGUgcmlnaHQgbnVtYmVyLCBzbyBpdCBjYWxscyBMYXN0VGFnV2FzKCkgb24KKyAgLy8gcmV0dXJuIGZyb20gdGhlIGVtYmVkZGVkIHBhcnNlciB0byBjaGVjay4KKyAgYm9vbCBMYXN0VGFnV2FzKHVpbnQzMiBleHBlY3RlZCk7CisKKyAgLy8gV2hlbiBwYXJzaW5nIG1lc3NhZ2UgKGJ1dCBOT1QgYSBncm91cCksIHRoaXMgbWV0aG9kIG11c3QgYmUgY2FsbGVkCisgIC8vIGltbWVkaWF0ZWx5IGFmdGVyIE1lcmdlRnJvbUNvZGVkU3RyZWFtKCkgcmV0dXJucyAoaWYgaXQgcmV0dXJucyB0cnVlKQorICAvLyB0byBmdXJ0aGVyIHZlcmlmeSB0aGF0IHRoZSBtZXNzYWdlIGVuZGVkIGluIGEgbGVnaXRpbWF0ZSB3YXkuICBGb3IKKyAgLy8gZXhhbXBsZSwgdGhpcyB2ZXJpZmllcyB0aGF0IHBhcnNpbmcgZGlkIG5vdCBlbmQgb24gYW4gZW5kLWdyb3VwIHRhZy4KKyAgLy8gSXQgYWxzbyBjaGVja3MgZm9yIHNvbWUgY2FzZXMgd2hlcmUsIGR1ZSB0byBvcHRpbWl6YXRpb25zLAorICAvLyBNZXJnZUZyb21Db2RlZFN0cmVhbSgpIGNhbiBpbmNvcnJlY3RseSByZXR1cm4gdHJ1ZS4KKyAgYm9vbCBDb25zdW1lZEVudGlyZU1lc3NhZ2UoKTsKKworICAvLyBMaW1pdHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAvLyBMaW1pdHMgYXJlIHVzZWQgd2hlbiBwYXJzaW5nIGxlbmd0aC1kZWxpbWl0ZWQgZW1iZWRkZWQgbWVzc2FnZXMuCisgIC8vIEFmdGVyIHRoZSBtZXNzYWdlJ3MgbGVuZ3RoIGlzIHJlYWQsIFB1c2hMaW1pdCgpIGlzIHVzZWQgdG8gcHJldmVudAorICAvLyB0aGUgQ29kZWRJbnB1dFN0cmVhbSBmcm9tIHJlYWRpbmcgYmV5b25kIHRoYXQgbGVuZ3RoLiAgT25jZSB0aGUKKyAgLy8gZW1iZWRkZWQgbWVzc2FnZSBoYXMgYmVlbiBwYXJzZWQsIFBvcExpbWl0KCkgaXMgY2FsbGVkIHRvIHVuZG8gdGhlCisgIC8vIGxpbWl0LgorCisgIC8vIE9wYXF1ZSB0eXBlIHVzZWQgd2l0aCBQdXNoTGltaXQoKSBhbmQgUG9wTGltaXQoKS4gIERvIG5vdCBtb2RpZnkKKyAgLy8gdmFsdWVzIG9mIHRoaXMgdHlwZSB5b3Vyc2VsZi4gIFRoZSBvbmx5IHJlYXNvbiB0aGF0IHRoaXMgaXNuJ3QgYQorICAvLyBzdHJ1Y3Qgd2l0aCBwcml2YXRlIGludGVybmFscyBpcyBmb3IgZWZmaWNpZW5jeS4KKyAgdHlwZWRlZiBpbnQgTGltaXQ7CisKKyAgLy8gUGxhY2VzIGEgbGltaXQgb24gdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IHRoZSBzdHJlYW0gbWF5IHJlYWQsCisgIC8vIHN0YXJ0aW5nIGZyb20gdGhlIGN1cnJlbnQgcG9zaXRpb24uICBPbmNlIHRoZSBzdHJlYW0gaGl0cyB0aGlzIGxpbWl0LAorICAvLyBpdCB3aWxsIGFjdCBsaWtlIHRoZSBlbmQgb2YgdGhlIGlucHV0IGhhcyBiZWVuIHJlYWNoZWQgdW50aWwgUG9wTGltaXQoKQorICAvLyBpcyBjYWxsZWQuCisgIC8vCisgIC8vIEFzIHRoZSBuYW1lcyBpbXBseSwgdGhlIHN0cmVhbSBjb25jZXB0dWFsbHkgaGFzIGEgc3RhY2sgb2YgbGltaXRzLiAgVGhlCisgIC8vIHNob3J0ZXN0IGxpbWl0IG9uIHRoZSBzdGFjayBpcyBhbHdheXMgZW5mb3JjZWQsIGV2ZW4gaWYgaXQgaXMgbm90IHRoZQorICAvLyB0b3AgbGltaXQuCisgIC8vCisgIC8vIFRoZSB2YWx1ZSByZXR1cm5lZCBieSBQdXNoTGltaXQoKSBpcyBvcGFxdWUgdG8gdGhlIGNhbGxlciwgYW5kIG11c3QKKyAgLy8gYmUgcGFzc2VkIHVuY2hhbmdlZCB0byB0aGUgY29ycmVzcG9uZGluZyBjYWxsIHRvIFBvcExpbWl0KCkuCisgIExpbWl0IFB1c2hMaW1pdChpbnQgYnl0ZV9saW1pdCk7CisKKyAgLy8gUG9wcyB0aGUgbGFzdCBsaW1pdCBwdXNoZWQgYnkgUHVzaExpbWl0KCkuICBUaGUgaW5wdXQgbXVzdCBiZSB0aGUgdmFsdWUKKyAgLy8gcmV0dXJuZWQgYnkgdGhhdCBjYWxsIHRvIFB1c2hMaW1pdCgpLgorICB2b2lkIFBvcExpbWl0KExpbWl0IGxpbWl0KTsKKworICAvLyBSZXR1cm5zIHRoZSBudW1iZXIgb2YgYnl0ZXMgbGVmdCB1bnRpbCB0aGUgbmVhcmVzdCBsaW1pdCBvbiB0aGUKKyAgLy8gc3RhY2sgaXMgaGl0LCBvciAtMSBpZiBubyBsaW1pdHMgYXJlIGluIHBsYWNlLgorICBpbnQgQnl0ZXNVbnRpbExpbWl0KCkgY29uc3Q7CisKKyAgLy8gUmV0dXJucyBjdXJyZW50IHBvc2l0aW9uIHJlbGF0aXZlIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGlucHV0IHN0cmVhbS4KKyAgaW50IEN1cnJlbnRQb3NpdGlvbigpIGNvbnN0OworCisgIC8vIFRvdGFsIEJ5dGVzIExpbWl0IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8vIFRvIHByZXZlbnQgbWFsaWNpb3VzIHVzZXJzIGZyb20gc2VuZGluZyBleGNlc3NpdmVseSBsYXJnZSBtZXNzYWdlcworICAvLyBhbmQgY2F1c2luZyBpbnRlZ2VyIG92ZXJmbG93cyBvciBtZW1vcnkgZXhoYXVzdGlvbiwgQ29kZWRJbnB1dFN0cmVhbQorICAvLyBpbXBvc2VzIGEgaGFyZCBsaW1pdCBvbiB0aGUgdG90YWwgbnVtYmVyIG9mIGJ5dGVzIGl0IHdpbGwgcmVhZC4KKworICAvLyBTZXRzIHRoZSBtYXhpbXVtIG51bWJlciBvZiBieXRlcyB0aGF0IHRoaXMgQ29kZWRJbnB1dFN0cmVhbSB3aWxsIHJlYWQKKyAgLy8gYmVmb3JlIHJlZnVzaW5nIHRvIGNvbnRpbnVlLiAgVG8gcHJldmVudCBpbnRlZ2VyIG92ZXJmbG93cyBpbiB0aGUKKyAgLy8gcHJvdG9jb2wgYnVmZmVycyBpbXBsZW1lbnRhdGlvbiwgYXMgd2VsbCBhcyB0byBwcmV2ZW50IHNlcnZlcnMgZnJvbQorICAvLyBhbGxvY2F0aW5nIGVub3Jtb3VzIGFtb3VudHMgb2YgbWVtb3J5IHRvIGhvbGQgcGFyc2VkIG1lc3NhZ2VzLCB0aGUKKyAgLy8gbWF4aW11bSBtZXNzYWdlIGxlbmd0aCBzaG91bGQgYmUgbGltaXRlZCB0byB0aGUgc2hvcnRlc3QgbGVuZ3RoIHRoYXQKKyAgLy8gd2lsbCBub3QgaGFybSB1c2FiaWxpdHkuICBUaGUgdGhlb3JldGljYWwgc2hvcnRlc3QgbWVzc2FnZSB0aGF0IGNvdWxkCisgIC8vIGNhdXNlIGludGVnZXIgb3ZlcmZsb3dzIGlzIDUxMk1CLiAgVGhlIGRlZmF1bHQgbGltaXQgaXMgNjRNQi4gIEFwcHMKKyAgLy8gc2hvdWxkIHNldCBzaG9ydGVyIGxpbWl0cyBpZiBwb3NzaWJsZS4gIElmIHdhcm5pbmdfdGhyZXNob2xkIGlzIG5vdCAtMSwKKyAgLy8gYSB3YXJuaW5nIHdpbGwgYmUgcHJpbnRlZCB0byBzdGRlcnIgYWZ0ZXIgd2FybmluZ190aHJlc2hvbGQgYnl0ZXMgYXJlCisgIC8vIHJlYWQuICBGb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkgYWxsIG5lZ2F0aXZlIHZhbHVlcyBnZXQgc3F1YXNoZWQgdG8gLTEsCisgIC8vIGFzIG90aGVyIG5lZ2F0aXZlIHZhbHVlcyBtaWdodCBoYXZlIHNwZWNpYWwgaW50ZXJuYWwgbWVhbmluZ3MuCisgIC8vIEFuIGVycm9yIHdpbGwgYWx3YXlzIGJlIHByaW50ZWQgdG8gc3RkZXJyIGlmIHRoZSBsaW1pdCBpcyByZWFjaGVkLgorICAvLworICAvLyBUaGlzIGlzIHVucmVsYXRlZCB0byBQdXNoTGltaXQoKS9Qb3BMaW1pdCgpLgorICAvLworICAvLyBIaW50OiAgSWYgeW91IGFyZSByZWFkaW5nIHRoaXMgYmVjYXVzZSB5b3VyIHByb2dyYW0gaXMgcHJpbnRpbmcgYQorICAvLyAgIHdhcm5pbmcgYWJvdXQgZGFuZ2Vyb3VzbHkgbGFyZ2UgcHJvdG9jb2wgbWVzc2FnZXMsIHlvdSBtYXkgYmUKKyAgLy8gICBjb25mdXNlZCBhYm91dCB3aGF0IHRvIGRvIG5leHQuICBUaGUgYmVzdCBvcHRpb24gaXMgdG8gY2hhbmdlIHlvdXIKKyAgLy8gICBkZXNpZ24gc3VjaCB0aGF0IGV4Y2Vzc2l2ZWx5IGxhcmdlIG1lc3NhZ2VzIGFyZSBub3QgbmVjZXNzYXJ5LgorICAvLyAgIEZvciBleGFtcGxlLCB0cnkgdG8gZGVzaWduIGZpbGUgZm9ybWF0cyB0byBjb25zaXN0IG9mIG1hbnkgc21hbGwKKyAgLy8gICBtZXNzYWdlcyByYXRoZXIgdGhhbiBhIHNpbmdsZSBsYXJnZSBvbmUuICBJZiB0aGlzIGlzIGluZmVhc2libGUsCisgIC8vICAgeW91IHdpbGwgbmVlZCB0byBpbmNyZWFzZSB0aGUgbGltaXQuICBDaGFuY2VzIGFyZSwgdGhvdWdoLCB0aGF0CisgIC8vICAgeW91ciBjb2RlIG5ldmVyIGNvbnN0cnVjdHMgYSBDb2RlZElucHV0U3RyZWFtIG9uIHdoaWNoIHRoZSBsaW1pdAorICAvLyAgIGNhbiBiZSBzZXQuICBZb3UgcHJvYmFibHkgcGFyc2UgbWVzc2FnZXMgYnkgY2FsbGluZyB0aGluZ3MgbGlrZQorICAvLyAgIE1lc3NhZ2U6OlBhcnNlRnJvbVN0cmluZygpLiAgSW4gdGhpcyBjYXNlLCB5b3Ugd2lsbCBuZWVkIHRvIGNoYW5nZQorICAvLyAgIHlvdXIgY29kZSB0byBpbnN0ZWFkIGNvbnN0cnVjdCBzb21lIHNvcnQgb2YgWmVyb0NvcHlJbnB1dFN0cmVhbQorICAvLyAgIChlLmcuIGFuIEFycmF5SW5wdXRTdHJlYW0pLCBjb25zdHJ1Y3QgYSBDb2RlZElucHV0U3RyZWFtIGFyb3VuZAorICAvLyAgIHRoYXQsIHRoZW4gY2FsbCBNZXNzYWdlOjpQYXJzZUZyb21Db2RlZFN0cmVhbSgpIGluc3RlYWQuICBUaGVuCisgIC8vICAgeW91IGNhbiBhZGp1c3QgdGhlIGxpbWl0LiAgWWVzLCBpdCdzIG1vcmUgd29yaywgYnV0IHlvdSdyZSBkb2luZworICAvLyAgIHNvbWV0aGluZyB1bnVzdWFsLgorICB2b2lkIFNldFRvdGFsQnl0ZXNMaW1pdChpbnQgdG90YWxfYnl0ZXNfbGltaXQsIGludCB3YXJuaW5nX3RocmVzaG9sZCk7CisKKyAgLy8gVGhlIFRvdGFsIEJ5dGVzIExpbWl0IG1pbnVzIHRoZSBDdXJyZW50IFBvc2l0aW9uLCBvciAtMSBpZiB0aGVyZQorICAvLyBpcyBubyBUb3RhbCBCeXRlcyBMaW1pdC4KKyAgaW50IEJ5dGVzVW50aWxUb3RhbEJ5dGVzTGltaXQoKSBjb25zdDsKKworICAvLyBSZWN1cnNpb24gTGltaXQgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAvLyBUbyBwcmV2ZW50IGNvcnJ1cHQgb3IgbWFsaWNpb3VzIG1lc3NhZ2VzIGZyb20gY2F1c2luZyBzdGFjayBvdmVyZmxvd3MsCisgIC8vIHdlIG11c3Qga2VlcCB0cmFjayBvZiB0aGUgZGVwdGggb2YgcmVjdXJzaW9uIHdoZW4gcGFyc2luZyBlbWJlZGRlZAorICAvLyBtZXNzYWdlcyBhbmQgZ3JvdXBzLiAgQ29kZWRJbnB1dFN0cmVhbSBrZWVwcyB0cmFjayBvZiB0aGlzIGJlY2F1c2UgaXQKKyAgLy8gaXMgdGhlIG9ubHkgb2JqZWN0IHRoYXQgaXMgcGFzc2VkIGRvd24gdGhlIHN0YWNrIGR1cmluZyBwYXJzaW5nLgorCisgIC8vIFNldHMgdGhlIG1heGltdW0gcmVjdXJzaW9uIGRlcHRoLiAgVGhlIGRlZmF1bHQgaXMgMTAwLgorICB2b2lkIFNldFJlY3Vyc2lvbkxpbWl0KGludCBsaW1pdCk7CisKKworICAvLyBJbmNyZW1lbnRzIHRoZSBjdXJyZW50IHJlY3Vyc2lvbiBkZXB0aC4gIFJldHVybnMgdHJ1ZSBpZiB0aGUgZGVwdGggaXMKKyAgLy8gdW5kZXIgdGhlIGxpbWl0LCBmYWxzZSBpZiBpdCBoYXMgZ29uZSBvdmVyLgorICBib29sIEluY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCk7CisKKyAgLy8gRGVjcmVtZW50cyB0aGUgcmVjdXJzaW9uIGRlcHRoIGlmIHBvc3NpYmxlLgorICB2b2lkIERlY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCk7CisKKyAgLy8gRGVjcmVtZW50cyB0aGUgcmVjdXJzaW9uIGRlcHRoIGJsaW5kbHkuICBUaGlzIGlzIGZhc3RlciB0aGFuCisgIC8vIERlY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCkuICBJdCBzaG91bGQgYmUgdXNlZCBvbmx5IGlmIGFsbCBwcmV2aW91cworICAvLyBpbmNyZW1lbnRzIHRvIHJlY3Vyc2lvbiBkZXB0aCB3ZXJlIHN1Y2Nlc3NmdWwuCisgIHZvaWQgVW5zYWZlRGVjcmVtZW50UmVjdXJzaW9uRGVwdGgoKTsKKworICAvLyBTaG9ydGhhbmQgZm9yIG1ha2VfcGFpcihQdXNoTGltaXQoYnl0ZV9saW1pdCksIC0tcmVjdXJzaW9uX2J1ZGdldF8pLgorICAvLyBVc2luZyB0aGlzIGNhbiByZWR1Y2UgY29kZSBzaXplIGFuZCBjb21wbGV4aXR5IGluIHNvbWUgY2FzZXMuICBUaGUgY2FsbGVyCisgIC8vIGlzIGV4cGVjdGVkIHRvIGNoZWNrIHRoYXQgdGhlIHNlY29uZCBwYXJ0IG9mIHRoZSByZXN1bHQgaXMgbm9uLW5lZ2F0aXZlICh0bworICAvLyBiYWlsIG91dCBpZiB0aGUgZGVwdGggb2YgcmVjdXJzaW9uIGlzIHRvbyBoaWdoKSBhbmQsIGlmIGFsbCBpcyB3ZWxsLCB0bworICAvLyBsYXRlciBwYXNzIHRoZSBmaXJzdCBwYXJ0IG9mIHRoZSByZXN1bHQgdG8gUG9wTGltaXQoKSBvciBzaW1pbGFyLgorICBzdGQ6OnBhaXI8Q29kZWRJbnB1dFN0cmVhbTo6TGltaXQsIGludD4gSW5jcmVtZW50UmVjdXJzaW9uRGVwdGhBbmRQdXNoTGltaXQoCisgICAgICBpbnQgYnl0ZV9saW1pdCk7CisKKyAgLy8gU2hvcnRoYW5kIGZvciBQdXNoTGltaXQoUmVhZFZhcmludDMyKCZsZW5ndGgpID8gbGVuZ3RoIDogMCkuCisgIExpbWl0IFJlYWRMZW5ndGhBbmRQdXNoTGltaXQoKTsKKworICAvLyBIZWxwZXIgdGhhdCBpcyBlcXVpdmFsZW50IHRvOiB7CisgIC8vICBib29sIHJlc3VsdCA9IENvbnN1bWVkRW50aXJlTWVzc2FnZSgpOworICAvLyAgUG9wTGltaXQobGltaXQpOworICAvLyAgVW5zYWZlRGVjcmVtZW50UmVjdXJzaW9uRGVwdGgoKTsKKyAgLy8gIHJldHVybiByZXN1bHQ7IH0KKyAgLy8gVXNpbmcgdGhpcyBjYW4gcmVkdWNlIGNvZGUgc2l6ZSBhbmQgY29tcGxleGl0eSBpbiBzb21lIGNhc2VzLgorICAvLyBEbyBub3QgdXNlIHVubGVzcyB0aGUgY3VycmVudCByZWN1cnNpb24gZGVwdGggaXMgZ3JlYXRlciB0aGFuIHplcm8uCisgIGJvb2wgRGVjcmVtZW50UmVjdXJzaW9uRGVwdGhBbmRQb3BMaW1pdChMaW1pdCBsaW1pdCk7CisKKyAgLy8gSGVscGVyIHRoYXQgaXMgZXF1aXZhbGVudCB0bzogeworICAvLyAgYm9vbCByZXN1bHQgPSBDb25zdW1lZEVudGlyZU1lc3NhZ2UoKTsKKyAgLy8gIFBvcExpbWl0KGxpbWl0KTsKKyAgLy8gIHJldHVybiByZXN1bHQ7IH0KKyAgLy8gVXNpbmcgdGhpcyBjYW4gcmVkdWNlIGNvZGUgc2l6ZSBhbmQgY29tcGxleGl0eSBpbiBzb21lIGNhc2VzLgorICBib29sIENoZWNrRW50aXJlTWVzc2FnZUNvbnN1bWVkQW5kUG9wTGltaXQoTGltaXQgbGltaXQpOworCisgIC8vIEV4dGVuc2lvbiBSZWdpc3RyeSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8vIEFEVkFOQ0VEIFVTQUdFOiAgOTkuOSUgb2YgcGVvcGxlIGNhbiBpZ25vcmUgdGhpcyBzZWN0aW9uLgorICAvLworICAvLyBCeSBkZWZhdWx0LCB3aGVuIHBhcnNpbmcgZXh0ZW5zaW9ucywgdGhlIHBhcnNlciBsb29rcyBmb3IgZXh0ZW5zaW9uCisgIC8vIGRlZmluaXRpb25zIGluIHRoZSBwb29sIHdoaWNoIG93bnMgdGhlIG91dGVyIG1lc3NhZ2UncyBEZXNjcmlwdG9yLgorICAvLyBIb3dldmVyLCB5b3UgbWF5IGNhbGwgU2V0RXh0ZW5zaW9uUmVnaXN0cnkoKSB0byBwcm92aWRlIGFuIGFsdGVybmF0aXZlCisgIC8vIHBvb2wgaW5zdGVhZC4gIFRoaXMgbWFrZXMgaXQgcG9zc2libGUsIGZvciBleGFtcGxlLCB0byBwYXJzZSBhIG1lc3NhZ2UKKyAgLy8gdXNpbmcgYSBnZW5lcmF0ZWQgY2xhc3MsIGJ1dCByZXByZXNlbnQgc29tZSBleHRlbnNpb25zIHVzaW5nCisgIC8vIER5bmFtaWNNZXNzYWdlLgorCisgIC8vIFNldCB0aGUgcG9vbCB1c2VkIHRvIGxvb2sgdXAgZXh0ZW5zaW9ucy4gIE1vc3QgdXNlcnMgZG8gbm90IG5lZWQgdG8gY2FsbAorICAvLyB0aGlzIGFzIHRoZSBjb3JyZWN0IHBvb2wgd2lsbCBiZSBjaG9zZW4gYXV0b21hdGljYWxseS4KKyAgLy8KKyAgLy8gV0FSTklORzogIEl0IGlzIHZlcnkgZWFzeSB0byBtaXN1c2UgdGhpcy4gIENhcmVmdWxseSByZWFkIHRoZSByZXF1aXJlbWVudHMKKyAgLy8gICBiZWxvdy4gIERvIG5vdCB1c2UgdGhpcyB1bmxlc3MgeW91IGFyZSBzdXJlIHlvdSBuZWVkIGl0LiAgQWxtb3N0IG5vIG9uZQorICAvLyAgIGRvZXMuCisgIC8vCisgIC8vIExldCdzIHNheSB5b3UgYXJlIHBhcnNpbmcgYSBtZXNzYWdlIGludG8gbWVzc2FnZSBvYmplY3QgbSwgYW5kIHlvdSB3YW50CisgIC8vIHRvIHRha2UgYWR2YW50YWdlIG9mIFNldEV4dGVuc2lvblJlZ2lzdHJ5KCkuICBZb3UgbXVzdCBmb2xsb3cgdGhlc2UKKyAgLy8gcmVxdWlyZW1lbnRzOgorICAvLworICAvLyBUaGUgZ2l2ZW4gRGVzY3JpcHRvclBvb2wgbXVzdCBjb250YWluIG0tPkdldERlc2NyaXB0b3IoKS4gIEl0IGlzIG5vdAorICAvLyBzdWZmaWNpZW50IGZvciBpdCB0byBzaW1wbHkgY29udGFpbiBhIGRlc2NyaXB0b3IgdGhhdCBoYXMgdGhlIHNhbWUgbmFtZQorICAvLyBhbmQgY29udGVudCAtLSBpdCBtdXN0IGJlIHRoZSAqZXhhY3Qgb2JqZWN0Ki4gIEluIG90aGVyIHdvcmRzOgorICAvLyAgIGFzc2VydChwb29sLT5GaW5kTWVzc2FnZVR5cGVCeU5hbWUobS0+R2V0RGVzY3JpcHRvcigpLT5mdWxsX25hbWUoKSkgPT0KKyAgLy8gICAgICAgICAgbS0+R2V0RGVzY3JpcHRvcigpKTsKKyAgLy8gVGhlcmUgYXJlIHR3byB3YXlzIHRvIHNhdGlzZnkgdGhpcyByZXF1aXJlbWVudDoKKyAgLy8gMSkgVXNlIG0tPkdldERlc2NyaXB0b3IoKS0+cG9vbCgpIGFzIHRoZSBwb29sLiAgVGhpcyBpcyBnZW5lcmFsbHkgdXNlbGVzcworICAvLyAgICBiZWNhdXNlIHRoaXMgaXMgdGhlIHBvb2wgdGhhdCB3b3VsZCBiZSB1c2VkIGFueXdheSBpZiB5b3UgZGlkbid0IGNhbGwKKyAgLy8gICAgU2V0RXh0ZW5zaW9uUmVnaXN0cnkoKSBhdCBhbGwuCisgIC8vIDIpIFVzZSBhIERlc2NyaXB0b3JQb29sIHdoaWNoIGhhcyBtLT5HZXREZXNjcmlwdG9yKCktPnBvb2woKSBhcyBhbgorICAvLyAgICAidW5kZXJsYXkiLiAgUmVhZCB0aGUgZG9jdW1lbnRhdGlvbiBmb3IgRGVzY3JpcHRvclBvb2wgZm9yIG1vcmUKKyAgLy8gICAgaW5mb3JtYXRpb24gYWJvdXQgdW5kZXJsYXlzLgorICAvLworICAvLyBZb3UgbXVzdCBhbHNvIHByb3ZpZGUgYSBNZXNzYWdlRmFjdG9yeS4gIFRoaXMgZmFjdG9yeSB3aWxsIGJlIHVzZWQgdG8KKyAgLy8gY29uc3RydWN0IE1lc3NhZ2Ugb2JqZWN0cyByZXByZXNlbnRpbmcgZXh0ZW5zaW9ucy4gIFRoZSBmYWN0b3J5J3MKKyAgLy8gR2V0UHJvdG90eXBlKCkgTVVTVCByZXR1cm4gbm9uLU5VTEwgZm9yIGFueSBEZXNjcmlwdG9yIHdoaWNoIGNhbiBiZSBmb3VuZAorICAvLyB0aHJvdWdoIHRoZSBwcm92aWRlZCBwb29sLgorICAvLworICAvLyBJZiB0aGUgcHJvdmlkZWQgZmFjdG9yeSBtaWdodCByZXR1cm4gaW5zdGFuY2VzIG9mIHByb3RvY29sLWNvbXBpbGVyLQorICAvLyBnZW5lcmF0ZWQgKGkuZS4gY29tcGlsZWQtaW4pIHR5cGVzLCBvciBpZiB0aGUgb3V0ZXIgbWVzc2FnZSBvYmplY3QgbSBpcworICAvLyBhIGdlbmVyYXRlZCB0eXBlLCB0aGVuIHRoZSBnaXZlbiBmYWN0b3J5IE1VU1QgaGF2ZSB0aGlzIHByb3BlcnR5OiAgSWYKKyAgLy8gR2V0UHJvdG90eXBlKCkgaXMgZ2l2ZW4gYSBEZXNjcmlwdG9yIHdoaWNoIHJlc2lkZXMgaW4KKyAgLy8gRGVzY3JpcHRvclBvb2w6OmdlbmVyYXRlZF9wb29sKCksIHRoZSBmYWN0b3J5IE1VU1QgcmV0dXJuIHRoZSBzYW1lCisgIC8vIHByb3RvdHlwZSB3aGljaCBNZXNzYWdlRmFjdG9yeTo6Z2VuZXJhdGVkX2ZhY3RvcnkoKSB3b3VsZCByZXR1cm4uICBUaGF0CisgIC8vIGlzLCBnaXZlbiBhIGRlc2NyaXB0b3IgZm9yIGEgZ2VuZXJhdGVkIHR5cGUsIHRoZSBmYWN0b3J5IG11c3QgcmV0dXJuIGFuCisgIC8vIGluc3RhbmNlIG9mIHRoZSBnZW5lcmF0ZWQgY2xhc3MgKE5PVCBEeW5hbWljTWVzc2FnZSkuICBIb3dldmVyLCB3aGVuCisgIC8vIGdpdmVuIGEgZGVzY3JpcHRvciBmb3IgYSB0eXBlIHRoYXQgaXMgTk9UIGluIGdlbmVyYXRlZF9wb29sLCB0aGUgZmFjdG9yeQorICAvLyBpcyBmcmVlIHRvIHJldHVybiBhbnkgaW1wbGVtZW50YXRpb24uCisgIC8vCisgIC8vIFRoZSByZWFzb24gZm9yIHRoaXMgcmVxdWlyZW1lbnQgaXMgdGhhdCBnZW5lcmF0ZWQgc3ViLW9iamVjdHMgbWF5IGJlCisgIC8vIGFjY2Vzc2VkIHZpYSB0aGUgc3RhbmRhcmQgKG5vbi1yZWZsZWN0aW9uKSBleHRlbnNpb24gYWNjZXNzb3IgbWV0aG9kcywKKyAgLy8gYW5kIHRoZXNlIG1ldGhvZHMgd2lsbCBkb3duLWNhc3QgdGhlIG9iamVjdCB0byB0aGUgZ2VuZXJhdGVkIGNsYXNzIHR5cGUuCisgIC8vIElmIHRoZSBvYmplY3QgaXMgbm90IGFjdHVhbGx5IG9mIHRoYXQgdHlwZSwgdGhlIHJlc3VsdHMgd291bGQgYmUgdW5kZWZpbmVkLgorICAvLyBPbiB0aGUgb3RoZXIgaGFuZCwgaWYgYW4gZXh0ZW5zaW9uIGlzIG5vdCBjb21waWxlZCBpbiwgdGhlbiB0aGVyZSBpcyBubworICAvLyB3YXkgdGhlIGNvZGUgY291bGQgZW5kIHVwIGFjY2Vzc2luZyBpdCB2aWEgdGhlIHN0YW5kYXJkIGFjY2Vzc29ycyAtLSB0aGUKKyAgLy8gb25seSB3YXkgdG8gYWNjZXNzIHRoZSBleHRlbnNpb24gaXMgdmlhIHJlZmxlY3Rpb24uICBXaGVuIHVzaW5nIHJlZmxlY3Rpb24sCisgIC8vIER5bmFtaWNNZXNzYWdlIGFuZCBnZW5lcmF0ZWQgbWVzc2FnZXMgYXJlIGluZGlzdGluZ3Vpc2hhYmxlLCBzbyBpdCdzIGZpbmUKKyAgLy8gaWYgdGhlc2Ugb2JqZWN0cyBhcmUgcmVwcmVzZW50ZWQgdXNpbmcgRHluYW1pY01lc3NhZ2UuCisgIC8vCisgIC8vIFVzaW5nIER5bmFtaWNNZXNzYWdlRmFjdG9yeSBvbiB3aGljaCB5b3UgaGF2ZSBjYWxsZWQKKyAgLy8gU2V0RGVsZWdhdGVUb0dlbmVyYXRlZEZhY3RvcnkodHJ1ZSkgc2hvdWxkIGJlIHN1ZmZpY2llbnQgdG8gc2F0aXNmeSB0aGUKKyAgLy8gYWJvdmUgcmVxdWlyZW1lbnQuCisgIC8vCisgIC8vIElmIGVpdGhlciBwb29sIG9yIGZhY3RvcnkgaXMgTlVMTCwgYm90aCBtdXN0IGJlIE5VTEwuCisgIC8vCisgIC8vIE5vdGUgdGhhdCB0aGlzIGZlYXR1cmUgaXMgaWdub3JlZCB3aGVuIHBhcnNpbmcgImxpdGUiIG1lc3NhZ2VzIGFzIHRoZXkgZG8KKyAgLy8gbm90IGhhdmUgZGVzY3JpcHRvcnMuCisgIHZvaWQgU2V0RXh0ZW5zaW9uUmVnaXN0cnkoY29uc3QgRGVzY3JpcHRvclBvb2wqIHBvb2wsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUZhY3RvcnkqIGZhY3RvcnkpOworCisgIC8vIEdldCB0aGUgRGVzY3JpcHRvclBvb2wgc2V0IHZpYSBTZXRFeHRlbnNpb25SZWdpc3RyeSgpLCBvciBOVUxMIGlmIG5vIHBvb2wKKyAgLy8gaGFzIGJlZW4gcHJvdmlkZWQuCisgIGNvbnN0IERlc2NyaXB0b3JQb29sKiBHZXRFeHRlbnNpb25Qb29sKCk7CisKKyAgLy8gR2V0IHRoZSBNZXNzYWdlRmFjdG9yeSBzZXQgdmlhIFNldEV4dGVuc2lvblJlZ2lzdHJ5KCksIG9yIE5VTEwgaWYgbm8KKyAgLy8gZmFjdG9yeSBoYXMgYmVlbiBwcm92aWRlZC4KKyAgTWVzc2FnZUZhY3RvcnkqIEdldEV4dGVuc2lvbkZhY3RvcnkoKTsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhDb2RlZElucHV0U3RyZWFtKTsKKworICBjb25zdCB1aW50OCogYnVmZmVyXzsKKyAgY29uc3QgdWludDgqIGJ1ZmZlcl9lbmRfOyAgICAgLy8gcG9pbnRlciB0byB0aGUgZW5kIG9mIHRoZSBidWZmZXIuCisgIFplcm9Db3B5SW5wdXRTdHJlYW0qIGlucHV0XzsKKyAgaW50IHRvdGFsX2J5dGVzX3JlYWRfOyAgLy8gdG90YWwgYnl0ZXMgcmVhZCBmcm9tIGlucHV0XywgaW5jbHVkaW5nCisgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoZSBjdXJyZW50IGJ1ZmZlcgorCisgIC8vIElmIHRvdGFsX2J5dGVzX3JlYWRfIHN1cnBhc3NlcyBJTlRfTUFYLCB3ZSByZWNvcmQgdGhlIGV4dHJhIGJ5dGVzIGhlcmUKKyAgLy8gc28gdGhhdCB3ZSBjYW4gQmFja1VwKCkgb24gZGVzdHJ1Y3Rpb24uCisgIGludCBvdmVyZmxvd19ieXRlc187CisKKyAgLy8gTGFzdFRhZ1dhcygpIHN0dWZmLgorICB1aW50MzIgbGFzdF90YWdfOyAgICAgICAgIC8vIHJlc3VsdCBvZiBsYXN0IFJlYWRUYWcoKSBvciBSZWFkVGFnV2l0aEN1dG9mZigpLgorCisgIC8vIFRoaXMgaXMgc2V0IHRydWUgYnkgUmVhZFRhZ3tGYWxsYmFjay9TbG93fSgpIGlmIGl0IGlzIGNhbGxlZCB3aGVuIGV4YWN0bHkKKyAgLy8gYXQgRU9GLCBvciBieSBFeHBlY3RBdEVuZCgpIHdoZW4gaXQgcmV0dXJucyB0cnVlLiAgVGhpcyBoYXBwZW5zIHdoZW4gd2UKKyAgLy8gcmVhY2ggdGhlIGVuZCBvZiBhIG1lc3NhZ2UgYW5kIGF0dGVtcHQgdG8gcmVhZCBhbm90aGVyIHRhZy4KKyAgYm9vbCBsZWdpdGltYXRlX21lc3NhZ2VfZW5kXzsKKworICAvLyBTZWUgRW5hYmxlQWxpYXNpbmcoKS4KKyAgYm9vbCBhbGlhc2luZ19lbmFibGVkXzsKKworICAvLyBMaW1pdHMKKyAgTGltaXQgY3VycmVudF9saW1pdF87ICAgLy8gaWYgcG9zaXRpb24gPSAtMSwgbm8gbGltaXQgaXMgYXBwbGllZAorCisgIC8vIEZvciBzaW1wbGljaXR5LCBpZiB0aGUgY3VycmVudCBidWZmZXIgY3Jvc3NlcyBhIGxpbWl0IChlaXRoZXIgYSBub3JtYWwKKyAgLy8gbGltaXQgY3JlYXRlZCBieSBQdXNoTGltaXQoKSBvciB0aGUgdG90YWwgYnl0ZXMgbGltaXQpLCBidWZmZXJfc2l6ZV8KKyAgLy8gb25seSB0cmFja3MgdGhlIG51bWJlciBvZiBieXRlcyBiZWZvcmUgdGhhdCBsaW1pdC4gIFRoaXMgZmllbGQKKyAgLy8gY29udGFpbnMgdGhlIG51bWJlciBvZiBieXRlcyBhZnRlciBpdC4gIE5vdGUgdGhhdCB0aGlzIGltcGxpZXMgdGhhdCBpZgorICAvLyBidWZmZXJfc2l6ZV8gPT0gMCBhbmQgYnVmZmVyX3NpemVfYWZ0ZXJfbGltaXRfID4gMCwgd2Uga25vdyB3ZSd2ZQorICAvLyBoaXQgYSBsaW1pdC4gIEhvd2V2ZXIsIGlmIGJvdGggYXJlIHplcm8sIGl0IGRvZXNuJ3QgbmVjZXNzYXJpbHkgbWVhbgorICAvLyB3ZSBhcmVuJ3QgYXQgYSBsaW1pdCAtLSB0aGUgYnVmZmVyIG1heSBoYXZlIGVuZGVkIGV4YWN0bHkgYXQgdGhlIGxpbWl0LgorICBpbnQgYnVmZmVyX3NpemVfYWZ0ZXJfbGltaXRfOworCisgIC8vIE1heGltdW0gbnVtYmVyIG9mIGJ5dGVzIHRvIHJlYWQsIHBlcmlvZC4gIFRoaXMgaXMgdW5yZWxhdGVkIHRvCisgIC8vIGN1cnJlbnRfbGltaXRfLiAgU2V0IHVzaW5nIFNldFRvdGFsQnl0ZXNMaW1pdCgpLgorICBpbnQgdG90YWxfYnl0ZXNfbGltaXRfOworCisgIC8vIElmIHBvc2l0aXZlLzA6IExpbWl0IGZvciBieXRlcyByZWFkIGFmdGVyIHdoaWNoIGEgd2FybmluZyBkdWUgdG8gc2l6ZQorICAvLyBzaG91bGQgYmUgbG9nZ2VkLgorICAvLyBJZiAtMTogUHJpbnRpbmcgb2Ygd2FybmluZyBkaXNhYmxlZC4gQ2FuIGJlIHNldCBieSBjbGllbnQuCisgIC8vIElmIC0yOiBJbnRlcm5hbDogTGltaXQgaGFzIGJlZW4gcmVhY2hlZCwgcHJpbnQgZnVsbCBzaXplIHdoZW4gZGVzdHJ1Y3RpbmcuCisgIGludCB0b3RhbF9ieXRlc193YXJuaW5nX3RocmVzaG9sZF87CisKKyAgLy8gQ3VycmVudCByZWN1cnNpb24gYnVkZ2V0LCBjb250cm9sbGVkIGJ5IEluY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCkgYW5kCisgIC8vIHNpbWlsYXIuICBTdGFydHMgYXQgcmVjdXJzaW9uX2xpbWl0XyBhbmQgZ29lcyBkb3duOiBpZiB0aGlzIHJlYWNoZXMKKyAgLy8gLTEgd2UgYXJlIG92ZXIgYnVkZ2V0LgorICBpbnQgcmVjdXJzaW9uX2J1ZGdldF87CisgIC8vIFJlY3Vyc2lvbiBkZXB0aCBsaW1pdCwgc2V0IGJ5IFNldFJlY3Vyc2lvbkxpbWl0KCkuCisgIGludCByZWN1cnNpb25fbGltaXRfOworCisgIC8vIFNlZSBTZXRFeHRlbnNpb25SZWdpc3RyeSgpLgorICBjb25zdCBEZXNjcmlwdG9yUG9vbCogZXh0ZW5zaW9uX3Bvb2xfOworICBNZXNzYWdlRmFjdG9yeSogZXh0ZW5zaW9uX2ZhY3RvcnlfOworCisgIC8vIFByaXZhdGUgbWVtYmVyIGZ1bmN0aW9ucy4KKworICAvLyBBZHZhbmNlIHRoZSBidWZmZXIgYnkgYSBnaXZlbiBudW1iZXIgb2YgYnl0ZXMuCisgIHZvaWQgQWR2YW5jZShpbnQgYW1vdW50KTsKKworICAvLyBCYWNrIHVwIGlucHV0XyB0byB0aGUgY3VycmVudCBidWZmZXIgcG9zaXRpb24uCisgIHZvaWQgQmFja1VwSW5wdXRUb0N1cnJlbnRQb3NpdGlvbigpOworCisgIC8vIFJlY29tcHV0ZXMgdGhlIHZhbHVlIG9mIGJ1ZmZlcl9zaXplX2FmdGVyX2xpbWl0Xy4gIE11c3QgYmUgY2FsbGVkIGFmdGVyCisgIC8vIGN1cnJlbnRfbGltaXRfIG9yIHRvdGFsX2J5dGVzX2xpbWl0XyBjaGFuZ2VzLgorICB2b2lkIFJlY29tcHV0ZUJ1ZmZlckxpbWl0cygpOworCisgIC8vIFdyaXRlcyBhbiBlcnJvciBtZXNzYWdlIHNheWluZyB0aGF0IHdlIGhpdCB0b3RhbF9ieXRlc19saW1pdF8uCisgIHZvaWQgUHJpbnRUb3RhbEJ5dGVzTGltaXRFcnJvcigpOworCisgIC8vIENhbGxlZCB3aGVuIHRoZSBidWZmZXIgcnVucyBvdXQgdG8gcmVxdWVzdCBtb3JlIGRhdGEuICBJbXBsaWVzIGFuCisgIC8vIEFkdmFuY2UoQnVmZmVyU2l6ZSgpKS4KKyAgYm9vbCBSZWZyZXNoKCk7CisKKyAgLy8gV2hlbiBwYXJzaW5nIHZhcmludHMsIHdlIG9wdGltaXplIGZvciB0aGUgY29tbW9uIGNhc2Ugb2Ygc21hbGwgdmFsdWVzLCBhbmQKKyAgLy8gdGhlbiBvcHRpbWl6ZSBmb3IgdGhlIGNhc2Ugd2hlbiB0aGUgdmFyaW50IGZpdHMgd2l0aGluIHRoZSBjdXJyZW50IGJ1ZmZlcgorICAvLyBwaWVjZS4gVGhlIEZhbGxiYWNrIG1ldGhvZCBpcyB1c2VkIHdoZW4gd2UgY2FuJ3QgdXNlIHRoZSBvbmUtYnl0ZQorICAvLyBvcHRpbWl6YXRpb24uIFRoZSBTbG93IG1ldGhvZCBpcyB5ZXQgYW5vdGhlciBmYWxsYmFjayB3aGVuIHRoZSBidWZmZXIgaXMKKyAgLy8gbm90IGxhcmdlIGVub3VnaC4gTWFraW5nIHRoZSBzbG93IHBhdGggb3V0LW9mLWxpbmUgc3BlZWRzIHVwIHRoZSBjb21tb24KKyAgLy8gY2FzZSBieSAxMC0xNSUuIFRoZSBzbG93IHBhdGggaXMgZmFpcmx5IHVuY29tbW9uOiBpdCBvbmx5IHRyaWdnZXJzIHdoZW4gYQorICAvLyBtZXNzYWdlIGNyb3NzZXMgbXVsdGlwbGUgYnVmZmVycy4gIE5vdGU6IFJlYWRWYXJpbnQzMkZhbGxiYWNrKCkgYW5kCisgIC8vIFJlYWRWYXJpbnQ2NEZhbGxiYWNrKCkgYXJlIGNhbGxlZCBmcmVxdWVudGx5IGFuZCBnZW5lcmFsbHkgbm90IGlubGluZWQsIHNvCisgIC8vIHRoZXkgaGF2ZSBiZWVuIG9wdGltaXplZCB0byBhdm9pZCAib3V0IiBwYXJhbWV0ZXJzLiAgVGhlIGZvcm1lciByZXR1cm5zIC0xCisgIC8vIGlmIGl0IGZhaWxzIGFuZCB0aGUgdWludDMyIGl0IHJlYWQgb3RoZXJ3aXNlLiAgVGhlIGxhdHRlciBoYXMgYSBib29sCisgIC8vIGluZGljYXRpbmcgc3VjY2VzcyBvciBmYWlsdXJlIGFzIHBhcnQgb2YgaXRzIHJldHVybiB0eXBlLgorICBpbnQ2NCBSZWFkVmFyaW50MzJGYWxsYmFjayh1aW50MzIgZmlyc3RfYnl0ZV9vcl96ZXJvKTsKKyAgc3RkOjpwYWlyPHVpbnQ2NCwgYm9vbD4gUmVhZFZhcmludDY0RmFsbGJhY2soKTsKKyAgYm9vbCBSZWFkVmFyaW50MzJTbG93KHVpbnQzMiogdmFsdWUpOworICBib29sIFJlYWRWYXJpbnQ2NFNsb3codWludDY0KiB2YWx1ZSk7CisgIGJvb2wgUmVhZExpdHRsZUVuZGlhbjMyRmFsbGJhY2sodWludDMyKiB2YWx1ZSk7CisgIGJvb2wgUmVhZExpdHRsZUVuZGlhbjY0RmFsbGJhY2sodWludDY0KiB2YWx1ZSk7CisgIC8vIEZhbGxiYWNrL3Nsb3cgbWV0aG9kcyBmb3IgcmVhZGluZyB0YWdzLiBUaGVzZSBkbyBub3QgdXBkYXRlIGxhc3RfdGFnXywKKyAgLy8gYnV0IHdpbGwgc2V0IGxlZ2l0aW1hdGVfbWVzc2FnZV9lbmRfIGlmIHdlIGFyZSBhdCB0aGUgZW5kIG9mIHRoZSBpbnB1dAorICAvLyBzdHJlYW0uCisgIHVpbnQzMiBSZWFkVGFnRmFsbGJhY2sodWludDMyIGZpcnN0X2J5dGVfb3JfemVybyk7CisgIHVpbnQzMiBSZWFkVGFnU2xvdygpOworICBib29sIFJlYWRTdHJpbmdGYWxsYmFjayhzdHJpbmcqIGJ1ZmZlciwgaW50IHNpemUpOworCisgIC8vIFJldHVybiB0aGUgc2l6ZSBvZiB0aGUgYnVmZmVyLgorICBpbnQgQnVmZmVyU2l6ZSgpIGNvbnN0OworCisgIHN0YXRpYyBjb25zdCBpbnQga0RlZmF1bHRUb3RhbEJ5dGVzTGltaXQgPSA2NCA8PCAyMDsgIC8vIDY0TUIKKworICBzdGF0aWMgY29uc3QgaW50IGtEZWZhdWx0VG90YWxCeXRlc1dhcm5pbmdUaHJlc2hvbGQgPSAzMiA8PCAyMDsgIC8vIDMyTUIKKworICBzdGF0aWMgaW50IGRlZmF1bHRfcmVjdXJzaW9uX2xpbWl0XzsgIC8vIDEwMCBieSBkZWZhdWx0LgorfTsKKworLy8gQ2xhc3Mgd2hpY2ggZW5jb2RlcyBhbmQgd3JpdGVzIGJpbmFyeSBkYXRhIHdoaWNoIGlzIGNvbXBvc2VkIG9mIHZhcmludC0KKy8vIGVuY29kZWQgaW50ZWdlcnMgYW5kIGZpeGVkLXdpZHRoIHBpZWNlcy4gIFdyYXBzIGEgWmVyb0NvcHlPdXRwdXRTdHJlYW0uCisvLyBNb3N0IHVzZXJzIHdpbGwgbm90IG5lZWQgdG8gZGVhbCB3aXRoIENvZGVkT3V0cHV0U3RyZWFtLgorLy8KKy8vIE1vc3QgbWV0aG9kcyBvZiBDb2RlZE91dHB1dFN0cmVhbSB3aGljaCByZXR1cm4gYSBib29sIHJldHVybiBmYWxzZSBpZiBhbgorLy8gdW5kZXJseWluZyBJL08gZXJyb3Igb2NjdXJzLiAgT25jZSBzdWNoIGEgZmFpbHVyZSBvY2N1cnMsIHRoZQorLy8gQ29kZWRPdXRwdXRTdHJlYW0gaXMgYnJva2VuIGFuZCBpcyBubyBsb25nZXIgdXNlZnVsLiBUaGUgV3JpdGUqIG1ldGhvZHMgZG8KKy8vIG5vdCByZXR1cm4gdGhlIHN0cmVhbSBzdGF0dXMsIGJ1dCB3aWxsIGludmFsaWRhdGUgdGhlIHN0cmVhbSBpZiBhbiBlcnJvcgorLy8gb2NjdXJzLiBUaGUgY2xpZW50IGNhbiBwcm9iZSBIYWRFcnJvcigpIHRvIGRldGVybWluZSB0aGUgc3RhdHVzLgorLy8KKy8vIE5vdGUgdGhhdCBldmVyeSBtZXRob2Qgb2YgQ29kZWRPdXRwdXRTdHJlYW0gd2hpY2ggd3JpdGVzIHNvbWUgZGF0YSBoYXMKKy8vIGEgY29ycmVzcG9uZGluZyBzdGF0aWMgIlRvQXJyYXkiIHZlcnNpb24uIFRoZXNlIHZlcnNpb25zIHdyaXRlIGRpcmVjdGx5CisvLyB0byB0aGUgcHJvdmlkZWQgYnVmZmVyLCByZXR1cm5pbmcgYSBwb2ludGVyIHBhc3QgdGhlIGxhc3Qgd3JpdHRlbiBieXRlLgorLy8gVGhleSByZXF1aXJlIHRoYXQgdGhlIGJ1ZmZlciBoYXMgc3VmZmljaWVudCBjYXBhY2l0eSBmb3IgdGhlIGVuY29kZWQgZGF0YS4KKy8vIFRoaXMgYWxsb3dzIGFuIG9wdGltaXphdGlvbiB3aGVyZSB3ZSBjaGVjayBpZiBhbiBvdXRwdXQgc3RyZWFtIGhhcyBlbm91Z2gKKy8vIHNwYWNlIGZvciBhbiBlbnRpcmUgbWVzc2FnZSBiZWZvcmUgd2Ugc3RhcnQgd3JpdGluZyBhbmQsIGlmIHRoZXJlIGlzLCB3ZQorLy8gY2FsbCBvbmx5IHRoZSBUb0FycmF5IG1ldGhvZHMgdG8gYXZvaWQgZG9pbmcgYm91bmQgY2hlY2tzIGZvciBlYWNoCisvLyBpbmRpdmlkdWFsIHZhbHVlLgorLy8gaS5lLiwgaW4gdGhlIGV4YW1wbGUgYWJvdmU6CisvLworLy8gICBDb2RlZE91dHB1dFN0cmVhbSBjb2RlZF9vdXRwdXQgPSBuZXcgQ29kZWRPdXRwdXRTdHJlYW0ocmF3X291dHB1dCk7CisvLyAgIGludCBtYWdpY19udW1iZXIgPSAxMjM0OworLy8gICBjaGFyIHRleHRbXSA9ICJIZWxsbyB3b3JsZCEiOworLy8KKy8vICAgaW50IGNvZGVkX3NpemUgPSBzaXplb2YobWFnaWNfbnVtYmVyKSArCisvLyAgICAgICAgICAgICAgICAgICAgQ29kZWRPdXRwdXRTdHJlYW06OlZhcmludFNpemUzMihzdHJsZW4odGV4dCkpICsKKy8vICAgICAgICAgICAgICAgICAgICBzdHJsZW4odGV4dCk7CisvLworLy8gICB1aW50OCogYnVmZmVyID0KKy8vICAgICAgIGNvZGVkX291dHB1dC0+R2V0RGlyZWN0QnVmZmVyRm9yTkJ5dGVzQW5kQWR2YW5jZShjb2RlZF9zaXplKTsKKy8vICAgaWYgKGJ1ZmZlciAhPSBOVUxMKSB7CisvLyAgICAgLy8gVGhlIG91dHB1dCBzdHJlYW0gaGFzIGVub3VnaCBzcGFjZSBpbiB0aGUgYnVmZmVyOiB3cml0ZSBkaXJlY3RseSB0bworLy8gICAgIC8vIHRoZSBhcnJheS4KKy8vICAgICBidWZmZXIgPSBDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVMaXR0bGVFbmRpYW4zMlRvQXJyYXkobWFnaWNfbnVtYmVyLAorLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWZmZXIpOworLy8gICAgIGJ1ZmZlciA9IENvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZVZhcmludDMyVG9BcnJheShzdHJsZW4odGV4dCksIGJ1ZmZlcik7CisvLyAgICAgYnVmZmVyID0gQ29kZWRPdXRwdXRTdHJlYW06OldyaXRlUmF3VG9BcnJheSh0ZXh0LCBzdHJsZW4odGV4dCksIGJ1ZmZlcik7CisvLyAgIH0gZWxzZSB7CisvLyAgICAgLy8gTWFrZSBib3VuZC1jaGVja2VkIHdyaXRlcywgd2hpY2ggd2lsbCBhc2sgdGhlIHVuZGVybHlpbmcgc3RyZWFtIGZvcgorLy8gICAgIC8vIG1vcmUgc3BhY2UgYXMgbmVlZGVkLgorLy8gICAgIGNvZGVkX291dHB1dC0+V3JpdGVMaXR0bGVFbmRpYW4zMihtYWdpY19udW1iZXIpOworLy8gICAgIGNvZGVkX291dHB1dC0+V3JpdGVWYXJpbnQzMihzdHJsZW4odGV4dCkpOworLy8gICAgIGNvZGVkX291dHB1dC0+V3JpdGVSYXcodGV4dCwgc3RybGVuKHRleHQpKTsKKy8vICAgfQorLy8KKy8vICAgZGVsZXRlIGNvZGVkX291dHB1dDsKK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBDb2RlZE91dHB1dFN0cmVhbSB7CisgcHVibGljOgorICAvLyBDcmVhdGUgYW4gQ29kZWRPdXRwdXRTdHJlYW0gdGhhdCB3cml0ZXMgdG8gdGhlIGdpdmVuIFplcm9Db3B5T3V0cHV0U3RyZWFtLgorICBleHBsaWNpdCBDb2RlZE91dHB1dFN0cmVhbShaZXJvQ29weU91dHB1dFN0cmVhbSogb3V0cHV0KTsKKyAgQ29kZWRPdXRwdXRTdHJlYW0oWmVyb0NvcHlPdXRwdXRTdHJlYW0qIG91dHB1dCwgYm9vbCBkb19lYWdlcl9yZWZyZXNoKTsKKworICAvLyBEZXN0cm95IHRoZSBDb2RlZE91dHB1dFN0cmVhbSBhbmQgcG9zaXRpb24gdGhlIHVuZGVybHlpbmcKKyAgLy8gWmVyb0NvcHlPdXRwdXRTdHJlYW0gaW1tZWRpYXRlbHkgYWZ0ZXIgdGhlIGxhc3QgYnl0ZSB3cml0dGVuLgorICB+Q29kZWRPdXRwdXRTdHJlYW0oKTsKKworICAvLyBUcmltcyBhbnkgdW51c2VkIHNwYWNlIGluIHRoZSB1bmRlcmx5aW5nIGJ1ZmZlciBzbyB0aGF0IGl0cyBzaXplIG1hdGNoZXMKKyAgLy8gdGhlIG51bWJlciBvZiBieXRlcyB3cml0dGVuIGJ5IHRoaXMgc3RyZWFtLiBUaGUgdW5kZXJseWluZyBidWZmZXIgd2lsbAorICAvLyBhdXRvbWF0aWNhbGx5IGJlIHRyaW1tZWQgd2hlbiB0aGlzIHN0cmVhbSBpcyBkZXN0cm95ZWQ7IHRoaXMgY2FsbCBpcyBvbmx5CisgIC8vIG5lY2Vzc2FyeSBpZiB0aGUgdW5kZXJseWluZyBidWZmZXIgaXMgYWNjZXNzZWQgKmJlZm9yZSogdGhlIHN0cmVhbSBpcworICAvLyBkZXN0cm95ZWQuCisgIHZvaWQgVHJpbSgpOworCisgIC8vIFNraXBzIGEgbnVtYmVyIG9mIGJ5dGVzLCBsZWF2aW5nIHRoZSBieXRlcyB1bm1vZGlmaWVkIGluIHRoZSB1bmRlcmx5aW5nCisgIC8vIGJ1ZmZlci4gIFJldHVybnMgZmFsc2UgaWYgYW4gdW5kZXJseWluZyB3cml0ZSBlcnJvciBvY2N1cnMuICBUaGlzIGlzCisgIC8vIG1haW5seSB1c2VmdWwgd2l0aCBHZXREaXJlY3RCdWZmZXJQb2ludGVyKCkuCisgIGJvb2wgU2tpcChpbnQgY291bnQpOworCisgIC8vIFNldHMgKmRhdGEgdG8gcG9pbnQgZGlyZWN0bHkgYXQgdGhlIHVud3JpdHRlbiBwYXJ0IG9mIHRoZQorICAvLyBDb2RlZE91dHB1dFN0cmVhbSdzIHVuZGVybHlpbmcgYnVmZmVyLCBhbmQgKnNpemUgdG8gdGhlIHNpemUgb2YgdGhhdAorICAvLyBidWZmZXIsIGJ1dCBkb2VzIG5vdCBhZHZhbmNlIHRoZSBzdHJlYW0ncyBjdXJyZW50IHBvc2l0aW9uLiAgVGhpcyB3aWxsCisgIC8vIGFsd2F5cyBlaXRoZXIgcHJvZHVjZSBhIG5vbi1lbXB0eSBidWZmZXIgb3IgcmV0dXJuIGZhbHNlLiAgSWYgdGhlIGNhbGxlcgorICAvLyB3cml0ZXMgYW55IGRhdGEgdG8gdGhpcyBidWZmZXIsIGl0IHNob3VsZCB0aGVuIGNhbGwgU2tpcCgpIHRvIHNraXAgb3ZlcgorICAvLyB0aGUgY29uc3VtZWQgYnl0ZXMuICBUaGlzIG1heSBiZSB1c2VmdWwgZm9yIGltcGxlbWVudGluZyBleHRlcm5hbCBmYXN0CisgIC8vIHNlcmlhbGl6YXRpb24gcm91dGluZXMgZm9yIHR5cGVzIG9mIGRhdGEgbm90IGNvdmVyZWQgYnkgdGhlCisgIC8vIENvZGVkT3V0cHV0U3RyZWFtIGludGVyZmFjZS4KKyAgYm9vbCBHZXREaXJlY3RCdWZmZXJQb2ludGVyKHZvaWQqKiBkYXRhLCBpbnQqIHNpemUpOworCisgIC8vIElmIHRoZXJlIGFyZSBhdCBsZWFzdCAic2l6ZSIgYnl0ZXMgYXZhaWxhYmxlIGluIHRoZSBjdXJyZW50IGJ1ZmZlciwKKyAgLy8gcmV0dXJucyBhIHBvaW50ZXIgZGlyZWN0bHkgaW50byB0aGUgYnVmZmVyIGFuZCBhZHZhbmNlcyBvdmVyIHRoZXNlIGJ5dGVzLgorICAvLyBUaGUgY2FsbGVyIG1heSB0aGVuIHdyaXRlIGRpcmVjdGx5IGludG8gdGhpcyBidWZmZXIgKGUuZy4gdXNpbmcgdGhlCisgIC8vICpUb0FycmF5IHN0YXRpYyBtZXRob2RzKSByYXRoZXIgdGhhbiBnbyB0aHJvdWdoIENvZGVkT3V0cHV0U3RyZWFtLiAgSWYKKyAgLy8gdGhlcmUgYXJlIG5vdCBlbm91Z2ggYnl0ZXMgYXZhaWxhYmxlLCByZXR1cm5zIE5VTEwuICBUaGUgcmV0dXJuIHBvaW50ZXIgaXMKKyAgLy8gaW52YWxpZGF0ZWQgYXMgc29vbiBhcyBhbnkgb3RoZXIgbm9uLWNvbnN0IG1ldGhvZCBvZiBDb2RlZE91dHB1dFN0cmVhbQorICAvLyBpcyBjYWxsZWQuCisgIGlubGluZSB1aW50OCogR2V0RGlyZWN0QnVmZmVyRm9yTkJ5dGVzQW5kQWR2YW5jZShpbnQgc2l6ZSk7CisKKyAgLy8gV3JpdGUgcmF3IGJ5dGVzLCBjb3B5aW5nIHRoZW0gZnJvbSB0aGUgZ2l2ZW4gYnVmZmVyLgorICB2b2lkIFdyaXRlUmF3KGNvbnN0IHZvaWQqIGJ1ZmZlciwgaW50IHNpemUpOworICAvLyBMaWtlIFdyaXRlUmF3KCkgIGJ1dCB3aWxsIHRyeSB0byB3cml0ZSBhbGlhc2VkIGRhdGEgaWYgYWxpYXNpbmcgaXMKKyAgLy8gdHVybmVkIG9uLgorICB2b2lkIFdyaXRlUmF3TWF5YmVBbGlhc2VkKGNvbnN0IHZvaWQqIGRhdGEsIGludCBzaXplKTsKKyAgLy8gTGlrZSBXcml0ZVJhdygpICBidXQgd3JpdGluZyBkaXJlY3RseSB0byB0aGUgdGFyZ2V0IGFycmF5LgorICAvLyBUaGlzIGlzIF9ub3RfIGlubGluZWQsIGFzIHRoZSBjb21waWxlciBvZnRlbiBvcHRpbWl6ZXMgbWVtY3B5IGludG8gaW5saW5lCisgIC8vIGNvcHkgbG9vcHMuIFNpbmNlIHRoaXMgZ2V0cyBjYWxsZWQgYnkgZXZlcnkgZmllbGQgd2l0aCBzdHJpbmcgb3IgYnl0ZXMKKyAgLy8gdHlwZSwgaW5saW5pbmcgbWF5IGxlYWQgdG8gYSBzaWduaWZpY2FudCBhbW91bnQgb2YgY29kZSBibG9hdCwgd2l0aCBvbmx5IGEKKyAgLy8gbWlub3IgcGVyZm9ybWFuY2UgZ2Fpbi4KKyAgc3RhdGljIHVpbnQ4KiBXcml0ZVJhd1RvQXJyYXkoY29uc3Qgdm9pZCogYnVmZmVyLCBpbnQgc2l6ZSwgdWludDgqIHRhcmdldCk7CisKKyAgLy8gRXF1aXZhbGVudCB0byBXcml0ZVJhdyhzdHIuZGF0YSgpLCBzdHIuc2l6ZSgpKS4KKyAgdm9pZCBXcml0ZVN0cmluZyhjb25zdCBzdHJpbmcmIHN0cik7CisgIC8vIExpa2UgV3JpdGVTdHJpbmcoKSAgYnV0IHdyaXRpbmcgZGlyZWN0bHkgdG8gdGhlIHRhcmdldCBhcnJheS4KKyAgc3RhdGljIHVpbnQ4KiBXcml0ZVN0cmluZ1RvQXJyYXkoY29uc3Qgc3RyaW5nJiBzdHIsIHVpbnQ4KiB0YXJnZXQpOworICAvLyBXcml0ZSB0aGUgdmFyaW50LWVuY29kZWQgc2l6ZSBvZiBzdHIgZm9sbG93ZWQgYnkgc3RyLgorICBzdGF0aWMgdWludDgqIFdyaXRlU3RyaW5nV2l0aFNpemVUb0FycmF5KGNvbnN0IHN0cmluZyYgc3RyLCB1aW50OCogdGFyZ2V0KTsKKworCisgIC8vIEluc3RydWN0cyB0aGUgQ29kZWRPdXRwdXRTdHJlYW0gdG8gYWxsb3cgdGhlIHVuZGVybHlpbmcKKyAgLy8gWmVyb0NvcHlPdXRwdXRTdHJlYW0gdG8gaG9sZCBwb2ludGVycyB0byB0aGUgb3JpZ2luYWwgc3RydWN0dXJlIGluc3RlYWQgb2YKKyAgLy8gY29weWluZywgaWYgaXQgc3VwcG9ydHMgaXQgKGkuZS4gb3V0cHV0LT5BbGxvd3NBbGlhc2luZygpIGlzIHRydWUpLiAgSWYgdGhlCisgIC8vIHVuZGVybHlpbmcgc3RyZWFtIGRvZXMgbm90IHN1cHBvcnQgYWxpYXNpbmcsIHRoZW4gZW5hYmxpbmcgaXQgaGFzIG5vCisgIC8vIGFmZmVjdC4gIEZvciBub3csIHRoaXMgb25seSBhZmZlY3RzIHRoZSBiZWhhdmlvciBvZgorICAvLyBXcml0ZVJhd01heWJlQWxpYXNlZCgpLgorICAvLworICAvLyBOT1RFOiBJdCBpcyBjYWxsZXIncyByZXNwb25zaWJpbGl0eSB0byBlbnN1cmUgdGhhdCB0aGUgY2h1bmsgb2YgbWVtb3J5CisgIC8vIHJlbWFpbnMgbGl2ZSB1bnRpbCBhbGwgb2YgdGhlIGRhdGEgaGFzIGJlZW4gY29uc3VtZWQgZnJvbSB0aGUgc3RyZWFtLgorICB2b2lkIEVuYWJsZUFsaWFzaW5nKGJvb2wgZW5hYmxlZCk7CisKKyAgLy8gV3JpdGUgYSAzMi1iaXQgbGl0dGxlLWVuZGlhbiBpbnRlZ2VyLgorICB2b2lkIFdyaXRlTGl0dGxlRW5kaWFuMzIodWludDMyIHZhbHVlKTsKKyAgLy8gTGlrZSBXcml0ZUxpdHRsZUVuZGlhbjMyKCkgIGJ1dCB3cml0aW5nIGRpcmVjdGx5IHRvIHRoZSB0YXJnZXQgYXJyYXkuCisgIHN0YXRpYyB1aW50OCogV3JpdGVMaXR0bGVFbmRpYW4zMlRvQXJyYXkodWludDMyIHZhbHVlLCB1aW50OCogdGFyZ2V0KTsKKyAgLy8gV3JpdGUgYSA2NC1iaXQgbGl0dGxlLWVuZGlhbiBpbnRlZ2VyLgorICB2b2lkIFdyaXRlTGl0dGxlRW5kaWFuNjQodWludDY0IHZhbHVlKTsKKyAgLy8gTGlrZSBXcml0ZUxpdHRsZUVuZGlhbjY0KCkgIGJ1dCB3cml0aW5nIGRpcmVjdGx5IHRvIHRoZSB0YXJnZXQgYXJyYXkuCisgIHN0YXRpYyB1aW50OCogV3JpdGVMaXR0bGVFbmRpYW42NFRvQXJyYXkodWludDY0IHZhbHVlLCB1aW50OCogdGFyZ2V0KTsKKworICAvLyBXcml0ZSBhbiB1bnNpZ25lZCBpbnRlZ2VyIHdpdGggVmFyaW50IGVuY29kaW5nLiAgV3JpdGluZyBhIDMyLWJpdCB2YWx1ZQorICAvLyBpcyBlcXVpdmFsZW50IHRvIGNhc3RpbmcgaXQgdG8gdWludDY0IGFuZCB3cml0aW5nIGl0IGFzIGEgNjQtYml0IHZhbHVlLAorICAvLyBidXQgbWF5IGJlIG1vcmUgZWZmaWNpZW50LgorICB2b2lkIFdyaXRlVmFyaW50MzIodWludDMyIHZhbHVlKTsKKyAgLy8gTGlrZSBXcml0ZVZhcmludDMyKCkgIGJ1dCB3cml0aW5nIGRpcmVjdGx5IHRvIHRoZSB0YXJnZXQgYXJyYXkuCisgIHN0YXRpYyB1aW50OCogV3JpdGVWYXJpbnQzMlRvQXJyYXkodWludDMyIHZhbHVlLCB1aW50OCogdGFyZ2V0KTsKKyAgLy8gV3JpdGUgYW4gdW5zaWduZWQgaW50ZWdlciB3aXRoIFZhcmludCBlbmNvZGluZy4KKyAgdm9pZCBXcml0ZVZhcmludDY0KHVpbnQ2NCB2YWx1ZSk7CisgIC8vIExpa2UgV3JpdGVWYXJpbnQ2NCgpICBidXQgd3JpdGluZyBkaXJlY3RseSB0byB0aGUgdGFyZ2V0IGFycmF5LgorICBzdGF0aWMgdWludDgqIFdyaXRlVmFyaW50NjRUb0FycmF5KHVpbnQ2NCB2YWx1ZSwgdWludDgqIHRhcmdldCk7CisKKyAgLy8gRXF1aXZhbGVudCB0byBXcml0ZVZhcmludDMyKCkgZXhjZXB0IHdoZW4gdGhlIHZhbHVlIGlzIG5lZ2F0aXZlLAorICAvLyBpbiB3aGljaCBjYXNlIGl0IG11c3QgYmUgc2lnbi1leHRlbmRlZCB0byBhIGZ1bGwgMTAgYnl0ZXMuCisgIHZvaWQgV3JpdGVWYXJpbnQzMlNpZ25FeHRlbmRlZChpbnQzMiB2YWx1ZSk7CisgIC8vIExpa2UgV3JpdGVWYXJpbnQzMlNpZ25FeHRlbmRlZCgpICBidXQgd3JpdGluZyBkaXJlY3RseSB0byB0aGUgdGFyZ2V0IGFycmF5LgorICBzdGF0aWMgdWludDgqIFdyaXRlVmFyaW50MzJTaWduRXh0ZW5kZWRUb0FycmF5KGludDMyIHZhbHVlLCB1aW50OCogdGFyZ2V0KTsKKworICAvLyBUaGlzIGlzIGlkZW50aWNhbCB0byBXcml0ZVZhcmludDMyKCksIGJ1dCBvcHRpbWl6ZWQgZm9yIHdyaXRpbmcgdGFncy4KKyAgLy8gSW4gcGFydGljdWxhciwgaWYgdGhlIGlucHV0IGlzIGEgY29tcGlsZS10aW1lIGNvbnN0YW50LCB0aGlzIG1ldGhvZAorICAvLyBjb21waWxlcyBkb3duIHRvIGEgY291cGxlIGluc3RydWN0aW9ucy4KKyAgLy8gQWx3YXlzIGlubGluZSBiZWNhdXNlIG90aGVyd2lzZSB0aGUgYWZvcm1lbnRpb25lZCBvcHRpbWl6YXRpb24gY2FuJ3Qgd29yaywKKyAgLy8gYnV0IEdDQyBieSBkZWZhdWx0IGRvZXNuJ3Qgd2FudCB0byBpbmxpbmUgdGhpcy4KKyAgdm9pZCBXcml0ZVRhZyh1aW50MzIgdmFsdWUpOworICAvLyBMaWtlIFdyaXRlVGFnKCkgIGJ1dCB3cml0aW5nIGRpcmVjdGx5IHRvIHRoZSB0YXJnZXQgYXJyYXkuCisgIEdPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORSBzdGF0aWMgdWludDgqIFdyaXRlVGFnVG9BcnJheSh1aW50MzIgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4KiB0YXJnZXQpOworCisgIC8vIFJldHVybnMgdGhlIG51bWJlciBvZiBieXRlcyBuZWVkZWQgdG8gZW5jb2RlIHRoZSBnaXZlbiB2YWx1ZSBhcyBhIHZhcmludC4KKyAgc3RhdGljIGludCBWYXJpbnRTaXplMzIodWludDMyIHZhbHVlKTsKKyAgLy8gUmV0dXJucyB0aGUgbnVtYmVyIG9mIGJ5dGVzIG5lZWRlZCB0byBlbmNvZGUgdGhlIGdpdmVuIHZhbHVlIGFzIGEgdmFyaW50LgorICBzdGF0aWMgaW50IFZhcmludFNpemU2NCh1aW50NjQgdmFsdWUpOworCisgIC8vIElmIG5lZ2F0aXZlLCAxMCBieXRlcy4gIE90aGVyaXdzZSwgc2FtZSBhcyBWYXJpbnRTaXplMzIoKS4KKyAgc3RhdGljIGludCBWYXJpbnRTaXplMzJTaWduRXh0ZW5kZWQoaW50MzIgdmFsdWUpOworCisgIC8vIENvbXBpbGUtdGltZSBlcXVpdmFsZW50IG9mIFZhcmludFNpemUzMigpLgorICB0ZW1wbGF0ZSA8dWludDMyIFZhbHVlPgorICBzdHJ1Y3QgU3RhdGljVmFyaW50U2l6ZTMyIHsKKyAgICBzdGF0aWMgY29uc3QgaW50IHZhbHVlID0KKyAgICAgICAgKFZhbHVlIDwgKDEgPDwgNykpCisgICAgICAgICAgICA/IDEKKyAgICAgICAgICAgIDogKFZhbHVlIDwgKDEgPDwgMTQpKQorICAgICAgICAgICAgICAgID8gMgorICAgICAgICAgICAgICAgIDogKFZhbHVlIDwgKDEgPDwgMjEpKQorICAgICAgICAgICAgICAgICAgICA/IDMKKyAgICAgICAgICAgICAgICAgICAgOiAoVmFsdWUgPCAoMSA8PCAyOCkpCisgICAgICAgICAgICAgICAgICAgICAgICA/IDQKKyAgICAgICAgICAgICAgICAgICAgICAgIDogNTsKKyAgfTsKKworICAvLyBSZXR1cm5zIHRoZSB0b3RhbCBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlbiBzaW5jZSB0aGlzIG9iamVjdCB3YXMgY3JlYXRlZC4KKyAgaW5saW5lIGludCBCeXRlQ291bnQoKSBjb25zdDsKKworICAvLyBSZXR1cm5zIHRydWUgaWYgdGhlcmUgd2FzIGFuIHVuZGVybHlpbmcgSS9PIGVycm9yIHNpbmNlIHRoaXMgb2JqZWN0IHdhcworICAvLyBjcmVhdGVkLgorICBib29sIEhhZEVycm9yKCkgY29uc3QgeyByZXR1cm4gaGFkX2Vycm9yXzsgfQorCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKENvZGVkT3V0cHV0U3RyZWFtKTsKKworICBaZXJvQ29weU91dHB1dFN0cmVhbSogb3V0cHV0XzsKKyAgdWludDgqIGJ1ZmZlcl87CisgIGludCBidWZmZXJfc2l6ZV87CisgIGludCB0b3RhbF9ieXRlc187ICAvLyBTdW0gb2Ygc2l6ZXMgb2YgYWxsIGJ1ZmZlcnMgc2VlbiBzbyBmYXIuCisgIGJvb2wgaGFkX2Vycm9yXzsgICAvLyBXaGV0aGVyIGFuIGVycm9yIG9jY3VycmVkIGR1cmluZyBvdXRwdXQuCisgIGJvb2wgYWxpYXNpbmdfZW5hYmxlZF87ICAvLyBTZWUgRW5hYmxlQWxpYXNpbmcoKS4KKworICAvLyBBZHZhbmNlIHRoZSBidWZmZXIgYnkgYSBnaXZlbiBudW1iZXIgb2YgYnl0ZXMuCisgIHZvaWQgQWR2YW5jZShpbnQgYW1vdW50KTsKKworICAvLyBDYWxsZWQgd2hlbiB0aGUgYnVmZmVyIHJ1bnMgb3V0IHRvIHJlcXVlc3QgbW9yZSBkYXRhLiAgSW1wbGllcyBhbgorICAvLyBBZHZhbmNlKGJ1ZmZlcl9zaXplXykuCisgIGJvb2wgUmVmcmVzaCgpOworCisgIC8vIExpa2UgV3JpdGVSYXcoKSBidXQgbWF5IGF2b2lkIGNvcHlpbmcgaWYgdGhlIHVuZGVybHlpbmcKKyAgLy8gWmVyb0NvcHlPdXRwdXRTdHJlYW0gc3VwcG9ydHMgaXQuCisgIHZvaWQgV3JpdGVBbGlhc2VkUmF3KGNvbnN0IHZvaWQqIGJ1ZmZlciwgaW50IHNpemUpOworCisgIC8vIElmIHRoaXMgd3JpdGUgbWlnaHQgY3Jvc3MgdGhlIGVuZCBvZiB0aGUgYnVmZmVyLCB3ZSBjb21wb3NlIHRoZSBieXRlcyBmaXJzdAorICAvLyB0aGVuIHVzZSBXcml0ZVJhdygpLgorICB2b2lkIFdyaXRlVmFyaW50MzJTbG93UGF0aCh1aW50MzIgdmFsdWUpOworCisgIC8vIEFsd2F5cy1pbmxpbmVkIHZlcnNpb25zIG9mIFdyaXRlVmFyaW50KiBmdW5jdGlvbnMgc28gdGhhdCBjb2RlIGNhbiBiZQorICAvLyByZXVzZWQsIHdoaWxlIHN0aWxsIGNvbnRyb2xsaW5nIHNpemUuIEZvciBpbnN0YW5jZSwgV3JpdGVWYXJpbnQzMlRvQXJyYXkoKQorICAvLyBzaG91bGQgbm90IGRpcmVjdGx5IGNhbGwgdGhpczogc2luY2UgaXQgaXMgaW5saW5lZCBpdHNlbGYsIGRvaW5nIHNvCisgIC8vIHdvdWxkIGdyZWF0bHkgaW5jcmVhc2UgdGhlIHNpemUgb2YgZ2VuZXJhdGVkIGNvZGUuIEluc3RlYWQsIGl0IHNob3VsZCBjYWxsCisgIC8vIFdyaXRlVmFyaW50MzJGYWxsYmFja1RvQXJyYXkuICBNZWFud2hpbGUsIFdyaXRlVmFyaW50MzIoKSBpcyBhbHJlYWR5CisgIC8vIG91dC1vZi1saW5lLCBzbyBpdCBzaG91bGQganVzdCBpbnZva2UgdGhpcyBkaXJlY3RseSB0byBhdm9pZCBhbnkgZXh0cmEKKyAgLy8gZnVuY3Rpb24gY2FsbCBvdmVyaGVhZC4KKyAgR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FIHN0YXRpYyB1aW50OCogV3JpdGVWYXJpbnQ2NFRvQXJyYXlJbmxpbmUoCisgICAgICB1aW50NjQgdmFsdWUsIHVpbnQ4KiB0YXJnZXQpOworCisgIHN0YXRpYyBpbnQgVmFyaW50U2l6ZTMyRmFsbGJhY2sodWludDMyIHZhbHVlKTsKK307CisKKy8vIGlubGluZSBtZXRob2RzID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKy8vIFRoZSB2YXN0IG1ham9yaXR5IG9mIHZhcmludHMgYXJlIG9ubHkgb25lIGJ5dGUuICBUaGVzZSBpbmxpbmUKKy8vIG1ldGhvZHMgb3B0aW1pemUgZm9yIHRoYXQgY2FzZS4KKworaW5saW5lIGJvb2wgQ29kZWRJbnB1dFN0cmVhbTo6UmVhZFZhcmludDMyKHVpbnQzMiogdmFsdWUpIHsKKyAgdWludDMyIHYgPSAwOworICBpZiAoR09PR0xFX1BSRURJQ1RfVFJVRShidWZmZXJfIDwgYnVmZmVyX2VuZF8pKSB7CisgICAgdiA9ICpidWZmZXJfOworICAgIGlmICh2IDwgMHg4MCkgeworICAgICAgKnZhbHVlID0gdjsKKyAgICAgIEFkdmFuY2UoMSk7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgIH0KKyAgaW50NjQgcmVzdWx0ID0gUmVhZFZhcmludDMyRmFsbGJhY2sodik7CisgICp2YWx1ZSA9IHN0YXRpY19jYXN0PHVpbnQzMj4ocmVzdWx0KTsKKyAgcmV0dXJuIHJlc3VsdCA+PSAwOworfQorCitpbmxpbmUgYm9vbCBDb2RlZElucHV0U3RyZWFtOjpSZWFkVmFyaW50NjQodWludDY0KiB2YWx1ZSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfVFJVRShidWZmZXJfIDwgYnVmZmVyX2VuZF8pICYmICpidWZmZXJfIDwgMHg4MCkgeworICAgICp2YWx1ZSA9ICpidWZmZXJfOworICAgIEFkdmFuY2UoMSk7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKyAgc3RkOjpwYWlyPHVpbnQ2NCwgYm9vbD4gcCA9IFJlYWRWYXJpbnQ2NEZhbGxiYWNrKCk7CisgICp2YWx1ZSA9IHAuZmlyc3Q7CisgIHJldHVybiBwLnNlY29uZDsKK30KKworLy8gc3RhdGljCitpbmxpbmUgY29uc3QgdWludDgqIENvZGVkSW5wdXRTdHJlYW06OlJlYWRMaXR0bGVFbmRpYW4zMkZyb21BcnJheSgKKyAgICBjb25zdCB1aW50OCogYnVmZmVyLAorICAgIHVpbnQzMiogdmFsdWUpIHsKKyNpZiBkZWZpbmVkKFBST1RPQlVGX0xJVFRMRV9FTkRJQU4pCisgIG1lbWNweSh2YWx1ZSwgYnVmZmVyLCBzaXplb2YoKnZhbHVlKSk7CisgIHJldHVybiBidWZmZXIgKyBzaXplb2YoKnZhbHVlKTsKKyNlbHNlCisgICp2YWx1ZSA9IChzdGF0aWNfY2FzdDx1aW50MzI+KGJ1ZmZlclswXSkgICAgICApIHwKKyAgICAgICAgICAgKHN0YXRpY19jYXN0PHVpbnQzMj4oYnVmZmVyWzFdKSA8PCAgOCkgfAorICAgICAgICAgICAoc3RhdGljX2Nhc3Q8dWludDMyPihidWZmZXJbMl0pIDw8IDE2KSB8CisgICAgICAgICAgIChzdGF0aWNfY2FzdDx1aW50MzI+KGJ1ZmZlclszXSkgPDwgMjQpOworICByZXR1cm4gYnVmZmVyICsgc2l6ZW9mKCp2YWx1ZSk7CisjZW5kaWYKK30KKy8vIHN0YXRpYworaW5saW5lIGNvbnN0IHVpbnQ4KiBDb2RlZElucHV0U3RyZWFtOjpSZWFkTGl0dGxlRW5kaWFuNjRGcm9tQXJyYXkoCisgICAgY29uc3QgdWludDgqIGJ1ZmZlciwKKyAgICB1aW50NjQqIHZhbHVlKSB7CisjaWYgZGVmaW5lZChQUk9UT0JVRl9MSVRUTEVfRU5ESUFOKQorICBtZW1jcHkodmFsdWUsIGJ1ZmZlciwgc2l6ZW9mKCp2YWx1ZSkpOworICByZXR1cm4gYnVmZmVyICsgc2l6ZW9mKCp2YWx1ZSk7CisjZWxzZQorICB1aW50MzIgcGFydDAgPSAoc3RhdGljX2Nhc3Q8dWludDMyPihidWZmZXJbMF0pICAgICAgKSB8CisgICAgICAgICAgICAgICAgIChzdGF0aWNfY2FzdDx1aW50MzI+KGJ1ZmZlclsxXSkgPDwgIDgpIHwKKyAgICAgICAgICAgICAgICAgKHN0YXRpY19jYXN0PHVpbnQzMj4oYnVmZmVyWzJdKSA8PCAxNikgfAorICAgICAgICAgICAgICAgICAoc3RhdGljX2Nhc3Q8dWludDMyPihidWZmZXJbM10pIDw8IDI0KTsKKyAgdWludDMyIHBhcnQxID0gKHN0YXRpY19jYXN0PHVpbnQzMj4oYnVmZmVyWzRdKSAgICAgICkgfAorICAgICAgICAgICAgICAgICAoc3RhdGljX2Nhc3Q8dWludDMyPihidWZmZXJbNV0pIDw8ICA4KSB8CisgICAgICAgICAgICAgICAgIChzdGF0aWNfY2FzdDx1aW50MzI+KGJ1ZmZlcls2XSkgPDwgMTYpIHwKKyAgICAgICAgICAgICAgICAgKHN0YXRpY19jYXN0PHVpbnQzMj4oYnVmZmVyWzddKSA8PCAyNCk7CisgICp2YWx1ZSA9IHN0YXRpY19jYXN0PHVpbnQ2ND4ocGFydDApIHwKKyAgICAgICAgICAoc3RhdGljX2Nhc3Q8dWludDY0PihwYXJ0MSkgPDwgMzIpOworICByZXR1cm4gYnVmZmVyICsgc2l6ZW9mKCp2YWx1ZSk7CisjZW5kaWYKK30KKworaW5saW5lIGJvb2wgQ29kZWRJbnB1dFN0cmVhbTo6UmVhZExpdHRsZUVuZGlhbjMyKHVpbnQzMiogdmFsdWUpIHsKKyNpZiBkZWZpbmVkKFBST1RPQlVGX0xJVFRMRV9FTkRJQU4pCisgIGlmIChHT09HTEVfUFJFRElDVF9UUlVFKEJ1ZmZlclNpemUoKSA+PSBzdGF0aWNfY2FzdDxpbnQ+KHNpemVvZigqdmFsdWUpKSkpIHsKKyAgICBtZW1jcHkodmFsdWUsIGJ1ZmZlcl8sIHNpemVvZigqdmFsdWUpKTsKKyAgICBBZHZhbmNlKHNpemVvZigqdmFsdWUpKTsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gUmVhZExpdHRsZUVuZGlhbjMyRmFsbGJhY2sodmFsdWUpOworICB9CisjZWxzZQorICByZXR1cm4gUmVhZExpdHRsZUVuZGlhbjMyRmFsbGJhY2sodmFsdWUpOworI2VuZGlmCit9CisKK2lubGluZSBib29sIENvZGVkSW5wdXRTdHJlYW06OlJlYWRMaXR0bGVFbmRpYW42NCh1aW50NjQqIHZhbHVlKSB7CisjaWYgZGVmaW5lZChQUk9UT0JVRl9MSVRUTEVfRU5ESUFOKQorICBpZiAoR09PR0xFX1BSRURJQ1RfVFJVRShCdWZmZXJTaXplKCkgPj0gc3RhdGljX2Nhc3Q8aW50PihzaXplb2YoKnZhbHVlKSkpKSB7CisgICAgbWVtY3B5KHZhbHVlLCBidWZmZXJfLCBzaXplb2YoKnZhbHVlKSk7CisgICAgQWR2YW5jZShzaXplb2YoKnZhbHVlKSk7CisgICAgcmV0dXJuIHRydWU7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIFJlYWRMaXR0bGVFbmRpYW42NEZhbGxiYWNrKHZhbHVlKTsKKyAgfQorI2Vsc2UKKyAgcmV0dXJuIFJlYWRMaXR0bGVFbmRpYW42NEZhbGxiYWNrKHZhbHVlKTsKKyNlbmRpZgorfQorCitpbmxpbmUgdWludDMyIENvZGVkSW5wdXRTdHJlYW06OlJlYWRUYWcoKSB7CisgIHVpbnQzMiB2ID0gMDsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX1RSVUUoYnVmZmVyXyA8IGJ1ZmZlcl9lbmRfKSkgeworICAgIHYgPSAqYnVmZmVyXzsKKyAgICBpZiAodiA8IDB4ODApIHsKKyAgICAgIGxhc3RfdGFnXyA9IHY7CisgICAgICBBZHZhbmNlKDEpOworICAgICAgcmV0dXJuIHY7CisgICAgfQorICB9CisgIGxhc3RfdGFnXyA9IFJlYWRUYWdGYWxsYmFjayh2KTsKKyAgcmV0dXJuIGxhc3RfdGFnXzsKK30KKworaW5saW5lIHN0ZDo6cGFpcjx1aW50MzIsIGJvb2w+IENvZGVkSW5wdXRTdHJlYW06OlJlYWRUYWdXaXRoQ3V0b2ZmKAorICAgIHVpbnQzMiBjdXRvZmYpIHsKKyAgLy8gSW4gcGVyZm9ybWFuY2Utc2Vuc2l0aXZlIGNvZGUgd2UgY2FuIGV4cGVjdCBjdXRvZmYgdG8gYmUgYSBjb21waWxlLXRpbWUKKyAgLy8gY29uc3RhbnQsIGFuZCB0aGluZ3MgbGlrZSAiY3V0b2ZmID49IGtNYXgxQnl0ZVZhcmludCIgdG8gYmUgZXZhbHVhdGVkIGF0CisgIC8vIGNvbXBpbGUgdGltZS4KKyAgdWludDMyIGZpcnN0X2J5dGVfb3JfemVybyA9IDA7CisgIGlmIChHT09HTEVfUFJFRElDVF9UUlVFKGJ1ZmZlcl8gPCBidWZmZXJfZW5kXykpIHsKKyAgICAvLyBIb3QgY2FzZTogYnVmZmVyXyBub25fZW1wdHksIGJ1ZmZlcl9bMF0gaW4gWzEsIDEyOCkuCisgICAgLy8gVE9ETyhncGlrZSk6IElzIGl0IHdvcnRoIHJlYXJyYW5naW5nIHRoaXM/IEUuZy4sIGlmIHRoZSBudW1iZXIgb2YgZmllbGRzCisgICAgLy8gaXMgbGFyZ2UgZW5vdWdoIHRoZW4gaXMgaXQgYmV0dGVyIHRvIGNoZWNrIGZvciB0aGUgdHdvLWJ5dGUgY2FzZSBmaXJzdD8KKyAgICBmaXJzdF9ieXRlX29yX3plcm8gPSBidWZmZXJfWzBdOworICAgIGlmIChzdGF0aWNfY2FzdDxpbnQ4PihidWZmZXJfWzBdKSA+IDApIHsKKyAgICAgIGNvbnN0IHVpbnQzMiBrTWF4MUJ5dGVWYXJpbnQgPSAweDdmOworICAgICAgdWludDMyIHRhZyA9IGxhc3RfdGFnXyA9IGJ1ZmZlcl9bMF07CisgICAgICBBZHZhbmNlKDEpOworICAgICAgcmV0dXJuIHN0ZDo6bWFrZV9wYWlyKHRhZywgY3V0b2ZmID49IGtNYXgxQnl0ZVZhcmludCB8fCB0YWcgPD0gY3V0b2ZmKTsKKyAgICB9CisgICAgLy8gT3RoZXIgaG90IGNhc2U6IGN1dG9mZiA+PSAweDgwLCBidWZmZXJfIGhhcyBhdCBsZWFzdCB0d28gYnl0ZXMgYXZhaWxhYmxlLAorICAgIC8vIGFuZCB0YWcgaXMgdHdvIGJ5dGVzLiAgVGhlIGxhdHRlciBpcyB0ZXN0ZWQgYnkgYml0d2lzZS1hbmQtbm90IG9mIHRoZQorICAgIC8vIGZpcnN0IGJ5dGUgYW5kIHRoZSBzZWNvbmQgYnl0ZS4KKyAgICBpZiAoY3V0b2ZmID49IDB4ODAgJiYKKyAgICAgICAgR09PR0xFX1BSRURJQ1RfVFJVRShidWZmZXJfICsgMSA8IGJ1ZmZlcl9lbmRfKSAmJgorICAgICAgICBHT09HTEVfUFJFRElDVF9UUlVFKChidWZmZXJfWzBdICYgfmJ1ZmZlcl9bMV0pID49IDB4ODApKSB7CisgICAgICBjb25zdCB1aW50MzIga01heDJCeXRlVmFyaW50ID0gKDB4N2YgPDwgNykgKyAweDdmOworICAgICAgdWludDMyIHRhZyA9IGxhc3RfdGFnXyA9ICgxdSA8PCA3KSAqIGJ1ZmZlcl9bMV0gKyAoYnVmZmVyX1swXSAtIDB4ODApOworICAgICAgQWR2YW5jZSgyKTsKKyAgICAgIC8vIEl0IG1pZ2h0IG1ha2Ugc2Vuc2UgdG8gdGVzdCBmb3IgdGFnID09IDAgbm93LCBidXQgaXQgaXMgc28gcmFyZSB0aGF0CisgICAgICAvLyB0aGF0IHdlIGRvbid0IGJvdGhlci4gIEEgdmFyaW50LWVuY29kZWQgMCBzaG91bGQgYmUgb25lIGJ5dGUgdW5sZXNzCisgICAgICAvLyB0aGUgZW5jb2RlciBsb3N0IGl0cyBtaW5kLiAgVGhlIHNlY29uZCBwYXJ0IG9mIHRoZSByZXR1cm4gdmFsdWUgb2YKKyAgICAgIC8vIHRoaXMgZnVuY3Rpb24gaXMgYWxsb3dlZCB0byBiZSBlaXRoZXIgdHJ1ZSBvciBmYWxzZSBpZiB0aGUgdGFnIGlzIDAsCisgICAgICAvLyBzbyB3ZSBkb24ndCBoYXZlIHRvIGNoZWNrIGZvciB0YWcgPT0gMC4gIFdlIG1heSBuZWVkIHRvIGNoZWNrIHdoZXRoZXIKKyAgICAgIC8vIGl0IGV4Y2VlZHMgY3V0b2ZmLgorICAgICAgYm9vbCBhdF9vcl9iZWxvd19jdXRvZmYgPSBjdXRvZmYgPj0ga01heDJCeXRlVmFyaW50IHx8IHRhZyA8PSBjdXRvZmY7CisgICAgICByZXR1cm4gc3RkOjptYWtlX3BhaXIodGFnLCBhdF9vcl9iZWxvd19jdXRvZmYpOworICAgIH0KKyAgfQorICAvLyBTbG93IHBhdGgKKyAgbGFzdF90YWdfID0gUmVhZFRhZ0ZhbGxiYWNrKGZpcnN0X2J5dGVfb3JfemVybyk7CisgIHJldHVybiBzdGQ6Om1ha2VfcGFpcihsYXN0X3RhZ18sIHN0YXRpY19jYXN0PHVpbnQzMj4obGFzdF90YWdfIC0gMSkgPCBjdXRvZmYpOworfQorCitpbmxpbmUgYm9vbCBDb2RlZElucHV0U3RyZWFtOjpMYXN0VGFnV2FzKHVpbnQzMiBleHBlY3RlZCkgeworICByZXR1cm4gbGFzdF90YWdfID09IGV4cGVjdGVkOworfQorCitpbmxpbmUgYm9vbCBDb2RlZElucHV0U3RyZWFtOjpDb25zdW1lZEVudGlyZU1lc3NhZ2UoKSB7CisgIHJldHVybiBsZWdpdGltYXRlX21lc3NhZ2VfZW5kXzsKK30KKworaW5saW5lIGJvb2wgQ29kZWRJbnB1dFN0cmVhbTo6RXhwZWN0VGFnKHVpbnQzMiBleHBlY3RlZCkgeworICBpZiAoZXhwZWN0ZWQgPCAoMSA8PCA3KSkgeworICAgIGlmIChHT09HTEVfUFJFRElDVF9UUlVFKGJ1ZmZlcl8gPCBidWZmZXJfZW5kXykgJiYgYnVmZmVyX1swXSA9PSBleHBlY3RlZCkgeworICAgICAgQWR2YW5jZSgxKTsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICB9IGVsc2UgaWYgKGV4cGVjdGVkIDwgKDEgPDwgMTQpKSB7CisgICAgaWYgKEdPT0dMRV9QUkVESUNUX1RSVUUoQnVmZmVyU2l6ZSgpID49IDIpICYmCisgICAgICAgIGJ1ZmZlcl9bMF0gPT0gc3RhdGljX2Nhc3Q8dWludDg+KGV4cGVjdGVkIHwgMHg4MCkgJiYKKyAgICAgICAgYnVmZmVyX1sxXSA9PSBzdGF0aWNfY2FzdDx1aW50OD4oZXhwZWN0ZWQgPj4gNykpIHsKKyAgICAgIEFkdmFuY2UoMik7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICAvLyBEb24ndCBib3RoZXIgb3B0aW1pemluZyBmb3IgbGFyZ2VyIHZhbHVlcy4KKyAgICByZXR1cm4gZmFsc2U7CisgIH0KK30KKworaW5saW5lIGNvbnN0IHVpbnQ4KiBDb2RlZElucHV0U3RyZWFtOjpFeHBlY3RUYWdGcm9tQXJyYXkoCisgICAgY29uc3QgdWludDgqIGJ1ZmZlciwgdWludDMyIGV4cGVjdGVkKSB7CisgIGlmIChleHBlY3RlZCA8ICgxIDw8IDcpKSB7CisgICAgaWYgKGJ1ZmZlclswXSA9PSBleHBlY3RlZCkgeworICAgICAgcmV0dXJuIGJ1ZmZlciArIDE7CisgICAgfQorICB9IGVsc2UgaWYgKGV4cGVjdGVkIDwgKDEgPDwgMTQpKSB7CisgICAgaWYgKGJ1ZmZlclswXSA9PSBzdGF0aWNfY2FzdDx1aW50OD4oZXhwZWN0ZWQgfCAweDgwKSAmJgorICAgICAgICBidWZmZXJbMV0gPT0gc3RhdGljX2Nhc3Q8dWludDg+KGV4cGVjdGVkID4+IDcpKSB7CisgICAgICByZXR1cm4gYnVmZmVyICsgMjsKKyAgICB9CisgIH0KKyAgcmV0dXJuIE5VTEw7Cit9CisKK2lubGluZSB2b2lkIENvZGVkSW5wdXRTdHJlYW06OkdldERpcmVjdEJ1ZmZlclBvaW50ZXJJbmxpbmUoY29uc3Qgdm9pZCoqIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCogc2l6ZSkgeworICAqZGF0YSA9IGJ1ZmZlcl87CisgICpzaXplID0gc3RhdGljX2Nhc3Q8aW50PihidWZmZXJfZW5kXyAtIGJ1ZmZlcl8pOworfQorCitpbmxpbmUgYm9vbCBDb2RlZElucHV0U3RyZWFtOjpFeHBlY3RBdEVuZCgpIHsKKyAgLy8gSWYgd2UgYXJlIGF0IGEgbGltaXQgd2Uga25vdyBubyBtb3JlIGJ5dGVzIGNhbiBiZSByZWFkLiAgT3RoZXJ3aXNlLCBpdCdzCisgIC8vIGhhcmQgdG8gc2F5IHdpdGhvdXQgY2FsbGluZyBSZWZyZXNoKCksIGFuZCB3ZSdkIHJhdGhlciBub3QgZG8gdGhhdC4KKworICBpZiAoYnVmZmVyXyA9PSBidWZmZXJfZW5kXyAmJgorICAgICAgKChidWZmZXJfc2l6ZV9hZnRlcl9saW1pdF8gIT0gMCkgfHwKKyAgICAgICAodG90YWxfYnl0ZXNfcmVhZF8gPT0gY3VycmVudF9saW1pdF8pKSkgeworICAgIGxhc3RfdGFnXyA9IDA7ICAgICAgICAgICAgICAgICAgIC8vIFByZXRlbmQgd2UgY2FsbGVkIFJlYWRUYWcoKS4uLgorICAgIGxlZ2l0aW1hdGVfbWVzc2FnZV9lbmRfID0gdHJ1ZTsgIC8vIC4uLiBhbmQgaXQgaGl0IEVPRi4KKyAgICByZXR1cm4gdHJ1ZTsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KK30KKworaW5saW5lIGludCBDb2RlZElucHV0U3RyZWFtOjpDdXJyZW50UG9zaXRpb24oKSBjb25zdCB7CisgIHJldHVybiB0b3RhbF9ieXRlc19yZWFkXyAtIChCdWZmZXJTaXplKCkgKyBidWZmZXJfc2l6ZV9hZnRlcl9saW1pdF8pOworfQorCitpbmxpbmUgdWludDgqIENvZGVkT3V0cHV0U3RyZWFtOjpHZXREaXJlY3RCdWZmZXJGb3JOQnl0ZXNBbmRBZHZhbmNlKGludCBzaXplKSB7CisgIGlmIChidWZmZXJfc2l6ZV8gPCBzaXplKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0gZWxzZSB7CisgICAgdWludDgqIHJlc3VsdCA9IGJ1ZmZlcl87CisgICAgQWR2YW5jZShzaXplKTsKKyAgICByZXR1cm4gcmVzdWx0OworICB9Cit9CisKK2lubGluZSB1aW50OCogQ29kZWRPdXRwdXRTdHJlYW06OldyaXRlVmFyaW50MzJUb0FycmF5KHVpbnQzMiB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4KiB0YXJnZXQpIHsKKyAgd2hpbGUgKHZhbHVlID49IDB4ODApIHsKKyAgICAqdGFyZ2V0ID0gc3RhdGljX2Nhc3Q8dWludDg+KHZhbHVlIHwgMHg4MCk7CisgICAgdmFsdWUgPj49IDc7CisgICAgKyt0YXJnZXQ7CisgIH0KKyAgKnRhcmdldCA9IHN0YXRpY19jYXN0PHVpbnQ4Pih2YWx1ZSk7CisgIHJldHVybiB0YXJnZXQgKyAxOworfQorCitpbmxpbmUgdm9pZCBDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVWYXJpbnQzMlNpZ25FeHRlbmRlZChpbnQzMiB2YWx1ZSkgeworICBpZiAodmFsdWUgPCAwKSB7CisgICAgV3JpdGVWYXJpbnQ2NChzdGF0aWNfY2FzdDx1aW50NjQ+KHZhbHVlKSk7CisgIH0gZWxzZSB7CisgICAgV3JpdGVWYXJpbnQzMihzdGF0aWNfY2FzdDx1aW50MzI+KHZhbHVlKSk7CisgIH0KK30KKworaW5saW5lIHVpbnQ4KiBDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVWYXJpbnQzMlNpZ25FeHRlbmRlZFRvQXJyYXkoCisgICAgaW50MzIgdmFsdWUsIHVpbnQ4KiB0YXJnZXQpIHsKKyAgaWYgKHZhbHVlIDwgMCkgeworICAgIHJldHVybiBXcml0ZVZhcmludDY0VG9BcnJheShzdGF0aWNfY2FzdDx1aW50NjQ+KHZhbHVlKSwgdGFyZ2V0KTsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gV3JpdGVWYXJpbnQzMlRvQXJyYXkoc3RhdGljX2Nhc3Q8dWludDMyPih2YWx1ZSksIHRhcmdldCk7CisgIH0KK30KKworaW5saW5lIHVpbnQ4KiBDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVMaXR0bGVFbmRpYW4zMlRvQXJyYXkodWludDMyIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDgqIHRhcmdldCkgeworI2lmIGRlZmluZWQoUFJPVE9CVUZfTElUVExFX0VORElBTikKKyAgbWVtY3B5KHRhcmdldCwgJnZhbHVlLCBzaXplb2YodmFsdWUpKTsKKyNlbHNlCisgIHRhcmdldFswXSA9IHN0YXRpY19jYXN0PHVpbnQ4Pih2YWx1ZSk7CisgIHRhcmdldFsxXSA9IHN0YXRpY19jYXN0PHVpbnQ4Pih2YWx1ZSA+PiAgOCk7CisgIHRhcmdldFsyXSA9IHN0YXRpY19jYXN0PHVpbnQ4Pih2YWx1ZSA+PiAxNik7CisgIHRhcmdldFszXSA9IHN0YXRpY19jYXN0PHVpbnQ4Pih2YWx1ZSA+PiAyNCk7CisjZW5kaWYKKyAgcmV0dXJuIHRhcmdldCArIHNpemVvZih2YWx1ZSk7Cit9CisKK2lubGluZSB1aW50OCogQ29kZWRPdXRwdXRTdHJlYW06OldyaXRlTGl0dGxlRW5kaWFuNjRUb0FycmF5KHVpbnQ2NCB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4KiB0YXJnZXQpIHsKKyNpZiBkZWZpbmVkKFBST1RPQlVGX0xJVFRMRV9FTkRJQU4pCisgIG1lbWNweSh0YXJnZXQsICZ2YWx1ZSwgc2l6ZW9mKHZhbHVlKSk7CisjZWxzZQorICB1aW50MzIgcGFydDAgPSBzdGF0aWNfY2FzdDx1aW50MzI+KHZhbHVlKTsKKyAgdWludDMyIHBhcnQxID0gc3RhdGljX2Nhc3Q8dWludDMyPih2YWx1ZSA+PiAzMik7CisKKyAgdGFyZ2V0WzBdID0gc3RhdGljX2Nhc3Q8dWludDg+KHBhcnQwKTsKKyAgdGFyZ2V0WzFdID0gc3RhdGljX2Nhc3Q8dWludDg+KHBhcnQwID4+ICA4KTsKKyAgdGFyZ2V0WzJdID0gc3RhdGljX2Nhc3Q8dWludDg+KHBhcnQwID4+IDE2KTsKKyAgdGFyZ2V0WzNdID0gc3RhdGljX2Nhc3Q8dWludDg+KHBhcnQwID4+IDI0KTsKKyAgdGFyZ2V0WzRdID0gc3RhdGljX2Nhc3Q8dWludDg+KHBhcnQxKTsKKyAgdGFyZ2V0WzVdID0gc3RhdGljX2Nhc3Q8dWludDg+KHBhcnQxID4+ICA4KTsKKyAgdGFyZ2V0WzZdID0gc3RhdGljX2Nhc3Q8dWludDg+KHBhcnQxID4+IDE2KTsKKyAgdGFyZ2V0WzddID0gc3RhdGljX2Nhc3Q8dWludDg+KHBhcnQxID4+IDI0KTsKKyNlbmRpZgorICByZXR1cm4gdGFyZ2V0ICsgc2l6ZW9mKHZhbHVlKTsKK30KKworaW5saW5lIHZvaWQgQ29kZWRPdXRwdXRTdHJlYW06OldyaXRlVmFyaW50MzIodWludDMyIHZhbHVlKSB7CisgIGlmIChidWZmZXJfc2l6ZV8gPj0gNSkgeworICAgIC8vIEZhc3QgcGF0aDogIFdlIGhhdmUgZW5vdWdoIGJ5dGVzIGxlZnQgaW4gdGhlIGJ1ZmZlciB0byBndWFyYW50ZWUgdGhhdAorICAgIC8vIHRoaXMgd3JpdGUgd29uJ3QgY3Jvc3MgdGhlIGVuZCwgc28gd2UgY2FuIHNraXAgdGhlIGNoZWNrcy4KKyAgICB1aW50OCogdGFyZ2V0ID0gYnVmZmVyXzsKKyAgICB1aW50OCogZW5kID0gV3JpdGVWYXJpbnQzMlRvQXJyYXkodmFsdWUsIHRhcmdldCk7CisgICAgaW50IHNpemUgPSBlbmQgLSB0YXJnZXQ7CisgICAgQWR2YW5jZShzaXplKTsKKyAgfSBlbHNlIHsKKyAgICBXcml0ZVZhcmludDMyU2xvd1BhdGgodmFsdWUpOworICB9Cit9CisKK2lubGluZSB2b2lkIENvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZVRhZyh1aW50MzIgdmFsdWUpIHsKKyAgV3JpdGVWYXJpbnQzMih2YWx1ZSk7Cit9CisKK2lubGluZSB1aW50OCogQ29kZWRPdXRwdXRTdHJlYW06OldyaXRlVGFnVG9BcnJheSgKKyAgICB1aW50MzIgdmFsdWUsIHVpbnQ4KiB0YXJnZXQpIHsKKyAgcmV0dXJuIFdyaXRlVmFyaW50MzJUb0FycmF5KHZhbHVlLCB0YXJnZXQpOworfQorCitpbmxpbmUgaW50IENvZGVkT3V0cHV0U3RyZWFtOjpWYXJpbnRTaXplMzIodWludDMyIHZhbHVlKSB7CisgIGlmICh2YWx1ZSA8ICgxIDw8IDcpKSB7CisgICAgcmV0dXJuIDE7CisgIH0gZWxzZSAgeworICAgIHJldHVybiBWYXJpbnRTaXplMzJGYWxsYmFjayh2YWx1ZSk7CisgIH0KK30KKworaW5saW5lIGludCBDb2RlZE91dHB1dFN0cmVhbTo6VmFyaW50U2l6ZTMyU2lnbkV4dGVuZGVkKGludDMyIHZhbHVlKSB7CisgIGlmICh2YWx1ZSA8IDApIHsKKyAgICByZXR1cm4gMTA7ICAgICAvLyBUT0RPKGtlbnRvbik6ICBNYWtlIHRoaXMgYSBzeW1ib2xpYyBjb25zdGFudC4KKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gVmFyaW50U2l6ZTMyKHN0YXRpY19jYXN0PHVpbnQzMj4odmFsdWUpKTsKKyAgfQorfQorCitpbmxpbmUgdm9pZCBDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVTdHJpbmcoY29uc3Qgc3RyaW5nJiBzdHIpIHsKKyAgV3JpdGVSYXcoc3RyLmRhdGEoKSwgc3RhdGljX2Nhc3Q8aW50PihzdHIuc2l6ZSgpKSk7Cit9CisKK2lubGluZSB2b2lkIENvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZVJhd01heWJlQWxpYXNlZCgKKyAgICBjb25zdCB2b2lkKiBkYXRhLCBpbnQgc2l6ZSkgeworICBpZiAoYWxpYXNpbmdfZW5hYmxlZF8pIHsKKyAgICBXcml0ZUFsaWFzZWRSYXcoZGF0YSwgc2l6ZSk7CisgIH0gZWxzZSB7CisgICAgV3JpdGVSYXcoZGF0YSwgc2l6ZSk7CisgIH0KK30KKworaW5saW5lIHVpbnQ4KiBDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVTdHJpbmdUb0FycmF5KAorICAgIGNvbnN0IHN0cmluZyYgc3RyLCB1aW50OCogdGFyZ2V0KSB7CisgIHJldHVybiBXcml0ZVJhd1RvQXJyYXkoc3RyLmRhdGEoKSwgc3RhdGljX2Nhc3Q8aW50PihzdHIuc2l6ZSgpKSwgdGFyZ2V0KTsKK30KKworaW5saW5lIGludCBDb2RlZE91dHB1dFN0cmVhbTo6Qnl0ZUNvdW50KCkgY29uc3QgeworICByZXR1cm4gdG90YWxfYnl0ZXNfIC0gYnVmZmVyX3NpemVfOworfQorCitpbmxpbmUgdm9pZCBDb2RlZElucHV0U3RyZWFtOjpBZHZhbmNlKGludCBhbW91bnQpIHsKKyAgYnVmZmVyXyArPSBhbW91bnQ7Cit9CisKK2lubGluZSB2b2lkIENvZGVkT3V0cHV0U3RyZWFtOjpBZHZhbmNlKGludCBhbW91bnQpIHsKKyAgYnVmZmVyXyArPSBhbW91bnQ7CisgIGJ1ZmZlcl9zaXplXyAtPSBhbW91bnQ7Cit9CisKK2lubGluZSB2b2lkIENvZGVkSW5wdXRTdHJlYW06OlNldFJlY3Vyc2lvbkxpbWl0KGludCBsaW1pdCkgeworICByZWN1cnNpb25fYnVkZ2V0XyArPSBsaW1pdCAtIHJlY3Vyc2lvbl9saW1pdF87CisgIHJlY3Vyc2lvbl9saW1pdF8gPSBsaW1pdDsKK30KKworaW5saW5lIGJvb2wgQ29kZWRJbnB1dFN0cmVhbTo6SW5jcmVtZW50UmVjdXJzaW9uRGVwdGgoKSB7CisgIC0tcmVjdXJzaW9uX2J1ZGdldF87CisgIHJldHVybiByZWN1cnNpb25fYnVkZ2V0XyA+PSAwOworfQorCitpbmxpbmUgdm9pZCBDb2RlZElucHV0U3RyZWFtOjpEZWNyZW1lbnRSZWN1cnNpb25EZXB0aCgpIHsKKyAgaWYgKHJlY3Vyc2lvbl9idWRnZXRfIDwgcmVjdXJzaW9uX2xpbWl0XykgKytyZWN1cnNpb25fYnVkZ2V0XzsKK30KKworaW5saW5lIHZvaWQgQ29kZWRJbnB1dFN0cmVhbTo6VW5zYWZlRGVjcmVtZW50UmVjdXJzaW9uRGVwdGgoKSB7CisgIGFzc2VydChyZWN1cnNpb25fYnVkZ2V0XyA8IHJlY3Vyc2lvbl9saW1pdF8pOworICArK3JlY3Vyc2lvbl9idWRnZXRfOworfQorCitpbmxpbmUgdm9pZCBDb2RlZElucHV0U3RyZWFtOjpTZXRFeHRlbnNpb25SZWdpc3RyeShjb25zdCBEZXNjcmlwdG9yUG9vbCogcG9vbCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VGYWN0b3J5KiBmYWN0b3J5KSB7CisgIGV4dGVuc2lvbl9wb29sXyA9IHBvb2w7CisgIGV4dGVuc2lvbl9mYWN0b3J5XyA9IGZhY3Rvcnk7Cit9CisKK2lubGluZSBjb25zdCBEZXNjcmlwdG9yUG9vbCogQ29kZWRJbnB1dFN0cmVhbTo6R2V0RXh0ZW5zaW9uUG9vbCgpIHsKKyAgcmV0dXJuIGV4dGVuc2lvbl9wb29sXzsKK30KKworaW5saW5lIE1lc3NhZ2VGYWN0b3J5KiBDb2RlZElucHV0U3RyZWFtOjpHZXRFeHRlbnNpb25GYWN0b3J5KCkgeworICByZXR1cm4gZXh0ZW5zaW9uX2ZhY3RvcnlfOworfQorCitpbmxpbmUgaW50IENvZGVkSW5wdXRTdHJlYW06OkJ1ZmZlclNpemUoKSBjb25zdCB7CisgIHJldHVybiBzdGF0aWNfY2FzdDxpbnQ+KGJ1ZmZlcl9lbmRfIC0gYnVmZmVyXyk7Cit9CisKK2lubGluZSBDb2RlZElucHV0U3RyZWFtOjpDb2RlZElucHV0U3RyZWFtKFplcm9Db3B5SW5wdXRTdHJlYW0qIGlucHV0KQorICA6IGJ1ZmZlcl8oTlVMTCksCisgICAgYnVmZmVyX2VuZF8oTlVMTCksCisgICAgaW5wdXRfKGlucHV0KSwKKyAgICB0b3RhbF9ieXRlc19yZWFkXygwKSwKKyAgICBvdmVyZmxvd19ieXRlc18oMCksCisgICAgbGFzdF90YWdfKDApLAorICAgIGxlZ2l0aW1hdGVfbWVzc2FnZV9lbmRfKGZhbHNlKSwKKyAgICBhbGlhc2luZ19lbmFibGVkXyhmYWxzZSksCisgICAgY3VycmVudF9saW1pdF8oa2ludDMybWF4KSwKKyAgICBidWZmZXJfc2l6ZV9hZnRlcl9saW1pdF8oMCksCisgICAgdG90YWxfYnl0ZXNfbGltaXRfKGtEZWZhdWx0VG90YWxCeXRlc0xpbWl0KSwKKyAgICB0b3RhbF9ieXRlc193YXJuaW5nX3RocmVzaG9sZF8oa0RlZmF1bHRUb3RhbEJ5dGVzV2FybmluZ1RocmVzaG9sZCksCisgICAgcmVjdXJzaW9uX2J1ZGdldF8oZGVmYXVsdF9yZWN1cnNpb25fbGltaXRfKSwKKyAgICByZWN1cnNpb25fbGltaXRfKGRlZmF1bHRfcmVjdXJzaW9uX2xpbWl0XyksCisgICAgZXh0ZW5zaW9uX3Bvb2xfKE5VTEwpLAorICAgIGV4dGVuc2lvbl9mYWN0b3J5XyhOVUxMKSB7CisgIC8vIEVhZ2VybHkgUmVmcmVzaCgpIHNvIGJ1ZmZlciBzcGFjZSBpcyBpbW1lZGlhdGVseSBhdmFpbGFibGUuCisgIFJlZnJlc2goKTsKK30KKworaW5saW5lIENvZGVkSW5wdXRTdHJlYW06OkNvZGVkSW5wdXRTdHJlYW0oY29uc3QgdWludDgqIGJ1ZmZlciwgaW50IHNpemUpCisgIDogYnVmZmVyXyhidWZmZXIpLAorICAgIGJ1ZmZlcl9lbmRfKGJ1ZmZlciArIHNpemUpLAorICAgIGlucHV0XyhOVUxMKSwKKyAgICB0b3RhbF9ieXRlc19yZWFkXyhzaXplKSwKKyAgICBvdmVyZmxvd19ieXRlc18oMCksCisgICAgbGFzdF90YWdfKDApLAorICAgIGxlZ2l0aW1hdGVfbWVzc2FnZV9lbmRfKGZhbHNlKSwKKyAgICBhbGlhc2luZ19lbmFibGVkXyhmYWxzZSksCisgICAgY3VycmVudF9saW1pdF8oc2l6ZSksCisgICAgYnVmZmVyX3NpemVfYWZ0ZXJfbGltaXRfKDApLAorICAgIHRvdGFsX2J5dGVzX2xpbWl0XyhrRGVmYXVsdFRvdGFsQnl0ZXNMaW1pdCksCisgICAgdG90YWxfYnl0ZXNfd2FybmluZ190aHJlc2hvbGRfKGtEZWZhdWx0VG90YWxCeXRlc1dhcm5pbmdUaHJlc2hvbGQpLAorICAgIHJlY3Vyc2lvbl9idWRnZXRfKGRlZmF1bHRfcmVjdXJzaW9uX2xpbWl0XyksCisgICAgcmVjdXJzaW9uX2xpbWl0XyhkZWZhdWx0X3JlY3Vyc2lvbl9saW1pdF8pLAorICAgIGV4dGVuc2lvbl9wb29sXyhOVUxMKSwKKyAgICBleHRlbnNpb25fZmFjdG9yeV8oTlVMTCkgeworICAvLyBOb3RlIHRoYXQgc2V0dGluZyBjdXJyZW50X2xpbWl0XyA9PSBzaXplIGlzIGltcG9ydGFudCB0byBwcmV2ZW50IHNvbWUKKyAgLy8gY29kZSBwYXRocyBmcm9tIHRyeWluZyB0byBhY2Nlc3MgaW5wdXRfIGFuZCBzZWdmYXVsdGluZy4KK30KKworaW5saW5lIGJvb2wgQ29kZWRJbnB1dFN0cmVhbTo6SXNGbGF0KCkgY29uc3QgeworICByZXR1cm4gaW5wdXRfID09IE5VTEw7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBpbworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKKworI2lmIF9NU0NfVkVSID49IDEzMDAgJiYgIWRlZmluZWQoX19JTlRFTF9DT01QSUxFUikKKyAgI3ByYWdtYSBydW50aW1lX2NoZWNrcygiYyIsIHJlc3RvcmUpCisjZW5kaWYgIC8vIF9NU0NfVkVSICYmICFkZWZpbmVkKF9fSU5URUxfQ09NUElMRVIpCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0lPX0NPREVEX1NUUkVBTV9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtX2lubC5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW1faW5sLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDk1YjA2ZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtX2lubC5oCkBAIC0wLDAgKzEsOTAgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGphc29uaEBnb29nbGUuY29tIChKYXNvbiBIc3VlaCkKKy8vCisvLyBJbXBsZW1lbnRzIG1ldGhvZHMgb2YgY29kZWRfc3RyZWFtLmggdGhhdCBuZWVkIHRvIGJlIGlubGluZWQgZm9yIHBlcmZvcm1hbmNlCisvLyByZWFzb25zLCBidXQgc2hvdWxkIG5vdCBiZSBkZWZpbmVkIGluIGEgcHVibGljIGhlYWRlci4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfSU9fQ09ERURfU1RSRUFNX0lOTF9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0lPX0NPREVEX1NUUkVBTV9JTkxfSF9fCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbG9nZ2luZy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbF9saXRlLmg+CisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdGxfdXRpbC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW8geworCitpbmxpbmUgYm9vbCBDb2RlZElucHV0U3RyZWFtOjpJbnRlcm5hbFJlYWRTdHJpbmdJbmxpbmUoc3RyaW5nKiBidWZmZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHNpemUpIHsKKyAgaWYgKHNpemUgPCAwKSByZXR1cm4gZmFsc2U7ICAvLyBzZWN1cml0eTogc2l6ZSBpcyBvZnRlbiB1c2VyLXN1cHBsaWVkCisKKyAgaWYgKEJ1ZmZlclNpemUoKSA+PSBzaXplKSB7CisgICAgU1RMU3RyaW5nUmVzaXplVW5pbml0aWFsaXplZChidWZmZXIsIHNpemUpOworICAgIHN0ZDo6cGFpcjxjaGFyKiwgYm9vbD4geiA9IGFzX3N0cmluZ19kYXRhKGJ1ZmZlcik7CisgICAgaWYgKHouc2Vjb25kKSB7CisgICAgICAvLyBPZGRseSBlbm91Z2gsIG1lbWNweSgpIHJlcXVpcmVzIGl0cyBmaXJzdCB0d28gYXJncyB0byBiZSBub24tTlVMTCBldmVuCisgICAgICAvLyBpZiB3ZSBjb3B5IDAgYnl0ZXMuICBTbywgd2UgaGF2ZSBlbnN1cmVkIHRoYXQgei5maXJzdCBpcyBub24tTlVMTCBoZXJlLgorICAgICAgR09PR0xFX0RDSEVDSyh6LmZpcnN0ICE9IE5VTEwpOworICAgICAgbWVtY3B5KHouZmlyc3QsIGJ1ZmZlcl8sIHNpemUpOworICAgICAgQWR2YW5jZShzaXplKTsKKyAgICB9CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICByZXR1cm4gUmVhZFN0cmluZ0ZhbGxiYWNrKGJ1ZmZlciwgc2l6ZSk7Cit9CisKK2lubGluZSBib29sIENvZGVkSW5wdXRTdHJlYW06OkludGVybmFsUmVhZFJhd0lubGluZSh2b2lkKiBidWZmZXIsIGludCBzaXplKSB7CisgIGludCBjdXJyZW50X2J1ZmZlcl9zaXplOworICB3aGlsZSAoKGN1cnJlbnRfYnVmZmVyX3NpemUgPSBCdWZmZXJTaXplKCkpIDwgc2l6ZSkgeworICAgIC8vIFJlYWRpbmcgcGFzdCBlbmQgb2YgYnVmZmVyLiAgQ29weSB3aGF0IHdlIGhhdmUsIHRoZW4gcmVmcmVzaC4KKyAgICBtZW1jcHkoYnVmZmVyLCBidWZmZXJfLCBjdXJyZW50X2J1ZmZlcl9zaXplKTsKKyAgICBidWZmZXIgPSByZWludGVycHJldF9jYXN0PHVpbnQ4Kj4oYnVmZmVyKSArIGN1cnJlbnRfYnVmZmVyX3NpemU7CisgICAgc2l6ZSAtPSBjdXJyZW50X2J1ZmZlcl9zaXplOworICAgIEFkdmFuY2UoY3VycmVudF9idWZmZXJfc2l6ZSk7CisgICAgaWYgKCFSZWZyZXNoKCkpIHJldHVybiBmYWxzZTsKKyAgfQorCisgIG1lbWNweShidWZmZXIsIGJ1ZmZlcl8sIHNpemUpOworICBBZHZhbmNlKHNpemUpOworCisgIHJldHVybiB0cnVlOworfQorCit9ICAvLyBuYW1lc3BhY2UgaW8KK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfSU9fQ09ERURfU1RSRUFNX0lOTF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtX3VuaXR0ZXN0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW1fdW5pdHRlc3QuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDE3ODJlMwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtX3VuaXR0ZXN0LmNjCkBAIC0wLDAgKzEsMTM4NSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorLy8KKy8vIFRoaXMgZmlsZSBjb250YWlucyB0ZXN0cyBhbmQgYmVuY2htYXJrcy4KKworI2luY2x1ZGUgPG1lbW9yeT4KKyNpZm5kZWYgX1NIQVJFRF9QVFJfSAorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaGFyZWRfcHRyLmg+CisjZW5kaWYKKyNpbmNsdWRlIDx2ZWN0b3I+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmg+CisKKyNpbmNsdWRlIDxsaW1pdHMuaD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbG9nZ2luZy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zY29wZWRfcHRyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZ29vZ2xldGVzdC5oPgorI2luY2x1ZGUgPGd0ZXN0L2d0ZXN0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbC5oPgorCisKKy8vIFRoaXMgZGVjbGFyZXMgYW4gdW5zaWduZWQgbG9uZyBsb25nIGludGVnZXIgbGl0ZXJhbCBpbiBhIHBvcnRhYmxlIHdheS4KKy8vIChUaGUgb3JpZ2luYWwgbWFjcm8gaXMgd2F5IHRvbyBiaWcgYW5kIHJ1aW5zIG15IGZvcm1hdHRpbmcuKQorI3VuZGVmIFVMTAorI2RlZmluZSBVTEwoeCkgR09PR0xFX1VMT05HTE9ORyh4KQorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW8geworbmFtZXNwYWNlIHsKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorLy8gRGF0YS1Ecml2ZW4gVGVzdCBJbmZyYXN0cnVjdHVyZQorCisvLyBURVNUXzFEIGFuZCBURVNUXzJEIGFyZSBtYWNyb3MgSSdkIGV2ZW50dWFsbHkgbGlrZSB0byBzZWUgYWRkZWQgdG8KKy8vIGdUZXN0LiAgVGhlc2UgbWFjcm9zIGNhbiBiZSB1c2VkIHRvIGRlY2xhcmUgdGVzdHMgd2hpY2ggc2hvdWxkIGJlCisvLyBydW4gbXVsdGlwbGUgdGltZXMsIG9uY2UgZm9yIGVhY2ggaXRlbSBpbiBzb21lIGlucHV0IGFycmF5LiAgVEVTVF8xRAorLy8gdGVzdHMgYWxsIGNhc2VzIGluIGEgc2luZ2xlIGlucHV0IGFycmF5LiAgVEVTVF8yRCB0ZXN0cyBhbGwKKy8vIGNvbWJpbmF0aW9ucyBvZiBjYXNlcyBmcm9tIHR3byBhcnJheXMuICBUaGUgYXJyYXlzIG11c3QgYmUgc3RhdGljYWxseQorLy8gZGVmaW5lZCBzdWNoIHRoYXQgdGhlIEdPT0dMRV9BUlJBWVNJWkUoKSBtYWNybyB3b3JrcyBvbiB0aGVtLiAgRXhhbXBsZToKKy8vCisvLyBpbnQga0Nhc2VzW10gPSB7MSwgMiwgMywgNH0KKy8vIFRFU1RfMUQoTXlGaXh0dXJlLCBNeVRlc3QsIGtDYXNlcykgeworLy8gICBFWFBFQ1RfR1Qoa0Nhc2VzX2Nhc2UsIDApOworLy8gfQorLy8KKy8vIFRoaXMgdGVzdCBpdGVyYXRlcyB0aHJvdWdoIHRoZSBudW1iZXJzIDEsIDIsIDMsIGFuZCA0IGFuZCB0ZXN0cyB0aGF0CisvLyB0aGV5IGFyZSBhbGwgZ3JhdGVyIHRoYW4gemVyby4gIEluIGNhc2Ugb2YgZmFpbHVyZSwgdGhlIGV4YWN0IGNhc2UKKy8vIHdoaWNoIGZhaWxlZCB3aWxsIGJlIHByaW50ZWQuICBUaGUgY2FzZSB0eXBlIG11c3QgYmUgcHJpbnRhYmxlIHVzaW5nCisvLyBvc3RyZWFtOjpvcGVyYXRvcjw8LgorCisvLyBUT0RPKGtlbnRvbik6ICBnVGVzdCBub3cgc3VwcG9ydHMgInBhcmFtZXRlcml6ZWQgdGVzdHMiIHdoaWNoIHdvdWxkIGJlCisvLyAgIGEgYmV0dGVyIHdheSB0byBhY2NvbXBsaXNoIHRoaXMuICBSZXdyaXRlIHdoZW4gdGltZSBwZXJtaXRzLgorCisjZGVmaW5lIFRFU1RfMUQoRklYVFVSRSwgTkFNRSwgQ0FTRVMpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGNsYXNzIEZJWFRVUkUjI18jI05BTUUjI19ERCA6IHB1YmxpYyBGSVhUVVJFIHsgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICBwcm90ZWN0ZWQ6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgdGVtcGxhdGUgPHR5cGVuYW1lIENhc2VUeXBlPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgdm9pZCBEb1NpbmdsZUNhc2UoY29uc3QgQ2FzZVR5cGUmIENBU0VTIyNfY2FzZSk7ICAgICAgICAgICAgICAgICAgICAgICBcCisgIH07ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIFRFU1RfRihGSVhUVVJFIyNfIyNOQU1FIyNfREQsIE5BTUUpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBHT09HTEVfQVJSQVlTSVpFKENBU0VTKTsgaSsrKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgU0NPUEVEX1RSQUNFKHRlc3Rpbmc6Ok1lc3NhZ2UoKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICA8PCAjQ0FTRVMgIiBjYXNlICMiIDw8IGkgPDwgIjogIiA8PCBDQVNFU1tpXSk7ICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgRG9TaW5nbGVDYXNlKENBU0VTW2ldKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgQ2FzZVR5cGU+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB2b2lkIEZJWFRVUkUjI18jI05BTUUjI19ERDo6RG9TaW5nbGVDYXNlKGNvbnN0IENhc2VUeXBlJiBDQVNFUyMjX2Nhc2UpCisKKyNkZWZpbmUgVEVTVF8yRChGSVhUVVJFLCBOQU1FLCBDQVNFUzEsIENBU0VTMikgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgY2xhc3MgRklYVFVSRSMjXyMjTkFNRSMjX0REIDogcHVibGljIEZJWFRVUkUgeyAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgIHByb3RlY3RlZDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgQ2FzZVR5cGUxLCB0eXBlbmFtZSBDYXNlVHlwZTI+ICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICB2b2lkIERvU2luZ2xlQ2FzZShjb25zdCBDYXNlVHlwZTEmIENBU0VTMSMjX2Nhc2UsICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICBjb25zdCBDYXNlVHlwZTImIENBU0VTMiMjX2Nhc2UpOyAgICAgICAgICAgICAgICAgICAgIFwKKyAgfTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgVEVTVF9GKEZJWFRVUkUjI18jI05BTUUjI19ERCwgTkFNRSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IEdPT0dMRV9BUlJBWVNJWkUoQ0FTRVMxKTsgaSsrKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICBmb3IgKGludCBqID0gMDsgaiA8IEdPT0dMRV9BUlJBWVNJWkUoQ0FTRVMyKTsgaisrKSB7ICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBTQ09QRURfVFJBQ0UodGVzdGluZzo6TWVzc2FnZSgpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgIDw8ICNDQVNFUzEgIiBjYXNlICMiIDw8IGkgPDwgIjogIiA8PCBDQVNFUzFbaV0gPDwgIiwgIiAgICAgICAgICAgXAorICAgICAgICAgIDw8ICNDQVNFUzIgIiBjYXNlICMiIDw8IGogPDwgIjogIiA8PCBDQVNFUzJbal0pOyAgICAgICAgICAgICAgICAgXAorICAgICAgICBEb1NpbmdsZUNhc2UoQ0FTRVMxW2ldLCBDQVNFUzJbal0pOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgQ2FzZVR5cGUxLCB0eXBlbmFtZSBDYXNlVHlwZTI+ICAgICAgICAgICAgICAgICAgICAgICAgXAorICB2b2lkIEZJWFRVUkUjI18jI05BTUUjI19ERDo6RG9TaW5nbGVDYXNlKGNvbnN0IENhc2VUeXBlMSYgQ0FTRVMxIyNfY2FzZSwgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IENhc2VUeXBlMiYgQ0FTRVMyIyNfY2FzZSkKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitjbGFzcyBDb2RlZFN0cmVhbVRlc3QgOiBwdWJsaWMgdGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICAvLyBIZWxwZXIgbWV0aG9kIHVzZWQgYnkgdGVzdHMgZm9yIGJ5dGVzIHdhcm5pbmcuIFNlZSBpbXBsZW1lbnRhdGlvbiBjb21tZW50CisgIC8vIGZvciBmdXJ0aGVyIGluZm9ybWF0aW9uLgorICBzdGF0aWMgdm9pZCBTZXR1cFRvdGFsQnl0ZXNMaW1pdFdhcm5pbmdUZXN0KAorICAgICAgaW50IHRvdGFsX2J5dGVzX2xpbWl0LCBpbnQgd2FybmluZ190aHJlc2hvbGQsCisgICAgICB2ZWN0b3I8c3RyaW5nPiogb3V0X2Vycm9ycywgdmVjdG9yPHN0cmluZz4qIG91dF93YXJuaW5ncyk7CisKKyAgLy8gQnVmZmVyIHVzZWQgZHVyaW5nIG1vc3Qgb2YgdGhlIHRlc3RzLiBUaGlzIGFzc3VtZXMgdGVzdHMgcnVuIHNlcXVlbnRpYWxseS4KKyAgc3RhdGljIGNvbnN0IGludCBrQnVmZmVyU2l6ZSA9IDEwMjQgKiA2NDsKKyAgc3RhdGljIHVpbnQ4IGJ1ZmZlcl9ba0J1ZmZlclNpemVdOworfTsKKwordWludDggQ29kZWRTdHJlYW1UZXN0OjpidWZmZXJfW0NvZGVkU3RyZWFtVGVzdDo6a0J1ZmZlclNpemVdOworCisvLyBXZSB0ZXN0IGVhY2ggb3BlcmF0aW9uIG92ZXIgYSB2YXJpZXR5IG9mIGJsb2NrIHNpemVzIHRvIGluc3VyZSB0aGF0CisvLyB3ZSB0ZXN0IGNhc2VzIHdoZXJlIHJlYWRzIG9yIHdyaXRlcyBjcm9zcyBidWZmZXIgYm91bmRhcmllcywgY2FzZXMKKy8vIHdoZXJlIHRoZXkgZG9uJ3QsIGFuZCBjYXNlcyB3aGVyZSB0aGVyZSBpcyBzbyBtdWNoIGJ1ZmZlciBsZWZ0IHRoYXQKKy8vIHdlIGNhbiB1c2Ugc3BlY2lhbCBvcHRpbWl6ZWQgcGF0aHMgdGhhdCBkb24ndCB3b3JyeSBhYm91dCBib3VuZHMKKy8vIGNoZWNrcy4KK2NvbnN0IGludCBrQmxvY2tTaXplc1tdID0gezEsIDIsIDMsIDUsIDcsIDEzLCAzMiwgMTAyNH07CisKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gVmFyaW50IHRlc3RzLgorCitzdHJ1Y3QgVmFyaW50Q2FzZSB7CisgIHVpbnQ4IGJ5dGVzWzEwXTsgICAgICAgICAgLy8gRW5jb2RlZCBieXRlcy4KKyAgaW50IHNpemU7ICAgICAgICAgICAgICAgICAvLyBFbmNvZGVkIHNpemUsIGluIGJ5dGVzLgorICB1aW50NjQgdmFsdWU7ICAgICAgICAgICAgIC8vIFBhcnNlZCB2YWx1ZS4KK307CisKK2lubGluZSBzdGQ6Om9zdHJlYW0mIG9wZXJhdG9yPDwoc3RkOjpvc3RyZWFtJiBvcywgY29uc3QgVmFyaW50Q2FzZSYgYykgeworICByZXR1cm4gb3MgPDwgYy52YWx1ZTsKK30KKworVmFyaW50Q2FzZSBrVmFyaW50Q2FzZXNbXSA9IHsKKyAgLy8gMzItYml0IHZhbHVlcworICB7ezB4MDB9ICAgICAgLCAxLCAwfSwKKyAge3sweDAxfSAgICAgICwgMSwgMX0sCisgIHt7MHg3Zn0gICAgICAsIDEsIDEyN30sCisgIHt7MHhhMiwgMHg3NH0sIDIsICgweDIyIDw8IDApIHwgKDB4NzQgPDwgNyl9LCAgICAgICAgICAvLyAxNDg4MgorICB7ezB4YmUsIDB4ZjcsIDB4OTIsIDB4ODQsIDB4MGJ9LCA1LCAgICAgICAgICAgICAgICAgICAgLy8gMjk2MTQ4ODgzMAorICAgICgweDNlIDw8IDApIHwgKDB4NzcgPDwgNykgfCAoMHgxMiA8PCAxNCkgfCAoMHgwNCA8PCAyMSkgfAorICAgIChVTEwoMHgwYikgPDwgMjgpfSwKKworICAvLyA2NC1iaXQKKyAge3sweGJlLCAweGY3LCAweDkyLCAweDg0LCAweDFifSwgNSwgICAgICAgICAgICAgICAgICAgIC8vIDcyNTY0NTYxMjYKKyAgICAoMHgzZSA8PCAwKSB8ICgweDc3IDw8IDcpIHwgKDB4MTIgPDwgMTQpIHwgKDB4MDQgPDwgMjEpIHwKKyAgICAoVUxMKDB4MWIpIDw8IDI4KX0sCisgIHt7MHg4MCwgMHhlNiwgMHhlYiwgMHg5YywgMHhjMywgMHhjOSwgMHhhNCwgMHg0OX0sIDgsICAvLyA0MTI1NjIwMjU4MDcxODMzNgorICAgICgweDAwIDw8IDApIHwgKDB4NjYgPDwgNykgfCAoMHg2YiA8PCAxNCkgfCAoMHgxYyA8PCAyMSkgfAorICAgIChVTEwoMHg0MykgPDwgMjgpIHwgKFVMTCgweDQ5KSA8PCAzNSkgfCAoVUxMKDB4MjQpIDw8IDQyKSB8CisgICAgKFVMTCgweDQ5KSA8PCA0OSl9LAorICAvLyAxMTk2NDM3ODMzMDk3ODczNTEzMQorICB7ezB4OWIsIDB4YTgsIDB4ZjksIDB4YzIsIDB4YmIsIDB4ZDYsIDB4ODAsIDB4ODUsIDB4YTYsIDB4MDF9LCAxMCwKKyAgICAoMHgxYiA8PCAwKSB8ICgweDI4IDw8IDcpIHwgKDB4NzkgPDwgMTQpIHwgKDB4NDIgPDwgMjEpIHwKKyAgICAoVUxMKDB4M2IpIDw8IDI4KSB8IChVTEwoMHg1NikgPDwgMzUpIHwgKFVMTCgweDAwKSA8PCA0MikgfAorICAgIChVTEwoMHgwNSkgPDwgNDkpIHwgKFVMTCgweDI2KSA8PCA1NikgfCAoVUxMKDB4MDEpIDw8IDYzKX0sCit9OworCitURVNUXzJEKENvZGVkU3RyZWFtVGVzdCwgUmVhZFZhcmludDMyLCBrVmFyaW50Q2FzZXMsIGtCbG9ja1NpemVzKSB7CisgIG1lbWNweShidWZmZXJfLCBrVmFyaW50Q2FzZXNfY2FzZS5ieXRlcywga1ZhcmludENhc2VzX2Nhc2Uuc2l6ZSk7CisgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQoYnVmZmVyXywgc2l6ZW9mKGJ1ZmZlcl8pLCBrQmxvY2tTaXplc19jYXNlKTsKKworICB7CisgICAgQ29kZWRJbnB1dFN0cmVhbSBjb2RlZF9pbnB1dCgmaW5wdXQpOworCisgICAgdWludDMyIHZhbHVlOworICAgIEVYUEVDVF9UUlVFKGNvZGVkX2lucHV0LlJlYWRWYXJpbnQzMigmdmFsdWUpKTsKKyAgICBFWFBFQ1RfRVEoc3RhdGljX2Nhc3Q8dWludDMyPihrVmFyaW50Q2FzZXNfY2FzZS52YWx1ZSksIHZhbHVlKTsKKyAgfQorCisgIEVYUEVDVF9FUShrVmFyaW50Q2FzZXNfY2FzZS5zaXplLCBpbnB1dC5CeXRlQ291bnQoKSk7Cit9CisKK1RFU1RfMkQoQ29kZWRTdHJlYW1UZXN0LCBSZWFkVGFnLCBrVmFyaW50Q2FzZXMsIGtCbG9ja1NpemVzKSB7CisgIG1lbWNweShidWZmZXJfLCBrVmFyaW50Q2FzZXNfY2FzZS5ieXRlcywga1ZhcmludENhc2VzX2Nhc2Uuc2l6ZSk7CisgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQoYnVmZmVyXywgc2l6ZW9mKGJ1ZmZlcl8pLCBrQmxvY2tTaXplc19jYXNlKTsKKworICB7CisgICAgQ29kZWRJbnB1dFN0cmVhbSBjb2RlZF9pbnB1dCgmaW5wdXQpOworCisgICAgdWludDMyIGV4cGVjdGVkX3ZhbHVlID0gc3RhdGljX2Nhc3Q8dWludDMyPihrVmFyaW50Q2FzZXNfY2FzZS52YWx1ZSk7CisgICAgRVhQRUNUX0VRKGV4cGVjdGVkX3ZhbHVlLCBjb2RlZF9pbnB1dC5SZWFkVGFnKCkpOworCisgICAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuTGFzdFRhZ1dhcyhleHBlY3RlZF92YWx1ZSkpOworICAgIEVYUEVDVF9GQUxTRShjb2RlZF9pbnB1dC5MYXN0VGFnV2FzKGV4cGVjdGVkX3ZhbHVlICsgMSkpOworICB9CisKKyAgRVhQRUNUX0VRKGtWYXJpbnRDYXNlc19jYXNlLnNpemUsIGlucHV0LkJ5dGVDb3VudCgpKTsKK30KKworLy8gVGhpcyBpcyB0aGUgcmVncmVzc2lvbiB0ZXN0IHRoYXQgdmVyaWZpZXMgdGhhdCB0aGVyZSBpcyBubyBpc3N1ZXMKKy8vIHdpdGggdGhlIGVtcHR5IGlucHV0IGJ1ZmZlcnMgaGFuZGxpbmcuCitURVNUX0YoQ29kZWRTdHJlYW1UZXN0LCBFbXB0eUlucHV0QmVmb3JlRW9zKSB7CisgIGNsYXNzIEluIDogcHVibGljIFplcm9Db3B5SW5wdXRTdHJlYW0geworICAgcHVibGljOgorICAgIEluKCkgOiBjb3VudF8oMCkge30KKyAgIHByaXZhdGU6CisgICAgdmlydHVhbCBib29sIE5leHQoY29uc3Qgdm9pZCoqIGRhdGEsIGludCogc2l6ZSkgeworICAgICAgKmRhdGEgPSBOVUxMOworICAgICAgKnNpemUgPSAwOworICAgICAgcmV0dXJuIGNvdW50XysrIDwgMjsKKyAgICB9CisgICAgdmlydHVhbCB2b2lkIEJhY2tVcChpbnQgY291bnQpICB7CisgICAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiVGVzdHMgbmV2ZXIgY2FsbCB0aGlzLiI7CisgICAgfQorICAgIHZpcnR1YWwgYm9vbCBTa2lwKGludCBjb3VudCkgeworICAgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIlRlc3RzIG5ldmVyIGNhbGwgdGhpcy4iOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICB2aXJ0dWFsIGludDY0IEJ5dGVDb3VudCgpIGNvbnN0IHsgcmV0dXJuIDA7IH0KKyAgICBpbnQgY291bnRfOworICB9IGluOworICBDb2RlZElucHV0U3RyZWFtIGlucHV0KCZpbik7CisgIGlucHV0LlJlYWRUYWcoKTsKKyAgRVhQRUNUX1RSVUUoaW5wdXQuQ29uc3VtZWRFbnRpcmVNZXNzYWdlKCkpOworfQorCitURVNUXzFEKENvZGVkU3RyZWFtVGVzdCwgRXhwZWN0VGFnLCBrVmFyaW50Q2FzZXMpIHsKKyAgLy8gTGVhdmUgb25lIGJ5dGUgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgYnVmZmVyIHNvIHdlIGNhbiByZWFkIGl0CisgIC8vIHRvIGZvcmNlIHRoZSBmaXJzdCBidWZmZXIgdG8gYmUgbG9hZGVkLgorICBidWZmZXJfWzBdID0gJ1wwJzsKKyAgbWVtY3B5KGJ1ZmZlcl8gKyAxLCBrVmFyaW50Q2FzZXNfY2FzZS5ieXRlcywga1ZhcmludENhc2VzX2Nhc2Uuc2l6ZSk7CisgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQoYnVmZmVyXywgc2l6ZW9mKGJ1ZmZlcl8pKTsKKworICB7CisgICAgQ29kZWRJbnB1dFN0cmVhbSBjb2RlZF9pbnB1dCgmaW5wdXQpOworCisgICAgLy8gUmVhZCBvbmUgYnl0ZSB0byBmb3JjZSBjb2RlZF9pbnB1dC5SZWZpbGwoKSB0byBiZSBjYWxsZWQuICBPdGhlcndpc2UsCisgICAgLy8gRXhwZWN0VGFnKCkgd2lsbCByZXR1cm4gYSBmYWxzZSBuZWdhdGl2ZS4KKyAgICB1aW50OCBkdW1teTsKKyAgICBjb2RlZF9pbnB1dC5SZWFkUmF3KCZkdW1teSwgMSk7CisgICAgRVhQRUNUX0VRKCh1aW50KSdcMCcsICh1aW50KWR1bW15KTsKKworICAgIHVpbnQzMiBleHBlY3RlZF92YWx1ZSA9IHN0YXRpY19jYXN0PHVpbnQzMj4oa1ZhcmludENhc2VzX2Nhc2UudmFsdWUpOworCisgICAgLy8gRXhwZWN0VGFnKCkgcHJvZHVjZXMgZmFsc2UgbmVnYXRpdmVzIGZvciBsYXJnZSB2YWx1ZXMuCisgICAgaWYgKGtWYXJpbnRDYXNlc19jYXNlLnNpemUgPD0gMikgeworICAgICAgRVhQRUNUX0ZBTFNFKGNvZGVkX2lucHV0LkV4cGVjdFRhZyhleHBlY3RlZF92YWx1ZSArIDEpKTsKKyAgICAgIEVYUEVDVF9UUlVFKGNvZGVkX2lucHV0LkV4cGVjdFRhZyhleHBlY3RlZF92YWx1ZSkpOworICAgIH0gZWxzZSB7CisgICAgICBFWFBFQ1RfRkFMU0UoY29kZWRfaW5wdXQuRXhwZWN0VGFnKGV4cGVjdGVkX3ZhbHVlKSk7CisgICAgfQorICB9CisKKyAgaWYgKGtWYXJpbnRDYXNlc19jYXNlLnNpemUgPD0gMikgeworICAgIEVYUEVDVF9FUShrVmFyaW50Q2FzZXNfY2FzZS5zaXplICsgMSwgaW5wdXQuQnl0ZUNvdW50KCkpOworICB9IGVsc2UgeworICAgIEVYUEVDVF9FUSgxLCBpbnB1dC5CeXRlQ291bnQoKSk7CisgIH0KK30KKworVEVTVF8xRChDb2RlZFN0cmVhbVRlc3QsIEV4cGVjdFRhZ0Zyb21BcnJheSwga1ZhcmludENhc2VzKSB7CisgIG1lbWNweShidWZmZXJfLCBrVmFyaW50Q2FzZXNfY2FzZS5ieXRlcywga1ZhcmludENhc2VzX2Nhc2Uuc2l6ZSk7CisKKyAgY29uc3QgdWludDMyIGV4cGVjdGVkX3ZhbHVlID0gc3RhdGljX2Nhc3Q8dWludDMyPihrVmFyaW50Q2FzZXNfY2FzZS52YWx1ZSk7CisKKyAgLy8gSWYgdGhlIGV4cGVjdGF0aW9uIHN1Y2NlZWRzLCBpdCBzaG91bGQgcmV0dXJuIGEgcG9pbnRlciBwYXN0IHRoZSB0YWcuCisgIGlmIChrVmFyaW50Q2FzZXNfY2FzZS5zaXplIDw9IDIpIHsKKyAgICBFWFBFQ1RfVFJVRShOVUxMID09CisgICAgICAgICAgICAgICAgQ29kZWRJbnB1dFN0cmVhbTo6RXhwZWN0VGFnRnJvbUFycmF5KGJ1ZmZlcl8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkX3ZhbHVlICsgMSkpOworICAgIEVYUEVDVF9UUlVFKGJ1ZmZlcl8gKyBrVmFyaW50Q2FzZXNfY2FzZS5zaXplID09CisgICAgICAgICAgICAgICAgQ29kZWRJbnB1dFN0cmVhbTo6RXhwZWN0VGFnRnJvbUFycmF5KGJ1ZmZlcl8sIGV4cGVjdGVkX3ZhbHVlKSk7CisgIH0gZWxzZSB7CisgICAgRVhQRUNUX1RSVUUoTlVMTCA9PQorICAgICAgICAgICAgICAgIENvZGVkSW5wdXRTdHJlYW06OkV4cGVjdFRhZ0Zyb21BcnJheShidWZmZXJfLCBleHBlY3RlZF92YWx1ZSkpOworICB9Cit9CisKK1RFU1RfMkQoQ29kZWRTdHJlYW1UZXN0LCBSZWFkVmFyaW50NjQsIGtWYXJpbnRDYXNlcywga0Jsb2NrU2l6ZXMpIHsKKyAgbWVtY3B5KGJ1ZmZlcl8sIGtWYXJpbnRDYXNlc19jYXNlLmJ5dGVzLCBrVmFyaW50Q2FzZXNfY2FzZS5zaXplKTsKKyAgQXJyYXlJbnB1dFN0cmVhbSBpbnB1dChidWZmZXJfLCBzaXplb2YoYnVmZmVyXyksIGtCbG9ja1NpemVzX2Nhc2UpOworCisgIHsKKyAgICBDb2RlZElucHV0U3RyZWFtIGNvZGVkX2lucHV0KCZpbnB1dCk7CisKKyAgICB1aW50NjQgdmFsdWU7CisgICAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuUmVhZFZhcmludDY0KCZ2YWx1ZSkpOworICAgIEVYUEVDVF9FUShrVmFyaW50Q2FzZXNfY2FzZS52YWx1ZSwgdmFsdWUpOworICB9CisKKyAgRVhQRUNUX0VRKGtWYXJpbnRDYXNlc19jYXNlLnNpemUsIGlucHV0LkJ5dGVDb3VudCgpKTsKK30KKworVEVTVF8yRChDb2RlZFN0cmVhbVRlc3QsIFdyaXRlVmFyaW50MzIsIGtWYXJpbnRDYXNlcywga0Jsb2NrU2l6ZXMpIHsKKyAgaWYgKGtWYXJpbnRDYXNlc19jYXNlLnZhbHVlID4gVUxMKDB4MDAwMDAwMDBGRkZGRkZGRikpIHsKKyAgICAvLyBTa2lwIHRoaXMgdGVzdCBmb3IgdGhlIDY0LWJpdCB2YWx1ZXMuCisgICAgcmV0dXJuOworICB9CisKKyAgQXJyYXlPdXRwdXRTdHJlYW0gb3V0cHV0KGJ1ZmZlcl8sIHNpemVvZihidWZmZXJfKSwga0Jsb2NrU2l6ZXNfY2FzZSk7CisKKyAgeworICAgIENvZGVkT3V0cHV0U3RyZWFtIGNvZGVkX291dHB1dCgmb3V0cHV0KTsKKworICAgIGNvZGVkX291dHB1dC5Xcml0ZVZhcmludDMyKHN0YXRpY19jYXN0PHVpbnQzMj4oa1ZhcmludENhc2VzX2Nhc2UudmFsdWUpKTsKKyAgICBFWFBFQ1RfRkFMU0UoY29kZWRfb3V0cHV0LkhhZEVycm9yKCkpOworCisgICAgRVhQRUNUX0VRKGtWYXJpbnRDYXNlc19jYXNlLnNpemUsIGNvZGVkX291dHB1dC5CeXRlQ291bnQoKSk7CisgIH0KKworICBFWFBFQ1RfRVEoa1ZhcmludENhc2VzX2Nhc2Uuc2l6ZSwgb3V0cHV0LkJ5dGVDb3VudCgpKTsKKyAgRVhQRUNUX0VRKDAsCisgICAgbWVtY21wKGJ1ZmZlcl8sIGtWYXJpbnRDYXNlc19jYXNlLmJ5dGVzLCBrVmFyaW50Q2FzZXNfY2FzZS5zaXplKSk7Cit9CisKK1RFU1RfMkQoQ29kZWRTdHJlYW1UZXN0LCBXcml0ZVZhcmludDY0LCBrVmFyaW50Q2FzZXMsIGtCbG9ja1NpemVzKSB7CisgIEFycmF5T3V0cHV0U3RyZWFtIG91dHB1dChidWZmZXJfLCBzaXplb2YoYnVmZmVyXyksIGtCbG9ja1NpemVzX2Nhc2UpOworCisgIHsKKyAgICBDb2RlZE91dHB1dFN0cmVhbSBjb2RlZF9vdXRwdXQoJm91dHB1dCk7CisKKyAgICBjb2RlZF9vdXRwdXQuV3JpdGVWYXJpbnQ2NChrVmFyaW50Q2FzZXNfY2FzZS52YWx1ZSk7CisgICAgRVhQRUNUX0ZBTFNFKGNvZGVkX291dHB1dC5IYWRFcnJvcigpKTsKKworICAgIEVYUEVDVF9FUShrVmFyaW50Q2FzZXNfY2FzZS5zaXplLCBjb2RlZF9vdXRwdXQuQnl0ZUNvdW50KCkpOworICB9CisKKyAgRVhQRUNUX0VRKGtWYXJpbnRDYXNlc19jYXNlLnNpemUsIG91dHB1dC5CeXRlQ291bnQoKSk7CisgIEVYUEVDVF9FUSgwLAorICAgIG1lbWNtcChidWZmZXJfLCBrVmFyaW50Q2FzZXNfY2FzZS5ieXRlcywga1ZhcmludENhc2VzX2Nhc2Uuc2l6ZSkpOworfQorCisvLyBUaGlzIHRlc3QgY2F1c2VzIGdjYyAzLjMuNSAoYW5kIGVhcmxpZXI/KSB0byBnaXZlIHRoZSBjcnlwdGljIGVycm9yOgorLy8gICAic29ycnksIHVuaW1wbGVtZW50ZWQ6IGBtZXRob2RfY2FsbF9leHByJyBub3Qgc3VwcG9ydGVkIGJ5IGR1bXBfZXhwciIKKyNpZiAhZGVmaW5lZChfX0dOVUNfXykgfHwgX19HTlVDX18gPiAzIHx8IChfX0dOVUNfXyA9PSAzICYmIF9fR05VQ19NSU5PUl9fID4gMykKKworaW50MzIga1NpZ25FeHRlbmRlZFZhcmludENhc2VzW10gPSB7CisgIDAsIDEsIC0xLCAxMjM3ODk0LCAtMzc4OTUxMzgKK307CisKK1RFU1RfMkQoQ29kZWRTdHJlYW1UZXN0LCBXcml0ZVZhcmludDMyU2lnbkV4dGVuZGVkLAorICAgICAgICBrU2lnbkV4dGVuZGVkVmFyaW50Q2FzZXMsIGtCbG9ja1NpemVzKSB7CisgIEFycmF5T3V0cHV0U3RyZWFtIG91dHB1dChidWZmZXJfLCBzaXplb2YoYnVmZmVyXyksIGtCbG9ja1NpemVzX2Nhc2UpOworCisgIHsKKyAgICBDb2RlZE91dHB1dFN0cmVhbSBjb2RlZF9vdXRwdXQoJm91dHB1dCk7CisKKyAgICBjb2RlZF9vdXRwdXQuV3JpdGVWYXJpbnQzMlNpZ25FeHRlbmRlZChrU2lnbkV4dGVuZGVkVmFyaW50Q2FzZXNfY2FzZSk7CisgICAgRVhQRUNUX0ZBTFNFKGNvZGVkX291dHB1dC5IYWRFcnJvcigpKTsKKworICAgIGlmIChrU2lnbkV4dGVuZGVkVmFyaW50Q2FzZXNfY2FzZSA8IDApIHsKKyAgICAgIEVYUEVDVF9FUSgxMCwgY29kZWRfb3V0cHV0LkJ5dGVDb3VudCgpKTsKKyAgICB9IGVsc2UgeworICAgICAgRVhQRUNUX0xFKGNvZGVkX291dHB1dC5CeXRlQ291bnQoKSwgNSk7CisgICAgfQorICB9CisKKyAgaWYgKGtTaWduRXh0ZW5kZWRWYXJpbnRDYXNlc19jYXNlIDwgMCkgeworICAgIEVYUEVDVF9FUSgxMCwgb3V0cHV0LkJ5dGVDb3VudCgpKTsKKyAgfSBlbHNlIHsKKyAgICBFWFBFQ1RfTEUob3V0cHV0LkJ5dGVDb3VudCgpLCA1KTsKKyAgfQorCisgIC8vIFJlYWQgdmFsdWUgYmFjayBpbiBhcyBhIHZhcmludDY0IGFuZCBpbnN1cmUgaXQgbWF0Y2hlcy4KKyAgQXJyYXlJbnB1dFN0cmVhbSBpbnB1dChidWZmZXJfLCBzaXplb2YoYnVmZmVyXykpOworCisgIHsKKyAgICBDb2RlZElucHV0U3RyZWFtIGNvZGVkX2lucHV0KCZpbnB1dCk7CisKKyAgICB1aW50NjQgdmFsdWU7CisgICAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuUmVhZFZhcmludDY0KCZ2YWx1ZSkpOworCisgICAgRVhQRUNUX0VRKGtTaWduRXh0ZW5kZWRWYXJpbnRDYXNlc19jYXNlLCBzdGF0aWNfY2FzdDxpbnQ2ND4odmFsdWUpKTsKKyAgfQorCisgIEVYUEVDVF9FUShvdXRwdXQuQnl0ZUNvdW50KCksIGlucHV0LkJ5dGVDb3VudCgpKTsKK30KKworI2VuZGlmCisKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gVmFyaW50IGZhaWx1cmUgdGVzdC4KKworc3RydWN0IFZhcmludEVycm9yQ2FzZSB7CisgIHVpbnQ4IGJ5dGVzWzEyXTsKKyAgaW50IHNpemU7CisgIGJvb2wgY2FuX3BhcnNlOworfTsKKworaW5saW5lIHN0ZDo6b3N0cmVhbSYgb3BlcmF0b3I8PChzdGQ6Om9zdHJlYW0mIG9zLCBjb25zdCBWYXJpbnRFcnJvckNhc2UmIGMpIHsKKyAgcmV0dXJuIG9zIDw8ICJzaXplICIgPDwgYy5zaXplOworfQorCitjb25zdCBWYXJpbnRFcnJvckNhc2Uga1ZhcmludEVycm9yQ2FzZXNbXSA9IHsKKyAgLy8gQ29udHJvbCBjYXNlLiAgKEluc3VyZXMgdGhhdCB0aGVyZSBpc24ndCBzb21ldGhpbmcgZWxzZSB3cm9uZyB0aGF0CisgIC8vIG1ha2VzIHBhcnNpbmcgYWx3YXlzIGZhaWwuKQorICB7ezB4MDB9LCAxLCB0cnVlfSwKKworICAvLyBObyBpbnB1dCBkYXRhLgorICB7e30sIDAsIGZhbHNlfSwKKworICAvLyBJbnB1dCBlbmRzIHVuZXhwZWN0ZWRseS4KKyAge3sweGYwLCAweGFifSwgMiwgZmFsc2V9LAorCisgIC8vIElucHV0IGVuZHMgdW5leHBlY3RlZGx5IGFmdGVyIDMyIGJpdHMuCisgIHt7MHhmMCwgMHhhYiwgMHhjOSwgMHg5YSwgMHhmOCwgMHhiMn0sIDYsIGZhbHNlfSwKKworICAvLyBMb25nZXIgdGhhbiAxMCBieXRlcy4KKyAge3sweGZmLCAweGZmLCAweGZmLCAweGZmLCAweGZmLCAweGZmLCAweGZmLCAweGZmLCAweGZmLCAweGZmLCAweDAxfSwKKyAgIDExLCBmYWxzZX0sCit9OworCitURVNUXzJEKENvZGVkU3RyZWFtVGVzdCwgUmVhZFZhcmludDMyRXJyb3IsIGtWYXJpbnRFcnJvckNhc2VzLCBrQmxvY2tTaXplcykgeworICBtZW1jcHkoYnVmZmVyXywga1ZhcmludEVycm9yQ2FzZXNfY2FzZS5ieXRlcywga1ZhcmludEVycm9yQ2FzZXNfY2FzZS5zaXplKTsKKyAgQXJyYXlJbnB1dFN0cmVhbSBpbnB1dChidWZmZXJfLCBrVmFyaW50RXJyb3JDYXNlc19jYXNlLnNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAga0Jsb2NrU2l6ZXNfY2FzZSk7CisgIENvZGVkSW5wdXRTdHJlYW0gY29kZWRfaW5wdXQoJmlucHV0KTsKKworICB1aW50MzIgdmFsdWU7CisgIEVYUEVDVF9FUShrVmFyaW50RXJyb3JDYXNlc19jYXNlLmNhbl9wYXJzZSwgY29kZWRfaW5wdXQuUmVhZFZhcmludDMyKCZ2YWx1ZSkpOworfQorCitURVNUXzJEKENvZGVkU3RyZWFtVGVzdCwgUmVhZFZhcmludDY0RXJyb3IsIGtWYXJpbnRFcnJvckNhc2VzLCBrQmxvY2tTaXplcykgeworICBtZW1jcHkoYnVmZmVyXywga1ZhcmludEVycm9yQ2FzZXNfY2FzZS5ieXRlcywga1ZhcmludEVycm9yQ2FzZXNfY2FzZS5zaXplKTsKKyAgQXJyYXlJbnB1dFN0cmVhbSBpbnB1dChidWZmZXJfLCBrVmFyaW50RXJyb3JDYXNlc19jYXNlLnNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAga0Jsb2NrU2l6ZXNfY2FzZSk7CisgIENvZGVkSW5wdXRTdHJlYW0gY29kZWRfaW5wdXQoJmlucHV0KTsKKworICB1aW50NjQgdmFsdWU7CisgIEVYUEVDVF9FUShrVmFyaW50RXJyb3JDYXNlc19jYXNlLmNhbl9wYXJzZSwgY29kZWRfaW5wdXQuUmVhZFZhcmludDY0KCZ2YWx1ZSkpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBWYXJpbnRTaXplCisKK3N0cnVjdCBWYXJpbnRTaXplQ2FzZSB7CisgIHVpbnQ2NCB2YWx1ZTsKKyAgaW50IHNpemU7Cit9OworCitpbmxpbmUgc3RkOjpvc3RyZWFtJiBvcGVyYXRvcjw8KHN0ZDo6b3N0cmVhbSYgb3MsIGNvbnN0IFZhcmludFNpemVDYXNlJiBjKSB7CisgIHJldHVybiBvcyA8PCBjLnZhbHVlOworfQorCitWYXJpbnRTaXplQ2FzZSBrVmFyaW50U2l6ZUNhc2VzW10gPSB7CisgIHswdSwgMX0sCisgIHsxdSwgMX0sCisgIHsxMjd1LCAxfSwKKyAgezEyOHUsIDJ9LAorICB7NzU4OTIzdSwgM30sCisgIHs0MDAwMDAwMDAwdSwgNX0sCisgIHtVTEwoNDEyNTYyMDI1ODA3MTgzMzYpLCA4fSwKKyAge1VMTCgxMTk2NDM3ODMzMDk3ODczNTEzMSksIDEwfSwKK307CisKK1RFU1RfMUQoQ29kZWRTdHJlYW1UZXN0LCBWYXJpbnRTaXplMzIsIGtWYXJpbnRTaXplQ2FzZXMpIHsKKyAgaWYgKGtWYXJpbnRTaXplQ2FzZXNfY2FzZS52YWx1ZSA+IDB4ZmZmZmZmZmZ1KSB7CisgICAgLy8gU2tpcCA2NC1iaXQgdmFsdWVzLgorICAgIHJldHVybjsKKyAgfQorCisgIEVYUEVDVF9FUShrVmFyaW50U2l6ZUNhc2VzX2Nhc2Uuc2l6ZSwKKyAgICBDb2RlZE91dHB1dFN0cmVhbTo6VmFyaW50U2l6ZTMyKAorICAgICAgc3RhdGljX2Nhc3Q8dWludDMyPihrVmFyaW50U2l6ZUNhc2VzX2Nhc2UudmFsdWUpKSk7Cit9CisKK1RFU1RfMUQoQ29kZWRTdHJlYW1UZXN0LCBWYXJpbnRTaXplNjQsIGtWYXJpbnRTaXplQ2FzZXMpIHsKKyAgRVhQRUNUX0VRKGtWYXJpbnRTaXplQ2FzZXNfY2FzZS5zaXplLAorICAgIENvZGVkT3V0cHV0U3RyZWFtOjpWYXJpbnRTaXplNjQoa1ZhcmludFNpemVDYXNlc19jYXNlLnZhbHVlKSk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIEZpeGVkLXNpemUgaW50IHRlc3RzCisKK3N0cnVjdCBGaXhlZDMyQ2FzZSB7CisgIHVpbnQ4IGJ5dGVzW3NpemVvZih1aW50MzIpXTsgICAgICAgICAgLy8gRW5jb2RlZCBieXRlcy4KKyAgdWludDMyIHZhbHVlOyAgICAgICAgICAgICAgICAgICAgICAgICAvLyBQYXJzZWQgdmFsdWUuCit9OworCitzdHJ1Y3QgRml4ZWQ2NENhc2UgeworICB1aW50OCBieXRlc1tzaXplb2YodWludDY0KV07ICAgICAgICAgIC8vIEVuY29kZWQgYnl0ZXMuCisgIHVpbnQ2NCB2YWx1ZTsgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUGFyc2VkIHZhbHVlLgorfTsKKworaW5saW5lIHN0ZDo6b3N0cmVhbSYgb3BlcmF0b3I8PChzdGQ6Om9zdHJlYW0mIG9zLCBjb25zdCBGaXhlZDMyQ2FzZSYgYykgeworICByZXR1cm4gb3MgPDwgIjB4IiA8PCBzdGQ6OmhleCA8PCBjLnZhbHVlIDw8IHN0ZDo6ZGVjOworfQorCitpbmxpbmUgc3RkOjpvc3RyZWFtJiBvcGVyYXRvcjw8KHN0ZDo6b3N0cmVhbSYgb3MsIGNvbnN0IEZpeGVkNjRDYXNlJiBjKSB7CisgIHJldHVybiBvcyA8PCAiMHgiIDw8IHN0ZDo6aGV4IDw8IGMudmFsdWUgPDwgc3RkOjpkZWM7Cit9CisKK0ZpeGVkMzJDYXNlIGtGaXhlZDMyQ2FzZXNbXSA9IHsKKyAge3sweGVmLCAweGNkLCAweGFiLCAweDkwfSwgMHg5MGFiY2RlZnV9LAorICB7ezB4MTIsIDB4MzQsIDB4NTYsIDB4Nzh9LCAweDc4NTYzNDEydX0sCit9OworCitGaXhlZDY0Q2FzZSBrRml4ZWQ2NENhc2VzW10gPSB7CisgIHt7MHhlZiwgMHhjZCwgMHhhYiwgMHg5MCwgMHgxMiwgMHgzNCwgMHg1NiwgMHg3OH0sIFVMTCgweDc4NTYzNDEyOTBhYmNkZWYpfSwKKyAge3sweDExLCAweDIyLCAweDMzLCAweDQ0LCAweDU1LCAweDY2LCAweDc3LCAweDg4fSwgVUxMKDB4ODg3NzY2NTU0NDMzMjIxMSl9LAorfTsKKworVEVTVF8yRChDb2RlZFN0cmVhbVRlc3QsIFJlYWRMaXR0bGVFbmRpYW4zMiwga0ZpeGVkMzJDYXNlcywga0Jsb2NrU2l6ZXMpIHsKKyAgbWVtY3B5KGJ1ZmZlcl8sIGtGaXhlZDMyQ2FzZXNfY2FzZS5ieXRlcywgc2l6ZW9mKGtGaXhlZDMyQ2FzZXNfY2FzZS5ieXRlcykpOworICBBcnJheUlucHV0U3RyZWFtIGlucHV0KGJ1ZmZlcl8sIHNpemVvZihidWZmZXJfKSwga0Jsb2NrU2l6ZXNfY2FzZSk7CisKKyAgeworICAgIENvZGVkSW5wdXRTdHJlYW0gY29kZWRfaW5wdXQoJmlucHV0KTsKKworICAgIHVpbnQzMiB2YWx1ZTsKKyAgICBFWFBFQ1RfVFJVRShjb2RlZF9pbnB1dC5SZWFkTGl0dGxlRW5kaWFuMzIoJnZhbHVlKSk7CisgICAgRVhQRUNUX0VRKGtGaXhlZDMyQ2FzZXNfY2FzZS52YWx1ZSwgdmFsdWUpOworICB9CisKKyAgRVhQRUNUX0VRKHNpemVvZih1aW50MzIpLCBpbnB1dC5CeXRlQ291bnQoKSk7Cit9CisKK1RFU1RfMkQoQ29kZWRTdHJlYW1UZXN0LCBSZWFkTGl0dGxlRW5kaWFuNjQsIGtGaXhlZDY0Q2FzZXMsIGtCbG9ja1NpemVzKSB7CisgIG1lbWNweShidWZmZXJfLCBrRml4ZWQ2NENhc2VzX2Nhc2UuYnl0ZXMsIHNpemVvZihrRml4ZWQ2NENhc2VzX2Nhc2UuYnl0ZXMpKTsKKyAgQXJyYXlJbnB1dFN0cmVhbSBpbnB1dChidWZmZXJfLCBzaXplb2YoYnVmZmVyXyksIGtCbG9ja1NpemVzX2Nhc2UpOworCisgIHsKKyAgICBDb2RlZElucHV0U3RyZWFtIGNvZGVkX2lucHV0KCZpbnB1dCk7CisKKyAgICB1aW50NjQgdmFsdWU7CisgICAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuUmVhZExpdHRsZUVuZGlhbjY0KCZ2YWx1ZSkpOworICAgIEVYUEVDVF9FUShrRml4ZWQ2NENhc2VzX2Nhc2UudmFsdWUsIHZhbHVlKTsKKyAgfQorCisgIEVYUEVDVF9FUShzaXplb2YodWludDY0KSwgaW5wdXQuQnl0ZUNvdW50KCkpOworfQorCitURVNUXzJEKENvZGVkU3RyZWFtVGVzdCwgV3JpdGVMaXR0bGVFbmRpYW4zMiwga0ZpeGVkMzJDYXNlcywga0Jsb2NrU2l6ZXMpIHsKKyAgQXJyYXlPdXRwdXRTdHJlYW0gb3V0cHV0KGJ1ZmZlcl8sIHNpemVvZihidWZmZXJfKSwga0Jsb2NrU2l6ZXNfY2FzZSk7CisKKyAgeworICAgIENvZGVkT3V0cHV0U3RyZWFtIGNvZGVkX291dHB1dCgmb3V0cHV0KTsKKworICAgIGNvZGVkX291dHB1dC5Xcml0ZUxpdHRsZUVuZGlhbjMyKGtGaXhlZDMyQ2FzZXNfY2FzZS52YWx1ZSk7CisgICAgRVhQRUNUX0ZBTFNFKGNvZGVkX291dHB1dC5IYWRFcnJvcigpKTsKKworICAgIEVYUEVDVF9FUShzaXplb2YodWludDMyKSwgY29kZWRfb3V0cHV0LkJ5dGVDb3VudCgpKTsKKyAgfQorCisgIEVYUEVDVF9FUShzaXplb2YodWludDMyKSwgb3V0cHV0LkJ5dGVDb3VudCgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lbWNtcChidWZmZXJfLCBrRml4ZWQzMkNhc2VzX2Nhc2UuYnl0ZXMsIHNpemVvZih1aW50MzIpKSk7Cit9CisKK1RFU1RfMkQoQ29kZWRTdHJlYW1UZXN0LCBXcml0ZUxpdHRsZUVuZGlhbjY0LCBrRml4ZWQ2NENhc2VzLCBrQmxvY2tTaXplcykgeworICBBcnJheU91dHB1dFN0cmVhbSBvdXRwdXQoYnVmZmVyXywgc2l6ZW9mKGJ1ZmZlcl8pLCBrQmxvY2tTaXplc19jYXNlKTsKKworICB7CisgICAgQ29kZWRPdXRwdXRTdHJlYW0gY29kZWRfb3V0cHV0KCZvdXRwdXQpOworCisgICAgY29kZWRfb3V0cHV0LldyaXRlTGl0dGxlRW5kaWFuNjQoa0ZpeGVkNjRDYXNlc19jYXNlLnZhbHVlKTsKKyAgICBFWFBFQ1RfRkFMU0UoY29kZWRfb3V0cHV0LkhhZEVycm9yKCkpOworCisgICAgRVhQRUNUX0VRKHNpemVvZih1aW50NjQpLCBjb2RlZF9vdXRwdXQuQnl0ZUNvdW50KCkpOworICB9CisKKyAgRVhQRUNUX0VRKHNpemVvZih1aW50NjQpLCBvdXRwdXQuQnl0ZUNvdW50KCkpOworICBFWFBFQ1RfRVEoMCwgbWVtY21wKGJ1ZmZlcl8sIGtGaXhlZDY0Q2FzZXNfY2FzZS5ieXRlcywgc2l6ZW9mKHVpbnQ2NCkpKTsKK30KKworLy8gVGVzdHMgdXNpbmcgdGhlIHN0YXRpYyBtZXRob2RzIHRvIHJlYWQgZml4ZWQtc2l6ZSB2YWx1ZXMgZnJvbSByYXcgYXJyYXlzLgorCitURVNUXzFEKENvZGVkU3RyZWFtVGVzdCwgUmVhZExpdHRsZUVuZGlhbjMyRnJvbUFycmF5LCBrRml4ZWQzMkNhc2VzKSB7CisgIG1lbWNweShidWZmZXJfLCBrRml4ZWQzMkNhc2VzX2Nhc2UuYnl0ZXMsIHNpemVvZihrRml4ZWQzMkNhc2VzX2Nhc2UuYnl0ZXMpKTsKKworICB1aW50MzIgdmFsdWU7CisgIGNvbnN0IHVpbnQ4KiBlbmQgPSBDb2RlZElucHV0U3RyZWFtOjpSZWFkTGl0dGxlRW5kaWFuMzJGcm9tQXJyYXkoCisgICAgICBidWZmZXJfLCAmdmFsdWUpOworICBFWFBFQ1RfRVEoa0ZpeGVkMzJDYXNlc19jYXNlLnZhbHVlLCB2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGVuZCA9PSBidWZmZXJfICsgc2l6ZW9mKHZhbHVlKSk7Cit9CisKK1RFU1RfMUQoQ29kZWRTdHJlYW1UZXN0LCBSZWFkTGl0dGxlRW5kaWFuNjRGcm9tQXJyYXksIGtGaXhlZDY0Q2FzZXMpIHsKKyAgbWVtY3B5KGJ1ZmZlcl8sIGtGaXhlZDY0Q2FzZXNfY2FzZS5ieXRlcywgc2l6ZW9mKGtGaXhlZDY0Q2FzZXNfY2FzZS5ieXRlcykpOworCisgIHVpbnQ2NCB2YWx1ZTsKKyAgY29uc3QgdWludDgqIGVuZCA9IENvZGVkSW5wdXRTdHJlYW06OlJlYWRMaXR0bGVFbmRpYW42NEZyb21BcnJheSgKKyAgICAgIGJ1ZmZlcl8sICZ2YWx1ZSk7CisgIEVYUEVDVF9FUShrRml4ZWQ2NENhc2VzX2Nhc2UudmFsdWUsIHZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoZW5kID09IGJ1ZmZlcl8gKyBzaXplb2YodmFsdWUpKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gUmF3IHJlYWRzIGFuZCB3cml0ZXMKKworY29uc3QgY2hhciBrUmF3Qnl0ZXNbXSA9ICJTb21lIGJ5dGVzIHdoaWNoIHdpbGwgYmUgd3JpdHRlbiBhbmQgcmVhZCByYXcuIjsKKworVEVTVF8xRChDb2RlZFN0cmVhbVRlc3QsIFJlYWRSYXcsIGtCbG9ja1NpemVzKSB7CisgIG1lbWNweShidWZmZXJfLCBrUmF3Qnl0ZXMsIHNpemVvZihrUmF3Qnl0ZXMpKTsKKyAgQXJyYXlJbnB1dFN0cmVhbSBpbnB1dChidWZmZXJfLCBzaXplb2YoYnVmZmVyXyksIGtCbG9ja1NpemVzX2Nhc2UpOworICBjaGFyIHJlYWRfYnVmZmVyW3NpemVvZihrUmF3Qnl0ZXMpXTsKKworICB7CisgICAgQ29kZWRJbnB1dFN0cmVhbSBjb2RlZF9pbnB1dCgmaW5wdXQpOworCisgICAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuUmVhZFJhdyhyZWFkX2J1ZmZlciwgc2l6ZW9mKGtSYXdCeXRlcykpKTsKKyAgICBFWFBFQ1RfRVEoMCwgbWVtY21wKGtSYXdCeXRlcywgcmVhZF9idWZmZXIsIHNpemVvZihrUmF3Qnl0ZXMpKSk7CisgIH0KKworICBFWFBFQ1RfRVEoc2l6ZW9mKGtSYXdCeXRlcyksIGlucHV0LkJ5dGVDb3VudCgpKTsKK30KKworVEVTVF8xRChDb2RlZFN0cmVhbVRlc3QsIFdyaXRlUmF3LCBrQmxvY2tTaXplcykgeworICBBcnJheU91dHB1dFN0cmVhbSBvdXRwdXQoYnVmZmVyXywgc2l6ZW9mKGJ1ZmZlcl8pLCBrQmxvY2tTaXplc19jYXNlKTsKKworICB7CisgICAgQ29kZWRPdXRwdXRTdHJlYW0gY29kZWRfb3V0cHV0KCZvdXRwdXQpOworCisgICAgY29kZWRfb3V0cHV0LldyaXRlUmF3KGtSYXdCeXRlcywgc2l6ZW9mKGtSYXdCeXRlcykpOworICAgIEVYUEVDVF9GQUxTRShjb2RlZF9vdXRwdXQuSGFkRXJyb3IoKSk7CisKKyAgICBFWFBFQ1RfRVEoc2l6ZW9mKGtSYXdCeXRlcyksIGNvZGVkX291dHB1dC5CeXRlQ291bnQoKSk7CisgIH0KKworICBFWFBFQ1RfRVEoc2l6ZW9mKGtSYXdCeXRlcyksIG91dHB1dC5CeXRlQ291bnQoKSk7CisgIEVYUEVDVF9FUSgwLCBtZW1jbXAoYnVmZmVyXywga1Jhd0J5dGVzLCBzaXplb2Yoa1Jhd0J5dGVzKSkpOworfQorCitURVNUXzFEKENvZGVkU3RyZWFtVGVzdCwgUmVhZFN0cmluZywga0Jsb2NrU2l6ZXMpIHsKKyAgbWVtY3B5KGJ1ZmZlcl8sIGtSYXdCeXRlcywgc2l6ZW9mKGtSYXdCeXRlcykpOworICBBcnJheUlucHV0U3RyZWFtIGlucHV0KGJ1ZmZlcl8sIHNpemVvZihidWZmZXJfKSwga0Jsb2NrU2l6ZXNfY2FzZSk7CisKKyAgeworICAgIENvZGVkSW5wdXRTdHJlYW0gY29kZWRfaW5wdXQoJmlucHV0KTsKKworICAgIHN0cmluZyBzdHI7CisgICAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuUmVhZFN0cmluZygmc3RyLCBzdHJsZW4oa1Jhd0J5dGVzKSkpOworICAgIEVYUEVDVF9FUShrUmF3Qnl0ZXMsIHN0cik7CisgIH0KKworICBFWFBFQ1RfRVEoc3RybGVuKGtSYXdCeXRlcyksIGlucHV0LkJ5dGVDb3VudCgpKTsKK30KKworLy8gQ2hlY2sgdG8gbWFrZSBzdXJlIFJlYWRTdHJpbmcgZG9lc24ndCBjcmFzaCBvbiBpbXBvc3NpYmx5IGxhcmdlIHN0cmluZ3MuCitURVNUXzFEKENvZGVkU3RyZWFtVGVzdCwgUmVhZFN0cmluZ0ltcG9zc2libHlMYXJnZSwga0Jsb2NrU2l6ZXMpIHsKKyAgQXJyYXlJbnB1dFN0cmVhbSBpbnB1dChidWZmZXJfLCBzaXplb2YoYnVmZmVyXyksIGtCbG9ja1NpemVzX2Nhc2UpOworCisgIHsKKyAgICBDb2RlZElucHV0U3RyZWFtIGNvZGVkX2lucHV0KCZpbnB1dCk7CisKKyAgICBzdHJpbmcgc3RyOworICAgIC8vIFRyeSB0byByZWFkIGEgZ2lnYWJ5dGUuCisgICAgRVhQRUNUX0ZBTFNFKGNvZGVkX2lucHV0LlJlYWRTdHJpbmcoJnN0ciwgMSA8PCAzMCkpOworICB9Cit9CisKK1RFU1RfRihDb2RlZFN0cmVhbVRlc3QsIFJlYWRTdHJpbmdJbXBvc3NpYmx5TGFyZ2VGcm9tU3RyaW5nT25TdGFjaykgeworICAvLyBTYW1lIHRlc3QgYXMgYWJvdmUsIGV4Y2VwdCBkaXJlY3RseSB1c2UgYSBidWZmZXIuIFRoaXMgdXNlZCB0byBjYXVzZQorICAvLyBjcmFzaGVzIHdoaWxlIHRoZSBhYm92ZSBkaWQgbm90LgorICB1aW50OCBidWZmZXJbOF07CisgIENvZGVkSW5wdXRTdHJlYW0gY29kZWRfaW5wdXQoYnVmZmVyLCA4KTsKKyAgc3RyaW5nIHN0cjsKKyAgRVhQRUNUX0ZBTFNFKGNvZGVkX2lucHV0LlJlYWRTdHJpbmcoJnN0ciwgMSA8PCAzMCkpOworfQorCitURVNUX0YoQ29kZWRTdHJlYW1UZXN0LCBSZWFkU3RyaW5nSW1wb3NzaWJseUxhcmdlRnJvbVN0cmluZ09uSGVhcCkgeworICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfYXJyYXk8dWludDg+IGJ1ZmZlcihuZXcgdWludDhbOF0pOworICBDb2RlZElucHV0U3RyZWFtIGNvZGVkX2lucHV0KGJ1ZmZlci5nZXQoKSwgOCk7CisgIHN0cmluZyBzdHI7CisgIEVYUEVDVF9GQUxTRShjb2RlZF9pbnB1dC5SZWFkU3RyaW5nKCZzdHIsIDEgPDwgMzApKTsKK30KKworVEVTVF8xRChDb2RlZFN0cmVhbVRlc3QsIFJlYWRTdHJpbmdSZXNlcnZlc01lbW9yeU9uVG90YWxMaW1pdCwga0Jsb2NrU2l6ZXMpIHsKKyAgbWVtY3B5KGJ1ZmZlcl8sIGtSYXdCeXRlcywgc2l6ZW9mKGtSYXdCeXRlcykpOworICBBcnJheUlucHV0U3RyZWFtIGlucHV0KGJ1ZmZlcl8sIHNpemVvZihidWZmZXJfKSwga0Jsb2NrU2l6ZXNfY2FzZSk7CisKKyAgeworICAgIENvZGVkSW5wdXRTdHJlYW0gY29kZWRfaW5wdXQoJmlucHV0KTsKKyAgICBjb2RlZF9pbnB1dC5TZXRUb3RhbEJ5dGVzTGltaXQoc2l6ZW9mKGtSYXdCeXRlcyksIHNpemVvZihrUmF3Qnl0ZXMpKTsKKyAgICBFWFBFQ1RfRVEoc2l6ZW9mKGtSYXdCeXRlcyksIGNvZGVkX2lucHV0LkJ5dGVzVW50aWxUb3RhbEJ5dGVzTGltaXQoKSk7CisKKyAgICBzdHJpbmcgc3RyOworICAgIEVYUEVDVF9UUlVFKGNvZGVkX2lucHV0LlJlYWRTdHJpbmcoJnN0ciwgc3RybGVuKGtSYXdCeXRlcykpKTsKKyAgICBFWFBFQ1RfRVEoc2l6ZW9mKGtSYXdCeXRlcykgLSBzdHJsZW4oa1Jhd0J5dGVzKSwKKyAgICAgICAgICAgICAgY29kZWRfaW5wdXQuQnl0ZXNVbnRpbFRvdGFsQnl0ZXNMaW1pdCgpKTsKKyAgICBFWFBFQ1RfRVEoa1Jhd0J5dGVzLCBzdHIpOworICAgIC8vIFRPRE8obGl1amlzaSk6IFJlcGxhY2Ugd2l0aCBhIG1vcmUgbWVhbmluZ2Z1bCB0ZXN0IChzZWUgY2wvNjA5NjYwMjMpLgorICAgIEVYUEVDVF9HRShzdHIuY2FwYWNpdHkoKSwgc3RybGVuKGtSYXdCeXRlcykpOworICB9CisKKyAgRVhQRUNUX0VRKHN0cmxlbihrUmF3Qnl0ZXMpLCBpbnB1dC5CeXRlQ291bnQoKSk7Cit9CisKK1RFU1RfMUQoQ29kZWRTdHJlYW1UZXN0LCBSZWFkU3RyaW5nUmVzZXJ2ZXNNZW1vcnlPblB1c2hlZExpbWl0LCBrQmxvY2tTaXplcykgeworICBtZW1jcHkoYnVmZmVyXywga1Jhd0J5dGVzLCBzaXplb2Yoa1Jhd0J5dGVzKSk7CisgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQoYnVmZmVyXywgc2l6ZW9mKGJ1ZmZlcl8pLCBrQmxvY2tTaXplc19jYXNlKTsKKworICB7CisgICAgQ29kZWRJbnB1dFN0cmVhbSBjb2RlZF9pbnB1dCgmaW5wdXQpOworICAgIGNvZGVkX2lucHV0LlB1c2hMaW1pdChzaXplb2YoYnVmZmVyXykpOworCisgICAgc3RyaW5nIHN0cjsKKyAgICBFWFBFQ1RfVFJVRShjb2RlZF9pbnB1dC5SZWFkU3RyaW5nKCZzdHIsIHN0cmxlbihrUmF3Qnl0ZXMpKSk7CisgICAgRVhQRUNUX0VRKGtSYXdCeXRlcywgc3RyKTsKKyAgICAvLyBUT0RPKGxpdWppc2kpOiBSZXBsYWNlIHdpdGggYSBtb3JlIG1lYW5pbmdmdWwgdGVzdCAoc2VlIGNsLzYwOTY2MDIzKS4KKyAgICBFWFBFQ1RfR0Uoc3RyLmNhcGFjaXR5KCksIHN0cmxlbihrUmF3Qnl0ZXMpKTsKKyAgfQorCisgIEVYUEVDVF9FUShzdHJsZW4oa1Jhd0J5dGVzKSwgaW5wdXQuQnl0ZUNvdW50KCkpOworfQorCitURVNUX0YoQ29kZWRTdHJlYW1UZXN0LCBSZWFkU3RyaW5nTm9SZXNlcnZhdGlvbklmTGltaXRzTm90U2V0KSB7CisgIG1lbWNweShidWZmZXJfLCBrUmF3Qnl0ZXMsIHNpemVvZihrUmF3Qnl0ZXMpKTsKKyAgLy8gQnVmZmVyIHNpemUgaW4gdGhlIGlucHV0IG11c3QgYmUgc21hbGxlciB0aGFuIHNpemVvZihrUmF3Qnl0ZXMpLAorICAvLyBvdGhlcndpc2UgY2hlY2sgYWdhaW5zdCBjYXBhY2l0eSB3aWxsIGZhaWwgYXMgUmVhZFN0cmluZ0lubGluZSgpCisgIC8vIHdpbGwgaGFuZGxlIHRoZSByZWFkaW5nIGFuZCB3aWxsIHJlc2VydmUgdGhlIG1lbW9yeSBhcyBuZWVkZWQuCisgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQoYnVmZmVyXywgc2l6ZW9mKGJ1ZmZlcl8pLCAzMik7CisKKyAgeworICAgIENvZGVkSW5wdXRTdHJlYW0gY29kZWRfaW5wdXQoJmlucHV0KTsKKworICAgIHN0cmluZyBzdHI7CisgICAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuUmVhZFN0cmluZygmc3RyLCBzdHJsZW4oa1Jhd0J5dGVzKSkpOworICAgIEVYUEVDVF9FUShrUmF3Qnl0ZXMsIHN0cik7CisgICAgLy8gTm90ZTogdGhpcyBjaGVjayBkZXBlbmRzIG9uIHN0cmluZyBjbGFzcyBpbXBsZW1lbnRhdGlvbi4gSXQKKyAgICAvLyBleHBlY3RzIHRoYXQgc3RyaW5nIHdpbGwgYWxsb2NhdGUgbW9yZSB0aGFuIHN0cmxlbihrUmF3Qnl0ZXMpCisgICAgLy8gaWYgdGhlIGNvbnRlbnQgb2Yga1Jhd0J5dGVzIGlzIGFwcGVuZGVkIHRvIHN0cmluZyBpbiBzbWFsbAorICAgIC8vIGNodW5rcy4KKyAgICAvLyBUT0RPKGxpdWppc2kpOiBSZXBsYWNlIHdpdGggYSBtb3JlIG1lYW5pbmdmdWwgdGVzdCAoc2VlIGNsLzYwOTY2MDIzKS4KKyAgICBFWFBFQ1RfR0Uoc3RyLmNhcGFjaXR5KCksIHN0cmxlbihrUmF3Qnl0ZXMpKTsKKyAgfQorCisgIEVYUEVDVF9FUShzdHJsZW4oa1Jhd0J5dGVzKSwgaW5wdXQuQnl0ZUNvdW50KCkpOworfQorCitURVNUX0YoQ29kZWRTdHJlYW1UZXN0LCBSZWFkU3RyaW5nTm9SZXNlcnZhdGlvblNpemVJc05lZ2F0aXZlKSB7CisgIG1lbWNweShidWZmZXJfLCBrUmF3Qnl0ZXMsIHNpemVvZihrUmF3Qnl0ZXMpKTsKKyAgLy8gQnVmZmVyIHNpemUgaW4gdGhlIGlucHV0IG11c3QgYmUgc21hbGxlciB0aGFuIHNpemVvZihrUmF3Qnl0ZXMpLAorICAvLyBvdGhlcndpc2UgY2hlY2sgYWdhaW5zdCBjYXBhY2l0eSB3aWxsIGZhaWwgYXMgUmVhZFN0cmluZ0lubGluZSgpCisgIC8vIHdpbGwgaGFuZGxlIHRoZSByZWFkaW5nIGFuZCB3aWxsIHJlc2VydmUgdGhlIG1lbW9yeSBhcyBuZWVkZWQuCisgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQoYnVmZmVyXywgc2l6ZW9mKGJ1ZmZlcl8pLCAzMik7CisKKyAgeworICAgIENvZGVkSW5wdXRTdHJlYW0gY29kZWRfaW5wdXQoJmlucHV0KTsKKyAgICBjb2RlZF9pbnB1dC5QdXNoTGltaXQoc2l6ZW9mKGJ1ZmZlcl8pKTsKKworICAgIHN0cmluZyBzdHI7CisgICAgRVhQRUNUX0ZBTFNFKGNvZGVkX2lucHV0LlJlYWRTdHJpbmcoJnN0ciwgLTEpKTsKKyAgICAvLyBOb3RlOiB0aGlzIGNoZWNrIGRlcGVuZHMgb24gc3RyaW5nIGNsYXNzIGltcGxlbWVudGF0aW9uLiBJdAorICAgIC8vIGV4cGVjdHMgdGhhdCBzdHJpbmcgd2lsbCBhbHdheXMgYWxsb2NhdGUgdGhlIHNhbWUgYW1vdW50IG9mCisgICAgLy8gbWVtb3J5IGZvciBhbiBlbXB0eSBzdHJpbmcuCisgICAgRVhQRUNUX0VRKHN0cmluZygpLmNhcGFjaXR5KCksIHN0ci5jYXBhY2l0eSgpKTsKKyAgfQorfQorCitURVNUX0YoQ29kZWRTdHJlYW1UZXN0LCBSZWFkU3RyaW5nTm9SZXNlcnZhdGlvblNpemVJc0xhcmdlKSB7CisgIG1lbWNweShidWZmZXJfLCBrUmF3Qnl0ZXMsIHNpemVvZihrUmF3Qnl0ZXMpKTsKKyAgLy8gQnVmZmVyIHNpemUgaW4gdGhlIGlucHV0IG11c3QgYmUgc21hbGxlciB0aGFuIHNpemVvZihrUmF3Qnl0ZXMpLAorICAvLyBvdGhlcndpc2UgY2hlY2sgYWdhaW5zdCBjYXBhY2l0eSB3aWxsIGZhaWwgYXMgUmVhZFN0cmluZ0lubGluZSgpCisgIC8vIHdpbGwgaGFuZGxlIHRoZSByZWFkaW5nIGFuZCB3aWxsIHJlc2VydmUgdGhlIG1lbW9yeSBhcyBuZWVkZWQuCisgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQoYnVmZmVyXywgc2l6ZW9mKGJ1ZmZlcl8pLCAzMik7CisKKyAgeworICAgIENvZGVkSW5wdXRTdHJlYW0gY29kZWRfaW5wdXQoJmlucHV0KTsKKyAgICBjb2RlZF9pbnB1dC5QdXNoTGltaXQoc2l6ZW9mKGJ1ZmZlcl8pKTsKKworICAgIHN0cmluZyBzdHI7CisgICAgRVhQRUNUX0ZBTFNFKGNvZGVkX2lucHV0LlJlYWRTdHJpbmcoJnN0ciwgMSA8PCAzMCkpOworICAgIEVYUEVDVF9HVCgxIDw8IDMwLCBzdHIuY2FwYWNpdHkoKSk7CisgIH0KK30KKworVEVTVF9GKENvZGVkU3RyZWFtVGVzdCwgUmVhZFN0cmluZ05vUmVzZXJ2YXRpb25TaXplSXNPdmVyVGhlTGltaXQpIHsKKyAgbWVtY3B5KGJ1ZmZlcl8sIGtSYXdCeXRlcywgc2l6ZW9mKGtSYXdCeXRlcykpOworICAvLyBCdWZmZXIgc2l6ZSBpbiB0aGUgaW5wdXQgbXVzdCBiZSBzbWFsbGVyIHRoYW4gc2l6ZW9mKGtSYXdCeXRlcyksCisgIC8vIG90aGVyd2lzZSBjaGVjayBhZ2FpbnN0IGNhcGFjaXR5IHdpbGwgZmFpbCBhcyBSZWFkU3RyaW5nSW5saW5lKCkKKyAgLy8gd2lsbCBoYW5kbGUgdGhlIHJlYWRpbmcgYW5kIHdpbGwgcmVzZXJ2ZSB0aGUgbWVtb3J5IGFzIG5lZWRlZC4KKyAgQXJyYXlJbnB1dFN0cmVhbSBpbnB1dChidWZmZXJfLCBzaXplb2YoYnVmZmVyXyksIDMyKTsKKworICB7CisgICAgQ29kZWRJbnB1dFN0cmVhbSBjb2RlZF9pbnB1dCgmaW5wdXQpOworICAgIGNvZGVkX2lucHV0LlB1c2hMaW1pdCgxNik7CisKKyAgICBzdHJpbmcgc3RyOworICAgIEVYUEVDVF9GQUxTRShjb2RlZF9pbnB1dC5SZWFkU3RyaW5nKCZzdHIsIHN0cmxlbihrUmF3Qnl0ZXMpKSk7CisgICAgLy8gTm90ZTogdGhpcyBjaGVjayBkZXBlbmRzIG9uIHN0cmluZyBjbGFzcyBpbXBsZW1lbnRhdGlvbi4gSXQKKyAgICAvLyBleHBlY3RzIHRoYXQgc3RyaW5nIHdpbGwgYWxsb2NhdGUgbGVzcyB0aGFuIHN0cmxlbihrUmF3Qnl0ZXMpCisgICAgLy8gZm9yIGFuIGVtcHR5IHN0cmluZy4KKyAgICBFWFBFQ1RfR1Qoc3RybGVuKGtSYXdCeXRlcyksIHN0ci5jYXBhY2l0eSgpKTsKKyAgfQorfQorCitURVNUX0YoQ29kZWRTdHJlYW1UZXN0LCBSZWFkU3RyaW5nTm9SZXNlcnZhdGlvblNpemVJc092ZXJUaGVUb3RhbEJ5dGVzTGltaXQpIHsKKyAgbWVtY3B5KGJ1ZmZlcl8sIGtSYXdCeXRlcywgc2l6ZW9mKGtSYXdCeXRlcykpOworICAvLyBCdWZmZXIgc2l6ZSBpbiB0aGUgaW5wdXQgbXVzdCBiZSBzbWFsbGVyIHRoYW4gc2l6ZW9mKGtSYXdCeXRlcyksCisgIC8vIG90aGVyd2lzZSBjaGVjayBhZ2FpbnN0IGNhcGFjaXR5IHdpbGwgZmFpbCBhcyBSZWFkU3RyaW5nSW5saW5lKCkKKyAgLy8gd2lsbCBoYW5kbGUgdGhlIHJlYWRpbmcgYW5kIHdpbGwgcmVzZXJ2ZSB0aGUgbWVtb3J5IGFzIG5lZWRlZC4KKyAgQXJyYXlJbnB1dFN0cmVhbSBpbnB1dChidWZmZXJfLCBzaXplb2YoYnVmZmVyXyksIDMyKTsKKworICB7CisgICAgQ29kZWRJbnB1dFN0cmVhbSBjb2RlZF9pbnB1dCgmaW5wdXQpOworICAgIGNvZGVkX2lucHV0LlNldFRvdGFsQnl0ZXNMaW1pdCgxNiwgMTYpOworCisgICAgc3RyaW5nIHN0cjsKKyAgICBFWFBFQ1RfRkFMU0UoY29kZWRfaW5wdXQuUmVhZFN0cmluZygmc3RyLCBzdHJsZW4oa1Jhd0J5dGVzKSkpOworICAgIC8vIE5vdGU6IHRoaXMgY2hlY2sgZGVwZW5kcyBvbiBzdHJpbmcgY2xhc3MgaW1wbGVtZW50YXRpb24uIEl0CisgICAgLy8gZXhwZWN0cyB0aGF0IHN0cmluZyB3aWxsIGFsbG9jYXRlIGxlc3MgdGhhbiBzdHJsZW4oa1Jhd0J5dGVzKQorICAgIC8vIGZvciBhbiBlbXB0eSBzdHJpbmcuCisgICAgRVhQRUNUX0dUKHN0cmxlbihrUmF3Qnl0ZXMpLCBzdHIuY2FwYWNpdHkoKSk7CisgIH0KK30KKworVEVTVF9GKENvZGVkU3RyZWFtVGVzdCwKKyAgICAgICBSZWFkU3RyaW5nTm9SZXNlcnZhdGlvblNpemVJc092ZXJUaGVDbG9zZXN0TGltaXRfR2xvYmFsTGltaXRJc0Nsb3NlcikgeworICBtZW1jcHkoYnVmZmVyXywga1Jhd0J5dGVzLCBzaXplb2Yoa1Jhd0J5dGVzKSk7CisgIC8vIEJ1ZmZlciBzaXplIGluIHRoZSBpbnB1dCBtdXN0IGJlIHNtYWxsZXIgdGhhbiBzaXplb2Yoa1Jhd0J5dGVzKSwKKyAgLy8gb3RoZXJ3aXNlIGNoZWNrIGFnYWluc3QgY2FwYWNpdHkgd2lsbCBmYWlsIGFzIFJlYWRTdHJpbmdJbmxpbmUoKQorICAvLyB3aWxsIGhhbmRsZSB0aGUgcmVhZGluZyBhbmQgd2lsbCByZXNlcnZlIHRoZSBtZW1vcnkgYXMgbmVlZGVkLgorICBBcnJheUlucHV0U3RyZWFtIGlucHV0KGJ1ZmZlcl8sIHNpemVvZihidWZmZXJfKSwgMzIpOworCisgIHsKKyAgICBDb2RlZElucHV0U3RyZWFtIGNvZGVkX2lucHV0KCZpbnB1dCk7CisgICAgY29kZWRfaW5wdXQuUHVzaExpbWl0KHNpemVvZihidWZmZXJfKSk7CisgICAgY29kZWRfaW5wdXQuU2V0VG90YWxCeXRlc0xpbWl0KDE2LCAxNik7CisKKyAgICBzdHJpbmcgc3RyOworICAgIEVYUEVDVF9GQUxTRShjb2RlZF9pbnB1dC5SZWFkU3RyaW5nKCZzdHIsIHN0cmxlbihrUmF3Qnl0ZXMpKSk7CisgICAgLy8gTm90ZTogdGhpcyBjaGVjayBkZXBlbmRzIG9uIHN0cmluZyBjbGFzcyBpbXBsZW1lbnRhdGlvbi4gSXQKKyAgICAvLyBleHBlY3RzIHRoYXQgc3RyaW5nIHdpbGwgYWxsb2NhdGUgbGVzcyB0aGFuIHN0cmxlbihrUmF3Qnl0ZXMpCisgICAgLy8gZm9yIGFuIGVtcHR5IHN0cmluZy4KKyAgICBFWFBFQ1RfR1Qoc3RybGVuKGtSYXdCeXRlcyksIHN0ci5jYXBhY2l0eSgpKTsKKyAgfQorfQorCitURVNUX0YoQ29kZWRTdHJlYW1UZXN0LAorICAgICAgIFJlYWRTdHJpbmdOb1Jlc2VydmF0aW9uU2l6ZUlzT3ZlclRoZUNsb3Nlc3RMaW1pdF9Mb2NhbExpbWl0SXNDbG9zZXIpIHsKKyAgbWVtY3B5KGJ1ZmZlcl8sIGtSYXdCeXRlcywgc2l6ZW9mKGtSYXdCeXRlcykpOworICAvLyBCdWZmZXIgc2l6ZSBpbiB0aGUgaW5wdXQgbXVzdCBiZSBzbWFsbGVyIHRoYW4gc2l6ZW9mKGtSYXdCeXRlcyksCisgIC8vIG90aGVyd2lzZSBjaGVjayBhZ2FpbnN0IGNhcGFjaXR5IHdpbGwgZmFpbCBhcyBSZWFkU3RyaW5nSW5saW5lKCkKKyAgLy8gd2lsbCBoYW5kbGUgdGhlIHJlYWRpbmcgYW5kIHdpbGwgcmVzZXJ2ZSB0aGUgbWVtb3J5IGFzIG5lZWRlZC4KKyAgQXJyYXlJbnB1dFN0cmVhbSBpbnB1dChidWZmZXJfLCBzaXplb2YoYnVmZmVyXyksIDMyKTsKKworICB7CisgICAgQ29kZWRJbnB1dFN0cmVhbSBjb2RlZF9pbnB1dCgmaW5wdXQpOworICAgIGNvZGVkX2lucHV0LlB1c2hMaW1pdCgxNik7CisgICAgY29kZWRfaW5wdXQuU2V0VG90YWxCeXRlc0xpbWl0KHNpemVvZihidWZmZXJfKSwgc2l6ZW9mKGJ1ZmZlcl8pKTsKKyAgICBFWFBFQ1RfRVEoc2l6ZW9mKGJ1ZmZlcl8pLCBjb2RlZF9pbnB1dC5CeXRlc1VudGlsVG90YWxCeXRlc0xpbWl0KCkpOworCisgICAgc3RyaW5nIHN0cjsKKyAgICBFWFBFQ1RfRkFMU0UoY29kZWRfaW5wdXQuUmVhZFN0cmluZygmc3RyLCBzdHJsZW4oa1Jhd0J5dGVzKSkpOworICAgIC8vIE5vdGU6IHRoaXMgY2hlY2sgZGVwZW5kcyBvbiBzdHJpbmcgY2xhc3MgaW1wbGVtZW50YXRpb24uIEl0CisgICAgLy8gZXhwZWN0cyB0aGF0IHN0cmluZyB3aWxsIGFsbG9jYXRlIGxlc3MgdGhhbiBzdHJsZW4oa1Jhd0J5dGVzKQorICAgIC8vIGZvciBhbiBlbXB0eSBzdHJpbmcuCisgICAgRVhQRUNUX0dUKHN0cmxlbihrUmF3Qnl0ZXMpLCBzdHIuY2FwYWNpdHkoKSk7CisgIH0KK30KKworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBTa2lwCisKK2NvbnN0IGNoYXIga1NraXBUZXN0Qnl0ZXNbXSA9CisgICI8QmVmb3JlIHNraXBwaW5nPjxUbyBiZSBza2lwcGVkPjxBZnRlciBza2lwcGluZz4iOworCitURVNUXzFEKENvZGVkU3RyZWFtVGVzdCwgU2tpcElucHV0LCBrQmxvY2tTaXplcykgeworICBtZW1jcHkoYnVmZmVyXywga1NraXBUZXN0Qnl0ZXMsIHNpemVvZihrU2tpcFRlc3RCeXRlcykpOworICBBcnJheUlucHV0U3RyZWFtIGlucHV0KGJ1ZmZlcl8sIHNpemVvZihidWZmZXJfKSwga0Jsb2NrU2l6ZXNfY2FzZSk7CisKKyAgeworICAgIENvZGVkSW5wdXRTdHJlYW0gY29kZWRfaW5wdXQoJmlucHV0KTsKKworICAgIHN0cmluZyBzdHI7CisgICAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuUmVhZFN0cmluZygmc3RyLCBzdHJsZW4oIjxCZWZvcmUgc2tpcHBpbmc+IikpKTsKKyAgICBFWFBFQ1RfRVEoIjxCZWZvcmUgc2tpcHBpbmc+Iiwgc3RyKTsKKyAgICBFWFBFQ1RfVFJVRShjb2RlZF9pbnB1dC5Ta2lwKHN0cmxlbigiPFRvIGJlIHNraXBwZWQ+IikpKTsKKyAgICBFWFBFQ1RfVFJVRShjb2RlZF9pbnB1dC5SZWFkU3RyaW5nKCZzdHIsIHN0cmxlbigiPEFmdGVyIHNraXBwaW5nPiIpKSk7CisgICAgRVhQRUNUX0VRKCI8QWZ0ZXIgc2tpcHBpbmc+Iiwgc3RyKTsKKyAgfQorCisgIEVYUEVDVF9FUShzdHJsZW4oa1NraXBUZXN0Qnl0ZXMpLCBpbnB1dC5CeXRlQ291bnQoKSk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIEdldERpcmVjdEJ1ZmZlclBvaW50ZXIKKworVEVTVF9GKENvZGVkU3RyZWFtVGVzdCwgR2V0RGlyZWN0QnVmZmVyUG9pbnRlcklucHV0KSB7CisgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQoYnVmZmVyXywgc2l6ZW9mKGJ1ZmZlcl8pLCA4KTsKKyAgQ29kZWRJbnB1dFN0cmVhbSBjb2RlZF9pbnB1dCgmaW5wdXQpOworCisgIGNvbnN0IHZvaWQqIHB0cjsKKyAgaW50IHNpemU7CisKKyAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuR2V0RGlyZWN0QnVmZmVyUG9pbnRlcigmcHRyLCAmc2l6ZSkpOworICBFWFBFQ1RfRVEoYnVmZmVyXywgcHRyKTsKKyAgRVhQRUNUX0VRKDgsIHNpemUpOworCisgIC8vIFBlZWtpbmcgYWdhaW4gc2hvdWxkIHJldHVybiB0aGUgc2FtZSBwb2ludGVyLgorICBFWFBFQ1RfVFJVRShjb2RlZF9pbnB1dC5HZXREaXJlY3RCdWZmZXJQb2ludGVyKCZwdHIsICZzaXplKSk7CisgIEVYUEVDVF9FUShidWZmZXJfLCBwdHIpOworICBFWFBFQ1RfRVEoOCwgc2l6ZSk7CisKKyAgLy8gU2tpcCBmb3J3YXJkIGluIHRoZSBzYW1lIGJ1ZmZlciB0aGVuIHBlZWsgYWdhaW4uCisgIEVYUEVDVF9UUlVFKGNvZGVkX2lucHV0LlNraXAoMykpOworICBFWFBFQ1RfVFJVRShjb2RlZF9pbnB1dC5HZXREaXJlY3RCdWZmZXJQb2ludGVyKCZwdHIsICZzaXplKSk7CisgIEVYUEVDVF9FUShidWZmZXJfICsgMywgcHRyKTsKKyAgRVhQRUNUX0VRKDUsIHNpemUpOworCisgIC8vIFNraXAgdG8gZW5kIG9mIGJ1ZmZlciBhbmQgcGVlayAtLSBzaG91bGQgZ2V0IG5leHQgYnVmZmVyLgorICBFWFBFQ1RfVFJVRShjb2RlZF9pbnB1dC5Ta2lwKDUpKTsKKyAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuR2V0RGlyZWN0QnVmZmVyUG9pbnRlcigmcHRyLCAmc2l6ZSkpOworICBFWFBFQ1RfRVEoYnVmZmVyXyArIDgsIHB0cik7CisgIEVYUEVDVF9FUSg4LCBzaXplKTsKK30KKworVEVTVF9GKENvZGVkU3RyZWFtVGVzdCwgR2V0RGlyZWN0QnVmZmVyUG9pbnRlcklubGluZUlucHV0KSB7CisgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQoYnVmZmVyXywgc2l6ZW9mKGJ1ZmZlcl8pLCA4KTsKKyAgQ29kZWRJbnB1dFN0cmVhbSBjb2RlZF9pbnB1dCgmaW5wdXQpOworCisgIGNvbnN0IHZvaWQqIHB0cjsKKyAgaW50IHNpemU7CisKKyAgY29kZWRfaW5wdXQuR2V0RGlyZWN0QnVmZmVyUG9pbnRlcklubGluZSgmcHRyLCAmc2l6ZSk7CisgIEVYUEVDVF9FUShidWZmZXJfLCBwdHIpOworICBFWFBFQ1RfRVEoOCwgc2l6ZSk7CisKKyAgLy8gUGVla2luZyBhZ2FpbiBzaG91bGQgcmV0dXJuIHRoZSBzYW1lIHBvaW50ZXIuCisgIGNvZGVkX2lucHV0LkdldERpcmVjdEJ1ZmZlclBvaW50ZXJJbmxpbmUoJnB0ciwgJnNpemUpOworICBFWFBFQ1RfRVEoYnVmZmVyXywgcHRyKTsKKyAgRVhQRUNUX0VRKDgsIHNpemUpOworCisgIC8vIFNraXAgZm9yd2FyZCBpbiB0aGUgc2FtZSBidWZmZXIgdGhlbiBwZWVrIGFnYWluLgorICBFWFBFQ1RfVFJVRShjb2RlZF9pbnB1dC5Ta2lwKDMpKTsKKyAgY29kZWRfaW5wdXQuR2V0RGlyZWN0QnVmZmVyUG9pbnRlcklubGluZSgmcHRyLCAmc2l6ZSk7CisgIEVYUEVDVF9FUShidWZmZXJfICsgMywgcHRyKTsKKyAgRVhQRUNUX0VRKDUsIHNpemUpOworCisgIC8vIFNraXAgdG8gZW5kIG9mIGJ1ZmZlciBhbmQgcGVlayAtLSBzaG91bGQgcmV0dXJuIGZhbHNlIGFuZCBwcm92aWRlIGFuIGVtcHR5CisgIC8vIGJ1ZmZlci4gSXQgZG9lcyBub3QgdHJ5IHRvIFJlZnJlc2goKS4KKyAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuU2tpcCg1KSk7CisgIGNvZGVkX2lucHV0LkdldERpcmVjdEJ1ZmZlclBvaW50ZXJJbmxpbmUoJnB0ciwgJnNpemUpOworICBFWFBFQ1RfRVEoYnVmZmVyXyArIDgsIHB0cik7CisgIEVYUEVDVF9FUSgwLCBzaXplKTsKK30KKworVEVTVF9GKENvZGVkU3RyZWFtVGVzdCwgR2V0RGlyZWN0QnVmZmVyUG9pbnRlck91dHB1dCkgeworICBBcnJheU91dHB1dFN0cmVhbSBvdXRwdXQoYnVmZmVyXywgc2l6ZW9mKGJ1ZmZlcl8pLCA4KTsKKyAgQ29kZWRPdXRwdXRTdHJlYW0gY29kZWRfb3V0cHV0KCZvdXRwdXQpOworCisgIHZvaWQqIHB0cjsKKyAgaW50IHNpemU7CisKKyAgRVhQRUNUX1RSVUUoY29kZWRfb3V0cHV0LkdldERpcmVjdEJ1ZmZlclBvaW50ZXIoJnB0ciwgJnNpemUpKTsKKyAgRVhQRUNUX0VRKGJ1ZmZlcl8sIHB0cik7CisgIEVYUEVDVF9FUSg4LCBzaXplKTsKKworICAvLyBQZWVraW5nIGFnYWluIHNob3VsZCByZXR1cm4gdGhlIHNhbWUgcG9pbnRlci4KKyAgRVhQRUNUX1RSVUUoY29kZWRfb3V0cHV0LkdldERpcmVjdEJ1ZmZlclBvaW50ZXIoJnB0ciwgJnNpemUpKTsKKyAgRVhQRUNUX0VRKGJ1ZmZlcl8sIHB0cik7CisgIEVYUEVDVF9FUSg4LCBzaXplKTsKKworICAvLyBTa2lwIGZvcndhcmQgaW4gdGhlIHNhbWUgYnVmZmVyIHRoZW4gcGVlayBhZ2Fpbi4KKyAgRVhQRUNUX1RSVUUoY29kZWRfb3V0cHV0LlNraXAoMykpOworICBFWFBFQ1RfVFJVRShjb2RlZF9vdXRwdXQuR2V0RGlyZWN0QnVmZmVyUG9pbnRlcigmcHRyLCAmc2l6ZSkpOworICBFWFBFQ1RfRVEoYnVmZmVyXyArIDMsIHB0cik7CisgIEVYUEVDVF9FUSg1LCBzaXplKTsKKworICAvLyBTa2lwIHRvIGVuZCBvZiBidWZmZXIgYW5kIHBlZWsgLS0gc2hvdWxkIGdldCBuZXh0IGJ1ZmZlci4KKyAgRVhQRUNUX1RSVUUoY29kZWRfb3V0cHV0LlNraXAoNSkpOworICBFWFBFQ1RfVFJVRShjb2RlZF9vdXRwdXQuR2V0RGlyZWN0QnVmZmVyUG9pbnRlcigmcHRyLCAmc2l6ZSkpOworICBFWFBFQ1RfRVEoYnVmZmVyXyArIDgsIHB0cik7CisgIEVYUEVDVF9FUSg4LCBzaXplKTsKKworICAvLyBTa2lwIG92ZXIgbXVsdGlwbGUgYnVmZmVycy4KKyAgRVhQRUNUX1RSVUUoY29kZWRfb3V0cHV0LlNraXAoMjIpKTsKKyAgRVhQRUNUX1RSVUUoY29kZWRfb3V0cHV0LkdldERpcmVjdEJ1ZmZlclBvaW50ZXIoJnB0ciwgJnNpemUpKTsKKyAgRVhQRUNUX0VRKGJ1ZmZlcl8gKyAzMCwgcHRyKTsKKyAgRVhQRUNUX0VRKDIsIHNpemUpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBMaW1pdHMKKworVEVTVF8xRChDb2RlZFN0cmVhbVRlc3QsIEJhc2ljTGltaXQsIGtCbG9ja1NpemVzKSB7CisgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQoYnVmZmVyXywgc2l6ZW9mKGJ1ZmZlcl8pLCBrQmxvY2tTaXplc19jYXNlKTsKKworICB7CisgICAgQ29kZWRJbnB1dFN0cmVhbSBjb2RlZF9pbnB1dCgmaW5wdXQpOworCisgICAgRVhQRUNUX0VRKC0xLCBjb2RlZF9pbnB1dC5CeXRlc1VudGlsTGltaXQoKSk7CisgICAgQ29kZWRJbnB1dFN0cmVhbTo6TGltaXQgbGltaXQgPSBjb2RlZF9pbnB1dC5QdXNoTGltaXQoOCk7CisKKyAgICAvLyBSZWFkIHVudGlsIHdlIGhpdCB0aGUgbGltaXQuCisgICAgdWludDMyIHZhbHVlOworICAgIEVYUEVDVF9FUSg4LCBjb2RlZF9pbnB1dC5CeXRlc1VudGlsTGltaXQoKSk7CisgICAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuUmVhZExpdHRsZUVuZGlhbjMyKCZ2YWx1ZSkpOworICAgIEVYUEVDVF9FUSg0LCBjb2RlZF9pbnB1dC5CeXRlc1VudGlsTGltaXQoKSk7CisgICAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuUmVhZExpdHRsZUVuZGlhbjMyKCZ2YWx1ZSkpOworICAgIEVYUEVDVF9FUSgwLCBjb2RlZF9pbnB1dC5CeXRlc1VudGlsTGltaXQoKSk7CisgICAgRVhQRUNUX0ZBTFNFKGNvZGVkX2lucHV0LlJlYWRMaXR0bGVFbmRpYW4zMigmdmFsdWUpKTsKKyAgICBFWFBFQ1RfRVEoMCwgY29kZWRfaW5wdXQuQnl0ZXNVbnRpbExpbWl0KCkpOworCisgICAgY29kZWRfaW5wdXQuUG9wTGltaXQobGltaXQpOworCisgICAgRVhQRUNUX0VRKC0xLCBjb2RlZF9pbnB1dC5CeXRlc1VudGlsTGltaXQoKSk7CisgICAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuUmVhZExpdHRsZUVuZGlhbjMyKCZ2YWx1ZSkpOworICB9CisKKyAgRVhQRUNUX0VRKDEyLCBpbnB1dC5CeXRlQ291bnQoKSk7Cit9CisKKy8vIFRlc3Qgd2hhdCBoYXBwZW5zIHdoZW4gd2UgcHVzaCB0d28gbGltaXRzIHdoZXJlIHRoZSBzZWNvbmQgKHRvcCkgb25lIGlzCisvLyBzaG9ydGVyLgorVEVTVF8xRChDb2RlZFN0cmVhbVRlc3QsIFNtYWxsTGltaXRPblRvcE9mQmlnTGltaXQsIGtCbG9ja1NpemVzKSB7CisgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQoYnVmZmVyXywgc2l6ZW9mKGJ1ZmZlcl8pLCBrQmxvY2tTaXplc19jYXNlKTsKKworICB7CisgICAgQ29kZWRJbnB1dFN0cmVhbSBjb2RlZF9pbnB1dCgmaW5wdXQpOworCisgICAgRVhQRUNUX0VRKC0xLCBjb2RlZF9pbnB1dC5CeXRlc1VudGlsTGltaXQoKSk7CisgICAgQ29kZWRJbnB1dFN0cmVhbTo6TGltaXQgbGltaXQxID0gY29kZWRfaW5wdXQuUHVzaExpbWl0KDgpOworICAgIEVYUEVDVF9FUSg4LCBjb2RlZF9pbnB1dC5CeXRlc1VudGlsTGltaXQoKSk7CisgICAgQ29kZWRJbnB1dFN0cmVhbTo6TGltaXQgbGltaXQyID0gY29kZWRfaW5wdXQuUHVzaExpbWl0KDQpOworCisgICAgdWludDMyIHZhbHVlOworCisgICAgLy8gUmVhZCB1bnRpbCB3ZSBoaXQgbGltaXQyLCB0aGUgdG9wIGFuZCBzaG9ydGVzdCBsaW1pdC4KKyAgICBFWFBFQ1RfRVEoNCwgY29kZWRfaW5wdXQuQnl0ZXNVbnRpbExpbWl0KCkpOworICAgIEVYUEVDVF9UUlVFKGNvZGVkX2lucHV0LlJlYWRMaXR0bGVFbmRpYW4zMigmdmFsdWUpKTsKKyAgICBFWFBFQ1RfRVEoMCwgY29kZWRfaW5wdXQuQnl0ZXNVbnRpbExpbWl0KCkpOworICAgIEVYUEVDVF9GQUxTRShjb2RlZF9pbnB1dC5SZWFkTGl0dGxlRW5kaWFuMzIoJnZhbHVlKSk7CisgICAgRVhQRUNUX0VRKDAsIGNvZGVkX2lucHV0LkJ5dGVzVW50aWxMaW1pdCgpKTsKKworICAgIGNvZGVkX2lucHV0LlBvcExpbWl0KGxpbWl0Mik7CisKKyAgICAvLyBSZWFkIHVudGlsIHdlIGhpdCBsaW1pdDEuCisgICAgRVhQRUNUX0VRKDQsIGNvZGVkX2lucHV0LkJ5dGVzVW50aWxMaW1pdCgpKTsKKyAgICBFWFBFQ1RfVFJVRShjb2RlZF9pbnB1dC5SZWFkTGl0dGxlRW5kaWFuMzIoJnZhbHVlKSk7CisgICAgRVhQRUNUX0VRKDAsIGNvZGVkX2lucHV0LkJ5dGVzVW50aWxMaW1pdCgpKTsKKyAgICBFWFBFQ1RfRkFMU0UoY29kZWRfaW5wdXQuUmVhZExpdHRsZUVuZGlhbjMyKCZ2YWx1ZSkpOworICAgIEVYUEVDVF9FUSgwLCBjb2RlZF9pbnB1dC5CeXRlc1VudGlsTGltaXQoKSk7CisKKyAgICBjb2RlZF9pbnB1dC5Qb3BMaW1pdChsaW1pdDEpOworCisgICAgLy8gTm8gbW9yZSBsaW1pdHMuCisgICAgRVhQRUNUX0VRKC0xLCBjb2RlZF9pbnB1dC5CeXRlc1VudGlsTGltaXQoKSk7CisgICAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuUmVhZExpdHRsZUVuZGlhbjMyKCZ2YWx1ZSkpOworICB9CisKKyAgRVhQRUNUX0VRKDEyLCBpbnB1dC5CeXRlQ291bnQoKSk7Cit9CisKKy8vIFRlc3Qgd2hhdCBoYXBwZW5zIHdoZW4gd2UgcHVzaCB0d28gbGltaXRzIHdoZXJlIHRoZSBzZWNvbmQgKHRvcCkgb25lIGlzCisvLyBsb25nZXIuICBJbiB0aGlzIGNhc2UsIHRoZSB0b3AgbGltaXQgaXMgc2hvcnRlbmVkIHRvIG1hdGNoIHRoZSBwcmV2aW91cworLy8gbGltaXQuCitURVNUXzFEKENvZGVkU3RyZWFtVGVzdCwgQmlnTGltaXRPblRvcE9mU21hbGxMaW1pdCwga0Jsb2NrU2l6ZXMpIHsKKyAgQXJyYXlJbnB1dFN0cmVhbSBpbnB1dChidWZmZXJfLCBzaXplb2YoYnVmZmVyXyksIGtCbG9ja1NpemVzX2Nhc2UpOworCisgIHsKKyAgICBDb2RlZElucHV0U3RyZWFtIGNvZGVkX2lucHV0KCZpbnB1dCk7CisKKyAgICBFWFBFQ1RfRVEoLTEsIGNvZGVkX2lucHV0LkJ5dGVzVW50aWxMaW1pdCgpKTsKKyAgICBDb2RlZElucHV0U3RyZWFtOjpMaW1pdCBsaW1pdDEgPSBjb2RlZF9pbnB1dC5QdXNoTGltaXQoNCk7CisgICAgRVhQRUNUX0VRKDQsIGNvZGVkX2lucHV0LkJ5dGVzVW50aWxMaW1pdCgpKTsKKyAgICBDb2RlZElucHV0U3RyZWFtOjpMaW1pdCBsaW1pdDIgPSBjb2RlZF9pbnB1dC5QdXNoTGltaXQoOCk7CisKKyAgICB1aW50MzIgdmFsdWU7CisKKyAgICAvLyBSZWFkIHVudGlsIHdlIGhpdCBsaW1pdDIuICBFeGNlcHQsIHdhaXQhICBsaW1pdDEgaXMgc2hvcnRlciwgc28KKyAgICAvLyB3ZSBlbmQgdXAgaGl0dGluZyB0aGF0IGZpcnN0LCBkZXNwaXRlIGhhdmluZyA0IGJ5dGVzIHRvIGdvIG9uCisgICAgLy8gbGltaXQyLgorICAgIEVYUEVDVF9FUSg0LCBjb2RlZF9pbnB1dC5CeXRlc1VudGlsTGltaXQoKSk7CisgICAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuUmVhZExpdHRsZUVuZGlhbjMyKCZ2YWx1ZSkpOworICAgIEVYUEVDVF9FUSgwLCBjb2RlZF9pbnB1dC5CeXRlc1VudGlsTGltaXQoKSk7CisgICAgRVhQRUNUX0ZBTFNFKGNvZGVkX2lucHV0LlJlYWRMaXR0bGVFbmRpYW4zMigmdmFsdWUpKTsKKyAgICBFWFBFQ1RfRVEoMCwgY29kZWRfaW5wdXQuQnl0ZXNVbnRpbExpbWl0KCkpOworCisgICAgY29kZWRfaW5wdXQuUG9wTGltaXQobGltaXQyKTsKKworICAgIC8vIE9LLCBwb3BwZWQgbGltaXQyLCBub3cgbGltaXQxIGlzIG9uIHRvcCwgd2hpY2ggd2UndmUgYWxyZWFkeSBoaXQuCisgICAgRVhQRUNUX0VRKDAsIGNvZGVkX2lucHV0LkJ5dGVzVW50aWxMaW1pdCgpKTsKKyAgICBFWFBFQ1RfRkFMU0UoY29kZWRfaW5wdXQuUmVhZExpdHRsZUVuZGlhbjMyKCZ2YWx1ZSkpOworICAgIEVYUEVDVF9FUSgwLCBjb2RlZF9pbnB1dC5CeXRlc1VudGlsTGltaXQoKSk7CisKKyAgICBjb2RlZF9pbnB1dC5Qb3BMaW1pdChsaW1pdDEpOworCisgICAgLy8gTm8gbW9yZSBsaW1pdHMuCisgICAgRVhQRUNUX0VRKC0xLCBjb2RlZF9pbnB1dC5CeXRlc1VudGlsTGltaXQoKSk7CisgICAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuUmVhZExpdHRsZUVuZGlhbjMyKCZ2YWx1ZSkpOworICB9CisKKyAgRVhQRUNUX0VRKDgsIGlucHV0LkJ5dGVDb3VudCgpKTsKK30KKworVEVTVF9GKENvZGVkU3RyZWFtVGVzdCwgRXhwZWN0QXRFbmQpIHsKKyAgLy8gVGVzdCBFeHBlY3RBdEVuZCgpLCB3aGljaCBpcyBiYXNlZCBvbiBsaW1pdHMuCisgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQoYnVmZmVyXywgc2l6ZW9mKGJ1ZmZlcl8pKTsKKyAgQ29kZWRJbnB1dFN0cmVhbSBjb2RlZF9pbnB1dCgmaW5wdXQpOworCisgIEVYUEVDVF9GQUxTRShjb2RlZF9pbnB1dC5FeHBlY3RBdEVuZCgpKTsKKworICBDb2RlZElucHV0U3RyZWFtOjpMaW1pdCBsaW1pdCA9IGNvZGVkX2lucHV0LlB1c2hMaW1pdCg0KTsKKworICB1aW50MzIgdmFsdWU7CisgIEVYUEVDVF9UUlVFKGNvZGVkX2lucHV0LlJlYWRMaXR0bGVFbmRpYW4zMigmdmFsdWUpKTsKKyAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuRXhwZWN0QXRFbmQoKSk7CisKKyAgY29kZWRfaW5wdXQuUG9wTGltaXQobGltaXQpOworICBFWFBFQ1RfRkFMU0UoY29kZWRfaW5wdXQuRXhwZWN0QXRFbmQoKSk7Cit9CisKK1RFU1RfRihDb2RlZFN0cmVhbVRlc3QsIE5lZ2F0aXZlTGltaXQpIHsKKyAgLy8gQ2hlY2sgd2hhdCBoYXBwZW5zIHdoZW4gd2UgcHVzaCBhIG5lZ2F0aXZlIGxpbWl0LgorICBBcnJheUlucHV0U3RyZWFtIGlucHV0KGJ1ZmZlcl8sIHNpemVvZihidWZmZXJfKSk7CisgIENvZGVkSW5wdXRTdHJlYW0gY29kZWRfaW5wdXQoJmlucHV0KTsKKworICBDb2RlZElucHV0U3RyZWFtOjpMaW1pdCBsaW1pdCA9IGNvZGVkX2lucHV0LlB1c2hMaW1pdCgtMTIzNCk7CisgIC8vIEJ5dGVzVW50aWxMaW1pdCgpIHJldHVybnMgLTEgdG8gbWVhbiAibm8gbGltaXQiLCB3aGljaCBhY3R1YWxseSBtZWFucworICAvLyAidGhlIGxpbWl0IGlzIElOVF9NQVggcmVsYXRpdmUgdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgc3RyZWFtIi4KKyAgRVhQRUNUX0VRKC0xLCBjb2RlZF9pbnB1dC5CeXRlc1VudGlsTGltaXQoKSk7CisgIGNvZGVkX2lucHV0LlBvcExpbWl0KGxpbWl0KTsKK30KKworVEVTVF9GKENvZGVkU3RyZWFtVGVzdCwgTmVnYXRpdmVMaW1pdEFmdGVyUmVhZGluZykgeworICAvLyBDaGVjayB3aGF0IGhhcHBlbnMgd2hlbiB3ZSBwdXNoIGEgbmVnYXRpdmUgbGltaXQuCisgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQoYnVmZmVyXywgc2l6ZW9mKGJ1ZmZlcl8pKTsKKyAgQ29kZWRJbnB1dFN0cmVhbSBjb2RlZF9pbnB1dCgmaW5wdXQpOworICBBU1NFUlRfVFJVRShjb2RlZF9pbnB1dC5Ta2lwKDEyOCkpOworCisgIENvZGVkSW5wdXRTdHJlYW06OkxpbWl0IGxpbWl0ID0gY29kZWRfaW5wdXQuUHVzaExpbWl0KC02NCk7CisgIC8vIEJ5dGVzVW50aWxMaW1pdCgpIHJldHVybnMgLTEgdG8gbWVhbiAibm8gbGltaXQiLCB3aGljaCBhY3R1YWxseSBtZWFucworICAvLyAidGhlIGxpbWl0IGlzIElOVF9NQVggcmVsYXRpdmUgdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgc3RyZWFtIi4KKyAgRVhQRUNUX0VRKC0xLCBjb2RlZF9pbnB1dC5CeXRlc1VudGlsTGltaXQoKSk7CisgIGNvZGVkX2lucHV0LlBvcExpbWl0KGxpbWl0KTsKK30KKworVEVTVF9GKENvZGVkU3RyZWFtVGVzdCwgT3ZlcmZsb3dMaW1pdCkgeworICAvLyBDaGVjayB3aGF0IGhhcHBlbnMgd2hlbiB3ZSBwdXNoIGEgbGltaXQgbGFyZ2UgZW5vdWdoIHRoYXQgaXRzIGFic29sdXRlCisgIC8vIHBvc2l0aW9uIGlzIG1vcmUgdGhhbiAyR0IgaW50byB0aGUgc3RyZWFtLgorICBBcnJheUlucHV0U3RyZWFtIGlucHV0KGJ1ZmZlcl8sIHNpemVvZihidWZmZXJfKSk7CisgIENvZGVkSW5wdXRTdHJlYW0gY29kZWRfaW5wdXQoJmlucHV0KTsKKyAgQVNTRVJUX1RSVUUoY29kZWRfaW5wdXQuU2tpcCgxMjgpKTsKKworICBDb2RlZElucHV0U3RyZWFtOjpMaW1pdCBsaW1pdCA9IGNvZGVkX2lucHV0LlB1c2hMaW1pdChJTlRfTUFYKTsKKyAgLy8gQnl0ZXNVbnRpbExpbWl0KCkgcmV0dXJucyAtMSB0byBtZWFuICJubyBsaW1pdCIsIHdoaWNoIGFjdHVhbGx5IG1lYW5zCisgIC8vICJ0aGUgbGltaXQgaXMgSU5UX01BWCByZWxhdGl2ZSB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzdHJlYW0iLgorICBFWFBFQ1RfRVEoLTEsIGNvZGVkX2lucHV0LkJ5dGVzVW50aWxMaW1pdCgpKTsKKyAgY29kZWRfaW5wdXQuUG9wTGltaXQobGltaXQpOworfQorCitURVNUX0YoQ29kZWRTdHJlYW1UZXN0LCBUb3RhbEJ5dGVzTGltaXQpIHsKKyAgQXJyYXlJbnB1dFN0cmVhbSBpbnB1dChidWZmZXJfLCBzaXplb2YoYnVmZmVyXykpOworICBDb2RlZElucHV0U3RyZWFtIGNvZGVkX2lucHV0KCZpbnB1dCk7CisgIGNvZGVkX2lucHV0LlNldFRvdGFsQnl0ZXNMaW1pdCgxNiwgLTEpOworICBFWFBFQ1RfRVEoMTYsIGNvZGVkX2lucHV0LkJ5dGVzVW50aWxUb3RhbEJ5dGVzTGltaXQoKSk7CisKKyAgc3RyaW5nIHN0cjsKKyAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuUmVhZFN0cmluZygmc3RyLCAxNikpOworICBFWFBFQ1RfRVEoMCwgY29kZWRfaW5wdXQuQnl0ZXNVbnRpbFRvdGFsQnl0ZXNMaW1pdCgpKTsKKworICB2ZWN0b3I8c3RyaW5nPiBlcnJvcnM7CisKKyAgeworICAgIFNjb3BlZE1lbW9yeUxvZyBlcnJvcl9sb2c7CisgICAgRVhQRUNUX0ZBTFNFKGNvZGVkX2lucHV0LlJlYWRTdHJpbmcoJnN0ciwgMSkpOworICAgIGVycm9ycyA9IGVycm9yX2xvZy5HZXRNZXNzYWdlcyhFUlJPUik7CisgIH0KKworICBBU1NFUlRfRVEoMSwgZXJyb3JzLnNpemUoKSk7CisgIEVYUEVDVF9QUkVEX0ZPUk1BVDIodGVzdGluZzo6SXNTdWJzdHJpbmcsCisgICAgIkEgcHJvdG9jb2wgbWVzc2FnZSB3YXMgcmVqZWN0ZWQgYmVjYXVzZSBpdCB3YXMgdG9vIGJpZyIsIGVycm9yc1swXSk7CisKKyAgY29kZWRfaW5wdXQuU2V0VG90YWxCeXRlc0xpbWl0KDMyLCAtMSk7CisgIEVYUEVDVF9FUSgxNiwgY29kZWRfaW5wdXQuQnl0ZXNVbnRpbFRvdGFsQnl0ZXNMaW1pdCgpKTsKKyAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuUmVhZFN0cmluZygmc3RyLCAxNikpOworICBFWFBFQ1RfRVEoMCwgY29kZWRfaW5wdXQuQnl0ZXNVbnRpbFRvdGFsQnl0ZXNMaW1pdCgpKTsKK30KKworVEVTVF9GKENvZGVkU3RyZWFtVGVzdCwgVG90YWxCeXRlc0xpbWl0Tm90VmFsaWRNZXNzYWdlRW5kKSB7CisgIC8vIHRvdGFsX2J5dGVzX2xpbWl0XyBpcyBub3QgYSB2YWxpZCBwbGFjZSBmb3IgYSBtZXNzYWdlIHRvIGVuZC4KKworICBBcnJheUlucHV0U3RyZWFtIGlucHV0KGJ1ZmZlcl8sIHNpemVvZihidWZmZXJfKSk7CisgIENvZGVkSW5wdXRTdHJlYW0gY29kZWRfaW5wdXQoJmlucHV0KTsKKworICAvLyBTZXQgYm90aCB0b3RhbF9ieXRlc19saW1pdCBhbmQgYSByZWd1bGFyIGxpbWl0IGF0IDE2IGJ5dGVzLgorICBjb2RlZF9pbnB1dC5TZXRUb3RhbEJ5dGVzTGltaXQoMTYsIC0xKTsKKyAgQ29kZWRJbnB1dFN0cmVhbTo6TGltaXQgbGltaXQgPSBjb2RlZF9pbnB1dC5QdXNoTGltaXQoMTYpOworCisgIC8vIFJlYWQgMTYgYnl0ZXMuCisgIHN0cmluZyBzdHI7CisgIEVYUEVDVF9UUlVFKGNvZGVkX2lucHV0LlJlYWRTdHJpbmcoJnN0ciwgMTYpKTsKKworICAvLyBSZWFkIGEgdGFnLiAgU2hvdWxkIGZhaWwsIGJ1dCByZXBvcnQgYmVpbmcgYSB2YWxpZCBlbmRwb2ludCBzaW5jZSBpdCdzCisgIC8vIGEgcmVndWxhciBsaW1pdC4KKyAgRVhQRUNUX0VRKDAsIGNvZGVkX2lucHV0LlJlYWRUYWcoKSk7CisgIEVYUEVDVF9UUlVFKGNvZGVkX2lucHV0LkNvbnN1bWVkRW50aXJlTWVzc2FnZSgpKTsKKworICAvLyBQb3AgdGhlIGxpbWl0LgorICBjb2RlZF9pbnB1dC5Qb3BMaW1pdChsaW1pdCk7CisKKyAgLy8gUmVhZCBhIHRhZy4gIFNob3VsZCBmYWlsLCBhbmQgcmVwb3J0ICpub3QqIGJlaW5nIGEgdmFsaWQgZW5kcG9pbnQsIHNpbmNlCisgIC8vIHRoaXMgdGltZSB3ZSdyZSBoaXR0aW5nIHRoZSB0b3RhbCBieXRlcyBsaW1pdC4KKyAgRVhQRUNUX0VRKDAsIGNvZGVkX2lucHV0LlJlYWRUYWcoKSk7CisgIEVYUEVDVF9GQUxTRShjb2RlZF9pbnB1dC5Db25zdW1lZEVudGlyZU1lc3NhZ2UoKSk7Cit9CisKKy8vIFRoaXMgbWV0aG9kIGlzIHVzZWQgYnkgdGhlIHRlc3RzIGJlbG93LgorLy8gSXQgY29uc3RydWN0cyBhIENvZGVkSW5wdXRTdHJlYW0gd2l0aCB0aGUgZ2l2ZW4gbGltaXRzIGFuZCB0cmllcyB0byByZWFkIDJLaUIKKy8vIG9mIGRhdGEgZnJvbSBpdC4gVGhlbiBpdCByZXR1cm5zIHRoZSBsb2dnZWQgZXJyb3JzIGFuZCB3YXJuaW5ncyBpbiB0aGUgZ2l2ZW4KKy8vIHZlY3RvcnMuCit2b2lkIENvZGVkU3RyZWFtVGVzdDo6U2V0dXBUb3RhbEJ5dGVzTGltaXRXYXJuaW5nVGVzdCgKKyAgICBpbnQgdG90YWxfYnl0ZXNfbGltaXQsIGludCB3YXJuaW5nX3RocmVzaG9sZCwKKyAgICB2ZWN0b3I8c3RyaW5nPiogb3V0X2Vycm9ycywgdmVjdG9yPHN0cmluZz4qIG91dF93YXJuaW5ncykgeworICBBcnJheUlucHV0U3RyZWFtIHJhd19pbnB1dChidWZmZXJfLCBzaXplb2YoYnVmZmVyXyksIDEyOCk7CisKKyAgU2NvcGVkTWVtb3J5TG9nIHNjb3BlZF9sb2c7CisgIHsKKyAgICBDb2RlZElucHV0U3RyZWFtIGlucHV0KCZyYXdfaW5wdXQpOworICAgIGlucHV0LlNldFRvdGFsQnl0ZXNMaW1pdCh0b3RhbF9ieXRlc19saW1pdCwgd2FybmluZ190aHJlc2hvbGQpOworICAgIHN0cmluZyBzdHI7CisgICAgRVhQRUNUX1RSVUUoaW5wdXQuUmVhZFN0cmluZygmc3RyLCAyMDQ4KSk7CisgIH0KKworICAqb3V0X2Vycm9ycyA9IHNjb3BlZF9sb2cuR2V0TWVzc2FnZXMoRVJST1IpOworICAqb3V0X3dhcm5pbmdzID0gc2NvcGVkX2xvZy5HZXRNZXNzYWdlcyhXQVJOSU5HKTsKK30KKworVEVTVF9GKENvZGVkU3RyZWFtVGVzdCwgVG90YWxCeXRlc0xpbWl0V2FybmluZykgeworICB2ZWN0b3I8c3RyaW5nPiBlcnJvcnM7CisgIHZlY3RvcjxzdHJpbmc+IHdhcm5pbmdzOworICBTZXR1cFRvdGFsQnl0ZXNMaW1pdFdhcm5pbmdUZXN0KDEwMjQwLCAxMDI0LCAmZXJyb3JzLCAmd2FybmluZ3MpOworCisgIEVYUEVDVF9FUSgwLCBlcnJvcnMuc2l6ZSgpKTsKKworICBBU1NFUlRfRVEoMiwgd2FybmluZ3Muc2l6ZSgpKTsKKyAgRVhQRUNUX1BSRURfRk9STUFUMih0ZXN0aW5nOjpJc1N1YnN0cmluZywKKyAgICAiUmVhZGluZyBkYW5nZXJvdXNseSBsYXJnZSBwcm90b2NvbCBtZXNzYWdlLiAgSWYgdGhlIG1lc3NhZ2UgdHVybnMgb3V0IHRvICIKKyAgICAiYmUgbGFyZ2VyIHRoYW4gMTAyNDAgYnl0ZXMsIHBhcnNpbmcgd2lsbCBiZSBoYWx0ZWQgZm9yIHNlY3VyaXR5IHJlYXNvbnMuIiwKKyAgICB3YXJuaW5nc1swXSk7CisgIEVYUEVDVF9QUkVEX0ZPUk1BVDIodGVzdGluZzo6SXNTdWJzdHJpbmcsCisgICAgIlRoZSB0b3RhbCBudW1iZXIgb2YgYnl0ZXMgcmVhZCB3YXMgMjA0OCIsCisgICAgd2FybmluZ3NbMV0pOworfQorCitURVNUX0YoQ29kZWRTdHJlYW1UZXN0LCBUb3RhbEJ5dGVzTGltaXRXYXJuaW5nRGlzYWJsZWQpIHsKKyAgdmVjdG9yPHN0cmluZz4gZXJyb3JzOworICB2ZWN0b3I8c3RyaW5nPiB3YXJuaW5nczsKKworICAvLyBUZXN0IHdpdGggLTEKKyAgU2V0dXBUb3RhbEJ5dGVzTGltaXRXYXJuaW5nVGVzdCgxMDI0MCwgLTEsICZlcnJvcnMsICZ3YXJuaW5ncyk7CisgIEVYUEVDVF9FUSgwLCBlcnJvcnMuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIHdhcm5pbmdzLnNpemUoKSk7CisKKyAgLy8gVGVzdCBhZ2FpbiB3aXRoIC0yLCBleHBlY3RpbmcgdGhlIHNhbWUgcmVzdWx0CisgIFNldHVwVG90YWxCeXRlc0xpbWl0V2FybmluZ1Rlc3QoMTAyNDAsIC0yLCAmZXJyb3JzLCAmd2FybmluZ3MpOworICBFWFBFQ1RfRVEoMCwgZXJyb3JzLnNpemUoKSk7CisgIEVYUEVDVF9FUSgwLCB3YXJuaW5ncy5zaXplKCkpOworfQorCisKK1RFU1RfRihDb2RlZFN0cmVhbVRlc3QsIFJlY3Vyc2lvbkxpbWl0KSB7CisgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQoYnVmZmVyXywgc2l6ZW9mKGJ1ZmZlcl8pKTsKKyAgQ29kZWRJbnB1dFN0cmVhbSBjb2RlZF9pbnB1dCgmaW5wdXQpOworICBjb2RlZF9pbnB1dC5TZXRSZWN1cnNpb25MaW1pdCg0KTsKKworICAvLyBUaGlzIGlzIHdheSB0b28gbXVjaCB0ZXN0aW5nIGZvciBhIGNvdW50ZXIuCisgIEVYUEVDVF9UUlVFKGNvZGVkX2lucHV0LkluY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCkpOyAgICAgIC8vIDEKKyAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuSW5jcmVtZW50UmVjdXJzaW9uRGVwdGgoKSk7ICAgICAgLy8gMgorICBFWFBFQ1RfVFJVRShjb2RlZF9pbnB1dC5JbmNyZW1lbnRSZWN1cnNpb25EZXB0aCgpKTsgICAgICAvLyAzCisgIEVYUEVDVF9UUlVFKGNvZGVkX2lucHV0LkluY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCkpOyAgICAgIC8vIDQKKyAgRVhQRUNUX0ZBTFNFKGNvZGVkX2lucHV0LkluY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCkpOyAgICAgLy8gNQorICBFWFBFQ1RfRkFMU0UoY29kZWRfaW5wdXQuSW5jcmVtZW50UmVjdXJzaW9uRGVwdGgoKSk7ICAgICAvLyA2CisgIGNvZGVkX2lucHV0LkRlY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCk7ICAgICAgICAgICAgICAgICAgIC8vIDUKKyAgRVhQRUNUX0ZBTFNFKGNvZGVkX2lucHV0LkluY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCkpOyAgICAgLy8gNgorICBjb2RlZF9pbnB1dC5EZWNyZW1lbnRSZWN1cnNpb25EZXB0aCgpOyAgICAgICAgICAgICAgICAgICAvLyA1CisgIGNvZGVkX2lucHV0LkRlY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCk7ICAgICAgICAgICAgICAgICAgIC8vIDQKKyAgY29kZWRfaW5wdXQuRGVjcmVtZW50UmVjdXJzaW9uRGVwdGgoKTsgICAgICAgICAgICAgICAgICAgLy8gMworICBFWFBFQ1RfVFJVRShjb2RlZF9pbnB1dC5JbmNyZW1lbnRSZWN1cnNpb25EZXB0aCgpKTsgICAgICAvLyA0CisgIEVYUEVDVF9GQUxTRShjb2RlZF9pbnB1dC5JbmNyZW1lbnRSZWN1cnNpb25EZXB0aCgpKTsgICAgIC8vIDUKKyAgY29kZWRfaW5wdXQuRGVjcmVtZW50UmVjdXJzaW9uRGVwdGgoKTsgICAgICAgICAgICAgICAgICAgLy8gNAorICBjb2RlZF9pbnB1dC5EZWNyZW1lbnRSZWN1cnNpb25EZXB0aCgpOyAgICAgICAgICAgICAgICAgICAvLyAzCisgIGNvZGVkX2lucHV0LkRlY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCk7ICAgICAgICAgICAgICAgICAgIC8vIDIKKyAgY29kZWRfaW5wdXQuRGVjcmVtZW50UmVjdXJzaW9uRGVwdGgoKTsgICAgICAgICAgICAgICAgICAgLy8gMQorICBjb2RlZF9pbnB1dC5EZWNyZW1lbnRSZWN1cnNpb25EZXB0aCgpOyAgICAgICAgICAgICAgICAgICAvLyAwCisgIGNvZGVkX2lucHV0LkRlY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCk7ICAgICAgICAgICAgICAgICAgIC8vIDAKKyAgY29kZWRfaW5wdXQuRGVjcmVtZW50UmVjdXJzaW9uRGVwdGgoKTsgICAgICAgICAgICAgICAgICAgLy8gMAorICBFWFBFQ1RfVFJVRShjb2RlZF9pbnB1dC5JbmNyZW1lbnRSZWN1cnNpb25EZXB0aCgpKTsgICAgICAvLyAxCisgIEVYUEVDVF9UUlVFKGNvZGVkX2lucHV0LkluY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCkpOyAgICAgIC8vIDIKKyAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuSW5jcmVtZW50UmVjdXJzaW9uRGVwdGgoKSk7ICAgICAgLy8gMworICBFWFBFQ1RfVFJVRShjb2RlZF9pbnB1dC5JbmNyZW1lbnRSZWN1cnNpb25EZXB0aCgpKTsgICAgICAvLyA0CisgIEVYUEVDVF9GQUxTRShjb2RlZF9pbnB1dC5JbmNyZW1lbnRSZWN1cnNpb25EZXB0aCgpKTsgICAgIC8vIDUKKworICBjb2RlZF9pbnB1dC5TZXRSZWN1cnNpb25MaW1pdCg2KTsKKyAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuSW5jcmVtZW50UmVjdXJzaW9uRGVwdGgoKSk7ICAgICAgLy8gNgorICBFWFBFQ1RfRkFMU0UoY29kZWRfaW5wdXQuSW5jcmVtZW50UmVjdXJzaW9uRGVwdGgoKSk7ICAgICAvLyA3Cit9CisKKworY2xhc3MgUmVhbGx5QmlnSW5wdXRTdHJlYW0gOiBwdWJsaWMgWmVyb0NvcHlJbnB1dFN0cmVhbSB7CisgcHVibGljOgorICBSZWFsbHlCaWdJbnB1dFN0cmVhbSgpIDogYmFja3VwX2Ftb3VudF8oMCksIGJ1ZmZlcl9jb3VudF8oMCkge30KKyAgflJlYWxseUJpZ0lucHV0U3RyZWFtKCkge30KKworICAvLyBpbXBsZW1lbnRzIFplcm9Db3B5SW5wdXRTdHJlYW0gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICBib29sIE5leHQoY29uc3Qgdm9pZCoqIGRhdGEsIGludCogc2l6ZSkgeworICAgIC8vIFdlIG9ubHkgZXhwZWN0IEJhY2tVcCgpIHRvIGJlIGNhbGxlZCBhdCB0aGUgZW5kLgorICAgIEVYUEVDVF9FUSgwLCBiYWNrdXBfYW1vdW50Xyk7CisKKyAgICBzd2l0Y2ggKGJ1ZmZlcl9jb3VudF8rKykgeworICAgICAgY2FzZSAwOgorICAgICAgICAqZGF0YSA9IGJ1ZmZlcl87CisgICAgICAgICpzaXplID0gc2l6ZW9mKGJ1ZmZlcl8pOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIGNhc2UgMToKKyAgICAgICAgLy8gUmV0dXJuIGFuIGVub3Jtb3VzbHkgbGFyZ2UgYnVmZmVyIHRoYXQsIHdoZW4gY29tYmluZWQgd2l0aCB0aGUgMWsKKyAgICAgICAgLy8gcmV0dXJuZWQgYWxyZWFkeSwgc2hvdWxkIG92ZXJmbG93IHRoZSB0b3RhbF9ieXRlc19yZWFkXyBjb3VudGVyIGluCisgICAgICAgIC8vIENvZGVkSW5wdXRTdHJlYW0uICBOb3RlIHRoYXQgd2UnbGwgb25seSByZWFkIHRoZSBmaXJzdCAxMDI0IGJ5dGVzCisgICAgICAgIC8vIG9mIHRoaXMgYnVmZmVyIHNvIGl0J3MgT0sgdGhhdCB3ZSBoYXZlIGl0IHBvaW50IGF0IGJ1ZmZlcl8uCisgICAgICAgICpkYXRhID0gYnVmZmVyXzsKKyAgICAgICAgKnNpemUgPSBJTlRfTUFYOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0KKworICB2b2lkIEJhY2tVcChpbnQgY291bnQpIHsKKyAgICBiYWNrdXBfYW1vdW50XyA9IGNvdW50OworICB9CisKKyAgYm9vbCBTa2lwKGludCBjb3VudCkgICAgeyBHT09HTEVfTE9HKEZBVEFMKSA8PCAiTm90IGltcGxlbWVudGVkLiI7IHJldHVybiBmYWxzZTsgfQorICBpbnQ2NCBCeXRlQ291bnQoKSBjb25zdCB7IEdPT0dMRV9MT0coRkFUQUwpIDw8ICJOb3QgaW1wbGVtZW50ZWQuIjsgcmV0dXJuIDA7IH0KKworICBpbnQgYmFja3VwX2Ftb3VudF87CisKKyBwcml2YXRlOgorICBjaGFyIGJ1ZmZlcl9bMTAyNF07CisgIGludDY0IGJ1ZmZlcl9jb3VudF87Cit9OworCitURVNUX0YoQ29kZWRTdHJlYW1UZXN0LCBJbnB1dE92ZXIyRykgeworICAvLyBDb2RlZElucHV0U3RyZWFtIHNob3VsZCBncmFjZWZ1bGx5IGhhbmRsZSBpbnB1dCBvdmVyIDJHIGFuZCBjYWxsCisgIC8vIGlucHV0LkJhY2tVcCgpIHdpdGggdGhlIGNvcnJlY3QgbnVtYmVyIG9mIGJ5dGVzIG9uIGRlc3RydWN0aW9uLgorICBSZWFsbHlCaWdJbnB1dFN0cmVhbSBpbnB1dDsKKworICB2ZWN0b3I8c3RyaW5nPiBlcnJvcnM7CisKKyAgeworICAgIFNjb3BlZE1lbW9yeUxvZyBlcnJvcl9sb2c7CisgICAgQ29kZWRJbnB1dFN0cmVhbSBjb2RlZF9pbnB1dCgmaW5wdXQpOworICAgIHN0cmluZyBzdHI7CisgICAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQuUmVhZFN0cmluZygmc3RyLCA1MTIpKTsKKyAgICBFWFBFQ1RfVFJVRShjb2RlZF9pbnB1dC5SZWFkU3RyaW5nKCZzdHIsIDEwMjQpKTsKKyAgICBlcnJvcnMgPSBlcnJvcl9sb2cuR2V0TWVzc2FnZXMoRVJST1IpOworICB9CisKKyAgRVhQRUNUX0VRKElOVF9NQVggLSA1MTIsIGlucHV0LmJhY2t1cF9hbW91bnRfKTsKKyAgRVhQRUNUX0VRKDAsIGVycm9ycy5zaXplKCkpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKworfSAgLy8gbmFtZXNwYWNlCit9ICAvLyBuYW1lc3BhY2UgaW8KK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby9nemlwX3N0cmVhbS5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vZ3ppcF9zdHJlYW0uY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWJlNmM4NgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vZ3ppcF9zdHJlYW0uY2MKQEAgLTAsMCArMSwzMzIgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGJyaWFub2xzb25AZ29vZ2xlLmNvbSAoQnJpYW4gT2xzb24pCisvLworLy8gVGhpcyBmaWxlIGNvbnRhaW5zIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiBjbGFzc2VzIEd6aXBJbnB1dFN0cmVhbSBhbmQKKy8vIEd6aXBPdXRwdXRTdHJlYW0uCisKKworI2lmIEhBVkVfWkxJQgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9nemlwX3N0cmVhbS5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9sb2dnaW5nLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbyB7CisKK3N0YXRpYyBjb25zdCBpbnQga0RlZmF1bHRCdWZmZXJTaXplID0gNjU1MzY7CisKK0d6aXBJbnB1dFN0cmVhbTo6R3ppcElucHV0U3RyZWFtKAorICAgIFplcm9Db3B5SW5wdXRTdHJlYW0qIHN1Yl9zdHJlYW0sIEZvcm1hdCBmb3JtYXQsIGludCBidWZmZXJfc2l6ZSkKKyAgICA6IGZvcm1hdF8oZm9ybWF0KSwgc3ViX3N0cmVhbV8oc3ViX3N0cmVhbSksIHplcnJvcl8oWl9PSyksIGJ5dGVfY291bnRfKDApIHsKKyAgemNvbnRleHRfLnN0YXRlID0gWl9OVUxMOworICB6Y29udGV4dF8uemFsbG9jID0gWl9OVUxMOworICB6Y29udGV4dF8uemZyZWUgPSBaX05VTEw7CisgIHpjb250ZXh0Xy5vcGFxdWUgPSBaX05VTEw7CisgIHpjb250ZXh0Xy50b3RhbF9vdXQgPSAwOworICB6Y29udGV4dF8ubmV4dF9pbiA9IE5VTEw7CisgIHpjb250ZXh0Xy5hdmFpbF9pbiA9IDA7CisgIHpjb250ZXh0Xy50b3RhbF9pbiA9IDA7CisgIHpjb250ZXh0Xy5tc2cgPSBOVUxMOworICBpZiAoYnVmZmVyX3NpemUgPT0gLTEpIHsKKyAgICBvdXRwdXRfYnVmZmVyX2xlbmd0aF8gPSBrRGVmYXVsdEJ1ZmZlclNpemU7CisgIH0gZWxzZSB7CisgICAgb3V0cHV0X2J1ZmZlcl9sZW5ndGhfID0gYnVmZmVyX3NpemU7CisgIH0KKyAgb3V0cHV0X2J1ZmZlcl8gPSBvcGVyYXRvciBuZXcob3V0cHV0X2J1ZmZlcl9sZW5ndGhfKTsKKyAgR09PR0xFX0NIRUNLKG91dHB1dF9idWZmZXJfICE9IE5VTEwpOworICB6Y29udGV4dF8ubmV4dF9vdXQgPSBzdGF0aWNfY2FzdDxCeXRlZio+KG91dHB1dF9idWZmZXJfKTsKKyAgemNvbnRleHRfLmF2YWlsX291dCA9IG91dHB1dF9idWZmZXJfbGVuZ3RoXzsKKyAgb3V0cHV0X3Bvc2l0aW9uXyA9IG91dHB1dF9idWZmZXJfOworfQorR3ppcElucHV0U3RyZWFtOjp+R3ppcElucHV0U3RyZWFtKCkgeworICBvcGVyYXRvciBkZWxldGUob3V0cHV0X2J1ZmZlcl8pOworICB6ZXJyb3JfID0gaW5mbGF0ZUVuZCgmemNvbnRleHRfKTsKK30KKworc3RhdGljIGlubGluZSBpbnQgaW50ZXJuYWxJbmZsYXRlSW5pdDIoCisgICAgel9zdHJlYW0qIHpjb250ZXh0LCBHemlwSW5wdXRTdHJlYW06OkZvcm1hdCBmb3JtYXQpIHsKKyAgaW50IHdpbmRvd0JpdHNGb3JtYXQgPSAwOworICBzd2l0Y2ggKGZvcm1hdCkgeworICAgIGNhc2UgR3ppcElucHV0U3RyZWFtOjpHWklQOiB3aW5kb3dCaXRzRm9ybWF0ID0gMTY7IGJyZWFrOworICAgIGNhc2UgR3ppcElucHV0U3RyZWFtOjpBVVRPOiB3aW5kb3dCaXRzRm9ybWF0ID0gMzI7IGJyZWFrOworICAgIGNhc2UgR3ppcElucHV0U3RyZWFtOjpaTElCOiB3aW5kb3dCaXRzRm9ybWF0ID0gMDsgYnJlYWs7CisgIH0KKyAgcmV0dXJuIGluZmxhdGVJbml0Mih6Y29udGV4dCwgLyogd2luZG93Qml0cyAqLzE1IHwgd2luZG93Qml0c0Zvcm1hdCk7Cit9CisKK2ludCBHemlwSW5wdXRTdHJlYW06OkluZmxhdGUoaW50IGZsdXNoKSB7CisgIGlmICgoemVycm9yXyA9PSBaX09LKSAmJiAoemNvbnRleHRfLmF2YWlsX291dCA9PSAwKSkgeworICAgIC8vIHByZXZpb3VzIGluZmxhdGUgZmlsbGVkIG91dHB1dCBidWZmZXIuIGRvbid0IGNoYW5nZSBpbnB1dCBwYXJhbXMgeWV0LgorICB9IGVsc2UgaWYgKHpjb250ZXh0Xy5hdmFpbF9pbiA9PSAwKSB7CisgICAgY29uc3Qgdm9pZCogaW47CisgICAgaW50IGluX3NpemU7CisgICAgYm9vbCBmaXJzdCA9IHpjb250ZXh0Xy5uZXh0X2luID09IE5VTEw7CisgICAgYm9vbCBvayA9IHN1Yl9zdHJlYW1fLT5OZXh0KCZpbiwgJmluX3NpemUpOworICAgIGlmICghb2spIHsKKyAgICAgIHpjb250ZXh0Xy5uZXh0X291dCA9IE5VTEw7CisgICAgICB6Y29udGV4dF8uYXZhaWxfb3V0ID0gMDsKKyAgICAgIHJldHVybiBaX1NUUkVBTV9FTkQ7CisgICAgfQorICAgIHpjb250ZXh0Xy5uZXh0X2luID0gc3RhdGljX2Nhc3Q8Qnl0ZWYqPihjb25zdF9jYXN0PHZvaWQqPihpbikpOworICAgIHpjb250ZXh0Xy5hdmFpbF9pbiA9IGluX3NpemU7CisgICAgaWYgKGZpcnN0KSB7CisgICAgICBpbnQgZXJyb3IgPSBpbnRlcm5hbEluZmxhdGVJbml0MigmemNvbnRleHRfLCBmb3JtYXRfKTsKKyAgICAgIGlmIChlcnJvciAhPSBaX09LKSB7CisgICAgICAgIHJldHVybiBlcnJvcjsKKyAgICAgIH0KKyAgICB9CisgIH0KKyAgemNvbnRleHRfLm5leHRfb3V0ID0gc3RhdGljX2Nhc3Q8Qnl0ZWYqPihvdXRwdXRfYnVmZmVyXyk7CisgIHpjb250ZXh0Xy5hdmFpbF9vdXQgPSBvdXRwdXRfYnVmZmVyX2xlbmd0aF87CisgIG91dHB1dF9wb3NpdGlvbl8gPSBvdXRwdXRfYnVmZmVyXzsKKyAgaW50IGVycm9yID0gaW5mbGF0ZSgmemNvbnRleHRfLCBmbHVzaCk7CisgIHJldHVybiBlcnJvcjsKK30KKwordm9pZCBHemlwSW5wdXRTdHJlYW06OkRvTmV4dE91dHB1dChjb25zdCB2b2lkKiogZGF0YSwgaW50KiBzaXplKSB7CisgICpkYXRhID0gb3V0cHV0X3Bvc2l0aW9uXzsKKyAgKnNpemUgPSAoKHVpbnRwdHJfdCl6Y29udGV4dF8ubmV4dF9vdXQpIC0gKCh1aW50cHRyX3Qpb3V0cHV0X3Bvc2l0aW9uXyk7CisgIG91dHB1dF9wb3NpdGlvbl8gPSB6Y29udGV4dF8ubmV4dF9vdXQ7Cit9CisKKy8vIGltcGxlbWVudHMgWmVyb0NvcHlJbnB1dFN0cmVhbSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCitib29sIEd6aXBJbnB1dFN0cmVhbTo6TmV4dChjb25zdCB2b2lkKiogZGF0YSwgaW50KiBzaXplKSB7CisgIGJvb2wgb2sgPSAoemVycm9yXyA9PSBaX09LKSB8fCAoemVycm9yXyA9PSBaX1NUUkVBTV9FTkQpCisgICAgICB8fCAoemVycm9yXyA9PSBaX0JVRl9FUlJPUik7CisgIGlmICgoIW9rKSB8fCAoemNvbnRleHRfLm5leHRfb3V0ID09IE5VTEwpKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIGlmICh6Y29udGV4dF8ubmV4dF9vdXQgIT0gb3V0cHV0X3Bvc2l0aW9uXykgeworICAgIERvTmV4dE91dHB1dChkYXRhLCBzaXplKTsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorICBpZiAoemVycm9yXyA9PSBaX1NUUkVBTV9FTkQpIHsKKyAgICBpZiAoemNvbnRleHRfLm5leHRfb3V0ICE9IE5VTEwpIHsKKyAgICAgIC8vIHN1Yl9zdHJlYW1fIG1heSBoYXZlIGNvbmNhdGVuYXRlZCBzdHJlYW1zIHRvIGZvbGxvdworICAgICAgemVycm9yXyA9IGluZmxhdGVFbmQoJnpjb250ZXh0Xyk7CisgICAgICBieXRlX2NvdW50XyArPSB6Y29udGV4dF8udG90YWxfb3V0OworICAgICAgaWYgKHplcnJvcl8gIT0gWl9PSykgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgICB6ZXJyb3JfID0gaW50ZXJuYWxJbmZsYXRlSW5pdDIoJnpjb250ZXh0XywgZm9ybWF0Xyk7CisgICAgICBpZiAoemVycm9yXyAhPSBaX09LKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgKmRhdGEgPSBOVUxMOworICAgICAgKnNpemUgPSAwOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgfQorICB6ZXJyb3JfID0gSW5mbGF0ZShaX05PX0ZMVVNIKTsKKyAgaWYgKCh6ZXJyb3JfID09IFpfU1RSRUFNX0VORCkgJiYgKHpjb250ZXh0Xy5uZXh0X291dCA9PSBOVUxMKSkgeworICAgIC8vIFRoZSB1bmRlcmx5aW5nIHN0cmVhbSdzIE5leHQgcmV0dXJuZWQgZmFsc2UgaW5zaWRlIEluZmxhdGUuCisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIG9rID0gKHplcnJvcl8gPT0gWl9PSykgfHwgKHplcnJvcl8gPT0gWl9TVFJFQU1fRU5EKQorICAgICAgfHwgKHplcnJvcl8gPT0gWl9CVUZfRVJST1IpOworICBpZiAoIW9rKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIERvTmV4dE91dHB1dChkYXRhLCBzaXplKTsKKyAgcmV0dXJuIHRydWU7Cit9Cit2b2lkIEd6aXBJbnB1dFN0cmVhbTo6QmFja1VwKGludCBjb3VudCkgeworICBvdXRwdXRfcG9zaXRpb25fID0gcmVpbnRlcnByZXRfY2FzdDx2b2lkKj4oCisgICAgICByZWludGVycHJldF9jYXN0PHVpbnRwdHJfdD4ob3V0cHV0X3Bvc2l0aW9uXykgLSBjb3VudCk7Cit9Citib29sIEd6aXBJbnB1dFN0cmVhbTo6U2tpcChpbnQgY291bnQpIHsKKyAgY29uc3Qgdm9pZCogZGF0YTsKKyAgaW50IHNpemU7CisgIGJvb2wgb2sgPSBOZXh0KCZkYXRhLCAmc2l6ZSk7CisgIHdoaWxlIChvayAmJiAoc2l6ZSA8IGNvdW50KSkgeworICAgIGNvdW50IC09IHNpemU7CisgICAgb2sgPSBOZXh0KCZkYXRhLCAmc2l6ZSk7CisgIH0KKyAgaWYgKHNpemUgPiBjb3VudCkgeworICAgIEJhY2tVcChzaXplIC0gY291bnQpOworICB9CisgIHJldHVybiBvazsKK30KK2ludDY0IEd6aXBJbnB1dFN0cmVhbTo6Qnl0ZUNvdW50KCkgY29uc3QgeworICBpbnQ2NCByZXQgPSBieXRlX2NvdW50XyArIHpjb250ZXh0Xy50b3RhbF9vdXQ7CisgIGlmICh6Y29udGV4dF8ubmV4dF9vdXQgIT0gTlVMTCAmJiBvdXRwdXRfcG9zaXRpb25fICE9IE5VTEwpIHsKKyAgICByZXQgKz0gcmVpbnRlcnByZXRfY2FzdDx1aW50cHRyX3Q+KHpjb250ZXh0Xy5uZXh0X291dCkgLQorICAgICAgICAgICByZWludGVycHJldF9jYXN0PHVpbnRwdHJfdD4ob3V0cHV0X3Bvc2l0aW9uXyk7CisgIH0KKyAgcmV0dXJuIHJldDsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitHemlwT3V0cHV0U3RyZWFtOjpPcHRpb25zOjpPcHRpb25zKCkKKyAgICA6IGZvcm1hdChHWklQKSwKKyAgICAgIGJ1ZmZlcl9zaXplKGtEZWZhdWx0QnVmZmVyU2l6ZSksCisgICAgICBjb21wcmVzc2lvbl9sZXZlbChaX0RFRkFVTFRfQ09NUFJFU1NJT04pLAorICAgICAgY29tcHJlc3Npb25fc3RyYXRlZ3koWl9ERUZBVUxUX1NUUkFURUdZKSB7fQorCitHemlwT3V0cHV0U3RyZWFtOjpHemlwT3V0cHV0U3RyZWFtKFplcm9Db3B5T3V0cHV0U3RyZWFtKiBzdWJfc3RyZWFtKSB7CisgIEluaXQoc3ViX3N0cmVhbSwgT3B0aW9ucygpKTsKK30KKworR3ppcE91dHB1dFN0cmVhbTo6R3ppcE91dHB1dFN0cmVhbShaZXJvQ29weU91dHB1dFN0cmVhbSogc3ViX3N0cmVhbSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT3B0aW9ucyYgb3B0aW9ucykgeworICBJbml0KHN1Yl9zdHJlYW0sIG9wdGlvbnMpOworfQorCit2b2lkIEd6aXBPdXRwdXRTdHJlYW06OkluaXQoWmVyb0NvcHlPdXRwdXRTdHJlYW0qIHN1Yl9zdHJlYW0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT3B0aW9ucyYgb3B0aW9ucykgeworICBzdWJfc3RyZWFtXyA9IHN1Yl9zdHJlYW07CisgIHN1Yl9kYXRhXyA9IE5VTEw7CisgIHN1Yl9kYXRhX3NpemVfID0gMDsKKworICBpbnB1dF9idWZmZXJfbGVuZ3RoXyA9IG9wdGlvbnMuYnVmZmVyX3NpemU7CisgIGlucHV0X2J1ZmZlcl8gPSBvcGVyYXRvciBuZXcoaW5wdXRfYnVmZmVyX2xlbmd0aF8pOworICBHT09HTEVfQ0hFQ0soaW5wdXRfYnVmZmVyXyAhPSBOVUxMKTsKKworICB6Y29udGV4dF8uemFsbG9jID0gWl9OVUxMOworICB6Y29udGV4dF8uemZyZWUgPSBaX05VTEw7CisgIHpjb250ZXh0Xy5vcGFxdWUgPSBaX05VTEw7CisgIHpjb250ZXh0Xy5uZXh0X291dCA9IE5VTEw7CisgIHpjb250ZXh0Xy5hdmFpbF9vdXQgPSAwOworICB6Y29udGV4dF8udG90YWxfb3V0ID0gMDsKKyAgemNvbnRleHRfLm5leHRfaW4gPSBOVUxMOworICB6Y29udGV4dF8uYXZhaWxfaW4gPSAwOworICB6Y29udGV4dF8udG90YWxfaW4gPSAwOworICB6Y29udGV4dF8ubXNnID0gTlVMTDsKKyAgLy8gZGVmYXVsdCB0byBHWklQIGZvcm1hdAorICBpbnQgd2luZG93Qml0c0Zvcm1hdCA9IDE2OworICBpZiAob3B0aW9ucy5mb3JtYXQgPT0gWkxJQikgeworICAgIHdpbmRvd0JpdHNGb3JtYXQgPSAwOworICB9CisgIHplcnJvcl8gPSBkZWZsYXRlSW5pdDIoCisgICAgICAmemNvbnRleHRfLAorICAgICAgb3B0aW9ucy5jb21wcmVzc2lvbl9sZXZlbCwKKyAgICAgIFpfREVGTEFURUQsCisgICAgICAvKiB3aW5kb3dCaXRzICovMTUgfCB3aW5kb3dCaXRzRm9ybWF0LAorICAgICAgLyogbWVtTGV2ZWwgKGRlZmF1bHQpICovOCwKKyAgICAgIG9wdGlvbnMuY29tcHJlc3Npb25fc3RyYXRlZ3kpOworfQorCitHemlwT3V0cHV0U3RyZWFtOjp+R3ppcE91dHB1dFN0cmVhbSgpIHsKKyAgQ2xvc2UoKTsKKyAgaWYgKGlucHV0X2J1ZmZlcl8gIT0gTlVMTCkgeworICAgIG9wZXJhdG9yIGRlbGV0ZShpbnB1dF9idWZmZXJfKTsKKyAgfQorfQorCisvLyBwcml2YXRlCitpbnQgR3ppcE91dHB1dFN0cmVhbTo6RGVmbGF0ZShpbnQgZmx1c2gpIHsKKyAgaW50IGVycm9yID0gWl9PSzsKKyAgZG8geworICAgIGlmICgoc3ViX2RhdGFfID09IE5VTEwpIHx8ICh6Y29udGV4dF8uYXZhaWxfb3V0ID09IDApKSB7CisgICAgICBib29sIG9rID0gc3ViX3N0cmVhbV8tPk5leHQoJnN1Yl9kYXRhXywgJnN1Yl9kYXRhX3NpemVfKTsKKyAgICAgIGlmICghb2spIHsKKyAgICAgICAgc3ViX2RhdGFfID0gTlVMTDsKKyAgICAgICAgc3ViX2RhdGFfc2l6ZV8gPSAwOworICAgICAgICByZXR1cm4gWl9CVUZfRVJST1I7CisgICAgICB9CisgICAgICBHT09HTEVfQ0hFQ0tfR1Qoc3ViX2RhdGFfc2l6ZV8sIDApOworICAgICAgemNvbnRleHRfLm5leHRfb3V0ID0gc3RhdGljX2Nhc3Q8Qnl0ZWYqPihzdWJfZGF0YV8pOworICAgICAgemNvbnRleHRfLmF2YWlsX291dCA9IHN1Yl9kYXRhX3NpemVfOworICAgIH0KKyAgICBlcnJvciA9IGRlZmxhdGUoJnpjb250ZXh0XywgZmx1c2gpOworICB9IHdoaWxlIChlcnJvciA9PSBaX09LICYmIHpjb250ZXh0Xy5hdmFpbF9vdXQgPT0gMCk7CisgIGlmICgoZmx1c2ggPT0gWl9GVUxMX0ZMVVNIKSB8fCAoZmx1c2ggPT0gWl9GSU5JU0gpKSB7CisgICAgLy8gTm90aWZ5IGxvd2VyIGxheWVyIG9mIGRhdGEuCisgICAgc3ViX3N0cmVhbV8tPkJhY2tVcCh6Y29udGV4dF8uYXZhaWxfb3V0KTsKKyAgICAvLyBXZSBkb24ndCBvd24gdGhlIGJ1ZmZlciBhbnltb3JlLgorICAgIHN1Yl9kYXRhXyA9IE5VTEw7CisgICAgc3ViX2RhdGFfc2l6ZV8gPSAwOworICB9CisgIHJldHVybiBlcnJvcjsKK30KKworLy8gaW1wbGVtZW50cyBaZXJvQ29weU91dHB1dFN0cmVhbSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK2Jvb2wgR3ppcE91dHB1dFN0cmVhbTo6TmV4dCh2b2lkKiogZGF0YSwgaW50KiBzaXplKSB7CisgIGlmICgoemVycm9yXyAhPSBaX09LKSAmJiAoemVycm9yXyAhPSBaX0JVRl9FUlJPUikpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgaWYgKHpjb250ZXh0Xy5hdmFpbF9pbiAhPSAwKSB7CisgICAgemVycm9yXyA9IERlZmxhdGUoWl9OT19GTFVTSCk7CisgICAgaWYgKHplcnJvcl8gIT0gWl9PSykgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgfQorICBpZiAoemNvbnRleHRfLmF2YWlsX2luID09IDApIHsKKyAgICAvLyBhbGwgaW5wdXQgd2FzIGNvbnN1bWVkLiByZXNldCB0aGUgYnVmZmVyLgorICAgIHpjb250ZXh0Xy5uZXh0X2luID0gc3RhdGljX2Nhc3Q8Qnl0ZWYqPihpbnB1dF9idWZmZXJfKTsKKyAgICB6Y29udGV4dF8uYXZhaWxfaW4gPSBpbnB1dF9idWZmZXJfbGVuZ3RoXzsKKyAgICAqZGF0YSA9IGlucHV0X2J1ZmZlcl87CisgICAgKnNpemUgPSBpbnB1dF9idWZmZXJfbGVuZ3RoXzsKKyAgfSBlbHNlIHsKKyAgICAvLyBUaGUgbG9vcCBpbiBEZWZsYXRlIHNob3VsZCBjb25zdW1lIGFsbCBhdmFpbF9pbgorICAgIEdPT0dMRV9MT0coREZBVEFMKSA8PCAiRGVmbGF0ZSBsZWZ0IGJ5dGVzIHVuY29uc3VtZWQiOworICB9CisgIHJldHVybiB0cnVlOworfQordm9pZCBHemlwT3V0cHV0U3RyZWFtOjpCYWNrVXAoaW50IGNvdW50KSB7CisgIEdPT0dMRV9DSEVDS19HRSh6Y29udGV4dF8uYXZhaWxfaW4sIGNvdW50KTsKKyAgemNvbnRleHRfLmF2YWlsX2luIC09IGNvdW50OworfQoraW50NjQgR3ppcE91dHB1dFN0cmVhbTo6Qnl0ZUNvdW50KCkgY29uc3QgeworICByZXR1cm4gemNvbnRleHRfLnRvdGFsX2luICsgemNvbnRleHRfLmF2YWlsX2luOworfQorCitib29sIEd6aXBPdXRwdXRTdHJlYW06OkZsdXNoKCkgeworICB6ZXJyb3JfID0gRGVmbGF0ZShaX0ZVTExfRkxVU0gpOworICAvLyBSZXR1cm4gdHJ1ZSBpZiB0aGUgZmx1c2ggc3VjY2VlZGVkIG9yIGlmIGl0IHdhcyBhIG5vLW9wLgorICByZXR1cm4gICh6ZXJyb3JfID09IFpfT0spIHx8CisgICAgICAoemVycm9yXyA9PSBaX0JVRl9FUlJPUiAmJiB6Y29udGV4dF8uYXZhaWxfaW4gPT0gMCAmJgorICAgICAgIHpjb250ZXh0Xy5hdmFpbF9vdXQgIT0gMCk7Cit9CisKK2Jvb2wgR3ppcE91dHB1dFN0cmVhbTo6Q2xvc2UoKSB7CisgIGlmICgoemVycm9yXyAhPSBaX09LKSAmJiAoemVycm9yXyAhPSBaX0JVRl9FUlJPUikpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgZG8geworICAgIHplcnJvcl8gPSBEZWZsYXRlKFpfRklOSVNIKTsKKyAgfSB3aGlsZSAoemVycm9yXyA9PSBaX09LKTsKKyAgemVycm9yXyA9IGRlZmxhdGVFbmQoJnpjb250ZXh0Xyk7CisgIGJvb2wgb2sgPSB6ZXJyb3JfID09IFpfT0s7CisgIHplcnJvcl8gPSBaX1NUUkVBTV9FTkQ7CisgIHJldHVybiBvazsKK30KKworfSAgLy8gbmFtZXNwYWNlIGlvCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI2VuZGlmICAvLyBIQVZFX1pMSUIKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vZ3ppcF9zdHJlYW0uaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vZ3ppcF9zdHJlYW0uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MjQ0NTAwCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby9nemlwX3N0cmVhbS5oCkBAIC0wLDAgKzEsMjEwIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBicmlhbm9sc29uQGdvb2dsZS5jb20gKEJyaWFuIE9sc29uKQorLy8KKy8vIFRoaXMgZmlsZSBjb250YWlucyB0aGUgZGVmaW5pdGlvbiBmb3IgY2xhc3NlcyBHemlwSW5wdXRTdHJlYW0gYW5kCisvLyBHemlwT3V0cHV0U3RyZWFtLgorLy8KKy8vIEd6aXBJbnB1dFN0cmVhbSBkZWNvbXByZXNzZXMgZGF0YSBmcm9tIGFuIHVuZGVybHlpbmcKKy8vIFplcm9Db3B5SW5wdXRTdHJlYW0gYW5kIHByb3ZpZGVzIHRoZSBkZWNvbXByZXNzZWQgZGF0YSBhcyBhCisvLyBaZXJvQ29weUlucHV0U3RyZWFtLgorLy8KKy8vIEd6aXBPdXRwdXRTdHJlYW0gaXMgYW4gWmVyb0NvcHlPdXRwdXRTdHJlYW0gdGhhdCBjb21wcmVzc2VzIGRhdGEgdG8KKy8vIGFuIHVuZGVybHlpbmcgWmVyb0NvcHlPdXRwdXRTdHJlYW0uCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0lPX0daSVBfU1RSRUFNX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfSU9fR1pJUF9TVFJFQU1fSF9fCisKKyNpbmNsdWRlIDx6bGliLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW0uaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGlvIHsKKworLy8gQSBaZXJvQ29weUlucHV0U3RyZWFtIHRoYXQgcmVhZHMgY29tcHJlc3NlZCBkYXRhIHRocm91Z2ggemxpYgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEd6aXBJbnB1dFN0cmVhbSA6IHB1YmxpYyBaZXJvQ29weUlucHV0U3RyZWFtIHsKKyBwdWJsaWM6CisgIC8vIEZvcm1hdCBrZXkgZm9yIGNvbnN0cnVjdG9yCisgIGVudW0gRm9ybWF0IHsKKyAgICAvLyB6bGliIHdpbGwgYXV0b2RldGVjdCBnemlwIGhlYWRlciBvciBkZWZsYXRlIHN0cmVhbQorICAgIEFVVE8gPSAwLAorCisgICAgLy8gR1pJUCBzdHJlYW1zIGhhdmUgc29tZSBleHRyYSBoZWFkZXIgZGF0YSBmb3IgZmlsZSBhdHRyaWJ1dGVzLgorICAgIEdaSVAgPSAxLAorCisgICAgLy8gU2ltcGxlciB6bGliIHN0cmVhbSBmb3JtYXQuCisgICAgWkxJQiA9IDIsCisgIH07CisKKyAgLy8gYnVmZmVyX3NpemUgYW5kIGZvcm1hdCBtYXkgYmUgLTEgZm9yIGRlZmF1bHQgb2YgNjRrQiBhbmQgR1pJUCBmb3JtYXQKKyAgZXhwbGljaXQgR3ppcElucHV0U3RyZWFtKAorICAgICAgWmVyb0NvcHlJbnB1dFN0cmVhbSogc3ViX3N0cmVhbSwKKyAgICAgIEZvcm1hdCBmb3JtYXQgPSBBVVRPLAorICAgICAgaW50IGJ1ZmZlcl9zaXplID0gLTEpOworICB2aXJ0dWFsIH5HemlwSW5wdXRTdHJlYW0oKTsKKworICAvLyBSZXR1cm4gbGFzdCBlcnJvciBtZXNzYWdlIG9yIE5VTEwgaWYgbm8gZXJyb3IuCisgIGlubGluZSBjb25zdCBjaGFyKiBabGliRXJyb3JNZXNzYWdlKCkgY29uc3QgeworICAgIHJldHVybiB6Y29udGV4dF8ubXNnOworICB9CisgIGlubGluZSBpbnQgWmxpYkVycm9yQ29kZSgpIGNvbnN0IHsKKyAgICByZXR1cm4gemVycm9yXzsKKyAgfQorCisgIC8vIGltcGxlbWVudHMgWmVyb0NvcHlJbnB1dFN0cmVhbSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIGJvb2wgTmV4dChjb25zdCB2b2lkKiogZGF0YSwgaW50KiBzaXplKTsKKyAgdm9pZCBCYWNrVXAoaW50IGNvdW50KTsKKyAgYm9vbCBTa2lwKGludCBjb3VudCk7CisgIGludDY0IEJ5dGVDb3VudCgpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgRm9ybWF0IGZvcm1hdF87CisKKyAgWmVyb0NvcHlJbnB1dFN0cmVhbSogc3ViX3N0cmVhbV87CisKKyAgel9zdHJlYW0gemNvbnRleHRfOworICBpbnQgemVycm9yXzsKKworICB2b2lkKiBvdXRwdXRfYnVmZmVyXzsKKyAgdm9pZCogb3V0cHV0X3Bvc2l0aW9uXzsKKyAgc2l6ZV90IG91dHB1dF9idWZmZXJfbGVuZ3RoXzsKKyAgaW50NjQgYnl0ZV9jb3VudF87CisKKyAgaW50IEluZmxhdGUoaW50IGZsdXNoKTsKKyAgdm9pZCBEb05leHRPdXRwdXQoY29uc3Qgdm9pZCoqIGRhdGEsIGludCogc2l6ZSk7CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEd6aXBJbnB1dFN0cmVhbSk7Cit9OworCisKK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBHemlwT3V0cHV0U3RyZWFtIDogcHVibGljIFplcm9Db3B5T3V0cHV0U3RyZWFtIHsKKyBwdWJsaWM6CisgIC8vIEZvcm1hdCBrZXkgZm9yIGNvbnN0cnVjdG9yCisgIGVudW0gRm9ybWF0IHsKKyAgICAvLyBHWklQIHN0cmVhbXMgaGF2ZSBzb21lIGV4dHJhIGhlYWRlciBkYXRhIGZvciBmaWxlIGF0dHJpYnV0ZXMuCisgICAgR1pJUCA9IDEsCisKKyAgICAvLyBTaW1wbGVyIHpsaWIgc3RyZWFtIGZvcm1hdC4KKyAgICBaTElCID0gMiwKKyAgfTsKKworICBzdHJ1Y3QgT3B0aW9ucyB7CisgICAgLy8gRGVmYXVsdHMgdG8gR1pJUC4KKyAgICBGb3JtYXQgZm9ybWF0OworCisgICAgLy8gV2hhdCBzaXplIGJ1ZmZlciB0byB1c2UgaW50ZXJuYWxseS4gIERlZmF1bHRzIHRvIDY0a0IuCisgICAgaW50IGJ1ZmZlcl9zaXplOworCisgICAgLy8gQSBudW1iZXIgYmV0d2VlbiAwIGFuZCA5LCB3aGVyZSAwIGlzIG5vIGNvbXByZXNzaW9uIGFuZCA5IGlzIGJlc3QKKyAgICAvLyBjb21wcmVzc2lvbi4gIERlZmF1bHRzIHRvIFpfREVGQVVMVF9DT01QUkVTU0lPTiAoc2VlIHpsaWIuaCkuCisgICAgaW50IGNvbXByZXNzaW9uX2xldmVsOworCisgICAgLy8gRGVmYXVsdHMgdG8gWl9ERUZBVUxUX1NUUkFURUdZLiAgQ2FuIGFsc28gYmUgc2V0IHRvIFpfRklMVEVSRUQsCisgICAgLy8gWl9IVUZGTUFOX09OTFksIG9yIFpfUkxFLiAgU2VlIHRoZSBkb2N1bWVudGF0aW9uIGZvciBkZWZsYXRlSW5pdDIgaW4KKyAgICAvLyB6bGliLmggZm9yIGRlZmluaXRpb25zIG9mIHRoZXNlIGNvbnN0YW50cy4KKyAgICBpbnQgY29tcHJlc3Npb25fc3RyYXRlZ3k7CisKKyAgICBPcHRpb25zKCk7ICAvLyBJbml0aWFsaXplcyB3aXRoIGRlZmF1bHQgdmFsdWVzLgorICB9OworCisgIC8vIENyZWF0ZSBhIEd6aXBPdXRwdXRTdHJlYW0gd2l0aCBkZWZhdWx0IG9wdGlvbnMuCisgIGV4cGxpY2l0IEd6aXBPdXRwdXRTdHJlYW0oWmVyb0NvcHlPdXRwdXRTdHJlYW0qIHN1Yl9zdHJlYW0pOworCisgIC8vIENyZWF0ZSBhIEd6aXBPdXRwdXRTdHJlYW0gd2l0aCB0aGUgZ2l2ZW4gb3B0aW9ucy4KKyAgR3ppcE91dHB1dFN0cmVhbSgKKyAgICAgIFplcm9Db3B5T3V0cHV0U3RyZWFtKiBzdWJfc3RyZWFtLAorICAgICAgY29uc3QgT3B0aW9ucyYgb3B0aW9ucyk7CisKKyAgdmlydHVhbCB+R3ppcE91dHB1dFN0cmVhbSgpOworCisgIC8vIFJldHVybiBsYXN0IGVycm9yIG1lc3NhZ2Ugb3IgTlVMTCBpZiBubyBlcnJvci4KKyAgaW5saW5lIGNvbnN0IGNoYXIqIFpsaWJFcnJvck1lc3NhZ2UoKSBjb25zdCB7CisgICAgcmV0dXJuIHpjb250ZXh0Xy5tc2c7CisgIH0KKyAgaW5saW5lIGludCBabGliRXJyb3JDb2RlKCkgY29uc3QgeworICAgIHJldHVybiB6ZXJyb3JfOworICB9CisKKyAgLy8gRmx1c2hlcyBkYXRhIHdyaXR0ZW4gc28gZmFyIHRvIHppcHBlZCBkYXRhIGluIHRoZSB1bmRlcmx5aW5nIHN0cmVhbS4KKyAgLy8gSXQgaXMgdGhlIGNhbGxlcidzIHJlc3BvbnNpYmlsaXR5IHRvIGZsdXNoIHRoZSB1bmRlcmx5aW5nIHN0cmVhbSBpZgorICAvLyBuZWNlc3NhcnkuCisgIC8vIENvbXByZXNzaW9uIG1heSBiZSBsZXNzIGVmZmljaWVudCBzdG9wcGluZyBhbmQgc3RhcnRpbmcgYXJvdW5kIGZsdXNoZXMuCisgIC8vIFJldHVybnMgdHJ1ZSBpZiBubyBlcnJvci4KKyAgLy8KKyAgLy8gUGxlYXNlIGVuc3VyZSB0aGF0IGJsb2NrIHNpemUgaXMgPiA2LiBIZXJlIGlzIGFuIGV4Y2VycHQgZnJvbSB0aGUgemxpYgorICAvLyBkb2MgdGhhdCBleHBsYWlucyB3aHk6CisgIC8vCisgIC8vIEluIHRoZSBjYXNlIG9mIGEgWl9GVUxMX0ZMVVNIIG9yIFpfU1lOQ19GTFVTSCwgbWFrZSBzdXJlIHRoYXQgYXZhaWxfb3V0CisgIC8vIGlzIGdyZWF0ZXIgdGhhbiBzaXggdG8gYXZvaWQgcmVwZWF0ZWQgZmx1c2ggbWFya2VycyBkdWUgdG8KKyAgLy8gYXZhaWxfb3V0ID09IDAgb24gcmV0dXJuLgorICBib29sIEZsdXNoKCk7CisKKyAgLy8gV3JpdGVzIG91dCBhbGwgZGF0YSBhbmQgY2xvc2VzIHRoZSBnemlwIHN0cmVhbS4KKyAgLy8gSXQgaXMgdGhlIGNhbGxlcidzIHJlc3BvbnNpYmlsaXR5IHRvIGNsb3NlIHRoZSB1bmRlcmx5aW5nIHN0cmVhbSBpZgorICAvLyBuZWNlc3NhcnkuCisgIC8vIFJldHVybnMgdHJ1ZSBpZiBubyBlcnJvci4KKyAgYm9vbCBDbG9zZSgpOworCisgIC8vIGltcGxlbWVudHMgWmVyb0NvcHlPdXRwdXRTdHJlYW0gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIGJvb2wgTmV4dCh2b2lkKiogZGF0YSwgaW50KiBzaXplKTsKKyAgdm9pZCBCYWNrVXAoaW50IGNvdW50KTsKKyAgaW50NjQgQnl0ZUNvdW50KCkgY29uc3Q7CisKKyBwcml2YXRlOgorICBaZXJvQ29weU91dHB1dFN0cmVhbSogc3ViX3N0cmVhbV87CisgIC8vIFJlc3VsdCBmcm9tIGNhbGxpbmcgTmV4dCgpIG9uIHN1Yl9zdHJlYW1fCisgIHZvaWQqIHN1Yl9kYXRhXzsKKyAgaW50IHN1Yl9kYXRhX3NpemVfOworCisgIHpfc3RyZWFtIHpjb250ZXh0XzsKKyAgaW50IHplcnJvcl87CisgIHZvaWQqIGlucHV0X2J1ZmZlcl87CisgIHNpemVfdCBpbnB1dF9idWZmZXJfbGVuZ3RoXzsKKworICAvLyBTaGFyZWQgY29uc3RydWN0b3IgY29kZS4KKyAgdm9pZCBJbml0KFplcm9Db3B5T3V0cHV0U3RyZWFtKiBzdWJfc3RyZWFtLCBjb25zdCBPcHRpb25zJiBvcHRpb25zKTsKKworICAvLyBEbyBzb21lIGNvbXByZXNzaW9uLgorICAvLyBUYWtlcyB6bGliIGZsdXNoIG1vZGUuCisgIC8vIFJldHVybnMgemxpYiBlcnJvciBjb2RlLgorICBpbnQgRGVmbGF0ZShpbnQgZmx1c2gpOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhHemlwT3V0cHV0U3RyZWFtKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBpbworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0lPX0daSVBfU1RSRUFNX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby9nemlwX3N0cmVhbV91bml0dGVzdC5zaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vZ3ppcF9zdHJlYW1fdW5pdHRlc3Quc2gKbmV3IGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMDAwMDAwMC4uMTYyNTFhOQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vZ3ppcF9zdHJlYW1fdW5pdHRlc3Quc2gKQEAgLTAsMCArMSw0NCBAQAorIyEvYmluL3NoIC14CisjCisjIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorIyBDb3B5cmlnaHQgMjAwOSBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyMgaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKyMKKyMgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisjIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKyMgbWV0OgorIworIyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorIyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisjICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKyMgY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorIyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisjIGRpc3RyaWJ1dGlvbi4KKyMgICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworIyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorIyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorIworIyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisjICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisjIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorIyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorIyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKyMgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorIyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKyMgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisjIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKyMgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisjIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisjCisjIEF1dGhvcjogYnJpYW5vbHNvbkBnb29nbGUuY29tIChCcmlhbiBPbHNvbikKKyMKKyMgVGVzdCBjb21wYXRpYmlsaXR5IGJldHdlZW4gY29tbWFuZCBsaW5lIGd6aXAvZ3VuemlwIGJpbmFyaWVzIGFuZAorIyBaZXJvQ29weVN0cmVhbSB2ZXJzaW9ucy4KKworVEVTVEZJTEU9TWFrZWZpbGUKKworKC4vemNnemlwIDwgJHtURVNURklMRX0gfCBndW56aXAgfCBjbXAgLSAke1RFU1RGSUxFfSkgJiYgXAorKGd6aXAgPCAke1RFU1RGSUxFfSB8IC4vemNndW56aXAgfCBjbXAgLSAke1RFU1RGSUxFfSkKKworIyBSZXN1bHQgb2YgIihjbWQpICYmIChjbWQpIiBpbXBsaWNpdGx5IGJlY29tZXMgcmVzdWx0IG9mIHRoaXMgc2NyaXB0CisjIGFuZCB0aHVzIHRoZSB0ZXN0LgpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby9wYWNrYWdlX2luZm8uaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vcGFja2FnZV9pbmZvLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGMxZmM5MQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vcGFja2FnZV9pbmZvLmgKQEAgLTAsMCArMSw1NCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorLy8KKy8vIFRoaXMgZmlsZSBleGlzdHMgc29sZWx5IHRvIGRvY3VtZW50IHRoZSBnb29nbGU6OnByb3RvYnVmOjppbyBuYW1lc3BhY2UuCisvLyBJdCBpcyBub3QgY29tcGlsZWQgaW50byBhbnl0aGluZywgYnV0IGl0IG1heSBiZSByZWFkIGJ5IGFuIGF1dG9tYXRlZAorLy8gZG9jdW1lbnRhdGlvbiBnZW5lcmF0b3IuCisKK25hbWVzcGFjZSBnb29nbGUgeworCituYW1lc3BhY2UgcHJvdG9idWYgeworCisvLyBBdXhpbGlhcnkgY2xhc3NlcyB1c2VkIGZvciBJL08uCisvLworLy8gVGhlIFByb3RvY29sIEJ1ZmZlciBsaWJyYXJ5IHVzZXMgdGhlIGNsYXNzZXMgaW4gdGhpcyBwYWNrYWdlIHRvIGRlYWwgd2l0aAorLy8gSS9PIGFuZCBlbmNvZGluZy9kZWNvZGluZyByYXcgYnl0ZXMuICBNb3N0IHVzZXJzIHdpbGwgbm90IG5lZWQgdG8KKy8vIGRlYWwgd2l0aCB0aGlzIHBhY2thZ2UuICBIb3dldmVyLCB1c2VycyB3aG8gd2FudCB0byBhZGFwdCB0aGUgc3lzdGVtIHRvCisvLyB3b3JrIHdpdGggdGhlaXIgb3duIEkvTyBhYnN0cmFjdGlvbnMgLS0gZS5nLiwgdG8gYWxsb3cgUHJvdG9jb2wgQnVmZmVycworLy8gdG8gYmUgcmVhZCBmcm9tIGEgZGlmZmVyZW50IGtpbmQgb2YgaW5wdXQgc3RyZWFtIHdpdGhvdXQgdGhlIG5lZWQgZm9yIGEKKy8vIHRlbXBvcmFyeSBidWZmZXIgLS0gc2hvdWxkIHRha2UgYSBjbG9zZXIgbG9vay4KK25hbWVzcGFjZSBpbyB7fQorCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ZDg4NjUwCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmNjCkBAIC0wLDAgKzEsMjg0IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2xvZ2dpbmcuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbyB7CisKK1ByaW50ZXI6OlByaW50ZXIoWmVyb0NvcHlPdXRwdXRTdHJlYW0qIG91dHB1dCwgY2hhciB2YXJpYWJsZV9kZWxpbWl0ZXIpCisgIDogdmFyaWFibGVfZGVsaW1pdGVyXyh2YXJpYWJsZV9kZWxpbWl0ZXIpLAorICAgIG91dHB1dF8ob3V0cHV0KSwKKyAgICBidWZmZXJfKE5VTEwpLAorICAgIGJ1ZmZlcl9zaXplXygwKSwKKyAgICBhdF9zdGFydF9vZl9saW5lXyh0cnVlKSwKKyAgICBmYWlsZWRfKGZhbHNlKSB7Cit9CisKK1ByaW50ZXI6On5QcmludGVyKCkgeworICAvLyBPbmx5IEJhY2tVcCgpIGlmIHdlIGhhdmUgY2FsbGVkIE5leHQoKSBhdCBsZWFzdCBvbmNlIGFuZCBuZXZlciBmYWlsZWQuCisgIGlmIChidWZmZXJfc2l6ZV8gPiAwICYmICFmYWlsZWRfKSB7CisgICAgb3V0cHV0Xy0+QmFja1VwKGJ1ZmZlcl9zaXplXyk7CisgIH0KK30KKwordm9pZCBQcmludGVyOjpQcmludChjb25zdCBtYXA8c3RyaW5nLCBzdHJpbmc+JiB2YXJpYWJsZXMsIGNvbnN0IGNoYXIqIHRleHQpIHsKKyAgaW50IHNpemUgPSBzdHJsZW4odGV4dCk7CisgIGludCBwb3MgPSAwOyAgLy8gVGhlIG51bWJlciBvZiBieXRlcyB3ZSd2ZSB3cml0dGVuIHNvIGZhci4KKworICBmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgeworICAgIGlmICh0ZXh0W2ldID09ICdcbicpIHsKKyAgICAgIC8vIFNhdyBuZXdsaW5lLiAgSWYgdGhlcmUgaXMgbW9yZSB0ZXh0LCB3ZSBtYXkgbmVlZCB0byBpbnNlcnQgYW4gaW5kZW50CisgICAgICAvLyBoZXJlLiAgU28sIHdyaXRlIHdoYXQgd2UgaGF2ZSBzbyBmYXIsIGluY2x1ZGluZyB0aGUgJ1xuJy4KKyAgICAgIFdyaXRlUmF3KHRleHQgKyBwb3MsIGkgLSBwb3MgKyAxKTsKKyAgICAgIHBvcyA9IGkgKyAxOworCisgICAgICAvLyBTZXR0aW5nIHRoaXMgdHJ1ZSB3aWxsIGNhdXNlIHRoZSBuZXh0IFdyaXRlUmF3KCkgdG8gaW5zZXJ0IGFuIGluZGVudAorICAgICAgLy8gZmlyc3QuCisgICAgICBhdF9zdGFydF9vZl9saW5lXyA9IHRydWU7CisKKyAgICB9IGVsc2UgaWYgKHRleHRbaV0gPT0gdmFyaWFibGVfZGVsaW1pdGVyXykgeworICAgICAgLy8gU2F3IHRoZSBzdGFydCBvZiBhIHZhcmlhYmxlIG5hbWUuCisKKyAgICAgIC8vIFdyaXRlIHdoYXQgd2UgaGF2ZSBzbyBmYXIuCisgICAgICBXcml0ZVJhdyh0ZXh0ICsgcG9zLCBpIC0gcG9zKTsKKyAgICAgIHBvcyA9IGkgKyAxOworCisgICAgICAvLyBGaW5kIGNsb3NpbmcgZGVsaW1pdGVyLgorICAgICAgY29uc3QgY2hhciogZW5kID0gc3RyY2hyKHRleHQgKyBwb3MsIHZhcmlhYmxlX2RlbGltaXRlcl8pOworICAgICAgaWYgKGVuZCA9PSBOVUxMKSB7CisgICAgICAgIEdPT0dMRV9MT0coREZBVEFMKSA8PCAiIFVuY2xvc2VkIHZhcmlhYmxlIG5hbWUuIjsKKyAgICAgICAgZW5kID0gdGV4dCArIHBvczsKKyAgICAgIH0KKyAgICAgIGludCBlbmRwb3MgPSBlbmQgLSB0ZXh0OworCisgICAgICBzdHJpbmcgdmFybmFtZSh0ZXh0ICsgcG9zLCBlbmRwb3MgLSBwb3MpOworICAgICAgaWYgKHZhcm5hbWUuZW1wdHkoKSkgeworICAgICAgICAvLyBUd28gZGVsaW1pdGVycyBpbiBhIHJvdyByZWR1Y2UgdG8gYSBsaXRlcmFsIGRlbGltaXRlciBjaGFyYWN0ZXIuCisgICAgICAgIFdyaXRlUmF3KCZ2YXJpYWJsZV9kZWxpbWl0ZXJfLCAxKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIC8vIFJlcGxhY2Ugd2l0aCB0aGUgdmFyaWFibGUncyB2YWx1ZS4KKyAgICAgICAgbWFwPHN0cmluZywgc3RyaW5nPjo6Y29uc3RfaXRlcmF0b3IgaXRlciA9IHZhcmlhYmxlcy5maW5kKHZhcm5hbWUpOworICAgICAgICBpZiAoaXRlciA9PSB2YXJpYWJsZXMuZW5kKCkpIHsKKyAgICAgICAgICBHT09HTEVfTE9HKERGQVRBTCkgPDwgIiBVbmRlZmluZWQgdmFyaWFibGU6ICIgPDwgdmFybmFtZTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBXcml0ZVJhdyhpdGVyLT5zZWNvbmQuZGF0YSgpLCBpdGVyLT5zZWNvbmQuc2l6ZSgpKTsKKyAgICAgICAgfQorICAgICAgfQorCisgICAgICAvLyBBZHZhbmNlIHBhc3QgdGhpcyB2YXJpYWJsZS4KKyAgICAgIGkgPSBlbmRwb3M7CisgICAgICBwb3MgPSBlbmRwb3MgKyAxOworICAgIH0KKyAgfQorCisgIC8vIFdyaXRlIHRoZSByZXN0LgorICBXcml0ZVJhdyh0ZXh0ICsgcG9zLCBzaXplIC0gcG9zKTsKK30KKwordm9pZCBQcmludGVyOjpQcmludChjb25zdCBjaGFyKiB0ZXh0KSB7CisgIHN0YXRpYyBtYXA8c3RyaW5nLCBzdHJpbmc+IGVtcHR5OworICBQcmludChlbXB0eSwgdGV4dCk7Cit9CisKK3ZvaWQgUHJpbnRlcjo6UHJpbnQoY29uc3QgY2hhciogdGV4dCwKKyAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogdmFyaWFibGUsIGNvbnN0IHN0cmluZyYgdmFsdWUpIHsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJzOworICB2YXJzW3ZhcmlhYmxlXSA9IHZhbHVlOworICBQcmludCh2YXJzLCB0ZXh0KTsKK30KKwordm9pZCBQcmludGVyOjpQcmludChjb25zdCBjaGFyKiB0ZXh0LAorICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTEsIGNvbnN0IHN0cmluZyYgdmFsdWUxLAorICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTIsIGNvbnN0IHN0cmluZyYgdmFsdWUyKSB7CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyczsKKyAgdmFyc1t2YXJpYWJsZTFdID0gdmFsdWUxOworICB2YXJzW3ZhcmlhYmxlMl0gPSB2YWx1ZTI7CisgIFByaW50KHZhcnMsIHRleHQpOworfQorCit2b2lkIFByaW50ZXI6OlByaW50KGNvbnN0IGNoYXIqIHRleHQsCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIHZhcmlhYmxlMSwgY29uc3Qgc3RyaW5nJiB2YWx1ZTEsCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIHZhcmlhYmxlMiwgY29uc3Qgc3RyaW5nJiB2YWx1ZTIsCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIHZhcmlhYmxlMywgY29uc3Qgc3RyaW5nJiB2YWx1ZTMpIHsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJzOworICB2YXJzW3ZhcmlhYmxlMV0gPSB2YWx1ZTE7CisgIHZhcnNbdmFyaWFibGUyXSA9IHZhbHVlMjsKKyAgdmFyc1t2YXJpYWJsZTNdID0gdmFsdWUzOworICBQcmludCh2YXJzLCB0ZXh0KTsKK30KKwordm9pZCBQcmludGVyOjpQcmludChjb25zdCBjaGFyKiB0ZXh0LAorICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTEsIGNvbnN0IHN0cmluZyYgdmFsdWUxLAorICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTIsIGNvbnN0IHN0cmluZyYgdmFsdWUyLAorICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTMsIGNvbnN0IHN0cmluZyYgdmFsdWUzLAorICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTQsIGNvbnN0IHN0cmluZyYgdmFsdWU0KSB7CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyczsKKyAgdmFyc1t2YXJpYWJsZTFdID0gdmFsdWUxOworICB2YXJzW3ZhcmlhYmxlMl0gPSB2YWx1ZTI7CisgIHZhcnNbdmFyaWFibGUzXSA9IHZhbHVlMzsKKyAgdmFyc1t2YXJpYWJsZTRdID0gdmFsdWU0OworICBQcmludCh2YXJzLCB0ZXh0KTsKK30KKwordm9pZCBQcmludGVyOjpQcmludChjb25zdCBjaGFyKiB0ZXh0LAorICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTEsIGNvbnN0IHN0cmluZyYgdmFsdWUxLAorICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTIsIGNvbnN0IHN0cmluZyYgdmFsdWUyLAorICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTMsIGNvbnN0IHN0cmluZyYgdmFsdWUzLAorICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTQsIGNvbnN0IHN0cmluZyYgdmFsdWU0LAorICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTUsIGNvbnN0IHN0cmluZyYgdmFsdWU1KSB7CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyczsKKyAgdmFyc1t2YXJpYWJsZTFdID0gdmFsdWUxOworICB2YXJzW3ZhcmlhYmxlMl0gPSB2YWx1ZTI7CisgIHZhcnNbdmFyaWFibGUzXSA9IHZhbHVlMzsKKyAgdmFyc1t2YXJpYWJsZTRdID0gdmFsdWU0OworICB2YXJzW3ZhcmlhYmxlNV0gPSB2YWx1ZTU7CisgIFByaW50KHZhcnMsIHRleHQpOworfQorCit2b2lkIFByaW50ZXI6OlByaW50KGNvbnN0IGNoYXIqIHRleHQsCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIHZhcmlhYmxlMSwgY29uc3Qgc3RyaW5nJiB2YWx1ZTEsCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIHZhcmlhYmxlMiwgY29uc3Qgc3RyaW5nJiB2YWx1ZTIsCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIHZhcmlhYmxlMywgY29uc3Qgc3RyaW5nJiB2YWx1ZTMsCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIHZhcmlhYmxlNCwgY29uc3Qgc3RyaW5nJiB2YWx1ZTQsCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIHZhcmlhYmxlNSwgY29uc3Qgc3RyaW5nJiB2YWx1ZTUsCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIHZhcmlhYmxlNiwgY29uc3Qgc3RyaW5nJiB2YWx1ZTYpIHsKKyAgbWFwPHN0cmluZywgc3RyaW5nPiB2YXJzOworICB2YXJzW3ZhcmlhYmxlMV0gPSB2YWx1ZTE7CisgIHZhcnNbdmFyaWFibGUyXSA9IHZhbHVlMjsKKyAgdmFyc1t2YXJpYWJsZTNdID0gdmFsdWUzOworICB2YXJzW3ZhcmlhYmxlNF0gPSB2YWx1ZTQ7CisgIHZhcnNbdmFyaWFibGU1XSA9IHZhbHVlNTsKKyAgdmFyc1t2YXJpYWJsZTZdID0gdmFsdWU2OworICBQcmludCh2YXJzLCB0ZXh0KTsKK30KKwordm9pZCBQcmludGVyOjpQcmludChjb25zdCBjaGFyKiB0ZXh0LAorICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTEsIGNvbnN0IHN0cmluZyYgdmFsdWUxLAorICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTIsIGNvbnN0IHN0cmluZyYgdmFsdWUyLAorICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTMsIGNvbnN0IHN0cmluZyYgdmFsdWUzLAorICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTQsIGNvbnN0IHN0cmluZyYgdmFsdWU0LAorICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTUsIGNvbnN0IHN0cmluZyYgdmFsdWU1LAorICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTYsIGNvbnN0IHN0cmluZyYgdmFsdWU2LAorICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTcsIGNvbnN0IHN0cmluZyYgdmFsdWU3KSB7CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyczsKKyAgdmFyc1t2YXJpYWJsZTFdID0gdmFsdWUxOworICB2YXJzW3ZhcmlhYmxlMl0gPSB2YWx1ZTI7CisgIHZhcnNbdmFyaWFibGUzXSA9IHZhbHVlMzsKKyAgdmFyc1t2YXJpYWJsZTRdID0gdmFsdWU0OworICB2YXJzW3ZhcmlhYmxlNV0gPSB2YWx1ZTU7CisgIHZhcnNbdmFyaWFibGU2XSA9IHZhbHVlNjsKKyAgdmFyc1t2YXJpYWJsZTddID0gdmFsdWU3OworICBQcmludCh2YXJzLCB0ZXh0KTsKK30KKwordm9pZCBQcmludGVyOjpQcmludChjb25zdCBjaGFyKiB0ZXh0LAorICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTEsIGNvbnN0IHN0cmluZyYgdmFsdWUxLAorICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTIsIGNvbnN0IHN0cmluZyYgdmFsdWUyLAorICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTMsIGNvbnN0IHN0cmluZyYgdmFsdWUzLAorICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTQsIGNvbnN0IHN0cmluZyYgdmFsdWU0LAorICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTUsIGNvbnN0IHN0cmluZyYgdmFsdWU1LAorICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTYsIGNvbnN0IHN0cmluZyYgdmFsdWU2LAorICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTcsIGNvbnN0IHN0cmluZyYgdmFsdWU3LAorICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTgsIGNvbnN0IHN0cmluZyYgdmFsdWU4KSB7CisgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyczsKKyAgdmFyc1t2YXJpYWJsZTFdID0gdmFsdWUxOworICB2YXJzW3ZhcmlhYmxlMl0gPSB2YWx1ZTI7CisgIHZhcnNbdmFyaWFibGUzXSA9IHZhbHVlMzsKKyAgdmFyc1t2YXJpYWJsZTRdID0gdmFsdWU0OworICB2YXJzW3ZhcmlhYmxlNV0gPSB2YWx1ZTU7CisgIHZhcnNbdmFyaWFibGU2XSA9IHZhbHVlNjsKKyAgdmFyc1t2YXJpYWJsZTddID0gdmFsdWU3OworICB2YXJzW3ZhcmlhYmxlOF0gPSB2YWx1ZTg7CisgIFByaW50KHZhcnMsIHRleHQpOworfQorCit2b2lkIFByaW50ZXI6OkluZGVudCgpIHsKKyAgaW5kZW50XyArPSAiICAiOworfQorCit2b2lkIFByaW50ZXI6Ok91dGRlbnQoKSB7CisgIGlmIChpbmRlbnRfLmVtcHR5KCkpIHsKKyAgICBHT09HTEVfTE9HKERGQVRBTCkgPDwgIiBPdXRkZW50KCkgd2l0aG91dCBtYXRjaGluZyBJbmRlbnQoKS4iOworICAgIHJldHVybjsKKyAgfQorCisgIGluZGVudF8ucmVzaXplKGluZGVudF8uc2l6ZSgpIC0gMik7Cit9CisKK3ZvaWQgUHJpbnRlcjo6UHJpbnRSYXcoY29uc3Qgc3RyaW5nJiBkYXRhKSB7CisgIFdyaXRlUmF3KGRhdGEuZGF0YSgpLCBkYXRhLnNpemUoKSk7Cit9CisKK3ZvaWQgUHJpbnRlcjo6UHJpbnRSYXcoY29uc3QgY2hhciogZGF0YSkgeworICBpZiAoZmFpbGVkXykgcmV0dXJuOworICBXcml0ZVJhdyhkYXRhLCBzdHJsZW4oZGF0YSkpOworfQorCit2b2lkIFByaW50ZXI6OldyaXRlUmF3KGNvbnN0IGNoYXIqIGRhdGEsIGludCBzaXplKSB7CisgIGlmIChmYWlsZWRfKSByZXR1cm47CisgIGlmIChzaXplID09IDApIHJldHVybjsKKworICBpZiAoYXRfc3RhcnRfb2ZfbGluZV8gJiYgKHNpemUgPiAwKSAmJiAoZGF0YVswXSAhPSAnXG4nKSkgeworICAgIC8vIEluc2VydCBhbiBpbmRlbnQuCisgICAgYXRfc3RhcnRfb2ZfbGluZV8gPSBmYWxzZTsKKyAgICBXcml0ZVJhdyhpbmRlbnRfLmRhdGEoKSwgaW5kZW50Xy5zaXplKCkpOworICAgIGlmIChmYWlsZWRfKSByZXR1cm47CisgIH0KKworICB3aGlsZSAoc2l6ZSA+IGJ1ZmZlcl9zaXplXykgeworICAgIC8vIERhdGEgZXhjZWVkcyBzcGFjZSBpbiB0aGUgYnVmZmVyLiAgQ29weSB3aGF0IHdlIGNhbiBhbmQgcmVxdWVzdCBhCisgICAgLy8gbmV3IGJ1ZmZlci4KKyAgICBtZW1jcHkoYnVmZmVyXywgZGF0YSwgYnVmZmVyX3NpemVfKTsKKyAgICBkYXRhICs9IGJ1ZmZlcl9zaXplXzsKKyAgICBzaXplIC09IGJ1ZmZlcl9zaXplXzsKKyAgICB2b2lkKiB2b2lkX2J1ZmZlcjsKKyAgICBmYWlsZWRfID0gIW91dHB1dF8tPk5leHQoJnZvaWRfYnVmZmVyLCAmYnVmZmVyX3NpemVfKTsKKyAgICBpZiAoZmFpbGVkXykgcmV0dXJuOworICAgIGJ1ZmZlcl8gPSByZWludGVycHJldF9jYXN0PGNoYXIqPih2b2lkX2J1ZmZlcik7CisgIH0KKworICAvLyBCdWZmZXIgaXMgYmlnIGVub3VnaCB0byByZWNlaXZlIHRoZSBkYXRhOyBjb3B5IGl0LgorICBtZW1jcHkoYnVmZmVyXywgZGF0YSwgc2l6ZSk7CisgIGJ1ZmZlcl8gKz0gc2l6ZTsKKyAgYnVmZmVyX3NpemVfIC09IHNpemU7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBpbworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYxNDkwYmIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaApAQCAtMCwwICsxLDE2OSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorLy8KKy8vIFV0aWxpdHkgY2xhc3MgZm9yIHdyaXRpbmcgdGV4dCB0byBhIFplcm9Db3B5T3V0cHV0U3RyZWFtLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9JT19QUklOVEVSX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfSU9fUFJJTlRFUl9IX18KKworI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW8geworCitjbGFzcyBaZXJvQ29weU91dHB1dFN0cmVhbTsgICAgIC8vIHplcm9fY29weV9zdHJlYW0uaAorCisvLyBUaGlzIHNpbXBsZSB1dGlsaXR5IGNsYXNzIGFzc2lzdHMgaW4gY29kZSBnZW5lcmF0aW9uLiAgSXQgYmFzaWNhbGx5CisvLyBhbGxvd3MgdGhlIGNhbGxlciB0byBkZWZpbmUgYSBzZXQgb2YgdmFyaWFibGVzIGFuZCB0aGVuIG91dHB1dCBzb21lCisvLyB0ZXh0IHdpdGggdmFyaWFibGUgc3Vic3RpdHV0aW9ucy4gIEV4YW1wbGUgdXNhZ2U6CisvLworLy8gICBQcmludGVyIHByaW50ZXIob3V0cHV0LCAnJCcpOworLy8gICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcnM7CisvLyAgIHZhcnNbIm5hbWUiXSA9ICJCb2IiOworLy8gICBwcmludGVyLlByaW50KHZhcnMsICJNeSBuYW1lIGlzICRuYW1lJC4iKTsKKy8vCisvLyBUaGUgYWJvdmUgd3JpdGVzICJNeSBuYW1lIGlzIEJvYi4iIHRvIHRoZSBvdXRwdXQgc3RyZWFtLgorLy8KKy8vIFByaW50ZXIgYWdncmVzc2l2ZWx5IGVuZm9yY2VzIGNvcnJlY3QgdXNhZ2UsIGNyYXNoaW5nICh3aXRoIGFzc2VydCBmYWlsdXJlcykKKy8vIGluIHRoZSBjYXNlIG9mIHVuZGVmaW5lZCB2YXJpYWJsZXMgaW4gZGVidWcgYnVpbGRzLiBUaGlzIGhlbHBzIGdyZWF0bHkgaW4KKy8vIGRlYnVnZ2luZyBjb2RlIHdoaWNoIHVzZXMgaXQuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgUHJpbnRlciB7CisgcHVibGljOgorICAvLyBDcmVhdGUgYSBwcmludGVyIHRoYXQgd3JpdGVzIHRleHQgdG8gdGhlIGdpdmVuIG91dHB1dCBzdHJlYW0uICBVc2UgdGhlCisgIC8vIGdpdmVuIGNoYXJhY3RlciBhcyB0aGUgZGVsaW1pdGVyIGZvciB2YXJpYWJsZXMuCisgIFByaW50ZXIoWmVyb0NvcHlPdXRwdXRTdHJlYW0qIG91dHB1dCwgY2hhciB2YXJpYWJsZV9kZWxpbWl0ZXIpOworICB+UHJpbnRlcigpOworCisgIC8vIFByaW50IHNvbWUgdGV4dCBhZnRlciBhcHBseWluZyB2YXJpYWJsZSBzdWJzdGl0dXRpb25zLiAgSWYgYSBwYXJ0aWN1bGFyCisgIC8vIHZhcmlhYmxlIGluIHRoZSB0ZXh0IGlzIG5vdCBkZWZpbmVkLCB0aGlzIHdpbGwgY3Jhc2guICBWYXJpYWJsZXMgdG8gYmUKKyAgLy8gc3Vic3RpdHV0ZWQgYXJlIGlkZW50aWZpZWQgYnkgdGhlaXIgbmFtZXMgc3Vycm91bmRlZCBieSBkZWxpbWl0ZXIKKyAgLy8gY2hhcmFjdGVycyAoYXMgZ2l2ZW4gdG8gdGhlIGNvbnN0cnVjdG9yKS4gIFRoZSB2YXJpYWJsZSBiaW5kaW5ncyBhcmUKKyAgLy8gZGVmaW5lZCBieSB0aGUgZ2l2ZW4gbWFwLgorICB2b2lkIFByaW50KGNvbnN0IG1hcDxzdHJpbmcsIHN0cmluZz4mIHZhcmlhYmxlcywgY29uc3QgY2hhciogdGV4dCk7CisKKyAgLy8gTGlrZSB0aGUgZmlyc3QgUHJpbnQoKSwgZXhjZXB0IHRoZSBzdWJzdGl0dXRpb25zIGFyZSBnaXZlbiBhcyBwYXJhbWV0ZXJzLgorICB2b2lkIFByaW50KGNvbnN0IGNoYXIqIHRleHQpOworICAvLyBMaWtlIHRoZSBmaXJzdCBQcmludCgpLCBleGNlcHQgdGhlIHN1YnN0aXR1dGlvbnMgYXJlIGdpdmVuIGFzIHBhcmFtZXRlcnMuCisgIHZvaWQgUHJpbnQoY29uc3QgY2hhciogdGV4dCwgY29uc3QgY2hhciogdmFyaWFibGUsIGNvbnN0IHN0cmluZyYgdmFsdWUpOworICAvLyBMaWtlIHRoZSBmaXJzdCBQcmludCgpLCBleGNlcHQgdGhlIHN1YnN0aXR1dGlvbnMgYXJlIGdpdmVuIGFzIHBhcmFtZXRlcnMuCisgIHZvaWQgUHJpbnQoY29uc3QgY2hhciogdGV4dCwgY29uc3QgY2hhciogdmFyaWFibGUxLCBjb25zdCBzdHJpbmcmIHZhbHVlMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTIsIGNvbnN0IHN0cmluZyYgdmFsdWUyKTsKKyAgLy8gTGlrZSB0aGUgZmlyc3QgUHJpbnQoKSwgZXhjZXB0IHRoZSBzdWJzdGl0dXRpb25zIGFyZSBnaXZlbiBhcyBwYXJhbWV0ZXJzLgorICB2b2lkIFByaW50KGNvbnN0IGNoYXIqIHRleHQsIGNvbnN0IGNoYXIqIHZhcmlhYmxlMSwgY29uc3Qgc3RyaW5nJiB2YWx1ZTEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogdmFyaWFibGUyLCBjb25zdCBzdHJpbmcmIHZhbHVlMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTMsIGNvbnN0IHN0cmluZyYgdmFsdWUzKTsKKyAgLy8gTGlrZSB0aGUgZmlyc3QgUHJpbnQoKSwgZXhjZXB0IHRoZSBzdWJzdGl0dXRpb25zIGFyZSBnaXZlbiBhcyBwYXJhbWV0ZXJzLgorICB2b2lkIFByaW50KGNvbnN0IGNoYXIqIHRleHQsIGNvbnN0IGNoYXIqIHZhcmlhYmxlMSwgY29uc3Qgc3RyaW5nJiB2YWx1ZTEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogdmFyaWFibGUyLCBjb25zdCBzdHJpbmcmIHZhbHVlMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTMsIGNvbnN0IHN0cmluZyYgdmFsdWUzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIHZhcmlhYmxlNCwgY29uc3Qgc3RyaW5nJiB2YWx1ZTQpOworICAvLyBMaWtlIHRoZSBmaXJzdCBQcmludCgpLCBleGNlcHQgdGhlIHN1YnN0aXR1dGlvbnMgYXJlIGdpdmVuIGFzIHBhcmFtZXRlcnMuCisgIHZvaWQgUHJpbnQoY29uc3QgY2hhciogdGV4dCwgY29uc3QgY2hhciogdmFyaWFibGUxLCBjb25zdCBzdHJpbmcmIHZhbHVlMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTIsIGNvbnN0IHN0cmluZyYgdmFsdWUyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIHZhcmlhYmxlMywgY29uc3Qgc3RyaW5nJiB2YWx1ZTMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogdmFyaWFibGU0LCBjb25zdCBzdHJpbmcmIHZhbHVlNCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTUsIGNvbnN0IHN0cmluZyYgdmFsdWU1KTsKKyAgLy8gTGlrZSB0aGUgZmlyc3QgUHJpbnQoKSwgZXhjZXB0IHRoZSBzdWJzdGl0dXRpb25zIGFyZSBnaXZlbiBhcyBwYXJhbWV0ZXJzLgorICB2b2lkIFByaW50KGNvbnN0IGNoYXIqIHRleHQsIGNvbnN0IGNoYXIqIHZhcmlhYmxlMSwgY29uc3Qgc3RyaW5nJiB2YWx1ZTEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogdmFyaWFibGUyLCBjb25zdCBzdHJpbmcmIHZhbHVlMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTMsIGNvbnN0IHN0cmluZyYgdmFsdWUzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIHZhcmlhYmxlNCwgY29uc3Qgc3RyaW5nJiB2YWx1ZTQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogdmFyaWFibGU1LCBjb25zdCBzdHJpbmcmIHZhbHVlNSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTYsIGNvbnN0IHN0cmluZyYgdmFsdWU2KTsKKyAgLy8gTGlrZSB0aGUgZmlyc3QgUHJpbnQoKSwgZXhjZXB0IHRoZSBzdWJzdGl0dXRpb25zIGFyZSBnaXZlbiBhcyBwYXJhbWV0ZXJzLgorICB2b2lkIFByaW50KGNvbnN0IGNoYXIqIHRleHQsIGNvbnN0IGNoYXIqIHZhcmlhYmxlMSwgY29uc3Qgc3RyaW5nJiB2YWx1ZTEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogdmFyaWFibGUyLCBjb25zdCBzdHJpbmcmIHZhbHVlMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTMsIGNvbnN0IHN0cmluZyYgdmFsdWUzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIHZhcmlhYmxlNCwgY29uc3Qgc3RyaW5nJiB2YWx1ZTQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogdmFyaWFibGU1LCBjb25zdCBzdHJpbmcmIHZhbHVlNSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTYsIGNvbnN0IHN0cmluZyYgdmFsdWU2LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIHZhcmlhYmxlNywgY29uc3Qgc3RyaW5nJiB2YWx1ZTcpOworICAvLyBMaWtlIHRoZSBmaXJzdCBQcmludCgpLCBleGNlcHQgdGhlIHN1YnN0aXR1dGlvbnMgYXJlIGdpdmVuIGFzIHBhcmFtZXRlcnMuCisgIHZvaWQgUHJpbnQoY29uc3QgY2hhciogdGV4dCwgY29uc3QgY2hhciogdmFyaWFibGUxLCBjb25zdCBzdHJpbmcmIHZhbHVlMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTIsIGNvbnN0IHN0cmluZyYgdmFsdWUyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIHZhcmlhYmxlMywgY29uc3Qgc3RyaW5nJiB2YWx1ZTMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogdmFyaWFibGU0LCBjb25zdCBzdHJpbmcmIHZhbHVlNCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTUsIGNvbnN0IHN0cmluZyYgdmFsdWU1LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIHZhcmlhYmxlNiwgY29uc3Qgc3RyaW5nJiB2YWx1ZTYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogdmFyaWFibGU3LCBjb25zdCBzdHJpbmcmIHZhbHVlNywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB2YXJpYWJsZTgsIGNvbnN0IHN0cmluZyYgdmFsdWU4KTsKKworICAvLyBJbmRlbnQgdGV4dCBieSB0d28gc3BhY2VzLiAgQWZ0ZXIgY2FsbGluZyBJbmRlbnQoKSwgdHdvIHNwYWNlcyB3aWxsIGJlCisgIC8vIGluc2VydGVkIGF0IHRoZSBiZWdpbm5pbmcgb2YgZWFjaCBsaW5lIG9mIHRleHQuICBJbmRlbnQoKSBtYXkgYmUgY2FsbGVkCisgIC8vIG11bHRpcGxlIHRpbWVzIHRvIHByb2R1Y2UgZGVlcGVyIGluZGVudHMuCisgIHZvaWQgSW5kZW50KCk7CisKKyAgLy8gUmVkdWNlcyB0aGUgY3VycmVudCBpbmRlbnQgbGV2ZWwgYnkgdHdvIHNwYWNlcywgb3IgY3Jhc2hlcyBpZiB0aGUgaW5kZW50CisgIC8vIGxldmVsIGlzIHplcm8uCisgIHZvaWQgT3V0ZGVudCgpOworCisgIC8vIFdyaXRlIGEgc3RyaW5nIHRvIHRoZSBvdXRwdXQgYnVmZmVyLgorICAvLyBUaGlzIG1ldGhvZCBkb2VzIG5vdCBsb29rIGZvciBuZXdsaW5lcyB0byBhZGQgaW5kZW50YXRpb24uCisgIHZvaWQgUHJpbnRSYXcoY29uc3Qgc3RyaW5nJiBkYXRhKTsKKworICAvLyBXcml0ZSBhIHplcm8tZGVsaW1pdGVkIHN0cmluZyB0byBvdXRwdXQgYnVmZmVyLgorICAvLyBUaGlzIG1ldGhvZCBkb2VzIG5vdCBsb29rIGZvciBuZXdsaW5lcyB0byBhZGQgaW5kZW50YXRpb24uCisgIHZvaWQgUHJpbnRSYXcoY29uc3QgY2hhciogZGF0YSk7CisKKyAgLy8gV3JpdGUgc29tZSBieXRlcyB0byB0aGUgb3V0cHV0IGJ1ZmZlci4KKyAgLy8gVGhpcyBtZXRob2QgZG9lcyBub3QgbG9vayBmb3IgbmV3bGluZXMgdG8gYWRkIGluZGVudGF0aW9uLgorICB2b2lkIFdyaXRlUmF3KGNvbnN0IGNoYXIqIGRhdGEsIGludCBzaXplKTsKKworICAvLyBUcnVlIGlmIGFueSB3cml0ZSB0byB0aGUgdW5kZXJseWluZyBzdHJlYW0gZmFpbGVkLiAgKFdlIGRvbid0IGp1c3QKKyAgLy8gY3Jhc2ggaW4gdGhpcyBjYXNlIGJlY2F1c2UgdGhpcyBpcyBhbiBJL08gZmFpbHVyZSwgbm90IGEgcHJvZ3JhbW1pbmcKKyAgLy8gZXJyb3IuKQorICBib29sIGZhaWxlZCgpIGNvbnN0IHsgcmV0dXJuIGZhaWxlZF87IH0KKworIHByaXZhdGU6CisgIGNvbnN0IGNoYXIgdmFyaWFibGVfZGVsaW1pdGVyXzsKKworICBaZXJvQ29weU91dHB1dFN0cmVhbSogY29uc3Qgb3V0cHV0XzsKKyAgY2hhciogYnVmZmVyXzsKKyAgaW50IGJ1ZmZlcl9zaXplXzsKKworICBzdHJpbmcgaW5kZW50XzsKKyAgYm9vbCBhdF9zdGFydF9vZl9saW5lXzsKKyAgYm9vbCBmYWlsZWRfOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhQcmludGVyKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBpbworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0lPX1BSSU5URVJfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXJfdW5pdHRlc3QuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXJfdW5pdHRlc3QuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjU4ZGQ5OAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlcl91bml0dGVzdC5jYwpAQCAtMCwwICsxLDI4NiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8dmVjdG9yPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3ByaW50ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbV9pbXBsLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbG9nZ2luZy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0Lmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGlvIHsKK25hbWVzcGFjZSB7CisKKy8vIEVhY2ggdGVzdCByZXBlYXRzIG92ZXIgc2V2ZXJhbCBibG9jayBzaXplcyBpbiBvcmRlciB0byB0ZXN0IGJvdGggY2FzZXMKKy8vIHdoZXJlIHBhcnRpY3VsYXIgd3JpdGVzIGNyb3NzIGEgYnVmZmVyIGJvdW5kYXJ5IGFuZCBjYXNlcyB3aGVyZSB0aGV5IGRvCisvLyBub3QuCisKK1RFU1QoUHJpbnRlciwgRW1wdHlQcmludGVyKSB7CisgIGNoYXIgYnVmZmVyWzgxOTJdOworICBjb25zdCBpbnQgYmxvY2tfc2l6ZSA9IDEwMDsKKyAgQXJyYXlPdXRwdXRTdHJlYW0gb3V0cHV0KGJ1ZmZlciwgR09PR0xFX0FSUkFZU0laRShidWZmZXIpLCBibG9ja19zaXplKTsKKyAgUHJpbnRlciBwcmludGVyKCZvdXRwdXQsICdcMCcpOworICBFWFBFQ1RfVFJVRSghcHJpbnRlci5mYWlsZWQoKSk7Cit9CisKK1RFU1QoUHJpbnRlciwgQmFzaWNQcmludGluZykgeworICBjaGFyIGJ1ZmZlcls4MTkyXTsKKworICBmb3IgKGludCBibG9ja19zaXplID0gMTsgYmxvY2tfc2l6ZSA8IDUxMjsgYmxvY2tfc2l6ZSAqPSAyKSB7CisgICAgQXJyYXlPdXRwdXRTdHJlYW0gb3V0cHV0KGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlciksIGJsb2NrX3NpemUpOworCisgICAgeworICAgICAgUHJpbnRlciBwcmludGVyKCZvdXRwdXQsICdcMCcpOworCisgICAgICBwcmludGVyLlByaW50KCJIZWxsbyBXb3JsZCEiKTsKKyAgICAgIHByaW50ZXIuUHJpbnQoIiAgVGhpcyBpcyB0aGUgc2FtZSBsaW5lLlxuIik7CisgICAgICBwcmludGVyLlByaW50KCJCdXQgdGhpcyBpcyBhIG5ldyBvbmUuXG5BbmQgdGhpcyBpcyBhbm90aGVyIG9uZS4iKTsKKworICAgICAgRVhQRUNUX0ZBTFNFKHByaW50ZXIuZmFpbGVkKCkpOworICAgIH0KKworICAgIGJ1ZmZlcltvdXRwdXQuQnl0ZUNvdW50KCldID0gJ1wwJzsKKworICAgIEVYUEVDVF9TVFJFUSgiSGVsbG8gV29ybGQhICBUaGlzIGlzIHRoZSBzYW1lIGxpbmUuXG4iCisgICAgICAgICAgICAgICAgICJCdXQgdGhpcyBpcyBhIG5ldyBvbmUuXG4iCisgICAgICAgICAgICAgICAgICJBbmQgdGhpcyBpcyBhbm90aGVyIG9uZS4iLAorICAgICAgICAgICAgICAgICBidWZmZXIpOworICB9Cit9CisKK1RFU1QoUHJpbnRlciwgV3JpdGVSYXcpIHsKKyAgY2hhciBidWZmZXJbODE5Ml07CisKKyAgZm9yIChpbnQgYmxvY2tfc2l6ZSA9IDE7IGJsb2NrX3NpemUgPCA1MTI7IGJsb2NrX3NpemUgKj0gMikgeworICAgIEFycmF5T3V0cHV0U3RyZWFtIG91dHB1dChidWZmZXIsIHNpemVvZihidWZmZXIpLCBibG9ja19zaXplKTsKKworICAgIHsKKyAgICAgIHN0cmluZyBzdHJpbmdfb2JqID0gIkZyb20gYW4gb2JqZWN0XG4iOworICAgICAgUHJpbnRlciBwcmludGVyKCZvdXRwdXQsICckJyk7CisgICAgICBwcmludGVyLldyaXRlUmF3KCJIZWxsbyBXb3JsZCEiLCAxMik7CisgICAgICBwcmludGVyLlByaW50UmF3KCIgIFRoaXMgaXMgdGhlIHNhbWUgbGluZS5cbiIpOworICAgICAgcHJpbnRlci5QcmludFJhdygiQnV0IHRoaXMgaXMgYSBuZXcgb25lLlxuQW5kIHRoaXMgaXMgYW5vdGhlciBvbmUuIik7CisgICAgICBwcmludGVyLldyaXRlUmF3KCJcbiIsIDEpOworICAgICAgcHJpbnRlci5QcmludFJhdyhzdHJpbmdfb2JqKTsKKyAgICAgIEVYUEVDVF9GQUxTRShwcmludGVyLmZhaWxlZCgpKTsKKyAgICB9CisKKyAgICBidWZmZXJbb3V0cHV0LkJ5dGVDb3VudCgpXSA9ICdcMCc7CisKKyAgICBFWFBFQ1RfU1RSRVEoIkhlbGxvIFdvcmxkISAgVGhpcyBpcyB0aGUgc2FtZSBsaW5lLlxuIgorICAgICAgICAgICAgICAgICAiQnV0IHRoaXMgaXMgYSBuZXcgb25lLlxuIgorICAgICAgICAgICAgICAgICAiQW5kIHRoaXMgaXMgYW5vdGhlciBvbmUuIgorICAgICAgICAgICAgICAgICAiXG4iCisgICAgICAgICAgICAgICAgICJGcm9tIGFuIG9iamVjdFxuIiwKKyAgICAgICAgICAgICAgICAgYnVmZmVyKTsKKyAgfQorfQorCitURVNUKFByaW50ZXIsIFZhcmlhYmxlU3Vic3RpdHV0aW9uKSB7CisgIGNoYXIgYnVmZmVyWzgxOTJdOworCisgIGZvciAoaW50IGJsb2NrX3NpemUgPSAxOyBibG9ja19zaXplIDwgNTEyOyBibG9ja19zaXplICo9IDIpIHsKKyAgICBBcnJheU91dHB1dFN0cmVhbSBvdXRwdXQoYnVmZmVyLCBzaXplb2YoYnVmZmVyKSwgYmxvY2tfc2l6ZSk7CisKKyAgICB7CisgICAgICBQcmludGVyIHByaW50ZXIoJm91dHB1dCwgJyQnKTsKKyAgICAgIG1hcDxzdHJpbmcsIHN0cmluZz4gdmFyczsKKworICAgICAgdmFyc1siZm9vIl0gPSAiV29ybGQiOworICAgICAgdmFyc1siYmFyIl0gPSAiJGZvbyQiOworICAgICAgdmFyc1siYWJjZGVmZyJdID0gIjEyMzQiOworCisgICAgICBwcmludGVyLlByaW50KHZhcnMsICJIZWxsbyAkZm9vJCFcbmJhciA9ICRiYXIkXG4iKTsKKyAgICAgIHByaW50ZXIuUHJpbnRSYXcoIlJhd0JpdFxuIik7CisgICAgICBwcmludGVyLlByaW50KHZhcnMsICIkYWJjZGVmZyRcbkEgbGl0ZXJhbCBkb2xsYXIgc2lnbjogICQkIik7CisKKyAgICAgIHZhcnNbImZvbyJdID0gImJsYWgiOworICAgICAgcHJpbnRlci5QcmludCh2YXJzLCAiXG5Ob3cgZm9vID0gJGZvbyQuIik7CisKKyAgICAgIEVYUEVDVF9GQUxTRShwcmludGVyLmZhaWxlZCgpKTsKKyAgICB9CisKKyAgICBidWZmZXJbb3V0cHV0LkJ5dGVDb3VudCgpXSA9ICdcMCc7CisKKyAgICBFWFBFQ1RfU1RSRVEoIkhlbGxvIFdvcmxkIVxuIgorICAgICAgICAgICAgICAgICAiYmFyID0gJGZvbyRcbiIKKyAgICAgICAgICAgICAgICAgIlJhd0JpdFxuIgorICAgICAgICAgICAgICAgICAiMTIzNFxuIgorICAgICAgICAgICAgICAgICAiQSBsaXRlcmFsIGRvbGxhciBzaWduOiAgJFxuIgorICAgICAgICAgICAgICAgICAiTm93IGZvbyA9IGJsYWguIiwKKyAgICAgICAgICAgICAgICAgYnVmZmVyKTsKKyAgfQorfQorCitURVNUKFByaW50ZXIsIElubGluZVZhcmlhYmxlU3Vic3RpdHV0aW9uKSB7CisgIGNoYXIgYnVmZmVyWzgxOTJdOworCisgIEFycmF5T3V0cHV0U3RyZWFtIG91dHB1dChidWZmZXIsIHNpemVvZihidWZmZXIpKTsKKworICB7CisgICAgUHJpbnRlciBwcmludGVyKCZvdXRwdXQsICckJyk7CisgICAgcHJpbnRlci5QcmludCgiSGVsbG8gJGZvbyQhXG4iLCAiZm9vIiwgIldvcmxkIik7CisgICAgcHJpbnRlci5QcmludFJhdygiUmF3Qml0XG4iKTsKKyAgICBwcmludGVyLlByaW50KCIkZm9vJCAkYmFyJFxuIiwgImZvbyIsICJvbmUiLCAiYmFyIiwgInR3byIpOworICAgIEVYUEVDVF9GQUxTRShwcmludGVyLmZhaWxlZCgpKTsKKyAgfQorCisgIGJ1ZmZlcltvdXRwdXQuQnl0ZUNvdW50KCldID0gJ1wwJzsKKworICBFWFBFQ1RfU1RSRVEoIkhlbGxvIFdvcmxkIVxuIgorICAgICAgICAgICAgICAgIlJhd0JpdFxuIgorICAgICAgICAgICAgICAgIm9uZSB0d29cbiIsCisgICAgICAgICAgICAgICBidWZmZXIpOworfQorCitURVNUKFByaW50ZXIsIEluZGVudGluZykgeworICBjaGFyIGJ1ZmZlcls4MTkyXTsKKworICBmb3IgKGludCBibG9ja19zaXplID0gMTsgYmxvY2tfc2l6ZSA8IDUxMjsgYmxvY2tfc2l6ZSAqPSAyKSB7CisgICAgQXJyYXlPdXRwdXRTdHJlYW0gb3V0cHV0KGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlciksIGJsb2NrX3NpemUpOworCisgICAgeworICAgICAgUHJpbnRlciBwcmludGVyKCZvdXRwdXQsICckJyk7CisgICAgICBtYXA8c3RyaW5nLCBzdHJpbmc+IHZhcnM7CisKKyAgICAgIHZhcnNbIm5ld2xpbmUiXSA9ICJcbiI7CisKKyAgICAgIHByaW50ZXIuUHJpbnQoIlRoaXMgaXMgbm90IGluZGVudGVkLlxuIik7CisgICAgICBwcmludGVyLkluZGVudCgpOworICAgICAgcHJpbnRlci5QcmludCgiVGhpcyBpcyBpbmRlbnRlZFxuQW5kIHNvIGlzIHRoaXNcbiIpOworICAgICAgcHJpbnRlci5PdXRkZW50KCk7CisgICAgICBwcmludGVyLlByaW50KCJCdXQgdGhpcyBpcyBub3QuIik7CisgICAgICBwcmludGVyLkluZGVudCgpOworICAgICAgcHJpbnRlci5QcmludCgiICBBbmQgdGhpcyBpcyBzdGlsbCB0aGUgc2FtZSBsaW5lLlxuIgorICAgICAgICAgICAgICAgICAgICAiQnV0IHRoaXMgaXMgaW5kZW50ZWQuXG4iKTsKKyAgICAgIHByaW50ZXIuUHJpbnRSYXcoIlJhd0JpdCBoYXMgaW5kZW50IGF0IHN0YXJ0XG4iKTsKKyAgICAgIHByaW50ZXIuUHJpbnRSYXcoImJ1dCBub3QgYWZ0ZXIgYSByYXcgbmV3bGluZVxuIik7CisgICAgICBwcmludGVyLlByaW50KHZhcnMsICJOb3RlIHRoYXQgYSBuZXdsaW5lIGluIGEgdmFyaWFibGUgd2lsbCBicmVhayAiCisgICAgICAgICAgICAgICAgICAgICJpbmRlbnRpbmcsIGFzIHdlIHNlZSRuZXdsaW5lJGhlcmUuXG4iKTsKKyAgICAgIHByaW50ZXIuSW5kZW50KCk7CisgICAgICBwcmludGVyLlByaW50KCJBbmQgdGhpcyIpOworICAgICAgcHJpbnRlci5PdXRkZW50KCk7CisgICAgICBwcmludGVyLk91dGRlbnQoKTsKKyAgICAgIHByaW50ZXIuUHJpbnQoIiBpcyBkb3VibGUtaW5kZW50ZWRcbkJhY2sgdG8gbm9ybWFsLiIpOworCisgICAgICBFWFBFQ1RfRkFMU0UocHJpbnRlci5mYWlsZWQoKSk7CisgICAgfQorCisgICAgYnVmZmVyW291dHB1dC5CeXRlQ291bnQoKV0gPSAnXDAnOworCisgICAgRVhQRUNUX1NUUkVRKAorICAgICAgIlRoaXMgaXMgbm90IGluZGVudGVkLlxuIgorICAgICAgIiAgVGhpcyBpcyBpbmRlbnRlZFxuIgorICAgICAgIiAgQW5kIHNvIGlzIHRoaXNcbiIKKyAgICAgICJCdXQgdGhpcyBpcyBub3QuICBBbmQgdGhpcyBpcyBzdGlsbCB0aGUgc2FtZSBsaW5lLlxuIgorICAgICAgIiAgQnV0IHRoaXMgaXMgaW5kZW50ZWQuXG4iCisgICAgICAiICBSYXdCaXQgaGFzIGluZGVudCBhdCBzdGFydFxuIgorICAgICAgImJ1dCBub3QgYWZ0ZXIgYSByYXcgbmV3bGluZVxuIgorICAgICAgIk5vdGUgdGhhdCBhIG5ld2xpbmUgaW4gYSB2YXJpYWJsZSB3aWxsIGJyZWFrIGluZGVudGluZywgYXMgd2Ugc2VlXG4iCisgICAgICAiaGVyZS5cbiIKKyAgICAgICIgICAgQW5kIHRoaXMgaXMgZG91YmxlLWluZGVudGVkXG4iCisgICAgICAiQmFjayB0byBub3JtYWwuIiwKKyAgICAgIGJ1ZmZlcik7CisgIH0KK30KKworLy8gRGVhdGggdGVzdHMgZG8gbm90IHdvcmsgb24gV2luZG93cyBhcyBvZiB5ZXQuCisjaWZkZWYgUFJPVE9CVUZfSEFTX0RFQVRIX1RFU1QKK1RFU1QoUHJpbnRlciwgRGVhdGgpIHsKKyAgY2hhciBidWZmZXJbODE5Ml07CisKKyAgQXJyYXlPdXRwdXRTdHJlYW0gb3V0cHV0KGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlcikpOworICBQcmludGVyIHByaW50ZXIoJm91dHB1dCwgJyQnKTsKKworICBFWFBFQ1RfREVCVUdfREVBVEgocHJpbnRlci5QcmludCgiJG5vc3VjaHZhciQiKSwgIlVuZGVmaW5lZCB2YXJpYWJsZSIpOworICBFWFBFQ1RfREVCVUdfREVBVEgocHJpbnRlci5QcmludCgiJHVuY2xvc2VkIiksICJVbmNsb3NlZCB2YXJpYWJsZSBuYW1lIik7CisgIEVYUEVDVF9ERUJVR19ERUFUSChwcmludGVyLk91dGRlbnQoKSwgIndpdGhvdXQgbWF0Y2hpbmcgSW5kZW50Iik7Cit9CisjZW5kaWYgIC8vIFBST1RPQlVGX0hBU19ERUFUSF9URVNUCisKK1RFU1QoUHJpbnRlciwgV3JpdGVGYWlsdXJlUGFydGlhbCkgeworICBjaGFyIGJ1ZmZlclsxN107CisKKyAgQXJyYXlPdXRwdXRTdHJlYW0gb3V0cHV0KGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlcikpOworICBQcmludGVyIHByaW50ZXIoJm91dHB1dCwgJyQnKTsKKworICAvLyBQcmludCAxNiBieXRlcyB0byBhbG1vc3QgZmlsbCB0aGUgYnVmZmVyIChzaG91bGQgbm90IGZhaWwpLgorICBwcmludGVyLlByaW50KCIwMTIzNDU2Nzg5YWJjZGVmIik7CisgIEVYUEVDVF9GQUxTRShwcmludGVyLmZhaWxlZCgpKTsKKworICAvLyBUcnkgdG8gcHJpbnQgMiBjaGFycy4gT25seSBvbmUgZml0cy4KKyAgcHJpbnRlci5QcmludCgiPD4iKTsKKyAgRVhQRUNUX1RSVUUocHJpbnRlci5mYWlsZWQoKSk7CisKKyAgLy8gQW55dGhpbmcgZWxzZSBzaG91bGQgZmFpbCB0b28uCisgIHByaW50ZXIuUHJpbnQoIiAiKTsKKyAgRVhQRUNUX1RSVUUocHJpbnRlci5mYWlsZWQoKSk7CisgIHByaW50ZXIuUHJpbnQoImJsYWgiKTsKKyAgRVhQRUNUX1RSVUUocHJpbnRlci5mYWlsZWQoKSk7CisKKyAgLy8gQnVmZmVyIHNob3VsZCBjb250YWluIHRoZSBmaXJzdCAxNyBieXRlcyB3cml0dGVuLgorICBFWFBFQ1RfRVEoIjAxMjM0NTY3ODlhYmNkZWY8Iiwgc3RyaW5nKGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlcikpKTsKK30KKworVEVTVChQcmludGVyLCBXcml0ZUZhaWx1cmVFeGFjdCkgeworICBjaGFyIGJ1ZmZlclsxNl07CisKKyAgQXJyYXlPdXRwdXRTdHJlYW0gb3V0cHV0KGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlcikpOworICBQcmludGVyIHByaW50ZXIoJm91dHB1dCwgJyQnKTsKKworICAvLyBQcmludCAxNiBieXRlcyB0byBmaWxsIHRoZSBidWZmZXIgZXhhY3RseSAoc2hvdWxkIG5vdCBmYWlsKS4KKyAgcHJpbnRlci5QcmludCgiMDEyMzQ1Njc4OWFiY2RlZiIpOworICBFWFBFQ1RfRkFMU0UocHJpbnRlci5mYWlsZWQoKSk7CisKKyAgLy8gVHJ5IHRvIHByaW50IG9uZSBtb3JlIGJ5dGUgKHNob3VsZCBmYWlsKS4KKyAgcHJpbnRlci5QcmludCgiICIpOworICBFWFBFQ1RfVFJVRShwcmludGVyLmZhaWxlZCgpKTsKKworICAvLyBTaG91bGQgbm90IGNyYXNoCisgIHByaW50ZXIuUHJpbnQoImJsYWgiKTsKKyAgRVhQRUNUX1RSVUUocHJpbnRlci5mYWlsZWQoKSk7CisKKyAgLy8gQnVmZmVyIHNob3VsZCBjb250YWluIHRoZSBmaXJzdCAxNiBieXRlcyB3cml0dGVuLgorICBFWFBFQ1RfRVEoIjAxMjM0NTY3ODlhYmNkZWYiLCBzdHJpbmcoYnVmZmVyLCBzaXplb2YoYnVmZmVyKSkpOworfQorCit9ICAvLyBuYW1lc3BhY2UKK30gIC8vIG5hbWVzcGFjZSBpbworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3N0cnRvZC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vc3RydG9kLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE5MGJiOWEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3N0cnRvZC5jYwpAQCAtMCwwICsxLDEyNSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vc3RydG9kLmg+CisKKyNpbmNsdWRlIDxjc3RkaW8+CisjaW5jbHVkZSA8Y3N0cmluZz4KKyNpbmNsdWRlIDxsaW1pdHM+CisjaW5jbHVkZSA8c3RyaW5nPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2xvZ2dpbmcuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbyB7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIE5vTG9jYWxlU3RydG9kKCkKKy8vICAgVGhpcyBjb2RlIHdpbGwgbWFrZSB5b3UgY3J5LgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCituYW1lc3BhY2UgeworCisvLyBSZXR1cm5zIGEgc3RyaW5nIGlkZW50aWNhbCB0byAqaW5wdXQgZXhjZXB0IHRoYXQgdGhlIGNoYXJhY3RlciBwb2ludGVkIHRvCisvLyBieSByYWRpeF9wb3MgKHdoaWNoIHNob3VsZCBiZSAnLicpIGlzIHJlcGxhY2VkIHdpdGggdGhlIGxvY2FsZS1zcGVjaWZpYworLy8gcmFkaXggY2hhcmFjdGVyLgorc3RyaW5nIExvY2FsaXplUmFkaXgoY29uc3QgY2hhciogaW5wdXQsIGNvbnN0IGNoYXIqIHJhZGl4X3BvcykgeworICAvLyBEZXRlcm1pbmUgdGhlIGxvY2FsZS1zcGVjaWZpYyByYWRpeCBjaGFyYWN0ZXIgYnkgY2FsbGluZyBzcHJpbnRmKCkgdG8KKyAgLy8gcHJpbnQgdGhlIG51bWJlciAxLjUsIHRoZW4gc3RyaXBwaW5nIG9mZiB0aGUgZGlnaXRzLiAgQXMgZmFyIGFzIEkgY2FuCisgIC8vIHRlbGwsIHRoaXMgaXMgdGhlIG9ubHkgcG9ydGFibGUsIHRocmVhZC1zYWZlIHdheSB0byBnZXQgdGhlIEMgbGlicmFyeQorICAvLyB0byBkaXZ1bGRnZSB0aGUgbG9jYWxlJ3MgcmFkaXggY2hhcmFjdGVyLiAgTm8sIGxvY2FsZWNvbnYoKSBpcyBOT1QKKyAgLy8gdGhyZWFkLXNhZmUuCisgIGNoYXIgdGVtcFsxNl07CisgIGludCBzaXplID0gc3ByaW50Zih0ZW1wLCAiJS4xZiIsIDEuNSk7CisgIEdPT0dMRV9DSEVDS19FUSh0ZW1wWzBdLCAnMScpOworICBHT09HTEVfQ0hFQ0tfRVEodGVtcFtzaXplLTFdLCAnNScpOworICBHT09HTEVfQ0hFQ0tfTEUoc2l6ZSwgNik7CisKKyAgLy8gTm93IHJlcGxhY2UgdGhlICcuJyBpbiB0aGUgaW5wdXQgd2l0aCBpdC4KKyAgc3RyaW5nIHJlc3VsdDsKKyAgcmVzdWx0LnJlc2VydmUoc3RybGVuKGlucHV0KSArIHNpemUgLSAzKTsKKyAgcmVzdWx0LmFwcGVuZChpbnB1dCwgcmFkaXhfcG9zKTsKKyAgcmVzdWx0LmFwcGVuZCh0ZW1wICsgMSwgc2l6ZSAtIDIpOworICByZXN1bHQuYXBwZW5kKHJhZGl4X3BvcyArIDEpOworICByZXR1cm4gcmVzdWx0OworfQorCit9ICAvLyBuYW1lc3BhY2UKKworZG91YmxlIE5vTG9jYWxlU3RydG9kKGNvbnN0IGNoYXIqIHRleHQsIGNoYXIqKiBvcmlnaW5hbF9lbmRwdHIpIHsKKyAgLy8gV2UgY2Fubm90IHNpbXBseSBzZXQgdGhlIGxvY2FsZSB0byAiQyIgdGVtcG9yYXJpbHkgd2l0aCBzZXRsb2NhbGUoKQorICAvLyBhcyB0aGlzIGlzIG5vdCB0aHJlYWQtc2FmZS4gIEluc3RlYWQsIHdlIHRyeSB0byBwYXJzZSBpbiB0aGUgY3VycmVudAorICAvLyBsb2NhbGUgZmlyc3QuICBJZiBwYXJzaW5nIHN0b3BzIGF0IGEgJy4nIGNoYXJhY3RlciwgdGhlbiB0aGlzIGlzIGEKKyAgLy8gcHJldHR5IGdvb2QgaGludCB0aGF0IHdlJ3JlIGFjdHVhbGx5IGluIHNvbWUgb3RoZXIgbG9jYWxlIGluIHdoaWNoCisgIC8vICcuJyBpcyBub3QgdGhlIHJhZGl4IGNoYXJhY3Rlci4KKworICBjaGFyKiB0ZW1wX2VuZHB0cjsKKyAgZG91YmxlIHJlc3VsdCA9IHN0cnRvZCh0ZXh0LCAmdGVtcF9lbmRwdHIpOworICBpZiAob3JpZ2luYWxfZW5kcHRyICE9IE5VTEwpICpvcmlnaW5hbF9lbmRwdHIgPSB0ZW1wX2VuZHB0cjsKKyAgaWYgKCp0ZW1wX2VuZHB0ciAhPSAnLicpIHJldHVybiByZXN1bHQ7CisKKyAgLy8gUGFyc2luZyBoYWx0ZWQgb24gYSAnLicuICBQZXJoYXBzIHdlJ3JlIGluIGEgZGlmZmVyZW50IGxvY2FsZT8gIExldCdzCisgIC8vIHRyeSB0byByZXBsYWNlIHRoZSAnLicgd2l0aCBhIGxvY2FsZS1zcGVjaWZpYyByYWRpeCBjaGFyYWN0ZXIgYW5kCisgIC8vIHRyeSBhZ2Fpbi4KKyAgc3RyaW5nIGxvY2FsaXplZCA9IExvY2FsaXplUmFkaXgodGV4dCwgdGVtcF9lbmRwdHIpOworICBjb25zdCBjaGFyKiBsb2NhbGl6ZWRfY3N0ciA9IGxvY2FsaXplZC5jX3N0cigpOworICBjaGFyKiBsb2NhbGl6ZWRfZW5kcHRyOworICByZXN1bHQgPSBzdHJ0b2QobG9jYWxpemVkX2NzdHIsICZsb2NhbGl6ZWRfZW5kcHRyKTsKKyAgaWYgKChsb2NhbGl6ZWRfZW5kcHRyIC0gbG9jYWxpemVkX2NzdHIpID4KKyAgICAgICh0ZW1wX2VuZHB0ciAtIHRleHQpKSB7CisgICAgLy8gVGhpcyBhdHRlbXB0IGdvdCBmdXJ0aGVyLCBzbyByZXBsYWNpbmcgdGhlIGRlY2ltYWwgbXVzdCBoYXZlIGhlbHBlZC4KKyAgICAvLyBVcGRhdGUgb3JpZ2luYWxfZW5kcHRyIHRvIHBvaW50IGF0IHRoZSByaWdodCBsb2NhdGlvbi4KKyAgICBpZiAob3JpZ2luYWxfZW5kcHRyICE9IE5VTEwpIHsKKyAgICAgIC8vIHNpemVfZGlmZiBpcyBub24temVybyBpZiB0aGUgbG9jYWxpemVkIHJhZGl4IGhhcyBtdWx0aXBsZSBieXRlcy4KKyAgICAgIGludCBzaXplX2RpZmYgPSBsb2NhbGl6ZWQuc2l6ZSgpIC0gc3RybGVuKHRleHQpOworICAgICAgLy8gY29uc3RfY2FzdCBpcyBuZWNlc3NhcnkgdG8gbWF0Y2ggdGhlIHN0cnRvZCgpIGludGVyZmFjZS4KKyAgICAgICpvcmlnaW5hbF9lbmRwdHIgPSBjb25zdF9jYXN0PGNoYXIqPigKKyAgICAgICAgdGV4dCArIChsb2NhbGl6ZWRfZW5kcHRyIC0gbG9jYWxpemVkX2NzdHIgLSBzaXplX2RpZmYpKTsKKyAgICB9CisgIH0KKworICByZXR1cm4gcmVzdWx0OworfQorCitmbG9hdCBTYWZlRG91YmxlVG9GbG9hdChkb3VibGUgdmFsdWUpIHsKKyAgaWYgKHZhbHVlID4gc3RkOjpudW1lcmljX2xpbWl0czxmbG9hdD46Om1heCgpKSB7CisgICAgcmV0dXJuIHN0ZDo6bnVtZXJpY19saW1pdHM8ZmxvYXQ+OjppbmZpbml0eSgpOworICB9IGVsc2UgaWYgKHZhbHVlIDwgLXN0ZDo6bnVtZXJpY19saW1pdHM8ZmxvYXQ+OjptYXgoKSkgeworICAgIHJldHVybiAtc3RkOjpudW1lcmljX2xpbWl0czxmbG9hdD46OmluZmluaXR5KCk7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIHN0YXRpY19jYXN0PGZsb2F0Pih2YWx1ZSk7CisgIH0KK30KKworfSAgLy8gbmFtZXNwYWNlIGlvCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vc3RydG9kLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3N0cnRvZC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY1NmU0MWMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3N0cnRvZC5oCkBAIC0wLDAgKzEsNTUgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBIGxvY2FsZS1pbmRlcGVuZGVudCB2ZXJzaW9uIG9mIHN0cnRvZCgpLCB1c2VkIHRvIHBhcnNlIGZsb2F0aW5nCisvLyBwb2ludCBkZWZhdWx0IHZhbHVlcyBpbiAucHJvdG8gZmlsZXMsIHdoZXJlIHRoZSBkZWNpbWFsIHNlcGFyYXRvcgorLy8gaXMgYWx3YXlzIGEgZG90LgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9JT19TVFJUT0RfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9JT19TVFJUT0RfSF9fCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbyB7CisKKy8vIEEgbG9jYWxlLWluZGVwZW5kZW50IHZlcnNpb24gb2YgdGhlIHN0YW5kYXJkIHN0cnRvZCgpLCB3aGljaCBhbHdheXMKKy8vIHVzZXMgYSBkb3QgYXMgdGhlIGRlY2ltYWwgc2VwYXJhdG9yLgorZG91YmxlIE5vTG9jYWxlU3RydG9kKGNvbnN0IGNoYXIqIHN0ciwgY2hhcioqIGVuZHB0cik7CisKKy8vIENhc3RzIGEgZG91YmxlIHZhbHVlIHRvIGEgZmxvYXQgdmFsdWUuIElmIHRoZSB2YWx1ZSBpcyBvdXRzaWRlIG9mIHRoZQorLy8gcmVwcmVzZW50YWJsZSByYW5nZSBvZiBmbG9hdCwgaXQgd2lsbCBiZSBjb252ZXJ0ZWQgdG8gcG9zaXRpdmUgb3IgbmVnYXRpdmUKKy8vIGluZmluaXR5LgorZmxvYXQgU2FmZURvdWJsZVRvRmxvYXQoZG91YmxlIHZhbHVlKTsKKworfSAgLy8gbmFtZXNwYWNlIGlvCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfSU9fU1RSVE9EX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby90b2tlbml6ZXIuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3Rva2VuaXplci5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZDU3NzA3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby90b2tlbml6ZXIuY2MKQEAgLTAsMCArMSwxMTM3IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisvLworLy8gSGVyZSB3ZSBoYXZlIGEgaGFuZC13cml0dGVuIGxleGVyLiAgQXQgZmlyc3QgeW91IG1pZ2h0IGFzayB5b3Vyc2VsZiwKKy8vICJIYW5kLXdyaXR0ZW4gdGV4dCBwcm9jZXNzaW5nPyAgSXMgS2VudG9uIGNyYXp5PyEiICBXZWxsLCBmaXJzdCBvZiBhbGwsCisvLyB5ZXMgSSBhbSBjcmF6eSwgYnV0IHRoYXQncyBiZXNpZGUgdGhlIHBvaW50LiAgVGhlcmUgYXJlIGFjdHVhbGx5IHJlYXNvbnMKKy8vIHdoeSBJIGVuZGVkIHVwIHdyaXRpbmcgdGhpcyB0aGlzIHdheS4KKy8vCisvLyBUaGUgdHJhZGl0aW9uYWwgYXBwcm9hY2ggdG8gbGV4aW5nIGlzIHRvIHVzZSBsZXggdG8gZ2VuZXJhdGUgYSBsZXhlciBmb3IKKy8vIHlvdS4gIFVuZm9ydHVuYXRlbHksIGxleCdzIG91dHB1dCBpcyByaWRpY3Vsb3VzbHkgdWdseSBhbmQgZGlmZmljdWx0IHRvCisvLyBpbnRlZ3JhdGUgY2xlYW5seSB3aXRoIEMrKyBjb2RlLCBlc3BlY2lhbGx5IGFic3RyYWN0IGNvZGUgb3IgY29kZSBtZWFudAorLy8gYXMgYSBsaWJyYXJ5LiAgQmV0dGVyIHBhcnNlci1nZW5lcmF0b3JzIGV4aXN0IGJ1dCB3b3VsZCBhZGQgZGVwZW5kZW5jaWVzCisvLyB3aGljaCBtb3N0IHVzZXJzIHdvbid0IGFscmVhZHkgaGF2ZSwgd2hpY2ggd2UnZCBsaWtlIHRvIGF2b2lkLiAgKEdOVSBmbGV4CisvLyBoYXMgYSBDKysgb3V0cHV0IG9wdGlvbiwgYnV0IGl0J3Mgc3RpbGwgcmlkaWN1bG91c2x5IHVnbHksIG5vbi1hYnN0cmFjdCwKKy8vIGFuZCBub3QgbGlicmFyeS1mcmllbmRseS4pCisvLworLy8gVGhlIG5leHQgYXBwcm9hY2ggdGhhdCBhbnkgZ29vZCBzb2Z0d2FyZSBlbmdpbmVlciBzaG91bGQgbG9vayBhdCBpcyB0bworLy8gdXNlIHJlZ3VsYXIgZXhwcmVzc2lvbnMuICBBbmQsIGluZGVlZCwgSSBkaWQuICBJIGhhdmUgY29kZSB3aGljaAorLy8gaW1wbGVtZW50cyB0aGlzIHNhbWUgY2xhc3MgdXNpbmcgcmVndWxhciBleHByZXNzaW9ucy4gIEl0J3MgYWJvdXQgMjAwCisvLyBsaW5lcyBzaG9ydGVyLiAgSG93ZXZlcjoKKy8vIC0gUmF0aGVyIHRoYW4gZXJyb3IgbWVzc2FnZXMgdGVsbGluZyB5b3UgIlRoaXMgc3RyaW5nIGhhcyBhbiBpbnZhbGlkCisvLyAgIGVzY2FwZSBzZXF1ZW5jZSBhdCBsaW5lIDUsIGNvbHVtbiA0NSIsIHlvdSBnZXQgZXJyb3IgbWVzc2FnZXMgbGlrZQorLy8gICAiUGFyc2UgZXJyb3Igb24gbGluZSA1Ii4gIEdpdmluZyBtb3JlIHByZWNpc2UgZXJyb3JzIHJlcXVpcmVzIGFkZGluZworLy8gICBhIGxvdCBvZiBjb2RlIHRoYXQgZW5kcyB1cCBiYXNpY2FsbHkgYXMgY29tcGxleCBhcyB0aGUgaGFuZC1jb2RlZAorLy8gICB2ZXJzaW9uIGFueXdheS4KKy8vIC0gVGhlIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byBtYXRjaCBhIHN0cmluZyBsaXRlcmFsIGxvb2tzIGxpa2UgdGhpczoKKy8vICAgICBrU3RyaW5nICA9IG5ldyBSRSgiKFwiKFteXCJcXFxcXXwiICAgICAgICAgICAgICAvLyBub24tZXNjYXBlZAorLy8gICAgICAgICAgICAgICAgICAgICAgICJcXFxcW2FiZm5ydHY/XCInXFxcXDAtN118IiAgIC8vIG5vcm1hbCBlc2NhcGUKKy8vICAgICAgICAgICAgICAgICAgICAgICAiXFxcXHhbMC05YS1mQS1GXSkqXCJ8IiAgICAgICAvLyBoZXggZXNjYXBlCisvLyAgICAgICAgICAgICAgICAgICAgICAgIlwnKFteXCdcXFxcXXwiICAgICAgICAvLyBBbHNvIHN1cHBvcnQgc2luZ2xlLXF1b3Rlcy4KKy8vICAgICAgICAgICAgICAgICAgICAgICAiXFxcXFthYmZucnR2P1wiJ1xcXFwwLTddfCIKKy8vICAgICAgICAgICAgICAgICAgICAgICAiXFxcXHhbMC05YS1mQS1GXSkqXCcpIik7CisvLyAgIFZlcmlmeWluZyB0aGUgY29ycmVjdG5lc3Mgb2YgdGhpcyBsaW5lIG5vaXNlIGlzIGFjdHVhbGx5IGhhcmRlciB0aGFuCisvLyAgIHZlcmlmeWluZyB0aGUgY29ycmVjdG5lc3Mgb2YgQ29uc3VtZVN0cmluZygpLCBkZWZpbmVkIGJlbG93LiAgSSdtIG5vdAorLy8gICBldmVuIGNvbmZpZGVudCB0aGF0IHRoZSBhYm92ZSBpcyBjb3JyZWN0LCBhZnRlciBzdGFyaW5nIGF0IGl0IGZvciBzb21lCisvLyAgIHRpbWUuCisvLyAtIFBDUkUgaXMgZmFzdCwgYnV0IHRoZXJlJ3Mgc3RpbGwgbW9yZSBvdmVyaGVhZCBpbnZvbHZlZCB0aGFuIHRoZSBjb2RlCisvLyAgIGJlbG93LgorLy8gLSBTYWRseSwgcmVndWxhciBleHByZXNzaW9ucyBhcmUgbm90IHBhcnQgb2YgdGhlIEMgc3RhbmRhcmQgbGlicmFyeSwgc28KKy8vICAgdXNpbmcgdGhlbSB3b3VsZCByZXF1aXJlIGRlcGVuZGluZyBvbiBzb21lIG90aGVyIGxpYnJhcnkuICBGb3IgdGhlCisvLyAgIG9wZW4gc291cmNlIHJlbGVhc2UsIHRoaXMgY291bGQgYmUgcmVhbGx5IGFubm95aW5nLiAgTm9ib2R5IGxpa2VzCisvLyAgIGRvd25sb2FkaW5nIG9uZSBwaWVjZSBvZiBzb2Z0d2FyZSBqdXN0IHRvIGZpbmQgdGhhdCB0aGV5IG5lZWQgdG8KKy8vICAgZG93bmxvYWQgc29tZXRoaW5nIGVsc2UgdG8gbWFrZSBpdCB3b3JrLCBhbmQgaW4gYWxsIGxpa2VsaWhvb2QKKy8vICAgcGVvcGxlIGRvd25sb2FkaW5nIFByb3RvY29sIEJ1ZmZlcnMgd2lsbCBhbHJlYWR5IGJlIGRvaW5nIHNvIGp1c3QKKy8vICAgdG8gbWFrZSBzb21ldGhpbmcgZWxzZSB3b3JrLiAgV2UgY291bGQgaW5jbHVkZSBhIGNvcHkgb2YgUENSRSB3aXRoCisvLyAgIG91ciBjb2RlLCBidXQgdGhhdCBvYmxpZ2F0ZXMgdXMgdG8ga2VlcCBpdCB1cC10by1kYXRlIGFuZCBqdXN0IHNlZW1zCisvLyAgIGxpa2UgYSBiaWcgd2FzdGUganVzdCB0byBzYXZlIDIwMCBsaW5lcyBvZiBjb2RlLgorLy8KKy8vIE9uIGEgc2ltaWxhciBidXQgdW5yZWxhdGVkIG5vdGUsIEknbSBldmVuIHNjYXJlZCB0byB1c2UgY3R5cGUuaC4KKy8vIEFwcGFyZW50bHkgZnVuY3Rpb25zIGxpa2UgaXNhbHBoYSgpIGFyZSBsb2NhbGUtZGVwZW5kZW50LiAgU28sIGlmIHdlIHVzZWQKKy8vIHRoYXQsIHRoZW4gaWYgdGhpcyBjb2RlIGlzIGJlaW5nIGNhbGxlZCBmcm9tIHNvbWUgcHJvZ3JhbSB0aGF0IGRvZXNuJ3QKKy8vIGhhdmUgaXRzIGxvY2FsZSBzZXQgdG8gIkMiLCBpdCB3b3VsZCBiZWhhdmUgc3RyYW5nZWx5LiAgV2UgY2FuJ3QganVzdCBzZXQKKy8vIHRoZSBsb2NhbGUgdG8gIkMiIG91cnNlbHZlcyBzaW5jZSB3ZSBtaWdodCBicmVhayB0aGUgY2FsbGluZyBwcm9ncmFtIHRoYXQKKy8vIHdheSwgcGFydGljdWxhcmx5IGlmIGl0IGlzIG11bHRpLXRocmVhZGVkLiAgV1RGPyAgU29tZW9uZSBwbGVhc2UgbGV0IG1lCisvLyAoS2VudG9uKSBrbm93IGlmIEknbSBtaXNzaW5nIHNvbWV0aGluZyBoZXJlLi4uCisvLworLy8gSSdkIGxvdmUgdG8gaGVhciBhYm91dCBvdGhlciBhbHRlcm5hdGl2ZXMsIHRob3VnaCwgYXMgdGhpcyBjb2RlIGlzbid0CisvLyBleGFjdGx5IHByZXR0eS4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby90b2tlbml6ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2xvZ2dpbmcuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RyaW5ncHJpbnRmLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3N0cnRvZC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RsX3V0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGlvIHsKK25hbWVzcGFjZSB7CisKKy8vIEFzIG1lbnRpb25lZCBhYm92ZSwgSSBkb24ndCB0cnVzdCBjdHlwZS5oIGR1ZSB0byB0aGUgcHJlc2VuY2Ugb2YgImxvY2FsZXMiLgorLy8gU28sIEkgaGF2ZSB3cml0dGVuIHJlcGxhY2VtZW50IGZ1bmN0aW9ucyBoZXJlLiAgU29tZW9uZSBwbGVhc2Ugc21hY2sgbWUgaWYKKy8vIHRoaXMgaXMgYSBiYWQgaWRlYSBvciBpZiB0aGVyZSBpcyBzb21lIHdheSBhcm91bmQgdGhpcy4KKy8vCisvLyBUaGVzZSAiY2hhcmFjdGVyIGNsYXNzZXMiIGFyZSBkZXNpZ25lZCB0byBiZSB1c2VkIGluIHRlbXBsYXRlIG1ldGhvZHMuCisvLyBGb3IgaW5zdGFuY2UsIFRva2VuaXplcjo6Q29uc3VtZVplcm9Pck1vcmU8V2hpdGVzcGFjZT4oKSB3aWxsIGVhdAorLy8gd2hpdGVzcGFjZS4KKworLy8gTm90ZTogIE5vIGNsYXNzIGlzIGFsbG93ZWQgdG8gY29udGFpbiAnXDAnLCBzaW5jZSB0aGlzIGlzIHVzZWQgdG8gbWFyayBlbmQtCisvLyAgIG9mLWlucHV0IGFuZCBpcyBoYW5kbGVkIHNwZWNpYWxseS4KKworI2RlZmluZSBDSEFSQUNURVJfQ0xBU1MoTkFNRSwgRVhQUkVTU0lPTikgICAgICBcCisgIGNsYXNzIE5BTUUgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgIHB1YmxpYzogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIHN0YXRpYyBpbmxpbmUgYm9vbCBJbkNsYXNzKGNoYXIgYykgeyAgICAgICBcCisgICAgICByZXR1cm4gRVhQUkVTU0lPTjsgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9CisKK0NIQVJBQ1RFUl9DTEFTUyhXaGl0ZXNwYWNlLCBjID09ICcgJyB8fCBjID09ICdcbicgfHwgYyA9PSAnXHQnIHx8CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYyA9PSAnXHInIHx8IGMgPT0gJ1x2JyB8fCBjID09ICdcZicpOworQ0hBUkFDVEVSX0NMQVNTKFdoaXRlc3BhY2VOb05ld2xpbmUsIGMgPT0gJyAnIHx8IGMgPT0gJ1x0JyB8fAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMgPT0gJ1xyJyB8fCBjID09ICdcdicgfHwgYyA9PSAnXGYnKTsKKworQ0hBUkFDVEVSX0NMQVNTKFVucHJpbnRhYmxlLCBjIDwgJyAnICYmIGMgPiAnXDAnKTsKKworQ0hBUkFDVEVSX0NMQVNTKERpZ2l0LCAnMCcgPD0gYyAmJiBjIDw9ICc5Jyk7CitDSEFSQUNURVJfQ0xBU1MoT2N0YWxEaWdpdCwgJzAnIDw9IGMgJiYgYyA8PSAnNycpOworQ0hBUkFDVEVSX0NMQVNTKEhleERpZ2l0LCAoJzAnIDw9IGMgJiYgYyA8PSAnOScpIHx8CisgICAgICAgICAgICAgICAgICAgICAgICAgICgnYScgPD0gYyAmJiBjIDw9ICdmJykgfHwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgKCdBJyA8PSBjICYmIGMgPD0gJ0YnKSk7CisKK0NIQVJBQ1RFUl9DTEFTUyhMZXR0ZXIsICgnYScgPD0gYyAmJiBjIDw9ICd6JykgfHwKKyAgICAgICAgICAgICAgICAgICAgICAgICgnQScgPD0gYyAmJiBjIDw9ICdaJykgfHwKKyAgICAgICAgICAgICAgICAgICAgICAgIChjID09ICdfJykpOworCitDSEFSQUNURVJfQ0xBU1MoQWxwaGFudW1lcmljLCAoJ2EnIDw9IGMgJiYgYyA8PSAneicpIHx8CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoJ0EnIDw9IGMgJiYgYyA8PSAnWicpIHx8CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoJzAnIDw9IGMgJiYgYyA8PSAnOScpIHx8CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYyA9PSAnXycpKTsKKworQ0hBUkFDVEVSX0NMQVNTKEVzY2FwZSwgYyA9PSAnYScgfHwgYyA9PSAnYicgfHwgYyA9PSAnZicgfHwgYyA9PSAnbicgfHwKKyAgICAgICAgICAgICAgICAgICAgICAgIGMgPT0gJ3InIHx8IGMgPT0gJ3QnIHx8IGMgPT0gJ3YnIHx8IGMgPT0gJ1xcJyB8fAorICAgICAgICAgICAgICAgICAgICAgICAgYyA9PSAnPycgfHwgYyA9PSAnXCcnIHx8IGMgPT0gJ1wiJyk7CisKKyN1bmRlZiBDSEFSQUNURVJfQ0xBU1MKKworLy8gR2l2ZW4gYSBjaGFyLCBpbnRlcnByZXQgaXQgYXMgYSBudW1lcmljIGRpZ2l0IGFuZCByZXR1cm4gaXRzIHZhbHVlLgorLy8gVGhpcyBzdXBwb3J0cyBhbnkgbnVtYmVyIGJhc2UgdXAgdG8gMzYuCitpbmxpbmUgaW50IERpZ2l0VmFsdWUoY2hhciBkaWdpdCkgeworICBpZiAoJzAnIDw9IGRpZ2l0ICYmIGRpZ2l0IDw9ICc5JykgcmV0dXJuIGRpZ2l0IC0gJzAnOworICBpZiAoJ2EnIDw9IGRpZ2l0ICYmIGRpZ2l0IDw9ICd6JykgcmV0dXJuIGRpZ2l0IC0gJ2EnICsgMTA7CisgIGlmICgnQScgPD0gZGlnaXQgJiYgZGlnaXQgPD0gJ1onKSByZXR1cm4gZGlnaXQgLSAnQScgKyAxMDsKKyAgcmV0dXJuIC0xOworfQorCisvLyBJbmxpbmUgYmVjYXVzZSBpdCdzIG9ubHkgdXNlZCBpbiBvbmUgcGxhY2UuCitpbmxpbmUgY2hhciBUcmFuc2xhdGVFc2NhcGUoY2hhciBjKSB7CisgIHN3aXRjaCAoYykgeworICAgIGNhc2UgJ2EnOiAgcmV0dXJuICdcYSc7CisgICAgY2FzZSAnYic6ICByZXR1cm4gJ1xiJzsKKyAgICBjYXNlICdmJzogIHJldHVybiAnXGYnOworICAgIGNhc2UgJ24nOiAgcmV0dXJuICdcbic7CisgICAgY2FzZSAncic6ICByZXR1cm4gJ1xyJzsKKyAgICBjYXNlICd0JzogIHJldHVybiAnXHQnOworICAgIGNhc2UgJ3YnOiAgcmV0dXJuICdcdic7CisgICAgY2FzZSAnXFwnOiByZXR1cm4gJ1xcJzsKKyAgICBjYXNlICc/JzogIHJldHVybiAnXD8nOyAgICAvLyBUcmlncmFwaHMgPSA6KAorICAgIGNhc2UgJ1wnJzogcmV0dXJuICdcJyc7CisgICAgY2FzZSAnIic6ICByZXR1cm4gJ1wiJzsKKworICAgIC8vIFdlIGV4cGVjdCBlc2NhcGUgc2VxdWVuY2VzIHRvIGhhdmUgYmVlbiB2YWxpZGF0ZWQgc2VwYXJhdGVseS4KKyAgICBkZWZhdWx0OiAgIHJldHVybiAnPyc7CisgIH0KK30KKworfSAgLy8gYW5vbnltb3VzIG5hbWVzcGFjZQorCitFcnJvckNvbGxlY3Rvcjo6fkVycm9yQ29sbGVjdG9yKCkge30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitUb2tlbml6ZXI6OlRva2VuaXplcihaZXJvQ29weUlucHV0U3RyZWFtKiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgIEVycm9yQ29sbGVjdG9yKiBlcnJvcl9jb2xsZWN0b3IpCisgIDogaW5wdXRfKGlucHV0KSwKKyAgICBlcnJvcl9jb2xsZWN0b3JfKGVycm9yX2NvbGxlY3RvciksCisgICAgYnVmZmVyXyhOVUxMKSwKKyAgICBidWZmZXJfc2l6ZV8oMCksCisgICAgYnVmZmVyX3Bvc18oMCksCisgICAgcmVhZF9lcnJvcl8oZmFsc2UpLAorICAgIGxpbmVfKDApLAorICAgIGNvbHVtbl8oMCksCisgICAgcmVjb3JkX3RhcmdldF8oTlVMTCksCisgICAgcmVjb3JkX3N0YXJ0XygtMSksCisgICAgYWxsb3dfZl9hZnRlcl9mbG9hdF8oZmFsc2UpLAorICAgIGNvbW1lbnRfc3R5bGVfKENQUF9DT01NRU5UX1NUWUxFKSwKKyAgICByZXF1aXJlX3NwYWNlX2FmdGVyX251bWJlcl8odHJ1ZSksCisgICAgYWxsb3dfbXVsdGlsaW5lX3N0cmluZ3NfKGZhbHNlKSB7CisKKyAgY3VycmVudF8ubGluZSA9IDA7CisgIGN1cnJlbnRfLmNvbHVtbiA9IDA7CisgIGN1cnJlbnRfLmVuZF9jb2x1bW4gPSAwOworICBjdXJyZW50Xy50eXBlID0gVFlQRV9TVEFSVDsKKworICBSZWZyZXNoKCk7Cit9CisKK1Rva2VuaXplcjo6flRva2VuaXplcigpIHsKKyAgLy8gSWYgd2UgaGFkIGFueSBidWZmZXIgbGVmdCB1bnJlYWQsIHJldHVybiBpdCB0byB0aGUgdW5kZXJseWluZyBzdHJlYW0KKyAgLy8gc28gdGhhdCBzb21lb25lIGVsc2UgY2FuIHJlYWQgaXQuCisgIGlmIChidWZmZXJfc2l6ZV8gPiBidWZmZXJfcG9zXykgeworICAgIGlucHV0Xy0+QmFja1VwKGJ1ZmZlcl9zaXplXyAtIGJ1ZmZlcl9wb3NfKTsKKyAgfQorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBJbnRlcm5hbCBoZWxwZXJzLgorCit2b2lkIFRva2VuaXplcjo6TmV4dENoYXIoKSB7CisgIC8vIFVwZGF0ZSBvdXIgbGluZSBhbmQgY29sdW1uIGNvdW50ZXJzIGJhc2VkIG9uIHRoZSBjaGFyYWN0ZXIgYmVpbmcKKyAgLy8gY29uc3VtZWQuCisgIGlmIChjdXJyZW50X2NoYXJfID09ICdcbicpIHsKKyAgICArK2xpbmVfOworICAgIGNvbHVtbl8gPSAwOworICB9IGVsc2UgaWYgKGN1cnJlbnRfY2hhcl8gPT0gJ1x0JykgeworICAgIGNvbHVtbl8gKz0ga1RhYldpZHRoIC0gY29sdW1uXyAlIGtUYWJXaWR0aDsKKyAgfSBlbHNlIHsKKyAgICArK2NvbHVtbl87CisgIH0KKworICAvLyBBZHZhbmNlIHRvIHRoZSBuZXh0IGNoYXJhY3Rlci4KKyAgKytidWZmZXJfcG9zXzsKKyAgaWYgKGJ1ZmZlcl9wb3NfIDwgYnVmZmVyX3NpemVfKSB7CisgICAgY3VycmVudF9jaGFyXyA9IGJ1ZmZlcl9bYnVmZmVyX3Bvc19dOworICB9IGVsc2UgeworICAgIFJlZnJlc2goKTsKKyAgfQorfQorCit2b2lkIFRva2VuaXplcjo6UmVmcmVzaCgpIHsKKyAgaWYgKHJlYWRfZXJyb3JfKSB7CisgICAgY3VycmVudF9jaGFyXyA9ICdcMCc7CisgICAgcmV0dXJuOworICB9CisKKyAgLy8gSWYgd2UncmUgaW4gYSB0b2tlbiwgYXBwZW5kIHRoZSByZXN0IG9mIHRoZSBidWZmZXIgdG8gaXQuCisgIGlmIChyZWNvcmRfdGFyZ2V0XyAhPSBOVUxMICYmIHJlY29yZF9zdGFydF8gPCBidWZmZXJfc2l6ZV8pIHsKKyAgICByZWNvcmRfdGFyZ2V0Xy0+YXBwZW5kKGJ1ZmZlcl8gKyByZWNvcmRfc3RhcnRfLCBidWZmZXJfc2l6ZV8gLSByZWNvcmRfc3RhcnRfKTsKKyAgICByZWNvcmRfc3RhcnRfID0gMDsKKyAgfQorCisgIGNvbnN0IHZvaWQqIGRhdGEgPSBOVUxMOworICBidWZmZXJfID0gTlVMTDsKKyAgYnVmZmVyX3Bvc18gPSAwOworICBkbyB7CisgICAgaWYgKCFpbnB1dF8tPk5leHQoJmRhdGEsICZidWZmZXJfc2l6ZV8pKSB7CisgICAgICAvLyBlbmQgb2Ygc3RyZWFtIChvciByZWFkIGVycm9yKQorICAgICAgYnVmZmVyX3NpemVfID0gMDsKKyAgICAgIHJlYWRfZXJyb3JfID0gdHJ1ZTsKKyAgICAgIGN1cnJlbnRfY2hhcl8gPSAnXDAnOworICAgICAgcmV0dXJuOworICAgIH0KKyAgfSB3aGlsZSAoYnVmZmVyX3NpemVfID09IDApOworCisgIGJ1ZmZlcl8gPSBzdGF0aWNfY2FzdDxjb25zdCBjaGFyKj4oZGF0YSk7CisKKyAgY3VycmVudF9jaGFyXyA9IGJ1ZmZlcl9bMF07Cit9CisKK2lubGluZSB2b2lkIFRva2VuaXplcjo6UmVjb3JkVG8oc3RyaW5nKiB0YXJnZXQpIHsKKyAgcmVjb3JkX3RhcmdldF8gPSB0YXJnZXQ7CisgIHJlY29yZF9zdGFydF8gPSBidWZmZXJfcG9zXzsKK30KKworaW5saW5lIHZvaWQgVG9rZW5pemVyOjpTdG9wUmVjb3JkaW5nKCkgeworICAvLyBOb3RlOiAgVGhlIGlmKCkgaXMgbmVjZXNzYXJ5IGJlY2F1c2Ugc29tZSBTVEwgaW1wbGVtZW50YXRpb25zIGNyYXNoIHdoZW4KKyAgLy8gICB5b3UgY2FsbCBzdHJpbmc6OmFwcGVuZChOVUxMLCAwKSwgcHJlc3VtYWJseSBiZWNhdXNlIHRoZXkgYXJlIHRyeWluZyB0bworICAvLyAgIGJlIGhlbHBmdWwgYnkgZGV0ZWN0aW5nIHRoZSBOVUxMIHBvaW50ZXIsIGV2ZW4gdGhvdWdoIHRoZXJlJ3Mgbm90aGluZworICAvLyAgIHdyb25nIHdpdGggcmVhZGluZyB6ZXJvIGJ5dGVzIGZyb20gTlVMTC4KKyAgaWYgKGJ1ZmZlcl9wb3NfICE9IHJlY29yZF9zdGFydF8pIHsKKyAgICByZWNvcmRfdGFyZ2V0Xy0+YXBwZW5kKGJ1ZmZlcl8gKyByZWNvcmRfc3RhcnRfLCBidWZmZXJfcG9zXyAtIHJlY29yZF9zdGFydF8pOworICB9CisgIHJlY29yZF90YXJnZXRfID0gTlVMTDsKKyAgcmVjb3JkX3N0YXJ0XyA9IC0xOworfQorCitpbmxpbmUgdm9pZCBUb2tlbml6ZXI6OlN0YXJ0VG9rZW4oKSB7CisgIGN1cnJlbnRfLnR5cGUgPSBUWVBFX1NUQVJUOyAgICAvLyBKdXN0IGZvciB0aGUgc2FrZSBvZiBpbml0aWFsaXppbmcgaXQuCisgIGN1cnJlbnRfLnRleHQuY2xlYXIoKTsKKyAgY3VycmVudF8ubGluZSA9IGxpbmVfOworICBjdXJyZW50Xy5jb2x1bW4gPSBjb2x1bW5fOworICBSZWNvcmRUbygmY3VycmVudF8udGV4dCk7Cit9CisKK2lubGluZSB2b2lkIFRva2VuaXplcjo6RW5kVG9rZW4oKSB7CisgIFN0b3BSZWNvcmRpbmcoKTsKKyAgY3VycmVudF8uZW5kX2NvbHVtbiA9IGNvbHVtbl87Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIEhlbHBlciBtZXRob2RzIHRoYXQgY29uc3VtZSBjaGFyYWN0ZXJzLgorCit0ZW1wbGF0ZTx0eXBlbmFtZSBDaGFyYWN0ZXJDbGFzcz4KK2lubGluZSBib29sIFRva2VuaXplcjo6TG9va2luZ0F0KCkgeworICByZXR1cm4gQ2hhcmFjdGVyQ2xhc3M6OkluQ2xhc3MoY3VycmVudF9jaGFyXyk7Cit9CisKK3RlbXBsYXRlPHR5cGVuYW1lIENoYXJhY3RlckNsYXNzPgoraW5saW5lIGJvb2wgVG9rZW5pemVyOjpUcnlDb25zdW1lT25lKCkgeworICBpZiAoQ2hhcmFjdGVyQ2xhc3M6OkluQ2xhc3MoY3VycmVudF9jaGFyXykpIHsKKyAgICBOZXh0Q2hhcigpOworICAgIHJldHVybiB0cnVlOworICB9IGVsc2UgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorfQorCitpbmxpbmUgYm9vbCBUb2tlbml6ZXI6OlRyeUNvbnN1bWUoY2hhciBjKSB7CisgIGlmIChjdXJyZW50X2NoYXJfID09IGMpIHsKKyAgICBOZXh0Q2hhcigpOworICAgIHJldHVybiB0cnVlOworICB9IGVsc2UgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorfQorCit0ZW1wbGF0ZTx0eXBlbmFtZSBDaGFyYWN0ZXJDbGFzcz4KK2lubGluZSB2b2lkIFRva2VuaXplcjo6Q29uc3VtZVplcm9Pck1vcmUoKSB7CisgIHdoaWxlIChDaGFyYWN0ZXJDbGFzczo6SW5DbGFzcyhjdXJyZW50X2NoYXJfKSkgeworICAgIE5leHRDaGFyKCk7CisgIH0KK30KKwordGVtcGxhdGU8dHlwZW5hbWUgQ2hhcmFjdGVyQ2xhc3M+CitpbmxpbmUgdm9pZCBUb2tlbml6ZXI6OkNvbnN1bWVPbmVPck1vcmUoY29uc3QgY2hhciogZXJyb3IpIHsKKyAgaWYgKCFDaGFyYWN0ZXJDbGFzczo6SW5DbGFzcyhjdXJyZW50X2NoYXJfKSkgeworICAgIEFkZEVycm9yKGVycm9yKTsKKyAgfSBlbHNlIHsKKyAgICBkbyB7CisgICAgICBOZXh0Q2hhcigpOworICAgIH0gd2hpbGUgKENoYXJhY3RlckNsYXNzOjpJbkNsYXNzKGN1cnJlbnRfY2hhcl8pKTsKKyAgfQorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBNZXRob2RzIHRoYXQgcmVhZCB3aG9sZSBwYXR0ZXJucyBtYXRjaGluZyBjZXJ0YWluIGtpbmRzIG9mIHRva2VucworLy8gb3IgY29tbWVudHMuCisKK3ZvaWQgVG9rZW5pemVyOjpDb25zdW1lU3RyaW5nKGNoYXIgZGVsaW1pdGVyKSB7CisgIHdoaWxlICh0cnVlKSB7CisgICAgc3dpdGNoIChjdXJyZW50X2NoYXJfKSB7CisgICAgICBjYXNlICdcMCc6CisgICAgICAgIEFkZEVycm9yKCJVbmV4cGVjdGVkIGVuZCBvZiBzdHJpbmcuIik7CisgICAgICAgIHJldHVybjsKKworICAgICAgY2FzZSAnXG4nOiB7CisgICAgICAgIGlmICghYWxsb3dfbXVsdGlsaW5lX3N0cmluZ3NfKSB7CisgICAgICAgICAgQWRkRXJyb3IoIlN0cmluZyBsaXRlcmFscyBjYW5ub3QgY3Jvc3MgbGluZSBib3VuZGFyaWVzLiIpOworICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBOZXh0Q2hhcigpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgY2FzZSAnXFwnOiB7CisgICAgICAgIC8vIEFuIGVzY2FwZSBzZXF1ZW5jZS4KKyAgICAgICAgTmV4dENoYXIoKTsKKyAgICAgICAgaWYgKFRyeUNvbnN1bWVPbmU8RXNjYXBlPigpKSB7CisgICAgICAgICAgLy8gVmFsaWQgZXNjYXBlIHNlcXVlbmNlLgorICAgICAgICB9IGVsc2UgaWYgKFRyeUNvbnN1bWVPbmU8T2N0YWxEaWdpdD4oKSkgeworICAgICAgICAgIC8vIFBvc3NpYmx5IGZvbGxvd2VkIGJ5IHR3byBtb3JlIG9jdGFsIGRpZ2l0cywgYnV0IHRoZXNlIHdpbGwKKyAgICAgICAgICAvLyBqdXN0IGJlIGNvbnN1bWVkIGJ5IHRoZSBtYWluIGxvb3AgYW55d2F5IHNvIHdlIGRvbid0IG5lZWQKKyAgICAgICAgICAvLyB0byBkbyBzbyBleHBsaWNpdGx5IGhlcmUuCisgICAgICAgIH0gZWxzZSBpZiAoVHJ5Q29uc3VtZSgneCcpKSB7CisgICAgICAgICAgaWYgKCFUcnlDb25zdW1lT25lPEhleERpZ2l0PigpKSB7CisgICAgICAgICAgICBBZGRFcnJvcigiRXhwZWN0ZWQgaGV4IGRpZ2l0cyBmb3IgZXNjYXBlIHNlcXVlbmNlLiIpOworICAgICAgICAgIH0KKyAgICAgICAgICAvLyBQb3NzaWJseSBmb2xsb3dlZCBieSBhbm90aGVyIGhleCBkaWdpdCwgYnV0IGFnYWluIHdlIGRvbid0IGNhcmUuCisgICAgICAgIH0gZWxzZSBpZiAoVHJ5Q29uc3VtZSgndScpKSB7CisgICAgICAgICAgaWYgKCFUcnlDb25zdW1lT25lPEhleERpZ2l0PigpIHx8CisgICAgICAgICAgICAgICFUcnlDb25zdW1lT25lPEhleERpZ2l0PigpIHx8CisgICAgICAgICAgICAgICFUcnlDb25zdW1lT25lPEhleERpZ2l0PigpIHx8CisgICAgICAgICAgICAgICFUcnlDb25zdW1lT25lPEhleERpZ2l0PigpKSB7CisgICAgICAgICAgICBBZGRFcnJvcigiRXhwZWN0ZWQgZm91ciBoZXggZGlnaXRzIGZvciBcXHUgZXNjYXBlIHNlcXVlbmNlLiIpOworICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIGlmIChUcnlDb25zdW1lKCdVJykpIHsKKyAgICAgICAgICAvLyBXZSBleHBlY3QgOCBoZXggZGlnaXRzOyBidXQgb25seSB0aGUgcmFuZ2UgdXAgdG8gMHgxMGZmZmYgaXMKKyAgICAgICAgICAvLyBsZWdhbC4KKyAgICAgICAgICBpZiAoIVRyeUNvbnN1bWUoJzAnKSB8fAorICAgICAgICAgICAgICAhVHJ5Q29uc3VtZSgnMCcpIHx8CisgICAgICAgICAgICAgICEoVHJ5Q29uc3VtZSgnMCcpIHx8IFRyeUNvbnN1bWUoJzEnKSkgfHwKKyAgICAgICAgICAgICAgIVRyeUNvbnN1bWVPbmU8SGV4RGlnaXQ+KCkgfHwKKyAgICAgICAgICAgICAgIVRyeUNvbnN1bWVPbmU8SGV4RGlnaXQ+KCkgfHwKKyAgICAgICAgICAgICAgIVRyeUNvbnN1bWVPbmU8SGV4RGlnaXQ+KCkgfHwKKyAgICAgICAgICAgICAgIVRyeUNvbnN1bWVPbmU8SGV4RGlnaXQ+KCkgfHwKKyAgICAgICAgICAgICAgIVRyeUNvbnN1bWVPbmU8SGV4RGlnaXQ+KCkpIHsKKyAgICAgICAgICAgIEFkZEVycm9yKCJFeHBlY3RlZCBlaWdodCBoZXggZGlnaXRzIHVwIHRvIDEwZmZmZiBmb3IgXFxVIGVzY2FwZSAiCisgICAgICAgICAgICAgICAgICAgICAic2VxdWVuY2UiKTsKKyAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgQWRkRXJyb3IoIkludmFsaWQgZXNjYXBlIHNlcXVlbmNlIGluIHN0cmluZyBsaXRlcmFsLiIpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBkZWZhdWx0OiB7CisgICAgICAgIGlmIChjdXJyZW50X2NoYXJfID09IGRlbGltaXRlcikgeworICAgICAgICAgIE5leHRDaGFyKCk7CisgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIE5leHRDaGFyKCk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgfQorfQorCitUb2tlbml6ZXI6OlRva2VuVHlwZSBUb2tlbml6ZXI6OkNvbnN1bWVOdW1iZXIoYm9vbCBzdGFydGVkX3dpdGhfemVybywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIHN0YXJ0ZWRfd2l0aF9kb3QpIHsKKyAgYm9vbCBpc19mbG9hdCA9IGZhbHNlOworCisgIGlmIChzdGFydGVkX3dpdGhfemVybyAmJiAoVHJ5Q29uc3VtZSgneCcpIHx8IFRyeUNvbnN1bWUoJ1gnKSkpIHsKKyAgICAvLyBBIGhleCBudW1iZXIgKHN0YXJ0ZWQgd2l0aCAiMHgiKS4KKyAgICBDb25zdW1lT25lT3JNb3JlPEhleERpZ2l0PigiXCIweFwiIG11c3QgYmUgZm9sbG93ZWQgYnkgaGV4IGRpZ2l0cy4iKTsKKworICB9IGVsc2UgaWYgKHN0YXJ0ZWRfd2l0aF96ZXJvICYmIExvb2tpbmdBdDxEaWdpdD4oKSkgeworICAgIC8vIEFuIG9jdGFsIG51bWJlciAoaGFkIGEgbGVhZGluZyB6ZXJvKS4KKyAgICBDb25zdW1lWmVyb09yTW9yZTxPY3RhbERpZ2l0PigpOworICAgIGlmIChMb29raW5nQXQ8RGlnaXQ+KCkpIHsKKyAgICAgIEFkZEVycm9yKCJOdW1iZXJzIHN0YXJ0aW5nIHdpdGggbGVhZGluZyB6ZXJvIG11c3QgYmUgaW4gb2N0YWwuIik7CisgICAgICBDb25zdW1lWmVyb09yTW9yZTxEaWdpdD4oKTsKKyAgICB9CisKKyAgfSBlbHNlIHsKKyAgICAvLyBBIGRlY2ltYWwgbnVtYmVyLgorICAgIGlmIChzdGFydGVkX3dpdGhfZG90KSB7CisgICAgICBpc19mbG9hdCA9IHRydWU7CisgICAgICBDb25zdW1lWmVyb09yTW9yZTxEaWdpdD4oKTsKKyAgICB9IGVsc2UgeworICAgICAgQ29uc3VtZVplcm9Pck1vcmU8RGlnaXQ+KCk7CisKKyAgICAgIGlmIChUcnlDb25zdW1lKCcuJykpIHsKKyAgICAgICAgaXNfZmxvYXQgPSB0cnVlOworICAgICAgICBDb25zdW1lWmVyb09yTW9yZTxEaWdpdD4oKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBpZiAoVHJ5Q29uc3VtZSgnZScpIHx8IFRyeUNvbnN1bWUoJ0UnKSkgeworICAgICAgaXNfZmxvYXQgPSB0cnVlOworICAgICAgVHJ5Q29uc3VtZSgnLScpIHx8IFRyeUNvbnN1bWUoJysnKTsKKyAgICAgIENvbnN1bWVPbmVPck1vcmU8RGlnaXQ+KCJcImVcIiBtdXN0IGJlIGZvbGxvd2VkIGJ5IGV4cG9uZW50LiIpOworICAgIH0KKworICAgIGlmIChhbGxvd19mX2FmdGVyX2Zsb2F0XyAmJiAoVHJ5Q29uc3VtZSgnZicpIHx8IFRyeUNvbnN1bWUoJ0YnKSkpIHsKKyAgICAgIGlzX2Zsb2F0ID0gdHJ1ZTsKKyAgICB9CisgIH0KKworICBpZiAoTG9va2luZ0F0PExldHRlcj4oKSAmJiByZXF1aXJlX3NwYWNlX2FmdGVyX251bWJlcl8pIHsKKyAgICBBZGRFcnJvcigiTmVlZCBzcGFjZSBiZXR3ZWVuIG51bWJlciBhbmQgaWRlbnRpZmllci4iKTsKKyAgfSBlbHNlIGlmIChjdXJyZW50X2NoYXJfID09ICcuJykgeworICAgIGlmIChpc19mbG9hdCkgeworICAgICAgQWRkRXJyb3IoCisgICAgICAgICJBbHJlYWR5IHNhdyBkZWNpbWFsIHBvaW50IG9yIGV4cG9uZW50OyBjYW4ndCBoYXZlIGFub3RoZXIgb25lLiIpOworICAgIH0gZWxzZSB7CisgICAgICBBZGRFcnJvcigiSGV4IGFuZCBvY3RhbCBudW1iZXJzIG11c3QgYmUgaW50ZWdlcnMuIik7CisgICAgfQorICB9CisKKyAgcmV0dXJuIGlzX2Zsb2F0ID8gVFlQRV9GTE9BVCA6IFRZUEVfSU5URUdFUjsKK30KKwordm9pZCBUb2tlbml6ZXI6OkNvbnN1bWVMaW5lQ29tbWVudChzdHJpbmcqIGNvbnRlbnQpIHsKKyAgaWYgKGNvbnRlbnQgIT0gTlVMTCkgUmVjb3JkVG8oY29udGVudCk7CisKKyAgd2hpbGUgKGN1cnJlbnRfY2hhcl8gIT0gJ1wwJyAmJiBjdXJyZW50X2NoYXJfICE9ICdcbicpIHsKKyAgICBOZXh0Q2hhcigpOworICB9CisgIFRyeUNvbnN1bWUoJ1xuJyk7CisKKyAgaWYgKGNvbnRlbnQgIT0gTlVMTCkgU3RvcFJlY29yZGluZygpOworfQorCit2b2lkIFRva2VuaXplcjo6Q29uc3VtZUJsb2NrQ29tbWVudChzdHJpbmcqIGNvbnRlbnQpIHsKKyAgaW50IHN0YXJ0X2xpbmUgPSBsaW5lXzsKKyAgaW50IHN0YXJ0X2NvbHVtbiA9IGNvbHVtbl8gLSAyOworCisgIGlmIChjb250ZW50ICE9IE5VTEwpIFJlY29yZFRvKGNvbnRlbnQpOworCisgIHdoaWxlICh0cnVlKSB7CisgICAgd2hpbGUgKGN1cnJlbnRfY2hhcl8gIT0gJ1wwJyAmJgorICAgICAgICAgICBjdXJyZW50X2NoYXJfICE9ICcqJyAmJgorICAgICAgICAgICBjdXJyZW50X2NoYXJfICE9ICcvJyAmJgorICAgICAgICAgICBjdXJyZW50X2NoYXJfICE9ICdcbicpIHsKKyAgICAgIE5leHRDaGFyKCk7CisgICAgfQorCisgICAgaWYgKFRyeUNvbnN1bWUoJ1xuJykpIHsKKyAgICAgIGlmIChjb250ZW50ICE9IE5VTEwpIFN0b3BSZWNvcmRpbmcoKTsKKworICAgICAgLy8gQ29uc3VtZSBsZWFkaW5nIHdoaXRlc3BhY2UgYW5kIGFzdGVyaXNrOworICAgICAgQ29uc3VtZVplcm9Pck1vcmU8V2hpdGVzcGFjZU5vTmV3bGluZT4oKTsKKyAgICAgIGlmIChUcnlDb25zdW1lKCcqJykpIHsKKyAgICAgICAgaWYgKFRyeUNvbnN1bWUoJy8nKSkgeworICAgICAgICAgIC8vIEVuZCBvZiBjb21tZW50LgorICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICB9CisKKyAgICAgIGlmIChjb250ZW50ICE9IE5VTEwpIFJlY29yZFRvKGNvbnRlbnQpOworICAgIH0gZWxzZSBpZiAoVHJ5Q29uc3VtZSgnKicpICYmIFRyeUNvbnN1bWUoJy8nKSkgeworICAgICAgLy8gRW5kIG9mIGNvbW1lbnQuCisgICAgICBpZiAoY29udGVudCAhPSBOVUxMKSB7CisgICAgICAgIFN0b3BSZWNvcmRpbmcoKTsKKyAgICAgICAgLy8gU3RyaXAgdHJhaWxpbmcgIiovIi4KKyAgICAgICAgY29udGVudC0+ZXJhc2UoY29udGVudC0+c2l6ZSgpIC0gMik7CisgICAgICB9CisgICAgICBicmVhazsKKyAgICB9IGVsc2UgaWYgKFRyeUNvbnN1bWUoJy8nKSAmJiBjdXJyZW50X2NoYXJfID09ICcqJykgeworICAgICAgLy8gTm90ZTogIFdlIGRpZG4ndCBjb25zdW1lIHRoZSAnKicgYmVjYXVzZSBpZiB0aGVyZSBpcyBhICcvJyBhZnRlciBpdAorICAgICAgLy8gICB3ZSB3YW50IHRvIGludGVycHJldCB0aGF0IGFzIHRoZSBlbmQgb2YgdGhlIGNvbW1lbnQuCisgICAgICBBZGRFcnJvcigKKyAgICAgICAgIlwiLypcIiBpbnNpZGUgYmxvY2sgY29tbWVudC4gIEJsb2NrIGNvbW1lbnRzIGNhbm5vdCBiZSBuZXN0ZWQuIik7CisgICAgfSBlbHNlIGlmIChjdXJyZW50X2NoYXJfID09ICdcMCcpIHsKKyAgICAgIEFkZEVycm9yKCJFbmQtb2YtZmlsZSBpbnNpZGUgYmxvY2sgY29tbWVudC4iKTsKKyAgICAgIGVycm9yX2NvbGxlY3Rvcl8tPkFkZEVycm9yKAorICAgICAgICBzdGFydF9saW5lLCBzdGFydF9jb2x1bW4sICIgIENvbW1lbnQgc3RhcnRlZCBoZXJlLiIpOworICAgICAgaWYgKGNvbnRlbnQgIT0gTlVMTCkgU3RvcFJlY29yZGluZygpOworICAgICAgYnJlYWs7CisgICAgfQorICB9Cit9CisKK1Rva2VuaXplcjo6TmV4dENvbW1lbnRTdGF0dXMgVG9rZW5pemVyOjpUcnlDb25zdW1lQ29tbWVudFN0YXJ0KCkgeworICBpZiAoY29tbWVudF9zdHlsZV8gPT0gQ1BQX0NPTU1FTlRfU1RZTEUgJiYgVHJ5Q29uc3VtZSgnLycpKSB7CisgICAgaWYgKFRyeUNvbnN1bWUoJy8nKSkgeworICAgICAgcmV0dXJuIExJTkVfQ09NTUVOVDsKKyAgICB9IGVsc2UgaWYgKFRyeUNvbnN1bWUoJyonKSkgeworICAgICAgcmV0dXJuIEJMT0NLX0NPTU1FTlQ7CisgICAgfSBlbHNlIHsKKyAgICAgIC8vIE9vcHMsIGl0IHdhcyBqdXN0IGEgc2xhc2guICBSZXR1cm4gaXQuCisgICAgICBjdXJyZW50Xy50eXBlID0gVFlQRV9TWU1CT0w7CisgICAgICBjdXJyZW50Xy50ZXh0ID0gIi8iOworICAgICAgY3VycmVudF8ubGluZSA9IGxpbmVfOworICAgICAgY3VycmVudF8uY29sdW1uID0gY29sdW1uXyAtIDE7CisgICAgICBjdXJyZW50Xy5lbmRfY29sdW1uID0gY29sdW1uXzsKKyAgICAgIHJldHVybiBTTEFTSF9OT1RfQ09NTUVOVDsKKyAgICB9CisgIH0gZWxzZSBpZiAoY29tbWVudF9zdHlsZV8gPT0gU0hfQ09NTUVOVF9TVFlMRSAmJiBUcnlDb25zdW1lKCcjJykpIHsKKyAgICByZXR1cm4gTElORV9DT01NRU5UOworICB9IGVsc2UgeworICAgIHJldHVybiBOT19DT01NRU5UOworICB9Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworYm9vbCBUb2tlbml6ZXI6Ok5leHQoKSB7CisgIHByZXZpb3VzXyA9IGN1cnJlbnRfOworCisgIHdoaWxlICghcmVhZF9lcnJvcl8pIHsKKyAgICBDb25zdW1lWmVyb09yTW9yZTxXaGl0ZXNwYWNlPigpOworCisgICAgc3dpdGNoIChUcnlDb25zdW1lQ29tbWVudFN0YXJ0KCkpIHsKKyAgICAgIGNhc2UgTElORV9DT01NRU5UOgorICAgICAgICBDb25zdW1lTGluZUNvbW1lbnQoTlVMTCk7CisgICAgICAgIGNvbnRpbnVlOworICAgICAgY2FzZSBCTE9DS19DT01NRU5UOgorICAgICAgICBDb25zdW1lQmxvY2tDb21tZW50KE5VTEwpOworICAgICAgICBjb250aW51ZTsKKyAgICAgIGNhc2UgU0xBU0hfTk9UX0NPTU1FTlQ6CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgY2FzZSBOT19DT01NRU5UOgorICAgICAgICBicmVhazsKKyAgICB9CisKKyAgICAvLyBDaGVjayBmb3IgRU9GIGJlZm9yZSBjb250aW51aW5nLgorICAgIGlmIChyZWFkX2Vycm9yXykgYnJlYWs7CisKKyAgICBpZiAoTG9va2luZ0F0PFVucHJpbnRhYmxlPigpIHx8IGN1cnJlbnRfY2hhcl8gPT0gJ1wwJykgeworICAgICAgQWRkRXJyb3IoIkludmFsaWQgY29udHJvbCBjaGFyYWN0ZXJzIGVuY291bnRlcmVkIGluIHRleHQuIik7CisgICAgICBOZXh0Q2hhcigpOworICAgICAgLy8gU2tpcCBtb3JlIHVucHJpbnRhYmxlIGNoYXJhY3RlcnMsIHRvby4gIEJ1dCwgcmVtZW1iZXIgdGhhdCAnXDAnIGlzCisgICAgICAvLyBhbHNvIHdoYXQgY3VycmVudF9jaGFyXyBpcyBzZXQgdG8gYWZ0ZXIgRU9GIC8gcmVhZCBlcnJvci4gIFdlIGhhdmUKKyAgICAgIC8vIHRvIGJlIGNhcmVmdWwgbm90IHRvIGdvIGludG8gYW4gaW5maW5pdGUgbG9vcCBvZiB0cnlpbmcgdG8gY29uc3VtZQorICAgICAgLy8gaXQsIHNvIG1ha2Ugc3VyZSB0byBjaGVjayByZWFkX2Vycm9yXyBleHBsaWNpdGx5IGJlZm9yZSBjb25zdW1pbmcKKyAgICAgIC8vICdcMCcuCisgICAgICB3aGlsZSAoVHJ5Q29uc3VtZU9uZTxVbnByaW50YWJsZT4oKSB8fAorICAgICAgICAgICAgICghcmVhZF9lcnJvcl8gJiYgVHJ5Q29uc3VtZSgnXDAnKSkpIHsKKyAgICAgICAgLy8gSWdub3JlLgorICAgICAgfQorCisgICAgfSBlbHNlIHsKKyAgICAgIC8vIFJlYWRpbmcgc29tZSBzb3J0IG9mIHRva2VuLgorICAgICAgU3RhcnRUb2tlbigpOworCisgICAgICBpZiAoVHJ5Q29uc3VtZU9uZTxMZXR0ZXI+KCkpIHsKKyAgICAgICAgQ29uc3VtZVplcm9Pck1vcmU8QWxwaGFudW1lcmljPigpOworICAgICAgICBjdXJyZW50Xy50eXBlID0gVFlQRV9JREVOVElGSUVSOworICAgICAgfSBlbHNlIGlmIChUcnlDb25zdW1lKCcwJykpIHsKKyAgICAgICAgY3VycmVudF8udHlwZSA9IENvbnN1bWVOdW1iZXIodHJ1ZSwgZmFsc2UpOworICAgICAgfSBlbHNlIGlmIChUcnlDb25zdW1lKCcuJykpIHsKKyAgICAgICAgLy8gVGhpcyBjb3VsZCBiZSB0aGUgYmVnaW5uaW5nIG9mIGEgZmxvYXRpbmctcG9pbnQgbnVtYmVyLCBvciBpdCBjb3VsZAorICAgICAgICAvLyBqdXN0IGJlIGEgJy4nIHN5bWJvbC4KKworICAgICAgICBpZiAoVHJ5Q29uc3VtZU9uZTxEaWdpdD4oKSkgeworICAgICAgICAgIC8vIEl0J3MgYSBmbG9hdGluZy1wb2ludCBudW1iZXIuCisgICAgICAgICAgaWYgKHByZXZpb3VzXy50eXBlID09IFRZUEVfSURFTlRJRklFUiAmJgorICAgICAgICAgICAgICBjdXJyZW50Xy5saW5lID09IHByZXZpb3VzXy5saW5lICYmCisgICAgICAgICAgICAgIGN1cnJlbnRfLmNvbHVtbiA9PSBwcmV2aW91c18uZW5kX2NvbHVtbikgeworICAgICAgICAgICAgLy8gV2UgZG9uJ3QgYWNjZXB0IHN5bnRheCBsaWtlICJibGFoLjEyMyIuCisgICAgICAgICAgICBlcnJvcl9jb2xsZWN0b3JfLT5BZGRFcnJvcihsaW5lXywgY29sdW1uXyAtIDIsCisgICAgICAgICAgICAgICJOZWVkIHNwYWNlIGJldHdlZW4gaWRlbnRpZmllciBhbmQgZGVjaW1hbCBwb2ludC4iKTsKKyAgICAgICAgICB9CisgICAgICAgICAgY3VycmVudF8udHlwZSA9IENvbnN1bWVOdW1iZXIoZmFsc2UsIHRydWUpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGN1cnJlbnRfLnR5cGUgPSBUWVBFX1NZTUJPTDsKKyAgICAgICAgfQorICAgICAgfSBlbHNlIGlmIChUcnlDb25zdW1lT25lPERpZ2l0PigpKSB7CisgICAgICAgIGN1cnJlbnRfLnR5cGUgPSBDb25zdW1lTnVtYmVyKGZhbHNlLCBmYWxzZSk7CisgICAgICB9IGVsc2UgaWYgKFRyeUNvbnN1bWUoJ1wiJykpIHsKKyAgICAgICAgQ29uc3VtZVN0cmluZygnXCInKTsKKyAgICAgICAgY3VycmVudF8udHlwZSA9IFRZUEVfU1RSSU5HOworICAgICAgfSBlbHNlIGlmIChUcnlDb25zdW1lKCdcJycpKSB7CisgICAgICAgIENvbnN1bWVTdHJpbmcoJ1wnJyk7CisgICAgICAgIGN1cnJlbnRfLnR5cGUgPSBUWVBFX1NUUklORzsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIC8vIENoZWNrIGlmIHRoZSBoaWdoIG9yZGVyIGJpdCBpcyBzZXQuCisgICAgICAgIGlmIChjdXJyZW50X2NoYXJfICYgMHg4MCkgeworICAgICAgICAgIGVycm9yX2NvbGxlY3Rvcl8tPkFkZEVycm9yKGxpbmVfLCBjb2x1bW5fLAorICAgICAgICAgICAgICBTdHJpbmdQcmludGYoIkludGVycHJldGluZyBub24gYXNjaWkgY29kZXBvaW50ICVkLiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0aWNfY2FzdDx1bnNpZ25lZCBjaGFyPihjdXJyZW50X2NoYXJfKSkpOworICAgICAgICB9CisgICAgICAgIE5leHRDaGFyKCk7CisgICAgICAgIGN1cnJlbnRfLnR5cGUgPSBUWVBFX1NZTUJPTDsKKyAgICAgIH0KKworICAgICAgRW5kVG9rZW4oKTsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgfQorCisgIC8vIEVPRgorICBjdXJyZW50Xy50eXBlID0gVFlQRV9FTkQ7CisgIGN1cnJlbnRfLnRleHQuY2xlYXIoKTsKKyAgY3VycmVudF8ubGluZSA9IGxpbmVfOworICBjdXJyZW50Xy5jb2x1bW4gPSBjb2x1bW5fOworICBjdXJyZW50Xy5lbmRfY29sdW1uID0gY29sdW1uXzsKKyAgcmV0dXJuIGZhbHNlOworfQorCituYW1lc3BhY2UgeworCisvLyBIZWxwZXIgY2xhc3MgZm9yIGNvbGxlY3RpbmcgY29tbWVudHMgYW5kIHB1dHRpbmcgdGhlbSBpbiB0aGUgcmlnaHQgcGxhY2VzLgorLy8KKy8vIFRoaXMgYmFzaWNhbGx5IGp1c3QgYnVmZmVycyB0aGUgbW9zdCByZWNlbnQgY29tbWVudCB1bnRpbCBpdCBjYW4gYmUgZGVjaWRlZAorLy8gZXhhY3RseSB3aGVyZSB0aGF0IGNvbW1lbnQgc2hvdWxkIGJlIHBsYWNlZC4gIFdoZW4gRmx1c2goKSBpcyBjYWxsZWQsIHRoZQorLy8gY3VycmVudCBjb21tZW50IGdvZXMgaW50byBlaXRoZXIgcHJldl90cmFpbGluZ19jb21tZW50cyBvciBkZXRhY2hlZF9jb21tZW50cy4KKy8vIFdoZW4gdGhlIENvbW1lbnRDb2xsZWN0b3IgaXMgZGVzdHJveWVkLCB0aGUgbGFzdCBidWZmZXJlZCBjb21tZW50IGdvZXMgaW50bworLy8gbmV4dF9sZWFkaW5nX2NvbW1lbnRzLgorY2xhc3MgQ29tbWVudENvbGxlY3RvciB7CisgcHVibGljOgorICBDb21tZW50Q29sbGVjdG9yKHN0cmluZyogcHJldl90cmFpbGluZ19jb21tZW50cywKKyAgICAgICAgICAgICAgICAgICB2ZWN0b3I8c3RyaW5nPiogZGV0YWNoZWRfY29tbWVudHMsCisgICAgICAgICAgICAgICAgICAgc3RyaW5nKiBuZXh0X2xlYWRpbmdfY29tbWVudHMpCisgICAgICA6IHByZXZfdHJhaWxpbmdfY29tbWVudHNfKHByZXZfdHJhaWxpbmdfY29tbWVudHMpLAorICAgICAgICBkZXRhY2hlZF9jb21tZW50c18oZGV0YWNoZWRfY29tbWVudHMpLAorICAgICAgICBuZXh0X2xlYWRpbmdfY29tbWVudHNfKG5leHRfbGVhZGluZ19jb21tZW50cyksCisgICAgICAgIGhhc19jb21tZW50XyhmYWxzZSksCisgICAgICAgIGlzX2xpbmVfY29tbWVudF8oZmFsc2UpLAorICAgICAgICBjYW5fYXR0YWNoX3RvX3ByZXZfKHRydWUpIHsKKyAgICBpZiAocHJldl90cmFpbGluZ19jb21tZW50cyAhPSBOVUxMKSBwcmV2X3RyYWlsaW5nX2NvbW1lbnRzLT5jbGVhcigpOworICAgIGlmIChkZXRhY2hlZF9jb21tZW50cyAhPSBOVUxMKSBkZXRhY2hlZF9jb21tZW50cy0+Y2xlYXIoKTsKKyAgICBpZiAobmV4dF9sZWFkaW5nX2NvbW1lbnRzICE9IE5VTEwpIG5leHRfbGVhZGluZ19jb21tZW50cy0+Y2xlYXIoKTsKKyAgfQorCisgIH5Db21tZW50Q29sbGVjdG9yKCkgeworICAgIC8vIFdoYXRldmVyIGlzIGluIHRoZSBidWZmZXIgaXMgYSBsZWFkaW5nIGNvbW1lbnQuCisgICAgaWYgKG5leHRfbGVhZGluZ19jb21tZW50c18gIT0gTlVMTCAmJiBoYXNfY29tbWVudF8pIHsKKyAgICAgIGNvbW1lbnRfYnVmZmVyXy5zd2FwKCpuZXh0X2xlYWRpbmdfY29tbWVudHNfKTsKKyAgICB9CisgIH0KKworICAvLyBBYm91dCB0byByZWFkIGEgbGluZSBjb21tZW50LiAgR2V0IHRoZSBjb21tZW50IGJ1ZmZlciBwb2ludGVyIGluIG9yZGVyIHRvCisgIC8vIHJlYWQgaW50byBpdC4KKyAgc3RyaW5nKiBHZXRCdWZmZXJGb3JMaW5lQ29tbWVudCgpIHsKKyAgICAvLyBXZSB3YW50IHRvIGNvbWJpbmUgd2l0aCBwcmV2aW91cyBsaW5lIGNvbW1lbnRzLCBidXQgbm90IGJsb2NrIGNvbW1lbnRzLgorICAgIGlmIChoYXNfY29tbWVudF8gJiYgIWlzX2xpbmVfY29tbWVudF8pIHsKKyAgICAgIEZsdXNoKCk7CisgICAgfQorICAgIGhhc19jb21tZW50XyA9IHRydWU7CisgICAgaXNfbGluZV9jb21tZW50XyA9IHRydWU7CisgICAgcmV0dXJuICZjb21tZW50X2J1ZmZlcl87CisgIH0KKworICAvLyBBYm91dCB0byByZWFkIGEgYmxvY2sgY29tbWVudC4gIEdldCB0aGUgY29tbWVudCBidWZmZXIgcG9pbnRlciBpbiBvcmRlciB0bworICAvLyByZWFkIGludG8gaXQuCisgIHN0cmluZyogR2V0QnVmZmVyRm9yQmxvY2tDb21tZW50KCkgeworICAgIGlmIChoYXNfY29tbWVudF8pIHsKKyAgICAgIEZsdXNoKCk7CisgICAgfQorICAgIGhhc19jb21tZW50XyA9IHRydWU7CisgICAgaXNfbGluZV9jb21tZW50XyA9IGZhbHNlOworICAgIHJldHVybiAmY29tbWVudF9idWZmZXJfOworICB9CisKKyAgdm9pZCBDbGVhckJ1ZmZlcigpIHsKKyAgICBjb21tZW50X2J1ZmZlcl8uY2xlYXIoKTsKKyAgICBoYXNfY29tbWVudF8gPSBmYWxzZTsKKyAgfQorCisgIC8vIENhbGxlZCBvbmNlIHdlIGtub3cgdGhhdCB0aGUgY29tbWVudCBidWZmZXIgaXMgY29tcGxldGUgYW5kIGlzICpub3QqCisgIC8vIGNvbm5lY3RlZCB0byB0aGUgbmV4dCB0b2tlbi4KKyAgdm9pZCBGbHVzaCgpIHsKKyAgICBpZiAoaGFzX2NvbW1lbnRfKSB7CisgICAgICBpZiAoY2FuX2F0dGFjaF90b19wcmV2XykgeworICAgICAgICBpZiAocHJldl90cmFpbGluZ19jb21tZW50c18gIT0gTlVMTCkgeworICAgICAgICAgIHByZXZfdHJhaWxpbmdfY29tbWVudHNfLT5hcHBlbmQoY29tbWVudF9idWZmZXJfKTsKKyAgICAgICAgfQorICAgICAgICBjYW5fYXR0YWNoX3RvX3ByZXZfID0gZmFsc2U7CisgICAgICB9IGVsc2UgeworICAgICAgICBpZiAoZGV0YWNoZWRfY29tbWVudHNfICE9IE5VTEwpIHsKKyAgICAgICAgICBkZXRhY2hlZF9jb21tZW50c18tPnB1c2hfYmFjayhjb21tZW50X2J1ZmZlcl8pOworICAgICAgICB9CisgICAgICB9CisgICAgICBDbGVhckJ1ZmZlcigpOworICAgIH0KKyAgfQorCisgIHZvaWQgRGV0YWNoRnJvbVByZXYoKSB7CisgICAgY2FuX2F0dGFjaF90b19wcmV2XyA9IGZhbHNlOworICB9CisKKyBwcml2YXRlOgorICBzdHJpbmcqIHByZXZfdHJhaWxpbmdfY29tbWVudHNfOworICB2ZWN0b3I8c3RyaW5nPiogZGV0YWNoZWRfY29tbWVudHNfOworICBzdHJpbmcqIG5leHRfbGVhZGluZ19jb21tZW50c187CisKKyAgc3RyaW5nIGNvbW1lbnRfYnVmZmVyXzsKKworICAvLyBUcnVlIGlmIGFueSBjb21tZW50cyB3ZXJlIHJlYWQgaW50byBjb21tZW50X2J1ZmZlcl8uICBUaGlzIGNhbiBiZSB0cnVlIGV2ZW4KKyAgLy8gaWYgY29tbWVudF9idWZmZXJfIGlzIGVtcHR5LCBuYW1lbHkgaWYgdGhlIGNvbW1lbnQgd2FzICIvKiovIi4KKyAgYm9vbCBoYXNfY29tbWVudF87CisKKyAgLy8gSXMgdGhlIGNvbW1lbnQgaW4gdGhlIGNvbW1lbnQgYnVmZmVyIGEgbGluZSBjb21tZW50PworICBib29sIGlzX2xpbmVfY29tbWVudF87CisKKyAgLy8gSXMgaXQgc3RpbGwgcG9zc2libGUgdGhhdCB3ZSBjb3VsZCBiZSByZWFkaW5nIGEgY29tbWVudCBhdHRhY2hlZCB0byB0aGUKKyAgLy8gcHJldmlvdXMgdG9rZW4/CisgIGJvb2wgY2FuX2F0dGFjaF90b19wcmV2XzsKK307CisKK30gLy8gbmFtZXNwYWNlCisKK2Jvb2wgVG9rZW5pemVyOjpOZXh0V2l0aENvbW1lbnRzKHN0cmluZyogcHJldl90cmFpbGluZ19jb21tZW50cywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlY3RvcjxzdHJpbmc+KiBkZXRhY2hlZF9jb21tZW50cywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyogbmV4dF9sZWFkaW5nX2NvbW1lbnRzKSB7CisgIENvbW1lbnRDb2xsZWN0b3IgY29sbGVjdG9yKHByZXZfdHJhaWxpbmdfY29tbWVudHMsIGRldGFjaGVkX2NvbW1lbnRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0X2xlYWRpbmdfY29tbWVudHMpOworCisgIGlmIChjdXJyZW50Xy50eXBlID09IFRZUEVfU1RBUlQpIHsKKyAgICAvLyBJZ25vcmUgdW5pY29kZSBieXRlIG9yZGVyIG1hcmsoQk9NKSBpZiBpdCBhcHBlYXJzIGF0IHRoZSBmaWxlCisgICAgLy8gYmVnaW5uaW5nLiBPbmx5IFVURi04IEJPTSAoMHhFRiAweEJCIDB4QkYpIGlzIGFjY2VwdGVkLgorICAgIGlmIChUcnlDb25zdW1lKChjaGFyKTB4RUYpKSB7CisgICAgICBpZiAoIVRyeUNvbnN1bWUoKGNoYXIpMHhCQikgfHwgIVRyeUNvbnN1bWUoKGNoYXIpMHhCRikpIHsKKyAgICAgICAgQWRkRXJyb3IoIlByb3RvIGZpbGUgc3RhcnRzIHdpdGggMHhFRiBidXQgbm90IFVURi04IEJPTS4gIgorICAgICAgICAgICAgICAgICAiT25seSBVVEYtOCBpcyBhY2NlcHRlZCBmb3IgcHJvdG8gZmlsZS4iKTsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgIH0KKyAgICBjb2xsZWN0b3IuRGV0YWNoRnJvbVByZXYoKTsKKyAgfSBlbHNlIHsKKyAgICAvLyBBIGNvbW1lbnQgYXBwZWFyaW5nIG9uIHRoZSBzYW1lIGxpbmUgbXVzdCBiZSBhdHRhY2hlZCB0byB0aGUgcHJldmlvdXMKKyAgICAvLyBkZWNsYXJhdGlvbi4KKyAgICBDb25zdW1lWmVyb09yTW9yZTxXaGl0ZXNwYWNlTm9OZXdsaW5lPigpOworICAgIHN3aXRjaCAoVHJ5Q29uc3VtZUNvbW1lbnRTdGFydCgpKSB7CisgICAgICBjYXNlIExJTkVfQ09NTUVOVDoKKyAgICAgICAgQ29uc3VtZUxpbmVDb21tZW50KGNvbGxlY3Rvci5HZXRCdWZmZXJGb3JMaW5lQ29tbWVudCgpKTsKKworICAgICAgICAvLyBEb24ndCBhbGxvdyBjb21tZW50cyBvbiBzdWJzZXF1ZW50IGxpbmVzIHRvIGJlIGF0dGFjaGVkIHRvIGEgdHJhaWxpbmcKKyAgICAgICAgLy8gY29tbWVudC4KKyAgICAgICAgY29sbGVjdG9yLkZsdXNoKCk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBCTE9DS19DT01NRU5UOgorICAgICAgICBDb25zdW1lQmxvY2tDb21tZW50KGNvbGxlY3Rvci5HZXRCdWZmZXJGb3JCbG9ja0NvbW1lbnQoKSk7CisKKyAgICAgICAgQ29uc3VtZVplcm9Pck1vcmU8V2hpdGVzcGFjZU5vTmV3bGluZT4oKTsKKyAgICAgICAgaWYgKCFUcnlDb25zdW1lKCdcbicpKSB7CisgICAgICAgICAgLy8gT29wcywgdGhlIG5leHQgdG9rZW4gaXMgb24gdGhlIHNhbWUgbGluZS4gIElmIHdlIHJlY29yZGVkIGEgY29tbWVudAorICAgICAgICAgIC8vIHdlIHJlYWxseSBoYXZlIG5vIGlkZWEgd2hpY2ggdG9rZW4gaXQgc2hvdWxkIGJlIGF0dGFjaGVkIHRvLgorICAgICAgICAgIGNvbGxlY3Rvci5DbGVhckJ1ZmZlcigpOworICAgICAgICAgIHJldHVybiBOZXh0KCk7CisgICAgICAgIH0KKworICAgICAgICAvLyBEb24ndCBhbGxvdyBjb21tZW50cyBvbiBzdWJzZXF1ZW50IGxpbmVzIHRvIGJlIGF0dGFjaGVkIHRvIGEgdHJhaWxpbmcKKyAgICAgICAgLy8gY29tbWVudC4KKyAgICAgICAgY29sbGVjdG9yLkZsdXNoKCk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBTTEFTSF9OT1RfQ09NTUVOVDoKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICBjYXNlIE5PX0NPTU1FTlQ6CisgICAgICAgIGlmICghVHJ5Q29uc3VtZSgnXG4nKSkgeworICAgICAgICAgIC8vIFRoZSBuZXh0IHRva2VuIGlzIG9uIHRoZSBzYW1lIGxpbmUuICBUaGVyZSBhcmUgbm8gY29tbWVudHMuCisgICAgICAgICAgcmV0dXJuIE5leHQoKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICB9CisgIH0KKworICAvLyBPSywgd2UgYXJlIG5vdyBvbiB0aGUgbGluZSAqYWZ0ZXIqIHRoZSBwcmV2aW91cyB0b2tlbi4KKyAgd2hpbGUgKHRydWUpIHsKKyAgICBDb25zdW1lWmVyb09yTW9yZTxXaGl0ZXNwYWNlTm9OZXdsaW5lPigpOworCisgICAgc3dpdGNoIChUcnlDb25zdW1lQ29tbWVudFN0YXJ0KCkpIHsKKyAgICAgIGNhc2UgTElORV9DT01NRU5UOgorICAgICAgICBDb25zdW1lTGluZUNvbW1lbnQoY29sbGVjdG9yLkdldEJ1ZmZlckZvckxpbmVDb21tZW50KCkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgQkxPQ0tfQ09NTUVOVDoKKyAgICAgICAgQ29uc3VtZUJsb2NrQ29tbWVudChjb2xsZWN0b3IuR2V0QnVmZmVyRm9yQmxvY2tDb21tZW50KCkpOworCisgICAgICAgIC8vIENvbnN1bWUgdGhlIHJlc3Qgb2YgdGhlIGxpbmUgc28gdGhhdCB3ZSBkb24ndCBpbnRlcnByZXQgaXQgYXMgYQorICAgICAgICAvLyBibGFuayBsaW5lIHRoZSBuZXh0IHRpbWUgYXJvdW5kIHRoZSBsb29wLgorICAgICAgICBDb25zdW1lWmVyb09yTW9yZTxXaGl0ZXNwYWNlTm9OZXdsaW5lPigpOworICAgICAgICBUcnlDb25zdW1lKCdcbicpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgU0xBU0hfTk9UX0NPTU1FTlQ6CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgY2FzZSBOT19DT01NRU5UOgorICAgICAgICBpZiAoVHJ5Q29uc3VtZSgnXG4nKSkgeworICAgICAgICAgIC8vIENvbXBsZXRlbHkgYmxhbmsgbGluZS4KKyAgICAgICAgICBjb2xsZWN0b3IuRmx1c2goKTsKKyAgICAgICAgICBjb2xsZWN0b3IuRGV0YWNoRnJvbVByZXYoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBib29sIHJlc3VsdCA9IE5leHQoKTsKKyAgICAgICAgICBpZiAoIXJlc3VsdCB8fAorICAgICAgICAgICAgICBjdXJyZW50Xy50ZXh0ID09ICJ9IiB8fAorICAgICAgICAgICAgICBjdXJyZW50Xy50ZXh0ID09ICJdIiB8fAorICAgICAgICAgICAgICBjdXJyZW50Xy50ZXh0ID09ICIpIikgeworICAgICAgICAgICAgLy8gSXQgbG9va3MgbGlrZSB3ZSdyZSBhdCB0aGUgZW5kIG9mIGEgc2NvcGUuICBJbiB0aGlzIGNhc2UgaXQKKyAgICAgICAgICAgIC8vIG1ha2VzIG5vIHNlbnNlIHRvIGF0dGFjaCBhIGNvbW1lbnQgdG8gdGhlIGZvbGxvd2luZyB0b2tlbi4KKyAgICAgICAgICAgIGNvbGxlY3Rvci5GbHVzaCgpOworICAgICAgICAgIH0KKyAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgIH0KKyAgfQorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBUb2tlbi1wYXJzaW5nIGhlbHBlcnMuICBSZW1lbWJlciB0aGF0IHRoZXNlIGRvbid0IG5lZWQgdG8gcmVwb3J0CisvLyBlcnJvcnMgc2luY2UgYW55IGVycm9ycyBzaG91bGQgYWxyZWFkeSBoYXZlIGJlZW4gcmVwb3J0ZWQgd2hpbGUKKy8vIHRva2VuaXppbmcuICBBbHNvLCB0aGVzZSBjYW4gYXNzdW1lIHRoYXQgd2hhdGV2ZXIgdGV4dCB0aGV5CisvLyBhcmUgZ2l2ZW4gaXMgdGV4dCB0aGF0IHRoZSB0b2tlbml6ZXIgYWN0dWFsbHkgcGFyc2VkIGFzIGEgdG9rZW4KKy8vIG9mIHRoZSBnaXZlbiB0eXBlLgorCitib29sIFRva2VuaXplcjo6UGFyc2VJbnRlZ2VyKGNvbnN0IHN0cmluZyYgdGV4dCwgdWludDY0IG1heF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDY0KiBvdXRwdXQpIHsKKyAgLy8gU2FkbHksIHdlIGNhbid0IGp1c3QgdXNlIHN0cnRvdWwoKSBzaW5jZSBpdCBpcyBvbmx5IDMyLWJpdCBhbmQgc3RydG91bGwoKQorICAvLyBpcyBub24tc3RhbmRhcmQuICBJIGhhdGUgdGhlIEMgc3RhbmRhcmQgbGlicmFyeS4gIDooCisKKy8vICByZXR1cm4gc3RydG91bGwodGV4dC5jX3N0cigpLCBOVUxMLCAwKTsKKworICBjb25zdCBjaGFyKiBwdHIgPSB0ZXh0LmNfc3RyKCk7CisgIGludCBiYXNlID0gMTA7CisgIGlmIChwdHJbMF0gPT0gJzAnKSB7CisgICAgaWYgKHB0clsxXSA9PSAneCcgfHwgcHRyWzFdID09ICdYJykgeworICAgICAgLy8gVGhpcyBpcyBoZXguCisgICAgICBiYXNlID0gMTY7CisgICAgICBwdHIgKz0gMjsKKyAgICB9IGVsc2UgeworICAgICAgLy8gVGhpcyBpcyBvY3RhbC4KKyAgICAgIGJhc2UgPSA4OworICAgIH0KKyAgfQorCisgIHVpbnQ2NCByZXN1bHQgPSAwOworICBmb3IgKDsgKnB0ciAhPSAnXDAnOyBwdHIrKykgeworICAgIGludCBkaWdpdCA9IERpZ2l0VmFsdWUoKnB0cik7CisgICAgR09PR0xFX0xPR19JRihERkFUQUwsIGRpZ2l0IDwgMCB8fCBkaWdpdCA+PSBiYXNlKQorICAgICAgPDwgIiBUb2tlbml6ZXI6OlBhcnNlSW50ZWdlcigpIHBhc3NlZCB0ZXh0IHRoYXQgY291bGQgbm90IGhhdmUgYmVlbiIKKyAgICAgICAgICIgdG9rZW5pemVkIGFzIGFuIGludGVnZXI6ICIgPDwgQ0VzY2FwZSh0ZXh0KTsKKyAgICBpZiAoZGlnaXQgPiBtYXhfdmFsdWUgfHwgcmVzdWx0ID4gKG1heF92YWx1ZSAtIGRpZ2l0KSAvIGJhc2UpIHsKKyAgICAgIC8vIE92ZXJmbG93LgorICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICByZXN1bHQgPSByZXN1bHQgKiBiYXNlICsgZGlnaXQ7CisgIH0KKworICAqb3V0cHV0ID0gcmVzdWx0OworICByZXR1cm4gdHJ1ZTsKK30KKworZG91YmxlIFRva2VuaXplcjo6UGFyc2VGbG9hdChjb25zdCBzdHJpbmcmIHRleHQpIHsKKyAgY29uc3QgY2hhciogc3RhcnQgPSB0ZXh0LmNfc3RyKCk7CisgIGNoYXIqIGVuZDsKKyAgZG91YmxlIHJlc3VsdCA9IE5vTG9jYWxlU3RydG9kKHN0YXJ0LCAmZW5kKTsKKworICAvLyAiMWUiIGlzIG5vdCBhIHZhbGlkIGZsb2F0LCBidXQgaWYgdGhlIHRva2VuaXplciByZWFkcyBpdCwgaXQgd2lsbAorICAvLyByZXBvcnQgYW4gZXJyb3IgYnV0IHN0aWxsIHJldHVybiBpdCBhcyBhIHZhbGlkIHRva2VuLiAgV2UgbmVlZCB0bworICAvLyBhY2NlcHQgYW55dGhpbmcgdGhlIHRva2VuaXplciBjb3VsZCBwb3NzaWJseSByZXR1cm4sIGVycm9yIG9yIG5vdC4KKyAgaWYgKCplbmQgPT0gJ2UnIHx8ICplbmQgPT0gJ0UnKSB7CisgICAgKytlbmQ7CisgICAgaWYgKCplbmQgPT0gJy0nIHx8ICplbmQgPT0gJysnKSArK2VuZDsKKyAgfQorCisgIC8vIElmIHRoZSBUb2tlbml6ZXIgaGFkIGFsbG93X2ZfYWZ0ZXJfZmxvYXRfIGVuYWJsZWQsIHRoZSBmbG9hdCBtYXkgYmUKKyAgLy8gc3VmZml4ZWQgd2l0aCB0aGUgbGV0dGVyICdmJy4KKyAgaWYgKCplbmQgPT0gJ2YnIHx8ICplbmQgPT0gJ0YnKSB7CisgICAgKytlbmQ7CisgIH0KKworICBHT09HTEVfTE9HX0lGKERGQVRBTCwgZW5kIC0gc3RhcnQgIT0gdGV4dC5zaXplKCkgfHwgKnN0YXJ0ID09ICctJykKKyAgICA8PCAiIFRva2VuaXplcjo6UGFyc2VGbG9hdCgpIHBhc3NlZCB0ZXh0IHRoYXQgY291bGQgbm90IGhhdmUgYmVlbiIKKyAgICAgICAiIHRva2VuaXplZCBhcyBhIGZsb2F0OiAiIDw8IENFc2NhcGUodGV4dCk7CisgIHJldHVybiByZXN1bHQ7Cit9CisKKy8vIEhlbHBlciB0byBhcHBlbmQgYSBVbmljb2RlIGNvZGUgcG9pbnQgdG8gYSBzdHJpbmcgYXMgVVRGOCwgd2l0aG91dCBicmluZ2luZworLy8gaW4gYW55IGV4dGVybmFsIGRlcGVuZGVuY2llcy4KK3N0YXRpYyB2b2lkIEFwcGVuZFVURjgodWludDMyIGNvZGVfcG9pbnQsIHN0cmluZyogb3V0cHV0KSB7CisgIHVpbnQzMiB0bXAgPSAwOworICBpbnQgbGVuID0gMDsKKyAgaWYgKGNvZGVfcG9pbnQgPD0gMHg3ZikgeworICAgIHRtcCA9IGNvZGVfcG9pbnQ7CisgICAgbGVuID0gMTsKKyAgfSBlbHNlIGlmIChjb2RlX3BvaW50IDw9IDB4MDdmZikgeworICAgIHRtcCA9IDB4MDAwMGMwODAgfAorICAgICAgICAoKGNvZGVfcG9pbnQgJiAweDA3YzApIDw8IDIpIHwKKyAgICAgICAgKGNvZGVfcG9pbnQgJiAweDAwM2YpOworICAgIGxlbiA9IDI7CisgIH0gZWxzZSBpZiAoY29kZV9wb2ludCA8PSAweGZmZmYpIHsKKyAgICB0bXAgPSAweDAwZTA4MDgwIHwKKyAgICAgICAgKChjb2RlX3BvaW50ICYgMHhmMDAwKSA8PCA0KSB8CisgICAgICAgICgoY29kZV9wb2ludCAmIDB4MGZjMCkgPDwgMikgfAorICAgICAgICAoY29kZV9wb2ludCAmIDB4MDAzZik7CisgICAgbGVuID0gMzsKKyAgfSBlbHNlIGlmIChjb2RlX3BvaW50IDw9IDB4MWZmZmZmKSB7CisgICAgdG1wID0gMHhmMDgwODA4MCB8CisgICAgICAgICgoY29kZV9wb2ludCAmIDB4MWMwMDAwKSA8PCA2KSB8CisgICAgICAgICgoY29kZV9wb2ludCAmIDB4MDNmMDAwKSA8PCA0KSB8CisgICAgICAgICgoY29kZV9wb2ludCAmIDB4MDAwZmMwKSA8PCAyKSB8CisgICAgICAgIChjb2RlX3BvaW50ICYgMHgwMDNmKTsKKyAgICBsZW4gPSA0OworICB9IGVsc2UgeworICAgIC8vIFVURi0xNiBpcyBvbmx5IGRlZmluZWQgZm9yIGNvZGUgcG9pbnRzIHVwIHRvIDB4MTBGRkZGLCBhbmQgVVRGLTggaXMKKyAgICAvLyBub3JtYWxseSBvbmx5IGRlZmluZWQgdXAgdG8gdGhlcmUgYXMgd2VsbC4KKyAgICBTdHJpbmdBcHBlbmRGKG91dHB1dCwgIlxcVSUwOHgiLCBjb2RlX3BvaW50KTsKKyAgICByZXR1cm47CisgIH0KKyAgdG1wID0gZ2h0b25sKHRtcCk7CisgIG91dHB1dC0+YXBwZW5kKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KCZ0bXApICsgc2l6ZW9mKHRtcCkgLSBsZW4sIGxlbik7Cit9CisKKy8vIFRyeSB0byByZWFkIDxsZW4+IGhleCBkaWdpdHMgZnJvbSBwdHIsIGFuZCBzdHVmZiB0aGUgbnVtZXJpYyByZXN1bHQgaW50bworLy8gKnJlc3VsdC4gUmV0dXJucyB0cnVlIGlmIHRoYXQgbWFueSBkaWdpdHMgd2VyZSBzdWNjZXNzZnVsbHkgY29uc3VtZWQuCitzdGF0aWMgYm9vbCBSZWFkSGV4RGlnaXRzKGNvbnN0IGNoYXIqIHB0ciwgaW50IGxlbiwgdWludDMyKiByZXN1bHQpIHsKKyAgKnJlc3VsdCA9IDA7CisgIGlmIChsZW4gPT0gMCkgcmV0dXJuIGZhbHNlOworICBmb3IgKGNvbnN0IGNoYXIqIGVuZCA9IHB0ciArIGxlbjsgcHRyIDwgZW5kOyArK3B0cikgeworICAgIGlmICgqcHRyID09ICdcMCcpIHJldHVybiBmYWxzZTsKKyAgICAqcmVzdWx0ID0gKCpyZXN1bHQgPDwgNCkgKyBEaWdpdFZhbHVlKCpwdHIpOworICB9CisgIHJldHVybiB0cnVlOworfQorCisvLyBIYW5kbGluZyBVVEYtMTYgc3Vycm9nYXRlIHBhaXJzLiBVVEYtMTYgZW5jb2RlcyBjb2RlIHBvaW50cyBpbiB0aGUgcmFuZ2UKKy8vIDB4MTAwMDAuLi4weDEwZmZmZiBhcyBhIHBhaXIgb2YgbnVtYmVycywgYSBoZWFkIHN1cnJvZ2F0ZSBmb2xsb3dlZCBieSBhIHRyYWlsCisvLyBzdXJyb2dhdGUuIFRoZXNlIG51bWJlcnMgYXJlIGluIGEgcmVzZXJ2ZWQgcmFuZ2Ugb2YgVW5pY29kZSBjb2RlIHBvaW50cywgc28KKy8vIGlmIHdlIGVuY291bnRlciBzdWNoIGEgcGFpciB3ZSBrbm93IGhvdyB0byBwYXJzZSBpdCBhbmQgY29udmVydCBpdCBpbnRvIGEKKy8vIHNpbmdsZSBjb2RlIHBvaW50Lgorc3RhdGljIGNvbnN0IHVpbnQzMiBrTWluSGVhZFN1cnJvZ2F0ZSA9IDB4ZDgwMDsKK3N0YXRpYyBjb25zdCB1aW50MzIga01heEhlYWRTdXJyb2dhdGUgPSAweGRjMDA7CitzdGF0aWMgY29uc3QgdWludDMyIGtNaW5UcmFpbFN1cnJvZ2F0ZSA9IDB4ZGMwMDsKK3N0YXRpYyBjb25zdCB1aW50MzIga01heFRyYWlsU3Vycm9nYXRlID0gMHhlMDAwOworCitzdGF0aWMgaW5saW5lIGJvb2wgSXNIZWFkU3Vycm9nYXRlKHVpbnQzMiBjb2RlX3BvaW50KSB7CisgIHJldHVybiAoY29kZV9wb2ludCA+PSBrTWluSGVhZFN1cnJvZ2F0ZSkgJiYgKGNvZGVfcG9pbnQgPCBrTWF4SGVhZFN1cnJvZ2F0ZSk7Cit9CisKK3N0YXRpYyBpbmxpbmUgYm9vbCBJc1RyYWlsU3Vycm9nYXRlKHVpbnQzMiBjb2RlX3BvaW50KSB7CisgIHJldHVybiAoY29kZV9wb2ludCA+PSBrTWluVHJhaWxTdXJyb2dhdGUpICYmCisgICAgICAoY29kZV9wb2ludCA8IGtNYXhUcmFpbFN1cnJvZ2F0ZSk7Cit9CisKKy8vIENvbWJpbmUgYSBoZWFkIGFuZCB0cmFpbCBzdXJyb2dhdGUgaW50byBhIHNpbmdsZSBVbmljb2RlIGNvZGUgcG9pbnQuCitzdGF0aWMgdWludDMyIEFzc2VtYmxlVVRGMTYodWludDMyIGhlYWRfc3Vycm9nYXRlLCB1aW50MzIgdHJhaWxfc3Vycm9nYXRlKSB7CisgIEdPT0dMRV9EQ0hFQ0soSXNIZWFkU3Vycm9nYXRlKGhlYWRfc3Vycm9nYXRlKSk7CisgIEdPT0dMRV9EQ0hFQ0soSXNUcmFpbFN1cnJvZ2F0ZSh0cmFpbF9zdXJyb2dhdGUpKTsKKyAgcmV0dXJuIDB4MTAwMDAgKyAoKChoZWFkX3N1cnJvZ2F0ZSAtIGtNaW5IZWFkU3Vycm9nYXRlKSA8PCAxMCkgfAorICAgICAgKHRyYWlsX3N1cnJvZ2F0ZSAtIGtNaW5UcmFpbFN1cnJvZ2F0ZSkpOworfQorCisvLyBDb252ZXJ0IHRoZSBlc2NhcGUgc2VxdWVuY2UgcGFyYW1ldGVyIHRvIGEgbnVtYmVyIG9mIGV4cGVjdGVkIGhleCBkaWdpdHMuCitzdGF0aWMgaW5saW5lIGludCBVbmljb2RlTGVuZ3RoKGNoYXIga2V5KSB7CisgIGlmIChrZXkgPT0gJ3UnKSByZXR1cm4gNDsKKyAgaWYgKGtleSA9PSAnVScpIHJldHVybiA4OworICByZXR1cm4gMDsKK30KKworLy8gR2l2ZW4gYSBwb2ludGVyIHRvIHRoZSAndScgb3IgJ1UnIHN0YXJ0aW5nIGEgVW5pY29kZSBlc2NhcGUgc2VxdWVuY2UsIGF0dGVtcHQKKy8vIHRvIHBhcnNlIHRoYXQgc2VxdWVuY2UuIE9uIHN1Y2Nlc3MsIHJldHVybnMgYSBwb2ludGVyIHRvIHRoZSBmaXJzdCBjaGFyCisvLyBiZXlvbmQgdGhhdCBzZXF1ZW5jZSwgYW5kIGZpbGxzIGluICpjb2RlX3BvaW50LiBPbiBmYWlsdXJlLCByZXR1cm5zIHB0cgorLy8gaXRzZWxmLgorc3RhdGljIGNvbnN0IGNoYXIqIEZldGNoVW5pY29kZVBvaW50KGNvbnN0IGNoYXIqIHB0ciwgdWludDMyKiBjb2RlX3BvaW50KSB7CisgIGNvbnN0IGNoYXIqIHAgPSBwdHI7CisgIC8vIEZldGNoIHRoZSBjb2RlIHBvaW50LgorICBjb25zdCBpbnQgbGVuID0gVW5pY29kZUxlbmd0aCgqcCsrKTsKKyAgaWYgKCFSZWFkSGV4RGlnaXRzKHAsIGxlbiwgY29kZV9wb2ludCkpCisgICAgcmV0dXJuIHB0cjsKKyAgcCArPSBsZW47CisKKyAgLy8gQ2hlY2sgaWYgdGhlIGNvZGUgcG9pbnQgd2UgcmVhZCBpcyBhICJoZWFkIHN1cnJvZ2F0ZS4iIElmIHNvLCB0aGVuIHdlCisgIC8vIGV4cGVjdCBpdCB0byBiZSBpbW1lZGlhdGVseSBmb2xsb3dlZCBieSBhbm90aGVyIGNvZGUgcG9pbnQgd2hpY2ggaXMgYSB2YWxpZAorICAvLyAidHJhaWwgc3Vycm9nYXRlLCIgYW5kIHRvZ2V0aGVyIHRoZXkgZm9ybSBhIFVURi0xNiBwYWlyIHdoaWNoIGRlY29kZXMgaW50bworICAvLyBhIHNpbmdsZSBVbmljb2RlIHBvaW50LiBUcmFpbCBzdXJyb2dhdGVzIG1heSBvbmx5IHVzZSBcdSwgbm90IFxVLgorICBpZiAoSXNIZWFkU3Vycm9nYXRlKCpjb2RlX3BvaW50KSAmJiAqcCA9PSAnXFwnICYmICoocCArIDEpID09ICd1JykgeworICAgIHVpbnQzMiB0cmFpbF9zdXJyb2dhdGU7CisgICAgaWYgKFJlYWRIZXhEaWdpdHMocCArIDIsIDQsICZ0cmFpbF9zdXJyb2dhdGUpICYmCisgICAgICAgIElzVHJhaWxTdXJyb2dhdGUodHJhaWxfc3Vycm9nYXRlKSkgeworICAgICAgKmNvZGVfcG9pbnQgPSBBc3NlbWJsZVVURjE2KCpjb2RlX3BvaW50LCB0cmFpbF9zdXJyb2dhdGUpOworICAgICAgcCArPSA2OworICAgIH0KKyAgICAvLyBJZiB0aGlzIGZhaWxlZCwgdGhlbiB3ZSBqdXN0IGVtaXQgdGhlIGhlYWQgc3Vycm9nYXRlIGFzIGEgY29kZSBwb2ludC4KKyAgICAvLyBJdCdzIGJvZ3VzLCBidXQgc28gaXMgdGhlIHN0cmluZy4KKyAgfQorCisgIHJldHVybiBwOworfQorCisvLyBUaGUgdGV4dCBzdHJpbmcgbXVzdCBiZWdpbiBhbmQgZW5kIHdpdGggc2luZ2xlIG9yIGRvdWJsZSBxdW90ZQorLy8gY2hhcmFjdGVycy4KK3ZvaWQgVG9rZW5pemVyOjpQYXJzZVN0cmluZ0FwcGVuZChjb25zdCBzdHJpbmcmIHRleHQsIHN0cmluZyogb3V0cHV0KSB7CisgIC8vIFJlbWluZGVyOiB0ZXh0WzBdIGlzIGFsd2F5cyBhIHF1b3RlIGNoYXJhY3Rlci4gIChJZiB0ZXh0IGlzCisgIC8vIGVtcHR5LCBpdCdzIGludmFsaWQsIHNvIHdlJ2xsIGp1c3QgcmV0dXJuKS4KKyAgY29uc3Qgc2l6ZV90IHRleHRfc2l6ZSA9IHRleHQuc2l6ZSgpOworICBpZiAodGV4dF9zaXplID09IDApIHsKKyAgICBHT09HTEVfTE9HKERGQVRBTCkKKyAgICAgIDw8ICIgVG9rZW5pemVyOjpQYXJzZVN0cmluZ0FwcGVuZCgpIHBhc3NlZCB0ZXh0IHRoYXQgY291bGQgbm90IgorICAgICAgICAgIiBoYXZlIGJlZW4gdG9rZW5pemVkIGFzIGEgc3RyaW5nOiAiIDw8IENFc2NhcGUodGV4dCk7CisgICAgcmV0dXJuOworICB9CisKKyAgLy8gUmVzZXJ2ZSByb29tIGZvciBuZXcgc3RyaW5nLiBUaGUgYnJhbmNoIGlzIG5lY2Vzc2FyeSBiZWNhdXNlIGlmCisgIC8vIHRoZXJlIGlzIGFscmVhZHkgc3BhY2UgYXZhaWxhYmxlIHRoZSByZXNlcnZlKCkgY2FsbCBtaWdodAorICAvLyBkb3duc2l6ZSB0aGUgb3V0cHV0LgorICBjb25zdCBzaXplX3QgbmV3X2xlbiA9IHRleHRfc2l6ZSArIG91dHB1dC0+c2l6ZSgpOworICBpZiAobmV3X2xlbiA+IG91dHB1dC0+Y2FwYWNpdHkoKSkgeworICAgIG91dHB1dC0+cmVzZXJ2ZShuZXdfbGVuKTsKKyAgfQorCisgIC8vIExvb3AgdGhyb3VnaCB0aGUgc3RyaW5nIGNvcHlpbmcgY2hhcmFjdGVycyB0byAib3V0cHV0IiBhbmQKKyAgLy8gaW50ZXJwcmV0aW5nIGVzY2FwZSBzZXF1ZW5jZXMuICBOb3RlIHRoYXQgYW55IGludmFsaWQgZXNjYXBlCisgIC8vIHNlcXVlbmNlcyBvciBvdGhlciBlcnJvcnMgd2VyZSBhbHJlYWR5IHJlcG9ydGVkIHdoaWxlIHRva2VuaXppbmcuCisgIC8vIEluIHRoaXMgY2FzZSB3ZSBkbyBub3QgbmVlZCB0byBwcm9kdWNlIHZhbGlkIHJlc3VsdHMuCisgIGZvciAoY29uc3QgY2hhciogcHRyID0gdGV4dC5jX3N0cigpICsgMTsgKnB0ciAhPSAnXDAnOyBwdHIrKykgeworICAgIGlmICgqcHRyID09ICdcXCcgJiYgcHRyWzFdICE9ICdcMCcpIHsKKyAgICAgIC8vIEFuIGVzY2FwZSBzZXF1ZW5jZS4KKyAgICAgICsrcHRyOworCisgICAgICBpZiAoT2N0YWxEaWdpdDo6SW5DbGFzcygqcHRyKSkgeworICAgICAgICAvLyBBbiBvY3RhbCBlc2NhcGUuICBNYXkgb25lLCB0d28sIG9yIHRocmVlIGRpZ2l0cy4KKyAgICAgICAgaW50IGNvZGUgPSBEaWdpdFZhbHVlKCpwdHIpOworICAgICAgICBpZiAoT2N0YWxEaWdpdDo6SW5DbGFzcyhwdHJbMV0pKSB7CisgICAgICAgICAgKytwdHI7CisgICAgICAgICAgY29kZSA9IGNvZGUgKiA4ICsgRGlnaXRWYWx1ZSgqcHRyKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoT2N0YWxEaWdpdDo6SW5DbGFzcyhwdHJbMV0pKSB7CisgICAgICAgICAgKytwdHI7CisgICAgICAgICAgY29kZSA9IGNvZGUgKiA4ICsgRGlnaXRWYWx1ZSgqcHRyKTsKKyAgICAgICAgfQorICAgICAgICBvdXRwdXQtPnB1c2hfYmFjayhzdGF0aWNfY2FzdDxjaGFyPihjb2RlKSk7CisKKyAgICAgIH0gZWxzZSBpZiAoKnB0ciA9PSAneCcpIHsKKyAgICAgICAgLy8gQSBoZXggZXNjYXBlLiAgTWF5IHplcm8sIG9uZSwgb3IgdHdvIGRpZ2l0cy4gIChUaGUgemVybyBjYXNlCisgICAgICAgIC8vIHdpbGwgaGF2ZSBiZWVuIGNhdWdodCBhcyBhbiBlcnJvciBlYXJsaWVyLikKKyAgICAgICAgaW50IGNvZGUgPSAwOworICAgICAgICBpZiAoSGV4RGlnaXQ6OkluQ2xhc3MocHRyWzFdKSkgeworICAgICAgICAgICsrcHRyOworICAgICAgICAgIGNvZGUgPSBEaWdpdFZhbHVlKCpwdHIpOworICAgICAgICB9CisgICAgICAgIGlmIChIZXhEaWdpdDo6SW5DbGFzcyhwdHJbMV0pKSB7CisgICAgICAgICAgKytwdHI7CisgICAgICAgICAgY29kZSA9IGNvZGUgKiAxNiArIERpZ2l0VmFsdWUoKnB0cik7CisgICAgICAgIH0KKyAgICAgICAgb3V0cHV0LT5wdXNoX2JhY2soc3RhdGljX2Nhc3Q8Y2hhcj4oY29kZSkpOworCisgICAgICB9IGVsc2UgaWYgKCpwdHIgPT0gJ3UnIHx8ICpwdHIgPT0gJ1UnKSB7CisgICAgICAgIHVpbnQzMiB1bmljb2RlOworICAgICAgICBjb25zdCBjaGFyKiBlbmQgPSBGZXRjaFVuaWNvZGVQb2ludChwdHIsICZ1bmljb2RlKTsKKyAgICAgICAgaWYgKGVuZCA9PSBwdHIpIHsKKyAgICAgICAgICAvLyBGYWlsdXJlOiBKdXN0IGR1bXAgb3V0IHdoYXQgd2Ugc2F3LCBkb24ndCB0cnkgdG8gcGFyc2UgaXQuCisgICAgICAgICAgb3V0cHV0LT5wdXNoX2JhY2soKnB0cik7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgQXBwZW5kVVRGOCh1bmljb2RlLCBvdXRwdXQpOworICAgICAgICAgIHB0ciA9IGVuZCAtIDE7ICAvLyBCZWNhdXNlIHdlJ3JlIGFib3V0IHRvICsrcHRyLgorICAgICAgICB9CisgICAgICB9IGVsc2UgeworICAgICAgICAvLyBTb21lIG90aGVyIGVzY2FwZSBjb2RlLgorICAgICAgICBvdXRwdXQtPnB1c2hfYmFjayhUcmFuc2xhdGVFc2NhcGUoKnB0cikpOworICAgICAgfQorCisgICAgfSBlbHNlIGlmICgqcHRyID09IHRleHRbMF0gJiYgcHRyWzFdID09ICdcMCcpIHsKKyAgICAgIC8vIElnbm9yZSBmaW5hbCBxdW90ZSBtYXRjaGluZyB0aGUgc3RhcnRpbmcgcXVvdGUuCisgICAgfSBlbHNlIHsKKyAgICAgIG91dHB1dC0+cHVzaF9iYWNrKCpwdHIpOworICAgIH0KKyAgfQorfQorCit0ZW1wbGF0ZTx0eXBlbmFtZSBDaGFyYWN0ZXJDbGFzcz4KK3N0YXRpYyBib29sIEFsbEluQ2xhc3MoY29uc3Qgc3RyaW5nJiBzKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgcy5zaXplKCk7ICsraSkgeworICAgIGlmICghQ2hhcmFjdGVyQ2xhc3M6OkluQ2xhc3Moc1tpXSkpCisgICAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgVG9rZW5pemVyOjpJc0lkZW50aWZpZXIoY29uc3Qgc3RyaW5nJiB0ZXh0KSB7CisgIC8vIE1pcnJvcnMgSURFTlRJRklFUiBkZWZpbml0aW9uIGluIFRva2VuaXplcjo6TmV4dCgpIGFib3ZlLgorICBpZiAodGV4dC5zaXplKCkgPT0gMCkKKyAgICByZXR1cm4gZmFsc2U7CisgIGlmICghTGV0dGVyOjpJbkNsYXNzKHRleHQuYXQoMCkpKQorICAgIHJldHVybiBmYWxzZTsKKyAgaWYgKCFBbGxJbkNsYXNzPEFscGhhbnVtZXJpYz4odGV4dC5zdWJzdHIoMSkpKQorICAgIHJldHVybiBmYWxzZTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBpbworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3Rva2VuaXplci5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby90b2tlbml6ZXIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40OTg4NWVkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby90b2tlbml6ZXIuaApAQCAtMCwwICsxLDQwMyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorLy8KKy8vIENsYXNzIGZvciBwYXJzaW5nIHRva2VuaXplZCB0ZXh0IGZyb20gYSBaZXJvQ29weUlucHV0U3RyZWFtLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9JT19UT0tFTklaRVJfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9JT19UT0tFTklaRVJfSF9fCisKKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8dmVjdG9yPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbG9nZ2luZy5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW8geworCitjbGFzcyBaZXJvQ29weUlucHV0U3RyZWFtOyAgICAgLy8gemVyb19jb3B5X3N0cmVhbS5oCisKKy8vIERlZmluZWQgaW4gdGhpcyBmaWxlLgorY2xhc3MgRXJyb3JDb2xsZWN0b3I7CitjbGFzcyBUb2tlbml6ZXI7CisKKy8vIEFic3RyYWN0IGludGVyZmFjZSBmb3IgYW4gb2JqZWN0IHdoaWNoIGNvbGxlY3RzIHRoZSBlcnJvcnMgdGhhdCBvY2N1cgorLy8gZHVyaW5nIHBhcnNpbmcuICBBIHR5cGljYWwgaW1wbGVtZW50YXRpb24gbWlnaHQgc2ltcGx5IHByaW50IHRoZSBlcnJvcnMKKy8vIHRvIHN0ZG91dC4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBFcnJvckNvbGxlY3RvciB7CisgcHVibGljOgorICBpbmxpbmUgRXJyb3JDb2xsZWN0b3IoKSB7fQorICB2aXJ0dWFsIH5FcnJvckNvbGxlY3RvcigpOworCisgIC8vIEluZGljYXRlcyB0aGF0IHRoZXJlIHdhcyBhbiBlcnJvciBpbiB0aGUgaW5wdXQgYXQgdGhlIGdpdmVuIGxpbmUgYW5kCisgIC8vIGNvbHVtbiBudW1iZXJzLiAgVGhlIG51bWJlcnMgYXJlIHplcm8tYmFzZWQsIHNvIHlvdSBtYXkgd2FudCB0byBhZGQKKyAgLy8gMSB0byBlYWNoIGJlZm9yZSBwcmludGluZyB0aGVtLgorICB2aXJ0dWFsIHZvaWQgQWRkRXJyb3IoaW50IGxpbmUsIGludCBjb2x1bW4sIGNvbnN0IHN0cmluZyYgbWVzc2FnZSkgPSAwOworCisgIC8vIEluZGljYXRlcyB0aGF0IHRoZXJlIHdhcyBhIHdhcm5pbmcgaW4gdGhlIGlucHV0IGF0IHRoZSBnaXZlbiBsaW5lIGFuZAorICAvLyBjb2x1bW4gbnVtYmVycy4gIFRoZSBudW1iZXJzIGFyZSB6ZXJvLWJhc2VkLCBzbyB5b3UgbWF5IHdhbnQgdG8gYWRkCisgIC8vIDEgdG8gZWFjaCBiZWZvcmUgcHJpbnRpbmcgdGhlbS4KKyAgdmlydHVhbCB2b2lkIEFkZFdhcm5pbmcoaW50IC8qIGxpbmUgKi8sIGludCAvKiBjb2x1bW4gKi8sCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgLyogbWVzc2FnZSAqLykgeyB9CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoRXJyb3JDb2xsZWN0b3IpOworfTsKKworLy8gVGhpcyBjbGFzcyBjb252ZXJ0cyBhIHN0cmVhbSBvZiByYXcgdGV4dCBpbnRvIGEgc3RyZWFtIG9mIHRva2VucyBmb3IKKy8vIHRoZSBwcm90b2NvbCBkZWZpbml0aW9uIHBhcnNlciB0byBwYXJzZS4gIFRoZSB0b2tlbnMgcmVjb2duaXplZCBhcmUKKy8vIHNpbWlsYXIgdG8gdGhvc2UgdGhhdCBtYWtlIHVwIHRoZSBDIGxhbmd1YWdlOyBzZWUgdGhlIFRva2VuVHlwZSBlbnVtIGZvcgorLy8gcHJlY2lzZSBkZXNjcmlwdGlvbnMuICBXaGl0ZXNwYWNlIGFuZCBjb21tZW50cyBhcmUgc2tpcHBlZC4gIEJ5IGRlZmF1bHQsCisvLyBDLSBhbmQgQysrLXN0eWxlIGNvbW1lbnRzIGFyZSByZWNvZ25pemVkLCBidXQgb3RoZXIgc3R5bGVzIGNhbiBiZSB1c2VkIGJ5CisvLyBjYWxsaW5nIHNldF9jb21tZW50X3N0eWxlKCkuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgVG9rZW5pemVyIHsKKyBwdWJsaWM6CisgIC8vIENvbnN0cnVjdCBhIFRva2VuaXplciB0aGF0IHJlYWRzIGFuZCB0b2tlbml6ZXMgdGV4dCBmcm9tIHRoZSBnaXZlbgorICAvLyBpbnB1dCBzdHJlYW0gYW5kIHdyaXRlcyBlcnJvcnMgdG8gdGhlIGdpdmVuIGVycm9yX2NvbGxlY3Rvci4KKyAgLy8gVGhlIGNhbGxlciBrZWVwcyBvd25lcnNoaXAgb2YgaW5wdXQgYW5kIGVycm9yX2NvbGxlY3Rvci4KKyAgVG9rZW5pemVyKFplcm9Db3B5SW5wdXRTdHJlYW0qIGlucHV0LCBFcnJvckNvbGxlY3RvciogZXJyb3JfY29sbGVjdG9yKTsKKyAgflRva2VuaXplcigpOworCisgIGVudW0gVG9rZW5UeXBlIHsKKyAgICBUWVBFX1NUQVJULCAgICAgICAvLyBOZXh0KCkgaGFzIG5vdCB5ZXQgYmVlbiBjYWxsZWQuCisgICAgVFlQRV9FTkQsICAgICAgICAgLy8gRW5kIG9mIGlucHV0IHJlYWNoZWQuICAidGV4dCIgaXMgZW1wdHkuCisKKyAgICBUWVBFX0lERU5USUZJRVIsICAvLyBBIHNlcXVlbmNlIG9mIGxldHRlcnMsIGRpZ2l0cywgYW5kIHVuZGVyc2NvcmVzLCBub3QKKyAgICAgICAgICAgICAgICAgICAgICAvLyBzdGFydGluZyB3aXRoIGEgZGlnaXQuICBJdCBpcyBhbiBlcnJvciBmb3IgYSBudW1iZXIKKyAgICAgICAgICAgICAgICAgICAgICAvLyB0byBiZSBmb2xsb3dlZCBieSBhbiBpZGVudGlmaWVyIHdpdGggbm8gc3BhY2UgaW4KKyAgICAgICAgICAgICAgICAgICAgICAvLyBiZXR3ZWVuLgorICAgIFRZUEVfSU5URUdFUiwgICAgIC8vIEEgc2VxdWVuY2Ugb2YgZGlnaXRzIHJlcHJlc2VudGluZyBhbiBpbnRlZ2VyLiAgTm9ybWFsbHkKKyAgICAgICAgICAgICAgICAgICAgICAvLyB0aGUgZGlnaXRzIGFyZSBkZWNpbWFsLCBidXQgYSBwcmVmaXggb2YgIjB4IiBpbmRpY2F0ZXMKKyAgICAgICAgICAgICAgICAgICAgICAvLyBhIGhleCBudW1iZXIgYW5kIGEgbGVhZGluZyB6ZXJvIGluZGljYXRlcyBvY3RhbCwganVzdAorICAgICAgICAgICAgICAgICAgICAgIC8vIGxpa2Ugd2l0aCBDIG51bWVyaWMgbGl0ZXJhbHMuICBBIGxlYWRpbmcgbmVnYXRpdmUgc2lnbgorICAgICAgICAgICAgICAgICAgICAgIC8vIGlzIE5PVCBpbmNsdWRlZCBpbiB0aGUgdG9rZW47IGl0J3MgdXAgdG8gdGhlIHBhcnNlciB0bworICAgICAgICAgICAgICAgICAgICAgIC8vIGludGVycHJldCB0aGUgdW5hcnkgbWludXMgb3BlcmF0b3Igb24gaXRzIG93bi4KKyAgICBUWVBFX0ZMT0FULCAgICAgICAvLyBBIGZsb2F0aW5nIHBvaW50IGxpdGVyYWwsIHdpdGggYSBmcmFjdGlvbmFsIHBhcnQgYW5kL29yCisgICAgICAgICAgICAgICAgICAgICAgLy8gYW4gZXhwb25lbnQuICBBbHdheXMgaW4gZGVjaW1hbC4gIEFnYWluLCBuZXZlcgorICAgICAgICAgICAgICAgICAgICAgIC8vIG5lZ2F0aXZlLgorICAgIFRZUEVfU1RSSU5HLCAgICAgIC8vIEEgcXVvdGVkIHNlcXVlbmNlIG9mIGVzY2FwZWQgY2hhcmFjdGVycy4gIEVpdGhlciBzaW5nbGUKKyAgICAgICAgICAgICAgICAgICAgICAvLyBvciBkb3VibGUgcXVvdGVzIGNhbiBiZSB1c2VkLCBidXQgdGhleSBtdXN0IG1hdGNoLgorICAgICAgICAgICAgICAgICAgICAgIC8vIEEgc3RyaW5nIGxpdGVyYWwgY2Fubm90IGNyb3NzIGEgbGluZSBicmVhay4KKyAgICBUWVBFX1NZTUJPTCwgICAgICAvLyBBbnkgb3RoZXIgcHJpbnRhYmxlIGNoYXJhY3RlciwgbGlrZSAnIScgb3IgJysnLgorICAgICAgICAgICAgICAgICAgICAgIC8vIFN5bWJvbHMgYXJlIGFsd2F5cyBhIHNpbmdsZSBjaGFyYWN0ZXIsIHNvICIhKyQlIiBpcworICAgICAgICAgICAgICAgICAgICAgIC8vIGZvdXIgdG9rZW5zLgorICB9OworCisgIC8vIFN0cnVjdHVyZSByZXByZXNlbnRpbmcgYSB0b2tlbiByZWFkIGZyb20gdGhlIHRva2VuIHN0cmVhbS4KKyAgc3RydWN0IFRva2VuIHsKKyAgICBUb2tlblR5cGUgdHlwZTsKKyAgICBzdHJpbmcgdGV4dDsgICAgICAgLy8gVGhlIGV4YWN0IHRleHQgb2YgdGhlIHRva2VuIGFzIGl0IGFwcGVhcmVkIGluCisgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoZSBpbnB1dC4gIGUuZy4gdG9rZW5zIG9mIFRZUEVfU1RSSU5HIHdpbGwgc3RpbGwKKyAgICAgICAgICAgICAgICAgICAgICAgLy8gYmUgZXNjYXBlZCBhbmQgaW4gcXVvdGVzLgorCisgICAgLy8gImxpbmUiIGFuZCAiY29sdW1uIiBzcGVjaWZ5IHRoZSBwb3NpdGlvbiBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIG9mCisgICAgLy8gdGhlIHRva2VuIHdpdGhpbiB0aGUgaW5wdXQgc3RyZWFtLiAgVGhleSBhcmUgemVyby1iYXNlZC4KKyAgICBpbnQgbGluZTsKKyAgICBpbnQgY29sdW1uOworICAgIGludCBlbmRfY29sdW1uOworICB9OworCisgIC8vIEdldCB0aGUgY3VycmVudCB0b2tlbi4gIFRoaXMgaXMgdXBkYXRlZCB3aGVuIE5leHQoKSBpcyBjYWxsZWQuICBCZWZvcmUKKyAgLy8gdGhlIGZpcnN0IGNhbGwgdG8gTmV4dCgpLCBjdXJyZW50KCkgaGFzIHR5cGUgVFlQRV9TVEFSVCBhbmQgbm8gY29udGVudHMuCisgIGNvbnN0IFRva2VuJiBjdXJyZW50KCk7CisKKyAgLy8gUmV0dXJuIHRoZSBwcmV2aW91cyB0b2tlbiAtLSBpLmUuIHdoYXQgY3VycmVudCgpIHJldHVybmVkIGJlZm9yZSB0aGUKKyAgLy8gcHJldmlvdXMgY2FsbCB0byBOZXh0KCkuCisgIGNvbnN0IFRva2VuJiBwcmV2aW91cygpOworCisgIC8vIEFkdmFuY2UgdG8gdGhlIG5leHQgdG9rZW4uICBSZXR1cm5zIGZhbHNlIGlmIHRoZSBlbmQgb2YgdGhlIGlucHV0IGlzCisgIC8vIHJlYWNoZWQuCisgIGJvb2wgTmV4dCgpOworCisgIC8vIExpa2UgTmV4dCgpLCBidXQgYWxzbyBjb2xsZWN0cyBjb21tZW50cyB3aGljaCBhcHBlYXIgYmV0d2VlbiB0aGUgcHJldmlvdXMKKyAgLy8gYW5kIG5leHQgdG9rZW5zLgorICAvLworICAvLyBDb21tZW50cyB3aGljaCBhcHBlYXIgdG8gYmUgYXR0YWNoZWQgdG8gdGhlIHByZXZpb3VzIHRva2VuIGFyZSBzdG9yZWQKKyAgLy8gaW4gKnByZXZfdGFpbGluZ19jb21tZW50cy4gIENvbW1lbnRzIHdoaWNoIGFwcGVhciB0byBiZSBhdHRhY2hlZCB0byB0aGUKKyAgLy8gbmV4dCB0b2tlbiBhcmUgc3RvcmVkIGluICpuZXh0X2xlYWRpbmdfY29tbWVudHMuICBDb21tZW50cyBhcHBlYXJpbmcgaW4KKyAgLy8gYmV0d2VlbiB3aGljaCBkbyBub3QgYXBwZWFyIHRvIGJlIGF0dGFjaGVkIHRvIGVpdGhlciB3aWxsIGJlIGFkZGVkIHRvCisgIC8vIGRldGFjaGVkX2NvbW1lbnRzLiAgQW55IG9mIHRoZXNlIHBhcmFtZXRlcnMgY2FuIGJlIE5VTEwgdG8gc2ltcGx5IGRpc2NhcmQKKyAgLy8gdGhlIGNvbW1lbnRzLgorICAvLworICAvLyBBIHNlcmllcyBvZiBsaW5lIGNvbW1lbnRzIGFwcGVhcmluZyBvbiBjb25zZWN1dGl2ZSBsaW5lcywgd2l0aCBubyBvdGhlcgorICAvLyB0b2tlbnMgYXBwZWFyaW5nIG9uIHRob3NlIGxpbmVzLCB3aWxsIGJlIHRyZWF0ZWQgYXMgYSBzaW5nbGUgY29tbWVudC4KKyAgLy8KKyAgLy8gT25seSB0aGUgY29tbWVudCBjb250ZW50IGlzIHJldHVybmVkOyBjb21tZW50IG1hcmtlcnMgKGUuZy4gLy8pIGFyZQorICAvLyBzdHJpcHBlZCBvdXQuICBGb3IgYmxvY2sgY29tbWVudHMsIGxlYWRpbmcgd2hpdGVzcGFjZSBhbmQgYW4gYXN0ZXJpc2sgd2lsbAorICAvLyBiZSBzdHJpcHBlZCBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgZWFjaCBsaW5lIG90aGVyIHRoYW4gdGhlIGZpcnN0LiAgTmV3bGluZXMKKyAgLy8gYXJlIGluY2x1ZGVkIGluIHRoZSBvdXRwdXQuCisgIC8vCisgIC8vIEV4YW1wbGVzOgorICAvLworICAvLyAgIG9wdGlvbmFsIGludDMyIGZvbyA9IDE7ICAvLyBDb21tZW50IGF0dGFjaGVkIHRvIGZvby4KKyAgLy8gICAvLyBDb21tZW50IGF0dGFjaGVkIHRvIGJhci4KKyAgLy8gICBvcHRpb25hbCBpbnQzMiBiYXIgPSAyOworICAvLworICAvLyAgIG9wdGlvbmFsIHN0cmluZyBiYXogPSAzOworICAvLyAgIC8vIENvbW1lbnQgYXR0YWNoZWQgdG8gYmF6LgorICAvLyAgIC8vIEFub3RoZXIgbGluZSBhdHRhY2hlZCB0byBiYXouCisgIC8vCisgIC8vICAgLy8gQ29tbWVudCBhdHRhY2hlZCB0byBxdXguCisgIC8vICAgLy8KKyAgLy8gICAvLyBBbm90aGVyIGxpbmUgYXR0YWNoZWQgdG8gcXV4LgorICAvLyAgIG9wdGlvbmFsIGRvdWJsZSBxdXggPSA0OworICAvLworICAvLyAgIC8vIERldGFjaGVkIGNvbW1lbnQuICBUaGlzIGlzIG5vdCBhdHRhY2hlZCB0byBxdXggb3IgY29yZ2UKKyAgLy8gICAvLyBiZWNhdXNlIHRoZXJlIGFyZSBibGFuayBsaW5lcyBzZXBhcmF0aW5nIGl0IGZyb20gYm90aC4KKyAgLy8KKyAgLy8gICBvcHRpb25hbCBzdHJpbmcgY29yZ2UgPSA1OworICAvLyAgIC8qIEJsb2NrIGNvbW1lbnQgYXR0YWNoZWQKKyAgLy8gICAgKiB0byBjb3JnZS4gIExlYWRpbmcgYXN0ZXJpc2tzCisgIC8vICAgICogd2lsbCBiZSByZW1vdmVkLiAqLworICAvLyAgIC8qIEJsb2NrIGNvbW1lbnQgYXR0YWNoZWQgdG8KKyAgLy8gICAgKiBncmF1bHQuICovCisgIC8vICAgb3B0aW9uYWwgaW50MzIgZ3JhdWx0ID0gNjsKKyAgYm9vbCBOZXh0V2l0aENvbW1lbnRzKHN0cmluZyogcHJldl90cmFpbGluZ19jb21tZW50cywKKyAgICAgICAgICAgICAgICAgICAgICAgIHZlY3RvcjxzdHJpbmc+KiBkZXRhY2hlZF9jb21tZW50cywKKyAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyogbmV4dF9sZWFkaW5nX2NvbW1lbnRzKTsKKworICAvLyBQYXJzZSBoZWxwZXJzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIFBhcnNlcyBhIFRZUEVfRkxPQVQgdG9rZW4uICBUaGlzIG5ldmVyIGZhaWxzLCBzbyBsb25nIGFzIHRoZSB0ZXh0IGFjdHVhbGx5CisgIC8vIGNvbWVzIGZyb20gYSBUWVBFX0ZMT0FUIHRva2VuIHBhcnNlZCBieSBUb2tlbml6ZXIuICBJZiBpdCBkb2Vzbid0LCB0aGUKKyAgLy8gcmVzdWx0IGlzIHVuZGVmaW5lZCAocG9zc2libHkgYW4gYXNzZXJ0IGZhaWx1cmUpLgorICBzdGF0aWMgZG91YmxlIFBhcnNlRmxvYXQoY29uc3Qgc3RyaW5nJiB0ZXh0KTsKKworICAvLyBQYXJzZXMgYSBUWVBFX1NUUklORyB0b2tlbi4gIFRoaXMgbmV2ZXIgZmFpbHMsIHNvIGxvbmcgYXMgdGhlIHRleHQgYWN0dWFsbHkKKyAgLy8gY29tZXMgZnJvbSBhIFRZUEVfU1RSSU5HIHRva2VuIHBhcnNlZCBieSBUb2tlbml6ZXIuICBJZiBpdCBkb2Vzbid0LCB0aGUKKyAgLy8gcmVzdWx0IGlzIHVuZGVmaW5lZCAocG9zc2libHkgYW4gYXNzZXJ0IGZhaWx1cmUpLgorICBzdGF0aWMgdm9pZCBQYXJzZVN0cmluZyhjb25zdCBzdHJpbmcmIHRleHQsIHN0cmluZyogb3V0cHV0KTsKKworICAvLyBJZGVudGljYWwgdG8gUGFyc2VTdHJpbmcsIGJ1dCBhcHBlbmRzIHRvIG91dHB1dC4KKyAgc3RhdGljIHZvaWQgUGFyc2VTdHJpbmdBcHBlbmQoY29uc3Qgc3RyaW5nJiB0ZXh0LCBzdHJpbmcqIG91dHB1dCk7CisKKyAgLy8gUGFyc2VzIGEgVFlQRV9JTlRFR0VSIHRva2VuLiAgUmV0dXJucyBmYWxzZSBpZiB0aGUgcmVzdWx0IHdvdWxkIGJlCisgIC8vIGdyZWF0ZXIgdGhhbiBtYXhfdmFsdWUuICBPdGhlcndpc2UsIHJldHVybnMgdHJ1ZSBhbmQgc2V0cyAqb3V0cHV0IHRvIHRoZQorICAvLyByZXN1bHQuICBJZiB0aGUgdGV4dCBpcyBub3QgZnJvbSBhIFRva2VuIG9mIHR5cGUgVFlQRV9JTlRFR0VSIG9yaWdpbmFsbHkKKyAgLy8gcGFyc2VkIGJ5IGEgVG9rZW5pemVyLCB0aGUgcmVzdWx0IGlzIHVuZGVmaW5lZCAocG9zc2libHkgYW4gYXNzZXJ0CisgIC8vIGZhaWx1cmUpLgorICBzdGF0aWMgYm9vbCBQYXJzZUludGVnZXIoY29uc3Qgc3RyaW5nJiB0ZXh0LCB1aW50NjQgbWF4X3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDY0KiBvdXRwdXQpOworCisgIC8vIE9wdGlvbnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gU2V0IHRydWUgdG8gYWxsb3cgZmxvYXRzIHRvIGJlIHN1ZmZpeGVkIHdpdGggdGhlIGxldHRlciAnZicuICBUb2tlbnMKKyAgLy8gd2hpY2ggd291bGQgb3RoZXJ3aXNlIGJlIGludGVnZXJzIGJ1dCB3aGljaCBoYXZlIHRoZSAnZicgc3VmZml4IHdpbGwgYmUKKyAgLy8gZm9yY2VkIHRvIGJlIGludGVycHJldGVkIGFzIGZsb2F0cy4gIEZvciBhbGwgb3RoZXIgcHVycG9zZXMsIHRoZSAnZicgaXMKKyAgLy8gaWdub3JlZC4KKyAgdm9pZCBzZXRfYWxsb3dfZl9hZnRlcl9mbG9hdChib29sIHZhbHVlKSB7IGFsbG93X2ZfYWZ0ZXJfZmxvYXRfID0gdmFsdWU7IH0KKworICAvLyBWYWxpZCB2YWx1ZXMgZm9yIHNldF9jb21tZW50X3N0eWxlKCkuCisgIGVudW0gQ29tbWVudFN0eWxlIHsKKyAgICAvLyBMaW5lIGNvbW1lbnRzIGJlZ2luIHdpdGggIi8vIiwgYmxvY2sgY29tbWVudHMgYXJlIGRlbGltaXRlZCBieSAiLyoiIGFuZAorICAgIC8vICIqLyIuCisgICAgQ1BQX0NPTU1FTlRfU1RZTEUsCisgICAgLy8gTGluZSBjb21tZW50cyBiZWdpbiB3aXRoICIjIi4gIE5vIHdheSB0byB3cml0ZSBibG9jayBjb21tZW50cy4KKyAgICBTSF9DT01NRU5UX1NUWUxFCisgIH07CisKKyAgLy8gU2V0cyB0aGUgY29tbWVudCBzdHlsZS4KKyAgdm9pZCBzZXRfY29tbWVudF9zdHlsZShDb21tZW50U3R5bGUgc3R5bGUpIHsgY29tbWVudF9zdHlsZV8gPSBzdHlsZTsgfQorCisgIC8vIFdoZXRoZXIgdG8gcmVxdWlyZSB3aGl0ZXNwYWNlIGJldHdlZW4gYSBudW1iZXIgYW5kIGEgZmllbGQgbmFtZS4KKyAgLy8gRGVmYXVsdCBpcyB0cnVlLiBEbyBub3QgdXNlIHRoaXM7IGZvciBHb29nbGUtaW50ZXJuYWwgY2xlYW51cCBvbmx5LgorICB2b2lkIHNldF9yZXF1aXJlX3NwYWNlX2FmdGVyX251bWJlcihib29sIHJlcXVpcmUpIHsKKyAgICByZXF1aXJlX3NwYWNlX2FmdGVyX251bWJlcl8gPSByZXF1aXJlOworICB9CisKKyAgLy8gV2hldGhlciB0byBhbGxvdyBzdHJpbmcgbGl0ZXJhbHMgdG8gc3BhbiBtdWx0aXBsZSBsaW5lcy4gRGVmYXVsdCBpcyBmYWxzZS4KKyAgLy8gRG8gbm90IHVzZSB0aGlzOyBmb3IgR29vZ2xlLWludGVybmFsIGNsZWFudXAgb25seS4KKyAgdm9pZCBzZXRfYWxsb3dfbXVsdGlsaW5lX3N0cmluZ3MoYm9vbCBhbGxvdykgeworICAgIGFsbG93X211bHRpbGluZV9zdHJpbmdzXyA9IGFsbG93OworICB9CisKKyAgLy8gRXh0ZXJuYWwgaGVscGVyOiB2YWxpZGF0ZSBhbiBpZGVudGlmaWVyLgorICBzdGF0aWMgYm9vbCBJc0lkZW50aWZpZXIoY29uc3Qgc3RyaW5nJiB0ZXh0KTsKKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhUb2tlbml6ZXIpOworCisgIFRva2VuIGN1cnJlbnRfOyAgICAgICAgICAgLy8gUmV0dXJuZWQgYnkgY3VycmVudCgpLgorICBUb2tlbiBwcmV2aW91c187ICAgICAgICAgIC8vIFJldHVybmVkIGJ5IHByZXZpb3VzKCkuCisKKyAgWmVyb0NvcHlJbnB1dFN0cmVhbSogaW5wdXRfOworICBFcnJvckNvbGxlY3RvciogZXJyb3JfY29sbGVjdG9yXzsKKworICBjaGFyIGN1cnJlbnRfY2hhcl87ICAgICAgIC8vID09IGJ1ZmZlcl9bYnVmZmVyX3Bvc19dLCB1cGRhdGVkIGJ5IE5leHRDaGFyKCkuCisgIGNvbnN0IGNoYXIqIGJ1ZmZlcl87ICAgICAgLy8gQ3VycmVudCBidWZmZXIgcmV0dXJuZWQgZnJvbSBpbnB1dF8uCisgIGludCBidWZmZXJfc2l6ZV87ICAgICAgICAgLy8gU2l6ZSBvZiBidWZmZXJfLgorICBpbnQgYnVmZmVyX3Bvc187ICAgICAgICAgIC8vIEN1cnJlbnQgcG9zaXRpb24gd2l0aGluIHRoZSBidWZmZXIuCisgIGJvb2wgcmVhZF9lcnJvcl87ICAgICAgICAgLy8gRGlkIHdlIHByZXZpb3VzbHkgZW5jb3VudGVyIGEgcmVhZCBlcnJvcj8KKworICAvLyBMaW5lIGFuZCBjb2x1bW4gbnVtYmVyIG9mIGN1cnJlbnRfY2hhcl8gd2l0aGluIHRoZSB3aG9sZSBpbnB1dCBzdHJlYW0uCisgIGludCBsaW5lXzsKKyAgaW50IGNvbHVtbl87CisKKyAgLy8gU3RyaW5nIHRvIHdoaWNoIHRleHQgc2hvdWxkIGJlIGFwcGVuZGVkIGFzIHdlIGFkdmFuY2UgdGhyb3VnaCBpdC4KKyAgLy8gQ2FsbCBSZWNvcmRUbygmc3RyKSB0byBzdGFydCByZWNvcmRpbmcgYW5kIFN0b3BSZWNvcmRpbmcoKSB0byBzdG9wLgorICAvLyBFLmcuIFN0YXJ0VG9rZW4oKSBjYWxscyBSZWNvcmRUbygmY3VycmVudF8udGV4dCkuICByZWNvcmRfc3RhcnRfIGlzIHRoZQorICAvLyBwb3NpdGlvbiB3aXRoaW4gdGhlIGN1cnJlbnQgYnVmZmVyIHdoZXJlIHJlY29yZGluZyBzdGFydGVkLgorICBzdHJpbmcqIHJlY29yZF90YXJnZXRfOworICBpbnQgcmVjb3JkX3N0YXJ0XzsKKworICAvLyBPcHRpb25zLgorICBib29sIGFsbG93X2ZfYWZ0ZXJfZmxvYXRfOworICBDb21tZW50U3R5bGUgY29tbWVudF9zdHlsZV87CisgIGJvb2wgcmVxdWlyZV9zcGFjZV9hZnRlcl9udW1iZXJfOworICBib29sIGFsbG93X211bHRpbGluZV9zdHJpbmdzXzsKKworICAvLyBTaW5jZSB3ZSBjb3VudCBjb2x1bW5zIHdlIG5lZWQgdG8gaW50ZXJwcmV0IHRhYnMgc29tZWhvdy4gIFdlJ2xsIHRha2UKKyAgLy8gdGhlIHN0YW5kYXJkIDgtY2hhcmFjdGVyIGRlZmluaXRpb24gZm9yIGxhY2sgb2YgYW55IHdheSB0byBkbyBiZXR0ZXIuCisgIHN0YXRpYyBjb25zdCBpbnQga1RhYldpZHRoID0gODsKKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAvLyBIZWxwZXIgbWV0aG9kcy4KKworICAvLyBDb25zdW1lIHRoaXMgY2hhcmFjdGVyIGFuZCBhZHZhbmNlIHRvIHRoZSBuZXh0IG9uZS4KKyAgdm9pZCBOZXh0Q2hhcigpOworCisgIC8vIFJlYWQgYSBuZXcgYnVmZmVyIGZyb20gdGhlIGlucHV0LgorICB2b2lkIFJlZnJlc2goKTsKKworICBpbmxpbmUgdm9pZCBSZWNvcmRUbyhzdHJpbmcqIHRhcmdldCk7CisgIGlubGluZSB2b2lkIFN0b3BSZWNvcmRpbmcoKTsKKworICAvLyBDYWxsZWQgd2hlbiB0aGUgY3VycmVudCBjaGFyYWN0ZXIgaXMgdGhlIGZpcnN0IGNoYXJhY3RlciBvZiBhIG5ldworICAvLyB0b2tlbiAobm90IGluY2x1ZGluZyB3aGl0ZXNwYWNlIG9yIGNvbW1lbnRzKS4KKyAgaW5saW5lIHZvaWQgU3RhcnRUb2tlbigpOworICAvLyBDYWxsZWQgd2hlbiB0aGUgY3VycmVudCBjaGFyYWN0ZXIgaXMgdGhlIGZpcnN0IGNoYXJhY3RlciBhZnRlciB0aGUKKyAgLy8gZW5kIG9mIHRoZSBsYXN0IHRva2VuLiAgQWZ0ZXIgdGhpcyByZXR1cm5zLCBjdXJyZW50Xy50ZXh0IHdpbGwKKyAgLy8gY29udGFpbiBhbGwgdGV4dCBjb25zdW1lZCBzaW5jZSBTdGFydFRva2VuKCkgd2FzIGNhbGxlZC4KKyAgaW5saW5lIHZvaWQgRW5kVG9rZW4oKTsKKworICAvLyBDb252ZW5pZW5jZSBtZXRob2QgdG8gYWRkIGFuIGVycm9yIGF0IHRoZSBjdXJyZW50IGxpbmUgYW5kIGNvbHVtbi4KKyAgdm9pZCBBZGRFcnJvcihjb25zdCBzdHJpbmcmIG1lc3NhZ2UpIHsKKyAgICBlcnJvcl9jb2xsZWN0b3JfLT5BZGRFcnJvcihsaW5lXywgY29sdW1uXywgbWVzc2FnZSk7CisgIH0KKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAvLyBUaGUgZm9sbG93aW5nIGZvdXIgbWV0aG9kcyBhcmUgdXNlZCB0byBjb25zdW1lIHRva2VucyBvZiBzcGVjaWZpYworICAvLyB0eXBlcy4gIFRoZXkgYXJlIGFjdHVhbGx5IHVzZWQgdG8gY29uc3VtZSBhbGwgY2hhcmFjdGVycyAqYWZ0ZXIqCisgIC8vIHRoZSBmaXJzdCwgc2luY2UgdGhlIGNhbGxpbmcgZnVuY3Rpb24gY29uc3VtZXMgdGhlIGZpcnN0IGNoYXJhY3RlcgorICAvLyBpbiBvcmRlciB0byBkZWNpZGUgd2hhdCBraW5kIG9mIHRva2VuIGlzIGJlaW5nIHJlYWQuCisKKyAgLy8gUmVhZCBhbmQgY29uc3VtZSBhIHN0cmluZywgZW5kaW5nIHdoZW4gdGhlIGdpdmVuIGRlbGltaXRlciBpcworICAvLyBjb25zdW1lZC4KKyAgdm9pZCBDb25zdW1lU3RyaW5nKGNoYXIgZGVsaW1pdGVyKTsKKworICAvLyBSZWFkIGFuZCBjb25zdW1lIGEgbnVtYmVyLCByZXR1cm5pbmcgVFlQRV9GTE9BVCBvciBUWVBFX0lOVEVHRVIKKyAgLy8gZGVwZW5kaW5nIG9uIHdoYXQgd2FzIHJlYWQuICBUaGlzIG5lZWRzIHRvIGtub3cgaWYgdGhlIGZpcnN0CisgIC8vIGNoYXJhY3RlciB3YXMgYSB6ZXJvIGluIG9yZGVyIHRvIGNvcnJlY3RseSByZWNvZ25pemUgaGV4IGFuZCBvY3RhbAorICAvLyBudW1iZXJzLgorICAvLyBJdCBhbHNvIG5lZWRzIHRvIGtub3cgaWYgdGhlIGZpcnN0IGNoYXJhY3RlZCB3YXMgYSAuIHRvIHBhcnNlIGZsb2F0aW5nCisgIC8vIHBvaW50IGNvcnJlY3RseS4KKyAgVG9rZW5UeXBlIENvbnN1bWVOdW1iZXIoYm9vbCBzdGFydGVkX3dpdGhfemVybywgYm9vbCBzdGFydGVkX3dpdGhfZG90KTsKKworICAvLyBDb25zdW1lIHRoZSByZXN0IG9mIGEgbGluZS4KKyAgdm9pZCBDb25zdW1lTGluZUNvbW1lbnQoc3RyaW5nKiBjb250ZW50KTsKKyAgLy8gQ29uc3VtZSB1bnRpbCAiKi8iLgorICB2b2lkIENvbnN1bWVCbG9ja0NvbW1lbnQoc3RyaW5nKiBjb250ZW50KTsKKworICBlbnVtIE5leHRDb21tZW50U3RhdHVzIHsKKyAgICAvLyBTdGFydGVkIGEgbGluZSBjb21tZW50LgorICAgIExJTkVfQ09NTUVOVCwKKworICAgIC8vIFN0YXJ0ZWQgYSBibG9jayBjb21tZW50LgorICAgIEJMT0NLX0NPTU1FTlQsCisKKyAgICAvLyBDb25zdW1lZCBhIHNsYXNoLCB0aGVuIHJlYWxpemVkIGl0IHdhc24ndCBhIGNvbW1lbnQuICBjdXJyZW50XyBoYXMKKyAgICAvLyBiZWVuIGZpbGxlZCBpbiB3aXRoIGEgc2xhc2ggdG9rZW4uICBUaGUgY2FsbGVyIHNob3VsZCByZXR1cm4gaXQuCisgICAgU0xBU0hfTk9UX0NPTU1FTlQsCisKKyAgICAvLyBXZSBkbyBub3QgYXBwZWFyIHRvIGJlIHN0YXJ0aW5nIGEgY29tbWVudCBoZXJlLgorICAgIE5PX0NPTU1FTlQKKyAgfTsKKworICAvLyBJZiB3ZSdyZSBhdCB0aGUgc3RhcnQgb2YgYSBuZXcgY29tbWVudCwgY29uc3VtZSBpdCBhbmQgcmV0dXJuIHdoYXQga2luZAorICAvLyBvZiBjb21tZW50IGl0IGlzLgorICBOZXh0Q29tbWVudFN0YXR1cyBUcnlDb25zdW1lQ29tbWVudFN0YXJ0KCk7CisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgLy8gVGhlc2UgaGVscGVyIG1ldGhvZHMgbWFrZSB0aGUgcGFyc2luZyBjb2RlIG1vcmUgcmVhZGFibGUuICBUaGUKKyAgLy8gImNoYXJhY3RlciBjbGFzc2VzIiByZWZlcnJlZCB0byBhcmUgZGVmaW5lZCBhdCB0aGUgdG9wIG9mIHRoZSAuY2MgZmlsZS4KKyAgLy8gQmFzaWNhbGx5IGl0IGlzIGEgQysrIGNsYXNzIHdpdGggb25lIG1ldGhvZDoKKyAgLy8gICBzdGF0aWMgYm9vbCBJbkNsYXNzKGNoYXIgYyk7CisgIC8vIFRoZSBtZXRob2QgcmV0dXJucyB0cnVlIGlmIGMgaXMgYSBtZW1iZXIgb2YgdGhpcyAiY2xhc3MiLCBsaWtlICJMZXR0ZXIiCisgIC8vIG9yICJEaWdpdCIuCisKKyAgLy8gUmV0dXJucyB0cnVlIGlmIHRoZSBjdXJyZW50IGNoYXJhY3RlciBpcyBvZiB0aGUgZ2l2ZW4gY2hhcmFjdGVyCisgIC8vIGNsYXNzLCBidXQgZG9lcyBub3QgY29uc3VtZSBhbnl0aGluZy4KKyAgdGVtcGxhdGU8dHlwZW5hbWUgQ2hhcmFjdGVyQ2xhc3M+CisgIGlubGluZSBib29sIExvb2tpbmdBdCgpOworCisgIC8vIElmIHRoZSBjdXJyZW50IGNoYXJhY3RlciBpcyBpbiB0aGUgZ2l2ZW4gY2xhc3MsIGNvbnN1bWUgaXQgYW5kIHJldHVybgorICAvLyB0cnVlLiAgT3RoZXJ3aXNlIHJldHVybiBmYWxzZS4KKyAgLy8gZS5nLiBUcnlDb25zdW1lT25lPExldHRlcj4oKQorICB0ZW1wbGF0ZTx0eXBlbmFtZSBDaGFyYWN0ZXJDbGFzcz4KKyAgaW5saW5lIGJvb2wgVHJ5Q29uc3VtZU9uZSgpOworCisgIC8vIExpa2UgYWJvdmUsIGJ1dCB0cnkgdG8gY29uc3VtZSB0aGUgc3BlY2lmaWMgY2hhcmFjdGVyIGluZGljYXRlZC4KKyAgaW5saW5lIGJvb2wgVHJ5Q29uc3VtZShjaGFyIGMpOworCisgIC8vIENvbnN1bWUgemVybyBvciBtb3JlIG9mIHRoZSBnaXZlbiBjaGFyYWN0ZXIgY2xhc3MuCisgIHRlbXBsYXRlPHR5cGVuYW1lIENoYXJhY3RlckNsYXNzPgorICBpbmxpbmUgdm9pZCBDb25zdW1lWmVyb09yTW9yZSgpOworCisgIC8vIENvbnN1bWUgb25lIG9yIG1vcmUgb2YgdGhlIGdpdmVuIGNoYXJhY3RlciBjbGFzcyBvciBsb2cgdGhlIGdpdmVuCisgIC8vIGVycm9yIG1lc3NhZ2UuCisgIC8vIGUuZy4gQ29uc3VtZU9uZU9yTW9yZTxEaWdpdD4oIkV4cGVjdGVkIGRpZ2l0cy4iKTsKKyAgdGVtcGxhdGU8dHlwZW5hbWUgQ2hhcmFjdGVyQ2xhc3M+CisgIGlubGluZSB2b2lkIENvbnN1bWVPbmVPck1vcmUoY29uc3QgY2hhciogZXJyb3IpOworfTsKKworLy8gaW5saW5lIG1ldGhvZHMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoraW5saW5lIGNvbnN0IFRva2VuaXplcjo6VG9rZW4mIFRva2VuaXplcjo6Y3VycmVudCgpIHsKKyAgcmV0dXJuIGN1cnJlbnRfOworfQorCitpbmxpbmUgY29uc3QgVG9rZW5pemVyOjpUb2tlbiYgVG9rZW5pemVyOjpwcmV2aW91cygpIHsKKyAgcmV0dXJuIHByZXZpb3VzXzsKK30KKworaW5saW5lIHZvaWQgVG9rZW5pemVyOjpQYXJzZVN0cmluZyhjb25zdCBzdHJpbmcmIHRleHQsIHN0cmluZyogb3V0cHV0KSB7CisgIG91dHB1dC0+Y2xlYXIoKTsKKyAgUGFyc2VTdHJpbmdBcHBlbmQodGV4dCwgb3V0cHV0KTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGlvCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfSU9fVE9LRU5JWkVSX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby90b2tlbml6ZXJfdW5pdHRlc3QuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3Rva2VuaXplcl91bml0dGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMGQ1MGEyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby90b2tlbml6ZXJfdW5pdHRlc3QuY2MKQEAgLTAsMCArMSwxMDAyIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxsaW1pdHMuaD4KKyNpbmNsdWRlIDxtYXRoLmg+CisKKyNpbmNsdWRlIDx2ZWN0b3I+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vdG9rZW5pemVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbC5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9sb2dnaW5nLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3Vic3RpdHV0ZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2dvb2dsZXRlc3QuaD4KKyNpbmNsdWRlIDxndGVzdC9ndGVzdC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW8geworbmFtZXNwYWNlIHsKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorLy8gRGF0YS1Ecml2ZW4gVGVzdCBJbmZyYXN0cnVjdHVyZQorCisvLyBUT0RPKGtlbnRvbik6ICBUaGlzIGlzIGNvcGllZCBmcm9tIGNvZGVkX3N0cmVhbV91bml0dGVzdC4gIFRoaXMgaXMKKy8vICAgdGVtcG9yYXJ5IHVudGlsIHRoZXNlIGZldGF1cmVzIGFyZSBpbnRlZ3JhdGVkIGludG8gZ1Rlc3QgaXRzZWxmLgorCisvLyBURVNUXzFEIGFuZCBURVNUXzJEIGFyZSBtYWNyb3MgSSdkIGV2ZW50dWFsbHkgbGlrZSB0byBzZWUgYWRkZWQgdG8KKy8vIGdUZXN0LiAgVGhlc2UgbWFjcm9zIGNhbiBiZSB1c2VkIHRvIGRlY2xhcmUgdGVzdHMgd2hpY2ggc2hvdWxkIGJlCisvLyBydW4gbXVsdGlwbGUgdGltZXMsIG9uY2UgZm9yIGVhY2ggaXRlbSBpbiBzb21lIGlucHV0IGFycmF5LiAgVEVTVF8xRAorLy8gdGVzdHMgYWxsIGNhc2VzIGluIGEgc2luZ2xlIGlucHV0IGFycmF5LiAgVEVTVF8yRCB0ZXN0cyBhbGwKKy8vIGNvbWJpbmF0aW9ucyBvZiBjYXNlcyBmcm9tIHR3byBhcnJheXMuICBUaGUgYXJyYXlzIG11c3QgYmUgc3RhdGljYWxseQorLy8gZGVmaW5lZCBzdWNoIHRoYXQgdGhlIEdPT0dMRV9BUlJBWVNJWkUoKSBtYWNybyB3b3JrcyBvbiB0aGVtLiAgRXhhbXBsZToKKy8vCisvLyBpbnQga0Nhc2VzW10gPSB7MSwgMiwgMywgNH0KKy8vIFRFU1RfMUQoTXlGaXh0dXJlLCBNeVRlc3QsIGtDYXNlcykgeworLy8gICBFWFBFQ1RfR1Qoa0Nhc2VzX2Nhc2UsIDApOworLy8gfQorLy8KKy8vIFRoaXMgdGVzdCBpdGVyYXRlcyB0aHJvdWdoIHRoZSBudW1iZXJzIDEsIDIsIDMsIGFuZCA0IGFuZCB0ZXN0cyB0aGF0CisvLyB0aGV5IGFyZSBhbGwgZ3JhdGVyIHRoYW4gemVyby4gIEluIGNhc2Ugb2YgZmFpbHVyZSwgdGhlIGV4YWN0IGNhc2UKKy8vIHdoaWNoIGZhaWxlZCB3aWxsIGJlIHByaW50ZWQuICBUaGUgY2FzZSB0eXBlIG11c3QgYmUgcHJpbnRhYmxlIHVzaW5nCisvLyBvc3RyZWFtOjpvcGVyYXRvcjw8LgorCisjZGVmaW5lIFRFU1RfMUQoRklYVFVSRSwgTkFNRSwgQ0FTRVMpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGNsYXNzIEZJWFRVUkUjI18jI05BTUUjI19ERCA6IHB1YmxpYyBGSVhUVVJFIHsgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICBwcm90ZWN0ZWQ6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgdGVtcGxhdGUgPHR5cGVuYW1lIENhc2VUeXBlPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgdm9pZCBEb1NpbmdsZUNhc2UoY29uc3QgQ2FzZVR5cGUmIENBU0VTIyNfY2FzZSk7ICAgICAgICAgICAgICAgICAgICAgICBcCisgIH07ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIFRFU1RfRihGSVhUVVJFIyNfIyNOQU1FIyNfREQsIE5BTUUpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBHT09HTEVfQVJSQVlTSVpFKENBU0VTKTsgaSsrKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgU0NPUEVEX1RSQUNFKHRlc3Rpbmc6Ok1lc3NhZ2UoKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICA8PCAjQ0FTRVMgIiBjYXNlICMiIDw8IGkgPDwgIjogIiA8PCBDQVNFU1tpXSk7ICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgRG9TaW5nbGVDYXNlKENBU0VTW2ldKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgQ2FzZVR5cGU+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB2b2lkIEZJWFRVUkUjI18jI05BTUUjI19ERDo6RG9TaW5nbGVDYXNlKGNvbnN0IENhc2VUeXBlJiBDQVNFUyMjX2Nhc2UpCisKKyNkZWZpbmUgVEVTVF8yRChGSVhUVVJFLCBOQU1FLCBDQVNFUzEsIENBU0VTMikgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgY2xhc3MgRklYVFVSRSMjXyMjTkFNRSMjX0REIDogcHVibGljIEZJWFRVUkUgeyAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgIHByb3RlY3RlZDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgQ2FzZVR5cGUxLCB0eXBlbmFtZSBDYXNlVHlwZTI+ICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICB2b2lkIERvU2luZ2xlQ2FzZShjb25zdCBDYXNlVHlwZTEmIENBU0VTMSMjX2Nhc2UsICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICBjb25zdCBDYXNlVHlwZTImIENBU0VTMiMjX2Nhc2UpOyAgICAgICAgICAgICAgICAgICAgIFwKKyAgfTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgVEVTVF9GKEZJWFRVUkUjI18jI05BTUUjI19ERCwgTkFNRSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IEdPT0dMRV9BUlJBWVNJWkUoQ0FTRVMxKTsgaSsrKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICBmb3IgKGludCBqID0gMDsgaiA8IEdPT0dMRV9BUlJBWVNJWkUoQ0FTRVMyKTsgaisrKSB7ICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBTQ09QRURfVFJBQ0UodGVzdGluZzo6TWVzc2FnZSgpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgIDw8ICNDQVNFUzEgIiBjYXNlICMiIDw8IGkgPDwgIjogIiA8PCBDQVNFUzFbaV0gPDwgIiwgIiAgICAgICAgICAgXAorICAgICAgICAgIDw8ICNDQVNFUzIgIiBjYXNlICMiIDw8IGogPDwgIjogIiA8PCBDQVNFUzJbal0pOyAgICAgICAgICAgICAgICAgXAorICAgICAgICBEb1NpbmdsZUNhc2UoQ0FTRVMxW2ldLCBDQVNFUzJbal0pOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgQ2FzZVR5cGUxLCB0eXBlbmFtZSBDYXNlVHlwZTI+ICAgICAgICAgICAgICAgICAgICAgICAgXAorICB2b2lkIEZJWFRVUkUjI18jI05BTUUjI19ERDo6RG9TaW5nbGVDYXNlKGNvbnN0IENhc2VUeXBlMSYgQ0FTRVMxIyNfY2FzZSwgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IENhc2VUeXBlMiYgQ0FTRVMyIyNfY2FzZSkKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBBbiBpbnB1dCBzdHJlYW0gdGhhdCBpcyBiYXNpY2FsbHkgbGlrZSBhbiBBcnJheUlucHV0U3RyZWFtIGJ1dCBzb21ldGltZXMKKy8vIHJldHVybnMgZW1wdHkgYnVmZmVycywganVzdCB0byB0aHJvdyB1cyBvZmYuCitjbGFzcyBUZXN0SW5wdXRTdHJlYW0gOiBwdWJsaWMgWmVyb0NvcHlJbnB1dFN0cmVhbSB7CisgcHVibGljOgorICBUZXN0SW5wdXRTdHJlYW0oY29uc3Qgdm9pZCogZGF0YSwgaW50IHNpemUsIGludCBibG9ja19zaXplKQorICAgIDogYXJyYXlfc3RyZWFtXyhkYXRhLCBzaXplLCBibG9ja19zaXplKSwgY291bnRlcl8oMCkge30KKyAgflRlc3RJbnB1dFN0cmVhbSgpIHt9CisKKyAgLy8gaW1wbGVtZW50cyBaZXJvQ29weUlucHV0U3RyZWFtIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgYm9vbCBOZXh0KGNvbnN0IHZvaWQqKiBkYXRhLCBpbnQqIHNpemUpIHsKKyAgICAvLyBXZSdsbCByZXR1cm4gZW1wdHkgYnVmZmVycyBzdGFydGluZyB3aXRoIHRoZSBmaXJzdCBidWZmZXIsIGFuZCBldmVyeQorICAgIC8vIDMgYW5kIDUgYnVmZmVycyBhZnRlciB0aGF0LgorICAgIGlmIChjb3VudGVyXyAlIDMgPT0gMCB8fCBjb3VudGVyXyAlIDUgPT0gMCkgeworICAgICAgKmRhdGEgPSBOVUxMOworICAgICAgKnNpemUgPSAwOworICAgICAgKytjb3VudGVyXzsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0gZWxzZSB7CisgICAgICArK2NvdW50ZXJfOworICAgICAgcmV0dXJuIGFycmF5X3N0cmVhbV8uTmV4dChkYXRhLCBzaXplKTsKKyAgICB9CisgIH0KKworICB2b2lkIEJhY2tVcChpbnQgY291bnQpICB7IHJldHVybiBhcnJheV9zdHJlYW1fLkJhY2tVcChjb3VudCk7IH0KKyAgYm9vbCBTa2lwKGludCBjb3VudCkgICAgeyByZXR1cm4gYXJyYXlfc3RyZWFtXy5Ta2lwKGNvdW50KTsgICB9CisgIGludDY0IEJ5dGVDb3VudCgpIGNvbnN0IHsgcmV0dXJuIGFycmF5X3N0cmVhbV8uQnl0ZUNvdW50KCk7ICAgfQorCisgcHJpdmF0ZToKKyAgQXJyYXlJbnB1dFN0cmVhbSBhcnJheV9zdHJlYW1fOworICBpbnQgY291bnRlcl87Cit9OworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIEFuIGVycm9yIGNvbGxlY3RvciB3aGljaCBzaW1wbHkgY29uY2F0ZW5hdGVzIGFsbCBpdHMgZXJyb3JzIGludG8gYSBiaWcKKy8vIGJsb2NrIG9mIHRleHQgd2hpY2ggY2FuIGJlIGNoZWNrZWQuCitjbGFzcyBUZXN0RXJyb3JDb2xsZWN0b3IgOiBwdWJsaWMgRXJyb3JDb2xsZWN0b3IgeworIHB1YmxpYzoKKyAgVGVzdEVycm9yQ29sbGVjdG9yKCkge30KKyAgflRlc3RFcnJvckNvbGxlY3RvcigpIHt9CisKKyAgc3RyaW5nIHRleHRfOworCisgIC8vIGltcGxlbWVudHMgRXJyb3JDb2xsZWN0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIHZvaWQgQWRkRXJyb3IoaW50IGxpbmUsIGludCBjb2x1bW4sIGNvbnN0IHN0cmluZyYgbWVzc2FnZSkgeworICAgIHN0cmluZ3M6OlN1YnN0aXR1dGVBbmRBcHBlbmQoJnRleHRfLCAiJDA6JDE6ICQyXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZSwgY29sdW1uLCBtZXNzYWdlKTsKKyAgfQorfTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBXZSB0ZXN0IGVhY2ggb3BlcmF0aW9uIG92ZXIgYSB2YXJpZXR5IG9mIGJsb2NrIHNpemVzIHRvIGluc3VyZSB0aGF0CisvLyB3ZSB0ZXN0IGNhc2VzIHdoZXJlIHJlYWRzIGNyb3NzIGJ1ZmZlciBib3VuZGFyaWVzIGFzIHdlbGwgYXMgY2FzZXMKKy8vIHdoZXJlIHRoZXkgZG9uJ3QuICBUaGlzIGlzIHNvcnQgb2YgYSBicnV0ZS1mb3JjZSBhcHByb2FjaCB0byB0aGlzLAorLy8gYnV0IGl0J3MgZWFzeSB0byB3cml0ZSBhbmQgZWFzeSB0byB1bmRlcnN0YW5kLgorY29uc3QgaW50IGtCbG9ja1NpemVzW10gPSB7MSwgMiwgMywgNSwgNywgMTMsIDMyLCAxMDI0fTsKKworY2xhc3MgVG9rZW5pemVyVGVzdCA6IHB1YmxpYyB0ZXN0aW5nOjpUZXN0IHsKKyBwcm90ZWN0ZWQ6CisgIC8vIEZvciBlYXN5IHRlc3RpbmcuCisgIHVpbnQ2NCBQYXJzZUludGVnZXIoY29uc3Qgc3RyaW5nJiB0ZXh0KSB7CisgICAgdWludDY0IHJlc3VsdDsKKyAgICBFWFBFQ1RfVFJVRShUb2tlbml6ZXI6OlBhcnNlSW50ZWdlcih0ZXh0LCBrdWludDY0bWF4LCAmcmVzdWx0KSk7CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorfTsKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisvLyBUaGVzZSB0ZXN0cyBjYXVzZXMgZ2NjIDMuMy41IChhbmQgZWFybGllcj8pIHRvIGdpdmUgdGhlIGNyeXB0aWMgZXJyb3I6CisvLyAgICJzb3JyeSwgdW5pbXBsZW1lbnRlZDogYG1ldGhvZF9jYWxsX2V4cHInIG5vdCBzdXBwb3J0ZWQgYnkgZHVtcF9leHByIgorI2lmICFkZWZpbmVkKF9fR05VQ19fKSB8fCBfX0dOVUNfXyA+IDMgfHwgKF9fR05VQ19fID09IDMgJiYgX19HTlVDX01JTk9SX18gPiAzKQorCisvLyBJbiBlYWNoIHRlc3QgY2FzZSwgdGhlIGVudGlyZSBpbnB1dCB0ZXh0IHNob3VsZCBwYXJzZSBhcyBhIHNpbmdsZSB0b2tlbgorLy8gb2YgdGhlIGdpdmVuIHR5cGUuCitzdHJ1Y3QgU2ltcGxlVG9rZW5DYXNlIHsKKyAgc3RyaW5nIGlucHV0OworICBUb2tlbml6ZXI6OlRva2VuVHlwZSB0eXBlOworfTsKKworaW5saW5lIG9zdHJlYW0mIG9wZXJhdG9yPDwob3N0cmVhbSYgb3V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgU2ltcGxlVG9rZW5DYXNlJiB0ZXN0X2Nhc2UpIHsKKyAgcmV0dXJuIG91dCA8PCBDRXNjYXBlKHRlc3RfY2FzZS5pbnB1dCk7Cit9CisKK1NpbXBsZVRva2VuQ2FzZSBrU2ltcGxlVG9rZW5DYXNlc1tdID0geworICAvLyBUZXN0IGlkZW50aWZpZXJzLgorICB7ICJoZWxsbyIsICAgICAgIFRva2VuaXplcjo6VFlQRV9JREVOVElGSUVSIH0sCisKKyAgLy8gVGVzdCBpbnRlZ2Vycy4KKyAgeyAiMTIzIiwgICAgICAgICBUb2tlbml6ZXI6OlRZUEVfSU5URUdFUiB9LAorICB7ICIweGFiNiIsICAgICAgIFRva2VuaXplcjo6VFlQRV9JTlRFR0VSIH0sCisgIHsgIjBYQUI2IiwgICAgICAgVG9rZW5pemVyOjpUWVBFX0lOVEVHRVIgfSwKKyAgeyAiMFgxMjM0NTY3IiwgICBUb2tlbml6ZXI6OlRZUEVfSU5URUdFUiB9LAorICB7ICIweDg5YWJjZGVmIiwgIFRva2VuaXplcjo6VFlQRV9JTlRFR0VSIH0sCisgIHsgIjB4ODlBQkNERUYiLCAgVG9rZW5pemVyOjpUWVBFX0lOVEVHRVIgfSwKKyAgeyAiMDEyMzQ1NjciLCAgICBUb2tlbml6ZXI6OlRZUEVfSU5URUdFUiB9LAorCisgIC8vIFRlc3QgZmxvYXRzLgorICB7ICIxMjMuNDUiLCAgICAgIFRva2VuaXplcjo6VFlQRV9GTE9BVCB9LAorICB7ICIxLiIsICAgICAgICAgIFRva2VuaXplcjo6VFlQRV9GTE9BVCB9LAorICB7ICIxZTMiLCAgICAgICAgIFRva2VuaXplcjo6VFlQRV9GTE9BVCB9LAorICB7ICIxRTMiLCAgICAgICAgIFRva2VuaXplcjo6VFlQRV9GTE9BVCB9LAorICB7ICIxZS0zIiwgICAgICAgIFRva2VuaXplcjo6VFlQRV9GTE9BVCB9LAorICB7ICIxZSszIiwgICAgICAgIFRva2VuaXplcjo6VFlQRV9GTE9BVCB9LAorICB7ICIxLmUzIiwgICAgICAgIFRva2VuaXplcjo6VFlQRV9GTE9BVCB9LAorICB7ICIxLjJlMyIsICAgICAgIFRva2VuaXplcjo6VFlQRV9GTE9BVCB9LAorICB7ICIuMSIsICAgICAgICAgIFRva2VuaXplcjo6VFlQRV9GTE9BVCB9LAorICB7ICIuMWUzIiwgICAgICAgIFRva2VuaXplcjo6VFlQRV9GTE9BVCB9LAorICB7ICIuMWUtMyIsICAgICAgIFRva2VuaXplcjo6VFlQRV9GTE9BVCB9LAorICB7ICIuMWUrMyIsICAgICAgIFRva2VuaXplcjo6VFlQRV9GTE9BVCB9LAorCisgIC8vIFRlc3Qgc3RyaW5ncy4KKyAgeyAiJ2hlbGxvJyIsICAgICBUb2tlbml6ZXI6OlRZUEVfU1RSSU5HIH0sCisgIHsgIlwiZm9vXCIiLCAgICAgVG9rZW5pemVyOjpUWVBFX1NUUklORyB9LAorICB7ICInYVwiYiciLCAgICAgIFRva2VuaXplcjo6VFlQRV9TVFJJTkcgfSwKKyAgeyAiXCJhJ2JcIiIsICAgICBUb2tlbml6ZXI6OlRZUEVfU1RSSU5HIH0sCisgIHsgIidhXFwnYiciLCAgICAgVG9rZW5pemVyOjpUWVBFX1NUUklORyB9LAorICB7ICJcImFcXFwiYlwiIiwgIFRva2VuaXplcjo6VFlQRV9TVFJJTkcgfSwKKyAgeyAiJ1xceGYnIiwgICAgICBUb2tlbml6ZXI6OlRZUEVfU1RSSU5HIH0sCisgIHsgIidcXDAnIiwgICAgICAgVG9rZW5pemVyOjpUWVBFX1NUUklORyB9LAorCisgIC8vIFRlc3Qgc3ltYm9scy4KKyAgeyAiKyIsICAgICAgICAgICBUb2tlbml6ZXI6OlRZUEVfU1lNQk9MIH0sCisgIHsgIi4iLCAgICAgICAgICAgVG9rZW5pemVyOjpUWVBFX1NZTUJPTCB9LAorfTsKKworVEVTVF8yRChUb2tlbml6ZXJUZXN0LCBTaW1wbGVUb2tlbnMsIGtTaW1wbGVUb2tlbkNhc2VzLCBrQmxvY2tTaXplcykgeworICAvLyBTZXQgdXAgdGhlIHRva2VuaXplci4KKyAgVGVzdElucHV0U3RyZWFtIGlucHV0KGtTaW1wbGVUb2tlbkNhc2VzX2Nhc2UuaW5wdXQuZGF0YSgpLAorICAgICAgICAgICAgICAgICAgICAgICAga1NpbXBsZVRva2VuQ2FzZXNfY2FzZS5pbnB1dC5zaXplKCksCisgICAgICAgICAgICAgICAgICAgICAgICBrQmxvY2tTaXplc19jYXNlKTsKKyAgVGVzdEVycm9yQ29sbGVjdG9yIGVycm9yX2NvbGxlY3RvcjsKKyAgVG9rZW5pemVyIHRva2VuaXplcigmaW5wdXQsICZlcnJvcl9jb2xsZWN0b3IpOworCisgIC8vIEJlZm9yZSBOZXh0KCkgaXMgY2FsbGVkLCB0aGUgaW5pdGlhbCB0b2tlbiBzaG91bGQgYWx3YXlzIGJlIFRZUEVfU1RBUlQuCisgIEVYUEVDVF9FUShUb2tlbml6ZXI6OlRZUEVfU1RBUlQsIHRva2VuaXplci5jdXJyZW50KCkudHlwZSk7CisgIEVYUEVDVF9FUSgiIiwgdG9rZW5pemVyLmN1cnJlbnQoKS50ZXh0KTsKKyAgRVhQRUNUX0VRKDAsIHRva2VuaXplci5jdXJyZW50KCkubGluZSk7CisgIEVYUEVDVF9FUSgwLCB0b2tlbml6ZXIuY3VycmVudCgpLmNvbHVtbik7CisgIEVYUEVDVF9FUSgwLCB0b2tlbml6ZXIuY3VycmVudCgpLmVuZF9jb2x1bW4pOworCisgIC8vIFBhcnNlIHRoZSB0b2tlbi4KKyAgQVNTRVJUX1RSVUUodG9rZW5pemVyLk5leHQoKSk7CisKKyAgLy8gQ2hlY2sgdGhhdCBpdCBoYXMgdGhlIHJpZ2h0IHR5cGUuCisgIEVYUEVDVF9FUShrU2ltcGxlVG9rZW5DYXNlc19jYXNlLnR5cGUsIHRva2VuaXplci5jdXJyZW50KCkudHlwZSk7CisgIC8vIENoZWNrIHRoYXQgaXQgY29udGFpbnMgdGhlIGNvbXBsZXRlIGlucHV0IHRleHQuCisgIEVYUEVDVF9FUShrU2ltcGxlVG9rZW5DYXNlc19jYXNlLmlucHV0LCB0b2tlbml6ZXIuY3VycmVudCgpLnRleHQpOworICAvLyBDaGVjayB0aGF0IGl0IGlzIGxvY2F0ZWQgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgaW5wdXQKKyAgRVhQRUNUX0VRKDAsIHRva2VuaXplci5jdXJyZW50KCkubGluZSk7CisgIEVYUEVDVF9FUSgwLCB0b2tlbml6ZXIuY3VycmVudCgpLmNvbHVtbik7CisgIEVYUEVDVF9FUShrU2ltcGxlVG9rZW5DYXNlc19jYXNlLmlucHV0LnNpemUoKSwKKyAgICAgICAgICAgIHRva2VuaXplci5jdXJyZW50KCkuZW5kX2NvbHVtbik7CisKKyAgLy8gVGhlcmUgc2hvdWxkIGJlIG5vIG1vcmUgaW5wdXQuCisgIEVYUEVDVF9GQUxTRSh0b2tlbml6ZXIuTmV4dCgpKTsKKworICAvLyBBZnRlciBOZXh0KCkgcmV0dXJucyBmYWxzZSwgdGhlIHRva2VuIHNob3VsZCBoYXZlIHR5cGUgVFlQRV9FTkQuCisgIEVYUEVDVF9FUShUb2tlbml6ZXI6OlRZUEVfRU5ELCB0b2tlbml6ZXIuY3VycmVudCgpLnR5cGUpOworICBFWFBFQ1RfRVEoIiIsIHRva2VuaXplci5jdXJyZW50KCkudGV4dCk7CisgIEVYUEVDVF9FUSgwLCB0b2tlbml6ZXIuY3VycmVudCgpLmxpbmUpOworICBFWFBFQ1RfRVEoa1NpbXBsZVRva2VuQ2FzZXNfY2FzZS5pbnB1dC5zaXplKCksIHRva2VuaXplci5jdXJyZW50KCkuY29sdW1uKTsKKyAgRVhQRUNUX0VRKGtTaW1wbGVUb2tlbkNhc2VzX2Nhc2UuaW5wdXQuc2l6ZSgpLAorICAgICAgICAgICAgdG9rZW5pemVyLmN1cnJlbnQoKS5lbmRfY29sdW1uKTsKKworICAvLyBUaGVyZSBzaG91bGQgYmUgbm8gZXJyb3JzLgorICBFWFBFQ1RfVFJVRShlcnJvcl9jb2xsZWN0b3IudGV4dF8uZW1wdHkoKSk7Cit9CisKK1RFU1RfMUQoVG9rZW5pemVyVGVzdCwgRmxvYXRTdWZmaXgsIGtCbG9ja1NpemVzKSB7CisgIC8vIFRlc3QgdGhlICJhbGxvd19mX2FmdGVyX2Zsb2F0IiBvcHRpb24uCisKKyAgLy8gU2V0IHVwIHRoZSB0b2tlbml6ZXIuCisgIGNvbnN0IGNoYXIqIHRleHQgPSAiMWYgMi41ZiA2ZTNmIDdGIjsKKyAgVGVzdElucHV0U3RyZWFtIGlucHV0KHRleHQsIHN0cmxlbih0ZXh0KSwga0Jsb2NrU2l6ZXNfY2FzZSk7CisgIFRlc3RFcnJvckNvbGxlY3RvciBlcnJvcl9jb2xsZWN0b3I7CisgIFRva2VuaXplciB0b2tlbml6ZXIoJmlucHV0LCAmZXJyb3JfY29sbGVjdG9yKTsKKyAgdG9rZW5pemVyLnNldF9hbGxvd19mX2FmdGVyX2Zsb2F0KHRydWUpOworCisgIC8vIEFkdmFuY2UgdGhyb3VnaCB0b2tlbnMgYW5kIGNoZWNrIHRoYXQgdGhleSBhcmUgcGFyc2VkIGFzIGV4cGVjdGVkLgorICBBU1NFUlRfVFJVRSh0b2tlbml6ZXIuTmV4dCgpKTsKKyAgRVhQRUNUX0VRKHRva2VuaXplci5jdXJyZW50KCkudGV4dCwgIjFmIik7CisgIEVYUEVDVF9FUSh0b2tlbml6ZXIuY3VycmVudCgpLnR5cGUsIFRva2VuaXplcjo6VFlQRV9GTE9BVCk7CisgIEFTU0VSVF9UUlVFKHRva2VuaXplci5OZXh0KCkpOworICBFWFBFQ1RfRVEodG9rZW5pemVyLmN1cnJlbnQoKS50ZXh0LCAiMi41ZiIpOworICBFWFBFQ1RfRVEodG9rZW5pemVyLmN1cnJlbnQoKS50eXBlLCBUb2tlbml6ZXI6OlRZUEVfRkxPQVQpOworICBBU1NFUlRfVFJVRSh0b2tlbml6ZXIuTmV4dCgpKTsKKyAgRVhQRUNUX0VRKHRva2VuaXplci5jdXJyZW50KCkudGV4dCwgIjZlM2YiKTsKKyAgRVhQRUNUX0VRKHRva2VuaXplci5jdXJyZW50KCkudHlwZSwgVG9rZW5pemVyOjpUWVBFX0ZMT0FUKTsKKyAgQVNTRVJUX1RSVUUodG9rZW5pemVyLk5leHQoKSk7CisgIEVYUEVDVF9FUSh0b2tlbml6ZXIuY3VycmVudCgpLnRleHQsICI3RiIpOworICBFWFBFQ1RfRVEodG9rZW5pemVyLmN1cnJlbnQoKS50eXBlLCBUb2tlbml6ZXI6OlRZUEVfRkxPQVQpOworCisgIC8vIFRoZXJlIHNob3VsZCBiZSBubyBtb3JlIGlucHV0LgorICBFWFBFQ1RfRkFMU0UodG9rZW5pemVyLk5leHQoKSk7CisgIC8vIFRoZXJlIHNob3VsZCBiZSBubyBlcnJvcnMuCisgIEVYUEVDVF9UUlVFKGVycm9yX2NvbGxlY3Rvci50ZXh0Xy5lbXB0eSgpKTsKK30KKworI2VuZGlmCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gSW4gZWFjaCBjYXNlLCB0aGUgaW5wdXQgaXMgcGFyc2VkIHRvIHByb2R1Y2UgYSBsaXN0IG9mIHRva2Vucy4gIFRoZQorLy8gbGFzdCB0b2tlbiBpbiAib3V0cHV0IiBtdXN0IGhhdmUgdHlwZSBUWVBFX0VORC4KK3N0cnVjdCBNdWx0aVRva2VuQ2FzZSB7CisgIHN0cmluZyBpbnB1dDsKKyAgVG9rZW5pemVyOjpUb2tlbiBvdXRwdXRbMTBdOyAgLy8gVGhlIGNvbXBpbGVyIHdhbnRzIGEgY29uc3RhbnQgYXJyYXkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2l6ZSBmb3IgaW5pdGlhbGl6YXRpb24gdG8gd29yay4gIFRoZXJlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlzIG5vIHJlYXNvbiB0aGlzIGNhbid0IGJlIGluY3JlYXNlZCBpZgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBuZWVkZWQuCit9OworCitpbmxpbmUgb3N0cmVhbSYgb3BlcmF0b3I8PChvc3RyZWFtJiBvdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNdWx0aVRva2VuQ2FzZSYgdGVzdF9jYXNlKSB7CisgIHJldHVybiBvdXQgPDwgQ0VzY2FwZSh0ZXN0X2Nhc2UuaW5wdXQpOworfQorCitNdWx0aVRva2VuQ2FzZSBrTXVsdGlUb2tlbkNhc2VzW10gPSB7CisgIC8vIFRlc3QgZW1wdHkgaW5wdXQuCisgIHsgIiIsIHsKKyAgICB7IFRva2VuaXplcjo6VFlQRV9FTkQgICAgICAgLCAiIiAgICAgLCAwLCAgMCB9LAorICB9fSwKKworICAvLyBUZXN0IGFsbCB0b2tlbiB0eXBlcyBhdCB0aGUgc2FtZSB0aW1lLgorICB7ICJmb28gMSAxLjIgKyAnYmFyJyIsIHsKKyAgICB7IFRva2VuaXplcjo6VFlQRV9JREVOVElGSUVSLCAiZm9vIiAgLCAwLCAgMCwgIDMgfSwKKyAgICB7IFRva2VuaXplcjo6VFlQRV9JTlRFR0VSICAgLCAiMSIgICAgLCAwLCAgNCwgIDUgfSwKKyAgICB7IFRva2VuaXplcjo6VFlQRV9GTE9BVCAgICAgLCAiMS4yIiAgLCAwLCAgNiwgIDkgfSwKKyAgICB7IFRva2VuaXplcjo6VFlQRV9TWU1CT0wgICAgLCAiKyIgICAgLCAwLCAxMCwgMTEgfSwKKyAgICB7IFRva2VuaXplcjo6VFlQRV9TVFJJTkcgICAgLCAiJ2JhciciLCAwLCAxMiwgMTcgfSwKKyAgICB7IFRva2VuaXplcjo6VFlQRV9FTkQgICAgICAgLCAiIiAgICAgLCAwLCAxNywgMTcgfSwKKyAgfX0sCisKKyAgLy8gVGVzdCB0aGF0IGNvbnNlY3V0aXZlIHN5bWJvbHMgYXJlIHBhcnNlZCBhcyBzZXBhcmF0ZSB0b2tlbnMuCisgIHsgIiFAKyUiLCB7CisgICAgeyBUb2tlbml6ZXI6OlRZUEVfU1lNQk9MICAgICwgIiEiICAgICwgMCwgMCwgMSB9LAorICAgIHsgVG9rZW5pemVyOjpUWVBFX1NZTUJPTCAgICAsICJAIiAgICAsIDAsIDEsIDIgfSwKKyAgICB7IFRva2VuaXplcjo6VFlQRV9TWU1CT0wgICAgLCAiKyIgICAgLCAwLCAyLCAzIH0sCisgICAgeyBUb2tlbml6ZXI6OlRZUEVfU1lNQk9MICAgICwgIiUiICAgICwgMCwgMywgNCB9LAorICAgIHsgVG9rZW5pemVyOjpUWVBFX0VORCAgICAgICAsICIiICAgICAsIDAsIDQsIDQgfSwKKyAgfX0sCisKKyAgLy8gVGVzdCB0aGF0IG5ld2xpbmVzIGFmZmVjdCBsaW5lIG51bWJlcnMgY29ycmVjdGx5LgorICB7ICJmb28gYmFyXG5yYWIgb29mIiwgeworICAgIHsgVG9rZW5pemVyOjpUWVBFX0lERU5USUZJRVIsICJmb28iLCAwLCAgMCwgMyB9LAorICAgIHsgVG9rZW5pemVyOjpUWVBFX0lERU5USUZJRVIsICJiYXIiLCAwLCAgNCwgNyB9LAorICAgIHsgVG9rZW5pemVyOjpUWVBFX0lERU5USUZJRVIsICJyYWIiLCAxLCAgMCwgMyB9LAorICAgIHsgVG9rZW5pemVyOjpUWVBFX0lERU5USUZJRVIsICJvb2YiLCAxLCAgNCwgNyB9LAorICAgIHsgVG9rZW5pemVyOjpUWVBFX0VORCAgICAgICAsICIiICAgLCAxLCAgNywgNyB9LAorICB9fSwKKworICAvLyBUZXN0IHRoYXQgdGFicyBhZmZlY3QgY29sdW1uIG51bWJlcnMgY29ycmVjdGx5LgorICB7ICJmb29cdGJhciAgXHRiYXoiLCB7CisgICAgeyBUb2tlbml6ZXI6OlRZUEVfSURFTlRJRklFUiwgImZvbyIsIDAsICAwLCAgMyB9LAorICAgIHsgVG9rZW5pemVyOjpUWVBFX0lERU5USUZJRVIsICJiYXIiLCAwLCAgOCwgMTEgfSwKKyAgICB7IFRva2VuaXplcjo6VFlQRV9JREVOVElGSUVSLCAiYmF6IiwgMCwgMTYsIDE5IH0sCisgICAgeyBUb2tlbml6ZXI6OlRZUEVfRU5EICAgICAgICwgIiIgICAsIDAsIDE5LCAxOSB9LAorICB9fSwKKworICAvLyBUZXN0IHRoYXQgdGFicyBpbiBzdHJpbmcgbGl0ZXJhbHMgYWZmZWN0IGNvbHVtbiBudW1iZXJzIGNvcnJlY3RseS4KKyAgeyAiXCJmb29cdGJhclwiIGJheiIsIHsKKyAgICB7IFRva2VuaXplcjo6VFlQRV9TVFJJTkcgICAgLCAiXCJmb29cdGJhclwiIiwgMCwgIDAsIDEyIH0sCisgICAgeyBUb2tlbml6ZXI6OlRZUEVfSURFTlRJRklFUiwgImJheiIgICAgICAgICAsIDAsIDEzLCAxNiB9LAorICAgIHsgVG9rZW5pemVyOjpUWVBFX0VORCAgICAgICAsICIiICAgICAgICAgICAgLCAwLCAxNiwgMTYgfSwKKyAgfX0sCisKKyAgLy8gVGVzdCB0aGF0IGxpbmUgY29tbWVudHMgYXJlIGlnbm9yZWQuCisgIHsgImZvbyAvLyBUaGlzIGlzIGEgY29tbWVudFxuIgorICAgICJiYXIgLy8gVGhpcyBpcyBhbm90aGVyIGNvbW1lbnQiLCB7CisgICAgeyBUb2tlbml6ZXI6OlRZUEVfSURFTlRJRklFUiwgImZvbyIsIDAsICAwLCAgMyB9LAorICAgIHsgVG9rZW5pemVyOjpUWVBFX0lERU5USUZJRVIsICJiYXIiLCAxLCAgMCwgIDMgfSwKKyAgICB7IFRva2VuaXplcjo6VFlQRV9FTkQgICAgICAgLCAiIiAgICwgMSwgMzAsIDMwIH0sCisgIH19LAorCisgIC8vIFRlc3QgdGhhdCBibG9jayBjb21tZW50cyBhcmUgaWdub3JlZC4KKyAgeyAiZm9vIC8qIFRoaXMgaXMgYSBibG9jayBjb21tZW50ICovIGJhciIsIHsKKyAgICB7IFRva2VuaXplcjo6VFlQRV9JREVOVElGSUVSLCAiZm9vIiwgMCwgIDAsICAzIH0sCisgICAgeyBUb2tlbml6ZXI6OlRZUEVfSURFTlRJRklFUiwgImJhciIsIDAsIDM0LCAzNyB9LAorICAgIHsgVG9rZW5pemVyOjpUWVBFX0VORCAgICAgICAsICIiICAgLCAwLCAzNywgMzcgfSwKKyAgfX0sCisKKyAgLy8gVGVzdCB0aGF0IHNoLXN0eWxlIGNvbW1lbnRzIGFyZSBub3QgaWdub3JlZCBieSBkZWZhdWx0LgorICB7ICJmb28gIyBiYXJcbiIKKyAgICAiYmF6IiwgeworICAgIHsgVG9rZW5pemVyOjpUWVBFX0lERU5USUZJRVIsICJmb28iLCAwLCAwLCAzIH0sCisgICAgeyBUb2tlbml6ZXI6OlRZUEVfU1lNQk9MICAgICwgIiMiICAsIDAsIDQsIDUgfSwKKyAgICB7IFRva2VuaXplcjo6VFlQRV9JREVOVElGSUVSLCAiYmFyIiwgMCwgNiwgOSB9LAorICAgIHsgVG9rZW5pemVyOjpUWVBFX0lERU5USUZJRVIsICJiYXoiLCAxLCAwLCAzIH0sCisgICAgeyBUb2tlbml6ZXI6OlRZUEVfRU5EICAgICAgICwgIiIgICAsIDEsIDMsIDMgfSwKKyAgfX0sCisKKyAgLy8gVGVzdCBhbGwgd2hpdGVzcGFjZSBjaGFycworICB7ICJmb29cblx0XHJcdlxmYmFyIiwgeworICAgIHsgVG9rZW5pemVyOjpUWVBFX0lERU5USUZJRVIsICJmb28iLCAwLCAgMCwgIDMgfSwKKyAgICB7IFRva2VuaXplcjo6VFlQRV9JREVOVElGSUVSLCAiYmFyIiwgMSwgMTEsIDE0IH0sCisgICAgeyBUb2tlbml6ZXI6OlRZUEVfRU5EICAgICAgICwgIiIgICAsIDEsIDE0LCAxNCB9LAorICB9fSwKK307CisKK1RFU1RfMkQoVG9rZW5pemVyVGVzdCwgTXVsdGlwbGVUb2tlbnMsIGtNdWx0aVRva2VuQ2FzZXMsIGtCbG9ja1NpemVzKSB7CisgIC8vIFNldCB1cCB0aGUgdG9rZW5pemVyLgorICBUZXN0SW5wdXRTdHJlYW0gaW5wdXQoa011bHRpVG9rZW5DYXNlc19jYXNlLmlucHV0LmRhdGEoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGtNdWx0aVRva2VuQ2FzZXNfY2FzZS5pbnB1dC5zaXplKCksCisgICAgICAgICAgICAgICAgICAgICAgICBrQmxvY2tTaXplc19jYXNlKTsKKyAgVGVzdEVycm9yQ29sbGVjdG9yIGVycm9yX2NvbGxlY3RvcjsKKyAgVG9rZW5pemVyIHRva2VuaXplcigmaW5wdXQsICZlcnJvcl9jb2xsZWN0b3IpOworCisgIC8vIEJlZm9yZSBOZXh0KCkgaXMgY2FsbGVkLCB0aGUgaW5pdGlhbCB0b2tlbiBzaG91bGQgYWx3YXlzIGJlIFRZUEVfU1RBUlQuCisgIEVYUEVDVF9FUShUb2tlbml6ZXI6OlRZUEVfU1RBUlQsIHRva2VuaXplci5jdXJyZW50KCkudHlwZSk7CisgIEVYUEVDVF9FUSgiIiwgdG9rZW5pemVyLmN1cnJlbnQoKS50ZXh0KTsKKyAgRVhQRUNUX0VRKDAsIHRva2VuaXplci5jdXJyZW50KCkubGluZSk7CisgIEVYUEVDVF9FUSgwLCB0b2tlbml6ZXIuY3VycmVudCgpLmNvbHVtbik7CisgIEVYUEVDVF9FUSgwLCB0b2tlbml6ZXIuY3VycmVudCgpLmVuZF9jb2x1bW4pOworCisgIC8vIExvb3AgdGhyb3VnaCBhbGwgZXhwZWN0ZWQgdG9rZW5zLgorICBpbnQgaSA9IDA7CisgIFRva2VuaXplcjo6VG9rZW4gdG9rZW47CisgIGRvIHsKKyAgICB0b2tlbiA9IGtNdWx0aVRva2VuQ2FzZXNfY2FzZS5vdXRwdXRbaSsrXTsKKworICAgIFNDT1BFRF9UUkFDRSh0ZXN0aW5nOjpNZXNzYWdlKCkgPDwgIlRva2VuICMiIDw8IGkgPDwgIjogIiA8PCB0b2tlbi50ZXh0KTsKKworICAgIFRva2VuaXplcjo6VG9rZW4gcHJldmlvdXMgPSB0b2tlbml6ZXIuY3VycmVudCgpOworCisgICAgLy8gTmV4dCgpIHNob3VsZCBvbmx5IHJldHVybiBmYWxzZSB3aGVuIGl0IGhpdHMgdGhlIGVuZCB0b2tlbi4KKyAgICBpZiAodG9rZW4udHlwZSAhPSBUb2tlbml6ZXI6OlRZUEVfRU5EKSB7CisgICAgICBBU1NFUlRfVFJVRSh0b2tlbml6ZXIuTmV4dCgpKTsKKyAgICB9IGVsc2UgeworICAgICAgQVNTRVJUX0ZBTFNFKHRva2VuaXplci5OZXh0KCkpOworICAgIH0KKworICAgIC8vIENoZWNrIHRoYXQgdGhlIHByZXZpb3VzIHRva2VuIGlzIHNldCBjb3JyZWN0bHkuCisgICAgRVhQRUNUX0VRKHByZXZpb3VzLnR5cGUsIHRva2VuaXplci5wcmV2aW91cygpLnR5cGUpOworICAgIEVYUEVDVF9FUShwcmV2aW91cy50ZXh0LCB0b2tlbml6ZXIucHJldmlvdXMoKS50ZXh0KTsKKyAgICBFWFBFQ1RfRVEocHJldmlvdXMubGluZSwgdG9rZW5pemVyLnByZXZpb3VzKCkubGluZSk7CisgICAgRVhQRUNUX0VRKHByZXZpb3VzLmNvbHVtbiwgdG9rZW5pemVyLnByZXZpb3VzKCkuY29sdW1uKTsKKyAgICBFWFBFQ1RfRVEocHJldmlvdXMuZW5kX2NvbHVtbiwgdG9rZW5pemVyLnByZXZpb3VzKCkuZW5kX2NvbHVtbik7CisKKyAgICAvLyBDaGVjayB0aGF0IHRoZSB0b2tlbiBtYXRjaGVzIHRoZSBleHBlY3RlZCBvbmUuCisgICAgRVhQRUNUX0VRKHRva2VuLnR5cGUsIHRva2VuaXplci5jdXJyZW50KCkudHlwZSk7CisgICAgRVhQRUNUX0VRKHRva2VuLnRleHQsIHRva2VuaXplci5jdXJyZW50KCkudGV4dCk7CisgICAgRVhQRUNUX0VRKHRva2VuLmxpbmUsIHRva2VuaXplci5jdXJyZW50KCkubGluZSk7CisgICAgRVhQRUNUX0VRKHRva2VuLmNvbHVtbiwgdG9rZW5pemVyLmN1cnJlbnQoKS5jb2x1bW4pOworICAgIEVYUEVDVF9FUSh0b2tlbi5lbmRfY29sdW1uLCB0b2tlbml6ZXIuY3VycmVudCgpLmVuZF9jb2x1bW4pOworCisgIH0gd2hpbGUgKHRva2VuLnR5cGUgIT0gVG9rZW5pemVyOjpUWVBFX0VORCk7CisKKyAgLy8gVGhlcmUgc2hvdWxkIGJlIG5vIGVycm9ycy4KKyAgRVhQRUNUX1RSVUUoZXJyb3JfY29sbGVjdG9yLnRleHRfLmVtcHR5KCkpOworfQorCisvLyBUaGlzIHRlc3QgY2F1c2VzIGdjYyAzLjMuNSAoYW5kIGVhcmxpZXI/KSB0byBnaXZlIHRoZSBjcnlwdGljIGVycm9yOgorLy8gICAic29ycnksIHVuaW1wbGVtZW50ZWQ6IGBtZXRob2RfY2FsbF9leHByJyBub3Qgc3VwcG9ydGVkIGJ5IGR1bXBfZXhwciIKKyNpZiAhZGVmaW5lZChfX0dOVUNfXykgfHwgX19HTlVDX18gPiAzIHx8IChfX0dOVUNfXyA9PSAzICYmIF9fR05VQ19NSU5PUl9fID4gMykKKworVEVTVF8xRChUb2tlbml6ZXJUZXN0LCBTaENvbW1lbnRTdHlsZSwga0Jsb2NrU2l6ZXMpIHsKKyAgLy8gVGVzdCB0aGUgImNvbW1lbnRfc3R5bGUiIG9wdGlvbi4KKworICBjb25zdCBjaGFyKiB0ZXh0ID0gImZvbyAjIGJhclxuIgorICAgICAgICAgICAgICAgICAgICAgImJheiAvLyBxdXhcbiIKKyAgICAgICAgICAgICAgICAgICAgICJjb3JnZSAvKiBncmF1bHQgKi9cbiIKKyAgICAgICAgICAgICAgICAgICAgICJnYXJwbHkiOworICBjb25zdCBjaGFyKiBjb25zdCBrVG9rZW5zW10gPSB7ImZvbyIsICAvLyAiIyBiYXIiIGlzIGlnbm9yZWQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJiYXoiLCAiLyIsICIvIiwgInF1eCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY29yZ2UiLCAiLyIsICIqIiwgImdyYXVsdCIsICIqIiwgIi8iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImdhcnBseSJ9OworCisgIC8vIFNldCB1cCB0aGUgdG9rZW5pemVyLgorICBUZXN0SW5wdXRTdHJlYW0gaW5wdXQodGV4dCwgc3RybGVuKHRleHQpLCBrQmxvY2tTaXplc19jYXNlKTsKKyAgVGVzdEVycm9yQ29sbGVjdG9yIGVycm9yX2NvbGxlY3RvcjsKKyAgVG9rZW5pemVyIHRva2VuaXplcigmaW5wdXQsICZlcnJvcl9jb2xsZWN0b3IpOworICB0b2tlbml6ZXIuc2V0X2NvbW1lbnRfc3R5bGUoVG9rZW5pemVyOjpTSF9DT01NRU5UX1NUWUxFKTsKKworICAvLyBBZHZhbmNlIHRocm91Z2ggdG9rZW5zIGFuZCBjaGVjayB0aGF0IHRoZXkgYXJlIHBhcnNlZCBhcyBleHBlY3RlZC4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBHT09HTEVfQVJSQVlTSVpFKGtUb2tlbnMpOyBpKyspIHsKKyAgICBFWFBFQ1RfVFJVRSh0b2tlbml6ZXIuTmV4dCgpKTsKKyAgICBFWFBFQ1RfRVEodG9rZW5pemVyLmN1cnJlbnQoKS50ZXh0LCBrVG9rZW5zW2ldKTsKKyAgfQorCisgIC8vIFRoZXJlIHNob3VsZCBiZSBubyBtb3JlIGlucHV0LgorICBFWFBFQ1RfRkFMU0UodG9rZW5pemVyLk5leHQoKSk7CisgIC8vIFRoZXJlIHNob3VsZCBiZSBubyBlcnJvcnMuCisgIEVYUEVDVF9UUlVFKGVycm9yX2NvbGxlY3Rvci50ZXh0Xy5lbXB0eSgpKTsKK30KKworI2VuZGlmCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gSW4gZWFjaCBjYXNlLCB0aGUgaW5wdXQgaXMgZXhwZWN0ZWQgdG8gaGF2ZSB0d28gdG9rZW5zIG5hbWVkICJwcmV2IiBhbmQKKy8vICJuZXh0IiB3aXRoIGNvbW1lbnRzIGluIGJldHdlZW4uCitzdHJ1Y3QgRG9jQ29tbWVudENhc2UgeworICBzdHJpbmcgaW5wdXQ7CisKKyAgY29uc3QgY2hhciogcHJldl90cmFpbGluZ19jb21tZW50czsKKyAgY29uc3QgY2hhciogZGV0YWNoZWRfY29tbWVudHNbMTBdOworICBjb25zdCBjaGFyKiBuZXh0X2xlYWRpbmdfY29tbWVudHM7Cit9OworCitpbmxpbmUgb3N0cmVhbSYgb3BlcmF0b3I8PChvc3RyZWFtJiBvdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEb2NDb21tZW50Q2FzZSYgdGVzdF9jYXNlKSB7CisgIHJldHVybiBvdXQgPDwgQ0VzY2FwZSh0ZXN0X2Nhc2UuaW5wdXQpOworfQorCitEb2NDb21tZW50Q2FzZSBrRG9jQ29tbWVudENhc2VzW10gPSB7CisgIHsKKyAgICAicHJldiBuZXh0IiwKKworICAgICIiLAorICAgIHt9LAorICAgICIiCisgICAgICB9LAorCisgICAgICAgIHsKKyAgICAgICJwcmV2IC8qIGlnbm9yZWQgKi8gbmV4dCIsCisKKyAgICAgICIiLAorICAgICAge30sCisgICAgICAiIgorICAgICAgICB9LAorCisgICAgICAgICAgeworICAgICAgICAicHJldiAvLyB0cmFpbGluZyBjb21tZW50XG4iCisgICAgICAgICAgICAibmV4dCIsCisKKyAgICAgICAgICAgICIgdHJhaWxpbmcgY29tbWVudFxuIiwKKyAgICAgICAgICAgIHt9LAorICAgICAgICAgICAgIiIKKyAgICAgICAgICB9LAorCisgICAgICAgICAgICB7CisgICAgICAgICAgInByZXZcbiIKKyAgICAgICAgICAgICAgIi8vIGxlYWRpbmcgY29tbWVudFxuIgorICAgICAgICAgICAgICAiLy8gbGluZSAyXG4iCisgICAgICAgICAgICAgICJuZXh0IiwKKworICAgICAgICAgICAgICAiIiwKKyAgICAgICAgICAgICAge30sCisgICAgICAgICAgICAgICIgbGVhZGluZyBjb21tZW50XG4iCisgICAgICAgICAgICAgICIgbGluZSAyXG4iCisgICAgICAgICAgICB9LAorCisgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICJwcmV2XG4iCisgICAgICAgICAgICAgICAgIi8vIHRyYWlsaW5nIGNvbW1lbnRcbiIKKyAgICAgICAgICAgICAgICAiLy8gbGluZSAyXG4iCisgICAgICAgICAgICAgICAgIlxuIgorICAgICAgICAgICAgICAgICJuZXh0IiwKKworICAgICAgICAgICAgICAgICIgdHJhaWxpbmcgY29tbWVudFxuIgorICAgICAgICAgICAgICAgICIgbGluZSAyXG4iLAorICAgICAgICAgICAgICAgIHt9LAorICAgICAgICAgICAgICAgICIiCisgICAgICAgICAgICAgIH0sCisKKyAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICJwcmV2IC8vIHRyYWlsaW5nIGNvbW1lbnRcbiIKKyAgICAgICAgICAgICAgICAgICIvLyBsZWFkaW5nIGNvbW1lbnRcbiIKKyAgICAgICAgICAgICAgICAgICIvLyBsaW5lIDJcbiIKKyAgICAgICAgICAgICAgICAgICJuZXh0IiwKKworICAgICAgICAgICAgICAgICAgIiB0cmFpbGluZyBjb21tZW50XG4iLAorICAgICAgICAgICAgICAgICAge30sCisgICAgICAgICAgICAgICAgICAiIGxlYWRpbmcgY29tbWVudFxuIgorICAgICAgICAgICAgICAgICAgIiBsaW5lIDJcbiIKKyAgICAgICAgICAgICAgICB9LAorCisgICAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgInByZXYgLyogdHJhaWxpbmcgYmxvY2sgY29tbWVudCAqL1xuIgorICAgICAgICAgICAgICAgICAgICAiLyogbGVhZGluZyBibG9jayBjb21tZW50XG4iCisgICAgICAgICAgICAgICAgICAgICIgKiBsaW5lIDJcbiIKKyAgICAgICAgICAgICAgICAgICAgIiAqIGxpbmUgMyAqLyIKKyAgICAgICAgICAgICAgICAgICAgIm5leHQiLAorCisgICAgICAgICAgICAgICAgICAgICIgdHJhaWxpbmcgYmxvY2sgY29tbWVudCAiLAorICAgICAgICAgICAgICAgICAgICB7fSwKKyAgICAgICAgICAgICAgICAgICAgIiBsZWFkaW5nIGJsb2NrIGNvbW1lbnRcbiIKKyAgICAgICAgICAgICAgICAgICAgIiBsaW5lIDJcbiIKKyAgICAgICAgICAgICAgICAgICAgIiBsaW5lIDMgIgorICAgICAgICAgICAgICAgICAgfSwKKworICAgICAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICAicHJldlxuIgorICAgICAgICAgICAgICAgICAgICAgICIvKiB0cmFpbGluZyBibG9jayBjb21tZW50XG4iCisgICAgICAgICAgICAgICAgICAgICAgIiAqIGxpbmUgMlxuIgorICAgICAgICAgICAgICAgICAgICAgICIgKiBsaW5lIDNcbiIKKyAgICAgICAgICAgICAgICAgICAgICAiICovXG4iCisgICAgICAgICAgICAgICAgICAgICAgIi8qIGxlYWRpbmcgYmxvY2sgY29tbWVudFxuIgorICAgICAgICAgICAgICAgICAgICAgICIgKiBsaW5lIDJcbiIKKyAgICAgICAgICAgICAgICAgICAgICAiICogbGluZSAzICovIgorICAgICAgICAgICAgICAgICAgICAgICJuZXh0IiwKKworICAgICAgICAgICAgICAgICAgICAgICIgdHJhaWxpbmcgYmxvY2sgY29tbWVudFxuIgorICAgICAgICAgICAgICAgICAgICAgICIgbGluZSAyXG4iCisgICAgICAgICAgICAgICAgICAgICAgIiBsaW5lIDNcbiIsCisgICAgICAgICAgICAgICAgICAgICAge30sCisgICAgICAgICAgICAgICAgICAgICAgIiBsZWFkaW5nIGJsb2NrIGNvbW1lbnRcbiIKKyAgICAgICAgICAgICAgICAgICAgICAiIGxpbmUgMlxuIgorICAgICAgICAgICAgICAgICAgICAgICIgbGluZSAzICIKKyAgICAgICAgICAgICAgICAgICAgfSwKKworICAgICAgICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgInByZXZcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICIvLyB0cmFpbGluZyBjb21tZW50XG4iCisgICAgICAgICAgICAgICAgICAgICAgICAiXG4iCisgICAgICAgICAgICAgICAgICAgICAgICAiLy8gZGV0YWNoZWQgY29tbWVudFxuIgorICAgICAgICAgICAgICAgICAgICAgICAgIi8vIGxpbmUgMlxuIgorICAgICAgICAgICAgICAgICAgICAgICAgIlxuIgorICAgICAgICAgICAgICAgICAgICAgICAgIi8vIHNlY29uZCBkZXRhY2hlZCBjb21tZW50XG4iCisgICAgICAgICAgICAgICAgICAgICAgICAiLyogdGhpcmQgZGV0YWNoZWQgY29tbWVudFxuIgorICAgICAgICAgICAgICAgICAgICAgICAgIiAqIGxpbmUgMiAqL1xuIgorICAgICAgICAgICAgICAgICAgICAgICAgIi8vIGxlYWRpbmcgY29tbWVudFxuIgorICAgICAgICAgICAgICAgICAgICAgICAgIm5leHQiLAorCisgICAgICAgICAgICAgICAgICAgICAgICAiIHRyYWlsaW5nIGNvbW1lbnRcbiIsCisgICAgICAgICAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICAgICAgIiBkZXRhY2hlZCBjb21tZW50XG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICIgbGluZSAyXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAiIHNlY29uZCBkZXRhY2hlZCBjb21tZW50XG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAiIHRoaXJkIGRldGFjaGVkIGNvbW1lbnRcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIiBsaW5lIDIgIgorICAgICAgICAgICAgICAgICAgICAgICAgfSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIiBsZWFkaW5nIGNvbW1lbnRcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgIH0sCisKKyAgICAgICAgICAgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICAgICAgInByZXYgLyoqL1xuIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLy8gZGV0YWNoZWQgY29tbWVudFxuIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLy8gbGVhZGluZyBjb21tZW50XG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm5leHQiLAorCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICAgICAgICAiIGRldGFjaGVkIGNvbW1lbnRcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiBsZWFkaW5nIGNvbW1lbnRcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LAorCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgInByZXYgLyoqL1xuIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLy8gbGVhZGluZyBjb21tZW50XG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJuZXh0IiwKKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge30sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgbGVhZGluZyBjb21tZW50XG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTsKKworVEVTVF8yRChUb2tlbml6ZXJUZXN0LCBEb2NDb21tZW50cywga0RvY0NvbW1lbnRDYXNlcywga0Jsb2NrU2l6ZXMpIHsKKyAgLy8gU2V0IHVwIHRoZSB0b2tlbml6ZXIuCisgIFRlc3RJbnB1dFN0cmVhbSBpbnB1dChrRG9jQ29tbWVudENhc2VzX2Nhc2UuaW5wdXQuZGF0YSgpLAorICAgICAgICAgICAgICAgICAgICAgICAga0RvY0NvbW1lbnRDYXNlc19jYXNlLmlucHV0LnNpemUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGtCbG9ja1NpemVzX2Nhc2UpOworICBUZXN0RXJyb3JDb2xsZWN0b3IgZXJyb3JfY29sbGVjdG9yOworICBUb2tlbml6ZXIgdG9rZW5pemVyKCZpbnB1dCwgJmVycm9yX2NvbGxlY3Rvcik7CisKKyAgLy8gU2V0IHVwIGEgc2Vjb25kIHRva2VuaXplciB3aGVyZSB3ZSdsbCBwYXNzIGFsbCBOVUxMcyB0byBOZXh0V2l0aENvbW1lbnRzKCkuCisgIFRlc3RJbnB1dFN0cmVhbSBpbnB1dDIoa0RvY0NvbW1lbnRDYXNlc19jYXNlLmlucHV0LmRhdGEoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGtEb2NDb21tZW50Q2FzZXNfY2FzZS5pbnB1dC5zaXplKCksCisgICAgICAgICAgICAgICAgICAgICAgICBrQmxvY2tTaXplc19jYXNlKTsKKyAgVG9rZW5pemVyIHRva2VuaXplcjIoJmlucHV0MiwgJmVycm9yX2NvbGxlY3Rvcik7CisKKyAgdG9rZW5pemVyLk5leHQoKTsKKyAgdG9rZW5pemVyMi5OZXh0KCk7CisKKyAgRVhQRUNUX0VRKCJwcmV2IiwgdG9rZW5pemVyLmN1cnJlbnQoKS50ZXh0KTsKKyAgRVhQRUNUX0VRKCJwcmV2IiwgdG9rZW5pemVyMi5jdXJyZW50KCkudGV4dCk7CisKKyAgc3RyaW5nIHByZXZfdHJhaWxpbmdfY29tbWVudHM7CisgIHZlY3RvcjxzdHJpbmc+IGRldGFjaGVkX2NvbW1lbnRzOworICBzdHJpbmcgbmV4dF9sZWFkaW5nX2NvbW1lbnRzOworICB0b2tlbml6ZXIuTmV4dFdpdGhDb21tZW50cygmcHJldl90cmFpbGluZ19jb21tZW50cywgJmRldGFjaGVkX2NvbW1lbnRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbmV4dF9sZWFkaW5nX2NvbW1lbnRzKTsKKyAgdG9rZW5pemVyMi5OZXh0V2l0aENvbW1lbnRzKE5VTEwsIE5VTEwsIE5VTEwpOworICBFWFBFQ1RfRVEoIm5leHQiLCB0b2tlbml6ZXIuY3VycmVudCgpLnRleHQpOworICBFWFBFQ1RfRVEoIm5leHQiLCB0b2tlbml6ZXIyLmN1cnJlbnQoKS50ZXh0KTsKKworICBFWFBFQ1RfRVEoa0RvY0NvbW1lbnRDYXNlc19jYXNlLnByZXZfdHJhaWxpbmdfY29tbWVudHMsCisgICAgICAgICAgICBwcmV2X3RyYWlsaW5nX2NvbW1lbnRzKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGRldGFjaGVkX2NvbW1lbnRzLnNpemUoKTsgaSsrKSB7CisgICAgQVNTRVJUX0xUKGksIEdPT0dMRV9BUlJBWVNJWkUoa0RvY0NvbW1lbnRDYXNlcykpOworICAgIEFTU0VSVF9UUlVFKGtEb2NDb21tZW50Q2FzZXNfY2FzZS5kZXRhY2hlZF9jb21tZW50c1tpXSAhPSBOVUxMKTsKKyAgICBFWFBFQ1RfRVEoa0RvY0NvbW1lbnRDYXNlc19jYXNlLmRldGFjaGVkX2NvbW1lbnRzW2ldLAorICAgICAgICAgICAgICBkZXRhY2hlZF9jb21tZW50c1tpXSk7CisgIH0KKworICAvLyBWZXJpZnkgdGhhdCB3ZSBtYXRjaGVkIGFsbCB0aGUgZGV0YWNoZWQgY29tbWVudHMuCisgIEVYUEVDVF9FUShOVUxMLAorICAgICAga0RvY0NvbW1lbnRDYXNlc19jYXNlLmRldGFjaGVkX2NvbW1lbnRzW2RldGFjaGVkX2NvbW1lbnRzLnNpemUoKV0pOworCisgIEVYUEVDVF9FUShrRG9jQ29tbWVudENhc2VzX2Nhc2UubmV4dF9sZWFkaW5nX2NvbW1lbnRzLAorICAgICAgICAgICAgbmV4dF9sZWFkaW5nX2NvbW1lbnRzKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBUZXN0IHBhcnNlIGhlbHBlcnMuICBJdCdzIG5vdCByZWFsbHkgd29ydGggc2V0dGluZyB1cCBhIGZ1bGwgZGF0YS1kcml2ZW4KKy8vIHRlc3QgaGVyZS4KK1RFU1RfRihUb2tlbml6ZXJUZXN0LCBQYXJzZUludGVnZXIpIHsKKyAgRVhQRUNUX0VRKDAsIFBhcnNlSW50ZWdlcigiMCIpKTsKKyAgRVhQRUNUX0VRKDEyMywgUGFyc2VJbnRlZ2VyKCIxMjMiKSk7CisgIEVYUEVDVF9FUSgweGFiY2RlZjEydSwgUGFyc2VJbnRlZ2VyKCIweGFiY2RlZjEyIikpOworICBFWFBFQ1RfRVEoMHhhYmNkZWYxMnUsIFBhcnNlSW50ZWdlcigiMHhBQkNERUYxMiIpKTsKKyAgRVhQRUNUX0VRKGt1aW50NjRtYXgsIFBhcnNlSW50ZWdlcigiMHhGRkZGRkZGRkZGRkZGRkZGIikpOworICBFWFBFQ1RfRVEoMDEyMzQ1NjcsIFBhcnNlSW50ZWdlcigiMDEyMzQ1NjciKSk7CisgIEVYUEVDVF9FUSgwWDEyMywgUGFyc2VJbnRlZ2VyKCIwWDEyMyIpKTsKKworICAvLyBUZXN0IGludmFsaWQgaW50ZWdlcnMgdGhhdCBtYXkgc3RpbGwgYmUgdG9rZW5pemVkIGFzIGludGVnZXJzLgorICBFWFBFQ1RfRVEoMCwgUGFyc2VJbnRlZ2VyKCIweCIpKTsKKworICB1aW50NjQgaTsKKyNpZmRlZiBQUk9UT0JVRl9IQVNfREVBVEhfVEVTVCAgLy8gZGVhdGggdGVzdHMgZG8gbm90IHdvcmsgb24gV2luZG93cyB5ZXQKKyAgLy8gVGVzdCBpbnZhbGlkIGludGVnZXJzIHRoYXQgd2lsbCBuZXZlciBiZSB0b2tlbml6ZWQgYXMgaW50ZWdlcnMuCisgIEVYUEVDVF9ERUJVR19ERUFUSChUb2tlbml6ZXI6OlBhcnNlSW50ZWdlcigienh5Iiwga3VpbnQ2NG1heCwgJmkpLAorICAgICJwYXNzZWQgdGV4dCB0aGF0IGNvdWxkIG5vdCBoYXZlIGJlZW4gdG9rZW5pemVkIGFzIGFuIGludGVnZXIiKTsKKyAgRVhQRUNUX0RFQlVHX0RFQVRIKFRva2VuaXplcjo6UGFyc2VJbnRlZ2VyKCIxLjIiLCBrdWludDY0bWF4LCAmaSksCisgICAgInBhc3NlZCB0ZXh0IHRoYXQgY291bGQgbm90IGhhdmUgYmVlbiB0b2tlbml6ZWQgYXMgYW4gaW50ZWdlciIpOworICBFWFBFQ1RfREVCVUdfREVBVEgoVG9rZW5pemVyOjpQYXJzZUludGVnZXIoIjA4Iiwga3VpbnQ2NG1heCwgJmkpLAorICAgICJwYXNzZWQgdGV4dCB0aGF0IGNvdWxkIG5vdCBoYXZlIGJlZW4gdG9rZW5pemVkIGFzIGFuIGludGVnZXIiKTsKKyAgRVhQRUNUX0RFQlVHX0RFQVRIKFRva2VuaXplcjo6UGFyc2VJbnRlZ2VyKCIweGciLCBrdWludDY0bWF4LCAmaSksCisgICAgInBhc3NlZCB0ZXh0IHRoYXQgY291bGQgbm90IGhhdmUgYmVlbiB0b2tlbml6ZWQgYXMgYW4gaW50ZWdlciIpOworICBFWFBFQ1RfREVCVUdfREVBVEgoVG9rZW5pemVyOjpQYXJzZUludGVnZXIoIi0xIiwga3VpbnQ2NG1heCwgJmkpLAorICAgICJwYXNzZWQgdGV4dCB0aGF0IGNvdWxkIG5vdCBoYXZlIGJlZW4gdG9rZW5pemVkIGFzIGFuIGludGVnZXIiKTsKKyNlbmRpZiAgLy8gUFJPVE9CVUZfSEFTX0RFQVRIX1RFU1QKKworICAvLyBUZXN0IG92ZXJmbG93cy4KKyAgRVhQRUNUX1RSVUUgKFRva2VuaXplcjo6UGFyc2VJbnRlZ2VyKCIwIiwgMCwgJmkpKTsKKyAgRVhQRUNUX0ZBTFNFKFRva2VuaXplcjo6UGFyc2VJbnRlZ2VyKCIxIiwgMCwgJmkpKTsKKyAgRVhQRUNUX1RSVUUgKFRva2VuaXplcjo6UGFyc2VJbnRlZ2VyKCIxIiwgMSwgJmkpKTsKKyAgRVhQRUNUX1RSVUUgKFRva2VuaXplcjo6UGFyc2VJbnRlZ2VyKCIxMjM0NSIsIDEyMzQ1LCAmaSkpOworICBFWFBFQ1RfRkFMU0UoVG9rZW5pemVyOjpQYXJzZUludGVnZXIoIjEyMzQ2IiwgMTIzNDUsICZpKSk7CisgIEVYUEVDVF9UUlVFIChUb2tlbml6ZXI6OlBhcnNlSW50ZWdlcigiMHhGRkZGRkZGRkZGRkZGRkZGIiAsIGt1aW50NjRtYXgsICZpKSk7CisgIEVYUEVDVF9GQUxTRShUb2tlbml6ZXI6OlBhcnNlSW50ZWdlcigiMHgxMDAwMDAwMDAwMDAwMDAwMCIsIGt1aW50NjRtYXgsICZpKSk7Cit9CisKK1RFU1RfRihUb2tlbml6ZXJUZXN0LCBQYXJzZUZsb2F0KSB7CisgIEVYUEVDVF9ET1VCTEVfRVEoMSAgICAsIFRva2VuaXplcjo6UGFyc2VGbG9hdCgiMS4iKSk7CisgIEVYUEVDVF9ET1VCTEVfRVEoMWUzICAsIFRva2VuaXplcjo6UGFyc2VGbG9hdCgiMWUzIikpOworICBFWFBFQ1RfRE9VQkxFX0VRKDFlMyAgLCBUb2tlbml6ZXI6OlBhcnNlRmxvYXQoIjFFMyIpKTsKKyAgRVhQRUNUX0RPVUJMRV9FUSgxLjVlMywgVG9rZW5pemVyOjpQYXJzZUZsb2F0KCIxLjVlMyIpKTsKKyAgRVhQRUNUX0RPVUJMRV9FUSguMSAgICwgVG9rZW5pemVyOjpQYXJzZUZsb2F0KCIuMSIpKTsKKyAgRVhQRUNUX0RPVUJMRV9FUSguMjUgICwgVG9rZW5pemVyOjpQYXJzZUZsb2F0KCIuMjUiKSk7CisgIEVYUEVDVF9ET1VCTEVfRVEoLjFlMyAsIFRva2VuaXplcjo6UGFyc2VGbG9hdCgiLjFlMyIpKTsKKyAgRVhQRUNUX0RPVUJMRV9FUSguMjVlMywgVG9rZW5pemVyOjpQYXJzZUZsb2F0KCIuMjVlMyIpKTsKKyAgRVhQRUNUX0RPVUJMRV9FUSguMWUrMywgVG9rZW5pemVyOjpQYXJzZUZsb2F0KCIuMWUrMyIpKTsKKyAgRVhQRUNUX0RPVUJMRV9FUSguMWUtMywgVG9rZW5pemVyOjpQYXJzZUZsb2F0KCIuMWUtMyIpKTsKKyAgRVhQRUNUX0RPVUJMRV9FUSg1ICAgICwgVG9rZW5pemVyOjpQYXJzZUZsb2F0KCI1IikpOworICBFWFBFQ1RfRE9VQkxFX0VRKDZlLTEyLCBUb2tlbml6ZXI6OlBhcnNlRmxvYXQoIjZlLTEyIikpOworICBFWFBFQ1RfRE9VQkxFX0VRKDEuMiAgLCBUb2tlbml6ZXI6OlBhcnNlRmxvYXQoIjEuMiIpKTsKKyAgRVhQRUNUX0RPVUJMRV9FUSgxLmUyICwgVG9rZW5pemVyOjpQYXJzZUZsb2F0KCIxLmUyIikpOworCisgIC8vIFRlc3QgaW52YWxpZCBpbnRlZ2VycyB0aGF0IG1heSBzdGlsbCBiZSB0b2tlbml6ZWQgYXMgaW50ZWdlcnMuCisgIEVYUEVDVF9ET1VCTEVfRVEoMSwgVG9rZW5pemVyOjpQYXJzZUZsb2F0KCIxZSIpKTsKKyAgRVhQRUNUX0RPVUJMRV9FUSgxLCBUb2tlbml6ZXI6OlBhcnNlRmxvYXQoIjFlLSIpKTsKKyAgRVhQRUNUX0RPVUJMRV9FUSgxLCBUb2tlbml6ZXI6OlBhcnNlRmxvYXQoIjEuZSIpKTsKKworICAvLyBUZXN0ICdmJyBzdWZmaXguCisgIEVYUEVDVF9ET1VCTEVfRVEoMSwgVG9rZW5pemVyOjpQYXJzZUZsb2F0KCIxZiIpKTsKKyAgRVhQRUNUX0RPVUJMRV9FUSgxLCBUb2tlbml6ZXI6OlBhcnNlRmxvYXQoIjEuMGYiKSk7CisgIEVYUEVDVF9ET1VCTEVfRVEoMSwgVG9rZW5pemVyOjpQYXJzZUZsb2F0KCIxRiIpKTsKKworICAvLyBUaGVzZSBzaG91bGQgcGFyc2Ugc3VjY2Vzc2Z1bGx5IGV2ZW4gdGhvdWdoIHRoZXkgYXJlIG91dCBvZiByYW5nZS4KKyAgLy8gT3ZlcmZsb3dzIGJlY29tZSBpbmZpbml0eSBhbmQgdW5kZXJmbG93cyBiZWNvbWUgemVyby4KKyAgRVhQRUNUX0VRKCAgICAgMC4wLCBUb2tlbml6ZXI6OlBhcnNlRmxvYXQoIjFlLTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTkiKSk7CisgIEVYUEVDVF9FUShIVUdFX1ZBTCwgVG9rZW5pemVyOjpQYXJzZUZsb2F0KCIxZSs5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5IikpOworCisjaWZkZWYgUFJPVE9CVUZfSEFTX0RFQVRIX1RFU1QgIC8vIGRlYXRoIHRlc3RzIGRvIG5vdCB3b3JrIG9uIFdpbmRvd3MgeWV0CisgIC8vIFRlc3QgaW52YWxpZCBpbnRlZ2VycyB0aGF0IHdpbGwgbmV2ZXIgYmUgdG9rZW5pemVkIGFzIGludGVnZXJzLgorICBFWFBFQ1RfREVCVUdfREVBVEgoVG9rZW5pemVyOjpQYXJzZUZsb2F0KCJ6eHkiKSwKKyAgICAicGFzc2VkIHRleHQgdGhhdCBjb3VsZCBub3QgaGF2ZSBiZWVuIHRva2VuaXplZCBhcyBhIGZsb2F0Iik7CisgIEVYUEVDVF9ERUJVR19ERUFUSChUb2tlbml6ZXI6OlBhcnNlRmxvYXQoIjEtZTAiKSwKKyAgICAicGFzc2VkIHRleHQgdGhhdCBjb3VsZCBub3QgaGF2ZSBiZWVuIHRva2VuaXplZCBhcyBhIGZsb2F0Iik7CisgIEVYUEVDVF9ERUJVR19ERUFUSChUb2tlbml6ZXI6OlBhcnNlRmxvYXQoIi0xLjAiKSwKKyAgICAicGFzc2VkIHRleHQgdGhhdCBjb3VsZCBub3QgaGF2ZSBiZWVuIHRva2VuaXplZCBhcyBhIGZsb2F0Iik7CisjZW5kaWYgIC8vIFBST1RPQlVGX0hBU19ERUFUSF9URVNUCit9CisKK1RFU1RfRihUb2tlbml6ZXJUZXN0LCBQYXJzZVN0cmluZykgeworICBzdHJpbmcgb3V0cHV0OworICBUb2tlbml6ZXI6OlBhcnNlU3RyaW5nKCInaGVsbG8nIiwgJm91dHB1dCk7CisgIEVYUEVDVF9FUSgiaGVsbG8iLCBvdXRwdXQpOworICBUb2tlbml6ZXI6OlBhcnNlU3RyaW5nKCJcImJsYWhcXG5ibGFoMlwiIiwgJm91dHB1dCk7CisgIEVYUEVDVF9FUSgiYmxhaFxuYmxhaDIiLCBvdXRwdXQpOworICBUb2tlbml6ZXI6OlBhcnNlU3RyaW5nKCInXFwxeFxcMVxcMTIzXFw3MzlcXDUyXFwzMzRuXFwzJyIsICZvdXRwdXQpOworICBFWFBFQ1RfRVEoIlwxeFwxXDEyM1w3MzlcNTJcMzM0blwzIiwgb3V0cHV0KTsKKyAgVG9rZW5pemVyOjpQYXJzZVN0cmluZygiJ1xceDIwXFx4NCciLCAmb3V0cHV0KTsKKyAgRVhQRUNUX0VRKCJceDIwXHg0Iiwgb3V0cHV0KTsKKworICAvLyBUZXN0IGludmFsaWQgc3RyaW5ncyB0aGF0IG1heSBzdGlsbCBiZSB0b2tlbml6ZWQgYXMgc3RyaW5ncy4KKyAgVG9rZW5pemVyOjpQYXJzZVN0cmluZygiXCJcXGFcXGxcXHZcXHQiLCAmb3V0cHV0KTsgIC8vIFxsIGlzIGludmFsaWQKKyAgRVhQRUNUX0VRKCJcYT9cdlx0Iiwgb3V0cHV0KTsKKyAgVG9rZW5pemVyOjpQYXJzZVN0cmluZygiJyIsICZvdXRwdXQpOworICBFWFBFQ1RfRVEoIiIsIG91dHB1dCk7CisgIFRva2VuaXplcjo6UGFyc2VTdHJpbmcoIidcXCIsICZvdXRwdXQpOworICBFWFBFQ1RfRVEoIlxcIiwgb3V0cHV0KTsKKworICAvLyBFeHBlcmltZW50IHdpdGggVW5pY29kZSBlc2NhcGVzLiBIZXJlIGFyZSBvbmUtLCB0d28tIGFuZCB0aHJlZS1ieXRlIFVuaWNvZGUKKyAgLy8gY2hhcmFjdGVycy4KKyAgVG9rZW5pemVyOjpQYXJzZVN0cmluZygiJ1xcdTAwMjRcXHUwMGEyXFx1MjBhY1xcVTAwMDI0YjYyWFgnIiwgJm91dHB1dCk7CisgIEVYUEVDVF9FUSgiJMKi4oKs8KStolhYIiwgb3V0cHV0KTsKKyAgLy8gU2FtZSB0aGluZyBlbmNvZGVkIHVzaW5nIFVURjE2LgorICBUb2tlbml6ZXI6OlBhcnNlU3RyaW5nKCInXFx1MDAyNFxcdTAwYTJcXHUyMGFjXFx1ZDg1MlxcdWRmNjJYWCciLCAmb3V0cHV0KTsKKyAgRVhQRUNUX0VRKCIkwqLigqzwpK2iWFgiLCBvdXRwdXQpOworICAvLyBIZXJlJ3Mgc29tZSBicm9rZW4gVVRGMTY7IHRoZXJlJ3MgYSBoZWFkIHN1cnJvZ2F0ZSB3aXRoIG5vIHRhaWwgc3Vycm9nYXRlLgorICAvLyBXZSBqdXN0IG91dHB1dCB0aGlzIGFzIGlmIGl0IHdlcmUgVVRGODsgaXQncyBub3QgYSBkZWZpbmVkIGNvZGUgcG9pbnQsIGJ1dAorICAvLyBpdCBoYXMgYSBkZWZpbmVkIGVuY29kaW5nLgorICBUb2tlbml6ZXI6OlBhcnNlU3RyaW5nKCInXFx1ZDg1MlhYJyIsICZvdXRwdXQpOworICBFWFBFQ1RfRVEoIlx4ZWRceGExXHg5MlhYIiwgb3V0cHV0KTsKKyAgLy8gTWFsZm9ybWVkIGVzY2FwZTogRGVtb25zIG1heSBmbHkgb3V0IG9mIHRoZSBub3NlLgorICBUb2tlbml6ZXI6OlBhcnNlU3RyaW5nKCJcXHUwIiwgJm91dHB1dCk7CisgIEVYUEVDVF9FUSgidTAiLCBvdXRwdXQpOworCisgIC8vIFRlc3QgaW52YWxpZCBzdHJpbmdzIHRoYXQgd2lsbCBuZXZlciBiZSB0b2tlbml6ZWQgYXMgc3RyaW5ncy4KKyNpZmRlZiBQUk9UT0JVRl9IQVNfREVBVEhfVEVTVCAgLy8gZGVhdGggdGVzdHMgZG8gbm90IHdvcmsgb24gV2luZG93cyB5ZXQKKyAgRVhQRUNUX0RFQlVHX0RFQVRIKFRva2VuaXplcjo6UGFyc2VTdHJpbmcoIiIsICZvdXRwdXQpLAorICAgICJwYXNzZWQgdGV4dCB0aGF0IGNvdWxkIG5vdCBoYXZlIGJlZW4gdG9rZW5pemVkIGFzIGEgc3RyaW5nIik7CisjZW5kaWYgIC8vIFBST1RPQlVGX0hBU19ERUFUSF9URVNUCit9CisKK1RFU1RfRihUb2tlbml6ZXJUZXN0LCBQYXJzZVN0cmluZ0FwcGVuZCkgeworICAvLyBDaGVjayB0aGF0IFBhcnNlU3RyaW5nIGFuZCBQYXJzZVN0cmluZ0FwcGVuZCBkaWZmZXIuCisgIHN0cmluZyBvdXRwdXQoInN0dWZmKyIpOworICBUb2tlbml6ZXI6OlBhcnNlU3RyaW5nQXBwZW5kKCInaGVsbG8nIiwgJm91dHB1dCk7CisgIEVYUEVDVF9FUSgic3R1ZmYraGVsbG8iLCBvdXRwdXQpOworICBUb2tlbml6ZXI6OlBhcnNlU3RyaW5nKCInaGVsbG8nIiwgJm91dHB1dCk7CisgIEVYUEVDVF9FUSgiaGVsbG8iLCBvdXRwdXQpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIEVhY2ggY2FzZSBwYXJzZXMgc29tZSBpbnB1dCB0ZXh0LCBpZ25vcmluZyB0aGUgdG9rZW5zIHByb2R1Y2VkLCBhbmQKKy8vIGNoZWNrcyB0aGF0IHRoZSBlcnJvciBvdXRwdXQgbWF0Y2hlcyB3aGF0IGlzIGV4cGVjdGVkLgorc3RydWN0IEVycm9yQ2FzZSB7CisgIHN0cmluZyBpbnB1dDsKKyAgYm9vbCByZWNvdmVyYWJsZTsgIC8vIFRydWUgaWYgdGhlIHRva2VuaXplciBzaG91bGQgYmUgYWJsZSB0byByZWNvdmVyIGFuZAorICAgICAgICAgICAgICAgICAgICAgLy8gcGFyc2UgbW9yZSB0b2tlbnMgYWZ0ZXIgc2VlaW5nIHRoaXMgZXJyb3IuICBDYXNlcworICAgICAgICAgICAgICAgICAgICAgLy8gZm9yIHdoaWNoIHRoaXMgaXMgdHJ1ZSBtdXN0IGVuZCB3aXRoICJmb28iIGFzCisgICAgICAgICAgICAgICAgICAgICAvLyB0aGUgbGFzdCB0b2tlbiwgd2hpY2ggdGhlIHRlc3Qgd2lsbCBjaGVjayBmb3IuCisgIGNvbnN0IGNoYXIqIGVycm9yczsKK307CisKK2lubGluZSBvc3RyZWFtJiBvcGVyYXRvcjw8KG9zdHJlYW0mIG91dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEVycm9yQ2FzZSYgdGVzdF9jYXNlKSB7CisgIHJldHVybiBvdXQgPDwgQ0VzY2FwZSh0ZXN0X2Nhc2UuaW5wdXQpOworfQorCitFcnJvckNhc2Uga0Vycm9yQ2FzZXNbXSA9IHsKKyAgLy8gU3RyaW5nIGVycm9ycy4KKyAgeyAiJ1xcbCcgZm9vIiwgdHJ1ZSwKKyAgICAiMDoyOiBJbnZhbGlkIGVzY2FwZSBzZXF1ZW5jZSBpbiBzdHJpbmcgbGl0ZXJhbC5cbiIgfSwKKyAgeyAiJ1xcWCcgZm9vIiwgdHJ1ZSwKKyAgICAiMDoyOiBJbnZhbGlkIGVzY2FwZSBzZXF1ZW5jZSBpbiBzdHJpbmcgbGl0ZXJhbC5cbiIgfSwKKyAgeyAiJ1xceCcgZm9vIiwgdHJ1ZSwKKyAgICAiMDozOiBFeHBlY3RlZCBoZXggZGlnaXRzIGZvciBlc2NhcGUgc2VxdWVuY2UuXG4iIH0sCisgIHsgIidmb28iLCBmYWxzZSwKKyAgICAiMDo0OiBVbmV4cGVjdGVkIGVuZCBvZiBzdHJpbmcuXG4iIH0sCisgIHsgIidiYXJcbmZvbyIsIHRydWUsCisgICAgIjA6NDogU3RyaW5nIGxpdGVyYWxzIGNhbm5vdCBjcm9zcyBsaW5lIGJvdW5kYXJpZXMuXG4iIH0sCisgIHsgIidcXHUwMScgZm9vIiwgdHJ1ZSwKKyAgICAiMDo1OiBFeHBlY3RlZCBmb3VyIGhleCBkaWdpdHMgZm9yIFxcdSBlc2NhcGUgc2VxdWVuY2UuXG4iIH0sCisgIHsgIidcXHUwMScgZm9vIiwgdHJ1ZSwKKyAgICAiMDo1OiBFeHBlY3RlZCBmb3VyIGhleCBkaWdpdHMgZm9yIFxcdSBlc2NhcGUgc2VxdWVuY2UuXG4iIH0sCisgIHsgIidcXHVYWVonIGZvbyIsIHRydWUsCisgICAgIjA6MzogRXhwZWN0ZWQgZm91ciBoZXggZGlnaXRzIGZvciBcXHUgZXNjYXBlIHNlcXVlbmNlLlxuIiB9LAorCisgIC8vIEludGVnZXIgZXJyb3JzLgorICB7ICIxMjNmb28iLCB0cnVlLAorICAgICIwOjM6IE5lZWQgc3BhY2UgYmV0d2VlbiBudW1iZXIgYW5kIGlkZW50aWZpZXIuXG4iIH0sCisKKyAgLy8gSGV4L29jdGFsIGVycm9ycy4KKyAgeyAiMHggZm9vIiwgdHJ1ZSwKKyAgICAiMDoyOiBcIjB4XCIgbXVzdCBiZSBmb2xsb3dlZCBieSBoZXggZGlnaXRzLlxuIiB9LAorICB7ICIwNTQxODIzIGZvbyIsIHRydWUsCisgICAgIjA6NDogTnVtYmVycyBzdGFydGluZyB3aXRoIGxlYWRpbmcgemVybyBtdXN0IGJlIGluIG9jdGFsLlxuIiB9LAorICB7ICIweDEyM3ogZm9vIiwgdHJ1ZSwKKyAgICAiMDo1OiBOZWVkIHNwYWNlIGJldHdlZW4gbnVtYmVyIGFuZCBpZGVudGlmaWVyLlxuIiB9LAorICB7ICIweDEyMy40IGZvbyIsIHRydWUsCisgICAgIjA6NTogSGV4IGFuZCBvY3RhbCBudW1iZXJzIG11c3QgYmUgaW50ZWdlcnMuXG4iIH0sCisgIHsgIjAxMjMuNCBmb28iLCB0cnVlLAorICAgICIwOjQ6IEhleCBhbmQgb2N0YWwgbnVtYmVycyBtdXN0IGJlIGludGVnZXJzLlxuIiB9LAorCisgIC8vIEZsb2F0IGVycm9ycy4KKyAgeyAiMWUgZm9vIiwgdHJ1ZSwKKyAgICAiMDoyOiBcImVcIiBtdXN0IGJlIGZvbGxvd2VkIGJ5IGV4cG9uZW50LlxuIiB9LAorICB7ICIxZS0gZm9vIiwgdHJ1ZSwKKyAgICAiMDozOiBcImVcIiBtdXN0IGJlIGZvbGxvd2VkIGJ5IGV4cG9uZW50LlxuIiB9LAorICB7ICIxLjIuMyBmb28iLCB0cnVlLAorICAgICIwOjM6IEFscmVhZHkgc2F3IGRlY2ltYWwgcG9pbnQgb3IgZXhwb25lbnQ7IGNhbid0IGhhdmUgYW5vdGhlciBvbmUuXG4iIH0sCisgIHsgIjFlMi4zIGZvbyIsIHRydWUsCisgICAgIjA6MzogQWxyZWFkeSBzYXcgZGVjaW1hbCBwb2ludCBvciBleHBvbmVudDsgY2FuJ3QgaGF2ZSBhbm90aGVyIG9uZS5cbiIgfSwKKyAgeyAiYS4xIGZvbyIsIHRydWUsCisgICAgIjA6MTogTmVlZCBzcGFjZSBiZXR3ZWVuIGlkZW50aWZpZXIgYW5kIGRlY2ltYWwgcG9pbnQuXG4iIH0sCisgIC8vIGFsbG93X2ZfYWZ0ZXJfZmxvYXQgbm90IGVuYWJsZWQsIHNvIHRoaXMgc2hvdWxkIGJlIGFuIGVycm9yLgorICB7ICIxLjBmIGZvbyIsIHRydWUsCisgICAgIjA6MzogTmVlZCBzcGFjZSBiZXR3ZWVuIG51bWJlciBhbmQgaWRlbnRpZmllci5cbiIgfSwKKworICAvLyBCbG9jayBjb21tZW50IGVycm9ycy4KKyAgeyAiLyoiLCBmYWxzZSwKKyAgICAiMDoyOiBFbmQtb2YtZmlsZSBpbnNpZGUgYmxvY2sgY29tbWVudC5cbiIKKyAgICAiMDowOiAgIENvbW1lbnQgc3RhcnRlZCBoZXJlLlxuIn0sCisgIHsgIi8qLyovIGZvbyIsIHRydWUsCisgICAgIjA6MzogXCIvKlwiIGluc2lkZSBibG9jayBjb21tZW50LiAgQmxvY2sgY29tbWVudHMgY2Fubm90IGJlIG5lc3RlZC5cbiJ9LAorCisgIC8vIENvbnRyb2wgY2hhcmFjdGVycy4gIE11bHRpcGxlIGNvbnNlY3V0aXZlIGNvbnRyb2wgY2hhcmFjdGVycyBzaG91bGQgb25seQorICAvLyBwcm9kdWNlIG9uZSBlcnJvci4KKyAgeyAiXGIgZm9vIiwgdHJ1ZSwKKyAgICAiMDowOiBJbnZhbGlkIGNvbnRyb2wgY2hhcmFjdGVycyBlbmNvdW50ZXJlZCBpbiB0ZXh0LlxuIiB9LAorICB7ICJcYlxiIGZvbyIsIHRydWUsCisgICAgIjA6MDogSW52YWxpZCBjb250cm9sIGNoYXJhY3RlcnMgZW5jb3VudGVyZWQgaW4gdGV4dC5cbiIgfSwKKworICAvLyBDaGVjayB0aGF0IGNvbnRyb2wgY2hhcmFjdGVycyBhdCBlbmQgb2YgaW5wdXQgZG9uJ3QgcmVzdWx0IGluIGFuCisgIC8vIGluZmluaXRlIGxvb3AuCisgIHsgIlxiIiwgZmFsc2UsCisgICAgIjA6MDogSW52YWxpZCBjb250cm9sIGNoYXJhY3RlcnMgZW5jb3VudGVyZWQgaW4gdGV4dC5cbiIgfSwKKworICAvLyBDaGVjayByZWNvdmVyeSBmcm9tICdcMCcuICBXZSBoYXZlIHRvIGV4cGxpY2l0bHkgc3BlY2lmeSB0aGUgbGVuZ3RoIG9mCisgIC8vIHRoZXNlIHN0cmluZ3MgYmVjYXVzZSBvdGhlcndpc2UgdGhlIHN0cmluZyBjb25zdHJ1Y3RvciB3aWxsIGp1c3QgY2FsbAorICAvLyBzdHJsZW4oKSB3aGljaCB3aWxsIHNlZSB0aGUgZmlyc3QgJ1wwJyBhbmQgdGhpbmsgdGhhdCBpcyB0aGUgZW5kIG9mIHRoZQorICAvLyBzdHJpbmcuCisgIHsgc3RyaW5nKCJcMGZvbyIsIDQpLCB0cnVlLAorICAgICIwOjA6IEludmFsaWQgY29udHJvbCBjaGFyYWN0ZXJzIGVuY291bnRlcmVkIGluIHRleHQuXG4iIH0sCisgIHsgc3RyaW5nKCJcMFwwZm9vIiwgNSksIHRydWUsCisgICAgIjA6MDogSW52YWxpZCBjb250cm9sIGNoYXJhY3RlcnMgZW5jb3VudGVyZWQgaW4gdGV4dC5cbiIgfSwKKworICAvLyBDaGVjayBlcnJvciBmcm9tIGhpZ2ggb3JkZXIgYml0cyBzZXQKKyAgeyAiXDMwMGZvbyIsIHRydWUsCisgICAgIjA6MDogSW50ZXJwcmV0aW5nIG5vbiBhc2NpaSBjb2RlcG9pbnQgMTkyLlxuIiB9LAorfTsKKworVEVTVF8yRChUb2tlbml6ZXJUZXN0LCBFcnJvcnMsIGtFcnJvckNhc2VzLCBrQmxvY2tTaXplcykgeworICAvLyBTZXQgdXAgdGhlIHRva2VuaXplci4KKyAgVGVzdElucHV0U3RyZWFtIGlucHV0KGtFcnJvckNhc2VzX2Nhc2UuaW5wdXQuZGF0YSgpLAorICAgICAgICAgICAgICAgICAgICAgICAga0Vycm9yQ2FzZXNfY2FzZS5pbnB1dC5zaXplKCksCisgICAgICAgICAgICAgICAgICAgICAgICBrQmxvY2tTaXplc19jYXNlKTsKKyAgVGVzdEVycm9yQ29sbGVjdG9yIGVycm9yX2NvbGxlY3RvcjsKKyAgVG9rZW5pemVyIHRva2VuaXplcigmaW5wdXQsICZlcnJvcl9jb2xsZWN0b3IpOworCisgIC8vIElnbm9yZSBhbGwgaW5wdXQsIGV4Y2VwdCByZW1lbWJlciBpZiB0aGUgbGFzdCB0b2tlbiB3YXMgImZvbyIuCisgIGJvb2wgbGFzdF93YXNfZm9vID0gZmFsc2U7CisgIHdoaWxlICh0b2tlbml6ZXIuTmV4dCgpKSB7CisgICAgbGFzdF93YXNfZm9vID0gdG9rZW5pemVyLmN1cnJlbnQoKS50ZXh0ID09ICJmb28iOworICB9CisKKyAgLy8gQ2hlY2sgdGhhdCB0aGUgZXJyb3JzIG1hdGNoIHdoYXQgd2FzIGV4cGVjdGVkLgorICBFWFBFQ1RfRVEoa0Vycm9yQ2FzZXNfY2FzZS5lcnJvcnMsIGVycm9yX2NvbGxlY3Rvci50ZXh0Xyk7CisKKyAgLy8gSWYgdGhlIGVycm9yIHdhcyByZWNvdmVyYWJsZSwgbWFrZSBzdXJlIHdlIHNhdyAiZm9vIiBhZnRlciBpdC4KKyAgaWYgKGtFcnJvckNhc2VzX2Nhc2UucmVjb3ZlcmFibGUpIHsKKyAgICBFWFBFQ1RfVFJVRShsYXN0X3dhc19mb28pOworICB9Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworVEVTVF8xRChUb2tlbml6ZXJUZXN0LCBCYWNrVXBPbkRlc3RydWN0aW9uLCBrQmxvY2tTaXplcykgeworICBzdHJpbmcgdGV4dCA9ICJmb28gYmFyIjsKKyAgVGVzdElucHV0U3RyZWFtIGlucHV0KHRleHQuZGF0YSgpLCB0ZXh0LnNpemUoKSwga0Jsb2NrU2l6ZXNfY2FzZSk7CisKKyAgLy8gQ3JlYXRlIGEgdG9rZW5pemVyLCByZWFkIG9uZSB0b2tlbiwgdGhlbiBkZXN0cm95IGl0LgorICB7CisgICAgVGVzdEVycm9yQ29sbGVjdG9yIGVycm9yX2NvbGxlY3RvcjsKKyAgICBUb2tlbml6ZXIgdG9rZW5pemVyKCZpbnB1dCwgJmVycm9yX2NvbGxlY3Rvcik7CisKKyAgICB0b2tlbml6ZXIuTmV4dCgpOworICB9CisKKyAgLy8gT25seSAiZm9vIiBzaG91bGQgaGF2ZSBiZWVuIHJlYWQuCisgIEVYUEVDVF9FUShzdHJsZW4oImZvbyIpLCBpbnB1dC5CeXRlQ291bnQoKSk7Cit9CisKKworfSAgLy8gbmFtZXNwYWNlCit9ICAvLyBuYW1lc3BhY2UgaW8KK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE4NmRlMDAKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW0uY2MKQEAgLTAsMCArMSw1OCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW0uaD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9sb2dnaW5nLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW8geworCitaZXJvQ29weUlucHV0U3RyZWFtOjp+WmVyb0NvcHlJbnB1dFN0cmVhbSgpIHt9CitaZXJvQ29weU91dHB1dFN0cmVhbTo6flplcm9Db3B5T3V0cHV0U3RyZWFtKCkge30KKworCitib29sIFplcm9Db3B5T3V0cHV0U3RyZWFtOjpXcml0ZUFsaWFzZWRSYXcoY29uc3Qgdm9pZCogLyogZGF0YSAqLywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgLyogc2l6ZSAqLykgeworICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiVGhpcyBaZXJvQ29weU91dHB1dFN0cmVhbSBkb2Vzbid0IHN1cHBvcnQgYWxpYXNpbmcuICIKKyAgICAgICAgICAgICAgICAiUmVhY2hpbmcgaGVyZSB1c3VhbGx5IG1lYW5zIGEgWmVyb0NvcHlPdXRwdXRTdHJlYW0gIgorICAgICAgICAgICAgICAgICJpbXBsZW1lbnRhdGlvbiBidWcuIjsKKyAgcmV0dXJuIGZhbHNlOworfQorCit9ICAvLyBuYW1lc3BhY2UgaW8KK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW0uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MjY1MGZjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtLmgKQEAgLTAsMCArMSwyNDggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBUaGlzIGZpbGUgY29udGFpbnMgdGhlIFplcm9Db3B5SW5wdXRTdHJlYW0gYW5kIFplcm9Db3B5T3V0cHV0U3RyZWFtCisvLyBpbnRlcmZhY2VzLCB3aGljaCByZXByZXNlbnQgYWJzdHJhY3QgSS9PIHN0cmVhbXMgdG8gYW5kIGZyb20gd2hpY2gKKy8vIHByb3RvY29sIGJ1ZmZlcnMgY2FuIGJlIHJlYWQgYW5kIHdyaXR0ZW4uICBGb3IgYSBmZXcgc2ltcGxlCisvLyBpbXBsZW1lbnRhdGlvbnMgb2YgdGhlc2UgaW50ZXJmYWNlcywgc2VlIHplcm9fY29weV9zdHJlYW1faW1wbC5oLgorLy8KKy8vIFRoZXNlIGludGVyZmFjZXMgYXJlIGRpZmZlcmVudCBmcm9tIGNsYXNzaWMgSS9PIHN0cmVhbXMgaW4gdGhhdCB0aGV5CisvLyB0cnkgdG8gbWluaW1pemUgdGhlIGFtb3VudCBvZiBkYXRhIGNvcHlpbmcgdGhhdCBuZWVkcyB0byBiZSBkb25lLgorLy8gVG8gYWNjb21wbGlzaCB0aGlzLCByZXNwb25zaWJpbGl0eSBmb3IgYWxsb2NhdGluZyBidWZmZXJzIGlzIG1vdmVkIHRvCisvLyB0aGUgc3RyZWFtIG9iamVjdCwgcmF0aGVyIHRoYW4gYmVpbmcgdGhlIHJlc3BvbnNpYmlsaXR5IG9mIHRoZSBjYWxsZXIuCisvLyBTbywgdGhlIHN0cmVhbSBjYW4gcmV0dXJuIGEgYnVmZmVyIHdoaWNoIGFjdHVhbGx5IHBvaW50cyBkaXJlY3RseSBpbnRvCisvLyB0aGUgZmluYWwgZGF0YSBzdHJ1Y3R1cmUgd2hlcmUgdGhlIGJ5dGVzIGFyZSB0byBiZSBzdG9yZWQsIGFuZCB0aGUgY2FsbGVyCisvLyBjYW4gaW50ZXJhY3QgZGlyZWN0bHkgd2l0aCB0aGF0IGJ1ZmZlciwgZWxpbWluYXRpbmcgYW4gaW50ZXJtZWRpYXRlIGNvcHkKKy8vIG9wZXJhdGlvbi4KKy8vCisvLyBBcyBhbiBleGFtcGxlLCBjb25zaWRlciB0aGUgY29tbW9uIGNhc2UgaW4gd2hpY2ggeW91IGFyZSByZWFkaW5nIGJ5dGVzCisvLyBmcm9tIGFuIGFycmF5IHRoYXQgaXMgYWxyZWFkeSBpbiBtZW1vcnkgKG9yIHBlcmhhcHMgYW4gbW1hcCgpZWQgZmlsZSkuCisvLyBXaXRoIGNsYXNzaWMgSS9PIHN0cmVhbXMsIHlvdSB3b3VsZCBkbyBzb21ldGhpbmcgbGlrZToKKy8vICAgY2hhciBidWZmZXJbQlVGRkVSX1NJWkVdOworLy8gICBpbnB1dC0+UmVhZChidWZmZXIsIEJVRkZFUl9TSVpFKTsKKy8vICAgRG9Tb21ldGhpbmcoYnVmZmVyLCBCVUZGRVJfU0laRSk7CisvLyBUaGVuLCB0aGUgc3RyZWFtIGJhc2ljYWxseSBqdXN0IGNhbGxzIG1lbWNweSgpIHRvIGNvcHkgdGhlIGRhdGEgZnJvbQorLy8gdGhlIGFycmF5IGludG8geW91ciBidWZmZXIuICBXaXRoIGEgWmVyb0NvcHlJbnB1dFN0cmVhbSwgeW91IHdvdWxkIGRvCisvLyB0aGlzIGluc3RlYWQ6CisvLyAgIGNvbnN0IHZvaWQqIGJ1ZmZlcjsKKy8vICAgaW50IHNpemU7CisvLyAgIGlucHV0LT5OZXh0KCZidWZmZXIsICZzaXplKTsKKy8vICAgRG9Tb21ldGhpbmcoYnVmZmVyLCBzaXplKTsKKy8vIEhlcmUsIG5vIGNvcHkgaXMgcGVyZm9ybWVkLiAgVGhlIGlucHV0IHN0cmVhbSByZXR1cm5zIGEgcG9pbnRlciBkaXJlY3RseQorLy8gaW50byB0aGUgYmFja2luZyBhcnJheSwgYW5kIHRoZSBjYWxsZXIgZW5kcyB1cCByZWFkaW5nIGRpcmVjdGx5IGZyb20gaXQuCisvLworLy8gSWYgeW91IHdhbnQgdG8gYmUgYWJsZSB0byByZWFkIHRoZSBvbGQtZmFzaGlvbiB3YXksIHlvdSBjYW4gY3JlYXRlCisvLyBhIENvZGVkSW5wdXRTdHJlYW0gb3IgQ29kZWRPdXRwdXRTdHJlYW0gd3JhcHBpbmcgdGhlc2Ugb2JqZWN0cyBhbmQgdXNlCisvLyB0aGVpciBSZWFkUmF3KCkvV3JpdGVSYXcoKSBtZXRob2RzLiAgVGhlc2Ugd2lsbCwgb2YgY291cnNlLCBhZGQgYSBjb3B5CisvLyBzdGVwLCBidXQgQ29kZWQqU3RyZWFtIHdpbGwgaGFuZGxlIGJ1ZmZlcmluZyBzbyBhdCBsZWFzdCBpdCB3aWxsIGJlCisvLyByZWFzb25hYmx5IGVmZmljaWVudC4KKy8vCisvLyBaZXJvQ29weUlucHV0U3RyZWFtIGV4YW1wbGU6CisvLyAgIC8vIFJlYWQgaW4gYSBmaWxlIGFuZCBwcmludCBpdHMgY29udGVudHMgdG8gc3Rkb3V0LgorLy8gICBpbnQgZmQgPSBvcGVuKCJteWZpbGUiLCBPX1JET05MWSk7CisvLyAgIFplcm9Db3B5SW5wdXRTdHJlYW0qIGlucHV0ID0gbmV3IEZpbGVJbnB1dFN0cmVhbShmZCk7CisvLworLy8gICBjb25zdCB2b2lkKiBidWZmZXI7CisvLyAgIGludCBzaXplOworLy8gICB3aGlsZSAoaW5wdXQtPk5leHQoJmJ1ZmZlciwgJnNpemUpKSB7CisvLyAgICAgY291dC53cml0ZShidWZmZXIsIHNpemUpOworLy8gICB9CisvLworLy8gICBkZWxldGUgaW5wdXQ7CisvLyAgIGNsb3NlKGZkKTsKKy8vCisvLyBaZXJvQ29weU91dHB1dFN0cmVhbSBleGFtcGxlOgorLy8gICAvLyBDb3B5IHRoZSBjb250ZW50cyBvZiAiaW5maWxlIiB0byAib3V0ZmlsZSIsIHVzaW5nIHBsYWluIHJlYWQoKSBmb3IKKy8vICAgLy8gImluZmlsZSIgYnV0IGEgWmVyb0NvcHlPdXRwdXRTdHJlYW0gZm9yICJvdXRmaWxlIi4KKy8vICAgaW50IGluZmQgPSBvcGVuKCJpbmZpbGUiLCBPX1JET05MWSk7CisvLyAgIGludCBvdXRmZCA9IG9wZW4oIm91dGZpbGUiLCBPX1dST05MWSk7CisvLyAgIFplcm9Db3B5T3V0cHV0U3RyZWFtKiBvdXRwdXQgPSBuZXcgRmlsZU91dHB1dFN0cmVhbShvdXRmZCk7CisvLworLy8gICB2b2lkKiBidWZmZXI7CisvLyAgIGludCBzaXplOworLy8gICB3aGlsZSAob3V0cHV0LT5OZXh0KCZidWZmZXIsICZzaXplKSkgeworLy8gICAgIGludCBieXRlcyA9IHJlYWQoaW5mZCwgYnVmZmVyLCBzaXplKTsKKy8vICAgICBpZiAoYnl0ZXMgPCBzaXplKSB7CisvLyAgICAgICAvLyBSZWFjaGVkIEVPRi4KKy8vICAgICAgIG91dHB1dC0+QmFja1VwKHNpemUgLSBieXRlcyk7CisvLyAgICAgICBicmVhazsKKy8vICAgICB9CisvLyAgIH0KKy8vCisvLyAgIGRlbGV0ZSBvdXRwdXQ7CisvLyAgIGNsb3NlKGluZmQpOworLy8gICBjbG9zZShvdXRmZCk7CisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0lPX1pFUk9fQ09QWV9TVFJFQU1fSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9JT19aRVJPX0NPUFlfU1RSRUFNX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW8geworCisvLyBEZWZpbmVkIGluIHRoaXMgZmlsZS4KK2NsYXNzIFplcm9Db3B5SW5wdXRTdHJlYW07CitjbGFzcyBaZXJvQ29weU91dHB1dFN0cmVhbTsKKworLy8gQWJzdHJhY3QgaW50ZXJmYWNlIHNpbWlsYXIgdG8gYW4gaW5wdXQgc3RyZWFtIGJ1dCBkZXNpZ25lZCB0byBtaW5pbWl6ZQorLy8gY29weWluZy4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBaZXJvQ29weUlucHV0U3RyZWFtIHsKKyBwdWJsaWM6CisgIGlubGluZSBaZXJvQ29weUlucHV0U3RyZWFtKCkge30KKyAgdmlydHVhbCB+WmVyb0NvcHlJbnB1dFN0cmVhbSgpOworCisgIC8vIE9idGFpbnMgYSBjaHVuayBvZiBkYXRhIGZyb20gdGhlIHN0cmVhbS4KKyAgLy8KKyAgLy8gUHJlY29uZGl0aW9uczoKKyAgLy8gKiAic2l6ZSIgYW5kICJkYXRhIiBhcmUgbm90IE5VTEwuCisgIC8vCisgIC8vIFBvc3Rjb25kaXRpb25zOgorICAvLyAqIElmIHRoZSByZXR1cm5lZCB2YWx1ZSBpcyBmYWxzZSwgdGhlcmUgaXMgbm8gbW9yZSBkYXRhIHRvIHJldHVybiBvcgorICAvLyAgIGFuIGVycm9yIG9jY3VycmVkLiAgQWxsIGVycm9ycyBhcmUgcGVybWFuZW50LgorICAvLyAqIE90aGVyd2lzZSwgInNpemUiIHBvaW50cyB0byB0aGUgYWN0dWFsIG51bWJlciBvZiBieXRlcyByZWFkIGFuZCAiZGF0YSIKKyAgLy8gICBwb2ludHMgdG8gYSBwb2ludGVyIHRvIGEgYnVmZmVyIGNvbnRhaW5pbmcgdGhlc2UgYnl0ZXMuCisgIC8vICogT3duZXJzaGlwIG9mIHRoaXMgYnVmZmVyIHJlbWFpbnMgd2l0aCB0aGUgc3RyZWFtLCBhbmQgdGhlIGJ1ZmZlcgorICAvLyAgIHJlbWFpbnMgdmFsaWQgb25seSB1bnRpbCBzb21lIG90aGVyIG1ldGhvZCBvZiB0aGUgc3RyZWFtIGlzIGNhbGxlZAorICAvLyAgIG9yIHRoZSBzdHJlYW0gaXMgZGVzdHJveWVkLgorICAvLyAqIEl0IGlzIGxlZ2FsIGZvciB0aGUgcmV0dXJuZWQgYnVmZmVyIHRvIGhhdmUgemVybyBzaXplLCBhcyBsb25nCisgIC8vICAgYXMgcmVwZWF0ZWRseSBjYWxsaW5nIE5leHQoKSBldmVudHVhbGx5IHlpZWxkcyBhIGJ1ZmZlciB3aXRoIG5vbi16ZXJvCisgIC8vICAgc2l6ZS4KKyAgdmlydHVhbCBib29sIE5leHQoY29uc3Qgdm9pZCoqIGRhdGEsIGludCogc2l6ZSkgPSAwOworCisgIC8vIEJhY2tzIHVwIGEgbnVtYmVyIG9mIGJ5dGVzLCBzbyB0aGF0IHRoZSBuZXh0IGNhbGwgdG8gTmV4dCgpIHJldHVybnMKKyAgLy8gZGF0YSBhZ2FpbiB0aGF0IHdhcyBhbHJlYWR5IHJldHVybmVkIGJ5IHRoZSBsYXN0IGNhbGwgdG8gTmV4dCgpLiAgVGhpcworICAvLyBpcyB1c2VmdWwgd2hlbiB3cml0aW5nIHByb2NlZHVyZXMgdGhhdCBhcmUgb25seSBzdXBwb3NlZCB0byByZWFkIHVwCisgIC8vIHRvIGEgY2VydGFpbiBwb2ludCBpbiB0aGUgaW5wdXQsIHRoZW4gcmV0dXJuLiAgSWYgTmV4dCgpIHJldHVybnMgYQorICAvLyBidWZmZXIgdGhhdCBnb2VzIGJleW9uZCB3aGF0IHlvdSB3YW50ZWQgdG8gcmVhZCwgeW91IGNhbiB1c2UgQmFja1VwKCkKKyAgLy8gdG8gcmV0dXJuIHRvIHRoZSBwb2ludCB3aGVyZSB5b3UgaW50ZW5kZWQgdG8gZmluaXNoLgorICAvLworICAvLyBQcmVjb25kaXRpb25zOgorICAvLyAqIFRoZSBsYXN0IG1ldGhvZCBjYWxsZWQgbXVzdCBoYXZlIGJlZW4gTmV4dCgpLgorICAvLyAqIGNvdW50IG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHRoZSBzaXplIG9mIHRoZSBsYXN0IGJ1ZmZlcgorICAvLyAgIHJldHVybmVkIGJ5IE5leHQoKS4KKyAgLy8KKyAgLy8gUG9zdGNvbmRpdGlvbnM6CisgIC8vICogVGhlIGxhc3QgImNvdW50IiBieXRlcyBvZiB0aGUgbGFzdCBidWZmZXIgcmV0dXJuZWQgYnkgTmV4dCgpIHdpbGwgYmUKKyAgLy8gICBwdXNoZWQgYmFjayBpbnRvIHRoZSBzdHJlYW0uICBTdWJzZXF1ZW50IGNhbGxzIHRvIE5leHQoKSB3aWxsIHJldHVybgorICAvLyAgIHRoZSBzYW1lIGRhdGEgYWdhaW4gYmVmb3JlIHByb2R1Y2luZyBuZXcgZGF0YS4KKyAgdmlydHVhbCB2b2lkIEJhY2tVcChpbnQgY291bnQpID0gMDsKKworICAvLyBTa2lwcyBhIG51bWJlciBvZiBieXRlcy4gIFJldHVybnMgZmFsc2UgaWYgdGhlIGVuZCBvZiB0aGUgc3RyZWFtIGlzCisgIC8vIHJlYWNoZWQgb3Igc29tZSBpbnB1dCBlcnJvciBvY2N1cnJlZC4gIEluIHRoZSBlbmQtb2Ytc3RyZWFtIGNhc2UsIHRoZQorICAvLyBzdHJlYW0gaXMgYWR2YW5jZWQgdG8gdGhlIGVuZCBvZiB0aGUgc3RyZWFtIChzbyBCeXRlQ291bnQoKSB3aWxsIHJldHVybgorICAvLyB0aGUgdG90YWwgc2l6ZSBvZiB0aGUgc3RyZWFtKS4KKyAgdmlydHVhbCBib29sIFNraXAoaW50IGNvdW50KSA9IDA7CisKKyAgLy8gUmV0dXJucyB0aGUgdG90YWwgbnVtYmVyIG9mIGJ5dGVzIHJlYWQgc2luY2UgdGhpcyBvYmplY3Qgd2FzIGNyZWF0ZWQuCisgIHZpcnR1YWwgaW50NjQgQnl0ZUNvdW50KCkgY29uc3QgPSAwOworCisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoWmVyb0NvcHlJbnB1dFN0cmVhbSk7Cit9OworCisvLyBBYnN0cmFjdCBpbnRlcmZhY2Ugc2ltaWxhciB0byBhbiBvdXRwdXQgc3RyZWFtIGJ1dCBkZXNpZ25lZCB0byBtaW5pbWl6ZQorLy8gY29weWluZy4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBaZXJvQ29weU91dHB1dFN0cmVhbSB7CisgcHVibGljOgorICBpbmxpbmUgWmVyb0NvcHlPdXRwdXRTdHJlYW0oKSB7fQorICB2aXJ0dWFsIH5aZXJvQ29weU91dHB1dFN0cmVhbSgpOworCisgIC8vIE9idGFpbnMgYSBidWZmZXIgaW50byB3aGljaCBkYXRhIGNhbiBiZSB3cml0dGVuLiAgQW55IGRhdGEgd3JpdHRlbgorICAvLyBpbnRvIHRoaXMgYnVmZmVyIHdpbGwgZXZlbnR1YWxseSAobWF5YmUgaW5zdGFudGx5LCBtYXliZSBsYXRlciBvbikKKyAgLy8gYmUgd3JpdHRlbiB0byB0aGUgb3V0cHV0LgorICAvLworICAvLyBQcmVjb25kaXRpb25zOgorICAvLyAqICJzaXplIiBhbmQgImRhdGEiIGFyZSBub3QgTlVMTC4KKyAgLy8KKyAgLy8gUG9zdGNvbmRpdGlvbnM6CisgIC8vICogSWYgdGhlIHJldHVybmVkIHZhbHVlIGlzIGZhbHNlLCBhbiBlcnJvciBvY2N1cnJlZC4gIEFsbCBlcnJvcnMgYXJlCisgIC8vICAgcGVybWFuZW50LgorICAvLyAqIE90aGVyd2lzZSwgInNpemUiIHBvaW50cyB0byB0aGUgYWN0dWFsIG51bWJlciBvZiBieXRlcyBpbiB0aGUgYnVmZmVyCisgIC8vICAgYW5kICJkYXRhIiBwb2ludHMgdG8gdGhlIGJ1ZmZlci4KKyAgLy8gKiBPd25lcnNoaXAgb2YgdGhpcyBidWZmZXIgcmVtYWlucyB3aXRoIHRoZSBzdHJlYW0sIGFuZCB0aGUgYnVmZmVyCisgIC8vICAgcmVtYWlucyB2YWxpZCBvbmx5IHVudGlsIHNvbWUgb3RoZXIgbWV0aG9kIG9mIHRoZSBzdHJlYW0gaXMgY2FsbGVkCisgIC8vICAgb3IgdGhlIHN0cmVhbSBpcyBkZXN0cm95ZWQuCisgIC8vICogQW55IGRhdGEgd2hpY2ggdGhlIGNhbGxlciBzdG9yZXMgaW4gdGhpcyBidWZmZXIgd2lsbCBldmVudHVhbGx5IGJlCisgIC8vICAgd3JpdHRlbiB0byB0aGUgb3V0cHV0ICh1bmxlc3MgQmFja1VwKCkgaXMgY2FsbGVkKS4KKyAgLy8gKiBJdCBpcyBsZWdhbCBmb3IgdGhlIHJldHVybmVkIGJ1ZmZlciB0byBoYXZlIHplcm8gc2l6ZSwgYXMgbG9uZworICAvLyAgIGFzIHJlcGVhdGVkbHkgY2FsbGluZyBOZXh0KCkgZXZlbnR1YWxseSB5aWVsZHMgYSBidWZmZXIgd2l0aCBub24temVybworICAvLyAgIHNpemUuCisgIHZpcnR1YWwgYm9vbCBOZXh0KHZvaWQqKiBkYXRhLCBpbnQqIHNpemUpID0gMDsKKworICAvLyBCYWNrcyB1cCBhIG51bWJlciBvZiBieXRlcywgc28gdGhhdCB0aGUgZW5kIG9mIHRoZSBsYXN0IGJ1ZmZlciByZXR1cm5lZAorICAvLyBieSBOZXh0KCkgaXMgbm90IGFjdHVhbGx5IHdyaXR0ZW4uICBUaGlzIGlzIG5lZWRlZCB3aGVuIHlvdSBmaW5pc2gKKyAgLy8gd3JpdGluZyBhbGwgdGhlIGRhdGEgeW91IHdhbnQgdG8gd3JpdGUsIGJ1dCB0aGUgbGFzdCBidWZmZXIgd2FzIGJpZ2dlcgorICAvLyB0aGFuIHlvdSBuZWVkZWQuICBZb3UgZG9uJ3Qgd2FudCB0byB3cml0ZSBhIGJ1bmNoIG9mIGdhcmJhZ2UgYWZ0ZXIgdGhlCisgIC8vIGVuZCBvZiB5b3VyIGRhdGEsIHNvIHlvdSB1c2UgQmFja1VwKCkgdG8gYmFjayB1cC4KKyAgLy8KKyAgLy8gUHJlY29uZGl0aW9uczoKKyAgLy8gKiBUaGUgbGFzdCBtZXRob2QgY2FsbGVkIG11c3QgaGF2ZSBiZWVuIE5leHQoKS4KKyAgLy8gKiBjb3VudCBtdXN0IGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byB0aGUgc2l6ZSBvZiB0aGUgbGFzdCBidWZmZXIKKyAgLy8gICByZXR1cm5lZCBieSBOZXh0KCkuCisgIC8vICogVGhlIGNhbGxlciBtdXN0IG5vdCBoYXZlIHdyaXR0ZW4gYW55dGhpbmcgdG8gdGhlIGxhc3QgImNvdW50IiBieXRlcworICAvLyAgIG9mIHRoYXQgYnVmZmVyLgorICAvLworICAvLyBQb3N0Y29uZGl0aW9uczoKKyAgLy8gKiBUaGUgbGFzdCAiY291bnQiIGJ5dGVzIG9mIHRoZSBsYXN0IGJ1ZmZlciByZXR1cm5lZCBieSBOZXh0KCkgd2lsbCBiZQorICAvLyAgIGlnbm9yZWQuCisgIHZpcnR1YWwgdm9pZCBCYWNrVXAoaW50IGNvdW50KSA9IDA7CisKKyAgLy8gUmV0dXJucyB0aGUgdG90YWwgbnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW4gc2luY2UgdGhpcyBvYmplY3Qgd2FzIGNyZWF0ZWQuCisgIHZpcnR1YWwgaW50NjQgQnl0ZUNvdW50KCkgY29uc3QgPSAwOworCisgIC8vIFdyaXRlIGEgZ2l2ZW4gY2h1bmsgb2YgZGF0YSB0byB0aGUgb3V0cHV0LiAgU29tZSBvdXRwdXQgc3RyZWFtcyBtYXkKKyAgLy8gaW1wbGVtZW50IHRoaXMgaW4gYSB3YXkgdGhhdCBhdm9pZHMgY29weWluZy4gQ2hlY2sgQWxsb3dzQWxpYXNpbmcoKSBiZWZvcmUKKyAgLy8gY2FsbGluZyBXcml0ZUFsaWFzZWRSYXcoKS4gSXQgd2lsbCBHT09HTEVfQ0hFQ0sgZmFpbCBpZiBXcml0ZUFsaWFzZWRSYXcoKSBpcworICAvLyBjYWxsZWQgb24gYSBzdHJlYW0gdGhhdCBkb2VzIG5vdCBhbGxvdyBhbGlhc2luZy4KKyAgLy8KKyAgLy8gTk9URTogSXQgaXMgY2FsbGVyJ3MgcmVzcG9uc2liaWxpdHkgdG8gZW5zdXJlIHRoYXQgdGhlIGNodW5rIG9mIG1lbW9yeQorICAvLyByZW1haW5zIGxpdmUgdW50aWwgYWxsIG9mIHRoZSBkYXRhIGhhcyBiZWVuIGNvbnN1bWVkIGZyb20gdGhlIHN0cmVhbS4KKyAgdmlydHVhbCBib29sIFdyaXRlQWxpYXNlZFJhdyhjb25zdCB2b2lkKiBkYXRhLCBpbnQgc2l6ZSk7CisgIHZpcnR1YWwgYm9vbCBBbGxvd3NBbGlhc2luZygpIGNvbnN0IHsgcmV0dXJuIGZhbHNlOyB9CisKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhaZXJvQ29weU91dHB1dFN0cmVhbSk7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgaW8KK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9JT19aRVJPX0NPUFlfU1RSRUFNX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX2ltcGwuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ZWMyYjVkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX2ltcGwuY2MKQEAgLTAsMCArMSw0NzQgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2lmZGVmIF9NU0NfVkVSCisjaW5jbHVkZSA8aW8uaD4KKyNlbHNlCisjaW5jbHVkZSA8dW5pc3RkLmg+CisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisjaW5jbHVkZSA8c3lzL3N0YXQuaD4KKyNpbmNsdWRlIDxmY250bC5oPgorI2VuZGlmCisjaW5jbHVkZSA8ZXJybm8uaD4KKyNpbmNsdWRlIDxpb3N0cmVhbT4KKyNpbmNsdWRlIDxhbGdvcml0aG0+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbV9pbXBsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9sb2dnaW5nLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0bF91dGlsLmg+CisKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGlvIHsKKworI2lmZGVmIF9XSU4zMgorLy8gV2luMzIgbHNlZWsgaXMgYnJva2VuOiAgSWYgaW52b2tlZCBvbiBhIG5vbi1zZWVrYWJsZSBmaWxlIGRlc2NyaXB0b3IsIGl0cworLy8gcmV0dXJuIHZhbHVlIGlzIHVuZGVmaW5lZC4gIFdlIHJlLWRlZmluZSBpdCB0byBhbHdheXMgcHJvZHVjZSBhbiBlcnJvci4KKyNkZWZpbmUgbHNlZWsoZmQsIG9mZnNldCwgb3JpZ2luKSAoKG9mZl90KS0xKQorI2VuZGlmCisKK25hbWVzcGFjZSB7CisKKy8vIEVJTlRSIHN1Y2tzLgoraW50IGNsb3NlX25vX2VpbnRyKGludCBmZCkgeworICBpbnQgcmVzdWx0OworICBkbyB7CisgICAgcmVzdWx0ID0gY2xvc2UoZmQpOworICB9IHdoaWxlIChyZXN1bHQgPCAwICYmIGVycm5vID09IEVJTlRSKTsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworfSAgLy8gbmFtZXNwYWNlCisKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitGaWxlSW5wdXRTdHJlYW06OkZpbGVJbnB1dFN0cmVhbShpbnQgZmlsZV9kZXNjcmlwdG9yLCBpbnQgYmxvY2tfc2l6ZSkKKyAgOiBjb3B5aW5nX2lucHV0XyhmaWxlX2Rlc2NyaXB0b3IpLAorICAgIGltcGxfKCZjb3B5aW5nX2lucHV0XywgYmxvY2tfc2l6ZSkgeworfQorCitGaWxlSW5wdXRTdHJlYW06On5GaWxlSW5wdXRTdHJlYW0oKSB7fQorCitib29sIEZpbGVJbnB1dFN0cmVhbTo6Q2xvc2UoKSB7CisgIHJldHVybiBjb3B5aW5nX2lucHV0Xy5DbG9zZSgpOworfQorCitib29sIEZpbGVJbnB1dFN0cmVhbTo6TmV4dChjb25zdCB2b2lkKiogZGF0YSwgaW50KiBzaXplKSB7CisgIHJldHVybiBpbXBsXy5OZXh0KGRhdGEsIHNpemUpOworfQorCit2b2lkIEZpbGVJbnB1dFN0cmVhbTo6QmFja1VwKGludCBjb3VudCkgeworICBpbXBsXy5CYWNrVXAoY291bnQpOworfQorCitib29sIEZpbGVJbnB1dFN0cmVhbTo6U2tpcChpbnQgY291bnQpIHsKKyAgcmV0dXJuIGltcGxfLlNraXAoY291bnQpOworfQorCitpbnQ2NCBGaWxlSW5wdXRTdHJlYW06OkJ5dGVDb3VudCgpIGNvbnN0IHsKKyAgcmV0dXJuIGltcGxfLkJ5dGVDb3VudCgpOworfQorCitGaWxlSW5wdXRTdHJlYW06OkNvcHlpbmdGaWxlSW5wdXRTdHJlYW06OkNvcHlpbmdGaWxlSW5wdXRTdHJlYW0oCisgICAgaW50IGZpbGVfZGVzY3JpcHRvcikKKyAgOiBmaWxlXyhmaWxlX2Rlc2NyaXB0b3IpLAorICAgIGNsb3NlX29uX2RlbGV0ZV8oZmFsc2UpLAorICAgIGlzX2Nsb3NlZF8oZmFsc2UpLAorICAgIGVycm5vXygwKSwKKyAgICBwcmV2aW91c19zZWVrX2ZhaWxlZF8oZmFsc2UpIHsKK30KKworRmlsZUlucHV0U3RyZWFtOjpDb3B5aW5nRmlsZUlucHV0U3RyZWFtOjp+Q29weWluZ0ZpbGVJbnB1dFN0cmVhbSgpIHsKKyAgaWYgKGNsb3NlX29uX2RlbGV0ZV8pIHsKKyAgICBpZiAoIUNsb3NlKCkpIHsKKyAgICAgIEdPT0dMRV9MT0coRVJST1IpIDw8ICJjbG9zZSgpIGZhaWxlZDogIiA8PCBzdHJlcnJvcihlcnJub18pOworICAgIH0KKyAgfQorfQorCitib29sIEZpbGVJbnB1dFN0cmVhbTo6Q29weWluZ0ZpbGVJbnB1dFN0cmVhbTo6Q2xvc2UoKSB7CisgIEdPT0dMRV9DSEVDSyghaXNfY2xvc2VkXyk7CisKKyAgaXNfY2xvc2VkXyA9IHRydWU7CisgIGlmIChjbG9zZV9ub19laW50cihmaWxlXykgIT0gMCkgeworICAgIC8vIFRoZSBkb2NzIG9uIGNsb3NlKCkgZG8gbm90IHNwZWNpZnkgd2hldGhlciBhIGZpbGUgZGVzY3JpcHRvciBpcyBzdGlsbAorICAgIC8vIG9wZW4gYWZ0ZXIgY2xvc2UoKSBmYWlscyB3aXRoIEVJTy4gIEhvd2V2ZXIsIHRoZSBnbGliYyBzb3VyY2UgY29kZQorICAgIC8vIHNlZW1zIHRvIGluZGljYXRlIHRoYXQgaXQgaXMgbm90LgorICAgIGVycm5vXyA9IGVycm5vOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIHJldHVybiB0cnVlOworfQorCitpbnQgRmlsZUlucHV0U3RyZWFtOjpDb3B5aW5nRmlsZUlucHV0U3RyZWFtOjpSZWFkKHZvaWQqIGJ1ZmZlciwgaW50IHNpemUpIHsKKyAgR09PR0xFX0NIRUNLKCFpc19jbG9zZWRfKTsKKworICBpbnQgcmVzdWx0OworICBkbyB7CisgICAgcmVzdWx0ID0gcmVhZChmaWxlXywgYnVmZmVyLCBzaXplKTsKKyAgfSB3aGlsZSAocmVzdWx0IDwgMCAmJiBlcnJubyA9PSBFSU5UUik7CisKKyAgaWYgKHJlc3VsdCA8IDApIHsKKyAgICAvLyBSZWFkIGVycm9yIChub3QgRU9GKS4KKyAgICBlcnJub18gPSBlcnJubzsKKyAgfQorCisgIHJldHVybiByZXN1bHQ7Cit9CisKK2ludCBGaWxlSW5wdXRTdHJlYW06OkNvcHlpbmdGaWxlSW5wdXRTdHJlYW06OlNraXAoaW50IGNvdW50KSB7CisgIEdPT0dMRV9DSEVDSyghaXNfY2xvc2VkXyk7CisKKyAgaWYgKCFwcmV2aW91c19zZWVrX2ZhaWxlZF8gJiYKKyAgICAgIGxzZWVrKGZpbGVfLCBjb3VudCwgU0VFS19DVVIpICE9IChvZmZfdCktMSkgeworICAgIC8vIFNlZWsgc3VjY2VlZGVkLgorICAgIHJldHVybiBjb3VudDsKKyAgfSBlbHNlIHsKKyAgICAvLyBGYWlsZWQgdG8gc2Vlay4KKworICAgIC8vIE5vdGUgdG8gc2VsZjogIERvbid0IHNlZWsgYWdhaW4uICBUaGlzIGZpbGUgZGVzY3JpcHRvciBkb2Vzbid0CisgICAgLy8gc3VwcG9ydCBpdC4KKyAgICBwcmV2aW91c19zZWVrX2ZhaWxlZF8gPSB0cnVlOworCisgICAgLy8gVXNlIHRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uLgorICAgIHJldHVybiBDb3B5aW5nSW5wdXRTdHJlYW06OlNraXAoY291bnQpOworICB9Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworRmlsZU91dHB1dFN0cmVhbTo6RmlsZU91dHB1dFN0cmVhbShpbnQgZmlsZV9kZXNjcmlwdG9yLCBpbnQgYmxvY2tfc2l6ZSkKKyAgOiBjb3B5aW5nX291dHB1dF8oZmlsZV9kZXNjcmlwdG9yKSwKKyAgICBpbXBsXygmY29weWluZ19vdXRwdXRfLCBibG9ja19zaXplKSB7Cit9CisKK0ZpbGVPdXRwdXRTdHJlYW06On5GaWxlT3V0cHV0U3RyZWFtKCkgeworICBpbXBsXy5GbHVzaCgpOworfQorCitib29sIEZpbGVPdXRwdXRTdHJlYW06OkNsb3NlKCkgeworICBib29sIGZsdXNoX3N1Y2NlZWRlZCA9IGltcGxfLkZsdXNoKCk7CisgIHJldHVybiBjb3B5aW5nX291dHB1dF8uQ2xvc2UoKSAmJiBmbHVzaF9zdWNjZWVkZWQ7Cit9CisKK2Jvb2wgRmlsZU91dHB1dFN0cmVhbTo6Rmx1c2goKSB7CisgIHJldHVybiBpbXBsXy5GbHVzaCgpOworfQorCitib29sIEZpbGVPdXRwdXRTdHJlYW06Ok5leHQodm9pZCoqIGRhdGEsIGludCogc2l6ZSkgeworICByZXR1cm4gaW1wbF8uTmV4dChkYXRhLCBzaXplKTsKK30KKwordm9pZCBGaWxlT3V0cHV0U3RyZWFtOjpCYWNrVXAoaW50IGNvdW50KSB7CisgIGltcGxfLkJhY2tVcChjb3VudCk7Cit9CisKK2ludDY0IEZpbGVPdXRwdXRTdHJlYW06OkJ5dGVDb3VudCgpIGNvbnN0IHsKKyAgcmV0dXJuIGltcGxfLkJ5dGVDb3VudCgpOworfQorCitGaWxlT3V0cHV0U3RyZWFtOjpDb3B5aW5nRmlsZU91dHB1dFN0cmVhbTo6Q29weWluZ0ZpbGVPdXRwdXRTdHJlYW0oCisgICAgaW50IGZpbGVfZGVzY3JpcHRvcikKKyAgOiBmaWxlXyhmaWxlX2Rlc2NyaXB0b3IpLAorICAgIGNsb3NlX29uX2RlbGV0ZV8oZmFsc2UpLAorICAgIGlzX2Nsb3NlZF8oZmFsc2UpLAorICAgIGVycm5vXygwKSB7Cit9CisKK0ZpbGVPdXRwdXRTdHJlYW06OkNvcHlpbmdGaWxlT3V0cHV0U3RyZWFtOjp+Q29weWluZ0ZpbGVPdXRwdXRTdHJlYW0oKSB7CisgIGlmIChjbG9zZV9vbl9kZWxldGVfKSB7CisgICAgaWYgKCFDbG9zZSgpKSB7CisgICAgICBHT09HTEVfTE9HKEVSUk9SKSA8PCAiY2xvc2UoKSBmYWlsZWQ6ICIgPDwgc3RyZXJyb3IoZXJybm9fKTsKKyAgICB9CisgIH0KK30KKworYm9vbCBGaWxlT3V0cHV0U3RyZWFtOjpDb3B5aW5nRmlsZU91dHB1dFN0cmVhbTo6Q2xvc2UoKSB7CisgIEdPT0dMRV9DSEVDSyghaXNfY2xvc2VkXyk7CisKKyAgaXNfY2xvc2VkXyA9IHRydWU7CisgIGlmIChjbG9zZV9ub19laW50cihmaWxlXykgIT0gMCkgeworICAgIC8vIFRoZSBkb2NzIG9uIGNsb3NlKCkgZG8gbm90IHNwZWNpZnkgd2hldGhlciBhIGZpbGUgZGVzY3JpcHRvciBpcyBzdGlsbAorICAgIC8vIG9wZW4gYWZ0ZXIgY2xvc2UoKSBmYWlscyB3aXRoIEVJTy4gIEhvd2V2ZXIsIHRoZSBnbGliYyBzb3VyY2UgY29kZQorICAgIC8vIHNlZW1zIHRvIGluZGljYXRlIHRoYXQgaXQgaXMgbm90LgorICAgIGVycm5vXyA9IGVycm5vOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIHJldHVybiB0cnVlOworfQorCitib29sIEZpbGVPdXRwdXRTdHJlYW06OkNvcHlpbmdGaWxlT3V0cHV0U3RyZWFtOjpXcml0ZSgKKyAgICBjb25zdCB2b2lkKiBidWZmZXIsIGludCBzaXplKSB7CisgIEdPT0dMRV9DSEVDSyghaXNfY2xvc2VkXyk7CisgIGludCB0b3RhbF93cml0dGVuID0gMDsKKworICBjb25zdCB1aW50OCogYnVmZmVyX2Jhc2UgPSByZWludGVycHJldF9jYXN0PGNvbnN0IHVpbnQ4Kj4oYnVmZmVyKTsKKworICB3aGlsZSAodG90YWxfd3JpdHRlbiA8IHNpemUpIHsKKyAgICBpbnQgYnl0ZXM7CisgICAgZG8geworICAgICAgYnl0ZXMgPSB3cml0ZShmaWxlXywgYnVmZmVyX2Jhc2UgKyB0b3RhbF93cml0dGVuLCBzaXplIC0gdG90YWxfd3JpdHRlbik7CisgICAgfSB3aGlsZSAoYnl0ZXMgPCAwICYmIGVycm5vID09IEVJTlRSKTsKKworICAgIGlmIChieXRlcyA8PSAwKSB7CisgICAgICAvLyBXcml0ZSBlcnJvci4KKworICAgICAgLy8gRklYTUUoa2VudG9uKTogIEFjY29yZGluZyB0byB0aGUgbWFuIHBhZ2UsIGlmIHdyaXRlKCkgcmV0dXJucyB6ZXJvLAorICAgICAgLy8gICB0aGVyZSB3YXMgbm8gZXJyb3I7IHdyaXRlKCkgc2ltcGx5IGRpZCBub3Qgd3JpdGUgYW55dGhpbmcuICBJdCdzCisgICAgICAvLyAgIHVuY2xlYXIgdW5kZXIgd2hhdCBjaXJjdW1zdGFuY2VzIHRoaXMgbWlnaHQgaGFwcGVuLCBidXQgcHJlc3VtYWJseQorICAgICAgLy8gICBlcnJubyB3b24ndCBiZSBzZXQgaW4gdGhpcyBjYXNlLiAgSSBhbSBjb25mdXNlZCBhcyB0byBob3cgc3VjaCBhbgorICAgICAgLy8gICBldmVudCBzaG91bGQgYmUgaGFuZGxlZC4gIEZvciBub3cgSSdtIHRyZWF0aW5nIGl0IGFzIGFuIGVycm9yLCBzaW5jZQorICAgICAgLy8gICByZXRyeWluZyBzZWVtcyBsaWtlIGl0IGNvdWxkIGxlYWQgdG8gYW4gaW5maW5pdGUgbG9vcC4gIEkgc3VzcGVjdAorICAgICAgLy8gICB0aGlzIG5ldmVyIGFjdHVhbGx5IGhhcHBlbnMgYW55d2F5LgorCisgICAgICBpZiAoYnl0ZXMgPCAwKSB7CisgICAgICAgIGVycm5vXyA9IGVycm5vOworICAgICAgfQorICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICB0b3RhbF93cml0dGVuICs9IGJ5dGVzOworICB9CisKKyAgcmV0dXJuIHRydWU7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworSXN0cmVhbUlucHV0U3RyZWFtOjpJc3RyZWFtSW5wdXRTdHJlYW0oaXN0cmVhbSogaW5wdXQsIGludCBibG9ja19zaXplKQorICA6IGNvcHlpbmdfaW5wdXRfKGlucHV0KSwKKyAgICBpbXBsXygmY29weWluZ19pbnB1dF8sIGJsb2NrX3NpemUpIHsKK30KKworSXN0cmVhbUlucHV0U3RyZWFtOjp+SXN0cmVhbUlucHV0U3RyZWFtKCkge30KKworYm9vbCBJc3RyZWFtSW5wdXRTdHJlYW06Ok5leHQoY29uc3Qgdm9pZCoqIGRhdGEsIGludCogc2l6ZSkgeworICByZXR1cm4gaW1wbF8uTmV4dChkYXRhLCBzaXplKTsKK30KKwordm9pZCBJc3RyZWFtSW5wdXRTdHJlYW06OkJhY2tVcChpbnQgY291bnQpIHsKKyAgaW1wbF8uQmFja1VwKGNvdW50KTsKK30KKworYm9vbCBJc3RyZWFtSW5wdXRTdHJlYW06OlNraXAoaW50IGNvdW50KSB7CisgIHJldHVybiBpbXBsXy5Ta2lwKGNvdW50KTsKK30KKworaW50NjQgSXN0cmVhbUlucHV0U3RyZWFtOjpCeXRlQ291bnQoKSBjb25zdCB7CisgIHJldHVybiBpbXBsXy5CeXRlQ291bnQoKTsKK30KKworSXN0cmVhbUlucHV0U3RyZWFtOjpDb3B5aW5nSXN0cmVhbUlucHV0U3RyZWFtOjpDb3B5aW5nSXN0cmVhbUlucHV0U3RyZWFtKAorICAgIGlzdHJlYW0qIGlucHV0KQorICA6IGlucHV0XyhpbnB1dCkgeworfQorCitJc3RyZWFtSW5wdXRTdHJlYW06OkNvcHlpbmdJc3RyZWFtSW5wdXRTdHJlYW06On5Db3B5aW5nSXN0cmVhbUlucHV0U3RyZWFtKCkge30KKworaW50IElzdHJlYW1JbnB1dFN0cmVhbTo6Q29weWluZ0lzdHJlYW1JbnB1dFN0cmVhbTo6UmVhZCgKKyAgICB2b2lkKiBidWZmZXIsIGludCBzaXplKSB7CisgIGlucHV0Xy0+cmVhZChyZWludGVycHJldF9jYXN0PGNoYXIqPihidWZmZXIpLCBzaXplKTsKKyAgaW50IHJlc3VsdCA9IGlucHV0Xy0+Z2NvdW50KCk7CisgIGlmIChyZXN1bHQgPT0gMCAmJiBpbnB1dF8tPmZhaWwoKSAmJiAhaW5wdXRfLT5lb2YoKSkgeworICAgIHJldHVybiAtMTsKKyAgfQorICByZXR1cm4gcmVzdWx0OworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK09zdHJlYW1PdXRwdXRTdHJlYW06Ok9zdHJlYW1PdXRwdXRTdHJlYW0ob3N0cmVhbSogb3V0cHV0LCBpbnQgYmxvY2tfc2l6ZSkKKyAgOiBjb3B5aW5nX291dHB1dF8ob3V0cHV0KSwKKyAgICBpbXBsXygmY29weWluZ19vdXRwdXRfLCBibG9ja19zaXplKSB7Cit9CisKK09zdHJlYW1PdXRwdXRTdHJlYW06On5Pc3RyZWFtT3V0cHV0U3RyZWFtKCkgeworICBpbXBsXy5GbHVzaCgpOworfQorCitib29sIE9zdHJlYW1PdXRwdXRTdHJlYW06Ok5leHQodm9pZCoqIGRhdGEsIGludCogc2l6ZSkgeworICByZXR1cm4gaW1wbF8uTmV4dChkYXRhLCBzaXplKTsKK30KKwordm9pZCBPc3RyZWFtT3V0cHV0U3RyZWFtOjpCYWNrVXAoaW50IGNvdW50KSB7CisgIGltcGxfLkJhY2tVcChjb3VudCk7Cit9CisKK2ludDY0IE9zdHJlYW1PdXRwdXRTdHJlYW06OkJ5dGVDb3VudCgpIGNvbnN0IHsKKyAgcmV0dXJuIGltcGxfLkJ5dGVDb3VudCgpOworfQorCitPc3RyZWFtT3V0cHV0U3RyZWFtOjpDb3B5aW5nT3N0cmVhbU91dHB1dFN0cmVhbTo6Q29weWluZ09zdHJlYW1PdXRwdXRTdHJlYW0oCisgICAgb3N0cmVhbSogb3V0cHV0KQorICA6IG91dHB1dF8ob3V0cHV0KSB7Cit9CisKK09zdHJlYW1PdXRwdXRTdHJlYW06OkNvcHlpbmdPc3RyZWFtT3V0cHV0U3RyZWFtOjp+Q29weWluZ09zdHJlYW1PdXRwdXRTdHJlYW0oKSB7Cit9CisKK2Jvb2wgT3N0cmVhbU91dHB1dFN0cmVhbTo6Q29weWluZ09zdHJlYW1PdXRwdXRTdHJlYW06OldyaXRlKAorICAgIGNvbnN0IHZvaWQqIGJ1ZmZlciwgaW50IHNpemUpIHsKKyAgb3V0cHV0Xy0+d3JpdGUocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4oYnVmZmVyKSwgc2l6ZSk7CisgIHJldHVybiBvdXRwdXRfLT5nb29kKCk7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworQ29uY2F0ZW5hdGluZ0lucHV0U3RyZWFtOjpDb25jYXRlbmF0aW5nSW5wdXRTdHJlYW0oCisgICAgWmVyb0NvcHlJbnB1dFN0cmVhbSogY29uc3Qgc3RyZWFtc1tdLCBpbnQgY291bnQpCisgIDogc3RyZWFtc18oc3RyZWFtcyksIHN0cmVhbV9jb3VudF8oY291bnQpLCBieXRlc19yZXRpcmVkXygwKSB7Cit9CisKK0NvbmNhdGVuYXRpbmdJbnB1dFN0cmVhbTo6fkNvbmNhdGVuYXRpbmdJbnB1dFN0cmVhbSgpIHsKK30KKworYm9vbCBDb25jYXRlbmF0aW5nSW5wdXRTdHJlYW06Ok5leHQoY29uc3Qgdm9pZCoqIGRhdGEsIGludCogc2l6ZSkgeworICB3aGlsZSAoc3RyZWFtX2NvdW50XyA+IDApIHsKKyAgICBpZiAoc3RyZWFtc19bMF0tPk5leHQoZGF0YSwgc2l6ZSkpIHJldHVybiB0cnVlOworCisgICAgLy8gVGhhdCBzdHJlYW0gaXMgZG9uZS4gIEFkdmFuY2UgdG8gdGhlIG5leHQgb25lLgorICAgIGJ5dGVzX3JldGlyZWRfICs9IHN0cmVhbXNfWzBdLT5CeXRlQ291bnQoKTsKKyAgICArK3N0cmVhbXNfOworICAgIC0tc3RyZWFtX2NvdW50XzsKKyAgfQorCisgIC8vIE5vIG1vcmUgc3RyZWFtcy4KKyAgcmV0dXJuIGZhbHNlOworfQorCit2b2lkIENvbmNhdGVuYXRpbmdJbnB1dFN0cmVhbTo6QmFja1VwKGludCBjb3VudCkgeworICBpZiAoc3RyZWFtX2NvdW50XyA+IDApIHsKKyAgICBzdHJlYW1zX1swXS0+QmFja1VwKGNvdW50KTsKKyAgfSBlbHNlIHsKKyAgICBHT09HTEVfTE9HKERGQVRBTCkgPDwgIkNhbid0IEJhY2tVcCgpIGFmdGVyIGZhaWxlZCBOZXh0KCkuIjsKKyAgfQorfQorCitib29sIENvbmNhdGVuYXRpbmdJbnB1dFN0cmVhbTo6U2tpcChpbnQgY291bnQpIHsKKyAgd2hpbGUgKHN0cmVhbV9jb3VudF8gPiAwKSB7CisgICAgLy8gQXNzdW1lIHRoYXQgQnl0ZUNvdW50KCkgY2FuIGJlIHVzZWQgdG8gZmluZCBvdXQgaG93IG11Y2ggd2UgYWN0dWFsbHkKKyAgICAvLyBza2lwcGVkIHdoZW4gU2tpcCgpIGZhaWxzLgorICAgIGludDY0IHRhcmdldF9ieXRlX2NvdW50ID0gc3RyZWFtc19bMF0tPkJ5dGVDb3VudCgpICsgY291bnQ7CisgICAgaWYgKHN0cmVhbXNfWzBdLT5Ta2lwKGNvdW50KSkgcmV0dXJuIHRydWU7CisKKyAgICAvLyBIaXQgdGhlIGVuZCBvZiB0aGUgc3RyZWFtLiAgRmlndXJlIG91dCBob3cgbWFueSBtb3JlIGJ5dGVzIHdlIHN0aWxsIGhhdmUKKyAgICAvLyB0byBza2lwLgorICAgIGludDY0IGZpbmFsX2J5dGVfY291bnQgPSBzdHJlYW1zX1swXS0+Qnl0ZUNvdW50KCk7CisgICAgR09PR0xFX0RDSEVDS19MVChmaW5hbF9ieXRlX2NvdW50LCB0YXJnZXRfYnl0ZV9jb3VudCk7CisgICAgY291bnQgPSB0YXJnZXRfYnl0ZV9jb3VudCAtIGZpbmFsX2J5dGVfY291bnQ7CisKKyAgICAvLyBUaGF0IHN0cmVhbSBpcyBkb25lLiAgQWR2YW5jZSB0byB0aGUgbmV4dCBvbmUuCisgICAgYnl0ZXNfcmV0aXJlZF8gKz0gZmluYWxfYnl0ZV9jb3VudDsKKyAgICArK3N0cmVhbXNfOworICAgIC0tc3RyZWFtX2NvdW50XzsKKyAgfQorCisgIHJldHVybiBmYWxzZTsKK30KKworaW50NjQgQ29uY2F0ZW5hdGluZ0lucHV0U3RyZWFtOjpCeXRlQ291bnQoKSBjb25zdCB7CisgIGlmIChzdHJlYW1fY291bnRfID09IDApIHsKKyAgICByZXR1cm4gYnl0ZXNfcmV0aXJlZF87CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIGJ5dGVzX3JldGlyZWRfICsgc3RyZWFtc19bMF0tPkJ5dGVDb3VudCgpOworICB9Cit9CisKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitMaW1pdGluZ0lucHV0U3RyZWFtOjpMaW1pdGluZ0lucHV0U3RyZWFtKFplcm9Db3B5SW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQ2NCBsaW1pdCkKKyAgOiBpbnB1dF8oaW5wdXQpLCBsaW1pdF8obGltaXQpIHsKKyAgcHJpb3JfYnl0ZXNfcmVhZF8gPSBpbnB1dF8tPkJ5dGVDb3VudCgpOworfQorCitMaW1pdGluZ0lucHV0U3RyZWFtOjp+TGltaXRpbmdJbnB1dFN0cmVhbSgpIHsKKyAgLy8gSWYgd2Ugb3ZlcnNob3QgdGhlIGxpbWl0LCBiYWNrIHVwLgorICBpZiAobGltaXRfIDwgMCkgaW5wdXRfLT5CYWNrVXAoLWxpbWl0Xyk7Cit9CisKK2Jvb2wgTGltaXRpbmdJbnB1dFN0cmVhbTo6TmV4dChjb25zdCB2b2lkKiogZGF0YSwgaW50KiBzaXplKSB7CisgIGlmIChsaW1pdF8gPD0gMCkgcmV0dXJuIGZhbHNlOworICBpZiAoIWlucHV0Xy0+TmV4dChkYXRhLCBzaXplKSkgcmV0dXJuIGZhbHNlOworCisgIGxpbWl0XyAtPSAqc2l6ZTsKKyAgaWYgKGxpbWl0XyA8IDApIHsKKyAgICAvLyBXZSBvdmVyc2hvdCB0aGUgbGltaXQuICBSZWR1Y2UgKnNpemUgdG8gaGlkZSB0aGUgcmVzdCBvZiB0aGUgYnVmZmVyLgorICAgICpzaXplICs9IGxpbWl0XzsKKyAgfQorICByZXR1cm4gdHJ1ZTsKK30KKwordm9pZCBMaW1pdGluZ0lucHV0U3RyZWFtOjpCYWNrVXAoaW50IGNvdW50KSB7CisgIGlmIChsaW1pdF8gPCAwKSB7CisgICAgaW5wdXRfLT5CYWNrVXAoY291bnQgLSBsaW1pdF8pOworICAgIGxpbWl0XyA9IGNvdW50OworICB9IGVsc2UgeworICAgIGlucHV0Xy0+QmFja1VwKGNvdW50KTsKKyAgICBsaW1pdF8gKz0gY291bnQ7CisgIH0KK30KKworYm9vbCBMaW1pdGluZ0lucHV0U3RyZWFtOjpTa2lwKGludCBjb3VudCkgeworICBpZiAoY291bnQgPiBsaW1pdF8pIHsKKyAgICBpZiAobGltaXRfIDwgMCkgcmV0dXJuIGZhbHNlOworICAgIGlucHV0Xy0+U2tpcChsaW1pdF8pOworICAgIGxpbWl0XyA9IDA7CisgICAgcmV0dXJuIGZhbHNlOworICB9IGVsc2UgeworICAgIGlmICghaW5wdXRfLT5Ta2lwKGNvdW50KSkgcmV0dXJuIGZhbHNlOworICAgIGxpbWl0XyAtPSBjb3VudDsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorfQorCitpbnQ2NCBMaW1pdGluZ0lucHV0U3RyZWFtOjpCeXRlQ291bnQoKSBjb25zdCB7CisgIGlmIChsaW1pdF8gPCAwKSB7CisgICAgcmV0dXJuIGlucHV0Xy0+Qnl0ZUNvdW50KCkgKyBsaW1pdF8gLSBwcmlvcl9ieXRlc19yZWFkXzsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gaW5wdXRfLT5CeXRlQ291bnQoKSAtIHByaW9yX2J5dGVzX3JlYWRfOworICB9Cit9CisKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCit9ICAvLyBuYW1lc3BhY2UgaW8KK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX2ltcGwuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbV9pbXBsLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDc0NmZhNgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbV9pbXBsLmgKQEAgLTAsMCArMSwzNTggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBUaGlzIGZpbGUgY29udGFpbnMgY29tbW9uIGltcGxlbWVudGF0aW9ucyBvZiB0aGUgaW50ZXJmYWNlcyBkZWZpbmVkIGluCisvLyB6ZXJvX2NvcHlfc3RyZWFtLmggd2hpY2ggYXJlIG9ubHkgaW5jbHVkZWQgaW4gdGhlIGZ1bGwgKG5vbi1saXRlKQorLy8gcHJvdG9idWYgbGlicmFyeS4gIFRoZXNlIGltcGxlbWVudGF0aW9ucyBpbmNsdWRlIFVuaXggZmlsZSBkZXNjcmlwdG9ycworLy8gYW5kIEMrKyBpb3N0cmVhbXMuICBTZWUgYWxzbzogIHplcm9fY29weV9zdHJlYW1faW1wbF9saXRlLmgKKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfSU9fWkVST19DT1BZX1NUUkVBTV9JTVBMX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfSU9fWkVST19DT1BZX1NUUkVBTV9JTVBMX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGlvc2Z3ZD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX2ltcGxfbGl0ZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKworCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW8geworCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworLy8gQSBaZXJvQ29weUlucHV0U3RyZWFtIHdoaWNoIHJlYWRzIGZyb20gYSBmaWxlIGRlc2NyaXB0b3IuCisvLworLy8gRmlsZUlucHV0U3RyZWFtIGlzIHByZWZlcnJlZCBvdmVyIHVzaW5nIGFuIGlmc3RyZWFtIHdpdGggSXN0cmVhbUlucHV0U3RyZWFtLgorLy8gVGhlIGxhdHRlciB3aWxsIGludHJvZHVjZSBhbiBleHRyYSBsYXllciBvZiBidWZmZXJpbmcsIGhhcm1pbmcgcGVyZm9ybWFuY2UuCisvLyBBbHNvLCBpdCdzIGNvbmNlaXZhYmxlIHRoYXQgRmlsZUlucHV0U3RyZWFtIGNvdWxkIHNvbWVkYXkgYmUgZW5oYW5jZWQKKy8vIHRvIHVzZSB6ZXJvLWNvcHkgZmlsZSBkZXNjcmlwdG9ycyBvbiBPU3Mgd2hpY2ggc3VwcG9ydCB0aGVtLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEZpbGVJbnB1dFN0cmVhbSA6IHB1YmxpYyBaZXJvQ29weUlucHV0U3RyZWFtIHsKKyBwdWJsaWM6CisgIC8vIENyZWF0ZXMgYSBzdHJlYW0gdGhhdCByZWFkcyBmcm9tIHRoZSBnaXZlbiBVbml4IGZpbGUgZGVzY3JpcHRvci4KKyAgLy8gSWYgYSBibG9ja19zaXplIGlzIGdpdmVuLCBpdCBzcGVjaWZpZXMgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0CisgIC8vIHNob3VsZCBiZSByZWFkIGFuZCByZXR1cm5lZCB3aXRoIGVhY2ggY2FsbCB0byBOZXh0KCkuICBPdGhlcndpc2UsCisgIC8vIGEgcmVhc29uYWJsZSBkZWZhdWx0IGlzIHVzZWQuCisgIGV4cGxpY2l0IEZpbGVJbnB1dFN0cmVhbShpbnQgZmlsZV9kZXNjcmlwdG9yLCBpbnQgYmxvY2tfc2l6ZSA9IC0xKTsKKyAgfkZpbGVJbnB1dFN0cmVhbSgpOworCisgIC8vIEZsdXNoZXMgYW55IGJ1ZmZlcnMgYW5kIGNsb3NlcyB0aGUgdW5kZXJseWluZyBmaWxlLiAgUmV0dXJucyBmYWxzZSBpZgorICAvLyBhbiBlcnJvciBvY2N1cnMgZHVyaW5nIHRoZSBwcm9jZXNzOyB1c2UgR2V0RXJybm8oKSB0byBleGFtaW5lIHRoZSBlcnJvci4KKyAgLy8gRXZlbiBpZiBhbiBlcnJvciBvY2N1cnMsIHRoZSBmaWxlIGRlc2NyaXB0b3IgaXMgY2xvc2VkIHdoZW4gdGhpcyByZXR1cm5zLgorICBib29sIENsb3NlKCk7CisKKyAgLy8gQnkgZGVmYXVsdCwgdGhlIGZpbGUgZGVzY3JpcHRvciBpcyBub3QgY2xvc2VkIHdoZW4gdGhlIHN0cmVhbSBpcworICAvLyBkZXN0cm95ZWQuICBDYWxsIFNldENsb3NlT25EZWxldGUodHJ1ZSkgdG8gY2hhbmdlIHRoYXQuICBXQVJOSU5HOgorICAvLyBUaGlzIGxlYXZlcyBubyB3YXkgZm9yIHRoZSBjYWxsZXIgdG8gZGV0ZWN0IGlmIGNsb3NlKCkgZmFpbHMuICBJZgorICAvLyBkZXRlY3RpbmcgY2xvc2UoKSBlcnJvcnMgaXMgaW1wb3J0YW50IHRvIHlvdSwgeW91IHNob3VsZCBhcnJhbmdlCisgIC8vIHRvIGNsb3NlIHRoZSBkZXNjcmlwdG9yIHlvdXJzZWxmLgorICB2b2lkIFNldENsb3NlT25EZWxldGUoYm9vbCB2YWx1ZSkgeyBjb3B5aW5nX2lucHV0Xy5TZXRDbG9zZU9uRGVsZXRlKHZhbHVlKTsgfQorCisgIC8vIElmIGFuIEkvTyBlcnJvciBoYXMgb2NjdXJyZWQgb24gdGhpcyBmaWxlIGRlc2NyaXB0b3IsIHRoaXMgaXMgdGhlCisgIC8vIGVycm5vIGZyb20gdGhhdCBlcnJvci4gIE90aGVyd2lzZSwgdGhpcyBpcyB6ZXJvLiAgT25jZSBhbiBlcnJvcgorICAvLyBvY2N1cnMsIHRoZSBzdHJlYW0gaXMgYnJva2VuIGFuZCBhbGwgc3Vic2VxdWVudCBvcGVyYXRpb25zIHdpbGwKKyAgLy8gZmFpbC4KKyAgaW50IEdldEVycm5vKCkgeyByZXR1cm4gY29weWluZ19pbnB1dF8uR2V0RXJybm8oKTsgfQorCisgIC8vIGltcGxlbWVudHMgWmVyb0NvcHlJbnB1dFN0cmVhbSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIGJvb2wgTmV4dChjb25zdCB2b2lkKiogZGF0YSwgaW50KiBzaXplKTsKKyAgdm9pZCBCYWNrVXAoaW50IGNvdW50KTsKKyAgYm9vbCBTa2lwKGludCBjb3VudCk7CisgIGludDY0IEJ5dGVDb3VudCgpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIENvcHlpbmdGaWxlSW5wdXRTdHJlYW0gOiBwdWJsaWMgQ29weWluZ0lucHV0U3RyZWFtIHsKKyAgIHB1YmxpYzoKKyAgICBDb3B5aW5nRmlsZUlucHV0U3RyZWFtKGludCBmaWxlX2Rlc2NyaXB0b3IpOworICAgIH5Db3B5aW5nRmlsZUlucHV0U3RyZWFtKCk7CisKKyAgICBib29sIENsb3NlKCk7CisgICAgdm9pZCBTZXRDbG9zZU9uRGVsZXRlKGJvb2wgdmFsdWUpIHsgY2xvc2Vfb25fZGVsZXRlXyA9IHZhbHVlOyB9CisgICAgaW50IEdldEVycm5vKCkgeyByZXR1cm4gZXJybm9fOyB9CisKKyAgICAvLyBpbXBsZW1lbnRzIENvcHlpbmdJbnB1dFN0cmVhbSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICBpbnQgUmVhZCh2b2lkKiBidWZmZXIsIGludCBzaXplKTsKKyAgICBpbnQgU2tpcChpbnQgY291bnQpOworCisgICBwcml2YXRlOgorICAgIC8vIFRoZSBmaWxlIGRlc2NyaXB0b3IuCisgICAgY29uc3QgaW50IGZpbGVfOworICAgIGJvb2wgY2xvc2Vfb25fZGVsZXRlXzsKKyAgICBib29sIGlzX2Nsb3NlZF87CisKKyAgICAvLyBUaGUgZXJybm8gb2YgdGhlIEkvTyBlcnJvciwgaWYgb25lIGhhcyBvY2N1cnJlZC4gIE90aGVyd2lzZSwgemVyby4KKyAgICBpbnQgZXJybm9fOworCisgICAgLy8gRGlkIHdlIHRyeSB0byBzZWVrIG9uY2UgYW5kIGZhaWw/ICBJZiBzbywgd2UgYXNzdW1lIHRoaXMgZmlsZSBkZXNjcmlwdG9yCisgICAgLy8gZG9lc24ndCBzdXBwb3J0IHNlZWtpbmcgYW5kIHdvbid0IHRyeSBhZ2Fpbi4KKyAgICBib29sIHByZXZpb3VzX3NlZWtfZmFpbGVkXzsKKworICAgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhDb3B5aW5nRmlsZUlucHV0U3RyZWFtKTsKKyAgfTsKKworICBDb3B5aW5nRmlsZUlucHV0U3RyZWFtIGNvcHlpbmdfaW5wdXRfOworICBDb3B5aW5nSW5wdXRTdHJlYW1BZGFwdG9yIGltcGxfOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhGaWxlSW5wdXRTdHJlYW0pOworfTsKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisvLyBBIFplcm9Db3B5T3V0cHV0U3RyZWFtIHdoaWNoIHdyaXRlcyB0byBhIGZpbGUgZGVzY3JpcHRvci4KKy8vCisvLyBGaWxlT3V0cHV0U3RyZWFtIGlzIHByZWZlcnJlZCBvdmVyIHVzaW5nIGFuIG9mc3RyZWFtIHdpdGgKKy8vIE9zdHJlYW1PdXRwdXRTdHJlYW0uICBUaGUgbGF0dGVyIHdpbGwgaW50cm9kdWNlIGFuIGV4dHJhIGxheWVyIG9mIGJ1ZmZlcmluZywKKy8vIGhhcm1pbmcgcGVyZm9ybWFuY2UuICBBbHNvLCBpdCdzIGNvbmNlaXZhYmxlIHRoYXQgRmlsZU91dHB1dFN0cmVhbSBjb3VsZAorLy8gc29tZWRheSBiZSBlbmhhbmNlZCB0byB1c2UgemVyby1jb3B5IGZpbGUgZGVzY3JpcHRvcnMgb24gT1NzIHdoaWNoCisvLyBzdXBwb3J0IHRoZW0uCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgRmlsZU91dHB1dFN0cmVhbSA6IHB1YmxpYyBaZXJvQ29weU91dHB1dFN0cmVhbSB7CisgcHVibGljOgorICAvLyBDcmVhdGVzIGEgc3RyZWFtIHRoYXQgd3JpdGVzIHRvIHRoZSBnaXZlbiBVbml4IGZpbGUgZGVzY3JpcHRvci4KKyAgLy8gSWYgYSBibG9ja19zaXplIGlzIGdpdmVuLCBpdCBzcGVjaWZpZXMgdGhlIHNpemUgb2YgdGhlIGJ1ZmZlcnMKKyAgLy8gdGhhdCBzaG91bGQgYmUgcmV0dXJuZWQgYnkgTmV4dCgpLiAgT3RoZXJ3aXNlLCBhIHJlYXNvbmFibGUgZGVmYXVsdAorICAvLyBpcyB1c2VkLgorICBleHBsaWNpdCBGaWxlT3V0cHV0U3RyZWFtKGludCBmaWxlX2Rlc2NyaXB0b3IsIGludCBibG9ja19zaXplID0gLTEpOworICB+RmlsZU91dHB1dFN0cmVhbSgpOworCisgIC8vIEZsdXNoZXMgYW55IGJ1ZmZlcnMgYW5kIGNsb3NlcyB0aGUgdW5kZXJseWluZyBmaWxlLiAgUmV0dXJucyBmYWxzZSBpZgorICAvLyBhbiBlcnJvciBvY2N1cnMgZHVyaW5nIHRoZSBwcm9jZXNzOyB1c2UgR2V0RXJybm8oKSB0byBleGFtaW5lIHRoZSBlcnJvci4KKyAgLy8gRXZlbiBpZiBhbiBlcnJvciBvY2N1cnMsIHRoZSBmaWxlIGRlc2NyaXB0b3IgaXMgY2xvc2VkIHdoZW4gdGhpcyByZXR1cm5zLgorICBib29sIENsb3NlKCk7CisKKyAgLy8gRmx1c2hlcyBGaWxlT3V0cHV0U3RyZWFtJ3MgYnVmZmVycyBidXQgZG9lcyBub3QgY2xvc2UgdGhlCisgIC8vIHVuZGVybHlpbmcgZmlsZS4gTm8gc3BlY2lhbCBtZWFzdXJlcyBhcmUgdGFrZW4gdG8gZW5zdXJlIHRoYXQKKyAgLy8gdW5kZXJseWluZyBvcGVyYXRpbmcgc3lzdGVtIGZpbGUgb2JqZWN0IGlzIHN5bmNocm9uaXplZCB0byBkaXNrLgorICBib29sIEZsdXNoKCk7CisKKyAgLy8gQnkgZGVmYXVsdCwgdGhlIGZpbGUgZGVzY3JpcHRvciBpcyBub3QgY2xvc2VkIHdoZW4gdGhlIHN0cmVhbSBpcworICAvLyBkZXN0cm95ZWQuICBDYWxsIFNldENsb3NlT25EZWxldGUodHJ1ZSkgdG8gY2hhbmdlIHRoYXQuICBXQVJOSU5HOgorICAvLyBUaGlzIGxlYXZlcyBubyB3YXkgZm9yIHRoZSBjYWxsZXIgdG8gZGV0ZWN0IGlmIGNsb3NlKCkgZmFpbHMuICBJZgorICAvLyBkZXRlY3RpbmcgY2xvc2UoKSBlcnJvcnMgaXMgaW1wb3J0YW50IHRvIHlvdSwgeW91IHNob3VsZCBhcnJhbmdlCisgIC8vIHRvIGNsb3NlIHRoZSBkZXNjcmlwdG9yIHlvdXJzZWxmLgorICB2b2lkIFNldENsb3NlT25EZWxldGUoYm9vbCB2YWx1ZSkgeyBjb3B5aW5nX291dHB1dF8uU2V0Q2xvc2VPbkRlbGV0ZSh2YWx1ZSk7IH0KKworICAvLyBJZiBhbiBJL08gZXJyb3IgaGFzIG9jY3VycmVkIG9uIHRoaXMgZmlsZSBkZXNjcmlwdG9yLCB0aGlzIGlzIHRoZQorICAvLyBlcnJubyBmcm9tIHRoYXQgZXJyb3IuICBPdGhlcndpc2UsIHRoaXMgaXMgemVyby4gIE9uY2UgYW4gZXJyb3IKKyAgLy8gb2NjdXJzLCB0aGUgc3RyZWFtIGlzIGJyb2tlbiBhbmQgYWxsIHN1YnNlcXVlbnQgb3BlcmF0aW9ucyB3aWxsCisgIC8vIGZhaWwuCisgIGludCBHZXRFcnJubygpIHsgcmV0dXJuIGNvcHlpbmdfb3V0cHV0Xy5HZXRFcnJubygpOyB9CisKKyAgLy8gaW1wbGVtZW50cyBaZXJvQ29weU91dHB1dFN0cmVhbSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgYm9vbCBOZXh0KHZvaWQqKiBkYXRhLCBpbnQqIHNpemUpOworICB2b2lkIEJhY2tVcChpbnQgY291bnQpOworICBpbnQ2NCBCeXRlQ291bnQoKSBjb25zdDsKKworIHByaXZhdGU6CisgIGNsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBDb3B5aW5nRmlsZU91dHB1dFN0cmVhbSA6IHB1YmxpYyBDb3B5aW5nT3V0cHV0U3RyZWFtIHsKKyAgIHB1YmxpYzoKKyAgICBDb3B5aW5nRmlsZU91dHB1dFN0cmVhbShpbnQgZmlsZV9kZXNjcmlwdG9yKTsKKyAgICB+Q29weWluZ0ZpbGVPdXRwdXRTdHJlYW0oKTsKKworICAgIGJvb2wgQ2xvc2UoKTsKKyAgICB2b2lkIFNldENsb3NlT25EZWxldGUoYm9vbCB2YWx1ZSkgeyBjbG9zZV9vbl9kZWxldGVfID0gdmFsdWU7IH0KKyAgICBpbnQgR2V0RXJybm8oKSB7IHJldHVybiBlcnJub187IH0KKworICAgIC8vIGltcGxlbWVudHMgQ29weWluZ091dHB1dFN0cmVhbSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAgIGJvb2wgV3JpdGUoY29uc3Qgdm9pZCogYnVmZmVyLCBpbnQgc2l6ZSk7CisKKyAgIHByaXZhdGU6CisgICAgLy8gVGhlIGZpbGUgZGVzY3JpcHRvci4KKyAgICBjb25zdCBpbnQgZmlsZV87CisgICAgYm9vbCBjbG9zZV9vbl9kZWxldGVfOworICAgIGJvb2wgaXNfY2xvc2VkXzsKKworICAgIC8vIFRoZSBlcnJubyBvZiB0aGUgSS9PIGVycm9yLCBpZiBvbmUgaGFzIG9jY3VycmVkLiAgT3RoZXJ3aXNlLCB6ZXJvLgorICAgIGludCBlcnJub187CisKKyAgICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoQ29weWluZ0ZpbGVPdXRwdXRTdHJlYW0pOworICB9OworCisgIENvcHlpbmdGaWxlT3V0cHV0U3RyZWFtIGNvcHlpbmdfb3V0cHV0XzsKKyAgQ29weWluZ091dHB1dFN0cmVhbUFkYXB0b3IgaW1wbF87CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEZpbGVPdXRwdXRTdHJlYW0pOworfTsKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisvLyBBIFplcm9Db3B5SW5wdXRTdHJlYW0gd2hpY2ggcmVhZHMgZnJvbSBhIEMrKyBpc3RyZWFtLgorLy8KKy8vIE5vdGUgdGhhdCBmb3IgcmVhZGluZyBmaWxlcyAob3IgYW55dGhpbmcgcmVwcmVzZW50ZWQgYnkgYSBmaWxlIGRlc2NyaXB0b3IpLAorLy8gRmlsZUlucHV0U3RyZWFtIGlzIG1vcmUgZWZmaWNpZW50LgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIElzdHJlYW1JbnB1dFN0cmVhbSA6IHB1YmxpYyBaZXJvQ29weUlucHV0U3RyZWFtIHsKKyBwdWJsaWM6CisgIC8vIENyZWF0ZXMgYSBzdHJlYW0gdGhhdCByZWFkcyBmcm9tIHRoZSBnaXZlbiBDKysgaXN0cmVhbS4KKyAgLy8gSWYgYSBibG9ja19zaXplIGlzIGdpdmVuLCBpdCBzcGVjaWZpZXMgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0CisgIC8vIHNob3VsZCBiZSByZWFkIGFuZCByZXR1cm5lZCB3aXRoIGVhY2ggY2FsbCB0byBOZXh0KCkuICBPdGhlcndpc2UsCisgIC8vIGEgcmVhc29uYWJsZSBkZWZhdWx0IGlzIHVzZWQuCisgIGV4cGxpY2l0IElzdHJlYW1JbnB1dFN0cmVhbShpc3RyZWFtKiBzdHJlYW0sIGludCBibG9ja19zaXplID0gLTEpOworICB+SXN0cmVhbUlucHV0U3RyZWFtKCk7CisKKyAgLy8gaW1wbGVtZW50cyBaZXJvQ29weUlucHV0U3RyZWFtIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgYm9vbCBOZXh0KGNvbnN0IHZvaWQqKiBkYXRhLCBpbnQqIHNpemUpOworICB2b2lkIEJhY2tVcChpbnQgY291bnQpOworICBib29sIFNraXAoaW50IGNvdW50KTsKKyAgaW50NjQgQnl0ZUNvdW50KCkgY29uc3Q7CisKKyBwcml2YXRlOgorICBjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgQ29weWluZ0lzdHJlYW1JbnB1dFN0cmVhbSA6IHB1YmxpYyBDb3B5aW5nSW5wdXRTdHJlYW0geworICAgcHVibGljOgorICAgIENvcHlpbmdJc3RyZWFtSW5wdXRTdHJlYW0oaXN0cmVhbSogaW5wdXQpOworICAgIH5Db3B5aW5nSXN0cmVhbUlucHV0U3RyZWFtKCk7CisKKyAgICAvLyBpbXBsZW1lbnRzIENvcHlpbmdJbnB1dFN0cmVhbSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICBpbnQgUmVhZCh2b2lkKiBidWZmZXIsIGludCBzaXplKTsKKyAgICAvLyAoV2UgdXNlIHRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIG9mIFNraXAoKS4pCisKKyAgIHByaXZhdGU6CisgICAgLy8gVGhlIHN0cmVhbS4KKyAgICBpc3RyZWFtKiBpbnB1dF87CisKKyAgICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoQ29weWluZ0lzdHJlYW1JbnB1dFN0cmVhbSk7CisgIH07CisKKyAgQ29weWluZ0lzdHJlYW1JbnB1dFN0cmVhbSBjb3B5aW5nX2lucHV0XzsKKyAgQ29weWluZ0lucHV0U3RyZWFtQWRhcHRvciBpbXBsXzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoSXN0cmVhbUlucHV0U3RyZWFtKTsKK307CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworLy8gQSBaZXJvQ29weU91dHB1dFN0cmVhbSB3aGljaCB3cml0ZXMgdG8gYSBDKysgb3N0cmVhbS4KKy8vCisvLyBOb3RlIHRoYXQgZm9yIHdyaXRpbmcgZmlsZXMgKG9yIGFueXRoaW5nIHJlcHJlc2VudGVkIGJ5IGEgZmlsZSBkZXNjcmlwdG9yKSwKKy8vIEZpbGVPdXRwdXRTdHJlYW0gaXMgbW9yZSBlZmZpY2llbnQuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgT3N0cmVhbU91dHB1dFN0cmVhbSA6IHB1YmxpYyBaZXJvQ29weU91dHB1dFN0cmVhbSB7CisgcHVibGljOgorICAvLyBDcmVhdGVzIGEgc3RyZWFtIHRoYXQgd3JpdGVzIHRvIHRoZSBnaXZlbiBDKysgb3N0cmVhbS4KKyAgLy8gSWYgYSBibG9ja19zaXplIGlzIGdpdmVuLCBpdCBzcGVjaWZpZXMgdGhlIHNpemUgb2YgdGhlIGJ1ZmZlcnMKKyAgLy8gdGhhdCBzaG91bGQgYmUgcmV0dXJuZWQgYnkgTmV4dCgpLiAgT3RoZXJ3aXNlLCBhIHJlYXNvbmFibGUgZGVmYXVsdAorICAvLyBpcyB1c2VkLgorICBleHBsaWNpdCBPc3RyZWFtT3V0cHV0U3RyZWFtKG9zdHJlYW0qIHN0cmVhbSwgaW50IGJsb2NrX3NpemUgPSAtMSk7CisgIH5Pc3RyZWFtT3V0cHV0U3RyZWFtKCk7CisKKyAgLy8gaW1wbGVtZW50cyBaZXJvQ29weU91dHB1dFN0cmVhbSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgYm9vbCBOZXh0KHZvaWQqKiBkYXRhLCBpbnQqIHNpemUpOworICB2b2lkIEJhY2tVcChpbnQgY291bnQpOworICBpbnQ2NCBCeXRlQ291bnQoKSBjb25zdDsKKworIHByaXZhdGU6CisgIGNsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBDb3B5aW5nT3N0cmVhbU91dHB1dFN0cmVhbSA6IHB1YmxpYyBDb3B5aW5nT3V0cHV0U3RyZWFtIHsKKyAgIHB1YmxpYzoKKyAgICBDb3B5aW5nT3N0cmVhbU91dHB1dFN0cmVhbShvc3RyZWFtKiBvdXRwdXQpOworICAgIH5Db3B5aW5nT3N0cmVhbU91dHB1dFN0cmVhbSgpOworCisgICAgLy8gaW1wbGVtZW50cyBDb3B5aW5nT3V0cHV0U3RyZWFtIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgYm9vbCBXcml0ZShjb25zdCB2b2lkKiBidWZmZXIsIGludCBzaXplKTsKKworICAgcHJpdmF0ZToKKyAgICAvLyBUaGUgc3RyZWFtLgorICAgIG9zdHJlYW0qIG91dHB1dF87CisKKyAgICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoQ29weWluZ09zdHJlYW1PdXRwdXRTdHJlYW0pOworICB9OworCisgIENvcHlpbmdPc3RyZWFtT3V0cHV0U3RyZWFtIGNvcHlpbmdfb3V0cHV0XzsKKyAgQ29weWluZ091dHB1dFN0cmVhbUFkYXB0b3IgaW1wbF87CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKE9zdHJlYW1PdXRwdXRTdHJlYW0pOworfTsKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisvLyBBIFplcm9Db3B5SW5wdXRTdHJlYW0gd2hpY2ggcmVhZHMgZnJvbSBzZXZlcmFsIG90aGVyIHN0cmVhbXMgaW4gc2VxdWVuY2UuCisvLyBDb25jYXRlbmF0aW5nSW5wdXRTdHJlYW0gaXMgdW5hYmxlIHRvIGRpc3Rpbmd1aXNoIGJldHdlZW4gZW5kLW9mLXN0cmVhbQorLy8gYW5kIHJlYWQgZXJyb3JzIGluIHRoZSB1bmRlcmx5aW5nIHN0cmVhbXMsIHNvIGl0IGFzc3VtZXMgYW55IGVycm9ycyBtZWFuCisvLyBlbmQtb2Ytc3RyZWFtLiAgU28sIGlmIHRoZSB1bmRlcmx5aW5nIHN0cmVhbXMgZmFpbCBmb3IgYW55IG90aGVyIHJlYXNvbiwKKy8vIENvbmNhdGVuYXRpbmdJbnB1dFN0cmVhbSBtYXkgZG8gb2RkIHRoaW5ncy4gIEl0IGlzIHN1Z2dlc3RlZCB0aGF0IHlvdSBkbworLy8gbm90IHVzZSBDb25jYXRlbmF0aW5nSW5wdXRTdHJlYW0gb24gc3RyZWFtcyB0aGF0IG1pZ2h0IHByb2R1Y2UgcmVhZCBlcnJvcnMKKy8vIG90aGVyIHRoYW4gZW5kLW9mLXN0cmVhbS4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBDb25jYXRlbmF0aW5nSW5wdXRTdHJlYW0gOiBwdWJsaWMgWmVyb0NvcHlJbnB1dFN0cmVhbSB7CisgcHVibGljOgorICAvLyBBbGwgc3RyZWFtcyBwYXNzZWQgaW4gYXMgd2VsbCBhcyB0aGUgYXJyYXkgaXRzZWxmIG11c3QgcmVtYWluIHZhbGlkCisgIC8vIHVudGlsIHRoZSBDb25jYXRlbmF0aW5nSW5wdXRTdHJlYW0gaXMgZGVzdHJveWVkLgorICBDb25jYXRlbmF0aW5nSW5wdXRTdHJlYW0oWmVyb0NvcHlJbnB1dFN0cmVhbSogY29uc3Qgc3RyZWFtc1tdLCBpbnQgY291bnQpOworICB+Q29uY2F0ZW5hdGluZ0lucHV0U3RyZWFtKCk7CisKKyAgLy8gaW1wbGVtZW50cyBaZXJvQ29weUlucHV0U3RyZWFtIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgYm9vbCBOZXh0KGNvbnN0IHZvaWQqKiBkYXRhLCBpbnQqIHNpemUpOworICB2b2lkIEJhY2tVcChpbnQgY291bnQpOworICBib29sIFNraXAoaW50IGNvdW50KTsKKyAgaW50NjQgQnl0ZUNvdW50KCkgY29uc3Q7CisKKworIHByaXZhdGU6CisgIC8vIEFzIHN0cmVhbXMgYXJlIHJldGlyZWQsIHN0cmVhbXNfIGlzIGluY3JlbWVudGVkIGFuZCBjb3VudF8gaXMKKyAgLy8gZGVjcmVtZW50ZWQuCisgIFplcm9Db3B5SW5wdXRTdHJlYW0qIGNvbnN0KiBzdHJlYW1zXzsKKyAgaW50IHN0cmVhbV9jb3VudF87CisgIGludDY0IGJ5dGVzX3JldGlyZWRfOyAgLy8gQnl0ZXMgcmVhZCBmcm9tIHByZXZpb3VzIHN0cmVhbXMuCisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKENvbmNhdGVuYXRpbmdJbnB1dFN0cmVhbSk7Cit9OworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKy8vIEEgWmVyb0NvcHlJbnB1dFN0cmVhbSB3aGljaCB3cmFwcyBzb21lIG90aGVyIHN0cmVhbSBhbmQgbGltaXRzIGl0IHRvCisvLyBhIHBhcnRpY3VsYXIgYnl0ZSBjb3VudC4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBMaW1pdGluZ0lucHV0U3RyZWFtIDogcHVibGljIFplcm9Db3B5SW5wdXRTdHJlYW0geworIHB1YmxpYzoKKyAgTGltaXRpbmdJbnB1dFN0cmVhbShaZXJvQ29weUlucHV0U3RyZWFtKiBpbnB1dCwgaW50NjQgbGltaXQpOworICB+TGltaXRpbmdJbnB1dFN0cmVhbSgpOworCisgIC8vIGltcGxlbWVudHMgWmVyb0NvcHlJbnB1dFN0cmVhbSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIGJvb2wgTmV4dChjb25zdCB2b2lkKiogZGF0YSwgaW50KiBzaXplKTsKKyAgdm9pZCBCYWNrVXAoaW50IGNvdW50KTsKKyAgYm9vbCBTa2lwKGludCBjb3VudCk7CisgIGludDY0IEJ5dGVDb3VudCgpIGNvbnN0OworCisKKyBwcml2YXRlOgorICBaZXJvQ29weUlucHV0U3RyZWFtKiBpbnB1dF87CisgIGludDY0IGxpbWl0XzsgIC8vIERlY3JlYXNlcyBhcyB3ZSBnbywgYmVjb21lcyBuZWdhdGl2ZSBpZiB3ZSBvdmVyc2hvb3QuCisgIGludDY0IHByaW9yX2J5dGVzX3JlYWRfOyAgLy8gQnl0ZXMgcmVhZCBvbiB1bmRlcmx5aW5nIHN0cmVhbSBhdCBjb25zdHJ1Y3Rpb24KKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoTGltaXRpbmdJbnB1dFN0cmVhbSk7Cit9OworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK30gIC8vIG5hbWVzcGFjZSBpbworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0lPX1pFUk9fQ09QWV9TVFJFQU1fSU1QTF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbV9pbXBsX2xpdGUuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbF9saXRlLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA4M2JlY2EKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbF9saXRlLmNjCkBAIC0wLDAgKzEsNDM4IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbV9pbXBsX2xpdGUuaD4KKworI2luY2x1ZGUgPGFsZ29yaXRobT4KKyNpbmNsdWRlIDxsaW1pdHM+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY2FzdHMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2xvZ2dpbmcuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RsX3V0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGlvIHsKKworbmFtZXNwYWNlIHsKKworLy8gRGVmYXVsdCBibG9jayBzaXplIGZvciBDb3B5aW5ne0luLE91dH1wdXRTdHJlYW1BZGFwdG9yLgorc3RhdGljIGNvbnN0IGludCBrRGVmYXVsdEJsb2NrU2l6ZSA9IDgxOTI7CisKK30gIC8vIG5hbWVzcGFjZQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK0FycmF5SW5wdXRTdHJlYW06OkFycmF5SW5wdXRTdHJlYW0oY29uc3Qgdm9pZCogZGF0YSwgaW50IHNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBibG9ja19zaXplKQorICA6IGRhdGFfKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgdWludDgqPihkYXRhKSksCisgICAgc2l6ZV8oc2l6ZSksCisgICAgYmxvY2tfc2l6ZV8oYmxvY2tfc2l6ZSA+IDAgPyBibG9ja19zaXplIDogc2l6ZSksCisgICAgcG9zaXRpb25fKDApLAorICAgIGxhc3RfcmV0dXJuZWRfc2l6ZV8oMCkgeworfQorCitBcnJheUlucHV0U3RyZWFtOjp+QXJyYXlJbnB1dFN0cmVhbSgpIHsKK30KKworYm9vbCBBcnJheUlucHV0U3RyZWFtOjpOZXh0KGNvbnN0IHZvaWQqKiBkYXRhLCBpbnQqIHNpemUpIHsKKyAgaWYgKHBvc2l0aW9uXyA8IHNpemVfKSB7CisgICAgbGFzdF9yZXR1cm5lZF9zaXplXyA9IG1pbihibG9ja19zaXplXywgc2l6ZV8gLSBwb3NpdGlvbl8pOworICAgICpkYXRhID0gZGF0YV8gKyBwb3NpdGlvbl87CisgICAgKnNpemUgPSBsYXN0X3JldHVybmVkX3NpemVfOworICAgIHBvc2l0aW9uXyArPSBsYXN0X3JldHVybmVkX3NpemVfOworICAgIHJldHVybiB0cnVlOworICB9IGVsc2UgeworICAgIC8vIFdlJ3JlIGF0IHRoZSBlbmQgb2YgdGhlIGFycmF5LgorICAgIGxhc3RfcmV0dXJuZWRfc2l6ZV8gPSAwOyAgIC8vIERvbid0IGxldCBjYWxsZXIgYmFjayB1cC4KKyAgICByZXR1cm4gZmFsc2U7CisgIH0KK30KKwordm9pZCBBcnJheUlucHV0U3RyZWFtOjpCYWNrVXAoaW50IGNvdW50KSB7CisgIEdPT0dMRV9DSEVDS19HVChsYXN0X3JldHVybmVkX3NpemVfLCAwKQorICAgICAgPDwgIkJhY2tVcCgpIGNhbiBvbmx5IGJlIGNhbGxlZCBhZnRlciBhIHN1Y2Nlc3NmdWwgTmV4dCgpLiI7CisgIEdPT0dMRV9DSEVDS19MRShjb3VudCwgbGFzdF9yZXR1cm5lZF9zaXplXyk7CisgIEdPT0dMRV9DSEVDS19HRShjb3VudCwgMCk7CisgIHBvc2l0aW9uXyAtPSBjb3VudDsKKyAgbGFzdF9yZXR1cm5lZF9zaXplXyA9IDA7ICAvLyBEb24ndCBsZXQgY2FsbGVyIGJhY2sgdXAgZnVydGhlci4KK30KKworYm9vbCBBcnJheUlucHV0U3RyZWFtOjpTa2lwKGludCBjb3VudCkgeworICBHT09HTEVfQ0hFQ0tfR0UoY291bnQsIDApOworICBsYXN0X3JldHVybmVkX3NpemVfID0gMDsgICAvLyBEb24ndCBsZXQgY2FsbGVyIGJhY2sgdXAuCisgIGlmIChjb3VudCA+IHNpemVfIC0gcG9zaXRpb25fKSB7CisgICAgcG9zaXRpb25fID0gc2l6ZV87CisgICAgcmV0dXJuIGZhbHNlOworICB9IGVsc2UgeworICAgIHBvc2l0aW9uXyArPSBjb3VudDsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorfQorCitpbnQ2NCBBcnJheUlucHV0U3RyZWFtOjpCeXRlQ291bnQoKSBjb25zdCB7CisgIHJldHVybiBwb3NpdGlvbl87Cit9CisKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitBcnJheU91dHB1dFN0cmVhbTo6QXJyYXlPdXRwdXRTdHJlYW0odm9pZCogZGF0YSwgaW50IHNpemUsIGludCBibG9ja19zaXplKQorICA6IGRhdGFfKHJlaW50ZXJwcmV0X2Nhc3Q8dWludDgqPihkYXRhKSksCisgICAgc2l6ZV8oc2l6ZSksCisgICAgYmxvY2tfc2l6ZV8oYmxvY2tfc2l6ZSA+IDAgPyBibG9ja19zaXplIDogc2l6ZSksCisgICAgcG9zaXRpb25fKDApLAorICAgIGxhc3RfcmV0dXJuZWRfc2l6ZV8oMCkgeworfQorCitBcnJheU91dHB1dFN0cmVhbTo6fkFycmF5T3V0cHV0U3RyZWFtKCkgeworfQorCitib29sIEFycmF5T3V0cHV0U3RyZWFtOjpOZXh0KHZvaWQqKiBkYXRhLCBpbnQqIHNpemUpIHsKKyAgaWYgKHBvc2l0aW9uXyA8IHNpemVfKSB7CisgICAgbGFzdF9yZXR1cm5lZF9zaXplXyA9IG1pbihibG9ja19zaXplXywgc2l6ZV8gLSBwb3NpdGlvbl8pOworICAgICpkYXRhID0gZGF0YV8gKyBwb3NpdGlvbl87CisgICAgKnNpemUgPSBsYXN0X3JldHVybmVkX3NpemVfOworICAgIHBvc2l0aW9uXyArPSBsYXN0X3JldHVybmVkX3NpemVfOworICAgIHJldHVybiB0cnVlOworICB9IGVsc2UgeworICAgIC8vIFdlJ3JlIGF0IHRoZSBlbmQgb2YgdGhlIGFycmF5LgorICAgIGxhc3RfcmV0dXJuZWRfc2l6ZV8gPSAwOyAgIC8vIERvbid0IGxldCBjYWxsZXIgYmFjayB1cC4KKyAgICByZXR1cm4gZmFsc2U7CisgIH0KK30KKwordm9pZCBBcnJheU91dHB1dFN0cmVhbTo6QmFja1VwKGludCBjb3VudCkgeworICBHT09HTEVfQ0hFQ0tfR1QobGFzdF9yZXR1cm5lZF9zaXplXywgMCkKKyAgICAgIDw8ICJCYWNrVXAoKSBjYW4gb25seSBiZSBjYWxsZWQgYWZ0ZXIgYSBzdWNjZXNzZnVsIE5leHQoKS4iOworICBHT09HTEVfQ0hFQ0tfTEUoY291bnQsIGxhc3RfcmV0dXJuZWRfc2l6ZV8pOworICBHT09HTEVfQ0hFQ0tfR0UoY291bnQsIDApOworICBwb3NpdGlvbl8gLT0gY291bnQ7CisgIGxhc3RfcmV0dXJuZWRfc2l6ZV8gPSAwOyAgLy8gRG9uJ3QgbGV0IGNhbGxlciBiYWNrIHVwIGZ1cnRoZXIuCit9CisKK2ludDY0IEFycmF5T3V0cHV0U3RyZWFtOjpCeXRlQ291bnQoKSBjb25zdCB7CisgIHJldHVybiBwb3NpdGlvbl87Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworU3RyaW5nT3V0cHV0U3RyZWFtOjpTdHJpbmdPdXRwdXRTdHJlYW0oc3RyaW5nKiB0YXJnZXQpCisgIDogdGFyZ2V0Xyh0YXJnZXQpIHsKK30KKworU3RyaW5nT3V0cHV0U3RyZWFtOjp+U3RyaW5nT3V0cHV0U3RyZWFtKCkgeworfQorCitib29sIFN0cmluZ091dHB1dFN0cmVhbTo6TmV4dCh2b2lkKiogZGF0YSwgaW50KiBzaXplKSB7CisgIEdPT0dMRV9DSEVDS19ORShOVUxMLCB0YXJnZXRfKTsKKyAgaW50IG9sZF9zaXplID0gdGFyZ2V0Xy0+c2l6ZSgpOworCisgIC8vIEdyb3cgdGhlIHN0cmluZy4KKyAgaWYgKG9sZF9zaXplIDwgdGFyZ2V0Xy0+Y2FwYWNpdHkoKSkgeworICAgIC8vIFJlc2l6ZSB0aGUgc3RyaW5nIHRvIG1hdGNoIGl0cyBjYXBhY2l0eSwgc2luY2Ugd2UgY2FuIGdldCBhd2F5CisgICAgLy8gd2l0aG91dCBhIG1lbW9yeSBhbGxvY2F0aW9uIHRoaXMgd2F5LgorICAgIFNUTFN0cmluZ1Jlc2l6ZVVuaW5pdGlhbGl6ZWQodGFyZ2V0XywgdGFyZ2V0Xy0+Y2FwYWNpdHkoKSk7CisgIH0gZWxzZSB7CisgICAgLy8gU2l6ZSBoYXMgcmVhY2hlZCBjYXBhY2l0eSwgdHJ5IHRvIGRvdWJsZSB0aGUgc2l6ZS4KKyAgICBpZiAob2xkX3NpemUgPiBzdGQ6Om51bWVyaWNfbGltaXRzPGludD46Om1heCgpIC8gMikgeworICAgICAgLy8gQ2FuIG5vdCBkb3VibGUgdGhlIHNpemUgb3RoZXJ3aXNlIGl0IGlzIGdvaW5nIHRvIGNhdXNlIGludGVnZXIKKyAgICAgIC8vIG92ZXJmbG93IGluIHRoZSBleHByZXNzaW9uIGJlbG93OiBvbGRfc2l6ZSAqIDIgIjsKKyAgICAgIEdPT0dMRV9MT0coRVJST1IpIDw8ICJDYW5ub3QgYWxsb2NhdGUgYnVmZmVyIGxhcmdlciB0aGFuIGtpbnQzMm1heCBmb3IgIgorICAgICAgICAgICAgICAgICA8PCAiU3RyaW5nT3V0cHV0U3RyZWFtLiI7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIC8vIERvdWJsZSB0aGUgc2l6ZSwgYWxzbyBtYWtlIHN1cmUgdGhhdCB0aGUgbmV3IHNpemUgaXMgYXQgbGVhc3QKKyAgICAvLyBrTWluaW11bVNpemUuCisgICAgU1RMU3RyaW5nUmVzaXplVW5pbml0aWFsaXplZCgKKyAgICAgIHRhcmdldF8sCisgICAgICBtYXgob2xkX3NpemUgKiAyLAorICAgICAgICAgIGtNaW5pbXVtU2l6ZSArIDApKTsgIC8vICIrIDAiIHdvcmtzIGFyb3VuZCBHQ0M0IHdlaXJkbmVzcy4KKyAgfQorCisgICpkYXRhID0gbXV0YWJsZV9zdHJpbmdfZGF0YSh0YXJnZXRfKSArIG9sZF9zaXplOworICAqc2l6ZSA9IHRhcmdldF8tPnNpemUoKSAtIG9sZF9zaXplOworICByZXR1cm4gdHJ1ZTsKK30KKwordm9pZCBTdHJpbmdPdXRwdXRTdHJlYW06OkJhY2tVcChpbnQgY291bnQpIHsKKyAgR09PR0xFX0NIRUNLX0dFKGNvdW50LCAwKTsKKyAgR09PR0xFX0NIRUNLX05FKE5VTEwsIHRhcmdldF8pOworICBHT09HTEVfQ0hFQ0tfTEUoY291bnQsIHRhcmdldF8tPnNpemUoKSk7CisgIHRhcmdldF8tPnJlc2l6ZSh0YXJnZXRfLT5zaXplKCkgLSBjb3VudCk7Cit9CisKK2ludDY0IFN0cmluZ091dHB1dFN0cmVhbTo6Qnl0ZUNvdW50KCkgY29uc3QgeworICBHT09HTEVfQ0hFQ0tfTkUoTlVMTCwgdGFyZ2V0Xyk7CisgIHJldHVybiB0YXJnZXRfLT5zaXplKCk7Cit9CisKK3ZvaWQgU3RyaW5nT3V0cHV0U3RyZWFtOjpTZXRTdHJpbmcoc3RyaW5nKiB0YXJnZXQpIHsKKyAgdGFyZ2V0XyA9IHRhcmdldDsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitMYXp5U3RyaW5nT3V0cHV0U3RyZWFtOjpMYXp5U3RyaW5nT3V0cHV0U3RyZWFtKAorICAgIFJlc3VsdENhbGxiYWNrPHN0cmluZyo+KiBjYWxsYmFjaykKKyAgICA6IFN0cmluZ091dHB1dFN0cmVhbShOVUxMKSwKKyAgICAgIGNhbGxiYWNrXyhHT09HTEVfQ0hFQ0tfTk9UTlVMTChjYWxsYmFjaykpLAorICAgICAgc3RyaW5nX2lzX3NldF8oZmFsc2UpIHsKK30KKworTGF6eVN0cmluZ091dHB1dFN0cmVhbTo6fkxhenlTdHJpbmdPdXRwdXRTdHJlYW0oKSB7Cit9CisKK2Jvb2wgTGF6eVN0cmluZ091dHB1dFN0cmVhbTo6TmV4dCh2b2lkKiogZGF0YSwgaW50KiBzaXplKSB7CisgIGlmICghc3RyaW5nX2lzX3NldF8pIHsKKyAgICBTZXRTdHJpbmcoY2FsbGJhY2tfLT5SdW4oKSk7CisgICAgc3RyaW5nX2lzX3NldF8gPSB0cnVlOworICB9CisgIHJldHVybiBTdHJpbmdPdXRwdXRTdHJlYW06Ok5leHQoZGF0YSwgc2l6ZSk7Cit9CisKK2ludDY0IExhenlTdHJpbmdPdXRwdXRTdHJlYW06OkJ5dGVDb3VudCgpIGNvbnN0IHsKKyAgcmV0dXJuIHN0cmluZ19pc19zZXRfID8gU3RyaW5nT3V0cHV0U3RyZWFtOjpCeXRlQ291bnQoKSA6IDA7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworQ29weWluZ0lucHV0U3RyZWFtOjp+Q29weWluZ0lucHV0U3RyZWFtKCkge30KKworaW50IENvcHlpbmdJbnB1dFN0cmVhbTo6U2tpcChpbnQgY291bnQpIHsKKyAgY2hhciBqdW5rWzQwOTZdOworICBpbnQgc2tpcHBlZCA9IDA7CisgIHdoaWxlIChza2lwcGVkIDwgY291bnQpIHsKKyAgICBpbnQgYnl0ZXMgPSBSZWFkKGp1bmssIG1pbihjb3VudCAtIHNraXBwZWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1wbGljaXRfY2FzdDxpbnQ+KHNpemVvZihqdW5rKSkpKTsKKyAgICBpZiAoYnl0ZXMgPD0gMCkgeworICAgICAgLy8gRU9GIG9yIHJlYWQgZXJyb3IuCisgICAgICByZXR1cm4gc2tpcHBlZDsKKyAgICB9CisgICAgc2tpcHBlZCArPSBieXRlczsKKyAgfQorICByZXR1cm4gc2tpcHBlZDsKK30KKworQ29weWluZ0lucHV0U3RyZWFtQWRhcHRvcjo6Q29weWluZ0lucHV0U3RyZWFtQWRhcHRvcigKKyAgICBDb3B5aW5nSW5wdXRTdHJlYW0qIGNvcHlpbmdfc3RyZWFtLCBpbnQgYmxvY2tfc2l6ZSkKKyAgOiBjb3B5aW5nX3N0cmVhbV8oY29weWluZ19zdHJlYW0pLAorICAgIG93bnNfY29weWluZ19zdHJlYW1fKGZhbHNlKSwKKyAgICBmYWlsZWRfKGZhbHNlKSwKKyAgICBwb3NpdGlvbl8oMCksCisgICAgYnVmZmVyX3NpemVfKGJsb2NrX3NpemUgPiAwID8gYmxvY2tfc2l6ZSA6IGtEZWZhdWx0QmxvY2tTaXplKSwKKyAgICBidWZmZXJfdXNlZF8oMCksCisgICAgYmFja3VwX2J5dGVzXygwKSB7Cit9CisKK0NvcHlpbmdJbnB1dFN0cmVhbUFkYXB0b3I6On5Db3B5aW5nSW5wdXRTdHJlYW1BZGFwdG9yKCkgeworICBpZiAob3duc19jb3B5aW5nX3N0cmVhbV8pIHsKKyAgICBkZWxldGUgY29weWluZ19zdHJlYW1fOworICB9Cit9CisKK2Jvb2wgQ29weWluZ0lucHV0U3RyZWFtQWRhcHRvcjo6TmV4dChjb25zdCB2b2lkKiogZGF0YSwgaW50KiBzaXplKSB7CisgIGlmIChmYWlsZWRfKSB7CisgICAgLy8gQWxyZWFkeSBmYWlsZWQgb24gYSBwcmV2aW91cyByZWFkLgorICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIEFsbG9jYXRlQnVmZmVySWZOZWVkZWQoKTsKKworICBpZiAoYmFja3VwX2J5dGVzXyA+IDApIHsKKyAgICAvLyBXZSBoYXZlIGRhdGEgbGVmdCBvdmVyIGZyb20gYSBwcmV2aW91cyBCYWNrVXAoKSwgc28ganVzdCByZXR1cm4gdGhhdC4KKyAgICAqZGF0YSA9IGJ1ZmZlcl8uZ2V0KCkgKyBidWZmZXJfdXNlZF8gLSBiYWNrdXBfYnl0ZXNfOworICAgICpzaXplID0gYmFja3VwX2J5dGVzXzsKKyAgICBiYWNrdXBfYnl0ZXNfID0gMDsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIC8vIFJlYWQgbmV3IGRhdGEgaW50byB0aGUgYnVmZmVyLgorICBidWZmZXJfdXNlZF8gPSBjb3B5aW5nX3N0cmVhbV8tPlJlYWQoYnVmZmVyXy5nZXQoKSwgYnVmZmVyX3NpemVfKTsKKyAgaWYgKGJ1ZmZlcl91c2VkXyA8PSAwKSB7CisgICAgLy8gRU9GIG9yIHJlYWQgZXJyb3IuICBXZSBkb24ndCBuZWVkIHRoZSBidWZmZXIgYW55bW9yZS4KKyAgICBpZiAoYnVmZmVyX3VzZWRfIDwgMCkgeworICAgICAgLy8gUmVhZCBlcnJvciAobm90IEVPRikuCisgICAgICBmYWlsZWRfID0gdHJ1ZTsKKyAgICB9CisgICAgRnJlZUJ1ZmZlcigpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICBwb3NpdGlvbl8gKz0gYnVmZmVyX3VzZWRfOworCisgICpzaXplID0gYnVmZmVyX3VzZWRfOworICAqZGF0YSA9IGJ1ZmZlcl8uZ2V0KCk7CisgIHJldHVybiB0cnVlOworfQorCit2b2lkIENvcHlpbmdJbnB1dFN0cmVhbUFkYXB0b3I6OkJhY2tVcChpbnQgY291bnQpIHsKKyAgR09PR0xFX0NIRUNLKGJhY2t1cF9ieXRlc18gPT0gMCAmJiBidWZmZXJfLmdldCgpICE9IE5VTEwpCisgICAgPDwgIiBCYWNrVXAoKSBjYW4gb25seSBiZSBjYWxsZWQgYWZ0ZXIgTmV4dCgpLiI7CisgIEdPT0dMRV9DSEVDS19MRShjb3VudCwgYnVmZmVyX3VzZWRfKQorICAgIDw8ICIgQ2FuJ3QgYmFjayB1cCBvdmVyIG1vcmUgYnl0ZXMgdGhhbiB3ZXJlIHJldHVybmVkIGJ5IHRoZSBsYXN0IGNhbGwiCisgICAgICAgIiB0byBOZXh0KCkuIjsKKyAgR09PR0xFX0NIRUNLX0dFKGNvdW50LCAwKQorICAgIDw8ICIgUGFyYW1ldGVyIHRvIEJhY2tVcCgpIGNhbid0IGJlIG5lZ2F0aXZlLiI7CisKKyAgYmFja3VwX2J5dGVzXyA9IGNvdW50OworfQorCitib29sIENvcHlpbmdJbnB1dFN0cmVhbUFkYXB0b3I6OlNraXAoaW50IGNvdW50KSB7CisgIEdPT0dMRV9DSEVDS19HRShjb3VudCwgMCk7CisKKyAgaWYgKGZhaWxlZF8pIHsKKyAgICAvLyBBbHJlYWR5IGZhaWxlZCBvbiBhIHByZXZpb3VzIHJlYWQuCisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8gRmlyc3Qgc2tpcCBhbnkgYnl0ZXMgbGVmdCBvdmVyIGZyb20gYSBwcmV2aW91cyBCYWNrVXAoKS4KKyAgaWYgKGJhY2t1cF9ieXRlc18gPj0gY291bnQpIHsKKyAgICAvLyBXZSBoYXZlIG1vcmUgZGF0YSBsZWZ0IG92ZXIgdGhhbiB3ZSdyZSB0cnlpbmcgdG8gc2tpcC4gIEp1c3QgY2hvcCBpdC4KKyAgICBiYWNrdXBfYnl0ZXNfIC09IGNvdW50OworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgY291bnQgLT0gYmFja3VwX2J5dGVzXzsKKyAgYmFja3VwX2J5dGVzXyA9IDA7CisKKyAgaW50IHNraXBwZWQgPSBjb3B5aW5nX3N0cmVhbV8tPlNraXAoY291bnQpOworICBwb3NpdGlvbl8gKz0gc2tpcHBlZDsKKyAgcmV0dXJuIHNraXBwZWQgPT0gY291bnQ7Cit9CisKK2ludDY0IENvcHlpbmdJbnB1dFN0cmVhbUFkYXB0b3I6OkJ5dGVDb3VudCgpIGNvbnN0IHsKKyAgcmV0dXJuIHBvc2l0aW9uXyAtIGJhY2t1cF9ieXRlc187Cit9CisKK3ZvaWQgQ29weWluZ0lucHV0U3RyZWFtQWRhcHRvcjo6QWxsb2NhdGVCdWZmZXJJZk5lZWRlZCgpIHsKKyAgaWYgKGJ1ZmZlcl8uZ2V0KCkgPT0gTlVMTCkgeworICAgIGJ1ZmZlcl8ucmVzZXQobmV3IHVpbnQ4W2J1ZmZlcl9zaXplX10pOworICB9Cit9CisKK3ZvaWQgQ29weWluZ0lucHV0U3RyZWFtQWRhcHRvcjo6RnJlZUJ1ZmZlcigpIHsKKyAgR09PR0xFX0NIRUNLX0VRKGJhY2t1cF9ieXRlc18sIDApOworICBidWZmZXJfdXNlZF8gPSAwOworICBidWZmZXJfLnJlc2V0KCk7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworQ29weWluZ091dHB1dFN0cmVhbTo6fkNvcHlpbmdPdXRwdXRTdHJlYW0oKSB7fQorCitDb3B5aW5nT3V0cHV0U3RyZWFtQWRhcHRvcjo6Q29weWluZ091dHB1dFN0cmVhbUFkYXB0b3IoCisgICAgQ29weWluZ091dHB1dFN0cmVhbSogY29weWluZ19zdHJlYW0sIGludCBibG9ja19zaXplKQorICA6IGNvcHlpbmdfc3RyZWFtXyhjb3B5aW5nX3N0cmVhbSksCisgICAgb3duc19jb3B5aW5nX3N0cmVhbV8oZmFsc2UpLAorICAgIGZhaWxlZF8oZmFsc2UpLAorICAgIHBvc2l0aW9uXygwKSwKKyAgICBidWZmZXJfc2l6ZV8oYmxvY2tfc2l6ZSA+IDAgPyBibG9ja19zaXplIDoga0RlZmF1bHRCbG9ja1NpemUpLAorICAgIGJ1ZmZlcl91c2VkXygwKSB7Cit9CisKK0NvcHlpbmdPdXRwdXRTdHJlYW1BZGFwdG9yOjp+Q29weWluZ091dHB1dFN0cmVhbUFkYXB0b3IoKSB7CisgIFdyaXRlQnVmZmVyKCk7CisgIGlmIChvd25zX2NvcHlpbmdfc3RyZWFtXykgeworICAgIGRlbGV0ZSBjb3B5aW5nX3N0cmVhbV87CisgIH0KK30KKworYm9vbCBDb3B5aW5nT3V0cHV0U3RyZWFtQWRhcHRvcjo6Rmx1c2goKSB7CisgIHJldHVybiBXcml0ZUJ1ZmZlcigpOworfQorCitib29sIENvcHlpbmdPdXRwdXRTdHJlYW1BZGFwdG9yOjpOZXh0KHZvaWQqKiBkYXRhLCBpbnQqIHNpemUpIHsKKyAgaWYgKGJ1ZmZlcl91c2VkXyA9PSBidWZmZXJfc2l6ZV8pIHsKKyAgICBpZiAoIVdyaXRlQnVmZmVyKCkpIHJldHVybiBmYWxzZTsKKyAgfQorCisgIEFsbG9jYXRlQnVmZmVySWZOZWVkZWQoKTsKKworICAqZGF0YSA9IGJ1ZmZlcl8uZ2V0KCkgKyBidWZmZXJfdXNlZF87CisgICpzaXplID0gYnVmZmVyX3NpemVfIC0gYnVmZmVyX3VzZWRfOworICBidWZmZXJfdXNlZF8gPSBidWZmZXJfc2l6ZV87CisgIHJldHVybiB0cnVlOworfQorCit2b2lkIENvcHlpbmdPdXRwdXRTdHJlYW1BZGFwdG9yOjpCYWNrVXAoaW50IGNvdW50KSB7CisgIEdPT0dMRV9DSEVDS19HRShjb3VudCwgMCk7CisgIEdPT0dMRV9DSEVDS19FUShidWZmZXJfdXNlZF8sIGJ1ZmZlcl9zaXplXykKKyAgICA8PCAiIEJhY2tVcCgpIGNhbiBvbmx5IGJlIGNhbGxlZCBhZnRlciBOZXh0KCkuIjsKKyAgR09PR0xFX0NIRUNLX0xFKGNvdW50LCBidWZmZXJfdXNlZF8pCisgICAgPDwgIiBDYW4ndCBiYWNrIHVwIG92ZXIgbW9yZSBieXRlcyB0aGFuIHdlcmUgcmV0dXJuZWQgYnkgdGhlIGxhc3QgY2FsbCIKKyAgICAgICAiIHRvIE5leHQoKS4iOworCisgIGJ1ZmZlcl91c2VkXyAtPSBjb3VudDsKK30KKworaW50NjQgQ29weWluZ091dHB1dFN0cmVhbUFkYXB0b3I6OkJ5dGVDb3VudCgpIGNvbnN0IHsKKyAgcmV0dXJuIHBvc2l0aW9uXyArIGJ1ZmZlcl91c2VkXzsKK30KKworYm9vbCBDb3B5aW5nT3V0cHV0U3RyZWFtQWRhcHRvcjo6V3JpdGVCdWZmZXIoKSB7CisgIGlmIChmYWlsZWRfKSB7CisgICAgLy8gQWxyZWFkeSBmYWlsZWQgb24gYSBwcmV2aW91cyB3cml0ZS4KKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBpZiAoYnVmZmVyX3VzZWRfID09IDApIHJldHVybiB0cnVlOworCisgIGlmIChjb3B5aW5nX3N0cmVhbV8tPldyaXRlKGJ1ZmZlcl8uZ2V0KCksIGJ1ZmZlcl91c2VkXykpIHsKKyAgICBwb3NpdGlvbl8gKz0gYnVmZmVyX3VzZWRfOworICAgIGJ1ZmZlcl91c2VkXyA9IDA7CisgICAgcmV0dXJuIHRydWU7CisgIH0gZWxzZSB7CisgICAgZmFpbGVkXyA9IHRydWU7CisgICAgRnJlZUJ1ZmZlcigpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorfQorCit2b2lkIENvcHlpbmdPdXRwdXRTdHJlYW1BZGFwdG9yOjpBbGxvY2F0ZUJ1ZmZlcklmTmVlZGVkKCkgeworICBpZiAoYnVmZmVyXyA9PSBOVUxMKSB7CisgICAgYnVmZmVyXy5yZXNldChuZXcgdWludDhbYnVmZmVyX3NpemVfXSk7CisgIH0KK30KKwordm9pZCBDb3B5aW5nT3V0cHV0U3RyZWFtQWRhcHRvcjo6RnJlZUJ1ZmZlcigpIHsKKyAgYnVmZmVyX3VzZWRfID0gMDsKKyAgYnVmZmVyXy5yZXNldCgpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK30gIC8vIG5hbWVzcGFjZSBpbworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbF9saXRlLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbF9saXRlLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWMzOTdkZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbV9pbXBsX2xpdGUuaApAQCAtMCwwICsxLDQxMCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorLy8KKy8vIFRoaXMgZmlsZSBjb250YWlucyBjb21tb24gaW1wbGVtZW50YXRpb25zIG9mIHRoZSBpbnRlcmZhY2VzIGRlZmluZWQgaW4KKy8vIHplcm9fY29weV9zdHJlYW0uaCB3aGljaCBhcmUgaW5jbHVkZWQgaW4gdGhlICJsaXRlIiBwcm90b2J1ZiBsaWJyYXJ5LgorLy8gVGhlc2UgaW1wbGVtZW50YXRpb25zIGNvdmVyIEkvTyBvbiByYXcgYXJyYXlzIGFuZCBzdHJpbmdzLCBhcyB3ZWxsIGFzCisvLyBhZGFwdG9ycyB3aGljaCBtYWtlIGl0IGVhc3kgdG8gaW1wbGVtZW50IHN0cmVhbXMgYmFzZWQgb24gdHJhZGl0aW9uYWwKKy8vIHN0cmVhbXMuICBPZiBjb3Vyc2UsIG1hbnkgdXNlcnMgd2lsbCBwcm9iYWJseSB3YW50IHRvIHdyaXRlIHRoZWlyIG93bgorLy8gaW1wbGVtZW50YXRpb25zIG9mIHRoZXNlIGludGVyZmFjZXMgc3BlY2lmaWMgdG8gdGhlIHBhcnRpY3VsYXIgSS9PCisvLyBhYnN0cmFjdGlvbnMgdGhleSBwcmVmZXIgdG8gdXNlLCBidXQgdGhlc2Ugc2hvdWxkIGNvdmVyIHRoZSBtb3N0IGNvbW1vbgorLy8gY2FzZXMuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0lPX1pFUk9fQ09QWV9TVFJFQU1fSU1QTF9MSVRFX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfSU9fWkVST19DT1BZX1NUUkVBTV9JTVBMX0xJVEVfSF9fCisKKyNpbmNsdWRlIDxtZW1vcnk+CisjaWZuZGVmIF9TSEFSRURfUFRSX0gKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc2hhcmVkX3B0ci5oPgorI2VuZGlmCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGlvc2Z3ZD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc2NvcGVkX3B0ci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdGxfdXRpbC5oPgorCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbyB7CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworLy8gQSBaZXJvQ29weUlucHV0U3RyZWFtIGJhY2tlZCBieSBhbiBpbi1tZW1vcnkgYXJyYXkgb2YgYnl0ZXMuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgQXJyYXlJbnB1dFN0cmVhbSA6IHB1YmxpYyBaZXJvQ29weUlucHV0U3RyZWFtIHsKKyBwdWJsaWM6CisgIC8vIENyZWF0ZSBhbiBJbnB1dFN0cmVhbSB0aGF0IHJldHVybnMgdGhlIGJ5dGVzIHBvaW50ZWQgdG8gYnkgImRhdGEiLgorICAvLyAiZGF0YSIgcmVtYWlucyB0aGUgcHJvcGVydHkgb2YgdGhlIGNhbGxlciBidXQgbXVzdCByZW1haW4gdmFsaWQgdW50aWwKKyAgLy8gdGhlIHN0cmVhbSBpcyBkZXN0cm95ZWQuICBJZiBhIGJsb2NrX3NpemUgaXMgZ2l2ZW4sIGNhbGxzIHRvIE5leHQoKQorICAvLyB3aWxsIHJldHVybiBkYXRhIGJsb2NrcyBubyBsYXJnZXIgdGhhbiB0aGUgZ2l2ZW4gc2l6ZS4gIE90aGVyd2lzZSwgdGhlCisgIC8vIGZpcnN0IGNhbGwgdG8gTmV4dCgpIHJldHVybnMgdGhlIGVudGlyZSBhcnJheS4gIGJsb2NrX3NpemUgaXMgbWFpbmx5CisgIC8vIHVzZWZ1bCBmb3IgdGVzdGluZzsgaW4gcHJvZHVjdGlvbiB5b3Ugd291bGQgcHJvYmFibHkgbmV2ZXIgd2FudCB0byBzZXQKKyAgLy8gaXQuCisgIEFycmF5SW5wdXRTdHJlYW0oY29uc3Qgdm9pZCogZGF0YSwgaW50IHNpemUsIGludCBibG9ja19zaXplID0gLTEpOworICB+QXJyYXlJbnB1dFN0cmVhbSgpOworCisgIC8vIGltcGxlbWVudHMgWmVyb0NvcHlJbnB1dFN0cmVhbSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIGJvb2wgTmV4dChjb25zdCB2b2lkKiogZGF0YSwgaW50KiBzaXplKTsKKyAgdm9pZCBCYWNrVXAoaW50IGNvdW50KTsKKyAgYm9vbCBTa2lwKGludCBjb3VudCk7CisgIGludDY0IEJ5dGVDb3VudCgpIGNvbnN0OworCisKKyBwcml2YXRlOgorICBjb25zdCB1aW50OCogY29uc3QgZGF0YV87ICAvLyBUaGUgYnl0ZSBhcnJheS4KKyAgY29uc3QgaW50IHNpemVfOyAgICAgICAgICAgLy8gVG90YWwgc2l6ZSBvZiB0aGUgYXJyYXkuCisgIGNvbnN0IGludCBibG9ja19zaXplXzsgICAgIC8vIEhvdyBtYW55IGJ5dGVzIHRvIHJldHVybiBhdCBhIHRpbWUuCisKKyAgaW50IHBvc2l0aW9uXzsKKyAgaW50IGxhc3RfcmV0dXJuZWRfc2l6ZV87ICAgLy8gSG93IG1hbnkgYnl0ZXMgd2UgcmV0dXJuZWQgbGFzdCB0aW1lIE5leHQoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB3YXMgY2FsbGVkICh1c2VkIGZvciBlcnJvciBjaGVja2luZyBvbmx5KS4KKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoQXJyYXlJbnB1dFN0cmVhbSk7Cit9OworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKy8vIEEgWmVyb0NvcHlPdXRwdXRTdHJlYW0gYmFja2VkIGJ5IGFuIGluLW1lbW9yeSBhcnJheSBvZiBieXRlcy4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBBcnJheU91dHB1dFN0cmVhbSA6IHB1YmxpYyBaZXJvQ29weU91dHB1dFN0cmVhbSB7CisgcHVibGljOgorICAvLyBDcmVhdGUgYW4gT3V0cHV0U3RyZWFtIHRoYXQgd3JpdGVzIHRvIHRoZSBieXRlcyBwb2ludGVkIHRvIGJ5ICJkYXRhIi4KKyAgLy8gImRhdGEiIHJlbWFpbnMgdGhlIHByb3BlcnR5IG9mIHRoZSBjYWxsZXIgYnV0IG11c3QgcmVtYWluIHZhbGlkIHVudGlsCisgIC8vIHRoZSBzdHJlYW0gaXMgZGVzdHJveWVkLiAgSWYgYSBibG9ja19zaXplIGlzIGdpdmVuLCBjYWxscyB0byBOZXh0KCkKKyAgLy8gd2lsbCByZXR1cm4gZGF0YSBibG9ja3Mgbm8gbGFyZ2VyIHRoYW4gdGhlIGdpdmVuIHNpemUuICBPdGhlcndpc2UsIHRoZQorICAvLyBmaXJzdCBjYWxsIHRvIE5leHQoKSByZXR1cm5zIHRoZSBlbnRpcmUgYXJyYXkuICBibG9ja19zaXplIGlzIG1haW5seQorICAvLyB1c2VmdWwgZm9yIHRlc3Rpbmc7IGluIHByb2R1Y3Rpb24geW91IHdvdWxkIHByb2JhYmx5IG5ldmVyIHdhbnQgdG8gc2V0CisgIC8vIGl0LgorICBBcnJheU91dHB1dFN0cmVhbSh2b2lkKiBkYXRhLCBpbnQgc2l6ZSwgaW50IGJsb2NrX3NpemUgPSAtMSk7CisgIH5BcnJheU91dHB1dFN0cmVhbSgpOworCisgIC8vIGltcGxlbWVudHMgWmVyb0NvcHlPdXRwdXRTdHJlYW0gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIGJvb2wgTmV4dCh2b2lkKiogZGF0YSwgaW50KiBzaXplKTsKKyAgdm9pZCBCYWNrVXAoaW50IGNvdW50KTsKKyAgaW50NjQgQnl0ZUNvdW50KCkgY29uc3Q7CisKKyBwcml2YXRlOgorICB1aW50OCogY29uc3QgZGF0YV87ICAgICAgICAvLyBUaGUgYnl0ZSBhcnJheS4KKyAgY29uc3QgaW50IHNpemVfOyAgICAgICAgICAgLy8gVG90YWwgc2l6ZSBvZiB0aGUgYXJyYXkuCisgIGNvbnN0IGludCBibG9ja19zaXplXzsgICAgIC8vIEhvdyBtYW55IGJ5dGVzIHRvIHJldHVybiBhdCBhIHRpbWUuCisKKyAgaW50IHBvc2l0aW9uXzsKKyAgaW50IGxhc3RfcmV0dXJuZWRfc2l6ZV87ICAgLy8gSG93IG1hbnkgYnl0ZXMgd2UgcmV0dXJuZWQgbGFzdCB0aW1lIE5leHQoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB3YXMgY2FsbGVkICh1c2VkIGZvciBlcnJvciBjaGVja2luZyBvbmx5KS4KKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoQXJyYXlPdXRwdXRTdHJlYW0pOworfTsKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisvLyBBIFplcm9Db3B5T3V0cHV0U3RyZWFtIHdoaWNoIGFwcGVuZHMgYnl0ZXMgdG8gYSBzdHJpbmcuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgU3RyaW5nT3V0cHV0U3RyZWFtIDogcHVibGljIFplcm9Db3B5T3V0cHV0U3RyZWFtIHsKKyBwdWJsaWM6CisgIC8vIENyZWF0ZSBhIFN0cmluZ091dHB1dFN0cmVhbSB3aGljaCBhcHBlbmRzIGJ5dGVzIHRvIHRoZSBnaXZlbiBzdHJpbmcuCisgIC8vIFRoZSBzdHJpbmcgcmVtYWlucyBwcm9wZXJ0eSBvZiB0aGUgY2FsbGVyLCBidXQgaXQgaXMgbXV0YXRlZCBpbiBhcmJpdHJhcnkKKyAgLy8gd2F5cyBhbmQgTVVTVCBOT1QgYmUgYWNjZXNzZWQgaW4gYW55IHdheSB1bnRpbCB5b3UncmUgZG9uZSB3aXRoIHRoZQorICAvLyBzdHJlYW0uIEVpdGhlciBiZSBzdXJlIHRoZXJlJ3Mgbm8gZnVydGhlciB1c2FnZSwgb3IgKHNhZmVzdCkgZGVzdHJveSB0aGUKKyAgLy8gc3RyZWFtIGJlZm9yZSB1c2luZyB0aGUgY29udGVudHMuCisgIC8vCisgIC8vIEhpbnQ6ICBJZiB5b3UgY2FsbCB0YXJnZXQtPnJlc2VydmUobikgYmVmb3JlIGNyZWF0aW5nIHRoZSBzdHJlYW0sCisgIC8vICAgdGhlIGZpcnN0IGNhbGwgdG8gTmV4dCgpIHdpbGwgcmV0dXJuIGF0IGxlYXN0IG4gYnl0ZXMgb2YgYnVmZmVyCisgIC8vICAgc3BhY2UuCisgIGV4cGxpY2l0IFN0cmluZ091dHB1dFN0cmVhbShzdHJpbmcqIHRhcmdldCk7CisgIH5TdHJpbmdPdXRwdXRTdHJlYW0oKTsKKworICAvLyBpbXBsZW1lbnRzIFplcm9Db3B5T3V0cHV0U3RyZWFtIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICBib29sIE5leHQodm9pZCoqIGRhdGEsIGludCogc2l6ZSk7CisgIHZvaWQgQmFja1VwKGludCBjb3VudCk7CisgIGludDY0IEJ5dGVDb3VudCgpIGNvbnN0OworCisgcHJvdGVjdGVkOgorICB2b2lkIFNldFN0cmluZyhzdHJpbmcqIHRhcmdldCk7CisKKyBwcml2YXRlOgorICBzdGF0aWMgY29uc3QgaW50IGtNaW5pbXVtU2l6ZSA9IDE2OworCisgIHN0cmluZyogdGFyZ2V0XzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoU3RyaW5nT3V0cHV0U3RyZWFtKTsKK307CisKKy8vIExhenlTdHJpbmdPdXRwdXRTdHJlYW0gaXMgYSBTdHJpbmdPdXRwdXRTdHJlYW0gd2l0aCBsYXp5IGFjcXVpc2l0aW9uIG9mCisvLyB0aGUgb3V0cHV0IHN0cmluZyBmcm9tIGEgY2FsbGJhY2suIFRoZSBzdHJpbmcgaXMgb3duZWQgZXh0ZXJuYWxseSwgYW5kIG5vdAorLy8gZGVsZXRlZCBpbiB0aGUgc3RyZWFtIGRlc3RydWN0b3IuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgTGF6eVN0cmluZ091dHB1dFN0cmVhbSA6IHB1YmxpYyBTdHJpbmdPdXRwdXRTdHJlYW0geworIHB1YmxpYzoKKyAgLy8gQ2FsbGJhY2sgc2hvdWxkIGJlIHBlcm1hbmVudCAobm9uLXNlbGYtZGVsZXRpbmcpLiBPd25lcnNoaXAgaXMgdHJhbnNmZXJyZWQKKyAgLy8gdG8gdGhlIExhenlTdHJpbmdPdXRwdXRTdHJlYW0uCisgIGV4cGxpY2l0IExhenlTdHJpbmdPdXRwdXRTdHJlYW0oUmVzdWx0Q2FsbGJhY2s8c3RyaW5nKj4qIGNhbGxiYWNrKTsKKyAgfkxhenlTdHJpbmdPdXRwdXRTdHJlYW0oKTsKKworICAvLyBpbXBsZW1lbnRzIFplcm9Db3B5T3V0cHV0U3RyZWFtLCBvdmVycmlkaW5nIFN0cmluZ091dHB1dFN0cmVhbSAtLS0tLS0tLS0tLQorICBib29sIE5leHQodm9pZCoqIGRhdGEsIGludCogc2l6ZSk7CisgIGludDY0IEJ5dGVDb3VudCgpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgY29uc3Qgc2NvcGVkX3B0cjxSZXN1bHRDYWxsYmFjazxzdHJpbmcqPiA+IGNhbGxiYWNrXzsKKyAgYm9vbCBzdHJpbmdfaXNfc2V0XzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoTGF6eVN0cmluZ091dHB1dFN0cmVhbSk7Cit9OworCisvLyBOb3RlOiAgVGhlcmUgaXMgbm8gU3RyaW5nSW5wdXRTdHJlYW0uICBJbnN0ZWFkLCBqdXN0IGNyZWF0ZSBhbgorLy8gQXJyYXlJbnB1dFN0cmVhbSBhcyBmb2xsb3dzOgorLy8gICBBcnJheUlucHV0U3RyZWFtIGlucHV0KHN0ci5kYXRhKCksIHN0ci5zaXplKCkpOworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKy8vIEEgZ2VuZXJpYyB0cmFkaXRpb25hbCBpbnB1dCBzdHJlYW0gaW50ZXJmYWNlLgorLy8KKy8vIExvdHMgb2YgdHJhZGl0aW9uYWwgaW5wdXQgc3RyZWFtcyAoZS5nLiBmaWxlIGRlc2NyaXB0b3JzLCBDIHN0ZGlvCisvLyBzdHJlYW1zLCBhbmQgQysrIGlvc3RyZWFtcykgZXhwb3NlIGFuIGludGVyZmFjZSB3aGVyZSBldmVyeSByZWFkCisvLyBpbnZvbHZlcyBjb3B5aW5nIGJ5dGVzIGludG8gYSBidWZmZXIuICBJZiB5b3Ugd2FudCB0byB0YWtlIHN1Y2ggYW4KKy8vIGludGVyZmFjZSBhbmQgbWFrZSBhIFplcm9Db3B5SW5wdXRTdHJlYW0gYmFzZWQgb24gaXQsIHNpbXBseSBpbXBsZW1lbnQKKy8vIENvcHlpbmdJbnB1dFN0cmVhbSBhbmQgdGhlbiB1c2UgQ29weWluZ0lucHV0U3RyZWFtQWRhcHRvci4KKy8vCisvLyBDb3B5aW5nSW5wdXRTdHJlYW0gaW1wbGVtZW50YXRpb25zIHNob3VsZCBhdm9pZCBidWZmZXJpbmcgaWYgcG9zc2libGUuCisvLyBDb3B5aW5nSW5wdXRTdHJlYW1BZGFwdG9yIGRvZXMgaXRzIG93biBidWZmZXJpbmcgYW5kIHdpbGwgcmVhZCBkYXRhCisvLyBpbiBsYXJnZSBibG9ja3MuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgQ29weWluZ0lucHV0U3RyZWFtIHsKKyBwdWJsaWM6CisgIHZpcnR1YWwgfkNvcHlpbmdJbnB1dFN0cmVhbSgpOworCisgIC8vIFJlYWRzIHVwIHRvICJzaXplIiBieXRlcyBpbnRvIHRoZSBnaXZlbiBidWZmZXIuICBSZXR1cm5zIHRoZSBudW1iZXIgb2YKKyAgLy8gYnl0ZXMgcmVhZC4gIFJlYWQoKSB3YWl0cyB1bnRpbCBhdCBsZWFzdCBvbmUgYnl0ZSBpcyBhdmFpbGFibGUsIG9yCisgIC8vIHJldHVybnMgemVybyBpZiBubyBieXRlcyB3aWxsIGV2ZXIgYmVjb21lIGF2YWlsYWJsZSAoRU9GKSwgb3IgLTEgaWYgYQorICAvLyBwZXJtYW5lbnQgcmVhZCBlcnJvciBvY2N1cnJlZC4KKyAgdmlydHVhbCBpbnQgUmVhZCh2b2lkKiBidWZmZXIsIGludCBzaXplKSA9IDA7CisKKyAgLy8gU2tpcHMgdGhlIG5leHQgImNvdW50IiBieXRlcyBvZiBpbnB1dC4gIFJldHVybnMgdGhlIG51bWJlciBvZiBieXRlcworICAvLyBhY3R1YWxseSBza2lwcGVkLiAgVGhpcyB3aWxsIGFsd2F5cyBiZSBleGFjdGx5IGVxdWFsIHRvICJjb3VudCIgdW5sZXNzCisgIC8vIEVPRiB3YXMgcmVhY2hlZCBvciBhIHBlcm1hbmVudCByZWFkIGVycm9yIG9jY3VycmVkLgorICAvLworICAvLyBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBqdXN0IHJlcGVhdGVkbHkgY2FsbHMgUmVhZCgpIGludG8gYSBzY3JhdGNoCisgIC8vIGJ1ZmZlci4KKyAgdmlydHVhbCBpbnQgU2tpcChpbnQgY291bnQpOworfTsKKworLy8gQSBaZXJvQ29weUlucHV0U3RyZWFtIHdoaWNoIHJlYWRzIGZyb20gYSBDb3B5aW5nSW5wdXRTdHJlYW0uICBUaGlzIGlzCisvLyB1c2VmdWwgZm9yIGltcGxlbWVudGluZyBaZXJvQ29weUlucHV0U3RyZWFtcyB0aGF0IHJlYWQgZnJvbSB0cmFkaXRpb25hbAorLy8gc3RyZWFtcy4gIE5vdGUgdGhhdCB0aGlzIGNsYXNzIGlzIG5vdCByZWFsbHkgemVyby1jb3B5LgorLy8KKy8vIElmIHlvdSB3YW50IHRvIHJlYWQgZnJvbSBmaWxlIGRlc2NyaXB0b3JzIG9yIEMrKyBpc3RyZWFtcywgdGhpcyBpcworLy8gYWxyZWFkeSBpbXBsZW1lbnRlZCBmb3IgeW91OiAgdXNlIEZpbGVJbnB1dFN0cmVhbSBvciBJc3RyZWFtSW5wdXRTdHJlYW0KKy8vIHJlc3BlY3RpdmVseS4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBDb3B5aW5nSW5wdXRTdHJlYW1BZGFwdG9yIDogcHVibGljIFplcm9Db3B5SW5wdXRTdHJlYW0geworIHB1YmxpYzoKKyAgLy8gQ3JlYXRlcyBhIHN0cmVhbSB0aGF0IHJlYWRzIGZyb20gdGhlIGdpdmVuIENvcHlpbmdJbnB1dFN0cmVhbS4KKyAgLy8gSWYgYSBibG9ja19zaXplIGlzIGdpdmVuLCBpdCBzcGVjaWZpZXMgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0CisgIC8vIHNob3VsZCBiZSByZWFkIGFuZCByZXR1cm5lZCB3aXRoIGVhY2ggY2FsbCB0byBOZXh0KCkuICBPdGhlcndpc2UsCisgIC8vIGEgcmVhc29uYWJsZSBkZWZhdWx0IGlzIHVzZWQuICBUaGUgY2FsbGVyIHJldGFpbnMgb3duZXJzaGlwIG9mCisgIC8vIGNvcHlpbmdfc3RyZWFtIHVubGVzcyBTZXRPd25zQ29weWluZ1N0cmVhbSh0cnVlKSBpcyBjYWxsZWQuCisgIGV4cGxpY2l0IENvcHlpbmdJbnB1dFN0cmVhbUFkYXB0b3IoQ29weWluZ0lucHV0U3RyZWFtKiBjb3B5aW5nX3N0cmVhbSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYmxvY2tfc2l6ZSA9IC0xKTsKKyAgfkNvcHlpbmdJbnB1dFN0cmVhbUFkYXB0b3IoKTsKKworICAvLyBDYWxsIFNldE93bnNDb3B5aW5nU3RyZWFtKHRydWUpIHRvIHRlbGwgdGhlIENvcHlpbmdJbnB1dFN0cmVhbUFkYXB0b3IgdG8KKyAgLy8gZGVsZXRlIHRoZSB1bmRlcmx5aW5nIENvcHlpbmdJbnB1dFN0cmVhbSB3aGVuIGl0IGlzIGRlc3Ryb3llZC4KKyAgdm9pZCBTZXRPd25zQ29weWluZ1N0cmVhbShib29sIHZhbHVlKSB7IG93bnNfY29weWluZ19zdHJlYW1fID0gdmFsdWU7IH0KKworICAvLyBpbXBsZW1lbnRzIFplcm9Db3B5SW5wdXRTdHJlYW0gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICBib29sIE5leHQoY29uc3Qgdm9pZCoqIGRhdGEsIGludCogc2l6ZSk7CisgIHZvaWQgQmFja1VwKGludCBjb3VudCk7CisgIGJvb2wgU2tpcChpbnQgY291bnQpOworICBpbnQ2NCBCeXRlQ291bnQoKSBjb25zdDsKKworIHByaXZhdGU6CisgIC8vIEluc3VyZXMgdGhhdCBidWZmZXJfIGlzIG5vdCBOVUxMLgorICB2b2lkIEFsbG9jYXRlQnVmZmVySWZOZWVkZWQoKTsKKyAgLy8gRnJlZXMgdGhlIGJ1ZmZlciBhbmQgcmVzZXRzIGJ1ZmZlcl91c2VkXy4KKyAgdm9pZCBGcmVlQnVmZmVyKCk7CisKKyAgLy8gVGhlIHVuZGVybHlpbmcgY29weWluZyBzdHJlYW0uCisgIENvcHlpbmdJbnB1dFN0cmVhbSogY29weWluZ19zdHJlYW1fOworICBib29sIG93bnNfY29weWluZ19zdHJlYW1fOworCisgIC8vIFRydWUgaWYgd2UgaGF2ZSBzZWVuIGEgcGVybWVuYW50IGVycm9yIGZyb20gdGhlIHVuZGVybHlpbmcgc3RyZWFtLgorICBib29sIGZhaWxlZF87CisKKyAgLy8gVGhlIGN1cnJlbnQgcG9zaXRpb24gb2YgY29weWluZ19zdHJlYW1fLCByZWxhdGl2ZSB0byB0aGUgcG9pbnQgd2hlcmUKKyAgLy8gd2Ugc3RhcnRlZCByZWFkaW5nLgorICBpbnQ2NCBwb3NpdGlvbl87CisKKyAgLy8gRGF0YSBpcyByZWFkIGludG8gdGhpcyBidWZmZXIuICBJdCBtYXkgYmUgTlVMTCBpZiBubyBidWZmZXIgaXMgY3VycmVudGx5CisgIC8vIGluIHVzZS4gIE90aGVyd2lzZSwgaXQgcG9pbnRzIHRvIGFuIGFycmF5IG9mIHNpemUgYnVmZmVyX3NpemVfLgorICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfYXJyYXk8dWludDg+IGJ1ZmZlcl87CisgIGNvbnN0IGludCBidWZmZXJfc2l6ZV87CisKKyAgLy8gTnVtYmVyIG9mIHZhbGlkIGJ5dGVzIGN1cnJlbnRseSBpbiB0aGUgYnVmZmVyIChpLmUuIHRoZSBzaXplIGxhc3QKKyAgLy8gcmV0dXJuZWQgYnkgTmV4dCgpKS4gIDAgPD0gYnVmZmVyX3VzZWRfIDw9IGJ1ZmZlcl9zaXplXy4KKyAgaW50IGJ1ZmZlcl91c2VkXzsKKworICAvLyBOdW1iZXIgb2YgYnl0ZXMgaW4gdGhlIGJ1ZmZlciB3aGljaCB3ZXJlIGJhY2tlZCB1cCBvdmVyIGJ5IGEgY2FsbCB0bworICAvLyBCYWNrVXAoKS4gIFRoZXNlIG5lZWQgdG8gYmUgcmV0dXJuZWQgYWdhaW4uCisgIC8vIDAgPD0gYmFja3VwX2J5dGVzXyA8PSBidWZmZXJfdXNlZF8KKyAgaW50IGJhY2t1cF9ieXRlc187CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKENvcHlpbmdJbnB1dFN0cmVhbUFkYXB0b3IpOworfTsKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisvLyBBIGdlbmVyaWMgdHJhZGl0aW9uYWwgb3V0cHV0IHN0cmVhbSBpbnRlcmZhY2UuCisvLworLy8gTG90cyBvZiB0cmFkaXRpb25hbCBvdXRwdXQgc3RyZWFtcyAoZS5nLiBmaWxlIGRlc2NyaXB0b3JzLCBDIHN0ZGlvCisvLyBzdHJlYW1zLCBhbmQgQysrIGlvc3RyZWFtcykgZXhwb3NlIGFuIGludGVyZmFjZSB3aGVyZSBldmVyeSB3cml0ZQorLy8gaW52b2x2ZXMgY29weWluZyBieXRlcyBmcm9tIGEgYnVmZmVyLiAgSWYgeW91IHdhbnQgdG8gdGFrZSBzdWNoIGFuCisvLyBpbnRlcmZhY2UgYW5kIG1ha2UgYSBaZXJvQ29weU91dHB1dFN0cmVhbSBiYXNlZCBvbiBpdCwgc2ltcGx5IGltcGxlbWVudAorLy8gQ29weWluZ091dHB1dFN0cmVhbSBhbmQgdGhlbiB1c2UgQ29weWluZ091dHB1dFN0cmVhbUFkYXB0b3IuCisvLworLy8gQ29weWluZ091dHB1dFN0cmVhbSBpbXBsZW1lbnRhdGlvbnMgc2hvdWxkIGF2b2lkIGJ1ZmZlcmluZyBpZiBwb3NzaWJsZS4KKy8vIENvcHlpbmdPdXRwdXRTdHJlYW1BZGFwdG9yIGRvZXMgaXRzIG93biBidWZmZXJpbmcgYW5kIHdpbGwgd3JpdGUgZGF0YQorLy8gaW4gbGFyZ2UgYmxvY2tzLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIENvcHlpbmdPdXRwdXRTdHJlYW0geworIHB1YmxpYzoKKyAgdmlydHVhbCB+Q29weWluZ091dHB1dFN0cmVhbSgpOworCisgIC8vIFdyaXRlcyAic2l6ZSIgYnl0ZXMgZnJvbSB0aGUgZ2l2ZW4gYnVmZmVyIHRvIHRoZSBvdXRwdXQuICBSZXR1cm5zIHRydWUKKyAgLy8gaWYgc3VjY2Vzc2Z1bCwgZmFsc2Ugb24gYSB3cml0ZSBlcnJvci4KKyAgdmlydHVhbCBib29sIFdyaXRlKGNvbnN0IHZvaWQqIGJ1ZmZlciwgaW50IHNpemUpID0gMDsKK307CisKKy8vIEEgWmVyb0NvcHlPdXRwdXRTdHJlYW0gd2hpY2ggd3JpdGVzIHRvIGEgQ29weWluZ091dHB1dFN0cmVhbS4gIFRoaXMgaXMKKy8vIHVzZWZ1bCBmb3IgaW1wbGVtZW50aW5nIFplcm9Db3B5T3V0cHV0U3RyZWFtcyB0aGF0IHdyaXRlIHRvIHRyYWRpdGlvbmFsCisvLyBzdHJlYW1zLiAgTm90ZSB0aGF0IHRoaXMgY2xhc3MgaXMgbm90IHJlYWxseSB6ZXJvLWNvcHkuCisvLworLy8gSWYgeW91IHdhbnQgdG8gd3JpdGUgdG8gZmlsZSBkZXNjcmlwdG9ycyBvciBDKysgb3N0cmVhbXMsIHRoaXMgaXMKKy8vIGFscmVhZHkgaW1wbGVtZW50ZWQgZm9yIHlvdTogIHVzZSBGaWxlT3V0cHV0U3RyZWFtIG9yIE9zdHJlYW1PdXRwdXRTdHJlYW0KKy8vIHJlc3BlY3RpdmVseS4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBDb3B5aW5nT3V0cHV0U3RyZWFtQWRhcHRvciA6IHB1YmxpYyBaZXJvQ29weU91dHB1dFN0cmVhbSB7CisgcHVibGljOgorICAvLyBDcmVhdGVzIGEgc3RyZWFtIHRoYXQgd3JpdGVzIHRvIHRoZSBnaXZlbiBVbml4IGZpbGUgZGVzY3JpcHRvci4KKyAgLy8gSWYgYSBibG9ja19zaXplIGlzIGdpdmVuLCBpdCBzcGVjaWZpZXMgdGhlIHNpemUgb2YgdGhlIGJ1ZmZlcnMKKyAgLy8gdGhhdCBzaG91bGQgYmUgcmV0dXJuZWQgYnkgTmV4dCgpLiAgT3RoZXJ3aXNlLCBhIHJlYXNvbmFibGUgZGVmYXVsdAorICAvLyBpcyB1c2VkLgorICBleHBsaWNpdCBDb3B5aW5nT3V0cHV0U3RyZWFtQWRhcHRvcihDb3B5aW5nT3V0cHV0U3RyZWFtKiBjb3B5aW5nX3N0cmVhbSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGJsb2NrX3NpemUgPSAtMSk7CisgIH5Db3B5aW5nT3V0cHV0U3RyZWFtQWRhcHRvcigpOworCisgIC8vIFdyaXRlcyBhbGwgcGVuZGluZyBkYXRhIHRvIHRoZSB1bmRlcmx5aW5nIHN0cmVhbS4gIFJldHVybnMgZmFsc2UgaWYgYQorICAvLyB3cml0ZSBlcnJvciBvY2N1cnJlZCBvbiB0aGUgdW5kZXJseWluZyBzdHJlYW0uICAoVGhlIHVuZGVybHlpbmcKKyAgLy8gc3RyZWFtIGl0c2VsZiBpcyBub3QgbmVjZXNzYXJpbHkgZmx1c2hlZC4pCisgIGJvb2wgRmx1c2goKTsKKworICAvLyBDYWxsIFNldE93bnNDb3B5aW5nU3RyZWFtKHRydWUpIHRvIHRlbGwgdGhlIENvcHlpbmdPdXRwdXRTdHJlYW1BZGFwdG9yIHRvCisgIC8vIGRlbGV0ZSB0aGUgdW5kZXJseWluZyBDb3B5aW5nT3V0cHV0U3RyZWFtIHdoZW4gaXQgaXMgZGVzdHJveWVkLgorICB2b2lkIFNldE93bnNDb3B5aW5nU3RyZWFtKGJvb2wgdmFsdWUpIHsgb3duc19jb3B5aW5nX3N0cmVhbV8gPSB2YWx1ZTsgfQorCisgIC8vIGltcGxlbWVudHMgWmVyb0NvcHlPdXRwdXRTdHJlYW0gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIGJvb2wgTmV4dCh2b2lkKiogZGF0YSwgaW50KiBzaXplKTsKKyAgdm9pZCBCYWNrVXAoaW50IGNvdW50KTsKKyAgaW50NjQgQnl0ZUNvdW50KCkgY29uc3Q7CisKKyBwcml2YXRlOgorICAvLyBXcml0ZSB0aGUgY3VycmVudCBidWZmZXIsIGlmIGl0IGlzIHByZXNlbnQuCisgIGJvb2wgV3JpdGVCdWZmZXIoKTsKKyAgLy8gSW5zdXJlcyB0aGF0IGJ1ZmZlcl8gaXMgbm90IE5VTEwuCisgIHZvaWQgQWxsb2NhdGVCdWZmZXJJZk5lZWRlZCgpOworICAvLyBGcmVlcyB0aGUgYnVmZmVyLgorICB2b2lkIEZyZWVCdWZmZXIoKTsKKworICAvLyBUaGUgdW5kZXJseWluZyBjb3B5aW5nIHN0cmVhbS4KKyAgQ29weWluZ091dHB1dFN0cmVhbSogY29weWluZ19zdHJlYW1fOworICBib29sIG93bnNfY29weWluZ19zdHJlYW1fOworCisgIC8vIFRydWUgaWYgd2UgaGF2ZSBzZWVuIGEgcGVybWVuYW50IGVycm9yIGZyb20gdGhlIHVuZGVybHlpbmcgc3RyZWFtLgorICBib29sIGZhaWxlZF87CisKKyAgLy8gVGhlIGN1cnJlbnQgcG9zaXRpb24gb2YgY29weWluZ19zdHJlYW1fLCByZWxhdGl2ZSB0byB0aGUgcG9pbnQgd2hlcmUKKyAgLy8gd2Ugc3RhcnRlZCB3cml0aW5nLgorICBpbnQ2NCBwb3NpdGlvbl87CisKKyAgLy8gRGF0YSBpcyB3cml0dGVuIGZyb20gdGhpcyBidWZmZXIuICBJdCBtYXkgYmUgTlVMTCBpZiBubyBidWZmZXIgaXMKKyAgLy8gY3VycmVudGx5IGluIHVzZS4gIE90aGVyd2lzZSwgaXQgcG9pbnRzIHRvIGFuIGFycmF5IG9mIHNpemUgYnVmZmVyX3NpemVfLgorICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfYXJyYXk8dWludDg+IGJ1ZmZlcl87CisgIGNvbnN0IGludCBidWZmZXJfc2l6ZV87CisKKyAgLy8gTnVtYmVyIG9mIHZhbGlkIGJ5dGVzIGN1cnJlbnRseSBpbiB0aGUgYnVmZmVyIChpLmUuIHRoZSBzaXplIGxhc3QKKyAgLy8gcmV0dXJuZWQgYnkgTmV4dCgpKS4gIFdoZW4gQmFja1VwKCkgaXMgY2FsbGVkLCB3ZSBqdXN0IHJlZHVjZSB0aGlzLgorICAvLyAwIDw9IGJ1ZmZlcl91c2VkXyA8PSBidWZmZXJfc2l6ZV8uCisgIGludCBidWZmZXJfdXNlZF87CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKENvcHlpbmdPdXRwdXRTdHJlYW1BZGFwdG9yKTsKK307CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworLy8gbXV0YWJsZV9zdHJpbmdfZGF0YSgpIGFuZCBhc19zdHJpbmdfZGF0YSgpIGFyZSB3b3JrYXJvdW5kcyB0byBpbXByb3ZlCisvLyB0aGUgcGVyZm9ybWFuY2Ugb2Ygd3JpdGluZyBuZXcgZGF0YSB0byBhbiBleGlzdGluZyBzdHJpbmcuICBVbmZvcnR1bmF0ZWx5CisvLyB0aGUgbWV0aG9kcyBwcm92aWRlZCBieSB0aGUgc3RyaW5nIGNsYXNzIGFyZSBzdWJvcHRpbWFsLCBhbmQgdXNpbmcgbWVtY3B5KCkKKy8vIGlzIG1pbGRseSBhbm5veWluZyBiZWNhdXNlIGl0IHJlcXVpcmVzIGl0cyBwb2ludGVyIGFyZ3MgdG8gYmUgbm9uLU5VTEwgZXZlbgorLy8gaWYgd2UgYXNrIGl0IHRvIGNvcHkgMCBieXRlcy4gIEZ1cnRoZXJtb3JlLCBzdHJpbmdfYXNfYXJyYXkoKSBoYXMgdGhlCisvLyBwcm9wZXJ0eSB0aGF0IGl0IGFsd2F5cyByZXR1cm5zIE5VTEwgaWYgaXRzIGFyZyBpcyB0aGUgZW1wdHkgc3RyaW5nLCBleGFjdGx5CisvLyB3aGF0IHdlIHdhbnQgdG8gYXZvaWQgaWYgd2UncmUgdXNpbmcgaXQgaW4gY29uanVuY3Rpb24gd2l0aCBtZW1jcHkoKSEKKy8vIFdpdGggQysrMTEsIHRoZSBkZXNpcmVkIG1lbWNweSgpIGJvaWxzIGRvd24gdG8gbWVtY3B5KC4uLiwgJigqcylbMF0sIHNpemUpLAorLy8gd2hlcmUgcyBpcyBhIHN0cmluZyouICBXaXRob3V0IEMrKzExLCAmKCpzKVswXSBpcyBub3QgZ3VhcmFudGVlZCB0byBiZSBzYWZlLAorLy8gc28gd2UgdXNlIHN0cmluZ19hc19hcnJheSgpLCBhbmQgbGl2ZSB3aXRoIHRoZSBleHRyYSBsb2dpYyB0aGF0IHRlc3RzIHdoZXRoZXIKKy8vICpzIGlzIGVtcHR5LgorCisvLyBSZXR1cm4gYSBwb2ludGVyIHRvIG11dGFibGUgY2hhcmFjdGVycyB1bmRlcmx5aW5nIHRoZSBnaXZlbiBzdHJpbmcuICBUaGUKKy8vIHJldHVybiB2YWx1ZSBpcyB2YWxpZCB1bnRpbCB0aGUgbmV4dCB0aW1lIHRoZSBzdHJpbmcgaXMgcmVzaXplZC4gIFdlCisvLyB0cnVzdCB0aGUgY2FsbGVyIHRvIHRyZWF0IHRoZSByZXR1cm4gdmFsdWUgYXMgYW4gYXJyYXkgb2YgbGVuZ3RoIHMtPnNpemUoKS4KK2lubGluZSBjaGFyKiBtdXRhYmxlX3N0cmluZ19kYXRhKHN0cmluZyogcykgeworI2lmZGVmIExBTkdfQ1hYMTEKKyAgLy8gVGhpcyBzaG91bGQgYmUgc2ltcGxlciAmIGZhc3RlciB0aGFuIHN0cmluZ19hc19hcnJheSgpIGJlY2F1c2UgdGhlIGxhdHRlcgorICAvLyBpcyBndWFyYW50ZWVkIHRvIHJldHVybiBOVUxMIHdoZW4gKnMgaXMgZW1wdHksIHNvIGl0IGhhcyB0byBjaGVjayBmb3IgdGhhdC4KKyAgcmV0dXJuICYoKnMpWzBdOworI2Vsc2UKKyAgcmV0dXJuIHN0cmluZ19hc19hcnJheShzKTsKKyNlbmRpZgorfQorCisvLyBhc19zdHJpbmdfZGF0YShzKSBpcyBlcXVpdmFsZW50IHRvCisvLyAgKHsgY2hhciogcCA9IG11dGFibGVfc3RyaW5nX2RhdGEocyk7IG1ha2VfcGFpcihwLCBwICE9IE5VTEwpOyB9KQorLy8gU29tZXRpbWVzIGl0J3MgZmFzdGVyOiBpbiBzb21lIHNjZW5hcmlvcyBwIGNhbm5vdCBiZSBOVUxMLCBhbmQgdGhlbiB0aGUKKy8vIGNvZGUgY2FuIGF2b2lkIHRoYXQgY2hlY2suCitpbmxpbmUgc3RkOjpwYWlyPGNoYXIqLCBib29sPiBhc19zdHJpbmdfZGF0YShzdHJpbmcqIHMpIHsKKyAgY2hhciAqcCA9IG11dGFibGVfc3RyaW5nX2RhdGEocyk7CisjaWZkZWYgTEFOR19DWFgxMQorICByZXR1cm4gc3RkOjptYWtlX3BhaXIocCwgdHJ1ZSk7CisjZWxzZQorICByZXR1cm4gbWFrZV9wYWlyKHAsIHAgIT0gTlVMTCk7CisjZW5kaWYKK30KKworfSAgLy8gbmFtZXNwYWNlIGlvCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfSU9fWkVST19DT1BZX1NUUkVBTV9JTVBMX0xJVEVfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1fdW5pdHRlc3QuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1fdW5pdHRlc3QuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGM3MzU4YwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbV91bml0dGVzdC5jYwpAQCAtMCwwICsxLDEwMDcgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBUZXN0aW5nIHN0cmF0ZWd5OiAgRm9yIGVhY2ggdHlwZSBvZiBJL08gKGFycmF5LCBzdHJpbmcsIGZpbGUsIGV0Yy4pIHdlCisvLyBjcmVhdGUgYW4gb3V0cHV0IHN0cmVhbSBhbmQgd3JpdGUgc29tZSBkYXRhIHRvIGl0LCB0aGVuIGNyZWF0ZSBhCisvLyBjb3JyZXNwb25kaW5nIGlucHV0IHN0cmVhbSB0byByZWFkIHRoZSBzYW1lIGRhdGEgYmFjayBhbmQgZXhwZWN0IGl0IHRvCisvLyBtYXRjaC4gIFdoZW4gdGhlIGRhdGEgaXMgd3JpdHRlbiwgaXQgaXMgd3JpdHRlbiBpbiBzZXZlcmFsIHNtYWxsIGNodW5rcworLy8gb2YgdmFyeWluZyBzaXplcywgd2l0aCBhIEJhY2tVcCgpIGFmdGVyIGVhY2ggY2h1bmsuICBJdCBpcyByZWFkIGJhY2sKKy8vIHNpbWlsYXJseSwgYnV0IHdpdGggY2h1bmtzIHNlcGFyYXRlZCBhdCBkaWZmZXJlbnQgcG9pbnRzLiAgVGhlIHdob2xlCisvLyBwcm9jZXNzIGlzIHJ1biB3aXRoIGEgdmFyaWV0eSBvZiBibG9jayBzaXplcyBmb3IgYm90aCB0aGUgaW5wdXQgYW5kCisvLyB0aGUgb3V0cHV0LgorLy8KKy8vIFRPRE8oa2VudG9uKTogIFJld3JpdGUgdGhpcyB0ZXN0IHRvIGJyaW5nIGl0IHVwIHRvIHRoZSBzdGFuZGFyZHMgb2YgYWxsCisvLyAgIHRoZSBvdGhlciBwcm90bzIgdGVzdHMuICBNYXkgd2FudCB0byB3YWl0IGZvciBnVGVzdCB0byBpbXBsZW1lbnQKKy8vICAgInBhcmFtZXRpemVkIHRlc3RzIiBzbyB0aGF0IG9uZSBzZXQgb2YgdGVzdHMgY2FuIGJlIHVzZWQgb24gYWxsIHRoZQorLy8gICBpbXBsZW1lbnRhdGlvbnMuCisKKworI2lmZGVmIF9NU0NfVkVSCisjaW5jbHVkZSA8aW8uaD4KKyNlbHNlCisjaW5jbHVkZSA8dW5pc3RkLmg+CisjZW5kaWYKKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKyNpbmNsdWRlIDxzeXMvc3RhdC5oPgorI2luY2x1ZGUgPGZjbnRsLmg+CisjaW5jbHVkZSA8ZXJybm8uaD4KKyNpbmNsdWRlIDxtZW1vcnk+CisjaWZuZGVmIF9TSEFSRURfUFRSX0gKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc2hhcmVkX3B0ci5oPgorI2VuZGlmCisjaW5jbHVkZSA8c3N0cmVhbT4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX2ltcGwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmg+CisKKyNpZiBIQVZFX1pMSUIKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vZ3ppcF9zdHJlYW0uaD4KKyNlbmRpZgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9sb2dnaW5nLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3Njb3BlZF9wdHIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZmlsZS5oPgorI2luY2x1ZGUgPGd0ZXN0L2d0ZXN0Lmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbyB7CituYW1lc3BhY2UgeworCisjaWZkZWYgX1dJTjMyCisjZGVmaW5lIHBpcGUoZmRzKSBfcGlwZShmZHMsIDQwOTYsIE9fQklOQVJZKQorI2VuZGlmCisKKyNpZm5kZWYgT19CSU5BUlkKKyNpZmRlZiBfT19CSU5BUlkKKyNkZWZpbmUgT19CSU5BUlkgX09fQklOQVJZCisjZWxzZQorI2RlZmluZSBPX0JJTkFSWSAwICAgICAvLyBJZiB0aGlzIGlzbid0IGRlZmluZWQsIHRoZSBwbGF0Zm9ybSBkb2Vzbid0IG5lZWQgaXQuCisjZW5kaWYKKyNlbmRpZgorCitjbGFzcyBJb1Rlc3QgOiBwdWJsaWMgdGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICAvLyBUZXN0IGhlbHBlcnMuCisKKyAgLy8gSGVscGVyIHRvIHdyaXRlIGFuIGFycmF5IG9mIGRhdGEgdG8gYW4gb3V0cHV0IHN0cmVhbS4KKyAgYm9vbCBXcml0ZVRvT3V0cHV0KFplcm9Db3B5T3V0cHV0U3RyZWFtKiBvdXRwdXQsIGNvbnN0IHZvaWQqIGRhdGEsIGludCBzaXplKTsKKyAgLy8gSGVscGVyIHRvIHJlYWQgYSBmaXhlZC1sZW5ndGggYXJyYXkgb2YgZGF0YSBmcm9tIGFuIGlucHV0IHN0cmVhbS4KKyAgaW50IFJlYWRGcm9tSW5wdXQoWmVyb0NvcHlJbnB1dFN0cmVhbSogaW5wdXQsIHZvaWQqIGRhdGEsIGludCBzaXplKTsKKyAgLy8gV3JpdGUgYSBzdHJpbmcgdG8gdGhlIG91dHB1dCBzdHJlYW0uCisgIHZvaWQgV3JpdGVTdHJpbmcoWmVyb0NvcHlPdXRwdXRTdHJlYW0qIG91dHB1dCwgY29uc3Qgc3RyaW5nJiBzdHIpOworICAvLyBSZWFkIGEgbnVtYmVyIG9mIGJ5dGVzIGVxdWFsIHRvIHRoZSBzaXplIG9mIHRoZSBnaXZlbiBzdHJpbmcgYW5kIGNoZWNrcworICAvLyB0aGF0IGl0IG1hdGNoZXMgdGhlIHN0cmluZy4KKyAgdm9pZCBSZWFkU3RyaW5nKFplcm9Db3B5SW5wdXRTdHJlYW0qIGlucHV0LCBjb25zdCBzdHJpbmcmIHN0cik7CisgIC8vIFdyaXRlcyBzb21lIHRleHQgdG8gdGhlIG91dHB1dCBzdHJlYW0gaW4gYSBwYXJ0aWN1bGFyIG9yZGVyLiAgUmV0dXJucworICAvLyB0aGUgbnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW4sIGluY2FzZSB0aGUgY2FsbGVyIG5lZWRzIHRoYXQgdG8gc2V0IHVwIGFuCisgIC8vIGlucHV0IHN0cmVhbS4KKyAgaW50IFdyaXRlU3R1ZmYoWmVyb0NvcHlPdXRwdXRTdHJlYW0qIG91dHB1dCk7CisgIC8vIFJlYWRzIHRleHQgZnJvbSBhbiBpbnB1dCBzdHJlYW0gYW5kIGV4cGVjdHMgaXQgdG8gbWF0Y2ggd2hhdAorICAvLyBXcml0ZVN0dWZmKCkgd3JpdGVzLgorICB2b2lkIFJlYWRTdHVmZihaZXJvQ29weUlucHV0U3RyZWFtKiBpbnB1dCk7CisKKyAgLy8gU2ltaWxhciB0byBXcml0ZVN0dWZmLCBidXQgcGVyZm9ybXMgbW9yZSBzb3BoaXN0aWNhdGVkIHRlc3RpbmcuCisgIGludCBXcml0ZVN0dWZmTGFyZ2UoWmVyb0NvcHlPdXRwdXRTdHJlYW0qIG91dHB1dCk7CisgIC8vIFJlYWRzIGFuZCB0ZXN0cyBhIHN0cmVhbSB0aGF0IHNob3VsZCBoYXZlIGJlZW4gd3JpdHRlbiB0bworICAvLyB2aWEgV3JpdGVTdHVmZkxhcmdlKCkuCisgIHZvaWQgUmVhZFN0dWZmTGFyZ2UoWmVyb0NvcHlJbnB1dFN0cmVhbSogaW5wdXQpOworCisjaWYgSEFWRV9aTElCCisgIHN0cmluZyBDb21wcmVzcyhjb25zdCBzdHJpbmcmIGRhdGEsIGNvbnN0IEd6aXBPdXRwdXRTdHJlYW06Ok9wdGlvbnMmIG9wdGlvbnMpOworICBzdHJpbmcgVW5jb21wcmVzcyhjb25zdCBzdHJpbmcmIGRhdGEpOworI2VuZGlmCisKKyAgc3RhdGljIGNvbnN0IGludCBrQmxvY2tTaXplc1tdOworICBzdGF0aWMgY29uc3QgaW50IGtCbG9ja1NpemVDb3VudDsKK307CisKK2NvbnN0IGludCBJb1Rlc3Q6OmtCbG9ja1NpemVzW10gPSB7LTEsIDEsIDIsIDUsIDcsIDEwLCAyMywgNjR9OworY29uc3QgaW50IElvVGVzdDo6a0Jsb2NrU2l6ZUNvdW50ID0gR09PR0xFX0FSUkFZU0laRShJb1Rlc3Q6OmtCbG9ja1NpemVzKTsKKworYm9vbCBJb1Rlc3Q6OldyaXRlVG9PdXRwdXQoWmVyb0NvcHlPdXRwdXRTdHJlYW0qIG91dHB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQqIGRhdGEsIGludCBzaXplKSB7CisgIGNvbnN0IHVpbnQ4KiBpbiA9IHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgdWludDgqPihkYXRhKTsKKyAgaW50IGluX3NpemUgPSBzaXplOworCisgIHZvaWQqIG91dDsKKyAgaW50IG91dF9zaXplOworCisgIHdoaWxlICh0cnVlKSB7CisgICAgaWYgKCFvdXRwdXQtPk5leHQoJm91dCwgJm91dF9zaXplKSkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBFWFBFQ1RfR1Qob3V0X3NpemUsIDApOworCisgICAgaWYgKGluX3NpemUgPD0gb3V0X3NpemUpIHsKKyAgICAgIG1lbWNweShvdXQsIGluLCBpbl9zaXplKTsKKyAgICAgIG91dHB1dC0+QmFja1VwKG91dF9zaXplIC0gaW5fc2l6ZSk7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBtZW1jcHkob3V0LCBpbiwgb3V0X3NpemUpOworICAgIGluICs9IG91dF9zaXplOworICAgIGluX3NpemUgLT0gb3V0X3NpemU7CisgIH0KK30KKworI2RlZmluZSBNQVhfUkVQRUFURURfWkVST1MgMTAwCisKK2ludCBJb1Rlc3Q6OlJlYWRGcm9tSW5wdXQoWmVyb0NvcHlJbnB1dFN0cmVhbSogaW5wdXQsIHZvaWQqIGRhdGEsIGludCBzaXplKSB7CisgIHVpbnQ4KiBvdXQgPSByZWludGVycHJldF9jYXN0PHVpbnQ4Kj4oZGF0YSk7CisgIGludCBvdXRfc2l6ZSA9IHNpemU7CisKKyAgY29uc3Qgdm9pZCogaW47CisgIGludCBpbl9zaXplID0gMDsKKworICBpbnQgcmVwZWF0ZWRfemVyb3MgPSAwOworCisgIHdoaWxlICh0cnVlKSB7CisgICAgaWYgKCFpbnB1dC0+TmV4dCgmaW4sICZpbl9zaXplKSkgeworICAgICAgcmV0dXJuIHNpemUgLSBvdXRfc2l6ZTsKKyAgICB9CisgICAgRVhQRUNUX0dUKGluX3NpemUsIC0xKTsKKyAgICBpZiAoaW5fc2l6ZSA9PSAwKSB7CisgICAgICByZXBlYXRlZF96ZXJvcysrOworICAgIH0gZWxzZSB7CisgICAgICByZXBlYXRlZF96ZXJvcyA9IDA7CisgICAgfQorICAgIEVYUEVDVF9MVChyZXBlYXRlZF96ZXJvcywgTUFYX1JFUEVBVEVEX1pFUk9TKTsKKworICAgIGlmIChvdXRfc2l6ZSA8PSBpbl9zaXplKSB7CisgICAgICBtZW1jcHkob3V0LCBpbiwgb3V0X3NpemUpOworICAgICAgaWYgKGluX3NpemUgPiBvdXRfc2l6ZSkgeworICAgICAgICBpbnB1dC0+QmFja1VwKGluX3NpemUgLSBvdXRfc2l6ZSk7CisgICAgICB9CisgICAgICByZXR1cm4gc2l6ZTsgIC8vIENvcGllZCBhbGwgb2YgaXQuCisgICAgfQorCisgICAgbWVtY3B5KG91dCwgaW4sIGluX3NpemUpOworICAgIG91dCArPSBpbl9zaXplOworICAgIG91dF9zaXplIC09IGluX3NpemU7CisgIH0KK30KKwordm9pZCBJb1Rlc3Q6OldyaXRlU3RyaW5nKFplcm9Db3B5T3V0cHV0U3RyZWFtKiBvdXRwdXQsIGNvbnN0IHN0cmluZyYgc3RyKSB7CisgIEVYUEVDVF9UUlVFKFdyaXRlVG9PdXRwdXQob3V0cHV0LCBzdHIuY19zdHIoKSwgc3RyLnNpemUoKSkpOworfQorCit2b2lkIElvVGVzdDo6UmVhZFN0cmluZyhaZXJvQ29weUlucHV0U3RyZWFtKiBpbnB1dCwgY29uc3Qgc3RyaW5nJiBzdHIpIHsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX2FycmF5PGNoYXI+IGJ1ZmZlcihuZXcgY2hhcltzdHIuc2l6ZSgpICsgMV0pOworICBidWZmZXJbc3RyLnNpemUoKV0gPSAnXDAnOworICBFWFBFQ1RfRVEoUmVhZEZyb21JbnB1dChpbnB1dCwgYnVmZmVyLmdldCgpLCBzdHIuc2l6ZSgpKSwgc3RyLnNpemUoKSk7CisgIEVYUEVDVF9TVFJFUShzdHIuY19zdHIoKSwgYnVmZmVyLmdldCgpKTsKK30KKworaW50IElvVGVzdDo6V3JpdGVTdHVmZihaZXJvQ29weU91dHB1dFN0cmVhbSogb3V0cHV0KSB7CisgIFdyaXRlU3RyaW5nKG91dHB1dCwgIkhlbGxvIHdvcmxkIVxuIik7CisgIFdyaXRlU3RyaW5nKG91dHB1dCwgIlNvbWUgdGUiKTsKKyAgV3JpdGVTdHJpbmcob3V0cHV0LCAieHQuICBCbGFoIGJsYWguIik7CisgIFdyaXRlU3RyaW5nKG91dHB1dCwgImFiY2RlZmciKTsKKyAgV3JpdGVTdHJpbmcob3V0cHV0LCAiMDEyMzQ1Njc4OTAxMjM0NTY3ODkiKTsKKyAgV3JpdGVTdHJpbmcob3V0cHV0LCAiZm9vYmFyIik7CisKKyAgRVhQRUNUX0VRKG91dHB1dC0+Qnl0ZUNvdW50KCksIDY4KTsKKworICBpbnQgcmVzdWx0ID0gb3V0cHV0LT5CeXRlQ291bnQoKTsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworLy8gUmVhZHMgdGV4dCBmcm9tIGFuIGlucHV0IHN0cmVhbSBhbmQgZXhwZWN0cyBpdCB0byBtYXRjaCB3aGF0IFdyaXRlU3R1ZmYoKQorLy8gd3JpdGVzLgordm9pZCBJb1Rlc3Q6OlJlYWRTdHVmZihaZXJvQ29weUlucHV0U3RyZWFtKiBpbnB1dCkgeworICBSZWFkU3RyaW5nKGlucHV0LCAiSGVsbG8gd29ybGQhXG4iKTsKKyAgUmVhZFN0cmluZyhpbnB1dCwgIlNvbWUgdGV4dC4gICIpOworICBSZWFkU3RyaW5nKGlucHV0LCAiQmxhaCAiKTsKKyAgUmVhZFN0cmluZyhpbnB1dCwgImJsYWguIik7CisgIFJlYWRTdHJpbmcoaW5wdXQsICJhYmNkZWZnIik7CisgIEVYUEVDVF9UUlVFKGlucHV0LT5Ta2lwKDIwKSk7CisgIFJlYWRTdHJpbmcoaW5wdXQsICJmb28iKTsKKyAgUmVhZFN0cmluZyhpbnB1dCwgImJhciIpOworCisgIEVYUEVDVF9FUShpbnB1dC0+Qnl0ZUNvdW50KCksIDY4KTsKKworICB1aW50OCBieXRlOworICBFWFBFQ1RfRVEoUmVhZEZyb21JbnB1dChpbnB1dCwgJmJ5dGUsIDEpLCAwKTsKK30KKworaW50IElvVGVzdDo6V3JpdGVTdHVmZkxhcmdlKFplcm9Db3B5T3V0cHV0U3RyZWFtKiBvdXRwdXQpIHsKKyAgV3JpdGVTdHJpbmcob3V0cHV0LCAiSGVsbG8gd29ybGQhXG4iKTsKKyAgV3JpdGVTdHJpbmcob3V0cHV0LCAiU29tZSB0ZSIpOworICBXcml0ZVN0cmluZyhvdXRwdXQsICJ4dC4gIEJsYWggYmxhaC4iKTsKKyAgV3JpdGVTdHJpbmcob3V0cHV0LCBzdHJpbmcoMTAwMDAwLCAneCcpKTsgIC8vIEEgdmVyeSBsb25nIHN0cmluZworICBXcml0ZVN0cmluZyhvdXRwdXQsIHN0cmluZygxMDAwMDAsICd5JykpOyAgLy8gQSB2ZXJ5IGxvbmcgc3RyaW5nCisgIFdyaXRlU3RyaW5nKG91dHB1dCwgIjAxMjM0NTY3ODkwMTIzNDU2Nzg5Iik7CisKKyAgRVhQRUNUX0VRKG91dHB1dC0+Qnl0ZUNvdW50KCksIDIwMDA1NSk7CisKKyAgaW50IHJlc3VsdCA9IG91dHB1dC0+Qnl0ZUNvdW50KCk7CisgIHJldHVybiByZXN1bHQ7Cit9CisKKy8vIFJlYWRzIHRleHQgZnJvbSBhbiBpbnB1dCBzdHJlYW0gYW5kIGV4cGVjdHMgaXQgdG8gbWF0Y2ggd2hhdCBXcml0ZVN0dWZmKCkKKy8vIHdyaXRlcy4KK3ZvaWQgSW9UZXN0OjpSZWFkU3R1ZmZMYXJnZShaZXJvQ29weUlucHV0U3RyZWFtKiBpbnB1dCkgeworICBSZWFkU3RyaW5nKGlucHV0LCAiSGVsbG8gd29ybGQhXG5Tb21lIHRleHQuICAiKTsKKyAgRVhQRUNUX1RSVUUoaW5wdXQtPlNraXAoNSkpOworICBSZWFkU3RyaW5nKGlucHV0LCAiYmxhaC4iKTsKKyAgRVhQRUNUX1RSVUUoaW5wdXQtPlNraXAoMTAwMDAwIC0gMTApKTsKKyAgUmVhZFN0cmluZyhpbnB1dCwgc3RyaW5nKDEwLCAneCcpICsgc3RyaW5nKDEwMDAwMCAtIDIwMDAwLCAneScpKTsKKyAgRVhQRUNUX1RSVUUoaW5wdXQtPlNraXAoMjAwMDAgLSAxMCkpOworICBSZWFkU3RyaW5nKGlucHV0LCAieXl5eXl5eXl5eTAxMjM0NTY3ODkwMTIzNDU2Nzg5Iik7CisKKyAgRVhQRUNUX0VRKGlucHV0LT5CeXRlQ291bnQoKSwgMjAwMDU1KTsKKworICB1aW50OCBieXRlOworICBFWFBFQ1RfRVEoUmVhZEZyb21JbnB1dChpbnB1dCwgJmJ5dGUsIDEpLCAwKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitURVNUX0YoSW9UZXN0LCBBcnJheUlvKSB7CisgIGNvbnN0IGludCBrQnVmZmVyU2l6ZSA9IDI1NjsKKyAgdWludDggYnVmZmVyW2tCdWZmZXJTaXplXTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGtCbG9ja1NpemVDb3VudDsgaSsrKSB7CisgICAgZm9yIChpbnQgaiA9IDA7IGogPCBrQmxvY2tTaXplQ291bnQ7IGorKykgeworICAgICAgaW50IHNpemU7CisgICAgICB7CisgICAgICAgIEFycmF5T3V0cHV0U3RyZWFtIG91dHB1dChidWZmZXIsIGtCdWZmZXJTaXplLCBrQmxvY2tTaXplc1tpXSk7CisgICAgICAgIHNpemUgPSBXcml0ZVN0dWZmKCZvdXRwdXQpOworICAgICAgfQorICAgICAgeworICAgICAgICBBcnJheUlucHV0U3RyZWFtIGlucHV0KGJ1ZmZlciwgc2l6ZSwga0Jsb2NrU2l6ZXNbal0pOworICAgICAgICBSZWFkU3R1ZmYoJmlucHV0KTsKKyAgICAgIH0KKyAgICB9CisgIH0KK30KKworVEVTVF9GKElvVGVzdCwgVHdvU2Vzc2lvbldyaXRlKSB7CisgIC8vIFRlc3QgdGhhdCB0d28gY29uY2F0ZW5hdGVkIHdyaXRlIHNlc3Npb25zIHJlYWQgY29ycmVjdGx5CisKKyAgc3RhdGljIGNvbnN0IGNoYXIqIHN0ckEgPSAiMDEyMzQ1Njc4OSI7CisgIHN0YXRpYyBjb25zdCBjaGFyKiBzdHJCID0gIldoaXJsZWRQZWFzIjsKKyAgY29uc3QgaW50IGtCdWZmZXJTaXplID0gMioxMDI0OworICB1aW50OCogYnVmZmVyID0gbmV3IHVpbnQ4W2tCdWZmZXJTaXplXTsKKyAgY2hhciogdGVtcF9idWZmZXIgPSBuZXcgY2hhcls0MF07CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBrQmxvY2tTaXplQ291bnQ7IGkrKykgeworICAgIGZvciAoaW50IGogPSAwOyBqIDwga0Jsb2NrU2l6ZUNvdW50OyBqKyspIHsKKyAgICAgIEFycmF5T3V0cHV0U3RyZWFtKiBvdXRwdXQgPQorICAgICAgICAgIG5ldyBBcnJheU91dHB1dFN0cmVhbShidWZmZXIsIGtCdWZmZXJTaXplLCBrQmxvY2tTaXplc1tpXSk7CisgICAgICBDb2RlZE91dHB1dFN0cmVhbSogY29kZWRfb3V0cHV0ID0gbmV3IENvZGVkT3V0cHV0U3RyZWFtKG91dHB1dCk7CisgICAgICBjb2RlZF9vdXRwdXQtPldyaXRlVmFyaW50MzIoc3RybGVuKHN0ckEpKTsKKyAgICAgIGNvZGVkX291dHB1dC0+V3JpdGVSYXcoc3RyQSwgc3RybGVuKHN0ckEpKTsKKyAgICAgIGRlbGV0ZSBjb2RlZF9vdXRwdXQ7ICAvLyBmbHVzaAorICAgICAgaW50NjQgcG9zID0gb3V0cHV0LT5CeXRlQ291bnQoKTsKKyAgICAgIGRlbGV0ZSBvdXRwdXQ7CisgICAgICBvdXRwdXQgPSBuZXcgQXJyYXlPdXRwdXRTdHJlYW0oCisgICAgICAgICAgYnVmZmVyICsgcG9zLCBrQnVmZmVyU2l6ZSAtIHBvcywga0Jsb2NrU2l6ZXNbaV0pOworICAgICAgY29kZWRfb3V0cHV0ID0gbmV3IENvZGVkT3V0cHV0U3RyZWFtKG91dHB1dCk7CisgICAgICBjb2RlZF9vdXRwdXQtPldyaXRlVmFyaW50MzIoc3RybGVuKHN0ckIpKTsKKyAgICAgIGNvZGVkX291dHB1dC0+V3JpdGVSYXcoc3RyQiwgc3RybGVuKHN0ckIpKTsKKyAgICAgIGRlbGV0ZSBjb2RlZF9vdXRwdXQ7ICAvLyBmbHVzaAorICAgICAgaW50NjQgc2l6ZSA9IHBvcyArIG91dHB1dC0+Qnl0ZUNvdW50KCk7CisgICAgICBkZWxldGUgb3V0cHV0OworCisgICAgICBBcnJheUlucHV0U3RyZWFtKiBpbnB1dCA9CisgICAgICAgICAgbmV3IEFycmF5SW5wdXRTdHJlYW0oYnVmZmVyLCBzaXplLCBrQmxvY2tTaXplc1tqXSk7CisgICAgICBDb2RlZElucHV0U3RyZWFtKiBjb2RlZF9pbnB1dCA9IG5ldyBDb2RlZElucHV0U3RyZWFtKGlucHV0KTsKKyAgICAgIHVpbnQzMiBpbnNpemU7CisgICAgICBFWFBFQ1RfVFJVRShjb2RlZF9pbnB1dC0+UmVhZFZhcmludDMyKCZpbnNpemUpKTsKKyAgICAgIEVYUEVDVF9FUShzdHJsZW4oc3RyQSksIGluc2l6ZSk7CisgICAgICBFWFBFQ1RfVFJVRShjb2RlZF9pbnB1dC0+UmVhZFJhdyh0ZW1wX2J1ZmZlciwgaW5zaXplKSk7CisgICAgICBFWFBFQ1RfRVEoMCwgbWVtY21wKHRlbXBfYnVmZmVyLCBzdHJBLCBpbnNpemUpKTsKKworICAgICAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQtPlJlYWRWYXJpbnQzMigmaW5zaXplKSk7CisgICAgICBFWFBFQ1RfRVEoc3RybGVuKHN0ckIpLCBpbnNpemUpOworICAgICAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQtPlJlYWRSYXcodGVtcF9idWZmZXIsIGluc2l6ZSkpOworICAgICAgRVhQRUNUX0VRKDAsIG1lbWNtcCh0ZW1wX2J1ZmZlciwgc3RyQiwgaW5zaXplKSk7CisKKyAgICAgIGRlbGV0ZSBjb2RlZF9pbnB1dDsKKyAgICAgIGRlbGV0ZSBpbnB1dDsKKyAgICB9CisgIH0KKworICBkZWxldGUgW10gdGVtcF9idWZmZXI7CisgIGRlbGV0ZSBbXSBidWZmZXI7Cit9CisKKyNpZiBIQVZFX1pMSUIKK1RFU1RfRihJb1Rlc3QsIEd6aXBJbykgeworICBjb25zdCBpbnQga0J1ZmZlclNpemUgPSAyKjEwMjQ7CisgIHVpbnQ4KiBidWZmZXIgPSBuZXcgdWludDhba0J1ZmZlclNpemVdOworICBmb3IgKGludCBpID0gMDsgaSA8IGtCbG9ja1NpemVDb3VudDsgaSsrKSB7CisgICAgZm9yIChpbnQgaiA9IDA7IGogPCBrQmxvY2tTaXplQ291bnQ7IGorKykgeworICAgICAgZm9yIChpbnQgeiA9IDA7IHogPCBrQmxvY2tTaXplQ291bnQ7IHorKykgeworICAgICAgICBpbnQgZ3ppcF9idWZmZXJfc2l6ZSA9IGtCbG9ja1NpemVzW3pdOworICAgICAgICBpbnQgc2l6ZTsKKyAgICAgICAgeworICAgICAgICAgIEFycmF5T3V0cHV0U3RyZWFtIG91dHB1dChidWZmZXIsIGtCdWZmZXJTaXplLCBrQmxvY2tTaXplc1tpXSk7CisgICAgICAgICAgR3ppcE91dHB1dFN0cmVhbTo6T3B0aW9ucyBvcHRpb25zOworICAgICAgICAgIG9wdGlvbnMuZm9ybWF0ID0gR3ppcE91dHB1dFN0cmVhbTo6R1pJUDsKKyAgICAgICAgICBpZiAoZ3ppcF9idWZmZXJfc2l6ZSAhPSAtMSkgeworICAgICAgICAgICAgb3B0aW9ucy5idWZmZXJfc2l6ZSA9IGd6aXBfYnVmZmVyX3NpemU7CisgICAgICAgICAgfQorICAgICAgICAgIEd6aXBPdXRwdXRTdHJlYW0gZ3pvdXQoJm91dHB1dCwgb3B0aW9ucyk7CisgICAgICAgICAgV3JpdGVTdHVmZigmZ3pvdXQpOworICAgICAgICAgIGd6b3V0LkNsb3NlKCk7CisgICAgICAgICAgc2l6ZSA9IG91dHB1dC5CeXRlQ291bnQoKTsKKyAgICAgICAgfQorICAgICAgICB7CisgICAgICAgICAgQXJyYXlJbnB1dFN0cmVhbSBpbnB1dChidWZmZXIsIHNpemUsIGtCbG9ja1NpemVzW2pdKTsKKyAgICAgICAgICBHemlwSW5wdXRTdHJlYW0gZ3ppbigKKyAgICAgICAgICAgICAgJmlucHV0LCBHemlwSW5wdXRTdHJlYW06OkdaSVAsIGd6aXBfYnVmZmVyX3NpemUpOworICAgICAgICAgIFJlYWRTdHVmZigmZ3ppbik7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgIH0KKyAgZGVsZXRlIFtdIGJ1ZmZlcjsKK30KKworVEVTVF9GKElvVGVzdCwgR3ppcElvV2l0aEZsdXNoKSB7CisgIGNvbnN0IGludCBrQnVmZmVyU2l6ZSA9IDIqMTAyNDsKKyAgdWludDgqIGJ1ZmZlciA9IG5ldyB1aW50OFtrQnVmZmVyU2l6ZV07CisgIC8vIFdlIHN0YXJ0IHdpdGggaSA9IDQgYXMgd2Ugd2FudCBhIGJsb2NrIHNpemUgPiA2LiBXaXRoIGJsb2NrIHNpemUgPD0gNgorICAvLyBGbHVzaCgpIGZpbGxzIHVwIHRoZSBlbnRpcmUgMksgYnVmZmVyIHdpdGggZmx1c2ggbWFya2VycyBhbmQgdGhlIHRlc3QKKyAgLy8gZmFpbHMuIFNlZSBkb2N1bWVudGF0aW9uIGZvciBGbHVzaCgpIGZvciBtb3JlIGRldGFpbC4KKyAgZm9yIChpbnQgaSA9IDQ7IGkgPCBrQmxvY2tTaXplQ291bnQ7IGkrKykgeworICAgIGZvciAoaW50IGogPSAwOyBqIDwga0Jsb2NrU2l6ZUNvdW50OyBqKyspIHsKKyAgICAgIGZvciAoaW50IHogPSAwOyB6IDwga0Jsb2NrU2l6ZUNvdW50OyB6KyspIHsKKyAgICAgICAgaW50IGd6aXBfYnVmZmVyX3NpemUgPSBrQmxvY2tTaXplc1t6XTsKKyAgICAgICAgaW50IHNpemU7CisgICAgICAgIHsKKyAgICAgICAgICBBcnJheU91dHB1dFN0cmVhbSBvdXRwdXQoYnVmZmVyLCBrQnVmZmVyU2l6ZSwga0Jsb2NrU2l6ZXNbaV0pOworICAgICAgICAgIEd6aXBPdXRwdXRTdHJlYW06Ok9wdGlvbnMgb3B0aW9uczsKKyAgICAgICAgICBvcHRpb25zLmZvcm1hdCA9IEd6aXBPdXRwdXRTdHJlYW06OkdaSVA7CisgICAgICAgICAgaWYgKGd6aXBfYnVmZmVyX3NpemUgIT0gLTEpIHsKKyAgICAgICAgICAgIG9wdGlvbnMuYnVmZmVyX3NpemUgPSBnemlwX2J1ZmZlcl9zaXplOworICAgICAgICAgIH0KKyAgICAgICAgICBHemlwT3V0cHV0U3RyZWFtIGd6b3V0KCZvdXRwdXQsIG9wdGlvbnMpOworICAgICAgICAgIFdyaXRlU3R1ZmYoJmd6b3V0KTsKKyAgICAgICAgICBFWFBFQ1RfVFJVRShnem91dC5GbHVzaCgpKTsKKyAgICAgICAgICBnem91dC5DbG9zZSgpOworICAgICAgICAgIHNpemUgPSBvdXRwdXQuQnl0ZUNvdW50KCk7CisgICAgICAgIH0KKyAgICAgICAgeworICAgICAgICAgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQoYnVmZmVyLCBzaXplLCBrQmxvY2tTaXplc1tqXSk7CisgICAgICAgICAgR3ppcElucHV0U3RyZWFtIGd6aW4oCisgICAgICAgICAgICAgICZpbnB1dCwgR3ppcElucHV0U3RyZWFtOjpHWklQLCBnemlwX2J1ZmZlcl9zaXplKTsKKyAgICAgICAgICBSZWFkU3R1ZmYoJmd6aW4pOworICAgICAgICB9CisgICAgICB9CisgICAgfQorICB9CisgIGRlbGV0ZSBbXSBidWZmZXI7Cit9CisKK1RFU1RfRihJb1Rlc3QsIEd6aXBJb0NvbnRpZ3VvdXNGbHVzaGVzKSB7CisgIGNvbnN0IGludCBrQnVmZmVyU2l6ZSA9IDIqMTAyNDsKKyAgdWludDgqIGJ1ZmZlciA9IG5ldyB1aW50OFtrQnVmZmVyU2l6ZV07CisKKyAgaW50IGJsb2NrX3NpemUgPSBrQmxvY2tTaXplc1s0XTsKKyAgaW50IGd6aXBfYnVmZmVyX3NpemUgPSBibG9ja19zaXplOworICBpbnQgc2l6ZTsKKworICBBcnJheU91dHB1dFN0cmVhbSBvdXRwdXQoYnVmZmVyLCBrQnVmZmVyU2l6ZSwgYmxvY2tfc2l6ZSk7CisgIEd6aXBPdXRwdXRTdHJlYW06Ok9wdGlvbnMgb3B0aW9uczsKKyAgb3B0aW9ucy5mb3JtYXQgPSBHemlwT3V0cHV0U3RyZWFtOjpHWklQOworICBpZiAoZ3ppcF9idWZmZXJfc2l6ZSAhPSAtMSkgeworICAgIG9wdGlvbnMuYnVmZmVyX3NpemUgPSBnemlwX2J1ZmZlcl9zaXplOworICB9CisgIEd6aXBPdXRwdXRTdHJlYW0gZ3pvdXQoJm91dHB1dCwgb3B0aW9ucyk7CisgIFdyaXRlU3R1ZmYoJmd6b3V0KTsKKyAgRVhQRUNUX1RSVUUoZ3pvdXQuRmx1c2goKSk7CisgIEVYUEVDVF9UUlVFKGd6b3V0LkZsdXNoKCkpOworICBnem91dC5DbG9zZSgpOworICBzaXplID0gb3V0cHV0LkJ5dGVDb3VudCgpOworCisgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQoYnVmZmVyLCBzaXplLCBibG9ja19zaXplKTsKKyAgR3ppcElucHV0U3RyZWFtIGd6aW4oCisgICAgICAmaW5wdXQsIEd6aXBJbnB1dFN0cmVhbTo6R1pJUCwgZ3ppcF9idWZmZXJfc2l6ZSk7CisgIFJlYWRTdHVmZigmZ3ppbik7CisKKyAgZGVsZXRlIFtdIGJ1ZmZlcjsKK30KKworVEVTVF9GKElvVGVzdCwgR3ppcElvUmVhZEFmdGVyRmx1c2gpIHsKKyAgY29uc3QgaW50IGtCdWZmZXJTaXplID0gMioxMDI0OworICB1aW50OCogYnVmZmVyID0gbmV3IHVpbnQ4W2tCdWZmZXJTaXplXTsKKworICBpbnQgYmxvY2tfc2l6ZSA9IGtCbG9ja1NpemVzWzRdOworICBpbnQgZ3ppcF9idWZmZXJfc2l6ZSA9IGJsb2NrX3NpemU7CisgIGludCBzaXplOworICBBcnJheU91dHB1dFN0cmVhbSBvdXRwdXQoYnVmZmVyLCBrQnVmZmVyU2l6ZSwgYmxvY2tfc2l6ZSk7CisgIEd6aXBPdXRwdXRTdHJlYW06Ok9wdGlvbnMgb3B0aW9uczsKKyAgb3B0aW9ucy5mb3JtYXQgPSBHemlwT3V0cHV0U3RyZWFtOjpHWklQOworICBpZiAoZ3ppcF9idWZmZXJfc2l6ZSAhPSAtMSkgeworICAgIG9wdGlvbnMuYnVmZmVyX3NpemUgPSBnemlwX2J1ZmZlcl9zaXplOworICB9CisKKyAgR3ppcE91dHB1dFN0cmVhbSBnem91dCgmb3V0cHV0LCBvcHRpb25zKTsKKyAgV3JpdGVTdHVmZigmZ3pvdXQpOworICBFWFBFQ1RfVFJVRShnem91dC5GbHVzaCgpKTsKKyAgc2l6ZSA9IG91dHB1dC5CeXRlQ291bnQoKTsKKworICBBcnJheUlucHV0U3RyZWFtIGlucHV0KGJ1ZmZlciwgc2l6ZSwgYmxvY2tfc2l6ZSk7CisgIEd6aXBJbnB1dFN0cmVhbSBnemluKAorICAgICAgJmlucHV0LCBHemlwSW5wdXRTdHJlYW06OkdaSVAsIGd6aXBfYnVmZmVyX3NpemUpOworICBSZWFkU3R1ZmYoJmd6aW4pOworCisgIGd6b3V0LkNsb3NlKCk7CisKKyAgZGVsZXRlIFtdIGJ1ZmZlcjsKK30KKworVEVTVF9GKElvVGVzdCwgWmxpYklvKSB7CisgIGNvbnN0IGludCBrQnVmZmVyU2l6ZSA9IDIqMTAyNDsKKyAgdWludDgqIGJ1ZmZlciA9IG5ldyB1aW50OFtrQnVmZmVyU2l6ZV07CisgIGZvciAoaW50IGkgPSAwOyBpIDwga0Jsb2NrU2l6ZUNvdW50OyBpKyspIHsKKyAgICBmb3IgKGludCBqID0gMDsgaiA8IGtCbG9ja1NpemVDb3VudDsgaisrKSB7CisgICAgICBmb3IgKGludCB6ID0gMDsgeiA8IGtCbG9ja1NpemVDb3VudDsgeisrKSB7CisgICAgICAgIGludCBnemlwX2J1ZmZlcl9zaXplID0ga0Jsb2NrU2l6ZXNbel07CisgICAgICAgIGludCBzaXplOworICAgICAgICB7CisgICAgICAgICAgQXJyYXlPdXRwdXRTdHJlYW0gb3V0cHV0KGJ1ZmZlciwga0J1ZmZlclNpemUsIGtCbG9ja1NpemVzW2ldKTsKKyAgICAgICAgICBHemlwT3V0cHV0U3RyZWFtOjpPcHRpb25zIG9wdGlvbnM7CisgICAgICAgICAgb3B0aW9ucy5mb3JtYXQgPSBHemlwT3V0cHV0U3RyZWFtOjpaTElCOworICAgICAgICAgIGlmIChnemlwX2J1ZmZlcl9zaXplICE9IC0xKSB7CisgICAgICAgICAgICBvcHRpb25zLmJ1ZmZlcl9zaXplID0gZ3ppcF9idWZmZXJfc2l6ZTsKKyAgICAgICAgICB9CisgICAgICAgICAgR3ppcE91dHB1dFN0cmVhbSBnem91dCgmb3V0cHV0LCBvcHRpb25zKTsKKyAgICAgICAgICBXcml0ZVN0dWZmKCZnem91dCk7CisgICAgICAgICAgZ3pvdXQuQ2xvc2UoKTsKKyAgICAgICAgICBzaXplID0gb3V0cHV0LkJ5dGVDb3VudCgpOworICAgICAgICB9CisgICAgICAgIHsKKyAgICAgICAgICBBcnJheUlucHV0U3RyZWFtIGlucHV0KGJ1ZmZlciwgc2l6ZSwga0Jsb2NrU2l6ZXNbal0pOworICAgICAgICAgIEd6aXBJbnB1dFN0cmVhbSBnemluKAorICAgICAgICAgICAgICAmaW5wdXQsIEd6aXBJbnB1dFN0cmVhbTo6WkxJQiwgZ3ppcF9idWZmZXJfc2l6ZSk7CisgICAgICAgICAgUmVhZFN0dWZmKCZnemluKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgfQorICBkZWxldGUgW10gYnVmZmVyOworfQorCitURVNUX0YoSW9UZXN0LCBabGliSW9JbnB1dEF1dG9kZXRlY3QpIHsKKyAgY29uc3QgaW50IGtCdWZmZXJTaXplID0gMioxMDI0OworICB1aW50OCogYnVmZmVyID0gbmV3IHVpbnQ4W2tCdWZmZXJTaXplXTsKKyAgaW50IHNpemU7CisgIHsKKyAgICBBcnJheU91dHB1dFN0cmVhbSBvdXRwdXQoYnVmZmVyLCBrQnVmZmVyU2l6ZSk7CisgICAgR3ppcE91dHB1dFN0cmVhbTo6T3B0aW9ucyBvcHRpb25zOworICAgIG9wdGlvbnMuZm9ybWF0ID0gR3ppcE91dHB1dFN0cmVhbTo6WkxJQjsKKyAgICBHemlwT3V0cHV0U3RyZWFtIGd6b3V0KCZvdXRwdXQsIG9wdGlvbnMpOworICAgIFdyaXRlU3R1ZmYoJmd6b3V0KTsKKyAgICBnem91dC5DbG9zZSgpOworICAgIHNpemUgPSBvdXRwdXQuQnl0ZUNvdW50KCk7CisgIH0KKyAgeworICAgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQoYnVmZmVyLCBzaXplKTsKKyAgICBHemlwSW5wdXRTdHJlYW0gZ3ppbigmaW5wdXQsIEd6aXBJbnB1dFN0cmVhbTo6QVVUTyk7CisgICAgUmVhZFN0dWZmKCZnemluKTsKKyAgfQorICB7CisgICAgQXJyYXlPdXRwdXRTdHJlYW0gb3V0cHV0KGJ1ZmZlciwga0J1ZmZlclNpemUpOworICAgIEd6aXBPdXRwdXRTdHJlYW06Ok9wdGlvbnMgb3B0aW9uczsKKyAgICBvcHRpb25zLmZvcm1hdCA9IEd6aXBPdXRwdXRTdHJlYW06OkdaSVA7CisgICAgR3ppcE91dHB1dFN0cmVhbSBnem91dCgmb3V0cHV0LCBvcHRpb25zKTsKKyAgICBXcml0ZVN0dWZmKCZnem91dCk7CisgICAgZ3pvdXQuQ2xvc2UoKTsKKyAgICBzaXplID0gb3V0cHV0LkJ5dGVDb3VudCgpOworICB9CisgIHsKKyAgICBBcnJheUlucHV0U3RyZWFtIGlucHV0KGJ1ZmZlciwgc2l6ZSk7CisgICAgR3ppcElucHV0U3RyZWFtIGd6aW4oJmlucHV0LCBHemlwSW5wdXRTdHJlYW06OkFVVE8pOworICAgIFJlYWRTdHVmZigmZ3ppbik7CisgIH0KKyAgZGVsZXRlIFtdIGJ1ZmZlcjsKK30KKworc3RyaW5nIElvVGVzdDo6Q29tcHJlc3MoY29uc3Qgc3RyaW5nJiBkYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgR3ppcE91dHB1dFN0cmVhbTo6T3B0aW9ucyYgb3B0aW9ucykgeworICBzdHJpbmcgcmVzdWx0OworICB7CisgICAgU3RyaW5nT3V0cHV0U3RyZWFtIG91dHB1dCgmcmVzdWx0KTsKKyAgICBHemlwT3V0cHV0U3RyZWFtIGd6b3V0KCZvdXRwdXQsIG9wdGlvbnMpOworICAgIFdyaXRlVG9PdXRwdXQoJmd6b3V0LCBkYXRhLmRhdGEoKSwgZGF0YS5zaXplKCkpOworICB9CisgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0cmluZyBJb1Rlc3Q6OlVuY29tcHJlc3MoY29uc3Qgc3RyaW5nJiBkYXRhKSB7CisgIHN0cmluZyByZXN1bHQ7CisgIHsKKyAgICBBcnJheUlucHV0U3RyZWFtIGlucHV0KGRhdGEuZGF0YSgpLCBkYXRhLnNpemUoKSk7CisgICAgR3ppcElucHV0U3RyZWFtIGd6aW4oJmlucHV0KTsKKyAgICBjb25zdCB2b2lkKiBidWZmZXI7CisgICAgaW50IHNpemU7CisgICAgd2hpbGUgKGd6aW4uTmV4dCgmYnVmZmVyLCAmc2l6ZSkpIHsKKyAgICAgIHJlc3VsdC5hcHBlbmQocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4oYnVmZmVyKSwgc2l6ZSk7CisgICAgfQorICB9CisgIHJldHVybiByZXN1bHQ7Cit9CisKK1RFU1RfRihJb1Rlc3QsIENvbXByZXNzaW9uT3B0aW9ucykgeworICAvLyBTb21lIGFkLWhvYyB0ZXN0aW5nIG9mIGNvbXByZXNzaW9uIG9wdGlvbnMuCisKKyAgc3RyaW5nIGdvbGRlbjsKKyAgR09PR0xFX0NIRUNLX09LKEZpbGU6OkdldENvbnRlbnRzKAorICAgICAgVGVzdFNvdXJjZURpcigpICsKKyAgICAgICAgICAiL2dvb2dsZS9wcm90b2J1Zi90ZXN0ZGF0YS9nb2xkZW5fbWVzc2FnZSIsCisgICAgICAmZ29sZGVuLCB0cnVlKSk7CisKKyAgR3ppcE91dHB1dFN0cmVhbTo6T3B0aW9ucyBvcHRpb25zOworICBzdHJpbmcgZ3ppcF9jb21wcmVzc2VkID0gQ29tcHJlc3MoZ29sZGVuLCBvcHRpb25zKTsKKworICBvcHRpb25zLmNvbXByZXNzaW9uX2xldmVsID0gMDsKKyAgc3RyaW5nIG5vdF9jb21wcmVzc2VkID0gQ29tcHJlc3MoZ29sZGVuLCBvcHRpb25zKTsKKworICAvLyBUcnkgemxpYiBjb21wcmVzc2lvbiBmb3IgZnVuLgorICBvcHRpb25zID0gR3ppcE91dHB1dFN0cmVhbTo6T3B0aW9ucygpOworICBvcHRpb25zLmZvcm1hdCA9IEd6aXBPdXRwdXRTdHJlYW06OlpMSUI7CisgIHN0cmluZyB6bGliX2NvbXByZXNzZWQgPSBDb21wcmVzcyhnb2xkZW4sIG9wdGlvbnMpOworCisgIC8vIFVuY29tcHJlc3NlZCBzaG91bGQgYmUgYmlnZ2VyIHRoYW4gdGhlIG9yaWdpbmFsIHNpbmNlIGl0IHNob3VsZCBoYXZlIHNvbWUKKyAgLy8gc29ydCBvZiBoZWFkZXIuCisgIEVYUEVDVF9HVChub3RfY29tcHJlc3NlZC5zaXplKCksIGdvbGRlbi5zaXplKCkpOworCisgIC8vIEhpZ2hlciBjb21wcmVzc2lvbiBsZXZlbHMgc2hvdWxkIHJlc3VsdCBpbiBzbWFsbGVyIHNpemVzLgorICBFWFBFQ1RfTFQoemxpYl9jb21wcmVzc2VkLnNpemUoKSwgbm90X2NvbXByZXNzZWQuc2l6ZSgpKTsKKworICAvLyBaTElCIGZvcm1hdCBzaG91bGQgZGlmZmVyIGZyb20gR1pJUCBmb3JtYXQuCisgIEVYUEVDVF9UUlVFKHpsaWJfY29tcHJlc3NlZCAhPSBnemlwX2NvbXByZXNzZWQpOworCisgIC8vIEV2ZXJ5dGhpbmcgc2hvdWxkIGRlY29tcHJlc3MgY29ycmVjdGx5LgorICBFWFBFQ1RfVFJVRShVbmNvbXByZXNzKG5vdF9jb21wcmVzc2VkKSA9PSBnb2xkZW4pOworICBFWFBFQ1RfVFJVRShVbmNvbXByZXNzKGd6aXBfY29tcHJlc3NlZCkgPT0gZ29sZGVuKTsKKyAgRVhQRUNUX1RSVUUoVW5jb21wcmVzcyh6bGliX2NvbXByZXNzZWQpID09IGdvbGRlbik7Cit9CisKK1RFU1RfRihJb1Rlc3QsIFR3b1Nlc3Npb25Xcml0ZUd6aXApIHsKKyAgLy8gVGVzdCB0aGF0IHR3byBjb25jYXRlbmF0ZWQgZ3ppcCBzdHJlYW1zIGNhbiBiZSByZWFkIGNvcnJlY3RseQorCisgIHN0YXRpYyBjb25zdCBjaGFyKiBzdHJBID0gIjAxMjM0NTY3ODkiOworICBzdGF0aWMgY29uc3QgY2hhciogc3RyQiA9ICJRdWlja0Jyb3duRm94IjsKKyAgY29uc3QgaW50IGtCdWZmZXJTaXplID0gMioxMDI0OworICB1aW50OCogYnVmZmVyID0gbmV3IHVpbnQ4W2tCdWZmZXJTaXplXTsKKyAgY2hhciogdGVtcF9idWZmZXIgPSBuZXcgY2hhcls0MF07CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBrQmxvY2tTaXplQ291bnQ7IGkrKykgeworICAgIGZvciAoaW50IGogPSAwOyBqIDwga0Jsb2NrU2l6ZUNvdW50OyBqKyspIHsKKyAgICAgIEFycmF5T3V0cHV0U3RyZWFtKiBvdXRwdXQgPQorICAgICAgICAgIG5ldyBBcnJheU91dHB1dFN0cmVhbShidWZmZXIsIGtCdWZmZXJTaXplLCBrQmxvY2tTaXplc1tpXSk7CisgICAgICBHemlwT3V0cHV0U3RyZWFtKiBnem91dCA9IG5ldyBHemlwT3V0cHV0U3RyZWFtKG91dHB1dCk7CisgICAgICBDb2RlZE91dHB1dFN0cmVhbSogY29kZWRfb3V0cHV0ID0gbmV3IENvZGVkT3V0cHV0U3RyZWFtKGd6b3V0KTsKKyAgICAgIGludDMyIG91dGxlbiA9IHN0cmxlbihzdHJBKSArIDE7CisgICAgICBjb2RlZF9vdXRwdXQtPldyaXRlVmFyaW50MzIob3V0bGVuKTsKKyAgICAgIGNvZGVkX291dHB1dC0+V3JpdGVSYXcoc3RyQSwgb3V0bGVuKTsKKyAgICAgIGRlbGV0ZSBjb2RlZF9vdXRwdXQ7ICAvLyBmbHVzaAorICAgICAgZGVsZXRlIGd6b3V0OyAgLy8gZmx1c2gKKyAgICAgIGludDY0IHBvcyA9IG91dHB1dC0+Qnl0ZUNvdW50KCk7CisgICAgICBkZWxldGUgb3V0cHV0OworICAgICAgb3V0cHV0ID0gbmV3IEFycmF5T3V0cHV0U3RyZWFtKAorICAgICAgICAgIGJ1ZmZlciArIHBvcywga0J1ZmZlclNpemUgLSBwb3MsIGtCbG9ja1NpemVzW2ldKTsKKyAgICAgIGd6b3V0ID0gbmV3IEd6aXBPdXRwdXRTdHJlYW0ob3V0cHV0KTsKKyAgICAgIGNvZGVkX291dHB1dCA9IG5ldyBDb2RlZE91dHB1dFN0cmVhbShnem91dCk7CisgICAgICBvdXRsZW4gPSBzdHJsZW4oc3RyQikgKyAxOworICAgICAgY29kZWRfb3V0cHV0LT5Xcml0ZVZhcmludDMyKG91dGxlbik7CisgICAgICBjb2RlZF9vdXRwdXQtPldyaXRlUmF3KHN0ckIsIG91dGxlbik7CisgICAgICBkZWxldGUgY29kZWRfb3V0cHV0OyAgLy8gZmx1c2gKKyAgICAgIGRlbGV0ZSBnem91dDsgIC8vIGZsdXNoCisgICAgICBpbnQ2NCBzaXplID0gcG9zICsgb3V0cHV0LT5CeXRlQ291bnQoKTsKKyAgICAgIGRlbGV0ZSBvdXRwdXQ7CisKKyAgICAgIEFycmF5SW5wdXRTdHJlYW0qIGlucHV0ID0KKyAgICAgICAgICBuZXcgQXJyYXlJbnB1dFN0cmVhbShidWZmZXIsIHNpemUsIGtCbG9ja1NpemVzW2pdKTsKKyAgICAgIEd6aXBJbnB1dFN0cmVhbSogZ3ppbiA9IG5ldyBHemlwSW5wdXRTdHJlYW0oaW5wdXQpOworICAgICAgQ29kZWRJbnB1dFN0cmVhbSogY29kZWRfaW5wdXQgPSBuZXcgQ29kZWRJbnB1dFN0cmVhbShnemluKTsKKyAgICAgIHVpbnQzMiBpbnNpemU7CisgICAgICBFWFBFQ1RfVFJVRShjb2RlZF9pbnB1dC0+UmVhZFZhcmludDMyKCZpbnNpemUpKTsKKyAgICAgIEVYUEVDVF9FUShzdHJsZW4oc3RyQSkgKyAxLCBpbnNpemUpOworICAgICAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQtPlJlYWRSYXcodGVtcF9idWZmZXIsIGluc2l6ZSkpOworICAgICAgRVhQRUNUX0VRKDAsIG1lbWNtcCh0ZW1wX2J1ZmZlciwgc3RyQSwgaW5zaXplKSkKKyAgICAgICAgICA8PCAic3RyQT0iIDw8IHN0ckEgPDwgIiBpbj0iIDw8IHRlbXBfYnVmZmVyOworCisgICAgICBFWFBFQ1RfVFJVRShjb2RlZF9pbnB1dC0+UmVhZFZhcmludDMyKCZpbnNpemUpKTsKKyAgICAgIEVYUEVDVF9FUShzdHJsZW4oc3RyQikgKyAxLCBpbnNpemUpOworICAgICAgRVhQRUNUX1RSVUUoY29kZWRfaW5wdXQtPlJlYWRSYXcodGVtcF9idWZmZXIsIGluc2l6ZSkpOworICAgICAgRVhQRUNUX0VRKDAsIG1lbWNtcCh0ZW1wX2J1ZmZlciwgc3RyQiwgaW5zaXplKSkKKyAgICAgICAgICA8PCAiIG91dF9ibG9ja19zaXplPSIgPDwga0Jsb2NrU2l6ZXNbaV0KKyAgICAgICAgICA8PCAiIGluX2Jsb2NrX3NpemU9IiA8PCBrQmxvY2tTaXplc1tqXQorICAgICAgICAgIDw8ICIgcG9zPSIgPDwgcG9zCisgICAgICAgICAgPDwgIiBzaXplPSIgPDwgc2l6ZQorICAgICAgICAgIDw8ICIgc3RyQj0iIDw8IHN0ckIgPDwgIiBpbj0iIDw8IHRlbXBfYnVmZmVyOworCisgICAgICBkZWxldGUgY29kZWRfaW5wdXQ7CisgICAgICBkZWxldGUgZ3ppbjsKKyAgICAgIGRlbGV0ZSBpbnB1dDsKKyAgICB9CisgIH0KKworICBkZWxldGUgW10gdGVtcF9idWZmZXI7CisgIGRlbGV0ZSBbXSBidWZmZXI7Cit9CisKK1RFU1RfRihJb1Rlc3QsIEd6aXBJbnB1dEJ5dGVDb3VudEFmdGVyQ2xvc2VkKSB7CisgIHN0cmluZyBnb2xkZW4gPSAiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoiOworICBzdHJpbmcgY29tcHJlc3NlZCA9IENvbXByZXNzKGdvbGRlbiwgR3ppcE91dHB1dFN0cmVhbTo6T3B0aW9ucygpKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGtCbG9ja1NpemVDb3VudDsgaSsrKSB7CisgICAgQXJyYXlJbnB1dFN0cmVhbSBhcnJfaW5wdXQoY29tcHJlc3NlZC5kYXRhKCksIGNvbXByZXNzZWQuc2l6ZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtCbG9ja1NpemVzW2ldKTsKKyAgICBHemlwSW5wdXRTdHJlYW0gZ3pfaW5wdXQoJmFycl9pbnB1dCk7CisgICAgY29uc3Qgdm9pZCogYnVmZmVyOworICAgIGludCBzaXplOworICAgIHdoaWxlIChnel9pbnB1dC5OZXh0KCZidWZmZXIsICZzaXplKSkgeworICAgICAgRVhQRUNUX0xFKGd6X2lucHV0LkJ5dGVDb3VudCgpLCBnb2xkZW4uc2l6ZSgpKTsKKyAgICB9CisgICAgRVhQRUNUX0VRKGdvbGRlbi5zaXplKCksIGd6X2lucHV0LkJ5dGVDb3VudCgpKTsKKyAgfQorfQorCitURVNUX0YoSW9UZXN0LCBHemlwSW5wdXRCeXRlQ291bnRBZnRlckNsb3NlZENvbmNhdGVuYXRlZFN0cmVhbXMpIHsKKyAgc3RyaW5nIGdvbGRlbjEgPSAiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoiOworICBzdHJpbmcgZ29sZGVuMiA9ICJ0aGUgcXVpY2sgYnJvd24gZm94IGp1bXBzIG92ZXIgdGhlIGxhenkgZG9nIjsKKyAgY29uc3Qgc2l6ZV90IHRvdGFsX3NpemUgPSBnb2xkZW4xLnNpemUoKSArIGdvbGRlbjIuc2l6ZSgpOworICBzdHJpbmcgY29tcHJlc3NlZCA9IENvbXByZXNzKGdvbGRlbjEsIEd6aXBPdXRwdXRTdHJlYW06Ok9wdGlvbnMoKSkgKworICAgICAgICAgICAgICAgICAgICAgIENvbXByZXNzKGdvbGRlbjIsIEd6aXBPdXRwdXRTdHJlYW06Ok9wdGlvbnMoKSk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBrQmxvY2tTaXplQ291bnQ7IGkrKykgeworICAgIEFycmF5SW5wdXRTdHJlYW0gYXJyX2lucHV0KGNvbXByZXNzZWQuZGF0YSgpLCBjb21wcmVzc2VkLnNpemUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrQmxvY2tTaXplc1tpXSk7CisgICAgR3ppcElucHV0U3RyZWFtIGd6X2lucHV0KCZhcnJfaW5wdXQpOworICAgIGNvbnN0IHZvaWQqIGJ1ZmZlcjsKKyAgICBpbnQgc2l6ZTsKKyAgICB3aGlsZSAoZ3pfaW5wdXQuTmV4dCgmYnVmZmVyLCAmc2l6ZSkpIHsKKyAgICAgIEVYUEVDVF9MRShnel9pbnB1dC5CeXRlQ291bnQoKSwgdG90YWxfc2l6ZSk7CisgICAgfQorICAgIEVYUEVDVF9FUSh0b3RhbF9zaXplLCBnel9pbnB1dC5CeXRlQ291bnQoKSk7CisgIH0KK30KKyNlbmRpZgorCisvLyBUaGVyZSBpcyBubyBzdHJpbmcgaW5wdXQsIG9ubHkgc3RyaW5nIG91dHB1dC4gIEFsc28sIGl0IGRvZXNuJ3Qgc3VwcG9ydAorLy8gZXhwbGljaXQgYmxvY2sgc2l6ZXMuICBTbywgd2UnbGwgb25seSBydW4gb25lIHRlc3QgYW5kIHdlJ2xsIHVzZQorLy8gQXJyYXlJbnB1dCB0byByZWFkIGJhY2sgdGhlIHJlc3VsdHMuCitURVNUX0YoSW9UZXN0LCBTdHJpbmdJbykgeworICBzdHJpbmcgc3RyOworICB7CisgICAgU3RyaW5nT3V0cHV0U3RyZWFtIG91dHB1dCgmc3RyKTsKKyAgICBXcml0ZVN0dWZmKCZvdXRwdXQpOworICB9CisgIHsKKyAgICBBcnJheUlucHV0U3RyZWFtIGlucHV0KHN0ci5kYXRhKCksIHN0ci5zaXplKCkpOworICAgIFJlYWRTdHVmZigmaW5wdXQpOworICB9Cit9CisKKworLy8gVG8gdGVzdCBmaWxlcywgd2UgY3JlYXRlIGEgdGVtcG9yYXJ5IGZpbGUsIHdyaXRlLCByZWFkLCB0cnVuY2F0ZSwgcmVwZWF0LgorVEVTVF9GKElvVGVzdCwgRmlsZUlvKSB7CisgIHN0cmluZyBmaWxlbmFtZSA9IFRlc3RUZW1wRGlyKCkgKyAiL3plcm9fY29weV9zdHJlYW1fdGVzdF9maWxlIjsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGtCbG9ja1NpemVDb3VudDsgaSsrKSB7CisgICAgZm9yIChpbnQgaiA9IDA7IGogPCBrQmxvY2tTaXplQ291bnQ7IGorKykgeworICAgICAgLy8gTWFrZSBhIHRlbXBvcmFyeSBmaWxlLgorICAgICAgaW50IGZpbGUgPQorICAgICAgICBvcGVuKGZpbGVuYW1lLmNfc3RyKCksIE9fUkRXUiB8IE9fQ1JFQVQgfCBPX1RSVU5DIHwgT19CSU5BUlksIDA3NzcpOworICAgICAgQVNTRVJUX0dFKGZpbGUsIDApOworCisgICAgICB7CisgICAgICAgIEZpbGVPdXRwdXRTdHJlYW0gb3V0cHV0KGZpbGUsIGtCbG9ja1NpemVzW2ldKTsKKyAgICAgICAgV3JpdGVTdHVmZigmb3V0cHV0KTsKKyAgICAgICAgRVhQRUNUX0VRKDAsIG91dHB1dC5HZXRFcnJubygpKTsKKyAgICAgIH0KKworICAgICAgLy8gUmV3aW5kLgorICAgICAgQVNTRVJUX05FKGxzZWVrKGZpbGUsIDAsIFNFRUtfU0VUKSwgKG9mZl90KS0xKTsKKworICAgICAgeworICAgICAgICBGaWxlSW5wdXRTdHJlYW0gaW5wdXQoZmlsZSwga0Jsb2NrU2l6ZXNbal0pOworICAgICAgICBSZWFkU3R1ZmYoJmlucHV0KTsKKyAgICAgICAgRVhQRUNUX0VRKDAsIGlucHV0LkdldEVycm5vKCkpOworICAgICAgfQorCisgICAgICBjbG9zZShmaWxlKTsKKyAgICB9CisgIH0KK30KKworI2lmIEhBVkVfWkxJQgorVEVTVF9GKElvVGVzdCwgR3ppcEZpbGVJbykgeworICBzdHJpbmcgZmlsZW5hbWUgPSBUZXN0VGVtcERpcigpICsgIi96ZXJvX2NvcHlfc3RyZWFtX3Rlc3RfZmlsZSI7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBrQmxvY2tTaXplQ291bnQ7IGkrKykgeworICAgIGZvciAoaW50IGogPSAwOyBqIDwga0Jsb2NrU2l6ZUNvdW50OyBqKyspIHsKKyAgICAgIC8vIE1ha2UgYSB0ZW1wb3JhcnkgZmlsZS4KKyAgICAgIGludCBmaWxlID0KKyAgICAgICAgb3BlbihmaWxlbmFtZS5jX3N0cigpLCBPX1JEV1IgfCBPX0NSRUFUIHwgT19UUlVOQyB8IE9fQklOQVJZLCAwNzc3KTsKKyAgICAgIEFTU0VSVF9HRShmaWxlLCAwKTsKKyAgICAgIHsKKyAgICAgICAgRmlsZU91dHB1dFN0cmVhbSBvdXRwdXQoZmlsZSwga0Jsb2NrU2l6ZXNbaV0pOworICAgICAgICBHemlwT3V0cHV0U3RyZWFtIGd6b3V0KCZvdXRwdXQpOworICAgICAgICBXcml0ZVN0dWZmTGFyZ2UoJmd6b3V0KTsKKyAgICAgICAgZ3pvdXQuQ2xvc2UoKTsKKyAgICAgICAgb3V0cHV0LkZsdXNoKCk7CisgICAgICAgIEVYUEVDVF9FUSgwLCBvdXRwdXQuR2V0RXJybm8oKSk7CisgICAgICB9CisKKyAgICAgIC8vIFJld2luZC4KKyAgICAgIEFTU0VSVF9ORShsc2VlayhmaWxlLCAwLCBTRUVLX1NFVCksIChvZmZfdCktMSk7CisKKyAgICAgIHsKKyAgICAgICAgRmlsZUlucHV0U3RyZWFtIGlucHV0KGZpbGUsIGtCbG9ja1NpemVzW2pdKTsKKyAgICAgICAgR3ppcElucHV0U3RyZWFtIGd6aW4oJmlucHV0KTsKKyAgICAgICAgUmVhZFN0dWZmTGFyZ2UoJmd6aW4pOworICAgICAgICBFWFBFQ1RfRVEoMCwgaW5wdXQuR2V0RXJybm8oKSk7CisgICAgICB9CisKKyAgICAgIGNsb3NlKGZpbGUpOworICAgIH0KKyAgfQorfQorI2VuZGlmCisKKy8vIE1TVkMgcmFpc2VzIHZhcmlvdXMgZGVidWdnaW5nIGV4Y2VwdGlvbnMgaWYgd2UgdHJ5IHRvIHVzZSBhIGZpbGUKKy8vIGRlc2NyaXB0b3Igb2YgLTEsIGRlZmVhdGluZyBvdXIgdGVzdHMgYmVsb3cuICBUaGlzIGNsYXNzIHdpbGwgZGlzYWJsZQorLy8gdGhlc2UgZGVidWcgYXNzZXJ0aW9ucyB3aGlsZSBpbiBzY29wZS4KK2NsYXNzIE1zdmNEZWJ1Z0Rpc2FibGVyIHsKKyBwdWJsaWM6CisjaWYgZGVmaW5lZChfTVNDX1ZFUikgJiYgX01TQ19WRVIgPj0gMTQwMAorICBNc3ZjRGVidWdEaXNhYmxlcigpIHsKKyAgICBvbGRfaGFuZGxlcl8gPSBfc2V0X2ludmFsaWRfcGFyYW1ldGVyX2hhbmRsZXIoTXlIYW5kbGVyKTsKKyAgICBvbGRfbW9kZV8gPSBfQ3J0U2V0UmVwb3J0TW9kZShfQ1JUX0FTU0VSVCwgMCk7CisgIH0KKyAgfk1zdmNEZWJ1Z0Rpc2FibGVyKCkgeworICAgIG9sZF9oYW5kbGVyXyA9IF9zZXRfaW52YWxpZF9wYXJhbWV0ZXJfaGFuZGxlcihvbGRfaGFuZGxlcl8pOworICAgIG9sZF9tb2RlXyA9IF9DcnRTZXRSZXBvcnRNb2RlKF9DUlRfQVNTRVJULCBvbGRfbW9kZV8pOworICB9CisKKyAgc3RhdGljIHZvaWQgTXlIYW5kbGVyKGNvbnN0IHdjaGFyX3QgKmV4cHIsCisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB3Y2hhcl90ICpmdW5jLAorICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgd2NoYXJfdCAqZmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGludCBsaW5lLAorICAgICAgICAgICAgICAgICAgICAgICAgdWludHB0cl90IHBSZXNlcnZlZCkgeworICAgIC8vIGRvIG5vdGhpbmcKKyAgfQorCisgIF9pbnZhbGlkX3BhcmFtZXRlcl9oYW5kbGVyIG9sZF9oYW5kbGVyXzsKKyAgaW50IG9sZF9tb2RlXzsKKyNlbHNlCisgIC8vIER1bW15IGNvbnN0cnVjdG9yIGFuZCBkZXN0cnVjdG9yIHRvIGVuc3VyZSB0aGF0IEdDQyBkb2Vzbid0IGNvbXBsYWluCisgIC8vIHRoYXQgZGVidWdfZGlzYWJsZXIgaXMgYW4gdW51c2VkIHZhcmlhYmxlLgorICBNc3ZjRGVidWdEaXNhYmxlcigpIHt9CisgIH5Nc3ZjRGVidWdEaXNhYmxlcigpIHt9CisjZW5kaWYKK307CisKKy8vIFRlc3QgdGhhdCBGaWxlSW5wdXRTdHJlYW1zIHJlcG9ydCBlcnJvcnMgY29ycmVjdGx5LgorVEVTVF9GKElvVGVzdCwgRmlsZVJlYWRFcnJvcikgeworICBNc3ZjRGVidWdEaXNhYmxlciBkZWJ1Z19kaXNhYmxlcjsKKworICAvLyAtMSA9IGludmFsaWQgZmlsZSBkZXNjcmlwdG9yLgorICBGaWxlSW5wdXRTdHJlYW0gaW5wdXQoLTEpOworCisgIGNvbnN0IHZvaWQqIGJ1ZmZlcjsKKyAgaW50IHNpemU7CisgIEVYUEVDVF9GQUxTRShpbnB1dC5OZXh0KCZidWZmZXIsICZzaXplKSk7CisgIEVYUEVDVF9FUShFQkFERiwgaW5wdXQuR2V0RXJybm8oKSk7Cit9CisKKy8vIFRlc3QgdGhhdCBGaWxlT3V0cHV0U3RyZWFtcyByZXBvcnQgZXJyb3JzIGNvcnJlY3RseS4KK1RFU1RfRihJb1Rlc3QsIEZpbGVXcml0ZUVycm9yKSB7CisgIE1zdmNEZWJ1Z0Rpc2FibGVyIGRlYnVnX2Rpc2FibGVyOworCisgIC8vIC0xID0gaW52YWxpZCBmaWxlIGRlc2NyaXB0b3IuCisgIEZpbGVPdXRwdXRTdHJlYW0gaW5wdXQoLTEpOworCisgIHZvaWQqIGJ1ZmZlcjsKKyAgaW50IHNpemU7CisKKyAgLy8gVGhlIGZpcnN0IGNhbGwgdG8gTmV4dCgpIHN1Y2NlZWRzIGJlY2F1c2UgaXQgZG9lc24ndCBoYXZlIGFueXRoaW5nIHRvCisgIC8vIHdyaXRlIHlldC4KKyAgRVhQRUNUX1RSVUUoaW5wdXQuTmV4dCgmYnVmZmVyLCAmc2l6ZSkpOworCisgIC8vIFNlY29uZCBjYWxsIGZhaWxzLgorICBFWFBFQ1RfRkFMU0UoaW5wdXQuTmV4dCgmYnVmZmVyLCAmc2l6ZSkpOworCisgIEVYUEVDVF9FUShFQkFERiwgaW5wdXQuR2V0RXJybm8oKSk7Cit9CisKKy8vIFBpcGVzIGFyZSBub3Qgc2Vla2FibGUsIHNvIEZpbGV7SW5wdXQsT3V0cHV0fVN0cmVhbSBlbmRzIHVwIGRvaW5nIHNvbWUKKy8vIGRpZmZlcmVudCB0aGluZ3MgdG8gaGFuZGxlIHRoZW0uICBXZSdsbCB0ZXN0IGJ5IHdyaXRpbmcgdG8gYSBwaXBlIGFuZAorLy8gcmVhZGluZyBiYWNrIGZyb20gaXQuCitURVNUX0YoSW9UZXN0LCBQaXBlSW8pIHsKKyAgaW50IGZpbGVzWzJdOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwga0Jsb2NrU2l6ZUNvdW50OyBpKyspIHsKKyAgICBmb3IgKGludCBqID0gMDsgaiA8IGtCbG9ja1NpemVDb3VudDsgaisrKSB7CisgICAgICAvLyBOZWVkIHRvIGNyZWF0ZSBhIG5ldyBwaXBlIGVhY2ggdGltZSBiZWNhdXNlIFJlYWRTdHVmZigpIGV4cGVjdHMKKyAgICAgIC8vIHRvIHNlZSBFT0YgYXQgdGhlIGVuZC4KKyAgICAgIEFTU0VSVF9FUShwaXBlKGZpbGVzKSwgMCk7CisKKyAgICAgIHsKKyAgICAgICAgRmlsZU91dHB1dFN0cmVhbSBvdXRwdXQoZmlsZXNbMV0sIGtCbG9ja1NpemVzW2ldKTsKKyAgICAgICAgV3JpdGVTdHVmZigmb3V0cHV0KTsKKyAgICAgICAgRVhQRUNUX0VRKDAsIG91dHB1dC5HZXRFcnJubygpKTsKKyAgICAgIH0KKyAgICAgIGNsb3NlKGZpbGVzWzFdKTsgIC8vIFNlbmQgRU9GLgorCisgICAgICB7CisgICAgICAgIEZpbGVJbnB1dFN0cmVhbSBpbnB1dChmaWxlc1swXSwga0Jsb2NrU2l6ZXNbal0pOworICAgICAgICBSZWFkU3R1ZmYoJmlucHV0KTsKKyAgICAgICAgRVhQRUNUX0VRKDAsIGlucHV0LkdldEVycm5vKCkpOworICAgICAgfQorICAgICAgY2xvc2UoZmlsZXNbMF0pOworICAgIH0KKyAgfQorfQorCisvLyBUZXN0IHVzaW5nIEMrKyBpb3N0cmVhbXMuCitURVNUX0YoSW9UZXN0LCBJb3N0cmVhbUlvKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwga0Jsb2NrU2l6ZUNvdW50OyBpKyspIHsKKyAgICBmb3IgKGludCBqID0gMDsgaiA8IGtCbG9ja1NpemVDb3VudDsgaisrKSB7CisgICAgICB7CisgICAgICAgIHN0cmluZ3N0cmVhbSBzdHJlYW07CisKKyAgICAgICAgeworICAgICAgICAgIE9zdHJlYW1PdXRwdXRTdHJlYW0gb3V0cHV0KCZzdHJlYW0sIGtCbG9ja1NpemVzW2ldKTsKKyAgICAgICAgICBXcml0ZVN0dWZmKCZvdXRwdXQpOworICAgICAgICAgIEVYUEVDVF9GQUxTRShzdHJlYW0uZmFpbCgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHsKKyAgICAgICAgICBJc3RyZWFtSW5wdXRTdHJlYW0gaW5wdXQoJnN0cmVhbSwga0Jsb2NrU2l6ZXNbal0pOworICAgICAgICAgIFJlYWRTdHVmZigmaW5wdXQpOworICAgICAgICAgIEVYUEVDVF9UUlVFKHN0cmVhbS5lb2YoKSk7CisgICAgICAgIH0KKyAgICAgIH0KKworICAgICAgeworICAgICAgICBzdHJpbmdzdHJlYW0gc3RyZWFtOworCisgICAgICAgIHsKKyAgICAgICAgICBPc3RyZWFtT3V0cHV0U3RyZWFtIG91dHB1dCgmc3RyZWFtLCBrQmxvY2tTaXplc1tpXSk7CisgICAgICAgICAgV3JpdGVTdHVmZkxhcmdlKCZvdXRwdXQpOworICAgICAgICAgIEVYUEVDVF9GQUxTRShzdHJlYW0uZmFpbCgpKTsKKyAgICAgICAgfQorCisgICAgICAgIHsKKyAgICAgICAgICBJc3RyZWFtSW5wdXRTdHJlYW0gaW5wdXQoJnN0cmVhbSwga0Jsb2NrU2l6ZXNbal0pOworICAgICAgICAgIFJlYWRTdHVmZkxhcmdlKCZpbnB1dCk7CisgICAgICAgICAgRVhQRUNUX1RSVUUoc3RyZWFtLmVvZigpKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgfQorfQorCisvLyBUbyB0ZXN0IENvbmNhdGVuYXRpbmdJbnB1dFN0cmVhbSwgd2UgY3JlYXRlIHNldmVyYWwgQXJyYXlJbnB1dFN0cmVhbXMKKy8vIGNvdmVyaW5nIGEgYnVmZmVyIGFuZCB0aGVuIGNvbmNhdGVuYXRlIHRoZW0uCitURVNUX0YoSW9UZXN0LCBDb25jYXRlbmF0aW5nSW5wdXRTdHJlYW0pIHsKKyAgY29uc3QgaW50IGtCdWZmZXJTaXplID0gMjU2OworICB1aW50OCBidWZmZXJba0J1ZmZlclNpemVdOworCisgIC8vIEZpbGwgdGhlIGJ1ZmZlci4KKyAgQXJyYXlPdXRwdXRTdHJlYW0gb3V0cHV0KGJ1ZmZlciwga0J1ZmZlclNpemUpOworICBXcml0ZVN0dWZmKCZvdXRwdXQpOworCisgIC8vIE5vdyBzcGxpdCBpdCB1cCBpbnRvIG11bHRpcGxlIHN0cmVhbXMgb2YgdmFyeWluZyBzaXplcy4KKyAgQVNTRVJUX0VRKDY4LCBvdXRwdXQuQnl0ZUNvdW50KCkpOyAgLy8gVGVzdCBkZXBlbmRzIG9uIHRoaXMuCisgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQxKGJ1ZmZlciAgICAgLCAxMik7CisgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQyKGJ1ZmZlciArIDEyLCAgNyk7CisgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQzKGJ1ZmZlciArIDE5LCAgNik7CisgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQ0KGJ1ZmZlciArIDI1LCAxNSk7CisgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQ1KGJ1ZmZlciArIDQwLCAgMCk7CisgIC8vIE5vdGU6ICBXZSB3YW50IHRvIG1ha2Ugc3VyZSB3ZSBoYXZlIGEgc3RyZWFtIGJvdW5kYXJ5IHNvbWV3aGVyZSBiZXR3ZWVuCisgIC8vIGJ5dGVzIDQyIGFuZCA2Miwgd2hpY2ggaXMgdGhlIHJhbmdlIHRoYXQgaXQgU2tpcCgpZWQgYnkgUmVhZFN0dWZmKCkuICBUaGlzCisgIC8vIHRlc3RzIHRoYXQgYSBidWcgdGhhdCBleGlzdGVkIGluIHRoZSBvcmlnaW5hbCBjb2RlIGZvciBTa2lwKCkgaXMgZml4ZWQuCisgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQ2KGJ1ZmZlciArIDQwLCAxMCk7CisgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQ3KGJ1ZmZlciArIDUwLCAxOCk7ICAvLyBUb3RhbCA9IDY4IGJ5dGVzLgorCisgIFplcm9Db3B5SW5wdXRTdHJlYW0qIHN0cmVhbXNbXSA9CisgICAgeyZpbnB1dDEsICZpbnB1dDIsICZpbnB1dDMsICZpbnB1dDQsICZpbnB1dDUsICZpbnB1dDYsICZpbnB1dDd9OworCisgIC8vIENyZWF0ZSB0aGUgY29uY2F0ZW5hdGluZyBzdHJlYW0gYW5kIHJlYWQuCisgIENvbmNhdGVuYXRpbmdJbnB1dFN0cmVhbSBpbnB1dChzdHJlYW1zLCBHT09HTEVfQVJSQVlTSVpFKHN0cmVhbXMpKTsKKyAgUmVhZFN0dWZmKCZpbnB1dCk7Cit9CisKKy8vIFRvIHRlc3QgTGltaXRpbmdJbnB1dFN0cmVhbSwgd2Ugd3JpdGUgb3VyIGdvbGRlbiB0ZXh0IHRvIGEgYnVmZmVyLCB0aGVuCisvLyBjcmVhdGUgYW4gQXJyYXlJbnB1dFN0cmVhbSB0aGF0IGNvbnRhaW5zIHRoZSB3aG9sZSBidWZmZXIgKG5vdCBqdXN0IHRoZQorLy8gYnl0ZXMgd3JpdHRlbiksIHRoZW4gdXNlIGEgTGltaXRpbmdJbnB1dFN0cmVhbSB0byBsaW1pdCBpdCBqdXN0IHRvIHRoZQorLy8gYnl0ZXMgd3JpdHRlbi4KK1RFU1RfRihJb1Rlc3QsIExpbWl0aW5nSW5wdXRTdHJlYW0pIHsKKyAgY29uc3QgaW50IGtCdWZmZXJTaXplID0gMjU2OworICB1aW50OCBidWZmZXJba0J1ZmZlclNpemVdOworCisgIC8vIEZpbGwgdGhlIGJ1ZmZlci4KKyAgQXJyYXlPdXRwdXRTdHJlYW0gb3V0cHV0KGJ1ZmZlciwga0J1ZmZlclNpemUpOworICBXcml0ZVN0dWZmKCZvdXRwdXQpOworCisgIC8vIFNldCB1cCBpbnB1dC4KKyAgQXJyYXlJbnB1dFN0cmVhbSBhcnJheV9pbnB1dChidWZmZXIsIGtCdWZmZXJTaXplKTsKKyAgTGltaXRpbmdJbnB1dFN0cmVhbSBpbnB1dCgmYXJyYXlfaW5wdXQsIG91dHB1dC5CeXRlQ291bnQoKSk7CisKKyAgUmVhZFN0dWZmKCZpbnB1dCk7Cit9CisKKy8vIENoZWNrcyB0aGF0IEJ5dGVDb3VudCB3b3JrcyBjb3JyZWN0bHkgZm9yIExpbWl0aW5nSW5wdXRTdHJlYW1zIHdoZXJlIHRoZQorLy8gdW5kZXJseWluZyBzdHJlYW0gaGFzIGFscmVhZHkgYmVlbiByZWFkLgorVEVTVF9GKElvVGVzdCwgTGltaXRpbmdJbnB1dFN0cmVhbUJ5dGVDb3VudCkgeworICBjb25zdCBpbnQga0hhbGZCdWZmZXJTaXplID0gMTI4OworICBjb25zdCBpbnQga0J1ZmZlclNpemUgPSBrSGFsZkJ1ZmZlclNpemUgKiAyOworICB1aW50OCBidWZmZXJba0J1ZmZlclNpemVdOworCisgIC8vIFNldCB1cCBpbnB1dC4gT25seSBhbGxvdyBoYWxmIHRvIGJlIHJlYWQgYXQgb25jZS4KKyAgQXJyYXlJbnB1dFN0cmVhbSBhcnJheV9pbnB1dChidWZmZXIsIGtCdWZmZXJTaXplLCBrSGFsZkJ1ZmZlclNpemUpOworICBjb25zdCB2b2lkKiBkYXRhOworICBpbnQgc2l6ZTsKKyAgRVhQRUNUX1RSVUUoYXJyYXlfaW5wdXQuTmV4dCgmZGF0YSwgJnNpemUpKTsKKyAgRVhQRUNUX0VRKGtIYWxmQnVmZmVyU2l6ZSwgYXJyYXlfaW5wdXQuQnl0ZUNvdW50KCkpOworICAvLyBrSGFsZkJ1ZmZlclNpemUgLSAxIHRvIHRlc3QgbGltaXRpbmcgbG9naWMgYXMgd2VsbC4KKyAgTGltaXRpbmdJbnB1dFN0cmVhbSBpbnB1dCgmYXJyYXlfaW5wdXQsIGtIYWxmQnVmZmVyU2l6ZSAtIDEpOworICBFWFBFQ1RfRVEoMCwgaW5wdXQuQnl0ZUNvdW50KCkpOworICBFWFBFQ1RfVFJVRShpbnB1dC5OZXh0KCZkYXRhLCAmc2l6ZSkpOworICBFWFBFQ1RfRVEoa0hhbGZCdWZmZXJTaXplIC0gMSAsIGlucHV0LkJ5dGVDb3VudCgpKTsKK30KKworLy8gQ2hlY2sgdGhhdCBhIHplcm8tc2l6ZSBhcnJheSBkb2Vzbid0IGNvbmZ1c2UgdGhlIGNvZGUuCitURVNUKFplcm9TaXplQXJyYXksIElucHV0KSB7CisgIEFycmF5SW5wdXRTdHJlYW0gaW5wdXQoTlVMTCwgMCk7CisgIGNvbnN0IHZvaWQqIGRhdGE7CisgIGludCBzaXplOworICBFWFBFQ1RfRkFMU0UoaW5wdXQuTmV4dCgmZGF0YSwgJnNpemUpKTsKK30KKworVEVTVChaZXJvU2l6ZUFycmF5LCBPdXRwdXQpIHsKKyAgQXJyYXlPdXRwdXRTdHJlYW0gb3V0cHV0KE5VTEwsIDApOworICB2b2lkKiBkYXRhOworICBpbnQgc2l6ZTsKKyAgRVhQRUNUX0ZBTFNFKG91dHB1dC5OZXh0KCZkYXRhLCAmc2l6ZSkpOworfQorCit9ICAvLyBuYW1lc3BhY2UKK30gIC8vIG5hbWVzcGFjZSBpbworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2xpdGVfYXJlbmFfdW5pdHRlc3QuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2xpdGVfYXJlbmFfdW5pdHRlc3QuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjBiZWU4OAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvbGl0ZV9hcmVuYV91bml0dGVzdC5jYwpAQCAtMCwwICsxLDgzIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9hcmVuYV90ZXN0X3V0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWFwX2xpdGVfdGVzdF91dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZ29vZ2xldGVzdC5oPgorI2luY2x1ZGUgPGd0ZXN0L2d0ZXN0Lmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSB7CisKK1RFU1QoTGl0ZUFyZW5hVGVzdCwgTWFwTm9IZWFwQWxsb2NhdGlvbikgeworICAvLyBBbGxvY2F0ZSBhIGxhcmdlIGluaXRpYWwgYmxvY2sgdG8gYXZvaWQgbWFsbG9jcyBkdXJpbmcgaG9va2VkIHRlc3QuCisgIHN0ZDo6dmVjdG9yPGNoYXI+IGFyZW5hX2Jsb2NrKDEyOCAqIDEwMjQpOworICBnb29nbGU6OnByb3RvYnVmOjpBcmVuYU9wdGlvbnMgb3B0aW9uczsKKyAgb3B0aW9ucy5pbml0aWFsX2Jsb2NrID0gJmFyZW5hX2Jsb2NrWzBdOworICBvcHRpb25zLmluaXRpYWxfYmxvY2tfc2l6ZSA9IGFyZW5hX2Jsb2NrLnNpemUoKTsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEgYXJlbmEob3B0aW9ucyk7CisgIHN0cmluZyBkYXRhOworICBkYXRhLnJlc2VydmUoMTI4ICogMTAyNCk7CisKKyAgeworICAgIC8vIFRPRE8odGVib3JpbmcpOiBFbmFibGUgbm8gaGVhcCBjaGVjayB3aGVuIEFyZW5hU3RyaW5nUHRyIGlzIHVzZWQgaW4KKyAgICAvLyBNYXAuCisgICAgLy8gZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6Ok5vSGVhcENoZWNrZXIgbm9faGVhcDsKKworICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0QXJlbmFNYXBMaXRlKiBmcm9tID0KKyAgICAgICAgZ29vZ2xlOjpwcm90b2J1Zjo6QXJlbmE6OkNyZWF0ZU1lc3NhZ2U8cHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RBcmVuYU1hcExpdGU+KCZhcmVuYSk7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6TWFwTGl0ZVRlc3RVdGlsOjpTZXRBcmVuYU1hcEZpZWxkcyhmcm9tKTsKKyAgICBmcm9tLT5TZXJpYWxpemVUb1N0cmluZygmZGF0YSk7CisKKyAgICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEFyZW5hTWFwTGl0ZSogdG8gPQorICAgICAgICBnb29nbGU6OnByb3RvYnVmOjpBcmVuYTo6Q3JlYXRlTWVzc2FnZTxwcm90b2J1Zl91bml0dGVzdDo6VGVzdEFyZW5hTWFwTGl0ZT4oJmFyZW5hKTsKKyAgICB0by0+UGFyc2VGcm9tU3RyaW5nKGRhdGEpOworICAgIGdvb2dsZTo6cHJvdG9idWY6Ok1hcExpdGVUZXN0VXRpbDo6RXhwZWN0QXJlbmFNYXBGaWVsZHNTZXQoKnRvKTsKKyAgfQorfQorCitURVNUKExpdGVBcmVuYVRlc3QsIFVua25vd25GaWVsZE1lbUxlYWspIHsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEgYXJlbmE7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpGb3JlaWduTWVzc2FnZUFyZW5hTGl0ZSogbWVzc2FnZSA9CisgICAgICBnb29nbGU6OnByb3RvYnVmOjpBcmVuYTo6Q3JlYXRlTWVzc2FnZTxwcm90b2J1Zl91bml0dGVzdDo6Rm9yZWlnbk1lc3NhZ2VBcmVuYUxpdGU+KAorICAgICAgICAgICZhcmVuYSk7CisgIHN0cmluZyBkYXRhID0gIlwwMTJcMDAwIjsKKyAgaW50IG9yaWdpbmFsX2NhcGFjaXR5ID0gZGF0YS5jYXBhY2l0eSgpOworICB3aGlsZSAoZGF0YS5jYXBhY2l0eSgpIDw9IG9yaWdpbmFsX2NhcGFjaXR5KSB7CisgICAgZGF0YS5hcHBlbmQoImEiKTsKKyAgfQorICBkYXRhWzFdID0gZGF0YS5zaXplKCkgLSAyOworICBtZXNzYWdlLT5QYXJzZUZyb21TdHJpbmcoZGF0YSk7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL2xpdGVfdW5pdHRlc3QuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL2xpdGVfdW5pdHRlc3QuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDE5NDhhYgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvbGl0ZV91bml0dGVzdC5jYwpAQCAtMCwwICsxLDY5MSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKworI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxpb3N0cmVhbT4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9sb2dnaW5nLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9hcmVuYV90ZXN0X3V0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWFwX2xpdGVfdW5pdHRlc3QucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWFwX2xpdGVfdGVzdF91dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RfdXRpbF9saXRlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2xpdGUucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbF9saXRlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0X2xpdGUuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZV9pbmwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorCit1c2luZyBuYW1lc3BhY2Ugc3RkOworCituYW1lc3BhY2UgeworLy8gSGVscGVyIG1ldGhvZHMgdG8gdGVzdCBwYXJzaW5nIG1lcmdlIGJlaGF2aW9yLgordm9pZCBFeHBlY3RNZXNzYWdlTWVyZ2VkKGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OnVuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlJiBtZXNzYWdlKSB7CisgIEdPT0dMRV9DSEVDSyhtZXNzYWdlLm9wdGlvbmFsX2ludDMyKCkgPT0gMyk7CisgIEdPT0dMRV9DSEVDSyhtZXNzYWdlLm9wdGlvbmFsX2ludDY0KCkgPT0gMik7CisgIEdPT0dMRV9DSEVDSyhtZXNzYWdlLm9wdGlvbmFsX3N0cmluZygpID09ICJoZWxsbyIpOworfQorCit2b2lkIEFzc2lnblBhcnNpbmdNZXJnZU1lc3NhZ2VzKAorICAgIGdvb2dsZTo6cHJvdG9idWY6OnVuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlKiBtc2cxLAorICAgIGdvb2dsZTo6cHJvdG9idWY6OnVuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlKiBtc2cyLAorICAgIGdvb2dsZTo6cHJvdG9idWY6OnVuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlKiBtc2czKSB7CisgIG1zZzEtPnNldF9vcHRpb25hbF9pbnQzMigxKTsKKyAgbXNnMi0+c2V0X29wdGlvbmFsX2ludDY0KDIpOworICBtc2czLT5zZXRfb3B0aW9uYWxfaW50MzIoMyk7CisgIG1zZzMtPnNldF9vcHRpb25hbF9zdHJpbmcoImhlbGxvIik7Cit9CisKK3ZvaWQgU2V0QWxsVHlwZXNJbkVtcHR5TWVzc2FnZVVua25vd25GaWVsZHMoCisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6dW5pdHRlc3Q6OlRlc3RFbXB0eU1lc3NhZ2VMaXRlKiBlbXB0eV9tZXNzYWdlKSB7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlIG1lc3NhZ2U7CisgIGdvb2dsZTo6cHJvdG9idWY6OlRlc3RVdGlsTGl0ZTo6RXhwZWN0Q2xlYXIobWVzc2FnZSk7CisgIGdvb2dsZTo6cHJvdG9idWY6OlRlc3RVdGlsTGl0ZTo6U2V0QWxsRmllbGRzKCZtZXNzYWdlKTsKKyAgc3RyaW5nIGRhdGEgPSBtZXNzYWdlLlNlcmlhbGl6ZUFzU3RyaW5nKCk7CisgIGVtcHR5X21lc3NhZ2UtPlBhcnNlRnJvbVN0cmluZyhkYXRhKTsKK30KKwordm9pZCBTZXRTb21lVHlwZXNJbkVtcHR5TWVzc2FnZVVua25vd25GaWVsZHMoCisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6dW5pdHRlc3Q6OlRlc3RFbXB0eU1lc3NhZ2VMaXRlKiBlbXB0eV9tZXNzYWdlKSB7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlIG1lc3NhZ2U7CisgIGdvb2dsZTo6cHJvdG9idWY6OlRlc3RVdGlsTGl0ZTo6RXhwZWN0Q2xlYXIobWVzc2FnZSk7CisgIG1lc3NhZ2Uuc2V0X29wdGlvbmFsX2ludDMyKDEwMSk7CisgIG1lc3NhZ2Uuc2V0X29wdGlvbmFsX2ludDY0KDEwMik7CisgIG1lc3NhZ2Uuc2V0X29wdGlvbmFsX3VpbnQzMigxMDMpOworICBtZXNzYWdlLnNldF9vcHRpb25hbF91aW50NjQoMTA0KTsKKyAgc3RyaW5nIGRhdGEgPSBtZXNzYWdlLlNlcmlhbGl6ZUFzU3RyaW5nKCk7CisgIGVtcHR5X21lc3NhZ2UtPlBhcnNlRnJvbVN0cmluZyhkYXRhKTsKK30KKworfSAgLy8gbmFtZXNwYWNlCisKKyNkZWZpbmUgRVhQRUNUX1RSVUUgR09PR0xFX0NIRUNLCisjZGVmaW5lIEFTU0VSVF9UUlVFIEdPT0dMRV9DSEVDSworI2RlZmluZSBFWFBFQ1RfRkFMU0UoQ09ORCkgR09PR0xFX0NIRUNLKCEoQ09ORCkpCisjZGVmaW5lIEVYUEVDVF9FUSBHT09HTEVfQ0hFQ0tfRVEKKyNkZWZpbmUgQVNTRVJUX0VRIEdPT0dMRV9DSEVDS19FUQorCitpbnQgbWFpbihpbnQgYXJnYywgY2hhciogYXJndltdKSB7CisgIHN0cmluZyBkYXRhLCBkYXRhMiwgcGFja2VkX2RhdGE7CisKKyAgeworICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlIG1lc3NhZ2UsIG1lc3NhZ2UyLCBtZXNzYWdlMzsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpUZXN0VXRpbExpdGU6OkV4cGVjdENsZWFyKG1lc3NhZ2UpOworICAgIGdvb2dsZTo6cHJvdG9idWY6OlRlc3RVdGlsTGl0ZTo6U2V0QWxsRmllbGRzKCZtZXNzYWdlKTsKKyAgICBtZXNzYWdlMi5Db3B5RnJvbShtZXNzYWdlKTsKKyAgICBkYXRhID0gbWVzc2FnZS5TZXJpYWxpemVBc1N0cmluZygpOworICAgIG1lc3NhZ2UzLlBhcnNlRnJvbVN0cmluZyhkYXRhKTsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpUZXN0VXRpbExpdGU6OkV4cGVjdEFsbEZpZWxkc1NldChtZXNzYWdlKTsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpUZXN0VXRpbExpdGU6OkV4cGVjdEFsbEZpZWxkc1NldChtZXNzYWdlMik7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6VGVzdFV0aWxMaXRlOjpFeHBlY3RBbGxGaWVsZHNTZXQobWVzc2FnZTMpOworICAgIGdvb2dsZTo6cHJvdG9idWY6OlRlc3RVdGlsTGl0ZTo6TW9kaWZ5UmVwZWF0ZWRGaWVsZHMoJm1lc3NhZ2UpOworICAgIGdvb2dsZTo6cHJvdG9idWY6OlRlc3RVdGlsTGl0ZTo6RXhwZWN0UmVwZWF0ZWRGaWVsZHNNb2RpZmllZChtZXNzYWdlKTsKKyAgICBtZXNzYWdlLkNsZWFyKCk7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6VGVzdFV0aWxMaXRlOjpFeHBlY3RDbGVhcihtZXNzYWdlKTsKKyAgfQorCisgIHsKKyAgICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnNMaXRlIG1lc3NhZ2UsIG1lc3NhZ2UyLCBtZXNzYWdlMzsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpUZXN0VXRpbExpdGU6OkV4cGVjdEV4dGVuc2lvbnNDbGVhcihtZXNzYWdlKTsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpUZXN0VXRpbExpdGU6OlNldEFsbEV4dGVuc2lvbnMoJm1lc3NhZ2UpOworICAgIG1lc3NhZ2UyLkNvcHlGcm9tKG1lc3NhZ2UpOworICAgIHN0cmluZyBleHRlbnNpb25zX2RhdGEgPSBtZXNzYWdlLlNlcmlhbGl6ZUFzU3RyaW5nKCk7CisgICAgbWVzc2FnZTMuUGFyc2VGcm9tU3RyaW5nKGV4dGVuc2lvbnNfZGF0YSk7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6VGVzdFV0aWxMaXRlOjpFeHBlY3RBbGxFeHRlbnNpb25zU2V0KG1lc3NhZ2UpOworICAgIGdvb2dsZTo6cHJvdG9idWY6OlRlc3RVdGlsTGl0ZTo6RXhwZWN0QWxsRXh0ZW5zaW9uc1NldChtZXNzYWdlMik7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6VGVzdFV0aWxMaXRlOjpFeHBlY3RBbGxFeHRlbnNpb25zU2V0KG1lc3NhZ2UzKTsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpUZXN0VXRpbExpdGU6Ok1vZGlmeVJlcGVhdGVkRXh0ZW5zaW9ucygmbWVzc2FnZSk7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6VGVzdFV0aWxMaXRlOjpFeHBlY3RSZXBlYXRlZEV4dGVuc2lvbnNNb2RpZmllZChtZXNzYWdlKTsKKyAgICBtZXNzYWdlLkNsZWFyKCk7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6VGVzdFV0aWxMaXRlOjpFeHBlY3RFeHRlbnNpb25zQ2xlYXIobWVzc2FnZSk7CisgIH0KKworICB7CisgICAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RQYWNrZWRUeXBlc0xpdGUgbWVzc2FnZSwgbWVzc2FnZTIsIG1lc3NhZ2UzOworICAgIGdvb2dsZTo6cHJvdG9idWY6OlRlc3RVdGlsTGl0ZTo6RXhwZWN0UGFja2VkQ2xlYXIobWVzc2FnZSk7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6VGVzdFV0aWxMaXRlOjpTZXRQYWNrZWRGaWVsZHMoJm1lc3NhZ2UpOworICAgIG1lc3NhZ2UyLkNvcHlGcm9tKG1lc3NhZ2UpOworICAgIHBhY2tlZF9kYXRhID0gbWVzc2FnZS5TZXJpYWxpemVBc1N0cmluZygpOworICAgIG1lc3NhZ2UzLlBhcnNlRnJvbVN0cmluZyhwYWNrZWRfZGF0YSk7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6VGVzdFV0aWxMaXRlOjpFeHBlY3RQYWNrZWRGaWVsZHNTZXQobWVzc2FnZSk7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6VGVzdFV0aWxMaXRlOjpFeHBlY3RQYWNrZWRGaWVsZHNTZXQobWVzc2FnZTIpOworICAgIGdvb2dsZTo6cHJvdG9idWY6OlRlc3RVdGlsTGl0ZTo6RXhwZWN0UGFja2VkRmllbGRzU2V0KG1lc3NhZ2UzKTsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpUZXN0VXRpbExpdGU6Ok1vZGlmeVBhY2tlZEZpZWxkcygmbWVzc2FnZSk7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6VGVzdFV0aWxMaXRlOjpFeHBlY3RQYWNrZWRGaWVsZHNNb2RpZmllZChtZXNzYWdlKTsKKyAgICBtZXNzYWdlLkNsZWFyKCk7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6VGVzdFV0aWxMaXRlOjpFeHBlY3RQYWNrZWRDbGVhcihtZXNzYWdlKTsKKyAgfQorCisgIHsKKyAgICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdFBhY2tlZEV4dGVuc2lvbnNMaXRlIG1lc3NhZ2UsIG1lc3NhZ2UyLCBtZXNzYWdlMzsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpUZXN0VXRpbExpdGU6OkV4cGVjdFBhY2tlZEV4dGVuc2lvbnNDbGVhcihtZXNzYWdlKTsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpUZXN0VXRpbExpdGU6OlNldFBhY2tlZEV4dGVuc2lvbnMoJm1lc3NhZ2UpOworICAgIG1lc3NhZ2UyLkNvcHlGcm9tKG1lc3NhZ2UpOworICAgIHN0cmluZyBwYWNrZWRfZXh0ZW5zaW9uc19kYXRhID0gbWVzc2FnZS5TZXJpYWxpemVBc1N0cmluZygpOworICAgIEdPT0dMRV9DSEVDSyhwYWNrZWRfZXh0ZW5zaW9uc19kYXRhID09IHBhY2tlZF9kYXRhKTsKKyAgICBtZXNzYWdlMy5QYXJzZUZyb21TdHJpbmcocGFja2VkX2V4dGVuc2lvbnNfZGF0YSk7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6VGVzdFV0aWxMaXRlOjpFeHBlY3RQYWNrZWRFeHRlbnNpb25zU2V0KG1lc3NhZ2UpOworICAgIGdvb2dsZTo6cHJvdG9idWY6OlRlc3RVdGlsTGl0ZTo6RXhwZWN0UGFja2VkRXh0ZW5zaW9uc1NldChtZXNzYWdlMik7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6VGVzdFV0aWxMaXRlOjpFeHBlY3RQYWNrZWRFeHRlbnNpb25zU2V0KG1lc3NhZ2UzKTsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpUZXN0VXRpbExpdGU6Ok1vZGlmeVBhY2tlZEV4dGVuc2lvbnMoJm1lc3NhZ2UpOworICAgIGdvb2dsZTo6cHJvdG9idWY6OlRlc3RVdGlsTGl0ZTo6RXhwZWN0UGFja2VkRXh0ZW5zaW9uc01vZGlmaWVkKG1lc3NhZ2UpOworICAgIG1lc3NhZ2UuQ2xlYXIoKTsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpUZXN0VXRpbExpdGU6OkV4cGVjdFBhY2tlZEV4dGVuc2lvbnNDbGVhcihtZXNzYWdlKTsKKyAgfQorCisgIHsKKyAgICAvLyBUZXN0IHRoYXQgaWYgYW4gb3B0aW9uYWwgb3IgcmVxdWlyZWQgbWVzc2FnZS9ncm91cCBmaWVsZCBhcHBlYXJzIG11bHRpcGxlCisgICAgLy8gdGltZXMgaW4gdGhlIGlucHV0LCB0aGV5IG5lZWQgdG8gYmUgbWVyZ2VkLgorICAgIGdvb2dsZTo6cHJvdG9idWY6OnVuaXR0ZXN0OjpUZXN0UGFyc2luZ01lcmdlTGl0ZTo6UmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IgZ2VuZXJhdG9yOworICAgIGdvb2dsZTo6cHJvdG9idWY6OnVuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlKiBtc2cxOworICAgIGdvb2dsZTo6cHJvdG9idWY6OnVuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlKiBtc2cyOworICAgIGdvb2dsZTo6cHJvdG9idWY6OnVuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlKiBtc2czOworCisjZGVmaW5lIEFTU0lHTl9SRVBFQVRFRF9GSUVMRChGSUVMRCkgICAgICAgICAgICAgICAgXAorICBtc2cxID0gZ2VuZXJhdG9yLmFkZF8jI0ZJRUxEKCk7ICAgICAgICAgICAgICAgICAgIFwKKyAgbXNnMiA9IGdlbmVyYXRvci5hZGRfIyNGSUVMRCgpOyAgICAgICAgICAgICAgICAgICBcCisgIG1zZzMgPSBnZW5lcmF0b3IuYWRkXyMjRklFTEQoKTsgICAgICAgICAgICAgICAgICAgXAorICBBc3NpZ25QYXJzaW5nTWVyZ2VNZXNzYWdlcyhtc2cxLCBtc2cyLCBtc2czKQorCisgICAgQVNTSUdOX1JFUEVBVEVEX0ZJRUxEKGZpZWxkMSk7CisgICAgQVNTSUdOX1JFUEVBVEVEX0ZJRUxEKGZpZWxkMik7CisgICAgQVNTSUdOX1JFUEVBVEVEX0ZJRUxEKGZpZWxkMyk7CisgICAgQVNTSUdOX1JFUEVBVEVEX0ZJRUxEKGV4dDEpOworICAgIEFTU0lHTl9SRVBFQVRFRF9GSUVMRChleHQyKTsKKworI3VuZGVmIEFTU0lHTl9SRVBFQVRFRF9GSUVMRAorI2RlZmluZSBBU1NJR05fUkVQRUFURURfR1JPVVAoRklFTEQpICAgICAgICAgICAgICAgIFwKKyAgbXNnMSA9IGdlbmVyYXRvci5hZGRfIyNGSUVMRCgpLT5tdXRhYmxlX2ZpZWxkMSgpOyBcCisgIG1zZzIgPSBnZW5lcmF0b3IuYWRkXyMjRklFTEQoKS0+bXV0YWJsZV9maWVsZDEoKTsgXAorICBtc2czID0gZ2VuZXJhdG9yLmFkZF8jI0ZJRUxEKCktPm11dGFibGVfZmllbGQxKCk7IFwKKyAgQXNzaWduUGFyc2luZ01lcmdlTWVzc2FnZXMobXNnMSwgbXNnMiwgbXNnMykKKworICAgIEFTU0lHTl9SRVBFQVRFRF9HUk9VUChncm91cDEpOworICAgIEFTU0lHTl9SRVBFQVRFRF9HUk9VUChncm91cDIpOworCisjdW5kZWYgQVNTSUdOX1JFUEVBVEVEX0dST1VQCisKKyAgICBzdHJpbmcgYnVmZmVyOworICAgIGdlbmVyYXRvci5TZXJpYWxpemVUb1N0cmluZygmYnVmZmVyKTsKKyAgICBnb29nbGU6OnByb3RvYnVmOjp1bml0dGVzdDo6VGVzdFBhcnNpbmdNZXJnZUxpdGUgcGFyc2luZ19tZXJnZTsKKyAgICBwYXJzaW5nX21lcmdlLlBhcnNlRnJvbVN0cmluZyhidWZmZXIpOworCisgICAgLy8gUmVxdWlyZWQgYW5kIG9wdGlvbmFsIGZpZWxkcyBzaG91bGQgYmUgbWVyZ2VkLgorICAgIEV4cGVjdE1lc3NhZ2VNZXJnZWQocGFyc2luZ19tZXJnZS5yZXF1aXJlZF9hbGxfdHlwZXMoKSk7CisgICAgRXhwZWN0TWVzc2FnZU1lcmdlZChwYXJzaW5nX21lcmdlLm9wdGlvbmFsX2FsbF90eXBlcygpKTsKKyAgICBFeHBlY3RNZXNzYWdlTWVyZ2VkKAorICAgICAgICBwYXJzaW5nX21lcmdlLm9wdGlvbmFsZ3JvdXAoKS5vcHRpb25hbF9ncm91cF9hbGxfdHlwZXMoKSk7CisgICAgRXhwZWN0TWVzc2FnZU1lcmdlZChwYXJzaW5nX21lcmdlLkdldEV4dGVuc2lvbigKKyAgICAgICAgZ29vZ2xlOjpwcm90b2J1Zjo6dW5pdHRlc3Q6OlRlc3RQYXJzaW5nTWVyZ2VMaXRlOjpvcHRpb25hbF9leHQpKTsKKworICAgIC8vIFJlcGVhdGVkIGZpZWxkcyBzaG91bGQgbm90IGJlIG1lcmdlZC4KKyAgICBHT09HTEVfQ0hFQ0socGFyc2luZ19tZXJnZS5yZXBlYXRlZF9hbGxfdHlwZXNfc2l6ZSgpID09IDMpOworICAgIEdPT0dMRV9DSEVDSyhwYXJzaW5nX21lcmdlLnJlcGVhdGVkZ3JvdXBfc2l6ZSgpID09IDMpOworICAgIEdPT0dMRV9DSEVDSyhwYXJzaW5nX21lcmdlLkV4dGVuc2lvblNpemUoCisgICAgICAgIGdvb2dsZTo6cHJvdG9idWY6OnVuaXR0ZXN0OjpUZXN0UGFyc2luZ01lcmdlTGl0ZTo6cmVwZWF0ZWRfZXh0KSA9PSAzKTsKKyAgfQorCisgIC8vIFRlc3QgdW5rbm93biBmaWVsZHMgc3VwcG9ydCBmb3IgbGl0ZSBtZXNzYWdlcy4KKyAgeworICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlIG1lc3NhZ2UsIG1lc3NhZ2UyOworICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0RW1wdHlNZXNzYWdlTGl0ZSBlbXB0eV9tZXNzYWdlOworICAgIGdvb2dsZTo6cHJvdG9idWY6OlRlc3RVdGlsTGl0ZTo6RXhwZWN0Q2xlYXIobWVzc2FnZSk7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6VGVzdFV0aWxMaXRlOjpTZXRBbGxGaWVsZHMoJm1lc3NhZ2UpOworICAgIGRhdGEgPSBtZXNzYWdlLlNlcmlhbGl6ZUFzU3RyaW5nKCk7CisgICAgZW1wdHlfbWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoZGF0YSk7CisgICAgZGF0YS5jbGVhcigpOworICAgIGRhdGEgPSBlbXB0eV9tZXNzYWdlLlNlcmlhbGl6ZUFzU3RyaW5nKCk7CisgICAgbWVzc2FnZTIuUGFyc2VGcm9tU3RyaW5nKGRhdGEpOworICAgIGRhdGEgPSBtZXNzYWdlMi5TZXJpYWxpemVBc1N0cmluZygpOworICAgIGdvb2dsZTo6cHJvdG9idWY6OlRlc3RVdGlsTGl0ZTo6RXhwZWN0QWxsRmllbGRzU2V0KG1lc3NhZ2UyKTsKKyAgICBtZXNzYWdlLkNsZWFyKCk7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6VGVzdFV0aWxMaXRlOjpFeHBlY3RDbGVhcihtZXNzYWdlKTsKKyAgfQorCisgIHsKKyAgICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnNMaXRlIG1lc3NhZ2UsIG1lc3NhZ2UyOworICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0RW1wdHlNZXNzYWdlTGl0ZSBlbXB0eV9tZXNzYWdlOworICAgIGdvb2dsZTo6cHJvdG9idWY6OlRlc3RVdGlsTGl0ZTo6RXhwZWN0RXh0ZW5zaW9uc0NsZWFyKG1lc3NhZ2UpOworICAgIGdvb2dsZTo6cHJvdG9idWY6OlRlc3RVdGlsTGl0ZTo6U2V0QWxsRXh0ZW5zaW9ucygmbWVzc2FnZSk7CisgICAgZGF0YSA9IG1lc3NhZ2UuU2VyaWFsaXplQXNTdHJpbmcoKTsKKyAgICBlbXB0eV9tZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhkYXRhKTsKKyAgICBkYXRhLmNsZWFyKCk7CisgICAgZGF0YSA9IGVtcHR5X21lc3NhZ2UuU2VyaWFsaXplQXNTdHJpbmcoKTsKKyAgICBtZXNzYWdlMi5QYXJzZUZyb21TdHJpbmcoZGF0YSk7CisgICAgZGF0YSA9IG1lc3NhZ2UyLlNlcmlhbGl6ZUFzU3RyaW5nKCk7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6VGVzdFV0aWxMaXRlOjpFeHBlY3RBbGxFeHRlbnNpb25zU2V0KG1lc3NhZ2UyKTsKKyAgICBtZXNzYWdlLkNsZWFyKCk7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6VGVzdFV0aWxMaXRlOjpFeHBlY3RFeHRlbnNpb25zQ2xlYXIobWVzc2FnZSk7CisgIH0KKworICB7CisgICAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RQYWNrZWRUeXBlc0xpdGUgbWVzc2FnZSwgbWVzc2FnZTI7CisgICAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RFbXB0eU1lc3NhZ2VMaXRlIGVtcHR5X21lc3NhZ2U7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6VGVzdFV0aWxMaXRlOjpFeHBlY3RQYWNrZWRDbGVhcihtZXNzYWdlKTsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpUZXN0VXRpbExpdGU6OlNldFBhY2tlZEZpZWxkcygmbWVzc2FnZSk7CisgICAgZGF0YSA9IG1lc3NhZ2UuU2VyaWFsaXplQXNTdHJpbmcoKTsKKyAgICBlbXB0eV9tZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhkYXRhKTsKKyAgICBkYXRhLmNsZWFyKCk7CisgICAgZGF0YSA9IGVtcHR5X21lc3NhZ2UuU2VyaWFsaXplQXNTdHJpbmcoKTsKKyAgICBtZXNzYWdlMi5QYXJzZUZyb21TdHJpbmcoZGF0YSk7CisgICAgZGF0YSA9IG1lc3NhZ2UyLlNlcmlhbGl6ZUFzU3RyaW5nKCk7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6VGVzdFV0aWxMaXRlOjpFeHBlY3RQYWNrZWRGaWVsZHNTZXQobWVzc2FnZTIpOworICAgIG1lc3NhZ2UuQ2xlYXIoKTsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpUZXN0VXRpbExpdGU6OkV4cGVjdFBhY2tlZENsZWFyKG1lc3NhZ2UpOworICB9CisKKyAgeworICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0UGFja2VkRXh0ZW5zaW9uc0xpdGUgbWVzc2FnZSwgbWVzc2FnZTI7CisgICAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RFbXB0eU1lc3NhZ2VMaXRlIGVtcHR5X21lc3NhZ2U7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6VGVzdFV0aWxMaXRlOjpFeHBlY3RQYWNrZWRFeHRlbnNpb25zQ2xlYXIobWVzc2FnZSk7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6VGVzdFV0aWxMaXRlOjpTZXRQYWNrZWRFeHRlbnNpb25zKCZtZXNzYWdlKTsKKyAgICBkYXRhID0gbWVzc2FnZS5TZXJpYWxpemVBc1N0cmluZygpOworICAgIGVtcHR5X21lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKGRhdGEpOworICAgIGRhdGEuY2xlYXIoKTsKKyAgICBkYXRhID0gZW1wdHlfbWVzc2FnZS5TZXJpYWxpemVBc1N0cmluZygpOworICAgIG1lc3NhZ2UyLlBhcnNlRnJvbVN0cmluZyhkYXRhKTsKKyAgICBkYXRhID0gbWVzc2FnZTIuU2VyaWFsaXplQXNTdHJpbmcoKTsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpUZXN0VXRpbExpdGU6OkV4cGVjdFBhY2tlZEV4dGVuc2lvbnNTZXQobWVzc2FnZTIpOworICAgIG1lc3NhZ2UuQ2xlYXIoKTsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpUZXN0VXRpbExpdGU6OkV4cGVjdFBhY2tlZEV4dGVuc2lvbnNDbGVhcihtZXNzYWdlKTsKKyAgfQorCisgIHsKKyAgICAvLyBUZXN0IFVua25vd24gZmllbGRzIHN3YXAKKyAgICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEVtcHR5TWVzc2FnZUxpdGUgZW1wdHlfbWVzc2FnZSwgZW1wdHlfbWVzc2FnZTI7CisgICAgU2V0QWxsVHlwZXNJbkVtcHR5TWVzc2FnZVVua25vd25GaWVsZHMoJmVtcHR5X21lc3NhZ2UpOworICAgIFNldFNvbWVUeXBlc0luRW1wdHlNZXNzYWdlVW5rbm93bkZpZWxkcygmZW1wdHlfbWVzc2FnZTIpOworICAgIGRhdGEgPSBlbXB0eV9tZXNzYWdlLlNlcmlhbGl6ZUFzU3RyaW5nKCk7CisgICAgZGF0YTIgPSBlbXB0eV9tZXNzYWdlMi5TZXJpYWxpemVBc1N0cmluZygpOworICAgIGVtcHR5X21lc3NhZ2UuU3dhcCgmZW1wdHlfbWVzc2FnZTIpOworICAgIEdPT0dMRV9DSEVDS19FUShkYXRhLCBlbXB0eV9tZXNzYWdlMi5TZXJpYWxpemVBc1N0cmluZygpKTsKKyAgICBHT09HTEVfQ0hFQ0tfRVEoZGF0YTIsIGVtcHR5X21lc3NhZ2UuU2VyaWFsaXplQXNTdHJpbmcoKSk7CisgIH0KKworICB7CisgICAgLy8gVGVzdCB1bmtub3duIGZpZWxkcyBzd2FwIHdpdGggc2VsZgorICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0RW1wdHlNZXNzYWdlTGl0ZSBlbXB0eV9tZXNzYWdlOworICAgIFNldEFsbFR5cGVzSW5FbXB0eU1lc3NhZ2VVbmtub3duRmllbGRzKCZlbXB0eV9tZXNzYWdlKTsKKyAgICBkYXRhID0gZW1wdHlfbWVzc2FnZS5TZXJpYWxpemVBc1N0cmluZygpOworICAgIGVtcHR5X21lc3NhZ2UuU3dhcCgmZW1wdHlfbWVzc2FnZSk7CisgICAgR09PR0xFX0NIRUNLX0VRKGRhdGEsIGVtcHR5X21lc3NhZ2UuU2VyaWFsaXplQXNTdHJpbmcoKSk7CisgIH0KKworICB7CisgICAgLy8gVGVzdCBNZXJnZUZyb20gd2l0aCB1bmtub3duIGZpZWxkcworICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlIG1lc3NhZ2UsIG1lc3NhZ2UyOworICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0RW1wdHlNZXNzYWdlTGl0ZSBlbXB0eV9tZXNzYWdlLCBlbXB0eV9tZXNzYWdlMjsKKyAgICBtZXNzYWdlLnNldF9vcHRpb25hbF9pbnQzMigxMDEpOworICAgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX2ludDMyKDIwMSk7CisgICAgbWVzc2FnZS5zZXRfb3B0aW9uYWxfbmVzdGVkX2VudW0oZ29vZ2xlOjpwcm90b2J1Zjo6dW5pdHRlc3Q6OlRlc3RBbGxUeXBlc0xpdGU6OkJBWik7CisgICAgbWVzc2FnZTIuc2V0X29wdGlvbmFsX2ludDY0KDEwMik7CisgICAgbWVzc2FnZTIuYWRkX3JlcGVhdGVkX2ludDY0KDIwMik7CisgICAgbWVzc2FnZTIuc2V0X29wdGlvbmFsX2ZvcmVpZ25fZW51bShnb29nbGU6OnByb3RvYnVmOjp1bml0dGVzdDo6Rk9SRUlHTl9MSVRFX0JBWik7CisKKyAgICBkYXRhID0gbWVzc2FnZS5TZXJpYWxpemVBc1N0cmluZygpOworICAgIGVtcHR5X21lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKGRhdGEpOworICAgIGRhdGEgPSBtZXNzYWdlMi5TZXJpYWxpemVBc1N0cmluZygpOworICAgIGVtcHR5X21lc3NhZ2UyLlBhcnNlRnJvbVN0cmluZyhkYXRhKTsKKyAgICBtZXNzYWdlLk1lcmdlRnJvbShtZXNzYWdlMik7CisgICAgZW1wdHlfbWVzc2FnZS5NZXJnZUZyb20oZW1wdHlfbWVzc2FnZTIpOworCisgICAgZGF0YSA9IGVtcHR5X21lc3NhZ2UuU2VyaWFsaXplQXNTdHJpbmcoKTsKKyAgICBtZXNzYWdlMi5QYXJzZUZyb21TdHJpbmcoZGF0YSk7CisgICAgLy8gV2UgZG8gbm90IGNvbXBhcmUgdGhlIHNlcmlhbGl6ZWQgb3V0cHV0IG9mIGEgbm9ybWFsIG1lc3NhZ2UgYW5kIGEgbGl0ZQorICAgIC8vIG1lc3NhZ2UgYmVjYXVzZSB0aGUgb3JkZXIgb2YgZmllbGRzIGRvIG5vdCBtYXRjaC4gV2UgY29udmVydCBsaXRlIG1lc3NhZ2UKKyAgICAvLyBiYWNrIGludG8gbm9ybWFsIG1lc3NhZ2UsIHRoZW4gY29tcGFyZS4KKyAgICBHT09HTEVfQ0hFQ0tfRVEobWVzc2FnZS5TZXJpYWxpemVBc1N0cmluZygpLCBtZXNzYWdlMi5TZXJpYWxpemVBc1N0cmluZygpKTsKKyAgfQorCisgIHsKKyAgICAvLyBUZXN0IHVua25vd24gZW51bSB2YWx1ZQorICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlIG1lc3NhZ2U7CisgICAgc3RyaW5nIGJ1ZmZlcjsKKyAgICB7CisgICAgICBnb29nbGU6OnByb3RvYnVmOjppbzo6U3RyaW5nT3V0cHV0U3RyZWFtIG91dHB1dF9zdHJlYW0oJmJ1ZmZlcik7CisgICAgICBnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0gY29kZWRfb3V0cHV0KCZvdXRwdXRfc3RyZWFtKTsKKyAgICAgIGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVUYWcoCisgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlc0xpdGU6OmtPcHRpb25hbE5lc3RlZEVudW1GaWVsZE51bWJlciwKKyAgICAgICAgICBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX1ZBUklOVCwgJmNvZGVkX291dHB1dCk7CisgICAgICBjb2RlZF9vdXRwdXQuV3JpdGVWYXJpbnQzMigxMCk7CisgICAgICBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlVGFnKAorICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlOjprUmVwZWF0ZWROZXN0ZWRFbnVtRmllbGROdW1iZXIsCisgICAgICAgICAgZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9WQVJJTlQsICZjb2RlZF9vdXRwdXQpOworICAgICAgY29kZWRfb3V0cHV0LldyaXRlVmFyaW50MzIoMjApOworICAgIH0KKyAgICBtZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhidWZmZXIpOworICAgIGRhdGEgPSBtZXNzYWdlLlNlcmlhbGl6ZUFzU3RyaW5nKCk7CisgICAgR09PR0xFX0NIRUNLX0VRKGRhdGEsIGJ1ZmZlcik7CisgIH0KKworICB7CisgICAgLy8gVGVzdCBDbGVhciB3aXRoIHVua25vd24gZmllbGRzCisgICAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RFbXB0eU1lc3NhZ2VMaXRlIGVtcHR5X21lc3NhZ2U7CisgICAgU2V0QWxsVHlwZXNJbkVtcHR5TWVzc2FnZVVua25vd25GaWVsZHMoJmVtcHR5X21lc3NhZ2UpOworICAgIGVtcHR5X21lc3NhZ2UuQ2xlYXIoKTsKKyAgICBHT09HTEVfQ0hFQ0tfRVEoMCwgZW1wdHlfbWVzc2FnZS51bmtub3duX2ZpZWxkcygpLnNpemUoKSk7CisgIH0KKworICAvLyBUZXN0cyBmb3IgbWFwIGxpdGUgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKyAgeworICAgIC8vIEFjY2Vzc29ycworICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0TWFwTGl0ZSBtZXNzYWdlOworCisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6TWFwTGl0ZVRlc3RVdGlsOjpTZXRNYXBGaWVsZHMoJm1lc3NhZ2UpOworICAgIGdvb2dsZTo6cHJvdG9idWY6Ok1hcExpdGVUZXN0VXRpbDo6RXhwZWN0TWFwRmllbGRzU2V0KG1lc3NhZ2UpOworCisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6TWFwTGl0ZVRlc3RVdGlsOjpNb2RpZnlNYXBGaWVsZHMoJm1lc3NhZ2UpOworICAgIGdvb2dsZTo6cHJvdG9idWY6Ok1hcExpdGVUZXN0VXRpbDo6RXhwZWN0TWFwRmllbGRzTW9kaWZpZWQobWVzc2FnZSk7CisgIH0KKworICB7CisgICAgLy8gU2V0TWFwRmllbGRzSW5pdGlhbGl6ZWQKKyAgICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdE1hcExpdGUgbWVzc2FnZTsKKworICAgIGdvb2dsZTo6cHJvdG9idWY6Ok1hcExpdGVUZXN0VXRpbDo6U2V0TWFwRmllbGRzSW5pdGlhbGl6ZWQoJm1lc3NhZ2UpOworICAgIGdvb2dsZTo6cHJvdG9idWY6Ok1hcExpdGVUZXN0VXRpbDo6RXhwZWN0TWFwRmllbGRzU2V0SW5pdGlhbGl6ZWQobWVzc2FnZSk7CisgIH0KKworICB7CisgICAgLy8gQ2xlYXIKKyAgICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdE1hcExpdGUgbWVzc2FnZTsKKworICAgIGdvb2dsZTo6cHJvdG9idWY6Ok1hcExpdGVUZXN0VXRpbDo6U2V0TWFwRmllbGRzKCZtZXNzYWdlKTsKKyAgICBtZXNzYWdlLkNsZWFyKCk7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6TWFwTGl0ZVRlc3RVdGlsOjpFeHBlY3RDbGVhcihtZXNzYWdlKTsKKyAgfQorCisgIHsKKyAgICAvLyBDbGVhck1lc3NhZ2VNYXAKKyAgICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdE1lc3NhZ2VNYXBMaXRlIG1lc3NhZ2U7CisKKyAgICAvLyBDcmVhdGVzIGEgVGVzdEFsbFR5cGVzIHdpdGggZGVmYXVsdCB2YWx1ZQorICAgIGdvb2dsZTo6cHJvdG9idWY6OlRlc3RVdGlsTGl0ZTo6RXhwZWN0Q2xlYXIoCisgICAgICAgICgqbWVzc2FnZS5tdXRhYmxlX21hcF9pbnQzMl9tZXNzYWdlKCkpWzBdKTsKKyAgfQorCisgIHsKKyAgICAvLyBDb3B5RnJvbQorICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0TWFwTGl0ZSBtZXNzYWdlMSwgbWVzc2FnZTI7CisKKyAgICBnb29nbGU6OnByb3RvYnVmOjpNYXBMaXRlVGVzdFV0aWw6OlNldE1hcEZpZWxkcygmbWVzc2FnZTEpOworICAgIG1lc3NhZ2UyLkNvcHlGcm9tKG1lc3NhZ2UxKTsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpNYXBMaXRlVGVzdFV0aWw6OkV4cGVjdE1hcEZpZWxkc1NldChtZXNzYWdlMik7CisKKyAgICAvLyBDb3B5aW5nIGZyb20gc2VsZiBzaG91bGQgYmUgYSBuby1vcC4KKyAgICBtZXNzYWdlMi5Db3B5RnJvbShtZXNzYWdlMik7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6TWFwTGl0ZVRlc3RVdGlsOjpFeHBlY3RNYXBGaWVsZHNTZXQobWVzc2FnZTIpOworICB9CisKKyAgeworICAgIC8vIENvcHlGcm9tTWVzc2FnZU1hcAorICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0TWVzc2FnZU1hcExpdGUgbWVzc2FnZTEsIG1lc3NhZ2UyOworCisgICAgKCptZXNzYWdlMS5tdXRhYmxlX21hcF9pbnQzMl9tZXNzYWdlKCkpWzBdLmFkZF9yZXBlYXRlZF9pbnQzMigxMDApOworICAgICgqbWVzc2FnZTIubXV0YWJsZV9tYXBfaW50MzJfbWVzc2FnZSgpKVswXS5hZGRfcmVwZWF0ZWRfaW50MzIoMTAxKTsKKworICAgIG1lc3NhZ2UxLkNvcHlGcm9tKG1lc3NhZ2UyKTsKKworICAgIC8vIENoZWNrcyByZXBlYXRlZCBmaWVsZCBpcyBvdmVyd3JpdHRlbi4KKyAgICBFWFBFQ1RfRVEoMSwgbWVzc2FnZTEubWFwX2ludDMyX21lc3NhZ2UoKS5hdCgwKS5yZXBlYXRlZF9pbnQzMl9zaXplKCkpOworICAgIEVYUEVDVF9FUSgxMDEsIG1lc3NhZ2UxLm1hcF9pbnQzMl9tZXNzYWdlKCkuYXQoMCkucmVwZWF0ZWRfaW50MzIoMCkpOworICB9CisKKyAgeworICAgIC8vIFN3YXBXaXRoRW1wdHkKKyAgICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdE1hcExpdGUgbWVzc2FnZTEsIG1lc3NhZ2UyOworCisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6TWFwTGl0ZVRlc3RVdGlsOjpTZXRNYXBGaWVsZHMoJm1lc3NhZ2UxKTsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpNYXBMaXRlVGVzdFV0aWw6OkV4cGVjdE1hcEZpZWxkc1NldChtZXNzYWdlMSk7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6TWFwTGl0ZVRlc3RVdGlsOjpFeHBlY3RDbGVhcihtZXNzYWdlMik7CisKKyAgICBtZXNzYWdlMS5Td2FwKCZtZXNzYWdlMik7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6TWFwTGl0ZVRlc3RVdGlsOjpFeHBlY3RNYXBGaWVsZHNTZXQobWVzc2FnZTIpOworICAgIGdvb2dsZTo6cHJvdG9idWY6Ok1hcExpdGVUZXN0VXRpbDo6RXhwZWN0Q2xlYXIobWVzc2FnZTEpOworICB9CisKKyAgeworICAgIC8vIFN3YXBXaXRoU2VsZgorICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0TWFwTGl0ZSBtZXNzYWdlOworCisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6TWFwTGl0ZVRlc3RVdGlsOjpTZXRNYXBGaWVsZHMoJm1lc3NhZ2UpOworICAgIGdvb2dsZTo6cHJvdG9idWY6Ok1hcExpdGVUZXN0VXRpbDo6RXhwZWN0TWFwRmllbGRzU2V0KG1lc3NhZ2UpOworCisgICAgbWVzc2FnZS5Td2FwKCZtZXNzYWdlKTsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpNYXBMaXRlVGVzdFV0aWw6OkV4cGVjdE1hcEZpZWxkc1NldChtZXNzYWdlKTsKKyAgfQorCisgIHsKKyAgICAvLyBTd2FwV2l0aE90aGVyCisgICAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RNYXBMaXRlIG1lc3NhZ2UxLCBtZXNzYWdlMjsKKworICAgIGdvb2dsZTo6cHJvdG9idWY6Ok1hcExpdGVUZXN0VXRpbDo6U2V0TWFwRmllbGRzKCZtZXNzYWdlMSk7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6TWFwTGl0ZVRlc3RVdGlsOjpTZXRNYXBGaWVsZHMoJm1lc3NhZ2UyKTsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpNYXBMaXRlVGVzdFV0aWw6Ok1vZGlmeU1hcEZpZWxkcygmbWVzc2FnZTIpOworCisgICAgbWVzc2FnZTEuU3dhcCgmbWVzc2FnZTIpOworICAgIGdvb2dsZTo6cHJvdG9idWY6Ok1hcExpdGVUZXN0VXRpbDo6RXhwZWN0TWFwRmllbGRzTW9kaWZpZWQobWVzc2FnZTEpOworICAgIGdvb2dsZTo6cHJvdG9idWY6Ok1hcExpdGVUZXN0VXRpbDo6RXhwZWN0TWFwRmllbGRzU2V0KG1lc3NhZ2UyKTsKKyAgfQorCisgIHsKKyAgICAvLyBDb3B5Q29uc3RydWN0b3IKKyAgICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdE1hcExpdGUgbWVzc2FnZTE7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6TWFwTGl0ZVRlc3RVdGlsOjpTZXRNYXBGaWVsZHMoJm1lc3NhZ2UxKTsKKworICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0TWFwTGl0ZSBtZXNzYWdlMihtZXNzYWdlMSk7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6TWFwTGl0ZVRlc3RVdGlsOjpFeHBlY3RNYXBGaWVsZHNTZXQobWVzc2FnZTIpOworICB9CisKKyAgeworICAgIC8vIENvcHlBc3NpZ25tZW50T3BlcmF0b3IKKyAgICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdE1hcExpdGUgbWVzc2FnZTE7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6TWFwTGl0ZVRlc3RVdGlsOjpTZXRNYXBGaWVsZHMoJm1lc3NhZ2UxKTsKKworICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0TWFwTGl0ZSBtZXNzYWdlMjsKKyAgICBtZXNzYWdlMiA9IG1lc3NhZ2UxOworICAgIGdvb2dsZTo6cHJvdG9idWY6Ok1hcExpdGVUZXN0VXRpbDo6RXhwZWN0TWFwRmllbGRzU2V0KG1lc3NhZ2UyKTsKKworICAgIC8vIE1ha2Ugc3VyZSB0aGF0IHNlbGYtYXNzaWdubWVudCBkb2VzIHNvbWV0aGluZyBzYW5lLgorICAgIG1lc3NhZ2UyLm9wZXJhdG9yPShtZXNzYWdlMik7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6TWFwTGl0ZVRlc3RVdGlsOjpFeHBlY3RNYXBGaWVsZHNTZXQobWVzc2FnZTIpOworICB9CisKKyAgeworICAgIC8vIE5vbkVtcHR5TWVyZ2VGcm9tCisgICAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RNYXBMaXRlIG1lc3NhZ2UxLCBtZXNzYWdlMjsKKworICAgIGdvb2dsZTo6cHJvdG9idWY6Ok1hcExpdGVUZXN0VXRpbDo6U2V0TWFwRmllbGRzKCZtZXNzYWdlMSk7CisKKyAgICAvLyBUaGlzIGZpZWxkIHdpbGwgdGVzdCBtZXJnaW5nIGludG8gYW4gZW1wdHkgc3BvdC4KKyAgICAoKm1lc3NhZ2UyLm11dGFibGVfbWFwX2ludDMyX2ludDMyKCkpWzFdID0gMTsKKyAgICBtZXNzYWdlMS5tdXRhYmxlX21hcF9pbnQzMl9pbnQzMigpLT5lcmFzZSgxKTsKKworICAgIC8vIFRoaXMgdGVzdHMgb3ZlcndyaXRpbmcuCisgICAgKCptZXNzYWdlMi5tdXRhYmxlX21hcF9pbnQzMl9kb3VibGUoKSlbMV0gPSAxOworICAgICgqbWVzc2FnZTEubXV0YWJsZV9tYXBfaW50MzJfZG91YmxlKCkpWzFdID0gMjsKKworICAgIG1lc3NhZ2UxLk1lcmdlRnJvbShtZXNzYWdlMik7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6TWFwTGl0ZVRlc3RVdGlsOjpFeHBlY3RNYXBGaWVsZHNTZXQobWVzc2FnZTEpOworICB9CisKKyAgeworICAgIC8vIE1lcmdlRnJvbU1lc3NhZ2VNYXAKKyAgICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdE1lc3NhZ2VNYXBMaXRlIG1lc3NhZ2UxLCBtZXNzYWdlMjsKKworICAgICgqbWVzc2FnZTEubXV0YWJsZV9tYXBfaW50MzJfbWVzc2FnZSgpKVswXS5hZGRfcmVwZWF0ZWRfaW50MzIoMTAwKTsKKyAgICAoKm1lc3NhZ2UyLm11dGFibGVfbWFwX2ludDMyX21lc3NhZ2UoKSlbMF0uYWRkX3JlcGVhdGVkX2ludDMyKDEwMSk7CisKKyAgICBtZXNzYWdlMS5NZXJnZUZyb20obWVzc2FnZTIpOworCisgICAgLy8gQ2hlY2tzIHJlcGVhdGVkIGZpZWxkIGlzIG92ZXJ3cml0dGVuLgorICAgIEVYUEVDVF9FUSgxLCBtZXNzYWdlMS5tYXBfaW50MzJfbWVzc2FnZSgpLmF0KDApLnJlcGVhdGVkX2ludDMyX3NpemUoKSk7CisgICAgRVhQRUNUX0VRKDEwMSwgbWVzc2FnZTEubWFwX2ludDMyX21lc3NhZ2UoKS5hdCgwKS5yZXBlYXRlZF9pbnQzMigwKSk7CisgIH0KKworICB7CisgICAgLy8gVGVzdCB0aGUgZ2VuZXJhdGVkIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoKQorICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0TWFwTGl0ZSBtZXNzYWdlMSwgbWVzc2FnZTI7CisgICAgc3RyaW5nIGRhdGE7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6TWFwTGl0ZVRlc3RVdGlsOjpTZXRNYXBGaWVsZHMoJm1lc3NhZ2UxKTsKKyAgICBpbnQgc2l6ZSA9IG1lc3NhZ2UxLkJ5dGVTaXplKCk7CisgICAgZGF0YS5yZXNpemUoc2l6ZSk7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogc3RhcnQgPSByZWludGVycHJldF9jYXN0PCA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4Kj4oOjpnb29nbGU6OnByb3RvYnVmOjpzdHJpbmdfYXNfYXJyYXkoJmRhdGEpKTsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBlbmQgPSBtZXNzYWdlMS5TZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KHN0YXJ0KTsKKyAgICBFWFBFQ1RfRVEoc2l6ZSwgZW5kIC0gc3RhcnQpOworICAgIEVYUEVDVF9UUlVFKG1lc3NhZ2UyLlBhcnNlRnJvbVN0cmluZyhkYXRhKSk7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6TWFwTGl0ZVRlc3RVdGlsOjpFeHBlY3RNYXBGaWVsZHNTZXQobWVzc2FnZTIpOworICB9CisKKyAgeworICAgIC8vIFRlc3QgdGhlIGdlbmVyYXRlZCBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoKQorICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0TWFwTGl0ZSBtZXNzYWdlMSwgbWVzc2FnZTI7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6TWFwTGl0ZVRlc3RVdGlsOjpTZXRNYXBGaWVsZHMoJm1lc3NhZ2UxKTsKKyAgICBpbnQgc2l6ZSA9IG1lc3NhZ2UxLkJ5dGVTaXplKCk7CisgICAgc3RyaW5nIGRhdGE7CisgICAgZGF0YS5yZXNpemUoc2l6ZSk7CisgICAgeworICAgICAgLy8gQWxsb3cgdGhlIG91dHB1dCBzdHJlYW0gdG8gYnVmZmVyIG9ubHkgb25lIGJ5dGUgYXQgYSB0aW1lLgorICAgICAgZ29vZ2xlOjpwcm90b2J1Zjo6aW86OkFycmF5T3V0cHV0U3RyZWFtIGFycmF5X3N0cmVhbSgKKyAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OnN0cmluZ19hc19hcnJheSgmZGF0YSksIHNpemUsIDEpOworICAgICAgZ29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dF9zdHJlYW0oJmFycmF5X3N0cmVhbSk7CisgICAgICBtZXNzYWdlMS5TZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoJm91dHB1dF9zdHJlYW0pOworICAgICAgRVhQRUNUX0ZBTFNFKG91dHB1dF9zdHJlYW0uSGFkRXJyb3IoKSk7CisgICAgICBFWFBFQ1RfRVEoc2l6ZSwgb3V0cHV0X3N0cmVhbS5CeXRlQ291bnQoKSk7CisgICAgfQorICAgIEVYUEVDVF9UUlVFKG1lc3NhZ2UyLlBhcnNlRnJvbVN0cmluZyhkYXRhKSk7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6TWFwTGl0ZVRlc3RVdGlsOjpFeHBlY3RNYXBGaWVsZHNTZXQobWVzc2FnZTIpOworICB9CisKKworICB7CisgICAgLy8gUHJvdG8yVW5rbm93bkVudW0KKyAgICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEVudW1NYXBQbHVzRXh0cmFMaXRlIGZyb207CisgICAgKCpmcm9tLm11dGFibGVfa25vd25fbWFwX2ZpZWxkKCkpWzBdID0KKyAgICAgICAgcHJvdG9idWZfdW5pdHRlc3Q6OkVfUFJPVE8yX01BUF9FTlVNX0ZPT19MSVRFOworICAgICgqZnJvbS5tdXRhYmxlX3Vua25vd25fbWFwX2ZpZWxkKCkpWzBdID0KKyAgICAgICAgcHJvdG9idWZfdW5pdHRlc3Q6OkVfUFJPVE8yX01BUF9FTlVNX0VYVFJBX0xJVEU7CisgICAgc3RyaW5nIGRhdGE7CisgICAgZnJvbS5TZXJpYWxpemVUb1N0cmluZygmZGF0YSk7CisKKyAgICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEVudW1NYXBMaXRlIHRvOworICAgIEVYUEVDVF9UUlVFKHRvLlBhcnNlRnJvbVN0cmluZyhkYXRhKSk7CisgICAgRVhQRUNUX0VRKDAsIHRvLnVua25vd25fbWFwX2ZpZWxkKCkuc2l6ZSgpKTsKKyAgICBFWFBFQ1RfRkFMU0UodG8ubXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5lbXB0eSgpKTsKKyAgICBFWFBFQ1RfRVEoMSwgdG8ua25vd25fbWFwX2ZpZWxkKCkuc2l6ZSgpKTsKKyAgICBFWFBFQ1RfRVEocHJvdG9idWZfdW5pdHRlc3Q6OlBST1RPMl9NQVBfRU5VTV9GT09fTElURSwKKyAgICAgICAgICAgICAgdG8ua25vd25fbWFwX2ZpZWxkKCkuYXQoMCkpOworCisgICAgZGF0YS5jbGVhcigpOworICAgIGZyb20uQ2xlYXIoKTsKKyAgICB0by5TZXJpYWxpemVUb1N0cmluZygmZGF0YSk7CisgICAgRVhQRUNUX1RSVUUoZnJvbS5QYXJzZUZyb21TdHJpbmcoZGF0YSkpOworICAgIEVYUEVDVF9FUSgxLCBmcm9tLmtub3duX21hcF9maWVsZCgpLnNpemUoKSk7CisgICAgRVhQRUNUX0VRKHByb3RvYnVmX3VuaXR0ZXN0OjpFX1BST1RPMl9NQVBfRU5VTV9GT09fTElURSwKKyAgICAgICAgICAgICAgZnJvbS5rbm93bl9tYXBfZmllbGQoKS5hdCgwKSk7CisgICAgRVhQRUNUX0VRKDEsIGZyb20udW5rbm93bl9tYXBfZmllbGQoKS5zaXplKCkpOworICAgIEVYUEVDVF9FUShwcm90b2J1Zl91bml0dGVzdDo6RV9QUk9UTzJfTUFQX0VOVU1fRVhUUkFfTElURSwKKyAgICAgICAgICAgICAgZnJvbS51bmtub3duX21hcF9maWVsZCgpLmF0KDApKTsKKyAgfQorCisgIHsKKyAgICAvLyBTdGFuZGFyZFdpcmVGb3JtYXQKKyAgICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdE1hcExpdGUgbWVzc2FnZTsKKyAgICBzdHJpbmcgZGF0YSA9ICJceDBBXHgwNFx4MDhceDAxXHgxMFx4MDEiOworCisgICAgRVhQRUNUX1RSVUUobWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoZGF0YSkpOworICAgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLm1hcF9pbnQzMl9pbnQzMigpLnNpemUoKSk7CisgICAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX2ludDMyX2ludDMyKCkuYXQoMSkpOworICB9CisKKyAgeworICAgIC8vIFVub3JkZXJlZFdpcmVGb3JtYXQKKyAgICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdE1hcExpdGUgbWVzc2FnZTsKKworICAgIC8vIHB1dCB2YWx1ZSBiZWZvcmUga2V5IGluIHdpcmUgZm9ybWF0CisgICAgc3RyaW5nIGRhdGEgPSAiXHgwQVx4MDRceDEwXHgwMVx4MDhceDAyIjsKKworICAgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKGRhdGEpKTsKKyAgICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfaW50MzJfaW50MzIoKS5zaXplKCkpOworICAgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLm1hcF9pbnQzMl9pbnQzMigpLmF0KDIpKTsKKyAgfQorCisgIHsKKyAgICAvLyBEdXBsaWNhdGVkS2V5V2lyZUZvcm1hdAorICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0TWFwTGl0ZSBtZXNzYWdlOworCisgICAgLy8gVHdvIGtleSBmaWVsZHMgaW4gd2lyZSBmb3JtYXQKKyAgICBzdHJpbmcgZGF0YSA9ICJceDBBXHgwNlx4MDhceDAxXHgwOFx4MDJceDEwXHgwMSI7CisKKyAgICBFWFBFQ1RfVFJVRShtZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhkYXRhKSk7CisgICAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX2ludDMyX2ludDMyKCkuc2l6ZSgpKTsKKyAgICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfaW50MzJfaW50MzIoKS5hdCgyKSk7CisgIH0KKworICB7CisgICAgLy8gRHVwbGljYXRlZFZhbHVlV2lyZUZvcm1hdAorICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0TWFwTGl0ZSBtZXNzYWdlOworCisgICAgLy8gVHdvIHZhbHVlIGZpZWxkcyBpbiB3aXJlIGZvcm1hdAorICAgIHN0cmluZyBkYXRhID0gIlx4MEFceDA2XHgwOFx4MDFceDEwXHgwMVx4MTBceDAyIjsKKworICAgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKGRhdGEpKTsKKyAgICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfaW50MzJfaW50MzIoKS5zaXplKCkpOworICAgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLm1hcF9pbnQzMl9pbnQzMigpLmF0KDEpKTsKKyAgfQorCisgIHsKKyAgICAvLyBNaXNzZWRLZXlXaXJlRm9ybWF0CisgICAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RNYXBMaXRlIG1lc3NhZ2U7CisKKyAgICAvLyBObyBrZXkgZmllbGQgaW4gd2lyZSBmb3JtYXQKKyAgICBzdHJpbmcgZGF0YSA9ICJceDBBXHgwMlx4MTBceDAxIjsKKworICAgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKGRhdGEpKTsKKyAgICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfaW50MzJfaW50MzIoKS5zaXplKCkpOworICAgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLm1hcF9pbnQzMl9pbnQzMigpLmF0KDApKTsKKyAgfQorCisgIHsKKyAgICAvLyBNaXNzZWRWYWx1ZVdpcmVGb3JtYXQKKyAgICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdE1hcExpdGUgbWVzc2FnZTsKKworICAgIC8vIE5vIHZhbHVlIGZpZWxkIGluIHdpcmUgZm9ybWF0CisgICAgc3RyaW5nIGRhdGEgPSAiXHgwQVx4MDJceDA4XHgwMSI7CisKKyAgICBFWFBFQ1RfVFJVRShtZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhkYXRhKSk7CisgICAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX2ludDMyX2ludDMyKCkuc2l6ZSgpKTsKKyAgICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfaW50MzJfaW50MzIoKS5hdCgxKSk7CisgIH0KKworICB7CisgICAgLy8gVW5rbm93bkZpZWxkV2lyZUZvcm1hdAorICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0TWFwTGl0ZSBtZXNzYWdlOworCisgICAgLy8gVW5rbm93biBmaWVsZCBpbiB3aXJlIGZvcm1hdAorICAgIHN0cmluZyBkYXRhID0gIlx4MEFceDA2XHgwOFx4MDJceDEwXHgwM1x4MThceDAxIjsKKworICAgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKGRhdGEpKTsKKyAgICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfaW50MzJfaW50MzIoKS5zaXplKCkpOworICAgIEVYUEVDVF9FUSgzLCBtZXNzYWdlLm1hcF9pbnQzMl9pbnQzMigpLmF0KDIpKTsKKyAgfQorCisgIHsKKyAgICAvLyBDb3JydXB0ZWRXaXJlRm9ybWF0CisgICAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RNYXBMaXRlIG1lc3NhZ2U7CisKKyAgICAvLyBjb3JydXB0ZWQgZGF0YSBpbiB3aXJlIGZvcm1hdAorICAgIHN0cmluZyBkYXRhID0gIlx4MEFceDA2XHgwOFx4MDJceDExXHgwMyI7CisKKyAgICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoZGF0YSkpOworICB9CisKKyAgeworICAgIC8vIElzSW5pdGlhbGl6ZWQKKyAgICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdFJlcXVpcmVkTWVzc2FnZU1hcExpdGUgbWFwX21lc3NhZ2U7CisKKyAgICAvLyBBZGQgYW4gdW5pbml0aWFsaXplZCBtZXNzYWdlLgorICAgICgqbWFwX21lc3NhZ2UubXV0YWJsZV9tYXBfZmllbGQoKSlbMF07CisgICAgRVhQRUNUX0ZBTFNFKG1hcF9tZXNzYWdlLklzSW5pdGlhbGl6ZWQoKSk7CisKKyAgICAvLyBJbml0aWFsaXplIHVuaW5pdGlhbGl6ZWQgbWVzc2FnZQorICAgICgqbWFwX21lc3NhZ2UubXV0YWJsZV9tYXBfZmllbGQoKSlbMF0uc2V0X2EoMCk7CisgICAgKCptYXBfbWVzc2FnZS5tdXRhYmxlX21hcF9maWVsZCgpKVswXS5zZXRfYigwKTsKKyAgICAoKm1hcF9tZXNzYWdlLm11dGFibGVfbWFwX2ZpZWxkKCkpWzBdLnNldF9jKDApOworICAgIEVYUEVDVF9UUlVFKG1hcF9tZXNzYWdlLklzSW5pdGlhbGl6ZWQoKSk7CisgIH0KKworICBzdGQ6OmNvdXQgPDwgIlBBU1MiIDw8IHN0ZDo6ZW5kbDsKKyAgcmV0dXJuIDA7Cit9CmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcC5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9tYXAuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZmM2MjQyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9tYXAuaApAQCAtMCwwICsxLDg4NCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX01BUF9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX01BUF9IX18KKworI2luY2x1ZGUgPGl0ZXJhdG9yPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9oYXNoLmg+CisjaW5jbHVkZSA8bGltaXRzPiAgLy8gVG8gc3VwcG9ydCBWaXN1YWwgU3R1ZGlvIDIwMDgKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvYXJlbmEuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX2VudW1fdXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tYXBfdHlwZV9oYW5kbGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21lc3NhZ2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIFQ+CitjbGFzcyBNYXA7CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbnVtPiBzdHJ1Y3QgaXNfcHJvdG9fZW51bTsKKworY2xhc3MgTWFwSXRlcmF0b3I7CisKK25hbWVzcGFjZSBpbnRlcm5hbCB7Cit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBULAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga2V5X3dpcmVfdHlwZSwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIHZhbHVlX3dpcmVfdHlwZSwKKyAgICAgICAgICBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlPgorY2xhc3MgTWFwRmllbGRMaXRlOworCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBULAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga2V5X3dpcmVfdHlwZSwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIHZhbHVlX3dpcmVfdHlwZSwKKyAgICAgICAgICBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlPgorY2xhc3MgTWFwRmllbGQ7CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIFQ+CitjbGFzcyBUeXBlRGVmaW5lZE1hcEZpZWxkQmFzZTsKKworY2xhc3MgRHluYW1pY01hcEZpZWxkOworCitjbGFzcyBHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjsKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorCisjZGVmaW5lIFRZUEVfQ0hFQ0soRVhQRUNURURUWVBFLCBNRVRIT0QpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGlmICh0eXBlKCkgIT0gRVhQRUNURURUWVBFKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgR09PR0xFX0xPRyhGQVRBTCkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICA8PCAiUHJvdG9jb2wgQnVmZmVyIG1hcCB1c2FnZSBlcnJvcjpcbiIgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICA8PCBNRVRIT0QgPDwgIiB0eXBlIGRvZXMgbm90IG1hdGNoXG4iICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICA8PCAiICBFeHBlY3RlZCA6ICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICA8PCBGaWVsZERlc2NyaXB0b3I6OkNwcFR5cGVOYW1lKEVYUEVDVEVEVFlQRSkgPDwgIlxuIiAgICAgICAgICAgXAorICAgICAgICA8PCAiICBBY3R1YWwgICA6ICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICA8PCBGaWVsZERlc2NyaXB0b3I6OkNwcFR5cGVOYW1lKHR5cGUoKSk7ICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9CisKKy8vIE1hcEtleSBpcyBhbiB1bmlvbiB0eXBlIGZvciByZXByZXNlbnRpbmcgYW55IHBvc3NpYmxlCisvLyBtYXAga2V5LgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIE1hcEtleSB7CisgcHVibGljOgorICBNYXBLZXkoKSA6IHR5cGVfKDApIHsKKyAgfQorICBNYXBLZXkoY29uc3QgTWFwS2V5JiBvdGhlcikgOiB0eXBlXygwKSB7CisgICAgQ29weUZyb20ob3RoZXIpOworICB9CisKKyAgfk1hcEtleSgpIHsKKyAgICBpZiAodHlwZV8gPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORykgeworICAgICAgZGVsZXRlIHZhbF8uc3RyaW5nX3ZhbHVlXzsKKyAgICB9CisgIH0KKworICBGaWVsZERlc2NyaXB0b3I6OkNwcFR5cGUgdHlwZSgpIGNvbnN0IHsKKyAgICBpZiAodHlwZV8gPT0gMCkgeworICAgICAgR09PR0xFX0xPRyhGQVRBTCkKKyAgICAgICAgICA8PCAiUHJvdG9jb2wgQnVmZmVyIG1hcCB1c2FnZSBlcnJvcjpcbiIKKyAgICAgICAgICA8PCAiTWFwS2V5Ojp0eXBlIE1hcEtleSBpcyBub3QgaW5pdGlhbGl6ZWQuICIKKyAgICAgICAgICA8PCAiQ2FsbCBzZXQgbWV0aG9kcyB0byBpbml0aWFsaXplIE1hcEtleS4iOworICAgIH0KKyAgICByZXR1cm4gKEZpZWxkRGVzY3JpcHRvcjo6Q3BwVHlwZSl0eXBlXzsKKyAgfQorCisgIHZvaWQgU2V0SW50NjRWYWx1ZShpbnQ2NCB2YWx1ZSkgeworICAgIFNldFR5cGUoRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0lOVDY0KTsKKyAgICB2YWxfLmludDY0X3ZhbHVlXyA9IHZhbHVlOworICB9CisgIHZvaWQgU2V0VUludDY0VmFsdWUodWludDY0IHZhbHVlKSB7CisgICAgU2V0VHlwZShGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDY0KTsKKyAgICB2YWxfLnVpbnQ2NF92YWx1ZV8gPSB2YWx1ZTsKKyAgfQorICB2b2lkIFNldEludDMyVmFsdWUoaW50MzIgdmFsdWUpIHsKKyAgICBTZXRUeXBlKEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9JTlQzMik7CisgICAgdmFsXy5pbnQzMl92YWx1ZV8gPSB2YWx1ZTsKKyAgfQorICB2b2lkIFNldFVJbnQzMlZhbHVlKHVpbnQzMiB2YWx1ZSkgeworICAgIFNldFR5cGUoRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1VJTlQzMik7CisgICAgdmFsXy51aW50MzJfdmFsdWVfID0gdmFsdWU7CisgIH0KKyAgdm9pZCBTZXRCb29sVmFsdWUoYm9vbCB2YWx1ZSkgeworICAgIFNldFR5cGUoRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0JPT0wpOworICAgIHZhbF8uYm9vbF92YWx1ZV8gPSB2YWx1ZTsKKyAgfQorICB2b2lkIFNldFN0cmluZ1ZhbHVlKGNvbnN0IHN0cmluZyYgdmFsKSB7CisgICAgU2V0VHlwZShGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HKTsKKyAgICAqdmFsXy5zdHJpbmdfdmFsdWVfID0gdmFsOworICB9CisKKyAgaW50NjQgR2V0SW50NjRWYWx1ZSgpIGNvbnN0IHsKKyAgICBUWVBFX0NIRUNLKEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9JTlQ2NCwKKyAgICAgICAgICAgICAgICJNYXBLZXk6OkdldEludDY0VmFsdWUiKTsKKyAgICByZXR1cm4gdmFsXy5pbnQ2NF92YWx1ZV87CisgIH0KKyAgdWludDY0IEdldFVJbnQ2NFZhbHVlKCkgY29uc3QgeworICAgIFRZUEVfQ0hFQ0soRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1VJTlQ2NCwKKyAgICAgICAgICAgICAgICJNYXBLZXk6OkdldFVJbnQ2NFZhbHVlIik7CisgICAgcmV0dXJuIHZhbF8udWludDY0X3ZhbHVlXzsKKyAgfQorICBpbnQzMiBHZXRJbnQzMlZhbHVlKCkgY29uc3QgeworICAgIFRZUEVfQ0hFQ0soRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0lOVDMyLAorICAgICAgICAgICAgICAgIk1hcEtleTo6R2V0SW50MzJWYWx1ZSIpOworICAgIHJldHVybiB2YWxfLmludDMyX3ZhbHVlXzsKKyAgfQorICB1aW50MzIgR2V0VUludDMyVmFsdWUoKSBjb25zdCB7CisgICAgVFlQRV9DSEVDSyhGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDMyLAorICAgICAgICAgICAgICAgIk1hcEtleTo6R2V0VUludDMyVmFsdWUiKTsKKyAgICByZXR1cm4gdmFsXy51aW50MzJfdmFsdWVfOworICB9CisgIGJvb2wgR2V0Qm9vbFZhbHVlKCkgY29uc3QgeworICAgIFRZUEVfQ0hFQ0soRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0JPT0wsCisgICAgICAgICAgICAgICAiTWFwS2V5OjpHZXRCb29sVmFsdWUiKTsKKyAgICByZXR1cm4gdmFsXy5ib29sX3ZhbHVlXzsKKyAgfQorICBjb25zdCBzdHJpbmcmIEdldFN0cmluZ1ZhbHVlKCkgY29uc3QgeworICAgIFRZUEVfQ0hFQ0soRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORywKKyAgICAgICAgICAgICAgICJNYXBLZXk6OkdldFN0cmluZ1ZhbHVlIik7CisgICAgcmV0dXJuICp2YWxfLnN0cmluZ192YWx1ZV87CisgIH0KKworICBib29sIG9wZXJhdG9yPT0oY29uc3QgTWFwS2V5JiBvdGhlcikgY29uc3QgeworICAgIGlmICh0eXBlXyAhPSBvdGhlci50eXBlXykgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBzd2l0Y2ggKHR5cGUoKSkgeworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HOgorICAgICAgICByZXR1cm4gKnZhbF8uc3RyaW5nX3ZhbHVlXyA9PSAqb3RoZXIudmFsXy5zdHJpbmdfdmFsdWVfOworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UNjQ6CisgICAgICAgIHJldHVybiB2YWxfLmludDY0X3ZhbHVlXyA9PSBvdGhlci52YWxfLmludDY0X3ZhbHVlXzsKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0lOVDMyOgorICAgICAgICByZXR1cm4gdmFsXy5pbnQzMl92YWx1ZV8gPT0gb3RoZXIudmFsXy5pbnQzMl92YWx1ZV87CisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9VSU5UNjQ6CisgICAgICAgIHJldHVybiB2YWxfLnVpbnQ2NF92YWx1ZV8gPT0gb3RoZXIudmFsXy51aW50NjRfdmFsdWVfOworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDMyOgorICAgICAgICByZXR1cm4gdmFsXy51aW50MzJfdmFsdWVfID09IG90aGVyLnZhbF8udWludDMyX3ZhbHVlXzsKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0JPT0w6CisgICAgICAgIHJldHVybiB2YWxfLmJvb2xfdmFsdWVfID09IG90aGVyLnZhbF8uYm9vbF92YWx1ZV87CisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9ET1VCTEU6CisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9GTE9BVDoKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0VOVU06CisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ2FuJ3QgZ2V0IGhlcmUuIjsKKyAgICB9CisgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkNhbid0IGdldCBoZXJlLiI7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgdm9pZCBDb3B5RnJvbShjb25zdCBNYXBLZXkmIG90aGVyKSB7CisgICAgU2V0VHlwZShvdGhlci50eXBlKCkpOworICAgIHN3aXRjaCAodHlwZV8pIHsKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORzoKKyAgICAgICAgKnZhbF8uc3RyaW5nX3ZhbHVlXyA9ICpvdGhlci52YWxfLnN0cmluZ192YWx1ZV87CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UNjQ6CisgICAgICAgIHZhbF8uaW50NjRfdmFsdWVfID0gb3RoZXIudmFsXy5pbnQ2NF92YWx1ZV87CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UMzI6CisgICAgICAgIHZhbF8uaW50MzJfdmFsdWVfID0gb3RoZXIudmFsXy5pbnQzMl92YWx1ZV87CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDY0OgorICAgICAgICB2YWxfLnVpbnQ2NF92YWx1ZV8gPSBvdGhlci52YWxfLnVpbnQ2NF92YWx1ZV87CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDMyOgorICAgICAgICB2YWxfLnVpbnQzMl92YWx1ZV8gPSBvdGhlci52YWxfLnVpbnQzMl92YWx1ZV87CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfQk9PTDoKKyAgICAgICAgdmFsXy5ib29sX3ZhbHVlXyA9IG90aGVyLnZhbF8uYm9vbF92YWx1ZV87CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRE9VQkxFOgorICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRkxPQVQ6CisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9FTlVNOgorICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRToKKyAgICAgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkNhbid0IGdldCBoZXJlLiI7CisgICAgICAgIGJyZWFrOworICAgIH0KKyAgfQorCisgcHJpdmF0ZToKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIEssIHR5cGVuYW1lIFY+CisgIGZyaWVuZCBjbGFzcyBpbnRlcm5hbDo6VHlwZURlZmluZWRNYXBGaWVsZEJhc2U7CisgIGZyaWVuZCBjbGFzcyBNYXBJdGVyYXRvcjsKKyAgZnJpZW5kIGNsYXNzIGludGVybmFsOjpEeW5hbWljTWFwRmllbGQ7CisKKyAgdW5pb24gS2V5VmFsdWUgeworICAgIEtleVZhbHVlKCkge30KKyAgICBzdHJpbmcqIHN0cmluZ192YWx1ZV87CisgICAgaW50NjQgaW50NjRfdmFsdWVfOworICAgIGludDMyIGludDMyX3ZhbHVlXzsKKyAgICB1aW50NjQgdWludDY0X3ZhbHVlXzsKKyAgICB1aW50MzIgdWludDMyX3ZhbHVlXzsKKyAgICBib29sIGJvb2xfdmFsdWVfOworICB9IHZhbF87CisKKyAgdm9pZCBTZXRUeXBlKEZpZWxkRGVzY3JpcHRvcjo6Q3BwVHlwZSB0eXBlKSB7CisgICAgaWYgKHR5cGVfID09IHR5cGUpIHJldHVybjsKKyAgICBpZiAodHlwZV8gPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORykgeworICAgICAgZGVsZXRlIHZhbF8uc3RyaW5nX3ZhbHVlXzsKKyAgICB9CisgICAgdHlwZV8gPSB0eXBlOworICAgIGlmICh0eXBlXyA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HKSB7CisgICAgICB2YWxfLnN0cmluZ192YWx1ZV8gPSBuZXcgc3RyaW5nOworICAgIH0KKyAgfQorCisgIC8vIHR5cGVfIGlzIDAgb3IgYSB2YWxpZCBGaWVsZERlc2NyaXB0b3I6OkNwcFR5cGUuCisgIGludCB0eXBlXzsKK307CisKKy8vIE1hcFZhbHVlUmVmIHBvaW50cyB0byBhIG1hcCB2YWx1ZS4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBNYXBWYWx1ZVJlZiB7CisgcHVibGljOgorICBNYXBWYWx1ZVJlZigpIDogZGF0YV8oTlVMTCksIHR5cGVfKDApIHt9CisKKyAgdm9pZCBTZXRJbnQ2NFZhbHVlKGludDY0IHZhbHVlKSB7CisgICAgVFlQRV9DSEVDSyhGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UNjQsCisgICAgICAgICAgICAgICAiTWFwVmFsdWVSZWY6OlNldEludDY0VmFsdWUiKTsKKyAgICAqcmVpbnRlcnByZXRfY2FzdDxpbnQ2NCo+KGRhdGFfKSA9IHZhbHVlOworICB9CisgIHZvaWQgU2V0VUludDY0VmFsdWUodWludDY0IHZhbHVlKSB7CisgICAgVFlQRV9DSEVDSyhGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDY0LAorICAgICAgICAgICAgICAgIk1hcFZhbHVlUmVmOjpTZXRVSW50NjRWYWx1ZSIpOworICAgICpyZWludGVycHJldF9jYXN0PHVpbnQ2NCo+KGRhdGFfKSA9IHZhbHVlOworICB9CisgIHZvaWQgU2V0SW50MzJWYWx1ZShpbnQzMiB2YWx1ZSkgeworICAgIFRZUEVfQ0hFQ0soRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0lOVDMyLAorICAgICAgICAgICAgICAgIk1hcFZhbHVlUmVmOjpTZXRJbnQzMlZhbHVlIik7CisgICAgKnJlaW50ZXJwcmV0X2Nhc3Q8aW50MzIqPihkYXRhXykgPSB2YWx1ZTsKKyAgfQorICB2b2lkIFNldFVJbnQzMlZhbHVlKHVpbnQzMiB2YWx1ZSkgeworICAgIFRZUEVfQ0hFQ0soRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1VJTlQzMiwKKyAgICAgICAgICAgICAgICJNYXBWYWx1ZVJlZjo6U2V0VUludDMyVmFsdWUiKTsKKyAgICAqcmVpbnRlcnByZXRfY2FzdDx1aW50MzIqPihkYXRhXykgPSB2YWx1ZTsKKyAgfQorICB2b2lkIFNldEJvb2xWYWx1ZShib29sIHZhbHVlKSB7CisgICAgVFlQRV9DSEVDSyhGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfQk9PTCwKKyAgICAgICAgICAgICAgICJNYXBWYWx1ZVJlZjo6U2V0Qm9vbFZhbHVlIik7CisgICAgKnJlaW50ZXJwcmV0X2Nhc3Q8Ym9vbCo+KGRhdGFfKSA9IHZhbHVlOworICB9CisgIC8vIFRPRE8oamllbHVvKSAtIENoZWNrcyB0aGF0IGVudW0gaXMgbWVtYmVyLgorICB2b2lkIFNldEVudW1WYWx1ZShpbnQgdmFsdWUpIHsKKyAgICBUWVBFX0NIRUNLKEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9FTlVNLAorICAgICAgICAgICAgICAgIk1hcFZhbHVlUmVmOjpTZXRFbnVtVmFsdWUiKTsKKyAgICAqcmVpbnRlcnByZXRfY2FzdDxpbnQqPihkYXRhXykgPSB2YWx1ZTsKKyAgfQorICB2b2lkIFNldFN0cmluZ1ZhbHVlKGNvbnN0IHN0cmluZyYgdmFsdWUpIHsKKyAgICBUWVBFX0NIRUNLKEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9TVFJJTkcsCisgICAgICAgICAgICAgICAiTWFwVmFsdWVSZWY6OlNldFN0cmluZ1ZhbHVlIik7CisgICAgKnJlaW50ZXJwcmV0X2Nhc3Q8c3RyaW5nKj4oZGF0YV8pID0gdmFsdWU7CisgIH0KKyAgdm9pZCBTZXRGbG9hdFZhbHVlKGZsb2F0IHZhbHVlKSB7CisgICAgVFlQRV9DSEVDSyhGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRkxPQVQsCisgICAgICAgICAgICAgICAiTWFwVmFsdWVSZWY6OlNldEZsb2F0VmFsdWUiKTsKKyAgICAqcmVpbnRlcnByZXRfY2FzdDxmbG9hdCo+KGRhdGFfKSA9IHZhbHVlOworICB9CisgIHZvaWQgU2V0RG91YmxlVmFsdWUoZG91YmxlIHZhbHVlKSB7CisgICAgVFlQRV9DSEVDSyhGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRE9VQkxFLAorICAgICAgICAgICAgICAgIk1hcFZhbHVlUmVmOjpTZXREb3VibGVWYWx1ZSIpOworICAgICpyZWludGVycHJldF9jYXN0PGRvdWJsZSo+KGRhdGFfKSA9IHZhbHVlOworICB9CisKKyAgaW50NjQgR2V0SW50NjRWYWx1ZSgpIGNvbnN0IHsKKyAgICBUWVBFX0NIRUNLKEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9JTlQ2NCwKKyAgICAgICAgICAgICAgICJNYXBWYWx1ZVJlZjo6R2V0SW50NjRWYWx1ZSIpOworICAgIHJldHVybiAqcmVpbnRlcnByZXRfY2FzdDxpbnQ2NCo+KGRhdGFfKTsKKyAgfQorICB1aW50NjQgR2V0VUludDY0VmFsdWUoKSBjb25zdCB7CisgICAgVFlQRV9DSEVDSyhGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDY0LAorICAgICAgICAgICAgICAgIk1hcFZhbHVlUmVmOjpHZXRVSW50NjRWYWx1ZSIpOworICAgIHJldHVybiAqcmVpbnRlcnByZXRfY2FzdDx1aW50NjQqPihkYXRhXyk7CisgIH0KKyAgaW50MzIgR2V0SW50MzJWYWx1ZSgpIGNvbnN0IHsKKyAgICBUWVBFX0NIRUNLKEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9JTlQzMiwKKyAgICAgICAgICAgICAgICJNYXBWYWx1ZVJlZjo6R2V0SW50MzJWYWx1ZSIpOworICAgIHJldHVybiAqcmVpbnRlcnByZXRfY2FzdDxpbnQzMio+KGRhdGFfKTsKKyAgfQorICB1aW50MzIgR2V0VUludDMyVmFsdWUoKSBjb25zdCB7CisgICAgVFlQRV9DSEVDSyhGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDMyLAorICAgICAgICAgICAgICAgIk1hcFZhbHVlUmVmOjpHZXRVSW50MzJWYWx1ZSIpOworICAgIHJldHVybiAqcmVpbnRlcnByZXRfY2FzdDx1aW50MzIqPihkYXRhXyk7CisgIH0KKyAgYm9vbCBHZXRCb29sVmFsdWUoKSBjb25zdCB7CisgICAgVFlQRV9DSEVDSyhGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfQk9PTCwKKyAgICAgICAgICAgICAgICJNYXBWYWx1ZVJlZjo6R2V0Qm9vbFZhbHVlIik7CisgICAgcmV0dXJuICpyZWludGVycHJldF9jYXN0PGJvb2wqPihkYXRhXyk7CisgIH0KKyAgaW50IEdldEVudW1WYWx1ZSgpIGNvbnN0IHsKKyAgICBUWVBFX0NIRUNLKEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9FTlVNLAorICAgICAgICAgICAgICAgIk1hcFZhbHVlUmVmOjpHZXRFbnVtVmFsdWUiKTsKKyAgICByZXR1cm4gKnJlaW50ZXJwcmV0X2Nhc3Q8aW50Kj4oZGF0YV8pOworICB9CisgIGNvbnN0IHN0cmluZyYgR2V0U3RyaW5nVmFsdWUoKSBjb25zdCB7CisgICAgVFlQRV9DSEVDSyhGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HLAorICAgICAgICAgICAgICAgIk1hcFZhbHVlUmVmOjpHZXRTdHJpbmdWYWx1ZSIpOworICAgIHJldHVybiAqcmVpbnRlcnByZXRfY2FzdDxzdHJpbmcqPihkYXRhXyk7CisgIH0KKyAgZmxvYXQgR2V0RmxvYXRWYWx1ZSgpIGNvbnN0IHsKKyAgICBUWVBFX0NIRUNLKEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9GTE9BVCwKKyAgICAgICAgICAgICAgICJNYXBWYWx1ZVJlZjo6R2V0RmxvYXRWYWx1ZSIpOworICAgIHJldHVybiAqcmVpbnRlcnByZXRfY2FzdDxmbG9hdCo+KGRhdGFfKTsKKyAgfQorICBkb3VibGUgR2V0RG91YmxlVmFsdWUoKSBjb25zdCB7CisgICAgVFlQRV9DSEVDSyhGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRE9VQkxFLAorICAgICAgICAgICAgICAgIk1hcFZhbHVlUmVmOjpHZXREb3VibGVWYWx1ZSIpOworICAgIHJldHVybiAqcmVpbnRlcnByZXRfY2FzdDxkb3VibGUqPihkYXRhXyk7CisgIH0KKworICBjb25zdCBNZXNzYWdlJiBHZXRNZXNzYWdlVmFsdWUoKSBjb25zdCB7CisgICAgVFlQRV9DSEVDSyhGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSwKKyAgICAgICAgICAgICAgICJNYXBWYWx1ZVJlZjo6R2V0TWVzc2FnZVZhbHVlIik7CisgICAgcmV0dXJuICpyZWludGVycHJldF9jYXN0PE1lc3NhZ2UqPihkYXRhXyk7CisgIH0KKworICBNZXNzYWdlKiBNdXRhYmxlTWVzc2FnZVZhbHVlKCkgeworICAgIFRZUEVfQ0hFQ0soRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UsCisgICAgICAgICAgICAgICAiTWFwVmFsdWVSZWY6Ok11dGFibGVNZXNzYWdlVmFsdWUiKTsKKyAgICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxNZXNzYWdlKj4oZGF0YV8pOworICB9CisKKyBwcml2YXRlOgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgSywgdHlwZW5hbWUgViwKKyAgICAgICAgICAgIGludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtleV93aXJlX3R5cGUsCisgICAgICAgICAgICBpbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSB2YWx1ZV93aXJlX3R5cGUsCisgICAgICAgICAgICBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlPgorICBmcmllbmQgY2xhc3MgaW50ZXJuYWw6Ok1hcEZpZWxkOworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgSywgdHlwZW5hbWUgVj4KKyAgZnJpZW5kIGNsYXNzIGludGVybmFsOjpUeXBlRGVmaW5lZE1hcEZpZWxkQmFzZTsKKyAgZnJpZW5kIGNsYXNzIE1hcEl0ZXJhdG9yOworICBmcmllbmQgY2xhc3MgaW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOworICBmcmllbmQgY2xhc3MgaW50ZXJuYWw6OkR5bmFtaWNNYXBGaWVsZDsKKworICB2b2lkIFNldFR5cGUoRmllbGREZXNjcmlwdG9yOjpDcHBUeXBlIHR5cGUpIHsKKyAgICB0eXBlXyA9IHR5cGU7CisgIH0KKworICBGaWVsZERlc2NyaXB0b3I6OkNwcFR5cGUgdHlwZSgpIGNvbnN0IHsKKyAgICBpZiAodHlwZV8gPT0gMCB8fCBkYXRhXyA9PSBOVUxMKSB7CisgICAgICBHT09HTEVfTE9HKEZBVEFMKQorICAgICAgICAgIDw8ICJQcm90b2NvbCBCdWZmZXIgbWFwIHVzYWdlIGVycm9yOlxuIgorICAgICAgICAgIDw8ICJNYXBWYWx1ZVJlZjo6dHlwZSBNYXBWYWx1ZVJlZiBpcyBub3QgaW5pdGlhbGl6ZWQuIjsKKyAgICB9CisgICAgcmV0dXJuIChGaWVsZERlc2NyaXB0b3I6OkNwcFR5cGUpdHlwZV87CisgIH0KKyAgdm9pZCBTZXRWYWx1ZShjb25zdCB2b2lkKiB2YWwpIHsKKyAgICBkYXRhXyA9IGNvbnN0X2Nhc3Q8dm9pZCo+KHZhbCk7CisgIH0KKyAgdm9pZCBDb3B5RnJvbShjb25zdCBNYXBWYWx1ZVJlZiYgb3RoZXIpIHsKKyAgICB0eXBlXyA9IG90aGVyLnR5cGVfOworICAgIGRhdGFfID0gb3RoZXIuZGF0YV87CisgIH0KKyAgLy8gT25seSB1c2VkIGluIER5bmFtaWNNYXBGaWVsZAorICB2b2lkIERlbGV0ZURhdGEoKSB7CisgICAgc3dpdGNoICh0eXBlXykgeworI2RlZmluZSBIQU5ETEVfVFlQRShDUFBUWVBFLCBUWVBFKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yOjpDUFBUWVBFXyMjQ1BQVFlQRTogeyAgICAgICAgXAorICAgICAgICBkZWxldGUgcmVpbnRlcnByZXRfY2FzdDxUWVBFKj4oZGF0YV8pOyAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgYnJlYWs7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICB9CisgICAgICBIQU5ETEVfVFlQRShJTlQzMiwgaW50MzIpOworICAgICAgSEFORExFX1RZUEUoSU5UNjQsIGludDY0KTsKKyAgICAgIEhBTkRMRV9UWVBFKFVJTlQzMiwgdWludDMyKTsKKyAgICAgIEhBTkRMRV9UWVBFKFVJTlQ2NCwgdWludDY0KTsKKyAgICAgIEhBTkRMRV9UWVBFKERPVUJMRSwgZG91YmxlKTsKKyAgICAgIEhBTkRMRV9UWVBFKEZMT0FULCBmbG9hdCk7CisgICAgICBIQU5ETEVfVFlQRShCT09MLCBib29sKTsKKyAgICAgIEhBTkRMRV9UWVBFKFNUUklORywgc3RyaW5nKTsKKyAgICAgIEhBTkRMRV9UWVBFKEVOVU0sIGludDMyKTsKKyAgICAgIEhBTkRMRV9UWVBFKE1FU1NBR0UsIE1lc3NhZ2UpOworI3VuZGVmIEhBTkRMRV9UWVBFCisgICAgfQorICB9CisgIC8vIGRhdGFfIHBvaW50IHRvIGEgbWFwIHZhbHVlLiBNYXBWYWx1ZVJlZiBkb2VzIG5vdAorICAvLyBvd24gdGhpcyB2YWx1ZS4KKyAgdm9pZCogZGF0YV87CisgIC8vIHR5cGVfIGlzIDAgb3IgYSB2YWxpZCBGaWVsZERlc2NyaXB0b3I6OkNwcFR5cGUuCisgIGludCB0eXBlXzsKK307CisKKyN1bmRlZiBUWVBFX0NIRUNLCisKKy8vIFRoaXMgaXMgdGhlIGNsYXNzIGZvciBnb29nbGU6OnByb3RvYnVmOjpNYXAncyBpbnRlcm5hbCB2YWx1ZV90eXBlLiBJbnN0ZWFkIG9mIHVzaW5nCisvLyBzdGQ6OnBhaXIgYXMgdmFsdWVfdHlwZSwgd2UgdXNlIHRoaXMgY2xhc3Mgd2hpY2ggcHJvdmlkZXMgdXMgbW9yZSBjb250cm9sIG9mCisvLyBpdHMgcHJvY2VzcyBvZiBjb25zdHJ1Y3Rpb24gYW5kIGRlc3RydWN0aW9uLgordGVtcGxhdGUgPHR5cGVuYW1lIEtleSwgdHlwZW5hbWUgVD4KK2NsYXNzIE1hcFBhaXIgeworIHB1YmxpYzoKKyAgdHlwZWRlZiBjb25zdCBLZXkgZmlyc3RfdHlwZTsKKyAgdHlwZWRlZiBUIHNlY29uZF90eXBlOworCisgIE1hcFBhaXIoY29uc3QgS2V5JiBvdGhlcl9maXJzdCwgY29uc3QgVCYgb3RoZXJfc2Vjb25kKQorICAgICAgOiBmaXJzdChvdGhlcl9maXJzdCksIHNlY29uZChvdGhlcl9zZWNvbmQpIHt9CisgIGV4cGxpY2l0IE1hcFBhaXIoY29uc3QgS2V5JiBvdGhlcl9maXJzdCkgOiBmaXJzdChvdGhlcl9maXJzdCksIHNlY29uZCgpIHt9CisgIE1hcFBhaXIoY29uc3QgTWFwUGFpciYgb3RoZXIpCisgICAgICA6IGZpcnN0KG90aGVyLmZpcnN0KSwgc2Vjb25kKG90aGVyLnNlY29uZCkge30KKworICB+TWFwUGFpcigpIHt9CisKKyAgLy8gSW1wbGljaXRseSBjb252ZXJ0aWJsZSB0byBzdGQ6OnBhaXIgb2YgY29tcGF0aWJsZSB0eXBlcy4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFQxLCB0eXBlbmFtZSBUMj4KKyAgb3BlcmF0b3Igc3RkOjpwYWlyPFQxLCBUMj4oKSBjb25zdCB7CisgICAgcmV0dXJuIHN0ZDo6cGFpcjxUMSwgVDI+KGZpcnN0LCBzZWNvbmQpOworICB9CisKKyAgY29uc3QgS2V5IGZpcnN0OworICBUIHNlY29uZDsKKworIHByaXZhdGU6CisgIGZyaWVuZCBjbGFzcyA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hOworICBmcmllbmQgY2xhc3MgTWFwPEtleSwgVD47Cit9OworCisvLyBnb29nbGU6OnByb3RvYnVmOjpNYXAgaXMgYW4gYXNzb2NpYXRpdmUgY29udGFpbmVyIHR5cGUgdXNlZCB0byBzdG9yZSBwcm90b2J1ZiBtYXAKKy8vIGZpZWxkcy4gSXRzIGludGVyZmFjZSBpcyBzaW1pbGFyIHRvIHN0ZDo6dW5vcmRlcmVkX21hcC4gVXNlcnMgc2hvdWxkIHVzZSB0aGlzCisvLyBpbnRlcmZhY2UgZGlyZWN0bHkgdG8gdmlzaXQgb3IgY2hhbmdlIG1hcCBmaWVsZHMuCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBUPgorY2xhc3MgTWFwIHsKKyBwdWJsaWM6CisgIHR5cGVkZWYgS2V5IGtleV90eXBlOworICB0eXBlZGVmIFQgbWFwcGVkX3R5cGU7CisgIHR5cGVkZWYgTWFwUGFpcjxLZXksIFQ+IHZhbHVlX3R5cGU7CisKKyAgdHlwZWRlZiB2YWx1ZV90eXBlKiBwb2ludGVyOworICB0eXBlZGVmIGNvbnN0IHZhbHVlX3R5cGUqIGNvbnN0X3BvaW50ZXI7CisgIHR5cGVkZWYgdmFsdWVfdHlwZSYgcmVmZXJlbmNlOworICB0eXBlZGVmIGNvbnN0IHZhbHVlX3R5cGUmIGNvbnN0X3JlZmVyZW5jZTsKKworICB0eXBlZGVmIHNpemVfdCBzaXplX3R5cGU7CisgIHR5cGVkZWYgaGFzaDxLZXk+IGhhc2hlcjsKKyAgdHlwZWRlZiBlcXVhbF90bzxLZXk+IGtleV9lcXVhbDsKKworICBNYXAoKQorICAgICAgOiBhcmVuYV8oTlVMTCksCisgICAgICAgIGFsbG9jYXRvcl8oYXJlbmFfKSwKKyAgICAgICAgZWxlbWVudHNfKDAsIGhhc2hlcigpLCBrZXlfZXF1YWwoKSwgYWxsb2NhdG9yXyksCisgICAgICAgIGRlZmF1bHRfZW51bV92YWx1ZV8oMCkge30KKyAgZXhwbGljaXQgTWFwKEFyZW5hKiBhcmVuYSkKKyAgICAgIDogYXJlbmFfKGFyZW5hKSwKKyAgICAgICAgYWxsb2NhdG9yXyhhcmVuYV8pLAorICAgICAgICBlbGVtZW50c18oMCwgaGFzaGVyKCksIGtleV9lcXVhbCgpLCBhbGxvY2F0b3JfKSwKKyAgICAgICAgZGVmYXVsdF9lbnVtX3ZhbHVlXygwKSB7CisgICAgYXJlbmFfLT5Pd25EZXN0cnVjdG9yKCZlbGVtZW50c18pOworICB9CisKKyAgTWFwKGNvbnN0IE1hcCYgb3RoZXIpCisgICAgICA6IGFyZW5hXyhOVUxMKSwKKyAgICAgICAgYWxsb2NhdG9yXyhhcmVuYV8pLAorICAgICAgICBlbGVtZW50c18oMCwgaGFzaGVyKCksIGtleV9lcXVhbCgpLCBhbGxvY2F0b3JfKSwKKyAgICAgICAgZGVmYXVsdF9lbnVtX3ZhbHVlXyhvdGhlci5kZWZhdWx0X2VudW1fdmFsdWVfKSB7CisgICAgaW5zZXJ0KG90aGVyLmJlZ2luKCksIG90aGVyLmVuZCgpKTsKKyAgfQorICB0ZW1wbGF0ZSA8Y2xhc3MgSW5wdXRJdD4KKyAgTWFwKGNvbnN0IElucHV0SXQmIGZpcnN0LCBjb25zdCBJbnB1dEl0JiBsYXN0KQorICAgICAgOiBhcmVuYV8oTlVMTCksCisgICAgICAgIGFsbG9jYXRvcl8oYXJlbmFfKSwKKyAgICAgICAgZWxlbWVudHNfKDAsIGhhc2hlcigpLCBrZXlfZXF1YWwoKSwgYWxsb2NhdG9yXyksCisgICAgICAgIGRlZmF1bHRfZW51bV92YWx1ZV8oMCkgeworICAgIGluc2VydChmaXJzdCwgbGFzdCk7CisgIH0KKworICB+TWFwKCkgeyBjbGVhcigpOyB9CisKKyBwcml2YXRlOgorICAvLyByZS1pbXBsZW1lbnQgc3RkOjphbGxvY2F0b3IgdG8gdXNlIGFyZW5hIGFsbG9jYXRvciBmb3IgbWVtb3J5IGFsbG9jYXRpb24uCisgIC8vIFVzZWQgZm9yIGdvb2dsZTo6cHJvdG9idWY6Ok1hcCBpbXBsZW1lbnRhdGlvbi4gVXNlcnMgc2hvdWxkIG5vdCB1c2UgdGhpcyBjbGFzcworICAvLyBkaXJlY3RseS4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFU+CisgIGNsYXNzIE1hcEFsbG9jYXRvciB7CisgICBwdWJsaWM6CisgICAgdHlwZWRlZiBVIHZhbHVlX3R5cGU7CisgICAgdHlwZWRlZiB2YWx1ZV90eXBlKiBwb2ludGVyOworICAgIHR5cGVkZWYgY29uc3QgdmFsdWVfdHlwZSogY29uc3RfcG9pbnRlcjsKKyAgICB0eXBlZGVmIHZhbHVlX3R5cGUmIHJlZmVyZW5jZTsKKyAgICB0eXBlZGVmIGNvbnN0IHZhbHVlX3R5cGUmIGNvbnN0X3JlZmVyZW5jZTsKKyAgICB0eXBlZGVmIHNpemVfdCBzaXplX3R5cGU7CisgICAgdHlwZWRlZiBwdHJkaWZmX3QgZGlmZmVyZW5jZV90eXBlOworCisgICAgTWFwQWxsb2NhdG9yKCkgOiBhcmVuYV8oTlVMTCkge30KKyAgICBleHBsaWNpdCBNYXBBbGxvY2F0b3IoQXJlbmEqIGFyZW5hKSA6IGFyZW5hXyhhcmVuYSkge30KKyAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgWD4KKyAgICBNYXBBbGxvY2F0b3IoY29uc3QgTWFwQWxsb2NhdG9yPFg+JiBhbGxvY2F0b3IpCisgICAgICAgIDogYXJlbmFfKGFsbG9jYXRvci5hcmVuYV8pIHt9CisKKyAgICBwb2ludGVyIGFsbG9jYXRlKHNpemVfdHlwZSBuLCBjb25zdF9wb2ludGVyIGhpbnQgPSAwKSB7CisgICAgICAvLyBJZiBhcmVuYSBpcyBub3QgZ2l2ZW4sIG1hbGxvYyBuZWVkcyB0byBiZSBjYWxsZWQgd2hpY2ggZG9lc24ndAorICAgICAgLy8gY29uc3RydWN0IGVsZW1lbnQgb2JqZWN0LgorICAgICAgaWYgKGFyZW5hXyA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiByZWludGVycHJldF9jYXN0PHBvaW50ZXI+KG1hbGxvYyhuICogc2l6ZW9mKHZhbHVlX3R5cGUpKSk7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxwb2ludGVyPigKKyAgICAgICAgICAgIEFyZW5hOjpDcmVhdGVBcnJheTx1aW50OD4oYXJlbmFfLCBuICogc2l6ZW9mKHZhbHVlX3R5cGUpKSk7CisgICAgICB9CisgICAgfQorCisgICAgdm9pZCBkZWFsbG9jYXRlKHBvaW50ZXIgcCwgc2l6ZV90eXBlIG4pIHsKKyAgICAgIGlmIChhcmVuYV8gPT0gTlVMTCkgeworICAgICAgICBmcmVlKHApOworICAgICAgfQorICAgIH0KKworI2lmIF9fY3BsdXNwbHVzID49IDIwMTEwM0wgJiYgIWRlZmluZWQoR09PR0xFX1BST1RPQlVGX09TX0FQUExFKSAmJiBcCisgICAgIWRlZmluZWQoR09PR0xFX1BST1RPQlVGX09TX05BQ0wpICYmICFkZWZpbmVkKEdPT0dMRV9QUk9UT0JVRl9PU19BTkRST0lEKQorICAgIHRlbXBsYXRlPGNsYXNzIE5vZGVUeXBlLCBjbGFzcy4uLiBBcmdzPgorICAgIHZvaWQgY29uc3RydWN0KE5vZGVUeXBlKiBwLCBBcmdzJiYuLi4gYXJncykgeworICAgICAgbmV3IChzdGF0aWNfY2FzdDx2b2lkKj4ocCkpIE5vZGVUeXBlKHN0ZDo6Zm9yd2FyZDxBcmdzPihhcmdzKS4uLik7CisgICAgfQorCisgICAgdGVtcGxhdGU8Y2xhc3MgTm9kZVR5cGU+CisgICAgdm9pZCBkZXN0cm95KE5vZGVUeXBlKiBwKSB7CisgICAgICBwLT5+Tm9kZVR5cGUoKTsKKyAgICB9CisjZWxzZQorICAgIHZvaWQgY29uc3RydWN0KHBvaW50ZXIgcCwgY29uc3RfcmVmZXJlbmNlIHQpIHsgbmV3IChwKSB2YWx1ZV90eXBlKHQpOyB9CisKKyAgICB2b2lkIGRlc3Ryb3kocG9pbnRlciBwKSB7IHAtPn52YWx1ZV90eXBlKCk7IH0KKyNlbmRpZgorCisgICAgdGVtcGxhdGUgPHR5cGVuYW1lIFg+CisgICAgc3RydWN0IHJlYmluZCB7CisgICAgICB0eXBlZGVmIE1hcEFsbG9jYXRvcjxYPiBvdGhlcjsKKyAgICB9OworCisgICAgdGVtcGxhdGUgPHR5cGVuYW1lIFg+CisgICAgYm9vbCBvcGVyYXRvcj09KGNvbnN0IE1hcEFsbG9jYXRvcjxYPiYgb3RoZXIpIGNvbnN0IHsKKyAgICAgIHJldHVybiBhcmVuYV8gPT0gb3RoZXIuYXJlbmFfOworICAgIH0KKworICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBYPgorICAgIGJvb2wgb3BlcmF0b3IhPShjb25zdCBNYXBBbGxvY2F0b3I8WD4mIG90aGVyKSBjb25zdCB7CisgICAgICByZXR1cm4gYXJlbmFfICE9IG90aGVyLmFyZW5hXzsKKyAgICB9CisKKyAgICAvLyBUbyBzdXBwb3J0IFZpc3VhbCBTdHVkaW8gMjAwOAorICAgIHNpemVfdHlwZSBtYXhfc2l6ZSgpIGNvbnN0IHsKKyAgICAgIHJldHVybiBzdGQ6Om51bWVyaWNfbGltaXRzPHNpemVfdHlwZT46Om1heCgpOworICAgIH0KKworICAgcHJpdmF0ZToKKyAgICB0eXBlZGVmIHZvaWQgRGVzdHJ1Y3RvclNraXBwYWJsZV87CisgICAgQXJlbmEqIGNvbnN0IGFyZW5hXzsKKworICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBYPgorICAgIGZyaWVuZCBjbGFzcyBNYXBBbGxvY2F0b3I7CisgIH07CisKKyAgdHlwZWRlZiBNYXBBbGxvY2F0b3I8c3RkOjpwYWlyPGNvbnN0IEtleSwgTWFwUGFpcjxLZXksIFQ+Kj4gPiBBbGxvY2F0b3I7CisgIHR5cGVkZWYgaGFzaF9tYXA8S2V5LCB2YWx1ZV90eXBlKiwgaGFzaDxLZXk+LCBlcXVhbF90bzxLZXk+LCBBbGxvY2F0b3I+CisgICAgICBJbm5lck1hcDsKKworIHB1YmxpYzoKKyAgLy8gSXRlcmF0b3JzCisgIGNsYXNzIGNvbnN0X2l0ZXJhdG9yCisgICAgICA6IHB1YmxpYyBzdGQ6Oml0ZXJhdG9yPHN0ZDo6Zm9yd2FyZF9pdGVyYXRvcl90YWcsIHZhbHVlX3R5cGUsIHB0cmRpZmZfdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWVfdHlwZSosIGNvbnN0IHZhbHVlX3R5cGUmPiB7CisgICAgdHlwZWRlZiB0eXBlbmFtZSBJbm5lck1hcDo6Y29uc3RfaXRlcmF0b3IgSW5uZXJJdDsKKworICAgcHVibGljOgorICAgIGNvbnN0X2l0ZXJhdG9yKCkge30KKyAgICBleHBsaWNpdCBjb25zdF9pdGVyYXRvcihjb25zdCBJbm5lckl0JiBpdCkgOiBpdF8oaXQpIHt9CisKKyAgICBjb25zdF9yZWZlcmVuY2Ugb3BlcmF0b3IqKCkgY29uc3QgeyByZXR1cm4gKml0Xy0+c2Vjb25kOyB9CisgICAgY29uc3RfcG9pbnRlciBvcGVyYXRvci0+KCkgY29uc3QgeyByZXR1cm4gaXRfLT5zZWNvbmQ7IH0KKworICAgIGNvbnN0X2l0ZXJhdG9yJiBvcGVyYXRvcisrKCkgeworICAgICAgKytpdF87CisgICAgICByZXR1cm4gKnRoaXM7CisgICAgfQorICAgIGNvbnN0X2l0ZXJhdG9yIG9wZXJhdG9yKysoaW50KSB7IHJldHVybiBjb25zdF9pdGVyYXRvcihpdF8rKyk7IH0KKworICAgIGZyaWVuZCBib29sIG9wZXJhdG9yPT0oY29uc3QgY29uc3RfaXRlcmF0b3ImIGEsIGNvbnN0IGNvbnN0X2l0ZXJhdG9yJiBiKSB7CisgICAgICByZXR1cm4gYS5pdF8gPT0gYi5pdF87CisgICAgfQorICAgIGZyaWVuZCBib29sIG9wZXJhdG9yIT0oY29uc3QgY29uc3RfaXRlcmF0b3ImIGEsIGNvbnN0IGNvbnN0X2l0ZXJhdG9yJiBiKSB7CisgICAgICByZXR1cm4gYS5pdF8gIT0gYi5pdF87CisgICAgfQorCisgICBwcml2YXRlOgorICAgIElubmVySXQgaXRfOworICB9OworCisgIGNsYXNzIGl0ZXJhdG9yIDogcHVibGljIHN0ZDo6aXRlcmF0b3I8c3RkOjpmb3J3YXJkX2l0ZXJhdG9yX3RhZywgdmFsdWVfdHlwZT4geworICAgIHR5cGVkZWYgdHlwZW5hbWUgSW5uZXJNYXA6Oml0ZXJhdG9yIElubmVySXQ7CisKKyAgIHB1YmxpYzoKKyAgICBpdGVyYXRvcigpIHt9CisgICAgZXhwbGljaXQgaXRlcmF0b3IoY29uc3QgSW5uZXJJdCYgaXQpIDogaXRfKGl0KSB7fQorCisgICAgcmVmZXJlbmNlIG9wZXJhdG9yKigpIGNvbnN0IHsgcmV0dXJuICppdF8tPnNlY29uZDsgfQorICAgIHBvaW50ZXIgb3BlcmF0b3ItPigpIGNvbnN0IHsgcmV0dXJuIGl0Xy0+c2Vjb25kOyB9CisKKyAgICBpdGVyYXRvciYgb3BlcmF0b3IrKygpIHsKKyAgICAgICsraXRfOworICAgICAgcmV0dXJuICp0aGlzOworICAgIH0KKyAgICBpdGVyYXRvciBvcGVyYXRvcisrKGludCkgeyByZXR1cm4gaXRlcmF0b3IoaXRfKyspOyB9CisKKyAgICAvLyBJbXBsaWNpdGx5IGNvbnZlcnRpYmxlIHRvIGNvbnN0X2l0ZXJhdG9yLgorICAgIG9wZXJhdG9yIGNvbnN0X2l0ZXJhdG9yKCkgY29uc3QgeyByZXR1cm4gY29uc3RfaXRlcmF0b3IoaXRfKTsgfQorCisgICAgZnJpZW5kIGJvb2wgb3BlcmF0b3I9PShjb25zdCBpdGVyYXRvciYgYSwgY29uc3QgaXRlcmF0b3ImIGIpIHsKKyAgICAgIHJldHVybiBhLml0XyA9PSBiLml0XzsKKyAgICB9CisgICAgZnJpZW5kIGJvb2wgb3BlcmF0b3IhPShjb25zdCBpdGVyYXRvciYgYSwgY29uc3QgaXRlcmF0b3ImIGIpIHsKKyAgICAgIHJldHVybiBhLml0XyAhPSBiLml0XzsKKyAgICB9CisKKyAgIHByaXZhdGU6CisgICAgZnJpZW5kIGNsYXNzIE1hcDsKKyAgICBJbm5lckl0IGl0XzsKKyAgfTsKKworICBpdGVyYXRvciBiZWdpbigpIHsgcmV0dXJuIGl0ZXJhdG9yKGVsZW1lbnRzXy5iZWdpbigpKTsgfQorICBpdGVyYXRvciBlbmQoKSB7IHJldHVybiBpdGVyYXRvcihlbGVtZW50c18uZW5kKCkpOyB9CisgIGNvbnN0X2l0ZXJhdG9yIGJlZ2luKCkgY29uc3QgeyByZXR1cm4gY29uc3RfaXRlcmF0b3IoZWxlbWVudHNfLmJlZ2luKCkpOyB9CisgIGNvbnN0X2l0ZXJhdG9yIGVuZCgpIGNvbnN0IHsgcmV0dXJuIGNvbnN0X2l0ZXJhdG9yKGVsZW1lbnRzXy5lbmQoKSk7IH0KKyAgY29uc3RfaXRlcmF0b3IgY2JlZ2luKCkgY29uc3QgeyByZXR1cm4gYmVnaW4oKTsgfQorICBjb25zdF9pdGVyYXRvciBjZW5kKCkgY29uc3QgeyByZXR1cm4gZW5kKCk7IH0KKworICAvLyBDYXBhY2l0eQorICBzaXplX3R5cGUgc2l6ZSgpIGNvbnN0IHsgcmV0dXJuIGVsZW1lbnRzXy5zaXplKCk7IH0KKyAgYm9vbCBlbXB0eSgpIGNvbnN0IHsgcmV0dXJuIGVsZW1lbnRzXy5lbXB0eSgpOyB9CisKKyAgLy8gRWxlbWVudCBhY2Nlc3MKKyAgVCYgb3BlcmF0b3JbXShjb25zdCBrZXlfdHlwZSYga2V5KSB7CisgICAgdmFsdWVfdHlwZSoqIHZhbHVlID0gJmVsZW1lbnRzX1trZXldOworICAgIGlmICgqdmFsdWUgPT0gTlVMTCkgeworICAgICAgKnZhbHVlID0gQ3JlYXRlVmFsdWVUeXBlSW50ZXJuYWwoa2V5KTsKKyAgICAgIGludGVybmFsOjpNYXBWYWx1ZUluaXRpYWxpemVyPGdvb2dsZTo6cHJvdG9idWY6OmlzX3Byb3RvX2VudW08VD46OnZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVD46OkluaXRpYWxpemUoKCp2YWx1ZSktPnNlY29uZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRfZW51bV92YWx1ZV8pOworICAgIH0KKyAgICByZXR1cm4gKCp2YWx1ZSktPnNlY29uZDsKKyAgfQorICBjb25zdCBUJiBhdChjb25zdCBrZXlfdHlwZSYga2V5KSBjb25zdCB7CisgICAgY29uc3RfaXRlcmF0b3IgaXQgPSBmaW5kKGtleSk7CisgICAgR09PR0xFX0NIRUNLKGl0ICE9IGVuZCgpKTsKKyAgICByZXR1cm4gaXQtPnNlY29uZDsKKyAgfQorICBUJiBhdChjb25zdCBrZXlfdHlwZSYga2V5KSB7CisgICAgaXRlcmF0b3IgaXQgPSBmaW5kKGtleSk7CisgICAgR09PR0xFX0NIRUNLKGl0ICE9IGVuZCgpKTsKKyAgICByZXR1cm4gaXQtPnNlY29uZDsKKyAgfQorCisgIC8vIExvb2t1cAorICBzaXplX3R5cGUgY291bnQoY29uc3Qga2V5X3R5cGUmIGtleSkgY29uc3QgeworICAgIHJldHVybiBlbGVtZW50c18uY291bnQoa2V5KTsKKyAgfQorICBjb25zdF9pdGVyYXRvciBmaW5kKGNvbnN0IGtleV90eXBlJiBrZXkpIGNvbnN0IHsKKyAgICByZXR1cm4gY29uc3RfaXRlcmF0b3IoZWxlbWVudHNfLmZpbmQoa2V5KSk7CisgIH0KKyAgaXRlcmF0b3IgZmluZChjb25zdCBrZXlfdHlwZSYga2V5KSB7CisgICAgcmV0dXJuIGl0ZXJhdG9yKGVsZW1lbnRzXy5maW5kKGtleSkpOworICB9CisgIHN0ZDo6cGFpcjxjb25zdF9pdGVyYXRvciwgY29uc3RfaXRlcmF0b3I+IGVxdWFsX3JhbmdlKAorICAgICAgY29uc3Qga2V5X3R5cGUmIGtleSkgY29uc3QgeworICAgIGNvbnN0X2l0ZXJhdG9yIGl0ID0gZmluZChrZXkpOworICAgIGlmIChpdCA9PSBlbmQoKSkgeworICAgICAgcmV0dXJuIHN0ZDo6cGFpcjxjb25zdF9pdGVyYXRvciwgY29uc3RfaXRlcmF0b3I+KGl0LCBpdCk7CisgICAgfSBlbHNlIHsKKyAgICAgIGNvbnN0X2l0ZXJhdG9yIGJlZ2luID0gaXQrKzsKKyAgICAgIHJldHVybiBzdGQ6OnBhaXI8Y29uc3RfaXRlcmF0b3IsIGNvbnN0X2l0ZXJhdG9yPihiZWdpbiwgaXQpOworICAgIH0KKyAgfQorICBzdGQ6OnBhaXI8aXRlcmF0b3IsIGl0ZXJhdG9yPiBlcXVhbF9yYW5nZShjb25zdCBrZXlfdHlwZSYga2V5KSB7CisgICAgaXRlcmF0b3IgaXQgPSBmaW5kKGtleSk7CisgICAgaWYgKGl0ID09IGVuZCgpKSB7CisgICAgICByZXR1cm4gc3RkOjpwYWlyPGl0ZXJhdG9yLCBpdGVyYXRvcj4oaXQsIGl0KTsKKyAgICB9IGVsc2UgeworICAgICAgaXRlcmF0b3IgYmVnaW4gPSBpdCsrOworICAgICAgcmV0dXJuIHN0ZDo6cGFpcjxpdGVyYXRvciwgaXRlcmF0b3I+KGJlZ2luLCBpdCk7CisgICAgfQorICB9CisKKyAgLy8gaW5zZXJ0CisgIHN0ZDo6cGFpcjxpdGVyYXRvciwgYm9vbD4gaW5zZXJ0KGNvbnN0IHZhbHVlX3R5cGUmIHZhbHVlKSB7CisgICAgaXRlcmF0b3IgaXQgPSBmaW5kKHZhbHVlLmZpcnN0KTsKKyAgICBpZiAoaXQgIT0gZW5kKCkpIHsKKyAgICAgIHJldHVybiBzdGQ6OnBhaXI8aXRlcmF0b3IsIGJvb2w+KGl0LCBmYWxzZSk7CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiBzdGQ6OnBhaXI8aXRlcmF0b3IsIGJvb2w+KAorICAgICAgICAgIGl0ZXJhdG9yKGVsZW1lbnRzXy5pbnNlcnQoc3RkOjpwYWlyPEtleSwgdmFsdWVfdHlwZSo+KAorICAgICAgICAgICAgICB2YWx1ZS5maXJzdCwgQ3JlYXRlVmFsdWVUeXBlSW50ZXJuYWwodmFsdWUpKSkuZmlyc3QpLCB0cnVlKTsKKyAgICB9CisgIH0KKyAgdGVtcGxhdGUgPGNsYXNzIElucHV0SXQ+CisgIHZvaWQgaW5zZXJ0KElucHV0SXQgZmlyc3QsIElucHV0SXQgbGFzdCkgeworICAgIGZvciAoSW5wdXRJdCBpdCA9IGZpcnN0OyBpdCAhPSBsYXN0OyArK2l0KSB7CisgICAgICBpdGVyYXRvciBleGlzdF9pdCA9IGZpbmQoaXQtPmZpcnN0KTsKKyAgICAgIGlmIChleGlzdF9pdCA9PSBlbmQoKSkgeworICAgICAgICBvcGVyYXRvcltdKGl0LT5maXJzdCkgPSBpdC0+c2Vjb25kOworICAgICAgfQorICAgIH0KKyAgfQorCisgIC8vIEVyYXNlCisgIHNpemVfdHlwZSBlcmFzZShjb25zdCBrZXlfdHlwZSYga2V5KSB7CisgICAgdHlwZW5hbWUgSW5uZXJNYXA6Oml0ZXJhdG9yIGl0ID0gZWxlbWVudHNfLmZpbmQoa2V5KTsKKyAgICBpZiAoaXQgPT0gZWxlbWVudHNfLmVuZCgpKSB7CisgICAgICByZXR1cm4gMDsKKyAgICB9IGVsc2UgeworICAgICAgaWYgKGFyZW5hXyA9PSBOVUxMKSBkZWxldGUgaXQtPnNlY29uZDsKKyAgICAgIGVsZW1lbnRzXy5lcmFzZShpdCk7CisgICAgICByZXR1cm4gMTsKKyAgICB9CisgIH0KKyAgdm9pZCBlcmFzZShpdGVyYXRvciBwb3MpIHsKKyAgICBpZiAoYXJlbmFfID09IE5VTEwpIGRlbGV0ZSBwb3MuaXRfLT5zZWNvbmQ7CisgICAgZWxlbWVudHNfLmVyYXNlKHBvcy5pdF8pOworICB9CisgIHZvaWQgZXJhc2UoaXRlcmF0b3IgZmlyc3QsIGl0ZXJhdG9yIGxhc3QpIHsKKyAgICBmb3IgKGl0ZXJhdG9yIGl0ID0gZmlyc3Q7IGl0ICE9IGxhc3Q7KSB7CisgICAgICBpZiAoYXJlbmFfID09IE5VTEwpIGRlbGV0ZSBpdC5pdF8tPnNlY29uZDsKKyAgICAgIGVsZW1lbnRzXy5lcmFzZSgoaXQrKykuaXRfKTsKKyAgICB9CisgIH0KKyAgdm9pZCBjbGVhcigpIHsKKyAgICBmb3IgKGl0ZXJhdG9yIGl0ID0gYmVnaW4oKTsgaXQgIT0gZW5kKCk7ICsraXQpIHsKKyAgICAgIGlmIChhcmVuYV8gPT0gTlVMTCkgZGVsZXRlIGl0Lml0Xy0+c2Vjb25kOworICAgIH0KKyAgICBlbGVtZW50c18uY2xlYXIoKTsKKyAgfQorCisgIC8vIEFzc2lnbgorICBNYXAmIG9wZXJhdG9yPShjb25zdCBNYXAmIG90aGVyKSB7CisgICAgaWYgKHRoaXMgIT0gJm90aGVyKSB7CisgICAgICBjbGVhcigpOworICAgICAgaW5zZXJ0KG90aGVyLmJlZ2luKCksIG90aGVyLmVuZCgpKTsKKyAgICB9CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyBwcml2YXRlOgorICAvLyBTZXQgZGVmYXVsdCBlbnVtIHZhbHVlIG9ubHkgZm9yIHByb3RvMiBtYXAgZmllbGQgd2hvc2UgdmFsdWUgaXMgZW51bSB0eXBlLgorICB2b2lkIFNldERlZmF1bHRFbnVtVmFsdWUoaW50IGRlZmF1bHRfZW51bV92YWx1ZSkgeworICAgIGRlZmF1bHRfZW51bV92YWx1ZV8gPSBkZWZhdWx0X2VudW1fdmFsdWU7CisgIH0KKworICB2YWx1ZV90eXBlKiBDcmVhdGVWYWx1ZVR5cGVJbnRlcm5hbChjb25zdCBLZXkmIGtleSkgeworICAgIGlmIChhcmVuYV8gPT0gTlVMTCkgeworICAgICAgcmV0dXJuIG5ldyB2YWx1ZV90eXBlKGtleSk7CisgICAgfSBlbHNlIHsKKyAgICAgIHZhbHVlX3R5cGUqIHZhbHVlID0gcmVpbnRlcnByZXRfY2FzdDx2YWx1ZV90eXBlKj4oCisgICAgICAgICAgQXJlbmE6OkNyZWF0ZUFycmF5PHVpbnQ4PihhcmVuYV8sIHNpemVvZih2YWx1ZV90eXBlKSkpOworICAgICAgQXJlbmE6OkNyZWF0ZUluQXJlbmFTdG9yYWdlKGNvbnN0X2Nhc3Q8S2V5Kj4oJnZhbHVlLT5maXJzdCksIGFyZW5hXyk7CisgICAgICBBcmVuYTo6Q3JlYXRlSW5BcmVuYVN0b3JhZ2UoJnZhbHVlLT5zZWNvbmQsIGFyZW5hXyk7CisgICAgICBjb25zdF9jYXN0PEtleSY+KHZhbHVlLT5maXJzdCkgPSBrZXk7CisgICAgICByZXR1cm4gdmFsdWU7CisgICAgfQorICB9CisKKyAgdmFsdWVfdHlwZSogQ3JlYXRlVmFsdWVUeXBlSW50ZXJuYWwoY29uc3QgdmFsdWVfdHlwZSYgdmFsdWUpIHsKKyAgICBpZiAoYXJlbmFfID09IE5VTEwpIHsKKyAgICAgIHJldHVybiBuZXcgdmFsdWVfdHlwZSh2YWx1ZSk7CisgICAgfSBlbHNlIHsKKyAgICAgIHZhbHVlX3R5cGUqIHAgPSByZWludGVycHJldF9jYXN0PHZhbHVlX3R5cGUqPigKKyAgICAgICAgICBBcmVuYTo6Q3JlYXRlQXJyYXk8dWludDg+KGFyZW5hXywgc2l6ZW9mKHZhbHVlX3R5cGUpKSk7CisgICAgICBBcmVuYTo6Q3JlYXRlSW5BcmVuYVN0b3JhZ2UoY29uc3RfY2FzdDxLZXkqPigmcC0+Zmlyc3QpLCBhcmVuYV8pOworICAgICAgQXJlbmE6OkNyZWF0ZUluQXJlbmFTdG9yYWdlKCZwLT5zZWNvbmQsIGFyZW5hXyk7CisgICAgICBjb25zdF9jYXN0PEtleSY+KHAtPmZpcnN0KSA9IHZhbHVlLmZpcnN0OworICAgICAgcC0+c2Vjb25kID0gdmFsdWUuc2Vjb25kOworICAgICAgcmV0dXJuIHA7CisgICAgfQorICB9CisKKyAgQXJlbmEqIGFyZW5hXzsKKyAgQWxsb2NhdG9yIGFsbG9jYXRvcl87CisgIElubmVyTWFwIGVsZW1lbnRzXzsKKyAgaW50IGRlZmF1bHRfZW51bV92YWx1ZV87CisKKyAgZnJpZW5kIGNsYXNzIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmE7CisgIHR5cGVkZWYgdm9pZCBJbnRlcm5hbEFyZW5hQ29uc3RydWN0YWJsZV87CisgIHR5cGVkZWYgdm9pZCBEZXN0cnVjdG9yU2tpcHBhYmxlXzsKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIEssIHR5cGVuYW1lIFYsCisgICAgICAgICAgICBpbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrZXlfd2lyZV90eXBlLAorICAgICAgICAgICAgaW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUgdmFsdWVfd2lyZV90eXBlLAorICAgICAgICAgICAgaW50IGRlZmF1bHRfZW51bV92YWx1ZT4KKyAgZnJpZW5kIGNsYXNzIGludGVybmFsOjpNYXBGaWVsZExpdGU7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworR09PR0xFX1BST1RPQlVGX0hBU0hfTkFNRVNQQUNFX0RFQ0xBUkFUSU9OX1NUQVJUCit0ZW1wbGF0ZTw+CitzdHJ1Y3QgaGFzaDxnb29nbGU6OnByb3RvYnVmOjpNYXBLZXk+IHsKKyAgc2l6ZV90CisgIG9wZXJhdG9yKCkoY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6TWFwS2V5JiBtYXBfa2V5KSBjb25zdCB7CisgICAgc3dpdGNoIChtYXBfa2V5LnR5cGUoKSkgeworICAgICAgY2FzZSBnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HOgorICAgICAgICByZXR1cm4gaGFzaDxzdHJpbmc+KCkobWFwX2tleS5HZXRTdHJpbmdWYWx1ZSgpKTsKKyAgICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0lOVDY0OgorICAgICAgICByZXR1cm4gaGFzaDwgOjpnb29nbGU6OnByb3RvYnVmOjppbnQ2ND4oKShtYXBfa2V5LkdldEludDY0VmFsdWUoKSk7CisgICAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9JTlQzMjoKKyAgICAgICAgcmV0dXJuIGhhc2g8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzI+KCkobWFwX2tleS5HZXRJbnQzMlZhbHVlKCkpOworICAgICAgY2FzZSBnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDY0OgorICAgICAgICByZXR1cm4gaGFzaDwgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50NjQ+KCkobWFwX2tleS5HZXRVSW50NjRWYWx1ZSgpKTsKKyAgICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1VJTlQzMjoKKyAgICAgICAgcmV0dXJuIGhhc2g8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyPigpKG1hcF9rZXkuR2V0VUludDMyVmFsdWUoKSk7CisgICAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9CT09MOgorICAgICAgICByZXR1cm4gaGFzaDxib29sPigpKG1hcF9rZXkuR2V0Qm9vbFZhbHVlKCkpOworICAgICAgY2FzZSBnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRE9VQkxFOgorICAgICAgY2FzZSBnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRkxPQVQ6CisgICAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9FTlVNOgorICAgICAgY2FzZSBnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRToKKyAgICAgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkNhbid0IGdldCBoZXJlLiI7CisgICAgfQorICAgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJDYW4ndCBnZXQgaGVyZS4iOworICAgIHJldHVybiAwOworICB9CisgIGJvb2wKKyAgb3BlcmF0b3IoKShjb25zdCBnb29nbGU6OnByb3RvYnVmOjpNYXBLZXkmIG1hcF9rZXkxLAorICAgICAgICAgICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6Ok1hcEtleSYgbWFwX2tleTIpIGNvbnN0IHsKKyAgICBzd2l0Y2ggKG1hcF9rZXkxLnR5cGUoKSkgeworI2RlZmluZSBDT01QQVJFX0NQUFRZUEUoQ1BQVFlQRSwgQ1BQVFlQRV9NRVRIT0QpICAgICAgICAgICAgIFwKKyAgICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yOjpDUFBUWVBFXyMjQ1BQVFlQRTogXAorICAgICAgICByZXR1cm4gbWFwX2tleTEuR2V0IyNDUFBUWVBFX01FVEhPRCMjVmFsdWUoKSA8ICAgICAgICAgICBcCisgICAgICAgICAgICAgICBtYXBfa2V5Mi5HZXQjI0NQUFRZUEVfTUVUSE9EIyNWYWx1ZSgpOworICAgICAgQ09NUEFSRV9DUFBUWVBFKFNUUklORywgU3RyaW5nKQorICAgICAgQ09NUEFSRV9DUFBUWVBFKElOVDY0LCAgSW50NjQpCisgICAgICBDT01QQVJFX0NQUFRZUEUoSU5UMzIsICBJbnQzMikKKyAgICAgIENPTVBBUkVfQ1BQVFlQRShVSU5UNjQsIFVJbnQ2NCkKKyAgICAgIENPTVBBUkVfQ1BQVFlQRShVSU5UMzIsIFVJbnQzMikKKyAgICAgIENPTVBBUkVfQ1BQVFlQRShCT09MLCAgIEJvb2wpCisjdW5kZWYgQ09NUEFSRV9DUFBUWVBFCisgICAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9ET1VCTEU6CisgICAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9GTE9BVDoKKyAgICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0VOVU06CisgICAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ2FuJ3QgZ2V0IGhlcmUuIjsKKyAgICB9CisgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkNhbid0IGdldCBoZXJlLiI7CisgICAgcmV0dXJuIHRydWU7CisgIH0KK307CitHT09HTEVfUFJPVE9CVUZfSEFTSF9OQU1FU1BBQ0VfREVDTEFSQVRJT05fRU5ECisKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX01BUF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvbWFwX2VudHJ5LmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF9lbnRyeS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk4N2M0ZTIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF9lbnRyeS5oCkBAIC0wLDAgKzEsMzA4IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfTUFQX0VOVFJZX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfTUFQX0VOVFJZX0hfXworCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9tZXNzYWdlX3JlZmxlY3Rpb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWFwX2VudHJ5X2xpdGUuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWFwX3R5cGVfaGFuZGxlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tZXRhZGF0YS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9yZWZsZWN0aW9uX29wcy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bmtub3duX2ZpZWxkX3NldC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdF9saXRlX2lubC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CitjbGFzcyBBcmVuYTsKK25hbWVzcGFjZSBpbnRlcm5hbCB7Cit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBWYWx1ZSwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtLZXlGaWVsZFR5cGUsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrVmFsdWVGaWVsZFR5cGUsCisgICAgICAgICAgaW50IGRlZmF1bHRfZW51bV92YWx1ZT4KK2NsYXNzIE1hcEZpZWxkOworfQorfQorCituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKworLy8gUmVnaXN0ZXIgYWxsIE1hcEVudHJ5IGRlZmF1bHQgaW5zdGFuY2VzIHNvIHdlIGNhbiBkZWxldGUgdGhlbSBpbgorLy8gU2h1dGRvd25Qcm90b2J1ZkxpYnJhcnkoKS4KK3ZvaWQgTElCUFJPVE9CVUZfRVhQT1JUIFJlZ2lzdGVyTWFwRW50cnlEZWZhdWx0SW5zdGFuY2UoCisgICAgTWVzc2FnZUxpdGUqIGRlZmF1bHRfaW5zdGFuY2UpOworCisvLyBUaGlzIGlzIHRoZSBjb21tb24gYmFzZSBjbGFzcyBmb3IgTWFwRW50cnkuIEl0IGlzIHVzZWQgYnkgTWFwRmllbGRCYXNlIGluCisvLyByZWZsZWN0aW9uIGFwaSwgaW4gd2hpY2ggdGhlIHN0YXRpYyB0eXBlIG9mIGtleSBhbmQgdmFsdWUgaXMgdW5rbm93bi4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBNYXBFbnRyeUJhc2UgOiBwdWJsaWMgTWVzc2FnZSB7CisgcHVibGljOgorICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEdldE1ldGFkYXRhKCkgY29uc3QgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgbWV0YWRhdGE7CisgICAgbWV0YWRhdGEuZGVzY3JpcHRvciA9IGRlc2NyaXB0b3JfOworICAgIG1ldGFkYXRhLnJlZmxlY3Rpb24gPSByZWZsZWN0aW9uXzsKKyAgICByZXR1cm4gbWV0YWRhdGE7CisgIH0KKworIHByb3RlY3RlZDoKKyAgTWFwRW50cnlCYXNlKCkgOiBkZXNjcmlwdG9yXyhOVUxMKSwgcmVmbGVjdGlvbl8oTlVMTCkgeyAgfQorICB2aXJ0dWFsIH5NYXBFbnRyeUJhc2UoKSB7fQorCisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uXzsKK307CisKKy8vIE1hcEVudHJ5IGlzIHRoZSByZXR1cm5lZCBnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlIHdoZW4gY2FsbGluZyBBZGRNZXNzYWdlIG9mCisvLyBnb29nbGU6OnByb3RvYnVmOjpSZWZsZWN0aW9uLiBJbiBvcmRlciB0byBsZXQgaXQgd29yayB3aXRoIGdlbmVyYXRlZCBtZXNzYWdlCisvLyByZWZsZWN0aW9uLCBpdHMgaW4tbWVtb3J5IHR5cGUgaXMgdGhlIHNhbWUgYXMgZ2VuZXJhdGVkIG1lc3NhZ2Ugd2l0aCB0aGUgc2FtZQorLy8gZmllbGRzLiBIb3dldmVyLCBpbiBvcmRlciB0byBkZWNpZGUgdGhlIGluLW1lbW9yeSB0eXBlIG9mIGtleS92YWx1ZSwgd2UgbmVlZAorLy8gdG8ga25vdyBib3RoIHRoZWlyIGNwcCB0eXBlIGluIGdlbmVyYXRlZCBhcGkgYW5kIHByb3RvIHR5cGUuIEluCisvLyBpbXBsbWVudGF0aW9uLCBhbGwgaW4tbWVtb3J5IHR5cGVzIGhhdmUgcmVsYXRlZCB3aXJlIGZvcm1hdCBmdW5jdGlvbnMgdG8KKy8vIHN1cHBvcnQgZXhjZXB0IEFyZW5hU3RyaW5nUHRyLiBUaGVyZWZvcmUsIHdlIG5lZWQgdG8gZGVmaW5lIGFub3RoZXIgdHlwZSB3aXRoCisvLyBzdXBwb3J0aW5nIHdpcmUgZm9ybWF0IGZ1bmN0aW9ucy4gU2luY2UgdGhpcyB0eXBlIGlzIG9ubHkgdXNlZCBhcyByZXR1cm4gdHlwZQorLy8gb2YgTWFwRW50cnkgYWNjZXNzb3JzLCBpdCdzIG5hbWVkIE1hcEVudHJ5IGFjY2Vzc29yIHR5cGUuCisvLworLy8gY3BwIHR5cGU6ICAgICAgICAgICAgICAgdGhlIHR5cGUgdmlzaWJsZSB0byB1c2VycyBpbiBwdWJsaWMgQVBJLgorLy8gcHJvdG8gdHlwZTogICAgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBvZiB0aGUgZmllbGQuCisvLyBpbi1tZW1vcnkgdHlwZTogICAgICAgICB0eXBlIG9mIHRoZSBkYXRhIG1lbWJlciB1c2VkIHRvIHN0b3JlZCB0aGlzIGZpZWxkLgorLy8gTWFwRW50cnkgYWNjZXNzb3IgdHlwZTogdHlwZSB1c2VkIGluIE1hcEVudHJ5IGdldHRlcnMvbXV0YXRvcnMgdG8gYWNjZXNzIHRoZQorLy8gICAgICAgICAgICAgICAgICAgICAgICAgZmllbGQuCisvLworLy8gY3BwIHR5cGUgfCBwcm90byB0eXBlICB8IGluLW1lbW9yeSB0eXBlIHwgTWFwRW50cnkgYWNjZXNzb3IgdHlwZQorLy8gaW50MzIgICAgICBUWVBFX0lOVDMyICAgIGludDMyICAgICAgICAgICAgaW50MzIKKy8vIGludDMyICAgICAgVFlQRV9GSVhFRDMyICBpbnQzMiAgICAgICAgICAgIGludDMyCisvLyBzdHJpbmcgICAgIFRZUEVfU1RSSU5HICAgQXJlbmFTdHJpbmdQdHIgICBzdHJpbmcKKy8vIEZvb0VudW0gICAgVFlQRV9FTlVNICAgICBpbnQgICAgICAgICAgICAgIGludAorLy8gRm9vTWVzc2FnZSBUWVBFX01FU1NBR0UgIEZvb01lc3NhZ2UqICAgICAgRm9vTWVzc2FnZQorLy8KKy8vIFRoZSBpbi1tZW1vcnkgdHlwZXMgb2YgcHJpbWl0aXZlIHR5cGVzIGNhbiBiZSBpbmZlcnJlZCBmcm9tIGl0cyBwcm90byB0eXBlLAorLy8gd2hpbGUgd2UgbmVlZCB0byBleHBsaWNpdGx5IHNwZWNpZnkgdGhlIGNwcCB0eXBlIGlmIHByb3RvIHR5cGUgaXMKKy8vIFRZUEVfTUVTU0FHRSB0byBpbmZlciB0aGUgaW4tbWVtb3J5IHR5cGUuICBNb3Jlb3ZlciwgZGVmYXVsdF9lbnVtX3ZhbHVlIGlzCisvLyB1c2VkIHRvIGluaXRpYWxpemUgZW51bSBmaWVsZCBpbiBwcm90bzIuCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBWYWx1ZSwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtLZXlGaWVsZFR5cGUsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrVmFsdWVGaWVsZFR5cGUsCisgICAgICAgICAgaW50IGRlZmF1bHRfZW51bV92YWx1ZT4KK2NsYXNzIE1hcEVudHJ5IDogcHVibGljIE1hcEVudHJ5QmFzZSB7CisgIC8vIFByb3ZpZGUgdXRpbGl0aWVzIHRvIHBhcnNlL3NlcmlhbGl6ZSBrZXkvdmFsdWUuICBQcm92aWRlIHV0aWxpdGllcyB0bworICAvLyBtYW5pcHVsYXRlIGludGVybmFsIHN0b3JlZCB0eXBlLgorICB0eXBlZGVmIE1hcFR5cGVIYW5kbGVyPGtLZXlGaWVsZFR5cGUsIEtleT4gS2V5VHlwZUhhbmRsZXI7CisgIHR5cGVkZWYgTWFwVHlwZUhhbmRsZXI8a1ZhbHVlRmllbGRUeXBlLCBWYWx1ZT4gVmFsdWVUeXBlSGFuZGxlcjsKKworICAvLyBFbnVtIHR5cGUgY2Fubm90IGJlIHVzZWQgZm9yIE1hcFR5cGVIYW5kbGVyOjpSZWFkLiBEZWZpbmUgYSB0eXBlCisgIC8vIHdoaWNoIHdpbGwgcmVwbGFjZSBFbnVtIHdpdGggaW50LgorICB0eXBlZGVmIHR5cGVuYW1lIEtleVR5cGVIYW5kbGVyOjpNYXBFbnRyeUFjY2Vzc29yVHlwZSBLZXlNYXBFbnRyeUFjY2Vzc29yVHlwZTsKKyAgdHlwZWRlZiB0eXBlbmFtZSBWYWx1ZVR5cGVIYW5kbGVyOjpNYXBFbnRyeUFjY2Vzc29yVHlwZQorICAgICAgVmFsdWVNYXBFbnRyeUFjY2Vzc29yVHlwZTsKKworICAvLyBBYmJyZXZpYXRpb24gZm9yIE1hcEVudHJ5CisgIHR5cGVkZWYgdHlwZW5hbWUgZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6Ok1hcEVudHJ5PAorICAgICAgS2V5LCBWYWx1ZSwga0tleUZpZWxkVHlwZSwga1ZhbHVlRmllbGRUeXBlLCBkZWZhdWx0X2VudW1fdmFsdWU+IEVudHJ5VHlwZTsKKworICAvLyBBYmJyZXZpYXRpb24gZm9yIE1hcEVudHJ5TGl0ZQorICB0eXBlZGVmIHR5cGVuYW1lIGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpNYXBFbnRyeUxpdGU8CisgICAgICBLZXksIFZhbHVlLCBrS2V5RmllbGRUeXBlLCBrVmFsdWVGaWVsZFR5cGUsIGRlZmF1bHRfZW51bV92YWx1ZT4KKyAgICAgIEVudHJ5TGl0ZVR5cGU7CisKKyBwdWJsaWM6CisgIH5NYXBFbnRyeSgpIHsKKyAgICBpZiAodGhpcyA9PSBkZWZhdWx0X2luc3RhbmNlXykgeworICAgICAgZGVsZXRlIHJlZmxlY3Rpb25fOworICAgIH0KKyAgfQorCisgIC8vIGFjY2Vzc29ycyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworICB2aXJ0dWFsIGlubGluZSBjb25zdCBLZXlNYXBFbnRyeUFjY2Vzc29yVHlwZSYga2V5KCkgY29uc3QgeworICAgIHJldHVybiBlbnRyeV9saXRlXy5rZXkoKTsKKyAgfQorICBpbmxpbmUgS2V5TWFwRW50cnlBY2Nlc3NvclR5cGUqIG11dGFibGVfa2V5KCkgeworICAgIHJldHVybiBlbnRyeV9saXRlXy5tdXRhYmxlX2tleSgpOworICB9CisgIHZpcnR1YWwgaW5saW5lIGNvbnN0IFZhbHVlTWFwRW50cnlBY2Nlc3NvclR5cGUmIHZhbHVlKCkgY29uc3QgeworICAgIHJldHVybiBlbnRyeV9saXRlXy52YWx1ZSgpOworICB9CisgIGlubGluZSBWYWx1ZU1hcEVudHJ5QWNjZXNzb3JUeXBlKiBtdXRhYmxlX3ZhbHVlKCkgeworICAgIHJldHVybiBlbnRyeV9saXRlXy5tdXRhYmxlX3ZhbHVlKCk7CisgIH0KKworICAvLyBpbXBsZW1lbnRzIE1lc3NhZ2UgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKyAgYm9vbCBNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyAgICByZXR1cm4gZW50cnlfbGl0ZV8uTWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKGlucHV0KTsKKyAgfQorCisgIGludCBCeXRlU2l6ZSgpIGNvbnN0IHsKKyAgICByZXR1cm4gZW50cnlfbGl0ZV8uQnl0ZVNpemUoKTsKKyAgfQorCisgIHZvaWQgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0IHsKKyAgICBlbnRyeV9saXRlXy5TZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMob3V0cHV0KTsKKyAgfQorCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogb3V0cHV0KSBjb25zdCB7CisgICAgcmV0dXJuIGVudHJ5X2xpdGVfLlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkob3V0cHV0KTsKKyAgfQorCisgIGludCBHZXRDYWNoZWRTaXplKCkgY29uc3QgeworICAgIHJldHVybiBlbnRyeV9saXRlXy5HZXRDYWNoZWRTaXplKCk7CisgIH0KKworICBib29sIElzSW5pdGlhbGl6ZWQoKSBjb25zdCB7CisgICAgcmV0dXJuIGVudHJ5X2xpdGVfLklzSW5pdGlhbGl6ZWQoKTsKKyAgfQorCisgIE1lc3NhZ2UqIE5ldygpIGNvbnN0IHsKKyAgICBNYXBFbnRyeSogZW50cnkgPSBuZXcgTWFwRW50cnk7CisgICAgZW50cnktPmRlc2NyaXB0b3JfID0gZGVzY3JpcHRvcl87CisgICAgZW50cnktPnJlZmxlY3Rpb25fID0gcmVmbGVjdGlvbl87CisgICAgZW50cnktPnNldF9kZWZhdWx0X2luc3RhbmNlKGRlZmF1bHRfaW5zdGFuY2VfKTsKKyAgICByZXR1cm4gZW50cnk7CisgIH0KKworICBNZXNzYWdlKiBOZXcoQXJlbmEqIGFyZW5hKSBjb25zdCB7CisgICAgTWFwRW50cnkqIGVudHJ5ID0gQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8TWFwRW50cnk+KGFyZW5hKTsKKyAgICBlbnRyeS0+ZGVzY3JpcHRvcl8gPSBkZXNjcmlwdG9yXzsKKyAgICBlbnRyeS0+cmVmbGVjdGlvbl8gPSByZWZsZWN0aW9uXzsKKyAgICBlbnRyeS0+c2V0X2RlZmF1bHRfaW5zdGFuY2UoZGVmYXVsdF9pbnN0YW5jZV8pOworICAgIHJldHVybiBlbnRyeTsKKyAgfQorCisgIGludCBTcGFjZVVzZWQoKSBjb25zdCB7CisgICAgaW50IHNpemUgPSBzaXplb2YoTWFwRW50cnkpOworICAgIHNpemUgKz0gZW50cnlfbGl0ZV8uU3BhY2VVc2VkKCk7CisgICAgcmV0dXJuIHNpemU7CisgIH0KKworICB2b2lkIENvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICAgIENsZWFyKCk7CisgICAgTWVyZ2VGcm9tKGZyb20pOworICB9CisKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgICAgR09PR0xFX0NIRUNLX05FKCZmcm9tLCB0aGlzKTsKKyAgICBjb25zdCBNYXBFbnRyeSogc291cmNlID0gZHluYW1pY19jYXN0X2lmX2F2YWlsYWJsZTxjb25zdCBNYXBFbnRyeSo+KCZmcm9tKTsKKyAgICBpZiAoc291cmNlID09IE5VTEwpIHsKKyAgICAgIFJlZmxlY3Rpb25PcHM6Ok1lcmdlKGZyb20sIHRoaXMpOworICAgIH0gZWxzZSB7CisgICAgICBNZXJnZUZyb20oKnNvdXJjZSk7CisgICAgfQorICB9CisKKyAgdm9pZCBDb3B5RnJvbShjb25zdCBNYXBFbnRyeSYgZnJvbSkgeworICAgIENsZWFyKCk7CisgICAgTWVyZ2VGcm9tKGZyb20pOworICB9CisKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgTWFwRW50cnkmIGZyb20pIHsKKyAgICBlbnRyeV9saXRlXy5NZXJnZUZyb20oZnJvbS5lbnRyeV9saXRlXyk7CisgIH0KKworICB2b2lkIENsZWFyKCkgeworICAgIGVudHJ5X2xpdGVfLkNsZWFyKCk7CisgIH0KKworICB2b2lkIEluaXRBc0RlZmF1bHRJbnN0YW5jZSgpIHsKKyAgICBlbnRyeV9saXRlXy5Jbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgfQorCisgIEFyZW5hKiBHZXRBcmVuYSgpIGNvbnN0IHsKKyAgICByZXR1cm4gZW50cnlfbGl0ZV8uR2V0QXJlbmEoKTsKKyAgfQorCisgIC8vIENyZWF0ZSBkZWZhdWx0IE1hcEVudHJ5IGluc3RhbmNlIGZvciBnaXZlbiBkZXNjcmlwdG9yLiBEZXNjcmlwdG9yIGhhcyB0byBiZQorICAvLyBnaXZlbiB3aGVuIGNyZWF0aW5nIGRlZmF1bHQgTWFwRW50cnkgaW5zdGFuY2UgYmVjYXVzZSBkaWZmZXJlbnQgbWFwIGZpZWxkCisgIC8vIG1heSBoYXZlIHRoZSBzYW1lIHR5cGUgYW5kIE1hcEVudHJ5IGNsYXNzLiBUaGUgZ2l2ZW4gZGVzY3JpcHRvciBpcyBuZWVkZWQKKyAgLy8gdG8gZGlzdGluZ3Vpc2ggaW5zdGFuY2VzIG9mIHRoZSBzYW1lIE1hcEVudHJ5IGNsYXNzLgorICBzdGF0aWMgTWFwRW50cnkqIENyZWF0ZURlZmF1bHRJbnN0YW5jZShjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgICAgTWFwRW50cnkqIGVudHJ5ID0gbmV3IE1hcEVudHJ5OworICAgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBuZXcgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24oCisgICAgICAgIGRlc2NyaXB0b3IsIGVudHJ5LCBvZmZzZXRzXywKKyAgICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChNYXBFbnRyeSwgZW50cnlfbGl0ZV8uX2hhc19iaXRzXyksCisgICAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoTWFwRW50cnksIF91bmtub3duX2ZpZWxkc18pLCAtMSwKKyAgICAgICAgRGVzY3JpcHRvclBvb2w6OmdlbmVyYXRlZF9wb29sKCksCisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZUZhY3Rvcnk6OmdlbmVyYXRlZF9mYWN0b3J5KCksCisgICAgICAgIHNpemVvZihNYXBFbnRyeSksCisgICAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoTWFwRW50cnksIF9pbnRlcm5hbF9tZXRhZGF0YV8pKTsKKyAgICBlbnRyeS0+ZGVzY3JpcHRvcl8gPSBkZXNjcmlwdG9yOworICAgIGVudHJ5LT5yZWZsZWN0aW9uXyA9IHJlZmxlY3Rpb247CisgICAgZW50cnktPnNldF9kZWZhdWx0X2luc3RhbmNlKGVudHJ5KTsKKyAgICBlbnRyeS0+SW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgICAgUmVnaXN0ZXJNYXBFbnRyeURlZmF1bHRJbnN0YW5jZShlbnRyeSk7CisgICAgcmV0dXJuIGVudHJ5OworICB9CisKKyBwcml2YXRlOgorICBNYXBFbnRyeSgpCisgICAgICA6IF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCksIGRlZmF1bHRfaW5zdGFuY2VfKE5VTEwpLCBlbnRyeV9saXRlXygpIHt9CisKKyAgZXhwbGljaXQgTWFwRW50cnkoQXJlbmEqIGFyZW5hKQorICAgICAgOiBfaW50ZXJuYWxfbWV0YWRhdGFfKGFyZW5hKSwKKyAgICAgICAgZGVmYXVsdF9pbnN0YW5jZV8oTlVMTCksCisgICAgICAgIGVudHJ5X2xpdGVfKGFyZW5hKSB7fQorCisgIGlubGluZSBBcmVuYSogR2V0QXJlbmFOb1ZpcnR1YWwoKSBjb25zdCB7CisgICAgcmV0dXJuIGVudHJ5X2xpdGVfLkdldEFyZW5hTm9WaXJ0dWFsKCk7CisgIH0KKworICB2b2lkIHNldF9kZWZhdWx0X2luc3RhbmNlKE1hcEVudHJ5KiBkZWZhdWx0X2luc3RhbmNlKSB7CisgICAgZGVmYXVsdF9pbnN0YW5jZV8gPSBkZWZhdWx0X2luc3RhbmNlOworICAgIGVudHJ5X2xpdGVfLnNldF9kZWZhdWx0X2luc3RhbmNlKCZkZWZhdWx0X2luc3RhbmNlLT5lbnRyeV9saXRlXyk7CisgIH0KKworICBzdGF0aWMgaW50IG9mZnNldHNfWzJdOworICBVbmtub3duRmllbGRTZXQgX3Vua25vd25fZmllbGRzXzsKKyAgSW50ZXJuYWxNZXRhZGF0YVdpdGhBcmVuYSBfaW50ZXJuYWxfbWV0YWRhdGFfOworICBNYXBFbnRyeSogZGVmYXVsdF9pbnN0YW5jZV87CisgIEVudHJ5TGl0ZVR5cGUgZW50cnlfbGl0ZV87CisKKyAgZnJpZW5kIGNsYXNzIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmE7CisgIHR5cGVkZWYgdm9pZCBJbnRlcm5hbEFyZW5hQ29uc3RydWN0YWJsZV87CisgIHR5cGVkZWYgdm9pZCBEZXN0cnVjdG9yU2tpcHBhYmxlXzsKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIEssIHR5cGVuYW1lIFYsIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga193aXJlX3R5cGUsCisgICAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlLCBpbnQgZGVmYXVsdF9lbnVtPgorICBmcmllbmQgY2xhc3MgaW50ZXJuYWw6Ok1hcEZpZWxkOworICBmcmllbmQgY2xhc3MgaW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhNYXBFbnRyeSk7Cit9OworCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBWYWx1ZSwgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrS2V5RmllbGRUeXBlLAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga1ZhbHVlRmllbGRUeXBlLCBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlPgoraW50IE1hcEVudHJ5PEtleSwgVmFsdWUsIGtLZXlGaWVsZFR5cGUsIGtWYWx1ZUZpZWxkVHlwZSwKKyAgICAgICAgICAgICBkZWZhdWx0X2VudW1fdmFsdWU+OjpvZmZzZXRzX1syXSA9IHsKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKE1hcEVudHJ5LCBlbnRyeV9saXRlXy5rZXlfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKE1hcEVudHJ5LCBlbnRyeV9saXRlXy52YWx1ZV8pLAorfTsKKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfTUFQX0VOVFJZX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9tYXBfZW50cnlfbGl0ZS5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9tYXBfZW50cnlfbGl0ZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdjZGYxYjkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF9lbnRyeV9saXRlLmgKQEAgLTAsMCArMSw0MDEgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9NQVBfRU5UUllfTElURV9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX01BUF9FTlRSWV9MSVRFX0hfXworCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21hcF90eXBlX2hhbmRsZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZV9pbmwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworY2xhc3MgQXJlbmE7CituYW1lc3BhY2UgaW50ZXJuYWwgewordGVtcGxhdGUgPHR5cGVuYW1lIEtleSwgdHlwZW5hbWUgVmFsdWUsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrS2V5RmllbGRUeXBlLAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga1ZhbHVlRmllbGRUeXBlLAorICAgICAgICAgIGludCBkZWZhdWx0X2VudW1fdmFsdWU+CitjbGFzcyBNYXBFbnRyeTsKK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIFZhbHVlLAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga0tleUZpZWxkVHlwZSwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtWYWx1ZUZpZWxkVHlwZSwKKyAgICAgICAgICBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlPgorY2xhc3MgTWFwRmllbGRMaXRlOworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKKy8vIE1hcEVudHJ5TGl0ZSBpcyB1c2VkIHRvIGltcGxlbWVudCBwYXJzaW5nIGFuZCBzZXJpYWxpemF0aW9uIG9mIG1hcCBmb3IgbGl0ZQorLy8gcnVudGltZS4KK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIFZhbHVlLAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga0tleUZpZWxkVHlwZSwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtWYWx1ZUZpZWxkVHlwZSwKKyAgICAgICAgICBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlPgorY2xhc3MgTWFwRW50cnlMaXRlIDogcHVibGljIE1lc3NhZ2VMaXRlIHsKKyAgLy8gUHJvdmlkZSB1dGlsaXRpZXMgdG8gcGFyc2Uvc2VyaWFsaXplIGtleS92YWx1ZS4gIFByb3ZpZGUgdXRpbGl0aWVzIHRvCisgIC8vIG1hbmlwdWxhdGUgaW50ZXJuYWwgc3RvcmVkIHR5cGUuCisgIHR5cGVkZWYgTWFwVHlwZUhhbmRsZXI8a0tleUZpZWxkVHlwZSwgS2V5PiBLZXlUeXBlSGFuZGxlcjsKKyAgdHlwZWRlZiBNYXBUeXBlSGFuZGxlcjxrVmFsdWVGaWVsZFR5cGUsIFZhbHVlPiBWYWx1ZVR5cGVIYW5kbGVyOworCisgIC8vIERlZmluZSBpbnRlcm5hbCBtZW1vcnkgbGF5b3V0LiBTdHJpbmdzIGFuZCBtZXNzYWdlcyBhcmUgc3RvcmVkIGFzCisgIC8vIHBvaW50ZXJzLCB3aGlsZSBvdGhlciB0eXBlcyBhcmUgc3RvcmVkIGFzIHZhbHVlcy4KKyAgdHlwZWRlZiB0eXBlbmFtZSBLZXlUeXBlSGFuZGxlcjo6VHlwZU9uTWVtb3J5IEtleU9uTWVtb3J5OworICB0eXBlZGVmIHR5cGVuYW1lIFZhbHVlVHlwZUhhbmRsZXI6OlR5cGVPbk1lbW9yeSBWYWx1ZU9uTWVtb3J5OworCisgIC8vIEVudW0gdHlwZSBjYW5ub3QgYmUgdXNlZCBmb3IgTWFwVHlwZUhhbmRsZXI6OlJlYWQuIERlZmluZSBhIHR5cGUKKyAgLy8gd2hpY2ggd2lsbCByZXBsYWNlIEVudW0gd2l0aCBpbnQuCisgIHR5cGVkZWYgdHlwZW5hbWUgS2V5VHlwZUhhbmRsZXI6Ok1hcEVudHJ5QWNjZXNzb3JUeXBlIEtleU1hcEVudHJ5QWNjZXNzb3JUeXBlOworICB0eXBlZGVmIHR5cGVuYW1lIFZhbHVlVHlwZUhhbmRsZXI6Ok1hcEVudHJ5QWNjZXNzb3JUeXBlCisgICAgICBWYWx1ZU1hcEVudHJ5QWNjZXNzb3JUeXBlOworCisgIC8vIENvbnN0YW50cyBmb3IgZmllbGQgbnVtYmVyLgorICBzdGF0aWMgY29uc3QgaW50IGtLZXlGaWVsZE51bWJlciA9IDE7CisgIHN0YXRpYyBjb25zdCBpbnQga1ZhbHVlRmllbGROdW1iZXIgPSAyOworCisgIC8vIENvbnN0YW50cyBmb3IgZmllbGQgdGFnLgorICBzdGF0aWMgY29uc3QgdWludDgga0tleVRhZyA9IEdPT0dMRV9QUk9UT0JVRl9XSVJFX0ZPUk1BVF9NQUtFX1RBRygKKyAgICAgIGtLZXlGaWVsZE51bWJlciwgS2V5VHlwZUhhbmRsZXI6OmtXaXJlVHlwZSk7CisgIHN0YXRpYyBjb25zdCB1aW50OCBrVmFsdWVUYWcgPSBHT09HTEVfUFJPVE9CVUZfV0lSRV9GT1JNQVRfTUFLRV9UQUcoCisgICAgICBrVmFsdWVGaWVsZE51bWJlciwgVmFsdWVUeXBlSGFuZGxlcjo6a1dpcmVUeXBlKTsKKyAgc3RhdGljIGNvbnN0IGludCBrVGFnU2l6ZSA9IDE7CisKKyBwdWJsaWM6CisgIH5NYXBFbnRyeUxpdGUoKSB7CisgICAgaWYgKHRoaXMgIT0gZGVmYXVsdF9pbnN0YW5jZV8pIHsKKyAgICAgIGlmIChHZXRBcmVuYU5vVmlydHVhbCgpICE9IE5VTEwpIHJldHVybjsKKyAgICAgIEtleVR5cGVIYW5kbGVyOjpEZWxldGVOb0FyZW5hKGtleV8pOworICAgICAgVmFsdWVUeXBlSGFuZGxlcjo6RGVsZXRlTm9BcmVuYSh2YWx1ZV8pOworICAgIH0KKyAgfQorCisgIC8vIGFjY2Vzc29ycyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworICB2aXJ0dWFsIGlubGluZSBjb25zdCBLZXlNYXBFbnRyeUFjY2Vzc29yVHlwZSYga2V5KCkgY29uc3QgeworICAgIHJldHVybiBLZXlUeXBlSGFuZGxlcjo6R2V0RXh0ZXJuYWxSZWZlcmVuY2Uoa2V5Xyk7CisgIH0KKyAgdmlydHVhbCBpbmxpbmUgY29uc3QgVmFsdWVNYXBFbnRyeUFjY2Vzc29yVHlwZSYgdmFsdWUoKSBjb25zdCB7CisgICAgR09PR0xFX0NIRUNLKGRlZmF1bHRfaW5zdGFuY2VfICE9IE5VTEwpOworICAgIHJldHVybiBWYWx1ZVR5cGVIYW5kbGVyOjpEZWZhdWx0SWZOb3RJbml0aWFsaXplZCh2YWx1ZV8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdF9pbnN0YW5jZV8tPnZhbHVlXyk7CisgIH0KKyAgaW5saW5lIEtleU1hcEVudHJ5QWNjZXNzb3JUeXBlKiBtdXRhYmxlX2tleSgpIHsKKyAgICBzZXRfaGFzX2tleSgpOworICAgIHJldHVybiBLZXlUeXBlSGFuZGxlcjo6RW5zdXJlTXV0YWJsZSgma2V5XywgR2V0QXJlbmFOb1ZpcnR1YWwoKSk7CisgIH0KKyAgaW5saW5lIFZhbHVlTWFwRW50cnlBY2Nlc3NvclR5cGUqIG11dGFibGVfdmFsdWUoKSB7CisgICAgc2V0X2hhc192YWx1ZSgpOworICAgIHJldHVybiBWYWx1ZVR5cGVIYW5kbGVyOjpFbnN1cmVNdXRhYmxlKCZ2YWx1ZV8sIEdldEFyZW5hTm9WaXJ0dWFsKCkpOworICB9CisKKyAgLy8gaW1wbGVtZW50cyBNZXNzYWdlTGl0ZSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisgIC8vIE1hcEVudHJ5TGl0ZSBpcyBmb3IgaW1wbGVtZW50YXRpb24gb25seSBhbmQgdGhpcyBmdW5jdGlvbiBpc24ndCBjYWxsZWQKKyAgLy8gYW55d2hlcmUuIEp1c3QgcHJvdmlkZSBhIGZha2UgaW1wbGVtZW50YXRpb24gaGVyZSBmb3IgTWVzc2FnZUxpdGUuCisgIHN0cmluZyBHZXRUeXBlTmFtZSgpIGNvbnN0IHsgcmV0dXJuICIiOyB9CisKKyAgdm9pZCBDaGVja1R5cGVBbmRNZXJnZUZyb20oY29uc3QgTWVzc2FnZUxpdGUmIG90aGVyKSB7CisgICAgTWVyZ2VGcm9tKCo6Omdvb2dsZTo6cHJvdG9idWY6OmRvd25fY2FzdDxjb25zdCBNYXBFbnRyeUxpdGUqPigmb3RoZXIpKTsKKyAgfQorCisgIGJvb2wgTWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KSB7CisgICAgdWludDMyIHRhZzsKKworICAgIGZvciAoOzspIHsKKyAgICAgIC8vIDEpIGNvcnJ1cHRlZCBkYXRhOiByZXR1cm4gZmFsc2U7CisgICAgICAvLyAyKSB1bmtub3duIGZpZWxkOiBza2lwIHdpdGhvdXQgcHV0dGluZyBpbnRvIHVua25vd24gZmllbGQgc2V0OworICAgICAgLy8gMykgdW5rbm93biBlbnVtIHZhbHVlOiBrZWVwIGl0IGluIHBhcnNpbmcuIEluIHByb3RvMiwgY2FsbGVyIHNob3VsZAorICAgICAgLy8gY2hlY2sgdGhlIHZhbHVlIGFuZCBwdXQgdGhpcyBlbnRyeSBpbnRvIGNvbnRhaW5pbmcgbWVzc2FnZSdzIHVua25vd24KKyAgICAgIC8vIGZpZWxkIHNldCBpZiB0aGUgdmFsdWUgaXMgYW4gdW5rbm93biBlbnVtLiBJbiBwcm90bzMsIGNhbGxlciBkb2Vzbid0CisgICAgICAvLyBuZWVkIHRvIGNhcmUgd2hldGhlciB0aGUgdmFsdWUgaXMgdW5rbm93biBlbnVtOworICAgICAgLy8gNCkgbWlzc2luZyBrZXkvdmFsdWU6IG1pc3NlZCBrZXkvdmFsdWUgd2lsbCBoYXZlIGRlZmF1bHQgdmFsdWUuIGNhbGxlcgorICAgICAgLy8gc2hvdWxkIHRha2UgdGhpcyBlbnRyeSBhcyBpZiBrZXkvdmFsdWUgaXMgc2V0IHRvIGRlZmF1bHQgdmFsdWUuCisgICAgICB0YWcgPSBpbnB1dC0+UmVhZFRhZygpOworICAgICAgc3dpdGNoICh0YWcpIHsKKyAgICAgICAgY2FzZSBrS2V5VGFnOgorICAgICAgICAgIGlmICghS2V5VHlwZUhhbmRsZXI6OlJlYWQoaW5wdXQsIG11dGFibGVfa2V5KCkpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgfQorICAgICAgICAgIHNldF9oYXNfa2V5KCk7CisgICAgICAgICAgaWYgKCFpbnB1dC0+RXhwZWN0VGFnKGtWYWx1ZVRhZykpIGJyZWFrOworICAgICAgICAgIEdPT0dMRV9GQUxMVEhST1VHSF9JTlRFTkRFRDsKKworICAgICAgICBjYXNlIGtWYWx1ZVRhZzoKKyAgICAgICAgICBpZiAoIVZhbHVlVHlwZUhhbmRsZXI6OlJlYWQoaW5wdXQsIG11dGFibGVfdmFsdWUoKSkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICB9CisgICAgICAgICAgc2V0X2hhc192YWx1ZSgpOworICAgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0QXRFbmQoKSkgcmV0dXJuIHRydWU7CisgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICBpZiAodGFnID09IDAgfHwKKyAgICAgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkdldFRhZ1dpcmVUeXBlKHRhZykgPT0KKyAgICAgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0VORF9HUk9VUCkgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgfQorICAgICAgICAgIGlmICghV2lyZUZvcm1hdExpdGU6OlNraXBGaWVsZChpbnB1dCwgdGFnKSkgcmV0dXJuIGZhbHNlOworICAgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgfQorCisgIGludCBCeXRlU2l6ZSgpIGNvbnN0IHsKKyAgICBpbnQgc2l6ZSA9IDA7CisgICAgc2l6ZSArPSBoYXNfa2V5KCkgPyBrVGFnU2l6ZSArIEtleVR5cGVIYW5kbGVyOjpCeXRlU2l6ZShrZXkoKSkgOiAwOworICAgIHNpemUgKz0gaGFzX3ZhbHVlKCkgPyBrVGFnU2l6ZSArIFZhbHVlVHlwZUhhbmRsZXI6OkJ5dGVTaXplKHZhbHVlKCkpIDogMDsKKyAgICByZXR1cm4gc2l6ZTsKKyAgfQorCisgIHZvaWQgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0IHsKKyAgICBLZXlUeXBlSGFuZGxlcjo6V3JpdGUoa0tleUZpZWxkTnVtYmVyLCBrZXkoKSwgb3V0cHV0KTsKKyAgICBWYWx1ZVR5cGVIYW5kbGVyOjpXcml0ZShrVmFsdWVGaWVsZE51bWJlciwgdmFsdWUoKSwgb3V0cHV0KTsKKyAgfQorCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogb3V0cHV0KSBjb25zdCB7CisgICAgb3V0cHV0ID0gS2V5VHlwZUhhbmRsZXI6OldyaXRlVG9BcnJheShrS2V5RmllbGROdW1iZXIsIGtleSgpLCBvdXRwdXQpOworICAgIG91dHB1dCA9IFZhbHVlVHlwZUhhbmRsZXI6OldyaXRlVG9BcnJheShrVmFsdWVGaWVsZE51bWJlciwgdmFsdWUoKSwgb3V0cHV0KTsKKyAgICByZXR1cm4gb3V0cHV0OworICB9CisKKyAgaW50IEdldENhY2hlZFNpemUoKSBjb25zdCB7CisgICAgaW50IHNpemUgPSAwOworICAgIHNpemUgKz0gaGFzX2tleSgpCisgICAgICAgID8ga1RhZ1NpemUgKyBLZXlUeXBlSGFuZGxlcjo6R2V0Q2FjaGVkU2l6ZShrZXkoKSkKKyAgICAgICAgOiAwOworICAgIHNpemUgKz0gaGFzX3ZhbHVlKCkKKyAgICAgICAgPyBrVGFnU2l6ZSArIFZhbHVlVHlwZUhhbmRsZXI6OkdldENhY2hlZFNpemUoCisgICAgICAgICAgICB2YWx1ZSgpKQorICAgICAgICA6IDA7CisgICAgcmV0dXJuIHNpemU7CisgIH0KKworICBib29sIElzSW5pdGlhbGl6ZWQoKSBjb25zdCB7IHJldHVybiBWYWx1ZVR5cGVIYW5kbGVyOjpJc0luaXRpYWxpemVkKHZhbHVlXyk7IH0KKworICBNZXNzYWdlTGl0ZSogTmV3KCkgY29uc3QgeworICAgIE1hcEVudHJ5TGl0ZSogZW50cnkgPSBuZXcgTWFwRW50cnlMaXRlOworICAgIGVudHJ5LT5kZWZhdWx0X2luc3RhbmNlXyA9IGRlZmF1bHRfaW5zdGFuY2VfOworICAgIHJldHVybiBlbnRyeTsKKyAgfQorCisgIE1lc3NhZ2VMaXRlKiBOZXcoQXJlbmEqIGFyZW5hKSBjb25zdCB7CisgICAgTWFwRW50cnlMaXRlKiBlbnRyeSA9IEFyZW5hOjpDcmVhdGVNZXNzYWdlPE1hcEVudHJ5TGl0ZT4oYXJlbmEpOworICAgIGVudHJ5LT5kZWZhdWx0X2luc3RhbmNlXyA9IGRlZmF1bHRfaW5zdGFuY2VfOworICAgIHJldHVybiBlbnRyeTsKKyAgfQorCisgIGludCBTcGFjZVVzZWQoKSBjb25zdCB7CisgICAgaW50IHNpemUgPSBzaXplb2YoTWFwRW50cnlMaXRlKTsKKyAgICBzaXplICs9IEtleVR5cGVIYW5kbGVyOjpTcGFjZVVzZWRJbk1hcEVudHJ5KGtleV8pOworICAgIHNpemUgKz0gVmFsdWVUeXBlSGFuZGxlcjo6U3BhY2VVc2VkSW5NYXBFbnRyeSh2YWx1ZV8pOworICAgIHJldHVybiBzaXplOworICB9CisKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgTWFwRW50cnlMaXRlJiBmcm9tKSB7CisgICAgaWYgKGZyb20uX2hhc19iaXRzX1swXSkgeworICAgICAgaWYgKGZyb20uaGFzX2tleSgpKSB7CisgICAgICAgIEtleVR5cGVIYW5kbGVyOjpFbnN1cmVNdXRhYmxlKCZrZXlfLCBHZXRBcmVuYU5vVmlydHVhbCgpKTsKKyAgICAgICAgS2V5VHlwZUhhbmRsZXI6Ok1lcmdlKGZyb20ua2V5KCksICZrZXlfLCBHZXRBcmVuYU5vVmlydHVhbCgpKTsKKyAgICAgICAgc2V0X2hhc19rZXkoKTsKKyAgICAgIH0KKyAgICAgIGlmIChmcm9tLmhhc192YWx1ZSgpKSB7CisgICAgICAgIFZhbHVlVHlwZUhhbmRsZXI6OkVuc3VyZU11dGFibGUoJnZhbHVlXywgR2V0QXJlbmFOb1ZpcnR1YWwoKSk7CisgICAgICAgIFZhbHVlVHlwZUhhbmRsZXI6Ok1lcmdlKGZyb20udmFsdWUoKSwgJnZhbHVlXywgR2V0QXJlbmFOb1ZpcnR1YWwoKSk7CisgICAgICAgIHNldF9oYXNfdmFsdWUoKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICB2b2lkIENsZWFyKCkgeworICAgIEtleVR5cGVIYW5kbGVyOjpDbGVhcigma2V5XywgR2V0QXJlbmFOb1ZpcnR1YWwoKSk7CisgICAgVmFsdWVUeXBlSGFuZGxlcjo6Q2xlYXJNYXliZUJ5RGVmYXVsdEVudW0oCisgICAgICAgICZ2YWx1ZV8sIEdldEFyZW5hTm9WaXJ0dWFsKCksIGRlZmF1bHRfZW51bV92YWx1ZSk7CisgICAgY2xlYXJfaGFzX2tleSgpOworICAgIGNsZWFyX2hhc192YWx1ZSgpOworICB9CisKKyAgdm9pZCBJbml0QXNEZWZhdWx0SW5zdGFuY2UoKSB7CisgICAgS2V5VHlwZUhhbmRsZXI6OkFzc2lnbkRlZmF1bHRWYWx1ZSgma2V5Xyk7CisgICAgVmFsdWVUeXBlSGFuZGxlcjo6QXNzaWduRGVmYXVsdFZhbHVlKCZ2YWx1ZV8pOworICB9CisKKyAgQXJlbmEqIEdldEFyZW5hKCkgY29uc3QgeworICAgIHJldHVybiBHZXRBcmVuYU5vVmlydHVhbCgpOworICB9CisKKyAgLy8gQ3JlYXRlIGEgTWFwRW50cnlMaXRlIGZvciBnaXZlbiBrZXkgYW5kIHZhbHVlIGZyb20gZ29vZ2xlOjpwcm90b2J1Zjo6TWFwIGluCisgIC8vIHNlcmlhbGl6YXRpb24uIFRoaXMgZnVuY3Rpb24gaXMgb25seSBjYWxsZWQgd2hlbiB2YWx1ZSBpcyBlbnVtLiBFbnVtIGlzCisgIC8vIHRyZWF0ZWQgZGlmZmVyZW50bHkgYmVjYXVzZSBpdHMgdHlwZSBpbiBNYXBFbnRyeSBpcyBpbnQgYW5kIGl0cyB0eXBlIGluCisgIC8vIGdvb2dsZTo6cHJvdG9idWY6Ok1hcCBpcyBlbnVtLiBXZSBjYW5ub3QgY3JlYXRlIGEgcmVmZXJlbmNlIHRvIGludCBmcm9tIGFuIGVudW0uCisgIHN0YXRpYyBNYXBFbnRyeUxpdGUqIEVudW1XcmFwKGNvbnN0IEtleSYga2V5LCBjb25zdCBWYWx1ZSB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJlbmEqIGFyZW5hKSB7CisgICAgcmV0dXJuIEFyZW5hOjpDcmVhdGVNZXNzYWdlPE1hcEVudW1FbnRyeVdyYXBwZXI8CisgICAgICAgIEtleSwgVmFsdWUsIGtLZXlGaWVsZFR5cGUsIGtWYWx1ZUZpZWxkVHlwZSwgZGVmYXVsdF9lbnVtX3ZhbHVlPiA+KAorICAgICAgICBhcmVuYSwga2V5LCB2YWx1ZSk7CisgIH0KKworICAvLyBMaWtlIGFib3ZlLCBidXQgZm9yIGFsbCB0aGUgb3RoZXIgdHlwZXMuIFRoaXMgYXZvaWRzIHZhbHVlIGNvcHkgdG8gY3JlYXRlCisgIC8vIE1hcEVudHJ5TGl0ZSBmcm9tIGdvb2dsZTo6cHJvdG9idWY6Ok1hcCBpbiBzZXJpYWxpemF0aW9uLgorICBzdGF0aWMgTWFwRW50cnlMaXRlKiBXcmFwKGNvbnN0IEtleSYga2V5LCBjb25zdCBWYWx1ZSYgdmFsdWUsIEFyZW5hKiBhcmVuYSkgeworICAgIHJldHVybiBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxNYXBFbnRyeVdyYXBwZXI8S2V5LCBWYWx1ZSwga0tleUZpZWxkVHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtWYWx1ZUZpZWxkVHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRfZW51bV92YWx1ZT4gPigKKyAgICAgICAgYXJlbmEsIGtleSwgdmFsdWUpOworICB9CisKKyBwcm90ZWN0ZWQ6CisgIHZvaWQgc2V0X2hhc19rZXkoKSB7IF9oYXNfYml0c19bMF0gfD0gMHgwMDAwMDAwMXU7IH0KKyAgYm9vbCBoYXNfa2V5KCkgY29uc3QgeyByZXR1cm4gKF9oYXNfYml0c19bMF0gJiAweDAwMDAwMDAxdSkgIT0gMDsgfQorICB2b2lkIGNsZWFyX2hhc19rZXkoKSB7IF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDF1OyB9CisgIHZvaWQgc2V0X2hhc192YWx1ZSgpIHsgX2hhc19iaXRzX1swXSB8PSAweDAwMDAwMDAydTsgfQorICBib29sIGhhc192YWx1ZSgpIGNvbnN0IHsgcmV0dXJuIChfaGFzX2JpdHNfWzBdICYgMHgwMDAwMDAwMnUpICE9IDA7IH0KKyAgdm9pZCBjbGVhcl9oYXNfdmFsdWUoKSB7IF9oYXNfYml0c19bMF0gJj0gfjB4MDAwMDAwMDJ1OyB9CisKKyBwcml2YXRlOgorICAvLyBTZXJpYWxpemluZyBhIGdlbmVyYXRlZCBtZXNzYWdlIGNvbnRhaW5pbmcgbWFwIGZpZWxkIGludm9sdmVzIHNlcmlhbGl6aW5nCisgIC8vIGtleS12YWx1ZSBwYWlycyBmcm9tIGdvb2dsZTo6cHJvdG9idWY6Ok1hcC4gVGhlIHdpcmUgZm9ybWF0IG9mIGVhY2gga2V5LXZhbHVlIHBhaXIKKyAgLy8gYWZ0ZXIgc2VyaWFsaXphdGlvbiBzaG91bGQgYmUgdGhlIHNhbWUgYXMgdGhhdCBvZiBhIE1hcEVudHJ5IG1lc3NhZ2UKKyAgLy8gY29udGFpbmluZyB0aGUgc2FtZSBrZXkgYW5kIHZhbHVlIGluc2lkZSBpdC4gIEhvd2V2ZXIsIGdvb2dsZTo6cHJvdG9idWY6Ok1hcCBkb2Vzbid0CisgIC8vIHN0b3JlIGtleSBhbmQgdmFsdWUgYXMgTWFwRW50cnkgbWVzc2FnZSwgd2hpY2ggZGlzYWJsZXMgdXMgdG8gdXNlIGV4aXN0aW5nCisgIC8vIGNvZGUgdG8gc2VyaWFsaXplIG1lc3NhZ2UuIEluIG9yZGVyIHRvIHVzZSBleGlzdGluZyBjb2RlIHRvIHNlcmlhbGl6ZQorICAvLyBtZXNzYWdlLCB3ZSBuZWVkIHRvIGNvbnN0cnVjdCBhIE1hcEVudHJ5IGZyb20ga2V5LXZhbHVlIHBhaXIuIEJ1dCBpdAorICAvLyBpbnZvbHZlcyBjb3B5IG9mIGtleSBhbmQgdmFsdWUgdG8gY29uc3RydWN0IGEgTWFwRW50cnkuIEluIG9yZGVyIHRvIGF2b2lkCisgIC8vIHRoaXMgY29weSBpbiBjb25zdHJ1Y3RpbmcgYSBNYXBFbnRyeSwgd2UgbmVlZCB0aGUgZm9sbG93aW5nIGNsYXNzIHdoaWNoCisgIC8vIG9ubHkgdGFrZXMgcmVmZXJlbmNlcyBvZiBnaXZlbiBrZXkgYW5kIHZhbHVlLgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgSywgdHlwZW5hbWUgViwgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrX3dpcmVfdHlwZSwKKyAgICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUgdl93aXJlX3R5cGUsIGludCBkZWZhdWx0X2VudW0+CisgIGNsYXNzIE1hcEVudHJ5V3JhcHBlcgorICAgICAgOiBwdWJsaWMgTWFwRW50cnlMaXRlPEssIFYsIGtfd2lyZV90eXBlLCB2X3dpcmVfdHlwZSwgZGVmYXVsdF9lbnVtPiB7CisgICAgdHlwZWRlZiBNYXBFbnRyeUxpdGU8SywgViwga193aXJlX3R5cGUsIHZfd2lyZV90eXBlLCBkZWZhdWx0X2VudW0+IEJhc2U7CisgICAgdHlwZWRlZiB0eXBlbmFtZSBCYXNlOjpLZXlNYXBFbnRyeUFjY2Vzc29yVHlwZSBLZXlNYXBFbnRyeUFjY2Vzc29yVHlwZTsKKyAgICB0eXBlZGVmIHR5cGVuYW1lIEJhc2U6OlZhbHVlTWFwRW50cnlBY2Nlc3NvclR5cGUgVmFsdWVNYXBFbnRyeUFjY2Vzc29yVHlwZTsKKworICAgcHVibGljOgorICAgIE1hcEVudHJ5V3JhcHBlcihBcmVuYSogYXJlbmEsIGNvbnN0IEsmIGtleSwgY29uc3QgViYgdmFsdWUpCisgICAgICAgIDogTWFwRW50cnlMaXRlPEssIFYsIGtfd2lyZV90eXBlLCB2X3dpcmVfdHlwZSwgZGVmYXVsdF9lbnVtPihhcmVuYSksCisgICAgICAgICAga2V5XyhrZXkpLAorICAgICAgICAgIHZhbHVlXyh2YWx1ZSkgeworICAgICAgQmFzZTo6c2V0X2hhc19rZXkoKTsKKyAgICAgIEJhc2U6OnNldF9oYXNfdmFsdWUoKTsKKyAgICB9CisgICAgaW5saW5lIGNvbnN0IEtleU1hcEVudHJ5QWNjZXNzb3JUeXBlJiBrZXkoKSBjb25zdCB7IHJldHVybiBrZXlfOyB9CisgICAgaW5saW5lIGNvbnN0IFZhbHVlTWFwRW50cnlBY2Nlc3NvclR5cGUmIHZhbHVlKCkgY29uc3QgeyByZXR1cm4gdmFsdWVfOyB9CisKKyAgIHByaXZhdGU6CisgICAgY29uc3QgS2V5JiBrZXlfOworICAgIGNvbnN0IFZhbHVlJiB2YWx1ZV87CisKKyAgICBmcmllbmQgY2xhc3MgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYTsKKyAgICB0eXBlZGVmIHZvaWQgSW50ZXJuYWxBcmVuYUNvbnN0cnVjdGFibGVfOworICAgIHR5cGVkZWYgdm9pZCBEZXN0cnVjdG9yU2tpcHBhYmxlXzsKKyAgfTsKKworICAvLyBMaWtlIGFib3ZlLCBidXQgZm9yIGVudW0gdmFsdWUgb25seSwgd2hpY2ggc3RvcmVzIHZhbHVlIGluc3RlYWQgb2YKKyAgLy8gcmVmZXJlbmNlIG9mIHZhbHVlIGZpZWxkIGluc2lkZS4gVGhpcyBpcyBuZWVkZWQgYmVjYXVzZSB0aGUgdHlwZSBvZiB2YWx1ZQorICAvLyBmaWVsZCBpbiBjb25zdHJ1Y3RvciBpcyBhbiBlbnVtLCB3aGlsZSB3ZSBuZWVkIHRvIHN0b3JlIGl0IGFzIGFuIGludC4gSWYgd2UKKyAgLy8gaW5pdGlhbGl6ZSBhIHJlZmVyZW5jZSB0byBpbnQgd2l0aCBhIHJlZmVyZW5jZSB0byBlbnVtLCBjb21waWxlciB3aWxsCisgIC8vIGdlbmVyYXRlIGEgdGVtcG9yYXJ5IGludCBmcm9tIGVudW0gYW5kIGluaXRpYWxpemUgdGhlIHJlZmVyZW5jZSB0byBpbnQgd2l0aAorICAvLyB0aGUgdGVtcG9yYXJ5LgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgSywgdHlwZW5hbWUgViwgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrX3dpcmVfdHlwZSwKKyAgICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUgdl93aXJlX3R5cGUsIGludCBkZWZhdWx0X2VudW0+CisgIGNsYXNzIE1hcEVudW1FbnRyeVdyYXBwZXIKKyAgICAgIDogcHVibGljIE1hcEVudHJ5TGl0ZTxLLCBWLCBrX3dpcmVfdHlwZSwgdl93aXJlX3R5cGUsIGRlZmF1bHRfZW51bT4geworICAgIHR5cGVkZWYgTWFwRW50cnlMaXRlPEssIFYsIGtfd2lyZV90eXBlLCB2X3dpcmVfdHlwZSwgZGVmYXVsdF9lbnVtPiBCYXNlOworICAgIHR5cGVkZWYgdHlwZW5hbWUgQmFzZTo6S2V5TWFwRW50cnlBY2Nlc3NvclR5cGUgS2V5TWFwRW50cnlBY2Nlc3NvclR5cGU7CisgICAgdHlwZWRlZiB0eXBlbmFtZSBCYXNlOjpWYWx1ZU1hcEVudHJ5QWNjZXNzb3JUeXBlIFZhbHVlTWFwRW50cnlBY2Nlc3NvclR5cGU7CisKKyAgIHB1YmxpYzoKKyAgICBNYXBFbnVtRW50cnlXcmFwcGVyKEFyZW5hKiBhcmVuYSwgY29uc3QgSyYga2V5LCBjb25zdCBWJiB2YWx1ZSkKKyAgICAgICAgOiBNYXBFbnRyeUxpdGU8SywgViwga193aXJlX3R5cGUsIHZfd2lyZV90eXBlLCBkZWZhdWx0X2VudW0+KGFyZW5hKSwKKyAgICAgICAgICBrZXlfKGtleSksCisgICAgICAgICAgdmFsdWVfKHZhbHVlKSB7CisgICAgICBCYXNlOjpzZXRfaGFzX2tleSgpOworICAgICAgQmFzZTo6c2V0X2hhc192YWx1ZSgpOworICAgIH0KKyAgICBpbmxpbmUgY29uc3QgS2V5TWFwRW50cnlBY2Nlc3NvclR5cGUmIGtleSgpIGNvbnN0IHsgcmV0dXJuIGtleV87IH0KKyAgICBpbmxpbmUgY29uc3QgVmFsdWVNYXBFbnRyeUFjY2Vzc29yVHlwZSYgdmFsdWUoKSBjb25zdCB7IHJldHVybiB2YWx1ZV87IH0KKworICAgcHJpdmF0ZToKKyAgICBjb25zdCBLZXlNYXBFbnRyeUFjY2Vzc29yVHlwZSYga2V5XzsKKyAgICBjb25zdCBWYWx1ZU1hcEVudHJ5QWNjZXNzb3JUeXBlIHZhbHVlXzsKKworICAgIGZyaWVuZCBjbGFzcyBnb29nbGU6OnByb3RvYnVmOjpBcmVuYTsKKyAgICB0eXBlZGVmIHZvaWQgRGVzdHJ1Y3RvclNraXBwYWJsZV87CisgIH07CisKKyAgTWFwRW50cnlMaXRlKCkgOiBkZWZhdWx0X2luc3RhbmNlXyhOVUxMKSwgYXJlbmFfKE5VTEwpIHsKKyAgICBLZXlUeXBlSGFuZGxlcjo6SW5pdGlhbGl6ZSgma2V5XywgTlVMTCk7CisgICAgVmFsdWVUeXBlSGFuZGxlcjo6SW5pdGlhbGl6ZU1heWJlQnlEZWZhdWx0RW51bSgKKyAgICAgICAgJnZhbHVlXywgZGVmYXVsdF9lbnVtX3ZhbHVlLCBOVUxMKTsKKyAgICBfaGFzX2JpdHNfWzBdID0gMDsKKyAgfQorCisgIGV4cGxpY2l0IE1hcEVudHJ5TGl0ZShBcmVuYSogYXJlbmEpCisgICAgICA6IGRlZmF1bHRfaW5zdGFuY2VfKE5VTEwpLCBhcmVuYV8oYXJlbmEpIHsKKyAgICBLZXlUeXBlSGFuZGxlcjo6SW5pdGlhbGl6ZSgma2V5XywgYXJlbmEpOworICAgIFZhbHVlVHlwZUhhbmRsZXI6OkluaXRpYWxpemVNYXliZUJ5RGVmYXVsdEVudW0oCisgICAgICAgICZ2YWx1ZV8sIGRlZmF1bHRfZW51bV92YWx1ZSwgYXJlbmEpOworICAgIF9oYXNfYml0c19bMF0gPSAwOworICB9CisKKyAgaW5saW5lIEFyZW5hKiBHZXRBcmVuYU5vVmlydHVhbCgpIGNvbnN0IHsKKyAgICByZXR1cm4gYXJlbmFfOworICB9CisKKyAgdm9pZCBzZXRfZGVmYXVsdF9pbnN0YW5jZShNYXBFbnRyeUxpdGUqIGRlZmF1bHRfaW5zdGFuY2UpIHsKKyAgICBkZWZhdWx0X2luc3RhbmNlXyA9IGRlZmF1bHRfaW5zdGFuY2U7CisgIH0KKworICBNYXBFbnRyeUxpdGUqIGRlZmF1bHRfaW5zdGFuY2VfOworCisgIEtleU9uTWVtb3J5IGtleV87CisgIFZhbHVlT25NZW1vcnkgdmFsdWVfOworICBBcmVuYSogYXJlbmFfOworICB1aW50MzIgX2hhc19iaXRzX1sxXTsKKworICBmcmllbmQgY2xhc3MgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYTsKKyAgdHlwZWRlZiB2b2lkIEludGVybmFsQXJlbmFDb25zdHJ1Y3RhYmxlXzsKKyAgdHlwZWRlZiB2b2lkIERlc3RydWN0b3JTa2lwcGFibGVfOworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgSywgdHlwZW5hbWUgViwgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSwKKyAgICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUsIGludD4KKyAgZnJpZW5kIGNsYXNzIGludGVybmFsOjpNYXBFbnRyeTsKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIEssIHR5cGVuYW1lIFYsIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUsCisgICAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlLCBpbnQ+CisgIGZyaWVuZCBjbGFzcyBpbnRlcm5hbDo6TWFwRmllbGRMaXRlOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhNYXBFbnRyeUxpdGUpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfTUFQX0VOVFJZX0xJVEVfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF9maWVsZC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvbWFwX2ZpZWxkLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVkZGM5NWMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF9maWVsZC5jYwpAQCAtMCwwICsxLDQ2NiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWFwX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21hcF9maWVsZF9pbmwuaD4KKworI2luY2x1ZGUgPHZlY3Rvcj4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKworUHJvdG9idWZPbmNlVHlwZSBtYXBfZW50cnlfZGVmYXVsdF9pbnN0YW5jZXNfb25jZV87CitNdXRleCogbWFwX2VudHJ5X2RlZmF1bHRfaW5zdGFuY2VzX211dGV4XzsKK3ZlY3RvcjxNZXNzYWdlTGl0ZSo+KiBtYXBfZW50cnlfZGVmYXVsdF9pbnN0YW5jZXNfOworCit2b2lkIERlbGV0ZU1hcEVudHJ5RGVmYXVsdEluc3RhbmNlcygpIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBtYXBfZW50cnlfZGVmYXVsdF9pbnN0YW5jZXNfLT5zaXplKCk7ICsraSkgeworICAgIGRlbGV0ZSBtYXBfZW50cnlfZGVmYXVsdF9pbnN0YW5jZXNfLT5hdChpKTsKKyAgfQorICBkZWxldGUgbWFwX2VudHJ5X2RlZmF1bHRfaW5zdGFuY2VzX211dGV4XzsKKyAgZGVsZXRlIG1hcF9lbnRyeV9kZWZhdWx0X2luc3RhbmNlc187Cit9CisKK3ZvaWQgSW5pdE1hcEVudHJ5RGVmYXVsdEluc3RhbmNlcygpIHsKKyAgbWFwX2VudHJ5X2RlZmF1bHRfaW5zdGFuY2VzX211dGV4XyA9IG5ldyBNdXRleCgpOworICBtYXBfZW50cnlfZGVmYXVsdF9pbnN0YW5jZXNfID0gbmV3IHZlY3RvcjxNZXNzYWdlTGl0ZSo+KCk7CisgIE9uU2h1dGRvd24oJkRlbGV0ZU1hcEVudHJ5RGVmYXVsdEluc3RhbmNlcyk7Cit9CisKK3ZvaWQgUmVnaXN0ZXJNYXBFbnRyeURlZmF1bHRJbnN0YW5jZShNZXNzYWdlTGl0ZSogZGVmYXVsdF9pbnN0YW5jZSkgeworICA6Omdvb2dsZTo6cHJvdG9idWY6Okdvb2dsZU9uY2VJbml0KCZtYXBfZW50cnlfZGVmYXVsdF9pbnN0YW5jZXNfb25jZV8sCisgICAgICAgICAgICAgICAgICZJbml0TWFwRW50cnlEZWZhdWx0SW5zdGFuY2VzKTsKKyAgTXV0ZXhMb2NrIGxvY2sobWFwX2VudHJ5X2RlZmF1bHRfaW5zdGFuY2VzX211dGV4Xyk7CisgIG1hcF9lbnRyeV9kZWZhdWx0X2luc3RhbmNlc18tPnB1c2hfYmFjayhkZWZhdWx0X2luc3RhbmNlKTsKK30KKworTWFwRmllbGRCYXNlOjp+TWFwRmllbGRCYXNlKCkgeworICBpZiAocmVwZWF0ZWRfZmllbGRfICE9IE5VTEwgJiYgYXJlbmFfID09IE5VTEwpIGRlbGV0ZSByZXBlYXRlZF9maWVsZF87Cit9CisKK2NvbnN0IFJlcGVhdGVkUHRyRmllbGRCYXNlJiBNYXBGaWVsZEJhc2U6OkdldFJlcGVhdGVkRmllbGQoKSBjb25zdCB7CisgIFN5bmNSZXBlYXRlZEZpZWxkV2l0aE1hcCgpOworICByZXR1cm4gKnJlcGVhdGVkX2ZpZWxkXzsKK30KKworUmVwZWF0ZWRQdHJGaWVsZEJhc2UqIE1hcEZpZWxkQmFzZTo6TXV0YWJsZVJlcGVhdGVkRmllbGQoKSB7CisgIFN5bmNSZXBlYXRlZEZpZWxkV2l0aE1hcCgpOworICBTZXRSZXBlYXRlZERpcnR5KCk7CisgIHJldHVybiByZXBlYXRlZF9maWVsZF87Cit9CisKK2ludCBNYXBGaWVsZEJhc2U6OlNwYWNlVXNlZEV4Y2x1ZGluZ1NlbGYoKSBjb25zdCB7CisgIG11dGV4Xy5Mb2NrKCk7CisgIGludCBzaXplID0gU3BhY2VVc2VkRXhjbHVkaW5nU2VsZk5vTG9jaygpOworICBtdXRleF8uVW5sb2NrKCk7CisgIHJldHVybiBzaXplOworfQorCitpbnQgTWFwRmllbGRCYXNlOjpTcGFjZVVzZWRFeGNsdWRpbmdTZWxmTm9Mb2NrKCkgY29uc3QgeworICBpZiAocmVwZWF0ZWRfZmllbGRfICE9IE5VTEwpIHsKKyAgICByZXR1cm4gcmVwZWF0ZWRfZmllbGRfLT5TcGFjZVVzZWRFeGNsdWRpbmdTZWxmKCk7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIDA7CisgIH0KK30KKwordm9pZCBNYXBGaWVsZEJhc2U6OkluaXRNZXRhZGF0YU9uY2UoKSBjb25zdCB7CisgIEdPT0dMRV9DSEVDSyhlbnRyeV9kZXNjcmlwdG9yXyAhPSBOVUxMKTsKKyAgR09PR0xFX0NIRUNLKGFzc2lnbl9kZXNjcmlwdG9yX2NhbGxiYWNrXyAhPSBOVUxMKTsKKyAgKCphc3NpZ25fZGVzY3JpcHRvcl9jYWxsYmFja18pKCk7Cit9CisKK3ZvaWQgTWFwRmllbGRCYXNlOjpTZXRNYXBEaXJ0eSgpIHsgc3RhdGVfID0gU1RBVEVfTU9ESUZJRURfTUFQOyB9CisKK3ZvaWQgTWFwRmllbGRCYXNlOjpTZXRSZXBlYXRlZERpcnR5KCkgeyBzdGF0ZV8gPSBTVEFURV9NT0RJRklFRF9SRVBFQVRFRDsgfQorCit2b2lkKiBNYXBGaWVsZEJhc2U6Ok11dGFibGVSZXBlYXRlZFB0ckZpZWxkKCkgY29uc3QgeyByZXR1cm4gcmVwZWF0ZWRfZmllbGRfOyB9CisKK3ZvaWQgTWFwRmllbGRCYXNlOjpTeW5jUmVwZWF0ZWRGaWVsZFdpdGhNYXAoKSBjb25zdCB7CisgIC8vICJBY3F1aXJlIiBpbnN1cmVzIHRoZSBvcGVyYXRpb24gYWZ0ZXIgU3luY1JlcGVhdGVkRmllbGRXaXRoTWFwIHdvbid0IGdldAorICAvLyBleGVjdXRlZCBiZWZvcmUgc3RhdGVfIGlzIGNoZWNrZWQuCisgIEF0b21pYzMyIHN0YXRlID0gZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFjcXVpcmVfTG9hZCgmc3RhdGVfKTsKKyAgaWYgKHN0YXRlID09IFNUQVRFX01PRElGSUVEX01BUCkgeworICAgIG11dGV4Xy5Mb2NrKCk7CisgICAgLy8gRG91YmxlIGNoZWNrIHN0YXRlLCBiZWNhdXNlIGFub3RoZXIgdGhyZWFkIG1heSBoYXZlIHNlZW4gdGhlIHNhbWUgc3RhdGUKKyAgICAvLyBhbmQgZG9uZSB0aGUgc3luY2hyb25pemF0aW9uIGJlZm9yZSB0aGUgY3VycmVudCB0aHJlYWQuCisgICAgaWYgKHN0YXRlXyA9PSBTVEFURV9NT0RJRklFRF9NQVApIHsKKyAgICAgIFN5bmNSZXBlYXRlZEZpZWxkV2l0aE1hcE5vTG9jaygpOworICAgICAgLy8gIlJlbGVhc2UiIGluc3VyZXMgc3RhdGVfIGNhbiBvbmx5IGJlIGNoYW5nZWQgImFmdGVyIgorICAgICAgLy8gU3luY1JlcGVhdGVkRmllbGRXaXRoTWFwTm9Mb2NrIGlzIGZpbmlzaGVkLgorICAgICAgZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlJlbGVhc2VfU3RvcmUoJnN0YXRlXywgQ0xFQU4pOworICAgIH0KKyAgICBtdXRleF8uVW5sb2NrKCk7CisgIH0KK30KKwordm9pZCBNYXBGaWVsZEJhc2U6OlN5bmNSZXBlYXRlZEZpZWxkV2l0aE1hcE5vTG9jaygpIGNvbnN0IHsKKyAgaWYgKHJlcGVhdGVkX2ZpZWxkXyA9PSBOVUxMKSB7CisgICAgcmVwZWF0ZWRfZmllbGRfID0gQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8UmVwZWF0ZWRQdHJGaWVsZDxNZXNzYWdlPiA+KGFyZW5hXyk7CisgIH0KK30KKwordm9pZCBNYXBGaWVsZEJhc2U6OlN5bmNNYXBXaXRoUmVwZWF0ZWRGaWVsZCgpIGNvbnN0IHsKKyAgLy8gIkFjcXVpcmUiIGluc3VyZXMgdGhlIG9wZXJhdGlvbiBhZnRlciBTeW5jTWFwV2l0aFJlcGVhdGVkRmllbGQgd29uJ3QgZ2V0CisgIC8vIGV4ZWN1dGVkIGJlZm9yZSBzdGF0ZV8gaXMgY2hlY2tlZC4KKyAgQXRvbWljMzIgc3RhdGUgPSBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QWNxdWlyZV9Mb2FkKCZzdGF0ZV8pOworICBpZiAoc3RhdGUgPT0gU1RBVEVfTU9ESUZJRURfUkVQRUFURUQpIHsKKyAgICBtdXRleF8uTG9jaygpOworICAgIC8vIERvdWJsZSBjaGVjayBzdGF0ZSwgYmVjYXVzZSBhbm90aGVyIHRocmVhZCBtYXkgaGF2ZSBzZWVuIHRoZSBzYW1lIHN0YXRlCisgICAgLy8gYW5kIGRvbmUgdGhlIHN5bmNocm9uaXphdGlvbiBiZWZvcmUgdGhlIGN1cnJlbnQgdGhyZWFkLgorICAgIGlmIChzdGF0ZV8gPT0gU1RBVEVfTU9ESUZJRURfUkVQRUFURUQpIHsKKyAgICAgIFN5bmNNYXBXaXRoUmVwZWF0ZWRGaWVsZE5vTG9jaygpOworICAgICAgLy8gIlJlbGVhc2UiIGluc3VyZXMgc3RhdGVfIGNhbiBvbmx5IGJlIGNoYW5nZWQgImFmdGVyIgorICAgICAgLy8gU3luY1JlcGVhdGVkRmllbGRXaXRoTWFwTm9Mb2NrIGlzIGZpbmlzaGVkLgorICAgICAgZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlJlbGVhc2VfU3RvcmUoJnN0YXRlXywgQ0xFQU4pOworICAgIH0KKyAgICBtdXRleF8uVW5sb2NrKCk7CisgIH0KK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tRHluYW1pY01hcEZpZWxkLS0tLS0tLS0tLS0tLS0tLS0tCitEeW5hbWljTWFwRmllbGQ6OkR5bmFtaWNNYXBGaWVsZChjb25zdCBNZXNzYWdlKiBkZWZhdWx0X2VudHJ5KQorICAgIDogZGVmYXVsdF9lbnRyeV8oZGVmYXVsdF9lbnRyeSkgeworfQorCitEeW5hbWljTWFwRmllbGQ6OkR5bmFtaWNNYXBGaWVsZChjb25zdCBNZXNzYWdlKiBkZWZhdWx0X2VudHJ5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJlbmEqIGFyZW5hKQorICAgIDogVHlwZURlZmluZWRNYXBGaWVsZEJhc2U8TWFwS2V5LCBNYXBWYWx1ZVJlZj4oYXJlbmEpLAorICAgICAgZGVmYXVsdF9lbnRyeV8oZGVmYXVsdF9lbnRyeSkgeworfQorCitEeW5hbWljTWFwRmllbGQ6On5EeW5hbWljTWFwRmllbGQoKSB7CisgIC8vIER5bmFtaWNNYXBGaWVsZCBvd25zIG1hcCB2YWx1ZXMuIE5lZWQgdG8gZGVsZXRlIHRoZW0gYmVmb3JlIGNsZWFyaW5nCisgIC8vIHRoZSBtYXAuCisgIGZvciAoTWFwPE1hcEtleSwgTWFwVmFsdWVSZWY+OjppdGVyYXRvciBpdGVyID0gbWFwXy5iZWdpbigpOworICAgICAgIGl0ZXIgIT0gbWFwXy5lbmQoKTsgKytpdGVyKSB7CisgICAgaXRlci0+c2Vjb25kLkRlbGV0ZURhdGEoKTsKKyAgfQorICBtYXBfLmNsZWFyKCk7Cit9CisKK2ludCBEeW5hbWljTWFwRmllbGQ6OnNpemUoKSBjb25zdCB7CisgIHJldHVybiBHZXRNYXAoKS5zaXplKCk7Cit9CisKK2Jvb2wgRHluYW1pY01hcEZpZWxkOjpDb250YWluc01hcEtleSgKKyAgICBjb25zdCBNYXBLZXkmIG1hcF9rZXkpIGNvbnN0IHsKKyAgY29uc3QgTWFwPE1hcEtleSwgTWFwVmFsdWVSZWY+JiBtYXAgPSBHZXRNYXAoKTsKKyAgTWFwPE1hcEtleSwgTWFwVmFsdWVSZWY+Ojpjb25zdF9pdGVyYXRvciBpdGVyID0gbWFwLmZpbmQobWFwX2tleSk7CisgIHJldHVybiBpdGVyICE9IG1hcC5lbmQoKTsKK30KKworYm9vbCBEeW5hbWljTWFwRmllbGQ6Okluc2VydE1hcFZhbHVlKAorICAgIGNvbnN0IE1hcEtleSYgbWFwX2tleSwgTWFwVmFsdWVSZWYqIHZhbCkgeworICBib29sIHJlc3VsdCA9IGZhbHNlOworCisgIE1hcFZhbHVlUmVmJiBtYXBfdmFsID0gKCpNdXRhYmxlTWFwKCkpW21hcF9rZXldOworICAvLyBJZiBtYXBfdmFsLmRhdGFfIGlzIG5vdCBzZXQsIGl0IGlzIG5ld2x5IGluc2VydGVkIGJ5IG1hcF9bbWFwX2tleV0uCisgIGlmIChtYXBfdmFsLmRhdGFfID09IE5VTEwpIHsKKyAgICByZXN1bHQgPSB0cnVlOworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogdmFsX2RlcyA9CisgICAgICAgIGRlZmF1bHRfZW50cnlfLT5HZXREZXNjcmlwdG9yKCktPkZpbmRGaWVsZEJ5TmFtZSgidmFsdWUiKTsKKyAgICBtYXBfdmFsLlNldFR5cGUodmFsX2Rlcy0+Y3BwX3R5cGUoKSk7CisgICAgLy8gQWxsb2NhdGUgbW9tZXJ5IGZvciB0aGUgaW5zZXJ0ZWQgTWFwVmFsdWVSZWYsIGFuZCBpbml0aWFsaXplIHRvCisgICAgLy8gZGVmYXVsdCB2YWx1ZS4KKyAgICBzd2l0Y2ggKHZhbF9kZXMtPmNwcF90eXBlKCkpIHsKKyNkZWZpbmUgSEFORExFX1RZUEUoQ1BQVFlQRSwgVFlQRSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV8jI0NQUFRZUEU6IHsgICAgICAgIFwKKyAgICAgICAgVFlQRSAqIHZhbHVlID0gbmV3IFRZUEUoKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIG1hcF92YWwuU2V0VmFsdWUodmFsdWUpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBicmVhazsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIH0KKyAgICAgIEhBTkRMRV9UWVBFKElOVDMyLCBpbnQzMik7CisgICAgICBIQU5ETEVfVFlQRShJTlQ2NCwgaW50NjQpOworICAgICAgSEFORExFX1RZUEUoVUlOVDMyLCB1aW50MzIpOworICAgICAgSEFORExFX1RZUEUoVUlOVDY0LCB1aW50NjQpOworICAgICAgSEFORExFX1RZUEUoRE9VQkxFLCBkb3VibGUpOworICAgICAgSEFORExFX1RZUEUoRkxPQVQsIGZsb2F0KTsKKyAgICAgIEhBTkRMRV9UWVBFKEJPT0wsIGJvb2wpOworICAgICAgSEFORExFX1RZUEUoU1RSSU5HLCBzdHJpbmcpOworICAgICAgSEFORExFX1RZUEUoRU5VTSwgaW50MzIpOworI3VuZGVmIEhBTkRMRV9UWVBFCisgICAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOiB7CisgICAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UgPSBkZWZhdWx0X2VudHJ5Xy0+R2V0UmVmbGVjdGlvbigpLT5HZXRNZXNzYWdlKAorICAgICAgICAgICAgKmRlZmF1bHRfZW50cnlfLCB2YWxfZGVzKTsKKyAgICAgICAgTWVzc2FnZSogdmFsdWUgPSBtZXNzYWdlLk5ldygpOworICAgICAgICBtYXBfdmFsLlNldFZhbHVlKHZhbHVlKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CisgIHZhbC0+Q29weUZyb20obWFwX3ZhbCk7CisgIHJldHVybiByZXN1bHQ7Cit9CisKK2Jvb2wgRHluYW1pY01hcEZpZWxkOjpEZWxldGVNYXBWYWx1ZShjb25zdCBNYXBLZXkmIG1hcF9rZXkpIHsKKyAgTWFwRmllbGRCYXNlOjpTeW5jTWFwV2l0aFJlcGVhdGVkRmllbGQoKTsKKyAgTWFwPE1hcEtleSwgTWFwVmFsdWVSZWY+OjppdGVyYXRvciBpdGVyID0gbWFwXy5maW5kKG1hcF9rZXkpOworICBpZiAoaXRlciA9PSBtYXBfLmVuZCgpKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIC8vIFNldCBtYXAgZGlydHkgb25seSBpZiB0aGUgZGVsZXRlIGlzIHN1Y2Nlc3NmdWwuCisgIE1hcEZpZWxkQmFzZTo6U2V0TWFwRGlydHkoKTsKKyAgaXRlci0+c2Vjb25kLkRlbGV0ZURhdGEoKTsKKyAgbWFwXy5lcmFzZShpdGVyKTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK2NvbnN0IE1hcDxNYXBLZXksIE1hcFZhbHVlUmVmPiYgRHluYW1pY01hcEZpZWxkOjpHZXRNYXAoKSBjb25zdCB7CisgIE1hcEZpZWxkQmFzZTo6U3luY01hcFdpdGhSZXBlYXRlZEZpZWxkKCk7CisgIHJldHVybiBtYXBfOworfQorCitNYXA8TWFwS2V5LCBNYXBWYWx1ZVJlZj4qIER5bmFtaWNNYXBGaWVsZDo6TXV0YWJsZU1hcCgpIHsKKyAgTWFwRmllbGRCYXNlOjpTeW5jTWFwV2l0aFJlcGVhdGVkRmllbGQoKTsKKyAgTWFwRmllbGRCYXNlOjpTZXRNYXBEaXJ0eSgpOworICByZXR1cm4gJm1hcF87Cit9CisKK3ZvaWQgRHluYW1pY01hcEZpZWxkOjpTZXRNYXBJdGVyYXRvclZhbHVlKE1hcEl0ZXJhdG9yKiBtYXBfaXRlcikgY29uc3QgeworICBNYXA8TWFwS2V5LCBNYXBWYWx1ZVJlZj46OmNvbnN0X2l0ZXJhdG9yIGl0ZXIgPQorICAgICAgVHlwZURlZmluZWRNYXBGaWVsZEJhc2U8TWFwS2V5LCBNYXBWYWx1ZVJlZj46OkludGVybmFsR2V0SXRlcmF0b3IoCisgICAgICAgICAgbWFwX2l0ZXIpOworICBpZiAoaXRlciA9PSBtYXBfLmVuZCgpKSByZXR1cm47CisgIG1hcF9pdGVyLT5rZXlfLkNvcHlGcm9tKGl0ZXItPmZpcnN0KTsKKyAgbWFwX2l0ZXItPnZhbHVlXy5Db3B5RnJvbShpdGVyLT5zZWNvbmQpOworfQorCit2b2lkIER5bmFtaWNNYXBGaWVsZDo6U3luY1JlcGVhdGVkRmllbGRXaXRoTWFwTm9Mb2NrKCkgY29uc3QgeworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gZGVmYXVsdF9lbnRyeV8tPkdldFJlZmxlY3Rpb24oKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBrZXlfZGVzID0KKyAgICAgIGRlZmF1bHRfZW50cnlfLT5HZXREZXNjcmlwdG9yKCktPkZpbmRGaWVsZEJ5TmFtZSgia2V5Iik7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogdmFsX2RlcyA9CisgICAgICBkZWZhdWx0X2VudHJ5Xy0+R2V0RGVzY3JpcHRvcigpLT5GaW5kRmllbGRCeU5hbWUoInZhbHVlIik7CisgIGlmIChNYXBGaWVsZEJhc2U6OnJlcGVhdGVkX2ZpZWxkXyA9PSBOVUxMKSB7CisgICAgaWYgKE1hcEZpZWxkQmFzZTo6YXJlbmFfID09IE5VTEwpIHsKKyAgICAgIE1hcEZpZWxkQmFzZTo6cmVwZWF0ZWRfZmllbGRfID0gbmV3IFJlcGVhdGVkUHRyRmllbGQ8TWVzc2FnZT4oKTsKKyAgICB9IGVsc2UgeworICAgICAgTWFwRmllbGRCYXNlOjpyZXBlYXRlZF9maWVsZF8gPQorICAgICAgICAgIEFyZW5hOjpDcmVhdGVNZXNzYWdlPFJlcGVhdGVkUHRyRmllbGQ8TWVzc2FnZT4gPigKKyAgICAgICAgICAgICAgTWFwRmllbGRCYXNlOjphcmVuYV8pOworICAgIH0KKyAgfQorCisgIE1hcEZpZWxkQmFzZTo6cmVwZWF0ZWRfZmllbGRfLT5DbGVhcigpOworCisgIGZvciAoTWFwPE1hcEtleSwgTWFwVmFsdWVSZWY+Ojpjb25zdF9pdGVyYXRvciBpdCA9IG1hcF8uYmVnaW4oKTsKKyAgICAgICBpdCAhPSBtYXBfLmVuZCgpOyArK2l0KSB7CisgICAgTWVzc2FnZSogbmV3X2VudHJ5ID0gZGVmYXVsdF9lbnRyeV8tPk5ldygpOworICAgIE1hcEZpZWxkQmFzZTo6cmVwZWF0ZWRfZmllbGRfLT5BZGRBbGxvY2F0ZWQobmV3X2VudHJ5KTsKKyAgICBjb25zdCBNYXBLZXkmIG1hcF9rZXkgPSBpdC0+Zmlyc3Q7CisgICAgc3dpdGNoIChrZXlfZGVzLT5jcHBfdHlwZSgpKSB7CisgICAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9TVFJJTkc6CisgICAgICAgIHJlZmxlY3Rpb24tPlNldFN0cmluZyhuZXdfZW50cnksIGtleV9kZXMsIG1hcF9rZXkuR2V0U3RyaW5nVmFsdWUoKSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UNjQ6CisgICAgICAgIHJlZmxlY3Rpb24tPlNldEludDY0KG5ld19lbnRyeSwga2V5X2RlcywgbWFwX2tleS5HZXRJbnQ2NFZhbHVlKCkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0lOVDMyOgorICAgICAgICByZWZsZWN0aW9uLT5TZXRJbnQzMihuZXdfZW50cnksIGtleV9kZXMsIG1hcF9rZXkuR2V0SW50MzJWYWx1ZSgpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9VSU5UNjQ6CisgICAgICAgIHJlZmxlY3Rpb24tPlNldFVJbnQ2NChuZXdfZW50cnksIGtleV9kZXMsIG1hcF9rZXkuR2V0VUludDY0VmFsdWUoKSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDMyOgorICAgICAgICByZWZsZWN0aW9uLT5TZXRVSW50MzIobmV3X2VudHJ5LCBrZXlfZGVzLCBtYXBfa2V5LkdldFVJbnQzMlZhbHVlKCkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0JPT0w6CisgICAgICAgIHJlZmxlY3Rpb24tPlNldEJvb2wobmV3X2VudHJ5LCBrZXlfZGVzLCBtYXBfa2V5LkdldEJvb2xWYWx1ZSgpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9ET1VCTEU6CisgICAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9GTE9BVDoKKyAgICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0VOVU06CisgICAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ2FuJ3QgZ2V0IGhlcmUuIjsKKyAgICAgICAgYnJlYWs7CisgICAgfQorICAgIGNvbnN0IE1hcFZhbHVlUmVmJiBtYXBfdmFsID0gaXQtPnNlY29uZDsKKyAgICBzd2l0Y2ggKHZhbF9kZXMtPmNwcF90eXBlKCkpIHsKKyAgICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORzoKKyAgICAgICAgcmVmbGVjdGlvbi0+U2V0U3RyaW5nKG5ld19lbnRyeSwgdmFsX2RlcywgbWFwX3ZhbC5HZXRTdHJpbmdWYWx1ZSgpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9JTlQ2NDoKKyAgICAgICAgcmVmbGVjdGlvbi0+U2V0SW50NjQobmV3X2VudHJ5LCB2YWxfZGVzLCBtYXBfdmFsLkdldEludDY0VmFsdWUoKSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UMzI6CisgICAgICAgIHJlZmxlY3Rpb24tPlNldEludDMyKG5ld19lbnRyeSwgdmFsX2RlcywgbWFwX3ZhbC5HZXRJbnQzMlZhbHVlKCkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1VJTlQ2NDoKKyAgICAgICAgcmVmbGVjdGlvbi0+U2V0VUludDY0KG5ld19lbnRyeSwgdmFsX2RlcywgbWFwX3ZhbC5HZXRVSW50NjRWYWx1ZSgpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9VSU5UMzI6CisgICAgICAgIHJlZmxlY3Rpb24tPlNldFVJbnQzMihuZXdfZW50cnksIHZhbF9kZXMsIG1hcF92YWwuR2V0VUludDMyVmFsdWUoKSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfQk9PTDoKKyAgICAgICAgcmVmbGVjdGlvbi0+U2V0Qm9vbChuZXdfZW50cnksIHZhbF9kZXMsIG1hcF92YWwuR2V0Qm9vbFZhbHVlKCkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0RPVUJMRToKKyAgICAgICAgcmVmbGVjdGlvbi0+U2V0RG91YmxlKG5ld19lbnRyeSwgdmFsX2RlcywgbWFwX3ZhbC5HZXREb3VibGVWYWx1ZSgpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9GTE9BVDoKKyAgICAgICAgcmVmbGVjdGlvbi0+U2V0RmxvYXQobmV3X2VudHJ5LCB2YWxfZGVzLCBtYXBfdmFsLkdldEZsb2F0VmFsdWUoKSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRU5VTToKKyAgICAgICAgcmVmbGVjdGlvbi0+U2V0RW51bVZhbHVlKG5ld19lbnRyeSwgdmFsX2RlcywgbWFwX3ZhbC5HZXRFbnVtVmFsdWUoKSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRTogeworICAgICAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlID0gbWFwX3ZhbC5HZXRNZXNzYWdlVmFsdWUoKTsKKyAgICAgICAgcmVmbGVjdGlvbi0+TXV0YWJsZU1lc3NhZ2UobmV3X2VudHJ5LCB2YWxfZGVzKS0+Q29weUZyb20obWVzc2FnZSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgfQorfQorCit2b2lkIER5bmFtaWNNYXBGaWVsZDo6U3luY01hcFdpdGhSZXBlYXRlZEZpZWxkTm9Mb2NrKCkgY29uc3QgeworICBNYXA8TWFwS2V5LCBNYXBWYWx1ZVJlZj4qIG1hcCA9ICZjb25zdF9jYXN0PER5bmFtaWNNYXBGaWVsZCo+KHRoaXMpLT5tYXBfOworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gZGVmYXVsdF9lbnRyeV8tPkdldFJlZmxlY3Rpb24oKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBrZXlfZGVzID0KKyAgICAgIGRlZmF1bHRfZW50cnlfLT5HZXREZXNjcmlwdG9yKCktPkZpbmRGaWVsZEJ5TmFtZSgia2V5Iik7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogdmFsX2RlcyA9CisgICAgICBkZWZhdWx0X2VudHJ5Xy0+R2V0RGVzY3JpcHRvcigpLT5GaW5kRmllbGRCeU5hbWUoInZhbHVlIik7CisgIC8vIER5bmFtaWNNYXBGaWVsZCBvd25zIG1hcCB2YWx1ZXMuIE5lZWQgdG8gZGVsZXRlIHRoZW0gYmVmb3JlIGNsZWFyaW5nCisgIC8vIHRoZSBtYXAuCisgIGZvciAoTWFwPE1hcEtleSwgTWFwVmFsdWVSZWY+OjppdGVyYXRvciBpdGVyID0gbWFwLT5iZWdpbigpOworICAgICAgIGl0ZXIgIT0gbWFwLT5lbmQoKTsgKytpdGVyKSB7CisgICAgaXRlci0+c2Vjb25kLkRlbGV0ZURhdGEoKTsKKyAgfQorICBtYXAtPmNsZWFyKCk7CisgIGZvciAoUmVwZWF0ZWRQdHJGaWVsZDxNZXNzYWdlPjo6aXRlcmF0b3IgaXQgPQorICAgICAgICAgICBNYXBGaWVsZEJhc2U6OnJlcGVhdGVkX2ZpZWxkXy0+YmVnaW4oKTsKKyAgICAgICBpdCAhPSBNYXBGaWVsZEJhc2U6OnJlcGVhdGVkX2ZpZWxkXy0+ZW5kKCk7ICsraXQpIHsKKyAgICBNYXBLZXkgbWFwX2tleTsKKyAgICBzd2l0Y2ggKGtleV9kZXMtPmNwcF90eXBlKCkpIHsKKyAgICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORzoKKyAgICAgICAgbWFwX2tleS5TZXRTdHJpbmdWYWx1ZShyZWZsZWN0aW9uLT5HZXRTdHJpbmcoKml0LCBrZXlfZGVzKSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UNjQ6CisgICAgICAgIG1hcF9rZXkuU2V0SW50NjRWYWx1ZShyZWZsZWN0aW9uLT5HZXRJbnQ2NCgqaXQsIGtleV9kZXMpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9JTlQzMjoKKyAgICAgICAgbWFwX2tleS5TZXRJbnQzMlZhbHVlKHJlZmxlY3Rpb24tPkdldEludDMyKCppdCwga2V5X2RlcykpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1VJTlQ2NDoKKyAgICAgICAgbWFwX2tleS5TZXRVSW50NjRWYWx1ZShyZWZsZWN0aW9uLT5HZXRVSW50NjQoKml0LCBrZXlfZGVzKSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDMyOgorICAgICAgICBtYXBfa2V5LlNldFVJbnQzMlZhbHVlKHJlZmxlY3Rpb24tPkdldFVJbnQzMigqaXQsIGtleV9kZXMpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9CT09MOgorICAgICAgICBtYXBfa2V5LlNldEJvb2xWYWx1ZShyZWZsZWN0aW9uLT5HZXRCb29sKCppdCwga2V5X2RlcykpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0RPVUJMRToKKyAgICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0ZMT0FUOgorICAgICAgY2FzZSBnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRU5VTToKKyAgICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U6CisgICAgICAgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJDYW4ndCBnZXQgaGVyZS4iOworICAgICAgICBicmVhazsKKyAgICB9CisgICAgTWFwVmFsdWVSZWYmIG1hcF92YWwgPSAoKm1hcClbbWFwX2tleV07CisgICAgbWFwX3ZhbC5TZXRUeXBlKHZhbF9kZXMtPmNwcF90eXBlKCkpOworICAgIHN3aXRjaCAodmFsX2Rlcy0+Y3BwX3R5cGUoKSkgeworI2RlZmluZSBIQU5ETEVfVFlQRShDUFBUWVBFLCBUWVBFLCBNRVRIT0QpICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yOjpDUFBUWVBFXyMjQ1BQVFlQRTogeyAgICAgICAgXAorICAgICAgICBUWVBFICogdmFsdWUgPSBuZXcgVFlQRTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgKnZhbHVlID0gcmVmbGVjdGlvbi0+R2V0IyNNRVRIT0QoKml0LCB2YWxfZGVzKTsgICAgICAgICBcCisgICAgICAgICAgICBtYXBfdmFsLlNldFZhbHVlKHZhbHVlKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgYnJlYWs7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIH0KKyAgICAgIEhBTkRMRV9UWVBFKElOVDMyLCBpbnQzMiwgSW50MzIpOworICAgICAgSEFORExFX1RZUEUoSU5UNjQsIGludDY0LCBJbnQ2NCk7CisgICAgICBIQU5ETEVfVFlQRShVSU5UMzIsIHVpbnQzMiwgVUludDMyKTsKKyAgICAgIEhBTkRMRV9UWVBFKFVJTlQ2NCwgdWludDY0LCBVSW50NjQpOworICAgICAgSEFORExFX1RZUEUoRE9VQkxFLCBkb3VibGUsIERvdWJsZSk7CisgICAgICBIQU5ETEVfVFlQRShGTE9BVCwgZmxvYXQsIEZsb2F0KTsKKyAgICAgIEhBTkRMRV9UWVBFKEJPT0wsIGJvb2wsIEJvb2wpOworICAgICAgSEFORExFX1RZUEUoU1RSSU5HLCBzdHJpbmcsIFN0cmluZyk7CisgICAgICBIQU5ETEVfVFlQRShFTlVNLCBpbnQzMiwgRW51bVZhbHVlKTsKKyN1bmRlZiBIQU5ETEVfVFlQRQorICAgICAgY2FzZSBnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRTogeworICAgICAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlID0gcmVmbGVjdGlvbi0+R2V0TWVzc2FnZSgqaXQsIHZhbF9kZXMpOworICAgICAgICBNZXNzYWdlKiB2YWx1ZSA9IG1lc3NhZ2UuTmV3KCk7CisgICAgICAgIHZhbHVlLT5Db3B5RnJvbShtZXNzYWdlKTsKKyAgICAgICAgbWFwX3ZhbC5TZXRWYWx1ZSh2YWx1ZSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgfQorfQorCitpbnQgRHluYW1pY01hcEZpZWxkOjpTcGFjZVVzZWRFeGNsdWRpbmdTZWxmTm9Mb2NrKCkgY29uc3QgeworICBpbnQgc2l6ZSA9IDA7CisgIGlmIChNYXBGaWVsZEJhc2U6OnJlcGVhdGVkX2ZpZWxkXyAhPSBOVUxMKSB7CisgICAgc2l6ZSArPSBNYXBGaWVsZEJhc2U6OnJlcGVhdGVkX2ZpZWxkXy0+U3BhY2VVc2VkRXhjbHVkaW5nU2VsZigpOworICB9CisgIHNpemUgKz0gc2l6ZW9mKG1hcF8pOworICBpbnQgbWFwX3NpemUgPSBtYXBfLnNpemUoKTsKKyAgaWYgKG1hcF9zaXplKSB7CisgICAgTWFwPE1hcEtleSwgTWFwVmFsdWVSZWY+Ojpjb25zdF9pdGVyYXRvciBpdCA9IG1hcF8uYmVnaW4oKTsKKyAgICBzaXplICs9IHNpemVvZihpdC0+Zmlyc3QpICogbWFwX3NpemU7CisgICAgc2l6ZSArPSBzaXplb2YoaXQtPnNlY29uZCkgKiBtYXBfc2l6ZTsKKyAgICAvLyBJZiBrZXkgaXMgc3RyaW5nLCBhZGQgdGhlIGFsbG9jYXRlZCBzcGFjZS4KKyAgICBpZiAoaXQtPmZpcnN0LnR5cGUoKSA9PSBnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HKSB7CisgICAgICBzaXplICs9IHNpemVvZihzdHJpbmcpICogbWFwX3NpemU7CisgICAgfQorICAgIC8vIEFkZCB0aGUgYWxsb2NhdGVkIHNwYWNlIGluIE1hcFZhbHVlUmVmLgorICAgIHN3aXRjaCAoaXQtPnNlY29uZC50eXBlKCkpIHsKKyNkZWZpbmUgSEFORExFX1RZUEUoQ1BQVFlQRSwgVFlQRSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV8jI0NQUFRZUEU6IHsgICAgICAgIFwKKyAgICAgICAgc2l6ZSArPSBzaXplb2YoVFlQRSkgKiBtYXBfc2l6ZTsgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGJyZWFrOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgfQorICAgICAgSEFORExFX1RZUEUoSU5UMzIsIGludDMyKTsKKyAgICAgIEhBTkRMRV9UWVBFKElOVDY0LCBpbnQ2NCk7CisgICAgICBIQU5ETEVfVFlQRShVSU5UMzIsIHVpbnQzMik7CisgICAgICBIQU5ETEVfVFlQRShVSU5UNjQsIHVpbnQ2NCk7CisgICAgICBIQU5ETEVfVFlQRShET1VCTEUsIGRvdWJsZSk7CisgICAgICBIQU5ETEVfVFlQRShGTE9BVCwgZmxvYXQpOworICAgICAgSEFORExFX1RZUEUoQk9PTCwgYm9vbCk7CisgICAgICBIQU5ETEVfVFlQRShTVFJJTkcsIHN0cmluZyk7CisgICAgICBIQU5ETEVfVFlQRShFTlVNLCBpbnQzMik7CisjdW5kZWYgSEFORExFX1RZUEUKKyAgICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U6IHsKKyAgICAgICAgd2hpbGUgKGl0ICE9IG1hcF8uZW5kKCkpIHsKKyAgICAgICAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlID0gaXQtPnNlY29uZC5HZXRNZXNzYWdlVmFsdWUoKTsKKyAgICAgICAgICBzaXplICs9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpLT5TcGFjZVVzZWQobWVzc2FnZSk7CisgICAgICAgICAgKytpdDsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KKyAgcmV0dXJuIHNpemU7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF9maWVsZC5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9tYXBfZmllbGQuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45MTMwMTY2Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9tYXBfZmllbGQuaApAQCAtMCwwICsxLDM5NiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX01BUF9GSUVMRF9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX01BUF9GSUVMRF9IX18KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbXV0ZXguaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9tZXNzYWdlX3JlZmxlY3Rpb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvYXJlbmEuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWFwX2VudHJ5Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21hcF9maWVsZF9saXRlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21hcF90eXBlX2hhbmRsZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWVzc2FnZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9yZXBlYXRlZF9maWVsZC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bmtub3duX2ZpZWxkX3NldC5oPgorCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK2NsYXNzIER5bmFtaWNNZXNzYWdlOworY2xhc3MgTWFwS2V5OworbmFtZXNwYWNlIGludGVybmFsIHsKKworY2xhc3MgQ29udGVuZGVkTWFwQ2xlYW5UZXN0OworY2xhc3MgR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb247CitjbGFzcyBNYXBGaWVsZEFjY2Vzc29yOworCisvLyBUaGlzIGNsYXNzIHByb3ZpZGVzIGFjY2Vzc3MgdG8gbWFwIGZpZWxkIHVzaW5nIHJlZmxlY3Rpb24sIHdoaWNoIGlzIHRoZSBzYW1lCisvLyBhcyB0aG9zZSBwcm92aWRlZCBmb3IgUmVwZWF0ZWRQdHJGaWVsZDxNZXNzYWdlPi4gSXQgaXMgdXNlZCBmb3IgaW50ZXJuYWwKKy8vIHJlZmxlY3Rpb24gaW1wbGVudGF0aW9uIG9ubHkuIFVzZXJzIHNob3VsZCBuZXZlciB1c2UgdGhpcyBkaXJlY3RseS4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBNYXBGaWVsZEJhc2UgeworIHB1YmxpYzoKKyAgTWFwRmllbGRCYXNlKCkKKyAgICAgIDogYXJlbmFfKE5VTEwpLAorICAgICAgICByZXBlYXRlZF9maWVsZF8oTlVMTCksCisgICAgICAgIGVudHJ5X2Rlc2NyaXB0b3JfKE5VTEwpLAorICAgICAgICBhc3NpZ25fZGVzY3JpcHRvcl9jYWxsYmFja18oTlVMTCksCisgICAgICAgIHN0YXRlXyhTVEFURV9NT0RJRklFRF9NQVApIHt9CisgIGV4cGxpY2l0IE1hcEZpZWxkQmFzZShBcmVuYSogYXJlbmEpCisgICAgICA6IGFyZW5hXyhhcmVuYSksCisgICAgICAgIHJlcGVhdGVkX2ZpZWxkXyhOVUxMKSwKKyAgICAgICAgZW50cnlfZGVzY3JpcHRvcl8oTlVMTCksCisgICAgICAgIGFzc2lnbl9kZXNjcmlwdG9yX2NhbGxiYWNrXyhOVUxMKSwKKyAgICAgICAgc3RhdGVfKFNUQVRFX01PRElGSUVEX01BUCkgeworICAgIC8vIE11dGV4J3MgZGVzdHJ1Y3RvciBuZWVkcyB0byBiZSBjYWxsZWQgZXhwbGljaXRseSB0byByZWxlYXNlIHJlc291cmNlcworICAgIC8vIGFjcXVpcmVkIGluIGl0cyBjb25zdHJ1Y3Rvci4KKyAgICBhcmVuYS0+T3duRGVzdHJ1Y3RvcigmbXV0ZXhfKTsKKyAgfQorICB2aXJ0dWFsIH5NYXBGaWVsZEJhc2UoKTsKKworICAvLyBSZXR1cm5zIHJlZmVyZW5jZSB0byBpbnRlcm5hbCByZXBlYXRlZCBmaWVsZC4gRGF0YSB3cml0dGVuIHVzaW5nCisgIC8vIGdvb2dsZTo6cHJvdG9idWY6Ok1hcCdzIGFwaSBwcmlvciB0byBjYWxsaW5nIHRoaXMgZnVuY3Rpb24gaXMgZ3VhcmFudHRlZCB0byBiZQorICAvLyBpbmNsdWRlZCBpbiByZXBlYXRlZCBmaWVsZC4KKyAgY29uc3QgUmVwZWF0ZWRQdHJGaWVsZEJhc2UmIEdldFJlcGVhdGVkRmllbGQoKSBjb25zdDsKKworICAvLyBMaWtlIGFib3ZlLiBSZXR1cm5zIG11dGFibGUgcG9pbnRlciB0byB0aGUgaW50ZXJuYWwgcmVwZWF0ZWQgZmllbGQuCisgIFJlcGVhdGVkUHRyRmllbGRCYXNlKiBNdXRhYmxlUmVwZWF0ZWRGaWVsZCgpOworCisgIC8vIFB1cmUgdmlydHVhbCBtYXAgQVBJcyBmb3IgTWFwIFJlZmxlY3Rpb24uCisgIHZpcnR1YWwgYm9vbCBDb250YWluc01hcEtleShjb25zdCBNYXBLZXkmIG1hcF9rZXkpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCBib29sIEluc2VydE1hcFZhbHVlKGNvbnN0IE1hcEtleSYgbWFwX2tleSwgTWFwVmFsdWVSZWYqIHZhbCkgPSAwOworICB2aXJ0dWFsIGJvb2wgRGVsZXRlTWFwVmFsdWUoY29uc3QgTWFwS2V5JiBtYXBfa2V5KSA9IDA7CisgIHZpcnR1YWwgYm9vbCBFcXVhbEl0ZXJhdG9yKGNvbnN0IE1hcEl0ZXJhdG9yJiBhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNYXBJdGVyYXRvciYgYikgY29uc3QgPSAwOworICB2aXJ0dWFsIHZvaWQgTWFwQmVnaW4oTWFwSXRlcmF0b3IqIG1hcF9pdGVyKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBNYXBFbmQoTWFwSXRlcmF0b3IqIG1hcF9pdGVyKSBjb25zdCA9IDA7CisgIC8vIFN5bmMgTWFwIHdpdGggcmVwZWF0ZWQgZmllbGQgYW5kIHJldHVybnMgdGhlIHNpemUgb2YgbWFwLgorICB2aXJ0dWFsIGludCBzaXplKCkgY29uc3QgPSAwOworCisgIC8vIFJldHVybnMgdGhlIG51bWJlciBvZiBieXRlcyB1c2VkIGJ5IHRoZSByZXBlYXRlZCBmaWVsZCwgZXhjbHVkaW5nCisgIC8vIHNpemVvZigqdGhpcykKKyAgaW50IFNwYWNlVXNlZEV4Y2x1ZGluZ1NlbGYoKSBjb25zdDsKKworIHByb3RlY3RlZDoKKyAgLy8gR2V0cyB0aGUgc2l6ZSBvZiBzcGFjZSB1c2VkIGJ5IG1hcCBmaWVsZC4KKyAgdmlydHVhbCBpbnQgU3BhY2VVc2VkRXhjbHVkaW5nU2VsZk5vTG9jaygpIGNvbnN0OworCisgIC8vIFN5bmNocm9uaXplcyB0aGUgY29udGVudCBpbiBNYXAgdG8gUmVwZWF0ZWRQdHJGaWVsZCBpZiB0aGVyZSBpcyBhbnkgY2hhbmdlCisgIC8vIHRvIE1hcCBhZnRlciBsYXN0IHN5bmNocm9uaXphdGlvbi4KKyAgdm9pZCBTeW5jUmVwZWF0ZWRGaWVsZFdpdGhNYXAoKSBjb25zdDsKKyAgdmlydHVhbCB2b2lkIFN5bmNSZXBlYXRlZEZpZWxkV2l0aE1hcE5vTG9jaygpIGNvbnN0OworCisgIC8vIFN5bmNocm9uaXplcyB0aGUgY29udGVudCBpbiBSZXBlYXRlZFB0ckZpZWxkIHRvIE1hcCBpZiB0aGVyZSBpcyBhbnkgY2hhbmdlCisgIC8vIHRvIFJlcGVhdGVkUHRyRmllbGQgYWZ0ZXIgbGFzdCBzeW5jaHJvbml6YXRpb24uCisgIHZvaWQgU3luY01hcFdpdGhSZXBlYXRlZEZpZWxkKCkgY29uc3Q7CisgIHZpcnR1YWwgdm9pZCBTeW5jTWFwV2l0aFJlcGVhdGVkRmllbGROb0xvY2soKSBjb25zdCB7fQorCisgIC8vIFRlbGxzIE1hcEZpZWxkQmFzZSB0aGF0IHRoZXJlIGlzIG5ldyBjaGFuZ2UgdG8gTWFwLgorICB2b2lkIFNldE1hcERpcnR5KCk7CisKKyAgLy8gVGVsbHMgTWFwRmllbGRCYXNlIHRoYXQgdGhlcmUgaXMgbmV3IGNoYW5nZSB0byBSZXBlYXRlZFBUckZpZWxkLgorICB2b2lkIFNldFJlcGVhdGVkRGlydHkoKTsKKworICAvLyBQcm92aWRlcyBkZXJpdmVkIGNsYXNzIHRoZSBhY2Nlc3MgdG8gcmVwZWF0ZWQgZmllbGQuCisgIHZvaWQqIE11dGFibGVSZXBlYXRlZFB0ckZpZWxkKCkgY29uc3Q7CisKKyAgLy8gQ3JlYXRlcyBkZXNjcmlwdG9yIGZvciBvbmx5IG9uZSB0aW1lLgorICB2b2lkIEluaXRNZXRhZGF0YU9uY2UoKSBjb25zdDsKKworICBlbnVtIFN0YXRlIHsKKyAgICBTVEFURV9NT0RJRklFRF9NQVAgPSAwLCAgICAgICAvLyBtYXAgaGFzIG5ld2x5IGFkZGVkIGRhdGEgdGhhdCBoYXMgbm90IGJlZW4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzeW5jaHJvbml6ZWQgdG8gcmVwZWF0ZWQgZmllbGQKKyAgICBTVEFURV9NT0RJRklFRF9SRVBFQVRFRCA9IDEsICAvLyByZXBlYXRlZCBmaWVsZCBoYXMgbmV3bHkgYWRkZWQgZGF0YSB0aGF0CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaGFzIG5vdCBiZWVuIHN5bmNocm9uaXplZCB0byBtYXAKKyAgICBDTEVBTiA9IDIsICAvLyBkYXRhIGluIG1hcCBhbmQgcmVwZWF0ZWQgZmllbGQgYXJlIHNhbWUKKyAgfTsKKworICBBcmVuYSogYXJlbmFfOworICBtdXRhYmxlIFJlcGVhdGVkUHRyRmllbGQ8TWVzc2FnZT4qIHJlcGVhdGVkX2ZpZWxkXzsKKyAgLy8gTWFwRW50cnkgY2FuIG9ubHkgYmUgY3JlYXRlZCBmcm9tIE1hcEZpZWxkLiBUbyBjcmVhdGUgTWFwRW50cnksIE1hcEZpZWxkCisgIC8vIG5lZWRzIHRvIGtub3cgaXRzIGRlc2NyaXB0b3IsIGJlY2F1c2UgTWFwRW50cnkgaXMgbm90IGdlbmVyYXRlZCBjbGFzcyB3aGljaAorICAvLyBjYW5ub3QgaW5pdGlhbGl6ZSBpdHMgb3duIGRlc2NyaXB0b3IgYnkgY2FsbGluZyBnZW5lcmF0ZWQKKyAgLy8gZGVzY3JpcHRvci1hc3NpZ24tZnVuY3Rpb24uIFRodXMsIHdlIG5lZWQgdG8gcmVnaXN0ZXIgYSBjYWxsYmFjayB0bworICAvLyBpbml0aWFsaXplIE1hcEVudHJ5J3MgZGVzY3JpcHRvci4KKyAgY29uc3QgRGVzY3JpcHRvcioqIGVudHJ5X2Rlc2NyaXB0b3JfOworICB2b2lkICgqYXNzaWduX2Rlc2NyaXB0b3JfY2FsbGJhY2tfKSgpOworCisgIG11dGFibGUgTXV0ZXggbXV0ZXhfOyAgLy8gVGhlIHRocmVhZCB0byBzeW5jaHJvbml6ZSBtYXAgYW5kIHJlcGVhdGVkIGZpZWxkCisgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbmVlZHMgdG8gZ2V0IGxvY2sgZmlyc3Q7CisgIG11dGFibGUgdm9sYXRpbGUgQXRvbWljMzIgc3RhdGVfOyAgLy8gMDogU1RBVEVfTU9ESUZJRURfTUFQCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gMTogU1RBVEVfTU9ESUZJRURfUkVQRUFURUQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAyOiBDTEVBTgorCisgcHJpdmF0ZToKKyAgZnJpZW5kIGNsYXNzIENvbnRlbmRlZE1hcENsZWFuVGVzdDsKKyAgZnJpZW5kIGNsYXNzIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOworICBmcmllbmQgY2xhc3MgTWFwRmllbGRBY2Nlc3NvcjsKKyAgZnJpZW5kIGNsYXNzIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RHluYW1pY01lc3NhZ2U7CisKKyAgLy8gVmlydHVhbCBoZWxwZXIgbWV0aG9kcyBmb3IgTWFwSXRlcmF0b3IuIE1hcEl0ZXJhdG9yIGRvZXNuJ3QgaGF2ZSB0aGUKKyAgLy8gdHlwZSBoZWxwZXIgZm9yIGtleSBhbmQgdmFsdWUuIENhbGwgdGhlc2UgaGVscCBtZXRob2RzIHRvIGRlYWwgd2l0aAorICAvLyBkaWZmZXJlbnQgdHlwZXMuIFJlYWwgaGVscGVyIG1ldGhvZHMgYXJlIGltcGxlbWVudGVkIGluCisgIC8vIFR5cGVEZWZpbmVkTWFwRmllbGRCYXNlLgorICBmcmllbmQgY2xhc3MgOjpnb29nbGU6OnByb3RvYnVmOjpNYXBJdGVyYXRvcjsKKyAgLy8gQWxsb2NhdGUgbWFwPC4uLj46Oml0ZXJhdG9yIGZvciBNYXBJdGVyYXRvci4KKyAgdmlydHVhbCB2b2lkIEluaXRpYWxpemVJdGVyYXRvcihNYXBJdGVyYXRvciogbWFwX2l0ZXIpIGNvbnN0ID0gMDsKKworICAvLyBEZWxldGVJdGVyYXRvcigpIGlzIGNhbGxlZCBieSB0aGUgZGVzdHJ1Y3RvciBvZiBNYXBJdGVyYXRvciBvbmx5LgorICAvLyBJdCBkZWxldGVzIG1hcDwuLi4+OjppdGVyYXRvciBmb3IgTWFwSXRlcmF0b3IuCisgIHZpcnR1YWwgdm9pZCBEZWxldGVJdGVyYXRvcihNYXBJdGVyYXRvciogbWFwX2l0ZXIpIGNvbnN0ID0gMDsKKworICAvLyBDb3B5IHRoZSBtYXA8Li4uPjo6aXRlcmF0b3IgZnJvbSBvdGhlcl9pdGVyYXRvciB0bworICAvLyB0aGlzX2l0ZXJhdG9yLgorICB2aXJ0dWFsIHZvaWQgQ29weUl0ZXJhdG9yKE1hcEl0ZXJhdG9yKiB0aGlzX2l0ZXJhdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1hcEl0ZXJhdG9yJiBvdGhlcl9pdGVyYXRvcikgY29uc3QgPSAwOworCisgIC8vIEluY3JlYXNlSXRlcmF0b3IoKSBpcyBjYWxsZWQgYnkgb3BlcmF0b3IrKygpIG9mIE1hcEl0ZXJhdG9yIG9ubHkuCisgIC8vIEl0IGltcGxlbWVudHMgdGhlICsrIG9wZXJhdG9yIG9mIE1hcEl0ZXJhdG9yLgorICB2aXJ0dWFsIHZvaWQgSW5jcmVhc2VJdGVyYXRvcihNYXBJdGVyYXRvciogbWFwX2l0ZXIpIGNvbnN0ID0gMDsKK307CisKKy8vIFRoaXMgY2xhc3MgcHJvdmlkZXMgY29tbW9uIE1hcCBSZWZsZWN0aW9uIGltcGxlbWVudGF0aW9ucyBmb3IgZ2VuZXJhdGVkCisvLyBtZXNzYWdlIGFuZCBkeW5hbWljIG1lc3NhZ2UuCit0ZW1wbGF0ZTx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIFQ+CitjbGFzcyBUeXBlRGVmaW5lZE1hcEZpZWxkQmFzZSA6IHB1YmxpYyBNYXBGaWVsZEJhc2UgeworIHB1YmxpYzoKKyAgVHlwZURlZmluZWRNYXBGaWVsZEJhc2UoKSB7fQorICBleHBsaWNpdCBUeXBlRGVmaW5lZE1hcEZpZWxkQmFzZShBcmVuYSogYXJlbmEpIDogTWFwRmllbGRCYXNlKGFyZW5hKSB7fQorICB+VHlwZURlZmluZWRNYXBGaWVsZEJhc2UoKSB7fQorICB2b2lkIE1hcEJlZ2luKE1hcEl0ZXJhdG9yKiBtYXBfaXRlcikgY29uc3Q7CisgIHZvaWQgTWFwRW5kKE1hcEl0ZXJhdG9yKiBtYXBfaXRlcikgY29uc3Q7CisgIGJvb2wgRXF1YWxJdGVyYXRvcihjb25zdCBNYXBJdGVyYXRvciYgYSwgY29uc3QgTWFwSXRlcmF0b3ImIGIpIGNvbnN0OworCisgIHZpcnR1YWwgY29uc3QgTWFwPEtleSwgVD4mIEdldE1hcCgpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCBNYXA8S2V5LCBUPiogTXV0YWJsZU1hcCgpID0gMDsKKworIHByb3RlY3RlZDoKKyAgdHlwZW5hbWUgTWFwPEtleSwgVD46OmNvbnN0X2l0ZXJhdG9yJiBJbnRlcm5hbEdldEl0ZXJhdG9yKAorICAgICAgY29uc3QgTWFwSXRlcmF0b3IqIG1hcF9pdGVyKSBjb25zdDsKKworIHByaXZhdGU6CisgIHZvaWQgSW5pdGlhbGl6ZUl0ZXJhdG9yKE1hcEl0ZXJhdG9yKiBtYXBfaXRlcikgY29uc3Q7CisgIHZvaWQgRGVsZXRlSXRlcmF0b3IoTWFwSXRlcmF0b3IqIG1hcF9pdGVyKSBjb25zdDsKKyAgdm9pZCBDb3B5SXRlcmF0b3IoTWFwSXRlcmF0b3IqIHRoaXNfaXRlcmF0b3JtLAorICAgICAgICAgICAgICAgICAgICBjb25zdCBNYXBJdGVyYXRvciYgdGhhdF9pdGVyYXRvcikgY29uc3Q7CisgIHZvaWQgSW5jcmVhc2VJdGVyYXRvcihNYXBJdGVyYXRvciogbWFwX2l0ZXIpIGNvbnN0OworCisgIHZpcnR1YWwgdm9pZCBTZXRNYXBJdGVyYXRvclZhbHVlKE1hcEl0ZXJhdG9yKiBtYXBfaXRlcikgY29uc3QgPSAwOworfTsKKworLy8gVGhpcyBjbGFzcyBwcm92aWRlcyBhY2Nlc3NzIHRvIG1hcCBmaWVsZCB1c2luZyBnZW5lcmF0ZWQgYXBpLiBJdCBpcyB1c2VkIGZvcgorLy8gaW50ZXJuYWwgZ2VuZXJhdGVkIG1lc3NhZ2UgaW1wbGVudGF0aW9uIG9ubHkuIFVzZXJzIHNob3VsZCBuZXZlciB1c2UgdGhpcworLy8gZGlyZWN0bHkuCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBULAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga0tleUZpZWxkVHlwZSwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtWYWx1ZUZpZWxkVHlwZSwKKyAgICAgICAgICBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlID0gMD4KK2NsYXNzIE1hcEZpZWxkIDogcHVibGljIFR5cGVEZWZpbmVkTWFwRmllbGRCYXNlPEtleSwgVD4sCisgICAgICAgICAgICAgICAgIHB1YmxpYyBNYXBGaWVsZExpdGU8S2V5LCBULCBrS2V5RmllbGRUeXBlLCBrVmFsdWVGaWVsZFR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdF9lbnVtX3ZhbHVlPiB7CisgIC8vIFByb3ZpZGUgdXRpbGl0aWVzIHRvIHBhcnNlL3NlcmlhbGl6ZSBrZXkvdmFsdWUuICBQcm92aWRlIHV0aWxpdGllcyB0bworICAvLyBtYW5pcHVsYXRlIGludGVybmFsIHN0b3JlZCB0eXBlLgorICB0eXBlZGVmIE1hcFR5cGVIYW5kbGVyPGtLZXlGaWVsZFR5cGUsIEtleT4gS2V5VHlwZUhhbmRsZXI7CisgIHR5cGVkZWYgTWFwVHlwZUhhbmRsZXI8a1ZhbHVlRmllbGRUeXBlLCBUPiBWYWx1ZVR5cGVIYW5kbGVyOworCisgIC8vIERlZmluZSBtZXNzYWdlIHR5cGUgZm9yIGludGVybmFsIHJlcGVhdGVkIGZpZWxkLgorICB0eXBlZGVmIE1hcEVudHJ5PEtleSwgVCwga0tleUZpZWxkVHlwZSwga1ZhbHVlRmllbGRUeXBlLCBkZWZhdWx0X2VudW1fdmFsdWU+CisgICAgICBFbnRyeVR5cGU7CisgIHR5cGVkZWYgTWFwRW50cnlMaXRlPEtleSwgVCwga0tleUZpZWxkVHlwZSwga1ZhbHVlRmllbGRUeXBlLAorICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0X2VudW1fdmFsdWU+IEVudHJ5TGl0ZVR5cGU7CisKKyAgLy8gRGVmaW5lIGFiYnJldmlhdGlvbiBmb3IgcGFyZW50IE1hcEZpZWxkTGl0ZQorICB0eXBlZGVmIE1hcEZpZWxkTGl0ZTxLZXksIFQsIGtLZXlGaWVsZFR5cGUsIGtWYWx1ZUZpZWxkVHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdF9lbnVtX3ZhbHVlPiBNYXBGaWVsZExpdGVUeXBlOworCisgIC8vIEVudW0gbmVlZHMgdG8gYmUgaGFuZGxlZCBkaWZmZXJlbnRseSBmcm9tIG90aGVyIHR5cGVzIGJlY2F1c2UgaXQgaGFzCisgIC8vIGRpZmZlcmVudCBleHBvc2VkIHR5cGUgaW4gZ29vZ2xlOjpwcm90b2J1Zjo6TWFwJ3MgYXBpIGFuZCByZXBlYXRlZCBmaWVsZCdzIGFwaS4gRm9yCisgIC8vIGRldGFpbHMgc2VlIHRoZSBjb21tZW50IGluIHRoZSBpbXBsZW1lbnRhdGlvbiBvZgorICAvLyBTeW5jTWFwV2l0aFJlcGVhdGVkRmllbGROb0xvY2suCisgIHN0YXRpYyBjb25zdCBib29sIGtJc1ZhbHVlRW51bSA9IFZhbHVlVHlwZUhhbmRsZXI6OmtJc0VudW07CisgIHR5cGVkZWYgdHlwZW5hbWUgTWFwSWY8a0lzVmFsdWVFbnVtLCBULCBjb25zdCBUJj46OnR5cGUgQ2FzdFZhbHVlVHlwZTsKKworIHB1YmxpYzoKKyAgTWFwRmllbGQoKTsKKyAgZXhwbGljaXQgTWFwRmllbGQoQXJlbmEqIGFyZW5hKTsKKyAgLy8gTWFwRmllbGQgZG9lc24ndCBvd24gdGhlIGRlZmF1bHRfZW50cnksIHdoaWNoIG1lYW5zIGRlZmF1bHRfZW50cnkgbXVzdAorICAvLyBvdXRsaXZlIHRoZSBsaWZldGltZSBvZiBNYXBGaWVsZC4KKyAgTWFwRmllbGQoY29uc3QgTWVzc2FnZSogZGVmYXVsdF9lbnRyeSk7CisgIC8vIEZvciB0ZXN0cyBvbmx5LgorICBNYXBGaWVsZChBcmVuYSogYXJlbmEsIGNvbnN0IE1lc3NhZ2UqIGRlZmF1bHRfZW50cnkpOworICB+TWFwRmllbGQoKTsKKworICAvLyBJbXBsZW1lbnQgTWFwRmllbGRCYXNlCisgIGJvb2wgQ29udGFpbnNNYXBLZXkoY29uc3QgTWFwS2V5JiBtYXBfa2V5KSBjb25zdDsKKyAgYm9vbCBJbnNlcnRNYXBWYWx1ZShjb25zdCBNYXBLZXkmIG1hcF9rZXksIE1hcFZhbHVlUmVmKiB2YWwpOworICBib29sIERlbGV0ZU1hcFZhbHVlKGNvbnN0IE1hcEtleSYgbWFwX2tleSk7CisKKyAgLy8gQWNjZXNzb3JzCisgIGNvbnN0IE1hcDxLZXksIFQ+JiBHZXRNYXAoKSBjb25zdDsKKyAgTWFwPEtleSwgVD4qIE11dGFibGVNYXAoKTsKKworICAvLyBDb252ZW5pZW50IG1ldGhvZHMgZm9yIGdlbmVyYXRlZCBtZXNzYWdlIGltcGxlbWVudGF0aW9uLgorICBpbnQgc2l6ZSgpIGNvbnN0OworICB2b2lkIENsZWFyKCk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IE1hcEZpZWxkTGl0ZVR5cGUmIG90aGVyKTsKKyAgdm9pZCBTd2FwKE1hcEZpZWxkTGl0ZVR5cGUqIG90aGVyKTsKKworICAvLyBBbGxvY2F0ZXMgbWV0YWRhdGEgb25seSBpZiB0aGlzIE1hcEZpZWxkIGlzIHBhcnQgb2YgYSBnZW5lcmF0ZWQgbWVzc2FnZS4KKyAgdm9pZCBTZXRFbnRyeURlc2NyaXB0b3IoY29uc3QgRGVzY3JpcHRvcioqIGRlc2NyaXB0b3IpOworICB2b2lkIFNldEFzc2lnbkRlc2NyaXB0b3JDYWxsYmFjayh2b2lkICgqY2FsbGJhY2spKCkpOworCisgcHJpdmF0ZToKKyAgdHlwZWRlZiB2b2lkIEludGVybmFsQXJlbmFDb25zdHJ1Y3RhYmxlXzsKKyAgdHlwZWRlZiB2b2lkIERlc3RydWN0b3JTa2lwcGFibGVfOworCisgIC8vIE1hcEZpZWxkIG5lZWRzIE1hcEVudHJ5J3MgZGVmYXVsdCBpbnN0YW5jZSB0byBjcmVhdGUgbmV3IE1hcEVudHJ5LgorICB2b2lkIEluaXREZWZhdWx0RW50cnlPbmNlKCkgY29uc3Q7CisKKyAgLy8gTWFudWFsbHkgc2V0IGRlZmF1bHQgZW50cnkgaW5zdGFuY2UuIEZvciB0ZXN0IG9ubHkuCisgIHZvaWQgU2V0RGVmYXVsdEVudHJ5T25jZShjb25zdCBFbnRyeVR5cGUqIGRlZmF1bHRfZW50cnkpIGNvbnN0OworCisgIC8vIENvbnZlbmllbnQgbWV0aG9kcyB0byBnZXQgaW50ZXJuYWwgZ29vZ2xlOjpwcm90b2J1Zjo6TWFwCisgIGNvbnN0IE1hcDxLZXksIFQ+JiBHZXRJbnRlcm5hbE1hcCgpIGNvbnN0OworICBNYXA8S2V5LCBUPiogTXV0YWJsZUludGVybmFsTWFwKCk7CisKKyAgLy8gSW1wbGVtZW50cyBNYXBGaWVsZEJhc2UKKyAgdm9pZCBTeW5jUmVwZWF0ZWRGaWVsZFdpdGhNYXBOb0xvY2soKSBjb25zdDsKKyAgdm9pZCBTeW5jTWFwV2l0aFJlcGVhdGVkRmllbGROb0xvY2soKSBjb25zdDsKKyAgaW50IFNwYWNlVXNlZEV4Y2x1ZGluZ1NlbGZOb0xvY2soKSBjb25zdDsKKworICB2b2lkIFNldE1hcEl0ZXJhdG9yVmFsdWUoTWFwSXRlcmF0b3IqIG1hcF9pdGVyKSBjb25zdDsKKworICBtdXRhYmxlIGNvbnN0IEVudHJ5VHlwZSogZGVmYXVsdF9lbnRyeV87CisKKyAgZnJpZW5kIGNsYXNzIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmE7Cit9OworCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgRHluYW1pY01hcEZpZWxkOiBwdWJsaWMgVHlwZURlZmluZWRNYXBGaWVsZEJhc2U8TWFwS2V5LCBNYXBWYWx1ZVJlZj4geworIHB1YmxpYzoKKyAgZXhwbGljaXQgRHluYW1pY01hcEZpZWxkKGNvbnN0IE1lc3NhZ2UqIGRlZmF1bHRfZW50cnkpOworICBEeW5hbWljTWFwRmllbGQoY29uc3QgTWVzc2FnZSogZGVmYXVsdF9lbnRyeSwgQXJlbmEqIGFyZW5hKTsKKyAgfkR5bmFtaWNNYXBGaWVsZCgpOworCisgIC8vIEltcGxlbWVudCBNYXBGaWVsZEJhc2UKKyAgYm9vbCBDb250YWluc01hcEtleShjb25zdCBNYXBLZXkmIG1hcF9rZXkpIGNvbnN0OworICBib29sIEluc2VydE1hcFZhbHVlKGNvbnN0IE1hcEtleSYgbWFwX2tleSwgTWFwVmFsdWVSZWYqIHZhbCk7CisgIGJvb2wgRGVsZXRlTWFwVmFsdWUoY29uc3QgTWFwS2V5JiBtYXBfa2V5KTsKKworICBjb25zdCBNYXA8TWFwS2V5LCBNYXBWYWx1ZVJlZj4mIEdldE1hcCgpIGNvbnN0OworICBNYXA8TWFwS2V5LCBNYXBWYWx1ZVJlZj4qIE11dGFibGVNYXAoKTsKKworICBpbnQgc2l6ZSgpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgTWFwPE1hcEtleSwgTWFwVmFsdWVSZWY+IG1hcF87CisgIGNvbnN0IE1lc3NhZ2UqIGRlZmF1bHRfZW50cnlfOworCisgIC8vIEltcGxlbWVudHMgTWFwRmllbGRCYXNlCisgIHZvaWQgU3luY1JlcGVhdGVkRmllbGRXaXRoTWFwTm9Mb2NrKCkgY29uc3Q7CisgIHZvaWQgU3luY01hcFdpdGhSZXBlYXRlZEZpZWxkTm9Mb2NrKCkgY29uc3Q7CisgIGludCBTcGFjZVVzZWRFeGNsdWRpbmdTZWxmTm9Mb2NrKCkgY29uc3Q7CisgIHZvaWQgU2V0TWFwSXRlcmF0b3JWYWx1ZShNYXBJdGVyYXRvciogbWFwX2l0ZXIpIGNvbnN0OworfTsKKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCisKK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBNYXBJdGVyYXRvciB7CisgcHVibGljOgorICBNYXBJdGVyYXRvcihNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgICAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKTsKKyAgICBtYXBfID0gcmVmbGVjdGlvbi0+TWFwRGF0YShtZXNzYWdlLCBmaWVsZCk7CisgICAga2V5Xy5TZXRUeXBlKGZpZWxkLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJrZXkiKS0+Y3BwX3R5cGUoKSk7CisgICAgdmFsdWVfLlNldFR5cGUoZmllbGQtPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoInZhbHVlIiktPmNwcF90eXBlKCkpOworICAgIG1hcF8tPkluaXRpYWxpemVJdGVyYXRvcih0aGlzKTsKKyAgfQorICBNYXBJdGVyYXRvcihjb25zdCBNYXBJdGVyYXRvciYgb3RoZXIpIHsKKyAgICBtYXBfID0gb3RoZXIubWFwXzsKKyAgICBtYXBfLT5Jbml0aWFsaXplSXRlcmF0b3IodGhpcyk7CisgICAgbWFwXy0+Q29weUl0ZXJhdG9yKHRoaXMsIG90aGVyKTsKKyAgfQorICB+TWFwSXRlcmF0b3IoKSB7CisgICAgbWFwXy0+RGVsZXRlSXRlcmF0b3IodGhpcyk7CisgIH0KKyAgZnJpZW5kIGJvb2wgb3BlcmF0b3I9PShjb25zdCBNYXBJdGVyYXRvciYgYSwgY29uc3QgTWFwSXRlcmF0b3ImIGIpIHsKKyAgICByZXR1cm4gYS5tYXBfLT5FcXVhbEl0ZXJhdG9yKGEsIGIpOworICB9CisgIGZyaWVuZCBib29sIG9wZXJhdG9yIT0oY29uc3QgTWFwSXRlcmF0b3ImIGEsIGNvbnN0IE1hcEl0ZXJhdG9yJiBiKSB7CisgICAgcmV0dXJuICFhLm1hcF8tPkVxdWFsSXRlcmF0b3IoYSwgYik7CisgIH0KKyAgTWFwSXRlcmF0b3ImIG9wZXJhdG9yKysoKSB7CisgICAgbWFwXy0+SW5jcmVhc2VJdGVyYXRvcih0aGlzKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKyAgTWFwSXRlcmF0b3Igb3BlcmF0b3IrKyhpbnQpIHsKKyAgICAvLyBpdGVyXyBpcyBjb3BpZWQgZnJvbSBNYXA8Li4uPjo6aXRlcmF0b3IsIG5vIG5lZWQgdG8KKyAgICAvLyBjb3B5IGZyb20gaXRzIHNlbGYgYWdhaW4uIFVzZSB0aGUgc2FtZSBpbXBsZW1lbnRhdGlvbgorICAgIC8vIHdpdGggb3BlcmF0b3IrKygpCisgICAgbWFwXy0+SW5jcmVhc2VJdGVyYXRvcih0aGlzKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKyAgY29uc3QgTWFwS2V5JiBHZXRLZXkoKSB7CisgICAgcmV0dXJuIGtleV87CisgIH0KKyAgY29uc3QgTWFwVmFsdWVSZWYmIEdldFZhbHVlUmVmKCkgeworICAgIHJldHVybiB2YWx1ZV87CisgIH0KKyAgTWFwVmFsdWVSZWYqIE11dGFibGVWYWx1ZVJlZigpIHsKKyAgICBtYXBfLT5TZXRNYXBEaXJ0eSgpOworICAgIHJldHVybiAmdmFsdWVfOworICB9CisKKyBwcml2YXRlOgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBUPgorICBmcmllbmQgY2xhc3MgaW50ZXJuYWw6OlR5cGVEZWZpbmVkTWFwRmllbGRCYXNlOworICBmcmllbmQgY2xhc3MgaW50ZXJuYWw6OkR5bmFtaWNNYXBGaWVsZDsKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIEtleSwgdHlwZW5hbWUgVCwKKyAgICAgICAgICAgIGludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtLZXlGaWVsZFR5cGUsCisgICAgICAgICAgICBpbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrVmFsdWVGaWVsZFR5cGUsCisgICAgICAgICAgICBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlPgorICBmcmllbmQgY2xhc3MgaW50ZXJuYWw6Ok1hcEZpZWxkOworCisgIC8vIHJlaW50ZXJwcmV0X2Nhc3QgZnJvbSBoZWFwLWFsbG9jYXRlZCBNYXA8Li4uPjo6aXRlcmF0b3IqLiBNYXBJdGVyYXRvciBvd25zCisgIC8vIHRoZSBpdGVyYXRvci4gSXQgaXMgYWxsb2NhdGVkIGJ5IE1hcEZpZWxkPC4uLj46OkluaXRpYWxpemVJdGVyYXRvcigpIGNhbGxlZAorICAvLyBpbiBjb25zdHJ1Y3RvciBhbmQgZGVsZXRlZCBieSBNYXBGaWVsZDwuLi4+OjpEZWxldGVJdGVyYXRvcigpIGNhbGxlZCBpbgorICAvLyBkZXN0cnVjdG9yLgorICB2b2lkKiBpdGVyXzsKKyAgLy8gUG9pbnQgdG8gYSBNYXBGaWVsZCB0byBjYWxsIGhlbHBlciBtZXRob2RzIGltcGxlbWVudGVkIGluIE1hcEZpZWxkLgorICAvLyBNYXBJdGVyYXRvciBkb2VzIG5vdCBvd24gdGhpcyBvYmplY3QuCisgIGludGVybmFsOjpNYXBGaWVsZEJhc2UqIG1hcF87CisgIE1hcEtleSBrZXlfOworICBNYXBWYWx1ZVJlZiB2YWx1ZV87Cit9OworCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfTUFQX0ZJRUxEX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9tYXBfZmllbGRfaW5sLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF9maWVsZF9pbmwuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMTE2Njk3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9tYXBfZmllbGRfaW5sLmgKQEAgLTAsMCArMSw0ODMgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9NQVBfRklFTERfSU5MX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfTUFQX0ZJRUxEX0lOTF9IX18KKworI2luY2x1ZGUgPG1lbW9yeT4KKyNpZm5kZWYgX1NIQVJFRF9QVFJfSAorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaGFyZWRfcHRyLmg+CisjZW5kaWYKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tYXAuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWFwX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21hcF90eXBlX2hhbmRsZXIuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKy8vIFVud3JhcE1hcEtleSB0ZW1wbGF0ZQordGVtcGxhdGU8dHlwZW5hbWUgVD4KK1QgVW53cmFwTWFwS2V5KGNvbnN0IE1hcEtleSYgbWFwX2tleSk7Cit0ZW1wbGF0ZTw+CitpbmxpbmUgaW50MzIgVW53cmFwTWFwS2V5PGludDMyPihjb25zdCBNYXBLZXkmIG1hcF9rZXkpIHsKKyAgcmV0dXJuIG1hcF9rZXkuR2V0SW50MzJWYWx1ZSgpOworfQordGVtcGxhdGU8PgoraW5saW5lIHVpbnQzMiBVbndyYXBNYXBLZXk8dWludDMyPihjb25zdCBNYXBLZXkmIG1hcF9rZXkpIHsKKyAgcmV0dXJuIG1hcF9rZXkuR2V0VUludDMyVmFsdWUoKTsKK30KK3RlbXBsYXRlPD4KK2lubGluZSBpbnQ2NCBVbndyYXBNYXBLZXk8aW50NjQ+KGNvbnN0IE1hcEtleSYgbWFwX2tleSkgeworICByZXR1cm4gbWFwX2tleS5HZXRJbnQ2NFZhbHVlKCk7Cit9Cit0ZW1wbGF0ZTw+CitpbmxpbmUgdWludDY0IFVud3JhcE1hcEtleTx1aW50NjQ+KGNvbnN0IE1hcEtleSYgbWFwX2tleSkgeworICByZXR1cm4gbWFwX2tleS5HZXRVSW50NjRWYWx1ZSgpOworfQordGVtcGxhdGU8PgoraW5saW5lIGJvb2wgVW53cmFwTWFwS2V5PGJvb2w+KGNvbnN0IE1hcEtleSYgbWFwX2tleSkgeworICByZXR1cm4gbWFwX2tleS5HZXRCb29sVmFsdWUoKTsKK30KK3RlbXBsYXRlPD4KK2lubGluZSBzdHJpbmcgVW53cmFwTWFwS2V5PHN0cmluZz4oY29uc3QgTWFwS2V5JiBtYXBfa2V5KSB7CisgIHJldHVybiBtYXBfa2V5LkdldFN0cmluZ1ZhbHVlKCk7Cit9CisKKy8vIFNldE1hcEtleSB0ZW1wbGF0ZQordGVtcGxhdGU8dHlwZW5hbWUgVD4KK2lubGluZSB2b2lkIFNldE1hcEtleShNYXBLZXkqIG1hcF9rZXksIGNvbnN0IFQmIHZhbHVlKTsKK3RlbXBsYXRlPD4KK2lubGluZSB2b2lkIFNldE1hcEtleTxpbnQzMj4oTWFwS2V5KiBtYXBfa2V5LCBjb25zdCBpbnQzMiYgdmFsdWUpIHsKKyAgbWFwX2tleS0+U2V0SW50MzJWYWx1ZSh2YWx1ZSk7Cit9Cit0ZW1wbGF0ZTw+CitpbmxpbmUgdm9pZCBTZXRNYXBLZXk8dWludDMyPihNYXBLZXkqIG1hcF9rZXksIGNvbnN0IHVpbnQzMiYgdmFsdWUpIHsKKyAgbWFwX2tleS0+U2V0VUludDMyVmFsdWUodmFsdWUpOworfQordGVtcGxhdGU8PgoraW5saW5lIHZvaWQgU2V0TWFwS2V5PGludDY0PihNYXBLZXkqIG1hcF9rZXksIGNvbnN0IGludDY0JiB2YWx1ZSkgeworICBtYXBfa2V5LT5TZXRJbnQ2NFZhbHVlKHZhbHVlKTsKK30KK3RlbXBsYXRlPD4KK2lubGluZSB2b2lkIFNldE1hcEtleTx1aW50NjQ+KE1hcEtleSogbWFwX2tleSwgY29uc3QgdWludDY0JiB2YWx1ZSkgeworICBtYXBfa2V5LT5TZXRVSW50NjRWYWx1ZSh2YWx1ZSk7Cit9Cit0ZW1wbGF0ZTw+CitpbmxpbmUgdm9pZCBTZXRNYXBLZXk8Ym9vbD4oTWFwS2V5KiBtYXBfa2V5LCBjb25zdCBib29sJiB2YWx1ZSkgeworICBtYXBfa2V5LT5TZXRCb29sVmFsdWUodmFsdWUpOworfQordGVtcGxhdGU8PgoraW5saW5lIHZvaWQgU2V0TWFwS2V5PHN0cmluZz4oTWFwS2V5KiBtYXBfa2V5LCBjb25zdCBzdHJpbmcmIHZhbHVlKSB7CisgIG1hcF9rZXktPlNldFN0cmluZ1ZhbHVlKHZhbHVlKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tVHlwZURlZmluZWRNYXBGaWVsZEJhc2UtLS0tLS0tLS0tLS0tLS0KK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIFQ+Cit0eXBlbmFtZSBNYXA8S2V5LCBUPjo6Y29uc3RfaXRlcmF0b3ImCitUeXBlRGVmaW5lZE1hcEZpZWxkQmFzZTxLZXksIFQ+OjpJbnRlcm5hbEdldEl0ZXJhdG9yKAorICAgIGNvbnN0IE1hcEl0ZXJhdG9yKiBtYXBfaXRlcikgY29uc3QgeworICByZXR1cm4gKnJlaW50ZXJwcmV0X2Nhc3Q8dHlwZW5hbWUgTWFwPEtleSwgVD46OmNvbnN0X2l0ZXJhdG9yICo+KAorICAgICAgbWFwX2l0ZXItPml0ZXJfKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEtleSwgdHlwZW5hbWUgVD4KK3ZvaWQgVHlwZURlZmluZWRNYXBGaWVsZEJhc2U8S2V5LCBUPjo6TWFwQmVnaW4oTWFwSXRlcmF0b3IqIG1hcF9pdGVyKSBjb25zdCB7CisgIEludGVybmFsR2V0SXRlcmF0b3IobWFwX2l0ZXIpID0gR2V0TWFwKCkuYmVnaW4oKTsKKyAgU2V0TWFwSXRlcmF0b3JWYWx1ZShtYXBfaXRlcik7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIFQ+Cit2b2lkIFR5cGVEZWZpbmVkTWFwRmllbGRCYXNlPEtleSwgVD46Ok1hcEVuZChNYXBJdGVyYXRvciogbWFwX2l0ZXIpIGNvbnN0IHsKKyAgSW50ZXJuYWxHZXRJdGVyYXRvcihtYXBfaXRlcikgPSBHZXRNYXAoKS5lbmQoKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEtleSwgdHlwZW5hbWUgVD4KK2Jvb2wgVHlwZURlZmluZWRNYXBGaWVsZEJhc2U8S2V5LCBUPjo6RXF1YWxJdGVyYXRvcihjb25zdCBNYXBJdGVyYXRvciYgYSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNYXBJdGVyYXRvciYgYikKKyAgICBjb25zdCB7CisgIHJldHVybiBJbnRlcm5hbEdldEl0ZXJhdG9yKCZhKSA9PSBJbnRlcm5hbEdldEl0ZXJhdG9yKCZiKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEtleSwgdHlwZW5hbWUgVD4KK3ZvaWQgVHlwZURlZmluZWRNYXBGaWVsZEJhc2U8S2V5LCBUPjo6SW5jcmVhc2VJdGVyYXRvcihNYXBJdGVyYXRvciogbWFwX2l0ZXIpCisgICAgY29uc3QgeworICArK0ludGVybmFsR2V0SXRlcmF0b3IobWFwX2l0ZXIpOworICBTZXRNYXBJdGVyYXRvclZhbHVlKG1hcF9pdGVyKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEtleSwgdHlwZW5hbWUgVD4KK3ZvaWQgVHlwZURlZmluZWRNYXBGaWVsZEJhc2U8S2V5LCBUPjo6SW5pdGlhbGl6ZUl0ZXJhdG9yKAorICAgIE1hcEl0ZXJhdG9yKiBtYXBfaXRlcikgY29uc3QgeworICBtYXBfaXRlci0+aXRlcl8gPSBuZXcgdHlwZW5hbWUgTWFwPEtleSwgVD46OmNvbnN0X2l0ZXJhdG9yOworICBHT09HTEVfQ0hFQ0sobWFwX2l0ZXItPml0ZXJfICE9IE5VTEwpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBUPgordm9pZCBUeXBlRGVmaW5lZE1hcEZpZWxkQmFzZTxLZXksIFQ+OjpEZWxldGVJdGVyYXRvcihNYXBJdGVyYXRvciogbWFwX2l0ZXIpCisgICAgY29uc3QgeworICBkZWxldGUgcmVpbnRlcnByZXRfY2FzdDx0eXBlbmFtZSBNYXA8S2V5LCBUPjo6Y29uc3RfaXRlcmF0b3IgKj4oCisgICAgICBtYXBfaXRlci0+aXRlcl8pOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBUPgordm9pZCBUeXBlRGVmaW5lZE1hcEZpZWxkQmFzZTxLZXksIFQ+OjpDb3B5SXRlcmF0b3IoCisgICAgTWFwSXRlcmF0b3IqIHRoaXNfaXRlciwKKyAgICBjb25zdCBNYXBJdGVyYXRvciYgdGhhdF9pdGVyKSBjb25zdCB7CisgIEludGVybmFsR2V0SXRlcmF0b3IodGhpc19pdGVyKSA9IEludGVybmFsR2V0SXRlcmF0b3IoJnRoYXRfaXRlcik7CisgIHRoaXNfaXRlci0+a2V5Xy5TZXRUeXBlKHRoYXRfaXRlci5rZXlfLnR5cGUoKSk7CisgIC8vIE1hcFZhbHVlUmVmOjp0eXBlKCkgZmFpbHMgd2hlbiBjb250YWluaW5nIGRhdGEgaXMgbnVsbC4gSG93ZXZlciwgaWYKKyAgLy8gdGhpc19pdGVyIHBvaW50cyB0byBNYXBFbmQsIGRhdGEgY2FuIGJlIG51bGwuCisgIHRoaXNfaXRlci0+dmFsdWVfLlNldFR5cGUoCisgICAgICBzdGF0aWNfY2FzdDxGaWVsZERlc2NyaXB0b3I6OkNwcFR5cGU+KHRoYXRfaXRlci52YWx1ZV8udHlwZV8pKTsKKyAgU2V0TWFwSXRlcmF0b3JWYWx1ZSh0aGlzX2l0ZXIpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIFQsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrS2V5RmllbGRUeXBlLAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga1ZhbHVlRmllbGRUeXBlLAorICAgICAgICAgIGludCBkZWZhdWx0X2VudW1fdmFsdWU+CitNYXBGaWVsZDxLZXksIFQsIGtLZXlGaWVsZFR5cGUsIGtWYWx1ZUZpZWxkVHlwZSwgZGVmYXVsdF9lbnVtX3ZhbHVlPjo6TWFwRmllbGQoKQorICAgIDogZGVmYXVsdF9lbnRyeV8oTlVMTCkge30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEtleSwgdHlwZW5hbWUgVCwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtLZXlGaWVsZFR5cGUsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrVmFsdWVGaWVsZFR5cGUsCisgICAgICAgICAgaW50IGRlZmF1bHRfZW51bV92YWx1ZT4KK01hcEZpZWxkPEtleSwgVCwga0tleUZpZWxkVHlwZSwga1ZhbHVlRmllbGRUeXBlLCBkZWZhdWx0X2VudW1fdmFsdWU+OjpNYXBGaWVsZCgKKyAgICBBcmVuYSogYXJlbmEpCisgICAgOiBUeXBlRGVmaW5lZE1hcEZpZWxkQmFzZTxLZXksIFQ+KGFyZW5hKSwKKyAgICAgIE1hcEZpZWxkTGl0ZTxLZXksIFQsIGtLZXlGaWVsZFR5cGUsIGtWYWx1ZUZpZWxkVHlwZSwgZGVmYXVsdF9lbnVtX3ZhbHVlPigKKyAgICAgICAgICBhcmVuYSksCisgICAgICBkZWZhdWx0X2VudHJ5XyhOVUxMKSB7fQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBULAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga0tleUZpZWxkVHlwZSwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtWYWx1ZUZpZWxkVHlwZSwKKyAgICAgICAgICBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlPgorTWFwRmllbGQ8S2V5LCBULCBrS2V5RmllbGRUeXBlLCBrVmFsdWVGaWVsZFR5cGUsIGRlZmF1bHRfZW51bV92YWx1ZT46Ok1hcEZpZWxkKAorICAgIGNvbnN0IE1lc3NhZ2UqIGRlZmF1bHRfZW50cnkpCisgICAgOiBkZWZhdWx0X2VudHJ5Xyhkb3duX2Nhc3Q8Y29uc3QgRW50cnlUeXBlKj4oZGVmYXVsdF9lbnRyeSkpIHt9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIFQsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrS2V5RmllbGRUeXBlLAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga1ZhbHVlRmllbGRUeXBlLAorICAgICAgICAgIGludCBkZWZhdWx0X2VudW1fdmFsdWU+CitNYXBGaWVsZDxLZXksIFQsIGtLZXlGaWVsZFR5cGUsIGtWYWx1ZUZpZWxkVHlwZSwgZGVmYXVsdF9lbnVtX3ZhbHVlPjo6TWFwRmllbGQoCisgICAgQXJlbmEqIGFyZW5hLCBjb25zdCBNZXNzYWdlKiBkZWZhdWx0X2VudHJ5KQorICAgIDogVHlwZURlZmluZWRNYXBGaWVsZEJhc2U8S2V5LCBUPihhcmVuYSksCisgICAgICBNYXBGaWVsZExpdGU8S2V5LCBULCBrS2V5RmllbGRUeXBlLCBrVmFsdWVGaWVsZFR5cGUsIGRlZmF1bHRfZW51bV92YWx1ZT4oCisgICAgICAgICAgYXJlbmEpLAorICAgICAgZGVmYXVsdF9lbnRyeV8oZG93bl9jYXN0PGNvbnN0IEVudHJ5VHlwZSo+KGRlZmF1bHRfZW50cnkpKSB7fQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBULAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga0tleUZpZWxkVHlwZSwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtWYWx1ZUZpZWxkVHlwZSwKKyAgICAgICAgICBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlPgorTWFwRmllbGQ8S2V5LCBULCBrS2V5RmllbGRUeXBlLCBrVmFsdWVGaWVsZFR5cGUsCisgICAgICAgICBkZWZhdWx0X2VudW1fdmFsdWU+Ojp+TWFwRmllbGQoKSB7fQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBULAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga0tleUZpZWxkVHlwZSwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtWYWx1ZUZpZWxkVHlwZSwKKyAgICAgICAgICBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlPgoraW50CitNYXBGaWVsZDxLZXksIFQsIGtLZXlGaWVsZFR5cGUsIGtWYWx1ZUZpZWxkVHlwZSwKKyAgICAgICAgIGRlZmF1bHRfZW51bV92YWx1ZT46OnNpemUoKSBjb25zdCB7CisgIE1hcEZpZWxkQmFzZTo6U3luY01hcFdpdGhSZXBlYXRlZEZpZWxkKCk7CisgIHJldHVybiBNYXBGaWVsZExpdGVUeXBlOjpHZXRJbnRlcm5hbE1hcCgpLnNpemUoKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEtleSwgdHlwZW5hbWUgVCwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtLZXlGaWVsZFR5cGUsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrVmFsdWVGaWVsZFR5cGUsCisgICAgICAgICAgaW50IGRlZmF1bHRfZW51bV92YWx1ZT4KK3ZvaWQKK01hcEZpZWxkPEtleSwgVCwga0tleUZpZWxkVHlwZSwga1ZhbHVlRmllbGRUeXBlLAorICAgICAgICAgZGVmYXVsdF9lbnVtX3ZhbHVlPjo6Q2xlYXIoKSB7CisgIE1hcEZpZWxkQmFzZTo6U3luY01hcFdpdGhSZXBlYXRlZEZpZWxkKCk7CisgIE1hcEZpZWxkTGl0ZVR5cGU6Ok11dGFibGVJbnRlcm5hbE1hcCgpLT5jbGVhcigpOworICBNYXBGaWVsZEJhc2U6OlNldE1hcERpcnR5KCk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIFQsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrS2V5RmllbGRUeXBlLAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga1ZhbHVlRmllbGRUeXBlLAorICAgICAgICAgIGludCBkZWZhdWx0X2VudW1fdmFsdWU+Cit2b2lkIE1hcEZpZWxkPEtleSwgVCwga0tleUZpZWxkVHlwZSwga1ZhbHVlRmllbGRUeXBlLAorICAgICAgICAgICAgICBkZWZhdWx0X2VudW1fdmFsdWU+OjpTZXRNYXBJdGVyYXRvclZhbHVlKAorICAgICAgICAgICAgICAgICAgTWFwSXRlcmF0b3IqIG1hcF9pdGVyKSBjb25zdCB7CisgIGNvbnN0IE1hcDxLZXksIFQ+JiBtYXAgPSBHZXRNYXAoKTsKKyAgdHlwZW5hbWUgTWFwPEtleSwgVD46OmNvbnN0X2l0ZXJhdG9yIGl0ZXIgPQorICAgICAgVHlwZURlZmluZWRNYXBGaWVsZEJhc2U8S2V5LCBUPjo6SW50ZXJuYWxHZXRJdGVyYXRvcihtYXBfaXRlcik7CisgIGlmIChpdGVyID09IG1hcC5lbmQoKSkgcmV0dXJuOworICBTZXRNYXBLZXkoJm1hcF9pdGVyLT5rZXlfLCBpdGVyLT5maXJzdCk7CisgIG1hcF9pdGVyLT52YWx1ZV8uU2V0VmFsdWUoJml0ZXItPnNlY29uZCk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIFQsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrS2V5RmllbGRUeXBlLAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga1ZhbHVlRmllbGRUeXBlLAorICAgICAgICAgIGludCBkZWZhdWx0X2VudW1fdmFsdWU+Citib29sIE1hcEZpZWxkPEtleSwgVCwga0tleUZpZWxkVHlwZSwga1ZhbHVlRmllbGRUeXBlLAorICAgICAgICAgICAgICBkZWZhdWx0X2VudW1fdmFsdWU+OjpDb250YWluc01hcEtleSgKKyAgICAgICAgICAgICAgICAgIGNvbnN0IE1hcEtleSYgbWFwX2tleSkgY29uc3QgeworICBjb25zdCBNYXA8S2V5LCBUPiYgbWFwID0gR2V0TWFwKCk7CisgIGNvbnN0IEtleSYga2V5ID0gVW53cmFwTWFwS2V5PEtleT4obWFwX2tleSk7CisgIHR5cGVuYW1lIE1hcDxLZXksIFQ+Ojpjb25zdF9pdGVyYXRvciBpdGVyID0gbWFwLmZpbmQoa2V5KTsKKyAgcmV0dXJuIGl0ZXIgIT0gbWFwLmVuZCgpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBULAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga0tleUZpZWxkVHlwZSwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtWYWx1ZUZpZWxkVHlwZSwKKyAgICAgICAgICBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlPgorYm9vbCBNYXBGaWVsZDxLZXksIFQsIGtLZXlGaWVsZFR5cGUsIGtWYWx1ZUZpZWxkVHlwZSwKKyAgICAgICAgICAgICAgZGVmYXVsdF9lbnVtX3ZhbHVlPjo6SW5zZXJ0TWFwVmFsdWUoY29uc3QgTWFwS2V5JiBtYXBfa2V5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYXBWYWx1ZVJlZiogdmFsKSB7CisgIE1hcDxLZXksIFQ+KiBtYXAgPSBNdXRhYmxlTWFwKCk7CisgIGJvb2wgcmVzdWx0ID0gZmFsc2U7CisgIGNvbnN0IEtleSYga2V5ID0gVW53cmFwTWFwS2V5PEtleT4obWFwX2tleSk7CisgIGlmIChtYXAtPmVuZCgpID09IG1hcC0+ZmluZChrZXkpKSB7CisgICAgcmVzdWx0ID0gdHJ1ZTsKKyAgfQorICB2YWwtPlNldFZhbHVlKCYoKCptYXApW2tleV0pKTsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEtleSwgdHlwZW5hbWUgVCwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtLZXlGaWVsZFR5cGUsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrVmFsdWVGaWVsZFR5cGUsCisgICAgICAgICAgaW50IGRlZmF1bHRfZW51bV92YWx1ZT4KK2Jvb2wgTWFwRmllbGQ8S2V5LCBULCBrS2V5RmllbGRUeXBlLCBrVmFsdWVGaWVsZFR5cGUsCisgICAgICAgICAgICAgIGRlZmF1bHRfZW51bV92YWx1ZT46OkRlbGV0ZU1hcFZhbHVlKAorICAgICAgICAgICAgICAgICAgY29uc3QgTWFwS2V5JiBtYXBfa2V5KSB7CisgIGNvbnN0IEtleSYga2V5ID0gVW53cmFwTWFwS2V5PEtleT4obWFwX2tleSk7CisgIHJldHVybiBNdXRhYmxlTWFwKCktPmVyYXNlKGtleSk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIFQsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrS2V5RmllbGRUeXBlLAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga1ZhbHVlRmllbGRUeXBlLAorICAgICAgICAgIGludCBkZWZhdWx0X2VudW1fdmFsdWU+Citjb25zdCBNYXA8S2V5LCBUPiYKK01hcEZpZWxkPEtleSwgVCwga0tleUZpZWxkVHlwZSwga1ZhbHVlRmllbGRUeXBlLAorICAgICAgICAgZGVmYXVsdF9lbnVtX3ZhbHVlPjo6R2V0TWFwKCkgY29uc3QgeworICBNYXBGaWVsZEJhc2U6OlN5bmNNYXBXaXRoUmVwZWF0ZWRGaWVsZCgpOworICByZXR1cm4gTWFwRmllbGRMaXRlVHlwZTo6R2V0SW50ZXJuYWxNYXAoKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEtleSwgdHlwZW5hbWUgVCwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtLZXlGaWVsZFR5cGUsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrVmFsdWVGaWVsZFR5cGUsCisgICAgICAgICAgaW50IGRlZmF1bHRfZW51bV92YWx1ZT4KK01hcDxLZXksIFQ+KgorTWFwRmllbGQ8S2V5LCBULCBrS2V5RmllbGRUeXBlLCBrVmFsdWVGaWVsZFR5cGUsCisgICAgICAgICBkZWZhdWx0X2VudW1fdmFsdWU+OjpNdXRhYmxlTWFwKCkgeworICBNYXBGaWVsZEJhc2U6OlN5bmNNYXBXaXRoUmVwZWF0ZWRGaWVsZCgpOworICBNYXA8S2V5LCBUPiogcmVzdWx0ID0gTWFwRmllbGRMaXRlVHlwZTo6TXV0YWJsZUludGVybmFsTWFwKCk7CisgIE1hcEZpZWxkQmFzZTo6U2V0TWFwRGlydHkoKTsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEtleSwgdHlwZW5hbWUgVCwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtLZXlGaWVsZFR5cGUsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrVmFsdWVGaWVsZFR5cGUsCisgICAgICAgICAgaW50IGRlZmF1bHRfZW51bV92YWx1ZT4KK3ZvaWQKK01hcEZpZWxkPEtleSwgVCwga0tleUZpZWxkVHlwZSwga1ZhbHVlRmllbGRUeXBlLAorICAgICAgICAgZGVmYXVsdF9lbnVtX3ZhbHVlPjo6TWVyZ2VGcm9tKAorICAgIGNvbnN0IE1hcEZpZWxkTGl0ZVR5cGUmIG90aGVyKSB7CisgIGNvbnN0IE1hcEZpZWxkJiBkb3duX290aGVyID0gZG93bl9jYXN0PGNvbnN0IE1hcEZpZWxkJj4ob3RoZXIpOworICBNYXBGaWVsZEJhc2U6OlN5bmNNYXBXaXRoUmVwZWF0ZWRGaWVsZCgpOworICBkb3duX290aGVyLlN5bmNNYXBXaXRoUmVwZWF0ZWRGaWVsZCgpOworICBNYXBGaWVsZExpdGVUeXBlOjpNZXJnZUZyb20ob3RoZXIpOworICBNYXBGaWVsZEJhc2U6OlNldE1hcERpcnR5KCk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIFQsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrS2V5RmllbGRUeXBlLAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga1ZhbHVlRmllbGRUeXBlLAorICAgICAgICAgIGludCBkZWZhdWx0X2VudW1fdmFsdWU+Cit2b2lkCitNYXBGaWVsZDxLZXksIFQsIGtLZXlGaWVsZFR5cGUsIGtWYWx1ZUZpZWxkVHlwZSwKKyAgICAgICAgIGRlZmF1bHRfZW51bV92YWx1ZT46OlN3YXAoCisgICAgTWFwRmllbGRMaXRlVHlwZSogb3RoZXIpIHsKKyAgTWFwRmllbGQqIGRvd25fb3RoZXIgPSBkb3duX2Nhc3Q8TWFwRmllbGQqPihvdGhlcik7CisgIHN0ZDo6c3dhcChNYXBGaWVsZEJhc2U6OnJlcGVhdGVkX2ZpZWxkXywgZG93bl9vdGhlci0+cmVwZWF0ZWRfZmllbGRfKTsKKyAgTWFwRmllbGRMaXRlVHlwZTo6U3dhcChvdGhlcik7CisgIHN0ZDo6c3dhcChNYXBGaWVsZEJhc2U6OnN0YXRlXywgZG93bl9vdGhlci0+c3RhdGVfKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEtleSwgdHlwZW5hbWUgVCwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtLZXlGaWVsZFR5cGUsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrVmFsdWVGaWVsZFR5cGUsCisgICAgICAgICAgaW50IGRlZmF1bHRfZW51bV92YWx1ZT4KK3ZvaWQKK01hcEZpZWxkPEtleSwgVCwga0tleUZpZWxkVHlwZSwga1ZhbHVlRmllbGRUeXBlLAorICAgICAgICAgZGVmYXVsdF9lbnVtX3ZhbHVlPjo6U2V0RW50cnlEZXNjcmlwdG9yKAorICAgIGNvbnN0IERlc2NyaXB0b3IqKiBkZXNjcmlwdG9yKSB7CisgIE1hcEZpZWxkQmFzZTo6ZW50cnlfZGVzY3JpcHRvcl8gPSBkZXNjcmlwdG9yOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBULAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga0tleUZpZWxkVHlwZSwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtWYWx1ZUZpZWxkVHlwZSwKKyAgICAgICAgICBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlPgordm9pZAorTWFwRmllbGQ8S2V5LCBULCBrS2V5RmllbGRUeXBlLCBrVmFsdWVGaWVsZFR5cGUsCisgICAgICAgICBkZWZhdWx0X2VudW1fdmFsdWU+OjpTZXRBc3NpZ25EZXNjcmlwdG9yQ2FsbGJhY2sodm9pZCAoKmNhbGxiYWNrKSgpKSB7CisgIE1hcEZpZWxkQmFzZTo6YXNzaWduX2Rlc2NyaXB0b3JfY2FsbGJhY2tfID0gY2FsbGJhY2s7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIFQsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrS2V5RmllbGRUeXBlLAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga1ZhbHVlRmllbGRUeXBlLAorICAgICAgICAgIGludCBkZWZhdWx0X2VudW1fdmFsdWU+Citjb25zdCBNYXA8S2V5LCBUPiYKK01hcEZpZWxkPEtleSwgVCwga0tleUZpZWxkVHlwZSwga1ZhbHVlRmllbGRUeXBlLAorICAgICAgICAgZGVmYXVsdF9lbnVtX3ZhbHVlPjo6R2V0SW50ZXJuYWxNYXAoKSBjb25zdCB7CisgIHJldHVybiBNYXBGaWVsZExpdGVUeXBlOjpHZXRJbnRlcm5hbE1hcCgpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBULAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga0tleUZpZWxkVHlwZSwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtWYWx1ZUZpZWxkVHlwZSwKKyAgICAgICAgICBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlPgorTWFwPEtleSwgVD4qCitNYXBGaWVsZDxLZXksIFQsIGtLZXlGaWVsZFR5cGUsIGtWYWx1ZUZpZWxkVHlwZSwKKyAgICAgICAgIGRlZmF1bHRfZW51bV92YWx1ZT46Ok11dGFibGVJbnRlcm5hbE1hcCgpIHsKKyAgcmV0dXJuIE1hcEZpZWxkTGl0ZVR5cGU6Ok11dGFibGVJbnRlcm5hbE1hcCgpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBULAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga0tleUZpZWxkVHlwZSwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtWYWx1ZUZpZWxkVHlwZSwKKyAgICAgICAgICBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlPgordm9pZAorTWFwRmllbGQ8S2V5LCBULCBrS2V5RmllbGRUeXBlLCBrVmFsdWVGaWVsZFR5cGUsCisgICAgICAgICBkZWZhdWx0X2VudW1fdmFsdWU+OjpTeW5jUmVwZWF0ZWRGaWVsZFdpdGhNYXBOb0xvY2soKSBjb25zdCB7CisgIGlmIChNYXBGaWVsZEJhc2U6OnJlcGVhdGVkX2ZpZWxkXyA9PSBOVUxMKSB7CisgICAgaWYgKE1hcEZpZWxkQmFzZTo6YXJlbmFfID09IE5VTEwpIHsKKyAgICAgIE1hcEZpZWxkQmFzZTo6cmVwZWF0ZWRfZmllbGRfID0gbmV3IFJlcGVhdGVkUHRyRmllbGQ8TWVzc2FnZT4oKTsKKyAgICB9IGVsc2UgeworICAgICAgTWFwRmllbGRCYXNlOjpyZXBlYXRlZF9maWVsZF8gPQorICAgICAgICAgIEFyZW5hOjpDcmVhdGVNZXNzYWdlPFJlcGVhdGVkUHRyRmllbGQ8TWVzc2FnZT4gPigKKyAgICAgICAgICAgICAgTWFwRmllbGRCYXNlOjphcmVuYV8pOworICAgIH0KKyAgfQorICBjb25zdCBNYXA8S2V5LCBUPiYgbWFwID0gR2V0SW50ZXJuYWxNYXAoKTsKKyAgUmVwZWF0ZWRQdHJGaWVsZDxFbnRyeVR5cGU+KiByZXBlYXRlZF9maWVsZCA9CisgICAgICByZWludGVycHJldF9jYXN0PFJlcGVhdGVkUHRyRmllbGQ8RW50cnlUeXBlPio+KAorICAgICAgICAgIE1hcEZpZWxkQmFzZTo6cmVwZWF0ZWRfZmllbGRfKTsKKworICByZXBlYXRlZF9maWVsZC0+Q2xlYXIoKTsKKworICBmb3IgKHR5cGVuYW1lIE1hcDxLZXksIFQ+Ojpjb25zdF9pdGVyYXRvciBpdCA9IG1hcC5iZWdpbigpOworICAgICAgIGl0ICE9IG1hcC5lbmQoKTsgKytpdCkgeworICAgIEluaXREZWZhdWx0RW50cnlPbmNlKCk7CisgICAgR09PR0xFX0NIRUNLKGRlZmF1bHRfZW50cnlfICE9IE5VTEwpOworICAgIEVudHJ5VHlwZSogbmV3X2VudHJ5ID0KKyAgICAgICAgZG93bl9jYXN0PEVudHJ5VHlwZSo+KGRlZmF1bHRfZW50cnlfLT5OZXcoTWFwRmllbGRCYXNlOjphcmVuYV8pKTsKKyAgICByZXBlYXRlZF9maWVsZC0+QWRkQWxsb2NhdGVkKG5ld19lbnRyeSk7CisgICAgKCpuZXdfZW50cnktPm11dGFibGVfa2V5KCkpID0gaXQtPmZpcnN0OworICAgICgqbmV3X2VudHJ5LT5tdXRhYmxlX3ZhbHVlKCkpID0gaXQtPnNlY29uZDsKKyAgfQorfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBULAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga0tleUZpZWxkVHlwZSwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtWYWx1ZUZpZWxkVHlwZSwKKyAgICAgICAgICBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlPgordm9pZAorTWFwRmllbGQ8S2V5LCBULCBrS2V5RmllbGRUeXBlLCBrVmFsdWVGaWVsZFR5cGUsCisgICAgICAgICBkZWZhdWx0X2VudW1fdmFsdWU+OjpTeW5jTWFwV2l0aFJlcGVhdGVkRmllbGROb0xvY2soKSBjb25zdCB7CisgIE1hcDxLZXksIFQ+KiBtYXAgPSBjb25zdF9jYXN0PE1hcEZpZWxkKj4odGhpcyktPk11dGFibGVJbnRlcm5hbE1hcCgpOworICBSZXBlYXRlZFB0ckZpZWxkPEVudHJ5VHlwZT4qIHJlcGVhdGVkX2ZpZWxkID0KKyAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8UmVwZWF0ZWRQdHJGaWVsZDxFbnRyeVR5cGU+Kj4oCisgICAgICAgICAgTWFwRmllbGRCYXNlOjpyZXBlYXRlZF9maWVsZF8pOworICBHT09HTEVfQ0hFQ0soTWFwRmllbGRCYXNlOjpyZXBlYXRlZF9maWVsZF8gIT0gTlVMTCk7CisgIG1hcC0+Y2xlYXIoKTsKKyAgZm9yICh0eXBlbmFtZSBSZXBlYXRlZFB0ckZpZWxkPEVudHJ5VHlwZT46Oml0ZXJhdG9yIGl0ID0KKyAgICAgICAgICAgcmVwZWF0ZWRfZmllbGQtPmJlZ2luKCk7IGl0ICE9IHJlcGVhdGVkX2ZpZWxkLT5lbmQoKTsgKytpdCkgeworICAgIC8vIENhc3QgaXMgbmVlZGVkIGJlY2F1c2UgTWFwJ3MgYXBpIGFuZCBpbnRlcm5hbCBzdG9yYWdlIGlzIGRpZmZlcmVudCB3aGVuCisgICAgLy8gdmFsdWUgaXMgZW51bS4gRm9yIGVudW0sIHdlIGNhbm5vdCBjYXN0IGFuIGludCB0byBlbnVtLiBUaHVzLCB3ZSBoYXZlIHRvCisgICAgLy8gY29weSB2YWx1ZS4gRm9yIG90aGVyIHR5cGVzLCB0aGV5IGhhdmUgc2FtZSBleHBvc2VkIGFwaSB0eXBlIGFuZCBpbnRlcm5hbAorICAgIC8vIHN0b3JlZCB0eXBlLiBXZSBzaG91bGQgbm90IGludHJvZHVjZSB2YWx1ZSBjb3B5IGZvciB0aGVtLiBXZSBhY2hpZXZlIHRoaXMKKyAgICAvLyBieSBjYXN0aW5nIHRvIHZhbHVlIGZvciBlbnVtIHdoaWxlIGNhc3RpbmcgdG8gcmVmZXJlbmNlIGZvciBvdGhlciB0eXBlcy4KKyAgICAoKm1hcClbaXQtPmtleSgpXSA9IHN0YXRpY19jYXN0PENhc3RWYWx1ZVR5cGU+KGl0LT52YWx1ZSgpKTsKKyAgfQorfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBULAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga0tleUZpZWxkVHlwZSwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtWYWx1ZUZpZWxkVHlwZSwKKyAgICAgICAgICBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlPgoraW50CitNYXBGaWVsZDxLZXksIFQsIGtLZXlGaWVsZFR5cGUsIGtWYWx1ZUZpZWxkVHlwZSwKKyAgICAgICAgIGRlZmF1bHRfZW51bV92YWx1ZT46OlNwYWNlVXNlZEV4Y2x1ZGluZ1NlbGZOb0xvY2soKSBjb25zdCB7CisgIGludCBzaXplID0gMDsKKyAgaWYgKE1hcEZpZWxkQmFzZTo6cmVwZWF0ZWRfZmllbGRfICE9IE5VTEwpIHsKKyAgICBzaXplICs9IE1hcEZpZWxkQmFzZTo6cmVwZWF0ZWRfZmllbGRfLT5TcGFjZVVzZWRFeGNsdWRpbmdTZWxmKCk7CisgIH0KKyAgTWFwPEtleSwgVD4qIG1hcCA9IGNvbnN0X2Nhc3Q8TWFwRmllbGQqPih0aGlzKS0+TXV0YWJsZUludGVybmFsTWFwKCk7CisgIHNpemUgKz0gc2l6ZW9mKCptYXApOworICBmb3IgKHR5cGVuYW1lIE1hcDxLZXksIFQ+OjppdGVyYXRvciBpdCA9IG1hcC0+YmVnaW4oKTsKKyAgICAgICBpdCAhPSBtYXAtPmVuZCgpOyArK2l0KSB7CisgICAgc2l6ZSArPSBLZXlUeXBlSGFuZGxlcjo6U3BhY2VVc2VkSW5NYXAoaXQtPmZpcnN0KTsKKyAgICBzaXplICs9IFZhbHVlVHlwZUhhbmRsZXI6OlNwYWNlVXNlZEluTWFwKGl0LT5zZWNvbmQpOworICB9CisgIHJldHVybiBzaXplOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBULAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga0tleUZpZWxkVHlwZSwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtWYWx1ZUZpZWxkVHlwZSwKKyAgICAgICAgICBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlPgordm9pZAorTWFwRmllbGQ8S2V5LCBULCBrS2V5RmllbGRUeXBlLCBrVmFsdWVGaWVsZFR5cGUsCisgICAgICAgICBkZWZhdWx0X2VudW1fdmFsdWU+OjpJbml0RGVmYXVsdEVudHJ5T25jZSgpCisgICAgY29uc3QgeworICBpZiAoZGVmYXVsdF9lbnRyeV8gPT0gTlVMTCkgeworICAgIE1hcEZpZWxkQmFzZTo6SW5pdE1ldGFkYXRhT25jZSgpOworICAgIEdPT0dMRV9DSEVDSygqTWFwRmllbGRCYXNlOjplbnRyeV9kZXNjcmlwdG9yXyAhPSBOVUxMKTsKKyAgICBkZWZhdWx0X2VudHJ5XyA9IGRvd25fY2FzdDxjb25zdCBFbnRyeVR5cGUqPigKKyAgICAgICAgTWVzc2FnZUZhY3Rvcnk6OmdlbmVyYXRlZF9mYWN0b3J5KCktPkdldFByb3RvdHlwZSgKKyAgICAgICAgICAgICpNYXBGaWVsZEJhc2U6OmVudHJ5X2Rlc2NyaXB0b3JfKSk7CisgIH0KK30KKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfTUFQX0ZJRUxEX0lOTF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvbWFwX2ZpZWxkX2xpdGUuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvbWFwX2ZpZWxkX2xpdGUuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NjBkYWU1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9tYXBfZmllbGRfbGl0ZS5oCkBAIC0wLDAgKzEsMjc4IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfTUFQX0ZJRUxEX0xJVEVfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9NQVBfRklFTERfTElURV9IX18KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tYXAuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWFwX2VudHJ5X2xpdGUuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKworLy8gVGhpcyBjbGFzcyBwcm92aWRlcyBhY2Nlc3NzIHRvIG1hcCBmaWVsZCB1c2luZyBnZW5lcmF0ZWQgYXBpLiBJdCBpcyB1c2VkIGZvcgorLy8gaW50ZXJuYWwgZ2VuZXJhdGVkIG1lc3NhZ2UgaW1wbGVudGF0aW9uIG9ubHkuIFVzZXJzIHNob3VsZCBuZXZlciB1c2UgdGhpcworLy8gZGlyZWN0bHkuCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBULAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga2V5X3dpcmVfdHlwZSwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIHZhbHVlX3dpcmVfdHlwZSwKKyAgICAgICAgICBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlID0gMD4KK2NsYXNzIE1hcEZpZWxkTGl0ZSB7CisgIC8vIERlZmluZSBtZXNzYWdlIHR5cGUgZm9yIGludGVybmFsIHJlcGVhdGVkIGZpZWxkLgorICB0eXBlZGVmIE1hcEVudHJ5TGl0ZTxLZXksIFQsIGtleV93aXJlX3R5cGUsIHZhbHVlX3dpcmVfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdF9lbnVtX3ZhbHVlPiBFbnRyeVR5cGU7CisKKyBwdWJsaWM6CisgIE1hcEZpZWxkTGl0ZSgpOworICBleHBsaWNpdCBNYXBGaWVsZExpdGUoQXJlbmEqIGFyZW5hKTsKKyAgdmlydHVhbCB+TWFwRmllbGRMaXRlKCk7CisKKyAgLy8gQWNjZXNzb3JzCisgIHZpcnR1YWwgY29uc3QgTWFwPEtleSwgVD4mIEdldE1hcCgpIGNvbnN0OworICB2aXJ0dWFsIE1hcDxLZXksIFQ+KiBNdXRhYmxlTWFwKCk7CisKKyAgLy8gQ29udmVuaWVudCBtZXRob2RzIGZvciBnZW5lcmF0ZWQgbWVzc2FnZSBpbXBsZW1lbnRhdGlvbi4KKyAgdmlydHVhbCBpbnQgc2l6ZSgpIGNvbnN0OworICB2aXJ0dWFsIHZvaWQgQ2xlYXIoKTsKKyAgdmlydHVhbCB2b2lkIE1lcmdlRnJvbShjb25zdCBNYXBGaWVsZExpdGUmIG90aGVyKTsKKyAgdmlydHVhbCB2b2lkIFN3YXAoTWFwRmllbGRMaXRlKiBvdGhlcik7CisKKyAgLy8gU2V0IGRlZmF1bHQgZW51bSB2YWx1ZSBvbmx5IGZvciBwcm90bzIgbWFwIGZpZWxkIHdob3NlIHZhbHVlIGlzIGVudW0gdHlwZS4KKyAgdm9pZCBTZXREZWZhdWx0RW51bVZhbHVlKCk7CisKKyAgLy8gVXNlZCBpbiB0aGUgaW1wbGVtZW50YXRpb24gb2YgcGFyc2luZy4gQ2FsbGVyIHNob3VsZCB0YWtlIHRoZSBvd25lcnNoaXAuCisgIEVudHJ5VHlwZSogTmV3RW50cnkoKSBjb25zdDsKKyAgLy8gVXNlZCBpbiB0aGUgaW1wbGVtZW50YXRpb24gb2Ygc2VyaWFsaXppbmcgZW51bSB2YWx1ZSB0eXBlLiBDYWxsZXIgc2hvdWxkCisgIC8vIHRha2UgdGhlIG93bmVyc2hpcC4KKyAgRW50cnlUeXBlKiBOZXdFbnVtRW50cnlXcmFwcGVyKGNvbnN0IEtleSYga2V5LCBjb25zdCBUIHQpIGNvbnN0OworICAvLyBVc2VkIGluIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiBzZXJpYWxpemluZyBvdGhlciB2YWx1ZSB0eXBlcy4gQ2FsbGVyIHNob3VsZAorICAvLyB0YWtlIHRoZSBvd25lcnNoaXAuCisgIEVudHJ5VHlwZSogTmV3RW50cnlXcmFwcGVyKGNvbnN0IEtleSYga2V5LCBjb25zdCBUJiB0KSBjb25zdDsKKworIHByb3RlY3RlZDoKKyAgLy8gQ29udmVuaWVudCBtZXRob2RzIHRvIGdldCBpbnRlcm5hbCBnb29nbGU6OnByb3RvYnVmOjpNYXAKKyAgdmlydHVhbCBjb25zdCBNYXA8S2V5LCBUPiYgR2V0SW50ZXJuYWxNYXAoKSBjb25zdDsKKyAgdmlydHVhbCBNYXA8S2V5LCBUPiogTXV0YWJsZUludGVybmFsTWFwKCk7CisKKyBwcml2YXRlOgorICB0eXBlZGVmIHZvaWQgRGVzdHJ1Y3RvclNraXBwYWJsZV87CisKKyAgQXJlbmEqIGFyZW5hXzsKKyAgTWFwPEtleSwgVD4qIG1hcF87CisKKyAgZnJpZW5kIGNsYXNzIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmE7Cit9OworCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBULAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga2V5X3dpcmVfdHlwZSwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIHZhbHVlX3dpcmVfdHlwZSwKKyAgICAgICAgICBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlPgorTWFwRmllbGRMaXRlPEtleSwgVCwga2V5X3dpcmVfdHlwZSwgdmFsdWVfd2lyZV90eXBlLAorICAgICAgICAgICAgIGRlZmF1bHRfZW51bV92YWx1ZT46Ok1hcEZpZWxkTGl0ZSgpCisgICAgOiBhcmVuYV8oTlVMTCkgeworICBtYXBfID0gbmV3IE1hcDxLZXksIFQ+OworICBTZXREZWZhdWx0RW51bVZhbHVlKCk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIFQsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrZXlfd2lyZV90eXBlLAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUgdmFsdWVfd2lyZV90eXBlLAorICAgICAgICAgIGludCBkZWZhdWx0X2VudW1fdmFsdWU+CitNYXBGaWVsZExpdGU8S2V5LCBULCBrZXlfd2lyZV90eXBlLCB2YWx1ZV93aXJlX3R5cGUsCisgICAgICAgICAgICAgZGVmYXVsdF9lbnVtX3ZhbHVlPjo6TWFwRmllbGRMaXRlKEFyZW5hKiBhcmVuYSkKKyAgOiBhcmVuYV8oYXJlbmEpIHsKKyAgbWFwXyA9IEFyZW5hOjpDcmVhdGVNZXNzYWdlPE1hcDxLZXksIFQ+ID4oYXJlbmEpOworICBTZXREZWZhdWx0RW51bVZhbHVlKCk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIFQsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrZXlfd2lyZV90eXBlLAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUgdmFsdWVfd2lyZV90eXBlLAorICAgICAgICAgIGludCBkZWZhdWx0X2VudW1fdmFsdWU+CitNYXBGaWVsZExpdGU8S2V5LCBULCBrZXlfd2lyZV90eXBlLCB2YWx1ZV93aXJlX3R5cGUsCisgICAgICAgICAgICAgZGVmYXVsdF9lbnVtX3ZhbHVlPjo6fk1hcEZpZWxkTGl0ZSgpIHsKKyAgZGVsZXRlIG1hcF87Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIFQsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrZXlfd2lyZV90eXBlLAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUgdmFsdWVfd2lyZV90eXBlLAorICAgICAgICAgIGludCBkZWZhdWx0X2VudW1fdmFsdWU+Citjb25zdCBNYXA8S2V5LCBUPiYKK01hcEZpZWxkTGl0ZTxLZXksIFQsIGtleV93aXJlX3R5cGUsIHZhbHVlX3dpcmVfdHlwZSwKKyAgICAgICAgICAgICBkZWZhdWx0X2VudW1fdmFsdWU+OjpHZXRNYXAoKSBjb25zdCB7CisgIHJldHVybiAqbWFwXzsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEtleSwgdHlwZW5hbWUgVCwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtleV93aXJlX3R5cGUsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSB2YWx1ZV93aXJlX3R5cGUsCisgICAgICAgICAgaW50IGRlZmF1bHRfZW51bV92YWx1ZT4KK01hcDxLZXksIFQ+KgorTWFwRmllbGRMaXRlPEtleSwgVCwga2V5X3dpcmVfdHlwZSwgdmFsdWVfd2lyZV90eXBlLAorICAgICAgICAgICAgIGRlZmF1bHRfZW51bV92YWx1ZT46Ok11dGFibGVNYXAoKSB7CisgIHJldHVybiBtYXBfOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBULAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga2V5X3dpcmVfdHlwZSwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIHZhbHVlX3dpcmVfdHlwZSwKKyAgICAgICAgICBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlPgoraW50CitNYXBGaWVsZExpdGU8S2V5LCBULCBrZXlfd2lyZV90eXBlLCB2YWx1ZV93aXJlX3R5cGUsCisgICAgICAgICAgICAgZGVmYXVsdF9lbnVtX3ZhbHVlPjo6c2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIG1hcF8tPnNpemUoKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEtleSwgdHlwZW5hbWUgVCwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtleV93aXJlX3R5cGUsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSB2YWx1ZV93aXJlX3R5cGUsCisgICAgICAgICAgaW50IGRlZmF1bHRfZW51bV92YWx1ZT4KK3ZvaWQKK01hcEZpZWxkTGl0ZTxLZXksIFQsIGtleV93aXJlX3R5cGUsIHZhbHVlX3dpcmVfdHlwZSwKKyAgICAgICAgICAgICBkZWZhdWx0X2VudW1fdmFsdWU+OjpDbGVhcigpIHsKKyAgbWFwXy0+Y2xlYXIoKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEtleSwgdHlwZW5hbWUgVCwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtleV93aXJlX3R5cGUsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSB2YWx1ZV93aXJlX3R5cGUsCisgICAgICAgICAgaW50IGRlZmF1bHRfZW51bV92YWx1ZT4KK3ZvaWQKK01hcEZpZWxkTGl0ZTxLZXksIFQsIGtleV93aXJlX3R5cGUsIHZhbHVlX3dpcmVfdHlwZSwKKyAgICAgICAgICAgICBkZWZhdWx0X2VudW1fdmFsdWU+OjpNZXJnZUZyb20oCisgICAgY29uc3QgTWFwRmllbGRMaXRlJiBvdGhlcikgeworICBmb3IgKHR5cGVuYW1lIE1hcDxLZXksIFQ+Ojpjb25zdF9pdGVyYXRvciBpdCA9IG90aGVyLm1hcF8tPmJlZ2luKCk7CisgICAgICAgaXQgIT0gb3RoZXIubWFwXy0+ZW5kKCk7ICsraXQpIHsKKyAgICAoKm1hcF8pW2l0LT5maXJzdF0gPSBpdC0+c2Vjb25kOworICB9Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIFQsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrZXlfd2lyZV90eXBlLAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUgdmFsdWVfd2lyZV90eXBlLAorICAgICAgICAgIGludCBkZWZhdWx0X2VudW1fdmFsdWU+Cit2b2lkCitNYXBGaWVsZExpdGU8S2V5LCBULCBrZXlfd2lyZV90eXBlLCB2YWx1ZV93aXJlX3R5cGUsCisgICAgICAgICAgICAgZGVmYXVsdF9lbnVtX3ZhbHVlPjo6U3dhcCgKKyAgICBNYXBGaWVsZExpdGUqIG90aGVyKSB7CisgIHN0ZDo6c3dhcChtYXBfLCBvdGhlci0+bWFwXyk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIFQsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrZXlfd2lyZV90eXBlLAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUgdmFsdWVfd2lyZV90eXBlLAorICAgICAgICAgIGludCBkZWZhdWx0X2VudW1fdmFsdWU+Cit2b2lkCitNYXBGaWVsZExpdGU8S2V5LCBULCBrZXlfd2lyZV90eXBlLCB2YWx1ZV93aXJlX3R5cGUsCisgICAgICAgICAgICAgZGVmYXVsdF9lbnVtX3ZhbHVlPjo6U2V0RGVmYXVsdEVudW1WYWx1ZSgpIHsKKyAgTXV0YWJsZUludGVybmFsTWFwKCktPlNldERlZmF1bHRFbnVtVmFsdWUoZGVmYXVsdF9lbnVtX3ZhbHVlKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEtleSwgdHlwZW5hbWUgVCwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtleV93aXJlX3R5cGUsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSB2YWx1ZV93aXJlX3R5cGUsCisgICAgICAgICAgaW50IGRlZmF1bHRfZW51bV92YWx1ZT4KK2NvbnN0IE1hcDxLZXksIFQ+JgorTWFwRmllbGRMaXRlPEtleSwgVCwga2V5X3dpcmVfdHlwZSwgdmFsdWVfd2lyZV90eXBlLAorICAgICAgICAgICAgIGRlZmF1bHRfZW51bV92YWx1ZT46OkdldEludGVybmFsTWFwKCkgY29uc3QgeworICByZXR1cm4gKm1hcF87Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIFQsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBrZXlfd2lyZV90eXBlLAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUgdmFsdWVfd2lyZV90eXBlLAorICAgICAgICAgIGludCBkZWZhdWx0X2VudW1fdmFsdWU+CitNYXA8S2V5LCBUPioKK01hcEZpZWxkTGl0ZTxLZXksIFQsIGtleV93aXJlX3R5cGUsIHZhbHVlX3dpcmVfdHlwZSwKKyAgICAgICAgICAgICBkZWZhdWx0X2VudW1fdmFsdWU+OjpNdXRhYmxlSW50ZXJuYWxNYXAoKSB7CisgIHJldHVybiBtYXBfOworfQorCisjZGVmaW5lIEVudHJ5VHlwZSBcCisgIE1hcEVudHJ5TGl0ZTxLZXksIFQsIGtleV93aXJlX3R5cGUsIHZhbHVlX3dpcmVfdHlwZSwgZGVmYXVsdF9lbnVtX3ZhbHVlPgorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBULAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUga2V5X3dpcmVfdHlwZSwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIHZhbHVlX3dpcmVfdHlwZSwKKyAgICAgICAgICBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlPgorRW50cnlUeXBlKgorTWFwRmllbGRMaXRlPEtleSwgVCwga2V5X3dpcmVfdHlwZSwgdmFsdWVfd2lyZV90eXBlLAorICAgICAgICAgICAgIGRlZmF1bHRfZW51bV92YWx1ZT46Ok5ld0VudHJ5KCkgY29uc3QgeworICBpZiAoYXJlbmFfID09IE5VTEwpIHsKKyAgICByZXR1cm4gbmV3IEVudHJ5VHlwZSgpOworICB9IGVsc2UgeworICAgIHJldHVybiBBcmVuYTo6Q3JlYXRlTWVzc2FnZTxFbnRyeVR5cGU+KGFyZW5hXyk7CisgIH0KK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEtleSwgdHlwZW5hbWUgVCwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtleV93aXJlX3R5cGUsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSB2YWx1ZV93aXJlX3R5cGUsCisgICAgICAgICAgaW50IGRlZmF1bHRfZW51bV92YWx1ZT4KK0VudHJ5VHlwZSoKK01hcEZpZWxkTGl0ZTxLZXksIFQsIGtleV93aXJlX3R5cGUsIHZhbHVlX3dpcmVfdHlwZSwKKyAgICAgICAgICAgICBkZWZhdWx0X2VudW1fdmFsdWU+OjpOZXdFbnVtRW50cnlXcmFwcGVyKGNvbnN0IEtleSYga2V5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVCB0KSBjb25zdCB7CisgIHJldHVybiBFbnRyeVR5cGU6OkVudW1XcmFwKGtleSwgdCwgYXJlbmFfKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEtleSwgdHlwZW5hbWUgVCwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGtleV93aXJlX3R5cGUsCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSB2YWx1ZV93aXJlX3R5cGUsCisgICAgICAgICAgaW50IGRlZmF1bHRfZW51bV92YWx1ZT4KK0VudHJ5VHlwZSoKK01hcEZpZWxkTGl0ZTxLZXksIFQsIGtleV93aXJlX3R5cGUsIHZhbHVlX3dpcmVfdHlwZSwKKyAgICAgICAgICAgICBkZWZhdWx0X2VudW1fdmFsdWU+OjpOZXdFbnRyeVdyYXBwZXIoY29uc3QgS2V5JiBrZXksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFQmIHQpIGNvbnN0IHsKKyAgcmV0dXJuIEVudHJ5VHlwZTo6V3JhcChrZXksIHQsIGFyZW5hXyk7Cit9CisKKyN1bmRlZiBFbnRyeVR5cGUKKworLy8gVHJ1ZSBpZiBJc0luaXRpYWxpemVkKCkgaXMgdHJ1ZSBmb3IgdmFsdWUgZmllbGQgaW4gYWxsIGVsZW1lbnRzIG9mIHQuIFQgaXMKKy8vIGV4cGVjdGVkIHRvIGJlIG1lc3NhZ2UuICBJdCdzIHVzZWZ1bCB0byBoYXZlIHRoaXMgaGVscGVyIGhlcmUgdG8ga2VlcCB0aGUKKy8vIHByb3RvYnVmIGNvbXBpbGVyIGZyb20gZXZlciBoYXZpbmcgdG8gZW1pdCBsb29wcyBpbiBJc0luaXRpYWxpemVkKCkgbWV0aG9kcy4KKy8vIFdlIHdhbnQgdGhlIEMrKyBjb21waWxlciB0byBpbmxpbmUgdGhpcyBvciBub3QgYXMgaXQgc2VlcyBmaXQuCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBUPgorYm9vbCBBbGxBcmVJbml0aWFsaXplZChjb25zdCBNYXA8S2V5LCBUPiYgdCkgeworICBmb3IgKHR5cGVuYW1lIE1hcDxLZXksIFQ+Ojpjb25zdF9pdGVyYXRvciBpdCA9IHQuYmVnaW4oKTsgaXQgIT0gdC5lbmQoKTsKKyAgICAgICArK2l0KSB7CisgICAgaWYgKCFpdC0+c2Vjb25kLklzSW5pdGlhbGl6ZWQoKSkgcmV0dXJuIGZhbHNlOworICB9CisgIHJldHVybiB0cnVlOworfQorCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9NQVBfRklFTERfTElURV9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvbWFwX2ZpZWxkX3Rlc3QuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF9maWVsZF90ZXN0LmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJmZjFkNmIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF9maWVsZF90ZXN0LmNjCkBAIC0wLDAgKzEsNDk0IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2luY2x1ZGUgPG1hcD4KKyNpbmNsdWRlIDxtZW1vcnk+CisjaWZuZGVmIF9TSEFSRURfUFRSX0gKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc2hhcmVkX3B0ci5oPgorI2VuZGlmCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbG9nZ2luZy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvYXJlbmEuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWFwLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2FyZW5hX3Rlc3RfdXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tYXBfdW5pdHRlc3QucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWFwX3Rlc3RfdXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tYXBfZmllbGRfaW5sLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21lc3NhZ2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcmVwZWF0ZWRfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZV9pbmwuaD4KKyNpbmNsdWRlIDxndGVzdC9ndGVzdC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKK3VzaW5nIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM7CisKK2NsYXNzIE1hcEZpZWxkQmFzZVN0dWIgOiBwdWJsaWMgTWFwRmllbGRCYXNlIHsKKyBwdWJsaWM6CisgIHR5cGVkZWYgdm9pZCBJbnRlcm5hbEFyZW5hQ29uc3RydWN0YWJsZV87CisgIHR5cGVkZWYgdm9pZCBEZXN0cnVjdG9yU2tpcHBhYmxlXzsKKyAgTWFwRmllbGRCYXNlU3R1YigpIHt9CisgIGV4cGxpY2l0IE1hcEZpZWxkQmFzZVN0dWIoQXJlbmEqIGFyZW5hKSA6IE1hcEZpZWxkQmFzZShhcmVuYSkge30KKyAgdm9pZCBTeW5jUmVwZWF0ZWRGaWVsZFdpdGhNYXAoKSBjb25zdCB7CisgICAgTWFwRmllbGRCYXNlOjpTeW5jUmVwZWF0ZWRGaWVsZFdpdGhNYXAoKTsKKyAgfQorICB2b2lkIFN5bmNNYXBXaXRoUmVwZWF0ZWRGaWVsZCgpIGNvbnN0IHsKKyAgICBNYXBGaWVsZEJhc2U6OlN5bmNNYXBXaXRoUmVwZWF0ZWRGaWVsZCgpOworICB9CisgIC8vIEdldCB1bmRlcmxpbmVkIHJlcGVhdGVkIGZpZWxkIHdpdGhvdXQgc3luY2hyb25pemluZyBtYXAuCisgIFJlcGVhdGVkUHRyRmllbGQ8TWVzc2FnZT4qIEludGVybmFsUmVwZWF0ZWRGaWVsZCgpIHsKKyAgICByZXR1cm4gcmVwZWF0ZWRfZmllbGRfOworICB9CisgIGJvb2wgSXNNYXBDbGVhbigpIHsgcmV0dXJuIHN0YXRlXyAhPSAwOyB9CisgIGJvb2wgSXNSZXBlYXRlZENsZWFuKCkgeyByZXR1cm4gc3RhdGVfICE9IDE7IH0KKyAgdm9pZCBTZXRNYXBEaXJ0eSgpIHsgc3RhdGVfID0gMDsgfQorICB2b2lkIFNldFJlcGVhdGVkRGlydHkoKSB7IHN0YXRlXyA9IDE7IH0KKyAgYm9vbCBDb250YWluc01hcEtleShjb25zdCBNYXBLZXkmIG1hcF9rZXkpIGNvbnN0IHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgYm9vbCBJbnNlcnRNYXBWYWx1ZShjb25zdCBNYXBLZXkmIG1hcF9rZXksIE1hcFZhbHVlUmVmKiB2YWwpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgYm9vbCBEZWxldGVNYXBWYWx1ZShjb25zdCBNYXBLZXkmIG1hcF9rZXkpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgYm9vbCBFcXVhbEl0ZXJhdG9yKGNvbnN0IE1hcEl0ZXJhdG9yJiBhLCBjb25zdCBNYXBJdGVyYXRvciYgYikgY29uc3QgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICBpbnQgc2l6ZSgpIGNvbnN0IHsgcmV0dXJuIDA7IH0KKyAgdm9pZCBNYXBCZWdpbihNYXBJdGVyYXRvciogbWFwX2l0ZXIpIGNvbnN0IHt9CisgIHZvaWQgTWFwRW5kKE1hcEl0ZXJhdG9yKiBtYXBfaXRlcikgY29uc3Qge30KKyAgdm9pZCBJbml0aWFsaXplSXRlcmF0b3IoTWFwSXRlcmF0b3IqIG1hcF9pdGVyKSBjb25zdCB7fQorICB2b2lkIERlbGV0ZUl0ZXJhdG9yKE1hcEl0ZXJhdG9yKiBtYXBfaXRlcikgY29uc3Qge30KKyAgdm9pZCBDb3B5SXRlcmF0b3IoTWFwSXRlcmF0b3IqIHRoaXNfaXRlcmF0b3IsCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1hcEl0ZXJhdG9yJiBvdGhlcl9pdGVyYXRvcikgY29uc3Qge30KKyAgdm9pZCBJbmNyZWFzZUl0ZXJhdG9yKE1hcEl0ZXJhdG9yKiBtYXBfaXRlcikgY29uc3Qge30KKyAgdm9pZCBTZXREZWZhdWx0TWVzc2FnZUVudHJ5KGNvbnN0IE1lc3NhZ2UqIG1lc3NhZ2UpIGNvbnN0IHt9CisgIGNvbnN0IE1lc3NhZ2UqIEdldERlZmF1bHRNZXNzYWdlRW50cnkoKSBjb25zdCB7IHJldHVybiBOVUxMOyB9Cit9OworCitjbGFzcyBNYXBGaWVsZEJhc2VQcmltaXRpdmVUZXN0IDogcHVibGljIDo6dGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICB0eXBlZGVmIE1hcEZpZWxkPGludDMyLCBpbnQzMiwgV2lyZUZvcm1hdExpdGU6OlRZUEVfSU5UMzIsCisgICAgICAgICAgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OlRZUEVfSU5UMzIsIGZhbHNlPiBNYXBGaWVsZFR5cGU7CisKKyAgTWFwRmllbGRCYXNlUHJpbWl0aXZlVGVzdCgpIHsKKyAgICAvLyBHZXQgZGVzY3JpcHRvcnMKKyAgICBtYXBfZGVzY3JpcHRvcl8gPSB1bml0dGVzdDo6VGVzdE1hcDo6ZGVzY3JpcHRvcigpCisgICAgICAgICAgICAgICAgICAgICAgICAgIC0+RmluZEZpZWxkQnlOYW1lKCJtYXBfaW50MzJfaW50MzIiKQorICAgICAgICAgICAgICAgICAgICAgICAgICAtPm1lc3NhZ2VfdHlwZSgpOworICAgIGtleV9kZXNjcmlwdG9yXyA9IG1hcF9kZXNjcmlwdG9yXy0+RmluZEZpZWxkQnlOYW1lKCJrZXkiKTsKKyAgICB2YWx1ZV9kZXNjcmlwdG9yXyA9IG1hcF9kZXNjcmlwdG9yXy0+RmluZEZpZWxkQnlOYW1lKCJ2YWx1ZSIpOworCisgICAgLy8gQnVpbGQgbWFwIGZpZWxkCisgICAgZGVmYXVsdF9lbnRyeV8gPQorICAgICAgICBNZXNzYWdlRmFjdG9yeTo6Z2VuZXJhdGVkX2ZhY3RvcnkoKS0+R2V0UHJvdG90eXBlKG1hcF9kZXNjcmlwdG9yXyk7CisgICAgbWFwX2ZpZWxkXy5yZXNldChuZXcgTWFwRmllbGRUeXBlKGRlZmF1bHRfZW50cnlfKSk7CisgICAgbWFwX2ZpZWxkX2Jhc2VfID0gbWFwX2ZpZWxkXy5nZXQoKTsKKyAgICBtYXBfID0gbWFwX2ZpZWxkXy0+TXV0YWJsZU1hcCgpOworICAgIGluaXRpYWxfdmFsdWVfbWFwX1swXSA9IDEwMDsKKyAgICBpbml0aWFsX3ZhbHVlX21hcF9bMV0gPSAxMDE7CisgICAgbWFwXy0+aW5zZXJ0KGluaXRpYWxfdmFsdWVfbWFwXy5iZWdpbigpLCBpbml0aWFsX3ZhbHVlX21hcF8uZW5kKCkpOworICAgIEVYUEVDVF9FUSgyLCBtYXBfLT5zaXplKCkpOworICB9CisKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxNYXBGaWVsZFR5cGU+IG1hcF9maWVsZF87CisgIE1hcEZpZWxkQmFzZSogbWFwX2ZpZWxkX2Jhc2VfOworICBNYXA8aW50MzIsIGludDMyPiogbWFwXzsKKyAgY29uc3QgRGVzY3JpcHRvciogbWFwX2Rlc2NyaXB0b3JfOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGtleV9kZXNjcmlwdG9yXzsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiB2YWx1ZV9kZXNjcmlwdG9yXzsKKyAgY29uc3QgTWVzc2FnZSogZGVmYXVsdF9lbnRyeV87CisgIHN0ZDo6bWFwPGludDMyLCBpbnQzMj4gaW5pdGlhbF92YWx1ZV9tYXBfOyAgLy8gY29weSBvZiBpbml0aWFsIHZhbHVlcyBpbnNlcnRlZAorfTsKKworVEVTVF9GKE1hcEZpZWxkQmFzZVByaW1pdGl2ZVRlc3QsIFNwYWNlVXNlZEV4Y2x1ZGluZ1NlbGYpIHsKKyAgRVhQRUNUX0xUKDAsIG1hcF9maWVsZF9iYXNlXy0+U3BhY2VVc2VkRXhjbHVkaW5nU2VsZigpKTsKK30KKworVEVTVF9GKE1hcEZpZWxkQmFzZVByaW1pdGl2ZVRlc3QsIEdldFJlcGVhdGVkRmllbGQpIHsKKyAgY29uc3QgUmVwZWF0ZWRQdHJGaWVsZDxNZXNzYWdlPiYgcmVwZWF0ZWQgPQorICAgICAgcmVpbnRlcnByZXRfY2FzdDxjb25zdCBSZXBlYXRlZFB0ckZpZWxkPE1lc3NhZ2U+Jj4oCisgICAgICAgICAgbWFwX2ZpZWxkX2Jhc2VfLT5HZXRSZXBlYXRlZEZpZWxkKCkpOworICBFWFBFQ1RfRVEoMiwgcmVwZWF0ZWQuc2l6ZSgpKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZC5zaXplKCk7IGkrKykgeworICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UgPSByZXBlYXRlZC5HZXQoaSk7CisgICAgaW50IGtleSA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMihtZXNzYWdlLCBrZXlfZGVzY3JpcHRvcl8pOworICAgIGludCB2YWx1ZSA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMihtZXNzYWdlLCB2YWx1ZV9kZXNjcmlwdG9yXyk7CisgICAgRVhQRUNUX0VRKHZhbHVlLCBpbml0aWFsX3ZhbHVlX21hcF9ba2V5XSk7CisgIH0KK30KKworVEVTVF9GKE1hcEZpZWxkQmFzZVByaW1pdGl2ZVRlc3QsIE11dGFibGVSZXBlYXRlZEZpZWxkKSB7CisgIFJlcGVhdGVkUHRyRmllbGQ8TWVzc2FnZT4qIHJlcGVhdGVkID0KKyAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8UmVwZWF0ZWRQdHJGaWVsZDxNZXNzYWdlPio+KAorICAgICAgICAgIG1hcF9maWVsZF9iYXNlXy0+TXV0YWJsZVJlcGVhdGVkRmllbGQoKSk7CisgIEVYUEVDVF9FUSgyLCByZXBlYXRlZC0+c2l6ZSgpKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZC0+c2l6ZSgpOyBpKyspIHsKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlID0gcmVwZWF0ZWQtPkdldChpKTsKKyAgICBpbnQga2V5ID0gbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKG1lc3NhZ2UsIGtleV9kZXNjcmlwdG9yXyk7CisgICAgaW50IHZhbHVlID0gbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKG1lc3NhZ2UsIHZhbHVlX2Rlc2NyaXB0b3JfKTsKKyAgICBFWFBFQ1RfRVEodmFsdWUsIGluaXRpYWxfdmFsdWVfbWFwX1trZXldKTsKKyAgfQorfQorCitURVNUX0YoTWFwRmllbGRCYXNlUHJpbWl0aXZlVGVzdCwgQXJlbmEpIHsKKyAgLy8gQWxsb2NhdGUgYSBsYXJnZSBpbml0aWFsIGJsb2NrIHRvIGF2b2lkIG1hbGxvY3MgZHVyaW5nIGhvb2tlZCB0ZXN0LgorICBzdGQ6OnZlY3RvcjxjaGFyPiBhcmVuYV9ibG9jaygxMjggKiAxMDI0KTsKKyAgQXJlbmFPcHRpb25zIG9wdGlvbnM7CisgIG9wdGlvbnMuaW5pdGlhbF9ibG9jayA9ICZhcmVuYV9ibG9ja1swXTsKKyAgb3B0aW9ucy5pbml0aWFsX2Jsb2NrX3NpemUgPSBhcmVuYV9ibG9jay5zaXplKCk7CisgIEFyZW5hIGFyZW5hKG9wdGlvbnMpOworCisgIHsKKyAgICAvLyBUT0RPKGxpdWppc2kpOiBSZS13cml0ZSB0aGUgdGVzdCB0byBlbnN1cmUgdGhlIG1lbW9yeSBmb3IgdGhlIG1hcCBhbmQKKyAgICAvLyByZXBlYXRlZCBmaWVsZHMgYXJlIGFsbG9jYXRlZCBmcm9tIGFyZW5hcy4KKyAgICAvLyBOb0hlYXBDaGVja2VyIG5vX2hlYXA7CisKKyAgICBNYXBGaWVsZFR5cGUqIG1hcF9maWVsZCA9CisgICAgICAgIEFyZW5hOjpDcmVhdGVNZXNzYWdlPE1hcEZpZWxkVHlwZT4oJmFyZW5hLCBkZWZhdWx0X2VudHJ5Xyk7CisKKyAgICAvLyBTZXQgY29udGVudCBpbiBtYXAKKyAgICAoKm1hcF9maWVsZC0+TXV0YWJsZU1hcCgpKVsxMDBdID0gMTAxOworCisgICAgLy8gVHJpZ2dlciBjb252ZXJzaW9uIHRvIHJlcGVhdGVkIGZpZWxkLgorICAgIG1hcF9maWVsZC0+R2V0UmVwZWF0ZWRGaWVsZCgpOworICB9CisKKyAgeworICAgIC8vIFRPRE8obGl1amlzaSk6IFJlLXdyaXRlIHRoZSB0ZXN0IHRvIGVuc3VyZSB0aGUgbWVtb3J5IGZvciB0aGUgbWFwIGFuZAorICAgIC8vIHJlcGVhdGVkIGZpZWxkcyBhcmUgYWxsb2NhdGVkIGZyb20gYXJlbmFzLgorICAgIC8vIE5vSGVhcENoZWNrZXIgbm9faGVhcDsKKworICAgIE1hcEZpZWxkQmFzZVN0dWIqIG1hcF9maWVsZCA9CisgICAgICAgIEFyZW5hOjpDcmVhdGVNZXNzYWdlPE1hcEZpZWxkQmFzZVN0dWI+KCZhcmVuYSk7CisKKyAgICAvLyBUcmlnZ2VyIGNvbnZlcnNpb24gdG8gcmVwZWF0ZWQgZmllbGQuCisgICAgRVhQRUNUX1RSVUUobWFwX2ZpZWxkLT5NdXRhYmxlUmVwZWF0ZWRGaWVsZCgpICE9IE5VTEwpOworICB9Cit9CisKK25hbWVzcGFjZSB7CitlbnVtIFN0YXRlIHsgQ0xFQU4sIE1BUF9ESVJUWSwgUkVQRUFURURfRElSVFkgfTsKK30gIC8vIGFub255bW91cyBuYW1lc3BhY2UKKworY2xhc3MgTWFwRmllbGRTdGF0ZVRlc3QKKyAgICA6IHB1YmxpYyB0ZXN0aW5nOjpUZXN0V2l0aFBhcmFtPFN0YXRlPiB7CisgcHVibGljOgorIHByb3RlY3RlZDoKKyAgdHlwZWRlZiBNYXBGaWVsZDxpbnQzMiwgaW50MzIsIFdpcmVGb3JtYXRMaXRlOjpUWVBFX0lOVDMyLAorICAgICAgICAgICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpUWVBFX0lOVDMyLCBmYWxzZT4gTWFwRmllbGRUeXBlOworICB0eXBlZGVmIE1hcEZpZWxkTGl0ZTxpbnQzMiwgaW50MzIsIFdpcmVGb3JtYXRMaXRlOjpUWVBFX0lOVDMyLAorICAgICAgICAgICAgICAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9JTlQzMiwgZmFsc2U+IE1hcEZpZWxkTGl0ZVR5cGU7CisgIE1hcEZpZWxkU3RhdGVUZXN0KCkgOiBzdGF0ZV8oR2V0UGFyYW0oKSkgeworICAgIC8vIEJ1aWxkIG1hcCBmaWVsZAorICAgIGNvbnN0IERlc2NyaXB0b3IqIG1hcF9kZXNjcmlwdG9yID0KKyAgICAgICAgdW5pdHRlc3Q6OlRlc3RNYXA6OmRlc2NyaXB0b3IoKQorICAgICAgICAgICAgLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9pbnQzMl9pbnQzMiIpCisgICAgICAgICAgICAtPm1lc3NhZ2VfdHlwZSgpOworICAgIGRlZmF1bHRfZW50cnlfID0KKyAgICAgICAgTWVzc2FnZUZhY3Rvcnk6OmdlbmVyYXRlZF9mYWN0b3J5KCktPkdldFByb3RvdHlwZShtYXBfZGVzY3JpcHRvcik7CisgICAgbWFwX2ZpZWxkXy5yZXNldChuZXcgTWFwRmllbGRUeXBlKGRlZmF1bHRfZW50cnlfKSk7CisgICAgbWFwX2ZpZWxkX2Jhc2VfID0gbWFwX2ZpZWxkXy5nZXQoKTsKKworICAgIEV4cGVjdChtYXBfZmllbGRfLmdldCgpLCBNQVBfRElSVFksIDAsIDAsIHRydWUpOworICAgIHN3aXRjaCAoc3RhdGVfKSB7CisgICAgICBjYXNlIENMRUFOOgorICAgICAgICBBZGRPbmVTdGlsbENsZWFuKG1hcF9maWVsZF8uZ2V0KCkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgTUFQX0RJUlRZOgorICAgICAgICBNYWtlTWFwRGlydHkobWFwX2ZpZWxkXy5nZXQoKSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBSRVBFQVRFRF9ESVJUWToKKyAgICAgICAgTWFrZVJlcGVhdGVkRGlydHkobWFwX2ZpZWxkXy5nZXQoKSk7CisgICAgICAgIGJyZWFrOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgYnJlYWs7CisgICAgfQorICB9CisKKyAgdm9pZCBBZGRPbmVTdGlsbENsZWFuKE1hcEZpZWxkVHlwZSogbWFwX2ZpZWxkKSB7CisgICAgTWFwRmllbGRCYXNlKiBtYXBfZmllbGRfYmFzZSA9IG1hcF9maWVsZDsKKyAgICBNYXA8aW50MzIsIGludDMyPiogbWFwID0gbWFwX2ZpZWxkLT5NdXRhYmxlTWFwKCk7CisgICAgKCptYXApWzBdID0gMDsKKyAgICBtYXBfZmllbGRfYmFzZS0+R2V0UmVwZWF0ZWRGaWVsZCgpOworICAgIEV4cGVjdChtYXBfZmllbGQsIENMRUFOLCAxLCAxLCBmYWxzZSk7CisgIH0KKworICB2b2lkIE1ha2VNYXBEaXJ0eShNYXBGaWVsZFR5cGUqIG1hcF9maWVsZCkgeworICAgIE1hcDxpbnQzMiwgaW50MzI+KiBtYXAgPSBtYXBfZmllbGQtPk11dGFibGVNYXAoKTsKKyAgICAoKm1hcClbMF0gPSAwOworICAgIEV4cGVjdChtYXBfZmllbGQsIE1BUF9ESVJUWSwgMSwgMCwgdHJ1ZSk7CisgIH0KKworICB2b2lkIE1ha2VSZXBlYXRlZERpcnR5KE1hcEZpZWxkVHlwZSogbWFwX2ZpZWxkKSB7CisgICAgTWFrZU1hcERpcnR5KG1hcF9maWVsZCk7CisgICAgTWFwRmllbGRCYXNlKiBtYXBfZmllbGRfYmFzZSA9IG1hcF9maWVsZDsKKyAgICBtYXBfZmllbGRfYmFzZS0+TXV0YWJsZVJlcGVhdGVkRmllbGQoKTsKKyAgICBNYXA8aW50MzIsIGludDMyPiogbWFwID0gaW1wbGljaXRfY2FzdDxNYXBGaWVsZExpdGVUeXBlKj4obWFwX2ZpZWxkKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLT5NYXBGaWVsZExpdGVUeXBlOjpNdXRhYmxlTWFwKCk7CisgICAgbWFwLT5jbGVhcigpOworCisgICAgRXhwZWN0KG1hcF9maWVsZCwgUkVQRUFURURfRElSVFksIDAsIDEsIGZhbHNlKTsKKyAgfQorCisgIHZvaWQgRXhwZWN0KE1hcEZpZWxkVHlwZSogbWFwX2ZpZWxkLCBTdGF0ZSBzdGF0ZSwgaW50IG1hcF9zaXplLAorICAgICAgICAgICAgICBpbnQgcmVwZWF0ZWRfc2l6ZSwgYm9vbCBpc19yZXBlYXRlZF9udWxsKSB7CisgICAgTWFwRmllbGRCYXNlKiBtYXBfZmllbGRfYmFzZSA9IG1hcF9maWVsZDsKKyAgICBNYXBGaWVsZEJhc2VTdHViKiBzdHViID0KKyAgICAgICAgcmVpbnRlcnByZXRfY2FzdDxNYXBGaWVsZEJhc2VTdHViKj4obWFwX2ZpZWxkX2Jhc2UpOworCisgICAgTWFwPGludDMyLCBpbnQzMj4qIG1hcCA9IGltcGxpY2l0X2Nhc3Q8TWFwRmllbGRMaXRlVHlwZSo+KG1hcF9maWVsZCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0+TWFwRmllbGRMaXRlVHlwZTo6TXV0YWJsZU1hcCgpOworICAgIFJlcGVhdGVkUHRyRmllbGQ8TWVzc2FnZT4qIHJlcGVhdGVkX2ZpZWxkID0gc3R1Yi0+SW50ZXJuYWxSZXBlYXRlZEZpZWxkKCk7CisKKyAgICBzd2l0Y2ggKHN0YXRlKSB7CisgICAgICBjYXNlIE1BUF9ESVJUWToKKyAgICAgICAgRVhQRUNUX0ZBTFNFKHN0dWItPklzTWFwQ2xlYW4oKSk7CisgICAgICAgIEVYUEVDVF9UUlVFKHN0dWItPklzUmVwZWF0ZWRDbGVhbigpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIFJFUEVBVEVEX0RJUlRZOgorICAgICAgICBFWFBFQ1RfVFJVRShzdHViLT5Jc01hcENsZWFuKCkpOworICAgICAgICBFWFBFQ1RfRkFMU0Uoc3R1Yi0+SXNSZXBlYXRlZENsZWFuKCkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgQ0xFQU46CisgICAgICAgIEVYUEVDVF9UUlVFKHN0dWItPklzTWFwQ2xlYW4oKSk7CisgICAgICAgIEVYUEVDVF9UUlVFKHN0dWItPklzUmVwZWF0ZWRDbGVhbigpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBkZWZhdWx0OgorICAgICAgICBGQUlMKCk7CisgICAgfQorCisgICAgRVhQRUNUX0VRKG1hcF9zaXplLCBtYXAtPnNpemUoKSk7CisgICAgaWYgKGlzX3JlcGVhdGVkX251bGwpIHsKKyAgICAgIEVYUEVDVF9UUlVFKHJlcGVhdGVkX2ZpZWxkID09IE5VTEwpOworICAgIH0gZWxzZSB7CisgICAgICBFWFBFQ1RfRVEocmVwZWF0ZWRfc2l6ZSwgcmVwZWF0ZWRfZmllbGQtPnNpemUoKSk7CisgICAgfQorICB9CisKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxNYXBGaWVsZFR5cGU+IG1hcF9maWVsZF87CisgIE1hcEZpZWxkQmFzZSogbWFwX2ZpZWxkX2Jhc2VfOworICBTdGF0ZSBzdGF0ZV87CisgIGNvbnN0IE1lc3NhZ2UqIGRlZmF1bHRfZW50cnlfOworfTsKKworSU5TVEFOVElBVEVfVEVTVF9DQVNFX1AoTWFwRmllbGRTdGF0ZVRlc3RJbnN0YW5jZSwgTWFwRmllbGRTdGF0ZVRlc3QsCisgICAgICAgICAgICAgICAgICAgICAgICA6OnRlc3Rpbmc6OlZhbHVlcyhDTEVBTiwgTUFQX0RJUlRZLCBSRVBFQVRFRF9ESVJUWSkpOworCitURVNUX1AoTWFwRmllbGRTdGF0ZVRlc3QsIEdldE1hcCkgeworICBtYXBfZmllbGRfLT5HZXRNYXAoKTsKKyAgaWYgKHN0YXRlXyAhPSBNQVBfRElSVFkpIHsKKyAgICBFeHBlY3QobWFwX2ZpZWxkXy5nZXQoKSwgQ0xFQU4sIDEsIDEsIGZhbHNlKTsKKyAgfSBlbHNlIHsKKyAgICBFeHBlY3QobWFwX2ZpZWxkXy5nZXQoKSwgTUFQX0RJUlRZLCAxLCAwLCB0cnVlKTsKKyAgfQorfQorCitURVNUX1AoTWFwRmllbGRTdGF0ZVRlc3QsIE11dGFibGVNYXApIHsKKyAgbWFwX2ZpZWxkXy0+TXV0YWJsZU1hcCgpOworICBpZiAoc3RhdGVfICE9IE1BUF9ESVJUWSkgeworICAgIEV4cGVjdChtYXBfZmllbGRfLmdldCgpLCBNQVBfRElSVFksIDEsIDEsIGZhbHNlKTsKKyAgfSBlbHNlIHsKKyAgICBFeHBlY3QobWFwX2ZpZWxkXy5nZXQoKSwgTUFQX0RJUlRZLCAxLCAwLCB0cnVlKTsKKyAgfQorfQorCitURVNUX1AoTWFwRmllbGRTdGF0ZVRlc3QsIE1lcmdlRnJvbUNsZWFuKSB7CisgIE1hcEZpZWxkVHlwZSBvdGhlcihkZWZhdWx0X2VudHJ5Xyk7CisgIEFkZE9uZVN0aWxsQ2xlYW4oJm90aGVyKTsKKworICBtYXBfZmllbGRfLT5NZXJnZUZyb20ob3RoZXIpOworCisgIGlmIChzdGF0ZV8gIT0gTUFQX0RJUlRZKSB7CisgICAgRXhwZWN0KG1hcF9maWVsZF8uZ2V0KCksIE1BUF9ESVJUWSwgMSwgMSwgZmFsc2UpOworICB9IGVsc2UgeworICAgIEV4cGVjdChtYXBfZmllbGRfLmdldCgpLCBNQVBfRElSVFksIDEsIDAsIHRydWUpOworICB9CisKKyAgRXhwZWN0KCZvdGhlciwgQ0xFQU4sIDEsIDEsIGZhbHNlKTsKK30KKworVEVTVF9QKE1hcEZpZWxkU3RhdGVUZXN0LCBNZXJnZUZyb21NYXBEaXJ0eSkgeworICBNYXBGaWVsZFR5cGUgb3RoZXIoZGVmYXVsdF9lbnRyeV8pOworICBNYWtlTWFwRGlydHkoJm90aGVyKTsKKworICBtYXBfZmllbGRfLT5NZXJnZUZyb20ob3RoZXIpOworCisgIGlmIChzdGF0ZV8gIT0gTUFQX0RJUlRZKSB7CisgICAgRXhwZWN0KG1hcF9maWVsZF8uZ2V0KCksIE1BUF9ESVJUWSwgMSwgMSwgZmFsc2UpOworICB9IGVsc2UgeworICAgIEV4cGVjdChtYXBfZmllbGRfLmdldCgpLCBNQVBfRElSVFksIDEsIDAsIHRydWUpOworICB9CisKKyAgRXhwZWN0KCZvdGhlciwgTUFQX0RJUlRZLCAxLCAwLCB0cnVlKTsKK30KKworVEVTVF9QKE1hcEZpZWxkU3RhdGVUZXN0LCBNZXJnZUZyb21SZXBlYXRlZERpcnR5KSB7CisgIE1hcEZpZWxkVHlwZSBvdGhlcihkZWZhdWx0X2VudHJ5Xyk7CisgIE1ha2VSZXBlYXRlZERpcnR5KCZvdGhlcik7CisKKyAgbWFwX2ZpZWxkXy0+TWVyZ2VGcm9tKG90aGVyKTsKKworICBpZiAoc3RhdGVfICE9IE1BUF9ESVJUWSkgeworICAgIEV4cGVjdChtYXBfZmllbGRfLmdldCgpLCBNQVBfRElSVFksIDEsIDEsIGZhbHNlKTsKKyAgfSBlbHNlIHsKKyAgICBFeHBlY3QobWFwX2ZpZWxkXy5nZXQoKSwgTUFQX0RJUlRZLCAxLCAwLCB0cnVlKTsKKyAgfQorCisgIEV4cGVjdCgmb3RoZXIsIENMRUFOLCAxLCAxLCBmYWxzZSk7Cit9CisKK1RFU1RfUChNYXBGaWVsZFN0YXRlVGVzdCwgU3dhcENsZWFuKSB7CisgIE1hcEZpZWxkVHlwZSBvdGhlcihkZWZhdWx0X2VudHJ5Xyk7CisgIEFkZE9uZVN0aWxsQ2xlYW4oJm90aGVyKTsKKworICBtYXBfZmllbGRfLT5Td2FwKCZvdGhlcik7CisKKyAgRXhwZWN0KG1hcF9maWVsZF8uZ2V0KCksIENMRUFOLCAxLCAxLCBmYWxzZSk7CisKKyAgc3dpdGNoIChzdGF0ZV8pIHsKKyAgICBjYXNlIENMRUFOOgorICAgICAgRXhwZWN0KCZvdGhlciwgQ0xFQU4sIDEsIDEsIGZhbHNlKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgTUFQX0RJUlRZOgorICAgICAgRXhwZWN0KCZvdGhlciwgTUFQX0RJUlRZLCAxLCAwLCB0cnVlKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgUkVQRUFURURfRElSVFk6CisgICAgICBFeHBlY3QoJm90aGVyLCBSRVBFQVRFRF9ESVJUWSwgMCwgMSwgZmFsc2UpOworICAgICAgYnJlYWs7CisgICAgZGVmYXVsdDoKKyAgICAgIGJyZWFrOworICB9Cit9CisKK1RFU1RfUChNYXBGaWVsZFN0YXRlVGVzdCwgU3dhcE1hcERpcnR5KSB7CisgIE1hcEZpZWxkVHlwZSBvdGhlcihkZWZhdWx0X2VudHJ5Xyk7CisgIE1ha2VNYXBEaXJ0eSgmb3RoZXIpOworCisgIG1hcF9maWVsZF8tPlN3YXAoJm90aGVyKTsKKworICBFeHBlY3QobWFwX2ZpZWxkXy5nZXQoKSwgTUFQX0RJUlRZLCAxLCAwLCB0cnVlKTsKKworICBzd2l0Y2ggKHN0YXRlXykgeworICAgIGNhc2UgQ0xFQU46CisgICAgICBFeHBlY3QoJm90aGVyLCBDTEVBTiwgMSwgMSwgZmFsc2UpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBNQVBfRElSVFk6CisgICAgICBFeHBlY3QoJm90aGVyLCBNQVBfRElSVFksIDEsIDAsIHRydWUpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBSRVBFQVRFRF9ESVJUWToKKyAgICAgIEV4cGVjdCgmb3RoZXIsIFJFUEVBVEVEX0RJUlRZLCAwLCAxLCBmYWxzZSk7CisgICAgICBicmVhazsKKyAgICBkZWZhdWx0OgorICAgICAgYnJlYWs7CisgIH0KK30KKworVEVTVF9QKE1hcEZpZWxkU3RhdGVUZXN0LCBTd2FwUmVwZWF0ZWREaXJ0eSkgeworICBNYXBGaWVsZFR5cGUgb3RoZXIoZGVmYXVsdF9lbnRyeV8pOworICBNYWtlUmVwZWF0ZWREaXJ0eSgmb3RoZXIpOworCisgIG1hcF9maWVsZF8tPlN3YXAoJm90aGVyKTsKKworICBFeHBlY3QobWFwX2ZpZWxkXy5nZXQoKSwgUkVQRUFURURfRElSVFksIDAsIDEsIGZhbHNlKTsKKworICBzd2l0Y2ggKHN0YXRlXykgeworICAgIGNhc2UgQ0xFQU46CisgICAgICBFeHBlY3QoJm90aGVyLCBDTEVBTiwgMSwgMSwgZmFsc2UpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBNQVBfRElSVFk6CisgICAgICBFeHBlY3QoJm90aGVyLCBNQVBfRElSVFksIDEsIDAsIHRydWUpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBSRVBFQVRFRF9ESVJUWToKKyAgICAgIEV4cGVjdCgmb3RoZXIsIFJFUEVBVEVEX0RJUlRZLCAwLCAxLCBmYWxzZSk7CisgICAgICBicmVhazsKKyAgICBkZWZhdWx0OgorICAgICAgYnJlYWs7CisgIH0KK30KKworVEVTVF9QKE1hcEZpZWxkU3RhdGVUZXN0LCBDbGVhcikgeworICBtYXBfZmllbGRfLT5DbGVhcigpOworCisgIGlmIChzdGF0ZV8gIT0gTUFQX0RJUlRZKSB7CisgICAgRXhwZWN0KG1hcF9maWVsZF8uZ2V0KCksIE1BUF9ESVJUWSwgMCwgMSwgZmFsc2UpOworICB9IGVsc2UgeworICAgIEV4cGVjdChtYXBfZmllbGRfLmdldCgpLCBNQVBfRElSVFksIDAsIDAsIHRydWUpOworICB9Cit9CisKK1RFU1RfUChNYXBGaWVsZFN0YXRlVGVzdCwgU3BhY2VVc2VkRXhjbHVkaW5nU2VsZikgeworICBtYXBfZmllbGRfYmFzZV8tPlNwYWNlVXNlZEV4Y2x1ZGluZ1NlbGYoKTsKKworICBzd2l0Y2ggKHN0YXRlXykgeworICAgIGNhc2UgQ0xFQU46CisgICAgICBFeHBlY3QobWFwX2ZpZWxkXy5nZXQoKSwgQ0xFQU4sIDEsIDEsIGZhbHNlKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgTUFQX0RJUlRZOgorICAgICAgRXhwZWN0KG1hcF9maWVsZF8uZ2V0KCksIE1BUF9ESVJUWSwgMSwgMCwgdHJ1ZSk7CisgICAgICBicmVhazsKKyAgICBjYXNlIFJFUEVBVEVEX0RJUlRZOgorICAgICAgRXhwZWN0KG1hcF9maWVsZF8uZ2V0KCksIFJFUEVBVEVEX0RJUlRZLCAwLCAxLCBmYWxzZSk7CisgICAgICBicmVhazsKKyAgICBkZWZhdWx0OgorICAgICAgYnJlYWs7CisgIH0KK30KKworVEVTVF9QKE1hcEZpZWxkU3RhdGVUZXN0LCBHZXRNYXBGaWVsZCkgeworICBtYXBfZmllbGRfYmFzZV8tPkdldFJlcGVhdGVkRmllbGQoKTsKKworICBpZiAoc3RhdGVfICE9IFJFUEVBVEVEX0RJUlRZKSB7CisgICAgRXhwZWN0KG1hcF9maWVsZF8uZ2V0KCksIENMRUFOLCAxLCAxLCBmYWxzZSk7CisgIH0gZWxzZSB7CisgICAgRXhwZWN0KG1hcF9maWVsZF8uZ2V0KCksIFJFUEVBVEVEX0RJUlRZLCAwLCAxLCBmYWxzZSk7CisgIH0KK30KKworVEVTVF9QKE1hcEZpZWxkU3RhdGVUZXN0LCBNdXRhYmxlTWFwRmllbGQpIHsKKyAgbWFwX2ZpZWxkX2Jhc2VfLT5NdXRhYmxlUmVwZWF0ZWRGaWVsZCgpOworCisgIGlmIChzdGF0ZV8gIT0gUkVQRUFURURfRElSVFkpIHsKKyAgICBFeHBlY3QobWFwX2ZpZWxkXy5nZXQoKSwgUkVQRUFURURfRElSVFksIDEsIDEsIGZhbHNlKTsKKyAgfSBlbHNlIHsKKyAgICBFeHBlY3QobWFwX2ZpZWxkXy5nZXQoKSwgUkVQRUFURURfRElSVFksIDAsIDEsIGZhbHNlKTsKKyAgfQorfQorCisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF9saXRlX3Rlc3RfdXRpbC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvbWFwX2xpdGVfdGVzdF91dGlsLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI2NWI0ZDYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF9saXRlX3Rlc3RfdXRpbC5jYwpAQCAtMCwwICsxLDkzIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tYXBfbGl0ZV90ZXN0X3V0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWFwX2xpdGVfdW5pdHRlc3QucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWFwX3Rlc3RfdXRpbF9pbXBsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKwordm9pZCBNYXBMaXRlVGVzdFV0aWw6OlNldE1hcEZpZWxkcyh1bml0dGVzdDo6VGVzdE1hcExpdGUqIG1lc3NhZ2UpIHsKKyAgTWFwVGVzdFV0aWxJbXBsOjpTZXRNYXBGaWVsZHM8dW5pdHRlc3Q6Ok1hcEVudW1MaXRlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0dGVzdDo6TUFQX0VOVU1fQkFSX0xJVEUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXR0ZXN0OjpNQVBfRU5VTV9CQVpfTElURT4obWVzc2FnZSk7Cit9CisKK3ZvaWQgTWFwTGl0ZVRlc3RVdGlsOjpTZXRBcmVuYU1hcEZpZWxkcyh1bml0dGVzdDo6VGVzdEFyZW5hTWFwTGl0ZSogbWVzc2FnZSkgeworICBNYXBUZXN0VXRpbEltcGw6OlNldEFyZW5hTWFwRmllbGRzPHVuaXR0ZXN0OjpNYXBFbnVtTGl0ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0dGVzdDo6TUFQX0VOVU1fQkFSX0xJVEUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHRlc3Q6Ok1BUF9FTlVNX0JBWl9MSVRFPihtZXNzYWdlKTsKK30KKwordm9pZCBNYXBMaXRlVGVzdFV0aWw6OlNldE1hcEZpZWxkc0luaXRpYWxpemVkKHVuaXR0ZXN0OjpUZXN0TWFwTGl0ZSogbWVzc2FnZSkgeworICBNYXBUZXN0VXRpbEltcGw6OlNldE1hcEZpZWxkc0luaXRpYWxpemVkKG1lc3NhZ2UpOworfQorCit2b2lkIE1hcExpdGVUZXN0VXRpbDo6TW9kaWZ5TWFwRmllbGRzKHVuaXR0ZXN0OjpUZXN0TWFwTGl0ZSogbWVzc2FnZSkgeworICBNYXBUZXN0VXRpbEltcGw6Ok1vZGlmeU1hcEZpZWxkczx1bml0dGVzdDo6TWFwRW51bUxpdGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXR0ZXN0OjpNQVBfRU5VTV9GT09fTElURT4obWVzc2FnZSk7Cit9CisKK3ZvaWQgTWFwTGl0ZVRlc3RVdGlsOjpFeHBlY3RDbGVhcihjb25zdCB1bml0dGVzdDo6VGVzdE1hcExpdGUmIG1lc3NhZ2UpIHsKKyAgTWFwVGVzdFV0aWxJbXBsOjpFeHBlY3RDbGVhcihtZXNzYWdlKTsKK30KKwordm9pZCBNYXBMaXRlVGVzdFV0aWw6OkV4cGVjdE1hcEZpZWxkc1NldChjb25zdCB1bml0dGVzdDo6VGVzdE1hcExpdGUmIG1lc3NhZ2UpIHsKKyAgTWFwVGVzdFV0aWxJbXBsOjpFeHBlY3RNYXBGaWVsZHNTZXQ8dW5pdHRlc3Q6Ok1hcEVudW1MaXRlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0dGVzdDo6TUFQX0VOVU1fQkFSX0xJVEUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXR0ZXN0OjpNQVBfRU5VTV9CQVpfTElURT4obWVzc2FnZSk7Cit9CisKK3ZvaWQgTWFwTGl0ZVRlc3RVdGlsOjpFeHBlY3RBcmVuYU1hcEZpZWxkc1NldCgKKyAgICBjb25zdCB1bml0dGVzdDo6VGVzdEFyZW5hTWFwTGl0ZSYgbWVzc2FnZSkgeworICBNYXBUZXN0VXRpbEltcGw6OkV4cGVjdEFyZW5hTWFwRmllbGRzU2V0PHVuaXR0ZXN0OjpNYXBFbnVtTGl0ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0dGVzdDo6TUFQX0VOVU1fQkFSX0xJVEUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHRlc3Q6Ok1BUF9FTlVNX0JBWl9MSVRFPigKKyAgICAgIG1lc3NhZ2UpOworfQorCit2b2lkIE1hcExpdGVUZXN0VXRpbDo6RXhwZWN0TWFwRmllbGRzU2V0SW5pdGlhbGl6ZWQoCisgICAgY29uc3QgdW5pdHRlc3Q6OlRlc3RNYXBMaXRlJiBtZXNzYWdlKSB7CisgIE1hcFRlc3RVdGlsSW1wbDo6RXhwZWN0TWFwRmllbGRzU2V0SW5pdGlhbGl6ZWQ8dW5pdHRlc3Q6Ok1hcEVudW1MaXRlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXR0ZXN0OjpNQVBfRU5VTV9GT09fTElURT4oCisgICAgICBtZXNzYWdlKTsKK30KKwordm9pZCBNYXBMaXRlVGVzdFV0aWw6OkV4cGVjdE1hcEZpZWxkc01vZGlmaWVkKAorICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0TWFwTGl0ZSYgbWVzc2FnZSkgeworICBNYXBUZXN0VXRpbEltcGw6OkV4cGVjdE1hcEZpZWxkc01vZGlmaWVkPHVuaXR0ZXN0OjpNYXBFbnVtTGl0ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0dGVzdDo6TUFQX0VOVU1fQkFSX0xJVEUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHRlc3Q6Ok1BUF9FTlVNX0ZPT19MSVRFPigKKyAgICAgIG1lc3NhZ2UpOworfQorCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvbWFwX2xpdGVfdGVzdF91dGlsLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF9saXRlX3Rlc3RfdXRpbC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY2ZGVkZGUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF9saXRlX3Rlc3RfdXRpbC5oCkBAIC0wLDAgKzEsODAgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9NQVBfTElURV9URVNUX1VUSUxfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9NQVBfTElURV9URVNUX1VUSUxfSF9fCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWFwX2xpdGVfdW5pdHRlc3QucGIuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCitjbGFzcyBNYXBMaXRlVGVzdFV0aWwgeworIHB1YmxpYzoKKyAgLy8gU2V0IGV2ZXJ5IGZpZWxkIGluIHRoZSBUZXN0TWFwTGl0ZSBtZXNzYWdlIHRvIGEgdW5pcXVlIHZhbHVlLgorICBzdGF0aWMgdm9pZCBTZXRNYXBGaWVsZHMocHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RNYXBMaXRlKiBtZXNzYWdlKTsKKworICAvLyBTZXQgZXZlcnkgZmllbGQgaW4gdGhlIFRlc3RBcmVuYU1hcExpdGUgbWVzc2FnZSB0byBhIHVuaXF1ZSB2YWx1ZS4KKyAgc3RhdGljIHZvaWQgU2V0QXJlbmFNYXBGaWVsZHMocHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RBcmVuYU1hcExpdGUqIG1lc3NhZ2UpOworCisgIC8vIFNldCBldmVyeSBmaWVsZCBpbiB0aGUgbWVzc2FnZSB0byBhIGRlZmF1bHQgdmFsdWUuCisgIHN0YXRpYyB2b2lkIFNldE1hcEZpZWxkc0luaXRpYWxpemVkKHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0TWFwTGl0ZSogbWVzc2FnZSk7CisKKyAgLy8gTW9kaWZ5IGFsbCB0aGUgbWFwIGZpZWxkcyBvZiB0aGUgbWVzc2FnZSAod2hpY2ggc2hvdWxkIGFscmVhZHkgaGF2ZSBiZWVuCisgIC8vIGluaXRpYWxpemVkIHdpdGggU2V0TWFwRmllbGRzKCkpLgorICBzdGF0aWMgdm9pZCBNb2RpZnlNYXBGaWVsZHMocHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RNYXBMaXRlKiBtZXNzYWdlKTsKKworICAvLyBDaGVjayB0aGF0IGFsbCBmaWVsZHMgaGF2ZSB0aGUgdmFsdWVzIHRoYXQgdGhleSBzaG91bGQgaGF2ZSBhZnRlcgorICAvLyBTZXRNYXBGaWVsZHMoKSBpcyBjYWxsZWQuCisgIHN0YXRpYyB2b2lkIEV4cGVjdE1hcEZpZWxkc1NldChjb25zdCBwcm90b2J1Zl91bml0dGVzdDo6VGVzdE1hcExpdGUmIG1lc3NhZ2UpOworCisgIC8vIENoZWNrIHRoYXQgYWxsIGZpZWxkcyBoYXZlIHRoZSB2YWx1ZXMgdGhhdCB0aGV5IHNob3VsZCBoYXZlIGFmdGVyCisgIC8vIFNldE1hcEZpZWxkcygpIGlzIGNhbGxlZCBmb3IgVGVzdEFyZW5hTWFwTGl0ZS4KKyAgc3RhdGljIHZvaWQgRXhwZWN0QXJlbmFNYXBGaWVsZHNTZXQoCisgICAgICBjb25zdCBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEFyZW5hTWFwTGl0ZSYgbWVzc2FnZSk7CisKKyAgLy8gQ2hlY2sgdGhhdCBhbGwgZmllbGRzIGhhdmUgdGhlIHZhbHVlcyB0aGF0IHRoZXkgc2hvdWxkIGhhdmUgYWZ0ZXIKKyAgLy8gU2V0TWFwRmllbGRzSW5pdGlhbGl6ZWQoKSBpcyBjYWxsZWQuCisgIHN0YXRpYyB2b2lkIEV4cGVjdE1hcEZpZWxkc1NldEluaXRpYWxpemVkKAorICAgICAgY29uc3QgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RNYXBMaXRlJiBtZXNzYWdlKTsKKworICAvLyBFeHBlY3QgdGhhdCB0aGUgbWVzc2FnZSBpcyBtb2RpZmllZCBhcyB3b3VsZCBiZSBleHBlY3RlZCBmcm9tCisgIC8vIE1vZGlmeU1hcEZpZWxkcygpLgorICBzdGF0aWMgdm9pZCBFeHBlY3RNYXBGaWVsZHNNb2RpZmllZCgKKyAgICAgIGNvbnN0IHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0TWFwTGl0ZSYgbWVzc2FnZSk7CisKKyAgLy8gQ2hlY2sgdGhhdCBhbGwgZmllbGRzIGFyZSBlbXB0eS4KKyAgc3RhdGljIHZvaWQgRXhwZWN0Q2xlYXIoY29uc3QgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RNYXBMaXRlJiBtZXNzYWdlKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9NQVBfTElURV9URVNUX1VUSUxfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF9saXRlX3VuaXR0ZXN0LnByb3RvIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9tYXBfbGl0ZV91bml0dGVzdC5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wNTkyZGQ3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9tYXBfbGl0ZV91bml0dGVzdC5wcm90bwpAQCAtMCwwICsxLDEzMCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3N5bnRheCA9ICJwcm90bzIiOworCitvcHRpb24gY2NfZW5hYmxlX2FyZW5hcyA9IHRydWU7CitvcHRpb24gb3B0aW1pemVfZm9yID0gTElURV9SVU5USU1FOworCitpbXBvcnQgImdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9saXRlLnByb3RvIjsKK2ltcG9ydCAiZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X25vX2FyZW5hX2xpdGUucHJvdG8iOworCitwYWNrYWdlIHByb3RvYnVmX3VuaXR0ZXN0OworCittZXNzYWdlIFRlc3RNYXBMaXRlIHsKKyAgbWFwPGludDMyICAgLCBpbnQzMiAgID4gbWFwX2ludDMyX2ludDMyICAgICAgID0gMTsKKyAgbWFwPGludDY0ICAgLCBpbnQ2NCAgID4gbWFwX2ludDY0X2ludDY0ICAgICAgID0gMjsKKyAgbWFwPHVpbnQzMiAgLCB1aW50MzIgID4gbWFwX3VpbnQzMl91aW50MzIgICAgID0gMzsKKyAgbWFwPHVpbnQ2NCAgLCB1aW50NjQgID4gbWFwX3VpbnQ2NF91aW50NjQgICAgID0gNDsKKyAgbWFwPHNpbnQzMiAgLCBzaW50MzIgID4gbWFwX3NpbnQzMl9zaW50MzIgICAgID0gNTsKKyAgbWFwPHNpbnQ2NCAgLCBzaW50NjQgID4gbWFwX3NpbnQ2NF9zaW50NjQgICAgID0gNjsKKyAgbWFwPGZpeGVkMzIgLCBmaXhlZDMyID4gbWFwX2ZpeGVkMzJfZml4ZWQzMiAgID0gNzsKKyAgbWFwPGZpeGVkNjQgLCBmaXhlZDY0ID4gbWFwX2ZpeGVkNjRfZml4ZWQ2NCAgID0gODsKKyAgbWFwPHNmaXhlZDMyLCBzZml4ZWQzMj4gbWFwX3NmaXhlZDMyX3NmaXhlZDMyID0gOTsKKyAgbWFwPHNmaXhlZDY0LCBzZml4ZWQ2ND4gbWFwX3NmaXhlZDY0X3NmaXhlZDY0ID0gMTA7CisgIG1hcDxpbnQzMiAgICwgZmxvYXQgICA+IG1hcF9pbnQzMl9mbG9hdCAgICAgICA9IDExOworICBtYXA8aW50MzIgICAsIGRvdWJsZSAgPiBtYXBfaW50MzJfZG91YmxlICAgICAgPSAxMjsKKyAgbWFwPGJvb2wgICAgLCBib29sICAgID4gbWFwX2Jvb2xfYm9vbCAgICAgICAgID0gMTM7CisgIG1hcDxzdHJpbmcgICwgc3RyaW5nICA+IG1hcF9zdHJpbmdfc3RyaW5nICAgICA9IDE0OworICBtYXA8aW50MzIgICAsIGJ5dGVzICAgPiBtYXBfaW50MzJfYnl0ZXMgICAgICAgPSAxNTsKKyAgbWFwPGludDMyICAgLCBNYXBFbnVtTGl0ZT4gbWFwX2ludDMyX2VudW0gICAgID0gMTY7CisgIG1hcDxpbnQzMiAgICwgRm9yZWlnbk1lc3NhZ2VMaXRlPiBtYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlID0gMTc7CisgIG1hcDxpbnQzMiwgaW50MzI+IHRlYm9yaW5nID0gMTg7Cit9CisKK21lc3NhZ2UgVGVzdEFyZW5hTWFwTGl0ZSB7CisgIG1hcDxpbnQzMiAgICwgaW50MzIgICA+IG1hcF9pbnQzMl9pbnQzMiAgICAgICA9IDE7CisgIG1hcDxpbnQ2NCAgICwgaW50NjQgICA+IG1hcF9pbnQ2NF9pbnQ2NCAgICAgICA9IDI7CisgIG1hcDx1aW50MzIgICwgdWludDMyICA+IG1hcF91aW50MzJfdWludDMyICAgICA9IDM7CisgIG1hcDx1aW50NjQgICwgdWludDY0ICA+IG1hcF91aW50NjRfdWludDY0ICAgICA9IDQ7CisgIG1hcDxzaW50MzIgICwgc2ludDMyICA+IG1hcF9zaW50MzJfc2ludDMyICAgICA9IDU7CisgIG1hcDxzaW50NjQgICwgc2ludDY0ICA+IG1hcF9zaW50NjRfc2ludDY0ICAgICA9IDY7CisgIG1hcDxmaXhlZDMyICwgZml4ZWQzMiA+IG1hcF9maXhlZDMyX2ZpeGVkMzIgICA9IDc7CisgIG1hcDxmaXhlZDY0ICwgZml4ZWQ2NCA+IG1hcF9maXhlZDY0X2ZpeGVkNjQgICA9IDg7CisgIG1hcDxzZml4ZWQzMiwgc2ZpeGVkMzI+IG1hcF9zZml4ZWQzMl9zZml4ZWQzMiA9IDk7CisgIG1hcDxzZml4ZWQ2NCwgc2ZpeGVkNjQ+IG1hcF9zZml4ZWQ2NF9zZml4ZWQ2NCA9IDEwOworICBtYXA8aW50MzIgICAsIGZsb2F0ICAgPiBtYXBfaW50MzJfZmxvYXQgICAgICAgPSAxMTsKKyAgbWFwPGludDMyICAgLCBkb3VibGUgID4gbWFwX2ludDMyX2RvdWJsZSAgICAgID0gMTI7CisgIG1hcDxib29sICAgICwgYm9vbCAgICA+IG1hcF9ib29sX2Jvb2wgICAgICAgICA9IDEzOworICBtYXA8c3RyaW5nICAsIHN0cmluZyAgPiBtYXBfc3RyaW5nX3N0cmluZyAgICAgPSAxNDsKKyAgbWFwPGludDMyICAgLCBieXRlcyAgID4gbWFwX2ludDMyX2J5dGVzICAgICAgID0gMTU7CisgIG1hcDxpbnQzMiAgICwgTWFwRW51bUxpdGU+IG1hcF9pbnQzMl9lbnVtICAgICA9IDE2OworICBtYXA8aW50MzIgICAsIEZvcmVpZ25NZXNzYWdlQXJlbmFMaXRlPiBtYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlID0gMTc7CisgIG1hcDxpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0X25vX2FyZW5hLkZvcmVpZ25NZXNzYWdlTGl0ZT4KKyAgICAgIG1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2Vfbm9fYXJlbmEgPSAxODsKK30KKworLy8gVGVzdCBlbWJlZGVkIG1lc3NhZ2Ugd2l0aCByZXF1aXJlZCBmaWVsZHMKK21lc3NhZ2UgVGVzdFJlcXVpcmVkTWVzc2FnZU1hcExpdGUgeworICBtYXA8aW50MzIsIFRlc3RSZXF1aXJlZExpdGU+IG1hcF9maWVsZCA9IDE7Cit9CisKK21lc3NhZ2UgVGVzdEVudW1NYXBMaXRlIHsKKyAgbWFwPGludDMyLCBQcm90bzJNYXBFbnVtTGl0ZT4ga25vd25fbWFwX2ZpZWxkID0gMTAxOworICBtYXA8aW50MzIsIFByb3RvMk1hcEVudW1MaXRlPiB1bmtub3duX21hcF9maWVsZCA9IDEwMjsKK30KKworbWVzc2FnZSBUZXN0RW51bU1hcFBsdXNFeHRyYUxpdGUgeworICBtYXA8aW50MzIsIFByb3RvMk1hcEVudW1QbHVzRXh0cmFMaXRlPiBrbm93bl9tYXBfZmllbGQgPSAxMDE7CisgIG1hcDxpbnQzMiwgUHJvdG8yTWFwRW51bVBsdXNFeHRyYUxpdGU+IHVua25vd25fbWFwX2ZpZWxkID0gMTAyOworfQorCittZXNzYWdlIFRlc3RNZXNzYWdlTWFwTGl0ZSB7CisgIG1hcDxpbnQzMiwgVGVzdEFsbFR5cGVzTGl0ZT4gbWFwX2ludDMyX21lc3NhZ2UgPSAxOworfQorCitlbnVtIFByb3RvMk1hcEVudW1MaXRlIHsKKyAgUFJPVE8yX01BUF9FTlVNX0ZPT19MSVRFID0gMDsKKyAgUFJPVE8yX01BUF9FTlVNX0JBUl9MSVRFID0gMTsKKyAgUFJPVE8yX01BUF9FTlVNX0JBWl9MSVRFID0gMjsKK30KKworZW51bSBQcm90bzJNYXBFbnVtUGx1c0V4dHJhTGl0ZSB7CisgIEVfUFJPVE8yX01BUF9FTlVNX0ZPT19MSVRFICAgPSAwOworICBFX1BST1RPMl9NQVBfRU5VTV9CQVJfTElURSAgID0gMTsKKyAgRV9QUk9UTzJfTUFQX0VOVU1fQkFaX0xJVEUgICA9IDI7CisgIEVfUFJPVE8yX01BUF9FTlVNX0VYVFJBX0xJVEUgPSAzOworfQorCitlbnVtIE1hcEVudW1MaXRlIHsKKyAgTUFQX0VOVU1fRk9PX0xJVEUgPSAwOworICBNQVBfRU5VTV9CQVJfTElURSA9IDE7CisgIE1BUF9FTlVNX0JBWl9MSVRFID0gMjsKK30KKworbWVzc2FnZSBUZXN0UmVxdWlyZWRMaXRlIHsKKyAgcmVxdWlyZWQgaW50MzIgYSA9IDE7CisgIHJlcXVpcmVkIGludDMyIGIgPSAyOworICByZXF1aXJlZCBpbnQzMiBjID0gMzsKK30KKworbWVzc2FnZSBGb3JlaWduTWVzc2FnZUFyZW5hTGl0ZSB7CisgIG9wdGlvbmFsIGludDMyIGMgPSAxOworfQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9tYXBfcHJvdG8yX3VuaXR0ZXN0LnByb3RvIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9tYXBfcHJvdG8yX3VuaXR0ZXN0LnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkxNmNjNTQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF9wcm90bzJfdW5pdHRlc3QucHJvdG8KQEAgLTAsMCArMSw2NiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3N5bnRheCA9ICJwcm90bzIiOworCisKK2ltcG9ydCAiZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2ltcG9ydC5wcm90byI7CisKKy8vIFdlIGRvbid0IHB1dCB0aGlzIGluIGEgcGFja2FnZSB3aXRoaW4gcHJvdG8yIGJlY2F1c2Ugd2UgbmVlZCB0byBtYWtlIHN1cmUKKy8vIHRoYXQgdGhlIGdlbmVyYXRlZCBjb2RlIGRvZXNuJ3QgZGVwZW5kIG9uIGJlaW5nIGluIHRoZSBwcm90bzIgbmFtZXNwYWNlLgorLy8gSW4gbWFwX3Rlc3RfdXRpbC5oIHdlIGRvICJ1c2luZyBuYW1lc3BhY2UgdW5pdHRlc3QgPSBwcm90b2J1Zl91bml0dGVzdCIuCitwYWNrYWdlIHByb3RvYnVmX3VuaXR0ZXN0OworCitlbnVtIFByb3RvMk1hcEVudW0geworICBQUk9UTzJfTUFQX0VOVU1fRk9PICAgPSAwOworICBQUk9UTzJfTUFQX0VOVU1fQkFSICAgPSAxOworICBQUk9UTzJfTUFQX0VOVU1fQkFaICAgPSAyOworfQorCitlbnVtIFByb3RvMk1hcEVudW1QbHVzRXh0cmEgeworICBFX1BST1RPMl9NQVBfRU5VTV9GT08gICA9IDA7CisgIEVfUFJPVE8yX01BUF9FTlVNX0JBUiAgID0gMTsKKyAgRV9QUk9UTzJfTUFQX0VOVU1fQkFaICAgPSAyOworICBFX1BST1RPMl9NQVBfRU5VTV9FWFRSQSA9IDM7Cit9CisKK21lc3NhZ2UgVGVzdEVudW1NYXAgeworICBtYXA8aW50MzIsIFByb3RvMk1hcEVudW0+IGtub3duX21hcF9maWVsZCA9IDEwMTsKKyAgbWFwPGludDMyLCBQcm90bzJNYXBFbnVtPiB1bmtub3duX21hcF9maWVsZCA9IDEwMjsKK30KKworbWVzc2FnZSBUZXN0RW51bU1hcFBsdXNFeHRyYSB7CisgIG1hcDxpbnQzMiwgUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4ga25vd25fbWFwX2ZpZWxkID0gMTAxOworICBtYXA8aW50MzIsIFByb3RvMk1hcEVudW1QbHVzRXh0cmE+IHVua25vd25fbWFwX2ZpZWxkID0gMTAyOworfQorCittZXNzYWdlIFRlc3RJbXBvcnRFbnVtTWFwIHsKKyAgbWFwPGludDMyLCBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0RW51bUZvck1hcD4gaW1wb3J0X2VudW1fYW1wID0gMTsKK30KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvbWFwX3Rlc3QuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF90ZXN0LmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ1MWIwMmUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF90ZXN0LmNjCkBAIC0wLDAgKzEsMjQ2OSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorI2luY2x1ZGUgPHNzdHJlYW0+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY2FzdHMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbG9nZ2luZy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc2NvcGVkX3B0ci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJpbmdwcmludGYuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9maWxlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2FyZW5hX3Rlc3RfdXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tYXBfcHJvdG8yX3VuaXR0ZXN0LnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21hcF91bml0dGVzdC5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tYXBfdGVzdF91dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RfdXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvcl9kYXRhYmFzZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9keW5hbWljX21lc3NhZ2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWFwLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21hcF9maWVsZF9pbmwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWVzc2FnZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9yZWZsZWN0aW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3JlZmxlY3Rpb25fb3BzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3RleHRfZm9ybWF0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0X2xpdGVfaW5sLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby90b2tlbml6ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbV9pbXBsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3Vic3RpdHV0ZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2dvb2dsZXRlc3QuaD4KKyNpbmNsdWRlIDxndGVzdC9ndGVzdC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKKwordXNpbmcgZ29vZ2xlOjpwcm90b2J1Zjo6dW5pdHRlc3Q6OkZvcmVpZ25NZXNzYWdlOwordXNpbmcgZ29vZ2xlOjpwcm90b2J1Zjo6dW5pdHRlc3Q6OlRlc3RBbGxUeXBlczsKK3VzaW5nIGdvb2dsZTo6cHJvdG9idWY6OnVuaXR0ZXN0OjpUZXN0TWFwOwordXNpbmcgZ29vZ2xlOjpwcm90b2J1Zjo6dW5pdHRlc3Q6OlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlOworCituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKworLy8gTWFwIEFQSSBUZXN0ID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK2NsYXNzIE1hcEltcGxUZXN0IDogcHVibGljIDo6dGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICBNYXBJbXBsVGVzdCgpCisgICAgICA6IG1hcF9wdHJfKG5ldyBNYXA8aW50MzIsIGludDMyPiksCisgICAgICAgIG1hcF8oKm1hcF9wdHJfKSwKKyAgICAgICAgY29uc3RfbWFwXygqbWFwX3B0cl8pIHsKKyAgICBFWFBFQ1RfVFJVRShtYXBfLmVtcHR5KCkpOworICAgIEVYUEVDVF9FUSgwLCBtYXBfLnNpemUoKSk7CisgIH0KKyAgfk1hcEltcGxUZXN0KCkge30KKworICB2b2lkIEV4cGVjdFNpbmdsZUVsZW1lbnQoaW50MzIga2V5LCBpbnQzMiB2YWx1ZSkgeworICAgIEVYUEVDVF9GQUxTRShtYXBfLmVtcHR5KCkpOworICAgIEVYUEVDVF9FUSgxLCBtYXBfLnNpemUoKSk7CisgICAgRXhwZWN0RWxlbWVudChrZXksIHZhbHVlKTsKKyAgfQorCisgIHZvaWQgRXhwZWN0RWxlbWVudHMoY29uc3Qgc3RkOjptYXA8aW50MzIsIGludDMyPiYgbWFwKSB7CisgICAgRVhQRUNUX0ZBTFNFKG1hcF8uZW1wdHkoKSk7CisgICAgRVhQRUNUX0VRKG1hcC5zaXplKCksIG1hcF8uc2l6ZSgpKTsKKyAgICBmb3IgKHN0ZDo6bWFwPGludDMyLCBpbnQzMj46OmNvbnN0X2l0ZXJhdG9yIGl0ID0gbWFwLmJlZ2luKCk7CisgICAgICAgICBpdCAhPSBtYXAuZW5kKCk7ICsraXQpIHsKKyAgICAgIEV4cGVjdEVsZW1lbnQoaXQtPmZpcnN0LCBpdC0+c2Vjb25kKTsKKyAgICB9CisgIH0KKworICB2b2lkIEV4cGVjdEVsZW1lbnQoaW50MzIga2V5LCBpbnQzMiB2YWx1ZSkgeworICAgIC8vIFRlc3QgbWFwIHNpemUgaXMgY29ycmVjdC4KKyAgICBFWFBFQ1RfRVEodmFsdWUsIG1hcF9ba2V5XSk7CisgICAgRVhQRUNUX0VRKDEsIG1hcF8uY291bnQoa2V5KSk7CisKKyAgICAvLyBDaGVjayBtdXRhYmxlIGF0IGFuZCBmaW5kIHdvcmsgY29ycmVjdGx5LgorICAgIEVYUEVDVF9FUSh2YWx1ZSwgbWFwXy5hdChrZXkpKTsKKyAgICBNYXA8aW50MzIsIGludDMyPjo6aXRlcmF0b3IgaXQgPSBtYXBfLmZpbmQoa2V5KTsKKworICAgIC8vIGludGVyYXRvciBkZXJlZmVyZW5jZWFibGUKKyAgICBFWFBFQ1RfRVEoa2V5LCAgICgqaXQpLmZpcnN0KTsKKyAgICBFWFBFQ1RfRVEodmFsdWUsICgqaXQpLnNlY29uZCk7CisgICAgRVhQRUNUX0VRKGtleSwgICBpdC0+Zmlyc3QpOworICAgIEVYUEVDVF9FUSh2YWx1ZSwgaXQtPnNlY29uZCk7CisKKyAgICAvLyBpdGVyYXRvciBtdXRhYmxlCisgICAgKCgqaXQpLnNlY29uZCkgPSB2YWx1ZSArIDE7CisgICAgRVhQRUNUX0VRKHZhbHVlICsgMSwgbWFwX1trZXldKTsKKyAgICAoKCppdCkuc2Vjb25kKSA9IHZhbHVlOworICAgIEVYUEVDVF9FUSh2YWx1ZSwgbWFwX1trZXldKTsKKworICAgIGl0LT5zZWNvbmQgPSB2YWx1ZSArIDE7CisgICAgRVhQRUNUX0VRKHZhbHVlICsgMSwgbWFwX1trZXldKTsKKyAgICBpdC0+c2Vjb25kID0gdmFsdWU7CisgICAgRVhQRUNUX0VRKHZhbHVlLCBtYXBfW2tleV0pOworCisgICAgLy8gY29weSBjb25zdHJ1Y3RvcgorICAgIE1hcDxpbnQzMiwgaW50MzI+OjppdGVyYXRvciBpdF9jb3B5ID0gaXQ7CisgICAgRVhQRUNUX0VRKGtleSwgaXRfY29weS0+Zmlyc3QpOworICAgIEVYUEVDVF9FUSh2YWx1ZSwgaXRfY29weS0+c2Vjb25kKTsKKworICAgIC8vIEltbXV0YWJsZSBBUEkgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKyAgICAvLyBDaGVjayBpbW11dGFibGUgYXQgYW5kIGZpbmQgd29yayBjb3JyZWN0bHkuCisgICAgRVhQRUNUX0VRKHZhbHVlLCBjb25zdF9tYXBfLmF0KGtleSkpOworICAgIE1hcDxpbnQzMiwgaW50MzI+Ojpjb25zdF9pdGVyYXRvciBjb25zdF9pdCA9IGNvbnN0X21hcF8uZmluZChrZXkpOworCisgICAgLy8gaW50ZXJhdG9yIGRlcmVmZXJlbmNlYWJsZQorICAgIEVYUEVDVF9FUShrZXksICgqY29uc3RfaXQpLmZpcnN0KTsKKyAgICBFWFBFQ1RfRVEodmFsdWUsICgqY29uc3RfaXQpLnNlY29uZCk7CisgICAgRVhQRUNUX0VRKGtleSwgY29uc3RfaXQtPmZpcnN0KTsKKyAgICBFWFBFQ1RfRVEodmFsdWUsIGNvbnN0X2l0LT5zZWNvbmQpOworCisgICAgLy8gY29weSBjb25zdHJ1Y3RvcgorICAgIE1hcDxpbnQzMiwgaW50MzI+Ojpjb25zdF9pdGVyYXRvciBjb25zdF9pdF9jb3B5ID0gY29uc3RfaXQ7CisgICAgRVhQRUNUX0VRKGtleSwgY29uc3RfaXRfY29weS0+Zmlyc3QpOworICAgIEVYUEVDVF9FUSh2YWx1ZSwgY29uc3RfaXRfY29weS0+c2Vjb25kKTsKKyAgfQorCisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8TWFwPGludDMyLCBpbnQzMj4gPiBtYXBfcHRyXzsKKyAgTWFwPGludDMyLCBpbnQzMj4mIG1hcF87CisgIGNvbnN0IE1hcDxpbnQzMiwgaW50MzI+JiBjb25zdF9tYXBfOworfTsKKworVEVTVF9GKE1hcEltcGxUZXN0LCBPcGVyYXRvckJyYWNrZXQpIHsKKyAgaW50MzIga2V5ID0gMDsKKyAgaW50MzIgdmFsdWUxID0gMTAwOworICBpbnQzMiB2YWx1ZTIgPSAxMDE7CisKKyAgRVhQRUNUX0VRKDAsIG1hcF9ba2V5XSk7CisKKyAgbWFwX1trZXldID0gdmFsdWUxOworICBFeHBlY3RTaW5nbGVFbGVtZW50KGtleSwgdmFsdWUxKTsKKworICBtYXBfW2tleV0gPSB2YWx1ZTI7CisgIEV4cGVjdFNpbmdsZUVsZW1lbnQoa2V5LCB2YWx1ZTIpOworfQorCitURVNUX0YoTWFwSW1wbFRlc3QsIE9wZXJhdG9yQnJhY2tldE5vbkV4aXN0KSB7CisgIGludDMyIGtleSA9IDA7CisgIGludDMyIGRlZmF1bHRfdmFsdWUgPSAwOworCisgIEVYUEVDVF9FUShkZWZhdWx0X3ZhbHVlLCBtYXBfW2tleV0pOworICBFeHBlY3RTaW5nbGVFbGVtZW50KGtleSwgZGVmYXVsdF92YWx1ZSk7Cit9CisKK1RFU1RfRihNYXBJbXBsVGVzdCwgTXV0YWJsZUF0KSB7CisgIGludDMyIGtleSA9IDA7CisgIGludDMyIHZhbHVlMSA9IDEwMDsKKyAgaW50MzIgdmFsdWUyID0gMTAxOworCisgIG1hcF9ba2V5XSA9IHZhbHVlMTsKKyAgRXhwZWN0U2luZ2xlRWxlbWVudChrZXksIHZhbHVlMSk7CisKKyAgbWFwXy5hdChrZXkpID0gdmFsdWUyOworICBFeHBlY3RTaW5nbGVFbGVtZW50KGtleSwgdmFsdWUyKTsKK30KKworI2lmZGVmIFBST1RPQlVGX0hBU19ERUFUSF9URVNUCisKK1RFU1RfRihNYXBJbXBsVGVzdCwgTXV0YWJsZUF0Tm9uRXhpc3REZWF0aFRlc3QpIHsKKyAgRVhQRUNUX0RFQVRIKG1hcF8uYXQoMCksICIiKTsKK30KKworVEVTVF9GKE1hcEltcGxUZXN0LCBJbW11dGFibGVBdE5vbkV4aXN0RGVhdGhUZXN0KSB7CisgIEVYUEVDVF9ERUFUSChjb25zdF9tYXBfLmF0KDApLCAiIik7Cit9CisKK1RFU1RfRihNYXBJbXBsVGVzdCwgVXNhZ2VFcnJvcnMpIHsKKyAgTWFwS2V5IGtleTsKKyAga2V5LlNldEludDY0VmFsdWUoMSk7CisgIEVYUEVDVF9ERUFUSChrZXkuR2V0VUludDY0VmFsdWUoKSwKKyAgICAgICAgICAgICAgICJQcm90b2NvbCBCdWZmZXIgbWFwIHVzYWdlIGVycm9yOlxuIgorICAgICAgICAgICAgICAgIk1hcEtleTo6R2V0VUludDY0VmFsdWUgdHlwZSBkb2VzIG5vdCBtYXRjaFxuIgorICAgICAgICAgICAgICAgIiAgRXhwZWN0ZWQgOiB1aW50NjRcbiIKKyAgICAgICAgICAgICAgICIgIEFjdHVhbCAgIDogaW50NjQiKTsKKworICBNYXBWYWx1ZVJlZiB2YWx1ZTsKKyAgRVhQRUNUX0RFQVRIKHZhbHVlLlNldEZsb2F0VmFsdWUoMC4xKSwKKyAgICAgICAgICAgICAgICJQcm90b2NvbCBCdWZmZXIgbWFwIHVzYWdlIGVycm9yOlxuIgorICAgICAgICAgICAgICAgIk1hcFZhbHVlUmVmOjp0eXBlIE1hcFZhbHVlUmVmIGlzIG5vdCBpbml0aWFsaXplZC4iKTsKK30KKworI2VuZGlmICAvLyBQUk9UT0JVRl9IQVNfREVBVEhfVEVTVAorCitURVNUX0YoTWFwSW1wbFRlc3QsIENvdW50Tm9uRXhpc3QpIHsKKyAgRVhQRUNUX0VRKDAsIG1hcF8uY291bnQoMCkpOworfQorCitURVNUX0YoTWFwSW1wbFRlc3QsIE11dGFibGVGaW5kTm9uRXhpc3QpIHsKKyAgRVhQRUNUX1RSVUUobWFwXy5lbmQoKSA9PSBtYXBfLmZpbmQoMCkpOworfQorCitURVNUX0YoTWFwSW1wbFRlc3QsIEltbXV0YWJsZUZpbmROb25FeGlzdCkgeworICBFWFBFQ1RfVFJVRShjb25zdF9tYXBfLmVuZCgpID09IGNvbnN0X21hcF8uZmluZCgwKSk7Cit9CisKK1RFU1RfRihNYXBJbXBsVGVzdCwgQ29uc3RFbmQpIHsKKyAgRVhQRUNUX1RSVUUoY29uc3RfbWFwXy5lbmQoKSA9PSBjb25zdF9tYXBfLmNlbmQoKSk7Cit9CisKK1RFU1RfRihNYXBJbXBsVGVzdCwgR2V0UmVmZXJlbmNlRnJvbUl0ZXJhdG9yKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7IGkrKykgeworICAgIG1hcF9baV0gPSBpOworICB9CisKKyAgZm9yIChNYXA8aW50MzIsIGludDMyPjo6Y29uc3RfaXRlcmF0b3IgaXQgPSBtYXBfLmNiZWdpbigpOworICAgICAgIGl0ICE9IG1hcF8uY2VuZCgpOykgeworICAgIE1hcDxpbnQzMiwgaW50MzI+Ojpjb25zdF9yZWZlcmVuY2UgZW50cnkgPSAqaXQrKzsKKyAgICBFWFBFQ1RfRVEoZW50cnkuZmlyc3QsIGVudHJ5LnNlY29uZCk7CisgIH0KKworICBmb3IgKE1hcDxpbnQzMiwgaW50MzI+Ojpjb25zdF9pdGVyYXRvciBpdCA9IGNvbnN0X21hcF8uYmVnaW4oKTsKKyAgICAgICBpdCAhPSBjb25zdF9tYXBfLmVuZCgpOykgeworICAgIE1hcDxpbnQzMiwgaW50MzI+Ojpjb25zdF9yZWZlcmVuY2UgZW50cnkgPSAqaXQrKzsKKyAgICBFWFBFQ1RfRVEoZW50cnkuZmlyc3QsIGVudHJ5LnNlY29uZCk7CisgIH0KKworICBmb3IgKE1hcDxpbnQzMiwgaW50MzI+OjppdGVyYXRvciBpdCA9IG1hcF8uYmVnaW4oKTsgaXQgIT0gbWFwXy5lbmQoKTspIHsKKyAgICBNYXA8aW50MzIsIGludDMyPjo6cmVmZXJlbmNlIGVudHJ5ID0gKml0Kys7CisgICAgRVhQRUNUX0VRKGVudHJ5LmZpcnN0ICsgMSwgKytlbnRyeS5zZWNvbmQpOworICB9Cit9CisKK1RFU1RfRihNYXBJbXBsVGVzdCwgSXRlcmF0b3JCYXNpYykgeworICBtYXBfWzBdID0gMDsKKworICAvLyBEZWZhdWx0IGNvbnN0cnVjdGlibGUgKHBlciBmb3J3YXJkIGl0ZXJhdG9yIHJlcXVpcmVtZW50cykuCisgIE1hcDxpbnQsIGludD46OmNvbnN0X2l0ZXJhdG9yIGNpdDsKKyAgTWFwPGludCwgaW50Pjo6aXRlcmF0b3IgaXQ7CisKKyAgaXQgPSBtYXBfLmJlZ2luKCk7CisgIGNpdCA9IGl0OyAgLy8gQ29udmVydHMgdG8gY29uc3RfaXRlcmF0b3IKKworICAvLyBDYW4gY29tcGFyZSBiZXR3ZWVuIHRoZW0uCisgIEVYUEVDVF9UUlVFKGl0ID09IGNpdCk7CisgIEVYUEVDVF9GQUxTRShjaXQgIT0gaXQpOworCisgIC8vIFByZSBpbmNyZW1lbnQuCisgIEVYUEVDVF9GQUxTRShpdCA9PSArK2NpdCk7CisKKyAgLy8gUG9zdCBpbmNyZW1lbnQuCisgIEVYUEVDVF9GQUxTRShpdCsrID09IGNpdCk7CisgIEVYUEVDVF9UUlVFKGl0ID09IGNpdCk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBUPgorYm9vbCBJc0NvbnN0SGVscGVyKFQmIC8qdCovKSB7ICAvLyBOT0xJTlQuIFdlIHdhbnQgdG8gY2F0Y2ggbm9uLWNvbnN0IHJlZnMgaGVyZS4KKyAgcmV0dXJuIGZhbHNlOworfQordGVtcGxhdGUgPHR5cGVuYW1lIFQ+Citib29sIElzQ29uc3RIZWxwZXIoY29uc3QgVCYgLyp0Ki8pIHsKKyAgcmV0dXJuIHRydWU7Cit9CisKK1RFU1RfRihNYXBJbXBsVGVzdCwgSXRlcmF0b3JDb25zdG5lc3MpIHsKKyAgbWFwX1swXSA9IDA7CisgIEVYUEVDVF9UUlVFKElzQ29uc3RIZWxwZXIoKm1hcF8uY2JlZ2luKCkpKTsKKyAgRVhQRUNUX1RSVUUoSXNDb25zdEhlbHBlcigqY29uc3RfbWFwXy5iZWdpbigpKSk7CisgIEVYUEVDVF9GQUxTRShJc0NvbnN0SGVscGVyKCptYXBfLmJlZ2luKCkpKTsKK30KKworYm9vbCBJc0ZvcndhcmRJdGVyYXRvckhlbHBlcihzdGQ6OmZvcndhcmRfaXRlcmF0b3JfdGFnIC8qdGFnKi8pIHsgcmV0dXJuIHRydWU7IH0KK3RlbXBsYXRlIDx0eXBlbmFtZSBUPgorYm9vbCBJc0ZvcndhcmRJdGVyYXRvckhlbHBlcihUIC8qdCovKSB7CisgIHJldHVybiBmYWxzZTsKK30KKworVEVTVF9GKE1hcEltcGxUZXN0LCBJdGVyYXRvckNhdGVnb3J5KSB7CisgIEVYUEVDVF9UUlVFKElzRm9yd2FyZEl0ZXJhdG9ySGVscGVyKAorICAgICAgc3RkOjppdGVyYXRvcl90cmFpdHM8TWFwPGludCwgaW50Pjo6aXRlcmF0b3I+OjppdGVyYXRvcl9jYXRlZ29yeSgpKSk7CisgIEVYUEVDVF9UUlVFKElzRm9yd2FyZEl0ZXJhdG9ySGVscGVyKHN0ZDo6aXRlcmF0b3JfdHJhaXRzPAorICAgICAgTWFwPGludCwgaW50Pjo6Y29uc3RfaXRlcmF0b3I+OjppdGVyYXRvcl9jYXRlZ29yeSgpKSk7Cit9CisKK1RFU1RfRihNYXBJbXBsVGVzdCwgSW5zZXJ0U2luZ2xlKSB7CisgIGludDMyIGtleSA9IDA7CisgIGludDMyIHZhbHVlMSA9IDEwMDsKKyAgaW50MzIgdmFsdWUyID0gMTAxOworCisgIC8vIEluc2VydCBhIG5vbi1leGlzdGVkIGtleS4KKyAgc3RkOjpwYWlyPE1hcDxpbnQzMiwgaW50MzI+OjppdGVyYXRvciwgYm9vbD4gcmVzdWx0MSA9CisgICAgICBtYXBfLmluc2VydChNYXA8aW50MzIsIGludDMyPjo6dmFsdWVfdHlwZShrZXksIHZhbHVlMSkpOworICBFeHBlY3RTaW5nbGVFbGVtZW50KGtleSwgdmFsdWUxKTsKKworICBNYXA8aW50MzIsIGludDMyPjo6aXRlcmF0b3IgaXQxID0gcmVzdWx0MS5maXJzdDsKKyAgRVhQRUNUX0VRKGtleSwgaXQxLT5maXJzdCk7CisgIEVYUEVDVF9FUSh2YWx1ZTEsIGl0MS0+c2Vjb25kKTsKKyAgRVhQRUNUX1RSVUUocmVzdWx0MS5zZWNvbmQpOworCisgIC8vIEluc2VydCBhbiBleGlzdGVkIGtleS4KKyAgc3RkOjpwYWlyPE1hcDxpbnQzMiwgaW50MzI+OjppdGVyYXRvciwgYm9vbD4gcmVzdWx0MiA9CisgICAgICBtYXBfLmluc2VydChNYXA8aW50MzIsIGludDMyPjo6dmFsdWVfdHlwZShrZXksIHZhbHVlMikpOworICBFeHBlY3RTaW5nbGVFbGVtZW50KGtleSwgdmFsdWUxKTsKKworICBNYXA8aW50MzIsIGludDMyPjo6aXRlcmF0b3IgaXQyID0gcmVzdWx0Mi5maXJzdDsKKyAgRVhQRUNUX1RSVUUoaXQxID09IGl0Mik7CisgIEVYUEVDVF9GQUxTRShyZXN1bHQyLnNlY29uZCk7Cit9CisKK1RFU1RfRihNYXBJbXBsVGVzdCwgSW5zZXJ0QnlJdGVyYXRvcikgeworICBpbnQzMiBrZXkxID0gMDsKKyAgaW50MzIga2V5MiA9IDE7CisgIGludDMyIHZhbHVlMWEgPSAxMDA7CisgIGludDMyIHZhbHVlMWIgPSAxMDE7CisgIGludDMyIHZhbHVlMmEgPSAyMDA7CisgIGludDMyIHZhbHVlMmIgPSAyMDE7CisKKyAgc3RkOjptYXA8aW50MzIsIGludDMyPiBtYXAxOworICBtYXAxW2tleTFdID0gdmFsdWUxYTsKKyAgbWFwMVtrZXkyXSA9IHZhbHVlMmE7CisKKyAgbWFwXy5pbnNlcnQobWFwMS5iZWdpbigpLCBtYXAxLmVuZCgpKTsKKyAgRXhwZWN0RWxlbWVudHMobWFwMSk7CisKKyAgc3RkOjptYXA8aW50MzIsIGludDMyPiBtYXAyOworICBtYXAyW2tleTFdID0gdmFsdWUxYjsKKyAgbWFwMltrZXkyXSA9IHZhbHVlMmI7CisKKyAgbWFwXy5pbnNlcnQobWFwMi5iZWdpbigpLCBtYXAyLmVuZCgpKTsKKyAgRXhwZWN0RWxlbWVudHMobWFwMSk7Cit9CisKK1RFU1RfRihNYXBJbXBsVGVzdCwgRXJhc2VTaW5nbGVCeUtleSkgeworICBpbnQzMiBrZXkgPSAwOworICBpbnQzMiB2YWx1ZSA9IDEwMDsKKworICBtYXBfW2tleV0gPSB2YWx1ZTsKKyAgRXhwZWN0U2luZ2xlRWxlbWVudChrZXksIHZhbHVlKTsKKworICAvLyBFcmFzZSBhbiBleGlzdGluZyBrZXkuCisgIEVYUEVDVF9FUSgxLCBtYXBfLmVyYXNlKGtleSkpOworICBFWFBFQ1RfVFJVRShtYXBfLmVtcHR5KCkpOworICBFWFBFQ1RfRVEoMCwgbWFwXy5zaXplKCkpOworICBFWFBFQ1RfVFJVRShtYXBfLmVuZCgpID09IG1hcF8uZmluZChrZXkpKTsKKyAgRVhQRUNUX1RSVUUobWFwXy5iZWdpbigpID09IG1hcF8uZW5kKCkpOworCisgIC8vIEVyYXNlIGEgbm9uLWV4aXN0aW5nIGtleS4KKyAgRVhQRUNUX0VRKDAsIG1hcF8uZXJhc2Uoa2V5KSk7Cit9CisKK1RFU1RfRihNYXBJbXBsVGVzdCwgRXJhc2VNdXRpcGxlQnlLZXkpIHsKKyAgLy8gZXJhc2UgaW4gb25lIHNwZWNpZmljIG9yZGVyIHRvIHRyaWdnZXIgY29ybmVyIGNhc2VzCisgIGZvciAoaW50IGkgPSAwOyBpIDwgNTsgaSsrKSB7CisgICAgbWFwX1tpXSA9IGk7CisgIH0KKworICBtYXBfLmVyYXNlKDApOworICBFWFBFQ1RfRVEoNCwgbWFwXy5zaXplKCkpOworICBFWFBFQ1RfVFJVRShtYXBfLmVuZCgpID09IG1hcF8uZmluZCgwKSk7CisKKyAgbWFwXy5lcmFzZSgxKTsKKyAgRVhQRUNUX0VRKDMsIG1hcF8uc2l6ZSgpKTsKKyAgRVhQRUNUX1RSVUUobWFwXy5lbmQoKSA9PSBtYXBfLmZpbmQoMSkpOworCisgIG1hcF8uZXJhc2UoMyk7CisgIEVYUEVDVF9FUSgyLCBtYXBfLnNpemUoKSk7CisgIEVYUEVDVF9UUlVFKG1hcF8uZW5kKCkgPT0gbWFwXy5maW5kKDMpKTsKKworICBtYXBfLmVyYXNlKDQpOworICBFWFBFQ1RfRVEoMSwgbWFwXy5zaXplKCkpOworICBFWFBFQ1RfVFJVRShtYXBfLmVuZCgpID09IG1hcF8uZmluZCg0KSk7CisKKyAgbWFwXy5lcmFzZSgyKTsKKyAgRVhQRUNUX0VRKDAsIG1hcF8uc2l6ZSgpKTsKKyAgRVhQRUNUX1RSVUUobWFwXy5lbmQoKSA9PSBtYXBfLmZpbmQoMikpOworfQorCitURVNUX0YoTWFwSW1wbFRlc3QsIEVyYXNlU2luZ2xlQnlJdGVyYXRvcikgeworICBpbnQzMiBrZXkgPSAwOworICBpbnQzMiB2YWx1ZSA9IDEwMDsKKworICBtYXBfW2tleV0gPSB2YWx1ZTsKKyAgRXhwZWN0U2luZ2xlRWxlbWVudChrZXksIHZhbHVlKTsKKworICBNYXA8aW50MzIsIGludDMyPjo6aXRlcmF0b3IgaXQgPSBtYXBfLmZpbmQoa2V5KTsKKyAgbWFwXy5lcmFzZShpdCk7CisgIEVYUEVDVF9UUlVFKG1hcF8uZW1wdHkoKSk7CisgIEVYUEVDVF9FUSgwLCBtYXBfLnNpemUoKSk7CisgIEVYUEVDVF9UUlVFKG1hcF8uZW5kKCkgPT0gbWFwXy5maW5kKGtleSkpOworICBFWFBFQ1RfVFJVRShtYXBfLmJlZ2luKCkgPT0gbWFwXy5lbmQoKSk7Cit9CisKK1RFU1RfRihNYXBJbXBsVGVzdCwgVmFsaWRJdGVyYXRvckFmdGVyRXJhc2UpIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgaSsrKSB7CisgICAgbWFwX1tpXSA9IGk7CisgIH0KKworICBpbnQgY291bnQgPSAwOworCisgIGZvciAoTWFwPGludDMyLCBpbnQzMj46Oml0ZXJhdG9yIGl0ID0gbWFwXy5iZWdpbigpOyBpdCAhPSBtYXBfLmVuZCgpOykgeworICAgIGNvdW50Kys7CisgICAgaWYgKGl0LT5maXJzdCAlIDIgPT0gMSkgeworICAgICAgbWFwXy5lcmFzZShpdCsrKTsKKyAgICB9IGVsc2UgeworICAgICAgKytpdDsKKyAgICB9CisgIH0KKworICBFWFBFQ1RfRVEoMTAsIGNvdW50KTsKKyAgRVhQRUNUX0VRKDUsIG1hcF8uc2l6ZSgpKTsKK30KKworVEVTVF9GKE1hcEltcGxUZXN0LCBFcmFzZUJ5SXRlcmF0b3IpIHsKKyAgaW50MzIga2V5MSA9IDA7CisgIGludDMyIGtleTIgPSAxOworICBpbnQzMiB2YWx1ZTEgPSAxMDA7CisgIGludDMyIHZhbHVlMiA9IDEwMTsKKworICBzdGQ6Om1hcDxpbnQzMiwgaW50MzI+IG1hcDsKKyAgbWFwW2tleTFdID0gdmFsdWUxOworICBtYXBba2V5Ml0gPSB2YWx1ZTI7CisKKyAgbWFwXy5pbnNlcnQobWFwLmJlZ2luKCksIG1hcC5lbmQoKSk7CisgIEV4cGVjdEVsZW1lbnRzKG1hcCk7CisKKyAgbWFwXy5lcmFzZShtYXBfLmJlZ2luKCksIG1hcF8uZW5kKCkpOworICBFWFBFQ1RfVFJVRShtYXBfLmVtcHR5KCkpOworICBFWFBFQ1RfRVEoMCwgbWFwXy5zaXplKCkpOworICBFWFBFQ1RfVFJVRShtYXBfLmVuZCgpID09IG1hcF8uZmluZChrZXkxKSk7CisgIEVYUEVDVF9UUlVFKG1hcF8uZW5kKCkgPT0gbWFwXy5maW5kKGtleTIpKTsKKyAgRVhQRUNUX1RSVUUobWFwXy5iZWdpbigpID09IG1hcF8uZW5kKCkpOworfQorCitURVNUX0YoTWFwSW1wbFRlc3QsIENsZWFyKSB7CisgIGludDMyIGtleSA9IDA7CisgIGludDMyIHZhbHVlID0gMTAwOworCisgIG1hcF9ba2V5XSA9IHZhbHVlOworICBFeHBlY3RTaW5nbGVFbGVtZW50KGtleSwgdmFsdWUpOworCisgIG1hcF8uY2xlYXIoKTsKKworICBFWFBFQ1RfVFJVRShtYXBfLmVtcHR5KCkpOworICBFWFBFQ1RfRVEoMCwgbWFwXy5zaXplKCkpOworICBFWFBFQ1RfVFJVRShtYXBfLmVuZCgpID09IG1hcF8uZmluZChrZXkpKTsKKyAgRVhQRUNUX1RSVUUobWFwXy5iZWdpbigpID09IG1hcF8uZW5kKCkpOworfQorCitURVNUX0YoTWFwSW1wbFRlc3QsIENvcHlDb25zdHJ1Y3RvcikgeworICBpbnQzMiBrZXkxID0gMDsKKyAgaW50MzIga2V5MiA9IDE7CisgIGludDMyIHZhbHVlMSA9IDEwMDsKKyAgaW50MzIgdmFsdWUyID0gMTAxOworCisgIHN0ZDo6bWFwPGludDMyLCBpbnQzMj4gbWFwOworICBtYXBba2V5MV0gPSB2YWx1ZTE7CisgIG1hcFtrZXkyXSA9IHZhbHVlMjsKKworICBtYXBfLmluc2VydChtYXAuYmVnaW4oKSwgbWFwLmVuZCgpKTsKKworICBNYXA8aW50MzIsIGludDMyPiBvdGhlcihtYXBfKTsKKworICBFWFBFQ1RfRVEoMiwgb3RoZXIuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKHZhbHVlMSwgb3RoZXIuYXQoa2V5MSkpOworICBFWFBFQ1RfRVEodmFsdWUyLCBvdGhlci5hdChrZXkyKSk7Cit9CisKK1RFU1RfRihNYXBJbXBsVGVzdCwgSXRlckNvbnN0cnVjdG9yKSB7CisgIGludDMyIGtleTEgPSAwOworICBpbnQzMiBrZXkyID0gMTsKKyAgaW50MzIgdmFsdWUxID0gMTAwOworICBpbnQzMiB2YWx1ZTIgPSAxMDE7CisKKyAgc3RkOjptYXA8aW50MzIsIGludDMyPiBtYXA7CisgIG1hcFtrZXkxXSA9IHZhbHVlMTsKKyAgbWFwW2tleTJdID0gdmFsdWUyOworCisgIE1hcDxpbnQzMiwgaW50MzI+IG5ld19tYXAobWFwLmJlZ2luKCksIG1hcC5lbmQoKSk7CisKKyAgRVhQRUNUX0VRKDIsIG5ld19tYXAuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKHZhbHVlMSwgbmV3X21hcC5hdChrZXkxKSk7CisgIEVYUEVDVF9FUSh2YWx1ZTIsIG5ld19tYXAuYXQoa2V5MikpOworfQorCitURVNUX0YoTWFwSW1wbFRlc3QsIEFzc2lnbmVyKSB7CisgIGludDMyIGtleTEgPSAwOworICBpbnQzMiBrZXkyID0gMTsKKyAgaW50MzIgdmFsdWUxID0gMTAwOworICBpbnQzMiB2YWx1ZTIgPSAxMDE7CisKKyAgc3RkOjptYXA8aW50MzIsIGludDMyPiBtYXA7CisgIG1hcFtrZXkxXSA9IHZhbHVlMTsKKyAgbWFwW2tleTJdID0gdmFsdWUyOworCisgIG1hcF8uaW5zZXJ0KG1hcC5iZWdpbigpLCBtYXAuZW5kKCkpOworCisgIE1hcDxpbnQzMiwgaW50MzI+IG90aGVyOworICBpbnQzMiBrZXlfb3RoZXIgPSAxMjM7CisgIGludDMyIHZhbHVlX290aGVyID0gMzIxOworICBvdGhlcltrZXlfb3RoZXJdID0gdmFsdWVfb3RoZXI7CisgIEVYUEVDVF9FUSgxLCBvdGhlci5zaXplKCkpOworCisgIG90aGVyID0gbWFwXzsKKworICBFWFBFQ1RfRVEoMiwgb3RoZXIuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKHZhbHVlMSwgb3RoZXIuYXQoa2V5MSkpOworICBFWFBFQ1RfRVEodmFsdWUyLCBvdGhlci5hdChrZXkyKSk7CisgIEVYUEVDVF9UUlVFKG90aGVyLmZpbmQoa2V5X290aGVyKSA9PSBvdGhlci5lbmQoKSk7CisKKyAgLy8gU2VsZiBhc3NpZ24KKyAgb3RoZXIgPSBvdGhlcjsKKyAgRVhQRUNUX0VRKDIsIG90aGVyLnNpemUoKSk7CisgIEVYUEVDVF9FUSh2YWx1ZTEsIG90aGVyLmF0KGtleTEpKTsKKyAgRVhQRUNUX0VRKHZhbHVlMiwgb3RoZXIuYXQoa2V5MikpOworfQorCitURVNUX0YoTWFwSW1wbFRlc3QsIFJlaGFzaCkgeworICBjb25zdCBpbnQgdGVzdF9zaXplID0gNTA7CisgIHN0ZDo6bWFwPGludDMyLCBpbnQzMj4gcmVmZXJlbmNlX21hcDsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0ZXN0X3NpemU7IGkrKykgeworICAgIHJlZmVyZW5jZV9tYXBbaV0gPSBpOworICB9CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGVzdF9zaXplOyBpKyspIHsKKyAgICBtYXBfW2ldID0gcmVmZXJlbmNlX21hcFtpXTsKKyAgICBFWFBFQ1RfRVEocmVmZXJlbmNlX21hcFtpXSwgbWFwX1tpXSk7CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0ZXN0X3NpemU7IGkrKykgeworICAgIG1hcF8uZXJhc2UoaSk7CisgICAgRVhQRUNUX1RSVUUobWFwXy5lbmQoKSA9PSBtYXBfLmZpbmQoaSkpOworICB9CisgIEVYUEVDVF9UUlVFKG1hcF8uZW1wdHkoKSk7Cit9CisKK1RFU1RfRihNYXBJbXBsVGVzdCwgRXF1YWxSYW5nZSkgeworICBpbnQga2V5ID0gMTAwLCBrZXlfbWlzc2luZyA9IDEwMTsKKyAgbWFwX1trZXldID0gMTAwOworCisgIHN0ZDo6cGFpcjxnb29nbGU6OnByb3RvYnVmOjpNYXA8aW50MzIsIGludDMyPjo6aXRlcmF0b3IsCisgICAgICAgICAgICBnb29nbGU6OnByb3RvYnVmOjpNYXA8aW50MzIsIGludDMyPjo6aXRlcmF0b3I+IHJhbmdlID0gbWFwXy5lcXVhbF9yYW5nZShrZXkpOworICBFWFBFQ1RfVFJVRShtYXBfLmZpbmQoa2V5KSA9PSByYW5nZS5maXJzdCk7CisgIEVYUEVDVF9UUlVFKCsrbWFwXy5maW5kKGtleSkgPT0gcmFuZ2Uuc2Vjb25kKTsKKworICByYW5nZSA9IG1hcF8uZXF1YWxfcmFuZ2Uoa2V5X21pc3NpbmcpOworICBFWFBFQ1RfVFJVRShtYXBfLmVuZCgpID09IHJhbmdlLmZpcnN0KTsKKyAgRVhQRUNUX1RSVUUobWFwXy5lbmQoKSA9PSByYW5nZS5zZWNvbmQpOworCisgIHN0ZDo6cGFpcjxnb29nbGU6OnByb3RvYnVmOjpNYXA8aW50MzIsIGludDMyPjo6Y29uc3RfaXRlcmF0b3IsCisgICAgICAgICAgICBnb29nbGU6OnByb3RvYnVmOjpNYXA8aW50MzIsIGludDMyPjo6Y29uc3RfaXRlcmF0b3I+IGNvbnN0X3JhbmdlID0KKyAgICAgIGNvbnN0X21hcF8uZXF1YWxfcmFuZ2Uoa2V5KTsKKyAgRVhQRUNUX1RSVUUoY29uc3RfbWFwXy5maW5kKGtleSkgPT0gY29uc3RfcmFuZ2UuZmlyc3QpOworICBFWFBFQ1RfVFJVRSgrK2NvbnN0X21hcF8uZmluZChrZXkpID09IGNvbnN0X3JhbmdlLnNlY29uZCk7CisKKyAgY29uc3RfcmFuZ2UgPSBjb25zdF9tYXBfLmVxdWFsX3JhbmdlKGtleV9taXNzaW5nKTsKKyAgRVhQRUNUX1RSVUUoY29uc3RfbWFwXy5lbmQoKSA9PSBjb25zdF9yYW5nZS5maXJzdCk7CisgIEVYUEVDVF9UUlVFKGNvbnN0X21hcF8uZW5kKCkgPT0gY29uc3RfcmFuZ2Uuc2Vjb25kKTsKK30KKworVEVTVF9GKE1hcEltcGxUZXN0LCBDb252ZXJ0VG9TdGRNYXApIHsKKyAgbWFwX1sxMDBdID0gMTAxOworICBzdGQ6Om1hcDxpbnQzMiwgaW50MzI+IHN0ZF9tYXAobWFwXy5iZWdpbigpLCBtYXBfLmVuZCgpKTsKKyAgRVhQRUNUX0VRKDEsIHN0ZF9tYXAuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEwMSwgc3RkX21hcFsxMDBdKTsKK30KKworVEVTVF9GKE1hcEltcGxUZXN0LCBDb252ZXJ0VG9TdGRWZWN0b3JPZlBhaXJzKSB7CisgIG1hcF9bMTAwXSA9IDEwMTsKKyAgc3RkOjp2ZWN0b3I8c3RkOjpwYWlyPGludDMyLCBpbnQzMj4gPiBzdGRfdmVjKG1hcF8uYmVnaW4oKSwgbWFwXy5lbmQoKSk7CisgIEVYUEVDVF9FUSgxLCBzdGRfdmVjLnNpemUoKSk7CisgIEVYUEVDVF9FUSgxMDAsIHN0ZF92ZWNbMF0uZmlyc3QpOworICBFWFBFQ1RfRVEoMTAxLCBzdGRfdmVjWzBdLnNlY29uZCk7Cit9CisKKy8vIE1hcCBGaWVsZCBSZWZsZWN0aW9uIFRlc3QgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitzdGF0aWMgaW50IEZ1bmMoaW50IGksIGludCBqKSB7CisgIHJldHVybiBpICogajsKK30KKworc3RhdGljIHN0cmluZyBTdHJGdW5jKGludCBpLCBpbnQgaikgeworICBzdHJpbmcgc3RyOworICBTU3RyaW5nUHJpbnRmKCZzdHIsICIlZCIsIEZ1bmMoaSwgaikpOworICByZXR1cm4gc3RyOworfQorCitzdGF0aWMgaW50IEludChjb25zdCBzdHJpbmcmIHZhbHVlKSB7CisgIGludCByZXN1bHQgPSAwOworICBzdGQ6OmlzdHJpbmdzdHJlYW0odmFsdWUpID4+IHJlc3VsdDsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworY2xhc3MgTWFwRmllbGRSZWZsZWN0aW9uVGVzdCA6IHB1YmxpYyB0ZXN0aW5nOjpUZXN0IHsKKyBwcm90ZWN0ZWQ6CisgIHR5cGVkZWYgRmllbGREZXNjcmlwdG9yIEZEOworfTsKKworVEVTVF9GKE1hcEZpZWxkUmVmbGVjdGlvblRlc3QsIFJlZ3VsYXJGaWVsZHMpIHsKKyAgVGVzdE1hcCBtZXNzYWdlOworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsID0gbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCk7CisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2MgPSBtZXNzYWdlLkdldERlc2NyaXB0b3IoKTsKKworICBNYXA8aW50MzIsIGludDMyPiogbWFwX2ludDMyX2ludDMyID0gbWVzc2FnZS5tdXRhYmxlX21hcF9pbnQzMl9pbnQzMigpOworICBNYXA8aW50MzIsIGRvdWJsZT4qIG1hcF9pbnQzMl9kb3VibGUgPSBtZXNzYWdlLm11dGFibGVfbWFwX2ludDMyX2RvdWJsZSgpOworICBNYXA8c3RyaW5nLCBzdHJpbmc+KiBtYXBfc3RyaW5nX3N0cmluZyA9IG1lc3NhZ2UubXV0YWJsZV9tYXBfc3RyaW5nX3N0cmluZygpOworICBNYXA8aW50MzIsIEZvcmVpZ25NZXNzYWdlPiogbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSA9CisgICAgICBtZXNzYWdlLm11dGFibGVfbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSgpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7ICsraSkgeworICAgICgqbWFwX2ludDMyX2ludDMyKVtpXSA9IEZ1bmMoaSwgMSk7CisgICAgKCptYXBfaW50MzJfZG91YmxlKVtpXSA9IEZ1bmMoaSwgMik7CisgICAgKCptYXBfc3RyaW5nX3N0cmluZylbU3RyRnVuYyhpLCAxKV0gPSBTdHJGdW5jKGksIDUpOworICAgICgqbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSlbaV0uc2V0X2MoRnVuYyhpLCA2KSk7CisgIH0KKworICAvLyBHZXQgRmllbGREZXNjcmlwdG9ycyBmb3IgYWxsIHRoZSBmaWVsZHMgb2YgaW50ZXJlc3QuCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmRfbWFwX2ludDMyX2ludDMyID0KKyAgICAgIGRlc2MtPkZpbmRGaWVsZEJ5TmFtZSgibWFwX2ludDMyX2ludDMyIik7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmRfbWFwX2ludDMyX2RvdWJsZSA9CisgICAgICBkZXNjLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9pbnQzMl9kb3VibGUiKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmZF9tYXBfc3RyaW5nX3N0cmluZyA9CisgICAgICBkZXNjLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9zdHJpbmdfc3RyaW5nIik7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmRfbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSA9CisgICAgICBkZXNjLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UiKTsKKworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZkX21hcF9pbnQzMl9pbjMyX2tleSA9CisgICAgICBmZF9tYXBfaW50MzJfaW50MzItPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoImtleSIpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZkX21hcF9pbnQzMl9pbjMyX3ZhbHVlID0KKyAgICAgIGZkX21hcF9pbnQzMl9pbnQzMi0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgidmFsdWUiKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmZF9tYXBfaW50MzJfZG91YmxlX2tleSA9CisgICAgICBmZF9tYXBfaW50MzJfZG91YmxlLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJrZXkiKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmZF9tYXBfaW50MzJfZG91YmxlX3ZhbHVlID0KKyAgICAgIGZkX21hcF9pbnQzMl9kb3VibGUtPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoInZhbHVlIik7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmRfbWFwX3N0cmluZ19zdHJpbmdfa2V5ID0KKyAgICAgIGZkX21hcF9zdHJpbmdfc3RyaW5nLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJrZXkiKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmZF9tYXBfc3RyaW5nX3N0cmluZ192YWx1ZSA9CisgICAgICBmZF9tYXBfc3RyaW5nX3N0cmluZy0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgidmFsdWUiKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmZF9tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlX2tleSA9CisgICAgICBmZF9tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJrZXkiKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmZF9tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlX3ZhbHVlID0KKyAgICAgIGZkX21hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UtPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoInZhbHVlIik7CisKKyAgLy8gR2V0IFJlcGVhdGVkUHRyRmllbGQgb2JqZWN0cyBmb3IgYWxsIGZpZWxkcyBvZiBpbnRlcmVzdC4KKyAgY29uc3QgUmVwZWF0ZWRQdHJGaWVsZDxNZXNzYWdlPiYgbWZfaW50MzJfaW50MzIgPQorICAgICAgcmVmbC0+R2V0UmVwZWF0ZWRQdHJGaWVsZDxNZXNzYWdlPihtZXNzYWdlLCBmZF9tYXBfaW50MzJfaW50MzIpOworICBjb25zdCBSZXBlYXRlZFB0ckZpZWxkPE1lc3NhZ2U+JiBtZl9pbnQzMl9kb3VibGUgPQorICAgICAgcmVmbC0+R2V0UmVwZWF0ZWRQdHJGaWVsZDxNZXNzYWdlPihtZXNzYWdlLCBmZF9tYXBfaW50MzJfZG91YmxlKTsKKyAgY29uc3QgUmVwZWF0ZWRQdHJGaWVsZDxNZXNzYWdlPiYgbWZfc3RyaW5nX3N0cmluZyA9CisgICAgICByZWZsLT5HZXRSZXBlYXRlZFB0ckZpZWxkPE1lc3NhZ2U+KG1lc3NhZ2UsIGZkX21hcF9zdHJpbmdfc3RyaW5nKTsKKyAgY29uc3QgUmVwZWF0ZWRQdHJGaWVsZDxNZXNzYWdlPiYKKyAgICAgIG1mX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSA9CisgICAgICAgICAgcmVmbC0+R2V0UmVwZWF0ZWRQdHJGaWVsZDxNZXNzYWdlPigKKyAgICAgICAgICAgICAgbWVzc2FnZSwgZmRfbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSk7CisKKyAgLy8gR2V0IG11dGFibGUgUmVwZWF0ZWRQdHJGaWVsZCBvYmplY3RzIGZvciBhbGwgZmllbGRzIG9mIGludGVyZXN0LgorICBSZXBlYXRlZFB0ckZpZWxkPE1lc3NhZ2U+KiBtbWZfaW50MzJfaW50MzIgPQorICAgICAgcmVmbC0+TXV0YWJsZVJlcGVhdGVkUHRyRmllbGQ8TWVzc2FnZT4oJm1lc3NhZ2UsIGZkX21hcF9pbnQzMl9pbnQzMik7CisgIFJlcGVhdGVkUHRyRmllbGQ8TWVzc2FnZT4qIG1tZl9pbnQzMl9kb3VibGUgPQorICAgICAgcmVmbC0+TXV0YWJsZVJlcGVhdGVkUHRyRmllbGQ8TWVzc2FnZT4oJm1lc3NhZ2UsIGZkX21hcF9pbnQzMl9kb3VibGUpOworICBSZXBlYXRlZFB0ckZpZWxkPE1lc3NhZ2U+KiBtbWZfc3RyaW5nX3N0cmluZyA9CisgICAgICByZWZsLT5NdXRhYmxlUmVwZWF0ZWRQdHJGaWVsZDxNZXNzYWdlPigmbWVzc2FnZSwgZmRfbWFwX3N0cmluZ19zdHJpbmcpOworICBSZXBlYXRlZFB0ckZpZWxkPE1lc3NhZ2U+KiBtbWZfaW50MzJfZm9yZWlnbl9tZXNzYWdlID0KKyAgICAgIHJlZmwtPk11dGFibGVSZXBlYXRlZFB0ckZpZWxkPE1lc3NhZ2U+KAorICAgICAgICAgICZtZXNzYWdlLCBmZF9tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlKTsKKworICAvLyBNYWtlIHN1cmUgd2UgY2FuIGRvIGdldHMgdGhyb3VnaCB0aGUgUmVwZWF0ZWRQdHJGaWVsZCBvYmplY3RzLgorICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyArK2kpIHsKKyAgICB7CisgICAgICAvLyBDaGVjayBnZXRzIHRocm91Z2ggY29uc3Qgb2JqZWN0cy4KKyAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2VfaW50MzJfaW50MzIgPSBtZl9pbnQzMl9pbnQzMi5HZXQoaSk7CisgICAgICBpbnQzMiBrZXlfaW50MzJfaW50MzIgPSBtZXNzYWdlX2ludDMyX2ludDMyLkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIoCisgICAgICAgICAgbWVzc2FnZV9pbnQzMl9pbnQzMiwgZmRfbWFwX2ludDMyX2luMzJfa2V5KTsKKyAgICAgIGludDMyIHZhbHVlX2ludDMyX2ludDMyID0gbWVzc2FnZV9pbnQzMl9pbnQzMi5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKAorICAgICAgICAgIG1lc3NhZ2VfaW50MzJfaW50MzIsIGZkX21hcF9pbnQzMl9pbjMyX3ZhbHVlKTsKKyAgICAgIEVYUEVDVF9FUSh2YWx1ZV9pbnQzMl9pbnQzMiwgRnVuYyhrZXlfaW50MzJfaW50MzIsIDEpKTsKKworICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZV9pbnQzMl9kb3VibGUgPSBtZl9pbnQzMl9kb3VibGUuR2V0KGkpOworICAgICAgaW50MzIga2V5X2ludDMyX2RvdWJsZSA9IG1lc3NhZ2VfaW50MzJfZG91YmxlLkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIoCisgICAgICAgICAgbWVzc2FnZV9pbnQzMl9kb3VibGUsIGZkX21hcF9pbnQzMl9kb3VibGVfa2V5KTsKKyAgICAgIGRvdWJsZSB2YWx1ZV9pbnQzMl9kb3VibGUgPQorICAgICAgICAgIG1lc3NhZ2VfaW50MzJfZG91YmxlLkdldFJlZmxlY3Rpb24oKS0+R2V0RG91YmxlKAorICAgICAgICAgICAgICBtZXNzYWdlX2ludDMyX2RvdWJsZSwgZmRfbWFwX2ludDMyX2RvdWJsZV92YWx1ZSk7CisgICAgICBFWFBFQ1RfRVEodmFsdWVfaW50MzJfZG91YmxlLCBGdW5jKGtleV9pbnQzMl9kb3VibGUsIDIpKTsKKworICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZV9zdHJpbmdfc3RyaW5nID0gbWZfc3RyaW5nX3N0cmluZy5HZXQoaSk7CisgICAgICBzdHJpbmcga2V5X3N0cmluZ19zdHJpbmcgPQorICAgICAgICAgIG1lc3NhZ2Vfc3RyaW5nX3N0cmluZy5HZXRSZWZsZWN0aW9uKCktPkdldFN0cmluZygKKyAgICAgICAgICAgICAgbWVzc2FnZV9zdHJpbmdfc3RyaW5nLCBmZF9tYXBfc3RyaW5nX3N0cmluZ19rZXkpOworICAgICAgc3RyaW5nIHZhbHVlX3N0cmluZ19zdHJpbmcgPQorICAgICAgICAgIG1lc3NhZ2Vfc3RyaW5nX3N0cmluZy5HZXRSZWZsZWN0aW9uKCktPkdldFN0cmluZygKKyAgICAgICAgICAgICAgbWVzc2FnZV9zdHJpbmdfc3RyaW5nLCBmZF9tYXBfc3RyaW5nX3N0cmluZ192YWx1ZSk7CisgICAgICBFWFBFQ1RfRVEodmFsdWVfc3RyaW5nX3N0cmluZywgU3RyRnVuYyhJbnQoa2V5X3N0cmluZ19zdHJpbmcpLCA1KSk7CisKKyAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2VfaW50MzJfbWVzc2FnZSA9IG1mX2ludDMyX2ZvcmVpZ25fbWVzc2FnZS5HZXQoaSk7CisgICAgICBpbnQzMiBrZXlfaW50MzJfbWVzc2FnZSA9IG1lc3NhZ2VfaW50MzJfbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKAorICAgICAgICAgIG1lc3NhZ2VfaW50MzJfbWVzc2FnZSwgZmRfbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZV9rZXkpOworICAgICAgY29uc3QgRm9yZWlnbk1lc3NhZ2UmIHZhbHVlX2ludDMyX21lc3NhZ2UgPQorICAgICAgICAgIGRvd25fY2FzdDxjb25zdCBGb3JlaWduTWVzc2FnZSY+KAorICAgICAgICAgICAgICBtZXNzYWdlX2ludDMyX21lc3NhZ2UuR2V0UmVmbGVjdGlvbigpCisgICAgICAgICAgICAgICAgICAtPkdldE1lc3NhZ2UobWVzc2FnZV9pbnQzMl9tZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZkX21hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2VfdmFsdWUpKTsKKyAgICAgIEVYUEVDVF9FUSh2YWx1ZV9pbnQzMl9tZXNzYWdlLmMoKSwgRnVuYyhrZXlfaW50MzJfbWVzc2FnZSwgNikpOworICAgIH0KKworICAgIHsKKyAgICAgIC8vIENoZWNrIGdldHMgdGhyb3VnaCBtdXRhYmxlIG9iamVjdHMuCisgICAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlX2ludDMyX2ludDMyID0gbW1mX2ludDMyX2ludDMyLT5HZXQoaSk7CisgICAgICBpbnQzMiBrZXlfaW50MzJfaW50MzIgPSBtZXNzYWdlX2ludDMyX2ludDMyLkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIoCisgICAgICAgICAgbWVzc2FnZV9pbnQzMl9pbnQzMiwgZmRfbWFwX2ludDMyX2luMzJfa2V5KTsKKyAgICAgIGludDMyIHZhbHVlX2ludDMyX2ludDMyID0gbWVzc2FnZV9pbnQzMl9pbnQzMi5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKAorICAgICAgICAgIG1lc3NhZ2VfaW50MzJfaW50MzIsIGZkX21hcF9pbnQzMl9pbjMyX3ZhbHVlKTsKKyAgICAgIEVYUEVDVF9FUSh2YWx1ZV9pbnQzMl9pbnQzMiwgRnVuYyhrZXlfaW50MzJfaW50MzIsIDEpKTsKKworICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZV9pbnQzMl9kb3VibGUgPSBtbWZfaW50MzJfZG91YmxlLT5HZXQoaSk7CisgICAgICBpbnQzMiBrZXlfaW50MzJfZG91YmxlID0gbWVzc2FnZV9pbnQzMl9kb3VibGUuR2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigKKyAgICAgICAgICBtZXNzYWdlX2ludDMyX2RvdWJsZSwgZmRfbWFwX2ludDMyX2RvdWJsZV9rZXkpOworICAgICAgZG91YmxlIHZhbHVlX2ludDMyX2RvdWJsZSA9CisgICAgICAgICAgbWVzc2FnZV9pbnQzMl9kb3VibGUuR2V0UmVmbGVjdGlvbigpLT5HZXREb3VibGUoCisgICAgICAgICAgICAgIG1lc3NhZ2VfaW50MzJfZG91YmxlLCBmZF9tYXBfaW50MzJfZG91YmxlX3ZhbHVlKTsKKyAgICAgIEVYUEVDVF9FUSh2YWx1ZV9pbnQzMl9kb3VibGUsIEZ1bmMoa2V5X2ludDMyX2RvdWJsZSwgMikpOworCisgICAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlX3N0cmluZ19zdHJpbmcgPSBtbWZfc3RyaW5nX3N0cmluZy0+R2V0KGkpOworICAgICAgc3RyaW5nIGtleV9zdHJpbmdfc3RyaW5nID0KKyAgICAgICAgICBtZXNzYWdlX3N0cmluZ19zdHJpbmcuR2V0UmVmbGVjdGlvbigpLT5HZXRTdHJpbmcoCisgICAgICAgICAgICAgIG1lc3NhZ2Vfc3RyaW5nX3N0cmluZywgZmRfbWFwX3N0cmluZ19zdHJpbmdfa2V5KTsKKyAgICAgIHN0cmluZyB2YWx1ZV9zdHJpbmdfc3RyaW5nID0KKyAgICAgICAgICBtZXNzYWdlX3N0cmluZ19zdHJpbmcuR2V0UmVmbGVjdGlvbigpLT5HZXRTdHJpbmcoCisgICAgICAgICAgICAgIG1lc3NhZ2Vfc3RyaW5nX3N0cmluZywgZmRfbWFwX3N0cmluZ19zdHJpbmdfdmFsdWUpOworICAgICAgRVhQRUNUX0VRKHZhbHVlX3N0cmluZ19zdHJpbmcsIFN0ckZ1bmMoSW50KGtleV9zdHJpbmdfc3RyaW5nKSwgNSkpOworCisgICAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlX2ludDMyX21lc3NhZ2UgPSBtbWZfaW50MzJfZm9yZWlnbl9tZXNzYWdlLT5HZXQoaSk7CisgICAgICBpbnQzMiBrZXlfaW50MzJfbWVzc2FnZSA9IG1lc3NhZ2VfaW50MzJfbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKAorICAgICAgICAgIG1lc3NhZ2VfaW50MzJfbWVzc2FnZSwgZmRfbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZV9rZXkpOworICAgICAgY29uc3QgRm9yZWlnbk1lc3NhZ2UmIHZhbHVlX2ludDMyX21lc3NhZ2UgPQorICAgICAgICAgIGRvd25fY2FzdDxjb25zdCBGb3JlaWduTWVzc2FnZSY+KAorICAgICAgICAgICAgICBtZXNzYWdlX2ludDMyX21lc3NhZ2UuR2V0UmVmbGVjdGlvbigpCisgICAgICAgICAgICAgICAgICAtPkdldE1lc3NhZ2UobWVzc2FnZV9pbnQzMl9tZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZkX21hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2VfdmFsdWUpKTsKKyAgICAgIEVYUEVDVF9FUSh2YWx1ZV9pbnQzMl9tZXNzYWdlLmMoKSwgRnVuYyhrZXlfaW50MzJfbWVzc2FnZSwgNikpOworICAgIH0KKyAgfQorCisgIC8vIERvIHNldHMgdGhyb3VnaCB0aGUgUmVwZWF0ZWRQdHJGaWVsZCBvYmplY3RzLgorICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyBpKyspIHsKKyAgICB7CisgICAgICBNZXNzYWdlKiBtZXNzYWdlX2ludDMyX2ludDMyID0gbW1mX2ludDMyX2ludDMyLT5NdXRhYmxlKGkpOworICAgICAgaW50MzIga2V5X2ludDMyX2ludDMyID0gbWVzc2FnZV9pbnQzMl9pbnQzMi0+R2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigKKyAgICAgICAgICAqbWVzc2FnZV9pbnQzMl9pbnQzMiwgZmRfbWFwX2ludDMyX2luMzJfa2V5KTsKKyAgICAgIG1lc3NhZ2VfaW50MzJfaW50MzItPkdldFJlZmxlY3Rpb24oKS0+U2V0SW50MzIobWVzc2FnZV9pbnQzMl9pbnQzMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmRfbWFwX2ludDMyX2luMzJfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZ1bmMoa2V5X2ludDMyX2ludDMyLCAtMSkpOworCisgICAgICBNZXNzYWdlKiBtZXNzYWdlX2ludDMyX2RvdWJsZSA9IG1tZl9pbnQzMl9kb3VibGUtPk11dGFibGUoaSk7CisgICAgICBpbnQzMiBrZXlfaW50MzJfZG91YmxlID0gbWVzc2FnZV9pbnQzMl9kb3VibGUtPkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIoCisgICAgICAgICAgKm1lc3NhZ2VfaW50MzJfZG91YmxlLCBmZF9tYXBfaW50MzJfZG91YmxlX2tleSk7CisgICAgICBtZXNzYWdlX2ludDMyX2RvdWJsZS0+R2V0UmVmbGVjdGlvbigpLT5TZXREb3VibGUoCisgICAgICAgICAgbWVzc2FnZV9pbnQzMl9kb3VibGUsIGZkX21hcF9pbnQzMl9kb3VibGVfdmFsdWUsCisgICAgICAgICAgRnVuYyhrZXlfaW50MzJfZG91YmxlLCAtMikpOworCisgICAgICBNZXNzYWdlKiBtZXNzYWdlX3N0cmluZ19zdHJpbmcgPSBtbWZfc3RyaW5nX3N0cmluZy0+TXV0YWJsZShpKTsKKyAgICAgIHN0cmluZyBrZXlfc3RyaW5nX3N0cmluZyA9CisgICAgICAgICAgbWVzc2FnZV9zdHJpbmdfc3RyaW5nLT5HZXRSZWZsZWN0aW9uKCktPkdldFN0cmluZygKKyAgICAgICAgICAgICAgKm1lc3NhZ2Vfc3RyaW5nX3N0cmluZywgZmRfbWFwX3N0cmluZ19zdHJpbmdfa2V5KTsKKyAgICAgIG1lc3NhZ2Vfc3RyaW5nX3N0cmluZy0+R2V0UmVmbGVjdGlvbigpLT5TZXRTdHJpbmcoCisgICAgICAgICAgbWVzc2FnZV9zdHJpbmdfc3RyaW5nLCBmZF9tYXBfc3RyaW5nX3N0cmluZ192YWx1ZSwKKyAgICAgICAgICBTdHJGdW5jKEludChrZXlfc3RyaW5nX3N0cmluZyksIC01KSk7CisKKyAgICAgIE1lc3NhZ2UqIG1lc3NhZ2VfaW50MzJfbWVzc2FnZSA9IG1tZl9pbnQzMl9mb3JlaWduX21lc3NhZ2UtPk11dGFibGUoaSk7CisgICAgICBpbnQzMiBrZXlfaW50MzJfbWVzc2FnZSA9CisgICAgICAgICAgbWVzc2FnZV9pbnQzMl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKAorICAgICAgICAgICAgICAqbWVzc2FnZV9pbnQzMl9tZXNzYWdlLCBmZF9tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlX2tleSk7CisgICAgICBGb3JlaWduTWVzc2FnZSogdmFsdWVfaW50MzJfbWVzc2FnZSA9IGRvd25fY2FzdDxGb3JlaWduTWVzc2FnZSo+KAorICAgICAgICAgIG1lc3NhZ2VfaW50MzJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAgICAgICAgIC0+TXV0YWJsZU1lc3NhZ2UobWVzc2FnZV9pbnQzMl9tZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZkX21hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2VfdmFsdWUpKTsKKyAgICAgIHZhbHVlX2ludDMyX21lc3NhZ2UtPnNldF9jKEZ1bmMoa2V5X2ludDMyX21lc3NhZ2UsIC02KSk7CisgICAgfQorICB9CisKKyAgLy8gQ2hlY2sgZ2V0cyB0aHJvdWdoIG11dGFibGUgb2JqZWN0cy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgaSsrKSB7CisgICAgRVhQRUNUX0VRKEZ1bmMoaSwgLTEpLCBtZXNzYWdlLm1hcF9pbnQzMl9pbnQzMigpLmF0KGkpKTsKKyAgICBFWFBFQ1RfRVEoRnVuYyhpLCAtMiksIG1lc3NhZ2UubWFwX2ludDMyX2RvdWJsZSgpLmF0KGkpKTsKKyAgICBFWFBFQ1RfRVEoU3RyRnVuYyhpLCAtNSksIG1lc3NhZ2UubWFwX3N0cmluZ19zdHJpbmcoKS5hdChTdHJGdW5jKGksIDEpKSk7CisgICAgRVhQRUNUX0VRKEZ1bmMoaSwgLTYpLCBtZXNzYWdlLm1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UoKS5hdChpKS5jKCkpOworICB9Cit9CisKK1RFU1RfRihNYXBGaWVsZFJlZmxlY3Rpb25UZXN0LCBSZXBlYXRlZEZpZWxkUmVmRm9yUmVndWxhckZpZWxkcykgeworICBUZXN0TWFwIG1lc3NhZ2U7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmwgPSBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKTsKKyAgY29uc3QgRGVzY3JpcHRvciogZGVzYyA9IG1lc3NhZ2UuR2V0RGVzY3JpcHRvcigpOworCisgIE1hcDxpbnQzMiwgaW50MzI+KiBtYXBfaW50MzJfaW50MzIgPSBtZXNzYWdlLm11dGFibGVfbWFwX2ludDMyX2ludDMyKCk7CisgIE1hcDxpbnQzMiwgZG91YmxlPiogbWFwX2ludDMyX2RvdWJsZSA9IG1lc3NhZ2UubXV0YWJsZV9tYXBfaW50MzJfZG91YmxlKCk7CisgIE1hcDxzdHJpbmcsIHN0cmluZz4qIG1hcF9zdHJpbmdfc3RyaW5nID0gbWVzc2FnZS5tdXRhYmxlX21hcF9zdHJpbmdfc3RyaW5nKCk7CisgIE1hcDxpbnQzMiwgRm9yZWlnbk1lc3NhZ2U+KiBtYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlID0KKyAgICAgIG1lc3NhZ2UubXV0YWJsZV9tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlKCk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgKytpKSB7CisgICAgKCptYXBfaW50MzJfaW50MzIpW2ldID0gRnVuYyhpLCAxKTsKKyAgICAoKm1hcF9pbnQzMl9kb3VibGUpW2ldID0gRnVuYyhpLCAyKTsKKyAgICAoKm1hcF9zdHJpbmdfc3RyaW5nKVtTdHJGdW5jKGksIDEpXSA9IFN0ckZ1bmMoaSwgNSk7CisgICAgKCptYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlKVtpXS5zZXRfYyhGdW5jKGksIDYpKTsKKyAgfQorCisgIC8vIEdldCBGaWVsZERlc2NyaXB0b3JzIGZvciBhbGwgdGhlIGZpZWxkcyBvZiBpbnRlcmVzdC4KKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmZF9tYXBfaW50MzJfaW50MzIgPQorICAgICAgZGVzYy0+RmluZEZpZWxkQnlOYW1lKCJtYXBfaW50MzJfaW50MzIiKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmZF9tYXBfaW50MzJfZG91YmxlID0KKyAgICAgIGRlc2MtPkZpbmRGaWVsZEJ5TmFtZSgibWFwX2ludDMyX2RvdWJsZSIpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZkX21hcF9zdHJpbmdfc3RyaW5nID0KKyAgICAgIGRlc2MtPkZpbmRGaWVsZEJ5TmFtZSgibWFwX3N0cmluZ19zdHJpbmciKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmZF9tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlID0KKyAgICAgIGRlc2MtPkZpbmRGaWVsZEJ5TmFtZSgibWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSIpOworCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmRfbWFwX2ludDMyX2luMzJfa2V5ID0KKyAgICAgIGZkX21hcF9pbnQzMl9pbnQzMi0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgia2V5Iik7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmRfbWFwX2ludDMyX2luMzJfdmFsdWUgPQorICAgICAgZmRfbWFwX2ludDMyX2ludDMyLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJ2YWx1ZSIpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZkX21hcF9pbnQzMl9kb3VibGVfa2V5ID0KKyAgICAgIGZkX21hcF9pbnQzMl9kb3VibGUtPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoImtleSIpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZkX21hcF9pbnQzMl9kb3VibGVfdmFsdWUgPQorICAgICAgZmRfbWFwX2ludDMyX2RvdWJsZS0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgidmFsdWUiKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmZF9tYXBfc3RyaW5nX3N0cmluZ19rZXkgPQorICAgICAgZmRfbWFwX3N0cmluZ19zdHJpbmctPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoImtleSIpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZkX21hcF9zdHJpbmdfc3RyaW5nX3ZhbHVlID0KKyAgICAgIGZkX21hcF9zdHJpbmdfc3RyaW5nLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJ2YWx1ZSIpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZkX21hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2Vfa2V5ID0KKyAgICAgIGZkX21hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UtPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoImtleSIpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZkX21hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2VfdmFsdWUgPQorICAgICAgZmRfbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZS0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgidmFsdWUiKTsKKworICAvLyBHZXQgUmVwZWF0ZWRGaWVsZFJlZiBvYmplY3RzIGZvciBhbGwgZmllbGRzIG9mIGludGVyZXN0LgorICBjb25zdCBSZXBlYXRlZEZpZWxkUmVmPE1lc3NhZ2U+IG1mX2ludDMyX2ludDMyID0KKyAgICAgIHJlZmwtPkdldFJlcGVhdGVkRmllbGRSZWY8TWVzc2FnZT4obWVzc2FnZSwgZmRfbWFwX2ludDMyX2ludDMyKTsKKyAgY29uc3QgUmVwZWF0ZWRGaWVsZFJlZjxNZXNzYWdlPiBtZl9pbnQzMl9kb3VibGUgPQorICAgICAgcmVmbC0+R2V0UmVwZWF0ZWRGaWVsZFJlZjxNZXNzYWdlPihtZXNzYWdlLCBmZF9tYXBfaW50MzJfZG91YmxlKTsKKyAgY29uc3QgUmVwZWF0ZWRGaWVsZFJlZjxNZXNzYWdlPiBtZl9zdHJpbmdfc3RyaW5nID0KKyAgICAgIHJlZmwtPkdldFJlcGVhdGVkRmllbGRSZWY8TWVzc2FnZT4obWVzc2FnZSwgZmRfbWFwX3N0cmluZ19zdHJpbmcpOworICBjb25zdCBSZXBlYXRlZEZpZWxkUmVmPE1lc3NhZ2U+IG1mX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSA9CisgICAgICByZWZsLT5HZXRSZXBlYXRlZEZpZWxkUmVmPE1lc3NhZ2U+KG1lc3NhZ2UsIGZkX21hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UpOworCisgIC8vIEdldCBtdXRhYmxlIFJlcGVhdGVkRmllbGRSZWYgb2JqZWN0cyBmb3IgYWxsIGZpZWxkcyBvZiBpbnRlcmVzdC4KKyAgY29uc3QgTXV0YWJsZVJlcGVhdGVkRmllbGRSZWY8TWVzc2FnZT4gbW1mX2ludDMyX2ludDMyID0KKyAgICAgIHJlZmwtPkdldE11dGFibGVSZXBlYXRlZEZpZWxkUmVmPE1lc3NhZ2U+KCZtZXNzYWdlLCBmZF9tYXBfaW50MzJfaW50MzIpOworICBjb25zdCBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxNZXNzYWdlPiBtbWZfaW50MzJfZG91YmxlID0KKyAgICAgIHJlZmwtPkdldE11dGFibGVSZXBlYXRlZEZpZWxkUmVmPE1lc3NhZ2U+KCZtZXNzYWdlLCBmZF9tYXBfaW50MzJfZG91YmxlKTsKKyAgY29uc3QgTXV0YWJsZVJlcGVhdGVkRmllbGRSZWY8TWVzc2FnZT4gbW1mX3N0cmluZ19zdHJpbmcgPQorICAgICAgcmVmbC0+R2V0TXV0YWJsZVJlcGVhdGVkRmllbGRSZWY8TWVzc2FnZT4oJm1lc3NhZ2UsIGZkX21hcF9zdHJpbmdfc3RyaW5nKTsKKyAgY29uc3QgTXV0YWJsZVJlcGVhdGVkRmllbGRSZWY8TWVzc2FnZT4KKyAgICAgIG1tZl9pbnQzMl9mb3JlaWduX21lc3NhZ2UgPQorICAgICAgICAgIHJlZmwtPkdldE11dGFibGVSZXBlYXRlZEZpZWxkUmVmPE1lc3NhZ2U+KAorICAgICAgICAgICAgICAmbWVzc2FnZSwgZmRfbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSk7CisKKyAgLy8gR2V0IGVudHJ5IGRlZmF1bHQgaW5zdGFuY2VzCisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8TWVzc2FnZT4gZW50cnlfaW50MzJfaW50MzIoCisgICAgICBNZXNzYWdlRmFjdG9yeTo6Z2VuZXJhdGVkX2ZhY3RvcnkoKQorICAgICAgICAgIC0+R2V0UHJvdG90eXBlKGZkX21hcF9pbnQzMl9pbnQzMi0+bWVzc2FnZV90eXBlKCkpCisgICAgICAgICAgLT5OZXcoKSk7CisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8TWVzc2FnZT4gZW50cnlfaW50MzJfZG91YmxlKAorICAgICAgTWVzc2FnZUZhY3Rvcnk6OmdlbmVyYXRlZF9mYWN0b3J5KCkKKyAgICAgICAgICAtPkdldFByb3RvdHlwZShmZF9tYXBfaW50MzJfZG91YmxlLT5tZXNzYWdlX3R5cGUoKSkKKyAgICAgICAgICAtPk5ldygpKTsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxNZXNzYWdlPiBlbnRyeV9zdHJpbmdfc3RyaW5nKAorICAgICAgTWVzc2FnZUZhY3Rvcnk6OmdlbmVyYXRlZF9mYWN0b3J5KCkKKyAgICAgICAgICAtPkdldFByb3RvdHlwZShmZF9tYXBfc3RyaW5nX3N0cmluZy0+bWVzc2FnZV90eXBlKCkpCisgICAgICAgICAgLT5OZXcoKSk7CisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8TWVzc2FnZT4gZW50cnlfaW50MzJfZm9yZWlnbl9tZXNzYWdlKAorICAgICAgTWVzc2FnZUZhY3Rvcnk6OmdlbmVyYXRlZF9mYWN0b3J5KCkKKyAgICAgICAgICAtPkdldFByb3RvdHlwZShmZF9tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlLT5tZXNzYWdlX3R5cGUoKSkKKyAgICAgICAgICAtPk5ldygpKTsKKworICBFWFBFQ1RfRVEoMTAsIG1mX2ludDMyX2ludDMyLnNpemUoKSk7CisgIEVYUEVDVF9FUSgxMCwgbW1mX2ludDMyX2ludDMyLnNpemUoKSk7CisgIEVYUEVDVF9FUSgxMCwgbWZfaW50MzJfZG91YmxlLnNpemUoKSk7CisgIEVYUEVDVF9FUSgxMCwgbW1mX2ludDMyX2RvdWJsZS5zaXplKCkpOworICBFWFBFQ1RfRVEoMTAsIG1mX3N0cmluZ19zdHJpbmcuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEwLCBtbWZfc3RyaW5nX3N0cmluZy5zaXplKCkpOworICBFWFBFQ1RfRVEoMTAsIG1mX2ludDMyX2ZvcmVpZ25fbWVzc2FnZS5zaXplKCkpOworICBFWFBFQ1RfRVEoMTAsIG1tZl9pbnQzMl9mb3JlaWduX21lc3NhZ2Uuc2l6ZSgpKTsKKworICBFWFBFQ1RfRkFMU0UobWZfaW50MzJfaW50MzIuZW1wdHkoKSk7CisgIEVYUEVDVF9GQUxTRShtbWZfaW50MzJfaW50MzIuZW1wdHkoKSk7CisgIEVYUEVDVF9GQUxTRShtZl9pbnQzMl9kb3VibGUuZW1wdHkoKSk7CisgIEVYUEVDVF9GQUxTRShtbWZfaW50MzJfZG91YmxlLmVtcHR5KCkpOworICBFWFBFQ1RfRkFMU0UobWZfc3RyaW5nX3N0cmluZy5lbXB0eSgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1tZl9zdHJpbmdfc3RyaW5nLmVtcHR5KCkpOworICBFWFBFQ1RfRkFMU0UobWZfaW50MzJfZm9yZWlnbl9tZXNzYWdlLmVtcHR5KCkpOworICBFWFBFQ1RfRkFMU0UobW1mX2ludDMyX2ZvcmVpZ25fbWVzc2FnZS5lbXB0eSgpKTsKKworICAvLyBNYWtlIHN1cmUgd2UgY2FuIGRvIGdldHMgdGhyb3VnaCB0aGUgUmVwZWF0ZWRGaWVsZFJlZiBvYmplY3RzLgorICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyArK2kpIHsKKyAgICB7CisgICAgICAvLyBDaGVjayBnZXRzIHRocm91Z2ggY29uc3Qgb2JqZWN0cy4KKyAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2VfaW50MzJfaW50MzIgPQorICAgICAgICAgIG1mX2ludDMyX2ludDMyLkdldChpLCBlbnRyeV9pbnQzMl9pbnQzMi5nZXQoKSk7CisgICAgICBpbnQzMiBrZXlfaW50MzJfaW50MzIgPSBtZXNzYWdlX2ludDMyX2ludDMyLkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIoCisgICAgICAgICAgbWVzc2FnZV9pbnQzMl9pbnQzMiwgZmRfbWFwX2ludDMyX2luMzJfa2V5KTsKKyAgICAgIGludDMyIHZhbHVlX2ludDMyX2ludDMyID0gbWVzc2FnZV9pbnQzMl9pbnQzMi5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKAorICAgICAgICAgIG1lc3NhZ2VfaW50MzJfaW50MzIsIGZkX21hcF9pbnQzMl9pbjMyX3ZhbHVlKTsKKyAgICAgIEVYUEVDVF9FUSh2YWx1ZV9pbnQzMl9pbnQzMiwgRnVuYyhrZXlfaW50MzJfaW50MzIsIDEpKTsKKworICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZV9pbnQzMl9kb3VibGUgPQorICAgICAgICAgIG1mX2ludDMyX2RvdWJsZS5HZXQoaSwgZW50cnlfaW50MzJfZG91YmxlLmdldCgpKTsKKyAgICAgIGludDMyIGtleV9pbnQzMl9kb3VibGUgPSBtZXNzYWdlX2ludDMyX2RvdWJsZS5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKAorICAgICAgICAgIG1lc3NhZ2VfaW50MzJfZG91YmxlLCBmZF9tYXBfaW50MzJfZG91YmxlX2tleSk7CisgICAgICBkb3VibGUgdmFsdWVfaW50MzJfZG91YmxlID0KKyAgICAgICAgICBtZXNzYWdlX2ludDMyX2RvdWJsZS5HZXRSZWZsZWN0aW9uKCktPkdldERvdWJsZSgKKyAgICAgICAgICAgICAgbWVzc2FnZV9pbnQzMl9kb3VibGUsIGZkX21hcF9pbnQzMl9kb3VibGVfdmFsdWUpOworICAgICAgRVhQRUNUX0VRKHZhbHVlX2ludDMyX2RvdWJsZSwgRnVuYyhrZXlfaW50MzJfZG91YmxlLCAyKSk7CisKKyAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2Vfc3RyaW5nX3N0cmluZyA9CisgICAgICAgICAgbWZfc3RyaW5nX3N0cmluZy5HZXQoaSwgZW50cnlfc3RyaW5nX3N0cmluZy5nZXQoKSk7CisgICAgICBzdHJpbmcga2V5X3N0cmluZ19zdHJpbmcgPQorICAgICAgICAgIG1lc3NhZ2Vfc3RyaW5nX3N0cmluZy5HZXRSZWZsZWN0aW9uKCktPkdldFN0cmluZygKKyAgICAgICAgICAgICAgbWVzc2FnZV9zdHJpbmdfc3RyaW5nLCBmZF9tYXBfc3RyaW5nX3N0cmluZ19rZXkpOworICAgICAgc3RyaW5nIHZhbHVlX3N0cmluZ19zdHJpbmcgPQorICAgICAgICAgIG1lc3NhZ2Vfc3RyaW5nX3N0cmluZy5HZXRSZWZsZWN0aW9uKCktPkdldFN0cmluZygKKyAgICAgICAgICAgICAgbWVzc2FnZV9zdHJpbmdfc3RyaW5nLCBmZF9tYXBfc3RyaW5nX3N0cmluZ192YWx1ZSk7CisgICAgICBFWFBFQ1RfRVEodmFsdWVfc3RyaW5nX3N0cmluZywgU3RyRnVuYyhJbnQoa2V5X3N0cmluZ19zdHJpbmcpLCA1KSk7CisKKyAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2VfaW50MzJfbWVzc2FnZSA9CisgICAgICAgICAgbWZfaW50MzJfZm9yZWlnbl9tZXNzYWdlLkdldChpLCBlbnRyeV9pbnQzMl9mb3JlaWduX21lc3NhZ2UuZ2V0KCkpOworICAgICAgaW50MzIga2V5X2ludDMyX21lc3NhZ2UgPSBtZXNzYWdlX2ludDMyX21lc3NhZ2UuR2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigKKyAgICAgICAgICBtZXNzYWdlX2ludDMyX21lc3NhZ2UsIGZkX21hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2Vfa2V5KTsKKyAgICAgIGNvbnN0IEZvcmVpZ25NZXNzYWdlJiB2YWx1ZV9pbnQzMl9tZXNzYWdlID0KKyAgICAgICAgICBkb3duX2Nhc3Q8Y29uc3QgRm9yZWlnbk1lc3NhZ2UmPigKKyAgICAgICAgICAgICAgbWVzc2FnZV9pbnQzMl9tZXNzYWdlLkdldFJlZmxlY3Rpb24oKQorICAgICAgICAgICAgICAgICAgLT5HZXRNZXNzYWdlKG1lc3NhZ2VfaW50MzJfbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmZF9tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlX3ZhbHVlKSk7CisgICAgICBFWFBFQ1RfRVEodmFsdWVfaW50MzJfbWVzc2FnZS5jKCksIEZ1bmMoa2V5X2ludDMyX21lc3NhZ2UsIDYpKTsKKyAgICB9CisKKyAgICB7CisgICAgICAvLyBDaGVjayBnZXRzIHRocm91Z2ggbXV0YWJsZSBvYmplY3RzLgorICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZV9pbnQzMl9pbnQzMiA9CisgICAgICAgICAgbW1mX2ludDMyX2ludDMyLkdldChpLCBlbnRyeV9pbnQzMl9pbnQzMi5nZXQoKSk7CisgICAgICBpbnQzMiBrZXlfaW50MzJfaW50MzIgPSBtZXNzYWdlX2ludDMyX2ludDMyLkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIoCisgICAgICAgICAgbWVzc2FnZV9pbnQzMl9pbnQzMiwgZmRfbWFwX2ludDMyX2luMzJfa2V5KTsKKyAgICAgIGludDMyIHZhbHVlX2ludDMyX2ludDMyID0gbWVzc2FnZV9pbnQzMl9pbnQzMi5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKAorICAgICAgICAgIG1lc3NhZ2VfaW50MzJfaW50MzIsIGZkX21hcF9pbnQzMl9pbjMyX3ZhbHVlKTsKKyAgICAgIEVYUEVDVF9FUSh2YWx1ZV9pbnQzMl9pbnQzMiwgRnVuYyhrZXlfaW50MzJfaW50MzIsIDEpKTsKKworICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZV9pbnQzMl9kb3VibGUgPQorICAgICAgICAgIG1tZl9pbnQzMl9kb3VibGUuR2V0KGksIGVudHJ5X2ludDMyX2RvdWJsZS5nZXQoKSk7CisgICAgICBpbnQzMiBrZXlfaW50MzJfZG91YmxlID0gbWVzc2FnZV9pbnQzMl9kb3VibGUuR2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigKKyAgICAgICAgICBtZXNzYWdlX2ludDMyX2RvdWJsZSwgZmRfbWFwX2ludDMyX2RvdWJsZV9rZXkpOworICAgICAgZG91YmxlIHZhbHVlX2ludDMyX2RvdWJsZSA9CisgICAgICAgICAgbWVzc2FnZV9pbnQzMl9kb3VibGUuR2V0UmVmbGVjdGlvbigpLT5HZXREb3VibGUoCisgICAgICAgICAgICAgIG1lc3NhZ2VfaW50MzJfZG91YmxlLCBmZF9tYXBfaW50MzJfZG91YmxlX3ZhbHVlKTsKKyAgICAgIEVYUEVDVF9FUSh2YWx1ZV9pbnQzMl9kb3VibGUsIEZ1bmMoa2V5X2ludDMyX2RvdWJsZSwgMikpOworCisgICAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlX3N0cmluZ19zdHJpbmcgPQorICAgICAgICAgIG1tZl9zdHJpbmdfc3RyaW5nLkdldChpLCBlbnRyeV9zdHJpbmdfc3RyaW5nLmdldCgpKTsKKyAgICAgIHN0cmluZyBrZXlfc3RyaW5nX3N0cmluZyA9CisgICAgICAgICAgbWVzc2FnZV9zdHJpbmdfc3RyaW5nLkdldFJlZmxlY3Rpb24oKS0+R2V0U3RyaW5nKAorICAgICAgICAgICAgICBtZXNzYWdlX3N0cmluZ19zdHJpbmcsIGZkX21hcF9zdHJpbmdfc3RyaW5nX2tleSk7CisgICAgICBzdHJpbmcgdmFsdWVfc3RyaW5nX3N0cmluZyA9CisgICAgICAgICAgbWVzc2FnZV9zdHJpbmdfc3RyaW5nLkdldFJlZmxlY3Rpb24oKS0+R2V0U3RyaW5nKAorICAgICAgICAgICAgICBtZXNzYWdlX3N0cmluZ19zdHJpbmcsIGZkX21hcF9zdHJpbmdfc3RyaW5nX3ZhbHVlKTsKKyAgICAgIEVYUEVDVF9FUSh2YWx1ZV9zdHJpbmdfc3RyaW5nLCBTdHJGdW5jKEludChrZXlfc3RyaW5nX3N0cmluZyksIDUpKTsKKworICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZV9pbnQzMl9tZXNzYWdlID0KKyAgICAgICAgICBtbWZfaW50MzJfZm9yZWlnbl9tZXNzYWdlLkdldChpLCBlbnRyeV9pbnQzMl9mb3JlaWduX21lc3NhZ2UuZ2V0KCkpOworICAgICAgaW50MzIga2V5X2ludDMyX21lc3NhZ2UgPSBtZXNzYWdlX2ludDMyX21lc3NhZ2UuR2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigKKyAgICAgICAgICBtZXNzYWdlX2ludDMyX21lc3NhZ2UsIGZkX21hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2Vfa2V5KTsKKyAgICAgIGNvbnN0IEZvcmVpZ25NZXNzYWdlJiB2YWx1ZV9pbnQzMl9tZXNzYWdlID0KKyAgICAgICAgICBkb3duX2Nhc3Q8Y29uc3QgRm9yZWlnbk1lc3NhZ2UmPigKKyAgICAgICAgICAgICAgbWVzc2FnZV9pbnQzMl9tZXNzYWdlLkdldFJlZmxlY3Rpb24oKQorICAgICAgICAgICAgICAgICAgLT5HZXRNZXNzYWdlKG1lc3NhZ2VfaW50MzJfbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmZF9tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlX3ZhbHVlKSk7CisgICAgICBFWFBFQ1RfRVEodmFsdWVfaW50MzJfbWVzc2FnZS5jKCksIEZ1bmMoa2V5X2ludDMyX21lc3NhZ2UsIDYpKTsKKyAgICB9CisgIH0KKworICAvLyBNYWtlIHN1cmUgd2UgY2FuIGRvIHNldHMgdGhyb3VnaCB0aGUgUmVwZWF0ZWRGaWVsZFJlZiBvYmplY3RzLgorICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyBpKyspIHsKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlX2ludDMyX2ludDMyID0KKyAgICAgICAgbW1mX2ludDMyX2ludDMyLkdldChpLCBlbnRyeV9pbnQzMl9pbnQzMi5nZXQoKSk7CisgICAgaW50IGtleSA9IG1lc3NhZ2VfaW50MzJfaW50MzIuR2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigKKyAgICAgICAgbWVzc2FnZV9pbnQzMl9pbnQzMiwgZmRfbWFwX2ludDMyX2luMzJfa2V5KTsKKworICAgIGVudHJ5X2ludDMyX2ludDMyLT5HZXRSZWZsZWN0aW9uKCktPlNldEludDMyKAorICAgICAgICBlbnRyeV9pbnQzMl9pbnQzMi5nZXQoKSwgZmRfbWFwX2ludDMyX2ludDMyLT5tZXNzYWdlX3R5cGUoKS0+ZmllbGQoMCksCisgICAgICAgIGtleSk7CisgICAgZW50cnlfaW50MzJfaW50MzItPkdldFJlZmxlY3Rpb24oKS0+U2V0SW50MzIoCisgICAgICAgIGVudHJ5X2ludDMyX2ludDMyLmdldCgpLCBmZF9tYXBfaW50MzJfaW50MzItPm1lc3NhZ2VfdHlwZSgpLT5maWVsZCgxKSwKKyAgICAgICAgRnVuYyhrZXksIC0xKSk7CisgICAgZW50cnlfaW50MzJfZG91YmxlLT5HZXRSZWZsZWN0aW9uKCktPlNldEludDMyKAorICAgICAgICBlbnRyeV9pbnQzMl9kb3VibGUuZ2V0KCksIGZkX21hcF9pbnQzMl9kb3VibGUtPm1lc3NhZ2VfdHlwZSgpLT5maWVsZCgwKSwKKyAgICAgICAga2V5KTsKKyAgICBlbnRyeV9pbnQzMl9kb3VibGUtPkdldFJlZmxlY3Rpb24oKS0+U2V0RG91YmxlKAorICAgICAgICBlbnRyeV9pbnQzMl9kb3VibGUuZ2V0KCksIGZkX21hcF9pbnQzMl9kb3VibGUtPm1lc3NhZ2VfdHlwZSgpLT5maWVsZCgxKSwKKyAgICAgICAgRnVuYyhrZXksIC0yKSk7CisgICAgZW50cnlfc3RyaW5nX3N0cmluZy0+R2V0UmVmbGVjdGlvbigpLT5TZXRTdHJpbmcoCisgICAgICAgIGVudHJ5X3N0cmluZ19zdHJpbmcuZ2V0KCksCisgICAgICAgIGZkX21hcF9zdHJpbmdfc3RyaW5nLT5tZXNzYWdlX3R5cGUoKS0+ZmllbGQoMCksIFN0ckZ1bmMoa2V5LCAxKSk7CisgICAgZW50cnlfc3RyaW5nX3N0cmluZy0+R2V0UmVmbGVjdGlvbigpLT5TZXRTdHJpbmcoCisgICAgICAgIGVudHJ5X3N0cmluZ19zdHJpbmcuZ2V0KCksCisgICAgICAgIGZkX21hcF9zdHJpbmdfc3RyaW5nLT5tZXNzYWdlX3R5cGUoKS0+ZmllbGQoMSksIFN0ckZ1bmMoa2V5LCAtNSkpOworICAgIGVudHJ5X2ludDMyX2ZvcmVpZ25fbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5TZXRJbnQzMigKKyAgICAgICAgZW50cnlfaW50MzJfZm9yZWlnbl9tZXNzYWdlLmdldCgpLAorICAgICAgICBmZF9tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlLT5tZXNzYWdlX3R5cGUoKS0+ZmllbGQoMCksIGtleSk7CisgICAgTWVzc2FnZSogdmFsdWVfbWVzc2FnZSA9CisgICAgICAgIGVudHJ5X2ludDMyX2ZvcmVpZ25fbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5NdXRhYmxlTWVzc2FnZSgKKyAgICAgICAgICAgIGVudHJ5X2ludDMyX2ZvcmVpZ25fbWVzc2FnZS5nZXQoKSwKKyAgICAgICAgICAgIGZkX21hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UtPm1lc3NhZ2VfdHlwZSgpLT5maWVsZCgxKSk7CisgICAgdmFsdWVfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5TZXRJbnQzMigKKyAgICAgICAgdmFsdWVfbWVzc2FnZSwgdmFsdWVfbWVzc2FnZS0+R2V0RGVzY3JpcHRvcigpLT5GaW5kRmllbGRCeU5hbWUoImMiKSwKKyAgICAgICAgRnVuYyhrZXksIC02KSk7CisKKyAgICBtbWZfaW50MzJfaW50MzIuU2V0KGksICplbnRyeV9pbnQzMl9pbnQzMik7CisgICAgbW1mX2ludDMyX2RvdWJsZS5TZXQoaSwgKmVudHJ5X2ludDMyX2RvdWJsZSk7CisgICAgbW1mX3N0cmluZ19zdHJpbmcuU2V0KGksICplbnRyeV9zdHJpbmdfc3RyaW5nKTsKKyAgICBtbWZfaW50MzJfZm9yZWlnbl9tZXNzYWdlLlNldChpLCAqZW50cnlfaW50MzJfZm9yZWlnbl9tZXNzYWdlKTsKKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7IGkrKykgeworICAgIEVYUEVDVF9FUShGdW5jKGksIC0xKSwgbWVzc2FnZS5tYXBfaW50MzJfaW50MzIoKS5hdChpKSk7CisgICAgRVhQRUNUX0VRKEZ1bmMoaSwgLTIpLCBtZXNzYWdlLm1hcF9pbnQzMl9kb3VibGUoKS5hdChpKSk7CisgICAgRVhQRUNUX0VRKFN0ckZ1bmMoaSwgLTUpLCBtZXNzYWdlLm1hcF9zdHJpbmdfc3RyaW5nKCkuYXQoU3RyRnVuYyhpLCAxKSkpOworICAgIEVYUEVDVF9FUShGdW5jKGksIC02KSwgbWVzc2FnZS5tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlKCkuYXQoaSkuYygpKTsKKyAgfQorCisgIC8vIFRlc3QgaXRlcmF0b3JzLgorICB7CisgICAgaW50IGluZGV4ID0gMDsKKyAgICBoYXNoX21hcDxpbnQzMiwgaW50MzI+IHJlc3VsdDsKKyAgICBmb3IgKFJlcGVhdGVkRmllbGRSZWY8TWVzc2FnZT46Oml0ZXJhdG9yIGl0ID0gbWZfaW50MzJfaW50MzIuYmVnaW4oKTsKKyAgICAgICAgIGl0ICE9IG1mX2ludDMyX2ludDMyLmVuZCgpOyArK2l0KSB7CisgICAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlID0gKml0OworICAgICAgaW50MzIga2V5ID0KKyAgICAgICAgICBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIobWVzc2FnZSwgZmRfbWFwX2ludDMyX2luMzJfa2V5KTsKKyAgICAgIGludDMyIHZhbHVlID0KKyAgICAgICAgICBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIobWVzc2FnZSwgZmRfbWFwX2ludDMyX2luMzJfdmFsdWUpOworICAgICAgcmVzdWx0W2tleV0gPSB2YWx1ZTsKKyAgICAgICsraW5kZXg7CisgICAgfQorICAgIEVYUEVDVF9FUSgxMCwgaW5kZXgpOworICAgIGZvciAoaGFzaF9tYXA8aW50MzIsIGludDMyPjo6Y29uc3RfaXRlcmF0b3IgaXQgPSByZXN1bHQuYmVnaW4oKTsKKyAgICAgICAgIGl0ICE9IHJlc3VsdC5lbmQoKTsgKytpdCkgeworICAgICAgRVhQRUNUX0VRKG1lc3NhZ2UubWFwX2ludDMyX2ludDMyKCkuYXQoaXQtPmZpcnN0KSwgaXQtPnNlY29uZCk7CisgICAgfQorICB9CisKKyAgeworICAgIGludCBpbmRleCA9IDA7CisgICAgaGFzaF9tYXA8aW50MzIsIGRvdWJsZT4gcmVzdWx0OworICAgIGZvciAoUmVwZWF0ZWRGaWVsZFJlZjxNZXNzYWdlPjo6aXRlcmF0b3IgaXQgPSBtZl9pbnQzMl9kb3VibGUuYmVnaW4oKTsKKyAgICAgICAgIGl0ICE9IG1mX2ludDMyX2RvdWJsZS5lbmQoKTsgKytpdCkgeworICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSA9ICppdDsKKyAgICAgIGludDMyIGtleSA9CisgICAgICAgICAgbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKG1lc3NhZ2UsIGZkX21hcF9pbnQzMl9kb3VibGVfa2V5KTsKKyAgICAgIGRvdWJsZSB2YWx1ZSA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpLT5HZXREb3VibGUoCisgICAgICAgICAgbWVzc2FnZSwgZmRfbWFwX2ludDMyX2RvdWJsZV92YWx1ZSk7CisgICAgICByZXN1bHRba2V5XSA9IHZhbHVlOworICAgICAgKytpbmRleDsKKyAgICB9CisgICAgRVhQRUNUX0VRKDEwLCBpbmRleCk7CisgICAgZm9yIChoYXNoX21hcDxpbnQzMiwgZG91YmxlPjo6Y29uc3RfaXRlcmF0b3IgaXQgPSByZXN1bHQuYmVnaW4oKTsKKyAgICAgICAgIGl0ICE9IHJlc3VsdC5lbmQoKTsgKytpdCkgeworICAgICAgRVhQRUNUX0VRKG1lc3NhZ2UubWFwX2ludDMyX2RvdWJsZSgpLmF0KGl0LT5maXJzdCksIGl0LT5zZWNvbmQpOworICAgIH0KKyAgfQorCisgIHsKKyAgICBpbnQgaW5kZXggPSAwOworICAgIGhhc2hfbWFwPHN0cmluZywgc3RyaW5nPiByZXN1bHQ7CisgICAgZm9yIChSZXBlYXRlZEZpZWxkUmVmPE1lc3NhZ2U+OjppdGVyYXRvciBpdCA9IG1mX3N0cmluZ19zdHJpbmcuYmVnaW4oKTsKKyAgICAgICAgIGl0ICE9IG1mX3N0cmluZ19zdHJpbmcuZW5kKCk7ICsraXQpIHsKKyAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UgPSAqaXQ7CisgICAgICBzdHJpbmcga2V5ID0KKyAgICAgICAgICBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+R2V0U3RyaW5nKG1lc3NhZ2UsIGZkX21hcF9zdHJpbmdfc3RyaW5nX2tleSk7CisgICAgICBzdHJpbmcgdmFsdWUgPSBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+R2V0U3RyaW5nKAorICAgICAgICAgIG1lc3NhZ2UsIGZkX21hcF9zdHJpbmdfc3RyaW5nX3ZhbHVlKTsKKyAgICAgIHJlc3VsdFtrZXldID0gdmFsdWU7CisgICAgICArK2luZGV4OworICAgIH0KKyAgICBFWFBFQ1RfRVEoMTAsIGluZGV4KTsKKyAgICBmb3IgKGhhc2hfbWFwPHN0cmluZywgc3RyaW5nPjo6Y29uc3RfaXRlcmF0b3IgaXQgPSByZXN1bHQuYmVnaW4oKTsKKyAgICAgICAgIGl0ICE9IHJlc3VsdC5lbmQoKTsgKytpdCkgeworICAgICAgRVhQRUNUX0VRKG1lc3NhZ2UubWFwX3N0cmluZ19zdHJpbmcoKS5hdChpdC0+Zmlyc3QpLCBpdC0+c2Vjb25kKTsKKyAgICB9CisgIH0KKworICB7CisgICAgaW50IGluZGV4ID0gMDsKKyAgICBzdGQ6Om1hcDxpbnQzMiwgRm9yZWlnbk1lc3NhZ2U+IHJlc3VsdDsKKyAgICBmb3IgKFJlcGVhdGVkRmllbGRSZWY8TWVzc2FnZT46Oml0ZXJhdG9yIGl0ID0KKyAgICAgICAgICAgICBtZl9pbnQzMl9mb3JlaWduX21lc3NhZ2UuYmVnaW4oKTsKKyAgICAgICAgIGl0ICE9IG1mX2ludDMyX2ZvcmVpZ25fbWVzc2FnZS5lbmQoKTsgKytpdCkgeworICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSA9ICppdDsKKyAgICAgIGludDMyIGtleSA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigKKyAgICAgICAgICBtZXNzYWdlLCBmZF9tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlX2tleSk7CisgICAgICBjb25zdCBGb3JlaWduTWVzc2FnZSYgc3ViX21lc3NhZ2UgPSBkb3duX2Nhc3Q8Y29uc3QgRm9yZWlnbk1lc3NhZ2UmPigKKyAgICAgICAgICBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKQorICAgICAgICAgICAgICAtPkdldE1lc3NhZ2UobWVzc2FnZSwgZmRfbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZV92YWx1ZSkpOworICAgICAgcmVzdWx0W2tleV0uTWVyZ2VGcm9tKHN1Yl9tZXNzYWdlKTsKKyAgICAgICsraW5kZXg7CisgICAgfQorICAgIEVYUEVDVF9FUSgxMCwgaW5kZXgpOworICAgIGZvciAoc3RkOjptYXA8aW50MzIsIEZvcmVpZ25NZXNzYWdlPjo6Y29uc3RfaXRlcmF0b3IgaXQgPSByZXN1bHQuYmVnaW4oKTsKKyAgICAgICAgIGl0ICE9IHJlc3VsdC5lbmQoKTsgKytpdCkgeworICAgICAgRVhQRUNUX0VRKG1lc3NhZ2UubWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSgpLmF0KGl0LT5maXJzdCkuYygpLAorICAgICAgICAgICAgICAgIGl0LT5zZWNvbmQuYygpKTsKKyAgICB9CisgIH0KKworICAvLyBUZXN0IE11dGFibGVSZXBlYXRlZEZpZWxkUmVmOjpBZGQoKQorICBlbnRyeV9pbnQzMl9pbnQzMi0+R2V0UmVmbGVjdGlvbigpLT5TZXRJbnQzMigKKyAgICAgIGVudHJ5X2ludDMyX2ludDMyLmdldCgpLCBmZF9tYXBfaW50MzJfaW50MzItPm1lc3NhZ2VfdHlwZSgpLT5maWVsZCgwKSwKKyAgICAgIDQzMjEpOworICBlbnRyeV9pbnQzMl9pbnQzMi0+R2V0UmVmbGVjdGlvbigpLT5TZXRJbnQzMigKKyAgICAgIGVudHJ5X2ludDMyX2ludDMyLmdldCgpLCBmZF9tYXBfaW50MzJfaW50MzItPm1lc3NhZ2VfdHlwZSgpLT5maWVsZCgxKSwKKyAgICAgIDEyMzQpOworICBtbWZfaW50MzJfaW50MzIuQWRkKCplbnRyeV9pbnQzMl9pbnQzMik7CisgIEVYUEVDVF9FUSgxMjM0LCBtZXNzYWdlLm1hcF9pbnQzMl9pbnQzMigpLmF0KDQzMjEpKTsKKworICBlbnRyeV9pbnQzMl9kb3VibGUtPkdldFJlZmxlY3Rpb24oKS0+U2V0SW50MzIoCisgICAgICBlbnRyeV9pbnQzMl9kb3VibGUuZ2V0KCksIGZkX21hcF9pbnQzMl9kb3VibGUtPm1lc3NhZ2VfdHlwZSgpLT5maWVsZCgwKSwKKyAgICAgIDQzMjEpOworICBlbnRyeV9pbnQzMl9kb3VibGUtPkdldFJlZmxlY3Rpb24oKS0+U2V0RG91YmxlKAorICAgICAgZW50cnlfaW50MzJfZG91YmxlLmdldCgpLCBmZF9tYXBfaW50MzJfZG91YmxlLT5tZXNzYWdlX3R5cGUoKS0+ZmllbGQoMSksCisgICAgICAxMjM0LjApOworICBtbWZfaW50MzJfZG91YmxlLkFkZCgqZW50cnlfaW50MzJfZG91YmxlKTsKKyAgRVhQRUNUX0VRKDEyMzQuMCwgbWVzc2FnZS5tYXBfaW50MzJfZG91YmxlKCkuYXQoNDMyMSkpOworCisgIGVudHJ5X3N0cmluZ19zdHJpbmctPkdldFJlZmxlY3Rpb24oKS0+U2V0U3RyaW5nKAorICAgICAgZW50cnlfc3RyaW5nX3N0cmluZy5nZXQoKSwKKyAgICAgIGZkX21hcF9zdHJpbmdfc3RyaW5nLT5tZXNzYWdlX3R5cGUoKS0+ZmllbGQoMCksICI0MzIxIik7CisgIGVudHJ5X3N0cmluZ19zdHJpbmctPkdldFJlZmxlY3Rpb24oKS0+U2V0U3RyaW5nKAorICAgICAgZW50cnlfc3RyaW5nX3N0cmluZy5nZXQoKSwgZmRfbWFwX3N0cmluZ19zdHJpbmctPm1lc3NhZ2VfdHlwZSgpLT5maWVsZCgxKSwKKyAgICAgICIxMjM0Iik7CisgIG1tZl9zdHJpbmdfc3RyaW5nLkFkZCgqZW50cnlfc3RyaW5nX3N0cmluZyk7CisgIEVYUEVDVF9FUSgiMTIzNCIsIG1lc3NhZ2UubWFwX3N0cmluZ19zdHJpbmcoKS5hdCgiNDMyMSIpKTsKKworICBlbnRyeV9pbnQzMl9mb3JlaWduX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+U2V0SW50MzIoCisgICAgICBlbnRyeV9pbnQzMl9mb3JlaWduX21lc3NhZ2UuZ2V0KCksCisgICAgICBmZF9tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlLT5tZXNzYWdlX3R5cGUoKS0+ZmllbGQoMCksIDQzMjEpOworICBNZXNzYWdlKiB2YWx1ZV9tZXNzYWdlID0KKyAgICAgIGVudHJ5X2ludDMyX2ZvcmVpZ25fbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5NdXRhYmxlTWVzc2FnZSgKKyAgICAgICAgICBlbnRyeV9pbnQzMl9mb3JlaWduX21lc3NhZ2UuZ2V0KCksCisgICAgICAgICAgZmRfbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZS0+bWVzc2FnZV90eXBlKCktPmZpZWxkKDEpKTsKKyAgRm9yZWlnbk1lc3NhZ2UgZm9yZWlnbl9tZXNzYWdlOworICBmb3JlaWduX21lc3NhZ2Uuc2V0X2MoMTIzNCk7CisgIHZhbHVlX21lc3NhZ2UtPkNvcHlGcm9tKGZvcmVpZ25fbWVzc2FnZSk7CisKKyAgbW1mX2ludDMyX2ZvcmVpZ25fbWVzc2FnZS5BZGQoKmVudHJ5X2ludDMyX2ZvcmVpZ25fbWVzc2FnZSk7CisgIEVYUEVDVF9FUSgxMjM0LCBtZXNzYWdlLm1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UoKS5hdCg0MzIxKS5jKCkpOworCisgIC8vIFRlc3QgUmVmbGVjdGlvbjo6QWRkQWxsb2NhdGVkTWVzc2FnZQorICBNZXNzYWdlKiBmcmVlX2VudHJ5X3N0cmluZ19zdHJpbmcgPSBNZXNzYWdlRmFjdG9yeTo6Z2VuZXJhdGVkX2ZhY3RvcnkoKQorICAgICAgLT5HZXRQcm90b3R5cGUoZmRfbWFwX3N0cmluZ19zdHJpbmctPm1lc3NhZ2VfdHlwZSgpKQorICAgICAgLT5OZXcoKTsKKyAgZW50cnlfc3RyaW5nX3N0cmluZy0+R2V0UmVmbGVjdGlvbigpLT5TZXRTdHJpbmcoCisgICAgICBmcmVlX2VudHJ5X3N0cmluZ19zdHJpbmcsCisgICAgICBmZF9tYXBfc3RyaW5nX3N0cmluZy0+bWVzc2FnZV90eXBlKCktPmZpZWxkKDApLCAiNDMyMSIpOworICBlbnRyeV9zdHJpbmdfc3RyaW5nLT5HZXRSZWZsZWN0aW9uKCktPlNldFN0cmluZygKKyAgICAgIGZyZWVfZW50cnlfc3RyaW5nX3N0cmluZywgZmRfbWFwX3N0cmluZ19zdHJpbmctPm1lc3NhZ2VfdHlwZSgpLT5maWVsZCgxKSwKKyAgICAgICIxMjM0Iik7CisgIHJlZmwtPkFkZEFsbG9jYXRlZE1lc3NhZ2UoJm1lc3NhZ2UsIGZkX21hcF9zdHJpbmdfc3RyaW5nLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyZWVfZW50cnlfc3RyaW5nX3N0cmluZyk7CisKKyAgLy8gVGVzdCBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjo6UmVtb3ZlTGFzdCgpCisgIG1tZl9pbnQzMl9pbnQzMi5SZW1vdmVMYXN0KCk7CisgIG1tZl9pbnQzMl9kb3VibGUuUmVtb3ZlTGFzdCgpOworICBtbWZfc3RyaW5nX3N0cmluZy5SZW1vdmVMYXN0KCk7CisgIG1tZl9pbnQzMl9mb3JlaWduX21lc3NhZ2UuUmVtb3ZlTGFzdCgpOworICBFWFBFQ1RfRVEoMTAsIG1lc3NhZ2UubWFwX2ludDMyX2ludDMyKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEwLCBtZXNzYWdlLm1hcF9pbnQzMl9kb3VibGUoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMTEsIG1lc3NhZ2UubWFwX3N0cmluZ19zdHJpbmcoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMTAsIG1lc3NhZ2UubWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSgpLnNpemUoKSk7CisKKyAgLy8gVGVzdCBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjo6U3dhcEVsZW1lbnRzKCkKKyAgeworICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UwYSA9IG1tZl9pbnQzMl9pbnQzMi5HZXQoMCwgZW50cnlfaW50MzJfaW50MzIuZ2V0KCkpOworICAgIGludDMyIGludDMyX3ZhbHVlMGEgPQorICAgICAgICBtZXNzYWdlMGEuR2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMihtZXNzYWdlMGEsIGZkX21hcF9pbnQzMl9pbjMyX3ZhbHVlKTsKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlOWEgPSBtbWZfaW50MzJfaW50MzIuR2V0KDksIGVudHJ5X2ludDMyX2ludDMyLmdldCgpKTsKKyAgICBpbnQzMiBpbnQzMl92YWx1ZTlhID0KKyAgICAgICAgbWVzc2FnZTlhLkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIobWVzc2FnZTlhLCBmZF9tYXBfaW50MzJfaW4zMl92YWx1ZSk7CisKKyAgICBtbWZfaW50MzJfaW50MzIuU3dhcEVsZW1lbnRzKDAsIDkpOworCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZTBiID0gbW1mX2ludDMyX2ludDMyLkdldCgwLCBlbnRyeV9pbnQzMl9pbnQzMi5nZXQoKSk7CisgICAgaW50MzIgaW50MzJfdmFsdWUwYiA9CisgICAgICAgIG1lc3NhZ2UwYi5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKG1lc3NhZ2UwYiwgZmRfbWFwX2ludDMyX2luMzJfdmFsdWUpOworICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2U5YiA9IG1tZl9pbnQzMl9pbnQzMi5HZXQoOSwgZW50cnlfaW50MzJfaW50MzIuZ2V0KCkpOworICAgIGludDMyIGludDMyX3ZhbHVlOWIgPQorICAgICAgICBtZXNzYWdlOWIuR2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMihtZXNzYWdlOWIsIGZkX21hcF9pbnQzMl9pbjMyX3ZhbHVlKTsKKworICAgIEVYUEVDVF9FUShpbnQzMl92YWx1ZTlhLCBpbnQzMl92YWx1ZTBiKTsKKyAgICBFWFBFQ1RfRVEoaW50MzJfdmFsdWUwYSwgaW50MzJfdmFsdWU5Yik7CisgIH0KKworICB7CisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZTBhID0KKyAgICAgICAgbW1mX2ludDMyX2RvdWJsZS5HZXQoMCwgZW50cnlfaW50MzJfZG91YmxlLmdldCgpKTsKKyAgICBkb3VibGUgZG91YmxlX3ZhbHVlMGEgPSBtZXNzYWdlMGEuR2V0UmVmbGVjdGlvbigpLT5HZXREb3VibGUoCisgICAgICAgIG1lc3NhZ2UwYSwgZmRfbWFwX2ludDMyX2RvdWJsZV92YWx1ZSk7CisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZTlhID0KKyAgICAgICAgbW1mX2ludDMyX2RvdWJsZS5HZXQoOSwgZW50cnlfaW50MzJfZG91YmxlLmdldCgpKTsKKyAgICBkb3VibGUgZG91YmxlX3ZhbHVlOWEgPSBtZXNzYWdlOWEuR2V0UmVmbGVjdGlvbigpLT5HZXREb3VibGUoCisgICAgICAgIG1lc3NhZ2U5YSwgZmRfbWFwX2ludDMyX2RvdWJsZV92YWx1ZSk7CisKKyAgICBtbWZfaW50MzJfZG91YmxlLlN3YXBFbGVtZW50cygwLCA5KTsKKworICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UwYiA9CisgICAgICAgIG1tZl9pbnQzMl9kb3VibGUuR2V0KDAsIGVudHJ5X2ludDMyX2RvdWJsZS5nZXQoKSk7CisgICAgZG91YmxlIGRvdWJsZV92YWx1ZTBiID0gbWVzc2FnZTBiLkdldFJlZmxlY3Rpb24oKS0+R2V0RG91YmxlKAorICAgICAgICBtZXNzYWdlMGIsIGZkX21hcF9pbnQzMl9kb3VibGVfdmFsdWUpOworICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2U5YiA9CisgICAgICAgIG1tZl9pbnQzMl9kb3VibGUuR2V0KDksIGVudHJ5X2ludDMyX2RvdWJsZS5nZXQoKSk7CisgICAgZG91YmxlIGRvdWJsZV92YWx1ZTliID0gbWVzc2FnZTliLkdldFJlZmxlY3Rpb24oKS0+R2V0RG91YmxlKAorICAgICAgICBtZXNzYWdlOWIsIGZkX21hcF9pbnQzMl9kb3VibGVfdmFsdWUpOworCisgICAgRVhQRUNUX0VRKGRvdWJsZV92YWx1ZTlhLCBkb3VibGVfdmFsdWUwYik7CisgICAgRVhQRUNUX0VRKGRvdWJsZV92YWx1ZTBhLCBkb3VibGVfdmFsdWU5Yik7CisgIH0KKworICB7CisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZTBhID0KKyAgICAgICAgbW1mX3N0cmluZ19zdHJpbmcuR2V0KDAsIGVudHJ5X3N0cmluZ19zdHJpbmcuZ2V0KCkpOworICAgIHN0cmluZyBzdHJpbmdfdmFsdWUwYSA9IG1lc3NhZ2UwYS5HZXRSZWZsZWN0aW9uKCktPkdldFN0cmluZygKKyAgICAgICAgbWVzc2FnZTBhLCBmZF9tYXBfc3RyaW5nX3N0cmluZ192YWx1ZSk7CisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZTlhID0KKyAgICAgICAgbW1mX3N0cmluZ19zdHJpbmcuR2V0KDksIGVudHJ5X3N0cmluZ19zdHJpbmcuZ2V0KCkpOworICAgIHN0cmluZyBzdHJpbmdfdmFsdWU5YSA9IG1lc3NhZ2U5YS5HZXRSZWZsZWN0aW9uKCktPkdldFN0cmluZygKKyAgICAgICAgbWVzc2FnZTlhLCBmZF9tYXBfc3RyaW5nX3N0cmluZ192YWx1ZSk7CisKKyAgICBtbWZfc3RyaW5nX3N0cmluZy5Td2FwRWxlbWVudHMoMCwgOSk7CisKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlMGIgPQorICAgICAgICBtbWZfc3RyaW5nX3N0cmluZy5HZXQoMCwgZW50cnlfc3RyaW5nX3N0cmluZy5nZXQoKSk7CisgICAgc3RyaW5nIHN0cmluZ192YWx1ZTBiID0gbWVzc2FnZTBiLkdldFJlZmxlY3Rpb24oKS0+R2V0U3RyaW5nKAorICAgICAgICBtZXNzYWdlMGIsIGZkX21hcF9zdHJpbmdfc3RyaW5nX3ZhbHVlKTsKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlOWIgPQorICAgICAgICBtbWZfc3RyaW5nX3N0cmluZy5HZXQoOSwgZW50cnlfc3RyaW5nX3N0cmluZy5nZXQoKSk7CisgICAgc3RyaW5nIHN0cmluZ192YWx1ZTliID0gbWVzc2FnZTliLkdldFJlZmxlY3Rpb24oKS0+R2V0U3RyaW5nKAorICAgICAgICBtZXNzYWdlOWIsIGZkX21hcF9zdHJpbmdfc3RyaW5nX3ZhbHVlKTsKKworICAgIEVYUEVDVF9FUShzdHJpbmdfdmFsdWU5YSwgc3RyaW5nX3ZhbHVlMGIpOworICAgIEVYUEVDVF9FUShzdHJpbmdfdmFsdWUwYSwgc3RyaW5nX3ZhbHVlOWIpOworICB9CisKKyAgeworICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UwYSA9CisgICAgICAgIG1tZl9pbnQzMl9mb3JlaWduX21lc3NhZ2UuR2V0KDAsIGVudHJ5X2ludDMyX2ZvcmVpZ25fbWVzc2FnZS5nZXQoKSk7CisgICAgY29uc3QgRm9yZWlnbk1lc3NhZ2UmIHN1Yl9tZXNzYWdlMGEgPSBkb3duX2Nhc3Q8Y29uc3QgRm9yZWlnbk1lc3NhZ2UmPigKKyAgICAgICAgbWVzc2FnZTBhLkdldFJlZmxlY3Rpb24oKQorICAgICAgICAgICAgLT5HZXRNZXNzYWdlKG1lc3NhZ2UwYSwgZmRfbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZV92YWx1ZSkpOworICAgIGludDMyIGludDMyX3ZhbHVlMGEgPSBzdWJfbWVzc2FnZTBhLmMoKTsKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlOWEgPQorICAgICAgICBtbWZfaW50MzJfZm9yZWlnbl9tZXNzYWdlLkdldCg5LCBlbnRyeV9pbnQzMl9mb3JlaWduX21lc3NhZ2UuZ2V0KCkpOworICAgIGNvbnN0IEZvcmVpZ25NZXNzYWdlJiBzdWJfbWVzc2FnZTlhID0gZG93bl9jYXN0PGNvbnN0IEZvcmVpZ25NZXNzYWdlJj4oCisgICAgICAgIG1lc3NhZ2U5YS5HZXRSZWZsZWN0aW9uKCkKKyAgICAgICAgICAgIC0+R2V0TWVzc2FnZShtZXNzYWdlOWEsIGZkX21hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2VfdmFsdWUpKTsKKyAgICBpbnQzMiBpbnQzMl92YWx1ZTlhID0gc3ViX21lc3NhZ2U5YS5jKCk7CisKKyAgICBtbWZfaW50MzJfZm9yZWlnbl9tZXNzYWdlLlN3YXBFbGVtZW50cygwLCA5KTsKKworICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UwYiA9CisgICAgICAgIG1tZl9pbnQzMl9mb3JlaWduX21lc3NhZ2UuR2V0KDAsIGVudHJ5X2ludDMyX2ZvcmVpZ25fbWVzc2FnZS5nZXQoKSk7CisgICAgY29uc3QgRm9yZWlnbk1lc3NhZ2UmIHN1Yl9tZXNzYWdlMGIgPSBkb3duX2Nhc3Q8Y29uc3QgRm9yZWlnbk1lc3NhZ2UmPigKKyAgICAgICAgbWVzc2FnZTBiLkdldFJlZmxlY3Rpb24oKQorICAgICAgICAgICAgLT5HZXRNZXNzYWdlKG1lc3NhZ2UwYiwgZmRfbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZV92YWx1ZSkpOworICAgIGludDMyIGludDMyX3ZhbHVlMGIgPSBzdWJfbWVzc2FnZTBiLmMoKTsKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlOWIgPQorICAgICAgICBtbWZfaW50MzJfZm9yZWlnbl9tZXNzYWdlLkdldCg5LCBlbnRyeV9pbnQzMl9mb3JlaWduX21lc3NhZ2UuZ2V0KCkpOworICAgIGNvbnN0IEZvcmVpZ25NZXNzYWdlJiBzdWJfbWVzc2FnZTliID0gZG93bl9jYXN0PGNvbnN0IEZvcmVpZ25NZXNzYWdlJj4oCisgICAgICAgIG1lc3NhZ2U5Yi5HZXRSZWZsZWN0aW9uKCkKKyAgICAgICAgICAgIC0+R2V0TWVzc2FnZShtZXNzYWdlOWIsIGZkX21hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2VfdmFsdWUpKTsKKyAgICBpbnQzMiBpbnQzMl92YWx1ZTliID0gc3ViX21lc3NhZ2U5Yi5jKCk7CisKKyAgICBFWFBFQ1RfRVEoaW50MzJfdmFsdWU5YSwgaW50MzJfdmFsdWUwYik7CisgICAgRVhQRUNUX0VRKGludDMyX3ZhbHVlMGEsIGludDMyX3ZhbHVlOWIpOworICB9Cit9CisKK1RFU1RfRihNYXBGaWVsZFJlZmxlY3Rpb25UZXN0LCBSZXBlYXRlZEZpZWxkUmVmTWVyZ2VGcm9tQW5kU3dhcCkgeworICAvLyBTZXQtdXAgbWVzc2FnZSBjb250ZW50LgorICBUZXN0TWFwIG0wLCBtMSwgbTI7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7ICsraSkgeworICAgICgqbTAubXV0YWJsZV9tYXBfaW50MzJfaW50MzIoKSlbaV0gPSBGdW5jKGksIDEpOworICAgICgqbTAubXV0YWJsZV9tYXBfaW50MzJfZG91YmxlKCkpW2ldID0gRnVuYyhpLCAyKTsKKyAgICAoKm0wLm11dGFibGVfbWFwX3N0cmluZ19zdHJpbmcoKSlbU3RyRnVuYyhpLCAxKV0gPSBTdHJGdW5jKGksIDUpOworICAgICgqbTAubXV0YWJsZV9tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlKCkpW2ldLnNldF9jKEZ1bmMoaSwgNikpOworICAgICgqbTEubXV0YWJsZV9tYXBfaW50MzJfaW50MzIoKSlbaSArIDEwXSA9IEZ1bmMoaSwgMTEpOworICAgICgqbTEubXV0YWJsZV9tYXBfaW50MzJfZG91YmxlKCkpW2kgKyAxMF0gPSBGdW5jKGksIDEyKTsKKyAgICAoKm0xLm11dGFibGVfbWFwX3N0cmluZ19zdHJpbmcoKSlbU3RyRnVuYyhpICsgMTAsIDEpXSA9IFN0ckZ1bmMoaSwgMTUpOworICAgICgqbTEubXV0YWJsZV9tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlKCkpW2kgKyAxMF0uc2V0X2MoRnVuYyhpLCAxNikpOworICAgICgqbTIubXV0YWJsZV9tYXBfaW50MzJfaW50MzIoKSlbaSArIDIwXSA9IEZ1bmMoaSwgMjEpOworICAgICgqbTIubXV0YWJsZV9tYXBfaW50MzJfZG91YmxlKCkpW2kgKyAyMF0gPSBGdW5jKGksIDIyKTsKKyAgICAoKm0yLm11dGFibGVfbWFwX3N0cmluZ19zdHJpbmcoKSlbU3RyRnVuYyhpICsgMjAsIDEpXSA9IFN0ckZ1bmMoaSwgMjUpOworICAgICgqbTIubXV0YWJsZV9tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlKCkpW2kgKyAyMF0uc2V0X2MoRnVuYyhpLCAyNikpOworICB9CisKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbCA9IG0wLkdldFJlZmxlY3Rpb24oKTsKKyAgY29uc3QgRGVzY3JpcHRvciogZGVzYyA9IG0wLkdldERlc2NyaXB0b3IoKTsKKworICAvLyBHZXQgRmllbGREZXNjcmlwdG9ycyBmb3IgYWxsIHRoZSBmaWVsZHMgb2YgaW50ZXJlc3QuCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmRfbWFwX2ludDMyX2ludDMyID0KKyAgICAgIGRlc2MtPkZpbmRGaWVsZEJ5TmFtZSgibWFwX2ludDMyX2ludDMyIik7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmRfbWFwX2ludDMyX2RvdWJsZSA9CisgICAgICBkZXNjLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9pbnQzMl9kb3VibGUiKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmZF9tYXBfc3RyaW5nX3N0cmluZyA9CisgICAgICBkZXNjLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9zdHJpbmdfc3RyaW5nIik7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmRfbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSA9CisgICAgICBkZXNjLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UiKTsKKworICAgIC8vIEdldCBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZiBvYmplY3RzIGZvciBhbGwgZmllbGRzIG9mIGludGVyZXN0LgorICBjb25zdCBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxNZXNzYWdlPiBtbWZfaW50MzJfaW50MzIgPQorICAgICAgcmVmbC0+R2V0TXV0YWJsZVJlcGVhdGVkRmllbGRSZWY8TWVzc2FnZT4oCisgICAgICAgICAgJm0wLCBmZF9tYXBfaW50MzJfaW50MzIpOworICBjb25zdCBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxNZXNzYWdlPiBtbWZfaW50MzJfZG91YmxlID0KKyAgICAgIHJlZmwtPkdldE11dGFibGVSZXBlYXRlZEZpZWxkUmVmPE1lc3NhZ2U+KAorICAgICAgICAgICZtMCwgZmRfbWFwX2ludDMyX2RvdWJsZSk7CisgIGNvbnN0IE11dGFibGVSZXBlYXRlZEZpZWxkUmVmPE1lc3NhZ2U+IG1tZl9zdHJpbmdfc3RyaW5nID0KKyAgICAgIHJlZmwtPkdldE11dGFibGVSZXBlYXRlZEZpZWxkUmVmPE1lc3NhZ2U+KAorICAgICAgICAgICZtMCwgZmRfbWFwX3N0cmluZ19zdHJpbmcpOworICBjb25zdCBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxNZXNzYWdlPgorICAgICAgbW1mX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSA9CisgICAgICAgICAgcmVmbC0+R2V0TXV0YWJsZVJlcGVhdGVkRmllbGRSZWY8TWVzc2FnZT4oCisgICAgICAgICAgICAgICZtMCwgZmRfbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSk7CisKKyAgLy8gVGVzdCBNdXRhYmxlUmVwZWF0ZWRSZWY6OkNvcHlGcm9tCisgIG1tZl9pbnQzMl9pbnQzMi5Db3B5RnJvbSgKKyAgICAgIHJlZmwtPkdldFJlcGVhdGVkRmllbGRSZWY8TWVzc2FnZT4oCisgICAgICAgICAgbTEsIGZkX21hcF9pbnQzMl9pbnQzMikpOworICBtbWZfaW50MzJfZG91YmxlLkNvcHlGcm9tKAorICAgICAgcmVmbC0+R2V0UmVwZWF0ZWRGaWVsZFJlZjxNZXNzYWdlPigKKyAgICAgICAgICBtMSwgZmRfbWFwX2ludDMyX2RvdWJsZSkpOworICBtbWZfc3RyaW5nX3N0cmluZy5Db3B5RnJvbSgKKyAgICAgIHJlZmwtPkdldFJlcGVhdGVkRmllbGRSZWY8TWVzc2FnZT4oCisgICAgICAgICAgbTEsIGZkX21hcF9zdHJpbmdfc3RyaW5nKSk7CisgIG1tZl9pbnQzMl9mb3JlaWduX21lc3NhZ2UuQ29weUZyb20oCisgICAgICByZWZsLT5HZXRSZXBlYXRlZEZpZWxkUmVmPE1lc3NhZ2U+KAorICAgICAgICAgIG0xLCBmZF9tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlKSk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgKytpKSB7CisgICAgRVhQRUNUX0VRKEZ1bmMoaSwgMTEpLCBtMC5tYXBfaW50MzJfaW50MzIoKS5hdChpICsgMTApKTsKKyAgICBFWFBFQ1RfRVEoRnVuYyhpLCAxMiksIG0wLm1hcF9pbnQzMl9kb3VibGUoKS5hdChpICsgMTApKTsKKyAgICBFWFBFQ1RfRVEoU3RyRnVuYyhpLCAxNSksIG0wLm1hcF9zdHJpbmdfc3RyaW5nKCkuYXQoU3RyRnVuYyhpICsgMTAsIDEpKSk7CisgICAgRVhQRUNUX0VRKEZ1bmMoaSwgMTYpLCBtMC5tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlKCkuYXQoaSArIDEwKS5jKCkpOworICB9CisKKyAgLy8gVGVzdCBNdXRhYmxlUmVwZWF0ZWRSZWY6Ok1lcmdlRnJvbQorICBtbWZfaW50MzJfaW50MzIuTWVyZ2VGcm9tKAorICAgICAgcmVmbC0+R2V0UmVwZWF0ZWRGaWVsZFJlZjxNZXNzYWdlPigKKyAgICAgICAgICBtMiwgZmRfbWFwX2ludDMyX2ludDMyKSk7CisgIG1tZl9pbnQzMl9kb3VibGUuTWVyZ2VGcm9tKAorICAgICAgcmVmbC0+R2V0UmVwZWF0ZWRGaWVsZFJlZjxNZXNzYWdlPigKKyAgICAgICAgICBtMiwgZmRfbWFwX2ludDMyX2RvdWJsZSkpOworICBtbWZfc3RyaW5nX3N0cmluZy5NZXJnZUZyb20oCisgICAgICByZWZsLT5HZXRSZXBlYXRlZEZpZWxkUmVmPE1lc3NhZ2U+KAorICAgICAgICAgIG0yLCBmZF9tYXBfc3RyaW5nX3N0cmluZykpOworICBtbWZfaW50MzJfZm9yZWlnbl9tZXNzYWdlLk1lcmdlRnJvbSgKKyAgICAgIHJlZmwtPkdldFJlcGVhdGVkRmllbGRSZWY8TWVzc2FnZT4oCisgICAgICAgICAgbTIsIGZkX21hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UpKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgKytpKSB7CisgICAgRVhQRUNUX0VRKEZ1bmMoaSwgMjEpLCBtMC5tYXBfaW50MzJfaW50MzIoKS5hdChpICsgMjApKTsKKyAgICBFWFBFQ1RfRVEoRnVuYyhpLCAyMiksIG0wLm1hcF9pbnQzMl9kb3VibGUoKS5hdChpICsgMjApKTsKKyAgICBFWFBFQ1RfRVEoU3RyRnVuYyhpLCAyNSksIG0wLm1hcF9zdHJpbmdfc3RyaW5nKCkuYXQoU3RyRnVuYyhpICsgMjAsIDEpKSk7CisgICAgRVhQRUNUX0VRKEZ1bmMoaSwgMjYpLCBtMC5tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlKCkuYXQoaSArIDIwKS5jKCkpOworICB9CisKKyAgLy8gVGVzdCBNdXRhYmxlUmVwZWF0ZWRSZWY6OlN3YXAKKyAgLy8gU3dhcCBiZXR3ZWVuIG0wIGFuZCBtMi4KKyAgbW1mX2ludDMyX2ludDMyLlN3YXAoCisgICAgICByZWZsLT5HZXRNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxNZXNzYWdlPigKKyAgICAgICAgICAmbTIsIGZkX21hcF9pbnQzMl9pbnQzMikpOworICBtbWZfaW50MzJfZG91YmxlLlN3YXAoCisgICAgICByZWZsLT5HZXRNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxNZXNzYWdlPigKKyAgICAgICAgICAmbTIsIGZkX21hcF9pbnQzMl9kb3VibGUpKTsKKyAgbW1mX3N0cmluZ19zdHJpbmcuU3dhcCgKKyAgICAgIHJlZmwtPkdldE11dGFibGVSZXBlYXRlZEZpZWxkUmVmPE1lc3NhZ2U+KAorICAgICAgICAgICZtMiwgZmRfbWFwX3N0cmluZ19zdHJpbmcpKTsKKyAgbW1mX2ludDMyX2ZvcmVpZ25fbWVzc2FnZS5Td2FwKAorICAgICAgcmVmbC0+R2V0TXV0YWJsZVJlcGVhdGVkRmllbGRSZWY8TWVzc2FnZT4oCisgICAgICAgICAgJm0yLCBmZF9tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlKSk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7ICsraSkgeworICAgIC8vIENoZWNrIHRoZSBjb250ZW50IG9mIG0wLgorICAgIEVYUEVDVF9FUShGdW5jKGksIDIxKSwgbTAubWFwX2ludDMyX2ludDMyKCkuYXQoaSArIDIwKSk7CisgICAgRVhQRUNUX0VRKEZ1bmMoaSwgMjIpLCBtMC5tYXBfaW50MzJfZG91YmxlKCkuYXQoaSArIDIwKSk7CisgICAgRVhQRUNUX0VRKFN0ckZ1bmMoaSwgMjUpLCBtMC5tYXBfc3RyaW5nX3N0cmluZygpLmF0KFN0ckZ1bmMoaSArIDIwLCAxKSkpOworICAgIEVYUEVDVF9FUShGdW5jKGksIDI2KSwgbTAubWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSgpLmF0KGkgKyAyMCkuYygpKTsKKworICAgIC8vIENoZWNrIHRoZSBjb250ZW50IG9mIG0yLgorICAgIEVYUEVDVF9FUShGdW5jKGksIDExKSwgbTIubWFwX2ludDMyX2ludDMyKCkuYXQoaSArIDEwKSk7CisgICAgRVhQRUNUX0VRKEZ1bmMoaSwgMTIpLCBtMi5tYXBfaW50MzJfZG91YmxlKCkuYXQoaSArIDEwKSk7CisgICAgRVhQRUNUX0VRKFN0ckZ1bmMoaSwgMTUpLCBtMi5tYXBfc3RyaW5nX3N0cmluZygpLmF0KFN0ckZ1bmMoaSArIDEwLCAxKSkpOworICAgIEVYUEVDVF9FUShGdW5jKGksIDE2KSwgbTIubWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSgpLmF0KGkgKyAxMCkuYygpKTsKKyAgICBFWFBFQ1RfRVEoRnVuYyhpLCAyMSksIG0yLm1hcF9pbnQzMl9pbnQzMigpLmF0KGkgKyAyMCkpOworICAgIEVYUEVDVF9FUShGdW5jKGksIDIyKSwgbTIubWFwX2ludDMyX2RvdWJsZSgpLmF0KGkgKyAyMCkpOworICAgIEVYUEVDVF9FUShTdHJGdW5jKGksIDI1KSwgbTIubWFwX3N0cmluZ19zdHJpbmcoKS5hdChTdHJGdW5jKGkgKyAyMCwgMSkpKTsKKyAgICBFWFBFQ1RfRVEoRnVuYyhpLCAyNiksIG0yLm1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UoKS5hdChpICsgMjApLmMoKSk7CisgIH0KKworICAvLyBUT0RPKHRlYm9yaW5nKTogYWRkIHRlc3QgZm9yIGR1cGxpY2F0ZWQga2V5Cit9CisKKy8vIEdlbmVyYXRlZCBNZXNzYWdlIFRlc3QgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitURVNUKEdlbmVyYXRlZE1hcEZpZWxkVGVzdCwgQWNjZXNzb3JzKSB7CisgIHVuaXR0ZXN0OjpUZXN0TWFwIG1lc3NhZ2U7CisKKyAgTWFwVGVzdFV0aWw6OlNldE1hcEZpZWxkcygmbWVzc2FnZSk7CisgIE1hcFRlc3RVdGlsOjpFeHBlY3RNYXBGaWVsZHNTZXQobWVzc2FnZSk7CisKKyAgTWFwVGVzdFV0aWw6Ok1vZGlmeU1hcEZpZWxkcygmbWVzc2FnZSk7CisgIE1hcFRlc3RVdGlsOjpFeHBlY3RNYXBGaWVsZHNNb2RpZmllZChtZXNzYWdlKTsKK30KKworVEVTVChHZW5lcmF0ZWRNYXBGaWVsZFRlc3QsIFNldE1hcEZpZWxkc0luaXRpYWxpemVkKSB7CisgIHVuaXR0ZXN0OjpUZXN0TWFwIG1lc3NhZ2U7CisKKyAgTWFwVGVzdFV0aWw6OlNldE1hcEZpZWxkc0luaXRpYWxpemVkKCZtZXNzYWdlKTsKKyAgTWFwVGVzdFV0aWw6OkV4cGVjdE1hcEZpZWxkc1NldEluaXRpYWxpemVkKG1lc3NhZ2UpOworfQorCitURVNUKEdlbmVyYXRlZE1hcEZpZWxkVGVzdCwgUHJvdG8yU2V0TWFwRmllbGRzSW5pdGlhbGl6ZWQpIHsKKyAgdW5pdHRlc3Q6OlRlc3RFbnVtTWFwIG1lc3NhZ2U7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6UFJPVE8yX01BUF9FTlVNX0ZPTywKKyAgICAgICAgICAgICgqbWVzc2FnZS5tdXRhYmxlX2tub3duX21hcF9maWVsZCgpKVswXSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWFwRmllbGRUZXN0LCBDbGVhcikgeworICB1bml0dGVzdDo6VGVzdE1hcCBtZXNzYWdlOworCisgIE1hcFRlc3RVdGlsOjpTZXRNYXBGaWVsZHMoJm1lc3NhZ2UpOworICBtZXNzYWdlLkNsZWFyKCk7CisgIE1hcFRlc3RVdGlsOjpFeHBlY3RDbGVhcihtZXNzYWdlKTsKK30KKworVEVTVChHZW5lcmF0ZWRNYXBGaWVsZFRlc3QsIENsZWFyTWVzc2FnZU1hcCkgeworICB1bml0dGVzdDo6VGVzdE1lc3NhZ2VNYXAgbWVzc2FnZTsKKworICAvLyBDcmVhdGVzIGEgVGVzdEFsbFR5cGVzIHdpdGggZGVmYXVsdCB2YWx1ZQorICBUZXN0VXRpbDo6RXhwZWN0Q2xlYXIoKCptZXNzYWdlLm11dGFibGVfbWFwX2ludDMyX21lc3NhZ2UoKSlbMF0pOworfQorCitURVNUKEdlbmVyYXRlZE1hcEZpZWxkVGVzdCwgQ29weUZyb20pIHsKKyAgdW5pdHRlc3Q6OlRlc3RNYXAgbWVzc2FnZTEsIG1lc3NhZ2UyOworCisgIE1hcFRlc3RVdGlsOjpTZXRNYXBGaWVsZHMoJm1lc3NhZ2UxKTsKKyAgbWVzc2FnZTIuQ29weUZyb20obWVzc2FnZTEpOworICBNYXBUZXN0VXRpbDo6RXhwZWN0TWFwRmllbGRzU2V0KG1lc3NhZ2UyKTsKKworICAvLyBDb3B5aW5nIGZyb20gc2VsZiBzaG91bGQgYmUgYSBuby1vcC4KKyAgbWVzc2FnZTIuQ29weUZyb20obWVzc2FnZTIpOworICBNYXBUZXN0VXRpbDo6RXhwZWN0TWFwRmllbGRzU2V0KG1lc3NhZ2UyKTsKK30KKworVEVTVChHZW5lcmF0ZWRNYXBGaWVsZFRlc3QsIENvcHlGcm9tTWVzc2FnZU1hcCkgeworICB1bml0dGVzdDo6VGVzdE1lc3NhZ2VNYXAgbWVzc2FnZTEsIG1lc3NhZ2UyOworCisgICgqbWVzc2FnZTEubXV0YWJsZV9tYXBfaW50MzJfbWVzc2FnZSgpKVswXS5hZGRfcmVwZWF0ZWRfaW50MzIoMTAwKTsKKyAgKCptZXNzYWdlMi5tdXRhYmxlX21hcF9pbnQzMl9tZXNzYWdlKCkpWzBdLmFkZF9yZXBlYXRlZF9pbnQzMigxMDEpOworCisgIG1lc3NhZ2UxLkNvcHlGcm9tKG1lc3NhZ2UyKTsKKworICAvLyBDaGVja3MgcmVwZWF0ZWQgZmllbGQgaXMgb3ZlcndyaXR0ZW4uCisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlMS5tYXBfaW50MzJfbWVzc2FnZSgpLmF0KDApLnJlcGVhdGVkX2ludDMyX3NpemUoKSk7CisgIEVYUEVDVF9FUSgxMDEsIG1lc3NhZ2UxLm1hcF9pbnQzMl9tZXNzYWdlKCkuYXQoMCkucmVwZWF0ZWRfaW50MzIoMCkpOworfQorCitURVNUKEdlbmVyYXRlZE1hcEZpZWxkVGVzdCwgU3dhcFdpdGhFbXB0eSkgeworICB1bml0dGVzdDo6VGVzdE1hcCBtZXNzYWdlMSwgbWVzc2FnZTI7CisKKyAgTWFwVGVzdFV0aWw6OlNldE1hcEZpZWxkcygmbWVzc2FnZTEpOworICBNYXBUZXN0VXRpbDo6RXhwZWN0TWFwRmllbGRzU2V0KG1lc3NhZ2UxKTsKKyAgTWFwVGVzdFV0aWw6OkV4cGVjdENsZWFyKG1lc3NhZ2UyKTsKKworICBtZXNzYWdlMS5Td2FwKCZtZXNzYWdlMik7CisgIE1hcFRlc3RVdGlsOjpFeHBlY3RNYXBGaWVsZHNTZXQobWVzc2FnZTIpOworICBNYXBUZXN0VXRpbDo6RXhwZWN0Q2xlYXIobWVzc2FnZTEpOworfQorCitURVNUKEdlbmVyYXRlZE1hcEZpZWxkVGVzdCwgU3dhcFdpdGhTZWxmKSB7CisgIHVuaXR0ZXN0OjpUZXN0TWFwIG1lc3NhZ2U7CisKKyAgTWFwVGVzdFV0aWw6OlNldE1hcEZpZWxkcygmbWVzc2FnZSk7CisgIE1hcFRlc3RVdGlsOjpFeHBlY3RNYXBGaWVsZHNTZXQobWVzc2FnZSk7CisKKyAgbWVzc2FnZS5Td2FwKCZtZXNzYWdlKTsKKyAgTWFwVGVzdFV0aWw6OkV4cGVjdE1hcEZpZWxkc1NldChtZXNzYWdlKTsKK30KKworVEVTVChHZW5lcmF0ZWRNYXBGaWVsZFRlc3QsIFN3YXBXaXRoT3RoZXIpIHsKKyAgdW5pdHRlc3Q6OlRlc3RNYXAgbWVzc2FnZTEsIG1lc3NhZ2UyOworCisgIE1hcFRlc3RVdGlsOjpTZXRNYXBGaWVsZHMoJm1lc3NhZ2UxKTsKKyAgTWFwVGVzdFV0aWw6OlNldE1hcEZpZWxkcygmbWVzc2FnZTIpOworICBNYXBUZXN0VXRpbDo6TW9kaWZ5TWFwRmllbGRzKCZtZXNzYWdlMik7CisKKyAgbWVzc2FnZTEuU3dhcCgmbWVzc2FnZTIpOworICBNYXBUZXN0VXRpbDo6RXhwZWN0TWFwRmllbGRzTW9kaWZpZWQobWVzc2FnZTEpOworICBNYXBUZXN0VXRpbDo6RXhwZWN0TWFwRmllbGRzU2V0KG1lc3NhZ2UyKTsKK30KKworVEVTVChHZW5lcmF0ZWRNYXBGaWVsZFRlc3QsIENvcHlDb25zdHJ1Y3RvcikgeworICB1bml0dGVzdDo6VGVzdE1hcCBtZXNzYWdlMTsKKyAgTWFwVGVzdFV0aWw6OlNldE1hcEZpZWxkcygmbWVzc2FnZTEpOworCisgIHVuaXR0ZXN0OjpUZXN0TWFwIG1lc3NhZ2UyKG1lc3NhZ2UxKTsKKyAgTWFwVGVzdFV0aWw6OkV4cGVjdE1hcEZpZWxkc1NldChtZXNzYWdlMik7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWFwRmllbGRUZXN0LCBDb3B5QXNzaWdubWVudE9wZXJhdG9yKSB7CisgIHVuaXR0ZXN0OjpUZXN0TWFwIG1lc3NhZ2UxOworICBNYXBUZXN0VXRpbDo6U2V0TWFwRmllbGRzKCZtZXNzYWdlMSk7CisKKyAgdW5pdHRlc3Q6OlRlc3RNYXAgbWVzc2FnZTI7CisgIG1lc3NhZ2UyID0gbWVzc2FnZTE7CisgIE1hcFRlc3RVdGlsOjpFeHBlY3RNYXBGaWVsZHNTZXQobWVzc2FnZTIpOworCisgIC8vIE1ha2Ugc3VyZSB0aGF0IHNlbGYtYXNzaWdubWVudCBkb2VzIHNvbWV0aGluZyBzYW5lLgorICBtZXNzYWdlMi5vcGVyYXRvcj0obWVzc2FnZTIpOworICBNYXBUZXN0VXRpbDo6RXhwZWN0TWFwRmllbGRzU2V0KG1lc3NhZ2UyKTsKK30KKworI2lmICFkZWZpbmVkKFBST1RPQlVGX1RFU1RfTk9fREVTQ1JJUFRPUlMpIHx8IFwKKyAgICAgICAgIWRlZmluZWQoR09PR0xFX1BST1RPQlVGX05PX1JUVEkpCitURVNUKEdlbmVyYXRlZE1hcEZpZWxkVGVzdCwgVXBjYXN0Q29weUZyb20pIHsKKyAgLy8gVGVzdCB0aGUgQ29weUZyb20gbWV0aG9kIHRoYXQgdGFrZXMgaW4gdGhlIGdlbmVyaWMgY29uc3QgTWVzc2FnZSYKKyAgLy8gcGFyYW1ldGVyLgorICB1bml0dGVzdDo6VGVzdE1hcCBtZXNzYWdlMSwgbWVzc2FnZTI7CisKKyAgTWFwVGVzdFV0aWw6OlNldE1hcEZpZWxkcygmbWVzc2FnZTEpOworCisgIGNvbnN0IE1lc3NhZ2UqIHNvdXJjZSA9IGltcGxpY2l0X2Nhc3Q8Y29uc3QgTWVzc2FnZSo+KCZtZXNzYWdlMSk7CisgIG1lc3NhZ2UyLkNvcHlGcm9tKCpzb3VyY2UpOworCisgIE1hcFRlc3RVdGlsOjpFeHBlY3RNYXBGaWVsZHNTZXQobWVzc2FnZTIpOworfQorI2VuZGlmCisKKyNpZm5kZWYgUFJPVE9CVUZfVEVTVF9OT19ERVNDUklQVE9SUworCitURVNUKEdlbmVyYXRlZE1hcEZpZWxkVGVzdCwgQ29weUZyb21EeW5hbWljTWVzc2FnZSkgeworICAvLyBUZXN0IGNvcHlpbmcgZnJvbSBhIER5bmFtaWNNZXNzYWdlLCB3aGljaCBtdXN0IGZhbGwgYmFjayB0byB1c2luZworICAvLyByZWZsZWN0aW9uLgorICB1bml0dGVzdDo6VGVzdE1hcCBtZXNzYWdlMjsKKworICAvLyBDb25zdHJ1Y3QgYSBuZXcgdmVyc2lvbiBvZiB0aGUgZHluYW1pYyBtZXNzYWdlIHZpYSB0aGUgZmFjdG9yeS4KKyAgRHluYW1pY01lc3NhZ2VGYWN0b3J5IGZhY3Rvcnk7CisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8TWVzc2FnZT4gbWVzc2FnZTE7CisgIG1lc3NhZ2UxLnJlc2V0KAorICAgICAgZmFjdG9yeS5HZXRQcm90b3R5cGUodW5pdHRlc3Q6OlRlc3RNYXA6OmRlc2NyaXB0b3IoKSktPk5ldygpKTsKKyAgTWFwUmVmbGVjdGlvblRlc3RlciByZWZsZWN0aW9uX3Rlc3RlcigKKyAgICAgIHVuaXR0ZXN0OjpUZXN0TWFwOjpkZXNjcmlwdG9yKCkpOworICByZWZsZWN0aW9uX3Rlc3Rlci5TZXRNYXBGaWVsZHNWaWFSZWZsZWN0aW9uKG1lc3NhZ2UxLmdldCgpKTsKKyAgcmVmbGVjdGlvbl90ZXN0ZXIuRXhwZWN0TWFwRmllbGRzU2V0VmlhUmVmbGVjdGlvbigqbWVzc2FnZTEpOworICByZWZsZWN0aW9uX3Rlc3Rlci5FeHBlY3RNYXBGaWVsZHNTZXRWaWFSZWZsZWN0aW9uSXRlcmF0b3IobWVzc2FnZTEuZ2V0KCkpOworICBtZXNzYWdlMi5Db3B5RnJvbSgqbWVzc2FnZTEpOworICBNYXBUZXN0VXRpbDo6RXhwZWN0TWFwRmllbGRzU2V0KG1lc3NhZ2UyKTsKK30KKworVEVTVChHZW5lcmF0ZWRNYXBGaWVsZFRlc3QsIENvcHlGcm9tRHluYW1pY01lc3NhZ2VNYXBSZWZsZWN0aW9uKSB7CisgIHVuaXR0ZXN0OjpUZXN0TWFwIG1lc3NhZ2UyOworCisgIC8vIENvbnN0cnVjdCBhIG5ldyB2ZXJzaW9uIG9mIHRoZSBkeW5hbWljIG1lc3NhZ2UgdmlhIHRoZSBmYWN0b3J5LgorICBEeW5hbWljTWVzc2FnZUZhY3RvcnkgZmFjdG9yeTsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxNZXNzYWdlPiBtZXNzYWdlMTsKKyAgbWVzc2FnZTEucmVzZXQoCisgICAgICBmYWN0b3J5LkdldFByb3RvdHlwZSh1bml0dGVzdDo6VGVzdE1hcDo6ZGVzY3JpcHRvcigpKS0+TmV3KCkpOworICBNYXBSZWZsZWN0aW9uVGVzdGVyIHJlZmxlY3Rpb25fdGVzdGVyKAorICAgICAgdW5pdHRlc3Q6OlRlc3RNYXA6OmRlc2NyaXB0b3IoKSk7CisgIHJlZmxlY3Rpb25fdGVzdGVyLlNldE1hcEZpZWxkc1ZpYU1hcFJlZmxlY3Rpb24obWVzc2FnZTEuZ2V0KCkpOworICByZWZsZWN0aW9uX3Rlc3Rlci5FeHBlY3RNYXBGaWVsZHNTZXRWaWFSZWZsZWN0aW9uKCptZXNzYWdlMSk7CisgIHJlZmxlY3Rpb25fdGVzdGVyLkV4cGVjdE1hcEZpZWxkc1NldFZpYVJlZmxlY3Rpb25JdGVyYXRvcihtZXNzYWdlMS5nZXQoKSk7CisgIG1lc3NhZ2UyLkNvcHlGcm9tKCptZXNzYWdlMSk7CisgIE1hcFRlc3RVdGlsOjpFeHBlY3RNYXBGaWVsZHNTZXQobWVzc2FnZTIpOworfQorCitURVNUKEdlbmVyYXRlZE1hcEZpZWxkVGVzdCwgRHluYW1pY01lc3NhZ2VDb3B5RnJvbSkgeworICAvLyBUZXN0IGNvcHlpbmcgdG8gYSBEeW5hbWljTWVzc2FnZSwgd2hpY2ggbXVzdCBmYWxsIGJhY2sgdG8gdXNpbmcgcmVmbGVjdGlvbi4KKyAgdW5pdHRlc3Q6OlRlc3RNYXAgbWVzc2FnZTI7CisgIE1hcFRlc3RVdGlsOjpTZXRNYXBGaWVsZHMoJm1lc3NhZ2UyKTsKKworICAvLyBDb25zdHJ1Y3QgYSBuZXcgdmVyc2lvbiBvZiB0aGUgZHluYW1pYyBtZXNzYWdlIHZpYSB0aGUgZmFjdG9yeS4KKyAgRHluYW1pY01lc3NhZ2VGYWN0b3J5IGZhY3Rvcnk7CisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8TWVzc2FnZT4gbWVzc2FnZTE7CisgIG1lc3NhZ2UxLnJlc2V0KAorICAgICAgZmFjdG9yeS5HZXRQcm90b3R5cGUodW5pdHRlc3Q6OlRlc3RNYXA6OmRlc2NyaXB0b3IoKSktPk5ldygpKTsKKworICBNYXBSZWZsZWN0aW9uVGVzdGVyIHJlZmxlY3Rpb25fdGVzdGVyKAorICAgICAgdW5pdHRlc3Q6OlRlc3RNYXA6OmRlc2NyaXB0b3IoKSk7CisgIG1lc3NhZ2UxLT5NZXJnZUZyb20obWVzc2FnZTIpOworICByZWZsZWN0aW9uX3Rlc3Rlci5FeHBlY3RNYXBGaWVsZHNTZXRWaWFSZWZsZWN0aW9uKCptZXNzYWdlMSk7CisgIHJlZmxlY3Rpb25fdGVzdGVyLkV4cGVjdE1hcEZpZWxkc1NldFZpYVJlZmxlY3Rpb25JdGVyYXRvcihtZXNzYWdlMS5nZXQoKSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWFwRmllbGRUZXN0LCBEeW5hbWljTWVzc2FnZUNvcHlGcm9tTWFwUmVmbGVjdGlvbikgeworICBNYXBSZWZsZWN0aW9uVGVzdGVyIHJlZmxlY3Rpb25fdGVzdGVyKAorICAgICAgdW5pdHRlc3Q6OlRlc3RNYXA6OmRlc2NyaXB0b3IoKSk7CisgIHVuaXR0ZXN0OjpUZXN0TWFwIG1lc3NhZ2UyOworICByZWZsZWN0aW9uX3Rlc3Rlci5TZXRNYXBGaWVsZHNWaWFNYXBSZWZsZWN0aW9uKCZtZXNzYWdlMik7CisKKyAgLy8gQ29uc3RydWN0IGEgZHluYW1pYyBtZXNzYWdlIHZpYSB0aGUgZmFjdG9yeS4KKyAgRHluYW1pY01lc3NhZ2VGYWN0b3J5IGZhY3Rvcnk7CisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8TWVzc2FnZT4gbWVzc2FnZTE7CisgIG1lc3NhZ2UxLnJlc2V0KAorICAgICAgZmFjdG9yeS5HZXRQcm90b3R5cGUodW5pdHRlc3Q6OlRlc3RNYXA6OmRlc2NyaXB0b3IoKSktPk5ldygpKTsKKworICBtZXNzYWdlMS0+TWVyZ2VGcm9tKG1lc3NhZ2UyKTsKKyAgcmVmbGVjdGlvbl90ZXN0ZXIuRXhwZWN0TWFwRmllbGRzU2V0VmlhUmVmbGVjdGlvbkl0ZXJhdG9yKG1lc3NhZ2UxLmdldCgpKTsKKyAgcmVmbGVjdGlvbl90ZXN0ZXIuRXhwZWN0TWFwRmllbGRzU2V0VmlhUmVmbGVjdGlvbigqbWVzc2FnZTEpOworfQorCitURVNUKEdlbmVyYXRlZE1hcEZpZWxkVGVzdCwgU3luY0R5bmFtaWNNYXBXaXRoUmVwZWF0ZWRGaWVsZCkgeworICAvLyBDb25zdHJ1Y3QgYSBkeW5hbWljIG1lc3NhZ2UgdmlhIHRoZSBmYWN0b3J5LgorICBNYXBSZWZsZWN0aW9uVGVzdGVyIHJlZmxlY3Rpb25fdGVzdGVyKAorICAgICAgdW5pdHRlc3Q6OlRlc3RNYXA6OmRlc2NyaXB0b3IoKSk7CisgIER5bmFtaWNNZXNzYWdlRmFjdG9yeSBmYWN0b3J5OworICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPE1lc3NhZ2U+IG1lc3NhZ2U7CisgIG1lc3NhZ2UucmVzZXQoCisgICAgICBmYWN0b3J5LkdldFByb3RvdHlwZSh1bml0dGVzdDo6VGVzdE1hcDo6ZGVzY3JpcHRvcigpKS0+TmV3KCkpOworICByZWZsZWN0aW9uX3Rlc3Rlci5TZXRNYXBGaWVsZHNWaWFSZWZsZWN0aW9uKG1lc3NhZ2UuZ2V0KCkpOworICByZWZsZWN0aW9uX3Rlc3Rlci5FeHBlY3RNYXBGaWVsZHNTZXRWaWFSZWZsZWN0aW9uSXRlcmF0b3IobWVzc2FnZS5nZXQoKSk7CisgIHJlZmxlY3Rpb25fdGVzdGVyLkV4cGVjdE1hcEZpZWxkc1NldFZpYVJlZmxlY3Rpb24oKm1lc3NhZ2UpOworfQorCisjZW5kaWYgIC8vICFQUk9UT0JVRl9URVNUX05PX0RFU0NSSVBUT1JTCisKK1RFU1QoR2VuZXJhdGVkTWFwRmllbGRUZXN0LCBOb25FbXB0eU1lcmdlRnJvbSkgeworICB1bml0dGVzdDo6VGVzdE1hcCBtZXNzYWdlMSwgbWVzc2FnZTI7CisKKyAgTWFwVGVzdFV0aWw6OlNldE1hcEZpZWxkcygmbWVzc2FnZTEpOworCisgIC8vIFRoaXMgZmllbGQgd2lsbCB0ZXN0IG1lcmdpbmcgaW50byBhbiBlbXB0eSBzcG90LgorICAoKm1lc3NhZ2UyLm11dGFibGVfbWFwX2ludDMyX2ludDMyKCkpWzFdID0gMTsKKyAgbWVzc2FnZTEubXV0YWJsZV9tYXBfaW50MzJfaW50MzIoKS0+ZXJhc2UoMSk7CisKKyAgLy8gVGhpcyB0ZXN0cyBvdmVyd3JpdGluZy4KKyAgKCptZXNzYWdlMi5tdXRhYmxlX21hcF9pbnQzMl9kb3VibGUoKSlbMV0gPSAxOworICAoKm1lc3NhZ2UxLm11dGFibGVfbWFwX2ludDMyX2RvdWJsZSgpKVsxXSA9IDI7CisKKyAgbWVzc2FnZTEuTWVyZ2VGcm9tKG1lc3NhZ2UyKTsKKyAgTWFwVGVzdFV0aWw6OkV4cGVjdE1hcEZpZWxkc1NldChtZXNzYWdlMSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWFwRmllbGRUZXN0LCBNZXJnZUZyb21NZXNzYWdlTWFwKSB7CisgIHVuaXR0ZXN0OjpUZXN0TWVzc2FnZU1hcCBtZXNzYWdlMSwgbWVzc2FnZTI7CisKKyAgKCptZXNzYWdlMS5tdXRhYmxlX21hcF9pbnQzMl9tZXNzYWdlKCkpWzBdLmFkZF9yZXBlYXRlZF9pbnQzMigxMDApOworICAoKm1lc3NhZ2UyLm11dGFibGVfbWFwX2ludDMyX21lc3NhZ2UoKSlbMF0uYWRkX3JlcGVhdGVkX2ludDMyKDEwMSk7CisKKyAgbWVzc2FnZTEuTWVyZ2VGcm9tKG1lc3NhZ2UyKTsKKworICAvLyBDaGVja3MgcmVwZWF0ZWQgZmllbGQgaXMgb3ZlcndyaXR0ZW4uCisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlMS5tYXBfaW50MzJfbWVzc2FnZSgpLmF0KDApLnJlcGVhdGVkX2ludDMyX3NpemUoKSk7CisgIEVYUEVDVF9FUSgxMDEsIG1lc3NhZ2UxLm1hcF9pbnQzMl9tZXNzYWdlKCkuYXQoMCkucmVwZWF0ZWRfaW50MzIoMCkpOworfQorCisvLyBUZXN0IHRoZSBnZW5lcmF0ZWQgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgpCitURVNUKEdlbmVyYXRlZE1hcEZpZWxkVGVzdCwgU2VyaWFsaXphdGlvblRvQXJyYXkpIHsKKyAgdW5pdHRlc3Q6OlRlc3RNYXAgbWVzc2FnZTEsIG1lc3NhZ2UyOworICBzdHJpbmcgZGF0YTsKKyAgTWFwVGVzdFV0aWw6OlNldE1hcEZpZWxkcygmbWVzc2FnZTEpOworICBpbnQgc2l6ZSA9IG1lc3NhZ2UxLkJ5dGVTaXplKCk7CisgIGRhdGEucmVzaXplKHNpemUpOworICB1aW50OCogc3RhcnQgPSByZWludGVycHJldF9jYXN0PHVpbnQ4Kj4oc3RyaW5nX2FzX2FycmF5KCZkYXRhKSk7CisgIHVpbnQ4KiBlbmQgPSBtZXNzYWdlMS5TZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KHN0YXJ0KTsKKyAgRVhQRUNUX0VRKHNpemUsIGVuZCAtIHN0YXJ0KTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZTIuUGFyc2VGcm9tU3RyaW5nKGRhdGEpKTsKKyAgTWFwVGVzdFV0aWw6OkV4cGVjdE1hcEZpZWxkc1NldChtZXNzYWdlMik7Cit9CisKKy8vIFRlc3QgdGhlIGdlbmVyYXRlZCBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoKQorVEVTVChHZW5lcmF0ZWRNYXBGaWVsZFRlc3QsIFNlcmlhbGl6YXRpb25Ub1N0cmVhbSkgeworICB1bml0dGVzdDo6VGVzdE1hcCBtZXNzYWdlMSwgbWVzc2FnZTI7CisgIE1hcFRlc3RVdGlsOjpTZXRNYXBGaWVsZHMoJm1lc3NhZ2UxKTsKKyAgaW50IHNpemUgPSBtZXNzYWdlMS5CeXRlU2l6ZSgpOworICBzdHJpbmcgZGF0YTsKKyAgZGF0YS5yZXNpemUoc2l6ZSk7CisgIHsKKyAgICAvLyBBbGxvdyB0aGUgb3V0cHV0IHN0cmVhbSB0byBidWZmZXIgb25seSBvbmUgYnl0ZSBhdCBhIHRpbWUuCisgICAgaW86OkFycmF5T3V0cHV0U3RyZWFtIGFycmF5X3N0cmVhbShzdHJpbmdfYXNfYXJyYXkoJmRhdGEpLCBzaXplLCAxKTsKKyAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0X3N0cmVhbSgmYXJyYXlfc3RyZWFtKTsKKyAgICBtZXNzYWdlMS5TZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoJm91dHB1dF9zdHJlYW0pOworICAgIEVYUEVDVF9GQUxTRShvdXRwdXRfc3RyZWFtLkhhZEVycm9yKCkpOworICAgIEVYUEVDVF9FUShzaXplLCBvdXRwdXRfc3RyZWFtLkJ5dGVDb3VudCgpKTsKKyAgfQorICBFWFBFQ1RfVFJVRShtZXNzYWdlMi5QYXJzZUZyb21TdHJpbmcoZGF0YSkpOworICBNYXBUZXN0VXRpbDo6RXhwZWN0TWFwRmllbGRzU2V0KG1lc3NhZ2UyKTsKK30KKworCitURVNUKEdlbmVyYXRlZE1hcEZpZWxkVGVzdCwgU2FtZVR5cGVNYXBzKSB7CisgIGNvbnN0IERlc2NyaXB0b3IqIG1hcDEgPSB1bml0dGVzdDo6VGVzdFNhbWVUeXBlTWFwOjpkZXNjcmlwdG9yKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtPkZpbmRGaWVsZEJ5TmFtZSgibWFwMSIpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLT5tZXNzYWdlX3R5cGUoKTsKKyAgY29uc3QgRGVzY3JpcHRvciogbWFwMiA9IHVuaXR0ZXN0OjpUZXN0U2FtZVR5cGVNYXA6OmRlc2NyaXB0b3IoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0+RmluZEZpZWxkQnlOYW1lKCJtYXAyIikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtPm1lc3NhZ2VfdHlwZSgpOworCisgIGNvbnN0IE1lc3NhZ2UqIG1hcDFfZW50cnkgPQorICAgICAgTWVzc2FnZUZhY3Rvcnk6OmdlbmVyYXRlZF9mYWN0b3J5KCktPkdldFByb3RvdHlwZShtYXAxKTsKKyAgY29uc3QgTWVzc2FnZSogbWFwMl9lbnRyeSA9CisgICAgICBNZXNzYWdlRmFjdG9yeTo6Z2VuZXJhdGVkX2ZhY3RvcnkoKS0+R2V0UHJvdG90eXBlKG1hcDIpOworCisgIEVYUEVDVF9FUShtYXAxLCBtYXAxX2VudHJ5LT5HZXREZXNjcmlwdG9yKCkpOworICBFWFBFQ1RfRVEobWFwMiwgbWFwMl9lbnRyeS0+R2V0RGVzY3JpcHRvcigpKTsKK30KKworVEVTVChHZW5lcmF0ZWRNYXBGaWVsZFRlc3QsIFByb3RvMlVua25vd25FbnVtKSB7CisgIHVuaXR0ZXN0OjpUZXN0RW51bU1hcFBsdXNFeHRyYSBmcm9tOworICAoKmZyb20ubXV0YWJsZV9rbm93bl9tYXBfZmllbGQoKSlbMF0gPSB1bml0dGVzdDo6RV9QUk9UTzJfTUFQX0VOVU1fRk9POworICAoKmZyb20ubXV0YWJsZV91bmtub3duX21hcF9maWVsZCgpKVswXSA9IHVuaXR0ZXN0OjpFX1BST1RPMl9NQVBfRU5VTV9FWFRSQTsKKyAgc3RyaW5nIGRhdGE7CisgIGZyb20uU2VyaWFsaXplVG9TdHJpbmcoJmRhdGEpOworCisgIHVuaXR0ZXN0OjpUZXN0RW51bU1hcCB0bzsKKyAgRVhQRUNUX1RSVUUodG8uUGFyc2VGcm9tU3RyaW5nKGRhdGEpKTsKKyAgRVhQRUNUX0VRKDAsIHRvLnVua25vd25fbWFwX2ZpZWxkKCkuc2l6ZSgpKTsKKyAgY29uc3QgVW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkX3NldCA9CisgICAgICB0by5HZXRSZWZsZWN0aW9uKCktPkdldFVua25vd25GaWVsZHModG8pOworICBFWFBFQ1RfRVEoMSwgdW5rbm93bl9maWVsZF9zZXQuZmllbGRfY291bnQoKSk7CisgIEVYUEVDVF9FUSgxLCB0by5rbm93bl9tYXBfZmllbGQoKS5zaXplKCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlBST1RPMl9NQVBfRU5VTV9GT08sIHRvLmtub3duX21hcF9maWVsZCgpLmF0KDApKTsKKworICBkYXRhLmNsZWFyKCk7CisgIGZyb20uQ2xlYXIoKTsKKyAgdG8uU2VyaWFsaXplVG9TdHJpbmcoJmRhdGEpOworICBFWFBFQ1RfVFJVRShmcm9tLlBhcnNlRnJvbVN0cmluZyhkYXRhKSk7CisgIEVYUEVDVF9FUSgwLCBmcm9tLkdldFJlZmxlY3Rpb24oKS0+R2V0VW5rbm93bkZpZWxkcyhmcm9tKS5maWVsZF9jb3VudCgpKTsKKyAgRVhQRUNUX0VRKDEsIGZyb20ua25vd25fbWFwX2ZpZWxkKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpFX1BST1RPMl9NQVBfRU5VTV9GT08sIGZyb20ua25vd25fbWFwX2ZpZWxkKCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMSwgZnJvbS51bmtub3duX21hcF9maWVsZCgpLnNpemUoKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6RV9QUk9UTzJfTUFQX0VOVU1fRVhUUkEsIGZyb20udW5rbm93bl9tYXBfZmllbGQoKS5hdCgwKSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWFwRmllbGRUZXN0LCBTdGFuZGFyZFdpcmVGb3JtYXQpIHsKKyAgdW5pdHRlc3Q6OlRlc3RNYXAgbWVzc2FnZTsKKyAgc3RyaW5nIGRhdGEgPSAiXHgwQVx4MDRceDA4XHgwMVx4MTBceDAxIjsKKworICBFWFBFQ1RfVFJVRShtZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhkYXRhKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLm1hcF9pbnQzMl9pbnQzMigpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLm1hcF9pbnQzMl9pbnQzMigpLmF0KDEpKTsKK30KKworVEVTVChHZW5lcmF0ZWRNYXBGaWVsZFRlc3QsIFVub3JkZXJlZFdpcmVGb3JtYXQpIHsKKyAgdW5pdHRlc3Q6OlRlc3RNYXAgbWVzc2FnZTsKKworICAvLyBwdXQgdmFsdWUgYmVmb3JlIGtleSBpbiB3aXJlIGZvcm1hdAorICBzdHJpbmcgZGF0YSA9ICJceDBBXHgwNFx4MTBceDAxXHgwOFx4MDIiOworCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKGRhdGEpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX2ludDMyX2ludDMyKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX2ludDMyX2ludDMyKCkuYXQoMikpOworfQorCitURVNUKEdlbmVyYXRlZE1hcEZpZWxkVGVzdCwgRHVwbGljYXRlZEtleVdpcmVGb3JtYXQpIHsKKyAgdW5pdHRlc3Q6OlRlc3RNYXAgbWVzc2FnZTsKKworICAvLyBUd28ga2V5IGZpZWxkcyBpbiB3aXJlIGZvcm1hdAorICBzdHJpbmcgZGF0YSA9ICJceDBBXHgwNlx4MDhceDAxXHgwOFx4MDJceDEwXHgwMSI7CisKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoZGF0YSkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfaW50MzJfaW50MzIoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfaW50MzJfaW50MzIoKS5hdCgyKSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWFwRmllbGRUZXN0LCBEdXBsaWNhdGVkVmFsdWVXaXJlRm9ybWF0KSB7CisgIHVuaXR0ZXN0OjpUZXN0TWFwIG1lc3NhZ2U7CisKKyAgLy8gVHdvIHZhbHVlIGZpZWxkcyBpbiB3aXJlIGZvcm1hdAorICBzdHJpbmcgZGF0YSA9ICJceDBBXHgwNlx4MDhceDAxXHgxMFx4MDFceDEwXHgwMiI7CisKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoZGF0YSkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfaW50MzJfaW50MzIoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfaW50MzJfaW50MzIoKS5hdCgxKSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWFwRmllbGRUZXN0LCBNaXNzZWRLZXlXaXJlRm9ybWF0KSB7CisgIHVuaXR0ZXN0OjpUZXN0TWFwIG1lc3NhZ2U7CisKKyAgLy8gTm8ga2V5IGZpZWxkIGluIHdpcmUgZm9ybWF0CisgIHN0cmluZyBkYXRhID0gIlx4MEFceDAyXHgxMFx4MDEiOworCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKGRhdGEpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX2ludDMyX2ludDMyKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX2ludDMyX2ludDMyKCkuYXQoMCkpOworfQorCitURVNUKEdlbmVyYXRlZE1hcEZpZWxkVGVzdCwgTWlzc2VkVmFsdWVXaXJlRm9ybWF0KSB7CisgIHVuaXR0ZXN0OjpUZXN0TWFwIG1lc3NhZ2U7CisKKyAgLy8gTm8gdmFsdWUgZmllbGQgaW4gd2lyZSBmb3JtYXQKKyAgc3RyaW5nIGRhdGEgPSAiXHgwQVx4MDJceDA4XHgwMSI7CisKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoZGF0YSkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfaW50MzJfaW50MzIoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfaW50MzJfaW50MzIoKS5hdCgxKSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWFwRmllbGRUZXN0LCBNaXNzZWRWYWx1ZVRleHRGb3JtYXQpIHsKKyAgdW5pdHRlc3Q6OlRlc3RNYXAgbWVzc2FnZTsKKworICAvLyBObyB2YWx1ZSBmaWVsZCBpbiB0ZXh0IGZvcm1hdAorICBzdHJpbmcgdGV4dCA9CisgICAgICAibWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSB7XG4iCisgICAgICAiICBrZXk6IDEyMzQ1Njc4OTBcbiIKKyAgICAgICJ9IjsKKworICBFWFBFQ1RfVFJVRShnb29nbGU6OnByb3RvYnVmOjpUZXh0Rm9ybWF0OjpQYXJzZUZyb21TdHJpbmcodGV4dCwgJm1lc3NhZ2UpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSgpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgxMSwgbWVzc2FnZS5CeXRlU2l6ZSgpKTsKK30KKworVEVTVChHZW5lcmF0ZWRNYXBGaWVsZFRlc3QsIFVua25vd25GaWVsZFdpcmVGb3JtYXQpIHsKKyAgdW5pdHRlc3Q6OlRlc3RNYXAgbWVzc2FnZTsKKworICAvLyBVbmtub3duIGZpZWxkIGluIHdpcmUgZm9ybWF0CisgIHN0cmluZyBkYXRhID0gIlx4MEFceDA2XHgwOFx4MDJceDEwXHgwM1x4MThceDAxIjsKKworICBFWFBFQ1RfVFJVRShtZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhkYXRhKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLm1hcF9pbnQzMl9pbnQzMigpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgzLCBtZXNzYWdlLm1hcF9pbnQzMl9pbnQzMigpLmF0KDIpKTsKK30KKworVEVTVChHZW5lcmF0ZWRNYXBGaWVsZFRlc3QsIENvcnJ1cHRlZFdpcmVGb3JtYXQpIHsKKyAgdW5pdHRlc3Q6OlRlc3RNYXAgbWVzc2FnZTsKKworICAvLyBjb3JydXB0ZWQgZGF0YSBpbiB3aXJlIGZvcm1hdAorICBzdHJpbmcgZGF0YSA9ICJceDBBXHgwNlx4MDhceDAyXHgxMVx4MDMiOworCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhkYXRhKSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWFwRmllbGRUZXN0LCBJc0luaXRpYWxpemVkKSB7CisgIHVuaXR0ZXN0OjpUZXN0UmVxdWlyZWRNZXNzYWdlTWFwIG1hcF9tZXNzYWdlOworCisgIC8vIEFkZCBhbiB1bmluaXRpYWxpemVkIG1lc3NhZ2UuCisgICgqbWFwX21lc3NhZ2UubXV0YWJsZV9tYXBfZmllbGQoKSlbMF07CisgIEVYUEVDVF9GQUxTRShtYXBfbWVzc2FnZS5Jc0luaXRpYWxpemVkKCkpOworCisgIC8vIEluaXRpYWxpemUgdW5pbml0aWFsaXplZCBtZXNzYWdlCisgICgqbWFwX21lc3NhZ2UubXV0YWJsZV9tYXBfZmllbGQoKSlbMF0uc2V0X2EoMCk7CisgICgqbWFwX21lc3NhZ2UubXV0YWJsZV9tYXBfZmllbGQoKSlbMF0uc2V0X2IoMCk7CisgICgqbWFwX21lc3NhZ2UubXV0YWJsZV9tYXBfZmllbGQoKSlbMF0uc2V0X2MoMCk7CisgIEVYUEVDVF9UUlVFKG1hcF9tZXNzYWdlLklzSW5pdGlhbGl6ZWQoKSk7Cit9CisKKy8vIEdlbmVyYXRlZCBNZXNzYWdlIFJlZmxlY3Rpb24gVGVzdCA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitURVNUKEdlbmVyYXRlZE1hcEZpZWxkUmVmbGVjdGlvblRlc3QsIFNwYWNlVXNlZCkgeworICB1bml0dGVzdDo6VGVzdE1hcCBtZXNzYWdlOworICBNYXBSZWZsZWN0aW9uVGVzdGVyIHJlZmxlY3Rpb25fdGVzdGVyKAorICAgIHVuaXR0ZXN0OjpUZXN0TWFwOjpkZXNjcmlwdG9yKCkpOworICByZWZsZWN0aW9uX3Rlc3Rlci5TZXRNYXBGaWVsZHNWaWFSZWZsZWN0aW9uKCZtZXNzYWdlKTsKKworICBFWFBFQ1RfTFQoMCwgbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPlNwYWNlVXNlZChtZXNzYWdlKSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWFwRmllbGRSZWZsZWN0aW9uVGVzdCwgQWNjZXNzb3JzKSB7CisgIC8vIFNldCBldmVyeSBmaWVsZCB0byBhIHVuaXF1ZSB2YWx1ZSB0aGVuIGdvIGJhY2sgYW5kIGNoZWNrIGFsbCB0aG9zZQorICAvLyB2YWx1ZXMuCisgIHVuaXR0ZXN0OjpUZXN0TWFwIG1lc3NhZ2U7CisgIE1hcFJlZmxlY3Rpb25UZXN0ZXIgcmVmbGVjdGlvbl90ZXN0ZXIoCisgICAgdW5pdHRlc3Q6OlRlc3RNYXA6OmRlc2NyaXB0b3IoKSk7CisgIHJlZmxlY3Rpb25fdGVzdGVyLlNldE1hcEZpZWxkc1ZpYVJlZmxlY3Rpb24oJm1lc3NhZ2UpOworICBNYXBUZXN0VXRpbDo6RXhwZWN0TWFwRmllbGRzU2V0KG1lc3NhZ2UpOworICByZWZsZWN0aW9uX3Rlc3Rlci5FeHBlY3RNYXBGaWVsZHNTZXRWaWFSZWZsZWN0aW9uKG1lc3NhZ2UpOworICByZWZsZWN0aW9uX3Rlc3Rlci5FeHBlY3RNYXBGaWVsZHNTZXRWaWFSZWZsZWN0aW9uSXRlcmF0b3IoJm1lc3NhZ2UpOworCisgIHJlZmxlY3Rpb25fdGVzdGVyLk1vZGlmeU1hcEZpZWxkc1ZpYVJlZmxlY3Rpb24oJm1lc3NhZ2UpOworICBNYXBUZXN0VXRpbDo6RXhwZWN0TWFwRmllbGRzTW9kaWZpZWQobWVzc2FnZSk7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWFwRmllbGRSZWZsZWN0aW9uVGVzdCwgU3dhcCkgeworICB1bml0dGVzdDo6VGVzdE1hcCBtZXNzYWdlMTsKKyAgdW5pdHRlc3Q6OlRlc3RNYXAgbWVzc2FnZTI7CisKKyAgTWFwVGVzdFV0aWw6OlNldE1hcEZpZWxkcygmbWVzc2FnZTEpOworCisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlMS5HZXRSZWZsZWN0aW9uKCk7CisgIHJlZmxlY3Rpb24tPlN3YXAoJm1lc3NhZ2UxLCAmbWVzc2FnZTIpOworCisgIE1hcFRlc3RVdGlsOjpFeHBlY3RDbGVhcihtZXNzYWdlMSk7CisgIE1hcFRlc3RVdGlsOjpFeHBlY3RNYXBGaWVsZHNTZXQobWVzc2FnZTIpOworfQorCitURVNUKEdlbmVyYXRlZE1hcEZpZWxkUmVmbGVjdGlvblRlc3QsIFN3YXBXaXRoQm90aFNldCkgeworICB1bml0dGVzdDo6VGVzdE1hcCBtZXNzYWdlMTsKKyAgdW5pdHRlc3Q6OlRlc3RNYXAgbWVzc2FnZTI7CisKKyAgTWFwVGVzdFV0aWw6OlNldE1hcEZpZWxkcygmbWVzc2FnZTEpOworICBNYXBUZXN0VXRpbDo6U2V0TWFwRmllbGRzKCZtZXNzYWdlMik7CisgIE1hcFRlc3RVdGlsOjpNb2RpZnlNYXBGaWVsZHMoJm1lc3NhZ2UyKTsKKworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZTEuR2V0UmVmbGVjdGlvbigpOworICByZWZsZWN0aW9uLT5Td2FwKCZtZXNzYWdlMSwgJm1lc3NhZ2UyKTsKKworICBNYXBUZXN0VXRpbDo6RXhwZWN0TWFwRmllbGRzTW9kaWZpZWQobWVzc2FnZTEpOworICBNYXBUZXN0VXRpbDo6RXhwZWN0TWFwRmllbGRzU2V0KG1lc3NhZ2UyKTsKK30KKworVEVTVChHZW5lcmF0ZWRNYXBGaWVsZFJlZmxlY3Rpb25UZXN0LCBTd2FwRmllbGRzKSB7CisgIHVuaXR0ZXN0OjpUZXN0TWFwIG1lc3NhZ2UxOworICB1bml0dGVzdDo6VGVzdE1hcCBtZXNzYWdlMjsKKworICBNYXBUZXN0VXRpbDo6U2V0TWFwRmllbGRzKCZtZXNzYWdlMik7CisKKyAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+IGZpZWxkczsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UxLkdldFJlZmxlY3Rpb24oKTsKKyAgcmVmbGVjdGlvbi0+TGlzdEZpZWxkcyhtZXNzYWdlMiwgJmZpZWxkcyk7CisgIHJlZmxlY3Rpb24tPlN3YXBGaWVsZHMoJm1lc3NhZ2UxLCAmbWVzc2FnZTIsIGZpZWxkcyk7CisKKyAgTWFwVGVzdFV0aWw6OkV4cGVjdE1hcEZpZWxkc1NldChtZXNzYWdlMSk7CisgIE1hcFRlc3RVdGlsOjpFeHBlY3RDbGVhcihtZXNzYWdlMik7Cit9CisKK1RFU1QoR2VuZXJhdGVkTWFwRmllbGRSZWZsZWN0aW9uVGVzdCwgQ2xlYXJGaWVsZCkgeworICB1bml0dGVzdDo6VGVzdE1hcCBtZXNzYWdlOworICBNYXBUZXN0VXRpbDo6U2V0TWFwRmllbGRzKCZtZXNzYWdlKTsKKyAgTWFwVGVzdFV0aWw6OkV4cGVjdE1hcEZpZWxkc1NldChtZXNzYWdlKTsKKworICBNYXBSZWZsZWN0aW9uVGVzdGVyIHJlZmxlY3Rpb25fdGVzdGVyKAorICAgICAgdW5pdHRlc3Q6OlRlc3RNYXA6OmRlc2NyaXB0b3IoKSk7CisgIHJlZmxlY3Rpb25fdGVzdGVyLkNsZWFyTWFwRmllbGRzVmlhUmVmbGVjdGlvbigmbWVzc2FnZSk7CisgIHJlZmxlY3Rpb25fdGVzdGVyLkV4cGVjdENsZWFyVmlhUmVmbGVjdGlvbihtZXNzYWdlKTsKKyAgcmVmbGVjdGlvbl90ZXN0ZXIuRXhwZWN0Q2xlYXJWaWFSZWZsZWN0aW9uSXRlcmF0b3IoJm1lc3NhZ2UpOworfQorCitURVNUKEdlbmVyYXRlZE1hcEZpZWxkUmVmbGVjdGlvblRlc3QsIFJlbW92ZUxhc3QpIHsKKyAgdW5pdHRlc3Q6OlRlc3RNYXAgbWVzc2FnZTsKKyAgTWFwUmVmbGVjdGlvblRlc3RlciByZWZsZWN0aW9uX3Rlc3RlcigKKyAgICAgIHVuaXR0ZXN0OjpUZXN0TWFwOjpkZXNjcmlwdG9yKCkpOworCisgIE1hcFRlc3RVdGlsOjpTZXRNYXBGaWVsZHMoJm1lc3NhZ2UpOworICBNYXBUZXN0VXRpbDo6RXhwZWN0TWFwc1NpemUobWVzc2FnZSwgMik7CisgIHN0ZDo6dmVjdG9yPGNvbnN0IE1lc3NhZ2UqPiBleHBlY3RlZF9lbnRyaWVzID0KKyAgICAgIE1hcFRlc3RVdGlsOjpHZXRNYXBFbnRyaWVzKG1lc3NhZ2UsIDApOworCisgIHJlZmxlY3Rpb25fdGVzdGVyLlJlbW92ZUxhc3RNYXBzVmlhUmVmbGVjdGlvbigmbWVzc2FnZSk7CisKKyAgTWFwVGVzdFV0aWw6OkV4cGVjdE1hcHNTaXplKG1lc3NhZ2UsIDEpOworICBzdGQ6OnZlY3Rvcjxjb25zdCBNZXNzYWdlKj4gcmVtYWluZWRfZW50cmllcyA9CisgICAgICBNYXBUZXN0VXRpbDo6R2V0TWFwRW50cmllcyhtZXNzYWdlLCAwKTsKKyAgRVhQRUNUX1RSVUUoZXhwZWN0ZWRfZW50cmllcyA9PSByZW1haW5lZF9lbnRyaWVzKTsKK30KKworVEVTVChHZW5lcmF0ZWRNYXBGaWVsZFJlZmxlY3Rpb25UZXN0LCBSZWxlYXNlTGFzdCkgeworICB1bml0dGVzdDo6VGVzdE1hcCBtZXNzYWdlOworICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yID0gbWVzc2FnZS5HZXREZXNjcmlwdG9yKCk7CisgIE1hcFJlZmxlY3Rpb25UZXN0ZXIgcmVmbGVjdGlvbl90ZXN0ZXIoZGVzY3JpcHRvcik7CisKKyAgTWFwVGVzdFV0aWw6OlNldE1hcEZpZWxkcygmbWVzc2FnZSk7CisKKyAgTWFwVGVzdFV0aWw6OkV4cGVjdE1hcHNTaXplKG1lc3NhZ2UsIDIpOworCisgIHJlZmxlY3Rpb25fdGVzdGVyLlJlbGVhc2VMYXN0TWFwc1ZpYVJlZmxlY3Rpb24oJm1lc3NhZ2UpOworCisgIE1hcFRlc3RVdGlsOjpFeHBlY3RNYXBzU2l6ZShtZXNzYWdlLCAxKTsKKworICAvLyBOb3cgdGVzdCB0aGF0IHdlIGFjdHVhbGx5IHJlbGVhc2UgdGhlIHJpZ2h0IG1lc3NhZ2UuCisgIG1lc3NhZ2UuQ2xlYXIoKTsKKyAgTWFwVGVzdFV0aWw6OlNldE1hcEZpZWxkcygmbWVzc2FnZSk7CisKKyAgTWFwVGVzdFV0aWw6OkV4cGVjdE1hcHNTaXplKG1lc3NhZ2UsIDIpOworICBzdGQ6OnZlY3Rvcjxjb25zdCBNZXNzYWdlKj4gZXhwZWN0X2xhc3QgPQorICAgICAgTWFwVGVzdFV0aWw6OkdldE1hcEVudHJpZXMobWVzc2FnZSwgMSk7CisgIHN0ZDo6dmVjdG9yPGNvbnN0IE1lc3NhZ2UqPiByZWxlYXNlX2xhc3QgPQorICAgICAgTWFwVGVzdFV0aWw6OkdldE1hcEVudHJpZXNGcm9tUmVsZWFzZSgmbWVzc2FnZSk7CisgIE1hcFRlc3RVdGlsOjpFeHBlY3RNYXBzU2l6ZShtZXNzYWdlLCAxKTsKKyAgRVhQRUNUX1RSVUUoZXhwZWN0X2xhc3QgPT0gcmVsZWFzZV9sYXN0KTsKKyAgZm9yIChzdGQ6OnZlY3Rvcjxjb25zdCBNZXNzYWdlKj46Oml0ZXJhdG9yIGl0ID0gcmVsZWFzZV9sYXN0LmJlZ2luKCk7CisgICAgICAgaXQgIT0gcmVsZWFzZV9sYXN0LmVuZCgpOyArK2l0KSB7CisgICAgZGVsZXRlICppdDsKKyAgfQorfQorCitURVNUKEdlbmVyYXRlZE1hcEZpZWxkUmVmbGVjdGlvblRlc3QsIFN3YXBFbGVtZW50cykgeworICB1bml0dGVzdDo6VGVzdE1hcCBtZXNzYWdlOworICBNYXBSZWZsZWN0aW9uVGVzdGVyIHJlZmxlY3Rpb25fdGVzdGVyKAorICAgIHVuaXR0ZXN0OjpUZXN0TWFwOjpkZXNjcmlwdG9yKCkpOworCisgIE1hcFRlc3RVdGlsOjpTZXRNYXBGaWVsZHMoJm1lc3NhZ2UpOworCisgIC8vIEdldCBwb2ludGVycyBvZiBtYXAgZW50cmllcyBhdCB0aGVpciBvcmlnaW5hbCBwb3NpdGlvbgorICBzdGQ6OnZlY3Rvcjxjb25zdCBNZXNzYWdlKj4gZW50cmllczAgPSBNYXBUZXN0VXRpbDo6R2V0TWFwRW50cmllcyhtZXNzYWdlLCAwKTsKKyAgc3RkOjp2ZWN0b3I8Y29uc3QgTWVzc2FnZSo+IGVudHJpZXMxID0gTWFwVGVzdFV0aWw6OkdldE1hcEVudHJpZXMobWVzc2FnZSwgMSk7CisKKyAgLy8gU3dhcCB0aGUgZmlyc3QgdGltZS4KKyAgcmVmbGVjdGlvbl90ZXN0ZXIuU3dhcE1hcHNWaWFSZWZsZWN0aW9uKCZtZXNzYWdlKTsKKworICAvLyBHZXQgcG9pbnRlciBvZiBtYXAgZW50cnkgYWZ0ZXIgc3dhcCBvbmNlLgorICBzdGQ6OnZlY3Rvcjxjb25zdCBNZXNzYWdlKj4gZW50cmllczBfb25jZSA9CisgICAgICBNYXBUZXN0VXRpbDo6R2V0TWFwRW50cmllcyhtZXNzYWdlLCAwKTsKKyAgc3RkOjp2ZWN0b3I8Y29uc3QgTWVzc2FnZSo+IGVudHJpZXMxX29uY2UgPQorICAgICAgTWFwVGVzdFV0aWw6OkdldE1hcEVudHJpZXMobWVzc2FnZSwgMSk7CisKKyAgLy8gVGVzdCBtYXAgZW50cmllcyBhcmUgc3dhcHBlZC4KKyAgTWFwVGVzdFV0aWw6OkV4cGVjdE1hcHNTaXplKG1lc3NhZ2UsIDIpOworICBFWFBFQ1RfVFJVRShlbnRyaWVzMCA9PSBlbnRyaWVzMV9vbmNlKTsKKyAgRVhQRUNUX1RSVUUoZW50cmllczEgPT0gZW50cmllczBfb25jZSk7CisKKyAgLy8gU3dhcCB0aGUgc2Vjb25kIHRpbWUuCisgIHJlZmxlY3Rpb25fdGVzdGVyLlN3YXBNYXBzVmlhUmVmbGVjdGlvbigmbWVzc2FnZSk7CisKKyAgLy8gR2V0IHBvaW50ZXIgb2YgbWFwIGVudHJ5IGFmdGVyIHN3YXAgb25jZS4KKyAgc3RkOjp2ZWN0b3I8Y29uc3QgTWVzc2FnZSo+IGVudHJpZXMwX3R3aWNlID0KKyAgICAgIE1hcFRlc3RVdGlsOjpHZXRNYXBFbnRyaWVzKG1lc3NhZ2UsIDApOworICBzdGQ6OnZlY3Rvcjxjb25zdCBNZXNzYWdlKj4gZW50cmllczFfdHdpY2UgPQorICAgICAgTWFwVGVzdFV0aWw6OkdldE1hcEVudHJpZXMobWVzc2FnZSwgMSk7CisKKyAgLy8gVGVzdCBtYXAgZW50cmllcyBhcmUgc3dhcHBlZCBiYWNrLgorICBNYXBUZXN0VXRpbDo6RXhwZWN0TWFwc1NpemUobWVzc2FnZSwgMik7CisgIEVYUEVDVF9UUlVFKGVudHJpZXMwID09IGVudHJpZXMwX3R3aWNlKTsKKyAgRVhQRUNUX1RSVUUoZW50cmllczEgPT0gZW50cmllczFfdHdpY2UpOworfQorCitURVNUKEdlbmVyYXRlZE1hcEZpZWxkUmVmbGVjdGlvblRlc3QsIE11dGFibGVVbmtub3duRmllbGRzKSB7CisgIHVuaXR0ZXN0OjpUZXN0TWFwIG1lc3NhZ2U7CisgIE1hcFJlZmxlY3Rpb25UZXN0ZXIgcmVmbGVjdGlvbl90ZXN0ZXIoCisgICAgdW5pdHRlc3Q6OlRlc3RNYXA6OmRlc2NyaXB0b3IoKSk7CisgIHJlZmxlY3Rpb25fdGVzdGVyLk11dGFibGVVbmtub3duRmllbGRzT2ZNYXBGaWVsZHNWaWFSZWZsZWN0aW9uKCZtZXNzYWdlKTsKK30KKworVEVTVChHZW5lcmF0ZWRNYXBGaWVsZFJlZmxlY3Rpb25UZXN0LCBFbWJlZFByb3RvMk1lc3NhZ2UpIHsKKyAgdW5pdHRlc3Q6OlRlc3RNZXNzYWdlTWFwIG1lc3NhZ2U7CisKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBtYXBfZmllbGQgPQorICAgICAgdW5pdHRlc3Q6OlRlc3RNZXNzYWdlTWFwOjpkZXNjcmlwdG9yKCktPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICAgICAibWFwX2ludDMyX21lc3NhZ2UiKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiB2YWx1ZSA9CisgICAgICBtYXBfZmllbGQtPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoInZhbHVlIik7CisKKyAgTWVzc2FnZSogZW50cnlfbWVzc2FnZSA9CisgICAgICBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+QWRkTWVzc2FnZSgmbWVzc2FnZSwgbWFwX2ZpZWxkKTsKKyAgRVhQRUNUX0VRKAorICAgICAgJmVudHJ5X21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0TWVzc2FnZSgqZW50cnlfbWVzc2FnZSwgdmFsdWUpLAorICAgICAgcmVpbnRlcnByZXRfY2FzdDxjb25zdCBNZXNzYWdlKj4oJlRlc3RBbGxUeXBlczo6ZGVmYXVsdF9pbnN0YW5jZSgpKSk7CisKKyAgTWVzc2FnZSogcHJvdG8yX21lc3NhZ2UgPQorICAgICAgZW50cnlfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5NdXRhYmxlTWVzc2FnZShlbnRyeV9tZXNzYWdlLCB2YWx1ZSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpkZXNjcmlwdG9yKCksCisgICAgICAgICAgICBwcm90bzJfbWVzc2FnZS0+R2V0RGVzY3JpcHRvcigpKTsKKyAgQVNTRVJUX0VRKDEsIG1lc3NhZ2UubWFwX2ludDMyX21lc3NhZ2UoKS5zaXplKCkpOworfQorCitURVNUKEdlbmVyYXRlZE1hcEZpZWxkUmVmbGVjdGlvblRlc3QsIE1lcmdlRnJvbUNsZWFyTWFwRW50cnkpIHsKKyAgdW5pdHRlc3Q6OlRlc3RNYXAgbWVzc2FnZTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBtYXBfZmllbGQgPQorICAgICAgdW5pdHRlc3Q6OlRlc3RNYXA6OmRlc2NyaXB0b3IoKS0+RmluZEZpZWxkQnlOYW1lKCJtYXBfaW50MzJfaW50MzIiKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBrZXkgPQorICAgICAgbWFwX2ZpZWxkLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJrZXkiKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiB2YWx1ZSA9CisgICAgICBtYXBfZmllbGQtPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoInZhbHVlIik7CisKKyAgTWVzc2FnZSogZW50cnlfbWVzc2FnZTEgPQorICAgICAgbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPkFkZE1lc3NhZ2UoJm1lc3NhZ2UsIG1hcF9maWVsZCk7CisgIEVYUEVDVF9GQUxTRShlbnRyeV9tZXNzYWdlMS0+R2V0UmVmbGVjdGlvbigpLT5IYXNGaWVsZCgqZW50cnlfbWVzc2FnZTEsIGtleSkpOworICBFWFBFQ1RfRkFMU0UoCisgICAgICBlbnRyeV9tZXNzYWdlMS0+R2V0UmVmbGVjdGlvbigpLT5IYXNGaWVsZCgqZW50cnlfbWVzc2FnZTEsIHZhbHVlKSk7CisKKyAgTWVzc2FnZSogZW50cnlfbWVzc2FnZTIgPQorICAgICAgbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPkFkZE1lc3NhZ2UoJm1lc3NhZ2UsIG1hcF9maWVsZCk7CisgIEVYUEVDVF9GQUxTRShlbnRyeV9tZXNzYWdlMi0+R2V0UmVmbGVjdGlvbigpLT5IYXNGaWVsZCgqZW50cnlfbWVzc2FnZTIsIGtleSkpOworICBFWFBFQ1RfRkFMU0UoCisgICAgICBlbnRyeV9tZXNzYWdlMi0+R2V0UmVmbGVjdGlvbigpLT5IYXNGaWVsZCgqZW50cnlfbWVzc2FnZTIsIHZhbHVlKSk7CisKKyAgZW50cnlfbWVzc2FnZTEtPk1lcmdlRnJvbSgqZW50cnlfbWVzc2FnZTIpOworICBFWFBFQ1RfRkFMU0UoZW50cnlfbWVzc2FnZTEtPkdldFJlZmxlY3Rpb24oKS0+SGFzRmllbGQoKmVudHJ5X21lc3NhZ2UxLCBrZXkpKTsKKyAgRVhQRUNUX0ZBTFNFKAorICAgICAgZW50cnlfbWVzc2FnZTEtPkdldFJlZmxlY3Rpb24oKS0+SGFzRmllbGQoKmVudHJ5X21lc3NhZ2UxLCB2YWx1ZSkpOworfQorCitURVNUKEdlbmVyYXRlZE1hcEZpZWxkUmVmbGVjdGlvblRlc3QsIE1hcEVudHJ5Q2xlYXIpIHsKKyAgdW5pdHRlc3Q6OlRlc3RNYXAgbWVzc2FnZTsKKyAgTWFwUmVmbGVjdGlvblRlc3RlciByZWZsZWN0aW9uX3Rlc3RlcigKKyAgICB1bml0dGVzdDo6VGVzdE1hcDo6ZGVzY3JpcHRvcigpKTsKKyAgcmVmbGVjdGlvbl90ZXN0ZXIuTXV0YWJsZVVua25vd25GaWVsZHNPZk1hcEZpZWxkc1ZpYVJlZmxlY3Rpb24oJm1lc3NhZ2UpOworfQorCitURVNUKEdlbmVyYXRlZE1hcEZpZWxkUmVmbGVjdGlvblRlc3QsIFByb3RvMk1hcEVudHJ5Q2xlYXIpIHsKKyAgdW5pdHRlc3Q6OlRlc3RFbnVtTWFwIG1lc3NhZ2U7CisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBtZXNzYWdlLkdldERlc2NyaXB0b3IoKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZF9kZXNjcmlwdG9yID0KKyAgICAgIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgia25vd25fbWFwX2ZpZWxkIik7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogdmFsdWVfZGVzY3JpcHRvciA9CisgICAgICBmaWVsZF9kZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJ2YWx1ZSIpOworICBNZXNzYWdlKiBzdWJfbWVzc2FnZSA9CisgICAgICBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+QWRkTWVzc2FnZSgmbWVzc2FnZSwgZmllbGRfZGVzY3JpcHRvcik7CisgIEVYUEVDVF9FUSgwLCBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRFbnVtVmFsdWUoKnN1Yl9tZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlX2Rlc2NyaXB0b3IpKTsKK30KKworLy8gTWFwIFJlZmxlY3Rpb24gQVBJIFRlc3QgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworVEVTVChHZW5lcmF0ZWRNYXBGaWVsZFJlZmxlY3Rpb25UZXN0LCBTZXRWaWFNYXBSZWZsZWN0aW9uKSB7CisgIHVuaXR0ZXN0OjpUZXN0TWFwIG1lc3NhZ2U7CisgIE1hcFJlZmxlY3Rpb25UZXN0ZXIgcmVmbGVjdGlvbl90ZXN0ZXIoCisgICAgICB1bml0dGVzdDo6VGVzdE1hcDo6ZGVzY3JpcHRvcigpKTsKKyAgcmVmbGVjdGlvbl90ZXN0ZXIuU2V0TWFwRmllbGRzVmlhTWFwUmVmbGVjdGlvbigmbWVzc2FnZSk7CisgIHJlZmxlY3Rpb25fdGVzdGVyLkV4cGVjdE1hcEZpZWxkc1NldFZpYVJlZmxlY3Rpb24obWVzc2FnZSk7CisgIHJlZmxlY3Rpb25fdGVzdGVyLkV4cGVjdE1hcEZpZWxkc1NldFZpYVJlZmxlY3Rpb25JdGVyYXRvcigmbWVzc2FnZSk7Cit9CisKKy8vIER5bmFtaWMgTWVzc2FnZSBUZXN0ID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitjbGFzcyBNYXBGaWVsZEluRHluYW1pY01lc3NhZ2VUZXN0IDogcHVibGljIHRlc3Rpbmc6OlRlc3QgeworIHByb3RlY3RlZDoKKyAgY29uc3QgRGVzY3JpcHRvclBvb2wqIHBvb2xfOworICBEeW5hbWljTWVzc2FnZUZhY3RvcnkgZmFjdG9yeV87CisgIGNvbnN0IERlc2NyaXB0b3IqIG1hcF9kZXNjcmlwdG9yXzsKKyAgY29uc3QgRGVzY3JpcHRvciogcmVjdXJzaXZlX21hcF9kZXNjcmlwdG9yXzsKKyAgY29uc3QgTWVzc2FnZSogbWFwX3Byb3RvdHlwZV87CisKKyAgTWFwRmllbGRJbkR5bmFtaWNNZXNzYWdlVGVzdCgpCisgICAgICA6IHBvb2xfKERlc2NyaXB0b3JQb29sOjpnZW5lcmF0ZWRfcG9vbCgpKSwgZmFjdG9yeV8ocG9vbF8pIHt9CisKKyAgdmlydHVhbCB2b2lkIFNldFVwKCkgeworICAgIG1hcF9kZXNjcmlwdG9yXyA9CisgICAgICBwb29sXy0+RmluZE1lc3NhZ2VUeXBlQnlOYW1lKCJwcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwIik7CisgICAgcmVjdXJzaXZlX21hcF9kZXNjcmlwdG9yXyA9CisgICAgICAgIHBvb2xfLT5GaW5kTWVzc2FnZVR5cGVCeU5hbWUoInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlIik7CisgICAgQVNTRVJUX1RSVUUobWFwX2Rlc2NyaXB0b3JfICE9IE5VTEwpOworICAgIEFTU0VSVF9UUlVFKHJlY3Vyc2l2ZV9tYXBfZGVzY3JpcHRvcl8gIT0gTlVMTCk7CisgICAgbWFwX3Byb3RvdHlwZV8gPSBmYWN0b3J5Xy5HZXRQcm90b3R5cGUobWFwX2Rlc2NyaXB0b3JfKTsKKyAgfQorfTsKKworVEVTVF9GKE1hcEZpZWxkSW5EeW5hbWljTWVzc2FnZVRlc3QsIE1hcEluZGVwZW5kZW50T2Zmc2V0cykgeworICAvLyBDaGVjayB0aGF0IGFsbCBmaWVsZHMgaGF2ZSBpbmRlcGVuZGVudCBvZmZzZXRzIGJ5IHNldHRpbmcgZWFjaAorICAvLyBvbmUgdG8gYSB1bmlxdWUgdmFsdWUgdGhlbiBjaGVja2luZyB0aGF0IHRoZXkgYWxsIHN0aWxsIGhhdmUgdGhvc2UKKyAgLy8gdW5pcXVlIHZhbHVlcyAoaS5lLiB0aGV5IGRvbid0IHN0b21wIGVhY2ggb3RoZXIpLgorICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPE1lc3NhZ2U+IG1lc3NhZ2UobWFwX3Byb3RvdHlwZV8tPk5ldygpKTsKKyAgTWFwUmVmbGVjdGlvblRlc3RlciByZWZsZWN0aW9uX3Rlc3RlcihtYXBfZGVzY3JpcHRvcl8pOworCisgIHJlZmxlY3Rpb25fdGVzdGVyLlNldE1hcEZpZWxkc1ZpYVJlZmxlY3Rpb24obWVzc2FnZS5nZXQoKSk7CisgIHJlZmxlY3Rpb25fdGVzdGVyLkV4cGVjdE1hcEZpZWxkc1NldFZpYVJlZmxlY3Rpb24oKm1lc3NhZ2UpOworfQorCitURVNUX0YoTWFwRmllbGRJbkR5bmFtaWNNZXNzYWdlVGVzdCwgRHluYW1pY01hcFJlZmxlY3Rpb24pIHsKKyAgLy8gQ2hlY2sgdGhhdCBtYXAgZmllbGRzIHdvcmsgcHJvcGVybHkuCisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8TWVzc2FnZT4gbWVzc2FnZShtYXBfcHJvdG90eXBlXy0+TmV3KCkpOworCisgIC8vIENoZWNrIHNldCBmdW5jdGlvbnMuCisgIE1hcFJlZmxlY3Rpb25UZXN0ZXIgcmVmbGVjdGlvbl90ZXN0ZXIobWFwX2Rlc2NyaXB0b3JfKTsKKyAgcmVmbGVjdGlvbl90ZXN0ZXIuU2V0TWFwRmllbGRzVmlhTWFwUmVmbGVjdGlvbihtZXNzYWdlLmdldCgpKTsKKyAgcmVmbGVjdGlvbl90ZXN0ZXIuRXhwZWN0TWFwRmllbGRzU2V0VmlhUmVmbGVjdGlvbigqbWVzc2FnZSk7Cit9CisKK1RFU1RfRihNYXBGaWVsZEluRHluYW1pY01lc3NhZ2VUZXN0LCBNYXBTcGFjZVVzZWQpIHsKKyAgLy8gVGVzdCB0aGF0IFNwYWNlVXNlZCgpIHdvcmtzIHByb3Blcmx5CisKKyAgLy8gU2luY2Ugd2Ugc2hhcmUgdGhlIGltcGxlbWVudGF0aW9uIHdpdGggZ2VuZXJhdGVkIG1lc3NhZ2VzLCB3ZSBkb24ndCBuZWVkCisgIC8vIHRvIHRlc3QgdmVyeSBtdWNoIGhlcmUuICBKdXN0IG1ha2Ugc3VyZSBpdCBhcHBlYXJzIHRvIGJlIHdvcmtpbmcuCisKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxNZXNzYWdlPiBtZXNzYWdlKG1hcF9wcm90b3R5cGVfLT5OZXcoKSk7CisgIE1hcFJlZmxlY3Rpb25UZXN0ZXIgcmVmbGVjdGlvbl90ZXN0ZXIobWFwX2Rlc2NyaXB0b3JfKTsKKworICBpbnQgaW5pdGlhbF9zcGFjZV91c2VkID0gbWVzc2FnZS0+U3BhY2VVc2VkKCk7CisKKyAgcmVmbGVjdGlvbl90ZXN0ZXIuU2V0TWFwRmllbGRzVmlhUmVmbGVjdGlvbihtZXNzYWdlLmdldCgpKTsKKyAgRVhQRUNUX0xUKGluaXRpYWxfc3BhY2VfdXNlZCwgbWVzc2FnZS0+U3BhY2VVc2VkKCkpOworfQorCitURVNUX0YoTWFwRmllbGRJbkR5bmFtaWNNZXNzYWdlVGVzdCwgUmVjdXJzaXZlTWFwKSB7CisgIFRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlIGZyb207CisgICgqZnJvbS5tdXRhYmxlX2EoKSlbIiJdOworICBzdHJpbmcgZGF0YSA9IGZyb20uU2VyaWFsaXplQXNTdHJpbmcoKTsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxNZXNzYWdlPiB0bygKKyAgICAgIGZhY3RvcnlfLkdldFByb3RvdHlwZShyZWN1cnNpdmVfbWFwX2Rlc2NyaXB0b3JfKS0+TmV3KCkpOworICBBU1NFUlRfVFJVRSh0by0+UGFyc2VGcm9tU3RyaW5nKGRhdGEpKTsKK30KKworLy8gUmVmbGVjdGlvbk9wcyBUZXN0ID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK1RFU1QoUmVmbGVjdGlvbk9wc0Zvck1hcEZpZWxkVGVzdCwgTWFwU2FuaXR5Q2hlY2spIHsKKyAgdW5pdHRlc3Q6OlRlc3RNYXAgbWVzc2FnZTsKKworICBNYXBUZXN0VXRpbDo6U2V0TWFwRmllbGRzKCZtZXNzYWdlKTsKKyAgTWFwVGVzdFV0aWw6OkV4cGVjdE1hcEZpZWxkc1NldChtZXNzYWdlKTsKK30KKworVEVTVChSZWZsZWN0aW9uT3BzRm9yTWFwRmllbGRUZXN0LCBNYXBDb3B5KSB7CisgIHVuaXR0ZXN0OjpUZXN0TWFwIG1lc3NhZ2UsIG1lc3NhZ2UyOworCisgIE1hcFRlc3RVdGlsOjpTZXRNYXBGaWVsZHMoJm1lc3NhZ2UpOworCisgIFJlZmxlY3Rpb25PcHM6OkNvcHkobWVzc2FnZSwgJm1lc3NhZ2UyKTsKKworICBNYXBUZXN0VXRpbDo6RXhwZWN0TWFwRmllbGRzU2V0KG1lc3NhZ2UyKTsKKworICAvLyBDb3B5aW5nIGZyb20gc2VsZiBzaG91bGQgYmUgYSBuby1vcC4KKyAgUmVmbGVjdGlvbk9wczo6Q29weShtZXNzYWdlMiwgJm1lc3NhZ2UyKTsKKyAgTWFwVGVzdFV0aWw6OkV4cGVjdE1hcEZpZWxkc1NldChtZXNzYWdlMik7Cit9CisKK1RFU1QoUmVmbGVjdGlvbk9wc0Zvck1hcEZpZWxkVGVzdCwgTWVyZ2VNYXApIHsKKyAgLy8gTm90ZTogIENvcHkgaXMgaW1wbGVtZW50ZWQgaW4gdGVybXMgb2YgTWVyZ2UoKSBzbyB0ZWNobmljYWxseSB0aGUgQ29weQorICAvLyAgIHRlc3QgYWxyZWFkeSB0ZXN0ZWQgbW9zdCBvZiB0aGlzLgorCisgIHVuaXR0ZXN0OjpUZXN0TWFwIG1lc3NhZ2UsIG1lc3NhZ2UyOworCisgIE1hcFRlc3RVdGlsOjpTZXRNYXBGaWVsZHMoJm1lc3NhZ2UpOworCisgIFJlZmxlY3Rpb25PcHM6Ok1lcmdlKG1lc3NhZ2UyLCAmbWVzc2FnZSk7CisKKyAgTWFwVGVzdFV0aWw6OkV4cGVjdE1hcEZpZWxkc1NldChtZXNzYWdlKTsKK30KKworVEVTVChSZWZsZWN0aW9uT3BzRm9yTWFwRmllbGRUZXN0LCBDbGVhck1hcCkgeworICB1bml0dGVzdDo6VGVzdE1hcCBtZXNzYWdlOworCisgIE1hcFRlc3RVdGlsOjpTZXRNYXBGaWVsZHMoJm1lc3NhZ2UpOworCisgIFJlZmxlY3Rpb25PcHM6OkNsZWFyKCZtZXNzYWdlKTsKKworICBNYXBUZXN0VXRpbDo6RXhwZWN0Q2xlYXIobWVzc2FnZSk7Cit9CisKK1RFU1QoUmVmbGVjdGlvbk9wc0Zvck1hcEZpZWxkVGVzdCwgTWFwRGlzY2FyZFVua25vd25GaWVsZHMpIHsKKyAgdW5pdHRlc3Q6OlRlc3RNYXAgbWVzc2FnZTsKKyAgTWFwVGVzdFV0aWw6OlNldE1hcEZpZWxkcygmbWVzc2FnZSk7CisKKyAgLy8gU2V0IHNvbWUgdW5rbm93biBmaWVsZHMgaW4gbWVzc2FnZS4KKyAgbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPk11dGFibGVVbmtub3duRmllbGRzKCZtZXNzYWdlKS0+CisgICAgICBBZGRWYXJpbnQoMTIzNDU2LCA2NTQzMjEpOworCisgIC8vIERpc2NhcmQgdGhlbS4KKyAgUmVmbGVjdGlvbk9wczo6RGlzY2FyZFVua25vd25GaWVsZHMoJm1lc3NhZ2UpOworICBNYXBUZXN0VXRpbDo6RXhwZWN0TWFwRmllbGRzU2V0KG1lc3NhZ2UpOworCisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+CisgICAgICBHZXRVbmtub3duRmllbGRzKG1lc3NhZ2UpLmZpZWxkX2NvdW50KCkpOworfQorCisvLyBXaXJlIEZvcm1hdCBUZXN0ID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworVEVTVChXaXJlRm9ybWF0Rm9yTWFwRmllbGRUZXN0LCBQYXJzZU1hcCkgeworICB1bml0dGVzdDo6VGVzdE1hcCBzb3VyY2UsIGRlc3Q7CisgIHN0cmluZyBkYXRhOworCisgIC8vIFNlcmlhbGl6ZSB1c2luZyB0aGUgZ2VuZXJhdGVkIGNvZGUuCisgIE1hcFRlc3RVdGlsOjpTZXRNYXBGaWVsZHMoJnNvdXJjZSk7CisgIHNvdXJjZS5TZXJpYWxpemVUb1N0cmluZygmZGF0YSk7CisKKyAgLy8gUGFyc2UgdXNpbmcgV2lyZUZvcm1hdC4KKyAgaW86OkFycmF5SW5wdXRTdHJlYW0gcmF3X2lucHV0KGRhdGEuZGF0YSgpLCBkYXRhLnNpemUoKSk7CisgIGlvOjpDb2RlZElucHV0U3RyZWFtIGlucHV0KCZyYXdfaW5wdXQpOworICBXaXJlRm9ybWF0OjpQYXJzZUFuZE1lcmdlUGFydGlhbCgmaW5wdXQsICZkZXN0KTsKKworICAvLyBDaGVjay4KKyAgTWFwVGVzdFV0aWw6OkV4cGVjdE1hcEZpZWxkc1NldChkZXN0KTsKK30KKworVEVTVChXaXJlRm9ybWF0Rm9yTWFwRmllbGRUZXN0LCBNYXBCeXRlU2l6ZSkgeworICB1bml0dGVzdDo6VGVzdE1hcCBtZXNzYWdlOworICBNYXBUZXN0VXRpbDo6U2V0TWFwRmllbGRzKCZtZXNzYWdlKTsKKworICBFWFBFQ1RfRVEobWVzc2FnZS5CeXRlU2l6ZSgpLCBXaXJlRm9ybWF0OjpCeXRlU2l6ZShtZXNzYWdlKSk7CisgIG1lc3NhZ2UuQ2xlYXIoKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuQnl0ZVNpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBXaXJlRm9ybWF0OjpCeXRlU2l6ZShtZXNzYWdlKSk7Cit9CisKK1RFU1QoV2lyZUZvcm1hdEZvck1hcEZpZWxkVGVzdCwgU2VyaWFsaXplTWFwKSB7CisgIHVuaXR0ZXN0OjpUZXN0TWFwIG1lc3NhZ2U7CisgIHN0cmluZyBnZW5lcmF0ZWRfZGF0YTsKKyAgc3RyaW5nIGR5bmFtaWNfZGF0YTsKKworICBNYXBUZXN0VXRpbDo6U2V0TWFwRmllbGRzKCZtZXNzYWdlKTsKKworICAvLyBTZXJpYWxpemUgdXNpbmcgdGhlIGdlbmVyYXRlZCBjb2RlLgorICB7CisgICAgbWVzc2FnZS5CeXRlU2l6ZSgpOworICAgIGlvOjpTdHJpbmdPdXRwdXRTdHJlYW0gcmF3X291dHB1dCgmZ2VuZXJhdGVkX2RhdGEpOworICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSBvdXRwdXQoJnJhd19vdXRwdXQpOworICAgIG1lc3NhZ2UuU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKCZvdXRwdXQpOworICAgIEFTU0VSVF9GQUxTRShvdXRwdXQuSGFkRXJyb3IoKSk7CisgIH0KKworICAvLyBTZXJpYWxpemUgdXNpbmcgV2lyZUZvcm1hdC4KKyAgeworICAgIGlvOjpTdHJpbmdPdXRwdXRTdHJlYW0gcmF3X291dHB1dCgmZHluYW1pY19kYXRhKTsKKyAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KCZyYXdfb3V0cHV0KTsKKyAgICBpbnQgc2l6ZSA9IFdpcmVGb3JtYXQ6OkJ5dGVTaXplKG1lc3NhZ2UpOworICAgIFdpcmVGb3JtYXQ6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcyhtZXNzYWdlLCBzaXplLCAmb3V0cHV0KTsKKyAgICBBU1NFUlRfRkFMU0Uob3V0cHV0LkhhZEVycm9yKCkpOworICB9CisKKyAgLy8gU2hvdWxkIGJlIHRoZSBzYW1lLgorICAvLyBEb24ndCB1c2UgRVhQRUNUX0VRIGhlcmUgYmVjYXVzZSB3ZSdyZSBjb21wYXJpbmcgcmF3IGJpbmFyeSBkYXRhIGFuZAorICAvLyB3ZSByZWFsbHkgZG9uJ3Qgd2FudCBpdCBkdW1wZWQgdG8gc3Rkb3V0IG9uIGZhaWx1cmUuCisgIEVYUEVDVF9UUlVFKGR5bmFtaWNfZGF0YSA9PSBnZW5lcmF0ZWRfZGF0YSk7Cit9CisKK1RFU1QoV2lyZUZvcm1hdEZvck1hcEZpZWxkVGVzdCwgTWFwUGFyc2VIZWxwZXJzKSB7CisgIHN0cmluZyBkYXRhOworCisgIHsKKyAgICAvLyBTZXQgdXAuCisgICAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RNYXAgbWVzc2FnZTsKKyAgICBNYXBUZXN0VXRpbDo6U2V0TWFwRmllbGRzKCZtZXNzYWdlKTsKKyAgICBtZXNzYWdlLlNlcmlhbGl6ZVRvU3RyaW5nKCZkYXRhKTsKKyAgfQorCisgIHsKKyAgICAvLyBUZXN0IFBhcnNlRnJvbVN0cmluZy4KKyAgICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdE1hcCBtZXNzYWdlOworICAgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKGRhdGEpKTsKKyAgICBNYXBUZXN0VXRpbDo6RXhwZWN0TWFwRmllbGRzU2V0KG1lc3NhZ2UpOworICB9CisKKyAgeworICAgIC8vIFRlc3QgUGFyc2VGcm9tSXN0cmVhbS4KKyAgICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdE1hcCBtZXNzYWdlOworICAgIHN0cmluZ3N0cmVhbSBzdHJlYW0oZGF0YSk7CisgICAgRVhQRUNUX1RSVUUobWVzc2FnZS5QYXJzZUZyb21Jc3RyZWFtKCZzdHJlYW0pKTsKKyAgICBFWFBFQ1RfVFJVRShzdHJlYW0uZW9mKCkpOworICAgIE1hcFRlc3RVdGlsOjpFeHBlY3RNYXBGaWVsZHNTZXQobWVzc2FnZSk7CisgIH0KKworICB7CisgICAgLy8gVGVzdCBQYXJzZUZyb21Cb3VuZGVkWmVyb0NvcHlTdHJlYW0uCisgICAgc3RyaW5nIGRhdGFfd2l0aF9qdW5rKGRhdGEpOworICAgIGRhdGFfd2l0aF9qdW5rLmFwcGVuZCgic29tZSBqdW5rIG9uIHRoZSBlbmQiKTsKKyAgICBpbzo6QXJyYXlJbnB1dFN0cmVhbSBzdHJlYW0oZGF0YV93aXRoX2p1bmsuZGF0YSgpLCBkYXRhX3dpdGhfanVuay5zaXplKCkpOworICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0TWFwIG1lc3NhZ2U7CisgICAgRVhQRUNUX1RSVUUobWVzc2FnZS5QYXJzZUZyb21Cb3VuZGVkWmVyb0NvcHlTdHJlYW0oJnN0cmVhbSwgZGF0YS5zaXplKCkpKTsKKyAgICBNYXBUZXN0VXRpbDo6RXhwZWN0TWFwRmllbGRzU2V0KG1lc3NhZ2UpOworICB9CisKKyAgeworICAgIC8vIFRlc3QgdGhhdCBQYXJzZUZyb21Cb3VuZGVkWmVyb0NvcHlTdHJlYW0gZmFpbHMgKGJ1dCBkb2Vzbid0IGNyYXNoKSBpZgorICAgIC8vIEVPRiBpcyByZWFjaGVkIGJlZm9yZSB0aGUgZXhwZWN0ZWQgbnVtYmVyIG9mIGJ5dGVzLgorICAgIGlvOjpBcnJheUlucHV0U3RyZWFtIHN0cmVhbShkYXRhLmRhdGEoKSwgZGF0YS5zaXplKCkpOworICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKyAgICBFWFBFQ1RfRkFMU0UoCisgICAgICBtZXNzYWdlLlBhcnNlRnJvbUJvdW5kZWRaZXJvQ29weVN0cmVhbSgmc3RyZWFtLCBkYXRhLnNpemUoKSArIDEpKTsKKyAgfQorfQorCisvLyBUZXh0IEZvcm1hdCBUZXN0ID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworVEVTVChUZXh0Rm9ybWF0TWFwVGVzdCwgU2VyaWFsaXplQW5kUGFyc2UpIHsKKyAgdW5pdHRlc3Q6OlRlc3RNYXAgc291cmNlOworICB1bml0dGVzdDo6VGVzdE1hcCBkZXN0OworICBNYXBUZXN0VXRpbDo6U2V0TWFwRmllbGRzKCZzb3VyY2UpOworICBzdHJpbmcgb3V0cHV0OworCisgIC8vIFRlc3QgY29tcGFjdCBBU0NJSQorICBUZXh0Rm9ybWF0OjpQcmludGVyIHByaW50ZXI7CisgIHByaW50ZXIuUHJpbnRUb1N0cmluZyhzb3VyY2UsICZvdXRwdXQpOworICBUZXh0Rm9ybWF0OjpQYXJzZXIgcGFyc2VyOworICBFWFBFQ1RfVFJVRShwYXJzZXIuUGFyc2VGcm9tU3RyaW5nKG91dHB1dCwgJmRlc3QpKTsKKyAgTWFwVGVzdFV0aWw6OkV4cGVjdE1hcEZpZWxkc1NldChkZXN0KTsKK30KKworVEVTVChUZXh0Rm9ybWF0TWFwVGVzdCwgU29ydGVkKSB7CisgIHVuaXR0ZXN0OjpUZXN0TWFwIG1lc3NhZ2U7CisgIE1hcFJlZmxlY3Rpb25UZXN0ZXIgdGVzdGVyKG1lc3NhZ2UuR2V0RGVzY3JpcHRvcigpKTsKKyAgdGVzdGVyLlNldE1hcEZpZWxkc1ZpYVJlZmxlY3Rpb24oJm1lc3NhZ2UpOworCisgIHN0cmluZyBleHBlY3RlZF90ZXh0OworICBHT09HTEVfQ0hFQ0tfT0soRmlsZTo6R2V0Q29udGVudHMoCisgICAgICBUZXN0U291cmNlRGlyKCkgKworICAgICAgICAgICIvZ29vZ2xlL3Byb3RvYnVmLyIKKyAgICAgICAgICAidGVzdGRhdGEvbWFwX3Rlc3RfZGF0YS50eHQiLAorICAgICAgJmV4cGVjdGVkX3RleHQsIHRydWUpKTsKKworICBFWFBFQ1RfRVEobWVzc2FnZS5EZWJ1Z1N0cmluZygpLCBleHBlY3RlZF90ZXh0KTsKKworICAvLyBUZXN0IGFnYWluIG9uIHRoZSByZXZlcnNlIG9yZGVyLgorICB1bml0dGVzdDo6VGVzdE1hcCBtZXNzYWdlMjsKKyAgdGVzdGVyLlNldE1hcEZpZWxkc1ZpYVJlZmxlY3Rpb24oJm1lc3NhZ2UyKTsKKyAgdGVzdGVyLlN3YXBNYXBzVmlhUmVmbGVjdGlvbigmbWVzc2FnZTIpOworICBFWFBFQ1RfRVEobWVzc2FnZTIuRGVidWdTdHJpbmcoKSwgZXhwZWN0ZWRfdGV4dCk7Cit9CisKKworLy8gYXJlbmEgc3VwcG9ydCA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CitURVNUKEFyZW5hVGVzdCwgUGFyc2luZ0FuZFNlcmlhbGl6aW5nTm9IZWFwQWxsb2NhdGlvbikgeworICAvLyBBbGxvY2F0ZSBhIGxhcmdlIGluaXRpYWwgYmxvY2sgdG8gYXZvaWQgbWFsbG9jcyBkdXJpbmcgaG9va2VkIHRlc3QuCisgIHN0ZDo6dmVjdG9yPGNoYXI+IGFyZW5hX2Jsb2NrKDEyOCAqIDEwMjQpOworICBBcmVuYU9wdGlvbnMgb3B0aW9uczsKKyAgb3B0aW9ucy5pbml0aWFsX2Jsb2NrID0gJmFyZW5hX2Jsb2NrWzBdOworICBvcHRpb25zLmluaXRpYWxfYmxvY2tfc2l6ZSA9IGFyZW5hX2Jsb2NrLnNpemUoKTsKKyAgQXJlbmEgYXJlbmEob3B0aW9ucyk7CisgIHN0cmluZyBkYXRhOworICBkYXRhLnJlc2VydmUoMTI4ICogMTAyNCk7CisKKyAgeworICAgIC8vIFRPRE8odGVib3JpbmcpOiBFbmFibGUgbm8gaGVhcCBjaGVjayB3aGVuIEFyZW5hU3RyaW5nUHRyIGlzIHVzZWQgaW4gbWFwLgorICAgIC8vIE5vSGVhcENoZWNrZXIgbm9faGVhcDsKKworICAgIHVuaXR0ZXN0OjpUZXN0QXJlbmFNYXAqIGZyb20gPQorICAgICAgICBBcmVuYTo6Q3JlYXRlTWVzc2FnZTx1bml0dGVzdDo6VGVzdEFyZW5hTWFwPigmYXJlbmEpOworICAgIE1hcFRlc3RVdGlsOjpTZXRBcmVuYU1hcEZpZWxkcyhmcm9tKTsKKyAgICBmcm9tLT5TZXJpYWxpemVUb1N0cmluZygmZGF0YSk7CisKKyAgICB1bml0dGVzdDo6VGVzdEFyZW5hTWFwKiB0byA9CisgICAgICAgIEFyZW5hOjpDcmVhdGVNZXNzYWdlPHVuaXR0ZXN0OjpUZXN0QXJlbmFNYXA+KCZhcmVuYSk7CisgICAgdG8tPlBhcnNlRnJvbVN0cmluZyhkYXRhKTsKKyAgICBNYXBUZXN0VXRpbDo6RXhwZWN0QXJlbmFNYXBGaWVsZHNTZXQoKnRvKTsKKyAgfQorfQorCisvLyBVc2UgdGV4dCBmb3JtYXQgcGFyc2luZyBhbmQgc2VyaWFsaXppbmcgdG8gdGVzdCByZWZsZWN0aW9uIGFwaS4KK1RFU1QoQXJlbmFUZXN0LCBSZWxmZWN0aW9uSW5UZXh0Rm9ybWF0KSB7CisgIEFyZW5hIGFyZW5hOworICBzdHJpbmcgZGF0YTsKKworICBUZXh0Rm9ybWF0OjpQcmludGVyIHByaW50ZXI7CisgIFRleHRGb3JtYXQ6OlBhcnNlciBwYXJzZXI7CisKKyAgdW5pdHRlc3Q6OlRlc3RBcmVuYU1hcCogZnJvbSA9CisgICAgICBBcmVuYTo6Q3JlYXRlTWVzc2FnZTx1bml0dGVzdDo6VGVzdEFyZW5hTWFwPigmYXJlbmEpOworICB1bml0dGVzdDo6VGVzdEFyZW5hTWFwKiB0byA9CisgICAgICBBcmVuYTo6Q3JlYXRlTWVzc2FnZTx1bml0dGVzdDo6VGVzdEFyZW5hTWFwPigmYXJlbmEpOworCisgIE1hcFRlc3RVdGlsOjpTZXRBcmVuYU1hcEZpZWxkcyhmcm9tKTsKKyAgcHJpbnRlci5QcmludFRvU3RyaW5nKCpmcm9tLCAmZGF0YSk7CisKKyAgRVhQRUNUX1RSVUUocGFyc2VyLlBhcnNlRnJvbVN0cmluZyhkYXRhLCB0bykpOworICBNYXBUZXN0VXRpbDo6RXhwZWN0QXJlbmFNYXBGaWVsZHNTZXQoKnRvKTsKK30KKworLy8gTWFrZSBzdXJlIHRoZSBtZW1vcnkgYWxsb2NhdGVkIGZvciBzdHJpbmcgaW4gbWFwIGlzIGRlYWxsb2NhdGVkLgorVEVTVChBcmVuYVRlc3QsIFN0cmluZ01hcE5vTGVhaykgeworICBBcmVuYSBhcmVuYTsKKyAgdW5pdHRlc3Q6OlRlc3RBcmVuYU1hcCogbWVzc2FnZSA9CisgICAgICBBcmVuYTo6Q3JlYXRlTWVzc2FnZTx1bml0dGVzdDo6VGVzdEFyZW5hTWFwPigmYXJlbmEpOworICBzdHJpbmcgZGF0YTsKKyAgLy8gU3RyaW5nIHdpdGggbGVuZ3RoIGxlc3MgdGhhbiAxNiB3aWxsIG5vdCBiZSBhbGxvY2F0ZWQgZnJvbSBoZWFwLgorICBpbnQgb3JpZ2luYWxfY2FwYWNpdHkgPSBkYXRhLmNhcGFjaXR5KCk7CisgIHdoaWxlIChkYXRhLmNhcGFjaXR5KCkgPD0gb3JpZ2luYWxfY2FwYWNpdHkpIHsKKyAgICBkYXRhLmFwcGVuZCgiYSIpOworICB9CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfc3RyaW5nX3N0cmluZygpKVtkYXRhXSA9IGRhdGE7CisgIC8vIFdlIHJlbHkgb24gaGVhcCBjaGVja2VycyB0byBkZXRlY3QgbWVtb3J5IGxlYWsgZm9yIHVzLgorICBBU1NFUlRfRkFMU0UobWVzc2FnZSA9PSBOVUxMKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvbWFwX3Rlc3RfdXRpbC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvbWFwX3Rlc3RfdXRpbC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hZTA5NDY0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9tYXBfdGVzdF91dGlsLmNjCkBAIC0wLDAgKzEsMTgwMSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWFwX3Rlc3RfdXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tYXBfdGVzdF91dGlsX2ltcGwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tZXNzYWdlLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKwordm9pZCBNYXBUZXN0VXRpbDo6U2V0TWFwRmllbGRzKHVuaXR0ZXN0OjpUZXN0TWFwKiBtZXNzYWdlKSB7CisgIE1hcFRlc3RVdGlsSW1wbDo6U2V0TWFwRmllbGRzPHVuaXR0ZXN0OjpNYXBFbnVtLCB1bml0dGVzdDo6TUFQX0VOVU1fQkFSLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0dGVzdDo6TUFQX0VOVU1fQkFaPihtZXNzYWdlKTsKK30KKwordm9pZCBNYXBUZXN0VXRpbDo6U2V0QXJlbmFNYXBGaWVsZHModW5pdHRlc3Q6OlRlc3RBcmVuYU1hcCogbWVzc2FnZSkgeworICBNYXBUZXN0VXRpbEltcGw6OlNldEFyZW5hTWFwRmllbGRzPHVuaXR0ZXN0OjpNYXBFbnVtLCB1bml0dGVzdDo6TUFQX0VOVU1fQkFSLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXR0ZXN0OjpNQVBfRU5VTV9CQVo+KG1lc3NhZ2UpOworfQorCit2b2lkIE1hcFRlc3RVdGlsOjpTZXRNYXBGaWVsZHNJbml0aWFsaXplZCh1bml0dGVzdDo6VGVzdE1hcCogbWVzc2FnZSkgeworICBNYXBUZXN0VXRpbEltcGw6OlNldE1hcEZpZWxkc0luaXRpYWxpemVkKG1lc3NhZ2UpOworfQorCit2b2lkIE1hcFRlc3RVdGlsOjpNb2RpZnlNYXBGaWVsZHModW5pdHRlc3Q6OlRlc3RNYXAqIG1lc3NhZ2UpIHsKKyAgTWFwVGVzdFV0aWxJbXBsOjpNb2RpZnlNYXBGaWVsZHM8dW5pdHRlc3Q6Ok1hcEVudW0sIHVuaXR0ZXN0OjpNQVBfRU5VTV9GT08+KAorICAgICAgbWVzc2FnZSk7Cit9CisKK3ZvaWQgTWFwVGVzdFV0aWw6OkV4cGVjdENsZWFyKGNvbnN0IHVuaXR0ZXN0OjpUZXN0TWFwJiBtZXNzYWdlKSB7CisgIE1hcFRlc3RVdGlsSW1wbDo6RXhwZWN0Q2xlYXIobWVzc2FnZSk7Cit9CisKK3ZvaWQgTWFwVGVzdFV0aWw6OkV4cGVjdE1hcEZpZWxkc1NldChjb25zdCB1bml0dGVzdDo6VGVzdE1hcCYgbWVzc2FnZSkgeworICBNYXBUZXN0VXRpbEltcGw6OkV4cGVjdE1hcEZpZWxkc1NldDx1bml0dGVzdDo6TWFwRW51bSwgdW5pdHRlc3Q6Ok1BUF9FTlVNX0JBUiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHRlc3Q6Ok1BUF9FTlVNX0JBWj4obWVzc2FnZSk7Cit9CisKK3ZvaWQgTWFwVGVzdFV0aWw6OkV4cGVjdEFyZW5hTWFwRmllbGRzU2V0KAorICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0QXJlbmFNYXAmIG1lc3NhZ2UpIHsKKyAgTWFwVGVzdFV0aWxJbXBsOjpFeHBlY3RBcmVuYU1hcEZpZWxkc1NldDwKKyAgICAgIHVuaXR0ZXN0OjpNYXBFbnVtLCB1bml0dGVzdDo6TUFQX0VOVU1fQkFSLCB1bml0dGVzdDo6TUFQX0VOVU1fQkFaPigKKyAgICAgIG1lc3NhZ2UpOworfQorCit2b2lkIE1hcFRlc3RVdGlsOjpFeHBlY3RNYXBGaWVsZHNTZXRJbml0aWFsaXplZCgKKyAgICBjb25zdCB1bml0dGVzdDo6VGVzdE1hcCYgbWVzc2FnZSkgeworICBNYXBUZXN0VXRpbEltcGw6OkV4cGVjdE1hcEZpZWxkc1NldEluaXRpYWxpemVkPHVuaXR0ZXN0OjpNYXBFbnVtLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXR0ZXN0OjpNQVBfRU5VTV9GT08+KAorICAgICAgbWVzc2FnZSk7Cit9CisKK3ZvaWQgTWFwVGVzdFV0aWw6OkV4cGVjdE1hcEZpZWxkc01vZGlmaWVkKAorICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0TWFwJiBtZXNzYWdlKSB7CisgIE1hcFRlc3RVdGlsSW1wbDo6RXhwZWN0TWFwRmllbGRzTW9kaWZpZWQ8CisgICAgICB1bml0dGVzdDo6TWFwRW51bSwgdW5pdHRlc3Q6Ok1BUF9FTlVNX0JBUiwgdW5pdHRlc3Q6Ok1BUF9FTlVNX0ZPTz4oCisgICAgICBtZXNzYWdlKTsKK30KKwordm9pZCBNYXBUZXN0VXRpbDo6RXhwZWN0TWFwc1NpemUoCisgICAgY29uc3QgdW5pdHRlc3Q6OlRlc3RNYXAmIG1lc3NhZ2UsIGludCBzaXplKSB7CisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBtZXNzYWdlLkdldERlc2NyaXB0b3IoKTsKKworICBFWFBFQ1RfRVEoc2l6ZSwgbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPkZpZWxkU2l6ZSgKKyAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9pbnQzMl9pbnQzMiIpKSk7CisgIEVYUEVDVF9FUShzaXplLCBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+RmllbGRTaXplKAorICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgibWFwX2ludDY0X2ludDY0IikpKTsKKyAgRVhQRUNUX0VRKHNpemUsIG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpLT5GaWVsZFNpemUoCisgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJtYXBfdWludDMyX3VpbnQzMiIpKSk7CisgIEVYUEVDVF9FUShzaXplLCBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+RmllbGRTaXplKAorICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgibWFwX3VpbnQ2NF91aW50NjQiKSkpOworICBFWFBFQ1RfRVEoc2l6ZSwgbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPkZpZWxkU2l6ZSgKKyAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9zaW50MzJfc2ludDMyIikpKTsKKyAgRVhQRUNUX0VRKHNpemUsIG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpLT5GaWVsZFNpemUoCisgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJtYXBfc2ludDY0X3NpbnQ2NCIpKSk7CisgIEVYUEVDVF9FUShzaXplLCBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+RmllbGRTaXplKAorICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgibWFwX2ZpeGVkMzJfZml4ZWQzMiIpKSk7CisgIEVYUEVDVF9FUShzaXplLCBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+RmllbGRTaXplKAorICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgibWFwX2ZpeGVkNjRfZml4ZWQ2NCIpKSk7CisgIEVYUEVDVF9FUShzaXplLCBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+RmllbGRTaXplKAorICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgibWFwX3NmaXhlZDMyX3NmaXhlZDMyIikpKTsKKyAgRVhQRUNUX0VRKHNpemUsIG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpLT5GaWVsZFNpemUoCisgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJtYXBfc2ZpeGVkNjRfc2ZpeGVkNjQiKSkpOworICBFWFBFQ1RfRVEoc2l6ZSwgbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPkZpZWxkU2l6ZSgKKyAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9pbnQzMl9mbG9hdCIpKSk7CisgIEVYUEVDVF9FUShzaXplLCBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+RmllbGRTaXplKAorICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgibWFwX2ludDMyX2RvdWJsZSIpKSk7CisgIEVYUEVDVF9FUShzaXplLCBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+RmllbGRTaXplKAorICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgibWFwX2Jvb2xfYm9vbCIpKSk7CisgIEVYUEVDVF9FUShzaXplLCBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+RmllbGRTaXplKAorICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgibWFwX3N0cmluZ19zdHJpbmciKSkpOworICBFWFBFQ1RfRVEoc2l6ZSwgbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPkZpZWxkU2l6ZSgKKyAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9pbnQzMl9ieXRlcyIpKSk7CisgIEVYUEVDVF9FUShzaXplLCBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+RmllbGRTaXplKAorICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgibWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSIpKSk7Cit9CisKK3N0ZDo6dmVjdG9yPGNvbnN0IE1lc3NhZ2UqPiBNYXBUZXN0VXRpbDo6R2V0TWFwRW50cmllcygKKyAgICBjb25zdCB1bml0dGVzdDo6VGVzdE1hcCYgbWVzc2FnZSwgaW50IGluZGV4KSB7CisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBtZXNzYWdlLkdldERlc2NyaXB0b3IoKTsKKyAgc3RkOjp2ZWN0b3I8Y29uc3QgTWVzc2FnZSo+IHJlc3VsdDsKKworICByZXN1bHQucHVzaF9iYWNrKCZtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+R2V0UmVwZWF0ZWRNZXNzYWdlKAorICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgibWFwX2ludDMyX2ludDMyIiksIGluZGV4KSk7CisgIHJlc3VsdC5wdXNoX2JhY2soJm1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpLT5HZXRSZXBlYXRlZE1lc3NhZ2UoCisgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJtYXBfaW50NjRfaW50NjQiKSwgaW5kZXgpKTsKKyAgcmVzdWx0LnB1c2hfYmFjaygmbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPkdldFJlcGVhdGVkTWVzc2FnZSgKKyAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoIm1hcF91aW50MzJfdWludDMyIiksIGluZGV4KSk7CisgIHJlc3VsdC5wdXNoX2JhY2soJm1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpLT5HZXRSZXBlYXRlZE1lc3NhZ2UoCisgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJtYXBfdWludDY0X3VpbnQ2NCIpLCBpbmRleCkpOworICByZXN1bHQucHVzaF9iYWNrKCZtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+R2V0UmVwZWF0ZWRNZXNzYWdlKAorICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgibWFwX3NpbnQzMl9zaW50MzIiKSwgaW5kZXgpKTsKKyAgcmVzdWx0LnB1c2hfYmFjaygmbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPkdldFJlcGVhdGVkTWVzc2FnZSgKKyAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9zaW50NjRfc2ludDY0IiksIGluZGV4KSk7CisgIHJlc3VsdC5wdXNoX2JhY2soJm1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpLT5HZXRSZXBlYXRlZE1lc3NhZ2UoCisgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJtYXBfZml4ZWQzMl9maXhlZDMyIiksIGluZGV4KSk7CisgIHJlc3VsdC5wdXNoX2JhY2soJm1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpLT5HZXRSZXBlYXRlZE1lc3NhZ2UoCisgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJtYXBfZml4ZWQ2NF9maXhlZDY0IiksIGluZGV4KSk7CisgIHJlc3VsdC5wdXNoX2JhY2soJm1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpLT5HZXRSZXBlYXRlZE1lc3NhZ2UoCisgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJtYXBfc2ZpeGVkMzJfc2ZpeGVkMzIiKSwgaW5kZXgpKTsKKyAgcmVzdWx0LnB1c2hfYmFjaygmbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPkdldFJlcGVhdGVkTWVzc2FnZSgKKyAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9zZml4ZWQ2NF9zZml4ZWQ2NCIpLCBpbmRleCkpOworICByZXN1bHQucHVzaF9iYWNrKCZtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+R2V0UmVwZWF0ZWRNZXNzYWdlKAorICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgibWFwX2ludDMyX2Zsb2F0IiksIGluZGV4KSk7CisgIHJlc3VsdC5wdXNoX2JhY2soJm1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpLT5HZXRSZXBlYXRlZE1lc3NhZ2UoCisgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJtYXBfaW50MzJfZG91YmxlIiksIGluZGV4KSk7CisgIHJlc3VsdC5wdXNoX2JhY2soJm1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpLT5HZXRSZXBlYXRlZE1lc3NhZ2UoCisgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJtYXBfYm9vbF9ib29sIiksIGluZGV4KSk7CisgIHJlc3VsdC5wdXNoX2JhY2soJm1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpLT5HZXRSZXBlYXRlZE1lc3NhZ2UoCisgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJtYXBfc3RyaW5nX3N0cmluZyIpLCBpbmRleCkpOworICByZXN1bHQucHVzaF9iYWNrKCZtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+R2V0UmVwZWF0ZWRNZXNzYWdlKAorICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgibWFwX2ludDMyX2J5dGVzIiksIGluZGV4KSk7CisgIHJlc3VsdC5wdXNoX2JhY2soJm1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpLT5HZXRSZXBlYXRlZE1lc3NhZ2UoCisgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJtYXBfaW50MzJfZW51bSIpLCBpbmRleCkpOworICByZXN1bHQucHVzaF9iYWNrKCZtZXNzYWdlLkdldFJlZmxlY3Rpb24oKS0+R2V0UmVwZWF0ZWRNZXNzYWdlKAorICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgibWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSIpLCBpbmRleCkpOworCisgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0ZDo6dmVjdG9yPGNvbnN0IE1lc3NhZ2UqPiBNYXBUZXN0VXRpbDo6R2V0TWFwRW50cmllc0Zyb21SZWxlYXNlKAorICAgIHVuaXR0ZXN0OjpUZXN0TWFwKiBtZXNzYWdlKSB7CisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBtZXNzYWdlLT5HZXREZXNjcmlwdG9yKCk7CisgIHN0ZDo6dmVjdG9yPGNvbnN0IE1lc3NhZ2UqPiByZXN1bHQ7CisKKyAgcmVzdWx0LnB1c2hfYmFjayhtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlJlbGVhc2VMYXN0KAorICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgibWFwX2ludDMyX2ludDMyIikpKTsKKyAgcmVzdWx0LnB1c2hfYmFjayhtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlJlbGVhc2VMYXN0KAorICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgibWFwX2ludDY0X2ludDY0IikpKTsKKyAgcmVzdWx0LnB1c2hfYmFjayhtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlJlbGVhc2VMYXN0KAorICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgibWFwX3VpbnQzMl91aW50MzIiKSkpOworICByZXN1bHQucHVzaF9iYWNrKG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+UmVsZWFzZUxhc3QoCisgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJtYXBfdWludDY0X3VpbnQ2NCIpKSk7CisgIHJlc3VsdC5wdXNoX2JhY2sobWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5SZWxlYXNlTGFzdCgKKyAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9zaW50MzJfc2ludDMyIikpKTsKKyAgcmVzdWx0LnB1c2hfYmFjayhtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlJlbGVhc2VMYXN0KAorICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgibWFwX3NpbnQ2NF9zaW50NjQiKSkpOworICByZXN1bHQucHVzaF9iYWNrKG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+UmVsZWFzZUxhc3QoCisgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJtYXBfZml4ZWQzMl9maXhlZDMyIikpKTsKKyAgcmVzdWx0LnB1c2hfYmFjayhtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlJlbGVhc2VMYXN0KAorICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgibWFwX2ZpeGVkNjRfZml4ZWQ2NCIpKSk7CisgIHJlc3VsdC5wdXNoX2JhY2sobWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5SZWxlYXNlTGFzdCgKKyAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9zZml4ZWQzMl9zZml4ZWQzMiIpKSk7CisgIHJlc3VsdC5wdXNoX2JhY2sobWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5SZWxlYXNlTGFzdCgKKyAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9zZml4ZWQ2NF9zZml4ZWQ2NCIpKSk7CisgIHJlc3VsdC5wdXNoX2JhY2sobWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5SZWxlYXNlTGFzdCgKKyAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9pbnQzMl9mbG9hdCIpKSk7CisgIHJlc3VsdC5wdXNoX2JhY2sobWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5SZWxlYXNlTGFzdCgKKyAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9pbnQzMl9kb3VibGUiKSkpOworICByZXN1bHQucHVzaF9iYWNrKG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+UmVsZWFzZUxhc3QoCisgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJtYXBfYm9vbF9ib29sIikpKTsKKyAgcmVzdWx0LnB1c2hfYmFjayhtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlJlbGVhc2VMYXN0KAorICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgibWFwX3N0cmluZ19zdHJpbmciKSkpOworICByZXN1bHQucHVzaF9iYWNrKG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+UmVsZWFzZUxhc3QoCisgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJtYXBfaW50MzJfYnl0ZXMiKSkpOworICByZXN1bHQucHVzaF9iYWNrKG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+UmVsZWFzZUxhc3QoCisgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJtYXBfaW50MzJfZW51bSIpKSk7CisgIHJlc3VsdC5wdXNoX2JhY2sobWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5SZWxlYXNlTGFzdCgKKyAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoIm1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UiKSkpOworCisgIHJldHVybiByZXN1bHQ7Cit9CisKK01hcFJlZmxlY3Rpb25UZXN0ZXI6Ok1hcFJlZmxlY3Rpb25UZXN0ZXIoCisgICAgY29uc3QgRGVzY3JpcHRvciogYmFzZV9kZXNjcmlwdG9yKQorICA6IGJhc2VfZGVzY3JpcHRvcl8oYmFzZV9kZXNjcmlwdG9yKSB7CisgIGNvbnN0IERlc2NyaXB0b3JQb29sKiBwb29sID0gYmFzZV9kZXNjcmlwdG9yLT5maWxlKCktPnBvb2woKTsKKworICBtYXBfZW51bV9mb29fID0gcG9vbC0+RmluZEVudW1WYWx1ZUJ5TmFtZSgicHJvdG9idWZfdW5pdHRlc3QuTUFQX0VOVU1fRk9PIik7CisgIG1hcF9lbnVtX2Jhcl8gPSBwb29sLT5GaW5kRW51bVZhbHVlQnlOYW1lKCJwcm90b2J1Zl91bml0dGVzdC5NQVBfRU5VTV9CQVIiKTsKKyAgbWFwX2VudW1fYmF6XyA9IHBvb2wtPkZpbmRFbnVtVmFsdWVCeU5hbWUoInByb3RvYnVmX3VuaXR0ZXN0Lk1BUF9FTlVNX0JBWiIpOworCisgIGZvcmVpZ25fY18gPSBwb29sLT5GaW5kRmllbGRCeU5hbWUoCisgICAgICAicHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UuYyIpOworICBtYXBfaW50MzJfaW50MzJfa2V5XyA9IHBvb2wtPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICJwcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwLk1hcEludDMySW50MzJFbnRyeS5rZXkiKTsKKyAgbWFwX2ludDMyX2ludDMyX3ZhbF8gPSBwb29sLT5GaW5kRmllbGRCeU5hbWUoCisgICAgICAicHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcC5NYXBJbnQzMkludDMyRW50cnkudmFsdWUiKTsKKyAgbWFwX2ludDY0X2ludDY0X2tleV8gPSBwb29sLT5GaW5kRmllbGRCeU5hbWUoCisgICAgICAicHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcC5NYXBJbnQ2NEludDY0RW50cnkua2V5Iik7CisgIG1hcF9pbnQ2NF9pbnQ2NF92YWxfID0gcG9vbC0+RmluZEZpZWxkQnlOYW1lKAorICAgICAgInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXAuTWFwSW50NjRJbnQ2NEVudHJ5LnZhbHVlIik7CisgIG1hcF91aW50MzJfdWludDMyX2tleV8gPSBwb29sLT5GaW5kRmllbGRCeU5hbWUoCisgICAgICAicHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcC5NYXBVaW50MzJVaW50MzJFbnRyeS5rZXkiKTsKKyAgbWFwX3VpbnQzMl91aW50MzJfdmFsXyA9IHBvb2wtPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICJwcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwLk1hcFVpbnQzMlVpbnQzMkVudHJ5LnZhbHVlIik7CisgIG1hcF91aW50NjRfdWludDY0X2tleV8gPSBwb29sLT5GaW5kRmllbGRCeU5hbWUoCisgICAgICAicHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcC5NYXBVaW50NjRVaW50NjRFbnRyeS5rZXkiKTsKKyAgbWFwX3VpbnQ2NF91aW50NjRfdmFsXyA9IHBvb2wtPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICJwcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwLk1hcFVpbnQ2NFVpbnQ2NEVudHJ5LnZhbHVlIik7CisgIG1hcF9zaW50MzJfc2ludDMyX2tleV8gPSBwb29sLT5GaW5kRmllbGRCeU5hbWUoCisgICAgICAicHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcC5NYXBTaW50MzJTaW50MzJFbnRyeS5rZXkiKTsKKyAgbWFwX3NpbnQzMl9zaW50MzJfdmFsXyA9IHBvb2wtPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICJwcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwLk1hcFNpbnQzMlNpbnQzMkVudHJ5LnZhbHVlIik7CisgIG1hcF9zaW50NjRfc2ludDY0X2tleV8gPSBwb29sLT5GaW5kRmllbGRCeU5hbWUoCisgICAgICAicHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcC5NYXBTaW50NjRTaW50NjRFbnRyeS5rZXkiKTsKKyAgbWFwX3NpbnQ2NF9zaW50NjRfdmFsXyA9IHBvb2wtPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICJwcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwLk1hcFNpbnQ2NFNpbnQ2NEVudHJ5LnZhbHVlIik7CisgIG1hcF9maXhlZDMyX2ZpeGVkMzJfa2V5XyA9IHBvb2wtPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICJwcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwLk1hcEZpeGVkMzJGaXhlZDMyRW50cnkua2V5Iik7CisgIG1hcF9maXhlZDMyX2ZpeGVkMzJfdmFsXyA9IHBvb2wtPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICJwcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwLk1hcEZpeGVkMzJGaXhlZDMyRW50cnkudmFsdWUiKTsKKyAgbWFwX2ZpeGVkNjRfZml4ZWQ2NF9rZXlfID0gcG9vbC0+RmluZEZpZWxkQnlOYW1lKAorICAgICAgInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXAuTWFwRml4ZWQ2NEZpeGVkNjRFbnRyeS5rZXkiKTsKKyAgbWFwX2ZpeGVkNjRfZml4ZWQ2NF92YWxfID0gcG9vbC0+RmluZEZpZWxkQnlOYW1lKAorICAgICAgInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXAuTWFwRml4ZWQ2NEZpeGVkNjRFbnRyeS52YWx1ZSIpOworICBtYXBfc2ZpeGVkMzJfc2ZpeGVkMzJfa2V5XyA9IHBvb2wtPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICJwcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwLk1hcFNmaXhlZDMyU2ZpeGVkMzJFbnRyeS5rZXkiKTsKKyAgbWFwX3NmaXhlZDMyX3NmaXhlZDMyX3ZhbF8gPSBwb29sLT5GaW5kRmllbGRCeU5hbWUoCisgICAgICAicHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcC5NYXBTZml4ZWQzMlNmaXhlZDMyRW50cnkudmFsdWUiKTsKKyAgbWFwX3NmaXhlZDY0X3NmaXhlZDY0X2tleV8gPSBwb29sLT5GaW5kRmllbGRCeU5hbWUoCisgICAgICAicHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcC5NYXBTZml4ZWQ2NFNmaXhlZDY0RW50cnkua2V5Iik7CisgIG1hcF9zZml4ZWQ2NF9zZml4ZWQ2NF92YWxfID0gcG9vbC0+RmluZEZpZWxkQnlOYW1lKAorICAgICAgInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXAuTWFwU2ZpeGVkNjRTZml4ZWQ2NEVudHJ5LnZhbHVlIik7CisgIG1hcF9pbnQzMl9mbG9hdF9rZXlfID0gcG9vbC0+RmluZEZpZWxkQnlOYW1lKAorICAgICAgInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXAuTWFwSW50MzJGbG9hdEVudHJ5LmtleSIpOworICBtYXBfaW50MzJfZmxvYXRfdmFsXyA9IHBvb2wtPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICJwcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwLk1hcEludDMyRmxvYXRFbnRyeS52YWx1ZSIpOworICBtYXBfaW50MzJfZG91YmxlX2tleV8gPSBwb29sLT5GaW5kRmllbGRCeU5hbWUoCisgICAgICAicHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcC5NYXBJbnQzMkRvdWJsZUVudHJ5LmtleSIpOworICBtYXBfaW50MzJfZG91YmxlX3ZhbF8gPSBwb29sLT5GaW5kRmllbGRCeU5hbWUoCisgICAgICAicHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcC5NYXBJbnQzMkRvdWJsZUVudHJ5LnZhbHVlIik7CisgIG1hcF9ib29sX2Jvb2xfa2V5XyA9IHBvb2wtPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICJwcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwLk1hcEJvb2xCb29sRW50cnkua2V5Iik7CisgIG1hcF9ib29sX2Jvb2xfdmFsXyA9IHBvb2wtPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICJwcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwLk1hcEJvb2xCb29sRW50cnkudmFsdWUiKTsKKyAgbWFwX3N0cmluZ19zdHJpbmdfa2V5XyA9IHBvb2wtPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICJwcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwLk1hcFN0cmluZ1N0cmluZ0VudHJ5LmtleSIpOworICBtYXBfc3RyaW5nX3N0cmluZ192YWxfID0gcG9vbC0+RmluZEZpZWxkQnlOYW1lKAorICAgICAgInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXAuTWFwU3RyaW5nU3RyaW5nRW50cnkudmFsdWUiKTsKKyAgbWFwX2ludDMyX2J5dGVzX2tleV8gPSBwb29sLT5GaW5kRmllbGRCeU5hbWUoCisgICAgICAicHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcC5NYXBJbnQzMkJ5dGVzRW50cnkua2V5Iik7CisgIG1hcF9pbnQzMl9ieXRlc192YWxfID0gcG9vbC0+RmluZEZpZWxkQnlOYW1lKAorICAgICAgInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXAuTWFwSW50MzJCeXRlc0VudHJ5LnZhbHVlIik7CisgIG1hcF9pbnQzMl9lbnVtX2tleV8gPSBwb29sLT5GaW5kRmllbGRCeU5hbWUoCisgICAgICAicHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcC5NYXBJbnQzMkVudW1FbnRyeS5rZXkiKTsKKyAgbWFwX2ludDMyX2VudW1fdmFsXyA9IHBvb2wtPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICJwcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwLk1hcEludDMyRW51bUVudHJ5LnZhbHVlIik7CisgIG1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2Vfa2V5XyA9IHBvb2wtPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICJwcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwLk1hcEludDMyRm9yZWlnbk1lc3NhZ2VFbnRyeS5rZXkiKTsKKyAgbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZV92YWxfID0gcG9vbC0+RmluZEZpZWxkQnlOYW1lKAorICAgICAgInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXAuTWFwSW50MzJGb3JlaWduTWVzc2FnZUVudHJ5LnZhbHVlIik7CisKKyAgRVhQRUNUX0ZBTFNFKG1hcF9lbnVtX2Zvb18gPT0gTlVMTCk7CisgIEVYUEVDVF9GQUxTRShtYXBfZW51bV9iYXJfID09IE5VTEwpOworICBFWFBFQ1RfRkFMU0UobWFwX2VudW1fYmF6XyA9PSBOVUxMKTsKKyAgRVhQRUNUX0ZBTFNFKG1hcF9pbnQzMl9pbnQzMl9rZXlfID09IE5VTEwpOworICBFWFBFQ1RfRkFMU0UobWFwX2ludDMyX2ludDMyX3ZhbF8gPT0gTlVMTCk7CisgIEVYUEVDVF9GQUxTRShtYXBfaW50NjRfaW50NjRfa2V5XyA9PSBOVUxMKTsKKyAgRVhQRUNUX0ZBTFNFKG1hcF9pbnQ2NF9pbnQ2NF92YWxfID09IE5VTEwpOworICBFWFBFQ1RfRkFMU0UobWFwX3VpbnQzMl91aW50MzJfa2V5XyA9PSBOVUxMKTsKKyAgRVhQRUNUX0ZBTFNFKG1hcF91aW50MzJfdWludDMyX3ZhbF8gPT0gTlVMTCk7CisgIEVYUEVDVF9GQUxTRShtYXBfdWludDY0X3VpbnQ2NF9rZXlfID09IE5VTEwpOworICBFWFBFQ1RfRkFMU0UobWFwX3VpbnQ2NF91aW50NjRfdmFsXyA9PSBOVUxMKTsKKyAgRVhQRUNUX0ZBTFNFKG1hcF9zaW50MzJfc2ludDMyX2tleV8gPT0gTlVMTCk7CisgIEVYUEVDVF9GQUxTRShtYXBfc2ludDMyX3NpbnQzMl92YWxfID09IE5VTEwpOworICBFWFBFQ1RfRkFMU0UobWFwX3NpbnQ2NF9zaW50NjRfa2V5XyA9PSBOVUxMKTsKKyAgRVhQRUNUX0ZBTFNFKG1hcF9zaW50NjRfc2ludDY0X3ZhbF8gPT0gTlVMTCk7CisgIEVYUEVDVF9GQUxTRShtYXBfZml4ZWQzMl9maXhlZDMyX2tleV8gPT0gTlVMTCk7CisgIEVYUEVDVF9GQUxTRShtYXBfZml4ZWQzMl9maXhlZDMyX3ZhbF8gPT0gTlVMTCk7CisgIEVYUEVDVF9GQUxTRShtYXBfZml4ZWQ2NF9maXhlZDY0X2tleV8gPT0gTlVMTCk7CisgIEVYUEVDVF9GQUxTRShtYXBfZml4ZWQ2NF9maXhlZDY0X3ZhbF8gPT0gTlVMTCk7CisgIEVYUEVDVF9GQUxTRShtYXBfc2ZpeGVkMzJfc2ZpeGVkMzJfa2V5XyA9PSBOVUxMKTsKKyAgRVhQRUNUX0ZBTFNFKG1hcF9zZml4ZWQzMl9zZml4ZWQzMl92YWxfID09IE5VTEwpOworICBFWFBFQ1RfRkFMU0UobWFwX3NmaXhlZDY0X3NmaXhlZDY0X2tleV8gPT0gTlVMTCk7CisgIEVYUEVDVF9GQUxTRShtYXBfc2ZpeGVkNjRfc2ZpeGVkNjRfdmFsXyA9PSBOVUxMKTsKKyAgRVhQRUNUX0ZBTFNFKG1hcF9pbnQzMl9mbG9hdF9rZXlfID09IE5VTEwpOworICBFWFBFQ1RfRkFMU0UobWFwX2ludDMyX2Zsb2F0X3ZhbF8gPT0gTlVMTCk7CisgIEVYUEVDVF9GQUxTRShtYXBfaW50MzJfZG91YmxlX2tleV8gPT0gTlVMTCk7CisgIEVYUEVDVF9GQUxTRShtYXBfaW50MzJfZG91YmxlX3ZhbF8gPT0gTlVMTCk7CisgIEVYUEVDVF9GQUxTRShtYXBfYm9vbF9ib29sX2tleV8gPT0gTlVMTCk7CisgIEVYUEVDVF9GQUxTRShtYXBfYm9vbF9ib29sX3ZhbF8gPT0gTlVMTCk7CisgIEVYUEVDVF9GQUxTRShtYXBfc3RyaW5nX3N0cmluZ19rZXlfID09IE5VTEwpOworICBFWFBFQ1RfRkFMU0UobWFwX3N0cmluZ19zdHJpbmdfdmFsXyA9PSBOVUxMKTsKKyAgRVhQRUNUX0ZBTFNFKG1hcF9pbnQzMl9ieXRlc19rZXlfID09IE5VTEwpOworICBFWFBFQ1RfRkFMU0UobWFwX2ludDMyX2J5dGVzX3ZhbF8gPT0gTlVMTCk7CisgIEVYUEVDVF9GQUxTRShtYXBfaW50MzJfZW51bV9rZXlfID09IE5VTEwpOworICBFWFBFQ1RfRkFMU0UobWFwX2ludDMyX2VudW1fdmFsXyA9PSBOVUxMKTsKKyAgRVhQRUNUX0ZBTFNFKG1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2Vfa2V5XyA9PSBOVUxMKTsKKyAgRVhQRUNUX0ZBTFNFKG1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2VfdmFsXyA9PSBOVUxMKTsKK30KKworLy8gU2hvcnRoYW5kIHRvIGdldCBhIEZpZWxkRGVzY3JpcHRvciBmb3IgYSBmaWVsZCBvZiB1bml0dGVzdDo6VGVzdE1hcC4KK2NvbnN0IEZpZWxkRGVzY3JpcHRvciogTWFwUmVmbGVjdGlvblRlc3Rlcjo6Rihjb25zdCBzdHJpbmcmIG5hbWUpIHsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiByZXN1bHQgPSBOVUxMOworICByZXN1bHQgPSBiYXNlX2Rlc2NyaXB0b3JfLT5GaW5kRmllbGRCeU5hbWUobmFtZSk7CisgIEdPT0dMRV9DSEVDSyhyZXN1bHQgIT0gTlVMTCk7CisgIHJldHVybiByZXN1bHQ7Cit9CisKK3ZvaWQgTWFwUmVmbGVjdGlvblRlc3Rlcjo6U2V0TWFwRmllbGRzVmlhUmVmbGVjdGlvbigKKyAgICBNZXNzYWdlKiBtZXNzYWdlKSB7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCk7CisgIE1lc3NhZ2UqIHN1Yl9tZXNzYWdlID0gTlVMTDsKKyAgTWVzc2FnZSogc3ViX2ZvcmVpZ25fbWVzc2FnZSA9IE5VTEw7CisKKyAgLy8gQWRkIGZpcnN0IGVsZW1lbnQuCisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfaW50MzJfaW50MzIiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0SW50MzIoc3ViX21lc3NhZ2UsIG1hcF9pbnQzMl9pbnQzMl9rZXlfLCAwKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRJbnQzMihzdWJfbWVzc2FnZSwgbWFwX2ludDMyX2ludDMyX3ZhbF8sIDApOworCisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfaW50NjRfaW50NjQiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0SW50NjQoc3ViX21lc3NhZ2UsIG1hcF9pbnQ2NF9pbnQ2NF9rZXlfLCAwKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRJbnQ2NChzdWJfbWVzc2FnZSwgbWFwX2ludDY0X2ludDY0X3ZhbF8sIDApOworCisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfdWludDMyX3VpbnQzMiIpKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRVSW50MzIoc3ViX21lc3NhZ2UsIG1hcF91aW50MzJfdWludDMyX2tleV8sIDApOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldFVJbnQzMihzdWJfbWVzc2FnZSwgbWFwX3VpbnQzMl91aW50MzJfdmFsXywgMCk7CisKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF91aW50NjRfdWludDY0IikpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldFVJbnQ2NChzdWJfbWVzc2FnZSwgbWFwX3VpbnQ2NF91aW50NjRfa2V5XywgMCk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0VUludDY0KHN1Yl9tZXNzYWdlLCBtYXBfdWludDY0X3VpbnQ2NF92YWxfLCAwKTsKKworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX3NpbnQzMl9zaW50MzIiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0SW50MzIoc3ViX21lc3NhZ2UsIG1hcF9zaW50MzJfc2ludDMyX2tleV8sIDApOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldEludDMyKHN1Yl9tZXNzYWdlLCBtYXBfc2ludDMyX3NpbnQzMl92YWxfLCAwKTsKKworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX3NpbnQ2NF9zaW50NjQiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0SW50NjQoc3ViX21lc3NhZ2UsIG1hcF9zaW50NjRfc2ludDY0X2tleV8sIDApOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldEludDY0KHN1Yl9tZXNzYWdlLCBtYXBfc2ludDY0X3NpbnQ2NF92YWxfLCAwKTsKKworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX2ZpeGVkMzJfZml4ZWQzMiIpKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRVSW50MzIoc3ViX21lc3NhZ2UsIG1hcF9maXhlZDMyX2ZpeGVkMzJfa2V5XywgMCk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0VUludDMyKHN1Yl9tZXNzYWdlLCBtYXBfZml4ZWQzMl9maXhlZDMyX3ZhbF8sIDApOworCisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfZml4ZWQ2NF9maXhlZDY0IikpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldFVJbnQ2NChzdWJfbWVzc2FnZSwgbWFwX2ZpeGVkNjRfZml4ZWQ2NF9rZXlfLCAwKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRVSW50NjQoc3ViX21lc3NhZ2UsIG1hcF9maXhlZDY0X2ZpeGVkNjRfdmFsXywgMCk7CisKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9zZml4ZWQzMl9zZml4ZWQzMiIpKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRJbnQzMihzdWJfbWVzc2FnZSwgbWFwX3NmaXhlZDMyX3NmaXhlZDMyX2tleV8sIDApOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldEludDMyKHN1Yl9tZXNzYWdlLCBtYXBfc2ZpeGVkMzJfc2ZpeGVkMzJfdmFsXywgMCk7CisKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9zZml4ZWQ2NF9zZml4ZWQ2NCIpKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRJbnQ2NChzdWJfbWVzc2FnZSwgbWFwX3NmaXhlZDY0X3NmaXhlZDY0X2tleV8sIDApOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldEludDY0KHN1Yl9tZXNzYWdlLCBtYXBfc2ZpeGVkNjRfc2ZpeGVkNjRfdmFsXywgMCk7CisKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9mbG9hdCIpKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRJbnQzMihzdWJfbWVzc2FnZSwgbWFwX2ludDMyX2Zsb2F0X2tleV8sIDApOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldEZsb2F0KHN1Yl9tZXNzYWdlLCBtYXBfaW50MzJfZmxvYXRfdmFsXywgMC4wKTsKKworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX2ludDMyX2RvdWJsZSIpKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRJbnQzMihzdWJfbWVzc2FnZSwgbWFwX2ludDMyX2RvdWJsZV9rZXlfLCAwKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXREb3VibGUoc3ViX21lc3NhZ2UsIG1hcF9pbnQzMl9kb3VibGVfdmFsXywgMC4wKTsKKworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX2Jvb2xfYm9vbCIpKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRCb29sKHN1Yl9tZXNzYWdlLCBtYXBfYm9vbF9ib29sX2tleV8sIGZhbHNlKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRCb29sKHN1Yl9tZXNzYWdlLCBtYXBfYm9vbF9ib29sX3ZhbF8sIGZhbHNlKTsKKworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX3N0cmluZ19zdHJpbmciKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0U3RyaW5nKHN1Yl9tZXNzYWdlLCBtYXBfc3RyaW5nX3N0cmluZ19rZXlfLCAiMCIpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldFN0cmluZyhzdWJfbWVzc2FnZSwgbWFwX3N0cmluZ19zdHJpbmdfdmFsXywgIjAiKTsKKworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX2ludDMyX2J5dGVzIikpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldEludDMyKHN1Yl9tZXNzYWdlLCBtYXBfaW50MzJfYnl0ZXNfa2V5XywgMCk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0U3RyaW5nKHN1Yl9tZXNzYWdlLCBtYXBfaW50MzJfYnl0ZXNfdmFsXywgIjAiKTsKKworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX2ludDMyX2VudW0iKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0SW50MzIoc3ViX21lc3NhZ2UsIG1hcF9pbnQzMl9lbnVtX2tleV8sIDApOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldEVudW0oc3ViX21lc3NhZ2UsIG1hcF9pbnQzMl9lbnVtX3ZhbF8sIG1hcF9lbnVtX2Jhcl8pOworCisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbgorICAgICAgLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0SW50MzIoc3ViX21lc3NhZ2UsIG1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2Vfa2V5XywgMCk7CisgIHN1Yl9mb3JlaWduX21lc3NhZ2UgPSBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT4KKyAgICAgIE11dGFibGVNZXNzYWdlKHN1Yl9tZXNzYWdlLCBtYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlX3ZhbF8sIE5VTEwpOworICBzdWJfZm9yZWlnbl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPgorICAgICAgU2V0SW50MzIoc3ViX2ZvcmVpZ25fbWVzc2FnZSwgZm9yZWlnbl9jXywgMCk7CisKKyAgLy8gQWRkIHNlY29uZCBlbGVtZW50CisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfaW50MzJfaW50MzIiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0SW50MzIoc3ViX21lc3NhZ2UsIG1hcF9pbnQzMl9pbnQzMl9rZXlfLCAxKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRJbnQzMihzdWJfbWVzc2FnZSwgbWFwX2ludDMyX2ludDMyX3ZhbF8sIDEpOworCisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfaW50NjRfaW50NjQiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0SW50NjQoc3ViX21lc3NhZ2UsIG1hcF9pbnQ2NF9pbnQ2NF9rZXlfLCAxKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRJbnQ2NChzdWJfbWVzc2FnZSwgbWFwX2ludDY0X2ludDY0X3ZhbF8sIDEpOworCisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfdWludDMyX3VpbnQzMiIpKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRVSW50MzIoc3ViX21lc3NhZ2UsIG1hcF91aW50MzJfdWludDMyX2tleV8sIDEpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldFVJbnQzMihzdWJfbWVzc2FnZSwgbWFwX3VpbnQzMl91aW50MzJfdmFsXywgMSk7CisKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF91aW50NjRfdWludDY0IikpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldFVJbnQ2NChzdWJfbWVzc2FnZSwgbWFwX3VpbnQ2NF91aW50NjRfa2V5XywgMSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0VUludDY0KHN1Yl9tZXNzYWdlLCBtYXBfdWludDY0X3VpbnQ2NF92YWxfLCAxKTsKKworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX3NpbnQzMl9zaW50MzIiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0SW50MzIoc3ViX21lc3NhZ2UsIG1hcF9zaW50MzJfc2ludDMyX2tleV8sIDEpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldEludDMyKHN1Yl9tZXNzYWdlLCBtYXBfc2ludDMyX3NpbnQzMl92YWxfLCAxKTsKKworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX3NpbnQ2NF9zaW50NjQiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0SW50NjQoc3ViX21lc3NhZ2UsIG1hcF9zaW50NjRfc2ludDY0X2tleV8sIDEpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldEludDY0KHN1Yl9tZXNzYWdlLCBtYXBfc2ludDY0X3NpbnQ2NF92YWxfLCAxKTsKKworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX2ZpeGVkMzJfZml4ZWQzMiIpKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRVSW50MzIoc3ViX21lc3NhZ2UsIG1hcF9maXhlZDMyX2ZpeGVkMzJfa2V5XywgMSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCkKKyAgICAgIC0+U2V0VUludDMyKHN1Yl9tZXNzYWdlLCBtYXBfZml4ZWQzMl9maXhlZDMyX3ZhbF8sIDEpOworCisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfZml4ZWQ2NF9maXhlZDY0IikpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldFVJbnQ2NChzdWJfbWVzc2FnZSwgbWFwX2ZpeGVkNjRfZml4ZWQ2NF9rZXlfLCAxKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRVSW50NjQoc3ViX21lc3NhZ2UsIG1hcF9maXhlZDY0X2ZpeGVkNjRfdmFsXywgMSk7CisKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9zZml4ZWQzMl9zZml4ZWQzMiIpKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRJbnQzMihzdWJfbWVzc2FnZSwgbWFwX3NmaXhlZDMyX3NmaXhlZDMyX2tleV8sIDEpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldEludDMyKHN1Yl9tZXNzYWdlLCBtYXBfc2ZpeGVkMzJfc2ZpeGVkMzJfdmFsXywgMSk7CisKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9zZml4ZWQ2NF9zZml4ZWQ2NCIpKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRJbnQ2NChzdWJfbWVzc2FnZSwgbWFwX3NmaXhlZDY0X3NmaXhlZDY0X2tleV8sIDEpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldEludDY0KHN1Yl9tZXNzYWdlLCBtYXBfc2ZpeGVkNjRfc2ZpeGVkNjRfdmFsXywgMSk7CisKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9mbG9hdCIpKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRJbnQzMihzdWJfbWVzc2FnZSwgbWFwX2ludDMyX2Zsb2F0X2tleV8sIDEpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldEZsb2F0KHN1Yl9tZXNzYWdlLCBtYXBfaW50MzJfZmxvYXRfdmFsXywgMS4wKTsKKworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX2ludDMyX2RvdWJsZSIpKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRJbnQzMihzdWJfbWVzc2FnZSwgbWFwX2ludDMyX2RvdWJsZV9rZXlfLCAxKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXREb3VibGUoc3ViX21lc3NhZ2UsIG1hcF9pbnQzMl9kb3VibGVfdmFsXywgMS4wKTsKKworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX2Jvb2xfYm9vbCIpKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRCb29sKHN1Yl9tZXNzYWdlLCBtYXBfYm9vbF9ib29sX2tleV8sIHRydWUpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldEJvb2woc3ViX21lc3NhZ2UsIG1hcF9ib29sX2Jvb2xfdmFsXywgdHJ1ZSk7CisKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9zdHJpbmdfc3RyaW5nIikpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldFN0cmluZyhzdWJfbWVzc2FnZSwgbWFwX3N0cmluZ19zdHJpbmdfa2V5XywgIjEiKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRTdHJpbmcoc3ViX21lc3NhZ2UsIG1hcF9zdHJpbmdfc3RyaW5nX3ZhbF8sICIxIik7CisKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9ieXRlcyIpKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRJbnQzMihzdWJfbWVzc2FnZSwgbWFwX2ludDMyX2J5dGVzX2tleV8sIDEpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldFN0cmluZyhzdWJfbWVzc2FnZSwgbWFwX2ludDMyX2J5dGVzX3ZhbF8sICIxIik7CisKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9lbnVtIikpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldEludDMyKHN1Yl9tZXNzYWdlLCBtYXBfaW50MzJfZW51bV9rZXlfLCAxKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgLT5TZXRFbnVtKHN1Yl9tZXNzYWdlLCBtYXBfaW50MzJfZW51bV92YWxfLCBtYXBfZW51bV9iYXpfKTsKKworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24KKyAgICAgIC0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlIikpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpCisgICAgICAtPlNldEludDMyKHN1Yl9tZXNzYWdlLCBtYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlX2tleV8sIDEpOworICBzdWJfZm9yZWlnbl9tZXNzYWdlID0gc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+CisgICAgICBNdXRhYmxlTWVzc2FnZShzdWJfbWVzc2FnZSwgbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZV92YWxfLCBOVUxMKTsKKyAgc3ViX2ZvcmVpZ25fbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT4KKyAgICAgIFNldEludDMyKHN1Yl9mb3JlaWduX21lc3NhZ2UsIGZvcmVpZ25fY18sIDEpOworfQorCit2b2lkIE1hcFJlZmxlY3Rpb25UZXN0ZXI6OlNldE1hcEZpZWxkc1ZpYU1hcFJlZmxlY3Rpb24oCisgICAgTWVzc2FnZSogbWVzc2FnZSkgeworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpOworCisgIE1lc3NhZ2UqIHN1Yl9mb3JlaWduX21lc3NhZ2UgPSBOVUxMOworICBNYXBWYWx1ZVJlZiBtYXBfdmFsOworCisgIC8vIEFkZCBmaXJzdCBlbGVtZW50LgorICBNYXBLZXkgbWFwX2tleTsKKyAgbWFwX2tleS5TZXRJbnQzMlZhbHVlKDApOworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5JbnNlcnRPckxvb2t1cE1hcFZhbHVlKAorICAgICAgbWVzc2FnZSwgRigibWFwX2ludDMyX2ludDMyIiksIG1hcF9rZXksICZtYXBfdmFsKSk7CisgIG1hcF92YWwuU2V0SW50MzJWYWx1ZSgwKTsKKworICBtYXBfa2V5LlNldEludDY0VmFsdWUoMCk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkluc2VydE9yTG9va3VwTWFwVmFsdWUoCisgICAgICBtZXNzYWdlLCBGKCJtYXBfaW50NjRfaW50NjQiKSwgbWFwX2tleSwgJm1hcF92YWwpKTsKKyAgbWFwX3ZhbC5TZXRJbnQ2NFZhbHVlKDApOworCisgIG1hcF9rZXkuU2V0VUludDMyVmFsdWUoMCk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkluc2VydE9yTG9va3VwTWFwVmFsdWUoCisgICAgICBtZXNzYWdlLCBGKCJtYXBfdWludDMyX3VpbnQzMiIpLCBtYXBfa2V5LCAmbWFwX3ZhbCkpOworICBtYXBfdmFsLlNldFVJbnQzMlZhbHVlKDApOworCisgIG1hcF9rZXkuU2V0VUludDY0VmFsdWUoMCk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkluc2VydE9yTG9va3VwTWFwVmFsdWUoCisgICAgICBtZXNzYWdlLCBGKCJtYXBfdWludDY0X3VpbnQ2NCIpLCBtYXBfa2V5LCAmbWFwX3ZhbCkpOworICBtYXBfdmFsLlNldFVJbnQ2NFZhbHVlKDApOworCisgIG1hcF9rZXkuU2V0SW50MzJWYWx1ZSgwKTsKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+SW5zZXJ0T3JMb29rdXBNYXBWYWx1ZSgKKyAgICAgIG1lc3NhZ2UsIEYoIm1hcF9zaW50MzJfc2ludDMyIiksIG1hcF9rZXksICZtYXBfdmFsKSk7CisgIG1hcF92YWwuU2V0SW50MzJWYWx1ZSgwKTsKKworICBtYXBfa2V5LlNldEludDY0VmFsdWUoMCk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkluc2VydE9yTG9va3VwTWFwVmFsdWUoCisgICAgICBtZXNzYWdlLCBGKCJtYXBfc2ludDY0X3NpbnQ2NCIpLCBtYXBfa2V5LCAmbWFwX3ZhbCkpOworICBtYXBfdmFsLlNldEludDY0VmFsdWUoMCk7CisKKyAgbWFwX2tleS5TZXRVSW50MzJWYWx1ZSgwKTsKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+SW5zZXJ0T3JMb29rdXBNYXBWYWx1ZSgKKyAgICAgIG1lc3NhZ2UsIEYoIm1hcF9maXhlZDMyX2ZpeGVkMzIiKSwgbWFwX2tleSwgJm1hcF92YWwpKTsKKyAgbWFwX3ZhbC5TZXRVSW50MzJWYWx1ZSgwKTsKKworICBtYXBfa2V5LlNldFVJbnQ2NFZhbHVlKDApOworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5JbnNlcnRPckxvb2t1cE1hcFZhbHVlKAorICAgICAgbWVzc2FnZSwgRigibWFwX2ZpeGVkNjRfZml4ZWQ2NCIpLCBtYXBfa2V5LCAmbWFwX3ZhbCkpOworICBtYXBfdmFsLlNldFVJbnQ2NFZhbHVlKDApOworCisgIG1hcF9rZXkuU2V0SW50MzJWYWx1ZSgwKTsKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+SW5zZXJ0T3JMb29rdXBNYXBWYWx1ZSgKKyAgICAgIG1lc3NhZ2UsIEYoIm1hcF9zZml4ZWQzMl9zZml4ZWQzMiIpLCBtYXBfa2V5LCAmbWFwX3ZhbCkpOworICBtYXBfdmFsLlNldEludDMyVmFsdWUoMCk7CisKKyAgbWFwX2tleS5TZXRJbnQ2NFZhbHVlKDApOworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5JbnNlcnRPckxvb2t1cE1hcFZhbHVlKAorICAgICAgbWVzc2FnZSwgRigibWFwX3NmaXhlZDY0X3NmaXhlZDY0IiksIG1hcF9rZXksICZtYXBfdmFsKSk7CisgIG1hcF92YWwuU2V0SW50NjRWYWx1ZSgwKTsKKworICBtYXBfa2V5LlNldEludDMyVmFsdWUoMCk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkluc2VydE9yTG9va3VwTWFwVmFsdWUoCisgICAgICBtZXNzYWdlLCBGKCJtYXBfaW50MzJfZmxvYXQiKSwgbWFwX2tleSwgJm1hcF92YWwpKTsKKyAgbWFwX3ZhbC5TZXRGbG9hdFZhbHVlKDAuMCk7CisKKyAgbWFwX2tleS5TZXRJbnQzMlZhbHVlKDApOworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5JbnNlcnRPckxvb2t1cE1hcFZhbHVlKAorICAgICAgbWVzc2FnZSwgRigibWFwX2ludDMyX2RvdWJsZSIpLCBtYXBfa2V5LCAmbWFwX3ZhbCkpOworICBtYXBfdmFsLlNldERvdWJsZVZhbHVlKDAuMCk7CisKKyAgbWFwX2tleS5TZXRCb29sVmFsdWUoZmFsc2UpOworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5JbnNlcnRPckxvb2t1cE1hcFZhbHVlKAorICAgICAgbWVzc2FnZSwgRigibWFwX2Jvb2xfYm9vbCIpLCBtYXBfa2V5LCAmbWFwX3ZhbCkpOworICBtYXBfdmFsLlNldEJvb2xWYWx1ZShmYWxzZSk7CisKKyAgbWFwX2tleS5TZXRTdHJpbmdWYWx1ZSgiMCIpOworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5JbnNlcnRPckxvb2t1cE1hcFZhbHVlKAorICAgICAgbWVzc2FnZSwgRigibWFwX3N0cmluZ19zdHJpbmciKSwgbWFwX2tleSwgJm1hcF92YWwpKTsKKyAgbWFwX3ZhbC5TZXRTdHJpbmdWYWx1ZSgiMCIpOworCisgIG1hcF9rZXkuU2V0SW50MzJWYWx1ZSgwKTsKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+SW5zZXJ0T3JMb29rdXBNYXBWYWx1ZSgKKyAgICAgIG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9ieXRlcyIpLCBtYXBfa2V5LCAmbWFwX3ZhbCkpOworICBtYXBfdmFsLlNldFN0cmluZ1ZhbHVlKCIwIik7CisKKyAgbWFwX2tleS5TZXRJbnQzMlZhbHVlKDApOworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5JbnNlcnRPckxvb2t1cE1hcFZhbHVlKAorICAgICAgbWVzc2FnZSwgRigibWFwX2ludDMyX2VudW0iKSwgbWFwX2tleSwgJm1hcF92YWwpKTsKKyAgbWFwX3ZhbC5TZXRFbnVtVmFsdWUobWFwX2VudW1fYmFyXy0+bnVtYmVyKCkpOworCisgIG1hcF9rZXkuU2V0SW50MzJWYWx1ZSgwKTsKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+SW5zZXJ0T3JMb29rdXBNYXBWYWx1ZSgKKyAgICAgIG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UiKSwgbWFwX2tleSwgJm1hcF92YWwpKTsKKyAgc3ViX2ZvcmVpZ25fbWVzc2FnZSA9IG1hcF92YWwuTXV0YWJsZU1lc3NhZ2VWYWx1ZSgpOworICBzdWJfZm9yZWlnbl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlNldEludDMyKAorICAgICAgc3ViX2ZvcmVpZ25fbWVzc2FnZSwgZm9yZWlnbl9jXywgMCk7CisKKyAgLy8gQWRkIHNlY29uZCBlbGVtZW50CisgIG1hcF9rZXkuU2V0SW50MzJWYWx1ZSgxKTsKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+SW5zZXJ0T3JMb29rdXBNYXBWYWx1ZSgKKyAgICAgIG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9pbnQzMiIpLCBtYXBfa2V5LCAmbWFwX3ZhbCkpOworICBtYXBfdmFsLlNldEludDMyVmFsdWUoMSk7CisgIEVYUEVDVF9GQUxTRShyZWZsZWN0aW9uLT5JbnNlcnRPckxvb2t1cE1hcFZhbHVlKAorICAgICAgbWVzc2FnZSwgRigibWFwX2ludDMyX2ludDMyIiksIG1hcF9rZXksICZtYXBfdmFsKSk7CisKKyAgbWFwX2tleS5TZXRJbnQ2NFZhbHVlKDEpOworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5JbnNlcnRPckxvb2t1cE1hcFZhbHVlKAorICAgICAgbWVzc2FnZSwgRigibWFwX2ludDY0X2ludDY0IiksIG1hcF9rZXksICZtYXBfdmFsKSk7CisgIG1hcF92YWwuU2V0SW50NjRWYWx1ZSgxKTsKKyAgRVhQRUNUX0ZBTFNFKHJlZmxlY3Rpb24tPkluc2VydE9yTG9va3VwTWFwVmFsdWUoCisgICAgICBtZXNzYWdlLCBGKCJtYXBfaW50NjRfaW50NjQiKSwgbWFwX2tleSwgJm1hcF92YWwpKTsKKworICBtYXBfa2V5LlNldFVJbnQzMlZhbHVlKDEpOworICByZWZsZWN0aW9uLT5JbnNlcnRPckxvb2t1cE1hcFZhbHVlKAorICAgICAgbWVzc2FnZSwgRigibWFwX3VpbnQzMl91aW50MzIiKSwgbWFwX2tleSwgJm1hcF92YWwpOworICBtYXBfdmFsLlNldFVJbnQzMlZhbHVlKDEpOworCisgIG1hcF9rZXkuU2V0VUludDY0VmFsdWUoMSk7CisgIHJlZmxlY3Rpb24tPkluc2VydE9yTG9va3VwTWFwVmFsdWUoCisgICAgICBtZXNzYWdlLCBGKCJtYXBfdWludDY0X3VpbnQ2NCIpLCBtYXBfa2V5LCAmbWFwX3ZhbCk7CisgIG1hcF92YWwuU2V0VUludDY0VmFsdWUoMSk7CisKKyAgbWFwX2tleS5TZXRJbnQzMlZhbHVlKDEpOworICByZWZsZWN0aW9uLT5JbnNlcnRPckxvb2t1cE1hcFZhbHVlKAorICAgICAgbWVzc2FnZSwgRigibWFwX3NpbnQzMl9zaW50MzIiKSwgbWFwX2tleSwgJm1hcF92YWwpOworICBtYXBfdmFsLlNldEludDMyVmFsdWUoMSk7CisKKyAgbWFwX2tleS5TZXRJbnQ2NFZhbHVlKDEpOworICByZWZsZWN0aW9uLT5JbnNlcnRPckxvb2t1cE1hcFZhbHVlKAorICAgICAgbWVzc2FnZSwgRigibWFwX3NpbnQ2NF9zaW50NjQiKSwgbWFwX2tleSwgJm1hcF92YWwpOworICBtYXBfdmFsLlNldEludDY0VmFsdWUoMSk7CisKKyAgbWFwX2tleS5TZXRVSW50MzJWYWx1ZSgxKTsKKyAgcmVmbGVjdGlvbi0+SW5zZXJ0T3JMb29rdXBNYXBWYWx1ZSgKKyAgICAgIG1lc3NhZ2UsIEYoIm1hcF9maXhlZDMyX2ZpeGVkMzIiKSwgbWFwX2tleSwgJm1hcF92YWwpOworICBtYXBfdmFsLlNldFVJbnQzMlZhbHVlKDEpOworCisgIG1hcF9rZXkuU2V0VUludDY0VmFsdWUoMSk7CisgIHJlZmxlY3Rpb24tPkluc2VydE9yTG9va3VwTWFwVmFsdWUoCisgICAgICBtZXNzYWdlLCBGKCJtYXBfZml4ZWQ2NF9maXhlZDY0IiksIG1hcF9rZXksICZtYXBfdmFsKTsKKyAgbWFwX3ZhbC5TZXRVSW50NjRWYWx1ZSgxKTsKKworICBtYXBfa2V5LlNldEludDMyVmFsdWUoMSk7CisgIHJlZmxlY3Rpb24tPkluc2VydE9yTG9va3VwTWFwVmFsdWUoCisgICAgICBtZXNzYWdlLCBGKCJtYXBfc2ZpeGVkMzJfc2ZpeGVkMzIiKSwgbWFwX2tleSwgJm1hcF92YWwpOworICBtYXBfdmFsLlNldEludDMyVmFsdWUoMSk7CisKKyAgbWFwX2tleS5TZXRJbnQ2NFZhbHVlKDEpOworICByZWZsZWN0aW9uLT5JbnNlcnRPckxvb2t1cE1hcFZhbHVlKAorICAgICAgbWVzc2FnZSwgRigibWFwX3NmaXhlZDY0X3NmaXhlZDY0IiksIG1hcF9rZXksICZtYXBfdmFsKTsKKyAgbWFwX3ZhbC5TZXRJbnQ2NFZhbHVlKDEpOworCisgIG1hcF9rZXkuU2V0SW50MzJWYWx1ZSgxKTsKKyAgcmVmbGVjdGlvbi0+SW5zZXJ0T3JMb29rdXBNYXBWYWx1ZSgKKyAgICAgIG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9mbG9hdCIpLCBtYXBfa2V5LCAmbWFwX3ZhbCk7CisgIG1hcF92YWwuU2V0RmxvYXRWYWx1ZSgxLjApOworCisgIG1hcF9rZXkuU2V0SW50MzJWYWx1ZSgxKTsKKyAgcmVmbGVjdGlvbi0+SW5zZXJ0T3JMb29rdXBNYXBWYWx1ZSgKKyAgICAgIG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9kb3VibGUiKSwgbWFwX2tleSwgJm1hcF92YWwpOworICBtYXBfdmFsLlNldERvdWJsZVZhbHVlKDEuMCk7CisKKyAgbWFwX2tleS5TZXRCb29sVmFsdWUodHJ1ZSk7CisgIHJlZmxlY3Rpb24tPkluc2VydE9yTG9va3VwTWFwVmFsdWUoCisgICAgICBtZXNzYWdlLCBGKCJtYXBfYm9vbF9ib29sIiksIG1hcF9rZXksICZtYXBfdmFsKTsKKyAgbWFwX3ZhbC5TZXRCb29sVmFsdWUodHJ1ZSk7CisKKyAgbWFwX2tleS5TZXRTdHJpbmdWYWx1ZSgiMSIpOworICByZWZsZWN0aW9uLT5JbnNlcnRPckxvb2t1cE1hcFZhbHVlKAorICAgICAgbWVzc2FnZSwgRigibWFwX3N0cmluZ19zdHJpbmciKSwgbWFwX2tleSwgJm1hcF92YWwpOworICBtYXBfdmFsLlNldFN0cmluZ1ZhbHVlKCIxIik7CisKKyAgbWFwX2tleS5TZXRJbnQzMlZhbHVlKDEpOworICByZWZsZWN0aW9uLT5JbnNlcnRPckxvb2t1cE1hcFZhbHVlKAorICAgICAgbWVzc2FnZSwgRigibWFwX2ludDMyX2J5dGVzIiksIG1hcF9rZXksICZtYXBfdmFsKTsKKyAgbWFwX3ZhbC5TZXRTdHJpbmdWYWx1ZSgiMSIpOworCisgIG1hcF9rZXkuU2V0SW50MzJWYWx1ZSgxKTsKKyAgcmVmbGVjdGlvbi0+SW5zZXJ0T3JMb29rdXBNYXBWYWx1ZSgKKyAgICAgIG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9lbnVtIiksIG1hcF9rZXksICZtYXBfdmFsKTsKKyAgbWFwX3ZhbC5TZXRFbnVtVmFsdWUobWFwX2VudW1fYmF6Xy0+bnVtYmVyKCkpOworCisgIG1hcF9rZXkuU2V0SW50MzJWYWx1ZSgxKTsKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+SW5zZXJ0T3JMb29rdXBNYXBWYWx1ZSgKKyAgICAgIG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UiKSwgbWFwX2tleSwgJm1hcF92YWwpKTsKKyAgc3ViX2ZvcmVpZ25fbWVzc2FnZSA9IG1hcF92YWwuTXV0YWJsZU1lc3NhZ2VWYWx1ZSgpOworICBzdWJfZm9yZWlnbl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlNldEludDMyKAorICAgICAgc3ViX2ZvcmVpZ25fbWVzc2FnZSwgZm9yZWlnbl9jXywgMSk7Cit9CisKK3ZvaWQgTWFwUmVmbGVjdGlvblRlc3Rlcjo6Q2xlYXJNYXBGaWVsZHNWaWFSZWZsZWN0aW9uKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UpIHsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKTsKKworICByZWZsZWN0aW9uLT5DbGVhckZpZWxkKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9pbnQzMiIpKTsKKyAgcmVmbGVjdGlvbi0+Q2xlYXJGaWVsZChtZXNzYWdlLCBGKCJtYXBfaW50NjRfaW50NjQiKSk7CisgIHJlZmxlY3Rpb24tPkNsZWFyRmllbGQobWVzc2FnZSwgRigibWFwX3VpbnQzMl91aW50MzIiKSk7CisgIHJlZmxlY3Rpb24tPkNsZWFyRmllbGQobWVzc2FnZSwgRigibWFwX3VpbnQ2NF91aW50NjQiKSk7CisgIHJlZmxlY3Rpb24tPkNsZWFyRmllbGQobWVzc2FnZSwgRigibWFwX3NpbnQzMl9zaW50MzIiKSk7CisgIHJlZmxlY3Rpb24tPkNsZWFyRmllbGQobWVzc2FnZSwgRigibWFwX3NpbnQ2NF9zaW50NjQiKSk7CisgIHJlZmxlY3Rpb24tPkNsZWFyRmllbGQobWVzc2FnZSwgRigibWFwX2ZpeGVkMzJfZml4ZWQzMiIpKTsKKyAgcmVmbGVjdGlvbi0+Q2xlYXJGaWVsZChtZXNzYWdlLCBGKCJtYXBfZml4ZWQ2NF9maXhlZDY0IikpOworICByZWZsZWN0aW9uLT5DbGVhckZpZWxkKG1lc3NhZ2UsIEYoIm1hcF9zZml4ZWQzMl9zZml4ZWQzMiIpKTsKKyAgcmVmbGVjdGlvbi0+Q2xlYXJGaWVsZChtZXNzYWdlLCBGKCJtYXBfc2ZpeGVkNjRfc2ZpeGVkNjQiKSk7CisgIHJlZmxlY3Rpb24tPkNsZWFyRmllbGQobWVzc2FnZSwgRigibWFwX2ludDMyX2Zsb2F0IikpOworICByZWZsZWN0aW9uLT5DbGVhckZpZWxkKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9kb3VibGUiKSk7CisgIHJlZmxlY3Rpb24tPkNsZWFyRmllbGQobWVzc2FnZSwgRigibWFwX2Jvb2xfYm9vbCIpKTsKKyAgcmVmbGVjdGlvbi0+Q2xlYXJGaWVsZChtZXNzYWdlLCBGKCJtYXBfc3RyaW5nX3N0cmluZyIpKTsKKyAgcmVmbGVjdGlvbi0+Q2xlYXJGaWVsZChtZXNzYWdlLCBGKCJtYXBfaW50MzJfYnl0ZXMiKSk7CisgIHJlZmxlY3Rpb24tPkNsZWFyRmllbGQobWVzc2FnZSwgRigibWFwX2ludDMyX2VudW0iKSk7CisgIHJlZmxlY3Rpb24tPkNsZWFyRmllbGQobWVzc2FnZSwgRigibWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSIpKTsKK30KKwordm9pZCBNYXBSZWZsZWN0aW9uVGVzdGVyOjpNb2RpZnlNYXBGaWVsZHNWaWFSZWZsZWN0aW9uKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UpIHsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKTsKKyAgTWFwVmFsdWVSZWYgbWFwX3ZhbDsKKyAgTWVzc2FnZSogc3ViX2ZvcmVpZ25fbWVzc2FnZTsKKworICAvLyBNb2RpZnkgdGhlIHNlY29uZCBlbGVtZW50CisgIE1hcEtleSBtYXBfa2V5OworICBtYXBfa2V5LlNldEludDMyVmFsdWUoMSk7CisgIEVYUEVDVF9GQUxTRShyZWZsZWN0aW9uLT5JbnNlcnRPckxvb2t1cE1hcFZhbHVlKAorICAgICAgbWVzc2FnZSwgRigibWFwX2ludDMyX2ludDMyIiksIG1hcF9rZXksICZtYXBfdmFsKSk7CisgIG1hcF92YWwuU2V0SW50MzJWYWx1ZSgyKTsKKworICBtYXBfa2V5LlNldEludDY0VmFsdWUoMSk7CisgIEVYUEVDVF9GQUxTRShyZWZsZWN0aW9uLT5JbnNlcnRPckxvb2t1cE1hcFZhbHVlKAorICAgICAgbWVzc2FnZSwgRigibWFwX2ludDY0X2ludDY0IiksIG1hcF9rZXksICZtYXBfdmFsKSk7CisgIG1hcF92YWwuU2V0SW50NjRWYWx1ZSgyKTsKKworICBtYXBfa2V5LlNldFVJbnQzMlZhbHVlKDEpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SW5zZXJ0T3JMb29rdXBNYXBWYWx1ZSgKKyAgICAgIG1lc3NhZ2UsIEYoIm1hcF91aW50MzJfdWludDMyIiksIG1hcF9rZXksICZtYXBfdmFsKSk7CisgIG1hcF92YWwuU2V0VUludDMyVmFsdWUoMik7CisKKyAgbWFwX2tleS5TZXRVSW50NjRWYWx1ZSgxKTsKKyAgcmVmbGVjdGlvbi0+SW5zZXJ0T3JMb29rdXBNYXBWYWx1ZSgKKyAgICAgIG1lc3NhZ2UsIEYoIm1hcF91aW50NjRfdWludDY0IiksIG1hcF9rZXksICZtYXBfdmFsKTsKKyAgbWFwX3ZhbC5TZXRVSW50NjRWYWx1ZSgyKTsKKworICBtYXBfa2V5LlNldEludDMyVmFsdWUoMSk7CisgIHJlZmxlY3Rpb24tPkluc2VydE9yTG9va3VwTWFwVmFsdWUoCisgICAgICBtZXNzYWdlLCBGKCJtYXBfc2ludDMyX3NpbnQzMiIpLCBtYXBfa2V5LCAmbWFwX3ZhbCk7CisgIG1hcF92YWwuU2V0SW50MzJWYWx1ZSgyKTsKKworICBtYXBfa2V5LlNldEludDY0VmFsdWUoMSk7CisgIHJlZmxlY3Rpb24tPkluc2VydE9yTG9va3VwTWFwVmFsdWUoCisgICAgICBtZXNzYWdlLCBGKCJtYXBfc2ludDY0X3NpbnQ2NCIpLCBtYXBfa2V5LCAmbWFwX3ZhbCk7CisgIG1hcF92YWwuU2V0SW50NjRWYWx1ZSgyKTsKKworICBtYXBfa2V5LlNldFVJbnQzMlZhbHVlKDEpOworICByZWZsZWN0aW9uLT5JbnNlcnRPckxvb2t1cE1hcFZhbHVlKAorICAgICAgbWVzc2FnZSwgRigibWFwX2ZpeGVkMzJfZml4ZWQzMiIpLCBtYXBfa2V5LCAmbWFwX3ZhbCk7CisgIG1hcF92YWwuU2V0VUludDMyVmFsdWUoMik7CisKKyAgbWFwX2tleS5TZXRVSW50NjRWYWx1ZSgxKTsKKyAgcmVmbGVjdGlvbi0+SW5zZXJ0T3JMb29rdXBNYXBWYWx1ZSgKKyAgICAgIG1lc3NhZ2UsIEYoIm1hcF9maXhlZDY0X2ZpeGVkNjQiKSwgbWFwX2tleSwgJm1hcF92YWwpOworICBtYXBfdmFsLlNldFVJbnQ2NFZhbHVlKDIpOworCisgIG1hcF9rZXkuU2V0SW50MzJWYWx1ZSgxKTsKKyAgcmVmbGVjdGlvbi0+SW5zZXJ0T3JMb29rdXBNYXBWYWx1ZSgKKyAgICAgIG1lc3NhZ2UsIEYoIm1hcF9zZml4ZWQzMl9zZml4ZWQzMiIpLCBtYXBfa2V5LCAmbWFwX3ZhbCk7CisgIG1hcF92YWwuU2V0SW50MzJWYWx1ZSgyKTsKKworICBtYXBfa2V5LlNldEludDY0VmFsdWUoMSk7CisgIHJlZmxlY3Rpb24tPkluc2VydE9yTG9va3VwTWFwVmFsdWUoCisgICAgICBtZXNzYWdlLCBGKCJtYXBfc2ZpeGVkNjRfc2ZpeGVkNjQiKSwgbWFwX2tleSwgJm1hcF92YWwpOworICBtYXBfdmFsLlNldEludDY0VmFsdWUoMik7CisKKyAgbWFwX2tleS5TZXRJbnQzMlZhbHVlKDEpOworICByZWZsZWN0aW9uLT5JbnNlcnRPckxvb2t1cE1hcFZhbHVlKAorICAgICAgbWVzc2FnZSwgRigibWFwX2ludDMyX2Zsb2F0IiksIG1hcF9rZXksICZtYXBfdmFsKTsKKyAgbWFwX3ZhbC5TZXRGbG9hdFZhbHVlKDIuMCk7CisKKyAgbWFwX2tleS5TZXRJbnQzMlZhbHVlKDEpOworICByZWZsZWN0aW9uLT5JbnNlcnRPckxvb2t1cE1hcFZhbHVlKAorICAgICAgbWVzc2FnZSwgRigibWFwX2ludDMyX2RvdWJsZSIpLCBtYXBfa2V5LCAmbWFwX3ZhbCk7CisgIG1hcF92YWwuU2V0RG91YmxlVmFsdWUoMi4wKTsKKworICBtYXBfa2V5LlNldEJvb2xWYWx1ZSh0cnVlKTsKKyAgcmVmbGVjdGlvbi0+SW5zZXJ0T3JMb29rdXBNYXBWYWx1ZSgKKyAgICAgIG1lc3NhZ2UsIEYoIm1hcF9ib29sX2Jvb2wiKSwgbWFwX2tleSwgJm1hcF92YWwpOworICBtYXBfdmFsLlNldEJvb2xWYWx1ZShmYWxzZSk7CisKKyAgbWFwX2tleS5TZXRTdHJpbmdWYWx1ZSgiMSIpOworICByZWZsZWN0aW9uLT5JbnNlcnRPckxvb2t1cE1hcFZhbHVlKAorICAgICAgbWVzc2FnZSwgRigibWFwX3N0cmluZ19zdHJpbmciKSwgbWFwX2tleSwgJm1hcF92YWwpOworICBtYXBfdmFsLlNldFN0cmluZ1ZhbHVlKCIyIik7CisKKyAgbWFwX2tleS5TZXRJbnQzMlZhbHVlKDEpOworICByZWZsZWN0aW9uLT5JbnNlcnRPckxvb2t1cE1hcFZhbHVlKAorICAgICAgbWVzc2FnZSwgRigibWFwX2ludDMyX2J5dGVzIiksIG1hcF9rZXksICZtYXBfdmFsKTsKKyAgbWFwX3ZhbC5TZXRTdHJpbmdWYWx1ZSgiMiIpOworCisgIG1hcF9rZXkuU2V0SW50MzJWYWx1ZSgxKTsKKyAgcmVmbGVjdGlvbi0+SW5zZXJ0T3JMb29rdXBNYXBWYWx1ZSgKKyAgICAgIG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9lbnVtIiksIG1hcF9rZXksICZtYXBfdmFsKTsKKyAgbWFwX3ZhbC5TZXRFbnVtVmFsdWUobWFwX2VudW1fZm9vXy0+bnVtYmVyKCkpOworCisgIG1hcF9rZXkuU2V0SW50MzJWYWx1ZSgxKTsKKyAgRVhQRUNUX0ZBTFNFKHJlZmxlY3Rpb24tPkluc2VydE9yTG9va3VwTWFwVmFsdWUoCisgICAgICBtZXNzYWdlLCBGKCJtYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlIiksIG1hcF9rZXksICZtYXBfdmFsKSk7CisgIHN1Yl9mb3JlaWduX21lc3NhZ2UgPSBtYXBfdmFsLk11dGFibGVNZXNzYWdlVmFsdWUoKTsKKyAgc3ViX2ZvcmVpZ25fbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5TZXRJbnQzMigKKyAgICAgIHN1Yl9mb3JlaWduX21lc3NhZ2UsIGZvcmVpZ25fY18sIDIpOworfQorCit2b2lkIE1hcFJlZmxlY3Rpb25UZXN0ZXI6OlJlbW92ZUxhc3RNYXBzVmlhUmVmbGVjdGlvbigKKyAgICBNZXNzYWdlKiBtZXNzYWdlKSB7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCk7CisKKyAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+IG91dHB1dDsKKyAgcmVmbGVjdGlvbi0+TGlzdEZpZWxkcygqbWVzc2FnZSwgJm91dHB1dCk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgb3V0cHV0LnNpemUoKTsgKytpKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IG91dHB1dFtpXTsKKyAgICBpZiAoIWZpZWxkLT5pc19yZXBlYXRlZCgpKSBjb250aW51ZTsKKyAgICByZWZsZWN0aW9uLT5SZW1vdmVMYXN0KG1lc3NhZ2UsIGZpZWxkKTsKKyAgfQorfQorCit2b2lkIE1hcFJlZmxlY3Rpb25UZXN0ZXI6OlJlbGVhc2VMYXN0TWFwc1ZpYVJlZmxlY3Rpb24oCisgICAgTWVzc2FnZSogbWVzc2FnZSkgeworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpOworCisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBvdXRwdXQ7CisgIHJlZmxlY3Rpb24tPkxpc3RGaWVsZHMoKm1lc3NhZ2UsICZvdXRwdXQpOworICBmb3IgKGludCBpID0gMDsgaSA8IG91dHB1dC5zaXplKCk7ICsraSkgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBvdXRwdXRbaV07CisgICAgaWYgKCFmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgY29udGludWU7CisgICAgaWYgKGZpZWxkLT5jcHBfdHlwZSgpICE9IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFKSBjb250aW51ZTsKKworICAgIE1lc3NhZ2UqIHJlbGVhc2VkID0gcmVmbGVjdGlvbi0+UmVsZWFzZUxhc3QobWVzc2FnZSwgZmllbGQpOworICAgIEFTU0VSVF9UUlVFKHJlbGVhc2VkICE9IE5VTEwpIDw8ICJSZWxlYXNlTGFzdCByZXR1cm5lZCBOVUxMIGZvcjogIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDw8IGZpZWxkLT5uYW1lKCk7CisgICAgZGVsZXRlIHJlbGVhc2VkOworICB9Cit9CisKK3ZvaWQgTWFwUmVmbGVjdGlvblRlc3Rlcjo6U3dhcE1hcHNWaWFSZWZsZWN0aW9uKE1lc3NhZ2UqIG1lc3NhZ2UpIHsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKTsKKyAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+IG91dHB1dDsKKyAgcmVmbGVjdGlvbi0+TGlzdEZpZWxkcygqbWVzc2FnZSwgJm91dHB1dCk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgb3V0cHV0LnNpemUoKTsgKytpKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IG91dHB1dFtpXTsKKyAgICBpZiAoIWZpZWxkLT5pc19yZXBlYXRlZCgpKSBjb250aW51ZTsKKyAgICByZWZsZWN0aW9uLT5Td2FwRWxlbWVudHMobWVzc2FnZSwgZmllbGQsIDAsIDEpOworICB9Cit9CisKK3ZvaWQgTWFwUmVmbGVjdGlvblRlc3Rlcjo6CisgICAgTXV0YWJsZVVua25vd25GaWVsZHNPZk1hcEZpZWxkc1ZpYVJlZmxlY3Rpb24oTWVzc2FnZSogbWVzc2FnZSkgeworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpOworICBNZXNzYWdlKiBzdWJfbWVzc2FnZSA9IE5VTEw7CisKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9pbnQzMiIpKTsKKyAgRVhQRUNUX1RSVUUoc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+TXV0YWJsZVVua25vd25GaWVsZHMoc3ViX21lc3NhZ2UpICE9CisgICAgICAgICAgICAgIE5VTEwpOworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX2ludDY0X2ludDY0IikpOworICBFWFBFQ1RfVFJVRShzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5NdXRhYmxlVW5rbm93bkZpZWxkcyhzdWJfbWVzc2FnZSkgIT0KKyAgICAgICAgICAgICAgTlVMTCk7CisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfdWludDMyX3VpbnQzMiIpKTsKKyAgRVhQRUNUX1RSVUUoc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+TXV0YWJsZVVua25vd25GaWVsZHMoc3ViX21lc3NhZ2UpICE9CisgICAgICAgICAgICAgIE5VTEwpOworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX3VpbnQ2NF91aW50NjQiKSk7CisgIEVYUEVDVF9UUlVFKHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPk11dGFibGVVbmtub3duRmllbGRzKHN1Yl9tZXNzYWdlKSAhPQorICAgICAgICAgICAgICBOVUxMKTsKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9zaW50MzJfc2ludDMyIikpOworICBFWFBFQ1RfVFJVRShzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5NdXRhYmxlVW5rbm93bkZpZWxkcyhzdWJfbWVzc2FnZSkgIT0KKyAgICAgICAgICAgICAgTlVMTCk7CisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfc2ludDY0X3NpbnQ2NCIpKTsKKyAgRVhQRUNUX1RSVUUoc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+TXV0YWJsZVVua25vd25GaWVsZHMoc3ViX21lc3NhZ2UpICE9CisgICAgICAgICAgICAgIE5VTEwpOworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX2ZpeGVkMzJfZml4ZWQzMiIpKTsKKyAgRVhQRUNUX1RSVUUoc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+TXV0YWJsZVVua25vd25GaWVsZHMoc3ViX21lc3NhZ2UpICE9CisgICAgICAgICAgICAgIE5VTEwpOworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX2ZpeGVkNjRfZml4ZWQ2NCIpKTsKKyAgRVhQRUNUX1RSVUUoc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+TXV0YWJsZVVua25vd25GaWVsZHMoc3ViX21lc3NhZ2UpICE9CisgICAgICAgICAgICAgIE5VTEwpOworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX3NmaXhlZDMyX3NmaXhlZDMyIikpOworICBFWFBFQ1RfVFJVRShzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5NdXRhYmxlVW5rbm93bkZpZWxkcyhzdWJfbWVzc2FnZSkgIT0KKyAgICAgICAgICAgICAgTlVMTCk7CisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfc2ZpeGVkNjRfc2ZpeGVkNjQiKSk7CisgIEVYUEVDVF9UUlVFKHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPk11dGFibGVVbmtub3duRmllbGRzKHN1Yl9tZXNzYWdlKSAhPQorICAgICAgICAgICAgICBOVUxMKTsKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9mbG9hdCIpKTsKKyAgRVhQRUNUX1RSVUUoc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+TXV0YWJsZVVua25vd25GaWVsZHMoc3ViX21lc3NhZ2UpICE9CisgICAgICAgICAgICAgIE5VTEwpOworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX2ludDMyX2RvdWJsZSIpKTsKKyAgRVhQRUNUX1RSVUUoc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+TXV0YWJsZVVua25vd25GaWVsZHMoc3ViX21lc3NhZ2UpICE9CisgICAgICAgICAgICAgIE5VTEwpOworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX2Jvb2xfYm9vbCIpKTsKKyAgRVhQRUNUX1RSVUUoc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+TXV0YWJsZVVua25vd25GaWVsZHMoc3ViX21lc3NhZ2UpICE9CisgICAgICAgICAgICAgIE5VTEwpOworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX3N0cmluZ19zdHJpbmciKSk7CisgIEVYUEVDVF9UUlVFKHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPk11dGFibGVVbmtub3duRmllbGRzKHN1Yl9tZXNzYWdlKSAhPQorICAgICAgICAgICAgICBOVUxMKTsKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9ieXRlcyIpKTsKKyAgRVhQRUNUX1RSVUUoc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+TXV0YWJsZVVua25vd25GaWVsZHMoc3ViX21lc3NhZ2UpICE9CisgICAgICAgICAgICAgIE5VTEwpOworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX2ludDMyX2VudW0iKSk7CisgIEVYUEVDVF9UUlVFKHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPk11dGFibGVVbmtub3duRmllbGRzKHN1Yl9tZXNzYWdlKSAhPQorICAgICAgICAgICAgICBOVUxMKTsKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UiKSk7CisgIEVYUEVDVF9UUlVFKHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPk11dGFibGVVbmtub3duRmllbGRzKHN1Yl9tZXNzYWdlKSAhPQorICAgICAgICAgICAgICBOVUxMKTsKK30KKwordm9pZCBNYXBSZWZsZWN0aW9uVGVzdGVyOjpFeHBlY3RNYXBGaWVsZHNTZXRWaWFSZWZsZWN0aW9uKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UpIHsKKyAgc3RyaW5nIHNjcmF0Y2g7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKTsKKyAgY29uc3QgTWVzc2FnZSogc3ViX21lc3NhZ2U7CisgIE1hcEtleSBtYXBfa2V5OworCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJtYXBfaW50MzJfaW50MzIiKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoIm1hcF9pbnQ2NF9pbnQ2NCIpKSk7CisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigibWFwX3VpbnQzMl91aW50MzIiKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoIm1hcF91aW50NjRfdWludDY0IikpKTsKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJtYXBfc2ludDMyX3NpbnQzMiIpKSk7CisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigibWFwX3NpbnQ2NF9zaW50NjQiKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoIm1hcF9maXhlZDMyX2ZpeGVkMzIiKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoIm1hcF9maXhlZDY0X2ZpeGVkNjQiKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoIm1hcF9zZml4ZWQzMl9zZml4ZWQzMiIpKSk7CisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigibWFwX3NmaXhlZDY0X3NmaXhlZDY0IikpKTsKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJtYXBfaW50MzJfZmxvYXQiKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9kb3VibGUiKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoIm1hcF9ib29sX2Jvb2wiKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoIm1hcF9zdHJpbmdfc3RyaW5nIikpKTsKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJtYXBfaW50MzJfYnl0ZXMiKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9lbnVtIikpKTsKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJtYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlIikpKTsKKworICB7CisgICAgc3RkOjptYXA8aW50MzIsIGludDMyPiBtYXA7CisgICAgbWFwWzBdID0gMDsKKyAgICBtYXBbMV0gPSAxOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjsgaSsrKSB7CisgICAgICAvLyBDaGVjayB3aXRoIFJlcGVhdGVkRmllbGQgUmVmbGVjdGlvbgorICAgICAgc3ViX21lc3NhZ2UgPQorICAgICAgICAgICZyZWZsZWN0aW9uLT5HZXRSZXBlYXRlZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX2ludDMyX2ludDMyIiksIGkpOworICAgICAgaW50MzIga2V5ID0gc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIoCisgICAgICAgICAgKnN1Yl9tZXNzYWdlLCBtYXBfaW50MzJfaW50MzJfa2V5Xyk7CisgICAgICBpbnQzMiB2YWwgPSBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigKKyAgICAgICAgICAqc3ViX21lc3NhZ2UsIG1hcF9pbnQzMl9pbnQzMl92YWxfKTsKKyAgICAgIEVYUEVDVF9FUShtYXBba2V5XSwgdmFsKTsKKyAgICAgIC8vIENoZWNrIHdpdGggTWFwIFJlZmxlY3Rpb24KKyAgICAgIG1hcF9rZXkuU2V0SW50MzJWYWx1ZShrZXkpOworICAgICAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+Q29udGFpbnNNYXBLZXkoCisgICAgICAgICAgbWVzc2FnZSwgRigibWFwX2ludDMyX2ludDMyIiksIG1hcF9rZXkpKTsKKyAgICB9CisgIH0KKyAgeworICAgIHN0ZDo6bWFwPGludDY0LCBpbnQ2ND4gbWFwOworICAgIG1hcFswXSA9IDA7CisgICAgbWFwWzFdID0gMTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IDI7IGkrKykgeworICAgICAgLy8gQ2hlY2sgd2l0aCBSZXBlYXRlZEZpZWxkIFJlZmxlY3Rpb24KKyAgICAgIHN1Yl9tZXNzYWdlID0KKyAgICAgICAgICAmcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9pbnQ2NF9pbnQ2NCIpLCBpKTsKKyAgICAgIGludDY0IGtleSA9IHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDY0KAorICAgICAgICAgICpzdWJfbWVzc2FnZSwgbWFwX2ludDY0X2ludDY0X2tleV8pOworICAgICAgaW50NjQgdmFsID0gc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0SW50NjQoCisgICAgICAgICAgKnN1Yl9tZXNzYWdlLCBtYXBfaW50NjRfaW50NjRfdmFsXyk7CisgICAgICBFWFBFQ1RfRVEobWFwW2tleV0sIHZhbCk7CisgICAgICAvLyBDaGVjayB3aXRoIE1hcCBSZWZsZWN0aW9uCisgICAgICBtYXBfa2V5LlNldEludDY0VmFsdWUoa2V5KTsKKyAgICAgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkNvbnRhaW5zTWFwS2V5KAorICAgICAgICAgIG1lc3NhZ2UsIEYoIm1hcF9pbnQ2NF9pbnQ2NCIpLCBtYXBfa2V5KSk7CisgICAgfQorICB9CisgIHsKKyAgICBzdGQ6Om1hcDx1aW50MzIsIHVpbnQzMj4gbWFwOworICAgIG1hcFswXSA9IDA7CisgICAgbWFwWzFdID0gMTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IDI7IGkrKykgeworICAgICAgLy8gQ2hlY2sgd2l0aCBSZXBlYXRlZEZpZWxkIFJlZmxlY3Rpb24KKyAgICAgIHN1Yl9tZXNzYWdlID0KKyAgICAgICAgICAmcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF91aW50MzJfdWludDMyIiksIGkpOworICAgICAgdWludDMyIGtleSA9IHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldFVJbnQzMigKKyAgICAgICAgICAqc3ViX21lc3NhZ2UsIG1hcF91aW50MzJfdWludDMyX2tleV8pOworICAgICAgdWludDMyIHZhbCA9IHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldFVJbnQzMigKKyAgICAgICAgICAqc3ViX21lc3NhZ2UsIG1hcF91aW50MzJfdWludDMyX3ZhbF8pOworICAgICAgRVhQRUNUX0VRKG1hcFtrZXldLCB2YWwpOworICAgICAgLy8gQ2hlY2sgd2l0aCBNYXAgUmVmbGVjdGlvbgorICAgICAgbWFwX2tleS5TZXRVSW50MzJWYWx1ZShrZXkpOworICAgICAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+Q29udGFpbnNNYXBLZXkoCisgICAgICAgICAgbWVzc2FnZSwgRigibWFwX3VpbnQzMl91aW50MzIiKSwgbWFwX2tleSkpOworICAgIH0KKyAgfQorICB7CisgICAgc3RkOjptYXA8dWludDY0LCB1aW50NjQ+IG1hcDsKKyAgICBtYXBbMF0gPSAwOworICAgIG1hcFsxXSA9IDE7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAyOyBpKyspIHsKKyAgICAgIHN1Yl9tZXNzYWdlID0KKyAgICAgICAgICAmcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF91aW50NjRfdWludDY0IiksIGkpOworICAgICAgdWludDY0IGtleSA9IHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldFVJbnQ2NCgKKyAgICAgICAgICAqc3ViX21lc3NhZ2UsIG1hcF91aW50NjRfdWludDY0X2tleV8pOworICAgICAgdWludDY0IHZhbCA9IHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldFVJbnQ2NCgKKyAgICAgICAgICAqc3ViX21lc3NhZ2UsIG1hcF91aW50NjRfdWludDY0X3ZhbF8pOworICAgICAgRVhQRUNUX0VRKG1hcFtrZXldLCB2YWwpOworICAgICAgLy8gQ2hlY2sgd2l0aCBNYXAgUmVmbGVjdGlvbgorICAgICAgbWFwX2tleS5TZXRVSW50NjRWYWx1ZShrZXkpOworICAgICAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+Q29udGFpbnNNYXBLZXkoCisgICAgICAgICAgbWVzc2FnZSwgRigibWFwX3VpbnQ2NF91aW50NjQiKSwgbWFwX2tleSkpOworICAgIH0KKyAgfQorICB7CisgICAgc3RkOjptYXA8aW50MzIsIGludDMyPiBtYXA7CisgICAgbWFwWzBdID0gMDsKKyAgICBtYXBbMV0gPSAxOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjsgaSsrKSB7CisgICAgICBzdWJfbWVzc2FnZSA9CisgICAgICAgICAgJnJlZmxlY3Rpb24tPkdldFJlcGVhdGVkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfc2ludDMyX3NpbnQzMiIpLCBpKTsKKyAgICAgIGludDMyIGtleSA9IHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKAorICAgICAgICAgICpzdWJfbWVzc2FnZSwgbWFwX3NpbnQzMl9zaW50MzJfa2V5Xyk7CisgICAgICBpbnQzMiB2YWwgPSBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigKKyAgICAgICAgICAqc3ViX21lc3NhZ2UsIG1hcF9zaW50MzJfc2ludDMyX3ZhbF8pOworICAgICAgRVhQRUNUX0VRKG1hcFtrZXldLCB2YWwpOworICAgICAgLy8gQ2hlY2sgd2l0aCBNYXAgUmVmbGVjdGlvbgorICAgICAgbWFwX2tleS5TZXRJbnQzMlZhbHVlKGtleSk7CisgICAgICBFWFBFQ1RfRVEodHJ1ZSwgcmVmbGVjdGlvbi0+Q29udGFpbnNNYXBLZXkoCisgICAgICAgICAgbWVzc2FnZSwgRigibWFwX3NpbnQzMl9zaW50MzIiKSwgbWFwX2tleSkpOworICAgIH0KKyAgfQorICB7CisgICAgc3RkOjptYXA8aW50NjQsIGludDY0PiBtYXA7CisgICAgbWFwWzBdID0gMDsKKyAgICBtYXBbMV0gPSAxOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjsgaSsrKSB7CisgICAgICBzdWJfbWVzc2FnZSA9CisgICAgICAgICAgJnJlZmxlY3Rpb24tPkdldFJlcGVhdGVkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfc2ludDY0X3NpbnQ2NCIpLCBpKTsKKyAgICAgIGludDY0IGtleSA9IHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDY0KAorICAgICAgICAgICpzdWJfbWVzc2FnZSwgbWFwX3NpbnQ2NF9zaW50NjRfa2V5Xyk7CisgICAgICBpbnQ2NCB2YWwgPSBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRJbnQ2NCgKKyAgICAgICAgICAqc3ViX21lc3NhZ2UsIG1hcF9zaW50NjRfc2ludDY0X3ZhbF8pOworICAgICAgRVhQRUNUX0VRKG1hcFtrZXldLCB2YWwpOworICAgICAgLy8gQ2hlY2sgd2l0aCBNYXAgUmVmbGVjdGlvbgorICAgICAgbWFwX2tleS5TZXRJbnQ2NFZhbHVlKGtleSk7CisgICAgICBFWFBFQ1RfRVEodHJ1ZSwgcmVmbGVjdGlvbi0+Q29udGFpbnNNYXBLZXkoCisgICAgICAgICAgbWVzc2FnZSwgRigibWFwX3NpbnQ2NF9zaW50NjQiKSwgbWFwX2tleSkpOworICAgIH0KKyAgfQorICB7CisgICAgc3RkOjptYXA8dWludDMyLCB1aW50MzI+IG1hcDsKKyAgICBtYXBbMF0gPSAwOworICAgIG1hcFsxXSA9IDE7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAyOyBpKyspIHsKKyAgICAgIHN1Yl9tZXNzYWdlID0KKyAgICAgICAgICAmcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9maXhlZDMyX2ZpeGVkMzIiKSwgaSk7CisgICAgICB1aW50MzIga2V5ID0gc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0VUludDMyKAorICAgICAgICAgICpzdWJfbWVzc2FnZSwgbWFwX2ZpeGVkMzJfZml4ZWQzMl9rZXlfKTsKKyAgICAgIHVpbnQzMiB2YWwgPSBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRVSW50MzIoCisgICAgICAgICAgKnN1Yl9tZXNzYWdlLCBtYXBfZml4ZWQzMl9maXhlZDMyX3ZhbF8pOworICAgICAgRVhQRUNUX0VRKG1hcFtrZXldLCB2YWwpOworICAgICAgLy8gQ2hlY2sgd2l0aCBNYXAgUmVmbGVjdGlvbgorICAgICAgbWFwX2tleS5TZXRVSW50MzJWYWx1ZShrZXkpOworICAgICAgRVhQRUNUX0VRKHRydWUsIHJlZmxlY3Rpb24tPkNvbnRhaW5zTWFwS2V5KAorICAgICAgICAgIG1lc3NhZ2UsIEYoIm1hcF9maXhlZDMyX2ZpeGVkMzIiKSwgbWFwX2tleSkpOworICAgIH0KKyAgfQorICB7CisgICAgc3RkOjptYXA8dWludDY0LCB1aW50NjQ+IG1hcDsKKyAgICBtYXBbMF0gPSAwOworICAgIG1hcFsxXSA9IDE7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAyOyBpKyspIHsKKyAgICAgIHN1Yl9tZXNzYWdlID0KKyAgICAgICAgICAmcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9maXhlZDY0X2ZpeGVkNjQiKSwgaSk7CisgICAgICB1aW50NjQga2V5ID0gc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0VUludDY0KAorICAgICAgICAgICpzdWJfbWVzc2FnZSwgbWFwX2ZpeGVkNjRfZml4ZWQ2NF9rZXlfKTsKKyAgICAgIHVpbnQ2NCB2YWwgPSBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRVSW50NjQoCisgICAgICAgICAgKnN1Yl9tZXNzYWdlLCBtYXBfZml4ZWQ2NF9maXhlZDY0X3ZhbF8pOworICAgICAgRVhQRUNUX0VRKG1hcFtrZXldLCB2YWwpOworICAgICAgLy8gQ2hlY2sgd2l0aCBNYXAgUmVmbGVjdGlvbgorICAgICAgbWFwX2tleS5TZXRVSW50NjRWYWx1ZShrZXkpOworICAgICAgRVhQRUNUX0VRKHRydWUsIHJlZmxlY3Rpb24tPkNvbnRhaW5zTWFwS2V5KAorICAgICAgICAgIG1lc3NhZ2UsIEYoIm1hcF9maXhlZDY0X2ZpeGVkNjQiKSwgbWFwX2tleSkpOworICAgIH0KKyAgfQorICB7CisgICAgc3RkOjptYXA8aW50MzIsIGludDMyPiBtYXA7CisgICAgbWFwWzBdID0gMDsKKyAgICBtYXBbMV0gPSAxOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjsgaSsrKSB7CisgICAgICBzdWJfbWVzc2FnZSA9ICZyZWZsZWN0aW9uLT5HZXRSZXBlYXRlZE1lc3NhZ2UoCisgICAgICAgICAgbWVzc2FnZSwgRigibWFwX3NmaXhlZDMyX3NmaXhlZDMyIiksIGkpOworICAgICAgaW50MzIga2V5ID0gc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIoCisgICAgICAgICAgKnN1Yl9tZXNzYWdlLCBtYXBfc2ZpeGVkMzJfc2ZpeGVkMzJfa2V5Xyk7CisgICAgICBpbnQzMiB2YWwgPSBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigKKyAgICAgICAgICAqc3ViX21lc3NhZ2UsIG1hcF9zZml4ZWQzMl9zZml4ZWQzMl92YWxfKTsKKyAgICAgIEVYUEVDVF9FUShtYXBba2V5XSwgdmFsKTsKKyAgICAgIC8vIENoZWNrIHdpdGggTWFwIFJlZmxlY3Rpb24KKyAgICAgIG1hcF9rZXkuU2V0SW50MzJWYWx1ZShrZXkpOworICAgICAgRVhQRUNUX0VRKHRydWUsIHJlZmxlY3Rpb24tPkNvbnRhaW5zTWFwS2V5KAorICAgICAgICAgIG1lc3NhZ2UsIEYoIm1hcF9zZml4ZWQzMl9zZml4ZWQzMiIpLCBtYXBfa2V5KSk7CisgICAgfQorICB9CisgIHsKKyAgICBzdGQ6Om1hcDxpbnQ2NCwgaW50NjQ+IG1hcDsKKyAgICBtYXBbMF0gPSAwOworICAgIG1hcFsxXSA9IDE7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAyOyBpKyspIHsKKyAgICAgIHN1Yl9tZXNzYWdlID0gJnJlZmxlY3Rpb24tPkdldFJlcGVhdGVkTWVzc2FnZSgKKyAgICAgICAgICBtZXNzYWdlLCBGKCJtYXBfc2ZpeGVkNjRfc2ZpeGVkNjQiKSwgaSk7CisgICAgICBpbnQ2NCBrZXkgPSBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRJbnQ2NCgKKyAgICAgICAgICAqc3ViX21lc3NhZ2UsIG1hcF9zZml4ZWQ2NF9zZml4ZWQ2NF9rZXlfKTsKKyAgICAgIGludDY0IHZhbCA9IHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDY0KAorICAgICAgICAgICpzdWJfbWVzc2FnZSwgbWFwX3NmaXhlZDY0X3NmaXhlZDY0X3ZhbF8pOworICAgICAgRVhQRUNUX0VRKG1hcFtrZXldLCB2YWwpOworICAgICAgLy8gQ2hlY2sgd2l0aCBNYXAgUmVmbGVjdGlvbgorICAgICAgbWFwX2tleS5TZXRJbnQ2NFZhbHVlKGtleSk7CisgICAgICBFWFBFQ1RfRVEodHJ1ZSwgcmVmbGVjdGlvbi0+Q29udGFpbnNNYXBLZXkoCisgICAgICAgICAgbWVzc2FnZSwgRigibWFwX3NmaXhlZDY0X3NmaXhlZDY0IiksIG1hcF9rZXkpKTsKKyAgICB9CisgIH0KKyAgeworICAgIHN0ZDo6bWFwPGludDMyLCBmbG9hdD4gbWFwOworICAgIG1hcFswXSA9IDAuMDsKKyAgICBtYXBbMV0gPSAxLjA7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAyOyBpKyspIHsKKyAgICAgIHN1Yl9tZXNzYWdlID0KKyAgICAgICAgICAmcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9mbG9hdCIpLCBpKTsKKyAgICAgIGludDMyICBrZXkgPSBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigKKyAgICAgICAgICAqc3ViX21lc3NhZ2UsIG1hcF9pbnQzMl9mbG9hdF9rZXlfKTsKKyAgICAgIGZsb2F0IHZhbCA9IHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEZsb2F0KAorICAgICAgICAgICpzdWJfbWVzc2FnZSwgbWFwX2ludDMyX2Zsb2F0X3ZhbF8pOworICAgICAgRVhQRUNUX0VRKG1hcFtrZXldLCB2YWwpOworICAgICAgLy8gQ2hlY2sgd2l0aCBNYXAgUmVmbGVjdGlvbgorICAgICAgbWFwX2tleS5TZXRJbnQzMlZhbHVlKGtleSk7CisgICAgICBFWFBFQ1RfRVEodHJ1ZSwgcmVmbGVjdGlvbi0+Q29udGFpbnNNYXBLZXkoCisgICAgICAgICAgbWVzc2FnZSwgRigibWFwX2ludDMyX2Zsb2F0IiksIG1hcF9rZXkpKTsKKyAgICB9CisgIH0KKyAgeworICAgIHN0ZDo6bWFwPGludDMyLCBkb3VibGU+IG1hcDsKKyAgICBtYXBbMF0gPSAwLjA7CisgICAgbWFwWzFdID0gMS4wOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjsgaSsrKSB7CisgICAgICBzdWJfbWVzc2FnZSA9CisgICAgICAgICAgJnJlZmxlY3Rpb24tPkdldFJlcGVhdGVkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfaW50MzJfZG91YmxlIiksIGkpOworICAgICAgaW50MzIgIGtleSA9IHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKAorICAgICAgICAgICpzdWJfbWVzc2FnZSwgbWFwX2ludDMyX2RvdWJsZV9rZXlfKTsKKyAgICAgIGRvdWJsZSB2YWwgPSBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXREb3VibGUoCisgICAgICAgICAgKnN1Yl9tZXNzYWdlLCBtYXBfaW50MzJfZG91YmxlX3ZhbF8pOworICAgICAgRVhQRUNUX0VRKG1hcFtrZXldLCB2YWwpOworICAgICAgLy8gQ2hlY2sgd2l0aCBNYXAgUmVmbGVjdGlvbgorICAgICAgbWFwX2tleS5TZXRJbnQzMlZhbHVlKGtleSk7CisgICAgICBFWFBFQ1RfRVEodHJ1ZSwgcmVmbGVjdGlvbi0+Q29udGFpbnNNYXBLZXkoCisgICAgICAgICAgbWVzc2FnZSwgRigibWFwX2ludDMyX2RvdWJsZSIpLCBtYXBfa2V5KSk7CisgICAgfQorICB9CisgIHsKKyAgICBzdGQ6Om1hcDxib29sLCBib29sPiBtYXA7CisgICAgbWFwW2ZhbHNlXSA9IGZhbHNlOworICAgIG1hcFt0cnVlXSA9IHRydWU7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAyOyBpKyspIHsKKyAgICAgIHN1Yl9tZXNzYWdlID0KKyAgICAgICAgICAmcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9ib29sX2Jvb2wiKSwgaSk7CisgICAgICBib29sIGtleSA9IHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEJvb2woCisgICAgICAgICAgKnN1Yl9tZXNzYWdlLCBtYXBfYm9vbF9ib29sX2tleV8pOworICAgICAgYm9vbCB2YWwgPSBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRCb29sKAorICAgICAgICAgICpzdWJfbWVzc2FnZSwgbWFwX2Jvb2xfYm9vbF92YWxfKTsKKyAgICAgIEVYUEVDVF9FUShtYXBba2V5XSwgdmFsKTsKKyAgICAgIC8vIENoZWNrIHdpdGggTWFwIFJlZmxlY3Rpb24KKyAgICAgIG1hcF9rZXkuU2V0Qm9vbFZhbHVlKGtleSk7CisgICAgICBFWFBFQ1RfRVEodHJ1ZSwgcmVmbGVjdGlvbi0+Q29udGFpbnNNYXBLZXkoCisgICAgICAgICAgbWVzc2FnZSwgRigibWFwX2Jvb2xfYm9vbCIpLCBtYXBfa2V5KSk7CisgICAgfQorICB9CisgIHsKKyAgICBzdGQ6Om1hcDxzdHJpbmcsIHN0cmluZz4gbWFwOworICAgIG1hcFsiMCJdID0gIjAiOworICAgIG1hcFsiMSJdID0gIjEiOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjsgaSsrKSB7CisgICAgICBzdWJfbWVzc2FnZSA9CisgICAgICAgICAgJnJlZmxlY3Rpb24tPkdldFJlcGVhdGVkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfc3RyaW5nX3N0cmluZyIpLCBpKTsKKyAgICAgIHN0cmluZyAga2V5ID0gc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0U3RyaW5nKAorICAgICAgICAgICpzdWJfbWVzc2FnZSwgbWFwX3N0cmluZ19zdHJpbmdfa2V5Xyk7CisgICAgICBzdHJpbmcgdmFsID0gc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0U3RyaW5nKAorICAgICAgICAgICpzdWJfbWVzc2FnZSwgbWFwX3N0cmluZ19zdHJpbmdfdmFsXyk7CisgICAgICBFWFBFQ1RfRVEobWFwW2tleV0sIHZhbCk7CisgICAgICAvLyBDaGVjayB3aXRoIE1hcCBSZWZsZWN0aW9uCisgICAgICBtYXBfa2V5LlNldFN0cmluZ1ZhbHVlKGtleSk7CisgICAgICBFWFBFQ1RfRVEodHJ1ZSwgcmVmbGVjdGlvbi0+Q29udGFpbnNNYXBLZXkoCisgICAgICAgICAgbWVzc2FnZSwgRigibWFwX3N0cmluZ19zdHJpbmciKSwgbWFwX2tleSkpOworICAgIH0KKyAgfQorICB7CisgICAgc3RkOjptYXA8aW50MzIsIHN0cmluZz4gbWFwOworICAgIG1hcFswXSA9ICIwIjsKKyAgICBtYXBbMV0gPSAiMSI7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAyOyBpKyspIHsKKyAgICAgIHN1Yl9tZXNzYWdlID0KKyAgICAgICAgICAmcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9ieXRlcyIpLCBpKTsKKyAgICAgIGludDMyICBrZXkgPSBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigKKyAgICAgICAgICAqc3ViX21lc3NhZ2UsIG1hcF9pbnQzMl9ieXRlc19rZXlfKTsKKyAgICAgIHN0cmluZyB2YWwgPSBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRTdHJpbmcoCisgICAgICAgICAgKnN1Yl9tZXNzYWdlLCBtYXBfaW50MzJfYnl0ZXNfdmFsXyk7CisgICAgICBFWFBFQ1RfRVEobWFwW2tleV0sIHZhbCk7CisgICAgICAvLyBDaGVjayB3aXRoIE1hcCBSZWZsZWN0aW9uCisgICAgICBtYXBfa2V5LlNldEludDMyVmFsdWUoa2V5KTsKKyAgICAgIEVYUEVDVF9FUSh0cnVlLCByZWZsZWN0aW9uLT5Db250YWluc01hcEtleSgKKyAgICAgICAgICBtZXNzYWdlLCBGKCJtYXBfaW50MzJfYnl0ZXMiKSwgbWFwX2tleSkpOworICAgIH0KKyAgfQorICB7CisgICAgc3RkOjptYXA8aW50MzIsIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqPiBtYXA7CisgICAgbWFwWzBdID0gbWFwX2VudW1fYmFyXzsKKyAgICBtYXBbMV0gPSBtYXBfZW51bV9iYXpfOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjsgaSsrKSB7CisgICAgICBzdWJfbWVzc2FnZSA9ICZyZWZsZWN0aW9uLT5HZXRSZXBlYXRlZE1lc3NhZ2UoCisgICAgICAgICAgbWVzc2FnZSwgRigibWFwX2ludDMyX2VudW0iKSwgaSk7CisgICAgICBpbnQzMiBrZXkgPSBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigKKyAgICAgICAgICAqc3ViX21lc3NhZ2UsIG1hcF9pbnQzMl9lbnVtX2tleV8pOworICAgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogdmFsID0gc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0RW51bSgKKyAgICAgICAgICAqc3ViX21lc3NhZ2UsIG1hcF9pbnQzMl9lbnVtX3ZhbF8pOworICAgICAgRVhQRUNUX0VRKG1hcFtrZXldLCB2YWwpOworICAgICAgLy8gQ2hlY2sgd2l0aCBNYXAgUmVmbGVjdGlvbgorICAgICAgbWFwX2tleS5TZXRJbnQzMlZhbHVlKGtleSk7CisgICAgICBFWFBFQ1RfRVEodHJ1ZSwgcmVmbGVjdGlvbi0+Q29udGFpbnNNYXBLZXkoCisgICAgICAgICAgbWVzc2FnZSwgRigibWFwX2ludDMyX2VudW0iKSwgbWFwX2tleSkpOworICAgIH0KKyAgfQorICB7CisgICAgc3RkOjptYXA8aW50MzIsIGludDMyPiBtYXA7CisgICAgbWFwWzBdID0gMDsKKyAgICBtYXBbMV0gPSAxOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjsgaSsrKSB7CisgICAgICBzdWJfbWVzc2FnZSA9ICZyZWZsZWN0aW9uLT5HZXRSZXBlYXRlZE1lc3NhZ2UoCisgICAgICAgICAgbWVzc2FnZSwgRigibWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSIpLCBpKTsKKyAgICAgIGludDMyICBrZXkgPSBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigKKyAgICAgICAgICAqc3ViX21lc3NhZ2UsIG1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2Vfa2V5Xyk7CisgICAgICBjb25zdCBNZXNzYWdlJiBmb3JlaWduX21lc3NhZ2UgPSBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRNZXNzYWdlKAorICAgICAgICAgICpzdWJfbWVzc2FnZSwgbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZV92YWxfKTsKKyAgICAgIGludDMyIHZhbCA9IGZvcmVpZ25fbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKAorICAgICAgICAgIGZvcmVpZ25fbWVzc2FnZSwgZm9yZWlnbl9jXyk7CisgICAgICBFWFBFQ1RfRVEobWFwW2tleV0sIHZhbCk7CisgICAgICAvLyBDaGVjayB3aXRoIE1hcCBSZWZsZWN0aW9uCisgICAgICBtYXBfa2V5LlNldEludDMyVmFsdWUoa2V5KTsKKyAgICAgIEVYUEVDVF9FUSh0cnVlLCByZWZsZWN0aW9uLT5Db250YWluc01hcEtleSgKKyAgICAgICAgICBtZXNzYWdlLCBGKCJtYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlIiksIG1hcF9rZXkpKTsKKyAgICB9CisgIH0KK30KKwordm9pZCBNYXBSZWZsZWN0aW9uVGVzdGVyOjpFeHBlY3RNYXBGaWVsZHNTZXRWaWFSZWZsZWN0aW9uSXRlcmF0b3IoCisgICAgTWVzc2FnZSogbWVzc2FnZSkgeworICBzdHJpbmcgc2NyYXRjaDsKKyAgc3RyaW5nIHNlcmlhbGl6ZWQ7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCk7CisKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZSgqbWVzc2FnZSwgRigibWFwX2ludDMyX2ludDMyIikpKTsKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZSgqbWVzc2FnZSwgRigibWFwX2ludDY0X2ludDY0IikpKTsKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZSgqbWVzc2FnZSwgRigibWFwX3VpbnQzMl91aW50MzIiKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKCptZXNzYWdlLCBGKCJtYXBfdWludDY0X3VpbnQ2NCIpKSk7CisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUoKm1lc3NhZ2UsIEYoIm1hcF9zaW50MzJfc2ludDMyIikpKTsKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZSgqbWVzc2FnZSwgRigibWFwX3NpbnQ2NF9zaW50NjQiKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKCptZXNzYWdlLCBGKCJtYXBfZml4ZWQzMl9maXhlZDMyIikpKTsKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZSgqbWVzc2FnZSwgRigibWFwX2ZpeGVkNjRfZml4ZWQ2NCIpKSk7CisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUoKm1lc3NhZ2UsIEYoIm1hcF9zZml4ZWQzMl9zZml4ZWQzMiIpKSk7CisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUoKm1lc3NhZ2UsIEYoIm1hcF9zZml4ZWQ2NF9zZml4ZWQ2NCIpKSk7CisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUoKm1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9mbG9hdCIpKSk7CisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUoKm1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9kb3VibGUiKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKCptZXNzYWdlLCBGKCJtYXBfYm9vbF9ib29sIikpKTsKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZSgqbWVzc2FnZSwgRigibWFwX3N0cmluZ19zdHJpbmciKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKCptZXNzYWdlLCBGKCJtYXBfaW50MzJfYnl0ZXMiKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKCptZXNzYWdlLCBGKCJtYXBfaW50MzJfZW51bSIpKSk7CisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUoKm1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UiKSkpOworCisgIHsKKyAgICBzdGQ6Om1hcDxpbnQzMiwgaW50MzI+IG1hcDsKKyAgICBtYXBbMF0gPSAwOworICAgIG1hcFsxXSA9IDE7CisgICAgaW50IHNpemUgPSAwOworICAgIGZvciAoTWFwSXRlcmF0b3IgaXRlciA9IHJlZmxlY3Rpb24tPk1hcEJlZ2luKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9pbnQzMiIpKTsKKyAgICAgICAgIGl0ZXIgIT0gcmVmbGVjdGlvbi0+TWFwRW5kKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9pbnQzMiIpKTsKKyAgICAgICAgICsraXRlciwgKytzaXplKSB7CisgICAgICAvLyBDaGVjayBjb25zdCBtZXRob2RzIGRvIG5vdCBpbnZhbGlkYXRlIG1hcC4KKyAgICAgIG1lc3NhZ2UtPkRlYnVnU3RyaW5nKCk7CisgICAgICBtZXNzYWdlLT5TaG9ydERlYnVnU3RyaW5nKCk7CisgICAgICBtZXNzYWdlLT5TZXJpYWxpemVUb1N0cmluZygmc2VyaWFsaXplZCk7CisgICAgICBtZXNzYWdlLT5TcGFjZVVzZWQoKTsKKyAgICAgIG1lc3NhZ2UtPkJ5dGVTaXplKCk7CisgICAgICBFWFBFQ1RfRVEobWFwW2l0ZXIuR2V0S2V5KCkuR2V0SW50MzJWYWx1ZSgpXSwKKyAgICAgICAgICAgICAgICBpdGVyLkdldFZhbHVlUmVmKCkuR2V0SW50MzJWYWx1ZSgpKTsKKyAgICB9CisgICAgRVhQRUNUX0VRKHNpemUsIDIpOworICB9CisgIHsKKyAgICBzdGQ6Om1hcDxpbnQ2NCwgaW50NjQ+IG1hcDsKKyAgICBtYXBbMF0gPSAwOworICAgIG1hcFsxXSA9IDE7CisgICAgZm9yIChNYXBJdGVyYXRvciBpdGVyID0gcmVmbGVjdGlvbi0+TWFwQmVnaW4obWVzc2FnZSwgRigibWFwX2ludDY0X2ludDY0IikpOworICAgICAgICAgaXRlciAhPSByZWZsZWN0aW9uLT5NYXBFbmQobWVzc2FnZSwgRigibWFwX2ludDY0X2ludDY0IikpOyArK2l0ZXIpIHsKKyAgICAgIEVYUEVDVF9FUShtYXBbaXRlci5HZXRLZXkoKS5HZXRJbnQ2NFZhbHVlKCldLAorICAgICAgICAgICAgICAgIGl0ZXIuR2V0VmFsdWVSZWYoKS5HZXRJbnQ2NFZhbHVlKCkpOworICAgIH0KKyAgfQorICB7CisgICAgc3RkOjptYXA8dWludDMyLCB1aW50MzI+IG1hcDsKKyAgICBtYXBbMF0gPSAwOworICAgIG1hcFsxXSA9IDE7CisgICAgZm9yIChNYXBJdGVyYXRvciBpdGVyID0gcmVmbGVjdGlvbi0+TWFwQmVnaW4oCisgICAgICAgICAgICAgbWVzc2FnZSwgRigibWFwX3VpbnQzMl91aW50MzIiKSk7CisgICAgICAgICBpdGVyICE9IHJlZmxlY3Rpb24tPk1hcEVuZChtZXNzYWdlLCBGKCJtYXBfdWludDMyX3VpbnQzMiIpKTsKKyAgICAgICAgICsraXRlcikgeworICAgICAgRVhQRUNUX0VRKG1hcFtpdGVyLkdldEtleSgpLkdldFVJbnQzMlZhbHVlKCldLAorICAgICAgICAgICAgICAgIGl0ZXIuR2V0VmFsdWVSZWYoKS5HZXRVSW50MzJWYWx1ZSgpKTsKKyAgICB9CisgIH0KKyAgeworICAgIHN0ZDo6bWFwPHVpbnQ2NCwgdWludDY0PiBtYXA7CisgICAgbWFwWzBdID0gMDsKKyAgICBtYXBbMV0gPSAxOworICAgIGZvciAoTWFwSXRlcmF0b3IgaXRlciA9IHJlZmxlY3Rpb24tPk1hcEJlZ2luKAorICAgICAgICAgICAgIG1lc3NhZ2UsIEYoIm1hcF91aW50NjRfdWludDY0IikpOworICAgICAgICAgaXRlciAhPSByZWZsZWN0aW9uLT5NYXBFbmQobWVzc2FnZSwgRigibWFwX3VpbnQ2NF91aW50NjQiKSk7CisgICAgICAgICArK2l0ZXIpIHsKKyAgICAgIEVYUEVDVF9FUShtYXBbaXRlci5HZXRLZXkoKS5HZXRVSW50NjRWYWx1ZSgpXSwKKyAgICAgICAgICAgICAgICBpdGVyLkdldFZhbHVlUmVmKCkuR2V0VUludDY0VmFsdWUoKSk7CisgICAgfQorICB9CisgIHsKKyAgICBzdGQ6Om1hcDxpbnQzMiwgaW50MzI+IG1hcDsKKyAgICBtYXBbMF0gPSAwOworICAgIG1hcFsxXSA9IDE7CisgICAgZm9yIChNYXBJdGVyYXRvciBpdGVyID0gcmVmbGVjdGlvbi0+TWFwQmVnaW4oCisgICAgICAgICAgICAgbWVzc2FnZSwgRigibWFwX3NpbnQzMl9zaW50MzIiKSk7CisgICAgICAgICBpdGVyICE9IHJlZmxlY3Rpb24tPk1hcEVuZChtZXNzYWdlLCBGKCJtYXBfc2ludDMyX3NpbnQzMiIpKTsKKyAgICAgICAgICsraXRlcikgeworICAgICAgRVhQRUNUX0VRKG1hcFtpdGVyLkdldEtleSgpLkdldEludDMyVmFsdWUoKV0sCisgICAgICAgICAgICAgICAgaXRlci5HZXRWYWx1ZVJlZigpLkdldEludDMyVmFsdWUoKSk7CisgICAgfQorICB9CisgIHsKKyAgICBzdGQ6Om1hcDxpbnQ2NCwgaW50NjQ+IG1hcDsKKyAgICBtYXBbMF0gPSAwOworICAgIG1hcFsxXSA9IDE7CisgICAgZm9yIChNYXBJdGVyYXRvciBpdGVyID0gcmVmbGVjdGlvbi0+TWFwQmVnaW4oCisgICAgICAgICAgICAgbWVzc2FnZSwgRigibWFwX3NpbnQ2NF9zaW50NjQiKSk7CisgICAgICAgICBpdGVyICE9IHJlZmxlY3Rpb24tPk1hcEVuZChtZXNzYWdlLCBGKCJtYXBfc2ludDY0X3NpbnQ2NCIpKTsgKytpdGVyKSB7CisgICAgICBFWFBFQ1RfRVEobWFwW2l0ZXIuR2V0S2V5KCkuR2V0SW50NjRWYWx1ZSgpXSwKKyAgICAgICAgICAgICAgICBpdGVyLkdldFZhbHVlUmVmKCkuR2V0SW50NjRWYWx1ZSgpKTsKKyAgICB9CisgIH0KKyAgeworICAgIHN0ZDo6bWFwPHVpbnQzMiwgdWludDMyPiBtYXA7CisgICAgbWFwWzBdID0gMDsKKyAgICBtYXBbMV0gPSAxOworICAgIGZvciAoTWFwSXRlcmF0b3IgaXRlciA9IHJlZmxlY3Rpb24tPk1hcEJlZ2luKAorICAgICAgICAgICAgIG1lc3NhZ2UsIEYoIm1hcF9maXhlZDMyX2ZpeGVkMzIiKSk7CisgICAgICAgICBpdGVyICE9IHJlZmxlY3Rpb24tPk1hcEVuZChtZXNzYWdlLCBGKCJtYXBfZml4ZWQzMl9maXhlZDMyIikpOworICAgICAgICAgKytpdGVyKSB7CisgICAgICBFWFBFQ1RfRVEobWFwW2l0ZXIuR2V0S2V5KCkuR2V0VUludDMyVmFsdWUoKV0sCisgICAgICAgICAgICAgICAgaXRlci5HZXRWYWx1ZVJlZigpLkdldFVJbnQzMlZhbHVlKCkpOworICAgIH0KKyAgfQorICB7CisgICAgc3RkOjptYXA8dWludDY0LCB1aW50NjQ+IG1hcDsKKyAgICBtYXBbMF0gPSAwOworICAgIG1hcFsxXSA9IDE7CisgICAgZm9yIChNYXBJdGVyYXRvciBpdGVyID0gcmVmbGVjdGlvbi0+TWFwQmVnaW4oCisgICAgICAgICAgICAgbWVzc2FnZSwgRigibWFwX2ZpeGVkNjRfZml4ZWQ2NCIpKTsKKyAgICAgICAgIGl0ZXIgIT0gcmVmbGVjdGlvbi0+TWFwRW5kKG1lc3NhZ2UsIEYoIm1hcF9maXhlZDY0X2ZpeGVkNjQiKSk7CisgICAgICAgICArK2l0ZXIpIHsKKyAgICAgIEVYUEVDVF9FUShtYXBbaXRlci5HZXRLZXkoKS5HZXRVSW50NjRWYWx1ZSgpXSwKKyAgICAgICAgICAgICAgICBpdGVyLkdldFZhbHVlUmVmKCkuR2V0VUludDY0VmFsdWUoKSk7CisgICAgfQorICB9CisgIHsKKyAgICBzdGQ6Om1hcDxpbnQzMiwgaW50MzI+IG1hcDsKKyAgICBtYXBbMF0gPSAwOworICAgIG1hcFsxXSA9IDE7CisgICAgZm9yIChNYXBJdGVyYXRvciBpdGVyID0gcmVmbGVjdGlvbi0+TWFwQmVnaW4oCisgICAgICAgICAgICAgbWVzc2FnZSwgRigibWFwX3NmaXhlZDMyX3NmaXhlZDMyIikpOworICAgICAgICAgaXRlciAhPSByZWZsZWN0aW9uLT5NYXBFbmQobWVzc2FnZSwgRigibWFwX3NmaXhlZDMyX3NmaXhlZDMyIikpOworICAgICAgICAgKytpdGVyKSB7CisgICAgICBFWFBFQ1RfRVEobWFwW2l0ZXIuR2V0S2V5KCkuR2V0SW50MzJWYWx1ZSgpXSwKKyAgICAgICAgICAgICAgICBpdGVyLkdldFZhbHVlUmVmKCkuR2V0SW50MzJWYWx1ZSgpKTsKKyAgICB9CisgIH0KKyAgeworICAgIHN0ZDo6bWFwPGludDMyLCBmbG9hdD4gbWFwOworICAgIG1hcFswXSA9IDAuMDsKKyAgICBtYXBbMV0gPSAxLjA7CisgICAgZm9yIChNYXBJdGVyYXRvciBpdGVyID0gcmVmbGVjdGlvbi0+TWFwQmVnaW4obWVzc2FnZSwgRigibWFwX2ludDMyX2Zsb2F0IikpOworICAgICAgICAgaXRlciAhPSByZWZsZWN0aW9uLT5NYXBFbmQobWVzc2FnZSwgRigibWFwX2ludDMyX2Zsb2F0IikpOyArK2l0ZXIpIHsKKyAgICAgIEVYUEVDVF9FUShtYXBbaXRlci5HZXRLZXkoKS5HZXRJbnQzMlZhbHVlKCldLAorICAgICAgICAgICAgICAgIGl0ZXIuR2V0VmFsdWVSZWYoKS5HZXRGbG9hdFZhbHVlKCkpOworICAgIH0KKyAgfQorICB7CisgICAgc3RkOjptYXA8aW50MzIsIGRvdWJsZT4gbWFwOworICAgIG1hcFswXSA9IDAuMDsKKyAgICBtYXBbMV0gPSAxLjA7CisgICAgZm9yIChNYXBJdGVyYXRvciBpdGVyID0gcmVmbGVjdGlvbi0+TWFwQmVnaW4oCisgICAgICAgICAgICAgbWVzc2FnZSwgRigibWFwX2ludDMyX2RvdWJsZSIpKTsKKyAgICAgICAgIGl0ZXIgIT0gcmVmbGVjdGlvbi0+TWFwRW5kKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9kb3VibGUiKSk7ICsraXRlcikgeworICAgICAgRVhQRUNUX0VRKG1hcFtpdGVyLkdldEtleSgpLkdldEludDMyVmFsdWUoKV0sCisgICAgICAgICAgICAgICAgaXRlci5HZXRWYWx1ZVJlZigpLkdldERvdWJsZVZhbHVlKCkpOworICAgIH0KKyAgfQorICB7CisgICAgc3RkOjptYXA8Ym9vbCwgYm9vbD4gbWFwOworICAgIG1hcFtmYWxzZV0gPSBmYWxzZTsKKyAgICBtYXBbdHJ1ZV0gPSB0cnVlOworICAgIGZvciAoTWFwSXRlcmF0b3IgaXRlciA9IHJlZmxlY3Rpb24tPk1hcEJlZ2luKG1lc3NhZ2UsIEYoIm1hcF9ib29sX2Jvb2wiKSk7CisgICAgICAgICBpdGVyICE9IHJlZmxlY3Rpb24tPk1hcEVuZChtZXNzYWdlLCBGKCJtYXBfYm9vbF9ib29sIikpOyArK2l0ZXIpIHsKKyAgICAgIEVYUEVDVF9FUShtYXBbaXRlci5HZXRLZXkoKS5HZXRCb29sVmFsdWUoKV0sCisgICAgICAgICAgICAgICAgaXRlci5HZXRWYWx1ZVJlZigpLkdldEJvb2xWYWx1ZSgpKTsKKyAgICB9CisgIH0KKyAgeworICAgIHN0ZDo6bWFwPHN0cmluZywgc3RyaW5nPiBtYXA7CisgICAgbWFwWyIwIl0gPSAiMCI7CisgICAgbWFwWyIxIl0gPSAiMSI7CisgICAgaW50IHNpemUgPSAwOworICAgIGZvciAoTWFwSXRlcmF0b3IgaXRlciA9IHJlZmxlY3Rpb24tPk1hcEJlZ2luKAorICAgICAgICAgICAgIG1lc3NhZ2UsIEYoIm1hcF9zdHJpbmdfc3RyaW5nIikpOworICAgICAgICAgaXRlciAhPSByZWZsZWN0aW9uLT5NYXBFbmQobWVzc2FnZSwgRigibWFwX3N0cmluZ19zdHJpbmciKSk7CisgICAgICAgICArK2l0ZXIsICsrc2l6ZSkgeworICAgICAgLy8gQ2hlY2sgY29uc3QgbWV0aG9kcyBkbyBub3QgaW52YWxpZGF0ZSBtYXAuCisgICAgICBtZXNzYWdlLT5EZWJ1Z1N0cmluZygpOworICAgICAgbWVzc2FnZS0+U2hvcnREZWJ1Z1N0cmluZygpOworICAgICAgbWVzc2FnZS0+U2VyaWFsaXplVG9TdHJpbmcoJnNlcmlhbGl6ZWQpOworICAgICAgbWVzc2FnZS0+U3BhY2VVc2VkKCk7CisgICAgICBtZXNzYWdlLT5CeXRlU2l6ZSgpOworICAgICAgRVhQRUNUX0VRKG1hcFtpdGVyLkdldEtleSgpLkdldFN0cmluZ1ZhbHVlKCldLAorICAgICAgICAgICAgICAgIGl0ZXIuR2V0VmFsdWVSZWYoKS5HZXRTdHJpbmdWYWx1ZSgpKTsKKyAgICB9CisgICAgRVhQRUNUX0VRKHNpemUsIDIpOworICB9CisgIHsKKyAgICBzdGQ6Om1hcDxpbnQzMiwgc3RyaW5nPiBtYXA7CisgICAgbWFwWzBdID0gIjAiOworICAgIG1hcFsxXSA9ICIxIjsKKyAgICBmb3IgKE1hcEl0ZXJhdG9yIGl0ZXIgPSByZWZsZWN0aW9uLT5NYXBCZWdpbihtZXNzYWdlLCBGKCJtYXBfaW50MzJfYnl0ZXMiKSk7CisgICAgICAgICBpdGVyICE9IHJlZmxlY3Rpb24tPk1hcEVuZChtZXNzYWdlLCBGKCJtYXBfaW50MzJfYnl0ZXMiKSk7ICsraXRlcikgeworICAgICAgRVhQRUNUX0VRKG1hcFtpdGVyLkdldEtleSgpLkdldEludDMyVmFsdWUoKV0sCisgICAgICAgICAgICAgICAgaXRlci5HZXRWYWx1ZVJlZigpLkdldFN0cmluZ1ZhbHVlKCkpOworICAgIH0KKyAgfQorICB7CisgICAgc3RkOjptYXA8aW50MzIsIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqPiBtYXA7CisgICAgbWFwWzBdID0gbWFwX2VudW1fYmFyXzsKKyAgICBtYXBbMV0gPSBtYXBfZW51bV9iYXpfOworICAgIGZvciAoTWFwSXRlcmF0b3IgaXRlciA9IHJlZmxlY3Rpb24tPk1hcEJlZ2luKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9lbnVtIikpOworICAgICAgICAgaXRlciAhPSByZWZsZWN0aW9uLT5NYXBFbmQobWVzc2FnZSwgRigibWFwX2ludDMyX2VudW0iKSk7ICsraXRlcikgeworICAgICAgRVhQRUNUX0VRKG1hcFtpdGVyLkdldEtleSgpLkdldEludDMyVmFsdWUoKV0tPm51bWJlcigpLAorICAgICAgICAgICAgICAgIGl0ZXIuR2V0VmFsdWVSZWYoKS5HZXRFbnVtVmFsdWUoKSk7CisgICAgfQorICB9CisgIHsKKyAgICBzdGQ6Om1hcDxpbnQzMiwgaW50MzI+IG1hcDsKKyAgICBtYXBbMF0gPSAwOworICAgIG1hcFsxXSA9IDE7CisgICAgaW50IHNpemUgPSAwOworICAgIGZvciAoTWFwSXRlcmF0b3IgaXRlciA9IHJlZmxlY3Rpb24tPk1hcEJlZ2luKAorICAgICAgICAgICAgIG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UiKSk7CisgICAgICAgICBpdGVyICE9IHJlZmxlY3Rpb24tPk1hcEVuZChtZXNzYWdlLCBGKCJtYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlIikpOworICAgICAgICAgKytpdGVyLCArK3NpemUpIHsKKyAgICAgIC8vIENoZWNrIGNvbnN0IG1ldGhvZHMgZG8gbm90IGludmFsaWRhdGUgbWFwLgorICAgICAgbWVzc2FnZS0+RGVidWdTdHJpbmcoKTsKKyAgICAgIG1lc3NhZ2UtPlNob3J0RGVidWdTdHJpbmcoKTsKKyAgICAgIG1lc3NhZ2UtPlNlcmlhbGl6ZVRvU3RyaW5nKCZzZXJpYWxpemVkKTsKKyAgICAgIG1lc3NhZ2UtPlNwYWNlVXNlZCgpOworICAgICAgbWVzc2FnZS0+Qnl0ZVNpemUoKTsKKyAgICAgIGNvbnN0IE1lc3NhZ2UmIHN1Yl9tZXNzYWdlID0gaXRlci5HZXRWYWx1ZVJlZigpLkdldE1lc3NhZ2VWYWx1ZSgpOworICAgICAgRVhQRUNUX0VRKG1hcFtpdGVyLkdldEtleSgpLkdldEludDMyVmFsdWUoKV0sCisgICAgICAgICAgICAgICAgc3ViX21lc3NhZ2UuR2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMihzdWJfbWVzc2FnZSwgZm9yZWlnbl9jXykpOworICAgIH0KKyAgICBFWFBFQ1RfRVEoc2l6ZSwgMik7CisgIH0KK30KKwordm9pZCBNYXBSZWZsZWN0aW9uVGVzdGVyOjpFeHBlY3RDbGVhclZpYVJlZmxlY3Rpb24oCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSkgeworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCk7CisgIC8vIE1hcCBmaWVsZHMgYXJlIGVtcHR5LgorICBFWFBFQ1RfRVEoMCwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9pbnQzMiIpKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigibWFwX2ludDY0X2ludDY0IikpKTsKKyAgRVhQRUNUX0VRKDAsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJtYXBfdWludDMyX3VpbnQzMiIpKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigibWFwX3VpbnQ2NF91aW50NjQiKSkpOworICBFWFBFQ1RfRVEoMCwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoIm1hcF9zaW50MzJfc2ludDMyIikpKTsKKyAgRVhQRUNUX0VRKDAsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJtYXBfc2ludDY0X3NpbnQ2NCIpKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigibWFwX2ZpeGVkMzJfZml4ZWQzMiIpKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigibWFwX2ZpeGVkNjRfZml4ZWQ2NCIpKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigibWFwX3NmaXhlZDMyX3NmaXhlZDMyIikpKTsKKyAgRVhQRUNUX0VRKDAsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJtYXBfc2ZpeGVkNjRfc2ZpeGVkNjQiKSkpOworICBFWFBFQ1RfRVEoMCwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9mbG9hdCIpKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigibWFwX2ludDMyX2RvdWJsZSIpKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigibWFwX2Jvb2xfYm9vbCIpKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigibWFwX3N0cmluZ19zdHJpbmciKSkpOworICBFWFBFQ1RfRVEoMCwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9ieXRlcyIpKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigibWFwX2ludDMyX2VudW0iKSkpOworICBFWFBFQ1RfRVEoMCwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UiKSkpOworfQorCit2b2lkIE1hcFJlZmxlY3Rpb25UZXN0ZXI6OkV4cGVjdENsZWFyVmlhUmVmbGVjdGlvbkl0ZXJhdG9yKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UpIHsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKTsKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+TWFwQmVnaW4obWVzc2FnZSwgRigibWFwX2ludDMyX2ludDMyIikpID09CisgICAgICAgICAgICAgIHJlZmxlY3Rpb24tPk1hcEVuZChtZXNzYWdlLCBGKCJtYXBfaW50MzJfaW50MzIiKSkpOworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5NYXBCZWdpbihtZXNzYWdlLCBGKCJtYXBfaW50NjRfaW50NjQiKSkgPT0KKyAgICAgICAgICAgICAgcmVmbGVjdGlvbi0+TWFwRW5kKG1lc3NhZ2UsIEYoIm1hcF9pbnQ2NF9pbnQ2NCIpKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPk1hcEJlZ2luKG1lc3NhZ2UsIEYoIm1hcF91aW50MzJfdWludDMyIikpID09CisgICAgICAgICAgICAgIHJlZmxlY3Rpb24tPk1hcEVuZChtZXNzYWdlLCBGKCJtYXBfdWludDMyX3VpbnQzMiIpKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPk1hcEJlZ2luKG1lc3NhZ2UsIEYoIm1hcF91aW50NjRfdWludDY0IikpID09CisgICAgICAgICAgICAgIHJlZmxlY3Rpb24tPk1hcEVuZChtZXNzYWdlLCBGKCJtYXBfdWludDY0X3VpbnQ2NCIpKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPk1hcEJlZ2luKG1lc3NhZ2UsIEYoIm1hcF9zaW50MzJfc2ludDMyIikpID09CisgICAgICAgICAgICAgIHJlZmxlY3Rpb24tPk1hcEVuZChtZXNzYWdlLCBGKCJtYXBfc2ludDMyX3NpbnQzMiIpKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPk1hcEJlZ2luKG1lc3NhZ2UsIEYoIm1hcF9zaW50NjRfc2ludDY0IikpID09CisgICAgICAgICAgICAgIHJlZmxlY3Rpb24tPk1hcEVuZChtZXNzYWdlLCBGKCJtYXBfc2ludDY0X3NpbnQ2NCIpKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPk1hcEJlZ2luKG1lc3NhZ2UsIEYoIm1hcF9maXhlZDMyX2ZpeGVkMzIiKSkgPT0KKyAgICAgICAgICAgICAgcmVmbGVjdGlvbi0+TWFwRW5kKG1lc3NhZ2UsIEYoIm1hcF9maXhlZDMyX2ZpeGVkMzIiKSkpOworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5NYXBCZWdpbihtZXNzYWdlLCBGKCJtYXBfZml4ZWQ2NF9maXhlZDY0IikpID09CisgICAgICAgICAgICAgIHJlZmxlY3Rpb24tPk1hcEVuZChtZXNzYWdlLCBGKCJtYXBfZml4ZWQ2NF9maXhlZDY0IikpKTsKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+TWFwQmVnaW4obWVzc2FnZSwgRigibWFwX3NmaXhlZDMyX3NmaXhlZDMyIikpID09CisgICAgICAgICAgICAgIHJlZmxlY3Rpb24tPk1hcEVuZChtZXNzYWdlLCBGKCJtYXBfc2ZpeGVkMzJfc2ZpeGVkMzIiKSkpOworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5NYXBCZWdpbihtZXNzYWdlLCBGKCJtYXBfc2ZpeGVkNjRfc2ZpeGVkNjQiKSkgPT0KKyAgICAgICAgICAgICAgcmVmbGVjdGlvbi0+TWFwRW5kKG1lc3NhZ2UsIEYoIm1hcF9zZml4ZWQ2NF9zZml4ZWQ2NCIpKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPk1hcEJlZ2luKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9mbG9hdCIpKSA9PQorICAgICAgICAgICAgICByZWZsZWN0aW9uLT5NYXBFbmQobWVzc2FnZSwgRigibWFwX2ludDMyX2Zsb2F0IikpKTsKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+TWFwQmVnaW4obWVzc2FnZSwgRigibWFwX2ludDMyX2RvdWJsZSIpKSA9PQorICAgICAgICAgICAgICByZWZsZWN0aW9uLT5NYXBFbmQobWVzc2FnZSwgRigibWFwX2ludDMyX2RvdWJsZSIpKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPk1hcEJlZ2luKG1lc3NhZ2UsIEYoIm1hcF9ib29sX2Jvb2wiKSkgPT0KKyAgICAgICAgICAgICAgcmVmbGVjdGlvbi0+TWFwRW5kKG1lc3NhZ2UsIEYoIm1hcF9ib29sX2Jvb2wiKSkpOworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5NYXBCZWdpbihtZXNzYWdlLCBGKCJtYXBfc3RyaW5nX3N0cmluZyIpKSA9PQorICAgICAgICAgICAgICByZWZsZWN0aW9uLT5NYXBFbmQobWVzc2FnZSwgRigibWFwX3N0cmluZ19zdHJpbmciKSkpOworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5NYXBCZWdpbihtZXNzYWdlLCBGKCJtYXBfaW50MzJfYnl0ZXMiKSkgPT0KKyAgICAgICAgICAgICAgcmVmbGVjdGlvbi0+TWFwRW5kKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9ieXRlcyIpKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPk1hcEJlZ2luKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9lbnVtIikpID09CisgICAgICAgICAgICAgIHJlZmxlY3Rpb24tPk1hcEVuZChtZXNzYWdlLCBGKCJtYXBfaW50MzJfZW51bSIpKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPk1hcEJlZ2luKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UiKSkgPT0KKyAgICAgICAgICAgICAgcmVmbGVjdGlvbi0+TWFwRW5kKG1lc3NhZ2UsIEYoIm1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UiKSkpOworfQorCit2b2lkIE1hcFJlZmxlY3Rpb25UZXN0ZXI6OkV4cGVjdE1hcEVudHJ5Q2xlYXJWaWFSZWZsZWN0aW9uKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UpIHsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKTsKKyAgY29uc3QgTWVzc2FnZSogc3ViX21lc3NhZ2U7CisKKyAgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciA9IEYoIm1hcF9pbnQzMl9pbnQzMiIpOworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvcioga2V5X2Rlc2NyaXB0b3IgPQorICAgICAgICBkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJrZXkiKTsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHZhbHVlX2Rlc2NyaXB0b3IgPQorICAgICAgICBkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJ2YWx1ZSIpOworICAgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfaW50MzJfaW50MzIiKSk7CisgICAgRVhQRUNUX0VRKDAsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKCpzdWJfbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5X2Rlc2NyaXB0b3IpKTsKKyAgICBFWFBFQ1RfRVEoMCwgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIoKnN1Yl9tZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZV9kZXNjcmlwdG9yKSk7CisgIH0KKyAgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciA9IEYoIm1hcF9pbnQ2NF9pbnQ2NCIpOworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvcioga2V5X2Rlc2NyaXB0b3IgPQorICAgICAgICBkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJrZXkiKTsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHZhbHVlX2Rlc2NyaXB0b3IgPQorICAgICAgICBkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJ2YWx1ZSIpOworICAgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfaW50NjRfaW50NjQiKSk7CisgICAgRVhQRUNUX0VRKDAsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDY0KCpzdWJfbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5X2Rlc2NyaXB0b3IpKTsKKyAgICBFWFBFQ1RfRVEoMCwgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0SW50NjQoKnN1Yl9tZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZV9kZXNjcmlwdG9yKSk7CisgIH0KKyAgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciA9IEYoIm1hcF91aW50MzJfdWludDMyIik7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBrZXlfZGVzY3JpcHRvciA9CisgICAgICAgIGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoImtleSIpOworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogdmFsdWVfZGVzY3JpcHRvciA9CisgICAgICAgIGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoInZhbHVlIik7CisgICAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF91aW50MzJfdWludDMyIikpOworICAgIEVYUEVDVF9FUSgwLCBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRVSW50MzIoKnN1Yl9tZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5X2Rlc2NyaXB0b3IpKTsKKyAgICBFWFBFQ1RfRVEoMCwgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0VUludDMyKCpzdWJfbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlX2Rlc2NyaXB0b3IpKTsKKyAgfQorICB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yID0gRigibWFwX3VpbnQ2NF91aW50NjQiKTsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGtleV9kZXNjcmlwdG9yID0KKyAgICAgICAgZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgia2V5Iik7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiB2YWx1ZV9kZXNjcmlwdG9yID0KKyAgICAgICAgZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgidmFsdWUiKTsKKyAgICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX3VpbnQ2NF91aW50NjQiKSk7CisgICAgRVhQRUNUX0VRKDAsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldFVJbnQ2NCgqc3ViX21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXlfZGVzY3JpcHRvcikpOworICAgIEVYUEVDVF9FUSgwLCBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRVSW50NjQoKnN1Yl9tZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVfZGVzY3JpcHRvcikpOworICB9CisgIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBGKCJtYXBfc2ludDMyX3NpbnQzMiIpOworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvcioga2V5X2Rlc2NyaXB0b3IgPQorICAgICAgICBkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJrZXkiKTsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHZhbHVlX2Rlc2NyaXB0b3IgPQorICAgICAgICBkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJ2YWx1ZSIpOworICAgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfc2ludDMyX3NpbnQzMiIpKTsKKyAgICBFWFBFQ1RfRVEoMCwgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIoKnN1Yl9tZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXlfZGVzY3JpcHRvcikpOworICAgIEVYUEVDVF9FUSgwLCBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigqc3ViX21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlX2Rlc2NyaXB0b3IpKTsKKyAgfQorICB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yID0gRigibWFwX3NpbnQ2NF9zaW50NjQiKTsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGtleV9kZXNjcmlwdG9yID0KKyAgICAgICAgZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgia2V5Iik7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiB2YWx1ZV9kZXNjcmlwdG9yID0KKyAgICAgICAgZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgidmFsdWUiKTsKKyAgICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX3NpbnQ2NF9zaW50NjQiKSk7CisgICAgRVhQRUNUX0VRKDAsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDY0KCpzdWJfbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5X2Rlc2NyaXB0b3IpKTsKKyAgICBFWFBFQ1RfRVEoMCwgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0SW50NjQoKnN1Yl9tZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZV9kZXNjcmlwdG9yKSk7CisgIH0KKyAgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciA9IEYoIm1hcF9maXhlZDMyX2ZpeGVkMzIiKTsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGtleV9kZXNjcmlwdG9yID0KKyAgICAgICAgZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgia2V5Iik7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiB2YWx1ZV9kZXNjcmlwdG9yID0KKyAgICAgICAgZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgidmFsdWUiKTsKKyAgICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX2ZpeGVkMzJfZml4ZWQzMiIpKTsKKyAgICBFWFBFQ1RfRVEoMCwgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0VUludDMyKCpzdWJfbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleV9kZXNjcmlwdG9yKSk7CisgICAgRVhQRUNUX0VRKDAsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldFVJbnQzMigqc3ViX21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZV9kZXNjcmlwdG9yKSk7CisgIH0KKyAgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciA9IEYoIm1hcF9maXhlZDY0X2ZpeGVkNjQiKTsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGtleV9kZXNjcmlwdG9yID0KKyAgICAgICAgZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgia2V5Iik7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiB2YWx1ZV9kZXNjcmlwdG9yID0KKyAgICAgICAgZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgidmFsdWUiKTsKKyAgICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX2ZpeGVkNjRfZml4ZWQ2NCIpKTsKKyAgICBFWFBFQ1RfRVEoMCwgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0VUludDY0KCpzdWJfbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleV9kZXNjcmlwdG9yKSk7CisgICAgRVhQRUNUX0VRKDAsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldFVJbnQ2NCgqc3ViX21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZV9kZXNjcmlwdG9yKSk7CisgIH0KKyAgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciA9IEYoIm1hcF9zZml4ZWQzMl9zZml4ZWQzMiIpOworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvcioga2V5X2Rlc2NyaXB0b3IgPQorICAgICAgICBkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJrZXkiKTsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHZhbHVlX2Rlc2NyaXB0b3IgPQorICAgICAgICBkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJ2YWx1ZSIpOworICAgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfc2ZpeGVkMzJfc2ZpeGVkMzIiKSk7CisgICAgRVhQRUNUX0VRKDAsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKCpzdWJfbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5X2Rlc2NyaXB0b3IpKTsKKyAgICBFWFBFQ1RfRVEoMCwgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIoKnN1Yl9tZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZV9kZXNjcmlwdG9yKSk7CisgIH0KKyAgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciA9IEYoIm1hcF9zZml4ZWQ2NF9zZml4ZWQ2NCIpOworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvcioga2V5X2Rlc2NyaXB0b3IgPQorICAgICAgICBkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJrZXkiKTsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHZhbHVlX2Rlc2NyaXB0b3IgPQorICAgICAgICBkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJ2YWx1ZSIpOworICAgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfc2ZpeGVkNjRfc2ZpeGVkNjQiKSk7CisgICAgRVhQRUNUX0VRKDAsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDY0KCpzdWJfbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5X2Rlc2NyaXB0b3IpKTsKKyAgICBFWFBFQ1RfRVEoMCwgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0SW50NjQoKnN1Yl9tZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZV9kZXNjcmlwdG9yKSk7CisgIH0KKyAgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciA9IEYoIm1hcF9pbnQzMl9mbG9hdCIpOworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvcioga2V5X2Rlc2NyaXB0b3IgPQorICAgICAgICBkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJrZXkiKTsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHZhbHVlX2Rlc2NyaXB0b3IgPQorICAgICAgICBkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJ2YWx1ZSIpOworICAgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfaW50MzJfZmxvYXQiKSk7CisgICAgRVhQRUNUX0VRKDAsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKCpzdWJfbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5X2Rlc2NyaXB0b3IpKTsKKyAgICBFWFBFQ1RfRVEoMCwgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0RmxvYXQoKnN1Yl9tZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZV9kZXNjcmlwdG9yKSk7CisgIH0KKyAgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciA9IEYoIm1hcF9pbnQzMl9kb3VibGUiKTsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGtleV9kZXNjcmlwdG9yID0KKyAgICAgICAgZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgia2V5Iik7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiB2YWx1ZV9kZXNjcmlwdG9yID0KKyAgICAgICAgZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgidmFsdWUiKTsKKyAgICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX2ludDMyX2RvdWJsZSIpKTsKKyAgICBFWFBFQ1RfRVEoMCwgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIoKnN1Yl9tZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXlfZGVzY3JpcHRvcikpOworICAgIEVYUEVDVF9FUSgwLCBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXREb3VibGUoKnN1Yl9tZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVfZGVzY3JpcHRvcikpOworICB9CisgIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBGKCJtYXBfYm9vbF9ib29sIik7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBrZXlfZGVzY3JpcHRvciA9CisgICAgICAgIGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoImtleSIpOworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogdmFsdWVfZGVzY3JpcHRvciA9CisgICAgICAgIGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoInZhbHVlIik7CisgICAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9ib29sX2Jvb2wiKSk7CisgICAgRVhQRUNUX0VRKGZhbHNlLCBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRCb29sKCpzdWJfbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5X2Rlc2NyaXB0b3IpKTsKKyAgICBFWFBFQ1RfRVEoZmFsc2UsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEJvb2woKnN1Yl9tZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZV9kZXNjcmlwdG9yKSk7CisgIH0KKyAgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciA9IEYoIm1hcF9zdHJpbmdfc3RyaW5nIik7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBrZXlfZGVzY3JpcHRvciA9CisgICAgICAgIGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoImtleSIpOworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogdmFsdWVfZGVzY3JpcHRvciA9CisgICAgICAgIGRlc2NyaXB0b3ItPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoInZhbHVlIik7CisgICAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5BZGRNZXNzYWdlKG1lc3NhZ2UsIEYoIm1hcF9zdHJpbmdfc3RyaW5nIikpOworICAgIEVYUEVDVF9FUSgiIiwgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0U3RyaW5nKCpzdWJfbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXlfZGVzY3JpcHRvcikpOworICAgIEVYUEVDVF9FUSgiIiwgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0U3RyaW5nKCpzdWJfbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZV9kZXNjcmlwdG9yKSk7CisgIH0KKyAgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzY3JpcHRvciA9IEYoIm1hcF9pbnQzMl9ieXRlcyIpOworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvcioga2V5X2Rlc2NyaXB0b3IgPQorICAgICAgICBkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJrZXkiKTsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHZhbHVlX2Rlc2NyaXB0b3IgPQorICAgICAgICBkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJ2YWx1ZSIpOworICAgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJtYXBfaW50MzJfYnl0ZXMiKSk7CisgICAgRVhQRUNUX0VRKDAsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKCpzdWJfbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5X2Rlc2NyaXB0b3IpKTsKKyAgICBFWFBFQ1RfRVEoIiIsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldFN0cmluZygqc3ViX21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlX2Rlc2NyaXB0b3IpKTsKKyAgfQorICB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkZXNjcmlwdG9yID0gRigibWFwX2ludDMyX2VudW0iKTsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGtleV9kZXNjcmlwdG9yID0KKyAgICAgICAgZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgia2V5Iik7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiB2YWx1ZV9kZXNjcmlwdG9yID0KKyAgICAgICAgZGVzY3JpcHRvci0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgidmFsdWUiKTsKKyAgICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigibWFwX2ludDMyX2VudW0iKSk7CisgICAgRVhQRUNUX0VRKDAsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKCpzdWJfbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5X2Rlc2NyaXB0b3IpKTsKKyAgICBFWFBFQ1RfRVEoMCwgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKQorICAgICAgICAgICAgICAgICAgICAgLT5HZXRFbnVtKCpzdWJfbWVzc2FnZSwgdmFsdWVfZGVzY3JpcHRvcikKKyAgICAgICAgICAgICAgICAgICAgIC0+bnVtYmVyKCkpOworICB9CisgIC8vIE1hcCB1c2luZyBtZXNzYWdlIGFzIHZhbHVlIGhhcyBiZWVuIHRlc3RlZCBpbiBvdGhlciBwbGFjZS4gVGh1cywgd2UgZG9uJ3QKKyAgLy8gdGVzdCBpdCBoZXJlLgorfQorCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvbWFwX3Rlc3RfdXRpbC5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9tYXBfdGVzdF91dGlsLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGVhZjBmNAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvbWFwX3Rlc3RfdXRpbC5oCkBAIC0wLDAgKzEsMTU5IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfTUFQX1RFU1RfVVRJTF9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX01BUF9URVNUX1VUSUxfSF9fCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWFwX3VuaXR0ZXN0LnBiLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworbmFtZXNwYWNlIHVuaXR0ZXN0ID0gOjpwcm90b2J1Zl91bml0dGVzdDsKKworY2xhc3MgTWFwVGVzdFV0aWwgeworIHB1YmxpYzoKKyAgLy8gU2V0IGV2ZXJ5IGZpZWxkIGluIHRoZSBUZXN0TWFwIG1lc3NhZ2UgdG8gYSB1bmlxdWUgdmFsdWUuCisgIHN0YXRpYyB2b2lkIFNldE1hcEZpZWxkcyh1bml0dGVzdDo6VGVzdE1hcCogbWVzc2FnZSk7CisKKyAgLy8gU2V0IGV2ZXJ5IGZpZWxkIGluIHRoZSBUZXN0QXJlbmFNYXAgbWVzc2FnZSB0byBhIHVuaXF1ZSB2YWx1ZS4KKyAgc3RhdGljIHZvaWQgU2V0QXJlbmFNYXBGaWVsZHModW5pdHRlc3Q6OlRlc3RBcmVuYU1hcCogbWVzc2FnZSk7CisKKyAgLy8gU2V0IGV2ZXJ5IGZpZWxkIGluIHRoZSBtZXNzYWdlIHRvIGEgZGVmYXVsdCB2YWx1ZS4KKyAgc3RhdGljIHZvaWQgU2V0TWFwRmllbGRzSW5pdGlhbGl6ZWQodW5pdHRlc3Q6OlRlc3RNYXAqIG1lc3NhZ2UpOworCisgIC8vIE1vZGlmeSBhbGwgdGhlIG1hcCBmaWVsZHMgb2YgdGhlIG1lc3NhZ2UgKHdoaWNoIHNob3VsZCBhbHJlYWR5IGhhdmUgYmVlbgorICAvLyBpbml0aWFsaXplZCB3aXRoIFNldE1hcEZpZWxkcygpKS4KKyAgc3RhdGljIHZvaWQgTW9kaWZ5TWFwRmllbGRzKHVuaXR0ZXN0OjpUZXN0TWFwKiBtZXNzYWdlKTsKKworICAvLyBDaGVjayB0aGF0IGFsbCBmaWVsZHMgaGF2ZSB0aGUgdmFsdWVzIHRoYXQgdGhleSBzaG91bGQgaGF2ZSBhZnRlcgorICAvLyBTZXRNYXBGaWVsZHMoKSBpcyBjYWxsZWQuCisgIHN0YXRpYyB2b2lkIEV4cGVjdE1hcEZpZWxkc1NldChjb25zdCB1bml0dGVzdDo6VGVzdE1hcCYgbWVzc2FnZSk7CisKKyAgLy8gQ2hlY2sgdGhhdCBhbGwgZmllbGRzIGhhdmUgdGhlIHZhbHVlcyB0aGF0IHRoZXkgc2hvdWxkIGhhdmUgYWZ0ZXIKKyAgLy8gU2V0TWFwRmllbGRzKCkgaXMgY2FsbGVkIGZvciBUZXN0QXJlbmFNYXAuCisgIHN0YXRpYyB2b2lkIEV4cGVjdEFyZW5hTWFwRmllbGRzU2V0KGNvbnN0IHVuaXR0ZXN0OjpUZXN0QXJlbmFNYXAmIG1lc3NhZ2UpOworCisgIC8vIENoZWNrIHRoYXQgYWxsIGZpZWxkcyBoYXZlIHRoZSB2YWx1ZXMgdGhhdCB0aGV5IHNob3VsZCBoYXZlIGFmdGVyCisgIC8vIFNldE1hcEZpZWxkc0luaXRpYWxpemVkKCkgaXMgY2FsbGVkLgorICBzdGF0aWMgdm9pZCBFeHBlY3RNYXBGaWVsZHNTZXRJbml0aWFsaXplZCgKKyAgICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0TWFwJiBtZXNzYWdlKTsKKworICAvLyBFeHBlY3QgdGhhdCB0aGUgbWVzc2FnZSBpcyBtb2RpZmllZCBhcyB3b3VsZCBiZSBleHBlY3RlZCBmcm9tCisgIC8vIE1vZGlmeU1hcEZpZWxkcygpLgorICBzdGF0aWMgdm9pZCBFeHBlY3RNYXBGaWVsZHNNb2RpZmllZChjb25zdCB1bml0dGVzdDo6VGVzdE1hcCYgbWVzc2FnZSk7CisKKyAgLy8gQ2hlY2sgdGhhdCBhbGwgZmllbGRzIGFyZSBlbXB0eS4KKyAgc3RhdGljIHZvaWQgRXhwZWN0Q2xlYXIoY29uc3QgdW5pdHRlc3Q6OlRlc3RNYXAmIG1lc3NhZ2UpOworCisgIC8vIENoZWNrIHRoYXQgYWxsIG1hcCBmaWVsZHMgaGF2ZSB0aGUgZ2l2ZW4gc2l6ZS4KKyAgc3RhdGljIHZvaWQgRXhwZWN0TWFwc1NpemUoY29uc3QgdW5pdHRlc3Q6OlRlc3RNYXAmIG1lc3NhZ2UsIGludCBzaXplKTsKKworICAvLyBHZXQgcG9pbnRlcnMgb2YgbWFwIGVudHJpZXMgYXQgZ2l2ZW4gaW5kZXguCisgIHN0YXRpYyBzdGQ6OnZlY3Rvcjxjb25zdCBNZXNzYWdlKj4gR2V0TWFwRW50cmllcygKKyAgICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0TWFwJiBtZXNzYWdlLCBpbnQgaW5kZXgpOworCisgIC8vIEdldCBwb2ludGVycyBvZiBtYXAgZW50cmllcyBmcm9tIHJlbGVhc2UuCisgIHN0YXRpYyBzdGQ6OnZlY3Rvcjxjb25zdCBNZXNzYWdlKj4gR2V0TWFwRW50cmllc0Zyb21SZWxlYXNlKAorICAgICAgdW5pdHRlc3Q6OlRlc3RNYXAqIG1lc3NhZ2UpOworfTsKKworLy8gTGlrZSBhYm92ZSwgYnV0IHVzZSB0aGUgcmVmbGVjdGlvbiBpbnRlcmZhY2UuCitjbGFzcyBNYXBSZWZsZWN0aW9uVGVzdGVyIHsKKyBwdWJsaWM6CisgIC8vIGJhc2VfZGVzY3JpcHRvciBtdXN0IGJlIGEgZGVzY3JpcHRvciBmb3IgVGVzdE1hcCwgd2hpY2ggaXMgdXNlZCBmb3IKKyAgLy8gTWFwUmVmbGVjdGlvblRlc3RlciB0byBmZXRjaCB0aGUgRmllbGREZXNjcmlwdG9ycyBuZWVkZWQgdG8gdXNlIHRoZQorICAvLyByZWZsZWN0aW9uIGludGVyZmFjZS4KKyAgZXhwbGljaXQgTWFwUmVmbGVjdGlvblRlc3Rlcihjb25zdCBEZXNjcmlwdG9yKiBiYXNlX2Rlc2NyaXB0b3IpOworCisgIHZvaWQgU2V0TWFwRmllbGRzVmlhUmVmbGVjdGlvbihNZXNzYWdlKiBtZXNzYWdlKTsKKyAgdm9pZCBTZXRNYXBGaWVsZHNWaWFNYXBSZWZsZWN0aW9uKE1lc3NhZ2UqIG1lc3NhZ2UpOworICB2b2lkIENsZWFyTWFwRmllbGRzVmlhUmVmbGVjdGlvbihNZXNzYWdlKiBtZXNzYWdlKTsKKyAgdm9pZCBNb2RpZnlNYXBGaWVsZHNWaWFSZWZsZWN0aW9uKE1lc3NhZ2UqIG1lc3NhZ2UpOworICB2b2lkIFJlbW92ZUxhc3RNYXBzVmlhUmVmbGVjdGlvbihNZXNzYWdlKiBtZXNzYWdlKTsKKyAgdm9pZCBSZWxlYXNlTGFzdE1hcHNWaWFSZWZsZWN0aW9uKE1lc3NhZ2UqIG1lc3NhZ2UpOworICB2b2lkIFN3YXBNYXBzVmlhUmVmbGVjdGlvbihNZXNzYWdlKiBtZXNzYWdlKTsKKyAgdm9pZCBNdXRhYmxlVW5rbm93bkZpZWxkc09mTWFwRmllbGRzVmlhUmVmbGVjdGlvbihNZXNzYWdlKiBtZXNzYWdlKTsKKyAgdm9pZCBFeHBlY3RNYXBGaWVsZHNTZXRWaWFSZWZsZWN0aW9uKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UpOworICB2b2lkIEV4cGVjdE1hcEZpZWxkc1NldFZpYVJlZmxlY3Rpb25JdGVyYXRvcihNZXNzYWdlKiBtZXNzYWdlKTsKKyAgdm9pZCBFeHBlY3RDbGVhclZpYVJlZmxlY3Rpb24oY29uc3QgTWVzc2FnZSYgbWVzc2FnZSk7CisgIHZvaWQgRXhwZWN0Q2xlYXJWaWFSZWZsZWN0aW9uSXRlcmF0b3IoTWVzc2FnZSogbWVzc2FnZSk7CisgIHZvaWQgRXhwZWN0TWFwRW50cnlDbGVhclZpYVJlZmxlY3Rpb24oTWVzc2FnZSogbWVzc2FnZSk7CisKKyBwcml2YXRlOgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIEYoY29uc3Qgc3RyaW5nJiBuYW1lKTsKKworICBjb25zdCBEZXNjcmlwdG9yKiBiYXNlX2Rlc2NyaXB0b3JfOworCisgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIG1hcF9lbnVtX2Jhcl87CisgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIG1hcF9lbnVtX2Jhel87CisgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIG1hcF9lbnVtX2Zvb187CisKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmb3JlaWduX2NfOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIG1hcF9pbnQzMl9pbnQzMl9rZXlfOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIG1hcF9pbnQzMl9pbnQzMl92YWxfOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIG1hcF9pbnQ2NF9pbnQ2NF9rZXlfOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIG1hcF9pbnQ2NF9pbnQ2NF92YWxfOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIG1hcF91aW50MzJfdWludDMyX2tleV87CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogbWFwX3VpbnQzMl91aW50MzJfdmFsXzsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBtYXBfdWludDY0X3VpbnQ2NF9rZXlfOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIG1hcF91aW50NjRfdWludDY0X3ZhbF87CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogbWFwX3NpbnQzMl9zaW50MzJfa2V5XzsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBtYXBfc2ludDMyX3NpbnQzMl92YWxfOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIG1hcF9zaW50NjRfc2ludDY0X2tleV87CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogbWFwX3NpbnQ2NF9zaW50NjRfdmFsXzsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBtYXBfZml4ZWQzMl9maXhlZDMyX2tleV87CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogbWFwX2ZpeGVkMzJfZml4ZWQzMl92YWxfOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIG1hcF9maXhlZDY0X2ZpeGVkNjRfa2V5XzsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBtYXBfZml4ZWQ2NF9maXhlZDY0X3ZhbF87CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogbWFwX3NmaXhlZDMyX3NmaXhlZDMyX2tleV87CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogbWFwX3NmaXhlZDMyX3NmaXhlZDMyX3ZhbF87CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogbWFwX3NmaXhlZDY0X3NmaXhlZDY0X2tleV87CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogbWFwX3NmaXhlZDY0X3NmaXhlZDY0X3ZhbF87CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogbWFwX2ludDMyX2Zsb2F0X2tleV87CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogbWFwX2ludDMyX2Zsb2F0X3ZhbF87CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogbWFwX2ludDMyX2RvdWJsZV9rZXlfOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIG1hcF9pbnQzMl9kb3VibGVfdmFsXzsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBtYXBfYm9vbF9ib29sX2tleV87CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogbWFwX2Jvb2xfYm9vbF92YWxfOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIG1hcF9zdHJpbmdfc3RyaW5nX2tleV87CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogbWFwX3N0cmluZ19zdHJpbmdfdmFsXzsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBtYXBfaW50MzJfYnl0ZXNfa2V5XzsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBtYXBfaW50MzJfYnl0ZXNfdmFsXzsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBtYXBfaW50MzJfZW51bV9rZXlfOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIG1hcF9pbnQzMl9lbnVtX3ZhbF87CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZV9rZXlfOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIG1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2VfdmFsXzsKK307CisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9NQVBfVEVTVF9VVElMX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9tYXBfdGVzdF91dGlsX2ltcGwuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvbWFwX3Rlc3RfdXRpbF9pbXBsLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjNiYTRlMAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvbWFwX3Rlc3RfdXRpbF9pbXBsLmgKQEAgLTAsMCArMSw0OTAgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9NQVBfVEVTVF9VVElMX0lNUExfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9NQVBfVEVTVF9VVElMX0lNUExfSF9fCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbG9nZ2luZy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKworCisjZGVmaW5lIEVYUEVDVF9UUlVFIEdPT0dMRV9DSEVDSworI2RlZmluZSBBU1NFUlRfVFJVRSBHT09HTEVfQ0hFQ0sKKyNkZWZpbmUgRVhQRUNUX0ZBTFNFKENPTkQpIEdPT0dMRV9DSEVDSyghKENPTkQpKQorI2RlZmluZSBFWFBFQ1RfRVEgR09PR0xFX0NIRUNLX0VRCisjZGVmaW5lIEFTU0VSVF9FUSBHT09HTEVfQ0hFQ0tfRVEKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWZfdW5pdHRlc3Qge30gIC8vIGZvcndhcmQgZGVjbGFyYXRpb24KKworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworbmFtZXNwYWNlIHVuaXR0ZXN0ID0gOjpwcm90b2J1Zl91bml0dGVzdDsKKworY2xhc3MgTWFwVGVzdFV0aWxJbXBsIHsKKyBwdWJsaWM6CisgIC8vIFNldCBldmVyeSBmaWVsZCBpbiB0aGUgVGVzdE1hcCBtZXNzYWdlIHRvIGEgdW5pcXVlIHZhbHVlLgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgRW51bVR5cGUsIEVudW1UeXBlIGVudW1fdmFsdWUwLAorICAgICAgICAgICAgRW51bVR5cGUgZW51bV92YWx1ZTEsIHR5cGVuYW1lIE1hcE1lc3NhZ2U+CisgIHN0YXRpYyB2b2lkIFNldE1hcEZpZWxkcyhNYXBNZXNzYWdlKiBtZXNzYWdlKTsKKworICAvLyBTZXQgZXZlcnkgZmllbGQgaW4gdGhlIFRlc3RBcmVuYU1hcCBtZXNzYWdlIHRvIGEgdW5pcXVlIHZhbHVlLgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgRW51bVR5cGUsIEVudW1UeXBlIGVudW1fdmFsdWUwLAorICAgICAgICAgICAgRW51bVR5cGUgZW51bV92YWx1ZTEsIHR5cGVuYW1lIE1hcE1lc3NhZ2U+CisgIHN0YXRpYyB2b2lkIFNldEFyZW5hTWFwRmllbGRzKE1hcE1lc3NhZ2UqIG1lc3NhZ2UpOworCisgIC8vIFNldCBldmVyeSBmaWVsZCBpbiB0aGUgbWVzc2FnZSB0byBhIGRlZmF1bHQgdmFsdWUuCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBNYXBNZXNzYWdlPgorICBzdGF0aWMgdm9pZCBTZXRNYXBGaWVsZHNJbml0aWFsaXplZChNYXBNZXNzYWdlKiBtZXNzYWdlKTsKKworICAvLyBNb2RpZnkgYWxsIHRoZSBtYXAgZmllbGRzIG9mIHRoZSBtZXNzYWdlICh3aGljaCBzaG91bGQgYWxyZWFkeSBoYXZlIGJlZW4KKyAgLy8gaW5pdGlhbGl6ZWQgd2l0aCBTZXRNYXBGaWVsZHMoKSkuCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBFbnVtVHlwZSwgRW51bVR5cGUgZW51bV92YWx1ZSwgdHlwZW5hbWUgTWFwTWVzc2FnZT4KKyAgc3RhdGljIHZvaWQgTW9kaWZ5TWFwRmllbGRzKE1hcE1lc3NhZ2UqIG1lc3NhZ2UpOworCisgIC8vIENoZWNrIHRoYXQgYWxsIGZpZWxkcyBoYXZlIHRoZSB2YWx1ZXMgdGhhdCB0aGV5IHNob3VsZCBoYXZlIGFmdGVyCisgIC8vIFNldE1hcEZpZWxkcygpIGlzIGNhbGxlZC4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIEVudW1UeXBlLCBFbnVtVHlwZSBlbnVtX3ZhbHVlMCwKKyAgICAgICAgICAgIEVudW1UeXBlIGVudW1fdmFsdWUxLCB0eXBlbmFtZSBNYXBNZXNzYWdlPgorICBzdGF0aWMgdm9pZCBFeHBlY3RNYXBGaWVsZHNTZXQoY29uc3QgTWFwTWVzc2FnZSYgbWVzc2FnZSk7CisKKyAgLy8gQ2hlY2sgdGhhdCBhbGwgZmllbGRzIGhhdmUgdGhlIHZhbHVlcyB0aGF0IHRoZXkgc2hvdWxkIGhhdmUgYWZ0ZXIKKyAgLy8gU2V0TWFwRmllbGRzKCkgaXMgY2FsbGVkIGZvciBUZXN0QXJlbmFNYXAuCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBFbnVtVHlwZSwgRW51bVR5cGUgZW51bV92YWx1ZTAsCisgICAgICAgICAgICBFbnVtVHlwZSBlbnVtX3ZhbHVlMSwgdHlwZW5hbWUgTWFwTWVzc2FnZT4KKyAgc3RhdGljIHZvaWQgRXhwZWN0QXJlbmFNYXBGaWVsZHNTZXQoY29uc3QgTWFwTWVzc2FnZSYgbWVzc2FnZSk7CisKKyAgLy8gQ2hlY2sgdGhhdCBhbGwgZmllbGRzIGhhdmUgdGhlIHZhbHVlcyB0aGF0IHRoZXkgc2hvdWxkIGhhdmUgYWZ0ZXIKKyAgLy8gU2V0TWFwRmllbGRzSW5pdGlhbGl6ZWQoKSBpcyBjYWxsZWQuCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBFbnVtVHlwZSwgRW51bVR5cGUgZW51bV92YWx1ZSwgdHlwZW5hbWUgTWFwTWVzc2FnZT4KKyAgc3RhdGljIHZvaWQgRXhwZWN0TWFwRmllbGRzU2V0SW5pdGlhbGl6ZWQoY29uc3QgTWFwTWVzc2FnZSYgbWVzc2FnZSk7CisKKyAgLy8gRXhwZWN0IHRoYXQgdGhlIG1lc3NhZ2UgaXMgbW9kaWZpZWQgYXMgd291bGQgYmUgZXhwZWN0ZWQgZnJvbQorICAvLyBNb2RpZnlNYXBGaWVsZHMoKS4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIEVudW1UeXBlLCBFbnVtVHlwZSBlbnVtX3ZhbHVlMCwKKyAgICAgICAgICAgIEVudW1UeXBlIGVudW1fdmFsdWUxLCB0eXBlbmFtZSBNYXBNZXNzYWdlPgorICBzdGF0aWMgdm9pZCBFeHBlY3RNYXBGaWVsZHNNb2RpZmllZChjb25zdCBNYXBNZXNzYWdlJiBtZXNzYWdlKTsKKworICAvLyBDaGVjayB0aGF0IGFsbCBmaWVsZHMgYXJlIGVtcHR5LgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgTWFwTWVzc2FnZT4KKyAgc3RhdGljIHZvaWQgRXhwZWN0Q2xlYXIoY29uc3QgTWFwTWVzc2FnZSYgbWVzc2FnZSk7CisKKyAgLy8gLy8gQ2hlY2sgdGhhdCBhbGwgbWFwIGZpZWxkcyBoYXZlIHRoZSBnaXZlbiBzaXplLgorICAvLyB0ZW1wbGF0ZSA8dHlwZW5hbWUgTWFwTWVzc2FnZT4KKyAgLy8gc3RhdGljIHZvaWQgRXhwZWN0TWFwc1NpemUoY29uc3QgTWFwTWVzc2FnZSYgbWVzc2FnZSwgaW50IHNpemUpOworCisgIC8vIC8vIEdldCBwb2ludGVycyBvZiBtYXAgZW50cmllcyBhdCBnaXZlbiBpbmRleC4KKyAgLy8gc3RhdGljIHN0ZDo6dmVjdG9yPGNvbnN0IE1lc3NhZ2UqPiBHZXRNYXBFbnRyaWVzKAorICAvLyAgICAgY29uc3QgTWFwTWVzc2FnZSYgbWVzc2FnZSwgaW50IGluZGV4KTsKKworICAvLyAvLyBHZXQgcG9pbnRlcnMgb2YgbWFwIGVudHJpZXMgZnJvbSByZWxlYXNlLgorICAvLyBzdGF0aWMgc3RkOjp2ZWN0b3I8Y29uc3QgTWVzc2FnZSo+IEdldE1hcEVudHJpZXNGcm9tUmVsZWFzZSgKKyAgLy8gICAgIE1hcE1lc3NhZ2UqIG1lc3NhZ2UpOworfTsKKwordGVtcGxhdGUgPHR5cGVuYW1lIEVudW1UeXBlLCBFbnVtVHlwZSBlbnVtX3ZhbHVlMCwKKyAgICAgICAgICBFbnVtVHlwZSBlbnVtX3ZhbHVlMSwgdHlwZW5hbWUgTWFwTWVzc2FnZT4KK3ZvaWQgTWFwVGVzdFV0aWxJbXBsOjpTZXRNYXBGaWVsZHMoTWFwTWVzc2FnZSogbWVzc2FnZSkgeworICAvLyBBZGQgZmlyc3QgZWxlbWVudC4KKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9pbnQzMl9pbnQzMigpKVswXSA9IDA7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfaW50NjRfaW50NjQoKSlbMF0gPSAwOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX3VpbnQzMl91aW50MzIoKSlbMF0gPSAwOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX3VpbnQ2NF91aW50NjQoKSlbMF0gPSAwOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX3NpbnQzMl9zaW50MzIoKSlbMF0gPSAwOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX3NpbnQ2NF9zaW50NjQoKSlbMF0gPSAwOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2ZpeGVkMzJfZml4ZWQzMigpKVswXSA9IDA7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfZml4ZWQ2NF9maXhlZDY0KCkpWzBdID0gMDsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9zZml4ZWQzMl9zZml4ZWQzMigpKVswXSA9IDA7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfc2ZpeGVkNjRfc2ZpeGVkNjQoKSlbMF0gPSAwOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2ludDMyX2Zsb2F0KCkpWzBdID0gMC4wOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2ludDMyX2RvdWJsZSgpKVswXSA9IDAuMDsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9ib29sX2Jvb2woKSlbMF0gPSBmYWxzZTsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9zdHJpbmdfc3RyaW5nKCkpWyIwIl0gPSAiMCI7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfaW50MzJfYnl0ZXMoKSlbMF0gPSAiMCI7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfaW50MzJfZW51bSgpKVswXSA9IGVudW1fdmFsdWUwOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSgpKVswXS5zZXRfYygwKTsKKworICAvLyBBZGQgc2Vjb25kIGVsZW1lbnQKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9pbnQzMl9pbnQzMigpKVsxXSA9IDE7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfaW50NjRfaW50NjQoKSlbMV0gPSAxOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX3VpbnQzMl91aW50MzIoKSlbMV0gPSAxOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX3VpbnQ2NF91aW50NjQoKSlbMV0gPSAxOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX3NpbnQzMl9zaW50MzIoKSlbMV0gPSAxOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX3NpbnQ2NF9zaW50NjQoKSlbMV0gPSAxOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2ZpeGVkMzJfZml4ZWQzMigpKVsxXSA9IDE7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfZml4ZWQ2NF9maXhlZDY0KCkpWzFdID0gMTsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9zZml4ZWQzMl9zZml4ZWQzMigpKVsxXSA9IDE7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfc2ZpeGVkNjRfc2ZpeGVkNjQoKSlbMV0gPSAxOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2ludDMyX2Zsb2F0KCkpWzFdID0gMS4wOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2ludDMyX2RvdWJsZSgpKVsxXSA9IDEuMDsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9ib29sX2Jvb2woKSlbMV0gPSB0cnVlOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX3N0cmluZ19zdHJpbmcoKSlbIjEiXSA9ICIxIjsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9pbnQzMl9ieXRlcygpKVsxXSA9ICIxIjsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9pbnQzMl9lbnVtKCkpWzFdID0gZW51bV92YWx1ZTE7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlKCkpWzFdLnNldF9jKDEpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRW51bVR5cGUsIEVudW1UeXBlIGVudW1fdmFsdWUwLAorICAgICAgICAgIEVudW1UeXBlIGVudW1fdmFsdWUxLCB0eXBlbmFtZSBNYXBNZXNzYWdlPgordm9pZCBNYXBUZXN0VXRpbEltcGw6OlNldEFyZW5hTWFwRmllbGRzKE1hcE1lc3NhZ2UqIG1lc3NhZ2UpIHsKKyAgLy8gQWRkIGZpcnN0IGVsZW1lbnQuCisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfaW50MzJfaW50MzIoKSlbMF0gPSAwOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2ludDY0X2ludDY0KCkpWzBdID0gMDsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF91aW50MzJfdWludDMyKCkpWzBdID0gMDsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF91aW50NjRfdWludDY0KCkpWzBdID0gMDsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9zaW50MzJfc2ludDMyKCkpWzBdID0gMDsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9zaW50NjRfc2ludDY0KCkpWzBdID0gMDsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9maXhlZDMyX2ZpeGVkMzIoKSlbMF0gPSAwOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2ZpeGVkNjRfZml4ZWQ2NCgpKVswXSA9IDA7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfc2ZpeGVkMzJfc2ZpeGVkMzIoKSlbMF0gPSAwOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX3NmaXhlZDY0X3NmaXhlZDY0KCkpWzBdID0gMDsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9pbnQzMl9mbG9hdCgpKVswXSA9IDAuMDsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9pbnQzMl9kb3VibGUoKSlbMF0gPSAwLjA7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfYm9vbF9ib29sKCkpWzBdID0gZmFsc2U7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfc3RyaW5nX3N0cmluZygpKVsiMCJdID0gIjAiOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2ludDMyX2J5dGVzKCkpWzBdID0gIjAiOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2ludDMyX2VudW0oKSlbMF0gPSBlbnVtX3ZhbHVlMDsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UoKSlbMF0uc2V0X2MoMCk7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlX25vX2FyZW5hKCkpWzBdLnNldF9jKDApOworCisgIC8vIEFkZCBzZWNvbmQgZWxlbWVudAorICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2ludDMyX2ludDMyKCkpWzFdID0gMTsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9pbnQ2NF9pbnQ2NCgpKVsxXSA9IDE7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfdWludDMyX3VpbnQzMigpKVsxXSA9IDE7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfdWludDY0X3VpbnQ2NCgpKVsxXSA9IDE7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfc2ludDMyX3NpbnQzMigpKVsxXSA9IDE7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfc2ludDY0X3NpbnQ2NCgpKVsxXSA9IDE7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfZml4ZWQzMl9maXhlZDMyKCkpWzFdID0gMTsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9maXhlZDY0X2ZpeGVkNjQoKSlbMV0gPSAxOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX3NmaXhlZDMyX3NmaXhlZDMyKCkpWzFdID0gMTsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9zZml4ZWQ2NF9zZml4ZWQ2NCgpKVsxXSA9IDE7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfaW50MzJfZmxvYXQoKSlbMV0gPSAxLjA7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfaW50MzJfZG91YmxlKCkpWzFdID0gMS4wOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2Jvb2xfYm9vbCgpKVsxXSA9IHRydWU7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfc3RyaW5nX3N0cmluZygpKVsiMSJdID0gIjEiOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2ludDMyX2J5dGVzKCkpWzFdID0gIjEiOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2ludDMyX2VudW0oKSlbMV0gPSBlbnVtX3ZhbHVlMTsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UoKSlbMV0uc2V0X2MoMSk7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlX25vX2FyZW5hKCkpWzFdLnNldF9jKDEpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgTWFwTWVzc2FnZT4KK3ZvaWQgTWFwVGVzdFV0aWxJbXBsOjpTZXRNYXBGaWVsZHNJbml0aWFsaXplZChNYXBNZXNzYWdlKiBtZXNzYWdlKSB7CisgIC8vIEFkZCBmaXJzdCBlbGVtZW50IHVzaW5nIGJyYWNrZXQgb3BlcmF0b3IsIHdoaWNoIHNob3VsZCBhc3NpZ24gZGVmYXVsdAorICAvLyB2YWx1ZSBhdXRvbWF0aWNhbGx5LgorICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2ludDMyX2ludDMyKCkpWzBdOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2ludDY0X2ludDY0KCkpWzBdOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX3VpbnQzMl91aW50MzIoKSlbMF07CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfdWludDY0X3VpbnQ2NCgpKVswXTsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9zaW50MzJfc2ludDMyKCkpWzBdOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX3NpbnQ2NF9zaW50NjQoKSlbMF07CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfZml4ZWQzMl9maXhlZDMyKCkpWzBdOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2ZpeGVkNjRfZml4ZWQ2NCgpKVswXTsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9zZml4ZWQzMl9zZml4ZWQzMigpKVswXTsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9zZml4ZWQ2NF9zZml4ZWQ2NCgpKVswXTsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9pbnQzMl9mbG9hdCgpKVswXTsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9pbnQzMl9kb3VibGUoKSlbMF07CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfYm9vbF9ib29sKCkpWzBdOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX3N0cmluZ19zdHJpbmcoKSlbIjAiXTsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9pbnQzMl9ieXRlcygpKVswXTsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9pbnQzMl9lbnVtKCkpWzBdOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSgpKVswXTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVudW1UeXBlLCBFbnVtVHlwZSBlbnVtX3ZhbHVlLCB0eXBlbmFtZSBNYXBNZXNzYWdlPgordm9pZCBNYXBUZXN0VXRpbEltcGw6Ok1vZGlmeU1hcEZpZWxkcyhNYXBNZXNzYWdlKiBtZXNzYWdlKSB7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfaW50MzJfaW50MzIoKSlbMV0gPSAyOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2ludDY0X2ludDY0KCkpWzFdID0gMjsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF91aW50MzJfdWludDMyKCkpWzFdID0gMjsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF91aW50NjRfdWludDY0KCkpWzFdID0gMjsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9zaW50MzJfc2ludDMyKCkpWzFdID0gMjsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9zaW50NjRfc2ludDY0KCkpWzFdID0gMjsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9maXhlZDMyX2ZpeGVkMzIoKSlbMV0gPSAyOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2ZpeGVkNjRfZml4ZWQ2NCgpKVsxXSA9IDI7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfc2ZpeGVkMzJfc2ZpeGVkMzIoKSlbMV0gPSAyOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX3NmaXhlZDY0X3NmaXhlZDY0KCkpWzFdID0gMjsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9pbnQzMl9mbG9hdCgpKVsxXSA9IDIuMDsKKyAgKCptZXNzYWdlLT5tdXRhYmxlX21hcF9pbnQzMl9kb3VibGUoKSlbMV0gPSAyLjA7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfYm9vbF9ib29sKCkpWzFdID0gZmFsc2U7CisgICgqbWVzc2FnZS0+bXV0YWJsZV9tYXBfc3RyaW5nX3N0cmluZygpKVsiMSJdID0gIjIiOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2ludDMyX2J5dGVzKCkpWzFdID0gIjIiOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2ludDMyX2VudW0oKSlbMV0gPSBlbnVtX3ZhbHVlOworICAoKm1lc3NhZ2UtPm11dGFibGVfbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSgpKVsxXS5zZXRfYygyKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIE1hcE1lc3NhZ2U+Cit2b2lkIE1hcFRlc3RVdGlsSW1wbDo6RXhwZWN0Q2xlYXIoY29uc3QgTWFwTWVzc2FnZSYgbWVzc2FnZSkgeworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfaW50MzJfaW50MzIoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfaW50NjRfaW50NjQoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfdWludDMyX3VpbnQzMigpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm1hcF91aW50NjRfdWludDY0KCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX3NpbnQzMl9zaW50MzIoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfc2ludDY0X3NpbnQ2NCgpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm1hcF9maXhlZDMyX2ZpeGVkMzIoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfZml4ZWQ2NF9maXhlZDY0KCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX3NmaXhlZDMyX3NmaXhlZDMyKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX3NmaXhlZDY0X3NmaXhlZDY0KCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX2ludDMyX2Zsb2F0KCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX2ludDMyX2RvdWJsZSgpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm1hcF9ib29sX2Jvb2woKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfc3RyaW5nX3N0cmluZygpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm1hcF9pbnQzMl9ieXRlcygpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm1hcF9pbnQzMl9lbnVtKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSgpLnNpemUoKSk7Cit9CisKKworCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRW51bVR5cGUsIEVudW1UeXBlIGVudW1fdmFsdWUwLAorICAgICAgICAgIEVudW1UeXBlIGVudW1fdmFsdWUxLCB0eXBlbmFtZSBNYXBNZXNzYWdlPgordm9pZCBNYXBUZXN0VXRpbEltcGw6OkV4cGVjdE1hcEZpZWxkc1NldChjb25zdCBNYXBNZXNzYWdlJiBtZXNzYWdlKSB7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLm1hcF9pbnQzMl9pbnQzMigpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLm1hcF9pbnQ2NF9pbnQ2NCgpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLm1hcF91aW50MzJfdWludDMyKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX3VpbnQ2NF91aW50NjQoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfc2ludDMyX3NpbnQzMigpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLm1hcF9zaW50NjRfc2ludDY0KCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX2ZpeGVkMzJfZml4ZWQzMigpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLm1hcF9maXhlZDY0X2ZpeGVkNjQoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfc2ZpeGVkMzJfc2ZpeGVkMzIoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfc2ZpeGVkNjRfc2ZpeGVkNjQoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfaW50MzJfZmxvYXQoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfaW50MzJfZG91YmxlKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX2Jvb2xfYm9vbCgpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLm1hcF9zdHJpbmdfc3RyaW5nKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX2ludDMyX2J5dGVzKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX2ludDMyX2VudW0oKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlKCkuc2l6ZSgpKTsKKworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfaW50MzJfaW50MzIoKS5hdCgwKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm1hcF9pbnQ2NF9pbnQ2NCgpLmF0KDApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX3VpbnQzMl91aW50MzIoKS5hdCgwKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm1hcF91aW50NjRfdWludDY0KCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfc2ludDMyX3NpbnQzMigpLmF0KDApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX3NpbnQ2NF9zaW50NjQoKS5hdCgwKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm1hcF9maXhlZDMyX2ZpeGVkMzIoKS5hdCgwKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm1hcF9maXhlZDY0X2ZpeGVkNjQoKS5hdCgwKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm1hcF9zZml4ZWQzMl9zZml4ZWQzMigpLmF0KDApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX3NmaXhlZDY0X3NmaXhlZDY0KCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfaW50MzJfZmxvYXQoKS5hdCgwKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm1hcF9pbnQzMl9kb3VibGUoKS5hdCgwKSk7CisgIEVYUEVDVF9FUShmYWxzZSwgbWVzc2FnZS5tYXBfYm9vbF9ib29sKCkuYXQoMCkpOworICBFWFBFQ1RfRVEoIjAiLCBtZXNzYWdlLm1hcF9zdHJpbmdfc3RyaW5nKCkuYXQoIjAiKSk7CisgIEVYUEVDVF9FUSgiMCIsIG1lc3NhZ2UubWFwX2ludDMyX2J5dGVzKCkuYXQoMCkpOworICBFWFBFQ1RfRVEoZW51bV92YWx1ZTAsIG1lc3NhZ2UubWFwX2ludDMyX2VudW0oKS5hdCgwKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UoKS5hdCgwKS5jKCkpOworCisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLm1hcF9pbnQzMl9pbnQzMigpLmF0KDEpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX2ludDY0X2ludDY0KCkuYXQoMSkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfdWludDMyX3VpbnQzMigpLmF0KDEpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX3VpbnQ2NF91aW50NjQoKS5hdCgxKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLm1hcF9zaW50MzJfc2ludDMyKCkuYXQoMSkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfc2ludDY0X3NpbnQ2NCgpLmF0KDEpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX2ZpeGVkMzJfZml4ZWQzMigpLmF0KDEpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX2ZpeGVkNjRfZml4ZWQ2NCgpLmF0KDEpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX3NmaXhlZDMyX3NmaXhlZDMyKCkuYXQoMSkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfc2ZpeGVkNjRfc2ZpeGVkNjQoKS5hdCgxKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLm1hcF9pbnQzMl9mbG9hdCgpLmF0KDEpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX2ludDMyX2RvdWJsZSgpLmF0KDEpKTsKKyAgRVhQRUNUX0VRKHRydWUsIG1lc3NhZ2UubWFwX2Jvb2xfYm9vbCgpLmF0KDEpKTsKKyAgRVhQRUNUX0VRKCIxIiwgbWVzc2FnZS5tYXBfc3RyaW5nX3N0cmluZygpLmF0KCIxIikpOworICBFWFBFQ1RfRVEoIjEiLCBtZXNzYWdlLm1hcF9pbnQzMl9ieXRlcygpLmF0KDEpKTsKKyAgRVhQRUNUX0VRKGVudW1fdmFsdWUxLCBtZXNzYWdlLm1hcF9pbnQzMl9lbnVtKCkuYXQoMSkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlKCkuYXQoMSkuYygpKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVudW1UeXBlLCBFbnVtVHlwZSBlbnVtX3ZhbHVlMCwKKyAgICAgICAgICBFbnVtVHlwZSBlbnVtX3ZhbHVlMSwgdHlwZW5hbWUgTWFwTWVzc2FnZT4KK3ZvaWQgTWFwVGVzdFV0aWxJbXBsOjpFeHBlY3RBcmVuYU1hcEZpZWxkc1NldChjb25zdCBNYXBNZXNzYWdlJiBtZXNzYWdlKSB7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLm1hcF9pbnQzMl9pbnQzMigpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLm1hcF9pbnQ2NF9pbnQ2NCgpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLm1hcF91aW50MzJfdWludDMyKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX3VpbnQ2NF91aW50NjQoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfc2ludDMyX3NpbnQzMigpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLm1hcF9zaW50NjRfc2ludDY0KCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX2ZpeGVkMzJfZml4ZWQzMigpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLm1hcF9maXhlZDY0X2ZpeGVkNjQoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfc2ZpeGVkMzJfc2ZpeGVkMzIoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfc2ZpeGVkNjRfc2ZpeGVkNjQoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfaW50MzJfZmxvYXQoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfaW50MzJfZG91YmxlKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX2Jvb2xfYm9vbCgpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLm1hcF9zdHJpbmdfc3RyaW5nKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX2ludDMyX2J5dGVzKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX2ludDMyX2VudW0oKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZV9ub19hcmVuYSgpLnNpemUoKSk7CisKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX2ludDMyX2ludDMyKCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfaW50NjRfaW50NjQoKS5hdCgwKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm1hcF91aW50MzJfdWludDMyKCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfdWludDY0X3VpbnQ2NCgpLmF0KDApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX3NpbnQzMl9zaW50MzIoKS5hdCgwKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm1hcF9zaW50NjRfc2ludDY0KCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfZml4ZWQzMl9maXhlZDMyKCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfZml4ZWQ2NF9maXhlZDY0KCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfc2ZpeGVkMzJfc2ZpeGVkMzIoKS5hdCgwKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm1hcF9zZml4ZWQ2NF9zZml4ZWQ2NCgpLmF0KDApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX2ludDMyX2Zsb2F0KCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfaW50MzJfZG91YmxlKCkuYXQoMCkpOworICBFWFBFQ1RfRVEoZmFsc2UsIG1lc3NhZ2UubWFwX2Jvb2xfYm9vbCgpLmF0KDApKTsKKyAgRVhQRUNUX0VRKCIwIiwgbWVzc2FnZS5tYXBfc3RyaW5nX3N0cmluZygpLmF0KCIwIikpOworICBFWFBFQ1RfRVEoIjAiLCBtZXNzYWdlLm1hcF9pbnQzMl9ieXRlcygpLmF0KDApKTsKKyAgRVhQRUNUX0VRKGVudW1fdmFsdWUwLCBtZXNzYWdlLm1hcF9pbnQzMl9lbnVtKCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlKCkuYXQoMCkuYygpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZV9ub19hcmVuYSgpLmF0KDApLmMoKSk7CisKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX2ludDMyX2ludDMyKCkuYXQoMSkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfaW50NjRfaW50NjQoKS5hdCgxKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLm1hcF91aW50MzJfdWludDMyKCkuYXQoMSkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfdWludDY0X3VpbnQ2NCgpLmF0KDEpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX3NpbnQzMl9zaW50MzIoKS5hdCgxKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLm1hcF9zaW50NjRfc2ludDY0KCkuYXQoMSkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfZml4ZWQzMl9maXhlZDMyKCkuYXQoMSkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfZml4ZWQ2NF9maXhlZDY0KCkuYXQoMSkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfc2ZpeGVkMzJfc2ZpeGVkMzIoKS5hdCgxKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLm1hcF9zZml4ZWQ2NF9zZml4ZWQ2NCgpLmF0KDEpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX2ludDMyX2Zsb2F0KCkuYXQoMSkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfaW50MzJfZG91YmxlKCkuYXQoMSkpOworICBFWFBFQ1RfRVEodHJ1ZSwgbWVzc2FnZS5tYXBfYm9vbF9ib29sKCkuYXQoMSkpOworICBFWFBFQ1RfRVEoIjEiLCBtZXNzYWdlLm1hcF9zdHJpbmdfc3RyaW5nKCkuYXQoIjEiKSk7CisgIEVYUEVDVF9FUSgiMSIsIG1lc3NhZ2UubWFwX2ludDMyX2J5dGVzKCkuYXQoMSkpOworICBFWFBFQ1RfRVEoZW51bV92YWx1ZTEsIG1lc3NhZ2UubWFwX2ludDMyX2VudW0oKS5hdCgxKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLm1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UoKS5hdCgxKS5jKCkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlX25vX2FyZW5hKCkuYXQoMSkuYygpKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVudW1UeXBlLCBFbnVtVHlwZSBlbnVtX3ZhbHVlLCB0eXBlbmFtZSBNYXBNZXNzYWdlPgordm9pZCBNYXBUZXN0VXRpbEltcGw6OkV4cGVjdE1hcEZpZWxkc1NldEluaXRpYWxpemVkKAorICAgIGNvbnN0IE1hcE1lc3NhZ2UmIG1lc3NhZ2UpIHsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX2ludDMyX2ludDMyKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX2ludDY0X2ludDY0KCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX3VpbnQzMl91aW50MzIoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfdWludDY0X3VpbnQ2NCgpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLm1hcF9zaW50MzJfc2ludDMyKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX3NpbnQ2NF9zaW50NjQoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfZml4ZWQzMl9maXhlZDMyKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX2ZpeGVkNjRfZml4ZWQ2NCgpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLm1hcF9zZml4ZWQzMl9zZml4ZWQzMigpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLm1hcF9zZml4ZWQ2NF9zZml4ZWQ2NCgpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLm1hcF9pbnQzMl9mbG9hdCgpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLm1hcF9pbnQzMl9kb3VibGUoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfYm9vbF9ib29sKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UubWFwX3N0cmluZ19zdHJpbmcoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfaW50MzJfYnl0ZXMoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5tYXBfaW50MzJfZW51bSgpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLm1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UoKS5zaXplKCkpOworCisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm1hcF9pbnQzMl9pbnQzMigpLmF0KDApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX2ludDY0X2ludDY0KCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfdWludDMyX3VpbnQzMigpLmF0KDApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX3VpbnQ2NF91aW50NjQoKS5hdCgwKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm1hcF9zaW50MzJfc2ludDMyKCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfc2ludDY0X3NpbnQ2NCgpLmF0KDApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX2ZpeGVkMzJfZml4ZWQzMigpLmF0KDApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX2ZpeGVkNjRfZml4ZWQ2NCgpLmF0KDApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX3NmaXhlZDMyX3NmaXhlZDMyKCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfc2ZpeGVkNjRfc2ZpeGVkNjQoKS5hdCgwKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm1hcF9pbnQzMl9mbG9hdCgpLmF0KDApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX2ludDMyX2RvdWJsZSgpLmF0KDApKTsKKyAgRVhQRUNUX0VRKGZhbHNlLCBtZXNzYWdlLm1hcF9ib29sX2Jvb2woKS5hdCgwKSk7CisgIEVYUEVDVF9FUSgiIiwgbWVzc2FnZS5tYXBfc3RyaW5nX3N0cmluZygpLmF0KCIwIikpOworICBFWFBFQ1RfRVEoIiIsIG1lc3NhZ2UubWFwX2ludDMyX2J5dGVzKCkuYXQoMCkpOworICBFWFBFQ1RfRVEoZW51bV92YWx1ZSwgbWVzc2FnZS5tYXBfaW50MzJfZW51bSgpLmF0KDApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSgpLmF0KDApLkJ5dGVTaXplKCkpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRW51bVR5cGUsIEVudW1UeXBlIGVudW1fdmFsdWUwLAorICAgICAgICAgICAgRW51bVR5cGUgZW51bV92YWx1ZTEsIHR5cGVuYW1lIE1hcE1lc3NhZ2U+Cit2b2lkIE1hcFRlc3RVdGlsSW1wbDo6RXhwZWN0TWFwRmllbGRzTW9kaWZpZWQoCisgICAgY29uc3QgTWFwTWVzc2FnZSYgbWVzc2FnZSkgeworICAvLyBNb2RpZnlNYXBGaWVsZHMgb25seSBzZXRzIHRoZSBzZWNvbmQgZWxlbWVudCBvZiBlYWNoIGZpZWxkLiAgSW4gYWRkaXRpb24gdG8KKyAgLy8gdmVyaWZ5aW5nIHRoaXMsIHdlIGFsc28gdmVyaWZ5IHRoYXQgdGhlIGZpcnN0IGVsZW1lbnQgYW5kIHNpemUgd2VyZSAqbm90KgorICAvLyBtb2RpZmllZC4KKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX2ludDMyX2ludDMyKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX2ludDY0X2ludDY0KCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX3VpbnQzMl91aW50MzIoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfdWludDY0X3VpbnQ2NCgpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLm1hcF9zaW50MzJfc2ludDMyKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX3NpbnQ2NF9zaW50NjQoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfZml4ZWQzMl9maXhlZDMyKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX2ZpeGVkNjRfZml4ZWQ2NCgpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLm1hcF9zZml4ZWQzMl9zZml4ZWQzMigpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLm1hcF9zZml4ZWQ2NF9zZml4ZWQ2NCgpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLm1hcF9pbnQzMl9mbG9hdCgpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLm1hcF9pbnQzMl9kb3VibGUoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfYm9vbF9ib29sKCkuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX3N0cmluZ19zdHJpbmcoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfaW50MzJfYnl0ZXMoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfaW50MzJfZW51bSgpLnNpemUoKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLm1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UoKS5zaXplKCkpOworCisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm1hcF9pbnQzMl9pbnQzMigpLmF0KDApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX2ludDY0X2ludDY0KCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfdWludDMyX3VpbnQzMigpLmF0KDApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX3VpbnQ2NF91aW50NjQoKS5hdCgwKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm1hcF9zaW50MzJfc2ludDMyKCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfc2ludDY0X3NpbnQ2NCgpLmF0KDApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX2ZpeGVkMzJfZml4ZWQzMigpLmF0KDApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX2ZpeGVkNjRfZml4ZWQ2NCgpLmF0KDApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX3NmaXhlZDMyX3NmaXhlZDMyKCkuYXQoMCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5tYXBfc2ZpeGVkNjRfc2ZpeGVkNjQoKS5hdCgwKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm1hcF9pbnQzMl9mbG9hdCgpLmF0KDApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX2ludDMyX2RvdWJsZSgpLmF0KDApKTsKKyAgRVhQRUNUX0VRKGZhbHNlLCBtZXNzYWdlLm1hcF9ib29sX2Jvb2woKS5hdCgwKSk7CisgIEVYUEVDVF9FUSgiMCIsIG1lc3NhZ2UubWFwX3N0cmluZ19zdHJpbmcoKS5hdCgiMCIpKTsKKyAgRVhQRUNUX0VRKCIwIiwgbWVzc2FnZS5tYXBfaW50MzJfYnl0ZXMoKS5hdCgwKSk7CisgIEVYUEVDVF9FUShlbnVtX3ZhbHVlMCwgbWVzc2FnZS5tYXBfaW50MzJfZW51bSgpLmF0KDApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UubWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSgpLmF0KDApLmMoKSk7CisKKyAgLy8gQWN0dWFsbHkgdmVyaWZ5IHRoZSBzZWNvbmQgKG1vZGlmaWVkKSBlbGVtZW50cyBub3cuCisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLm1hcF9pbnQzMl9pbnQzMigpLmF0KDEpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX2ludDY0X2ludDY0KCkuYXQoMSkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfdWludDMyX3VpbnQzMigpLmF0KDEpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX3VpbnQ2NF91aW50NjQoKS5hdCgxKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLm1hcF9zaW50MzJfc2ludDMyKCkuYXQoMSkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfc2ludDY0X3NpbnQ2NCgpLmF0KDEpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX2ZpeGVkMzJfZml4ZWQzMigpLmF0KDEpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX2ZpeGVkNjRfZml4ZWQ2NCgpLmF0KDEpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX3NmaXhlZDMyX3NmaXhlZDMyKCkuYXQoMSkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5tYXBfc2ZpeGVkNjRfc2ZpeGVkNjQoKS5hdCgxKSk7CisgIEVYUEVDVF9FUSgyLCBtZXNzYWdlLm1hcF9pbnQzMl9mbG9hdCgpLmF0KDEpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX2ludDMyX2RvdWJsZSgpLmF0KDEpKTsKKyAgRVhQRUNUX0VRKGZhbHNlLCBtZXNzYWdlLm1hcF9ib29sX2Jvb2woKS5hdCgxKSk7CisgIEVYUEVDVF9FUSgiMiIsIG1lc3NhZ2UubWFwX3N0cmluZ19zdHJpbmcoKS5hdCgiMSIpKTsKKyAgRVhQRUNUX0VRKCIyIiwgbWVzc2FnZS5tYXBfaW50MzJfYnl0ZXMoKS5hdCgxKSk7CisgIEVYUEVDVF9FUShlbnVtX3ZhbHVlMSwgbWVzc2FnZS5tYXBfaW50MzJfZW51bSgpLmF0KDEpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UubWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSgpLmF0KDEpLmMoKSk7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9NQVBfVEVTVF9VVElMX0lNUExfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF90eXBlX2hhbmRsZXIuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvbWFwX3R5cGVfaGFuZGxlci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY4YWQ3NTgKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF90eXBlX2hhbmRsZXIuaApAQCAtMCwwICsxLDcyNyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX1RZUEVfSEFORExFUl9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1RZUEVfSEFORExFUl9IX18KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9hcmVuYS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfbWVzc2FnZV91dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0X2xpdGVfaW5sLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKKy8vIFVzZWQgZm9yIGNvbXBpbGUgdGltZSB0eXBlIHNlbGVjdGlvbi4gTWFwSWY6OnR5cGUgd2lsbCBiZSBUcnVlVHlwZSBpZiBGbGFnIGlzCisvLyB0cnVlIGFuZCBGYWxzZVR5cGUgb3RoZXJ3aXNlLgordGVtcGxhdGU8Ym9vbCBGbGFnLCB0eXBlbmFtZSBUcnVlVHlwZSwgdHlwZW5hbWUgRmFsc2VUeXBlPgorc3RydWN0IE1hcElmOworCit0ZW1wbGF0ZTx0eXBlbmFtZSBUcnVlVHlwZSwgdHlwZW5hbWUgRmFsc2VUeXBlPgorc3RydWN0IE1hcElmPHRydWUsIFRydWVUeXBlLCBGYWxzZVR5cGU+IHsKKyAgdHlwZWRlZiBUcnVlVHlwZSB0eXBlOworfTsKKwordGVtcGxhdGU8dHlwZW5hbWUgVHJ1ZVR5cGUsIHR5cGVuYW1lIEZhbHNlVHlwZT4KK3N0cnVjdCBNYXBJZjxmYWxzZSwgVHJ1ZVR5cGUsIEZhbHNlVHlwZT4geworICB0eXBlZGVmIEZhbHNlVHlwZSB0eXBlOworfTsKKworLy8gSW4gcHJvdG8yIE1hcCwgZW51bSBuZWVkcyB0byBiZSBpbml0aWFsaXplZCB0byBnaXZlbiBkZWZhdWx0IHZhbHVlLCB3aGlsZQorLy8gb3RoZXIgdHlwZXMnIGRlZmF1bHQgdmFsdWUgY2FuIGJlIGluZmVycmVkIGZyb20gdGhlIHR5cGUuCit0ZW1wbGF0ZSA8Ym9vbCBJc0VudW0sIHR5cGVuYW1lIFR5cGU+CitjbGFzcyBNYXBWYWx1ZUluaXRpYWxpemVyIHsKKyBwdWJsaWM6CisgIHN0YXRpYyBpbmxpbmUgdm9pZCBJbml0aWFsaXplKFR5cGUmIHR5cGUsIGludCBkZWZhdWx0X2VudW1fdmFsdWUpOworfTsKKwordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+CitjbGFzcyBNYXBWYWx1ZUluaXRpYWxpemVyPHRydWUsIFR5cGU+IHsKKyBwdWJsaWM6CisgIHN0YXRpYyBpbmxpbmUgdm9pZCBJbml0aWFsaXplKFR5cGUmIHZhbHVlLCBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlKSB7CisgICAgdmFsdWUgPSBzdGF0aWNfY2FzdDxUeXBlPihkZWZhdWx0X2VudW1fdmFsdWUpOworICB9Cit9OworCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4KK2NsYXNzIE1hcFZhbHVlSW5pdGlhbGl6ZXI8ZmFsc2UsIFR5cGU+IHsKKyBwdWJsaWM6CisgIHN0YXRpYyBpbmxpbmUgdm9pZCBJbml0aWFsaXplKFR5cGUmIHZhbHVlLCBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlKSB7fQorfTsKKwordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGUsIGJvb2wgaXNfYXJlbmFfY29uc3RydWN0YWJsZT4KK2NsYXNzIE1hcEFyZW5hTWVzc2FnZUNyZWF0b3IgeworIHB1YmxpYzoKKyAgLy8gVXNlIGFyZW5hIHRvIGNyZWF0ZSBtZXNzYWdlIGlmIFR5cGUgaXMgYXJlbmEgY29uc3RydWN0YWJsZS4gT3RoZXJ3aXNlLAorICAvLyBjcmVhdGUgdGhlIG1lc3NhZ2Ugb24gaGVhcC4KKyAgc3RhdGljIGlubGluZSBUeXBlKiBDcmVhdGVNZXNzYWdlKEFyZW5hKiBhcmVuYSk7Cit9OwordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+CitjbGFzcyBNYXBBcmVuYU1lc3NhZ2VDcmVhdG9yPFR5cGUsIHRydWU+IHsKKyBwdWJsaWM6CisgIHN0YXRpYyBpbmxpbmUgVHlwZSogQ3JlYXRlTWVzc2FnZShBcmVuYSogYXJlbmEpIHsKKyAgICByZXR1cm4gQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VHlwZT4oYXJlbmEpOworICB9Cit9OwordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+CitjbGFzcyBNYXBBcmVuYU1lc3NhZ2VDcmVhdG9yPFR5cGUsIGZhbHNlPiB7CisgcHVibGljOgorICBzdGF0aWMgaW5saW5lIFR5cGUqIENyZWF0ZU1lc3NhZ2UoQXJlbmEqIGFyZW5hKSB7CisgICAgcmV0dXJuIEFyZW5hOjpDcmVhdGU8VHlwZT4oYXJlbmEpOworICB9Cit9OworCisvLyBEZWZpbmUgY29uc3RhbnRzIGZvciBnaXZlbiB3aXJlIGZpZWxkIHR5cGUKK3RlbXBsYXRlIDxXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIGZpZWxkX3R5cGUsIHR5cGVuYW1lIFR5cGU+CitjbGFzcyBNYXBXaXJlRmllbGRUeXBlVHJhaXRzIHt9OworCisjZGVmaW5lIFRZUEVfVFJBSVRTKEZpZWxkVHlwZSwgQ1R5cGUsIFdpcmVGb3JtYXRUeXBlLCBJc01lc3NhZ2UsIElzRW51bSkgICBcCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUeXBlPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGNsYXNzIE1hcFdpcmVGaWVsZFR5cGVUcmFpdHM8V2lyZUZvcm1hdExpdGU6OlRZUEVfIyNGaWVsZFR5cGUsIFR5cGU+IHsgICBcCisgICBwdWJsaWM6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgc3RhdGljIGNvbnN0IGJvb2wga0lzTWVzc2FnZSA9IElzTWVzc2FnZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgc3RhdGljIGNvbnN0IGJvb2wga0lzRW51bSA9IElzRW51bTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgdHlwZWRlZiB0eXBlbmFtZSBNYXBJZjxrSXNNZXNzYWdlLCBUeXBlKiwgQ1R5cGU+Ojp0eXBlIFR5cGVPbk1lbW9yeTsgICBcCisgICAgdHlwZWRlZiB0eXBlbmFtZSBNYXBJZjxrSXNFbnVtLCBpbnQsIFR5cGU+Ojp0eXBlIE1hcEVudHJ5QWNjZXNzb3JUeXBlOyBcCisgICAgc3RhdGljIGNvbnN0IFdpcmVGb3JtYXRMaXRlOjpXaXJlVHlwZSBrV2lyZVR5cGUgPSAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV8jI1dpcmVGb3JtYXRUeXBlOyAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIH07CisKK1RZUEVfVFJBSVRTKE1FU1NBR0UgLCBUeXBlLCBMRU5HVEhfREVMSU1JVEVELCB0cnVlLCBmYWxzZSkKK1RZUEVfVFJBSVRTKFNUUklORyAgLCBBcmVuYVN0cmluZ1B0ciwgTEVOR1RIX0RFTElNSVRFRCwgZmFsc2UsIGZhbHNlKQorVFlQRV9UUkFJVFMoQllURVMgICAsIEFyZW5hU3RyaW5nUHRyICwgIExFTkdUSF9ERUxJTUlURUQsIGZhbHNlLCBmYWxzZSkKK1RZUEVfVFJBSVRTKElOVDY0ICAgLCBpbnQ2NCAgLCAgVkFSSU5UICwgZmFsc2UsIGZhbHNlKQorVFlQRV9UUkFJVFMoVUlOVDY0ICAsIHVpbnQ2NCAsICBWQVJJTlQgLCBmYWxzZSwgZmFsc2UpCitUWVBFX1RSQUlUUyhJTlQzMiAgICwgaW50MzIgICwgIFZBUklOVCAsIGZhbHNlLCBmYWxzZSkKK1RZUEVfVFJBSVRTKFVJTlQzMiAgLCB1aW50MzIgLCAgVkFSSU5UICwgZmFsc2UsIGZhbHNlKQorVFlQRV9UUkFJVFMoU0lOVDY0ICAsIGludDY0ICAsICBWQVJJTlQgLCBmYWxzZSwgZmFsc2UpCitUWVBFX1RSQUlUUyhTSU5UMzIgICwgaW50MzIgICwgIFZBUklOVCAsIGZhbHNlLCBmYWxzZSkKK1RZUEVfVFJBSVRTKEVOVU0gICAgLCBpbnQgICAgLCAgVkFSSU5UICwgZmFsc2UsIHRydWUgKQorVFlQRV9UUkFJVFMoRE9VQkxFICAsIGRvdWJsZSAsICBGSVhFRDY0LCBmYWxzZSwgZmFsc2UpCitUWVBFX1RSQUlUUyhGTE9BVCAgICwgZmxvYXQgICwgIEZJWEVEMzIsIGZhbHNlLCBmYWxzZSkKK1RZUEVfVFJBSVRTKEZJWEVENjQgLCB1aW50NjQgLCAgRklYRUQ2NCwgZmFsc2UsIGZhbHNlKQorVFlQRV9UUkFJVFMoRklYRUQzMiAsIHVpbnQzMiAsICBGSVhFRDMyLCBmYWxzZSwgZmFsc2UpCitUWVBFX1RSQUlUUyhTRklYRUQ2NCwgaW50NjQgICwgIEZJWEVENjQsIGZhbHNlLCBmYWxzZSkKK1RZUEVfVFJBSVRTKFNGSVhFRDMyLCBpbnQzMiAgLCAgRklYRUQzMiwgZmFsc2UsIGZhbHNlKQorVFlQRV9UUkFJVFMoQk9PTCAgICAsIGJvb2wgICAsICBWQVJJTlQgLCBmYWxzZSwgZmFsc2UpCisKKyN1bmRlZiBUWVBFX1RSQUlUUworCit0ZW1wbGF0ZSA8V2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBmaWVsZF90eXBlLCB0eXBlbmFtZSBUeXBlPgorY2xhc3MgTWFwVHlwZUhhbmRsZXIge307CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBUeXBlPgorY2xhc3MgTWFwVHlwZUhhbmRsZXI8V2lyZUZvcm1hdExpdGU6OlRZUEVfTUVTU0FHRSwgVHlwZT4geworIHB1YmxpYzoKKyAgLy8gRW51bSB0eXBlIGNhbm5vdCBiZSB1c2VkIGZvciBNYXBUeXBlSGFuZGxlcjo6UmVhZC4gRGVmaW5lIGEgdHlwZSB3aGljaCB3aWxsCisgIC8vIHJlcGxhY2UgRW51bSB3aXRoIGludC4KKyAgdHlwZWRlZiB0eXBlbmFtZSBNYXBXaXJlRmllbGRUeXBlVHJhaXRzPFdpcmVGb3JtYXRMaXRlOjpUWVBFX01FU1NBR0UsCisgICAgICBUeXBlPjo6TWFwRW50cnlBY2Nlc3NvclR5cGUgTWFwRW50cnlBY2Nlc3NvclR5cGU7CisgIC8vIEludGVybmFsIHN0b3JlZCB0eXBlIGluIE1hcEVudHJ5TGl0ZSBmb3IgZ2l2ZW4gd2lyZSBmaWVsZCB0eXBlLgorICB0eXBlZGVmIHR5cGVuYW1lIE1hcFdpcmVGaWVsZFR5cGVUcmFpdHM8V2lyZUZvcm1hdExpdGU6OlRZUEVfTUVTU0FHRSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGU+OjpUeXBlT25NZW1vcnkgVHlwZU9uTWVtb3J5OworICAvLyBDb3JyZXNwb25kaW5nIHdpcmUgdHlwZSBmb3IgZmllbGQgdHlwZS4KKyAgc3RhdGljIGNvbnN0IFdpcmVGb3JtYXRMaXRlOjpXaXJlVHlwZSBrV2lyZVR5cGUgPQorICAgICAgTWFwV2lyZUZpZWxkVHlwZVRyYWl0czxXaXJlRm9ybWF0TGl0ZTo6VFlQRV9NRVNTQUdFLCBUeXBlPjo6a1dpcmVUeXBlOworICAvLyBXaGV0aGVyIHdpcmUgdHlwZSBpcyBmb3IgbWVzc2FnZS4KKyAgc3RhdGljIGNvbnN0IGJvb2wga0lzTWVzc2FnZSA9CisgICAgICBNYXBXaXJlRmllbGRUeXBlVHJhaXRzPFdpcmVGb3JtYXRMaXRlOjpUWVBFX01FU1NBR0UsIFR5cGU+OjprSXNNZXNzYWdlOworICAvLyBXaGV0aGVyIHdpcmUgdHlwZSBpcyBmb3IgZW51bS4KKyAgc3RhdGljIGNvbnN0IGJvb2wga0lzRW51bSA9CisgICAgICBNYXBXaXJlRmllbGRUeXBlVHJhaXRzPFdpcmVGb3JtYXRMaXRlOjpUWVBFX01FU1NBR0UsIFR5cGU+OjprSXNFbnVtOworCisgIC8vIEZ1bmN0aW9ucyB1c2VkIGluIHBhcnNpbmcgYW5kIHNlcmlhbGl6YXRpb24uID09PT09PT09PT09PT09PT09PT0KKyAgc3RhdGljIGlubGluZSBpbnQgQnl0ZVNpemUoY29uc3QgTWFwRW50cnlBY2Nlc3NvclR5cGUmIHZhbHVlKTsKKyAgc3RhdGljIGlubGluZSBpbnQgR2V0Q2FjaGVkU2l6ZShjb25zdCBNYXBFbnRyeUFjY2Vzc29yVHlwZSYgdmFsdWUpOworICBzdGF0aWMgaW5saW5lIGJvb2wgUmVhZChpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgIE1hcEVudHJ5QWNjZXNzb3JUeXBlKiB2YWx1ZSk7CisgIHN0YXRpYyBpbmxpbmUgdm9pZCBXcml0ZShpbnQgZmllbGQsIGNvbnN0IE1hcEVudHJ5QWNjZXNzb3JUeXBlJiB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KTsKKyAgc3RhdGljIGlubGluZSB1aW50OCogV3JpdGVUb0FycmF5KGludCBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1hcEVudHJ5QWNjZXNzb3JUeXBlJiB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4KiBvdXRwdXQpOworCisgIC8vIEZ1bmN0aW9ucyB0byBtYW5pcHVsYXRlIGRhdGEgb24gbWVtb3J5LiA9PT09PT09PT09PT09PT09PT09PT09PT0KKyAgc3RhdGljIGlubGluZSBjb25zdCBUeXBlJiBHZXRFeHRlcm5hbFJlZmVyZW5jZShjb25zdCBUeXBlKiB2YWx1ZSk7CisgIHN0YXRpYyBpbmxpbmUgdm9pZCBEZWxldGVOb0FyZW5hKGNvbnN0IFR5cGUqIHgpOworICBzdGF0aWMgaW5saW5lIHZvaWQgTWVyZ2UoY29uc3QgVHlwZSYgZnJvbSwgVHlwZSoqIHRvLCBBcmVuYSogYXJlbmEpOworICBzdGF0aWMgaW5saW5lIHZvaWQgQ2xlYXIoVHlwZSoqIHZhbHVlLCBBcmVuYSogYXJlbmEpOworICBzdGF0aWMgaW5saW5lIHZvaWQgQ2xlYXJNYXliZUJ5RGVmYXVsdEVudW0oVHlwZSoqIHZhbHVlLCBBcmVuYSogYXJlbmEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlKTsKKyAgc3RhdGljIGlubGluZSB2b2lkIEluaXRpYWxpemUoVHlwZSoqIHgsIEFyZW5hKiBhcmVuYSk7CisKKyAgc3RhdGljIGlubGluZSB2b2lkIEluaXRpYWxpemVNYXliZUJ5RGVmYXVsdEVudW0oVHlwZSoqIHgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBkZWZhdWx0X2VudW1fdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFyZW5hKiBhcmVuYSk7CisgIHN0YXRpYyBpbmxpbmUgVHlwZSogRW5zdXJlTXV0YWJsZShUeXBlKiogdmFsdWUsIEFyZW5hKiBhcmVuYSk7CisgIC8vIFNwYWNlVXNlZEluTWFwRW50cnk6IFJldHVybiBieXRlcyB1c2VkIGJ5IHZhbHVlIGluIE1hcEVudHJ5LCBleGNsdWRpbmcKKyAgLy8gdGhvc2UgYWxyZWFkeSBjYWxjdWxhdGUgaW4gc2l6ZW9mKE1hcEZpZWxkKS4KKyAgc3RhdGljIGlubGluZSBpbnQgU3BhY2VVc2VkSW5NYXBFbnRyeShjb25zdCBUeXBlKiB2YWx1ZSk7CisgIC8vIFJldHVybiBieXRlcyB1c2VkIGJ5IHZhbHVlIGluIE1hcC4KKyAgc3RhdGljIGlubGluZSBpbnQgU3BhY2VVc2VkSW5NYXAoY29uc3QgVHlwZSYgdmFsdWUpOworICAvLyBBc3NpZ24gZGVmYXVsdCB2YWx1ZSB0byBnaXZlbiBpbnN0YW5jZS4KKyAgc3RhdGljIGlubGluZSB2b2lkIEFzc2lnbkRlZmF1bHRWYWx1ZShUeXBlKiogdmFsdWUpOworICAvLyBSZXR1cm4gZGVmYXVsdCBpbnN0YW5jZSBpZiB2YWx1ZSBpcyBub3QgaW5pdGlhbGl6ZWQgd2hlbiBjYWxsaW5nIGNvbnN0CisgIC8vIHJlZmVyZW5jZSBhY2Nlc3Nvci4KKyAgc3RhdGljIGlubGluZSBjb25zdCBUeXBlJiBEZWZhdWx0SWZOb3RJbml0aWFsaXplZCgKKyAgICAgIGNvbnN0IFR5cGUqIHZhbHVlLCBjb25zdCBUeXBlKiBkZWZhdWx0X3ZhbHVlKTsKKyAgLy8gQ2hlY2sgaWYgYWxsIHJlcXVpcmVkIGZpZWxkcyBoYXZlIHZhbHVlcyBzZXQuCisgIHN0YXRpYyBpbmxpbmUgYm9vbCBJc0luaXRpYWxpemVkKFR5cGUqIHZhbHVlKTsKK307CisKKyNkZWZpbmUgTUFQX0hBTkRMRVIoRmllbGRUeXBlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgY2xhc3MgTWFwVHlwZUhhbmRsZXI8V2lyZUZvcm1hdExpdGU6OlRZUEVfIyNGaWVsZFR5cGUsIFR5cGU+IHsgICAgICAgICAgICAgIFwKKyAgIHB1YmxpYzogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICB0eXBlZGVmIHR5cGVuYW1lIE1hcFdpcmVGaWVsZFR5cGVUcmFpdHM8V2lyZUZvcm1hdExpdGU6OlRZUEVfIyNGaWVsZFR5cGUsIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZT46Ok1hcEVudHJ5QWNjZXNzb3JUeXBlICAgICAgIFwKKyAgICAgICAgTWFwRW50cnlBY2Nlc3NvclR5cGU7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICB0eXBlZGVmIHR5cGVuYW1lIE1hcFdpcmVGaWVsZFR5cGVUcmFpdHM8V2lyZUZvcm1hdExpdGU6OlRZUEVfIyNGaWVsZFR5cGUsIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZT46OlR5cGVPbk1lbW9yeSBUeXBlT25NZW1vcnk7IFwKKyAgICBzdGF0aWMgY29uc3QgV2lyZUZvcm1hdExpdGU6OldpcmVUeXBlIGtXaXJlVHlwZSA9ICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgTWFwV2lyZUZpZWxkVHlwZVRyYWl0czxXaXJlRm9ybWF0TGl0ZTo6VFlQRV8jI0ZpZWxkVHlwZSwgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlPjo6a1dpcmVUeXBlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBzdGF0aWMgY29uc3QgYm9vbCBrSXNNZXNzYWdlID0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgTWFwV2lyZUZpZWxkVHlwZVRyYWl0czxXaXJlRm9ybWF0TGl0ZTo6VFlQRV8jI0ZpZWxkVHlwZSwgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlPjo6a0lzTWVzc2FnZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBzdGF0aWMgY29uc3QgYm9vbCBrSXNFbnVtID0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgTWFwV2lyZUZpZWxkVHlwZVRyYWl0czxXaXJlRm9ybWF0TGl0ZTo6VFlQRV8jI0ZpZWxkVHlwZSwgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlPjo6a0lzRW51bTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBzdGF0aWMgaW5saW5lIGludCBCeXRlU2l6ZShjb25zdCBNYXBFbnRyeUFjY2Vzc29yVHlwZSYgdmFsdWUpOyAgICAgICAgICAgIFwKKyAgICBzdGF0aWMgaW5saW5lIGludCBHZXRDYWNoZWRTaXplKGNvbnN0IE1hcEVudHJ5QWNjZXNzb3JUeXBlJiB2YWx1ZSk7ICAgICAgIFwKKyAgICBzdGF0aWMgaW5saW5lIGJvb2wgUmVhZChpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYXBFbnRyeUFjY2Vzc29yVHlwZSogdmFsdWUpOyAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBzdGF0aWMgaW5saW5lIHZvaWQgV3JpdGUoaW50IGZpZWxkLCBjb25zdCBNYXBFbnRyeUFjY2Vzc29yVHlwZSYgdmFsdWUsICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpOyAgICAgICAgICAgICAgICAgIFwKKyAgICBzdGF0aWMgaW5saW5lIHVpbnQ4KiBXcml0ZVRvQXJyYXkoaW50IGZpZWxkLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWFwRW50cnlBY2Nlc3NvclR5cGUmIHZhbHVlLCAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDgqIG91dHB1dCk7ICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBzdGF0aWMgaW5saW5lIGNvbnN0IE1hcEVudHJ5QWNjZXNzb3JUeXBlJiBHZXRFeHRlcm5hbFJlZmVyZW5jZSggICAgICAgICAgIFwKKyAgICAgICAgY29uc3QgVHlwZU9uTWVtb3J5JiB2YWx1ZSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBzdGF0aWMgaW5saW5lIHZvaWQgRGVsZXRlTm9BcmVuYShjb25zdCBUeXBlT25NZW1vcnkmIHgpOyAgICAgICAgICAgICAgICAgIFwKKyAgICBzdGF0aWMgaW5saW5lIHZvaWQgTWVyZ2UoY29uc3QgTWFwRW50cnlBY2Nlc3NvclR5cGUmIGZyb20sICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZU9uTWVtb3J5KiB0bywgQXJlbmEqIGFyZW5hKTsgICAgICAgICAgICAgICAgIFwKKyAgICBzdGF0aWMgaW5saW5lIHZvaWQgQ2xlYXIoVHlwZU9uTWVtb3J5KiB2YWx1ZSwgQXJlbmEqIGFyZW5hKTsgICAgICAgICAgICAgIFwKKyAgICBzdGF0aWMgaW5saW5lIHZvaWQgQ2xlYXJNYXliZUJ5RGVmYXVsdEVudW0oVHlwZU9uTWVtb3J5KiB2YWx1ZSwgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJlbmEqIGFyZW5hLCAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGRlZmF1bHRfZW51bSk7ICAgICAgICAgICAgIFwKKyAgICBzdGF0aWMgaW5saW5lIGludCBTcGFjZVVzZWRJbk1hcEVudHJ5KGNvbnN0IFR5cGVPbk1lbW9yeSYgdmFsdWUpOyAgICAgICAgIFwKKyAgICBzdGF0aWMgaW5saW5lIGludCBTcGFjZVVzZWRJbk1hcChjb25zdCBUeXBlT25NZW1vcnkmIHZhbHVlKTsgICAgICAgICAgICAgIFwKKyAgICBzdGF0aWMgaW5saW5lIGludCBTcGFjZVVzZWRJbk1hcChjb25zdCBzdHJpbmcmIHZhbHVlKTsgICAgICAgICAgICAgICAgICAgIFwKKyAgICBzdGF0aWMgaW5saW5lIHZvaWQgQXNzaWduRGVmYXVsdFZhbHVlKFR5cGVPbk1lbW9yeSogdmFsdWUpOyAgICAgICAgICAgICAgIFwKKyAgICBzdGF0aWMgaW5saW5lIGNvbnN0IE1hcEVudHJ5QWNjZXNzb3JUeXBlJiBEZWZhdWx0SWZOb3RJbml0aWFsaXplZCggICAgICAgIFwKKyAgICAgICAgY29uc3QgVHlwZU9uTWVtb3J5JiB2YWx1ZSwgY29uc3QgVHlwZU9uTWVtb3J5JiBkZWZhdWx0X3ZhbHVlKTsgICAgICAgIFwKKyAgICBzdGF0aWMgaW5saW5lIGJvb2wgSXNJbml0aWFsaXplZChjb25zdCBUeXBlT25NZW1vcnkmIHZhbHVlKTsgICAgICAgICAgICAgIFwKKyAgICBzdGF0aWMgdm9pZCBEZWxldGVOb0FyZW5hKFR5cGVPbk1lbW9yeSYgdmFsdWUpOyAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBzdGF0aWMgaW5saW5lIHZvaWQgSW5pdGlhbGl6ZShUeXBlT25NZW1vcnkqIHZhbHVlLCBBcmVuYSogYXJlbmEpOyAgICAgICAgIFwKKyAgICBzdGF0aWMgaW5saW5lIHZvaWQgSW5pdGlhbGl6ZU1heWJlQnlEZWZhdWx0RW51bShUeXBlT25NZW1vcnkqIHZhbHVlLCAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlLCAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBcmVuYSogYXJlbmEpOyAgICAgICAgICAgIFwKKyAgICBzdGF0aWMgaW5saW5lIE1hcEVudHJ5QWNjZXNzb3JUeXBlKiBFbnN1cmVNdXRhYmxlKFR5cGVPbk1lbW9yeSogdmFsdWUsICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFyZW5hKiBhcmVuYSk7ICAgICAgICAgIFwKKyAgfTsKK01BUF9IQU5ETEVSKFNUUklORykKK01BUF9IQU5ETEVSKEJZVEVTKQorTUFQX0hBTkRMRVIoSU5UNjQpCitNQVBfSEFORExFUihVSU5UNjQpCitNQVBfSEFORExFUihJTlQzMikKK01BUF9IQU5ETEVSKFVJTlQzMikKK01BUF9IQU5ETEVSKFNJTlQ2NCkKK01BUF9IQU5ETEVSKFNJTlQzMikKK01BUF9IQU5ETEVSKEVOVU0pCitNQVBfSEFORExFUihET1VCTEUpCitNQVBfSEFORExFUihGTE9BVCkKK01BUF9IQU5ETEVSKEZJWEVENjQpCitNQVBfSEFORExFUihGSVhFRDMyKQorTUFQX0hBTkRMRVIoU0ZJWEVENjQpCitNQVBfSEFORExFUihTRklYRUQzMikKK01BUF9IQU5ETEVSKEJPT0wpCisjdW5kZWYgTUFQX0hBTkRMRVIKKwordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+CitpbmxpbmUgaW50CitNYXBUeXBlSGFuZGxlcjxXaXJlRm9ybWF0TGl0ZTo6VFlQRV9NRVNTQUdFLCBUeXBlPjo6Qnl0ZVNpemUoCisgICAgY29uc3QgTWFwRW50cnlBY2Nlc3NvclR5cGUmIHZhbHVlKSB7CisgIHJldHVybiBXaXJlRm9ybWF0TGl0ZTo6TWVzc2FnZVNpemVOb1ZpcnR1YWwodmFsdWUpOworfQorCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9CWVRFX1NJWkUoRmllbGRUeXBlLCBEZWNsYXJlZFR5cGUpICAgICAgICAgICAgICAgICAgICAgXAorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgaW5saW5lIGludCBNYXBUeXBlSGFuZGxlcjxXaXJlRm9ybWF0TGl0ZTo6VFlQRV8jI0ZpZWxkVHlwZSwgVHlwZT46OkJ5dGVTaXplKCBcCisgICAgICBjb25zdCBNYXBFbnRyeUFjY2Vzc29yVHlwZSYgdmFsdWUpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIHJldHVybiBXaXJlRm9ybWF0TGl0ZTo6RGVjbGFyZWRUeXBlIyNTaXplKHZhbHVlKTsgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgfQorCitHT09HTEVfUFJPVE9CVUZfQllURV9TSVpFKFNUUklORywgU3RyaW5nKQorR09PR0xFX1BST1RPQlVGX0JZVEVfU0laRShCWVRFUyAsIEJ5dGVzKQorR09PR0xFX1BST1RPQlVGX0JZVEVfU0laRShJTlQ2NCAsIEludDY0KQorR09PR0xFX1BST1RPQlVGX0JZVEVfU0laRShVSU5UNjQsIFVJbnQ2NCkKK0dPT0dMRV9QUk9UT0JVRl9CWVRFX1NJWkUoSU5UMzIgLCBJbnQzMikKK0dPT0dMRV9QUk9UT0JVRl9CWVRFX1NJWkUoVUlOVDMyLCBVSW50MzIpCitHT09HTEVfUFJPVE9CVUZfQllURV9TSVpFKFNJTlQ2NCwgU0ludDY0KQorR09PR0xFX1BST1RPQlVGX0JZVEVfU0laRShTSU5UMzIsIFNJbnQzMikKK0dPT0dMRV9QUk9UT0JVRl9CWVRFX1NJWkUoRU5VTSAgLCBFbnVtKQorCisjdW5kZWYgR09PR0xFX1BST1RPQlVGX0JZVEVfU0laRQorCisjZGVmaW5lIEZJWEVEX0JZVEVfU0laRShGaWVsZFR5cGUsIERlY2xhcmVkVHlwZSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgaW5saW5lIGludCBNYXBUeXBlSGFuZGxlcjxXaXJlRm9ybWF0TGl0ZTo6VFlQRV8jI0ZpZWxkVHlwZSwgVHlwZT46OkJ5dGVTaXplKCBcCisgICAgICBjb25zdCBNYXBFbnRyeUFjY2Vzc29yVHlwZSYgdmFsdWUpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIHJldHVybiBXaXJlRm9ybWF0TGl0ZTo6ayMjRGVjbGFyZWRUeXBlIyNTaXplOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgfQorCitGSVhFRF9CWVRFX1NJWkUoRE9VQkxFICAsIERvdWJsZSkKK0ZJWEVEX0JZVEVfU0laRShGTE9BVCAgICwgRmxvYXQpCitGSVhFRF9CWVRFX1NJWkUoRklYRUQ2NCAsIEZpeGVkNjQpCitGSVhFRF9CWVRFX1NJWkUoRklYRUQzMiAsIEZpeGVkMzIpCitGSVhFRF9CWVRFX1NJWkUoU0ZJWEVENjQsIFNGaXhlZDY0KQorRklYRURfQllURV9TSVpFKFNGSVhFRDMyLCBTRml4ZWQzMikKK0ZJWEVEX0JZVEVfU0laRShCT09MICAgICwgQm9vbCkKKworI3VuZGVmIEZJWEVEX0JZVEVfU0laRQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4KK2lubGluZSBpbnQKK01hcFR5cGVIYW5kbGVyPFdpcmVGb3JtYXRMaXRlOjpUWVBFX01FU1NBR0UsIFR5cGU+OjpHZXRDYWNoZWRTaXplKAorICAgIGNvbnN0IE1hcEVudHJ5QWNjZXNzb3JUeXBlJiB2YWx1ZSkgeworICByZXR1cm4gV2lyZUZvcm1hdExpdGU6Okxlbmd0aERlbGltaXRlZFNpemUodmFsdWUuR2V0Q2FjaGVkU2l6ZSgpKTsKK30KKworI2RlZmluZSBHRVRfQ0FDSEVEX1NJWkUoRmllbGRUeXBlLCBEZWNsYXJlZFR5cGUpICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGlubGluZSBpbnQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBNYXBUeXBlSGFuZGxlcjxXaXJlRm9ybWF0TGl0ZTo6VFlQRV8jI0ZpZWxkVHlwZSwgVHlwZT46OkdldENhY2hlZFNpemUoIFwKKyAgICAgIGNvbnN0IE1hcEVudHJ5QWNjZXNzb3JUeXBlJiB2YWx1ZSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgcmV0dXJuIFdpcmVGb3JtYXRMaXRlOjpEZWNsYXJlZFR5cGUjI1NpemUodmFsdWUpOyAgICAgICAgICAgICAgICAgICAgXAorICB9CisKK0dFVF9DQUNIRURfU0laRShTVFJJTkcsIFN0cmluZykKK0dFVF9DQUNIRURfU0laRShCWVRFUyAsIEJ5dGVzKQorR0VUX0NBQ0hFRF9TSVpFKElOVDY0ICwgSW50NjQpCitHRVRfQ0FDSEVEX1NJWkUoVUlOVDY0LCBVSW50NjQpCitHRVRfQ0FDSEVEX1NJWkUoSU5UMzIgLCBJbnQzMikKK0dFVF9DQUNIRURfU0laRShVSU5UMzIsIFVJbnQzMikKK0dFVF9DQUNIRURfU0laRShTSU5UNjQsIFNJbnQ2NCkKK0dFVF9DQUNIRURfU0laRShTSU5UMzIsIFNJbnQzMikKK0dFVF9DQUNIRURfU0laRShFTlVNICAsIEVudW0pCisKKyN1bmRlZiBHRVRfQ0FDSEVEX1NJWkUKKworI2RlZmluZSBHRVRfRklYRURfQ0FDSEVEX1NJWkUoRmllbGRUeXBlLCBEZWNsYXJlZFR5cGUpICAgICAgICAgICAgICAgICAgIFwKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGlubGluZSBpbnQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBNYXBUeXBlSGFuZGxlcjxXaXJlRm9ybWF0TGl0ZTo6VFlQRV8jI0ZpZWxkVHlwZSwgVHlwZT46OkdldENhY2hlZFNpemUoIFwKKyAgICAgIGNvbnN0IE1hcEVudHJ5QWNjZXNzb3JUeXBlJiB2YWx1ZSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgcmV0dXJuIFdpcmVGb3JtYXRMaXRlOjprIyNEZWNsYXJlZFR5cGUjI1NpemU7ICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9CisKK0dFVF9GSVhFRF9DQUNIRURfU0laRShET1VCTEUgICwgRG91YmxlKQorR0VUX0ZJWEVEX0NBQ0hFRF9TSVpFKEZMT0FUICAgLCBGbG9hdCkKK0dFVF9GSVhFRF9DQUNIRURfU0laRShGSVhFRDY0ICwgRml4ZWQ2NCkKK0dFVF9GSVhFRF9DQUNIRURfU0laRShGSVhFRDMyICwgRml4ZWQzMikKK0dFVF9GSVhFRF9DQUNIRURfU0laRShTRklYRUQ2NCwgU0ZpeGVkNjQpCitHRVRfRklYRURfQ0FDSEVEX1NJWkUoU0ZJWEVEMzIsIFNGaXhlZDMyKQorR0VUX0ZJWEVEX0NBQ0hFRF9TSVpFKEJPT0wgICAgLCBCb29sKQorCisjdW5kZWYgR0VUX0ZJWEVEX0NBQ0hFRF9TSVpFCisKK3RlbXBsYXRlIDx0eXBlbmFtZSBUeXBlPgoraW5saW5lIHZvaWQgTWFwVHlwZUhhbmRsZXI8V2lyZUZvcm1hdExpdGU6OlRZUEVfTUVTU0FHRSwgVHlwZT46OldyaXRlKAorICAgIGludCBmaWVsZCwgY29uc3QgTWFwRW50cnlBY2Nlc3NvclR5cGUmIHZhbHVlLAorICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSB7CisgIFdpcmVGb3JtYXRMaXRlOjpXcml0ZU1lc3NhZ2VNYXliZVRvQXJyYXkoZmllbGQsIHZhbHVlLCBvdXRwdXQpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4KK2lubGluZSB1aW50OCoKK01hcFR5cGVIYW5kbGVyPFdpcmVGb3JtYXRMaXRlOjpUWVBFX01FU1NBR0UsIFR5cGU+OjpXcml0ZVRvQXJyYXkoCisgICAgaW50IGZpZWxkLCBjb25zdCBNYXBFbnRyeUFjY2Vzc29yVHlwZSYgdmFsdWUsIHVpbnQ4KiBvdXRwdXQpIHsKKyAgcmV0dXJuIFdpcmVGb3JtYXRMaXRlOjpXcml0ZU1lc3NhZ2VUb0FycmF5KGZpZWxkLCB2YWx1ZSwgb3V0cHV0KTsKK30KKworI2RlZmluZSBXUklURV9NRVRIT0QoRmllbGRUeXBlLCBEZWNsYXJlZFR5cGUpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGlubGluZSB2b2lkIE1hcFR5cGVIYW5kbGVyPFdpcmVGb3JtYXRMaXRlOjpUWVBFXyMjRmllbGRUeXBlLCBUeXBlPjo6V3JpdGUoICAgXAorICAgICAgaW50IGZpZWxkLCBjb25zdCBNYXBFbnRyeUFjY2Vzc29yVHlwZSYgdmFsdWUsICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgcmV0dXJuIFdpcmVGb3JtYXRMaXRlOjpXcml0ZSMjRGVjbGFyZWRUeXBlKGZpZWxkLCB2YWx1ZSwgb3V0cHV0KTsgICAgICAgICAgXAorICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGlubGluZSB1aW50OCogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBNYXBUeXBlSGFuZGxlcjxXaXJlRm9ybWF0TGl0ZTo6VFlQRV8jI0ZpZWxkVHlwZSwgVHlwZT46OldyaXRlVG9BcnJheSggICAgICAgIFwKKyAgICAgIGludCBmaWVsZCwgY29uc3QgTWFwRW50cnlBY2Nlc3NvclR5cGUmIHZhbHVlLCB1aW50OCogb3V0cHV0KSB7ICAgICAgICAgICBcCisgICAgcmV0dXJuIFdpcmVGb3JtYXRMaXRlOjpXcml0ZSMjRGVjbGFyZWRUeXBlIyNUb0FycmF5KGZpZWxkLCB2YWx1ZSwgb3V0cHV0KTsgXAorICB9CisKK1dSSVRFX01FVEhPRChTVFJJTkcgICwgU3RyaW5nKQorV1JJVEVfTUVUSE9EKEJZVEVTICAgLCBCeXRlcykKK1dSSVRFX01FVEhPRChJTlQ2NCAgICwgSW50NjQpCitXUklURV9NRVRIT0QoVUlOVDY0ICAsIFVJbnQ2NCkKK1dSSVRFX01FVEhPRChJTlQzMiAgICwgSW50MzIpCitXUklURV9NRVRIT0QoVUlOVDMyICAsIFVJbnQzMikKK1dSSVRFX01FVEhPRChTSU5UNjQgICwgU0ludDY0KQorV1JJVEVfTUVUSE9EKFNJTlQzMiAgLCBTSW50MzIpCitXUklURV9NRVRIT0QoRU5VTSAgICAsIEVudW0pCitXUklURV9NRVRIT0QoRE9VQkxFICAsIERvdWJsZSkKK1dSSVRFX01FVEhPRChGTE9BVCAgICwgRmxvYXQpCitXUklURV9NRVRIT0QoRklYRUQ2NCAsIEZpeGVkNjQpCitXUklURV9NRVRIT0QoRklYRUQzMiAsIEZpeGVkMzIpCitXUklURV9NRVRIT0QoU0ZJWEVENjQsIFNGaXhlZDY0KQorV1JJVEVfTUVUSE9EKFNGSVhFRDMyLCBTRml4ZWQzMikKK1dSSVRFX01FVEhPRChCT09MICAgICwgQm9vbCkKKworI3VuZGVmIFdSSVRFX01FVEhPRAorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4KK2lubGluZSBib29sIE1hcFR5cGVIYW5kbGVyPFdpcmVGb3JtYXRMaXRlOjpUWVBFX01FU1NBR0UsIFR5cGU+OjpSZWFkKAorICAgIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwgTWFwRW50cnlBY2Nlc3NvclR5cGUqIHZhbHVlKSB7CisgIHJldHVybiBXaXJlRm9ybWF0TGl0ZTo6UmVhZE1lc3NhZ2VOb1ZpcnR1YWwoaW5wdXQsIHZhbHVlKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+CitpbmxpbmUgYm9vbCBNYXBUeXBlSGFuZGxlcjxXaXJlRm9ybWF0TGl0ZTo6VFlQRV9TVFJJTkcsIFR5cGU+OjpSZWFkKAorICAgIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwgTWFwRW50cnlBY2Nlc3NvclR5cGUqIHZhbHVlKSB7CisgIHJldHVybiBXaXJlRm9ybWF0TGl0ZTo6UmVhZFN0cmluZyhpbnB1dCwgdmFsdWUpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4KK2lubGluZSBib29sIE1hcFR5cGVIYW5kbGVyPFdpcmVGb3JtYXRMaXRlOjpUWVBFX0JZVEVTLCBUeXBlPjo6UmVhZCgKKyAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsIE1hcEVudHJ5QWNjZXNzb3JUeXBlKiB2YWx1ZSkgeworICByZXR1cm4gV2lyZUZvcm1hdExpdGU6OlJlYWRCeXRlcyhpbnB1dCwgdmFsdWUpOworfQorCisjZGVmaW5lIFJFQURfTUVUSE9EKEZpZWxkVHlwZSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgaW5saW5lIGJvb2wgTWFwVHlwZUhhbmRsZXI8V2lyZUZvcm1hdExpdGU6OlRZUEVfIyNGaWVsZFR5cGUsIFR5cGU+OjpSZWFkKCBcCisgICAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsIE1hcEVudHJ5QWNjZXNzb3JUeXBlKiB2YWx1ZSkgeyAgICAgICAgICAgXAorICAgIHJldHVybiBXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTxUeXBlT25NZW1vcnksICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OlRZUEVfIyNGaWVsZFR5cGU+KCBcCisgICAgICAgIGlucHV0LCB2YWx1ZSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9CisKK1JFQURfTUVUSE9EKElOVDY0KQorUkVBRF9NRVRIT0QoVUlOVDY0KQorUkVBRF9NRVRIT0QoSU5UMzIpCitSRUFEX01FVEhPRChVSU5UMzIpCitSRUFEX01FVEhPRChTSU5UNjQpCitSRUFEX01FVEhPRChTSU5UMzIpCitSRUFEX01FVEhPRChFTlVNKQorUkVBRF9NRVRIT0QoRE9VQkxFKQorUkVBRF9NRVRIT0QoRkxPQVQpCitSRUFEX01FVEhPRChGSVhFRDY0KQorUkVBRF9NRVRIT0QoRklYRUQzMikKK1JFQURfTUVUSE9EKFNGSVhFRDY0KQorUkVBRF9NRVRIT0QoU0ZJWEVEMzIpCitSRUFEX01FVEhPRChCT09MKQorCisjdW5kZWYgUkVBRF9NRVRIT0QKKworLy8gRGVmaW5pdGlvbiBmb3IgbWVzc2FnZSBoYW5kbGVyCisKK3RlbXBsYXRlIDx0eXBlbmFtZSBUeXBlPgoraW5saW5lIGNvbnN0IFR5cGUmCitNYXBUeXBlSGFuZGxlcjxXaXJlRm9ybWF0TGl0ZTo6VFlQRV9NRVNTQUdFLAorICAgICAgICAgICAgICAgICAgICAgICAgVHlwZT46OkdldEV4dGVybmFsUmVmZXJlbmNlKGNvbnN0IFR5cGUqIHZhbHVlKSB7CisgIHJldHVybiAqdmFsdWU7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBUeXBlPgoraW5saW5lIGludAorTWFwVHlwZUhhbmRsZXI8V2lyZUZvcm1hdExpdGU6OlRZUEVfTUVTU0FHRSwKKyAgICAgICAgICAgICAgICAgICAgICAgIFR5cGU+OjpTcGFjZVVzZWRJbk1hcEVudHJ5KGNvbnN0IFR5cGUqIHZhbHVlKSB7CisgIHJldHVybiB2YWx1ZS0+U3BhY2VVc2VkKCk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBUeXBlPgoraW50IE1hcFR5cGVIYW5kbGVyPFdpcmVGb3JtYXRMaXRlOjpUWVBFX01FU1NBR0UsIFR5cGU+OjpTcGFjZVVzZWRJbk1hcCgKKyAgICBjb25zdCBUeXBlJiB2YWx1ZSkgeworICByZXR1cm4gdmFsdWUuU3BhY2VVc2VkKCk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBUeXBlPgoraW5saW5lIHZvaWQgTWFwVHlwZUhhbmRsZXI8V2lyZUZvcm1hdExpdGU6OlRZUEVfTUVTU0FHRSwgVHlwZT46OkNsZWFyKAorICAgIFR5cGUqKiB2YWx1ZSwgQXJlbmEqIGFyZW5hKSB7CisgIGlmICgqdmFsdWUgIT0gTlVMTCkgKCp2YWx1ZSktPkNsZWFyKCk7Cit9Cit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4KK2lubGluZSB2b2lkCitNYXBUeXBlSGFuZGxlcjxXaXJlRm9ybWF0TGl0ZTo6VFlQRV9NRVNTQUdFLAorICAgICAgICAgICAgICAgICAgICAgICAgVHlwZT46OkNsZWFyTWF5YmVCeURlZmF1bHRFbnVtKFR5cGUqKiB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBcmVuYSogYXJlbmEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGRlZmF1bHRfZW51bV92YWx1ZSkgeworICBpZiAoKnZhbHVlICE9IE5VTEwpICgqdmFsdWUpLT5DbGVhcigpOworfQordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+CitpbmxpbmUgdm9pZCBNYXBUeXBlSGFuZGxlcjxXaXJlRm9ybWF0TGl0ZTo6VFlQRV9NRVNTQUdFLCBUeXBlPjo6TWVyZ2UoCisgICAgY29uc3QgVHlwZSYgZnJvbSwgVHlwZSoqIHRvLCBBcmVuYSogYXJlbmEpIHsKKyAgKCp0byktPk1lcmdlRnJvbShmcm9tKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+Cit2b2lkIE1hcFR5cGVIYW5kbGVyPFdpcmVGb3JtYXRMaXRlOjpUWVBFX01FU1NBR0UsIFR5cGU+OjpEZWxldGVOb0FyZW5hKAorICAgIGNvbnN0IFR5cGUqIHB0cikgeworICBkZWxldGUgcHRyOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4KK2lubGluZSB2b2lkIE1hcFR5cGVIYW5kbGVyPFdpcmVGb3JtYXRMaXRlOjpUWVBFX01FU1NBR0UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlPjo6QXNzaWduRGVmYXVsdFZhbHVlKFR5cGUqKiB2YWx1ZSkgeworICAqdmFsdWUgPSBjb25zdF9jYXN0PFR5cGUqPigmVHlwZTo6ZGVmYXVsdF9pbnN0YW5jZSgpKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+CitpbmxpbmUgdm9pZCBNYXBUeXBlSGFuZGxlcjxXaXJlRm9ybWF0TGl0ZTo6VFlQRV9NRVNTQUdFLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZT46OkluaXRpYWxpemUoVHlwZSoqIHgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBcmVuYSogYXJlbmEpIHsKKyAgKnggPSBOVUxMOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4KK2lubGluZSB2b2lkIE1hcFR5cGVIYW5kbGVyPFdpcmVGb3JtYXRMaXRlOjpUWVBFX01FU1NBR0UsIFR5cGU+OjoKKyAgICBJbml0aWFsaXplTWF5YmVCeURlZmF1bHRFbnVtKFR5cGUqKiB4LCBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJlbmEqIGFyZW5hKSB7CisgICp4ID0gTlVMTDsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+CitpbmxpbmUgVHlwZSogTWFwVHlwZUhhbmRsZXI8V2lyZUZvcm1hdExpdGU6OlRZUEVfTUVTU0FHRSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlPjo6RW5zdXJlTXV0YWJsZShUeXBlKiogdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJlbmEqIGFyZW5hKSB7CisgIGlmICgqdmFsdWUgPT0gTlVMTCkgeworICAgICp2YWx1ZSA9CisgICAgICAgIE1hcEFyZW5hTWVzc2FnZUNyZWF0b3I8VHlwZSwgQXJlbmE6OmlzX2FyZW5hX2NvbnN0cnVjdGFibGU8VHlwZT46OgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOjp2YWx1ZT46OkNyZWF0ZU1lc3NhZ2UoYXJlbmEpOworICB9CisgIHJldHVybiAqdmFsdWU7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBUeXBlPgoraW5saW5lIGNvbnN0IFR5cGUmIE1hcFR5cGVIYW5kbGVyPFdpcmVGb3JtYXRMaXRlOjpUWVBFX01FU1NBR0UsIFR5cGU+OjoKKyAgICBEZWZhdWx0SWZOb3RJbml0aWFsaXplZChjb25zdCBUeXBlKiB2YWx1ZSwgY29uc3QgVHlwZSogZGVmYXVsdF92YWx1ZSkgeworICByZXR1cm4gdmFsdWUgIT0gTlVMTCA/ICp2YWx1ZSA6ICpkZWZhdWx0X3ZhbHVlOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4KK2lubGluZSBib29sIE1hcFR5cGVIYW5kbGVyPFdpcmVGb3JtYXRMaXRlOjpUWVBFX01FU1NBR0UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlPjo6SXNJbml0aWFsaXplZChUeXBlKiB2YWx1ZSkgeworICByZXR1cm4gdmFsdWUtPklzSW5pdGlhbGl6ZWQoKTsKK30KKworLy8gRGVmaW5pdGlvbiBmb3Igc3RyaW5nL2J5dGVzIGhhbmRsZXIKKworI2RlZmluZSBTVFJJTkdfT1JfQllURVNfSEFORExFUl9GVU5DVElPTlMoRmllbGRUeXBlKSAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGlubGluZSBjb25zdCB0eXBlbmFtZSBNYXBUeXBlSGFuZGxlcjxXaXJlRm9ybWF0TGl0ZTo6VFlQRV8jI0ZpZWxkVHlwZSwgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZT46Ok1hcEVudHJ5QWNjZXNzb3JUeXBlJiAgICAgICAgICAgIFwKKyAgTWFwVHlwZUhhbmRsZXI8V2lyZUZvcm1hdExpdGU6OlRZUEVfIyNGaWVsZFR5cGUsICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgIFR5cGU+OjpHZXRFeHRlcm5hbFJlZmVyZW5jZShjb25zdCBUeXBlT25NZW1vcnkmIHZhbHVlKSB7ICAgICAgXAorICAgIHJldHVybiB2YWx1ZS5HZXQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nKCkpOyAgICAgICAgICAgICAgICAgICBcCisgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgaW5saW5lIGludCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIE1hcFR5cGVIYW5kbGVyPFdpcmVGb3JtYXRMaXRlOjpUWVBFXyMjRmllbGRUeXBlLCBUeXBlPjo6U3BhY2VVc2VkSW5NYXBFbnRyeSggXAorICAgICAgY29uc3QgVHlwZU9uTWVtb3J5JiB2YWx1ZSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICByZXR1cm4gc2l6ZW9mKHZhbHVlKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgaW5saW5lIGludCBNYXBUeXBlSGFuZGxlcjxXaXJlRm9ybWF0TGl0ZTo6VFlQRV8jI0ZpZWxkVHlwZSwgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZT46OlNwYWNlVXNlZEluTWFwKGNvbnN0IFR5cGVPbk1lbW9yeSYgdmFsdWUpIHsgXAorICAgIHJldHVybiBzaXplb2YodmFsdWUpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUeXBlPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBpbmxpbmUgaW50IE1hcFR5cGVIYW5kbGVyPFdpcmVGb3JtYXRMaXRlOjpUWVBFXyMjRmllbGRUeXBlLCAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlPjo6U3BhY2VVc2VkSW5NYXAoY29uc3Qgc3RyaW5nJiB2YWx1ZSkgeyAgICAgICBcCisgICAgcmV0dXJuIHNpemVvZih2YWx1ZSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGlubGluZSB2b2lkIE1hcFR5cGVIYW5kbGVyPFdpcmVGb3JtYXRMaXRlOjpUWVBFXyMjRmllbGRUeXBlLCBUeXBlPjo6Q2xlYXIoICAgXAorICAgICAgVHlwZU9uTWVtb3J5KiB2YWx1ZSwgQXJlbmEqIGFyZW5hKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICB2YWx1ZS0+Q2xlYXJUb0VtcHR5KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZygpLCBhcmVuYSk7ICAgICAgICAgXAorICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGlubGluZSB2b2lkICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBNYXBUeXBlSGFuZGxlcjxXaXJlRm9ybWF0TGl0ZTo6VFlQRV8jI0ZpZWxkVHlwZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgVHlwZT46OkNsZWFyTWF5YmVCeURlZmF1bHRFbnVtKFR5cGVPbk1lbW9yeSogdmFsdWUsICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBcmVuYSogYXJlbmEsICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGRlZmF1bHRfZW51bSkgeyAgICAgICAgICAgIFwKKyAgICBDbGVhcih2YWx1ZSwgYXJlbmEpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgaW5saW5lIHZvaWQgTWFwVHlwZUhhbmRsZXI8V2lyZUZvcm1hdExpdGU6OlRZUEVfIyNGaWVsZFR5cGUsIFR5cGU+OjpNZXJnZSggICBcCisgICAgICBjb25zdCBNYXBFbnRyeUFjY2Vzc29yVHlwZSYgZnJvbSwgVHlwZU9uTWVtb3J5KiB0bywgQXJlbmEqIGFyZW5hKSB7ICAgICAgXAorICAgIHRvLT5TZXQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nKCksIGZyb20sIGFyZW5hKTsgICAgICAgICAgICAgICBcCisgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdm9pZCBNYXBUeXBlSGFuZGxlcjxXaXJlRm9ybWF0TGl0ZTo6VFlQRV8jI0ZpZWxkVHlwZSwgVHlwZT46OkRlbGV0ZU5vQXJlbmEoICBcCisgICAgICBUeXBlT25NZW1vcnkmIHZhbHVlKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIHZhbHVlLkRlc3Ryb3lOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZygpKTsgICAgICAgICAgICAgICBcCisgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgaW5saW5lIHZvaWQgTWFwVHlwZUhhbmRsZXI8V2lyZUZvcm1hdExpdGU6OlRZUEVfIyNGaWVsZFR5cGUsICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGU+OjpBc3NpZ25EZWZhdWx0VmFsdWUoVHlwZU9uTWVtb3J5KiB2YWx1ZSkge30gXAorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgaW5saW5lIHZvaWQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIE1hcFR5cGVIYW5kbGVyPFdpcmVGb3JtYXRMaXRlOjpUWVBFXyMjRmllbGRUeXBlLCBUeXBlPjo6SW5pdGlhbGl6ZSggICAgICAgICAgXAorICAgICAgVHlwZU9uTWVtb3J5KiB2YWx1ZSwgQXJlbmEqIGFyZW5hKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICB2YWx1ZS0+VW5zYWZlU2V0RGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmcoKSk7ICAgICAgICAgICAgXAorICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGlubGluZSB2b2lkICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBNYXBUeXBlSGFuZGxlcjxXaXJlRm9ybWF0TGl0ZTo6VFlQRV8jI0ZpZWxkVHlwZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgVHlwZT46OkluaXRpYWxpemVNYXliZUJ5RGVmYXVsdEVudW0oVHlwZU9uTWVtb3J5KiB2YWx1ZSwgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBkZWZhdWx0X2VudW1fdmFsdWUsICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBcmVuYSogYXJlbmEpIHsgICAgICAgICAgIFwKKyAgICBJbml0aWFsaXplKHZhbHVlLCBhcmVuYSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgaW5saW5lIHR5cGVuYW1lIE1hcFR5cGVIYW5kbGVyPFdpcmVGb3JtYXRMaXRlOjpUWVBFXyMjRmllbGRUeXBlLCAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlPjo6TWFwRW50cnlBY2Nlc3NvclR5cGUqICAgICAgICAgICAgICAgICAgXAorICBNYXBUeXBlSGFuZGxlcjxXaXJlRm9ybWF0TGl0ZTo6VFlQRV8jI0ZpZWxkVHlwZSwgVHlwZT46OkVuc3VyZU11dGFibGUoICAgICAgIFwKKyAgICAgIFR5cGVPbk1lbW9yeSogdmFsdWUsIEFyZW5hKiBhcmVuYSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgcmV0dXJuIHZhbHVlLT5NdXRhYmxlKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZygpLCBhcmVuYSk7ICAgICAgIFwKKyAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUeXBlPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBpbmxpbmUgY29uc3QgdHlwZW5hbWUgTWFwVHlwZUhhbmRsZXI8V2lyZUZvcm1hdExpdGU6OlRZUEVfIyNGaWVsZFR5cGUsICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGU+OjpNYXBFbnRyeUFjY2Vzc29yVHlwZSYgICAgICAgICAgICBcCisgIE1hcFR5cGVIYW5kbGVyPFdpcmVGb3JtYXRMaXRlOjpUWVBFXyMjRmllbGRUeXBlLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICBUeXBlPjo6RGVmYXVsdElmTm90SW5pdGlhbGl6ZWQoY29uc3QgVHlwZU9uTWVtb3J5JiB2YWx1ZSwgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFR5cGVPbk1lbW9yeSYgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdF92YWx1ZSkgeyAgICAgICAgICAgXAorICAgIHJldHVybiB2YWx1ZS5HZXQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nKCkpOyAgICAgICAgICAgICAgICAgICBcCisgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgaW5saW5lIGJvb2wgTWFwVHlwZUhhbmRsZXI8V2lyZUZvcm1hdExpdGU6OlRZUEVfIyNGaWVsZFR5cGUsICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGU+OjpJc0luaXRpYWxpemVkKGNvbnN0IFR5cGVPbk1lbW9yeSYgdmFsdWUpIHsgXAorICAgIHJldHVybiB0cnVlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgfQorU1RSSU5HX09SX0JZVEVTX0hBTkRMRVJfRlVOQ1RJT05TKFNUUklORykKK1NUUklOR19PUl9CWVRFU19IQU5ETEVSX0ZVTkNUSU9OUyhCWVRFUykKKyN1bmRlZiBTVFJJTkdfT1JfQllURVNfSEFORExFUl9GVU5DVElPTlMKKworI2RlZmluZSBQUklNSVRJVkVfSEFORExFUl9GVU5DVElPTlMoRmllbGRUeXBlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGlubGluZSBjb25zdCB0eXBlbmFtZSBNYXBUeXBlSGFuZGxlcjxXaXJlRm9ybWF0TGl0ZTo6VFlQRV8jI0ZpZWxkVHlwZSwgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZT46Ok1hcEVudHJ5QWNjZXNzb3JUeXBlJiAgICAgICAgICAgIFwKKyAgTWFwVHlwZUhhbmRsZXI8V2lyZUZvcm1hdExpdGU6OlRZUEVfIyNGaWVsZFR5cGUsICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgIFR5cGU+OjpHZXRFeHRlcm5hbFJlZmVyZW5jZShjb25zdCBUeXBlT25NZW1vcnkmIHZhbHVlKSB7ICAgICAgXAorICAgIHJldHVybiB2YWx1ZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUeXBlPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBpbmxpbmUgaW50ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgTWFwVHlwZUhhbmRsZXI8V2lyZUZvcm1hdExpdGU6OlRZUEVfIyNGaWVsZFR5cGUsIFR5cGU+OjpTcGFjZVVzZWRJbk1hcEVudHJ5KCBcCisgICAgICBjb25zdCBUeXBlT25NZW1vcnkmIHZhbHVlKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIHJldHVybiAwOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUeXBlPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBpbmxpbmUgaW50IE1hcFR5cGVIYW5kbGVyPFdpcmVGb3JtYXRMaXRlOjpUWVBFXyMjRmllbGRUeXBlLCAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlPjo6U3BhY2VVc2VkSW5NYXAoY29uc3QgVHlwZU9uTWVtb3J5JiB2YWx1ZSkgeyBcCisgICAgcmV0dXJuIHNpemVvZihUeXBlKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGlubGluZSB2b2lkIE1hcFR5cGVIYW5kbGVyPFdpcmVGb3JtYXRMaXRlOjpUWVBFXyMjRmllbGRUeXBlLCBUeXBlPjo6Q2xlYXIoICAgXAorICAgICAgVHlwZU9uTWVtb3J5KiB2YWx1ZSwgQXJlbmEqIGFyZW5hKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAqdmFsdWUgPSAwOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgaW5saW5lIHZvaWQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIE1hcFR5cGVIYW5kbGVyPFdpcmVGb3JtYXRMaXRlOjpUWVBFXyMjRmllbGRUeXBlLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICBUeXBlPjo6Q2xlYXJNYXliZUJ5RGVmYXVsdEVudW0oVHlwZU9uTWVtb3J5KiB2YWx1ZSwgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFyZW5hKiBhcmVuYSwgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZGVmYXVsdF9lbnVtX3ZhbHVlKSB7ICAgICAgXAorICAgICp2YWx1ZSA9IHN0YXRpY19jYXN0PFR5cGVPbk1lbW9yeT4oZGVmYXVsdF9lbnVtX3ZhbHVlKTsgICAgICAgICAgICAgICAgICAgIFwKKyAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUeXBlPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBpbmxpbmUgdm9pZCBNYXBUeXBlSGFuZGxlcjxXaXJlRm9ybWF0TGl0ZTo6VFlQRV8jI0ZpZWxkVHlwZSwgVHlwZT46Ok1lcmdlKCAgIFwKKyAgICAgIGNvbnN0IE1hcEVudHJ5QWNjZXNzb3JUeXBlJiBmcm9tLCBUeXBlT25NZW1vcnkqIHRvLCBBcmVuYSogYXJlbmEpIHsgICAgICBcCisgICAgKnRvID0gZnJvbTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGlubGluZSB2b2lkIE1hcFR5cGVIYW5kbGVyPFdpcmVGb3JtYXRMaXRlOjpUWVBFXyMjRmllbGRUeXBlLCAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlPjo6RGVsZXRlTm9BcmVuYShUeXBlT25NZW1vcnkmIHgpIHt9ICAgICAgICAgIFwKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGlubGluZSB2b2lkIE1hcFR5cGVIYW5kbGVyPFdpcmVGb3JtYXRMaXRlOjpUWVBFXyMjRmllbGRUeXBlLCAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlPjo6QXNzaWduRGVmYXVsdFZhbHVlKFR5cGVPbk1lbW9yeSogdmFsdWUpIHt9IFwKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGlubGluZSB2b2lkICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBNYXBUeXBlSGFuZGxlcjxXaXJlRm9ybWF0TGl0ZTo6VFlQRV8jI0ZpZWxkVHlwZSwgVHlwZT46OkluaXRpYWxpemUoICAgICAgICAgIFwKKyAgICAgIFR5cGVPbk1lbW9yeSogdmFsdWUsIEFyZW5hKiBhcmVuYSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgKnZhbHVlID0gMDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGlubGluZSB2b2lkICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBNYXBUeXBlSGFuZGxlcjxXaXJlRm9ybWF0TGl0ZTo6VFlQRV8jI0ZpZWxkVHlwZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgVHlwZT46OkluaXRpYWxpemVNYXliZUJ5RGVmYXVsdEVudW0oVHlwZU9uTWVtb3J5KiB2YWx1ZSwgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBkZWZhdWx0X2VudW1fdmFsdWUsICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBcmVuYSogYXJlbmEpIHsgICAgICAgICAgIFwKKyAgICAqdmFsdWUgPSBzdGF0aWNfY2FzdDxUeXBlT25NZW1vcnk+KGRlZmF1bHRfZW51bV92YWx1ZSk7ICAgICAgICAgICAgICAgICAgICBcCisgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZT4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgaW5saW5lIHR5cGVuYW1lIE1hcFR5cGVIYW5kbGVyPFdpcmVGb3JtYXRMaXRlOjpUWVBFXyMjRmllbGRUeXBlLCAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlPjo6TWFwRW50cnlBY2Nlc3NvclR5cGUqICAgICAgICAgICAgICAgICAgXAorICBNYXBUeXBlSGFuZGxlcjxXaXJlRm9ybWF0TGl0ZTo6VFlQRV8jI0ZpZWxkVHlwZSwgVHlwZT46OkVuc3VyZU11dGFibGUoICAgICAgIFwKKyAgICAgIFR5cGVPbk1lbW9yeSogdmFsdWUsIEFyZW5hKiBhcmVuYSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgcmV0dXJuIHZhbHVlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGlubGluZSBjb25zdCB0eXBlbmFtZSBNYXBUeXBlSGFuZGxlcjxXaXJlRm9ybWF0TGl0ZTo6VFlQRV8jI0ZpZWxkVHlwZSwgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZT46Ok1hcEVudHJ5QWNjZXNzb3JUeXBlJiAgICAgICAgICAgIFwKKyAgTWFwVHlwZUhhbmRsZXI8V2lyZUZvcm1hdExpdGU6OlRZUEVfIyNGaWVsZFR5cGUsICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgIFR5cGU+OjpEZWZhdWx0SWZOb3RJbml0aWFsaXplZChjb25zdCBUeXBlT25NZW1vcnkmIHZhbHVlLCAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVHlwZU9uTWVtb3J5JiAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0X3ZhbHVlKSB7ICAgICAgICAgICBcCisgICAgcmV0dXJuIHZhbHVlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGlubGluZSBib29sIE1hcFR5cGVIYW5kbGVyPFdpcmVGb3JtYXRMaXRlOjpUWVBFXyMjRmllbGRUeXBlLCAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlPjo6SXNJbml0aWFsaXplZChjb25zdCBUeXBlT25NZW1vcnkmIHZhbHVlKSB7IFwKKyAgICByZXR1cm4gdHJ1ZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIH0KK1BSSU1JVElWRV9IQU5ETEVSX0ZVTkNUSU9OUyhJTlQ2NCkKK1BSSU1JVElWRV9IQU5ETEVSX0ZVTkNUSU9OUyhVSU5UNjQpCitQUklNSVRJVkVfSEFORExFUl9GVU5DVElPTlMoSU5UMzIpCitQUklNSVRJVkVfSEFORExFUl9GVU5DVElPTlMoVUlOVDMyKQorUFJJTUlUSVZFX0hBTkRMRVJfRlVOQ1RJT05TKFNJTlQ2NCkKK1BSSU1JVElWRV9IQU5ETEVSX0ZVTkNUSU9OUyhTSU5UMzIpCitQUklNSVRJVkVfSEFORExFUl9GVU5DVElPTlMoRU5VTSkKK1BSSU1JVElWRV9IQU5ETEVSX0ZVTkNUSU9OUyhET1VCTEUpCitQUklNSVRJVkVfSEFORExFUl9GVU5DVElPTlMoRkxPQVQpCitQUklNSVRJVkVfSEFORExFUl9GVU5DVElPTlMoRklYRUQ2NCkKK1BSSU1JVElWRV9IQU5ETEVSX0ZVTkNUSU9OUyhGSVhFRDMyKQorUFJJTUlUSVZFX0hBTkRMRVJfRlVOQ1RJT05TKFNGSVhFRDY0KQorUFJJTUlUSVZFX0hBTkRMRVJfRlVOQ1RJT05TKFNGSVhFRDMyKQorUFJJTUlUSVZFX0hBTkRMRVJfRlVOQ1RJT05TKEJPT0wpCisjdW5kZWYgUFJJTUlUSVZFX0hBTkRMRVJfRlVOQ1RJT05TCisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX1RZUEVfSEFORExFUl9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvbWFwX3VuaXR0ZXN0LnByb3RvIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9tYXBfdW5pdHRlc3QucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWVhMWU4YwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvbWFwX3VuaXR0ZXN0LnByb3RvCkBAIC0wLDAgKzEsMTI5IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworc3ludGF4ID0gInByb3RvMyI7CisKK29wdGlvbiBjY19lbmFibGVfYXJlbmFzID0gdHJ1ZTsKKworaW1wb3J0ICJnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucHJvdG8iOworaW1wb3J0ICJnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fYXJlbmEucHJvdG8iOworCisvLyBXZSBkb24ndCBwdXQgdGhpcyBpbiBhIHBhY2thZ2Ugd2l0aGluIHByb3RvMiBiZWNhdXNlIHdlIG5lZWQgdG8gbWFrZSBzdXJlCisvLyB0aGF0IHRoZSBnZW5lcmF0ZWQgY29kZSBkb2Vzbid0IGRlcGVuZCBvbiBiZWluZyBpbiB0aGUgcHJvdG8yIG5hbWVzcGFjZS4KKy8vIEluIG1hcF90ZXN0X3V0aWwuaCB3ZSBkbyAidXNpbmcgbmFtZXNwYWNlIHVuaXR0ZXN0ID0gcHJvdG9idWZfdW5pdHRlc3QiLgorcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdDsKKworLy8gVGVzdHMgbWFwcy4KK21lc3NhZ2UgVGVzdE1hcCB7CisgIG1hcDxpbnQzMiAgICwgaW50MzIgICA+IG1hcF9pbnQzMl9pbnQzMiAgICAgICA9IDE7CisgIG1hcDxpbnQ2NCAgICwgaW50NjQgICA+IG1hcF9pbnQ2NF9pbnQ2NCAgICAgICA9IDI7CisgIG1hcDx1aW50MzIgICwgdWludDMyICA+IG1hcF91aW50MzJfdWludDMyICAgICA9IDM7CisgIG1hcDx1aW50NjQgICwgdWludDY0ICA+IG1hcF91aW50NjRfdWludDY0ICAgICA9IDQ7CisgIG1hcDxzaW50MzIgICwgc2ludDMyICA+IG1hcF9zaW50MzJfc2ludDMyICAgICA9IDU7CisgIG1hcDxzaW50NjQgICwgc2ludDY0ICA+IG1hcF9zaW50NjRfc2ludDY0ICAgICA9IDY7CisgIG1hcDxmaXhlZDMyICwgZml4ZWQzMiA+IG1hcF9maXhlZDMyX2ZpeGVkMzIgICA9IDc7CisgIG1hcDxmaXhlZDY0ICwgZml4ZWQ2NCA+IG1hcF9maXhlZDY0X2ZpeGVkNjQgICA9IDg7CisgIG1hcDxzZml4ZWQzMiwgc2ZpeGVkMzI+IG1hcF9zZml4ZWQzMl9zZml4ZWQzMiA9IDk7CisgIG1hcDxzZml4ZWQ2NCwgc2ZpeGVkNjQ+IG1hcF9zZml4ZWQ2NF9zZml4ZWQ2NCA9IDEwOworICBtYXA8aW50MzIgICAsIGZsb2F0ICAgPiBtYXBfaW50MzJfZmxvYXQgICAgICAgPSAxMTsKKyAgbWFwPGludDMyICAgLCBkb3VibGUgID4gbWFwX2ludDMyX2RvdWJsZSAgICAgID0gMTI7CisgIG1hcDxib29sICAgICwgYm9vbCAgICA+IG1hcF9ib29sX2Jvb2wgICAgICAgICA9IDEzOworICBtYXA8c3RyaW5nICAsIHN0cmluZyAgPiBtYXBfc3RyaW5nX3N0cmluZyAgICAgPSAxNDsKKyAgbWFwPGludDMyICAgLCBieXRlcyAgID4gbWFwX2ludDMyX2J5dGVzICAgICAgID0gMTU7CisgIG1hcDxpbnQzMiAgICwgTWFwRW51bSA+IG1hcF9pbnQzMl9lbnVtICAgICAgICA9IDE2OworICBtYXA8aW50MzIgICAsIEZvcmVpZ25NZXNzYWdlPiBtYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlID0gMTc7CisgIG1hcDxzdHJpbmcgICwgRm9yZWlnbk1lc3NhZ2U+IG1hcF9zdHJpbmdfZm9yZWlnbl9tZXNzYWdlID0gMTg7Cit9CisKK21lc3NhZ2UgVGVzdE1hcFN1Ym1lc3NhZ2UgeworICBUZXN0TWFwIHRlc3RfbWFwID0gMTsKK30KKworbWVzc2FnZSBUZXN0TWVzc2FnZU1hcCB7CisgIG1hcDxpbnQzMiwgVGVzdEFsbFR5cGVzPiBtYXBfaW50MzJfbWVzc2FnZSA9IDE7Cit9CisKKy8vIFR3byBtYXAgZmllbGRzIHNoYXJlIHRoZSBzYW1lIGVudHJ5IGRlZmF1bHQgaW5zdGFuY2UuCittZXNzYWdlIFRlc3RTYW1lVHlwZU1hcCB7CisgIG1hcDxpbnQzMiwgaW50MzI+IG1hcDEgPSAxOworICBtYXA8aW50MzIsIGludDMyPiBtYXAyID0gMjsKK30KKworCitlbnVtIE1hcEVudW0geworICBNQVBfRU5VTV9GT08gPSAwOworICBNQVBfRU5VTV9CQVIgPSAxOworICBNQVBfRU5VTV9CQVogPSAyOworfQorCisvLyBUZXN0IGVtYmVkZWQgbWVzc2FnZSB3aXRoIHJlcXVpcmVkIGZpZWxkcworbWVzc2FnZSBUZXN0UmVxdWlyZWRNZXNzYWdlTWFwIHsKKyAgbWFwPGludDMyLCBUZXN0UmVxdWlyZWQ+IG1hcF9maWVsZCA9IDE7Cit9CisKK21lc3NhZ2UgVGVzdEFyZW5hTWFwIHsKKyAgbWFwPGludDMyICAgLCBpbnQzMiAgID4gbWFwX2ludDMyX2ludDMyICAgICAgID0gMTsKKyAgbWFwPGludDY0ICAgLCBpbnQ2NCAgID4gbWFwX2ludDY0X2ludDY0ICAgICAgID0gMjsKKyAgbWFwPHVpbnQzMiAgLCB1aW50MzIgID4gbWFwX3VpbnQzMl91aW50MzIgICAgID0gMzsKKyAgbWFwPHVpbnQ2NCAgLCB1aW50NjQgID4gbWFwX3VpbnQ2NF91aW50NjQgICAgID0gNDsKKyAgbWFwPHNpbnQzMiAgLCBzaW50MzIgID4gbWFwX3NpbnQzMl9zaW50MzIgICAgID0gNTsKKyAgbWFwPHNpbnQ2NCAgLCBzaW50NjQgID4gbWFwX3NpbnQ2NF9zaW50NjQgICAgID0gNjsKKyAgbWFwPGZpeGVkMzIgLCBmaXhlZDMyID4gbWFwX2ZpeGVkMzJfZml4ZWQzMiAgID0gNzsKKyAgbWFwPGZpeGVkNjQgLCBmaXhlZDY0ID4gbWFwX2ZpeGVkNjRfZml4ZWQ2NCAgID0gODsKKyAgbWFwPHNmaXhlZDMyLCBzZml4ZWQzMj4gbWFwX3NmaXhlZDMyX3NmaXhlZDMyID0gOTsKKyAgbWFwPHNmaXhlZDY0LCBzZml4ZWQ2ND4gbWFwX3NmaXhlZDY0X3NmaXhlZDY0ID0gMTA7CisgIG1hcDxpbnQzMiAgICwgZmxvYXQgICA+IG1hcF9pbnQzMl9mbG9hdCAgICAgICA9IDExOworICBtYXA8aW50MzIgICAsIGRvdWJsZSAgPiBtYXBfaW50MzJfZG91YmxlICAgICAgPSAxMjsKKyAgbWFwPGJvb2wgICAgLCBib29sICAgID4gbWFwX2Jvb2xfYm9vbCAgICAgICAgID0gMTM7CisgIG1hcDxzdHJpbmcgICwgc3RyaW5nICA+IG1hcF9zdHJpbmdfc3RyaW5nICAgICA9IDE0OworICBtYXA8aW50MzIgICAsIGJ5dGVzICAgPiBtYXBfaW50MzJfYnl0ZXMgICAgICAgPSAxNTsKKyAgbWFwPGludDMyICAgLCBNYXBFbnVtID4gbWFwX2ludDMyX2VudW0gICAgICAgID0gMTY7CisgIG1hcDxpbnQzMiAgICwgRm9yZWlnbk1lc3NhZ2U+IG1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UgPSAxNzsKKyAgbWFwPGludDMyLCAucHJvdG9idWZfdW5pdHRlc3Rfbm9fYXJlbmEuRm9yZWlnbk1lc3NhZ2U+CisgICAgICBtYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlX25vX2FyZW5hID0gMTg7Cit9CisKKy8vIFByZXZpb3VzbHksIG1lc3NhZ2UgY29udGFpbmluZyBlbnVtIGNhbGxlZCBUeXBlIGNhbm5vdCBiZSB1c2VkIGFzIHZhbHVlIG9mCisvLyBtYXAgZmllbGQuCittZXNzYWdlIE1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGUgeworICBlbnVtIFR5cGUgeworICAgIFRZUEVfRk9PID0gMDsKKyAgfQorICBtYXA8c3RyaW5nLCBNZXNzYWdlQ29udGFpbmluZ0VudW1DYWxsZWRUeXBlPiB0eXBlID0gMTsKK30KKworLy8gUHJldmlvdXNseSwgbWVzc2FnZSBjYW5ub3QgY29udGFpbiBtYXAgZmllbGQgY2FsbGVkICJlbnRyeSIuCittZXNzYWdlIE1lc3NhZ2VDb250YWluaW5nTWFwQ2FsbGVkRW50cnkgeworICBtYXA8aW50MzIsIGludDMyPiBlbnRyeSA9IDE7Cit9CisKK21lc3NhZ2UgVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2UgeworICBtYXA8c3RyaW5nLCBUZXN0UmVjdXJzaXZlTWFwTWVzc2FnZT4gYSA9IDE7Cit9CmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF91bml0dGVzdF9wcm90bzMucHJvdG8gYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL21hcF91bml0dGVzdF9wcm90bzMucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTZiZTI3NwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvbWFwX3VuaXR0ZXN0X3Byb3RvMy5wcm90bwpAQCAtMCwwICsxLDEyMCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIFRoaXMgZmlsZSBpcyBtb3N0bHkgZXF1aXZhbGVudCB0byBtYXBfdW5pdHRlc3QucHJvdG8sIGJ1dCBpbXBvcnRzCisvLyB1bml0dGVzdF9wcm90bzMucHJvdG8gaW5zdGVhZCBvZiB1bml0dGVzdC5wcm90bywgc28gdGhhdCBpdCBvbmx5CisvLyB1c2VzIHByb3RvMyBtZXNzYWdlcy4gVGhpcyBtYWtlcyBpdCBzdWl0YWJsZSBmb3IgdGVzdGluZworLy8gaW1wbGVtZW50YXRpb25zIHdoaWNoIG9ubHkgc3VwcG9ydCBwcm90bzMuCisvLyBUaGUgVGVzdFJlcXVpcmVkTWVzc2FnZU1hcCBtZXNzYWdlIGhhcyBiZWVuIHJlbW92ZWQgYXMgdGhlcmUgYXJlIG5vCisvLyByZXF1aXJlZCBmaWVsZHMgaW4gcHJvdG8zLgorc3ludGF4ID0gInByb3RvMyI7CisKK29wdGlvbiBjY19lbmFibGVfYXJlbmFzID0gdHJ1ZTsKK29wdGlvbiBjc2hhcnBfbmFtZXNwYWNlID0gIkdvb2dsZS5Qcm90b2J1Zi5UZXN0UHJvdG9zIjsKKworaW1wb3J0ICJnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJvdG8zLnByb3RvIjsKKworLy8gV2UgZG9uJ3QgcHV0IHRoaXMgaW4gYSBwYWNrYWdlIHdpdGhpbiBwcm90bzIgYmVjYXVzZSB3ZSBuZWVkIHRvIG1ha2Ugc3VyZQorLy8gdGhhdCB0aGUgZ2VuZXJhdGVkIGNvZGUgZG9lc24ndCBkZXBlbmQgb24gYmVpbmcgaW4gdGhlIHByb3RvMiBuYW1lc3BhY2UuCisvLyBJbiBtYXBfdGVzdF91dGlsLmggd2UgZG8gInVzaW5nIG5hbWVzcGFjZSB1bml0dGVzdCA9IHByb3RvYnVmX3VuaXR0ZXN0Ii4KK3BhY2thZ2UgcHJvdG9idWZfdW5pdHRlc3Q7CisKKy8vIFRlc3RzIG1hcHMuCittZXNzYWdlIFRlc3RNYXAgeworICBtYXA8aW50MzIgICAsIGludDMyICAgPiBtYXBfaW50MzJfaW50MzIgICAgICAgPSAxOworICBtYXA8aW50NjQgICAsIGludDY0ICAgPiBtYXBfaW50NjRfaW50NjQgICAgICAgPSAyOworICBtYXA8dWludDMyICAsIHVpbnQzMiAgPiBtYXBfdWludDMyX3VpbnQzMiAgICAgPSAzOworICBtYXA8dWludDY0ICAsIHVpbnQ2NCAgPiBtYXBfdWludDY0X3VpbnQ2NCAgICAgPSA0OworICBtYXA8c2ludDMyICAsIHNpbnQzMiAgPiBtYXBfc2ludDMyX3NpbnQzMiAgICAgPSA1OworICBtYXA8c2ludDY0ICAsIHNpbnQ2NCAgPiBtYXBfc2ludDY0X3NpbnQ2NCAgICAgPSA2OworICBtYXA8Zml4ZWQzMiAsIGZpeGVkMzIgPiBtYXBfZml4ZWQzMl9maXhlZDMyICAgPSA3OworICBtYXA8Zml4ZWQ2NCAsIGZpeGVkNjQgPiBtYXBfZml4ZWQ2NF9maXhlZDY0ICAgPSA4OworICBtYXA8c2ZpeGVkMzIsIHNmaXhlZDMyPiBtYXBfc2ZpeGVkMzJfc2ZpeGVkMzIgPSA5OworICBtYXA8c2ZpeGVkNjQsIHNmaXhlZDY0PiBtYXBfc2ZpeGVkNjRfc2ZpeGVkNjQgPSAxMDsKKyAgbWFwPGludDMyICAgLCBmbG9hdCAgID4gbWFwX2ludDMyX2Zsb2F0ICAgICAgID0gMTE7CisgIG1hcDxpbnQzMiAgICwgZG91YmxlICA+IG1hcF9pbnQzMl9kb3VibGUgICAgICA9IDEyOworICBtYXA8Ym9vbCAgICAsIGJvb2wgICAgPiBtYXBfYm9vbF9ib29sICAgICAgICAgPSAxMzsKKyAgbWFwPHN0cmluZyAgLCBzdHJpbmcgID4gbWFwX3N0cmluZ19zdHJpbmcgICAgID0gMTQ7CisgIG1hcDxpbnQzMiAgICwgYnl0ZXMgICA+IG1hcF9pbnQzMl9ieXRlcyAgICAgICA9IDE1OworICBtYXA8aW50MzIgICAsIE1hcEVudW0gPiBtYXBfaW50MzJfZW51bSAgICAgICAgPSAxNjsKKyAgbWFwPGludDMyICAgLCBGb3JlaWduTWVzc2FnZT4gbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSA9IDE3OworfQorCittZXNzYWdlIFRlc3RNYXBTdWJtZXNzYWdlIHsKKyAgVGVzdE1hcCB0ZXN0X21hcCA9IDE7Cit9CisKK21lc3NhZ2UgVGVzdE1lc3NhZ2VNYXAgeworICBtYXA8aW50MzIsIFRlc3RBbGxUeXBlcz4gbWFwX2ludDMyX21lc3NhZ2UgPSAxOworfQorCisvLyBUd28gbWFwIGZpZWxkcyBzaGFyZSB0aGUgc2FtZSBlbnRyeSBkZWZhdWx0IGluc3RhbmNlLgorbWVzc2FnZSBUZXN0U2FtZVR5cGVNYXAgeworICBtYXA8aW50MzIsIGludDMyPiBtYXAxID0gMTsKKyAgbWFwPGludDMyLCBpbnQzMj4gbWFwMiA9IDI7Cit9CisKK2VudW0gTWFwRW51bSB7CisgIE1BUF9FTlVNX0ZPTyA9IDA7CisgIE1BUF9FTlVNX0JBUiA9IDE7CisgIE1BUF9FTlVNX0JBWiA9IDI7Cit9CisKK21lc3NhZ2UgVGVzdEFyZW5hTWFwIHsKKyAgbWFwPGludDMyICAgLCBpbnQzMiAgID4gbWFwX2ludDMyX2ludDMyICAgICAgID0gMTsKKyAgbWFwPGludDY0ICAgLCBpbnQ2NCAgID4gbWFwX2ludDY0X2ludDY0ICAgICAgID0gMjsKKyAgbWFwPHVpbnQzMiAgLCB1aW50MzIgID4gbWFwX3VpbnQzMl91aW50MzIgICAgID0gMzsKKyAgbWFwPHVpbnQ2NCAgLCB1aW50NjQgID4gbWFwX3VpbnQ2NF91aW50NjQgICAgID0gNDsKKyAgbWFwPHNpbnQzMiAgLCBzaW50MzIgID4gbWFwX3NpbnQzMl9zaW50MzIgICAgID0gNTsKKyAgbWFwPHNpbnQ2NCAgLCBzaW50NjQgID4gbWFwX3NpbnQ2NF9zaW50NjQgICAgID0gNjsKKyAgbWFwPGZpeGVkMzIgLCBmaXhlZDMyID4gbWFwX2ZpeGVkMzJfZml4ZWQzMiAgID0gNzsKKyAgbWFwPGZpeGVkNjQgLCBmaXhlZDY0ID4gbWFwX2ZpeGVkNjRfZml4ZWQ2NCAgID0gODsKKyAgbWFwPHNmaXhlZDMyLCBzZml4ZWQzMj4gbWFwX3NmaXhlZDMyX3NmaXhlZDMyID0gOTsKKyAgbWFwPHNmaXhlZDY0LCBzZml4ZWQ2ND4gbWFwX3NmaXhlZDY0X3NmaXhlZDY0ID0gMTA7CisgIG1hcDxpbnQzMiAgICwgZmxvYXQgICA+IG1hcF9pbnQzMl9mbG9hdCAgICAgICA9IDExOworICBtYXA8aW50MzIgICAsIGRvdWJsZSAgPiBtYXBfaW50MzJfZG91YmxlICAgICAgPSAxMjsKKyAgbWFwPGJvb2wgICAgLCBib29sICAgID4gbWFwX2Jvb2xfYm9vbCAgICAgICAgID0gMTM7CisgIG1hcDxpbnQzMiAgICwgTWFwRW51bSA+IG1hcF9pbnQzMl9lbnVtICAgICAgICA9IDE0OworICBtYXA8aW50MzIgICAsIEZvcmVpZ25NZXNzYWdlPiBtYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlID0gMTU7Cit9CisKKy8vIFByZXZpb3VzbHksIG1lc3NhZ2UgY29udGFpbmluZyBlbnVtIGNhbGxlZCBUeXBlIGNhbm5vdCBiZSB1c2VkIGFzIHZhbHVlIG9mCisvLyBtYXAgZmllbGQuCittZXNzYWdlIE1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGUgeworICBlbnVtIFR5cGUgeworICAgIFRZUEVfRk9PID0gMDsKKyAgfQorICBtYXA8aW50MzIsIE1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGU+IHR5cGUgPSAxOworfQorCisvLyBQcmV2aW91c2x5LCBtZXNzYWdlIGNhbm5vdCBjb250YWluIG1hcCBmaWVsZCBjYWxsZWQgImVudHJ5Ii4KK21lc3NhZ2UgTWVzc2FnZUNvbnRhaW5pbmdNYXBDYWxsZWRFbnRyeSB7CisgIG1hcDxpbnQzMiwgaW50MzI+IGVudHJ5ID0gMTsKK30KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvbWVzc2FnZS5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvbWVzc2FnZS5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMzI3NDhiCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9tZXNzYWdlLmNjCkBAIC0wLDAgKzEsNTE3IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxpb3N0cmVhbT4KKyNpbmNsdWRlIDxzdGFjaz4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvaGFzaC5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21lc3NhZ2UuaD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9sb2dnaW5nLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9tdXRleC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9vbmNlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3JlZmxlY3Rpb25faW50ZXJuYWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21hcF9maWVsZC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9tZXNzYWdlX3V0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcmVmbGVjdGlvbl9vcHMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9tYXBfdXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaW5nbGV0b24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RsX3V0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCit1c2luZyBpbnRlcm5hbDo6V2lyZUZvcm1hdDsKK3VzaW5nIGludGVybmFsOjpSZWZsZWN0aW9uT3BzOworCitNZXNzYWdlOjp+TWVzc2FnZSgpIHt9CisKK3ZvaWQgTWVzc2FnZTo6TWVyZ2VGcm9tKGNvbnN0IE1lc3NhZ2UmIGZyb20pIHsKKyAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciA9IEdldERlc2NyaXB0b3IoKTsKKyAgR09PR0xFX0NIRUNLX0VRKGZyb20uR2V0RGVzY3JpcHRvcigpLCBkZXNjcmlwdG9yKQorICAgIDw8ICI6IFRyaWVkIHRvIG1lcmdlIGZyb20gYSBtZXNzYWdlIHdpdGggYSBkaWZmZXJlbnQgdHlwZS4gICIKKyAgICAgICAidG86ICIgPDwgZGVzY3JpcHRvci0+ZnVsbF9uYW1lKCkgPDwgIiwgIgorICAgICAgICJmcm9tOiIgPDwgZnJvbS5HZXREZXNjcmlwdG9yKCktPmZ1bGxfbmFtZSgpOworICBSZWZsZWN0aW9uT3BzOjpNZXJnZShmcm9tLCB0aGlzKTsKK30KKwordm9pZCBNZXNzYWdlOjpDaGVja1R5cGVBbmRNZXJnZUZyb20oY29uc3QgTWVzc2FnZUxpdGUmIG90aGVyKSB7CisgIE1lcmdlRnJvbSgqZG93bl9jYXN0PGNvbnN0IE1lc3NhZ2UqPigmb3RoZXIpKTsKK30KKwordm9pZCBNZXNzYWdlOjpDb3B5RnJvbShjb25zdCBNZXNzYWdlJiBmcm9tKSB7CisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBHZXREZXNjcmlwdG9yKCk7CisgIEdPT0dMRV9DSEVDS19FUShmcm9tLkdldERlc2NyaXB0b3IoKSwgZGVzY3JpcHRvcikKKyAgICA8PCAiOiBUcmllZCB0byBjb3B5IGZyb20gYSBtZXNzYWdlIHdpdGggYSBkaWZmZXJlbnQgdHlwZS4gIgorICAgICAgICJ0bzogIiA8PCBkZXNjcmlwdG9yLT5mdWxsX25hbWUoKSA8PCAiLCAiCisgICAgICAgImZyb206IiA8PCBmcm9tLkdldERlc2NyaXB0b3IoKS0+ZnVsbF9uYW1lKCk7CisgIFJlZmxlY3Rpb25PcHM6OkNvcHkoZnJvbSwgdGhpcyk7Cit9CisKK3N0cmluZyBNZXNzYWdlOjpHZXRUeXBlTmFtZSgpIGNvbnN0IHsKKyAgcmV0dXJuIEdldERlc2NyaXB0b3IoKS0+ZnVsbF9uYW1lKCk7Cit9CisKK3ZvaWQgTWVzc2FnZTo6Q2xlYXIoKSB7CisgIFJlZmxlY3Rpb25PcHM6OkNsZWFyKHRoaXMpOworfQorCitib29sIE1lc3NhZ2U6OklzSW5pdGlhbGl6ZWQoKSBjb25zdCB7CisgIHJldHVybiBSZWZsZWN0aW9uT3BzOjpJc0luaXRpYWxpemVkKCp0aGlzKTsKK30KKwordm9pZCBNZXNzYWdlOjpGaW5kSW5pdGlhbGl6YXRpb25FcnJvcnModmVjdG9yPHN0cmluZz4qIGVycm9ycykgY29uc3QgeworICByZXR1cm4gUmVmbGVjdGlvbk9wczo6RmluZEluaXRpYWxpemF0aW9uRXJyb3JzKCp0aGlzLCAiIiwgZXJyb3JzKTsKK30KKworc3RyaW5nIE1lc3NhZ2U6OkluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmcoKSBjb25zdCB7CisgIHZlY3RvcjxzdHJpbmc+IGVycm9yczsKKyAgRmluZEluaXRpYWxpemF0aW9uRXJyb3JzKCZlcnJvcnMpOworICByZXR1cm4gSm9pbihlcnJvcnMsICIsICIpOworfQorCit2b2lkIE1lc3NhZ2U6OkNoZWNrSW5pdGlhbGl6ZWQoKSBjb25zdCB7CisgIEdPT0dMRV9DSEVDSyhJc0luaXRpYWxpemVkKCkpCisgICAgPDwgIk1lc3NhZ2Ugb2YgdHlwZSBcIiIgPDwgR2V0RGVzY3JpcHRvcigpLT5mdWxsX25hbWUoKQorICAgIDw8ICJcIiBpcyBtaXNzaW5nIHJlcXVpcmVkIGZpZWxkczogIiA8PCBJbml0aWFsaXphdGlvbkVycm9yU3RyaW5nKCk7Cit9CisKK3ZvaWQgTWVzc2FnZTo6RGlzY2FyZFVua25vd25GaWVsZHMoKSB7CisgIHJldHVybiBSZWZsZWN0aW9uT3BzOjpEaXNjYXJkVW5rbm93bkZpZWxkcyh0aGlzKTsKK30KKworYm9vbCBNZXNzYWdlOjpNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KSB7CisgIHJldHVybiBXaXJlRm9ybWF0OjpQYXJzZUFuZE1lcmdlUGFydGlhbChpbnB1dCwgdGhpcyk7Cit9CisKK2Jvb2wgTWVzc2FnZTo6UGFyc2VGcm9tRmlsZURlc2NyaXB0b3IoaW50IGZpbGVfZGVzY3JpcHRvcikgeworICBpbzo6RmlsZUlucHV0U3RyZWFtIGlucHV0KGZpbGVfZGVzY3JpcHRvcik7CisgIHJldHVybiBQYXJzZUZyb21aZXJvQ29weVN0cmVhbSgmaW5wdXQpICYmIGlucHV0LkdldEVycm5vKCkgPT0gMDsKK30KKworYm9vbCBNZXNzYWdlOjpQYXJzZVBhcnRpYWxGcm9tRmlsZURlc2NyaXB0b3IoaW50IGZpbGVfZGVzY3JpcHRvcikgeworICBpbzo6RmlsZUlucHV0U3RyZWFtIGlucHV0KGZpbGVfZGVzY3JpcHRvcik7CisgIHJldHVybiBQYXJzZVBhcnRpYWxGcm9tWmVyb0NvcHlTdHJlYW0oJmlucHV0KSAmJiBpbnB1dC5HZXRFcnJubygpID09IDA7Cit9CisKK2Jvb2wgTWVzc2FnZTo6UGFyc2VGcm9tSXN0cmVhbShpc3RyZWFtKiBpbnB1dCkgeworICBpbzo6SXN0cmVhbUlucHV0U3RyZWFtIHplcm9fY29weV9pbnB1dChpbnB1dCk7CisgIHJldHVybiBQYXJzZUZyb21aZXJvQ29weVN0cmVhbSgmemVyb19jb3B5X2lucHV0KSAmJiBpbnB1dC0+ZW9mKCk7Cit9CisKK2Jvb2wgTWVzc2FnZTo6UGFyc2VQYXJ0aWFsRnJvbUlzdHJlYW0oaXN0cmVhbSogaW5wdXQpIHsKKyAgaW86OklzdHJlYW1JbnB1dFN0cmVhbSB6ZXJvX2NvcHlfaW5wdXQoaW5wdXQpOworICByZXR1cm4gUGFyc2VQYXJ0aWFsRnJvbVplcm9Db3B5U3RyZWFtKCZ6ZXJvX2NvcHlfaW5wdXQpICYmIGlucHV0LT5lb2YoKTsKK30KKworCit2b2lkIE1lc3NhZ2U6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3QgeworICBXaXJlRm9ybWF0OjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoKnRoaXMsIEdldENhY2hlZFNpemUoKSwgb3V0cHV0KTsKK30KKworaW50IE1lc3NhZ2U6OkJ5dGVTaXplKCkgY29uc3QgeworICBpbnQgc2l6ZSA9IFdpcmVGb3JtYXQ6OkJ5dGVTaXplKCp0aGlzKTsKKyAgU2V0Q2FjaGVkU2l6ZShzaXplKTsKKyAgcmV0dXJuIHNpemU7Cit9CisKK3ZvaWQgTWVzc2FnZTo6U2V0Q2FjaGVkU2l6ZShpbnQgLyogc2l6ZSAqLykgY29uc3QgeworICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiTWVzc2FnZSBjbGFzcyBcIiIgPDwgR2V0RGVzY3JpcHRvcigpLT5mdWxsX25hbWUoKQorICAgICAgICAgICAgIDw8ICJcIiBpbXBsZW1lbnRzIG5laXRoZXIgU2V0Q2FjaGVkU2l6ZSgpIG5vciBCeXRlU2l6ZSgpLiAgIgorICAgICAgICAgICAgICAgICJNdXN0IGltcGxlbWVudCBvbmUgb3IgdGhlIG90aGVyLiI7Cit9CisKK2ludCBNZXNzYWdlOjpTcGFjZVVzZWQoKSBjb25zdCB7CisgIHJldHVybiBHZXRSZWZsZWN0aW9uKCktPlNwYWNlVXNlZCgqdGhpcyk7Cit9CisKK2Jvb2wgTWVzc2FnZTo6U2VyaWFsaXplVG9GaWxlRGVzY3JpcHRvcihpbnQgZmlsZV9kZXNjcmlwdG9yKSBjb25zdCB7CisgIGlvOjpGaWxlT3V0cHV0U3RyZWFtIG91dHB1dChmaWxlX2Rlc2NyaXB0b3IpOworICByZXR1cm4gU2VyaWFsaXplVG9aZXJvQ29weVN0cmVhbSgmb3V0cHV0KTsKK30KKworYm9vbCBNZXNzYWdlOjpTZXJpYWxpemVQYXJ0aWFsVG9GaWxlRGVzY3JpcHRvcihpbnQgZmlsZV9kZXNjcmlwdG9yKSBjb25zdCB7CisgIGlvOjpGaWxlT3V0cHV0U3RyZWFtIG91dHB1dChmaWxlX2Rlc2NyaXB0b3IpOworICByZXR1cm4gU2VyaWFsaXplUGFydGlhbFRvWmVyb0NvcHlTdHJlYW0oJm91dHB1dCk7Cit9CisKK2Jvb2wgTWVzc2FnZTo6U2VyaWFsaXplVG9Pc3RyZWFtKG9zdHJlYW0qIG91dHB1dCkgY29uc3QgeworICB7CisgICAgaW86Ok9zdHJlYW1PdXRwdXRTdHJlYW0gemVyb19jb3B5X291dHB1dChvdXRwdXQpOworICAgIGlmICghU2VyaWFsaXplVG9aZXJvQ29weVN0cmVhbSgmemVyb19jb3B5X291dHB1dCkpIHJldHVybiBmYWxzZTsKKyAgfQorICByZXR1cm4gb3V0cHV0LT5nb29kKCk7Cit9CisKK2Jvb2wgTWVzc2FnZTo6U2VyaWFsaXplUGFydGlhbFRvT3N0cmVhbShvc3RyZWFtKiBvdXRwdXQpIGNvbnN0IHsKKyAgaW86Ok9zdHJlYW1PdXRwdXRTdHJlYW0gemVyb19jb3B5X291dHB1dChvdXRwdXQpOworICByZXR1cm4gU2VyaWFsaXplUGFydGlhbFRvWmVyb0NvcHlTdHJlYW0oJnplcm9fY29weV9vdXRwdXQpOworfQorCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisvLyBSZWZsZWN0aW9uIGFuZCBhc3NvY2lhdGVkIFRlbXBsYXRlIFNwZWNpYWxpemF0aW9ucworCitSZWZsZWN0aW9uOjp+UmVmbGVjdGlvbigpIHt9CisKKyNkZWZpbmUgSEFORExFX1RZUEUoVFlQRSwgQ1BQVFlQRSwgQ1RZUEUpICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCit0ZW1wbGF0ZTw+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorY29uc3QgUmVwZWF0ZWRGaWVsZDxUWVBFPiYgUmVmbGVjdGlvbjo6R2V0UmVwZWF0ZWRGaWVsZDxUWVBFPiggICAgICAgIFwKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7ICAgICBcCisgIHJldHVybiAqc3RhdGljX2Nhc3Q8UmVwZWF0ZWRGaWVsZDxUWVBFPiogPiggICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgTXV0YWJsZVJhd1JlcGVhdGVkRmllbGQoY29uc3RfY2FzdDxNZXNzYWdlKj4oJm1lc3NhZ2UpLCAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGQsIENQUFRZUEUsIENUWVBFLCBOVUxMKSk7ICAgICAgICAgICAgICBcCit9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKK3RlbXBsYXRlPD4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCitSZXBlYXRlZEZpZWxkPFRZUEU+KiBSZWZsZWN0aW9uOjpNdXRhYmxlUmVwZWF0ZWRGaWVsZDxUWVBFPiggICAgICAgICAgXAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0IHsgICAgICAgICAgIFwKKyAgcmV0dXJuIHN0YXRpY19jYXN0PFJlcGVhdGVkRmllbGQ8VFlQRT4qID4oICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICBNdXRhYmxlUmF3UmVwZWF0ZWRGaWVsZChtZXNzYWdlLCBmaWVsZCwgQ1BQVFlQRSwgQ1RZUEUsIE5VTEwpKTsgXAorfQorCitIQU5ETEVfVFlQRShpbnQzMiwgIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9JTlQzMiwgIC0xKTsKK0hBTkRMRV9UWVBFKGludDY0LCAgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0lOVDY0LCAgLTEpOworSEFORExFX1RZUEUodWludDMyLCBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDMyLCAtMSk7CitIQU5ETEVfVFlQRSh1aW50NjQsIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9VSU5UNjQsIC0xKTsKK0hBTkRMRV9UWVBFKGZsb2F0LCAgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0ZMT0FULCAgLTEpOworSEFORExFX1RZUEUoZG91YmxlLCBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRE9VQkxFLCAtMSk7CitIQU5ETEVfVFlQRShib29sLCAgIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9CT09MLCAgIC0xKTsKKworCisjdW5kZWYgSEFORExFX1RZUEUKKwordm9pZCogUmVmbGVjdGlvbjo6TXV0YWJsZVJhd1JlcGVhdGVkU3RyaW5nKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGJvb2wgaXNfc3RyaW5nKSBjb25zdCB7CisgIHJldHVybiBNdXRhYmxlUmF3UmVwZWF0ZWRGaWVsZChtZXNzYWdlLCBmaWVsZCwKKyAgICAgIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9TVFJJTkcsIEZpZWxkT3B0aW9uczo6U1RSSU5HLCBOVUxMKTsKK30KKworCisvLyBEZWZhdWx0IEVudW1WYWx1ZSBBUEkgaW1wbGVtZW50YXRpb25zLiBSZWFsIHJlZmxlY3Rpb24gaW1wbGVtZW50YXRpb25zIHNob3VsZAorLy8gb3ZlcnJpZGUgdGhlc2UuIEhvd2V2ZXIsIHRoZXJlIGFyZSBzZXZlcmFsIGxlZ2FjeSBpbXBsZW1lbnRhdGlvbnMgdGhhdCBkbworLy8gbm90LCBhbmQgY2Fubm90IGVhc2lseSBiZSBjaGFuZ2VkIGF0IHRoZSBzYW1lIHRpbWUgYXMgdGhlIFJlZmxlY3Rpb24gQVBJLCBzbworLy8gd2UgcHJvdmlkZSB0aGVzZSBmb3Igbm93LgorLy8gVE9ETzogUmVtb3ZlIHRoZXNlIG9uY2UgYWxsIFJlZmxlY3Rpb24gaW1wbGVtZW50YXRpb25zIGFyZSB1cGRhdGVkLgoraW50IFJlZmxlY3Rpb246OkdldEVudW1WYWx1ZShjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7CisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJVbmltcGxlbWVudGVkIEVudW1WYWx1ZSBBUEkuIjsKKyAgcmV0dXJuIDA7Cit9Cit2b2lkIFJlZmxlY3Rpb246OlNldEVudW1WYWx1ZShNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgIGludCB2YWx1ZSkgY29uc3QgeworICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiVW5pbXBsZW1lbnRlZCBFbnVtVmFsdWUgQVBJLiI7Cit9CitpbnQgUmVmbGVjdGlvbjo6R2V0UmVwZWF0ZWRFbnVtVmFsdWUoCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBpbnQgaW5kZXgpIGNvbnN0IHsKKyAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIlVuaW1wbGVtZW50ZWQgRW51bVZhbHVlIEFQSS4iOworICByZXR1cm4gMDsKK30KK3ZvaWQgUmVmbGVjdGlvbjo6U2V0UmVwZWF0ZWRFbnVtVmFsdWUoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBpbnQgaW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHZhbHVlKSBjb25zdCB7CisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJVbmltcGxlbWVudGVkIEVudW1WYWx1ZSBBUEkuIjsKK30KK3ZvaWQgUmVmbGVjdGlvbjo6QWRkRW51bVZhbHVlKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgaW50IHZhbHVlKSBjb25zdCB7CisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJVbmltcGxlbWVudGVkIEVudW1WYWx1ZSBBUEkuIjsKK30KKworTWFwSXRlcmF0b3IgUmVmbGVjdGlvbjo6TWFwQmVnaW4oCisgICAgTWVzc2FnZSogbWVzc2FnZSwKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7CisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJVbmltcGxlbWVudGVkIE1hcCBSZWZsZWN0aW9uIEFQSS4iOworICBNYXBJdGVyYXRvciBpdGVyKG1lc3NhZ2UsIGZpZWxkKTsKKyAgcmV0dXJuIGl0ZXI7Cit9CisKK01hcEl0ZXJhdG9yIFJlZmxlY3Rpb246Ok1hcEVuZCgKKyAgICBNZXNzYWdlKiBtZXNzYWdlLAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0IHsKKyAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIlVuaW1wbGVtZW50ZWQgTWFwIFJlZmxlY3Rpb24gQVBJLiI7CisgIE1hcEl0ZXJhdG9yIGl0ZXIobWVzc2FnZSwgZmllbGQpOworICByZXR1cm4gaXRlcjsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKy8vIE1lc3NhZ2VGYWN0b3J5CisKK01lc3NhZ2VGYWN0b3J5Ojp+TWVzc2FnZUZhY3RvcnkoKSB7fQorCituYW1lc3BhY2UgeworCitjbGFzcyBHZW5lcmF0ZWRNZXNzYWdlRmFjdG9yeSA6IHB1YmxpYyBNZXNzYWdlRmFjdG9yeSB7CisgcHVibGljOgorICBHZW5lcmF0ZWRNZXNzYWdlRmFjdG9yeSgpOworICB+R2VuZXJhdGVkTWVzc2FnZUZhY3RvcnkoKTsKKworICBzdGF0aWMgR2VuZXJhdGVkTWVzc2FnZUZhY3RvcnkqIHNpbmdsZXRvbigpOworCisgIHR5cGVkZWYgdm9pZCBSZWdpc3RyYXRpb25GdW5jKGNvbnN0IHN0cmluZyYpOworICB2b2lkIFJlZ2lzdGVyRmlsZShjb25zdCBjaGFyKiBmaWxlLCBSZWdpc3RyYXRpb25GdW5jKiByZWdpc3RyYXRpb25fZnVuYyk7CisgIHZvaWQgUmVnaXN0ZXJUeXBlKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIGNvbnN0IE1lc3NhZ2UqIHByb3RvdHlwZSk7CisKKyAgLy8gaW1wbGVtZW50cyBNZXNzYWdlRmFjdG9yeSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgY29uc3QgTWVzc2FnZSogR2V0UHJvdG90eXBlKGNvbnN0IERlc2NyaXB0b3IqIHR5cGUpOworCisgcHJpdmF0ZToKKyAgLy8gT25seSB3cml0dGVuIGF0IHN0YXRpYyBpbml0IHRpbWUsIHNvIGRvZXMgbm90IHJlcXVpcmUgbG9ja2luZy4KKyAgaGFzaF9tYXA8Y29uc3QgY2hhciosIFJlZ2lzdHJhdGlvbkZ1bmMqLAorICAgICAgICAgICBoYXNoPGNvbnN0IGNoYXIqPiwgc3RyZXE+IGZpbGVfbWFwXzsKKworICAvLyBJbml0aWFsaXplZCBsYXppbHksIHNvIHJlcXVpcmVzIGxvY2tpbmcuCisgIE11dGV4IG11dGV4XzsKKyAgaGFzaF9tYXA8Y29uc3QgRGVzY3JpcHRvciosIGNvbnN0IE1lc3NhZ2UqPiB0eXBlX21hcF87Cit9OworCitHZW5lcmF0ZWRNZXNzYWdlRmFjdG9yeSogZ2VuZXJhdGVkX21lc3NhZ2VfZmFjdG9yeV8gPSBOVUxMOworR09PR0xFX1BST1RPQlVGX0RFQ0xBUkVfT05DRShnZW5lcmF0ZWRfbWVzc2FnZV9mYWN0b3J5X29uY2VfaW5pdF8pOworCit2b2lkIFNodXRkb3duR2VuZXJhdGVkTWVzc2FnZUZhY3RvcnkoKSB7CisgIGRlbGV0ZSBnZW5lcmF0ZWRfbWVzc2FnZV9mYWN0b3J5XzsKK30KKwordm9pZCBJbml0R2VuZXJhdGVkTWVzc2FnZUZhY3RvcnkoKSB7CisgIGdlbmVyYXRlZF9tZXNzYWdlX2ZhY3RvcnlfID0gbmV3IEdlbmVyYXRlZE1lc3NhZ2VGYWN0b3J5OworICBpbnRlcm5hbDo6T25TaHV0ZG93bigmU2h1dGRvd25HZW5lcmF0ZWRNZXNzYWdlRmFjdG9yeSk7Cit9CisKK0dlbmVyYXRlZE1lc3NhZ2VGYWN0b3J5OjpHZW5lcmF0ZWRNZXNzYWdlRmFjdG9yeSgpIHt9CitHZW5lcmF0ZWRNZXNzYWdlRmFjdG9yeTo6fkdlbmVyYXRlZE1lc3NhZ2VGYWN0b3J5KCkge30KKworR2VuZXJhdGVkTWVzc2FnZUZhY3RvcnkqIEdlbmVyYXRlZE1lc3NhZ2VGYWN0b3J5OjpzaW5nbGV0b24oKSB7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6R29vZ2xlT25jZUluaXQoJmdlbmVyYXRlZF9tZXNzYWdlX2ZhY3Rvcnlfb25jZV9pbml0XywKKyAgICAgICAgICAgICAgICAgJkluaXRHZW5lcmF0ZWRNZXNzYWdlRmFjdG9yeSk7CisgIHJldHVybiBnZW5lcmF0ZWRfbWVzc2FnZV9mYWN0b3J5XzsKK30KKwordm9pZCBHZW5lcmF0ZWRNZXNzYWdlRmFjdG9yeTo6UmVnaXN0ZXJGaWxlKAorICAgIGNvbnN0IGNoYXIqIGZpbGUsIFJlZ2lzdHJhdGlvbkZ1bmMqIHJlZ2lzdHJhdGlvbl9mdW5jKSB7CisgIGlmICghSW5zZXJ0SWZOb3RQcmVzZW50KCZmaWxlX21hcF8sIGZpbGUsIHJlZ2lzdHJhdGlvbl9mdW5jKSkgeworICAgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJGaWxlIGlzIGFscmVhZHkgcmVnaXN0ZXJlZDogIiA8PCBmaWxlOworICB9Cit9CisKK3ZvaWQgR2VuZXJhdGVkTWVzc2FnZUZhY3Rvcnk6OlJlZ2lzdGVyVHlwZShjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2UqIHByb3RvdHlwZSkgeworICBHT09HTEVfRENIRUNLX0VRKGRlc2NyaXB0b3ItPmZpbGUoKS0+cG9vbCgpLCBEZXNjcmlwdG9yUG9vbDo6Z2VuZXJhdGVkX3Bvb2woKSkKKyAgICA8PCAiVHJpZWQgdG8gcmVnaXN0ZXIgYSBub24tZ2VuZXJhdGVkIHR5cGUgd2l0aCB0aGUgZ2VuZXJhdGVkICIKKyAgICAgICAidHlwZSByZWdpc3RyeS4iOworCisgIC8vIFRoaXMgc2hvdWxkIG9ubHkgYmUgY2FsbGVkIGFzIGEgcmVzdWx0IG9mIGNhbGxpbmcgYSBmaWxlIHJlZ2lzdHJhdGlvbgorICAvLyBmdW5jdGlvbiBkdXJpbmcgR2V0UHJvdG90eXBlKCksIGluIHdoaWNoIGNhc2Ugd2UgYWxyZWFkeSBoYXZlIGxvY2tlZAorICAvLyB0aGUgbXV0ZXguCisgIG11dGV4Xy5Bc3NlcnRIZWxkKCk7CisgIGlmICghSW5zZXJ0SWZOb3RQcmVzZW50KCZ0eXBlX21hcF8sIGRlc2NyaXB0b3IsIHByb3RvdHlwZSkpIHsKKyAgICBHT09HTEVfTE9HKERGQVRBTCkgPDwgIlR5cGUgaXMgYWxyZWFkeSByZWdpc3RlcmVkOiAiIDw8IGRlc2NyaXB0b3ItPmZ1bGxfbmFtZSgpOworICB9Cit9CisKKworY29uc3QgTWVzc2FnZSogR2VuZXJhdGVkTWVzc2FnZUZhY3Rvcnk6OkdldFByb3RvdHlwZShjb25zdCBEZXNjcmlwdG9yKiB0eXBlKSB7CisgIHsKKyAgICBSZWFkZXJNdXRleExvY2sgbG9jaygmbXV0ZXhfKTsKKyAgICBjb25zdCBNZXNzYWdlKiByZXN1bHQgPSBGaW5kUHRyT3JOdWxsKHR5cGVfbWFwXywgdHlwZSk7CisgICAgaWYgKHJlc3VsdCAhPSBOVUxMKSByZXR1cm4gcmVzdWx0OworICB9CisKKyAgLy8gSWYgdGhlIHR5cGUgaXMgbm90IGluIHRoZSBnZW5lcmF0ZWQgcG9vbCwgdGhlbiB3ZSBjYW4ndCBwb3NzaWJseSBoYW5kbGUKKyAgLy8gaXQuCisgIGlmICh0eXBlLT5maWxlKCktPnBvb2woKSAhPSBEZXNjcmlwdG9yUG9vbDo6Z2VuZXJhdGVkX3Bvb2woKSkgcmV0dXJuIE5VTEw7CisKKyAgLy8gQXBwYXJlbnRseSB0aGUgZmlsZSBoYXNuJ3QgYmVlbiByZWdpc3RlcmVkIHlldC4gIExldCdzIGRvIHRoYXQgbm93LgorICBSZWdpc3RyYXRpb25GdW5jKiByZWdpc3RyYXRpb25fZnVuYyA9CisgICAgICBGaW5kUHRyT3JOdWxsKGZpbGVfbWFwXywgdHlwZS0+ZmlsZSgpLT5uYW1lKCkuY19zdHIoKSk7CisgIGlmIChyZWdpc3RyYXRpb25fZnVuYyA9PSBOVUxMKSB7CisgICAgR09PR0xFX0xPRyhERkFUQUwpIDw8ICJGaWxlIGFwcGVhcnMgdG8gYmUgaW4gZ2VuZXJhdGVkIHBvb2wgYnV0IHdhc24ndCAiCisgICAgICAgICAgICAgICAgICAgInJlZ2lzdGVyZWQ6ICIgPDwgdHlwZS0+ZmlsZSgpLT5uYW1lKCk7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKworICBXcml0ZXJNdXRleExvY2sgbG9jaygmbXV0ZXhfKTsKKworICAvLyBDaGVjayBpZiBhbm90aGVyIHRocmVhZCBwcmVlbXB0ZWQgdXMuCisgIGNvbnN0IE1lc3NhZ2UqIHJlc3VsdCA9IEZpbmRQdHJPck51bGwodHlwZV9tYXBfLCB0eXBlKTsKKyAgaWYgKHJlc3VsdCA9PSBOVUxMKSB7CisgICAgLy8gTm9wZS4gIE9LLCByZWdpc3RlciBldmVyeXRoaW5nLgorICAgIHJlZ2lzdHJhdGlvbl9mdW5jKHR5cGUtPmZpbGUoKS0+bmFtZSgpKTsKKyAgICAvLyBTaG91bGQgYmUgaGVyZSBub3cuCisgICAgcmVzdWx0ID0gRmluZFB0ck9yTnVsbCh0eXBlX21hcF8sIHR5cGUpOworICB9CisKKyAgaWYgKHJlc3VsdCA9PSBOVUxMKSB7CisgICAgR09PR0xFX0xPRyhERkFUQUwpIDw8ICJUeXBlIGFwcGVhcnMgdG8gYmUgaW4gZ2VuZXJhdGVkIHBvb2wgYnV0IHdhc24ndCAiCisgICAgICAgICAgICAgICAgPDwgInJlZ2lzdGVyZWQ6ICIgPDwgdHlwZS0+ZnVsbF9uYW1lKCk7CisgIH0KKworICByZXR1cm4gcmVzdWx0OworfQorCit9ICAvLyBuYW1lc3BhY2UKKworTWVzc2FnZUZhY3RvcnkqIE1lc3NhZ2VGYWN0b3J5OjpnZW5lcmF0ZWRfZmFjdG9yeSgpIHsKKyAgcmV0dXJuIEdlbmVyYXRlZE1lc3NhZ2VGYWN0b3J5OjpzaW5nbGV0b24oKTsKK30KKwordm9pZCBNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZEZpbGUoCisgICAgY29uc3QgY2hhciogZmlsZW5hbWUsIHZvaWQgKCpyZWdpc3Rlcl9tZXNzYWdlcykoY29uc3Qgc3RyaW5nJikpIHsKKyAgR2VuZXJhdGVkTWVzc2FnZUZhY3Rvcnk6OnNpbmdsZXRvbigpLT5SZWdpc3RlckZpbGUoZmlsZW5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2lzdGVyX21lc3NhZ2VzKTsKK30KKwordm9pZCBNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZE1lc3NhZ2UoCisgICAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwgY29uc3QgTWVzc2FnZSogcHJvdG90eXBlKSB7CisgIEdlbmVyYXRlZE1lc3NhZ2VGYWN0b3J5OjpzaW5nbGV0b24oKS0+UmVnaXN0ZXJUeXBlKGRlc2NyaXB0b3IsIHByb3RvdHlwZSk7Cit9CisKKworTWVzc2FnZUZhY3RvcnkqIFJlZmxlY3Rpb246OkdldE1lc3NhZ2VGYWN0b3J5KCkgY29uc3QgeworICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiTm90IGltcGxlbWVudGVkLiI7CisgIHJldHVybiBOVUxMOworfQorCit2b2lkKiBSZWZsZWN0aW9uOjpSZXBlYXRlZEZpZWxkRGF0YSgKKyAgICBNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgIEZpZWxkRGVzY3JpcHRvcjo6Q3BwVHlwZSBjcHBfdHlwZSwKKyAgICBjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlX3R5cGUpIGNvbnN0IHsKKyAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIk5vdCBpbXBsZW1lbnRlZC4iOworICByZXR1cm4gTlVMTDsKK30KKworbmFtZXNwYWNlIGludGVybmFsIHsKK1JlcGVhdGVkRmllbGRBY2Nlc3Nvcjo6flJlcGVhdGVkRmllbGRBY2Nlc3NvcigpIHsKK30KK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorCitjb25zdCBpbnRlcm5hbDo6UmVwZWF0ZWRGaWVsZEFjY2Vzc29yKiBSZWZsZWN0aW9uOjpSZXBlYXRlZEZpZWxkQWNjZXNzb3IoCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3QgeworICBHT09HTEVfQ0hFQ0soZmllbGQtPmlzX3JlcGVhdGVkKCkpOworICBzd2l0Y2ggKGZpZWxkLT5jcHBfdHlwZSgpKSB7CisjZGVmaW5lIEhBTkRMRV9QUklNSVRJVkVfVFlQRShUWVBFLCB0eXBlKSBcCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfICMjIFRZUEU6IFwKKyAgICAgIHJldHVybiBpbnRlcm5hbDo6U2luZ2xldG9uPGludGVybmFsOjpSZXBlYXRlZEZpZWxkUHJpbWl0aXZlQWNjZXNzb3I8dHlwZT4gPjo6Z2V0KCk7CisgICAgSEFORExFX1BSSU1JVElWRV9UWVBFKElOVDMyLCBpbnQzMikKKyAgICBIQU5ETEVfUFJJTUlUSVZFX1RZUEUoVUlOVDMyLCB1aW50MzIpCisgICAgSEFORExFX1BSSU1JVElWRV9UWVBFKElOVDY0LCBpbnQ2NCkKKyAgICBIQU5ETEVfUFJJTUlUSVZFX1RZUEUoVUlOVDY0LCB1aW50NjQpCisgICAgSEFORExFX1BSSU1JVElWRV9UWVBFKEZMT0FULCBmbG9hdCkKKyAgICBIQU5ETEVfUFJJTUlUSVZFX1RZUEUoRE9VQkxFLCBkb3VibGUpCisgICAgSEFORExFX1BSSU1JVElWRV9UWVBFKEJPT0wsIGJvb2wpCisgICAgSEFORExFX1BSSU1JVElWRV9UWVBFKEVOVU0sIGludDMyKQorI3VuZGVmIEhBTkRMRV9QUklNSVRJVkVfVFlQRQorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORzoKKyAgICAgIHN3aXRjaCAoZmllbGQtPm9wdGlvbnMoKS5jdHlwZSgpKSB7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgIGNhc2UgRmllbGRPcHRpb25zOjpTVFJJTkc6CisgICAgICAgICAgcmV0dXJuIGludGVybmFsOjpTaW5nbGV0b248aW50ZXJuYWw6OlJlcGVhdGVkUHRyRmllbGRTdHJpbmdBY2Nlc3Nvcj46OmdldCgpOworICAgICAgfQorICAgICAgYnJlYWs7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRToKKyAgICAgIGlmIChmaWVsZC0+aXNfbWFwKCkpIHsKKyAgICAgICAgcmV0dXJuIGludGVybmFsOjpTaW5nbGV0b248aW50ZXJuYWw6Ok1hcEZpZWxkQWNjZXNzb3I+OjpnZXQoKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiBpbnRlcm5hbDo6U2luZ2xldG9uPGludGVybmFsOjpSZXBlYXRlZFB0ckZpZWxkTWVzc2FnZUFjY2Vzc29yPjo6Z2V0KCk7CisgICAgICB9CisgIH0KKyAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIlNob3VsZCBub3QgcmVhY2ggaGVyZS4iOworICByZXR1cm4gTlVMTDsKK30KKworbmFtZXNwYWNlIGludGVybmFsIHsKK25hbWVzcGFjZSB7Cit2b2lkIFNodXRkb3duUmVwZWF0ZWRGaWVsZEFjY2Vzc29yKCkgeworICBpbnRlcm5hbDo6U2luZ2xldG9uPGludGVybmFsOjpSZXBlYXRlZEZpZWxkUHJpbWl0aXZlQWNjZXNzb3I8aW50MzI+ID46OlNodXREb3duKCk7CisgIGludGVybmFsOjpTaW5nbGV0b248aW50ZXJuYWw6OlJlcGVhdGVkRmllbGRQcmltaXRpdmVBY2Nlc3Nvcjx1aW50MzI+ID46OlNodXREb3duKCk7CisgIGludGVybmFsOjpTaW5nbGV0b248aW50ZXJuYWw6OlJlcGVhdGVkRmllbGRQcmltaXRpdmVBY2Nlc3NvcjxpbnQ2ND4gPjo6U2h1dERvd24oKTsKKyAgaW50ZXJuYWw6OlNpbmdsZXRvbjxpbnRlcm5hbDo6UmVwZWF0ZWRGaWVsZFByaW1pdGl2ZUFjY2Vzc29yPHVpbnQ2ND4gPjo6U2h1dERvd24oKTsKKyAgaW50ZXJuYWw6OlNpbmdsZXRvbjxpbnRlcm5hbDo6UmVwZWF0ZWRGaWVsZFByaW1pdGl2ZUFjY2Vzc29yPGZsb2F0PiA+OjpTaHV0RG93bigpOworICBpbnRlcm5hbDo6U2luZ2xldG9uPGludGVybmFsOjpSZXBlYXRlZEZpZWxkUHJpbWl0aXZlQWNjZXNzb3I8ZG91YmxlPiA+OjpTaHV0RG93bigpOworICBpbnRlcm5hbDo6U2luZ2xldG9uPGludGVybmFsOjpSZXBlYXRlZEZpZWxkUHJpbWl0aXZlQWNjZXNzb3I8Ym9vbD4gPjo6U2h1dERvd24oKTsKKyAgaW50ZXJuYWw6OlNpbmdsZXRvbjxpbnRlcm5hbDo6UmVwZWF0ZWRQdHJGaWVsZFN0cmluZ0FjY2Vzc29yPjo6U2h1dERvd24oKTsKKyAgaW50ZXJuYWw6OlNpbmdsZXRvbjxpbnRlcm5hbDo6UmVwZWF0ZWRQdHJGaWVsZE1lc3NhZ2VBY2Nlc3Nvcj46OlNodXREb3duKCk7CisgIGludGVybmFsOjpTaW5nbGV0b248aW50ZXJuYWw6Ok1hcEZpZWxkQWNjZXNzb3I+OjpTaHV0RG93bigpOworfQorCitzdHJ1Y3QgU2h1dGRvd25SZXBlYXRlZEZpZWxkUmVnaXN0ZXIgeworICBTaHV0ZG93blJlcGVhdGVkRmllbGRSZWdpc3RlcigpIHsKKyAgICBPblNodXRkb3duKCZTaHV0ZG93blJlcGVhdGVkRmllbGRBY2Nlc3Nvcik7CisgIH0KK30gc2h1dGRvd25fOworCit9ICAvLyBuYW1lc3BhY2UKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorCituYW1lc3BhY2UgaW50ZXJuYWwgewordGVtcGxhdGU8PgorI2lmIGRlZmluZWQoX01TQ19WRVIpICYmIChfTVNDX1ZFUiA+PSAxOTAwKQorLy8gTm90ZTogZm9yY2Ugbm9pbmxpbmUgdG8gd29ya2Fyb3VuZCBNU1ZDIDIwMTUgY29tcGlsZXIgYnVnLCBpc3N1ZSAjMjQwCitHT09HTEVfQVRUUklCVVRFX05PSU5MSU5FCisjZW5kaWYKK01lc3NhZ2UqIEdlbmVyaWNUeXBlSGFuZGxlcjxNZXNzYWdlPjo6TmV3RnJvbVByb3RvdHlwZSgKKyAgICBjb25zdCBNZXNzYWdlKiBwcm90b3R5cGUsIGdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgeworICByZXR1cm4gcHJvdG90eXBlLT5OZXcoYXJlbmEpOworfQordGVtcGxhdGU8PgorI2lmIGRlZmluZWQoX01TQ19WRVIpICYmIChfTVNDX1ZFUiA+PSAxOTAwKQorLy8gTm90ZTogZm9yY2Ugbm9pbmxpbmUgdG8gd29ya2Fyb3VuZCBNU1ZDIDIwMTUgY29tcGlsZXIgYnVnLCBpc3N1ZSAjMjQwCitHT09HTEVfQVRUUklCVVRFX05PSU5MSU5FCisjZW5kaWYKK2dvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZW5lcmljVHlwZUhhbmRsZXI8TWVzc2FnZT46OkdldEFyZW5hKAorICAgIE1lc3NhZ2UqIHZhbHVlKSB7CisgIHJldHVybiB2YWx1ZS0+R2V0QXJlbmEoKTsKK30KK3RlbXBsYXRlPD4KKyNpZiBkZWZpbmVkKF9NU0NfVkVSKSAmJiAoX01TQ19WRVIgPj0gMTkwMCkKKy8vIE5vdGU6IGZvcmNlIG5vaW5saW5lIHRvIHdvcmthcm91bmQgTVNWQyAyMDE1IGNvbXBpbGVyIGJ1ZywgaXNzdWUgIzI0MAorR09PR0xFX0FUVFJJQlVURV9OT0lOTElORQorI2VuZGlmCit2b2lkKiBHZW5lcmljVHlwZUhhbmRsZXI8TWVzc2FnZT46OkdldE1heWJlQXJlbmFQb2ludGVyKAorICAgIE1lc3NhZ2UqIHZhbHVlKSB7CisgIHJldHVybiB2YWx1ZS0+R2V0TWF5YmVBcmVuYVBvaW50ZXIoKTsKK30KK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvbWVzc2FnZS5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9tZXNzYWdlLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTRkOTI3NwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvbWVzc2FnZS5oCkBAIC0wLDAgKzEsMTE1MCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorLy8KKy8vIERlZmluZXMgTWVzc2FnZSwgdGhlIGFic3RyYWN0IGludGVyZmFjZSBpbXBsZW1lbnRlZCBieSBub24tbGl0ZQorLy8gcHJvdG9jb2wgbWVzc2FnZSBvYmplY3RzLiAgQWx0aG91Z2ggaXQncyBwb3NzaWJsZSB0byBpbXBsZW1lbnQgdGhpcworLy8gaW50ZXJmYWNlIG1hbnVhbGx5LCBtb3N0IHVzZXJzIHdpbGwgdXNlIHRoZSBwcm90b2NvbCBjb21waWxlciB0bworLy8gZ2VuZXJhdGUgaW1wbGVtZW50YXRpb25zLgorLy8KKy8vIEV4YW1wbGUgdXNhZ2U6CisvLworLy8gU2F5IHlvdSBoYXZlIGEgbWVzc2FnZSBkZWZpbmVkIGFzOgorLy8KKy8vICAgbWVzc2FnZSBGb28geworLy8gICAgIG9wdGlvbmFsIHN0cmluZyB0ZXh0ID0gMTsKKy8vICAgICByZXBlYXRlZCBpbnQzMiBudW1iZXJzID0gMjsKKy8vICAgfQorLy8KKy8vIFRoZW4sIGlmIHlvdSB1c2VkIHRoZSBwcm90b2NvbCBjb21waWxlciB0byBnZW5lcmF0ZSBhIGNsYXNzIGZyb20gdGhlIGFib3ZlCisvLyBkZWZpbml0aW9uLCB5b3UgY291bGQgdXNlIGl0IGxpa2Ugc286CisvLworLy8gICBzdHJpbmcgZGF0YTsgIC8vIFdpbGwgc3RvcmUgYSBzZXJpYWxpemVkIHZlcnNpb24gb2YgdGhlIG1lc3NhZ2UuCisvLworLy8gICB7CisvLyAgICAgLy8gQ3JlYXRlIGEgbWVzc2FnZSBhbmQgc2VyaWFsaXplIGl0LgorLy8gICAgIEZvbyBmb287CisvLyAgICAgZm9vLnNldF90ZXh0KCJIZWxsbyBXb3JsZCEiKTsKKy8vICAgICBmb28uYWRkX251bWJlcnMoMSk7CisvLyAgICAgZm9vLmFkZF9udW1iZXJzKDUpOworLy8gICAgIGZvby5hZGRfbnVtYmVycyg0Mik7CisvLworLy8gICAgIGZvby5TZXJpYWxpemVUb1N0cmluZygmZGF0YSk7CisvLyAgIH0KKy8vCisvLyAgIHsKKy8vICAgICAvLyBQYXJzZSB0aGUgc2VyaWFsaXplZCBtZXNzYWdlIGFuZCBjaGVjayB0aGF0IGl0IGNvbnRhaW5zIHRoZQorLy8gICAgIC8vIGNvcnJlY3QgZGF0YS4KKy8vICAgICBGb28gZm9vOworLy8gICAgIGZvby5QYXJzZUZyb21TdHJpbmcoZGF0YSk7CisvLworLy8gICAgIGFzc2VydChmb28udGV4dCgpID09ICJIZWxsbyBXb3JsZCEiKTsKKy8vICAgICBhc3NlcnQoZm9vLm51bWJlcnNfc2l6ZSgpID09IDMpOworLy8gICAgIGFzc2VydChmb28ubnVtYmVycygwKSA9PSAxKTsKKy8vICAgICBhc3NlcnQoZm9vLm51bWJlcnMoMSkgPT0gNSk7CisvLyAgICAgYXNzZXJ0KGZvby5udW1iZXJzKDIpID09IDQyKTsKKy8vICAgfQorLy8KKy8vICAgeworLy8gICAgIC8vIFNhbWUgYXMgdGhlIGxhc3QgYmxvY2ssIGJ1dCBkbyBpdCBkeW5hbWljYWxseSB2aWEgdGhlIE1lc3NhZ2UKKy8vICAgICAvLyByZWZsZWN0aW9uIGludGVyZmFjZS4KKy8vICAgICBNZXNzYWdlKiBmb28gPSBuZXcgRm9vOworLy8gICAgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBmb28tPkdldERlc2NyaXB0b3IoKTsKKy8vCisvLyAgICAgLy8gR2V0IHRoZSBkZXNjcmlwdG9ycyBmb3IgdGhlIGZpZWxkcyB3ZSdyZSBpbnRlcmVzdGVkIGluIGFuZCB2ZXJpZnkKKy8vICAgICAvLyB0aGVpciB0eXBlcy4KKy8vICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHRleHRfZmllbGQgPSBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoInRleHQiKTsKKy8vICAgICBhc3NlcnQodGV4dF9maWVsZCAhPSBOVUxMKTsKKy8vICAgICBhc3NlcnQodGV4dF9maWVsZC0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TVFJJTkcpOworLy8gICAgIGFzc2VydCh0ZXh0X2ZpZWxkLT5sYWJlbCgpID09IEZpZWxkRGVzY3JpcHRvcjo6TEFCRUxfT1BUSU9OQUwpOworLy8gICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogbnVtYmVyc19maWVsZCA9IGRlc2NyaXB0b3ItPgorLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpbmRGaWVsZEJ5TmFtZSgibnVtYmVycyIpOworLy8gICAgIGFzc2VydChudW1iZXJzX2ZpZWxkICE9IE5VTEwpOworLy8gICAgIGFzc2VydChudW1iZXJzX2ZpZWxkLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX0lOVDMyKTsKKy8vICAgICBhc3NlcnQobnVtYmVyc19maWVsZC0+bGFiZWwoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkxBQkVMX1JFUEVBVEVEKTsKKy8vCisvLyAgICAgLy8gUGFyc2UgdGhlIG1lc3NhZ2UuCisvLyAgICAgZm9vLT5QYXJzZUZyb21TdHJpbmcoZGF0YSk7CisvLworLy8gICAgIC8vIFVzZSB0aGUgcmVmbGVjdGlvbiBpbnRlcmZhY2UgdG8gZXhhbWluZSB0aGUgY29udGVudHMuCisvLyAgICAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IGZvby0+R2V0UmVmbGVjdGlvbigpOworLy8gICAgIGFzc2VydChyZWZsZWN0aW9uLT5HZXRTdHJpbmcoKmZvbywgdGV4dF9maWVsZCkgPT0gIkhlbGxvIFdvcmxkISIpOworLy8gICAgIGFzc2VydChyZWZsZWN0aW9uLT5GaWVsZFNpemUoKmZvbywgbnVtYmVyc19maWVsZCkgPT0gMyk7CisvLyAgICAgYXNzZXJ0KHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkSW50MzIoKmZvbywgbnVtYmVyc19maWVsZCwgMCkgPT0gMSk7CisvLyAgICAgYXNzZXJ0KHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkSW50MzIoKmZvbywgbnVtYmVyc19maWVsZCwgMSkgPT0gNSk7CisvLyAgICAgYXNzZXJ0KHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkSW50MzIoKmZvbywgbnVtYmVyc19maWVsZCwgMikgPT0gNDIpOworLy8KKy8vICAgICBkZWxldGUgZm9vOworLy8gICB9CisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX01FU1NBR0VfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9NRVNTQUdFX0hfXworCisjaW5jbHVkZSA8aW9zZndkPgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvdHlwZV90cmFpdHMuaD4KKyNpbmNsdWRlIDx2ZWN0b3I+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvYXJlbmEuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWVzc2FnZV9saXRlLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKworCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9IQVNfT05FT0YKKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0hBU19BUkVOQVMKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCisvLyBEZWZpbmVkIGluIHRoaXMgZmlsZS4KK2NsYXNzIE1lc3NhZ2U7CitjbGFzcyBSZWZsZWN0aW9uOworY2xhc3MgTWVzc2FnZUZhY3Rvcnk7CisKKy8vIERlZmluZWQgaW4gb3RoZXIgZmlsZXMuCitjbGFzcyBNYXBLZXk7CitjbGFzcyBNYXBWYWx1ZVJlZjsKK2NsYXNzIE1hcEl0ZXJhdG9yOworY2xhc3MgTWFwUmVmbGVjdGlvblRlc3RlcjsKKworbmFtZXNwYWNlIGludGVybmFsIHsKK2NsYXNzIE1hcEZpZWxkQmFzZTsKK30KK2NsYXNzIFVua25vd25GaWVsZFNldDsgICAgICAgICAvLyB1bmtub3duX2ZpZWxkX3NldC5oCituYW1lc3BhY2UgaW8geworY2xhc3MgWmVyb0NvcHlJbnB1dFN0cmVhbTsgICAgIC8vIHplcm9fY29weV9zdHJlYW0uaAorY2xhc3MgWmVyb0NvcHlPdXRwdXRTdHJlYW07ICAgIC8vIHplcm9fY29weV9zdHJlYW0uaAorY2xhc3MgQ29kZWRJbnB1dFN0cmVhbTsgICAgICAgIC8vIGNvZGVkX3N0cmVhbS5oCitjbGFzcyBDb2RlZE91dHB1dFN0cmVhbTsgICAgICAgLy8gY29kZWRfc3RyZWFtLmgKK30KK25hbWVzcGFjZSBweXRob24geworY2xhc3MgTWFwUmVmbGVjdGlvbkZyaWVuZDsgICAgIC8vIHNjYWxhcl9tYXBfY29udGFpbmVyLmgKK30KKworCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorY2xhc3MgUmVwZWF0ZWRGaWVsZDsgICAgIC8vIHJlcGVhdGVkX2ZpZWxkLmgKKwordGVtcGxhdGU8dHlwZW5hbWUgVD4KK2NsYXNzIFJlcGVhdGVkUHRyRmllbGQ7ICAvLyByZXBlYXRlZF9maWVsZC5oCisKKy8vIEEgY29udGFpbmVyIHRvIGhvbGQgbWVzc2FnZSBtZXRhZGF0YS4KK3N0cnVjdCBNZXRhZGF0YSB7CisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3I7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb247Cit9OworCisvLyBBYnN0cmFjdCBpbnRlcmZhY2UgZm9yIHByb3RvY29sIG1lc3NhZ2VzLgorLy8KKy8vIFNlZSBhbHNvIE1lc3NhZ2VMaXRlLCB3aGljaCBjb250YWlucyBtb3N0IGV2ZXJ5LWRheSBvcGVyYXRpb25zLiAgTWVzc2FnZQorLy8gYWRkcyBkZXNjcmlwdG9ycyBhbmQgcmVmbGVjdGlvbiBvbiB0b3Agb2YgdGhhdC4KKy8vCisvLyBUaGUgbWV0aG9kcyBvZiB0aGlzIGNsYXNzIHRoYXQgYXJlIHZpcnR1YWwgYnV0IG5vdCBwdXJlLXZpcnR1YWwgaGF2ZQorLy8gZGVmYXVsdCBpbXBsZW1lbnRhdGlvbnMgYmFzZWQgb24gcmVmbGVjdGlvbi4gIE1lc3NhZ2UgY2xhc3NlcyB3aGljaCBhcmUKKy8vIG9wdGltaXplZCBmb3Igc3BlZWQgd2lsbCB3YW50IHRvIG92ZXJyaWRlIHRoZXNlIHdpdGggZmFzdGVyIGltcGxlbWVudGF0aW9ucywKKy8vIGJ1dCBjbGFzc2VzIG9wdGltaXplZCBmb3IgY29kZSBzaXplIG1heSBiZSBoYXBweSB3aXRoIGtlZXBpbmcgdGhlbS4gIFNlZQorLy8gdGhlIG9wdGltaXplX2ZvciBvcHRpb24gaW4gZGVzY3JpcHRvci5wcm90by4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBNZXNzYWdlIDogcHVibGljIE1lc3NhZ2VMaXRlIHsKKyBwdWJsaWM6CisgIGlubGluZSBNZXNzYWdlKCkge30KKyAgdmlydHVhbCB+TWVzc2FnZSgpOworCisgIC8vIEJhc2ljIE9wZXJhdGlvbnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gQ29uc3RydWN0IGEgbmV3IGluc3RhbmNlIG9mIHRoZSBzYW1lIHR5cGUuICBPd25lcnNoaXAgaXMgcGFzc2VkIHRvIHRoZQorICAvLyBjYWxsZXIuICAoVGhpcyBpcyBhbHNvIGRlZmluZWQgaW4gTWVzc2FnZUxpdGUsIGJ1dCBpcyBkZWZpbmVkIGFnYWluIGhlcmUKKyAgLy8gZm9yIHJldHVybi10eXBlIGNvdmFyaWFuY2UuKQorICB2aXJ0dWFsIE1lc3NhZ2UqIE5ldygpIGNvbnN0ID0gMDsKKworICAvLyBDb25zdHJ1Y3QgYSBuZXcgaW5zdGFuY2Ugb24gdGhlIGFyZW5hLiBPd25lcnNoaXAgaXMgcGFzc2VkIHRvIHRoZSBjYWxsZXIKKyAgLy8gaWYgYXJlbmEgaXMgYSBOVUxMLiBEZWZhdWx0IGltcGxlbWVudGF0aW9uIGFsbG93cyBmb3IgQVBJIGNvbXBhdGliaWxpdHkKKyAgLy8gZHVyaW5nIHRoZSBBcmVuYSB0cmFuc2l0aW9uLgorICB2aXJ0dWFsIE1lc3NhZ2UqIE5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3QgeworICAgIE1lc3NhZ2UqIG1lc3NhZ2UgPSBOZXcoKTsKKyAgICBpZiAoYXJlbmEgIT0gTlVMTCkgeworICAgICAgYXJlbmEtPk93bihtZXNzYWdlKTsKKyAgICB9CisgICAgcmV0dXJuIG1lc3NhZ2U7CisgIH0KKworICAvLyBNYWtlIHRoaXMgbWVzc2FnZSBpbnRvIGEgY29weSBvZiB0aGUgZ2l2ZW4gbWVzc2FnZS4gIFRoZSBnaXZlbiBtZXNzYWdlCisgIC8vIG11c3QgaGF2ZSB0aGUgc2FtZSBkZXNjcmlwdG9yLCBidXQgbmVlZCBub3QgbmVjZXNzYXJpbHkgYmUgdGhlIHNhbWUgY2xhc3MuCisgIC8vIEJ5IGRlZmF1bHQgdGhpcyBpcyBqdXN0IGltcGxlbWVudGVkIGFzICJDbGVhcigpOyBNZXJnZUZyb20oZnJvbSk7Ii4KKyAgdmlydHVhbCB2b2lkIENvcHlGcm9tKGNvbnN0IE1lc3NhZ2UmIGZyb20pOworCisgIC8vIE1lcmdlIHRoZSBmaWVsZHMgZnJvbSB0aGUgZ2l2ZW4gbWVzc2FnZSBpbnRvIHRoaXMgbWVzc2FnZS4gIFNpbmd1bGFyCisgIC8vIGZpZWxkcyB3aWxsIGJlIG92ZXJ3cml0dGVuLCBpZiBzcGVjaWZpZWQgaW4gZnJvbSwgZXhjZXB0IGZvciBlbWJlZGRlZAorICAvLyBtZXNzYWdlcyB3aGljaCB3aWxsIGJlIG1lcmdlZC4gIFJlcGVhdGVkIGZpZWxkcyB3aWxsIGJlIGNvbmNhdGVuYXRlZC4KKyAgLy8gVGhlIGdpdmVuIG1lc3NhZ2UgbXVzdCBiZSBvZiB0aGUgc2FtZSB0eXBlIGFzIHRoaXMgbWVzc2FnZSAoaS5lLiB0aGUKKyAgLy8gZXhhY3Qgc2FtZSBjbGFzcykuCisgIHZpcnR1YWwgdm9pZCBNZXJnZUZyb20oY29uc3QgTWVzc2FnZSYgZnJvbSk7CisKKyAgLy8gVmVyaWZpZXMgdGhhdCBJc0luaXRpYWxpemVkKCkgcmV0dXJucyB0cnVlLiAgR09PR0xFX0NIRUNLLWZhaWxzIG90aGVyd2lzZSwgd2l0aAorICAvLyBhIG5pY2UgZXJyb3IgbWVzc2FnZS4KKyAgdm9pZCBDaGVja0luaXRpYWxpemVkKCkgY29uc3Q7CisKKyAgLy8gU2xvd2x5IGJ1aWxkIGEgbGlzdCBvZiBhbGwgcmVxdWlyZWQgZmllbGRzIHRoYXQgYXJlIG5vdCBzZXQuCisgIC8vIFRoaXMgaXMgbXVjaCwgbXVjaCBzbG93ZXIgdGhhbiBJc0luaXRpYWxpemVkKCkgYXMgaXQgaXMgaW1wbGVtZW50ZWQKKyAgLy8gcHVyZWx5IHZpYSByZWZsZWN0aW9uLiAgR2VuZXJhbGx5LCB5b3Ugc2hvdWxkIG5vdCBjYWxsIHRoaXMgdW5sZXNzIHlvdQorICAvLyBoYXZlIGFscmVhZHkgZGV0ZXJtaW5lZCB0aGF0IGFuIGVycm9yIGV4aXN0cyBieSBjYWxsaW5nIElzSW5pdGlhbGl6ZWQoKS4KKyAgdm9pZCBGaW5kSW5pdGlhbGl6YXRpb25FcnJvcnMoc3RkOjp2ZWN0b3I8c3RyaW5nPiogZXJyb3JzKSBjb25zdDsKKworICAvLyBMaWtlIEZpbmRJbml0aWFsaXphdGlvbkVycm9ycywgYnV0IGpvaW5zIGFsbCB0aGUgc3RyaW5ncywgZGVsaW1pdGVkIGJ5CisgIC8vIGNvbW1hcywgYW5kIHJldHVybnMgdGhlbS4KKyAgc3RyaW5nIEluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmcoKSBjb25zdDsKKworICAvLyBDbGVhcnMgYWxsIHVua25vd24gZmllbGRzIGZyb20gdGhpcyBtZXNzYWdlIGFuZCBhbGwgZW1iZWRkZWQgbWVzc2FnZXMuCisgIC8vIE5vcm1hbGx5LCBpZiB1bmtub3duIHRhZyBudW1iZXJzIGFyZSBlbmNvdW50ZXJlZCB3aGVuIHBhcnNpbmcgYSBtZXNzYWdlLAorICAvLyB0aGUgdGFnIGFuZCB2YWx1ZSBhcmUgc3RvcmVkIGluIHRoZSBtZXNzYWdlJ3MgVW5rbm93bkZpZWxkU2V0IGFuZAorICAvLyB0aGVuIHdyaXR0ZW4gYmFjayBvdXQgd2hlbiB0aGUgbWVzc2FnZSBpcyBzZXJpYWxpemVkLiAgVGhpcyBhbGxvd3Mgc2VydmVycworICAvLyB3aGljaCBzaW1wbHkgcm91dGUgbWVzc2FnZXMgdG8gb3RoZXIgc2VydmVycyB0byBwYXNzIHRocm91Z2ggbWVzc2FnZXMKKyAgLy8gdGhhdCBoYXZlIG5ldyBmaWVsZCBkZWZpbml0aW9ucyB3aGljaCB0aGV5IGRvbid0IHlldCBrbm93IGFib3V0LiAgSG93ZXZlciwKKyAgLy8gdGhpcyBiZWhhdmlvciBjYW4gaGF2ZSBzZWN1cml0eSBpbXBsaWNhdGlvbnMuICBUbyBhdm9pZCBpdCwgY2FsbCB0aGlzCisgIC8vIG1ldGhvZCBhZnRlciBwYXJzaW5nLgorICAvLworICAvLyBTZWUgUmVmbGVjdGlvbjo6R2V0VW5rbm93bkZpZWxkcygpIGZvciBtb3JlIG9uIHVua25vd24gZmllbGRzLgorICB2aXJ0dWFsIHZvaWQgRGlzY2FyZFVua25vd25GaWVsZHMoKTsKKworICAvLyBDb21wdXRlcyAoYW4gZXN0aW1hdGUgb2YpIHRoZSB0b3RhbCBudW1iZXIgb2YgYnl0ZXMgY3VycmVudGx5IHVzZWQgZm9yCisgIC8vIHN0b3JpbmcgdGhlIG1lc3NhZ2UgaW4gbWVtb3J5LiAgVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gY2FsbHMgdGhlCisgIC8vIFJlZmxlY3Rpb24gb2JqZWN0J3MgU3BhY2VVc2VkKCkgbWV0aG9kLgorICAvLworICAvLyBTcGFjZVVzZWQoKSBpcyBub3RpY2VhYmx5IHNsb3dlciB0aGFuIEJ5dGVTaXplKCksIGFzIGl0IGlzIGltcGxlbWVudGVkCisgIC8vIHVzaW5nIHJlZmxlY3Rpb24gKHJhdGhlciB0aGFuIHRoZSBnZW5lcmF0ZWQgY29kZSBpbXBsZW1lbnRhdGlvbiBmb3IKKyAgLy8gQnl0ZVNpemUoKSkuIExpa2UgQnl0ZVNpemUoKSwgaXRzIENQVSB0aW1lIGlzIGxpbmVhciBpbiB0aGUgbnVtYmVyIG9mCisgIC8vIGZpZWxkcyBkZWZpbmVkIGZvciB0aGUgcHJvdG8uCisgIHZpcnR1YWwgaW50IFNwYWNlVXNlZCgpIGNvbnN0OworCisgIC8vIERlYnVnZ2luZyAmIFRlc3RpbmctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gR2VuZXJhdGVzIGEgaHVtYW4gcmVhZGFibGUgZm9ybSBvZiB0aGlzIG1lc3NhZ2UsIHVzZWZ1bCBmb3IgZGVidWdnaW5nCisgIC8vIGFuZCBvdGhlciBwdXJwb3Nlcy4KKyAgc3RyaW5nIERlYnVnU3RyaW5nKCkgY29uc3Q7CisgIC8vIExpa2UgRGVidWdTdHJpbmcoKSwgYnV0IHdpdGggbGVzcyB3aGl0ZXNwYWNlLgorICBzdHJpbmcgU2hvcnREZWJ1Z1N0cmluZygpIGNvbnN0OworICAvLyBMaWtlIERlYnVnU3RyaW5nKCksIGJ1dCBkbyBub3QgZXNjYXBlIFVURi04IGJ5dGUgc2VxdWVuY2VzLgorICBzdHJpbmcgVXRmOERlYnVnU3RyaW5nKCkgY29uc3Q7CisgIC8vIENvbnZlbmllbmNlIGZ1bmN0aW9uIHVzZWZ1bCBpbiBHREIuICBQcmludHMgRGVidWdTdHJpbmcoKSB0byBzdGRvdXQuCisgIHZvaWQgUHJpbnREZWJ1Z1N0cmluZygpIGNvbnN0OworCisgIC8vIEhlYXZ5IEkvTyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8vIEFkZGl0aW9uYWwgcGFyc2luZyBhbmQgc2VyaWFsaXphdGlvbiBtZXRob2RzIG5vdCBpbXBsZW1lbnRlZCBieQorICAvLyBNZXNzYWdlTGl0ZSBiZWNhdXNlIHRoZXkgYXJlIG5vdCBzdXBwb3J0ZWQgYnkgdGhlIGxpdGUgbGlicmFyeS4KKworICAvLyBQYXJzZSBhIHByb3RvY29sIGJ1ZmZlciBmcm9tIGEgZmlsZSBkZXNjcmlwdG9yLiAgSWYgc3VjY2Vzc2Z1bCwgdGhlIGVudGlyZQorICAvLyBpbnB1dCB3aWxsIGJlIGNvbnN1bWVkLgorICBib29sIFBhcnNlRnJvbUZpbGVEZXNjcmlwdG9yKGludCBmaWxlX2Rlc2NyaXB0b3IpOworICAvLyBMaWtlIFBhcnNlRnJvbUZpbGVEZXNjcmlwdG9yKCksIGJ1dCBhY2NlcHRzIG1lc3NhZ2VzIHRoYXQgYXJlIG1pc3NpbmcKKyAgLy8gcmVxdWlyZWQgZmllbGRzLgorICBib29sIFBhcnNlUGFydGlhbEZyb21GaWxlRGVzY3JpcHRvcihpbnQgZmlsZV9kZXNjcmlwdG9yKTsKKyAgLy8gUGFyc2UgYSBwcm90b2NvbCBidWZmZXIgZnJvbSBhIEMrKyBpc3RyZWFtLiAgSWYgc3VjY2Vzc2Z1bCwgdGhlIGVudGlyZQorICAvLyBpbnB1dCB3aWxsIGJlIGNvbnN1bWVkLgorICBib29sIFBhcnNlRnJvbUlzdHJlYW0oaXN0cmVhbSogaW5wdXQpOworICAvLyBMaWtlIFBhcnNlRnJvbUlzdHJlYW0oKSwgYnV0IGFjY2VwdHMgbWVzc2FnZXMgdGhhdCBhcmUgbWlzc2luZworICAvLyByZXF1aXJlZCBmaWVsZHMuCisgIGJvb2wgUGFyc2VQYXJ0aWFsRnJvbUlzdHJlYW0oaXN0cmVhbSogaW5wdXQpOworCisgIC8vIFNlcmlhbGl6ZSB0aGUgbWVzc2FnZSBhbmQgd3JpdGUgaXQgdG8gdGhlIGdpdmVuIGZpbGUgZGVzY3JpcHRvci4gIEFsbAorICAvLyByZXF1aXJlZCBmaWVsZHMgbXVzdCBiZSBzZXQuCisgIGJvb2wgU2VyaWFsaXplVG9GaWxlRGVzY3JpcHRvcihpbnQgZmlsZV9kZXNjcmlwdG9yKSBjb25zdDsKKyAgLy8gTGlrZSBTZXJpYWxpemVUb0ZpbGVEZXNjcmlwdG9yKCksIGJ1dCBhbGxvd3MgbWlzc2luZyByZXF1aXJlZCBmaWVsZHMuCisgIGJvb2wgU2VyaWFsaXplUGFydGlhbFRvRmlsZURlc2NyaXB0b3IoaW50IGZpbGVfZGVzY3JpcHRvcikgY29uc3Q7CisgIC8vIFNlcmlhbGl6ZSB0aGUgbWVzc2FnZSBhbmQgd3JpdGUgaXQgdG8gdGhlIGdpdmVuIEMrKyBvc3RyZWFtLiAgQWxsCisgIC8vIHJlcXVpcmVkIGZpZWxkcyBtdXN0IGJlIHNldC4KKyAgYm9vbCBTZXJpYWxpemVUb09zdHJlYW0ob3N0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgLy8gTGlrZSBTZXJpYWxpemVUb09zdHJlYW0oKSwgYnV0IGFsbG93cyBtaXNzaW5nIHJlcXVpcmVkIGZpZWxkcy4KKyAgYm9vbCBTZXJpYWxpemVQYXJ0aWFsVG9Pc3RyZWFtKG9zdHJlYW0qIG91dHB1dCkgY29uc3Q7CisKKworICAvLyBSZWZsZWN0aW9uLWJhc2VkIG1ldGhvZHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAvLyBUaGVzZSBtZXRob2RzIGFyZSBwdXJlLXZpcnR1YWwgaW4gTWVzc2FnZUxpdGUsIGJ1dCBNZXNzYWdlIHByb3ZpZGVzCisgIC8vIHJlZmxlY3Rpb24tYmFzZWQgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbnMuCisKKyAgdmlydHVhbCBzdHJpbmcgR2V0VHlwZU5hbWUoKSBjb25zdDsKKyAgdmlydHVhbCB2b2lkIENsZWFyKCk7CisgIHZpcnR1YWwgYm9vbCBJc0luaXRpYWxpemVkKCkgY29uc3Q7CisgIHZpcnR1YWwgdm9pZCBDaGVja1R5cGVBbmRNZXJnZUZyb20oY29uc3QgTWVzc2FnZUxpdGUmIG90aGVyKTsKKyAgdmlydHVhbCBib29sIE1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbShpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpOworICB2aXJ0dWFsIGludCBCeXRlU2l6ZSgpIGNvbnN0OworICB2aXJ0dWFsIHZvaWQgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKworIHByaXZhdGU6CisgIC8vIFRoaXMgaXMgY2FsbGVkIG9ubHkgYnkgdGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gb2YgQnl0ZVNpemUoKSwgdG8KKyAgLy8gdXBkYXRlIHRoZSBjYWNoZWQgc2l6ZS4gIElmIHlvdSBvdmVycmlkZSBCeXRlU2l6ZSgpLCB5b3UgZG8gbm90IG5lZWQKKyAgLy8gdG8gb3ZlcnJpZGUgdGhpcy4gIElmIHlvdSBkbyBub3Qgb3ZlcnJpZGUgQnl0ZVNpemUoKSwgeW91IE1VU1Qgb3ZlcnJpZGUKKyAgLy8gdGhpczsgdGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gd2lsbCBjcmFzaC4KKyAgLy8KKyAgLy8gVGhlIG1ldGhvZCBpcyBwcml2YXRlIGJlY2F1c2Ugc3ViY2xhc3NlcyBzaG91bGQgbmV2ZXIgY2FsbCBpdDsgb25seQorICAvLyBvdmVycmlkZSBpdC4gIFllcywgQysrIGxldHMgeW91IGRvIHRoYXQuICBDcmF6eSwgaHVoPworICB2aXJ0dWFsIHZvaWQgU2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3Q7CisKKyBwdWJsaWM6CisKKyAgLy8gSW50cm9zcGVjdGlvbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBUeXBlZGVmIGZvciBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eS4KKyAgdHlwZWRlZiBnb29nbGU6OnByb3RvYnVmOjpSZWZsZWN0aW9uIFJlZmxlY3Rpb247CisKKyAgLy8gR2V0IGEgRGVzY3JpcHRvciBmb3IgdGhpcyBtZXNzYWdlJ3MgdHlwZS4gIFRoaXMgZGVzY3JpYmVzIHdoYXQKKyAgLy8gZmllbGRzIHRoZSBtZXNzYWdlIGNvbnRhaW5zLCB0aGUgdHlwZXMgb2YgdGhvc2UgZmllbGRzLCBldGMuCisgIGNvbnN0IERlc2NyaXB0b3IqIEdldERlc2NyaXB0b3IoKSBjb25zdCB7IHJldHVybiBHZXRNZXRhZGF0YSgpLmRlc2NyaXB0b3I7IH0KKworICAvLyBHZXQgdGhlIFJlZmxlY3Rpb24gaW50ZXJmYWNlIGZvciB0aGlzIE1lc3NhZ2UsIHdoaWNoIGNhbiBiZSB1c2VkIHRvCisgIC8vIHJlYWQgYW5kIG1vZGlmeSB0aGUgZmllbGRzIG9mIHRoZSBNZXNzYWdlIGR5bmFtaWNhbGx5IChpbiBvdGhlciB3b3JkcywKKyAgLy8gd2l0aG91dCBrbm93aW5nIHRoZSBtZXNzYWdlIHR5cGUgYXQgY29tcGlsZSB0aW1lKS4gIFRoaXMgb2JqZWN0IHJlbWFpbnMKKyAgLy8gcHJvcGVydHkgb2YgdGhlIE1lc3NhZ2UuCisgIC8vCisgIC8vIFRoaXMgbWV0aG9kIHJlbWFpbnMgdmlydHVhbCBpbiBjYXNlIGEgc3ViY2xhc3MgZG9lcyBub3QgaW1wbGVtZW50CisgIC8vIHJlZmxlY3Rpb24gYW5kIHdhbnRzIHRvIG92ZXJyaWRlIHRoZSBkZWZhdWx0IGJlaGF2aW9yLgorICB2aXJ0dWFsIGNvbnN0IFJlZmxlY3Rpb24qIEdldFJlZmxlY3Rpb24oKSBjb25zdCB7CisgICAgcmV0dXJuIEdldE1ldGFkYXRhKCkucmVmbGVjdGlvbjsKKyAgfQorCisgcHJvdGVjdGVkOgorICAvLyBHZXQgYSBzdHJ1Y3QgY29udGFpbmluZyB0aGUgbWV0YWRhdGEgZm9yIHRoZSBNZXNzYWdlLiBNb3N0IHN1YmNsYXNzZXMgb25seQorICAvLyBuZWVkIHRvIGltcGxlbWVudCB0aGlzIG1ldGhvZCwgcmF0aGVyIHRoYW4gdGhlIEdldERlc2NyaXB0b3IoKSBhbmQKKyAgLy8gR2V0UmVmbGVjdGlvbigpIHdyYXBwZXJzLgorICB2aXJ0dWFsIE1ldGFkYXRhIEdldE1ldGFkYXRhKCkgY29uc3QgID0gMDsKKworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKE1lc3NhZ2UpOworfTsKKworbmFtZXNwYWNlIGludGVybmFsIHsKKy8vIEZvcndhcmQtZGVjbGFyZSBpbnRlcmZhY2VzIHVzZWQgdG8gaW1wbGVtZW50IFJlcGVhdGVkRmllbGRSZWYuCisvLyBUaGVzZSBhcmUgcHJvdG9idWYgaW50ZXJuYWxzIHRoYXQgdXNlcnMgc2hvdWxkbid0IGNhcmUgYWJvdXQuCitjbGFzcyBSZXBlYXRlZEZpZWxkQWNjZXNzb3I7Cit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKKworLy8gRm9yd2FyZC1kZWNsYXJlIFJlcGVhdGVkRmllbGRSZWYgdGVtcGxhdGVzLiBUaGUgc2Vjb25kIHR5cGUgcGFyYW1ldGVyIGlzCisvLyB1c2VkIGZvciBTRklOQUUgdHJpY2tzLiBVc2VycyBzaG91bGQgaWdub3JlIGl0LgordGVtcGxhdGU8dHlwZW5hbWUgVCwgdHlwZW5hbWUgRW5hYmxlID0gdm9pZD4KK2NsYXNzIFJlcGVhdGVkRmllbGRSZWY7CisKK3RlbXBsYXRlPHR5cGVuYW1lIFQsIHR5cGVuYW1lIEVuYWJsZSA9IHZvaWQ+CitjbGFzcyBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjsKKworLy8gVGhpcyBpbnRlcmZhY2UgY29udGFpbnMgbWV0aG9kcyB0aGF0IGNhbiBiZSB1c2VkIHRvIGR5bmFtaWNhbGx5IGFjY2VzcworLy8gYW5kIG1vZGlmeSB0aGUgZmllbGRzIG9mIGEgcHJvdG9jb2wgbWVzc2FnZS4gIFRoZWlyIHNlbWFudGljcyBhcmUKKy8vIHNpbWlsYXIgdG8gdGhlIGFjY2Vzc29ycyB0aGUgcHJvdG9jb2wgY29tcGlsZXIgZ2VuZXJhdGVzLgorLy8KKy8vIFRvIGdldCB0aGUgUmVmbGVjdGlvbiBmb3IgYSBnaXZlbiBNZXNzYWdlLCBjYWxsIE1lc3NhZ2U6OkdldFJlZmxlY3Rpb24oKS4KKy8vCisvLyBUaGlzIGludGVyZmFjZSBpcyBzZXBhcmF0ZSBmcm9tIE1lc3NhZ2Ugb25seSBmb3IgZWZmaWNpZW5jeSByZWFzb25zOworLy8gdGhlIHZhc3QgbWFqb3JpdHkgb2YgaW1wbGVtZW50YXRpb25zIG9mIE1lc3NhZ2Ugd2lsbCBzaGFyZSB0aGUgc2FtZQorLy8gaW1wbGVtZW50YXRpb24gb2YgUmVmbGVjdGlvbiAoR2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24sCisvLyBkZWZpbmVkIGluIGdlbmVyYXRlZF9tZXNzYWdlLmgpLCBhbmQgYWxsIE1lc3NhZ2VzIG9mIGEgcGFydGljdWxhciBjbGFzcworLy8gc2hvdWxkIHNoYXJlIHRoZSBzYW1lIFJlZmxlY3Rpb24gb2JqZWN0ICh0aG91Z2ggeW91IHNob3VsZCBub3QgcmVseSBvbgorLy8gdGhlIGxhdHRlciBmYWN0KS4KKy8vCisvLyBUaGVyZSBhcmUgc2V2ZXJhbCB3YXlzIHRoYXQgdGhlc2UgbWV0aG9kcyBjYW4gYmUgdXNlZCBpbmNvcnJlY3RseS4gIEZvcgorLy8gZXhhbXBsZSwgYW55IG9mIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyB3aWxsIGxlYWQgdG8gdW5kZWZpbmVkCisvLyByZXN1bHRzIChwcm9iYWJseSBhc3NlcnRpb24gZmFpbHVyZXMpOgorLy8gLSBUaGUgRmllbGREZXNjcmlwdG9yIGlzIG5vdCBhIGZpZWxkIG9mIHRoaXMgbWVzc2FnZSB0eXBlLgorLy8gLSBUaGUgbWV0aG9kIGNhbGxlZCBpcyBub3QgYXBwcm9wcmlhdGUgZm9yIHRoZSBmaWVsZCdzIHR5cGUuICBGb3IKKy8vICAgZWFjaCBmaWVsZCB0eXBlIGluIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV8qLCB0aGVyZSBpcyBvbmx5IG9uZQorLy8gICBHZXQqKCkgbWV0aG9kLCBvbmUgU2V0KigpIG1ldGhvZCwgYW5kIG9uZSBBZGQqKCkgbWV0aG9kIHRoYXQgaXMKKy8vICAgdmFsaWQgZm9yIHRoYXQgdHlwZS4gIEl0IHNob3VsZCBiZSBvYnZpb3VzIHdoaWNoIChleGNlcHQgbWF5YmUKKy8vICAgZm9yIFRZUEVfQllURVMsIHdoaWNoIGFyZSByZXByZXNlbnRlZCB1c2luZyBzdHJpbmdzIGluIEMrKykuCisvLyAtIEEgR2V0KigpIG9yIFNldCooKSBtZXRob2QgZm9yIHNpbmd1bGFyIGZpZWxkcyBpcyBjYWxsZWQgb24gYSByZXBlYXRlZAorLy8gICBmaWVsZC4KKy8vIC0gR2V0UmVwZWF0ZWQqKCksIFNldFJlcGVhdGVkKigpLCBvciBBZGQqKCkgaXMgY2FsbGVkIG9uIGEgbm9uLXJlcGVhdGVkCisvLyAgIGZpZWxkLgorLy8gLSBUaGUgTWVzc2FnZSBvYmplY3QgcGFzc2VkIHRvIGFueSBtZXRob2QgaXMgbm90IG9mIHRoZSByaWdodCB0eXBlIGZvcgorLy8gICB0aGlzIFJlZmxlY3Rpb24gb2JqZWN0IChpLmUuIG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpICE9IHJlZmxlY3Rpb24pLgorLy8KKy8vIFlvdSBtaWdodCB3b25kZXIgd2h5IHRoZXJlIGlzIG5vdCBhbnkgYWJzdHJhY3QgcmVwcmVzZW50YXRpb24gZm9yIGEgZmllbGQKKy8vIG9mIGFyYml0cmFyeSB0eXBlLiAgRS5nLiwgd2h5IGlzbid0IHRoZXJlIGp1c3QgYSAiR2V0RmllbGQoKSIgbWV0aG9kIHRoYXQKKy8vIHJldHVybnMgImNvbnN0IEZpZWxkJiIsIHdoZXJlICJGaWVsZCIgaXMgc29tZSBjbGFzcyB3aXRoIGFjY2Vzc29ycyBsaWtlCisvLyAiR2V0SW50MzJWYWx1ZSgpIi4gIFRoZSBwcm9ibGVtIGlzIHRoYXQgc29tZW9uZSB3b3VsZCBoYXZlIHRvIGRlYWwgd2l0aAorLy8gYWxsb2NhdGluZyB0aGVzZSBGaWVsZCBvYmplY3RzLiAgRm9yIGdlbmVyYXRlZCBtZXNzYWdlIGNsYXNzZXMsIGhhdmluZyB0bworLy8gYWxsb2NhdGUgc3BhY2UgZm9yIGFuIGFkZGl0aW9uYWwgb2JqZWN0IHRvIHdyYXAgZXZlcnkgZmllbGQgd291bGQgYXQgbGVhc3QKKy8vIGRvdWJsZSB0aGUgbWVzc2FnZSdzIG1lbW9yeSBmb290cHJpbnQsIHByb2JhYmx5IHdvcnNlLiAgQWxsb2NhdGluZyB0aGUKKy8vIG9iamVjdHMgb24tZGVtYW5kLCBvbiB0aGUgb3RoZXIgaGFuZCwgd291bGQgYmUgZXhwZW5zaXZlIGFuZCBwcm9uZSB0bworLy8gbWVtb3J5IGxlYWtzLiAgU28sIGluc3RlYWQgd2UgZW5kZWQgdXAgd2l0aCB0aGlzIGZsYXQgaW50ZXJmYWNlLgorLy8KKy8vIFRPRE8oa2VudG9uKTogIENyZWF0ZSBhIHV0aWxpdHkgY2xhc3Mgd2hpY2ggY2FsbGVycyBjYW4gdXNlIHRvIHJlYWQgYW5kCisvLyAgIHdyaXRlIGZpZWxkcyBmcm9tIGEgUmVmbGVjdGlvbiB3aXRob3V0IHBheWluZyBhdHRlbnRpb24gdG8gdGhlIHR5cGUuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgUmVmbGVjdGlvbiB7CisgcHVibGljOgorICBpbmxpbmUgUmVmbGVjdGlvbigpIHt9CisgIHZpcnR1YWwgflJlZmxlY3Rpb24oKTsKKworICAvLyBHZXQgdGhlIFVua25vd25GaWVsZFNldCBmb3IgdGhlIG1lc3NhZ2UuICBUaGlzIGNvbnRhaW5zIGZpZWxkcyB3aGljaAorICAvLyB3ZXJlIHNlZW4gd2hlbiB0aGUgTWVzc2FnZSB3YXMgcGFyc2VkIGJ1dCB3ZXJlIG5vdCByZWNvZ25pemVkIGFjY29yZGluZworICAvLyB0byB0aGUgTWVzc2FnZSdzIGRlZmluaXRpb24uIEZvciBwcm90bzMgcHJvdG9zLCB0aGlzIG1ldGhvZCB3aWxsIGFsd2F5cworICAvLyByZXR1cm4gYW4gZW1wdHkgVW5rbm93bkZpZWxkU2V0LgorICB2aXJ0dWFsIGNvbnN0IFVua25vd25GaWVsZFNldCYgR2V0VW5rbm93bkZpZWxkcygKKyAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UpIGNvbnN0ID0gMDsKKyAgLy8gR2V0IGEgbXV0YWJsZSBwb2ludGVyIHRvIHRoZSBVbmtub3duRmllbGRTZXQgZm9yIHRoZSBtZXNzYWdlLiAgVGhpcworICAvLyBjb250YWlucyBmaWVsZHMgd2hpY2ggd2VyZSBzZWVuIHdoZW4gdGhlIE1lc3NhZ2Ugd2FzIHBhcnNlZCBidXQgd2VyZSBub3QKKyAgLy8gcmVjb2duaXplZCBhY2NvcmRpbmcgdG8gdGhlIE1lc3NhZ2UncyBkZWZpbml0aW9uLiBGb3IgcHJvdG8zIHByb3RvcywgdGhpcworICAvLyBtZXRob2Qgd2lsbCByZXR1cm4gYSB2YWxpZCBtdXRhYmxlIFVua25vd25GaWVsZFNldCBwb2ludGVyIGJ1dCBtb2RpZnlpbmcKKyAgLy8gaXQgd29uJ3QgYWZmZWN0IHRoZSBzZXJpYWxpemVkIGJ5dGVzIG9mIHRoZSBtZXNzYWdlLgorICB2aXJ0dWFsIFVua25vd25GaWVsZFNldCogTXV0YWJsZVVua25vd25GaWVsZHMoTWVzc2FnZSogbWVzc2FnZSkgY29uc3QgPSAwOworCisgIC8vIEVzdGltYXRlIHRoZSBhbW91bnQgb2YgbWVtb3J5IHVzZWQgYnkgdGhlIG1lc3NhZ2Ugb2JqZWN0LgorICB2aXJ0dWFsIGludCBTcGFjZVVzZWQoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSkgY29uc3QgPSAwOworCisgIC8vIENoZWNrIGlmIHRoZSBnaXZlbiBub24tcmVwZWF0ZWQgZmllbGQgaXMgc2V0LgorICB2aXJ0dWFsIGJvb2wgSGFzRmllbGQoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0ID0gMDsKKworICAvLyBHZXQgdGhlIG51bWJlciBvZiBlbGVtZW50cyBvZiBhIHJlcGVhdGVkIGZpZWxkLgorICB2aXJ0dWFsIGludCBGaWVsZFNpemUoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0ID0gMDsKKworICAvLyBDbGVhciB0aGUgdmFsdWUgb2YgYSBmaWVsZCwgc28gdGhhdCBIYXNGaWVsZCgpIHJldHVybnMgZmFsc2Ugb3IKKyAgLy8gRmllbGRTaXplKCkgcmV0dXJucyB6ZXJvLgorICB2aXJ0dWFsIHZvaWQgQ2xlYXJGaWVsZChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCA9IDA7CisKKyAgLy8gQ2hlY2sgaWYgdGhlIG9uZW9mIGlzIHNldC4gUmV0dXJucyB0cnVlIGlmIGFueSBmaWVsZCBpbiBvbmVvZgorICAvLyBpcyBzZXQsIGZhbHNlIG90aGVyd2lzZS4KKyAgLy8gVE9ETyhqaWVsdW8pIC0gbWFrZSBpdCBwdXJlIHZpcnR1YWwgYWZ0ZXIgdXBkYXRpbmcgYWxsCisgIC8vIHRoZSBzdWJjbGFzc2VzLgorICB2aXJ0dWFsIGJvb2wgSGFzT25lb2YoY29uc3QgTWVzc2FnZSYgLyptZXNzYWdlKi8sCisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBPbmVvZkRlc2NyaXB0b3IqIC8qb25lb2ZfZGVzY3JpcHRvciovKSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgdmlydHVhbCB2b2lkIENsZWFyT25lb2YoTWVzc2FnZSogLyptZXNzYWdlKi8sCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE9uZW9mRGVzY3JpcHRvciogLypvbmVvZl9kZXNjcmlwdG9yKi8pIGNvbnN0IHt9CisKKyAgLy8gUmV0dXJucyB0aGUgZmllbGQgZGVzY3JpcHRvciBpZiB0aGUgb25lb2YgaXMgc2V0LiBOVUxMIG90aGVyd2lzZS4KKyAgLy8gVE9ETyhqaWVsdW8pIC0gbWFrZSBpdCBwdXJlIHZpcnR1YWwuCisgIHZpcnR1YWwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBHZXRPbmVvZkZpZWxkRGVzY3JpcHRvcigKKyAgICAgIGNvbnN0IE1lc3NhZ2UmIC8qbWVzc2FnZSovLAorICAgICAgY29uc3QgT25lb2ZEZXNjcmlwdG9yKiAvKm9uZW9mX2Rlc2NyaXB0b3IqLykgY29uc3QgeworICAgIHJldHVybiBOVUxMOworICB9CisKKyAgLy8gUmVtb3ZlcyB0aGUgbGFzdCBlbGVtZW50IG9mIGEgcmVwZWF0ZWQgZmllbGQuCisgIC8vIFdlIGRvbid0IHByb3ZpZGUgYSB3YXkgdG8gcmVtb3ZlIGFueSBlbGVtZW50IG90aGVyIHRoYW4gdGhlIGxhc3QKKyAgLy8gYmVjYXVzZSBpdCBpbnZpdGVzIGluZWZmaWNpZW50IHVzZSwgc3VjaCBhcyBPKG5eMikgZmlsdGVyaW5nIGxvb3BzCisgIC8vIHRoYXQgc2hvdWxkIGhhdmUgYmVlbiBPKG4pLiAgSWYgeW91IHdhbnQgdG8gcmVtb3ZlIGFuIGVsZW1lbnQgb3RoZXIKKyAgLy8gdGhhbiB0aGUgbGFzdCwgdGhlIGJlc3Qgd2F5IHRvIGRvIGl0IGlzIHRvIHJlLWFycmFuZ2UgdGhlIGVsZW1lbnRzCisgIC8vICh1c2luZyBTd2FwKCkpIHNvIHRoYXQgdGhlIG9uZSB5b3Ugd2FudCByZW1vdmVkIGlzIGF0IHRoZSBlbmQsIHRoZW4KKyAgLy8gY2FsbCBSZW1vdmVMYXN0KCkuCisgIHZpcnR1YWwgdm9pZCBSZW1vdmVMYXN0KE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0ID0gMDsKKyAgLy8gUmVtb3ZlcyB0aGUgbGFzdCBlbGVtZW50IG9mIGEgcmVwZWF0ZWQgbWVzc2FnZSBmaWVsZCwgYW5kIHJldHVybnMgdGhlCisgIC8vIHBvaW50ZXIgdG8gdGhlIGNhbGxlci4gIENhbGxlciB0YWtlcyBvd25lcnNoaXAgb2YgdGhlIHJldHVybmVkIHBvaW50ZXIuCisgIHZpcnR1YWwgTWVzc2FnZSogUmVsZWFzZUxhc3QoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCA9IDA7CisKKyAgLy8gU3dhcCB0aGUgY29tcGxldGUgY29udGVudHMgb2YgdHdvIG1lc3NhZ2VzLgorICB2aXJ0dWFsIHZvaWQgU3dhcChNZXNzYWdlKiBtZXNzYWdlMSwgTWVzc2FnZSogbWVzc2FnZTIpIGNvbnN0ID0gMDsKKworICAvLyBTd2FwIGZpZWxkcyBsaXN0ZWQgaW4gZmllbGRzIHZlY3RvciBvZiB0d28gbWVzc2FnZXMuCisgIHZpcnR1YWwgdm9pZCBTd2FwRmllbGRzKE1lc3NhZ2UqIG1lc3NhZ2UxLAorICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlKiBtZXNzYWdlMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RkOjp2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4mIGZpZWxkcykKKyAgICAgIGNvbnN0ID0gMDsKKworICAvLyBTd2FwIHR3byBlbGVtZW50cyBvZiBhIHJlcGVhdGVkIGZpZWxkLgorICB2aXJ0dWFsIHZvaWQgU3dhcEVsZW1lbnRzKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXgxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleDIpIGNvbnN0ID0gMDsKKworICAvLyBMaXN0IGFsbCBmaWVsZHMgb2YgdGhlIG1lc3NhZ2Ugd2hpY2ggYXJlIGN1cnJlbnRseSBzZXQuICBUaGlzIGluY2x1ZGVzCisgIC8vIGV4dGVuc2lvbnMuICBTaW5ndWxhciBmaWVsZHMgd2lsbCBvbmx5IGJlIGxpc3RlZCBpZiBIYXNGaWVsZChmaWVsZCkgd291bGQKKyAgLy8gcmV0dXJuIHRydWUgYW5kIHJlcGVhdGVkIGZpZWxkcyB3aWxsIG9ubHkgYmUgbGlzdGVkIGlmIEZpZWxkU2l6ZShmaWVsZCkKKyAgLy8gd291bGQgcmV0dXJuIG5vbi16ZXJvLiAgRmllbGRzIChib3RoIG5vcm1hbCBmaWVsZHMgYW5kIGV4dGVuc2lvbiBmaWVsZHMpCisgIC8vIHdpbGwgYmUgbGlzdGVkIG9yZGVyZWQgYnkgZmllbGQgbnVtYmVyLgorICB2aXJ0dWFsIHZvaWQgTGlzdEZpZWxkcygKKyAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICBzdGQ6OnZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiogb3V0cHV0KSBjb25zdCA9IDA7CisKKyAgLy8gU2luZ3VsYXIgZmllbGQgZ2V0dGVycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgLy8gVGhlc2UgZ2V0IHRoZSB2YWx1ZSBvZiBhIG5vbi1yZXBlYXRlZCBmaWVsZC4gIFRoZXkgcmV0dXJuIHRoZSBkZWZhdWx0CisgIC8vIHZhbHVlIGZvciBmaWVsZHMgdGhhdCBhcmVuJ3Qgc2V0LgorCisgIHZpcnR1YWwgaW50MzIgIEdldEludDMyIChjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3QgPSAwOworICB2aXJ0dWFsIGludDY0ICBHZXRJbnQ2NCAoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCB1aW50MzIgR2V0VUludDMyKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdWludDY0IEdldFVJbnQ2NChjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3QgPSAwOworICB2aXJ0dWFsIGZsb2F0ICBHZXRGbG9hdCAoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCBkb3VibGUgR2V0RG91YmxlKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgYm9vbCAgIEdldEJvb2wgIChjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3QgPSAwOworICB2aXJ0dWFsIHN0cmluZyBHZXRTdHJpbmcoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBHZXRFbnVtKAorICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3QgPSAwOworCisgIC8vIEdldEVudW1WYWx1ZSgpIHJldHVybnMgYW4gZW51bSBmaWVsZCdzIHZhbHVlIGFzIGFuIGludGVnZXIgcmF0aGVyIHRoYW4KKyAgLy8gYW4gRW51bVZhbHVlRGVzY3JpcHRvciouIElmIHRoZSBpbnRlZ2VyIHZhbHVlIGRvZXMgbm90IGNvcnJlc3BvbmQgdG8gYQorICAvLyBrbm93biB2YWx1ZSBkZXNjcmlwdG9yLCBhIG5ldyB2YWx1ZSBkZXNjcmlwdG9yIGlzIGNyZWF0ZWQuIChTdWNoIGEgdmFsdWUKKyAgLy8gd2lsbCBvbmx5IGJlIHByZXNlbnQgd2hlbiB0aGUgbmV3IHVua25vd24tZW51bS12YWx1ZSBzZW1hbnRpY3MgYXJlIGVuYWJsZWQKKyAgLy8gZm9yIGEgbWVzc2FnZS4pCisgIHZpcnR1YWwgaW50IEdldEVudW1WYWx1ZSgKKyAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0OworCisgIC8vIFNlZSBNdXRhYmxlTWVzc2FnZSgpIGZvciB0aGUgbWVhbmluZyBvZiB0aGUgImZhY3RvcnkiIHBhcmFtZXRlci4KKyAgdmlydHVhbCBjb25zdCBNZXNzYWdlJiBHZXRNZXNzYWdlKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUZhY3RvcnkqIGZhY3RvcnkgPSBOVUxMKSBjb25zdCA9IDA7CisKKyAgLy8gR2V0IGEgc3RyaW5nIHZhbHVlIHdpdGhvdXQgY29weWluZywgaWYgcG9zc2libGUuCisgIC8vCisgIC8vIEdldFN0cmluZygpIG5lY2Vzc2FyaWx5IHJldHVybnMgYSBjb3B5IG9mIHRoZSBzdHJpbmcuICBUaGlzIGNhbiBiZQorICAvLyBpbmVmZmljaWVudCB3aGVuIHRoZSBzdHJpbmcgaXMgYWxyZWFkeSBzdG9yZWQgaW4gYSBzdHJpbmcgb2JqZWN0IGluIHRoZQorICAvLyB1bmRlcmx5aW5nIG1lc3NhZ2UuICBHZXRTdHJpbmdSZWZlcmVuY2UoKSB3aWxsIHJldHVybiBhIHJlZmVyZW5jZSB0byB0aGUKKyAgLy8gdW5kZXJseWluZyBzdHJpbmcgaW4gdGhpcyBjYXNlLiAgT3RoZXJ3aXNlLCBpdCB3aWxsIGNvcHkgdGhlIHN0cmluZyBpbnRvCisgIC8vICpzY3JhdGNoIGFuZCByZXR1cm4gdGhhdC4KKyAgLy8KKyAgLy8gTm90ZTogIEl0IGlzIHBlcmZlY3RseSByZWFzb25hYmxlIGFuZCB1c2VmdWwgdG8gd3JpdGUgY29kZSBsaWtlOgorICAvLyAgICAgc3RyID0gcmVmbGVjdGlvbi0+R2V0U3RyaW5nUmVmZXJlbmNlKGZpZWxkLCAmc3RyKTsKKyAgLy8gICBUaGlzIGxpbmUgd291bGQgZW5zdXJlIHRoYXQgb25seSBvbmUgY29weSBvZiB0aGUgc3RyaW5nIGlzIG1hZGUKKyAgLy8gICByZWdhcmRsZXNzIG9mIHRoZSBmaWVsZCdzIHVuZGVybHlpbmcgcmVwcmVzZW50YXRpb24uICBXaGVuIGluaXRpYWxpemluZworICAvLyAgIGEgbmV3bHktY29uc3RydWN0ZWQgc3RyaW5nLCB0aG91Z2gsIGl0J3MganVzdCBhcyBmYXN0IGFuZCBtb3JlIHJlYWRhYmxlCisgIC8vICAgdG8gdXNlIGNvZGUgbGlrZToKKyAgLy8gICAgIHN0cmluZyBzdHIgPSByZWZsZWN0aW9uLT5HZXRTdHJpbmcobWVzc2FnZSwgZmllbGQpOworICB2aXJ0dWFsIGNvbnN0IHN0cmluZyYgR2V0U3RyaW5nUmVmZXJlbmNlKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcqIHNjcmF0Y2gpIGNvbnN0ID0gMDsKKworCisgIC8vIFNpbmd1bGFyIGZpZWxkIG11dGF0b3JzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8vIFRoZXNlIG11dGF0ZSB0aGUgdmFsdWUgb2YgYSBub24tcmVwZWF0ZWQgZmllbGQuCisKKyAgdmlydHVhbCB2b2lkIFNldEludDMyIChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGludDMyICB2YWx1ZSkgY29uc3QgPSAwOworICB2aXJ0dWFsIHZvaWQgU2V0SW50NjQgKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50NjQgIHZhbHVlKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBTZXRVSW50MzIoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCB1aW50MzIgdmFsdWUpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCB2b2lkIFNldFVJbnQ2NChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIHVpbnQ2NCB2YWx1ZSkgY29uc3QgPSAwOworICB2aXJ0dWFsIHZvaWQgU2V0RmxvYXQgKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgZmxvYXQgIHZhbHVlKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBTZXREb3VibGUoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBkb3VibGUgdmFsdWUpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCB2b2lkIFNldEJvb2wgIChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGJvb2wgICB2YWx1ZSkgY29uc3QgPSAwOworICB2aXJ0dWFsIHZvaWQgU2V0U3RyaW5nKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHZhbHVlKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBTZXRFbnVtICAoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIHZhbHVlKSBjb25zdCA9IDA7CisgIC8vIFNldCBhbiBlbnVtIGZpZWxkJ3MgdmFsdWUgd2l0aCBhbiBpbnRlZ2VyIHJhdGhlciB0aGFuIEVudW1WYWx1ZURlc2NyaXB0b3IuCisgIC8vIElmIHRoZSB2YWx1ZSBkb2VzIG5vdCBjb3JyZXNwb25kIHRvIGEga25vd24gZW51bSB2YWx1ZSwgZWl0aGVyIGJlaGF2aW9yIGlzCisgIC8vIHVuZGVmaW5lZCAoZm9yIHByb3RvMiBtZXNzYWdlcyksIG9yIHRoZSB2YWx1ZSBpcyBhY2NlcHRlZCBzaWxlbnRseSBmb3IKKyAgLy8gbWVzc2FnZXMgd2l0aCBuZXcgdW5rbm93bi1lbnVtLXZhbHVlIHNlbWFudGljcy4KKyAgdmlydHVhbCB2b2lkIFNldEVudW1WYWx1ZShNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHZhbHVlKSBjb25zdDsKKworICAvLyBHZXQgYSBtdXRhYmxlIHBvaW50ZXIgdG8gYSBmaWVsZCB3aXRoIGEgbWVzc2FnZSB0eXBlLiAgSWYgYSBNZXNzYWdlRmFjdG9yeQorICAvLyBpcyBwcm92aWRlZCwgaXQgd2lsbCBiZSB1c2VkIHRvIGNvbnN0cnVjdCBpbnN0YW5jZXMgb2YgdGhlIHN1Yi1tZXNzYWdlOworICAvLyBvdGhlcndpc2UsIHRoZSBkZWZhdWx0IGZhY3RvcnkgaXMgdXNlZC4gIElmIHRoZSBmaWVsZCBpcyBhbiBleHRlbnNpb24gdGhhdAorICAvLyBkb2VzIG5vdCBsaXZlIGluIHRoZSBzYW1lIHBvb2wgYXMgdGhlIGNvbnRhaW5pbmcgbWVzc2FnZSdzIGRlc2NyaXB0b3IgKGUuZy4KKyAgLy8gaXQgbGl2ZXMgaW4gYW4gb3ZlcmxheSBwb29sKSwgdGhlbiBhIE1lc3NhZ2VGYWN0b3J5IG11c3QgYmUgcHJvdmlkZWQuCisgIC8vIElmIHlvdSBoYXZlIG5vIGlkZWEgd2hhdCB0aGF0IG1lYW50LCB0aGVuIHlvdSBwcm9iYWJseSBkb24ndCBuZWVkIHRvIHdvcnJ5CisgIC8vIGFib3V0IGl0IChkb24ndCBwcm92aWRlIGEgTWVzc2FnZUZhY3RvcnkpLiAgV0FSTklORzogIElmIHRoZQorICAvLyBGaWVsZERlc2NyaXB0b3IgaXMgZm9yIGEgY29tcGlsZWQtaW4gZXh0ZW5zaW9uLCB0aGVuCisgIC8vIGZhY3RvcnktPkdldFByb3RvdHlwZShmaWVsZC0+bWVzc2FnZV90eXBlKCkgTVVTVCByZXR1cm4gYW4gaW5zdGFuY2Ugb2YgdGhlCisgIC8vIGNvbXBpbGVkLWluIGNsYXNzIGZvciB0aGlzIHR5cGUsIE5PVCBEeW5hbWljTWVzc2FnZS4KKyAgdmlydHVhbCBNZXNzYWdlKiBNdXRhYmxlTWVzc2FnZShNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUZhY3RvcnkqIGZhY3RvcnkgPSBOVUxMKSBjb25zdCA9IDA7CisgIC8vIFJlcGxhY2VzIHRoZSBtZXNzYWdlIHNwZWNpZmllZCBieSAnZmllbGQnIHdpdGggdGhlIGFscmVhZHktYWxsb2NhdGVkIG9iamVjdAorICAvLyBzdWJfbWVzc2FnZSwgcGFzc2luZyBvd25lcnNoaXAgdG8gdGhlIG1lc3NhZ2UuICBJZiB0aGUgZmllbGQgY29udGFpbmVkIGEKKyAgLy8gbWVzc2FnZSwgdGhhdCBtZXNzYWdlIGlzIGRlbGV0ZWQuICBJZiBzdWJfbWVzc2FnZSBpcyBOVUxMLCB0aGUgZmllbGQgaXMKKyAgLy8gY2xlYXJlZC4KKyAgdmlydHVhbCB2b2lkIFNldEFsbG9jYXRlZE1lc3NhZ2UoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZSogc3ViX21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0ID0gMDsKKyAgLy8gUmVsZWFzZXMgdGhlIG1lc3NhZ2Ugc3BlY2lmaWVkIGJ5ICdmaWVsZCcgYW5kIHJldHVybnMgdGhlIHBvaW50ZXIsCisgIC8vIFJlbGVhc2VNZXNzYWdlKCkgd2lsbCByZXR1cm4gdGhlIG1lc3NhZ2UgdGhlIG1lc3NhZ2Ugb2JqZWN0IGlmIGl0IGV4aXN0cy4KKyAgLy8gT3RoZXJ3aXNlLCBpdCBtYXkgb3IgbWF5IG5vdCByZXR1cm4gTlVMTC4gIEluIGFueSBjYXNlLCBpZiB0aGUgcmV0dXJuIHZhbHVlCisgIC8vIGlzIG5vbi1OVUxMLCB0aGUgY2FsbGVyIHRha2VzIG93bmVyc2hpcCBvZiB0aGUgcG9pbnRlci4KKyAgLy8gSWYgdGhlIGZpZWxkIGV4aXN0ZWQgKEhhc0ZpZWxkKCkgaXMgdHJ1ZSksIHRoZW4gdGhlIHJldHVybmVkIHBvaW50ZXIgd2lsbAorICAvLyBiZSB0aGUgc2FtZSBhcyB0aGUgcG9pbnRlciByZXR1cm5lZCBieSBNdXRhYmxlTWVzc2FnZSgpLgorICAvLyBUaGlzIGZ1bmN0aW9uIGhhcyB0aGUgc2FtZSBlZmZlY3QgYXMgQ2xlYXJGaWVsZCgpLgorICB2aXJ0dWFsIE1lc3NhZ2UqIFJlbGVhc2VNZXNzYWdlKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlRmFjdG9yeSogZmFjdG9yeSA9IE5VTEwpIGNvbnN0ID0gMDsKKworCisgIC8vIFJlcGVhdGVkIGZpZWxkIGdldHRlcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8vIFRoZXNlIGdldCB0aGUgdmFsdWUgb2Ygb25lIGVsZW1lbnQgb2YgYSByZXBlYXRlZCBmaWVsZC4KKworICB2aXJ0dWFsIGludDMyICBHZXRSZXBlYXRlZEludDMyIChjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXgpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCBpbnQ2NCAgR2V0UmVwZWF0ZWRJbnQ2NCAoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGluZGV4KSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdWludDMyIEdldFJlcGVhdGVkVUludDMyKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCkgY29uc3QgPSAwOworICB2aXJ0dWFsIHVpbnQ2NCBHZXRSZXBlYXRlZFVJbnQ2NChjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXgpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCBmbG9hdCAgR2V0UmVwZWF0ZWRGbG9hdCAoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGluZGV4KSBjb25zdCA9IDA7CisgIHZpcnR1YWwgZG91YmxlIEdldFJlcGVhdGVkRG91YmxlKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCkgY29uc3QgPSAwOworICB2aXJ0dWFsIGJvb2wgICBHZXRSZXBlYXRlZEJvb2wgIChjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXgpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCBzdHJpbmcgR2V0UmVwZWF0ZWRTdHJpbmcoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGluZGV4KSBjb25zdCA9IDA7CisgIHZpcnR1YWwgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogR2V0UmVwZWF0ZWRFbnVtKAorICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGludCBpbmRleCkgY29uc3QgPSAwOworICAvLyBHZXRSZXBlYXRlZEVudW1WYWx1ZSgpIHJldHVybnMgYW4gZW51bSBmaWVsZCdzIHZhbHVlIGFzIGFuIGludGVnZXIgcmF0aGVyCisgIC8vIHRoYW4gYW4gRW51bVZhbHVlRGVzY3JpcHRvciouIElmIHRoZSBpbnRlZ2VyIHZhbHVlIGRvZXMgbm90IGNvcnJlc3BvbmQgdG8gYQorICAvLyBrbm93biB2YWx1ZSBkZXNjcmlwdG9yLCBhIG5ldyB2YWx1ZSBkZXNjcmlwdG9yIGlzIGNyZWF0ZWQuIChTdWNoIGEgdmFsdWUKKyAgLy8gd2lsbCBvbmx5IGJlIHByZXNlbnQgd2hlbiB0aGUgbmV3IHVua25vd24tZW51bS12YWx1ZSBzZW1hbnRpY3MgYXJlIGVuYWJsZWQKKyAgLy8gZm9yIGEgbWVzc2FnZS4pCisgIHZpcnR1YWwgaW50IEdldFJlcGVhdGVkRW51bVZhbHVlKAorICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGludCBpbmRleCkgY29uc3Q7CisgIHZpcnR1YWwgY29uc3QgTWVzc2FnZSYgR2V0UmVwZWF0ZWRNZXNzYWdlKAorICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGludCBpbmRleCkgY29uc3QgPSAwOworCisgIC8vIFNlZSBHZXRTdHJpbmdSZWZlcmVuY2UoKSwgYWJvdmUuCisgIHZpcnR1YWwgY29uc3Qgc3RyaW5nJiBHZXRSZXBlYXRlZFN0cmluZ1JlZmVyZW5jZSgKKyAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICBpbnQgaW5kZXgsIHN0cmluZyogc2NyYXRjaCkgY29uc3QgPSAwOworCisKKyAgLy8gUmVwZWF0ZWQgZmllbGQgbXV0YXRvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgLy8gVGhlc2UgbXV0YXRlIHRoZSB2YWx1ZSBvZiBvbmUgZWxlbWVudCBvZiBhIHJlcGVhdGVkIGZpZWxkLgorCisgIHZpcnR1YWwgdm9pZCBTZXRSZXBlYXRlZEludDMyIChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCwgaW50MzIgIHZhbHVlKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBTZXRSZXBlYXRlZEludDY0IChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCwgaW50NjQgIHZhbHVlKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBTZXRSZXBlYXRlZFVJbnQzMihNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCwgdWludDMyIHZhbHVlKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBTZXRSZXBlYXRlZFVJbnQ2NChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCwgdWludDY0IHZhbHVlKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBTZXRSZXBlYXRlZEZsb2F0IChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCwgZmxvYXQgIHZhbHVlKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBTZXRSZXBlYXRlZERvdWJsZShNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCwgZG91YmxlIHZhbHVlKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBTZXRSZXBlYXRlZEJvb2wgIChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCwgYm9vbCAgIHZhbHVlKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBTZXRSZXBlYXRlZFN0cmluZyhNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCwgY29uc3Qgc3RyaW5nJiB2YWx1ZSkgY29uc3QgPSAwOworICB2aXJ0dWFsIHZvaWQgU2V0UmVwZWF0ZWRFbnVtKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50IGluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIHZhbHVlKSBjb25zdCA9IDA7CisgIC8vIFNldCBhbiBlbnVtIGZpZWxkJ3MgdmFsdWUgd2l0aCBhbiBpbnRlZ2VyIHJhdGhlciB0aGFuIEVudW1WYWx1ZURlc2NyaXB0b3IuCisgIC8vIElmIHRoZSB2YWx1ZSBkb2VzIG5vdCBjb3JyZXNwb25kIHRvIGEga25vd24gZW51bSB2YWx1ZSwgZWl0aGVyIGJlaGF2aW9yIGlzCisgIC8vIHVuZGVmaW5lZCAoZm9yIHByb3RvMiBtZXNzYWdlcyksIG9yIHRoZSB2YWx1ZSBpcyBhY2NlcHRlZCBzaWxlbnRseSBmb3IKKyAgLy8gbWVzc2FnZXMgd2l0aCBuZXcgdW5rbm93bi1lbnVtLXZhbHVlIHNlbWFudGljcy4KKyAgdmlydHVhbCB2b2lkIFNldFJlcGVhdGVkRW51bVZhbHVlKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBpbnQgaW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgdmFsdWUpIGNvbnN0OworICAvLyBHZXQgYSBtdXRhYmxlIHBvaW50ZXIgdG8gYW4gZWxlbWVudCBvZiBhIHJlcGVhdGVkIGZpZWxkIHdpdGggYSBtZXNzYWdlCisgIC8vIHR5cGUuCisgIHZpcnR1YWwgTWVzc2FnZSogTXV0YWJsZVJlcGVhdGVkTWVzc2FnZSgKKyAgICAgIE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGludCBpbmRleCkgY29uc3QgPSAwOworCisKKyAgLy8gUmVwZWF0ZWQgZmllbGQgYWRkZXJzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgLy8gVGhlc2UgYWRkIGFuIGVsZW1lbnQgdG8gYSByZXBlYXRlZCBmaWVsZC4KKworICB2aXJ0dWFsIHZvaWQgQWRkSW50MzIgKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50MzIgIHZhbHVlKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBBZGRJbnQ2NCAoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBpbnQ2NCAgdmFsdWUpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCB2b2lkIEFkZFVJbnQzMihNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIHVpbnQzMiB2YWx1ZSkgY29uc3QgPSAwOworICB2aXJ0dWFsIHZvaWQgQWRkVUludDY0KE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgdWludDY0IHZhbHVlKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBBZGRGbG9hdCAoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBmbG9hdCAgdmFsdWUpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCB2b2lkIEFkZERvdWJsZShNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGRvdWJsZSB2YWx1ZSkgY29uc3QgPSAwOworICB2aXJ0dWFsIHZvaWQgQWRkQm9vbCAgKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgYm9vbCAgIHZhbHVlKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBBZGRTdHJpbmcoTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgdmFsdWUpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCB2b2lkIEFkZEVudW0gIChNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogdmFsdWUpIGNvbnN0ID0gMDsKKyAgLy8gU2V0IGFuIGVudW0gZmllbGQncyB2YWx1ZSB3aXRoIGFuIGludGVnZXIgcmF0aGVyIHRoYW4gRW51bVZhbHVlRGVzY3JpcHRvci4KKyAgLy8gSWYgdGhlIHZhbHVlIGRvZXMgbm90IGNvcnJlc3BvbmQgdG8gYSBrbm93biBlbnVtIHZhbHVlLCBlaXRoZXIgYmVoYXZpb3IgaXMKKyAgLy8gdW5kZWZpbmVkIChmb3IgcHJvdG8yIG1lc3NhZ2VzKSwgb3IgdGhlIHZhbHVlIGlzIGFjY2VwdGVkIHNpbGVudGx5IGZvcgorICAvLyBtZXNzYWdlcyB3aXRoIG5ldyB1bmtub3duLWVudW0tdmFsdWUgc2VtYW50aWNzLgorICB2aXJ0dWFsIHZvaWQgQWRkRW51bVZhbHVlKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgdmFsdWUpIGNvbnN0OworICAvLyBTZWUgTXV0YWJsZU1lc3NhZ2UoKSBmb3IgY29tbWVudHMgb24gdGhlICJmYWN0b3J5IiBwYXJhbWV0ZXIuCisgIHZpcnR1YWwgTWVzc2FnZSogQWRkTWVzc2FnZShNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VGYWN0b3J5KiBmYWN0b3J5ID0gTlVMTCkgY29uc3QgPSAwOworCisgIC8vIEFwcGVuZHMgYW4gYWxyZWFkeS1hbGxvY2F0ZWQgb2JqZWN0ICduZXdfZW50cnknIHRvIHRoZSByZXBlYXRlZCBmaWVsZAorICAvLyBzcGVjaWZ5ZWQgYnkgJ2ZpZWxkJyBwYXNzaW5nIG93bmVyc2hpcCB0byB0aGUgbWVzc2FnZS4KKyAgLy8gVE9ETyh0bWFyZWspOiBNYWtlIHZpcnR1YWwgYWZ0ZXIgYWxsIHN1YmNsYXNzZXMgaGF2ZSBiZWVuCisgIC8vIHVwZGF0ZWQuCisgIHZpcnR1YWwgdm9pZCBBZGRBbGxvY2F0ZWRNZXNzYWdlKE1lc3NhZ2UqIC8qIG1lc3NhZ2UgKi8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogLypmaWVsZCAqLywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZSogLyogbmV3X2VudHJ5ICovKSBjb25zdCB7fQorCisKKyAgLy8gR2V0IGEgUmVwZWF0ZWRGaWVsZFJlZiBvYmplY3QgdGhhdCBjYW4gYmUgdXNlZCB0byByZWFkIHRoZSB1bmRlcmx5aW5nCisgIC8vIHJlcGVhdGVkIGZpZWxkLiBUaGUgdHlwZSBwYXJhbWV0ZXIgVCBtdXN0IGJlIHNldCBhY2NvcmRpbmcgdG8gdGhlCisgIC8vIGZpZWxkJ3MgY3BwIHR5cGUuIFRoZSBmb2xsb3dpbmcgdGFibGUgc2hvd3MgdGhlIG1hcHBpbmcgZnJvbSBjcHAgdHlwZQorICAvLyB0byBhY2NlcHRhYmxlIFQuCisgIC8vCisgIC8vICAgZmllbGQtPmNwcF90eXBlKCkgICAgICBUCisgIC8vICAgQ1BQVFlQRV9JTlQzMiAgICAgICAgaW50MzIKKyAgLy8gICBDUFBUWVBFX1VJTlQzMiAgICAgICB1aW50MzIKKyAgLy8gICBDUFBUWVBFX0lOVDY0ICAgICAgICBpbnQ2NAorICAvLyAgIENQUFRZUEVfVUlOVDY0ICAgICAgIHVpbnQ2NAorICAvLyAgIENQUFRZUEVfRE9VQkxFICAgICAgIGRvdWJsZQorICAvLyAgIENQUFRZUEVfRkxPQVQgICAgICAgIGZsb2F0CisgIC8vICAgQ1BQVFlQRV9CT09MICAgICAgICAgYm9vbAorICAvLyAgIENQUFRZUEVfRU5VTSAgICAgICAgIGdlbmVyYXRlZCBlbnVtIHR5cGUgb3IgaW50MzIKKyAgLy8gICBDUFBUWVBFX1NUUklORyAgICAgICBzdHJpbmcKKyAgLy8gICBDUFBUWVBFX01FU1NBR0UgICAgICBnZW5lcmF0ZWQgbWVzc2FnZSB0eXBlIG9yIGdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UKKyAgLy8KKyAgLy8gQSBSZXBlYXRlZEZpZWxkUmVmIG9iamVjdCBjYW4gYmUgY29waWVkIGFuZCB0aGUgcmVzdWx0ZWQgb2JqZWN0IHdpbGwgcG9pbnQKKyAgLy8gdG8gdGhlIHNhbWUgcmVwZWF0ZWQgZmllbGQgaW4gdGhlIHNhbWUgbWVzc2FnZS4gVGhlIG9iamVjdCBjYW4gYmUgdXNlZCBhcworICAvLyBsb25nIGFzIHRoZSBtZXNzYWdlIGlzIG5vdCBkZXN0cm95ZWQuCisgIC8vCisgIC8vIE5vdGUgdGhhdCB0byB1c2UgdGhpcyBtZXRob2QgdXNlcnMgbmVlZCB0byBpbmNsdWRlIHRoZSBoZWFkZXIgZmlsZQorICAvLyAiZ29vZ2xlL3Byb3RvYnVmL3JlZmxlY3Rpb24uaCIgKHdoaWNoIGRlZmluZXMgdGhlIFJlcGVhdGVkRmllbGRSZWYKKyAgLy8gY2xhc3MgdGVtcGxhdGVzKS4KKyAgdGVtcGxhdGU8dHlwZW5hbWUgVD4KKyAgUmVwZWF0ZWRGaWVsZFJlZjxUPiBHZXRSZXBlYXRlZEZpZWxkUmVmKAorICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3Q7CisKKyAgLy8gTGlrZSBHZXRSZXBlYXRlZEZpZWxkUmVmKCkgYnV0IHJldHVybiBhbiBvYmplY3QgdGhhdCBjYW4gYWxzbyBiZSB1c2VkCisgIC8vIG1hbmlwdWxhdGUgdGhlIHVuZGVybHlpbmcgcmVwZWF0ZWQgZmllbGQuCisgIHRlbXBsYXRlPHR5cGVuYW1lIFQ+CisgIE11dGFibGVSZXBlYXRlZEZpZWxkUmVmPFQ+IEdldE11dGFibGVSZXBlYXRlZEZpZWxkUmVmKAorICAgICAgTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3Q7CisKKyAgLy8gREVQUkVDQVRFRC4gUGxlYXNlIHVzZSBHZXQoTXV0YWJsZSlSZXBlYXRlZEZpZWxkUmVmKCkgZm9yIHJlcGVhdGVkIGZpZWxkCisgIC8vIGFjY2Vzcy4gVGhlIGZvbGxvd2luZyByZXBlYXRlZCBmaWVsZCBhY2Nlc29ycyB3aWxsIGJlIHJlbW92ZWQgaW4gdGhlCisgIC8vIGZ1dHVyZS4KKyAgLy8KKyAgLy8gUmVwZWF0ZWQgZmllbGQgYWNjZXNzb3JzICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8vIFRoZSBtZXRob2RzIGFib3ZlLCBlLmcuIEdldFJlcGVhdGVkSW50MzIobXNnLCBmZCwgaW5kZXgpLCBwcm92aWRlIHNpbmd1bGFyCisgIC8vIGFjY2VzcyB0byB0aGUgZGF0YSBpbiBhIFJlcGVhdGVkRmllbGQuICBUaGUgbWV0aG9kcyBiZWxvdyBwcm92aWRlIGFnZ3JlZ2F0ZQorICAvLyBhY2Nlc3MgYnkgZXhwb3NpbmcgdGhlIFJlcGVhdGVkRmllbGQgb2JqZWN0IGl0c2VsZiB3aXRoIHRoZSBNZXNzYWdlLgorICAvLyBBcHBseWluZyB0aGVzZSB0ZW1wbGF0ZXMgdG8gaW5hcHByb3ByaWF0ZSB0eXBlcyB3aWxsIGxlYWQgdG8gYW4gdW5kZWZpbmVkCisgIC8vIHJlZmVyZW5jZSBhdCBsaW5rIHRpbWUgKGUuZy4gR2V0UmVwZWF0ZWRGaWVsZDwqKipkb3VibGU+KSwgb3IgcG9zc2libHkgYQorICAvLyB0ZW1wbGF0ZSBtYXRjaGluZyBlcnJvciBhdCBjb21waWxlIHRpbWUgKGUuZy4gR2V0UmVwZWF0ZWRQdHJGaWVsZDxGaWxlPikuCisgIC8vCisgIC8vIFVzYWdlIGV4YW1wbGU6IG15X2RvdWJzID0gcmVmbC0+R2V0UmVwZWF0ZWRGaWVsZDxkb3VibGU+KG1zZywgZmQpOworCisgIC8vIERFUFJFQ0FURUQuIFBsZWFzZSB1c2UgR2V0UmVwZWF0ZWRGaWVsZFJlZigpLgorICAvLworICAvLyBmb3IgVCA9IENvcmQgYW5kIGFsbCBwcm90b2J1ZiBzY2FsYXIgdHlwZXMgZXhjZXB0IGVudW1zLgorICB0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorICBjb25zdCBSZXBlYXRlZEZpZWxkPFQ+JiBHZXRSZXBlYXRlZEZpZWxkKAorICAgICAgY29uc3QgTWVzc2FnZSYsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciopIGNvbnN0OworCisgIC8vIERFUFJFQ0FURUQuIFBsZWFzZSB1c2UgR2V0TXV0YWJsZVJlcGVhdGVkRmllbGRSZWYoKS4KKyAgLy8KKyAgLy8gZm9yIFQgPSBDb3JkIGFuZCBhbGwgcHJvdG9idWYgc2NhbGFyIHR5cGVzIGV4Y2VwdCBlbnVtcy4KKyAgdGVtcGxhdGU8dHlwZW5hbWUgVD4KKyAgUmVwZWF0ZWRGaWVsZDxUPiogTXV0YWJsZVJlcGVhdGVkRmllbGQoCisgICAgICBNZXNzYWdlKiwgY29uc3QgRmllbGREZXNjcmlwdG9yKikgY29uc3Q7CisKKyAgLy8gREVQUkVDQVRFRC4gUGxlYXNlIHVzZSBHZXRSZXBlYXRlZEZpZWxkUmVmKCkuCisgIC8vCisgIC8vIGZvciBUID0gc3RyaW5nLCBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6U3RyaW5nUGllY2VGaWVsZAorICAvLyAgICAgICAgIGdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UgJiBkZXNjZW5kYW50cy4KKyAgdGVtcGxhdGU8dHlwZW5hbWUgVD4KKyAgY29uc3QgUmVwZWF0ZWRQdHJGaWVsZDxUPiYgR2V0UmVwZWF0ZWRQdHJGaWVsZCgKKyAgICAgIGNvbnN0IE1lc3NhZ2UmLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqKSBjb25zdDsKKworICAvLyBERVBSRUNBVEVELiBQbGVhc2UgdXNlIEdldE11dGFibGVSZXBlYXRlZEZpZWxkUmVmKCkuCisgIC8vCisgIC8vIGZvciBUID0gc3RyaW5nLCBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6U3RyaW5nUGllY2VGaWVsZAorICAvLyAgICAgICAgIGdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UgJiBkZXNjZW5kYW50cy4KKyAgdGVtcGxhdGU8dHlwZW5hbWUgVD4KKyAgUmVwZWF0ZWRQdHJGaWVsZDxUPiogTXV0YWJsZVJlcGVhdGVkUHRyRmllbGQoCisgICAgICBNZXNzYWdlKiwgY29uc3QgRmllbGREZXNjcmlwdG9yKikgY29uc3Q7CisKKyAgLy8gRXh0ZW5zaW9ucyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gVHJ5IHRvIGZpbmQgYW4gZXh0ZW5zaW9uIG9mIHRoaXMgbWVzc2FnZSB0eXBlIGJ5IGZ1bGx5LXF1YWxpZmllZCBmaWVsZAorICAvLyBuYW1lLiAgUmV0dXJucyBOVUxMIGlmIG5vIGV4dGVuc2lvbiBpcyBrbm93biBmb3IgdGhpcyBuYW1lIG9yIG51bWJlci4KKyAgdmlydHVhbCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIEZpbmRLbm93bkV4dGVuc2lvbkJ5TmFtZSgKKyAgICAgIGNvbnN0IHN0cmluZyYgbmFtZSkgY29uc3QgPSAwOworCisgIC8vIFRyeSB0byBmaW5kIGFuIGV4dGVuc2lvbiBvZiB0aGlzIG1lc3NhZ2UgdHlwZSBieSBmaWVsZCBudW1iZXIuCisgIC8vIFJldHVybnMgTlVMTCBpZiBubyBleHRlbnNpb24gaXMga25vd24gZm9yIHRoaXMgbmFtZSBvciBudW1iZXIuCisgIHZpcnR1YWwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBGaW5kS25vd25FeHRlbnNpb25CeU51bWJlcigKKyAgICAgIGludCBudW1iZXIpIGNvbnN0ID0gMDsKKworICAvLyBGZWF0dXJlIEZsYWdzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBEb2VzIHRoaXMgbWVzc2FnZSBzdXBwb3J0IHN0b3JpbmcgYXJiaXRyYXJ5IGludGVnZXIgdmFsdWVzIGluIGVudW0gZmllbGRzPworICAvLyBJZiB8dHJ1ZXwsIEdldEVudW1WYWx1ZS9TZXRFbnVtVmFsdWUgYW5kIGFzc29jaWF0ZWQgcmVwZWF0ZWQtZmllbGQgdmVyc2lvbnMKKyAgLy8gdGFrZSBhcmJpdHJhcnkgaW50ZWdlciB2YWx1ZXMsIGFuZCB0aGUgbGVnYWN5IEdldEVudW0oKSBnZXR0ZXIgd2lsbAorICAvLyBkeW5hbWljYWxseSBjcmVhdGUgYW4gRW51bVZhbHVlRGVzY3JpcHRvciBmb3IgYW55IGludGVnZXIgdmFsdWUgd2l0aG91dAorICAvLyBvbmUuIElmIHxmYWxzZXwsIHNldHRpbmcgYW4gdW5rbm93biBlbnVtIHZhbHVlIHZpYSB0aGUgaW50ZWdlci1iYXNlZAorICAvLyBzZXR0ZXJzIHJlc3VsdHMgaW4gdW5kZWZpbmVkIGJlaGF2aW9yIChpbiBwcmFjdGljZSwgR09PR0xFX0RDSEVDSy1mYWlscykuCisgIC8vCisgIC8vIEdlbmVyaWMgY29kZSB0aGF0IHVzZXMgcmVmbGVjdGlvbiB0byBoYW5kbGUgbWVzc2FnZXMgd2l0aCBlbnVtIGZpZWxkcworICAvLyBzaG91bGQgY2hlY2sgdGhpcyBmbGFnIGJlZm9yZSB1c2luZyB0aGUgaW50ZWdlci1iYXNlZCBzZXR0ZXIsIGFuZCBlaXRoZXIKKyAgLy8gZG93bmdyYWRlIHRvIGEgY29tcGF0aWJsZSB2YWx1ZSBvciB1c2UgdGhlIFVua25vd25GaWVsZFNldCBpZiBub3QuIEZvcgorICAvLyBleGFtcGxlOgorICAvLworICAvLyBpbnQgbmV3X3ZhbHVlID0gR2V0VmFsdWVGcm9tQXBwbGljYXRpb25Mb2dpYygpOworICAvLyBpZiAocmVmbGVjdGlvbi0+U3VwcG9ydHNVbmtub3duRW51bVZhbHVlcygpKSB7CisgIC8vICAgICByZWZsZWN0aW9uLT5TZXRFbnVtVmFsdWUobWVzc2FnZSwgZmllbGQsIG5ld192YWx1ZSk7CisgIC8vIH0gZWxzZSB7CisgIC8vICAgICBpZiAoZmllbGRfZGVzY3JpcHRvci0+ZW51bV90eXBlKCktPgorICAvLyAgICAgICAgICAgICBGaW5kVmFsdWVCeU51bXZlcihuZXdfdmFsdWUpICE9IE5VTEwpIHsKKyAgLy8gICAgICAgICByZWZsZWN0aW9uLT5TZXRFbnVtVmFsdWUobWVzc2FnZSwgZmllbGQsIG5ld192YWx1ZSk7CisgIC8vICAgICB9IGVsc2UgaWYgKGVtaXRfdW5rbm93bl9lbnVtX3ZhbHVlcykgeworICAvLyAgICAgICAgIHJlZmxlY3Rpb24tPk11dGFibGVVbmtub3duRmllbGRzKG1lc3NhZ2UpLT5BZGRWYXJpbnQoCisgIC8vICAgICAgICAgICAgIGZpZWxkLT5udW1iZXIoKSwKKyAgLy8gICAgICAgICAgICAgbmV3X3ZhbHVlKTsKKyAgLy8gICAgIH0gZWxzZSB7CisgIC8vICAgICAgICAgLy8gY29udmVydCB2YWx1ZSB0byBhIGNvbXBhdGlibGUvZGVmYXVsdCB2YWx1ZS4KKyAgLy8gICAgICAgICBuZXdfdmFsdWUgPSBDb21wYXRpYmxlRG93bmdyYWRlKG5ld192YWx1ZSk7CisgIC8vICAgICAgICAgcmVmbGVjdGlvbi0+U2V0RW51bVZhbHVlKG1lc3NhZ2UsIGZpZWxkLCBuZXdfdmFsdWUpOworICAvLyAgICAgfQorICAvLyB9CisgIHZpcnR1YWwgYm9vbCBTdXBwb3J0c1Vua25vd25FbnVtVmFsdWVzKCkgY29uc3QgeyByZXR1cm4gZmFsc2U7IH0KKworICAvLyBSZXR1cm5zIHRoZSBNZXNzYWdlRmFjdG9yeSBhc3NvY2lhdGVkIHdpdGggdGhpcyBtZXNzYWdlLiAgVGhpcyBjYW4gYmUKKyAgLy8gdXNlZnVsIGZvciBkZXRlcm1pbmluZyBpZiBhIG1lc3NhZ2UgaXMgYSBnZW5lcmF0ZWQgbWVzc2FnZSBvciBub3QsIGZvcgorICAvLyBleGFtcGxlOgorICAvLworICAvLyBpZiAobWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRNZXNzYWdlRmFjdG9yeSgpID09CisgIC8vICAgICBnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlRmFjdG9yeTo6Z2VuZXJhdGVkX2ZhY3RvcnkoKSkgeworICAvLyAgIC8vIFRoaXMgaXMgYSBnZW5lcmF0ZWQgbWVzc2FnZS4KKyAgLy8gfQorICAvLworICAvLyBJdCBjYW4gYWxzbyBiZSB1c2VkIHRvIGNyZWF0ZSBtb3JlIG1lc3NhZ2VzIG9mIHRoaXMgdHlwZSwgdGhvdWdoCisgIC8vIE1lc3NhZ2U6Ok5ldygpIGlzIGFuIGVhc2llciB3YXkgdG8gYWNjb21wbGlzaCB0aGlzLgorICB2aXJ0dWFsIE1lc3NhZ2VGYWN0b3J5KiBHZXRNZXNzYWdlRmFjdG9yeSgpIGNvbnN0OworCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgcHJvdGVjdGVkOgorICAvLyBPYnRhaW4gYSBwb2ludGVyIHRvIGEgUmVwZWF0ZWQgRmllbGQgU3RydWN0dXJlIGFuZCBkbyBzb21lIHR5cGUgY2hlY2tpbmc6CisgIC8vICAgb24gZmllbGQtPmNwcF90eXBlKCksCisgIC8vICAgb24gZmllbGQtPmZpZWxkX29wdGlvbigpLmN0eXBlKCkgKGlmIGN0eXBlID49IDApCisgIC8vICAgb2YgZmllbGQtPm1lc3NhZ2VfdHlwZSgpIChpZiBtZXNzYWdlX3R5cGUgIT0gTlVMTCkuCisgIC8vIFdlIHVzZSAyIHJvdXRpbmUgcmF0aGVyIHRoYW4gNCAoY29uc3QgdnMgbXV0YWJsZSkgeCAoc2NhbGFyIHZzIHBvaW50ZXIpLgorICB2aXJ0dWFsIHZvaWQqIE11dGFibGVSYXdSZXBlYXRlZEZpZWxkKAorICAgICAgTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgRmllbGREZXNjcmlwdG9yOjpDcHBUeXBlLAorICAgICAgaW50IGN0eXBlLCBjb25zdCBEZXNjcmlwdG9yKiBtZXNzYWdlX3R5cGUpIGNvbnN0ID0gMDsKKworICAvLyBUT0RPKGppZWx1bykgLSBtYWtlIGl0IHB1cmUgdmlydHVhbCBhZnRlciB1cGRhdGluZyBhbGwgdGhlIHN1YmNsYXNzZXMuCisgIHZpcnR1YWwgY29uc3Qgdm9pZCogR2V0UmF3UmVwZWF0ZWRGaWVsZCgKKyAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICBGaWVsZERlc2NyaXB0b3I6OkNwcFR5cGUgY3BwdHlwZSwgaW50IGN0eXBlLAorICAgICAgY29uc3QgRGVzY3JpcHRvciogbWVzc2FnZV90eXBlKSBjb25zdCB7CisgICAgcmV0dXJuIE11dGFibGVSYXdSZXBlYXRlZEZpZWxkKAorICAgICAgICBjb25zdF9jYXN0PE1lc3NhZ2UqPigmbWVzc2FnZSksIGZpZWxkLCBjcHB0eXBlLCBjdHlwZSwgbWVzc2FnZV90eXBlKTsKKyAgfQorCisgIC8vIFRoZSBmb2xsb3dpbmcgbWV0aG9kcyBhcmUgdXNlZCB0byBpbXBsZW1lbnQgKE11dGFibGUpUmVwZWF0ZWRGaWVsZFJlZi4KKyAgLy8gQSBSZWYgb2JqZWN0IHdpbGwgc3RvcmUgYSByYXcgcG9pbnRlciB0byB0aGUgcmVwZWF0ZWQgZmllbGQgZGF0YSAob2J0YWluZWQKKyAgLy8gZnJvbSBSZXBlYXRlZEZpZWxkRGF0YSgpKSBhbmQgYSBwb2ludGVyIHRvIGEgQWNjZXNzb3IgKG9idGFpbmVkIGZyb20KKyAgLy8gUmVwZWF0ZWRGaWVsZEFjY2Vzc29yKSB3aGljaCB3aWxsIGJlIHVzZWQgdG8gYWNjZXNzIHRoZSByYXcgZGF0YS4KKyAgLy8KKyAgLy8gVE9ETyh4aWFvZmVuZyk6IE1ha2UgdGhlc2UgbWV0aG9kcyBwdXJlLXZpcnR1YWwuCisKKyAgLy8gUmV0dXJucyBhIHJhdyBwb2ludGVyIHRvIHRoZSByZXBlYXRlZCBmaWVsZAorICAvLworICAvLyAiY3BwX3R5cGUiIGFuZCAibWVzc2FnZV90eXBlIiBhcmUgZGVjdWRlZCBmcm9tIHRoZSB0eXBlIHBhcmFtZXRlciBUIHBhc3NlZAorICAvLyB0byBHZXQoTXV0YWJsZSlSZXBlYXRlZEZpZWxkUmVmLiBJZiBUIGlzIGEgZ2VuZXJhdGVkIG1lc3NhZ2UgdHlwZSwKKyAgLy8gIm1lc3NhZ2VfdHlwZSIgc2hvdWxkIGJlIHNldCB0byBpdHMgZGVzY3JpcHRvci4gT3RoZXJ3aXNlICJtZXNzYWdlX3R5cGUiCisgIC8vIHNob3VsZCBiZSBzZXQgdG8gTlVMTC4gSW1wbGVtZW50YXRpb25zIG9mIHRoaXMgbWV0aG9kIHNob3VsZCBjaGVjayB3aGV0aGVyCisgIC8vICJjcHBfdHlwZSIvIm1lc3NhZ2VfdHlwZSIgaXMgY29uc2lzdGVudCB3aXRoIHRoZSBhY3R1YWwgdHlwZSBvZiB0aGUgZmllbGQuCisgIC8vIFdlIHVzZSAxIHJvdXRpbmUgcmF0aGVyIHRoYW4gMiAoY29uc3QgdnMgbXV0YWJsZSkgYmVjYXVzZSBpdCBpcyBwcm90ZWN0ZWQKKyAgLy8gYW5kIGl0IGRvZXNuJ3QgY2hhbmdlIHRoZSBtZXNzYWdlLgorICB2aXJ0dWFsIHZvaWQqIFJlcGVhdGVkRmllbGREYXRhKAorICAgICAgTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgIEZpZWxkRGVzY3JpcHRvcjo6Q3BwVHlwZSBjcHBfdHlwZSwKKyAgICAgIGNvbnN0IERlc2NyaXB0b3IqIG1lc3NhZ2VfdHlwZSkgY29uc3Q7CisKKyAgLy8gVGhlIHJldHVybmVkIHBvaW50ZXIgc2hvdWxkIHBvaW50IHRvIGEgc2luZ2xldG9uIGluc3RhbmNlIHdoaWNoIGltcGxlbWVudHMKKyAgLy8gdGhlIFJlcGVhdGVkRmllbGRBY2Nlc3NvciBpbnRlcmZhY2UuCisgIHZpcnR1YWwgY29uc3QgaW50ZXJuYWw6OlJlcGVhdGVkRmllbGRBY2Nlc3NvciogUmVwZWF0ZWRGaWVsZEFjY2Vzc29yKAorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3Q7CisKKyBwcml2YXRlOgorICB0ZW1wbGF0ZTx0eXBlbmFtZSBULCB0eXBlbmFtZSBFbmFibGU+CisgIGZyaWVuZCBjbGFzcyBSZXBlYXRlZEZpZWxkUmVmOworICB0ZW1wbGF0ZTx0eXBlbmFtZSBULCB0eXBlbmFtZSBFbmFibGU+CisgIGZyaWVuZCBjbGFzcyBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjsKKyAgZnJpZW5kIGNsYXNzIDo6Z29vZ2xlOjpwcm90b2J1Zjo6cHl0aG9uOjpNYXBSZWZsZWN0aW9uRnJpZW5kOworCisgIC8vIFNwZWNpYWwgdmVyc2lvbiBmb3Igc3BlY2lhbGl6ZWQgaW1wbGVtZW50YXRpb25zIG9mIHN0cmluZy4gIFdlIGNhbid0IGNhbGwKKyAgLy8gTXV0YWJsZVJhd1JlcGVhdGVkRmllbGQgZGlyZWN0bHkgaGVyZSBiZWNhdXNlIHdlIGRvbid0IGhhdmUgYWNjZXNzIHRvCisgIC8vIEZpZWxkT3B0aW9uczo6KiB3aGljaCBhcmUgZGVmaW5lZCBpbiBkZXNjcmlwdG9yLnBiLmguICBJbmNsdWRpbmcgdGhhdAorICAvLyBmaWxlIGhlcmUgaXMgbm90IHBvc3NpYmxlIGJlY2F1c2UgaXQgd291bGQgY2F1c2UgYSBjaXJjdWxhciBpbmNsdWRlIGN5Y2xlLgorICAvLyBXZSB1c2UgMSByb3V0aW5lIHJhdGhlciB0aGFuIDIgKGNvbnN0IHZzIG11dGFibGUpIGJlY2F1c2UgaXQgaXMgcHJpdmF0ZQorICAvLyBhbmQgbXV0YWJsZSBhIHJlcGVhdGVkIHN0cmluZyBmaWVsZCBkb2Vzbid0IGNoYW5nZSB0aGUgbWVzc2FnZS4KKyAgdm9pZCogTXV0YWJsZVJhd1JlcGVhdGVkU3RyaW5nKAorICAgICAgTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgYm9vbCBpc19zdHJpbmcpIGNvbnN0OworCisgIGZyaWVuZCBjbGFzcyBNYXBSZWZsZWN0aW9uVGVzdGVyOworICAvLyBUT0RPKGppZWx1bykgLSBtYWtlIHRoZSBtYXAgQVBJcyBwdXJlIHZpcnR1YWwgYWZ0ZXIgdXBkYXRpbmcKKyAgLy8gYWxsIHRoZSBzdWJjbGFzc2VzLgorICAvLyBSZXR1cm5zIHRydWUgaWYga2V5IGlzIGluIG1hcC4gUmV0dXJucyBmYWxzZSBpZiBrZXkgaXMgbm90IGluIG1hcCBmaWVsZC4KKyAgdmlydHVhbCBib29sIENvbnRhaW5zTWFwS2V5KGNvbnN0IE1lc3NhZ2UmIC8qIG1lc3NhZ2UqLywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogLyogZmllbGQgKi8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNYXBLZXkmIC8qIGtleSAqLykgY29uc3QgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vIElmIGtleSBpcyBpbiBtYXAgZmllbGQ6IFNhdmVzIHRoZSB2YWx1ZSBwb2ludGVyIHRvIHZhbCBhbmQgcmV0dXJucworICAvLyBmYWxzZS4gSWYga2V5IGluIG5vdCBpbiBtYXAgZmllbGQ6IEluc2VydCB0aGUga2V5IGludG8gbWFwLCBzYXZlcworICAvLyB2YWx1ZSBwb2ludGVyIHRvIHZhbCBhbmQgcmV0dW5zIHRydWUuCisgIHZpcnR1YWwgYm9vbCBJbnNlcnRPckxvb2t1cE1hcFZhbHVlKE1lc3NhZ2UqIC8qIG1lc3NhZ2UgKi8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogLyogZmllbGQgKi8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1hcEtleSYgLyoga2V5ICovLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYXBWYWx1ZVJlZiogLyogdmFsICovKSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8gRGVsZXRlIGFuZCByZXR1cm5zIHRydWUgaWYga2V5IGlzIGluIHRoZSBtYXAgZmllbGQuIFJldHVybnMgZmFsc2UKKyAgLy8gb3RoZXJ3aXNlLgorICB2aXJ0dWFsIGJvb2wgRGVsZXRlTWFwVmFsdWUoTWVzc2FnZSogLyogbWVzYWdlICovLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiAvKiBmaWVsZCAqLywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1hcEtleSYgLyoga2V5ICovKSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8gUmV0dXJucyBhIE1hcEl0ZXJhdG9yIHJlZmVycmluZyB0byB0aGUgZmlyc3QgZWxlbWVudCBpbiB0aGUgbWFwIGZpZWxkLgorICAvLyBJZiB0aGUgbWFwIGZpZWxkIGlzIGVtcHR5LCB0aGlzIGZ1bmN0aW9uIHJldHVybnMgdGhlIHNhbWUgYXMKKyAgLy8gcmVmbGVjdGlvbjo6TWFwRW5kLiBNdXRhdGlvbiB0byB0aGUgZmllbGQgbWF5IGludmFsaWRhdGUgdGhlIGl0ZXJhdG9yLgorICB2aXJ0dWFsIE1hcEl0ZXJhdG9yIE1hcEJlZ2luKAorICAgICAgTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0OworCisgIC8vIFJldHVybnMgYSBNYXBJdGVyYXRvciByZWZlcnJpbmcgdG8gdGhlIHRoZW9yZXRpY2FsIGVsZW1lbnQgdGhhdCB3b3VsZAorICAvLyBmb2xsb3cgdGhlIGxhc3QgZWxlbWVudCBpbiB0aGUgbWFwIGZpZWxkLiBJdCBkb2VzIG5vdCBwb2ludCB0byBhbnkKKyAgLy8gcmVhbCBlbGVtZW50LiBNdXRhdGlvbiB0byB0aGUgZmllbGQgbWF5IGludmFsaWRhdGUgdGhlIGl0ZXJhdG9yLgorICB2aXJ0dWFsIE1hcEl0ZXJhdG9yIE1hcEVuZCgKKyAgICAgIE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdDsKKworICAvLyBHZXQgdGhlIG51bWJlciBvZiA8a2V5LCB2YWx1ZT4gcGFpciBvZiBhIG1hcCBmaWVsZC4gVGhlIHJlc3VsdCBtYXkgYmUKKyAgLy8gZGlmZmVyZW50IGZyb20gRmllbGRTaXplIHdoaWNoIGNhbiBoYXZlIGR1cGxpY2F0ZSBrZXlzLgorICB2aXJ0dWFsIGludCBNYXBTaXplKGNvbnN0IE1lc3NhZ2UmIC8qIG1lc3NhZ2UgKi8sCisgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiAvKiBmaWVsZCAqLykgY29uc3QgeworICAgIHJldHVybiAwOworICB9CisKKyAgLy8gSGVscCBtZXRob2QgZm9yIE1hcEl0ZXJhdG9yLgorICBmcmllbmQgY2xhc3MgTWFwSXRlcmF0b3I7CisgIHZpcnR1YWwgaW50ZXJuYWw6Ok1hcEZpZWxkQmFzZSogTWFwRGF0YSgKKyAgICAgIE1lc3NhZ2UqIC8qIG1lc3NhZ2UgKi8sIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogLyogZmllbGQgKi8pIGNvbnN0IHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhSZWZsZWN0aW9uKTsKK307CisKKy8vIEFic3RyYWN0IGludGVyZmFjZSBmb3IgYSBmYWN0b3J5IGZvciBtZXNzYWdlIG9iamVjdHMuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgTWVzc2FnZUZhY3RvcnkgeworIHB1YmxpYzoKKyAgaW5saW5lIE1lc3NhZ2VGYWN0b3J5KCkge30KKyAgdmlydHVhbCB+TWVzc2FnZUZhY3RvcnkoKTsKKworICAvLyBHaXZlbiBhIERlc2NyaXB0b3IsIGdldHMgb3IgY29uc3RydWN0cyB0aGUgZGVmYXVsdCAocHJvdG90eXBlKSBNZXNzYWdlCisgIC8vIG9mIHRoYXQgdHlwZS4gIFlvdSBjYW4gdGhlbiBjYWxsIHRoYXQgbWVzc2FnZSdzIE5ldygpIG1ldGhvZCB0byBjb25zdHJ1Y3QKKyAgLy8gYSBtdXRhYmxlIG1lc3NhZ2Ugb2YgdGhhdCB0eXBlLgorICAvLworICAvLyBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIHdpdGggdGhlIHNhbWUgRGVzY3JpcHRvciByZXR1cm5zIHRoZSBzYW1lCisgIC8vIG9iamVjdC4gIFRoZSByZXR1cm5lZCBvYmplY3QgcmVtYWlucyBwcm9wZXJ0eSBvZiB0aGUgZmFjdG9yeS4gIEFsc28sIGFueQorICAvLyBvYmplY3RzIGNyZWF0ZWQgYnkgY2FsbGluZyB0aGUgcHJvdG90eXBlJ3MgTmV3KCkgbWV0aG9kIHNoYXJlIHNvbWUgZGF0YQorICAvLyB3aXRoIHRoZSBwcm90b3R5cGUsIHNvIHRoZXNlIG11c3QgYmUgZGVzdHJveWVkIGJlZm9yZSB0aGUgTWVzc2FnZUZhY3RvcnkKKyAgLy8gaXMgZGVzdHJveWVkLgorICAvLworICAvLyBUaGUgZ2l2ZW4gZGVzY3JpcHRvciBtdXN0IG91dGxpdmUgdGhlIHJldHVybmVkIG1lc3NhZ2UsIGFuZCBoZW5jZSBtdXN0CisgIC8vIG91dGxpdmUgdGhlIE1lc3NhZ2VGYWN0b3J5LgorICAvLworICAvLyBTb21lIGltcGxlbWVudGF0aW9ucyBkbyBub3Qgc3VwcG9ydCBhbGwgdHlwZXMuICBHZXRQcm90b3R5cGUoKSB3aWxsCisgIC8vIHJldHVybiBOVUxMIGlmIHRoZSBkZXNjcmlwdG9yIHBhc3NlZCBpbiBpcyBub3Qgc3VwcG9ydGVkLgorICAvLworICAvLyBUaGlzIG1ldGhvZCBtYXkgb3IgbWF5IG5vdCBiZSB0aHJlYWQtc2FmZSBkZXBlbmRpbmcgb24gdGhlIGltcGxlbWVudGF0aW9uLgorICAvLyBFYWNoIGltcGxlbWVudGF0aW9uIHNob3VsZCBkb2N1bWVudCBpdHMgb3duIGRlZ3JlZSB0aHJlYWQtc2FmZXR5LgorICB2aXJ0dWFsIGNvbnN0IE1lc3NhZ2UqIEdldFByb3RvdHlwZShjb25zdCBEZXNjcmlwdG9yKiB0eXBlKSA9IDA7CisKKyAgLy8gR2V0cyBhIE1lc3NhZ2VGYWN0b3J5IHdoaWNoIHN1cHBvcnRzIGFsbCBnZW5lcmF0ZWQsIGNvbXBpbGVkLWluIG1lc3NhZ2VzLgorICAvLyBJbiBvdGhlciB3b3JkcywgZm9yIGFueSBjb21waWxlZC1pbiB0eXBlIEZvb01lc3NhZ2UsIHRoZSBmb2xsb3dpbmcgaXMgdHJ1ZToKKyAgLy8gICBNZXNzYWdlRmFjdG9yeTo6Z2VuZXJhdGVkX2ZhY3RvcnkoKS0+R2V0UHJvdG90eXBlKAorICAvLyAgICAgRm9vTWVzc2FnZTo6ZGVzY3JpcHRvcigpKSA9PSBGb29NZXNzYWdlOjpkZWZhdWx0X2luc3RhbmNlKCkKKyAgLy8gVGhpcyBmYWN0b3J5IHN1cHBvcnRzIGFsbCB0eXBlcyB3aGljaCBhcmUgZm91bmQgaW4KKyAgLy8gRGVzY3JpcHRvclBvb2w6OmdlbmVyYXRlZF9wb29sKCkuICBJZiBnaXZlbiBhIGRlc2NyaXB0b3IgZnJvbSBhbnkgb3RoZXIKKyAgLy8gcG9vbCwgR2V0UHJvdG90eXBlKCkgd2lsbCByZXR1cm4gTlVMTC4gIChZb3UgY2FuIGFsc28gY2hlY2sgaWYgYQorICAvLyBkZXNjcmlwdG9yIGlzIGZvciBhIGdlbmVyYXRlZCBtZXNzYWdlIGJ5IGNoZWNraW5nIGlmCisgIC8vIGRlc2NyaXB0b3ItPmZpbGUoKS0+cG9vbCgpID09IERlc2NyaXB0b3JQb29sOjpnZW5lcmF0ZWRfcG9vbCgpLikKKyAgLy8KKyAgLy8gVGhpcyBmYWN0b3J5IGlzIDEwMCUgdGhyZWFkLXNhZmU7IGNhbGxpbmcgR2V0UHJvdG90eXBlKCkgZG9lcyBub3QgbW9kaWZ5CisgIC8vIGFueSBzaGFyZWQgZGF0YS4KKyAgLy8KKyAgLy8gVGhpcyBmYWN0b3J5IGlzIGEgc2luZ2xldG9uLiAgVGhlIGNhbGxlciBtdXN0IG5vdCBkZWxldGUgdGhlIG9iamVjdC4KKyAgc3RhdGljIE1lc3NhZ2VGYWN0b3J5KiBnZW5lcmF0ZWRfZmFjdG9yeSgpOworCisgIC8vIEZvciBpbnRlcm5hbCB1c2Ugb25seTogIFJlZ2lzdGVycyBhIC5wcm90byBmaWxlIGF0IHN0YXRpYyBpbml0aWFsaXphdGlvbgorICAvLyB0aW1lLCB0byBiZSBwbGFjZWQgaW4gZ2VuZXJhdGVkX2ZhY3RvcnkuICBUaGUgZmlyc3QgdGltZSBHZXRQcm90b3R5cGUoKQorICAvLyBpcyBjYWxsZWQgd2l0aCBhIGRlc2NyaXB0b3IgZnJvbSB0aGlzIGZpbGUsIHxyZWdpc3Rlcl9tZXNzYWdlc3wgd2lsbCBiZQorICAvLyBjYWxsZWQsIHdpdGggdGhlIGZpbGUgbmFtZSBhcyB0aGUgcGFyYW1ldGVyLiAgSXQgbXVzdCBjYWxsCisgIC8vIEludGVybmFsUmVnaXN0ZXJHZW5lcmF0ZWRNZXNzYWdlKCkgKGJlbG93KSB0byByZWdpc3RlciBlYWNoIG1lc3NhZ2UgdHlwZQorICAvLyBpbiB0aGUgZmlsZS4gIFRoaXMgc3RyYW5nZSBtZWNoYW5pc20gaXMgbmVjZXNzYXJ5IGJlY2F1c2UgZGVzY3JpcHRvcnMgYXJlCisgIC8vIGJ1aWx0IGxhemlseSwgc28gd2UgY2FuJ3QgcmVnaXN0ZXIgdHlwZXMgYnkgdGhlaXIgZGVzY3JpcHRvciB1bnRpbCB3ZQorICAvLyBrbm93IHRoYXQgdGhlIGRlc2NyaXB0b3IgZXhpc3RzLiAgfGZpbGVuYW1lfCBtdXN0IGJlIGEgcGVybWFuZW50IHN0cmluZy4KKyAgc3RhdGljIHZvaWQgSW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZEZpbGUoCisgICAgICBjb25zdCBjaGFyKiBmaWxlbmFtZSwgdm9pZCAoKnJlZ2lzdGVyX21lc3NhZ2VzKShjb25zdCBzdHJpbmcmKSk7CisKKyAgLy8gRm9yIGludGVybmFsIHVzZSBvbmx5OiAgUmVnaXN0ZXJzIGEgbWVzc2FnZSB0eXBlLiAgQ2FsbGVkIG9ubHkgYnkgdGhlCisgIC8vIGZ1bmN0aW9ucyB3aGljaCBhcmUgcmVnaXN0ZXJlZCB3aXRoIEludGVybmFsUmVnaXN0ZXJHZW5lcmF0ZWRGaWxlKCksCisgIC8vIGFib3ZlLgorICBzdGF0aWMgdm9pZCBJbnRlcm5hbFJlZ2lzdGVyR2VuZXJhdGVkTWVzc2FnZShjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNZXNzYWdlKiBwcm90b3R5cGUpOworCisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoTWVzc2FnZUZhY3RvcnkpOworfTsKKworI2RlZmluZSBERUNMQVJFX0dFVF9SRVBFQVRFRF9GSUVMRChUWVBFKSAgICAgICAgICAgICAgICAgICAgICAgICBcCit0ZW1wbGF0ZTw+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKK0xJQlBST1RPQlVGX0VYUE9SVCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorY29uc3QgUmVwZWF0ZWRGaWVsZDxUWVBFPiYgUmVmbGVjdGlvbjo6R2V0UmVwZWF0ZWRGaWVsZDxUWVBFPiggICBcCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3Q7IFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAordGVtcGxhdGU8PiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCitMSUJQUk9UT0JVRl9FWFBPUlQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKK1JlcGVhdGVkRmllbGQ8VFlQRT4qIFJlZmxlY3Rpb246Ok11dGFibGVSZXBlYXRlZEZpZWxkPFRZUEU+KCAgICAgXAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0OworCitERUNMQVJFX0dFVF9SRVBFQVRFRF9GSUVMRChpbnQzMikKK0RFQ0xBUkVfR0VUX1JFUEVBVEVEX0ZJRUxEKGludDY0KQorREVDTEFSRV9HRVRfUkVQRUFURURfRklFTEQodWludDMyKQorREVDTEFSRV9HRVRfUkVQRUFURURfRklFTEQodWludDY0KQorREVDTEFSRV9HRVRfUkVQRUFURURfRklFTEQoZmxvYXQpCitERUNMQVJFX0dFVF9SRVBFQVRFRF9GSUVMRChkb3VibGUpCitERUNMQVJFX0dFVF9SRVBFQVRFRF9GSUVMRChib29sKQorCisjdW5kZWYgREVDTEFSRV9HRVRfUkVQRUFURURfRklFTEQKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKy8vIEltcGxlbWVudGF0aW9uIGRldGFpbHMgZm9yIHtHZXQsTXV0YWJsZX1SYXdSZXBlYXRlZFB0ckZpZWxkLiAgV2UgcHJvdmlkZQorLy8gc3BlY2lhbGl6YXRpb25zIGZvciA8c3RyaW5nPiwgPFN0cmluZ1BpZWNlRmllbGQ+IGFuZCA8TWVzc2FnZT4gYW5kIGhhbmRsZQorLy8gZXZlcnl0aGluZyBlbHNlIHdpdGggdGhlIGRlZmF1bHQgdGVtcGxhdGUgd2hpY2ggd2lsbCBtYXRjaCBhbnkgdHlwZSBoYXZpbmcKKy8vIGEgbWV0aG9kIHdpdGggc2lnbmF0dXJlICJzdGF0aWMgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogZGVzY3JpcHRvcigpIi4KKy8vIFN1Y2ggYSB0eXBlIHByZXN1bWFibHkgaXMgYSBkZXNjZW5kYW50IG9mIGdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UuCisKK3RlbXBsYXRlPD4KK2lubGluZSBjb25zdCBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4mIFJlZmxlY3Rpb246OkdldFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPigKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7CisgIHJldHVybiAqc3RhdGljX2Nhc3Q8UmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+KiA+KAorICAgICAgTXV0YWJsZVJhd1JlcGVhdGVkU3RyaW5nKGNvbnN0X2Nhc3Q8TWVzc2FnZSo+KCZtZXNzYWdlKSwgZmllbGQsIHRydWUpKTsKK30KKwordGVtcGxhdGU8PgoraW5saW5lIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPiogUmVmbGVjdGlvbjo6TXV0YWJsZVJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPigKKyAgICBNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7CisgIHJldHVybiBzdGF0aWNfY2FzdDxSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4qID4oCisgICAgICBNdXRhYmxlUmF3UmVwZWF0ZWRTdHJpbmcobWVzc2FnZSwgZmllbGQsIHRydWUpKTsKK30KKworCisvLyAtLS0tLQorCit0ZW1wbGF0ZTw+CitpbmxpbmUgY29uc3QgUmVwZWF0ZWRQdHJGaWVsZDxNZXNzYWdlPiYgUmVmbGVjdGlvbjo6R2V0UmVwZWF0ZWRQdHJGaWVsZCgKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7CisgIHJldHVybiAqc3RhdGljX2Nhc3Q8Y29uc3QgUmVwZWF0ZWRQdHJGaWVsZDxNZXNzYWdlPiogPigKKyAgICAgIEdldFJhd1JlcGVhdGVkRmllbGQobWVzc2FnZSwgZmllbGQsIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFLAorICAgICAgICAgICAgICAgICAgICAgICAgICAtMSwgTlVMTCkpOworfQorCit0ZW1wbGF0ZTw+CitpbmxpbmUgUmVwZWF0ZWRQdHJGaWVsZDxNZXNzYWdlPiogUmVmbGVjdGlvbjo6TXV0YWJsZVJlcGVhdGVkUHRyRmllbGQoCisgICAgTWVzc2FnZSogbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3QgeworICByZXR1cm4gc3RhdGljX2Nhc3Q8UmVwZWF0ZWRQdHJGaWVsZDxNZXNzYWdlPiogPigKKyAgICAgIE11dGFibGVSYXdSZXBlYXRlZEZpZWxkKG1lc3NhZ2UsIGZpZWxkLAorICAgICAgICAgIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFLCAtMSwKKyAgICAgICAgICBOVUxMKSk7Cit9CisKK3RlbXBsYXRlPHR5cGVuYW1lIFBCPgoraW5saW5lIGNvbnN0IFJlcGVhdGVkUHRyRmllbGQ8UEI+JiBSZWZsZWN0aW9uOjpHZXRSZXBlYXRlZFB0ckZpZWxkKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0IHsKKyAgcmV0dXJuICpzdGF0aWNfY2FzdDxjb25zdCBSZXBlYXRlZFB0ckZpZWxkPFBCPiogPigKKyAgICAgIEdldFJhd1JlcGVhdGVkRmllbGQobWVzc2FnZSwgZmllbGQsIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFLAorICAgICAgICAgICAgICAgICAgICAgICAgICAtMSwgUEI6OmRlZmF1bHRfaW5zdGFuY2UoKS5HZXREZXNjcmlwdG9yKCkpKTsKK30KKwordGVtcGxhdGU8dHlwZW5hbWUgUEI+CitpbmxpbmUgUmVwZWF0ZWRQdHJGaWVsZDxQQj4qIFJlZmxlY3Rpb246Ok11dGFibGVSZXBlYXRlZFB0ckZpZWxkKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0IHsKKyAgcmV0dXJuIHN0YXRpY19jYXN0PFJlcGVhdGVkUHRyRmllbGQ8UEI+KiA+KAorICAgICAgTXV0YWJsZVJhd1JlcGVhdGVkRmllbGQobWVzc2FnZSwgZmllbGQsCisgICAgICAgICAgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UsIC0xLAorICAgICAgICAgIFBCOjpkZWZhdWx0X2luc3RhbmNlKCkuR2V0RGVzY3JpcHRvcigpKSk7Cit9Cit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfTUVTU0FHRV9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvbWVzc2FnZV9saXRlLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9tZXNzYWdlX2xpdGUuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWJkOGJjZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvbWVzc2FnZV9saXRlLmNjCkBAIC0wLDAgKzEsMzY1IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yczogd2lua0Bnb29nbGUuY29tIChXaW5rIFNhdmlsbGUpLAorLy8gICAgICAgICAga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21lc3NhZ2VfbGl0ZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9hcmVuYS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9yZXBlYXRlZF9maWVsZC5oPgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbG9nZ2luZy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbF9saXRlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0bF91dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworTWVzc2FnZUxpdGU6On5NZXNzYWdlTGl0ZSgpIHt9CisKK3N0cmluZyBNZXNzYWdlTGl0ZTo6SW5pdGlhbGl6YXRpb25FcnJvclN0cmluZygpIGNvbnN0IHsKKyAgcmV0dXJuICIoY2Fubm90IGRldGVybWluZSBtaXNzaW5nIGZpZWxkcyBmb3IgbGl0ZSBtZXNzYWdlKSI7Cit9CisKK25hbWVzcGFjZSB7CisKKy8vIFdoZW4gc2VyaWFsaXppbmcsIHdlIGZpcnN0IGNvbXB1dGUgdGhlIGJ5dGUgc2l6ZSwgdGhlbiBzZXJpYWxpemUgdGhlIG1lc3NhZ2UuCisvLyBJZiBzZXJpYWxpemF0aW9uIHByb2R1Y2VzIGEgZGlmZmVyZW50IG51bWJlciBvZiBieXRlcyB0aGFuIGV4cGVjdGVkLCB3ZQorLy8gY2FsbCB0aGlzIGZ1bmN0aW9uLCB3aGljaCBjcmFzaGVzLiAgVGhlIHByb2JsZW0gY291bGQgYmUgZHVlIHRvIGEgYnVnIGluIHRoZQorLy8gcHJvdG9idWYgaW1wbGVtZW50YXRpb24gYnV0IGlzIG1vcmUgbGlrZWx5IGNhdXNlZCBieSBjb25jdXJyZW50IG1vZGlmaWNhdGlvbgorLy8gb2YgdGhlIG1lc3NhZ2UuICBUaGlzIGZ1bmN0aW9uIGF0dGVtcHRzIHRvIGRpc3Rpbmd1aXNoIGJldHdlZW4gdGhlIHR3byBhbmQKKy8vIHByb3ZpZGUgYSB1c2VmdWwgZXJyb3IgbWVzc2FnZS4KK3ZvaWQgQnl0ZVNpemVDb25zaXN0ZW5jeUVycm9yKGludCBieXRlX3NpemVfYmVmb3JlX3NlcmlhbGl6YXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYnl0ZV9zaXplX2FmdGVyX3NlcmlhbGl6YXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYnl0ZXNfcHJvZHVjZWRfYnlfc2VyaWFsaXphdGlvbikgeworICBHT09HTEVfQ0hFQ0tfRVEoYnl0ZV9zaXplX2JlZm9yZV9zZXJpYWxpemF0aW9uLCBieXRlX3NpemVfYWZ0ZXJfc2VyaWFsaXphdGlvbikKKyAgICAgIDw8ICJQcm90b2NvbCBtZXNzYWdlIHdhcyBtb2RpZmllZCBjb25jdXJyZW50bHkgZHVyaW5nIHNlcmlhbGl6YXRpb24uIjsKKyAgR09PR0xFX0NIRUNLX0VRKGJ5dGVzX3Byb2R1Y2VkX2J5X3NlcmlhbGl6YXRpb24sIGJ5dGVfc2l6ZV9iZWZvcmVfc2VyaWFsaXphdGlvbikKKyAgICAgIDw8ICJCeXRlIHNpemUgY2FsY3VsYXRpb24gYW5kIHNlcmlhbGl6YXRpb24gd2VyZSBpbmNvbnNpc3RlbnQuICBUaGlzICIKKyAgICAgICAgICJtYXkgaW5kaWNhdGUgYSBidWcgaW4gcHJvdG9jb2wgYnVmZmVycyBvciBpdCBtYXkgYmUgY2F1c2VkIGJ5ICIKKyAgICAgICAgICJjb25jdXJyZW50IG1vZGlmaWNhdGlvbiBvZiB0aGUgbWVzc2FnZS4iOworICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiVGhpcyBzaG91bGRuJ3QgYmUgY2FsbGVkIGlmIGFsbCB0aGUgc2l6ZXMgYXJlIGVxdWFsLiI7Cit9CisKK3N0cmluZyBJbml0aWFsaXphdGlvbkVycm9yTWVzc2FnZShjb25zdCBjaGFyKiBhY3Rpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZUxpdGUmIG1lc3NhZ2UpIHsKKyAgLy8gTm90ZTogIFdlIHdhbnQgdG8gYXZvaWQgZGVwZW5kaW5nIG9uIHN0cnV0aWwgaW4gdGhlIGxpdGUgbGlicmFyeSwgb3RoZXJ3aXNlCisgIC8vICAgd2UnZCB1c2U6CisgIC8vCisgIC8vIHJldHVybiBzdHJpbmdzOjpTdWJzdGl0dXRlKAorICAvLyAgICJDYW4ndCAkMCBtZXNzYWdlIG9mIHR5cGUgXCIkMVwiIGJlY2F1c2UgaXQgaXMgbWlzc2luZyByZXF1aXJlZCAiCisgIC8vICAgImZpZWxkczogJDIiLAorICAvLyAgIGFjdGlvbiwgbWVzc2FnZS5HZXRUeXBlTmFtZSgpLAorICAvLyAgIG1lc3NhZ2UuSW5pdGlhbGl6YXRpb25FcnJvclN0cmluZygpKTsKKworICBzdHJpbmcgcmVzdWx0OworICByZXN1bHQgKz0gIkNhbid0ICI7CisgIHJlc3VsdCArPSBhY3Rpb247CisgIHJlc3VsdCArPSAiIG1lc3NhZ2Ugb2YgdHlwZSBcIiI7CisgIHJlc3VsdCArPSBtZXNzYWdlLkdldFR5cGVOYW1lKCk7CisgIHJlc3VsdCArPSAiXCIgYmVjYXVzZSBpdCBpcyBtaXNzaW5nIHJlcXVpcmVkIGZpZWxkczogIjsKKyAgcmVzdWx0ICs9IG1lc3NhZ2UuSW5pdGlhbGl6YXRpb25FcnJvclN0cmluZygpOworICByZXR1cm4gcmVzdWx0OworfQorCisvLyBTZXZlcmFsIG9mIHRoZSBQYXJzZSBtZXRob2RzIGJlbG93IGp1c3QgZG8gb25lIHRoaW5nIGFuZCB0aGVuIGNhbGwgYW5vdGhlcgorLy8gbWV0aG9kLiAgSW4gYSBuYWl2ZSBpbXBsZW1lbnRhdGlvbiwgd2UgbWlnaHQgaGF2ZSBQYXJzZUZyb21TdHJpbmcoKSBjYWxsCisvLyBQYXJzZUZyb21BcnJheSgpIHdoaWNoIHdvdWxkIGNhbGwgUGFyc2VGcm9tWmVyb0NvcHlTdHJlYW0oKSB3aGljaCB3b3VsZCBjYWxsCisvLyBQYXJzZUZyb21Db2RlZFN0cmVhbSgpIHdoaWNoIHdvdWxkIGNhbGwgTWVyZ2VGcm9tQ29kZWRTdHJlYW0oKSB3aGljaCB3b3VsZAorLy8gY2FsbCBNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oKS4gIEhvd2V2ZXIsIHdoZW4gcGFyc2luZyB2ZXJ5IHNtYWxsCisvLyBtZXNzYWdlcywgZXZlcnkgZnVuY3Rpb24gY2FsbCBpbnRyb2R1Y2VzIHNpZ25pZmljYW50IG92ZXJoZWFkLiAgVG8gYXZvaWQKKy8vIHRoaXMgd2l0aG91dCByZXByb2R1Y2luZyBjb2RlLCB3ZSB1c2UgdGhlc2UgZm9yY2VkLWlubGluZSBoZWxwZXJzLgorR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FIGJvb2wgSW5saW5lTWVyZ2VGcm9tQ29kZWRTdHJlYW0oCisgICAgaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LCBNZXNzYWdlTGl0ZSogbWVzc2FnZSk7CitHT09HTEVfQVRUUklCVVRFX0FMV0FZU19JTkxJTkUgYm9vbCBJbmxpbmVQYXJzZUZyb21Db2RlZFN0cmVhbSgKKyAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsIE1lc3NhZ2VMaXRlKiBtZXNzYWdlKTsKK0dPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORSBib29sIElubGluZVBhcnNlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsIE1lc3NhZ2VMaXRlKiBtZXNzYWdlKTsKK0dPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORSBib29sIElubGluZVBhcnNlRnJvbUFycmF5KAorICAgIGNvbnN0IHZvaWQqIGRhdGEsIGludCBzaXplLCBNZXNzYWdlTGl0ZSogbWVzc2FnZSk7CitHT09HTEVfQVRUUklCVVRFX0FMV0FZU19JTkxJTkUgYm9vbCBJbmxpbmVQYXJzZVBhcnRpYWxGcm9tQXJyYXkoCisgICAgY29uc3Qgdm9pZCogZGF0YSwgaW50IHNpemUsIE1lc3NhZ2VMaXRlKiBtZXNzYWdlKTsKKworaW5saW5lIGJvb2wgSW5saW5lTWVyZ2VGcm9tQ29kZWRTdHJlYW0oaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUxpdGUqIG1lc3NhZ2UpIHsKKyAgaWYgKCFtZXNzYWdlLT5NZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oaW5wdXQpKSByZXR1cm4gZmFsc2U7CisgIGlmICghbWVzc2FnZS0+SXNJbml0aWFsaXplZCgpKSB7CisgICAgR09PR0xFX0xPRyhFUlJPUikgPDwgSW5pdGlhbGl6YXRpb25FcnJvck1lc3NhZ2UoInBhcnNlIiwgKm1lc3NhZ2UpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICByZXR1cm4gdHJ1ZTsKK30KKworaW5saW5lIGJvb2wgSW5saW5lUGFyc2VGcm9tQ29kZWRTdHJlYW0oaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUxpdGUqIG1lc3NhZ2UpIHsKKyAgbWVzc2FnZS0+Q2xlYXIoKTsKKyAgcmV0dXJuIElubGluZU1lcmdlRnJvbUNvZGVkU3RyZWFtKGlucHV0LCBtZXNzYWdlKTsKK30KKworaW5saW5lIGJvb2wgSW5saW5lUGFyc2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlTGl0ZSogbWVzc2FnZSkgeworICBtZXNzYWdlLT5DbGVhcigpOworICByZXR1cm4gbWVzc2FnZS0+TWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKGlucHV0KTsKK30KKworaW5saW5lIGJvb2wgSW5saW5lUGFyc2VGcm9tQXJyYXkoCisgICAgY29uc3Qgdm9pZCogZGF0YSwgaW50IHNpemUsIE1lc3NhZ2VMaXRlKiBtZXNzYWdlKSB7CisgIGlvOjpDb2RlZElucHV0U3RyZWFtIGlucHV0KHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgdWludDgqPihkYXRhKSwgc2l6ZSk7CisgIHJldHVybiBJbmxpbmVQYXJzZUZyb21Db2RlZFN0cmVhbSgmaW5wdXQsIG1lc3NhZ2UpICYmCisgICAgICAgICBpbnB1dC5Db25zdW1lZEVudGlyZU1lc3NhZ2UoKTsKK30KKworaW5saW5lIGJvb2wgSW5saW5lUGFyc2VQYXJ0aWFsRnJvbUFycmF5KAorICAgIGNvbnN0IHZvaWQqIGRhdGEsIGludCBzaXplLCBNZXNzYWdlTGl0ZSogbWVzc2FnZSkgeworICBpbzo6Q29kZWRJbnB1dFN0cmVhbSBpbnB1dChyZWludGVycHJldF9jYXN0PGNvbnN0IHVpbnQ4Kj4oZGF0YSksIHNpemUpOworICByZXR1cm4gSW5saW5lUGFyc2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKCZpbnB1dCwgbWVzc2FnZSkgJiYKKyAgICAgICAgIGlucHV0LkNvbnN1bWVkRW50aXJlTWVzc2FnZSgpOworfQorCit9ICAvLyBuYW1lc3BhY2UKKworCitNZXNzYWdlTGl0ZSogTWVzc2FnZUxpdGU6Ok5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3QgeworICBNZXNzYWdlTGl0ZSogbWVzc2FnZSA9IE5ldygpOworICBpZiAoYXJlbmEgIT0gTlVMTCkgeworICAgIGFyZW5hLT5Pd24obWVzc2FnZSk7CisgIH0KKyAgcmV0dXJuIG1lc3NhZ2U7Cit9CisKK2Jvb2wgTWVzc2FnZUxpdGU6Ok1lcmdlRnJvbUNvZGVkU3RyZWFtKGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCkgeworICByZXR1cm4gSW5saW5lTWVyZ2VGcm9tQ29kZWRTdHJlYW0oaW5wdXQsIHRoaXMpOworfQorCitib29sIE1lc3NhZ2VMaXRlOjpQYXJzZUZyb21Db2RlZFN0cmVhbShpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyAgcmV0dXJuIElubGluZVBhcnNlRnJvbUNvZGVkU3RyZWFtKGlucHV0LCB0aGlzKTsKK30KKworYm9vbCBNZXNzYWdlTGl0ZTo6UGFyc2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCkgeworICByZXR1cm4gSW5saW5lUGFyc2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKGlucHV0LCB0aGlzKTsKK30KKworYm9vbCBNZXNzYWdlTGl0ZTo6UGFyc2VGcm9tWmVyb0NvcHlTdHJlYW0oaW86Olplcm9Db3B5SW5wdXRTdHJlYW0qIGlucHV0KSB7CisgIGlvOjpDb2RlZElucHV0U3RyZWFtIGRlY29kZXIoaW5wdXQpOworICByZXR1cm4gUGFyc2VGcm9tQ29kZWRTdHJlYW0oJmRlY29kZXIpICYmIGRlY29kZXIuQ29uc3VtZWRFbnRpcmVNZXNzYWdlKCk7Cit9CisKK2Jvb2wgTWVzc2FnZUxpdGU6OlBhcnNlUGFydGlhbEZyb21aZXJvQ29weVN0cmVhbSgKKyAgICBpbzo6WmVyb0NvcHlJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyAgaW86OkNvZGVkSW5wdXRTdHJlYW0gZGVjb2RlcihpbnB1dCk7CisgIHJldHVybiBQYXJzZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oJmRlY29kZXIpICYmCisgICAgICAgICBkZWNvZGVyLkNvbnN1bWVkRW50aXJlTWVzc2FnZSgpOworfQorCitib29sIE1lc3NhZ2VMaXRlOjpQYXJzZUZyb21Cb3VuZGVkWmVyb0NvcHlTdHJlYW0oCisgICAgaW86Olplcm9Db3B5SW5wdXRTdHJlYW0qIGlucHV0LCBpbnQgc2l6ZSkgeworICBpbzo6Q29kZWRJbnB1dFN0cmVhbSBkZWNvZGVyKGlucHV0KTsKKyAgZGVjb2Rlci5QdXNoTGltaXQoc2l6ZSk7CisgIHJldHVybiBQYXJzZUZyb21Db2RlZFN0cmVhbSgmZGVjb2RlcikgJiYKKyAgICAgICAgIGRlY29kZXIuQ29uc3VtZWRFbnRpcmVNZXNzYWdlKCkgJiYKKyAgICAgICAgIGRlY29kZXIuQnl0ZXNVbnRpbExpbWl0KCkgPT0gMDsKK30KKworYm9vbCBNZXNzYWdlTGl0ZTo6UGFyc2VQYXJ0aWFsRnJvbUJvdW5kZWRaZXJvQ29weVN0cmVhbSgKKyAgICBpbzo6WmVyb0NvcHlJbnB1dFN0cmVhbSogaW5wdXQsIGludCBzaXplKSB7CisgIGlvOjpDb2RlZElucHV0U3RyZWFtIGRlY29kZXIoaW5wdXQpOworICBkZWNvZGVyLlB1c2hMaW1pdChzaXplKTsKKyAgcmV0dXJuIFBhcnNlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgmZGVjb2RlcikgJiYKKyAgICAgICAgIGRlY29kZXIuQ29uc3VtZWRFbnRpcmVNZXNzYWdlKCkgJiYKKyAgICAgICAgIGRlY29kZXIuQnl0ZXNVbnRpbExpbWl0KCkgPT0gMDsKK30KKworYm9vbCBNZXNzYWdlTGl0ZTo6UGFyc2VGcm9tU3RyaW5nKGNvbnN0IHN0cmluZyYgZGF0YSkgeworICByZXR1cm4gSW5saW5lUGFyc2VGcm9tQXJyYXkoZGF0YS5kYXRhKCksIGRhdGEuc2l6ZSgpLCB0aGlzKTsKK30KKworYm9vbCBNZXNzYWdlTGl0ZTo6UGFyc2VQYXJ0aWFsRnJvbVN0cmluZyhjb25zdCBzdHJpbmcmIGRhdGEpIHsKKyAgcmV0dXJuIElubGluZVBhcnNlUGFydGlhbEZyb21BcnJheShkYXRhLmRhdGEoKSwgZGF0YS5zaXplKCksIHRoaXMpOworfQorCitib29sIE1lc3NhZ2VMaXRlOjpQYXJzZUZyb21BcnJheShjb25zdCB2b2lkKiBkYXRhLCBpbnQgc2l6ZSkgeworICByZXR1cm4gSW5saW5lUGFyc2VGcm9tQXJyYXkoZGF0YSwgc2l6ZSwgdGhpcyk7Cit9CisKK2Jvb2wgTWVzc2FnZUxpdGU6OlBhcnNlUGFydGlhbEZyb21BcnJheShjb25zdCB2b2lkKiBkYXRhLCBpbnQgc2l6ZSkgeworICByZXR1cm4gSW5saW5lUGFyc2VQYXJ0aWFsRnJvbUFycmF5KGRhdGEsIHNpemUsIHRoaXMpOworfQorCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKwordWludDgqIE1lc3NhZ2VMaXRlOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KHVpbnQ4KiB0YXJnZXQpIGNvbnN0IHsKKyAgLy8gV2Ugb25seSBvcHRpbWl6ZSB0aGlzIHdoZW4gdXNpbmcgb3B0aW1pemVfZm9yID0gU1BFRUQuICBJbiBvdGhlciBjYXNlcworICAvLyB3ZSBqdXN0IHVzZSB0aGUgQ29kZWRPdXRwdXRTdHJlYW0gcGF0aC4KKyAgaW50IHNpemUgPSBHZXRDYWNoZWRTaXplKCk7CisgIGlvOjpBcnJheU91dHB1dFN0cmVhbSBvdXQodGFyZ2V0LCBzaXplKTsKKyAgaW86OkNvZGVkT3V0cHV0U3RyZWFtIGNvZGVkX291dCgmb3V0KTsKKyAgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKCZjb2RlZF9vdXQpOworICBHT09HTEVfQ0hFQ0soIWNvZGVkX291dC5IYWRFcnJvcigpKTsKKyAgcmV0dXJuIHRhcmdldCArIHNpemU7Cit9CisKK2Jvb2wgTWVzc2FnZUxpdGU6OlNlcmlhbGl6ZVRvQ29kZWRTdHJlYW0oaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0IHsKKyAgR09PR0xFX0RDSEVDSyhJc0luaXRpYWxpemVkKCkpIDw8IEluaXRpYWxpemF0aW9uRXJyb3JNZXNzYWdlKCJzZXJpYWxpemUiLCAqdGhpcyk7CisgIHJldHVybiBTZXJpYWxpemVQYXJ0aWFsVG9Db2RlZFN0cmVhbShvdXRwdXQpOworfQorCitib29sIE1lc3NhZ2VMaXRlOjpTZXJpYWxpemVQYXJ0aWFsVG9Db2RlZFN0cmVhbSgKKyAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3QgeworICBjb25zdCBpbnQgc2l6ZSA9IEJ5dGVTaXplKCk7ICAvLyBGb3JjZSBzaXplIHRvIGJlIGNhY2hlZC4KKyAgaWYgKHNpemUgPCAwKSB7CisgICAgLy8gTWVzc2FnZXMgPjJHIGNhbm5vdCBiZSBzZXJpYWxpemVkIGR1ZSB0byBvdmVyZmxvdyBjb21wdXRpbmcgQnl0ZVNpemUuCisgICAgR09PR0xFX0xPRyhFUlJPUikgPDwgIkVycm9yIGNvbXB1dGluZyBCeXRlU2l6ZSAocG9zc2libGUgb3ZlcmZsb3c/KS4iOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIHVpbnQ4KiBidWZmZXIgPSBvdXRwdXQtPkdldERpcmVjdEJ1ZmZlckZvck5CeXRlc0FuZEFkdmFuY2Uoc2l6ZSk7CisgIGlmIChidWZmZXIgIT0gTlVMTCkgeworICAgIHVpbnQ4KiBlbmQgPSBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KGJ1ZmZlcik7CisgICAgaWYgKGVuZCAtIGJ1ZmZlciAhPSBzaXplKSB7CisgICAgICBCeXRlU2l6ZUNvbnNpc3RlbmN5RXJyb3Ioc2l6ZSwgQnl0ZVNpemUoKSwgZW5kIC0gYnVmZmVyKTsKKyAgICB9CisgICAgcmV0dXJuIHRydWU7CisgIH0gZWxzZSB7CisgICAgaW50IG9yaWdpbmFsX2J5dGVfY291bnQgPSBvdXRwdXQtPkJ5dGVDb3VudCgpOworICAgIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcyhvdXRwdXQpOworICAgIGlmIChvdXRwdXQtPkhhZEVycm9yKCkpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgaW50IGZpbmFsX2J5dGVfY291bnQgPSBvdXRwdXQtPkJ5dGVDb3VudCgpOworCisgICAgaWYgKGZpbmFsX2J5dGVfY291bnQgLSBvcmlnaW5hbF9ieXRlX2NvdW50ICE9IHNpemUpIHsKKyAgICAgIEJ5dGVTaXplQ29uc2lzdGVuY3lFcnJvcihzaXplLCBCeXRlU2l6ZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsX2J5dGVfY291bnQgLSBvcmlnaW5hbF9ieXRlX2NvdW50KTsKKyAgICB9CisKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorfQorCitib29sIE1lc3NhZ2VMaXRlOjpTZXJpYWxpemVUb1plcm9Db3B5U3RyZWFtKAorICAgIGlvOjpaZXJvQ29weU91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSBlbmNvZGVyKG91dHB1dCk7CisgIHJldHVybiBTZXJpYWxpemVUb0NvZGVkU3RyZWFtKCZlbmNvZGVyKTsKK30KKworYm9vbCBNZXNzYWdlTGl0ZTo6U2VyaWFsaXplUGFydGlhbFRvWmVyb0NvcHlTdHJlYW0oCisgICAgaW86Olplcm9Db3B5T3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0IHsKKyAgaW86OkNvZGVkT3V0cHV0U3RyZWFtIGVuY29kZXIob3V0cHV0KTsKKyAgcmV0dXJuIFNlcmlhbGl6ZVBhcnRpYWxUb0NvZGVkU3RyZWFtKCZlbmNvZGVyKTsKK30KKworYm9vbCBNZXNzYWdlTGl0ZTo6QXBwZW5kVG9TdHJpbmcoc3RyaW5nKiBvdXRwdXQpIGNvbnN0IHsKKyAgR09PR0xFX0RDSEVDSyhJc0luaXRpYWxpemVkKCkpIDw8IEluaXRpYWxpemF0aW9uRXJyb3JNZXNzYWdlKCJzZXJpYWxpemUiLCAqdGhpcyk7CisgIHJldHVybiBBcHBlbmRQYXJ0aWFsVG9TdHJpbmcob3V0cHV0KTsKK30KKworYm9vbCBNZXNzYWdlTGl0ZTo6QXBwZW5kUGFydGlhbFRvU3RyaW5nKHN0cmluZyogb3V0cHV0KSBjb25zdCB7CisgIGludCBvbGRfc2l6ZSA9IG91dHB1dC0+c2l6ZSgpOworICBpbnQgYnl0ZV9zaXplID0gQnl0ZVNpemUoKTsKKyAgaWYgKGJ5dGVfc2l6ZSA8IDApIHsKKyAgICAvLyBNZXNzYWdlcyA+MkcgY2Fubm90IGJlIHNlcmlhbGl6ZWQgZHVlIHRvIG92ZXJmbG93IGNvbXB1dGluZyBCeXRlU2l6ZS4KKyAgICBHT09HTEVfTE9HKEVSUk9SKSA8PCAiRXJyb3IgY29tcHV0aW5nIEJ5dGVTaXplIChwb3NzaWJsZSBvdmVyZmxvdz8pLiI7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgU1RMU3RyaW5nUmVzaXplVW5pbml0aWFsaXplZChvdXRwdXQsIG9sZF9zaXplICsgYnl0ZV9zaXplKTsKKyAgdWludDgqIHN0YXJ0ID0KKyAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8dWludDgqPihpbzo6bXV0YWJsZV9zdHJpbmdfZGF0YShvdXRwdXQpICsgb2xkX3NpemUpOworICB1aW50OCogZW5kID0gU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheShzdGFydCk7CisgIGlmIChlbmQgLSBzdGFydCAhPSBieXRlX3NpemUpIHsKKyAgICBCeXRlU2l6ZUNvbnNpc3RlbmN5RXJyb3IoYnl0ZV9zaXplLCBCeXRlU2l6ZSgpLCBlbmQgLSBzdGFydCk7CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgTWVzc2FnZUxpdGU6OlNlcmlhbGl6ZVRvU3RyaW5nKHN0cmluZyogb3V0cHV0KSBjb25zdCB7CisgIG91dHB1dC0+Y2xlYXIoKTsKKyAgcmV0dXJuIEFwcGVuZFRvU3RyaW5nKG91dHB1dCk7Cit9CisKK2Jvb2wgTWVzc2FnZUxpdGU6OlNlcmlhbGl6ZVBhcnRpYWxUb1N0cmluZyhzdHJpbmcqIG91dHB1dCkgY29uc3QgeworICBvdXRwdXQtPmNsZWFyKCk7CisgIHJldHVybiBBcHBlbmRQYXJ0aWFsVG9TdHJpbmcob3V0cHV0KTsKK30KKworYm9vbCBNZXNzYWdlTGl0ZTo6U2VyaWFsaXplVG9BcnJheSh2b2lkKiBkYXRhLCBpbnQgc2l6ZSkgY29uc3QgeworICBHT09HTEVfRENIRUNLKElzSW5pdGlhbGl6ZWQoKSkgPDwgSW5pdGlhbGl6YXRpb25FcnJvck1lc3NhZ2UoInNlcmlhbGl6ZSIsICp0aGlzKTsKKyAgcmV0dXJuIFNlcmlhbGl6ZVBhcnRpYWxUb0FycmF5KGRhdGEsIHNpemUpOworfQorCitib29sIE1lc3NhZ2VMaXRlOjpTZXJpYWxpemVQYXJ0aWFsVG9BcnJheSh2b2lkKiBkYXRhLCBpbnQgc2l6ZSkgY29uc3QgeworICBpbnQgYnl0ZV9zaXplID0gQnl0ZVNpemUoKTsKKyAgaWYgKHNpemUgPCBieXRlX3NpemUpIHJldHVybiBmYWxzZTsKKyAgdWludDgqIHN0YXJ0ID0gcmVpbnRlcnByZXRfY2FzdDx1aW50OCo+KGRhdGEpOworICB1aW50OCogZW5kID0gU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheShzdGFydCk7CisgIGlmIChlbmQgLSBzdGFydCAhPSBieXRlX3NpemUpIHsKKyAgICBCeXRlU2l6ZUNvbnNpc3RlbmN5RXJyb3IoYnl0ZV9zaXplLCBCeXRlU2l6ZSgpLCBlbmQgLSBzdGFydCk7CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKK3N0cmluZyBNZXNzYWdlTGl0ZTo6U2VyaWFsaXplQXNTdHJpbmcoKSBjb25zdCB7CisgIC8vIElmIHRoZSBjb21waWxlciBpbXBsZW1lbnRzIHRoZSAoTmFtZWQpIFJldHVybiBWYWx1ZSBPcHRpbWl6YXRpb24sCisgIC8vIHRoZSBsb2NhbCB2YXJpYWJsZSAnb3V0cHV0JyB3aWxsIG5vdCBhY3R1YWxseSByZXNpZGUgb24gdGhlIHN0YWNrCisgIC8vIG9mIHRoaXMgZnVuY3Rpb24sIGJ1dCB3aWxsIGJlIG92ZXJsYWlkIHdpdGggdGhlIG9iamVjdCB0aGF0IHRoZQorICAvLyBjYWxsZXIgc3VwcGxpZWQgZm9yIHRoZSByZXR1cm4gdmFsdWUgdG8gYmUgY29uc3RydWN0ZWQgaW4uCisgIHN0cmluZyBvdXRwdXQ7CisgIGlmICghQXBwZW5kVG9TdHJpbmcoJm91dHB1dCkpCisgICAgb3V0cHV0LmNsZWFyKCk7CisgIHJldHVybiBvdXRwdXQ7Cit9CisKK3N0cmluZyBNZXNzYWdlTGl0ZTo6U2VyaWFsaXplUGFydGlhbEFzU3RyaW5nKCkgY29uc3QgeworICBzdHJpbmcgb3V0cHV0OworICBpZiAoIUFwcGVuZFBhcnRpYWxUb1N0cmluZygmb3V0cHV0KSkKKyAgICBvdXRwdXQuY2xlYXIoKTsKKyAgcmV0dXJuIG91dHB1dDsKK30KKworbmFtZXNwYWNlIGludGVybmFsIHsKK3RlbXBsYXRlPD4KK01lc3NhZ2VMaXRlKiBHZW5lcmljVHlwZUhhbmRsZXI8TWVzc2FnZUxpdGU+OjpOZXdGcm9tUHJvdG90eXBlKAorICAgIGNvbnN0IE1lc3NhZ2VMaXRlKiBwcm90b3R5cGUsIGdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgeworICByZXR1cm4gcHJvdG90eXBlLT5OZXcoYXJlbmEpOworfQordGVtcGxhdGUgPD4KK3ZvaWQgR2VuZXJpY1R5cGVIYW5kbGVyPE1lc3NhZ2VMaXRlPjo6TWVyZ2UoY29uc3QgTWVzc2FnZUxpdGUmIGZyb20sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VMaXRlKiB0bykgeworICB0by0+Q2hlY2tUeXBlQW5kTWVyZ2VGcm9tKGZyb20pOworfQorfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9tZXNzYWdlX2xpdGUuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvbWVzc2FnZV9saXRlLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGMxNmY0YwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvbWVzc2FnZV9saXRlLmgKQEAgLTAsMCArMSwyNzcgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3JzOiB3aW5rQGdvb2dsZS5jb20gKFdpbmsgU2F2aWxsZSksCisvLyAgICAgICAgICBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisvLworLy8gRGVmaW5lcyBNZXNzYWdlTGl0ZSwgdGhlIGFic3RyYWN0IGludGVyZmFjZSBpbXBsZW1lbnRlZCBieSBhbGwgKGxpdGUKKy8vIGFuZCBub24tbGl0ZSkgcHJvdG9jb2wgbWVzc2FnZSBvYmplY3RzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9NRVNTQUdFX0xJVEVfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9NRVNTQUdFX0xJVEVfSF9fCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworICBjbGFzcyBBcmVuYTsKK25hbWVzcGFjZSBpbyB7CisgIGNsYXNzIENvZGVkSW5wdXRTdHJlYW07CisgIGNsYXNzIENvZGVkT3V0cHV0U3RyZWFtOworICBjbGFzcyBaZXJvQ29weUlucHV0U3RyZWFtOworICBjbGFzcyBaZXJvQ29weU91dHB1dFN0cmVhbTsKK30KKworLy8gSW50ZXJmYWNlIHRvIGxpZ2h0IHdlaWdodCBwcm90b2NvbCBtZXNzYWdlcy4KKy8vCisvLyBUaGlzIGludGVyZmFjZSBpcyBpbXBsZW1lbnRlZCBieSBhbGwgcHJvdG9jb2wgbWVzc2FnZSBvYmplY3RzLiAgTm9uLWxpdGUKKy8vIG1lc3NhZ2VzIGFkZGl0aW9uYWxseSBpbXBsZW1lbnQgdGhlIE1lc3NhZ2UgaW50ZXJmYWNlLCB3aGljaCBpcyBhCisvLyBzdWJjbGFzcyBvZiBNZXNzYWdlTGl0ZS4gIFVzZSBNZXNzYWdlTGl0ZSBpbnN0ZWFkIHdoZW4geW91IG9ubHkgbmVlZAorLy8gdGhlIHN1YnNldCBvZiBmZWF0dXJlcyB3aGljaCBpdCBzdXBwb3J0cyAtLSBuYW1lbHksIG5vdGhpbmcgdGhhdCB1c2VzCisvLyBkZXNjcmlwdG9ycyBvciByZWZsZWN0aW9uLiAgWW91IGNhbiBpbnN0cnVjdCB0aGUgcHJvdG9jb2wgY29tcGlsZXIKKy8vIHRvIGdlbmVyYXRlIGNsYXNzZXMgd2hpY2ggaW1wbGVtZW50IG9ubHkgTWVzc2FnZUxpdGUsIG5vdCB0aGUgZnVsbAorLy8gTWVzc2FnZSBpbnRlcmZhY2UsIGJ5IGFkZGluZyB0aGUgZm9sbG93aW5nIGxpbmUgdG8gdGhlIC5wcm90byBmaWxlOgorLy8KKy8vICAgb3B0aW9uIG9wdGltaXplX2ZvciA9IExJVEVfUlVOVElNRTsKKy8vCisvLyBUaGlzIGlzIHBhcnRpY3VsYXJseSB1c2VmdWwgb24gcmVzb3VyY2UtY29uc3RyYWluZWQgc3lzdGVtcyB3aGVyZQorLy8gdGhlIGZ1bGwgcHJvdG9jb2wgYnVmZmVycyBydW50aW1lIGxpYnJhcnkgaXMgdG9vIGJpZy4KKy8vCisvLyBOb3RlIHRoYXQgb24gbm9uLWNvbnN0cmFpbmVkIHN5c3RlbXMgKGUuZy4gc2VydmVycykgd2hlbiB5b3UgbmVlZAorLy8gdG8gbGluayBpbiBsb3RzIG9mIHByb3RvY29sIGRlZmluaXRpb25zLCBhIGJldHRlciB3YXkgdG8gcmVkdWNlCisvLyB0b3RhbCBjb2RlIGZvb3RwcmludCBpcyB0byB1c2Ugb3B0aW1pemVfZm9yID0gQ09ERV9TSVpFLiAgVGhpcworLy8gd2lsbCBtYWtlIHRoZSBnZW5lcmF0ZWQgY29kZSBzbWFsbGVyIHdoaWxlIHN0aWxsIHN1cHBvcnRpbmcgYWxsIHRoZQorLy8gc2FtZSBmZWF0dXJlcyAoYXQgdGhlIGV4cGVuc2Ugb2Ygc3BlZWQpLiAgb3B0aW1pemVfZm9yID0gTElURV9SVU5USU1FCisvLyBpcyBiZXN0IHdoZW4geW91IG9ubHkgaGF2ZSBhIHNtYWxsIG51bWJlciBvZiBtZXNzYWdlIHR5cGVzIGxpbmtlZAorLy8gaW50byB5b3VyIGJpbmFyeSwgaW4gd2hpY2ggY2FzZSB0aGUgc2l6ZSBvZiB0aGUgcHJvdG9jb2wgYnVmZmVycworLy8gcnVudGltZSBpdHNlbGYgaXMgdGhlIGJpZ2dlc3QgcHJvYmxlbS4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBNZXNzYWdlTGl0ZSB7CisgcHVibGljOgorICBpbmxpbmUgTWVzc2FnZUxpdGUoKSB7fQorICB2aXJ0dWFsIH5NZXNzYWdlTGl0ZSgpOworCisgIC8vIEJhc2ljIE9wZXJhdGlvbnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gR2V0IHRoZSBuYW1lIG9mIHRoaXMgbWVzc2FnZSB0eXBlLCBlLmcuICJmb28uYmFyLkJhelByb3RvIi4KKyAgdmlydHVhbCBzdHJpbmcgR2V0VHlwZU5hbWUoKSBjb25zdCA9IDA7CisKKyAgLy8gQ29uc3RydWN0IGEgbmV3IGluc3RhbmNlIG9mIHRoZSBzYW1lIHR5cGUuICBPd25lcnNoaXAgaXMgcGFzc2VkIHRvIHRoZQorICAvLyBjYWxsZXIuCisgIHZpcnR1YWwgTWVzc2FnZUxpdGUqIE5ldygpIGNvbnN0ID0gMDsKKworICAvLyBDb25zdHJ1Y3QgYSBuZXcgaW5zdGFuY2Ugb24gdGhlIGFyZW5hLiBPd25lcnNoaXAgaXMgcGFzc2VkIHRvIHRoZSBjYWxsZXIKKyAgLy8gaWYgYXJlbmEgaXMgYSBOVUxMLiBEZWZhdWx0IGltcGxlbWVudGF0aW9uIGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eS4KKyAgdmlydHVhbCBNZXNzYWdlTGl0ZSogTmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdDsKKworICAvLyBHZXQgdGhlIGFyZW5hLCBpZiBhbnksIGFzc29jaWF0ZWQgd2l0aCB0aGlzIG1lc3NhZ2UuIFZpcnR1YWwgbWV0aG9kCisgIC8vIHJlcXVpcmVkIGZvciBnZW5lcmljIG9wZXJhdGlvbnMgYnV0IG1vc3QgYXJlbmEtcmVsYXRlZCBvcGVyYXRpb25zIHNob3VsZAorICAvLyB1c2UgdGhlIEdldEFyZW5hTm9WaXJ0dWFsKCkgZ2VuZXJhdGVkLWNvZGUgbWV0aG9kLiBEZWZhdWx0IGltcGxlbWVudGF0aW9uCisgIC8vIHRvIHJlZHVjZSBjb2RlIHNpemUgYnkgYXZvaWRpbmcgdGhlIG5lZWQgZm9yIHBlci10eXBlIGltcGxlbWVudGF0aW9ucyB3aGVuCisgIC8vIHR5cGVzIGRvIG5vdCBpbXBsZW1lbnQgYXJlbmEgc3VwcG9ydC4KKyAgdmlydHVhbCA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYSgpIGNvbnN0IHsgcmV0dXJuIE5VTEw7IH0KKworICAvLyBHZXQgYSBwb2ludGVyIHRoYXQgbWF5IGJlIGVxdWFsIHRvIHRoaXMgbWVzc2FnZSdzIGFyZW5hLCBvciBtYXkgbm90IGJlLiBJZgorICAvLyB0aGUgdmFsdWUgcmV0dXJuZWQgYnkgdGhpcyBtZXRob2QgaXMgZXF1YWwgdG8gc29tZSBhcmVuYSBwb2ludGVyLCB0aGVuIHRoaXMKKyAgLy8gbWVzc2FnZSBpcyBvbiB0aGF0IGFyZW5hOyBob3dldmVyLCBpZiB0aGlzIG1lc3NhZ2UgaXMgb24gc29tZSBhcmVuYSwgdGhpcworICAvLyBtZXRob2QgbWF5IG9yIG1heSBub3QgcmV0dXJuIHRoYXQgYXJlbmEncyBwb2ludGVyLiBBcyBhIHRyYWRlb2ZmLCB0aGlzCisgIC8vIG1ldGhvZCBtYXkgYmUgbW9yZSBlZmZpY2llbnQgdGhhbiBHZXRBcmVuYSgpLiBUaGUgaW50ZW50IGlzIHRvIGFsbG93CisgIC8vIHVuZGVybHlpbmcgcmVwcmVzZW50YXRpb25zIHRoYXQgdXNlIGUuZy4gdGFnZ2VkIHBvaW50ZXJzIHRvIHNvbWV0aW1lcyBzdG9yZQorICAvLyB0aGUgYXJlbmEgcG9pbnRlciBkaXJlY3RseSwgYW5kIHNvbWV0aW1lcyBpbiBhIG1vcmUgaW5kaXJlY3Qgd2F5LCBhbmQgYWxsb3cKKyAgLy8gYSBmYXN0cGF0aCBjb21wYXJpc29uIGFnYWluc3QgdGhlIGFyZW5hIHBvaW50ZXIgd2hlbiBpdCdzIGVhc3kgdG8gb2J0YWluLgorICB2aXJ0dWFsIHZvaWQqIEdldE1heWJlQXJlbmFQb2ludGVyKCkgY29uc3QgeyByZXR1cm4gR2V0QXJlbmEoKTsgfQorCisgIC8vIENsZWFyIGFsbCBmaWVsZHMgb2YgdGhlIG1lc3NhZ2UgYW5kIHNldCB0aGVtIHRvIHRoZWlyIGRlZmF1bHQgdmFsdWVzLgorICAvLyBDbGVhcigpIGF2b2lkcyBmcmVlaW5nIG1lbW9yeSwgYXNzdW1pbmcgdGhhdCBhbnkgbWVtb3J5IGFsbG9jYXRlZAorICAvLyB0byBob2xkIHBhcnRzIG9mIHRoZSBtZXNzYWdlIHdpbGwgYmUgbmVlZGVkIGFnYWluIHRvIGhvbGQgdGhlIG5leHQKKyAgLy8gbWVzc2FnZS4gIElmIHlvdSBhY3R1YWxseSB3YW50IHRvIGZyZWUgdGhlIG1lbW9yeSB1c2VkIGJ5IGEgTWVzc2FnZSwKKyAgLy8geW91IG11c3QgZGVsZXRlIGl0LgorICB2aXJ0dWFsIHZvaWQgQ2xlYXIoKSA9IDA7CisKKyAgLy8gUXVpY2tseSBjaGVjayBpZiBhbGwgcmVxdWlyZWQgZmllbGRzIGhhdmUgdmFsdWVzIHNldC4KKyAgdmlydHVhbCBib29sIElzSW5pdGlhbGl6ZWQoKSBjb25zdCA9IDA7CisKKyAgLy8gVGhpcyBpcyBub3QgaW1wbGVtZW50ZWQgZm9yIExpdGUgbWVzc2FnZXMgLS0gaXQganVzdCByZXR1cm5zICIoY2Fubm90CisgIC8vIGRldGVybWluZSBtaXNzaW5nIGZpZWxkcyBmb3IgbGl0ZSBtZXNzYWdlKSIuICBIb3dldmVyLCBpdCBpcyBpbXBsZW1lbnRlZAorICAvLyBmb3IgZnVsbCBtZXNzYWdlcy4gIFNlZSBtZXNzYWdlLmguCisgIHZpcnR1YWwgc3RyaW5nIEluaXRpYWxpemF0aW9uRXJyb3JTdHJpbmcoKSBjb25zdDsKKworICAvLyBJZiB8b3RoZXJ8IGlzIHRoZSBleGFjdCBzYW1lIGNsYXNzIGFzIHRoaXMsIGNhbGxzIE1lcmdlRnJvbSgpLiAgT3RoZXJ3aXNlLAorICAvLyByZXN1bHRzIGFyZSB1bmRlZmluZWQgKHByb2JhYmx5IGNyYXNoKS4KKyAgdmlydHVhbCB2b2lkIENoZWNrVHlwZUFuZE1lcmdlRnJvbShjb25zdCBNZXNzYWdlTGl0ZSYgb3RoZXIpID0gMDsKKworICAvLyBQYXJzaW5nIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAvLyBNZXRob2RzIGZvciBwYXJzaW5nIGluIHByb3RvY29sIGJ1ZmZlciBmb3JtYXQuICBNb3N0IG9mIHRoZXNlIGFyZQorICAvLyBqdXN0IHNpbXBsZSB3cmFwcGVycyBhcm91bmQgTWVyZ2VGcm9tQ29kZWRTdHJlYW0oKS4gIENsZWFyKCkgd2lsbCBiZSBjYWxsZWQKKyAgLy8gYmVmb3JlIG1lcmdpbmcgdGhlIGlucHV0LgorCisgIC8vIEZpbGwgdGhlIG1lc3NhZ2Ugd2l0aCBhIHByb3RvY29sIGJ1ZmZlciBwYXJzZWQgZnJvbSB0aGUgZ2l2ZW4gaW5wdXQgc3RyZWFtLgorICAvLyBSZXR1cm5zIGZhbHNlIG9uIGEgcmVhZCBlcnJvciBvciBpZiB0aGUgaW5wdXQgaXMgaW4gdGhlIHdyb25nIGZvcm1hdC4gIEEKKyAgLy8gc3VjY2Vzc2Z1bCByZXR1cm4gZG9lcyBub3QgaW5kaWNhdGUgdGhlIGVudGlyZSBpbnB1dCBpcyBjb25zdW1lZCwgZW5zdXJlCisgIC8vIHlvdSBjYWxsIENvbnN1bWVkRW50aXJlTWVzc2FnZSgpIHRvIGNoZWNrIHRoYXQgaWYgYXBwbGljYWJsZS4KKyAgYm9vbCBQYXJzZUZyb21Db2RlZFN0cmVhbShpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpOworICAvLyBMaWtlIFBhcnNlRnJvbUNvZGVkU3RyZWFtKCksIGJ1dCBhY2NlcHRzIG1lc3NhZ2VzIHRoYXQgYXJlIG1pc3NpbmcKKyAgLy8gcmVxdWlyZWQgZmllbGRzLgorICBib29sIFBhcnNlUGFydGlhbEZyb21Db2RlZFN0cmVhbShpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpOworICAvLyBSZWFkIGEgcHJvdG9jb2wgYnVmZmVyIGZyb20gdGhlIGdpdmVuIHplcm8tY29weSBpbnB1dCBzdHJlYW0uICBJZgorICAvLyBzdWNjZXNzZnVsLCB0aGUgZW50aXJlIGlucHV0IHdpbGwgYmUgY29uc3VtZWQuCisgIGJvb2wgUGFyc2VGcm9tWmVyb0NvcHlTdHJlYW0oaW86Olplcm9Db3B5SW5wdXRTdHJlYW0qIGlucHV0KTsKKyAgLy8gTGlrZSBQYXJzZUZyb21aZXJvQ29weVN0cmVhbSgpLCBidXQgYWNjZXB0cyBtZXNzYWdlcyB0aGF0IGFyZSBtaXNzaW5nCisgIC8vIHJlcXVpcmVkIGZpZWxkcy4KKyAgYm9vbCBQYXJzZVBhcnRpYWxGcm9tWmVyb0NvcHlTdHJlYW0oaW86Olplcm9Db3B5SW5wdXRTdHJlYW0qIGlucHV0KTsKKyAgLy8gUmVhZCBhIHByb3RvY29sIGJ1ZmZlciBmcm9tIHRoZSBnaXZlbiB6ZXJvLWNvcHkgaW5wdXQgc3RyZWFtLCBleHBlY3RpbmcKKyAgLy8gdGhlIG1lc3NhZ2UgdG8gYmUgZXhhY3RseSAic2l6ZSIgYnl0ZXMgbG9uZy4gIElmIHN1Y2Nlc3NmdWwsIGV4YWN0bHkKKyAgLy8gdGhpcyBtYW55IGJ5dGVzIHdpbGwgaGF2ZSBiZWVuIGNvbnN1bWVkIGZyb20gdGhlIGlucHV0LgorICBib29sIFBhcnNlRnJvbUJvdW5kZWRaZXJvQ29weVN0cmVhbShpbzo6WmVyb0NvcHlJbnB1dFN0cmVhbSogaW5wdXQsIGludCBzaXplKTsKKyAgLy8gTGlrZSBQYXJzZUZyb21Cb3VuZGVkWmVyb0NvcHlTdHJlYW0oKSwgYnV0IGFjY2VwdHMgbWVzc2FnZXMgdGhhdCBhcmUKKyAgLy8gbWlzc2luZyByZXF1aXJlZCBmaWVsZHMuCisgIGJvb2wgUGFyc2VQYXJ0aWFsRnJvbUJvdW5kZWRaZXJvQ29weVN0cmVhbShpbzo6WmVyb0NvcHlJbnB1dFN0cmVhbSogaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgc2l6ZSk7CisgIC8vIFBhcnNlcyBhIHByb3RvY29sIGJ1ZmZlciBjb250YWluZWQgaW4gYSBzdHJpbmcuIFJldHVybnMgdHJ1ZSBvbiBzdWNjZXNzLgorICAvLyBUaGlzIGZ1bmN0aW9uIHRha2VzIGEgc3RyaW5nIGluIHRoZSAobm9uLWh1bWFuLXJlYWRhYmxlKSBiaW5hcnkgd2lyZQorICAvLyBmb3JtYXQsIG1hdGNoaW5nIHRoZSBlbmNvZGluZyBvdXRwdXQgYnkgTWVzc2FnZUxpdGU6OlNlcmlhbGl6ZVRvU3RyaW5nKCkuCisgIC8vIElmIHlvdSdkIGxpa2UgdG8gY29udmVydCBhIGh1bWFuLXJlYWRhYmxlIHN0cmluZyBpbnRvIGEgcHJvdG9jb2wgYnVmZmVyCisgIC8vIG9iamVjdCwgc2VlIGdvb2dsZTo6cHJvdG9idWY6OlRleHRGb3JtYXQ6OlBhcnNlRnJvbVN0cmluZygpLgorICBib29sIFBhcnNlRnJvbVN0cmluZyhjb25zdCBzdHJpbmcmIGRhdGEpOworICAvLyBMaWtlIFBhcnNlRnJvbVN0cmluZygpLCBidXQgYWNjZXB0cyBtZXNzYWdlcyB0aGF0IGFyZSBtaXNzaW5nCisgIC8vIHJlcXVpcmVkIGZpZWxkcy4KKyAgYm9vbCBQYXJzZVBhcnRpYWxGcm9tU3RyaW5nKGNvbnN0IHN0cmluZyYgZGF0YSk7CisgIC8vIFBhcnNlIGEgcHJvdG9jb2wgYnVmZmVyIGNvbnRhaW5lZCBpbiBhbiBhcnJheSBvZiBieXRlcy4KKyAgYm9vbCBQYXJzZUZyb21BcnJheShjb25zdCB2b2lkKiBkYXRhLCBpbnQgc2l6ZSk7CisgIC8vIExpa2UgUGFyc2VGcm9tQXJyYXkoKSwgYnV0IGFjY2VwdHMgbWVzc2FnZXMgdGhhdCBhcmUgbWlzc2luZworICAvLyByZXF1aXJlZCBmaWVsZHMuCisgIGJvb2wgUGFyc2VQYXJ0aWFsRnJvbUFycmF5KGNvbnN0IHZvaWQqIGRhdGEsIGludCBzaXplKTsKKworCisgIC8vIFJlYWRzIGEgcHJvdG9jb2wgYnVmZmVyIGZyb20gdGhlIHN0cmVhbSBhbmQgbWVyZ2VzIGl0IGludG8gdGhpcworICAvLyBNZXNzYWdlLiAgU2luZ3VsYXIgZmllbGRzIHJlYWQgZnJvbSB0aGUgaW5wdXQgb3ZlcndyaXRlIHdoYXQgaXMKKyAgLy8gYWxyZWFkeSBpbiB0aGUgTWVzc2FnZSBhbmQgcmVwZWF0ZWQgZmllbGRzIGFyZSBhcHBlbmRlZCB0byB0aG9zZQorICAvLyBhbHJlYWR5IHByZXNlbnQuCisgIC8vCisgIC8vIEl0IGlzIHRoZSByZXNwb25zaWJpbGl0eSBvZiB0aGUgY2FsbGVyIHRvIGNhbGwgaW5wdXQtPkxhc3RUYWdXYXMoKQorICAvLyAoZm9yIGdyb3Vwcykgb3IgaW5wdXQtPkNvbnN1bWVkRW50aXJlTWVzc2FnZSgpIChmb3Igbm9uLWdyb3VwcykgYWZ0ZXIKKyAgLy8gdGhpcyByZXR1cm5zIHRvIHZlcmlmeSB0aGF0IHRoZSBtZXNzYWdlJ3MgZW5kIHdhcyBkZWxpbWl0ZWQgY29ycmVjdGx5LgorICAvLworICAvLyBQYXJzZWZyb21Db2RlZFN0cmVhbSgpIGlzIGltcGxlbWVudGVkIGFzIENsZWFyKCkgZm9sbG93ZWQgYnkKKyAgLy8gTWVyZ2VGcm9tQ29kZWRTdHJlYW0oKS4KKyAgYm9vbCBNZXJnZUZyb21Db2RlZFN0cmVhbShpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpOworCisgIC8vIExpa2UgTWVyZ2VGcm9tQ29kZWRTdHJlYW0oKSwgYnV0IHN1Y2NlZWRzIGV2ZW4gaWYgcmVxdWlyZWQgZmllbGRzIGFyZQorICAvLyBtaXNzaW5nIGluIHRoZSBpbnB1dC4KKyAgLy8KKyAgLy8gTWVyZ2VGcm9tQ29kZWRTdHJlYW0oKSBpcyBqdXN0IGltcGxlbWVudGVkIGFzIE1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgpCisgIC8vIGZvbGxvd2VkIGJ5IElzSW5pdGlhbGl6ZWQoKS4KKyAgdmlydHVhbCBib29sIE1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbShpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpID0gMDsKKworCisgIC8vIFNlcmlhbGl6YXRpb24gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8vIE1ldGhvZHMgZm9yIHNlcmlhbGl6aW5nIGluIHByb3RvY29sIGJ1ZmZlciBmb3JtYXQuICBNb3N0IG9mIHRoZXNlCisgIC8vIGFyZSBqdXN0IHNpbXBsZSB3cmFwcGVycyBhcm91bmQgQnl0ZVNpemUoKSBhbmQgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKCkuCisKKyAgLy8gV3JpdGUgYSBwcm90b2NvbCBidWZmZXIgb2YgdGhpcyBtZXNzYWdlIHRvIHRoZSBnaXZlbiBvdXRwdXQuICBSZXR1cm5zCisgIC8vIGZhbHNlIG9uIGEgd3JpdGUgZXJyb3IuICBJZiB0aGUgbWVzc2FnZSBpcyBtaXNzaW5nIHJlcXVpcmVkIGZpZWxkcywKKyAgLy8gdGhpcyBtYXkgR09PR0xFX0NIRUNLLWZhaWwuCisgIGJvb2wgU2VyaWFsaXplVG9Db2RlZFN0cmVhbShpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3Q7CisgIC8vIExpa2UgU2VyaWFsaXplVG9Db2RlZFN0cmVhbSgpLCBidXQgYWxsb3dzIG1pc3NpbmcgcmVxdWlyZWQgZmllbGRzLgorICBib29sIFNlcmlhbGl6ZVBhcnRpYWxUb0NvZGVkU3RyZWFtKGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgLy8gV3JpdGUgdGhlIG1lc3NhZ2UgdG8gdGhlIGdpdmVuIHplcm8tY29weSBvdXRwdXQgc3RyZWFtLiAgQWxsIHJlcXVpcmVkCisgIC8vIGZpZWxkcyBtdXN0IGJlIHNldC4KKyAgYm9vbCBTZXJpYWxpemVUb1plcm9Db3B5U3RyZWFtKGlvOjpaZXJvQ29weU91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgLy8gTGlrZSBTZXJpYWxpemVUb1plcm9Db3B5U3RyZWFtKCksIGJ1dCBhbGxvd3MgbWlzc2luZyByZXF1aXJlZCBmaWVsZHMuCisgIGJvb2wgU2VyaWFsaXplUGFydGlhbFRvWmVyb0NvcHlTdHJlYW0oaW86Olplcm9Db3B5T3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0OworICAvLyBTZXJpYWxpemUgdGhlIG1lc3NhZ2UgYW5kIHN0b3JlIGl0IGluIHRoZSBnaXZlbiBzdHJpbmcuICBBbGwgcmVxdWlyZWQKKyAgLy8gZmllbGRzIG11c3QgYmUgc2V0LgorICBib29sIFNlcmlhbGl6ZVRvU3RyaW5nKHN0cmluZyogb3V0cHV0KSBjb25zdDsKKyAgLy8gTGlrZSBTZXJpYWxpemVUb1N0cmluZygpLCBidXQgYWxsb3dzIG1pc3NpbmcgcmVxdWlyZWQgZmllbGRzLgorICBib29sIFNlcmlhbGl6ZVBhcnRpYWxUb1N0cmluZyhzdHJpbmcqIG91dHB1dCkgY29uc3Q7CisgIC8vIFNlcmlhbGl6ZSB0aGUgbWVzc2FnZSBhbmQgc3RvcmUgaXQgaW4gdGhlIGdpdmVuIGJ5dGUgYXJyYXkuICBBbGwgcmVxdWlyZWQKKyAgLy8gZmllbGRzIG11c3QgYmUgc2V0LgorICBib29sIFNlcmlhbGl6ZVRvQXJyYXkodm9pZCogZGF0YSwgaW50IHNpemUpIGNvbnN0OworICAvLyBMaWtlIFNlcmlhbGl6ZVRvQXJyYXkoKSwgYnV0IGFsbG93cyBtaXNzaW5nIHJlcXVpcmVkIGZpZWxkcy4KKyAgYm9vbCBTZXJpYWxpemVQYXJ0aWFsVG9BcnJheSh2b2lkKiBkYXRhLCBpbnQgc2l6ZSkgY29uc3Q7CisKKyAgLy8gTWFrZSBhIHN0cmluZyBlbmNvZGluZyB0aGUgbWVzc2FnZS4gSXMgZXF1aXZhbGVudCB0byBjYWxsaW5nCisgIC8vIFNlcmlhbGl6ZVRvU3RyaW5nKCkgb24gYSBzdHJpbmcgYW5kIHVzaW5nIHRoYXQuICBSZXR1cm5zIHRoZSBlbXB0eQorICAvLyBzdHJpbmcgaWYgU2VyaWFsaXplVG9TdHJpbmcoKSB3b3VsZCBoYXZlIHJldHVybmVkIGFuIGVycm9yLgorICAvLyBOb3RlOiBJZiB5b3UgaW50ZW5kIHRvIGdlbmVyYXRlIG1hbnkgc3VjaCBzdHJpbmdzLCB5b3UgbWF5CisgIC8vIHJlZHVjZSBoZWFwIGZyYWdtZW50YXRpb24gYnkgaW5zdGVhZCByZS11c2luZyB0aGUgc2FtZSBzdHJpbmcKKyAgLy8gb2JqZWN0IHdpdGggY2FsbHMgdG8gU2VyaWFsaXplVG9TdHJpbmcoKS4KKyAgc3RyaW5nIFNlcmlhbGl6ZUFzU3RyaW5nKCkgY29uc3Q7CisgIC8vIExpa2UgU2VyaWFsaXplQXNTdHJpbmcoKSwgYnV0IGFsbG93cyBtaXNzaW5nIHJlcXVpcmVkIGZpZWxkcy4KKyAgc3RyaW5nIFNlcmlhbGl6ZVBhcnRpYWxBc1N0cmluZygpIGNvbnN0OworCisgIC8vIExpa2UgU2VyaWFsaXplVG9TdHJpbmcoKSwgYnV0IGFwcGVuZHMgdG8gdGhlIGRhdGEgdG8gdGhlIHN0cmluZydzIGV4aXN0aW5nCisgIC8vIGNvbnRlbnRzLiAgQWxsIHJlcXVpcmVkIGZpZWxkcyBtdXN0IGJlIHNldC4KKyAgYm9vbCBBcHBlbmRUb1N0cmluZyhzdHJpbmcqIG91dHB1dCkgY29uc3Q7CisgIC8vIExpa2UgQXBwZW5kVG9TdHJpbmcoKSwgYnV0IGFsbG93cyBtaXNzaW5nIHJlcXVpcmVkIGZpZWxkcy4KKyAgYm9vbCBBcHBlbmRQYXJ0aWFsVG9TdHJpbmcoc3RyaW5nKiBvdXRwdXQpIGNvbnN0OworCisgIC8vIENvbXB1dGVzIHRoZSBzZXJpYWxpemVkIHNpemUgb2YgdGhlIG1lc3NhZ2UuICBUaGlzIHJlY3Vyc2l2ZWx5IGNhbGxzCisgIC8vIEJ5dGVTaXplKCkgb24gYWxsIGVtYmVkZGVkIG1lc3NhZ2VzLiAgSWYgYSBzdWJjbGFzcyBkb2VzIG5vdCBvdmVycmlkZQorICAvLyB0aGlzLCBpdCBNVVNUIG92ZXJyaWRlIFNldENhY2hlZFNpemUoKS4KKyAgLy8KKyAgLy8gQnl0ZVNpemUoKSBpcyBnZW5lcmFsbHkgbGluZWFyIGluIHRoZSBudW1iZXIgb2YgZmllbGRzIGRlZmluZWQgZm9yIHRoZQorICAvLyBwcm90by4KKyAgdmlydHVhbCBpbnQgQnl0ZVNpemUoKSBjb25zdCA9IDA7CisKKyAgLy8gU2VyaWFsaXplcyB0aGUgbWVzc2FnZSB3aXRob3V0IHJlY29tcHV0aW5nIHRoZSBzaXplLiAgVGhlIG1lc3NhZ2UgbXVzdAorICAvLyBub3QgaGF2ZSBjaGFuZ2VkIHNpbmNlIHRoZSBsYXN0IGNhbGwgdG8gQnl0ZVNpemUoKTsgaWYgaXQgaGFzLCB0aGUgcmVzdWx0cworICAvLyBhcmUgdW5kZWZpbmVkLgorICB2aXJ0dWFsIHZvaWQgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0ID0gMDsKKworICAvLyBMaWtlIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcywgYnV0IHdyaXRlcyBkaXJlY3RseSB0byAqdGFyZ2V0LCByZXR1cm5pbmcKKyAgLy8gYSBwb2ludGVyIHRvIHRoZSBieXRlIGltbWVkaWF0ZWx5IGFmdGVyIHRoZSBsYXN0IGJ5dGUgd3JpdHRlbi4gICJ0YXJnZXQiCisgIC8vIG11c3QgcG9pbnQgYXQgYSBieXRlIGFycmF5IG9mIGF0IGxlYXN0IEJ5dGVTaXplKCkgYnl0ZXMuCisgIHZpcnR1YWwgdWludDgqIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkodWludDgqIHRhcmdldCkgY29uc3Q7CisKKyAgLy8gUmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSBsYXN0IGNhbGwgdG8gQnl0ZVNpemUoKS4gIEFuIGVtYmVkZGVkIG1lc3NhZ2UncworICAvLyBzaXplIGlzIG5lZWRlZCBib3RoIHRvIHNlcmlhbGl6ZSBpdCAoYmVjYXVzZSBlbWJlZGRlZCBtZXNzYWdlcyBhcmUKKyAgLy8gbGVuZ3RoLWRlbGltaXRlZCkgYW5kIHRvIGNvbXB1dGUgdGhlIG91dGVyIG1lc3NhZ2UncyBzaXplLiAgQ2FjaGluZworICAvLyB0aGUgc2l6ZSBhdm9pZHMgY29tcHV0aW5nIGl0IG11bHRpcGxlIHRpbWVzLgorICAvLworICAvLyBCeXRlU2l6ZSgpIGRvZXMgbm90IGF1dG9tYXRpY2FsbHkgdXNlIHRoZSBjYWNoZWQgc2l6ZSB3aGVuIGF2YWlsYWJsZQorICAvLyBiZWNhdXNlIHRoaXMgd291bGQgcmVxdWlyZSBpbnZhbGlkYXRpbmcgaXQgZXZlcnkgdGltZSB0aGUgbWVzc2FnZSB3YXMKKyAgLy8gbW9kaWZpZWQsIHdoaWNoIHdvdWxkIGJlIHRvbyBoYXJkIGFuZCBleHBlbnNpdmUuICAoRS5nLiBpZiBhIGRlZXBseS1uZXN0ZWQKKyAgLy8gc3ViLW1lc3NhZ2UgaXMgY2hhbmdlZCwgYWxsIG9mIGl0cyBwYXJlbnRzJyBjYWNoZWQgc2l6ZXMgd291bGQgbmVlZCB0byBiZQorICAvLyBpbnZhbGlkYXRlZCwgd2hpY2ggaXMgdG9vIG11Y2ggd29yayBmb3IgYW4gb3RoZXJ3aXNlIGlubGluZWQgc2V0dGVyCisgIC8vIG1ldGhvZC4pCisgIHZpcnR1YWwgaW50IEdldENhY2hlZFNpemUoKSBjb25zdCA9IDA7CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoTWVzc2FnZUxpdGUpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX01FU1NBR0VfTElURV9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvbWVzc2FnZV91bml0dGVzdC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvbWVzc2FnZV91bml0dGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZDQ3ODBmCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9tZXNzYWdlX3VuaXR0ZXN0LmNjCkBAIC0wLDAgKzEsNDcwIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWVzc2FnZS5oPgorCisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisjaW5jbHVkZSA8c3lzL3N0YXQuaD4KKyNpbmNsdWRlIDxmY250bC5oPgorI2lmZGVmIF9NU0NfVkVSCisjaW5jbHVkZSA8aW8uaD4KKyNlbHNlCisjaW5jbHVkZSA8dW5pc3RkLmg+CisjZW5kaWYKKyNpbmNsdWRlIDxzc3RyZWFtPgorI2luY2x1ZGUgPGZzdHJlYW0+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdF91dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX2ltcGwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9tZXNzYWdlX3JlZmxlY3Rpb24uaD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9sb2dnaW5nLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2dvb2dsZXRlc3QuaD4KKyNpbmNsdWRlIDxndGVzdC9ndGVzdC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKKyNpZm5kZWYgT19CSU5BUlkKKyNpZmRlZiBfT19CSU5BUlkKKyNkZWZpbmUgT19CSU5BUlkgX09fQklOQVJZCisjZWxzZQorI2RlZmluZSBPX0JJTkFSWSAwICAgICAvLyBJZiB0aGlzIGlzbid0IGRlZmluZWQsIHRoZSBwbGF0Zm9ybSBkb2Vzbid0IG5lZWQgaXQuCisjZW5kaWYKKyNlbmRpZgorCitURVNUKE1lc3NhZ2VUZXN0LCBTZXJpYWxpemVIZWxwZXJzKSB7CisgIC8vIFRPRE8oa2VudG9uKTogIFRlc3QgbW9yZSBoZWxwZXJzPyAgVGhleSdyZSBhbGwgdHdvLWxpbmVycyBzbyBpdCBzZWVtcworICAvLyAgIGxpa2UgYSB3YXN0ZSBvZiB0aW1lLgorCisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbWVzc2FnZSk7CisgIHN0cmluZ3N0cmVhbSBzdHJlYW07CisKKyAgc3RyaW5nIHN0cjEoImZvbyIpOworICBzdHJpbmcgc3RyMigiYmFyIik7CisKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5TZXJpYWxpemVUb1N0cmluZygmc3RyMSkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkFwcGVuZFRvU3RyaW5nKCZzdHIyKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuU2VyaWFsaXplVG9Pc3RyZWFtKCZzdHJlYW0pKTsKKworICBFWFBFQ1RfRVEoc3RyMS5zaXplKCkgKyAzLCBzdHIyLnNpemUoKSk7CisgIEVYUEVDVF9FUSgiYmFyIiwgc3RyMi5zdWJzdHIoMCwgMykpOworICAvLyBEb24ndCB1c2UgRVhQRUNUX0VRIGJlY2F1c2Ugd2UgZG9uJ3Qgd2FudCB0byBkdW1wIHJhdyBiaW5hcnkgZGF0YSB0bworICAvLyBzdGRvdXQuCisgIEVYUEVDVF9UUlVFKHN0cjIuc3Vic3RyKDMpID09IHN0cjEpOworCisgIC8vIEdDQyBnaXZlcyBzb21lIHNvcnQgb2YgZXJyb3IgaWYgd2UgdHJ5IHRvIGp1c3QgZG8gc3RyZWFtLnN0cigpID09IHN0cjEuCisgIHN0cmluZyB0ZW1wID0gc3RyZWFtLnN0cigpOworICBFWFBFQ1RfVFJVRSh0ZW1wID09IHN0cjEpOworCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuU2VyaWFsaXplQXNTdHJpbmcoKSA9PSBzdHIxKTsKKworfQorCitURVNUKE1lc3NhZ2VUZXN0LCBTZXJpYWxpemVUb0Jyb2tlbk9zdHJlYW0pIHsKKyAgb2ZzdHJlYW0gb3V0OworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisgIG1lc3NhZ2Uuc2V0X29wdGlvbmFsX2ludDMyKDEyMyk7CisKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuU2VyaWFsaXplVG9Pc3RyZWFtKCZvdXQpKTsKK30KKworVEVTVChNZXNzYWdlVGVzdCwgUGFyc2VGcm9tRmlsZURlc2NyaXB0b3IpIHsKKyAgc3RyaW5nIGZpbGVuYW1lID0gVGVzdFNvdXJjZURpcigpICsKKyAgICAgICAgICAgICAgICAgICAgIi9nb29nbGUvcHJvdG9idWYvdGVzdGRhdGEvZ29sZGVuX21lc3NhZ2UiOworICBpbnQgZmlsZSA9IG9wZW4oZmlsZW5hbWUuY19zdHIoKSwgT19SRE9OTFkgfCBPX0JJTkFSWSk7CisKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLlBhcnNlRnJvbUZpbGVEZXNjcmlwdG9yKGZpbGUpKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEZpZWxkc1NldChtZXNzYWdlKTsKKworICBFWFBFQ1RfR0UoY2xvc2UoZmlsZSksIDApOworfQorCitURVNUKE1lc3NhZ2VUZXN0LCBQYXJzZVBhY2tlZEZyb21GaWxlRGVzY3JpcHRvcikgeworICBzdHJpbmcgZmlsZW5hbWUgPQorICAgICAgVGVzdFNvdXJjZURpcigpICsKKyAgICAgICIvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RkYXRhL2dvbGRlbl9wYWNrZWRfZmllbGRzX21lc3NhZ2UiOworICBpbnQgZmlsZSA9IG9wZW4oZmlsZW5hbWUuY19zdHIoKSwgT19SRE9OTFkgfCBPX0JJTkFSWSk7CisKKyAgdW5pdHRlc3Q6OlRlc3RQYWNrZWRUeXBlcyBtZXNzYWdlOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLlBhcnNlRnJvbUZpbGVEZXNjcmlwdG9yKGZpbGUpKTsKKyAgVGVzdFV0aWw6OkV4cGVjdFBhY2tlZEZpZWxkc1NldChtZXNzYWdlKTsKKworICBFWFBFQ1RfR0UoY2xvc2UoZmlsZSksIDApOworfQorCitURVNUKE1lc3NhZ2VUZXN0LCBQYXJzZUhlbHBlcnMpIHsKKyAgLy8gVE9ETyhrZW50b24pOiAgVGVzdCBtb3JlIGhlbHBlcnM/ICBUaGV5J3JlIGFsbCB0d28tbGluZXJzIHNvIGl0IHNlZW1zCisgIC8vICAgbGlrZSBhIHdhc3RlIG9mIHRpbWUuCisgIHN0cmluZyBkYXRhOworCisgIHsKKyAgICAvLyBTZXQgdXAuCisgICAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlOworICAgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1lc3NhZ2UpOworICAgIG1lc3NhZ2UuU2VyaWFsaXplVG9TdHJpbmcoJmRhdGEpOworICB9CisKKyAgeworICAgIC8vIFRlc3QgUGFyc2VGcm9tU3RyaW5nLgorICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKyAgICBFWFBFQ1RfVFJVRShtZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhkYXRhKSk7CisgICAgVGVzdFV0aWw6OkV4cGVjdEFsbEZpZWxkc1NldChtZXNzYWdlKTsKKyAgfQorCisgIHsKKyAgICAvLyBUZXN0IFBhcnNlRnJvbUlzdHJlYW0uCisgICAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlOworICAgIHN0cmluZ3N0cmVhbSBzdHJlYW0oZGF0YSk7CisgICAgRVhQRUNUX1RSVUUobWVzc2FnZS5QYXJzZUZyb21Jc3RyZWFtKCZzdHJlYW0pKTsKKyAgICBFWFBFQ1RfVFJVRShzdHJlYW0uZW9mKCkpOworICAgIFRlc3RVdGlsOjpFeHBlY3RBbGxGaWVsZHNTZXQobWVzc2FnZSk7CisgIH0KKworICB7CisgICAgLy8gVGVzdCBQYXJzZUZyb21Cb3VuZGVkWmVyb0NvcHlTdHJlYW0uCisgICAgc3RyaW5nIGRhdGFfd2l0aF9qdW5rKGRhdGEpOworICAgIGRhdGFfd2l0aF9qdW5rLmFwcGVuZCgic29tZSBqdW5rIG9uIHRoZSBlbmQiKTsKKyAgICBpbzo6QXJyYXlJbnB1dFN0cmVhbSBzdHJlYW0oZGF0YV93aXRoX2p1bmsuZGF0YSgpLCBkYXRhX3dpdGhfanVuay5zaXplKCkpOworICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKyAgICBFWFBFQ1RfVFJVRShtZXNzYWdlLlBhcnNlRnJvbUJvdW5kZWRaZXJvQ29weVN0cmVhbSgmc3RyZWFtLCBkYXRhLnNpemUoKSkpOworICAgIFRlc3RVdGlsOjpFeHBlY3RBbGxGaWVsZHNTZXQobWVzc2FnZSk7CisgIH0KKworICB7CisgICAgLy8gVGVzdCB0aGF0IFBhcnNlRnJvbUJvdW5kZWRaZXJvQ29weVN0cmVhbSBmYWlscyAoYnV0IGRvZXNuJ3QgY3Jhc2gpIGlmCisgICAgLy8gRU9GIGlzIHJlYWNoZWQgYmVmb3JlIHRoZSBleHBlY3RlZCBudW1iZXIgb2YgYnl0ZXMuCisgICAgaW86OkFycmF5SW5wdXRTdHJlYW0gc3RyZWFtKGRhdGEuZGF0YSgpLCBkYXRhLnNpemUoKSk7CisgICAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlOworICAgIEVYUEVDVF9GQUxTRSgKKyAgICAgIG1lc3NhZ2UuUGFyc2VGcm9tQm91bmRlZFplcm9Db3B5U3RyZWFtKCZzdHJlYW0sIGRhdGEuc2l6ZSgpICsgMSkpOworICB9Cit9CisKK1RFU1QoTWVzc2FnZVRlc3QsIFBhcnNlRmFpbHNJZk5vdEluaXRpYWxpemVkKSB7CisgIHVuaXR0ZXN0OjpUZXN0UmVxdWlyZWQgbWVzc2FnZTsKKyAgdmVjdG9yPHN0cmluZz4gZXJyb3JzOworCisgIHsKKyAgICBTY29wZWRNZW1vcnlMb2cgbG9nOworICAgIEVYUEVDVF9GQUxTRShtZXNzYWdlLlBhcnNlRnJvbVN0cmluZygiIikpOworICAgIGVycm9ycyA9IGxvZy5HZXRNZXNzYWdlcyhFUlJPUik7CisgIH0KKworICBBU1NFUlRfRVEoMSwgZXJyb3JzLnNpemUoKSk7CisgIEVYUEVDVF9FUSgiQ2FuJ3QgcGFyc2UgbWVzc2FnZSBvZiB0eXBlIFwicHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkXCIgIgorICAgICAgICAgICAgImJlY2F1c2UgaXQgaXMgbWlzc2luZyByZXF1aXJlZCBmaWVsZHM6IGEsIGIsIGMiLAorICAgICAgICAgICAgZXJyb3JzWzBdKTsKK30KKworVEVTVChNZXNzYWdlVGVzdCwgQnlwYXNzSW5pdGlhbGl6YXRpb25DaGVja09uUGFyc2UpIHsKKyAgdW5pdHRlc3Q6OlRlc3RSZXF1aXJlZCBtZXNzYWdlOworICBpbzo6QXJyYXlJbnB1dFN0cmVhbSByYXdfaW5wdXQoTlVMTCwgMCk7CisgIGlvOjpDb2RlZElucHV0U3RyZWFtIGlucHV0KCZyYXdfaW5wdXQpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLk1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgmaW5wdXQpKTsKK30KKworVEVTVChNZXNzYWdlVGVzdCwgSW5pdGlhbGl6YXRpb25FcnJvclN0cmluZykgeworICB1bml0dGVzdDo6VGVzdFJlcXVpcmVkIG1lc3NhZ2U7CisgIEVYUEVDVF9FUSgiYSwgYiwgYyIsIG1lc3NhZ2UuSW5pdGlhbGl6YXRpb25FcnJvclN0cmluZygpKTsKK30KKworVEVTVChNZXNzYWdlVGVzdCwgRHluYW1pY0Nhc3RUb0dlbmVyYXRlZCkgeworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIHRlc3RfYWxsX3R5cGVzOworCisgIGdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UqIHRlc3RfYWxsX3R5cGVzX3BvaW50ZXIgPSAmdGVzdF9hbGxfdHlwZXM7CisgIEVYUEVDVF9FUSgmdGVzdF9hbGxfdHlwZXMsCisgICAgICAgICAgICBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RHluYW1pY0Nhc3RUb0dlbmVyYXRlZDx1bml0dGVzdDo6VGVzdEFsbFR5cGVzPigKKyAgICAgICAgICAgICAgICB0ZXN0X2FsbF90eXBlc19wb2ludGVyKSk7CisgIEVYUEVDVF9FUShOVUxMLAorICAgICAgICAgICAgZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkR5bmFtaWNDYXN0VG9HZW5lcmF0ZWQ8dW5pdHRlc3Q6OlRlc3RSZXF1aXJlZD4oCisgICAgICAgICAgICAgICAgdGVzdF9hbGxfdHlwZXNfcG9pbnRlcikpOworCisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UqIHRlc3RfYWxsX3R5cGVzX3BvaW50ZXJfY29uc3QgPSAmdGVzdF9hbGxfdHlwZXM7CisgIEVYUEVDVF9FUSgKKyAgICAgICZ0ZXN0X2FsbF90eXBlcywKKyAgICAgIGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpEeW5hbWljQ2FzdFRvR2VuZXJhdGVkPGNvbnN0IHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM+KAorICAgICAgICAgIHRlc3RfYWxsX3R5cGVzX3BvaW50ZXJfY29uc3QpKTsKKyAgRVhQRUNUX0VRKAorICAgICAgTlVMTCwKKyAgICAgIGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpEeW5hbWljQ2FzdFRvR2VuZXJhdGVkPGNvbnN0IHVuaXR0ZXN0OjpUZXN0UmVxdWlyZWQ+KAorICAgICAgICAgIHRlc3RfYWxsX3R5cGVzX3BvaW50ZXJfY29uc3QpKTsKK30KKworI2lmZGVmIFBST1RPQlVGX0hBU19ERUFUSF9URVNUICAvLyBkZWF0aCB0ZXN0cyBkbyBub3Qgd29yayBvbiBXaW5kb3dzIHlldC4KKworVEVTVChNZXNzYWdlVGVzdCwgU2VyaWFsaXplRmFpbHNJZk5vdEluaXRpYWxpemVkKSB7CisgIHVuaXR0ZXN0OjpUZXN0UmVxdWlyZWQgbWVzc2FnZTsKKyAgc3RyaW5nIGRhdGE7CisgIEVYUEVDVF9ERUJVR19ERUFUSChFWFBFQ1RfVFJVRShtZXNzYWdlLlNlcmlhbGl6ZVRvU3RyaW5nKCZkYXRhKSksCisgICAgIkNhbid0IHNlcmlhbGl6ZSBtZXNzYWdlIG9mIHR5cGUgXCJwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRcIiBiZWNhdXNlICIKKyAgICAiaXQgaXMgbWlzc2luZyByZXF1aXJlZCBmaWVsZHM6IGEsIGIsIGMiKTsKK30KKworVEVTVChNZXNzYWdlVGVzdCwgQ2hlY2tJbml0aWFsaXplZCkgeworICB1bml0dGVzdDo6VGVzdFJlcXVpcmVkIG1lc3NhZ2U7CisgIEVYUEVDVF9ERUFUSChtZXNzYWdlLkNoZWNrSW5pdGlhbGl6ZWQoKSwKKyAgICAiTWVzc2FnZSBvZiB0eXBlIFwicHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkXCIgaXMgbWlzc2luZyByZXF1aXJlZCAiCisgICAgImZpZWxkczogYSwgYiwgYyIpOworfQorCitURVNUKE1lc3NhZ2VUZXN0LCBDaGVja092ZXJmbG93KSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKyAgLy8gQ3JlYXRlIGEgbWVzc2FnZSB3aXRoIHNpemUganVzdCBvdmVyIDJHQi4gVGhpcyB0cmlnZ2VycyBpbnRlZ2VyIG92ZXJmbG93CisgIC8vIHdoZW4gY29tcHV0aW5nIG1lc3NhZ2Ugc2l6ZS4KKyAgY29uc3Qgc3RyaW5nIGRhdGEoMTAyNCwgJ3gnKTsKKyAgQ29yZCBvbmVfbWVnYWJ5dGU7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTAyNDsgaSsrKSB7CisgICAgb25lX21lZ2FieXRlLkFwcGVuZChkYXRhKTsKKyAgfQorCisgIGZvciAoaW50IGkgPSAwOyBpIDwgMiAqIDEwMjQgKyAxOyArK2kpIHsKKyAgICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9jb3JkKCktPkNvcHlGcm9tKG9uZV9tZWdhYnl0ZSk7CisgIH0KKworICBDb3JkIHNlcmlhbGl6ZWQ7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkFwcGVuZFRvQ29yZCgmc2VyaWFsaXplZCkpOworfQorCisjZW5kaWYgIC8vIFBST1RPQlVGX0hBU19ERUFUSF9URVNUCisKK25hbWVzcGFjZSB7CisKK2NsYXNzIE5lZ2F0aXZlQnl0ZVNpemUgOiBwdWJsaWMgdW5pdHRlc3Q6OlRlc3RSZXF1aXJlZCB7CisgcHVibGljOgorICB2aXJ0dWFsIGludCBCeXRlU2l6ZSgpIGNvbnN0IHsgcmV0dXJuIC0xOyB9Cit9OworCit9ICAvLyBuYW1lc3BhY2UKKworVEVTVChNZXNzYWdlVGVzdCwgU2VyaWFsaXphdGlvbkZhaWxzT25OZWdhdGl2ZUJ5dGVTaXplKSB7CisgIE5lZ2F0aXZlQnl0ZVNpemUgbWVzc2FnZTsKKyAgc3RyaW5nIHN0cmluZ19vdXRwdXQ7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkFwcGVuZFBhcnRpYWxUb1N0cmluZygmc3RyaW5nX291dHB1dCkpOworCisgIGlvOjpBcnJheU91dHB1dFN0cmVhbSBjb2RlZF9yYXdfb3V0cHV0KE5VTEwsIDEwMCk7CisgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSBjb2RlZF9vdXRwdXQoJmNvZGVkX3Jhd19vdXRwdXQpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5TZXJpYWxpemVQYXJ0aWFsVG9Db2RlZFN0cmVhbSgmY29kZWRfb3V0cHV0KSk7Cit9CisKK1RFU1QoTWVzc2FnZVRlc3QsIEJ5cGFzc0luaXRpYWxpemF0aW9uQ2hlY2tPblNlcmlhbGl6ZSkgeworICB1bml0dGVzdDo6VGVzdFJlcXVpcmVkIG1lc3NhZ2U7CisgIGlvOjpBcnJheU91dHB1dFN0cmVhbSByYXdfb3V0cHV0KE5VTEwsIDApOworICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KCZyYXdfb3V0cHV0KTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5TZXJpYWxpemVQYXJ0aWFsVG9Db2RlZFN0cmVhbSgmb3V0cHV0KSk7Cit9CisKK1RFU1QoTWVzc2FnZVRlc3QsIEZpbmRJbml0aWFsaXphdGlvbkVycm9ycykgeworICB1bml0dGVzdDo6VGVzdFJlcXVpcmVkIG1lc3NhZ2U7CisgIHZlY3RvcjxzdHJpbmc+IGVycm9yczsKKyAgbWVzc2FnZS5GaW5kSW5pdGlhbGl6YXRpb25FcnJvcnMoJmVycm9ycyk7CisgIEFTU0VSVF9FUSgzLCBlcnJvcnMuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKCJhIiwgZXJyb3JzWzBdKTsKKyAgRVhQRUNUX0VRKCJiIiwgZXJyb3JzWzFdKTsKKyAgRVhQRUNUX0VRKCJjIiwgZXJyb3JzWzJdKTsKK30KKworVEVTVChNZXNzYWdlVGVzdCwgUGFyc2VGYWlsc09uSW52YWxpZE1lc3NhZ2VFbmQpIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlOworCisgIC8vIENvbnRyb2wgY2FzZS4KKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5QYXJzZUZyb21BcnJheSgiIiwgMCkpOworCisgIC8vIFRoZSBieXRlIGlzIGEgdmFsaWQgdmFyaW50LCBidXQgbm90IGEgdmFsaWQgdGFnICh6ZXJvKS4KKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuUGFyc2VGcm9tQXJyYXkoIlwwIiwgMSkpOworCisgIC8vIFRoZSBieXRlIGlzIGEgbWFsZm9ybWVkIHZhcmludC4KKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuUGFyc2VGcm9tQXJyYXkoIlwyMDAiLCAxKSk7CisKKyAgLy8gVGhlIGJ5dGUgaXMgYW4gZW5kZ3JvdXAgdGFnLCBidXQgd2UgYXJlbid0IHBhcnNpbmcgYSBncm91cC4KKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuUGFyc2VGcm9tQXJyYXkoIlwwMTQiLCAxKSk7Cit9CisKK25hbWVzcGFjZSB7CisKK3ZvaWQgRXhwZWN0TWVzc2FnZU1lcmdlZChjb25zdCB1bml0dGVzdDo6VGVzdEFsbFR5cGVzJiBtZXNzYWdlKSB7CisgIEVYUEVDVF9FUSgzLCBtZXNzYWdlLm9wdGlvbmFsX2ludDMyKCkpOworICBFWFBFQ1RfRVEoMiwgbWVzc2FnZS5vcHRpb25hbF9pbnQ2NCgpKTsKKyAgRVhQRUNUX0VRKCJoZWxsbyIsIG1lc3NhZ2Uub3B0aW9uYWxfc3RyaW5nKCkpOworfQorCit2b2lkIEFzc2lnblBhcnNpbmdNZXJnZU1lc3NhZ2VzKAorICAgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMqIG1zZzEsCisgICAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyogbXNnMiwKKyAgICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzKiBtc2czKSB7CisgIG1zZzEtPnNldF9vcHRpb25hbF9pbnQzMigxKTsKKyAgbXNnMi0+c2V0X29wdGlvbmFsX2ludDY0KDIpOworICBtc2czLT5zZXRfb3B0aW9uYWxfaW50MzIoMyk7CisgIG1zZzMtPnNldF9vcHRpb25hbF9zdHJpbmcoImhlbGxvIik7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCisvLyBUZXN0IHRoYXQgaWYgYW4gb3B0aW9uYWwgb3IgcmVxdWlyZWQgbWVzc2FnZS9ncm91cCBmaWVsZCBhcHBlYXJzIG11bHRpcGxlCisvLyB0aW1lcyBpbiB0aGUgaW5wdXQsIHRoZXkgbmVlZCB0byBiZSBtZXJnZWQuCitURVNUKE1lc3NhZ2VUZXN0LCBQYXJzaW5nTWVyZ2UpIHsKKyAgdW5pdHRlc3Q6OlRlc3RQYXJzaW5nTWVyZ2U6OlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yIGdlbmVyYXRvcjsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyogbXNnMTsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyogbXNnMjsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyogbXNnMzsKKworI2RlZmluZSBBU1NJR05fUkVQRUFURURfRklFTEQoRklFTEQpICAgICAgICAgICAgICAgIFwKKyAgbXNnMSA9IGdlbmVyYXRvci5hZGRfIyNGSUVMRCgpOyAgICAgICAgICAgICAgICAgICBcCisgIG1zZzIgPSBnZW5lcmF0b3IuYWRkXyMjRklFTEQoKTsgICAgICAgICAgICAgICAgICAgXAorICBtc2czID0gZ2VuZXJhdG9yLmFkZF8jI0ZJRUxEKCk7ICAgICAgICAgICAgICAgICAgIFwKKyAgQXNzaWduUGFyc2luZ01lcmdlTWVzc2FnZXMobXNnMSwgbXNnMiwgbXNnMykKKworICBBU1NJR05fUkVQRUFURURfRklFTEQoZmllbGQxKTsKKyAgQVNTSUdOX1JFUEVBVEVEX0ZJRUxEKGZpZWxkMik7CisgIEFTU0lHTl9SRVBFQVRFRF9GSUVMRChmaWVsZDMpOworICBBU1NJR05fUkVQRUFURURfRklFTEQoZXh0MSk7CisgIEFTU0lHTl9SRVBFQVRFRF9GSUVMRChleHQyKTsKKworI3VuZGVmIEFTU0lHTl9SRVBFQVRFRF9GSUVMRAorI2RlZmluZSBBU1NJR05fUkVQRUFURURfR1JPVVAoRklFTEQpICAgICAgICAgICAgICAgIFwKKyAgbXNnMSA9IGdlbmVyYXRvci5hZGRfIyNGSUVMRCgpLT5tdXRhYmxlX2ZpZWxkMSgpOyBcCisgIG1zZzIgPSBnZW5lcmF0b3IuYWRkXyMjRklFTEQoKS0+bXV0YWJsZV9maWVsZDEoKTsgXAorICBtc2czID0gZ2VuZXJhdG9yLmFkZF8jI0ZJRUxEKCktPm11dGFibGVfZmllbGQxKCk7IFwKKyAgQXNzaWduUGFyc2luZ01lcmdlTWVzc2FnZXMobXNnMSwgbXNnMiwgbXNnMykKKworICBBU1NJR05fUkVQRUFURURfR1JPVVAoZ3JvdXAxKTsKKyAgQVNTSUdOX1JFUEVBVEVEX0dST1VQKGdyb3VwMik7CisKKyN1bmRlZiBBU1NJR05fUkVQRUFURURfR1JPVVAKKworICBzdHJpbmcgYnVmZmVyOworICBnZW5lcmF0b3IuU2VyaWFsaXplVG9TdHJpbmcoJmJ1ZmZlcik7CisgIHVuaXR0ZXN0OjpUZXN0UGFyc2luZ01lcmdlIHBhcnNpbmdfbWVyZ2U7CisgIHBhcnNpbmdfbWVyZ2UuUGFyc2VGcm9tU3RyaW5nKGJ1ZmZlcik7CisKKyAgLy8gUmVxdWlyZWQgYW5kIG9wdGlvbmFsIGZpZWxkcyBzaG91bGQgYmUgbWVyZ2VkLgorICBFeHBlY3RNZXNzYWdlTWVyZ2VkKHBhcnNpbmdfbWVyZ2UucmVxdWlyZWRfYWxsX3R5cGVzKCkpOworICBFeHBlY3RNZXNzYWdlTWVyZ2VkKHBhcnNpbmdfbWVyZ2Uub3B0aW9uYWxfYWxsX3R5cGVzKCkpOworICBFeHBlY3RNZXNzYWdlTWVyZ2VkKAorICAgICAgcGFyc2luZ19tZXJnZS5vcHRpb25hbGdyb3VwKCkub3B0aW9uYWxfZ3JvdXBfYWxsX3R5cGVzKCkpOworICBFeHBlY3RNZXNzYWdlTWVyZ2VkKAorICAgICAgcGFyc2luZ19tZXJnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OlRlc3RQYXJzaW5nTWVyZ2U6Om9wdGlvbmFsX2V4dCkpOworCisgIC8vIFJlcGVhdGVkIGZpZWxkcyBzaG91bGQgbm90IGJlIG1lcmdlZC4KKyAgRVhQRUNUX0VRKDMsIHBhcnNpbmdfbWVyZ2UucmVwZWF0ZWRfYWxsX3R5cGVzX3NpemUoKSk7CisgIEVYUEVDVF9FUSgzLCBwYXJzaW5nX21lcmdlLnJlcGVhdGVkZ3JvdXBfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDMsIHBhcnNpbmdfbWVyZ2UuRXh0ZW5zaW9uU2l6ZSgKKyAgICAgIHVuaXR0ZXN0OjpUZXN0UGFyc2luZ01lcmdlOjpyZXBlYXRlZF9leHQpKTsKK30KKworVEVTVChNZXNzYWdlVGVzdCwgTWVyZ2VGcm9tKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgc291cmNlOworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIGRlc3Q7CisKKyAgLy8gT3B0aW9uYWwgZmllbGRzCisgIHNvdXJjZS5zZXRfb3B0aW9uYWxfaW50MzIoMSk7ICAvLyBvbmx5IHNvdXJjZQorICBzb3VyY2Uuc2V0X29wdGlvbmFsX2ludDY0KDIpOyAgLy8gYm90aCBzb3VyY2UgYW5kIGRlc3QKKyAgZGVzdC5zZXRfb3B0aW9uYWxfaW50NjQoMyk7CisgIGRlc3Quc2V0X29wdGlvbmFsX3VpbnQzMig0KTsgICAvLyBvbmx5IGRlc3QKKworICAvLyBPcHRpb25hbCBmaWVsZHMgd2l0aCBkZWZhdWx0cworICBzb3VyY2Uuc2V0X2RlZmF1bHRfaW50MzIoMTMpOyAgLy8gb25seSBzb3VyY2UKKyAgc291cmNlLnNldF9kZWZhdWx0X2ludDY0KDE0KTsgIC8vIGJvdGggc291cmNlIGFuZCBkZXN0CisgIGRlc3Quc2V0X2RlZmF1bHRfaW50NjQoMTUpOworICBkZXN0LnNldF9kZWZhdWx0X3VpbnQzMigxNik7ICAgLy8gb25seSBkZXN0CisKKyAgLy8gUmVwZWF0ZWQgZmllbGRzCisgIHNvdXJjZS5hZGRfcmVwZWF0ZWRfaW50MzIoNSk7ICAvLyBvbmx5IHNvdXJjZQorICBzb3VyY2UuYWRkX3JlcGVhdGVkX2ludDMyKDYpOworICBzb3VyY2UuYWRkX3JlcGVhdGVkX2ludDY0KDcpOyAgLy8gYm90aCBzb3VyY2UgYW5kIGRlc3QKKyAgc291cmNlLmFkZF9yZXBlYXRlZF9pbnQ2NCg4KTsKKyAgZGVzdC5hZGRfcmVwZWF0ZWRfaW50NjQoOSk7CisgIGRlc3QuYWRkX3JlcGVhdGVkX2ludDY0KDEwKTsKKyAgZGVzdC5hZGRfcmVwZWF0ZWRfdWludDMyKDExKTsgIC8vIG9ubHkgZGVzdAorICBkZXN0LmFkZF9yZXBlYXRlZF91aW50MzIoMTIpOworCisgIGRlc3QuTWVyZ2VGcm9tKHNvdXJjZSk7CisKKyAgLy8gT3B0aW9uYWwgZmllbGRzOiBzb3VyY2Ugb3ZlcndyaXRlcyBkZXN0IGlmIHNvdXJjZSBpcyBzcGVjaWZpZWQKKyAgRVhQRUNUX0VRKDEsIGRlc3Qub3B0aW9uYWxfaW50MzIoKSk7ICAvLyBvbmx5IHNvdXJjZTogdXNlIHNvdXJjZQorICBFWFBFQ1RfRVEoMiwgZGVzdC5vcHRpb25hbF9pbnQ2NCgpKTsgIC8vIHNvdXJjZSBhbmQgZGVzdDogdXNlIHNvdXJjZQorICBFWFBFQ1RfRVEoNCwgZGVzdC5vcHRpb25hbF91aW50MzIoKSk7ICAvLyBvbmx5IGRlc3Q6IHVzZSBkZXN0CisgIEVYUEVDVF9FUSgwLCBkZXN0Lm9wdGlvbmFsX3VpbnQ2NCgpKTsgIC8vIG5laXRoZXI6IHVzZSBkZWZhdWx0CisKKyAgLy8gT3B0aW9uYWwgZmllbGRzIHdpdGggZGVmYXVsdHMKKyAgRVhQRUNUX0VRKDEzLCBkZXN0LmRlZmF1bHRfaW50MzIoKSk7ICAvLyBvbmx5IHNvdXJjZTogdXNlIHNvdXJjZQorICBFWFBFQ1RfRVEoMTQsIGRlc3QuZGVmYXVsdF9pbnQ2NCgpKTsgIC8vIHNvdXJjZSBhbmQgZGVzdDogdXNlIHNvdXJjZQorICBFWFBFQ1RfRVEoMTYsIGRlc3QuZGVmYXVsdF91aW50MzIoKSk7ICAvLyBvbmx5IGRlc3Q6IHVzZSBkZXN0CisgIEVYUEVDVF9FUSg0NCwgZGVzdC5kZWZhdWx0X3VpbnQ2NCgpKTsgIC8vIG5laXRoZXI6IHVzZSBkZWZhdWx0CisKKyAgLy8gUmVwZWF0ZWQgZmllbGRzOiBjb25jYXRlbmF0ZSBzb3VyY2Ugb250byB0aGUgZW5kIG9mIGRlc3QKKyAgQVNTRVJUX0VRKDIsIGRlc3QucmVwZWF0ZWRfaW50MzJfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDUsIGRlc3QucmVwZWF0ZWRfaW50MzIoMCkpOworICBFWFBFQ1RfRVEoNiwgZGVzdC5yZXBlYXRlZF9pbnQzMigxKSk7CisgIEFTU0VSVF9FUSg0LCBkZXN0LnJlcGVhdGVkX2ludDY0X3NpemUoKSk7CisgIEVYUEVDVF9FUSg5LCAgZGVzdC5yZXBlYXRlZF9pbnQ2NCgwKSk7CisgIEVYUEVDVF9FUSgxMCwgZGVzdC5yZXBlYXRlZF9pbnQ2NCgxKSk7CisgIEVYUEVDVF9FUSg3LCAgZGVzdC5yZXBlYXRlZF9pbnQ2NCgyKSk7CisgIEVYUEVDVF9FUSg4LCAgZGVzdC5yZXBlYXRlZF9pbnQ2NCgzKSk7CisgIEFTU0VSVF9FUSgyLCBkZXN0LnJlcGVhdGVkX3VpbnQzMl9zaXplKCkpOworICBFWFBFQ1RfRVEoMTEsIGRlc3QucmVwZWF0ZWRfdWludDMyKDApKTsKKyAgRVhQRUNUX0VRKDEyLCBkZXN0LnJlcGVhdGVkX3VpbnQzMigxKSk7CisgIEFTU0VSVF9FUSgwLCBkZXN0LnJlcGVhdGVkX3VpbnQ2NF9zaXplKCkpOworfQorCitURVNUKE1lc3NhZ2VGYWN0b3J5VGVzdCwgR2VuZXJhdGVkRmFjdG9yeUxvb2t1cCkgeworICBFWFBFQ1RfRVEoCisgICAgTWVzc2FnZUZhY3Rvcnk6OmdlbmVyYXRlZF9mYWN0b3J5KCktPkdldFByb3RvdHlwZSgKKyAgICAgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OmRlc2NyaXB0b3IoKSksCisgICAgJnByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OmRlZmF1bHRfaW5zdGFuY2UoKSk7Cit9CisKK1RFU1QoTWVzc2FnZUZhY3RvcnlUZXN0LCBHZW5lcmF0ZWRGYWN0b3J5VW5rbm93blR5cGUpIHsKKyAgLy8gQ29uc3RydWN0IGEgbmV3IGRlc2NyaXB0b3IuCisgIERlc2NyaXB0b3JQb29sIHBvb2w7CisgIEZpbGVEZXNjcmlwdG9yUHJvdG8gZmlsZTsKKyAgZmlsZS5zZXRfbmFtZSgiZm9vLnByb3RvIik7CisgIGZpbGUuYWRkX21lc3NhZ2VfdHlwZSgpLT5zZXRfbmFtZSgiRm9vIik7CisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBwb29sLkJ1aWxkRmlsZShmaWxlKS0+bWVzc2FnZV90eXBlKDApOworCisgIC8vIFRyeWluZyB0byBjb25zdHJ1Y3QgaXQgc2hvdWxkIHJldHVybiBOVUxMLgorICBFWFBFQ1RfVFJVRSgKKyAgICBNZXNzYWdlRmFjdG9yeTo6Z2VuZXJhdGVkX2ZhY3RvcnkoKS0+R2V0UHJvdG90eXBlKGRlc2NyaXB0b3IpID09IE5VTEwpOworfQorCisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9tZXRhZGF0YS5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9tZXRhZGF0YS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIxOTY0NWQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL21ldGFkYXRhLmgKQEAgLTAsMCArMSwxNjMgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBUaGlzIGhlYWRlciBmaWxlIGRlZmluZXMgYW4gaW50ZXJuYWwgY2xhc3MgdGhhdCBlbmNhcHN1bGF0ZXMgaW50ZXJuYWwgbWVzc2FnZQorLy8gbWV0YWRhdGEgKFVua25vd24tZmllbGQgc2V0LCBBcmVuYSBwb2ludGVyLCAuLi4pIGFuZCBhbGxvd3MgaXRzCisvLyByZXByZXNlbnRhdGlvbiB0byBiZSBtYWRlIG1vcmUgc3BhY2UtZWZmaWNpZW50IHZpYSB2YXJpb3VzIG9wdGltaXphdGlvbnMuCisvLworLy8gTm90ZSB0aGF0IHRoaXMgaXMgZGlzdGluY3QgZnJvbSBnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSwgd2hpY2ggZW5jYXBzdWxhdGVzCisvLyBEZXNjcmlwdG9yIGFuZCBSZWZsZWN0aW9uIHBvaW50ZXJzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9NRVRBREFUQV9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX01FVEFEQVRBX0hfXworCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9hcmVuYS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bmtub3duX2ZpZWxkX3NldC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW50ZXJuYWwgeworCisvLyBUaGlzIGlzIHRoZSByZXByZXNlbnRhdGlvbiBmb3IgbWVzc2FnZXMgdGhhdCBzdXBwb3J0IGFyZW5hIGFsbG9jYXRpb24uIEl0CisvLyB1c2VzIGEgdGFnZ2VkIHBvaW50ZXIgdG8gZWl0aGVyIHN0b3JlIHRoZSBBcmVuYSBwb2ludGVyLCBpZiB0aGVyZSBhcmUgbm8KKy8vIHVua25vd24gZmllbGRzLCBvciBhIHBvaW50ZXIgdG8gYSBibG9jayBvZiBtZW1vcnkgd2l0aCBib3RoIHRoZSBBcmVuYSBwb2ludGVyCisvLyBhbmQgdGhlIFVua25vd25GaWVsZFNldCwgaWYgdGhlcmUgYXJlIHVua25vd24gZmllbGRzLiBUaGlzIG9wdGltaXphdGlvbgorLy8gYWxsb3dzIGZvciAiemVyby1vdmVyaGVhZCIgc3RvcmFnZSBvZiB0aGUgQXJlbmEgcG9pbnRlciwgcmVsYXRpdmUgdG8gdGhlCisvLyBhYm92ZSBiYXNlbGluZSBpbXBsZW1lbnRhdGlvbi4KKy8vCisvLyBUaGUgdGFnZ2VkIHBvaW50ZXIgdXNlcyB0aGUgTFNCIHRvIGRpc2FtYmlndWF0ZSBjYXNlcywgYW5kIHVzZXMgYml0IDAgPT0gMCB0bworLy8gaW5kaWNhdGUgYW4gYXJlbmEgcG9pbnRlciBhbmQgYml0IDAgPT0gMSB0byBpbmRpY2F0ZSBhIFVGUytBcmVuYS1jb250YWluZXIKKy8vIHBvaW50ZXIuCitjbGFzcyBJbnRlcm5hbE1ldGFkYXRhV2l0aEFyZW5hIHsKKyBwdWJsaWM6CisgIEludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEoKSA6IHB0cl8oTlVMTCkge30KKyAgZXhwbGljaXQgSW50ZXJuYWxNZXRhZGF0YVdpdGhBcmVuYShBcmVuYSogYXJlbmEpCisgICAgICA6IHB0cl8gKGFyZW5hKSB7fQorCisgIH5JbnRlcm5hbE1ldGFkYXRhV2l0aEFyZW5hKCkgeworICAgIGlmIChoYXZlX3Vua25vd25fZmllbGRzKCkgJiYgYXJlbmEoKSA9PSBOVUxMKSB7CisgICAgICBkZWxldGUgUHRyVmFsdWU8Q29udGFpbmVyPigpOworICAgIH0KKyAgICBwdHJfID0gTlVMTDsKKyAgfQorCisgIEdPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORSBjb25zdCBVbmtub3duRmllbGRTZXQmIHVua25vd25fZmllbGRzKCkgY29uc3QgeworICAgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRShoYXZlX3Vua25vd25fZmllbGRzKCkpKSB7CisgICAgICByZXR1cm4gUHRyVmFsdWU8Q29udGFpbmVyPigpLT51bmtub3duX2ZpZWxkc187CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiAqVW5rbm93bkZpZWxkU2V0OjpkZWZhdWx0X2luc3RhbmNlKCk7CisgICAgfQorICB9CisKKyAgR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FIFVua25vd25GaWVsZFNldCogbXV0YWJsZV91bmtub3duX2ZpZWxkcygpIHsKKyAgICBpZiAoR09PR0xFX1BSRURJQ1RfVFJVRShoYXZlX3Vua25vd25fZmllbGRzKCkpKSB7CisgICAgICByZXR1cm4gJlB0clZhbHVlPENvbnRhaW5lcj4oKS0+dW5rbm93bl9maWVsZHNfOworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gbXV0YWJsZV91bmtub3duX2ZpZWxkc19zbG93KCk7CisgICAgfQorICB9CisKKyAgR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FIEFyZW5hKiBhcmVuYSgpIGNvbnN0IHsKKyAgICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoaGF2ZV91bmtub3duX2ZpZWxkcygpKSkgeworICAgICAgcmV0dXJuIFB0clZhbHVlPENvbnRhaW5lcj4oKS0+YXJlbmFfOworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gUHRyVmFsdWU8QXJlbmE+KCk7CisgICAgfQorICB9CisKKyAgR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FIGJvb2wgaGF2ZV91bmtub3duX2ZpZWxkcygpIGNvbnN0IHsKKyAgICByZXR1cm4gUHRyVGFnKCkgPT0ga1RhZ0NvbnRhaW5lcjsKKyAgfQorCisgIEdPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORSB2b2lkIFN3YXAoSW50ZXJuYWxNZXRhZGF0YVdpdGhBcmVuYSogb3RoZXIpIHsKKyAgICAvLyBTZW1hbnRpY3MgaGVyZSBhcmUgdGhhdCB3ZSBzd2FwIG9ubHkgdGhlIHVua25vd24gZmllbGRzLCBub3QgdGhlIGFyZW5hCisgICAgLy8gcG9pbnRlci4gV2UgY2Fubm90IHNpbXBseSBzd2FwIHB0cl8gd2l0aCBvdGhlci0+cHRyXyBiZWNhdXNlIHdlIG5lZWQgdG8KKyAgICAvLyBtYWludGFpbiBvdXIgb3duIGFyZW5hIHB0ci4gQWxzbywgb3VyIHB0cl8gYW5kIG90aGVyJ3MgcHRyXyBtYXkgYmUgaW4KKyAgICAvLyBkaWZmZXJlbnQgc3RhdGVzIChkaXJlY3QgYXJlbmEgcG9pbnRlciB2cy4gY29udGFpbmVyIHdpdGggVUZTKSBzbyB3ZQorICAgIC8vIGNhbm5vdCBzaW1wbHkgc3dhcCBwdHJfIGFuZCB0aGVuIHJlc3RvcmUgdGhlIGFyZW5hIHBvaW50ZXJzLiBXZSByZXVzZQorICAgIC8vIFVGUydzIHN3YXAgaW1wbGVtZW50YXRpb24gaW5zdGVhZC4KKyAgICBpZiAoaGF2ZV91bmtub3duX2ZpZWxkcygpIHx8IG90aGVyLT5oYXZlX3Vua25vd25fZmllbGRzKCkpIHsKKyAgICAgIG11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+U3dhcChvdGhlci0+bXV0YWJsZV91bmtub3duX2ZpZWxkcygpKTsKKyAgICB9CisgIH0KKworICBHT09HTEVfQVRUUklCVVRFX0FMV0FZU19JTkxJTkUgdm9pZCogcmF3X2FyZW5hX3B0cigpIGNvbnN0IHsKKyAgICByZXR1cm4gcHRyXzsKKyAgfQorCisgcHJpdmF0ZToKKyAgdm9pZCogcHRyXzsKKworICAvLyBUYWdnZWQgcG9pbnRlciBpbXBsZW1lbnRhdGlvbi4KKyAgZW51bSB7CisgICAgLy8gcHRyXyBpcyBhbiBBcmVuYSouCisgICAga1RhZ0FyZW5hID0gMCwKKyAgICAvLyBwdHJfIGlzIGEgQ29udGFpbmVyKi4KKyAgICBrVGFnQ29udGFpbmVyID0gMSwKKyAgfTsKKyAgc3RhdGljIGNvbnN0IGludHB0cl90IGtQdHJUYWdNYXNrID0gMTsKKyAgc3RhdGljIGNvbnN0IGludHB0cl90IGtQdHJWYWx1ZU1hc2sgPSB+a1B0clRhZ01hc2s7CisKKyAgLy8gQWNjZXNzb3JzIGZvciBwb2ludGVyIHRhZyBhbmQgcG9pbnRlciB2YWx1ZS4KKyAgR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FIGludCBQdHJUYWcoKSBjb25zdCB7CisgICAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8aW50cHRyX3Q+KHB0cl8pICYga1B0clRhZ01hc2s7CisgIH0KKworICB0ZW1wbGF0ZTx0eXBlbmFtZSBUPiBUKiBQdHJWYWx1ZSgpIGNvbnN0IHsKKyAgICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxUKj4oCisgICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8aW50cHRyX3Q+KHB0cl8pICYga1B0clZhbHVlTWFzayk7CisgIH0KKworICAvLyBJZiBwdHJfJ3MgdGFnIGlzIGtUYWdDb250YWluZXIsIGl0IHBvaW50cyB0byBhbiBpbnN0YW5jZSBvZiB0aGlzIHN0cnVjdC4KKyAgc3RydWN0IENvbnRhaW5lciB7CisgICAgVW5rbm93bkZpZWxkU2V0IHVua25vd25fZmllbGRzXzsKKyAgICBBcmVuYSogYXJlbmFfOworICB9OworCisgIEdPT0dMRV9BVFRSSUJVVEVfTk9JTkxJTkUgVW5rbm93bkZpZWxkU2V0KiBtdXRhYmxlX3Vua25vd25fZmllbGRzX3Nsb3coKSB7CisgICAgQXJlbmEqIG15X2FyZW5hID0gYXJlbmEoKTsKKyAgICBDb250YWluZXIqIGNvbnRhaW5lciA9IEFyZW5hOjpDcmVhdGU8Q29udGFpbmVyPihteV9hcmVuYSk7CisgICAgcHRyXyA9IHJlaW50ZXJwcmV0X2Nhc3Q8dm9pZCo+KAorICAgICAgICByZWludGVycHJldF9jYXN0PGludHB0cl90Pihjb250YWluZXIpIHwga1RhZ0NvbnRhaW5lcik7CisgICAgY29udGFpbmVyLT5hcmVuYV8gPSBteV9hcmVuYTsKKyAgICByZXR1cm4gJihjb250YWluZXItPnVua25vd25fZmllbGRzXyk7CisgIH0KK307CisKKy8vIFRlbXBvcmFyeSBjb21wYXRpYmlsaXR5IHR5cGVkZWYuIFJlbW92ZSBvbmNlIHRoaXMgaXMgcmVsZWFzZWQgaW4gY29tcG9uZW50cworLy8gYW5kIHVwYiBDTCBpcyBzdWJtaXR0ZWQuCit0eXBlZGVmIEludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEgSW50ZXJuYWxNZXRhZGF0YTsKKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfTUVUQURBVEFfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL25vX2ZpZWxkX3ByZXNlbmNlX3Rlc3QuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL25vX2ZpZWxkX3ByZXNlbmNlX3Rlc3QuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmM0MWJlZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvbm9fZmllbGRfcHJlc2VuY2VfdGVzdC5jYwpAQCAtMCwwICsxLDU3NyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fZmllbGRfcHJlc2VuY2UucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIHsKKworLy8gSGVscGVyOiBjaGVja3MgdGhhdCBhbGwgZmllbGRzIGhhdmUgZGVmYXVsdCAoemVyby9lbXB0eSkgdmFsdWVzLgordm9pZCBDaGVja0RlZmF1bHRWYWx1ZXMoCisgICAgY29uc3QgcHJvdG8yX25vZmllbGRwcmVzZW5jZV91bml0dGVzdDo6VGVzdEFsbFR5cGVzJiBtKSB7CisgIEVYUEVDVF9FUSgwLCBtLm9wdGlvbmFsX2ludDMyKCkpOworICBFWFBFQ1RfRVEoMCwgbS5vcHRpb25hbF9pbnQ2NCgpKTsKKyAgRVhQRUNUX0VRKDAsIG0ub3B0aW9uYWxfdWludDMyKCkpOworICBFWFBFQ1RfRVEoMCwgbS5vcHRpb25hbF91aW50NjQoKSk7CisgIEVYUEVDVF9FUSgwLCBtLm9wdGlvbmFsX3NpbnQzMigpKTsKKyAgRVhQRUNUX0VRKDAsIG0ub3B0aW9uYWxfc2ludDY0KCkpOworICBFWFBFQ1RfRVEoMCwgbS5vcHRpb25hbF9maXhlZDMyKCkpOworICBFWFBFQ1RfRVEoMCwgbS5vcHRpb25hbF9maXhlZDY0KCkpOworICBFWFBFQ1RfRVEoMCwgbS5vcHRpb25hbF9zZml4ZWQzMigpKTsKKyAgRVhQRUNUX0VRKDAsIG0ub3B0aW9uYWxfc2ZpeGVkNjQoKSk7CisgIEVYUEVDVF9FUSgwLCBtLm9wdGlvbmFsX2Zsb2F0KCkpOworICBFWFBFQ1RfRVEoMCwgbS5vcHRpb25hbF9kb3VibGUoKSk7CisgIEVYUEVDVF9FUShmYWxzZSwgbS5vcHRpb25hbF9ib29sKCkpOworICBFWFBFQ1RfRVEoMCwgbS5vcHRpb25hbF9zdHJpbmcoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbS5vcHRpb25hbF9ieXRlcygpLnNpemUoKSk7CisKKyAgRVhQRUNUX0VRKGZhbHNlLCBtLmhhc19vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpKTsKKyAgLy8gYWNjZXNzb3IgZm9yIG1lc3NhZ2UgZmllbGRzIHJldHVybnMgZGVmYXVsdCBpbnN0YW5jZSB3aGVuIG5vdCBwcmVzZW50CisgIEVYUEVDVF9FUSgwLCBtLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCkuYmIoKSk7CisgIEVYUEVDVF9FUShmYWxzZSwgbS5oYXNfb3B0aW9uYWxfcHJvdG8yX21lc3NhZ2UoKSk7CisgIC8vIEVtYmVkZGVkIHByb3RvMiBtZXNzYWdlcyBzdGlsbCBoYXZlIHByb3RvMiBzZW1hbnRpY3MsIGUuZy4gbm9uLXplcm8gZGVmYXVsdAorICAvLyB2YWx1ZXMuIEhlcmUgdGhlIHN1Ym1lc3NhZ2UgaXMgbm90IHByZXNlbnQgYnV0IGl0cyBhY2Nlc3NvciByZXR1cm5zIHRoZQorICAvLyBkZWZhdWx0IGluc3RhbmNlLgorICBFWFBFQ1RfRVEoNDEsIG0ub3B0aW9uYWxfcHJvdG8yX21lc3NhZ2UoKS5kZWZhdWx0X2ludDMyKCkpOworICBFWFBFQ1RfRVEoZmFsc2UsIG0uaGFzX29wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSgpKTsKKyAgRVhQRUNUX0VRKHByb3RvMl9ub2ZpZWxkcHJlc2VuY2VfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlc19OZXN0ZWRFbnVtX0ZPTywKKyAgICAgICAgICAgIG0ub3B0aW9uYWxfbmVzdGVkX2VudW0oKSk7CisgIEVYUEVDVF9FUShwcm90bzJfbm9maWVsZHByZXNlbmNlX3VuaXR0ZXN0OjpGT1JFSUdOX0ZPTywKKyAgICAgICAgICAgIG0ub3B0aW9uYWxfZm9yZWlnbl9lbnVtKCkpOworCisKKyAgRVhQRUNUX0VRKDAsIG0ucmVwZWF0ZWRfaW50MzJfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG0ucmVwZWF0ZWRfaW50NjRfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG0ucmVwZWF0ZWRfdWludDMyX3NpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBtLnJlcGVhdGVkX3VpbnQ2NF9zaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbS5yZXBlYXRlZF9zaW50MzJfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG0ucmVwZWF0ZWRfc2ludDY0X3NpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBtLnJlcGVhdGVkX2ZpeGVkMzJfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG0ucmVwZWF0ZWRfZml4ZWQ2NF9zaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbS5yZXBlYXRlZF9zZml4ZWQzMl9zaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbS5yZXBlYXRlZF9zZml4ZWQ2NF9zaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbS5yZXBlYXRlZF9mbG9hdF9zaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbS5yZXBlYXRlZF9kb3VibGVfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG0ucmVwZWF0ZWRfYm9vbF9zaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbS5yZXBlYXRlZF9zdHJpbmdfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG0ucmVwZWF0ZWRfYnl0ZXNfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG0ucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2Vfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG0ucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX3NpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBtLnJlcGVhdGVkX3Byb3RvMl9tZXNzYWdlX3NpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBtLnJlcGVhdGVkX25lc3RlZF9lbnVtX3NpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBtLnJlcGVhdGVkX2ZvcmVpZ25fZW51bV9zaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbS5yZXBlYXRlZF9sYXp5X21lc3NhZ2Vfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKHByb3RvMl9ub2ZpZWxkcHJlc2VuY2VfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6T05FT0ZfRklFTERfTk9UX1NFVCwKKyAgICAgICAgICAgIG0ub25lb2ZfZmllbGRfY2FzZSgpKTsKK30KKwordm9pZCBGaWxsVmFsdWVzKHByb3RvMl9ub2ZpZWxkcHJlc2VuY2VfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyogbSkgeworICBtLT5zZXRfb3B0aW9uYWxfaW50MzIoMTAwKTsKKyAgbS0+c2V0X29wdGlvbmFsX2ludDY0KDEwMSk7CisgIG0tPnNldF9vcHRpb25hbF91aW50MzIoMTAyKTsKKyAgbS0+c2V0X29wdGlvbmFsX3VpbnQ2NCgxMDMpOworICBtLT5zZXRfb3B0aW9uYWxfc2ludDMyKDEwNCk7CisgIG0tPnNldF9vcHRpb25hbF9zaW50NjQoMTA1KTsKKyAgbS0+c2V0X29wdGlvbmFsX2ZpeGVkMzIoMTA2KTsKKyAgbS0+c2V0X29wdGlvbmFsX2ZpeGVkNjQoMTA3KTsKKyAgbS0+c2V0X29wdGlvbmFsX3NmaXhlZDMyKDEwOCk7CisgIG0tPnNldF9vcHRpb25hbF9zZml4ZWQ2NCgxMDkpOworICBtLT5zZXRfb3B0aW9uYWxfZmxvYXQoMTEwLjApOworICBtLT5zZXRfb3B0aW9uYWxfZG91YmxlKDExMS4wKTsKKyAgbS0+c2V0X29wdGlvbmFsX2Jvb2wodHJ1ZSk7CisgIG0tPnNldF9vcHRpb25hbF9zdHJpbmcoImFzZGYiKTsKKyAgbS0+c2V0X29wdGlvbmFsX2J5dGVzKCJqa2w7Iik7CisgIG0tPm11dGFibGVfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKS0+c2V0X2JiKDQyKTsKKyAgbS0+bXV0YWJsZV9vcHRpb25hbF9mb3JlaWduX21lc3NhZ2UoKS0+c2V0X2MoNDMpOworICBtLT5tdXRhYmxlX29wdGlvbmFsX3Byb3RvMl9tZXNzYWdlKCktPnNldF9vcHRpb25hbF9pbnQzMig0NCk7CisgIG0tPnNldF9vcHRpb25hbF9uZXN0ZWRfZW51bSgKKyAgICAgIHByb3RvMl9ub2ZpZWxkcHJlc2VuY2VfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlc19OZXN0ZWRFbnVtX0JBWik7CisgIG0tPnNldF9vcHRpb25hbF9mb3JlaWduX2VudW0oCisgICAgICBwcm90bzJfbm9maWVsZHByZXNlbmNlX3VuaXR0ZXN0OjpGT1JFSUdOX0JBWik7CisgIG0tPm11dGFibGVfb3B0aW9uYWxfbGF6eV9tZXNzYWdlKCktPnNldF9iYig0NSk7CisgIG0tPmFkZF9yZXBlYXRlZF9pbnQzMigxMDApOworICBtLT5hZGRfcmVwZWF0ZWRfaW50NjQoMTAxKTsKKyAgbS0+YWRkX3JlcGVhdGVkX3VpbnQzMigxMDIpOworICBtLT5hZGRfcmVwZWF0ZWRfdWludDY0KDEwMyk7CisgIG0tPmFkZF9yZXBlYXRlZF9zaW50MzIoMTA0KTsKKyAgbS0+YWRkX3JlcGVhdGVkX3NpbnQ2NCgxMDUpOworICBtLT5hZGRfcmVwZWF0ZWRfZml4ZWQzMigxMDYpOworICBtLT5hZGRfcmVwZWF0ZWRfZml4ZWQ2NCgxMDcpOworICBtLT5hZGRfcmVwZWF0ZWRfc2ZpeGVkMzIoMTA4KTsKKyAgbS0+YWRkX3JlcGVhdGVkX3NmaXhlZDY0KDEwOSk7CisgIG0tPmFkZF9yZXBlYXRlZF9mbG9hdCgxMTAuMCk7CisgIG0tPmFkZF9yZXBlYXRlZF9kb3VibGUoMTExLjApOworICBtLT5hZGRfcmVwZWF0ZWRfYm9vbCh0cnVlKTsKKyAgbS0+YWRkX3JlcGVhdGVkX3N0cmluZygiYXNkZiIpOworICBtLT5hZGRfcmVwZWF0ZWRfYnl0ZXMoImprbDsiKTsKKyAgbS0+YWRkX3JlcGVhdGVkX25lc3RlZF9tZXNzYWdlKCktPnNldF9iYig0Nik7CisgIG0tPmFkZF9yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UoKS0+c2V0X2MoNDcpOworICBtLT5hZGRfcmVwZWF0ZWRfcHJvdG8yX21lc3NhZ2UoKS0+c2V0X29wdGlvbmFsX2ludDMyKDQ4KTsKKyAgbS0+YWRkX3JlcGVhdGVkX25lc3RlZF9lbnVtKAorICAgICAgcHJvdG8yX25vZmllbGRwcmVzZW5jZV91bml0dGVzdDo6VGVzdEFsbFR5cGVzX05lc3RlZEVudW1fQkFaKTsKKyAgbS0+YWRkX3JlcGVhdGVkX2ZvcmVpZ25fZW51bSgKKyAgICAgIHByb3RvMl9ub2ZpZWxkcHJlc2VuY2VfdW5pdHRlc3Q6OkZPUkVJR05fQkFaKTsKKyAgbS0+YWRkX3JlcGVhdGVkX2xhenlfbWVzc2FnZSgpLT5zZXRfYmIoNDkpOworCisgIG0tPnNldF9vbmVvZl91aW50MzIoMSk7CisgIG0tPm11dGFibGVfb25lb2ZfbmVzdGVkX21lc3NhZ2UoKS0+c2V0X2JiKDUwKTsKKyAgbS0+c2V0X29uZW9mX3N0cmluZygidGVzdCIpOyAgLy8gb25seSB0aGlzIG9uZSByZW1haW5zIHNldAorfQorCit2b2lkIENoZWNrTm9uRGVmYXVsdFZhbHVlcygKK2NvbnN0IHByb3RvMl9ub2ZpZWxkcHJlc2VuY2VfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyYgbSkgeworICBFWFBFQ1RfRVEoMTAwLCBtLm9wdGlvbmFsX2ludDMyKCkpOworICBFWFBFQ1RfRVEoMTAxLCBtLm9wdGlvbmFsX2ludDY0KCkpOworICBFWFBFQ1RfRVEoMTAyLCBtLm9wdGlvbmFsX3VpbnQzMigpKTsKKyAgRVhQRUNUX0VRKDEwMywgbS5vcHRpb25hbF91aW50NjQoKSk7CisgIEVYUEVDVF9FUSgxMDQsIG0ub3B0aW9uYWxfc2ludDMyKCkpOworICBFWFBFQ1RfRVEoMTA1LCBtLm9wdGlvbmFsX3NpbnQ2NCgpKTsKKyAgRVhQRUNUX0VRKDEwNiwgbS5vcHRpb25hbF9maXhlZDMyKCkpOworICBFWFBFQ1RfRVEoMTA3LCBtLm9wdGlvbmFsX2ZpeGVkNjQoKSk7CisgIEVYUEVDVF9FUSgxMDgsIG0ub3B0aW9uYWxfc2ZpeGVkMzIoKSk7CisgIEVYUEVDVF9FUSgxMDksIG0ub3B0aW9uYWxfc2ZpeGVkNjQoKSk7CisgIEVYUEVDVF9FUSgxMTAuMCwgbS5vcHRpb25hbF9mbG9hdCgpKTsKKyAgRVhQRUNUX0VRKDExMS4wLCBtLm9wdGlvbmFsX2RvdWJsZSgpKTsKKyAgRVhQRUNUX0VRKHRydWUsIG0ub3B0aW9uYWxfYm9vbCgpKTsKKyAgRVhQRUNUX0VRKCJhc2RmIiwgbS5vcHRpb25hbF9zdHJpbmcoKSk7CisgIEVYUEVDVF9FUSgiamtsOyIsIG0ub3B0aW9uYWxfYnl0ZXMoKSk7CisgIEVYUEVDVF9FUSh0cnVlLCBtLmhhc19vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpKTsKKyAgRVhQRUNUX0VRKDQyLCBtLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCkuYmIoKSk7CisgIEVYUEVDVF9FUSh0cnVlLCBtLmhhc19vcHRpb25hbF9mb3JlaWduX21lc3NhZ2UoKSk7CisgIEVYUEVDVF9FUSg0MywgbS5vcHRpb25hbF9mb3JlaWduX21lc3NhZ2UoKS5jKCkpOworICBFWFBFQ1RfRVEodHJ1ZSwgbS5oYXNfb3B0aW9uYWxfcHJvdG8yX21lc3NhZ2UoKSk7CisgIEVYUEVDVF9FUSg0NCwgbS5vcHRpb25hbF9wcm90bzJfbWVzc2FnZSgpLm9wdGlvbmFsX2ludDMyKCkpOworICBFWFBFQ1RfRVEocHJvdG8yX25vZmllbGRwcmVzZW5jZV91bml0dGVzdDo6VGVzdEFsbFR5cGVzX05lc3RlZEVudW1fQkFaLAorICAgICAgICAgICAgbS5vcHRpb25hbF9uZXN0ZWRfZW51bSgpKTsKKyAgRVhQRUNUX0VRKHByb3RvMl9ub2ZpZWxkcHJlc2VuY2VfdW5pdHRlc3Q6OkZPUkVJR05fQkFaLAorICAgICAgICAgICAgbS5vcHRpb25hbF9mb3JlaWduX2VudW0oKSk7CisgIEVYUEVDVF9FUSh0cnVlLCBtLmhhc19vcHRpb25hbF9sYXp5X21lc3NhZ2UoKSk7CisgIEVYUEVDVF9FUSg0NSwgbS5vcHRpb25hbF9sYXp5X21lc3NhZ2UoKS5iYigpKTsKKworICBFWFBFQ1RfRVEoMSwgbS5yZXBlYXRlZF9pbnQzMl9zaXplKCkpOworICBFWFBFQ1RfRVEoMTAwLCBtLnJlcGVhdGVkX2ludDMyKDApKTsKKyAgRVhQRUNUX0VRKDEsIG0ucmVwZWF0ZWRfaW50NjRfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEwMSwgbS5yZXBlYXRlZF9pbnQ2NCgwKSk7CisgIEVYUEVDVF9FUSgxLCBtLnJlcGVhdGVkX3VpbnQzMl9zaXplKCkpOworICBFWFBFQ1RfRVEoMTAyLCBtLnJlcGVhdGVkX3VpbnQzMigwKSk7CisgIEVYUEVDVF9FUSgxLCBtLnJlcGVhdGVkX3VpbnQ2NF9zaXplKCkpOworICBFWFBFQ1RfRVEoMTAzLCBtLnJlcGVhdGVkX3VpbnQ2NCgwKSk7CisgIEVYUEVDVF9FUSgxLCBtLnJlcGVhdGVkX3NpbnQzMl9zaXplKCkpOworICBFWFBFQ1RfRVEoMTA0LCBtLnJlcGVhdGVkX3NpbnQzMigwKSk7CisgIEVYUEVDVF9FUSgxLCBtLnJlcGVhdGVkX3NpbnQ2NF9zaXplKCkpOworICBFWFBFQ1RfRVEoMTA1LCBtLnJlcGVhdGVkX3NpbnQ2NCgwKSk7CisgIEVYUEVDVF9FUSgxLCBtLnJlcGVhdGVkX2ZpeGVkMzJfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEwNiwgbS5yZXBlYXRlZF9maXhlZDMyKDApKTsKKyAgRVhQRUNUX0VRKDEsIG0ucmVwZWF0ZWRfZml4ZWQ2NF9zaXplKCkpOworICBFWFBFQ1RfRVEoMTA3LCBtLnJlcGVhdGVkX2ZpeGVkNjQoMCkpOworICBFWFBFQ1RfRVEoMSwgbS5yZXBlYXRlZF9zZml4ZWQzMl9zaXplKCkpOworICBFWFBFQ1RfRVEoMTA4LCBtLnJlcGVhdGVkX3NmaXhlZDMyKDApKTsKKyAgRVhQRUNUX0VRKDEsIG0ucmVwZWF0ZWRfc2ZpeGVkNjRfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEwOSwgbS5yZXBlYXRlZF9zZml4ZWQ2NCgwKSk7CisgIEVYUEVDVF9FUSgxLCBtLnJlcGVhdGVkX2Zsb2F0X3NpemUoKSk7CisgIEVYUEVDVF9FUSgxMTAuMCwgbS5yZXBlYXRlZF9mbG9hdCgwKSk7CisgIEVYUEVDVF9FUSgxLCBtLnJlcGVhdGVkX2RvdWJsZV9zaXplKCkpOworICBFWFBFQ1RfRVEoMTExLjAsIG0ucmVwZWF0ZWRfZG91YmxlKDApKTsKKyAgRVhQRUNUX0VRKDEsIG0ucmVwZWF0ZWRfYm9vbF9zaXplKCkpOworICBFWFBFQ1RfRVEodHJ1ZSwgbS5yZXBlYXRlZF9ib29sKDApKTsKKyAgRVhQRUNUX0VRKDEsIG0ucmVwZWF0ZWRfc3RyaW5nX3NpemUoKSk7CisgIEVYUEVDVF9FUSgiYXNkZiIsIG0ucmVwZWF0ZWRfc3RyaW5nKDApKTsKKyAgRVhQRUNUX0VRKDEsIG0ucmVwZWF0ZWRfYnl0ZXNfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKCJqa2w7IiwgbS5yZXBlYXRlZF9ieXRlcygwKSk7CisgIEVYUEVDVF9FUSgxLCBtLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX3NpemUoKSk7CisgIEVYUEVDVF9FUSg0NiwgbS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSgwKS5iYigpKTsKKyAgRVhQRUNUX0VRKDEsIG0ucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX3NpemUoKSk7CisgIEVYUEVDVF9FUSg0NywgbS5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UoMCkuYygpKTsKKyAgRVhQRUNUX0VRKDEsIG0ucmVwZWF0ZWRfcHJvdG8yX21lc3NhZ2Vfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDQ4LCBtLnJlcGVhdGVkX3Byb3RvMl9tZXNzYWdlKDApLm9wdGlvbmFsX2ludDMyKCkpOworICBFWFBFQ1RfRVEoMSwgbS5yZXBlYXRlZF9uZXN0ZWRfZW51bV9zaXplKCkpOworICBFWFBFQ1RfRVEocHJvdG8yX25vZmllbGRwcmVzZW5jZV91bml0dGVzdDo6VGVzdEFsbFR5cGVzX05lc3RlZEVudW1fQkFaLAorICAgICAgICAgICAgbS5yZXBlYXRlZF9uZXN0ZWRfZW51bSgwKSk7CisgIEVYUEVDVF9FUSgxLCBtLnJlcGVhdGVkX2ZvcmVpZ25fZW51bV9zaXplKCkpOworICBFWFBFQ1RfRVEocHJvdG8yX25vZmllbGRwcmVzZW5jZV91bml0dGVzdDo6Rk9SRUlHTl9CQVosCisgICAgICAgICAgICBtLnJlcGVhdGVkX2ZvcmVpZ25fZW51bSgwKSk7CisgIEVYUEVDVF9FUSgxLCBtLnJlcGVhdGVkX2xhenlfbWVzc2FnZV9zaXplKCkpOworICBFWFBFQ1RfRVEoNDksIG0ucmVwZWF0ZWRfbGF6eV9tZXNzYWdlKDApLmJiKCkpOworCisgIEVYUEVDVF9FUShwcm90bzJfbm9maWVsZHByZXNlbmNlX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OmtPbmVvZlN0cmluZywKKyAgICAgICAgICAgIG0ub25lb2ZfZmllbGRfY2FzZSgpKTsKKyAgRVhQRUNUX0VRKCJ0ZXN0IiwgbS5vbmVvZl9zdHJpbmcoKSk7Cit9CisKK1RFU1QoTm9GaWVsZFByZXNlbmNlVGVzdCwgQmFzaWNNZXNzYWdlVGVzdCkgeworICBwcm90bzJfbm9maWVsZHByZXNlbmNlX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKyAgLy8gQ2hlY2sgZGVmYXVsdCB2YWx1ZXMsIGZpbGwgYWxsIGZpZWxkcywgY2hlY2sgdmFsdWVzLiBXZSBqdXN0IHdhbnQgdG8KKyAgLy8gZXhlcmNpc2UgdGhlIGJhc2ljIGdldHRlcnMvc2V0dGVyIHBhdGhzIGhlcmUgdG8gbWFrZSBzdXJlIG5vCisgIC8vIGZpZWxkLXByZXNlbmNlLXJlbGF0ZWQgY2hhbmdlcyBicm9rZSB0aGVzZS4KKyAgQ2hlY2tEZWZhdWx0VmFsdWVzKG1lc3NhZ2UpOworICBGaWxsVmFsdWVzKCZtZXNzYWdlKTsKKyAgQ2hlY2tOb25EZWZhdWx0VmFsdWVzKG1lc3NhZ2UpOworCisgIC8vIENsZWFyKCkgc2hvdWxkIGJlIGVxdWl2YWxlbnQgdG8gZ2V0dGluZyBhIGZyZXNobHktY29uc3RydWN0ZWQgbWVzc2FnZS4KKyAgbWVzc2FnZS5DbGVhcigpOworICBDaGVja0RlZmF1bHRWYWx1ZXMobWVzc2FnZSk7Cit9CisKK1RFU1QoTm9GaWVsZFByZXNlbmNlVGVzdCwgTWVzc2FnZUZpZWxkUHJlc2VuY2VUZXN0KSB7CisgIC8vIGNoZWNrIHRoYXQgcHJlc2VuY2Ugc3RpbGwgd29ya3MgcHJvcGVybHkgZm9yIG1lc3NhZ2UgZmllbGRzLgorICBwcm90bzJfbm9maWVsZHByZXNlbmNlX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKyAgRVhQRUNUX0VRKGZhbHNlLCBtZXNzYWdlLmhhc19vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpKTsKKyAgLy8gR2V0dGVyIHNob3VsZCBmZXRjaCBkZWZhdWx0IGluc3RhbmNlLCBhbmQgbm90IGNhdXNlIHRoZSBmaWVsZCB0byBiZWNvbWUKKyAgLy8gcHJlc2VudC4KKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2Uub3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKS5iYigpKTsKKyAgRVhQRUNUX0VRKGZhbHNlLCBtZXNzYWdlLmhhc19vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpKTsKKyAgbWVzc2FnZS5tdXRhYmxlX29wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCktPnNldF9iYig0Mik7CisgIEVYUEVDVF9FUSh0cnVlLCBtZXNzYWdlLmhhc19vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpKTsKKyAgbWVzc2FnZS5jbGVhcl9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpOworICBFWFBFQ1RfRVEoZmFsc2UsIG1lc3NhZ2UuaGFzX29wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCkpOworCisgIC8vIExpa2V3aXNlIGZvciBhIGxhenkgbWVzc2FnZSBmaWVsZC4KKyAgRVhQRUNUX0VRKGZhbHNlLCBtZXNzYWdlLmhhc19vcHRpb25hbF9sYXp5X21lc3NhZ2UoKSk7CisgIC8vIEdldHRlciBzaG91bGQgZmV0Y2ggZGVmYXVsdCBpbnN0YW5jZSwgYW5kIG5vdCBjYXVzZSB0aGUgZmllbGQgdG8gYmVjb21lCisgIC8vIHByZXNlbnQuCisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm9wdGlvbmFsX2xhenlfbWVzc2FnZSgpLmJiKCkpOworICBFWFBFQ1RfRVEoZmFsc2UsIG1lc3NhZ2UuaGFzX29wdGlvbmFsX2xhenlfbWVzc2FnZSgpKTsKKyAgbWVzc2FnZS5tdXRhYmxlX29wdGlvbmFsX2xhenlfbWVzc2FnZSgpLT5zZXRfYmIoNDIpOworICBFWFBFQ1RfRVEodHJ1ZSwgbWVzc2FnZS5oYXNfb3B0aW9uYWxfbGF6eV9tZXNzYWdlKCkpOworICBtZXNzYWdlLmNsZWFyX29wdGlvbmFsX2xhenlfbWVzc2FnZSgpOworICBFWFBFQ1RfRVEoZmFsc2UsIG1lc3NhZ2UuaGFzX29wdGlvbmFsX2xhenlfbWVzc2FnZSgpKTsKKworICAvLyBUZXN0IGZpZWxkIHByZXNlbmNlIG9mIGEgbWVzc2FnZSBmaWVsZCBvbiB0aGUgZGVmYXVsdCBpbnN0YW5jZS4KKyAgRVhQRUNUX0VRKGZhbHNlLCBwcm90bzJfbm9maWVsZHByZXNlbmNlX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OgorICAgICAgICAgICAgZGVmYXVsdF9pbnN0YW5jZSgpLmhhc19vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpKTsKK30KKworVEVTVChOb0ZpZWxkUHJlc2VuY2VUZXN0LCBSZWZsZWN0aW9uSGFzRmllbGRUZXN0KSB7CisgIC8vIGNoZWNrIHRoYXQgSGFzRmllbGQgcmVwb3J0cyB0cnVlIG9uIGFsbCBzY2FsYXIgZmllbGRzLiBDaGVjayB0aGF0IGl0CisgIC8vIGJlaGF2ZXMgcHJvcGVybHkgZm9yIG1lc3NhZ2UgZmllbGRzLgorCisgIHByb3RvMl9ub2ZpZWxkcHJlc2VuY2VfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlOworICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpSZWZsZWN0aW9uKiByID0gbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCk7CisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIGRlc2MgPSBtZXNzYWdlLkdldERlc2NyaXB0b3IoKTsKKworICAvLyBDaGVjayBpbml0aWFsIHN0YXRlOiBzY2FsYXJzIG5vdCBwcmVzZW50IChkdWUgdG8gbmVlZCB0byBiZSBjb25zaXN0ZW50IHdpdGgKKyAgLy8gTWVyZ2VGcm9tKCkpLCBtZXNzYWdlIGZpZWxkcyBub3QgcHJlc2VudCwgb25lb2ZzIG5vdCBwcmVzZW50LgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2MtPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBkZXNjLT5maWVsZChpKTsKKyAgICBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkpIGNvbnRpbnVlOworICAgIEVYUEVDVF9FUShmYWxzZSwgci0+SGFzRmllbGQobWVzc2FnZSwgZmllbGQpKTsKKyAgfQorCisgIC8vIFRlc3QgZmllbGQgcHJlc2VuY2Ugb2YgYSBtZXNzYWdlIGZpZWxkIG9uIHRoZSBkZWZhdWx0IGluc3RhbmNlLgorICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3IqIG1zZ19maWVsZCA9CisgICAgICBkZXNjLT5GaW5kRmllbGRCeU5hbWUoIm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlIik7CisgIEVYUEVDVF9FUShmYWxzZSwgci0+SGFzRmllbGQoCisgICAgICBwcm90bzJfbm9maWVsZHByZXNlbmNlX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OgorICAgICAgZGVmYXVsdF9pbnN0YW5jZSgpLCBtc2dfZmllbGQpKTsKKworICAvLyBGaWxsIGFsbCBmaWVsZHMsIGV4cGVjdCBldmVyeXRoaW5nIHRvIHJlcG9ydCB0cnVlIChjaGVjayBvbmVvZnMgYmVsb3cpLgorICBGaWxsVmFsdWVzKCZtZXNzYWdlKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzYy0+ZmllbGQoaSk7CisgICAgaWYgKGZpZWxkLT5pc19yZXBlYXRlZCgpIHx8IGZpZWxkLT5jb250YWluaW5nX29uZW9mKCkpIHsKKyAgICAgIGNvbnRpbnVlOworICAgIH0KKyAgICBpZiAoZmllbGQtPm9wdGlvbnMoKS5jdHlwZSgpICE9IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkT3B0aW9uczo6U1RSSU5HKSB7CisgICAgICBjb250aW51ZTsKKyAgICB9CisgICAgRVhQRUNUX0VRKHRydWUsIHItPkhhc0ZpZWxkKG1lc3NhZ2UsIGZpZWxkKSk7CisgIH0KKworICBtZXNzYWdlLkNsZWFyKCk7CisKKyAgLy8gQ2hlY2sgemVyby9lbXB0eS1tZWFucy1ub3QtcHJlc2VudCBzZW1hbnRpY3MuCisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvciogZmllbGRfaW50MzIgPSBkZXNjLT5GaW5kRmllbGRCeU5hbWUoCisgICAgICAib3B0aW9uYWxfaW50MzIiKTsKKyAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yKiBmaWVsZF9kb3VibGUgPSBkZXNjLT5GaW5kRmllbGRCeU5hbWUoCisgICAgICAib3B0aW9uYWxfZG91YmxlIik7CisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvciogZmllbGRfc3RyaW5nID0gZGVzYy0+RmluZEZpZWxkQnlOYW1lKAorICAgICAgIm9wdGlvbmFsX3N0cmluZyIpOworCisgIEVYUEVDVF9FUShmYWxzZSwgci0+SGFzRmllbGQobWVzc2FnZSwgZmllbGRfaW50MzIpKTsKKyAgRVhQRUNUX0VRKGZhbHNlLCByLT5IYXNGaWVsZChtZXNzYWdlLCBmaWVsZF9kb3VibGUpKTsKKyAgRVhQRUNUX0VRKGZhbHNlLCByLT5IYXNGaWVsZChtZXNzYWdlLCBmaWVsZF9zdHJpbmcpKTsKKworICBtZXNzYWdlLnNldF9vcHRpb25hbF9pbnQzMig0Mik7CisgIEVYUEVDVF9FUSh0cnVlLCByLT5IYXNGaWVsZChtZXNzYWdlLCBmaWVsZF9pbnQzMikpOworICBtZXNzYWdlLnNldF9vcHRpb25hbF9pbnQzMigwKTsKKyAgRVhQRUNUX0VRKGZhbHNlLCByLT5IYXNGaWVsZChtZXNzYWdlLCBmaWVsZF9pbnQzMikpOworCisgIG1lc3NhZ2Uuc2V0X29wdGlvbmFsX2RvdWJsZSg0Mi4wKTsKKyAgRVhQRUNUX0VRKHRydWUsIHItPkhhc0ZpZWxkKG1lc3NhZ2UsIGZpZWxkX2RvdWJsZSkpOworICBtZXNzYWdlLnNldF9vcHRpb25hbF9kb3VibGUoMC4wKTsKKyAgRVhQRUNUX0VRKGZhbHNlLCByLT5IYXNGaWVsZChtZXNzYWdlLCBmaWVsZF9kb3VibGUpKTsKKworICBtZXNzYWdlLnNldF9vcHRpb25hbF9zdHJpbmcoInRlc3QiKTsKKyAgRVhQRUNUX0VRKHRydWUsIHItPkhhc0ZpZWxkKG1lc3NhZ2UsIGZpZWxkX3N0cmluZykpOworICBtZXNzYWdlLnNldF9vcHRpb25hbF9zdHJpbmcoIiIpOworICBFWFBFQ1RfRVEoZmFsc2UsIHItPkhhc0ZpZWxkKG1lc3NhZ2UsIGZpZWxkX3N0cmluZykpOworfQorCitURVNUKE5vRmllbGRQcmVzZW5jZVRlc3QsIFJlZmxlY3Rpb25DbGVhckZpZWxkVGVzdCkgeworICBwcm90bzJfbm9maWVsZHByZXNlbmNlX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKworICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpSZWZsZWN0aW9uKiByID0gbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCk7CisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIGRlc2MgPSBtZXNzYWdlLkdldERlc2NyaXB0b3IoKTsKKworICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3IqIGZpZWxkX2ludDMyID0gZGVzYy0+RmluZEZpZWxkQnlOYW1lKAorICAgICAgIm9wdGlvbmFsX2ludDMyIik7CisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvciogZmllbGRfZG91YmxlID0gZGVzYy0+RmluZEZpZWxkQnlOYW1lKAorICAgICAgIm9wdGlvbmFsX2RvdWJsZSIpOworICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3IqIGZpZWxkX3N0cmluZyA9IGRlc2MtPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICJvcHRpb25hbF9zdHJpbmciKTsKKyAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yKiBmaWVsZF9tZXNzYWdlID0gZGVzYy0+RmluZEZpZWxkQnlOYW1lKAorICAgICAgIm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlIik7CisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvciogZmllbGRfbGF6eSA9IGRlc2MtPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICJvcHRpb25hbF9sYXp5X21lc3NhZ2UiKTsKKworICBtZXNzYWdlLnNldF9vcHRpb25hbF9pbnQzMig0Mik7CisgIHItPkNsZWFyRmllbGQoJm1lc3NhZ2UsIGZpZWxkX2ludDMyKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2Uub3B0aW9uYWxfaW50MzIoKSk7CisKKyAgbWVzc2FnZS5zZXRfb3B0aW9uYWxfZG91YmxlKDQyLjApOworICByLT5DbGVhckZpZWxkKCZtZXNzYWdlLCBmaWVsZF9kb3VibGUpOworICBFWFBFQ1RfRVEoMC4wLCBtZXNzYWdlLm9wdGlvbmFsX2RvdWJsZSgpKTsKKworICBtZXNzYWdlLnNldF9vcHRpb25hbF9zdHJpbmcoInRlc3QiKTsKKyAgci0+Q2xlYXJGaWVsZCgmbWVzc2FnZSwgZmllbGRfc3RyaW5nKTsKKyAgRVhQRUNUX0VRKCIiLCBtZXNzYWdlLm9wdGlvbmFsX3N0cmluZygpKTsKKworICBtZXNzYWdlLm11dGFibGVfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKS0+c2V0X2JiKDEyMzQpOworICByLT5DbGVhckZpZWxkKCZtZXNzYWdlLCBmaWVsZF9tZXNzYWdlKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpLmJiKCkpOworCisgIG1lc3NhZ2UubXV0YWJsZV9vcHRpb25hbF9sYXp5X21lc3NhZ2UoKS0+c2V0X2JiKDQyKTsKKyAgci0+Q2xlYXJGaWVsZCgmbWVzc2FnZSwgZmllbGRfbGF6eSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9sYXp5X21lc3NhZ2UoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm9wdGlvbmFsX2xhenlfbWVzc2FnZSgpLmJiKCkpOworfQorCitURVNUKE5vRmllbGRQcmVzZW5jZVRlc3QsIEhhc0ZpZWxkT25lb2ZzVGVzdCkgeworICAvLyBjaGVjayB0aGF0IEhhc0ZpZWxkIGJlaGF2ZXMgcHJvcGVybHkgZm9yIG9uZW9mcy4KKyAgcHJvdG8yX25vZmllbGRwcmVzZW5jZV91bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisKKyAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6UmVmbGVjdGlvbiogciA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpOworICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBkZXNjID0gbWVzc2FnZS5HZXREZXNjcmlwdG9yKCk7CisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvciogZGVzY19vbmVvZl91aW50MzIgPQorICAgICAgZGVzYy0+RmluZEZpZWxkQnlOYW1lKCJvbmVvZl91aW50MzIiKTsKKyAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yKiBkZXNjX29uZW9mX25lc3RlZF9tZXNzYWdlID0KKyAgICAgIGRlc2MtPkZpbmRGaWVsZEJ5TmFtZSgib25lb2ZfbmVzdGVkX21lc3NhZ2UiKTsKKyAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yKiBkZXNjX29uZW9mX3N0cmluZyA9CisgICAgICBkZXNjLT5GaW5kRmllbGRCeU5hbWUoIm9uZW9mX3N0cmluZyIpOworICBHT09HTEVfQ0hFQ0tfTk9UTlVMTChkZXNjX29uZW9mX3VpbnQzMik7CisgIEdPT0dMRV9DSEVDS19OT1ROVUxMKGRlc2Nfb25lb2ZfbmVzdGVkX21lc3NhZ2UpOworICBHT09HTEVfQ0hFQ0tfTk9UTlVMTChkZXNjX29uZW9mX3N0cmluZyk7CisKKyAgRVhQRUNUX0VRKGZhbHNlLCByLT5IYXNGaWVsZChtZXNzYWdlLCBkZXNjX29uZW9mX3VpbnQzMikpOworICBFWFBFQ1RfRVEoZmFsc2UsIHItPkhhc0ZpZWxkKG1lc3NhZ2UsIGRlc2Nfb25lb2ZfbmVzdGVkX21lc3NhZ2UpKTsKKyAgRVhQRUNUX0VRKGZhbHNlLCByLT5IYXNGaWVsZChtZXNzYWdlLCBkZXNjX29uZW9mX3N0cmluZykpOworCisgIG1lc3NhZ2Uuc2V0X29uZW9mX3N0cmluZygidGVzdCIpOworICBFWFBFQ1RfRVEoZmFsc2UsIHItPkhhc0ZpZWxkKG1lc3NhZ2UsIGRlc2Nfb25lb2ZfdWludDMyKSk7CisgIEVYUEVDVF9FUShmYWxzZSwgci0+SGFzRmllbGQobWVzc2FnZSwgZGVzY19vbmVvZl9uZXN0ZWRfbWVzc2FnZSkpOworICBFWFBFQ1RfRVEodHJ1ZSwgci0+SGFzRmllbGQobWVzc2FnZSwgZGVzY19vbmVvZl9zdHJpbmcpKTsKKyAgbWVzc2FnZS5tdXRhYmxlX29uZW9mX25lc3RlZF9tZXNzYWdlKCktPnNldF9iYig0Mik7CisgIEVYUEVDVF9FUShmYWxzZSwgci0+SGFzRmllbGQobWVzc2FnZSwgZGVzY19vbmVvZl91aW50MzIpKTsKKyAgRVhQRUNUX0VRKHRydWUsIHItPkhhc0ZpZWxkKG1lc3NhZ2UsIGRlc2Nfb25lb2ZfbmVzdGVkX21lc3NhZ2UpKTsKKyAgRVhQRUNUX0VRKGZhbHNlLCByLT5IYXNGaWVsZChtZXNzYWdlLCBkZXNjX29uZW9mX3N0cmluZykpOworCisgIG1lc3NhZ2UuQ2xlYXIoKTsKKyAgRVhQRUNUX0VRKGZhbHNlLCByLT5IYXNGaWVsZChtZXNzYWdlLCBkZXNjX29uZW9mX3VpbnQzMikpOworICBFWFBFQ1RfRVEoZmFsc2UsIHItPkhhc0ZpZWxkKG1lc3NhZ2UsIGRlc2Nfb25lb2ZfbmVzdGVkX21lc3NhZ2UpKTsKKyAgRVhQRUNUX0VRKGZhbHNlLCByLT5IYXNGaWVsZChtZXNzYWdlLCBkZXNjX29uZW9mX3N0cmluZykpOworfQorCitURVNUKE5vRmllbGRQcmVzZW5jZVRlc3QsIERvbnRTZXJpYWxpemVEZWZhdWx0VmFsdWVzVGVzdCkgeworICAvLyBjaGVjayB0aGF0IHNlcmlhbGl6ZWQgZGF0YSBjb250YWlucyBvbmx5IG5vbi16ZXJvIG51bWVyaWMgZmllbGRzL25vbi1lbXB0eQorICAvLyBzdHJpbmcvYnl0ZSBmaWVsZHMuCisgIHByb3RvMl9ub2ZpZWxkcHJlc2VuY2VfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlOworICBzdHJpbmcgb3V0cHV0OworCisgIC8vIEFsbCBkZWZhdWx0IHZhbHVlcyAtPiBubyBvdXRwdXQuCisgIG1lc3NhZ2UuU2VyaWFsaXplVG9TdHJpbmcoJm91dHB1dCk7CisgIEVYUEVDVF9FUSgwLCBvdXRwdXQuc2l6ZSgpKTsKKworICAvLyBaZXJvIHZhbHVlcyAtPiBzdGlsbCBubyBvdXRwdXQuCisgIG1lc3NhZ2Uuc2V0X29wdGlvbmFsX2ludDMyKDApOworICBtZXNzYWdlLnNldF9vcHRpb25hbF9pbnQ2NCgwKTsKKyAgbWVzc2FnZS5zZXRfb3B0aW9uYWxfdWludDMyKDApOworICBtZXNzYWdlLnNldF9vcHRpb25hbF91aW50NjQoMCk7CisgIG1lc3NhZ2Uuc2V0X29wdGlvbmFsX3NpbnQzMigwKTsKKyAgbWVzc2FnZS5zZXRfb3B0aW9uYWxfc2ludDY0KDApOworICBtZXNzYWdlLnNldF9vcHRpb25hbF9maXhlZDMyKDApOworICBtZXNzYWdlLnNldF9vcHRpb25hbF9maXhlZDY0KDApOworICBtZXNzYWdlLnNldF9vcHRpb25hbF9zZml4ZWQzMigwKTsKKyAgbWVzc2FnZS5zZXRfb3B0aW9uYWxfc2ZpeGVkNjQoMCk7CisgIG1lc3NhZ2Uuc2V0X29wdGlvbmFsX2Zsb2F0KDApOworICBtZXNzYWdlLnNldF9vcHRpb25hbF9kb3VibGUoMCk7CisgIG1lc3NhZ2Uuc2V0X29wdGlvbmFsX2Jvb2woMCk7CisgIG1lc3NhZ2Uuc2V0X29wdGlvbmFsX3N0cmluZygiIik7CisgIG1lc3NhZ2Uuc2V0X29wdGlvbmFsX2J5dGVzKCIiKTsKKyAgbWVzc2FnZS5zZXRfb3B0aW9uYWxfbmVzdGVkX2VudW0oCisgICAgICBwcm90bzJfbm9maWVsZHByZXNlbmNlX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXNfTmVzdGVkRW51bV9GT08pOyAgLy8gZmlyc3QgZW51bSBlbnRyeQorICBtZXNzYWdlLnNldF9vcHRpb25hbF9mb3JlaWduX2VudW0oCisgICAgICBwcm90bzJfbm9maWVsZHByZXNlbmNlX3VuaXR0ZXN0OjpGT1JFSUdOX0ZPTyk7ICAvLyBmaXJzdCBlbnVtIGVudHJ5CisKKyAgbWVzc2FnZS5TZXJpYWxpemVUb1N0cmluZygmb3V0cHV0KTsKKyAgRVhQRUNUX0VRKDAsIG91dHB1dC5zaXplKCkpOworCisgIG1lc3NhZ2Uuc2V0X29wdGlvbmFsX2ludDMyKDEpOworICBtZXNzYWdlLlNlcmlhbGl6ZVRvU3RyaW5nKCZvdXRwdXQpOworICBFWFBFQ1RfRVEoMiwgb3V0cHV0LnNpemUoKSk7CisgIEVYUEVDVF9FUSgiXHgwOFx4MDEiLCBvdXRwdXQpOworCisgIG1lc3NhZ2Uuc2V0X29wdGlvbmFsX2ludDMyKDApOworICBtZXNzYWdlLlNlcmlhbGl6ZVRvU3RyaW5nKCZvdXRwdXQpOworICBFWFBFQ1RfRVEoMCwgb3V0cHV0LnNpemUoKSk7Cit9CisKK1RFU1QoTm9GaWVsZFByZXNlbmNlVGVzdCwgTWVyZ2VGcm9tSWZOb256ZXJvVGVzdCkgeworICAvLyBjaGVjayB0aGF0IE1lcmdlRnJvbSBjb3BpZXMgaWYgbm9uemVyby9ub25kZWZhdWx0IG9ubHkuCisgIHByb3RvMl9ub2ZpZWxkcHJlc2VuY2VfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBzb3VyY2U7CisgIHByb3RvMl9ub2ZpZWxkcHJlc2VuY2VfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBkZXN0OworCisgIGRlc3Quc2V0X29wdGlvbmFsX2ludDMyKDQyKTsKKyAgZGVzdC5zZXRfb3B0aW9uYWxfc3RyaW5nKCJ0ZXN0Iik7CisgIHNvdXJjZS5zZXRfb3B0aW9uYWxfaW50MzIoMCk7CisgIHNvdXJjZS5zZXRfb3B0aW9uYWxfc3RyaW5nKCIiKTsKKyAgLy8gTWVyZ2VGcm9tKCkgY29waWVzIG9ubHkgaWYgcHJlc2VudCBpbiBzZXJpYWxpemF0aW9uLCBpLmUuLCBub24temVyby4KKyAgZGVzdC5NZXJnZUZyb20oc291cmNlKTsKKyAgRVhQRUNUX0VRKDQyLCBkZXN0Lm9wdGlvbmFsX2ludDMyKCkpOworICBFWFBFQ1RfRVEoInRlc3QiLCBkZXN0Lm9wdGlvbmFsX3N0cmluZygpKTsKKworICBzb3VyY2Uuc2V0X29wdGlvbmFsX2ludDMyKDg0KTsKKyAgc291cmNlLnNldF9vcHRpb25hbF9zdHJpbmcoInRlc3QyIik7CisgIGRlc3QuTWVyZ2VGcm9tKHNvdXJjZSk7CisgIEVYUEVDVF9FUSg4NCwgZGVzdC5vcHRpb25hbF9pbnQzMigpKTsKKyAgRVhQRUNUX0VRKCJ0ZXN0MiIsIGRlc3Qub3B0aW9uYWxfc3RyaW5nKCkpOworfQorCitURVNUKE5vRmllbGRQcmVzZW5jZVRlc3QsIElzSW5pdGlhbGl6ZWRUZXN0KSB7CisgIC8vIENoZWNrIHRoYXQgSXNJbml0aWFsaXplZCB3b3JrcyBwcm9wZXJseS4KKyAgcHJvdG8yX25vZmllbGRwcmVzZW5jZV91bml0dGVzdDo6VGVzdFByb3RvMlJlcXVpcmVkIG1lc3NhZ2U7CisKKyAgRVhQRUNUX0VRKHRydWUsIG1lc3NhZ2UuSXNJbml0aWFsaXplZCgpKTsKKyAgbWVzc2FnZS5tdXRhYmxlX3Byb3RvMigpLT5zZXRfYSgxKTsKKyAgRVhQRUNUX0VRKGZhbHNlLCBtZXNzYWdlLklzSW5pdGlhbGl6ZWQoKSk7CisgIG1lc3NhZ2UubXV0YWJsZV9wcm90bzIoKS0+c2V0X2IoMSk7CisgIEVYUEVDVF9FUShmYWxzZSwgbWVzc2FnZS5Jc0luaXRpYWxpemVkKCkpOworICBtZXNzYWdlLm11dGFibGVfcHJvdG8yKCktPnNldF9jKDEpOworICBFWFBFQ1RfRVEodHJ1ZSwgbWVzc2FnZS5Jc0luaXRpYWxpemVkKCkpOworfQorCitURVNUKE5vRmllbGRQcmVzZW5jZVRlc3QsIExhenlNZXNzYWdlRmllbGRIYXNCaXQpIHsKKyAgLy8gQ2hlY2sgdGhhdCBoYXMtYml0IGludGVyYWN0aW9uIHdpdGggbGF6eSBtZXNzYWdlIHdvcmtzIChoYXMtYml0IGJlZm9yZSBhbmQKKyAgLy8gYWZ0ZXIgbGF6eSBkZWNvZGUpLgorICBwcm90bzJfbm9maWVsZHByZXNlbmNlX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKyAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6UmVmbGVjdGlvbiogciA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpOworICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBkZXNjID0gbWVzc2FnZS5HZXREZXNjcmlwdG9yKCk7CisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBkZXNjLT5GaW5kRmllbGRCeU5hbWUoCisgICAgICAib3B0aW9uYWxfbGF6eV9tZXNzYWdlIik7CisgIEdPT0dMRV9DSEVDS19OT1ROVUxMKGZpZWxkKTsKKworICBFWFBFQ1RfRVEoZmFsc2UsIG1lc3NhZ2UuaGFzX29wdGlvbmFsX2xhenlfbWVzc2FnZSgpKTsKKyAgRVhQRUNUX0VRKGZhbHNlLCByLT5IYXNGaWVsZChtZXNzYWdlLCBmaWVsZCkpOworCisgIG1lc3NhZ2UubXV0YWJsZV9vcHRpb25hbF9sYXp5X21lc3NhZ2UoKS0+c2V0X2JiKDQyKTsKKyAgRVhQRUNUX0VRKHRydWUsIG1lc3NhZ2UuaGFzX29wdGlvbmFsX2xhenlfbWVzc2FnZSgpKTsKKyAgRVhQRUNUX0VRKHRydWUsIHItPkhhc0ZpZWxkKG1lc3NhZ2UsIGZpZWxkKSk7CisKKyAgLy8gU2VyaWFsaXplIGFuZCBwYXJzZSB3aXRoIGEgbmV3IG1lc3NhZ2Ugb2JqZWN0IHNvIHRoYXQgbGF6eSBmaWVsZCBvbiBuZXcKKyAgLy8gb2JqZWN0IGlzIGluIHVucGFyc2VkIHN0YXRlLgorICBzdHJpbmcgb3V0cHV0OworICBtZXNzYWdlLlNlcmlhbGl6ZVRvU3RyaW5nKCZvdXRwdXQpOworICBwcm90bzJfbm9maWVsZHByZXNlbmNlX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTI7CisgIG1lc3NhZ2UyLlBhcnNlRnJvbVN0cmluZyhvdXRwdXQpOworCisgIEVYUEVDVF9FUSh0cnVlLCBtZXNzYWdlMi5oYXNfb3B0aW9uYWxfbGF6eV9tZXNzYWdlKCkpOworICBFWFBFQ1RfRVEodHJ1ZSwgci0+SGFzRmllbGQobWVzc2FnZTIsIGZpZWxkKSk7CisKKyAgLy8gQWNjZXNzIGZpZWxkIHRvIGZvcmNlIGxhenkgcGFyc2UuCisgIEVYUEVDVF9FUSg0MiwgbWVzc2FnZS5vcHRpb25hbF9sYXp5X21lc3NhZ2UoKS5iYigpKTsKKyAgRVhQRUNUX0VRKHRydWUsIG1lc3NhZ2UyLmhhc19vcHRpb25hbF9sYXp5X21lc3NhZ2UoKSk7CisgIEVYUEVDVF9FUSh0cnVlLCByLT5IYXNGaWVsZChtZXNzYWdlMiwgZmllbGQpKTsKK30KKworVEVTVChOb0ZpZWxkUHJlc2VuY2VUZXN0LCBPbmVvZlByZXNlbmNlKSB7CisgIHByb3RvMl9ub2ZpZWxkcHJlc2VuY2VfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlOworICAvLyBvbmVvZiBmaWVsZHMgc3RpbGwgaGF2ZSBmaWVsZCBwcmVzZW5jZSAtLSBlbnN1cmUgdGhhdCB0aGlzIGdvZXMgb24gdGhlIHdpcmUKKyAgLy8gZXZlbiB0aG91Z2ggaXRzIHZhbHVlIGlzIHRoZSBlbXB0eSBzdHJpbmcuCisgIG1lc3NhZ2Uuc2V0X29uZW9mX3N0cmluZygiIik7CisgIHN0cmluZyBzZXJpYWxpemVkOworICBtZXNzYWdlLlNlcmlhbGl6ZVRvU3RyaW5nKCZzZXJpYWxpemVkKTsKKyAgLy8gVGFnOiAxMTMgLS0+IHRhZyBpcyAoMTEzIDw8IDMpIHwgMiAobGVuZ3RoIGRlbGltaXRlZCkgPSA5MDYKKyAgLy8gdmFyaW50OiAweDhhIDB4MDcKKyAgLy8gTGVuZ3RoOiAweDAwCisgIEVYUEVDVF9FUSgzLCBzZXJpYWxpemVkLnNpemUoKSk7CisgIEVYUEVDVF9FUShzdGF0aWNfY2FzdDxjaGFyPigweDhhKSwgc2VyaWFsaXplZC5hdCgwKSk7CisgIEVYUEVDVF9FUShzdGF0aWNfY2FzdDxjaGFyPigweDA3KSwgc2VyaWFsaXplZC5hdCgxKSk7CisgIEVYUEVDVF9FUShzdGF0aWNfY2FzdDxjaGFyPigweDAwKSwgc2VyaWFsaXplZC5hdCgyKSk7CisKKyAgbWVzc2FnZS5DbGVhcigpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhzZXJpYWxpemVkKSk7CisgIEVYUEVDVF9FUShwcm90bzJfbm9maWVsZHByZXNlbmNlX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OmtPbmVvZlN0cmluZywKKyAgICAgICAgICAgIG1lc3NhZ2Uub25lb2ZfZmllbGRfY2FzZSgpKTsKKworICAvLyBBbHNvIHRlc3QgaW50MzIgYW5kIGVudW0gZmllbGRzLgorICBtZXNzYWdlLkNsZWFyKCk7CisgIG1lc3NhZ2Uuc2V0X29uZW9mX3VpbnQzMigwKTsgIC8vIHdvdWxkIG5vdCBnbyBvbiB3aXJlIGlmIG9yZGluYXJ5IGZpZWxkLgorICBtZXNzYWdlLlNlcmlhbGl6ZVRvU3RyaW5nKCZzZXJpYWxpemVkKTsKKyAgRVhQRUNUX0VRKDMsIHNlcmlhbGl6ZWQuc2l6ZSgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoc2VyaWFsaXplZCkpOworICBFWFBFQ1RfRVEocHJvdG8yX25vZmllbGRwcmVzZW5jZV91bml0dGVzdDo6VGVzdEFsbFR5cGVzOjprT25lb2ZVaW50MzIsCisgICAgICAgICAgICBtZXNzYWdlLm9uZW9mX2ZpZWxkX2Nhc2UoKSk7CisKKyAgbWVzc2FnZS5DbGVhcigpOworICBtZXNzYWdlLnNldF9vbmVvZl9lbnVtKHByb3RvMl9ub2ZpZWxkcHJlc2VuY2VfdW5pdHRlc3Q6OgorICAgICAgICAgICAgICAgICAgICAgICAgIFRlc3RBbGxUeXBlc19OZXN0ZWRFbnVtX0ZPTyk7ICAvLyBkZWZhdWx0IHZhbHVlLgorICBtZXNzYWdlLlNlcmlhbGl6ZVRvU3RyaW5nKCZzZXJpYWxpemVkKTsKKyAgRVhQRUNUX0VRKDMsIHNlcmlhbGl6ZWQuc2l6ZSgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoc2VyaWFsaXplZCkpOworICBFWFBFQ1RfRVEocHJvdG8yX25vZmllbGRwcmVzZW5jZV91bml0dGVzdDo6VGVzdEFsbFR5cGVzOjprT25lb2ZFbnVtLAorICAgICAgICAgICAgbWVzc2FnZS5vbmVvZl9maWVsZF9jYXNlKCkpOworCisgIG1lc3NhZ2UuQ2xlYXIoKTsKKyAgbWVzc2FnZS5zZXRfb25lb2Zfc3RyaW5nKCJ0ZXN0Iik7CisgIG1lc3NhZ2UuY2xlYXJfb25lb2Zfc3RyaW5nKCk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkJ5dGVTaXplKCkpOworfQorCit9ICAvLyBuYW1lc3BhY2UKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3BhY2thZ2VfaW5mby5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9wYWNrYWdlX2luZm8uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45MzVlOTYzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9wYWNrYWdlX2luZm8uaApAQCAtMCwwICsxLDY0IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisvLworLy8gVGhpcyBmaWxlIGV4aXN0cyBzb2xlbHkgdG8gZG9jdW1lbnQgdGhlIGdvb2dsZTo6cHJvdG9idWYgbmFtZXNwYWNlLgorLy8gSXQgaXMgbm90IGNvbXBpbGVkIGludG8gYW55dGhpbmcsIGJ1dCBpdCBtYXkgYmUgcmVhZCBieSBhbiBhdXRvbWF0ZWQKKy8vIGRvY3VtZW50YXRpb24gZ2VuZXJhdG9yLgorCituYW1lc3BhY2UgZ29vZ2xlIHsKKworLy8gQ29yZSBjb21wb25lbnRzIG9mIHRoZSBQcm90b2NvbCBCdWZmZXJzIHJ1bnRpbWUgbGlicmFyeS4KKy8vCisvLyBUaGUgZmlsZXMgaW4gdGhpcyBwYWNrYWdlIHJlcHJlc2VudCB0aGUgY29yZSBvZiB0aGUgUHJvdG9jb2wgQnVmZmVyCisvLyBzeXN0ZW0uICBBbGwgb2YgdGhlbSBhcmUgcGFydCBvZiB0aGUgbGlicHJvdG9idWYgbGlicmFyeS4KKy8vCisvLyBBIG5vdGUgb24gdGhyZWFkLXNhZmV0eToKKy8vCisvLyBUaHJlYWQtc2FmZXR5IGluIHRoZSBQcm90b2NvbCBCdWZmZXIgbGlicmFyeSBmb2xsb3dzIGEgc2ltcGxlIHJ1bGU6CisvLyB1bmxlc3MgZXhwbGljaXRseSBub3RlZCBvdGhlcndpc2UsIGl0IGlzIGFsd2F5cyBzYWZlIHRvIHVzZSBhbiBvYmplY3QKKy8vIGZyb20gbXVsdGlwbGUgdGhyZWFkcyBzaW11bHRhbmVvdXNseSBhcyBsb25nIGFzIHRoZSBvYmplY3QgaXMgZGVjbGFyZWQKKy8vIGNvbnN0IGluIGFsbCB0aHJlYWRzIChvciwgaXQgaXMgb25seSB1c2VkIGluIHdheXMgdGhhdCB3b3VsZCBiZSBhbGxvd2VkCisvLyBpZiBpdCB3ZXJlIGRlY2xhcmVkIGNvbnN0KS4gIEhvd2V2ZXIsIGlmIGFuIG9iamVjdCBpcyBhY2Nlc3NlZCBpbiBvbmUKKy8vIHRocmVhZCBpbiBhIHdheSB0aGF0IHdvdWxkIG5vdCBiZSBhbGxvd2VkIGlmIGl0IHdlcmUgY29uc3QsIHRoZW4gaXQgaXMKKy8vIG5vdCBzYWZlIHRvIGFjY2VzcyB0aGF0IG9iamVjdCBpbiBhbnkgb3RoZXIgdGhyZWFkIHNpbXVsdGFuZW91c2x5LgorLy8KKy8vIFB1dCBzaW1wbHksIHJlYWQtb25seSBhY2Nlc3MgdG8gYW4gb2JqZWN0IGNhbiBoYXBwZW4gaW4gbXVsdGlwbGUgdGhyZWFkcworLy8gc2ltdWx0YW5lb3VzbHksIGJ1dCB3cml0ZSBhY2Nlc3MgY2FuIG9ubHkgaGFwcGVuIGluIGEgc2luZ2xlIHRocmVhZCBhdAorLy8gYSB0aW1lLgorLy8KKy8vIFRoZSBpbXBsZW1lbnRhdGlvbiBkb2VzIGNvbnRhaW4gc29tZSAiY29uc3QiIG1ldGhvZHMgd2hpY2ggYWN0dWFsbHkgbW9kaWZ5CisvLyB0aGUgb2JqZWN0IGJlaGluZCB0aGUgc2NlbmVzIC0tIGUuZy4sIHRvIGNhY2hlIHJlc3VsdHMgLS0gYnV0IGluIHRoZXNlIGNhc2VzCisvLyBtdXRleCBsb2NraW5nIGlzIHVzZWQgdG8gbWFrZSB0aGUgYWNjZXNzIHRocmVhZC1zYWZlLgorbmFtZXNwYWNlIHByb3RvYnVmIHt9Cit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3ByZXNlcnZlX3Vua25vd25fZW51bV90ZXN0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9wcmVzZXJ2ZV91bmtub3duX2VudW1fdGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNjczZThhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9wcmVzZXJ2ZV91bmtub3duX2VudW1fdGVzdC5jYwpAQCAtMCwwICsxLDI4OSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJlc2VydmVfdW5rbm93bl9lbnVtLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X3ByZXNlcnZlX3Vua25vd25fZW51bTIucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZHluYW1pY19tZXNzYWdlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxndGVzdC9ndGVzdC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgeworCit2b2lkIEZpbGxNZXNzYWdlKAorICAgIHByb3RvM19wcmVzZXJ2ZV91bmtub3duX2VudW1fdW5pdHRlc3Q6Ok15TWVzc2FnZVBsdXNFeHRyYSogbWVzc2FnZSkgeworICBtZXNzYWdlLT5zZXRfZSgKKyAgICAgIHByb3RvM19wcmVzZXJ2ZV91bmtub3duX2VudW1fdW5pdHRlc3Q6OkVfRVhUUkEpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfZSgKKyAgICAgIHByb3RvM19wcmVzZXJ2ZV91bmtub3duX2VudW1fdW5pdHRlc3Q6OkVfRVhUUkEpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfcGFja2VkX2UoCisgICAgICBwcm90bzNfcHJlc2VydmVfdW5rbm93bl9lbnVtX3VuaXR0ZXN0OjpFX0VYVFJBKTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX3BhY2tlZF91bmV4cGVjdGVkX2UoCisgICAgICBwcm90bzNfcHJlc2VydmVfdW5rbm93bl9lbnVtX3VuaXR0ZXN0OjpFX0VYVFJBKTsKKyAgbWVzc2FnZS0+c2V0X29uZW9mX2VfMSgKKyAgICAgIHByb3RvM19wcmVzZXJ2ZV91bmtub3duX2VudW1fdW5pdHRlc3Q6OkVfRVhUUkEpOworfQorCit2b2lkIENoZWNrTWVzc2FnZSgKKyAgICBjb25zdCBwcm90bzNfcHJlc2VydmVfdW5rbm93bl9lbnVtX3VuaXR0ZXN0OjpNeU1lc3NhZ2VQbHVzRXh0cmEmIG1lc3NhZ2UpIHsKKyAgRVhQRUNUX0VRKHByb3RvM19wcmVzZXJ2ZV91bmtub3duX2VudW1fdW5pdHRlc3Q6OkVfRVhUUkEsCisgICAgICAgICAgICBtZXNzYWdlLmUoKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX2Vfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKHByb3RvM19wcmVzZXJ2ZV91bmtub3duX2VudW1fdW5pdHRlc3Q6OkVfRVhUUkEsCisgICAgICAgICAgICBtZXNzYWdlLnJlcGVhdGVkX2UoMCkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5yZXBlYXRlZF9wYWNrZWRfZV9zaXplKCkpOworICBFWFBFQ1RfRVEocHJvdG8zX3ByZXNlcnZlX3Vua25vd25fZW51bV91bml0dGVzdDo6RV9FWFRSQSwKKyAgICAgICAgICAgIG1lc3NhZ2UucmVwZWF0ZWRfcGFja2VkX2UoMCkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5yZXBlYXRlZF9wYWNrZWRfdW5leHBlY3RlZF9lX3NpemUoKSk7CisgIEVYUEVDVF9FUShwcm90bzNfcHJlc2VydmVfdW5rbm93bl9lbnVtX3VuaXR0ZXN0OjpFX0VYVFJBLAorICAgICAgICAgICAgbWVzc2FnZS5yZXBlYXRlZF9wYWNrZWRfdW5leHBlY3RlZF9lKDApKTsKKyAgRVhQRUNUX0VRKHByb3RvM19wcmVzZXJ2ZV91bmtub3duX2VudW1fdW5pdHRlc3Q6OkVfRVhUUkEsCisgICAgICAgICAgICBtZXNzYWdlLm9uZW9mX2VfMSgpKTsKK30KKwordm9pZCBDaGVja01lc3NhZ2UoCisgICAgY29uc3QgcHJvdG8zX3ByZXNlcnZlX3Vua25vd25fZW51bV91bml0dGVzdDo6TXlNZXNzYWdlJiBtZXNzYWdlKSB7CisgIEVYUEVDVF9FUShzdGF0aWNfY2FzdDxpbnQ+KAorICAgICAgICAgICAgICBwcm90bzNfcHJlc2VydmVfdW5rbm93bl9lbnVtX3VuaXR0ZXN0OjpFX0VYVFJBKSwKKyAgICAgICAgICAgIHN0YXRpY19jYXN0PGludD4obWVzc2FnZS5lKCkpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UucmVwZWF0ZWRfZV9zaXplKCkpOworICBFWFBFQ1RfRVEoc3RhdGljX2Nhc3Q8aW50PigKKyAgICAgICAgICAgICAgcHJvdG8zX3ByZXNlcnZlX3Vua25vd25fZW51bV91bml0dGVzdDo6RV9FWFRSQSksCisgICAgICAgICAgICBzdGF0aWNfY2FzdDxpbnQ+KG1lc3NhZ2UucmVwZWF0ZWRfZSgwKSkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5yZXBlYXRlZF9wYWNrZWRfZV9zaXplKCkpOworICBFWFBFQ1RfRVEoc3RhdGljX2Nhc3Q8aW50PigKKyAgICAgICAgICAgICAgcHJvdG8zX3ByZXNlcnZlX3Vua25vd25fZW51bV91bml0dGVzdDo6RV9FWFRSQSksCisgICAgICAgICAgICBzdGF0aWNfY2FzdDxpbnQ+KG1lc3NhZ2UucmVwZWF0ZWRfcGFja2VkX2UoMCkpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UucmVwZWF0ZWRfcGFja2VkX3VuZXhwZWN0ZWRfZV9zaXplKCkpOworICBFWFBFQ1RfRVEoc3RhdGljX2Nhc3Q8aW50PigKKyAgICAgICAgICAgICAgcHJvdG8zX3ByZXNlcnZlX3Vua25vd25fZW51bV91bml0dGVzdDo6RV9FWFRSQSksCisgICAgICAgICAgICBzdGF0aWNfY2FzdDxpbnQ+KG1lc3NhZ2UucmVwZWF0ZWRfcGFja2VkX3VuZXhwZWN0ZWRfZSgwKSkpOworICBFWFBFQ1RfRVEoc3RhdGljX2Nhc3Q8aW50PigKKyAgICAgICAgICAgICAgcHJvdG8zX3ByZXNlcnZlX3Vua25vd25fZW51bV91bml0dGVzdDo6RV9FWFRSQSksCisgICAgICAgICAgICBzdGF0aWNfY2FzdDxpbnQ+KG1lc3NhZ2Uub25lb2ZfZV8xKCkpKTsKK30KKworfSAgLy8gYW5vbnltb3VzIG5hbWVzcGFjZQorCisvLyBUZXN0IHRoYXQgcGFyc2luZyBwcmVzZXJ2ZXMgYW4gdW5rbm93biB2YWx1ZSBpbiB0aGUgZW51bSBmaWVsZCBhbmQgZG9lcyBub3QKKy8vIHB1bnQgaXQgdG8gdGhlIFVua25vd25GaWVsZFNldC4KK1RFU1QoUHJlc2VydmVVbmtub3duRW51bVRlc3QsIFByZXNlcnZlUGFyc2VBbmRTZXJpYWxpemUpIHsKKyAgcHJvdG8zX3ByZXNlcnZlX3Vua25vd25fZW51bV91bml0dGVzdDo6TXlNZXNzYWdlUGx1c0V4dHJhIG9yaWdfbWVzc2FnZTsKKyAgRmlsbE1lc3NhZ2UoJm9yaWdfbWVzc2FnZSk7CisgIHN0cmluZyBzZXJpYWxpemVkOworICBvcmlnX21lc3NhZ2UuU2VyaWFsaXplVG9TdHJpbmcoJnNlcmlhbGl6ZWQpOworCisgIHByb3RvM19wcmVzZXJ2ZV91bmtub3duX2VudW1fdW5pdHRlc3Q6Ok15TWVzc2FnZSBtZXNzYWdlOworICBFWFBFQ1RfRVEodHJ1ZSwgbWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoc2VyaWFsaXplZCkpOworICBDaGVja01lc3NhZ2UobWVzc2FnZSk7CisKKyAgc2VyaWFsaXplZC5jbGVhcigpOworICBtZXNzYWdlLlNlcmlhbGl6ZVRvU3RyaW5nKCZzZXJpYWxpemVkKTsKKyAgRVhQRUNUX0VRKHRydWUsIG9yaWdfbWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoc2VyaWFsaXplZCkpOworICBDaGVja01lc3NhZ2Uob3JpZ19tZXNzYWdlKTsKK30KKworLy8gVGVzdCB0aGF0IHJlZmxlY3Rpb24gYmFzZWQgaW1wbGVtZW50YXRpb24gYWxzbyBrZWVwcyB1bmtub3duIGVudW0gdmFsdWVzIGFuZAorLy8gZG9lc24ndCBwdXQgdGhlbSBpbnRvIFVua25vd25GaWVsZFNldC4KK1RFU1QoUHJlc2VydmVVbmtub3duRW51bVRlc3QsIFByZXNlcnZlUGFyc2VBbmRTZXJpYWxpemVEeW5hbWljTWVzc2FnZSkgeworICBwcm90bzNfcHJlc2VydmVfdW5rbm93bl9lbnVtX3VuaXR0ZXN0OjpNeU1lc3NhZ2VQbHVzRXh0cmEgb3JpZ19tZXNzYWdlOworICBGaWxsTWVzc2FnZSgmb3JpZ19tZXNzYWdlKTsKKyAgc3RyaW5nIHNlcmlhbGl6ZWQgPSBvcmlnX21lc3NhZ2UuU2VyaWFsaXplQXNTdHJpbmcoKTsKKworICBnb29nbGU6OnByb3RvYnVmOjpEeW5hbWljTWVzc2FnZUZhY3RvcnkgZmFjdG9yeTsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlPiBtZXNzYWdlKGZhY3RvcnkuR2V0UHJvdG90eXBlKAorICAgICAgcHJvdG8zX3ByZXNlcnZlX3Vua25vd25fZW51bV91bml0dGVzdDo6TXlNZXNzYWdlOjpkZXNjcmlwdG9yKCkpLT5OZXcoKSk7CisgIEVYUEVDVF9FUSh0cnVlLCBtZXNzYWdlLT5QYXJzZUZyb21TdHJpbmcoc2VyaWFsaXplZCkpOworICBtZXNzYWdlLT5EaXNjYXJkVW5rbm93bkZpZWxkcygpOworCisgIHNlcmlhbGl6ZWQgPSBtZXNzYWdlLT5TZXJpYWxpemVBc1N0cmluZygpOworICBFWFBFQ1RfRVEodHJ1ZSwgb3JpZ19tZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhzZXJpYWxpemVkKSk7CisgIENoZWNrTWVzc2FnZShvcmlnX21lc3NhZ2UpOworfQorCisvLyBUZXN0IHRoYXQgZm9yIHByb3RvMiBtZXNzYWdlcywgdW5rbm93biB2YWx1ZXMgYXJlIGluIHVua25vd24gZmllbGRzLgorVEVTVChQcmVzZXJ2ZVVua25vd25FbnVtVGVzdCwgUHJvdG8ySGlkZXNVbmtub3duVmFsdWVzKSB7CisgIHByb3RvM19wcmVzZXJ2ZV91bmtub3duX2VudW1fdW5pdHRlc3Q6Ok15TWVzc2FnZVBsdXNFeHRyYSBvcmlnX21lc3NhZ2U7CisgIEZpbGxNZXNzYWdlKCZvcmlnX21lc3NhZ2UpOworCisgIHN0cmluZyBzZXJpYWxpemVkOworICBvcmlnX21lc3NhZ2UuU2VyaWFsaXplVG9TdHJpbmcoJnNlcmlhbGl6ZWQpOworCisgIHByb3RvMl9wcmVzZXJ2ZV91bmtub3duX2VudW1fdW5pdHRlc3Q6Ok15TWVzc2FnZSBtZXNzYWdlOworICBFWFBFQ1RfRVEodHJ1ZSwgbWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoc2VyaWFsaXplZCkpOworICAvLyBUaGUgaW50ZXJtZWRpYXRlIG1lc3NhZ2UgaGFzIGV2ZXJ5dGhpbmcgaW4gaXRzICJ1bmtub3duIGZpZWxkcyIuCisgIHByb3RvMl9wcmVzZXJ2ZV91bmtub3duX2VudW1fdW5pdHRlc3Q6Ok15TWVzc2FnZSBtZXNzYWdlMiA9IG1lc3NhZ2U7CisgIG1lc3NhZ2UyLkRpc2NhcmRVbmtub3duRmllbGRzKCk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlMi5CeXRlU2l6ZSgpKTsKKworICAvLyBCdXQgd2hlbiB3ZSBwYXNzIGl0IHRvIHRoZSBjb3JyZWN0IHN0cnVjdHVyZSwgYWxsIHZhbHVlcyBhcmUgdGhlcmUuCisgIHNlcmlhbGl6ZWQuY2xlYXIoKTsKKyAgbWVzc2FnZS5TZXJpYWxpemVUb1N0cmluZygmc2VyaWFsaXplZCk7CisgIEVYUEVDVF9FUSh0cnVlLCBvcmlnX21lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKHNlcmlhbGl6ZWQpKTsKKyAgQ2hlY2tNZXNzYWdlKG9yaWdfbWVzc2FnZSk7Cit9CisKKy8vIFNhbWUgYXMgYmVmb3JlLCBmb3IgYSBkeW5hbWljIG1lc3NhZ2UuCitURVNUKFByZXNlcnZlVW5rbm93bkVudW1UZXN0LCBEeW5hbWljUHJvdG8ySGlkZXNVbmtub3duVmFsdWVzKSB7CisgIHByb3RvM19wcmVzZXJ2ZV91bmtub3duX2VudW1fdW5pdHRlc3Q6Ok15TWVzc2FnZVBsdXNFeHRyYSBvcmlnX21lc3NhZ2U7CisgIEZpbGxNZXNzYWdlKCZvcmlnX21lc3NhZ2UpOworCisgIHN0cmluZyBzZXJpYWxpemVkOworICBvcmlnX21lc3NhZ2UuU2VyaWFsaXplVG9TdHJpbmcoJnNlcmlhbGl6ZWQpOworCisgIGdvb2dsZTo6cHJvdG9idWY6OkR5bmFtaWNNZXNzYWdlRmFjdG9yeSBmYWN0b3J5OworICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPGdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2U+IG1lc3NhZ2UoZmFjdG9yeS5HZXRQcm90b3R5cGUoCisgICAgICBwcm90bzJfcHJlc2VydmVfdW5rbm93bl9lbnVtX3VuaXR0ZXN0OjpNeU1lc3NhZ2U6OmRlc2NyaXB0b3IoKSktPk5ldygpKTsKKyAgRVhQRUNUX0VRKHRydWUsIG1lc3NhZ2UtPlBhcnNlRnJvbVN0cmluZyhzZXJpYWxpemVkKSk7CisgIC8vIFRoZSBpbnRlcm1lZGlhdGUgbWVzc2FnZSBoYXMgZXZlcnl0aGluZyBpbiBpdHMgInVua25vd24gZmllbGRzIi4KKyAgcHJvdG8yX3ByZXNlcnZlX3Vua25vd25fZW51bV91bml0dGVzdDo6TXlNZXNzYWdlIG1lc3NhZ2UyOworICBtZXNzYWdlMi5Db3B5RnJvbSgqbWVzc2FnZSk7CisgIG1lc3NhZ2UyLkRpc2NhcmRVbmtub3duRmllbGRzKCk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlMi5CeXRlU2l6ZSgpKTsKKworICAvLyBCdXQgd2hlbiB3ZSBwYXNzIGl0IHRvIHRoZSBjb3JyZWN0IHN0cnVjdHVyZSwgYWxsIHZhbHVlcyBhcmUgdGhlcmUuCisgIHNlcmlhbGl6ZWQuY2xlYXIoKTsKKyAgbWVzc2FnZS0+U2VyaWFsaXplVG9TdHJpbmcoJnNlcmlhbGl6ZWQpOworICBFWFBFQ1RfRVEodHJ1ZSwgb3JpZ19tZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhzZXJpYWxpemVkKSk7CisgIENoZWNrTWVzc2FnZShvcmlnX21lc3NhZ2UpOworfQorCisvLyBUZXN0IHRoYXQgcmVmbGVjdGlvbiBwcm92aWRlcyBFbnVtVmFsdWVEZXNjcmlwdG9ycyBmb3IgdW5rbm93biB2YWx1ZXMuCitURVNUKFByZXNlcnZlVW5rbm93bkVudW1UZXN0LCBEeW5hbWljRW51bVZhbHVlRGVzY3JpcHRvcnMpIHsKKyAgcHJvdG8zX3ByZXNlcnZlX3Vua25vd25fZW51bV91bml0dGVzdDo6TXlNZXNzYWdlUGx1c0V4dHJhIG9yaWdfbWVzc2FnZTsKKyAgRmlsbE1lc3NhZ2UoJm9yaWdfbWVzc2FnZSk7CisgIHN0cmluZyBzZXJpYWxpemVkOworICBvcmlnX21lc3NhZ2UuU2VyaWFsaXplVG9TdHJpbmcoJnNlcmlhbGl6ZWQpOworCisgIHByb3RvM19wcmVzZXJ2ZV91bmtub3duX2VudW1fdW5pdHRlc3Q6Ok15TWVzc2FnZSBtZXNzYWdlOworICBFWFBFQ1RfRVEodHJ1ZSwgbWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoc2VyaWFsaXplZCkpOworICBDaGVja01lc3NhZ2UobWVzc2FnZSk7CisKKyAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6UmVmbGVjdGlvbiogciA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpOworICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBkID0gbWVzc2FnZS5HZXREZXNjcmlwdG9yKCk7CisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBkLT5GaW5kRmllbGRCeU5hbWUoImUiKTsKKworICAvLyBUaGlzIHNob3VsZCBkeW5hbWljYWxseSBjcmVhdGUgYW4gRW51bVZhbHVlRGVzY3JpcHRvci4KKyAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlRGVzY3JpcHRvciogZW51bV92YWx1ZSA9IHItPkdldEVudW0obWVzc2FnZSwgZmllbGQpOworICBFWFBFQ1RfRVEoZW51bV92YWx1ZS0+bnVtYmVyKCksCisgICAgICAgICAgICBzdGF0aWNfY2FzdDxpbnQ+KHByb3RvM19wcmVzZXJ2ZV91bmtub3duX2VudW1fdW5pdHRlc3Q6OkVfRVhUUkEpKTsKKworICAvLyBGZXRjaGluZyB2YWx1ZSBmb3IgYSBzZWNvbmQgdGltZSBzaG91bGQgcmV0dXJuIHRoZSBzYW1lIHBvaW50ZXIuCisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZURlc2NyaXB0b3IqIGVudW1fdmFsdWVfc2Vjb25kID0KKyAgICAgIHItPkdldEVudW0obWVzc2FnZSwgZmllbGQpOworICBFWFBFQ1RfRVEoZW51bV92YWx1ZSwgZW51bV92YWx1ZV9zZWNvbmQpOworCisgIC8vIENoZWNrIHRoZSByZXBlYXRlZCBjYXNlIHRvby4KKyAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yKiByZXBlYXRlZF9maWVsZCA9CisgICAgICBkLT5GaW5kRmllbGRCeU5hbWUoInJlcGVhdGVkX2UiKTsKKyAgZW51bV92YWx1ZSA9IHItPkdldFJlcGVhdGVkRW51bShtZXNzYWdlLCByZXBlYXRlZF9maWVsZCwgMCk7CisgIEVYUEVDVF9FUShlbnVtX3ZhbHVlLT5udW1iZXIoKSwKKyAgICAgICAgICAgIHN0YXRpY19jYXN0PGludD4ocHJvdG8zX3ByZXNlcnZlX3Vua25vd25fZW51bV91bml0dGVzdDo6RV9FWFRSQSkpOworICAvLyBTaG91bGQgcmV1c2UgdGhlIHNhbWUgRW51bVZhbHVlRGVzY3JpcHRvciwgZXZlbiBmb3IgYSBkaWZmZXJlbnQgZmllbGQuCisgIEVYUEVDVF9FUShlbnVtX3ZhbHVlLCBlbnVtX3ZhbHVlX3NlY29uZCk7CisKKyAgLy8gV2Ugc2hvdWxkIGJlIGFibGUgdG8gdXNlIHRoZSByZXR1cm5lZCB2YWx1ZSBkZXNjcmlwdG9yIHRvIHNldCBhIHZhbHVlIG9uCisgIC8vIGFub3RoZXIgbWVzc2FnZS4KKyAgZ29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSogbSA9IG1lc3NhZ2UuTmV3KCk7CisgIHItPlNldEVudW0obSwgZmllbGQsIGVudW1fdmFsdWUpOworICBFWFBFQ1RfRVEoZW51bV92YWx1ZSwgci0+R2V0RW51bSgqbSwgZmllbGQpKTsKKyAgZGVsZXRlIG07Cit9CisKKy8vIFRlc3QgdGhhdCB0aGUgbmV3IGludGVnZXItYmFzZWQgZW51bSByZWZsZWN0aW9uIEFQSSB3b3Jrcy4KK1RFU1QoUHJlc2VydmVVbmtub3duRW51bVRlc3QsIEludGVnZXJFbnVtUmVmbGVjdGlvbkFQSSkgeworICBwcm90bzNfcHJlc2VydmVfdW5rbm93bl9lbnVtX3VuaXR0ZXN0OjpNeU1lc3NhZ2UgbWVzc2FnZTsKKyAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6UmVmbGVjdGlvbiogciA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpOworICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBkID0gbWVzc2FnZS5HZXREZXNjcmlwdG9yKCk7CisKKyAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yKiBzaW5ndWxhcl9maWVsZCA9IGQtPkZpbmRGaWVsZEJ5TmFtZSgiZSIpOworICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3IqIHJlcGVhdGVkX2ZpZWxkID0KKyAgICAgIGQtPkZpbmRGaWVsZEJ5TmFtZSgicmVwZWF0ZWRfZSIpOworCisgIHItPlNldEVudW1WYWx1ZSgmbWVzc2FnZSwgc2luZ3VsYXJfZmllbGQsIDQyKTsKKyAgRVhQRUNUX0VRKDQyLCByLT5HZXRFbnVtVmFsdWUobWVzc2FnZSwgc2luZ3VsYXJfZmllbGQpKTsKKyAgci0+QWRkRW51bVZhbHVlKCZtZXNzYWdlLCByZXBlYXRlZF9maWVsZCwgNDIpOworICByLT5BZGRFbnVtVmFsdWUoJm1lc3NhZ2UsIHJlcGVhdGVkX2ZpZWxkLCA0Mik7CisgIEVYUEVDVF9FUSg0Miwgci0+R2V0UmVwZWF0ZWRFbnVtVmFsdWUobWVzc2FnZSwgcmVwZWF0ZWRfZmllbGQsIDApKTsKKyAgci0+U2V0UmVwZWF0ZWRFbnVtVmFsdWUoJm1lc3NhZ2UsIHJlcGVhdGVkX2ZpZWxkLCAxLCA4NCk7CisgIEVYUEVDVF9FUSg4NCwgci0+R2V0UmVwZWF0ZWRFbnVtVmFsdWUobWVzc2FnZSwgcmVwZWF0ZWRfZmllbGQsIDEpKTsKKyAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlRGVzY3JpcHRvciogZW51bV92YWx1ZSA9IHItPkdldEVudW0obWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaW5ndWxhcl9maWVsZCk7CisgIEVYUEVDVF9FUSg0MiwgZW51bV92YWx1ZS0+bnVtYmVyKCkpOworfQorCisvLyBUZXN0IHRoYXQgdGhlIEVudW1WYWx1ZSBBUEkgd29ya3MgcHJvcGVybHkgZm9yIHByb3RvMiBtZXNzYWdlcyBhcyB3ZWxsLgorVEVTVChQcmVzZXJ2ZVVua25vd25FbnVtVGVzdCwgUHJvdG8yQ2F0Y2hlc1Vua25vd25WYWx1ZXMpIHsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlOyAgLy8gcHJvdG8yIG1lc3NhZ2UKKyAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6UmVmbGVjdGlvbiogciA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpOworICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBkID0gbWVzc2FnZS5HZXREZXNjcmlwdG9yKCk7CisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvciogcmVwZWF0ZWRfZmllbGQgPQorICAgICAgZC0+RmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF9uZXN0ZWRfZW51bSIpOworICAvLyBBZGQgb25lIGVsZW1lbnQgdG8gdGhlIHJlcGVhdGVkIGZpZWxkIHNvIHRoYXQgd2UgY2FuIHRlc3QKKyAgLy8gU2V0UmVwZWF0ZWRFbnVtVmFsdWUuCisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZURlc2NyaXB0b3IqIGVudW1fdmFsdWUgPQorICAgICAgcmVwZWF0ZWRfZmllbGQtPmVudW1fdHlwZSgpLT5GaW5kVmFsdWVCeU5hbWUoIkJBUiIpOworICBFWFBFQ1RfVFJVRShlbnVtX3ZhbHVlICE9IE5VTEwpOworICByLT5BZGRFbnVtKCZtZXNzYWdlLCByZXBlYXRlZF9maWVsZCwgZW51bV92YWx1ZSk7CisKKyNpZmRlZiBQUk9UT0JVRl9IQVNfREVBVEhfVEVTVAorICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3IqIHNpbmd1bGFyX2ZpZWxkID0KKyAgICAgIGQtPkZpbmRGaWVsZEJ5TmFtZSgib3B0aW9uYWxfbmVzdGVkX2VudW0iKTsKKyAgLy8gRW51bS1maWVsZCBpbnRlZ2VyLWJhc2VkIHNldHRlcnMgR09PR0xFX0RDSEVDSy1mYWlsIG9uIGludmFsaWQgdmFsdWVzLCBpbiBvcmRlciB0bworICAvLyByZW1haW4gY29uc2lzdGVudCB3aXRoIHByb3RvMiBnZW5lcmF0ZWQgY29kZS4KKyAgRVhQRUNUX0RFQlVHX0RFQVRIKHsKKyAgICByLT5TZXRFbnVtVmFsdWUoJm1lc3NhZ2UsIHNpbmd1bGFyX2ZpZWxkLCA0MjQyKTsKKyAgICByLT5HZXRFbnVtKG1lc3NhZ2UsIHNpbmd1bGFyX2ZpZWxkKS0+bnVtYmVyKCk7CisgIH0sICJTZXRFbnVtVmFsdWUgYWNjZXB0cyBvbmx5IHZhbGlkIGludGVnZXIgdmFsdWVzIik7CisgIEVYUEVDVF9ERUJVR19ERUFUSCh7CisgICAgci0+U2V0UmVwZWF0ZWRFbnVtVmFsdWUoJm1lc3NhZ2UsIHJlcGVhdGVkX2ZpZWxkLCAwLCA0MjQyKTsKKyAgICByLT5HZXRSZXBlYXRlZEVudW0obWVzc2FnZSwgcmVwZWF0ZWRfZmllbGQsIDApOworICB9LCAiU2V0UmVwZWF0ZWRFbnVtVmFsdWUgYWNjZXB0cyBvbmx5IHZhbGlkIGludGVnZXIgdmFsdWVzIik7CisgIEVYUEVDVF9ERUJVR19ERUFUSCh7CisgICAgci0+QWRkRW51bVZhbHVlKCZtZXNzYWdlLCByZXBlYXRlZF9maWVsZCwgNDI0Mik7CisgICAgci0+R2V0UmVwZWF0ZWRFbnVtKG1lc3NhZ2UsIHJlcGVhdGVkX2ZpZWxkLCAxKTsKKyAgfSwgIkFkZEVudW1WYWx1ZSBhY2NlcHRzIG9ubHkgdmFsaWQgaW50ZWdlciB2YWx1ZXMiKTsKKyNlbmRpZiAgLy8gUFJPVE9CVUZfSEFTX0RFQVRIX1RFU1QKK30KKworVEVTVChQcmVzZXJ2ZVVua25vd25FbnVtVGVzdCwgU3VwcG9ydHNVbmtub3duRW51bVZhbHVlc0FQSSkgeworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEFsbFR5cGVzIHByb3RvMl9tZXNzYWdlOworICBwcm90bzNfcHJlc2VydmVfdW5rbm93bl9lbnVtX3VuaXR0ZXN0OjpNeU1lc3NhZ2UgbmV3X21lc3NhZ2U7CisKKyAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6UmVmbGVjdGlvbiogcHJvdG8yX3JlZmxlY3Rpb24gPSBwcm90bzJfbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCk7CisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlJlZmxlY3Rpb24qIG5ld19yZWZsZWN0aW9uID0gbmV3X21lc3NhZ2UuR2V0UmVmbGVjdGlvbigpOworCisgIEVYUEVDVF9GQUxTRShwcm90bzJfcmVmbGVjdGlvbi0+U3VwcG9ydHNVbmtub3duRW51bVZhbHVlcygpKTsKKyAgRVhQRUNUX1RSVUUobmV3X3JlZmxlY3Rpb24tPlN1cHBvcnRzVW5rbm93bkVudW1WYWx1ZXMoKSk7Cit9Cit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9wcm90bzNfYXJlbmFfdW5pdHRlc3QuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjgzOGUwZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LmNjCkBAIC0wLDAgKzEsMjA5IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxtZW1vcnk+CisjaWZuZGVmIF9TSEFSRURfUFRSX0gKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc2hhcmVkX3B0ci5oPgorI2VuZGlmCisjaW5jbHVkZSA8dmVjdG9yPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RfdXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9wcm90bzNfYXJlbmEucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvYXJlbmEuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0Lmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7Cit1c2luZyBwcm90bzNfYXJlbmFfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlczsKKworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSB7CisvLyBXZSBzZWxlY3RpdmVseSBzZXQvY2hlY2sgYSBmZXcgcmVwcmVzZW50YXRpdmUgZmllbGRzIHJhdGhlciB0aGFuIGFsbCBmaWVsZHMKKy8vIGFzIHRoaXMgdGVzdCBpcyBvbmx5IGV4cGVjdGVkIHRvIGNvdmVyIHRoZSBiYXNpY3Mgb2YgYXJlbmEgc3VwcG9ydC4KK3ZvaWQgU2V0QWxsRmllbGRzKFRlc3RBbGxUeXBlcyogbSkgeworICBtLT5zZXRfb3B0aW9uYWxfaW50MzIoMTAwKTsKKyAgbS0+c2V0X29wdGlvbmFsX3N0cmluZygiYXNkZiIpOworICBtLT5zZXRfb3B0aW9uYWxfYnl0ZXMoImprbDsiKTsKKyAgbS0+bXV0YWJsZV9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpLT5zZXRfYmIoNDIpOworICBtLT5tdXRhYmxlX29wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSgpLT5zZXRfYyg0Myk7CisgIG0tPnNldF9vcHRpb25hbF9uZXN0ZWRfZW51bSgKKyAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdDo6VGVzdEFsbFR5cGVzX05lc3RlZEVudW1fQkFaKTsKKyAgbS0+c2V0X29wdGlvbmFsX2ZvcmVpZ25fZW51bSgKKyAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdDo6Rk9SRUlHTl9CQVopOworICBtLT5tdXRhYmxlX29wdGlvbmFsX2xhenlfbWVzc2FnZSgpLT5zZXRfYmIoNDUpOworICBtLT5hZGRfcmVwZWF0ZWRfaW50MzIoMTAwKTsKKyAgbS0+YWRkX3JlcGVhdGVkX3N0cmluZygiYXNkZiIpOworICBtLT5hZGRfcmVwZWF0ZWRfYnl0ZXMoImprbDsiKTsKKyAgbS0+YWRkX3JlcGVhdGVkX25lc3RlZF9tZXNzYWdlKCktPnNldF9iYig0Nik7CisgIG0tPmFkZF9yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UoKS0+c2V0X2MoNDcpOworICBtLT5hZGRfcmVwZWF0ZWRfbmVzdGVkX2VudW0oCisgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlc19OZXN0ZWRFbnVtX0JBWik7CisgIG0tPmFkZF9yZXBlYXRlZF9mb3JlaWduX2VudW0oCisgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3Q6OkZPUkVJR05fQkFaKTsKKyAgbS0+YWRkX3JlcGVhdGVkX2xhenlfbWVzc2FnZSgpLT5zZXRfYmIoNDkpOworCisgIG0tPnNldF9vbmVvZl91aW50MzIoMSk7CisgIG0tPm11dGFibGVfb25lb2ZfbmVzdGVkX21lc3NhZ2UoKS0+c2V0X2JiKDUwKTsKKyAgbS0+c2V0X29uZW9mX3N0cmluZygidGVzdCIpOyAgLy8gb25seSB0aGlzIG9uZSByZW1haW5zIHNldAorfQorCit2b2lkIEV4cGVjdEFsbEZpZWxkc1NldChjb25zdCBUZXN0QWxsVHlwZXMmIG0pIHsKKyAgRVhQRUNUX0VRKDEwMCwgbS5vcHRpb25hbF9pbnQzMigpKTsKKyAgRVhQRUNUX0VRKCJhc2RmIiwgbS5vcHRpb25hbF9zdHJpbmcoKSk7CisgIEVYUEVDVF9FUSgiamtsOyIsIG0ub3B0aW9uYWxfYnl0ZXMoKSk7CisgIEVYUEVDVF9FUSh0cnVlLCBtLmhhc19vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpKTsKKyAgRVhQRUNUX0VRKDQyLCBtLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCkuYmIoKSk7CisgIEVYUEVDVF9FUSh0cnVlLCBtLmhhc19vcHRpb25hbF9mb3JlaWduX21lc3NhZ2UoKSk7CisgIEVYUEVDVF9FUSg0MywgbS5vcHRpb25hbF9mb3JlaWduX21lc3NhZ2UoKS5jKCkpOworICBFWFBFQ1RfRVEocHJvdG8zX2FyZW5hX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXNfTmVzdGVkRW51bV9CQVosCisgICAgICAgICAgICBtLm9wdGlvbmFsX25lc3RlZF9lbnVtKCkpOworICBFWFBFQ1RfRVEocHJvdG8zX2FyZW5hX3VuaXR0ZXN0OjpGT1JFSUdOX0JBWiwKKyAgICAgICAgICAgIG0ub3B0aW9uYWxfZm9yZWlnbl9lbnVtKCkpOworICBFWFBFQ1RfRVEodHJ1ZSwgbS5oYXNfb3B0aW9uYWxfbGF6eV9tZXNzYWdlKCkpOworICBFWFBFQ1RfRVEoNDUsIG0ub3B0aW9uYWxfbGF6eV9tZXNzYWdlKCkuYmIoKSk7CisKKyAgRVhQRUNUX0VRKDEsIG0ucmVwZWF0ZWRfaW50MzJfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEwMCwgbS5yZXBlYXRlZF9pbnQzMigwKSk7CisgIEVYUEVDVF9FUSgxLCBtLnJlcGVhdGVkX3N0cmluZ19zaXplKCkpOworICBFWFBFQ1RfRVEoImFzZGYiLCBtLnJlcGVhdGVkX3N0cmluZygwKSk7CisgIEVYUEVDVF9FUSgxLCBtLnJlcGVhdGVkX2J5dGVzX3NpemUoKSk7CisgIEVYUEVDVF9FUSgiamtsOyIsIG0ucmVwZWF0ZWRfYnl0ZXMoMCkpOworICBFWFBFQ1RfRVEoMSwgbS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9zaXplKCkpOworICBFWFBFQ1RfRVEoNDYsIG0ucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UoMCkuYmIoKSk7CisgIEVYUEVDVF9FUSgxLCBtLnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZV9zaXplKCkpOworICBFWFBFQ1RfRVEoNDcsIG0ucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKDApLmMoKSk7CisgIEVYUEVDVF9FUSgxLCBtLnJlcGVhdGVkX25lc3RlZF9lbnVtX3NpemUoKSk7CisgIEVYUEVDVF9FUShwcm90bzNfYXJlbmFfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlc19OZXN0ZWRFbnVtX0JBWiwKKyAgICAgICAgICAgIG0ucmVwZWF0ZWRfbmVzdGVkX2VudW0oMCkpOworICBFWFBFQ1RfRVEoMSwgbS5yZXBlYXRlZF9mb3JlaWduX2VudW1fc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKHByb3RvM19hcmVuYV91bml0dGVzdDo6Rk9SRUlHTl9CQVosCisgICAgICAgICAgICBtLnJlcGVhdGVkX2ZvcmVpZ25fZW51bSgwKSk7CisgIEVYUEVDVF9FUSgxLCBtLnJlcGVhdGVkX2xhenlfbWVzc2FnZV9zaXplKCkpOworICBFWFBFQ1RfRVEoNDksIG0ucmVwZWF0ZWRfbGF6eV9tZXNzYWdlKDApLmJiKCkpOworCisgIEVYUEVDVF9FUShwcm90bzNfYXJlbmFfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6a09uZW9mU3RyaW5nLAorICAgICAgICAgICAgbS5vbmVvZl9maWVsZF9jYXNlKCkpOworICBFWFBFQ1RfRVEoInRlc3QiLCBtLm9uZW9mX3N0cmluZygpKTsKK30KKworLy8gSW4gdGhpcyBmaWxlIHdlIG9ubHkgdGVzdCBzb21lIGJhc2ljIGZ1bmN0aW9uYWxpdGllcyBvZiBhcmVuYSBzdXBwb3J0IGluCisvLyBwcm90bzMgYW5kIGV4cGVjdCB0aGUgYXJlbmEgc3VwcG9ydCB0byBiZSBmdWxseSB0ZXN0ZWQgaW4gcHJvdG8yIHVuaXR0ZXN0cworLy8gYmVjYXVzZSBwcm90bzMgc2hhcmVzIG1vc3QgY29kZSB3aXRoIHByb3RvMi4KKworVEVTVChQcm90bzNBcmVuYVRlc3QsIFBhcnNpbmcpIHsKKyAgVGVzdEFsbFR5cGVzIG9yaWdpbmFsOworICBTZXRBbGxGaWVsZHMoJm9yaWdpbmFsKTsKKworICBBcmVuYSBhcmVuYTsKKyAgVGVzdEFsbFR5cGVzKiBhcmVuYV9tZXNzYWdlID0gQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEFsbFR5cGVzPigmYXJlbmEpOworICBhcmVuYV9tZXNzYWdlLT5QYXJzZUZyb21TdHJpbmcob3JpZ2luYWwuU2VyaWFsaXplQXNTdHJpbmcoKSk7CisgIEV4cGVjdEFsbEZpZWxkc1NldCgqYXJlbmFfbWVzc2FnZSk7Cit9CisKK1RFU1QoUHJvdG8zQXJlbmFUZXN0LCBVbmtub3duRmllbGRzKSB7CisgIFRlc3RBbGxUeXBlcyBvcmlnaW5hbDsKKyAgU2V0QWxsRmllbGRzKCZvcmlnaW5hbCk7CisKKyAgQXJlbmEgYXJlbmE7CisgIFRlc3RBbGxUeXBlcyogYXJlbmFfbWVzc2FnZSA9IEFyZW5hOjpDcmVhdGVNZXNzYWdlPFRlc3RBbGxUeXBlcz4oJmFyZW5hKTsKKyAgYXJlbmFfbWVzc2FnZS0+UGFyc2VGcm9tU3RyaW5nKG9yaWdpbmFsLlNlcmlhbGl6ZUFzU3RyaW5nKCkpOworICBFeHBlY3RBbGxGaWVsZHNTZXQoKmFyZW5hX21lc3NhZ2UpOworCisgIC8vIEluIHByb3RvMyB3ZSBjYW4gc3RpbGwgZ2V0IGEgcG9pbnRlciB0byB0aGUgVW5rbm93bkZpZWxkU2V0IHRocm91Z2gKKyAgLy8gcmVmbGVjdGlvbiBBUEkuCisgIFVua25vd25GaWVsZFNldCogdW5rbm93bl9maWVsZHMgPQorICAgICAgYXJlbmFfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5NdXRhYmxlVW5rbm93bkZpZWxkcyhhcmVuYV9tZXNzYWdlKTsKKyAgLy8gV2UgY2FuIG1vZGlmeSB0aGlzIFVua25vd25GaWVsZFNldC4KKyAgdW5rbm93bl9maWVsZHMtPkFkZFZhcmludCgxLCAyKTsKKyAgLy8gQnV0IHRoZSBjaGFuZ2Ugd2lsbCBuZXZlciB3aWxsIHNlcmlhbGl6ZWQgYmFjay4KKyAgQVNTRVJUX0VRKG9yaWdpbmFsLkJ5dGVTaXplKCksIGFyZW5hX21lc3NhZ2UtPkJ5dGVTaXplKCkpOworICBBU1NFUlRfVFJVRSgKKyAgICAgIGFyZW5hX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0VW5rbm93bkZpZWxkcygqYXJlbmFfbWVzc2FnZSkuZW1wdHkoKSk7Cit9CisKK1RFU1QoUHJvdG8zQXJlbmFUZXN0LCBTd2FwKSB7CisgIEFyZW5hIGFyZW5hMTsKKyAgQXJlbmEgYXJlbmEyOworCisgIC8vIFRlc3QgU3dhcCgpLgorICBUZXN0QWxsVHlwZXMqIGFyZW5hMV9tZXNzYWdlID0gQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEFsbFR5cGVzPigmYXJlbmExKTsKKyAgVGVzdEFsbFR5cGVzKiBhcmVuYTJfbWVzc2FnZSA9IEFyZW5hOjpDcmVhdGVNZXNzYWdlPFRlc3RBbGxUeXBlcz4oJmFyZW5hMik7CisgIGFyZW5hMV9tZXNzYWdlLT5Td2FwKGFyZW5hMl9tZXNzYWdlKTsKKyAgRVhQRUNUX0VRKCZhcmVuYTEsIGFyZW5hMV9tZXNzYWdlLT5HZXRBcmVuYSgpKTsKKyAgRVhQRUNUX0VRKCZhcmVuYTIsIGFyZW5hMl9tZXNzYWdlLT5HZXRBcmVuYSgpKTsKK30KKworVEVTVChQcm90bzNBcmVuYVRlc3QsIFNldEFsbG9jYXRlZE1lc3NhZ2UpIHsKKyAgQXJlbmEgYXJlbmE7CisgIFRlc3RBbGxUeXBlcyAqYXJlbmFfbWVzc2FnZSA9IEFyZW5hOjpDcmVhdGVNZXNzYWdlPFRlc3RBbGxUeXBlcz4oJmFyZW5hKTsKKyAgVGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlKiBuZXN0ZWQgPSBuZXcgVGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlOworICBuZXN0ZWQtPnNldF9iYigxMTgpOworICBhcmVuYV9tZXNzYWdlLT5zZXRfYWxsb2NhdGVkX29wdGlvbmFsX25lc3RlZF9tZXNzYWdlKG5lc3RlZCk7CisgIEVYUEVDVF9FUSgxMTgsIGFyZW5hX21lc3NhZ2UtPm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCkuYmIoKSk7Cit9CisKK1RFU1QoUHJvdG8zQXJlbmFUZXN0LCBSZWxlYXNlTWVzc2FnZSkgeworICBBcmVuYSBhcmVuYTsKKyAgVGVzdEFsbFR5cGVzKiBhcmVuYV9tZXNzYWdlID0gQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEFsbFR5cGVzPigmYXJlbmEpOworICBhcmVuYV9tZXNzYWdlLT5tdXRhYmxlX29wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCktPnNldF9iYigxMTgpOworICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPFRlc3RBbGxUeXBlczo6TmVzdGVkTWVzc2FnZT4gbmVzdGVkKAorICAgICAgYXJlbmFfbWVzc2FnZS0+cmVsZWFzZV9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpKTsKKyAgRVhQRUNUX0VRKDExOCwgbmVzdGVkLT5iYigpKTsKK30KKworVEVTVChQcm90bzNBcmVuYVRlc3QsIE1lc3NhZ2VGaWVsZENsZWFyKSB7CisgIC8vIEdpdEh1YiBpc3N1ZSAjMzEwOiBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL3Byb3RvYnVmL2lzc3Vlcy8zMTAKKyAgQXJlbmEgYXJlbmE7CisgIFRlc3RBbGxUeXBlcyogYXJlbmFfbWVzc2FnZSA9IEFyZW5hOjpDcmVhdGVNZXNzYWdlPFRlc3RBbGxUeXBlcz4oJmFyZW5hKTsKKyAgYXJlbmFfbWVzc2FnZS0+bXV0YWJsZV9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpLT5zZXRfYmIoMTE4KTsKKyAgLy8gVGhpcyBzaG91bGQgbm90IGNyYXNoLCBidXQgcHJpb3IgdG8gdGhlIGJ1Z2ZpeCwgaXQgdHJpZWQgdG8gdXNlIGBvcGVyYXRvcgorICAvLyBkZWxldGVgIHRoZSBuZXN0ZWQgbWVzc2FnZSAod2hpY2ggaXMgb24gdGhlIGFyZW5hKToKKyAgYXJlbmFfbWVzc2FnZS0+Q2xlYXIoKTsKK30KKworVEVTVChQcm90bzNBcmVuYVRlc3QsIE1lc3NhZ2VGaWVsZENsZWFyVmlhUmVmbGVjdGlvbikgeworICBBcmVuYSBhcmVuYTsKKyAgVGVzdEFsbFR5cGVzKiBtZXNzYWdlID0gQXJlbmE6OkNyZWF0ZU1lc3NhZ2U8VGVzdEFsbFR5cGVzPigmYXJlbmEpOworICBjb25zdCBSZWZsZWN0aW9uKiByID0gbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpOworICBjb25zdCBEZXNjcmlwdG9yKiBkID0gbWVzc2FnZS0+R2V0RGVzY3JpcHRvcigpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIG1zZ19maWVsZCA9IGQtPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICJvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSIpOworCisgIG1lc3NhZ2UtPm11dGFibGVfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKS0+c2V0X2JiKDEpOworICByLT5DbGVhckZpZWxkKG1lc3NhZ2UsIG1zZ19maWVsZCk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLT5oYXNfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLT5vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpLmJiKCkpOworfQorCit9ICAvLyBuYW1lc3BhY2UKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9yZWZsZWN0aW9uLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3JlZmxlY3Rpb24uaApuZXcgZmlsZSBtb2RlIDEwMDc1NQppbmRleCAwMDAwMDAwLi42NzFhYWZkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9yZWZsZWN0aW9uLmgKQEAgLTAsMCArMSw2MDAgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBUaGlzIGhlYWRlciBkZWZpbmVzIHRoZSBSZXBlYXRlZEZpZWxkUmVmIGNsYXNzIHRlbXBsYXRlIHVzZWQgdG8gYWNjZXNzCisvLyByZXBlYXRlZCBmaWVsZHMgd2l0aCBwcm90b2J1ZiByZWZsZWN0aW9uIEFQSS4KKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX1JFRkxFQ1RJT05fSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9SRUZMRUNUSU9OX0hfXworCisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21lc3NhZ2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX2VudW1fdXRpbC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW50ZXJuYWwgewordGVtcGxhdGU8dHlwZW5hbWUgVCwgdHlwZW5hbWUgRW5hYmxlID0gdm9pZD4KK3N0cnVjdCBSZWZUeXBlVHJhaXRzOworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCisKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+CitSZXBlYXRlZEZpZWxkUmVmPFQ+IFJlZmxlY3Rpb246OkdldFJlcGVhdGVkRmllbGRSZWYoCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3QgeworICByZXR1cm4gUmVwZWF0ZWRGaWVsZFJlZjxUPihtZXNzYWdlLCBmaWVsZCk7Cit9CisKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+CitNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxUPiBSZWZsZWN0aW9uOjpHZXRNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZigKKyAgICBNZXNzYWdlKiBtZXNzYWdlLCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSBjb25zdCB7CisgIHJldHVybiBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxUPihtZXNzYWdlLCBmaWVsZCk7Cit9CisKKy8vIFJlcGVhdGVkRmllbGRSZWYgZGVmaW5pdGlvbiBmb3Igbm9uLW1lc3NhZ2UgdHlwZXMuCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorY2xhc3MgUmVwZWF0ZWRGaWVsZFJlZjwKKyAgICBULCB0eXBlbmFtZSBpbnRlcm5hbDo6ZW5hYmxlX2lmPCFpbnRlcm5hbDo6aXNfYmFzZV9vZjxNZXNzYWdlLCBUPjo6dmFsdWU+Ojp0eXBlPiB7CisgIHR5cGVkZWYgdHlwZW5hbWUgaW50ZXJuYWw6OlJlZlR5cGVUcmFpdHM8VD46Oml0ZXJhdG9yIEl0ZXJhdG9yVHlwZTsKKyAgdHlwZWRlZiB0eXBlbmFtZSBpbnRlcm5hbDo6UmVmVHlwZVRyYWl0czxUPjo6QWNjZXNzb3JUeXBlIEFjY2Vzc29yVHlwZTsKKworIHB1YmxpYzoKKyAgYm9vbCBlbXB0eSgpIGNvbnN0IHsKKyAgICByZXR1cm4gYWNjZXNzb3JfLT5Jc0VtcHR5KGRhdGFfKTsKKyAgfQorICBpbnQgc2l6ZSgpIGNvbnN0IHsKKyAgICByZXR1cm4gYWNjZXNzb3JfLT5TaXplKGRhdGFfKTsKKyAgfQorICBUIEdldChpbnQgaW5kZXgpIGNvbnN0IHsKKyAgICByZXR1cm4gYWNjZXNzb3JfLT50ZW1wbGF0ZSBHZXQ8VD4oZGF0YV8sIGluZGV4KTsKKyAgfQorCisgIHR5cGVkZWYgSXRlcmF0b3JUeXBlIGl0ZXJhdG9yOworICB0eXBlZGVmIEl0ZXJhdG9yVHlwZSBjb25zdF9pdGVyYXRvcjsKKyAgaXRlcmF0b3IgYmVnaW4oKSBjb25zdCB7CisgICAgcmV0dXJuIGl0ZXJhdG9yKGRhdGFfLCBhY2Nlc3Nvcl8sIHRydWUpOworICB9CisgIGl0ZXJhdG9yIGVuZCgpIGNvbnN0IHsKKyAgICByZXR1cm4gaXRlcmF0b3IoZGF0YV8sIGFjY2Vzc29yXywgZmFsc2UpOworICB9CisKKyBwcml2YXRlOgorICBmcmllbmQgY2xhc3MgUmVmbGVjdGlvbjsKKyAgUmVwZWF0ZWRGaWVsZFJlZigKKyAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgICAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpOworICAgIGRhdGFfID0gcmVmbGVjdGlvbi0+UmVwZWF0ZWRGaWVsZERhdGEoCisgICAgICAgIGNvbnN0X2Nhc3Q8TWVzc2FnZSo+KCZtZXNzYWdlKSwgZmllbGQsCisgICAgICAgIGludGVybmFsOjpSZWZUeXBlVHJhaXRzPFQ+OjpjcHBfdHlwZSwgTlVMTCk7CisgICAgYWNjZXNzb3JfID0gcmVmbGVjdGlvbi0+UmVwZWF0ZWRGaWVsZEFjY2Vzc29yKGZpZWxkKTsKKyAgfQorCisgIGNvbnN0IHZvaWQqIGRhdGFfOworICBjb25zdCBBY2Nlc3NvclR5cGUqIGFjY2Vzc29yXzsKK307CisKKy8vIE11dGFibGVSZXBlYXRlZEZpZWxkUmVmIGRlZmluaXRpb24gZm9yIG5vbi1tZXNzYWdlIHR5cGVzLgordGVtcGxhdGU8dHlwZW5hbWUgVD4KK2NsYXNzIE11dGFibGVSZXBlYXRlZEZpZWxkUmVmPAorICAgIFQsIHR5cGVuYW1lIGludGVybmFsOjplbmFibGVfaWY8IWludGVybmFsOjppc19iYXNlX29mPE1lc3NhZ2UsIFQ+Ojp2YWx1ZT46OnR5cGU+IHsKKyAgdHlwZWRlZiB0eXBlbmFtZSBpbnRlcm5hbDo6UmVmVHlwZVRyYWl0czxUPjo6QWNjZXNzb3JUeXBlIEFjY2Vzc29yVHlwZTsKKworIHB1YmxpYzoKKyAgYm9vbCBlbXB0eSgpIGNvbnN0IHsKKyAgICByZXR1cm4gYWNjZXNzb3JfLT5Jc0VtcHR5KGRhdGFfKTsKKyAgfQorICBpbnQgc2l6ZSgpIGNvbnN0IHsKKyAgICByZXR1cm4gYWNjZXNzb3JfLT5TaXplKGRhdGFfKTsKKyAgfQorICBUIEdldChpbnQgaW5kZXgpIGNvbnN0IHsKKyAgICByZXR1cm4gYWNjZXNzb3JfLT50ZW1wbGF0ZSBHZXQ8VD4oZGF0YV8sIGluZGV4KTsKKyAgfQorCisgIHZvaWQgU2V0KGludCBpbmRleCwgY29uc3QgVCYgdmFsdWUpIGNvbnN0IHsKKyAgICBhY2Nlc3Nvcl8tPnRlbXBsYXRlIFNldDxUPihkYXRhXywgaW5kZXgsIHZhbHVlKTsKKyAgfQorICB2b2lkIEFkZChjb25zdCBUJiB2YWx1ZSkgY29uc3QgeworICAgIGFjY2Vzc29yXy0+dGVtcGxhdGUgQWRkPFQ+KGRhdGFfLCB2YWx1ZSk7CisgIH0KKyAgdm9pZCBSZW1vdmVMYXN0KCkgY29uc3QgeworICAgIGFjY2Vzc29yXy0+UmVtb3ZlTGFzdChkYXRhXyk7CisgIH0KKyAgdm9pZCBTd2FwRWxlbWVudHMoaW50IGluZGV4MSwgaW50IGluZGV4MikgY29uc3QgeworICAgIGFjY2Vzc29yXy0+U3dhcEVsZW1lbnRzKGRhdGFfLCBpbmRleDEsIGluZGV4Mik7CisgIH0KKyAgdm9pZCBDbGVhcigpIGNvbnN0IHsKKyAgICBhY2Nlc3Nvcl8tPkNsZWFyKGRhdGFfKTsKKyAgfQorCisgIHZvaWQgU3dhcChjb25zdCBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZiYgb3RoZXIpIGNvbnN0IHsKKyAgICBhY2Nlc3Nvcl8tPlN3YXAoZGF0YV8sIG90aGVyLmFjY2Vzc29yXywgb3RoZXIuZGF0YV8pOworICB9CisKKyAgdGVtcGxhdGU8dHlwZW5hbWUgQ29udGFpbmVyPgorICB2b2lkIE1lcmdlRnJvbShjb25zdCBDb250YWluZXImIGNvbnRhaW5lcikgY29uc3QgeworICAgIHR5cGVkZWYgdHlwZW5hbWUgQ29udGFpbmVyOjpjb25zdF9pdGVyYXRvciBJdGVyYXRvcjsKKyAgICBmb3IgKEl0ZXJhdG9yIGl0ID0gY29udGFpbmVyLmJlZ2luKCk7IGl0ICE9IGNvbnRhaW5lci5lbmQoKTsgKytpdCkgeworICAgICAgQWRkKCppdCk7CisgICAgfQorICB9CisgIHRlbXBsYXRlPHR5cGVuYW1lIENvbnRhaW5lcj4KKyAgdm9pZCBDb3B5RnJvbShjb25zdCBDb250YWluZXImIGNvbnRhaW5lcikgY29uc3QgeworICAgIENsZWFyKCk7CisgICAgTWVyZ2VGcm9tKGNvbnRhaW5lcik7CisgIH0KKworIHByaXZhdGU6CisgIGZyaWVuZCBjbGFzcyBSZWZsZWN0aW9uOworICBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZigKKyAgICAgIE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisgICAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKTsKKyAgICBkYXRhXyA9IHJlZmxlY3Rpb24tPlJlcGVhdGVkRmllbGREYXRhKAorICAgICAgICBtZXNzYWdlLCBmaWVsZCwgaW50ZXJuYWw6OlJlZlR5cGVUcmFpdHM8VD46OmNwcF90eXBlLCBOVUxMKTsKKyAgICBhY2Nlc3Nvcl8gPSByZWZsZWN0aW9uLT5SZXBlYXRlZEZpZWxkQWNjZXNzb3IoZmllbGQpOworICB9CisKKyAgdm9pZCogZGF0YV87CisgIGNvbnN0IEFjY2Vzc29yVHlwZSogYWNjZXNzb3JfOworfTsKKworLy8gUmVwZWF0ZWRGaWVsZFJlZiBkZWZpbml0aW9uIGZvciBtZXNzYWdlIHR5cGVzLgordGVtcGxhdGU8dHlwZW5hbWUgVD4KK2NsYXNzIFJlcGVhdGVkRmllbGRSZWY8CisgICAgVCwgdHlwZW5hbWUgaW50ZXJuYWw6OmVuYWJsZV9pZjxpbnRlcm5hbDo6aXNfYmFzZV9vZjxNZXNzYWdlLCBUPjo6dmFsdWU+Ojp0eXBlPiB7CisgIHR5cGVkZWYgdHlwZW5hbWUgaW50ZXJuYWw6OlJlZlR5cGVUcmFpdHM8VD46Oml0ZXJhdG9yIEl0ZXJhdG9yVHlwZTsKKyAgdHlwZWRlZiB0eXBlbmFtZSBpbnRlcm5hbDo6UmVmVHlwZVRyYWl0czxUPjo6QWNjZXNzb3JUeXBlIEFjY2Vzc29yVHlwZTsKKworIHB1YmxpYzoKKyAgYm9vbCBlbXB0eSgpIGNvbnN0IHsKKyAgICByZXR1cm4gYWNjZXNzb3JfLT5Jc0VtcHR5KGRhdGFfKTsKKyAgfQorICBpbnQgc2l6ZSgpIGNvbnN0IHsKKyAgICByZXR1cm4gYWNjZXNzb3JfLT5TaXplKGRhdGFfKTsKKyAgfQorICAvLyBUaGlzIG1ldGhvZCByZXR1cm5zIGEgcmVmZXJlbmNlIHRvIHRoZSB1bmRlcmx5aW5nIG1lc3NhZ2Ugb2JqZWN0IGlmIGl0CisgIC8vIGV4aXN0cy4gSWYgYSBtZXNzYWdlIG9iamVjdCBkb2Vzbid0IGV4aXN0IChlLmcuLCBkYXRhIHN0b3JlZCBpbiBzZXJpYWxpemVkCisgIC8vIGZvcm0pLCBzY3JhdGNoX3NwYWNlIHdpbGwgYmUgZmlsbGVkIHdpdGggdGhlIGRhdGEgYW5kIGEgcmVmZXJlbmNlIHRvIGl0CisgIC8vIHdpbGwgYmUgcmV0dXJuZWQuCisgIC8vCisgIC8vIEV4YW1wbGU6CisgIC8vICAgUmVwZWF0ZWRGaWVsZFJlZjxNZXNzYWdlPiBoID0gLi4uCisgIC8vICAgdW5pcXVlX3B0cjxNZXNzYWdlPiBzY3JhdGNoX3NwYWNlKGguTmV3TWVzc2FnZSgpKTsKKyAgLy8gICBjb25zdCBNZXNzYWdlJiBpdGVtID0gaC5HZXQoaW5kZXgsIHNjcmF0Y2hfc3BhY2UuZ2V0KCkpOworICBjb25zdCBUJiBHZXQoaW50IGluZGV4LCBUKiBzY3JhdGNoX3NwYWNlKSBjb25zdCB7CisgICAgcmV0dXJuICpzdGF0aWNfY2FzdDxjb25zdCBUKj4oYWNjZXNzb3JfLT5HZXQoZGF0YV8sIGluZGV4LCBzY3JhdGNoX3NwYWNlKSk7CisgIH0KKyAgLy8gQ3JlYXRlIGEgbmV3IG1lc3NhZ2Ugb2YgdGhlIHNhbWUgdHlwZSBhcyB0aGUgbWVzc2FnZXMgc3RvcmVkIGluIHRoaXMKKyAgLy8gcmVwZWF0ZWQgZmllbGQuIENhbGxlciB0YWtlcyBvd25lcnNoaXAgb2YgdGhlIHJldHVybmVkIG9iamVjdC4KKyAgVCogTmV3TWVzc2FnZSgpIGNvbnN0IHsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8VCo+KGRlZmF1bHRfaW5zdGFuY2VfLT5OZXcoKSk7CisgIH0KKworICB0eXBlZGVmIEl0ZXJhdG9yVHlwZSBpdGVyYXRvcjsKKyAgdHlwZWRlZiBJdGVyYXRvclR5cGUgY29uc3RfaXRlcmF0b3I7CisgIGl0ZXJhdG9yIGJlZ2luKCkgY29uc3QgeworICAgIHJldHVybiBpdGVyYXRvcihkYXRhXywgYWNjZXNzb3JfLCB0cnVlLCBOZXdNZXNzYWdlKCkpOworICB9CisgIGl0ZXJhdG9yIGVuZCgpIGNvbnN0IHsKKyAgICByZXR1cm4gaXRlcmF0b3IoZGF0YV8sIGFjY2Vzc29yXywgZmFsc2UsIE5ld01lc3NhZ2UoKSk7CisgIH0KKworIHByaXZhdGU6CisgIGZyaWVuZCBjbGFzcyBSZWZsZWN0aW9uOworICBSZXBlYXRlZEZpZWxkUmVmKAorICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCk7CisgICAgZGF0YV8gPSByZWZsZWN0aW9uLT5SZXBlYXRlZEZpZWxkRGF0YSgKKyAgICAgICAgY29uc3RfY2FzdDxNZXNzYWdlKj4oJm1lc3NhZ2UpLCBmaWVsZCwKKyAgICAgICAgaW50ZXJuYWw6OlJlZlR5cGVUcmFpdHM8VD46OmNwcF90eXBlLAorICAgICAgICBpbnRlcm5hbDo6UmVmVHlwZVRyYWl0czxUPjo6R2V0TWVzc2FnZUZpZWxkRGVzY3JpcHRvcigpKTsKKyAgICBhY2Nlc3Nvcl8gPSByZWZsZWN0aW9uLT5SZXBlYXRlZEZpZWxkQWNjZXNzb3IoZmllbGQpOworICAgIGRlZmF1bHRfaW5zdGFuY2VfID0KKyAgICAgICAgcmVmbGVjdGlvbi0+R2V0TWVzc2FnZUZhY3RvcnkoKS0+R2V0UHJvdG90eXBlKGZpZWxkLT5tZXNzYWdlX3R5cGUoKSk7CisgIH0KKworICBjb25zdCB2b2lkKiBkYXRhXzsKKyAgY29uc3QgQWNjZXNzb3JUeXBlKiBhY2Nlc3Nvcl87CisgIGNvbnN0IE1lc3NhZ2UqIGRlZmF1bHRfaW5zdGFuY2VfOworfTsKKworLy8gTXV0YWJsZVJlcGVhdGVkRmllbGRSZWYgZGVmaW5pdGlvbiBmb3IgbWVzc2FnZSB0eXBlcy4KK3RlbXBsYXRlPHR5cGVuYW1lIFQ+CitjbGFzcyBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjwKKyAgICBULCB0eXBlbmFtZSBpbnRlcm5hbDo6ZW5hYmxlX2lmPGludGVybmFsOjppc19iYXNlX29mPE1lc3NhZ2UsIFQ+Ojp2YWx1ZT46OnR5cGU+IHsKKyAgdHlwZWRlZiB0eXBlbmFtZSBpbnRlcm5hbDo6UmVmVHlwZVRyYWl0czxUPjo6QWNjZXNzb3JUeXBlIEFjY2Vzc29yVHlwZTsKKworIHB1YmxpYzoKKyAgYm9vbCBlbXB0eSgpIGNvbnN0IHsKKyAgICByZXR1cm4gYWNjZXNzb3JfLT5Jc0VtcHR5KGRhdGFfKTsKKyAgfQorICBpbnQgc2l6ZSgpIGNvbnN0IHsKKyAgICByZXR1cm4gYWNjZXNzb3JfLT5TaXplKGRhdGFfKTsKKyAgfQorICAvLyBTZWUgY29tbWVudHMgZm9yIFJlcGVhdGVkRmllbGRSZWY8TWVzc2FnZT46OkdldCgpCisgIGNvbnN0IFQmIEdldChpbnQgaW5kZXgsIFQqIHNjcmF0Y2hfc3BhY2UpIGNvbnN0IHsKKyAgICByZXR1cm4gKnN0YXRpY19jYXN0PGNvbnN0IFQqPihhY2Nlc3Nvcl8tPkdldChkYXRhXywgaW5kZXgsIHNjcmF0Y2hfc3BhY2UpKTsKKyAgfQorICAvLyBDcmVhdGUgYSBuZXcgbWVzc2FnZSBvZiB0aGUgc2FtZSB0eXBlIGFzIHRoZSBtZXNzYWdlcyBzdG9yZWQgaW4gdGhpcworICAvLyByZXBlYXRlZCBmaWVsZC4gQ2FsbGVyIHRha2VzIG93bmVyc2hpcCBvZiB0aGUgcmV0dXJuZWQgb2JqZWN0LgorICBUKiBOZXdNZXNzYWdlKCkgY29uc3QgeworICAgIHJldHVybiBzdGF0aWNfY2FzdDxUKj4oZGVmYXVsdF9pbnN0YW5jZV8tPk5ldygpKTsKKyAgfQorCisgIHZvaWQgU2V0KGludCBpbmRleCwgY29uc3QgVCYgdmFsdWUpIGNvbnN0IHsKKyAgICBhY2Nlc3Nvcl8tPlNldChkYXRhXywgaW5kZXgsICZ2YWx1ZSk7CisgIH0KKyAgdm9pZCBBZGQoY29uc3QgVCYgdmFsdWUpIGNvbnN0IHsKKyAgICBhY2Nlc3Nvcl8tPkFkZChkYXRhXywgJnZhbHVlKTsKKyAgfQorICB2b2lkIFJlbW92ZUxhc3QoKSBjb25zdCB7CisgICAgYWNjZXNzb3JfLT5SZW1vdmVMYXN0KGRhdGFfKTsKKyAgfQorICB2b2lkIFN3YXBFbGVtZW50cyhpbnQgaW5kZXgxLCBpbnQgaW5kZXgyKSBjb25zdCB7CisgICAgYWNjZXNzb3JfLT5Td2FwRWxlbWVudHMoZGF0YV8sIGluZGV4MSwgaW5kZXgyKTsKKyAgfQorICB2b2lkIENsZWFyKCkgY29uc3QgeworICAgIGFjY2Vzc29yXy0+Q2xlYXIoZGF0YV8pOworICB9CisKKyAgdm9pZCBTd2FwKGNvbnN0IE11dGFibGVSZXBlYXRlZEZpZWxkUmVmJiBvdGhlcikgY29uc3QgeworICAgIGFjY2Vzc29yXy0+U3dhcChkYXRhXywgb3RoZXIuYWNjZXNzb3JfLCBvdGhlci5kYXRhXyk7CisgIH0KKworICB0ZW1wbGF0ZTx0eXBlbmFtZSBDb250YWluZXI+CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IENvbnRhaW5lciYgY29udGFpbmVyKSBjb25zdCB7CisgICAgdHlwZWRlZiB0eXBlbmFtZSBDb250YWluZXI6OmNvbnN0X2l0ZXJhdG9yIEl0ZXJhdG9yOworICAgIGZvciAoSXRlcmF0b3IgaXQgPSBjb250YWluZXIuYmVnaW4oKTsgaXQgIT0gY29udGFpbmVyLmVuZCgpOyArK2l0KSB7CisgICAgICBBZGQoKml0KTsKKyAgICB9CisgIH0KKyAgdGVtcGxhdGU8dHlwZW5hbWUgQ29udGFpbmVyPgorICB2b2lkIENvcHlGcm9tKGNvbnN0IENvbnRhaW5lciYgY29udGFpbmVyKSBjb25zdCB7CisgICAgQ2xlYXIoKTsKKyAgICBNZXJnZUZyb20oY29udGFpbmVyKTsKKyAgfQorCisgcHJpdmF0ZToKKyAgZnJpZW5kIGNsYXNzIFJlZmxlY3Rpb247CisgIE11dGFibGVSZXBlYXRlZEZpZWxkUmVmKAorICAgICAgTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpOworICAgIGRhdGFfID0gcmVmbGVjdGlvbi0+UmVwZWF0ZWRGaWVsZERhdGEoCisgICAgICAgIG1lc3NhZ2UsIGZpZWxkLCBpbnRlcm5hbDo6UmVmVHlwZVRyYWl0czxUPjo6Y3BwX3R5cGUsCisgICAgICAgIGludGVybmFsOjpSZWZUeXBlVHJhaXRzPFQ+OjpHZXRNZXNzYWdlRmllbGREZXNjcmlwdG9yKCkpOworICAgIGFjY2Vzc29yXyA9IHJlZmxlY3Rpb24tPlJlcGVhdGVkRmllbGRBY2Nlc3NvcihmaWVsZCk7CisgICAgZGVmYXVsdF9pbnN0YW5jZV8gPQorICAgICAgICByZWZsZWN0aW9uLT5HZXRNZXNzYWdlRmFjdG9yeSgpLT5HZXRQcm90b3R5cGUoZmllbGQtPm1lc3NhZ2VfdHlwZSgpKTsKKyAgfQorCisgIHZvaWQqIGRhdGFfOworICBjb25zdCBBY2Nlc3NvclR5cGUqIGFjY2Vzc29yXzsKKyAgY29uc3QgTWVzc2FnZSogZGVmYXVsdF9pbnN0YW5jZV87Cit9OworCituYW1lc3BhY2UgaW50ZXJuYWwgeworLy8gSW50ZXJmYWNlcyB1c2VkIHRvIGltcGxlbWVudCByZWZsZWN0aW9uIFJlcGVhdGVkRmllbGRSZWYgQVBJLgorLy8gUmVmbGVjdGlvbjo6R2V0UmVwZWF0ZWRBY2Nlc3NvcigpIHNob3VsZCByZXR1cm4gYSBwb2ludGVyIHRvIGFuIHNpbmdsZXRvbgorLy8gb2JqZWN0IHRoYXQgaW1wbGVtZW50cyB0aGUgYmVsb3cgaW50ZXJmYWNlLgorLy8KKy8vIFRoaXMgaW50ZXJmYWNlIHBhc3Nlcy9yZXR1cm5zIHZhbHVlcyB1c2luZyB2b2lkIHBvaW50ZXJzLiBUaGUgYWN0dWFsIHR5cGUKKy8vIG9mIHRoZSB2YWx1ZSBkZXBlbmRzIG9uIHRoZSBmaWVsZCdzIGNwcF90eXBlLiBGb2xsb3dpbmcgaXMgYSBtYXBwaW5nIGZyb20KKy8vIGNwcF90eXBlIHRvIHRoZSB0eXBlIHRoYXQgc2hvdWxkIGJlIHVzZWQgaW4gdGhpcyBpbnRlcmZhY2U6CisvLworLy8gICBmaWVsZC0+Y3BwX3R5cGUoKSAgICAgIFQgICAgICAgICAgICAgICAgQWN0dWFsIHR5cGUgb2Ygdm9pZCoKKy8vICAgQ1BQVFlQRV9JTlQzMiAgICAgICAgaW50MzIgICAgICAgICAgICAgICAgICAgaW50MzIKKy8vICAgQ1BQVFlQRV9VSU5UMzIgICAgICAgdWludDMyICAgICAgICAgICAgICAgICAgdWludDMyCisvLyAgIENQUFRZUEVfSU5UNjQgICAgICAgIGludDY0ICAgICAgICAgICAgICAgICAgIGludDY0CisvLyAgIENQUFRZUEVfVUlOVDY0ICAgICAgIHVpbnQ2NCAgICAgICAgICAgICAgICAgIHVpbnQ2NAorLy8gICBDUFBUWVBFX0RPVUJMRSAgICAgICBkb3VibGUgICAgICAgICAgICAgICAgICBkb3VibGUKKy8vICAgQ1BQVFlQRV9GTE9BVCAgICAgICAgZmxvYXQgICAgICAgICAgICAgICAgICAgZmxvYXQKKy8vICAgQ1BQVFlQRV9CT09MICAgICAgICAgYm9vbCAgICAgICAgICAgICAgICAgICAgYm9vbAorLy8gICBDUFBUWVBFX0VOVU0gICAgICAgICBnZW5lcmF0ZWQgZW51bSB0eXBlICAgICBpbnQzMgorLy8gICBDUFBUWVBFX1NUUklORyAgICAgICBzdHJpbmcgICAgICAgICAgICAgICAgICBzdHJpbmcKKy8vICAgQ1BQVFlQRV9NRVNTQUdFICAgICAgZ2VuZXJhdGVkIG1lc3NhZ2UgdHlwZSAgZ29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZQorLy8gICAgICAgICAgICAgICAgICAgICAgICBvciBnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlCisvLworLy8gTm90ZSB0aGF0IGZvciBlbnVtcyB3ZSB1c2UgaW50MzIgaW4gdGhlIGludGVyZmFjZS4KKy8vCisvLyBZb3UgY2FuIG1hcCBmcm9tIFQgdG8gdGhlIGFjdHVhbCB0eXBlIHVzaW5nIFJlZlR5cGVUcmFpdHM6CisvLyAgIHR5cGVkZWYgUmVmVHlwZVRyYWl0czxUPjo6QWNjZXNzb3JWYWx1ZVR5cGUgQWN0dWFsVHlwZTsKK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBSZXBlYXRlZEZpZWxkQWNjZXNzb3IgeworIHB1YmxpYzoKKyAgLy8gVHlwZWRlZnMgZm9yIGNsYXJpdHkuCisgIHR5cGVkZWYgdm9pZCBGaWVsZDsKKyAgdHlwZWRlZiB2b2lkIFZhbHVlOworICB0eXBlZGVmIHZvaWQgSXRlcmF0b3I7CisKKyAgdmlydHVhbCB+UmVwZWF0ZWRGaWVsZEFjY2Vzc29yKCk7CisgIHZpcnR1YWwgYm9vbCBJc0VtcHR5KGNvbnN0IEZpZWxkKiBkYXRhKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgaW50IFNpemUoY29uc3QgRmllbGQqIGRhdGEpIGNvbnN0ID0gMDsKKyAgLy8gRGVwZW5kcyBvbiB0aGUgdW5kZXJseWluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgcmVwZWF0ZWQgZmllbGQsIHRoaXMKKyAgLy8gbWV0aG9kIGNhbiByZXR1cm4gYSBwb2ludGVyIHRvIHRoZSB1bmRlcmx5aW5nIG9iamVjdCBpZiBzdWNoIGFuIG9iamVjdAorICAvLyBleGlzdHMsIG9yIGZpbGwgdGhlIGRhdGEgaW50byBzY3JhdGNoX3NwYWNlIGFuZCByZXR1cm4gc2NyYXRjaF9zcGFjZS4KKyAgLy8gQ2FsbGVycyBvZiB0aGlzIG1ldGhvZCBtdXN0IGVuc3VyZSBzY3JhdGNoX3NwYWNlIGlzIGEgdmFsaWQgcG9pbnRlcgorICAvLyB0byBhIG11dGFibGUgb2JqZWN0IG9mIHRoZSBjb3JyZWN0IHR5cGUuCisgIHZpcnR1YWwgY29uc3QgVmFsdWUqIEdldCgKKyAgICAgIGNvbnN0IEZpZWxkKiBkYXRhLCBpbnQgaW5kZXgsIFZhbHVlKiBzY3JhdGNoX3NwYWNlKSBjb25zdCA9IDA7CisKKyAgdmlydHVhbCB2b2lkIENsZWFyKEZpZWxkKiBkYXRhKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBTZXQoRmllbGQqIGRhdGEsIGludCBpbmRleCwgY29uc3QgVmFsdWUqIHZhbHVlKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBBZGQoRmllbGQqIGRhdGEsIGNvbnN0IFZhbHVlKiB2YWx1ZSkgY29uc3QgPSAwOworICB2aXJ0dWFsIHZvaWQgUmVtb3ZlTGFzdChGaWVsZCogZGF0YSkgY29uc3QgPSAwOworICB2aXJ0dWFsIHZvaWQgU3dhcEVsZW1lbnRzKEZpZWxkKiBkYXRhLCBpbnQgaW5kZXgxLCBpbnQgaW5kZXgyKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBTd2FwKEZpZWxkKiBkYXRhLCBjb25zdCBSZXBlYXRlZEZpZWxkQWNjZXNzb3IqIG90aGVyX211dGF0b3IsCisgICAgICAgICAgICAgICAgICAgIEZpZWxkKiBvdGhlcl9kYXRhKSBjb25zdCA9IDA7CisKKyAgLy8gQ3JlYXRlIGFuIGl0ZXJhdG9yIHRoYXQgcG9pbnRzIGF0IHRoZSBiZWdpbmluZyBvZiB0aGUgcmVwZWF0ZWQgZmllbGQuCisgIHZpcnR1YWwgSXRlcmF0b3IqIEJlZ2luSXRlcmF0b3IoY29uc3QgRmllbGQqIGRhdGEpIGNvbnN0ID0gMDsKKyAgLy8gQ3JlYXRlIGFuIGl0ZXJhdG9yIHRoYXQgcG9pbnRzIGF0IHRoZSBlbmQgb2YgdGhlIHJlcGVhdGVkIGZpZWxkLgorICB2aXJ0dWFsIEl0ZXJhdG9yKiBFbmRJdGVyYXRvcihjb25zdCBGaWVsZCogZGF0YSkgY29uc3QgPSAwOworICAvLyBNYWtlIGEgY29weSBvZiBhbiBpdGVyYXRvciBhbmQgcmV0dXJuIHRoZSBuZXcgY29weS4KKyAgdmlydHVhbCBJdGVyYXRvciogQ29weUl0ZXJhdG9yKGNvbnN0IEZpZWxkKiBkYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgSXRlcmF0b3IqIGl0ZXJhdG9yKSBjb25zdCA9IDA7CisgIC8vIE1vdmUgYW4gaXRlcmF0b3IgdG8gcG9pbnQgdG8gdGhlIG5leHQgZWxlbWVudC4KKyAgdmlydHVhbCBJdGVyYXRvciogQWR2YW5jZUl0ZXJhdG9yKGNvbnN0IEZpZWxkKiBkYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSXRlcmF0b3IqIGl0ZXJhdG9yKSBjb25zdCA9IDA7CisgIC8vIENvbXBhcmUgd2hldGhlciB0d28gaXRlcmF0b3JzIHBvaW50IHRvIHRoZSBzYW1lIGVsZW1lbnQuCisgIHZpcnR1YWwgYm9vbCBFcXVhbHNJdGVyYXRvcihjb25zdCBGaWVsZCogZGF0YSwgY29uc3QgSXRlcmF0b3IqIGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBJdGVyYXRvciogYikgY29uc3QgPSAwOworICAvLyBEZWxldGUgYW4gaXRlcmF0b3IgY3JlYXRlZCBieSBCZWdpbkl0ZXJhdG9yKCksIEVuZEl0ZXJhdG9yKCkgYW5kCisgIC8vIENvcHlJdGVyYXRvcigpLgorICB2aXJ0dWFsIHZvaWQgRGVsZXRlSXRlcmF0b3IoY29uc3QgRmllbGQqIGRhdGEsIEl0ZXJhdG9yKiBpdGVyYXRvcikgY29uc3QgPSAwOworICAvLyBMaWtlIEdldCgpIGJ1dCBmb3IgaXRlcmF0b3JzLgorICB2aXJ0dWFsIGNvbnN0IFZhbHVlKiBHZXRJdGVyYXRvclZhbHVlKGNvbnN0IEZpZWxkKiBkYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEl0ZXJhdG9yKiBpdGVyYXRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWYWx1ZSogc2NyYXRjaF9zcGFjZSkgY29uc3QgPSAwOworCisgIC8vIFRlbXBsYXRlZCBtZXRob2RzIHRoYXQgbWFrZSB1c2luZyB0aGlzIGludGVyZmFjZSBlYXNpZXIgZm9yIG5vbi1tZXNzYWdlCisgIC8vIHR5cGVzLgorICB0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorICBUIEdldChjb25zdCBGaWVsZCogZGF0YSwgaW50IGluZGV4KSBjb25zdCB7CisgICAgdHlwZWRlZiB0eXBlbmFtZSBSZWZUeXBlVHJhaXRzPFQ+OjpBY2Nlc3NvclZhbHVlVHlwZSBBY3R1YWxUeXBlOworICAgIEFjdHVhbFR5cGUgc2NyYXRjaF9zcGFjZTsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8VD4oCisgICAgICAgICpyZWludGVycHJldF9jYXN0PGNvbnN0IEFjdHVhbFR5cGUqPigKKyAgICAgICAgICAgIEdldChkYXRhLCBpbmRleCwgc3RhdGljX2Nhc3Q8VmFsdWUqPigmc2NyYXRjaF9zcGFjZSkpKSk7CisgIH0KKworICB0ZW1wbGF0ZTx0eXBlbmFtZSBULCB0eXBlbmFtZSBWYWx1ZVR5cGU+CisgIHZvaWQgU2V0KEZpZWxkKiBkYXRhLCBpbnQgaW5kZXgsIGNvbnN0IFZhbHVlVHlwZSYgdmFsdWUpIGNvbnN0IHsKKyAgICB0eXBlZGVmIHR5cGVuYW1lIFJlZlR5cGVUcmFpdHM8VD46OkFjY2Vzc29yVmFsdWVUeXBlIEFjdHVhbFR5cGU7CisgICAgLy8gSW4gdGhpcyBSZXBlYXRlZEZpZWxkQWNjZXNzb3IgaW50ZXJmYWNlIHdlIHBhc3MvcmV0dXJuIGRhdGEgdXNpbmcKKyAgICAvLyByYXcgcG9pbnRlcnMuIFR5cGUgb2YgdGhlIGRhdGEgdGhlc2UgcmF3IHBvaW50ZXJzIHBvaW50IHRvIHNob3VsZAorICAgIC8vIGJlIEFjdHVhbFR5cGUuIEhlcmUgd2UgaGF2ZSBhIFZhbHVlVHlwZSBvYmplY3QgYW5kIHdhbnQgYSBBY3R1YWxUeXBlCisgICAgLy8gcG9pbnRlci4gV2UgY2FuJ3QgY2FzdCBhIFZhbHVlVHlwZSBwb2ludGVyIHRvIGFuIEFjdHVhbFR5cGUgcG9pbnRlcgorICAgIC8vIGRpcmVjdGx5IGJlY2F1c2UgdGhlaXIgdHlwZSBtaWdodCBiZSBkaWZmZXJlbnQgKGZvciBlbnVtcyBWYWx1ZVR5cGUKKyAgICAvLyBtYXkgYmUgYSBnZW5lcmF0ZWQgZW51bSB0eXBlIHdoaWxlIEFjdHVhbFR5cGUgaXMgaW50MzIpLiBUbyBiZSBzYWZlCisgICAgLy8gd2UgbWFrZSBhIGNvcHkgdG8gZ2V0IGEgdGVtcG9yYXJ5IEFjdHVhbFR5cGUgb2JqZWN0IGFuZCB1c2UgaXQuCisgICAgQWN0dWFsVHlwZSB0bXAgPSBzdGF0aWNfY2FzdDxBY3R1YWxUeXBlPih2YWx1ZSk7CisgICAgU2V0KGRhdGEsIGluZGV4LCBzdGF0aWNfY2FzdDxjb25zdCBWYWx1ZSo+KCZ0bXApKTsKKyAgfQorCisgIHRlbXBsYXRlPHR5cGVuYW1lIFQsIHR5cGVuYW1lIFZhbHVlVHlwZT4KKyAgdm9pZCBBZGQoRmllbGQqIGRhdGEsIGNvbnN0IFZhbHVlVHlwZSYgdmFsdWUpIGNvbnN0IHsKKyAgICB0eXBlZGVmIHR5cGVuYW1lIFJlZlR5cGVUcmFpdHM8VD46OkFjY2Vzc29yVmFsdWVUeXBlIEFjdHVhbFR5cGU7CisgICAgLy8gSW4gdGhpcyBSZXBlYXRlZEZpZWxkQWNjZXNzb3IgaW50ZXJmYWNlIHdlIHBhc3MvcmV0dXJuIGRhdGEgdXNpbmcKKyAgICAvLyByYXcgcG9pbnRlcnMuIFR5cGUgb2YgdGhlIGRhdGEgdGhlc2UgcmF3IHBvaW50ZXJzIHBvaW50IHRvIHNob3VsZAorICAgIC8vIGJlIEFjdHVhbFR5cGUuIEhlcmUgd2UgaGF2ZSBhIFZhbHVlVHlwZSBvYmplY3QgYW5kIHdhbnQgYSBBY3R1YWxUeXBlCisgICAgLy8gcG9pbnRlci4gV2UgY2FuJ3QgY2FzdCBhIFZhbHVlVHlwZSBwb2ludGVyIHRvIGFuIEFjdHVhbFR5cGUgcG9pbnRlcgorICAgIC8vIGRpcmVjdGx5IGJlY2F1c2UgdGhlaXIgdHlwZSBtaWdodCBiZSBkaWZmZXJlbnQgKGZvciBlbnVtcyBWYWx1ZVR5cGUKKyAgICAvLyBtYXkgYmUgYSBnZW5lcmF0ZWQgZW51bSB0eXBlIHdoaWxlIEFjdHVhbFR5cGUgaXMgaW50MzIpLiBUbyBiZSBzYWZlCisgICAgLy8gd2UgbWFrZSBhIGNvcHkgdG8gZ2V0IGEgdGVtcG9yYXJ5IEFjdHVhbFR5cGUgb2JqZWN0IGFuZCB1c2UgaXQuCisgICAgQWN0dWFsVHlwZSB0bXAgPSBzdGF0aWNfY2FzdDxBY3R1YWxUeXBlPih2YWx1ZSk7CisgICAgQWRkKGRhdGEsIHN0YXRpY19jYXN0PGNvbnN0IFZhbHVlKj4oJnRtcCkpOworICB9Cit9OworCisvLyBJbXBsZW1lbnQgKE11dGFibGUpUmVwZWF0ZWRGaWVsZFJlZjo6aXRlcmF0b3IKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+CitjbGFzcyBSZXBlYXRlZEZpZWxkUmVmSXRlcmF0b3IKKyAgICA6IHB1YmxpYyBzdGQ6Oml0ZXJhdG9yPHN0ZDo6Zm9yd2FyZF9pdGVyYXRvcl90YWcsIFQ+IHsKKyAgdHlwZWRlZiB0eXBlbmFtZSBSZWZUeXBlVHJhaXRzPFQ+OjpBY2Nlc3NvclZhbHVlVHlwZSBBY2Nlc3NvclZhbHVlVHlwZTsKKyAgdHlwZWRlZiB0eXBlbmFtZSBSZWZUeXBlVHJhaXRzPFQ+OjpJdGVyYXRvclZhbHVlVHlwZSBJdGVyYXRvclZhbHVlVHlwZTsKKyAgdHlwZWRlZiB0eXBlbmFtZSBSZWZUeXBlVHJhaXRzPFQ+OjpJdGVyYXRvclBvaW50ZXJUeXBlIEl0ZXJhdG9yUG9pbnRlclR5cGU7CisKKyBwdWJsaWM6CisgIC8vIENvbnN0cnVjdG9yIGZvciBub24tbWVzc2FnZSBmaWVsZHMuCisgIFJlcGVhdGVkRmllbGRSZWZJdGVyYXRvcihjb25zdCB2b2lkKiBkYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUmVwZWF0ZWRGaWVsZEFjY2Vzc29yKiBhY2Nlc3NvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgYmVnaW4pCisgICAgICA6IGRhdGFfKGRhdGEpLCBhY2Nlc3Nvcl8oYWNjZXNzb3IpLAorICAgICAgICBpdGVyYXRvcl8oYmVnaW4gPyBhY2Nlc3Nvci0+QmVnaW5JdGVyYXRvcihkYXRhKSA6CisgICAgICAgICAgICAgICAgICAgICAgICAgIGFjY2Vzc29yLT5FbmRJdGVyYXRvcihkYXRhKSksCisgICAgICAgIHNjcmF0Y2hfc3BhY2VfKG5ldyBBY2Nlc3NvclZhbHVlVHlwZSkgeworICB9CisgIC8vIENvbnN0cnVjdG9yIGZvciBtZXNzYWdlIGZpZWxkcy4KKyAgUmVwZWF0ZWRGaWVsZFJlZkl0ZXJhdG9yKGNvbnN0IHZvaWQqIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBSZXBlYXRlZEZpZWxkQWNjZXNzb3IqIGFjY2Vzc29yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBiZWdpbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIEFjY2Vzc29yVmFsdWVUeXBlKiBzY3JhdGNoX3NwYWNlKQorICAgICAgOiBkYXRhXyhkYXRhKSwgYWNjZXNzb3JfKGFjY2Vzc29yKSwKKyAgICAgICAgaXRlcmF0b3JfKGJlZ2luID8gYWNjZXNzb3ItPkJlZ2luSXRlcmF0b3IoZGF0YSkgOgorICAgICAgICAgICAgICAgICAgICAgICAgICBhY2Nlc3Nvci0+RW5kSXRlcmF0b3IoZGF0YSkpLAorICAgICAgICBzY3JhdGNoX3NwYWNlXyhzY3JhdGNoX3NwYWNlKSB7CisgIH0KKyAgflJlcGVhdGVkRmllbGRSZWZJdGVyYXRvcigpIHsKKyAgICBhY2Nlc3Nvcl8tPkRlbGV0ZUl0ZXJhdG9yKGRhdGFfLCBpdGVyYXRvcl8pOworICB9CisgIFJlcGVhdGVkRmllbGRSZWZJdGVyYXRvciBvcGVyYXRvcisrKGludCkgeworICAgIFJlcGVhdGVkRmllbGRSZWZJdGVyYXRvciB0bXAoKnRoaXMpOworICAgIGl0ZXJhdG9yXyA9IGFjY2Vzc29yXy0+QWR2YW5jZUl0ZXJhdG9yKGRhdGFfLCBpdGVyYXRvcl8pOworICAgIHJldHVybiB0bXA7CisgIH0KKyAgUmVwZWF0ZWRGaWVsZFJlZkl0ZXJhdG9yJiBvcGVyYXRvcisrKCkgeworICAgIGl0ZXJhdG9yXyA9IGFjY2Vzc29yXy0+QWR2YW5jZUl0ZXJhdG9yKGRhdGFfLCBpdGVyYXRvcl8pOworICAgIHJldHVybiAqdGhpczsKKyAgfQorICBJdGVyYXRvclZhbHVlVHlwZSBvcGVyYXRvciooKSBjb25zdCB7CisgICAgcmV0dXJuIHN0YXRpY19jYXN0PEl0ZXJhdG9yVmFsdWVUeXBlPigKKyAgICAgICAgKnN0YXRpY19jYXN0PGNvbnN0IEFjY2Vzc29yVmFsdWVUeXBlKj4oCisgICAgICAgICAgICBhY2Nlc3Nvcl8tPkdldEl0ZXJhdG9yVmFsdWUoCisgICAgICAgICAgICAgICAgZGF0YV8sIGl0ZXJhdG9yXywgc2NyYXRjaF9zcGFjZV8uZ2V0KCkpKSk7CisgIH0KKyAgSXRlcmF0b3JQb2ludGVyVHlwZSBvcGVyYXRvci0+KCkgY29uc3QgeworICAgIHJldHVybiBzdGF0aWNfY2FzdDxJdGVyYXRvclBvaW50ZXJUeXBlPigKKyAgICAgICAgYWNjZXNzb3JfLT5HZXRJdGVyYXRvclZhbHVlKAorICAgICAgICAgICAgZGF0YV8sIGl0ZXJhdG9yXywgc2NyYXRjaF9zcGFjZV8uZ2V0KCkpKTsKKyAgfQorICBib29sIG9wZXJhdG9yIT0oY29uc3QgUmVwZWF0ZWRGaWVsZFJlZkl0ZXJhdG9yJiBvdGhlcikgY29uc3QgeworICAgIGFzc2VydChkYXRhXyA9PSBvdGhlci5kYXRhXyk7CisgICAgYXNzZXJ0KGFjY2Vzc29yXyA9PSBvdGhlci5hY2Nlc3Nvcl8pOworICAgIHJldHVybiAhYWNjZXNzb3JfLT5FcXVhbHNJdGVyYXRvcihkYXRhXywgaXRlcmF0b3JfLCBvdGhlci5pdGVyYXRvcl8pOworICB9CisgIGJvb2wgb3BlcmF0b3I9PShjb25zdCBSZXBlYXRlZEZpZWxkUmVmSXRlcmF0b3ImIG90aGVyKSBjb25zdCB7CisgICAgcmV0dXJuICF0aGlzLT5vcGVyYXRvciE9KG90aGVyKTsKKyAgfQorCisgIFJlcGVhdGVkRmllbGRSZWZJdGVyYXRvcihjb25zdCBSZXBlYXRlZEZpZWxkUmVmSXRlcmF0b3ImIG90aGVyKQorICAgICAgOiBkYXRhXyhvdGhlci5kYXRhXyksIGFjY2Vzc29yXyhvdGhlci5hY2Nlc3Nvcl8pLAorICAgICAgICBpdGVyYXRvcl8oYWNjZXNzb3JfLT5Db3B5SXRlcmF0b3IoZGF0YV8sIG90aGVyLml0ZXJhdG9yXykpIHsKKyAgfQorICBSZXBlYXRlZEZpZWxkUmVmSXRlcmF0b3ImIG9wZXJhdG9yPShjb25zdCBSZXBlYXRlZEZpZWxkUmVmSXRlcmF0b3ImIG90aGVyKSB7CisgICAgaWYgKHRoaXMgIT0gJm90aGVyKSB7CisgICAgICBhY2Nlc3Nvcl8tPkRlbGV0ZUl0ZXJhdG9yKGRhdGFfLCBpdGVyYXRvcl8pOworICAgICAgZGF0YV8gPSBvdGhlci5kYXRhXzsKKyAgICAgIGFjY2Vzc29yXyA9IG90aGVyLmFjY2Vzc29yXzsKKyAgICAgIGl0ZXJhdG9yXyA9IGFjY2Vzc29yXy0+Q29weUl0ZXJhdG9yKGRhdGFfLCBvdGhlci5pdGVyYXRvcl8pOworICAgIH0KKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworIHByb3RlY3RlZDoKKyAgY29uc3Qgdm9pZCogZGF0YV87CisgIGNvbnN0IFJlcGVhdGVkRmllbGRBY2Nlc3NvciogYWNjZXNzb3JfOworICB2b2lkKiBpdGVyYXRvcl87CisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8QWNjZXNzb3JWYWx1ZVR5cGU+IHNjcmF0Y2hfc3BhY2VfOworfTsKKworLy8gVHlwZVRyYWl0cyB0aGF0IG1hcHMgdGhlIHR5cGUgcGFyYW1ldGVyIFQgb2YgUmVwZWF0ZWRGaWVsZFJlZiBvcgorLy8gTXV0YWJsZVJlcGVhdGVkRmllbGRSZWYgdG8gY29ycmVzcG9uZGluZyBpdGVyYXRvciB0eXBlLAorLy8gUmVwZWF0ZWRGaWVsZEFjY2Vzc29yIHR5cGUsIGV0Yy4KK3RlbXBsYXRlPHR5cGVuYW1lIFQ+CitzdHJ1Y3QgUHJpbWl0aXZlVHJhaXRzIHsKKyAgc3RhdGljIGNvbnN0IGJvb2wgaXNfcHJpbWl0aXZlID0gZmFsc2U7Cit9OworI2RlZmluZSBERUZJTkVfUFJJTUlUSVZFKFRZUEUsIHR5cGUpIFwKKyAgICB0ZW1wbGF0ZTw+IHN0cnVjdCBQcmltaXRpdmVUcmFpdHM8dHlwZT4geyBcCisgICAgICBzdGF0aWMgY29uc3QgYm9vbCBpc19wcmltaXRpdmUgPSB0cnVlOyBcCisgICAgICBzdGF0aWMgY29uc3QgRmllbGREZXNjcmlwdG9yOjpDcHBUeXBlIGNwcF90eXBlID0gXAorICAgICAgICAgIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV8gIyMgVFlQRTsgXAorICAgIH07CitERUZJTkVfUFJJTUlUSVZFKElOVDMyLCBpbnQzMikKK0RFRklORV9QUklNSVRJVkUoVUlOVDMyLCB1aW50MzIpCitERUZJTkVfUFJJTUlUSVZFKElOVDY0LCBpbnQ2NCkKK0RFRklORV9QUklNSVRJVkUoVUlOVDY0LCB1aW50NjQpCitERUZJTkVfUFJJTUlUSVZFKEZMT0FULCBmbG9hdCkKK0RFRklORV9QUklNSVRJVkUoRE9VQkxFLCBkb3VibGUpCitERUZJTkVfUFJJTUlUSVZFKEJPT0wsIGJvb2wpCisjdW5kZWYgREVGSU5FX1BSSU1JVElWRQorCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorc3RydWN0IFJlZlR5cGVUcmFpdHM8CisgICAgVCwgdHlwZW5hbWUgaW50ZXJuYWw6OmVuYWJsZV9pZjxQcmltaXRpdmVUcmFpdHM8VD46OmlzX3ByaW1pdGl2ZT46OnR5cGU+IHsKKyAgdHlwZWRlZiBSZXBlYXRlZEZpZWxkUmVmSXRlcmF0b3I8VD4gaXRlcmF0b3I7CisgIHR5cGVkZWYgUmVwZWF0ZWRGaWVsZEFjY2Vzc29yIEFjY2Vzc29yVHlwZTsKKyAgdHlwZWRlZiBUIEFjY2Vzc29yVmFsdWVUeXBlOworICB0eXBlZGVmIFQgSXRlcmF0b3JWYWx1ZVR5cGU7CisgIHR5cGVkZWYgVCogSXRlcmF0b3JQb2ludGVyVHlwZTsKKyAgc3RhdGljIGNvbnN0IEZpZWxkRGVzY3JpcHRvcjo6Q3BwVHlwZSBjcHBfdHlwZSA9CisgICAgICBQcmltaXRpdmVUcmFpdHM8VD46OmNwcF90eXBlOworICBzdGF0aWMgY29uc3QgRGVzY3JpcHRvciogR2V0TWVzc2FnZUZpZWxkRGVzY3JpcHRvcigpIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorfTsKKwordGVtcGxhdGU8dHlwZW5hbWUgVD4KK3N0cnVjdCBSZWZUeXBlVHJhaXRzPAorICAgIFQsIHR5cGVuYW1lIGludGVybmFsOjplbmFibGVfaWY8aXNfcHJvdG9fZW51bTxUPjo6dmFsdWU+Ojp0eXBlPiB7CisgIHR5cGVkZWYgUmVwZWF0ZWRGaWVsZFJlZkl0ZXJhdG9yPFQ+IGl0ZXJhdG9yOworICB0eXBlZGVmIFJlcGVhdGVkRmllbGRBY2Nlc3NvciBBY2Nlc3NvclR5cGU7CisgIC8vIFdlIHVzZSBpbnQzMiBmb3IgcmVwZWF0ZWQgZW51bXMgaW4gUmVwZWF0ZWRGaWVsZEFjY2Vzc29yLgorICB0eXBlZGVmIGludDMyIEFjY2Vzc29yVmFsdWVUeXBlOworICB0eXBlZGVmIFQgSXRlcmF0b3JWYWx1ZVR5cGU7CisgIHR5cGVkZWYgaW50MzIqIEl0ZXJhdG9yUG9pbnRlclR5cGU7CisgIHN0YXRpYyBjb25zdCBGaWVsZERlc2NyaXB0b3I6OkNwcFR5cGUgY3BwX3R5cGUgPQorICAgICAgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0VOVU07CisgIHN0YXRpYyBjb25zdCBEZXNjcmlwdG9yKiBHZXRNZXNzYWdlRmllbGREZXNjcmlwdG9yKCkgeworICAgIHJldHVybiBOVUxMOworICB9Cit9OworCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorc3RydWN0IFJlZlR5cGVUcmFpdHM8CisgICAgVCwgdHlwZW5hbWUgaW50ZXJuYWw6OmVuYWJsZV9pZjwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6aXNfc2FtZTxzdHJpbmcsIFQ+Ojp2YWx1ZT46OnR5cGU+IHsKKyAgdHlwZWRlZiBSZXBlYXRlZEZpZWxkUmVmSXRlcmF0b3I8VD4gaXRlcmF0b3I7CisgIHR5cGVkZWYgUmVwZWF0ZWRGaWVsZEFjY2Vzc29yIEFjY2Vzc29yVHlwZTsKKyAgdHlwZWRlZiBzdHJpbmcgQWNjZXNzb3JWYWx1ZVR5cGU7CisgIHR5cGVkZWYgc3RyaW5nIEl0ZXJhdG9yVmFsdWVUeXBlOworICB0eXBlZGVmIHN0cmluZyogSXRlcmF0b3JQb2ludGVyVHlwZTsKKyAgc3RhdGljIGNvbnN0IEZpZWxkRGVzY3JpcHRvcjo6Q3BwVHlwZSBjcHBfdHlwZSA9CisgICAgICBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HOworICBzdGF0aWMgY29uc3QgRGVzY3JpcHRvciogR2V0TWVzc2FnZUZpZWxkRGVzY3JpcHRvcigpIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorfTsKKwordGVtcGxhdGU8dHlwZW5hbWUgVD4KK3N0cnVjdCBNZXNzYWdlRGVzY3JpcHRvckdldHRlciB7CisgIHN0YXRpYyBjb25zdCBEZXNjcmlwdG9yKiBnZXQoKSB7CisgICAgcmV0dXJuIFQ6OmRlZmF1bHRfaW5zdGFuY2UoKS5HZXREZXNjcmlwdG9yKCk7CisgIH0KK307Cit0ZW1wbGF0ZTw+CitzdHJ1Y3QgTWVzc2FnZURlc2NyaXB0b3JHZXR0ZXI8TWVzc2FnZT4geworICBzdGF0aWMgY29uc3QgRGVzY3JpcHRvciogZ2V0KCkgeworICAgIHJldHVybiBOVUxMOworICB9Cit9OworCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorc3RydWN0IFJlZlR5cGVUcmFpdHM8CisgICAgVCwgdHlwZW5hbWUgaW50ZXJuYWw6OmVuYWJsZV9pZjxpbnRlcm5hbDo6aXNfYmFzZV9vZjxNZXNzYWdlLCBUPjo6dmFsdWU+Ojp0eXBlPiB7CisgIHR5cGVkZWYgUmVwZWF0ZWRGaWVsZFJlZkl0ZXJhdG9yPFQ+IGl0ZXJhdG9yOworICB0eXBlZGVmIFJlcGVhdGVkRmllbGRBY2Nlc3NvciBBY2Nlc3NvclR5cGU7CisgIHR5cGVkZWYgTWVzc2FnZSBBY2Nlc3NvclZhbHVlVHlwZTsKKyAgdHlwZWRlZiBjb25zdCBUJiBJdGVyYXRvclZhbHVlVHlwZTsKKyAgdHlwZWRlZiBjb25zdCBUKiBJdGVyYXRvclBvaW50ZXJUeXBlOworICBzdGF0aWMgY29uc3QgRmllbGREZXNjcmlwdG9yOjpDcHBUeXBlIGNwcF90eXBlID0KKyAgICAgIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOworICBzdGF0aWMgY29uc3QgRGVzY3JpcHRvciogR2V0TWVzc2FnZUZpZWxkRGVzY3JpcHRvcigpIHsKKyAgICByZXR1cm4gTWVzc2FnZURlc2NyaXB0b3JHZXR0ZXI8VD46OmdldCgpOworICB9Cit9OworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfUkVGTEVDVElPTl9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvcmVmbGVjdGlvbl9pbnRlcm5hbC5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9yZWZsZWN0aW9uX2ludGVybmFsLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmNiNDI0NwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvcmVmbGVjdGlvbl9pbnRlcm5hbC5oCkBAIC0wLDAgKzEsMzc4IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfUkVGTEVDVElPTl9JTlRFUk5BTF9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1JFRkxFQ1RJT05fSU5URVJOQUxfSF9fCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWFwX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3JlZmxlY3Rpb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcmVwZWF0ZWRfZmllbGQuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKy8vIEEgYmFzZSBjbGFzcyBmb3IgUmVwZWF0ZWRGaWVsZEFjY2Vzc29yIGltcGxlbWVudGF0aW9ucyB0aGF0IGNhbiBzdXBwb3J0CisvLyByYW5kb20tYWNjZXNzIGVmZmljaWVudGx5LiBBbGwgaXRlcmF0b3IgbWV0aG9kcyBkZWxlZ2F0ZXMgdGhlIHdvcmsgdG8KKy8vIGNvcnJlc3BvbmRpbmcgcmFuZG9tLWFjY2VzcyBtZXRob2RzLgorY2xhc3MgUmFuZG9tQWNjZXNzUmVwZWF0ZWRGaWVsZEFjY2Vzc29yIDogcHVibGljIFJlcGVhdGVkRmllbGRBY2Nlc3NvciB7CisgcHVibGljOgorICB2aXJ0dWFsIH5SYW5kb21BY2Nlc3NSZXBlYXRlZEZpZWxkQWNjZXNzb3IoKSB7fQorCisgIHZpcnR1YWwgSXRlcmF0b3IqIEJlZ2luSXRlcmF0b3IoY29uc3QgRmllbGQqIGRhdGEpIGNvbnN0IHsKKyAgICByZXR1cm4gUG9zaXRpb25Ub0l0ZXJhdG9yKDApOworICB9CisgIHZpcnR1YWwgSXRlcmF0b3IqIEVuZEl0ZXJhdG9yKGNvbnN0IEZpZWxkKiBkYXRhKSBjb25zdCB7CisgICAgcmV0dXJuIFBvc2l0aW9uVG9JdGVyYXRvcih0aGlzLT5TaXplKGRhdGEpKTsKKyAgfQorICB2aXJ0dWFsIEl0ZXJhdG9yKiBDb3B5SXRlcmF0b3IoY29uc3QgRmllbGQqIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBJdGVyYXRvciogaXRlcmF0b3IpIGNvbnN0IHsKKyAgICByZXR1cm4gY29uc3RfY2FzdDxJdGVyYXRvcio+KGl0ZXJhdG9yKTsKKyAgfQorICB2aXJ0dWFsIEl0ZXJhdG9yKiBBZHZhbmNlSXRlcmF0b3IoY29uc3QgRmllbGQqIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJdGVyYXRvciogaXRlcmF0b3IpIGNvbnN0IHsKKyAgICByZXR1cm4gUG9zaXRpb25Ub0l0ZXJhdG9yKEl0ZXJhdG9yVG9Qb3NpdGlvbihpdGVyYXRvcikgKyAxKTsKKyAgfQorICB2aXJ0dWFsIGJvb2wgRXF1YWxzSXRlcmF0b3IoY29uc3QgRmllbGQqIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBJdGVyYXRvciogYSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEl0ZXJhdG9yKiBiKSBjb25zdCB7CisgICAgcmV0dXJuIGEgPT0gYjsKKyAgfQorICB2aXJ0dWFsIHZvaWQgRGVsZXRlSXRlcmF0b3IoY29uc3QgRmllbGQqIGRhdGEsIEl0ZXJhdG9yKiBpdGVyYXRvcikgY29uc3QgeworICB9CisgIHZpcnR1YWwgY29uc3QgVmFsdWUqIEdldEl0ZXJhdG9yVmFsdWUoY29uc3QgRmllbGQqIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgSXRlcmF0b3IqIGl0ZXJhdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZhbHVlKiBzY3JhdGNoX3NwYWNlKSBjb25zdCB7CisgICAgcmV0dXJuIEdldChkYXRhLCBzdGF0aWNfY2FzdDxpbnQ+KEl0ZXJhdG9yVG9Qb3NpdGlvbihpdGVyYXRvcikpLAorICAgICAgICAgICAgICAgc2NyYXRjaF9zcGFjZSk7CisgIH0KKworIHByaXZhdGU6CisgIHN0YXRpYyBpbnRwdHJfdCBJdGVyYXRvclRvUG9zaXRpb24oY29uc3QgSXRlcmF0b3IqIGl0ZXJhdG9yKSB7CisgICAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8aW50cHRyX3Q+KGl0ZXJhdG9yKTsKKyAgfQorICBzdGF0aWMgSXRlcmF0b3IqIFBvc2l0aW9uVG9JdGVyYXRvcihpbnRwdHJfdCBwb3NpdGlvbikgeworICAgIHJldHVybiByZWludGVycHJldF9jYXN0PEl0ZXJhdG9yKj4ocG9zaXRpb24pOworICB9Cit9OworCisvLyBCYXNlIGNsYXNzIGZvciBSZXBlYXRlZEZpZWxkQWNjZXNzb3IgaW1wbGVtZW50YXRpb25zIHRoYXQgbWFuaXB1bGF0ZXMKKy8vIFJlcGVhdGVkRmllbGQ8VD4uCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorY2xhc3MgUmVwZWF0ZWRGaWVsZFdyYXBwZXIgOiBwdWJsaWMgUmFuZG9tQWNjZXNzUmVwZWF0ZWRGaWVsZEFjY2Vzc29yIHsKKyBwdWJsaWM6CisgIFJlcGVhdGVkRmllbGRXcmFwcGVyKCkge30KKyAgdmlydHVhbCB+UmVwZWF0ZWRGaWVsZFdyYXBwZXIoKSB7fQorICB2aXJ0dWFsIGJvb2wgSXNFbXB0eShjb25zdCBGaWVsZCogZGF0YSkgY29uc3QgeworICAgIHJldHVybiBHZXRSZXBlYXRlZEZpZWxkKGRhdGEpLT5lbXB0eSgpOworICB9CisgIHZpcnR1YWwgaW50IFNpemUoY29uc3QgRmllbGQqIGRhdGEpIGNvbnN0IHsKKyAgICByZXR1cm4gR2V0UmVwZWF0ZWRGaWVsZChkYXRhKS0+c2l6ZSgpOworICB9CisgIHZpcnR1YWwgY29uc3QgVmFsdWUqIEdldChjb25zdCBGaWVsZCogZGF0YSwgaW50IGluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICBWYWx1ZSogc2NyYXRjaF9zcGFjZSkgY29uc3QgeworICAgIHJldHVybiBDb252ZXJ0RnJvbVQoR2V0UmVwZWF0ZWRGaWVsZChkYXRhKS0+R2V0KGluZGV4KSwgc2NyYXRjaF9zcGFjZSk7CisgIH0KKyAgdmlydHVhbCB2b2lkIENsZWFyKEZpZWxkKiBkYXRhKSBjb25zdCB7CisgICAgTXV0YWJsZVJlcGVhdGVkRmllbGQoZGF0YSktPkNsZWFyKCk7CisgIH0KKyAgdmlydHVhbCB2b2lkIFNldChGaWVsZCogZGF0YSwgaW50IGluZGV4LCBjb25zdCBWYWx1ZSogdmFsdWUpIGNvbnN0IHsKKyAgICBNdXRhYmxlUmVwZWF0ZWRGaWVsZChkYXRhKS0+U2V0KGluZGV4LCBDb252ZXJ0VG9UKHZhbHVlKSk7CisgIH0KKyAgdmlydHVhbCB2b2lkIEFkZChGaWVsZCogZGF0YSwgY29uc3QgVmFsdWUqIHZhbHVlKSBjb25zdCB7CisgICAgTXV0YWJsZVJlcGVhdGVkRmllbGQoZGF0YSktPkFkZChDb252ZXJ0VG9UKHZhbHVlKSk7CisgIH0KKyAgdmlydHVhbCB2b2lkIFJlbW92ZUxhc3QoRmllbGQqIGRhdGEpIGNvbnN0IHsKKyAgICBNdXRhYmxlUmVwZWF0ZWRGaWVsZChkYXRhKS0+UmVtb3ZlTGFzdCgpOworICB9CisgIHZpcnR1YWwgdm9pZCBTd2FwRWxlbWVudHMoRmllbGQqIGRhdGEsIGludCBpbmRleDEsIGludCBpbmRleDIpIGNvbnN0IHsKKyAgICBNdXRhYmxlUmVwZWF0ZWRGaWVsZChkYXRhKS0+U3dhcEVsZW1lbnRzKGluZGV4MSwgaW5kZXgyKTsKKyAgfQorCisgcHJvdGVjdGVkOgorICB0eXBlZGVmIFJlcGVhdGVkRmllbGQ8VD4gUmVwZWF0ZWRGaWVsZFR5cGU7CisgIHN0YXRpYyBjb25zdCBSZXBlYXRlZEZpZWxkVHlwZSogR2V0UmVwZWF0ZWRGaWVsZChjb25zdCBGaWVsZCogZGF0YSkgeworICAgIHJldHVybiByZWludGVycHJldF9jYXN0PGNvbnN0IFJlcGVhdGVkRmllbGRUeXBlKj4oZGF0YSk7CisgIH0KKyAgc3RhdGljIFJlcGVhdGVkRmllbGRUeXBlKiBNdXRhYmxlUmVwZWF0ZWRGaWVsZChGaWVsZCogZGF0YSkgeworICAgIHJldHVybiByZWludGVycHJldF9jYXN0PFJlcGVhdGVkRmllbGRUeXBlKj4oZGF0YSk7CisgIH0KKworICAvLyBDb252ZXJ0IGFuIG9iamVjdCByZWNldmllZCBieSB0aGlzIGFjY2Vzc29yIHRvIGFuIG9iamVjdCB0byBiZSBzdG9yZWQgaW4KKyAgLy8gdGhlIHVuZGVybHlpbmcgUmVwZWF0ZWRGaWVsZC4KKyAgdmlydHVhbCBUIENvbnZlcnRUb1QoY29uc3QgVmFsdWUqIHZhbHVlKSBjb25zdCA9IDA7CisKKyAgLy8gQ29udmVydCBhbiBvYmplY3Qgc3RvcmVkIGluIFJlcGVhdGVkUHRyRmllbGQgdG8gYW4gb2JqZWN0IHRoYXQgd2lsbCBiZQorICAvLyByZXR1cm5lZCBieSB0aGlzIGFjY2Vzc29yLiBJZiB0aGUgdHdvIG9iamVjdHMgaGF2ZSB0aGUgc2FtZSB0eXBlICh0cnVlCisgIC8vIGZvciBzdHJpbmcgZmllbGRzIHdpdGggY3R5cGU9U1RSSU5HKSwgYSBwb2ludGVyIHRvIHRoZSBzb3VyY2Ugb2JqZWN0IGNhbgorICAvLyBiZSByZXR1cm5lZCBkaXJlY3RseS4gT3RoZXJ3aXNlLCBkYXRhIHNob3VsZCBiZSBjb3BpZWQgZnJvbSB2YWx1ZSB0bworICAvLyBzY3JhdGNoX3NwYWNlIGFuZCBzY3JhdGNoX3NwYWNlIHNob3VsZCBiZSByZXR1cm5lZC4KKyAgdmlydHVhbCBjb25zdCBWYWx1ZSogQ29udmVydEZyb21UKGNvbnN0IFQmIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmFsdWUqIHNjcmF0Y2hfc3BhY2UpIGNvbnN0ID0gMDsKK307CisKKy8vIEJhc2UgY2xhc3MgZm9yIFJlcGVhdGVkRmllbGRBY2Nlc3NvciBpbXBsZW1lbnRhdGlvbnMgdGhhdCBtYW5pcHVsYXRlcworLy8gUmVwZWF0ZWRQdHJGaWVsZDxUPi4KK3RlbXBsYXRlPHR5cGVuYW1lIFQ+CitjbGFzcyBSZXBlYXRlZFB0ckZpZWxkV3JhcHBlciA6IHB1YmxpYyBSYW5kb21BY2Nlc3NSZXBlYXRlZEZpZWxkQWNjZXNzb3IgeworIHB1YmxpYzoKKyAgUmVwZWF0ZWRQdHJGaWVsZFdyYXBwZXIoKSB7fQorICB2aXJ0dWFsIH5SZXBlYXRlZFB0ckZpZWxkV3JhcHBlcigpIHt9CisgIHZpcnR1YWwgYm9vbCBJc0VtcHR5KGNvbnN0IEZpZWxkKiBkYXRhKSBjb25zdCB7CisgICAgcmV0dXJuIEdldFJlcGVhdGVkRmllbGQoZGF0YSktPmVtcHR5KCk7CisgIH0KKyAgdmlydHVhbCBpbnQgU2l6ZShjb25zdCBGaWVsZCogZGF0YSkgY29uc3QgeworICAgIHJldHVybiBHZXRSZXBlYXRlZEZpZWxkKGRhdGEpLT5zaXplKCk7CisgIH0KKyAgdmlydHVhbCBjb25zdCBWYWx1ZSogR2V0KGNvbnN0IEZpZWxkKiBkYXRhLCBpbnQgaW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBWYWx1ZSogc2NyYXRjaF9zcGFjZSkgY29uc3QgeworICAgIHJldHVybiBDb252ZXJ0RnJvbVQoR2V0UmVwZWF0ZWRGaWVsZChkYXRhKS0+R2V0KGluZGV4KSwgc2NyYXRjaF9zcGFjZSk7CisgIH0KKyAgdmlydHVhbCB2b2lkIENsZWFyKEZpZWxkKiBkYXRhKSBjb25zdCB7CisgICAgTXV0YWJsZVJlcGVhdGVkRmllbGQoZGF0YSktPkNsZWFyKCk7CisgIH0KKyAgdmlydHVhbCB2b2lkIFNldChGaWVsZCogZGF0YSwgaW50IGluZGV4LCBjb25zdCBWYWx1ZSogdmFsdWUpIGNvbnN0IHsKKyAgICBDb252ZXJ0VG9UKHZhbHVlLCBNdXRhYmxlUmVwZWF0ZWRGaWVsZChkYXRhKS0+TXV0YWJsZShpbmRleCkpOworICB9CisgIHZpcnR1YWwgdm9pZCBBZGQoRmllbGQqIGRhdGEsIGNvbnN0IFZhbHVlKiB2YWx1ZSkgY29uc3QgeworICAgIFQqIGFsbG9jYXRlZCA9IE5ldyh2YWx1ZSk7CisgICAgQ29udmVydFRvVCh2YWx1ZSwgYWxsb2NhdGVkKTsKKyAgICBNdXRhYmxlUmVwZWF0ZWRGaWVsZChkYXRhKS0+QWRkQWxsb2NhdGVkKGFsbG9jYXRlZCk7CisgIH0KKyAgdmlydHVhbCB2b2lkIFJlbW92ZUxhc3QoRmllbGQqIGRhdGEpIGNvbnN0IHsKKyAgICBNdXRhYmxlUmVwZWF0ZWRGaWVsZChkYXRhKS0+UmVtb3ZlTGFzdCgpOworICB9CisgIHZpcnR1YWwgdm9pZCBTd2FwRWxlbWVudHMoRmllbGQqIGRhdGEsIGludCBpbmRleDEsIGludCBpbmRleDIpIGNvbnN0IHsKKyAgICBNdXRhYmxlUmVwZWF0ZWRGaWVsZChkYXRhKS0+U3dhcEVsZW1lbnRzKGluZGV4MSwgaW5kZXgyKTsKKyAgfQorCisgcHJvdGVjdGVkOgorICB0eXBlZGVmIFJlcGVhdGVkUHRyRmllbGQ8VD4gUmVwZWF0ZWRGaWVsZFR5cGU7CisgIHN0YXRpYyBjb25zdCBSZXBlYXRlZEZpZWxkVHlwZSogR2V0UmVwZWF0ZWRGaWVsZChjb25zdCBGaWVsZCogZGF0YSkgeworICAgIHJldHVybiByZWludGVycHJldF9jYXN0PGNvbnN0IFJlcGVhdGVkRmllbGRUeXBlKj4oZGF0YSk7CisgIH0KKyAgc3RhdGljIFJlcGVhdGVkRmllbGRUeXBlKiBNdXRhYmxlUmVwZWF0ZWRGaWVsZChGaWVsZCogZGF0YSkgeworICAgIHJldHVybiByZWludGVycHJldF9jYXN0PFJlcGVhdGVkRmllbGRUeXBlKj4oZGF0YSk7CisgIH0KKworICAvLyBDcmVhdGUgYSBuZXcgVCBpbnN0YW5jZS4gRm9yIHJlcGVhdGVkIG1lc3NhZ2UgZmllbGRzLCBUIGNhbiBiZSBzcGVjaWZpZWQKKyAgLy8gYXMgZ29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSBzbyB3ZSBjYW4ndCB1c2UgIm5ldyBUKCkiIGRpcmVjdGx5LiBJbiB0aGF0IGNhc2UsIHZhbHVlCisgIC8vIHNob3VsZCBiZSBhIG1lc3NhZ2Ugb2YgdGhlIHNhbWUgdHlwZSAoaXQncyBlbnN1cmVkIGJ5IHRoZSBjYWxsZXIpIGFuZCBhCisgIC8vIG5ldyBtZXNzYWdlIG9iamVjdCB3aWxsIGJlIGNyZWF0ZWQgdXNpbmcgaXQuCisgIHZpcnR1YWwgVCogTmV3KGNvbnN0IFZhbHVlKiB2YWx1ZSkgY29uc3QgPSAwOworCisgIC8vIENvbnZlcnQgYW4gb2JqZWN0IHJlY2VpdmVkIGJ5IHRoaXMgYWNjZXNzb3IgdG8gYW4gb2JqZWN0IHRoYXQgd2lsbCBiZQorICAvLyBzdG9yZWQgaW4gdGhlIHVuZGVybHlpbmcgUmVwZWF0ZWRQdHJGaWVsZC4KKyAgdmlydHVhbCB2b2lkIENvbnZlcnRUb1QoY29uc3QgVmFsdWUqIHZhbHVlLCBUKiByZXN1bHQpIGNvbnN0ID0gMDsKKworICAvLyBDb252ZXJ0IGFuIG9iamVjdCBzdG9yZWQgaW4gUmVwZWF0ZWRQdHJGaWVsZCB0byBhbiBvYmplY3QgdGhhdCB3aWxsIGJlCisgIC8vIHJldHVybmVkIGJ5IHRoaXMgYWNjZXNzb3IuIElmIHRoZSB0d28gb2JqZWN0cyBoYXZlIHRoZSBzYW1lIHR5cGUgKHRydWUKKyAgLy8gZm9yIHN0cmluZyBmaWVsZHMgd2l0aCBjdHlwZT1TVFJJTkcpLCBhIHBvaW50ZXIgdG8gdGhlIHNvdXJjZSBvYmplY3QgY2FuCisgIC8vIGJlIHJldHVybmVkIGRpcmVjdGx5LiBPdGhlcndpc2UsIGRhdGEgc2hvdWxkIGJlIGNvcGllZCBmcm9tIHZhbHVlIHRvCisgIC8vIHNjcmF0Y2hfc3BhY2UgYW5kIHNjcmF0Y2hfc3BhY2Ugc2hvdWxkIGJlIHJldHVybmVkLgorICB2aXJ0dWFsIGNvbnN0IFZhbHVlKiBDb252ZXJ0RnJvbVQoY29uc3QgVCYgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWYWx1ZSogc2NyYXRjaF9zcGFjZSkgY29uc3QgPSAwOworfTsKKworLy8gQW4gaW1wbGVtZW50YXRpb24gb2YgUmFuZG9tQWNjZXNzUmVwZWF0ZWRGaWVsZEFjY2Vzc29yIHRoYXQgbWFuaXB1bGF0ZXMKKy8vIE1hcEZpZWxkQmFzZS4KK2NsYXNzIE1hcEZpZWxkQWNjZXNzb3IgOiBwdWJsaWMgUmFuZG9tQWNjZXNzUmVwZWF0ZWRGaWVsZEFjY2Vzc29yIHsKKyBwdWJsaWM6CisgIE1hcEZpZWxkQWNjZXNzb3IoKSB7fQorICB2aXJ0dWFsIH5NYXBGaWVsZEFjY2Vzc29yKCkge30KKyAgdmlydHVhbCBib29sIElzRW1wdHkoY29uc3QgRmllbGQqIGRhdGEpIGNvbnN0IHsKKyAgICByZXR1cm4gR2V0UmVwZWF0ZWRGaWVsZChkYXRhKS0+ZW1wdHkoKTsKKyAgfQorICB2aXJ0dWFsIGludCBTaXplKGNvbnN0IEZpZWxkKiBkYXRhKSBjb25zdCB7CisgICAgcmV0dXJuIEdldFJlcGVhdGVkRmllbGQoZGF0YSktPnNpemUoKTsKKyAgfQorICB2aXJ0dWFsIGNvbnN0IFZhbHVlKiBHZXQoY29uc3QgRmllbGQqIGRhdGEsIGludCBpbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIFZhbHVlKiBzY3JhdGNoX3NwYWNlKSBjb25zdCB7CisgICAgcmV0dXJuIENvbnZlcnRGcm9tRW50cnkoR2V0UmVwZWF0ZWRGaWVsZChkYXRhKS0+R2V0KGluZGV4KSwgc2NyYXRjaF9zcGFjZSk7CisgIH0KKyAgdmlydHVhbCB2b2lkIENsZWFyKEZpZWxkKiBkYXRhKSBjb25zdCB7CisgICAgTXV0YWJsZVJlcGVhdGVkRmllbGQoZGF0YSktPkNsZWFyKCk7CisgIH0KKyAgdmlydHVhbCB2b2lkIFNldChGaWVsZCogZGF0YSwgaW50IGluZGV4LCBjb25zdCBWYWx1ZSogdmFsdWUpIGNvbnN0IHsKKyAgICBDb252ZXJ0VG9FbnRyeSh2YWx1ZSwgTXV0YWJsZVJlcGVhdGVkRmllbGQoZGF0YSktPk11dGFibGUoaW5kZXgpKTsKKyAgfQorICB2aXJ0dWFsIHZvaWQgQWRkKEZpZWxkKiBkYXRhLCBjb25zdCBWYWx1ZSogdmFsdWUpIGNvbnN0IHsKKyAgICBNZXNzYWdlKiBhbGxvY2F0ZWQgPSBOZXcodmFsdWUpOworICAgIENvbnZlcnRUb0VudHJ5KHZhbHVlLCBhbGxvY2F0ZWQpOworICAgIE11dGFibGVSZXBlYXRlZEZpZWxkKGRhdGEpLT5BZGRBbGxvY2F0ZWQoYWxsb2NhdGVkKTsKKyAgfQorICB2aXJ0dWFsIHZvaWQgUmVtb3ZlTGFzdChGaWVsZCogZGF0YSkgY29uc3QgeworICAgIE11dGFibGVSZXBlYXRlZEZpZWxkKGRhdGEpLT5SZW1vdmVMYXN0KCk7CisgIH0KKyAgdmlydHVhbCB2b2lkIFN3YXBFbGVtZW50cyhGaWVsZCogZGF0YSwgaW50IGluZGV4MSwgaW50IGluZGV4MikgY29uc3QgeworICAgIE11dGFibGVSZXBlYXRlZEZpZWxkKGRhdGEpLT5Td2FwRWxlbWVudHMoaW5kZXgxLCBpbmRleDIpOworICB9CisgIHZpcnR1YWwgdm9pZCBTd2FwKAorICAgICAgRmllbGQqIGRhdGEsCisgICAgICBjb25zdCBpbnRlcm5hbDo6UmVwZWF0ZWRGaWVsZEFjY2Vzc29yKiBvdGhlcl9tdXRhdG9yLAorICAgICAgRmllbGQqIG90aGVyX2RhdGEpIGNvbnN0IHsKKyAgICBHT09HTEVfQ0hFQ0sodGhpcyA9PSBvdGhlcl9tdXRhdG9yKTsKKyAgICBNdXRhYmxlUmVwZWF0ZWRGaWVsZChkYXRhKS0+U3dhcChNdXRhYmxlUmVwZWF0ZWRGaWVsZChvdGhlcl9kYXRhKSk7CisgIH0KKworIHByb3RlY3RlZDoKKyAgdHlwZWRlZiBSZXBlYXRlZFB0ckZpZWxkPE1lc3NhZ2U+IFJlcGVhdGVkRmllbGRUeXBlOworICBzdGF0aWMgY29uc3QgUmVwZWF0ZWRGaWVsZFR5cGUqIEdldFJlcGVhdGVkRmllbGQoY29uc3QgRmllbGQqIGRhdGEpIHsKKyAgICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxjb25zdCBSZXBlYXRlZEZpZWxkVHlwZSo+KAorICAgICAgICAoJnJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgTWFwRmllbGRCYXNlKj4oZGF0YSktPkdldFJlcGVhdGVkRmllbGQoKSkpOworICB9CisgIHN0YXRpYyBSZXBlYXRlZEZpZWxkVHlwZSogTXV0YWJsZVJlcGVhdGVkRmllbGQoRmllbGQqIGRhdGEpIHsKKyAgICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxSZXBlYXRlZEZpZWxkVHlwZSo+KAorICAgICAgICByZWludGVycHJldF9jYXN0PE1hcEZpZWxkQmFzZSo+KGRhdGEpLT5NdXRhYmxlUmVwZWF0ZWRGaWVsZCgpKTsKKyAgfQorICB2aXJ0dWFsIE1lc3NhZ2UqIE5ldyhjb25zdCBWYWx1ZSogdmFsdWUpIGNvbnN0IHsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8Y29uc3QgTWVzc2FnZSo+KHZhbHVlKS0+TmV3KCk7CisgIH0KKyAgLy8gQ29udmVydCBhbiBvYmplY3QgcmVjZWl2ZWQgYnkgdGhpcyBhY2Nlc3NvciB0byBhbiBNYXBFbnRyeSBtZXNzYWdlIHRvIGJlCisgIC8vIHN0b3JlZCBpbiB0aGUgdW5kZXJseWluZyBNYXBGaWVsZEJhc2UuCisgIHZpcnR1YWwgdm9pZCBDb252ZXJ0VG9FbnRyeShjb25zdCBWYWx1ZSogdmFsdWUsIE1lc3NhZ2UqIHJlc3VsdCkgY29uc3QgeworICAgIHJlc3VsdC0+Q29weUZyb20oKnN0YXRpY19jYXN0PGNvbnN0IE1lc3NhZ2UqPih2YWx1ZSkpOworICB9CisgIC8vIENvbnZlcnQgYSBNYXBFbnRyeSBtZXNzYWdlIHN0b3JlZCBpbiB0aGUgdW5kZXJseWluZyBNYXBGaWVsZEJhc2UgdG8gYW4KKyAgLy8gb2JqZWN0IHRoYXQgd2lsbCBiZSByZXR1cm5lZCBieSB0aGlzIGFjY2Vzc29yLgorICB2aXJ0dWFsIGNvbnN0IFZhbHVlKiBDb252ZXJ0RnJvbUVudHJ5KGNvbnN0IE1lc3NhZ2UmIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZhbHVlKiBzY3JhdGNoX3NwYWNlKSBjb25zdCB7CisgICAgcmV0dXJuIHN0YXRpY19jYXN0PGNvbnN0IFZhbHVlKj4oJnZhbHVlKTsKKyAgfQorfTsKKworLy8gRGVmYXVsdCBpbXBsZW1lbnRhdGlvbnMgb2YgUmVwZWF0ZWRGaWVsZEFjY2Vzc29yIGZvciBwcmltaXRpdmUgdHlwZXMuCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorY2xhc3MgUmVwZWF0ZWRGaWVsZFByaW1pdGl2ZUFjY2Vzc29yIDogcHVibGljIFJlcGVhdGVkRmllbGRXcmFwcGVyPFQ+IHsKKyAgdHlwZWRlZiB2b2lkIEZpZWxkOworICB0eXBlZGVmIHZvaWQgVmFsdWU7CisgIHVzaW5nIFJlcGVhdGVkRmllbGRXcmFwcGVyPFQ+OjpNdXRhYmxlUmVwZWF0ZWRGaWVsZDsKKworIHB1YmxpYzoKKyAgUmVwZWF0ZWRGaWVsZFByaW1pdGl2ZUFjY2Vzc29yKCkge30KKyAgdmlydHVhbCB+UmVwZWF0ZWRGaWVsZFByaW1pdGl2ZUFjY2Vzc29yKCkge30KKyAgdmlydHVhbCB2b2lkIFN3YXAoCisgICAgICBGaWVsZCogZGF0YSwKKyAgICAgIGNvbnN0IGludGVybmFsOjpSZXBlYXRlZEZpZWxkQWNjZXNzb3IqIG90aGVyX211dGF0b3IsCisgICAgICBGaWVsZCogb3RoZXJfZGF0YSkgY29uc3QgeworICAgIC8vIEN1cnJlbnRseSBSZXBlYXRlZEZpZWxkUHJpbWl0aXZlQWNjZXNzb3IgaXMgdGhlIG9ubHkgaW1wbGVtZW50YXRpb24gb2YKKyAgICAvLyBSZXBlYXRlZEZpZWxkQWNjZXNzb3IgZm9yIHByaW1pdGl2ZSB0eXBlcy4gQXMgd2UgYXJlIHVzaW5nIHNpbmdsZXRvbnMKKyAgICAvLyBmb3IgdGhlc2UgYWNjZXNzb3JzLCBoZXJlICJvdGhlcl9tdXRhdG9yIiBtdXN0IGJlICJ0aGlzIi4KKyAgICBHT09HTEVfQ0hFQ0sodGhpcyA9PSBvdGhlcl9tdXRhdG9yKTsKKyAgICBNdXRhYmxlUmVwZWF0ZWRGaWVsZChkYXRhKS0+U3dhcChNdXRhYmxlUmVwZWF0ZWRGaWVsZChvdGhlcl9kYXRhKSk7CisgIH0KKworIHByb3RlY3RlZDoKKyAgdmlydHVhbCBUIENvbnZlcnRUb1QoY29uc3QgVmFsdWUqIHZhbHVlKSBjb25zdCB7CisgICAgcmV0dXJuICpzdGF0aWNfY2FzdDxjb25zdCBUKj4odmFsdWUpOworICB9CisgIHZpcnR1YWwgY29uc3QgVmFsdWUqIENvbnZlcnRGcm9tVChjb25zdCBUJiB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZhbHVlKiBzY3JhdGNoX3NwYWNlKSBjb25zdCB7CisgICAgcmV0dXJuIHN0YXRpY19jYXN0PGNvbnN0IFZhbHVlKj4oJnZhbHVlKTsKKyAgfQorfTsKKworLy8gRGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBvZiBSZXBlYXRlZEZpZWxkQWNjZXNzb3IgZm9yIHN0cmluZyBmaWVsZHMgd2l0aAorLy8gY3R5cGU9U1RSSU5HLgorY2xhc3MgUmVwZWF0ZWRQdHJGaWVsZFN0cmluZ0FjY2Vzc29yIDogcHVibGljIFJlcGVhdGVkUHRyRmllbGRXcmFwcGVyPHN0cmluZz4geworICB0eXBlZGVmIHZvaWQgRmllbGQ7CisgIHR5cGVkZWYgdm9pZCBWYWx1ZTsKKyAgdXNpbmcgUmVwZWF0ZWRGaWVsZEFjY2Vzc29yOjpBZGQ7CisKKyBwdWJsaWM6CisgIFJlcGVhdGVkUHRyRmllbGRTdHJpbmdBY2Nlc3NvcigpIHt9CisgIHZpcnR1YWwgflJlcGVhdGVkUHRyRmllbGRTdHJpbmdBY2Nlc3NvcigpIHt9CisgIHZpcnR1YWwgdm9pZCBTd2FwKAorICAgICAgRmllbGQqIGRhdGEsCisgICAgICBjb25zdCBpbnRlcm5hbDo6UmVwZWF0ZWRGaWVsZEFjY2Vzc29yKiBvdGhlcl9tdXRhdG9yLAorICAgICAgRmllbGQqIG90aGVyX2RhdGEpIGNvbnN0IHsKKyAgICBpZiAodGhpcyA9PSBvdGhlcl9tdXRhdG9yKSB7CisgICAgICBNdXRhYmxlUmVwZWF0ZWRGaWVsZChkYXRhKS0+U3dhcChNdXRhYmxlUmVwZWF0ZWRGaWVsZChvdGhlcl9kYXRhKSk7CisgICAgfSBlbHNlIHsKKyAgICAgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPiB0bXA7CisgICAgICB0bXAuU3dhcChNdXRhYmxlUmVwZWF0ZWRGaWVsZChkYXRhKSk7CisgICAgICBpbnQgb3RoZXJfc2l6ZSA9IG90aGVyX211dGF0b3ItPlNpemUob3RoZXJfZGF0YSk7CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG90aGVyX3NpemU7ICsraSkgeworICAgICAgICBBZGQ8c3RyaW5nPihkYXRhLCBvdGhlcl9tdXRhdG9yLT5HZXQ8c3RyaW5nPihvdGhlcl9kYXRhLCBpKSk7CisgICAgICB9CisgICAgICBpbnQgc2l6ZSA9IFNpemUoZGF0YSk7CisgICAgICBvdGhlcl9tdXRhdG9yLT5DbGVhcihvdGhlcl9kYXRhKTsKKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgKytpKSB7CisgICAgICAgIG90aGVyX211dGF0b3ItPkFkZDxzdHJpbmc+KG90aGVyX2RhdGEsIHRtcC5HZXQoaSkpOworICAgICAgfQorICAgIH0KKyAgfQorCisgcHJvdGVjdGVkOgorICB2aXJ0dWFsIHN0cmluZyogTmV3KGNvbnN0IFZhbHVlKikgY29uc3QgeworICAgIHJldHVybiBuZXcgc3RyaW5nKCk7CisgIH0KKyAgdmlydHVhbCB2b2lkIENvbnZlcnRUb1QoY29uc3QgVmFsdWUqIHZhbHVlLCBzdHJpbmcqIHJlc3VsdCkgY29uc3QgeworICAgICpyZXN1bHQgPSAqc3RhdGljX2Nhc3Q8Y29uc3Qgc3RyaW5nKj4odmFsdWUpOworICB9CisgIHZpcnR1YWwgY29uc3QgVmFsdWUqIENvbnZlcnRGcm9tVChjb25zdCBzdHJpbmcmIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmFsdWUqIHNjcmF0Y2hfc3BhY2UpIGNvbnN0IHsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8Y29uc3QgVmFsdWUqPigmdmFsdWUpOworICB9Cit9OworCisKK2NsYXNzIFJlcGVhdGVkUHRyRmllbGRNZXNzYWdlQWNjZXNzb3IKKyAgICA6IHB1YmxpYyBSZXBlYXRlZFB0ckZpZWxkV3JhcHBlcjxNZXNzYWdlPiB7CisgIHR5cGVkZWYgdm9pZCBGaWVsZDsKKyAgdHlwZWRlZiB2b2lkIFZhbHVlOworCisgcHVibGljOgorICBSZXBlYXRlZFB0ckZpZWxkTWVzc2FnZUFjY2Vzc29yKCkge30KKyAgdmlydHVhbCB+UmVwZWF0ZWRQdHJGaWVsZE1lc3NhZ2VBY2Nlc3NvcigpIHt9CisgIHZpcnR1YWwgdm9pZCBTd2FwKAorICAgICAgRmllbGQqIGRhdGEsCisgICAgICBjb25zdCBpbnRlcm5hbDo6UmVwZWF0ZWRGaWVsZEFjY2Vzc29yKiBvdGhlcl9tdXRhdG9yLAorICAgICAgRmllbGQqIG90aGVyX2RhdGEpIGNvbnN0IHsKKyAgICBHT09HTEVfQ0hFQ0sodGhpcyA9PSBvdGhlcl9tdXRhdG9yKTsKKyAgICBNdXRhYmxlUmVwZWF0ZWRGaWVsZChkYXRhKS0+U3dhcChNdXRhYmxlUmVwZWF0ZWRGaWVsZChvdGhlcl9kYXRhKSk7CisgIH0KKworIHByb3RlY3RlZDoKKyAgdmlydHVhbCBNZXNzYWdlKiBOZXcoY29uc3QgVmFsdWUqIHZhbHVlKSBjb25zdCB7CisgICAgcmV0dXJuIHN0YXRpY19jYXN0PGNvbnN0IE1lc3NhZ2UqPih2YWx1ZSktPk5ldygpOworICB9CisgIHZpcnR1YWwgdm9pZCBDb252ZXJ0VG9UKGNvbnN0IFZhbHVlKiB2YWx1ZSwgTWVzc2FnZSogcmVzdWx0KSBjb25zdCB7CisgICAgcmVzdWx0LT5Db3B5RnJvbSgqc3RhdGljX2Nhc3Q8Y29uc3QgTWVzc2FnZSo+KHZhbHVlKSk7CisgIH0KKyAgdmlydHVhbCBjb25zdCBWYWx1ZSogQ29udmVydEZyb21UKGNvbnN0IE1lc3NhZ2UmIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmFsdWUqIHNjcmF0Y2hfc3BhY2UpIGNvbnN0IHsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8Y29uc3QgVmFsdWUqPigmdmFsdWUpOworICB9Cit9OworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfUkVGTEVDVElPTl9JTlRFUk5BTF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvcmVmbGVjdGlvbl9vcHMuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3JlZmxlY3Rpb25fb3BzLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ2MjlkZWMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3JlZmxlY3Rpb25fb3BzLmNjCkBAIC0wLDAgKzEsMjY5IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8dmVjdG9yPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3JlZmxlY3Rpb25fb3BzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bmtub3duX2ZpZWxkX3NldC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKK3ZvaWQgUmVmbGVjdGlvbk9wczo6Q29weShjb25zdCBNZXNzYWdlJiBmcm9tLCBNZXNzYWdlKiB0bykgeworICBpZiAoJmZyb20gPT0gdG8pIHJldHVybjsKKyAgQ2xlYXIodG8pOworICBNZXJnZShmcm9tLCB0byk7Cit9CisKK3ZvaWQgUmVmbGVjdGlvbk9wczo6TWVyZ2UoY29uc3QgTWVzc2FnZSYgZnJvbSwgTWVzc2FnZSogdG8pIHsKKyAgR09PR0xFX0NIRUNLX05FKCZmcm9tLCB0byk7CisKKyAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciA9IGZyb20uR2V0RGVzY3JpcHRvcigpOworICBHT09HTEVfQ0hFQ0tfRVEodG8tPkdldERlc2NyaXB0b3IoKSwgZGVzY3JpcHRvcikKKyAgICA8PCAiVHJpZWQgdG8gbWVyZ2UgbWVzc2FnZXMgb2YgZGlmZmVyZW50IHR5cGVzICIKKyAgICA8PCAiKG1lcmdlICIgPDwgZGVzY3JpcHRvci0+ZnVsbF9uYW1lKCkKKyAgICA8PCAiIHRvICIgPDwgdG8tPkdldERlc2NyaXB0b3IoKS0+ZnVsbF9uYW1lKCkgPDwgIikiOworCisgIGNvbnN0IFJlZmxlY3Rpb24qIGZyb21fcmVmbGVjdGlvbiA9IGZyb20uR2V0UmVmbGVjdGlvbigpOworICBjb25zdCBSZWZsZWN0aW9uKiB0b19yZWZsZWN0aW9uID0gdG8tPkdldFJlZmxlY3Rpb24oKTsKKworICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4gZmllbGRzOworICBmcm9tX3JlZmxlY3Rpb24tPkxpc3RGaWVsZHMoZnJvbSwgJmZpZWxkcyk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRzLnNpemUoKTsgaSsrKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGZpZWxkc1tpXTsKKworICAgIGlmIChmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgeworICAgICAgaW50IGNvdW50ID0gZnJvbV9yZWZsZWN0aW9uLT5GaWVsZFNpemUoZnJvbSwgZmllbGQpOworICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBjb3VudDsgaisrKSB7CisgICAgICAgIHN3aXRjaCAoZmllbGQtPmNwcF90eXBlKCkpIHsKKyNkZWZpbmUgSEFORExFX1RZUEUoQ1BQVFlQRSwgTUVUSE9EKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfIyNDUFBUWVBFOiAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgdG9fcmVmbGVjdGlvbi0+QWRkIyNNRVRIT0QodG8sIGZpZWxkLCAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgZnJvbV9yZWZsZWN0aW9uLT5HZXRSZXBlYXRlZCMjTUVUSE9EKGZyb20sIGZpZWxkLCBqKSk7ICAgICBcCisgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgIEhBTkRMRV9UWVBFKElOVDMyICwgSW50MzIgKTsKKyAgICAgICAgICBIQU5ETEVfVFlQRShJTlQ2NCAsIEludDY0ICk7CisgICAgICAgICAgSEFORExFX1RZUEUoVUlOVDMyLCBVSW50MzIpOworICAgICAgICAgIEhBTkRMRV9UWVBFKFVJTlQ2NCwgVUludDY0KTsKKyAgICAgICAgICBIQU5ETEVfVFlQRShGTE9BVCAsIEZsb2F0ICk7CisgICAgICAgICAgSEFORExFX1RZUEUoRE9VQkxFLCBEb3VibGUpOworICAgICAgICAgIEhBTkRMRV9UWVBFKEJPT0wgICwgQm9vbCAgKTsKKyAgICAgICAgICBIQU5ETEVfVFlQRShTVFJJTkcsIFN0cmluZyk7CisgICAgICAgICAgSEFORExFX1RZUEUoRU5VTSAgLCBFbnVtICApOworI3VuZGVmIEhBTkRMRV9UWVBFCisKKyAgICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgICAgICAgdG9fcmVmbGVjdGlvbi0+QWRkTWVzc2FnZSh0bywgZmllbGQpLT5NZXJnZUZyb20oCisgICAgICAgICAgICAgIGZyb21fcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRNZXNzYWdlKGZyb20sIGZpZWxkLCBqKSk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICBzd2l0Y2ggKGZpZWxkLT5jcHBfdHlwZSgpKSB7CisjZGVmaW5lIEhBTkRMRV9UWVBFKENQUFRZUEUsIE1FVEhPRCkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV8jI0NQUFRZUEU6ICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICB0b19yZWZsZWN0aW9uLT5TZXQjI01FVEhPRCh0bywgZmllbGQsICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICBmcm9tX3JlZmxlY3Rpb24tPkdldCMjTUVUSE9EKGZyb20sIGZpZWxkKSk7ICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgIGJyZWFrOworCisgICAgICAgIEhBTkRMRV9UWVBFKElOVDMyICwgSW50MzIgKTsKKyAgICAgICAgSEFORExFX1RZUEUoSU5UNjQgLCBJbnQ2NCApOworICAgICAgICBIQU5ETEVfVFlQRShVSU5UMzIsIFVJbnQzMik7CisgICAgICAgIEhBTkRMRV9UWVBFKFVJTlQ2NCwgVUludDY0KTsKKyAgICAgICAgSEFORExFX1RZUEUoRkxPQVQgLCBGbG9hdCApOworICAgICAgICBIQU5ETEVfVFlQRShET1VCTEUsIERvdWJsZSk7CisgICAgICAgIEhBTkRMRV9UWVBFKEJPT0wgICwgQm9vbCAgKTsKKyAgICAgICAgSEFORExFX1RZUEUoU1RSSU5HLCBTdHJpbmcpOworICAgICAgICBIQU5ETEVfVFlQRShFTlVNICAsIEVudW0gICk7CisjdW5kZWYgSEFORExFX1RZUEUKKworICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOgorICAgICAgICAgIHRvX3JlZmxlY3Rpb24tPk11dGFibGVNZXNzYWdlKHRvLCBmaWVsZCktPk1lcmdlRnJvbSgKKyAgICAgICAgICAgIGZyb21fcmVmbGVjdGlvbi0+R2V0TWVzc2FnZShmcm9tLCBmaWVsZCkpOworICAgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgfQorCisgIHRvX3JlZmxlY3Rpb24tPk11dGFibGVVbmtub3duRmllbGRzKHRvKS0+TWVyZ2VGcm9tKAorICAgIGZyb21fcmVmbGVjdGlvbi0+R2V0VW5rbm93bkZpZWxkcyhmcm9tKSk7Cit9CisKK3ZvaWQgUmVmbGVjdGlvbk9wczo6Q2xlYXIoTWVzc2FnZSogbWVzc2FnZSkgeworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpOworCisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBmaWVsZHM7CisgIHJlZmxlY3Rpb24tPkxpc3RGaWVsZHMoKm1lc3NhZ2UsICZmaWVsZHMpOworICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkcy5zaXplKCk7IGkrKykgeworICAgIHJlZmxlY3Rpb24tPkNsZWFyRmllbGQobWVzc2FnZSwgZmllbGRzW2ldKTsKKyAgfQorCisgIHJlZmxlY3Rpb24tPk11dGFibGVVbmtub3duRmllbGRzKG1lc3NhZ2UpLT5DbGVhcigpOworfQorCitib29sIFJlZmxlY3Rpb25PcHM6OklzSW5pdGlhbGl6ZWQoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSkgeworICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yID0gbWVzc2FnZS5HZXREZXNjcmlwdG9yKCk7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKTsKKworICAvLyBDaGVjayByZXF1aXJlZCBmaWVsZHMgb2YgdGhpcyBtZXNzYWdlLgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3ItPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGlmIChkZXNjcmlwdG9yLT5maWVsZChpKS0+aXNfcmVxdWlyZWQoKSkgeworICAgICAgaWYgKCFyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBkZXNjcmlwdG9yLT5maWVsZChpKSkpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgIH0KKyAgfQorCisgIC8vIENoZWNrIHRoYXQgc3ViLW1lc3NhZ2VzIGFyZSBpbml0aWFsaXplZC4KKyAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+IGZpZWxkczsKKyAgcmVmbGVjdGlvbi0+TGlzdEZpZWxkcyhtZXNzYWdlLCAmZmllbGRzKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZHMuc2l6ZSgpOyBpKyspIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZmllbGRzW2ldOworICAgIGlmIChmaWVsZC0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSkgeworCisgICAgICBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkpIHsKKyAgICAgICAgaW50IHNpemUgPSByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgZmllbGQpOworCisgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgc2l6ZTsgaisrKSB7CisgICAgICAgICAgaWYgKCFyZWZsZWN0aW9uLT5HZXRSZXBlYXRlZE1lc3NhZ2UobWVzc2FnZSwgZmllbGQsIGopCisgICAgICAgICAgICAgICAgICAgICAgICAgIC5Jc0luaXRpYWxpemVkKCkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGlmICghcmVmbGVjdGlvbi0+R2V0TWVzc2FnZShtZXNzYWdlLCBmaWVsZCkuSXNJbml0aWFsaXplZCgpKSB7CisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICB9CisgICAgfQorICB9CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgUmVmbGVjdGlvbk9wczo6RGlzY2FyZFVua25vd25GaWVsZHMoTWVzc2FnZSogbWVzc2FnZSkgeworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpOworCisgIHJlZmxlY3Rpb24tPk11dGFibGVVbmtub3duRmllbGRzKG1lc3NhZ2UpLT5DbGVhcigpOworCisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBmaWVsZHM7CisgIHJlZmxlY3Rpb24tPkxpc3RGaWVsZHMoKm1lc3NhZ2UsICZmaWVsZHMpOworICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkcy5zaXplKCk7IGkrKykgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBmaWVsZHNbaV07CisgICAgaWYgKGZpZWxkLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFKSB7CisgICAgICBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkpIHsKKyAgICAgICAgaW50IHNpemUgPSByZWZsZWN0aW9uLT5GaWVsZFNpemUoKm1lc3NhZ2UsIGZpZWxkKTsKKyAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBzaXplOyBqKyspIHsKKyAgICAgICAgICByZWZsZWN0aW9uLT5NdXRhYmxlUmVwZWF0ZWRNZXNzYWdlKG1lc3NhZ2UsIGZpZWxkLCBqKQorICAgICAgICAgICAgICAgICAgICAtPkRpc2NhcmRVbmtub3duRmllbGRzKCk7CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJlZmxlY3Rpb24tPk11dGFibGVNZXNzYWdlKG1lc3NhZ2UsIGZpZWxkKS0+RGlzY2FyZFVua25vd25GaWVsZHMoKTsKKyAgICAgIH0KKyAgICB9CisgIH0KK30KKworc3RhdGljIHN0cmluZyBTdWJNZXNzYWdlUHJlZml4KGNvbnN0IHN0cmluZyYgcHJlZml4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGluZGV4KSB7CisgIHN0cmluZyByZXN1bHQocHJlZml4KTsKKyAgaWYgKGZpZWxkLT5pc19leHRlbnNpb24oKSkgeworICAgIHJlc3VsdC5hcHBlbmQoIigiKTsKKyAgICByZXN1bHQuYXBwZW5kKGZpZWxkLT5mdWxsX25hbWUoKSk7CisgICAgcmVzdWx0LmFwcGVuZCgiKSIpOworICB9IGVsc2UgeworICAgIHJlc3VsdC5hcHBlbmQoZmllbGQtPm5hbWUoKSk7CisgIH0KKyAgaWYgKGluZGV4ICE9IC0xKSB7CisgICAgcmVzdWx0LmFwcGVuZCgiWyIpOworICAgIHJlc3VsdC5hcHBlbmQoU2ltcGxlSXRvYShpbmRleCkpOworICAgIHJlc3VsdC5hcHBlbmQoIl0iKTsKKyAgfQorICByZXN1bHQuYXBwZW5kKCIuIik7CisgIHJldHVybiByZXN1bHQ7Cit9CisKK3ZvaWQgUmVmbGVjdGlvbk9wczo6RmluZEluaXRpYWxpemF0aW9uRXJyb3JzKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgY29uc3Qgc3RyaW5nJiBwcmVmaXgsCisgICAgdmVjdG9yPHN0cmluZz4qIGVycm9ycykgeworICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yID0gbWVzc2FnZS5HZXREZXNjcmlwdG9yKCk7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKTsKKworICAvLyBDaGVjayByZXF1aXJlZCBmaWVsZHMgb2YgdGhpcyBtZXNzYWdlLgorICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3ItPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGlmIChkZXNjcmlwdG9yLT5maWVsZChpKS0+aXNfcmVxdWlyZWQoKSkgeworICAgICAgaWYgKCFyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBkZXNjcmlwdG9yLT5maWVsZChpKSkpIHsKKyAgICAgICAgZXJyb3JzLT5wdXNoX2JhY2socHJlZml4ICsgZGVzY3JpcHRvci0+ZmllbGQoaSktPm5hbWUoKSk7CisgICAgICB9CisgICAgfQorICB9CisKKyAgLy8gQ2hlY2sgc3ViLW1lc3NhZ2VzLgorICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4gZmllbGRzOworICByZWZsZWN0aW9uLT5MaXN0RmllbGRzKG1lc3NhZ2UsICZmaWVsZHMpOworICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkcy5zaXplKCk7IGkrKykgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBmaWVsZHNbaV07CisgICAgaWYgKGZpZWxkLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFKSB7CisKKyAgICAgIGlmIChmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgeworICAgICAgICBpbnQgc2l6ZSA9IHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBmaWVsZCk7CisKKyAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBzaXplOyBqKyspIHsKKyAgICAgICAgICBjb25zdCBNZXNzYWdlJiBzdWJfbWVzc2FnZSA9CisgICAgICAgICAgICByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZE1lc3NhZ2UobWVzc2FnZSwgZmllbGQsIGopOworICAgICAgICAgIEZpbmRJbml0aWFsaXphdGlvbkVycm9ycyhzdWJfbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3ViTWVzc2FnZVByZWZpeChwcmVmaXgsIGZpZWxkLCBqKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JzKTsKKyAgICAgICAgfQorICAgICAgfSBlbHNlIHsKKyAgICAgICAgY29uc3QgTWVzc2FnZSYgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5HZXRNZXNzYWdlKG1lc3NhZ2UsIGZpZWxkKTsKKyAgICAgICAgRmluZEluaXRpYWxpemF0aW9uRXJyb3JzKHN1Yl9tZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3ViTWVzc2FnZVByZWZpeChwcmVmaXgsIGZpZWxkLCAtMSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvcnMpOworICAgICAgfQorICAgIH0KKyAgfQorfQorCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9yZWZsZWN0aW9uX29wcy5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9yZWZsZWN0aW9uX29wcy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ3NzU5MTEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3JlZmxlY3Rpb25fb3BzLmgKQEAgLTAsMCArMSw4MSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorLy8KKy8vIFRoaXMgaGVhZGVyIGlzIGxvZ2ljYWxseSBpbnRlcm5hbCwgYnV0IGlzIG1hZGUgcHVibGljIGJlY2F1c2UgaXQgaXMgdXNlZAorLy8gZnJvbSBwcm90b2NvbC1jb21waWxlci1nZW5lcmF0ZWQgY29kZSwgd2hpY2ggbWF5IHJlc2lkZSBpbiBvdGhlciBjb21wb25lbnRzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9SRUZMRUNUSU9OX09QU19IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1JFRkxFQ1RJT05fT1BTX0hfXworCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tZXNzYWdlLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKKy8vIEJhc2ljIG9wZXJhdGlvbnMgdGhhdCBjYW4gYmUgcGVyZm9ybWVkIHVzaW5nIHJlZmxlY3Rpb24uCisvLyBUaGVzZSBjYW4gYmUgdXNlZCBhcyBhIGNoZWFwIHdheSB0byBpbXBsZW1lbnQgdGhlIGNvcnJlc3BvbmRpbmcKKy8vIG1ldGhvZHMgb2YgdGhlIE1lc3NhZ2UgaW50ZXJmYWNlLCB0aG91Z2ggdGhleSBhcmUgbGlrZWx5IHRvIGJlCisvLyBzbG93ZXIgdGhhbiBpbXBsZW1lbnRhdGlvbnMgdGFpbG9yZWQgZm9yIHRoZSBzcGVjaWZpYyBtZXNzYWdlIHR5cGUuCisvLworLy8gVGhpcyBjbGFzcyBzaG91bGQgc3RheSBsaW1pdGVkIHRvIG9wZXJhdGlvbnMgbmVlZGVkIHRvIGltcGxlbWVudAorLy8gdGhlIE1lc3NhZ2UgaW50ZXJmYWNlLgorLy8KKy8vIFRoaXMgY2xhc3MgaXMgcmVhbGx5IGEgbmFtZXNwYWNlIHRoYXQgY29udGFpbnMgb25seSBzdGF0aWMgbWV0aG9kcy4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBSZWZsZWN0aW9uT3BzIHsKKyBwdWJsaWM6CisgIHN0YXRpYyB2b2lkIENvcHkoY29uc3QgTWVzc2FnZSYgZnJvbSwgTWVzc2FnZSogdG8pOworICBzdGF0aWMgdm9pZCBNZXJnZShjb25zdCBNZXNzYWdlJiBmcm9tLCBNZXNzYWdlKiB0byk7CisgIHN0YXRpYyB2b2lkIENsZWFyKE1lc3NhZ2UqIG1lc3NhZ2UpOworICBzdGF0aWMgYm9vbCBJc0luaXRpYWxpemVkKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UpOworICBzdGF0aWMgdm9pZCBEaXNjYXJkVW5rbm93bkZpZWxkcyhNZXNzYWdlKiBtZXNzYWdlKTsKKworICAvLyBGaW5kcyBhbGwgdW5zZXQgcmVxdWlyZWQgZmllbGRzIGluIHRoZSBtZXNzYWdlIGFuZCBhZGRzIHRoZWlyIGZ1bGwKKyAgLy8gcGF0aHMgKGUuZy4gImZvby5iYXJbNV0uYmF6IikgdG8gKm5hbWVzLiAgInByZWZpeCIgd2lsbCBiZSBhdHRhY2hlZCB0bworICAvLyB0aGUgZnJvbnQgb2YgZWFjaCBuYW1lLgorICBzdGF0aWMgdm9pZCBGaW5kSW5pdGlhbGl6YXRpb25FcnJvcnMoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgcHJlZml4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjdG9yPHN0cmluZz4qIGVycm9ycyk7CisKKyBwcml2YXRlOgorICAvLyBBbGwgbWV0aG9kcyBhcmUgc3RhdGljLiAgTm8gbmVlZCB0byBjb25zdHJ1Y3QuCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhSZWZsZWN0aW9uT3BzKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX1JFRkxFQ1RJT05fT1BTX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9yZWZsZWN0aW9uX29wc191bml0dGVzdC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvcmVmbGVjdGlvbl9vcHNfdW5pdHRlc3QuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODhkNmJmYgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvcmVmbGVjdGlvbl9vcHNfdW5pdHRlc3QuY2MKQEAgLTAsMCArMSw0NzYgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9yZWZsZWN0aW9uX29wcy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RfdXRpbC5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2xvZ2dpbmcuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZ29vZ2xldGVzdC5oPgorI2luY2x1ZGUgPGd0ZXN0L2d0ZXN0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKK25hbWVzcGFjZSB7CisKK1RFU1QoUmVmbGVjdGlvbk9wc1Rlc3QsIFNhbml0eUNoZWNrKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZtZXNzYWdlKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEZpZWxkc1NldChtZXNzYWdlKTsKK30KKworVEVTVChSZWZsZWN0aW9uT3BzVGVzdCwgQ29weSkgeworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2UsIG1lc3NhZ2UyOworCisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1lc3NhZ2UpOworCisgIFJlZmxlY3Rpb25PcHM6OkNvcHkobWVzc2FnZSwgJm1lc3NhZ2UyKTsKKworICBUZXN0VXRpbDo6RXhwZWN0QWxsRmllbGRzU2V0KG1lc3NhZ2UyKTsKKworICAvLyBDb3B5aW5nIGZyb20gc2VsZiBzaG91bGQgYmUgYSBuby1vcC4KKyAgUmVmbGVjdGlvbk9wczo6Q29weShtZXNzYWdlMiwgJm1lc3NhZ2UyKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEZpZWxkc1NldChtZXNzYWdlMik7Cit9CisKK1RFU1QoUmVmbGVjdGlvbk9wc1Rlc3QsIENvcHlFeHRlbnNpb25zKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyBtZXNzYWdlLCBtZXNzYWdlMjsKKworICBUZXN0VXRpbDo6U2V0QWxsRXh0ZW5zaW9ucygmbWVzc2FnZSk7CisKKyAgUmVmbGVjdGlvbk9wczo6Q29weShtZXNzYWdlLCAmbWVzc2FnZTIpOworCisgIFRlc3RVdGlsOjpFeHBlY3RBbGxFeHRlbnNpb25zU2V0KG1lc3NhZ2UyKTsKK30KKworVEVTVChSZWZsZWN0aW9uT3BzVGVzdCwgQ29weU9uZW9mKSB7CisgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIG1lc3NhZ2UsIG1lc3NhZ2UyOworICBUZXN0VXRpbDo6U2V0T25lb2YxKCZtZXNzYWdlKTsKKyAgUmVmbGVjdGlvbk9wczo6Q29weShtZXNzYWdlLCAmbWVzc2FnZTIpOworICBUZXN0VXRpbDo6RXhwZWN0T25lb2ZTZXQxKG1lc3NhZ2UyKTsKKworICBUZXN0VXRpbDo6U2V0T25lb2YyKCZtZXNzYWdlKTsKKyAgVGVzdFV0aWw6OkV4cGVjdE9uZW9mU2V0MihtZXNzYWdlKTsKKyAgUmVmbGVjdGlvbk9wczo6Q29weShtZXNzYWdlLCAmbWVzc2FnZTIpOworICBUZXN0VXRpbDo6RXhwZWN0T25lb2ZTZXQyKG1lc3NhZ2UyKTsKK30KKworVEVTVChSZWZsZWN0aW9uT3BzVGVzdCwgTWVyZ2UpIHsKKyAgLy8gTm90ZTogIENvcHkgaXMgaW1wbGVtZW50ZWQgaW4gdGVybXMgb2YgTWVyZ2UoKSBzbyB0ZWNobmljYWxseSB0aGUgQ29weQorICAvLyAgIHRlc3QgYWxyZWFkeSB0ZXN0ZWQgbW9zdCBvZiB0aGlzLgorCisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZSwgbWVzc2FnZTI7CisKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbWVzc2FnZSk7CisKKyAgLy8gVGhpcyBmaWVsZCB3aWxsIHRlc3QgbWVyZ2luZyBpbnRvIGFuIGVtcHR5IHNwb3QuCisgIG1lc3NhZ2UyLnNldF9vcHRpb25hbF9pbnQzMihtZXNzYWdlLm9wdGlvbmFsX2ludDMyKCkpOworICBtZXNzYWdlLmNsZWFyX29wdGlvbmFsX2ludDMyKCk7CisKKyAgLy8gVGhpcyB0ZXN0cyBvdmVyd3JpdGluZy4KKyAgbWVzc2FnZTIuc2V0X29wdGlvbmFsX3N0cmluZyhtZXNzYWdlLm9wdGlvbmFsX3N0cmluZygpKTsKKyAgbWVzc2FnZS5zZXRfb3B0aW9uYWxfc3RyaW5nKCJzb21ldGhpbmcgZWxzZSIpOworCisgIC8vIFRoaXMgdGVzdHMgY29uY2F0ZW5hdGluZy4KKyAgbWVzc2FnZTIuYWRkX3JlcGVhdGVkX2ludDMyKG1lc3NhZ2UucmVwZWF0ZWRfaW50MzIoMSkpOworICBpbnQzMiBpID0gbWVzc2FnZS5yZXBlYXRlZF9pbnQzMigwKTsKKyAgbWVzc2FnZS5jbGVhcl9yZXBlYXRlZF9pbnQzMigpOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9pbnQzMihpKTsKKworICBSZWZsZWN0aW9uT3BzOjpNZXJnZShtZXNzYWdlMiwgJm1lc3NhZ2UpOworCisgIFRlc3RVdGlsOjpFeHBlY3RBbGxGaWVsZHNTZXQobWVzc2FnZSk7Cit9CisKK1RFU1QoUmVmbGVjdGlvbk9wc1Rlc3QsIE1lcmdlRXh0ZW5zaW9ucykgeworICAvLyBOb3RlOiAgQ29weSBpcyBpbXBsZW1lbnRlZCBpbiB0ZXJtcyBvZiBNZXJnZSgpIHNvIHRlY2huaWNhbGx5IHRoZSBDb3B5CisgIC8vICAgdGVzdCBhbHJlYWR5IHRlc3RlZCBtb3N0IG9mIHRoaXMuCisKKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2UsIG1lc3NhZ2UyOworCisgIFRlc3RVdGlsOjpTZXRBbGxFeHRlbnNpb25zKCZtZXNzYWdlKTsKKworICAvLyBUaGlzIGZpZWxkIHdpbGwgdGVzdCBtZXJnaW5nIGludG8gYW4gZW1wdHkgc3BvdC4KKyAgbWVzc2FnZTIuU2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbnQzMl9leHRlbnNpb24sCisgICAgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ludDMyX2V4dGVuc2lvbikpOworICBtZXNzYWdlLkNsZWFyRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbnQzMl9leHRlbnNpb24pOworCisgIC8vIFRoaXMgdGVzdHMgb3ZlcndyaXRpbmcuCisgIG1lc3NhZ2UyLlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc3RyaW5nX2V4dGVuc2lvbiwKKyAgICBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc3RyaW5nX2V4dGVuc2lvbikpOworICBtZXNzYWdlLlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc3RyaW5nX2V4dGVuc2lvbiwgInNvbWV0aGluZyBlbHNlIik7CisKKyAgLy8gVGhpcyB0ZXN0cyBjb25jYXRlbmF0aW5nLgorICBtZXNzYWdlMi5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ludDMyX2V4dGVuc2lvbiwKKyAgICBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9uLCAxKSk7CisgIGludDMyIGkgPSBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9uLCAwKTsKKyAgbWVzc2FnZS5DbGVhckV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9uKTsKKyAgbWVzc2FnZS5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ludDMyX2V4dGVuc2lvbiwgaSk7CisKKyAgUmVmbGVjdGlvbk9wczo6TWVyZ2UobWVzc2FnZTIsICZtZXNzYWdlKTsKKworICBUZXN0VXRpbDo6RXhwZWN0QWxsRXh0ZW5zaW9uc1NldChtZXNzYWdlKTsKK30KKworVEVTVChSZWZsZWN0aW9uT3BzVGVzdCwgTWVyZ2VVbmtub3duKSB7CisgIC8vIFRlc3QgdGhhdCB0aGUgbWVzc2FnZXMnIFVua25vd25GaWVsZFNldHMgYXJlIGNvcnJlY3RseSBtZXJnZWQuCisgIHVuaXR0ZXN0OjpUZXN0RW1wdHlNZXNzYWdlIG1lc3NhZ2UxLCBtZXNzYWdlMjsKKyAgbWVzc2FnZTEubXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5BZGRWYXJpbnQoMTIzNCwgMSk7CisgIG1lc3NhZ2UyLm11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+QWRkVmFyaW50KDEyMzQsIDIpOworCisgIFJlZmxlY3Rpb25PcHM6Ok1lcmdlKG1lc3NhZ2UyLCAmbWVzc2FnZTEpOworCisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlMS51bmtub3duX2ZpZWxkcygpLmZpZWxkX2NvdW50KCkpOworICBBU1NFUlRfRVEoVW5rbm93bkZpZWxkOjpUWVBFX1ZBUklOVCwKKyAgICAgICAgICAgIG1lc3NhZ2UxLnVua25vd25fZmllbGRzKCkuZmllbGQoMCkudHlwZSgpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UxLnVua25vd25fZmllbGRzKCkuZmllbGQoMCkudmFyaW50KCkpOworICBBU1NFUlRfRVEoVW5rbm93bkZpZWxkOjpUWVBFX1ZBUklOVCwKKyAgICAgICAgICAgIG1lc3NhZ2UxLnVua25vd25fZmllbGRzKCkuZmllbGQoMSkudHlwZSgpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UxLnVua25vd25fZmllbGRzKCkuZmllbGQoMSkudmFyaW50KCkpOworfQorCitURVNUKFJlZmxlY3Rpb25PcHNUZXN0LCBNZXJnZU9uZW9mKSB7CisgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIG1lc3NhZ2UxLCBtZXNzYWdlMjsKKyAgVGVzdFV0aWw6OlNldE9uZW9mMSgmbWVzc2FnZTEpOworCisgIC8vIE1lcmdlIHRvIGVtcHR5IG1lc3NhZ2UKKyAgUmVmbGVjdGlvbk9wczo6TWVyZ2UobWVzc2FnZTEsICZtZXNzYWdlMik7CisgIFRlc3RVdGlsOjpFeHBlY3RPbmVvZlNldDEobWVzc2FnZTIpOworCisgIC8vIE1lcmdlIHdpdGggdGhlIHNhbWUgb25lb2YgZmllbGRzCisgIFJlZmxlY3Rpb25PcHM6Ok1lcmdlKG1lc3NhZ2UxLCAmbWVzc2FnZTIpOworICBUZXN0VXRpbDo6RXhwZWN0T25lb2ZTZXQxKG1lc3NhZ2UyKTsKKworICAvLyBNZXJnZSB3aXRoIGRpZmZlcmVudCBvbmVvZiBmaWVsZHMKKyAgVGVzdFV0aWw6OlNldE9uZW9mMigmbWVzc2FnZTEpOworICBSZWZsZWN0aW9uT3BzOjpNZXJnZShtZXNzYWdlMSwgJm1lc3NhZ2UyKTsKKyAgVGVzdFV0aWw6OkV4cGVjdE9uZW9mU2V0MihtZXNzYWdlMik7Cit9CisKKyNpZmRlZiBQUk9UT0JVRl9IQVNfREVBVEhfVEVTVAorCitURVNUKFJlZmxlY3Rpb25PcHNUZXN0LCBNZXJnZUZyb21TZWxmKSB7CisgIC8vIE5vdGU6ICBDb3B5IGlzIGltcGxlbWVudGVkIGluIHRlcm1zIG9mIE1lcmdlKCkgc28gdGVjaG5pY2FsbHkgdGhlIENvcHkKKyAgLy8gICB0ZXN0IGFscmVhZHkgdGVzdGVkIG1vc3Qgb2YgdGhpcy4KKworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisKKyAgRVhQRUNUX0RFQVRIKAorICAgIFJlZmxlY3Rpb25PcHM6Ok1lcmdlKG1lc3NhZ2UsICZtZXNzYWdlKSwKKyAgICAiJmZyb20iKTsKK30KKworI2VuZGlmICAvLyBQUk9UT0JVRl9IQVNfREVBVEhfVEVTVAorCitURVNUKFJlZmxlY3Rpb25PcHNUZXN0LCBDbGVhcikgeworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbWVzc2FnZSk7CisKKyAgUmVmbGVjdGlvbk9wczo6Q2xlYXIoJm1lc3NhZ2UpOworCisgIFRlc3RVdGlsOjpFeHBlY3RDbGVhcihtZXNzYWdlKTsKKworICAvLyBDaGVjayB0aGF0IGdldHRpbmcgZW1iZWRkZWQgbWVzc2FnZXMgcmV0dXJucyB0aGUgb2JqZWN0cyBjcmVhdGVkIGR1cmluZworICAvLyBTZXRBbGxGaWVsZHMoKSByYXRoZXIgdGhhbiBkZWZhdWx0IGluc3RhbmNlcy4KKyAgRVhQRUNUX05FKCZ1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpPcHRpb25hbEdyb3VwOjpkZWZhdWx0X2luc3RhbmNlKCksCisgICAgICAgICAgICAmbWVzc2FnZS5vcHRpb25hbGdyb3VwKCkpOworICBFWFBFQ1RfTkUoJnVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2U6OmRlZmF1bHRfaW5zdGFuY2UoKSwKKyAgICAgICAgICAgICZtZXNzYWdlLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCkpOworICBFWFBFQ1RfTkUoJnVuaXR0ZXN0OjpGb3JlaWduTWVzc2FnZTo6ZGVmYXVsdF9pbnN0YW5jZSgpLAorICAgICAgICAgICAgJm1lc3NhZ2Uub3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlKCkpOworICBFWFBFQ1RfTkUoJnVuaXR0ZXN0X2ltcG9ydDo6SW1wb3J0TWVzc2FnZTo6ZGVmYXVsdF9pbnN0YW5jZSgpLAorICAgICAgICAgICAgJm1lc3NhZ2Uub3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UoKSk7Cit9CisKK1RFU1QoUmVmbGVjdGlvbk9wc1Rlc3QsIENsZWFyRXh0ZW5zaW9ucykgeworICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTsKKworICBUZXN0VXRpbDo6U2V0QWxsRXh0ZW5zaW9ucygmbWVzc2FnZSk7CisKKyAgUmVmbGVjdGlvbk9wczo6Q2xlYXIoJm1lc3NhZ2UpOworCisgIFRlc3RVdGlsOjpFeHBlY3RFeHRlbnNpb25zQ2xlYXIobWVzc2FnZSk7CisKKyAgLy8gQ2hlY2sgdGhhdCBnZXR0aW5nIGVtYmVkZGVkIG1lc3NhZ2VzIHJldHVybnMgdGhlIG9iamVjdHMgY3JlYXRlZCBkdXJpbmcKKyAgLy8gU2V0QWxsRXh0ZW5zaW9ucygpIHJhdGhlciB0aGFuIGRlZmF1bHQgaW5zdGFuY2VzLgorICBFWFBFQ1RfTkUoJnVuaXR0ZXN0OjpPcHRpb25hbEdyb3VwX2V4dGVuc2lvbjo6ZGVmYXVsdF9pbnN0YW5jZSgpLAorICAgICAgICAgICAgJm1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbGdyb3VwX2V4dGVuc2lvbikpOworICBFWFBFQ1RfTkUoJnVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2U6OmRlZmF1bHRfaW5zdGFuY2UoKSwKKyAgICAgICAgICAgICZtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9ORSgmdW5pdHRlc3Q6OkZvcmVpZ25NZXNzYWdlOjpkZWZhdWx0X2luc3RhbmNlKCksCisgICAgICAgICAgICAmbWVzc2FnZS5HZXRFeHRlbnNpb24oCisgICAgICAgICAgICAgIHVuaXR0ZXN0OjpvcHRpb25hbF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9ORSgmdW5pdHRlc3RfaW1wb3J0OjpJbXBvcnRNZXNzYWdlOjpkZWZhdWx0X2luc3RhbmNlKCksCisgICAgICAgICAgICAmbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbikpOworfQorCitURVNUKFJlZmxlY3Rpb25PcHNUZXN0LCBDbGVhclVua25vd24pIHsKKyAgLy8gVGVzdCB0aGF0IHRoZSBtZXNzYWdlJ3MgVW5rbm93bkZpZWxkU2V0IGlzIGNvcnJlY3RseSBjbGVhcmVkLgorICB1bml0dGVzdDo6VGVzdEVtcHR5TWVzc2FnZSBtZXNzYWdlOworICBtZXNzYWdlLm11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+QWRkVmFyaW50KDEyMzQsIDEpOworCisgIFJlZmxlY3Rpb25PcHM6OkNsZWFyKCZtZXNzYWdlKTsKKworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS51bmtub3duX2ZpZWxkcygpLmZpZWxkX2NvdW50KCkpOworfQorCitURVNUKFJlZmxlY3Rpb25PcHNUZXN0LCBDbGVhck9uZW9mKSB7CisgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIG1lc3NhZ2U7CisKKyAgVGVzdFV0aWw6OkV4cGVjdE9uZW9mQ2xlYXIobWVzc2FnZSk7CisgIFRlc3RVdGlsOjpTZXRPbmVvZjEoJm1lc3NhZ2UpOworICBUZXN0VXRpbDo6RXhwZWN0T25lb2ZTZXQxKG1lc3NhZ2UpOworICBSZWZsZWN0aW9uT3BzOjpDbGVhcigmbWVzc2FnZSk7CisgIFRlc3RVdGlsOjpFeHBlY3RPbmVvZkNsZWFyKG1lc3NhZ2UpOworCisgIFRlc3RVdGlsOjpTZXRPbmVvZjEoJm1lc3NhZ2UpOworICBUZXN0VXRpbDo6RXhwZWN0T25lb2ZTZXQxKG1lc3NhZ2UpOworICBUZXN0VXRpbDo6U2V0T25lb2YyKCZtZXNzYWdlKTsKKyAgVGVzdFV0aWw6OkV4cGVjdE9uZW9mU2V0MihtZXNzYWdlKTsKKyAgUmVmbGVjdGlvbk9wczo6Q2xlYXIoJm1lc3NhZ2UpOworICBUZXN0VXRpbDo6RXhwZWN0T25lb2ZDbGVhcihtZXNzYWdlKTsKK30KKworVEVTVChSZWZsZWN0aW9uT3BzVGVzdCwgRGlzY2FyZFVua25vd25GaWVsZHMpIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlOworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZtZXNzYWdlKTsKKworICAvLyBTZXQgc29tZSB1bmtub3duIGZpZWxkcyBpbiBtZXNzYWdlLgorICBtZXNzYWdlLm11dGFibGVfdW5rbm93bl9maWVsZHMoKQorICAgICAgICAtPkFkZFZhcmludCgxMjM0NTYsIDY1NDMyMSk7CisgIG1lc3NhZ2UubXV0YWJsZV9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpCisgICAgICAgIC0+bXV0YWJsZV91bmtub3duX2ZpZWxkcygpCisgICAgICAgIC0+QWRkVmFyaW50KDEyMzQ1NiwgNjU0MzIxKTsKKyAgbWVzc2FnZS5tdXRhYmxlX3JlcGVhdGVkX25lc3RlZF9tZXNzYWdlKDApCisgICAgICAgIC0+bXV0YWJsZV91bmtub3duX2ZpZWxkcygpCisgICAgICAgIC0+QWRkVmFyaW50KDEyMzQ1NiwgNjU0MzIxKTsKKworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS51bmtub3duX2ZpZWxkcygpLmZpZWxkX2NvdW50KCkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpCisgICAgICAgICAgICAgICAgICAgICAgLnVua25vd25fZmllbGRzKCkuZmllbGRfY291bnQoKSk7CisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlKDApCisgICAgICAgICAgICAgICAgICAgICAgLnVua25vd25fZmllbGRzKCkuZmllbGRfY291bnQoKSk7CisKKyAgLy8gRGlzY2FyZCB0aGVtLgorICBSZWZsZWN0aW9uT3BzOjpEaXNjYXJkVW5rbm93bkZpZWxkcygmbWVzc2FnZSk7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxGaWVsZHNTZXQobWVzc2FnZSk7CisKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UudW5rbm93bl9maWVsZHMoKS5maWVsZF9jb3VudCgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2Uub3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKQorICAgICAgICAgICAgICAgICAgICAgIC51bmtub3duX2ZpZWxkcygpLmZpZWxkX2NvdW50KCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSgwKQorICAgICAgICAgICAgICAgICAgICAgIC51bmtub3duX2ZpZWxkcygpLmZpZWxkX2NvdW50KCkpOworfQorCitURVNUKFJlZmxlY3Rpb25PcHNUZXN0LCBEaXNjYXJkVW5rbm93bkV4dGVuc2lvbnMpIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIG1lc3NhZ2U7CisgIFRlc3RVdGlsOjpTZXRBbGxFeHRlbnNpb25zKCZtZXNzYWdlKTsKKworICAvLyBTZXQgc29tZSB1bmtub3duIGZpZWxkcy4KKyAgbWVzc2FnZS5tdXRhYmxlX3Vua25vd25fZmllbGRzKCkKKyAgICAgICAgLT5BZGRWYXJpbnQoMTIzNDU2LCA2NTQzMjEpOworICBtZXNzYWdlLk11dGFibGVFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbikKKyAgICAgICAgLT5tdXRhYmxlX3Vua25vd25fZmllbGRzKCkKKyAgICAgICAgLT5BZGRWYXJpbnQoMTIzNDU2LCA2NTQzMjEpOworICBtZXNzYWdlLk11dGFibGVFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiwgMCkKKyAgICAgICAgLT5tdXRhYmxlX3Vua25vd25fZmllbGRzKCkKKyAgICAgICAgLT5BZGRWYXJpbnQoMTIzNDU2LCA2NTQzMjEpOworCisgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLnVua25vd25fZmllbGRzKCkuZmllbGRfY291bnQoKSk7CisgIEVYUEVDVF9FUSgxLAorICAgIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb24pCisgICAgICAgICAgIC51bmtub3duX2ZpZWxkcygpLmZpZWxkX2NvdW50KCkpOworICBFWFBFQ1RfRVEoMSwKKyAgICBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uLCAwKQorICAgICAgICAgICAudW5rbm93bl9maWVsZHMoKS5maWVsZF9jb3VudCgpKTsKKworICAvLyBEaXNjYXJkIHRoZW0uCisgIFJlZmxlY3Rpb25PcHM6OkRpc2NhcmRVbmtub3duRmllbGRzKCZtZXNzYWdlKTsKKyAgVGVzdFV0aWw6OkV4cGVjdEFsbEV4dGVuc2lvbnNTZXQobWVzc2FnZSk7CisKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UudW5rbm93bl9maWVsZHMoKS5maWVsZF9jb3VudCgpKTsKKyAgRVhQRUNUX0VRKDAsCisgICAgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbikKKyAgICAgICAgICAgLnVua25vd25fZmllbGRzKCkuZmllbGRfY291bnQoKSk7CisgIEVYUEVDVF9FUSgwLAorICAgIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb24sIDApCisgICAgICAgICAgIC51bmtub3duX2ZpZWxkcygpLmZpZWxkX2NvdW50KCkpOworfQorCitURVNUKFJlZmxlY3Rpb25PcHNUZXN0LCBJc0luaXRpYWxpemVkKSB7CisgIHVuaXR0ZXN0OjpUZXN0UmVxdWlyZWQgbWVzc2FnZTsKKworICBFWFBFQ1RfRkFMU0UoUmVmbGVjdGlvbk9wczo6SXNJbml0aWFsaXplZChtZXNzYWdlKSk7CisgIG1lc3NhZ2Uuc2V0X2EoMSk7CisgIEVYUEVDVF9GQUxTRShSZWZsZWN0aW9uT3BzOjpJc0luaXRpYWxpemVkKG1lc3NhZ2UpKTsKKyAgbWVzc2FnZS5zZXRfYigyKTsKKyAgRVhQRUNUX0ZBTFNFKFJlZmxlY3Rpb25PcHM6OklzSW5pdGlhbGl6ZWQobWVzc2FnZSkpOworICBtZXNzYWdlLnNldF9jKDMpOworICBFWFBFQ1RfVFJVRShSZWZsZWN0aW9uT3BzOjpJc0luaXRpYWxpemVkKG1lc3NhZ2UpKTsKK30KKworVEVTVChSZWZsZWN0aW9uT3BzVGVzdCwgRm9yZWlnbklzSW5pdGlhbGl6ZWQpIHsKKyAgdW5pdHRlc3Q6OlRlc3RSZXF1aXJlZEZvcmVpZ24gbWVzc2FnZTsKKworICAvLyBTdGFydHMgb3V0IGluaXRpYWxpemVkIGJlY2F1c2UgdGhlIGZvcmVpZ24gbWVzc2FnZSBpcyBpdHNlbGYgYW4gb3B0aW9uYWwKKyAgLy8gZmllbGQuCisgIEVYUEVDVF9UUlVFKFJlZmxlY3Rpb25PcHM6OklzSW5pdGlhbGl6ZWQobWVzc2FnZSkpOworCisgIC8vIE9uY2Ugd2UgY3JlYXRlIHRoYXQgZmllbGQsIHRoZSBtZXNzYWdlIGlzIG5vIGxvbmdlciBpbml0aWFsaXplZC4KKyAgbWVzc2FnZS5tdXRhYmxlX29wdGlvbmFsX21lc3NhZ2UoKTsKKyAgRVhQRUNUX0ZBTFNFKFJlZmxlY3Rpb25PcHM6OklzSW5pdGlhbGl6ZWQobWVzc2FnZSkpOworCisgIC8vIEluaXRpYWxpemUgaXQuICBOb3cgd2UncmUgaW5pdGlhbGl6ZWQuCisgIG1lc3NhZ2UubXV0YWJsZV9vcHRpb25hbF9tZXNzYWdlKCktPnNldF9hKDEpOworICBtZXNzYWdlLm11dGFibGVfb3B0aW9uYWxfbWVzc2FnZSgpLT5zZXRfYigyKTsKKyAgbWVzc2FnZS5tdXRhYmxlX29wdGlvbmFsX21lc3NhZ2UoKS0+c2V0X2MoMyk7CisgIEVYUEVDVF9UUlVFKFJlZmxlY3Rpb25PcHM6OklzSW5pdGlhbGl6ZWQobWVzc2FnZSkpOworCisgIC8vIEFkZCBhIHJlcGVhdGVkIHZlcnNpb24gb2YgdGhlIG1lc3NhZ2UuICBObyBsb25nZXIgaW5pdGlhbGl6ZWQuCisgIHVuaXR0ZXN0OjpUZXN0UmVxdWlyZWQqIHN1Yl9tZXNzYWdlID0gbWVzc2FnZS5hZGRfcmVwZWF0ZWRfbWVzc2FnZSgpOworICBFWFBFQ1RfRkFMU0UoUmVmbGVjdGlvbk9wczo6SXNJbml0aWFsaXplZChtZXNzYWdlKSk7CisKKyAgLy8gSW5pdGlhbGl6ZSB0aGF0IHJlcGVhdGVkIHZlcnNpb24uCisgIHN1Yl9tZXNzYWdlLT5zZXRfYSgxKTsKKyAgc3ViX21lc3NhZ2UtPnNldF9iKDIpOworICBzdWJfbWVzc2FnZS0+c2V0X2MoMyk7CisgIEVYUEVDVF9UUlVFKFJlZmxlY3Rpb25PcHM6OklzSW5pdGlhbGl6ZWQobWVzc2FnZSkpOworfQorCitURVNUKFJlZmxlY3Rpb25PcHNUZXN0LCBFeHRlbnNpb25Jc0luaXRpYWxpemVkKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyBtZXNzYWdlOworCisgIC8vIFN0YXJ0cyBvdXQgaW5pdGlhbGl6ZWQgYmVjYXVzZSB0aGUgZm9yZWlnbiBtZXNzYWdlIGlzIGl0c2VsZiBhbiBvcHRpb25hbAorICAvLyBmaWVsZC4KKyAgRVhQRUNUX1RSVUUoUmVmbGVjdGlvbk9wczo6SXNJbml0aWFsaXplZChtZXNzYWdlKSk7CisKKyAgLy8gT25jZSB3ZSBjcmVhdGUgdGhhdCBmaWVsZCwgdGhlIG1lc3NhZ2UgaXMgbm8gbG9uZ2VyIGluaXRpYWxpemVkLgorICBtZXNzYWdlLk11dGFibGVFeHRlbnNpb24odW5pdHRlc3Q6OlRlc3RSZXF1aXJlZDo6c2luZ2xlKTsKKyAgRVhQRUNUX0ZBTFNFKFJlZmxlY3Rpb25PcHM6OklzSW5pdGlhbGl6ZWQobWVzc2FnZSkpOworCisgIC8vIEluaXRpYWxpemUgaXQuICBOb3cgd2UncmUgaW5pdGlhbGl6ZWQuCisgIG1lc3NhZ2UuTXV0YWJsZUV4dGVuc2lvbih1bml0dGVzdDo6VGVzdFJlcXVpcmVkOjpzaW5nbGUpLT5zZXRfYSgxKTsKKyAgbWVzc2FnZS5NdXRhYmxlRXh0ZW5zaW9uKHVuaXR0ZXN0OjpUZXN0UmVxdWlyZWQ6OnNpbmdsZSktPnNldF9iKDIpOworICBtZXNzYWdlLk11dGFibGVFeHRlbnNpb24odW5pdHRlc3Q6OlRlc3RSZXF1aXJlZDo6c2luZ2xlKS0+c2V0X2MoMyk7CisgIEVYUEVDVF9UUlVFKFJlZmxlY3Rpb25PcHM6OklzSW5pdGlhbGl6ZWQobWVzc2FnZSkpOworCisgIC8vIEFkZCBhIHJlcGVhdGVkIHZlcnNpb24gb2YgdGhlIG1lc3NhZ2UuICBObyBsb25nZXIgaW5pdGlhbGl6ZWQuCisgIG1lc3NhZ2UuQWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpUZXN0UmVxdWlyZWQ6Om11bHRpKTsKKyAgRVhQRUNUX0ZBTFNFKFJlZmxlY3Rpb25PcHM6OklzSW5pdGlhbGl6ZWQobWVzc2FnZSkpOworCisgIC8vIEluaXRpYWxpemUgdGhhdCByZXBlYXRlZCB2ZXJzaW9uLgorICBtZXNzYWdlLk11dGFibGVFeHRlbnNpb24odW5pdHRlc3Q6OlRlc3RSZXF1aXJlZDo6bXVsdGksIDApLT5zZXRfYSgxKTsKKyAgbWVzc2FnZS5NdXRhYmxlRXh0ZW5zaW9uKHVuaXR0ZXN0OjpUZXN0UmVxdWlyZWQ6Om11bHRpLCAwKS0+c2V0X2IoMik7CisgIG1lc3NhZ2UuTXV0YWJsZUV4dGVuc2lvbih1bml0dGVzdDo6VGVzdFJlcXVpcmVkOjptdWx0aSwgMCktPnNldF9jKDMpOworICBFWFBFQ1RfVFJVRShSZWZsZWN0aW9uT3BzOjpJc0luaXRpYWxpemVkKG1lc3NhZ2UpKTsKK30KKworVEVTVChSZWZsZWN0aW9uT3BzVGVzdCwgT25lb2ZJc0luaXRpYWxpemVkKSB7CisgIHVuaXR0ZXN0OjpUZXN0UmVxdWlyZWRPbmVvZiBtZXNzYWdlOworICBFWFBFQ1RfVFJVRShSZWZsZWN0aW9uT3BzOjpJc0luaXRpYWxpemVkKG1lc3NhZ2UpKTsKKworICBtZXNzYWdlLm11dGFibGVfZm9vX21lc3NhZ2UoKTsKKyAgRVhQRUNUX0ZBTFNFKFJlZmxlY3Rpb25PcHM6OklzSW5pdGlhbGl6ZWQobWVzc2FnZSkpOworCisgIG1lc3NhZ2Uuc2V0X2Zvb19pbnQoMSk7CisgIEVYUEVDVF9UUlVFKFJlZmxlY3Rpb25PcHM6OklzSW5pdGlhbGl6ZWQobWVzc2FnZSkpOworCisgIG1lc3NhZ2UubXV0YWJsZV9mb29fbWVzc2FnZSgpOworICBFWFBFQ1RfRkFMU0UoUmVmbGVjdGlvbk9wczo6SXNJbml0aWFsaXplZChtZXNzYWdlKSk7CisgIG1lc3NhZ2UubXV0YWJsZV9mb29fbWVzc2FnZSgpLT5zZXRfcmVxdWlyZWRfZG91YmxlKDAuMSk7CisgIEVYUEVDVF9UUlVFKFJlZmxlY3Rpb25PcHM6OklzSW5pdGlhbGl6ZWQobWVzc2FnZSkpOworfQorCitzdGF0aWMgc3RyaW5nIEZpbmRJbml0aWFsaXphdGlvbkVycm9ycyhjb25zdCBNZXNzYWdlJiBtZXNzYWdlKSB7CisgIHZlY3RvcjxzdHJpbmc+IGVycm9yczsKKyAgUmVmbGVjdGlvbk9wczo6RmluZEluaXRpYWxpemF0aW9uRXJyb3JzKG1lc3NhZ2UsICIiLCAmZXJyb3JzKTsKKyAgcmV0dXJuIEpvaW4oZXJyb3JzLCAiLCIpOworfQorCitURVNUKFJlZmxlY3Rpb25PcHNUZXN0LCBGaW5kSW5pdGlhbGl6YXRpb25FcnJvcnMpIHsKKyAgdW5pdHRlc3Q6OlRlc3RSZXF1aXJlZCBtZXNzYWdlOworICBFWFBFQ1RfRVEoImEsYixjIiwgRmluZEluaXRpYWxpemF0aW9uRXJyb3JzKG1lc3NhZ2UpKTsKK30KKworVEVTVChSZWZsZWN0aW9uT3BzVGVzdCwgRmluZEZvcmVpZ25Jbml0aWFsaXphdGlvbkVycm9ycykgeworICB1bml0dGVzdDo6VGVzdFJlcXVpcmVkRm9yZWlnbiBtZXNzYWdlOworICBtZXNzYWdlLm11dGFibGVfb3B0aW9uYWxfbWVzc2FnZSgpOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9tZXNzYWdlKCk7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX21lc3NhZ2UoKTsKKyAgRVhQRUNUX0VRKCJvcHRpb25hbF9tZXNzYWdlLmEsIgorICAgICAgICAgICAgIm9wdGlvbmFsX21lc3NhZ2UuYiwiCisgICAgICAgICAgICAib3B0aW9uYWxfbWVzc2FnZS5jLCIKKyAgICAgICAgICAgICJyZXBlYXRlZF9tZXNzYWdlWzBdLmEsIgorICAgICAgICAgICAgInJlcGVhdGVkX21lc3NhZ2VbMF0uYiwiCisgICAgICAgICAgICAicmVwZWF0ZWRfbWVzc2FnZVswXS5jLCIKKyAgICAgICAgICAgICJyZXBlYXRlZF9tZXNzYWdlWzFdLmEsIgorICAgICAgICAgICAgInJlcGVhdGVkX21lc3NhZ2VbMV0uYiwiCisgICAgICAgICAgICAicmVwZWF0ZWRfbWVzc2FnZVsxXS5jIiwKKyAgICAgICAgICAgIEZpbmRJbml0aWFsaXphdGlvbkVycm9ycyhtZXNzYWdlKSk7Cit9CisKK1RFU1QoUmVmbGVjdGlvbk9wc1Rlc3QsIEZpbmRFeHRlbnNpb25Jbml0aWFsaXphdGlvbkVycm9ycykgeworICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTsKKyAgbWVzc2FnZS5NdXRhYmxlRXh0ZW5zaW9uKHVuaXR0ZXN0OjpUZXN0UmVxdWlyZWQ6OnNpbmdsZSk7CisgIG1lc3NhZ2UuQWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpUZXN0UmVxdWlyZWQ6Om11bHRpKTsKKyAgbWVzc2FnZS5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OlRlc3RSZXF1aXJlZDo6bXVsdGkpOworICBFWFBFQ1RfRVEoIihwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQuc2luZ2xlKS5hLCIKKyAgICAgICAgICAgICIocHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkLnNpbmdsZSkuYiwiCisgICAgICAgICAgICAiKHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZC5zaW5nbGUpLmMsIgorICAgICAgICAgICAgIihwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQubXVsdGkpWzBdLmEsIgorICAgICAgICAgICAgIihwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQubXVsdGkpWzBdLmIsIgorICAgICAgICAgICAgIihwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQubXVsdGkpWzBdLmMsIgorICAgICAgICAgICAgIihwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQubXVsdGkpWzFdLmEsIgorICAgICAgICAgICAgIihwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQubXVsdGkpWzFdLmIsIgorICAgICAgICAgICAgIihwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQubXVsdGkpWzFdLmMiLAorICAgICAgICAgICAgRmluZEluaXRpYWxpemF0aW9uRXJyb3JzKG1lc3NhZ2UpKTsKK30KKworVEVTVChSZWZsZWN0aW9uT3BzVGVzdCwgRmluZE9uZW9mSW5pdGlhbGl6YXRpb25FcnJvcnMpIHsKKyAgdW5pdHRlc3Q6OlRlc3RSZXF1aXJlZE9uZW9mIG1lc3NhZ2U7CisgIG1lc3NhZ2UubXV0YWJsZV9mb29fbWVzc2FnZSgpOworICBFWFBFQ1RfRVEoImZvb19tZXNzYWdlLnJlcXVpcmVkX2RvdWJsZSIsCisgICAgICAgICAgICBGaW5kSW5pdGlhbGl6YXRpb25FcnJvcnMobWVzc2FnZSkpOworfQorCit9ICAvLyBuYW1lc3BhY2UKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3JlcGVhdGVkX2ZpZWxkLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9yZXBlYXRlZF9maWVsZC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NDllMGEyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9yZXBlYXRlZF9maWVsZC5jYwpAQCAtMCwwICsxLDEwMiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8YWxnb3JpdGhtPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3JlcGVhdGVkX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2xvZ2dpbmcuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworbmFtZXNwYWNlIGludGVybmFsIHsKKwordm9pZCoqIFJlcGVhdGVkUHRyRmllbGRCYXNlOjpJbnRlcm5hbEV4dGVuZChpbnQgZXh0ZW5kX2Ftb3VudCkgeworICBpbnQgbmV3X3NpemUgPSBjdXJyZW50X3NpemVfICsgZXh0ZW5kX2Ftb3VudDsKKyAgaWYgKHRvdGFsX3NpemVfID49IG5ld19zaXplKSB7CisgICAgLy8gTi5CLjogcmVwXyBpcyBub24tTlVMTCBiZWNhdXNlIGV4dGVuZF9hbW91bnQgaXMgYWx3YXlzID4gMCwgaGVuY2UKKyAgICAvLyB0b3RhbF9zaXplIG11c3QgYmUgbm9uLXplcm8gc2luY2UgaXQgaXMgbG93ZXItYm91bmRlZCBieSBuZXdfc2l6ZS4KKyAgICByZXR1cm4gJnJlcF8tPmVsZW1lbnRzW2N1cnJlbnRfc2l6ZV9dOworICB9CisgIFJlcCogb2xkX3JlcCA9IHJlcF87CisgIEFyZW5hKiBhcmVuYSA9IEdldEFyZW5hTm9WaXJ0dWFsKCk7CisgIG5ld19zaXplID0gbWF4KGtNaW5SZXBlYXRlZEZpZWxkQWxsb2NhdGlvblNpemUsCisgICAgICAgICAgICAgICAgIG1heCh0b3RhbF9zaXplXyAqIDIsIG5ld19zaXplKSk7CisgIEdPT0dMRV9DSEVDS19MRShuZXdfc2l6ZSwKKyAgICAgICAgICAgKHN0ZDo6bnVtZXJpY19saW1pdHM8c2l6ZV90Pjo6bWF4KCkgLSBrUmVwSGVhZGVyU2l6ZSkgLworICAgICAgICAgICBzaXplb2Yob2xkX3JlcC0+ZWxlbWVudHNbMF0pKQorICAgICAgPDwgIlJlcXVlc3RlZCBzaXplIGlzIHRvbyBsYXJnZSB0byBmaXQgaW50byBzaXplX3QuIjsKKyAgaWYgKGFyZW5hID09IE5VTEwpIHsKKyAgICByZXBfID0gcmVpbnRlcnByZXRfY2FzdDxSZXAqPigKKyAgICAgICAgbmV3IGNoYXJba1JlcEhlYWRlclNpemUgKyBzaXplb2Yob2xkX3JlcC0+ZWxlbWVudHNbMF0pICogbmV3X3NpemVdKTsKKyAgfSBlbHNlIHsKKyAgICByZXBfID0gcmVpbnRlcnByZXRfY2FzdDxSZXAqPigKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYTo6Q3JlYXRlQXJyYXk8Y2hhcj4oYXJlbmEsCisgICAgICAgICAgICBrUmVwSGVhZGVyU2l6ZSArIHNpemVvZihvbGRfcmVwLT5lbGVtZW50c1swXSkgKiBuZXdfc2l6ZSkpOworICB9CisgIHRvdGFsX3NpemVfID0gbmV3X3NpemU7CisgIGlmIChvbGRfcmVwICYmIG9sZF9yZXAtPmFsbG9jYXRlZF9zaXplID4gMCkgeworICAgIG1lbWNweShyZXBfLT5lbGVtZW50cywgb2xkX3JlcC0+ZWxlbWVudHMsCisgICAgICAgICAgIG9sZF9yZXAtPmFsbG9jYXRlZF9zaXplICogc2l6ZW9mKHJlcF8tPmVsZW1lbnRzWzBdKSk7CisgICAgcmVwXy0+YWxsb2NhdGVkX3NpemUgPSBvbGRfcmVwLT5hbGxvY2F0ZWRfc2l6ZTsKKyAgfSBlbHNlIHsKKyAgICByZXBfLT5hbGxvY2F0ZWRfc2l6ZSA9IDA7CisgIH0KKyAgaWYgKGFyZW5hID09IE5VTEwpIHsKKyAgICBkZWxldGUgW10gcmVpbnRlcnByZXRfY2FzdDxjaGFyKj4ob2xkX3JlcCk7CisgIH0KKyAgcmV0dXJuICZyZXBfLT5lbGVtZW50c1tjdXJyZW50X3NpemVfXTsKK30KKwordm9pZCBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6UmVzZXJ2ZShpbnQgbmV3X3NpemUpIHsKKyAgaWYgKG5ld19zaXplID4gY3VycmVudF9zaXplXykgeworICAgIEludGVybmFsRXh0ZW5kKG5ld19zaXplIC0gY3VycmVudF9zaXplXyk7CisgIH0KK30KKwordm9pZCBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6Q2xvc2VHYXAoaW50IHN0YXJ0LCBpbnQgbnVtKSB7CisgIGlmIChyZXBfID09IE5VTEwpIHJldHVybjsKKyAgLy8gQ2xvc2UgdXAgYSBnYXAgb2YgIm51bSIgZWxlbWVudHMgc3RhcnRpbmcgYXQgb2Zmc2V0ICJzdGFydCIuCisgIGZvciAoaW50IGkgPSBzdGFydCArIG51bTsgaSA8IHJlcF8tPmFsbG9jYXRlZF9zaXplOyArK2kpCisgICAgcmVwXy0+ZWxlbWVudHNbaSAtIG51bV0gPSByZXBfLT5lbGVtZW50c1tpXTsKKyAgY3VycmVudF9zaXplXyAtPSBudW07CisgIHJlcF8tPmFsbG9jYXRlZF9zaXplIC09IG51bTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCisKKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3JlcGVhdGVkX2ZpZWxkLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3JlcGVhdGVkX2ZpZWxkLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTQ0N2ZhNAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvcmVwZWF0ZWRfZmllbGQuaApAQCAtMCwwICsxLDI0MjAgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBSZXBlYXRlZEZpZWxkIGFuZCBSZXBlYXRlZFB0ckZpZWxkIGFyZSB1c2VkIGJ5IGdlbmVyYXRlZCBwcm90b2NvbCBtZXNzYWdlCisvLyBjbGFzc2VzIHRvIG1hbmlwdWxhdGUgcmVwZWF0ZWQgZmllbGRzLiAgVGhlc2UgY2xhc3NlcyBhcmUgdmVyeSBzaW1pbGFyIHRvCisvLyBTVEwncyB2ZWN0b3IsIGJ1dCBpbmNsdWRlIGEgbnVtYmVyIG9mIG9wdGltaXphdGlvbnMgZm91bmQgdG8gYmUgdXNlZnVsCisvLyBzcGVjaWZpY2FsbHkgaW4gdGhlIGNhc2Ugb2YgUHJvdG9jb2wgQnVmZmVycy4gIFJlcGVhdGVkUHRyRmllbGQgaXMKKy8vIHBhcnRpY3VsYXJseSBkaWZmZXJlbnQgZnJvbSBTVEwgdmVjdG9yIGFzIGl0IG1hbmFnZXMgb3duZXJzaGlwIG9mIHRoZQorLy8gcG9pbnRlcnMgdGhhdCBpdCBjb250YWlucy4KKy8vCisvLyBUeXBpY2FsbHksIGNsaWVudHMgc2hvdWxkIG5vdCBuZWVkIHRvIGFjY2VzcyBSZXBlYXRlZEZpZWxkIG9iamVjdHMgZGlyZWN0bHksCisvLyBidXQgc2hvdWxkIGluc3RlYWQgdXNlIHRoZSBhY2Nlc3NvciBmdW5jdGlvbnMgZ2VuZXJhdGVkIGF1dG9tYXRpY2FsbHkgYnkgdGhlCisvLyBwcm90b2NvbCBjb21waWxlci4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfUkVQRUFURURfRklFTERfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9SRVBFQVRFRF9GSUVMRF9IX18KKworI2lmZGVmIF9NU0NfVkVSCisvLyBUaGlzIGlzIHJlcXVpcmVkIGZvciBtaW4vbWF4IG9uIFZTMjAxMyBvbmx5LgorI2luY2x1ZGUgPGFsZ29yaXRobT4KKyNlbmRpZgorCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGl0ZXJhdG9yPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jYXN0cy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9sb2dnaW5nLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy90eXBlX3RyYWl0cy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9hcmVuYS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfbWVzc2FnZV91dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21lc3NhZ2VfbGl0ZS5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKKworbmFtZXNwYWNlIHVwYiB7CituYW1lc3BhY2UgZ29vZ2xlX29wZW5zb3VyY2UgeworY2xhc3MgR01SX0hhbmRsZXJzOworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZV9vcGVuc291cmNlCit9ICAvLyBuYW1lc3BhY2UgdXBiCisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKK2NsYXNzIE1lc3NhZ2U7CisKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKK3N0YXRpYyBjb25zdCBpbnQga01pblJlcGVhdGVkRmllbGRBbGxvY2F0aW9uU2l6ZSA9IDQ7CisKKy8vIEEgdXRpbGl0eSBmdW5jdGlvbiBmb3IgbG9nZ2luZyB0aGF0IGRvZXNuJ3QgbmVlZCBhbnkgdGVtcGxhdGUgdHlwZXMuCit2b2lkIExvZ0luZGV4T3V0T2ZCb3VuZHMoaW50IGluZGV4LCBpbnQgc2l6ZSk7CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBJdGVyPgoraW5saW5lIGludCBDYWxjdWxhdGVSZXNlcnZlKEl0ZXIgYmVnaW4sIEl0ZXIgZW5kLCBzdGQ6OmZvcndhcmRfaXRlcmF0b3JfdGFnKSB7CisgIHJldHVybiBzdGQ6OmRpc3RhbmNlKGJlZ2luLCBlbmQpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgSXRlcj4KK2lubGluZSBpbnQgQ2FsY3VsYXRlUmVzZXJ2ZShJdGVyIC8qYmVnaW4qLywgSXRlciAvKmVuZCovLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6aW5wdXRfaXRlcmF0b3JfdGFnIC8qdW51c2VkKi8pIHsKKyAgcmV0dXJuIC0xOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgSXRlcj4KK2lubGluZSBpbnQgQ2FsY3VsYXRlUmVzZXJ2ZShJdGVyIGJlZ2luLCBJdGVyIGVuZCkgeworICB0eXBlZGVmIHR5cGVuYW1lIHN0ZDo6aXRlcmF0b3JfdHJhaXRzPEl0ZXI+OjppdGVyYXRvcl9jYXRlZ29yeSBDYXRlZ29yeTsKKyAgcmV0dXJuIENhbGN1bGF0ZVJlc2VydmUoYmVnaW4sIGVuZCwgQ2F0ZWdvcnkoKSk7Cit9Cit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKKworCisvLyBSZXBlYXRlZEZpZWxkIGlzIHVzZWQgdG8gcmVwcmVzZW50IHJlcGVhdGVkIGZpZWxkcyBvZiBhIHByaW1pdGl2ZSB0eXBlIChpbgorLy8gb3RoZXIgd29yZHMsIGV2ZXJ5dGhpbmcgZXhjZXB0IHN0cmluZ3MgYW5kIG5lc3RlZCBNZXNzYWdlcykuICBNb3N0IHVzZXJzIHdpbGwKKy8vIG5vdCBldmVyIHVzZSBhIFJlcGVhdGVkRmllbGQgZGlyZWN0bHk7IHRoZXkgd2lsbCB1c2UgdGhlIGdldC1ieS1pbmRleCwKKy8vIHNldC1ieS1pbmRleCwgYW5kIGFkZCBhY2Nlc3NvcnMgdGhhdCBhcmUgZ2VuZXJhdGVkIGZvciBhbGwgcmVwZWF0ZWQgZmllbGRzLgordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitjbGFzcyBSZXBlYXRlZEZpZWxkIHsKKyBwdWJsaWM6CisgIFJlcGVhdGVkRmllbGQoKTsKKyAgZXhwbGljaXQgUmVwZWF0ZWRGaWVsZChBcmVuYSogYXJlbmEpOworICBSZXBlYXRlZEZpZWxkKGNvbnN0IFJlcGVhdGVkRmllbGQmIG90aGVyKTsKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIEl0ZXI+CisgIFJlcGVhdGVkRmllbGQoSXRlciBiZWdpbiwgY29uc3QgSXRlciYgZW5kKTsKKyAgflJlcGVhdGVkRmllbGQoKTsKKworICBSZXBlYXRlZEZpZWxkJiBvcGVyYXRvcj0oY29uc3QgUmVwZWF0ZWRGaWVsZCYgb3RoZXIpOworCisgIGJvb2wgZW1wdHkoKSBjb25zdDsKKyAgaW50IHNpemUoKSBjb25zdDsKKworICBjb25zdCBFbGVtZW50JiBHZXQoaW50IGluZGV4KSBjb25zdDsKKyAgRWxlbWVudCogTXV0YWJsZShpbnQgaW5kZXgpOworICB2b2lkIFNldChpbnQgaW5kZXgsIGNvbnN0IEVsZW1lbnQmIHZhbHVlKTsKKyAgdm9pZCBBZGQoY29uc3QgRWxlbWVudCYgdmFsdWUpOworICBFbGVtZW50KiBBZGQoKTsKKyAgLy8gUmVtb3ZlIHRoZSBsYXN0IGVsZW1lbnQgaW4gdGhlIGFycmF5LgorICB2b2lkIFJlbW92ZUxhc3QoKTsKKworICAvLyBFeHRyYWN0IGVsZW1lbnRzIHdpdGggaW5kaWNlcyBpbiAiW3N0YXJ0IC4uIHN0YXJ0K251bS0xXSIuCisgIC8vIENvcHkgdGhlbSBpbnRvICJlbGVtZW50c1swIC4uIG51bS0xXSIgaWYgImVsZW1lbnRzIiBpcyBub3QgTlVMTC4KKyAgLy8gQ2F1dGlvbjogaW1wbGVtZW50YXRpb24gYWxzbyBtb3ZlcyBlbGVtZW50cyB3aXRoIGluZGljZXMgW3N0YXJ0K251bSAuLl0uCisgIC8vIENhbGxpbmcgdGhpcyByb3V0aW5lIGluc2lkZSBhIGxvb3AgY2FuIGNhdXNlIHF1YWRyYXRpYyBiZWhhdmlvci4KKyAgdm9pZCBFeHRyYWN0U3VicmFuZ2UoaW50IHN0YXJ0LCBpbnQgbnVtLCBFbGVtZW50KiBlbGVtZW50cyk7CisKKyAgdm9pZCBDbGVhcigpOworICB2b2lkIE1lcmdlRnJvbShjb25zdCBSZXBlYXRlZEZpZWxkJiBvdGhlcik7CisgIHZvaWQgQ29weUZyb20oY29uc3QgUmVwZWF0ZWRGaWVsZCYgb3RoZXIpOworCisgIC8vIFJlc2VydmUgc3BhY2UgdG8gZXhwYW5kIHRoZSBmaWVsZCB0byBhdCBsZWFzdCB0aGUgZ2l2ZW4gc2l6ZS4gIElmIHRoZQorICAvLyBhcnJheSBpcyBncm93biwgaXQgd2lsbCBhbHdheXMgYmUgYXQgbGVhc3QgZG91YmxlZCBpbiBzaXplLgorICB2b2lkIFJlc2VydmUoaW50IG5ld19zaXplKTsKKworICAvLyBSZXNpemUgdGhlIFJlcGVhdGVkRmllbGQgdG8gYSBuZXcsIHNtYWxsZXIgc2l6ZS4gIFRoaXMgaXMgTygxKS4KKyAgdm9pZCBUcnVuY2F0ZShpbnQgbmV3X3NpemUpOworCisgIHZvaWQgQWRkQWxyZWFkeVJlc2VydmVkKGNvbnN0IEVsZW1lbnQmIHZhbHVlKTsKKyAgRWxlbWVudCogQWRkQWxyZWFkeVJlc2VydmVkKCk7CisgIGludCBDYXBhY2l0eSgpIGNvbnN0OworCisgIC8vIExpa2UgU1RMIHJlc2l6ZS4gIFVzZXMgdmFsdWUgdG8gZmlsbCBhcHBlbmRlZCBlbGVtZW50cy4KKyAgLy8gTGlrZSBUcnVuY2F0ZSgpIGlmIG5ld19zaXplIDw9IHNpemUoKSwgb3RoZXJ3aXNlIHRoaXMgaXMKKyAgLy8gTyhuZXdfc2l6ZSAtIHNpemUoKSkuCisgIHZvaWQgUmVzaXplKGludCBuZXdfc2l6ZSwgY29uc3QgRWxlbWVudCYgdmFsdWUpOworCisgIC8vIEdldHMgdGhlIHVuZGVybHlpbmcgYXJyYXkuICBUaGlzIHBvaW50ZXIgaXMgcG9zc2libHkgaW52YWxpZGF0ZWQgYnkKKyAgLy8gYW55IGFkZCBvciByZW1vdmUgb3BlcmF0aW9uLgorICBFbGVtZW50KiBtdXRhYmxlX2RhdGEoKTsKKyAgY29uc3QgRWxlbWVudCogZGF0YSgpIGNvbnN0OworCisgIC8vIFN3YXAgZW50aXJlIGNvbnRlbnRzIHdpdGggIm90aGVyIi4gSWYgdGhleSBhcmUgc2VwYXJhdGUgYXJlbmFzIHRoZW4sIGNvcGllcworICAvLyBkYXRhIGJldHdlZW4gZWFjaCBvdGhlci4KKyAgdm9pZCBTd2FwKFJlcGVhdGVkRmllbGQqIG90aGVyKTsKKworICAvLyBTd2FwIGVudGlyZSBjb250ZW50cyB3aXRoICJvdGhlciIuIFNob3VsZCBiZSBjYWxsZWQgb25seSBpZiB0aGUgY2FsbGVyIGNhbgorICAvLyBndWFyYW50ZWUgdGhhdCBib3RoIHJlcGVhdGVkIGZpZWxkcyBhcmUgb24gdGhlIHNhbWUgYXJlbmEgb3IgYXJlIG9uIHRoZQorICAvLyBoZWFwLiBTd2FwcGluZyBiZXR3ZWVuIGRpZmZlcmVudCBhcmVuYXMgaXMgZGlzYWxsb3dlZCBhbmQgY2F1Z2h0IGJ5IGEKKyAgLy8gR09PR0xFX0RDSEVDSyAoc2VlIEFQSSBkb2NzIGZvciBkZXRhaWxzKS4KKyAgdm9pZCBVbnNhZmVBcmVuYVN3YXAoUmVwZWF0ZWRGaWVsZCogb3RoZXIpOworCisgIC8vIFN3YXAgdHdvIGVsZW1lbnRzLgorICB2b2lkIFN3YXBFbGVtZW50cyhpbnQgaW5kZXgxLCBpbnQgaW5kZXgyKTsKKworICAvLyBTVEwtbGlrZSBpdGVyYXRvciBzdXBwb3J0CisgIHR5cGVkZWYgRWxlbWVudCogaXRlcmF0b3I7CisgIHR5cGVkZWYgY29uc3QgRWxlbWVudCogY29uc3RfaXRlcmF0b3I7CisgIHR5cGVkZWYgRWxlbWVudCB2YWx1ZV90eXBlOworICB0eXBlZGVmIHZhbHVlX3R5cGUmIHJlZmVyZW5jZTsKKyAgdHlwZWRlZiBjb25zdCB2YWx1ZV90eXBlJiBjb25zdF9yZWZlcmVuY2U7CisgIHR5cGVkZWYgdmFsdWVfdHlwZSogcG9pbnRlcjsKKyAgdHlwZWRlZiBjb25zdCB2YWx1ZV90eXBlKiBjb25zdF9wb2ludGVyOworICB0eXBlZGVmIGludCBzaXplX3R5cGU7CisgIHR5cGVkZWYgcHRyZGlmZl90IGRpZmZlcmVuY2VfdHlwZTsKKworICBpdGVyYXRvciBiZWdpbigpOworICBjb25zdF9pdGVyYXRvciBiZWdpbigpIGNvbnN0OworICBjb25zdF9pdGVyYXRvciBjYmVnaW4oKSBjb25zdDsKKyAgaXRlcmF0b3IgZW5kKCk7CisgIGNvbnN0X2l0ZXJhdG9yIGVuZCgpIGNvbnN0OworICBjb25zdF9pdGVyYXRvciBjZW5kKCkgY29uc3Q7CisKKyAgLy8gUmV2ZXJzZSBpdGVyYXRvciBzdXBwb3J0CisgIHR5cGVkZWYgc3RkOjpyZXZlcnNlX2l0ZXJhdG9yPGNvbnN0X2l0ZXJhdG9yPiBjb25zdF9yZXZlcnNlX2l0ZXJhdG9yOworICB0eXBlZGVmIHN0ZDo6cmV2ZXJzZV9pdGVyYXRvcjxpdGVyYXRvcj4gcmV2ZXJzZV9pdGVyYXRvcjsKKyAgcmV2ZXJzZV9pdGVyYXRvciByYmVnaW4oKSB7CisgICAgcmV0dXJuIHJldmVyc2VfaXRlcmF0b3IoZW5kKCkpOworICB9CisgIGNvbnN0X3JldmVyc2VfaXRlcmF0b3IgcmJlZ2luKCkgY29uc3QgeworICAgIHJldHVybiBjb25zdF9yZXZlcnNlX2l0ZXJhdG9yKGVuZCgpKTsKKyAgfQorICByZXZlcnNlX2l0ZXJhdG9yIHJlbmQoKSB7CisgICAgcmV0dXJuIHJldmVyc2VfaXRlcmF0b3IoYmVnaW4oKSk7CisgIH0KKyAgY29uc3RfcmV2ZXJzZV9pdGVyYXRvciByZW5kKCkgY29uc3QgeworICAgIHJldHVybiBjb25zdF9yZXZlcnNlX2l0ZXJhdG9yKGJlZ2luKCkpOworICB9CisKKyAgLy8gUmV0dXJucyB0aGUgbnVtYmVyIG9mIGJ5dGVzIHVzZWQgYnkgdGhlIHJlcGVhdGVkIGZpZWxkLCBleGNsdWRpbmcKKyAgLy8gc2l6ZW9mKCp0aGlzKQorICBpbnQgU3BhY2VVc2VkRXhjbHVkaW5nU2VsZigpIGNvbnN0OworCisgIC8vIFJlbW92ZXMgdGhlIGVsZW1lbnQgcmVmZXJlbmNlZCBieSBwb3NpdGlvbi4KKyAgLy8KKyAgLy8gUmV0dXJucyBhbiBpdGVyYXRvciB0byB0aGUgZWxlbWVudCBpbW1lZGlhdGVseSBmb2xsb3dpbmcgdGhlIHJlbW92ZWQKKyAgLy8gZWxlbWVudC4KKyAgLy8KKyAgLy8gSW52YWxpZGF0ZXMgYWxsIGl0ZXJhdG9ycyBhdCBvciBhZnRlciB0aGUgcmVtb3ZlZCBlbGVtZW50LCBpbmNsdWRpbmcgZW5kKCkuCisgIGl0ZXJhdG9yIGVyYXNlKGNvbnN0X2l0ZXJhdG9yIHBvc2l0aW9uKTsKKworICAvLyBSZW1vdmVzIHRoZSBlbGVtZW50cyBpbiB0aGUgcmFuZ2UgW2ZpcnN0LCBsYXN0KS4KKyAgLy8KKyAgLy8gUmV0dXJucyBhbiBpdGVyYXRvciB0byB0aGUgZWxlbWVudCBpbW1lZGlhdGVseSBmb2xsb3dpbmcgdGhlIHJlbW92ZWQgcmFuZ2UuCisgIC8vCisgIC8vIEludmFsaWRhdGVzIGFsbCBpdGVyYXRvcnMgYXQgb3IgYWZ0ZXIgdGhlIHJlbW92ZWQgcmFuZ2UsIGluY2x1ZGluZyBlbmQoKS4KKyAgaXRlcmF0b3IgZXJhc2UoY29uc3RfaXRlcmF0b3IgZmlyc3QsIGNvbnN0X2l0ZXJhdG9yIGxhc3QpOworCisgIC8vIEdldCB0aGUgQXJlbmEgb24gd2hpY2ggdGhpcyBSZXBlYXRlZEZpZWxkIHN0b3JlcyBpdHMgZWxlbWVudHMuCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hKCkgY29uc3QgeworICAgIHJldHVybiBHZXRBcmVuYU5vVmlydHVhbCgpOworICB9CisKKyBwcml2YXRlOgorICBzdGF0aWMgY29uc3QgaW50IGtJbml0aWFsU2l6ZSA9IDA7CisgIC8vIEEgbm90ZSBvbiB0aGUgcmVwcmVzZW50YXRpb24gaGVyZSAoc2VlIGFsc28gY29tbWVudCBiZWxvdyBmb3IKKyAgLy8gUmVwZWF0ZWRQdHJGaWVsZEJhc2UncyBzdHJ1Y3QgUmVwKToKKyAgLy8KKyAgLy8gV2UgbWFpbnRhaW4gdGhlIHNhbWUgc2l6ZW9mKFJlcGVhdGVkRmllbGQpIGFzIGJlZm9yZSB3ZSBhZGRlZCBhcmVuYSBzdXBwb3J0CisgIC8vIHNvIHRoYXQgd2UgZG8gbm90IGRlZ3JhZGUgcGVyZm9ybWFuY2UgYnkgYmxvYXRpbmcgbWVtb3J5IHVzYWdlLiBEaXJlY3RseQorICAvLyBhZGRpbmcgYW4gYXJlbmFfIGVsZW1lbnQgdG8gUmVwZWF0ZWRGaWVsZCBpcyBxdWl0ZSBjb3N0bHkuIEJ5IHVzaW5nCisgIC8vIGluZGlyZWN0aW9uIGluIHRoaXMgd2F5LCB3ZSBrZWVwIHRoZSBzYW1lIHNpemUgd2hlbiB0aGUgUmVwZWF0ZWRGaWVsZCBpcworICAvLyBlbXB0eSAoY29tbW9uIGNhc2UpLCBhbmQgYWRkIG9ubHkgYW4gOC1ieXRlIGhlYWRlciB0byB0aGUgZWxlbWVudHMgYXJyYXkKKyAgLy8gd2hlbiBub24tZW1wdHkuIFdlIG1ha2Ugc3VyZSB0byBwbGFjZSB0aGUgc2l6ZSBmaWVsZHMgZGlyZWN0bHkgaW4gdGhlCisgIC8vIFJlcGVhdGVkRmllbGQgY2xhc3MgdG8gYXZvaWQgY29zdGx5IGNhY2hlIG1pc3NlcyBkdWUgdG8gdGhlIGluZGlyZWN0aW9uLgorICBpbnQgY3VycmVudF9zaXplXzsKKyAgaW50IHRvdGFsX3NpemVfOworICBzdHJ1Y3QgUmVwIHsKKyAgICBBcmVuYSogYXJlbmE7CisgICAgRWxlbWVudCAgZWxlbWVudHNbMV07CisgIH07CisgIC8vIFdlIGNhbiBub3QgdXNlIHNpemVvZihSZXApIC0gc2l6ZW9mKEVsZW1lbnQpIGR1ZSB0byB0aGUgdHJhaWxpbmcgcGFkZGluZyBvbgorICAvLyB0aGUgc3RydWN0LiBXZSBjYW4gbm90IHVzZSBzaXplb2YoQXJlbmEqKSBhcyB3ZWxsIGJlY2F1c2UgdGhlcmUgbWlnaHQgYmUKKyAgLy8gYSAiZ2FwIiBhZnRlciB0aGUgZmllbGQgYXJlbmEgYW5kIGJlZm9yZSB0aGUgZmllbGQgZWxlbWVudHMgKGUuZy4sIHdoZW4KKyAgLy8gRWxlbWVudCBpcyBkb3VibGUgYW5kIHBvaW50ZXIgaXMgMzJiaXQpLgorICBzdGF0aWMgY29uc3Qgc2l6ZV90IGtSZXBIZWFkZXJTaXplOworICAvLyBDb250YWlucyBhcmVuYSBwdHIgYW5kIHRoZSBlbGVtZW50cyBhcnJheS4gV2UgYWxzbyBrZWVwIHRoZSBpbnZhcmlhbnQgdGhhdAorICAvLyBpZiByZXBfIGlzIE5VTEwsIHRoZW4gYXJlbmEgaXMgTlVMTC4KKyAgUmVwKiByZXBfOworCisgIGZyaWVuZCBjbGFzcyBBcmVuYTsKKyAgdHlwZWRlZiB2b2lkIEludGVybmFsQXJlbmFDb25zdHJ1Y3RhYmxlXzsKKworICAvLyBNb3ZlIHRoZSBjb250ZW50cyBvZiB8ZnJvbXwgaW50byB8dG98LCBwb3NzaWJseSBjbG9iYmVyaW5nIHxmcm9tfCBpbiB0aGUKKyAgLy8gcHJvY2Vzcy4gIEZvciBwcmltaXRpdmUgdHlwZXMgdGhpcyBpcyBqdXN0IGEgbWVtY3B5KCksIGJ1dCBpdCBjb3VsZCBiZQorICAvLyBzcGVjaWFsaXplZCBmb3Igbm9uLXByaW1pdGl2ZSB0eXBlcyB0bywgc2F5LCBzd2FwIGVhY2ggZWxlbWVudCBpbnN0ZWFkLgorICB2b2lkIE1vdmVBcnJheShFbGVtZW50KiB0bywgRWxlbWVudCogZnJvbSwgaW50IHNpemUpOworCisgIC8vIENvcHkgdGhlIGVsZW1lbnRzIG9mIHxmcm9tfCBpbnRvIHx0b3wuCisgIHZvaWQgQ29weUFycmF5KEVsZW1lbnQqIHRvLCBjb25zdCBFbGVtZW50KiBmcm9tLCBpbnQgc2l6ZSk7CisKKyAgaW5saW5lIHZvaWQgSW50ZXJuYWxTd2FwKFJlcGVhdGVkRmllbGQqIG90aGVyKTsKKworICAvLyBJbnRlcm5hbCBoZWxwZXIgZXhwZWN0ZWQgYnkgQXJlbmEgbWV0aG9kcy4KKyAgaW5saW5lIEFyZW5hKiBHZXRBcmVuYU5vVmlydHVhbCgpIGNvbnN0IHsKKyAgICByZXR1cm4gKHJlcF8gPT0gTlVMTCkgPyBOVUxMIDogcmVwXy0+YXJlbmE7CisgIH0KK307CisKK3RlbXBsYXRlPHR5cGVuYW1lIEVsZW1lbnQ+Citjb25zdCBzaXplX3QgUmVwZWF0ZWRGaWVsZDxFbGVtZW50Pjo6a1JlcEhlYWRlclNpemUgPQorICAgIHJlaW50ZXJwcmV0X2Nhc3Q8c2l6ZV90PigmcmVpbnRlcnByZXRfY2FzdDxSZXAqPigxNiktPmVsZW1lbnRzWzBdKSAtIDE2OworCituYW1lc3BhY2UgaW50ZXJuYWwgewordGVtcGxhdGUgPHR5cGVuYW1lIEl0PiBjbGFzcyBSZXBlYXRlZFB0ckl0ZXJhdG9yOwordGVtcGxhdGUgPHR5cGVuYW1lIEl0LCB0eXBlbmFtZSBWb2lkUHRyPiBjbGFzcyBSZXBlYXRlZFB0ck92ZXJQdHJzSXRlcmF0b3I7Cit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKKworbmFtZXNwYWNlIGludGVybmFsIHsKKworLy8gVGhpcyBpcyBhIGhlbHBlciB0ZW1wbGF0ZSB0byBjb3B5IGFuIGFycmF5IG9mIGVsZW1lbnRzIGVmZmVjaWVudGx5IHdoZW4gdGhleQorLy8gaGF2ZSBhIHRyaXZpYWwgY29weSBjb25zdHJ1Y3RvciwgYW5kIGNvcnJlY3RseSBvdGhlcndpc2UuIFRoaXMgcmVhbGx5CisvLyBzaG91bGRuJ3QgYmUgbmVjZXNzYXJ5LCBidXQgb3VyIGNvbXBpbGVyIGRvZXNuJ3Qgb3B0aW1pemUgc3RkOjpjb3B5IHZlcnkKKy8vIGVmZmVjdGl2ZWx5LgordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQsCisgICAgICAgICAgYm9vbCBIYXNUcml2aWFsQ29weSA9IGhhc190cml2aWFsX2NvcHk8RWxlbWVudD46OnZhbHVlPgorc3RydWN0IEVsZW1lbnRDb3BpZXIgeworICB2b2lkIG9wZXJhdG9yKCkoRWxlbWVudCogdG8sIGNvbnN0IEVsZW1lbnQqIGZyb20sIGludCBhcnJheV9zaXplKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorCituYW1lc3BhY2UgaW50ZXJuYWwgeworCisvLyB0eXBlLXRyYWl0cyBoZWxwZXIgZm9yIFJlcGVhdGVkUHRyRmllbGRCYXNlOiB3ZSBvbmx5IHdhbnQgdG8gaW52b2tlCisvLyBhcmVuYS1yZWxhdGVkICJjb3B5IGlmIG9uIGRpZmZlcmVudCBhcmVuYSIgYmVoYXZpb3IgaWYgdGhlIG5lY2Vzc2FyeSBtZXRob2RzCisvLyBleGlzdCBvbiB0aGUgY29udGFpbmVkIHR5cGUuIEluIHBhcnRpY3VsYXIsIHdlIHJlbHkgb24gTWVyZ2VGcm9tKCkgZXhpc3RpbmcKKy8vIGFzIGEgZ2VuZXJhbCBwcm94eSBmb3IgdGhlIGZhY3QgdGhhdCBhIGNvcHkgd2lsbCB3b3JrLCBhbmQgd2UgYWxzbyBwcm92aWRlIGEKKy8vIHNwZWNpZmljIG92ZXJyaWRlIGZvciBzdHJpbmcqLgordGVtcGxhdGU8dHlwZW5hbWUgVD4KK3N0cnVjdCBUeXBlSW1wbGVtZW50c01lcmdlQmVoYXZpb3IgeworICB0eXBlZGVmIGNoYXIgSGFzTWVyZ2U7CisgIHR5cGVkZWYgbG9uZyBIYXNOb01lcmdlOworCisgIC8vIFdlIGFjY2VwdCBlaXRoZXIgb2Y6CisgIC8vIC0gdm9pZCBNZXJnZUZyb20oY29uc3QgVCYgb3RoZXIpCisgIC8vIC0gYm9vbCBNZXJnZUZyb20oY29uc3QgVCYgb3RoZXIpCisgIC8vCisgIC8vIFdlIG1hbmdsZSB0aGVzZSBuYW1lcyBhIGJpdCB0byBhdm9pZCBjb21wYXRpYmlsaXR5IGlzc3VlcyBpbiAndW5jbGVhbicKKyAgLy8gaW5jbHVkZSBlbnZpcm9ubWVudHMgdGhhdCBtYXkgaGF2ZSwgZS5nLiwgIiNkZWZpbmUgdGVzdCAuLi4iICh5ZXMsIHRoaXMKKyAgLy8gZXhpc3RzKS4KKyAgdGVtcGxhdGU8dHlwZW5hbWUgVSwgdHlwZW5hbWUgUmV0VHlwZSwgUmV0VHlwZSAoVTo6KikoY29uc3QgVSYgYXJnKT4KKyAgICAgIHN0cnVjdCBDaGVja1R5cGU7CisgIHRlbXBsYXRlPHR5cGVuYW1lIFU+IHN0YXRpYyBIYXNNZXJnZSBDaGVjaygKKyAgICAgIENoZWNrVHlwZTxVLCB2b2lkLCAmVTo6TWVyZ2VGcm9tPiopOworICB0ZW1wbGF0ZTx0eXBlbmFtZSBVPiBzdGF0aWMgSGFzTWVyZ2UgQ2hlY2soCisgICAgICBDaGVja1R5cGU8VSwgYm9vbCwgJlU6Ok1lcmdlRnJvbT4qKTsKKyAgdGVtcGxhdGU8dHlwZW5hbWUgVT4gc3RhdGljIEhhc05vTWVyZ2UgQ2hlY2soLi4uKTsKKworICAvLyBSZXNvdmxlcyB0byBlaXRoZXIgZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OnRydWVfdHlwZSBvciBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6ZmFsc2VfdHlwZS4KKyAgdHlwZWRlZiBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6aW50ZWdyYWxfY29uc3RhbnQ8Ym9vbCwKKyAgICAgICAgICAgICAgIChzaXplb2YoQ2hlY2s8VD4oMCkpID09IHNpemVvZihIYXNNZXJnZSkpPiB0eXBlOworfTsKKwordGVtcGxhdGU8Pgorc3RydWN0IFR5cGVJbXBsZW1lbnRzTWVyZ2VCZWhhdmlvcjwgOjpzdGQ6OnN0cmluZyA+IHsKKyAgdHlwZWRlZiBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6dHJ1ZV90eXBlIHR5cGU7Cit9OworCisvLyBUaGlzIGlzIHRoZSBjb21tb24gYmFzZSBjbGFzcyBmb3IgUmVwZWF0ZWRQdHJGaWVsZHMuICBJdCBkZWFscyBvbmx5IGluIHZvaWQqCisvLyBwb2ludGVycy4gIFVzZXJzIHNob3VsZCBub3QgdXNlIHRoaXMgaW50ZXJmYWNlIGRpcmVjdGx5LgorLy8KKy8vIFRoZSBtZXRob2RzIG9mIHRoaXMgaW50ZXJmYWNlIGNvcnJlc3BvbmQgdG8gdGhlIG1ldGhvZHMgb2YgUmVwZWF0ZWRQdHJGaWVsZCwKKy8vIGJ1dCBtYXkgaGF2ZSBhIHRlbXBsYXRlIGFyZ3VtZW50IGNhbGxlZCBUeXBlSGFuZGxlci4gIEl0cyBzaWduYXR1cmUgaXM6CisvLyAgIGNsYXNzIFR5cGVIYW5kbGVyIHsKKy8vICAgIHB1YmxpYzoKKy8vICAgICB0eXBlZGVmIE15VHlwZSBUeXBlOworLy8gICAgIHN0YXRpYyBUeXBlKiBOZXcoKTsKKy8vICAgICBzdGF0aWMgdm9pZCBEZWxldGUoVHlwZSopOworLy8gICAgIHN0YXRpYyB2b2lkIENsZWFyKFR5cGUqKTsKKy8vICAgICBzdGF0aWMgdm9pZCBNZXJnZShjb25zdCBUeXBlJiBmcm9tLCBUeXBlKiB0byk7CisvLworLy8gICAgIC8vIE9ubHkgbmVlZHMgdG8gYmUgaW1wbGVtZW50ZWQgaWYgU3BhY2VVc2VkRXhjbHVkaW5nU2VsZigpIGlzIGNhbGxlZC4KKy8vICAgICBzdGF0aWMgaW50IFNwYWNlVXNlZChjb25zdCBUeXBlJik7CisvLyAgIH07CitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgUmVwZWF0ZWRQdHJGaWVsZEJhc2UgeworIHByb3RlY3RlZDoKKyAgLy8gVGhlIHJlZmxlY3Rpb24gaW1wbGVtZW50YXRpb24gbmVlZHMgdG8gY2FsbCBwcm90ZWN0ZWQgbWV0aG9kcyBkaXJlY3RseSwKKyAgLy8gcmVpbnRlcnByZXRpbmcgcG9pbnRlcnMgYXMgYmVpbmcgdG8gTWVzc2FnZSBpbnN0ZWFkIG9mIGEgc3BlY2lmaWMgTWVzc2FnZQorICAvLyBzdWJjbGFzcy4KKyAgZnJpZW5kIGNsYXNzIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOworCisgIC8vIEV4dGVuc2lvblNldCBzdG9yZXMgcmVwZWF0ZWQgbWVzc2FnZSBleHRlbnNpb25zIGFzCisgIC8vIFJlcGVhdGVkUHRyRmllbGQ8TWVzc2FnZUxpdGU+LCBidXQgbm9uLWxpdGUgRXh0ZW5zaW9uU2V0cyBuZWVkIHRvCisgIC8vIGltcGxlbWVudCBTcGFjZVVzZWQoKSwgYW5kIHRodXMgbmVlZCB0byBjYWxsIFNwYWNlVXNlZEV4Y2x1ZGluZ1NlbGYoKQorICAvLyByZWludGVycHJldGluZyBNZXNzYWdlTGl0ZSBhcyBNZXNzYWdlLiAgRXh0ZW5zaW9uU2V0IGFsc28gbmVlZHMgdG8gbWFrZQorICAvLyB1c2Ugb2YgQWRkRnJvbUNsZWFyZWQoKSwgd2hpY2ggaXMgbm90IHBhcnQgb2YgdGhlIHB1YmxpYyBpbnRlcmZhY2UuCisgIGZyaWVuZCBjbGFzcyBFeHRlbnNpb25TZXQ7CisKKyAgLy8gVGhlIE1hcEZpZWxkQmFzZSBpbXBsZW1lbnRhdGlvbiBuZWVkcyB0byBjYWxsIHByb3RlY3RlZCBtZXRob2RzIGRpcmVjdGx5LAorICAvLyByZWludGVycHJldGluZyBwb2ludGVycyBhcyBiZWluZyB0byBNZXNzYWdlIGluc3RlYWQgb2YgYSBzcGVjaWZpYyBNZXNzYWdlCisgIC8vIHN1YmNsYXNzLgorICBmcmllbmQgY2xhc3MgTWFwRmllbGRCYXNlOworCisgIC8vIFRvIHBhcnNlIGRpcmVjdGx5IGludG8gYSBwcm90bzIgZ2VuZXJhdGVkIGNsYXNzLCB0aGUgdXBiIGNsYXNzIEdNUl9IYW5kbGVycworICAvLyBuZWVkcyB0byBiZSBhYmxlIHRvIG1vZGlmeSBhIFJlcGVhdGVkUHRyRmllbGRCYXNlIGRpcmVjdGx5LgorICBmcmllbmQgY2xhc3MgdXBiOjpnb29nbGVfb3BlbnNvdXJjZTo6R01SX0hhbmRsZXJzOworCisgIFJlcGVhdGVkUHRyRmllbGRCYXNlKCk7CisgIGV4cGxpY2l0IFJlcGVhdGVkUHRyRmllbGRCYXNlKDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKTsKKyAgflJlcGVhdGVkUHRyRmllbGRCYXNlKCkge30KKworICAvLyBNdXN0IGJlIGNhbGxlZCBmcm9tIGRlc3RydWN0b3IuCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUeXBlSGFuZGxlcj4KKyAgdm9pZCBEZXN0cm95KCk7CisKKyAgYm9vbCBlbXB0eSgpIGNvbnN0OworICBpbnQgc2l6ZSgpIGNvbnN0OworCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUeXBlSGFuZGxlcj4KKyAgY29uc3QgdHlwZW5hbWUgVHlwZUhhbmRsZXI6OlR5cGUmIEdldChpbnQgaW5kZXgpIGNvbnN0OworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+CisgIHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKiBNdXRhYmxlKGludCBpbmRleCk7CisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUeXBlSGFuZGxlcj4KKyAgdm9pZCBEZWxldGUoaW50IGluZGV4KTsKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGVIYW5kbGVyPgorICB0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZSogQWRkKHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKiBwcm90b3R5cGUgPSBOVUxMKTsKKworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+CisgIHZvaWQgUmVtb3ZlTGFzdCgpOworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+CisgIHZvaWQgQ2xlYXIoKTsKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGVIYW5kbGVyPgorICB2b2lkIE1lcmdlRnJvbShjb25zdCBSZXBlYXRlZFB0ckZpZWxkQmFzZSYgb3RoZXIpOworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+CisgIHZvaWQgQ29weUZyb20oY29uc3QgUmVwZWF0ZWRQdHJGaWVsZEJhc2UmIG90aGVyKTsKKworICB2b2lkIENsb3NlR2FwKGludCBzdGFydCwgaW50IG51bSk7CisKKyAgdm9pZCBSZXNlcnZlKGludCBuZXdfc2l6ZSk7CisKKyAgaW50IENhcGFjaXR5KCkgY29uc3Q7CisKKyAgLy8gVXNlZCBmb3IgY29uc3RydWN0aW5nIGl0ZXJhdG9ycy4KKyAgdm9pZCogY29uc3QqIHJhd19kYXRhKCkgY29uc3Q7CisgIHZvaWQqKiByYXdfbXV0YWJsZV9kYXRhKCkgY29uc3Q7CisKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGVIYW5kbGVyPgorICB0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZSoqIG11dGFibGVfZGF0YSgpOworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+CisgIGNvbnN0IHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKiBjb25zdCogZGF0YSgpIGNvbnN0OworCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUeXBlSGFuZGxlcj4KKyAgR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FIHZvaWQgU3dhcChSZXBlYXRlZFB0ckZpZWxkQmFzZSogb3RoZXIpOworCisgIHZvaWQgU3dhcEVsZW1lbnRzKGludCBpbmRleDEsIGludCBpbmRleDIpOworCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUeXBlSGFuZGxlcj4KKyAgaW50IFNwYWNlVXNlZEV4Y2x1ZGluZ1NlbGYoKSBjb25zdDsKKworCisgIC8vIEFkdmFuY2VkIG1lbW9yeSBtYW5hZ2VtZW50IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gTGlrZSBBZGQoKSwgYnV0IGlmIHRoZXJlIGFyZSBubyBjbGVhcmVkIG9iamVjdHMgdG8gdXNlLCByZXR1cm5zIE5VTEwuCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUeXBlSGFuZGxlcj4KKyAgdHlwZW5hbWUgVHlwZUhhbmRsZXI6OlR5cGUqIEFkZEZyb21DbGVhcmVkKCk7CisKKyAgdGVtcGxhdGU8dHlwZW5hbWUgVHlwZUhhbmRsZXI+CisgIHZvaWQgQWRkQWxsb2NhdGVkKHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKiB2YWx1ZSkgeworICAgIHR5cGVuYW1lIFR5cGVJbXBsZW1lbnRzTWVyZ2VCZWhhdmlvcjx0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZT46OnR5cGUgdDsKKyAgICBBZGRBbGxvY2F0ZWRJbnRlcm5hbDxUeXBlSGFuZGxlcj4odmFsdWUsIHQpOworICB9CisKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGVIYW5kbGVyPgorICB2b2lkIFVuc2FmZUFyZW5hQWRkQWxsb2NhdGVkKHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKiB2YWx1ZSk7CisKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGVIYW5kbGVyPgorICB0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZSogUmVsZWFzZUxhc3QoKSB7CisgICAgdHlwZW5hbWUgVHlwZUltcGxlbWVudHNNZXJnZUJlaGF2aW9yPHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlPjo6dHlwZSB0OworICAgIHJldHVybiBSZWxlYXNlTGFzdEludGVybmFsPFR5cGVIYW5kbGVyPih0KTsKKyAgfQorCisgIC8vIFJlbGVhc2VzIGxhc3QgZWxlbWVudCBhbmQgcmV0dXJucyBpdCwgYnV0IGRvZXMgbm90IGRvIG91dC1vZi1hcmVuYSBjb3B5LgorICAvLyBBbmQganVzdCByZXR1cm5zIHRoZSByYXcgcG9pbnRlciB0byB0aGUgY29udGFpbmVkIGVsZW1lbnQgaW4gdGhlIGFyZW5hLgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+CisgIHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKiBVbnNhZmVBcmVuYVJlbGVhc2VMYXN0KCk7CisKKyAgaW50IENsZWFyZWRDb3VudCgpIGNvbnN0OworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+CisgIHZvaWQgQWRkQ2xlYXJlZCh0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZSogdmFsdWUpOworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+CisgIHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKiBSZWxlYXNlQ2xlYXJlZCgpOworCisgcHJvdGVjdGVkOgorICBpbmxpbmUgdm9pZCBJbnRlcm5hbFN3YXAoUmVwZWF0ZWRQdHJGaWVsZEJhc2UqIG90aGVyKTsKKworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+CisgIHZvaWQgQWRkQWxsb2NhdGVkSW50ZXJuYWwodHlwZW5hbWUgVHlwZUhhbmRsZXI6OlR5cGUqIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjp0cnVlX3R5cGUpOworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+CisgIHZvaWQgQWRkQWxsb2NhdGVkSW50ZXJuYWwodHlwZW5hbWUgVHlwZUhhbmRsZXI6OlR5cGUqIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpmYWxzZV90eXBlKTsKKworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+IEdPT0dMRV9BVFRSSUJVVEVfTk9JTkxJTkUKKyAgdm9pZCBBZGRBbGxvY2F0ZWRTbG93V2l0aENvcHkodHlwZW5hbWUgVHlwZUhhbmRsZXI6OlR5cGUqIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBcmVuYSogdmFsdWVfYXJlbmEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFyZW5hKiBteV9hcmVuYSk7CisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUeXBlSGFuZGxlcj4gR09PR0xFX0FUVFJJQlVURV9OT0lOTElORQorICB2b2lkIEFkZEFsbG9jYXRlZFNsb3dXaXRob3V0Q29weSh0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZSogdmFsdWUpOworCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUeXBlSGFuZGxlcj4KKyAgdHlwZW5hbWUgVHlwZUhhbmRsZXI6OlR5cGUqIFJlbGVhc2VMYXN0SW50ZXJuYWwoZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OnRydWVfdHlwZSk7CisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUeXBlSGFuZGxlcj4KKyAgdHlwZW5hbWUgVHlwZUhhbmRsZXI6OlR5cGUqIFJlbGVhc2VMYXN0SW50ZXJuYWwoZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OmZhbHNlX3R5cGUpOworCisgIHRlbXBsYXRlPHR5cGVuYW1lIFR5cGVIYW5kbGVyPiBHT09HTEVfQVRUUklCVVRFX05PSU5MSU5FCisgIHZvaWQgU3dhcEZhbGxiYWNrKFJlcGVhdGVkUHRyRmllbGRCYXNlKiBvdGhlcik7CisKKyAgaW5saW5lIEFyZW5hKiBHZXRBcmVuYU5vVmlydHVhbCgpIGNvbnN0IHsKKyAgICByZXR1cm4gYXJlbmFfOworICB9CisKKyBwcml2YXRlOgorICBzdGF0aWMgY29uc3QgaW50IGtJbml0aWFsU2l6ZSA9IDA7CisgIC8vIEEgZmV3IG5vdGVzIG9uIGludGVybmFsIHJlcHJlc2VudGF0aW9uOgorICAvLworICAvLyBXZSB1c2UgYW4gaW5kaXJlY3RlZCBhcHByb2FjaCwgd2l0aCBzdHJ1Y3QgUmVwLCB0byBrZWVwCisgIC8vIHNpemVvZihSZXBlYXRlZFB0ckZpZWxkQmFzZSkgZXF1aXZhbGVudCB0byB3aGF0IGl0IHdhcyBiZWZvcmUgYXJlbmEgc3VwcG9ydAorICAvLyB3YXMgYWRkZWQsIG5hbWVseSwgMyA4LWJ5dGUgbWFjaGluZSB3b3JkcyBvbiB4ODYtNjQuIEFuIGluc3RhbmNlIG9mIFJlcCBpcworICAvLyBhbGxvY2F0ZWQgb25seSB3aGVuIHRoZSByZXBlYXRlZCBmaWVsZCBpcyBub24tZW1wdHksIGFuZCBpdCBpcyBhCisgIC8vIGR5bmFtaWNhbGx5LXNpemVkIHN0cnVjdCAodGhlIGhlYWRlciBpcyBkaXJlY3RseSBmb2xsb3dlZCBieSBlbGVtZW50c1tdKS4KKyAgLy8gV2UgcGxhY2UgYXJlbmFfIGFuZCBjdXJyZW50X3NpemVfIGRpcmVjdGx5IGluIHRoZSBvYmplY3QgdG8gYXZvaWQgY2FjaGUKKyAgLy8gbWlzc2VzIGR1ZSB0byB0aGUgaW5kaXJlY3Rpb24sIGJlY2F1c2UgdGhlc2UgZmllbGRzIGFyZSBjaGVja2VkIGZyZXF1ZW50bHkuCisgIC8vIFBsYWNpbmcgYWxsIGZpZWxkcyBkaXJlY3RseSBpbiB0aGUgUmVwZWF0ZWRQdHJGaWVsZEJhc2UgaW5zdGFuY2UgY29zdHMKKyAgLy8gc2lnbmlmaWNhbnQgcGVyZm9ybWFuY2UgZm9yIG1lbW9yeS1zZW5zaXRpdmUgd29ya2xvYWRzLgorICBBcmVuYSogYXJlbmFfOworICBpbnQgICAgY3VycmVudF9zaXplXzsKKyAgaW50ICAgIHRvdGFsX3NpemVfOworICBzdHJ1Y3QgUmVwIHsKKyAgICBpbnQgICAgYWxsb2NhdGVkX3NpemU7CisgICAgdm9pZCogIGVsZW1lbnRzWzFdOworICB9OworICBzdGF0aWMgY29uc3Qgc2l6ZV90IGtSZXBIZWFkZXJTaXplID0gc2l6ZW9mKFJlcCkgLSBzaXplb2Yodm9pZCopOworICAvLyBDb250YWlucyBhcmVuYSBwdHIgYW5kIHRoZSBlbGVtZW50cyBhcnJheS4gV2UgYWxzbyBrZWVwIHRoZSBpbnZhcmlhbnQgdGhhdAorICAvLyBpZiByZXBfIGlzIE5VTEwsIHRoZW4gYXJlbmEgaXMgTlVMTC4KKyAgUmVwKiByZXBfOworCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUeXBlSGFuZGxlcj4KKyAgc3RhdGljIGlubGluZSB0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZSogY2FzdCh2b2lkKiBlbGVtZW50KSB7CisgICAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8dHlwZW5hbWUgVHlwZUhhbmRsZXI6OlR5cGUqPihlbGVtZW50KTsKKyAgfQorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+CisgIHN0YXRpYyBpbmxpbmUgY29uc3QgdHlwZW5hbWUgVHlwZUhhbmRsZXI6OlR5cGUqIGNhc3QoY29uc3Qgdm9pZCogZWxlbWVudCkgeworICAgIHJldHVybiByZWludGVycHJldF9jYXN0PGNvbnN0IHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKj4oZWxlbWVudCk7CisgIH0KKworICAvLyBOb24tdGVtcGxhdGVkIGlubmVyIGZ1bmN0aW9uIHRvIGF2b2lkIGNvZGUgZHVwbGljYXRpb24uIFRha2VzIGEgZnVuY3Rpb24KKyAgLy8gcG9pbnRlciB0byB0aGUgdHlwZS1zcGVjaWZpYyAodGVtcGxhdGVkKSBpbm5lciBhbGxvY2F0ZS9tZXJnZSBsb29wLgorICB2b2lkIE1lcmdlRnJvbUludGVybmFsKAorICAgICAgY29uc3QgUmVwZWF0ZWRQdHJGaWVsZEJhc2UmIG90aGVyLAorICAgICAgdm9pZCAoUmVwZWF0ZWRQdHJGaWVsZEJhc2U6Oippbm5lcl9sb29wKSh2b2lkKiosIHZvaWQqKiwgaW50LCBpbnQpKTsKKworICB0ZW1wbGF0ZTx0eXBlbmFtZSBUeXBlSGFuZGxlcj4KKyAgdm9pZCBNZXJnZUZyb21Jbm5lckxvb3AoCisgICAgICB2b2lkKiogb3VyX2VsZW1zLCB2b2lkKiogb3RoZXJfZWxlbXMsIGludCBsZW5ndGgsIGludCBhbHJlYWR5X2FsbG9jYXRlZCk7CisKKyAgLy8gSW50ZXJuYWwgaGVscGVyOiBleHRlbmQgYXJyYXkgc3BhY2UgaWYgbmVjZXNzYXJ5IHRvIGNvbnRhaW4gfGV4dGVuZF9hbW91bnR8CisgIC8vIG1vcmUgZWxlbWVudHMsIGFuZCByZXR1cm4gYSBwb2ludGVyIHRvIHRoZSBlbGVtZW50IGltbWVkaWF0ZWx5IGZvbGxvd2luZworICAvLyB0aGUgb2xkIGxpc3Qgb2YgZWxlbWVudHMuICBUaGlzIGludGVyZmFjZSBmYWN0b3JzIG91dCBjb21tb24gYmVoYXZpb3IgZnJvbQorICAvLyBSZXNlcnZlKCkgYW5kIE1lcmdlRnJvbSgpIHRvIHJlZHVjZSBjb2RlIHNpemUuIHxleHRlbmRfYW1vdW50fCBtdXN0IGJlID4gMC4KKyAgdm9pZCoqIEludGVybmFsRXh0ZW5kKGludCBleHRlbmRfYW1vdW50KTsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoUmVwZWF0ZWRQdHJGaWVsZEJhc2UpOworfTsKKwordGVtcGxhdGUgPHR5cGVuYW1lIEdlbmVyaWNUeXBlPgorY2xhc3MgR2VuZXJpY1R5cGVIYW5kbGVyIHsKKyBwdWJsaWM6CisgIHR5cGVkZWYgR2VuZXJpY1R5cGUgVHlwZTsKKyAgc3RhdGljIGlubGluZSBHZW5lcmljVHlwZSogTmV3KEFyZW5hKiBhcmVuYSkgeworICAgIHJldHVybiA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hOjpDcmVhdGVNYXliZU1lc3NhZ2U8VHlwZT4oCisgICAgICAgIGFyZW5hLCBzdGF0aWNfY2FzdDxHZW5lcmljVHlwZSo+KDApKTsKKyAgfQorICAvLyBXZSBmb3JjZSBOZXdGcm9tUHJvdG90eXBlKCkgYW5kIERlbGV0ZSgpIHRvIGJlIG5vbi1pbmxpbmUgdG8gcmVkdWNlIGNvZGUKKyAgLy8gc2l6ZTogZWxzZSwgc2V2ZXJhbCBvdGhlciBtZXRob2RzIGdldCBpbmxpbmVkIGNvcGllcyBvZiBtZXNzYWdlIHR5cGVzJworICAvLyBjb25zdHJ1Y3RvcnMgYW5kIGRlc3RydWN0b3JzLgorICBHT09HTEVfQVRUUklCVVRFX05PSU5MSU5FIHN0YXRpYyBHZW5lcmljVHlwZSogTmV3RnJvbVByb3RvdHlwZSgKKyAgICAgIGNvbnN0IEdlbmVyaWNUeXBlKiBwcm90b3R5cGUsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hID0gTlVMTCk7CisgIEdPT0dMRV9BVFRSSUJVVEVfTk9JTkxJTkUgc3RhdGljIHZvaWQgRGVsZXRlKEdlbmVyaWNUeXBlKiB2YWx1ZSwgQXJlbmEqIGFyZW5hKTsKKyAgc3RhdGljIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYShHZW5lcmljVHlwZSogdmFsdWUpIHsKKyAgICByZXR1cm4gOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYTo6R2V0QXJlbmE8VHlwZT4odmFsdWUpOworICB9CisgIHN0YXRpYyBpbmxpbmUgdm9pZCogR2V0TWF5YmVBcmVuYVBvaW50ZXIoR2VuZXJpY1R5cGUqIHZhbHVlKSB7CisgICAgcmV0dXJuIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmE6OkdldEFyZW5hPFR5cGU+KHZhbHVlKTsKKyAgfQorCisgIHN0YXRpYyBpbmxpbmUgdm9pZCBDbGVhcihHZW5lcmljVHlwZSogdmFsdWUpIHsgdmFsdWUtPkNsZWFyKCk7IH0KKyAgR09PR0xFX0FUVFJJQlVURV9OT0lOTElORSBzdGF0aWMgdm9pZCBNZXJnZShjb25zdCBHZW5lcmljVHlwZSYgZnJvbSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdlbmVyaWNUeXBlKiB0byk7CisgIHN0YXRpYyBpbmxpbmUgaW50IFNwYWNlVXNlZChjb25zdCBHZW5lcmljVHlwZSYgdmFsdWUpIHsKKyAgICByZXR1cm4gdmFsdWUuU3BhY2VVc2VkKCk7CisgIH0KKyAgc3RhdGljIGlubGluZSBjb25zdCBUeXBlJiBkZWZhdWx0X2luc3RhbmNlKCkgeworICAgIHJldHVybiBUeXBlOjpkZWZhdWx0X2luc3RhbmNlKCk7CisgIH0KK307CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBHZW5lcmljVHlwZT4KK0dlbmVyaWNUeXBlKiBHZW5lcmljVHlwZUhhbmRsZXI8R2VuZXJpY1R5cGU+OjpOZXdGcm9tUHJvdG90eXBlKAorICAgIGNvbnN0IEdlbmVyaWNUeXBlKiAvKiBwcm90b3R5cGUgKi8sIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSB7CisgIHJldHVybiBOZXcoYXJlbmEpOworfQordGVtcGxhdGUgPHR5cGVuYW1lIEdlbmVyaWNUeXBlPgordm9pZCBHZW5lcmljVHlwZUhhbmRsZXI8R2VuZXJpY1R5cGU+OjpEZWxldGUoR2VuZXJpY1R5cGUqIHZhbHVlLCBBcmVuYSogYXJlbmEpIHsKKyAgaWYgKGFyZW5hID09IE5VTEwpIHsKKyAgICBkZWxldGUgdmFsdWU7CisgIH0KK30KK3RlbXBsYXRlIDx0eXBlbmFtZSBHZW5lcmljVHlwZT4KK3ZvaWQgR2VuZXJpY1R5cGVIYW5kbGVyPEdlbmVyaWNUeXBlPjo6TWVyZ2UoY29uc3QgR2VuZXJpY1R5cGUmIGZyb20sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdlbmVyaWNUeXBlKiB0bykgeworICB0by0+TWVyZ2VGcm9tKGZyb20pOworfQorCisvLyBOZXdGcm9tUHJvdG90eXBlKCkgYW5kIE1lcmdlKCkgY2Fubm90IGJlIGRlZmluZWQgaGVyZTsgaWYgdGhleSdyZSBkZWNsYXJlZAorLy8gaW5saW5lIHRoZSBjb21waWxlciB3aWxsIGNvbXBsYWluIGFib3V0IG5vdCBtYXRjaGluZyBHT09HTEVfQVRUUklCVVRFX05PSU5MSU5FCisvLyBhYm92ZSwgYW5kIGlmIG5vdCwgY29tcGlsYXRpb24gd2lsbCByZXN1bHQgaW4gbXVsdGlwbGUgZGVmaW5pdGlvbnMuICBUaGVzZQorLy8gYXJlIHRoZXJlZm9yZSBkZWNsYXJlZCBhcyBzcGVjaWFsaXphdGlvbnMgaGVyZSBhbmQgZGVmaW5lZCBpbgorLy8gbWVzc2FnZV9saXRlLmNjLgordGVtcGxhdGU8PgorTWVzc2FnZUxpdGUqIEdlbmVyaWNUeXBlSGFuZGxlcjxNZXNzYWdlTGl0ZT46Ok5ld0Zyb21Qcm90b3R5cGUoCisgICAgY29uc3QgTWVzc2FnZUxpdGUqIHByb3RvdHlwZSwgZ29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKTsKK3RlbXBsYXRlPD4KK2lubGluZSBnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogR2VuZXJpY1R5cGVIYW5kbGVyPE1lc3NhZ2VMaXRlPjo6R2V0QXJlbmEoCisgICAgTWVzc2FnZUxpdGUqIHZhbHVlKSB7CisgIHJldHVybiB2YWx1ZS0+R2V0QXJlbmEoKTsKK30KK3RlbXBsYXRlPD4KK2lubGluZSB2b2lkKiBHZW5lcmljVHlwZUhhbmRsZXI8TWVzc2FnZUxpdGU+OjpHZXRNYXliZUFyZW5hUG9pbnRlcigKKyAgICBNZXNzYWdlTGl0ZSogdmFsdWUpIHsKKyAgcmV0dXJuIHZhbHVlLT5HZXRNYXliZUFyZW5hUG9pbnRlcigpOworfQordGVtcGxhdGUgPD4KK3ZvaWQgR2VuZXJpY1R5cGVIYW5kbGVyPE1lc3NhZ2VMaXRlPjo6TWVyZ2UoY29uc3QgTWVzc2FnZUxpdGUmIGZyb20sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VMaXRlKiB0byk7CisKKy8vIERlY2xhcmF0aW9ucyBvZiB0aGUgc3BlY2lhbGl6YXRpb24gYXMgd2UgY2Fubm90IGRlZmluZSB0aGVtIGhlcmUsIGFzIHRoZQorLy8gaGVhZGVyIHRoYXQgZGVmaW5lcyBQcm90b2NvbE1lc3NhZ2UgZGVwZW5kcyBvbiB0eXBlcyBkZWZpbmVkIGluIHRoaXMgaGVhZGVyLgorI2RlZmluZSBERUNMQVJFX1NQRUNJQUxJWkFUSU9OU19GT1JfQkFTRV9QUk9UT19UWVBFUyhUeXBlTmFtZSkgICAgICAgICAgICAgICAgIFwKKyAgICB0ZW1wbGF0ZTw+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgVHlwZU5hbWUqIEdlbmVyaWNUeXBlSGFuZGxlcjxUeXBlTmFtZT46Ok5ld0Zyb21Qcm90b3R5cGUoICAgICAgICAgICAgICAgICAgXAorICAgICAgICBjb25zdCBUeXBlTmFtZSogcHJvdG90eXBlLCBnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpOyAgICAgICAgICAgICAgICAgICAgICBcCisgICAgdGVtcGxhdGU8PiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZW5lcmljVHlwZUhhbmRsZXI8VHlwZU5hbWU+OjpHZXRBcmVuYSggICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIFR5cGVOYW1lKiB2YWx1ZSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIHRlbXBsYXRlPD4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICB2b2lkKiBHZW5lcmljVHlwZUhhbmRsZXI8VHlwZU5hbWU+OjpHZXRNYXliZUFyZW5hUG9pbnRlciggICAgICAgICAgICAgICAgICBcCisgICAgICAgIFR5cGVOYW1lKiB2YWx1ZSk7CisKKy8vIE1lc3NhZ2Ugc3BlY2lhbGl6YXRpb24gYm9kaWVzIGRlZmluZWQgaW4gbWVzc2FnZS5jYy4gVGhpcyBzcGxpdCBpcyBuZWNlc3NhcnkKKy8vIHRvIGFsbG93IHByb3RvMi1saXRlICh3aGljaCBpbmNsdWRlcyB0aGlzIGhlYWRlcikgdG8gYmUgaW5kZXBlbmRlbnQgb2YKKy8vIE1lc3NhZ2UuCitERUNMQVJFX1NQRUNJQUxJWkFUSU9OU19GT1JfQkFTRV9QUk9UT19UWVBFUyhNZXNzYWdlKQorCisKKyN1bmRlZiBERUNMQVJFX1NQRUNJQUxJWkFUSU9OU19GT1JfQkFTRV9QUk9UT19UWVBFUworCit0ZW1wbGF0ZSA8PgoraW5saW5lIGNvbnN0IE1lc3NhZ2VMaXRlJiBHZW5lcmljVHlwZUhhbmRsZXI8TWVzc2FnZUxpdGU+OjpkZWZhdWx0X2luc3RhbmNlKCkgeworICAvLyBZZXMsIHRoZSBiZWhhdmlvciBvZiB0aGUgY29kZSBpcyB1bmRlZmluZWQsIGJ1dCB0aGlzIGZ1bmN0aW9uIGlzIG9ubHkKKyAgLy8gY2FsbGVkIHdoZW4gd2UncmUgYWxyZWFkeSBkZWVwIGludG8gdGhlIHdvcmxkIG9mIHVuZGVmaW5lZCwgYmVjYXVzZSB0aGUKKyAgLy8gY2FsbGVyIGNhbGxlZCBHZXQoaW5kZXgpIG91dCBvZiBib3VuZHMuCisgIE1lc3NhZ2VMaXRlKiBudWxsID0gTlVMTDsKKyAgcmV0dXJuICpudWxsOworfQorCit0ZW1wbGF0ZSA8PgoraW5saW5lIGNvbnN0IE1lc3NhZ2UmIEdlbmVyaWNUeXBlSGFuZGxlcjxNZXNzYWdlPjo6ZGVmYXVsdF9pbnN0YW5jZSgpIHsKKyAgLy8gWWVzLCB0aGUgYmVoYXZpb3Igb2YgdGhlIGNvZGUgaXMgdW5kZWZpbmVkLCBidXQgdGhpcyBmdW5jdGlvbiBpcyBvbmx5CisgIC8vIGNhbGxlZCB3aGVuIHdlJ3JlIGFscmVhZHkgZGVlcCBpbnRvIHRoZSB3b3JsZCBvZiB1bmRlZmluZWQsIGJlY2F1c2UgdGhlCisgIC8vIGNhbGxlciBjYWxsZWQgR2V0KGluZGV4KSBvdXQgb2YgYm91bmRzLgorICBNZXNzYWdlKiBudWxsID0gTlVMTDsKKyAgcmV0dXJuICpudWxsOworfQorCisKKy8vIEhBQ0s6ICBJZiBhIGNsYXNzIGlzIGRlY2xhcmVkIGFzIERMTC1leHBvcnRlZCBpbiBNU1ZDLCBpdCBpbnNpc3RzIG9uCisvLyAgIGdlbmVyYXRpbmcgY29waWVzIG9mIGFsbCBpdHMgbWV0aG9kcyAtLSBldmVuIGlubGluZSBvbmVzIC0tIHRvIGluY2x1ZGUKKy8vICAgaW4gdGhlIERMTC4gIEJ1dCBTcGFjZVVzZWQoKSBjYWxscyBTdHJpbmdTcGFjZVVzZWRFeGNsdWRpbmdTZWxmKCkgd2hpY2gKKy8vICAgaXNuJ3QgaW4gdGhlIGxpdGUgbGlicmFyeSwgdGhlcmVmb3JlIHRoZSBsaXRlIGxpYnJhcnkgY2Fubm90IGxpbmsgaWYKKy8vICAgU3RyaW5nVHlwZUhhbmRsZXIgaXMgZXhwb3J0ZWQuICBTbywgd2UgZmFjdG9yIG91dCBTdHJpbmdUeXBlSGFuZGxlckJhc2UsCisvLyAgIGV4cG9ydCB0aGF0LCB0aGVuIG1ha2UgU3RyaW5nVHlwZUhhbmRsZXIgYmUgYSBzdWJjbGFzcyB3aGljaCBpcyBOT1QKKy8vICAgZXhwb3J0ZWQuCisvLyBUT0RPKGtlbnRvbik6ICBOb3cgdGhhdCBTdHJpbmdTcGFjZVVzZWRFeGNsdWRpbmdTZWxmKCkgaXMgaW4gdGhlIGxpdGUKKy8vICAgbGlicmFyeSwgdGhpcyBjYW4gYmUgY2xlYW5lZCB1cC4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBTdHJpbmdUeXBlSGFuZGxlckJhc2UgeworIHB1YmxpYzoKKyAgdHlwZWRlZiBzdHJpbmcgVHlwZTsKKworICBzdGF0aWMgaW5saW5lIHN0cmluZyogTmV3KEFyZW5hKiBhcmVuYSkgeworICAgIHJldHVybiBBcmVuYTo6Q3JlYXRlPHN0cmluZz4oYXJlbmEpOworICB9CisgIHN0YXRpYyBpbmxpbmUgc3RyaW5nKiBOZXdGcm9tUHJvdG90eXBlKGNvbnN0IHN0cmluZyosCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSB7CisgICAgcmV0dXJuIE5ldyhhcmVuYSk7CisgIH0KKyAgc3RhdGljIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYShzdHJpbmcqKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgc3RhdGljIGlubGluZSB2b2lkKiBHZXRNYXliZUFyZW5hUG9pbnRlcihzdHJpbmcqIC8qIHZhbHVlICovKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgc3RhdGljIGlubGluZSB2b2lkIERlbGV0ZShzdHJpbmcqIHZhbHVlLCBBcmVuYSogYXJlbmEpIHsKKyAgICBpZiAoYXJlbmEgPT0gTlVMTCkgeworICAgICAgZGVsZXRlIHZhbHVlOworICAgIH0KKyAgfQorICBzdGF0aWMgaW5saW5lIHZvaWQgQ2xlYXIoc3RyaW5nKiB2YWx1ZSkgeyB2YWx1ZS0+Y2xlYXIoKTsgfQorICBzdGF0aWMgaW5saW5lIHZvaWQgTWVyZ2UoY29uc3Qgc3RyaW5nJiBmcm9tLCBzdHJpbmcqIHRvKSB7ICp0byA9IGZyb207IH0KKyAgc3RhdGljIGlubGluZSBjb25zdCBUeXBlJiBkZWZhdWx0X2luc3RhbmNlKCkgeworICAgIHJldHVybiA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZygpOworICB9Cit9OworCitjbGFzcyBTdHJpbmdUeXBlSGFuZGxlciA6IHB1YmxpYyBTdHJpbmdUeXBlSGFuZGxlckJhc2UgeworIHB1YmxpYzoKKyAgc3RhdGljIGludCBTcGFjZVVzZWQoY29uc3Qgc3RyaW5nJiB2YWx1ZSkgIHsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8aW50PihzaXplb2YodmFsdWUpKSArIFN0cmluZ1NwYWNlVXNlZEV4Y2x1ZGluZ1NlbGYodmFsdWUpOworICB9Cit9OworCisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorCisvLyBSZXBlYXRlZFB0ckZpZWxkIGlzIGxpa2UgUmVwZWF0ZWRGaWVsZCwgYnV0IHVzZWQgZm9yIHJlcGVhdGVkIHN0cmluZ3Mgb3IKKy8vIE1lc3NhZ2VzLgordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitjbGFzcyBSZXBlYXRlZFB0ckZpZWxkIDogcHVibGljIGludGVybmFsOjpSZXBlYXRlZFB0ckZpZWxkQmFzZSB7CisgcHVibGljOgorICBSZXBlYXRlZFB0ckZpZWxkKCk7CisgIGV4cGxpY2l0IFJlcGVhdGVkUHRyRmllbGQoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpOworCisgIFJlcGVhdGVkUHRyRmllbGQoY29uc3QgUmVwZWF0ZWRQdHJGaWVsZCYgb3RoZXIpOworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgSXRlcj4KKyAgUmVwZWF0ZWRQdHJGaWVsZChJdGVyIGJlZ2luLCBjb25zdCBJdGVyJiBlbmQpOworICB+UmVwZWF0ZWRQdHJGaWVsZCgpOworCisgIFJlcGVhdGVkUHRyRmllbGQmIG9wZXJhdG9yPShjb25zdCBSZXBlYXRlZFB0ckZpZWxkJiBvdGhlcik7CisKKyAgYm9vbCBlbXB0eSgpIGNvbnN0OworICBpbnQgc2l6ZSgpIGNvbnN0OworCisgIGNvbnN0IEVsZW1lbnQmIEdldChpbnQgaW5kZXgpIGNvbnN0OworICBFbGVtZW50KiBNdXRhYmxlKGludCBpbmRleCk7CisgIEVsZW1lbnQqIEFkZCgpOworCisgIC8vIFJlbW92ZSB0aGUgbGFzdCBlbGVtZW50IGluIHRoZSBhcnJheS4KKyAgLy8gT3duZXJzaGlwIG9mIHRoZSBlbGVtZW50IGlzIHJldGFpbmVkIGJ5IHRoZSBhcnJheS4KKyAgdm9pZCBSZW1vdmVMYXN0KCk7CisKKyAgLy8gRGVsZXRlIGVsZW1lbnRzIHdpdGggaW5kaWNlcyBpbiB0aGUgcmFuZ2UgW3N0YXJ0IC4uIHN0YXJ0K251bS0xXS4KKyAgLy8gQ2F1dGlvbjogaW1wbGVtZW50YXRpb24gbW92ZXMgYWxsIGVsZW1lbnRzIHdpdGggaW5kaWNlcyBbc3RhcnQrbnVtIC4uIF0uCisgIC8vIENhbGxpbmcgdGhpcyByb3V0aW5lIGluc2lkZSBhIGxvb3AgY2FuIGNhdXNlIHF1YWRyYXRpYyBiZWhhdmlvci4KKyAgdm9pZCBEZWxldGVTdWJyYW5nZShpbnQgc3RhcnQsIGludCBudW0pOworCisgIHZvaWQgQ2xlYXIoKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgUmVwZWF0ZWRQdHJGaWVsZCYgb3RoZXIpOworICB2b2lkIENvcHlGcm9tKGNvbnN0IFJlcGVhdGVkUHRyRmllbGQmIG90aGVyKTsKKworICAvLyBSZXNlcnZlIHNwYWNlIHRvIGV4cGFuZCB0aGUgZmllbGQgdG8gYXQgbGVhc3QgdGhlIGdpdmVuIHNpemUuICBUaGlzIG9ubHkKKyAgLy8gcmVzaXplcyB0aGUgcG9pbnRlciBhcnJheTsgaXQgZG9lc24ndCBhbGxvY2F0ZSBhbnkgb2JqZWN0cy4gIElmIHRoZQorICAvLyBhcnJheSBpcyBncm93biwgaXQgd2lsbCBhbHdheXMgYmUgYXQgbGVhc3QgZG91YmxlZCBpbiBzaXplLgorICB2b2lkIFJlc2VydmUoaW50IG5ld19zaXplKTsKKworICBpbnQgQ2FwYWNpdHkoKSBjb25zdDsKKworICAvLyBHZXRzIHRoZSB1bmRlcmx5aW5nIGFycmF5LiAgVGhpcyBwb2ludGVyIGlzIHBvc3NpYmx5IGludmFsaWRhdGVkIGJ5CisgIC8vIGFueSBhZGQgb3IgcmVtb3ZlIG9wZXJhdGlvbi4KKyAgRWxlbWVudCoqIG11dGFibGVfZGF0YSgpOworICBjb25zdCBFbGVtZW50KiBjb25zdCogZGF0YSgpIGNvbnN0OworCisgIC8vIFN3YXAgZW50aXJlIGNvbnRlbnRzIHdpdGggIm90aGVyIi4gSWYgdGhleSBhcmUgb24gc2VwYXJhdGUgYXJlbmFzLCB0aGVuCisgIC8vIGNvcGllcyBkYXRhLgorICB2b2lkIFN3YXAoUmVwZWF0ZWRQdHJGaWVsZCogb3RoZXIpOworCisgIC8vIFN3YXAgZW50aXJlIGNvbnRlbnRzIHdpdGggIm90aGVyIi4gQ2FsbGVyIHNob3VsZCBndWFyYW50ZWUgdGhhdCBlaXRoZXIgYm90aAorICAvLyBmaWVsZHMgYXJlIG9uIHRoZSBzYW1lIGFyZW5hIG9yIGJvdGggYXJlIG9uIHRoZSBoZWFwLiBTd2FwcGluZyBiZXR3ZWVuCisgIC8vIGRpZmZlcmVudCBhcmVuYXMgd2l0aCB0aGlzIGZ1bmN0aW9uIGlzIGRpc2FsbG93ZWQgYW5kIGlzIGNhdWdodCB2aWEKKyAgLy8gR09PR0xFX0RDSEVDSy4KKyAgdm9pZCBVbnNhZmVBcmVuYVN3YXAoUmVwZWF0ZWRQdHJGaWVsZCogb3RoZXIpOworCisgIC8vIFN3YXAgdHdvIGVsZW1lbnRzLgorICB2b2lkIFN3YXBFbGVtZW50cyhpbnQgaW5kZXgxLCBpbnQgaW5kZXgyKTsKKworICAvLyBTVEwtbGlrZSBpdGVyYXRvciBzdXBwb3J0CisgIHR5cGVkZWYgaW50ZXJuYWw6OlJlcGVhdGVkUHRySXRlcmF0b3I8RWxlbWVudD4gaXRlcmF0b3I7CisgIHR5cGVkZWYgaW50ZXJuYWw6OlJlcGVhdGVkUHRySXRlcmF0b3I8Y29uc3QgRWxlbWVudD4gY29uc3RfaXRlcmF0b3I7CisgIHR5cGVkZWYgRWxlbWVudCB2YWx1ZV90eXBlOworICB0eXBlZGVmIHZhbHVlX3R5cGUmIHJlZmVyZW5jZTsKKyAgdHlwZWRlZiBjb25zdCB2YWx1ZV90eXBlJiBjb25zdF9yZWZlcmVuY2U7CisgIHR5cGVkZWYgdmFsdWVfdHlwZSogcG9pbnRlcjsKKyAgdHlwZWRlZiBjb25zdCB2YWx1ZV90eXBlKiBjb25zdF9wb2ludGVyOworICB0eXBlZGVmIGludCBzaXplX3R5cGU7CisgIHR5cGVkZWYgcHRyZGlmZl90IGRpZmZlcmVuY2VfdHlwZTsKKworICBpdGVyYXRvciBiZWdpbigpOworICBjb25zdF9pdGVyYXRvciBiZWdpbigpIGNvbnN0OworICBjb25zdF9pdGVyYXRvciBjYmVnaW4oKSBjb25zdDsKKyAgaXRlcmF0b3IgZW5kKCk7CisgIGNvbnN0X2l0ZXJhdG9yIGVuZCgpIGNvbnN0OworICBjb25zdF9pdGVyYXRvciBjZW5kKCkgY29uc3Q7CisKKyAgLy8gUmV2ZXJzZSBpdGVyYXRvciBzdXBwb3J0CisgIHR5cGVkZWYgc3RkOjpyZXZlcnNlX2l0ZXJhdG9yPGNvbnN0X2l0ZXJhdG9yPiBjb25zdF9yZXZlcnNlX2l0ZXJhdG9yOworICB0eXBlZGVmIHN0ZDo6cmV2ZXJzZV9pdGVyYXRvcjxpdGVyYXRvcj4gcmV2ZXJzZV9pdGVyYXRvcjsKKyAgcmV2ZXJzZV9pdGVyYXRvciByYmVnaW4oKSB7CisgICAgcmV0dXJuIHJldmVyc2VfaXRlcmF0b3IoZW5kKCkpOworICB9CisgIGNvbnN0X3JldmVyc2VfaXRlcmF0b3IgcmJlZ2luKCkgY29uc3QgeworICAgIHJldHVybiBjb25zdF9yZXZlcnNlX2l0ZXJhdG9yKGVuZCgpKTsKKyAgfQorICByZXZlcnNlX2l0ZXJhdG9yIHJlbmQoKSB7CisgICAgcmV0dXJuIHJldmVyc2VfaXRlcmF0b3IoYmVnaW4oKSk7CisgIH0KKyAgY29uc3RfcmV2ZXJzZV9pdGVyYXRvciByZW5kKCkgY29uc3QgeworICAgIHJldHVybiBjb25zdF9yZXZlcnNlX2l0ZXJhdG9yKGJlZ2luKCkpOworICB9CisKKyAgLy8gQ3VzdG9tIFNUTC1saWtlIGl0ZXJhdG9yIHRoYXQgaXRlcmF0ZXMgb3ZlciBhbmQgcmV0dXJucyB0aGUgdW5kZXJseWluZworICAvLyBwb2ludGVycyB0byBFbGVtZW50IHJhdGhlciB0aGFuIEVsZW1lbnQgaXRzZWxmLgorICB0eXBlZGVmIGludGVybmFsOjpSZXBlYXRlZFB0ck92ZXJQdHJzSXRlcmF0b3I8RWxlbWVudCwgdm9pZCo+CisgIHBvaW50ZXJfaXRlcmF0b3I7CisgIHR5cGVkZWYgaW50ZXJuYWw6OlJlcGVhdGVkUHRyT3ZlclB0cnNJdGVyYXRvcjxjb25zdCBFbGVtZW50LCBjb25zdCB2b2lkKj4KKyAgY29uc3RfcG9pbnRlcl9pdGVyYXRvcjsKKyAgcG9pbnRlcl9pdGVyYXRvciBwb2ludGVyX2JlZ2luKCk7CisgIGNvbnN0X3BvaW50ZXJfaXRlcmF0b3IgcG9pbnRlcl9iZWdpbigpIGNvbnN0OworICBwb2ludGVyX2l0ZXJhdG9yIHBvaW50ZXJfZW5kKCk7CisgIGNvbnN0X3BvaW50ZXJfaXRlcmF0b3IgcG9pbnRlcl9lbmQoKSBjb25zdDsKKworICAvLyBSZXR1cm5zIChhbiBlc3RpbWF0ZSBvZikgdGhlIG51bWJlciBvZiBieXRlcyB1c2VkIGJ5IHRoZSByZXBlYXRlZCBmaWVsZCwKKyAgLy8gZXhjbHVkaW5nIHNpemVvZigqdGhpcykuCisgIGludCBTcGFjZVVzZWRFeGNsdWRpbmdTZWxmKCkgY29uc3Q7CisKKyAgLy8gQWR2YW5jZWQgbWVtb3J5IG1hbmFnZW1lbnQgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgLy8gV2hlbiBoYXJkY29yZSBtZW1vcnkgbWFuYWdlbWVudCBiZWNvbWVzIG5lY2Vzc2FyeSAtLSBhcyBpdCBzb21ldGltZXMKKyAgLy8gZG9lcyBoZXJlIGF0IEdvb2dsZSAtLSB0aGUgZm9sbG93aW5nIG1ldGhvZHMgbWF5IGJlIHVzZWZ1bC4KKworICAvLyBBZGQgYW4gYWxyZWFkeS1hbGxvY2F0ZWQgb2JqZWN0LCBwYXNzaW5nIG93bmVyc2hpcCB0byB0aGUKKyAgLy8gUmVwZWF0ZWRQdHJGaWVsZC4KKyAgLy8KKyAgLy8gTm90ZSB0aGF0IHNvbWUgc3BlY2lhbCBiZWhhdmlvciBvY2N1cnMgd2l0aCByZXNwZWN0IHRvIGFyZW5hczoKKyAgLy8KKyAgLy8gICAoaSkgaWYgdGhpcyBmaWVsZCBob2xkcyBzdWJtZXNzYWdlcywgdGhlIG5ldyBzdWJtZXNzYWdlIHdpbGwgYmUgY29waWVkIGlmCisgIC8vICAgdGhlIG9yaWdpbmFsIGlzIGluIGFuIGFyZW5hIGFuZCB0aGlzIFJlcGVhdGVkUHRyRmllbGQgaXMgZWl0aGVyIGluIGEKKyAgLy8gICBkaWZmZXJlbnQgYXJlbmEsIG9yIG9uIHRoZSBoZWFwLgorICAvLyAgIChpaSkgaWYgdGhpcyBmaWVsZCBob2xkcyBzdHJpbmdzLCB0aGUgcGFzc2VkLWluIHN0cmluZyAqbXVzdCogYmUKKyAgLy8gICBoZWFwLWFsbG9jYXRlZCwgbm90IGFyZW5hLWFsbG9jYXRlZC4gVGhlcmUgaXMgbm8gd2F5IHRvIGR5bmFtaWNhbGx5IGNoZWNrCisgIC8vICAgdGhpcyBhdCBydW50aW1lLCBzbyBVc2VyIEJld2FyZS4KKyAgdm9pZCBBZGRBbGxvY2F0ZWQoRWxlbWVudCogdmFsdWUpOworCisgIC8vIFJlbW92ZSB0aGUgbGFzdCBlbGVtZW50IGFuZCByZXR1cm4gaXQsIHBhc3Npbmcgb3duZXJzaGlwIHRvIHRoZSBjYWxsZXIuCisgIC8vIFJlcXVpcmVzOiAgc2l6ZSgpID4gMAorICAvLworICAvLyBJZiB0aGlzIFJlcGVhdGVkUHRyRmllbGQgaXMgb24gYW4gYXJlbmEsIGFuIG9iamVjdCBjb3B5IGlzIHJlcXVpcmVkIHRvIHBhc3MKKyAgLy8gb3duZXJzaGlwIGJhY2sgdG8gdGhlIHVzZXIgKGZvciBjb21wYXRpYmxlIHNlbWFudGljcykuIFVzZQorICAvLyBVbnNhZmVBcmVuYVJlbGVhc2VMYXN0KCkgaWYgdGhpcyBiZWhhdmlvciBpcyB1bmRlc2lyZWQuCisgIEVsZW1lbnQqIFJlbGVhc2VMYXN0KCk7CisKKyAgLy8gQWRkIGFuIGFscmVhZHktYWxsb2NhdGVkIG9iamVjdCwgc2tpcHBpbmcgYXJlbmEtb3duZXJzaGlwIGNoZWNrcy4gVGhlIHVzZXIKKyAgLy8gbXVzdCBndWFyYW50ZWUgdGhhdCB0aGUgZ2l2ZW4gb2JqZWN0IGlzIGluIHRoZSBzYW1lIGFyZW5hIGFzIHRoaXMKKyAgLy8gUmVwZWF0ZWRQdHJGaWVsZC4KKyAgdm9pZCBVbnNhZmVBcmVuYUFkZEFsbG9jYXRlZChFbGVtZW50KiB2YWx1ZSk7CisKKyAgLy8gUmVtb3ZlIHRoZSBsYXN0IGVsZW1lbnQgYW5kIHJldHVybiBpdC4gIFdvcmtzIG9ubHkgd2hlbiBvcGVyYXRpbmcgb24gYW4KKyAgLy8gYXJlbmEuIFRoZSByZXR1cm5lZCBwb2ludGVyIGlzIHRvIHRoZSBvcmlnaW5hbCBvYmplY3QgaW4gdGhlIGFyZW5hLCBoZW5jZQorICAvLyBoYXMgdGhlIGFyZW5hJ3MgbGlmZXRpbWUuCisgIC8vIFJlcXVpcmVzOiAgY3VycmVudF9zaXplXyA+IDAKKyAgRWxlbWVudCogVW5zYWZlQXJlbmFSZWxlYXNlTGFzdCgpOworCisgIC8vIEV4dHJhY3QgZWxlbWVudHMgd2l0aCBpbmRpY2VzIGluIHRoZSByYW5nZSAiW3N0YXJ0IC4uIHN0YXJ0K251bS0xXSIuCisgIC8vIFRoZSBjYWxsZXIgYXNzdW1lcyBvd25lcnNoaXAgb2YgdGhlIGV4dHJhY3RlZCBlbGVtZW50cyBhbmQgaXMgcmVzcG9uc2libGUKKyAgLy8gZm9yIGRlbGV0aW5nIHRoZW0gd2hlbiB0aGV5IGFyZSBubyBsb25nZXIgbmVlZGVkLgorICAvLyBJZiAiZWxlbWVudHMiIGlzIG5vbi1OVUxMLCB0aGVuIHBvaW50ZXJzIHRvIHRoZSBleHRyYWN0ZWQgZWxlbWVudHMKKyAgLy8gYXJlIHN0b3JlZCBpbiAiZWxlbWVudHNbMCAuLiBudW0tMV0iIGZvciB0aGUgY29udmVuaWVuY2Ugb2YgdGhlIGNhbGxlci4KKyAgLy8gSWYgImVsZW1lbnRzIiBpcyBOVUxMLCB0aGVuIHRoZSBjYWxsZXIgbXVzdCB1c2Ugc29tZSBvdGhlciBtZWNoYW5pc20KKyAgLy8gdG8gcGVyZm9ybSBhbnkgZnVydGhlciBvcGVyYXRpb25zIChsaWtlIGRlbGV0aW9uKSBvbiB0aGVzZSBlbGVtZW50cy4KKyAgLy8gQ2F1dGlvbjogaW1wbGVtZW50YXRpb24gYWxzbyBtb3ZlcyBlbGVtZW50cyB3aXRoIGluZGljZXMgW3N0YXJ0K251bSAuLl0uCisgIC8vIENhbGxpbmcgdGhpcyByb3V0aW5lIGluc2lkZSBhIGxvb3AgY2FuIGNhdXNlIHF1YWRyYXRpYyBiZWhhdmlvci4KKyAgLy8KKyAgLy8gTWVtb3J5IGNvcHlpbmcgYmVoYXZpb3IgaXMgaWRlbnRpY2FsIHRvIFJlbGVhc2VMYXN0KCksIGRlc2NyaWJlZCBhYm92ZTogaWYKKyAgLy8gdGhpcyBSZXBlYXRlZFB0ckZpZWxkIGlzIG9uIGFuIGFyZW5hLCBhbiBvYmplY3QgY29weSBpcyBwZXJmb3JtZWQgZm9yIGVhY2gKKyAgLy8gcmV0dXJuZWQgZWxlbWVudCwgc28gdGhhdCBhbGwgcmV0dXJuZWQgZWxlbWVudCBwb2ludGVycyBhcmUgdG8KKyAgLy8gaGVhcC1hbGxvY2F0ZWQgY29waWVzLiBJZiB0aGlzIGNvcHkgaXMgbm90IGRlc2lyZWQsIHRoZSB1c2VyIHNob3VsZCBjYWxsCisgIC8vIFVuc2FmZUFyZW5hRXh0cmFjdFN1YnJhbmdlKCkuCisgIHZvaWQgRXh0cmFjdFN1YnJhbmdlKGludCBzdGFydCwgaW50IG51bSwgRWxlbWVudCoqIGVsZW1lbnRzKTsKKworICAvLyBJZGVudGljYWwgdG8gRXh0cmFjdFN1YnJhbmdlKCkgZGVzY3JpYmVkIGFib3ZlLCBleGNlcHQgdGhhdCB3aGVuIHRoaXMKKyAgLy8gcmVwZWF0ZWQgZmllbGQgaXMgb24gYW4gYXJlbmEsIG5vIG9iamVjdCBjb3BpZXMgYXJlIHBlcmZvcm1lZC4gSW5zdGVhZCwgdGhlCisgIC8vIHJhdyBvYmplY3QgcG9pbnRlcnMgYXJlIHJldHVybmVkLiBUaHVzLCBpZiBvbiBhbiBhcmVuYSwgdGhlIHJldHVybmVkCisgIC8vIG9iamVjdHMgbXVzdCBub3QgYmUgZnJlZWQsIGJlY2F1c2UgdGhleSB3aWxsIG5vdCBiZSBoZWFwLWFsbG9jYXRlZCBvYmplY3RzLgorICB2b2lkIFVuc2FmZUFyZW5hRXh0cmFjdFN1YnJhbmdlKGludCBzdGFydCwgaW50IG51bSwgRWxlbWVudCoqIGVsZW1lbnRzKTsKKworICAvLyBXaGVuIGVsZW1lbnRzIGFyZSByZW1vdmVkIGJ5IGNhbGxzIHRvIFJlbW92ZUxhc3QoKSBvciBDbGVhcigpLCB0aGV5CisgIC8vIGFyZSBub3QgYWN0dWFsbHkgZnJlZWQuICBJbnN0ZWFkLCB0aGV5IGFyZSBjbGVhcmVkIGFuZCBrZXB0IHNvIHRoYXQKKyAgLy8gdGhleSBjYW4gYmUgcmV1c2VkIGxhdGVyLiAgVGhpcyBjYW4gc2F2ZSBsb3RzIG9mIENQVSB0aW1lIHdoZW4KKyAgLy8gcmVwZWF0ZWRseSByZXVzaW5nIGEgcHJvdG9jb2wgbWVzc2FnZSBmb3Igc2ltaWxhciBwdXJwb3Nlcy4KKyAgLy8KKyAgLy8gSGFyZGNvcmUgcHJvZ3JhbXMgbWF5IGNob29zZSB0byBtYW5pcHVsYXRlIHRoZXNlIGNsZWFyZWQgb2JqZWN0cworICAvLyB0byBiZXR0ZXIgb3B0aW1pemUgbWVtb3J5IG1hbmFnZW1lbnQgdXNpbmcgdGhlIGZvbGxvd2luZyByb3V0aW5lcy4KKworICAvLyBHZXQgdGhlIG51bWJlciBvZiBjbGVhcmVkIG9iamVjdHMgdGhhdCBhcmUgY3VycmVudGx5IGJlaW5nIGtlcHQKKyAgLy8gYXJvdW5kIGZvciByZXVzZS4KKyAgaW50IENsZWFyZWRDb3VudCgpIGNvbnN0OworICAvLyBBZGQgYW4gZWxlbWVudCB0byB0aGUgcG9vbCBvZiBjbGVhcmVkIG9iamVjdHMsIHBhc3Npbmcgb3duZXJzaGlwIHRvCisgIC8vIHRoZSBSZXBlYXRlZFB0ckZpZWxkLiAgVGhlIGVsZW1lbnQgbXVzdCBiZSBjbGVhcmVkIHByaW9yIHRvIGNhbGxpbmcKKyAgLy8gdGhpcyBtZXRob2QuCisgIC8vCisgIC8vIFRoaXMgbWV0aG9kIGNhbm5vdCBiZSBjYWxsZWQgd2hlbiB0aGUgcmVwZWF0ZWQgZmllbGQgaXMgb24gYW4gYXJlbmEgb3Igd2hlbgorICAvLyB8dmFsdWV8IGlzOyBib3RoIGNhc2VzIHdpbGwgdHJpZ2dlciBhIEdPT0dMRV9EQ0hFQ0stZmFpbHVyZS4KKyAgdm9pZCBBZGRDbGVhcmVkKEVsZW1lbnQqIHZhbHVlKTsKKyAgLy8gUmVtb3ZlIGEgc2luZ2xlIGVsZW1lbnQgZnJvbSB0aGUgY2xlYXJlZCBwb29sIGFuZCByZXR1cm4gaXQsIHBhc3NpbmcKKyAgLy8gb3duZXJzaGlwIHRvIHRoZSBjYWxsZXIuICBUaGUgZWxlbWVudCBpcyBndWFyYW50ZWVkIHRvIGJlIGNsZWFyZWQuCisgIC8vIFJlcXVpcmVzOiAgQ2xlYXJlZENvdW50KCkgPiAwCisgIC8vCisgIC8vCisgIC8vIFRoaXMgbWV0aG9kIGNhbm5vdCBiZSBjYWxsZWQgd2hlbiB0aGUgcmVwZWF0ZWQgZmllbGQgaXMgb24gYW4gYXJlbmE7IGRvaW5nCisgIC8vIHNvIHdpbGwgdHJpZ2dlciBhIEdPT0dMRV9EQ0hFQ0stZmFpbHVyZS4KKyAgRWxlbWVudCogUmVsZWFzZUNsZWFyZWQoKTsKKworICAvLyBSZW1vdmVzIHRoZSBlbGVtZW50IHJlZmVyZW5jZWQgYnkgcG9zaXRpb24uCisgIC8vCisgIC8vIFJldHVybnMgYW4gaXRlcmF0b3IgdG8gdGhlIGVsZW1lbnQgaW1tZWRpYXRlbHkgZm9sbG93aW5nIHRoZSByZW1vdmVkCisgIC8vIGVsZW1lbnQuCisgIC8vCisgIC8vIEludmFsaWRhdGVzIGFsbCBpdGVyYXRvcnMgYXQgb3IgYWZ0ZXIgdGhlIHJlbW92ZWQgZWxlbWVudCwgaW5jbHVkaW5nIGVuZCgpLgorICBpdGVyYXRvciBlcmFzZShjb25zdF9pdGVyYXRvciBwb3NpdGlvbik7CisKKyAgLy8gUmVtb3ZlcyB0aGUgZWxlbWVudHMgaW4gdGhlIHJhbmdlIFtmaXJzdCwgbGFzdCkuCisgIC8vCisgIC8vIFJldHVybnMgYW4gaXRlcmF0b3IgdG8gdGhlIGVsZW1lbnQgaW1tZWRpYXRlbHkgZm9sbG93aW5nIHRoZSByZW1vdmVkIHJhbmdlLgorICAvLworICAvLyBJbnZhbGlkYXRlcyBhbGwgaXRlcmF0b3JzIGF0IG9yIGFmdGVyIHRoZSByZW1vdmVkIHJhbmdlLCBpbmNsdWRpbmcgZW5kKCkuCisgIGl0ZXJhdG9yIGVyYXNlKGNvbnN0X2l0ZXJhdG9yIGZpcnN0LCBjb25zdF9pdGVyYXRvciBsYXN0KTsKKworICAvLyBHZXRzIHRoZSBhcmVuYSBvbiB3aGljaCB0aGlzIFJlcGVhdGVkUHRyRmllbGQgc3RvcmVzIGl0cyBlbGVtZW50cy4KKyAgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogR2V0QXJlbmEoKSBjb25zdCB7CisgICAgcmV0dXJuIEdldEFyZW5hTm9WaXJ0dWFsKCk7CisgIH0KKworIHByb3RlY3RlZDoKKyAgLy8gTm90ZTogIFJlcGVhdGVkUHRyRmllbGQgU0hPVUxEIE5PVCBiZSBzdWJjbGFzc2VkIGJ5IHVzZXJzLiAgV2Ugb25seQorICAvLyAgIHN1YmNsYXNzIGl0IGluIG9uZSBwbGFjZSBhcyBhIGhhY2sgZm9yIGNvbXBhdGliaWxpdHkgd2l0aCBwcm90bzEuICBUaGUKKyAgLy8gICBzdWJjbGFzcyBuZWVkcyB0byBrbm93IGFib3V0IFR5cGVIYW5kbGVyIGluIG9yZGVyIHRvIGNhbGwgcHJvdGVjdGVkCisgIC8vICAgbWV0aG9kcyBvbiBSZXBlYXRlZFB0ckZpZWxkQmFzZS4KKyAgY2xhc3MgVHlwZUhhbmRsZXI7CisKKyAgLy8gSW50ZXJuYWwgYXJlbmEgYWNjZXNzb3IgZXhwZWN0ZWQgYnkgaGVscGVycyBpbiBBcmVuYS4KKyAgaW5saW5lIEFyZW5hKiBHZXRBcmVuYU5vVmlydHVhbCgpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgLy8gSW1wbGVtZW50YXRpb25zIGZvciBFeHRyYWN0U3VicmFuZ2UoKS4gVGhlIGNvcHlpbmcgYmVoYXZpb3IgbXVzdCBiZQorICAvLyBpbmNsdWRlZCBvbmx5IGlmIHRoZSB0eXBlIHN1cHBvcnRzIHRoZSBuZWNlc3Nhcnkgb3BlcmF0aW9ucyAoZS5nLiwKKyAgLy8gTWVyZ2VGcm9tKCkpLCBzbyB3ZSBtdXN0IHJlc29sdmUgdGhpcyBhdCBjb21waWxlIHRpbWUuIEV4dHJhY3RTdWJyYW5nZSgpCisgIC8vIHVzZXMgU0ZJTkFFIHRvIGNob29zZSBvbmUgb2YgdGhlIGJlbG93IGltcGxlbWVudGF0aW9ucy4KKyAgdm9pZCBFeHRyYWN0U3VicmFuZ2VJbnRlcm5hbChpbnQgc3RhcnQsIGludCBudW0sIEVsZW1lbnQqKiBlbGVtZW50cywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6dHJ1ZV90eXBlKTsKKyAgdm9pZCBFeHRyYWN0U3VicmFuZ2VJbnRlcm5hbChpbnQgc3RhcnQsIGludCBudW0sIEVsZW1lbnQqKiBlbGVtZW50cywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6ZmFsc2VfdHlwZSk7CisKKyAgZnJpZW5kIGNsYXNzIEFyZW5hOworICB0eXBlZGVmIHZvaWQgSW50ZXJuYWxBcmVuYUNvbnN0cnVjdGFibGVfOworCit9OworCisvLyBpbXBsZW1lbnRhdGlvbiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIFJlcGVhdGVkRmllbGQ8RWxlbWVudD46OlJlcGVhdGVkRmllbGQoKQorICA6IGN1cnJlbnRfc2l6ZV8oMCksCisgICAgdG90YWxfc2l6ZV8oMCksCisgICAgcmVwXyhOVUxMKSB7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIFJlcGVhdGVkRmllbGQ8RWxlbWVudD46OlJlcGVhdGVkRmllbGQoQXJlbmEqIGFyZW5hKQorICA6IGN1cnJlbnRfc2l6ZV8oMCksCisgICAgdG90YWxfc2l6ZV8oMCksCisgICAgcmVwXyhOVUxMKSB7CisgLy8gSW4gY2FzZSBhcmVuYSBpcyBOVUxMLCB0aGVuIHdlIGRvIG5vdCBjcmVhdGUgcmVwXywgYXMgY29kZSBoYXMgYW4gaW52YXJpYW50CisgLy8gYHJlcF8gPT0gTlVMTCB0aGVuIGFyZW5hID09IE5VTExgLgorIGlmIChhcmVuYSAhPSBOVUxMKSB7CisgIHJlcF8gPSByZWludGVycHJldF9jYXN0PFJlcCo+KAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYTo6Q3JlYXRlQXJyYXk8Y2hhcj4oYXJlbmEsIGtSZXBIZWFkZXJTaXplKSk7CisgIHJlcF8tPmFyZW5hID0gYXJlbmE7CisgfQorfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSBSZXBlYXRlZEZpZWxkPEVsZW1lbnQ+OjpSZXBlYXRlZEZpZWxkKGNvbnN0IFJlcGVhdGVkRmllbGQmIG90aGVyKQorICA6IGN1cnJlbnRfc2l6ZV8oMCksCisgICAgdG90YWxfc2l6ZV8oMCksCisgICAgcmVwXyhOVUxMKSB7CisgIENvcHlGcm9tKG90aGVyKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+Cit0ZW1wbGF0ZSA8dHlwZW5hbWUgSXRlcj4KK1JlcGVhdGVkRmllbGQ8RWxlbWVudD46OlJlcGVhdGVkRmllbGQoSXRlciBiZWdpbiwgY29uc3QgSXRlciYgZW5kKQorICA6IGN1cnJlbnRfc2l6ZV8oMCksCisgICAgdG90YWxfc2l6ZV8oMCksCisgICAgcmVwXyhOVUxMKSB7CisgIGludCByZXNlcnZlID0gaW50ZXJuYWw6OkNhbGN1bGF0ZVJlc2VydmUoYmVnaW4sIGVuZCk7CisgIGlmIChyZXNlcnZlICE9IC0xKSB7CisgICAgUmVzZXJ2ZShyZXNlcnZlKTsKKyAgICBmb3IgKDsgYmVnaW4gIT0gZW5kOyArK2JlZ2luKSB7CisgICAgICBBZGRBbHJlYWR5UmVzZXJ2ZWQoKmJlZ2luKTsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgZm9yICg7IGJlZ2luICE9IGVuZDsgKytiZWdpbikgeworICAgICAgQWRkKCpiZWdpbik7CisgICAgfQorICB9Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgorUmVwZWF0ZWRGaWVsZDxFbGVtZW50Pjo6flJlcGVhdGVkRmllbGQoKSB7CisgIC8vIFNlZSBleHBsYW5hdGlvbiBpbiBSZXNlcnZlKCk6IHdlIG5lZWQgdG8gaW52b2tlIGRlc3RydWN0b3JzIGhlcmUgZm9yIHRoZQorICAvLyBjYXNlIHRoYXQgRWxlbWVudCBoYXMgYSBub24tdHJpdmlhbCBkZXN0cnVjdG9yLiBJZiBFbGVtZW50IGhhcyBhIHRyaXZpYWwKKyAgLy8gZGVzdHJ1Y3RvciAoZm9yIGV4YW1wbGUsIGlmIGl0J3MgYSBwcmltaXRpdmUgdHlwZSwgbGlrZSBpbnQzMiksIHRoaXMgZW50aXJlCisgIC8vIGxvb3Agd2lsbCBiZSByZW1vdmVkIGJ5IHRoZSBvcHRpbWl6ZXIuCisgIGlmIChyZXBfICE9IE5VTEwpIHsKKyAgICBFbGVtZW50KiBlID0gJnJlcF8tPmVsZW1lbnRzWzBdOworICAgIEVsZW1lbnQqIGxpbWl0ID0gJnJlcF8tPmVsZW1lbnRzW3RvdGFsX3NpemVfXTsKKyAgICBmb3IgKDsgZSA8IGxpbWl0OyBlKyspIHsKKyAgICAgIGUtPkVsZW1lbnQ6On5FbGVtZW50KCk7CisgICAgfQorICAgIGlmIChyZXBfLT5hcmVuYSA9PSBOVUxMKSB7CisgICAgICBkZWxldGVbXSByZWludGVycHJldF9jYXN0PGNoYXIqPihyZXBfKTsKKyAgICB9CisgIH0KK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgUmVwZWF0ZWRGaWVsZDxFbGVtZW50PiYKK1JlcGVhdGVkRmllbGQ8RWxlbWVudD46Om9wZXJhdG9yPShjb25zdCBSZXBlYXRlZEZpZWxkJiBvdGhlcikgeworICBpZiAodGhpcyAhPSAmb3RoZXIpCisgICAgQ29weUZyb20ob3RoZXIpOworICByZXR1cm4gKnRoaXM7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIGJvb2wgUmVwZWF0ZWRGaWVsZDxFbGVtZW50Pjo6ZW1wdHkoKSBjb25zdCB7CisgIHJldHVybiBjdXJyZW50X3NpemVfID09IDA7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIGludCBSZXBlYXRlZEZpZWxkPEVsZW1lbnQ+OjpzaXplKCkgY29uc3QgeworICByZXR1cm4gY3VycmVudF9zaXplXzsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgaW50IFJlcGVhdGVkRmllbGQ8RWxlbWVudD46OkNhcGFjaXR5KCkgY29uc3QgeworICByZXR1cm4gdG90YWxfc2l6ZV87Cit9CisKK3RlbXBsYXRlPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgdm9pZCBSZXBlYXRlZEZpZWxkPEVsZW1lbnQ+OjpBZGRBbHJlYWR5UmVzZXJ2ZWQoY29uc3QgRWxlbWVudCYgdmFsdWUpIHsKKyAgR09PR0xFX0RDSEVDS19MVChjdXJyZW50X3NpemVfLCB0b3RhbF9zaXplXyk7CisgIHJlcF8tPmVsZW1lbnRzW2N1cnJlbnRfc2l6ZV8rK10gPSB2YWx1ZTsKK30KKwordGVtcGxhdGU8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSBFbGVtZW50KiBSZXBlYXRlZEZpZWxkPEVsZW1lbnQ+OjpBZGRBbHJlYWR5UmVzZXJ2ZWQoKSB7CisgIEdPT0dMRV9EQ0hFQ0tfTFQoY3VycmVudF9zaXplXywgdG90YWxfc2l6ZV8pOworICByZXR1cm4gJnJlcF8tPmVsZW1lbnRzW2N1cnJlbnRfc2l6ZV8rK107Cit9CisKK3RlbXBsYXRlPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgdm9pZCBSZXBlYXRlZEZpZWxkPEVsZW1lbnQ+OjpSZXNpemUoaW50IG5ld19zaXplLCBjb25zdCBFbGVtZW50JiB2YWx1ZSkgeworICBHT09HTEVfRENIRUNLX0dFKG5ld19zaXplLCAwKTsKKyAgaWYgKG5ld19zaXplID4gY3VycmVudF9zaXplXykgeworICAgIFJlc2VydmUobmV3X3NpemUpOworICAgIHN0ZDo6ZmlsbCgmcmVwXy0+ZWxlbWVudHNbY3VycmVudF9zaXplX10sCisgICAgICAgICAgICAgICZyZXBfLT5lbGVtZW50c1tuZXdfc2l6ZV0sIHZhbHVlKTsKKyAgfQorICBjdXJyZW50X3NpemVfID0gbmV3X3NpemU7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIGNvbnN0IEVsZW1lbnQmIFJlcGVhdGVkRmllbGQ8RWxlbWVudD46OkdldChpbnQgaW5kZXgpIGNvbnN0IHsKKyAgR09PR0xFX0RDSEVDS19HRShpbmRleCwgMCk7CisgIEdPT0dMRV9EQ0hFQ0tfTFQoaW5kZXgsIGN1cnJlbnRfc2l6ZV8pOworICByZXR1cm4gcmVwXy0+ZWxlbWVudHNbaW5kZXhdOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSBFbGVtZW50KiBSZXBlYXRlZEZpZWxkPEVsZW1lbnQ+OjpNdXRhYmxlKGludCBpbmRleCkgeworICBHT09HTEVfRENIRUNLX0dFKGluZGV4LCAwKTsKKyAgR09PR0xFX0RDSEVDS19MVChpbmRleCwgY3VycmVudF9zaXplXyk7CisgIHJldHVybiAmcmVwXy0+ZWxlbWVudHNbaW5kZXhdOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSB2b2lkIFJlcGVhdGVkRmllbGQ8RWxlbWVudD46OlNldChpbnQgaW5kZXgsIGNvbnN0IEVsZW1lbnQmIHZhbHVlKSB7CisgIEdPT0dMRV9EQ0hFQ0tfR0UoaW5kZXgsIDApOworICBHT09HTEVfRENIRUNLX0xUKGluZGV4LCBjdXJyZW50X3NpemVfKTsKKyAgcmVwXy0+ZWxlbWVudHNbaW5kZXhdID0gdmFsdWU7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIHZvaWQgUmVwZWF0ZWRGaWVsZDxFbGVtZW50Pjo6QWRkKGNvbnN0IEVsZW1lbnQmIHZhbHVlKSB7CisgIGlmIChjdXJyZW50X3NpemVfID09IHRvdGFsX3NpemVfKSBSZXNlcnZlKHRvdGFsX3NpemVfICsgMSk7CisgIHJlcF8tPmVsZW1lbnRzW2N1cnJlbnRfc2l6ZV8rK10gPSB2YWx1ZTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgRWxlbWVudCogUmVwZWF0ZWRGaWVsZDxFbGVtZW50Pjo6QWRkKCkgeworICBpZiAoY3VycmVudF9zaXplXyA9PSB0b3RhbF9zaXplXykgUmVzZXJ2ZSh0b3RhbF9zaXplXyArIDEpOworICByZXR1cm4gJnJlcF8tPmVsZW1lbnRzW2N1cnJlbnRfc2l6ZV8rK107Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIHZvaWQgUmVwZWF0ZWRGaWVsZDxFbGVtZW50Pjo6UmVtb3ZlTGFzdCgpIHsKKyAgR09PR0xFX0RDSEVDS19HVChjdXJyZW50X3NpemVfLCAwKTsKKyAgY3VycmVudF9zaXplXy0tOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK3ZvaWQgUmVwZWF0ZWRGaWVsZDxFbGVtZW50Pjo6RXh0cmFjdFN1YnJhbmdlKAorICAgIGludCBzdGFydCwgaW50IG51bSwgRWxlbWVudCogZWxlbWVudHMpIHsKKyAgR09PR0xFX0RDSEVDS19HRShzdGFydCwgMCk7CisgIEdPT0dMRV9EQ0hFQ0tfR0UobnVtLCAwKTsKKyAgR09PR0xFX0RDSEVDS19MRShzdGFydCArIG51bSwgdGhpcy0+Y3VycmVudF9zaXplXyk7CisKKyAgLy8gU2F2ZSB0aGUgdmFsdWVzIG9mIHRoZSByZW1vdmVkIGVsZW1lbnRzIGlmIHJlcXVlc3RlZC4KKyAgaWYgKGVsZW1lbnRzICE9IE5VTEwpIHsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bTsgKytpKQorICAgICAgZWxlbWVudHNbaV0gPSB0aGlzLT5HZXQoaSArIHN0YXJ0KTsKKyAgfQorCisgIC8vIFNsaWRlIHJlbWFpbmluZyBlbGVtZW50cyBkb3duIHRvIGZpbGwgdGhlIGdhcC4KKyAgaWYgKG51bSA+IDApIHsKKyAgICBmb3IgKGludCBpID0gc3RhcnQgKyBudW07IGkgPCB0aGlzLT5jdXJyZW50X3NpemVfOyArK2kpCisgICAgICB0aGlzLT5TZXQoaSAtIG51bSwgdGhpcy0+R2V0KGkpKTsKKyAgICB0aGlzLT5UcnVuY2F0ZSh0aGlzLT5jdXJyZW50X3NpemVfIC0gbnVtKTsKKyAgfQorfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSB2b2lkIFJlcGVhdGVkRmllbGQ8RWxlbWVudD46OkNsZWFyKCkgeworICBjdXJyZW50X3NpemVfID0gMDsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgdm9pZCBSZXBlYXRlZEZpZWxkPEVsZW1lbnQ+OjpNZXJnZUZyb20oY29uc3QgUmVwZWF0ZWRGaWVsZCYgb3RoZXIpIHsKKyAgR09PR0xFX0NIRUNLX05FKCZvdGhlciwgdGhpcyk7CisgIGlmIChvdGhlci5jdXJyZW50X3NpemVfICE9IDApIHsKKyAgICBSZXNlcnZlKGN1cnJlbnRfc2l6ZV8gKyBvdGhlci5jdXJyZW50X3NpemVfKTsKKyAgICBDb3B5QXJyYXkocmVwXy0+ZWxlbWVudHMgKyBjdXJyZW50X3NpemVfLAorICAgICAgICAgICAgICBvdGhlci5yZXBfLT5lbGVtZW50cywgb3RoZXIuY3VycmVudF9zaXplXyk7CisgICAgY3VycmVudF9zaXplXyArPSBvdGhlci5jdXJyZW50X3NpemVfOworICB9Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIHZvaWQgUmVwZWF0ZWRGaWVsZDxFbGVtZW50Pjo6Q29weUZyb20oY29uc3QgUmVwZWF0ZWRGaWVsZCYgb3RoZXIpIHsKKyAgaWYgKCZvdGhlciA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShvdGhlcik7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIHR5cGVuYW1lIFJlcGVhdGVkRmllbGQ8RWxlbWVudD46Oml0ZXJhdG9yIFJlcGVhdGVkRmllbGQ8RWxlbWVudD46OmVyYXNlKAorICAgIGNvbnN0X2l0ZXJhdG9yIHBvc2l0aW9uKSB7CisgIHJldHVybiBlcmFzZShwb3NpdGlvbiwgcG9zaXRpb24gKyAxKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgdHlwZW5hbWUgUmVwZWF0ZWRGaWVsZDxFbGVtZW50Pjo6aXRlcmF0b3IgUmVwZWF0ZWRGaWVsZDxFbGVtZW50Pjo6ZXJhc2UoCisgICAgY29uc3RfaXRlcmF0b3IgZmlyc3QsIGNvbnN0X2l0ZXJhdG9yIGxhc3QpIHsKKyAgc2l6ZV90eXBlIGZpcnN0X29mZnNldCA9IGZpcnN0IC0gY2JlZ2luKCk7CisgIGlmIChmaXJzdCAhPSBsYXN0KSB7CisgICAgVHJ1bmNhdGUoc3RkOjpjb3B5KGxhc3QsIGNlbmQoKSwgYmVnaW4oKSArIGZpcnN0X29mZnNldCkgLSBjYmVnaW4oKSk7CisgIH0KKyAgcmV0dXJuIGJlZ2luKCkgKyBmaXJzdF9vZmZzZXQ7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIEVsZW1lbnQqIFJlcGVhdGVkRmllbGQ8RWxlbWVudD46Om11dGFibGVfZGF0YSgpIHsKKyAgcmV0dXJuIHJlcF8gPyByZXBfLT5lbGVtZW50cyA6IE5VTEw7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIGNvbnN0IEVsZW1lbnQqIFJlcGVhdGVkRmllbGQ8RWxlbWVudD46OmRhdGEoKSBjb25zdCB7CisgIHJldHVybiByZXBfID8gcmVwXy0+ZWxlbWVudHMgOiBOVUxMOworfQorCisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIHZvaWQgUmVwZWF0ZWRGaWVsZDxFbGVtZW50Pjo6SW50ZXJuYWxTd2FwKFJlcGVhdGVkRmllbGQqIG90aGVyKSB7CisgIHN0ZDo6c3dhcChyZXBfLCBvdGhlci0+cmVwXyk7CisgIHN0ZDo6c3dhcChjdXJyZW50X3NpemVfLCBvdGhlci0+Y3VycmVudF9zaXplXyk7CisgIHN0ZDo6c3dhcCh0b3RhbF9zaXplXywgb3RoZXItPnRvdGFsX3NpemVfKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+Cit2b2lkIFJlcGVhdGVkRmllbGQ8RWxlbWVudD46OlN3YXAoUmVwZWF0ZWRGaWVsZCogb3RoZXIpIHsKKyAgaWYgKHRoaXMgPT0gb3RoZXIpIHJldHVybjsKKyAgaWYgKEdldEFyZW5hTm9WaXJ0dWFsKCkgPT0gIG90aGVyLT5HZXRBcmVuYU5vVmlydHVhbCgpKSB7CisgICAgSW50ZXJuYWxTd2FwKG90aGVyKTsKKyAgfSBlbHNlIHsKKyAgICBSZXBlYXRlZEZpZWxkPEVsZW1lbnQ+IHRlbXAob3RoZXItPkdldEFyZW5hTm9WaXJ0dWFsKCkpOworICAgIHRlbXAuTWVyZ2VGcm9tKCp0aGlzKTsKKyAgICBDb3B5RnJvbSgqb3RoZXIpOworICAgIG90aGVyLT5VbnNhZmVBcmVuYVN3YXAoJnRlbXApOworICB9Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50Pgordm9pZCBSZXBlYXRlZEZpZWxkPEVsZW1lbnQ+OjpVbnNhZmVBcmVuYVN3YXAoUmVwZWF0ZWRGaWVsZCogb3RoZXIpIHsKKyAgaWYgKHRoaXMgPT0gb3RoZXIpIHJldHVybjsKKyAgR09PR0xFX0RDSEVDSyhHZXRBcmVuYU5vVmlydHVhbCgpID09IG90aGVyLT5HZXRBcmVuYU5vVmlydHVhbCgpKTsKKyAgSW50ZXJuYWxTd2FwKG90aGVyKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+Cit2b2lkIFJlcGVhdGVkRmllbGQ8RWxlbWVudD46OlN3YXBFbGVtZW50cyhpbnQgaW5kZXgxLCBpbnQgaW5kZXgyKSB7CisgIHVzaW5nIHN0ZDo6c3dhcDsgIC8vIGVuYWJsZSBBREwgd2l0aCBmYWxsYmFjaworICBzd2FwKHJlcF8tPmVsZW1lbnRzW2luZGV4MV0sIHJlcF8tPmVsZW1lbnRzW2luZGV4Ml0pOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSB0eXBlbmFtZSBSZXBlYXRlZEZpZWxkPEVsZW1lbnQ+OjppdGVyYXRvcgorUmVwZWF0ZWRGaWVsZDxFbGVtZW50Pjo6YmVnaW4oKSB7CisgIHJldHVybiByZXBfID8gcmVwXy0+ZWxlbWVudHMgOiBOVUxMOworfQordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgdHlwZW5hbWUgUmVwZWF0ZWRGaWVsZDxFbGVtZW50Pjo6Y29uc3RfaXRlcmF0b3IKK1JlcGVhdGVkRmllbGQ8RWxlbWVudD46OmJlZ2luKCkgY29uc3QgeworICByZXR1cm4gcmVwXyA/IHJlcF8tPmVsZW1lbnRzIDogTlVMTDsKK30KK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIHR5cGVuYW1lIFJlcGVhdGVkRmllbGQ8RWxlbWVudD46OmNvbnN0X2l0ZXJhdG9yCitSZXBlYXRlZEZpZWxkPEVsZW1lbnQ+OjpjYmVnaW4oKSBjb25zdCB7CisgIHJldHVybiByZXBfID8gcmVwXy0+ZWxlbWVudHMgOiBOVUxMOworfQordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgdHlwZW5hbWUgUmVwZWF0ZWRGaWVsZDxFbGVtZW50Pjo6aXRlcmF0b3IKK1JlcGVhdGVkRmllbGQ8RWxlbWVudD46OmVuZCgpIHsKKyAgcmV0dXJuIHJlcF8gPyByZXBfLT5lbGVtZW50cyArIGN1cnJlbnRfc2l6ZV8gOiBOVUxMOworfQordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgdHlwZW5hbWUgUmVwZWF0ZWRGaWVsZDxFbGVtZW50Pjo6Y29uc3RfaXRlcmF0b3IKK1JlcGVhdGVkRmllbGQ8RWxlbWVudD46OmVuZCgpIGNvbnN0IHsKKyAgcmV0dXJuIHJlcF8gPyByZXBfLT5lbGVtZW50cyArIGN1cnJlbnRfc2l6ZV8gOiBOVUxMOworfQordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgdHlwZW5hbWUgUmVwZWF0ZWRGaWVsZDxFbGVtZW50Pjo6Y29uc3RfaXRlcmF0b3IKK1JlcGVhdGVkRmllbGQ8RWxlbWVudD46OmNlbmQoKSBjb25zdCB7CisgIHJldHVybiByZXBfID8gcmVwXy0+ZWxlbWVudHMgKyBjdXJyZW50X3NpemVfIDogTlVMTDsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgaW50IFJlcGVhdGVkRmllbGQ8RWxlbWVudD46OlNwYWNlVXNlZEV4Y2x1ZGluZ1NlbGYoKSBjb25zdCB7CisgIHJldHVybiByZXBfID8KKyAgICAgICh0b3RhbF9zaXplXyAqIHNpemVvZihFbGVtZW50KSArIGtSZXBIZWFkZXJTaXplKSA6IDA7Cit9CisKKy8vIEF2b2lkIGlubGluaW5nIG9mIFJlc2VydmUoKTogbmV3LCBjb3B5LCBhbmQgZGVsZXRlW10gbGVhZCB0byBhIHNpZ25pZmljYW50CisvLyBhbW91bnQgb2YgY29kZSBibG9hdC4KK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50Pgordm9pZCBSZXBlYXRlZEZpZWxkPEVsZW1lbnQ+OjpSZXNlcnZlKGludCBuZXdfc2l6ZSkgeworICBpZiAodG90YWxfc2l6ZV8gPj0gbmV3X3NpemUpIHJldHVybjsKKyAgUmVwKiBvbGRfcmVwID0gcmVwXzsKKyAgQXJlbmEqIGFyZW5hID0gR2V0QXJlbmFOb1ZpcnR1YWwoKTsKKyAgbmV3X3NpemUgPSBtYXgoZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OmtNaW5SZXBlYXRlZEZpZWxkQWxsb2NhdGlvblNpemUsCisgICAgICAgICAgICAgICAgIG1heCh0b3RhbF9zaXplXyAqIDIsIG5ld19zaXplKSk7CisgIEdPT0dMRV9DSEVDS19MRShzdGF0aWNfY2FzdDxzaXplX3Q+KG5ld19zaXplKSwKKyAgICAgICAgICAgKHN0ZDo6bnVtZXJpY19saW1pdHM8c2l6ZV90Pjo6bWF4KCkgLSBrUmVwSGVhZGVyU2l6ZSkgLworICAgICAgICAgICBzaXplb2YoRWxlbWVudCkpCisgICAgICA8PCAiUmVxdWVzdGVkIHNpemUgaXMgdG9vIGxhcmdlIHRvIGZpdCBpbnRvIHNpemVfdC4iOworICBpZiAoYXJlbmEgPT0gTlVMTCkgeworICAgIHJlcF8gPSByZWludGVycHJldF9jYXN0PFJlcCo+KAorICAgICAgICBuZXcgY2hhcltrUmVwSGVhZGVyU2l6ZSArIHNpemVvZihFbGVtZW50KSAqIG5ld19zaXplXSk7CisgIH0gZWxzZSB7CisgICAgcmVwXyA9IHJlaW50ZXJwcmV0X2Nhc3Q8UmVwKj4oCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hOjpDcmVhdGVBcnJheTxjaGFyPihhcmVuYSwKKyAgICAgICAgICAgICAgICBrUmVwSGVhZGVyU2l6ZSArIHNpemVvZihFbGVtZW50KSAqIG5ld19zaXplKSk7CisgIH0KKyAgcmVwXy0+YXJlbmEgPSBhcmVuYTsKKyAgaW50IG9sZF90b3RhbF9zaXplID0gdG90YWxfc2l6ZV87CisgIHRvdGFsX3NpemVfID0gbmV3X3NpemU7CisgIC8vIEludm9rZSBwbGFjZW1lbnQtbmV3IG9uIG5ld2x5IGFsbG9jYXRlZCBlbGVtZW50cy4gV2Ugc2hvdWxkbid0IGhhdmUgdG8gZG8KKyAgLy8gdGhpcywgc2luY2UgRWxlbWVudCBpcyBzdXBwb3NlZCB0byBiZSBQT0QsIGJ1dCBhIHByZXZpb3VzIHZlcnNpb24gb2YgdGhpcworICAvLyBjb2RlIGFsbG9jYXRlZCBzdG9yYWdlIHdpdGggIm5ldyBFbGVtZW50W3NpemVdIiBhbmQgc29tZSBjb2RlIHVzZXMKKyAgLy8gUmVwZWF0ZWRGaWVsZCB3aXRoIG5vbi1QT0QgdHlwZXMsIHJlbHlpbmcgb24gY29uc3RydWN0b3IgaW52b2NhdGlvbi4gSWYKKyAgLy8gRWxlbWVudCBoYXMgYSB0cml2aWFsIGNvbnN0cnVjdG9yIChlLmcuLCBpbnQzMiksIGdjYyAodGVzdGVkIHdpdGggLU8yKQorICAvLyBjb21wbGV0ZWx5IHJlbW92ZXMgdGhpcyBsb29wIGJlY2F1c2UgdGhlIGxvb3AgYm9keSBpcyBlbXB0eSwgc28gdGhpcyBoYXMgbm8KKyAgLy8gZWZmZWN0IHVubGVzcyBpdHMgc2lkZS1lZmZlY3RzIGFyZSByZXF1aXJlZCBmb3IgY29ycmVjdG5lc3MuCisgIC8vIE5vdGUgdGhhdCB3ZSBkbyB0aGlzIGJlZm9yZSBNb3ZlQXJyYXkoKSBiZWxvdyBiZWNhdXNlIEVsZW1lbnQncyBjb3B5CisgIC8vIGFzc2lnbm1lbnQgaW1wbGVtZW50YXRpb24gd2lsbCB3YW50IGFuIGluaXRpYWxpemVkIGluc3RhbmNlIGZpcnN0LgorICBFbGVtZW50KiBlID0gJnJlcF8tPmVsZW1lbnRzWzBdOworICBFbGVtZW50KiBsaW1pdCA9ICZyZXBfLT5lbGVtZW50c1t0b3RhbF9zaXplX107CisgIGZvciAoOyBlIDwgbGltaXQ7IGUrKykgeworICAgIG5ldyAoZSkgRWxlbWVudCgpOworICB9CisgIGlmIChjdXJyZW50X3NpemVfID4gMCkgeworICAgIE1vdmVBcnJheShyZXBfLT5lbGVtZW50cywgb2xkX3JlcC0+ZWxlbWVudHMsIGN1cnJlbnRfc2l6ZV8pOworICB9CisgIGlmIChvbGRfcmVwKSB7CisgICAgLy8gTGlrZXdpc2UsIHdlIG5lZWQgdG8gaW52b2tlIGRlc3RydWN0b3JzIG9uIHRoZSBvbGQgYXJyYXkuIElmIEVsZW1lbnQgaGFzCisgICAgLy8gbm8gZGVzdHJ1Y3RvciwgdGhpcyBsb29wIHdpbGwgZGlzYXBwZWFyLgorICAgIGUgPSAmb2xkX3JlcC0+ZWxlbWVudHNbMF07CisgICAgbGltaXQgPSAmb2xkX3JlcC0+ZWxlbWVudHNbb2xkX3RvdGFsX3NpemVdOworICAgIGZvciAoOyBlIDwgbGltaXQ7IGUrKykgeworICAgICAgZS0+RWxlbWVudDo6fkVsZW1lbnQoKTsKKyAgICB9CisgICAgaWYgKGFyZW5hID09IE5VTEwpIHsKKyAgICAgIGRlbGV0ZVtdIHJlaW50ZXJwcmV0X2Nhc3Q8Y2hhcio+KG9sZF9yZXApOworICAgIH0KKyAgfQorfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSB2b2lkIFJlcGVhdGVkRmllbGQ8RWxlbWVudD46OlRydW5jYXRlKGludCBuZXdfc2l6ZSkgeworICBHT09HTEVfRENIRUNLX0xFKG5ld19zaXplLCBjdXJyZW50X3NpemVfKTsKKyAgaWYgKGN1cnJlbnRfc2l6ZV8gPiAwKSB7CisgICAgY3VycmVudF9zaXplXyA9IG5ld19zaXplOworICB9Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIHZvaWQgUmVwZWF0ZWRGaWVsZDxFbGVtZW50Pjo6TW92ZUFycmF5KAorICBFbGVtZW50KiB0bywgRWxlbWVudCogZnJvbSwgaW50IGFycmF5X3NpemUpIHsKKyAgQ29weUFycmF5KHRvLCBmcm9tLCBhcnJheV9zaXplKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgdm9pZCBSZXBlYXRlZEZpZWxkPEVsZW1lbnQ+OjpDb3B5QXJyYXkoCisgIEVsZW1lbnQqIHRvLCBjb25zdCBFbGVtZW50KiBmcm9tLCBpbnQgYXJyYXlfc2l6ZSkgeworICBpbnRlcm5hbDo6RWxlbWVudENvcGllcjxFbGVtZW50PigpKHRvLCBmcm9tLCBhcnJheV9zaXplKTsKK30KKworbmFtZXNwYWNlIGludGVybmFsIHsKKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQsIGJvb2wgSGFzVHJpdmlhbENvcHk+Cit2b2lkIEVsZW1lbnRDb3BpZXI8RWxlbWVudCwgSGFzVHJpdmlhbENvcHk+OjpvcGVyYXRvcigpKAorICBFbGVtZW50KiB0bywgY29uc3QgRWxlbWVudCogZnJvbSwgaW50IGFycmF5X3NpemUpIHsKKyAgc3RkOjpjb3B5KGZyb20sIGZyb20gKyBhcnJheV9zaXplLCB0byk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50Pgorc3RydWN0IEVsZW1lbnRDb3BpZXI8RWxlbWVudCwgdHJ1ZT4geworICB2b2lkIG9wZXJhdG9yKCkoRWxlbWVudCogdG8sIGNvbnN0IEVsZW1lbnQqIGZyb20sIGludCBhcnJheV9zaXplKSB7CisgICAgbWVtY3B5KHRvLCBmcm9tLCBhcnJheV9zaXplICogc2l6ZW9mKEVsZW1lbnQpKTsKKyAgfQorfTsKKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCisKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCituYW1lc3BhY2UgaW50ZXJuYWwgeworCitpbmxpbmUgUmVwZWF0ZWRQdHJGaWVsZEJhc2U6OlJlcGVhdGVkUHRyRmllbGRCYXNlKCkKKyAgOiBhcmVuYV8oTlVMTCksCisgICAgY3VycmVudF9zaXplXygwKSwKKyAgICB0b3RhbF9zaXplXygwKSwKKyAgICByZXBfKE5VTEwpIHsKK30KKworaW5saW5lIFJlcGVhdGVkUHRyRmllbGRCYXNlOjpSZXBlYXRlZFB0ckZpZWxkQmFzZSg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkKKyAgOiBhcmVuYV8oYXJlbmEpLAorICAgIGN1cnJlbnRfc2l6ZV8oMCksCisgICAgdG90YWxfc2l6ZV8oMCksCisgICAgcmVwXyhOVUxMKSB7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBUeXBlSGFuZGxlcj4KK3ZvaWQgUmVwZWF0ZWRQdHJGaWVsZEJhc2U6OkRlc3Ryb3koKSB7CisgIGlmIChyZXBfICE9IE5VTEwpIHsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcF8tPmFsbG9jYXRlZF9zaXplOyBpKyspIHsKKyAgICAgIFR5cGVIYW5kbGVyOjpEZWxldGUoY2FzdDxUeXBlSGFuZGxlcj4ocmVwXy0+ZWxlbWVudHNbaV0pLCBhcmVuYV8pOworICAgIH0KKyAgICBpZiAoYXJlbmFfID09IE5VTEwpIHsKKyAgICAgIGRlbGV0ZSBbXSByZWludGVycHJldF9jYXN0PGNoYXIqPihyZXBfKTsKKyAgICB9CisgIH0KKyAgcmVwXyA9IE5VTEw7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBUeXBlSGFuZGxlcj4KK2lubGluZSB2b2lkIFJlcGVhdGVkUHRyRmllbGRCYXNlOjpTd2FwKFJlcGVhdGVkUHRyRmllbGRCYXNlKiBvdGhlcikgeworICBpZiAob3RoZXItPkdldEFyZW5hTm9WaXJ0dWFsKCkgPT0gR2V0QXJlbmFOb1ZpcnR1YWwoKSkgeworICAgIEludGVybmFsU3dhcChvdGhlcik7CisgIH0gZWxzZSB7CisgICAgU3dhcEZhbGxiYWNrPFR5cGVIYW5kbGVyPihvdGhlcik7CisgIH0KK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGVIYW5kbGVyPgordm9pZCBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6U3dhcEZhbGxiYWNrKFJlcGVhdGVkUHRyRmllbGRCYXNlKiBvdGhlcikgeworICBHT09HTEVfRENIRUNLKG90aGVyLT5HZXRBcmVuYU5vVmlydHVhbCgpICE9IEdldEFyZW5hTm9WaXJ0dWFsKCkpOworCisgIC8vIENvcHkgc2VtYW50aWNzIGluIHRoaXMgY2FzZS4gV2UgdHJ5IHRvIGltcHJvdmUgZWZmaWNpZW5jeSBieSBwbGFjaW5nIHRoZQorICAvLyB0ZW1wb3Jhcnkgb24gfG90aGVyfCdzIGFyZW5hIHNvIHRoYXQgbWVzc2FnZXMgYXJlIGNvcGllZCBjcm9zcy1hcmVuYSBvbmx5CisgIC8vIG9uY2UsIG5vdCB0d2ljZS4KKyAgUmVwZWF0ZWRQdHJGaWVsZEJhc2UgdGVtcChvdGhlci0+R2V0QXJlbmFOb1ZpcnR1YWwoKSk7CisgIHRlbXAuTWVyZ2VGcm9tPFR5cGVIYW5kbGVyPigqdGhpcyk7CisgIHRoaXMtPkNsZWFyPFR5cGVIYW5kbGVyPigpOworICB0aGlzLT5NZXJnZUZyb208VHlwZUhhbmRsZXI+KCpvdGhlcik7CisgIG90aGVyLT5DbGVhcjxUeXBlSGFuZGxlcj4oKTsKKyAgb3RoZXItPkludGVybmFsU3dhcCgmdGVtcCk7CisgIHRlbXAuRGVzdHJveTxUeXBlSGFuZGxlcj4oKTsgIC8vIEZyZWVzIHJlcF8gaWYgYG90aGVyYCBoYWQgbm8gYXJlbmEuCit9CisKK2lubGluZSBib29sIFJlcGVhdGVkUHRyRmllbGRCYXNlOjplbXB0eSgpIGNvbnN0IHsKKyAgcmV0dXJuIGN1cnJlbnRfc2l6ZV8gPT0gMDsKK30KKworaW5saW5lIGludCBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6c2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIGN1cnJlbnRfc2l6ZV87Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBUeXBlSGFuZGxlcj4KK2lubGluZSBjb25zdCB0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZSYKK1JlcGVhdGVkUHRyRmllbGRCYXNlOjpHZXQoaW50IGluZGV4KSBjb25zdCB7CisgIEdPT0dMRV9EQ0hFQ0tfR0UoaW5kZXgsIDApOworICBHT09HTEVfRENIRUNLX0xUKGluZGV4LCBjdXJyZW50X3NpemVfKTsKKyAgcmV0dXJuICpjYXN0PFR5cGVIYW5kbGVyPihyZXBfLT5lbGVtZW50c1tpbmRleF0pOworfQorCisKK3RlbXBsYXRlIDx0eXBlbmFtZSBUeXBlSGFuZGxlcj4KK2lubGluZSB0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZSoKK1JlcGVhdGVkUHRyRmllbGRCYXNlOjpNdXRhYmxlKGludCBpbmRleCkgeworICBHT09HTEVfRENIRUNLX0dFKGluZGV4LCAwKTsKKyAgR09PR0xFX0RDSEVDS19MVChpbmRleCwgY3VycmVudF9zaXplXyk7CisgIHJldHVybiBjYXN0PFR5cGVIYW5kbGVyPihyZXBfLT5lbGVtZW50c1tpbmRleF0pOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+CitpbmxpbmUgdm9pZCBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6RGVsZXRlKGludCBpbmRleCkgeworICBHT09HTEVfRENIRUNLX0dFKGluZGV4LCAwKTsKKyAgR09PR0xFX0RDSEVDS19MVChpbmRleCwgY3VycmVudF9zaXplXyk7CisgIFR5cGVIYW5kbGVyOjpEZWxldGUoY2FzdDxUeXBlSGFuZGxlcj4ocmVwXy0+ZWxlbWVudHNbaW5kZXhdKSwgYXJlbmFfKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGVIYW5kbGVyPgoraW5saW5lIHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKiBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6QWRkKAorICAgIHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKiBwcm90b3R5cGUpIHsKKyAgaWYgKHJlcF8gIT0gTlVMTCAmJiBjdXJyZW50X3NpemVfIDwgcmVwXy0+YWxsb2NhdGVkX3NpemUpIHsKKyAgICByZXR1cm4gY2FzdDxUeXBlSGFuZGxlcj4ocmVwXy0+ZWxlbWVudHNbY3VycmVudF9zaXplXysrXSk7CisgIH0KKyAgaWYgKCFyZXBfIHx8IHJlcF8tPmFsbG9jYXRlZF9zaXplID09IHRvdGFsX3NpemVfKSB7CisgICAgUmVzZXJ2ZSh0b3RhbF9zaXplXyArIDEpOworICB9CisgICsrcmVwXy0+YWxsb2NhdGVkX3NpemU7CisgIHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKiByZXN1bHQgPQorICAgICAgVHlwZUhhbmRsZXI6Ok5ld0Zyb21Qcm90b3R5cGUocHJvdG90eXBlLCBhcmVuYV8pOworICByZXBfLT5lbGVtZW50c1tjdXJyZW50X3NpemVfKytdID0gcmVzdWx0OworICByZXR1cm4gcmVzdWx0OworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+CitpbmxpbmUgdm9pZCBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6UmVtb3ZlTGFzdCgpIHsKKyAgR09PR0xFX0RDSEVDS19HVChjdXJyZW50X3NpemVfLCAwKTsKKyAgVHlwZUhhbmRsZXI6OkNsZWFyKGNhc3Q8VHlwZUhhbmRsZXI+KHJlcF8tPmVsZW1lbnRzWy0tY3VycmVudF9zaXplX10pKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGVIYW5kbGVyPgordm9pZCBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6Q2xlYXIoKSB7CisgIGNvbnN0IGludCBuID0gY3VycmVudF9zaXplXzsKKyAgR09PR0xFX0RDSEVDS19HRShuLCAwKTsKKyAgaWYgKG4gPiAwKSB7CisgICAgdm9pZCogY29uc3QqIGVsZW1lbnRzID0gcmVwXy0+ZWxlbWVudHM7CisgICAgaW50IGkgPSAwOworICAgIGRvIHsKKyAgICAgIFR5cGVIYW5kbGVyOjpDbGVhcihjYXN0PFR5cGVIYW5kbGVyPihlbGVtZW50c1tpKytdKSk7CisgICAgfSB3aGlsZSAoaSA8IG4pOworICAgIGN1cnJlbnRfc2l6ZV8gPSAwOworICB9Cit9CisKKy8vIFRvIGF2b2lkIHVubmVjZXNzYXJ5IGNvZGUgZHVwbGljYXRpb24gYW5kIHJlZHVjZSBiaW5hcnkgc2l6ZSwgd2UgdXNlIGEKKy8vIGxheWVyZWQgYXBwcm9hY2ggdG8gaW1wbGVtZW50aW5nIE1lcmdlRnJvbSgpLiBUaGUgdG9wbGV2ZWwgbWV0aG9kIGlzCisvLyB0ZW1wbGF0ZWQsIHNvIHdlIGdldCBhIHNtYWxsIHRodW5rIHBlciBjb25jcmV0ZSBtZXNzYWdlIHR5cGUgaW4gdGhlIGJpbmFyeS4KKy8vIFRoaXMgY2FsbHMgYSBzaGFyZWQgaW1wbGVtZW50YXRpb24gd2l0aCBtb3N0IG9mIHRoZSBsb2dpYywgcGFzc2luZyBhIGZ1bmN0aW9uCisvLyBwb2ludGVyIHRvIGFub3RoZXIgdHlwZS1zcGVjaWZpYyBwaWVjZSBvZiBjb2RlIHRoYXQgY2FsbHMgdGhlIG9iamVjdC1hbGxvY2F0ZQorLy8gYW5kIG1lcmdlIGhhbmRsZXJzLgordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGVIYW5kbGVyPgoraW5saW5lIHZvaWQgUmVwZWF0ZWRQdHJGaWVsZEJhc2U6Ok1lcmdlRnJvbShjb25zdCBSZXBlYXRlZFB0ckZpZWxkQmFzZSYgb3RoZXIpIHsKKyAgR09PR0xFX0RDSEVDS19ORSgmb3RoZXIsIHRoaXMpOworICBpZiAob3RoZXIuY3VycmVudF9zaXplXyA9PSAwKSByZXR1cm47CisgIE1lcmdlRnJvbUludGVybmFsKAorICAgICAgb3RoZXIsICZSZXBlYXRlZFB0ckZpZWxkQmFzZTo6TWVyZ2VGcm9tSW5uZXJMb29wPFR5cGVIYW5kbGVyPik7Cit9CisKK2lubGluZSB2b2lkIFJlcGVhdGVkUHRyRmllbGRCYXNlOjpNZXJnZUZyb21JbnRlcm5hbCgKKyAgICBjb25zdCBSZXBlYXRlZFB0ckZpZWxkQmFzZSYgb3RoZXIsCisgICAgdm9pZCAoUmVwZWF0ZWRQdHJGaWVsZEJhc2U6Oippbm5lcl9sb29wKSh2b2lkKiosIHZvaWQqKiwgaW50LCBpbnQpKSB7CisgIC8vIE5vdGU6IHdyYXBwZXIgaGFzIGFscmVhZHkgZ3VhcmFudGVlZCB0aGF0IG90aGVyLnJlcF8gIT0gTlVMTCBoZXJlLgorICBpbnQgb3RoZXJfc2l6ZSA9IG90aGVyLmN1cnJlbnRfc2l6ZV87CisgIHZvaWQqKiBvdGhlcl9lbGVtZW50cyA9IG90aGVyLnJlcF8tPmVsZW1lbnRzOworICB2b2lkKiogbmV3X2VsZW1lbnRzID0gSW50ZXJuYWxFeHRlbmQob3RoZXJfc2l6ZSk7CisgIGludCBhbGxvY2F0ZWRfZWxlbXMgPSByZXBfLT5hbGxvY2F0ZWRfc2l6ZSAtIGN1cnJlbnRfc2l6ZV87CisgICh0aGlzLT4qaW5uZXJfbG9vcCkobmV3X2VsZW1lbnRzLCBvdGhlcl9lbGVtZW50cywKKyAgICAgICAgICAgICAgICAgICAgICBvdGhlcl9zaXplLCBhbGxvY2F0ZWRfZWxlbXMpOworICBjdXJyZW50X3NpemVfICs9IG90aGVyX3NpemU7CisgIGlmIChyZXBfLT5hbGxvY2F0ZWRfc2l6ZSA8IGN1cnJlbnRfc2l6ZV8pIHsKKyAgICByZXBfLT5hbGxvY2F0ZWRfc2l6ZSA9IGN1cnJlbnRfc2l6ZV87CisgIH0KK30KKworLy8gTWVyZ2VzIG90aGVyX2VsZW1zIHRvIG91cl9lbGVtcy4KK3RlbXBsYXRlPHR5cGVuYW1lIFR5cGVIYW5kbGVyPgordm9pZCBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6TWVyZ2VGcm9tSW5uZXJMb29wKAorICAgIHZvaWQqKiBvdXJfZWxlbXMsIHZvaWQqKiBvdGhlcl9lbGVtcywgaW50IGxlbmd0aCwgaW50IGFscmVhZHlfYWxsb2NhdGVkKSB7CisgIC8vIFNwbGl0IGludG8gdHdvIGxvb3BzLCBvdmVyIHJhbmdlcyBbMCwgYWxsb2NhdGVkKSBhbmQgW2FsbG9jYXRlZCwgbGVuZ3RoKSwKKyAgLy8gdG8gYXZvaWQgYSBicmFuY2ggd2l0aGluIHRoZSBsb29wLgorICBmb3IgKGludCBpID0gMDsgaSA8IGFscmVhZHlfYWxsb2NhdGVkICYmIGkgPCBsZW5ndGg7IGkrKykgeworICAgIC8vIEFscmVhZHkgYWxsb2NhdGVkOiB1c2UgZXhpc3RpbmcgZWxlbWVudC4KKyAgICB0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZSogb3RoZXJfZWxlbSA9CisgICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8dHlwZW5hbWUgVHlwZUhhbmRsZXI6OlR5cGUqPihvdGhlcl9lbGVtc1tpXSk7CisgICAgdHlwZW5hbWUgVHlwZUhhbmRsZXI6OlR5cGUqIG5ld19lbGVtID0KKyAgICAgICAgcmVpbnRlcnByZXRfY2FzdDx0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZSo+KG91cl9lbGVtc1tpXSk7CisgICAgVHlwZUhhbmRsZXI6Ok1lcmdlKCpvdGhlcl9lbGVtLCBuZXdfZWxlbSk7CisgIH0KKyAgQXJlbmEqIGFyZW5hID0gR2V0QXJlbmFOb1ZpcnR1YWwoKTsKKyAgZm9yIChpbnQgaSA9IGFscmVhZHlfYWxsb2NhdGVkOyBpIDwgbGVuZ3RoOyBpKyspIHsKKyAgICAvLyBOb3QgYWxsb2NhdGVkOiBhbGxvYyBhIG5ldyBlbGVtZW50IGZpcnN0LCB0aGVuIG1lcmdlIGl0LgorICAgIHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKiBvdGhlcl9lbGVtID0KKyAgICAgICAgcmVpbnRlcnByZXRfY2FzdDx0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZSo+KG90aGVyX2VsZW1zW2ldKTsKKyAgICB0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZSogbmV3X2VsZW0gPQorICAgICAgICBUeXBlSGFuZGxlcjo6TmV3RnJvbVByb3RvdHlwZShvdGhlcl9lbGVtLCBhcmVuYSk7CisgICAgVHlwZUhhbmRsZXI6Ok1lcmdlKCpvdGhlcl9lbGVtLCBuZXdfZWxlbSk7CisgICAgb3VyX2VsZW1zW2ldID0gbmV3X2VsZW07CisgIH0KK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGVIYW5kbGVyPgoraW5saW5lIHZvaWQgUmVwZWF0ZWRQdHJGaWVsZEJhc2U6OkNvcHlGcm9tKGNvbnN0IFJlcGVhdGVkUHRyRmllbGRCYXNlJiBvdGhlcikgeworICBpZiAoJm90aGVyID09IHRoaXMpIHJldHVybjsKKyAgUmVwZWF0ZWRQdHJGaWVsZEJhc2U6OkNsZWFyPFR5cGVIYW5kbGVyPigpOworICBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6TWVyZ2VGcm9tPFR5cGVIYW5kbGVyPihvdGhlcik7Cit9CisKK2lubGluZSBpbnQgUmVwZWF0ZWRQdHJGaWVsZEJhc2U6OkNhcGFjaXR5KCkgY29uc3QgeworICByZXR1cm4gdG90YWxfc2l6ZV87Cit9CisKK2lubGluZSB2b2lkKiBjb25zdCogUmVwZWF0ZWRQdHJGaWVsZEJhc2U6OnJhd19kYXRhKCkgY29uc3QgeworICByZXR1cm4gcmVwXyA/IHJlcF8tPmVsZW1lbnRzIDogTlVMTDsKK30KKworaW5saW5lIHZvaWQqKiBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6cmF3X211dGFibGVfZGF0YSgpIGNvbnN0IHsKKyAgcmV0dXJuIHJlcF8gPyBjb25zdF9jYXN0PHZvaWQqKj4ocmVwXy0+ZWxlbWVudHMpIDogTlVMTDsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGVIYW5kbGVyPgoraW5saW5lIHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKiogUmVwZWF0ZWRQdHJGaWVsZEJhc2U6Om11dGFibGVfZGF0YSgpIHsKKyAgLy8gVE9ETyhrZW50b24pOiAgQnJlYWtzIEMrKyBhbGlhc2luZyBydWxlcy4gIFdlIHNob3VsZCBwcm9iYWJseSByZW1vdmUgdGhpcworICAvLyAgIG1ldGhvZCBlbnRpcmVseS4KKyAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8dHlwZW5hbWUgVHlwZUhhbmRsZXI6OlR5cGUqKj4ocmF3X211dGFibGVfZGF0YSgpKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGVIYW5kbGVyPgoraW5saW5lIGNvbnN0IHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKiBjb25zdCoKK1JlcGVhdGVkUHRyRmllbGRCYXNlOjpkYXRhKCkgY29uc3QgeworICAvLyBUT0RPKGtlbnRvbik6ICBCcmVha3MgQysrIGFsaWFzaW5nIHJ1bGVzLiAgV2Ugc2hvdWxkIHByb2JhYmx5IHJlbW92ZSB0aGlzCisgIC8vICAgbWV0aG9kIGVudGlyZWx5LgorICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxjb25zdCB0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZSogY29uc3QqPihyYXdfZGF0YSgpKTsKK30KKworaW5saW5lIHZvaWQgUmVwZWF0ZWRQdHJGaWVsZEJhc2U6OlN3YXBFbGVtZW50cyhpbnQgaW5kZXgxLCBpbnQgaW5kZXgyKSB7CisgIHVzaW5nIHN0ZDo6c3dhcDsgIC8vIGVuYWJsZSBBREwgd2l0aCBmYWxsYmFjaworICBzd2FwKHJlcF8tPmVsZW1lbnRzW2luZGV4MV0sIHJlcF8tPmVsZW1lbnRzW2luZGV4Ml0pOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+CitpbmxpbmUgaW50IFJlcGVhdGVkUHRyRmllbGRCYXNlOjpTcGFjZVVzZWRFeGNsdWRpbmdTZWxmKCkgY29uc3QgeworICBpbnQgYWxsb2NhdGVkX2J5dGVzID0gdG90YWxfc2l6ZV8gKiBzaXplb2Yodm9pZCopOworICBpZiAocmVwXyAhPSBOVUxMKSB7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBfLT5hbGxvY2F0ZWRfc2l6ZTsgKytpKSB7CisgICAgICBhbGxvY2F0ZWRfYnl0ZXMgKz0gVHlwZUhhbmRsZXI6OlNwYWNlVXNlZCgKKyAgICAgICAgICAqY2FzdDxUeXBlSGFuZGxlcj4ocmVwXy0+ZWxlbWVudHNbaV0pKTsKKyAgICB9CisgICAgYWxsb2NhdGVkX2J5dGVzICs9IGtSZXBIZWFkZXJTaXplOworICB9CisgIHJldHVybiBhbGxvY2F0ZWRfYnl0ZXM7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBUeXBlSGFuZGxlcj4KK2lubGluZSB0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZSogUmVwZWF0ZWRQdHJGaWVsZEJhc2U6OkFkZEZyb21DbGVhcmVkKCkgeworICBpZiAocmVwXyAhPSBOVUxMICYmIGN1cnJlbnRfc2l6ZV8gPCByZXBfLT5hbGxvY2F0ZWRfc2l6ZSkgeworICAgIHJldHVybiBjYXN0PFR5cGVIYW5kbGVyPihyZXBfLT5lbGVtZW50c1tjdXJyZW50X3NpemVfKytdKTsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorfQorCisvLyBBZGRBbGxvY2F0ZWQgdmVyc2lvbiB0aGF0IGltcGxlbWVudHMgYXJlbmEtc2FmZSBjb3B5aW5nIGJlaGF2aW9yLgordGVtcGxhdGUgPHR5cGVuYW1lIFR5cGVIYW5kbGVyPgordm9pZCBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6QWRkQWxsb2NhdGVkSW50ZXJuYWwoCisgICAgdHlwZW5hbWUgVHlwZUhhbmRsZXI6OlR5cGUqIHZhbHVlLAorICAgIGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjp0cnVlX3R5cGUpIHsKKyAgQXJlbmEqIGVsZW1lbnRfYXJlbmEgPSByZWludGVycHJldF9jYXN0PEFyZW5hKj4oCisgICAgICBUeXBlSGFuZGxlcjo6R2V0TWF5YmVBcmVuYVBvaW50ZXIodmFsdWUpKTsKKyAgQXJlbmEqIGFyZW5hID0gR2V0QXJlbmFOb1ZpcnR1YWwoKTsKKyAgaWYgKGFyZW5hID09IGVsZW1lbnRfYXJlbmEgJiYgcmVwXyAmJgorICAgICAgcmVwXy0+YWxsb2NhdGVkX3NpemUgPCB0b3RhbF9zaXplXykgeworICAgIC8vIEZhc3QgcGF0aDogdW5kZXJseWluZyBhcmVuYSByZXByZXNlbnRhdGlvbiAodGFnZ2VkIHBvaW50ZXIpIGlzIGVxdWFsIHRvCisgICAgLy8gb3VyIGFyZW5hIHBvaW50ZXIsIGFuZCB3ZSBjYW4gYWRkIHRvIGFycmF5IHdpdGhvdXQgcmVzaXppbmcgaXQgKGF0IGxlYXN0CisgICAgLy8gb25lIHNsb3QgdGhhdCBpcyBub3QgYWxsb2NhdGVkKS4KKyAgICB2b2lkKiogZWxlbXMgPSByZXBfLT5lbGVtZW50czsKKyAgICBpZiAoY3VycmVudF9zaXplXyA8IHJlcF8tPmFsbG9jYXRlZF9zaXplKSB7CisgICAgICAvLyBNYWtlIHNwYWNlIGF0IFtjdXJyZW50XSBieSBtb3ZpbmcgZmlyc3QgYWxsb2NhdGVkIGVsZW1lbnQgdG8gZW5kIG9mCisgICAgICAvLyBhbGxvY2F0ZWQgbGlzdC4KKyAgICAgIGVsZW1zW3JlcF8tPmFsbG9jYXRlZF9zaXplXSA9IGVsZW1zW2N1cnJlbnRfc2l6ZV9dOworICAgIH0KKyAgICBlbGVtc1tjdXJyZW50X3NpemVfXSA9IHZhbHVlOworICAgIGN1cnJlbnRfc2l6ZV8gPSBjdXJyZW50X3NpemVfICsgMTsKKyAgICByZXBfLT5hbGxvY2F0ZWRfc2l6ZSA9IHJlcF8tPmFsbG9jYXRlZF9zaXplICsgMTsKKyAgICByZXR1cm47CisgIH0gZWxzZSB7CisgICAgQWRkQWxsb2NhdGVkU2xvd1dpdGhDb3B5PFR5cGVIYW5kbGVyPigKKyAgICAgICAgdmFsdWUsIFR5cGVIYW5kbGVyOjpHZXRBcmVuYSh2YWx1ZSksIGFyZW5hKTsKKyAgfQorfQorCisvLyBTbG93cGF0aCBoYW5kbGVzIGFsbCBjYXNlcywgY29weWluZyBpZiBuZWNlc3NhcnkuCit0ZW1wbGF0ZTx0eXBlbmFtZSBUeXBlSGFuZGxlcj4KK3ZvaWQgUmVwZWF0ZWRQdHJGaWVsZEJhc2U6OkFkZEFsbG9jYXRlZFNsb3dXaXRoQ29weSgKKyAgICAvLyBQYXNzIHZhbHVlX2FyZW5hIGFuZCBteV9hcmVuYSB0byBhdm9pZCBkdXBsaWNhdGUgdmlydHVhbCBjYWxsICh2YWx1ZSkgb3IKKyAgICAvLyBsb2FkIChtaW5lKS4KKyAgICB0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZSogdmFsdWUsIEFyZW5hKiB2YWx1ZV9hcmVuYSwgQXJlbmEqIG15X2FyZW5hKSB7CisgIC8vIEVuc3VyZSB0aGF0IGVpdGhlciB0aGUgdmFsdWUgaXMgaW4gdGhlIHNhbWUgYXJlbmEsIG9yIGlmIG5vdCwgd2UgZG8gdGhlCisgIC8vIGFwcHJvcHJpYXRlIHRoaW5nOiBPd24oKSBpdCAoaWYgaXQncyBvbiBoZWFwIGFuZCB3ZSdyZSBpbiBhbiBhcmVuYSkgb3IgY29weQorICAvLyBpdCB0byBvdXIgYXJlbmEvaGVhcCAob3RoZXJ3aXNlKS4KKyAgaWYgKG15X2FyZW5hICE9IE5VTEwgJiYgdmFsdWVfYXJlbmEgPT0gTlVMTCkgeworICAgIG15X2FyZW5hLT5Pd24odmFsdWUpOworICB9IGVsc2UgaWYgKG15X2FyZW5hICE9IHZhbHVlX2FyZW5hKSB7CisgICAgdHlwZW5hbWUgVHlwZUhhbmRsZXI6OlR5cGUqIG5ld192YWx1ZSA9CisgICAgICAgIFR5cGVIYW5kbGVyOjpOZXdGcm9tUHJvdG90eXBlKHZhbHVlLCBteV9hcmVuYSk7CisgICAgVHlwZUhhbmRsZXI6Ok1lcmdlKCp2YWx1ZSwgbmV3X3ZhbHVlKTsKKyAgICBUeXBlSGFuZGxlcjo6RGVsZXRlKHZhbHVlLCB2YWx1ZV9hcmVuYSk7CisgICAgdmFsdWUgPSBuZXdfdmFsdWU7CisgIH0KKworICBVbnNhZmVBcmVuYUFkZEFsbG9jYXRlZDxUeXBlSGFuZGxlcj4odmFsdWUpOworfQorCisvLyBBZGRBbGxvY2F0ZWQgdmVyc2lvbiB0aGF0IGRvZXMgbm90IGltcGxlbWVudCBhcmVuYS1zYWZlIGNvcHlpbmcgYmVoYXZpb3IuCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+Cit2b2lkIFJlcGVhdGVkUHRyRmllbGRCYXNlOjpBZGRBbGxvY2F0ZWRJbnRlcm5hbCgKKyAgICB0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZSogdmFsdWUsCisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OmZhbHNlX3R5cGUpIHsKKyAgaWYgKHJlcF8gJiYgIHJlcF8tPmFsbG9jYXRlZF9zaXplIDwgdG90YWxfc2l6ZV8pIHsKKyAgICAvLyBGYXN0IHBhdGg6IHVuZGVybHlpbmcgYXJlbmEgcmVwcmVzZW50YXRpb24gKHRhZ2dlZCBwb2ludGVyKSBpcyBlcXVhbCB0bworICAgIC8vIG91ciBhcmVuYSBwb2ludGVyLCBhbmQgd2UgY2FuIGFkZCB0byBhcnJheSB3aXRob3V0IHJlc2l6aW5nIGl0IChhdCBsZWFzdAorICAgIC8vIG9uZSBzbG90IHRoYXQgaXMgbm90IGFsbG9jYXRlZCkuCisgICAgdm9pZCoqIGVsZW1zID0gcmVwXy0+ZWxlbWVudHM7CisgICAgaWYgKGN1cnJlbnRfc2l6ZV8gPCByZXBfLT5hbGxvY2F0ZWRfc2l6ZSkgeworICAgICAgLy8gTWFrZSBzcGFjZSBhdCBbY3VycmVudF0gYnkgbW92aW5nIGZpcnN0IGFsbG9jYXRlZCBlbGVtZW50IHRvIGVuZCBvZgorICAgICAgLy8gYWxsb2NhdGVkIGxpc3QuCisgICAgICBlbGVtc1tyZXBfLT5hbGxvY2F0ZWRfc2l6ZV0gPSBlbGVtc1tjdXJyZW50X3NpemVfXTsKKyAgICB9CisgICAgZWxlbXNbY3VycmVudF9zaXplX10gPSB2YWx1ZTsKKyAgICBjdXJyZW50X3NpemVfID0gY3VycmVudF9zaXplXyArIDE7CisgICAgKytyZXBfLT5hbGxvY2F0ZWRfc2l6ZTsKKyAgICByZXR1cm47CisgIH0gZWxzZSB7CisgICAgVW5zYWZlQXJlbmFBZGRBbGxvY2F0ZWQ8VHlwZUhhbmRsZXI+KHZhbHVlKTsKKyAgfQorfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+Cit2b2lkIFJlcGVhdGVkUHRyRmllbGRCYXNlOjpVbnNhZmVBcmVuYUFkZEFsbG9jYXRlZCgKKyAgICB0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZSogdmFsdWUpIHsKKyAgLy8gTWFrZSByb29tIGZvciB0aGUgbmV3IHBvaW50ZXIuCisgIGlmICghcmVwXyB8fCBjdXJyZW50X3NpemVfID09IHRvdGFsX3NpemVfKSB7CisgICAgLy8gVGhlIGFycmF5IGlzIGNvbXBsZXRlbHkgZnVsbCB3aXRoIG5vIGNsZWFyZWQgb2JqZWN0cywgc28gZ3JvdyBpdC4KKyAgICBSZXNlcnZlKHRvdGFsX3NpemVfICsgMSk7CisgICAgKytyZXBfLT5hbGxvY2F0ZWRfc2l6ZTsKKyAgfSBlbHNlIGlmIChyZXBfLT5hbGxvY2F0ZWRfc2l6ZSA9PSB0b3RhbF9zaXplXykgeworICAgIC8vIFRoZXJlIGlzIG5vIG1vcmUgc3BhY2UgaW4gdGhlIHBvaW50ZXIgYXJyYXkgYmVjYXVzZSBpdCBjb250YWlucyBzb21lCisgICAgLy8gY2xlYXJlZCBvYmplY3RzIGF3YWl0aW5nIHJldXNlLiAgV2UgZG9uJ3Qgd2FudCB0byBncm93IHRoZSBhcnJheSBpbiB0aGlzCisgICAgLy8gY2FzZSBiZWNhdXNlIG90aGVyd2lzZSBhIGxvb3AgY2FsbGluZyBBZGRBbGxvY2F0ZWQoKSBmb2xsb3dlZCBieSBDbGVhcigpCisgICAgLy8gd291bGQgbGVhayBtZW1vcnkuCisgICAgVHlwZUhhbmRsZXI6OkRlbGV0ZSgKKyAgICAgICAgY2FzdDxUeXBlSGFuZGxlcj4ocmVwXy0+ZWxlbWVudHNbY3VycmVudF9zaXplX10pLCBhcmVuYV8pOworICB9IGVsc2UgaWYgKGN1cnJlbnRfc2l6ZV8gPCByZXBfLT5hbGxvY2F0ZWRfc2l6ZSkgeworICAgIC8vIFdlIGhhdmUgc29tZSBjbGVhcmVkIG9iamVjdHMuICBXZSBkb24ndCBjYXJlIGFib3V0IHRoZWlyIG9yZGVyLCBzbyB3ZQorICAgIC8vIGNhbiBqdXN0IG1vdmUgdGhlIGZpcnN0IG9uZSB0byB0aGUgZW5kIHRvIG1ha2Ugc3BhY2UuCisgICAgcmVwXy0+ZWxlbWVudHNbcmVwXy0+YWxsb2NhdGVkX3NpemVdID0gcmVwXy0+ZWxlbWVudHNbY3VycmVudF9zaXplX107CisgICAgKytyZXBfLT5hbGxvY2F0ZWRfc2l6ZTsKKyAgfSBlbHNlIHsKKyAgICAvLyBUaGVyZSBhcmUgbm8gY2xlYXJlZCBvYmplY3RzLgorICAgICsrcmVwXy0+YWxsb2NhdGVkX3NpemU7CisgIH0KKworICByZXBfLT5lbGVtZW50c1tjdXJyZW50X3NpemVfKytdID0gdmFsdWU7Cit9CisKKy8vIFJlbGVhc2VMYXN0KCkgZm9yIHR5cGVzIHRoYXQgaW1wbGVtZW50IG1lcmdlL2NvcHkgYmVoYXZpb3IuCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+CitpbmxpbmUgdHlwZW5hbWUgVHlwZUhhbmRsZXI6OlR5cGUqCitSZXBlYXRlZFB0ckZpZWxkQmFzZTo6UmVsZWFzZUxhc3RJbnRlcm5hbChnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6dHJ1ZV90eXBlKSB7CisgIC8vIEZpcnN0LCByZWxlYXNlIGFuIGVsZW1lbnQuCisgIHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlKiByZXN1bHQgPSBVbnNhZmVBcmVuYVJlbGVhc2VMYXN0PFR5cGVIYW5kbGVyPigpOworICAvLyBOb3cgcGVyZm9ybSBhIGNvcHkgaWYgd2UncmUgb24gYW4gYXJlbmEuCisgIEFyZW5hKiBhcmVuYSA9IEdldEFyZW5hTm9WaXJ0dWFsKCk7CisgIGlmIChhcmVuYSA9PSBOVUxMKSB7CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfSBlbHNlIHsKKyAgICB0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZSogbmV3X3Jlc3VsdCA9CisgICAgICAgIFR5cGVIYW5kbGVyOjpOZXdGcm9tUHJvdG90eXBlKHJlc3VsdCwgTlVMTCk7CisgICAgVHlwZUhhbmRsZXI6Ok1lcmdlKCpyZXN1bHQsIG5ld19yZXN1bHQpOworICAgIHJldHVybiBuZXdfcmVzdWx0OworICB9Cit9CisKKy8vIFJlbGVhc2VMYXN0KCkgZm9yIHR5cGVzIHRoYXQgKmRvIG5vdCogaW1wbGVtZW50IG1lcmdlL2NvcHkgYmVoYXZpb3IgLS0gdGhpcworLy8gaXMgdGhlIHNhbWUgYXMgVW5zYWZlQXJlbmFSZWxlYXNlTGFzdCgpLiBOb3RlIHRoYXQgd2UgR09PR0xFX0RDSEVDSy1mYWlsIGlmIHdlJ3JlIG9uCisvLyBhbiBhcmVuYSwgc2luY2UgdGhlIHVzZXIgcmVhbGx5IHNob3VsZCBpbXBsZW1lbnQgdGhlIGNvcHkgb3BlcmF0aW9uIGluIHRoaXMKKy8vIGNhc2UuCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+CitpbmxpbmUgdHlwZW5hbWUgVHlwZUhhbmRsZXI6OlR5cGUqCitSZXBlYXRlZFB0ckZpZWxkQmFzZTo6UmVsZWFzZUxhc3RJbnRlcm5hbChnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6ZmFsc2VfdHlwZSkgeworICBHT09HTEVfRENIRUNLKEdldEFyZW5hTm9WaXJ0dWFsKCkgPT0gTlVMTCkKKyAgICAgIDw8ICJSZWxlYXNlTGFzdCgpIGNhbGxlZCBvbiBhIFJlcGVhdGVkUHRyRmllbGQgdGhhdCBpcyBvbiBhbiBhcmVuYSwgIgorICAgICAgPDwgIndpdGggYSB0eXBlIHRoYXQgZG9lcyBub3QgaW1wbGVtZW50IE1lcmdlRnJvbS4gVGhpcyBpcyB1bnNhZmU7ICIKKyAgICAgIDw8ICJwbGVhc2UgaW1wbGVtZW50IE1lcmdlRnJvbSBmb3IgeW91ciB0eXBlLiI7CisgIHJldHVybiBVbnNhZmVBcmVuYVJlbGVhc2VMYXN0PFR5cGVIYW5kbGVyPigpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+CitpbmxpbmUgdHlwZW5hbWUgVHlwZUhhbmRsZXI6OlR5cGUqCisgIFJlcGVhdGVkUHRyRmllbGRCYXNlOjpVbnNhZmVBcmVuYVJlbGVhc2VMYXN0KCkgeworICBHT09HTEVfRENIRUNLX0dUKGN1cnJlbnRfc2l6ZV8sIDApOworICB0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZSogcmVzdWx0ID0KKyAgICAgIGNhc3Q8VHlwZUhhbmRsZXI+KHJlcF8tPmVsZW1lbnRzWy0tY3VycmVudF9zaXplX10pOworICAtLXJlcF8tPmFsbG9jYXRlZF9zaXplOworICBpZiAoY3VycmVudF9zaXplXyA8IHJlcF8tPmFsbG9jYXRlZF9zaXplKSB7CisgICAgLy8gVGhlcmUgYXJlIGNsZWFyZWQgZWxlbWVudHMgb24gdGhlIGVuZDsgcmVwbGFjZSB0aGUgcmVtb3ZlZCBlbGVtZW50CisgICAgLy8gd2l0aCB0aGUgbGFzdCBhbGxvY2F0ZWQgZWxlbWVudC4KKyAgICByZXBfLT5lbGVtZW50c1tjdXJyZW50X3NpemVfXSA9IHJlcF8tPmVsZW1lbnRzW3JlcF8tPmFsbG9jYXRlZF9zaXplXTsKKyAgfQorICByZXR1cm4gcmVzdWx0OworfQorCitpbmxpbmUgaW50IFJlcGVhdGVkUHRyRmllbGRCYXNlOjpDbGVhcmVkQ291bnQoKSBjb25zdCB7CisgIHJldHVybiByZXBfID8gKHJlcF8tPmFsbG9jYXRlZF9zaXplIC0gY3VycmVudF9zaXplXykgOiAwOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHlwZUhhbmRsZXI+CitpbmxpbmUgdm9pZCBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6QWRkQ2xlYXJlZCgKKyAgICB0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZSogdmFsdWUpIHsKKyAgR09PR0xFX0RDSEVDSyhHZXRBcmVuYU5vVmlydHVhbCgpID09IE5VTEwpCisgICAgICA8PCAiQWRkQ2xlYXJlZCgpIGNhbiBvbmx5IGJlIHVzZWQgb24gYSBSZXBlYXRlZFB0ckZpZWxkIG5vdCBvbiBhbiBhcmVuYS4iOworICBHT09HTEVfRENIRUNLKFR5cGVIYW5kbGVyOjpHZXRBcmVuYSh2YWx1ZSkgPT0gTlVMTCkKKyAgICAgIDw8ICJBZGRDbGVhcmVkKCkgY2FuIG9ubHkgYWNjZXB0IHZhbHVlcyBub3Qgb24gYW4gYXJlbmEuIjsKKyAgaWYgKCFyZXBfIHx8IHJlcF8tPmFsbG9jYXRlZF9zaXplID09IHRvdGFsX3NpemVfKSB7CisgICAgUmVzZXJ2ZSh0b3RhbF9zaXplXyArIDEpOworICB9CisgIHJlcF8tPmVsZW1lbnRzW3JlcF8tPmFsbG9jYXRlZF9zaXplKytdID0gdmFsdWU7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBUeXBlSGFuZGxlcj4KK2lubGluZSB0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZSogUmVwZWF0ZWRQdHJGaWVsZEJhc2U6OlJlbGVhc2VDbGVhcmVkKCkgeworICBHT09HTEVfRENIRUNLKEdldEFyZW5hTm9WaXJ0dWFsKCkgPT0gTlVMTCkKKyAgICAgIDw8ICJSZWxlYXNlQ2xlYXJlZCgpIGNhbiBvbmx5IGJlIHVzZWQgb24gYSBSZXBlYXRlZFB0ckZpZWxkIG5vdCBvbiAiCisgICAgICA8PCAiYW4gYXJlbmEuIjsKKyAgR09PR0xFX0RDSEVDSyhHZXRBcmVuYU5vVmlydHVhbCgpID09IE5VTEwpOworICBHT09HTEVfRENIRUNLKHJlcF8gIT0gTlVMTCk7CisgIEdPT0dMRV9EQ0hFQ0tfR1QocmVwXy0+YWxsb2NhdGVkX3NpemUsIGN1cnJlbnRfc2l6ZV8pOworICByZXR1cm4gY2FzdDxUeXBlSGFuZGxlcj4ocmVwXy0+ZWxlbWVudHNbLS1yZXBfLT5hbGxvY2F0ZWRfc2l6ZV0pOworfQorCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2NsYXNzIFJlcGVhdGVkUHRyRmllbGQ8RWxlbWVudD46OlR5cGVIYW5kbGVyCisgICAgOiBwdWJsaWMgaW50ZXJuYWw6OkdlbmVyaWNUeXBlSGFuZGxlcjxFbGVtZW50PiB7Cit9OworCit0ZW1wbGF0ZSA8PgorY2xhc3MgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+OjpUeXBlSGFuZGxlcgorICAgIDogcHVibGljIGludGVybmFsOjpTdHJpbmdUeXBlSGFuZGxlciB7Cit9OworCisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIFJlcGVhdGVkUHRyRmllbGQ8RWxlbWVudD46OlJlcGVhdGVkUHRyRmllbGQoKQorICA6IFJlcGVhdGVkUHRyRmllbGRCYXNlKCkge30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6UmVwZWF0ZWRQdHJGaWVsZCg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgOgorICBSZXBlYXRlZFB0ckZpZWxkQmFzZShhcmVuYSkge30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6UmVwZWF0ZWRQdHJGaWVsZCgKKyAgICBjb25zdCBSZXBlYXRlZFB0ckZpZWxkJiBvdGhlcikKKyAgOiBSZXBlYXRlZFB0ckZpZWxkQmFzZSgpIHsKKyAgQ29weUZyb20ob3RoZXIpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK3RlbXBsYXRlIDx0eXBlbmFtZSBJdGVyPgoraW5saW5lIFJlcGVhdGVkUHRyRmllbGQ8RWxlbWVudD46OlJlcGVhdGVkUHRyRmllbGQoCisgICAgSXRlciBiZWdpbiwgY29uc3QgSXRlciYgZW5kKSB7CisgIGludCByZXNlcnZlID0gaW50ZXJuYWw6OkNhbGN1bGF0ZVJlc2VydmUoYmVnaW4sIGVuZCk7CisgIGlmIChyZXNlcnZlICE9IC0xKSB7CisgICAgUmVzZXJ2ZShyZXNlcnZlKTsKKyAgfQorICBmb3IgKDsgYmVnaW4gIT0gZW5kOyArK2JlZ2luKSB7CisgICAgKkFkZCgpID0gKmJlZ2luOworICB9Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgorUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6flJlcGVhdGVkUHRyRmllbGQoKSB7CisgIERlc3Ryb3k8VHlwZUhhbmRsZXI+KCk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIFJlcGVhdGVkUHRyRmllbGQ8RWxlbWVudD4mIFJlcGVhdGVkUHRyRmllbGQ8RWxlbWVudD46Om9wZXJhdG9yPSgKKyAgICBjb25zdCBSZXBlYXRlZFB0ckZpZWxkJiBvdGhlcikgeworICBpZiAodGhpcyAhPSAmb3RoZXIpCisgICAgQ29weUZyb20ob3RoZXIpOworICByZXR1cm4gKnRoaXM7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIGJvb2wgUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6ZW1wdHkoKSBjb25zdCB7CisgIHJldHVybiBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6ZW1wdHkoKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgaW50IFJlcGVhdGVkUHRyRmllbGQ8RWxlbWVudD46OnNpemUoKSBjb25zdCB7CisgIHJldHVybiBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6c2l6ZSgpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSBjb25zdCBFbGVtZW50JiBSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+OjpHZXQoaW50IGluZGV4KSBjb25zdCB7CisgIHJldHVybiBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6R2V0PFR5cGVIYW5kbGVyPihpbmRleCk7Cit9CisKKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgRWxlbWVudCogUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6TXV0YWJsZShpbnQgaW5kZXgpIHsKKyAgcmV0dXJuIFJlcGVhdGVkUHRyRmllbGRCYXNlOjpNdXRhYmxlPFR5cGVIYW5kbGVyPihpbmRleCk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIEVsZW1lbnQqIFJlcGVhdGVkUHRyRmllbGQ8RWxlbWVudD46OkFkZCgpIHsKKyAgcmV0dXJuIFJlcGVhdGVkUHRyRmllbGRCYXNlOjpBZGQ8VHlwZUhhbmRsZXI+KCk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIHZvaWQgUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6UmVtb3ZlTGFzdCgpIHsKKyAgUmVwZWF0ZWRQdHJGaWVsZEJhc2U6OlJlbW92ZUxhc3Q8VHlwZUhhbmRsZXI+KCk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIHZvaWQgUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6RGVsZXRlU3VicmFuZ2UoaW50IHN0YXJ0LCBpbnQgbnVtKSB7CisgIEdPT0dMRV9EQ0hFQ0tfR0Uoc3RhcnQsIDApOworICBHT09HTEVfRENIRUNLX0dFKG51bSwgMCk7CisgIEdPT0dMRV9EQ0hFQ0tfTEUoc3RhcnQgKyBudW0sIHNpemUoKSk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtOyArK2kpIHsKKyAgICBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6RGVsZXRlPFR5cGVIYW5kbGVyPihzdGFydCArIGkpOworICB9CisgIEV4dHJhY3RTdWJyYW5nZShzdGFydCwgbnVtLCBOVUxMKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgdm9pZCBSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+OjpFeHRyYWN0U3VicmFuZ2UoCisgICAgaW50IHN0YXJ0LCBpbnQgbnVtLCBFbGVtZW50KiogZWxlbWVudHMpIHsKKyAgdHlwZW5hbWUgaW50ZXJuYWw6OlR5cGVJbXBsZW1lbnRzTWVyZ2VCZWhhdmlvcjwKKyAgICAgIHR5cGVuYW1lIFR5cGVIYW5kbGVyOjpUeXBlPjo6dHlwZSB0OworICBFeHRyYWN0U3VicmFuZ2VJbnRlcm5hbChzdGFydCwgbnVtLCBlbGVtZW50cywgdCk7Cit9CisKKy8vIEV4dHJhY3RTdWJyYW5nZSgpIGltcGxlbWVudGF0aW9uIGZvciB0eXBlcyB0aGF0IGltcGxlbWVudCBtZXJnZS9jb3B5CisvLyBiZWhhdmlvci4KK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIHZvaWQgUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6RXh0cmFjdFN1YnJhbmdlSW50ZXJuYWwoCisgICAgaW50IHN0YXJ0LCBpbnQgbnVtLCBFbGVtZW50KiogZWxlbWVudHMsIGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjp0cnVlX3R5cGUpIHsKKyAgR09PR0xFX0RDSEVDS19HRShzdGFydCwgMCk7CisgIEdPT0dMRV9EQ0hFQ0tfR0UobnVtLCAwKTsKKyAgR09PR0xFX0RDSEVDS19MRShzdGFydCArIG51bSwgc2l6ZSgpKTsKKworICBpZiAobnVtID4gMCkgeworICAgIC8vIFNhdmUgdGhlIHZhbHVlcyBvZiB0aGUgcmVtb3ZlZCBlbGVtZW50cyBpZiByZXF1ZXN0ZWQuCisgICAgaWYgKGVsZW1lbnRzICE9IE5VTEwpIHsKKyAgICAgIGlmIChHZXRBcmVuYU5vVmlydHVhbCgpICE9IE5VTEwpIHsKKyAgICAgICAgLy8gSWYgd2UncmUgb24gYW4gYXJlbmEsIHdlIHBlcmZvcm0gYSBjb3B5IGZvciBlYWNoIGVsZW1lbnQgc28gdGhhdCB0aGUKKyAgICAgICAgLy8gcmV0dXJuZWQgZWxlbWVudHMgYXJlIGhlYXAtYWxsb2NhdGVkLgorICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bTsgKytpKSB7CisgICAgICAgICAgRWxlbWVudCogZWxlbWVudCA9IFJlcGVhdGVkUHRyRmllbGRCYXNlOjoKKyAgICAgICAgICAgICAgTXV0YWJsZTxUeXBlSGFuZGxlcj4oaSArIHN0YXJ0KTsKKyAgICAgICAgICB0eXBlbmFtZSBUeXBlSGFuZGxlcjo6VHlwZSogbmV3X3ZhbHVlID0KKyAgICAgICAgICAgICAgVHlwZUhhbmRsZXI6Ok5ld0Zyb21Qcm90b3R5cGUoZWxlbWVudCwgTlVMTCk7CisgICAgICAgICAgVHlwZUhhbmRsZXI6Ok1lcmdlKCplbGVtZW50LCBuZXdfdmFsdWUpOworICAgICAgICAgIGVsZW1lbnRzW2ldID0gbmV3X3ZhbHVlOworICAgICAgICB9CisgICAgICB9IGVsc2UgeworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bTsgKytpKSB7CisgICAgICAgICAgZWxlbWVudHNbaV0gPSBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6TXV0YWJsZTxUeXBlSGFuZGxlcj4oaSArIHN0YXJ0KTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgICBDbG9zZUdhcChzdGFydCwgbnVtKTsKKyAgfQorfQorCisvLyBFeHRyYWN0U3VicmFuZ2UoKSBpbXBsZW1lbnRhdGlvbiBmb3IgdHlwZXMgdGhhdCBkbyBub3QgaW1wbGVtZW50IG1lcmdlL2NvcHkKKy8vIGJlaGF2aW9yLgordGVtcGxhdGU8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSB2b2lkIFJlcGVhdGVkUHRyRmllbGQ8RWxlbWVudD46OkV4dHJhY3RTdWJyYW5nZUludGVybmFsKAorICAgIGludCBzdGFydCwgaW50IG51bSwgRWxlbWVudCoqIGVsZW1lbnRzLCBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6ZmFsc2VfdHlwZSkgeworICAvLyBUaGlzIGNhc2UgaXMgaWRlbnRpY2FsIHRvIFVuc2FmZUFyZW5hRXh0cmFjdFN1YnJhbmdlKCkuIEhvd2V2ZXIsIHNpbmNlCisgIC8vIEV4dHJhY3RTdWJyYW5nZSgpIG11c3QgcmV0dXJuIGhlYXAtYWxsb2NhdGVkIG9iamVjdHMgYnkgY29udHJhY3QsIGFuZCB3ZQorICAvLyBjYW5ub3QgZnVsZmlsbCB0aGlzIGNvbnRyYWN0IGlmIHdlIGFyZSBhbiBvbiBhcmVuYSwgd2UgbXVzdCBHT09HTEVfRENIRUNLKCkgdGhhdAorICAvLyB3ZSBhcmUgbm90IG9uIGFuIGFyZW5hLgorICBHT09HTEVfRENIRUNLKEdldEFyZW5hTm9WaXJ0dWFsKCkgPT0gTlVMTCkKKyAgICAgIDw8ICJFeHRyYWN0U3VicmFuZ2UoKSB3aGVuIGFyZW5hIGlzIG5vbi1OVUxMIGlzIG9ubHkgc3VwcG9ydGVkIHdoZW4gIgorICAgICAgPDwgInRoZSBFbGVtZW50IHR5cGUgc3VwcGxpZXMgYSBNZXJnZUZyb20oKSBvcGVyYXRpb24gdG8gbWFrZSBjb3BpZXMuIjsKKyAgVW5zYWZlQXJlbmFFeHRyYWN0U3VicmFuZ2Uoc3RhcnQsIG51bSwgZWxlbWVudHMpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSB2b2lkIFJlcGVhdGVkUHRyRmllbGQ8RWxlbWVudD46OlVuc2FmZUFyZW5hRXh0cmFjdFN1YnJhbmdlKAorICAgIGludCBzdGFydCwgaW50IG51bSwgRWxlbWVudCoqIGVsZW1lbnRzKSB7CisgIEdPT0dMRV9EQ0hFQ0tfR0Uoc3RhcnQsIDApOworICBHT09HTEVfRENIRUNLX0dFKG51bSwgMCk7CisgIEdPT0dMRV9EQ0hFQ0tfTEUoc3RhcnQgKyBudW0sIHNpemUoKSk7CisKKyAgaWYgKG51bSA+IDApIHsKKyAgICAvLyBTYXZlIHRoZSB2YWx1ZXMgb2YgdGhlIHJlbW92ZWQgZWxlbWVudHMgaWYgcmVxdWVzdGVkLgorICAgIGlmIChlbGVtZW50cyAhPSBOVUxMKSB7CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bTsgKytpKSB7CisgICAgICAgIGVsZW1lbnRzW2ldID0gUmVwZWF0ZWRQdHJGaWVsZEJhc2U6Ok11dGFibGU8VHlwZUhhbmRsZXI+KGkgKyBzdGFydCk7CisgICAgICB9CisgICAgfQorICAgIENsb3NlR2FwKHN0YXJ0LCBudW0pOworICB9Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIHZvaWQgUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6Q2xlYXIoKSB7CisgIFJlcGVhdGVkUHRyRmllbGRCYXNlOjpDbGVhcjxUeXBlSGFuZGxlcj4oKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgdm9pZCBSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+OjpNZXJnZUZyb20oCisgICAgY29uc3QgUmVwZWF0ZWRQdHJGaWVsZCYgb3RoZXIpIHsKKyAgUmVwZWF0ZWRQdHJGaWVsZEJhc2U6Ok1lcmdlRnJvbTxUeXBlSGFuZGxlcj4ob3RoZXIpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSB2b2lkIFJlcGVhdGVkUHRyRmllbGQ8RWxlbWVudD46OkNvcHlGcm9tKAorICAgIGNvbnN0IFJlcGVhdGVkUHRyRmllbGQmIG90aGVyKSB7CisgIFJlcGVhdGVkUHRyRmllbGRCYXNlOjpDb3B5RnJvbTxUeXBlSGFuZGxlcj4ob3RoZXIpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSB0eXBlbmFtZSBSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+OjppdGVyYXRvcgorUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6ZXJhc2UoY29uc3RfaXRlcmF0b3IgcG9zaXRpb24pIHsKKyAgcmV0dXJuIGVyYXNlKHBvc2l0aW9uLCBwb3NpdGlvbiArIDEpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSB0eXBlbmFtZSBSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+OjppdGVyYXRvcgorUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6ZXJhc2UoY29uc3RfaXRlcmF0b3IgZmlyc3QsIGNvbnN0X2l0ZXJhdG9yIGxhc3QpIHsKKyAgc2l6ZV90eXBlIHBvc19vZmZzZXQgPSBzdGQ6OmRpc3RhbmNlKGNiZWdpbigpLCBmaXJzdCk7CisgIHNpemVfdHlwZSBsYXN0X29mZnNldCA9IHN0ZDo6ZGlzdGFuY2UoY2JlZ2luKCksIGxhc3QpOworICBEZWxldGVTdWJyYW5nZShwb3Nfb2Zmc2V0LCBsYXN0X29mZnNldCAtIHBvc19vZmZzZXQpOworICByZXR1cm4gYmVnaW4oKSArIHBvc19vZmZzZXQ7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIEVsZW1lbnQqKiBSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+OjptdXRhYmxlX2RhdGEoKSB7CisgIHJldHVybiBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6bXV0YWJsZV9kYXRhPFR5cGVIYW5kbGVyPigpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSBjb25zdCBFbGVtZW50KiBjb25zdCogUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6ZGF0YSgpIGNvbnN0IHsKKyAgcmV0dXJuIFJlcGVhdGVkUHRyRmllbGRCYXNlOjpkYXRhPFR5cGVIYW5kbGVyPigpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSB2b2lkIFJlcGVhdGVkUHRyRmllbGQ8RWxlbWVudD46OlN3YXAoUmVwZWF0ZWRQdHJGaWVsZCogb3RoZXIpIHsKKyAgaWYgKHRoaXMgPT0gb3RoZXIpCisgICAgcmV0dXJuOworICBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6U3dhcDxUeXBlSGFuZGxlcj4ob3RoZXIpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSB2b2lkIFJlcGVhdGVkUHRyRmllbGQ8RWxlbWVudD46OlVuc2FmZUFyZW5hU3dhcCgKKyAgICBSZXBlYXRlZFB0ckZpZWxkKiBvdGhlcikgeworICBHT09HTEVfRENIRUNLKEdldEFyZW5hTm9WaXJ0dWFsKCkgPT0gb3RoZXItPkdldEFyZW5hTm9WaXJ0dWFsKCkpOworICBpZiAodGhpcyA9PSBvdGhlcikKKyAgICAgIHJldHVybjsKKyAgUmVwZWF0ZWRQdHJGaWVsZEJhc2U6OkludGVybmFsU3dhcChvdGhlcik7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIHZvaWQgUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6U3dhcEVsZW1lbnRzKGludCBpbmRleDEsIGludCBpbmRleDIpIHsKKyAgUmVwZWF0ZWRQdHJGaWVsZEJhc2U6OlN3YXBFbGVtZW50cyhpbmRleDEsIGluZGV4Mik7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIEFyZW5hKiBSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+OjpHZXRBcmVuYU5vVmlydHVhbCgpIGNvbnN0IHsKKyAgcmV0dXJuIFJlcGVhdGVkUHRyRmllbGRCYXNlOjpHZXRBcmVuYU5vVmlydHVhbCgpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSBpbnQgUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6U3BhY2VVc2VkRXhjbHVkaW5nU2VsZigpIGNvbnN0IHsKKyAgcmV0dXJuIFJlcGVhdGVkUHRyRmllbGRCYXNlOjpTcGFjZVVzZWRFeGNsdWRpbmdTZWxmPFR5cGVIYW5kbGVyPigpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSB2b2lkIFJlcGVhdGVkUHRyRmllbGQ8RWxlbWVudD46OkFkZEFsbG9jYXRlZChFbGVtZW50KiB2YWx1ZSkgeworICBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6QWRkQWxsb2NhdGVkPFR5cGVIYW5kbGVyPih2YWx1ZSk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIHZvaWQgUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6VW5zYWZlQXJlbmFBZGRBbGxvY2F0ZWQoRWxlbWVudCogdmFsdWUpIHsKKyAgUmVwZWF0ZWRQdHJGaWVsZEJhc2U6OlVuc2FmZUFyZW5hQWRkQWxsb2NhdGVkPFR5cGVIYW5kbGVyPih2YWx1ZSk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIEVsZW1lbnQqIFJlcGVhdGVkUHRyRmllbGQ8RWxlbWVudD46OlJlbGVhc2VMYXN0KCkgeworICByZXR1cm4gUmVwZWF0ZWRQdHJGaWVsZEJhc2U6OlJlbGVhc2VMYXN0PFR5cGVIYW5kbGVyPigpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSBFbGVtZW50KiBSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+OjpVbnNhZmVBcmVuYVJlbGVhc2VMYXN0KCkgeworICByZXR1cm4gUmVwZWF0ZWRQdHJGaWVsZEJhc2U6OlVuc2FmZUFyZW5hUmVsZWFzZUxhc3Q8VHlwZUhhbmRsZXI+KCk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIGludCBSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+OjpDbGVhcmVkQ291bnQoKSBjb25zdCB7CisgIHJldHVybiBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6Q2xlYXJlZENvdW50KCk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIHZvaWQgUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6QWRkQ2xlYXJlZChFbGVtZW50KiB2YWx1ZSkgeworICByZXR1cm4gUmVwZWF0ZWRQdHJGaWVsZEJhc2U6OkFkZENsZWFyZWQ8VHlwZUhhbmRsZXI+KHZhbHVlKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgRWxlbWVudCogUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6UmVsZWFzZUNsZWFyZWQoKSB7CisgIHJldHVybiBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6UmVsZWFzZUNsZWFyZWQ8VHlwZUhhbmRsZXI+KCk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIHZvaWQgUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6UmVzZXJ2ZShpbnQgbmV3X3NpemUpIHsKKyAgcmV0dXJuIFJlcGVhdGVkUHRyRmllbGRCYXNlOjpSZXNlcnZlKG5ld19zaXplKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgaW50IFJlcGVhdGVkUHRyRmllbGQ8RWxlbWVudD46OkNhcGFjaXR5KCkgY29uc3QgeworICByZXR1cm4gUmVwZWF0ZWRQdHJGaWVsZEJhc2U6OkNhcGFjaXR5KCk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworbmFtZXNwYWNlIGludGVybmFsIHsKKworLy8gU1RMLWxpa2UgaXRlcmF0b3IgaW1wbGVtZW50YXRpb24gZm9yIFJlcGVhdGVkUHRyRmllbGQuICBZb3Ugc2hvdWxkIG5vdAorLy8gcmVmZXIgdG8gdGhpcyBjbGFzcyBkaXJlY3RseTsgdXNlIFJlcGVhdGVkUHRyRmllbGQ8VD46Oml0ZXJhdG9yIGluc3RlYWQuCisvLworLy8gVGhlIGl0ZXJhdG9yIGZvciBSZXBlYXRlZFB0ckZpZWxkPFQ+LCBSZXBlYXRlZFB0ckl0ZXJhdG9yPFQ+LCBpcworLy8gdmVyeSBzaW1pbGFyIHRvIGl0ZXJhdG9yX3B0cjxUKio+IGluIHV0aWwvZ3RsL2l0ZXJhdG9yX2FkYXB0b3JzLmgsCisvLyBidXQgYWRkcyByYW5kb20tYWNjZXNzIG9wZXJhdG9ycyBhbmQgaXMgbW9kaWZpZWQgdG8gd3JhcCBhIHZvaWQqKiBiYXNlCisvLyBpdGVyYXRvciAoc2luY2UgUmVwZWF0ZWRQdHJGaWVsZCBzdG9yZXMgaXRzIGFycmF5IGFzIGEgdm9pZCogYXJyYXkgYW5kCisvLyBjYXN0aW5nIHZvaWQqKiB0byBUKiogd291bGQgdmlvbGF0ZSBDKysgYWxpYXNpbmcgcnVsZXMpLgorLy8KKy8vIFRoaXMgY29kZSBiYXNlZCBvbiBuZXQvcHJvdG8vcHJvdG8tYXJyYXktaW50ZXJuYWwuaCBieSBKZWZmcmV5IFlhc3NraW4KKy8vIChqeWFzc2tpbkBnb29nbGUuY29tKS4KK3RlbXBsYXRlPHR5cGVuYW1lIEVsZW1lbnQ+CitjbGFzcyBSZXBlYXRlZFB0ckl0ZXJhdG9yCisgICAgOiBwdWJsaWMgc3RkOjppdGVyYXRvcjwKKyAgICAgICAgICBzdGQ6OnJhbmRvbV9hY2Nlc3NfaXRlcmF0b3JfdGFnLCBFbGVtZW50PiB7CisgcHVibGljOgorICB0eXBlZGVmIFJlcGVhdGVkUHRySXRlcmF0b3I8RWxlbWVudD4gaXRlcmF0b3I7CisgIHR5cGVkZWYgc3RkOjppdGVyYXRvcjwKKyAgICAgICAgICBzdGQ6OnJhbmRvbV9hY2Nlc3NfaXRlcmF0b3JfdGFnLCBFbGVtZW50PiBzdXBlcmNsYXNzOworCisgIC8vIFNoYWRvdyB0aGUgdmFsdWVfdHlwZSBpbiBzdGQ6Oml0ZXJhdG9yPD4gYmVjYXVzZSBjb25zdF9pdGVyYXRvcjo6dmFsdWVfdHlwZQorICAvLyBuZWVkcyB0byBiZSBULCBub3QgY29uc3QgVC4KKyAgdHlwZWRlZiB0eXBlbmFtZSByZW1vdmVfY29uc3Q8RWxlbWVudD46OnR5cGUgdmFsdWVfdHlwZTsKKworICAvLyBMZXQgdGhlIGNvbXBpbGVyIGtub3cgdGhhdCB0aGVzZSBhcmUgdHlwZSBuYW1lcywgc28gd2UgZG9uJ3QgaGF2ZSB0bworICAvLyB3cml0ZSAidHlwZW5hbWUiIGluIGZyb250IG9mIHRoZW0gZXZlcnl3aGVyZS4KKyAgdHlwZWRlZiB0eXBlbmFtZSBzdXBlcmNsYXNzOjpyZWZlcmVuY2UgcmVmZXJlbmNlOworICB0eXBlZGVmIHR5cGVuYW1lIHN1cGVyY2xhc3M6OnBvaW50ZXIgcG9pbnRlcjsKKyAgdHlwZWRlZiB0eXBlbmFtZSBzdXBlcmNsYXNzOjpkaWZmZXJlbmNlX3R5cGUgZGlmZmVyZW5jZV90eXBlOworCisgIFJlcGVhdGVkUHRySXRlcmF0b3IoKSA6IGl0XyhOVUxMKSB7fQorICBleHBsaWNpdCBSZXBlYXRlZFB0ckl0ZXJhdG9yKHZvaWQqIGNvbnN0KiBpdCkgOiBpdF8oaXQpIHt9CisKKyAgLy8gQWxsb3cgInVwY2FzdGluZyIgZnJvbSBSZXBlYXRlZFB0ckl0ZXJhdG9yPFQqKj4gdG8KKyAgLy8gUmVwZWF0ZWRQdHJJdGVyYXRvcjxjb25zdCBUKmNvbnN0Kj4uCisgIHRlbXBsYXRlPHR5cGVuYW1lIE90aGVyRWxlbWVudD4KKyAgUmVwZWF0ZWRQdHJJdGVyYXRvcihjb25zdCBSZXBlYXRlZFB0ckl0ZXJhdG9yPE90aGVyRWxlbWVudD4mIG90aGVyKQorICAgICAgOiBpdF8ob3RoZXIuaXRfKSB7CisgICAgLy8gRm9yY2UgYSBjb21waWxlciBlcnJvciBpZiB0aGUgb3RoZXIgdHlwZSBpcyBub3QgY29udmVydGlibGUgdG8gb3Vycy4KKyAgICBpZiAoZmFsc2UpIHsKKyAgICAgIGltcGxpY2l0X2Nhc3Q8RWxlbWVudCosIE90aGVyRWxlbWVudCo+KDApOworICAgIH0KKyAgfQorCisgIC8vIGRlcmVmZXJlbmNlYWJsZQorICByZWZlcmVuY2Ugb3BlcmF0b3IqKCkgY29uc3QgeyByZXR1cm4gKnJlaW50ZXJwcmV0X2Nhc3Q8RWxlbWVudCo+KCppdF8pOyB9CisgIHBvaW50ZXIgICBvcGVyYXRvci0+KCkgY29uc3QgeyByZXR1cm4gJihvcGVyYXRvciooKSk7IH0KKworICAvLyB7aW5jLGRlY31yZW1lbnRhYmxlCisgIGl0ZXJhdG9yJiBvcGVyYXRvcisrKCkgeyArK2l0XzsgcmV0dXJuICp0aGlzOyB9CisgIGl0ZXJhdG9yICBvcGVyYXRvcisrKGludCkgeyByZXR1cm4gaXRlcmF0b3IoaXRfKyspOyB9CisgIGl0ZXJhdG9yJiBvcGVyYXRvci0tKCkgeyAtLWl0XzsgcmV0dXJuICp0aGlzOyB9CisgIGl0ZXJhdG9yICBvcGVyYXRvci0tKGludCkgeyByZXR1cm4gaXRlcmF0b3IoaXRfLS0pOyB9CisKKyAgLy8gZXF1YWxpdHlfY29tcGFyYWJsZQorICBib29sIG9wZXJhdG9yPT0oY29uc3QgaXRlcmF0b3ImIHgpIGNvbnN0IHsgcmV0dXJuIGl0XyA9PSB4Lml0XzsgfQorICBib29sIG9wZXJhdG9yIT0oY29uc3QgaXRlcmF0b3ImIHgpIGNvbnN0IHsgcmV0dXJuIGl0XyAhPSB4Lml0XzsgfQorCisgIC8vIGxlc3NfdGhhbl9jb21wYXJhYmxlCisgIGJvb2wgb3BlcmF0b3I8KGNvbnN0IGl0ZXJhdG9yJiB4KSBjb25zdCB7IHJldHVybiBpdF8gPCB4Lml0XzsgfQorICBib29sIG9wZXJhdG9yPD0oY29uc3QgaXRlcmF0b3ImIHgpIGNvbnN0IHsgcmV0dXJuIGl0XyA8PSB4Lml0XzsgfQorICBib29sIG9wZXJhdG9yPihjb25zdCBpdGVyYXRvciYgeCkgY29uc3QgeyByZXR1cm4gaXRfID4geC5pdF87IH0KKyAgYm9vbCBvcGVyYXRvcj49KGNvbnN0IGl0ZXJhdG9yJiB4KSBjb25zdCB7IHJldHVybiBpdF8gPj0geC5pdF87IH0KKworICAvLyBhZGRhYmxlLCBzdWJ0cmFjdGFibGUKKyAgaXRlcmF0b3ImIG9wZXJhdG9yKz0oZGlmZmVyZW5jZV90eXBlIGQpIHsKKyAgICBpdF8gKz0gZDsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKyAgZnJpZW5kIGl0ZXJhdG9yIG9wZXJhdG9yKyhpdGVyYXRvciBpdCwgY29uc3QgZGlmZmVyZW5jZV90eXBlIGQpIHsKKyAgICBpdCArPSBkOworICAgIHJldHVybiBpdDsKKyAgfQorICBmcmllbmQgaXRlcmF0b3Igb3BlcmF0b3IrKGNvbnN0IGRpZmZlcmVuY2VfdHlwZSBkLCBpdGVyYXRvciBpdCkgeworICAgIGl0ICs9IGQ7CisgICAgcmV0dXJuIGl0OworICB9CisgIGl0ZXJhdG9yJiBvcGVyYXRvci09KGRpZmZlcmVuY2VfdHlwZSBkKSB7CisgICAgaXRfIC09IGQ7CisgICAgcmV0dXJuICp0aGlzOworICB9CisgIGZyaWVuZCBpdGVyYXRvciBvcGVyYXRvci0oaXRlcmF0b3IgaXQsIGRpZmZlcmVuY2VfdHlwZSBkKSB7CisgICAgaXQgLT0gZDsKKyAgICByZXR1cm4gaXQ7CisgIH0KKworICAvLyBpbmRleGFibGUKKyAgcmVmZXJlbmNlIG9wZXJhdG9yW10oZGlmZmVyZW5jZV90eXBlIGQpIGNvbnN0IHsgcmV0dXJuICooKnRoaXMgKyBkKTsgfQorCisgIC8vIHJhbmRvbSBhY2Nlc3MgaXRlcmF0b3IKKyAgZGlmZmVyZW5jZV90eXBlIG9wZXJhdG9yLShjb25zdCBpdGVyYXRvciYgeCkgY29uc3QgeyByZXR1cm4gaXRfIC0geC5pdF87IH0KKworIHByaXZhdGU6CisgIHRlbXBsYXRlPHR5cGVuYW1lIE90aGVyRWxlbWVudD4KKyAgZnJpZW5kIGNsYXNzIFJlcGVhdGVkUHRySXRlcmF0b3I7CisKKyAgLy8gVGhlIGludGVybmFsIGl0ZXJhdG9yLgorICB2b2lkKiBjb25zdCogaXRfOworfTsKKworLy8gUHJvdmlkZSBhbiBpdGVyYXRvciB0aGF0IG9wZXJhdGVzIG9uIHBvaW50ZXJzIHRvIHRoZSB1bmRlcmx5aW5nIG9iamVjdHMKKy8vIHJhdGhlciB0aGFuIHRoZSBvYmplY3RzIHRoZW1zZWx2ZXMgYXMgUmVwZWF0ZWRQdHJJdGVyYXRvciBkb2VzLgorLy8gQ29uc2lkZXIgdXNpbmcgdGhpcyB3aGVuIHdvcmtpbmcgd2l0aCBzdGwgYWxnb3JpdGhtcyB0aGF0IGNoYW5nZQorLy8gdGhlIGFycmF5LgorLy8gVGhlIFZvaWRQdHIgdGVtcGxhdGUgcGFyYW1ldGVyIGhvbGRzIHRoZSB0eXBlLWFnbm9zdGljIHBvaW50ZXIgdmFsdWUKKy8vIHJlZmVyZW5jZWQgYnkgdGhlIGl0ZXJhdG9yLiAgSXQgc2hvdWxkIGVpdGhlciBiZSAidm9pZCAqIiBmb3IgYSBtdXRhYmxlCisvLyBpdGVyYXRvciwgb3IgImNvbnN0IHZvaWQgKiIgZm9yIGEgY29uc3RhbnQgaXRlcmF0b3IuCit0ZW1wbGF0ZTx0eXBlbmFtZSBFbGVtZW50LCB0eXBlbmFtZSBWb2lkUHRyPgorY2xhc3MgUmVwZWF0ZWRQdHJPdmVyUHRyc0l0ZXJhdG9yCisgICAgOiBwdWJsaWMgc3RkOjppdGVyYXRvcjxzdGQ6OnJhbmRvbV9hY2Nlc3NfaXRlcmF0b3JfdGFnLCBFbGVtZW50Kj4geworIHB1YmxpYzoKKyAgdHlwZWRlZiBSZXBlYXRlZFB0ck92ZXJQdHJzSXRlcmF0b3I8RWxlbWVudCwgVm9pZFB0cj4gaXRlcmF0b3I7CisgIHR5cGVkZWYgc3RkOjppdGVyYXRvcjwKKyAgICAgICAgICBzdGQ6OnJhbmRvbV9hY2Nlc3NfaXRlcmF0b3JfdGFnLCBFbGVtZW50Kj4gc3VwZXJjbGFzczsKKworICAvLyBTaGFkb3cgdGhlIHZhbHVlX3R5cGUgaW4gc3RkOjppdGVyYXRvcjw+IGJlY2F1c2UgY29uc3RfaXRlcmF0b3I6OnZhbHVlX3R5cGUKKyAgLy8gbmVlZHMgdG8gYmUgVCwgbm90IGNvbnN0IFQuCisgIHR5cGVkZWYgdHlwZW5hbWUgcmVtb3ZlX2NvbnN0PEVsZW1lbnQqPjo6dHlwZSB2YWx1ZV90eXBlOworCisgIC8vIExldCB0aGUgY29tcGlsZXIga25vdyB0aGF0IHRoZXNlIGFyZSB0eXBlIG5hbWVzLCBzbyB3ZSBkb24ndCBoYXZlIHRvCisgIC8vIHdyaXRlICJ0eXBlbmFtZSIgaW4gZnJvbnQgb2YgdGhlbSBldmVyeXdoZXJlLgorICB0eXBlZGVmIHR5cGVuYW1lIHN1cGVyY2xhc3M6OnJlZmVyZW5jZSByZWZlcmVuY2U7CisgIHR5cGVkZWYgdHlwZW5hbWUgc3VwZXJjbGFzczo6cG9pbnRlciBwb2ludGVyOworICB0eXBlZGVmIHR5cGVuYW1lIHN1cGVyY2xhc3M6OmRpZmZlcmVuY2VfdHlwZSBkaWZmZXJlbmNlX3R5cGU7CisKKyAgUmVwZWF0ZWRQdHJPdmVyUHRyc0l0ZXJhdG9yKCkgOiBpdF8oTlVMTCkge30KKyAgZXhwbGljaXQgUmVwZWF0ZWRQdHJPdmVyUHRyc0l0ZXJhdG9yKFZvaWRQdHIqIGl0KSA6IGl0XyhpdCkge30KKworICAvLyBkZXJlZmVyZW5jZWFibGUKKyAgcmVmZXJlbmNlIG9wZXJhdG9yKigpIGNvbnN0IHsgcmV0dXJuICpyZWludGVycHJldF9jYXN0PEVsZW1lbnQqKj4oaXRfKTsgfQorICBwb2ludGVyICAgb3BlcmF0b3ItPigpIGNvbnN0IHsgcmV0dXJuICYob3BlcmF0b3IqKCkpOyB9CisKKyAgLy8ge2luYyxkZWN9cmVtZW50YWJsZQorICBpdGVyYXRvciYgb3BlcmF0b3IrKygpIHsgKytpdF87IHJldHVybiAqdGhpczsgfQorICBpdGVyYXRvciAgb3BlcmF0b3IrKyhpbnQpIHsgcmV0dXJuIGl0ZXJhdG9yKGl0XysrKTsgfQorICBpdGVyYXRvciYgb3BlcmF0b3ItLSgpIHsgLS1pdF87IHJldHVybiAqdGhpczsgfQorICBpdGVyYXRvciAgb3BlcmF0b3ItLShpbnQpIHsgcmV0dXJuIGl0ZXJhdG9yKGl0Xy0tKTsgfQorCisgIC8vIGVxdWFsaXR5X2NvbXBhcmFibGUKKyAgYm9vbCBvcGVyYXRvcj09KGNvbnN0IGl0ZXJhdG9yJiB4KSBjb25zdCB7IHJldHVybiBpdF8gPT0geC5pdF87IH0KKyAgYm9vbCBvcGVyYXRvciE9KGNvbnN0IGl0ZXJhdG9yJiB4KSBjb25zdCB7IHJldHVybiBpdF8gIT0geC5pdF87IH0KKworICAvLyBsZXNzX3RoYW5fY29tcGFyYWJsZQorICBib29sIG9wZXJhdG9yPChjb25zdCBpdGVyYXRvciYgeCkgY29uc3QgeyByZXR1cm4gaXRfIDwgeC5pdF87IH0KKyAgYm9vbCBvcGVyYXRvcjw9KGNvbnN0IGl0ZXJhdG9yJiB4KSBjb25zdCB7IHJldHVybiBpdF8gPD0geC5pdF87IH0KKyAgYm9vbCBvcGVyYXRvcj4oY29uc3QgaXRlcmF0b3ImIHgpIGNvbnN0IHsgcmV0dXJuIGl0XyA+IHguaXRfOyB9CisgIGJvb2wgb3BlcmF0b3I+PShjb25zdCBpdGVyYXRvciYgeCkgY29uc3QgeyByZXR1cm4gaXRfID49IHguaXRfOyB9CisKKyAgLy8gYWRkYWJsZSwgc3VidHJhY3RhYmxlCisgIGl0ZXJhdG9yJiBvcGVyYXRvcis9KGRpZmZlcmVuY2VfdHlwZSBkKSB7CisgICAgaXRfICs9IGQ7CisgICAgcmV0dXJuICp0aGlzOworICB9CisgIGZyaWVuZCBpdGVyYXRvciBvcGVyYXRvcisoaXRlcmF0b3IgaXQsIGRpZmZlcmVuY2VfdHlwZSBkKSB7CisgICAgaXQgKz0gZDsKKyAgICByZXR1cm4gaXQ7CisgIH0KKyAgZnJpZW5kIGl0ZXJhdG9yIG9wZXJhdG9yKyhkaWZmZXJlbmNlX3R5cGUgZCwgaXRlcmF0b3IgaXQpIHsKKyAgICBpdCArPSBkOworICAgIHJldHVybiBpdDsKKyAgfQorICBpdGVyYXRvciYgb3BlcmF0b3ItPShkaWZmZXJlbmNlX3R5cGUgZCkgeworICAgIGl0XyAtPSBkOworICAgIHJldHVybiAqdGhpczsKKyAgfQorICBmcmllbmQgaXRlcmF0b3Igb3BlcmF0b3ItKGl0ZXJhdG9yIGl0LCBkaWZmZXJlbmNlX3R5cGUgZCkgeworICAgIGl0IC09IGQ7CisgICAgcmV0dXJuIGl0OworICB9CisKKyAgLy8gaW5kZXhhYmxlCisgIHJlZmVyZW5jZSBvcGVyYXRvcltdKGRpZmZlcmVuY2VfdHlwZSBkKSBjb25zdCB7IHJldHVybiAqKCp0aGlzICsgZCk7IH0KKworICAvLyByYW5kb20gYWNjZXNzIGl0ZXJhdG9yCisgIGRpZmZlcmVuY2VfdHlwZSBvcGVyYXRvci0oY29uc3QgaXRlcmF0b3ImIHgpIGNvbnN0IHsgcmV0dXJuIGl0XyAtIHguaXRfOyB9CisKKyBwcml2YXRlOgorICB0ZW1wbGF0ZTx0eXBlbmFtZSBPdGhlckVsZW1lbnQ+CisgIGZyaWVuZCBjbGFzcyBSZXBlYXRlZFB0ckl0ZXJhdG9yOworCisgIC8vIFRoZSBpbnRlcm5hbCBpdGVyYXRvci4KKyAgVm9pZFB0ciogaXRfOworfTsKKwordm9pZCBSZXBlYXRlZFB0ckZpZWxkQmFzZTo6SW50ZXJuYWxTd2FwKFJlcGVhdGVkUHRyRmllbGRCYXNlKiBvdGhlcikgeworICBzdGQ6OnN3YXAocmVwXywgb3RoZXItPnJlcF8pOworICBzdGQ6OnN3YXAoY3VycmVudF9zaXplXywgb3RoZXItPmN1cnJlbnRfc2l6ZV8pOworICBzdGQ6OnN3YXAodG90YWxfc2l6ZV8sIG90aGVyLT50b3RhbF9zaXplXyk7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSB0eXBlbmFtZSBSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+OjppdGVyYXRvcgorUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6YmVnaW4oKSB7CisgIHJldHVybiBpdGVyYXRvcihyYXdfZGF0YSgpKTsKK30KK3RlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50PgoraW5saW5lIHR5cGVuYW1lIFJlcGVhdGVkUHRyRmllbGQ8RWxlbWVudD46OmNvbnN0X2l0ZXJhdG9yCitSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+OjpiZWdpbigpIGNvbnN0IHsKKyAgcmV0dXJuIGl0ZXJhdG9yKHJhd19kYXRhKCkpOworfQordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgdHlwZW5hbWUgUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6Y29uc3RfaXRlcmF0b3IKK1JlcGVhdGVkUHRyRmllbGQ8RWxlbWVudD46OmNiZWdpbigpIGNvbnN0IHsKKyAgcmV0dXJuIGJlZ2luKCk7Cit9Cit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSB0eXBlbmFtZSBSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+OjppdGVyYXRvcgorUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6ZW5kKCkgeworICByZXR1cm4gaXRlcmF0b3IocmF3X2RhdGEoKSArIHNpemUoKSk7Cit9Cit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSB0eXBlbmFtZSBSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+Ojpjb25zdF9pdGVyYXRvcgorUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6ZW5kKCkgY29uc3QgeworICByZXR1cm4gaXRlcmF0b3IocmF3X2RhdGEoKSArIHNpemUoKSk7Cit9Cit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSB0eXBlbmFtZSBSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+Ojpjb25zdF9pdGVyYXRvcgorUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6Y2VuZCgpIGNvbnN0IHsKKyAgcmV0dXJuIGVuZCgpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSB0eXBlbmFtZSBSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+Ojpwb2ludGVyX2l0ZXJhdG9yCitSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+Ojpwb2ludGVyX2JlZ2luKCkgeworICByZXR1cm4gcG9pbnRlcl9pdGVyYXRvcihyYXdfbXV0YWJsZV9kYXRhKCkpOworfQordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgdHlwZW5hbWUgUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6Y29uc3RfcG9pbnRlcl9pdGVyYXRvcgorUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6cG9pbnRlcl9iZWdpbigpIGNvbnN0IHsKKyAgcmV0dXJuIGNvbnN0X3BvaW50ZXJfaXRlcmF0b3IoY29uc3RfY2FzdDxjb25zdCB2b2lkKio+KHJhd19tdXRhYmxlX2RhdGEoKSkpOworfQordGVtcGxhdGUgPHR5cGVuYW1lIEVsZW1lbnQ+CitpbmxpbmUgdHlwZW5hbWUgUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6cG9pbnRlcl9pdGVyYXRvcgorUmVwZWF0ZWRQdHJGaWVsZDxFbGVtZW50Pjo6cG9pbnRlcl9lbmQoKSB7CisgIHJldHVybiBwb2ludGVyX2l0ZXJhdG9yKHJhd19tdXRhYmxlX2RhdGEoKSArIHNpemUoKSk7Cit9Cit0ZW1wbGF0ZSA8dHlwZW5hbWUgRWxlbWVudD4KK2lubGluZSB0eXBlbmFtZSBSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+Ojpjb25zdF9wb2ludGVyX2l0ZXJhdG9yCitSZXBlYXRlZFB0ckZpZWxkPEVsZW1lbnQ+Ojpwb2ludGVyX2VuZCgpIGNvbnN0IHsKKyAgcmV0dXJuIGNvbnN0X3BvaW50ZXJfaXRlcmF0b3IoCisgICAgICBjb25zdF9jYXN0PGNvbnN0IHZvaWQqKj4ocmF3X211dGFibGVfZGF0YSgpICsgc2l6ZSgpKSk7Cit9CisKKworLy8gSXRlcmF0b3JzIGFuZCBoZWxwZXIgZnVuY3Rpb25zIHRoYXQgZm9sbG93IHRoZSBzcGlyaXQgb2YgdGhlIFNUTAorLy8gc3RkOjpiYWNrX2luc2VydF9pdGVyYXRvciBhbmQgc3RkOjpiYWNrX2luc2VydGVyIGJ1dCBhcmUgdGFpbG9yLW1hZGUKKy8vIGZvciBSZXBlYXRlZEZpZWxkIGFuZCBSZXBlYXRlZFB0ckZpZWxkLiBUeXBpY2FsIHVzYWdlIHdvdWxkIGJlOgorLy8KKy8vICAgc3RkOjpjb3B5KHNvbWVfc2VxdWVuY2UuYmVnaW4oKSwgc29tZV9zZXF1ZW5jZS5lbmQoKSwKKy8vICAgICAgICAgICAgIGdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkRmllbGRCYWNrSW5zZXJ0ZXIocHJvdG8ubXV0YWJsZV9zZXF1ZW5jZSgpKSk7CisvLworLy8gUG9ydGVkIGJ5IGpvaGFubmVzIGZyb20gdXRpbC9ndGwvcHJvdG8tYXJyYXktaXRlcmF0b3JzLmgKKworbmFtZXNwYWNlIGludGVybmFsIHsKKy8vIEEgYmFjayBpbnNlcnRlciBmb3IgUmVwZWF0ZWRGaWVsZCBvYmplY3RzLgordGVtcGxhdGU8dHlwZW5hbWUgVD4gY2xhc3MgUmVwZWF0ZWRGaWVsZEJhY2tJbnNlcnRJdGVyYXRvcgorICAgIDogcHVibGljIHN0ZDo6aXRlcmF0b3I8c3RkOjpvdXRwdXRfaXRlcmF0b3JfdGFnLCBUPiB7CisgcHVibGljOgorICBleHBsaWNpdCBSZXBlYXRlZEZpZWxkQmFja0luc2VydEl0ZXJhdG9yKAorICAgICAgUmVwZWF0ZWRGaWVsZDxUPiogY29uc3QgbXV0YWJsZV9maWVsZCkKKyAgICAgIDogZmllbGRfKG11dGFibGVfZmllbGQpIHsKKyAgfQorICBSZXBlYXRlZEZpZWxkQmFja0luc2VydEl0ZXJhdG9yPFQ+JiBvcGVyYXRvcj0oY29uc3QgVCYgdmFsdWUpIHsKKyAgICBmaWVsZF8tPkFkZCh2YWx1ZSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisgIFJlcGVhdGVkRmllbGRCYWNrSW5zZXJ0SXRlcmF0b3I8VD4mIG9wZXJhdG9yKigpIHsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKyAgUmVwZWF0ZWRGaWVsZEJhY2tJbnNlcnRJdGVyYXRvcjxUPiYgb3BlcmF0b3IrKygpIHsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKyAgUmVwZWF0ZWRGaWVsZEJhY2tJbnNlcnRJdGVyYXRvcjxUPiYgb3BlcmF0b3IrKyhpbnQgLyogdW51c2VkICovKSB7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyBwcml2YXRlOgorICBSZXBlYXRlZEZpZWxkPFQ+KiBmaWVsZF87Cit9OworCisvLyBBIGJhY2sgaW5zZXJ0ZXIgZm9yIFJlcGVhdGVkUHRyRmllbGQgb2JqZWN0cy4KK3RlbXBsYXRlPHR5cGVuYW1lIFQ+IGNsYXNzIFJlcGVhdGVkUHRyRmllbGRCYWNrSW5zZXJ0SXRlcmF0b3IKKyAgICA6IHB1YmxpYyBzdGQ6Oml0ZXJhdG9yPHN0ZDo6b3V0cHV0X2l0ZXJhdG9yX3RhZywgVD4geworIHB1YmxpYzoKKyAgUmVwZWF0ZWRQdHJGaWVsZEJhY2tJbnNlcnRJdGVyYXRvcigKKyAgICAgIFJlcGVhdGVkUHRyRmllbGQ8VD4qIGNvbnN0IG11dGFibGVfZmllbGQpCisgICAgICA6IGZpZWxkXyhtdXRhYmxlX2ZpZWxkKSB7CisgIH0KKyAgUmVwZWF0ZWRQdHJGaWVsZEJhY2tJbnNlcnRJdGVyYXRvcjxUPiYgb3BlcmF0b3I9KGNvbnN0IFQmIHZhbHVlKSB7CisgICAgKmZpZWxkXy0+QWRkKCkgPSB2YWx1ZTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKyAgUmVwZWF0ZWRQdHJGaWVsZEJhY2tJbnNlcnRJdGVyYXRvcjxUPiYgb3BlcmF0b3I9KAorICAgICAgY29uc3QgVCogY29uc3QgcHRyX3RvX3ZhbHVlKSB7CisgICAgKmZpZWxkXy0+QWRkKCkgPSAqcHRyX3RvX3ZhbHVlOworICAgIHJldHVybiAqdGhpczsKKyAgfQorICBSZXBlYXRlZFB0ckZpZWxkQmFja0luc2VydEl0ZXJhdG9yPFQ+JiBvcGVyYXRvciooKSB7CisgICAgcmV0dXJuICp0aGlzOworICB9CisgIFJlcGVhdGVkUHRyRmllbGRCYWNrSW5zZXJ0SXRlcmF0b3I8VD4mIG9wZXJhdG9yKysoKSB7CisgICAgcmV0dXJuICp0aGlzOworICB9CisgIFJlcGVhdGVkUHRyRmllbGRCYWNrSW5zZXJ0SXRlcmF0b3I8VD4mIG9wZXJhdG9yKysoaW50IC8qIHVudXNlZCAqLykgeworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgcHJpdmF0ZToKKyAgUmVwZWF0ZWRQdHJGaWVsZDxUPiogZmllbGRfOworfTsKKworLy8gQSBiYWNrIGluc2VydGVyIGZvciBSZXBlYXRlZFB0ckZpZWxkcyB0aGF0IGluc2VydHMgYnkgdHJhbnNmZXJpbmcgb3duZXJzaGlwCisvLyBvZiBhIHBvaW50ZXIuCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPiBjbGFzcyBBbGxvY2F0ZWRSZXBlYXRlZFB0ckZpZWxkQmFja0luc2VydEl0ZXJhdG9yCisgICAgOiBwdWJsaWMgc3RkOjppdGVyYXRvcjxzdGQ6Om91dHB1dF9pdGVyYXRvcl90YWcsIFQ+IHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IEFsbG9jYXRlZFJlcGVhdGVkUHRyRmllbGRCYWNrSW5zZXJ0SXRlcmF0b3IoCisgICAgICBSZXBlYXRlZFB0ckZpZWxkPFQ+KiBjb25zdCBtdXRhYmxlX2ZpZWxkKQorICAgICAgOiBmaWVsZF8obXV0YWJsZV9maWVsZCkgeworICB9CisgIEFsbG9jYXRlZFJlcGVhdGVkUHRyRmllbGRCYWNrSW5zZXJ0SXRlcmF0b3I8VD4mIG9wZXJhdG9yPSgKKyAgICAgIFQqIGNvbnN0IHB0cl90b192YWx1ZSkgeworICAgIGZpZWxkXy0+QWRkQWxsb2NhdGVkKHB0cl90b192YWx1ZSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisgIEFsbG9jYXRlZFJlcGVhdGVkUHRyRmllbGRCYWNrSW5zZXJ0SXRlcmF0b3I8VD4mIG9wZXJhdG9yKigpIHsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKyAgQWxsb2NhdGVkUmVwZWF0ZWRQdHJGaWVsZEJhY2tJbnNlcnRJdGVyYXRvcjxUPiYgb3BlcmF0b3IrKygpIHsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKyAgQWxsb2NhdGVkUmVwZWF0ZWRQdHJGaWVsZEJhY2tJbnNlcnRJdGVyYXRvcjxUPiYgb3BlcmF0b3IrKygKKyAgICAgIGludCAvKiB1bnVzZWQgKi8pIHsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworIHByaXZhdGU6CisgIFJlcGVhdGVkUHRyRmllbGQ8VD4qIGZpZWxkXzsKK307Cit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKKworLy8gUHJvdmlkZXMgYSBiYWNrIGluc2VydCBpdGVyYXRvciBmb3IgUmVwZWF0ZWRGaWVsZCBpbnN0YW5jZXMsCisvLyBzaW1pbGFyIHRvIHN0ZDo6YmFja19pbnNlcnRlcigpLgordGVtcGxhdGU8dHlwZW5hbWUgVD4gaW50ZXJuYWw6OlJlcGVhdGVkRmllbGRCYWNrSW5zZXJ0SXRlcmF0b3I8VD4KK1JlcGVhdGVkRmllbGRCYWNrSW5zZXJ0ZXIoUmVwZWF0ZWRGaWVsZDxUPiogY29uc3QgbXV0YWJsZV9maWVsZCkgeworICByZXR1cm4gaW50ZXJuYWw6OlJlcGVhdGVkRmllbGRCYWNrSW5zZXJ0SXRlcmF0b3I8VD4obXV0YWJsZV9maWVsZCk7Cit9CisKKy8vIFByb3ZpZGVzIGEgYmFjayBpbnNlcnQgaXRlcmF0b3IgZm9yIFJlcGVhdGVkUHRyRmllbGQgaW5zdGFuY2VzLAorLy8gc2ltaWxhciB0byBzdGQ6OmJhY2tfaW5zZXJ0ZXIoKS4KK3RlbXBsYXRlPHR5cGVuYW1lIFQ+IGludGVybmFsOjpSZXBlYXRlZFB0ckZpZWxkQmFja0luc2VydEl0ZXJhdG9yPFQ+CitSZXBlYXRlZFB0ckZpZWxkQmFja0luc2VydGVyKFJlcGVhdGVkUHRyRmllbGQ8VD4qIGNvbnN0IG11dGFibGVfZmllbGQpIHsKKyAgcmV0dXJuIGludGVybmFsOjpSZXBlYXRlZFB0ckZpZWxkQmFja0luc2VydEl0ZXJhdG9yPFQ+KG11dGFibGVfZmllbGQpOworfQorCisvLyBTcGVjaWFsIGJhY2sgaW5zZXJ0IGl0ZXJhdG9yIGZvciBSZXBlYXRlZFB0ckZpZWxkIGluc3RhbmNlcywganVzdCBpbgorLy8gY2FzZSBzb21lb25lIHdhbnRzIHRvIHdyaXRlIGdlbmVyaWMgdGVtcGxhdGUgY29kZSB0aGF0IGNhbiBhY2Nlc3MgYm90aAorLy8gUmVwZWF0ZWRGaWVsZHMgYW5kIFJlcGVhdGVkUHRyRmllbGRzIHVzaW5nIGEgY29tbW9uIG5hbWUuCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPiBpbnRlcm5hbDo6UmVwZWF0ZWRQdHJGaWVsZEJhY2tJbnNlcnRJdGVyYXRvcjxUPgorUmVwZWF0ZWRGaWVsZEJhY2tJbnNlcnRlcihSZXBlYXRlZFB0ckZpZWxkPFQ+KiBjb25zdCBtdXRhYmxlX2ZpZWxkKSB7CisgIHJldHVybiBpbnRlcm5hbDo6UmVwZWF0ZWRQdHJGaWVsZEJhY2tJbnNlcnRJdGVyYXRvcjxUPihtdXRhYmxlX2ZpZWxkKTsKK30KKworLy8gUHJvdmlkZXMgYSBiYWNrIGluc2VydCBpdGVyYXRvciBmb3IgUmVwZWF0ZWRQdHJGaWVsZCBpbnN0YW5jZXMKKy8vIHNpbWlsYXIgdG8gc3RkOjpiYWNrX2luc2VydGVyKCkgd2hpY2ggdHJhbnNmZXJzIHRoZSBvd25lcnNoaXAgd2hpbGUKKy8vIGNvcHlpbmcgZWxlbWVudHMuCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPiBpbnRlcm5hbDo6QWxsb2NhdGVkUmVwZWF0ZWRQdHJGaWVsZEJhY2tJbnNlcnRJdGVyYXRvcjxUPgorQWxsb2NhdGVkUmVwZWF0ZWRQdHJGaWVsZEJhY2tJbnNlcnRlcigKKyAgICBSZXBlYXRlZFB0ckZpZWxkPFQ+KiBjb25zdCBtdXRhYmxlX2ZpZWxkKSB7CisgIHJldHVybiBpbnRlcm5hbDo6QWxsb2NhdGVkUmVwZWF0ZWRQdHJGaWVsZEJhY2tJbnNlcnRJdGVyYXRvcjxUPigKKyAgICAgIG11dGFibGVfZmllbGQpOworfQorCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfUkVQRUFURURfRklFTERfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3JlcGVhdGVkX2ZpZWxkX3JlZmxlY3Rpb24uaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvcmVwZWF0ZWRfZmllbGRfcmVmbGVjdGlvbi5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ0ZDE0ZDUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3JlcGVhdGVkX2ZpZWxkX3JlZmxlY3Rpb24uaApAQCAtMCwwICsxLDMzNyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIFRoaXMgaGVhZGVyIGZpbGUgaXMgcHJvdG9idWYgaW50ZXJuYWwuIFVzZXJzIHNob3VsZCBub3QgaW5jbHVkZSB0aGlzCisvLyBmaWxlIGRpcmVjdGx5LgorI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfUkVQRUFURURfRklFTERfUkVGTEVDVElPTl9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1JFUEVBVEVEX0ZJRUxEX1JFRkxFQ1RJT05fSF9fCisKKyNpbmNsdWRlIDxtZW1vcnk+CisjaWZuZGVmIF9TSEFSRURfUFRSX0gKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc2hhcmVkX3B0ci5oPgorI2VuZGlmCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX2VudW1fcmVmbGVjdGlvbi5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW50ZXJuYWwgeworLy8gSW50ZXJmYWNlcyB1c2VkIHRvIGltcGxlbWVudCByZWZsZWN0aW9uIFJlcGVhdGVkRmllbGRSZWYgQVBJLgorLy8gUmVmbGVjdGlvbjo6R2V0UmVwZWF0ZWRBY2Nlc3NvcigpIHNob3VsZCByZXR1cm4gYSBwb2ludGVyIHRvIGFuIHNpbmdsZXRvbgorLy8gb2JqZWN0IHRoYXQgaW1wbGVtZW50cyB0aGUgYmVsb3cgaW50ZXJmYWNlLgorLy8KKy8vIFRoaXMgaW50ZXJmYWNlIHBhc3Nlcy9yZXR1cm5zIHZhbHVlcyB1c2luZyB2b2lkIHBvaW50ZXJzLiBUaGUgYWN0dWFsIHR5cGUKKy8vIG9mIHRoZSB2YWx1ZSBkZXBlbmRzIG9uIHRoZSBmaWVsZCdzIGNwcF90eXBlLiBGb2xsb3dpbmcgaXMgYSBtYXBwaW5nIGZyb20KKy8vIGNwcF90eXBlIHRvIHRoZSB0eXBlIHRoYXQgc2hvdWxkIGJlIHVzZWQgaW4gdGhpcyBpbnRlcmZhY2U6CisvLworLy8gICBmaWVsZC0+Y3BwX3R5cGUoKSAgICAgIFQgICAgICAgICAgICAgICAgQWN0dWFsIHR5cGUgb2Ygdm9pZCoKKy8vICAgQ1BQVFlQRV9JTlQzMiAgICAgICAgaW50MzIgICAgICAgICAgICAgICAgICAgaW50MzIKKy8vICAgQ1BQVFlQRV9VSU5UMzIgICAgICAgdWludDMyICAgICAgICAgICAgICAgICAgdWludDMyCisvLyAgIENQUFRZUEVfSU5UNjQgICAgICAgIGludDY0ICAgICAgICAgICAgICAgICAgIGludDY0CisvLyAgIENQUFRZUEVfVUlOVDY0ICAgICAgIHVpbnQ2NCAgICAgICAgICAgICAgICAgIHVpbnQ2NAorLy8gICBDUFBUWVBFX0RPVUJMRSAgICAgICBkb3VibGUgICAgICAgICAgICAgICAgICBkb3VibGUKKy8vICAgQ1BQVFlQRV9GTE9BVCAgICAgICAgZmxvYXQgICAgICAgICAgICAgICAgICAgZmxvYXQKKy8vICAgQ1BQVFlQRV9CT09MICAgICAgICAgYm9vbCAgICAgICAgICAgICAgICAgICAgYm9vbAorLy8gICBDUFBUWVBFX0VOVU0gICAgICAgICBnZW5lcmF0ZWQgZW51bSB0eXBlICAgICBpbnQzMgorLy8gICBDUFBUWVBFX1NUUklORyAgICAgICBzdHJpbmcgICAgICAgICAgICAgICAgICBzdHJpbmcKKy8vICAgQ1BQVFlQRV9NRVNTQUdFICAgICAgZ2VuZXJhdGVkIG1lc3NhZ2UgdHlwZSAgZ29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZQorLy8gICAgICAgICAgICAgICAgICAgICAgICBvciBnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlCisvLworLy8gTm90ZSB0aGF0IGZvciBlbnVtcyB3ZSB1c2UgaW50MzIgaW4gdGhlIGludGVyZmFjZS4KKy8vCisvLyBZb3UgY2FuIG1hcCBmcm9tIFQgdG8gdGhlIGFjdHVhbCB0eXBlIHVzaW5nIFJlZlR5cGVUcmFpdHM6CisvLyAgIHR5cGVkZWYgUmVmVHlwZVRyYWl0czxUPjo6QWNjZXNzb3JWYWx1ZVR5cGUgQWN0dWFsVHlwZTsKK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBSZXBlYXRlZEZpZWxkQWNjZXNzb3IgeworIHB1YmxpYzoKKyAgLy8gVHlwZWRlZnMgZm9yIGNsYXJpdHkuCisgIHR5cGVkZWYgdm9pZCBGaWVsZDsKKyAgdHlwZWRlZiB2b2lkIFZhbHVlOworICB0eXBlZGVmIHZvaWQgSXRlcmF0b3I7CisKKyAgdmlydHVhbCB+UmVwZWF0ZWRGaWVsZEFjY2Vzc29yKCk7CisgIHZpcnR1YWwgYm9vbCBJc0VtcHR5KGNvbnN0IEZpZWxkKiBkYXRhKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgaW50IFNpemUoY29uc3QgRmllbGQqIGRhdGEpIGNvbnN0ID0gMDsKKyAgLy8gRGVwZW5kcyBvbiB0aGUgdW5kZXJseWluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgcmVwZWF0ZWQgZmllbGQsIHRoaXMKKyAgLy8gbWV0aG9kIGNhbiByZXR1cm4gYSBwb2ludGVyIHRvIHRoZSB1bmRlcmx5aW5nIG9iamVjdCBpZiBzdWNoIGFuIG9iamVjdAorICAvLyBleGlzdHMsIG9yIGZpbGwgdGhlIGRhdGEgaW50byBzY3JhdGNoX3NwYWNlIGFuZCByZXR1cm4gc2NyYXRjaF9zcGFjZS4KKyAgLy8gQ2FsbGVycyBvZiB0aGlzIG1ldGhvZCBtdXN0IGVuc3VyZSBzY3JhdGNoX3NwYWNlIGlzIGEgdmFsaWQgcG9pbnRlcgorICAvLyB0byBhIG11dGFibGUgb2JqZWN0IG9mIHRoZSBjb3JyZWN0IHR5cGUuCisgIHZpcnR1YWwgY29uc3QgVmFsdWUqIEdldCgKKyAgICAgIGNvbnN0IEZpZWxkKiBkYXRhLCBpbnQgaW5kZXgsIFZhbHVlKiBzY3JhdGNoX3NwYWNlKSBjb25zdCA9IDA7CisKKyAgdmlydHVhbCB2b2lkIENsZWFyKEZpZWxkKiBkYXRhKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBTZXQoRmllbGQqIGRhdGEsIGludCBpbmRleCwgY29uc3QgVmFsdWUqIHZhbHVlKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBBZGQoRmllbGQqIGRhdGEsIGNvbnN0IFZhbHVlKiB2YWx1ZSkgY29uc3QgPSAwOworICB2aXJ0dWFsIHZvaWQgUmVtb3ZlTGFzdChGaWVsZCogZGF0YSkgY29uc3QgPSAwOworICB2aXJ0dWFsIHZvaWQgU3dhcEVsZW1lbnRzKEZpZWxkKiBkYXRhLCBpbnQgaW5kZXgxLCBpbnQgaW5kZXgyKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBTd2FwKEZpZWxkKiBkYXRhLCBjb25zdCBSZXBlYXRlZEZpZWxkQWNjZXNzb3IqIG90aGVyX211dGF0b3IsCisgICAgICAgICAgICAgICAgICAgIEZpZWxkKiBvdGhlcl9kYXRhKSBjb25zdCA9IDA7CisKKyAgLy8gQ3JlYXRlIGFuIGl0ZXJhdG9yIHRoYXQgcG9pbnRzIGF0IHRoZSBiZWdpbmluZyBvZiB0aGUgcmVwZWF0ZWQgZmllbGQuCisgIHZpcnR1YWwgSXRlcmF0b3IqIEJlZ2luSXRlcmF0b3IoY29uc3QgRmllbGQqIGRhdGEpIGNvbnN0ID0gMDsKKyAgLy8gQ3JlYXRlIGFuIGl0ZXJhdG9yIHRoYXQgcG9pbnRzIGF0IHRoZSBlbmQgb2YgdGhlIHJlcGVhdGVkIGZpZWxkLgorICB2aXJ0dWFsIEl0ZXJhdG9yKiBFbmRJdGVyYXRvcihjb25zdCBGaWVsZCogZGF0YSkgY29uc3QgPSAwOworICAvLyBNYWtlIGEgY29weSBvZiBhbiBpdGVyYXRvciBhbmQgcmV0dXJuIHRoZSBuZXcgY29weS4KKyAgdmlydHVhbCBJdGVyYXRvciogQ29weUl0ZXJhdG9yKGNvbnN0IEZpZWxkKiBkYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgSXRlcmF0b3IqIGl0ZXJhdG9yKSBjb25zdCA9IDA7CisgIC8vIE1vdmUgYW4gaXRlcmF0b3IgdG8gcG9pbnQgdG8gdGhlIG5leHQgZWxlbWVudC4KKyAgdmlydHVhbCBJdGVyYXRvciogQWR2YW5jZUl0ZXJhdG9yKGNvbnN0IEZpZWxkKiBkYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSXRlcmF0b3IqIGl0ZXJhdG9yKSBjb25zdCA9IDA7CisgIC8vIENvbXBhcmUgd2hldGhlciB0d28gaXRlcmF0b3JzIHBvaW50IHRvIHRoZSBzYW1lIGVsZW1lbnQuCisgIHZpcnR1YWwgYm9vbCBFcXVhbHNJdGVyYXRvcihjb25zdCBGaWVsZCogZGF0YSwgY29uc3QgSXRlcmF0b3IqIGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBJdGVyYXRvciogYikgY29uc3QgPSAwOworICAvLyBEZWxldGUgYW4gaXRlcmF0b3IgY3JlYXRlZCBieSBCZWdpbkl0ZXJhdG9yKCksIEVuZEl0ZXJhdG9yKCkgYW5kCisgIC8vIENvcHlJdGVyYXRvcigpLgorICB2aXJ0dWFsIHZvaWQgRGVsZXRlSXRlcmF0b3IoY29uc3QgRmllbGQqIGRhdGEsIEl0ZXJhdG9yKiBpdGVyYXRvcikgY29uc3QgPSAwOworICAvLyBMaWtlIEdldCgpIGJ1dCBmb3IgaXRlcmF0b3JzLgorICB2aXJ0dWFsIGNvbnN0IFZhbHVlKiBHZXRJdGVyYXRvclZhbHVlKGNvbnN0IEZpZWxkKiBkYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEl0ZXJhdG9yKiBpdGVyYXRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWYWx1ZSogc2NyYXRjaF9zcGFjZSkgY29uc3QgPSAwOworCisgIC8vIFRlbXBsYXRlZCBtZXRob2RzIHRoYXQgbWFrZSB1c2luZyB0aGlzIGludGVyZmFjZSBlYXNpZXIgZm9yIG5vbi1tZXNzYWdlCisgIC8vIHR5cGVzLgorICB0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorICBUIEdldChjb25zdCBGaWVsZCogZGF0YSwgaW50IGluZGV4KSBjb25zdCB7CisgICAgdHlwZWRlZiB0eXBlbmFtZSBSZWZUeXBlVHJhaXRzPFQ+OjpBY2Nlc3NvclZhbHVlVHlwZSBBY3R1YWxUeXBlOworICAgIEFjdHVhbFR5cGUgc2NyYXRjaF9zcGFjZTsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8VD4oCisgICAgICAgICpyZWludGVycHJldF9jYXN0PGNvbnN0IEFjdHVhbFR5cGUqPigKKyAgICAgICAgICAgIEdldChkYXRhLCBpbmRleCwgc3RhdGljX2Nhc3Q8VmFsdWUqPigmc2NyYXRjaF9zcGFjZSkpKSk7CisgIH0KKworICB0ZW1wbGF0ZTx0eXBlbmFtZSBULCB0eXBlbmFtZSBWYWx1ZVR5cGU+CisgIHZvaWQgU2V0KEZpZWxkKiBkYXRhLCBpbnQgaW5kZXgsIGNvbnN0IFZhbHVlVHlwZSYgdmFsdWUpIGNvbnN0IHsKKyAgICB0eXBlZGVmIHR5cGVuYW1lIFJlZlR5cGVUcmFpdHM8VD46OkFjY2Vzc29yVmFsdWVUeXBlIEFjdHVhbFR5cGU7CisgICAgLy8gSW4gdGhpcyBSZXBlYXRlZEZpZWxkQWNjZXNzb3IgaW50ZXJmYWNlIHdlIHBhc3MvcmV0dXJuIGRhdGEgdXNpbmcKKyAgICAvLyByYXcgcG9pbnRlcnMuIFR5cGUgb2YgdGhlIGRhdGEgdGhlc2UgcmF3IHBvaW50ZXJzIHBvaW50IHRvIHNob3VsZAorICAgIC8vIGJlIEFjdHVhbFR5cGUuIEhlcmUgd2UgaGF2ZSBhIFZhbHVlVHlwZSBvYmplY3QgYW5kIHdhbnQgYSBBY3R1YWxUeXBlCisgICAgLy8gcG9pbnRlci4gV2UgY2FuJ3QgY2FzdCBhIFZhbHVlVHlwZSBwb2ludGVyIHRvIGFuIEFjdHVhbFR5cGUgcG9pbnRlcgorICAgIC8vIGRpcmVjdGx5IGJlY2F1c2UgdGhlaXIgdHlwZSBtaWdodCBiZSBkaWZmZXJlbnQgKGZvciBlbnVtcyBWYWx1ZVR5cGUKKyAgICAvLyBtYXkgYmUgYSBnZW5lcmF0ZWQgZW51bSB0eXBlIHdoaWxlIEFjdHVhbFR5cGUgaXMgaW50MzIpLiBUbyBiZSBzYWZlCisgICAgLy8gd2UgbWFrZSBhIGNvcHkgdG8gZ2V0IGEgdGVtcG9yYXJ5IEFjdHVhbFR5cGUgb2JqZWN0IGFuZCB1c2UgaXQuCisgICAgQWN0dWFsVHlwZSB0bXAgPSBzdGF0aWNfY2FzdDxBY3R1YWxUeXBlPih2YWx1ZSk7CisgICAgU2V0KGRhdGEsIGluZGV4LCBzdGF0aWNfY2FzdDxjb25zdCBWYWx1ZSo+KCZ0bXApKTsKKyAgfQorCisgIHRlbXBsYXRlPHR5cGVuYW1lIFQsIHR5cGVuYW1lIFZhbHVlVHlwZT4KKyAgdm9pZCBBZGQoRmllbGQqIGRhdGEsIGNvbnN0IFZhbHVlVHlwZSYgdmFsdWUpIGNvbnN0IHsKKyAgICB0eXBlZGVmIHR5cGVuYW1lIFJlZlR5cGVUcmFpdHM8VD46OkFjY2Vzc29yVmFsdWVUeXBlIEFjdHVhbFR5cGU7CisgICAgLy8gSW4gdGhpcyBSZXBlYXRlZEZpZWxkQWNjZXNzb3IgaW50ZXJmYWNlIHdlIHBhc3MvcmV0dXJuIGRhdGEgdXNpbmcKKyAgICAvLyByYXcgcG9pbnRlcnMuIFR5cGUgb2YgdGhlIGRhdGEgdGhlc2UgcmF3IHBvaW50ZXJzIHBvaW50IHRvIHNob3VsZAorICAgIC8vIGJlIEFjdHVhbFR5cGUuIEhlcmUgd2UgaGF2ZSBhIFZhbHVlVHlwZSBvYmplY3QgYW5kIHdhbnQgYSBBY3R1YWxUeXBlCisgICAgLy8gcG9pbnRlci4gV2UgY2FuJ3QgY2FzdCBhIFZhbHVlVHlwZSBwb2ludGVyIHRvIGFuIEFjdHVhbFR5cGUgcG9pbnRlcgorICAgIC8vIGRpcmVjdGx5IGJlY2F1c2UgdGhlaXIgdHlwZSBtaWdodCBiZSBkaWZmZXJlbnQgKGZvciBlbnVtcyBWYWx1ZVR5cGUKKyAgICAvLyBtYXkgYmUgYSBnZW5lcmF0ZWQgZW51bSB0eXBlIHdoaWxlIEFjdHVhbFR5cGUgaXMgaW50MzIpLiBUbyBiZSBzYWZlCisgICAgLy8gd2UgbWFrZSBhIGNvcHkgdG8gZ2V0IGEgdGVtcG9yYXJ5IEFjdHVhbFR5cGUgb2JqZWN0IGFuZCB1c2UgaXQuCisgICAgQWN0dWFsVHlwZSB0bXAgPSBzdGF0aWNfY2FzdDxBY3R1YWxUeXBlPih2YWx1ZSk7CisgICAgQWRkKGRhdGEsIHN0YXRpY19jYXN0PGNvbnN0IFZhbHVlKj4oJnRtcCkpOworICB9Cit9OworCisvLyBJbXBsZW1lbnQgKE11dGFibGUpUmVwZWF0ZWRGaWVsZFJlZjo6aXRlcmF0b3IKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+CitjbGFzcyBSZXBlYXRlZEZpZWxkUmVmSXRlcmF0b3IKKyAgICA6IHB1YmxpYyBzdGQ6Oml0ZXJhdG9yPHN0ZDo6Zm9yd2FyZF9pdGVyYXRvcl90YWcsIFQ+IHsKKyAgdHlwZWRlZiB0eXBlbmFtZSBSZWZUeXBlVHJhaXRzPFQ+OjpBY2Nlc3NvclZhbHVlVHlwZSBBY2Nlc3NvclZhbHVlVHlwZTsKKyAgdHlwZWRlZiB0eXBlbmFtZSBSZWZUeXBlVHJhaXRzPFQ+OjpJdGVyYXRvclZhbHVlVHlwZSBJdGVyYXRvclZhbHVlVHlwZTsKKyAgdHlwZWRlZiB0eXBlbmFtZSBSZWZUeXBlVHJhaXRzPFQ+OjpJdGVyYXRvclBvaW50ZXJUeXBlIEl0ZXJhdG9yUG9pbnRlclR5cGU7CisKKyBwdWJsaWM6CisgIC8vIENvbnN0cnVjdG9yIGZvciBub24tbWVzc2FnZSBmaWVsZHMuCisgIFJlcGVhdGVkRmllbGRSZWZJdGVyYXRvcihjb25zdCB2b2lkKiBkYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUmVwZWF0ZWRGaWVsZEFjY2Vzc29yKiBhY2Nlc3NvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgYmVnaW4pCisgICAgICA6IGRhdGFfKGRhdGEpLCBhY2Nlc3Nvcl8oYWNjZXNzb3IpLAorICAgICAgICBpdGVyYXRvcl8oYmVnaW4gPyBhY2Nlc3Nvci0+QmVnaW5JdGVyYXRvcihkYXRhKSA6CisgICAgICAgICAgICAgICAgICAgICAgICAgIGFjY2Vzc29yLT5FbmRJdGVyYXRvcihkYXRhKSksCisgICAgICAgIHNjcmF0Y2hfc3BhY2VfKG5ldyBBY2Nlc3NvclZhbHVlVHlwZSkgeworICB9CisgIC8vIENvbnN0cnVjdG9yIGZvciBtZXNzYWdlIGZpZWxkcy4KKyAgUmVwZWF0ZWRGaWVsZFJlZkl0ZXJhdG9yKGNvbnN0IHZvaWQqIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBSZXBlYXRlZEZpZWxkQWNjZXNzb3IqIGFjY2Vzc29yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBiZWdpbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIEFjY2Vzc29yVmFsdWVUeXBlKiBzY3JhdGNoX3NwYWNlKQorICAgICAgOiBkYXRhXyhkYXRhKSwgYWNjZXNzb3JfKGFjY2Vzc29yKSwKKyAgICAgICAgaXRlcmF0b3JfKGJlZ2luID8gYWNjZXNzb3ItPkJlZ2luSXRlcmF0b3IoZGF0YSkgOgorICAgICAgICAgICAgICAgICAgICAgICAgICBhY2Nlc3Nvci0+RW5kSXRlcmF0b3IoZGF0YSkpLAorICAgICAgICBzY3JhdGNoX3NwYWNlXyhzY3JhdGNoX3NwYWNlKSB7CisgIH0KKyAgflJlcGVhdGVkRmllbGRSZWZJdGVyYXRvcigpIHsKKyAgICBhY2Nlc3Nvcl8tPkRlbGV0ZUl0ZXJhdG9yKGRhdGFfLCBpdGVyYXRvcl8pOworICB9CisgIFJlcGVhdGVkRmllbGRSZWZJdGVyYXRvciBvcGVyYXRvcisrKGludCkgeworICAgIFJlcGVhdGVkRmllbGRSZWZJdGVyYXRvciB0bXAoKnRoaXMpOworICAgIGl0ZXJhdG9yXyA9IGFjY2Vzc29yXy0+QWR2YW5jZUl0ZXJhdG9yKGRhdGFfLCBpdGVyYXRvcl8pOworICAgIHJldHVybiB0bXA7CisgIH0KKyAgUmVwZWF0ZWRGaWVsZFJlZkl0ZXJhdG9yJiBvcGVyYXRvcisrKCkgeworICAgIGl0ZXJhdG9yXyA9IGFjY2Vzc29yXy0+QWR2YW5jZUl0ZXJhdG9yKGRhdGFfLCBpdGVyYXRvcl8pOworICAgIHJldHVybiAqdGhpczsKKyAgfQorICBJdGVyYXRvclZhbHVlVHlwZSBvcGVyYXRvciooKSBjb25zdCB7CisgICAgcmV0dXJuIHN0YXRpY19jYXN0PEl0ZXJhdG9yVmFsdWVUeXBlPigKKyAgICAgICAgKnN0YXRpY19jYXN0PGNvbnN0IEFjY2Vzc29yVmFsdWVUeXBlKj4oCisgICAgICAgICAgICBhY2Nlc3Nvcl8tPkdldEl0ZXJhdG9yVmFsdWUoCisgICAgICAgICAgICAgICAgZGF0YV8sIGl0ZXJhdG9yXywgc2NyYXRjaF9zcGFjZV8uZ2V0KCkpKSk7CisgIH0KKyAgSXRlcmF0b3JQb2ludGVyVHlwZSBvcGVyYXRvci0+KCkgY29uc3QgeworICAgIHJldHVybiBzdGF0aWNfY2FzdDxJdGVyYXRvclBvaW50ZXJUeXBlPigKKyAgICAgICAgYWNjZXNzb3JfLT5HZXRJdGVyYXRvclZhbHVlKAorICAgICAgICAgICAgZGF0YV8sIGl0ZXJhdG9yXywgc2NyYXRjaF9zcGFjZV8uZ2V0KCkpKTsKKyAgfQorICBib29sIG9wZXJhdG9yIT0oY29uc3QgUmVwZWF0ZWRGaWVsZFJlZkl0ZXJhdG9yJiBvdGhlcikgY29uc3QgeworICAgIGFzc2VydChkYXRhXyA9PSBvdGhlci5kYXRhXyk7CisgICAgYXNzZXJ0KGFjY2Vzc29yXyA9PSBvdGhlci5hY2Nlc3Nvcl8pOworICAgIHJldHVybiAhYWNjZXNzb3JfLT5FcXVhbHNJdGVyYXRvcihkYXRhXywgaXRlcmF0b3JfLCBvdGhlci5pdGVyYXRvcl8pOworICB9CisgIGJvb2wgb3BlcmF0b3I9PShjb25zdCBSZXBlYXRlZEZpZWxkUmVmSXRlcmF0b3ImIG90aGVyKSBjb25zdCB7CisgICAgcmV0dXJuICF0aGlzLT5vcGVyYXRvciE9KG90aGVyKTsKKyAgfQorCisgIFJlcGVhdGVkRmllbGRSZWZJdGVyYXRvcihjb25zdCBSZXBlYXRlZEZpZWxkUmVmSXRlcmF0b3ImIG90aGVyKQorICAgICAgOiBkYXRhXyhvdGhlci5kYXRhXyksIGFjY2Vzc29yXyhvdGhlci5hY2Nlc3Nvcl8pLAorICAgICAgICBpdGVyYXRvcl8oYWNjZXNzb3JfLT5Db3B5SXRlcmF0b3IoZGF0YV8sIG90aGVyLml0ZXJhdG9yXykpIHsKKyAgfQorICBSZXBlYXRlZEZpZWxkUmVmSXRlcmF0b3ImIG9wZXJhdG9yPShjb25zdCBSZXBlYXRlZEZpZWxkUmVmSXRlcmF0b3ImIG90aGVyKSB7CisgICAgaWYgKHRoaXMgIT0gJm90aGVyKSB7CisgICAgICBhY2Nlc3Nvcl8tPkRlbGV0ZUl0ZXJhdG9yKGRhdGFfLCBpdGVyYXRvcl8pOworICAgICAgZGF0YV8gPSBvdGhlci5kYXRhXzsKKyAgICAgIGFjY2Vzc29yXyA9IG90aGVyLmFjY2Vzc29yXzsKKyAgICAgIGl0ZXJhdG9yXyA9IGFjY2Vzc29yXy0+Q29weUl0ZXJhdG9yKGRhdGFfLCBvdGhlci5pdGVyYXRvcl8pOworICAgIH0KKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworIHByb3RlY3RlZDoKKyAgY29uc3Qgdm9pZCogZGF0YV87CisgIGNvbnN0IFJlcGVhdGVkRmllbGRBY2Nlc3NvciogYWNjZXNzb3JfOworICB2b2lkKiBpdGVyYXRvcl87CisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8QWNjZXNzb3JWYWx1ZVR5cGU+IHNjcmF0Y2hfc3BhY2VfOworfTsKKworLy8gVHlwZVRyYWl0cyB0aGF0IG1hcHMgdGhlIHR5cGUgcGFyYW1ldGVyIFQgb2YgUmVwZWF0ZWRGaWVsZFJlZiBvcgorLy8gTXV0YWJsZVJlcGVhdGVkRmllbGRSZWYgdG8gY29ycmVzcG9uZGluZyBpdGVyYXRvciB0eXBlLAorLy8gUmVwZWF0ZWRGaWVsZEFjY2Vzc29yIHR5cGUsIGV0Yy4KK3RlbXBsYXRlPHR5cGVuYW1lIFQ+CitzdHJ1Y3QgUHJpbWl0aXZlVHJhaXRzIHsKKyAgc3RhdGljIGNvbnN0IGJvb2wgaXNfcHJpbWl0aXZlID0gZmFsc2U7Cit9OworI2RlZmluZSBERUZJTkVfUFJJTUlUSVZFKFRZUEUsIHR5cGUpIFwKKyAgICB0ZW1wbGF0ZTw+IHN0cnVjdCBQcmltaXRpdmVUcmFpdHM8dHlwZT4geyBcCisgICAgICBzdGF0aWMgY29uc3QgYm9vbCBpc19wcmltaXRpdmUgPSB0cnVlOyBcCisgICAgICBzdGF0aWMgY29uc3QgRmllbGREZXNjcmlwdG9yOjpDcHBUeXBlIGNwcF90eXBlID0gXAorICAgICAgICAgIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV8gIyMgVFlQRTsgXAorICAgIH07CitERUZJTkVfUFJJTUlUSVZFKElOVDMyLCBpbnQzMikKK0RFRklORV9QUklNSVRJVkUoVUlOVDMyLCB1aW50MzIpCitERUZJTkVfUFJJTUlUSVZFKElOVDY0LCBpbnQ2NCkKK0RFRklORV9QUklNSVRJVkUoVUlOVDY0LCB1aW50NjQpCitERUZJTkVfUFJJTUlUSVZFKEZMT0FULCBmbG9hdCkKK0RFRklORV9QUklNSVRJVkUoRE9VQkxFLCBkb3VibGUpCitERUZJTkVfUFJJTUlUSVZFKEJPT0wsIGJvb2wpCisjdW5kZWYgREVGSU5FX1BSSU1JVElWRQorCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorc3RydWN0IFJlZlR5cGVUcmFpdHM8CisgICAgVCwgdHlwZW5hbWUgaW50ZXJuYWw6OmVuYWJsZV9pZjxQcmltaXRpdmVUcmFpdHM8VD46OmlzX3ByaW1pdGl2ZT46OnR5cGU+IHsKKyAgdHlwZWRlZiBSZXBlYXRlZEZpZWxkUmVmSXRlcmF0b3I8VD4gaXRlcmF0b3I7CisgIHR5cGVkZWYgUmVwZWF0ZWRGaWVsZEFjY2Vzc29yIEFjY2Vzc29yVHlwZTsKKyAgdHlwZWRlZiBUIEFjY2Vzc29yVmFsdWVUeXBlOworICB0eXBlZGVmIFQgSXRlcmF0b3JWYWx1ZVR5cGU7CisgIHR5cGVkZWYgVCogSXRlcmF0b3JQb2ludGVyVHlwZTsKKyAgc3RhdGljIGNvbnN0IEZpZWxkRGVzY3JpcHRvcjo6Q3BwVHlwZSBjcHBfdHlwZSA9CisgICAgICBQcmltaXRpdmVUcmFpdHM8VD46OmNwcF90eXBlOworICBzdGF0aWMgY29uc3QgRGVzY3JpcHRvciogR2V0TWVzc2FnZUZpZWxkRGVzY3JpcHRvcigpIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorfTsKKwordGVtcGxhdGU8dHlwZW5hbWUgVD4KK3N0cnVjdCBSZWZUeXBlVHJhaXRzPAorICAgIFQsIHR5cGVuYW1lIGludGVybmFsOjplbmFibGVfaWY8aXNfcHJvdG9fZW51bTxUPjo6dmFsdWU+Ojp0eXBlPiB7CisgIHR5cGVkZWYgUmVwZWF0ZWRGaWVsZFJlZkl0ZXJhdG9yPFQ+IGl0ZXJhdG9yOworICB0eXBlZGVmIFJlcGVhdGVkRmllbGRBY2Nlc3NvciBBY2Nlc3NvclR5cGU7CisgIC8vIFdlIHVzZSBpbnQzMiBmb3IgcmVwZWF0ZWQgZW51bXMgaW4gUmVwZWF0ZWRGaWVsZEFjY2Vzc29yLgorICB0eXBlZGVmIGludDMyIEFjY2Vzc29yVmFsdWVUeXBlOworICB0eXBlZGVmIFQgSXRlcmF0b3JWYWx1ZVR5cGU7CisgIHR5cGVkZWYgaW50MzIqIEl0ZXJhdG9yUG9pbnRlclR5cGU7CisgIHN0YXRpYyBjb25zdCBGaWVsZERlc2NyaXB0b3I6OkNwcFR5cGUgY3BwX3R5cGUgPQorICAgICAgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0VOVU07CisgIHN0YXRpYyBjb25zdCBEZXNjcmlwdG9yKiBHZXRNZXNzYWdlRmllbGREZXNjcmlwdG9yKCkgeworICAgIHJldHVybiBOVUxMOworICB9Cit9OworCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorc3RydWN0IFJlZlR5cGVUcmFpdHM8CisgICAgVCwgdHlwZW5hbWUgaW50ZXJuYWw6OmVuYWJsZV9pZjxpbnRlcm5hbDo6aXNfc2FtZTxzdHJpbmcsIFQ+Ojp2YWx1ZT46OnR5cGU+IHsKKyAgdHlwZWRlZiBSZXBlYXRlZEZpZWxkUmVmSXRlcmF0b3I8VD4gaXRlcmF0b3I7CisgIHR5cGVkZWYgUmVwZWF0ZWRGaWVsZEFjY2Vzc29yIEFjY2Vzc29yVHlwZTsKKyAgdHlwZWRlZiBzdHJpbmcgQWNjZXNzb3JWYWx1ZVR5cGU7CisgIHR5cGVkZWYgc3RyaW5nIEl0ZXJhdG9yVmFsdWVUeXBlOworICB0eXBlZGVmIHN0cmluZyogSXRlcmF0b3JQb2ludGVyVHlwZTsKKyAgc3RhdGljIGNvbnN0IEZpZWxkRGVzY3JpcHRvcjo6Q3BwVHlwZSBjcHBfdHlwZSA9CisgICAgICBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HOworICBzdGF0aWMgY29uc3QgRGVzY3JpcHRvciogR2V0TWVzc2FnZUZpZWxkRGVzY3JpcHRvcigpIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorfTsKKwordGVtcGxhdGU8dHlwZW5hbWUgVD4KK3N0cnVjdCBNZXNzYWdlRGVzY3JpcHRvckdldHRlciB7CisgIHN0YXRpYyBjb25zdCBEZXNjcmlwdG9yKiBnZXQoKSB7CisgICAgcmV0dXJuIFQ6OmRlZmF1bHRfaW5zdGFuY2UoKS5HZXREZXNjcmlwdG9yKCk7CisgIH0KK307Cit0ZW1wbGF0ZTw+CitzdHJ1Y3QgTWVzc2FnZURlc2NyaXB0b3JHZXR0ZXI8TWVzc2FnZT4geworICBzdGF0aWMgY29uc3QgRGVzY3JpcHRvciogZ2V0KCkgeworICAgIHJldHVybiBOVUxMOworICB9Cit9OworCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorc3RydWN0IFJlZlR5cGVUcmFpdHM8CisgICAgVCwgdHlwZW5hbWUgaW50ZXJuYWw6OmVuYWJsZV9pZjxpbnRlcm5hbDo6aXNfYmFzZV9vZjxNZXNzYWdlLCBUPjo6dmFsdWU+Ojp0eXBlPiB7CisgIHR5cGVkZWYgUmVwZWF0ZWRGaWVsZFJlZkl0ZXJhdG9yPFQ+IGl0ZXJhdG9yOworICB0eXBlZGVmIFJlcGVhdGVkRmllbGRBY2Nlc3NvciBBY2Nlc3NvclR5cGU7CisgIHR5cGVkZWYgTWVzc2FnZSBBY2Nlc3NvclZhbHVlVHlwZTsKKyAgdHlwZWRlZiBjb25zdCBUJiBJdGVyYXRvclZhbHVlVHlwZTsKKyAgdHlwZWRlZiBjb25zdCBUKiBJdGVyYXRvclBvaW50ZXJUeXBlOworICBzdGF0aWMgY29uc3QgRmllbGREZXNjcmlwdG9yOjpDcHBUeXBlIGNwcF90eXBlID0KKyAgICAgIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOworICBzdGF0aWMgY29uc3QgRGVzY3JpcHRvciogR2V0TWVzc2FnZUZpZWxkRGVzY3JpcHRvcigpIHsKKyAgICByZXR1cm4gTWVzc2FnZURlc2NyaXB0b3JHZXR0ZXI8VD46OmdldCgpOworICB9Cit9OworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX1JFUEVBVEVEX0ZJRUxEX1JFRkxFQ1RJT05fSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3JlcGVhdGVkX2ZpZWxkX3JlZmxlY3Rpb25fdW5pdHRlc3QuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3JlcGVhdGVkX2ZpZWxkX3JlZmxlY3Rpb25fdW5pdHRlc3QuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmNlYmU1YwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvcmVwZWF0ZWRfZmllbGRfcmVmbGVjdGlvbl91bml0dGVzdC5jYwpAQCAtMCwwICsxLDcwNiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjogdGdzQGdvb2dsZS5jb20gKFRvbSBTenltYW5za2kpCisvLworLy8gVGVzdCByZWZsZWN0aW9uIG1ldGhvZHMgZm9yIGFnZ3JlZ2F0ZSBhY2Nlc3MgdG8gUmVwZWF0ZWRbUHRyXUZpZWxkcy4KKy8vIFRoaXMgdGVzdCBwcm90bzIgbWV0aG9kcyBvbiBhIHByb3RvMiBsYXlvdXQuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY2FzdHMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RyaW5ncHJpbnRmLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2R5bmFtaWNfbWVzc2FnZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXN0X3V0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcmVmbGVjdGlvbi5oPgorI2luY2x1ZGUgPGd0ZXN0L2d0ZXN0Lmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKwordXNpbmcgdW5pdHRlc3Q6OkZvcmVpZ25NZXNzYWdlOwordXNpbmcgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlczsKK3VzaW5nIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9uczsKKworbmFtZXNwYWNlIHsKKworc3RhdGljIGludCBGdW5jKGludCBpLCBpbnQgaikgeworICByZXR1cm4gaSAqIGo7Cit9CisKK3N0YXRpYyBzdHJpbmcgU3RyRnVuYyhpbnQgaSwgaW50IGopIHsKKyAgc3RyaW5nIHN0cjsKKyAgU1N0cmluZ1ByaW50Zigmc3RyLCAiJWQiLCBGdW5jKGksIDQpKTsKKyAgcmV0dXJuIHN0cjsKK30KKworVEVTVChSZXBlYXRlZEZpZWxkUmVmbGVjdGlvblRlc3QsIFJlZ3VsYXJGaWVsZHMpIHsKKyAgVGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmwgPSBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKTsKKyAgY29uc3QgRGVzY3JpcHRvciogZGVzYyA9IG1lc3NhZ2UuR2V0RGVzY3JpcHRvcigpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7ICsraSkgeworICAgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX2ludDMyKEZ1bmMoaSwgMSkpOworICAgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX2RvdWJsZShGdW5jKGksIDIpKTsKKyAgICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9zdHJpbmcoU3RyRnVuYyhpLCA1KSk7CisgICAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKCktPnNldF9jKEZ1bmMoaSwgNikpOworICB9CisKKyAgLy8gR2V0IEZpZWxkRGVzY3JpcHRvcnMgZm9yIGFsbCB0aGUgZmllbGRzIG9mIGludGVyZXN0LgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZkX3JlcGVhdGVkX2ludDMyID0KKyAgICAgIGRlc2MtPkZpbmRGaWVsZEJ5TmFtZSgicmVwZWF0ZWRfaW50MzIiKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmZF9yZXBlYXRlZF9kb3VibGUgPQorICAgICAgZGVzYy0+RmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF9kb3VibGUiKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmZF9yZXBlYXRlZF9zdHJpbmcgPQorICAgICAgZGVzYy0+RmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF9zdHJpbmciKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmZF9yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPQorICAgICAgZGVzYy0+RmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UiKTsKKworICAvLyBHZXQgUmVwZWF0ZWRGaWVsZCBvYmplY3RzIGZvciBhbGwgZmllbGRzIG9mIGludGVyZXN0LgorICBjb25zdCBSZXBlYXRlZEZpZWxkPGludDMyPiYgcmZfaW50MzIgPQorICAgICAgcmVmbC0+R2V0UmVwZWF0ZWRGaWVsZDxpbnQzMj4obWVzc2FnZSwgZmRfcmVwZWF0ZWRfaW50MzIpOworICBjb25zdCBSZXBlYXRlZEZpZWxkPGRvdWJsZT4mIHJmX2RvdWJsZSA9CisgICAgICByZWZsLT5HZXRSZXBlYXRlZEZpZWxkPGRvdWJsZT4obWVzc2FnZSwgZmRfcmVwZWF0ZWRfZG91YmxlKTsKKworICAvLyBHZXQgbXV0YWJsZSBSZXBlYXRlZEZpZWxkIG9iamVjdHMgZm9yIGFsbCBmaWVsZHMgb2YgaW50ZXJlc3QuCisgIFJlcGVhdGVkRmllbGQ8aW50MzI+KiBtcmZfaW50MzIgPQorICAgICAgcmVmbC0+TXV0YWJsZVJlcGVhdGVkRmllbGQ8aW50MzI+KCZtZXNzYWdlLCBmZF9yZXBlYXRlZF9pbnQzMik7CisgIFJlcGVhdGVkRmllbGQ8ZG91YmxlPiogbXJmX2RvdWJsZSA9CisgICAgICByZWZsLT5NdXRhYmxlUmVwZWF0ZWRGaWVsZDxkb3VibGU+KCZtZXNzYWdlLCBmZF9yZXBlYXRlZF9kb3VibGUpOworCisgIC8vIEdldCBSZXBlYXRlZFB0ckZpZWxkIG9iamVjdHMgZm9yIGFsbCBmaWVsZHMgb2YgaW50ZXJlc3QuCisgIGNvbnN0IFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPiYgcnBmX3N0cmluZyA9CisgICAgICByZWZsLT5HZXRSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4obWVzc2FnZSwgZmRfcmVwZWF0ZWRfc3RyaW5nKTsKKyAgY29uc3QgUmVwZWF0ZWRQdHJGaWVsZDxGb3JlaWduTWVzc2FnZT4mIHJwZl9mb3JlaWduX21lc3NhZ2UgPQorICAgICAgcmVmbC0+R2V0UmVwZWF0ZWRQdHJGaWVsZDxGb3JlaWduTWVzc2FnZT4oCisgICAgICAgICAgbWVzc2FnZSwgZmRfcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKTsKKyAgY29uc3QgUmVwZWF0ZWRQdHJGaWVsZDxNZXNzYWdlPiYgcnBmX21lc3NhZ2UgPQorICAgICAgcmVmbC0+R2V0UmVwZWF0ZWRQdHJGaWVsZDxNZXNzYWdlPigKKyAgICAgICAgICBtZXNzYWdlLCBmZF9yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UpOworCisgIC8vIEdldCBtdXRhYmxlIFJlcGVhdGVkUHRyRmllbGQgb2JqZWN0cyBmb3IgYWxsIGZpZWxkcyBvZiBpbnRlcmVzdC4KKyAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+KiBtcnBmX3N0cmluZyA9CisgICAgICByZWZsLT5NdXRhYmxlUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+KCZtZXNzYWdlLCBmZF9yZXBlYXRlZF9zdHJpbmcpOworICBSZXBlYXRlZFB0ckZpZWxkPEZvcmVpZ25NZXNzYWdlPiogbXJwZl9mb3JlaWduX21lc3NhZ2UgPQorICAgICAgcmVmbC0+TXV0YWJsZVJlcGVhdGVkUHRyRmllbGQ8Rm9yZWlnbk1lc3NhZ2U+KAorICAgICAgICAgICZtZXNzYWdlLCBmZF9yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UpOworICBSZXBlYXRlZFB0ckZpZWxkPE1lc3NhZ2U+KiBtcnBmX21lc3NhZ2UgPQorICAgICAgcmVmbC0+TXV0YWJsZVJlcGVhdGVkUHRyRmllbGQ8TWVzc2FnZT4oCisgICAgICAgICAgJm1lc3NhZ2UsIGZkX3JlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSk7CisKKyAgLy8gTWFrZSBzdXJlIHdlIGNhbiBkbyBnZXRzIGFuZCBzZXRzIHRocm91Z2ggdGhlIFJlcGVhdGVkW1B0cl1GaWVsZCBvYmplY3RzLgorICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyArK2kpIHsKKyAgICAvLyBDaGVjayBnZXRzIHRocm91Z2ggY29uc3Qgb2JqZWN0cy4KKyAgICBFWFBFQ1RfRVEocmZfaW50MzIuR2V0KGkpLCBGdW5jKGksIDEpKTsKKyAgICBFWFBFQ1RfRVEocmZfZG91YmxlLkdldChpKSwgRnVuYyhpLCAyKSk7CisgICAgRVhQRUNUX0VRKHJwZl9zdHJpbmcuR2V0KGkpLCBTdHJGdW5jKGksIDUpKTsKKyAgICBFWFBFQ1RfRVEocnBmX2ZvcmVpZ25fbWVzc2FnZS5HZXQoaSkuYygpLCBGdW5jKGksIDYpKTsKKyAgICBFWFBFQ1RfRVEoZG93bl9jYXN0PGNvbnN0IEZvcmVpZ25NZXNzYWdlKj4oJnJwZl9tZXNzYWdlLkdldChpKSktPmMoKSwKKyAgICAgICAgICAgICAgRnVuYyhpLCA2KSk7CisKKyAgICAvLyBDaGVjayBnZXRzIHRocm91Z2ggbXV0YWJsZSBvYmplY3RzLgorICAgIEVYUEVDVF9FUShtcmZfaW50MzItPkdldChpKSwgRnVuYyhpLCAxKSk7CisgICAgRVhQRUNUX0VRKG1yZl9kb3VibGUtPkdldChpKSwgRnVuYyhpLCAyKSk7CisgICAgRVhQRUNUX0VRKG1ycGZfc3RyaW5nLT5HZXQoaSksIFN0ckZ1bmMoaSwgNSkpOworICAgIEVYUEVDVF9FUShtcnBmX2ZvcmVpZ25fbWVzc2FnZS0+R2V0KGkpLmMoKSwgRnVuYyhpLCA2KSk7CisgICAgRVhQRUNUX0VRKGRvd25fY2FzdDxjb25zdCBGb3JlaWduTWVzc2FnZSo+KCZtcnBmX21lc3NhZ2UtPkdldChpKSktPmMoKSwKKyAgICAgICAgICAgICAgRnVuYyhpLCA2KSk7CisKKyAgICAvLyBDaGVjayBzZXRzIHRocm91Z2ggbXV0YWJsZSBvYmplY3RzLgorICAgIG1yZl9pbnQzMi0+U2V0KGksIEZ1bmMoaSwgLTEpKTsKKyAgICBtcmZfZG91YmxlLT5TZXQoaSwgRnVuYyhpLCAtMikpOworICAgIG1ycGZfc3RyaW5nLT5NdXRhYmxlKGkpLT5hc3NpZ24oU3RyRnVuYyhpLCAtNSkpOworICAgIG1ycGZfZm9yZWlnbl9tZXNzYWdlLT5NdXRhYmxlKGkpLT5zZXRfYyhGdW5jKGksIC02KSk7CisgICAgRVhQRUNUX0VRKG1lc3NhZ2UucmVwZWF0ZWRfaW50MzIoaSksIEZ1bmMoaSwgLTEpKTsKKyAgICBFWFBFQ1RfRVEobWVzc2FnZS5yZXBlYXRlZF9kb3VibGUoaSksIEZ1bmMoaSwgLTIpKTsKKyAgICBFWFBFQ1RfRVEobWVzc2FnZS5yZXBlYXRlZF9zdHJpbmcoaSksIFN0ckZ1bmMoaSwgLTUpKTsKKyAgICBFWFBFQ1RfRVEobWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UoaSkuYygpLCBGdW5jKGksIC02KSk7CisgICAgZG93bl9jYXN0PEZvcmVpZ25NZXNzYWdlKj4obXJwZl9tZXNzYWdlLT5NdXRhYmxlKGkpKS0+c2V0X2MoRnVuYyhpLCA3KSk7CisgICAgRVhQRUNUX0VRKG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKGkpLmMoKSwgRnVuYyhpLCA3KSk7CisgIH0KKworI2lmZGVmIFBST1RPQlVGX0hBU19ERUFUSF9URVNUCisgIC8vIE1ha2Ugc3VyZSB0eXBlcyBhcmUgY2hlY2tlZCBjb3JyZWN0bHkgYXQgcnVudGltZS4KKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmZF9vcHRpb25hbF9pbnQzMiA9CisgICAgICBkZXNjLT5GaW5kRmllbGRCeU5hbWUoIm9wdGlvbmFsX2ludDMyIik7CisgIEVYUEVDVF9ERUFUSChyZWZsLT5HZXRSZXBlYXRlZEZpZWxkPGludDMyPigKKyAgICAgIG1lc3NhZ2UsIGZkX29wdGlvbmFsX2ludDMyKSwgInJlcXVpcmVzIGEgcmVwZWF0ZWQgZmllbGQiKTsKKyAgRVhQRUNUX0RFQVRIKHJlZmwtPkdldFJlcGVhdGVkRmllbGQ8ZG91YmxlPigKKyAgICAgIG1lc3NhZ2UsIGZkX3JlcGVhdGVkX2ludDMyKSwgIm5vdCB0aGUgcmlnaHQgdHlwZSIpOworICBFWFBFQ1RfREVBVEgocmVmbC0+R2V0UmVwZWF0ZWRQdHJGaWVsZDxUZXN0QWxsVHlwZXM+KAorICAgICAgbWVzc2FnZSwgZmRfcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKSwgIndyb25nIHN1Ym1lc3NhZ2UgdHlwZSIpOworI2VuZGlmICAvLyBQUk9UT0JVRl9IQVNfREVBVEhfVEVTVAorfQorCisKK1RFU1QoUmVwZWF0ZWRGaWVsZFJlZmxlY3Rpb25UZXN0LCBFeHRlbnNpb25GaWVsZHMpIHsKKyAgVGVzdEFsbEV4dGVuc2lvbnMgZXh0ZW5kZWRfbWVzc2FnZTsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbCA9IGV4dGVuZGVkX21lc3NhZ2UuR2V0UmVmbGVjdGlvbigpOworICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjID0gZXh0ZW5kZWRfbWVzc2FnZS5HZXREZXNjcmlwdG9yKCk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgKytpKSB7CisgICAgZXh0ZW5kZWRfbWVzc2FnZS5BZGRFeHRlbnNpb24oCisgICAgICAgIHVuaXR0ZXN0OjpyZXBlYXRlZF9pbnQ2NF9leHRlbnNpb24sIEZ1bmMoaSwgMSkpOworICB9CisKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmZF9yZXBlYXRlZF9pbnQ2NF9leHRlbnNpb24gPQorICAgICAgZGVzYy0+ZmlsZSgpLT5GaW5kRXh0ZW5zaW9uQnlOYW1lKCJyZXBlYXRlZF9pbnQ2NF9leHRlbnNpb24iKTsKKyAgR09PR0xFX0NIRUNLKGZkX3JlcGVhdGVkX2ludDY0X2V4dGVuc2lvbiAhPSBOVUxMKTsKKworICBjb25zdCBSZXBlYXRlZEZpZWxkPGludDY0PiYgcmZfaW50NjRfZXh0ZW5zaW9uID0KKyAgICAgIHJlZmwtPkdldFJlcGVhdGVkRmllbGQ8aW50NjQ+KGV4dGVuZGVkX21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmZF9yZXBlYXRlZF9pbnQ2NF9leHRlbnNpb24pOworCisgIFJlcGVhdGVkRmllbGQ8aW50NjQ+KiBtcmZfaW50NjRfZXh0ZW5zaW9uID0KKyAgICAgIHJlZmwtPk11dGFibGVSZXBlYXRlZEZpZWxkPGludDY0PigmZXh0ZW5kZWRfbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmZF9yZXBlYXRlZF9pbnQ2NF9leHRlbnNpb24pOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7ICsraSkgeworICAgIEVYUEVDVF9FUShGdW5jKGksIDEpLCByZl9pbnQ2NF9leHRlbnNpb24uR2V0KGkpKTsKKyAgICBtcmZfaW50NjRfZXh0ZW5zaW9uLT5TZXQoaSwgRnVuYyhpLCAtMSkpOworICAgIEVYUEVDVF9FUShGdW5jKGksIC0xKSwKKyAgICAgICAgZXh0ZW5kZWRfbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ludDY0X2V4dGVuc2lvbiwgaSkpOworICB9Cit9CisKK3RlbXBsYXRlPHR5cGVuYW1lIFJlZiwgdHlwZW5hbWUgTWVzc2FnZVR5cGUsIHR5cGVuYW1lIFZhbHVlVHlwZT4KK3ZvaWQgVGVzdFJlcGVhdGVkRmllbGRSZWZJdGVyYXRvcigKKyAgICBjb25zdCBSZWYmIGhhbmRsZSwgY29uc3QgTWVzc2FnZVR5cGUmIG1lc3NhZ2UsCisgICAgVmFsdWVUeXBlIChNZXNzYWdlVHlwZTo6KkdldEZ1bmMpKGludCkgY29uc3QpIHsKKyAgaW50IGluZGV4ID0gMDsKKyAgZm9yICh0eXBlbmFtZSBSZWY6OmNvbnN0X2l0ZXJhdG9yIGl0ID0gaGFuZGxlLmJlZ2luKCk7CisgICAgICAgaXQgIT0gaGFuZGxlLmVuZCgpOyArK2l0KSB7CisgICAgRVhQRUNUX0VRKChtZXNzYWdlLipHZXRGdW5jKShpbmRleCksICppdCk7CisgICAgKytpbmRleDsKKyAgfQorICBFWFBFQ1RfRVEoaGFuZGxlLnNpemUoKSwgaW5kZXgpOworfQorCitURVNUKFJlcGVhdGVkRmllbGRSZWZsZWN0aW9uVGVzdCwgUmVwZWF0ZWRGaWVsZFJlZkZvclJlZ3VsYXJGaWVsZHMpIHsKKyAgVGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmwgPSBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKTsKKyAgY29uc3QgRGVzY3JpcHRvciogZGVzYyA9IG1lc3NhZ2UuR2V0RGVzY3JpcHRvcigpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7ICsraSkgeworICAgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX2ludDMyKEZ1bmMoaSwgMSkpOworICAgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX2RvdWJsZShGdW5jKGksIDIpKTsKKyAgICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9zdHJpbmcoU3RyRnVuYyhpLCA1KSk7CisgICAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKCktPnNldF9jKEZ1bmMoaSwgNikpOworICB9CisKKyAgLy8gR2V0IEZpZWxkRGVzY3JpcHRvcnMgZm9yIGFsbCB0aGUgZmllbGRzIG9mIGludGVyZXN0LgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZkX3JlcGVhdGVkX2ludDMyID0KKyAgICAgIGRlc2MtPkZpbmRGaWVsZEJ5TmFtZSgicmVwZWF0ZWRfaW50MzIiKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmZF9yZXBlYXRlZF9kb3VibGUgPQorICAgICAgZGVzYy0+RmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF9kb3VibGUiKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmZF9yZXBlYXRlZF9zdHJpbmcgPQorICAgICAgZGVzYy0+RmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF9zdHJpbmciKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmZF9yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPQorICAgICAgZGVzYy0+RmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UiKTsKKworICAvLyBHZXQgUmVwZWF0ZWRGaWVsZFJlZiBvYmplY3RzIGZvciBhbGwgZmllbGRzIG9mIGludGVyZXN0LgorICBjb25zdCBSZXBlYXRlZEZpZWxkUmVmPGludDMyPiByZl9pbnQzMiA9CisgICAgICByZWZsLT5HZXRSZXBlYXRlZEZpZWxkUmVmPGludDMyPihtZXNzYWdlLCBmZF9yZXBlYXRlZF9pbnQzMik7CisgIGNvbnN0IFJlcGVhdGVkRmllbGRSZWY8ZG91YmxlPiByZl9kb3VibGUgPQorICAgICAgcmVmbC0+R2V0UmVwZWF0ZWRGaWVsZFJlZjxkb3VibGU+KG1lc3NhZ2UsIGZkX3JlcGVhdGVkX2RvdWJsZSk7CisgIGNvbnN0IFJlcGVhdGVkRmllbGRSZWY8c3RyaW5nPiByZl9zdHJpbmcgPQorICAgICAgcmVmbC0+R2V0UmVwZWF0ZWRGaWVsZFJlZjxzdHJpbmc+KG1lc3NhZ2UsIGZkX3JlcGVhdGVkX3N0cmluZyk7CisgIGNvbnN0IFJlcGVhdGVkRmllbGRSZWY8Rm9yZWlnbk1lc3NhZ2U+IHJmX2ZvcmVpZ25fbWVzc2FnZSA9CisgICAgICByZWZsLT5HZXRSZXBlYXRlZEZpZWxkUmVmPEZvcmVpZ25NZXNzYWdlPigKKyAgICAgICAgICBtZXNzYWdlLCBmZF9yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UpOworICBjb25zdCBSZXBlYXRlZEZpZWxkUmVmPE1lc3NhZ2U+IHJmX21lc3NhZ2UgPQorICAgICAgcmVmbC0+R2V0UmVwZWF0ZWRGaWVsZFJlZjxNZXNzYWdlPigKKyAgICAgICAgICBtZXNzYWdlLCBmZF9yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UpOworCisgIC8vIEdldCBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZiBvYmplY3RzIGZvciBhbGwgZmllbGRzIG9mIGludGVyZXN0LgorICBjb25zdCBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxpbnQzMj4gbXJmX2ludDMyID0KKyAgICAgIHJlZmwtPkdldE11dGFibGVSZXBlYXRlZEZpZWxkUmVmPGludDMyPigmbWVzc2FnZSwgZmRfcmVwZWF0ZWRfaW50MzIpOworICBjb25zdCBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxkb3VibGU+IG1yZl9kb3VibGUgPQorICAgICAgcmVmbC0+R2V0TXV0YWJsZVJlcGVhdGVkRmllbGRSZWY8ZG91YmxlPigmbWVzc2FnZSwgZmRfcmVwZWF0ZWRfZG91YmxlKTsKKyAgY29uc3QgTXV0YWJsZVJlcGVhdGVkRmllbGRSZWY8c3RyaW5nPiBtcmZfc3RyaW5nID0KKyAgICAgIHJlZmwtPkdldE11dGFibGVSZXBlYXRlZEZpZWxkUmVmPHN0cmluZz4oJm1lc3NhZ2UsIGZkX3JlcGVhdGVkX3N0cmluZyk7CisgIGNvbnN0IE11dGFibGVSZXBlYXRlZEZpZWxkUmVmPEZvcmVpZ25NZXNzYWdlPiBtcmZfZm9yZWlnbl9tZXNzYWdlID0KKyAgICAgIHJlZmwtPkdldE11dGFibGVSZXBlYXRlZEZpZWxkUmVmPEZvcmVpZ25NZXNzYWdlPigKKyAgICAgICAgICAmbWVzc2FnZSwgZmRfcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKTsKKyAgY29uc3QgTXV0YWJsZVJlcGVhdGVkRmllbGRSZWY8TWVzc2FnZT4gbXJmX21lc3NhZ2UgPQorICAgICAgcmVmbC0+R2V0TXV0YWJsZVJlcGVhdGVkRmllbGRSZWY8TWVzc2FnZT4oCisgICAgICAgICAgJm1lc3NhZ2UsIGZkX3JlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSk7CisKKyAgRVhQRUNUX0VRKG1lc3NhZ2UucmVwZWF0ZWRfaW50MzJfc2l6ZSgpLCByZl9pbnQzMi5zaXplKCkpOworICBFWFBFQ1RfRVEobWVzc2FnZS5yZXBlYXRlZF9pbnQzMl9zaXplKCksIG1yZl9pbnQzMi5zaXplKCkpOworICBFWFBFQ1RfRVEobWVzc2FnZS5yZXBlYXRlZF9kb3VibGVfc2l6ZSgpLCByZl9kb3VibGUuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UucmVwZWF0ZWRfZG91YmxlX3NpemUoKSwgbXJmX2RvdWJsZS5zaXplKCkpOworICBFWFBFQ1RfRVEobWVzc2FnZS5yZXBlYXRlZF9zdHJpbmdfc2l6ZSgpLCByZl9zdHJpbmcuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nX3NpemUoKSwgbXJmX3N0cmluZy5zaXplKCkpOworICBFWFBFQ1RfRVEobWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2Vfc2l6ZSgpLAorICAgICAgICAgICAgcmZfZm9yZWlnbl9tZXNzYWdlLnNpemUoKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlLnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZV9zaXplKCksCisgICAgICAgICAgICBtcmZfZm9yZWlnbl9tZXNzYWdlLnNpemUoKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlLnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZV9zaXplKCksIHJmX21lc3NhZ2Uuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX3NpemUoKSwgbXJmX21lc3NhZ2Uuc2l6ZSgpKTsKKworICBFWFBFQ1RfRkFMU0UocmZfaW50MzIuZW1wdHkoKSk7CisgIEVYUEVDVF9GQUxTRShtcmZfaW50MzIuZW1wdHkoKSk7CisgIEVYUEVDVF9GQUxTRShyZl9kb3VibGUuZW1wdHkoKSk7CisgIEVYUEVDVF9GQUxTRShtcmZfZG91YmxlLmVtcHR5KCkpOworICBFWFBFQ1RfRkFMU0UocmZfc3RyaW5nLmVtcHR5KCkpOworICBFWFBFQ1RfRkFMU0UobXJmX3N0cmluZy5lbXB0eSgpKTsKKyAgRVhQRUNUX0ZBTFNFKHJmX2ZvcmVpZ25fbWVzc2FnZS5lbXB0eSgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1yZl9mb3JlaWduX21lc3NhZ2UuZW1wdHkoKSk7CisgIEVYUEVDVF9GQUxTRShyZl9tZXNzYWdlLmVtcHR5KCkpOworICBFWFBFQ1RfRkFMU0UobXJmX21lc3NhZ2UuZW1wdHkoKSk7CisKKyAgLy8gTWFrZSBzdXJlIHdlIGNhbiBkbyBnZXRzIGFuZCBzZXRzIHRocm91Z2ggdGhlIFJlcGVhdGVkRmllbGRSZWYgb2JqZWN0cy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgKytpKSB7CisgICAgLy8gQ2hlY2sgZ2V0cyB0aHJvdWdoIGNvbnN0IG9iamVjdHMuCisgICAgRVhQRUNUX0VRKHJmX2ludDMyLkdldChpKSwgRnVuYyhpLCAxKSk7CisgICAgRVhQRUNUX0VRKHJmX2RvdWJsZS5HZXQoaSksIEZ1bmMoaSwgMikpOworICAgIEVYUEVDVF9FUShyZl9zdHJpbmcuR2V0KGkpLCBTdHJGdW5jKGksIDUpKTsKKyAgICBGb3JlaWduTWVzc2FnZSBzY3JhdGNoX3NwYWNlOworICAgIEVYUEVDVF9FUShyZl9mb3JlaWduX21lc3NhZ2UuR2V0KGksICZzY3JhdGNoX3NwYWNlKS5jKCksIEZ1bmMoaSwgNikpOworICAgIEVYUEVDVF9FUShkb3duX2Nhc3Q8Y29uc3QgRm9yZWlnbk1lc3NhZ2UmPigKKyAgICAgICAgcmZfbWVzc2FnZS5HZXQoaSwgJnNjcmF0Y2hfc3BhY2UpKS5jKCksIEZ1bmMoaSwgNikpOworCisgICAgLy8gQ2hlY2sgZ2V0cyB0aHJvdWdoIG11dGFibGUgb2JqZWN0cy4KKyAgICBFWFBFQ1RfRVEobXJmX2ludDMyLkdldChpKSwgRnVuYyhpLCAxKSk7CisgICAgRVhQRUNUX0VRKG1yZl9kb3VibGUuR2V0KGkpLCBGdW5jKGksIDIpKTsKKyAgICBFWFBFQ1RfRVEobXJmX3N0cmluZy5HZXQoaSksIFN0ckZ1bmMoaSwgNSkpOworICAgIEVYUEVDVF9FUShtcmZfZm9yZWlnbl9tZXNzYWdlLkdldChpLCAmc2NyYXRjaF9zcGFjZSkuYygpLCBGdW5jKGksIDYpKTsKKyAgICBFWFBFQ1RfRVEoZG93bl9jYXN0PGNvbnN0IEZvcmVpZ25NZXNzYWdlJj4oCisgICAgICAgIG1yZl9tZXNzYWdlLkdldChpLCAmc2NyYXRjaF9zcGFjZSkpLmMoKSwgRnVuYyhpLCA2KSk7CisKKyAgICAvLyBDaGVjayBzZXRzIHRocm91Z2ggbXV0YWJsZSBvYmplY3RzLgorICAgIG1yZl9pbnQzMi5TZXQoaSwgRnVuYyhpLCAtMSkpOworICAgIG1yZl9kb3VibGUuU2V0KGksIEZ1bmMoaSwgLTIpKTsKKyAgICBtcmZfc3RyaW5nLlNldChpLCBTdHJGdW5jKGksIC01KSk7CisgICAgRm9yZWlnbk1lc3NhZ2UgZm9yZWlnbl9tZXNzYWdlOworICAgIGZvcmVpZ25fbWVzc2FnZS5zZXRfYyhGdW5jKGksIC02KSk7CisgICAgbXJmX2ZvcmVpZ25fbWVzc2FnZS5TZXQoaSwgZm9yZWlnbl9tZXNzYWdlKTsKKyAgICBFWFBFQ1RfRVEobWVzc2FnZS5yZXBlYXRlZF9pbnQzMihpKSwgRnVuYyhpLCAtMSkpOworICAgIEVYUEVDVF9FUShtZXNzYWdlLnJlcGVhdGVkX2RvdWJsZShpKSwgRnVuYyhpLCAtMikpOworICAgIEVYUEVDVF9FUShtZXNzYWdlLnJlcGVhdGVkX3N0cmluZyhpKSwgU3RyRnVuYyhpLCAtNSkpOworICAgIEVYUEVDVF9FUShtZXNzYWdlLnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZShpKS5jKCksIEZ1bmMoaSwgLTYpKTsKKyAgICBmb3JlaWduX21lc3NhZ2Uuc2V0X2MoRnVuYyhpLCA3KSk7CisgICAgbXJmX21lc3NhZ2UuU2V0KGksIGZvcmVpZ25fbWVzc2FnZSk7CisgICAgRVhQRUNUX0VRKG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKGkpLmMoKSwgRnVuYyhpLCA3KSk7CisgIH0KKworICAvLyBUZXN0IGl0ZXJhdG9ycy4KKyAgVGVzdFJlcGVhdGVkRmllbGRSZWZJdGVyYXRvcihyZl9pbnQzMiwgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmVGVzdEFsbFR5cGVzOjpyZXBlYXRlZF9pbnQzMik7CisgIFRlc3RSZXBlYXRlZEZpZWxkUmVmSXRlcmF0b3IocmZfZG91YmxlLCBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZUZXN0QWxsVHlwZXM6OnJlcGVhdGVkX2RvdWJsZSk7CisgIFRlc3RSZXBlYXRlZEZpZWxkUmVmSXRlcmF0b3IocmZfc3RyaW5nLCBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZUZXN0QWxsVHlwZXM6OnJlcGVhdGVkX3N0cmluZyk7CisKKyAgLy8gVGVzdCBpdGVyYXRvcnMgZm9yIG1lc3NhZ2UgZmllbGRzLgorICB0eXBlZGVmIFJlcGVhdGVkRmllbGRSZWY8Rm9yZWlnbk1lc3NhZ2U+OjppdGVyYXRvciBNZXNzYWdlSXRlcmF0b3I7CisgIGludCBpbmRleCA9IDA7CisgIGZvciAoTWVzc2FnZUl0ZXJhdG9yIGl0ID0gcmZfZm9yZWlnbl9tZXNzYWdlLmJlZ2luKCk7CisgICAgICAgaXQgIT0gcmZfZm9yZWlnbl9tZXNzYWdlLmVuZCgpOyArK2l0KSB7CisgICAgRVhQRUNUX0VRKG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKGluZGV4KS5jKCksIGl0LT5jKCkpOworICAgICsraW5kZXg7CisgIH0KKyAgRVhQRUNUX0VRKDEwLCBpbmRleCk7CisKKyAgLy8gVGVzdCBpdGVyYXRvciBvcGVyYXRvcnMgdGhhdCBhcmUgbm90IHVzdXNhbGx5IHVzZWQgaW4gcmVndWxhciBmb3ItbG9vcHMuCisgIC8vIEluY2x1ZGluZzogcG9zdCBpbmNyZW1lbnQsIGFzc2lnbiwgPT0uCisgIE1lc3NhZ2VJdGVyYXRvciBvbGRfaXQgPSByZl9mb3JlaWduX21lc3NhZ2UuYmVnaW4oKTsKKyAgTWVzc2FnZUl0ZXJhdG9yIG5ld19pdCA9IG9sZF9pdCsrOworICBFWFBFQ1RfRkFMU0Uob2xkX2l0ID09IG5ld19pdCk7CisgIC8vIENoZWNrIHRoYXQgb2xkX2l0KysgaW5jcmVtZW50cyBvbGRfaXQgb25jZS4KKyAgZm9yIChpbmRleCA9IDE7IG9sZF9pdCAhPSByZl9mb3JlaWduX21lc3NhZ2UuZW5kKCk7ICsrb2xkX2l0LCArK2luZGV4KSB7CisgICAgRVhQRUNUX0VRKG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKGluZGV4KS5jKCksIG9sZF9pdC0+YygpKTsKKyAgfQorICBFWFBFQ1RfRVEoMTAsIGluZGV4KTsKKyAgLy8gVGVzdCBhc3NpZ24gb3BlcmF0b3IuCisgIG9sZF9pdCA9IG5ld19pdDsKKyAgZm9yIChpbmRleCA9IDA7IG9sZF9pdCAhPSByZl9mb3JlaWduX21lc3NhZ2UuZW5kKCk7ICsrb2xkX2l0LCArK2luZGV4KSB7CisgICAgRVhQRUNUX0VRKG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKGluZGV4KS5jKCksIG9sZF9pdC0+YygpKTsKKyAgfQorICBFWFBFQ1RfRVEoMTAsIGluZGV4KTsKKyAgLy8gQ2hlY2sgdGhhdCB0aGUgcmV0dXJuZWQgdmFsdWUgb2Ygb2xkX2l0KysgaXMgdGhlIG9uZSBiZWZvcmUgaW5jcmVtZW50LgorICBmb3IgKGluZGV4ID0gMDsgbmV3X2l0ICE9IHJmX2ZvcmVpZ25fbWVzc2FnZS5lbmQoKTsgKytuZXdfaXQsICsraW5kZXgpIHsKKyAgICBFWFBFQ1RfRVEobWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UoaW5kZXgpLmMoKSwgbmV3X2l0LT5jKCkpOworICB9CisgIEVYUEVDVF9FUSgxMCwgaW5kZXgpOworCisgIC8vIFRlc3QgTXV0YWJsZVJlcGVhdGVkRmllbGRSZWY6OkFkZCgpCisgIG1yZl9pbnQzMi5BZGQoMTIzNCk7CisgIG1yZl9kb3VibGUuQWRkKDEyMzQuMCk7CisgIG1yZl9zdHJpbmcuQWRkKCIxMjM0Iik7CisgIEZvcmVpZ25NZXNzYWdlIGZvcmVpZ25fbWVzc2FnZTsKKyAgZm9yZWlnbl9tZXNzYWdlLnNldF9jKDEyMzQpOworICBtcmZfZm9yZWlnbl9tZXNzYWdlLkFkZChmb3JlaWduX21lc3NhZ2UpOworICBFWFBFQ1RfRVEoMTIzNCwgbWVzc2FnZS5yZXBlYXRlZF9pbnQzMigxMCkpOworICBFWFBFQ1RfRVEoMTIzNC4wLCBtZXNzYWdlLnJlcGVhdGVkX2RvdWJsZSgxMCkpOworICBFWFBFQ1RfRVEoIjEyMzQiLCBtZXNzYWdlLnJlcGVhdGVkX3N0cmluZygxMCkpOworICBFWFBFQ1RfRVEoMTIzNCwgbWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UoMTApLmMoKSk7CisKKyAgLy8gVGVzdCBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjo6UmVtb3ZlTGFzdCgpCisgIG1yZl9pbnQzMi5SZW1vdmVMYXN0KCk7CisgIG1yZl9kb3VibGUuUmVtb3ZlTGFzdCgpOworICBtcmZfc3RyaW5nLlJlbW92ZUxhc3QoKTsKKyAgbXJmX2ZvcmVpZ25fbWVzc2FnZS5SZW1vdmVMYXN0KCk7CisgIEVYUEVDVF9FUSgxMCwgbWVzc2FnZS5yZXBlYXRlZF9pbnQzMl9zaXplKCkpOworICBFWFBFQ1RfRVEoMTAsIG1lc3NhZ2UucmVwZWF0ZWRfZG91YmxlX3NpemUoKSk7CisgIEVYUEVDVF9FUSgxMCwgbWVzc2FnZS5yZXBlYXRlZF9zdHJpbmdfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEwLCBtZXNzYWdlLnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZV9zaXplKCkpOworCisgIC8vIFRlc3QgTXV0YWJsZVJlcGVhdGVkRmllbGRSZWY6OlN3YXBFbGVtZW50cygpCisgIG1yZl9pbnQzMi5Td2FwRWxlbWVudHMoMCwgOSk7CisgIG1yZl9kb3VibGUuU3dhcEVsZW1lbnRzKDAsIDkpOworICBtcmZfc3RyaW5nLlN3YXBFbGVtZW50cygwLCA5KTsKKyAgbXJmX2ZvcmVpZ25fbWVzc2FnZS5Td2FwRWxlbWVudHMoMCwgOSk7CisgIEVYUEVDVF9FUShGdW5jKDksIC0xKSwgbWVzc2FnZS5yZXBlYXRlZF9pbnQzMigwKSk7CisgIEVYUEVDVF9FUShGdW5jKDAsIC0xKSwgbWVzc2FnZS5yZXBlYXRlZF9pbnQzMig5KSk7CisgIEVYUEVDVF9FUShGdW5jKDksIC0yKSwgbWVzc2FnZS5yZXBlYXRlZF9kb3VibGUoMCkpOworICBFWFBFQ1RfRVEoRnVuYygwLCAtMiksIG1lc3NhZ2UucmVwZWF0ZWRfZG91YmxlKDkpKTsKKyAgRVhQRUNUX0VRKFN0ckZ1bmMoOSwgLTUpLCBtZXNzYWdlLnJlcGVhdGVkX3N0cmluZygwKSk7CisgIEVYUEVDVF9FUShTdHJGdW5jKDAsIC01KSwgbWVzc2FnZS5yZXBlYXRlZF9zdHJpbmcoOSkpOworICBFWFBFQ1RfRVEoRnVuYyg5LCA3KSwgbWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UoMCkuYygpKTsKKyAgRVhQRUNUX0VRKEZ1bmMoMCwgNyksIG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKDkpLmMoKSk7CisKKyAgLy8gVGVzdCBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjo6Q2xlYXIoKQorICBtcmZfaW50MzIuQ2xlYXIoKTsKKyAgbXJmX2RvdWJsZS5DbGVhcigpOworICBtcmZfc3RyaW5nLkNsZWFyKCk7CisgIG1yZl9mb3JlaWduX21lc3NhZ2UuQ2xlYXIoKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucmVwZWF0ZWRfaW50MzJfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucmVwZWF0ZWRfZG91YmxlX3NpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX3N0cmluZ19zaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2Vfc2l6ZSgpKTsKKworICAvLyBUZXN0IChNdXRhYmxlKVJlcGVhdGVkRmllbGRSZWY6OmVtcHR5KCkKKyAgRVhQRUNUX1RSVUUocmZfaW50MzIuZW1wdHkoKSk7CisgIEVYUEVDVF9UUlVFKG1yZl9pbnQzMi5lbXB0eSgpKTsKKyAgRVhQRUNUX1RSVUUocmZfZG91YmxlLmVtcHR5KCkpOworICBFWFBFQ1RfVFJVRShtcmZfZG91YmxlLmVtcHR5KCkpOworICBFWFBFQ1RfVFJVRShyZl9zdHJpbmcuZW1wdHkoKSk7CisgIEVYUEVDVF9UUlVFKG1yZl9zdHJpbmcuZW1wdHkoKSk7CisgIEVYUEVDVF9UUlVFKHJmX2ZvcmVpZ25fbWVzc2FnZS5lbXB0eSgpKTsKKyAgRVhQRUNUX1RSVUUobXJmX2ZvcmVpZ25fbWVzc2FnZS5lbXB0eSgpKTsKKyAgRVhQRUNUX1RSVUUocmZfbWVzc2FnZS5lbXB0eSgpKTsKKyAgRVhQRUNUX1RSVUUobXJmX21lc3NhZ2UuZW1wdHkoKSk7CisKKyNpZmRlZiBQUk9UT0JVRl9IQVNfREVBVEhfVEVTVAorCisgIC8vIE1ha2Ugc3VyZSB0eXBlcyBhcmUgY2hlY2tlZCBjb3JyZWN0bHkgYXQgcnVudGltZS4KKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmZF9vcHRpb25hbF9pbnQzMiA9CisgICAgICBkZXNjLT5GaW5kRmllbGRCeU5hbWUoIm9wdGlvbmFsX2ludDMyIik7CisgIEVYUEVDVF9ERUFUSChyZWZsLT5HZXRSZXBlYXRlZEZpZWxkUmVmPGludDMyPigKKyAgICAgIG1lc3NhZ2UsIGZkX29wdGlvbmFsX2ludDMyKSwgIiIpOworICBFWFBFQ1RfREVBVEgocmVmbC0+R2V0UmVwZWF0ZWRGaWVsZFJlZjxkb3VibGU+KAorICAgICAgbWVzc2FnZSwgZmRfcmVwZWF0ZWRfaW50MzIpLCAiIik7CisgIEVYUEVDVF9ERUFUSChyZWZsLT5HZXRSZXBlYXRlZEZpZWxkUmVmPFRlc3RBbGxUeXBlcz4oCisgICAgICBtZXNzYWdlLCBmZF9yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UpLCAiIik7CisKKyNlbmRpZiAgLy8gUFJPVE9CVUZfSEFTX0RFQVRIX1RFU1QKK30KKworVEVTVChSZXBlYXRlZEZpZWxkUmVmbGVjdGlvblRlc3QsIFJlcGVhdGVkRmllbGRSZWZGb3JFbnVtcykgeworICBUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbCA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpOworICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjID0gbWVzc2FnZS5HZXREZXNjcmlwdG9yKCk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgKytpKSB7CisgICAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfbmVzdGVkX2VudW0oVGVzdEFsbFR5cGVzOjpCQVIpOworICB9CisKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmZF9yZXBlYXRlZF9uZXN0ZWRfZW51bSA9CisgICAgICBkZXNjLT5GaW5kRmllbGRCeU5hbWUoInJlcGVhdGVkX25lc3RlZF9lbnVtIik7CisgIGNvbnN0IFJlcGVhdGVkRmllbGRSZWY8VGVzdEFsbFR5cGVzOjpOZXN0ZWRFbnVtPiBlbnVtX3JlZiA9CisgICAgICByZWZsLT5HZXRSZXBlYXRlZEZpZWxkUmVmPFRlc3RBbGxUeXBlczo6TmVzdGVkRW51bT4oCisgICAgICAgICAgbWVzc2FnZSwgZmRfcmVwZWF0ZWRfbmVzdGVkX2VudW0pOworICBjb25zdCBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxUZXN0QWxsVHlwZXM6Ok5lc3RlZEVudW0+CisgIG11dGFibGVfZW51bV9yZWYgPQorICAgICAgcmVmbC0+R2V0TXV0YWJsZVJlcGVhdGVkRmllbGRSZWY8VGVzdEFsbFR5cGVzOjpOZXN0ZWRFbnVtPigKKyAgICAgICAgICAmbWVzc2FnZSwgZmRfcmVwZWF0ZWRfbmVzdGVkX2VudW0pOworICBjb25zdCBSZXBlYXRlZEZpZWxkUmVmPGludDMyPiBpbnQzMl9yZWYgPQorICAgICAgcmVmbC0+R2V0UmVwZWF0ZWRGaWVsZFJlZjxpbnQzMj4oCisgICAgICAgICAgbWVzc2FnZSwgZmRfcmVwZWF0ZWRfbmVzdGVkX2VudW0pOworICBjb25zdCBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxpbnQzMj4gbXV0YWJsZV9pbnQzMl9yZWYgPQorICAgICAgcmVmbC0+R2V0TXV0YWJsZVJlcGVhdGVkRmllbGRSZWY8aW50MzI+KAorICAgICAgICAgICZtZXNzYWdlLCBmZF9yZXBlYXRlZF9uZXN0ZWRfZW51bSk7CisKKyAgRVhQRUNUX0VRKG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX2VudW1fc2l6ZSgpLCBlbnVtX3JlZi5zaXplKCkpOworICBFWFBFQ1RfRVEobWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfZW51bV9zaXplKCksIG11dGFibGVfZW51bV9yZWYuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX2VudW1fc2l6ZSgpLCBpbnQzMl9yZWYuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX2VudW1fc2l6ZSgpLCBtdXRhYmxlX2ludDMyX3JlZi5zaXplKCkpOworCisgIEVYUEVDVF9GQUxTRShlbnVtX3JlZi5lbXB0eSgpKTsKKyAgRVhQRUNUX0ZBTFNFKG11dGFibGVfZW51bV9yZWYuZW1wdHkoKSk7CisgIEVYUEVDVF9GQUxTRShpbnQzMl9yZWYuZW1wdHkoKSk7CisgIEVYUEVDVF9GQUxTRShtdXRhYmxlX2ludDMyX3JlZi5lbXB0eSgpKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyArK2kpIHsKKyAgICBFWFBFQ1RfRVEoVGVzdEFsbFR5cGVzOjpCQVIsIGVudW1fcmVmLkdldChpKSk7CisgICAgRVhQRUNUX0VRKFRlc3RBbGxUeXBlczo6QkFSLCBtdXRhYmxlX2VudW1fcmVmLkdldChpKSk7CisgICAgbXV0YWJsZV9lbnVtX3JlZi5TZXQoaSwgVGVzdEFsbFR5cGVzOjpCQVopOworICAgIEVYUEVDVF9FUShUZXN0QWxsVHlwZXM6OkJBWiwgZW51bV9yZWYuR2V0KGkpKTsKKyAgICBFWFBFQ1RfRVEoVGVzdEFsbFR5cGVzOjpCQVosIG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX2VudW0oaSkpOworCisgICAgbWVzc2FnZS5zZXRfcmVwZWF0ZWRfbmVzdGVkX2VudW0oaSwgVGVzdEFsbFR5cGVzOjpCQVIpOworICAgIEVYUEVDVF9FUShUZXN0QWxsVHlwZXM6OkJBUiwgaW50MzJfcmVmLkdldChpKSk7CisgICAgRVhQRUNUX0VRKFRlc3RBbGxUeXBlczo6QkFSLCBtdXRhYmxlX2ludDMyX3JlZi5HZXQoaSkpOworICAgIG11dGFibGVfaW50MzJfcmVmLlNldChpLCBUZXN0QWxsVHlwZXM6OkJBWik7CisgICAgRVhQRUNUX0VRKFRlc3RBbGxUeXBlczo6QkFaLCBpbnQzMl9yZWYuR2V0KGkpKTsKKyAgICBFWFBFQ1RfRVEoVGVzdEFsbFR5cGVzOjpCQVosIG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX2VudW0oaSkpOworICB9CisKKyAgVGVzdFJlcGVhdGVkRmllbGRSZWZJdGVyYXRvcihlbnVtX3JlZiwgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmVGVzdEFsbFR5cGVzOjpyZXBlYXRlZF9uZXN0ZWRfZW51bSk7CisgIFRlc3RSZXBlYXRlZEZpZWxkUmVmSXRlcmF0b3IoaW50MzJfcmVmLCBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZUZXN0QWxsVHlwZXM6OnJlcGVhdGVkX25lc3RlZF9lbnVtKTsKKworICAvLyBUZXN0IEFkZCgpCisgIG11dGFibGVfZW51bV9yZWYuQWRkKFRlc3RBbGxUeXBlczo6Rk9PKTsKKyAgRVhQRUNUX0VRKFRlc3RBbGxUeXBlczo6Rk9PLCBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9lbnVtKDEwKSk7CisgIG11dGFibGVfaW50MzJfcmVmLkFkZChUZXN0QWxsVHlwZXM6OkJBUik7CisgIEVYUEVDVF9FUShUZXN0QWxsVHlwZXM6OkJBUiwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfZW51bSgxMSkpOworCisgIC8vIFRlc3QgUmVtb3ZlTGFzdCgpCisgIG11dGFibGVfZW51bV9yZWYuUmVtb3ZlTGFzdCgpOworICBFWFBFQ1RfRVEoMTEsIG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX2VudW1fc2l6ZSgpKTsKKyAgbXV0YWJsZV9pbnQzMl9yZWYuUmVtb3ZlTGFzdCgpOworICBFWFBFQ1RfRVEoMTAsIG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX2VudW1fc2l6ZSgpKTsKKworICAvLyBUZXN0IFN3YXBFbGVtZW50cygpCisgIG11dGFibGVfZW51bV9yZWYuU2V0KDAsIFRlc3RBbGxUeXBlczo6QkFSKTsKKyAgbXV0YWJsZV9lbnVtX3JlZi5TZXQoOSwgVGVzdEFsbFR5cGVzOjpCQVopOworICBtdXRhYmxlX2VudW1fcmVmLlN3YXBFbGVtZW50cygwLCA5KTsKKyAgRVhQRUNUX0VRKFRlc3RBbGxUeXBlczo6QkFaLCBlbnVtX3JlZi5HZXQoMCkpOworICBFWFBFQ1RfRVEoVGVzdEFsbFR5cGVzOjpCQVIsIGVudW1fcmVmLkdldCg5KSk7CisgIG11dGFibGVfaW50MzJfcmVmLlN3YXBFbGVtZW50cygwLCA5KTsKKyAgRVhQRUNUX0VRKFRlc3RBbGxUeXBlczo6QkFSLCBlbnVtX3JlZi5HZXQoMCkpOworICBFWFBFQ1RfRVEoVGVzdEFsbFR5cGVzOjpCQVosIGVudW1fcmVmLkdldCg5KSk7CisKKyAgLy8gVGVzdCBDbGVhcigpCisgIG11dGFibGVfZW51bV9yZWYuQ2xlYXIoKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX2VudW1fc2l6ZSgpKTsKKyAgbXV0YWJsZV9lbnVtX3JlZi5BZGQoVGVzdEFsbFR5cGVzOjpGT08pOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfZW51bV9zaXplKCkpOworICBtdXRhYmxlX2ludDMyX3JlZi5DbGVhcigpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfZW51bV9zaXplKCkpOworCisgIC8vIFRlc3QgZW1wdHkoKQorICBFWFBFQ1RfVFJVRShlbnVtX3JlZi5lbXB0eSgpKTsKKyAgRVhQRUNUX1RSVUUobXV0YWJsZV9lbnVtX3JlZi5lbXB0eSgpKTsKKyAgRVhQRUNUX1RSVUUoaW50MzJfcmVmLmVtcHR5KCkpOworICBFWFBFQ1RfVFJVRShtdXRhYmxlX2ludDMyX3JlZi5lbXB0eSgpKTsKK30KKworVEVTVChSZXBlYXRlZEZpZWxkUmVmbGVjdGlvblRlc3QsIFJlcGVhdGVkRmllbGRSZWZGb3JFeHRlbnNpb25GaWVsZHMpIHsKKyAgVGVzdEFsbEV4dGVuc2lvbnMgZXh0ZW5kZWRfbWVzc2FnZTsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbCA9IGV4dGVuZGVkX21lc3NhZ2UuR2V0UmVmbGVjdGlvbigpOworICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjID0gZXh0ZW5kZWRfbWVzc2FnZS5HZXREZXNjcmlwdG9yKCk7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgKytpKSB7CisgICAgZXh0ZW5kZWRfbWVzc2FnZS5BZGRFeHRlbnNpb24oCisgICAgICAgIHVuaXR0ZXN0OjpyZXBlYXRlZF9pbnQ2NF9leHRlbnNpb24sIEZ1bmMoaSwgMSkpOworICB9CisKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmZF9yZXBlYXRlZF9pbnQ2NF9leHRlbnNpb24gPQorICAgICAgZGVzYy0+ZmlsZSgpLT5GaW5kRXh0ZW5zaW9uQnlOYW1lKCJyZXBlYXRlZF9pbnQ2NF9leHRlbnNpb24iKTsKKyAgR09PR0xFX0NIRUNLKGZkX3JlcGVhdGVkX2ludDY0X2V4dGVuc2lvbiAhPSBOVUxMKTsKKworICBjb25zdCBSZXBlYXRlZEZpZWxkUmVmPGludDY0PiByZl9pbnQ2NF9leHRlbnNpb24gPQorICAgICAgcmVmbC0+R2V0UmVwZWF0ZWRGaWVsZFJlZjxpbnQ2ND4oZXh0ZW5kZWRfbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZkX3JlcGVhdGVkX2ludDY0X2V4dGVuc2lvbik7CisKKyAgY29uc3QgTXV0YWJsZVJlcGVhdGVkRmllbGRSZWY8aW50NjQ+IG1yZl9pbnQ2NF9leHRlbnNpb24gPQorICAgICAgcmVmbC0+R2V0TXV0YWJsZVJlcGVhdGVkRmllbGRSZWY8aW50NjQ+KCZleHRlbmRlZF9tZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZkX3JlcGVhdGVkX2ludDY0X2V4dGVuc2lvbik7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgKytpKSB7CisgICAgRVhQRUNUX0VRKEZ1bmMoaSwgMSksIHJmX2ludDY0X2V4dGVuc2lvbi5HZXQoaSkpOworICAgIG1yZl9pbnQ2NF9leHRlbnNpb24uU2V0KGksIEZ1bmMoaSwgLTEpKTsKKyAgICBFWFBFQ1RfRVEoRnVuYyhpLCAtMSksCisgICAgICAgIGV4dGVuZGVkX21lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbnQ2NF9leHRlbnNpb24sIGkpKTsKKyAgfQorfQorCisKK1RFU1QoUmVwZWF0ZWRGaWVsZFJlZmxlY3Rpb25UZXN0LCBSZXBlYXRlZEZpZWxkUmVmTWVyZ2VGcm9tQW5kU3dhcCkgeworICAvLyBTZXQtdXAgbWVzc2FnZSBjb250ZW50LgorICBUZXN0QWxsVHlwZXMgbTAsIG0xLCBtMjsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgKytpKSB7CisgICAgbTAuYWRkX3JlcGVhdGVkX2ludDMyKEZ1bmMoaSwgMSkpOworICAgIG0wLmFkZF9yZXBlYXRlZF9kb3VibGUoRnVuYyhpLCAyKSk7CisgICAgbTAuYWRkX3JlcGVhdGVkX3N0cmluZyhTdHJGdW5jKGksIDUpKTsKKyAgICBtMC5hZGRfcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKCktPnNldF9jKEZ1bmMoaSwgNikpOworICAgIG0wLmFkZF9yZXBlYXRlZF9uZXN0ZWRfZW51bShUZXN0QWxsVHlwZXM6OkZPTyk7CisgICAgbTEuYWRkX3JlcGVhdGVkX2ludDMyKEZ1bmMoaSwgMTEpKTsKKyAgICBtMS5hZGRfcmVwZWF0ZWRfZG91YmxlKEZ1bmMoaSwgMTIpKTsKKyAgICBtMS5hZGRfcmVwZWF0ZWRfc3RyaW5nKFN0ckZ1bmMoaSwgMTUpKTsKKyAgICBtMS5hZGRfcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKCktPnNldF9jKEZ1bmMoaSwgMTYpKTsKKyAgICBtMS5hZGRfcmVwZWF0ZWRfbmVzdGVkX2VudW0oVGVzdEFsbFR5cGVzOjpCQVIpOworICAgIG0yLmFkZF9yZXBlYXRlZF9pbnQzMihGdW5jKGksIDIxKSk7CisgICAgbTIuYWRkX3JlcGVhdGVkX2RvdWJsZShGdW5jKGksIDIyKSk7CisgICAgbTIuYWRkX3JlcGVhdGVkX3N0cmluZyhTdHJGdW5jKGksIDI1KSk7CisgICAgbTIuYWRkX3JlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSgpLT5zZXRfYyhGdW5jKGksIDI2KSk7CisgICAgbTIuYWRkX3JlcGVhdGVkX25lc3RlZF9lbnVtKFRlc3RBbGxUeXBlczo6QkFaKTsKKyAgfQorCisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmwgPSBtMC5HZXRSZWZsZWN0aW9uKCk7CisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2MgPSBtMC5HZXREZXNjcmlwdG9yKCk7CisKKyAgLy8gR2V0IEZpZWxkRGVzY3JpcHRvcnMgZm9yIGFsbCB0aGUgZmllbGRzIG9mIGludGVyZXN0LgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZkX3JlcGVhdGVkX2ludDMyID0KKyAgICAgIGRlc2MtPkZpbmRGaWVsZEJ5TmFtZSgicmVwZWF0ZWRfaW50MzIiKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmZF9yZXBlYXRlZF9kb3VibGUgPQorICAgICAgZGVzYy0+RmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF9kb3VibGUiKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmZF9yZXBlYXRlZF9zdHJpbmcgPQorICAgICAgZGVzYy0+RmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF9zdHJpbmciKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmZF9yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPQorICAgICAgZGVzYy0+RmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UiKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmZF9yZXBlYXRlZF9uZXN0ZWRfZW51bSA9CisgICAgICBkZXNjLT5GaW5kRmllbGRCeU5hbWUoInJlcGVhdGVkX25lc3RlZF9lbnVtIik7CisKKyAgLy8gR2V0IE11dGFibGVSZXBlYXRlZEZpZWxkUmVmIG9iamVjdHMgZm9yIGFsbCBmaWVsZHMgb2YgaW50ZXJlc3QuCisgIGNvbnN0IE11dGFibGVSZXBlYXRlZEZpZWxkUmVmPGludDMyPiBtcmZfaW50MzIgPQorICAgICAgcmVmbC0+R2V0TXV0YWJsZVJlcGVhdGVkRmllbGRSZWY8aW50MzI+KCZtMCwgZmRfcmVwZWF0ZWRfaW50MzIpOworICBjb25zdCBNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxkb3VibGU+IG1yZl9kb3VibGUgPQorICAgICAgcmVmbC0+R2V0TXV0YWJsZVJlcGVhdGVkRmllbGRSZWY8ZG91YmxlPigmbTAsIGZkX3JlcGVhdGVkX2RvdWJsZSk7CisgIGNvbnN0IE11dGFibGVSZXBlYXRlZEZpZWxkUmVmPHN0cmluZz4gbXJmX3N0cmluZyA9CisgICAgICByZWZsLT5HZXRNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxzdHJpbmc+KCZtMCwgZmRfcmVwZWF0ZWRfc3RyaW5nKTsKKyAgY29uc3QgTXV0YWJsZVJlcGVhdGVkRmllbGRSZWY8Rm9yZWlnbk1lc3NhZ2U+IG1yZl9mb3JlaWduX21lc3NhZ2UgPQorICAgICAgcmVmbC0+R2V0TXV0YWJsZVJlcGVhdGVkRmllbGRSZWY8Rm9yZWlnbk1lc3NhZ2U+KAorICAgICAgICAgICZtMCwgZmRfcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKTsKKyAgY29uc3QgTXV0YWJsZVJlcGVhdGVkRmllbGRSZWY8VGVzdEFsbFR5cGVzOjpOZXN0ZWRFbnVtPgorICBtcmZfbmVzdGVkX2VudW0gPQorICAgICAgcmVmbC0+R2V0TXV0YWJsZVJlcGVhdGVkRmllbGRSZWY8VGVzdEFsbFR5cGVzOjpOZXN0ZWRFbnVtPigKKyAgICAgICAgICAmbTAsIGZkX3JlcGVhdGVkX25lc3RlZF9lbnVtKTsKKworICAvLyBUZXN0IE11dGFibGVSZXBlYXRlZFJlZjo6Q29weUZyb20KKyAgbXJmX2ludDMyLkNvcHlGcm9tKAorICAgICAgcmVmbC0+R2V0UmVwZWF0ZWRGaWVsZFJlZjxpbnQzMj4obTEsIGZkX3JlcGVhdGVkX2ludDMyKSk7CisgIG1yZl9kb3VibGUuQ29weUZyb20oCisgICAgICByZWZsLT5HZXRSZXBlYXRlZEZpZWxkUmVmPGRvdWJsZT4obTEsIGZkX3JlcGVhdGVkX2RvdWJsZSkpOworICBtcmZfc3RyaW5nLkNvcHlGcm9tKAorICAgICAgcmVmbC0+R2V0UmVwZWF0ZWRGaWVsZFJlZjxzdHJpbmc+KG0xLCBmZF9yZXBlYXRlZF9zdHJpbmcpKTsKKyAgbXJmX2ZvcmVpZ25fbWVzc2FnZS5Db3B5RnJvbSgKKyAgICAgIHJlZmwtPkdldFJlcGVhdGVkRmllbGRSZWY8Rm9yZWlnbk1lc3NhZ2U+KAorICAgICAgICAgIG0xLCBmZF9yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UpKTsKKyAgbXJmX25lc3RlZF9lbnVtLkNvcHlGcm9tKAorICAgICAgcmVmbC0+R2V0UmVwZWF0ZWRGaWVsZFJlZjxUZXN0QWxsVHlwZXM6Ok5lc3RlZEVudW0+KAorICAgICAgICAgIG0xLCBmZF9yZXBlYXRlZF9uZXN0ZWRfZW51bSkpOworICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyArK2kpIHsKKyAgICBFWFBFQ1RfRVEoRnVuYyhpLCAxMSksIG0wLnJlcGVhdGVkX2ludDMyKGkpKTsKKyAgICBFWFBFQ1RfRVEoRnVuYyhpLCAxMiksIG0wLnJlcGVhdGVkX2RvdWJsZShpKSk7CisgICAgRVhQRUNUX0VRKFN0ckZ1bmMoaSwgMTUpLCBtMC5yZXBlYXRlZF9zdHJpbmcoaSkpOworICAgIEVYUEVDVF9FUShGdW5jKGksIDE2KSwgbTAucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKGkpLmMoKSk7CisgICAgRVhQRUNUX0VRKFRlc3RBbGxUeXBlczo6QkFSLCBtMC5yZXBlYXRlZF9uZXN0ZWRfZW51bShpKSk7CisgIH0KKworICAvLyBUZXN0IE11dGFibGVSZXBlYXRlZFJlZjo6TWVyZ2VGcm9tCisgIG1yZl9pbnQzMi5NZXJnZUZyb20oCisgICAgICByZWZsLT5HZXRSZXBlYXRlZEZpZWxkUmVmPGludDMyPihtMiwgZmRfcmVwZWF0ZWRfaW50MzIpKTsKKyAgbXJmX2RvdWJsZS5NZXJnZUZyb20oCisgICAgICByZWZsLT5HZXRSZXBlYXRlZEZpZWxkUmVmPGRvdWJsZT4obTIsIGZkX3JlcGVhdGVkX2RvdWJsZSkpOworICBtcmZfc3RyaW5nLk1lcmdlRnJvbSgKKyAgICAgIHJlZmwtPkdldFJlcGVhdGVkRmllbGRSZWY8c3RyaW5nPihtMiwgZmRfcmVwZWF0ZWRfc3RyaW5nKSk7CisgIG1yZl9mb3JlaWduX21lc3NhZ2UuTWVyZ2VGcm9tKAorICAgICAgcmVmbC0+R2V0UmVwZWF0ZWRGaWVsZFJlZjxGb3JlaWduTWVzc2FnZT4oCisgICAgICAgICAgbTIsIGZkX3JlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSkpOworICBtcmZfbmVzdGVkX2VudW0uTWVyZ2VGcm9tKAorICAgICAgcmVmbC0+R2V0UmVwZWF0ZWRGaWVsZFJlZjxUZXN0QWxsVHlwZXM6Ok5lc3RlZEVudW0+KAorICAgICAgICAgIG0yLCBmZF9yZXBlYXRlZF9uZXN0ZWRfZW51bSkpOworICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyArK2kpIHsKKyAgICBFWFBFQ1RfRVEoRnVuYyhpLCAyMSksIG0wLnJlcGVhdGVkX2ludDMyKGkgKyAxMCkpOworICAgIEVYUEVDVF9FUShGdW5jKGksIDIyKSwgbTAucmVwZWF0ZWRfZG91YmxlKGkgKyAxMCkpOworICAgIEVYUEVDVF9FUShTdHJGdW5jKGksIDI1KSwgbTAucmVwZWF0ZWRfc3RyaW5nKGkgKyAxMCkpOworICAgIEVYUEVDVF9FUShGdW5jKGksIDI2KSwgbTAucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKGkgKyAxMCkuYygpKTsKKyAgICBFWFBFQ1RfRVEoVGVzdEFsbFR5cGVzOjpCQVosIG0wLnJlcGVhdGVkX25lc3RlZF9lbnVtKGkgKyAxMCkpOworICB9CisKKyAgLy8gVGVzdCBNdXRhYmxlUmVwZWF0ZWRSZWY6OlN3YXAKKyAgLy8gU3dhcCBiZXR3ZWVuIG0wIGFuZCBtMi4KKyAgbXJmX2ludDMyLlN3YXAoCisgICAgICByZWZsLT5HZXRNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxpbnQzMj4oJm0yLCBmZF9yZXBlYXRlZF9pbnQzMikpOworICBtcmZfZG91YmxlLlN3YXAoCisgICAgICByZWZsLT5HZXRNdXRhYmxlUmVwZWF0ZWRGaWVsZFJlZjxkb3VibGU+KCZtMiwgZmRfcmVwZWF0ZWRfZG91YmxlKSk7CisgIG1yZl9zdHJpbmcuU3dhcCgKKyAgICAgIHJlZmwtPkdldE11dGFibGVSZXBlYXRlZEZpZWxkUmVmPHN0cmluZz4oJm0yLCBmZF9yZXBlYXRlZF9zdHJpbmcpKTsKKyAgbXJmX2ZvcmVpZ25fbWVzc2FnZS5Td2FwKAorICAgICAgcmVmbC0+R2V0TXV0YWJsZVJlcGVhdGVkRmllbGRSZWY8Rm9yZWlnbk1lc3NhZ2U+KAorICAgICAgICAgICZtMiwgZmRfcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKSk7CisgIG1yZl9uZXN0ZWRfZW51bS5Td2FwKAorICAgICAgcmVmbC0+R2V0TXV0YWJsZVJlcGVhdGVkRmllbGRSZWY8VGVzdEFsbFR5cGVzOjpOZXN0ZWRFbnVtPigKKyAgICAgICAgICAmbTIsIGZkX3JlcGVhdGVkX25lc3RlZF9lbnVtKSk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7ICsraSkgeworICAgIC8vIENoZWNrIHRoZSBjb250ZW50IG9mIG0wLgorICAgIEVYUEVDVF9FUShGdW5jKGksIDIxKSwgbTAucmVwZWF0ZWRfaW50MzIoaSkpOworICAgIEVYUEVDVF9FUShGdW5jKGksIDIyKSwgbTAucmVwZWF0ZWRfZG91YmxlKGkpKTsKKyAgICBFWFBFQ1RfRVEoU3RyRnVuYyhpLCAyNSksIG0wLnJlcGVhdGVkX3N0cmluZyhpKSk7CisgICAgRVhQRUNUX0VRKEZ1bmMoaSwgMjYpLCBtMC5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UoaSkuYygpKTsKKyAgICBFWFBFQ1RfRVEoVGVzdEFsbFR5cGVzOjpCQVosIG0wLnJlcGVhdGVkX25lc3RlZF9lbnVtKGkpKTsKKworICAgIC8vIENoZWNrIHRoZSBjb250ZW50IG9mIG0yLgorICAgIEVYUEVDVF9FUShGdW5jKGksIDExKSwgbTIucmVwZWF0ZWRfaW50MzIoaSkpOworICAgIEVYUEVDVF9FUShGdW5jKGksIDEyKSwgbTIucmVwZWF0ZWRfZG91YmxlKGkpKTsKKyAgICBFWFBFQ1RfRVEoU3RyRnVuYyhpLCAxNSksIG0yLnJlcGVhdGVkX3N0cmluZyhpKSk7CisgICAgRVhQRUNUX0VRKEZ1bmMoaSwgMTYpLCBtMi5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UoaSkuYygpKTsKKyAgICBFWFBFQ1RfRVEoVGVzdEFsbFR5cGVzOjpCQVIsIG0yLnJlcGVhdGVkX25lc3RlZF9lbnVtKGkpKTsKKyAgICBFWFBFQ1RfRVEoRnVuYyhpLCAyMSksIG0yLnJlcGVhdGVkX2ludDMyKGkgKyAxMCkpOworICAgIEVYUEVDVF9FUShGdW5jKGksIDIyKSwgbTIucmVwZWF0ZWRfZG91YmxlKGkgKyAxMCkpOworICAgIEVYUEVDVF9FUShTdHJGdW5jKGksIDI1KSwgbTIucmVwZWF0ZWRfc3RyaW5nKGkgKyAxMCkpOworICAgIEVYUEVDVF9FUShGdW5jKGksIDI2KSwgbTIucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKGkgKyAxMCkuYygpKTsKKyAgICBFWFBFQ1RfRVEoVGVzdEFsbFR5cGVzOjpCQVosIG0yLnJlcGVhdGVkX25lc3RlZF9lbnVtKGkgKyAxMCkpOworICB9Cit9CisKKy8vIFRlc3QgdGhhdCBHZXRSZXBlYXRlZEZpZWxkUmVmL011dGFibGVSZXBlYXRlZEZpZWxkUmVmIHdvcmtzIHdpdGgKKy8vIER5bmFtaWNNZXNzYWdlLgorVEVTVChSZXBlYXRlZEZpZWxkUmVmbGVjdGlvblRlc3QsIFJlcGVhdGVkRmllbGRSZWZEeW5hbWljTWVzc2FnZSkgeworICAvLyBEeW5hbWljTWVzc2FnZSBzaGFyZXMgdGhlIHNhbWUgbWVtb3J5IGxheW91dCBhcyBnZW5lcmF0ZWQgbWVzc2FnZQorICAvLyBhbmQgdXNlIHRoZSBzYW1lIEdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uIGNvZGUgZm9yIHJlZmxlY3Rpb24uCisgIC8vIEFsbCBjb2RlIHBhdGhzIHNob3VsZCBhbHJlYWR5IGJlIGNvdmVyZWQgYnkgdGhlIG90aGVyIHRlc3RzIGZvcgorICAvLyBnZW5lcmF0ZWQgbWVzc2FnZXMuIEhlcmUgd2UganVzdCB0ZXN0IG9uZSBmaWVsZC4KKworICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjID0gVGVzdEFsbFR5cGVzOjpkZXNjcmlwdG9yKCk7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmRfcmVwZWF0ZWRfaW50MzIgPQorICAgICAgZGVzYy0+RmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF9pbnQzMiIpOworCisgIER5bmFtaWNNZXNzYWdlRmFjdG9yeSBmYWN0b3J5OworICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPE1lc3NhZ2U+IGR5bmFtaWNfbWVzc2FnZShmYWN0b3J5LkdldFByb3RvdHlwZShkZXNjKS0+TmV3KCkpOworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsID0gZHluYW1pY19tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCk7CisKKyAgTXV0YWJsZVJlcGVhdGVkRmllbGRSZWY8aW50MzI+IHJmX2ludDMyID0KKyAgICAgIHJlZmwtPkdldE11dGFibGVSZXBlYXRlZEZpZWxkUmVmPGludDMyPigKKyAgICAgICAgICBkeW5hbWljX21lc3NhZ2UuZ2V0KCksIGZkX3JlcGVhdGVkX2ludDMyKTsKKyAgcmZfaW50MzIuQWRkKDEyMzQpOworICBFWFBFQ1RfRVEoMSwgcmVmbC0+RmllbGRTaXplKCpkeW5hbWljX21lc3NhZ2UsIGZkX3JlcGVhdGVkX2ludDMyKSk7CisgIEVYUEVDVF9FUSgxMjM0LCByZWZsLT5HZXRSZXBlYXRlZEludDMyKCpkeW5hbWljX21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZkX3JlcGVhdGVkX2ludDMyLCAwKSk7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3JlcGVhdGVkX2ZpZWxkX3VuaXR0ZXN0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9yZXBlYXRlZF9maWVsZF91bml0dGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNDU2NjRiCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9yZXBlYXRlZF9maWVsZF91bml0dGVzdC5jYwpAQCAtMCwwICsxLDE1MjggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBUT0RPKGtlbnRvbik6ICBJbXByb3ZlIHRoaXMgdW5pdHRlc3QgdG8gYnJpbmcgaXQgdXAgdG8gdGhlIHN0YW5kYXJkcyBvZgorLy8gICBvdGhlciBwcm90bzIgdW5pdHRlc3RzLgorCisjaW5jbHVkZSA8YWxnb3JpdGhtPgorI2luY2x1ZGUgPGxpbWl0cz4KKyNpbmNsdWRlIDxsaXN0PgorI2luY2x1ZGUgPHZlY3Rvcj4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9yZXBlYXRlZF9maWVsZC5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2xvZ2dpbmcuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0Lmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RsX3V0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7Cit1c2luZyBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEFsbFR5cGVzOworCituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIHsKKworLy8gVGVzdCBvcGVyYXRpb25zIG9uIGEgc21hbGwgUmVwZWF0ZWRGaWVsZC4KK1RFU1QoUmVwZWF0ZWRGaWVsZCwgU21hbGwpIHsKKyAgUmVwZWF0ZWRGaWVsZDxpbnQ+IGZpZWxkOworCisgIEVYUEVDVF9UUlVFKGZpZWxkLmVtcHR5KCkpOworICBFWFBFQ1RfRVEoZmllbGQuc2l6ZSgpLCAwKTsKKworICBmaWVsZC5BZGQoNSk7CisKKyAgRVhQRUNUX0ZBTFNFKGZpZWxkLmVtcHR5KCkpOworICBFWFBFQ1RfRVEoZmllbGQuc2l6ZSgpLCAxKTsKKyAgRVhQRUNUX0VRKGZpZWxkLkdldCgwKSwgNSk7CisKKyAgZmllbGQuQWRkKDQyKTsKKworICBFWFBFQ1RfRkFMU0UoZmllbGQuZW1wdHkoKSk7CisgIEVYUEVDVF9FUShmaWVsZC5zaXplKCksIDIpOworICBFWFBFQ1RfRVEoZmllbGQuR2V0KDApLCA1KTsKKyAgRVhQRUNUX0VRKGZpZWxkLkdldCgxKSwgNDIpOworCisgIGZpZWxkLlNldCgxLCAyMyk7CisKKyAgRVhQRUNUX0ZBTFNFKGZpZWxkLmVtcHR5KCkpOworICBFWFBFQ1RfRVEoZmllbGQuc2l6ZSgpLCAyKTsKKyAgRVhQRUNUX0VRKGZpZWxkLkdldCgwKSwgNSk7CisgIEVYUEVDVF9FUShmaWVsZC5HZXQoMSksIDIzKTsKKworICBmaWVsZC5SZW1vdmVMYXN0KCk7CisKKyAgRVhQRUNUX0ZBTFNFKGZpZWxkLmVtcHR5KCkpOworICBFWFBFQ1RfRVEoZmllbGQuc2l6ZSgpLCAxKTsKKyAgRVhQRUNUX0VRKGZpZWxkLkdldCgwKSwgNSk7CisKKyAgZmllbGQuQ2xlYXIoKTsKKworICBFWFBFQ1RfVFJVRShmaWVsZC5lbXB0eSgpKTsKKyAgRVhQRUNUX0VRKGZpZWxkLnNpemUoKSwgMCk7CisgIC8vIEFkZGl0aW9uYWwgYnl0ZXMgYXJlIGZvciAnc3RydWN0IFJlcCcgaGVhZGVyLgorICBpbnQgZXhwZWN0ZWRfdXNhZ2UgPSA0ICogc2l6ZW9mKGludCkgKyBzaXplb2YoQXJlbmEqKTsKKyAgRVhQRUNUX0VRKGZpZWxkLlNwYWNlVXNlZEV4Y2x1ZGluZ1NlbGYoKSwgZXhwZWN0ZWRfdXNhZ2UpOworfQorCisKKy8vIFRlc3Qgb3BlcmF0aW9ucyBvbiBhIFJlcGVhdGVkRmllbGQgd2hpY2ggaXMgbGFyZ2UgZW5vdWdoIHRvIGFsbG9jYXRlIGEKKy8vIHNlcGFyYXRlIGFycmF5LgorVEVTVChSZXBlYXRlZEZpZWxkLCBMYXJnZSkgeworICBSZXBlYXRlZEZpZWxkPGludD4gZmllbGQ7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxNjsgaSsrKSB7CisgICAgZmllbGQuQWRkKGkgKiBpKTsKKyAgfQorCisgIEVYUEVDVF9GQUxTRShmaWVsZC5lbXB0eSgpKTsKKyAgRVhQRUNUX0VRKGZpZWxkLnNpemUoKSwgMTYpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTY7IGkrKykgeworICAgIEVYUEVDVF9FUShmaWVsZC5HZXQoaSksIGkgKiBpKTsKKyAgfQorCisgIGludCBleHBlY3RlZF91c2FnZSA9IDE2ICogc2l6ZW9mKGludCk7CisgIEVYUEVDVF9HRShmaWVsZC5TcGFjZVVzZWRFeGNsdWRpbmdTZWxmKCksIGV4cGVjdGVkX3VzYWdlKTsKK30KKworLy8gVGVzdCBzd2FwcGluZyBiZXR3ZWVuIHZhcmlvdXMgdHlwZXMgb2YgUmVwZWF0ZWRGaWVsZHMuCitURVNUKFJlcGVhdGVkRmllbGQsIFN3YXBTbWFsbFNtYWxsKSB7CisgIFJlcGVhdGVkRmllbGQ8aW50PiBmaWVsZDE7CisgIFJlcGVhdGVkRmllbGQ8aW50PiBmaWVsZDI7CisKKyAgZmllbGQxLkFkZCg1KTsKKyAgZmllbGQxLkFkZCg0Mik7CisKKyAgRVhQRUNUX0ZBTFNFKGZpZWxkMS5lbXB0eSgpKTsKKyAgRVhQRUNUX0VRKGZpZWxkMS5zaXplKCksIDIpOworICBFWFBFQ1RfRVEoZmllbGQxLkdldCgwKSwgNSk7CisgIEVYUEVDVF9FUShmaWVsZDEuR2V0KDEpLCA0Mik7CisKKyAgRVhQRUNUX1RSVUUoZmllbGQyLmVtcHR5KCkpOworICBFWFBFQ1RfRVEoZmllbGQyLnNpemUoKSwgMCk7CisKKyAgZmllbGQxLlN3YXAoJmZpZWxkMik7CisKKyAgRVhQRUNUX1RSVUUoZmllbGQxLmVtcHR5KCkpOworICBFWFBFQ1RfRVEoZmllbGQxLnNpemUoKSwgMCk7CisKKyAgRVhQRUNUX0ZBTFNFKGZpZWxkMi5lbXB0eSgpKTsKKyAgRVhQRUNUX0VRKGZpZWxkMi5zaXplKCksIDIpOworICBFWFBFQ1RfRVEoZmllbGQyLkdldCgwKSwgNSk7CisgIEVYUEVDVF9FUShmaWVsZDIuR2V0KDEpLCA0Mik7Cit9CisKK1RFU1QoUmVwZWF0ZWRGaWVsZCwgU3dhcExhcmdlU21hbGwpIHsKKyAgUmVwZWF0ZWRGaWVsZDxpbnQ+IGZpZWxkMTsKKyAgUmVwZWF0ZWRGaWVsZDxpbnQ+IGZpZWxkMjsKKworICBmb3IgKGludCBpID0gMDsgaSA8IDE2OyBpKyspIHsKKyAgICBmaWVsZDEuQWRkKGkgKiBpKTsKKyAgfQorICBmaWVsZDIuQWRkKDUpOworICBmaWVsZDIuQWRkKDQyKTsKKyAgZmllbGQxLlN3YXAoJmZpZWxkMik7CisKKyAgRVhQRUNUX0VRKGZpZWxkMS5zaXplKCksIDIpOworICBFWFBFQ1RfRVEoZmllbGQxLkdldCgwKSwgNSk7CisgIEVYUEVDVF9FUShmaWVsZDEuR2V0KDEpLCA0Mik7CisgIEVYUEVDVF9FUShmaWVsZDIuc2l6ZSgpLCAxNik7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTY7IGkrKykgeworICAgIEVYUEVDVF9FUShmaWVsZDIuR2V0KGkpLCBpICogaSk7CisgIH0KK30KKworVEVTVChSZXBlYXRlZEZpZWxkLCBTd2FwTGFyZ2VMYXJnZSkgeworICBSZXBlYXRlZEZpZWxkPGludD4gZmllbGQxOworICBSZXBlYXRlZEZpZWxkPGludD4gZmllbGQyOworCisgIGZpZWxkMS5BZGQoNSk7CisgIGZpZWxkMS5BZGQoNDIpOworICBmb3IgKGludCBpID0gMDsgaSA8IDE2OyBpKyspIHsKKyAgICBmaWVsZDEuQWRkKGkpOworICAgIGZpZWxkMi5BZGQoaSAqIGkpOworICB9CisgIGZpZWxkMi5Td2FwKCZmaWVsZDEpOworCisgIEVYUEVDVF9FUShmaWVsZDEuc2l6ZSgpLCAxNik7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTY7IGkrKykgeworICAgIEVYUEVDVF9FUShmaWVsZDEuR2V0KGkpLCBpICogaSk7CisgIH0KKyAgRVhQRUNUX0VRKGZpZWxkMi5zaXplKCksIDE4KTsKKyAgRVhQRUNUX0VRKGZpZWxkMi5HZXQoMCksIDUpOworICBFWFBFQ1RfRVEoZmllbGQyLkdldCgxKSwgNDIpOworICBmb3IgKGludCBpID0gMjsgaSA8IDE4OyBpKyspIHsKKyAgICBFWFBFQ1RfRVEoZmllbGQyLkdldChpKSwgaSAtIDIpOworICB9Cit9CisKKy8vIERldGVybWluZXMgaG93IG11Y2ggc3BhY2Ugd2FzIHJlc2VydmVkIGJ5IHRoZSBnaXZlbiBmaWVsZCBieSBhZGRpbmcgZWxlbWVudHMKKy8vIHRvIGl0IHVudGlsIGl0IHJlLWFsbG9jYXRlcyBpdHMgc3BhY2UuCitzdGF0aWMgaW50IFJlc2VydmVkU3BhY2UoUmVwZWF0ZWRGaWVsZDxpbnQ+KiBmaWVsZCkgeworICBjb25zdCBpbnQqIHB0ciA9IGZpZWxkLT5kYXRhKCk7CisgIGRvIHsKKyAgICBmaWVsZC0+QWRkKDApOworICB9IHdoaWxlIChmaWVsZC0+ZGF0YSgpID09IHB0cik7CisKKyAgcmV0dXJuIGZpZWxkLT5zaXplKCkgLSAxOworfQorCitURVNUKFJlcGVhdGVkRmllbGQsIFJlc2VydmVNb3JlVGhhbkRvdWJsZSkgeworICAvLyBSZXNlcnZlIG1vcmUgdGhhbiBkb3VibGUgdGhlIHByZXZpb3VzIHNwYWNlIGluIHRoZSBmaWVsZCBhbmQgZXhwZWN0IHRoZQorICAvLyBmaWVsZCB0byByZXNlcnZlIGV4YWN0bHkgdGhlIGFtb3VudCBzcGVjaWZpZWQuCisgIFJlcGVhdGVkRmllbGQ8aW50PiBmaWVsZDsKKyAgZmllbGQuUmVzZXJ2ZSgyMCk7CisKKyAgRVhQRUNUX0VRKDIwLCBSZXNlcnZlZFNwYWNlKCZmaWVsZCkpOworfQorCitURVNUKFJlcGVhdGVkRmllbGQsIFJlc2VydmVMZXNzVGhhbkRvdWJsZSkgeworICAvLyBSZXNlcnZlIGxlc3MgdGhhbiBkb3VibGUgdGhlIHByZXZpb3VzIHNwYWNlIGluIHRoZSBmaWVsZCBhbmQgZXhwZWN0IHRoZQorICAvLyBmaWVsZCB0byBncm93IGJ5IGRvdWJsZSBpbnN0ZWFkLgorICBSZXBlYXRlZEZpZWxkPGludD4gZmllbGQ7CisgIGZpZWxkLlJlc2VydmUoMjApOworICBmaWVsZC5SZXNlcnZlKDMwKTsKKworICBFWFBFQ1RfRVEoNDAsIFJlc2VydmVkU3BhY2UoJmZpZWxkKSk7Cit9CisKK1RFU1QoUmVwZWF0ZWRGaWVsZCwgUmVzZXJ2ZUxlc3NUaGFuRXhpc3RpbmcpIHsKKyAgLy8gUmVzZXJ2ZSBsZXNzIHRoYW4gdGhlIHByZXZpb3VzIHNwYWNlIGluIHRoZSBmaWVsZCBhbmQgZXhwZWN0IHRoZQorICAvLyBmaWVsZCB0byBub3QgcmUtYWxsb2NhdGUgYXQgYWxsLgorICBSZXBlYXRlZEZpZWxkPGludD4gZmllbGQ7CisgIGZpZWxkLlJlc2VydmUoMjApOworICBjb25zdCBpbnQqIHByZXZpb3VzX3B0ciA9IGZpZWxkLmRhdGEoKTsKKyAgZmllbGQuUmVzZXJ2ZSgxMCk7CisKKyAgRVhQRUNUX0VRKHByZXZpb3VzX3B0ciwgZmllbGQuZGF0YSgpKTsKKyAgRVhQRUNUX0VRKDIwLCBSZXNlcnZlZFNwYWNlKCZmaWVsZCkpOworfQorCitURVNUKFJlcGVhdGVkRmllbGQsIFJlc2l6ZSkgeworICBSZXBlYXRlZEZpZWxkPGludD4gZmllbGQ7CisgIGZpZWxkLlJlc2l6ZSgyLCAxKTsKKyAgRVhQRUNUX0VRKDIsIGZpZWxkLnNpemUoKSk7CisgIGZpZWxkLlJlc2l6ZSg1LCAyKTsKKyAgRVhQRUNUX0VRKDUsIGZpZWxkLnNpemUoKSk7CisgIGZpZWxkLlJlc2l6ZSg0LCAzKTsKKyAgQVNTRVJUX0VRKDQsIGZpZWxkLnNpemUoKSk7CisgIEVYUEVDVF9FUSgxLCBmaWVsZC5HZXQoMCkpOworICBFWFBFQ1RfRVEoMSwgZmllbGQuR2V0KDEpKTsKKyAgRVhQRUNUX0VRKDIsIGZpZWxkLkdldCgyKSk7CisgIEVYUEVDVF9FUSgyLCBmaWVsZC5HZXQoMykpOworICBmaWVsZC5SZXNpemUoMCwgNCk7CisgIEVYUEVDVF9UUlVFKGZpZWxkLmVtcHR5KCkpOworfQorCitURVNUKFJlcGVhdGVkRmllbGQsIE1lcmdlRnJvbSkgeworICBSZXBlYXRlZEZpZWxkPGludD4gc291cmNlLCBkZXN0aW5hdGlvbjsKKyAgc291cmNlLkFkZCg0KTsKKyAgc291cmNlLkFkZCg1KTsKKyAgZGVzdGluYXRpb24uQWRkKDEpOworICBkZXN0aW5hdGlvbi5BZGQoMik7CisgIGRlc3RpbmF0aW9uLkFkZCgzKTsKKworICBkZXN0aW5hdGlvbi5NZXJnZUZyb20oc291cmNlKTsKKworICBBU1NFUlRfRVEoNSwgZGVzdGluYXRpb24uc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEsIGRlc3RpbmF0aW9uLkdldCgwKSk7CisgIEVYUEVDVF9FUSgyLCBkZXN0aW5hdGlvbi5HZXQoMSkpOworICBFWFBFQ1RfRVEoMywgZGVzdGluYXRpb24uR2V0KDIpKTsKKyAgRVhQRUNUX0VRKDQsIGRlc3RpbmF0aW9uLkdldCgzKSk7CisgIEVYUEVDVF9FUSg1LCBkZXN0aW5hdGlvbi5HZXQoNCkpOworfQorCisjaWZkZWYgUFJPVE9CVUZfSEFTX0RFQVRIX1RFU1QKK1RFU1QoUmVwZWF0ZWRGaWVsZCwgTWVyZ2VGcm9tU2VsZikgeworICBSZXBlYXRlZEZpZWxkPGludD4gbWU7CisgIG1lLkFkZCgzKTsKKyAgRVhQRUNUX0RFQVRIKG1lLk1lcmdlRnJvbShtZSksICIiKTsKK30KKyNlbmRpZiAgLy8gUFJPVE9CVUZfSEFTX0RFQVRIX1RFU1QKKworVEVTVChSZXBlYXRlZEZpZWxkLCBDb3B5RnJvbSkgeworICBSZXBlYXRlZEZpZWxkPGludD4gc291cmNlLCBkZXN0aW5hdGlvbjsKKyAgc291cmNlLkFkZCg0KTsKKyAgc291cmNlLkFkZCg1KTsKKyAgZGVzdGluYXRpb24uQWRkKDEpOworICBkZXN0aW5hdGlvbi5BZGQoMik7CisgIGRlc3RpbmF0aW9uLkFkZCgzKTsKKworICBkZXN0aW5hdGlvbi5Db3B5RnJvbShzb3VyY2UpOworCisgIEFTU0VSVF9FUSgyLCBkZXN0aW5hdGlvbi5zaXplKCkpOworICBFWFBFQ1RfRVEoNCwgZGVzdGluYXRpb24uR2V0KDApKTsKKyAgRVhQRUNUX0VRKDUsIGRlc3RpbmF0aW9uLkdldCgxKSk7Cit9CisKK1RFU1QoUmVwZWF0ZWRGaWVsZCwgQ29weUZyb21TZWxmKSB7CisgIFJlcGVhdGVkRmllbGQ8aW50PiBtZTsKKyAgbWUuQWRkKDMpOworICBtZS5Db3B5RnJvbShtZSk7CisgIEFTU0VSVF9FUSgxLCBtZS5zaXplKCkpOworICBFWFBFQ1RfRVEoMywgbWUuR2V0KDApKTsKK30KKworVEVTVChSZXBlYXRlZEZpZWxkLCBFcmFzZSkgeworICBSZXBlYXRlZEZpZWxkPGludD4gbWU7CisgIFJlcGVhdGVkRmllbGQ8aW50Pjo6aXRlcmF0b3IgaXQgPSBtZS5lcmFzZShtZS5iZWdpbigpLCBtZS5lbmQoKSk7CisgIEVYUEVDVF9UUlVFKG1lLmJlZ2luKCkgPT0gaXQpOworICBFWFBFQ1RfRVEoMCwgbWUuc2l6ZSgpKTsKKworICBtZS5BZGQoMSk7CisgIG1lLkFkZCgyKTsKKyAgbWUuQWRkKDMpOworICBpdCA9IG1lLmVyYXNlKG1lLmJlZ2luKCksIG1lLmVuZCgpKTsKKyAgRVhQRUNUX1RSVUUobWUuYmVnaW4oKSA9PSBpdCk7CisgIEVYUEVDVF9FUSgwLCBtZS5zaXplKCkpOworCisgIG1lLkFkZCg0KTsKKyAgbWUuQWRkKDUpOworICBtZS5BZGQoNik7CisgIGl0ID0gbWUuZXJhc2UobWUuYmVnaW4oKSArIDIsIG1lLmVuZCgpKTsKKyAgRVhQRUNUX1RSVUUobWUuYmVnaW4oKSArIDIgPT0gaXQpOworICBFWFBFQ1RfRVEoMiwgbWUuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDQsIG1lLkdldCgwKSk7CisgIEVYUEVDVF9FUSg1LCBtZS5HZXQoMSkpOworCisgIG1lLkFkZCg2KTsKKyAgbWUuQWRkKDcpOworICBtZS5BZGQoOCk7CisgIGl0ID0gbWUuZXJhc2UobWUuYmVnaW4oKSArIDEsIG1lLmJlZ2luKCkgKyAzKTsKKyAgRVhQRUNUX1RSVUUobWUuYmVnaW4oKSArIDEgPT0gaXQpOworICBFWFBFQ1RfRVEoMywgbWUuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDQsIG1lLkdldCgwKSk7CisgIEVYUEVDVF9FUSg3LCBtZS5HZXQoMSkpOworICBFWFBFQ1RfRVEoOCwgbWUuR2V0KDIpKTsKK30KKworVEVTVChSZXBlYXRlZEZpZWxkLCBDb3B5Q29uc3RydWN0KSB7CisgIFJlcGVhdGVkRmllbGQ8aW50PiBzb3VyY2U7CisgIHNvdXJjZS5BZGQoMSk7CisgIHNvdXJjZS5BZGQoMik7CisKKyAgUmVwZWF0ZWRGaWVsZDxpbnQ+IGRlc3RpbmF0aW9uKHNvdXJjZSk7CisKKyAgQVNTRVJUX0VRKDIsIGRlc3RpbmF0aW9uLnNpemUoKSk7CisgIEVYUEVDVF9FUSgxLCBkZXN0aW5hdGlvbi5HZXQoMCkpOworICBFWFBFQ1RfRVEoMiwgZGVzdGluYXRpb24uR2V0KDEpKTsKK30KKworVEVTVChSZXBlYXRlZEZpZWxkLCBJdGVyYXRvckNvbnN0cnVjdCkgeworICB2ZWN0b3I8aW50PiB2YWx1ZXM7CisgIHZhbHVlcy5wdXNoX2JhY2soMSk7CisgIHZhbHVlcy5wdXNoX2JhY2soMik7CisKKyAgUmVwZWF0ZWRGaWVsZDxpbnQ+IGZpZWxkKHZhbHVlcy5iZWdpbigpLCB2YWx1ZXMuZW5kKCkpOworICBBU1NFUlRfRVEodmFsdWVzLnNpemUoKSwgZmllbGQuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKHZhbHVlc1swXSwgZmllbGQuR2V0KDApKTsKKyAgRVhQRUNUX0VRKHZhbHVlc1sxXSwgZmllbGQuR2V0KDEpKTsKKworICBSZXBlYXRlZEZpZWxkPGludD4gb3RoZXIoZmllbGQuYmVnaW4oKSwgZmllbGQuZW5kKCkpOworICBBU1NFUlRfRVEodmFsdWVzLnNpemUoKSwgb3RoZXIuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKHZhbHVlc1swXSwgb3RoZXIuR2V0KDApKTsKKyAgRVhQRUNUX0VRKHZhbHVlc1sxXSwgb3RoZXIuR2V0KDEpKTsKK30KKworVEVTVChSZXBlYXRlZEZpZWxkLCBDb3B5QXNzaWduKSB7CisgIFJlcGVhdGVkRmllbGQ8aW50PiBzb3VyY2UsIGRlc3RpbmF0aW9uOworICBzb3VyY2UuQWRkKDQpOworICBzb3VyY2UuQWRkKDUpOworICBkZXN0aW5hdGlvbi5BZGQoMSk7CisgIGRlc3RpbmF0aW9uLkFkZCgyKTsKKyAgZGVzdGluYXRpb24uQWRkKDMpOworCisgIGRlc3RpbmF0aW9uID0gc291cmNlOworCisgIEFTU0VSVF9FUSgyLCBkZXN0aW5hdGlvbi5zaXplKCkpOworICBFWFBFQ1RfRVEoNCwgZGVzdGluYXRpb24uR2V0KDApKTsKKyAgRVhQRUNUX0VRKDUsIGRlc3RpbmF0aW9uLkdldCgxKSk7Cit9CisKK1RFU1QoUmVwZWF0ZWRGaWVsZCwgU2VsZkFzc2lnbikgeworICAvLyBWZXJpZnkgdGhhdCBhc3NpZ25tZW50IHRvIHNlbGYgZG9lcyBub3QgZGVzdHJveSBkYXRhLgorICBSZXBlYXRlZEZpZWxkPGludD4gc291cmNlLCAqcDsKKyAgcCA9ICZzb3VyY2U7CisgIHNvdXJjZS5BZGQoNyk7CisgIHNvdXJjZS5BZGQoOCk7CisKKyAgKnAgPSBzb3VyY2U7CisKKyAgQVNTRVJUX0VRKDIsIHNvdXJjZS5zaXplKCkpOworICBFWFBFQ1RfRVEoNywgc291cmNlLkdldCgwKSk7CisgIEVYUEVDVF9FUSg4LCBzb3VyY2UuR2V0KDEpKTsKK30KKworVEVTVChSZXBlYXRlZEZpZWxkLCBNdXRhYmxlRGF0YUlzTXV0YWJsZSkgeworICBSZXBlYXRlZEZpZWxkPGludD4gZmllbGQ7CisgIGZpZWxkLkFkZCgxKTsKKyAgRVhQRUNUX0VRKDEsIGZpZWxkLkdldCgwKSk7CisgIC8vIFRoZSBmYWN0IHRoYXQgdGhpcyBsaW5lIGNvbXBpbGVzIHdvdWxkIGJlIGVub3VnaCwgYnV0IHdlJ2xsIGNoZWNrIHRoZQorICAvLyB2YWx1ZSBhbnl3YXkuCisgICpmaWVsZC5tdXRhYmxlX2RhdGEoKSA9IDI7CisgIEVYUEVDVF9FUSgyLCBmaWVsZC5HZXQoMCkpOworfQorCitURVNUKFJlcGVhdGVkRmllbGQsIFRydW5jYXRlKSB7CisgIFJlcGVhdGVkRmllbGQ8aW50PiBmaWVsZDsKKworICBmaWVsZC5BZGQoMTIpOworICBmaWVsZC5BZGQoMzQpOworICBmaWVsZC5BZGQoNTYpOworICBmaWVsZC5BZGQoNzgpOworICBFWFBFQ1RfRVEoNCwgZmllbGQuc2l6ZSgpKTsKKworICBmaWVsZC5UcnVuY2F0ZSgzKTsKKyAgRVhQRUNUX0VRKDMsIGZpZWxkLnNpemUoKSk7CisKKyAgZmllbGQuQWRkKDkwKTsKKyAgRVhQRUNUX0VRKDQsIGZpZWxkLnNpemUoKSk7CisgIEVYUEVDVF9FUSg5MCwgZmllbGQuR2V0KDMpKTsKKworICAvLyBUcnVuY2F0aW9ucyB0aGF0IGRvbid0IGNoYW5nZSB0aGUgc2l6ZSBhcmUgYWxsb3dlZCwgYnV0IGdyb3dpbmcgaXMgbm90CisgIC8vIGFsbG93ZWQuCisgIGZpZWxkLlRydW5jYXRlKGZpZWxkLnNpemUoKSk7CisjaWZkZWYgUFJPVE9CVUZfSEFTX0RFQVRIX1RFU1QKKyAgRVhQRUNUX0RFQlVHX0RFQVRIKGZpZWxkLlRydW5jYXRlKGZpZWxkLnNpemUoKSArIDEpLCAibmV3X3NpemUiKTsKKyNlbmRpZgorfQorCisKK1RFU1QoUmVwZWF0ZWRGaWVsZCwgRXh0cmFjdFN1YnJhbmdlKSB7CisgIC8vIEV4aGF1c3RpdmVseSB0ZXN0IGV2ZXJ5IHN1YnJhbmdlIGluIGFycmF5cyBvZiBhbGwgc2l6ZXMgZnJvbSAwIHRocm91Z2ggOS4KKyAgZm9yIChpbnQgc3ogPSAwOyBzeiA8IDEwOyArK3N6KSB7CisgICAgZm9yIChpbnQgbnVtID0gMDsgbnVtIDw9IHN6OyArK251bSkgeworICAgICAgZm9yIChpbnQgc3RhcnQgPSAwOyBzdGFydCA8IHN6IC0gbnVtOyArK3N0YXJ0KSB7CisgICAgICAgIC8vIENyZWF0ZSBSZXBlYXRlZEZpZWxkIHdpdGggc3ogZWxlbWVudHMgaGF2aW5nIHZhbHVlcyAwIHRocm91Z2ggc3otMS4KKyAgICAgICAgUmVwZWF0ZWRGaWVsZDxpbnQzMj4gZmllbGQ7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc3o7ICsraSkKKyAgICAgICAgICBmaWVsZC5BZGQoaSk7CisgICAgICAgIEVYUEVDVF9FUShmaWVsZC5zaXplKCksIHN6KTsKKworICAgICAgICAvLyBDcmVhdGUgYSBjYXRjaGVyIGFycmF5IGFuZCBjYWxsIEV4dHJhY3RTdWJyYW5nZS4KKyAgICAgICAgaW50MzIgY2F0Y2hlclsxMF07CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7ICsraSkKKyAgICAgICAgICBjYXRjaGVyW2ldID0gLTE7CisgICAgICAgIGZpZWxkLkV4dHJhY3RTdWJyYW5nZShzdGFydCwgbnVtLCBjYXRjaGVyKTsKKworICAgICAgICAvLyBEb2VzIHRoZSByZXN1bHRpbmcgYXJyYXkgaGF2ZSB0aGUgcmlnaHQgc2l6ZT8KKyAgICAgICAgRVhQRUNUX0VRKGZpZWxkLnNpemUoKSwgc3ogLSBudW0pOworCisgICAgICAgIC8vIFdlcmUgdGhlIHJlbW92ZWQgZWxlbWVudHMgZXh0cmFjdGVkIGludG8gdGhlIGNhdGNoZXIgYXJyYXk/CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtOyArK2kpCisgICAgICAgICAgRVhQRUNUX0VRKGNhdGNoZXJbaV0sIHN0YXJ0ICsgaSk7CisgICAgICAgIEVYUEVDVF9FUShjYXRjaGVyW251bV0sIC0xKTsKKworICAgICAgICAvLyBEb2VzIHRoZSByZXN1bHRpbmcgYXJyYXkgY29udGFpbiB0aGUgcmlnaHQgdmFsdWVzPworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHN0YXJ0OyArK2kpCisgICAgICAgICAgRVhQRUNUX0VRKGZpZWxkLkdldChpKSwgaSk7CisgICAgICAgIGZvciAoaW50IGkgPSBzdGFydDsgaSA8IGZpZWxkLnNpemUoKTsgKytpKQorICAgICAgICAgIEVYUEVDVF9FUShmaWVsZC5HZXQoaSksIGkgKyBudW0pOworICAgICAgfQorICAgIH0KKyAgfQorfQorCitURVNUKFJlcGVhdGVkRmllbGQsIENsZWFyVGhlblJlc2VydmVNb3JlKSB7CisgIC8vIFRlc3QgdGhhdCBSZXNlcnZlIHByb3Blcmx5IGRlc3Ryb3lzIHRoZSBvbGQgaW50ZXJuYWwgYXJyYXkgd2hlbiBpdCdzIGZvcmNlZAorICAvLyB0byBhbGxvY2F0ZSBhIG5ldyBvbmUsIGV2ZW4gd2hlbiBjbGVhcmVkLWJ1dC1ub3QtZGVsZXRlZCBvYmplY3RzIGFyZQorICAvLyBwcmVzZW50LiBVc2UgYSAnc3RyaW5nJyBhbmQgPiAxNiBieXRlcyBsZW5ndGggc28gdGhhdCB0aGUgZWxlbWVudHMgYXJlCisgIC8vIG5vbi1QT0QgYW5kIGFsbG9jYXRlIC0tIHRoZSBsZWFrIGNoZWNrZXIgd2lsbCBjYXRjaCBhbnkgc2tpcHBlZCBkZXN0cnVjdG9yCisgIC8vIGNhbGxzIGhlcmUuCisgIFJlcGVhdGVkRmllbGQ8c3RyaW5nPiBmaWVsZDsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAzMjsgaSsrKSB7CisgICAgZmllbGQuQWRkKHN0cmluZygiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5IikpOworICB9CisgIEVYUEVDVF9FUSgzMiwgZmllbGQuc2l6ZSgpKTsKKyAgZmllbGQuQ2xlYXIoKTsKKyAgRVhQRUNUX0VRKDAsIGZpZWxkLnNpemUoKSk7CisgIEVYUEVDVF9FUSgzMiwgZmllbGQuQ2FwYWNpdHkoKSk7CisKKyAgZmllbGQuUmVzZXJ2ZSgxMDI0KTsKKyAgRVhQRUNUX0VRKDAsIGZpZWxkLnNpemUoKSk7CisgIEVYUEVDVF9FUSgxMDI0LCBmaWVsZC5DYXBhY2l0eSgpKTsKKyAgLy8gRmluaXNoIHRlc3QgLS0gfGZpZWxkfCBzaG91bGQgZGVzdHJveSB0aGUgY2xlYXJlZC1idXQtbm90LXlldC1kZXN0cm95ZWQKKyAgLy8gc3RyaW5ncy4KK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorLy8gUmVwZWF0ZWRQdHJGaWVsZCB0ZXN0cy4gIFRoZXNlIHByZXR0eSBtdWNoIGp1c3QgbWlycm9yIHRoZSBSZXBlYXRlZEZpZWxkCisvLyB0ZXN0cyBhYm92ZS4KKworVEVTVChSZXBlYXRlZFB0ckZpZWxkLCBTbWFsbCkgeworICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4gZmllbGQ7CisKKyAgRVhQRUNUX1RSVUUoZmllbGQuZW1wdHkoKSk7CisgIEVYUEVDVF9FUShmaWVsZC5zaXplKCksIDApOworCisgIGZpZWxkLkFkZCgpLT5hc3NpZ24oImZvbyIpOworCisgIEVYUEVDVF9GQUxTRShmaWVsZC5lbXB0eSgpKTsKKyAgRVhQRUNUX0VRKGZpZWxkLnNpemUoKSwgMSk7CisgIEVYUEVDVF9FUShmaWVsZC5HZXQoMCksICJmb28iKTsKKworICBmaWVsZC5BZGQoKS0+YXNzaWduKCJiYXIiKTsKKworICBFWFBFQ1RfRkFMU0UoZmllbGQuZW1wdHkoKSk7CisgIEVYUEVDVF9FUShmaWVsZC5zaXplKCksIDIpOworICBFWFBFQ1RfRVEoZmllbGQuR2V0KDApLCAiZm9vIik7CisgIEVYUEVDVF9FUShmaWVsZC5HZXQoMSksICJiYXIiKTsKKworICBmaWVsZC5NdXRhYmxlKDEpLT5hc3NpZ24oImJheiIpOworCisgIEVYUEVDVF9GQUxTRShmaWVsZC5lbXB0eSgpKTsKKyAgRVhQRUNUX0VRKGZpZWxkLnNpemUoKSwgMik7CisgIEVYUEVDVF9FUShmaWVsZC5HZXQoMCksICJmb28iKTsKKyAgRVhQRUNUX0VRKGZpZWxkLkdldCgxKSwgImJheiIpOworCisgIGZpZWxkLlJlbW92ZUxhc3QoKTsKKworICBFWFBFQ1RfRkFMU0UoZmllbGQuZW1wdHkoKSk7CisgIEVYUEVDVF9FUShmaWVsZC5zaXplKCksIDEpOworICBFWFBFQ1RfRVEoZmllbGQuR2V0KDApLCAiZm9vIik7CisKKyAgZmllbGQuQ2xlYXIoKTsKKworICBFWFBFQ1RfVFJVRShmaWVsZC5lbXB0eSgpKTsKKyAgRVhQRUNUX0VRKGZpZWxkLnNpemUoKSwgMCk7Cit9CisKK1RFU1QoUmVwZWF0ZWRQdHJGaWVsZCwgTGFyZ2UpIHsKKyAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+IGZpZWxkOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTY7IGkrKykgeworICAgICpmaWVsZC5BZGQoKSArPSAnYScgKyBpOworICB9CisKKyAgRVhQRUNUX0VRKGZpZWxkLnNpemUoKSwgMTYpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTY7IGkrKykgeworICAgIEVYUEVDVF9FUShmaWVsZC5HZXQoaSkuc2l6ZSgpLCAxKTsKKyAgICBFWFBFQ1RfRVEoZmllbGQuR2V0KGkpWzBdLCAnYScgKyBpKTsKKyAgfQorCisgIGludCBtaW5fZXhwZWN0ZWRfdXNhZ2UgPSAxNiAqIHNpemVvZihzdHJpbmcpOworICBFWFBFQ1RfR0UoZmllbGQuU3BhY2VVc2VkRXhjbHVkaW5nU2VsZigpLCBtaW5fZXhwZWN0ZWRfdXNhZ2UpOworfQorCitURVNUKFJlcGVhdGVkUHRyRmllbGQsIFN3YXBTbWFsbFNtYWxsKSB7CisgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPiBmaWVsZDE7CisgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPiBmaWVsZDI7CisKKyAgRVhQRUNUX1RSVUUoZmllbGQxLmVtcHR5KCkpOworICBFWFBFQ1RfRVEoZmllbGQxLnNpemUoKSwgMCk7CisgIEVYUEVDVF9UUlVFKGZpZWxkMi5lbXB0eSgpKTsKKyAgRVhQRUNUX0VRKGZpZWxkMi5zaXplKCksIDApOworCisgIGZpZWxkMS5BZGQoKS0+YXNzaWduKCJmb28iKTsKKyAgZmllbGQxLkFkZCgpLT5hc3NpZ24oImJhciIpOworCisgIEVYUEVDVF9GQUxTRShmaWVsZDEuZW1wdHkoKSk7CisgIEVYUEVDVF9FUShmaWVsZDEuc2l6ZSgpLCAyKTsKKyAgRVhQRUNUX0VRKGZpZWxkMS5HZXQoMCksICJmb28iKTsKKyAgRVhQRUNUX0VRKGZpZWxkMS5HZXQoMSksICJiYXIiKTsKKworICBFWFBFQ1RfVFJVRShmaWVsZDIuZW1wdHkoKSk7CisgIEVYUEVDVF9FUShmaWVsZDIuc2l6ZSgpLCAwKTsKKworICBmaWVsZDEuU3dhcCgmZmllbGQyKTsKKworICBFWFBFQ1RfVFJVRShmaWVsZDEuZW1wdHkoKSk7CisgIEVYUEVDVF9FUShmaWVsZDEuc2l6ZSgpLCAwKTsKKworICBFWFBFQ1RfRVEoZmllbGQyLnNpemUoKSwgMik7CisgIEVYUEVDVF9FUShmaWVsZDIuR2V0KDApLCAiZm9vIik7CisgIEVYUEVDVF9FUShmaWVsZDIuR2V0KDEpLCAiYmFyIik7Cit9CisKK1RFU1QoUmVwZWF0ZWRQdHJGaWVsZCwgU3dhcExhcmdlU21hbGwpIHsKKyAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+IGZpZWxkMTsKKyAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+IGZpZWxkMjsKKworICBmaWVsZDIuQWRkKCktPmFzc2lnbigiZm9vIik7CisgIGZpZWxkMi5BZGQoKS0+YXNzaWduKCJiYXIiKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxNjsgaSsrKSB7CisgICAgKmZpZWxkMS5BZGQoKSArPSAnYScgKyBpOworICB9CisgIGZpZWxkMS5Td2FwKCZmaWVsZDIpOworCisgIEVYUEVDVF9FUShmaWVsZDEuc2l6ZSgpLCAyKTsKKyAgRVhQRUNUX0VRKGZpZWxkMS5HZXQoMCksICJmb28iKTsKKyAgRVhQRUNUX0VRKGZpZWxkMS5HZXQoMSksICJiYXIiKTsKKyAgRVhQRUNUX0VRKGZpZWxkMi5zaXplKCksIDE2KTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxNjsgaSsrKSB7CisgICAgRVhQRUNUX0VRKGZpZWxkMi5HZXQoaSkuc2l6ZSgpLCAxKTsKKyAgICBFWFBFQ1RfRVEoZmllbGQyLkdldChpKVswXSwgJ2EnICsgaSk7CisgIH0KK30KKworVEVTVChSZXBlYXRlZFB0ckZpZWxkLCBTd2FwTGFyZ2VMYXJnZSkgeworICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4gZmllbGQxOworICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4gZmllbGQyOworCisgIGZpZWxkMS5BZGQoKS0+YXNzaWduKCJmb28iKTsKKyAgZmllbGQxLkFkZCgpLT5hc3NpZ24oImJhciIpOworICBmb3IgKGludCBpID0gMDsgaSA8IDE2OyBpKyspIHsKKyAgICAqZmllbGQxLkFkZCgpICs9ICdBJyArIGk7CisgICAgKmZpZWxkMi5BZGQoKSArPSAnYScgKyBpOworICB9CisgIGZpZWxkMi5Td2FwKCZmaWVsZDEpOworCisgIEVYUEVDVF9FUShmaWVsZDEuc2l6ZSgpLCAxNik7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTY7IGkrKykgeworICAgIEVYUEVDVF9FUShmaWVsZDEuR2V0KGkpLnNpemUoKSwgMSk7CisgICAgRVhQRUNUX0VRKGZpZWxkMS5HZXQoaSlbMF0sICdhJyArIGkpOworICB9CisgIEVYUEVDVF9FUShmaWVsZDIuc2l6ZSgpLCAxOCk7CisgIEVYUEVDVF9FUShmaWVsZDIuR2V0KDApLCAiZm9vIik7CisgIEVYUEVDVF9FUShmaWVsZDIuR2V0KDEpLCAiYmFyIik7CisgIGZvciAoaW50IGkgPSAyOyBpIDwgMTg7IGkrKykgeworICAgIEVYUEVDVF9FUShmaWVsZDIuR2V0KGkpLnNpemUoKSwgMSk7CisgICAgRVhQRUNUX0VRKGZpZWxkMi5HZXQoaSlbMF0sICdBJyArIGkgLSAyKTsKKyAgfQorfQorCitzdGF0aWMgaW50IFJlc2VydmVkU3BhY2UoUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+KiBmaWVsZCkgeworICBjb25zdCBzdHJpbmcqIGNvbnN0KiBwdHIgPSBmaWVsZC0+ZGF0YSgpOworICBkbyB7CisgICAgZmllbGQtPkFkZCgpOworICB9IHdoaWxlIChmaWVsZC0+ZGF0YSgpID09IHB0cik7CisKKyAgcmV0dXJuIGZpZWxkLT5zaXplKCkgLSAxOworfQorCitURVNUKFJlcGVhdGVkUHRyRmllbGQsIFJlc2VydmVNb3JlVGhhbkRvdWJsZSkgeworICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4gZmllbGQ7CisgIGZpZWxkLlJlc2VydmUoMjApOworCisgIEVYUEVDVF9FUSgyMCwgUmVzZXJ2ZWRTcGFjZSgmZmllbGQpKTsKK30KKworVEVTVChSZXBlYXRlZFB0ckZpZWxkLCBSZXNlcnZlTGVzc1RoYW5Eb3VibGUpIHsKKyAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+IGZpZWxkOworICBmaWVsZC5SZXNlcnZlKDIwKTsKKyAgZmllbGQuUmVzZXJ2ZSgzMCk7CisKKyAgRVhQRUNUX0VRKDQwLCBSZXNlcnZlZFNwYWNlKCZmaWVsZCkpOworfQorCitURVNUKFJlcGVhdGVkUHRyRmllbGQsIFJlc2VydmVMZXNzVGhhbkV4aXN0aW5nKSB7CisgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPiBmaWVsZDsKKyAgZmllbGQuUmVzZXJ2ZSgyMCk7CisgIGNvbnN0IHN0cmluZyogY29uc3QqIHByZXZpb3VzX3B0ciA9IGZpZWxkLmRhdGEoKTsKKyAgZmllbGQuUmVzZXJ2ZSgxMCk7CisKKyAgRVhQRUNUX0VRKHByZXZpb3VzX3B0ciwgZmllbGQuZGF0YSgpKTsKKyAgRVhQRUNUX0VRKDIwLCBSZXNlcnZlZFNwYWNlKCZmaWVsZCkpOworfQorCitURVNUKFJlcGVhdGVkUHRyRmllbGQsIFJlc2VydmVEb2VzbnRMb3NlQWxsb2NhdGVkKSB7CisgIC8vIENoZWNrIHRoYXQgYSBidWcgaXMgZml4ZWQ6ICBBbiBlYXJsaWVyIGltcGxlbWVudGF0aW9uIG9mIFJlc2VydmUoKQorICAvLyBmYWlsZWQgdG8gY29weSBwb2ludGVycyB0byBhbGxvY2F0ZWQtYnV0LWNsZWFyZWQgb2JqZWN0cywgcG9zc2libHkKKyAgLy8gbGVhZGluZyB0byBzZWdmYXVsdHMuCisgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPiBmaWVsZDsKKyAgc3RyaW5nKiBmaXJzdCA9IGZpZWxkLkFkZCgpOworICBmaWVsZC5SZW1vdmVMYXN0KCk7CisKKyAgZmllbGQuUmVzZXJ2ZSgyMCk7CisgIEVYUEVDVF9FUShmaXJzdCwgZmllbGQuQWRkKCkpOworfQorCisvLyBDbGVhcmluZyBlbGVtZW50cyBpcyB0cmlja3kgd2l0aCBSZXBlYXRlZFB0ckZpZWxkcyBzaW5jZSB0aGUgbWVtb3J5IGZvcgorLy8gdGhlIGVsZW1lbnRzIGlzIHJldGFpbmVkIGFuZCByZXVzZWQuCitURVNUKFJlcGVhdGVkUHRyRmllbGQsIENsZWFyZWRFbGVtZW50cykgeworICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4gZmllbGQ7CisKKyAgc3RyaW5nKiBvcmlnaW5hbCA9IGZpZWxkLkFkZCgpOworICAqb3JpZ2luYWwgPSAiZm9vIjsKKworICBFWFBFQ1RfRVEoZmllbGQuQ2xlYXJlZENvdW50KCksIDApOworCisgIGZpZWxkLlJlbW92ZUxhc3QoKTsKKyAgRVhQRUNUX1RSVUUob3JpZ2luYWwtPmVtcHR5KCkpOworICBFWFBFQ1RfRVEoZmllbGQuQ2xlYXJlZENvdW50KCksIDEpOworCisgIEVYUEVDVF9FUShmaWVsZC5BZGQoKSwgb3JpZ2luYWwpOyAgLy8gU2hvdWxkIHJldHVybiBzYW1lIHN0cmluZyBmb3IgcmV1c2UuCisKKyAgRVhQRUNUX0VRKGZpZWxkLlJlbGVhc2VMYXN0KCksIG9yaWdpbmFsKTsgIC8vIFdlIHRha2Ugb3duZXJzaGlwLgorICBFWFBFQ1RfRVEoZmllbGQuQ2xlYXJlZENvdW50KCksIDApOworCisgIEVYUEVDVF9ORShmaWVsZC5BZGQoKSwgb3JpZ2luYWwpOyAgLy8gU2hvdWxkIE5PVCByZXR1cm4gdGhlIHNhbWUgc3RyaW5nLgorICBFWFBFQ1RfRVEoZmllbGQuQ2xlYXJlZENvdW50KCksIDApOworCisgIGZpZWxkLkFkZEFsbG9jYXRlZChvcmlnaW5hbCk7ICAvLyBHaXZlIG93bmVyc2hpcCBiYWNrLgorICBFWFBFQ1RfRVEoZmllbGQuQ2xlYXJlZENvdW50KCksIDApOworICBFWFBFQ1RfRVEoZmllbGQuTXV0YWJsZSgxKSwgb3JpZ2luYWwpOworCisgIGZpZWxkLkNsZWFyKCk7CisgIEVYUEVDVF9FUShmaWVsZC5DbGVhcmVkQ291bnQoKSwgMik7CisgIEVYUEVDVF9FUShmaWVsZC5SZWxlYXNlQ2xlYXJlZCgpLCBvcmlnaW5hbCk7ICAvLyBUYWtlIG93bmVyc2hpcCBhZ2Fpbi4KKyAgRVhQRUNUX0VRKGZpZWxkLkNsZWFyZWRDb3VudCgpLCAxKTsKKyAgRVhQRUNUX05FKGZpZWxkLkFkZCgpLCBvcmlnaW5hbCk7CisgIEVYUEVDVF9FUShmaWVsZC5DbGVhcmVkQ291bnQoKSwgMCk7CisgIEVYUEVDVF9ORShmaWVsZC5BZGQoKSwgb3JpZ2luYWwpOworICBFWFBFQ1RfRVEoZmllbGQuQ2xlYXJlZENvdW50KCksIDApOworCisgIGZpZWxkLkFkZENsZWFyZWQob3JpZ2luYWwpOyAgLy8gR2l2ZSBvd25lcnNoaXAgYmFjaywgYnV0IGFzIGEgY2xlYXJlZCBvYmplY3QuCisgIEVYUEVDVF9FUShmaWVsZC5DbGVhcmVkQ291bnQoKSwgMSk7CisgIEVYUEVDVF9FUShmaWVsZC5BZGQoKSwgb3JpZ2luYWwpOworICBFWFBFQ1RfRVEoZmllbGQuQ2xlYXJlZENvdW50KCksIDApOworfQorCisvLyBUZXN0IGFsbCBjb2RlIHBhdGhzIGluIEFkZEFsbG9jYXRlZCgpLgorVEVTVChSZXBlYXRlZFB0ckZpZWxkLCBBZGRBbG9jYXRlZCkgeworICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4gZmllbGQ7CisgIHdoaWxlIChmaWVsZC5zaXplKCkgPCBmaWVsZC5DYXBhY2l0eSgpKSB7CisgICAgZmllbGQuQWRkKCktPmFzc2lnbigiZmlsbGVyIik7CisgIH0KKworICBpbnQgaW5kZXggPSBmaWVsZC5zaXplKCk7CisKKyAgLy8gRmlyc3QgYnJhbmNoOiAgRmllbGQgaXMgYXQgY2FwYWNpdHkgd2l0aCBubyBjbGVhcmVkIG9iamVjdHMuCisgIHN0cmluZyogZm9vID0gbmV3IHN0cmluZygiZm9vIik7CisgIGZpZWxkLkFkZEFsbG9jYXRlZChmb28pOworICBFWFBFQ1RfRVEoaW5kZXggKyAxLCBmaWVsZC5zaXplKCkpOworICBFWFBFQ1RfRVEoMCwgZmllbGQuQ2xlYXJlZENvdW50KCkpOworICBFWFBFQ1RfRVEoZm9vLCAmZmllbGQuR2V0KGluZGV4KSk7CisKKyAgLy8gTGFzdCBicmFuY2g6ICBGaWVsZCBpcyBub3QgYXQgY2FwYWNpdHkgYW5kIHRoZXJlIGFyZSBubyBjbGVhcmVkIG9iamVjdHMuCisgIHN0cmluZyogYmFyID0gbmV3IHN0cmluZygiYmFyIik7CisgIGZpZWxkLkFkZEFsbG9jYXRlZChiYXIpOworICArK2luZGV4OworICBFWFBFQ1RfRVEoaW5kZXggKyAxLCBmaWVsZC5zaXplKCkpOworICBFWFBFQ1RfRVEoMCwgZmllbGQuQ2xlYXJlZENvdW50KCkpOworICBFWFBFQ1RfRVEoYmFyLCAmZmllbGQuR2V0KGluZGV4KSk7CisKKyAgLy8gVGhpcmQgYnJhbmNoOiAgRmllbGQgaXMgbm90IGF0IGNhcGFjaXR5IGFuZCB0aGVyZSBhcmUgbm8gY2xlYXJlZCBvYmplY3RzLgorICBmaWVsZC5SZW1vdmVMYXN0KCk7CisgIHN0cmluZyogYmF6ID0gbmV3IHN0cmluZygiYmF6Iik7CisgIGZpZWxkLkFkZEFsbG9jYXRlZChiYXopOworICBFWFBFQ1RfRVEoaW5kZXggKyAxLCBmaWVsZC5zaXplKCkpOworICBFWFBFQ1RfRVEoMSwgZmllbGQuQ2xlYXJlZENvdW50KCkpOworICBFWFBFQ1RfRVEoYmF6LCAmZmllbGQuR2V0KGluZGV4KSk7CisKKyAgLy8gU2Vjb25kIGJyYW5jaDogIEZpZWxkIGlzIGF0IGNhcGFjaXR5IGJ1dCBoYXMgc29tZSBjbGVhcmVkIG9iamVjdHMuCisgIHdoaWxlIChmaWVsZC5zaXplKCkgPCBmaWVsZC5DYXBhY2l0eSgpKSB7CisgICAgZmllbGQuQWRkKCktPmFzc2lnbigiZmlsbGVyMiIpOworICB9CisgIGZpZWxkLlJlbW92ZUxhc3QoKTsKKyAgaW5kZXggPSBmaWVsZC5zaXplKCk7CisgIHN0cmluZyogcXV4ID0gbmV3IHN0cmluZygicXV4Iik7CisgIGZpZWxkLkFkZEFsbG9jYXRlZChxdXgpOworICBFWFBFQ1RfRVEoaW5kZXggKyAxLCBmaWVsZC5zaXplKCkpOworICAvLyBXZSBzaG91bGQgaGF2ZSBkaXNjYXJkZWQgdGhlIGNsZWFyZWQgb2JqZWN0LgorICBFWFBFQ1RfRVEoMCwgZmllbGQuQ2xlYXJlZENvdW50KCkpOworICBFWFBFQ1RfRVEocXV4LCAmZmllbGQuR2V0KGluZGV4KSk7Cit9CisKK1RFU1QoUmVwZWF0ZWRQdHJGaWVsZCwgTWVyZ2VGcm9tKSB7CisgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPiBzb3VyY2UsIGRlc3RpbmF0aW9uOworICBzb3VyY2UuQWRkKCktPmFzc2lnbigiNCIpOworICBzb3VyY2UuQWRkKCktPmFzc2lnbigiNSIpOworICBkZXN0aW5hdGlvbi5BZGQoKS0+YXNzaWduKCIxIik7CisgIGRlc3RpbmF0aW9uLkFkZCgpLT5hc3NpZ24oIjIiKTsKKyAgZGVzdGluYXRpb24uQWRkKCktPmFzc2lnbigiMyIpOworCisgIGRlc3RpbmF0aW9uLk1lcmdlRnJvbShzb3VyY2UpOworCisgIEFTU0VSVF9FUSg1LCBkZXN0aW5hdGlvbi5zaXplKCkpOworICBFWFBFQ1RfRVEoIjEiLCBkZXN0aW5hdGlvbi5HZXQoMCkpOworICBFWFBFQ1RfRVEoIjIiLCBkZXN0aW5hdGlvbi5HZXQoMSkpOworICBFWFBFQ1RfRVEoIjMiLCBkZXN0aW5hdGlvbi5HZXQoMikpOworICBFWFBFQ1RfRVEoIjQiLCBkZXN0aW5hdGlvbi5HZXQoMykpOworICBFWFBFQ1RfRVEoIjUiLCBkZXN0aW5hdGlvbi5HZXQoNCkpOworfQorCisjaWZkZWYgUFJPVE9CVUZfSEFTX0RFQVRIX1RFU1QKK1RFU1QoUmVwZWF0ZWRQdHJGaWVsZCwgTWVyZ2VGcm9tU2VsZikgeworICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4gbWU7CisgIG1lLkFkZCgpLT5hc3NpZ24oIjEiKTsKKyAgRVhQRUNUX0RFQVRIKG1lLk1lcmdlRnJvbShtZSksICIiKTsKK30KKyNlbmRpZiAgLy8gUFJPVE9CVUZfSEFTX0RFQVRIX1RFU1QKKworVEVTVChSZXBlYXRlZFB0ckZpZWxkLCBDb3B5RnJvbSkgeworICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4gc291cmNlLCBkZXN0aW5hdGlvbjsKKyAgc291cmNlLkFkZCgpLT5hc3NpZ24oIjQiKTsKKyAgc291cmNlLkFkZCgpLT5hc3NpZ24oIjUiKTsKKyAgZGVzdGluYXRpb24uQWRkKCktPmFzc2lnbigiMSIpOworICBkZXN0aW5hdGlvbi5BZGQoKS0+YXNzaWduKCIyIik7CisgIGRlc3RpbmF0aW9uLkFkZCgpLT5hc3NpZ24oIjMiKTsKKworICBkZXN0aW5hdGlvbi5Db3B5RnJvbShzb3VyY2UpOworCisgIEFTU0VSVF9FUSgyLCBkZXN0aW5hdGlvbi5zaXplKCkpOworICBFWFBFQ1RfRVEoIjQiLCBkZXN0aW5hdGlvbi5HZXQoMCkpOworICBFWFBFQ1RfRVEoIjUiLCBkZXN0aW5hdGlvbi5HZXQoMSkpOworfQorCitURVNUKFJlcGVhdGVkUHRyRmllbGQsIENvcHlGcm9tU2VsZikgeworICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4gbWU7CisgIG1lLkFkZCgpLT5hc3NpZ24oIjEiKTsKKyAgbWUuQ29weUZyb20obWUpOworICBBU1NFUlRfRVEoMSwgbWUuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKCIxIiwgbWUuR2V0KDApKTsKK30KKworVEVTVChSZXBlYXRlZFB0ckZpZWxkLCBFcmFzZSkgeworICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4gbWU7CisgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPjo6aXRlcmF0b3IgaXQgPSBtZS5lcmFzZShtZS5iZWdpbigpLCBtZS5lbmQoKSk7CisgIEVYUEVDVF9UUlVFKG1lLmJlZ2luKCkgPT0gaXQpOworICBFWFBFQ1RfRVEoMCwgbWUuc2l6ZSgpKTsKKworICAqbWUuQWRkKCkgPSAiMSI7CisgICptZS5BZGQoKSA9ICIyIjsKKyAgKm1lLkFkZCgpID0gIjMiOworICBpdCA9IG1lLmVyYXNlKG1lLmJlZ2luKCksIG1lLmVuZCgpKTsKKyAgRVhQRUNUX1RSVUUobWUuYmVnaW4oKSA9PSBpdCk7CisgIEVYUEVDVF9FUSgwLCBtZS5zaXplKCkpOworCisgICptZS5BZGQoKSA9ICI0IjsKKyAgKm1lLkFkZCgpID0gIjUiOworICAqbWUuQWRkKCkgPSAiNiI7CisgIGl0ID0gbWUuZXJhc2UobWUuYmVnaW4oKSArIDIsIG1lLmVuZCgpKTsKKyAgRVhQRUNUX1RSVUUobWUuYmVnaW4oKSArIDIgPT0gaXQpOworICBFWFBFQ1RfRVEoMiwgbWUuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKCI0IiwgbWUuR2V0KDApKTsKKyAgRVhQRUNUX0VRKCI1IiwgbWUuR2V0KDEpKTsKKworICAqbWUuQWRkKCkgPSAiNiI7CisgICptZS5BZGQoKSA9ICI3IjsKKyAgKm1lLkFkZCgpID0gIjgiOworICBpdCA9IG1lLmVyYXNlKG1lLmJlZ2luKCkgKyAxLCBtZS5iZWdpbigpICsgMyk7CisgIEVYUEVDVF9UUlVFKG1lLmJlZ2luKCkgKyAxID09IGl0KTsKKyAgRVhQRUNUX0VRKDMsIG1lLnNpemUoKSk7CisgIEVYUEVDVF9FUSgiNCIsIG1lLkdldCgwKSk7CisgIEVYUEVDVF9FUSgiNyIsIG1lLkdldCgxKSk7CisgIEVYUEVDVF9FUSgiOCIsIG1lLkdldCgyKSk7Cit9CisKK1RFU1QoUmVwZWF0ZWRQdHJGaWVsZCwgQ29weUNvbnN0cnVjdCkgeworICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4gc291cmNlOworICBzb3VyY2UuQWRkKCktPmFzc2lnbigiMSIpOworICBzb3VyY2UuQWRkKCktPmFzc2lnbigiMiIpOworCisgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPiBkZXN0aW5hdGlvbihzb3VyY2UpOworCisgIEFTU0VSVF9FUSgyLCBkZXN0aW5hdGlvbi5zaXplKCkpOworICBFWFBFQ1RfRVEoIjEiLCBkZXN0aW5hdGlvbi5HZXQoMCkpOworICBFWFBFQ1RfRVEoIjIiLCBkZXN0aW5hdGlvbi5HZXQoMSkpOworfQorCitURVNUKFJlcGVhdGVkUHRyRmllbGQsIEl0ZXJhdG9yQ29uc3RydWN0X1N0cmluZykgeworICB2ZWN0b3I8c3RyaW5nPiB2YWx1ZXM7CisgIHZhbHVlcy5wdXNoX2JhY2soIjEiKTsKKyAgdmFsdWVzLnB1c2hfYmFjaygiMiIpOworCisgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPiBmaWVsZCh2YWx1ZXMuYmVnaW4oKSwgdmFsdWVzLmVuZCgpKTsKKyAgQVNTRVJUX0VRKHZhbHVlcy5zaXplKCksIGZpZWxkLnNpemUoKSk7CisgIEVYUEVDVF9FUSh2YWx1ZXNbMF0sIGZpZWxkLkdldCgwKSk7CisgIEVYUEVDVF9FUSh2YWx1ZXNbMV0sIGZpZWxkLkdldCgxKSk7CisKKyAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+IG90aGVyKGZpZWxkLmJlZ2luKCksIGZpZWxkLmVuZCgpKTsKKyAgQVNTRVJUX0VRKHZhbHVlcy5zaXplKCksIG90aGVyLnNpemUoKSk7CisgIEVYUEVDVF9FUSh2YWx1ZXNbMF0sIG90aGVyLkdldCgwKSk7CisgIEVYUEVDVF9FUSh2YWx1ZXNbMV0sIG90aGVyLkdldCgxKSk7Cit9CisKK1RFU1QoUmVwZWF0ZWRQdHJGaWVsZCwgSXRlcmF0b3JDb25zdHJ1Y3RfUHJvdG8pIHsKKyAgdHlwZWRlZiBUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2UgTmVzdGVkOworICB2ZWN0b3I8TmVzdGVkPiB2YWx1ZXM7CisgIHZhbHVlcy5wdXNoX2JhY2soTmVzdGVkKCkpOworICB2YWx1ZXMuYmFjaygpLnNldF9iYigxKTsKKyAgdmFsdWVzLnB1c2hfYmFjayhOZXN0ZWQoKSk7CisgIHZhbHVlcy5iYWNrKCkuc2V0X2JiKDIpOworCisgIFJlcGVhdGVkUHRyRmllbGQ8TmVzdGVkPiBmaWVsZCh2YWx1ZXMuYmVnaW4oKSwgdmFsdWVzLmVuZCgpKTsKKyAgQVNTRVJUX0VRKHZhbHVlcy5zaXplKCksIGZpZWxkLnNpemUoKSk7CisgIEVYUEVDVF9FUSh2YWx1ZXNbMF0uYmIoKSwgZmllbGQuR2V0KDApLmJiKCkpOworICBFWFBFQ1RfRVEodmFsdWVzWzFdLmJiKCksIGZpZWxkLkdldCgxKS5iYigpKTsKKworICBSZXBlYXRlZFB0ckZpZWxkPE5lc3RlZD4gb3RoZXIoZmllbGQuYmVnaW4oKSwgZmllbGQuZW5kKCkpOworICBBU1NFUlRfRVEodmFsdWVzLnNpemUoKSwgb3RoZXIuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKHZhbHVlc1swXS5iYigpLCBvdGhlci5HZXQoMCkuYmIoKSk7CisgIEVYUEVDVF9FUSh2YWx1ZXNbMV0uYmIoKSwgb3RoZXIuR2V0KDEpLmJiKCkpOworfQorCitURVNUKFJlcGVhdGVkUHRyRmllbGQsIENvcHlBc3NpZ24pIHsKKyAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+IHNvdXJjZSwgZGVzdGluYXRpb247CisgIHNvdXJjZS5BZGQoKS0+YXNzaWduKCI0Iik7CisgIHNvdXJjZS5BZGQoKS0+YXNzaWduKCI1Iik7CisgIGRlc3RpbmF0aW9uLkFkZCgpLT5hc3NpZ24oIjEiKTsKKyAgZGVzdGluYXRpb24uQWRkKCktPmFzc2lnbigiMiIpOworICBkZXN0aW5hdGlvbi5BZGQoKS0+YXNzaWduKCIzIik7CisKKyAgZGVzdGluYXRpb24gPSBzb3VyY2U7CisKKyAgQVNTRVJUX0VRKDIsIGRlc3RpbmF0aW9uLnNpemUoKSk7CisgIEVYUEVDVF9FUSgiNCIsIGRlc3RpbmF0aW9uLkdldCgwKSk7CisgIEVYUEVDVF9FUSgiNSIsIGRlc3RpbmF0aW9uLkdldCgxKSk7Cit9CisKK1RFU1QoUmVwZWF0ZWRQdHJGaWVsZCwgU2VsZkFzc2lnbikgeworICAvLyBWZXJpZnkgdGhhdCBhc3NpZ25tZW50IHRvIHNlbGYgZG9lcyBub3QgZGVzdHJveSBkYXRhLgorICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz4gc291cmNlLCAqcDsKKyAgcCA9ICZzb3VyY2U7CisgIHNvdXJjZS5BZGQoKS0+YXNzaWduKCI3Iik7CisgIHNvdXJjZS5BZGQoKS0+YXNzaWduKCI4Iik7CisKKyAgKnAgPSBzb3VyY2U7CisKKyAgQVNTRVJUX0VRKDIsIHNvdXJjZS5zaXplKCkpOworICBFWFBFQ1RfRVEoIjciLCBzb3VyY2UuR2V0KDApKTsKKyAgRVhQRUNUX0VRKCI4Iiwgc291cmNlLkdldCgxKSk7Cit9CisKK1RFU1QoUmVwZWF0ZWRQdHJGaWVsZCwgTXV0YWJsZURhdGFJc011dGFibGUpIHsKKyAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+IGZpZWxkOworICAqZmllbGQuQWRkKCkgPSAiMSI7CisgIEVYUEVDVF9FUSgiMSIsIGZpZWxkLkdldCgwKSk7CisgIC8vIFRoZSBmYWN0IHRoYXQgdGhpcyBsaW5lIGNvbXBpbGVzIHdvdWxkIGJlIGVub3VnaCwgYnV0IHdlJ2xsIGNoZWNrIHRoZQorICAvLyB2YWx1ZSBhbnl3YXkuCisgIHN0cmluZyoqIGRhdGEgPSBmaWVsZC5tdXRhYmxlX2RhdGEoKTsKKyAgKipkYXRhID0gIjIiOworICBFWFBFQ1RfRVEoIjIiLCBmaWVsZC5HZXQoMCkpOworfQorCitURVNUKFJlcGVhdGVkUHRyRmllbGQsIEV4dHJhY3RTdWJyYW5nZSkgeworICAvLyBFeGhhdXN0aXZlbHkgdGVzdCBldmVyeSBzdWJyYW5nZSBpbiBhcnJheXMgb2YgYWxsIHNpemVzIGZyb20gMCB0aHJvdWdoIDkKKyAgLy8gd2l0aCAwIHRocm91Z2ggMyBjbGVhcmVkIGVsZW1lbnRzIGF0IHRoZSBlbmQuCisgIGZvciAoaW50IHN6ID0gMDsgc3ogPCAxMDsgKytzeikgeworICAgIGZvciAoaW50IG51bSA9IDA7IG51bSA8PSBzejsgKytudW0pIHsKKyAgICAgIGZvciAoaW50IHN0YXJ0ID0gMDsgc3RhcnQgPCBzeiAtIG51bTsgKytzdGFydCkgeworICAgICAgICBmb3IgKGludCBleHRyYSA9IDA7IGV4dHJhIDwgNDsgKytleHRyYSkgeworICAgICAgICAgIHZlY3RvcjxzdHJpbmcqPiBzdWJqZWN0OworCisgICAgICAgICAgLy8gQ3JlYXRlIGFuIGFycmF5IHdpdGggInN6IiBlbGVtZW50cyBhbmQgImV4dHJhIiBjbGVhcmVkIGVsZW1lbnRzLgorICAgICAgICAgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPiBmaWVsZDsKKyAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHN6ICsgZXh0cmE7ICsraSkgeworICAgICAgICAgICAgc3ViamVjdC5wdXNoX2JhY2sobmV3IHN0cmluZygpKTsKKyAgICAgICAgICAgIGZpZWxkLkFkZEFsbG9jYXRlZChzdWJqZWN0W2ldKTsKKyAgICAgICAgICB9CisgICAgICAgICAgRVhQRUNUX0VRKGZpZWxkLnNpemUoKSwgc3ogKyBleHRyYSk7CisgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBleHRyYTsgKytpKQorICAgICAgICAgICAgZmllbGQuUmVtb3ZlTGFzdCgpOworICAgICAgICAgIEVYUEVDVF9FUShmaWVsZC5zaXplKCksIHN6KTsKKyAgICAgICAgICBFWFBFQ1RfRVEoZmllbGQuQ2xlYXJlZENvdW50KCksIGV4dHJhKTsKKworICAgICAgICAgIC8vIENyZWF0ZSBhIGNhdGNoZXIgYXJyYXkgYW5kIGNhbGwgRXh0cmFjdFN1YnJhbmdlLgorICAgICAgICAgIHN0cmluZyogY2F0Y2hlclsxMF07CisgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgKytpKQorICAgICAgICAgICAgY2F0Y2hlcltpXSA9IE5VTEw7CisgICAgICAgICAgZmllbGQuRXh0cmFjdFN1YnJhbmdlKHN0YXJ0LCBudW0sIGNhdGNoZXIpOworCisgICAgICAgICAgLy8gRG9lcyB0aGUgcmVzdWx0aW5nIGFycmF5IGhhdmUgdGhlIHJpZ2h0IHNpemU/CisgICAgICAgICAgRVhQRUNUX0VRKGZpZWxkLnNpemUoKSwgc3ogLSBudW0pOworCisgICAgICAgICAgLy8gV2VyZSB0aGUgcmVtb3ZlZCBlbGVtZW50cyBleHRyYWN0ZWQgaW50byB0aGUgY2F0Y2hlciBhcnJheT8KKyAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bTsgKytpKQorICAgICAgICAgICAgRVhQRUNUX0VRKGNhdGNoZXJbaV0sIHN1YmplY3Rbc3RhcnQgKyBpXSk7CisgICAgICAgICAgRVhQRUNUX0VRKE5VTEwsIGNhdGNoZXJbbnVtXSk7CisKKyAgICAgICAgICAvLyBEb2VzIHRoZSByZXN1bHRpbmcgYXJyYXkgY29udGFpbiB0aGUgcmlnaHQgdmFsdWVzPworICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc3RhcnQ7ICsraSkKKyAgICAgICAgICAgIEVYUEVDVF9FUShmaWVsZC5NdXRhYmxlKGkpLCBzdWJqZWN0W2ldKTsKKyAgICAgICAgICBmb3IgKGludCBpID0gc3RhcnQ7IGkgPCBmaWVsZC5zaXplKCk7ICsraSkKKyAgICAgICAgICAgIEVYUEVDVF9FUShmaWVsZC5NdXRhYmxlKGkpLCBzdWJqZWN0W2kgKyBudW1dKTsKKworICAgICAgICAgIC8vIFJlaW5zdGF0ZSB0aGUgY2xlYXJlZCBlbGVtZW50cy4KKyAgICAgICAgICBFWFBFQ1RfRVEoZmllbGQuQ2xlYXJlZENvdW50KCksIGV4dHJhKTsKKyAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGV4dHJhOyArK2kpCisgICAgICAgICAgICBmaWVsZC5BZGQoKTsKKyAgICAgICAgICBFWFBFQ1RfRVEoZmllbGQuQ2xlYXJlZENvdW50KCksIDApOworICAgICAgICAgIEVYUEVDVF9FUShmaWVsZC5zaXplKCksIHN6IC0gbnVtICsgZXh0cmEpOworCisgICAgICAgICAgLy8gTWFrZSBzdXJlIHRoZSBleHRyYSBlbGVtZW50cyBhcmUgYWxsIHRoZXJlIChpbiBzb21lIG9yZGVyKS4KKyAgICAgICAgICBmb3IgKGludCBpID0gc3o7IGkgPCBzeiArIGV4dHJhOyArK2kpIHsKKyAgICAgICAgICAgIGludCBjb3VudCA9IDA7CisgICAgICAgICAgICBmb3IgKGludCBqID0gc3o7IGogPCBzeiArIGV4dHJhOyArK2opIHsKKyAgICAgICAgICAgICAgaWYgKGZpZWxkLk11dGFibGUoaiAtIG51bSkgPT0gc3ViamVjdFtpXSkKKyAgICAgICAgICAgICAgICBjb3VudCArPSAxOworICAgICAgICAgICAgfQorICAgICAgICAgICAgRVhQRUNUX0VRKGNvdW50LCAxKTsKKyAgICAgICAgICB9CisKKyAgICAgICAgICAvLyBSZWxlYXNlIHRoZSBjYXVnaHQgZWxlbWVudHMuCisgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW07ICsraSkKKyAgICAgICAgICAgIGRlbGV0ZSBjYXRjaGVyW2ldOworICAgICAgICB9CisgICAgICB9CisgICAgfQorICB9Cit9CisKK1RFU1QoUmVwZWF0ZWRQdHJGaWVsZCwgRGVsZXRlU3VicmFuZ2UpIHsKKyAgLy8gRGVsZXRlU3VicmFuZ2UgaXMgYSB0cml2aWFsIGV4dGVuc2lvbiBvZiBFeHRlbmRTdWJyYW5nZS4KK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisvLyBJdGVyYXRvciB0ZXN0cyBzdG9sZW4gZnJvbSBuZXQvcHJvdG8vcHJvdG8tYXJyYXlfdW5pdHRlc3QuCitjbGFzcyBSZXBlYXRlZEZpZWxkSXRlcmF0b3JUZXN0IDogcHVibGljIHRlc3Rpbmc6OlRlc3QgeworIHByb3RlY3RlZDoKKyAgdmlydHVhbCB2b2lkIFNldFVwKCkgeworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMzsgKytpKSB7CisgICAgICBwcm90b19hcnJheV8uQWRkKGkpOworICAgIH0KKyAgfQorCisgIFJlcGVhdGVkRmllbGQ8aW50PiBwcm90b19hcnJheV87Cit9OworCitURVNUX0YoUmVwZWF0ZWRGaWVsZEl0ZXJhdG9yVGVzdCwgQ29udmVydGlibGUpIHsKKyAgUmVwZWF0ZWRGaWVsZDxpbnQ+OjppdGVyYXRvciBpdGVyID0gcHJvdG9fYXJyYXlfLmJlZ2luKCk7CisgIFJlcGVhdGVkRmllbGQ8aW50Pjo6Y29uc3RfaXRlcmF0b3IgY19pdGVyID0gaXRlcjsKKyAgUmVwZWF0ZWRGaWVsZDxpbnQ+Ojp2YWx1ZV90eXBlIHZhbHVlID0gKmNfaXRlcjsKKyAgRVhQRUNUX0VRKDAsIHZhbHVlKTsKK30KKworVEVTVF9GKFJlcGVhdGVkRmllbGRJdGVyYXRvclRlc3QsIE11dGFibGVJdGVyYXRpb24pIHsKKyAgUmVwZWF0ZWRGaWVsZDxpbnQ+OjppdGVyYXRvciBpdGVyID0gcHJvdG9fYXJyYXlfLmJlZ2luKCk7CisgIEVYUEVDVF9FUSgwLCAqaXRlcik7CisgICsraXRlcjsKKyAgRVhQRUNUX0VRKDEsICppdGVyKyspOworICBFWFBFQ1RfRVEoMiwgKml0ZXIpOworICArK2l0ZXI7CisgIEVYUEVDVF9UUlVFKHByb3RvX2FycmF5Xy5lbmQoKSA9PSBpdGVyKTsKKworICBFWFBFQ1RfRVEoMiwgKihwcm90b19hcnJheV8uZW5kKCkgLSAxKSk7Cit9CisKK1RFU1RfRihSZXBlYXRlZEZpZWxkSXRlcmF0b3JUZXN0LCBDb25zdEl0ZXJhdGlvbikgeworICBjb25zdCBSZXBlYXRlZEZpZWxkPGludD4mIGNvbnN0X3Byb3RvX2FycmF5ID0gcHJvdG9fYXJyYXlfOworICBSZXBlYXRlZEZpZWxkPGludD46OmNvbnN0X2l0ZXJhdG9yIGl0ZXIgPSBjb25zdF9wcm90b19hcnJheS5iZWdpbigpOworICBFWFBFQ1RfRVEoMCwgKml0ZXIpOworICArK2l0ZXI7CisgIEVYUEVDVF9FUSgxLCAqaXRlcisrKTsKKyAgRVhQRUNUX0VRKDIsICppdGVyKTsKKyAgKytpdGVyOworICBFWFBFQ1RfVFJVRShwcm90b19hcnJheV8uZW5kKCkgPT0gaXRlcik7CisgIEVYUEVDVF9FUSgyLCAqKHByb3RvX2FycmF5Xy5lbmQoKSAtIDEpKTsKK30KKworVEVTVF9GKFJlcGVhdGVkRmllbGRJdGVyYXRvclRlc3QsIE11dGF0aW9uKSB7CisgIFJlcGVhdGVkRmllbGQ8aW50Pjo6aXRlcmF0b3IgaXRlciA9IHByb3RvX2FycmF5Xy5iZWdpbigpOworICAqaXRlciA9IDc7CisgIEVYUEVDVF9FUSg3LCBwcm90b19hcnJheV8uR2V0KDApKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBSZXBlYXRlZFB0ckZpZWxkSXRlcmF0b3JUZXN0IDogcHVibGljIHRlc3Rpbmc6OlRlc3QgeworIHByb3RlY3RlZDoKKyAgdmlydHVhbCB2b2lkIFNldFVwKCkgeworICAgIHByb3RvX2FycmF5Xy5BZGQoKS0+YXNzaWduKCJmb28iKTsKKyAgICBwcm90b19hcnJheV8uQWRkKCktPmFzc2lnbigiYmFyIik7CisgICAgcHJvdG9fYXJyYXlfLkFkZCgpLT5hc3NpZ24oImJheiIpOworICB9CisKKyAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+IHByb3RvX2FycmF5XzsKK307CisKK1RFU1RfRihSZXBlYXRlZFB0ckZpZWxkSXRlcmF0b3JUZXN0LCBDb252ZXJ0aWJsZSkgeworICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz46Oml0ZXJhdG9yIGl0ZXIgPSBwcm90b19hcnJheV8uYmVnaW4oKTsKKyAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+Ojpjb25zdF9pdGVyYXRvciBjX2l0ZXIgPSBpdGVyOworICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz46OnZhbHVlX3R5cGUgdmFsdWUgPSAqY19pdGVyOworICBFWFBFQ1RfRVEoImZvbyIsIHZhbHVlKTsKK30KKworVEVTVF9GKFJlcGVhdGVkUHRyRmllbGRJdGVyYXRvclRlc3QsIE11dGFibGVJdGVyYXRpb24pIHsKKyAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+OjppdGVyYXRvciBpdGVyID0gcHJvdG9fYXJyYXlfLmJlZ2luKCk7CisgIEVYUEVDVF9FUSgiZm9vIiwgKml0ZXIpOworICArK2l0ZXI7CisgIEVYUEVDVF9FUSgiYmFyIiwgKihpdGVyKyspKTsKKyAgRVhQRUNUX0VRKCJiYXoiLCAqaXRlcik7CisgICsraXRlcjsKKyAgRVhQRUNUX1RSVUUocHJvdG9fYXJyYXlfLmVuZCgpID09IGl0ZXIpOworICBFWFBFQ1RfRVEoImJheiIsICooLS1wcm90b19hcnJheV8uZW5kKCkpKTsKK30KKworVEVTVF9GKFJlcGVhdGVkUHRyRmllbGRJdGVyYXRvclRlc3QsIENvbnN0SXRlcmF0aW9uKSB7CisgIGNvbnN0IFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPiYgY29uc3RfcHJvdG9fYXJyYXkgPSBwcm90b19hcnJheV87CisgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPjo6Y29uc3RfaXRlcmF0b3IgaXRlciA9IGNvbnN0X3Byb3RvX2FycmF5LmJlZ2luKCk7CisgIEVYUEVDVF9FUSgiZm9vIiwgKml0ZXIpOworICArK2l0ZXI7CisgIEVYUEVDVF9FUSgiYmFyIiwgKihpdGVyKyspKTsKKyAgRVhQRUNUX0VRKCJiYXoiLCAqaXRlcik7CisgICsraXRlcjsKKyAgRVhQRUNUX1RSVUUoY29uc3RfcHJvdG9fYXJyYXkuZW5kKCkgPT0gaXRlcik7CisgIEVYUEVDVF9FUSgiYmF6IiwgKigtLWNvbnN0X3Byb3RvX2FycmF5LmVuZCgpKSk7Cit9CisKK1RFU1RfRihSZXBlYXRlZFB0ckZpZWxkSXRlcmF0b3JUZXN0LCBNdXRhYmxlUmV2ZXJzZUl0ZXJhdGlvbikgeworICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz46OnJldmVyc2VfaXRlcmF0b3IgaXRlciA9IHByb3RvX2FycmF5Xy5yYmVnaW4oKTsKKyAgRVhQRUNUX0VRKCJiYXoiLCAqaXRlcik7CisgICsraXRlcjsKKyAgRVhQRUNUX0VRKCJiYXIiLCAqKGl0ZXIrKykpOworICBFWFBFQ1RfRVEoImZvbyIsICppdGVyKTsKKyAgKytpdGVyOworICBFWFBFQ1RfVFJVRShwcm90b19hcnJheV8ucmVuZCgpID09IGl0ZXIpOworICBFWFBFQ1RfRVEoImZvbyIsICooLS1wcm90b19hcnJheV8ucmVuZCgpKSk7Cit9CisKK1RFU1RfRihSZXBlYXRlZFB0ckZpZWxkSXRlcmF0b3JUZXN0LCBDb25zdFJldmVyc2VJdGVyYXRpb24pIHsKKyAgY29uc3QgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+JiBjb25zdF9wcm90b19hcnJheSA9IHByb3RvX2FycmF5XzsKKyAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+Ojpjb25zdF9yZXZlcnNlX2l0ZXJhdG9yIGl0ZXIKKyAgICAgID0gY29uc3RfcHJvdG9fYXJyYXkucmJlZ2luKCk7CisgIEVYUEVDVF9FUSgiYmF6IiwgKml0ZXIpOworICArK2l0ZXI7CisgIEVYUEVDVF9FUSgiYmFyIiwgKihpdGVyKyspKTsKKyAgRVhQRUNUX0VRKCJmb28iLCAqaXRlcik7CisgICsraXRlcjsKKyAgRVhQRUNUX1RSVUUoY29uc3RfcHJvdG9fYXJyYXkucmVuZCgpID09IGl0ZXIpOworICBFWFBFQ1RfRVEoImZvbyIsICooLS1jb25zdF9wcm90b19hcnJheS5yZW5kKCkpKTsKK30KKworVEVTVF9GKFJlcGVhdGVkUHRyRmllbGRJdGVyYXRvclRlc3QsIFJhbmRvbUFjY2VzcykgeworICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz46Oml0ZXJhdG9yIGl0ZXIgPSBwcm90b19hcnJheV8uYmVnaW4oKTsKKyAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+OjppdGVyYXRvciBpdGVyMiA9IGl0ZXI7CisgICsraXRlcjI7CisgICsraXRlcjI7CisgIEVYUEVDVF9UUlVFKGl0ZXIgKyAyID09IGl0ZXIyKTsKKyAgRVhQRUNUX1RSVUUoaXRlciA9PSBpdGVyMiAtIDIpOworICBFWFBFQ1RfRVEoImJheiIsIGl0ZXJbMl0pOworICBFWFBFQ1RfRVEoImJheiIsICooaXRlciArIDIpKTsKKyAgRVhQRUNUX0VRKDMsIHByb3RvX2FycmF5Xy5lbmQoKSAtIHByb3RvX2FycmF5Xy5iZWdpbigpKTsKK30KKworVEVTVF9GKFJlcGVhdGVkUHRyRmllbGRJdGVyYXRvclRlc3QsIENvbXBhcmFibGUpIHsKKyAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+Ojpjb25zdF9pdGVyYXRvciBpdGVyID0gcHJvdG9fYXJyYXlfLmJlZ2luKCk7CisgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPjo6Y29uc3RfaXRlcmF0b3IgaXRlcjIgPSBpdGVyICsgMTsKKyAgRVhQRUNUX1RSVUUoaXRlciA9PSBpdGVyKTsKKyAgRVhQRUNUX1RSVUUoaXRlciAhPSBpdGVyMik7CisgIEVYUEVDVF9UUlVFKGl0ZXIgPCBpdGVyMik7CisgIEVYUEVDVF9UUlVFKGl0ZXIgPD0gaXRlcjIpOworICBFWFBFQ1RfVFJVRShpdGVyIDw9IGl0ZXIpOworICBFWFBFQ1RfVFJVRShpdGVyMiA+IGl0ZXIpOworICBFWFBFQ1RfVFJVRShpdGVyMiA+PSBpdGVyKTsKKyAgRVhQRUNUX1RSVUUoaXRlciA+PSBpdGVyKTsKK30KKworLy8gVW5pbml0aWFsaXplZCBpdGVyYXRvciBkb2VzIG5vdCBwb2ludCB0byBhbnkgb2YgdGhlIFJlcGVhdGVkUHRyRmllbGQuCitURVNUX0YoUmVwZWF0ZWRQdHJGaWVsZEl0ZXJhdG9yVGVzdCwgVW5pbml0aWFsaXplZEl0ZXJhdG9yKSB7CisgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPjo6aXRlcmF0b3IgaXRlcjsKKyAgRVhQRUNUX1RSVUUoaXRlciAhPSBwcm90b19hcnJheV8uYmVnaW4oKSk7CisgIEVYUEVDVF9UUlVFKGl0ZXIgIT0gcHJvdG9fYXJyYXlfLmJlZ2luKCkgKyAxKTsKKyAgRVhQRUNUX1RSVUUoaXRlciAhPSBwcm90b19hcnJheV8uYmVnaW4oKSArIDIpOworICBFWFBFQ1RfVFJVRShpdGVyICE9IHByb3RvX2FycmF5Xy5iZWdpbigpICsgMyk7CisgIEVYUEVDVF9UUlVFKGl0ZXIgIT0gcHJvdG9fYXJyYXlfLmVuZCgpKTsKK30KKworVEVTVF9GKFJlcGVhdGVkUHRyRmllbGRJdGVyYXRvclRlc3QsIFNUTEFsZ29yaXRobXNfbG93ZXJfYm91bmQpIHsKKyAgcHJvdG9fYXJyYXlfLkNsZWFyKCk7CisgIHByb3RvX2FycmF5Xy5BZGQoKS0+YXNzaWduKCJhIik7CisgIHByb3RvX2FycmF5Xy5BZGQoKS0+YXNzaWduKCJjIik7CisgIHByb3RvX2FycmF5Xy5BZGQoKS0+YXNzaWduKCJkIik7CisgIHByb3RvX2FycmF5Xy5BZGQoKS0+YXNzaWduKCJuIik7CisgIHByb3RvX2FycmF5Xy5BZGQoKS0+YXNzaWduKCJwIik7CisgIHByb3RvX2FycmF5Xy5BZGQoKS0+YXNzaWduKCJ4Iik7CisgIHByb3RvX2FycmF5Xy5BZGQoKS0+YXNzaWduKCJ5Iik7CisKKyAgc3RyaW5nIHYgPSAiZiI7CisgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPjo6Y29uc3RfaXRlcmF0b3IgaXQgPQorICAgICAgc3RkOjpsb3dlcl9ib3VuZChwcm90b19hcnJheV8uYmVnaW4oKSwgcHJvdG9fYXJyYXlfLmVuZCgpLCB2KTsKKworICBFWFBFQ1RfRVEoKml0LCAibiIpOworICBFWFBFQ1RfVFJVRShpdCA9PSBwcm90b19hcnJheV8uYmVnaW4oKSArIDMpOworfQorCitURVNUX0YoUmVwZWF0ZWRQdHJGaWVsZEl0ZXJhdG9yVGVzdCwgTXV0YXRpb24pIHsKKyAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+OjppdGVyYXRvciBpdGVyID0gcHJvdG9fYXJyYXlfLmJlZ2luKCk7CisgICppdGVyID0gInF1eCI7CisgIEVYUEVDVF9FUSgicXV4IiwgcHJvdG9fYXJyYXlfLkdldCgwKSk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgUmVwZWF0ZWRQdHJGaWVsZFB0cnNJdGVyYXRvclRlc3QgOiBwdWJsaWMgdGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICB2aXJ0dWFsIHZvaWQgU2V0VXAoKSB7CisgICAgcHJvdG9fYXJyYXlfLkFkZCgpLT5hc3NpZ24oImZvbyIpOworICAgIHByb3RvX2FycmF5Xy5BZGQoKS0+YXNzaWduKCJiYXIiKTsKKyAgICBwcm90b19hcnJheV8uQWRkKCktPmFzc2lnbigiYmF6Iik7CisgICAgY29uc3RfcHJvdG9fYXJyYXlfID0gJnByb3RvX2FycmF5XzsKKyAgfQorCisgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPiBwcm90b19hcnJheV87CisgIGNvbnN0IFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPiogY29uc3RfcHJvdG9fYXJyYXlfOworfTsKKworVEVTVF9GKFJlcGVhdGVkUHRyRmllbGRQdHJzSXRlcmF0b3JUZXN0LCBDb252ZXJ0aWJsZVB0cikgeworICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz46OnBvaW50ZXJfaXRlcmF0b3IgaXRlciA9CisgICAgICBwcm90b19hcnJheV8ucG9pbnRlcl9iZWdpbigpOworICBzdGF0aWNfY2FzdDx2b2lkPihpdGVyKTsKK30KKworVEVTVF9GKFJlcGVhdGVkUHRyRmllbGRQdHJzSXRlcmF0b3JUZXN0LCBDb252ZXJ0aWJsZUNvbnN0UHRyKSB7CisgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPjo6Y29uc3RfcG9pbnRlcl9pdGVyYXRvciBpdGVyID0KKyAgICAgIGNvbnN0X3Byb3RvX2FycmF5Xy0+cG9pbnRlcl9iZWdpbigpOworICBzdGF0aWNfY2FzdDx2b2lkPihpdGVyKTsKK30KKworVEVTVF9GKFJlcGVhdGVkUHRyRmllbGRQdHJzSXRlcmF0b3JUZXN0LCBNdXRhYmxlUHRySXRlcmF0aW9uKSB7CisgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPjo6cG9pbnRlcl9pdGVyYXRvciBpdGVyID0KKyAgICAgIHByb3RvX2FycmF5Xy5wb2ludGVyX2JlZ2luKCk7CisgIEVYUEVDVF9FUSgiZm9vIiwgKippdGVyKTsKKyAgKytpdGVyOworICBFWFBFQ1RfRVEoImJhciIsICoqKGl0ZXIrKykpOworICBFWFBFQ1RfRVEoImJheiIsICoqaXRlcik7CisgICsraXRlcjsKKyAgRVhQRUNUX1RSVUUocHJvdG9fYXJyYXlfLnBvaW50ZXJfZW5kKCkgPT0gaXRlcik7CisgIEVYUEVDVF9FUSgiYmF6IiwgKiooLS1wcm90b19hcnJheV8ucG9pbnRlcl9lbmQoKSkpOworfQorCitURVNUX0YoUmVwZWF0ZWRQdHJGaWVsZFB0cnNJdGVyYXRvclRlc3QsIE11dGFibGVDb25zdFB0ckl0ZXJhdGlvbikgeworICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz46OmNvbnN0X3BvaW50ZXJfaXRlcmF0b3IgaXRlciA9CisgICAgICBjb25zdF9wcm90b19hcnJheV8tPnBvaW50ZXJfYmVnaW4oKTsKKyAgRVhQRUNUX0VRKCJmb28iLCAqKml0ZXIpOworICArK2l0ZXI7CisgIEVYUEVDVF9FUSgiYmFyIiwgKiooaXRlcisrKSk7CisgIEVYUEVDVF9FUSgiYmF6IiwgKippdGVyKTsKKyAgKytpdGVyOworICBFWFBFQ1RfVFJVRShjb25zdF9wcm90b19hcnJheV8tPnBvaW50ZXJfZW5kKCkgPT0gaXRlcik7CisgIEVYUEVDVF9FUSgiYmF6IiwgKiooLS1jb25zdF9wcm90b19hcnJheV8tPnBvaW50ZXJfZW5kKCkpKTsKK30KKworVEVTVF9GKFJlcGVhdGVkUHRyRmllbGRQdHJzSXRlcmF0b3JUZXN0LCBSYW5kb21QdHJBY2Nlc3MpIHsKKyAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+Ojpwb2ludGVyX2l0ZXJhdG9yIGl0ZXIgPQorICAgICAgcHJvdG9fYXJyYXlfLnBvaW50ZXJfYmVnaW4oKTsKKyAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+Ojpwb2ludGVyX2l0ZXJhdG9yIGl0ZXIyID0gaXRlcjsKKyAgKytpdGVyMjsKKyAgKytpdGVyMjsKKyAgRVhQRUNUX1RSVUUoaXRlciArIDIgPT0gaXRlcjIpOworICBFWFBFQ1RfVFJVRShpdGVyID09IGl0ZXIyIC0gMik7CisgIEVYUEVDVF9FUSgiYmF6IiwgKml0ZXJbMl0pOworICBFWFBFQ1RfRVEoImJheiIsICoqKGl0ZXIgKyAyKSk7CisgIEVYUEVDVF9FUSgzLCBwcm90b19hcnJheV8uZW5kKCkgLSBwcm90b19hcnJheV8uYmVnaW4oKSk7Cit9CisKK1RFU1RfRihSZXBlYXRlZFB0ckZpZWxkUHRyc0l0ZXJhdG9yVGVzdCwgUmFuZG9tQ29uc3RQdHJBY2Nlc3MpIHsKKyAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+Ojpjb25zdF9wb2ludGVyX2l0ZXJhdG9yIGl0ZXIgPQorICAgICAgY29uc3RfcHJvdG9fYXJyYXlfLT5wb2ludGVyX2JlZ2luKCk7CisgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPjo6Y29uc3RfcG9pbnRlcl9pdGVyYXRvciBpdGVyMiA9IGl0ZXI7CisgICsraXRlcjI7CisgICsraXRlcjI7CisgIEVYUEVDVF9UUlVFKGl0ZXIgKyAyID09IGl0ZXIyKTsKKyAgRVhQRUNUX1RSVUUoaXRlciA9PSBpdGVyMiAtIDIpOworICBFWFBFQ1RfRVEoImJheiIsICppdGVyWzJdKTsKKyAgRVhQRUNUX0VRKCJiYXoiLCAqKihpdGVyICsgMikpOworICBFWFBFQ1RfRVEoMywgY29uc3RfcHJvdG9fYXJyYXlfLT5lbmQoKSAtIGNvbnN0X3Byb3RvX2FycmF5Xy0+YmVnaW4oKSk7Cit9CisKK1RFU1RfRihSZXBlYXRlZFB0ckZpZWxkUHRyc0l0ZXJhdG9yVGVzdCwgQ29tcGFyYWJsZVB0cikgeworICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz46OnBvaW50ZXJfaXRlcmF0b3IgaXRlciA9CisgICAgICBwcm90b19hcnJheV8ucG9pbnRlcl9iZWdpbigpOworICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz46OnBvaW50ZXJfaXRlcmF0b3IgaXRlcjIgPSBpdGVyICsgMTsKKyAgRVhQRUNUX1RSVUUoaXRlciA9PSBpdGVyKTsKKyAgRVhQRUNUX1RSVUUoaXRlciAhPSBpdGVyMik7CisgIEVYUEVDVF9UUlVFKGl0ZXIgPCBpdGVyMik7CisgIEVYUEVDVF9UUlVFKGl0ZXIgPD0gaXRlcjIpOworICBFWFBFQ1RfVFJVRShpdGVyIDw9IGl0ZXIpOworICBFWFBFQ1RfVFJVRShpdGVyMiA+IGl0ZXIpOworICBFWFBFQ1RfVFJVRShpdGVyMiA+PSBpdGVyKTsKKyAgRVhQRUNUX1RSVUUoaXRlciA+PSBpdGVyKTsKK30KKworVEVTVF9GKFJlcGVhdGVkUHRyRmllbGRQdHJzSXRlcmF0b3JUZXN0LCBDb21wYXJhYmxlQ29uc3RQdHIpIHsKKyAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+Ojpjb25zdF9wb2ludGVyX2l0ZXJhdG9yIGl0ZXIgPQorICAgICAgY29uc3RfcHJvdG9fYXJyYXlfLT5wb2ludGVyX2JlZ2luKCk7CisgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPjo6Y29uc3RfcG9pbnRlcl9pdGVyYXRvciBpdGVyMiA9IGl0ZXIgKyAxOworICBFWFBFQ1RfVFJVRShpdGVyID09IGl0ZXIpOworICBFWFBFQ1RfVFJVRShpdGVyICE9IGl0ZXIyKTsKKyAgRVhQRUNUX1RSVUUoaXRlciA8IGl0ZXIyKTsKKyAgRVhQRUNUX1RSVUUoaXRlciA8PSBpdGVyMik7CisgIEVYUEVDVF9UUlVFKGl0ZXIgPD0gaXRlcik7CisgIEVYUEVDVF9UUlVFKGl0ZXIyID4gaXRlcik7CisgIEVYUEVDVF9UUlVFKGl0ZXIyID49IGl0ZXIpOworICBFWFBFQ1RfVFJVRShpdGVyID49IGl0ZXIpOworfQorCisvLyBVbmluaXRpYWxpemVkIGl0ZXJhdG9yIGRvZXMgbm90IHBvaW50IHRvIGFueSBvZiB0aGUgUmVwZWF0ZWRQdHJPdmVyUHRycy4KKy8vIERlcmVmZXJlbmNpbmcgYW4gdW5pbml0aWFsaXplZCBpdGVyYXRvciBjcmFzaGVzIHRoZSBwcm9jZXNzLgorVEVTVF9GKFJlcGVhdGVkUHRyRmllbGRQdHJzSXRlcmF0b3JUZXN0LCBVbmluaXRpYWxpemVkUHRySXRlcmF0b3IpIHsKKyAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+Ojpwb2ludGVyX2l0ZXJhdG9yIGl0ZXI7CisgIEVYUEVDVF9UUlVFKGl0ZXIgIT0gcHJvdG9fYXJyYXlfLnBvaW50ZXJfYmVnaW4oKSk7CisgIEVYUEVDVF9UUlVFKGl0ZXIgIT0gcHJvdG9fYXJyYXlfLnBvaW50ZXJfYmVnaW4oKSArIDEpOworICBFWFBFQ1RfVFJVRShpdGVyICE9IHByb3RvX2FycmF5Xy5wb2ludGVyX2JlZ2luKCkgKyAyKTsKKyAgRVhQRUNUX1RSVUUoaXRlciAhPSBwcm90b19hcnJheV8ucG9pbnRlcl9iZWdpbigpICsgMyk7CisgIEVYUEVDVF9UUlVFKGl0ZXIgIT0gcHJvdG9fYXJyYXlfLnBvaW50ZXJfZW5kKCkpOworfQorCitURVNUX0YoUmVwZWF0ZWRQdHJGaWVsZFB0cnNJdGVyYXRvclRlc3QsIFVuaW5pdGlhbGl6ZWRDb25zdFB0ckl0ZXJhdG9yKSB7CisgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPjo6Y29uc3RfcG9pbnRlcl9pdGVyYXRvciBpdGVyOworICBFWFBFQ1RfVFJVRShpdGVyICE9IGNvbnN0X3Byb3RvX2FycmF5Xy0+cG9pbnRlcl9iZWdpbigpKTsKKyAgRVhQRUNUX1RSVUUoaXRlciAhPSBjb25zdF9wcm90b19hcnJheV8tPnBvaW50ZXJfYmVnaW4oKSArIDEpOworICBFWFBFQ1RfVFJVRShpdGVyICE9IGNvbnN0X3Byb3RvX2FycmF5Xy0+cG9pbnRlcl9iZWdpbigpICsgMik7CisgIEVYUEVDVF9UUlVFKGl0ZXIgIT0gY29uc3RfcHJvdG9fYXJyYXlfLT5wb2ludGVyX2JlZ2luKCkgKyAzKTsKKyAgRVhQRUNUX1RSVUUoaXRlciAhPSBjb25zdF9wcm90b19hcnJheV8tPnBvaW50ZXJfZW5kKCkpOworfQorCisvLyBUaGlzIGNvbXBhcmlzb24gZnVuY3RvciBpcyByZXF1aXJlZCBieSB0aGUgdGVzdHMgZm9yIFJlcGVhdGVkUHRyT3ZlclB0cnMuCisvLyBUaGV5IG9wZXJhdGUgb24gc3RyaW5ncyBhbmQgbmVlZCB0byBjb21wYXJlIHN0cmluZ3MgYXMgc3RyaW5ncyBpbgorLy8gYW55IHN0bCBhbGdvcml0aG0sIGV2ZW4gdGhvdWdoIHRoZSBpdGVyYXRvciByZXR1cm5zIGEgcG9pbnRlciB0byBhIHN0cmluZworLy8gLSBpLmUuICppdGVyIGhhcyB0eXBlIHN0cmluZyouCitzdHJ1Y3QgU3RyaW5nTGVzc1RoYW4geworICBib29sIG9wZXJhdG9yKCkoY29uc3Qgc3RyaW5nKiB6LCBjb25zdCBzdHJpbmcmIHkpIHsKKyAgICByZXR1cm4gKnogPCB5OworICB9CisgIGJvb2wgb3BlcmF0b3IoKShjb25zdCBzdHJpbmcqIHosIGNvbnN0IHN0cmluZyogeSkgY29uc3QgeyByZXR1cm4gKnogPCAqeTsgfQorfTsKKworVEVTVF9GKFJlcGVhdGVkUHRyRmllbGRQdHJzSXRlcmF0b3JUZXN0LCBQdHJTVExBbGdvcml0aG1zX2xvd2VyX2JvdW5kKSB7CisgIHByb3RvX2FycmF5Xy5DbGVhcigpOworICBwcm90b19hcnJheV8uQWRkKCktPmFzc2lnbigiYSIpOworICBwcm90b19hcnJheV8uQWRkKCktPmFzc2lnbigiYyIpOworICBwcm90b19hcnJheV8uQWRkKCktPmFzc2lnbigiZCIpOworICBwcm90b19hcnJheV8uQWRkKCktPmFzc2lnbigibiIpOworICBwcm90b19hcnJheV8uQWRkKCktPmFzc2lnbigicCIpOworICBwcm90b19hcnJheV8uQWRkKCktPmFzc2lnbigieCIpOworICBwcm90b19hcnJheV8uQWRkKCktPmFzc2lnbigieSIpOworCisgIHsKKyAgICBzdHJpbmcgdiA9ICJmIjsKKyAgICBSZXBlYXRlZFB0ckZpZWxkPHN0cmluZz46OnBvaW50ZXJfaXRlcmF0b3IgaXQgPQorICAgICAgICBzdGQ6Omxvd2VyX2JvdW5kKHByb3RvX2FycmF5Xy5wb2ludGVyX2JlZ2luKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdG9fYXJyYXlfLnBvaW50ZXJfZW5kKCksICZ2LCBTdHJpbmdMZXNzVGhhbigpKTsKKworICAgIEdPT0dMRV9DSEVDSygqaXQgIT0gTlVMTCk7CisKKyAgICBFWFBFQ1RfRVEoKippdCwgIm4iKTsKKyAgICBFWFBFQ1RfVFJVRShpdCA9PSBwcm90b19hcnJheV8ucG9pbnRlcl9iZWdpbigpICsgMyk7CisgIH0KKyAgeworICAgIHN0cmluZyB2ID0gImYiOworICAgIFJlcGVhdGVkUHRyRmllbGQ8c3RyaW5nPjo6Y29uc3RfcG9pbnRlcl9pdGVyYXRvciBpdCA9IHN0ZDo6bG93ZXJfYm91bmQoCisgICAgICAgIGNvbnN0X3Byb3RvX2FycmF5Xy0+cG9pbnRlcl9iZWdpbigpLCBjb25zdF9wcm90b19hcnJheV8tPnBvaW50ZXJfZW5kKCksCisgICAgICAgICZ2LCBTdHJpbmdMZXNzVGhhbigpKTsKKworICAgIEdPT0dMRV9DSEVDSygqaXQgIT0gTlVMTCk7CisKKyAgICBFWFBFQ1RfRVEoKippdCwgIm4iKTsKKyAgICBFWFBFQ1RfVFJVRShpdCA9PSBjb25zdF9wcm90b19hcnJheV8tPnBvaW50ZXJfYmVnaW4oKSArIDMpOworICB9Cit9CisKK1RFU1RfRihSZXBlYXRlZFB0ckZpZWxkUHRyc0l0ZXJhdG9yVGVzdCwgUHRyTXV0YXRpb24pIHsKKyAgUmVwZWF0ZWRQdHJGaWVsZDxzdHJpbmc+Ojpwb2ludGVyX2l0ZXJhdG9yIGl0ZXIgPQorICAgICAgcHJvdG9fYXJyYXlfLnBvaW50ZXJfYmVnaW4oKTsKKyAgKippdGVyID0gInF1eCI7CisgIEVYUEVDVF9FUSgicXV4IiwgcHJvdG9fYXJyYXlfLkdldCgwKSk7CisKKyAgRVhQRUNUX0VRKCJiYXIiLCBwcm90b19hcnJheV8uR2V0KDEpKTsKKyAgRVhQRUNUX0VRKCJiYXoiLCBwcm90b19hcnJheV8uR2V0KDIpKTsKKyAgKytpdGVyOworICBkZWxldGUgKml0ZXI7CisgICppdGVyID0gbmV3IHN0cmluZygiYSIpOworICArK2l0ZXI7CisgIGRlbGV0ZSAqaXRlcjsKKyAgKml0ZXIgPSBuZXcgc3RyaW5nKCJiIik7CisgIEVYUEVDVF9FUSgiYSIsIHByb3RvX2FycmF5Xy5HZXQoMSkpOworICBFWFBFQ1RfRVEoImIiLCBwcm90b19hcnJheV8uR2V0KDIpKTsKK30KKworVEVTVF9GKFJlcGVhdGVkUHRyRmllbGRQdHJzSXRlcmF0b3JUZXN0LCBTb3J0KSB7CisgIHByb3RvX2FycmF5Xy5BZGQoKS0+YXNzaWduKCJjIik7CisgIHByb3RvX2FycmF5Xy5BZGQoKS0+YXNzaWduKCJkIik7CisgIHByb3RvX2FycmF5Xy5BZGQoKS0+YXNzaWduKCJuIik7CisgIHByb3RvX2FycmF5Xy5BZGQoKS0+YXNzaWduKCJwIik7CisgIHByb3RvX2FycmF5Xy5BZGQoKS0+YXNzaWduKCJhIik7CisgIHByb3RvX2FycmF5Xy5BZGQoKS0+YXNzaWduKCJ5Iik7CisgIHByb3RvX2FycmF5Xy5BZGQoKS0+YXNzaWduKCJ4Iik7CisgIEVYUEVDVF9FUSgiZm9vIiwgcHJvdG9fYXJyYXlfLkdldCgwKSk7CisgIEVYUEVDVF9FUSgibiIsIHByb3RvX2FycmF5Xy5HZXQoNSkpOworICBFWFBFQ1RfRVEoIngiLCBwcm90b19hcnJheV8uR2V0KDkpKTsKKyAgc3RkOjpzb3J0KHByb3RvX2FycmF5Xy5wb2ludGVyX2JlZ2luKCksIHByb3RvX2FycmF5Xy5wb2ludGVyX2VuZCgpLAorICAgICAgICAgICAgU3RyaW5nTGVzc1RoYW4oKSk7CisgIEVYUEVDVF9FUSgiYSIsIHByb3RvX2FycmF5Xy5HZXQoMCkpOworICBFWFBFQ1RfRVEoImJheiIsIHByb3RvX2FycmF5Xy5HZXQoMikpOworICBFWFBFQ1RfRVEoInkiLCBwcm90b19hcnJheV8uR2V0KDkpKTsKK30KKworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gVW5pdC10ZXN0cyBmb3IgdGhlIGluc2VydCBpdGVyYXRvcnMKKy8vIGdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkRmllbGRCYWNrSW5zZXJ0ZXIsCisvLyBnb29nbGU6OnByb3RvYnVmOjpBbGxvY2F0ZWRSZXBlYXRlZFB0ckZpZWxkQmFja0luc2VydGVyCisvLyBQb3J0ZWQgZnJvbSB1dGlsL2d0bC9wcm90by1hcnJheS1pdGVyYXRvcnNfdW5pdHRlc3QuCisKK2NsYXNzIFJlcGVhdGVkRmllbGRJbnNlcnRpb25JdGVyYXRvcnNUZXN0IDogcHVibGljIHRlc3Rpbmc6OlRlc3QgeworIHByb3RlY3RlZDoKKyAgc3RkOjpsaXN0PGRvdWJsZT4gaGFsdmVzOworICBzdGQ6Omxpc3Q8aW50PiBmaWJvbmFjY2k7CisgIHN0ZDo6dmVjdG9yPHN0cmluZz4gd29yZHM7CisgIHR5cGVkZWYgVGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlIE5lc3RlZDsKKyAgTmVzdGVkIG5lc3RlZHNbMl07CisgIHN0ZDo6dmVjdG9yPE5lc3RlZCo+IG5lc3RlZF9wdHJzOworICBUZXN0QWxsVHlwZXMgcHJvdG9idWZmZXI7CisKKyAgdmlydHVhbCB2b2lkIFNldFVwKCkgeworICAgIGZpYm9uYWNjaS5wdXNoX2JhY2soMSk7CisgICAgZmlib25hY2NpLnB1c2hfYmFjaygxKTsKKyAgICBmaWJvbmFjY2kucHVzaF9iYWNrKDIpOworICAgIGZpYm9uYWNjaS5wdXNoX2JhY2soMyk7CisgICAgZmlib25hY2NpLnB1c2hfYmFjayg1KTsKKyAgICBmaWJvbmFjY2kucHVzaF9iYWNrKDgpOworICAgIHN0ZDo6Y29weShmaWJvbmFjY2kuYmVnaW4oKSwgZmlib25hY2NpLmVuZCgpLAorICAgICAgICAgICAgICBSZXBlYXRlZEZpZWxkQmFja0luc2VydGVyKHByb3RvYnVmZmVyLm11dGFibGVfcmVwZWF0ZWRfaW50MzIoKSkpOworCisgICAgaGFsdmVzLnB1c2hfYmFjaygxLjApOworICAgIGhhbHZlcy5wdXNoX2JhY2soMC41KTsKKyAgICBoYWx2ZXMucHVzaF9iYWNrKDAuMjUpOworICAgIGhhbHZlcy5wdXNoX2JhY2soMC4xMjUpOworICAgIGhhbHZlcy5wdXNoX2JhY2soMC4wNjI1KTsKKyAgICBzdGQ6OmNvcHkoaGFsdmVzLmJlZ2luKCksIGhhbHZlcy5lbmQoKSwKKyAgICAgICAgICAgICAgUmVwZWF0ZWRGaWVsZEJhY2tJbnNlcnRlcihwcm90b2J1ZmZlci5tdXRhYmxlX3JlcGVhdGVkX2RvdWJsZSgpKSk7CisKKyAgICB3b3Jkcy5wdXNoX2JhY2soIkFibGUiKTsKKyAgICB3b3Jkcy5wdXNoX2JhY2soIndhcyIpOworICAgIHdvcmRzLnB1c2hfYmFjaygiSSIpOworICAgIHdvcmRzLnB1c2hfYmFjaygiZXJlIik7CisgICAgd29yZHMucHVzaF9iYWNrKCJJIik7CisgICAgd29yZHMucHVzaF9iYWNrKCJzYXciKTsKKyAgICB3b3Jkcy5wdXNoX2JhY2soIkVsYmEiKTsKKyAgICBzdGQ6OmNvcHkod29yZHMuYmVnaW4oKSwgd29yZHMuZW5kKCksCisgICAgICAgICAgICAgIFJlcGVhdGVkRmllbGRCYWNrSW5zZXJ0ZXIocHJvdG9idWZmZXIubXV0YWJsZV9yZXBlYXRlZF9zdHJpbmcoKSkpOworCisgICAgbmVzdGVkc1swXS5zZXRfYmIoMTcpOworICAgIG5lc3RlZHNbMV0uc2V0X2JiKDQ3MTEpOworICAgIHN0ZDo6Y29weSgmbmVzdGVkc1swXSwgJm5lc3RlZHNbMl0sCisgICAgICAgICAgICAgIFJlcGVhdGVkRmllbGRCYWNrSW5zZXJ0ZXIoCisgICAgICAgICAgICAgICAgICBwcm90b2J1ZmZlci5tdXRhYmxlX3JlcGVhdGVkX25lc3RlZF9tZXNzYWdlKCkpKTsKKworICAgIG5lc3RlZF9wdHJzLnB1c2hfYmFjayhuZXcgTmVzdGVkKTsKKyAgICBuZXN0ZWRfcHRycy5iYWNrKCktPnNldF9iYigxNzApOworICAgIG5lc3RlZF9wdHJzLnB1c2hfYmFjayhuZXcgTmVzdGVkKTsKKyAgICBuZXN0ZWRfcHRycy5iYWNrKCktPnNldF9iYig0NzExMCk7CisgICAgc3RkOjpjb3B5KG5lc3RlZF9wdHJzLmJlZ2luKCksIG5lc3RlZF9wdHJzLmVuZCgpLAorICAgICAgICAgICAgICBSZXBlYXRlZEZpZWxkQmFja0luc2VydGVyKAorICAgICAgICAgICAgICAgICAgcHJvdG9idWZmZXIubXV0YWJsZV9yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSgpKSk7CisgIH0KKworICB2aXJ0dWFsIHZvaWQgVGVhckRvd24oKSB7CisgICAgU1RMRGVsZXRlQ29udGFpbmVyUG9pbnRlcnMobmVzdGVkX3B0cnMuYmVnaW4oKSwgbmVzdGVkX3B0cnMuZW5kKCkpOworICB9Cit9OworCitURVNUX0YoUmVwZWF0ZWRGaWVsZEluc2VydGlvbkl0ZXJhdG9yc1Rlc3QsIEZpYm9uYWNjaSkgeworICBFWFBFQ1RfVFJVRShzdGQ6OmVxdWFsKGZpYm9uYWNjaS5iZWdpbigpLAorICAgICAgICAgICAgICAgICAgICAgICAgIGZpYm9uYWNjaS5lbmQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBwcm90b2J1ZmZlci5yZXBlYXRlZF9pbnQzMigpLmJlZ2luKCkpKTsKKyAgRVhQRUNUX1RSVUUoc3RkOjplcXVhbChwcm90b2J1ZmZlci5yZXBlYXRlZF9pbnQzMigpLmJlZ2luKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZmZXIucmVwZWF0ZWRfaW50MzIoKS5lbmQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBmaWJvbmFjY2kuYmVnaW4oKSkpOworfQorCitURVNUX0YoUmVwZWF0ZWRGaWVsZEluc2VydGlvbkl0ZXJhdG9yc1Rlc3QsIEhhbHZlcykgeworICBFWFBFQ1RfVFJVRShzdGQ6OmVxdWFsKGhhbHZlcy5iZWdpbigpLAorICAgICAgICAgICAgICAgICAgICAgICAgIGhhbHZlcy5lbmQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBwcm90b2J1ZmZlci5yZXBlYXRlZF9kb3VibGUoKS5iZWdpbigpKSk7CisgIEVYUEVDVF9UUlVFKHN0ZDo6ZXF1YWwocHJvdG9idWZmZXIucmVwZWF0ZWRfZG91YmxlKCkuYmVnaW4oKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBwcm90b2J1ZmZlci5yZXBlYXRlZF9kb3VibGUoKS5lbmQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBoYWx2ZXMuYmVnaW4oKSkpOworfQorCitURVNUX0YoUmVwZWF0ZWRGaWVsZEluc2VydGlvbkl0ZXJhdG9yc1Rlc3QsIFdvcmRzKSB7CisgIEFTU0VSVF9FUSh3b3Jkcy5zaXplKCksIHByb3RvYnVmZmVyLnJlcGVhdGVkX3N0cmluZ19zaXplKCkpOworICBmb3IgKGludCBpID0gMDsgaSA8IHdvcmRzLnNpemUoKTsgKytpKQorICAgIEVYUEVDVF9FUSh3b3Jkcy5hdChpKSwgcHJvdG9idWZmZXIucmVwZWF0ZWRfc3RyaW5nKGkpKTsKK30KKworVEVTVF9GKFJlcGVhdGVkRmllbGRJbnNlcnRpb25JdGVyYXRvcnNUZXN0LCBXb3JkczIpIHsKKyAgd29yZHMuY2xlYXIoKTsKKyAgd29yZHMucHVzaF9iYWNrKCJzaW5nIik7CisgIHdvcmRzLnB1c2hfYmFjaygiYSIpOworICB3b3Jkcy5wdXNoX2JhY2soInNvbmciKTsKKyAgd29yZHMucHVzaF9iYWNrKCJvZiIpOworICB3b3Jkcy5wdXNoX2JhY2soInNpeCIpOworICB3b3Jkcy5wdXNoX2JhY2soInBlbmNlIik7CisgIHByb3RvYnVmZmVyLm11dGFibGVfcmVwZWF0ZWRfc3RyaW5nKCktPkNsZWFyKCk7CisgIHN0ZDo6Y29weSh3b3Jkcy5iZWdpbigpLCB3b3Jkcy5lbmQoKSwgUmVwZWF0ZWRQdHJGaWVsZEJhY2tJbnNlcnRlcigKKyAgICAgIHByb3RvYnVmZmVyLm11dGFibGVfcmVwZWF0ZWRfc3RyaW5nKCkpKTsKKyAgQVNTRVJUX0VRKHdvcmRzLnNpemUoKSwgcHJvdG9idWZmZXIucmVwZWF0ZWRfc3RyaW5nX3NpemUoKSk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgd29yZHMuc2l6ZSgpOyArK2kpCisgICAgRVhQRUNUX0VRKHdvcmRzLmF0KGkpLCBwcm90b2J1ZmZlci5yZXBlYXRlZF9zdHJpbmcoaSkpOworfQorCitURVNUX0YoUmVwZWF0ZWRGaWVsZEluc2VydGlvbkl0ZXJhdG9yc1Rlc3QsIE5lc3RlZHMpIHsKKyAgQVNTRVJUX0VRKHByb3RvYnVmZmVyLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX3NpemUoKSwgNCk7CisgIEVYUEVDVF9FUShwcm90b2J1ZmZlci5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSgwKS5iYigpLCAxNyk7CisgIEVYUEVDVF9FUShwcm90b2J1ZmZlci5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSgxKS5iYigpLCA0NzExKTsKKyAgRVhQRUNUX0VRKHByb3RvYnVmZmVyLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlKDIpLmJiKCksIDE3MCk7CisgIEVYUEVDVF9FUShwcm90b2J1ZmZlci5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSgzKS5iYigpLCA0NzExMCk7Cit9CisKK1RFU1RfRihSZXBlYXRlZEZpZWxkSW5zZXJ0aW9uSXRlcmF0b3JzVGVzdCwKKyAgICAgICBBbGxvY2F0ZWRSZXBlYXRlZFB0ckZpZWxkV2l0aFN0cmluZ0ludERhdGEpIHsKKyAgdmVjdG9yPE5lc3RlZCo+IGRhdGE7CisgIFRlc3RBbGxUeXBlcyBnb2xkZW5wcm90bzsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgKytpKSB7CisgICAgTmVzdGVkKiBuZXdfZGF0YSA9IG5ldyBOZXN0ZWQ7CisgICAgbmV3X2RhdGEtPnNldF9iYihpKTsKKyAgICBkYXRhLnB1c2hfYmFjayhuZXdfZGF0YSk7CisKKyAgICBuZXdfZGF0YSA9IGdvbGRlbnByb3RvLmFkZF9yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSgpOworICAgIG5ld19kYXRhLT5zZXRfYmIoaSk7CisgIH0KKyAgVGVzdEFsbFR5cGVzIHRlc3Rwcm90bzsKKyAgc3RkOjpjb3B5KGRhdGEuYmVnaW4oKSwgZGF0YS5lbmQoKSwKKyAgICAgICAgICAgIEFsbG9jYXRlZFJlcGVhdGVkUHRyRmllbGRCYWNrSW5zZXJ0ZXIoCisgICAgICAgICAgICAgICAgdGVzdHByb3RvLm11dGFibGVfcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UoKSkpOworICBFWFBFQ1RfRVEodGVzdHByb3RvLkRlYnVnU3RyaW5nKCksIGdvbGRlbnByb3RvLkRlYnVnU3RyaW5nKCkpOworfQorCitURVNUX0YoUmVwZWF0ZWRGaWVsZEluc2VydGlvbkl0ZXJhdG9yc1Rlc3QsCisgICAgICAgQWxsb2NhdGVkUmVwZWF0ZWRQdHJGaWVsZFdpdGhTdHJpbmcpIHsKKyAgdmVjdG9yPHN0cmluZyo+IGRhdGE7CisgIFRlc3RBbGxUeXBlcyBnb2xkZW5wcm90bzsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgKytpKSB7CisgICAgc3RyaW5nKiBuZXdfZGF0YSA9IG5ldyBzdHJpbmc7CisgICAgKm5ld19kYXRhID0gIm5hbWUtIiArIFNpbXBsZUl0b2EoaSk7CisgICAgZGF0YS5wdXNoX2JhY2sobmV3X2RhdGEpOworCisgICAgbmV3X2RhdGEgPSBnb2xkZW5wcm90by5hZGRfcmVwZWF0ZWRfc3RyaW5nKCk7CisgICAgKm5ld19kYXRhID0gIm5hbWUtIiArIFNpbXBsZUl0b2EoaSk7CisgIH0KKyAgVGVzdEFsbFR5cGVzIHRlc3Rwcm90bzsKKyAgc3RkOjpjb3B5KGRhdGEuYmVnaW4oKSwgZGF0YS5lbmQoKSwgQWxsb2NhdGVkUmVwZWF0ZWRQdHJGaWVsZEJhY2tJbnNlcnRlcigKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlc3Rwcm90by5tdXRhYmxlX3JlcGVhdGVkX3N0cmluZygpKSk7CisgIEVYUEVDVF9FUSh0ZXN0cHJvdG8uRGVidWdTdHJpbmcoKSwgZ29sZGVucHJvdG8uRGVidWdTdHJpbmcoKSk7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvc2VydmljZS5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc2VydmljZS5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mZmE5MTlkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zZXJ2aWNlLmNjCkBAIC0wLDAgKzEsNDYgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zZXJ2aWNlLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworU2VydmljZTo6flNlcnZpY2UoKSB7fQorUnBjQ2hhbm5lbDo6flJwY0NoYW5uZWwoKSB7fQorUnBjQ29udHJvbGxlcjo6flJwY0NvbnRyb2xsZXIoKSB7fQorCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zZXJ2aWNlLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3NlcnZpY2UuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hZDZmOTY4Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zZXJ2aWNlLmgKQEAgLTAsMCArMSwyOTIgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBERVBSRUNBVEVEOiAgVGhpcyBtb2R1bGUgZGVjbGFyZXMgdGhlIGFic3RyYWN0IGludGVyZmFjZXMgdW5kZXJseWluZyBwcm90bzIKKy8vIFJQQyBzZXJ2aWNlcy4gIFRoZXNlIGFyZSBpbnRlbnRlZCB0byBiZSBpbmRlcGVuZGVudCBvZiBhbnkgcGFydGljdWxhciBSUEMKKy8vIGltcGxlbWVudGF0aW9uLCBzbyB0aGF0IHByb3RvMiBzZXJ2aWNlcyBjYW4gYmUgdXNlZCBvbiB0b3Agb2YgYSB2YXJpZXR5CisvLyBvZiBpbXBsZW1lbnRhdGlvbnMuICBTdGFydGluZyB3aXRoIHZlcnNpb24gMi4zLjAsIFJQQyBpbXBsZW1lbnRhdGlvbnMgc2hvdWxkCisvLyBub3QgdHJ5IHRvIGJ1aWxkIG9uIHRoZXNlLCBidXQgc2hvdWxkIGluc3RlYWQgcHJvdmlkZSBjb2RlIGdlbmVyYXRvciBwbHVnaW5zCisvLyB3aGljaCBnZW5lcmF0ZSBjb2RlIHNwZWNpZmljIHRvIHRoZSBwYXJ0aWN1bGFyIFJQQyBpbXBsZW1lbnRhdGlvbi4gIFRoaXMgd2F5CisvLyB0aGUgZ2VuZXJhdGVkIGNvZGUgY2FuIGJlIG1vcmUgYXBwcm9wcmlhdGUgZm9yIHRoZSBpbXBsZW1lbnRhdGlvbiBpbiB1c2UKKy8vIGFuZCBjYW4gYXZvaWQgdW5uZWNlc3NhcnkgbGF5ZXJzIG9mIGluZGlyZWN0aW9uLgorLy8KKy8vCisvLyBXaGVuIHlvdSB1c2UgdGhlIHByb3RvY29sIGNvbXBpbGVyIHRvIGNvbXBpbGUgYSBzZXJ2aWNlIGRlZmluaXRpb24sIGl0CisvLyBnZW5lcmF0ZXMgdHdvIGNsYXNzZXM6ICBBbiBhYnN0cmFjdCBpbnRlcmZhY2UgZm9yIHRoZSBzZXJ2aWNlICh3aXRoCisvLyBtZXRob2RzIG1hdGNoaW5nIHRoZSBzZXJ2aWNlIGRlZmluaXRpb24pIGFuZCBhICJzdHViIiBpbXBsZW1lbnRhdGlvbi4KKy8vIEEgc3R1YiBpcyBqdXN0IGEgdHlwZS1zYWZlIHdyYXBwZXIgYXJvdW5kIGFuIFJwY0NoYW5uZWwgd2hpY2ggZW11bGF0ZXMgYQorLy8gbG9jYWwgaW1wbGVtZW50YXRpb24gb2YgdGhlIHNlcnZpY2UuCisvLworLy8gRm9yIGV4YW1wbGUsIHRoZSBzZXJ2aWNlIGRlZmluaXRpb246CisvLyAgIHNlcnZpY2UgTXlTZXJ2aWNlIHsKKy8vICAgICBycGMgRm9vKE15UmVxdWVzdCkgcmV0dXJucyhNeVJlc3BvbnNlKTsKKy8vICAgfQorLy8gd2lsbCBnZW5lcmF0ZSBhYnN0cmFjdCBpbnRlcmZhY2UgIk15U2VydmljZSIgYW5kIGNsYXNzICJNeVNlcnZpY2U6OlN0dWIiLgorLy8gWW91IGNvdWxkIGltcGxlbWVudCBhIE15U2VydmljZSBhcyBmb2xsb3dzOgorLy8gICBjbGFzcyBNeVNlcnZpY2VJbXBsIDogcHVibGljIE15U2VydmljZSB7CisvLyAgICBwdWJsaWM6CisvLyAgICAgTXlTZXJ2aWNlSW1wbCgpIHt9CisvLyAgICAgfk15U2VydmljZUltcGwoKSB7fQorLy8KKy8vICAgICAvLyBpbXBsZW1lbnRzIE15U2VydmljZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vCisvLyAgICAgdm9pZCBGb28oZ29vZ2xlOjpwcm90b2J1Zjo6UnBjQ29udHJvbGxlciogY29udHJvbGxlciwKKy8vICAgICAgICAgICAgICBjb25zdCBNeVJlcXVlc3QqIHJlcXVlc3QsCisvLyAgICAgICAgICAgICAgTXlSZXNwb25zZSogcmVzcG9uc2UsCisvLyAgICAgICAgICAgICAgQ2xvc3VyZSogZG9uZSkgeworLy8gICAgICAgLy8gLi4uIHJlYWQgcmVxdWVzdCBhbmQgZmlsbCBpbiByZXNwb25zZSAuLi4KKy8vICAgICAgIGRvbmUtPlJ1bigpOworLy8gICAgIH0KKy8vICAgfTsKKy8vIFlvdSB3b3VsZCB0aGVuIHJlZ2lzdGVyIGFuIGluc3RhbmNlIG9mIE15U2VydmljZUltcGwgd2l0aCB5b3VyIFJQQyBzZXJ2ZXIKKy8vIGltcGxlbWVudGF0aW9uLiAgKEhvdyB0byBkbyB0aGF0IGRlcGVuZHMgb24gdGhlIGltcGxlbWVudGF0aW9uLikKKy8vCisvLyBUbyBjYWxsIGEgcmVtb3RlIE15U2VydmljZUltcGwsIGZpcnN0IHlvdSBuZWVkIGFuIFJwY0NoYW5uZWwgY29ubmVjdGVkIHRvIGl0LgorLy8gSG93IHRvIGNvbnN0cnVjdCBhIGNoYW5uZWwgZGVwZW5kcywgYWdhaW4sIG9uIHlvdXIgUlBDIGltcGxlbWVudGF0aW9uLgorLy8gSGVyZSB3ZSB1c2UgYSBoeXBvdGhldGljYWwgIk15UnBjQ2hhbm5lbCIgYXMgYW4gZXhhbXBsZToKKy8vICAgTXlScGNDaGFubmVsIGNoYW5uZWwoInJwYzpob3N0bmFtZToxMjM0L215c2VydmljZSIpOworLy8gICBNeVJwY0NvbnRyb2xsZXIgY29udHJvbGxlcjsKKy8vICAgTXlTZXJ2aWNlSW1wbDo6U3R1YiBzdHViKCZjaGFubmVsKTsKKy8vICAgRm9vUmVxdWVzdCByZXF1ZXN0OworLy8gICBGb29SZXNwb25zZSByZXNwb25zZTsKKy8vCisvLyAgIC8vIC4uLiBmaWxsIGluIHJlcXVlc3QgLi4uCisvLworLy8gICBzdHViLkZvbygmY29udHJvbGxlciwgcmVxdWVzdCwgJnJlc3BvbnNlLCBOZXdDYWxsYmFjayhIYW5kbGVSZXNwb25zZSkpOworLy8KKy8vIE9uIFRocmVhZC1TYWZldHk6CisvLworLy8gRGlmZmVyZW50IFJQQyBpbXBsZW1lbnRhdGlvbnMgbWF5IG1ha2UgZGlmZmVyZW50IGd1YXJhbnRlZXMgYWJvdXQgd2hhdAorLy8gdGhyZWFkcyB0aGV5IG1heSBydW4gY2FsbGJhY2tzIG9uLCBhbmQgd2hhdCB0aHJlYWRzIHRoZSBhcHBsaWNhdGlvbiBpcworLy8gYWxsb3dlZCB0byB1c2UgdG8gY2FsbCB0aGUgUlBDIHN5c3RlbS4gIFBvcnRhYmxlIHNvZnR3YXJlIHNob3VsZCBiZSByZWFkeQorLy8gZm9yIGNhbGxiYWNrcyB0byBiZSBjYWxsZWQgb24gYW55IHRocmVhZCwgYnV0IHNob3VsZCBub3QgdHJ5IHRvIGNhbGwgdGhlCisvLyBSUEMgc3lzdGVtIGZyb20gYW55IHRocmVhZCBleGNlcHQgZm9yIHRoZSBvbmVzIG9uIHdoaWNoIGl0IHJlY2VpdmVkIHRoZQorLy8gY2FsbGJhY2tzLiAgUmVhbGlzdGljYWxseSwgdGhvdWdoLCBzaW1wbGUgc29mdHdhcmUgd2lsbCBwcm9iYWJseSB3YW50IHRvCisvLyB1c2UgYSBzaW5nbGUtdGhyZWFkZWQgUlBDIHN5c3RlbSB3aGlsZSBoaWdoLWVuZCBzb2Z0d2FyZSB3aWxsIHdhbnQgdG8KKy8vIHVzZSBtdWx0aXBsZSB0aHJlYWRzLiAgUlBDIGltcGxlbWVudGF0aW9ucyBzaG91bGQgcHJvdmlkZSBtdWx0aXBsZQorLy8gY2hvaWNlcy4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfU0VSVklDRV9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1NFUlZJQ0VfSF9fCisKKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jYWxsYmFjay5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKKy8vIERlZmluZWQgaW4gdGhpcyBmaWxlLgorY2xhc3MgU2VydmljZTsKK2NsYXNzIFJwY0NvbnRyb2xsZXI7CitjbGFzcyBScGNDaGFubmVsOworCisvLyBEZWZpbmVkIGluIG90aGVyIGZpbGVzLgorY2xhc3MgRGVzY3JpcHRvcjsgICAgICAgICAgICAvLyBkZXNjcmlwdG9yLmgKK2NsYXNzIFNlcnZpY2VEZXNjcmlwdG9yOyAgICAgLy8gZGVzY3JpcHRvci5oCitjbGFzcyBNZXRob2REZXNjcmlwdG9yOyAgICAgIC8vIGRlc2NyaXB0b3IuaAorY2xhc3MgTWVzc2FnZTsgICAgICAgICAgICAgICAvLyBtZXNzYWdlLmgKKworLy8gQWJzdHJhY3QgYmFzZSBpbnRlcmZhY2UgZm9yIHByb3RvY29sLWJ1ZmZlci1iYXNlZCBSUEMgc2VydmljZXMuICBTZXJ2aWNlcworLy8gdGhlbXNlbHZlcyBhcmUgYWJzdHJhY3QgaW50ZXJmYWNlcyAoaW1wbGVtZW50ZWQgZWl0aGVyIGJ5IHNlcnZlcnMgb3IgYXMKKy8vIHN0dWJzKSwgYnV0IHRoZXkgc3ViY2xhc3MgdGhpcyBiYXNlIGludGVyZmFjZS4gIFRoZSBtZXRob2RzIG9mIHRoaXMKKy8vIGludGVyZmFjZSBjYW4gYmUgdXNlZCB0byBjYWxsIHRoZSBtZXRob2RzIG9mIHRoZSBTZXJ2aWNlIHdpdGhvdXQga25vd2luZworLy8gaXRzIGV4YWN0IHR5cGUgYXQgY29tcGlsZSB0aW1lIChhbmFsb2dvdXMgdG8gUmVmbGVjdGlvbikuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgU2VydmljZSB7CisgcHVibGljOgorICBpbmxpbmUgU2VydmljZSgpIHt9CisgIHZpcnR1YWwgflNlcnZpY2UoKTsKKworICAvLyBXaGVuIGNvbnN0cnVjdGluZyBhIHN0dWIsIHlvdSBtYXkgcGFzcyBTVFVCX09XTlNfQ0hBTk5FTCBhcyB0aGUgc2Vjb25kCisgIC8vIHBhcmFtZXRlciB0byB0aGUgY29uc3RydWN0b3IgdG8gdGVsbCBpdCB0byBkZWxldGUgaXRzIFJwY0NoYW5uZWwgd2hlbgorICAvLyBkZXN0cm95ZWQuCisgIGVudW0gQ2hhbm5lbE93bmVyc2hpcCB7CisgICAgU1RVQl9PV05TX0NIQU5ORUwsCisgICAgU1RVQl9ET0VTTlRfT1dOX0NIQU5ORUwKKyAgfTsKKworICAvLyBHZXQgdGhlIFNlcnZpY2VEZXNjcmlwdG9yIGRlc2NyaWJpbmcgdGhpcyBzZXJ2aWNlIGFuZCBpdHMgbWV0aG9kcy4KKyAgdmlydHVhbCBjb25zdCBTZXJ2aWNlRGVzY3JpcHRvciogR2V0RGVzY3JpcHRvcigpID0gMDsKKworICAvLyBDYWxsIGEgbWV0aG9kIG9mIHRoZSBzZXJ2aWNlIHNwZWNpZmllZCBieSBNZXRob2REZXNjcmlwdG9yLiAgVGhpcyBpcworICAvLyBub3JtYWxseSBpbXBsZW1lbnRlZCBhcyBhIHNpbXBsZSBzd2l0Y2goKSB0aGF0IGNhbGxzIHRoZSBzdGFuZGFyZAorICAvLyBkZWZpbml0aW9ucyBvZiB0aGUgc2VydmljZSdzIG1ldGhvZHMuCisgIC8vCisgIC8vIFByZWNvbmRpdGlvbnM6CisgIC8vICogbWV0aG9kLT5zZXJ2aWNlKCkgPT0gR2V0RGVzY3JpcHRvcigpCisgIC8vICogcmVxdWVzdCBhbmQgcmVzcG9uc2UgYXJlIG9mIHRoZSBleGFjdCBzYW1lIGNsYXNzZXMgYXMgdGhlIG9iamVjdHMKKyAgLy8gICByZXR1cm5lZCBieSBHZXRSZXF1ZXN0UHJvdG90eXBlKG1ldGhvZCkgYW5kCisgIC8vICAgR2V0UmVzcG9uc2VQcm90b3R5cGUobWV0aG9kKS4KKyAgLy8gKiBBZnRlciB0aGUgY2FsbCBoYXMgc3RhcnRlZCwgdGhlIHJlcXVlc3QgbXVzdCBub3QgYmUgbW9kaWZpZWQgYW5kIHRoZQorICAvLyAgIHJlc3BvbnNlIG11c3Qgbm90IGJlIGFjY2Vzc2VkIGF0IGFsbCB1bnRpbCAiZG9uZSIgaXMgY2FsbGVkLgorICAvLyAqICJjb250cm9sbGVyIiBpcyBvZiB0aGUgY29ycmVjdCB0eXBlIGZvciB0aGUgUlBDIGltcGxlbWVudGF0aW9uIGJlaW5nCisgIC8vICAgdXNlZCBieSB0aGlzIFNlcnZpY2UuICBGb3Igc3R1YnMsIHRoZSAiY29ycmVjdCB0eXBlIiBkZXBlbmRzIG9uIHRoZQorICAvLyAgIFJwY0NoYW5uZWwgd2hpY2ggdGhlIHN0dWIgaXMgdXNpbmcuICBTZXJ2ZXItc2lkZSBTZXJ2aWNlCisgIC8vICAgaW1wbGVtZW50YXRpb25zIGFyZSBleHBlY3RlZCB0byBhY2NlcHQgd2hhdGV2ZXIgdHlwZSBvZiBScGNDb250cm9sbGVyCisgIC8vICAgdGhlIHNlcnZlci1zaWRlIFJQQyBpbXBsZW1lbnRhdGlvbiB1c2VzLgorICAvLworICAvLyBQb3N0Y29uZGl0aW9uczoKKyAgLy8gKiAiZG9uZSIgd2lsbCBiZSBjYWxsZWQgd2hlbiB0aGUgbWV0aG9kIGlzIGNvbXBsZXRlLiAgVGhpcyBtYXkgYmUKKyAgLy8gICBiZWZvcmUgQ2FsbE1ldGhvZCgpIHJldHVybnMgb3IgaXQgbWF5IGJlIGF0IHNvbWUgcG9pbnQgaW4gdGhlIGZ1dHVyZS4KKyAgLy8gKiBJZiB0aGUgUlBDIHN1Y2NlZWRlZCwgInJlc3BvbnNlIiBjb250YWlucyB0aGUgcmVzcG9uc2UgcmV0dXJuZWQgYnkKKyAgLy8gICB0aGUgc2VydmVyLgorICAvLyAqIElmIHRoZSBSUEMgZmFpbGVkLCAicmVzcG9uc2UiJ3MgY29udGVudHMgYXJlIHVuZGVmaW5lZC4gIFRoZQorICAvLyAgIFJwY0NvbnRyb2xsZXIgY2FuIGJlIHF1ZXJpZWQgdG8gZGV0ZXJtaW5lIGlmIGFuIGVycm9yIG9jY3VycmVkIGFuZAorICAvLyAgIHBvc3NpYmx5IHRvIGdldCBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHRoZSBlcnJvci4KKyAgdmlydHVhbCB2b2lkIENhbGxNZXRob2QoY29uc3QgTWV0aG9kRGVzY3JpcHRvciogbWV0aG9kLAorICAgICAgICAgICAgICAgICAgICAgICAgICBScGNDb250cm9sbGVyKiBjb250cm9sbGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNZXNzYWdlKiByZXF1ZXN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlKiByZXNwb25zZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xvc3VyZSogZG9uZSkgPSAwOworCisgIC8vIENhbGxNZXRob2QoKSByZXF1aXJlcyB0aGF0IHRoZSByZXF1ZXN0IGFuZCByZXNwb25zZSBwYXNzZWQgaW4gYXJlIG9mIGEKKyAgLy8gcGFydGljdWxhciBzdWJjbGFzcyBvZiBNZXNzYWdlLiAgR2V0UmVxdWVzdFByb3RvdHlwZSgpIGFuZAorICAvLyBHZXRSZXNwb25zZVByb3RvdHlwZSgpIGdldCB0aGUgZGVmYXVsdCBpbnN0YW5jZXMgb2YgdGhlc2UgcmVxdWlyZWQgdHlwZXMuCisgIC8vIFlvdSBjYW4gdGhlbiBjYWxsIE1lc3NhZ2U6Ok5ldygpIG9uIHRoZXNlIGluc3RhbmNlcyB0byBjb25zdHJ1Y3QgbXV0YWJsZQorICAvLyBvYmplY3RzIHdoaWNoIHlvdSBjYW4gdGhlbiBwYXNzIHRvIENhbGxNZXRob2QoKS4KKyAgLy8KKyAgLy8gRXhhbXBsZToKKyAgLy8gICBjb25zdCBNZXRob2REZXNjcmlwdG9yKiBtZXRob2QgPQorICAvLyAgICAgc2VydmljZS0+R2V0RGVzY3JpcHRvcigpLT5GaW5kTWV0aG9kQnlOYW1lKCJGb28iKTsKKyAgLy8gICBNZXNzYWdlKiByZXF1ZXN0ICA9IHN0dWItPkdldFJlcXVlc3RQcm90b3R5cGUgKG1ldGhvZCktPk5ldygpOworICAvLyAgIE1lc3NhZ2UqIHJlc3BvbnNlID0gc3R1Yi0+R2V0UmVzcG9uc2VQcm90b3R5cGUobWV0aG9kKS0+TmV3KCk7CisgIC8vICAgcmVxdWVzdC0+UGFyc2VGcm9tU3RyaW5nKGlucHV0KTsKKyAgLy8gICBzZXJ2aWNlLT5DYWxsTWV0aG9kKG1ldGhvZCwgKnJlcXVlc3QsIHJlc3BvbnNlLCBjYWxsYmFjayk7CisgIHZpcnR1YWwgY29uc3QgTWVzc2FnZSYgR2V0UmVxdWVzdFByb3RvdHlwZSgKKyAgICBjb25zdCBNZXRob2REZXNjcmlwdG9yKiBtZXRob2QpIGNvbnN0ID0gMDsKKyAgdmlydHVhbCBjb25zdCBNZXNzYWdlJiBHZXRSZXNwb25zZVByb3RvdHlwZSgKKyAgICBjb25zdCBNZXRob2REZXNjcmlwdG9yKiBtZXRob2QpIGNvbnN0ID0gMDsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhTZXJ2aWNlKTsKK307CisKKy8vIEFuIFJwY0NvbnRyb2xsZXIgbWVkaWF0ZXMgYSBzaW5nbGUgbWV0aG9kIGNhbGwuICBUaGUgcHJpbWFyeSBwdXJwb3NlIG9mCisvLyB0aGUgY29udHJvbGxlciBpcyB0byBwcm92aWRlIGEgd2F5IHRvIG1hbmlwdWxhdGUgc2V0dGluZ3Mgc3BlY2lmaWMgdG8gdGhlCisvLyBSUEMgaW1wbGVtZW50YXRpb24gYW5kIHRvIGZpbmQgb3V0IGFib3V0IFJQQy1sZXZlbCBlcnJvcnMuCisvLworLy8gVGhlIG1ldGhvZHMgcHJvdmlkZWQgYnkgdGhlIFJwY0NvbnRyb2xsZXIgaW50ZXJmYWNlIGFyZSBpbnRlbmRlZCB0byBiZSBhCisvLyAibGVhc3QgY29tbW9uIGRlbm9taW5hdG9yIiBzZXQgb2YgZmVhdHVyZXMgd2hpY2ggd2UgZXhwZWN0IGFsbAorLy8gaW1wbGVtZW50YXRpb25zIHRvIHN1cHBvcnQuICBTcGVjaWZpYyBpbXBsZW1lbnRhdGlvbnMgbWF5IHByb3ZpZGUgbW9yZQorLy8gYWR2YW5jZWQgZmVhdHVyZXMgKGUuZy4gZGVhZGxpbmUgcHJvcGFnYXRpb24pLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFJwY0NvbnRyb2xsZXIgeworIHB1YmxpYzoKKyAgaW5saW5lIFJwY0NvbnRyb2xsZXIoKSB7fQorICB2aXJ0dWFsIH5ScGNDb250cm9sbGVyKCk7CisKKyAgLy8gQ2xpZW50LXNpZGUgbWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgLy8gVGhlc2UgY2FsbHMgbWF5IGJlIG1hZGUgZnJvbSB0aGUgY2xpZW50IHNpZGUgb25seS4gIFRoZWlyIHJlc3VsdHMKKyAgLy8gYXJlIHVuZGVmaW5lZCBvbiB0aGUgc2VydmVyIHNpZGUgKG1heSBjcmFzaCkuCisKKyAgLy8gUmVzZXRzIHRoZSBScGNDb250cm9sbGVyIHRvIGl0cyBpbml0aWFsIHN0YXRlIHNvIHRoYXQgaXQgbWF5IGJlIHJldXNlZCBpbgorICAvLyBhIG5ldyBjYWxsLiAgTXVzdCBub3QgYmUgY2FsbGVkIHdoaWxlIGFuIFJQQyBpcyBpbiBwcm9ncmVzcy4KKyAgdmlydHVhbCB2b2lkIFJlc2V0KCkgPSAwOworCisgIC8vIEFmdGVyIGEgY2FsbCBoYXMgZmluaXNoZWQsIHJldHVybnMgdHJ1ZSBpZiB0aGUgY2FsbCBmYWlsZWQuICBUaGUgcG9zc2libGUKKyAgLy8gcmVhc29ucyBmb3IgZmFpbHVyZSBkZXBlbmQgb24gdGhlIFJQQyBpbXBsZW1lbnRhdGlvbi4gIEZhaWxlZCgpIG11c3Qgbm90CisgIC8vIGJlIGNhbGxlZCBiZWZvcmUgYSBjYWxsIGhhcyBmaW5pc2hlZC4gIElmIEZhaWxlZCgpIHJldHVybnMgdHJ1ZSwgdGhlCisgIC8vIGNvbnRlbnRzIG9mIHRoZSByZXNwb25zZSBtZXNzYWdlIGFyZSB1bmRlZmluZWQuCisgIHZpcnR1YWwgYm9vbCBGYWlsZWQoKSBjb25zdCA9IDA7CisKKyAgLy8gSWYgRmFpbGVkKCkgaXMgdHJ1ZSwgcmV0dXJucyBhIGh1bWFuLXJlYWRhYmxlIGRlc2NyaXB0aW9uIG9mIHRoZSBlcnJvci4KKyAgdmlydHVhbCBzdHJpbmcgRXJyb3JUZXh0KCkgY29uc3QgPSAwOworCisgIC8vIEFkdmlzZXMgdGhlIFJQQyBzeXN0ZW0gdGhhdCB0aGUgY2FsbGVyIGRlc2lyZXMgdGhhdCB0aGUgUlBDIGNhbGwgYmUKKyAgLy8gY2FuY2VsZWQuICBUaGUgUlBDIHN5c3RlbSBtYXkgY2FuY2VsIGl0IGltbWVkaWF0ZWx5LCBtYXkgd2FpdCBhd2hpbGUgYW5kCisgIC8vIHRoZW4gY2FuY2VsIGl0LCBvciBtYXkgbm90IGV2ZW4gY2FuY2VsIHRoZSBjYWxsIGF0IGFsbC4gIElmIHRoZSBjYWxsIGlzCisgIC8vIGNhbmNlbGVkLCB0aGUgImRvbmUiIGNhbGxiYWNrIHdpbGwgc3RpbGwgYmUgY2FsbGVkIGFuZCB0aGUgUnBjQ29udHJvbGxlcgorICAvLyB3aWxsIGluZGljYXRlIHRoYXQgdGhlIGNhbGwgZmFpbGVkIGF0IHRoYXQgdGltZS4KKyAgdmlydHVhbCB2b2lkIFN0YXJ0Q2FuY2VsKCkgPSAwOworCisgIC8vIFNlcnZlci1zaWRlIG1ldGhvZHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8vIFRoZXNlIGNhbGxzIG1heSBiZSBtYWRlIGZyb20gdGhlIHNlcnZlciBzaWRlIG9ubHkuICBUaGVpciByZXN1bHRzCisgIC8vIGFyZSB1bmRlZmluZWQgb24gdGhlIGNsaWVudCBzaWRlIChtYXkgY3Jhc2gpLgorCisgIC8vIENhdXNlcyBGYWlsZWQoKSB0byByZXR1cm4gdHJ1ZSBvbiB0aGUgY2xpZW50IHNpZGUuICAicmVhc29uIiB3aWxsIGJlCisgIC8vIGluY29ycG9yYXRlZCBpbnRvIHRoZSBtZXNzYWdlIHJldHVybmVkIGJ5IEVycm9yVGV4dCgpLiAgSWYgeW91IGZpbmQKKyAgLy8geW91IG5lZWQgdG8gcmV0dXJuIG1hY2hpbmUtcmVhZGFibGUgaW5mb3JtYXRpb24gYWJvdXQgZmFpbHVyZXMsIHlvdQorICAvLyBzaG91bGQgaW5jb3Jwb3JhdGUgaXQgaW50byB5b3VyIHJlc3BvbnNlIHByb3RvY29sIGJ1ZmZlciBhbmQgc2hvdWxkCisgIC8vIE5PVCBjYWxsIFNldEZhaWxlZCgpLgorICB2aXJ0dWFsIHZvaWQgU2V0RmFpbGVkKGNvbnN0IHN0cmluZyYgcmVhc29uKSA9IDA7CisKKyAgLy8gSWYgdHJ1ZSwgaW5kaWNhdGVzIHRoYXQgdGhlIGNsaWVudCBjYW5jZWxlZCB0aGUgUlBDLCBzbyB0aGUgc2VydmVyIG1heQorICAvLyBhcyB3ZWxsIGdpdmUgdXAgb24gcmVwbHlpbmcgdG8gaXQuICBUaGUgc2VydmVyIHNob3VsZCBzdGlsbCBjYWxsIHRoZQorICAvLyBmaW5hbCAiZG9uZSIgY2FsbGJhY2suCisgIHZpcnR1YWwgYm9vbCBJc0NhbmNlbGVkKCkgY29uc3QgPSAwOworCisgIC8vIEFza3MgdGhhdCB0aGUgZ2l2ZW4gY2FsbGJhY2sgYmUgY2FsbGVkIHdoZW4gdGhlIFJQQyBpcyBjYW5jZWxlZC4gIFRoZQorICAvLyBjYWxsYmFjayB3aWxsIGFsd2F5cyBiZSBjYWxsZWQgZXhhY3RseSBvbmNlLiAgSWYgdGhlIFJQQyBjb21wbGV0ZXMgd2l0aG91dAorICAvLyBiZWluZyBjYW5jZWxlZCwgdGhlIGNhbGxiYWNrIHdpbGwgYmUgY2FsbGVkIGFmdGVyIGNvbXBsZXRpb24uICBJZiB0aGUgUlBDCisgIC8vIGhhcyBhbHJlYWR5IGJlZW4gY2FuY2VsZWQgd2hlbiBOb3RpZnlPbkNhbmNlbCgpIGlzIGNhbGxlZCwgdGhlIGNhbGxiYWNrCisgIC8vIHdpbGwgYmUgY2FsbGVkIGltbWVkaWF0ZWx5LgorICAvLworICAvLyBOb3RpZnlPbkNhbmNlbCgpIG11c3QgYmUgY2FsbGVkIG5vIG1vcmUgdGhhbiBvbmNlIHBlciByZXF1ZXN0LgorICB2aXJ0dWFsIHZvaWQgTm90aWZ5T25DYW5jZWwoQ2xvc3VyZSogY2FsbGJhY2spID0gMDsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhScGNDb250cm9sbGVyKTsKK307CisKKy8vIEFic3RyYWN0IGludGVyZmFjZSBmb3IgYW4gUlBDIGNoYW5uZWwuICBBbiBScGNDaGFubmVsIHJlcHJlc2VudHMgYQorLy8gY29tbXVuaWNhdGlvbiBsaW5lIHRvIGEgU2VydmljZSB3aGljaCBjYW4gYmUgdXNlZCB0byBjYWxsIHRoYXQgU2VydmljZSdzCisvLyBtZXRob2RzLiAgVGhlIFNlcnZpY2UgbWF5IGJlIHJ1bm5pbmcgb24gYW5vdGhlciBtYWNoaW5lLiAgTm9ybWFsbHksIHlvdQorLy8gc2hvdWxkIG5vdCBjYWxsIGFuIFJwY0NoYW5uZWwgZGlyZWN0bHksIGJ1dCBpbnN0ZWFkIGNvbnN0cnVjdCBhIHN0dWIgU2VydmljZQorLy8gd3JhcHBpbmcgaXQuICBFeGFtcGxlOgorLy8gICBScGNDaGFubmVsKiBjaGFubmVsID0gbmV3IE15UnBjQ2hhbm5lbCgicmVtb3RlaG9zdC5leGFtcGxlLmNvbToxMjM0Iik7CisvLyAgIE15U2VydmljZSogc2VydmljZSA9IG5ldyBNeVNlcnZpY2U6OlN0dWIoY2hhbm5lbCk7CisvLyAgIHNlcnZpY2UtPk15TWV0aG9kKHJlcXVlc3QsICZyZXNwb25zZSwgY2FsbGJhY2spOworY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFJwY0NoYW5uZWwgeworIHB1YmxpYzoKKyAgaW5saW5lIFJwY0NoYW5uZWwoKSB7fQorICB2aXJ0dWFsIH5ScGNDaGFubmVsKCk7CisKKyAgLy8gQ2FsbCB0aGUgZ2l2ZW4gbWV0aG9kIG9mIHRoZSByZW1vdGUgc2VydmljZS4gIFRoZSBzaWduYXR1cmUgb2YgdGhpcworICAvLyBwcm9jZWR1cmUgbG9va3MgdGhlIHNhbWUgYXMgU2VydmljZTo6Q2FsbE1ldGhvZCgpLCBidXQgdGhlIHJlcXVpcmVtZW50cworICAvLyBhcmUgbGVzcyBzdHJpY3QgaW4gb25lIGltcG9ydGFudCB3YXk6ICB0aGUgcmVxdWVzdCBhbmQgcmVzcG9uc2Ugb2JqZWN0cworICAvLyBuZWVkIG5vdCBiZSBvZiBhbnkgc3BlY2lmaWMgY2xhc3MgYXMgbG9uZyBhcyB0aGVpciBkZXNjcmlwdG9ycyBhcmUKKyAgLy8gbWV0aG9kLT5pbnB1dF90eXBlKCkgYW5kIG1ldGhvZC0+b3V0cHV0X3R5cGUoKS4KKyAgdmlydHVhbCB2b2lkIENhbGxNZXRob2QoY29uc3QgTWV0aG9kRGVzY3JpcHRvciogbWV0aG9kLAorICAgICAgICAgICAgICAgICAgICAgICAgICBScGNDb250cm9sbGVyKiBjb250cm9sbGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNZXNzYWdlKiByZXF1ZXN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlKiByZXNwb25zZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xvc3VyZSogZG9uZSkgPSAwOworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFJwY0NoYW5uZWwpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX1NFUlZJQ0VfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3NvdXJjZV9jb250ZXh0LnBiLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zb3VyY2VfY29udGV4dC5wYi5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMmViN2FlCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zb3VyY2VfY29udGV4dC5wYi5jYwpAQCAtMCwwICsxLDM4OCBAQAorLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCEKKy8vIHNvdXJjZTogZ29vZ2xlL3Byb3RvYnVmL3NvdXJjZV9jb250ZXh0LnByb3RvCisKKyNkZWZpbmUgSU5URVJOQUxfU1VQUFJFU1NfUFJPVE9CVUZfRklFTERfREVQUkVDQVRJT04KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc291cmNlX2NvbnRleHQucGIuaD4KKworI2luY2x1ZGUgPGFsZ29yaXRobT4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvcG9ydC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9vbmNlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdF9saXRlX2lubC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9tZXNzYWdlX3JlZmxlY3Rpb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcmVmbGVjdGlvbl9vcHMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuaD4KKy8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbmNsdWRlcykKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCituYW1lc3BhY2UgeworCitjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIFNvdXJjZUNvbnRleHRfZGVzY3JpcHRvcl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24qCisgIFNvdXJjZUNvbnRleHRfcmVmbGVjdGlvbl8gPSBOVUxMOworCit9ICAvLyBuYW1lc3BhY2UKKworCit2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZzb3VyY2VfNWZjb250ZXh0XzJlcHJvdG8oKSB7CisgIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZzb3VyY2VfNWZjb250ZXh0XzJlcHJvdG8oKTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlRGVzY3JpcHRvciogZmlsZSA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUG9vbDo6Z2VuZXJhdGVkX3Bvb2woKS0+RmluZEZpbGVCeU5hbWUoCisgICAgICAiZ29vZ2xlL3Byb3RvYnVmL3NvdXJjZV9jb250ZXh0LnByb3RvIik7CisgIEdPT0dMRV9DSEVDSyhmaWxlICE9IE5VTEwpOworICBTb3VyY2VDb250ZXh0X2Rlc2NyaXB0b3JfID0gZmlsZS0+bWVzc2FnZV90eXBlKDApOworICBzdGF0aWMgY29uc3QgaW50IFNvdXJjZUNvbnRleHRfb2Zmc2V0c19bMV0gPSB7CisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChTb3VyY2VDb250ZXh0LCBmaWxlX25hbWVfKSwKKyAgfTsKKyAgU291cmNlQ29udGV4dF9yZWZsZWN0aW9uXyA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok5ld0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKAorICAgICAgU291cmNlQ29udGV4dF9kZXNjcmlwdG9yXywKKyAgICAgIFNvdXJjZUNvbnRleHQ6OmRlZmF1bHRfaW5zdGFuY2VfLAorICAgICAgU291cmNlQ29udGV4dF9vZmZzZXRzXywKKyAgICAgIC0xLAorICAgICAgLTEsCisgICAgICAtMSwKKyAgICAgIHNpemVvZihTb3VyY2VDb250ZXh0KSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoU291cmNlQ29udGV4dCwgX2ludGVybmFsX21ldGFkYXRhXyksCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKFNvdXJjZUNvbnRleHQsIF9pc19kZWZhdWx0X2luc3RhbmNlXykpOworfQorCituYW1lc3BhY2UgeworCitHT09HTEVfUFJPVE9CVUZfREVDTEFSRV9PTkNFKHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzX29uY2VfKTsKK2lubGluZSB2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpIHsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpHb29nbGVPbmNlSW5pdCgmcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNfb25jZV8sCisgICAgICAgICAgICAgICAgICZwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmc291cmNlXzVmY29udGV4dF8yZXByb3RvKTsKK30KKwordm9pZCBwcm90b2J1Zl9SZWdpc3RlclR5cGVzKGNvbnN0IDo6c3RkOjpzdHJpbmcmKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VGYWN0b3J5OjpJbnRlcm5hbFJlZ2lzdGVyR2VuZXJhdGVkTWVzc2FnZSgKKyAgICAgIFNvdXJjZUNvbnRleHRfZGVzY3JpcHRvcl8sICZTb3VyY2VDb250ZXh0OjpkZWZhdWx0X2luc3RhbmNlKCkpOworfQorCit9ICAvLyBuYW1lc3BhY2UKKwordm9pZCBwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZzb3VyY2VfNWZjb250ZXh0XzJlcHJvdG8oKSB7CisgIGRlbGV0ZSBTb3VyY2VDb250ZXh0OjpkZWZhdWx0X2luc3RhbmNlXzsKKyAgZGVsZXRlIFNvdXJjZUNvbnRleHRfcmVmbGVjdGlvbl87Cit9CisKK3ZvaWQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZnNvdXJjZV81ZmNvbnRleHRfMmVwcm90bygpIHsKKyAgc3RhdGljIGJvb2wgYWxyZWFkeV9oZXJlID0gZmFsc2U7CisgIGlmIChhbHJlYWR5X2hlcmUpIHJldHVybjsKKyAgYWxyZWFkeV9oZXJlID0gdHJ1ZTsKKyAgR09PR0xFX1BST1RPQlVGX1ZFUklGWV9WRVJTSU9OOworCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclBvb2w6OkludGVybmFsQWRkR2VuZXJhdGVkRmlsZSgKKyAgICAiXG4kZ29vZ2xlL3Byb3RvYnVmL3NvdXJjZV9jb250ZXh0LnByb3RvXDAyMlwwMTciCisgICAgImdvb2dsZS5wcm90b2J1ZlwiXCJcblxyU291cmNlQ29udGV4dFwwMjJcMDIxXG5cdGZpbGUiCisgICAgIl9uYW1lXDAzMFwwMDEgXDAwMShcdEJVXG5cMDIzY29tLmdvb2dsZS5wcm90b2J1ZkJcMDIyU291ciIKKyAgICAiY2VDb250ZXh0UHJvdG9QXDAwMVwyNDBcMDAxXDAwMVwyNDJcMDAyXDAwM0dQQlwyNTJcMDAyXDAzNkdvb2dsZS5Qcm90byIKKyAgICAiYnVmLldlbGxLbm93blR5cGVzYlwwMDZwcm90bzMiLCAxODYpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VGYWN0b3J5OjpJbnRlcm5hbFJlZ2lzdGVyR2VuZXJhdGVkRmlsZSgKKyAgICAiZ29vZ2xlL3Byb3RvYnVmL3NvdXJjZV9jb250ZXh0LnByb3RvIiwgJnByb3RvYnVmX1JlZ2lzdGVyVHlwZXMpOworICBTb3VyY2VDb250ZXh0OjpkZWZhdWx0X2luc3RhbmNlXyA9IG5ldyBTb3VyY2VDb250ZXh0KCk7CisgIFNvdXJjZUNvbnRleHQ6OmRlZmF1bHRfaW5zdGFuY2VfLT5Jbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6T25TaHV0ZG93bigmcHJvdG9idWZfU2h1dGRvd25GaWxlX2dvb2dsZV8yZnByb3RvYnVmXzJmc291cmNlXzVmY29udGV4dF8yZXByb3RvKTsKK30KKworLy8gRm9yY2UgQWRkRGVzY3JpcHRvcnMoKSB0byBiZSBjYWxsZWQgYXQgc3RhdGljIGluaXRpYWxpemF0aW9uIHRpbWUuCitzdHJ1Y3QgU3RhdGljRGVzY3JpcHRvckluaXRpYWxpemVyX2dvb2dsZV8yZnByb3RvYnVmXzJmc291cmNlXzVmY29udGV4dF8yZXByb3RvIHsKKyAgU3RhdGljRGVzY3JpcHRvckluaXRpYWxpemVyX2dvb2dsZV8yZnByb3RvYnVmXzJmc291cmNlXzVmY29udGV4dF8yZXByb3RvKCkgeworICAgIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZzb3VyY2VfNWZjb250ZXh0XzJlcHJvdG8oKTsKKyAgfQorfSBzdGF0aWNfZGVzY3JpcHRvcl9pbml0aWFsaXplcl9nb29nbGVfMmZwcm90b2J1Zl8yZnNvdXJjZV81ZmNvbnRleHRfMmVwcm90b187CisKK25hbWVzcGFjZSB7CisKK3N0YXRpYyB2b2lkIE1lcmdlRnJvbUZhaWwoaW50IGxpbmUpIEdPT0dMRV9BVFRSSUJVVEVfQ09MRDsKK3N0YXRpYyB2b2lkIE1lcmdlRnJvbUZhaWwoaW50IGxpbmUpIHsKKyAgR09PR0xFX0NIRUNLKGZhbHNlKSA8PCBfX0ZJTEVfXyA8PCAiOiIgPDwgbGluZTsKK30KKworfSAgLy8gbmFtZXNwYWNlCisKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisjaWYgIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKK2NvbnN0IGludCBTb3VyY2VDb250ZXh0OjprRmlsZU5hbWVGaWVsZE51bWJlcjsKKyNlbmRpZiAgLy8gIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKKworU291cmNlQ29udGV4dDo6U291cmNlQ29udGV4dCgpCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgeworICBTaGFyZWRDdG9yKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCkKK30KKwordm9pZCBTb3VyY2VDb250ZXh0OjpJbml0QXNEZWZhdWx0SW5zdGFuY2UoKSB7CisgIF9pc19kZWZhdWx0X2luc3RhbmNlXyA9IHRydWU7Cit9CisKK1NvdXJjZUNvbnRleHQ6OlNvdXJjZUNvbnRleHQoY29uc3QgU291cmNlQ29udGV4dCYgZnJvbSkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwKKyAgICBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICBNZXJnZUZyb20oZnJvbSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb3B5X2NvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0KQorfQorCit2b2lkIFNvdXJjZUNvbnRleHQ6OlNoYXJlZEN0b3IoKSB7CisgICAgX2lzX2RlZmF1bHRfaW5zdGFuY2VfID0gZmFsc2U7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSAwOworICBmaWxlX25hbWVfLlVuc2FmZVNldERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKworU291cmNlQ29udGV4dDo6flNvdXJjZUNvbnRleHQoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChkZXN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0KQorICBTaGFyZWREdG9yKCk7Cit9CisKK3ZvaWQgU291cmNlQ29udGV4dDo6U2hhcmVkRHRvcigpIHsKKyAgZmlsZV9uYW1lXy5EZXN0cm95Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBpZiAodGhpcyAhPSBkZWZhdWx0X2luc3RhbmNlXykgeworICB9Cit9CisKK3ZvaWQgU291cmNlQ29udGV4dDo6U2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3QgeworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIFNvdXJjZUNvbnRleHQ6OmRlc2NyaXB0b3IoKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICByZXR1cm4gU291cmNlQ29udGV4dF9kZXNjcmlwdG9yXzsKK30KKworY29uc3QgU291cmNlQ29udGV4dCYgU291cmNlQ29udGV4dDo6ZGVmYXVsdF9pbnN0YW5jZSgpIHsKKyAgaWYgKGRlZmF1bHRfaW5zdGFuY2VfID09IE5VTEwpIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZzb3VyY2VfNWZjb250ZXh0XzJlcHJvdG8oKTsKKyAgcmV0dXJuICpkZWZhdWx0X2luc3RhbmNlXzsKK30KKworU291cmNlQ29udGV4dCogU291cmNlQ29udGV4dDo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBOVUxMOworCitTb3VyY2VDb250ZXh0KiBTb3VyY2VDb250ZXh0OjpOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0IHsKKyAgU291cmNlQ29udGV4dCogbiA9IG5ldyBTb3VyY2VDb250ZXh0OworICBpZiAoYXJlbmEgIT0gTlVMTCkgeworICAgIGFyZW5hLT5Pd24obik7CisgIH0KKyAgcmV0dXJuIG47Cit9CisKK3ZvaWQgU291cmNlQ29udGV4dDo6Q2xlYXIoKSB7CisgIGZpbGVfbmFtZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorCitib29sIFNvdXJjZUNvbnRleHQ6Ok1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCkgeworI2RlZmluZSBET18oRVhQUkVTU0lPTikgaWYgKCEoRVhQUkVTU0lPTikpIGdvdG8gZmFpbHVyZQorICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiB0YWc7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdGFydDpnb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCkKKyAgZm9yICg7OykgeworICAgIDo6c3RkOjpwYWlyPCA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiwgYm9vbD4gcCA9IGlucHV0LT5SZWFkVGFnV2l0aEN1dG9mZigxMjcpOworICAgIHRhZyA9IHAuZmlyc3Q7CisgICAgaWYgKCFwLnNlY29uZCkgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICBzd2l0Y2ggKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdGaWVsZE51bWJlcih0YWcpKSB7CisgICAgICAvLyBvcHRpb25hbCBzdHJpbmcgZmlsZV9uYW1lID0gMTsKKyAgICAgIGNhc2UgMTogeworICAgICAgICBpZiAodGFnID09IDEwKSB7CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkU3RyaW5nKAorICAgICAgICAgICAgICAgIGlucHV0LCB0aGlzLT5tdXRhYmxlX2ZpbGVfbmFtZSgpKSk7CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpWZXJpZnlVdGY4U3RyaW5nKAorICAgICAgICAgICAgdGhpcy0+ZmlsZV9uYW1lKCkuZGF0YSgpLCB0aGlzLT5maWxlX25hbWUoKS5sZW5ndGgoKSwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpQQVJTRSwKKyAgICAgICAgICAgICJnb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dC5maWxlX25hbWUiKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdEF0RW5kKCkpIGdvdG8gc3VjY2VzczsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGRlZmF1bHQ6IHsKKyAgICAgIGhhbmRsZV91bnVzdWFsOgorICAgICAgICBpZiAodGFnID09IDAgfHwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdXaXJlVHlwZSh0YWcpID09CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRU5EX0dST1VQKSB7CisgICAgICAgICAgZ290byBzdWNjZXNzOworICAgICAgICB9CisgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U2tpcEZpZWxkKGlucHV0LCB0YWcpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CitzdWNjZXNzOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3VjY2Vzczpnb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCkKKyAgcmV0dXJuIHRydWU7CitmYWlsdXJlOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2VfZmFpbHVyZTpnb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCkKKyAgcmV0dXJuIGZhbHNlOworI3VuZGVmIERPXworfQorCit2b2lkIFNvdXJjZUNvbnRleHQ6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQpCisgIC8vIG9wdGlvbmFsIHN0cmluZyBmaWxlX25hbWUgPSAxOworICBpZiAodGhpcy0+ZmlsZV9uYW1lKCkuc2l6ZSgpID4gMCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpWZXJpZnlVdGY4U3RyaW5nKAorICAgICAgdGhpcy0+ZmlsZV9uYW1lKCkuZGF0YSgpLCB0aGlzLT5maWxlX25hbWUoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQuZmlsZV9uYW1lIik7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nTWF5YmVBbGlhc2VkKAorICAgICAgMSwgdGhpcy0+ZmlsZV9uYW1lKCksIG91dHB1dCk7CisgIH0KKworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX2VuZDpnb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCkKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogU291cmNlQ29udGV4dDo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiB0YXJnZXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9zdGFydDpnb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCkKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIGZpbGVfbmFtZSA9IDE7CisgIGlmICh0aGlzLT5maWxlX25hbWUoKS5zaXplKCkgPiAwKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlZlcmlmeVV0ZjhTdHJpbmcoCisgICAgICB0aGlzLT5maWxlX25hbWUoKS5kYXRhKCksIHRoaXMtPmZpbGVfbmFtZSgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dC5maWxlX25hbWUiKTsKKyAgICB0YXJnZXQgPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nVG9BcnJheSgKKyAgICAgICAgMSwgdGhpcy0+ZmlsZV9uYW1lKCksIHRhcmdldCk7CisgIH0KKworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X2VuZDpnb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCkKKyAgcmV0dXJuIHRhcmdldDsKK30KKworaW50IFNvdXJjZUNvbnRleHQ6OkJ5dGVTaXplKCkgY29uc3QgeworICBpbnQgdG90YWxfc2l6ZSA9IDA7CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIGZpbGVfbmFtZSA9IDE7CisgIGlmICh0aGlzLT5maWxlX25hbWUoKS5zaXplKCkgPiAwKSB7CisgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTdHJpbmdTaXplKAorICAgICAgICB0aGlzLT5maWxlX25hbWUoKSk7CisgIH0KKworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gdG90YWxfc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7CisgIHJldHVybiB0b3RhbF9zaXplOworfQorCit2b2lkIFNvdXJjZUNvbnRleHQ6Ok1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgY29uc3QgU291cmNlQ29udGV4dCogc291cmNlID0gCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpEeW5hbWljQ2FzdFRvR2VuZXJhdGVkPGNvbnN0IFNvdXJjZUNvbnRleHQ+KAorICAgICAgICAgICZmcm9tKTsKKyAgaWYgKHNvdXJjZSA9PSBOVUxMKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6UmVmbGVjdGlvbk9wczo6TWVyZ2UoZnJvbSwgdGhpcyk7CisgIH0gZWxzZSB7CisgICAgTWVyZ2VGcm9tKCpzb3VyY2UpOworICB9Cit9CisKK3ZvaWQgU291cmNlQ29udGV4dDo6TWVyZ2VGcm9tKGNvbnN0IFNvdXJjZUNvbnRleHQmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgaWYgKGZyb20uZmlsZV9uYW1lKCkuc2l6ZSgpID4gMCkgeworCisgICAgZmlsZV9uYW1lXy5Bc3NpZ25XaXRoRGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGZyb20uZmlsZV9uYW1lXyk7CisgIH0KK30KKwordm9pZCBTb3VyY2VDb250ZXh0OjpDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCit2b2lkIFNvdXJjZUNvbnRleHQ6OkNvcHlGcm9tKGNvbnN0IFNvdXJjZUNvbnRleHQmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCitib29sIFNvdXJjZUNvbnRleHQ6OklzSW5pdGlhbGl6ZWQoKSBjb25zdCB7CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgU291cmNlQ29udGV4dDo6U3dhcChTb3VyY2VDb250ZXh0KiBvdGhlcikgeworICBpZiAob3RoZXIgPT0gdGhpcykgcmV0dXJuOworICBJbnRlcm5hbFN3YXAob3RoZXIpOworfQordm9pZCBTb3VyY2VDb250ZXh0OjpJbnRlcm5hbFN3YXAoU291cmNlQ29udGV4dCogb3RoZXIpIHsKKyAgZmlsZV9uYW1lXy5Td2FwKCZvdGhlci0+ZmlsZV9uYW1lXyk7CisgIF9pbnRlcm5hbF9tZXRhZGF0YV8uU3dhcCgmb3RoZXItPl9pbnRlcm5hbF9tZXRhZGF0YV8pOworICBzdGQ6OnN3YXAoX2NhY2hlZF9zaXplXywgb3RoZXItPl9jYWNoZWRfc2l6ZV8pOworfQorCis6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIFNvdXJjZUNvbnRleHQ6OkdldE1ldGFkYXRhKCkgY29uc3QgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBtZXRhZGF0YTsKKyAgbWV0YWRhdGEuZGVzY3JpcHRvciA9IFNvdXJjZUNvbnRleHRfZGVzY3JpcHRvcl87CisgIG1ldGFkYXRhLnJlZmxlY3Rpb24gPSBTb3VyY2VDb250ZXh0X3JlZmxlY3Rpb25fOworICByZXR1cm4gbWV0YWRhdGE7Cit9CisKKyNpZiBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKy8vIFNvdXJjZUNvbnRleHQKKworLy8gb3B0aW9uYWwgc3RyaW5nIGZpbGVfbmFtZSA9IDE7Cit2b2lkIFNvdXJjZUNvbnRleHQ6OmNsZWFyX2ZpbGVfbmFtZSgpIHsKKyAgZmlsZV9uYW1lXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CisgY29uc3QgOjpzdGQ6OnN0cmluZyYgU291cmNlQ29udGV4dDo6ZmlsZV9uYW1lKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0LmZpbGVfbmFtZSkKKyAgcmV0dXJuIGZpbGVfbmFtZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgU291cmNlQ29udGV4dDo6c2V0X2ZpbGVfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICAKKyAgZmlsZV9uYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0LmZpbGVfbmFtZSkKK30KKyB2b2lkIFNvdXJjZUNvbnRleHQ6OnNldF9maWxlX25hbWUoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgCisgIGZpbGVfbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0LmZpbGVfbmFtZSkKK30KKyB2b2lkIFNvdXJjZUNvbnRleHQ6OnNldF9maWxlX25hbWUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIAorICBmaWxlX25hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0LmZpbGVfbmFtZSkKK30KKyA6OnN0ZDo6c3RyaW5nKiBTb3VyY2VDb250ZXh0OjptdXRhYmxlX2ZpbGVfbmFtZSgpIHsKKyAgCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0LmZpbGVfbmFtZSkKKyAgcmV0dXJuIGZpbGVfbmFtZV8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyA6OnN0ZDo6c3RyaW5nKiBTb3VyY2VDb250ZXh0OjpyZWxlYXNlX2ZpbGVfbmFtZSgpIHsKKyAgCisgIHJldHVybiBmaWxlX25hbWVfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBTb3VyY2VDb250ZXh0OjpzZXRfYWxsb2NhdGVkX2ZpbGVfbmFtZSg6OnN0ZDo6c3RyaW5nKiBmaWxlX25hbWUpIHsKKyAgaWYgKGZpbGVfbmFtZSAhPSBOVUxMKSB7CisgICAgCisgIH0gZWxzZSB7CisgICAgCisgIH0KKyAgZmlsZV9uYW1lXy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgZmlsZV9uYW1lKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQuZmlsZV9uYW1lKQorfQorCisjZW5kaWYgIC8vIFBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworCisvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobmFtZXNwYWNlX3Njb3BlKQorCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGdsb2JhbF9zY29wZSkKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvc291cmNlX2NvbnRleHQucGIuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvc291cmNlX2NvbnRleHQucGIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMmUxMTQ2Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zb3VyY2VfY29udGV4dC5wYi5oCkBAIC0wLDAgKzEsMTg1IEBACisvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQorLy8gc291cmNlOiBnb29nbGUvcHJvdG9idWYvc291cmNlX2NvbnRleHQucHJvdG8KKworI2lmbmRlZiBQUk9UT0JVRl9nb29nbGVfMmZwcm90b2J1Zl8yZnNvdXJjZV81ZmNvbnRleHRfMmVwcm90b19fSU5DTFVERUQKKyNkZWZpbmUgUFJPVE9CVUZfZ29vZ2xlXzJmcHJvdG9idWZfMmZzb3VyY2VfNWZjb250ZXh0XzJlcHJvdG9fX0lOQ0xVREVECisKKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisKKyNpZiBHT09HTEVfUFJPVE9CVUZfVkVSU0lPTiA8IDMwMDAwMDAKKyNlcnJvciBUaGlzIGZpbGUgd2FzIGdlbmVyYXRlZCBieSBhIG5ld2VyIHZlcnNpb24gb2YgcHJvdG9jIHdoaWNoIGlzCisjZXJyb3IgaW5jb21wYXRpYmxlIHdpdGggeW91ciBQcm90b2NvbCBCdWZmZXIgaGVhZGVycy4gIFBsZWFzZSB1cGRhdGUKKyNlcnJvciB5b3VyIGhlYWRlcnMuCisjZW5kaWYKKyNpZiAzMDAwMDAwIDwgR09PR0xFX1BST1RPQlVGX01JTl9QUk9UT0NfVkVSU0lPTgorI2Vycm9yIFRoaXMgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IGFuIG9sZGVyIHZlcnNpb24gb2YgcHJvdG9jIHdoaWNoIGlzCisjZXJyb3IgaW5jb21wYXRpYmxlIHdpdGggeW91ciBQcm90b2NvbCBCdWZmZXIgaGVhZGVycy4gIFBsZWFzZQorI2Vycm9yIHJlZ2VuZXJhdGUgdGhpcyBmaWxlIHdpdGggYSBuZXdlciB2ZXJzaW9uIG9mIHByb3RvYy4KKyNlbmRpZgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2FyZW5hLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2FyZW5hc3RyaW5nLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9tZXNzYWdlX3V0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWV0YWRhdGEuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWVzc2FnZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9yZXBlYXRlZF9maWVsZC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9leHRlbnNpb25fc2V0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Vua25vd25fZmllbGRfc2V0Lmg+CisvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW5jbHVkZXMpCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworLy8gSW50ZXJuYWwgaW1wbGVtZW50YXRpb24gZGV0YWlsIC0tIGRvIG5vdCBjYWxsIHRoZXNlLgordm9pZCBMSUJQUk9UT0JVRl9FWFBPUlQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZnNvdXJjZV81ZmNvbnRleHRfMmVwcm90bygpOwordm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmc291cmNlXzVmY29udGV4dF8yZXByb3RvKCk7Cit2b2lkIHByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZnNvdXJjZV81ZmNvbnRleHRfMmVwcm90bygpOworCitjbGFzcyBTb3VyY2VDb250ZXh0OworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBTb3VyY2VDb250ZXh0IDogcHVibGljIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSB7CisgcHVibGljOgorICBTb3VyY2VDb250ZXh0KCk7CisgIHZpcnR1YWwgflNvdXJjZUNvbnRleHQoKTsKKworICBTb3VyY2VDb250ZXh0KGNvbnN0IFNvdXJjZUNvbnRleHQmIGZyb20pOworCisgIGlubGluZSBTb3VyY2VDb250ZXh0JiBvcGVyYXRvcj0oY29uc3QgU291cmNlQ29udGV4dCYgZnJvbSkgeworICAgIENvcHlGcm9tKGZyb20pOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIHN0YXRpYyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIGRlc2NyaXB0b3IoKTsKKyAgc3RhdGljIGNvbnN0IFNvdXJjZUNvbnRleHQmIGRlZmF1bHRfaW5zdGFuY2UoKTsKKworICB2b2lkIFN3YXAoU291cmNlQ29udGV4dCogb3RoZXIpOworCisgIC8vIGltcGxlbWVudHMgTWVzc2FnZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgaW5saW5lIFNvdXJjZUNvbnRleHQqIE5ldygpIGNvbnN0IHsgcmV0dXJuIE5ldyhOVUxMKTsgfQorCisgIFNvdXJjZUNvbnRleHQqIE5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3Q7CisgIHZvaWQgQ29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCBTb3VyY2VDb250ZXh0JiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgU291cmNlQ29udGV4dCYgZnJvbSk7CisgIHZvaWQgQ2xlYXIoKTsKKyAgYm9vbCBJc0luaXRpYWxpemVkKCkgY29uc3Q7CisKKyAgaW50IEJ5dGVTaXplKCkgY29uc3Q7CisgIGJvb2wgTWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpOworICB2b2lkIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIG91dHB1dCkgY29uc3Q7CisgIGludCBHZXRDYWNoZWRTaXplKCkgY29uc3QgeyByZXR1cm4gX2NhY2hlZF9zaXplXzsgfQorICBwcml2YXRlOgorICB2b2lkIFNoYXJlZEN0b3IoKTsKKyAgdm9pZCBTaGFyZWREdG9yKCk7CisgIHZvaWQgU2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3Q7CisgIHZvaWQgSW50ZXJuYWxTd2FwKFNvdXJjZUNvbnRleHQqIG90aGVyKTsKKyAgcHJpdmF0ZToKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hTm9WaXJ0dWFsKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLmFyZW5hKCk7CisgIH0KKyAgaW5saW5lIHZvaWQqIE1heWJlQXJlbmFQdHIoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ucmF3X2FyZW5hX3B0cigpOworICB9CisgIHB1YmxpYzoKKworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEdldE1ldGFkYXRhKCkgY29uc3Q7CisKKyAgLy8gbmVzdGVkIHR5cGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBhY2Nlc3NvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIG9wdGlvbmFsIHN0cmluZyBmaWxlX25hbWUgPSAxOworICB2b2lkIGNsZWFyX2ZpbGVfbmFtZSgpOworICBzdGF0aWMgY29uc3QgaW50IGtGaWxlTmFtZUZpZWxkTnVtYmVyID0gMTsKKyAgY29uc3QgOjpzdGQ6OnN0cmluZyYgZmlsZV9uYW1lKCkgY29uc3Q7CisgIHZvaWQgc2V0X2ZpbGVfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X2ZpbGVfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSk7CisgIHZvaWQgc2V0X2ZpbGVfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpOworICA6OnN0ZDo6c3RyaW5nKiBtdXRhYmxlX2ZpbGVfbmFtZSgpOworICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlX2ZpbGVfbmFtZSgpOworICB2b2lkIHNldF9hbGxvY2F0ZWRfZmlsZV9uYW1lKDo6c3RkOjpzdHJpbmcqIGZpbGVfbmFtZSk7CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0KQorIHByaXZhdGU6CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6SW50ZXJuYWxNZXRhZGF0YVdpdGhBcmVuYSBfaW50ZXJuYWxfbWV0YWRhdGFfOworICBib29sIF9pc19kZWZhdWx0X2luc3RhbmNlXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QXJlbmFTdHJpbmdQdHIgZmlsZV9uYW1lXzsKKyAgbXV0YWJsZSBpbnQgX2NhY2hlZF9zaXplXzsKKyAgZnJpZW5kIHZvaWQgTElCUFJPVE9CVUZfRVhQT1JUIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZzb3VyY2VfNWZjb250ZXh0XzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfQXNzaWduRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZnNvdXJjZV81ZmNvbnRleHRfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZzb3VyY2VfNWZjb250ZXh0XzJlcHJvdG8oKTsKKworICB2b2lkIEluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICBzdGF0aWMgU291cmNlQ29udGV4dCogZGVmYXVsdF9pbnN0YW5jZV87Cit9OworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworI2lmICFQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKy8vIFNvdXJjZUNvbnRleHQKKworLy8gb3B0aW9uYWwgc3RyaW5nIGZpbGVfbmFtZSA9IDE7CitpbmxpbmUgdm9pZCBTb3VyY2VDb250ZXh0OjpjbGVhcl9maWxlX25hbWUoKSB7CisgIGZpbGVfbmFtZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIFNvdXJjZUNvbnRleHQ6OmZpbGVfbmFtZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dC5maWxlX25hbWUpCisgIHJldHVybiBmaWxlX25hbWVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIFNvdXJjZUNvbnRleHQ6OnNldF9maWxlX25hbWUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgCisgIGZpbGVfbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dC5maWxlX25hbWUpCit9CitpbmxpbmUgdm9pZCBTb3VyY2VDb250ZXh0OjpzZXRfZmlsZV9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIAorICBmaWxlX25hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dC5maWxlX25hbWUpCit9CitpbmxpbmUgdm9pZCBTb3VyY2VDb250ZXh0OjpzZXRfZmlsZV9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICAKKyAgZmlsZV9uYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dC5maWxlX25hbWUpCit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogU291cmNlQ29udGV4dDo6bXV0YWJsZV9maWxlX25hbWUoKSB7CisgIAorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dC5maWxlX25hbWUpCisgIHJldHVybiBmaWxlX25hbWVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogU291cmNlQ29udGV4dDo6cmVsZWFzZV9maWxlX25hbWUoKSB7CisgIAorICByZXR1cm4gZmlsZV9uYW1lXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgU291cmNlQ29udGV4dDo6c2V0X2FsbG9jYXRlZF9maWxlX25hbWUoOjpzdGQ6OnN0cmluZyogZmlsZV9uYW1lKSB7CisgIGlmIChmaWxlX25hbWUgIT0gTlVMTCkgeworICAgIAorICB9IGVsc2UgeworICAgIAorICB9CisgIGZpbGVfbmFtZV8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGZpbGVfbmFtZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0LmZpbGVfbmFtZSkKK30KKworI2VuZGlmICAvLyAhUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisKKy8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChuYW1lc3BhY2Vfc2NvcGUpCisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZ2xvYmFsX3Njb3BlKQorCisjZW5kaWYgIC8vIFBST1RPQlVGX2dvb2dsZV8yZnByb3RvYnVmXzJmc291cmNlXzVmY29udGV4dF8yZXByb3RvX19JTkNMVURFRApkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zb3VyY2VfY29udGV4dC5wcm90byBiL3NyYy9nb29nbGUvcHJvdG9idWYvc291cmNlX2NvbnRleHQucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDc2MjUyYwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc291cmNlX2NvbnRleHQucHJvdG8KQEAgLTAsMCArMSw0OCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3N5bnRheCA9ICJwcm90bzMiOworCitwYWNrYWdlIGdvb2dsZS5wcm90b2J1ZjsKKworb3B0aW9uIGNzaGFycF9uYW1lc3BhY2UgPSAiR29vZ2xlLlByb3RvYnVmLldlbGxLbm93blR5cGVzIjsKK29wdGlvbiBqYXZhX3BhY2thZ2UgPSAiY29tLmdvb2dsZS5wcm90b2J1ZiI7CitvcHRpb24gamF2YV9vdXRlcl9jbGFzc25hbWUgPSAiU291cmNlQ29udGV4dFByb3RvIjsKK29wdGlvbiBqYXZhX211bHRpcGxlX2ZpbGVzID0gdHJ1ZTsKK29wdGlvbiBqYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaCA9IHRydWU7CitvcHRpb24gb2JqY19jbGFzc19wcmVmaXggPSAiR1BCIjsKKworLy8gYFNvdXJjZUNvbnRleHRgIHJlcHJlc2VudHMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHNvdXJjZSBvZiBhCisvLyBwcm90b2J1ZiBlbGVtZW50LCBsaWtlIHRoZSBmaWxlIGluIHdoaWNoIGl0IGlzIGRlZmluZWQuCittZXNzYWdlIFNvdXJjZUNvbnRleHQgeworICAvLyBUaGUgcGF0aC1xdWFsaWZpZWQgbmFtZSBvZiB0aGUgLnByb3RvIGZpbGUgdGhhdCBjb250YWluZWQgdGhlIGFzc29jaWF0ZWQKKyAgLy8gcHJvdG9idWYgZWxlbWVudC4gIEZvciBleGFtcGxlOiBgImdvb2dsZS9wcm90b2J1Zi9zb3VyY2UucHJvdG8iYC4KKyAgc3RyaW5nIGZpbGVfbmFtZSA9IDE7Cit9CmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0cnVjdC5wYi5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3RydWN0LnBiLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUwMjA1OTcKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0cnVjdC5wYi5jYwpAQCAtMCwwICsxLDE0NzAgQEAKKy8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCisvLyBzb3VyY2U6IGdvb2dsZS9wcm90b2J1Zi9zdHJ1Y3QucHJvdG8KKworI2RlZmluZSBJTlRFUk5BTF9TVVBQUkVTU19QUk9UT0JVRl9GSUVMRF9ERVBSRUNBVElPTgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHJ1Y3QucGIuaD4KKworI2luY2x1ZGUgPGFsZ29yaXRobT4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvcG9ydC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9vbmNlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdF9saXRlX2lubC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9tZXNzYWdlX3JlZmxlY3Rpb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcmVmbGVjdGlvbl9vcHMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuaD4KKy8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbmNsdWRlcykKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCituYW1lc3BhY2UgeworCitjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIFN0cnVjdF9kZXNjcmlwdG9yXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbioKKyAgU3RydWN0X3JlZmxlY3Rpb25fID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogU3RydWN0X0ZpZWxkc0VudHJ5X2Rlc2NyaXB0b3JfID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogVmFsdWVfZGVzY3JpcHRvcl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24qCisgIFZhbHVlX3JlZmxlY3Rpb25fID0gTlVMTDsKK3N0cnVjdCBWYWx1ZU9uZW9mSW5zdGFuY2UgeworICBpbnQgbnVsbF92YWx1ZV87CisgIGRvdWJsZSBudW1iZXJfdmFsdWVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBcmVuYVN0cmluZ1B0ciBzdHJpbmdfdmFsdWVfOworICBib29sIGJvb2xfdmFsdWVfOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlN0cnVjdCogc3RydWN0X3ZhbHVlXzsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpMaXN0VmFsdWUqIGxpc3RfdmFsdWVfOworfSogVmFsdWVfZGVmYXVsdF9vbmVvZl9pbnN0YW5jZV8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBMaXN0VmFsdWVfZGVzY3JpcHRvcl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24qCisgIExpc3RWYWx1ZV9yZWZsZWN0aW9uXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yKiBOdWxsVmFsdWVfZGVzY3JpcHRvcl8gPSBOVUxMOworCit9ICAvLyBuYW1lc3BhY2UKKworCit2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZzdHJ1Y3RfMmVwcm90bygpIHsKKyAgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZnN0cnVjdF8yZXByb3RvKCk7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmlsZURlc2NyaXB0b3IqIGZpbGUgPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclBvb2w6OmdlbmVyYXRlZF9wb29sKCktPkZpbmRGaWxlQnlOYW1lKAorICAgICAgImdvb2dsZS9wcm90b2J1Zi9zdHJ1Y3QucHJvdG8iKTsKKyAgR09PR0xFX0NIRUNLKGZpbGUgIT0gTlVMTCk7CisgIFN0cnVjdF9kZXNjcmlwdG9yXyA9IGZpbGUtPm1lc3NhZ2VfdHlwZSgwKTsKKyAgc3RhdGljIGNvbnN0IGludCBTdHJ1Y3Rfb2Zmc2V0c19bMV0gPSB7CisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChTdHJ1Y3QsIGZpZWxkc18pLAorICB9OworICBTdHJ1Y3RfcmVmbGVjdGlvbl8gPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpOZXdHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbigKKyAgICAgIFN0cnVjdF9kZXNjcmlwdG9yXywKKyAgICAgIFN0cnVjdDo6ZGVmYXVsdF9pbnN0YW5jZV8sCisgICAgICBTdHJ1Y3Rfb2Zmc2V0c18sCisgICAgICAtMSwKKyAgICAgIC0xLAorICAgICAgLTEsCisgICAgICBzaXplb2YoU3RydWN0KSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoU3RydWN0LCBfaW50ZXJuYWxfbWV0YWRhdGFfKSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoU3RydWN0LCBfaXNfZGVmYXVsdF9pbnN0YW5jZV8pKTsKKyAgU3RydWN0X0ZpZWxkc0VudHJ5X2Rlc2NyaXB0b3JfID0gU3RydWN0X2Rlc2NyaXB0b3JfLT5uZXN0ZWRfdHlwZSgwKTsKKyAgVmFsdWVfZGVzY3JpcHRvcl8gPSBmaWxlLT5tZXNzYWdlX3R5cGUoMSk7CisgIHN0YXRpYyBjb25zdCBpbnQgVmFsdWVfb2Zmc2V0c19bN10gPSB7CisgICAgUFJPVE8yX0dFTkVSQVRFRF9ERUZBVUxUX09ORU9GX0ZJRUxEX09GRlNFVChWYWx1ZV9kZWZhdWx0X29uZW9mX2luc3RhbmNlXywgbnVsbF92YWx1ZV8pLAorICAgIFBST1RPMl9HRU5FUkFURURfREVGQVVMVF9PTkVPRl9GSUVMRF9PRkZTRVQoVmFsdWVfZGVmYXVsdF9vbmVvZl9pbnN0YW5jZV8sIG51bWJlcl92YWx1ZV8pLAorICAgIFBST1RPMl9HRU5FUkFURURfREVGQVVMVF9PTkVPRl9GSUVMRF9PRkZTRVQoVmFsdWVfZGVmYXVsdF9vbmVvZl9pbnN0YW5jZV8sIHN0cmluZ192YWx1ZV8pLAorICAgIFBST1RPMl9HRU5FUkFURURfREVGQVVMVF9PTkVPRl9GSUVMRF9PRkZTRVQoVmFsdWVfZGVmYXVsdF9vbmVvZl9pbnN0YW5jZV8sIGJvb2xfdmFsdWVfKSwKKyAgICBQUk9UTzJfR0VORVJBVEVEX0RFRkFVTFRfT05FT0ZfRklFTERfT0ZGU0VUKFZhbHVlX2RlZmF1bHRfb25lb2ZfaW5zdGFuY2VfLCBzdHJ1Y3RfdmFsdWVfKSwKKyAgICBQUk9UTzJfR0VORVJBVEVEX0RFRkFVTFRfT05FT0ZfRklFTERfT0ZGU0VUKFZhbHVlX2RlZmF1bHRfb25lb2ZfaW5zdGFuY2VfLCBsaXN0X3ZhbHVlXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChWYWx1ZSwga2luZF8pLAorICB9OworICBWYWx1ZV9yZWZsZWN0aW9uXyA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok5ld0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKAorICAgICAgVmFsdWVfZGVzY3JpcHRvcl8sCisgICAgICBWYWx1ZTo6ZGVmYXVsdF9pbnN0YW5jZV8sCisgICAgICBWYWx1ZV9vZmZzZXRzXywKKyAgICAgIC0xLAorICAgICAgLTEsCisgICAgICAtMSwKKyAgICAgIFZhbHVlX2RlZmF1bHRfb25lb2ZfaW5zdGFuY2VfLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChWYWx1ZSwgX29uZW9mX2Nhc2VfWzBdKSwKKyAgICAgIHNpemVvZihWYWx1ZSksCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKFZhbHVlLCBfaW50ZXJuYWxfbWV0YWRhdGFfKSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoVmFsdWUsIF9pc19kZWZhdWx0X2luc3RhbmNlXykpOworICBMaXN0VmFsdWVfZGVzY3JpcHRvcl8gPSBmaWxlLT5tZXNzYWdlX3R5cGUoMik7CisgIHN0YXRpYyBjb25zdCBpbnQgTGlzdFZhbHVlX29mZnNldHNfWzFdID0geworICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoTGlzdFZhbHVlLCB2YWx1ZXNfKSwKKyAgfTsKKyAgTGlzdFZhbHVlX3JlZmxlY3Rpb25fID0KKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6TmV3R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24oCisgICAgICBMaXN0VmFsdWVfZGVzY3JpcHRvcl8sCisgICAgICBMaXN0VmFsdWU6OmRlZmF1bHRfaW5zdGFuY2VfLAorICAgICAgTGlzdFZhbHVlX29mZnNldHNfLAorICAgICAgLTEsCisgICAgICAtMSwKKyAgICAgIC0xLAorICAgICAgc2l6ZW9mKExpc3RWYWx1ZSksCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKExpc3RWYWx1ZSwgX2ludGVybmFsX21ldGFkYXRhXyksCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKExpc3RWYWx1ZSwgX2lzX2RlZmF1bHRfaW5zdGFuY2VfKSk7CisgIE51bGxWYWx1ZV9kZXNjcmlwdG9yXyA9IGZpbGUtPmVudW1fdHlwZSgwKTsKK30KKworbmFtZXNwYWNlIHsKKworR09PR0xFX1BST1RPQlVGX0RFQ0xBUkVfT05DRShwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc19vbmNlXyk7CitpbmxpbmUgdm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKSB7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6R29vZ2xlT25jZUluaXQoJnByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzX29uY2VfLAorICAgICAgICAgICAgICAgICAmcHJvdG9idWZfQXNzaWduRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZnN0cnVjdF8yZXByb3RvKTsKK30KKwordm9pZCBwcm90b2J1Zl9SZWdpc3RlclR5cGVzKGNvbnN0IDo6c3RkOjpzdHJpbmcmKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VGYWN0b3J5OjpJbnRlcm5hbFJlZ2lzdGVyR2VuZXJhdGVkTWVzc2FnZSgKKyAgICAgIFN0cnVjdF9kZXNjcmlwdG9yXywgJlN0cnVjdDo6ZGVmYXVsdF9pbnN0YW5jZSgpKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZE1lc3NhZ2UoCisgICAgICAgIFN0cnVjdF9GaWVsZHNFbnRyeV9kZXNjcmlwdG9yXywKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6TWFwRW50cnk8CisgICAgICAgICAgICA6OnN0ZDo6c3RyaW5nLAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjpWYWx1ZSwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX1NUUklORywKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX01FU1NBR0UsCisgICAgICAgICAgICAwPjo6Q3JlYXRlRGVmYXVsdEluc3RhbmNlKAorICAgICAgICAgICAgICAgIFN0cnVjdF9GaWVsZHNFbnRyeV9kZXNjcmlwdG9yXykpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VGYWN0b3J5OjpJbnRlcm5hbFJlZ2lzdGVyR2VuZXJhdGVkTWVzc2FnZSgKKyAgICAgIFZhbHVlX2Rlc2NyaXB0b3JfLCAmVmFsdWU6OmRlZmF1bHRfaW5zdGFuY2UoKSk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZUZhY3Rvcnk6OkludGVybmFsUmVnaXN0ZXJHZW5lcmF0ZWRNZXNzYWdlKAorICAgICAgTGlzdFZhbHVlX2Rlc2NyaXB0b3JfLCAmTGlzdFZhbHVlOjpkZWZhdWx0X2luc3RhbmNlKCkpOworfQorCit9ICAvLyBuYW1lc3BhY2UKKwordm9pZCBwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZzdHJ1Y3RfMmVwcm90bygpIHsKKyAgZGVsZXRlIFN0cnVjdDo6ZGVmYXVsdF9pbnN0YW5jZV87CisgIGRlbGV0ZSBTdHJ1Y3RfcmVmbGVjdGlvbl87CisgIGRlbGV0ZSBWYWx1ZTo6ZGVmYXVsdF9pbnN0YW5jZV87CisgIGRlbGV0ZSBWYWx1ZV9kZWZhdWx0X29uZW9mX2luc3RhbmNlXzsKKyAgZGVsZXRlIFZhbHVlX3JlZmxlY3Rpb25fOworICBkZWxldGUgTGlzdFZhbHVlOjpkZWZhdWx0X2luc3RhbmNlXzsKKyAgZGVsZXRlIExpc3RWYWx1ZV9yZWZsZWN0aW9uXzsKK30KKwordm9pZCBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmc3RydWN0XzJlcHJvdG8oKSB7CisgIHN0YXRpYyBib29sIGFscmVhZHlfaGVyZSA9IGZhbHNlOworICBpZiAoYWxyZWFkeV9oZXJlKSByZXR1cm47CisgIGFscmVhZHlfaGVyZSA9IHRydWU7CisgIEdPT0dMRV9QUk9UT0JVRl9WRVJJRllfVkVSU0lPTjsKKworICA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQb29sOjpJbnRlcm5hbEFkZEdlbmVyYXRlZEZpbGUoCisgICAgIlxuXDAzNGdvb2dsZS9wcm90b2J1Zi9zdHJ1Y3QucHJvdG9cMDIyXDAxN2dvb2dsZS5wIgorICAgICJyb3RvYnVmXCJcMjA0XDAwMVxuXDAwNlN0cnVjdFwwMjIzXG5cMDA2ZmllbGRzXDAzMFwwMDEgXDAwMyhcMDEzMiMuZ29vIgorICAgICJnbGUucHJvdG9idWYuU3RydWN0LkZpZWxkc0VudHJ5XDAzMkVcblwwMTNGaWVsZCIKKyAgICAic0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMiVcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMzJcMDI2LmdvbyIKKyAgICAiZ2xlLnByb3RvYnVmLlZhbHVlOlwwMDI4XDAwMVwiXDM1MlwwMDFcblwwMDVWYWx1ZVwwMjIwXG5cbm51bGwiCisgICAgIl92YWx1ZVwwMzBcMDAxIFwwMDEoXDAxNjJcMDMyLmdvb2dsZS5wcm90b2J1Zi5OdWxsVmFsdWUiCisgICAgIkhcMDAwXDAyMlwwMjZcblwwMTRudW1iZXJfdmFsdWVcMDMwXDAwMiBcMDAxKFwwMDFIXDAwMFwwMjJcMDI2XG5cMDE0c3RyaW5nX3ZhbCIKKyAgICAidWVcMDMwXDAwMyBcMDAxKFx0SFwwMDBcMDIyXDAyNFxuXG5ib29sX3ZhbHVlXDAzMFwwMDQgXDAwMShcMDEwSFwwMDBcMDIyL1xuXDAxNHN0cnUiCisgICAgImN0X3ZhbHVlXDAzMFwwMDUgXDAwMShcMDEzMlwwMjcuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdEgiCisgICAgIlwwMDBcMDIyMFxuXG5saXN0X3ZhbHVlXDAzMFwwMDYgXDAwMShcMDEzMlwwMzIuZ29vZ2xlLnByb3RvYnVmLiIKKyAgICAiTGlzdFZhbHVlSFwwMDBCXDAwNlxuXDAwNGtpbmRcIjNcblx0TGlzdFZhbHVlXDAyMiZcblwwMDZ2YWx1IgorICAgICJlc1wwMzBcMDAxIFwwMDMoXDAxMzJcMDI2Lmdvb2dsZS5wcm90b2J1Zi5WYWx1ZSpcMDMzXG5cdE51bGwiCisgICAgIlZhbHVlXDAyMlwwMTZcblxuTlVMTF9WQUxVRVwwMjBcMDAwQk5cblwwMjNjb20uZ29vZ2xlLnByb3QiCisgICAgIm9idWZCXDAxM1N0cnVjdFByb3RvUFwwMDFcMjQwXDAwMVwwMDFcMjQyXDAwMlwwMDNHUEJcMjUyXDAwMlwwMzZHb29nbGUuUHIiCisgICAgIm90b2J1Zi5XZWxsS25vd25UeXBlc2JcMDA2cHJvdG8zIiwgNTg5KTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZEZpbGUoCisgICAgImdvb2dsZS9wcm90b2J1Zi9zdHJ1Y3QucHJvdG8iLCAmcHJvdG9idWZfUmVnaXN0ZXJUeXBlcyk7CisgIFN0cnVjdDo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBuZXcgU3RydWN0KCk7CisgIFZhbHVlOjpkZWZhdWx0X2luc3RhbmNlXyA9IG5ldyBWYWx1ZSgpOworICBWYWx1ZV9kZWZhdWx0X29uZW9mX2luc3RhbmNlXyA9IG5ldyBWYWx1ZU9uZW9mSW5zdGFuY2UoKTsKKyAgTGlzdFZhbHVlOjpkZWZhdWx0X2luc3RhbmNlXyA9IG5ldyBMaXN0VmFsdWUoKTsKKyAgU3RydWN0OjpkZWZhdWx0X2luc3RhbmNlXy0+SW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIFZhbHVlOjpkZWZhdWx0X2luc3RhbmNlXy0+SW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIExpc3RWYWx1ZTo6ZGVmYXVsdF9pbnN0YW5jZV8tPkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpPblNodXRkb3duKCZwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZzdHJ1Y3RfMmVwcm90byk7Cit9CisKKy8vIEZvcmNlIEFkZERlc2NyaXB0b3JzKCkgdG8gYmUgY2FsbGVkIGF0IHN0YXRpYyBpbml0aWFsaXphdGlvbiB0aW1lLgorc3RydWN0IFN0YXRpY0Rlc2NyaXB0b3JJbml0aWFsaXplcl9nb29nbGVfMmZwcm90b2J1Zl8yZnN0cnVjdF8yZXByb3RvIHsKKyAgU3RhdGljRGVzY3JpcHRvckluaXRpYWxpemVyX2dvb2dsZV8yZnByb3RvYnVmXzJmc3RydWN0XzJlcHJvdG8oKSB7CisgICAgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZnN0cnVjdF8yZXByb3RvKCk7CisgIH0KK30gc3RhdGljX2Rlc2NyaXB0b3JfaW5pdGlhbGl6ZXJfZ29vZ2xlXzJmcHJvdG9idWZfMmZzdHJ1Y3RfMmVwcm90b187Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yKiBOdWxsVmFsdWVfZGVzY3JpcHRvcigpIHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIHJldHVybiBOdWxsVmFsdWVfZGVzY3JpcHRvcl87Cit9Citib29sIE51bGxWYWx1ZV9Jc1ZhbGlkKGludCB2YWx1ZSkgeworICBzd2l0Y2godmFsdWUpIHsKKyAgICBjYXNlIDA6CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICBkZWZhdWx0OgorICAgICAgcmV0dXJuIGZhbHNlOworICB9Cit9CisKKworbmFtZXNwYWNlIHsKKworc3RhdGljIHZvaWQgTWVyZ2VGcm9tRmFpbChpbnQgbGluZSkgR09PR0xFX0FUVFJJQlVURV9DT0xEOworc3RhdGljIHZvaWQgTWVyZ2VGcm9tRmFpbChpbnQgbGluZSkgeworICBHT09HTEVfQ0hFQ0soZmFsc2UpIDw8IF9fRklMRV9fIDw8ICI6IiA8PCBsaW5lOworfQorCit9ICAvLyBuYW1lc3BhY2UKKworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKyNpZiAhZGVmaW5lZChfTVNDX1ZFUikgfHwgX01TQ19WRVIgPj0gMTkwMAorY29uc3QgaW50IFN0cnVjdDo6a0ZpZWxkc0ZpZWxkTnVtYmVyOworI2VuZGlmICAvLyAhZGVmaW5lZChfTVNDX1ZFUikgfHwgX01TQ19WRVIgPj0gMTkwMAorCitTdHJ1Y3Q6OlN0cnVjdCgpCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgeworICBTaGFyZWRDdG9yKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuU3RydWN0KQorfQorCit2b2lkIFN0cnVjdDo6SW5pdEFzRGVmYXVsdEluc3RhbmNlKCkgeworICBfaXNfZGVmYXVsdF9pbnN0YW5jZV8gPSB0cnVlOworfQorCitTdHJ1Y3Q6OlN0cnVjdChjb25zdCBTdHJ1Y3QmIGZyb20pCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksCisgICAgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29weV9jb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuU3RydWN0KQorfQorCit2b2lkIFN0cnVjdDo6U2hhcmVkQ3RvcigpIHsKKyAgICBfaXNfZGVmYXVsdF9pbnN0YW5jZV8gPSBmYWxzZTsKKyAgX2NhY2hlZF9zaXplXyA9IDA7CisgIGZpZWxkc18uU2V0QXNzaWduRGVzY3JpcHRvckNhbGxiYWNrKAorICAgICAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKTsKKyAgZmllbGRzXy5TZXRFbnRyeURlc2NyaXB0b3IoCisgICAgICAmOjpnb29nbGU6OnByb3RvYnVmOjpTdHJ1Y3RfRmllbGRzRW50cnlfZGVzY3JpcHRvcl8pOworfQorCitTdHJ1Y3Q6On5TdHJ1Y3QoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChkZXN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QpCisgIFNoYXJlZER0b3IoKTsKK30KKwordm9pZCBTdHJ1Y3Q6OlNoYXJlZER0b3IoKSB7CisgIGlmICh0aGlzICE9IGRlZmF1bHRfaW5zdGFuY2VfKSB7CisgIH0KK30KKwordm9pZCBTdHJ1Y3Q6OlNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0IHsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHNpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBTdHJ1Y3Q6OmRlc2NyaXB0b3IoKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICByZXR1cm4gU3RydWN0X2Rlc2NyaXB0b3JfOworfQorCitjb25zdCBTdHJ1Y3QmIFN0cnVjdDo6ZGVmYXVsdF9pbnN0YW5jZSgpIHsKKyAgaWYgKGRlZmF1bHRfaW5zdGFuY2VfID09IE5VTEwpIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZzdHJ1Y3RfMmVwcm90bygpOworICByZXR1cm4gKmRlZmF1bHRfaW5zdGFuY2VfOworfQorCitTdHJ1Y3QqIFN0cnVjdDo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBOVUxMOworCitTdHJ1Y3QqIFN0cnVjdDo6TmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdCB7CisgIFN0cnVjdCogbiA9IG5ldyBTdHJ1Y3Q7CisgIGlmIChhcmVuYSAhPSBOVUxMKSB7CisgICAgYXJlbmEtPk93bihuKTsKKyAgfQorICByZXR1cm4gbjsKK30KKwordm9pZCBTdHJ1Y3Q6OkNsZWFyKCkgeworICBmaWVsZHNfLkNsZWFyKCk7Cit9CisKK2Jvb2wgU3RydWN0OjpNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyNkZWZpbmUgRE9fKEVYUFJFU1NJT04pIGlmICghKEVYUFJFU1NJT04pKSBnb3RvIGZhaWx1cmUKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgdGFnOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLlN0cnVjdCkKKyAgZm9yICg7OykgeworICAgIDo6c3RkOjpwYWlyPCA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiwgYm9vbD4gcCA9IGlucHV0LT5SZWFkVGFnV2l0aEN1dG9mZigxMjcpOworICAgIHRhZyA9IHAuZmlyc3Q7CisgICAgaWYgKCFwLnNlY29uZCkgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICBzd2l0Y2ggKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdGaWVsZE51bWJlcih0YWcpKSB7CisgICAgICAvLyBtYXA8c3RyaW5nLCAuZ29vZ2xlLnByb3RvYnVmLlZhbHVlPiBmaWVsZHMgPSAxOworICAgICAgY2FzZSAxOiB7CisgICAgICAgIGlmICh0YWcgPT0gMTApIHsKKyAgICAgICAgICBET18oaW5wdXQtPkluY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCkpOworICAgICAgICAgcGFyc2VfbG9vcF9maWVsZHM6CisgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPFN0cnVjdF9GaWVsZHNFbnRyeT4gZW50cnkoZmllbGRzXy5OZXdFbnRyeSgpKTsKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRNZXNzYWdlTm9WaXJ0dWFsKAorICAgICAgICAgICAgICBpbnB1dCwgZW50cnkuZ2V0KCkpKTsKKyAgICAgICAgICAoKm11dGFibGVfZmllbGRzKCkpW2VudHJ5LT5rZXkoKV0uU3dhcChlbnRyeS0+bXV0YWJsZV92YWx1ZSgpKTsKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlZlcmlmeVV0ZjhTdHJpbmcoCisgICAgICAgICAgICBlbnRyeS0+a2V5KCkuZGF0YSgpLCBlbnRyeS0+a2V5KCkubGVuZ3RoKCksCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UEFSU0UsCisgICAgICAgICAgICAiZ29vZ2xlLnByb3RvYnVmLlN0cnVjdC5GaWVsZHNFbnRyeS5rZXkiKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygxMCkpIGdvdG8gcGFyc2VfbG9vcF9maWVsZHM7CisgICAgICAgIGlucHV0LT5VbnNhZmVEZWNyZW1lbnRSZWN1cnNpb25EZXB0aCgpOworICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdEF0RW5kKCkpIGdvdG8gc3VjY2VzczsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGRlZmF1bHQ6IHsKKyAgICAgIGhhbmRsZV91bnVzdWFsOgorICAgICAgICBpZiAodGFnID09IDAgfHwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdXaXJlVHlwZSh0YWcpID09CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRU5EX0dST1VQKSB7CisgICAgICAgICAgZ290byBzdWNjZXNzOworICAgICAgICB9CisgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U2tpcEZpZWxkKGlucHV0LCB0YWcpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CitzdWNjZXNzOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3VjY2Vzczpnb29nbGUucHJvdG9idWYuU3RydWN0KQorICByZXR1cm4gdHJ1ZTsKK2ZhaWx1cmU6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9mYWlsdXJlOmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QpCisgIHJldHVybiBmYWxzZTsKKyN1bmRlZiBET18KK30KKwordm9pZCBTdHJ1Y3Q6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLlN0cnVjdCkKKyAgLy8gbWFwPHN0cmluZywgLmdvb2dsZS5wcm90b2J1Zi5WYWx1ZT4gZmllbGRzID0gMTsKKyAgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxTdHJ1Y3RfRmllbGRzRW50cnk+IGVudHJ5OworICAgIGZvciAoOjpnb29nbGU6OnByb3RvYnVmOjpNYXA8IDo6c3RkOjpzdHJpbmcsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VmFsdWUgPjo6Y29uc3RfaXRlcmF0b3IKKyAgICAgICAgaXQgPSB0aGlzLT5maWVsZHMoKS5iZWdpbigpOworICAgICAgICBpdCAhPSB0aGlzLT5maWVsZHMoKS5lbmQoKTsgKytpdCkgeworICAgICAgZW50cnkucmVzZXQoZmllbGRzXy5OZXdFbnRyeVdyYXBwZXIoaXQtPmZpcnN0LCBpdC0+c2Vjb25kKSk7CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgICAgIDEsICplbnRyeSwgb3V0cHV0KTsKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpWZXJpZnlVdGY4U3RyaW5nKAorICAgICAgICBpdC0+Zmlyc3QuZGF0YSgpLCBpdC0+Zmlyc3QubGVuZ3RoKCksCisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTRVJJQUxJWkUsCisgICAgICAgICJnb29nbGUucHJvdG9idWYuU3RydWN0LkZpZWxkc0VudHJ5LmtleSIpOworICAgIH0KKyAgfQorCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfZW5kOmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QpCit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIFN0cnVjdDo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiB0YXJnZXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9zdGFydDpnb29nbGUucHJvdG9idWYuU3RydWN0KQorICAvLyBtYXA8c3RyaW5nLCAuZ29vZ2xlLnByb3RvYnVmLlZhbHVlPiBmaWVsZHMgPSAxOworICB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPFN0cnVjdF9GaWVsZHNFbnRyeT4gZW50cnk7CisgICAgZm9yICg6Omdvb2dsZTo6cHJvdG9idWY6Ok1hcDwgOjpzdGQ6OnN0cmluZywgOjpnb29nbGU6OnByb3RvYnVmOjpWYWx1ZSA+Ojpjb25zdF9pdGVyYXRvcgorICAgICAgICBpdCA9IHRoaXMtPmZpZWxkcygpLmJlZ2luKCk7CisgICAgICAgIGl0ICE9IHRoaXMtPmZpZWxkcygpLmVuZCgpOyArK2l0KSB7CisgICAgICBlbnRyeS5yZXNldChmaWVsZHNfLk5ld0VudHJ5V3JhcHBlcihpdC0+Zmlyc3QsIGl0LT5zZWNvbmQpKTsKKyAgICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjoKKyAgICAgICAgICBXcml0ZU1lc3NhZ2VOb1ZpcnR1YWxUb0FycmF5KAorICAgICAgICAgICAgICAxLCAqZW50cnksIHRhcmdldCk7CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VmVyaWZ5VXRmOFN0cmluZygKKyAgICAgICAgaXQtPmZpcnN0LmRhdGEoKSwgaXQtPmZpcnN0Lmxlbmd0aCgpLAorICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U0VSSUFMSVpFLAorICAgICAgICAiZ29vZ2xlLnByb3RvYnVmLlN0cnVjdC5GaWVsZHNFbnRyeS5rZXkiKTsKKyAgICB9CisgIH0KKworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X2VuZDpnb29nbGUucHJvdG9idWYuU3RydWN0KQorICByZXR1cm4gdGFyZ2V0OworfQorCitpbnQgU3RydWN0OjpCeXRlU2l6ZSgpIGNvbnN0IHsKKyAgaW50IHRvdGFsX3NpemUgPSAwOworCisgIC8vIG1hcDxzdHJpbmcsIC5nb29nbGUucHJvdG9idWYuVmFsdWU+IGZpZWxkcyA9IDE7CisgIHRvdGFsX3NpemUgKz0gMSAqIHRoaXMtPmZpZWxkc19zaXplKCk7CisgIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8U3RydWN0X0ZpZWxkc0VudHJ5PiBlbnRyeTsKKyAgICBmb3IgKDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWFwPCA6OnN0ZDo6c3RyaW5nLCA6Omdvb2dsZTo6cHJvdG9idWY6OlZhbHVlID46OmNvbnN0X2l0ZXJhdG9yCisgICAgICAgIGl0ID0gdGhpcy0+ZmllbGRzKCkuYmVnaW4oKTsKKyAgICAgICAgaXQgIT0gdGhpcy0+ZmllbGRzKCkuZW5kKCk7ICsraXQpIHsKKyAgICAgIGVudHJ5LnJlc2V0KGZpZWxkc18uTmV3RW50cnlXcmFwcGVyKGl0LT5maXJzdCwgaXQtPnNlY29uZCkpOworICAgICAgdG90YWxfc2l6ZSArPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6CisgICAgICAgICAgTWVzc2FnZVNpemVOb1ZpcnR1YWwoKmVudHJ5KTsKKyAgICB9CisgIH0KKworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gdG90YWxfc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7CisgIHJldHVybiB0b3RhbF9zaXplOworfQorCit2b2lkIFN0cnVjdDo6TWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBjb25zdCBTdHJ1Y3QqIHNvdXJjZSA9IAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RHluYW1pY0Nhc3RUb0dlbmVyYXRlZDxjb25zdCBTdHJ1Y3Q+KAorICAgICAgICAgICZmcm9tKTsKKyAgaWYgKHNvdXJjZSA9PSBOVUxMKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6UmVmbGVjdGlvbk9wczo6TWVyZ2UoZnJvbSwgdGhpcyk7CisgIH0gZWxzZSB7CisgICAgTWVyZ2VGcm9tKCpzb3VyY2UpOworICB9Cit9CisKK3ZvaWQgU3RydWN0OjpNZXJnZUZyb20oY29uc3QgU3RydWN0JiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGZpZWxkc18uTWVyZ2VGcm9tKGZyb20uZmllbGRzXyk7Cit9CisKK3ZvaWQgU3RydWN0OjpDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCit2b2lkIFN0cnVjdDo6Q29weUZyb20oY29uc3QgU3RydWN0JiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKworYm9vbCBTdHJ1Y3Q6OklzSW5pdGlhbGl6ZWQoKSBjb25zdCB7CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgU3RydWN0OjpTd2FwKFN0cnVjdCogb3RoZXIpIHsKKyAgaWYgKG90aGVyID09IHRoaXMpIHJldHVybjsKKyAgSW50ZXJuYWxTd2FwKG90aGVyKTsKK30KK3ZvaWQgU3RydWN0OjpJbnRlcm5hbFN3YXAoU3RydWN0KiBvdGhlcikgeworICBmaWVsZHNfLlN3YXAoJm90aGVyLT5maWVsZHNfKTsKKyAgX2ludGVybmFsX21ldGFkYXRhXy5Td2FwKCZvdGhlci0+X2ludGVybmFsX21ldGFkYXRhXyk7CisgIHN0ZDo6c3dhcChfY2FjaGVkX3NpemVfLCBvdGhlci0+X2NhY2hlZF9zaXplXyk7Cit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgU3RydWN0OjpHZXRNZXRhZGF0YSgpIGNvbnN0IHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgbWV0YWRhdGE7CisgIG1ldGFkYXRhLmRlc2NyaXB0b3IgPSBTdHJ1Y3RfZGVzY3JpcHRvcl87CisgIG1ldGFkYXRhLnJlZmxlY3Rpb24gPSBTdHJ1Y3RfcmVmbGVjdGlvbl87CisgIHJldHVybiBtZXRhZGF0YTsKK30KKworI2lmIFBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworLy8gU3RydWN0CisKKy8vIG1hcDxzdHJpbmcsIC5nb29nbGUucHJvdG9idWYuVmFsdWU+IGZpZWxkcyA9IDE7CitpbnQgU3RydWN0OjpmaWVsZHNfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIGZpZWxkc18uc2l6ZSgpOworfQordm9pZCBTdHJ1Y3Q6OmNsZWFyX2ZpZWxkcygpIHsKKyAgZmllbGRzXy5DbGVhcigpOworfQorIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWFwPCA6OnN0ZDo6c3RyaW5nLCA6Omdvb2dsZTo6cHJvdG9idWY6OlZhbHVlID4mCitTdHJ1Y3Q6OmZpZWxkcygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX21hcDpnb29nbGUucHJvdG9idWYuU3RydWN0LmZpZWxkcykKKyAgcmV0dXJuIGZpZWxkc18uR2V0TWFwKCk7Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjpNYXA8IDo6c3RkOjpzdHJpbmcsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VmFsdWUgPioKK1N0cnVjdDo6bXV0YWJsZV9maWVsZHMoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX21hcDpnb29nbGUucHJvdG9idWYuU3RydWN0LmZpZWxkcykKKyAgcmV0dXJuIGZpZWxkc18uTXV0YWJsZU1hcCgpOworfQorCisjZW5kaWYgIC8vIFBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKyNpZiAhZGVmaW5lZChfTVNDX1ZFUikgfHwgX01TQ19WRVIgPj0gMTkwMAorY29uc3QgaW50IFZhbHVlOjprTnVsbFZhbHVlRmllbGROdW1iZXI7Citjb25zdCBpbnQgVmFsdWU6OmtOdW1iZXJWYWx1ZUZpZWxkTnVtYmVyOworY29uc3QgaW50IFZhbHVlOjprU3RyaW5nVmFsdWVGaWVsZE51bWJlcjsKK2NvbnN0IGludCBWYWx1ZTo6a0Jvb2xWYWx1ZUZpZWxkTnVtYmVyOworY29uc3QgaW50IFZhbHVlOjprU3RydWN0VmFsdWVGaWVsZE51bWJlcjsKK2NvbnN0IGludCBWYWx1ZTo6a0xpc3RWYWx1ZUZpZWxkTnVtYmVyOworI2VuZGlmICAvLyAhZGVmaW5lZChfTVNDX1ZFUikgfHwgX01TQ19WRVIgPj0gMTkwMAorCitWYWx1ZTo6VmFsdWUoKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpLCBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLlZhbHVlKQorfQorCit2b2lkIFZhbHVlOjpJbml0QXNEZWZhdWx0SW5zdGFuY2UoKSB7CisgIF9pc19kZWZhdWx0X2luc3RhbmNlXyA9IHRydWU7CisgIFZhbHVlX2RlZmF1bHRfb25lb2ZfaW5zdGFuY2VfLT5udWxsX3ZhbHVlXyA9IDA7CisgIFZhbHVlX2RlZmF1bHRfb25lb2ZfaW5zdGFuY2VfLT5udW1iZXJfdmFsdWVfID0gMDsKKyAgVmFsdWVfZGVmYXVsdF9vbmVvZl9pbnN0YW5jZV8tPnN0cmluZ192YWx1ZV8uVW5zYWZlU2V0RGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBWYWx1ZV9kZWZhdWx0X29uZW9mX2luc3RhbmNlXy0+Ym9vbF92YWx1ZV8gPSBmYWxzZTsKKyAgVmFsdWVfZGVmYXVsdF9vbmVvZl9pbnN0YW5jZV8tPnN0cnVjdF92YWx1ZV8gPSBjb25zdF9jYXN0PCA6Omdvb2dsZTo6cHJvdG9idWY6OlN0cnVjdCo+KCY6Omdvb2dsZTo6cHJvdG9idWY6OlN0cnVjdDo6ZGVmYXVsdF9pbnN0YW5jZSgpKTsKKyAgVmFsdWVfZGVmYXVsdF9vbmVvZl9pbnN0YW5jZV8tPmxpc3RfdmFsdWVfID0gY29uc3RfY2FzdDwgOjpnb29nbGU6OnByb3RvYnVmOjpMaXN0VmFsdWUqPigmOjpnb29nbGU6OnByb3RvYnVmOjpMaXN0VmFsdWU6OmRlZmF1bHRfaW5zdGFuY2UoKSk7Cit9CisKK1ZhbHVlOjpWYWx1ZShjb25zdCBWYWx1ZSYgZnJvbSkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwKKyAgICBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICBNZXJnZUZyb20oZnJvbSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb3B5X2NvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5WYWx1ZSkKK30KKwordm9pZCBWYWx1ZTo6U2hhcmVkQ3RvcigpIHsKKyAgICBfaXNfZGVmYXVsdF9pbnN0YW5jZV8gPSBmYWxzZTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmcoKTsKKyAgX2NhY2hlZF9zaXplXyA9IDA7CisgIGNsZWFyX2hhc19raW5kKCk7Cit9CisKK1ZhbHVlOjp+VmFsdWUoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChkZXN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5WYWx1ZSkKKyAgU2hhcmVkRHRvcigpOworfQorCit2b2lkIFZhbHVlOjpTaGFyZWREdG9yKCkgeworICBpZiAoaGFzX2tpbmQoKSkgeworICAgIGNsZWFyX2tpbmQoKTsKKyAgfQorICBpZiAodGhpcyAhPSBkZWZhdWx0X2luc3RhbmNlXykgeworICB9Cit9CisKK3ZvaWQgVmFsdWU6OlNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0IHsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHNpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBWYWx1ZTo6ZGVzY3JpcHRvcigpIHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIHJldHVybiBWYWx1ZV9kZXNjcmlwdG9yXzsKK30KKworY29uc3QgVmFsdWUmIFZhbHVlOjpkZWZhdWx0X2luc3RhbmNlKCkgeworICBpZiAoZGVmYXVsdF9pbnN0YW5jZV8gPT0gTlVMTCkgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZnN0cnVjdF8yZXByb3RvKCk7CisgIHJldHVybiAqZGVmYXVsdF9pbnN0YW5jZV87Cit9CisKK1ZhbHVlKiBWYWx1ZTo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBOVUxMOworCitWYWx1ZSogVmFsdWU6Ok5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3QgeworICBWYWx1ZSogbiA9IG5ldyBWYWx1ZTsKKyAgaWYgKGFyZW5hICE9IE5VTEwpIHsKKyAgICBhcmVuYS0+T3duKG4pOworICB9CisgIHJldHVybiBuOworfQorCit2b2lkIFZhbHVlOjpjbGVhcl9raW5kKCkgeworICBzd2l0Y2goa2luZF9jYXNlKCkpIHsKKyAgICBjYXNlIGtOdWxsVmFsdWU6IHsKKyAgICAgIC8vIE5vIG5lZWQgdG8gY2xlYXIKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIGtOdW1iZXJWYWx1ZTogeworICAgICAgLy8gTm8gbmVlZCB0byBjbGVhcgorICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2Uga1N0cmluZ1ZhbHVlOiB7CisgICAgICBraW5kXy5zdHJpbmdfdmFsdWVfLkRlc3Ryb3lOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBrQm9vbFZhbHVlOiB7CisgICAgICAvLyBObyBuZWVkIHRvIGNsZWFyCisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBrU3RydWN0VmFsdWU6IHsKKyAgICAgIGRlbGV0ZSBraW5kXy5zdHJ1Y3RfdmFsdWVfOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2Uga0xpc3RWYWx1ZTogeworICAgICAgZGVsZXRlIGtpbmRfLmxpc3RfdmFsdWVfOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgS0lORF9OT1RfU0VUOiB7CisgICAgICBicmVhazsKKyAgICB9CisgIH0KKyAgX29uZW9mX2Nhc2VfWzBdID0gS0lORF9OT1RfU0VUOworfQorCisKK3ZvaWQgVmFsdWU6OkNsZWFyKCkgeworICBjbGVhcl9raW5kKCk7Cit9CisKK2Jvb2wgVmFsdWU6Ok1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCkgeworI2RlZmluZSBET18oRVhQUkVTU0lPTikgaWYgKCEoRVhQUkVTU0lPTikpIGdvdG8gZmFpbHVyZQorICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiB0YWc7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdGFydDpnb29nbGUucHJvdG9idWYuVmFsdWUpCisgIGZvciAoOzspIHsKKyAgICA6OnN0ZDo6cGFpcjwgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIsIGJvb2w+IHAgPSBpbnB1dC0+UmVhZFRhZ1dpdGhDdXRvZmYoMTI3KTsKKyAgICB0YWcgPSBwLmZpcnN0OworICAgIGlmICghcC5zZWNvbmQpIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgc3dpdGNoICg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnRmllbGROdW1iZXIodGFnKSkgeworICAgICAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5OdWxsVmFsdWUgbnVsbF92YWx1ZSA9IDE7CisgICAgICBjYXNlIDE6IHsKKyAgICAgICAgaWYgKHRhZyA9PSA4KSB7CisgICAgICAgICAgaW50IHZhbHVlOworICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgaW50LCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9FTlVNPigKKyAgICAgICAgICAgICAgICAgaW5wdXQsICZ2YWx1ZSkpKTsKKyAgICAgICAgICBzZXRfbnVsbF92YWx1ZShzdGF0aWNfY2FzdDwgOjpnb29nbGU6OnByb3RvYnVmOjpOdWxsVmFsdWUgPih2YWx1ZSkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMTcpKSBnb3RvIHBhcnNlX251bWJlcl92YWx1ZTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIGRvdWJsZSBudW1iZXJfdmFsdWUgPSAyOworICAgICAgY2FzZSAyOiB7CisgICAgICAgIGlmICh0YWcgPT0gMTcpIHsKKyAgICAgICAgIHBhcnNlX251bWJlcl92YWx1ZToKKyAgICAgICAgICBjbGVhcl9raW5kKCk7CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICBkb3VibGUsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0RPVUJMRT4oCisgICAgICAgICAgICAgICAgIGlucHV0LCAma2luZF8ubnVtYmVyX3ZhbHVlXykpKTsKKyAgICAgICAgICBzZXRfaGFzX251bWJlcl92YWx1ZSgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMjYpKSBnb3RvIHBhcnNlX3N0cmluZ192YWx1ZTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIHN0cmluZyBzdHJpbmdfdmFsdWUgPSAzOworICAgICAgY2FzZSAzOiB7CisgICAgICAgIGlmICh0YWcgPT0gMjYpIHsKKyAgICAgICAgIHBhcnNlX3N0cmluZ192YWx1ZToKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoCisgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPm11dGFibGVfc3RyaW5nX3ZhbHVlKCkpKTsKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlZlcmlmeVV0ZjhTdHJpbmcoCisgICAgICAgICAgICB0aGlzLT5zdHJpbmdfdmFsdWUoKS5kYXRhKCksIHRoaXMtPnN0cmluZ192YWx1ZSgpLmxlbmd0aCgpLAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlBBUlNFLAorICAgICAgICAgICAgImdvb2dsZS5wcm90b2J1Zi5WYWx1ZS5zdHJpbmdfdmFsdWUiKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygzMikpIGdvdG8gcGFyc2VfYm9vbF92YWx1ZTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIGJvb2wgYm9vbF92YWx1ZSA9IDQ7CisgICAgICBjYXNlIDQ6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAzMikgeworICAgICAgICAgcGFyc2VfYm9vbF92YWx1ZToKKyAgICAgICAgICBjbGVhcl9raW5kKCk7CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICBib29sLCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9CT09MPigKKyAgICAgICAgICAgICAgICAgaW5wdXQsICZraW5kXy5ib29sX3ZhbHVlXykpKTsKKyAgICAgICAgICBzZXRfaGFzX2Jvb2xfdmFsdWUoKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDQyKSkgZ290byBwYXJzZV9zdHJ1Y3RfdmFsdWU7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCBzdHJ1Y3RfdmFsdWUgPSA1OworICAgICAgY2FzZSA1OiB7CisgICAgICAgIGlmICh0YWcgPT0gNDIpIHsKKyAgICAgICAgIHBhcnNlX3N0cnVjdF92YWx1ZToKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRNZXNzYWdlTm9WaXJ0dWFsKAorICAgICAgICAgICAgICAgaW5wdXQsIG11dGFibGVfc3RydWN0X3ZhbHVlKCkpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDUwKSkgZ290byBwYXJzZV9saXN0X3ZhbHVlOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5MaXN0VmFsdWUgbGlzdF92YWx1ZSA9IDY7CisgICAgICBjYXNlIDY6IHsKKyAgICAgICAgaWYgKHRhZyA9PSA1MCkgeworICAgICAgICAgcGFyc2VfbGlzdF92YWx1ZToKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRNZXNzYWdlTm9WaXJ0dWFsKAorICAgICAgICAgICAgICAgaW5wdXQsIG11dGFibGVfbGlzdF92YWx1ZSgpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdEF0RW5kKCkpIGdvdG8gc3VjY2VzczsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGRlZmF1bHQ6IHsKKyAgICAgIGhhbmRsZV91bnVzdWFsOgorICAgICAgICBpZiAodGFnID09IDAgfHwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdXaXJlVHlwZSh0YWcpID09CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRU5EX0dST1VQKSB7CisgICAgICAgICAgZ290byBzdWNjZXNzOworICAgICAgICB9CisgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U2tpcEZpZWxkKGlucHV0LCB0YWcpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CitzdWNjZXNzOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3VjY2Vzczpnb29nbGUucHJvdG9idWYuVmFsdWUpCisgIHJldHVybiB0cnVlOworZmFpbHVyZToKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX2ZhaWx1cmU6Z29vZ2xlLnByb3RvYnVmLlZhbHVlKQorICByZXR1cm4gZmFsc2U7CisjdW5kZWYgRE9fCit9CisKK3ZvaWQgVmFsdWU6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLlZhbHVlKQorICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLk51bGxWYWx1ZSBudWxsX3ZhbHVlID0gMTsKKyAgaWYgKGhhc19udWxsX3ZhbHVlKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVFbnVtKAorICAgICAgMSwgdGhpcy0+bnVsbF92YWx1ZSgpLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgZG91YmxlIG51bWJlcl92YWx1ZSA9IDI7CisgIGlmIChoYXNfbnVtYmVyX3ZhbHVlKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVEb3VibGUoMiwgdGhpcy0+bnVtYmVyX3ZhbHVlKCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgc3RyaW5nX3ZhbHVlID0gMzsKKyAgaWYgKGhhc19zdHJpbmdfdmFsdWUoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpWZXJpZnlVdGY4U3RyaW5nKAorICAgICAgdGhpcy0+c3RyaW5nX3ZhbHVlKCkuZGF0YSgpLCB0aGlzLT5zdHJpbmdfdmFsdWUoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLlZhbHVlLnN0cmluZ192YWx1ZSIpOworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ01heWJlQWxpYXNlZCgKKyAgICAgIDMsIHRoaXMtPnN0cmluZ192YWx1ZSgpLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgYm9vbCBib29sX3ZhbHVlID0gNDsKKyAgaWYgKGhhc19ib29sX3ZhbHVlKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCb29sKDQsIHRoaXMtPmJvb2xfdmFsdWUoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuU3RydWN0IHN0cnVjdF92YWx1ZSA9IDU7CisgIGlmIChoYXNfc3RydWN0X3ZhbHVlKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgNSwgKmtpbmRfLnN0cnVjdF92YWx1ZV8sIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkxpc3RWYWx1ZSBsaXN0X3ZhbHVlID0gNjsKKyAgaWYgKGhhc19saXN0X3ZhbHVlKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgNiwgKmtpbmRfLmxpc3RfdmFsdWVfLCBvdXRwdXQpOworICB9CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9lbmQ6Z29vZ2xlLnByb3RvYnVmLlZhbHVlKQorfQorCis6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBWYWx1ZTo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiB0YXJnZXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9zdGFydDpnb29nbGUucHJvdG9idWYuVmFsdWUpCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuTnVsbFZhbHVlIG51bGxfdmFsdWUgPSAxOworICBpZiAoaGFzX251bGxfdmFsdWUoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUVudW1Ub0FycmF5KAorICAgICAgMSwgdGhpcy0+bnVsbF92YWx1ZSgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgZG91YmxlIG51bWJlcl92YWx1ZSA9IDI7CisgIGlmIChoYXNfbnVtYmVyX3ZhbHVlKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVEb3VibGVUb0FycmF5KDIsIHRoaXMtPm51bWJlcl92YWx1ZSgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIHN0cmluZ192YWx1ZSA9IDM7CisgIGlmIChoYXNfc3RyaW5nX3ZhbHVlKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VmVyaWZ5VXRmOFN0cmluZygKKyAgICAgIHRoaXMtPnN0cmluZ192YWx1ZSgpLmRhdGEoKSwgdGhpcy0+c3RyaW5nX3ZhbHVlKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5WYWx1ZS5zdHJpbmdfdmFsdWUiKTsKKyAgICB0YXJnZXQgPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nVG9BcnJheSgKKyAgICAgICAgMywgdGhpcy0+c3RyaW5nX3ZhbHVlKCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBib29sIGJvb2xfdmFsdWUgPSA0OworICBpZiAoaGFzX2Jvb2xfdmFsdWUoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2xUb0FycmF5KDQsIHRoaXMtPmJvb2xfdmFsdWUoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuU3RydWN0IHN0cnVjdF92YWx1ZSA9IDU7CisgIGlmIChoYXNfc3RydWN0X3ZhbHVlKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6CisgICAgICBXcml0ZU1lc3NhZ2VOb1ZpcnR1YWxUb0FycmF5KAorICAgICAgICA1LCAqa2luZF8uc3RydWN0X3ZhbHVlXywgdGFyZ2V0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuTGlzdFZhbHVlIGxpc3RfdmFsdWUgPSA2OworICBpZiAoaGFzX2xpc3RfdmFsdWUoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjoKKyAgICAgIFdyaXRlTWVzc2FnZU5vVmlydHVhbFRvQXJyYXkoCisgICAgICAgIDYsICpraW5kXy5saXN0X3ZhbHVlXywgdGFyZ2V0KTsKKyAgfQorCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfZW5kOmdvb2dsZS5wcm90b2J1Zi5WYWx1ZSkKKyAgcmV0dXJuIHRhcmdldDsKK30KKworaW50IFZhbHVlOjpCeXRlU2l6ZSgpIGNvbnN0IHsKKyAgaW50IHRvdGFsX3NpemUgPSAwOworCisgIHN3aXRjaCAoa2luZF9jYXNlKCkpIHsKKyAgICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLk51bGxWYWx1ZSBudWxsX3ZhbHVlID0gMTsKKyAgICBjYXNlIGtOdWxsVmFsdWU6IHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpFbnVtU2l6ZSh0aGlzLT5udWxsX3ZhbHVlKCkpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIC8vIG9wdGlvbmFsIGRvdWJsZSBudW1iZXJfdmFsdWUgPSAyOworICAgIGNhc2Uga051bWJlclZhbHVlOiB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKyA4OworICAgICAgYnJlYWs7CisgICAgfQorICAgIC8vIG9wdGlvbmFsIHN0cmluZyBzdHJpbmdfdmFsdWUgPSAzOworICAgIGNhc2Uga1N0cmluZ1ZhbHVlOiB7CisgICAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U3RyaW5nU2l6ZSgKKyAgICAgICAgICB0aGlzLT5zdHJpbmdfdmFsdWUoKSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgLy8gb3B0aW9uYWwgYm9vbCBib29sX3ZhbHVlID0gNDsKKyAgICBjYXNlIGtCb29sVmFsdWU6IHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArIDE7CisgICAgICBicmVhazsKKyAgICB9CisgICAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3Qgc3RydWN0X3ZhbHVlID0gNTsKKyAgICBjYXNlIGtTdHJ1Y3RWYWx1ZTogeworICAgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1lc3NhZ2VTaXplTm9WaXJ0dWFsKAorICAgICAgICAgICpraW5kXy5zdHJ1Y3RfdmFsdWVfKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkxpc3RWYWx1ZSBsaXN0X3ZhbHVlID0gNjsKKyAgICBjYXNlIGtMaXN0VmFsdWU6IHsKKyAgICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpNZXNzYWdlU2l6ZU5vVmlydHVhbCgKKyAgICAgICAgICAqa2luZF8ubGlzdF92YWx1ZV8pOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgS0lORF9OT1RfU0VUOiB7CisgICAgICBicmVhazsKKyAgICB9CisgIH0KKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHRvdGFsX3NpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworICByZXR1cm4gdG90YWxfc2l6ZTsKK30KKwordm9pZCBWYWx1ZTo6TWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBjb25zdCBWYWx1ZSogc291cmNlID0gCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpEeW5hbWljQ2FzdFRvR2VuZXJhdGVkPGNvbnN0IFZhbHVlPigKKyAgICAgICAgICAmZnJvbSk7CisgIGlmIChzb3VyY2UgPT0gTlVMTCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlJlZmxlY3Rpb25PcHM6Ok1lcmdlKGZyb20sIHRoaXMpOworICB9IGVsc2UgeworICAgIE1lcmdlRnJvbSgqc291cmNlKTsKKyAgfQorfQorCit2b2lkIFZhbHVlOjpNZXJnZUZyb20oY29uc3QgVmFsdWUmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgc3dpdGNoIChmcm9tLmtpbmRfY2FzZSgpKSB7CisgICAgY2FzZSBrTnVsbFZhbHVlOiB7CisgICAgICBzZXRfbnVsbF92YWx1ZShmcm9tLm51bGxfdmFsdWUoKSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBrTnVtYmVyVmFsdWU6IHsKKyAgICAgIHNldF9udW1iZXJfdmFsdWUoZnJvbS5udW1iZXJfdmFsdWUoKSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBrU3RyaW5nVmFsdWU6IHsKKyAgICAgIHNldF9zdHJpbmdfdmFsdWUoZnJvbS5zdHJpbmdfdmFsdWUoKSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBrQm9vbFZhbHVlOiB7CisgICAgICBzZXRfYm9vbF92YWx1ZShmcm9tLmJvb2xfdmFsdWUoKSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBrU3RydWN0VmFsdWU6IHsKKyAgICAgIG11dGFibGVfc3RydWN0X3ZhbHVlKCktPjo6Z29vZ2xlOjpwcm90b2J1Zjo6U3RydWN0OjpNZXJnZUZyb20oZnJvbS5zdHJ1Y3RfdmFsdWUoKSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBrTGlzdFZhbHVlOiB7CisgICAgICBtdXRhYmxlX2xpc3RfdmFsdWUoKS0+Ojpnb29nbGU6OnByb3RvYnVmOjpMaXN0VmFsdWU6Ok1lcmdlRnJvbShmcm9tLmxpc3RfdmFsdWUoKSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBLSU5EX05PVF9TRVQ6IHsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgfQorfQorCit2b2lkIFZhbHVlOjpDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCit2b2lkIFZhbHVlOjpDb3B5RnJvbShjb25zdCBWYWx1ZSYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK2Jvb2wgVmFsdWU6OklzSW5pdGlhbGl6ZWQoKSBjb25zdCB7CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgVmFsdWU6OlN3YXAoVmFsdWUqIG90aGVyKSB7CisgIGlmIChvdGhlciA9PSB0aGlzKSByZXR1cm47CisgIEludGVybmFsU3dhcChvdGhlcik7Cit9Cit2b2lkIFZhbHVlOjpJbnRlcm5hbFN3YXAoVmFsdWUqIG90aGVyKSB7CisgIHN0ZDo6c3dhcChraW5kXywgb3RoZXItPmtpbmRfKTsKKyAgc3RkOjpzd2FwKF9vbmVvZl9jYXNlX1swXSwgb3RoZXItPl9vbmVvZl9jYXNlX1swXSk7CisgIF9pbnRlcm5hbF9tZXRhZGF0YV8uU3dhcCgmb3RoZXItPl9pbnRlcm5hbF9tZXRhZGF0YV8pOworICBzdGQ6OnN3YXAoX2NhY2hlZF9zaXplXywgb3RoZXItPl9jYWNoZWRfc2l6ZV8pOworfQorCis6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIFZhbHVlOjpHZXRNZXRhZGF0YSgpIGNvbnN0IHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgbWV0YWRhdGE7CisgIG1ldGFkYXRhLmRlc2NyaXB0b3IgPSBWYWx1ZV9kZXNjcmlwdG9yXzsKKyAgbWV0YWRhdGEucmVmbGVjdGlvbiA9IFZhbHVlX3JlZmxlY3Rpb25fOworICByZXR1cm4gbWV0YWRhdGE7Cit9CisKKyNpZiBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKy8vIFZhbHVlCisKKy8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuTnVsbFZhbHVlIG51bGxfdmFsdWUgPSAxOworYm9vbCBWYWx1ZTo6aGFzX251bGxfdmFsdWUoKSBjb25zdCB7CisgIHJldHVybiBraW5kX2Nhc2UoKSA9PSBrTnVsbFZhbHVlOworfQordm9pZCBWYWx1ZTo6c2V0X2hhc19udWxsX3ZhbHVlKCkgeworICBfb25lb2ZfY2FzZV9bMF0gPSBrTnVsbFZhbHVlOworfQordm9pZCBWYWx1ZTo6Y2xlYXJfbnVsbF92YWx1ZSgpIHsKKyAgaWYgKGhhc19udWxsX3ZhbHVlKCkpIHsKKyAgICBraW5kXy5udWxsX3ZhbHVlXyA9IDA7CisgICAgY2xlYXJfaGFzX2tpbmQoKTsKKyAgfQorfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TnVsbFZhbHVlIFZhbHVlOjpudWxsX3ZhbHVlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5WYWx1ZS5udWxsX3ZhbHVlKQorICBpZiAoaGFzX251bGxfdmFsdWUoKSkgeworICAgIHJldHVybiBzdGF0aWNfY2FzdDwgOjpnb29nbGU6OnByb3RvYnVmOjpOdWxsVmFsdWUgPihraW5kXy5udWxsX3ZhbHVlXyk7CisgIH0KKyAgcmV0dXJuIHN0YXRpY19jYXN0PCA6Omdvb2dsZTo6cHJvdG9idWY6Ok51bGxWYWx1ZSA+KDApOworfQorIHZvaWQgVmFsdWU6OnNldF9udWxsX3ZhbHVlKDo6Z29vZ2xlOjpwcm90b2J1Zjo6TnVsbFZhbHVlIHZhbHVlKSB7CisgIGlmICghaGFzX251bGxfdmFsdWUoKSkgeworICAgIGNsZWFyX2tpbmQoKTsKKyAgICBzZXRfaGFzX251bGxfdmFsdWUoKTsKKyAgfQorICBraW5kXy5udWxsX3ZhbHVlXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5WYWx1ZS5udWxsX3ZhbHVlKQorfQorCisvLyBvcHRpb25hbCBkb3VibGUgbnVtYmVyX3ZhbHVlID0gMjsKK2Jvb2wgVmFsdWU6Omhhc19udW1iZXJfdmFsdWUoKSBjb25zdCB7CisgIHJldHVybiBraW5kX2Nhc2UoKSA9PSBrTnVtYmVyVmFsdWU7Cit9Cit2b2lkIFZhbHVlOjpzZXRfaGFzX251bWJlcl92YWx1ZSgpIHsKKyAgX29uZW9mX2Nhc2VfWzBdID0ga051bWJlclZhbHVlOworfQordm9pZCBWYWx1ZTo6Y2xlYXJfbnVtYmVyX3ZhbHVlKCkgeworICBpZiAoaGFzX251bWJlcl92YWx1ZSgpKSB7CisgICAga2luZF8ubnVtYmVyX3ZhbHVlXyA9IDA7CisgICAgY2xlYXJfaGFzX2tpbmQoKTsKKyAgfQorfQorIGRvdWJsZSBWYWx1ZTo6bnVtYmVyX3ZhbHVlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5WYWx1ZS5udW1iZXJfdmFsdWUpCisgIGlmIChoYXNfbnVtYmVyX3ZhbHVlKCkpIHsKKyAgICByZXR1cm4ga2luZF8ubnVtYmVyX3ZhbHVlXzsKKyAgfQorICByZXR1cm4gMDsKK30KKyB2b2lkIFZhbHVlOjpzZXRfbnVtYmVyX3ZhbHVlKGRvdWJsZSB2YWx1ZSkgeworICBpZiAoIWhhc19udW1iZXJfdmFsdWUoKSkgeworICAgIGNsZWFyX2tpbmQoKTsKKyAgICBzZXRfaGFzX251bWJlcl92YWx1ZSgpOworICB9CisgIGtpbmRfLm51bWJlcl92YWx1ZV8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuVmFsdWUubnVtYmVyX3ZhbHVlKQorfQorCisvLyBvcHRpb25hbCBzdHJpbmcgc3RyaW5nX3ZhbHVlID0gMzsKK2Jvb2wgVmFsdWU6Omhhc19zdHJpbmdfdmFsdWUoKSBjb25zdCB7CisgIHJldHVybiBraW5kX2Nhc2UoKSA9PSBrU3RyaW5nVmFsdWU7Cit9Cit2b2lkIFZhbHVlOjpzZXRfaGFzX3N0cmluZ192YWx1ZSgpIHsKKyAgX29uZW9mX2Nhc2VfWzBdID0ga1N0cmluZ1ZhbHVlOworfQordm9pZCBWYWx1ZTo6Y2xlYXJfc3RyaW5nX3ZhbHVlKCkgeworICBpZiAoaGFzX3N0cmluZ192YWx1ZSgpKSB7CisgICAga2luZF8uc3RyaW5nX3ZhbHVlXy5EZXN0cm95Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICAgIGNsZWFyX2hhc19raW5kKCk7CisgIH0KK30KKyBjb25zdCA6OnN0ZDo6c3RyaW5nJiBWYWx1ZTo6c3RyaW5nX3ZhbHVlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5WYWx1ZS5zdHJpbmdfdmFsdWUpCisgIGlmIChoYXNfc3RyaW5nX3ZhbHVlKCkpIHsKKyAgICByZXR1cm4ga2luZF8uc3RyaW5nX3ZhbHVlXy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIH0KKyAgcmV0dXJuIComOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCk7Cit9Cisgdm9pZCBWYWx1ZTo6c2V0X3N0cmluZ192YWx1ZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5WYWx1ZS5zdHJpbmdfdmFsdWUpCisgIGlmICghaGFzX3N0cmluZ192YWx1ZSgpKSB7CisgICAgY2xlYXJfa2luZCgpOworICAgIHNldF9oYXNfc3RyaW5nX3ZhbHVlKCk7CisgICAga2luZF8uc3RyaW5nX3ZhbHVlXy5VbnNhZmVTZXREZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIH0KKyAga2luZF8uc3RyaW5nX3ZhbHVlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5WYWx1ZS5zdHJpbmdfdmFsdWUpCit9Cisgdm9pZCBWYWx1ZTo6c2V0X3N0cmluZ192YWx1ZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBpZiAoIWhhc19zdHJpbmdfdmFsdWUoKSkgeworICAgIGNsZWFyX2tpbmQoKTsKKyAgICBzZXRfaGFzX3N0cmluZ192YWx1ZSgpOworICAgIGtpbmRfLnN0cmluZ192YWx1ZV8uVW5zYWZlU2V0RGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICB9CisgIGtpbmRfLnN0cmluZ192YWx1ZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuVmFsdWUuc3RyaW5nX3ZhbHVlKQorfQorIHZvaWQgVmFsdWU6OnNldF9zdHJpbmdfdmFsdWUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIGlmICghaGFzX3N0cmluZ192YWx1ZSgpKSB7CisgICAgY2xlYXJfa2luZCgpOworICAgIHNldF9oYXNfc3RyaW5nX3ZhbHVlKCk7CisgICAga2luZF8uc3RyaW5nX3ZhbHVlXy5VbnNhZmVTZXREZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIH0KKyAga2luZF8uc3RyaW5nX3ZhbHVlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZygKKyAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLlZhbHVlLnN0cmluZ192YWx1ZSkKK30KKyA6OnN0ZDo6c3RyaW5nKiBWYWx1ZTo6bXV0YWJsZV9zdHJpbmdfdmFsdWUoKSB7CisgIGlmICghaGFzX3N0cmluZ192YWx1ZSgpKSB7CisgICAgY2xlYXJfa2luZCgpOworICAgIHNldF9oYXNfc3RyaW5nX3ZhbHVlKCk7CisgICAga2luZF8uc3RyaW5nX3ZhbHVlXy5VbnNhZmVTZXREZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLlZhbHVlLnN0cmluZ192YWx1ZSkKKyAgcmV0dXJuIGtpbmRfLnN0cmluZ192YWx1ZV8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyA6OnN0ZDo6c3RyaW5nKiBWYWx1ZTo6cmVsZWFzZV9zdHJpbmdfdmFsdWUoKSB7CisgIGlmIChoYXNfc3RyaW5nX3ZhbHVlKCkpIHsKKyAgICBjbGVhcl9oYXNfa2luZCgpOworICAgIHJldHVybiBraW5kXy5zdHJpbmdfdmFsdWVfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KK30KKyB2b2lkIFZhbHVlOjpzZXRfYWxsb2NhdGVkX3N0cmluZ192YWx1ZSg6OnN0ZDo6c3RyaW5nKiBzdHJpbmdfdmFsdWUpIHsKKyAgaWYgKCFoYXNfc3RyaW5nX3ZhbHVlKCkpIHsKKyAgICBraW5kXy5zdHJpbmdfdmFsdWVfLlVuc2FmZVNldERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgfQorICBjbGVhcl9raW5kKCk7CisgIGlmIChzdHJpbmdfdmFsdWUgIT0gTlVMTCkgeworICAgIHNldF9oYXNfc3RyaW5nX3ZhbHVlKCk7CisgICAga2luZF8uc3RyaW5nX3ZhbHVlXy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgICAgc3RyaW5nX3ZhbHVlKTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuVmFsdWUuc3RyaW5nX3ZhbHVlKQorfQorCisvLyBvcHRpb25hbCBib29sIGJvb2xfdmFsdWUgPSA0OworYm9vbCBWYWx1ZTo6aGFzX2Jvb2xfdmFsdWUoKSBjb25zdCB7CisgIHJldHVybiBraW5kX2Nhc2UoKSA9PSBrQm9vbFZhbHVlOworfQordm9pZCBWYWx1ZTo6c2V0X2hhc19ib29sX3ZhbHVlKCkgeworICBfb25lb2ZfY2FzZV9bMF0gPSBrQm9vbFZhbHVlOworfQordm9pZCBWYWx1ZTo6Y2xlYXJfYm9vbF92YWx1ZSgpIHsKKyAgaWYgKGhhc19ib29sX3ZhbHVlKCkpIHsKKyAgICBraW5kXy5ib29sX3ZhbHVlXyA9IGZhbHNlOworICAgIGNsZWFyX2hhc19raW5kKCk7CisgIH0KK30KKyBib29sIFZhbHVlOjpib29sX3ZhbHVlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5WYWx1ZS5ib29sX3ZhbHVlKQorICBpZiAoaGFzX2Jvb2xfdmFsdWUoKSkgeworICAgIHJldHVybiBraW5kXy5ib29sX3ZhbHVlXzsKKyAgfQorICByZXR1cm4gZmFsc2U7Cit9Cisgdm9pZCBWYWx1ZTo6c2V0X2Jvb2xfdmFsdWUoYm9vbCB2YWx1ZSkgeworICBpZiAoIWhhc19ib29sX3ZhbHVlKCkpIHsKKyAgICBjbGVhcl9raW5kKCk7CisgICAgc2V0X2hhc19ib29sX3ZhbHVlKCk7CisgIH0KKyAga2luZF8uYm9vbF92YWx1ZV8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuVmFsdWUuYm9vbF92YWx1ZSkKK30KKworLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3Qgc3RydWN0X3ZhbHVlID0gNTsKK2Jvb2wgVmFsdWU6Omhhc19zdHJ1Y3RfdmFsdWUoKSBjb25zdCB7CisgIHJldHVybiBraW5kX2Nhc2UoKSA9PSBrU3RydWN0VmFsdWU7Cit9Cit2b2lkIFZhbHVlOjpzZXRfaGFzX3N0cnVjdF92YWx1ZSgpIHsKKyAgX29uZW9mX2Nhc2VfWzBdID0ga1N0cnVjdFZhbHVlOworfQordm9pZCBWYWx1ZTo6Y2xlYXJfc3RydWN0X3ZhbHVlKCkgeworICBpZiAoaGFzX3N0cnVjdF92YWx1ZSgpKSB7CisgICAgZGVsZXRlIGtpbmRfLnN0cnVjdF92YWx1ZV87CisgICAgY2xlYXJfaGFzX2tpbmQoKTsKKyAgfQorfQorIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6U3RydWN0JiBWYWx1ZTo6c3RydWN0X3ZhbHVlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5WYWx1ZS5zdHJ1Y3RfdmFsdWUpCisgIHJldHVybiBoYXNfc3RydWN0X3ZhbHVlKCkKKyAgICAgID8gKmtpbmRfLnN0cnVjdF92YWx1ZV8KKyAgICAgIDogOjpnb29nbGU6OnByb3RvYnVmOjpTdHJ1Y3Q6OmRlZmF1bHRfaW5zdGFuY2UoKTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6U3RydWN0KiBWYWx1ZTo6bXV0YWJsZV9zdHJ1Y3RfdmFsdWUoKSB7CisgIGlmICghaGFzX3N0cnVjdF92YWx1ZSgpKSB7CisgICAgY2xlYXJfa2luZCgpOworICAgIHNldF9oYXNfc3RydWN0X3ZhbHVlKCk7CisgICAga2luZF8uc3RydWN0X3ZhbHVlXyA9IG5ldyA6Omdvb2dsZTo6cHJvdG9idWY6OlN0cnVjdDsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuVmFsdWUuc3RydWN0X3ZhbHVlKQorICByZXR1cm4ga2luZF8uc3RydWN0X3ZhbHVlXzsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6U3RydWN0KiBWYWx1ZTo6cmVsZWFzZV9zdHJ1Y3RfdmFsdWUoKSB7CisgIGlmIChoYXNfc3RydWN0X3ZhbHVlKCkpIHsKKyAgICBjbGVhcl9oYXNfa2luZCgpOworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6U3RydWN0KiB0ZW1wID0ga2luZF8uc3RydWN0X3ZhbHVlXzsKKyAgICBraW5kXy5zdHJ1Y3RfdmFsdWVfID0gTlVMTDsKKyAgICByZXR1cm4gdGVtcDsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorfQordm9pZCBWYWx1ZTo6c2V0X2FsbG9jYXRlZF9zdHJ1Y3RfdmFsdWUoOjpnb29nbGU6OnByb3RvYnVmOjpTdHJ1Y3QqIHN0cnVjdF92YWx1ZSkgeworICBjbGVhcl9raW5kKCk7CisgIGlmIChzdHJ1Y3RfdmFsdWUpIHsKKyAgICBzZXRfaGFzX3N0cnVjdF92YWx1ZSgpOworICAgIGtpbmRfLnN0cnVjdF92YWx1ZV8gPSBzdHJ1Y3RfdmFsdWU7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLlZhbHVlLnN0cnVjdF92YWx1ZSkKK30KKworLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5MaXN0VmFsdWUgbGlzdF92YWx1ZSA9IDY7Citib29sIFZhbHVlOjpoYXNfbGlzdF92YWx1ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIGtpbmRfY2FzZSgpID09IGtMaXN0VmFsdWU7Cit9Cit2b2lkIFZhbHVlOjpzZXRfaGFzX2xpc3RfdmFsdWUoKSB7CisgIF9vbmVvZl9jYXNlX1swXSA9IGtMaXN0VmFsdWU7Cit9Cit2b2lkIFZhbHVlOjpjbGVhcl9saXN0X3ZhbHVlKCkgeworICBpZiAoaGFzX2xpc3RfdmFsdWUoKSkgeworICAgIGRlbGV0ZSBraW5kXy5saXN0X3ZhbHVlXzsKKyAgICBjbGVhcl9oYXNfa2luZCgpOworICB9Cit9CisgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpMaXN0VmFsdWUmIFZhbHVlOjpsaXN0X3ZhbHVlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5WYWx1ZS5saXN0X3ZhbHVlKQorICByZXR1cm4gaGFzX2xpc3RfdmFsdWUoKQorICAgICAgPyAqa2luZF8ubGlzdF92YWx1ZV8KKyAgICAgIDogOjpnb29nbGU6OnByb3RvYnVmOjpMaXN0VmFsdWU6OmRlZmF1bHRfaW5zdGFuY2UoKTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6TGlzdFZhbHVlKiBWYWx1ZTo6bXV0YWJsZV9saXN0X3ZhbHVlKCkgeworICBpZiAoIWhhc19saXN0X3ZhbHVlKCkpIHsKKyAgICBjbGVhcl9raW5kKCk7CisgICAgc2V0X2hhc19saXN0X3ZhbHVlKCk7CisgICAga2luZF8ubGlzdF92YWx1ZV8gPSBuZXcgOjpnb29nbGU6OnByb3RvYnVmOjpMaXN0VmFsdWU7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLlZhbHVlLmxpc3RfdmFsdWUpCisgIHJldHVybiBraW5kXy5saXN0X3ZhbHVlXzsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6TGlzdFZhbHVlKiBWYWx1ZTo6cmVsZWFzZV9saXN0X3ZhbHVlKCkgeworICBpZiAoaGFzX2xpc3RfdmFsdWUoKSkgeworICAgIGNsZWFyX2hhc19raW5kKCk7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjpMaXN0VmFsdWUqIHRlbXAgPSBraW5kXy5saXN0X3ZhbHVlXzsKKyAgICBraW5kXy5saXN0X3ZhbHVlXyA9IE5VTEw7CisgICAgcmV0dXJuIHRlbXA7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KK30KK3ZvaWQgVmFsdWU6OnNldF9hbGxvY2F0ZWRfbGlzdF92YWx1ZSg6Omdvb2dsZTo6cHJvdG9idWY6Okxpc3RWYWx1ZSogbGlzdF92YWx1ZSkgeworICBjbGVhcl9raW5kKCk7CisgIGlmIChsaXN0X3ZhbHVlKSB7CisgICAgc2V0X2hhc19saXN0X3ZhbHVlKCk7CisgICAga2luZF8ubGlzdF92YWx1ZV8gPSBsaXN0X3ZhbHVlOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5WYWx1ZS5saXN0X3ZhbHVlKQorfQorCitib29sIFZhbHVlOjpoYXNfa2luZCgpIGNvbnN0IHsKKyAgcmV0dXJuIGtpbmRfY2FzZSgpICE9IEtJTkRfTk9UX1NFVDsKK30KK3ZvaWQgVmFsdWU6OmNsZWFyX2hhc19raW5kKCkgeworICBfb25lb2ZfY2FzZV9bMF0gPSBLSU5EX05PVF9TRVQ7Cit9CitWYWx1ZTo6S2luZENhc2UgVmFsdWU6OmtpbmRfY2FzZSgpIGNvbnN0IHsKKyAgcmV0dXJuIFZhbHVlOjpLaW5kQ2FzZShfb25lb2ZfY2FzZV9bMF0pOworfQorI2VuZGlmICAvLyBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisjaWYgIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKK2NvbnN0IGludCBMaXN0VmFsdWU6OmtWYWx1ZXNGaWVsZE51bWJlcjsKKyNlbmRpZiAgLy8gIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKKworTGlzdFZhbHVlOjpMaXN0VmFsdWUoKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpLCBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLkxpc3RWYWx1ZSkKK30KKwordm9pZCBMaXN0VmFsdWU6OkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpIHsKKyAgX2lzX2RlZmF1bHRfaW5zdGFuY2VfID0gdHJ1ZTsKK30KKworTGlzdFZhbHVlOjpMaXN0VmFsdWUoY29uc3QgTGlzdFZhbHVlJiBmcm9tKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpLAorICAgIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgeworICBTaGFyZWRDdG9yKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvcHlfY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLkxpc3RWYWx1ZSkKK30KKwordm9pZCBMaXN0VmFsdWU6OlNoYXJlZEN0b3IoKSB7CisgICAgX2lzX2RlZmF1bHRfaW5zdGFuY2VfID0gZmFsc2U7CisgIF9jYWNoZWRfc2l6ZV8gPSAwOworfQorCitMaXN0VmFsdWU6On5MaXN0VmFsdWUoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChkZXN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5MaXN0VmFsdWUpCisgIFNoYXJlZER0b3IoKTsKK30KKwordm9pZCBMaXN0VmFsdWU6OlNoYXJlZER0b3IoKSB7CisgIGlmICh0aGlzICE9IGRlZmF1bHRfaW5zdGFuY2VfKSB7CisgIH0KK30KKwordm9pZCBMaXN0VmFsdWU6OlNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0IHsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHNpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBMaXN0VmFsdWU6OmRlc2NyaXB0b3IoKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICByZXR1cm4gTGlzdFZhbHVlX2Rlc2NyaXB0b3JfOworfQorCitjb25zdCBMaXN0VmFsdWUmIExpc3RWYWx1ZTo6ZGVmYXVsdF9pbnN0YW5jZSgpIHsKKyAgaWYgKGRlZmF1bHRfaW5zdGFuY2VfID09IE5VTEwpIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZzdHJ1Y3RfMmVwcm90bygpOworICByZXR1cm4gKmRlZmF1bHRfaW5zdGFuY2VfOworfQorCitMaXN0VmFsdWUqIExpc3RWYWx1ZTo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBOVUxMOworCitMaXN0VmFsdWUqIExpc3RWYWx1ZTo6TmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdCB7CisgIExpc3RWYWx1ZSogbiA9IG5ldyBMaXN0VmFsdWU7CisgIGlmIChhcmVuYSAhPSBOVUxMKSB7CisgICAgYXJlbmEtPk93bihuKTsKKyAgfQorICByZXR1cm4gbjsKK30KKwordm9pZCBMaXN0VmFsdWU6OkNsZWFyKCkgeworICB2YWx1ZXNfLkNsZWFyKCk7Cit9CisKK2Jvb2wgTGlzdFZhbHVlOjpNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyNkZWZpbmUgRE9fKEVYUFJFU1NJT04pIGlmICghKEVYUFJFU1NJT04pKSBnb3RvIGZhaWx1cmUKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgdGFnOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkxpc3RWYWx1ZSkKKyAgZm9yICg7OykgeworICAgIDo6c3RkOjpwYWlyPCA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiwgYm9vbD4gcCA9IGlucHV0LT5SZWFkVGFnV2l0aEN1dG9mZigxMjcpOworICAgIHRhZyA9IHAuZmlyc3Q7CisgICAgaWYgKCFwLnNlY29uZCkgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICBzd2l0Y2ggKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdGaWVsZE51bWJlcih0YWcpKSB7CisgICAgICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlZhbHVlIHZhbHVlcyA9IDE7CisgICAgICBjYXNlIDE6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAxMCkgeworICAgICAgICAgIERPXyhpbnB1dC0+SW5jcmVtZW50UmVjdXJzaW9uRGVwdGgoKSk7CisgICAgICAgICBwYXJzZV9sb29wX3ZhbHVlczoKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRNZXNzYWdlTm9WaXJ0dWFsTm9SZWN1cnNpb25EZXB0aCgKKyAgICAgICAgICAgICAgICBpbnB1dCwgYWRkX3ZhbHVlcygpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygxMCkpIGdvdG8gcGFyc2VfbG9vcF92YWx1ZXM7CisgICAgICAgIGlucHV0LT5VbnNhZmVEZWNyZW1lbnRSZWN1cnNpb25EZXB0aCgpOworICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdEF0RW5kKCkpIGdvdG8gc3VjY2VzczsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGRlZmF1bHQ6IHsKKyAgICAgIGhhbmRsZV91bnVzdWFsOgorICAgICAgICBpZiAodGFnID09IDAgfHwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdXaXJlVHlwZSh0YWcpID09CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRU5EX0dST1VQKSB7CisgICAgICAgICAgZ290byBzdWNjZXNzOworICAgICAgICB9CisgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U2tpcEZpZWxkKGlucHV0LCB0YWcpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CitzdWNjZXNzOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3VjY2Vzczpnb29nbGUucHJvdG9idWYuTGlzdFZhbHVlKQorICByZXR1cm4gdHJ1ZTsKK2ZhaWx1cmU6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9mYWlsdXJlOmdvb2dsZS5wcm90b2J1Zi5MaXN0VmFsdWUpCisgIHJldHVybiBmYWxzZTsKKyN1bmRlZiBET18KK30KKwordm9pZCBMaXN0VmFsdWU6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkxpc3RWYWx1ZSkKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5WYWx1ZSB2YWx1ZXMgPSAxOworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPnZhbHVlc19zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgMSwgdGhpcy0+dmFsdWVzKGkpLCBvdXRwdXQpOworICB9CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9lbmQ6Z29vZ2xlLnByb3RvYnVmLkxpc3RWYWx1ZSkKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogTGlzdFZhbHVlOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIHRhcmdldCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5MaXN0VmFsdWUpCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVmFsdWUgdmFsdWVzID0gMTsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT52YWx1ZXNfc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OgorICAgICAgV3JpdGVNZXNzYWdlTm9WaXJ0dWFsVG9BcnJheSgKKyAgICAgICAgMSwgdGhpcy0+dmFsdWVzKGkpLCB0YXJnZXQpOworICB9CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9lbmQ6Z29vZ2xlLnByb3RvYnVmLkxpc3RWYWx1ZSkKKyAgcmV0dXJuIHRhcmdldDsKK30KKworaW50IExpc3RWYWx1ZTo6Qnl0ZVNpemUoKSBjb25zdCB7CisgIGludCB0b3RhbF9zaXplID0gMDsKKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlZhbHVlIHZhbHVlcyA9IDE7CisgIHRvdGFsX3NpemUgKz0gMSAqIHRoaXMtPnZhbHVlc19zaXplKCk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+dmFsdWVzX3NpemUoKTsgaSsrKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1lc3NhZ2VTaXplTm9WaXJ0dWFsKAorICAgICAgICB0aGlzLT52YWx1ZXMoaSkpOworICB9CisKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHRvdGFsX3NpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworICByZXR1cm4gdG90YWxfc2l6ZTsKK30KKwordm9pZCBMaXN0VmFsdWU6Ok1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgY29uc3QgTGlzdFZhbHVlKiBzb3VyY2UgPSAKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkR5bmFtaWNDYXN0VG9HZW5lcmF0ZWQ8Y29uc3QgTGlzdFZhbHVlPigKKyAgICAgICAgICAmZnJvbSk7CisgIGlmIChzb3VyY2UgPT0gTlVMTCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlJlZmxlY3Rpb25PcHM6Ok1lcmdlKGZyb20sIHRoaXMpOworICB9IGVsc2UgeworICAgIE1lcmdlRnJvbSgqc291cmNlKTsKKyAgfQorfQorCit2b2lkIExpc3RWYWx1ZTo6TWVyZ2VGcm9tKGNvbnN0IExpc3RWYWx1ZSYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICB2YWx1ZXNfLk1lcmdlRnJvbShmcm9tLnZhbHVlc18pOworfQorCit2b2lkIExpc3RWYWx1ZTo6Q29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKwordm9pZCBMaXN0VmFsdWU6OkNvcHlGcm9tKGNvbnN0IExpc3RWYWx1ZSYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK2Jvb2wgTGlzdFZhbHVlOjpJc0luaXRpYWxpemVkKCkgY29uc3QgeworCisgIHJldHVybiB0cnVlOworfQorCit2b2lkIExpc3RWYWx1ZTo6U3dhcChMaXN0VmFsdWUqIG90aGVyKSB7CisgIGlmIChvdGhlciA9PSB0aGlzKSByZXR1cm47CisgIEludGVybmFsU3dhcChvdGhlcik7Cit9Cit2b2lkIExpc3RWYWx1ZTo6SW50ZXJuYWxTd2FwKExpc3RWYWx1ZSogb3RoZXIpIHsKKyAgdmFsdWVzXy5VbnNhZmVBcmVuYVN3YXAoJm90aGVyLT52YWx1ZXNfKTsKKyAgX2ludGVybmFsX21ldGFkYXRhXy5Td2FwKCZvdGhlci0+X2ludGVybmFsX21ldGFkYXRhXyk7CisgIHN0ZDo6c3dhcChfY2FjaGVkX3NpemVfLCBvdGhlci0+X2NhY2hlZF9zaXplXyk7Cit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgTGlzdFZhbHVlOjpHZXRNZXRhZGF0YSgpIGNvbnN0IHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgbWV0YWRhdGE7CisgIG1ldGFkYXRhLmRlc2NyaXB0b3IgPSBMaXN0VmFsdWVfZGVzY3JpcHRvcl87CisgIG1ldGFkYXRhLnJlZmxlY3Rpb24gPSBMaXN0VmFsdWVfcmVmbGVjdGlvbl87CisgIHJldHVybiBtZXRhZGF0YTsKK30KKworI2lmIFBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworLy8gTGlzdFZhbHVlCisKKy8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVmFsdWUgdmFsdWVzID0gMTsKK2ludCBMaXN0VmFsdWU6OnZhbHVlc19zaXplKCkgY29uc3QgeworICByZXR1cm4gdmFsdWVzXy5zaXplKCk7Cit9Cit2b2lkIExpc3RWYWx1ZTo6Y2xlYXJfdmFsdWVzKCkgeworICB2YWx1ZXNfLkNsZWFyKCk7Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlZhbHVlJiBMaXN0VmFsdWU6OnZhbHVlcyhpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuTGlzdFZhbHVlLnZhbHVlcykKKyAgcmV0dXJuIHZhbHVlc18uR2V0KGluZGV4KTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6VmFsdWUqIExpc3RWYWx1ZTo6bXV0YWJsZV92YWx1ZXMoaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5MaXN0VmFsdWUudmFsdWVzKQorICByZXR1cm4gdmFsdWVzXy5NdXRhYmxlKGluZGV4KTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6VmFsdWUqIExpc3RWYWx1ZTo6YWRkX3ZhbHVlcygpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuTGlzdFZhbHVlLnZhbHVlcykKKyAgcmV0dXJuIHZhbHVlc18uQWRkKCk7Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VmFsdWUgPioKK0xpc3RWYWx1ZTo6bXV0YWJsZV92YWx1ZXMoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkxpc3RWYWx1ZS52YWx1ZXMpCisgIHJldHVybiAmdmFsdWVzXzsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpWYWx1ZSA+JgorTGlzdFZhbHVlOjp2YWx1ZXMoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5MaXN0VmFsdWUudmFsdWVzKQorICByZXR1cm4gdmFsdWVzXzsKK30KKworI2VuZGlmICAvLyBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKworLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG5hbWVzcGFjZV9zY29wZSkKKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKy8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChnbG9iYWxfc2NvcGUpCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0cnVjdC5wYi5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHJ1Y3QucGIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wNTI3YzgxCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHJ1Y3QucGIuaApAQCAtMCwwICsxLDc2NiBAQAorLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCEKKy8vIHNvdXJjZTogZ29vZ2xlL3Byb3RvYnVmL3N0cnVjdC5wcm90bworCisjaWZuZGVmIFBST1RPQlVGX2dvb2dsZV8yZnByb3RvYnVmXzJmc3RydWN0XzJlcHJvdG9fX0lOQ0xVREVECisjZGVmaW5lIFBST1RPQlVGX2dvb2dsZV8yZnByb3RvYnVmXzJmc3RydWN0XzJlcHJvdG9fX0lOQ0xVREVECisKKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisKKyNpZiBHT09HTEVfUFJPVE9CVUZfVkVSU0lPTiA8IDMwMDAwMDAKKyNlcnJvciBUaGlzIGZpbGUgd2FzIGdlbmVyYXRlZCBieSBhIG5ld2VyIHZlcnNpb24gb2YgcHJvdG9jIHdoaWNoIGlzCisjZXJyb3IgaW5jb21wYXRpYmxlIHdpdGggeW91ciBQcm90b2NvbCBCdWZmZXIgaGVhZGVycy4gIFBsZWFzZSB1cGRhdGUKKyNlcnJvciB5b3VyIGhlYWRlcnMuCisjZW5kaWYKKyNpZiAzMDAwMDAwIDwgR09PR0xFX1BST1RPQlVGX01JTl9QUk9UT0NfVkVSU0lPTgorI2Vycm9yIFRoaXMgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IGFuIG9sZGVyIHZlcnNpb24gb2YgcHJvdG9jIHdoaWNoIGlzCisjZXJyb3IgaW5jb21wYXRpYmxlIHdpdGggeW91ciBQcm90b2NvbCBCdWZmZXIgaGVhZGVycy4gIFBsZWFzZQorI2Vycm9yIHJlZ2VuZXJhdGUgdGhpcyBmaWxlIHdpdGggYSBuZXdlciB2ZXJzaW9uIG9mIHByb3RvYy4KKyNlbmRpZgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2FyZW5hLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2FyZW5hc3RyaW5nLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9tZXNzYWdlX3V0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWV0YWRhdGEuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWVzc2FnZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9yZXBlYXRlZF9maWVsZC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9leHRlbnNpb25fc2V0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21hcC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tYXBfZmllbGRfaW5sLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9lbnVtX3JlZmxlY3Rpb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdW5rbm93bl9maWVsZF9zZXQuaD4KKy8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbmNsdWRlcykKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCisvLyBJbnRlcm5hbCBpbXBsZW1lbnRhdGlvbiBkZXRhaWwgLS0gZG8gbm90IGNhbGwgdGhlc2UuCit2b2lkIExJQlBST1RPQlVGX0VYUE9SVCBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmc3RydWN0XzJlcHJvdG8oKTsKK3ZvaWQgcHJvdG9idWZfQXNzaWduRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZnN0cnVjdF8yZXByb3RvKCk7Cit2b2lkIHByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZnN0cnVjdF8yZXByb3RvKCk7CisKK2NsYXNzIExpc3RWYWx1ZTsKK2NsYXNzIFN0cnVjdDsKK2NsYXNzIFZhbHVlOworCitlbnVtIE51bGxWYWx1ZSB7CisgIE5VTExfVkFMVUUgPSAwLAorICBOdWxsVmFsdWVfSU5UX01JTl9TRU5USU5FTF9ET19OT1RfVVNFXyA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6a2ludDMybWluLAorICBOdWxsVmFsdWVfSU5UX01BWF9TRU5USU5FTF9ET19OT1RfVVNFXyA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6a2ludDMybWF4Cit9OworTElCUFJPVE9CVUZfRVhQT1JUIGJvb2wgTnVsbFZhbHVlX0lzVmFsaWQoaW50IHZhbHVlKTsKK2NvbnN0IE51bGxWYWx1ZSBOdWxsVmFsdWVfTUlOID0gTlVMTF9WQUxVRTsKK2NvbnN0IE51bGxWYWx1ZSBOdWxsVmFsdWVfTUFYID0gTlVMTF9WQUxVRTsKK2NvbnN0IGludCBOdWxsVmFsdWVfQVJSQVlTSVpFID0gTnVsbFZhbHVlX01BWCArIDE7CisKK0xJQlBST1RPQlVGX0VYUE9SVCBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yKiBOdWxsVmFsdWVfZGVzY3JpcHRvcigpOworaW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIE51bGxWYWx1ZV9OYW1lKE51bGxWYWx1ZSB2YWx1ZSkgeworICByZXR1cm4gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6TmFtZU9mRW51bSgKKyAgICBOdWxsVmFsdWVfZGVzY3JpcHRvcigpLCB2YWx1ZSk7Cit9CitpbmxpbmUgYm9vbCBOdWxsVmFsdWVfUGFyc2UoCisgICAgY29uc3QgOjpzdGQ6OnN0cmluZyYgbmFtZSwgTnVsbFZhbHVlKiB2YWx1ZSkgeworICByZXR1cm4gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6UGFyc2VOYW1lZEVudW08TnVsbFZhbHVlPigKKyAgICBOdWxsVmFsdWVfZGVzY3JpcHRvcigpLCBuYW1lLCB2YWx1ZSk7Cit9CisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBTdHJ1Y3QgOiBwdWJsaWMgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlIHsKKyBwdWJsaWM6CisgIFN0cnVjdCgpOworICB2aXJ0dWFsIH5TdHJ1Y3QoKTsKKworICBTdHJ1Y3QoY29uc3QgU3RydWN0JiBmcm9tKTsKKworICBpbmxpbmUgU3RydWN0JiBvcGVyYXRvcj0oY29uc3QgU3RydWN0JiBmcm9tKSB7CisgICAgQ29weUZyb20oZnJvbSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgc3RhdGljIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogZGVzY3JpcHRvcigpOworICBzdGF0aWMgY29uc3QgU3RydWN0JiBkZWZhdWx0X2luc3RhbmNlKCk7CisKKyAgdm9pZCBTd2FwKFN0cnVjdCogb3RoZXIpOworCisgIC8vIGltcGxlbWVudHMgTWVzc2FnZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgaW5saW5lIFN0cnVjdCogTmV3KCkgY29uc3QgeyByZXR1cm4gTmV3KE5VTEwpOyB9CisKKyAgU3RydWN0KiBOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0OworICB2b2lkIENvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgQ29weUZyb20oY29uc3QgU3RydWN0JiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgU3RydWN0JiBmcm9tKTsKKyAgdm9pZCBDbGVhcigpOworICBib29sIElzSW5pdGlhbGl6ZWQoKSBjb25zdDsKKworICBpbnQgQnl0ZVNpemUoKSBjb25zdDsKKyAgYm9vbCBNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCk7CisgIHZvaWQgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogb3V0cHV0KSBjb25zdDsKKyAgaW50IEdldENhY2hlZFNpemUoKSBjb25zdCB7IHJldHVybiBfY2FjaGVkX3NpemVfOyB9CisgIHByaXZhdGU6CisgIHZvaWQgU2hhcmVkQ3RvcigpOworICB2b2lkIFNoYXJlZER0b3IoKTsKKyAgdm9pZCBTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdDsKKyAgdm9pZCBJbnRlcm5hbFN3YXAoU3RydWN0KiBvdGhlcik7CisgIHByaXZhdGU6CisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYU5vVmlydHVhbCgpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5hcmVuYSgpOworICB9CisgIGlubGluZSB2b2lkKiBNYXliZUFyZW5hUHRyKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnJhd19hcmVuYV9wdHIoKTsKKyAgfQorICBwdWJsaWM6CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBHZXRNZXRhZGF0YSgpIGNvbnN0OworCisgIC8vIG5lc3RlZCB0eXBlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKworICAvLyBhY2Nlc3NvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIG1hcDxzdHJpbmcsIC5nb29nbGUucHJvdG9idWYuVmFsdWU+IGZpZWxkcyA9IDE7CisgIGludCBmaWVsZHNfc2l6ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX2ZpZWxkcygpOworICBzdGF0aWMgY29uc3QgaW50IGtGaWVsZHNGaWVsZE51bWJlciA9IDE7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWFwPCA6OnN0ZDo6c3RyaW5nLCA6Omdvb2dsZTo6cHJvdG9idWY6OlZhbHVlID4mCisgICAgICBmaWVsZHMoKSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNYXA8IDo6c3RkOjpzdHJpbmcsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VmFsdWUgPioKKyAgICAgIG11dGFibGVfZmllbGRzKCk7CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QpCisgcHJpdmF0ZToKKworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpJbnRlcm5hbE1ldGFkYXRhV2l0aEFyZW5hIF9pbnRlcm5hbF9tZXRhZGF0YV87CisgIGJvb2wgX2lzX2RlZmF1bHRfaW5zdGFuY2VfOworICB0eXBlZGVmIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6Ok1hcEVudHJ5TGl0ZTwKKyAgICAgIDo6c3RkOjpzdHJpbmcsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VmFsdWUsCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9TVFJJTkcsCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9NRVNTQUdFLAorICAgICAgMCA+CisgICAgICBTdHJ1Y3RfRmllbGRzRW50cnk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6Ok1hcEZpZWxkPAorICAgICAgOjpzdGQ6OnN0cmluZywgOjpnb29nbGU6OnByb3RvYnVmOjpWYWx1ZSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX1NUUklORywKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX01FU1NBR0UsCisgICAgICAwID4gZmllbGRzXzsKKyAgbXV0YWJsZSBpbnQgX2NhY2hlZF9zaXplXzsKKyAgZnJpZW5kIHZvaWQgTElCUFJPVE9CVUZfRVhQT1JUIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZzdHJ1Y3RfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmc3RydWN0XzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfU2h1dGRvd25GaWxlX2dvb2dsZV8yZnByb3RvYnVmXzJmc3RydWN0XzJlcHJvdG8oKTsKKworICB2b2lkIEluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICBzdGF0aWMgU3RydWN0KiBkZWZhdWx0X2luc3RhbmNlXzsKK307CisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBWYWx1ZSA6IHB1YmxpYyA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UgeworIHB1YmxpYzoKKyAgVmFsdWUoKTsKKyAgdmlydHVhbCB+VmFsdWUoKTsKKworICBWYWx1ZShjb25zdCBWYWx1ZSYgZnJvbSk7CisKKyAgaW5saW5lIFZhbHVlJiBvcGVyYXRvcj0oY29uc3QgVmFsdWUmIGZyb20pIHsKKyAgICBDb3B5RnJvbShmcm9tKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworICBzdGF0aWMgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKCk7CisgIHN0YXRpYyBjb25zdCBWYWx1ZSYgZGVmYXVsdF9pbnN0YW5jZSgpOworCisgIGVudW0gS2luZENhc2UgeworICAgIGtOdWxsVmFsdWUgPSAxLAorICAgIGtOdW1iZXJWYWx1ZSA9IDIsCisgICAga1N0cmluZ1ZhbHVlID0gMywKKyAgICBrQm9vbFZhbHVlID0gNCwKKyAgICBrU3RydWN0VmFsdWUgPSA1LAorICAgIGtMaXN0VmFsdWUgPSA2LAorICAgIEtJTkRfTk9UX1NFVCA9IDAsCisgIH07CisKKyAgdm9pZCBTd2FwKFZhbHVlKiBvdGhlcik7CisKKyAgLy8gaW1wbGVtZW50cyBNZXNzYWdlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBpbmxpbmUgVmFsdWUqIE5ldygpIGNvbnN0IHsgcmV0dXJuIE5ldyhOVUxMKTsgfQorCisgIFZhbHVlKiBOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0OworICB2b2lkIENvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgQ29weUZyb20oY29uc3QgVmFsdWUmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCBWYWx1ZSYgZnJvbSk7CisgIHZvaWQgQ2xlYXIoKTsKKyAgYm9vbCBJc0luaXRpYWxpemVkKCkgY29uc3Q7CisKKyAgaW50IEJ5dGVTaXplKCkgY29uc3Q7CisgIGJvb2wgTWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpOworICB2b2lkIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIG91dHB1dCkgY29uc3Q7CisgIGludCBHZXRDYWNoZWRTaXplKCkgY29uc3QgeyByZXR1cm4gX2NhY2hlZF9zaXplXzsgfQorICBwcml2YXRlOgorICB2b2lkIFNoYXJlZEN0b3IoKTsKKyAgdm9pZCBTaGFyZWREdG9yKCk7CisgIHZvaWQgU2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3Q7CisgIHZvaWQgSW50ZXJuYWxTd2FwKFZhbHVlKiBvdGhlcik7CisgIHByaXZhdGU6CisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYU5vVmlydHVhbCgpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5hcmVuYSgpOworICB9CisgIGlubGluZSB2b2lkKiBNYXliZUFyZW5hUHRyKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnJhd19hcmVuYV9wdHIoKTsKKyAgfQorICBwdWJsaWM6CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBHZXRNZXRhZGF0YSgpIGNvbnN0OworCisgIC8vIG5lc3RlZCB0eXBlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gYWNjZXNzb3JzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLk51bGxWYWx1ZSBudWxsX3ZhbHVlID0gMTsKKyAgcHJpdmF0ZToKKyAgYm9vbCBoYXNfbnVsbF92YWx1ZSgpIGNvbnN0OworICBwdWJsaWM6CisgIHZvaWQgY2xlYXJfbnVsbF92YWx1ZSgpOworICBzdGF0aWMgY29uc3QgaW50IGtOdWxsVmFsdWVGaWVsZE51bWJlciA9IDE7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TnVsbFZhbHVlIG51bGxfdmFsdWUoKSBjb25zdDsKKyAgdm9pZCBzZXRfbnVsbF92YWx1ZSg6Omdvb2dsZTo6cHJvdG9idWY6Ok51bGxWYWx1ZSB2YWx1ZSk7CisKKyAgLy8gb3B0aW9uYWwgZG91YmxlIG51bWJlcl92YWx1ZSA9IDI7CisgIHByaXZhdGU6CisgIGJvb2wgaGFzX251bWJlcl92YWx1ZSgpIGNvbnN0OworICBwdWJsaWM6CisgIHZvaWQgY2xlYXJfbnVtYmVyX3ZhbHVlKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga051bWJlclZhbHVlRmllbGROdW1iZXIgPSAyOworICBkb3VibGUgbnVtYmVyX3ZhbHVlKCkgY29uc3Q7CisgIHZvaWQgc2V0X251bWJlcl92YWx1ZShkb3VibGUgdmFsdWUpOworCisgIC8vIG9wdGlvbmFsIHN0cmluZyBzdHJpbmdfdmFsdWUgPSAzOworICBwcml2YXRlOgorICBib29sIGhhc19zdHJpbmdfdmFsdWUoKSBjb25zdDsKKyAgcHVibGljOgorICB2b2lkIGNsZWFyX3N0cmluZ192YWx1ZSgpOworICBzdGF0aWMgY29uc3QgaW50IGtTdHJpbmdWYWx1ZUZpZWxkTnVtYmVyID0gMzsKKyAgY29uc3QgOjpzdGQ6OnN0cmluZyYgc3RyaW5nX3ZhbHVlKCkgY29uc3Q7CisgIHZvaWQgc2V0X3N0cmluZ192YWx1ZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X3N0cmluZ192YWx1ZShjb25zdCBjaGFyKiB2YWx1ZSk7CisgIHZvaWQgc2V0X3N0cmluZ192YWx1ZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpOworICA6OnN0ZDo6c3RyaW5nKiBtdXRhYmxlX3N0cmluZ192YWx1ZSgpOworICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlX3N0cmluZ192YWx1ZSgpOworICB2b2lkIHNldF9hbGxvY2F0ZWRfc3RyaW5nX3ZhbHVlKDo6c3RkOjpzdHJpbmcqIHN0cmluZ192YWx1ZSk7CisKKyAgLy8gb3B0aW9uYWwgYm9vbCBib29sX3ZhbHVlID0gNDsKKyAgcHJpdmF0ZToKKyAgYm9vbCBoYXNfYm9vbF92YWx1ZSgpIGNvbnN0OworICBwdWJsaWM6CisgIHZvaWQgY2xlYXJfYm9vbF92YWx1ZSgpOworICBzdGF0aWMgY29uc3QgaW50IGtCb29sVmFsdWVGaWVsZE51bWJlciA9IDQ7CisgIGJvb2wgYm9vbF92YWx1ZSgpIGNvbnN0OworICB2b2lkIHNldF9ib29sX3ZhbHVlKGJvb2wgdmFsdWUpOworCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuU3RydWN0IHN0cnVjdF92YWx1ZSA9IDU7CisgIGJvb2wgaGFzX3N0cnVjdF92YWx1ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX3N0cnVjdF92YWx1ZSgpOworICBzdGF0aWMgY29uc3QgaW50IGtTdHJ1Y3RWYWx1ZUZpZWxkTnVtYmVyID0gNTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpTdHJ1Y3QmIHN0cnVjdF92YWx1ZSgpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OlN0cnVjdCogbXV0YWJsZV9zdHJ1Y3RfdmFsdWUoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpTdHJ1Y3QqIHJlbGVhc2Vfc3RydWN0X3ZhbHVlKCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF9zdHJ1Y3RfdmFsdWUoOjpnb29nbGU6OnByb3RvYnVmOjpTdHJ1Y3QqIHN0cnVjdF92YWx1ZSk7CisKKyAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5MaXN0VmFsdWUgbGlzdF92YWx1ZSA9IDY7CisgIGJvb2wgaGFzX2xpc3RfdmFsdWUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9saXN0X3ZhbHVlKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga0xpc3RWYWx1ZUZpZWxkTnVtYmVyID0gNjsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpMaXN0VmFsdWUmIGxpc3RfdmFsdWUoKSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpMaXN0VmFsdWUqIG11dGFibGVfbGlzdF92YWx1ZSgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Okxpc3RWYWx1ZSogcmVsZWFzZV9saXN0X3ZhbHVlKCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF9saXN0X3ZhbHVlKDo6Z29vZ2xlOjpwcm90b2J1Zjo6TGlzdFZhbHVlKiBsaXN0X3ZhbHVlKTsKKworICBLaW5kQ2FzZSBraW5kX2Nhc2UoKSBjb25zdDsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmdvb2dsZS5wcm90b2J1Zi5WYWx1ZSkKKyBwcml2YXRlOgorICBpbmxpbmUgdm9pZCBzZXRfaGFzX251bGxfdmFsdWUoKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19udW1iZXJfdmFsdWUoKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19zdHJpbmdfdmFsdWUoKTsKKyAgaW5saW5lIHZvaWQgc2V0X2hhc19ib29sX3ZhbHVlKCk7CisgIGlubGluZSB2b2lkIHNldF9oYXNfc3RydWN0X3ZhbHVlKCk7CisgIGlubGluZSB2b2lkIHNldF9oYXNfbGlzdF92YWx1ZSgpOworCisgIGlubGluZSBib29sIGhhc19raW5kKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfa2luZCgpOworICBpbmxpbmUgdm9pZCBjbGVhcl9oYXNfa2luZCgpOworCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEgX2ludGVybmFsX21ldGFkYXRhXzsKKyAgYm9vbCBfaXNfZGVmYXVsdF9pbnN0YW5jZV87CisgIHVuaW9uIEtpbmRVbmlvbiB7CisgICAgS2luZFVuaW9uKCkge30KKyAgICBpbnQgbnVsbF92YWx1ZV87CisgICAgZG91YmxlIG51bWJlcl92YWx1ZV87CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QXJlbmFTdHJpbmdQdHIgc3RyaW5nX3ZhbHVlXzsKKyAgICBib29sIGJvb2xfdmFsdWVfOworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6U3RydWN0KiBzdHJ1Y3RfdmFsdWVfOworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TGlzdFZhbHVlKiBsaXN0X3ZhbHVlXzsKKyAgfSBraW5kXzsKKyAgbXV0YWJsZSBpbnQgX2NhY2hlZF9zaXplXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgX29uZW9mX2Nhc2VfWzFdOworCisgIGZyaWVuZCB2b2lkIExJQlBST1RPQlVGX0VYUE9SVCBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmc3RydWN0XzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfQXNzaWduRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZnN0cnVjdF8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZnN0cnVjdF8yZXByb3RvKCk7CisKKyAgdm9pZCBJbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgc3RhdGljIFZhbHVlKiBkZWZhdWx0X2luc3RhbmNlXzsKK307CisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBMaXN0VmFsdWUgOiBwdWJsaWMgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlIHsKKyBwdWJsaWM6CisgIExpc3RWYWx1ZSgpOworICB2aXJ0dWFsIH5MaXN0VmFsdWUoKTsKKworICBMaXN0VmFsdWUoY29uc3QgTGlzdFZhbHVlJiBmcm9tKTsKKworICBpbmxpbmUgTGlzdFZhbHVlJiBvcGVyYXRvcj0oY29uc3QgTGlzdFZhbHVlJiBmcm9tKSB7CisgICAgQ29weUZyb20oZnJvbSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgc3RhdGljIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogZGVzY3JpcHRvcigpOworICBzdGF0aWMgY29uc3QgTGlzdFZhbHVlJiBkZWZhdWx0X2luc3RhbmNlKCk7CisKKyAgdm9pZCBTd2FwKExpc3RWYWx1ZSogb3RoZXIpOworCisgIC8vIGltcGxlbWVudHMgTWVzc2FnZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgaW5saW5lIExpc3RWYWx1ZSogTmV3KCkgY29uc3QgeyByZXR1cm4gTmV3KE5VTEwpOyB9CisKKyAgTGlzdFZhbHVlKiBOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0OworICB2b2lkIENvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgQ29weUZyb20oY29uc3QgTGlzdFZhbHVlJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgTGlzdFZhbHVlJiBmcm9tKTsKKyAgdm9pZCBDbGVhcigpOworICBib29sIElzSW5pdGlhbGl6ZWQoKSBjb25zdDsKKworICBpbnQgQnl0ZVNpemUoKSBjb25zdDsKKyAgYm9vbCBNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCk7CisgIHZvaWQgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogb3V0cHV0KSBjb25zdDsKKyAgaW50IEdldENhY2hlZFNpemUoKSBjb25zdCB7IHJldHVybiBfY2FjaGVkX3NpemVfOyB9CisgIHByaXZhdGU6CisgIHZvaWQgU2hhcmVkQ3RvcigpOworICB2b2lkIFNoYXJlZER0b3IoKTsKKyAgdm9pZCBTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdDsKKyAgdm9pZCBJbnRlcm5hbFN3YXAoTGlzdFZhbHVlKiBvdGhlcik7CisgIHByaXZhdGU6CisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYU5vVmlydHVhbCgpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5hcmVuYSgpOworICB9CisgIGlubGluZSB2b2lkKiBNYXliZUFyZW5hUHRyKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnJhd19hcmVuYV9wdHIoKTsKKyAgfQorICBwdWJsaWM6CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBHZXRNZXRhZGF0YSgpIGNvbnN0OworCisgIC8vIG5lc3RlZCB0eXBlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gYWNjZXNzb3JzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlZhbHVlIHZhbHVlcyA9IDE7CisgIGludCB2YWx1ZXNfc2l6ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX3ZhbHVlcygpOworICBzdGF0aWMgY29uc3QgaW50IGtWYWx1ZXNGaWVsZE51bWJlciA9IDE7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6VmFsdWUmIHZhbHVlcyhpbnQgaW5kZXgpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OlZhbHVlKiBtdXRhYmxlX3ZhbHVlcyhpbnQgaW5kZXgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlZhbHVlKiBhZGRfdmFsdWVzKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpWYWx1ZSA+KgorICAgICAgbXV0YWJsZV92YWx1ZXMoKTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlZhbHVlID4mCisgICAgICB2YWx1ZXMoKSBjb25zdDsKKworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6Z29vZ2xlLnByb3RvYnVmLkxpc3RWYWx1ZSkKKyBwcml2YXRlOgorCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEgX2ludGVybmFsX21ldGFkYXRhXzsKKyAgYm9vbCBfaXNfZGVmYXVsdF9pbnN0YW5jZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpWYWx1ZSA+IHZhbHVlc187CisgIG11dGFibGUgaW50IF9jYWNoZWRfc2l6ZV87CisgIGZyaWVuZCB2b2lkIExJQlBST1RPQlVGX0VYUE9SVCBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmc3RydWN0XzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfQXNzaWduRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZnN0cnVjdF8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZnN0cnVjdF8yZXByb3RvKCk7CisKKyAgdm9pZCBJbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgc3RhdGljIExpc3RWYWx1ZSogZGVmYXVsdF9pbnN0YW5jZV87Cit9OworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworI2lmICFQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKy8vIFN0cnVjdAorCisvLyBtYXA8c3RyaW5nLCAuZ29vZ2xlLnByb3RvYnVmLlZhbHVlPiBmaWVsZHMgPSAxOworaW5saW5lIGludCBTdHJ1Y3Q6OmZpZWxkc19zaXplKCkgY29uc3QgeworICByZXR1cm4gZmllbGRzXy5zaXplKCk7Cit9CitpbmxpbmUgdm9pZCBTdHJ1Y3Q6OmNsZWFyX2ZpZWxkcygpIHsKKyAgZmllbGRzXy5DbGVhcigpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWFwPCA6OnN0ZDo6c3RyaW5nLCA6Omdvb2dsZTo6cHJvdG9idWY6OlZhbHVlID4mCitTdHJ1Y3Q6OmZpZWxkcygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX21hcDpnb29nbGUucHJvdG9idWYuU3RydWN0LmZpZWxkcykKKyAgcmV0dXJuIGZpZWxkc18uR2V0TWFwKCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpNYXA8IDo6c3RkOjpzdHJpbmcsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VmFsdWUgPioKK1N0cnVjdDo6bXV0YWJsZV9maWVsZHMoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX21hcDpnb29nbGUucHJvdG9idWYuU3RydWN0LmZpZWxkcykKKyAgcmV0dXJuIGZpZWxkc18uTXV0YWJsZU1hcCgpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIFZhbHVlCisKKy8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuTnVsbFZhbHVlIG51bGxfdmFsdWUgPSAxOworaW5saW5lIGJvb2wgVmFsdWU6Omhhc19udWxsX3ZhbHVlKCkgY29uc3QgeworICByZXR1cm4ga2luZF9jYXNlKCkgPT0ga051bGxWYWx1ZTsKK30KK2lubGluZSB2b2lkIFZhbHVlOjpzZXRfaGFzX251bGxfdmFsdWUoKSB7CisgIF9vbmVvZl9jYXNlX1swXSA9IGtOdWxsVmFsdWU7Cit9CitpbmxpbmUgdm9pZCBWYWx1ZTo6Y2xlYXJfbnVsbF92YWx1ZSgpIHsKKyAgaWYgKGhhc19udWxsX3ZhbHVlKCkpIHsKKyAgICBraW5kXy5udWxsX3ZhbHVlXyA9IDA7CisgICAgY2xlYXJfaGFzX2tpbmQoKTsKKyAgfQorfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TnVsbFZhbHVlIFZhbHVlOjpudWxsX3ZhbHVlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5WYWx1ZS5udWxsX3ZhbHVlKQorICBpZiAoaGFzX251bGxfdmFsdWUoKSkgeworICAgIHJldHVybiBzdGF0aWNfY2FzdDwgOjpnb29nbGU6OnByb3RvYnVmOjpOdWxsVmFsdWUgPihraW5kXy5udWxsX3ZhbHVlXyk7CisgIH0KKyAgcmV0dXJuIHN0YXRpY19jYXN0PCA6Omdvb2dsZTo6cHJvdG9idWY6Ok51bGxWYWx1ZSA+KDApOworfQoraW5saW5lIHZvaWQgVmFsdWU6OnNldF9udWxsX3ZhbHVlKDo6Z29vZ2xlOjpwcm90b2J1Zjo6TnVsbFZhbHVlIHZhbHVlKSB7CisgIGlmICghaGFzX251bGxfdmFsdWUoKSkgeworICAgIGNsZWFyX2tpbmQoKTsKKyAgICBzZXRfaGFzX251bGxfdmFsdWUoKTsKKyAgfQorICBraW5kXy5udWxsX3ZhbHVlXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5WYWx1ZS5udWxsX3ZhbHVlKQorfQorCisvLyBvcHRpb25hbCBkb3VibGUgbnVtYmVyX3ZhbHVlID0gMjsKK2lubGluZSBib29sIFZhbHVlOjpoYXNfbnVtYmVyX3ZhbHVlKCkgY29uc3QgeworICByZXR1cm4ga2luZF9jYXNlKCkgPT0ga051bWJlclZhbHVlOworfQoraW5saW5lIHZvaWQgVmFsdWU6OnNldF9oYXNfbnVtYmVyX3ZhbHVlKCkgeworICBfb25lb2ZfY2FzZV9bMF0gPSBrTnVtYmVyVmFsdWU7Cit9CitpbmxpbmUgdm9pZCBWYWx1ZTo6Y2xlYXJfbnVtYmVyX3ZhbHVlKCkgeworICBpZiAoaGFzX251bWJlcl92YWx1ZSgpKSB7CisgICAga2luZF8ubnVtYmVyX3ZhbHVlXyA9IDA7CisgICAgY2xlYXJfaGFzX2tpbmQoKTsKKyAgfQorfQoraW5saW5lIGRvdWJsZSBWYWx1ZTo6bnVtYmVyX3ZhbHVlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5WYWx1ZS5udW1iZXJfdmFsdWUpCisgIGlmIChoYXNfbnVtYmVyX3ZhbHVlKCkpIHsKKyAgICByZXR1cm4ga2luZF8ubnVtYmVyX3ZhbHVlXzsKKyAgfQorICByZXR1cm4gMDsKK30KK2lubGluZSB2b2lkIFZhbHVlOjpzZXRfbnVtYmVyX3ZhbHVlKGRvdWJsZSB2YWx1ZSkgeworICBpZiAoIWhhc19udW1iZXJfdmFsdWUoKSkgeworICAgIGNsZWFyX2tpbmQoKTsKKyAgICBzZXRfaGFzX251bWJlcl92YWx1ZSgpOworICB9CisgIGtpbmRfLm51bWJlcl92YWx1ZV8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuVmFsdWUubnVtYmVyX3ZhbHVlKQorfQorCisvLyBvcHRpb25hbCBzdHJpbmcgc3RyaW5nX3ZhbHVlID0gMzsKK2lubGluZSBib29sIFZhbHVlOjpoYXNfc3RyaW5nX3ZhbHVlKCkgY29uc3QgeworICByZXR1cm4ga2luZF9jYXNlKCkgPT0ga1N0cmluZ1ZhbHVlOworfQoraW5saW5lIHZvaWQgVmFsdWU6OnNldF9oYXNfc3RyaW5nX3ZhbHVlKCkgeworICBfb25lb2ZfY2FzZV9bMF0gPSBrU3RyaW5nVmFsdWU7Cit9CitpbmxpbmUgdm9pZCBWYWx1ZTo6Y2xlYXJfc3RyaW5nX3ZhbHVlKCkgeworICBpZiAoaGFzX3N0cmluZ192YWx1ZSgpKSB7CisgICAga2luZF8uc3RyaW5nX3ZhbHVlXy5EZXN0cm95Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICAgIGNsZWFyX2hhc19raW5kKCk7CisgIH0KK30KK2lubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBWYWx1ZTo6c3RyaW5nX3ZhbHVlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5WYWx1ZS5zdHJpbmdfdmFsdWUpCisgIGlmIChoYXNfc3RyaW5nX3ZhbHVlKCkpIHsKKyAgICByZXR1cm4ga2luZF8uc3RyaW5nX3ZhbHVlXy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIH0KKyAgcmV0dXJuIComOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCk7Cit9CitpbmxpbmUgdm9pZCBWYWx1ZTo6c2V0X3N0cmluZ192YWx1ZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5WYWx1ZS5zdHJpbmdfdmFsdWUpCisgIGlmICghaGFzX3N0cmluZ192YWx1ZSgpKSB7CisgICAgY2xlYXJfa2luZCgpOworICAgIHNldF9oYXNfc3RyaW5nX3ZhbHVlKCk7CisgICAga2luZF8uc3RyaW5nX3ZhbHVlXy5VbnNhZmVTZXREZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIH0KKyAga2luZF8uc3RyaW5nX3ZhbHVlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5WYWx1ZS5zdHJpbmdfdmFsdWUpCit9CitpbmxpbmUgdm9pZCBWYWx1ZTo6c2V0X3N0cmluZ192YWx1ZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICBpZiAoIWhhc19zdHJpbmdfdmFsdWUoKSkgeworICAgIGNsZWFyX2tpbmQoKTsKKyAgICBzZXRfaGFzX3N0cmluZ192YWx1ZSgpOworICAgIGtpbmRfLnN0cmluZ192YWx1ZV8uVW5zYWZlU2V0RGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICB9CisgIGtpbmRfLnN0cmluZ192YWx1ZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuVmFsdWUuc3RyaW5nX3ZhbHVlKQorfQoraW5saW5lIHZvaWQgVmFsdWU6OnNldF9zdHJpbmdfdmFsdWUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIGlmICghaGFzX3N0cmluZ192YWx1ZSgpKSB7CisgICAgY2xlYXJfa2luZCgpOworICAgIHNldF9oYXNfc3RyaW5nX3ZhbHVlKCk7CisgICAga2luZF8uc3RyaW5nX3ZhbHVlXy5VbnNhZmVTZXREZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIH0KKyAga2luZF8uc3RyaW5nX3ZhbHVlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZygKKyAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLlZhbHVlLnN0cmluZ192YWx1ZSkKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBWYWx1ZTo6bXV0YWJsZV9zdHJpbmdfdmFsdWUoKSB7CisgIGlmICghaGFzX3N0cmluZ192YWx1ZSgpKSB7CisgICAgY2xlYXJfa2luZCgpOworICAgIHNldF9oYXNfc3RyaW5nX3ZhbHVlKCk7CisgICAga2luZF8uc3RyaW5nX3ZhbHVlXy5VbnNhZmVTZXREZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLlZhbHVlLnN0cmluZ192YWx1ZSkKKyAgcmV0dXJuIGtpbmRfLnN0cmluZ192YWx1ZV8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBWYWx1ZTo6cmVsZWFzZV9zdHJpbmdfdmFsdWUoKSB7CisgIGlmIChoYXNfc3RyaW5nX3ZhbHVlKCkpIHsKKyAgICBjbGVhcl9oYXNfa2luZCgpOworICAgIHJldHVybiBraW5kXy5zdHJpbmdfdmFsdWVfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KK30KK2lubGluZSB2b2lkIFZhbHVlOjpzZXRfYWxsb2NhdGVkX3N0cmluZ192YWx1ZSg6OnN0ZDo6c3RyaW5nKiBzdHJpbmdfdmFsdWUpIHsKKyAgaWYgKCFoYXNfc3RyaW5nX3ZhbHVlKCkpIHsKKyAgICBraW5kXy5zdHJpbmdfdmFsdWVfLlVuc2FmZVNldERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgfQorICBjbGVhcl9raW5kKCk7CisgIGlmIChzdHJpbmdfdmFsdWUgIT0gTlVMTCkgeworICAgIHNldF9oYXNfc3RyaW5nX3ZhbHVlKCk7CisgICAga2luZF8uc3RyaW5nX3ZhbHVlXy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgICAgc3RyaW5nX3ZhbHVlKTsKKyAgfQorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuVmFsdWUuc3RyaW5nX3ZhbHVlKQorfQorCisvLyBvcHRpb25hbCBib29sIGJvb2xfdmFsdWUgPSA0OworaW5saW5lIGJvb2wgVmFsdWU6Omhhc19ib29sX3ZhbHVlKCkgY29uc3QgeworICByZXR1cm4ga2luZF9jYXNlKCkgPT0ga0Jvb2xWYWx1ZTsKK30KK2lubGluZSB2b2lkIFZhbHVlOjpzZXRfaGFzX2Jvb2xfdmFsdWUoKSB7CisgIF9vbmVvZl9jYXNlX1swXSA9IGtCb29sVmFsdWU7Cit9CitpbmxpbmUgdm9pZCBWYWx1ZTo6Y2xlYXJfYm9vbF92YWx1ZSgpIHsKKyAgaWYgKGhhc19ib29sX3ZhbHVlKCkpIHsKKyAgICBraW5kXy5ib29sX3ZhbHVlXyA9IGZhbHNlOworICAgIGNsZWFyX2hhc19raW5kKCk7CisgIH0KK30KK2lubGluZSBib29sIFZhbHVlOjpib29sX3ZhbHVlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5WYWx1ZS5ib29sX3ZhbHVlKQorICBpZiAoaGFzX2Jvb2xfdmFsdWUoKSkgeworICAgIHJldHVybiBraW5kXy5ib29sX3ZhbHVlXzsKKyAgfQorICByZXR1cm4gZmFsc2U7Cit9CitpbmxpbmUgdm9pZCBWYWx1ZTo6c2V0X2Jvb2xfdmFsdWUoYm9vbCB2YWx1ZSkgeworICBpZiAoIWhhc19ib29sX3ZhbHVlKCkpIHsKKyAgICBjbGVhcl9raW5kKCk7CisgICAgc2V0X2hhc19ib29sX3ZhbHVlKCk7CisgIH0KKyAga2luZF8uYm9vbF92YWx1ZV8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuVmFsdWUuYm9vbF92YWx1ZSkKK30KKworLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3Qgc3RydWN0X3ZhbHVlID0gNTsKK2lubGluZSBib29sIFZhbHVlOjpoYXNfc3RydWN0X3ZhbHVlKCkgY29uc3QgeworICByZXR1cm4ga2luZF9jYXNlKCkgPT0ga1N0cnVjdFZhbHVlOworfQoraW5saW5lIHZvaWQgVmFsdWU6OnNldF9oYXNfc3RydWN0X3ZhbHVlKCkgeworICBfb25lb2ZfY2FzZV9bMF0gPSBrU3RydWN0VmFsdWU7Cit9CitpbmxpbmUgdm9pZCBWYWx1ZTo6Y2xlYXJfc3RydWN0X3ZhbHVlKCkgeworICBpZiAoaGFzX3N0cnVjdF92YWx1ZSgpKSB7CisgICAgZGVsZXRlIGtpbmRfLnN0cnVjdF92YWx1ZV87CisgICAgY2xlYXJfaGFzX2tpbmQoKTsKKyAgfQorfQoraW5saW5lICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlN0cnVjdCYgVmFsdWU6OnN0cnVjdF92YWx1ZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuVmFsdWUuc3RydWN0X3ZhbHVlKQorICByZXR1cm4gaGFzX3N0cnVjdF92YWx1ZSgpCisgICAgICA/ICpraW5kXy5zdHJ1Y3RfdmFsdWVfCisgICAgICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6U3RydWN0OjpkZWZhdWx0X2luc3RhbmNlKCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpTdHJ1Y3QqIFZhbHVlOjptdXRhYmxlX3N0cnVjdF92YWx1ZSgpIHsKKyAgaWYgKCFoYXNfc3RydWN0X3ZhbHVlKCkpIHsKKyAgICBjbGVhcl9raW5kKCk7CisgICAgc2V0X2hhc19zdHJ1Y3RfdmFsdWUoKTsKKyAgICBraW5kXy5zdHJ1Y3RfdmFsdWVfID0gbmV3IDo6Z29vZ2xlOjpwcm90b2J1Zjo6U3RydWN0OworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5WYWx1ZS5zdHJ1Y3RfdmFsdWUpCisgIHJldHVybiBraW5kXy5zdHJ1Y3RfdmFsdWVfOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6U3RydWN0KiBWYWx1ZTo6cmVsZWFzZV9zdHJ1Y3RfdmFsdWUoKSB7CisgIGlmIChoYXNfc3RydWN0X3ZhbHVlKCkpIHsKKyAgICBjbGVhcl9oYXNfa2luZCgpOworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6U3RydWN0KiB0ZW1wID0ga2luZF8uc3RydWN0X3ZhbHVlXzsKKyAgICBraW5kXy5zdHJ1Y3RfdmFsdWVfID0gTlVMTDsKKyAgICByZXR1cm4gdGVtcDsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorfQoraW5saW5lIHZvaWQgVmFsdWU6OnNldF9hbGxvY2F0ZWRfc3RydWN0X3ZhbHVlKDo6Z29vZ2xlOjpwcm90b2J1Zjo6U3RydWN0KiBzdHJ1Y3RfdmFsdWUpIHsKKyAgY2xlYXJfa2luZCgpOworICBpZiAoc3RydWN0X3ZhbHVlKSB7CisgICAgc2V0X2hhc19zdHJ1Y3RfdmFsdWUoKTsKKyAgICBraW5kXy5zdHJ1Y3RfdmFsdWVfID0gc3RydWN0X3ZhbHVlOworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5WYWx1ZS5zdHJ1Y3RfdmFsdWUpCit9CisKKy8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuTGlzdFZhbHVlIGxpc3RfdmFsdWUgPSA2OworaW5saW5lIGJvb2wgVmFsdWU6Omhhc19saXN0X3ZhbHVlKCkgY29uc3QgeworICByZXR1cm4ga2luZF9jYXNlKCkgPT0ga0xpc3RWYWx1ZTsKK30KK2lubGluZSB2b2lkIFZhbHVlOjpzZXRfaGFzX2xpc3RfdmFsdWUoKSB7CisgIF9vbmVvZl9jYXNlX1swXSA9IGtMaXN0VmFsdWU7Cit9CitpbmxpbmUgdm9pZCBWYWx1ZTo6Y2xlYXJfbGlzdF92YWx1ZSgpIHsKKyAgaWYgKGhhc19saXN0X3ZhbHVlKCkpIHsKKyAgICBkZWxldGUga2luZF8ubGlzdF92YWx1ZV87CisgICAgY2xlYXJfaGFzX2tpbmQoKTsKKyAgfQorfQoraW5saW5lICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Okxpc3RWYWx1ZSYgVmFsdWU6Omxpc3RfdmFsdWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlZhbHVlLmxpc3RfdmFsdWUpCisgIHJldHVybiBoYXNfbGlzdF92YWx1ZSgpCisgICAgICA/ICpraW5kXy5saXN0X3ZhbHVlXworICAgICAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Okxpc3RWYWx1ZTo6ZGVmYXVsdF9pbnN0YW5jZSgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TGlzdFZhbHVlKiBWYWx1ZTo6bXV0YWJsZV9saXN0X3ZhbHVlKCkgeworICBpZiAoIWhhc19saXN0X3ZhbHVlKCkpIHsKKyAgICBjbGVhcl9raW5kKCk7CisgICAgc2V0X2hhc19saXN0X3ZhbHVlKCk7CisgICAga2luZF8ubGlzdF92YWx1ZV8gPSBuZXcgOjpnb29nbGU6OnByb3RvYnVmOjpMaXN0VmFsdWU7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLlZhbHVlLmxpc3RfdmFsdWUpCisgIHJldHVybiBraW5kXy5saXN0X3ZhbHVlXzsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6Okxpc3RWYWx1ZSogVmFsdWU6OnJlbGVhc2VfbGlzdF92YWx1ZSgpIHsKKyAgaWYgKGhhc19saXN0X3ZhbHVlKCkpIHsKKyAgICBjbGVhcl9oYXNfa2luZCgpOworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TGlzdFZhbHVlKiB0ZW1wID0ga2luZF8ubGlzdF92YWx1ZV87CisgICAga2luZF8ubGlzdF92YWx1ZV8gPSBOVUxMOworICAgIHJldHVybiB0ZW1wOworICB9IGVsc2UgeworICAgIHJldHVybiBOVUxMOworICB9Cit9CitpbmxpbmUgdm9pZCBWYWx1ZTo6c2V0X2FsbG9jYXRlZF9saXN0X3ZhbHVlKDo6Z29vZ2xlOjpwcm90b2J1Zjo6TGlzdFZhbHVlKiBsaXN0X3ZhbHVlKSB7CisgIGNsZWFyX2tpbmQoKTsKKyAgaWYgKGxpc3RfdmFsdWUpIHsKKyAgICBzZXRfaGFzX2xpc3RfdmFsdWUoKTsKKyAgICBraW5kXy5saXN0X3ZhbHVlXyA9IGxpc3RfdmFsdWU7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLlZhbHVlLmxpc3RfdmFsdWUpCit9CisKK2lubGluZSBib29sIFZhbHVlOjpoYXNfa2luZCgpIGNvbnN0IHsKKyAgcmV0dXJuIGtpbmRfY2FzZSgpICE9IEtJTkRfTk9UX1NFVDsKK30KK2lubGluZSB2b2lkIFZhbHVlOjpjbGVhcl9oYXNfa2luZCgpIHsKKyAgX29uZW9mX2Nhc2VfWzBdID0gS0lORF9OT1RfU0VUOworfQoraW5saW5lIFZhbHVlOjpLaW5kQ2FzZSBWYWx1ZTo6a2luZF9jYXNlKCkgY29uc3QgeworICByZXR1cm4gVmFsdWU6OktpbmRDYXNlKF9vbmVvZl9jYXNlX1swXSk7Cit9CisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIExpc3RWYWx1ZQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlZhbHVlIHZhbHVlcyA9IDE7CitpbmxpbmUgaW50IExpc3RWYWx1ZTo6dmFsdWVzX3NpemUoKSBjb25zdCB7CisgIHJldHVybiB2YWx1ZXNfLnNpemUoKTsKK30KK2lubGluZSB2b2lkIExpc3RWYWx1ZTo6Y2xlYXJfdmFsdWVzKCkgeworICB2YWx1ZXNfLkNsZWFyKCk7Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpWYWx1ZSYgTGlzdFZhbHVlOjp2YWx1ZXMoaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkxpc3RWYWx1ZS52YWx1ZXMpCisgIHJldHVybiB2YWx1ZXNfLkdldChpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpWYWx1ZSogTGlzdFZhbHVlOjptdXRhYmxlX3ZhbHVlcyhpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkxpc3RWYWx1ZS52YWx1ZXMpCisgIHJldHVybiB2YWx1ZXNfLk11dGFibGUoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6VmFsdWUqIExpc3RWYWx1ZTo6YWRkX3ZhbHVlcygpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuTGlzdFZhbHVlLnZhbHVlcykKKyAgcmV0dXJuIHZhbHVlc18uQWRkKCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlZhbHVlID4qCitMaXN0VmFsdWU6Om11dGFibGVfdmFsdWVzKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5MaXN0VmFsdWUudmFsdWVzKQorICByZXR1cm4gJnZhbHVlc187Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OlZhbHVlID4mCitMaXN0VmFsdWU6OnZhbHVlcygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkxpc3RWYWx1ZS52YWx1ZXMpCisgIHJldHVybiB2YWx1ZXNfOworfQorCisjZW5kaWYgIC8vICFQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisKKy8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChuYW1lc3BhY2Vfc2NvcGUpCisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisjaWZuZGVmIFNXSUcKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKwordGVtcGxhdGUgPD4gc3RydWN0IGlzX3Byb3RvX2VudW08IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TnVsbFZhbHVlPiA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OnRydWVfdHlwZSB7fTsKK3RlbXBsYXRlIDw+CitpbmxpbmUgY29uc3QgRW51bURlc2NyaXB0b3IqIEdldEVudW1EZXNjcmlwdG9yPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok51bGxWYWx1ZT4oKSB7CisgIHJldHVybiA6Omdvb2dsZTo6cHJvdG9idWY6Ok51bGxWYWx1ZV9kZXNjcmlwdG9yKCk7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBTV0lHCisKKy8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChnbG9iYWxfc2NvcGUpCisKKyNlbmRpZiAgLy8gUFJPVE9CVUZfZ29vZ2xlXzJmcHJvdG9idWZfMmZzdHJ1Y3RfMmVwcm90b19fSU5DTFVERUQKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvc3RydWN0LnByb3RvIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHJ1Y3QucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODU2MmUyYwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3RydWN0LnByb3RvCkBAIC0wLDAgKzEsOTUgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitzeW50YXggPSAicHJvdG8zIjsKKworcGFja2FnZSBnb29nbGUucHJvdG9idWY7CisKK29wdGlvbiBjc2hhcnBfbmFtZXNwYWNlID0gIkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlcyI7CitvcHRpb24gamF2YV9wYWNrYWdlID0gImNvbS5nb29nbGUucHJvdG9idWYiOworb3B0aW9uIGphdmFfb3V0ZXJfY2xhc3NuYW1lID0gIlN0cnVjdFByb3RvIjsKK29wdGlvbiBqYXZhX211bHRpcGxlX2ZpbGVzID0gdHJ1ZTsKK29wdGlvbiBqYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaCA9IHRydWU7CitvcHRpb24gb2JqY19jbGFzc19wcmVmaXggPSAiR1BCIjsKKworCisvLyBgU3RydWN0YCByZXByZXNlbnRzIGEgc3RydWN0dXJlZCBkYXRhIHZhbHVlLCBjb25zaXN0aW5nIG9mIGZpZWxkcworLy8gd2hpY2ggbWFwIHRvIGR5bmFtaWNhbGx5IHR5cGVkIHZhbHVlcy4gSW4gc29tZSBsYW5ndWFnZXMsIGBTdHJ1Y3RgCisvLyBtaWdodCBiZSBzdXBwb3J0ZWQgYnkgYSBuYXRpdmUgcmVwcmVzZW50YXRpb24uIEZvciBleGFtcGxlLCBpbgorLy8gc2NyaXB0aW5nIGxhbmd1YWdlcyBsaWtlIEpTIGEgc3RydWN0IGlzIHJlcHJlc2VudGVkIGFzIGFuCisvLyBvYmplY3QuIFRoZSBkZXRhaWxzIG9mIHRoYXQgcmVwcmVzZW50YXRpb24gYXJlIGRlc2NyaWJlZCB0b2dldGhlcgorLy8gd2l0aCB0aGUgcHJvdG8gc3VwcG9ydCBmb3IgdGhlIGxhbmd1YWdlLgorLy8KKy8vIFRoZSBKU09OIHJlcHJlc2VudGF0aW9uIGZvciBgU3RydWN0YCBpcyBKU09OIG9iamVjdC4KK21lc3NhZ2UgU3RydWN0IHsKKyAgLy8gTWFwIG9mIGR5bmFtaWNhbGx5IHR5cGVkIHZhbHVlcy4KKyAgbWFwPHN0cmluZywgVmFsdWU+IGZpZWxkcyA9IDE7Cit9CisKKy8vIGBWYWx1ZWAgcmVwcmVzZW50cyBhIGR5bmFtaWNhbGx5IHR5cGVkIHZhbHVlIHdoaWNoIGNhbiBiZSBlaXRoZXIKKy8vIG51bGwsIGEgbnVtYmVyLCBhIHN0cmluZywgYSBib29sZWFuLCBhIHJlY3Vyc2l2ZSBzdHJ1Y3QgdmFsdWUsIG9yIGEKKy8vIGxpc3Qgb2YgdmFsdWVzLiBBIHByb2R1Y2VyIG9mIHZhbHVlIGlzIGV4cGVjdGVkIHRvIHNldCBvbmUgb2YgdGhhdAorLy8gdmFyaWFudHMsIGFic2VuY2Ugb2YgYW55IHZhcmlhbnQgaW5kaWNhdGVzIGFuIGVycm9yLgorLy8KKy8vIFRoZSBKU09OIHJlcHJlc2VudGF0aW9uIGZvciBgVmFsdWVgIGlzIEpTT04gdmFsdWUuCittZXNzYWdlIFZhbHVlIHsKKyAgLy8gVGhlIGtpbmQgb2YgdmFsdWUuCisgIG9uZW9mIGtpbmQgeworICAgIC8vIFJlcHJlc2VudHMgYSBudWxsIHZhbHVlLgorICAgIE51bGxWYWx1ZSBudWxsX3ZhbHVlID0gMTsKKyAgICAvLyBSZXByZXNlbnRzIGEgZG91YmxlIHZhbHVlLgorICAgIGRvdWJsZSBudW1iZXJfdmFsdWUgPSAyOworICAgIC8vIFJlcHJlc2VudHMgYSBzdHJpbmcgdmFsdWUuCisgICAgc3RyaW5nIHN0cmluZ192YWx1ZSA9IDM7CisgICAgLy8gUmVwcmVzZW50cyBhIGJvb2xlYW4gdmFsdWUuCisgICAgYm9vbCBib29sX3ZhbHVlID0gNDsKKyAgICAvLyBSZXByZXNlbnRzIGEgc3RydWN0dXJlZCB2YWx1ZS4KKyAgICBTdHJ1Y3Qgc3RydWN0X3ZhbHVlID0gNTsKKyAgICAvLyBSZXByZXNlbnRzIGEgcmVwZWF0ZWQgYFZhbHVlYC4KKyAgICBMaXN0VmFsdWUgbGlzdF92YWx1ZSA9IDY7CisgIH0KK30KKworLy8gYE51bGxWYWx1ZWAgaXMgYSBzaW5nbGV0b24gZW51bWVyYXRpb24gdG8gcmVwcmVzZW50IHRoZSBudWxsIHZhbHVlIGZvciB0aGUKKy8vIGBWYWx1ZWAgdHlwZSB1bmlvbi4KKy8vCisvLyAgVGhlIEpTT04gcmVwcmVzZW50YXRpb24gZm9yIGBOdWxsVmFsdWVgIGlzIEpTT04gYG51bGxgLgorZW51bSBOdWxsVmFsdWUgeworICAvLyBOdWxsIHZhbHVlLgorICBOVUxMX1ZBTFVFID0gMDsKK30KKworLy8gYExpc3RWYWx1ZWAgaXMgYSB3cmFwcGVyIGFyb3VuZCBhIHJlcGVhdGVkIGZpZWxkIG9mIHZhbHVlcy4KKy8vCisvLyBUaGUgSlNPTiByZXByZXNlbnRhdGlvbiBmb3IgYExpc3RWYWx1ZWAgaXMgSlNPTiBhcnJheS4KK21lc3NhZ2UgTGlzdFZhbHVlIHsKKyAgLy8gUmVwZWF0ZWQgZmllbGQgb2YgZHluYW1pY2FsbHkgdHlwZWQgdmFsdWVzLgorICByZXBlYXRlZCBWYWx1ZSB2YWx1ZXMgPSAxOworfQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNfc2VxdWVuY2VfbnVtLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY19zZXF1ZW5jZV9udW0uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iYjIwOTQyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNfc2VxdWVuY2VfbnVtLmgKQEAgLTAsMCArMSw1NCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAxNCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNfU0VRVUVOQ0VfTlVNX0hfCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNfU0VRVUVOQ0VfTlVNX0hfCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKK2NsYXNzIFNlcXVlbmNlTnVtYmVyIHsKKyBwdWJsaWM6CisgIFNlcXVlbmNlTnVtYmVyKCkgOiB3b3JkXygwKSB7fQorCisgIEF0b21pY1dvcmQgR2V0TmV4dCgpIHsKKyAgICByZXR1cm4gTm9CYXJyaWVyX0F0b21pY0luY3JlbWVudCgmd29yZF8sIDEpIC0gMTsKKyAgfQorIHByaXZhdGU6CisgIEF0b21pY1dvcmQgd29yZF87Cit9OworCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNfU0VRVUVOQ0VfTlVNX0hfCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wcy5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHMuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jYjkzMjI3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHMuaApAQCAtMCwwICsxLDI0NCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAxMiBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIFRoZSByb3V0aW5lcyBleHBvcnRlZCBieSB0aGlzIG1vZHVsZSBhcmUgc3VidGxlLiAgSWYgeW91IHVzZSB0aGVtLCBldmVuIGlmCisvLyB5b3UgZ2V0IHRoZSBjb2RlIHJpZ2h0LCBpdCB3aWxsIGRlcGVuZCBvbiBjYXJlZnVsIHJlYXNvbmluZyBhYm91dCBhdG9taWNpdHkKKy8vIGFuZCBtZW1vcnkgb3JkZXJpbmc7IGl0IHdpbGwgYmUgbGVzcyByZWFkYWJsZSwgYW5kIGhhcmRlciB0byBtYWludGFpbi4gIElmCisvLyB5b3UgcGxhbiB0byB1c2UgdGhlc2Ugcm91dGluZXMsIHlvdSBzaG91bGQgaGF2ZSBhIGdvb2QgcmVhc29uLCBzdWNoIGFzIHNvbGlkCisvLyBldmlkZW5jZSB0aGF0IHBlcmZvcm1hbmNlIHdvdWxkIG90aGVyd2lzZSBzdWZmZXIsIG9yIHRoZXJlIGJlaW5nIG5vCisvLyBhbHRlcm5hdGl2ZS4gIFlvdSBzaG91bGQgYXNzdW1lIG9ubHkgcHJvcGVydGllcyBleHBsaWNpdGx5IGd1YXJhbnRlZWQgYnkgdGhlCisvLyBzcGVjaWZpY2F0aW9ucyBpbiB0aGlzIGZpbGUuICBZb3UgYXJlIGFsbW9zdCBjZXJ0YWlubHkgX25vdF8gd3JpdGluZyBjb2RlCisvLyBqdXN0IGZvciB0aGUgeDg2OyBpZiB5b3UgYXNzdW1lIHg4NiBzZW1hbnRpY3MsIHg4NiBoYXJkd2FyZSBidWdzIGFuZAorLy8gaW1wbGVtZW50YXRpb25zIG9uIG90aGVyIGFyY2h0ZWN0dXJlcyB3aWxsIGNhdXNlIHlvdXIgY29kZSB0byBicmVhay4gIElmIHlvdQorLy8gZG8gbm90IGtub3cgd2hhdCB5b3UgYXJlIGRvaW5nLCBhdm9pZCB0aGVzZSByb3V0aW5lcywgYW5kIHVzZSBhIE11dGV4LgorLy8KKy8vIEl0IGlzIGluY29ycmVjdCB0byBtYWtlIGRpcmVjdCBhc3NpZ25tZW50cyB0by9mcm9tIGFuIGF0b21pYyB2YXJpYWJsZS4KKy8vIFlvdSBzaG91bGQgdXNlIG9uZSBvZiB0aGUgTG9hZCBvciBTdG9yZSByb3V0aW5lcy4gIFRoZSBOb0JhcnJpZXIKKy8vIHZlcnNpb25zIGFyZSBwcm92aWRlZCB3aGVuIG5vIGJhcnJpZXJzIGFyZSBuZWVkZWQ6CisvLyAgIE5vQmFycmllcl9TdG9yZSgpCisvLyAgIE5vQmFycmllcl9Mb2FkKCkKKy8vIEFsdGhvdWdoIHRoZXJlIGFyZSBjdXJyZW50bHkgbm8gY29tcGlsZXIgZW5mb3JjZW1lbnQsIHlvdSBhcmUgZW5jb3VyYWdlZAorLy8gdG8gdXNlIHRoZXNlLgorCisvLyBUaGlzIGhlYWRlciBhbmQgdGhlIGltcGxlbWVudGF0aW9ucyBmb3IgZWFjaCBwbGF0Zm9ybSAobG9jYXRlZCBpbgorLy8gYXRvbWljb3BzX2ludGVybmFsc18qKSBtdXN0IGJlIGtlcHQgaW4gc3luYyB3aXRoIHRoZSB1cHN0cmVhbSBjb2RlIChWOCkuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19IXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQVRPTUlDT1BTX0hfCisKKy8vIERvbid0IGluY2x1ZGUgdGhpcyBmaWxlIGZvciBwZW9wbGUgbm90IGNvbmNlcm5lZCBhYm91dCB0aHJlYWQgc2FmZXR5LgorI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfTk9fVEhSRUFEX1NBRkVUWQorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9wbGF0Zm9ybV9tYWNyb3MuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKworI2lmIGRlZmluZWQoR09PR0xFX1BST1RPQlVGX0FSQ0hfUE9XRVIpCisjaWYgZGVmaW5lZChfTFA2NCkgfHwgZGVmaW5lZChfX0xQNjRfXykKK3R5cGVkZWYgaW50MzIgQXRvbWljMzI7Cit0eXBlZGVmIGludHB0cl90IEF0b21pYzY0OworI2Vsc2UKK3R5cGVkZWYgaW50cHRyX3QgQXRvbWljMzI7Cit0eXBlZGVmIGludDY0IEF0b21pYzY0OworI2VuZGlmCisjZWxzZQordHlwZWRlZiBpbnQzMiBBdG9taWMzMjsKKyNpZmRlZiBHT09HTEVfUFJPVE9CVUZfQVJDSF82NF9CSVQKKy8vIFdlIG5lZWQgdG8gYmUgYWJsZSB0byBnbyBiZXR3ZWVuIEF0b21pYzY0IGFuZCBBdG9taWNXb3JkIGltcGxpY2l0bHkuICBUaGlzCisvLyBtZWFucyBBdG9taWM2NCBhbmQgQXRvbWljV29yZCBzaG91bGQgYmUgdGhlIHNhbWUgdHlwZSBvbiA2NC1iaXQuCisjaWYgZGVmaW5lZChfX0lMUDMyX18pIHx8IGRlZmluZWQoR09PR0xFX1BST1RPQlVGX09TX05BQ0wpCisvLyBOYUNsJ3MgaW50cHRyX3QgaXMgbm90IGFjdHVhbGx5IDY0LWJpdHMgb24gNjQtYml0IQorLy8gaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL25hdGl2ZWNsaWVudC9pc3N1ZXMvZGV0YWlsP2lkPTExNjIKKy8vIHNwYXJjdjkncyBwb2ludGVyIHR5cGUgaXMgMzJiaXRzCit0eXBlZGVmIGludDY0IEF0b21pYzY0OworI2Vsc2UKK3R5cGVkZWYgaW50cHRyX3QgQXRvbWljNjQ7CisjZW5kaWYKKyNlbmRpZgorI2VuZGlmCisKKy8vIFVzZSBBdG9taWNXb3JkIGZvciBhIG1hY2hpbmUtc2l6ZWQgcG9pbnRlci4gIEl0IHdpbGwgdXNlIHRoZSBBdG9taWMzMiBvcgorLy8gQXRvbWljNjQgcm91dGluZXMgYmVsb3csIGRlcGVuZGluZyBvbiB5b3VyIGFyY2hpdGVjdHVyZS4KK3R5cGVkZWYgaW50cHRyX3QgQXRvbWljV29yZDsKKworLy8gQXRvbWljYWxseSBleGVjdXRlOgorLy8gICAgICByZXN1bHQgPSAqcHRyOworLy8gICAgICBpZiAoKnB0ciA9PSBvbGRfdmFsdWUpCisvLyAgICAgICAgKnB0ciA9IG5ld192YWx1ZTsKKy8vICAgICAgcmV0dXJuIHJlc3VsdDsKKy8vCisvLyBJLmUuLCByZXBsYWNlICIqcHRyIiB3aXRoICJuZXdfdmFsdWUiIGlmICIqcHRyIiB1c2VkIHRvIGJlICJvbGRfdmFsdWUiLgorLy8gQWx3YXlzIHJldHVybiB0aGUgb2xkIHZhbHVlIG9mICIqcHRyIgorLy8KKy8vIFRoaXMgcm91dGluZSBpbXBsaWVzIG5vIG1lbW9yeSBiYXJyaWVycy4KK0F0b21pYzMyIE5vQmFycmllcl9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBuZXdfdmFsdWUpOworCisvLyBBdG9taWNhbGx5IHN0b3JlIG5ld192YWx1ZSBpbnRvICpwdHIsIHJldHVybmluZyB0aGUgcHJldmlvdXMgdmFsdWUgaGVsZCBpbgorLy8gKnB0ci4gIFRoaXMgcm91dGluZSBpbXBsaWVzIG5vIG1lbW9yeSBiYXJyaWVycy4KK0F0b21pYzMyIE5vQmFycmllcl9BdG9taWNFeGNoYW5nZSh2b2xhdGlsZSBBdG9taWMzMiogcHRyLCBBdG9taWMzMiBuZXdfdmFsdWUpOworCisvLyBBdG9taWNhbGx5IGluY3JlbWVudCAqcHRyIGJ5ICJpbmNyZW1lbnQiLiAgUmV0dXJucyB0aGUgbmV3IHZhbHVlIG9mCisvLyAqcHRyIHdpdGggdGhlIGluY3JlbWVudCBhcHBsaWVkLiAgVGhpcyByb3V0aW5lIGltcGxpZXMgbm8gbWVtb3J5IGJhcnJpZXJzLgorQXRvbWljMzIgTm9CYXJyaWVyX0F0b21pY0luY3JlbWVudCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLCBBdG9taWMzMiBpbmNyZW1lbnQpOworCitBdG9taWMzMiBCYXJyaWVyX0F0b21pY0luY3JlbWVudCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgaW5jcmVtZW50KTsKKworLy8gVGhlc2UgZm9sbG93aW5nIGxvd2VyLWxldmVsIG9wZXJhdGlvbnMgYXJlIHR5cGljYWxseSB1c2VmdWwgb25seSB0byBwZW9wbGUKKy8vIGltcGxlbWVudGluZyBoaWdoZXItbGV2ZWwgc3luY2hyb25pemF0aW9uIG9wZXJhdGlvbnMgbGlrZSBzcGlubG9ja3MsCisvLyBtdXRleGVzLCBhbmQgY29uZGl0aW9uLXZhcmlhYmxlcy4gIFRoZXkgY29tYmluZSBDb21wYXJlQW5kU3dhcCgpLCBhIGxvYWQsIG9yCisvLyBhIHN0b3JlIHdpdGggYXBwcm9wcmlhdGUgbWVtb3J5LW9yZGVyaW5nIGluc3RydWN0aW9ucy4gICJBY3F1aXJlIiBvcGVyYXRpb25zCisvLyBlbnN1cmUgdGhhdCBubyBsYXRlciBtZW1vcnkgYWNjZXNzIGNhbiBiZSByZW9yZGVyZWQgYWhlYWQgb2YgdGhlIG9wZXJhdGlvbi4KKy8vICJSZWxlYXNlIiBvcGVyYXRpb25zIGVuc3VyZSB0aGF0IG5vIHByZXZpb3VzIG1lbW9yeSBhY2Nlc3MgY2FuIGJlIHJlb3JkZXJlZAorLy8gYWZ0ZXIgdGhlIG9wZXJhdGlvbi4gICJCYXJyaWVyIiBvcGVyYXRpb25zIGhhdmUgYm90aCAiQWNxdWlyZSIgYW5kICJSZWxlYXNlIgorLy8gc2VtYW50aWNzLiAgIEEgTWVtb3J5QmFycmllcigpIGhhcyAiQmFycmllciIgc2VtYW50aWNzLCBidXQgZG9lcyBubyBtZW1vcnkKKy8vIGFjY2Vzcy4KK0F0b21pYzMyIEFjcXVpcmVfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBuZXdfdmFsdWUpOworQXRvbWljMzIgUmVsZWFzZV9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG5ld192YWx1ZSk7CisKKyNpZiBkZWZpbmVkKF9fTUlOR1czMl9fKSAmJiBkZWZpbmVkKE1lbW9yeUJhcnJpZXIpCisjdW5kZWYgTWVtb3J5QmFycmllcgorI2VuZGlmCit2b2lkIE1lbW9yeUJhcnJpZXIoKTsKK3ZvaWQgTm9CYXJyaWVyX1N0b3JlKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsIEF0b21pYzMyIHZhbHVlKTsKK3ZvaWQgQWNxdWlyZV9TdG9yZSh2b2xhdGlsZSBBdG9taWMzMiogcHRyLCBBdG9taWMzMiB2YWx1ZSk7Cit2b2lkIFJlbGVhc2VfU3RvcmUodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwgQXRvbWljMzIgdmFsdWUpOworCitBdG9taWMzMiBOb0JhcnJpZXJfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWMzMiogcHRyKTsKK0F0b21pYzMyIEFjcXVpcmVfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWMzMiogcHRyKTsKK0F0b21pYzMyIFJlbGVhc2VfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWMzMiogcHRyKTsKKworLy8gNjQtYml0IGF0b21pYyBvcGVyYXRpb25zIChvbmx5IGF2YWlsYWJsZSBvbiA2NC1iaXQgcHJvY2Vzc29ycykuCisjaWZkZWYgR09PR0xFX1BST1RPQlVGX0FSQ0hfNjRfQklUCitBdG9taWM2NCBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgbmV3X3ZhbHVlKTsKK0F0b21pYzY0IE5vQmFycmllcl9BdG9taWNFeGNoYW5nZSh2b2xhdGlsZSBBdG9taWM2NCogcHRyLCBBdG9taWM2NCBuZXdfdmFsdWUpOworQXRvbWljNjQgTm9CYXJyaWVyX0F0b21pY0luY3JlbWVudCh2b2xhdGlsZSBBdG9taWM2NCogcHRyLCBBdG9taWM2NCBpbmNyZW1lbnQpOworQXRvbWljNjQgQmFycmllcl9BdG9taWNJbmNyZW1lbnQodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwgQXRvbWljNjQgaW5jcmVtZW50KTsKKworQXRvbWljNjQgQWNxdWlyZV9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWM2NCogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG5ld192YWx1ZSk7CitBdG9taWM2NCBSZWxlYXNlX0NvbXBhcmVBbmRTd2FwKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgbmV3X3ZhbHVlKTsKK3ZvaWQgTm9CYXJyaWVyX1N0b3JlKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsIEF0b21pYzY0IHZhbHVlKTsKK3ZvaWQgQWNxdWlyZV9TdG9yZSh2b2xhdGlsZSBBdG9taWM2NCogcHRyLCBBdG9taWM2NCB2YWx1ZSk7Cit2b2lkIFJlbGVhc2VfU3RvcmUodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwgQXRvbWljNjQgdmFsdWUpOworQXRvbWljNjQgTm9CYXJyaWVyX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljNjQqIHB0cik7CitBdG9taWM2NCBBY3F1aXJlX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljNjQqIHB0cik7CitBdG9taWM2NCBSZWxlYXNlX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljNjQqIHB0cik7CisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9BUkNIXzY0X0JJVAorCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisvLyBJbmNsdWRlIG91ciBwbGF0Zm9ybSBzcGVjaWZpYyBpbXBsZW1lbnRhdGlvbi4KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19FUlJPUiBcCisiQXRvbWljIG9wZXJhdGlvbnMgYXJlIG5vdCBzdXBwb3J0ZWQgb24geW91ciBwbGF0Zm9ybSIKKworLy8gVGhyZWFkU2FuaXRpemVyLCBodHRwOi8vY2xhbmcubGx2bS5vcmcvZG9jcy9UaHJlYWRTYW5pdGl6ZXIuaHRtbC4KKyNpZiBkZWZpbmVkKFRIUkVBRF9TQU5JVElaRVIpCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfdHNhbi5oPgorLy8gTVNWQy4KKyNlbGlmIGRlZmluZWQoX01TQ19WRVIpCisjaWYgZGVmaW5lZChHT09HTEVfUFJPVE9CVUZfQVJDSF9JQTMyKSB8fCBkZWZpbmVkKEdPT0dMRV9QUk9UT0JVRl9BUkNIX1g2NCkKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc194ODZfbXN2Yy5oPgorI2Vsc2UKKyNlcnJvciBHT09HTEVfUFJPVE9CVUZfQVRPTUlDT1BTX0VSUk9SCisjZW5kaWYKKworLy8gU29sYXJpcworI2VsaWYgZGVmaW5lZChHT09HTEVfUFJPVE9CVUZfT1NfU09MQVJJUykKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc19zb2xhcmlzLmg+CisKKy8vIEFJWAorI2VsaWYgZGVmaW5lZChHT09HTEVfUFJPVE9CVUZfT1NfQUlYKQorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX3Bvd2VyLmg+CisKKy8vIEFwcGxlLgorI2VsaWYgZGVmaW5lZChHT09HTEVfUFJPVE9CVUZfT1NfQVBQTEUpCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfbWFjb3N4Lmg+CisKKy8vIEdDQy4KKyNlbGlmIGRlZmluZWQoX19HTlVDX18pCisjaWYgZGVmaW5lZChHT09HTEVfUFJPVE9CVUZfQVJDSF9JQTMyKSB8fCBkZWZpbmVkKEdPT0dMRV9QUk9UT0JVRl9BUkNIX1g2NCkKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc194ODZfZ2NjLmg+CisjZWxpZiBkZWZpbmVkKEdPT0dMRV9QUk9UT0JVRl9BUkNIX0FSTSkgJiYgZGVmaW5lZChfX2xpbnV4X18pCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfYXJtX2djYy5oPgorI2VsaWYgZGVmaW5lZChHT09HTEVfUFJPVE9CVUZfQVJDSF9BQVJDSDY0KQorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX2FybTY0X2djYy5oPgorI2VsaWYgZGVmaW5lZChHT09HTEVfUFJPVE9CVUZfQVJDSF9BUk1fUU5YKQorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX2FybV9xbnguaD4KKyNlbGlmIGRlZmluZWQoR09PR0xFX1BST1RPQlVGX0FSQ0hfTUlQUykgfHwgZGVmaW5lZChHT09HTEVfUFJPVE9CVUZfQVJDSF9NSVBTNjQpCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfbWlwc19nY2MuaD4KKyNlbGlmIGRlZmluZWQoR09PR0xFX1BST1RPQlVGX0FSQ0hfUE9XRVIpCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfcG93ZXIuaD4KKyNlbGlmIGRlZmluZWQoX19uYXRpdmVfY2xpZW50X18pCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfcG5hY2wuaD4KKyNlbGlmICgoKF9fR05VQ19fID09IDQpICYmIChfX0dOVUNfTUlOT1JfXyA+PSA3KSkgfHwgKF9fR05VQ19fID4gNCkpCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfZ2VuZXJpY19nY2MuaD4KKyNlbGlmIGRlZmluZWQoX19jbGFuZ19fKQorI2lmIF9faGFzX2V4dGVuc2lvbihjX2F0b21pYykKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc19nZW5lcmljX2djYy5oPgorI2Vsc2UKKyNlcnJvciBHT09HTEVfUFJPVE9CVUZfQVRPTUlDT1BTX0VSUk9SCisjZW5kaWYKKyNlbHNlCisjZXJyb3IgR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19FUlJPUgorI2VuZGlmCisKKy8vIFVua25vd24uCisjZWxzZQorI2Vycm9yIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNPUFNfRVJST1IKKyNlbmRpZgorCisvLyBPbiBzb21lIHBsYXRmb3JtcyB3ZSBuZWVkIGFkZGl0aW9uYWwgZGVjbGFyYXRpb25zIHRvIG1ha2UgQXRvbWljV29yZAorLy8gY29tcGF0aWJsZSB3aXRoIG91ciBvdGhlciBBdG9taWMqIHR5cGVzLgorI2lmIGRlZmluZWQoR09PR0xFX1BST1RPQlVGX09TX0FQUExFKQorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX2F0b21pY3dvcmRfY29tcGF0Lmg+CisjZW5kaWYKKworI3VuZGVmIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNPUFNfRVJST1IKKworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfTk9fVEhSRUFEX1NBRkVUWQorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNPUFNfSF8KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc19hcm02NF9nY2MuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc19hcm02NF9nY2MuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wYTJkMmI4Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX2FybTY0X2djYy5oCkBAIC0wLDAgKzEsMzI1IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDEyIEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gVGhpcyBmaWxlIGlzIGFuIGludGVybmFsIGF0b21pYyBpbXBsZW1lbnRhdGlvbiwgdXNlIGF0b21pY29wcy5oIGluc3RlYWQuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19JTlRFUk5BTFNfQVJNNjRfR0NDX0hfCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNPUFNfSU5URVJOQUxTX0FSTTY0X0dDQ19IXworCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW50ZXJuYWwgeworCitpbmxpbmUgdm9pZCBNZW1vcnlCYXJyaWVyKCkgeworICBfX2FzbV9fIF9fdm9sYXRpbGVfXyAoImRtYiBpc2giIDo6OiAibWVtb3J5Iik7ICAvLyBOT0xJTlQKK30KKworLy8gTm9CYXJyaWVyIHZlcnNpb25zIG9mIHRoZSBvcGVyYXRpb24gaW5jbHVkZSAibWVtb3J5IiBpbiB0aGUgY2xvYmJlciBsaXN0LgorLy8gVGhpcyBpcyBub3QgcmVxdWlyZWQgZm9yIGRpcmVjdCB1c2FnZSBvZiB0aGUgTm9CYXJyaWVyIHZlcnNpb25zIG9mIHRoZQorLy8gb3BlcmF0aW9ucy4gSG93ZXZlciB0aGlzIGlzIHJlcXVpcmVkIGZvciBjb3JyZWN0bmVzcyB3aGVuIHRoZXkgYXJlIHVzZWQgYXMKKy8vIHBhcnQgb2YgdGhlIEFjcXVpcmUgb3IgUmVsZWFzZSB2ZXJzaW9ucywgdG8gZW5zdXJlIHRoYXQgbm90aGluZyBmcm9tIG91dHNpZGUKKy8vIHRoZSBjYWxsIGlzIHJlb3JkZXJlZCBiZXR3ZWVuIHRoZSBvcGVyYXRpb24gYW5kIHRoZSBtZW1vcnkgYmFycmllci4gVGhpcyBkb2VzCisvLyBub3QgY2hhbmdlIHRoZSBjb2RlIGdlbmVyYXRlZCwgc28gaGFzIG5vIG9yIG1pbmltYWwgaW1wYWN0IG9uIHRoZQorLy8gTm9CYXJyaWVyIG9wZXJhdGlvbnMuCisKK2lubGluZSBBdG9taWMzMiBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBuZXdfdmFsdWUpIHsKKyAgQXRvbWljMzIgcHJldjsKKyAgaW50MzJfdCB0ZW1wOworCisgIF9fYXNtX18gX192b2xhdGlsZV9fICggIC8vIE5PTElOVAorICAgICIwOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuXHQiCisgICAgImxkeHIgJXdbcHJldl0sICVbcHRyXSAgICAgICAgICAgICAgICAgXG5cdCIgIC8vIExvYWQgdGhlIHByZXZpb3VzIHZhbHVlLgorICAgICJjbXAgJXdbcHJldl0sICV3W29sZF92YWx1ZV0gICAgICAgICAgIFxuXHQiCisgICAgImJuZSAxZiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG5cdCIKKyAgICAic3R4ciAld1t0ZW1wXSwgJXdbbmV3X3ZhbHVlXSwgJVtwdHJdICBcblx0IiAgLy8gVHJ5IHRvIHN0b3JlIHRoZSBuZXcgdmFsdWUuCisgICAgImNibnogJXdbdGVtcF0sIDBiICAgICAgICAgICAgICAgICAgICAgXG5cdCIgIC8vIFJldHJ5IGlmIGl0IGRpZCBub3Qgd29yay4KKyAgICAiMTogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcblx0IgorICAgIDogW3ByZXZdIj0mciIgKHByZXYpLAorICAgICAgW3RlbXBdIj0mciIgKHRlbXApLAorICAgICAgW3B0cl0iK1EiICgqcHRyKQorICAgIDogW29sZF92YWx1ZV0iSUpyIiAob2xkX3ZhbHVlKSwKKyAgICAgIFtuZXdfdmFsdWVdInIiIChuZXdfdmFsdWUpCisgICAgOiAiY2MiLCAibWVtb3J5IgorICApOyAgLy8gTk9MSU5UCisKKyAgcmV0dXJuIHByZXY7Cit9CisKK2lubGluZSBBdG9taWMzMiBOb0JhcnJpZXJfQXRvbWljRXhjaGFuZ2Uodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgbmV3X3ZhbHVlKSB7CisgIEF0b21pYzMyIHJlc3VsdDsKKyAgaW50MzJfdCB0ZW1wOworCisgIF9fYXNtX18gX192b2xhdGlsZV9fICggIC8vIE5PTElOVAorICAgICIwOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuXHQiCisgICAgImxkeHIgJXdbcmVzdWx0XSwgJVtwdHJdICAgICAgICAgICAgICAgXG5cdCIgIC8vIExvYWQgdGhlIHByZXZpb3VzIHZhbHVlLgorICAgICJzdHhyICV3W3RlbXBdLCAld1tuZXdfdmFsdWVdLCAlW3B0cl0gIFxuXHQiICAvLyBUcnkgdG8gc3RvcmUgdGhlIG5ldyB2YWx1ZS4KKyAgICAiY2JueiAld1t0ZW1wXSwgMGIgICAgICAgICAgICAgICAgICAgICBcblx0IiAgLy8gUmV0cnkgaWYgaXQgZGlkIG5vdCB3b3JrLgorICAgIDogW3Jlc3VsdF0iPSZyIiAocmVzdWx0KSwKKyAgICAgIFt0ZW1wXSI9JnIiICh0ZW1wKSwKKyAgICAgIFtwdHJdIitRIiAoKnB0cikKKyAgICA6IFtuZXdfdmFsdWVdInIiIChuZXdfdmFsdWUpCisgICAgOiAibWVtb3J5IgorICApOyAgLy8gTk9MSU5UCisKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworaW5saW5lIEF0b21pYzMyIE5vQmFycmllcl9BdG9taWNJbmNyZW1lbnQodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIGluY3JlbWVudCkgeworICBBdG9taWMzMiByZXN1bHQ7CisgIGludDMyX3QgdGVtcDsKKworICBfX2FzbV9fIF9fdm9sYXRpbGVfXyAoICAvLyBOT0xJTlQKKyAgICAiMDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcblx0IgorICAgICJsZHhyICV3W3Jlc3VsdF0sICVbcHRyXSAgICAgICAgICAgICAgICAgIFxuXHQiICAvLyBMb2FkIHRoZSBwcmV2aW91cyB2YWx1ZS4KKyAgICAiYWRkICV3W3Jlc3VsdF0sICV3W3Jlc3VsdF0sICV3W2luY3JlbWVudF1cblx0IgorICAgICJzdHhyICV3W3RlbXBdLCAld1tyZXN1bHRdLCAlW3B0cl0gICAgICAgIFxuXHQiICAvLyBUcnkgdG8gc3RvcmUgdGhlIHJlc3VsdC4KKyAgICAiY2JueiAld1t0ZW1wXSwgMGIgICAgICAgICAgICAgICAgICAgICAgICBcblx0IiAgLy8gUmV0cnkgb24gZmFpbHVyZS4KKyAgICA6IFtyZXN1bHRdIj0mciIgKHJlc3VsdCksCisgICAgICBbdGVtcF0iPSZyIiAodGVtcCksCisgICAgICBbcHRyXSIrUSIgKCpwdHIpCisgICAgOiBbaW5jcmVtZW50XSJJSnIiIChpbmNyZW1lbnQpCisgICAgOiAibWVtb3J5IgorICApOyAgLy8gTk9MSU5UCisKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworaW5saW5lIEF0b21pYzMyIEJhcnJpZXJfQXRvbWljSW5jcmVtZW50KHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgaW5jcmVtZW50KSB7CisgIE1lbW9yeUJhcnJpZXIoKTsKKyAgQXRvbWljMzIgcmVzdWx0ID0gTm9CYXJyaWVyX0F0b21pY0luY3JlbWVudChwdHIsIGluY3JlbWVudCk7CisgIE1lbW9yeUJhcnJpZXIoKTsKKworICByZXR1cm4gcmVzdWx0OworfQorCitpbmxpbmUgQXRvbWljMzIgQWNxdWlyZV9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgbmV3X3ZhbHVlKSB7CisgIEF0b21pYzMyIHByZXYgPSBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAocHRyLCBvbGRfdmFsdWUsIG5ld192YWx1ZSk7CisgIE1lbW9yeUJhcnJpZXIoKTsKKworICByZXR1cm4gcHJldjsKK30KKworaW5saW5lIEF0b21pYzMyIFJlbGVhc2VfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG5ld192YWx1ZSkgeworICBNZW1vcnlCYXJyaWVyKCk7CisgIEF0b21pYzMyIHByZXYgPSBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAocHRyLCBvbGRfdmFsdWUsIG5ld192YWx1ZSk7CisKKyAgcmV0dXJuIHByZXY7Cit9CisKK2lubGluZSB2b2lkIE5vQmFycmllcl9TdG9yZSh2b2xhdGlsZSBBdG9taWMzMiogcHRyLCBBdG9taWMzMiB2YWx1ZSkgeworICAqcHRyID0gdmFsdWU7Cit9CisKK2lubGluZSB2b2lkIEFjcXVpcmVfU3RvcmUodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwgQXRvbWljMzIgdmFsdWUpIHsKKyAgKnB0ciA9IHZhbHVlOworICBNZW1vcnlCYXJyaWVyKCk7Cit9CisKK2lubGluZSB2b2lkIFJlbGVhc2VfU3RvcmUodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwgQXRvbWljMzIgdmFsdWUpIHsKKyAgX19hc21fXyBfX3ZvbGF0aWxlX18gKCAgLy8gTk9MSU5UCisgICAgInN0bHIgJXdbdmFsdWVdLCAlW3B0cl0gIFxuXHQiCisgICAgOiBbcHRyXSI9USIgKCpwdHIpCisgICAgOiBbdmFsdWVdInIiICh2YWx1ZSkKKyAgICA6ICJtZW1vcnkiCisgICk7ICAvLyBOT0xJTlQKK30KKworaW5saW5lIEF0b21pYzMyIE5vQmFycmllcl9Mb2FkKHZvbGF0aWxlIGNvbnN0IEF0b21pYzMyKiBwdHIpIHsKKyAgcmV0dXJuICpwdHI7Cit9CisKK2lubGluZSBBdG9taWMzMiBBY3F1aXJlX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljMzIqIHB0cikgeworICBBdG9taWMzMiB2YWx1ZTsKKworICBfX2FzbV9fIF9fdm9sYXRpbGVfXyAoICAvLyBOT0xJTlQKKyAgICAibGRhciAld1t2YWx1ZV0sICVbcHRyXSAgXG5cdCIKKyAgICA6IFt2YWx1ZV0iPXIiICh2YWx1ZSkKKyAgICA6IFtwdHJdIlEiICgqcHRyKQorICAgIDogIm1lbW9yeSIKKyAgKTsgIC8vIE5PTElOVAorCisgIHJldHVybiB2YWx1ZTsKK30KKworaW5saW5lIEF0b21pYzMyIFJlbGVhc2VfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWMzMiogcHRyKSB7CisgIE1lbW9yeUJhcnJpZXIoKTsKKyAgcmV0dXJuICpwdHI7Cit9CisKKy8vIDY0LWJpdCB2ZXJzaW9ucyBvZiB0aGUgb3BlcmF0aW9ucy4KKy8vIFNlZSB0aGUgMzItYml0IHZlcnNpb25zIGZvciBjb21tZW50cy4KKworaW5saW5lIEF0b21pYzY0IE5vQmFycmllcl9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWM2NCogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG5ld192YWx1ZSkgeworICBBdG9taWM2NCBwcmV2OworICBpbnQzMl90IHRlbXA7CisKKyAgX19hc21fXyBfX3ZvbGF0aWxlX18gKCAgLy8gTk9MSU5UCisgICAgIjA6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG5cdCIKKyAgICAibGR4ciAlW3ByZXZdLCAlW3B0cl0gICAgICAgICAgICAgICAgICBcblx0IgorICAgICJjbXAgJVtwcmV2XSwgJVtvbGRfdmFsdWVdICAgICAgICAgICAgIFxuXHQiCisgICAgImJuZSAxZiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG5cdCIKKyAgICAic3R4ciAld1t0ZW1wXSwgJVtuZXdfdmFsdWVdLCAlW3B0cl0gICBcblx0IgorICAgICJjYm56ICV3W3RlbXBdLCAwYiAgICAgICAgICAgICAgICAgICAgIFxuXHQiCisgICAgIjE6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG5cdCIKKyAgICA6IFtwcmV2XSI9JnIiIChwcmV2KSwKKyAgICAgIFt0ZW1wXSI9JnIiICh0ZW1wKSwKKyAgICAgIFtwdHJdIitRIiAoKnB0cikKKyAgICA6IFtvbGRfdmFsdWVdIklKciIgKG9sZF92YWx1ZSksCisgICAgICBbbmV3X3ZhbHVlXSJyIiAobmV3X3ZhbHVlKQorICAgIDogImNjIiwgIm1lbW9yeSIKKyAgKTsgIC8vIE5PTElOVAorCisgIHJldHVybiBwcmV2OworfQorCitpbmxpbmUgQXRvbWljNjQgTm9CYXJyaWVyX0F0b21pY0V4Y2hhbmdlKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG5ld192YWx1ZSkgeworICBBdG9taWM2NCByZXN1bHQ7CisgIGludDMyX3QgdGVtcDsKKworICBfX2FzbV9fIF9fdm9sYXRpbGVfXyAoICAvLyBOT0xJTlQKKyAgICAiMDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcblx0IgorICAgICJsZHhyICVbcmVzdWx0XSwgJVtwdHJdICAgICAgICAgICAgICAgIFxuXHQiCisgICAgInN0eHIgJXdbdGVtcF0sICVbbmV3X3ZhbHVlXSwgJVtwdHJdICAgXG5cdCIKKyAgICAiY2JueiAld1t0ZW1wXSwgMGIgICAgICAgICAgICAgICAgICAgICBcblx0IgorICAgIDogW3Jlc3VsdF0iPSZyIiAocmVzdWx0KSwKKyAgICAgIFt0ZW1wXSI9JnIiICh0ZW1wKSwKKyAgICAgIFtwdHJdIitRIiAoKnB0cikKKyAgICA6IFtuZXdfdmFsdWVdInIiIChuZXdfdmFsdWUpCisgICAgOiAibWVtb3J5IgorICApOyAgLy8gTk9MSU5UCisKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworaW5saW5lIEF0b21pYzY0IE5vQmFycmllcl9BdG9taWNJbmNyZW1lbnQodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IGluY3JlbWVudCkgeworICBBdG9taWM2NCByZXN1bHQ7CisgIGludDMyX3QgdGVtcDsKKworICBfX2FzbV9fIF9fdm9sYXRpbGVfXyAoICAvLyBOT0xJTlQKKyAgICAiMDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG5cdCIKKyAgICAibGR4ciAlW3Jlc3VsdF0sICVbcHRyXSAgICAgICAgICAgICAgICAgXG5cdCIKKyAgICAiYWRkICVbcmVzdWx0XSwgJVtyZXN1bHRdLCAlW2luY3JlbWVudF0gXG5cdCIKKyAgICAic3R4ciAld1t0ZW1wXSwgJVtyZXN1bHRdLCAlW3B0cl0gICAgICAgXG5cdCIKKyAgICAiY2JueiAld1t0ZW1wXSwgMGIgICAgICAgICAgICAgICAgICAgICAgXG5cdCIKKyAgICA6IFtyZXN1bHRdIj0mciIgKHJlc3VsdCksCisgICAgICBbdGVtcF0iPSZyIiAodGVtcCksCisgICAgICBbcHRyXSIrUSIgKCpwdHIpCisgICAgOiBbaW5jcmVtZW50XSJJSnIiIChpbmNyZW1lbnQpCisgICAgOiAibWVtb3J5IgorICApOyAgLy8gTk9MSU5UCisKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworaW5saW5lIEF0b21pYzY0IEJhcnJpZXJfQXRvbWljSW5jcmVtZW50KHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgaW5jcmVtZW50KSB7CisgIE1lbW9yeUJhcnJpZXIoKTsKKyAgQXRvbWljNjQgcmVzdWx0ID0gTm9CYXJyaWVyX0F0b21pY0luY3JlbWVudChwdHIsIGluY3JlbWVudCk7CisgIE1lbW9yeUJhcnJpZXIoKTsKKworICByZXR1cm4gcmVzdWx0OworfQorCitpbmxpbmUgQXRvbWljNjQgQWNxdWlyZV9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWM2NCogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgbmV3X3ZhbHVlKSB7CisgIEF0b21pYzY0IHByZXYgPSBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAocHRyLCBvbGRfdmFsdWUsIG5ld192YWx1ZSk7CisgIE1lbW9yeUJhcnJpZXIoKTsKKworICByZXR1cm4gcHJldjsKK30KKworaW5saW5lIEF0b21pYzY0IFJlbGVhc2VfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG5ld192YWx1ZSkgeworICBNZW1vcnlCYXJyaWVyKCk7CisgIEF0b21pYzY0IHByZXYgPSBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAocHRyLCBvbGRfdmFsdWUsIG5ld192YWx1ZSk7CisKKyAgcmV0dXJuIHByZXY7Cit9CisKK2lubGluZSB2b2lkIE5vQmFycmllcl9TdG9yZSh2b2xhdGlsZSBBdG9taWM2NCogcHRyLCBBdG9taWM2NCB2YWx1ZSkgeworICAqcHRyID0gdmFsdWU7Cit9CisKK2lubGluZSB2b2lkIEFjcXVpcmVfU3RvcmUodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwgQXRvbWljNjQgdmFsdWUpIHsKKyAgKnB0ciA9IHZhbHVlOworICBNZW1vcnlCYXJyaWVyKCk7Cit9CisKK2lubGluZSB2b2lkIFJlbGVhc2VfU3RvcmUodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwgQXRvbWljNjQgdmFsdWUpIHsKKyAgX19hc21fXyBfX3ZvbGF0aWxlX18gKCAgLy8gTk9MSU5UCisgICAgInN0bHIgJXhbdmFsdWVdLCAlW3B0cl0gIFxuXHQiCisgICAgOiBbcHRyXSI9USIgKCpwdHIpCisgICAgOiBbdmFsdWVdInIiICh2YWx1ZSkKKyAgICA6ICJtZW1vcnkiCisgICk7ICAvLyBOT0xJTlQKK30KKworaW5saW5lIEF0b21pYzY0IE5vQmFycmllcl9Mb2FkKHZvbGF0aWxlIGNvbnN0IEF0b21pYzY0KiBwdHIpIHsKKyAgcmV0dXJuICpwdHI7Cit9CisKK2lubGluZSBBdG9taWM2NCBBY3F1aXJlX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljNjQqIHB0cikgeworICBBdG9taWM2NCB2YWx1ZTsKKworICBfX2FzbV9fIF9fdm9sYXRpbGVfXyAoICAvLyBOT0xJTlQKKyAgICAibGRhciAleFt2YWx1ZV0sICVbcHRyXSAgXG5cdCIKKyAgICA6IFt2YWx1ZV0iPXIiICh2YWx1ZSkKKyAgICA6IFtwdHJdIlEiICgqcHRyKQorICAgIDogIm1lbW9yeSIKKyAgKTsgIC8vIE5PTElOVAorCisgIHJldHVybiB2YWx1ZTsKK30KKworaW5saW5lIEF0b21pYzY0IFJlbGVhc2VfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWM2NCogcHRyKSB7CisgIE1lbW9yeUJhcnJpZXIoKTsKKyAgcmV0dXJuICpwdHI7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19JTlRFUk5BTFNfQVJNNjRfR0NDX0hfCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfYXJtX2djYy5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX2FybV9nY2MuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45MGU3MjdiCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX2FybV9nY2MuaApAQCAtMCwwICsxLDE1MSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAxMiBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIFRoaXMgZmlsZSBpcyBhbiBpbnRlcm5hbCBhdG9taWMgaW1wbGVtZW50YXRpb24sIHVzZSBhdG9taWNvcHMuaCBpbnN0ZWFkLgorLy8KKy8vIExpbnV4S2VybmVsQ21weGNoZyBhbmQgQmFycmllcl9BdG9taWNJbmNyZW1lbnQgYXJlIGZyb20gR29vZ2xlIEdlYXJzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNPUFNfSU5URVJOQUxTX0FSTV9HQ0NfSF8KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19JTlRFUk5BTFNfQVJNX0dDQ19IXworCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW50ZXJuYWwgeworCisvLyAweGZmZmYwZmMwIGlzIHRoZSBoYXJkIGNvZGVkIGFkZHJlc3Mgb2YgYSBmdW5jdGlvbiBwcm92aWRlZCBieQorLy8gdGhlIGtlcm5lbCB3aGljaCBpbXBsZW1lbnRzIGFuIGF0b21pYyBjb21wYXJlLWV4Y2hhbmdlLiBPbiBvbGRlcgorLy8gQVJNIGFyY2hpdGVjdHVyZSByZXZpc2lvbnMgKHByZS12NikgdGhpcyBtYXkgYmUgaW1wbGVtZW50ZWQgdXNpbmcKKy8vIGEgc3lzY2FsbC4gVGhpcyBhZGRyZXNzIGlzIHN0YWJsZSwgYW5kIGluIGFjdGl2ZSB1c2UgKGhhcmQgY29kZWQpCisvLyBieSBhdCBsZWFzdCBnbGliYy0yLjcgYW5kIHRoZSBBbmRyb2lkIEMgbGlicmFyeS4KK3R5cGVkZWYgQXRvbWljMzIgKCpMaW51eEtlcm5lbENtcHhjaGdGdW5jKShBdG9taWMzMiBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgbmV3X3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvbGF0aWxlIEF0b21pYzMyKiBwdHIpOworTGludXhLZXJuZWxDbXB4Y2hnRnVuYyBwTGludXhLZXJuZWxDbXB4Y2hnIF9fYXR0cmlidXRlX18oKHdlYWspKSA9CisgICAgKExpbnV4S2VybmVsQ21weGNoZ0Z1bmMpIDB4ZmZmZjBmYzA7CisKK3R5cGVkZWYgdm9pZCAoKkxpbnV4S2VybmVsTWVtb3J5QmFycmllckZ1bmMpKHZvaWQpOworTGludXhLZXJuZWxNZW1vcnlCYXJyaWVyRnVuYyBwTGludXhLZXJuZWxNZW1vcnlCYXJyaWVyIF9fYXR0cmlidXRlX18oKHdlYWspKSA9CisgICAgKExpbnV4S2VybmVsTWVtb3J5QmFycmllckZ1bmMpIDB4ZmZmZjBmYTA7CisKKworaW5saW5lIEF0b21pYzMyIE5vQmFycmllcl9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG5ld192YWx1ZSkgeworICBBdG9taWMzMiBwcmV2X3ZhbHVlID0gKnB0cjsKKyAgZG8geworICAgIGlmICghcExpbnV4S2VybmVsQ21weGNoZyhvbGRfdmFsdWUsIG5ld192YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RfY2FzdDxBdG9taWMzMio+KHB0cikpKSB7CisgICAgICByZXR1cm4gb2xkX3ZhbHVlOworICAgIH0KKyAgICBwcmV2X3ZhbHVlID0gKnB0cjsKKyAgfSB3aGlsZSAocHJldl92YWx1ZSA9PSBvbGRfdmFsdWUpOworICByZXR1cm4gcHJldl92YWx1ZTsKK30KKworaW5saW5lIEF0b21pYzMyIE5vQmFycmllcl9BdG9taWNFeGNoYW5nZSh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBuZXdfdmFsdWUpIHsKKyAgQXRvbWljMzIgb2xkX3ZhbHVlOworICBkbyB7CisgICAgb2xkX3ZhbHVlID0gKnB0cjsKKyAgfSB3aGlsZSAocExpbnV4S2VybmVsQ21weGNoZyhvbGRfdmFsdWUsIG5ld192YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdF9jYXN0PEF0b21pYzMyKj4ocHRyKSkpOworICByZXR1cm4gb2xkX3ZhbHVlOworfQorCitpbmxpbmUgQXRvbWljMzIgTm9CYXJyaWVyX0F0b21pY0luY3JlbWVudCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgaW5jcmVtZW50KSB7CisgIHJldHVybiBCYXJyaWVyX0F0b21pY0luY3JlbWVudChwdHIsIGluY3JlbWVudCk7Cit9CisKK2lubGluZSBBdG9taWMzMiBCYXJyaWVyX0F0b21pY0luY3JlbWVudCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIGluY3JlbWVudCkgeworICBmb3IgKDs7KSB7CisgICAgLy8gQXRvbWljIGV4Y2hhbmdlIHRoZSBvbGQgdmFsdWUgd2l0aCBhbiBpbmNyZW1lbnRlZCBvbmUuCisgICAgQXRvbWljMzIgb2xkX3ZhbHVlID0gKnB0cjsKKyAgICBBdG9taWMzMiBuZXdfdmFsdWUgPSBvbGRfdmFsdWUgKyBpbmNyZW1lbnQ7CisgICAgaWYgKHBMaW51eEtlcm5lbENtcHhjaGcob2xkX3ZhbHVlLCBuZXdfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RfY2FzdDxBdG9taWMzMio+KHB0cikpID09IDApIHsKKyAgICAgIC8vIFRoZSBleGNoYW5nZSB0b29rIHBsYWNlIGFzIGV4cGVjdGVkLgorICAgICAgcmV0dXJuIG5ld192YWx1ZTsKKyAgICB9CisgICAgLy8gT3RoZXJ3aXNlLCAqcHRyIGNoYW5nZWQgbWlkLWxvb3AgYW5kIHdlIG5lZWQgdG8gcmV0cnkuCisgIH0KK30KKworaW5saW5lIEF0b21pYzMyIEFjcXVpcmVfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG5ld192YWx1ZSkgeworICByZXR1cm4gTm9CYXJyaWVyX0NvbXBhcmVBbmRTd2FwKHB0ciwgb2xkX3ZhbHVlLCBuZXdfdmFsdWUpOworfQorCitpbmxpbmUgQXRvbWljMzIgUmVsZWFzZV9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgbmV3X3ZhbHVlKSB7CisgIHJldHVybiBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAocHRyLCBvbGRfdmFsdWUsIG5ld192YWx1ZSk7Cit9CisKK2lubGluZSB2b2lkIE5vQmFycmllcl9TdG9yZSh2b2xhdGlsZSBBdG9taWMzMiogcHRyLCBBdG9taWMzMiB2YWx1ZSkgeworICAqcHRyID0gdmFsdWU7Cit9CisKK2lubGluZSB2b2lkIE1lbW9yeUJhcnJpZXIoKSB7CisgIHBMaW51eEtlcm5lbE1lbW9yeUJhcnJpZXIoKTsKK30KKworaW5saW5lIHZvaWQgQWNxdWlyZV9TdG9yZSh2b2xhdGlsZSBBdG9taWMzMiogcHRyLCBBdG9taWMzMiB2YWx1ZSkgeworICAqcHRyID0gdmFsdWU7CisgIE1lbW9yeUJhcnJpZXIoKTsKK30KKworaW5saW5lIHZvaWQgUmVsZWFzZV9TdG9yZSh2b2xhdGlsZSBBdG9taWMzMiogcHRyLCBBdG9taWMzMiB2YWx1ZSkgeworICBNZW1vcnlCYXJyaWVyKCk7CisgICpwdHIgPSB2YWx1ZTsKK30KKworaW5saW5lIEF0b21pYzMyIE5vQmFycmllcl9Mb2FkKHZvbGF0aWxlIGNvbnN0IEF0b21pYzMyKiBwdHIpIHsKKyAgcmV0dXJuICpwdHI7Cit9CisKK2lubGluZSBBdG9taWMzMiBBY3F1aXJlX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljMzIqIHB0cikgeworICBBdG9taWMzMiB2YWx1ZSA9ICpwdHI7CisgIE1lbW9yeUJhcnJpZXIoKTsKKyAgcmV0dXJuIHZhbHVlOworfQorCitpbmxpbmUgQXRvbWljMzIgUmVsZWFzZV9Mb2FkKHZvbGF0aWxlIGNvbnN0IEF0b21pYzMyKiBwdHIpIHsKKyAgTWVtb3J5QmFycmllcigpOworICByZXR1cm4gKnB0cjsKK30KKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQVRPTUlDT1BTX0lOVEVSTkFMU19BUk1fR0NDX0hfCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfYXJtX3FueC5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX2FybV9xbnguaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xN2RmYWE1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX2FybV9xbnguaApAQCAtMCwwICsxLDE0NiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAxMiBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIFRoaXMgZmlsZSBpcyBhbiBpbnRlcm5hbCBhdG9taWMgaW1wbGVtZW50YXRpb24sIHVzZSBhdG9taWNvcHMuaCBpbnN0ZWFkLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNPUFNfSU5URVJOQUxTX0FSTV9RTlhfSF8KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19JTlRFUk5BTFNfQVJNX1FOWF9IXworCisvLyBGb3IgX3NtcF9jbXB4Y2hnKCkKKyNpbmNsdWRlIDxwdGhyZWFkLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKK2lubGluZSBBdG9taWMzMiBRTlhDbXB4Y2hnKEF0b21pYzMyIG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG5ld192YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvbGF0aWxlIEF0b21pYzMyKiBwdHIpIHsKKyAgcmV0dXJuIHN0YXRpY19jYXN0PEF0b21pYzMyPigKKyAgICAgIF9zbXBfY21weGNoZygodm9sYXRpbGUgdW5zaWduZWQgKilwdHIsCisgICAgICAgICAgICAgICAgICAgKHVuc2lnbmVkKW9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAodW5zaWduZWQpbmV3X3ZhbHVlKSk7Cit9CisKKworaW5saW5lIEF0b21pYzMyIE5vQmFycmllcl9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG5ld192YWx1ZSkgeworICBBdG9taWMzMiBwcmV2X3ZhbHVlID0gKnB0cjsKKyAgZG8geworICAgIGlmICghUU5YQ21weGNoZyhvbGRfdmFsdWUsIG5ld192YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgY29uc3RfY2FzdDxBdG9taWMzMio+KHB0cikpKSB7CisgICAgICByZXR1cm4gb2xkX3ZhbHVlOworICAgIH0KKyAgICBwcmV2X3ZhbHVlID0gKnB0cjsKKyAgfSB3aGlsZSAocHJldl92YWx1ZSA9PSBvbGRfdmFsdWUpOworICByZXR1cm4gcHJldl92YWx1ZTsKK30KKworaW5saW5lIEF0b21pYzMyIE5vQmFycmllcl9BdG9taWNFeGNoYW5nZSh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBuZXdfdmFsdWUpIHsKKyAgQXRvbWljMzIgb2xkX3ZhbHVlOworICBkbyB7CisgICAgb2xkX3ZhbHVlID0gKnB0cjsKKyAgfSB3aGlsZSAoUU5YQ21weGNoZyhvbGRfdmFsdWUsIG5ld192YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICBjb25zdF9jYXN0PEF0b21pYzMyKj4ocHRyKSkpOworICByZXR1cm4gb2xkX3ZhbHVlOworfQorCitpbmxpbmUgQXRvbWljMzIgTm9CYXJyaWVyX0F0b21pY0luY3JlbWVudCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgaW5jcmVtZW50KSB7CisgIHJldHVybiBCYXJyaWVyX0F0b21pY0luY3JlbWVudChwdHIsIGluY3JlbWVudCk7Cit9CisKK2lubGluZSBBdG9taWMzMiBCYXJyaWVyX0F0b21pY0luY3JlbWVudCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIGluY3JlbWVudCkgeworICBmb3IgKDs7KSB7CisgICAgLy8gQXRvbWljIGV4Y2hhbmdlIHRoZSBvbGQgdmFsdWUgd2l0aCBhbiBpbmNyZW1lbnRlZCBvbmUuCisgICAgQXRvbWljMzIgb2xkX3ZhbHVlID0gKnB0cjsKKyAgICBBdG9taWMzMiBuZXdfdmFsdWUgPSBvbGRfdmFsdWUgKyBpbmNyZW1lbnQ7CisgICAgaWYgKFFOWENtcHhjaGcob2xkX3ZhbHVlLCBuZXdfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgY29uc3RfY2FzdDxBdG9taWMzMio+KHB0cikpID09IDApIHsKKyAgICAgIC8vIFRoZSBleGNoYW5nZSB0b29rIHBsYWNlIGFzIGV4cGVjdGVkLgorICAgICAgcmV0dXJuIG5ld192YWx1ZTsKKyAgICB9CisgICAgLy8gT3RoZXJ3aXNlLCAqcHRyIGNoYW5nZWQgbWlkLWxvb3AgYW5kIHdlIG5lZWQgdG8gcmV0cnkuCisgIH0KK30KKworaW5saW5lIEF0b21pYzMyIEFjcXVpcmVfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG5ld192YWx1ZSkgeworICByZXR1cm4gTm9CYXJyaWVyX0NvbXBhcmVBbmRTd2FwKHB0ciwgb2xkX3ZhbHVlLCBuZXdfdmFsdWUpOworfQorCitpbmxpbmUgQXRvbWljMzIgUmVsZWFzZV9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgbmV3X3ZhbHVlKSB7CisgIHJldHVybiBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAocHRyLCBvbGRfdmFsdWUsIG5ld192YWx1ZSk7Cit9CisKK2lubGluZSB2b2lkIE5vQmFycmllcl9TdG9yZSh2b2xhdGlsZSBBdG9taWMzMiogcHRyLCBBdG9taWMzMiB2YWx1ZSkgeworICAqcHRyID0gdmFsdWU7Cit9CisKK2lubGluZSB2b2lkIE1lbW9yeUJhcnJpZXIoKSB7CisgIF9fc3luY19zeW5jaHJvbml6ZSgpOworfQorCitpbmxpbmUgdm9pZCBBY3F1aXJlX1N0b3JlKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsIEF0b21pYzMyIHZhbHVlKSB7CisgICpwdHIgPSB2YWx1ZTsKKyAgTWVtb3J5QmFycmllcigpOworfQorCitpbmxpbmUgdm9pZCBSZWxlYXNlX1N0b3JlKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsIEF0b21pYzMyIHZhbHVlKSB7CisgIE1lbW9yeUJhcnJpZXIoKTsKKyAgKnB0ciA9IHZhbHVlOworfQorCitpbmxpbmUgQXRvbWljMzIgTm9CYXJyaWVyX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljMzIqIHB0cikgeworICByZXR1cm4gKnB0cjsKK30KKworaW5saW5lIEF0b21pYzMyIEFjcXVpcmVfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWMzMiogcHRyKSB7CisgIEF0b21pYzMyIHZhbHVlID0gKnB0cjsKKyAgTWVtb3J5QmFycmllcigpOworICByZXR1cm4gdmFsdWU7Cit9CisKK2lubGluZSBBdG9taWMzMiBSZWxlYXNlX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljMzIqIHB0cikgeworICBNZW1vcnlCYXJyaWVyKCk7CisgIHJldHVybiAqcHRyOworfQorCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNPUFNfSU5URVJOQUxTX0FSTV9RTlhfSF8KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc19hdG9taWN3b3JkX2NvbXBhdC5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX2F0b21pY3dvcmRfY29tcGF0LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWIxOThmZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc19hdG9taWN3b3JkX2NvbXBhdC5oCkBAIC0wLDAgKzEsMTIyIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDEyIEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gVGhpcyBmaWxlIGlzIGFuIGludGVybmFsIGF0b21pYyBpbXBsZW1lbnRhdGlvbiwgdXNlIGF0b21pY29wcy5oIGluc3RlYWQuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19JTlRFUk5BTFNfQVRPTUlDV09SRF9DT01QQVRfSF8KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19JTlRFUk5BTFNfQVRPTUlDV09SRF9DT01QQVRfSF8KKworLy8gQXRvbWljV29yZCBpcyBhIHN5bm9ueW0gZm9yIGludHB0cl90LCBhbmQgQXRvbWljMzIgaXMgYSBzeW5vbnltIGZvciBpbnQzMiwKKy8vIHdoaWNoIGluIHR1cm4gbWVhbnMgaW50LiBPbiBzb21lIExQMzIgcGxhdGZvcm1zLCBpbnRwdHJfdCBpcyBhbiBpbnQsIGJ1dAorLy8gb24gb3RoZXJzLCBpdCdzIGEgbG9uZy4gV2hlbiBBdG9taWNXb3JkIGFuZCBBdG9taWMzMiBhcmUgYmFzZWQgb24gZGlmZmVyZW50CisvLyBmdW5kYW1lbnRhbCB0eXBlcywgdGhlaXIgcG9pbnRlcnMgYXJlIGluY29tcGF0aWJsZS4KKy8vCisvLyBUaGlzIGZpbGUgZGVmaW5lcyBmdW5jdGlvbiBvdmVybG9hZHMgdG8gYWxsb3cgYm90aCBBdG9taWNXb3JkIGFuZCBBdG9taWMzMgorLy8gZGF0YSB0byBiZSB1c2VkIHdpdGggdGhpcyBpbnRlcmZhY2UuCisvLworLy8gT24gTFA2NCBwbGF0Zm9ybXMsIEF0b21pY1dvcmQgYW5kIEF0b21pYzY0IGFyZSBib3RoIGFsd2F5cyBsb25nLAorLy8gc28gdGhpcyBwcm9ibGVtIGRvZXNuJ3Qgb2NjdXIuCisKKyNpZiAhZGVmaW5lZChHT09HTEVfUFJPVE9CVUZfQVJDSF82NF9CSVQpCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKK2lubGluZSBBdG9taWNXb3JkIE5vQmFycmllcl9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWNXb3JkKiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljV29yZCBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljV29yZCBuZXdfdmFsdWUpIHsKKyAgcmV0dXJuIE5vQmFycmllcl9Db21wYXJlQW5kU3dhcCgKKyAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8dm9sYXRpbGUgQXRvbWljMzIqPihwdHIpLCBvbGRfdmFsdWUsIG5ld192YWx1ZSk7Cit9CisKK2lubGluZSBBdG9taWNXb3JkIE5vQmFycmllcl9BdG9taWNFeGNoYW5nZSh2b2xhdGlsZSBBdG9taWNXb3JkKiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljV29yZCBuZXdfdmFsdWUpIHsKKyAgcmV0dXJuIE5vQmFycmllcl9BdG9taWNFeGNoYW5nZSgKKyAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8dm9sYXRpbGUgQXRvbWljMzIqPihwdHIpLCBuZXdfdmFsdWUpOworfQorCitpbmxpbmUgQXRvbWljV29yZCBOb0JhcnJpZXJfQXRvbWljSW5jcmVtZW50KHZvbGF0aWxlIEF0b21pY1dvcmQqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljV29yZCBpbmNyZW1lbnQpIHsKKyAgcmV0dXJuIE5vQmFycmllcl9BdG9taWNJbmNyZW1lbnQoCisgICAgICByZWludGVycHJldF9jYXN0PHZvbGF0aWxlIEF0b21pYzMyKj4ocHRyKSwgaW5jcmVtZW50KTsKK30KKworaW5saW5lIEF0b21pY1dvcmQgQmFycmllcl9BdG9taWNJbmNyZW1lbnQodm9sYXRpbGUgQXRvbWljV29yZCogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljV29yZCBpbmNyZW1lbnQpIHsKKyAgcmV0dXJuIEJhcnJpZXJfQXRvbWljSW5jcmVtZW50KAorICAgICAgcmVpbnRlcnByZXRfY2FzdDx2b2xhdGlsZSBBdG9taWMzMio+KHB0ciksIGluY3JlbWVudCk7Cit9CisKK2lubGluZSBBdG9taWNXb3JkIEFjcXVpcmVfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljV29yZCogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWNXb3JkIG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljV29yZCBuZXdfdmFsdWUpIHsKKyAgcmV0dXJuIEFjcXVpcmVfQ29tcGFyZUFuZFN3YXAoCisgICAgICByZWludGVycHJldF9jYXN0PHZvbGF0aWxlIEF0b21pYzMyKj4ocHRyKSwgb2xkX3ZhbHVlLCBuZXdfdmFsdWUpOworfQorCitpbmxpbmUgQXRvbWljV29yZCBSZWxlYXNlX0NvbXBhcmVBbmRTd2FwKHZvbGF0aWxlIEF0b21pY1dvcmQqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljV29yZCBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pY1dvcmQgbmV3X3ZhbHVlKSB7CisgIHJldHVybiBSZWxlYXNlX0NvbXBhcmVBbmRTd2FwKAorICAgICAgcmVpbnRlcnByZXRfY2FzdDx2b2xhdGlsZSBBdG9taWMzMio+KHB0ciksIG9sZF92YWx1ZSwgbmV3X3ZhbHVlKTsKK30KKworaW5saW5lIHZvaWQgTm9CYXJyaWVyX1N0b3JlKHZvbGF0aWxlIEF0b21pY1dvcmQgKnB0ciwgQXRvbWljV29yZCB2YWx1ZSkgeworICBOb0JhcnJpZXJfU3RvcmUocmVpbnRlcnByZXRfY2FzdDx2b2xhdGlsZSBBdG9taWMzMio+KHB0ciksIHZhbHVlKTsKK30KKworaW5saW5lIHZvaWQgQWNxdWlyZV9TdG9yZSh2b2xhdGlsZSBBdG9taWNXb3JkKiBwdHIsIEF0b21pY1dvcmQgdmFsdWUpIHsKKyAgcmV0dXJuIEFjcXVpcmVfU3RvcmUocmVpbnRlcnByZXRfY2FzdDx2b2xhdGlsZSBBdG9taWMzMio+KHB0ciksIHZhbHVlKTsKK30KKworaW5saW5lIHZvaWQgUmVsZWFzZV9TdG9yZSh2b2xhdGlsZSBBdG9taWNXb3JkKiBwdHIsIEF0b21pY1dvcmQgdmFsdWUpIHsKKyAgcmV0dXJuIFJlbGVhc2VfU3RvcmUocmVpbnRlcnByZXRfY2FzdDx2b2xhdGlsZSBBdG9taWMzMio+KHB0ciksIHZhbHVlKTsKK30KKworaW5saW5lIEF0b21pY1dvcmQgTm9CYXJyaWVyX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljV29yZCAqcHRyKSB7CisgIHJldHVybiBOb0JhcnJpZXJfTG9hZChyZWludGVycHJldF9jYXN0PHZvbGF0aWxlIGNvbnN0IEF0b21pYzMyKj4ocHRyKSk7Cit9CisKK2lubGluZSBBdG9taWNXb3JkIEFjcXVpcmVfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWNXb3JkKiBwdHIpIHsKKyAgcmV0dXJuIEFjcXVpcmVfTG9hZChyZWludGVycHJldF9jYXN0PHZvbGF0aWxlIGNvbnN0IEF0b21pYzMyKj4ocHRyKSk7Cit9CisKK2lubGluZSBBdG9taWNXb3JkIFJlbGVhc2VfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWNXb3JkKiBwdHIpIHsKKyAgcmV0dXJuIFJlbGVhc2VfTG9hZChyZWludGVycHJldF9jYXN0PHZvbGF0aWxlIGNvbnN0IEF0b21pYzMyKj4ocHRyKSk7Cit9CisKK30gICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKyNlbmRpZiAgLy8gIWRlZmluZWQoR09PR0xFX1BST1RPQlVGX0FSQ0hfNjRfQklUKQorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNPUFNfSU5URVJOQUxTX0FUT01JQ1dPUkRfQ09NUEFUX0hfCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfZ2VuZXJpY19nY2MuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc19nZW5lcmljX2djYy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmEwMTE2YTYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfZ2VuZXJpY19nY2MuaApAQCAtMCwwICsxLDEzNyBAQAorLy8gQ29weXJpZ2h0IDIwMTMgUmVkIEhhdCBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIFJlZCBIYXQgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gVGhpcyBmaWxlIGlzIGFuIGludGVybmFsIGF0b21pYyBpbXBsZW1lbnRhdGlvbiwgdXNlIGF0b21pY29wcy5oIGluc3RlYWQuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19JTlRFUk5BTFNfR0VORVJJQ19HQ0NfSF8KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19JTlRFUk5BTFNfR0VORVJJQ19HQ0NfSF8KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKworaW5saW5lIEF0b21pYzMyIE5vQmFycmllcl9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG5ld192YWx1ZSkgeworICBfX2F0b21pY19jb21wYXJlX2V4Y2hhbmdlX24ocHRyLCAmb2xkX3ZhbHVlLCBuZXdfdmFsdWUsIHRydWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfX0FUT01JQ19SRUxBWEVELCBfX0FUT01JQ19SRUxBWEVEKTsKKyAgcmV0dXJuIG9sZF92YWx1ZTsKK30KKworaW5saW5lIEF0b21pYzMyIE5vQmFycmllcl9BdG9taWNFeGNoYW5nZSh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBuZXdfdmFsdWUpIHsKKyAgcmV0dXJuIF9fYXRvbWljX2V4Y2hhbmdlX24ocHRyLCBuZXdfdmFsdWUsIF9fQVRPTUlDX1JFTEFYRUQpOworfQorCitpbmxpbmUgQXRvbWljMzIgTm9CYXJyaWVyX0F0b21pY0luY3JlbWVudCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgaW5jcmVtZW50KSB7CisgIHJldHVybiBfX2F0b21pY19hZGRfZmV0Y2gocHRyLCBpbmNyZW1lbnQsIF9fQVRPTUlDX1JFTEFYRUQpOworfQorCitpbmxpbmUgQXRvbWljMzIgQmFycmllcl9BdG9taWNJbmNyZW1lbnQodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBpbmNyZW1lbnQpIHsKKyAgcmV0dXJuIF9fYXRvbWljX2FkZF9mZXRjaChwdHIsIGluY3JlbWVudCwgX19BVE9NSUNfU0VRX0NTVCk7Cit9CisKK2lubGluZSBBdG9taWMzMiBBY3F1aXJlX0NvbXBhcmVBbmRTd2FwKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBuZXdfdmFsdWUpIHsKKyAgX19hdG9taWNfY29tcGFyZV9leGNoYW5nZV9uKHB0ciwgJm9sZF92YWx1ZSwgbmV3X3ZhbHVlLCB0cnVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX19BVE9NSUNfQUNRVUlSRSwgX19BVE9NSUNfQUNRVUlSRSk7CisgIHJldHVybiBvbGRfdmFsdWU7Cit9CisKK2lubGluZSBBdG9taWMzMiBSZWxlYXNlX0NvbXBhcmVBbmRTd2FwKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBuZXdfdmFsdWUpIHsKKyAgX19hdG9taWNfY29tcGFyZV9leGNoYW5nZV9uKHB0ciwgJm9sZF92YWx1ZSwgbmV3X3ZhbHVlLCB0cnVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX19BVE9NSUNfUkVMRUFTRSwgX19BVE9NSUNfQUNRVUlSRSk7CisgIHJldHVybiBvbGRfdmFsdWU7Cit9CisKK2lubGluZSB2b2lkIE5vQmFycmllcl9TdG9yZSh2b2xhdGlsZSBBdG9taWMzMiogcHRyLCBBdG9taWMzMiB2YWx1ZSkgeworICBfX2F0b21pY19zdG9yZV9uKHB0ciwgdmFsdWUsIF9fQVRPTUlDX1JFTEFYRUQpOworfQorCitpbmxpbmUgdm9pZCBNZW1vcnlCYXJyaWVyKCkgeworICBfX3N5bmNfc3luY2hyb25pemUoKTsKK30KKworaW5saW5lIHZvaWQgQWNxdWlyZV9TdG9yZSh2b2xhdGlsZSBBdG9taWMzMiogcHRyLCBBdG9taWMzMiB2YWx1ZSkgeworICBfX2F0b21pY19zdG9yZV9uKHB0ciwgdmFsdWUsIF9fQVRPTUlDX1NFUV9DU1QpOworfQorCitpbmxpbmUgdm9pZCBSZWxlYXNlX1N0b3JlKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsIEF0b21pYzMyIHZhbHVlKSB7CisgIF9fYXRvbWljX3N0b3JlX24ocHRyLCB2YWx1ZSwgX19BVE9NSUNfUkVMRUFTRSk7Cit9CisKK2lubGluZSBBdG9taWMzMiBOb0JhcnJpZXJfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWMzMiogcHRyKSB7CisgIHJldHVybiBfX2F0b21pY19sb2FkX24ocHRyLCBfX0FUT01JQ19SRUxBWEVEKTsKK30KKworaW5saW5lIEF0b21pYzMyIEFjcXVpcmVfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWMzMiogcHRyKSB7CisgIHJldHVybiBfX2F0b21pY19sb2FkX24ocHRyLCBfX0FUT01JQ19BQ1FVSVJFKTsKK30KKworaW5saW5lIEF0b21pYzMyIFJlbGVhc2VfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWMzMiogcHRyKSB7CisgIHJldHVybiBfX2F0b21pY19sb2FkX24ocHRyLCBfX0FUT01JQ19TRVFfQ1NUKTsKK30KKworI2lmZGVmIF9fTFA2NF9fCisKK2lubGluZSB2b2lkIFJlbGVhc2VfU3RvcmUodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwgQXRvbWljNjQgdmFsdWUpIHsKKyAgX19hdG9taWNfc3RvcmVfbihwdHIsIHZhbHVlLCBfX0FUT01JQ19SRUxFQVNFKTsKK30KKworaW5saW5lIEF0b21pYzY0IEFjcXVpcmVfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWM2NCogcHRyKSB7CisgIHJldHVybiBfX2F0b21pY19sb2FkX24ocHRyLCBfX0FUT01JQ19BQ1FVSVJFKTsKK30KKworaW5saW5lIEF0b21pYzY0IEFjcXVpcmVfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG5ld192YWx1ZSkgeworICBfX2F0b21pY19jb21wYXJlX2V4Y2hhbmdlX24ocHRyLCAmb2xkX3ZhbHVlLCBuZXdfdmFsdWUsIHRydWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfX0FUT01JQ19BQ1FVSVJFLCBfX0FUT01JQ19BQ1FVSVJFKTsKKyAgcmV0dXJuIG9sZF92YWx1ZTsKK30KKworaW5saW5lIEF0b21pYzY0IE5vQmFycmllcl9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWM2NCogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG5ld192YWx1ZSkgeworICBfX2F0b21pY19jb21wYXJlX2V4Y2hhbmdlX24ocHRyLCAmb2xkX3ZhbHVlLCBuZXdfdmFsdWUsIHRydWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfX0FUT01JQ19SRUxBWEVELCBfX0FUT01JQ19SRUxBWEVEKTsKKyAgcmV0dXJuIG9sZF92YWx1ZTsKK30KKworI2VuZGlmIC8vIGRlZmluZWQoX19MUDY0X18pCisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19JTlRFUk5BTFNfR0VORVJJQ19HQ0NfSF8KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc19tYWNvc3guaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc19tYWNvc3guaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43OTYzMzI0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX21hY29zeC5oCkBAIC0wLDAgKzEsMjI1IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDEyIEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gVGhpcyBmaWxlIGlzIGFuIGludGVybmFsIGF0b21pYyBpbXBsZW1lbnRhdGlvbiwgdXNlIGF0b21pY29wcy5oIGluc3RlYWQuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19JTlRFUk5BTFNfTUFDT1NYX0hfCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNPUFNfSU5URVJOQUxTX01BQ09TWF9IXworCisjaW5jbHVkZSA8bGlia2Vybi9PU0F0b21pYy5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW50ZXJuYWwgeworCitpbmxpbmUgQXRvbWljMzIgTm9CYXJyaWVyX0NvbXBhcmVBbmRTd2FwKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgbmV3X3ZhbHVlKSB7CisgIEF0b21pYzMyIHByZXZfdmFsdWU7CisgIGRvIHsKKyAgICBpZiAoT1NBdG9taWNDb21wYXJlQW5kU3dhcDMyKG9sZF92YWx1ZSwgbmV3X3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RfY2FzdDxBdG9taWMzMio+KHB0cikpKSB7CisgICAgICByZXR1cm4gb2xkX3ZhbHVlOworICAgIH0KKyAgICBwcmV2X3ZhbHVlID0gKnB0cjsKKyAgfSB3aGlsZSAocHJldl92YWx1ZSA9PSBvbGRfdmFsdWUpOworICByZXR1cm4gcHJldl92YWx1ZTsKK30KKworaW5saW5lIEF0b21pYzMyIE5vQmFycmllcl9BdG9taWNFeGNoYW5nZSh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBuZXdfdmFsdWUpIHsKKyAgQXRvbWljMzIgb2xkX3ZhbHVlOworICBkbyB7CisgICAgb2xkX3ZhbHVlID0gKnB0cjsKKyAgfSB3aGlsZSAoIU9TQXRvbWljQ29tcGFyZUFuZFN3YXAzMihvbGRfdmFsdWUsIG5ld192YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdF9jYXN0PEF0b21pYzMyKj4ocHRyKSkpOworICByZXR1cm4gb2xkX3ZhbHVlOworfQorCitpbmxpbmUgQXRvbWljMzIgTm9CYXJyaWVyX0F0b21pY0luY3JlbWVudCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgaW5jcmVtZW50KSB7CisgIHJldHVybiBPU0F0b21pY0FkZDMyKGluY3JlbWVudCwgY29uc3RfY2FzdDxBdG9taWMzMio+KHB0cikpOworfQorCitpbmxpbmUgQXRvbWljMzIgQmFycmllcl9BdG9taWNJbmNyZW1lbnQodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIGluY3JlbWVudCkgeworICByZXR1cm4gT1NBdG9taWNBZGQzMkJhcnJpZXIoaW5jcmVtZW50LCBjb25zdF9jYXN0PEF0b21pYzMyKj4ocHRyKSk7Cit9CisKK2lubGluZSB2b2lkIE1lbW9yeUJhcnJpZXIoKSB7CisgIE9TTWVtb3J5QmFycmllcigpOworfQorCitpbmxpbmUgQXRvbWljMzIgQWNxdWlyZV9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgbmV3X3ZhbHVlKSB7CisgIEF0b21pYzMyIHByZXZfdmFsdWU7CisgIGRvIHsKKyAgICBpZiAoT1NBdG9taWNDb21wYXJlQW5kU3dhcDMyQmFycmllcihvbGRfdmFsdWUsIG5ld192YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdF9jYXN0PEF0b21pYzMyKj4ocHRyKSkpIHsKKyAgICAgIHJldHVybiBvbGRfdmFsdWU7CisgICAgfQorICAgIHByZXZfdmFsdWUgPSAqcHRyOworICB9IHdoaWxlIChwcmV2X3ZhbHVlID09IG9sZF92YWx1ZSk7CisgIHJldHVybiBwcmV2X3ZhbHVlOworfQorCitpbmxpbmUgQXRvbWljMzIgUmVsZWFzZV9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgbmV3X3ZhbHVlKSB7CisgIHJldHVybiBBY3F1aXJlX0NvbXBhcmVBbmRTd2FwKHB0ciwgb2xkX3ZhbHVlLCBuZXdfdmFsdWUpOworfQorCitpbmxpbmUgdm9pZCBOb0JhcnJpZXJfU3RvcmUodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwgQXRvbWljMzIgdmFsdWUpIHsKKyAgKnB0ciA9IHZhbHVlOworfQorCitpbmxpbmUgdm9pZCBBY3F1aXJlX1N0b3JlKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsIEF0b21pYzMyIHZhbHVlKSB7CisgICpwdHIgPSB2YWx1ZTsKKyAgTWVtb3J5QmFycmllcigpOworfQorCitpbmxpbmUgdm9pZCBSZWxlYXNlX1N0b3JlKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsIEF0b21pYzMyIHZhbHVlKSB7CisgIE1lbW9yeUJhcnJpZXIoKTsKKyAgKnB0ciA9IHZhbHVlOworfQorCitpbmxpbmUgQXRvbWljMzIgTm9CYXJyaWVyX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljMzIqIHB0cikgeworICByZXR1cm4gKnB0cjsKK30KKworaW5saW5lIEF0b21pYzMyIEFjcXVpcmVfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWMzMiogcHRyKSB7CisgIEF0b21pYzMyIHZhbHVlID0gKnB0cjsKKyAgTWVtb3J5QmFycmllcigpOworICByZXR1cm4gdmFsdWU7Cit9CisKK2lubGluZSBBdG9taWMzMiBSZWxlYXNlX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljMzIqIHB0cikgeworICBNZW1vcnlCYXJyaWVyKCk7CisgIHJldHVybiAqcHRyOworfQorCisjaWZkZWYgX19MUDY0X18KKworLy8gNjQtYml0IGltcGxlbWVudGF0aW9uIG9uIDY0LWJpdCBwbGF0Zm9ybQorCitpbmxpbmUgQXRvbWljNjQgTm9CYXJyaWVyX0NvbXBhcmVBbmRTd2FwKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgbmV3X3ZhbHVlKSB7CisgIEF0b21pYzY0IHByZXZfdmFsdWU7CisgIGRvIHsKKyAgICBpZiAoT1NBdG9taWNDb21wYXJlQW5kU3dhcDY0KG9sZF92YWx1ZSwgbmV3X3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVpbnRlcnByZXRfY2FzdDx2b2xhdGlsZSBpbnQ2NF90Kj4ocHRyKSkpIHsKKyAgICAgIHJldHVybiBvbGRfdmFsdWU7CisgICAgfQorICAgIHByZXZfdmFsdWUgPSAqcHRyOworICB9IHdoaWxlIChwcmV2X3ZhbHVlID09IG9sZF92YWx1ZSk7CisgIHJldHVybiBwcmV2X3ZhbHVlOworfQorCitpbmxpbmUgQXRvbWljNjQgTm9CYXJyaWVyX0F0b21pY0V4Y2hhbmdlKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG5ld192YWx1ZSkgeworICBBdG9taWM2NCBvbGRfdmFsdWU7CisgIGRvIHsKKyAgICBvbGRfdmFsdWUgPSAqcHRyOworICB9IHdoaWxlICghT1NBdG9taWNDb21wYXJlQW5kU3dhcDY0KG9sZF92YWx1ZSwgbmV3X3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8dm9sYXRpbGUgaW50NjRfdCo+KHB0cikpKTsKKyAgcmV0dXJuIG9sZF92YWx1ZTsKK30KKworaW5saW5lIEF0b21pYzY0IE5vQmFycmllcl9BdG9taWNJbmNyZW1lbnQodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IGluY3JlbWVudCkgeworICByZXR1cm4gT1NBdG9taWNBZGQ2NChpbmNyZW1lbnQsIHJlaW50ZXJwcmV0X2Nhc3Q8dm9sYXRpbGUgaW50NjRfdCo+KHB0cikpOworfQorCitpbmxpbmUgQXRvbWljNjQgQmFycmllcl9BdG9taWNJbmNyZW1lbnQodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBpbmNyZW1lbnQpIHsKKyAgcmV0dXJuIE9TQXRvbWljQWRkNjRCYXJyaWVyKGluY3JlbWVudCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8dm9sYXRpbGUgaW50NjRfdCo+KHB0cikpOworfQorCitpbmxpbmUgQXRvbWljNjQgQWNxdWlyZV9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWM2NCogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgbmV3X3ZhbHVlKSB7CisgIEF0b21pYzY0IHByZXZfdmFsdWU7CisgIGRvIHsKKyAgICBpZiAoT1NBdG9taWNDb21wYXJlQW5kU3dhcDY0QmFycmllcigKKyAgICAgICAgb2xkX3ZhbHVlLCBuZXdfdmFsdWUsIHJlaW50ZXJwcmV0X2Nhc3Q8dm9sYXRpbGUgaW50NjRfdCo+KHB0cikpKSB7CisgICAgICByZXR1cm4gb2xkX3ZhbHVlOworICAgIH0KKyAgICBwcmV2X3ZhbHVlID0gKnB0cjsKKyAgfSB3aGlsZSAocHJldl92YWx1ZSA9PSBvbGRfdmFsdWUpOworICByZXR1cm4gcHJldl92YWx1ZTsKK30KKworaW5saW5lIEF0b21pYzY0IFJlbGVhc2VfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG5ld192YWx1ZSkgeworICAvLyBUaGUgbGliIGtlcm4gaW50ZXJmYWNlIGRvZXMgbm90IGRpc3Rpbmd1aXNoIGJldHdlZW4KKyAgLy8gQWNxdWlyZSBhbmQgUmVsZWFzZSBtZW1vcnkgYmFycmllcnM7IHRoZXkgYXJlIGVxdWl2YWxlbnQuCisgIHJldHVybiBBY3F1aXJlX0NvbXBhcmVBbmRTd2FwKHB0ciwgb2xkX3ZhbHVlLCBuZXdfdmFsdWUpOworfQorCitpbmxpbmUgdm9pZCBOb0JhcnJpZXJfU3RvcmUodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwgQXRvbWljNjQgdmFsdWUpIHsKKyAgKnB0ciA9IHZhbHVlOworfQorCitpbmxpbmUgdm9pZCBBY3F1aXJlX1N0b3JlKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsIEF0b21pYzY0IHZhbHVlKSB7CisgICpwdHIgPSB2YWx1ZTsKKyAgTWVtb3J5QmFycmllcigpOworfQorCitpbmxpbmUgdm9pZCBSZWxlYXNlX1N0b3JlKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsIEF0b21pYzY0IHZhbHVlKSB7CisgIE1lbW9yeUJhcnJpZXIoKTsKKyAgKnB0ciA9IHZhbHVlOworfQorCitpbmxpbmUgQXRvbWljNjQgTm9CYXJyaWVyX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljNjQqIHB0cikgeworICByZXR1cm4gKnB0cjsKK30KKworaW5saW5lIEF0b21pYzY0IEFjcXVpcmVfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWM2NCogcHRyKSB7CisgIEF0b21pYzY0IHZhbHVlID0gKnB0cjsKKyAgTWVtb3J5QmFycmllcigpOworICByZXR1cm4gdmFsdWU7Cit9CisKK2lubGluZSBBdG9taWM2NCBSZWxlYXNlX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljNjQqIHB0cikgeworICBNZW1vcnlCYXJyaWVyKCk7CisgIHJldHVybiAqcHRyOworfQorCisjZW5kaWYgIC8vIGRlZmluZWQoX19MUDY0X18pCisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19JTlRFUk5BTFNfTUFDT1NYX0hfCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfbWlwc19nY2MuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc19taXBzX2djYy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY1ODM3YzkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfbWlwc19nY2MuaApAQCAtMCwwICsxLDMxMyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAxMiBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIFRoaXMgZmlsZSBpcyBhbiBpbnRlcm5hbCBhdG9taWMgaW1wbGVtZW50YXRpb24sIHVzZSBhdG9taWNvcHMuaCBpbnN0ZWFkLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNPUFNfSU5URVJOQUxTX01JUFNfR0NDX0hfCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNPUFNfSU5URVJOQUxTX01JUFNfR0NDX0hfCisKKyNkZWZpbmUgQVRPTUlDT1BTX0NPTVBJTEVSX0JBUlJJRVIoKSBfX2FzbV9fIF9fdm9sYXRpbGVfXygiIiA6IDogOiAibWVtb3J5IikKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKworLy8gQXRvbWljYWxseSBleGVjdXRlOgorLy8gICAgICByZXN1bHQgPSAqcHRyOworLy8gICAgICBpZiAoKnB0ciA9PSBvbGRfdmFsdWUpCisvLyAgICAgICAgKnB0ciA9IG5ld192YWx1ZTsKKy8vICAgICAgcmV0dXJuIHJlc3VsdDsKKy8vCisvLyBJLmUuLCByZXBsYWNlICIqcHRyIiB3aXRoICJuZXdfdmFsdWUiIGlmICIqcHRyIiB1c2VkIHRvIGJlICJvbGRfdmFsdWUiLgorLy8gQWx3YXlzIHJldHVybiB0aGUgb2xkIHZhbHVlIG9mICIqcHRyIgorLy8KKy8vIFRoaXMgcm91dGluZSBpbXBsaWVzIG5vIG1lbW9yeSBiYXJyaWVycy4KK2lubGluZSBBdG9taWMzMiBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBuZXdfdmFsdWUpIHsKKyAgQXRvbWljMzIgcHJldiwgdG1wOworICBfX2FzbV9fIF9fdm9sYXRpbGVfXygiLnNldCBwdXNoXG4iCisgICAgICAgICAgICAgICAgICAgICAgICIuc2V0IG5vcmVvcmRlclxuIgorICAgICAgICAgICAgICAgICAgICAgICAiMTpcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgImxsICUwLCAlNVxuIiAgLy8gcHJldiA9ICpwdHIKKyAgICAgICAgICAgICAgICAgICAgICAgImJuZSAlMCwgJTMsIDJmXG4iICAvLyBpZiAocHJldiAhPSBvbGRfdmFsdWUpIGdvdG8gMgorICAgICAgICAgICAgICAgICAgICAgICAibW92ZSAlMiwgJTRcbiIgIC8vIHRtcCA9IG5ld192YWx1ZQorICAgICAgICAgICAgICAgICAgICAgICAic2MgJTIsICUxXG4iICAvLyAqcHRyID0gdG1wICh3aXRoIGF0b21pYyBjaGVjaykKKyAgICAgICAgICAgICAgICAgICAgICAgImJlcXogJTIsIDFiXG4iICAvLyBzdGFydCBhZ2FpbiBvbiBhdG9taWMgZXJyb3IKKyAgICAgICAgICAgICAgICAgICAgICAgIm5vcFxuIiAgLy8gZGVsYXkgc2xvdCBub3AKKyAgICAgICAgICAgICAgICAgICAgICAgIjI6XG4iCisgICAgICAgICAgICAgICAgICAgICAgICIuc2V0IHBvcFxuIgorICAgICAgICAgICAgICAgICAgICAgICA6ICI9JnIiIChwcmV2KSwgIj1tIiAoKnB0ciksICI9JnIiICh0bXApCisgICAgICAgICAgICAgICAgICAgICAgIDogInIiIChvbGRfdmFsdWUpLCAiciIgKG5ld192YWx1ZSksICJtIiAoKnB0cikKKyAgICAgICAgICAgICAgICAgICAgICAgOiAibWVtb3J5Iik7CisgIHJldHVybiBwcmV2OworfQorCisvLyBBdG9taWNhbGx5IHN0b3JlIG5ld192YWx1ZSBpbnRvICpwdHIsIHJldHVybmluZyB0aGUgcHJldmlvdXMgdmFsdWUgaGVsZCBpbgorLy8gKnB0ci4gIFRoaXMgcm91dGluZSBpbXBsaWVzIG5vIG1lbW9yeSBiYXJyaWVycy4KK2lubGluZSBBdG9taWMzMiBOb0JhcnJpZXJfQXRvbWljRXhjaGFuZ2Uodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgbmV3X3ZhbHVlKSB7CisgIEF0b21pYzMyIHRlbXAsIG9sZDsKKyAgX19hc21fXyBfX3ZvbGF0aWxlX18oIi5zZXQgcHVzaFxuIgorICAgICAgICAgICAgICAgICAgICAgICAiLnNldCBub3Jlb3JkZXJcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgIjE6XG4iCisgICAgICAgICAgICAgICAgICAgICAgICJsbCAlMSwgJTRcbiIgIC8vIG9sZCA9ICpwdHIKKyAgICAgICAgICAgICAgICAgICAgICAgIm1vdmUgJTAsICUzXG4iICAvLyB0ZW1wID0gbmV3X3ZhbHVlCisgICAgICAgICAgICAgICAgICAgICAgICJzYyAlMCwgJTJcbiIgIC8vICpwdHIgPSB0ZW1wICh3aXRoIGF0b21pYyBjaGVjaykKKyAgICAgICAgICAgICAgICAgICAgICAgImJlcXogJTAsIDFiXG4iICAvLyBzdGFydCBhZ2FpbiBvbiBhdG9taWMgZXJyb3IKKyAgICAgICAgICAgICAgICAgICAgICAgIm5vcFxuIiAgLy8gZGVsYXkgc2xvdCBub3AKKyAgICAgICAgICAgICAgICAgICAgICAgIi5zZXQgcG9wXG4iCisgICAgICAgICAgICAgICAgICAgICAgIDogIj0mciIgKHRlbXApLCAiPSZyIiAob2xkKSwgIj1tIiAoKnB0cikKKyAgICAgICAgICAgICAgICAgICAgICAgOiAiciIgKG5ld192YWx1ZSksICJtIiAoKnB0cikKKyAgICAgICAgICAgICAgICAgICAgICAgOiAibWVtb3J5Iik7CisKKyAgcmV0dXJuIG9sZDsKK30KKworLy8gQXRvbWljYWxseSBpbmNyZW1lbnQgKnB0ciBieSAiaW5jcmVtZW50Ii4gIFJldHVybnMgdGhlIG5ldyB2YWx1ZSBvZgorLy8gKnB0ciB3aXRoIHRoZSBpbmNyZW1lbnQgYXBwbGllZC4gIFRoaXMgcm91dGluZSBpbXBsaWVzIG5vIG1lbW9yeSBiYXJyaWVycy4KK2lubGluZSBBdG9taWMzMiBOb0JhcnJpZXJfQXRvbWljSW5jcmVtZW50KHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBpbmNyZW1lbnQpIHsKKyAgQXRvbWljMzIgdGVtcCwgdGVtcDI7CisKKyAgX19hc21fXyBfX3ZvbGF0aWxlX18oIi5zZXQgcHVzaFxuIgorICAgICAgICAgICAgICAgICAgICAgICAiLnNldCBub3Jlb3JkZXJcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgIjE6XG4iCisgICAgICAgICAgICAgICAgICAgICAgICJsbCAlMCwgJTRcbiIgIC8vIHRlbXAgPSAqcHRyCisgICAgICAgICAgICAgICAgICAgICAgICJhZGR1ICUxLCAlMCwgJTNcbiIgIC8vIHRlbXAyID0gdGVtcCArIGluY3JlbWVudAorICAgICAgICAgICAgICAgICAgICAgICAic2MgJTEsICUyXG4iICAvLyAqcHRyID0gdGVtcDIgKHdpdGggYXRvbWljIGNoZWNrKQorICAgICAgICAgICAgICAgICAgICAgICAiYmVxeiAlMSwgMWJcbiIgIC8vIHN0YXJ0IGFnYWluIG9uIGF0b21pYyBlcnJvcgorICAgICAgICAgICAgICAgICAgICAgICAiYWRkdSAlMSwgJTAsICUzXG4iICAvLyB0ZW1wMiA9IHRlbXAgKyBpbmNyZW1lbnQKKyAgICAgICAgICAgICAgICAgICAgICAgIi5zZXQgcG9wXG4iCisgICAgICAgICAgICAgICAgICAgICAgIDogIj0mciIgKHRlbXApLCAiPSZyIiAodGVtcDIpLCAiPW0iICgqcHRyKQorICAgICAgICAgICAgICAgICAgICAgICA6ICJJciIgKGluY3JlbWVudCksICJtIiAoKnB0cikKKyAgICAgICAgICAgICAgICAgICAgICAgOiAibWVtb3J5Iik7CisgIC8vIHRlbXAyIG5vdyBob2xkcyB0aGUgZmluYWwgdmFsdWUuCisgIHJldHVybiB0ZW1wMjsKK30KKworaW5saW5lIEF0b21pYzMyIEJhcnJpZXJfQXRvbWljSW5jcmVtZW50KHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgaW5jcmVtZW50KSB7CisgIEFUT01JQ09QU19DT01QSUxFUl9CQVJSSUVSKCk7CisgIEF0b21pYzMyIHJlcyA9IE5vQmFycmllcl9BdG9taWNJbmNyZW1lbnQocHRyLCBpbmNyZW1lbnQpOworICBBVE9NSUNPUFNfQ09NUElMRVJfQkFSUklFUigpOworICByZXR1cm4gcmVzOworfQorCisvLyAiQWNxdWlyZSIgb3BlcmF0aW9ucworLy8gZW5zdXJlIHRoYXQgbm8gbGF0ZXIgbWVtb3J5IGFjY2VzcyBjYW4gYmUgcmVvcmRlcmVkIGFoZWFkIG9mIHRoZSBvcGVyYXRpb24uCisvLyAiUmVsZWFzZSIgb3BlcmF0aW9ucyBlbnN1cmUgdGhhdCBubyBwcmV2aW91cyBtZW1vcnkgYWNjZXNzIGNhbiBiZSByZW9yZGVyZWQKKy8vIGFmdGVyIHRoZSBvcGVyYXRpb24uICAiQmFycmllciIgb3BlcmF0aW9ucyBoYXZlIGJvdGggIkFjcXVpcmUiIGFuZCAiUmVsZWFzZSIKKy8vIHNlbWFudGljcy4gICBBIE1lbW9yeUJhcnJpZXIoKSBoYXMgIkJhcnJpZXIiIHNlbWFudGljcywgYnV0IGRvZXMgbm8gbWVtb3J5CisvLyBhY2Nlc3MuCitpbmxpbmUgQXRvbWljMzIgQWNxdWlyZV9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgbmV3X3ZhbHVlKSB7CisgIEFUT01JQ09QU19DT01QSUxFUl9CQVJSSUVSKCk7CisgIEF0b21pYzMyIHJlcyA9IE5vQmFycmllcl9Db21wYXJlQW5kU3dhcChwdHIsIG9sZF92YWx1ZSwgbmV3X3ZhbHVlKTsKKyAgQVRPTUlDT1BTX0NPTVBJTEVSX0JBUlJJRVIoKTsKKyAgcmV0dXJuIHJlczsKK30KKworaW5saW5lIEF0b21pYzMyIFJlbGVhc2VfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG5ld192YWx1ZSkgeworICBBVE9NSUNPUFNfQ09NUElMRVJfQkFSUklFUigpOworICBBdG9taWMzMiByZXMgPSBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAocHRyLCBvbGRfdmFsdWUsIG5ld192YWx1ZSk7CisgIEFUT01JQ09QU19DT01QSUxFUl9CQVJSSUVSKCk7CisgIHJldHVybiByZXM7Cit9CisKK2lubGluZSB2b2lkIE5vQmFycmllcl9TdG9yZSh2b2xhdGlsZSBBdG9taWMzMiogcHRyLCBBdG9taWMzMiB2YWx1ZSkgeworICAqcHRyID0gdmFsdWU7Cit9CisKK2lubGluZSB2b2lkIE1lbW9yeUJhcnJpZXIoKSB7CisgIF9fYXNtX18gX192b2xhdGlsZV9fKCJzeW5jIiA6IDogOiAibWVtb3J5Iik7Cit9CisKK2lubGluZSB2b2lkIEFjcXVpcmVfU3RvcmUodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwgQXRvbWljMzIgdmFsdWUpIHsKKyAgKnB0ciA9IHZhbHVlOworICBNZW1vcnlCYXJyaWVyKCk7Cit9CisKK2lubGluZSB2b2lkIFJlbGVhc2VfU3RvcmUodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwgQXRvbWljMzIgdmFsdWUpIHsKKyAgTWVtb3J5QmFycmllcigpOworICAqcHRyID0gdmFsdWU7Cit9CisKK2lubGluZSBBdG9taWMzMiBOb0JhcnJpZXJfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWMzMiogcHRyKSB7CisgIHJldHVybiAqcHRyOworfQorCitpbmxpbmUgQXRvbWljMzIgQWNxdWlyZV9Mb2FkKHZvbGF0aWxlIGNvbnN0IEF0b21pYzMyKiBwdHIpIHsKKyAgQXRvbWljMzIgdmFsdWUgPSAqcHRyOworICBNZW1vcnlCYXJyaWVyKCk7CisgIHJldHVybiB2YWx1ZTsKK30KKworaW5saW5lIEF0b21pYzMyIFJlbGVhc2VfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWMzMiogcHRyKSB7CisgIE1lbW9yeUJhcnJpZXIoKTsKKyAgcmV0dXJuICpwdHI7Cit9CisKKyNpZiBkZWZpbmVkKF9fTFA2NF9fKQorLy8gNjQtYml0IHZlcnNpb25zIG9mIHRoZSBhdG9taWMgb3BzLgorCitpbmxpbmUgQXRvbWljNjQgTm9CYXJyaWVyX0NvbXBhcmVBbmRTd2FwKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgbmV3X3ZhbHVlKSB7CisgIEF0b21pYzY0IHByZXYsIHRtcDsKKyAgX19hc21fXyBfX3ZvbGF0aWxlX18oIi5zZXQgcHVzaFxuIgorICAgICAgICAgICAgICAgICAgICAgICAiLnNldCBub3Jlb3JkZXJcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgIjE6XG4iCisgICAgICAgICAgICAgICAgICAgICAgICJsbGQgJTAsICU1XG4iICAvLyBwcmV2ID0gKnB0cgorICAgICAgICAgICAgICAgICAgICAgICAiYm5lICUwLCAlMywgMmZcbiIgIC8vIGlmIChwcmV2ICE9IG9sZF92YWx1ZSkgZ290byAyCisgICAgICAgICAgICAgICAgICAgICAgICJtb3ZlICUyLCAlNFxuIiAgLy8gdG1wID0gbmV3X3ZhbHVlCisgICAgICAgICAgICAgICAgICAgICAgICJzY2QgJTIsICUxXG4iICAvLyAqcHRyID0gdG1wICh3aXRoIGF0b21pYyBjaGVjaykKKyAgICAgICAgICAgICAgICAgICAgICAgImJlcXogJTIsIDFiXG4iICAvLyBzdGFydCBhZ2FpbiBvbiBhdG9taWMgZXJyb3IKKyAgICAgICAgICAgICAgICAgICAgICAgIm5vcFxuIiAgLy8gZGVsYXkgc2xvdCBub3AKKyAgICAgICAgICAgICAgICAgICAgICAgIjI6XG4iCisgICAgICAgICAgICAgICAgICAgICAgICIuc2V0IHBvcFxuIgorICAgICAgICAgICAgICAgICAgICAgICA6ICI9JnIiIChwcmV2KSwgIj1tIiAoKnB0ciksICI9JnIiICh0bXApCisgICAgICAgICAgICAgICAgICAgICAgIDogInIiIChvbGRfdmFsdWUpLCAiciIgKG5ld192YWx1ZSksICJtIiAoKnB0cikKKyAgICAgICAgICAgICAgICAgICAgICAgOiAibWVtb3J5Iik7CisgIHJldHVybiBwcmV2OworfQorCisvLyBBdG9taWNhbGx5IHN0b3JlIG5ld192YWx1ZSBpbnRvICpwdHIsIHJldHVybmluZyB0aGUgcHJldmlvdXMgdmFsdWUgaGVsZCBpbgorLy8gKnB0ci4gIFRoaXMgcm91dGluZSBpbXBsaWVzIG5vIG1lbW9yeSBiYXJyaWVycy4KK2lubGluZSBBdG9taWM2NCBOb0JhcnJpZXJfQXRvbWljRXhjaGFuZ2Uodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgbmV3X3ZhbHVlKSB7CisgIEF0b21pYzY0IHRlbXAsIG9sZDsKKyAgX19hc21fXyBfX3ZvbGF0aWxlX18oIi5zZXQgcHVzaFxuIgorICAgICAgICAgICAgICAgICAgICAgICAiLnNldCBub3Jlb3JkZXJcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgIjE6XG4iCisgICAgICAgICAgICAgICAgICAgICAgICJsbGQgJTEsICU0XG4iICAvLyBvbGQgPSAqcHRyCisgICAgICAgICAgICAgICAgICAgICAgICJtb3ZlICUwLCAlM1xuIiAgLy8gdGVtcCA9IG5ld192YWx1ZQorICAgICAgICAgICAgICAgICAgICAgICAic2NkICUwLCAlMlxuIiAgLy8gKnB0ciA9IHRlbXAgKHdpdGggYXRvbWljIGNoZWNrKQorICAgICAgICAgICAgICAgICAgICAgICAiYmVxeiAlMCwgMWJcbiIgIC8vIHN0YXJ0IGFnYWluIG9uIGF0b21pYyBlcnJvcgorICAgICAgICAgICAgICAgICAgICAgICAibm9wXG4iICAvLyBkZWxheSBzbG90IG5vcAorICAgICAgICAgICAgICAgICAgICAgICAiLnNldCBwb3BcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgOiAiPSZyIiAodGVtcCksICI9JnIiIChvbGQpLCAiPW0iICgqcHRyKQorICAgICAgICAgICAgICAgICAgICAgICA6ICJyIiAobmV3X3ZhbHVlKSwgIm0iICgqcHRyKQorICAgICAgICAgICAgICAgICAgICAgICA6ICJtZW1vcnkiKTsKKworICByZXR1cm4gb2xkOworfQorCisvLyBBdG9taWNhbGx5IGluY3JlbWVudCAqcHRyIGJ5ICJpbmNyZW1lbnQiLiAgUmV0dXJucyB0aGUgbmV3IHZhbHVlIG9mCisvLyAqcHRyIHdpdGggdGhlIGluY3JlbWVudCBhcHBsaWVkLiAgVGhpcyByb3V0aW5lIGltcGxpZXMgbm8gbWVtb3J5IGJhcnJpZXJzLgoraW5saW5lIEF0b21pYzY0IE5vQmFycmllcl9BdG9taWNJbmNyZW1lbnQodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IGluY3JlbWVudCkgeworICBBdG9taWM2NCB0ZW1wLCB0ZW1wMjsKKworICBfX2FzbV9fIF9fdm9sYXRpbGVfXygiLnNldCBwdXNoXG4iCisgICAgICAgICAgICAgICAgICAgICAgICIuc2V0IG5vcmVvcmRlclxuIgorICAgICAgICAgICAgICAgICAgICAgICAiMTpcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgImxsZCAlMCwgJTRcbiIgIC8vIHRlbXAgPSAqcHRyCisgICAgICAgICAgICAgICAgICAgICAgICJkYWRkdSAlMSwgJTAsICUzXG4iICAvLyB0ZW1wMiA9IHRlbXAgKyBpbmNyZW1lbnQKKyAgICAgICAgICAgICAgICAgICAgICAgInNjZCAlMSwgJTJcbiIgIC8vICpwdHIgPSB0ZW1wMiAod2l0aCBhdG9taWMgY2hlY2spCisgICAgICAgICAgICAgICAgICAgICAgICJiZXF6ICUxLCAxYlxuIiAgLy8gc3RhcnQgYWdhaW4gb24gYXRvbWljIGVycm9yCisgICAgICAgICAgICAgICAgICAgICAgICJkYWRkdSAlMSwgJTAsICUzXG4iICAvLyB0ZW1wMiA9IHRlbXAgKyBpbmNyZW1lbnQKKyAgICAgICAgICAgICAgICAgICAgICAgIi5zZXQgcG9wXG4iCisgICAgICAgICAgICAgICAgICAgICAgIDogIj0mciIgKHRlbXApLCAiPSZyIiAodGVtcDIpLCAiPW0iICgqcHRyKQorICAgICAgICAgICAgICAgICAgICAgICA6ICJJciIgKGluY3JlbWVudCksICJtIiAoKnB0cikKKyAgICAgICAgICAgICAgICAgICAgICAgOiAibWVtb3J5Iik7CisgIC8vIHRlbXAyIG5vdyBob2xkcyB0aGUgZmluYWwgdmFsdWUuCisgIHJldHVybiB0ZW1wMjsKK30KKworaW5saW5lIEF0b21pYzY0IEJhcnJpZXJfQXRvbWljSW5jcmVtZW50KHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgaW5jcmVtZW50KSB7CisgIE1lbW9yeUJhcnJpZXIoKTsKKyAgQXRvbWljNjQgcmVzID0gTm9CYXJyaWVyX0F0b21pY0luY3JlbWVudChwdHIsIGluY3JlbWVudCk7CisgIE1lbW9yeUJhcnJpZXIoKTsKKyAgcmV0dXJuIHJlczsKK30KKworLy8gIkFjcXVpcmUiIG9wZXJhdGlvbnMKKy8vIGVuc3VyZSB0aGF0IG5vIGxhdGVyIG1lbW9yeSBhY2Nlc3MgY2FuIGJlIHJlb3JkZXJlZCBhaGVhZCBvZiB0aGUgb3BlcmF0aW9uLgorLy8gIlJlbGVhc2UiIG9wZXJhdGlvbnMgZW5zdXJlIHRoYXQgbm8gcHJldmlvdXMgbWVtb3J5IGFjY2VzcyBjYW4gYmUgcmVvcmRlcmVkCisvLyBhZnRlciB0aGUgb3BlcmF0aW9uLiAgIkJhcnJpZXIiIG9wZXJhdGlvbnMgaGF2ZSBib3RoICJBY3F1aXJlIiBhbmQgIlJlbGVhc2UiCisvLyBzZW1hbnRpY3MuICAgQSBNZW1vcnlCYXJyaWVyKCkgaGFzICJCYXJyaWVyIiBzZW1hbnRpY3MsIGJ1dCBkb2VzIG5vIG1lbW9yeQorLy8gYWNjZXNzLgoraW5saW5lIEF0b21pYzY0IEFjcXVpcmVfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG5ld192YWx1ZSkgeworICBBdG9taWM2NCByZXMgPSBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAocHRyLCBvbGRfdmFsdWUsIG5ld192YWx1ZSk7CisgIE1lbW9yeUJhcnJpZXIoKTsKKyAgcmV0dXJuIHJlczsKK30KKworaW5saW5lIEF0b21pYzY0IFJlbGVhc2VfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG5ld192YWx1ZSkgeworICBNZW1vcnlCYXJyaWVyKCk7CisgIHJldHVybiBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAocHRyLCBvbGRfdmFsdWUsIG5ld192YWx1ZSk7Cit9CisKK2lubGluZSB2b2lkIE5vQmFycmllcl9TdG9yZSh2b2xhdGlsZSBBdG9taWM2NCogcHRyLCBBdG9taWM2NCB2YWx1ZSkgeworICAqcHRyID0gdmFsdWU7Cit9CisKK2lubGluZSB2b2lkIEFjcXVpcmVfU3RvcmUodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwgQXRvbWljNjQgdmFsdWUpIHsKKyAgKnB0ciA9IHZhbHVlOworICBNZW1vcnlCYXJyaWVyKCk7Cit9CisKK2lubGluZSB2b2lkIFJlbGVhc2VfU3RvcmUodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwgQXRvbWljNjQgdmFsdWUpIHsKKyAgTWVtb3J5QmFycmllcigpOworICAqcHRyID0gdmFsdWU7Cit9CisKK2lubGluZSBBdG9taWM2NCBOb0JhcnJpZXJfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWM2NCogcHRyKSB7CisgIHJldHVybiAqcHRyOworfQorCitpbmxpbmUgQXRvbWljNjQgQWNxdWlyZV9Mb2FkKHZvbGF0aWxlIGNvbnN0IEF0b21pYzY0KiBwdHIpIHsKKyAgQXRvbWljNjQgdmFsdWUgPSAqcHRyOworICBNZW1vcnlCYXJyaWVyKCk7CisgIHJldHVybiB2YWx1ZTsKK30KKworaW5saW5lIEF0b21pYzY0IFJlbGVhc2VfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWM2NCogcHRyKSB7CisgIE1lbW9yeUJhcnJpZXIoKTsKKyAgcmV0dXJuICpwdHI7Cit9CisjZW5kaWYKKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI3VuZGVmIEFUT01JQ09QU19DT01QSUxFUl9CQVJSSUVSCisKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19JTlRFUk5BTFNfTUlQU19HQ0NfSF8KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc19wbmFjbC5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX3BuYWNsLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2IzMTRmZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc19wbmFjbC5oCkBAIC0wLDAgKzEsMjMxIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDEyIEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gVGhpcyBmaWxlIGlzIGFuIGludGVybmFsIGF0b21pYyBpbXBsZW1lbnRhdGlvbiwgdXNlIGF0b21pY29wcy5oIGluc3RlYWQuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19JTlRFUk5BTFNfUE5BQ0xfSF8KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19JTlRFUk5BTFNfUE5BQ0xfSF8KKworI2luY2x1ZGUgPGF0b21pYz4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKworLy8gVGhpcyBpbXBsZW1lbnRhdGlvbiBpcyB0cmFuc2l0aW9uYWwgYW5kIG1haW50YWlucyB0aGUgb3JpZ2luYWwgQVBJIGZvcgorLy8gYXRvbWljb3BzLmguIFRoaXMgcmVxdWlyZXMgY2FzdGluZyBtZW1vcnkgbG9jYXRpb25zIHRvIHRoZSBhdG9taWMgdHlwZXMsIGFuZAorLy8gYXNzdW1lcyB0aGF0IHRoZSBBUEkgYW5kIHRoZSBDKysxMSBpbXBsZW1lbnRhdGlvbiBhcmUgbGF5b3V0LWNvbXBhdGlibGUsCisvLyB3aGljaCBpc24ndCB0cnVlIGZvciBhbGwgaW1wbGVtZW50YXRpb25zIG9yIGhhcmR3YXJlIHBsYXRmb3Jtcy4gVGhlIHN0YXRpYworLy8gYXNzZXJ0aW9uIHNob3VsZCBkZXRlY3QgdGhpcyBpc3N1ZSwgd2VyZSBpdCB0byBmaXJlIHRoZW4gdGhpcyBoZWFkZXIKKy8vIHNob3VsZG4ndCBiZSB1c2VkLgorLy8KKy8vIFRPRE8oamZiKSBJZiB0aGlzIGhlYWRlciBtYW5hZ2VzIHRvIHN0YXkgY29tbWl0dGVkIHRoZW4gdGhlIEFQSSBzaG91bGQgYmUKKy8vICAgICAgICAgICBtb2RpZmllZCwgYW5kIGFsbCBjYWxsIHNpdGVzIHVwZGF0ZWQuCit0eXBlZGVmIHZvbGF0aWxlIHN0ZDo6YXRvbWljPEF0b21pYzMyPiogQXRvbWljTG9jYXRpb24zMjsKK3N0YXRpY19hc3NlcnQoc2l6ZW9mKCooQXRvbWljTG9jYXRpb24zMikgbnVsbHB0cikgPT0gc2l6ZW9mKEF0b21pYzMyKSwKKyAgICAgICAgICAgICAgImluY29tcGF0aWJsZSAzMi1iaXQgYXRvbWljIGxheW91dCIpOworCitpbmxpbmUgdm9pZCBNZW1vcnlCYXJyaWVyKCkgeworI2lmIGRlZmluZWQoX19HTElCQ1hYX18pCisgIC8vIFdvcmsgYXJvdW5kIGxpYnN0ZGMrKyBidWcgNTEwMzggd2hlcmUgYXRvbWljX3RocmVhZF9mZW5jZSB3YXMgZGVjbGFyZWQgYnV0CisgIC8vIG5vdCBkZWZpbmVkLCBsZWFkaW5nIHRvIHRoZSBsaW5rZXIgY29tcGxhaW5pbmcgYWJvdXQgdW5kZWZpbmVkIHJlZmVyZW5jZXMuCisgIF9fYXRvbWljX3RocmVhZF9mZW5jZShzdGQ6Om1lbW9yeV9vcmRlcl9zZXFfY3N0KTsKKyNlbHNlCisgIHN0ZDo6YXRvbWljX3RocmVhZF9mZW5jZShzdGQ6Om1lbW9yeV9vcmRlcl9zZXFfY3N0KTsKKyNlbmRpZgorfQorCitpbmxpbmUgQXRvbWljMzIgTm9CYXJyaWVyX0NvbXBhcmVBbmRTd2FwKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgbmV3X3ZhbHVlKSB7CisgICgoQXRvbWljTG9jYXRpb24zMilwdHIpCisgICAgICAtPmNvbXBhcmVfZXhjaGFuZ2Vfc3Ryb25nKG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3X3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6Om1lbW9yeV9vcmRlcl9yZWxheGVkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6Om1lbW9yeV9vcmRlcl9yZWxheGVkKTsKKyAgcmV0dXJuIG9sZF92YWx1ZTsKK30KKworaW5saW5lIEF0b21pYzMyIE5vQmFycmllcl9BdG9taWNFeGNoYW5nZSh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBuZXdfdmFsdWUpIHsKKyAgcmV0dXJuICgoQXRvbWljTG9jYXRpb24zMilwdHIpCisgICAgICAtPmV4Y2hhbmdlKG5ld192YWx1ZSwgc3RkOjptZW1vcnlfb3JkZXJfcmVsYXhlZCk7Cit9CisKK2lubGluZSBBdG9taWMzMiBOb0JhcnJpZXJfQXRvbWljSW5jcmVtZW50KHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBpbmNyZW1lbnQpIHsKKyAgcmV0dXJuIGluY3JlbWVudCArCisgICAgICAgICAoKEF0b21pY0xvY2F0aW9uMzIpcHRyKQorICAgICAgICAgICAgIC0+ZmV0Y2hfYWRkKGluY3JlbWVudCwgc3RkOjptZW1vcnlfb3JkZXJfcmVsYXhlZCk7Cit9CisKK2lubGluZSBBdG9taWMzMiBCYXJyaWVyX0F0b21pY0luY3JlbWVudCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIGluY3JlbWVudCkgeworICByZXR1cm4gaW5jcmVtZW50ICsgKChBdG9taWNMb2NhdGlvbjMyKXB0ciktPmZldGNoX2FkZChpbmNyZW1lbnQpOworfQorCitpbmxpbmUgQXRvbWljMzIgQWNxdWlyZV9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgbmV3X3ZhbHVlKSB7CisgICgoQXRvbWljTG9jYXRpb24zMilwdHIpCisgICAgICAtPmNvbXBhcmVfZXhjaGFuZ2Vfc3Ryb25nKG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3X3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6Om1lbW9yeV9vcmRlcl9hY3F1aXJlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6Om1lbW9yeV9vcmRlcl9hY3F1aXJlKTsKKyAgcmV0dXJuIG9sZF92YWx1ZTsKK30KKworaW5saW5lIEF0b21pYzMyIFJlbGVhc2VfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG5ld192YWx1ZSkgeworICAoKEF0b21pY0xvY2F0aW9uMzIpcHRyKQorICAgICAgLT5jb21wYXJlX2V4Y2hhbmdlX3N0cm9uZyhvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld192YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjptZW1vcnlfb3JkZXJfcmVsZWFzZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjptZW1vcnlfb3JkZXJfcmVsYXhlZCk7CisgIHJldHVybiBvbGRfdmFsdWU7Cit9CisKK2lubGluZSB2b2lkIE5vQmFycmllcl9TdG9yZSh2b2xhdGlsZSBBdG9taWMzMiogcHRyLCBBdG9taWMzMiB2YWx1ZSkgeworICAoKEF0b21pY0xvY2F0aW9uMzIpcHRyKS0+c3RvcmUodmFsdWUsIHN0ZDo6bWVtb3J5X29yZGVyX3JlbGF4ZWQpOworfQorCitpbmxpbmUgdm9pZCBBY3F1aXJlX1N0b3JlKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsIEF0b21pYzMyIHZhbHVlKSB7CisgICgoQXRvbWljTG9jYXRpb24zMilwdHIpLT5zdG9yZSh2YWx1ZSwgc3RkOjptZW1vcnlfb3JkZXJfcmVsYXhlZCk7CisgIE1lbW9yeUJhcnJpZXIoKTsKK30KKworaW5saW5lIHZvaWQgUmVsZWFzZV9TdG9yZSh2b2xhdGlsZSBBdG9taWMzMiogcHRyLCBBdG9taWMzMiB2YWx1ZSkgeworICAoKEF0b21pY0xvY2F0aW9uMzIpcHRyKS0+c3RvcmUodmFsdWUsIHN0ZDo6bWVtb3J5X29yZGVyX3JlbGVhc2UpOworfQorCitpbmxpbmUgQXRvbWljMzIgTm9CYXJyaWVyX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljMzIqIHB0cikgeworICByZXR1cm4gKChBdG9taWNMb2NhdGlvbjMyKXB0ciktPmxvYWQoc3RkOjptZW1vcnlfb3JkZXJfcmVsYXhlZCk7Cit9CisKK2lubGluZSBBdG9taWMzMiBBY3F1aXJlX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljMzIqIHB0cikgeworICByZXR1cm4gKChBdG9taWNMb2NhdGlvbjMyKXB0ciktPmxvYWQoc3RkOjptZW1vcnlfb3JkZXJfYWNxdWlyZSk7Cit9CisKK2lubGluZSBBdG9taWMzMiBSZWxlYXNlX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljMzIqIHB0cikgeworICBNZW1vcnlCYXJyaWVyKCk7CisgIHJldHVybiAoKEF0b21pY0xvY2F0aW9uMzIpcHRyKS0+bG9hZChzdGQ6Om1lbW9yeV9vcmRlcl9yZWxheGVkKTsKK30KKworI2lmIGRlZmluZWQoR09PR0xFX1BST1RPQlVGX0FSQ0hfNjRfQklUKQorCit0eXBlZGVmIHZvbGF0aWxlIHN0ZDo6YXRvbWljPEF0b21pYzY0PiogQXRvbWljTG9jYXRpb242NDsKK3N0YXRpY19hc3NlcnQoc2l6ZW9mKCooQXRvbWljTG9jYXRpb242NCkgbnVsbHB0cikgPT0gc2l6ZW9mKEF0b21pYzY0KSwKKyAgICAgICAgICAgICAgImluY29tcGF0aWJsZSA2NC1iaXQgYXRvbWljIGxheW91dCIpOworCitpbmxpbmUgQXRvbWljNjQgTm9CYXJyaWVyX0NvbXBhcmVBbmRTd2FwKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgbmV3X3ZhbHVlKSB7CisgICgoQXRvbWljTG9jYXRpb242NClwdHIpCisgICAgICAtPmNvbXBhcmVfZXhjaGFuZ2Vfc3Ryb25nKG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3X3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6Om1lbW9yeV9vcmRlcl9yZWxheGVkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6Om1lbW9yeV9vcmRlcl9yZWxheGVkKTsKKyAgcmV0dXJuIG9sZF92YWx1ZTsKK30KKworaW5saW5lIEF0b21pYzY0IE5vQmFycmllcl9BdG9taWNFeGNoYW5nZSh2b2xhdGlsZSBBdG9taWM2NCogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBuZXdfdmFsdWUpIHsKKyAgcmV0dXJuICgoQXRvbWljTG9jYXRpb242NClwdHIpCisgICAgICAtPmV4Y2hhbmdlKG5ld192YWx1ZSwgc3RkOjptZW1vcnlfb3JkZXJfcmVsYXhlZCk7Cit9CisKK2lubGluZSBBdG9taWM2NCBOb0JhcnJpZXJfQXRvbWljSW5jcmVtZW50KHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBpbmNyZW1lbnQpIHsKKyAgcmV0dXJuIGluY3JlbWVudCArCisgICAgICAgICAoKEF0b21pY0xvY2F0aW9uNjQpcHRyKQorICAgICAgICAgICAgIC0+ZmV0Y2hfYWRkKGluY3JlbWVudCwgc3RkOjptZW1vcnlfb3JkZXJfcmVsYXhlZCk7Cit9CisKK2lubGluZSBBdG9taWM2NCBCYXJyaWVyX0F0b21pY0luY3JlbWVudCh2b2xhdGlsZSBBdG9taWM2NCogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IGluY3JlbWVudCkgeworICByZXR1cm4gaW5jcmVtZW50ICsgKChBdG9taWNMb2NhdGlvbjY0KXB0ciktPmZldGNoX2FkZChpbmNyZW1lbnQpOworfQorCitpbmxpbmUgQXRvbWljNjQgQWNxdWlyZV9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWM2NCogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgbmV3X3ZhbHVlKSB7CisgICgoQXRvbWljTG9jYXRpb242NClwdHIpCisgICAgICAtPmNvbXBhcmVfZXhjaGFuZ2Vfc3Ryb25nKG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3X3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6Om1lbW9yeV9vcmRlcl9hY3F1aXJlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6Om1lbW9yeV9vcmRlcl9hY3F1aXJlKTsKKyAgcmV0dXJuIG9sZF92YWx1ZTsKK30KKworaW5saW5lIEF0b21pYzY0IFJlbGVhc2VfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG5ld192YWx1ZSkgeworICAoKEF0b21pY0xvY2F0aW9uNjQpcHRyKQorICAgICAgLT5jb21wYXJlX2V4Y2hhbmdlX3N0cm9uZyhvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld192YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjptZW1vcnlfb3JkZXJfcmVsZWFzZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjptZW1vcnlfb3JkZXJfcmVsYXhlZCk7CisgIHJldHVybiBvbGRfdmFsdWU7Cit9CisKK2lubGluZSB2b2lkIE5vQmFycmllcl9TdG9yZSh2b2xhdGlsZSBBdG9taWM2NCogcHRyLCBBdG9taWM2NCB2YWx1ZSkgeworICAoKEF0b21pY0xvY2F0aW9uNjQpcHRyKS0+c3RvcmUodmFsdWUsIHN0ZDo6bWVtb3J5X29yZGVyX3JlbGF4ZWQpOworfQorCitpbmxpbmUgdm9pZCBBY3F1aXJlX1N0b3JlKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsIEF0b21pYzY0IHZhbHVlKSB7CisgICgoQXRvbWljTG9jYXRpb242NClwdHIpLT5zdG9yZSh2YWx1ZSwgc3RkOjptZW1vcnlfb3JkZXJfcmVsYXhlZCk7CisgIE1lbW9yeUJhcnJpZXIoKTsKK30KKworaW5saW5lIHZvaWQgUmVsZWFzZV9TdG9yZSh2b2xhdGlsZSBBdG9taWM2NCogcHRyLCBBdG9taWM2NCB2YWx1ZSkgeworICAoKEF0b21pY0xvY2F0aW9uNjQpcHRyKS0+c3RvcmUodmFsdWUsIHN0ZDo6bWVtb3J5X29yZGVyX3JlbGVhc2UpOworfQorCitpbmxpbmUgQXRvbWljNjQgTm9CYXJyaWVyX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljNjQqIHB0cikgeworICByZXR1cm4gKChBdG9taWNMb2NhdGlvbjY0KXB0ciktPmxvYWQoc3RkOjptZW1vcnlfb3JkZXJfcmVsYXhlZCk7Cit9CisKK2lubGluZSBBdG9taWM2NCBBY3F1aXJlX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljNjQqIHB0cikgeworICByZXR1cm4gKChBdG9taWNMb2NhdGlvbjY0KXB0ciktPmxvYWQoc3RkOjptZW1vcnlfb3JkZXJfYWNxdWlyZSk7Cit9CisKK2lubGluZSBBdG9taWM2NCBSZWxlYXNlX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljNjQqIHB0cikgeworICBNZW1vcnlCYXJyaWVyKCk7CisgIHJldHVybiAoKEF0b21pY0xvY2F0aW9uNjQpcHRyKS0+bG9hZChzdGQ6Om1lbW9yeV9vcmRlcl9yZWxheGVkKTsKK30KKworI2VuZGlmICAvLyBkZWZpbmVkKEdPT0dMRV9QUk9UT0JVRl9BUkNIXzY0X0JJVCkKKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfQVRPTUlDT1BTX0lOVEVSTkFMU19QTkFDTF9IXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX3Bvd2VyLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfcG93ZXIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iOGE0MmYyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX3Bvd2VyLmgKQEAgLTAsMCArMSw0NDAgQEAKKy8vIENvcHlyaWdodCAyMDE0IEJsb29tYmVyZyBGaW5hbmNlIExQLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEJsb29tYmVyZyBGaW5hbmNlIExQLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gVGhpcyBmaWxlIGlzIGFuIGludGVybmFsIGF0b21pYyBpbXBsZW1lbnRhdGlvbiwgdXNlIGF0b21pY29wcy5oIGluc3RlYWQuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19JTlRFUk5BTFNfQUlYX0hfCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNPUFNfSU5URVJOQUxTX0FJWF9IXworCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW50ZXJuYWwgeworCitpbmxpbmUgQXRvbWljMzIgTm9CYXJyaWVyX0NvbXBhcmVBbmRTd2FwKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgbmV3X3ZhbHVlKSB7CisgIEF0b21pYzMyIHJlc3VsdDsKKworICBhc20gdm9sYXRpbGUgKAorICAgICAgIjE6ICAgICBsd2FyeCAlW3Jlc10sICVbemVyb10sICVbb2JqXSAgIFxuXHQiICAvLyBsb2FkIGFuZCByZXNlcnZlCisgICAgICAiICAgICAgIGNtcHcgJVtjbXBdLCAlW3Jlc10gICAgICAgICAgICAgXG5cdCIgIC8vIGNvbXBhcmUgdmFsdWVzCisgICAgICAiICAgICAgIGJuZS0gMmYgICAgICAgICAgICAgICAgICAgICAgICAgXG5cdCIKKyAgICAgICIgICAgICAgc3R3Y3guICVbdmFsXSwgJVt6ZXJvXSwgJVtvYmpdICBcblx0IiAgLy8gc3RvcmUgbmV3IHZhbHVlCisgICAgICAiICAgICAgIGJuZS0gMWIgICAgICAgICAgICAgICAgICAgICAgICAgXG5cdCIKKyAgICAgICIyOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcblx0IgorICAgICAgICAgICAgICA6IFtyZXNdICAiPSZiIiAocmVzdWx0KQorICAgICAgICAgICAgICA6IFtvYmpdICAiYiIgICAocHRyKSwKKyAgICAgICAgICAgICAgICBbY21wXSAgImIiICAgKG9sZF92YWx1ZSksCisgICAgICAgICAgICAgICAgW3ZhbF0gICJiIiAgIChuZXdfdmFsdWUpLAorICAgICAgICAgICAgICAgIFt6ZXJvXSAiaSIgICAoMCkKKyAgICAgICAgICAgICAgOiAiY3IwIiwgImN0ciIpOworCisgIHJldHVybiByZXN1bHQ7Cit9CisKK2lubGluZSBBdG9taWMzMiBOb0JhcnJpZXJfQXRvbWljRXhjaGFuZ2Uodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgbmV3X3ZhbHVlKSB7CisgIEF0b21pYzMyIHJlc3VsdDsKKworICBhc20gdm9sYXRpbGUgKAorICAgICAgIjE6ICAgICBsd2FyeCAlW3Jlc10sICVbemVyb10sICVbb2JqXSAgICAgICBcblx0IgorICAgICAgIiAgICAgICBzdHdjeC4gJVt2YWxdLCAlW3plcm9dLCAlW29ial0gICAgICBcblx0IgorICAgICAgIiAgICAgICBibmUtIDFiICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcblx0IgorICAgICAgICAgICAgICA6IFtyZXNdICAiPSZiIiAocmVzdWx0KQorICAgICAgICAgICAgICA6IFtvYmpdICAiYiIgICAocHRyKSwKKyAgICAgICAgICAgICAgICBbdmFsXSAgImIiICAgKG5ld192YWx1ZSksCisgICAgICAgICAgICAgICAgW3plcm9dICJpIiAgICgwKQorICAgICAgICAgICAgICA6ICJjcjAiLCAiY3RyIik7CisKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworaW5saW5lIEF0b21pYzMyIE5vQmFycmllcl9BdG9taWNJbmNyZW1lbnQodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIGluY3JlbWVudCkgeworICBBdG9taWMzMiByZXN1bHQ7CisKKyAgYXNtIHZvbGF0aWxlICgKKyAgICAgICIxOiAgICAgbHdhcnggJVtyZXNdLCAlW3plcm9dLCAlW29ial0gICBcblx0IiAgLy8gbG9hZCBhbmQgcmVzZXJ2ZQorICAgICAgIiAgICAgICBhZGQgJVtyZXNdLCAlW3ZhbF0sICVbcmVzXSAgICAgIFxuXHQiICAvLyBhZGQgdGhlIG9wZXJhbmQKKyAgICAgICIgICAgICAgc3R3Y3guICVbcmVzXSwgJVt6ZXJvXSwgJVtvYmpdICBcblx0IiAgLy8gc3RvcmUgb2xkIHZhbHVlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlmIHN0aWxsIHJlc2VydmVkCisgICAgICAiICAgICAgIGJuZS0gMWIgICAgICAgICAgICAgICAgICAgICAgICAgXG5cdCIKKyAgICAgICAgICAgICAgOiBbcmVzXSAgIj0mYiIgKHJlc3VsdCkKKyAgICAgICAgICAgICAgOiBbb2JqXSAgImIiICAgKHB0ciksCisgICAgICAgICAgICAgICAgW3ZhbF0gICJiIiAgIChpbmNyZW1lbnQpLAorICAgICAgICAgICAgICAgIFt6ZXJvXSAiaSIgICAoMCkKKyAgICAgICAgICAgICAgOiAiY3IwIiwgImN0ciIpOworCisgIHJldHVybiByZXN1bHQ7Cit9CisKK2lubGluZSB2b2lkIE1lbW9yeUJhcnJpZXIodm9pZCkgeworICBhc20gdm9sYXRpbGUgKAorICAgICAgIiAgICAgICBsd3N5bmMgICAgICAgICAgICAgICAgICAgICAgICAgIFxuXHQiCisgICAgICAiICAgICAgIGlzeW5jICAgICAgICAgICAgICAgICAgICAgICAgICAgXG5cdCIKKyAgICAgICAgICAgICAgOgorICAgICAgICAgICAgICA6CisgICAgICAgICAgICAgIDogIm1lbW9yeSIpOworfQorCitpbmxpbmUgQXRvbWljMzIgQmFycmllcl9BdG9taWNJbmNyZW1lbnQodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBpbmNyZW1lbnQpIHsKKyAgQXRvbWljMzIgcmVzdWx0OworCisgIGFzbSB2b2xhdGlsZSAoCisgICAgICAiICAgICAgIGx3c3luYyAgICAgICAgICAgICAgICAgICAgICAgICAgXG5cdCIKKworICAgICAgIjE6ICAgICBsd2FyeCAlW3Jlc10sICVbemVyb10sICVbb2JqXSAgIFxuXHQiICAvLyBsb2FkIGFuZCByZXNlcnZlCisgICAgICAiICAgICAgIGFkZCAlW3Jlc10sICVbdmFsXSwgJVtyZXNdICAgICAgXG5cdCIgIC8vIGFkZCB0aGUgb3BlcmFuZAorICAgICAgIiAgICAgICBzdHdjeC4gJVtyZXNdLCAlW3plcm9dLCAlW29ial0gIFxuXHQiICAvLyBzdG9yZSBvbGQgdmFsdWUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgc3RpbGwgcmVzZXJ2ZWQKKyAgICAgICIgICAgICAgYm5lLSAxYiAgICAgICAgICAgICAgICAgICAgICAgICBcblx0IgorICAgICAgIiAgICAgICBpc3luYyAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuXHQiCisgICAgICAgICAgICAgIDogW3Jlc10gICI9JmIiIChyZXN1bHQpCisgICAgICAgICAgICAgIDogW29ial0gICJiIiAgIChwdHIpLAorICAgICAgICAgICAgICAgIFt2YWxdICAiYiIgICAoaW5jcmVtZW50KSwKKyAgICAgICAgICAgICAgICBbemVyb10gImkiICAgKDApCisgICAgICAgICAgICAgIDogImNyMCIsICJjdHIiKTsKKworICByZXR1cm4gcmVzdWx0OworfQorCitpbmxpbmUgQXRvbWljMzIgQWNxdWlyZV9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgbmV3X3ZhbHVlKSB7CisgIEF0b21pYzMyIHJlc3VsdDsKKworICBhc20gdm9sYXRpbGUgKAorICAgICAgIjE6ICAgICBsd2FyeCAlW3Jlc10sICVbemVyb10sICVbb2JqXSAgIFxuXHQiICAvLyBsb2FkIGFuZCByZXNlcnZlCisgICAgICAiICAgICAgIGNtcHcgJVtjbXBdLCAlW3Jlc10gICAgICAgICAgICAgXG5cdCIgIC8vIGNvbXBhcmUgdmFsdWVzCisgICAgICAiICAgICAgIGJuZS0gMmYgICAgICAgICAgICAgICAgICAgICAgICAgXG5cdCIKKyAgICAgICIgICAgICAgc3R3Y3guICVbdmFsXSwgJVt6ZXJvXSwgJVtvYmpdICBcblx0IiAgLy8gc3RvcmUgbmV3IHZhbHVlCisgICAgICAiICAgICAgIGJuZS0gMWIgICAgICAgICAgICAgICAgICAgICAgICAgXG5cdCIKKworICAgICAgIiAgICAgICBpc3luYyAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuXHQiCisgICAgICAiMjogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG5cdCIKKyAgICAgICAgICAgICAgOiBbcmVzXSAgIj0mYiIgKHJlc3VsdCkKKyAgICAgICAgICAgICAgOiBbb2JqXSAgImIiICAgKHB0ciksCisgICAgICAgICAgICAgICAgW2NtcF0gICJiIiAgIChvbGRfdmFsdWUpLAorICAgICAgICAgICAgICAgIFt2YWxdICAiYiIgICAobmV3X3ZhbHVlKSwKKyAgICAgICAgICAgICAgICBbemVyb10gImkiICAgKDApCisgICAgICAgICAgICAgIDogImNyMCIsICJjdHIiKTsKKworICByZXR1cm4gcmVzdWx0OworfQorCitpbmxpbmUgQXRvbWljMzIgUmVsZWFzZV9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgbmV3X3ZhbHVlKSB7CisgIEF0b21pYzMyIHJlc3VsdDsKKworICBhc20gdm9sYXRpbGUgKAorICAgICAgIiAgICAgICBsd3N5bmMgICAgICAgICAgICAgICAgICAgICAgICAgIFxuXHQiCisKKyAgICAgICIxOiAgICAgbHdhcnggJVtyZXNdLCAlW3plcm9dLCAlW29ial0gICBcblx0IiAgLy8gbG9hZCBhbmQgcmVzZXJ2ZQorICAgICAgIiAgICAgICBjbXB3ICVbY21wXSwgJVtyZXNdICAgICAgICAgICAgIFxuXHQiICAvLyBjb21wYXJlIHZhbHVlcworICAgICAgIiAgICAgICBibmUtIDJmICAgICAgICAgICAgICAgICAgICAgICAgIFxuXHQiCisgICAgICAiICAgICAgIHN0d2N4LiAlW3ZhbF0sICVbemVyb10sICVbb2JqXSAgXG5cdCIgIC8vIHN0b3JlIG5ldyB2YWx1ZQorICAgICAgIiAgICAgICBibmUtIDFiICAgICAgICAgICAgICAgICAgICAgICAgIFxuXHQiCisKKyAgICAgICIyOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcblx0IgorICAgICAgICAgICAgICA6IFtyZXNdICAiPSZiIiAocmVzdWx0KQorICAgICAgICAgICAgICA6IFtvYmpdICAiYiIgICAocHRyKSwKKyAgICAgICAgICAgICAgICBbY21wXSAgImIiICAgKG9sZF92YWx1ZSksCisgICAgICAgICAgICAgICAgW3ZhbF0gICJiIiAgIChuZXdfdmFsdWUpLAorICAgICAgICAgICAgICAgIFt6ZXJvXSAiaSIgICAoMCkKKyAgICAgICAgICAgICAgOiAiY3IwIiwgImN0ciIpOworCisgIHJldHVybiByZXN1bHQ7Cit9CisKK2lubGluZSB2b2lkIE5vQmFycmllcl9TdG9yZSh2b2xhdGlsZSBBdG9taWMzMiogcHRyLCBBdG9taWMzMiB2YWx1ZSkgeworICAqcHRyID0gdmFsdWU7Cit9CisKK2lubGluZSB2b2lkIEFjcXVpcmVfU3RvcmUodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwgQXRvbWljMzIgdmFsdWUpIHsKKyAgYXNtIHZvbGF0aWxlICgKKyAgICAgICIgICAgICAgc3R3ICVbdmFsXSwgJVtvYmpdICAgICAgXG5cdCIKKyAgICAgICIgICAgICAgaXN5bmMgICAgICAgICAgICAgICAgICAgXG5cdCIKKyAgICAgICAgICAgICAgOiBbb2JqXSAiPW0iICgqcHRyKQorICAgICAgICAgICAgICA6IFt2YWxdICAiYiIgICh2YWx1ZSkpOworfQorCitpbmxpbmUgdm9pZCBSZWxlYXNlX1N0b3JlKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsIEF0b21pYzMyIHZhbHVlKSB7CisgIGFzbSB2b2xhdGlsZSAoCisgICAgICAiICAgICAgIGx3c3luYyAgICAgICAgICAgICAgICAgIFxuXHQiCisgICAgICAiICAgICAgIHN0dyAlW3ZhbF0sICVbb2JqXSAgICAgIFxuXHQiCisgICAgICAgICAgICAgIDogW29ial0gIj1tIiAoKnB0cikKKyAgICAgICAgICAgICAgOiBbdmFsXSAgImIiICAodmFsdWUpKTsKK30KKworaW5saW5lIEF0b21pYzMyIE5vQmFycmllcl9Mb2FkKHZvbGF0aWxlIGNvbnN0IEF0b21pYzMyKiBwdHIpIHsKKyAgcmV0dXJuICpwdHI7Cit9CisKK2lubGluZSBBdG9taWMzMiBBY3F1aXJlX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljMzIqIHB0cikgeworICBBdG9taWMzMiByZXN1bHQ7CisKKyAgYXNtIHZvbGF0aWxlICgKKyAgICAgICIxOiAgICAgbHd6ICVbcmVzXSwgJVtvYmpdICAgICAgICAgICAgICBcblx0IgorICAgICAgIiAgICAgICBjbXB3ICVbcmVzXSwgJVtyZXNdICAgICAgICAgICAgIFxuXHQiIC8vIGNyZWF0ZSBkYXRhCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZGVwZW5kZW5jeSBmb3IKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBsb2FkL2xvYWQgb3JkZXJpbmcKKyAgICAgICIgICAgICAgYm5lLSAxYiAgICAgICAgICAgICAgICAgICAgICAgICBcblx0IiAvLyBuZXZlciB0YWtlbgorCisgICAgICAiICAgICAgIGlzeW5jICAgICAgICAgICAgICAgICAgICAgICAgICAgXG5cdCIKKyAgICAgICAgICAgICAgOiBbcmVzXSAgIj1iIiAocmVzdWx0KQorICAgICAgICAgICAgICA6IFtvYmpdICAibSIgICgqcHRyKSwKKyAgICAgICAgICAgICAgICBbemVyb10gImkiICAoMCkKKyAgICAgICAgICAgICAgOiAiY3IwIiwgImN0ciIpOworCisgIHJldHVybiByZXN1bHQ7Cit9CisKK2lubGluZSBBdG9taWMzMiBSZWxlYXNlX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljMzIqIHB0cikgeworICBBdG9taWMzMiByZXN1bHQ7CisKKyAgYXNtIHZvbGF0aWxlICgKKyAgICAgICIgICAgICAgbHdzeW5jICAgICAgICAgICAgICAgICAgICAgICAgICBcblx0IgorCisgICAgICAiMTogICAgIGx3eiAlW3Jlc10sICVbb2JqXSAgICAgICAgICAgICAgXG5cdCIKKyAgICAgICIgICAgICAgY21wdyAlW3Jlc10sICVbcmVzXSAgICAgICAgICAgICBcblx0IiAvLyBjcmVhdGUgZGF0YQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRlcGVuZGVuY3kgZm9yCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbG9hZC9sb2FkIG9yZGVyaW5nCisgICAgICAiICAgICAgIGJuZS0gMWIgICAgICAgICAgICAgICAgICAgICAgICAgXG5cdCIgLy8gbmV2ZXIgdGFrZW4KKyAgICAgICAgICAgICAgOiBbcmVzXSAgIj1iIiAocmVzdWx0KQorICAgICAgICAgICAgICA6IFtvYmpdICAibSIgICgqcHRyKSwKKyAgICAgICAgICAgICAgICBbemVyb10gImkiICAoMCkKKyAgICAgICAgICAgICAgOiAiY3IwIiwgImN0ciIpOworCisgIHJldHVybiByZXN1bHQ7Cit9CisKKyNpZmRlZiBHT09HTEVfUFJPVE9CVUZfQVJDSF82NF9CSVQKK2lubGluZSBBdG9taWM2NCBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBuZXdfdmFsdWUpIHsKKyAgQXRvbWljNjQgcmVzdWx0OworCisgIGFzbSB2b2xhdGlsZSAoCisgICAgICAiMTogICAgIGxkYXJ4ICVbcmVzXSwgJVt6ZXJvXSwgJVtvYmpdICAgXG5cdCIgIC8vIGxvYWQgYW5kIHJlc2VydmUKKyAgICAgICIgICAgICAgY21wZCAlW2NtcF0sICVbcmVzXSAgICAgICAgICAgICBcblx0IiAgLy8gY29tcGFyZSB2YWx1ZXMKKyAgICAgICIgICAgICAgYm5lLSAyZiAgICAgICAgICAgICAgICAgICAgICAgICBcblx0IgorCisgICAgICAiICAgICAgIHN0ZGN4LiAlW3ZhbF0sICVbemVyb10sICVbb2JqXSAgXG5cdCIgIC8vIHN0b3JlIHRoZSBuZXcgdmFsdWUKKyAgICAgICIgICAgICAgYm5lLSAxYiAgICAgICAgICAgICAgICAgICAgICAgICBcblx0IgorICAgICAgIjI6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuXHQiCisgICAgICAgICAgICAgIDogW3Jlc10gICI9JmIiIChyZXN1bHQpCisgICAgICAgICAgICAgIDogW29ial0gICJiIiAgIChwdHIpLAorICAgICAgICAgICAgICAgIFtjbXBdICAiYiIgICAob2xkX3ZhbHVlKSwKKyAgICAgICAgICAgICAgICBbdmFsXSAgImIiICAgKG5ld192YWx1ZSksCisgICAgICAgICAgICAgICAgW3plcm9dICJpIiAgICgwKQorICAgICAgICAgICAgICA6ICJjcjAiLCAiY3RyIik7CisKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworaW5saW5lIEF0b21pYzY0IE5vQmFycmllcl9BdG9taWNFeGNoYW5nZSh2b2xhdGlsZSBBdG9taWM2NCogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBuZXdfdmFsdWUpIHsKKyAgQXRvbWljNjQgcmVzdWx0OworCisgIGFzbSB2b2xhdGlsZSAoCisgICAgICAiMTogICAgIGxkYXJ4ICVbcmVzXSwgJVt6ZXJvXSwgJVtvYmpdICAgICAgIFxuXHQiCisgICAgICAiICAgICAgIHN0ZGN4LiAlW3ZhbF0sICVbemVyb10sICVbb2JqXSAgICAgIFxuXHQiCisgICAgICAiICAgICAgIGJuZS0gMWIgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuXHQiCisgICAgICAgICAgICAgIDogW3Jlc10gICI9JmIiIChyZXN1bHQpCisgICAgICAgICAgICAgIDogW29ial0gICJiIiAgIChwdHIpLAorICAgICAgICAgICAgICAgIFt2YWxdICAiYiIgICAobmV3X3ZhbHVlKSwKKyAgICAgICAgICAgICAgICBbemVyb10gImkiICAgKDApCisgICAgICAgICAgICAgIDogImNyMCIsICJjdHIiKTsKKworICByZXR1cm4gcmVzdWx0OworfQorCitpbmxpbmUgQXRvbWljNjQgTm9CYXJyaWVyX0F0b21pY0luY3JlbWVudCh2b2xhdGlsZSBBdG9taWM2NCogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgaW5jcmVtZW50KSB7CisgIEF0b21pYzY0IHJlc3VsdDsKKworICBhc20gdm9sYXRpbGUgKAorICAgICAgIjE6ICAgICBsZGFyeCAlW3Jlc10sICVbemVyb10sICVbb2JqXSAgIFxuXHQiIC8vIGxvYWQgYW5kIHJlc2VydmUKKyAgICAgICIgICAgICAgYWRkICVbcmVzXSwgJVtyZXNdLCAlW3ZhbF0gICAgICBcblx0IiAvLyBhZGQgdGhlIG9wZXJhbmQKKyAgICAgICIgICAgICAgc3RkY3guICVbcmVzXSwgJVt6ZXJvXSwgJVtvYmpdICBcblx0IiAvLyBzdG9yZSBvbGQgdmFsdWUgaWYKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzdGlsbCByZXNlcnZlZAorCisgICAgICAiICAgICAgIGJuZS0gMWIgICAgICAgICAgICAgICAgICAgICAgICAgXG5cdCIKKyAgICAgICAgICAgICAgOiBbcmVzXSAgIj0mYiIgKHJlc3VsdCkKKyAgICAgICAgICAgICAgOiBbb2JqXSAgImIiICAgKHB0ciksCisgICAgICAgICAgICAgICAgW3ZhbF0gICJiIiAgIChpbmNyZW1lbnQpLAorICAgICAgICAgICAgICAgIFt6ZXJvXSAiaSIgICAoMCkKKyAgICAgICAgICAgICAgOiAiY3IwIiwgImN0ciIpOworCisgIHJldHVybiByZXN1bHQ7Cit9CisKK2lubGluZSBBdG9taWM2NCBCYXJyaWVyX0F0b21pY0luY3JlbWVudCh2b2xhdGlsZSBBdG9taWM2NCogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IGluY3JlbWVudCkgeworCisgIEF0b21pYzY0IHJlc3VsdDsKKworICBhc20gdm9sYXRpbGUgKAorICAgICAgIiAgICAgICBsd3N5bmMgICAgICAgICAgICAgICAgICAgICAgICAgIFxuXHQiCisKKyAgICAgICIxOiAgICAgbGRhcnggJVtyZXNdLCAlW3plcm9dLCAlW29ial0gICBcblx0IiAvLyBsb2FkIGFuZCByZXNlcnZlCisgICAgICAiICAgICAgIGFkZCAlW3Jlc10sICVbcmVzXSwgJVt2YWxdICAgICAgXG5cdCIgLy8gYWRkIHRoZSBvcGVyYW5kCisgICAgICAiICAgICAgIHN0ZGN4LiAlW3Jlc10sICVbemVyb10sICVbb2JqXSAgXG5cdCIgLy8gc3RvcmUgb2xkIHZhbHVlIGlmCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3RpbGwgcmVzZXJ2ZWQKKworICAgICAgIiAgICAgICBibmUtIDFiICAgICAgICAgICAgICAgICAgICAgICAgIFxuXHQiCisKKyAgICAgICIgICAgICAgaXN5bmMgICAgICAgICAgICAgICAgICAgICAgICAgICBcblx0IgorICAgICAgICAgICAgICA6IFtyZXNdICAiPSZiIiAocmVzdWx0KQorICAgICAgICAgICAgICA6IFtvYmpdICAiYiIgICAocHRyKSwKKyAgICAgICAgICAgICAgICBbdmFsXSAgImIiICAgKGluY3JlbWVudCksCisgICAgICAgICAgICAgICAgW3plcm9dICJpIiAgICgwKQorICAgICAgICAgICAgICA6ICJjcjAiLCAiY3RyIik7CisKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworaW5saW5lIEF0b21pYzY0IEFjcXVpcmVfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG5ld192YWx1ZSkgeworICBBdG9taWM2NCByZXN1bHQ7CisKKyAgYXNtIHZvbGF0aWxlICgKKyAgICAgICIxOiAgICAgbGRhcnggJVtyZXNdLCAlW3plcm9dLCAlW29ial0gICBcblx0IiAgLy8gbG9hZCBhbmQgcmVzZXJ2ZQorICAgICAgIiAgICAgICBjbXBkICVbY21wXSwgJVtyZXNdICAgICAgICAgICAgIFxuXHQiICAvLyBjb21wYXJlIHZhbHVlcworICAgICAgIiAgICAgICBibmUtIDJmICAgICAgICAgICAgICAgICAgICAgICAgIFxuXHQiCisKKyAgICAgICIgICAgICAgc3RkY3guICVbdmFsXSwgJVt6ZXJvXSwgJVtvYmpdICBcblx0IiAgLy8gc3RvcmUgdGhlIG5ldyB2YWx1ZQorICAgICAgIiAgICAgICBibmUtIDFiICAgICAgICAgICAgICAgICAgICAgICAgIFxuXHQiCisgICAgICAiICAgICAgIGlzeW5jICAgICAgICAgICAgICAgICAgICAgICAgICAgXG5cdCIKKyAgICAgICIyOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcblx0IgorICAgICAgICAgICAgICA6IFtyZXNdICAiPSZiIiAocmVzdWx0KQorICAgICAgICAgICAgICA6IFtvYmpdICAiYiIgICAocHRyKSwKKyAgICAgICAgICAgICAgICBbY21wXSAgImIiICAgKG9sZF92YWx1ZSksCisgICAgICAgICAgICAgICAgW3ZhbF0gICJiIiAgIChuZXdfdmFsdWUpLAorICAgICAgICAgICAgICAgIFt6ZXJvXSAiaSIgICAoMCkKKyAgICAgICAgICAgICAgOiAiY3IwIiwgImN0ciIpOworCisgIHJldHVybiByZXN1bHQ7Cit9CisKK2lubGluZSBBdG9taWM2NCBSZWxlYXNlX0NvbXBhcmVBbmRTd2FwKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBuZXdfdmFsdWUpIHsKKyAgQXRvbWljNjQgcmVzdWx0OworCisgIGFzbSB2b2xhdGlsZSAoCisgICAgICAiICAgICAgIGx3c3luYyAgICAgICAgICAgICAgICAgICAgICAgICAgXG5cdCIKKworICAgICAgIjE6ICAgICBsZGFyeCAlW3Jlc10sICVbemVyb10sICVbb2JqXSAgIFxuXHQiICAvLyBsb2FkIGFuZCByZXNlcnZlCisgICAgICAiICAgICAgIGNtcGQgJVtjbXBdLCAlW3Jlc10gICAgICAgICAgICAgXG5cdCIgIC8vIGNvbXBhcmUgdmFsdWVzCisgICAgICAiICAgICAgIGJuZS0gMmYgICAgICAgICAgICAgICAgICAgICAgICAgXG5cdCIKKworICAgICAgIiAgICAgICBzdGRjeC4gJVt2YWxdLCAlW3plcm9dLCAlW29ial0gIFxuXHQiICAvLyBzdG9yZSB0aGUgbmV3IHZhbHVlCisgICAgICAiICAgICAgIGJuZS0gMWIgICAgICAgICAgICAgICAgICAgICAgICAgXG5cdCIKKyAgICAgICIyOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcblx0IgorICAgICAgICAgICAgICA6IFtyZXNdICAiPSZiIiAocmVzdWx0KQorICAgICAgICAgICAgICA6IFtvYmpdICAiYiIgICAocHRyKSwKKyAgICAgICAgICAgICAgICBbY21wXSAgImIiICAgKG9sZF92YWx1ZSksCisgICAgICAgICAgICAgICAgW3ZhbF0gICJiIiAgIChuZXdfdmFsdWUpLAorICAgICAgICAgICAgICAgIFt6ZXJvXSAiaSIgICAoMCkKKyAgICAgICAgICAgICAgOiAiY3IwIiwgImN0ciIpOworCisgIHJldHVybiByZXN1bHQ7Cit9CisKK2lubGluZSB2b2lkIE5vQmFycmllcl9TdG9yZSh2b2xhdGlsZSBBdG9taWM2NCogcHRyLCBBdG9taWM2NCB2YWx1ZSkgeworICAqcHRyID0gdmFsdWU7Cit9CisKK2lubGluZSB2b2lkIEFjcXVpcmVfU3RvcmUodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwgQXRvbWljNjQgdmFsdWUpIHsKKyAgYXNtIHZvbGF0aWxlICgKKyAgICAgICIgICAgICAgc3RkICVbdmFsXSwgJVtvYmpdICAgICAgICAgIFxuXHQiCisgICAgICAiICAgICAgIGlzeW5jICAgICAgICAgICAgICAgICAgICAgICBcblx0IgorICAgICAgICAgICAgICA6IFtvYmpdICI9bSIgKCpwdHIpCisgICAgICAgICAgICAgIDogW3ZhbF0gImIiICAodmFsdWUpKTsKK30KKworaW5saW5lIHZvaWQgUmVsZWFzZV9TdG9yZSh2b2xhdGlsZSBBdG9taWM2NCogcHRyLCBBdG9taWM2NCB2YWx1ZSkgeworICBhc20gdm9sYXRpbGUgKAorICAgICAgIiAgICAgICBsd3N5bmMgICAgICAgICAgICAgICAgICAgICAgXG5cdCIKKyAgICAgICIgICAgICAgc3RkICVbdmFsXSwgJVtvYmpdICAgICAgICAgIFxuXHQiCisgICAgICAgICAgICAgIDogW29ial0gIj1tIiAoKnB0cikKKyAgICAgICAgICAgICAgOiBbdmFsXSAiYiIgICh2YWx1ZSkpOworfQorCitpbmxpbmUgQXRvbWljNjQgTm9CYXJyaWVyX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljNjQqIHB0cikgeworICByZXR1cm4gKnB0cjsKK30KKworaW5saW5lIEF0b21pYzY0IEFjcXVpcmVfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWM2NCogcHRyKSB7CisgIEF0b21pYzY0IHJlc3VsdDsKKworICBhc20gdm9sYXRpbGUgKAorICAgICAgIjE6ICAgICBsZCAlW3Jlc10sICVbb2JqXSAgICAgICAgICAgICAgICAgICBcblx0IgorICAgICAgIiAgICAgICBjbXBkICVbcmVzXSwgJVtyZXNdICAgICAgICAgICAgICAgICBcblx0IiAvLyBjcmVhdGUgZGF0YQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBkZXBlbmRlbmN5IGZvcgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBsb2FkL2xvYWQgb3JkZXJpbmcKKyAgICAgICIgICAgICAgYm5lLSAxYiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG5cdCIgLy8gbmV2ZXIgdGFrZW4KKworICAgICAgIiAgICAgICBpc3luYyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcblx0IgorICAgICAgICAgICAgICA6IFtyZXNdICAiPWIiIChyZXN1bHQpCisgICAgICAgICAgICAgIDogW29ial0gICJtIiAgKCpwdHIpLAorICAgICAgICAgICAgICAgIFt6ZXJvXSAiaSIgICgwKQorICAgICAgICAgICAgICA6ICJjcjAiLCAiY3RyIik7CisKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworaW5saW5lIEF0b21pYzY0IFJlbGVhc2VfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWM2NCogcHRyKSB7CisgIEF0b21pYzY0IHJlc3VsdDsKKworICBhc20gdm9sYXRpbGUgKAorICAgICAgIiAgICAgICBsd3N5bmMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcblx0IgorCisgICAgICAiMTogICAgIGxkICVbcmVzXSwgJVtvYmpdICAgICAgICAgICAgICAgICAgIFxuXHQiCisgICAgICAiICAgICAgIGNtcGQgJVtyZXNdLCAlW3Jlc10gICAgICAgICAgICAgICAgIFxuXHQiIC8vIGNyZWF0ZSBkYXRhCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRlcGVuZGVuY3kgZm9yCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGxvYWQvbG9hZCBvcmRlcmluZworICAgICAgIiAgICAgICBibmUtIDFiICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcblx0IiAvLyBuZXZlciB0YWtlbgorICAgICAgICAgICAgICA6IFtyZXNdICAiPWIiIChyZXN1bHQpCisgICAgICAgICAgICAgIDogW29ial0gICJtIiAgKCpwdHIpLAorICAgICAgICAgICAgICAgIFt6ZXJvXSAiaSIgICgwKQorICAgICAgICAgICAgICA6ICJjcjAiLCAiY3RyIik7CisKKyAgcmV0dXJuIHJlc3VsdDsKK30KKyNlbmRpZgorCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNPUFNfSU5URVJOQUxTX1NQQVJDX0dDQ19IXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX3NvbGFyaXMuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc19zb2xhcmlzLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDgwNTdlYwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc19zb2xhcmlzLmgKQEAgLTAsMCArMSwxODggQEAKKy8vIENvcHlyaWdodCAyMDE0IEdvb2dsZSBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBUaGlzIGZpbGUgaXMgYW4gaW50ZXJuYWwgYXRvbWljIGltcGxlbWVudGF0aW9uLCB1c2UgYXRvbWljb3BzLmggaW5zdGVhZC4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfQVRPTUlDT1BTX0lOVEVSTkFMU19TUEFSQ19HQ0NfSF8KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19JTlRFUk5BTFNfU1BBUkNfR0NDX0hfCisKKyNpbmNsdWRlIDxhdG9taWMuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKworaW5saW5lIEF0b21pYzMyIE5vQmFycmllcl9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG5ld192YWx1ZSkgeworICByZXR1cm4gKEF0b21pYzMyKWF0b21pY19jYXNfMzIoKHZvbGF0aWxlIHVpbnQzMl90KilwdHIsICh1aW50MzJfdClvbGRfdmFsdWUsICh1aW50MzJfdCluZXdfdmFsdWUpOworfQorCitpbmxpbmUgQXRvbWljMzIgTm9CYXJyaWVyX0F0b21pY0V4Y2hhbmdlKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG5ld192YWx1ZSkgeworICByZXR1cm4gKEF0b21pYzMyKWF0b21pY19zd2FwXzMyKCh2b2xhdGlsZSB1aW50MzJfdCopcHRyLCAodWludDMyX3QpbmV3X3ZhbHVlKTsKK30KKworaW5saW5lIEF0b21pYzMyIE5vQmFycmllcl9BdG9taWNJbmNyZW1lbnQodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIGluY3JlbWVudCkgeworICByZXR1cm4gKEF0b21pYzMyKWF0b21pY19hZGRfMzJfbnYoKHZvbGF0aWxlIHVpbnQzMl90KilwdHIsICh1aW50MzJfdClpbmNyZW1lbnQpOworfQorCitpbmxpbmUgdm9pZCBNZW1vcnlCYXJyaWVyKHZvaWQpIHsKKwltZW1iYXJfcHJvZHVjZXIoKTsKKwltZW1iYXJfY29uc3VtZXIoKTsKK30KKworaW5saW5lIEF0b21pYzMyIEJhcnJpZXJfQXRvbWljSW5jcmVtZW50KHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgaW5jcmVtZW50KSB7CisgIE1lbW9yeUJhcnJpZXIoKTsKKyAgQXRvbWljMzIgcmV0ID0gTm9CYXJyaWVyX0F0b21pY0luY3JlbWVudChwdHIsIGluY3JlbWVudCk7CisgIE1lbW9yeUJhcnJpZXIoKTsKKworICByZXR1cm4gcmV0OworfQorCitpbmxpbmUgQXRvbWljMzIgQWNxdWlyZV9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgbmV3X3ZhbHVlKSB7CisgIEF0b21pYzMyIHJldCA9IE5vQmFycmllcl9Db21wYXJlQW5kU3dhcChwdHIsIG9sZF92YWx1ZSwgbmV3X3ZhbHVlKTsKKyAgTWVtb3J5QmFycmllcigpOworCisgIHJldHVybiByZXQ7Cit9CisKK2lubGluZSBBdG9taWMzMiBSZWxlYXNlX0NvbXBhcmVBbmRTd2FwKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBuZXdfdmFsdWUpIHsKKyAgTWVtb3J5QmFycmllcigpOworICByZXR1cm4gTm9CYXJyaWVyX0NvbXBhcmVBbmRTd2FwKHB0ciwgb2xkX3ZhbHVlLCBuZXdfdmFsdWUpOworfQorCitpbmxpbmUgdm9pZCBOb0JhcnJpZXJfU3RvcmUodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwgQXRvbWljMzIgdmFsdWUpIHsKKyAgKnB0ciA9IHZhbHVlOworfQorCitpbmxpbmUgdm9pZCBBY3F1aXJlX1N0b3JlKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsIEF0b21pYzMyIHZhbHVlKSB7CisgICpwdHIgPSB2YWx1ZTsKKyAgbWVtYmFyX3Byb2R1Y2VyKCk7Cit9CisKK2lubGluZSB2b2lkIFJlbGVhc2VfU3RvcmUodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwgQXRvbWljMzIgdmFsdWUpIHsKKyAgbWVtYmFyX2NvbnN1bWVyKCk7CisgICpwdHIgPSB2YWx1ZTsKK30KKworaW5saW5lIEF0b21pYzMyIE5vQmFycmllcl9Mb2FkKHZvbGF0aWxlIGNvbnN0IEF0b21pYzMyKiBwdHIpIHsKKyAgcmV0dXJuICpwdHI7Cit9CisKK2lubGluZSBBdG9taWMzMiBBY3F1aXJlX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljMzIqIHB0cikgeworICBBdG9taWMzMiB2YWwgPSAqcHRyOworICBtZW1iYXJfY29uc3VtZXIoKTsKKyAgcmV0dXJuIHZhbDsKK30KKworaW5saW5lIEF0b21pYzMyIFJlbGVhc2VfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWMzMiogcHRyKSB7CisgIG1lbWJhcl9wcm9kdWNlcigpOworICByZXR1cm4gKnB0cjsKK30KKworI2lmZGVmIEdPT0dMRV9QUk9UT0JVRl9BUkNIXzY0X0JJVAoraW5saW5lIEF0b21pYzY0IE5vQmFycmllcl9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWM2NCogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG5ld192YWx1ZSkgeworICByZXR1cm4gYXRvbWljX2Nhc182NCgodm9sYXRpbGUgdWludDY0X3QqKXB0ciwgKHVpbnQ2NF90KW9sZF92YWx1ZSwgKHVpbnQ2NF90KW5ld192YWx1ZSk7Cit9CisKK2lubGluZSBBdG9taWM2NCBOb0JhcnJpZXJfQXRvbWljRXhjaGFuZ2Uodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwgQXRvbWljNjQgbmV3X3ZhbHVlKSB7CisgIHJldHVybiBhdG9taWNfc3dhcF82NCgodm9sYXRpbGUgdWludDY0X3QqKXB0ciwgKHVpbnQ2NF90KW5ld192YWx1ZSk7Cit9CisKK2lubGluZSBBdG9taWM2NCBOb0JhcnJpZXJfQXRvbWljSW5jcmVtZW50KHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsIEF0b21pYzY0IGluY3JlbWVudCkgeworICByZXR1cm4gYXRvbWljX2FkZF82NF9udigodm9sYXRpbGUgdWludDY0X3QqKXB0ciwgaW5jcmVtZW50KTsKK30KKworaW5saW5lIEF0b21pYzY0IEJhcnJpZXJfQXRvbWljSW5jcmVtZW50KHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsIEF0b21pYzY0IGluY3JlbWVudCkgeworICBNZW1vcnlCYXJyaWVyKCk7CisgIEF0b21pYzY0IHJldCA9IGF0b21pY19hZGRfNjRfbnYoKHZvbGF0aWxlIHVpbnQ2NF90KilwdHIsIGluY3JlbWVudCk7CisgIE1lbW9yeUJhcnJpZXIoKTsKKyAgcmV0dXJuIHJldDsKK30KKworaW5saW5lIEF0b21pYzY0IEFjcXVpcmVfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG5ld192YWx1ZSkgeworICBBdG9taWM2NCByZXQgPSBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAocHRyLCBvbGRfdmFsdWUsIG5ld192YWx1ZSk7CisgIE1lbW9yeUJhcnJpZXIoKTsKKyAgcmV0dXJuIHJldDsKK30KKworaW5saW5lIEF0b21pYzY0IFJlbGVhc2VfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG5ld192YWx1ZSkgeworICBNZW1vcnlCYXJyaWVyKCk7CisgIHJldHVybiBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAocHRyLCBvbGRfdmFsdWUsIG5ld192YWx1ZSk7Cit9CisKK2lubGluZSB2b2lkIE5vQmFycmllcl9TdG9yZSh2b2xhdGlsZSBBdG9taWM2NCogcHRyLCBBdG9taWM2NCB2YWx1ZSkgeworICAqcHRyID0gdmFsdWU7Cit9CisKK2lubGluZSB2b2lkIEFjcXVpcmVfU3RvcmUodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwgQXRvbWljNjQgdmFsdWUpIHsKKyAgKnB0ciA9IHZhbHVlOworICBtZW1iYXJfcHJvZHVjZXIoKTsKK30KKworaW5saW5lIHZvaWQgUmVsZWFzZV9TdG9yZSh2b2xhdGlsZSBBdG9taWM2NCogcHRyLCBBdG9taWM2NCB2YWx1ZSkgeworICBtZW1iYXJfY29uc3VtZXIoKTsKKyAgKnB0ciA9IHZhbHVlOworfQorCitpbmxpbmUgQXRvbWljNjQgTm9CYXJyaWVyX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljNjQqIHB0cikgeworICByZXR1cm4gKnB0cjsKK30KKworaW5saW5lIEF0b21pYzY0IEFjcXVpcmVfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWM2NCogcHRyKSB7CisgIEF0b21pYzY0IHJldCA9ICpwdHI7CisgIG1lbWJhcl9jb25zdW1lcigpOworICByZXR1cm4gcmV0OworfQorCitpbmxpbmUgQXRvbWljNjQgUmVsZWFzZV9Mb2FkKHZvbGF0aWxlIGNvbnN0IEF0b21pYzY0KiBwdHIpIHsKKyAgbWVtYmFyX3Byb2R1Y2VyKCk7CisgIHJldHVybiAqcHRyOworfQorI2VuZGlmCisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19JTlRFUk5BTFNfU1BBUkNfR0NDX0hfCisKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc190c2FuLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfdHNhbi5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBjOTAzNTQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfdHNhbi5oCkBAIC0wLDAgKzEsMjE5IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDEzIEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gVGhpcyBmaWxlIGlzIGFuIGludGVybmFsIGF0b21pYyBpbXBsZW1lbnRhdGlvbiBmb3IgY29tcGlsZXItYmFzZWQKKy8vIFRocmVhZFNhbml0aXplciAoaHR0cDovL2NsYW5nLmxsdm0ub3JnL2RvY3MvVGhyZWFkU2FuaXRpemVyLmh0bWwpLgorLy8gVXNlIGF0b21pY29wcy5oIGluc3RlYWQuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19JTlRFUk5BTFNfVFNBTl9IXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQVRPTUlDT1BTX0lOVEVSTkFMU19UU0FOX0hfCisKKyNkZWZpbmUgQVRPTUlDT1BTX0NPTVBJTEVSX0JBUlJJRVIoKSBfX2FzbV9fIF9fdm9sYXRpbGVfXygiIiA6IDogOiAibWVtb3J5IikKKworI2luY2x1ZGUgPHNhbml0aXplci90c2FuX2ludGVyZmFjZV9hdG9taWMuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKworaW5saW5lIEF0b21pYzMyIE5vQmFycmllcl9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWMzMiAqcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG5ld192YWx1ZSkgeworICBBdG9taWMzMiBjbXAgPSBvbGRfdmFsdWU7CisgIF9fdHNhbl9hdG9taWMzMl9jb21wYXJlX2V4Y2hhbmdlX3N0cm9uZyhwdHIsICZjbXAsIG5ld192YWx1ZSwKKyAgICAgIF9fdHNhbl9tZW1vcnlfb3JkZXJfcmVsYXhlZCwgX190c2FuX21lbW9yeV9vcmRlcl9yZWxheGVkKTsKKyAgcmV0dXJuIGNtcDsKK30KKworaW5saW5lIEF0b21pYzMyIE5vQmFycmllcl9BdG9taWNFeGNoYW5nZSh2b2xhdGlsZSBBdG9taWMzMiAqcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBuZXdfdmFsdWUpIHsKKyAgcmV0dXJuIF9fdHNhbl9hdG9taWMzMl9leGNoYW5nZShwdHIsIG5ld192YWx1ZSwKKyAgICAgIF9fdHNhbl9tZW1vcnlfb3JkZXJfcmVsYXhlZCk7Cit9CisKK2lubGluZSBBdG9taWMzMiBBY3F1aXJlX0F0b21pY0V4Y2hhbmdlKHZvbGF0aWxlIEF0b21pYzMyICpwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBuZXdfdmFsdWUpIHsKKyAgcmV0dXJuIF9fdHNhbl9hdG9taWMzMl9leGNoYW5nZShwdHIsIG5ld192YWx1ZSwKKyAgICAgIF9fdHNhbl9tZW1vcnlfb3JkZXJfYWNxdWlyZSk7Cit9CisKK2lubGluZSBBdG9taWMzMiBSZWxlYXNlX0F0b21pY0V4Y2hhbmdlKHZvbGF0aWxlIEF0b21pYzMyICpwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBuZXdfdmFsdWUpIHsKKyAgcmV0dXJuIF9fdHNhbl9hdG9taWMzMl9leGNoYW5nZShwdHIsIG5ld192YWx1ZSwKKyAgICAgIF9fdHNhbl9tZW1vcnlfb3JkZXJfcmVsZWFzZSk7Cit9CisKK2lubGluZSBBdG9taWMzMiBOb0JhcnJpZXJfQXRvbWljSW5jcmVtZW50KHZvbGF0aWxlIEF0b21pYzMyICpwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBpbmNyZW1lbnQpIHsKKyAgcmV0dXJuIGluY3JlbWVudCArIF9fdHNhbl9hdG9taWMzMl9mZXRjaF9hZGQocHRyLCBpbmNyZW1lbnQsCisgICAgICBfX3RzYW5fbWVtb3J5X29yZGVyX3JlbGF4ZWQpOworfQorCitpbmxpbmUgQXRvbWljMzIgQmFycmllcl9BdG9taWNJbmNyZW1lbnQodm9sYXRpbGUgQXRvbWljMzIgKnB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBpbmNyZW1lbnQpIHsKKyAgcmV0dXJuIGluY3JlbWVudCArIF9fdHNhbl9hdG9taWMzMl9mZXRjaF9hZGQocHRyLCBpbmNyZW1lbnQsCisgICAgICBfX3RzYW5fbWVtb3J5X29yZGVyX2FjcV9yZWwpOworfQorCitpbmxpbmUgQXRvbWljMzIgQWNxdWlyZV9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWMzMiAqcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgbmV3X3ZhbHVlKSB7CisgIEF0b21pYzMyIGNtcCA9IG9sZF92YWx1ZTsKKyAgX190c2FuX2F0b21pYzMyX2NvbXBhcmVfZXhjaGFuZ2Vfc3Ryb25nKHB0ciwgJmNtcCwgbmV3X3ZhbHVlLAorICAgICAgX190c2FuX21lbW9yeV9vcmRlcl9hY3F1aXJlLCBfX3RzYW5fbWVtb3J5X29yZGVyX2FjcXVpcmUpOworICByZXR1cm4gY21wOworfQorCitpbmxpbmUgQXRvbWljMzIgUmVsZWFzZV9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWMzMiAqcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgbmV3X3ZhbHVlKSB7CisgIEF0b21pYzMyIGNtcCA9IG9sZF92YWx1ZTsKKyAgX190c2FuX2F0b21pYzMyX2NvbXBhcmVfZXhjaGFuZ2Vfc3Ryb25nKHB0ciwgJmNtcCwgbmV3X3ZhbHVlLAorICAgICAgX190c2FuX21lbW9yeV9vcmRlcl9yZWxlYXNlLCBfX3RzYW5fbWVtb3J5X29yZGVyX3JlbGF4ZWQpOworICByZXR1cm4gY21wOworfQorCitpbmxpbmUgdm9pZCBOb0JhcnJpZXJfU3RvcmUodm9sYXRpbGUgQXRvbWljMzIgKnB0ciwgQXRvbWljMzIgdmFsdWUpIHsKKyAgX190c2FuX2F0b21pYzMyX3N0b3JlKHB0ciwgdmFsdWUsIF9fdHNhbl9tZW1vcnlfb3JkZXJfcmVsYXhlZCk7Cit9CisKK2lubGluZSB2b2lkIEFjcXVpcmVfU3RvcmUodm9sYXRpbGUgQXRvbWljMzIgKnB0ciwgQXRvbWljMzIgdmFsdWUpIHsKKyAgX190c2FuX2F0b21pYzMyX3N0b3JlKHB0ciwgdmFsdWUsIF9fdHNhbl9tZW1vcnlfb3JkZXJfcmVsYXhlZCk7CisgIF9fdHNhbl9hdG9taWNfdGhyZWFkX2ZlbmNlKF9fdHNhbl9tZW1vcnlfb3JkZXJfc2VxX2NzdCk7Cit9CisKK2lubGluZSB2b2lkIFJlbGVhc2VfU3RvcmUodm9sYXRpbGUgQXRvbWljMzIgKnB0ciwgQXRvbWljMzIgdmFsdWUpIHsKKyAgX190c2FuX2F0b21pYzMyX3N0b3JlKHB0ciwgdmFsdWUsIF9fdHNhbl9tZW1vcnlfb3JkZXJfcmVsZWFzZSk7Cit9CisKK2lubGluZSBBdG9taWMzMiBOb0JhcnJpZXJfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWMzMiAqcHRyKSB7CisgIHJldHVybiBfX3RzYW5fYXRvbWljMzJfbG9hZChwdHIsIF9fdHNhbl9tZW1vcnlfb3JkZXJfcmVsYXhlZCk7Cit9CisKK2lubGluZSBBdG9taWMzMiBBY3F1aXJlX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljMzIgKnB0cikgeworICByZXR1cm4gX190c2FuX2F0b21pYzMyX2xvYWQocHRyLCBfX3RzYW5fbWVtb3J5X29yZGVyX2FjcXVpcmUpOworfQorCitpbmxpbmUgQXRvbWljMzIgUmVsZWFzZV9Mb2FkKHZvbGF0aWxlIGNvbnN0IEF0b21pYzMyICpwdHIpIHsKKyAgX190c2FuX2F0b21pY190aHJlYWRfZmVuY2UoX190c2FuX21lbW9yeV9vcmRlcl9zZXFfY3N0KTsKKyAgcmV0dXJuIF9fdHNhbl9hdG9taWMzMl9sb2FkKHB0ciwgX190c2FuX21lbW9yeV9vcmRlcl9yZWxheGVkKTsKK30KKworaW5saW5lIEF0b21pYzY0IE5vQmFycmllcl9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWM2NCAqcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG5ld192YWx1ZSkgeworICBBdG9taWM2NCBjbXAgPSBvbGRfdmFsdWU7CisgIF9fdHNhbl9hdG9taWM2NF9jb21wYXJlX2V4Y2hhbmdlX3N0cm9uZyhwdHIsICZjbXAsIG5ld192YWx1ZSwKKyAgICAgIF9fdHNhbl9tZW1vcnlfb3JkZXJfcmVsYXhlZCwgX190c2FuX21lbW9yeV9vcmRlcl9yZWxheGVkKTsKKyAgcmV0dXJuIGNtcDsKK30KKworaW5saW5lIEF0b21pYzY0IE5vQmFycmllcl9BdG9taWNFeGNoYW5nZSh2b2xhdGlsZSBBdG9taWM2NCAqcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBuZXdfdmFsdWUpIHsKKyAgcmV0dXJuIF9fdHNhbl9hdG9taWM2NF9leGNoYW5nZShwdHIsIG5ld192YWx1ZSwgX190c2FuX21lbW9yeV9vcmRlcl9yZWxheGVkKTsKK30KKworaW5saW5lIEF0b21pYzY0IEFjcXVpcmVfQXRvbWljRXhjaGFuZ2Uodm9sYXRpbGUgQXRvbWljNjQgKnB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG5ld192YWx1ZSkgeworICByZXR1cm4gX190c2FuX2F0b21pYzY0X2V4Y2hhbmdlKHB0ciwgbmV3X3ZhbHVlLCBfX3RzYW5fbWVtb3J5X29yZGVyX2FjcXVpcmUpOworfQorCitpbmxpbmUgQXRvbWljNjQgUmVsZWFzZV9BdG9taWNFeGNoYW5nZSh2b2xhdGlsZSBBdG9taWM2NCAqcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgbmV3X3ZhbHVlKSB7CisgIHJldHVybiBfX3RzYW5fYXRvbWljNjRfZXhjaGFuZ2UocHRyLCBuZXdfdmFsdWUsIF9fdHNhbl9tZW1vcnlfb3JkZXJfcmVsZWFzZSk7Cit9CisKK2lubGluZSBBdG9taWM2NCBOb0JhcnJpZXJfQXRvbWljSW5jcmVtZW50KHZvbGF0aWxlIEF0b21pYzY0ICpwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBpbmNyZW1lbnQpIHsKKyAgcmV0dXJuIGluY3JlbWVudCArIF9fdHNhbl9hdG9taWM2NF9mZXRjaF9hZGQocHRyLCBpbmNyZW1lbnQsCisgICAgICBfX3RzYW5fbWVtb3J5X29yZGVyX3JlbGF4ZWQpOworfQorCitpbmxpbmUgQXRvbWljNjQgQmFycmllcl9BdG9taWNJbmNyZW1lbnQodm9sYXRpbGUgQXRvbWljNjQgKnB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBpbmNyZW1lbnQpIHsKKyAgcmV0dXJuIGluY3JlbWVudCArIF9fdHNhbl9hdG9taWM2NF9mZXRjaF9hZGQocHRyLCBpbmNyZW1lbnQsCisgICAgICBfX3RzYW5fbWVtb3J5X29yZGVyX2FjcV9yZWwpOworfQorCitpbmxpbmUgdm9pZCBOb0JhcnJpZXJfU3RvcmUodm9sYXRpbGUgQXRvbWljNjQgKnB0ciwgQXRvbWljNjQgdmFsdWUpIHsKKyAgX190c2FuX2F0b21pYzY0X3N0b3JlKHB0ciwgdmFsdWUsIF9fdHNhbl9tZW1vcnlfb3JkZXJfcmVsYXhlZCk7Cit9CisKK2lubGluZSB2b2lkIEFjcXVpcmVfU3RvcmUodm9sYXRpbGUgQXRvbWljNjQgKnB0ciwgQXRvbWljNjQgdmFsdWUpIHsKKyAgX190c2FuX2F0b21pYzY0X3N0b3JlKHB0ciwgdmFsdWUsIF9fdHNhbl9tZW1vcnlfb3JkZXJfcmVsYXhlZCk7CisgIF9fdHNhbl9hdG9taWNfdGhyZWFkX2ZlbmNlKF9fdHNhbl9tZW1vcnlfb3JkZXJfc2VxX2NzdCk7Cit9CisKK2lubGluZSB2b2lkIFJlbGVhc2VfU3RvcmUodm9sYXRpbGUgQXRvbWljNjQgKnB0ciwgQXRvbWljNjQgdmFsdWUpIHsKKyAgX190c2FuX2F0b21pYzY0X3N0b3JlKHB0ciwgdmFsdWUsIF9fdHNhbl9tZW1vcnlfb3JkZXJfcmVsZWFzZSk7Cit9CisKK2lubGluZSBBdG9taWM2NCBOb0JhcnJpZXJfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWM2NCAqcHRyKSB7CisgIHJldHVybiBfX3RzYW5fYXRvbWljNjRfbG9hZChwdHIsIF9fdHNhbl9tZW1vcnlfb3JkZXJfcmVsYXhlZCk7Cit9CisKK2lubGluZSBBdG9taWM2NCBBY3F1aXJlX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljNjQgKnB0cikgeworICByZXR1cm4gX190c2FuX2F0b21pYzY0X2xvYWQocHRyLCBfX3RzYW5fbWVtb3J5X29yZGVyX2FjcXVpcmUpOworfQorCitpbmxpbmUgQXRvbWljNjQgUmVsZWFzZV9Mb2FkKHZvbGF0aWxlIGNvbnN0IEF0b21pYzY0ICpwdHIpIHsKKyAgX190c2FuX2F0b21pY190aHJlYWRfZmVuY2UoX190c2FuX21lbW9yeV9vcmRlcl9zZXFfY3N0KTsKKyAgcmV0dXJuIF9fdHNhbl9hdG9taWM2NF9sb2FkKHB0ciwgX190c2FuX21lbW9yeV9vcmRlcl9yZWxheGVkKTsKK30KKworaW5saW5lIEF0b21pYzY0IEFjcXVpcmVfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljNjQgKnB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG5ld192YWx1ZSkgeworICBBdG9taWM2NCBjbXAgPSBvbGRfdmFsdWU7CisgIF9fdHNhbl9hdG9taWM2NF9jb21wYXJlX2V4Y2hhbmdlX3N0cm9uZyhwdHIsICZjbXAsIG5ld192YWx1ZSwKKyAgICAgIF9fdHNhbl9tZW1vcnlfb3JkZXJfYWNxdWlyZSwgX190c2FuX21lbW9yeV9vcmRlcl9hY3F1aXJlKTsKKyAgcmV0dXJuIGNtcDsKK30KKworaW5saW5lIEF0b21pYzY0IFJlbGVhc2VfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljNjQgKnB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG5ld192YWx1ZSkgeworICBBdG9taWM2NCBjbXAgPSBvbGRfdmFsdWU7CisgIF9fdHNhbl9hdG9taWM2NF9jb21wYXJlX2V4Y2hhbmdlX3N0cm9uZyhwdHIsICZjbXAsIG5ld192YWx1ZSwKKyAgICAgIF9fdHNhbl9tZW1vcnlfb3JkZXJfcmVsZWFzZSwgX190c2FuX21lbW9yeV9vcmRlcl9yZWxheGVkKTsKKyAgcmV0dXJuIGNtcDsKK30KKworaW5saW5lIHZvaWQgTWVtb3J5QmFycmllcigpIHsKKyAgX190c2FuX2F0b21pY190aHJlYWRfZmVuY2UoX190c2FuX21lbW9yeV9vcmRlcl9zZXFfY3N0KTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI3VuZGVmIEFUT01JQ09QU19DT01QSUxFUl9CQVJSSUVSCisKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19JTlRFUk5BTFNfVFNBTl9IXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX3g4Nl9nY2MuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfeDg2X2djYy5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41M2M5ZWFlCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX3g4Nl9nY2MuY2MKQEAgLTAsMCArMSwxMzcgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMTIgR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBUaGlzIG1vZHVsZSBnZXRzIGVub3VnaCBDUFUgaW5mb3JtYXRpb24gdG8gb3B0aW1pemUgdGhlCisvLyBhdG9taWNvcHMgbW9kdWxlIG9uIHg4Ni4KKworI2luY2x1ZGUgPGNzdHJpbmc+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzLmg+CisKKy8vIFRoaXMgZmlsZSBvbmx5IG1ha2VzIHNlbnNlIHdpdGggYXRvbWljb3BzX2ludGVybmFsc194ODZfZ2NjLmggLS0gaXQKKy8vIGRlcGVuZHMgb24gc3RydWN0cyB0aGF0IGFyZSBkZWZpbmVkIGluIHRoYXQgZmlsZS4gIElmIGF0b21pY29wcy5oCisvLyBkb2Vzbid0IHN1Yi1pbmNsdWRlIHRoYXQgZmlsZSwgdGhlbiB3ZSBhcmVuJ3QgbmVlZGVkLCBhbmQgc2hvdWxkbid0CisvLyB0cnkgdG8gZG8gYW55dGhpbmcuCisjaWZkZWYgR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19JTlRFUk5BTFNfWDg2X0dDQ19IXworCisvLyBJbmxpbmUgY3B1aWQgaW5zdHJ1Y3Rpb24uICBJbiBQSUMgY29tcGlsYXRpb25zLCAlZWJ4IGNvbnRhaW5zIHRoZSBhZGRyZXNzCisvLyBvZiB0aGUgZ2xvYmFsIG9mZnNldCB0YWJsZS4gIFRvIGF2b2lkIGJyZWFraW5nIHN1Y2ggZXhlY3V0YWJsZXMsIHRoaXMgY29kZQorLy8gbXVzdCBwcmVzZXJ2ZSB0aGF0IHJlZ2lzdGVyJ3MgdmFsdWUgYWNyb3NzIGNwdWlkIGluc3RydWN0aW9ucy4KKyNpZiBkZWZpbmVkKF9faTM4Nl9fKQorI2RlZmluZSBjcHVpZChhLCBiLCBjLCBkLCBpbnApIFwKKyAgYXNtKCJtb3YgJSVlYngsICUlZWRpXG4iICAgICBcCisgICAgICAiY3B1aWRcbiIgICAgICAgICAgICAgICAgXAorICAgICAgInhjaGcgJSVlZGksICUlZWJ4XG4iICAgIFwKKyAgICAgIDogIj1hIiAoYSksICI9RCIgKGIpLCAiPWMiIChjKSwgIj1kIiAoZCkgOiAiYSIgKGlucCkpCisjZWxpZiBkZWZpbmVkKF9feDg2XzY0X18pCisjZGVmaW5lIGNwdWlkKGEsIGIsIGMsIGQsIGlucCkgXAorICBhc20oIm1vdiAlJXJieCwgJSVyZGlcbiIgICAgIFwKKyAgICAgICJjcHVpZFxuIiAgICAgICAgICAgICAgICBcCisgICAgICAieGNoZyAlJXJkaSwgJSVyYnhcbiIgICAgXAorICAgICAgOiAiPWEiIChhKSwgIj1EIiAoYiksICI9YyIgKGMpLCAiPWQiIChkKSA6ICJhIiAoaW5wKSkKKyNlbmRpZgorCisjaWYgZGVmaW5lZChjcHVpZCkgICAgICAgIC8vIGluaXRpYWxpemUgdGhlIHN0cnVjdCBvbmx5IG9uIHg4NgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW50ZXJuYWwgeworCisvLyBTZXQgdGhlIGZsYWdzIHNvIHRoYXQgY29kZSB3aWxsIHJ1biBjb3JyZWN0bHkgYW5kIGNvbnNlcnZhdGl2ZWx5LCBzbyBldmVuCisvLyBpZiB3ZSBoYXZlbid0IGJlZW4gaW5pdGlhbGl6ZWQgeWV0LCB3ZSdyZSBwcm9iYWJseSBzaW5nbGUgdGhyZWFkZWQsIGFuZCBvdXIKKy8vIGRlZmF1bHQgdmFsdWVzIHNob3VsZCBob3BlZnVsbHkgYmUgcHJldHR5IHNhZmUuCitzdHJ1Y3QgQXRvbWljT3BzX3g4NkNQVUZlYXR1cmVTdHJ1Y3QgQXRvbWljT3BzX0ludGVybmFseDg2Q1BVRmVhdHVyZXMgPSB7CisgIGZhbHNlLCAgICAgICAgICAvLyBidWcgY2FuJ3QgZXhpc3QgYmVmb3JlIHByb2Nlc3Mgc3Bhd25zIG11bHRpcGxlIHRocmVhZHMKKyAgZmFsc2UsICAgICAgICAgIC8vIG5vIFNTRTIKK307CisKK25hbWVzcGFjZSB7CisKKy8vIEluaXRpYWxpemUgdGhlIEF0b21pY09wc19JbnRlcm5hbHg4NkNQVUZlYXR1cmVzIHN0cnVjdC4KK3ZvaWQgQXRvbWljT3BzX0ludGVybmFseDg2Q1BVRmVhdHVyZXNJbml0KCkgeworICB1aW50MzJfdCBlYXg7CisgIHVpbnQzMl90IGVieDsKKyAgdWludDMyX3QgZWN4OworICB1aW50MzJfdCBlZHg7CisKKyAgLy8gR2V0IHZlbmRvciBzdHJpbmcgKGlzc3VlIENQVUlEIHdpdGggZWF4ID0gMCkKKyAgY3B1aWQoZWF4LCBlYngsIGVjeCwgZWR4LCAwKTsKKyAgY2hhciB2ZW5kb3JbMTNdOworICBtZW1jcHkodmVuZG9yLCAmZWJ4LCA0KTsKKyAgbWVtY3B5KHZlbmRvciArIDQsICZlZHgsIDQpOworICBtZW1jcHkodmVuZG9yICsgOCwgJmVjeCwgNCk7CisgIHZlbmRvclsxMl0gPSAwOworCisgIC8vIGdldCBmZWF0dXJlIGZsYWdzIGluIGVjeC9lZHgsIGFuZCBmYW1pbHkvbW9kZWwgaW4gZWF4CisgIGNwdWlkKGVheCwgZWJ4LCBlY3gsIGVkeCwgMSk7CisKKyAgaW50IGZhbWlseSA9IChlYXggPj4gOCkgJiAweGY7ICAgICAgICAvLyBmYW1pbHkgYW5kIG1vZGVsIGZpZWxkcworICBpbnQgbW9kZWwgPSAoZWF4ID4+IDQpICYgMHhmOworICBpZiAoZmFtaWx5ID09IDB4ZikgeyAgICAgICAgICAgICAgICAgIC8vIHVzZSBleHRlbmRlZCBmYW1pbHkgYW5kIG1vZGVsIGZpZWxkcworICAgIGZhbWlseSArPSAoZWF4ID4+IDIwKSAmIDB4ZmY7CisgICAgbW9kZWwgKz0gKChlYXggPj4gMTYpICYgMHhmKSA8PCA0OworICB9CisKKyAgLy8gT3B0ZXJvbiBSZXYgRSBoYXMgYSBidWcgaW4gd2hpY2ggb24gdmVyeSByYXJlIG9jY2FzaW9ucyBhIGxvY2tlZAorICAvLyBpbnN0cnVjdGlvbiBkb2Vzbid0IGFjdCBhcyBhIHJlYWQtYWNxdWlyZSBiYXJyaWVyIGlmIGZvbGxvd2VkIGJ5IGEKKyAgLy8gbm9uLWxvY2tlZCByZWFkLW1vZGlmeS13cml0ZSBpbnN0cnVjdGlvbi4gIFJldiBGIGhhcyB0aGlzIGJ1ZyBpbgorICAvLyBwcmUtcmVsZWFzZSB2ZXJzaW9ucywgYnV0IG5vdCBpbiB2ZXJzaW9ucyByZWxlYXNlZCB0byBjdXN0b21lcnMsCisgIC8vIHNvIHdlIHRlc3Qgb25seSBmb3IgUmV2IEUsIHdoaWNoIGlzIGZhbWlseSAxNSwgbW9kZWwgMzIuLjYzIGluY2x1c2l2ZS4KKyAgaWYgKHN0cmNtcCh2ZW5kb3IsICJBdXRoZW50aWNBTUQiKSA9PSAwICYmICAgICAgIC8vIEFNRAorICAgICAgZmFtaWx5ID09IDE1ICYmCisgICAgICAzMiA8PSBtb2RlbCAmJiBtb2RlbCA8PSA2MykgeworICAgIEF0b21pY09wc19JbnRlcm5hbHg4NkNQVUZlYXR1cmVzLmhhc19hbWRfbG9ja19tYl9idWcgPSB0cnVlOworICB9IGVsc2UgeworICAgIEF0b21pY09wc19JbnRlcm5hbHg4NkNQVUZlYXR1cmVzLmhhc19hbWRfbG9ja19tYl9idWcgPSBmYWxzZTsKKyAgfQorCisgIC8vIGVkeCBiaXQgMjYgaXMgU1NFMiB3aGljaCB3ZSB1c2UgdG8gdGVsbCB1c2Ugd2hldGhlciB3ZSBjYW4gdXNlIG1mZW5jZQorICBBdG9taWNPcHNfSW50ZXJuYWx4ODZDUFVGZWF0dXJlcy5oYXNfc3NlMiA9ICgoZWR4ID4+IDI2KSAmIDEpOworfQorCitjbGFzcyBBdG9taWNPcHN4ODZJbml0aWFsaXplciB7CisgcHVibGljOgorICBBdG9taWNPcHN4ODZJbml0aWFsaXplcigpIHsKKyAgICBBdG9taWNPcHNfSW50ZXJuYWx4ODZDUFVGZWF0dXJlc0luaXQoKTsKKyAgfQorfTsKKworLy8gQSBnbG9iYWwgdG8gZ2V0IHVzZSBpbml0aWFsaXplZCBvbiBzdGFydHVwIHZpYSBzdGF0aWMgaW5pdGlhbGl6YXRpb24gOi8KK0F0b21pY09wc3g4NkluaXRpYWxpemVyIGdfaW5pdGVyOworCit9ICAvLyBuYW1lc3BhY2UKKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI2VuZGlmICAvLyBfX2kzODZfXworCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNPUFNfSU5URVJOQUxTX1g4Nl9HQ0NfSF8KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc194ODZfZ2NjLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfeDg2X2djYy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVkY2NjNTkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wc19pbnRlcm5hbHNfeDg2X2djYy5oCkBAIC0wLDAgKzEsMjkzIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDEyIEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gVGhpcyBmaWxlIGlzIGFuIGludGVybmFsIGF0b21pYyBpbXBsZW1lbnRhdGlvbiwgdXNlIGF0b21pY29wcy5oIGluc3RlYWQuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19JTlRFUk5BTFNfWDg2X0dDQ19IXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQVRPTUlDT1BTX0lOVEVSTkFMU19YODZfR0NDX0hfCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKKy8vIFRoaXMgc3RydWN0IGlzIG5vdCBwYXJ0IG9mIHRoZSBwdWJsaWMgQVBJIG9mIHRoaXMgbW9kdWxlOyBjbGllbnRzIG1heSBub3QKKy8vIHVzZSBpdC4KKy8vIEZlYXR1cmVzIG9mIHRoaXMgeDg2LiAgVmFsdWVzIG1heSBub3QgYmUgY29ycmVjdCBiZWZvcmUgbWFpbigpIGlzIHJ1biwKKy8vIGJ1dCBhcmUgc2V0IGNvbnNlcnZhdGl2ZWx5Lgorc3RydWN0IEF0b21pY09wc194ODZDUFVGZWF0dXJlU3RydWN0IHsKKyAgYm9vbCBoYXNfYW1kX2xvY2tfbWJfYnVnOyAgLy8gUHJvY2Vzc29yIGhhcyBBTUQgbWVtb3J5LWJhcnJpZXIgYnVnOyBkbyBsZmVuY2UKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYWZ0ZXIgYWNxdWlyZSBjb21wYXJlLWFuZC1zd2FwLgorICBib29sIGhhc19zc2UyOyAgICAgICAgICAgICAvLyBQcm9jZXNzb3IgaGFzIFNTRTIuCit9OworZXh0ZXJuIHN0cnVjdCBBdG9taWNPcHNfeDg2Q1BVRmVhdHVyZVN0cnVjdCBBdG9taWNPcHNfSW50ZXJuYWx4ODZDUFVGZWF0dXJlczsKKworI2RlZmluZSBBVE9NSUNPUFNfQ09NUElMRVJfQkFSUklFUigpIF9fYXNtX18gX192b2xhdGlsZV9fKCIiIDogOiA6ICJtZW1vcnkiKQorCisvLyAzMi1iaXQgbG93LWxldmVsIG9wZXJhdGlvbnMgb24gYW55IHBsYXRmb3JtLgorCitpbmxpbmUgQXRvbWljMzIgTm9CYXJyaWVyX0NvbXBhcmVBbmRTd2FwKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgbmV3X3ZhbHVlKSB7CisgIEF0b21pYzMyIHByZXY7CisgIF9fYXNtX18gX192b2xhdGlsZV9fKCJsb2NrOyBjbXB4Y2hnbCAlMSwlMiIKKyAgICAgICAgICAgICAgICAgICAgICAgOiAiPWEiIChwcmV2KQorICAgICAgICAgICAgICAgICAgICAgICA6ICJxIiAobmV3X3ZhbHVlKSwgIm0iICgqcHRyKSwgIjAiIChvbGRfdmFsdWUpCisgICAgICAgICAgICAgICAgICAgICAgIDogIm1lbW9yeSIpOworICByZXR1cm4gcHJldjsKK30KKworaW5saW5lIEF0b21pYzMyIE5vQmFycmllcl9BdG9taWNFeGNoYW5nZSh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBuZXdfdmFsdWUpIHsKKyAgX19hc21fXyBfX3ZvbGF0aWxlX18oInhjaGdsICUxLCUwIiAgLy8gVGhlIGxvY2sgcHJlZml4IGlzIGltcGxpY2l0IGZvciB4Y2hnLgorICAgICAgICAgICAgICAgICAgICAgICA6ICI9ciIgKG5ld192YWx1ZSkKKyAgICAgICAgICAgICAgICAgICAgICAgOiAibSIgKCpwdHIpLCAiMCIgKG5ld192YWx1ZSkKKyAgICAgICAgICAgICAgICAgICAgICAgOiAibWVtb3J5Iik7CisgIHJldHVybiBuZXdfdmFsdWU7ICAvLyBOb3cgaXQncyB0aGUgcHJldmlvdXMgdmFsdWUuCit9CisKK2lubGluZSBBdG9taWMzMiBOb0JhcnJpZXJfQXRvbWljSW5jcmVtZW50KHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBpbmNyZW1lbnQpIHsKKyAgQXRvbWljMzIgdGVtcCA9IGluY3JlbWVudDsKKyAgX19hc21fXyBfX3ZvbGF0aWxlX18oImxvY2s7IHhhZGRsICUwLCUxIgorICAgICAgICAgICAgICAgICAgICAgICA6ICIrciIgKHRlbXApLCAiK20iICgqcHRyKQorICAgICAgICAgICAgICAgICAgICAgICA6IDogIm1lbW9yeSIpOworICAvLyB0ZW1wIG5vdyBob2xkcyB0aGUgb2xkIHZhbHVlIG9mICpwdHIKKyAgcmV0dXJuIHRlbXAgKyBpbmNyZW1lbnQ7Cit9CisKK2lubGluZSBBdG9taWMzMiBCYXJyaWVyX0F0b21pY0luY3JlbWVudCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIGluY3JlbWVudCkgeworICBBdG9taWMzMiB0ZW1wID0gaW5jcmVtZW50OworICBfX2FzbV9fIF9fdm9sYXRpbGVfXygibG9jazsgeGFkZGwgJTAsJTEiCisgICAgICAgICAgICAgICAgICAgICAgIDogIityIiAodGVtcCksICIrbSIgKCpwdHIpCisgICAgICAgICAgICAgICAgICAgICAgIDogOiAibWVtb3J5Iik7CisgIC8vIHRlbXAgbm93IGhvbGRzIHRoZSBvbGQgdmFsdWUgb2YgKnB0cgorICBpZiAoQXRvbWljT3BzX0ludGVybmFseDg2Q1BVRmVhdHVyZXMuaGFzX2FtZF9sb2NrX21iX2J1ZykgeworICAgIF9fYXNtX18gX192b2xhdGlsZV9fKCJsZmVuY2UiIDogOiA6ICJtZW1vcnkiKTsKKyAgfQorICByZXR1cm4gdGVtcCArIGluY3JlbWVudDsKK30KKworaW5saW5lIEF0b21pYzMyIEFjcXVpcmVfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG5ld192YWx1ZSkgeworICBBdG9taWMzMiB4ID0gTm9CYXJyaWVyX0NvbXBhcmVBbmRTd2FwKHB0ciwgb2xkX3ZhbHVlLCBuZXdfdmFsdWUpOworICBpZiAoQXRvbWljT3BzX0ludGVybmFseDg2Q1BVRmVhdHVyZXMuaGFzX2FtZF9sb2NrX21iX2J1ZykgeworICAgIF9fYXNtX18gX192b2xhdGlsZV9fKCJsZmVuY2UiIDogOiA6ICJtZW1vcnkiKTsKKyAgfQorICByZXR1cm4geDsKK30KKworaW5saW5lIEF0b21pYzMyIFJlbGVhc2VfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG5ld192YWx1ZSkgeworICByZXR1cm4gTm9CYXJyaWVyX0NvbXBhcmVBbmRTd2FwKHB0ciwgb2xkX3ZhbHVlLCBuZXdfdmFsdWUpOworfQorCitpbmxpbmUgdm9pZCBOb0JhcnJpZXJfU3RvcmUodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwgQXRvbWljMzIgdmFsdWUpIHsKKyAgKnB0ciA9IHZhbHVlOworfQorCisjaWYgZGVmaW5lZChfX3g4Nl82NF9fKQorCisvLyA2NC1iaXQgaW1wbGVtZW50YXRpb25zIG9mIG1lbW9yeSBiYXJyaWVyIGNhbiBiZSBzaW1wbGVyLCBiZWNhdXNlIGl0CisvLyAibWZlbmNlIiBpcyBndWFyYW50ZWVkIHRvIGV4aXN0LgoraW5saW5lIHZvaWQgTWVtb3J5QmFycmllcigpIHsKKyAgX19hc21fXyBfX3ZvbGF0aWxlX18oIm1mZW5jZSIgOiA6IDogIm1lbW9yeSIpOworfQorCitpbmxpbmUgdm9pZCBBY3F1aXJlX1N0b3JlKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsIEF0b21pYzMyIHZhbHVlKSB7CisgICpwdHIgPSB2YWx1ZTsKKyAgTWVtb3J5QmFycmllcigpOworfQorCisjZWxzZQorCitpbmxpbmUgdm9pZCBNZW1vcnlCYXJyaWVyKCkgeworICBpZiAoQXRvbWljT3BzX0ludGVybmFseDg2Q1BVRmVhdHVyZXMuaGFzX3NzZTIpIHsKKyAgICBfX2FzbV9fIF9fdm9sYXRpbGVfXygibWZlbmNlIiA6IDogOiAibWVtb3J5Iik7CisgIH0gZWxzZSB7ICAvLyBtZmVuY2UgaXMgZmFzdGVyIGJ1dCBub3QgcHJlc2VudCBvbiBQSUlJCisgICAgQXRvbWljMzIgeCA9IDA7CisgICAgTm9CYXJyaWVyX0F0b21pY0V4Y2hhbmdlKCZ4LCAwKTsgIC8vIGFjdHMgYXMgYSBiYXJyaWVyIG9uIFBJSUkKKyAgfQorfQorCitpbmxpbmUgdm9pZCBBY3F1aXJlX1N0b3JlKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsIEF0b21pYzMyIHZhbHVlKSB7CisgIGlmIChBdG9taWNPcHNfSW50ZXJuYWx4ODZDUFVGZWF0dXJlcy5oYXNfc3NlMikgeworICAgICpwdHIgPSB2YWx1ZTsKKyAgICBfX2FzbV9fIF9fdm9sYXRpbGVfXygibWZlbmNlIiA6IDogOiAibWVtb3J5Iik7CisgIH0gZWxzZSB7CisgICAgTm9CYXJyaWVyX0F0b21pY0V4Y2hhbmdlKHB0ciwgdmFsdWUpOworICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhY3RzIGFzIGEgYmFycmllciBvbiBQSUlJCisgIH0KK30KKyNlbmRpZgorCitpbmxpbmUgdm9pZCBSZWxlYXNlX1N0b3JlKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsIEF0b21pYzMyIHZhbHVlKSB7CisgIEFUT01JQ09QU19DT01QSUxFUl9CQVJSSUVSKCk7CisgICpwdHIgPSB2YWx1ZTsgIC8vIEFuIHg4NiBzdG9yZSBhY3RzIGFzIGEgcmVsZWFzZSBiYXJyaWVyLgorICAvLyBTZWUgY29tbWVudHMgaW4gQXRvbWljNjQgdmVyc2lvbiBvZiBSZWxlYXNlX1N0b3JlKCksIGJlbG93LgorfQorCitpbmxpbmUgQXRvbWljMzIgTm9CYXJyaWVyX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljMzIqIHB0cikgeworICByZXR1cm4gKnB0cjsKK30KKworaW5saW5lIEF0b21pYzMyIEFjcXVpcmVfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWMzMiogcHRyKSB7CisgIEF0b21pYzMyIHZhbHVlID0gKnB0cjsgIC8vIEFuIHg4NiBsb2FkIGFjdHMgYXMgYSBhY3F1aXJlIGJhcnJpZXIuCisgIC8vIFNlZSBjb21tZW50cyBpbiBBdG9taWM2NCB2ZXJzaW9uIG9mIFJlbGVhc2VfU3RvcmUoKSwgYmVsb3cuCisgIEFUT01JQ09QU19DT01QSUxFUl9CQVJSSUVSKCk7CisgIHJldHVybiB2YWx1ZTsKK30KKworaW5saW5lIEF0b21pYzMyIFJlbGVhc2VfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWMzMiogcHRyKSB7CisgIE1lbW9yeUJhcnJpZXIoKTsKKyAgcmV0dXJuICpwdHI7Cit9CisKKyNpZiBkZWZpbmVkKF9feDg2XzY0X18pCisKKy8vIDY0LWJpdCBsb3ctbGV2ZWwgb3BlcmF0aW9ucyBvbiA2NC1iaXQgcGxhdGZvcm0uCisKK2lubGluZSBBdG9taWM2NCBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBuZXdfdmFsdWUpIHsKKyAgQXRvbWljNjQgcHJldjsKKyAgX19hc21fXyBfX3ZvbGF0aWxlX18oImxvY2s7IGNtcHhjaGdxICUxLCUyIgorICAgICAgICAgICAgICAgICAgICAgICA6ICI9YSIgKHByZXYpCisgICAgICAgICAgICAgICAgICAgICAgIDogInEiIChuZXdfdmFsdWUpLCAibSIgKCpwdHIpLCAiMCIgKG9sZF92YWx1ZSkKKyAgICAgICAgICAgICAgICAgICAgICAgOiAibWVtb3J5Iik7CisgIHJldHVybiBwcmV2OworfQorCitpbmxpbmUgQXRvbWljNjQgTm9CYXJyaWVyX0F0b21pY0V4Y2hhbmdlKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG5ld192YWx1ZSkgeworICBfX2FzbV9fIF9fdm9sYXRpbGVfXygieGNoZ3EgJTEsJTAiICAvLyBUaGUgbG9jayBwcmVmaXggaXMgaW1wbGljaXQgZm9yIHhjaGcuCisgICAgICAgICAgICAgICAgICAgICAgIDogIj1yIiAobmV3X3ZhbHVlKQorICAgICAgICAgICAgICAgICAgICAgICA6ICJtIiAoKnB0ciksICIwIiAobmV3X3ZhbHVlKQorICAgICAgICAgICAgICAgICAgICAgICA6ICJtZW1vcnkiKTsKKyAgcmV0dXJuIG5ld192YWx1ZTsgIC8vIE5vdyBpdCdzIHRoZSBwcmV2aW91cyB2YWx1ZS4KK30KKworaW5saW5lIEF0b21pYzY0IE5vQmFycmllcl9BdG9taWNJbmNyZW1lbnQodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IGluY3JlbWVudCkgeworICBBdG9taWM2NCB0ZW1wID0gaW5jcmVtZW50OworICBfX2FzbV9fIF9fdm9sYXRpbGVfXygibG9jazsgeGFkZHEgJTAsJTEiCisgICAgICAgICAgICAgICAgICAgICAgIDogIityIiAodGVtcCksICIrbSIgKCpwdHIpCisgICAgICAgICAgICAgICAgICAgICAgIDogOiAibWVtb3J5Iik7CisgIC8vIHRlbXAgbm93IGNvbnRhaW5zIHRoZSBwcmV2aW91cyB2YWx1ZSBvZiAqcHRyCisgIHJldHVybiB0ZW1wICsgaW5jcmVtZW50OworfQorCitpbmxpbmUgQXRvbWljNjQgQmFycmllcl9BdG9taWNJbmNyZW1lbnQodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBpbmNyZW1lbnQpIHsKKyAgQXRvbWljNjQgdGVtcCA9IGluY3JlbWVudDsKKyAgX19hc21fXyBfX3ZvbGF0aWxlX18oImxvY2s7IHhhZGRxICUwLCUxIgorICAgICAgICAgICAgICAgICAgICAgICA6ICIrciIgKHRlbXApLCAiK20iICgqcHRyKQorICAgICAgICAgICAgICAgICAgICAgICA6IDogIm1lbW9yeSIpOworICAvLyB0ZW1wIG5vdyBjb250YWlucyB0aGUgcHJldmlvdXMgdmFsdWUgb2YgKnB0cgorICBpZiAoQXRvbWljT3BzX0ludGVybmFseDg2Q1BVRmVhdHVyZXMuaGFzX2FtZF9sb2NrX21iX2J1ZykgeworICAgIF9fYXNtX18gX192b2xhdGlsZV9fKCJsZmVuY2UiIDogOiA6ICJtZW1vcnkiKTsKKyAgfQorICByZXR1cm4gdGVtcCArIGluY3JlbWVudDsKK30KKworaW5saW5lIHZvaWQgTm9CYXJyaWVyX1N0b3JlKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsIEF0b21pYzY0IHZhbHVlKSB7CisgICpwdHIgPSB2YWx1ZTsKK30KKworaW5saW5lIHZvaWQgQWNxdWlyZV9TdG9yZSh2b2xhdGlsZSBBdG9taWM2NCogcHRyLCBBdG9taWM2NCB2YWx1ZSkgeworICAqcHRyID0gdmFsdWU7CisgIE1lbW9yeUJhcnJpZXIoKTsKK30KKworaW5saW5lIHZvaWQgUmVsZWFzZV9TdG9yZSh2b2xhdGlsZSBBdG9taWM2NCogcHRyLCBBdG9taWM2NCB2YWx1ZSkgeworICBBVE9NSUNPUFNfQ09NUElMRVJfQkFSUklFUigpOworCisgICpwdHIgPSB2YWx1ZTsgIC8vIEFuIHg4NiBzdG9yZSBhY3RzIGFzIGEgcmVsZWFzZSBiYXJyaWVyCisgICAgICAgICAgICAgICAgIC8vIGZvciBjdXJyZW50IEFNRC9JbnRlbCBjaGlwcyBhcyBvZiBKYW4gMjAwOC4KKyAgICAgICAgICAgICAgICAgLy8gU2VlIGFsc28gQWNxdWlyZV9Mb2FkKCksIGJlbG93LgorCisgIC8vIFdoZW4gbmV3IGNoaXBzIGNvbWUgb3V0LCBjaGVjazoKKyAgLy8gIElBLTMyIEludGVsIEFyY2hpdGVjdHVyZSBTb2Z0d2FyZSBEZXZlbG9wZXIncyBNYW51YWwsIFZvbHVtZSAzOgorICAvLyAgU3lzdGVtIFByb2dyYW1taW5nIEd1aWRlLCBDaGF0cGVyIDc6IE11bHRpcGxlLXByb2Nlc3NvciBtYW5hZ2VtZW50LAorICAvLyAgU2VjdGlvbiA3LjIsIE1lbW9yeSBPcmRlcmluZy4KKyAgLy8gTGFzdCBzZWVuIGF0OgorICAvLyAgIGh0dHA6Ly9kZXZlbG9wZXIuaW50ZWwuY29tL2Rlc2lnbi9wZW50aXVtNC9tYW51YWxzL2luZGV4X25ldy5odG0KKyAgLy8KKyAgLy8geDg2IHN0b3Jlcy9sb2FkcyBmYWlsIHRvIGFjdCBhcyBiYXJyaWVycyBmb3IgYSBmZXcgaW5zdHJ1Y3Rpb25zIChjbGZsdXNoCisgIC8vIG1hc2ttb3ZkcXUgbWFza21vdnEgbW92bnRkcSBtb3ZudGkgbW92bnRwZCBtb3ZudHBzIG1vdm50cSkgYnV0IHRoZXNlIGFyZQorICAvLyBub3QgZ2VuZXJhdGVkIGJ5IHRoZSBjb21waWxlciwgYW5kIGFyZSByYXJlLiAgVXNlcnMgb2YgdGhlc2UgaW5zdHJ1Y3Rpb25zCisgIC8vIG5lZWQgdG8ga25vdyBhYm91dCBjYWNoZSBiZWhhdmlvdXIgaW4gYW55IGNhc2Ugc2luY2UgYWxsIG9mIHRoZXNlIGludm9sdmUKKyAgLy8gZWl0aGVyIGZsdXNoaW5nIGNhY2hlIGxpbmVzIG9yIG5vbi10ZW1wb3JhbCBjYWNoZSBoaW50cy4KK30KKworaW5saW5lIEF0b21pYzY0IE5vQmFycmllcl9Mb2FkKHZvbGF0aWxlIGNvbnN0IEF0b21pYzY0KiBwdHIpIHsKKyAgcmV0dXJuICpwdHI7Cit9CisKK2lubGluZSBBdG9taWM2NCBBY3F1aXJlX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljNjQqIHB0cikgeworICBBdG9taWM2NCB2YWx1ZSA9ICpwdHI7ICAvLyBBbiB4ODYgbG9hZCBhY3RzIGFzIGEgYWNxdWlyZSBiYXJyaWVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBmb3IgY3VycmVudCBBTUQvSW50ZWwgY2hpcHMgYXMgb2YgSmFuIDIwMDguCisgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNlZSBhbHNvIFJlbGVhc2VfU3RvcmUoKSwgYWJvdmUuCisgIEFUT01JQ09QU19DT01QSUxFUl9CQVJSSUVSKCk7CisgIHJldHVybiB2YWx1ZTsKK30KKworaW5saW5lIEF0b21pYzY0IFJlbGVhc2VfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWM2NCogcHRyKSB7CisgIE1lbW9yeUJhcnJpZXIoKTsKKyAgcmV0dXJuICpwdHI7Cit9CisKK2lubGluZSBBdG9taWM2NCBBY3F1aXJlX0NvbXBhcmVBbmRTd2FwKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBuZXdfdmFsdWUpIHsKKyAgQXRvbWljNjQgeCA9IE5vQmFycmllcl9Db21wYXJlQW5kU3dhcChwdHIsIG9sZF92YWx1ZSwgbmV3X3ZhbHVlKTsKKyAgaWYgKEF0b21pY09wc19JbnRlcm5hbHg4NkNQVUZlYXR1cmVzLmhhc19hbWRfbG9ja19tYl9idWcpIHsKKyAgICBfX2FzbV9fIF9fdm9sYXRpbGVfXygibGZlbmNlIiA6IDogOiAibWVtb3J5Iik7CisgIH0KKyAgcmV0dXJuIHg7Cit9CisKK2lubGluZSBBdG9taWM2NCBSZWxlYXNlX0NvbXBhcmVBbmRTd2FwKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBuZXdfdmFsdWUpIHsKKyAgcmV0dXJuIE5vQmFycmllcl9Db21wYXJlQW5kU3dhcChwdHIsIG9sZF92YWx1ZSwgbmV3X3ZhbHVlKTsKK30KKworI2VuZGlmICAvLyBkZWZpbmVkKF9feDg2XzY0X18pCisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKyN1bmRlZiBBVE9NSUNPUFNfQ09NUElMRVJfQkFSUklFUgorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9BVE9NSUNPUFNfSU5URVJOQUxTX1g4Nl9HQ0NfSF8KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc194ODZfbXN2Yy5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc194ODZfbXN2Yy5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NDFiMTY0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX3g4Nl9tc3ZjLmNjCkBAIC0wLDAgKzEsMTEyIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDEyIEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gVGhlIGNvbXBpbGF0aW9uIG9mIGV4dGVuc2lvbl9zZXQuY2MgZmFpbHMgd2hlbiB3aW5kb3dzLmggaXMgaW5jbHVkZWQuCisvLyBUaGVyZWZvcmUgd2UgbW92ZSB0aGUgY29kZSBkZXBlbmRpbmcgb24gd2luZG93cy5oIHRvIHRoaXMgc2VwYXJhdGUgY2MgZmlsZS4KKworLy8gRG9uJ3QgY29tcGlsZSB0aGlzIGZpbGUgZm9yIHBlb3BsZSBub3QgY29uY2VybmVkIGFib3V0IHRocmVhZCBzYWZldHkuCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9OT19USFJFQURfU0FGRVRZCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzLmg+CisKKyNpZmRlZiBHT09HTEVfUFJPVE9CVUZfQVRPTUlDT1BTX0lOVEVSTkFMU19YODZfTVNWQ19IXworCisjaW5jbHVkZSA8d2luZG93cy5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW50ZXJuYWwgeworCitpbmxpbmUgdm9pZCBNZW1vcnlCYXJyaWVyKCkgeworICAvLyBXZSB1c2UgTWVtb3J5QmFycmllciBmcm9tIFdpbk5ULmgKKyAgOjpNZW1vcnlCYXJyaWVyKCk7Cit9CisKK0F0b21pYzMyIE5vQmFycmllcl9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBuZXdfdmFsdWUpIHsKKyAgTE9ORyByZXN1bHQgPSBJbnRlcmxvY2tlZENvbXBhcmVFeGNoYW5nZSgKKyAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8dm9sYXRpbGUgTE9ORyo+KHB0ciksCisgICAgICBzdGF0aWNfY2FzdDxMT05HPihuZXdfdmFsdWUpLAorICAgICAgc3RhdGljX2Nhc3Q8TE9ORz4ob2xkX3ZhbHVlKSk7CisgIHJldHVybiBzdGF0aWNfY2FzdDxBdG9taWMzMj4ocmVzdWx0KTsKK30KKworQXRvbWljMzIgTm9CYXJyaWVyX0F0b21pY0V4Y2hhbmdlKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgbmV3X3ZhbHVlKSB7CisgIExPTkcgcmVzdWx0ID0gSW50ZXJsb2NrZWRFeGNoYW5nZSgKKyAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8dm9sYXRpbGUgTE9ORyo+KHB0ciksCisgICAgICBzdGF0aWNfY2FzdDxMT05HPihuZXdfdmFsdWUpKTsKKyAgcmV0dXJuIHN0YXRpY19jYXN0PEF0b21pYzMyPihyZXN1bHQpOworfQorCitBdG9taWMzMiBCYXJyaWVyX0F0b21pY0luY3JlbWVudCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgaW5jcmVtZW50KSB7CisgIHJldHVybiBJbnRlcmxvY2tlZEV4Y2hhbmdlQWRkKAorICAgICAgcmVpbnRlcnByZXRfY2FzdDx2b2xhdGlsZSBMT05HKj4ocHRyKSwKKyAgICAgIHN0YXRpY19jYXN0PExPTkc+KGluY3JlbWVudCkpICsgaW5jcmVtZW50OworfQorCisjaWYgZGVmaW5lZChfV0lONjQpCisKKy8vIDY0LWJpdCBsb3ctbGV2ZWwgb3BlcmF0aW9ucyBvbiA2NC1iaXQgcGxhdGZvcm0uCisKK0F0b21pYzY0IE5vQmFycmllcl9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWM2NCogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWM2NCBuZXdfdmFsdWUpIHsKKyAgUFZPSUQgcmVzdWx0ID0gSW50ZXJsb2NrZWRDb21wYXJlRXhjaGFuZ2VQb2ludGVyKAorICAgIHJlaW50ZXJwcmV0X2Nhc3Q8dm9sYXRpbGUgUFZPSUQqPihwdHIpLAorICAgIHJlaW50ZXJwcmV0X2Nhc3Q8UFZPSUQ+KG5ld192YWx1ZSksIHJlaW50ZXJwcmV0X2Nhc3Q8UFZPSUQ+KG9sZF92YWx1ZSkpOworICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxBdG9taWM2ND4ocmVzdWx0KTsKK30KKworQXRvbWljNjQgTm9CYXJyaWVyX0F0b21pY0V4Y2hhbmdlKHZvbGF0aWxlIEF0b21pYzY0KiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgbmV3X3ZhbHVlKSB7CisgIFBWT0lEIHJlc3VsdCA9IEludGVybG9ja2VkRXhjaGFuZ2VQb2ludGVyKAorICAgIHJlaW50ZXJwcmV0X2Nhc3Q8dm9sYXRpbGUgUFZPSUQqPihwdHIpLAorICAgIHJlaW50ZXJwcmV0X2Nhc3Q8UFZPSUQ+KG5ld192YWx1ZSkpOworICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxBdG9taWM2ND4ocmVzdWx0KTsKK30KKworQXRvbWljNjQgQmFycmllcl9BdG9taWNJbmNyZW1lbnQodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IGluY3JlbWVudCkgeworICByZXR1cm4gSW50ZXJsb2NrZWRFeGNoYW5nZUFkZDY0KAorICAgICAgcmVpbnRlcnByZXRfY2FzdDx2b2xhdGlsZSBMT05HTE9ORyo+KHB0ciksCisgICAgICBzdGF0aWNfY2FzdDxMT05HTE9ORz4oaW5jcmVtZW50KSkgKyBpbmNyZW1lbnQ7Cit9CisKKyNlbmRpZiAgLy8gZGVmaW5lZChfV0lONjQpCisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19JTlRFUk5BTFNfWDg2X01TVkNfSF8KKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX05PX1RIUkVBRF9TQUZFVFkKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc194ODZfbXN2Yy5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHNfaW50ZXJuYWxzX3g4Nl9tc3ZjLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTUzYTY0MQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzX2ludGVybmFsc194ODZfbXN2Yy5oCkBAIC0wLDAgKzEsMTUwIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDEyIEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gVGhpcyBmaWxlIGlzIGFuIGludGVybmFsIGF0b21pYyBpbXBsZW1lbnRhdGlvbiwgdXNlIGF0b21pY29wcy5oIGluc3RlYWQuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19JTlRFUk5BTFNfWDg2X01TVkNfSF8KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19JTlRFUk5BTFNfWDg2X01TVkNfSF8KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKworaW5saW5lIEF0b21pYzMyIE5vQmFycmllcl9BdG9taWNJbmNyZW1lbnQodm9sYXRpbGUgQXRvbWljMzIqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzMyIGluY3JlbWVudCkgeworICByZXR1cm4gQmFycmllcl9BdG9taWNJbmNyZW1lbnQocHRyLCBpbmNyZW1lbnQpOworfQorCisjaWYgIShkZWZpbmVkKF9NU0NfVkVSKSAmJiBfTVNDX1ZFUiA+PSAxNDAwKQorI2Vycm9yICJXZSByZXF1aXJlIGF0IGxlYXN0IHZzMjAwNSBmb3IgTWVtb3J5QmFycmllciIKKyNlbmRpZgorCitpbmxpbmUgQXRvbWljMzIgQWNxdWlyZV9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWMzMiogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljMzIgbmV3X3ZhbHVlKSB7CisgIHJldHVybiBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAocHRyLCBvbGRfdmFsdWUsIG5ld192YWx1ZSk7Cit9CisKK2lubGluZSBBdG9taWMzMiBSZWxlYXNlX0NvbXBhcmVBbmRTd2FwKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBvbGRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWMzMiBuZXdfdmFsdWUpIHsKKyAgcmV0dXJuIE5vQmFycmllcl9Db21wYXJlQW5kU3dhcChwdHIsIG9sZF92YWx1ZSwgbmV3X3ZhbHVlKTsKK30KKworaW5saW5lIHZvaWQgTm9CYXJyaWVyX1N0b3JlKHZvbGF0aWxlIEF0b21pYzMyKiBwdHIsIEF0b21pYzMyIHZhbHVlKSB7CisgICpwdHIgPSB2YWx1ZTsKK30KKworaW5saW5lIHZvaWQgQWNxdWlyZV9TdG9yZSh2b2xhdGlsZSBBdG9taWMzMiogcHRyLCBBdG9taWMzMiB2YWx1ZSkgeworICBOb0JhcnJpZXJfQXRvbWljRXhjaGFuZ2UocHRyLCB2YWx1ZSk7CisgICAgICAgICAgICAgIC8vIGFjdHMgYXMgYSBiYXJyaWVyIGluIHRoaXMgaW1wbGVtZW50YXRpb24KK30KKworaW5saW5lIHZvaWQgUmVsZWFzZV9TdG9yZSh2b2xhdGlsZSBBdG9taWMzMiogcHRyLCBBdG9taWMzMiB2YWx1ZSkgeworICAqcHRyID0gdmFsdWU7ICAvLyB3b3JrcyB3L28gYmFycmllciBmb3IgY3VycmVudCBJbnRlbCBjaGlwcyBhcyBvZiBKdW5lIDIwMDUKKyAgLy8gU2VlIGNvbW1lbnRzIGluIEF0b21pYzY0IHZlcnNpb24gb2YgUmVsZWFzZV9TdG9yZSgpIGJlbG93LgorfQorCitpbmxpbmUgQXRvbWljMzIgTm9CYXJyaWVyX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljMzIqIHB0cikgeworICByZXR1cm4gKnB0cjsKK30KKworaW5saW5lIEF0b21pYzMyIEFjcXVpcmVfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWMzMiogcHRyKSB7CisgIEF0b21pYzMyIHZhbHVlID0gKnB0cjsKKyAgcmV0dXJuIHZhbHVlOworfQorCitpbmxpbmUgQXRvbWljMzIgUmVsZWFzZV9Mb2FkKHZvbGF0aWxlIGNvbnN0IEF0b21pYzMyKiBwdHIpIHsKKyAgTWVtb3J5QmFycmllcigpOworICByZXR1cm4gKnB0cjsKK30KKworI2lmIGRlZmluZWQoX1dJTjY0KQorCisvLyA2NC1iaXQgbG93LWxldmVsIG9wZXJhdGlvbnMgb24gNjQtYml0IHBsYXRmb3JtLgorCitpbmxpbmUgQXRvbWljNjQgTm9CYXJyaWVyX0F0b21pY0luY3JlbWVudCh2b2xhdGlsZSBBdG9taWM2NCogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgaW5jcmVtZW50KSB7CisgIHJldHVybiBCYXJyaWVyX0F0b21pY0luY3JlbWVudChwdHIsIGluY3JlbWVudCk7Cit9CisKK2lubGluZSB2b2lkIE5vQmFycmllcl9TdG9yZSh2b2xhdGlsZSBBdG9taWM2NCogcHRyLCBBdG9taWM2NCB2YWx1ZSkgeworICAqcHRyID0gdmFsdWU7Cit9CisKK2lubGluZSB2b2lkIEFjcXVpcmVfU3RvcmUodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwgQXRvbWljNjQgdmFsdWUpIHsKKyAgTm9CYXJyaWVyX0F0b21pY0V4Y2hhbmdlKHB0ciwgdmFsdWUpOworICAgICAgICAgICAgICAvLyBhY3RzIGFzIGEgYmFycmllciBpbiB0aGlzIGltcGxlbWVudGF0aW9uCit9CisKK2lubGluZSB2b2lkIFJlbGVhc2VfU3RvcmUodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwgQXRvbWljNjQgdmFsdWUpIHsKKyAgKnB0ciA9IHZhbHVlOyAgLy8gd29ya3Mgdy9vIGJhcnJpZXIgZm9yIGN1cnJlbnQgSW50ZWwgY2hpcHMgYXMgb2YgSnVuZSAyMDA1CisKKyAgLy8gV2hlbiBuZXcgY2hpcHMgY29tZSBvdXQsIGNoZWNrOgorICAvLyAgSUEtMzIgSW50ZWwgQXJjaGl0ZWN0dXJlIFNvZnR3YXJlIERldmVsb3BlcidzIE1hbnVhbCwgVm9sdW1lIDM6CisgIC8vICBTeXN0ZW0gUHJvZ3JhbW1pbmcgR3VpZGUsIENoYXRwZXIgNzogTXVsdGlwbGUtcHJvY2Vzc29yIG1hbmFnZW1lbnQsCisgIC8vICBTZWN0aW9uIDcuMiwgTWVtb3J5IE9yZGVyaW5nLgorICAvLyBMYXN0IHNlZW4gYXQ6CisgIC8vICAgaHR0cDovL2RldmVsb3Blci5pbnRlbC5jb20vZGVzaWduL3BlbnRpdW00L21hbnVhbHMvaW5kZXhfbmV3Lmh0bQorfQorCitpbmxpbmUgQXRvbWljNjQgTm9CYXJyaWVyX0xvYWQodm9sYXRpbGUgY29uc3QgQXRvbWljNjQqIHB0cikgeworICByZXR1cm4gKnB0cjsKK30KKworaW5saW5lIEF0b21pYzY0IEFjcXVpcmVfTG9hZCh2b2xhdGlsZSBjb25zdCBBdG9taWM2NCogcHRyKSB7CisgIEF0b21pYzY0IHZhbHVlID0gKnB0cjsKKyAgcmV0dXJuIHZhbHVlOworfQorCitpbmxpbmUgQXRvbWljNjQgUmVsZWFzZV9Mb2FkKHZvbGF0aWxlIGNvbnN0IEF0b21pYzY0KiBwdHIpIHsKKyAgTWVtb3J5QmFycmllcigpOworICByZXR1cm4gKnB0cjsKK30KKworaW5saW5lIEF0b21pYzY0IEFjcXVpcmVfQ29tcGFyZUFuZFN3YXAodm9sYXRpbGUgQXRvbWljNjQqIHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG9sZF92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pYzY0IG5ld192YWx1ZSkgeworICByZXR1cm4gTm9CYXJyaWVyX0NvbXBhcmVBbmRTd2FwKHB0ciwgb2xkX3ZhbHVlLCBuZXdfdmFsdWUpOworfQorCitpbmxpbmUgQXRvbWljNjQgUmVsZWFzZV9Db21wYXJlQW5kU3dhcCh2b2xhdGlsZSBBdG9taWM2NCogcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgb2xkX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljNjQgbmV3X3ZhbHVlKSB7CisgIHJldHVybiBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAocHRyLCBvbGRfdmFsdWUsIG5ld192YWx1ZSk7Cit9CisKKyNlbmRpZiAgLy8gZGVmaW5lZChfV0lONjQpCisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0FUT01JQ09QU19JTlRFUk5BTFNfWDg2X01TVkNfSF8KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYnl0ZXN0cmVhbS5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYnl0ZXN0cmVhbS5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNGFmNmE1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9ieXRlc3RyZWFtLmNjCkBAIC0wLDAgKzEsMTk2IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9ieXRlc3RyZWFtLmg+CisKKyNpbmNsdWRlIDxzdHJpbmcuaD4KKyNpbmNsdWRlIDxhbGdvcml0aG0+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBzdHJpbmdzIHsKKwordm9pZCBCeXRlU291cmNlOjpDb3B5VG8oQnl0ZVNpbmsqIHNpbmssIHNpemVfdCBuKSB7CisgIHdoaWxlIChuID4gMCkgeworICAgIFN0cmluZ1BpZWNlIGZyYWdtZW50ID0gUGVlaygpOworICAgIGlmIChmcmFnbWVudC5lbXB0eSgpKSB7CisgICAgICBHT09HTEVfTE9HKERGQVRBTCkgPDwgIkJ5dGVTb3VyY2U6OkNvcHlUbygpIG92ZXJyYW4gaW5wdXQuIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBzdGQ6OnNpemVfdCBmcmFnbWVudF9zaXplID0gc3RkOjptaW48c3RkOjpzaXplX3Q+KG4sIGZyYWdtZW50LnNpemUoKSk7CisgICAgc2luay0+QXBwZW5kKGZyYWdtZW50LmRhdGEoKSwgZnJhZ21lbnRfc2l6ZSk7CisgICAgU2tpcChmcmFnbWVudF9zaXplKTsKKyAgICBuIC09IGZyYWdtZW50X3NpemU7CisgIH0KK30KKwordm9pZCBCeXRlU2luazo6Rmx1c2goKSB7fQorCit2b2lkIFVuY2hlY2tlZEFycmF5Qnl0ZVNpbms6OkFwcGVuZChjb25zdCBjaGFyKiBkYXRhLCBzaXplX3QgbikgeworICBpZiAoZGF0YSAhPSBkZXN0XykgeworICAgIC8vIENhdGNoIGNhc2VzIHdoZXJlIHRoZSBwb2ludGVyIHJldHVybmVkIGJ5IEdldEFwcGVuZEJ1ZmZlcigpIHdhcyBtb2RpZmllZC4KKyAgICBHT09HTEVfRENIRUNLKCEoZGVzdF8gPD0gZGF0YSAmJiBkYXRhIDwgKGRlc3RfICsgbikpKQorICAgICAgICA8PCAiQXBwZW5kKCkgZGF0YVtdIG92ZXJsYXBzIHdpdGggZGVzdF9bXSI7CisgICAgbWVtY3B5KGRlc3RfLCBkYXRhLCBuKTsKKyAgfQorICBkZXN0XyArPSBuOworfQorCitDaGVja2VkQXJyYXlCeXRlU2luazo6Q2hlY2tlZEFycmF5Qnl0ZVNpbmsoY2hhciogb3V0YnVmLCBzaXplX3QgY2FwYWNpdHkpCisgICAgOiBvdXRidWZfKG91dGJ1ZiksIGNhcGFjaXR5XyhjYXBhY2l0eSksIHNpemVfKDApLCBvdmVyZmxvd2VkXyhmYWxzZSkgeworfQorCit2b2lkIENoZWNrZWRBcnJheUJ5dGVTaW5rOjpBcHBlbmQoY29uc3QgY2hhciogYnl0ZXMsIHNpemVfdCBuKSB7CisgIHNpemVfdCBhdmFpbGFibGUgPSBjYXBhY2l0eV8gLSBzaXplXzsKKyAgaWYgKG4gPiBhdmFpbGFibGUpIHsKKyAgICBuID0gYXZhaWxhYmxlOworICAgIG92ZXJmbG93ZWRfID0gdHJ1ZTsKKyAgfQorICBpZiAobiA+IDAgJiYgYnl0ZXMgIT0gKG91dGJ1Zl8gKyBzaXplXykpIHsKKyAgICAvLyBDYXRjaCBjYXNlcyB3aGVyZSB0aGUgcG9pbnRlciByZXR1cm5lZCBieSBHZXRBcHBlbmRCdWZmZXIoKSB3YXMgbW9kaWZpZWQuCisgICAgR09PR0xFX0RDSEVDSyghKG91dGJ1Zl8gPD0gYnl0ZXMgJiYgYnl0ZXMgPCAob3V0YnVmXyArIGNhcGFjaXR5XykpKQorICAgICAgICA8PCAiQXBwZW5kKCkgYnl0ZXNbXSBvdmVybGFwcyB3aXRoIG91dGJ1Zl9bXSI7CisgICAgbWVtY3B5KG91dGJ1Zl8gKyBzaXplXywgYnl0ZXMsIG4pOworICB9CisgIHNpemVfICs9IG47Cit9CisKK0dyb3dpbmdBcnJheUJ5dGVTaW5rOjpHcm93aW5nQXJyYXlCeXRlU2luayhzaXplX3QgZXN0aW1hdGVkX3NpemUpCisgICAgOiBjYXBhY2l0eV8oZXN0aW1hdGVkX3NpemUpLAorICAgICAgYnVmXyhuZXcgY2hhcltlc3RpbWF0ZWRfc2l6ZV0pLAorICAgICAgc2l6ZV8oMCkgeworfQorCitHcm93aW5nQXJyYXlCeXRlU2luazo6fkdyb3dpbmdBcnJheUJ5dGVTaW5rKCkgeworICBkZWxldGVbXSBidWZfOyAgLy8gSnVzdCBpbiBjYXNlIHRoZSB1c2VyIGRpZG4ndCBjYWxsIEdldEJ1ZmZlci4KK30KKwordm9pZCBHcm93aW5nQXJyYXlCeXRlU2luazo6QXBwZW5kKGNvbnN0IGNoYXIqIGJ5dGVzLCBzaXplX3QgbikgeworICBzaXplX3QgYXZhaWxhYmxlID0gY2FwYWNpdHlfIC0gc2l6ZV87CisgIGlmIChieXRlcyAhPSAoYnVmXyArIHNpemVfKSkgeworICAgIC8vIENhdGNoIGNhc2VzIHdoZXJlIHRoZSBwb2ludGVyIHJldHVybmVkIGJ5IEdldEFwcGVuZEJ1ZmZlcigpIHdhcyBtb2RpZmllZC4KKyAgICAvLyBXZSBuZWVkIHRvIHRlc3QgZm9yIHRoaXMgYmVmb3JlIGNhbGxpbmcgRXhwYW5kKCkgd2hpY2ggbWF5IHJlYWxsb2NhdGUuCisgICAgR09PR0xFX0RDSEVDSyghKGJ1Zl8gPD0gYnl0ZXMgJiYgYnl0ZXMgPCAoYnVmXyArIGNhcGFjaXR5XykpKQorICAgICAgICA8PCAiQXBwZW5kKCkgYnl0ZXNbXSBvdmVybGFwcyB3aXRoIGJ1Zl9bXSI7CisgIH0KKyAgaWYgKG4gPiBhdmFpbGFibGUpIHsKKyAgICBFeHBhbmQobiAtIGF2YWlsYWJsZSk7CisgIH0KKyAgaWYgKG4gPiAwICYmIGJ5dGVzICE9IChidWZfICsgc2l6ZV8pKSB7CisgICAgbWVtY3B5KGJ1Zl8gKyBzaXplXywgYnl0ZXMsIG4pOworICB9CisgIHNpemVfICs9IG47Cit9CisKK2NoYXIqIEdyb3dpbmdBcnJheUJ5dGVTaW5rOjpHZXRCdWZmZXIoc2l6ZV90KiBuYnl0ZXMpIHsKKyAgU2hyaW5rVG9GaXQoKTsKKyAgY2hhciogYiA9IGJ1Zl87CisgICpuYnl0ZXMgPSBzaXplXzsKKyAgYnVmXyA9IE5VTEw7CisgIHNpemVfID0gY2FwYWNpdHlfID0gMDsKKyAgcmV0dXJuIGI7Cit9CisKK3ZvaWQgR3Jvd2luZ0FycmF5Qnl0ZVNpbms6OkV4cGFuZChzaXplX3QgYW1vdW50KSB7ICAvLyBFeHBhbmQgYnkgYXQgbGVhc3QgNTAlLgorICBzaXplX3QgbmV3X2NhcGFjaXR5ID0gc3RkOjptYXgoY2FwYWNpdHlfICsgYW1vdW50LCAoMyAqIGNhcGFjaXR5XykgLyAyKTsKKyAgY2hhciogYmlnZ2VyID0gbmV3IGNoYXJbbmV3X2NhcGFjaXR5XTsKKyAgbWVtY3B5KGJpZ2dlciwgYnVmXywgc2l6ZV8pOworICBkZWxldGVbXSBidWZfOworICBidWZfID0gYmlnZ2VyOworICBjYXBhY2l0eV8gPSBuZXdfY2FwYWNpdHk7Cit9CisKK3ZvaWQgR3Jvd2luZ0FycmF5Qnl0ZVNpbms6OlNocmlua1RvRml0KCkgeworICAvLyBTaHJpbmsgb25seSBpZiB0aGUgYnVmZmVyIGlzIGxhcmdlIGFuZCBzaXplXyBpcyBsZXNzIHRoYW4gMy80CisgIC8vIG9mIGNhcGFjaXR5Xy4KKyAgaWYgKGNhcGFjaXR5XyA+IDI1NiAmJiBzaXplXyA8ICgzICogY2FwYWNpdHlfKSAvIDQpIHsKKyAgICBjaGFyKiBqdXN0X2Vub3VnaCA9IG5ldyBjaGFyW3NpemVfXTsKKyAgICBtZW1jcHkoanVzdF9lbm91Z2gsIGJ1Zl8sIHNpemVfKTsKKyAgICBkZWxldGVbXSBidWZfOworICAgIGJ1Zl8gPSBqdXN0X2Vub3VnaDsKKyAgICBjYXBhY2l0eV8gPSBzaXplXzsKKyAgfQorfQorCit2b2lkIFN0cmluZ0J5dGVTaW5rOjpBcHBlbmQoY29uc3QgY2hhciogZGF0YSwgc2l6ZV90IG4pIHsKKyAgZGVzdF8tPmFwcGVuZChkYXRhLCBuKTsKK30KKworc2l6ZV90IEFycmF5Qnl0ZVNvdXJjZTo6QXZhaWxhYmxlKCkgY29uc3QgeworICByZXR1cm4gaW5wdXRfLnNpemUoKTsKK30KKworU3RyaW5nUGllY2UgQXJyYXlCeXRlU291cmNlOjpQZWVrKCkgeworICByZXR1cm4gaW5wdXRfOworfQorCit2b2lkIEFycmF5Qnl0ZVNvdXJjZTo6U2tpcChzaXplX3QgbikgeworICBHT09HTEVfRENIRUNLX0xFKG4sIGlucHV0Xy5zaXplKCkpOworICBpbnB1dF8ucmVtb3ZlX3ByZWZpeChuKTsKK30KKworTGltaXRCeXRlU291cmNlOjpMaW1pdEJ5dGVTb3VyY2UoQnl0ZVNvdXJjZSAqc291cmNlLCBzaXplX3QgbGltaXQpCisgIDogc291cmNlXyhzb3VyY2UpLAorICAgIGxpbWl0XyhsaW1pdCkgeworfQorCitzaXplX3QgTGltaXRCeXRlU291cmNlOjpBdmFpbGFibGUoKSBjb25zdCB7CisgIHNpemVfdCBhdmFpbGFibGUgPSBzb3VyY2VfLT5BdmFpbGFibGUoKTsKKyAgaWYgKGF2YWlsYWJsZSA+IGxpbWl0XykgeworICAgIGF2YWlsYWJsZSA9IGxpbWl0XzsKKyAgfQorCisgIHJldHVybiBhdmFpbGFibGU7Cit9CisKK1N0cmluZ1BpZWNlIExpbWl0Qnl0ZVNvdXJjZTo6UGVlaygpIHsKKyAgU3RyaW5nUGllY2UgcGllY2Uoc291cmNlXy0+UGVlaygpKTsKKyAgaWYgKHBpZWNlLnNpemUoKSA+IGxpbWl0XykgeworICAgIHBpZWNlLnNldChwaWVjZS5kYXRhKCksIGxpbWl0Xyk7CisgIH0KKworICByZXR1cm4gcGllY2U7Cit9CisKK3ZvaWQgTGltaXRCeXRlU291cmNlOjpTa2lwKHNpemVfdCBuKSB7CisgIEdPT0dMRV9EQ0hFQ0tfTEUobiwgbGltaXRfKTsKKyAgc291cmNlXy0+U2tpcChuKTsKKyAgbGltaXRfIC09IG47Cit9CisKK3ZvaWQgTGltaXRCeXRlU291cmNlOjpDb3B5VG8oQnl0ZVNpbmsgKnNpbmssIHNpemVfdCBuKSB7CisgIEdPT0dMRV9EQ0hFQ0tfTEUobiwgbGltaXRfKTsKKyAgc291cmNlXy0+Q29weVRvKHNpbmssIG4pOworICBsaW1pdF8gLT0gbjsKK30KKworfSAgLy8gbmFtZXNwYWNlIHN0cmluZ3MKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9ieXRlc3RyZWFtLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2J5dGVzdHJlYW0uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZThlMDIwCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9ieXRlc3RyZWFtLmgKQEAgLTAsMCArMSwzNDggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBUaGlzIGZpbGUgZGVjbGFyZXMgdGhlIEJ5dGVTaW5rIGFuZCBCeXRlU291cmNlIGFic3RyYWN0IGludGVyZmFjZXMuIFRoZXNlCisvLyBpbnRlcmZhY2VzIHJlcHJlc2VudCBvYmplY3RzIHRoYXQgY29uc3VtZSAoQnl0ZVNpbmspIG9yIHByb2R1Y2UgKEJ5dGVTb3VyY2UpCisvLyBhIHNlcXVlbmNlIG9mIGJ5dGVzLiBVc2luZyB0aGVzZSBhYnN0cmFjdCBpbnRlcmZhY2VzIGluIHlvdXIgQVBJcyBjYW4gaGVscAorLy8gbWFrZSB5b3VyIGNvZGUgd29yayB3aXRoIGEgdmFyaWV0eSBvZiBpbnB1dCBhbmQgb3V0cHV0IHR5cGVzLgorLy8KKy8vIFRoaXMgZmlsZSBhbHNvIGRlY2xhcmVzIHRoZSBmb2xsb3dpbmcgY29tbW9ubHkgdXNlZCBpbXBsZW1lbnRhdGlvbnMgb2YgdGhlc2UKKy8vIGludGVyZmFjZXMuCisvLworLy8gICBCeXRlU2luazoKKy8vICAgICAgVW5jaGVja2VkQXJyYXlCeXRlU2luayAgV3JpdGVzIHRvIGFuIGFycmF5LCB3aXRob3V0IGJvdW5kcyBjaGVja2luZworLy8gICAgICBDaGVja2VkQXJyYXlCeXRlU2luayAgICBXcml0ZXMgdG8gYW4gYXJyYXksIHdpdGggYm91bmRzIGNoZWNraW5nCisvLyAgICAgIEdyb3dpbmdBcnJheUJ5dGVTaW5rICAgIEFsbG9jYXRlcyBhbmQgd3JpdGVzIHRvIGEgZ3Jvd2FibGUgYnVmZmVyCisvLyAgICAgIFN0cmluZ0J5dGVTaW5rICAgICAgICAgIFdyaXRlcyB0byBhbiBTVEwgc3RyaW5nCisvLyAgICAgIE51bGxCeXRlU2luayAgICAgICAgICAgIENvbnN1bWVzIGEgbmV2ZXItZW5kaW5nIHN0cmVhbSBvZiBieXRlcworLy8KKy8vICAgQnl0ZVNvdXJjZToKKy8vICAgICAgQXJyYXlCeXRlU291cmNlICAgICAgICAgUmVhZHMgZnJvbSBhbiBhcnJheSBvciBzdHJpbmcvU3RyaW5nUGllY2UKKy8vICAgICAgTGltaXRlZEJ5dGVTb3VyY2UgICAgICAgTGltaXRzIHRoZSBudW1iZXIgb2YgYnl0ZXMgcmVhZCBmcm9tIGFuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX1NUVUJTX0JZVEVTVFJFQU1fSF8KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1NUVUJTX0JZVEVTVFJFQU1fSF8KKworI2luY2x1ZGUgPHN0ZGRlZi5oPgorI2luY2x1ZGUgPHN0cmluZz4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RyaW5ncGllY2UuaD4KKworY2xhc3MgQ29yZEJ5dGVTaW5rOworY2xhc3MgTWVtQmxvY2s7CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBzdHJpbmdzIHsKKworLy8gQW4gYWJzdHJhY3QgaW50ZXJmYWNlIGZvciBhbiBvYmplY3QgdGhhdCBjb25zdW1lcyBhIHNlcXVlbmNlIG9mIGJ5dGVzLiBUaGlzCisvLyBpbnRlcmZhY2Ugb2ZmZXJzIDMgZGlmZmVyZW50IHdheXMgdG8gYXBwZW5kIGRhdGEsIGFuZCBhIEZsdXNoKCkgZnVuY3Rpb24uCisvLworLy8gRXhhbXBsZToKKy8vCisvLyAgIHN0cmluZyBteV9kYXRhOworLy8gICAuLi4KKy8vICAgQnl0ZVNpbmsqIHNpbmsgPSAuLi4KKy8vICAgc2luay0+QXBwZW5kKG15X2RhdGEuZGF0YSgpLCBteV9kYXRhLnNpemUoKSk7CisvLyAgIHNpbmstPkZsdXNoKCk7CisvLworY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEJ5dGVTaW5rIHsKKyBwdWJsaWM6CisgIEJ5dGVTaW5rKCkge30KKyAgdmlydHVhbCB+Qnl0ZVNpbmsoKSB7fQorCisgIC8vIEFwcGVuZHMgdGhlICJuIiBieXRlcyBzdGFydGluZyBhdCAiYnl0ZXMiLgorICB2aXJ0dWFsIHZvaWQgQXBwZW5kKGNvbnN0IGNoYXIqIGJ5dGVzLCBzaXplX3QgbikgPSAwOworCisgIC8vIEZsdXNoZXMgaW50ZXJuYWwgYnVmZmVycy4gVGhlIGRlZmF1bHQgaW1wbGVtZW5hdGlvbiBkb2VzIG5vdGhpbmcuIEJ5dGVTaW5rCisgIC8vIHN1YmNsYXNzZXMgbWF5IHVzZSBpbnRlcm5hbCBidWZmZXJzIHRoYXQgcmVxdWlyZSBjYWxsaW5nIEZsdXNoKCkgYXQgdGhlIGVuZAorICAvLyBvZiB0aGUgc3RyZWFtLgorICB2aXJ0dWFsIHZvaWQgRmx1c2goKTsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhCeXRlU2luayk7Cit9OworCisvLyBBbiBhYnN0cmFjdCBpbnRlcmZhY2UgZm9yIGFuIG9iamVjdCB0aGF0IHByb2R1Y2VzIGEgZml4ZWQtc2l6ZSBzZXF1ZW5jZSBvZgorLy8gYnl0ZXMuCisvLworLy8gRXhhbXBsZToKKy8vCisvLyAgIEJ5dGVTb3VyY2UqIHNvdXJjZSA9IC4uLgorLy8gICB3aGlsZSAoc291cmNlLT5BdmFpbGFibGUoKSA+IDApIHsKKy8vICAgICBTdHJpbmdQaWVjZSBkYXRhID0gc291cmNlLT5QZWVrKCk7CisvLyAgICAgLi4uIGRvIHNvbWV0aGluZyB3aXRoICJkYXRhIiAuLi4KKy8vICAgICBzb3VyY2UtPlNraXAoZGF0YS5sZW5ndGgoKSk7CisvLyAgIH0KKy8vCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgQnl0ZVNvdXJjZSB7CisgcHVibGljOgorICBCeXRlU291cmNlKCkge30KKyAgdmlydHVhbCB+Qnl0ZVNvdXJjZSgpIHt9CisKKyAgLy8gUmV0dXJucyB0aGUgbnVtYmVyIG9mIGJ5dGVzIGxlZnQgdG8gcmVhZCBmcm9tIHRoZSBzb3VyY2UuIEF2YWlsYWJsZSgpCisgIC8vIHNob3VsZCBkZWNyZWFzZSBieSBOIGVhY2ggdGltZSBTa2lwKE4pIGlzIGNhbGxlZC4gQXZhaWxhYmxlKCkgbWF5IG5vdAorICAvLyBpbmNyZWFzZS4gQXZhaWxhYmxlKCkgcmV0dXJuaW5nIDAgaW5kaWNhdGVzIHRoYXQgdGhlIEJ5dGVTb3VyY2UgaXMKKyAgLy8gZXhoYXVzdGVkLgorICAvLworICAvLyBOb3RlOiBTaXplKCkgbWF5IGhhdmUgYmVlbiBhIG1vcmUgYXBwcm9wcmlhdGUgbmFtZSBhcyBpdCdzIG1vcmUKKyAgLy8gICAgICAgaW5kaWNhdGl2ZSBvZiB0aGUgZml4ZWQtc2l6ZSBuYXR1cmUgb2YgYSBCeXRlU291cmNlLgorICB2aXJ0dWFsIHNpemVfdCBBdmFpbGFibGUoKSBjb25zdCA9IDA7CisKKyAgLy8gUmV0dXJucyBhIFN0cmluZ1BpZWNlIG9mIHRoZSBuZXh0IGNvbnRpZ3VvdXMgcmVnaW9uIG9mIHRoZSBzb3VyY2UuIERvZXMgbm90CisgIC8vIHJlcG9zaXRpb24gdGhlIHNvdXJjZS4gVGhlIHJldHVybmVkIHJlZ2lvbiBpcyBlbXB0eSBpZmYgQXZhaWxhYmxlKCkgPT0gMC4KKyAgLy8KKyAgLy8gVGhlIHJldHVybmVkIHJlZ2lvbiBpcyB2YWxpZCB1bnRpbCB0aGUgbmV4dCBjYWxsIHRvIFNraXAoKSBvciB1bnRpbCB0aGlzCisgIC8vIG9iamVjdCBpcyBkZXN0cm95ZWQsIHdoaWNoZXZlciBvY2N1cnMgZmlyc3QuCisgIC8vCisgIC8vIFRoZSBsZW5ndGggb2YgdGhlIHJldHVybmVkIFN0cmluZ1BpZWNlIHdpbGwgYmUgPD0gQXZhaWxhYmxlKCkuCisgIHZpcnR1YWwgU3RyaW5nUGllY2UgUGVlaygpID0gMDsKKworICAvLyBTa2lwcyB0aGUgbmV4dCBuIGJ5dGVzLiBJbnZhbGlkYXRlcyBhbnkgU3RyaW5nUGllY2UgcmV0dXJuZWQgYnkgYSBwcmV2aW91cworICAvLyBjYWxsIHRvIFBlZWsoKS4KKyAgLy8KKyAgLy8gUkVRVUlSRVM6IEF2YWlsYWJsZSgpID49IG4KKyAgdmlydHVhbCB2b2lkIFNraXAoc2l6ZV90IG4pID0gMDsKKworICAvLyBXcml0ZXMgdGhlIG5leHQgbiBieXRlcyBpbiB0aGlzIEJ5dGVTb3VyY2UgdG8gdGhlIGdpdmVuIEJ5dGVTaW5rLCBhbmQKKyAgLy8gYWR2YW5jZXMgdGhpcyBCeXRlU291cmNlIHBhc3QgdGhlIGNvcGllZCBieXRlcy4gVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24KKyAgLy8gb2YgdGhpcyBtZXRob2QganVzdCBjb3BpZXMgdGhlIGJ5dGVzIG5vcm1hbGx5LCBidXQgc3ViY2xhc3NlcyBtaWdodAorICAvLyBvdmVycmlkZSBDb3B5VG8gdG8gb3B0aW1pemUgY2VydGFpbiBjYXNlcy4KKyAgLy8KKyAgLy8gUkVRVUlSRVM6IEF2YWlsYWJsZSgpID49IG4KKyAgdmlydHVhbCB2b2lkIENvcHlUbyhCeXRlU2luayogc2luaywgc2l6ZV90IG4pOworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEJ5dGVTb3VyY2UpOworfTsKKworLy8KKy8vIFNvbWUgY29tbW9ubHkgdXNlZCBpbXBsZW1lbnRhdGlvbnMgb2YgQnl0ZVNpbmsKKy8vCisKKy8vIEltcGxlbWVudGF0aW9uIG9mIEJ5dGVTaW5rIHRoYXQgd3JpdGVzIHRvIGFuIHVuc2l6ZWQgYnl0ZSBhcnJheS4gTm8KKy8vIGJvdW5kcy1jaGVja2luZyBpcyBwZXJmb3JtZWQtLWl0IGlzIHRoZSBjYWxsZXIncyByZXNwb25zaWJpbGl0eSB0byBlbnN1cmUKKy8vIHRoYXQgdGhlIGRlc3RpbmF0aW9uIGFycmF5IGlzIGxhcmdlIGVub3VnaC4KKy8vCisvLyBFeGFtcGxlOgorLy8KKy8vICAgY2hhciBidWZbMTBdOworLy8gICBVbmNoZWNrZWRBcnJheUJ5dGVTaW5rIHNpbmsoYnVmKTsKKy8vICAgc2luay5BcHBlbmQoImhpIiwgMik7ICAgIC8vIE9LCisvLyAgIHNpbmsuQXBwZW5kKGRhdGEsIDEwMCk7ICAvLyBXT09QUyEgT3ZlcmZsb3dzIGJ1ZlsxMF0uCisvLworY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFVuY2hlY2tlZEFycmF5Qnl0ZVNpbmsgOiBwdWJsaWMgQnl0ZVNpbmsgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgVW5jaGVja2VkQXJyYXlCeXRlU2luayhjaGFyKiBkZXN0KSA6IGRlc3RfKGRlc3QpIHt9CisgIHZpcnR1YWwgdm9pZCBBcHBlbmQoY29uc3QgY2hhciogZGF0YSwgc2l6ZV90IG4pOworCisgIC8vIFJldHVybnMgdGhlIGN1cnJlbnQgb3V0cHV0IHBvaW50ZXIgc28gdGhhdCBhIGNhbGxlciBjYW4gc2VlIGhvdyBtYW55IGJ5dGVzCisgIC8vIHdlcmUgcHJvZHVjZWQuCisgIC8vCisgIC8vIE5vdGU6IHRoaXMgbWV0aG9kIGlzIG5vdCBwYXJ0IG9mIHRoZSBCeXRlU2luayBpbnRlcmZhY2UuCisgIGNoYXIqIEN1cnJlbnREZXN0aW5hdGlvbigpIGNvbnN0IHsgcmV0dXJuIGRlc3RfOyB9CisKKyBwcml2YXRlOgorICBjaGFyKiBkZXN0XzsKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFVuY2hlY2tlZEFycmF5Qnl0ZVNpbmspOworfTsKKworLy8gSW1wbGVtZW50YXRpb24gb2YgQnl0ZVNpbmsgdGhhdCB3cml0ZXMgdG8gYSBzaXplZCBieXRlIGFycmF5LiBUaGlzIHNpbmsgd2lsbAorLy8gbm90IHdyaXRlIG1vcmUgdGhhbiAiY2FwYWNpdHkiIGJ5dGVzIHRvIG91dGJ1Zi4gT25jZSAiY2FwYWNpdHkiIGJ5dGVzIGFyZQorLy8gYXBwZW5kZWQsIHN1YnNlcXVlbnQgYnl0ZXMgd2lsbCBiZSBpZ25vcmVkIGFuZCBPdmVyZmxvd2VkKCkgd2lsbCByZXR1cm4gdHJ1ZS4KKy8vIE92ZXJmbG93ZWQoKSBkb2VzIG5vdCBjYXVzZSBhIHJ1bnRpbWUgZXJyb3IgKGkuZS4sIGl0IGRvZXMgbm90IENIRUNLIGZhaWwpLgorLy8KKy8vIEV4YW1wbGU6CisvLworLy8gICBjaGFyIGJ1ZlsxMF07CisvLyAgIENoZWNrZWRBcnJheUJ5dGVTaW5rIHNpbmsoYnVmLCAxMCk7CisvLyAgIHNpbmsuQXBwZW5kKCJoaSIsIDIpOyAgICAvLyBPSworLy8gICBzaW5rLkFwcGVuZChkYXRhLCAxMDApOyAgLy8gV2lsbCBvbmx5IHdyaXRlIDggbW9yZSBieXRlcworLy8KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBDaGVja2VkQXJyYXlCeXRlU2luayA6IHB1YmxpYyBCeXRlU2luayB7CisgcHVibGljOgorICBDaGVja2VkQXJyYXlCeXRlU2luayhjaGFyKiBvdXRidWYsIHNpemVfdCBjYXBhY2l0eSk7CisgIHZpcnR1YWwgdm9pZCBBcHBlbmQoY29uc3QgY2hhciogYnl0ZXMsIHNpemVfdCBuKTsKKworICAvLyBSZXR1cm5zIHRoZSBudW1iZXIgb2YgYnl0ZXMgYWN0dWFsbHkgd3JpdHRlbiB0byB0aGUgc2luay4KKyAgc2l6ZV90IE51bWJlck9mQnl0ZXNXcml0dGVuKCkgY29uc3QgeyByZXR1cm4gc2l6ZV87IH0KKworICAvLyBSZXR1cm5zIHRydWUgaWYgYW55IGJ5dGVzIHdlcmUgZGlzY2FyZGVkLCBpLmUuLCBpZiB0aGVyZSB3YXMgYW4KKyAgLy8gYXR0ZW1wdCB0byB3cml0ZSBtb3JlIHRoYW4gJ2NhcGFjaXR5JyBieXRlcy4KKyAgYm9vbCBPdmVyZmxvd2VkKCkgY29uc3QgeyByZXR1cm4gb3ZlcmZsb3dlZF87IH0KKworIHByaXZhdGU6CisgIGNoYXIqIG91dGJ1Zl87CisgIGNvbnN0IHNpemVfdCBjYXBhY2l0eV87CisgIHNpemVfdCBzaXplXzsKKyAgYm9vbCBvdmVyZmxvd2VkXzsKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKENoZWNrZWRBcnJheUJ5dGVTaW5rKTsKK307CisKKy8vIEltcGxlbWVudGF0aW9uIG9mIEJ5dGVTaW5rIHRoYXQgYWxsb2NhdGVzIGFuIGludGVybmFsIGJ1ZmZlciAoYSBjaGFyIGFycmF5KQorLy8gYW5kIGV4cGFuZHMgaXQgYXMgbmVlZGVkIHRvIGFjY29tb2RhdGUgYXBwZW5kZWQgZGF0YSAoc2ltaWxhciB0byBhIHN0cmluZyksCisvLyBhbmQgYWxsb3dzIHRoZSBjYWxsZXIgdG8gdGFrZSBvd25lcnNoaXAgb2YgdGhlIGludGVybmFsIGJ1ZmZlciB2aWEgdGhlCisvLyBHZXRCdWZmZXIoKSBtZXRob2QuIFRoZSBidWZmZXIgcmV0dXJuZWQgZnJvbSBHZXRCdWZmZXIoKSBtdXN0IGJlIGRlbGV0ZWQgYnkKKy8vIHRoZSBjYWxsZXIgd2l0aCBkZWxldGVbXS4gR2V0QnVmZmVyKCkgYWxzbyBzZXRzIHRoZSBpbnRlcm5hbCBidWZmZXIgdG8gYmUKKy8vIGVtcHR5LCBhbmQgc3Vic2VxdWVudCBhcHBlbmRzIHRvIHRoZSBzaW5rIHdpbGwgY3JlYXRlIGEgbmV3IGJ1ZmZlci4gVGhlCisvLyBkZXN0cnVjdG9yIHdpbGwgZnJlZSB0aGUgaW50ZXJuYWwgYnVmZmVyIGlmIEdldEJ1ZmZlcigpIHdhcyBub3QgY2FsbGVkLgorLy8KKy8vIEV4YW1wbGU6CisvLworLy8gICBHcm93aW5nQXJyYXlCeXRlU2luayBzaW5rKDEwKTsKKy8vICAgc2luay5BcHBlbmQoImhpIiwgMik7CisvLyAgIHNpbmsuQXBwZW5kKGRhdGEsIG4pOworLy8gICBjb25zdCBjaGFyKiBidWYgPSBzaW5rLkdldEJ1ZmZlcigpOyAgLy8gT3duZXJzaGlwIHRyYW5zZmVycmVkCisvLyAgIGRlbGV0ZVtdIGJ1ZjsKKy8vCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgR3Jvd2luZ0FycmF5Qnl0ZVNpbmsgOiBwdWJsaWMgc3RyaW5nczo6Qnl0ZVNpbmsgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgR3Jvd2luZ0FycmF5Qnl0ZVNpbmsoc2l6ZV90IGVzdGltYXRlZF9zaXplKTsKKyAgdmlydHVhbCB+R3Jvd2luZ0FycmF5Qnl0ZVNpbmsoKTsKKyAgdmlydHVhbCB2b2lkIEFwcGVuZChjb25zdCBjaGFyKiBieXRlcywgc2l6ZV90IG4pOworCisgIC8vIFJldHVybnMgdGhlIGFsbG9jYXRlZCBidWZmZXIsIGFuZCBzZXRzIG5ieXRlcyB0byBpdHMgc2l6ZS4gVGhlIGNhbGxlciB0YWtlcworICAvLyBvd25lcnNoaXAgb2YgdGhlIGJ1ZmZlciBhbmQgbXVzdCBkZWxldGUgaXQgd2l0aCBkZWxldGVbXS4KKyAgY2hhciogR2V0QnVmZmVyKHNpemVfdCogbmJ5dGVzKTsKKworIHByaXZhdGU6CisgIHZvaWQgRXhwYW5kKHNpemVfdCBhbW91bnQpOworICB2b2lkIFNocmlua1RvRml0KCk7CisKKyAgc2l6ZV90IGNhcGFjaXR5XzsKKyAgY2hhciogYnVmXzsKKyAgc2l6ZV90IHNpemVfOworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoR3Jvd2luZ0FycmF5Qnl0ZVNpbmspOworfTsKKworLy8gSW1wbGVtZW50YXRpb24gb2YgQnl0ZVNpbmsgdGhhdCBhcHBlbmRzIHRvIHRoZSBnaXZlbiBzdHJpbmcuCisvLyBFeGlzdGluZyBjb250ZW50cyBvZiAiZGVzdCIgYXJlIG5vdCBtb2RpZmllZDsgbmV3IGRhdGEgaXMgYXBwZW5kZWQuCisvLworLy8gRXhhbXBsZToKKy8vCisvLyAgIHN0cmluZyBkZXN0ID0gIkhlbGxvICI7CisvLyAgIFN0cmluZ0J5dGVTaW5rIHNpbmsoJmRlc3QpOworLy8gICBzaW5rLkFwcGVuZCgiV29ybGQiLCA1KTsKKy8vICAgYXNzZXJ0KGRlc3QgPT0gIkhlbGxvIFdvcmxkIik7CisvLworY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFN0cmluZ0J5dGVTaW5rIDogcHVibGljIEJ5dGVTaW5rIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IFN0cmluZ0J5dGVTaW5rKHN0cmluZyogZGVzdCkgOiBkZXN0XyhkZXN0KSB7fQorICB2aXJ0dWFsIHZvaWQgQXBwZW5kKGNvbnN0IGNoYXIqIGRhdGEsIHNpemVfdCBuKTsKKworIHByaXZhdGU6CisgIHN0cmluZyogZGVzdF87CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhTdHJpbmdCeXRlU2luayk7Cit9OworCisvLyBJbXBsZW1lbnRhdGlvbiBvZiBCeXRlU2luayB0aGF0IGRpc2NhcmRzIGFsbCBkYXRhLgorLy8KKy8vIEV4YW1wbGU6CisvLworLy8gICBOdWxsQnl0ZVNpbmsgc2luazsKKy8vICAgc2luay5BcHBlbmQoZGF0YSwgZGF0YS5zaXplKCkpOyAgLy8gQWxsIGRhdGEgaWdub3JlZC4KKy8vCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgTnVsbEJ5dGVTaW5rIDogcHVibGljIEJ5dGVTaW5rIHsKKyBwdWJsaWM6CisgIE51bGxCeXRlU2luaygpIHt9CisgIHZpcnR1YWwgdm9pZCBBcHBlbmQoY29uc3QgY2hhciAqZGF0YSwgc2l6ZV90IG4pIHt9CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoTnVsbEJ5dGVTaW5rKTsKK307CisKKy8vCisvLyBTb21lIGNvbW1vbmx5IHVzZWQgaW1wbGVtZW50YXRpb25zIG9mIEJ5dGVTb3VyY2UKKy8vCisKKy8vIEltcGxlbWVudGF0aW9uIG9mIEJ5dGVTb3VyY2UgdGhhdCByZWFkcyBmcm9tIGEgU3RyaW5nUGllY2UuCisvLworLy8gRXhhbXBsZToKKy8vCisvLyAgIHN0cmluZyBkYXRhID0gIkhlbGxvIjsKKy8vICAgQXJyYXlCeXRlU291cmNlIHNvdXJjZShkYXRhKTsKKy8vICAgYXNzZXJ0KHNvdXJjZS5BdmFpbGFibGUoKSA9PSA1KTsKKy8vICAgYXNzZXJ0KHNvdXJjZS5QZWVrKCkgPT0gIkhlbGxvIik7CisvLworY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEFycmF5Qnl0ZVNvdXJjZSA6IHB1YmxpYyBCeXRlU291cmNlIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IEFycmF5Qnl0ZVNvdXJjZShTdHJpbmdQaWVjZSBzKSA6IGlucHV0XyhzKSB7fQorCisgIHZpcnR1YWwgc2l6ZV90IEF2YWlsYWJsZSgpIGNvbnN0OworICB2aXJ0dWFsIFN0cmluZ1BpZWNlIFBlZWsoKTsKKyAgdmlydHVhbCB2b2lkIFNraXAoc2l6ZV90IG4pOworCisgcHJpdmF0ZToKKyAgU3RyaW5nUGllY2UgICBpbnB1dF87CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhBcnJheUJ5dGVTb3VyY2UpOworfTsKKworLy8gSW1wbGVtZW50YXRpb24gb2YgQnl0ZVNvdXJjZSB0aGF0IHdyYXBzIGFub3RoZXIgQnl0ZVNvdXJjZSwgbGltaXRpbmcgdGhlCisvLyBudW1iZXIgb2YgYnl0ZXMgcmV0dXJuZWQuCisvLworLy8gVGhlIGNhbGxlciBtYWludGFpbnMgb3duZXJzaGlwIG9mIHRoZSB1bmRlcmx5aW5nIHNvdXJjZSwgYW5kIG1heSBub3QgdXNlIHRoZQorLy8gdW5kZXJseWluZyBzb3VyY2Ugd2hpbGUgdXNpbmcgdGhlIExpbWl0Qnl0ZVNvdXJjZSBvYmplY3QuICBUaGUgdW5kZXJseWluZworLy8gc291cmNlJ3MgcG9pbnRlciBpcyBhZHZhbmNlZCBieSBuIGJ5dGVzIGV2ZXJ5IHRpbWUgdGhpcyBMaW1pdEJ5dGVTb3VyY2UKKy8vIG9iamVjdCBpcyBhZHZhbmNlZCBieSBuLgorLy8KKy8vIEV4YW1wbGU6CisvLworLy8gICBzdHJpbmcgZGF0YSA9ICJIZWxsbyBXb3JsZCI7CisvLyAgIEFycmF5Qnl0ZVNvdXJjZSBhYnMoZGF0YSk7CisvLyAgIGFzc2VydChhYnMuQXZhaWxhYmxlKCkgPT0gZGF0YS5zaXplKCkpOworLy8KKy8vICAgTGltaXRCeXRlU291cmNlIGxpbWl0KGFicywgNSk7CisvLyAgIGFzc2VydChsaW1pdC5BdmFpbGFibGUoKSA9PSA1KTsKKy8vICAgYXNzZXJ0KGxpbWl0LlBlZWsoKSA9PSAiSGVsbG8iKTsKKy8vCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgTGltaXRCeXRlU291cmNlIDogcHVibGljIEJ5dGVTb3VyY2UgeworIHB1YmxpYzoKKyAgLy8gUmV0dXJucyBhdCBtb3N0ICJsaW1pdCIgYnl0ZXMgZnJvbSAic291cmNlIi4KKyAgTGltaXRCeXRlU291cmNlKEJ5dGVTb3VyY2UqIHNvdXJjZSwgc2l6ZV90IGxpbWl0KTsKKworICB2aXJ0dWFsIHNpemVfdCBBdmFpbGFibGUoKSBjb25zdDsKKyAgdmlydHVhbCBTdHJpbmdQaWVjZSBQZWVrKCk7CisgIHZpcnR1YWwgdm9pZCBTa2lwKHNpemVfdCBuKTsKKworICAvLyBXZSBvdmVycmlkZSBDb3B5VG8gc28gdGhhdCB3ZSBjYW4gZm9yd2FyZCB0byB0aGUgdW5kZXJseWluZyBzb3VyY2UsIGluCisgIC8vIGNhc2UgaXQgaGFzIGFuIGVmZmljaWVudCBpbXBsZW1lbnRhdGlvbiBvZiBDb3B5VG8uCisgIHZpcnR1YWwgdm9pZCBDb3B5VG8oQnl0ZVNpbmsqIHNpbmssIHNpemVfdCBuKTsKKworIHByaXZhdGU6CisgIEJ5dGVTb3VyY2UqIHNvdXJjZV87CisgIHNpemVfdCBsaW1pdF87Cit9OworCit9ICAvLyBuYW1lc3BhY2Ugc3RyaW5ncworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX1NUVUJTX0JZVEVTVFJFQU1fSF8KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYnl0ZXN0cmVhbV91bml0dGVzdC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvYnl0ZXN0cmVhbV91bml0dGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wNmYxMTRhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9ieXRlc3RyZWFtX3VuaXR0ZXN0LmNjCkBAIC0wLDAgKzEsMTQ2IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9ieXRlc3RyZWFtLmg+CisKKyNpbmNsdWRlIDxzdGRpby5oPgorI2luY2x1ZGUgPHN0cmluZy5oPgorI2luY2x1ZGUgPGFsZ29yaXRobT4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2dvb2dsZXRlc3QuaD4KKyNpbmNsdWRlIDxndGVzdC9ndGVzdC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2Ugc3RyaW5ncyB7CituYW1lc3BhY2UgeworCisvLyBXZSB1c2UgdGhpcyBjbGFzcyBpbnN0ZWFkIG9mIEFycmF5Qnl0ZVNvdXJjZSB0byBzaW11bGF0ZSBhIEJ5dGVTb3VyY2UgdGhhdAorLy8gY29udGFpbnMgbXVsdGlwbGUgZnJhZ21lbnRzLiAgQXJyYXlCeXRlU291cmNlIHJldHVybnMgdGhlIGVudGlyZSBhcnJheSBpbgorLy8gb25lIGZyYWdtZW50LgorY2xhc3MgTW9ja0J5dGVTb3VyY2UgOiBwdWJsaWMgQnl0ZVNvdXJjZSB7CisgcHVibGljOgorICBNb2NrQnl0ZVNvdXJjZShTdHJpbmdQaWVjZSBkYXRhLCBpbnQgYmxvY2tfc2l6ZSkKKyAgICA6IGRhdGFfKGRhdGEpLCBibG9ja19zaXplXyhibG9ja19zaXplKSB7fQorCisgIHNpemVfdCBBdmFpbGFibGUoKSBjb25zdCB7IHJldHVybiBkYXRhXy5zaXplKCk7IH0KKyAgU3RyaW5nUGllY2UgUGVlaygpIHsKKyAgICByZXR1cm4gZGF0YV8uc3Vic3RyKDAsIGJsb2NrX3NpemVfKTsKKyAgfQorICB2b2lkIFNraXAoc2l6ZV90IG4pIHsgZGF0YV8ucmVtb3ZlX3ByZWZpeChuKTsgfQorCisgcHJpdmF0ZToKKyAgU3RyaW5nUGllY2UgZGF0YV87CisgIGludCBibG9ja19zaXplXzsKK307CisKK1RFU1QoQnl0ZVNvdXJjZVRlc3QsIENvcHlUbykgeworICBTdHJpbmdQaWVjZSBkYXRhKCJIZWxsbyB3b3JsZCEiKTsKKyAgTW9ja0J5dGVTb3VyY2Ugc291cmNlKGRhdGEsIDMpOworICBzdHJpbmcgc3RyOworICBTdHJpbmdCeXRlU2luayBzaW5rKCZzdHIpOworCisgIHNvdXJjZS5Db3B5VG8oJnNpbmssIGRhdGEuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKGRhdGEsIHN0cik7Cit9CisKK1RFU1QoQnl0ZVNvdXJjZVRlc3QsIENvcHlTdWJzdHJpbmdUbykgeworICBTdHJpbmdQaWVjZSBkYXRhKCJIZWxsbyB3b3JsZCEiKTsKKyAgTW9ja0J5dGVTb3VyY2Ugc291cmNlKGRhdGEsIDMpOworICBzb3VyY2UuU2tpcCgxKTsKKyAgc3RyaW5nIHN0cjsKKyAgU3RyaW5nQnl0ZVNpbmsgc2luaygmc3RyKTsKKworICBzb3VyY2UuQ29weVRvKCZzaW5rLCBkYXRhLnNpemUoKSAtIDIpOworICBFWFBFQ1RfRVEoZGF0YS5zdWJzdHIoMSwgZGF0YS5zaXplKCkgLSAyKSwgc3RyKTsKKyAgRVhQRUNUX0VRKCIhIiwgc291cmNlLlBlZWsoKSk7Cit9CisKK1RFU1QoQnl0ZVNvdXJjZVRlc3QsIExpbWl0Qnl0ZVNvdXJjZSkgeworICBTdHJpbmdQaWVjZSBkYXRhKCJIZWxsbyB3b3JsZCEiKTsKKyAgTW9ja0J5dGVTb3VyY2Ugc291cmNlKGRhdGEsIDMpOworICBMaW1pdEJ5dGVTb3VyY2UgbGltaXRfc291cmNlKCZzb3VyY2UsIDYpOworICBFWFBFQ1RfRVEoNiwgbGltaXRfc291cmNlLkF2YWlsYWJsZSgpKTsKKyAgbGltaXRfc291cmNlLlNraXAoMSk7CisgIEVYUEVDVF9FUSg1LCBsaW1pdF9zb3VyY2UuQXZhaWxhYmxlKCkpOworCisgIHsKKyAgICBzdHJpbmcgc3RyOworICAgIFN0cmluZ0J5dGVTaW5rIHNpbmsoJnN0cik7CisgICAgbGltaXRfc291cmNlLkNvcHlUbygmc2luaywgbGltaXRfc291cmNlLkF2YWlsYWJsZSgpKTsKKyAgICBFWFBFQ1RfRVEoImVsbG8gIiwgc3RyKTsKKyAgICBFWFBFQ1RfRVEoMCwgbGltaXRfc291cmNlLkF2YWlsYWJsZSgpKTsKKyAgICBFWFBFQ1RfRVEoNiwgc291cmNlLkF2YWlsYWJsZSgpKTsKKyAgfQorCisgIHsKKyAgICBzdHJpbmcgc3RyOworICAgIFN0cmluZ0J5dGVTaW5rIHNpbmsoJnN0cik7CisgICAgc291cmNlLkNvcHlUbygmc2luaywgc291cmNlLkF2YWlsYWJsZSgpKTsKKyAgICBFWFBFQ1RfRVEoIndvcmxkISIsIHN0cik7CisgICAgRVhQRUNUX0VRKDAsIHNvdXJjZS5BdmFpbGFibGUoKSk7CisgIH0KK30KKworVEVTVChCeXRlU291cmNlVGVzdCwgQ29weVRvU3RyaW5nQnl0ZVNpbmspIHsKKyAgU3RyaW5nUGllY2UgZGF0YSgiSGVsbG8gd29ybGQhIik7CisgIE1vY2tCeXRlU291cmNlIHNvdXJjZShkYXRhLCAzKTsKKyAgc3RyaW5nIHN0cjsKKyAgU3RyaW5nQnl0ZVNpbmsgc2luaygmc3RyKTsKKyAgc291cmNlLkNvcHlUbygmc2luaywgZGF0YS5zaXplKCkpOworICBFWFBFQ1RfRVEoZGF0YSwgc3RyKTsKK30KKworLy8gVmVyaWZ5IHRoYXQgQnl0ZVNpbmsgaXMgc3ViY2xhc3NhYmxlIGFuZCBGbHVzaCgpIG92ZXJyaWRhYmxlLgorY2xhc3MgRmx1c2hpbmdCeXRlU2luayA6IHB1YmxpYyBTdHJpbmdCeXRlU2luayB7CisgcHVibGljOgorICBleHBsaWNpdCBGbHVzaGluZ0J5dGVTaW5rKHN0cmluZyogZGVzdCkgOiBTdHJpbmdCeXRlU2luayhkZXN0KSB7fQorICB2aXJ0dWFsIHZvaWQgRmx1c2goKSB7IEFwcGVuZCgieiIsIDEpOyB9CisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEZsdXNoaW5nQnl0ZVNpbmspOworfTsKKworLy8gV3JpdGUgYW5kIEZsdXNoIHZpYSB0aGUgQnl0ZVNpbmsgc3VwZXJjbGFzcyBpbnRlcmZhY2UuCit2b2lkIFdyaXRlQW5kRmx1c2goQnl0ZVNpbmsqIHMpIHsKKyAgcy0+QXBwZW5kKCJhYmMiLCAzKTsKKyAgcy0+Rmx1c2goKTsKK30KKworVEVTVChCeXRlU2lua1Rlc3QsIEZsdXNoKSB7CisgIHN0cmluZyBzdHI7CisgIEZsdXNoaW5nQnl0ZVNpbmsgZl9zaW5rKCZzdHIpOworICBXcml0ZUFuZEZsdXNoKCZmX3NpbmspOworICBFWFBFQ1RfU1RSRVEoImFiY3oiLCBzdHIuY19zdHIoKSk7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorfSAgLy8gbmFtZXNwYWNlIHN0cmluZ3MKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9jYWxsYmFjay5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9jYWxsYmFjay5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg3MjcxYzUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NhbGxiYWNrLmgKQEAgLTAsMCArMSw1NDYgQEAKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX1NUVUJTX0NBTExCQUNLX0hfCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9TVFVCU19DQUxMQkFDS19IXworCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL21hY3Jvcy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy90eXBlX3RyYWl0cy5oPgorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisvLyBlbXVsYXRlcyBnb29nbGUzL2Jhc2UvY2FsbGJhY2suaAorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKKy8vIEFic3RyYWN0IGludGVyZmFjZSBmb3IgYSBjYWxsYmFjay4gIFdoZW4gY2FsbGluZyBhbiBSUEMsIHlvdSBtdXN0IHByb3ZpZGUKKy8vIGEgQ2xvc3VyZSB0byBjYWxsIHdoZW4gdGhlIHByb2NlZHVyZSBjb21wbGV0ZXMuICBTZWUgdGhlIFNlcnZpY2UgaW50ZXJmYWNlCisvLyBpbiBzZXJ2aWNlLmguCisvLworLy8gVG8gYXV0b21hdGljYWxseSBjb25zdHJ1Y3QgYSBDbG9zdXJlIHdoaWNoIGNhbGxzIGEgcGFydGljdWxhciBmdW5jdGlvbiBvcgorLy8gbWV0aG9kIHdpdGggYSBwYXJ0aWN1bGFyIHNldCBvZiBwYXJhbWV0ZXJzLCB1c2UgdGhlIE5ld0NhbGxiYWNrKCkgZnVuY3Rpb24uCisvLyBFeGFtcGxlOgorLy8gICB2b2lkIEZvb0RvbmUoY29uc3QgRm9vUmVzcG9uc2UqIHJlc3BvbnNlKSB7CisvLyAgICAgLi4uCisvLyAgIH0KKy8vCisvLyAgIHZvaWQgQ2FsbEZvbygpIHsKKy8vICAgICAuLi4KKy8vICAgICAvLyBXaGVuIGRvbmUsIGNhbGwgRm9vRG9uZSgpIGFuZCBwYXNzIGl0IGEgcG9pbnRlciB0byB0aGUgcmVzcG9uc2UuCisvLyAgICAgQ2xvc3VyZSogY2FsbGJhY2sgPSBOZXdDYWxsYmFjaygmRm9vRG9uZSwgcmVzcG9uc2UpOworLy8gICAgIC8vIE1ha2UgdGhlIGNhbGwuCisvLyAgICAgc2VydmljZS0+Rm9vKGNvbnRyb2xsZXIsIHJlcXVlc3QsIHJlc3BvbnNlLCBjYWxsYmFjayk7CisvLyAgIH0KKy8vCisvLyBFeGFtcGxlIHRoYXQgY2FsbHMgYSBtZXRob2Q6CisvLyAgIGNsYXNzIEhhbmRsZXIgeworLy8gICAgcHVibGljOgorLy8gICAgIC4uLgorLy8KKy8vICAgICB2b2lkIEZvb0RvbmUoY29uc3QgRm9vUmVzcG9uc2UqIHJlc3BvbnNlKSB7CisvLyAgICAgICAuLi4KKy8vICAgICB9CisvLworLy8gICAgIHZvaWQgQ2FsbEZvbygpIHsKKy8vICAgICAgIC4uLgorLy8gICAgICAgLy8gV2hlbiBkb25lLCBjYWxsIEZvb0RvbmUoKSBhbmQgcGFzcyBpdCBhIHBvaW50ZXIgdG8gdGhlIHJlc3BvbnNlLgorLy8gICAgICAgQ2xvc3VyZSogY2FsbGJhY2sgPSBOZXdDYWxsYmFjayh0aGlzLCAmSGFuZGxlcjo6Rm9vRG9uZSwgcmVzcG9uc2UpOworLy8gICAgICAgLy8gTWFrZSB0aGUgY2FsbC4KKy8vICAgICAgIHNlcnZpY2UtPkZvbyhjb250cm9sbGVyLCByZXF1ZXN0LCByZXNwb25zZSwgY2FsbGJhY2spOworLy8gICAgIH0KKy8vICAgfTsKKy8vCisvLyBDdXJyZW50bHkgTmV3Q2FsbGJhY2soKSBzdXBwb3J0cyBiaW5kaW5nIHplcm8sIG9uZSwgb3IgdHdvIGFyZ3VtZW50cy4KKy8vCisvLyBDYWxsYmFja3MgY3JlYXRlZCB3aXRoIE5ld0NhbGxiYWNrKCkgYXV0b21hdGljYWxseSBkZWxldGUgdGhlbXNlbHZlcyB3aGVuCisvLyBleGVjdXRlZC4gIFRoZXkgc2hvdWxkIGJlIHVzZWQgd2hlbiBhIGNhbGxiYWNrIGlzIHRvIGJlIGNhbGxlZCBleGFjdGx5CisvLyBvbmNlICh1c3VhbGx5IHRoZSBjYXNlIHdpdGggUlBDIGNhbGxiYWNrcykuICBJZiBhIGNhbGxiYWNrIG1heSBiZSBjYWxsZWQKKy8vIGEgZGlmZmVyZW50IG51bWJlciBvZiB0aW1lcyAoaW5jbHVkaW5nIHplcm8pLCBjcmVhdGUgaXQgd2l0aAorLy8gTmV3UGVybWFuZW50Q2FsbGJhY2soKSBpbnN0ZWFkLiAgWW91IGFyZSB0aGVuIHJlc3BvbnNpYmxlIGZvciBkZWxldGluZyB0aGUKKy8vIGNhbGxiYWNrICh1c2luZyB0aGUgImRlbGV0ZSIga2V5d29yZCBhcyBub3JtYWwpLgorLy8KKy8vIE5vdGUgdGhhdCBOZXdDYWxsYmFjaygpIGlzIGEgYml0IHRvdWNoeSByZWdhcmRpbmcgYXJndW1lbnQgdHlwZXMuICBHZW5lcmFsbHksCisvLyB0aGUgdmFsdWVzIHlvdSBwcm92aWRlIGZvciB0aGUgcGFyYW1ldGVyIGJpbmRpbmdzIG11c3QgZXhhY3RseSBtYXRjaCB0aGUKKy8vIHR5cGVzIGFjY2VwdGVkIGJ5IHRoZSBjYWxsYmFjayBmdW5jdGlvbi4gIEZvciBleGFtcGxlOgorLy8gICB2b2lkIEZvbyhzdHJpbmcgcyk7CisvLyAgIE5ld0NhbGxiYWNrKCZGb28sICJmb28iKTsgICAgICAgICAgLy8gV09OJ1QgV09SSzogIGNvbnN0IGNoYXIqICE9IHN0cmluZworLy8gICBOZXdDYWxsYmFjaygmRm9vLCBzdHJpbmcoImZvbyIpKTsgIC8vIFdPUktTCisvLyBBbHNvIG5vdGUgdGhhdCB0aGUgYXJndW1lbnRzIGNhbm5vdCBiZSByZWZlcmVuY2VzOgorLy8gICB2b2lkIEZvbyhjb25zdCBzdHJpbmcmIHMpOworLy8gICBzdHJpbmcgbXlfc3RyOworLy8gICBOZXdDYWxsYmFjaygmRm9vLCBteV9zdHIpOyAgLy8gV09OJ1QgV09SSzogIENhbid0IHVzZSByZWZlcmVjbmVzLgorLy8gSG93ZXZlciwgY29ycmVjdGx5LXR5cGVkIHBvaW50ZXJzIHdpbGwgd29yayBqdXN0IGZpbmUuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgQ2xvc3VyZSB7CisgcHVibGljOgorICBDbG9zdXJlKCkge30KKyAgdmlydHVhbCB+Q2xvc3VyZSgpOworCisgIHZpcnR1YWwgdm9pZCBSdW4oKSA9IDA7CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoQ2xvc3VyZSk7Cit9OworCit0ZW1wbGF0ZTx0eXBlbmFtZSBSPgorY2xhc3MgUmVzdWx0Q2FsbGJhY2sgeworIHB1YmxpYzoKKyAgUmVzdWx0Q2FsbGJhY2soKSB7fQorICB2aXJ0dWFsIH5SZXN1bHRDYWxsYmFjaygpIHt9CisKKyAgdmlydHVhbCBSIFJ1bigpID0gMDsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhSZXN1bHRDYWxsYmFjayk7Cit9OworCit0ZW1wbGF0ZTx0eXBlbmFtZSBSLCB0eXBlbmFtZSBBMT4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBSZXN1bHRDYWxsYmFjazEgeworIHB1YmxpYzoKKyAgUmVzdWx0Q2FsbGJhY2sxKCkge30KKyAgdmlydHVhbCB+UmVzdWx0Q2FsbGJhY2sxKCkge30KKworICB2aXJ0dWFsIFIgUnVuKEExKSA9IDA7CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoUmVzdWx0Q2FsbGJhY2sxKTsKK307CisKK3RlbXBsYXRlPHR5cGVuYW1lIFIsIHR5cGVuYW1lIEExLCB0eXBlbmFtZSBBMj4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBSZXN1bHRDYWxsYmFjazIgeworIHB1YmxpYzoKKyAgUmVzdWx0Q2FsbGJhY2syKCkge30KKyAgdmlydHVhbCB+UmVzdWx0Q2FsbGJhY2syKCkge30KKworICB2aXJ0dWFsIFIgUnVuKEExLEEyKSA9IDA7CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoUmVzdWx0Q2FsbGJhY2syKTsKK307CisKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBGdW5jdGlvbkNsb3N1cmUwIDogcHVibGljIENsb3N1cmUgeworIHB1YmxpYzoKKyAgdHlwZWRlZiB2b2lkICgqRnVuY3Rpb25UeXBlKSgpOworCisgIEZ1bmN0aW9uQ2xvc3VyZTAoRnVuY3Rpb25UeXBlIGZ1bmN0aW9uLCBib29sIHNlbGZfZGVsZXRpbmcpCisgICAgOiBmdW5jdGlvbl8oZnVuY3Rpb24pLCBzZWxmX2RlbGV0aW5nXyhzZWxmX2RlbGV0aW5nKSB7fQorICB+RnVuY3Rpb25DbG9zdXJlMCgpOworCisgIHZvaWQgUnVuKCkgeworICAgIGJvb2wgbmVlZHNfZGVsZXRlID0gc2VsZl9kZWxldGluZ187ICAvLyByZWFkIGluIGNhc2UgY2FsbGJhY2sgZGVsZXRlcworICAgIGZ1bmN0aW9uXygpOworICAgIGlmIChuZWVkc19kZWxldGUpIGRlbGV0ZSB0aGlzOworICB9CisKKyBwcml2YXRlOgorICBGdW5jdGlvblR5cGUgZnVuY3Rpb25fOworICBib29sIHNlbGZfZGVsZXRpbmdfOworfTsKKwordGVtcGxhdGUgPHR5cGVuYW1lIENsYXNzPgorY2xhc3MgTWV0aG9kQ2xvc3VyZTAgOiBwdWJsaWMgQ2xvc3VyZSB7CisgcHVibGljOgorICB0eXBlZGVmIHZvaWQgKENsYXNzOjoqTWV0aG9kVHlwZSkoKTsKKworICBNZXRob2RDbG9zdXJlMChDbGFzcyogb2JqZWN0LCBNZXRob2RUeXBlIG1ldGhvZCwgYm9vbCBzZWxmX2RlbGV0aW5nKQorICAgIDogb2JqZWN0XyhvYmplY3QpLCBtZXRob2RfKG1ldGhvZCksIHNlbGZfZGVsZXRpbmdfKHNlbGZfZGVsZXRpbmcpIHt9CisgIH5NZXRob2RDbG9zdXJlMCgpIHt9CisKKyAgdm9pZCBSdW4oKSB7CisgICAgYm9vbCBuZWVkc19kZWxldGUgPSBzZWxmX2RlbGV0aW5nXzsgIC8vIHJlYWQgaW4gY2FzZSBjYWxsYmFjayBkZWxldGVzCisgICAgKG9iamVjdF8tPiptZXRob2RfKSgpOworICAgIGlmIChuZWVkc19kZWxldGUpIGRlbGV0ZSB0aGlzOworICB9CisKKyBwcml2YXRlOgorICBDbGFzcyogb2JqZWN0XzsKKyAgTWV0aG9kVHlwZSBtZXRob2RfOworICBib29sIHNlbGZfZGVsZXRpbmdfOworfTsKKwordGVtcGxhdGUgPHR5cGVuYW1lIEFyZzE+CitjbGFzcyBGdW5jdGlvbkNsb3N1cmUxIDogcHVibGljIENsb3N1cmUgeworIHB1YmxpYzoKKyAgdHlwZWRlZiB2b2lkICgqRnVuY3Rpb25UeXBlKShBcmcxIGFyZzEpOworCisgIEZ1bmN0aW9uQ2xvc3VyZTEoRnVuY3Rpb25UeXBlIGZ1bmN0aW9uLCBib29sIHNlbGZfZGVsZXRpbmcsCisgICAgICAgICAgICAgICAgICAgQXJnMSBhcmcxKQorICAgIDogZnVuY3Rpb25fKGZ1bmN0aW9uKSwgc2VsZl9kZWxldGluZ18oc2VsZl9kZWxldGluZyksCisgICAgICBhcmcxXyhhcmcxKSB7fQorICB+RnVuY3Rpb25DbG9zdXJlMSgpIHt9CisKKyAgdm9pZCBSdW4oKSB7CisgICAgYm9vbCBuZWVkc19kZWxldGUgPSBzZWxmX2RlbGV0aW5nXzsgIC8vIHJlYWQgaW4gY2FzZSBjYWxsYmFjayBkZWxldGVzCisgICAgZnVuY3Rpb25fKGFyZzFfKTsKKyAgICBpZiAobmVlZHNfZGVsZXRlKSBkZWxldGUgdGhpczsKKyAgfQorCisgcHJpdmF0ZToKKyAgRnVuY3Rpb25UeXBlIGZ1bmN0aW9uXzsKKyAgYm9vbCBzZWxmX2RlbGV0aW5nXzsKKyAgQXJnMSBhcmcxXzsKK307CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBDbGFzcywgdHlwZW5hbWUgQXJnMT4KK2NsYXNzIE1ldGhvZENsb3N1cmUxIDogcHVibGljIENsb3N1cmUgeworIHB1YmxpYzoKKyAgdHlwZWRlZiB2b2lkIChDbGFzczo6Kk1ldGhvZFR5cGUpKEFyZzEgYXJnMSk7CisKKyAgTWV0aG9kQ2xvc3VyZTEoQ2xhc3MqIG9iamVjdCwgTWV0aG9kVHlwZSBtZXRob2QsIGJvb2wgc2VsZl9kZWxldGluZywKKyAgICAgICAgICAgICAgICAgQXJnMSBhcmcxKQorICAgIDogb2JqZWN0XyhvYmplY3QpLCBtZXRob2RfKG1ldGhvZCksIHNlbGZfZGVsZXRpbmdfKHNlbGZfZGVsZXRpbmcpLAorICAgICAgYXJnMV8oYXJnMSkge30KKyAgfk1ldGhvZENsb3N1cmUxKCkge30KKworICB2b2lkIFJ1bigpIHsKKyAgICBib29sIG5lZWRzX2RlbGV0ZSA9IHNlbGZfZGVsZXRpbmdfOyAgLy8gcmVhZCBpbiBjYXNlIGNhbGxiYWNrIGRlbGV0ZXMKKyAgICAob2JqZWN0Xy0+Km1ldGhvZF8pKGFyZzFfKTsKKyAgICBpZiAobmVlZHNfZGVsZXRlKSBkZWxldGUgdGhpczsKKyAgfQorCisgcHJpdmF0ZToKKyAgQ2xhc3MqIG9iamVjdF87CisgIE1ldGhvZFR5cGUgbWV0aG9kXzsKKyAgYm9vbCBzZWxmX2RlbGV0aW5nXzsKKyAgQXJnMSBhcmcxXzsKK307CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBBcmcxLCB0eXBlbmFtZSBBcmcyPgorY2xhc3MgRnVuY3Rpb25DbG9zdXJlMiA6IHB1YmxpYyBDbG9zdXJlIHsKKyBwdWJsaWM6CisgIHR5cGVkZWYgdm9pZCAoKkZ1bmN0aW9uVHlwZSkoQXJnMSBhcmcxLCBBcmcyIGFyZzIpOworCisgIEZ1bmN0aW9uQ2xvc3VyZTIoRnVuY3Rpb25UeXBlIGZ1bmN0aW9uLCBib29sIHNlbGZfZGVsZXRpbmcsCisgICAgICAgICAgICAgICAgICAgQXJnMSBhcmcxLCBBcmcyIGFyZzIpCisgICAgOiBmdW5jdGlvbl8oZnVuY3Rpb24pLCBzZWxmX2RlbGV0aW5nXyhzZWxmX2RlbGV0aW5nKSwKKyAgICAgIGFyZzFfKGFyZzEpLCBhcmcyXyhhcmcyKSB7fQorICB+RnVuY3Rpb25DbG9zdXJlMigpIHt9CisKKyAgdm9pZCBSdW4oKSB7CisgICAgYm9vbCBuZWVkc19kZWxldGUgPSBzZWxmX2RlbGV0aW5nXzsgIC8vIHJlYWQgaW4gY2FzZSBjYWxsYmFjayBkZWxldGVzCisgICAgZnVuY3Rpb25fKGFyZzFfLCBhcmcyXyk7CisgICAgaWYgKG5lZWRzX2RlbGV0ZSkgZGVsZXRlIHRoaXM7CisgIH0KKworIHByaXZhdGU6CisgIEZ1bmN0aW9uVHlwZSBmdW5jdGlvbl87CisgIGJvb2wgc2VsZl9kZWxldGluZ187CisgIEFyZzEgYXJnMV87CisgIEFyZzIgYXJnMl87Cit9OworCit0ZW1wbGF0ZSA8dHlwZW5hbWUgQ2xhc3MsIHR5cGVuYW1lIEFyZzEsIHR5cGVuYW1lIEFyZzI+CitjbGFzcyBNZXRob2RDbG9zdXJlMiA6IHB1YmxpYyBDbG9zdXJlIHsKKyBwdWJsaWM6CisgIHR5cGVkZWYgdm9pZCAoQ2xhc3M6OipNZXRob2RUeXBlKShBcmcxIGFyZzEsIEFyZzIgYXJnMik7CisKKyAgTWV0aG9kQ2xvc3VyZTIoQ2xhc3MqIG9iamVjdCwgTWV0aG9kVHlwZSBtZXRob2QsIGJvb2wgc2VsZl9kZWxldGluZywKKyAgICAgICAgICAgICAgICAgQXJnMSBhcmcxLCBBcmcyIGFyZzIpCisgICAgOiBvYmplY3RfKG9iamVjdCksIG1ldGhvZF8obWV0aG9kKSwgc2VsZl9kZWxldGluZ18oc2VsZl9kZWxldGluZyksCisgICAgICBhcmcxXyhhcmcxKSwgYXJnMl8oYXJnMikge30KKyAgfk1ldGhvZENsb3N1cmUyKCkge30KKworICB2b2lkIFJ1bigpIHsKKyAgICBib29sIG5lZWRzX2RlbGV0ZSA9IHNlbGZfZGVsZXRpbmdfOyAgLy8gcmVhZCBpbiBjYXNlIGNhbGxiYWNrIGRlbGV0ZXMKKyAgICAob2JqZWN0Xy0+Km1ldGhvZF8pKGFyZzFfLCBhcmcyXyk7CisgICAgaWYgKG5lZWRzX2RlbGV0ZSkgZGVsZXRlIHRoaXM7CisgIH0KKworIHByaXZhdGU6CisgIENsYXNzKiBvYmplY3RfOworICBNZXRob2RUeXBlIG1ldGhvZF87CisgIGJvb2wgc2VsZl9kZWxldGluZ187CisgIEFyZzEgYXJnMV87CisgIEFyZzIgYXJnMl87Cit9OworCit0ZW1wbGF0ZTx0eXBlbmFtZSBSPgorY2xhc3MgRnVuY3Rpb25SZXN1bHRDYWxsYmFja18wXzAgOiBwdWJsaWMgUmVzdWx0Q2FsbGJhY2s8Uj4geworIHB1YmxpYzoKKyAgdHlwZWRlZiBSICgqRnVuY3Rpb25UeXBlKSgpOworCisgIEZ1bmN0aW9uUmVzdWx0Q2FsbGJhY2tfMF8wKEZ1bmN0aW9uVHlwZSBmdW5jdGlvbiwgYm9vbCBzZWxmX2RlbGV0aW5nKQorICAgICAgOiBmdW5jdGlvbl8oZnVuY3Rpb24pLCBzZWxmX2RlbGV0aW5nXyhzZWxmX2RlbGV0aW5nKSB7fQorICB+RnVuY3Rpb25SZXN1bHRDYWxsYmFja18wXzAoKSB7fQorCisgIFIgUnVuKCkgeworICAgIGJvb2wgbmVlZHNfZGVsZXRlID0gc2VsZl9kZWxldGluZ187ICAvLyByZWFkIGluIGNhc2UgY2FsbGJhY2sgZGVsZXRlcworICAgIFIgcmVzdWx0ID0gZnVuY3Rpb25fKCk7CisgICAgaWYgKG5lZWRzX2RlbGV0ZSkgZGVsZXRlIHRoaXM7CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorCisgcHJpdmF0ZToKKyAgRnVuY3Rpb25UeXBlIGZ1bmN0aW9uXzsKKyAgYm9vbCBzZWxmX2RlbGV0aW5nXzsKK307CisKK3RlbXBsYXRlPHR5cGVuYW1lIFIsIHR5cGVuYW1lIFAxPgorY2xhc3MgRnVuY3Rpb25SZXN1bHRDYWxsYmFja18xXzAgOiBwdWJsaWMgUmVzdWx0Q2FsbGJhY2s8Uj4geworIHB1YmxpYzoKKyAgdHlwZWRlZiBSICgqRnVuY3Rpb25UeXBlKShQMSk7CisKKyAgRnVuY3Rpb25SZXN1bHRDYWxsYmFja18xXzAoRnVuY3Rpb25UeXBlIGZ1bmN0aW9uLCBib29sIHNlbGZfZGVsZXRpbmcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFAxIHAxKQorICAgICAgOiBmdW5jdGlvbl8oZnVuY3Rpb24pLCBzZWxmX2RlbGV0aW5nXyhzZWxmX2RlbGV0aW5nKSwgcDFfKHAxKSB7fQorICB+RnVuY3Rpb25SZXN1bHRDYWxsYmFja18xXzAoKSB7fQorCisgIFIgUnVuKCkgeworICAgIGJvb2wgbmVlZHNfZGVsZXRlID0gc2VsZl9kZWxldGluZ187ICAvLyByZWFkIGluIGNhc2UgY2FsbGJhY2sgZGVsZXRlcworICAgIFIgcmVzdWx0ID0gZnVuY3Rpb25fKHAxXyk7CisgICAgaWYgKG5lZWRzX2RlbGV0ZSkgZGVsZXRlIHRoaXM7CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorCisgcHJpdmF0ZToKKyAgRnVuY3Rpb25UeXBlIGZ1bmN0aW9uXzsKKyAgYm9vbCBzZWxmX2RlbGV0aW5nXzsKKyAgUDEgcDFfOworfTsKKwordGVtcGxhdGU8dHlwZW5hbWUgUiwgdHlwZW5hbWUgQXJnMT4KK2NsYXNzIEZ1bmN0aW9uUmVzdWx0Q2FsbGJhY2tfMF8xIDogcHVibGljIFJlc3VsdENhbGxiYWNrMTxSLCBBcmcxPiB7CisgcHVibGljOgorICB0eXBlZGVmIFIgKCpGdW5jdGlvblR5cGUpKEFyZzEgYXJnMSk7CisKKyAgRnVuY3Rpb25SZXN1bHRDYWxsYmFja18wXzEoRnVuY3Rpb25UeXBlIGZ1bmN0aW9uLCBib29sIHNlbGZfZGVsZXRpbmcpCisgICAgICA6IGZ1bmN0aW9uXyhmdW5jdGlvbiksIHNlbGZfZGVsZXRpbmdfKHNlbGZfZGVsZXRpbmcpIHt9CisgIH5GdW5jdGlvblJlc3VsdENhbGxiYWNrXzBfMSgpIHt9CisKKyAgUiBSdW4oQXJnMSBhMSkgeworICAgIGJvb2wgbmVlZHNfZGVsZXRlID0gc2VsZl9kZWxldGluZ187ICAvLyByZWFkIGluIGNhc2UgY2FsbGJhY2sgZGVsZXRlcworICAgIFIgcmVzdWx0ID0gZnVuY3Rpb25fKGExKTsKKyAgICBpZiAobmVlZHNfZGVsZXRlKSBkZWxldGUgdGhpczsKKyAgICByZXR1cm4gcmVzdWx0OworICB9CisKKyBwcml2YXRlOgorICBGdW5jdGlvblR5cGUgZnVuY3Rpb25fOworICBib29sIHNlbGZfZGVsZXRpbmdfOworfTsKKwordGVtcGxhdGU8dHlwZW5hbWUgUiwgdHlwZW5hbWUgUDEsIHR5cGVuYW1lIEExPgorY2xhc3MgRnVuY3Rpb25SZXN1bHRDYWxsYmFja18xXzEgOiBwdWJsaWMgUmVzdWx0Q2FsbGJhY2sxPFIsIEExPiB7CisgcHVibGljOgorICB0eXBlZGVmIFIgKCpGdW5jdGlvblR5cGUpKFAxLCBBMSk7CisKKyAgRnVuY3Rpb25SZXN1bHRDYWxsYmFja18xXzEoRnVuY3Rpb25UeXBlIGZ1bmN0aW9uLCBib29sIHNlbGZfZGVsZXRpbmcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFAxIHAxKQorICAgICAgOiBmdW5jdGlvbl8oZnVuY3Rpb24pLCBzZWxmX2RlbGV0aW5nXyhzZWxmX2RlbGV0aW5nKSwgcDFfKHAxKSB7fQorICB+RnVuY3Rpb25SZXN1bHRDYWxsYmFja18xXzEoKSB7fQorCisgIFIgUnVuKEExIGExKSB7CisgICAgYm9vbCBuZWVkc19kZWxldGUgPSBzZWxmX2RlbGV0aW5nXzsgIC8vIHJlYWQgaW4gY2FzZSBjYWxsYmFjayBkZWxldGVzCisgICAgUiByZXN1bHQgPSBmdW5jdGlvbl8ocDFfLCBhMSk7CisgICAgaWYgKG5lZWRzX2RlbGV0ZSkgZGVsZXRlIHRoaXM7CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorCisgcHJpdmF0ZToKKyAgRnVuY3Rpb25UeXBlIGZ1bmN0aW9uXzsKKyAgYm9vbCBzZWxmX2RlbGV0aW5nXzsKKyAgUDEgcDFfOworfTsKKwordGVtcGxhdGUgPHR5cGVuYW1lIFQ+CitzdHJ1Y3QgSW50ZXJuYWxDb25zdFJlZiB7CisgIHR5cGVkZWYgdHlwZW5hbWUgcmVtb3ZlX3JlZmVyZW5jZTxUPjo6dHlwZSBiYXNlX3R5cGU7CisgIHR5cGVkZWYgY29uc3QgYmFzZV90eXBlJiB0eXBlOworfTsKKwordGVtcGxhdGUgPHR5cGVuYW1lIFIsIHR5cGVuYW1lIFQsIHR5cGVuYW1lIFAxLCB0eXBlbmFtZSBQMiwgdHlwZW5hbWUgUDMsCisgICAgICAgICAgdHlwZW5hbWUgUDQsIHR5cGVuYW1lIFA1LCB0eXBlbmFtZSBBMSwgdHlwZW5hbWUgQTI+CitjbGFzcyBNZXRob2RSZXN1bHRDYWxsYmFja181XzIgOiBwdWJsaWMgUmVzdWx0Q2FsbGJhY2syPFIsIEExLCBBMj4geworIHB1YmxpYzoKKyAgdHlwZWRlZiBSIChUOjoqTWV0aG9kVHlwZSkoUDEsIFAyLCBQMywgUDQsIFA1LCBBMSwgQTIpOworICBNZXRob2RSZXN1bHRDYWxsYmFja181XzIoVCogb2JqZWN0LCBNZXRob2RUeXBlIG1ldGhvZCwgYm9vbCBzZWxmX2RlbGV0aW5nLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgUDEgcDEsIFAyIHAyLCBQMyBwMywgUDQgcDQsIFA1IHA1KQorICAgICAgOiBvYmplY3RfKG9iamVjdCksCisgICAgICAgIG1ldGhvZF8obWV0aG9kKSwKKyAgICAgICAgc2VsZl9kZWxldGluZ18oc2VsZl9kZWxldGluZyksCisgICAgICAgIHAxXyhwMSksCisgICAgICAgIHAyXyhwMiksCisgICAgICAgIHAzXyhwMyksCisgICAgICAgIHA0XyhwNCksCisgICAgICAgIHA1XyhwNSkge30KKyAgfk1ldGhvZFJlc3VsdENhbGxiYWNrXzVfMigpIHt9CisKKyAgUiBSdW4oQTEgYTEsIEEyIGEyKSB7CisgICAgYm9vbCBuZWVkc19kZWxldGUgPSBzZWxmX2RlbGV0aW5nXzsKKyAgICBSIHJlc3VsdCA9IChvYmplY3RfLT4qbWV0aG9kXykocDFfLCBwMl8sIHAzXywgcDRfLCBwNV8sIGExLCBhMik7CisgICAgaWYgKG5lZWRzX2RlbGV0ZSkgZGVsZXRlIHRoaXM7CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorCisgcHJpdmF0ZToKKyAgVCogb2JqZWN0XzsKKyAgTWV0aG9kVHlwZSBtZXRob2RfOworICBib29sIHNlbGZfZGVsZXRpbmdfOworICB0eXBlbmFtZSByZW1vdmVfcmVmZXJlbmNlPFAxPjo6dHlwZSBwMV87CisgIHR5cGVuYW1lIHJlbW92ZV9yZWZlcmVuY2U8UDI+Ojp0eXBlIHAyXzsKKyAgdHlwZW5hbWUgcmVtb3ZlX3JlZmVyZW5jZTxQMz46OnR5cGUgcDNfOworICB0eXBlbmFtZSByZW1vdmVfcmVmZXJlbmNlPFA0Pjo6dHlwZSBwNF87CisgIHR5cGVuYW1lIHJlbW92ZV9yZWZlcmVuY2U8UDU+Ojp0eXBlIHA1XzsKK307CisKKy8vIFNlZSBDbG9zdXJlLgoraW5saW5lIENsb3N1cmUqIE5ld0NhbGxiYWNrKHZvaWQgKCpmdW5jdGlvbikoKSkgeworICByZXR1cm4gbmV3IGludGVybmFsOjpGdW5jdGlvbkNsb3N1cmUwKGZ1bmN0aW9uLCB0cnVlKTsKK30KKworLy8gU2VlIENsb3N1cmUuCitpbmxpbmUgQ2xvc3VyZSogTmV3UGVybWFuZW50Q2FsbGJhY2sodm9pZCAoKmZ1bmN0aW9uKSgpKSB7CisgIHJldHVybiBuZXcgaW50ZXJuYWw6OkZ1bmN0aW9uQ2xvc3VyZTAoZnVuY3Rpb24sIGZhbHNlKTsKK30KKworLy8gU2VlIENsb3N1cmUuCit0ZW1wbGF0ZSA8dHlwZW5hbWUgQ2xhc3M+CitpbmxpbmUgQ2xvc3VyZSogTmV3Q2FsbGJhY2soQ2xhc3MqIG9iamVjdCwgdm9pZCAoQ2xhc3M6OiptZXRob2QpKCkpIHsKKyAgcmV0dXJuIG5ldyBpbnRlcm5hbDo6TWV0aG9kQ2xvc3VyZTA8Q2xhc3M+KG9iamVjdCwgbWV0aG9kLCB0cnVlKTsKK30KKworLy8gU2VlIENsb3N1cmUuCit0ZW1wbGF0ZSA8dHlwZW5hbWUgQ2xhc3M+CitpbmxpbmUgQ2xvc3VyZSogTmV3UGVybWFuZW50Q2FsbGJhY2soQ2xhc3MqIG9iamVjdCwgdm9pZCAoQ2xhc3M6OiptZXRob2QpKCkpIHsKKyAgcmV0dXJuIG5ldyBpbnRlcm5hbDo6TWV0aG9kQ2xvc3VyZTA8Q2xhc3M+KG9iamVjdCwgbWV0aG9kLCBmYWxzZSk7Cit9CisKKy8vIFNlZSBDbG9zdXJlLgordGVtcGxhdGUgPHR5cGVuYW1lIEFyZzE+CitpbmxpbmUgQ2xvc3VyZSogTmV3Q2FsbGJhY2sodm9pZCAoKmZ1bmN0aW9uKShBcmcxKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBBcmcxIGFyZzEpIHsKKyAgcmV0dXJuIG5ldyBpbnRlcm5hbDo6RnVuY3Rpb25DbG9zdXJlMTxBcmcxPihmdW5jdGlvbiwgdHJ1ZSwgYXJnMSk7Cit9CisKKy8vIFNlZSBDbG9zdXJlLgordGVtcGxhdGUgPHR5cGVuYW1lIEFyZzE+CitpbmxpbmUgQ2xvc3VyZSogTmV3UGVybWFuZW50Q2FsbGJhY2sodm9pZCAoKmZ1bmN0aW9uKShBcmcxKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBcmcxIGFyZzEpIHsKKyAgcmV0dXJuIG5ldyBpbnRlcm5hbDo6RnVuY3Rpb25DbG9zdXJlMTxBcmcxPihmdW5jdGlvbiwgZmFsc2UsIGFyZzEpOworfQorCisvLyBTZWUgQ2xvc3VyZS4KK3RlbXBsYXRlIDx0eXBlbmFtZSBDbGFzcywgdHlwZW5hbWUgQXJnMT4KK2lubGluZSBDbG9zdXJlKiBOZXdDYWxsYmFjayhDbGFzcyogb2JqZWN0LCB2b2lkIChDbGFzczo6Km1ldGhvZCkoQXJnMSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJnMSBhcmcxKSB7CisgIHJldHVybiBuZXcgaW50ZXJuYWw6Ok1ldGhvZENsb3N1cmUxPENsYXNzLCBBcmcxPihvYmplY3QsIG1ldGhvZCwgdHJ1ZSwgYXJnMSk7Cit9CisKKy8vIFNlZSBDbG9zdXJlLgordGVtcGxhdGUgPHR5cGVuYW1lIENsYXNzLCB0eXBlbmFtZSBBcmcxPgoraW5saW5lIENsb3N1cmUqIE5ld1Blcm1hbmVudENhbGxiYWNrKENsYXNzKiBvYmplY3QsIHZvaWQgKENsYXNzOjoqbWV0aG9kKShBcmcxKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBcmcxIGFyZzEpIHsKKyAgcmV0dXJuIG5ldyBpbnRlcm5hbDo6TWV0aG9kQ2xvc3VyZTE8Q2xhc3MsIEFyZzE+KG9iamVjdCwgbWV0aG9kLCBmYWxzZSwgYXJnMSk7Cit9CisKKy8vIFNlZSBDbG9zdXJlLgordGVtcGxhdGUgPHR5cGVuYW1lIEFyZzEsIHR5cGVuYW1lIEFyZzI+CitpbmxpbmUgQ2xvc3VyZSogTmV3Q2FsbGJhY2sodm9pZCAoKmZ1bmN0aW9uKShBcmcxLCBBcmcyKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBBcmcxIGFyZzEsIEFyZzIgYXJnMikgeworICByZXR1cm4gbmV3IGludGVybmFsOjpGdW5jdGlvbkNsb3N1cmUyPEFyZzEsIEFyZzI+KAorICAgIGZ1bmN0aW9uLCB0cnVlLCBhcmcxLCBhcmcyKTsKK30KKworLy8gU2VlIENsb3N1cmUuCit0ZW1wbGF0ZSA8dHlwZW5hbWUgQXJnMSwgdHlwZW5hbWUgQXJnMj4KK2lubGluZSBDbG9zdXJlKiBOZXdQZXJtYW5lbnRDYWxsYmFjayh2b2lkICgqZnVuY3Rpb24pKEFyZzEsIEFyZzIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFyZzEgYXJnMSwgQXJnMiBhcmcyKSB7CisgIHJldHVybiBuZXcgaW50ZXJuYWw6OkZ1bmN0aW9uQ2xvc3VyZTI8QXJnMSwgQXJnMj4oCisgICAgZnVuY3Rpb24sIGZhbHNlLCBhcmcxLCBhcmcyKTsKK30KKworLy8gU2VlIENsb3N1cmUuCit0ZW1wbGF0ZSA8dHlwZW5hbWUgQ2xhc3MsIHR5cGVuYW1lIEFyZzEsIHR5cGVuYW1lIEFyZzI+CitpbmxpbmUgQ2xvc3VyZSogTmV3Q2FsbGJhY2soQ2xhc3MqIG9iamVjdCwgdm9pZCAoQ2xhc3M6OiptZXRob2QpKEFyZzEsIEFyZzIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFyZzEgYXJnMSwgQXJnMiBhcmcyKSB7CisgIHJldHVybiBuZXcgaW50ZXJuYWw6Ok1ldGhvZENsb3N1cmUyPENsYXNzLCBBcmcxLCBBcmcyPigKKyAgICBvYmplY3QsIG1ldGhvZCwgdHJ1ZSwgYXJnMSwgYXJnMik7Cit9CisKKy8vIFNlZSBDbG9zdXJlLgordGVtcGxhdGUgPHR5cGVuYW1lIENsYXNzLCB0eXBlbmFtZSBBcmcxLCB0eXBlbmFtZSBBcmcyPgoraW5saW5lIENsb3N1cmUqIE5ld1Blcm1hbmVudENhbGxiYWNrKAorICAgIENsYXNzKiBvYmplY3QsIHZvaWQgKENsYXNzOjoqbWV0aG9kKShBcmcxLCBBcmcyKSwKKyAgICBBcmcxIGFyZzEsIEFyZzIgYXJnMikgeworICByZXR1cm4gbmV3IGludGVybmFsOjpNZXRob2RDbG9zdXJlMjxDbGFzcywgQXJnMSwgQXJnMj4oCisgICAgb2JqZWN0LCBtZXRob2QsIGZhbHNlLCBhcmcxLCBhcmcyKTsKK30KKworLy8gU2VlIFJlc3VsdENhbGxiYWNrCit0ZW1wbGF0ZTx0eXBlbmFtZSBSPgoraW5saW5lIFJlc3VsdENhbGxiYWNrPFI+KiBOZXdDYWxsYmFjayhSICgqZnVuY3Rpb24pKCkpIHsKKyAgcmV0dXJuIG5ldyBpbnRlcm5hbDo6RnVuY3Rpb25SZXN1bHRDYWxsYmFja18wXzA8Uj4oZnVuY3Rpb24sIHRydWUpOworfQorCisvLyBTZWUgUmVzdWx0Q2FsbGJhY2sKK3RlbXBsYXRlPHR5cGVuYW1lIFI+CitpbmxpbmUgUmVzdWx0Q2FsbGJhY2s8Uj4qIE5ld1Blcm1hbmVudENhbGxiYWNrKFIgKCpmdW5jdGlvbikoKSkgeworICByZXR1cm4gbmV3IGludGVybmFsOjpGdW5jdGlvblJlc3VsdENhbGxiYWNrXzBfMDxSPihmdW5jdGlvbiwgZmFsc2UpOworfQorCisvLyBTZWUgUmVzdWx0Q2FsbGJhY2sKK3RlbXBsYXRlPHR5cGVuYW1lIFIsIHR5cGVuYW1lIFAxPgoraW5saW5lIFJlc3VsdENhbGxiYWNrPFI+KiBOZXdDYWxsYmFjayhSICgqZnVuY3Rpb24pKFAxKSwgUDEgcDEpIHsKKyAgcmV0dXJuIG5ldyBpbnRlcm5hbDo6RnVuY3Rpb25SZXN1bHRDYWxsYmFja18xXzA8UiwgUDE+KAorICAgICAgZnVuY3Rpb24sIHRydWUsIHAxKTsKK30KKworLy8gU2VlIFJlc3VsdENhbGxiYWNrCit0ZW1wbGF0ZTx0eXBlbmFtZSBSLCB0eXBlbmFtZSBQMT4KK2lubGluZSBSZXN1bHRDYWxsYmFjazxSPiogTmV3UGVybWFuZW50Q2FsbGJhY2soCisgICAgUiAoKmZ1bmN0aW9uKShQMSksIFAxIHAxKSB7CisgIHJldHVybiBuZXcgaW50ZXJuYWw6OkZ1bmN0aW9uUmVzdWx0Q2FsbGJhY2tfMV8wPFIsIFAxPigKKyAgICAgIGZ1bmN0aW9uLCBmYWxzZSwgcDEpOworfQorCisvLyBTZWUgUmVzdWx0Q2FsbGJhY2sxCit0ZW1wbGF0ZTx0eXBlbmFtZSBSLCB0eXBlbmFtZSBBMT4KK2lubGluZSBSZXN1bHRDYWxsYmFjazE8UiwgQTE+KiBOZXdDYWxsYmFjayhSICgqZnVuY3Rpb24pKEExKSkgeworICByZXR1cm4gbmV3IGludGVybmFsOjpGdW5jdGlvblJlc3VsdENhbGxiYWNrXzBfMTxSLCBBMT4oZnVuY3Rpb24sIHRydWUpOworfQorCisvLyBTZWUgUmVzdWx0Q2FsbGJhY2sxCit0ZW1wbGF0ZTx0eXBlbmFtZSBSLCB0eXBlbmFtZSBBMT4KK2lubGluZSBSZXN1bHRDYWxsYmFjazE8UiwgQTE+KiBOZXdQZXJtYW5lbnRDYWxsYmFjayhSICgqZnVuY3Rpb24pKEExKSkgeworICByZXR1cm4gbmV3IGludGVybmFsOjpGdW5jdGlvblJlc3VsdENhbGxiYWNrXzBfMTxSLCBBMT4oZnVuY3Rpb24sIGZhbHNlKTsKK30KKworLy8gU2VlIFJlc3VsdENhbGxiYWNrMQordGVtcGxhdGU8dHlwZW5hbWUgUiwgdHlwZW5hbWUgUDEsIHR5cGVuYW1lIEExPgoraW5saW5lIFJlc3VsdENhbGxiYWNrMTxSLCBBMT4qIE5ld0NhbGxiYWNrKFIgKCpmdW5jdGlvbikoUDEsIEExKSwgUDEgcDEpIHsKKyAgcmV0dXJuIG5ldyBpbnRlcm5hbDo6RnVuY3Rpb25SZXN1bHRDYWxsYmFja18xXzE8UiwgUDEsIEExPigKKyAgICAgIGZ1bmN0aW9uLCB0cnVlLCBwMSk7Cit9CisKKy8vIFNlZSBSZXN1bHRDYWxsYmFjazEKK3RlbXBsYXRlPHR5cGVuYW1lIFIsIHR5cGVuYW1lIFAxLCB0eXBlbmFtZSBBMT4KK2lubGluZSBSZXN1bHRDYWxsYmFjazE8UiwgQTE+KiBOZXdQZXJtYW5lbnRDYWxsYmFjaygKKyAgICBSICgqZnVuY3Rpb24pKFAxLCBBMSksIFAxIHAxKSB7CisgIHJldHVybiBuZXcgaW50ZXJuYWw6OkZ1bmN0aW9uUmVzdWx0Q2FsbGJhY2tfMV8xPFIsIFAxLCBBMT4oCisgICAgICBmdW5jdGlvbiwgZmFsc2UsIHAxKTsKK30KKworLy8gU2VlIE1ldGhvZFJlc3VsdENhbGxiYWNrXzVfMgordGVtcGxhdGUgPHR5cGVuYW1lIFIsIHR5cGVuYW1lIFQsIHR5cGVuYW1lIFAxLCB0eXBlbmFtZSBQMiwgdHlwZW5hbWUgUDMsCisgICAgICAgICAgdHlwZW5hbWUgUDQsIHR5cGVuYW1lIFA1LCB0eXBlbmFtZSBBMSwgdHlwZW5hbWUgQTI+CitpbmxpbmUgUmVzdWx0Q2FsbGJhY2syPFIsIEExLCBBMj4qIE5ld1Blcm1hbmVudENhbGxiYWNrKAorICAgIFQqIG9iamVjdCwgUiAoVDo6KmZ1bmN0aW9uKShQMSwgUDIsIFAzLCBQNCwgUDUsIEExLCBBMiksCisgICAgdHlwZW5hbWUgaW50ZXJuYWw6OkludGVybmFsQ29uc3RSZWY8UDE+Ojp0eXBlIHAxLAorICAgIHR5cGVuYW1lIGludGVybmFsOjpJbnRlcm5hbENvbnN0UmVmPFAyPjo6dHlwZSBwMiwKKyAgICB0eXBlbmFtZSBpbnRlcm5hbDo6SW50ZXJuYWxDb25zdFJlZjxQMz46OnR5cGUgcDMsCisgICAgdHlwZW5hbWUgaW50ZXJuYWw6OkludGVybmFsQ29uc3RSZWY8UDQ+Ojp0eXBlIHA0LAorICAgIHR5cGVuYW1lIGludGVybmFsOjpJbnRlcm5hbENvbnN0UmVmPFA1Pjo6dHlwZSBwNSkgeworICByZXR1cm4gbmV3IGludGVybmFsOjpNZXRob2RSZXN1bHRDYWxsYmFja181XzI8UiwgVCwgUDEsIFAyLCBQMywgUDQsIFA1LCBBMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEEyPihvYmplY3QsIGZ1bmN0aW9uLCBmYWxzZSwgcDEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcDIsIHAzLCBwNCwgcDUpOworfQorCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKKworLy8gQSBmdW5jdGlvbiB3aGljaCBkb2VzIG5vdGhpbmcuICBVc2VmdWwgZm9yIGNyZWF0aW5nIG5vLW9wIGNhbGxiYWNrcywgZS5nLjoKKy8vICAgQ2xvc3VyZSogbm90aGluZyA9IE5ld0NhbGxiYWNrKCZEb05vdGhpbmcpOwordm9pZCBMSUJQUk9UT0JVRl9FWFBPUlQgRG9Ob3RoaW5nKCk7CisKKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX1NUVUJTX0NBTExCQUNLX0hfCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2Nhc3RzLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2Nhc3RzLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmU2NTI4NAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvY2FzdHMuaApAQCAtMCwwICsxLDEzMyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAxNCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NBU1RTX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQ0FTVFNfSF9fCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3R5cGVfdHJhaXRzLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisvLyBVc2UgaW1wbGljaXRfY2FzdCBhcyBhIHNhZmUgdmVyc2lvbiBvZiBzdGF0aWNfY2FzdCBvciBjb25zdF9jYXN0CisvLyBmb3IgdXBjYXN0aW5nIGluIHRoZSB0eXBlIGhpZXJhcmNoeSAoaS5lLiBjYXN0aW5nIGEgcG9pbnRlciB0byBGb28KKy8vIHRvIGEgcG9pbnRlciB0byBTdXBlcmNsYXNzT2ZGb28gb3IgY2FzdGluZyBhIHBvaW50ZXIgdG8gRm9vIHRvCisvLyBhIGNvbnN0IHBvaW50ZXIgdG8gRm9vKS4KKy8vIFdoZW4geW91IHVzZSBpbXBsaWNpdF9jYXN0LCB0aGUgY29tcGlsZXIgY2hlY2tzIHRoYXQgdGhlIGNhc3QgaXMgc2FmZS4KKy8vIFN1Y2ggZXhwbGljaXQgaW1wbGljaXRfY2FzdHMgYXJlIG5lY2Vzc2FyeSBpbiBzdXJwcmlzaW5nbHkgbWFueQorLy8gc2l0dWF0aW9ucyB3aGVyZSBDKysgZGVtYW5kcyBhbiBleGFjdCB0eXBlIG1hdGNoIGluc3RlYWQgb2YgYW4KKy8vIGFyZ3VtZW50IHR5cGUgY29udmVydGFibGUgdG8gYSB0YXJnZXQgdHlwZS4KKy8vCisvLyBUaGUgRnJvbSB0eXBlIGNhbiBiZSBpbmZlcnJlZCwgc28gdGhlIHByZWZlcnJlZCBzeW50YXggZm9yIHVzaW5nCisvLyBpbXBsaWNpdF9jYXN0IGlzIHRoZSBzYW1lIGFzIGZvciBzdGF0aWNfY2FzdCBldGMuOgorLy8KKy8vICAgaW1wbGljaXRfY2FzdDxUb1R5cGU+KGV4cHIpCisvLworLy8gaW1wbGljaXRfY2FzdCB3b3VsZCBoYXZlIGJlZW4gcGFydCBvZiB0aGUgQysrIHN0YW5kYXJkIGxpYnJhcnksCisvLyBidXQgdGhlIHByb3Bvc2FsIHdhcyBzdWJtaXR0ZWQgdG9vIGxhdGUuICBJdCB3aWxsIHByb2JhYmx5IG1ha2UKKy8vIGl0cyB3YXkgaW50byB0aGUgbGFuZ3VhZ2UgaW4gdGhlIGZ1dHVyZS4KK3RlbXBsYXRlPHR5cGVuYW1lIFRvLCB0eXBlbmFtZSBGcm9tPgoraW5saW5lIFRvIGltcGxpY2l0X2Nhc3QoRnJvbSBjb25zdCAmZikgeworICByZXR1cm4gZjsKK30KKworLy8gV2hlbiB5b3UgdXBjYXN0ICh0aGF0IGlzLCBjYXN0IGEgcG9pbnRlciBmcm9tIHR5cGUgRm9vIHRvIHR5cGUKKy8vIFN1cGVyY2xhc3NPZkZvbyksIGl0J3MgZmluZSB0byB1c2UgaW1wbGljaXRfY2FzdDw+LCBzaW5jZSB1cGNhc3RzCisvLyBhbHdheXMgc3VjY2VlZC4gIFdoZW4geW91IGRvd25jYXN0ICh0aGF0IGlzLCBjYXN0IGEgcG9pbnRlciBmcm9tCisvLyB0eXBlIEZvbyB0byB0eXBlIFN1YmNsYXNzT2ZGb28pLCBzdGF0aWNfY2FzdDw+IGlzbid0IHNhZmUsIGJlY2F1c2UKKy8vIGhvdyBkbyB5b3Uga25vdyB0aGUgcG9pbnRlciBpcyByZWFsbHkgb2YgdHlwZSBTdWJjbGFzc09mRm9vPyAgSXQKKy8vIGNvdWxkIGJlIGEgYmFyZSBGb28sIG9yIG9mIHR5cGUgRGlmZmVyZW50U3ViY2xhc3NPZkZvby4gIFRodXMsCisvLyB3aGVuIHlvdSBkb3duY2FzdCwgeW91IHNob3VsZCB1c2UgdGhpcyBtYWNyby4gIEluIGRlYnVnIG1vZGUsIHdlCisvLyB1c2UgZHluYW1pY19jYXN0PD4gdG8gZG91YmxlLWNoZWNrIHRoZSBkb3duY2FzdCBpcyBsZWdhbCAod2UgZGllCisvLyBpZiBpdCdzIG5vdCkuICBJbiBub3JtYWwgbW9kZSwgd2UgZG8gdGhlIGVmZmljaWVudCBzdGF0aWNfY2FzdDw+CisvLyBpbnN0ZWFkLiAgVGh1cywgaXQncyBpbXBvcnRhbnQgdG8gdGVzdCBpbiBkZWJ1ZyBtb2RlIHRvIG1ha2Ugc3VyZQorLy8gdGhlIGNhc3QgaXMgbGVnYWwhCisvLyAgICBUaGlzIGlzIHRoZSBvbmx5IHBsYWNlIGluIHRoZSBjb2RlIHdlIHNob3VsZCB1c2UgZHluYW1pY19jYXN0PD4uCisvLyBJbiBwYXJ0aWN1bGFyLCB5b3UgU0hPVUxETidUIGJlIHVzaW5nIGR5bmFtaWNfY2FzdDw+IGluIG9yZGVyIHRvCisvLyBkbyBSVFRJIChlZyBjb2RlIGxpa2UgdGhpczoKKy8vICAgIGlmIChkeW5hbWljX2Nhc3Q8U3ViY2xhc3MxPihmb28pKSBIYW5kbGVBU3ViY2xhc3MxT2JqZWN0KGZvbyk7CisvLyAgICBpZiAoZHluYW1pY19jYXN0PFN1YmNsYXNzMj4oZm9vKSkgSGFuZGxlQVN1YmNsYXNzMk9iamVjdChmb28pOworLy8gWW91IHNob3VsZCBkZXNpZ24gdGhlIGNvZGUgc29tZSBvdGhlciB3YXkgbm90IHRvIG5lZWQgdGhpcy4KKwordGVtcGxhdGU8dHlwZW5hbWUgVG8sIHR5cGVuYW1lIEZyb20+ICAgICAvLyB1c2UgbGlrZSB0aGlzOiBkb3duX2Nhc3Q8VCo+KGZvbyk7CitpbmxpbmUgVG8gZG93bl9jYXN0KEZyb20qIGYpIHsgICAgICAgICAgICAgICAgICAgLy8gc28gd2Ugb25seSBhY2NlcHQgcG9pbnRlcnMKKyAgLy8gRW5zdXJlcyB0aGF0IFRvIGlzIGEgc3ViLXR5cGUgb2YgRnJvbSAqLiAgVGhpcyB0ZXN0IGlzIGhlcmUgb25seQorICAvLyBmb3IgY29tcGlsZS10aW1lIHR5cGUgY2hlY2tpbmcsIGFuZCBoYXMgbm8gb3ZlcmhlYWQgaW4gYW4KKyAgLy8gb3B0aW1pemVkIGJ1aWxkIGF0IHJ1bi10aW1lLCBhcyBpdCB3aWxsIGJlIG9wdGltaXplZCBhd2F5CisgIC8vIGNvbXBsZXRlbHkuCisgIGlmIChmYWxzZSkgeworICAgIGltcGxpY2l0X2Nhc3Q8RnJvbSosIFRvPigwKTsKKyAgfQorCisjaWYgIWRlZmluZWQoTkRFQlVHKSAmJiAhZGVmaW5lZChHT09HTEVfUFJPVE9CVUZfTk9fUlRUSSkKKyAgYXNzZXJ0KGYgPT0gTlVMTCB8fCBkeW5hbWljX2Nhc3Q8VG8+KGYpICE9IE5VTEwpOyAgLy8gUlRUSTogZGVidWcgbW9kZSBvbmx5IQorI2VuZGlmCisgIHJldHVybiBzdGF0aWNfY2FzdDxUbz4oZik7Cit9CisKK3RlbXBsYXRlPHR5cGVuYW1lIFRvLCB0eXBlbmFtZSBGcm9tPiAgICAvLyB1c2UgbGlrZSB0aGlzOiBkb3duX2Nhc3Q8VCY+KGZvbyk7CitpbmxpbmUgVG8gZG93bl9jYXN0KEZyb20mIGYpIHsKKyAgdHlwZWRlZiB0eXBlbmFtZSByZW1vdmVfcmVmZXJlbmNlPFRvPjo6dHlwZSogVG9Bc1BvaW50ZXI7CisgIC8vIEVuc3VyZXMgdGhhdCBUbyBpcyBhIHN1Yi10eXBlIG9mIEZyb20gKi4gIFRoaXMgdGVzdCBpcyBoZXJlIG9ubHkKKyAgLy8gZm9yIGNvbXBpbGUtdGltZSB0eXBlIGNoZWNraW5nLCBhbmQgaGFzIG5vIG92ZXJoZWFkIGluIGFuCisgIC8vIG9wdGltaXplZCBidWlsZCBhdCBydW4tdGltZSwgYXMgaXQgd2lsbCBiZSBvcHRpbWl6ZWQgYXdheQorICAvLyBjb21wbGV0ZWx5LgorICBpZiAoZmFsc2UpIHsKKyAgICBpbXBsaWNpdF9jYXN0PEZyb20qLCBUb0FzUG9pbnRlcj4oMCk7CisgIH0KKworI2lmICFkZWZpbmVkKE5ERUJVRykgJiYgIWRlZmluZWQoR09PR0xFX1BST1RPQlVGX05PX1JUVEkpCisgIC8vIFJUVEk6IGRlYnVnIG1vZGUgb25seSEKKyAgYXNzZXJ0KGR5bmFtaWNfY2FzdDxUb0FzUG9pbnRlcj4oJmYpICE9IE5VTEwpOworI2VuZGlmCisgIHJldHVybiAqc3RhdGljX2Nhc3Q8VG9Bc1BvaW50ZXI+KCZmKTsKK30KKwordGVtcGxhdGU8dHlwZW5hbWUgVG8sIHR5cGVuYW1lIEZyb20+CitpbmxpbmUgVG8gYml0X2Nhc3QoY29uc3QgRnJvbSYgZnJvbSkgeworICBHT09HTEVfQ09NUElMRV9BU1NFUlQoc2l6ZW9mKEZyb20pID09IHNpemVvZihUbyksCisgICAgICAgICAgICAgICAgICAgICAgICBiaXRfY2FzdF93aXRoX2RpZmZlcmVudF9zaXplcyk7CisgIFRvIGRlc3Q7CisgIG1lbWNweSgmZGVzdCwgJmZyb20sIHNpemVvZihkZXN0KSk7CisgIHJldHVybiBkZXN0OworfQorCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKKworLy8gV2UgbWFkZSB0aGVzZSBpbnRlcm5hbCBzbyB0aGF0IHRoZXkgd291bGQgc2hvdyB1cCBhcyBzdWNoIGluIHRoZSBkb2NzLAorLy8gYnV0IHdlIGRvbid0IHdhbnQgdG8gc3RpY2sgImludGVybmFsOjoiIGluIGZyb250IG9mIHRoZW0gZXZlcnl3aGVyZS4KK3VzaW5nIGludGVybmFsOjppbXBsaWNpdF9jYXN0OwordXNpbmcgaW50ZXJuYWw6OmRvd25fY2FzdDsKK3VzaW5nIGludGVybmFsOjpiaXRfY2FzdDsKKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DQVNUU19IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTRkYmFmYQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmNjCkBAIC0wLDAgKzEsNDU5IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9vbmNlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0YXR1cy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJpbmdwaWVjZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2ludDEyOC5oPgorI2luY2x1ZGUgPGVycm5vLmg+CisjaW5jbHVkZSA8c3N0cmVhbT4KKyNpbmNsdWRlIDxzdGRpby5oPgorI2luY2x1ZGUgPHZlY3Rvcj4KKworI2lmZGVmIF9XSU4zMgorI2RlZmluZSBXSU4zMl9MRUFOX0FORF9NRUFOICAvLyBXZSBvbmx5IG5lZWQgbWluaW1hbCBpbmNsdWRlcworI2luY2x1ZGUgPHdpbmRvd3MuaD4KKyNkZWZpbmUgc25wcmludGYgX3NucHJpbnRmICAgIC8vIHNlZSBjb21tZW50IGluIHN0cnV0aWwuY2MKKyNlbGlmIGRlZmluZWQoSEFWRV9QVEhSRUFEKQorI2luY2x1ZGUgPHB0aHJlYWQuaD4KKyNlbHNlCisjZXJyb3IgIk5vIHN1aXRhYmxlIHRocmVhZGluZyBsaWJyYXJ5IGF2YWlsYWJsZS4iCisjZW5kaWYKKyNpZiBkZWZpbmVkKF9fQU5EUk9JRF9fKQorI2luY2x1ZGUgPGFuZHJvaWQvbG9nLmg+CisjZW5kaWYKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCituYW1lc3BhY2UgaW50ZXJuYWwgeworCit2b2lkIFZlcmlmeVZlcnNpb24oaW50IGhlYWRlclZlcnNpb24sCisgICAgICAgICAgICAgICAgICAgaW50IG1pbkxpYnJhcnlWZXJzaW9uLAorICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIGZpbGVuYW1lKSB7CisgIGlmIChHT09HTEVfUFJPVE9CVUZfVkVSU0lPTiA8IG1pbkxpYnJhcnlWZXJzaW9uKSB7CisgICAgLy8gTGlicmFyeSBpcyB0b28gb2xkIGZvciBoZWFkZXJzLgorICAgIEdPT0dMRV9MT0coRkFUQUwpCisgICAgICA8PCAiVGhpcyBwcm9ncmFtIHJlcXVpcmVzIHZlcnNpb24gIiA8PCBWZXJzaW9uU3RyaW5nKG1pbkxpYnJhcnlWZXJzaW9uKQorICAgICAgPDwgIiBvZiB0aGUgUHJvdG9jb2wgQnVmZmVyIHJ1bnRpbWUgbGlicmFyeSwgYnV0IHRoZSBpbnN0YWxsZWQgdmVyc2lvbiAiCisgICAgICAgICAiaXMgIiA8PCBWZXJzaW9uU3RyaW5nKEdPT0dMRV9QUk9UT0JVRl9WRVJTSU9OKSA8PCAiLiAgUGxlYXNlIHVwZGF0ZSAiCisgICAgICAgICAieW91ciBsaWJyYXJ5LiAgSWYgeW91IGNvbXBpbGVkIHRoZSBwcm9ncmFtIHlvdXJzZWxmLCBtYWtlIHN1cmUgdGhhdCAiCisgICAgICAgICAieW91ciBoZWFkZXJzIGFyZSBmcm9tIHRoZSBzYW1lIHZlcnNpb24gb2YgUHJvdG9jb2wgQnVmZmVycyBhcyB5b3VyICIKKyAgICAgICAgICJsaW5rLXRpbWUgbGlicmFyeS4gIChWZXJzaW9uIHZlcmlmaWNhdGlvbiBmYWlsZWQgaW4gXCIiCisgICAgICA8PCBmaWxlbmFtZSA8PCAiXCIuKSI7CisgIH0KKyAgaWYgKGhlYWRlclZlcnNpb24gPCBrTWluSGVhZGVyVmVyc2lvbkZvckxpYnJhcnkpIHsKKyAgICAvLyBIZWFkZXJzIGFyZSB0b28gb2xkIGZvciBsaWJyYXJ5LgorICAgIEdPT0dMRV9MT0coRkFUQUwpCisgICAgICA8PCAiVGhpcyBwcm9ncmFtIHdhcyBjb21waWxlZCBhZ2FpbnN0IHZlcnNpb24gIgorICAgICAgPDwgVmVyc2lvblN0cmluZyhoZWFkZXJWZXJzaW9uKSA8PCAiIG9mIHRoZSBQcm90b2NvbCBCdWZmZXIgcnVudGltZSAiCisgICAgICAgICAibGlicmFyeSwgd2hpY2ggaXMgbm90IGNvbXBhdGlibGUgd2l0aCB0aGUgaW5zdGFsbGVkIHZlcnNpb24gKCIKKyAgICAgIDw8IFZlcnNpb25TdHJpbmcoR09PR0xFX1BST1RPQlVGX1ZFUlNJT04pIDw8ICAiKS4gIENvbnRhY3QgdGhlIHByb2dyYW0gIgorICAgICAgICAgImF1dGhvciBmb3IgYW4gdXBkYXRlLiAgSWYgeW91IGNvbXBpbGVkIHRoZSBwcm9ncmFtIHlvdXJzZWxmLCBtYWtlICIKKyAgICAgICAgICJzdXJlIHRoYXQgeW91ciBoZWFkZXJzIGFyZSBmcm9tIHRoZSBzYW1lIHZlcnNpb24gb2YgUHJvdG9jb2wgQnVmZmVycyAiCisgICAgICAgICAiYXMgeW91ciBsaW5rLXRpbWUgbGlicmFyeS4gIChWZXJzaW9uIHZlcmlmaWNhdGlvbiBmYWlsZWQgaW4gXCIiCisgICAgICA8PCBmaWxlbmFtZSA8PCAiXCIuKSI7CisgIH0KK30KKworc3RyaW5nIFZlcnNpb25TdHJpbmcoaW50IHZlcnNpb24pIHsKKyAgaW50IG1ham9yID0gdmVyc2lvbiAvIDEwMDAwMDA7CisgIGludCBtaW5vciA9ICh2ZXJzaW9uIC8gMTAwMCkgJSAxMDAwOworICBpbnQgbWljcm8gPSB2ZXJzaW9uICUgMTAwMDsKKworICAvLyAxMjggYnl0ZXMgc2hvdWxkIGFsd2F5cyBiZSBlbm91Z2gsIGJ1dCB3ZSB1c2Ugc25wcmludGYoKSBhbnl3YXkgdG8gYmUKKyAgLy8gc2FmZS4KKyAgY2hhciBidWZmZXJbMTI4XTsKKyAgc25wcmludGYoYnVmZmVyLCBzaXplb2YoYnVmZmVyKSwgIiVkLiVkLiVkIiwgbWFqb3IsIG1pbm9yLCBtaWNybyk7CisKKyAgLy8gR3VhcmQgYWdhaW5zdCBicm9rZW4gTVNWQyBzbnByaW50ZigpLgorICBidWZmZXJbc2l6ZW9mKGJ1ZmZlciktMV0gPSAnXDAnOworCisgIHJldHVybiBidWZmZXI7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisvLyBlbXVsYXRlcyBnb29nbGUzL2Jhc2UvbG9nZ2luZy5jYworCituYW1lc3BhY2UgaW50ZXJuYWwgeworI2lmIGRlZmluZWQoX19BTkRST0lEX18pCitpbmxpbmUgdm9pZCBEZWZhdWx0TG9nSGFuZGxlcihMb2dMZXZlbCBsZXZlbCwgY29uc3QgY2hhciogZmlsZW5hbWUsIGludCBsaW5lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBtZXNzYWdlKSB7CisjaWZkZWYgR09PR0xFX1BST1RPQlVGX01JTl9MT0dfTEVWRUwKKyAgaWYgKGxldmVsIDwgR09PR0xFX1BST1RPQlVGX01JTl9MT0dfTEVWRUwpIHsKKyAgICByZXR1cm47CisgIH0KKyAgc3RhdGljIGNvbnN0IGNoYXIqIGxldmVsX25hbWVzW10gPSB7IklORk8iLCAiV0FSTklORyIsICJFUlJPUiIsICJGQVRBTCJ9OworCisgIHN0YXRpYyBjb25zdCBpbnQgYW5kcm9pZF9sb2dfbGV2ZWxzW10gPSB7CisgICAgICBBTkRST0lEX0xPR19JTkZPLCAgIC8vIExPRyhJTkZPKSwKKyAgICAgIEFORFJPSURfTE9HX1dBUk4sICAgLy8gTE9HKFdBUk5JTkcpCisgICAgICBBTkRST0lEX0xPR19FUlJPUiwgIC8vIExPRyhFUlJPUikKKyAgICAgIEFORFJPSURfTE9HX0ZBVEFMLCAgLy8gTE9HKEZBVEFMKQorICB9OworCisgIC8vIEJvdW5kIHRoZSBsb2dnaW5nIGxldmVsLgorICBjb25zdCBpbnQgYW5kcm9pZF9sb2dfbGV2ZWwgPSBhbmRyb2lkX2xvZ19sZXZlbHNbbGV2ZWxdOworICA6OnN0ZDo6b3N0cmluZ3N0cmVhbSBvc3RyOworICBvc3RyIDw8ICJbbGlicHJvdG9idWYgIiA8PCBsZXZlbF9uYW1lc1tsZXZlbF0gPDwgIiAiIDw8IGZpbGVuYW1lIDw8ICI6IgorICAgICAgIDw8IGxpbmUgPDwgIl0gIiA8PCBtZXNzYWdlLmNfc3RyKCk7CisKKyAgLy8gT3V0cHV0IHRoZSBsb2cgc3RyaW5nIHRoZSBBbmRyb2lkIGxvZyBhdCB0aGUgYXBwcm9wcmlhdGUgbGV2ZWwuCisgIF9fYW5kcm9pZF9sb2dfd3JpdGUoYW5kcm9pZF9sb2dfbGV2ZWwsICJsaWJwcm90b2J1Zi1uYXRpdmUiLAorICAgICAgICAgICAgICAgICAgICAgIG9zdHIuc3RyKCkuY19zdHIoKSk7CisgIC8vIEFsc28gb3V0cHV0IHRvIHN0ZDo6Y2Vyci4KKyAgZnByaW50ZihzdGRlcnIsICIlcyIsIG9zdHIuc3RyKCkuY19zdHIoKSk7CisgIGZmbHVzaChzdGRlcnIpOworCisgIC8vIEluZGljYXRlIHRlcm1pbmF0aW9uIGlmIG5lZWRlZC4KKyAgaWYgKGFuZHJvaWRfbG9nX2xldmVsID09IEFORFJPSURfTE9HX0ZBVEFMKSB7CisgICAgX19hbmRyb2lkX2xvZ193cml0ZShBTkRST0lEX0xPR19GQVRBTCwgImxpYnByb3RvYnVmLW5hdGl2ZSIsCisgICAgICAgICAgICAgICAgICAgICAgICAidGVybWluYXRpbmcuXG4iKTsKKyAgfQorI2VuZGlmCit9CisjZWxzZQordm9pZCBEZWZhdWx0TG9nSGFuZGxlcihMb2dMZXZlbCBsZXZlbCwgY29uc3QgY2hhciogZmlsZW5hbWUsIGludCBsaW5lLAorICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIG1lc3NhZ2UpIHsKKyAgc3RhdGljIGNvbnN0IGNoYXIqIGxldmVsX25hbWVzW10gPSB7ICJJTkZPIiwgIldBUk5JTkciLCAiRVJST1IiLCAiRkFUQUwiIH07CisKKyAgLy8gV2UgdXNlIGZwcmludGYoKSBpbnN0ZWFkIG9mIGNlcnIgYmVjYXVzZSB3ZSB3YW50IHRoaXMgdG8gd29yayBhdCBzdGF0aWMKKyAgLy8gaW5pdGlhbGl6YXRpb24gdGltZS4KKyAgZnByaW50ZihzdGRlcnIsICJbbGlicHJvdG9idWYgJXMgJXM6JWRdICVzXG4iLAorICAgICAgICAgIGxldmVsX25hbWVzW2xldmVsXSwgZmlsZW5hbWUsIGxpbmUsIG1lc3NhZ2UuY19zdHIoKSk7CisgIGZmbHVzaChzdGRlcnIpOyAgLy8gTmVlZGVkIG9uIE1TVkMuCit9CisjZW5kaWYKKwordm9pZCBOdWxsTG9nSGFuZGxlcihMb2dMZXZlbCAvKiBsZXZlbCAqLywgY29uc3QgY2hhciogLyogZmlsZW5hbWUgKi8sCisgICAgICAgICAgICAgICAgICAgIGludCAvKiBsaW5lICovLCBjb25zdCBzdHJpbmcmIC8qIG1lc3NhZ2UgKi8pIHsKKyAgLy8gTm90aGluZy4KK30KKworc3RhdGljIExvZ0hhbmRsZXIqIGxvZ19oYW5kbGVyXyA9ICZEZWZhdWx0TG9nSGFuZGxlcjsKK3N0YXRpYyBpbnQgbG9nX3NpbGVuY2VyX2NvdW50XyA9IDA7CisKK3N0YXRpYyBNdXRleCogbG9nX3NpbGVuY2VyX2NvdW50X211dGV4XyA9IE5VTEw7CitHT09HTEVfUFJPVE9CVUZfREVDTEFSRV9PTkNFKGxvZ19zaWxlbmNlcl9jb3VudF9pbml0Xyk7CisKK3ZvaWQgRGVsZXRlTG9nU2lsZW5jZXJDb3VudCgpIHsKKyAgZGVsZXRlIGxvZ19zaWxlbmNlcl9jb3VudF9tdXRleF87CisgIGxvZ19zaWxlbmNlcl9jb3VudF9tdXRleF8gPSBOVUxMOworfQordm9pZCBJbml0TG9nU2lsZW5jZXJDb3VudCgpIHsKKyAgbG9nX3NpbGVuY2VyX2NvdW50X211dGV4XyA9IG5ldyBNdXRleDsKKyAgT25TaHV0ZG93bigmRGVsZXRlTG9nU2lsZW5jZXJDb3VudCk7Cit9Cit2b2lkIEluaXRMb2dTaWxlbmNlckNvdW50T25jZSgpIHsKKyAgR29vZ2xlT25jZUluaXQoJmxvZ19zaWxlbmNlcl9jb3VudF9pbml0XywgJkluaXRMb2dTaWxlbmNlckNvdW50KTsKK30KKworTG9nTWVzc2FnZSYgTG9nTWVzc2FnZTo6b3BlcmF0b3I8PChjb25zdCBzdHJpbmcmIHZhbHVlKSB7CisgIG1lc3NhZ2VfICs9IHZhbHVlOworICByZXR1cm4gKnRoaXM7Cit9CisKK0xvZ01lc3NhZ2UmIExvZ01lc3NhZ2U6Om9wZXJhdG9yPDwoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgbWVzc2FnZV8gKz0gdmFsdWU7CisgIHJldHVybiAqdGhpczsKK30KKworTG9nTWVzc2FnZSYgTG9nTWVzc2FnZTo6b3BlcmF0b3I8PChjb25zdCBTdHJpbmdQaWVjZSYgdmFsdWUpIHsKKyAgbWVzc2FnZV8gKz0gdmFsdWUuVG9TdHJpbmcoKTsKKyAgcmV0dXJuICp0aGlzOworfQorCitMb2dNZXNzYWdlJiBMb2dNZXNzYWdlOjpvcGVyYXRvcjw8KAorICAgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6dXRpbDo6U3RhdHVzJiBzdGF0dXMpIHsKKyAgbWVzc2FnZV8gKz0gc3RhdHVzLlRvU3RyaW5nKCk7CisgIHJldHVybiAqdGhpczsKK30KKworTG9nTWVzc2FnZSYgTG9nTWVzc2FnZTo6b3BlcmF0b3I8PChjb25zdCB1aW50MTI4JiB2YWx1ZSkgeworICBzdGQ6Om9zdHJpbmdzdHJlYW0gc3RyOworICBzdHIgPDwgdmFsdWU7CisgIG1lc3NhZ2VfICs9IHN0ci5zdHIoKTsKKyAgcmV0dXJuICp0aGlzOworfQorCisvLyBTaW5jZSB0aGlzIGlzIGp1c3QgZm9yIGxvZ2dpbmcsIHdlIGRvbid0IGNhcmUgaWYgdGhlIGN1cnJlbnQgbG9jYWxlIGNoYW5nZXMKKy8vIHRoZSByZXN1bHRzIC0tIGluIGZhY3QsIHdlIHByb2JhYmx5IHByZWZlciB0aGF0LiAgU28gd2UgdXNlIHNucHJpbnRmKCkKKy8vIGluc3RlYWQgb2YgU2ltcGxlKnRvYSgpLgorI3VuZGVmIERFQ0xBUkVfU1RSRUFNX09QRVJBVE9SCisjZGVmaW5lIERFQ0xBUkVfU1RSRUFNX09QRVJBVE9SKFRZUEUsIEZPUk1BVCkgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgTG9nTWVzc2FnZSYgTG9nTWVzc2FnZTo6b3BlcmF0b3I8PChUWVBFIHZhbHVlKSB7ICAgICAgICAgICAgICAgICAgXAorICAgIC8qIDEyOCBieXRlcyBzaG91bGQgYmUgYmlnIGVub3VnaCBmb3IgYW55IG9mIHRoZSBwcmltaXRpdmUgKi8gICBcCisgICAgLyogdmFsdWVzIHdoaWNoIHdlIHByaW50IHdpdGggdGhpcywgYnV0IHdlbGwgdXNlIHNucHJpbnRmKCkgKi8gIFwKKyAgICAvKiBhbnl3YXkgdG8gYmUgZXh0cmEgc2FmZS4gKi8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGNoYXIgYnVmZmVyWzEyOF07ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgc25wcmludGYoYnVmZmVyLCBzaXplb2YoYnVmZmVyKSwgRk9STUFULCB2YWx1ZSk7ICAgICAgICAgICAgICAgIFwKKyAgICAvKiBHdWFyZCBhZ2FpbnN0IGJyb2tlbiBNU1ZDIHNucHJpbnRmKCkuICovICAgICAgICAgICAgICAgICAgICAgXAorICAgIGJ1ZmZlcltzaXplb2YoYnVmZmVyKS0xXSA9ICdcMCc7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgbWVzc2FnZV8gKz0gYnVmZmVyOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICByZXR1cm4gKnRoaXM7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9CisKK0RFQ0xBUkVfU1RSRUFNX09QRVJBVE9SKGNoYXIgICAgICAgICAsICIlYyIgKQorREVDTEFSRV9TVFJFQU1fT1BFUkFUT1IoaW50ICAgICAgICAgICwgIiVkIiApCitERUNMQVJFX1NUUkVBTV9PUEVSQVRPUih1bnNpZ25lZCBpbnQgLCAiJXUiICkKK0RFQ0xBUkVfU1RSRUFNX09QRVJBVE9SKGxvbmcgICAgICAgICAsICIlbGQiKQorREVDTEFSRV9TVFJFQU1fT1BFUkFUT1IodW5zaWduZWQgbG9uZywgIiVsdSIpCitERUNMQVJFX1NUUkVBTV9PUEVSQVRPUihkb3VibGUgICAgICAgLCAiJWciICkKK0RFQ0xBUkVfU1RSRUFNX09QRVJBVE9SKHZvaWQqICAgICAgICAsICIlcCIgKQorREVDTEFSRV9TVFJFQU1fT1BFUkFUT1IobG9uZyBsb25nICAgICAgICAgLCAiJSIgR09PR0xFX0xMX0ZPUk1BVCAiZCIpCitERUNMQVJFX1NUUkVBTV9PUEVSQVRPUih1bnNpZ25lZCBsb25nIGxvbmcsICIlIiBHT09HTEVfTExfRk9STUFUICJ1IikKKyN1bmRlZiBERUNMQVJFX1NUUkVBTV9PUEVSQVRPUgorCitMb2dNZXNzYWdlOjpMb2dNZXNzYWdlKExvZ0xldmVsIGxldmVsLCBjb25zdCBjaGFyKiBmaWxlbmFtZSwgaW50IGxpbmUpCisgIDogbGV2ZWxfKGxldmVsKSwgZmlsZW5hbWVfKGZpbGVuYW1lKSwgbGluZV8obGluZSkge30KK0xvZ01lc3NhZ2U6On5Mb2dNZXNzYWdlKCkge30KKwordm9pZCBMb2dNZXNzYWdlOjpGaW5pc2goKSB7CisgIGJvb2wgc3VwcHJlc3MgPSBmYWxzZTsKKworICBpZiAobGV2ZWxfICE9IExPR0xFVkVMX0ZBVEFMKSB7CisgICAgSW5pdExvZ1NpbGVuY2VyQ291bnRPbmNlKCk7CisgICAgTXV0ZXhMb2NrIGxvY2sobG9nX3NpbGVuY2VyX2NvdW50X211dGV4Xyk7CisgICAgc3VwcHJlc3MgPSBsb2dfc2lsZW5jZXJfY291bnRfID4gMDsKKyAgfQorCisgIGlmICghc3VwcHJlc3MpIHsKKyAgICBsb2dfaGFuZGxlcl8obGV2ZWxfLCBmaWxlbmFtZV8sIGxpbmVfLCBtZXNzYWdlXyk7CisgIH0KKworICBpZiAobGV2ZWxfID09IExPR0xFVkVMX0ZBVEFMKSB7CisjaWYgUFJPVE9CVUZfVVNFX0VYQ0VQVElPTlMKKyAgICB0aHJvdyBGYXRhbEV4Y2VwdGlvbihmaWxlbmFtZV8sIGxpbmVfLCBtZXNzYWdlXyk7CisjZWxzZQorICAgIGFib3J0KCk7CisjZW5kaWYKKyAgfQorfQorCit2b2lkIExvZ0ZpbmlzaGVyOjpvcGVyYXRvcj0oTG9nTWVzc2FnZSYgb3RoZXIpIHsKKyAgb3RoZXIuRmluaXNoKCk7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorCitMb2dIYW5kbGVyKiBTZXRMb2dIYW5kbGVyKExvZ0hhbmRsZXIqIG5ld19mdW5jKSB7CisgIExvZ0hhbmRsZXIqIG9sZCA9IGludGVybmFsOjpsb2dfaGFuZGxlcl87CisgIGlmIChvbGQgPT0gJmludGVybmFsOjpOdWxsTG9nSGFuZGxlcikgeworICAgIG9sZCA9IE5VTEw7CisgIH0KKyAgaWYgKG5ld19mdW5jID09IE5VTEwpIHsKKyAgICBpbnRlcm5hbDo6bG9nX2hhbmRsZXJfID0gJmludGVybmFsOjpOdWxsTG9nSGFuZGxlcjsKKyAgfSBlbHNlIHsKKyAgICBpbnRlcm5hbDo6bG9nX2hhbmRsZXJfID0gbmV3X2Z1bmM7CisgIH0KKyAgcmV0dXJuIG9sZDsKK30KKworTG9nU2lsZW5jZXI6OkxvZ1NpbGVuY2VyKCkgeworICBpbnRlcm5hbDo6SW5pdExvZ1NpbGVuY2VyQ291bnRPbmNlKCk7CisgIE11dGV4TG9jayBsb2NrKGludGVybmFsOjpsb2dfc2lsZW5jZXJfY291bnRfbXV0ZXhfKTsKKyAgKytpbnRlcm5hbDo6bG9nX3NpbGVuY2VyX2NvdW50XzsKK307CisKK0xvZ1NpbGVuY2VyOjp+TG9nU2lsZW5jZXIoKSB7CisgIGludGVybmFsOjpJbml0TG9nU2lsZW5jZXJDb3VudE9uY2UoKTsKKyAgTXV0ZXhMb2NrIGxvY2soaW50ZXJuYWw6OmxvZ19zaWxlbmNlcl9jb3VudF9tdXRleF8pOworICAtLWludGVybmFsOjpsb2dfc2lsZW5jZXJfY291bnRfOworfTsKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorLy8gZW11bGF0ZXMgZ29vZ2xlMy9iYXNlL2NhbGxiYWNrLmNjCisKK0Nsb3N1cmU6On5DbG9zdXJlKCkge30KKworbmFtZXNwYWNlIGludGVybmFsIHsgRnVuY3Rpb25DbG9zdXJlMDo6fkZ1bmN0aW9uQ2xvc3VyZTAoKSB7fSB9CisKK3ZvaWQgRG9Ob3RoaW5nKCkge30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorLy8gZW11bGF0ZXMgZ29vZ2xlMy9iYXNlL211dGV4LmNjCisKKyNpZmRlZiBfV0lOMzIKKworc3RydWN0IE11dGV4OjpJbnRlcm5hbCB7CisgIENSSVRJQ0FMX1NFQ1RJT04gbXV0ZXg7CisjaWZuZGVmIE5ERUJVRworICAvLyBVc2VkIG9ubHkgdG8gaW1wbGVtZW50IEFzc2VydEhlbGQoKS4KKyAgRFdPUkQgdGhyZWFkX2lkOworI2VuZGlmCit9OworCitNdXRleDo6TXV0ZXgoKQorICA6IG1JbnRlcm5hbChuZXcgSW50ZXJuYWwpIHsKKyAgSW5pdGlhbGl6ZUNyaXRpY2FsU2VjdGlvbigmbUludGVybmFsLT5tdXRleCk7Cit9CisKK011dGV4Ojp+TXV0ZXgoKSB7CisgIERlbGV0ZUNyaXRpY2FsU2VjdGlvbigmbUludGVybmFsLT5tdXRleCk7CisgIGRlbGV0ZSBtSW50ZXJuYWw7Cit9CisKK3ZvaWQgTXV0ZXg6OkxvY2soKSB7CisgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZtSW50ZXJuYWwtPm11dGV4KTsKKyNpZm5kZWYgTkRFQlVHCisgIG1JbnRlcm5hbC0+dGhyZWFkX2lkID0gR2V0Q3VycmVudFRocmVhZElkKCk7CisjZW5kaWYKK30KKwordm9pZCBNdXRleDo6VW5sb2NrKCkgeworI2lmbmRlZiBOREVCVUcKKyAgbUludGVybmFsLT50aHJlYWRfaWQgPSAwOworI2VuZGlmCisgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZtSW50ZXJuYWwtPm11dGV4KTsKK30KKwordm9pZCBNdXRleDo6QXNzZXJ0SGVsZCgpIHsKKyNpZm5kZWYgTkRFQlVHCisgIEdPT0dMRV9EQ0hFQ0tfRVEobUludGVybmFsLT50aHJlYWRfaWQsIEdldEN1cnJlbnRUaHJlYWRJZCgpKTsKKyNlbmRpZgorfQorCisjZWxpZiBkZWZpbmVkKEhBVkVfUFRIUkVBRCkKKworc3RydWN0IE11dGV4OjpJbnRlcm5hbCB7CisgIHB0aHJlYWRfbXV0ZXhfdCBtdXRleDsKK307CisKK011dGV4OjpNdXRleCgpCisgIDogbUludGVybmFsKG5ldyBJbnRlcm5hbCkgeworICBwdGhyZWFkX211dGV4X2luaXQoJm1JbnRlcm5hbC0+bXV0ZXgsIE5VTEwpOworfQorCitNdXRleDo6fk11dGV4KCkgeworICBwdGhyZWFkX211dGV4X2Rlc3Ryb3koJm1JbnRlcm5hbC0+bXV0ZXgpOworICBkZWxldGUgbUludGVybmFsOworfQorCit2b2lkIE11dGV4OjpMb2NrKCkgeworICBpbnQgcmVzdWx0ID0gcHRocmVhZF9tdXRleF9sb2NrKCZtSW50ZXJuYWwtPm11dGV4KTsKKyAgaWYgKHJlc3VsdCAhPSAwKSB7CisgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgInB0aHJlYWRfbXV0ZXhfbG9jazogIiA8PCBzdHJlcnJvcihyZXN1bHQpOworICB9Cit9CisKK3ZvaWQgTXV0ZXg6OlVubG9jaygpIHsKKyAgaW50IHJlc3VsdCA9IHB0aHJlYWRfbXV0ZXhfdW5sb2NrKCZtSW50ZXJuYWwtPm11dGV4KTsKKyAgaWYgKHJlc3VsdCAhPSAwKSB7CisgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgInB0aHJlYWRfbXV0ZXhfdW5sb2NrOiAiIDw8IHN0cmVycm9yKHJlc3VsdCk7CisgIH0KK30KKwordm9pZCBNdXRleDo6QXNzZXJ0SGVsZCgpIHsKKyAgLy8gcHRocmVhZHMgZG9zbid0IHByb3ZpZGUgYSB3YXkgdG8gY2hlY2sgd2hpY2ggdGhyZWFkIGhvbGRzIHRoZSBtdXRleC4KKyAgLy8gVE9ETyhrZW50b24pOiAgTWF5YmUga2VlcCB0cmFjayBvZiBsb2NraW5nIHRocmVhZCBJRCBsaWtlIHdpdGggV0lOMzI/Cit9CisKKyNlbmRpZgorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisvLyBlbXVsYXRlcyBnb29nbGUzL3V0aWwvZW5kaWFuL2VuZGlhbi5oCisvLworLy8gVE9ETyh4aWFvZmVuZyk6IFBST1RPQlVGX0xJVFRMRV9FTkRJQU4gaXMgdW5mb3J0dW5hdGVseSBkZWZpbmVkIGluCisvLyBnb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmggYW5kIHRoZXJlZm9yZSBjYW4gbm90IGJlIHVzZWQgaGVyZS4KKy8vIE1heWJlIG1vdmUgdGhhdCBtYWNybyBkZWZpbml0aW9uIGhlcmUgaW4gdGhlIGZ1cnR1cmUuCit1aW50MzIgZ2h0b25sKHVpbnQzMiB4KSB7CisgIHVuaW9uIHsKKyAgICB1aW50MzIgcmVzdWx0OworICAgIHVpbnQ4IHJlc3VsdF9hcnJheVs0XTsKKyAgfTsKKyAgcmVzdWx0X2FycmF5WzBdID0gc3RhdGljX2Nhc3Q8dWludDg+KHggPj4gMjQpOworICByZXN1bHRfYXJyYXlbMV0gPSBzdGF0aWNfY2FzdDx1aW50OD4oKHggPj4gMTYpICYgMHhGRik7CisgIHJlc3VsdF9hcnJheVsyXSA9IHN0YXRpY19jYXN0PHVpbnQ4PigoeCA+PiA4KSAmIDB4RkYpOworICByZXN1bHRfYXJyYXlbM10gPSBzdGF0aWNfY2FzdDx1aW50OD4oeCAmIDB4RkYpOworICByZXR1cm4gcmVzdWx0OworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisvLyBTaHV0ZG93biBzdXBwb3J0LgorCituYW1lc3BhY2UgaW50ZXJuYWwgeworCit0eXBlZGVmIHZvaWQgT25TaHV0ZG93bkZ1bmMoKTsKK3ZlY3Rvcjx2b2lkICgqKSgpPiogc2h1dGRvd25fZnVuY3Rpb25zID0gTlVMTDsKK011dGV4KiBzaHV0ZG93bl9mdW5jdGlvbnNfbXV0ZXggPSBOVUxMOworR09PR0xFX1BST1RPQlVGX0RFQ0xBUkVfT05DRShzaHV0ZG93bl9mdW5jdGlvbnNfaW5pdCk7CisKK3ZvaWQgSW5pdFNodXRkb3duRnVuY3Rpb25zKCkgeworICBzaHV0ZG93bl9mdW5jdGlvbnMgPSBuZXcgdmVjdG9yPHZvaWQgKCopKCk+OworICBzaHV0ZG93bl9mdW5jdGlvbnNfbXV0ZXggPSBuZXcgTXV0ZXg7Cit9CisKK2lubGluZSB2b2lkIEluaXRTaHV0ZG93bkZ1bmN0aW9uc09uY2UoKSB7CisgIEdvb2dsZU9uY2VJbml0KCZzaHV0ZG93bl9mdW5jdGlvbnNfaW5pdCwgJkluaXRTaHV0ZG93bkZ1bmN0aW9ucyk7Cit9CisKK3ZvaWQgT25TaHV0ZG93bih2b2lkICgqZnVuYykoKSkgeworICBJbml0U2h1dGRvd25GdW5jdGlvbnNPbmNlKCk7CisgIE11dGV4TG9jayBsb2NrKHNodXRkb3duX2Z1bmN0aW9uc19tdXRleCk7CisgIHNodXRkb3duX2Z1bmN0aW9ucy0+cHVzaF9iYWNrKGZ1bmMpOworfQorCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKKwordm9pZCBTaHV0ZG93blByb3RvYnVmTGlicmFyeSgpIHsKKyAgaW50ZXJuYWw6OkluaXRTaHV0ZG93bkZ1bmN0aW9uc09uY2UoKTsKKworICAvLyBXZSBkb24ndCBuZWVkIHRvIGxvY2sgc2h1dGRvd25fZnVuY3Rpb25zX211dGV4IGJlY2F1c2UgaXQncyB1cCB0byB0aGUKKyAgLy8gY2FsbGVyIHRvIG1ha2Ugc3VyZSB0aGF0IG5vIG9uZSBpcyB1c2luZyB0aGUgbGlicmFyeSBiZWZvcmUgdGhpcyBpcworICAvLyBjYWxsZWQuCisKKyAgLy8gTWFrZSBpdCBzYWZlIHRvIGNhbGwgdGhpcyBtdWx0aXBsZSB0aW1lcy4KKyAgaWYgKGludGVybmFsOjpzaHV0ZG93bl9mdW5jdGlvbnMgPT0gTlVMTCkgcmV0dXJuOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgaW50ZXJuYWw6OnNodXRkb3duX2Z1bmN0aW9ucy0+c2l6ZSgpOyBpKyspIHsKKyAgICBpbnRlcm5hbDo6c2h1dGRvd25fZnVuY3Rpb25zLT5hdChpKSgpOworICB9CisgIGRlbGV0ZSBpbnRlcm5hbDo6c2h1dGRvd25fZnVuY3Rpb25zOworICBpbnRlcm5hbDo6c2h1dGRvd25fZnVuY3Rpb25zID0gTlVMTDsKKyAgZGVsZXRlIGludGVybmFsOjpzaHV0ZG93bl9mdW5jdGlvbnNfbXV0ZXg7CisgIGludGVybmFsOjpzaHV0ZG93bl9mdW5jdGlvbnNfbXV0ZXggPSBOVUxMOworfQorCisjaWYgUFJPVE9CVUZfVVNFX0VYQ0VQVElPTlMKK0ZhdGFsRXhjZXB0aW9uOjp+RmF0YWxFeGNlcHRpb24oKSB0aHJvdygpIHt9CisKK2NvbnN0IGNoYXIqIEZhdGFsRXhjZXB0aW9uOjp3aGF0KCkgY29uc3QgdGhyb3coKSB7CisgIHJldHVybiBtZXNzYWdlXy5jX3N0cigpOworfQorI2VuZGlmCisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWMwNWNhYwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmgKQEAgLTAsMCArMSwyMjUgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpIGFuZCBvdGhlcnMKKy8vCisvLyBDb250YWlucyBiYXNpYyB0eXBlcyBhbmQgdXRpbGl0aWVzIHVzZWQgYnkgdGhlIHJlc3Qgb2YgdGhlIGxpYnJhcnkuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0NPTU1PTl9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0NPTU1PTl9IX18KKworI2luY2x1ZGUgPHN0cmluZz4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9wb3J0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL21hY3Jvcy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9wbGF0Zm9ybV9tYWNyb3MuaD4KKworLy8gVE9ETyhsaXVqaXNpKTogUmVtb3ZlIHRoZSBmb2xsb3dpbmcgaW5jbHVkZXMgYWZ0ZXIgdGhlIGluY2x1ZGUgY2xlYW4tdXAuCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2xvZ2dpbmcuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc2NvcGVkX3B0ci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9tdXRleC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jYWxsYmFjay5oPgorCisjaWZuZGVmIFBST1RPQlVGX1VTRV9FWENFUFRJT05TCisjaWYgZGVmaW5lZChfTVNDX1ZFUikgJiYgZGVmaW5lZChfQ1BQVU5XSU5EKQorICAjZGVmaW5lIFBST1RPQlVGX1VTRV9FWENFUFRJT05TIDEKKyNlbGlmIGRlZmluZWQoX19FWENFUFRJT05TKQorICAjZGVmaW5lIFBST1RPQlVGX1VTRV9FWENFUFRJT05TIDEKKyNlbHNlCisgICNkZWZpbmUgUFJPVE9CVUZfVVNFX0VYQ0VQVElPTlMgMAorI2VuZGlmCisjZW5kaWYKKworI2lmIFBST1RPQlVGX1VTRV9FWENFUFRJT05TCisjaW5jbHVkZSA8ZXhjZXB0aW9uPgorI2VuZGlmCisjaWYgZGVmaW5lZChfX0FQUExFX18pCisjaW5jbHVkZSA8VGFyZ2V0Q29uZGl0aW9uYWxzLmg+ICAvLyBmb3IgVEFSR0VUX09TX0lQSE9ORQorI2VuZGlmCisKKyNpZiBkZWZpbmVkKF9fQU5EUk9JRF9fKSB8fCBkZWZpbmVkKEdPT0dMRV9QUk9UT0JVRl9PU19BTkRST0lEKSB8fCAoZGVmaW5lZChUQVJHRVRfT1NfSVBIT05FKSAmJiBUQVJHRVRfT1NfSVBIT05FKSB8fCBkZWZpbmVkKEdPT0dMRV9QUk9UT0JVRl9PU19JUEhPTkUpCisjaW5jbHVkZSA8cHRocmVhZC5oPgorI2VuZGlmCisKKyNpZiBkZWZpbmVkKF9XSU4zMikgJiYgZGVmaW5lZChHZXRNZXNzYWdlKQorLy8gQWxsb3cgR2V0TWVzc2FnZSB0byBiZSB1c2VkIGFzIGEgdmFsaWQgbWV0aG9kIG5hbWUgaW4gcHJvdG9idWYgY2xhc3Nlcy4KKy8vIHdpbmRvd3MuaCBkZWZpbmVzIEdldE1lc3NhZ2UoKSBhcyBhIG1hY3JvLiAgTGV0J3MgcmUtZGVmaW5lIGl0IGFzIGFuIGlubGluZQorLy8gZnVuY3Rpb24uICBUaGUgaW5saW5lIGZ1bmN0aW9uIHNob3VsZCBiZSBlcXVpdmFsZW50IGZvciBDKysgdXNlcnMuCitpbmxpbmUgQk9PTCBHZXRNZXNzYWdlX1dpbjMyKAorICAgIExQTVNHIGxwTXNnLCBIV05EIGhXbmQsCisgICAgVUlOVCB3TXNnRmlsdGVyTWluLCBVSU5UIHdNc2dGaWx0ZXJNYXgpIHsKKyAgcmV0dXJuIEdldE1lc3NhZ2UobHBNc2csIGhXbmQsIHdNc2dGaWx0ZXJNaW4sIHdNc2dGaWx0ZXJNYXgpOworfQorI3VuZGVmIEdldE1lc3NhZ2UKK2lubGluZSBCT09MIEdldE1lc3NhZ2UoCisgICAgTFBNU0cgbHBNc2csIEhXTkQgaFduZCwKKyAgICBVSU5UIHdNc2dGaWx0ZXJNaW4sIFVJTlQgd01zZ0ZpbHRlck1heCkgeworICByZXR1cm4gR2V0TWVzc2FnZV9XaW4zMihscE1zZywgaFduZCwgd01zZ0ZpbHRlck1pbiwgd01zZ0ZpbHRlck1heCk7Cit9CisjZW5kaWYKKworbmFtZXNwYWNlIHN0ZCB7fQorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW50ZXJuYWwgeworCisvLyBTb21lIG9mIHRoZXNlIGNvbnN0YW50cyBhcmUgbWFjcm9zIHJhdGhlciB0aGFuIGNvbnN0IGludHMgc28gdGhhdCB0aGV5IGNhbgorLy8gYmUgdXNlZCBpbiAjaWYgZGlyZWN0aXZlcy4KKworLy8gVGhlIGN1cnJlbnQgdmVyc2lvbiwgcmVwcmVzZW50ZWQgYXMgYSBzaW5nbGUgaW50ZWdlciB0byBtYWtlIGNvbXBhcmlzb24KKy8vIGVhc2llcjogIG1ham9yICogMTBeNiArIG1pbm9yICogMTBeMyArIG1pY3JvCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9WRVJTSU9OIDMwMDAwMDAKKworLy8gVGhlIG1pbmltdW0gbGlicmFyeSB2ZXJzaW9uIHdoaWNoIHdvcmtzIHdpdGggdGhlIGN1cnJlbnQgdmVyc2lvbiBvZiB0aGUKKy8vIGhlYWRlcnMuCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9NSU5fTElCUkFSWV9WRVJTSU9OIDMwMDAwMDAKKworLy8gVGhlIG1pbmltdW0gaGVhZGVyIHZlcnNpb24gd2hpY2ggd29ya3Mgd2l0aCB0aGUgY3VycmVudCB2ZXJzaW9uIG9mCisvLyB0aGUgbGlicmFyeS4gIFRoaXMgY29uc3RhbnQgc2hvdWxkIG9ubHkgYmUgdXNlZCBieSBwcm90b2MncyBDKysgY29kZQorLy8gZ2VuZXJhdG9yLgorc3RhdGljIGNvbnN0IGludCBrTWluSGVhZGVyVmVyc2lvbkZvckxpYnJhcnkgPSAzMDAwMDAwOworCisvLyBUaGUgbWluaW11bSBwcm90b2MgdmVyc2lvbiB3aGljaCB3b3JrcyB3aXRoIHRoZSBjdXJyZW50IHZlcnNpb24gb2YgdGhlCisvLyBoZWFkZXJzLgorI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfTUlOX1BST1RPQ19WRVJTSU9OIDMwMDAwMDAKKworLy8gVGhlIG1pbmltdW0gaGVhZGVyIHZlcnNpb24gd2hpY2ggd29ya3Mgd2l0aCB0aGUgY3VycmVudCB2ZXJzaW9uIG9mCisvLyBwcm90b2MuICBUaGlzIGNvbnN0YW50IHNob3VsZCBvbmx5IGJlIHVzZWQgaW4gVmVyaWZ5VmVyc2lvbigpLgorc3RhdGljIGNvbnN0IGludCBrTWluSGVhZGVyVmVyc2lvbkZvclByb3RvYyA9IDMwMDAwMDA7CisKKy8vIFZlcmlmaWVzIHRoYXQgdGhlIGhlYWRlcnMgYW5kIGxpYnJhcmllcyBhcmUgY29tcGF0aWJsZS4gIFVzZSB0aGUgbWFjcm8KKy8vIGJlbG93IHRvIGNhbGwgdGhpcy4KK3ZvaWQgTElCUFJPVE9CVUZfRVhQT1JUIFZlcmlmeVZlcnNpb24oaW50IGhlYWRlclZlcnNpb24sIGludCBtaW5MaWJyYXJ5VmVyc2lvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogZmlsZW5hbWUpOworCisvLyBDb252ZXJ0cyBhIG51bWVyaWMgdmVyc2lvbiBudW1iZXIgdG8gYSBzdHJpbmcuCitzdGQ6OnN0cmluZyBMSUJQUk9UT0JVRl9FWFBPUlQgVmVyc2lvblN0cmluZyhpbnQgdmVyc2lvbik7CisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorCisvLyBQbGFjZSB0aGlzIG1hY3JvIGluIHlvdXIgbWFpbigpIGZ1bmN0aW9uIChvciBzb21ld2hlcmUgYmVmb3JlIHlvdSBhdHRlbXB0CisvLyB0byB1c2UgdGhlIHByb3RvYnVmIGxpYnJhcnkpIHRvIHZlcmlmeSB0aGF0IHRoZSB2ZXJzaW9uIHlvdSBsaW5rIGFnYWluc3QKKy8vIG1hdGNoZXMgdGhlIGhlYWRlcnMgeW91IGNvbXBpbGVkIGFnYWluc3QuICBJZiBhIHZlcnNpb24gbWlzbWF0Y2ggaXMKKy8vIGRldGVjdGVkLCB0aGUgcHJvY2VzcyB3aWxsIGFib3J0LgorI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfVkVSSUZZX1ZFUlNJT04gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlZlcmlmeVZlcnNpb24oICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBHT09HTEVfUFJPVE9CVUZfVkVSU0lPTiwgR09PR0xFX1BST1RPQlVGX01JTl9MSUJSQVJZX1ZFUlNJT04sICAgICAgICAgXAorICAgIF9fRklMRV9fKQorCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKy8vIGZyb20gZ29vZ2xlMy91dGlsL3V0ZjgvcHVibGljL3VuaWxpYi5oCisKK2NsYXNzIFN0cmluZ1BpZWNlOworbmFtZXNwYWNlIGludGVybmFsIHsKKworLy8gQ2hlY2tzIGlmIHRoZSBidWZmZXIgY29udGFpbnMgc3RydWN0dXJhbGx5LXZhbGlkIFVURi04LiAgSW1wbGVtZW50ZWQgaW4KKy8vIHN0cnVjdHVyYWxseV92YWxpZC5jYy4KK0xJQlBST1RPQlVGX0VYUE9SVCBib29sIElzU3RydWN0dXJhbGx5VmFsaWRVVEY4KGNvbnN0IGNoYXIqIGJ1ZiwgaW50IGxlbik7CisKK2lubGluZSBib29sIElzU3RydWN0dXJhbGx5VmFsaWRVVEY4KGNvbnN0IHN0ZDo6c3RyaW5nJiBzdHIpIHsKKyAgcmV0dXJuIElzU3RydWN0dXJhbGx5VmFsaWRVVEY4KHN0ci5kYXRhKCksIHN0YXRpY19jYXN0PGludD4oc3RyLmxlbmd0aCgpKSk7Cit9CisKKy8vIFJldHVybnMgaW5pdGlhbCBudW1iZXIgb2YgYnl0ZXMgb2Ygc3RydWN0dWFsbHkgdmFsaWQgVVRGLTguCitMSUJQUk9UT0JVRl9FWFBPUlQgaW50IFVURjhTcG5TdHJ1Y3R1cmFsbHlWYWxpZChjb25zdCBTdHJpbmdQaWVjZSYgc3RyKTsKKworLy8gQ29lcmNlIFVURi04IGJ5dGUgc3RyaW5nIGluIHNyY19zdHIgdG8gYmUKKy8vIGEgc3RydWN0dXJhbGx5LXZhbGlkIGVxdWFsLWxlbmd0aCBzdHJpbmcgYnkgc2VsZWN0aXZlbHkKKy8vIG92ZXJ3cml0aW5nIGlsbGVnYWwgYnl0ZXMgd2l0aCByZXBsYWNlX2NoYXIgKHR5cGljYWxseSAnICcgb3IgJz8nKS4KKy8vIHJlcGxhY2VfY2hhciBtdXN0IGJlIGxlZ2FsIHByaW50YWJsZSA3LWJpdCBBc2NpaSAweDIwLi4weDdlLgorLy8gc3JjX3N0ciBpcyByZWFkLW9ubHkuCisvLworLy8gUmV0dXJucyBwb2ludGVyIHRvIG91dHB1dCBidWZmZXIsIHNyY19zdHIuZGF0YSgpIGlmIG5vIGNoYW5nZXMgd2VyZSBtYWRlLAorLy8gIG9yIGlkc3QgaWYgc29tZSBieXRlcyB3ZXJlIGNoYW5nZWQuIGlkc3QgaXMgYWxsb2NhdGVkIGJ5IHRoZSBjYWxsZXIKKy8vICBhbmQgbXVzdCBiZSBhdCBsZWFzdCBhcyBiaWcgYXMgc3JjX3N0cgorLy8KKy8vIE9wdGltaXplZCBmb3I6IGFsbCBzdHJ1Y3R1cmFsbHkgdmFsaWQgYW5kIG5vIGJ5dGUgY29weWluZyBpcyBkb25lLgorLy8KK0xJQlBST1RPQlVGX0VYUE9SVCBjaGFyKiBVVEY4Q29lcmNlVG9TdHJ1Y3R1cmFsbHlWYWxpZCgKKyAgICBjb25zdCBTdHJpbmdQaWVjZSYgc3RyLCBjaGFyKiBkc3QsIGNoYXIgcmVwbGFjZV9jaGFyKTsKKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCisKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorLy8gU2h1dGRvd24gc3VwcG9ydC4KKworLy8gU2h1dCBkb3duIHRoZSBlbnRpcmUgcHJvdG9jb2wgYnVmZmVycyBsaWJyYXJ5LCBkZWxldGluZyBhbGwgc3RhdGljLWR1cmF0aW9uCisvLyBvYmplY3RzIGFsbG9jYXRlZCBieSB0aGUgbGlicmFyeSBvciBieSBnZW5lcmF0ZWQgLnBiLmNjIGZpbGVzLgorLy8KKy8vIFRoZXJlIGFyZSB0d28gcmVhc29ucyB5b3UgbWlnaHQgd2FudCB0byBjYWxsIHRoaXM6CisvLyAqIFlvdSB1c2UgYSBkcmFjb25pYW4gZGVmaW5pdGlvbiBvZiAibWVtb3J5IGxlYWsiIGluIHdoaWNoIHlvdSBleHBlY3QKKy8vICAgZXZlcnkgc2luZ2xlIG1hbGxvYygpIHRvIGhhdmUgYSBjb3JyZXNwb25kaW5nIGZyZWUoKSwgZXZlbiBmb3Igb2JqZWN0cworLy8gICB3aGljaCBsaXZlIHVudGlsIHByb2dyYW0gZXhpdC4KKy8vICogWW91IGFyZSB3cml0aW5nIGEgZHluYW1pY2FsbHktbG9hZGVkIGxpYnJhcnkgd2hpY2ggbmVlZHMgdG8gY2xlYW4gdXAKKy8vICAgYWZ0ZXIgaXRzZWxmIHdoZW4gdGhlIGxpYnJhcnkgaXMgdW5sb2FkZWQuCisvLworLy8gSXQgaXMgc2FmZSB0byBjYWxsIHRoaXMgbXVsdGlwbGUgdGltZXMuICBIb3dldmVyLCBpdCBpcyBub3Qgc2FmZSB0byB1c2UKKy8vIGFueSBvdGhlciBwYXJ0IG9mIHRoZSBwcm90b2NvbCBidWZmZXJzIGxpYnJhcnkgYWZ0ZXIKKy8vIFNodXRkb3duUHJvdG9idWZMaWJyYXJ5KCkgaGFzIGJlZW4gY2FsbGVkLgorTElCUFJPVE9CVUZfRVhQT1JUIHZvaWQgU2h1dGRvd25Qcm90b2J1ZkxpYnJhcnkoKTsKKworbmFtZXNwYWNlIGludGVybmFsIHsKKworLy8gUmVnaXN0ZXIgYSBmdW5jdGlvbiB0byBiZSBjYWxsZWQgd2hlbiBTaHV0ZG93blByb3RvY29sQnVmZmVycygpIGlzIGNhbGxlZC4KK0xJQlBST1RPQlVGX0VYUE9SVCB2b2lkIE9uU2h1dGRvd24odm9pZCAoKmZ1bmMpKCkpOworCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKKworI2lmIFBST1RPQlVGX1VTRV9FWENFUFRJT05TCitjbGFzcyBGYXRhbEV4Y2VwdGlvbiA6IHB1YmxpYyBzdGQ6OmV4Y2VwdGlvbiB7CisgcHVibGljOgorICBGYXRhbEV4Y2VwdGlvbihjb25zdCBjaGFyKiBmaWxlbmFtZSwgaW50IGxpbmUsIGNvbnN0IHN0ZDo6c3RyaW5nJiBtZXNzYWdlKQorICAgICAgOiBmaWxlbmFtZV8oZmlsZW5hbWUpLCBsaW5lXyhsaW5lKSwgbWVzc2FnZV8obWVzc2FnZSkge30KKyAgdmlydHVhbCB+RmF0YWxFeGNlcHRpb24oKSB0aHJvdygpOworCisgIHZpcnR1YWwgY29uc3QgY2hhciogd2hhdCgpIGNvbnN0IHRocm93KCk7CisKKyAgY29uc3QgY2hhciogZmlsZW5hbWUoKSBjb25zdCB7IHJldHVybiBmaWxlbmFtZV87IH0KKyAgaW50IGxpbmUoKSBjb25zdCB7IHJldHVybiBsaW5lXzsgfQorICBjb25zdCBzdGQ6OnN0cmluZyYgbWVzc2FnZSgpIGNvbnN0IHsgcmV0dXJuIG1lc3NhZ2VfOyB9CisKKyBwcml2YXRlOgorICBjb25zdCBjaGFyKiBmaWxlbmFtZV87CisgIGNvbnN0IGludCBsaW5lXzsKKyAgY29uc3Qgc3RkOjpzdHJpbmcgbWVzc2FnZV87Cit9OworI2VuZGlmCisKKy8vIFRoaXMgaXMgYXQgdGhlIGVuZCBvZiB0aGUgZmlsZSBpbnN0ZWFkIG9mIHRoZSBiZWdpbm5pbmcgdG8gd29yayBhcm91bmQgYSBidWcKKy8vIGluIHNvbWUgdmVyc2lvbnMgb2YgTVNWQy4KK3VzaW5nIG5hbWVzcGFjZSBzdGQ7ICAvLyBEb24ndCBkbyB0aGlzIGF0IGhvbWUsIGtpZHMuCisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9DT01NT05fSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbl91bml0dGVzdC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uX3VuaXR0ZXN0LmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI1YmFlOWIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbl91bml0dGVzdC5jYwpAQCAtMCwwICsxLDM1OCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKworI2luY2x1ZGUgPHZlY3Rvcj4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY2FzdHMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3Vic3RpdHV0ZS5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZ29vZ2xldGVzdC5oPgorI2luY2x1ZGUgPGd0ZXN0L2d0ZXN0Lmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK3VzaW5nIGludGVybmFsOjpOZXdDYWxsYmFjazsKK3VzaW5nIGludGVybmFsOjpOZXdQZXJtYW5lbnRDYWxsYmFjazsKK25hbWVzcGFjZSB7CisKKy8vIFRPRE8oa2VudG9uKTogIE1vcmUgdGVzdHMuCisKKyNpZmRlZiBQQUNLQUdFX1ZFUlNJT04gIC8vIG9ubHkgZGVmaW5lZCB3aGVuIHVzaW5nIGF1dG9tYWtlLCBub3QgTVNWQworCitURVNUKFZlcnNpb25UZXN0LCBWZXJzaW9uTWF0Y2hlc0NvbmZpZykgeworICAvLyBWZXJpZnkgdGhhdCB0aGUgdmVyc2lvbiBzdHJpbmcgc3BlY2lmaWVkIGluIGNvbmZpZy5oIG1hdGNoZXMgdGhlIG9uZQorICAvLyBpbiBjb21tb24uaC4gIFRoZSBjb25maWcuaCB2ZXJzaW9uIGlzIGEgc3RyaW5nIHdoaWNoIG1heSBoYXZlIGEgc3VmZml4CisgIC8vIGxpa2UgImJldGEiIG9yICJyYzEiLCBzbyB3ZSByZW1vdmUgdGhhdC4KKyAgc3RyaW5nIHZlcnNpb24gPSBQQUNLQUdFX1ZFUlNJT047CisgIGludCBwb3MgPSAwOworICB3aGlsZSAocG9zIDwgdmVyc2lvbi5zaXplKCkgJiYKKyAgICAgICAgIChhc2NpaV9pc2RpZ2l0KHZlcnNpb25bcG9zXSkgfHwgdmVyc2lvbltwb3NdID09ICcuJykpIHsKKyAgICArK3BvczsKKyAgfQorICB2ZXJzaW9uLmVyYXNlKHBvcyk7CisKKyAgRVhQRUNUX0VRKHZlcnNpb24sIGludGVybmFsOjpWZXJzaW9uU3RyaW5nKEdPT0dMRV9QUk9UT0JVRl9WRVJTSU9OKSk7Cit9CisKKyNlbmRpZiAgLy8gUEFDS0FHRV9WRVJTSU9OCisKK1RFU1QoQ29tbW9uVGVzdCwgSW50TWluTWF4Q29uc3RhbnRzKSB7CisgIC8vIGtpbnQzMm1pbiB3YXMgZGVjbGFyZWQgaW5jb3JyZWN0bHkgaW4gdGhlIGZpcnN0IHJlbGVhc2Ugb2YgcHJvdG9idWZzLgorICAvLyBVZ2guCisgIEVYUEVDVF9MVChraW50MzJtaW4sIGtpbnQzMm1heCk7CisgIEVYUEVDVF9FUShzdGF0aWNfY2FzdDx1aW50MzI+KGtpbnQzMm1pbiksIHN0YXRpY19jYXN0PHVpbnQzMj4oa2ludDMybWF4KSArIDEpOworICBFWFBFQ1RfTFQoa2ludDY0bWluLCBraW50NjRtYXgpOworICBFWFBFQ1RfRVEoc3RhdGljX2Nhc3Q8dWludDY0PihraW50NjRtaW4pLCBzdGF0aWNfY2FzdDx1aW50NjQ+KGtpbnQ2NG1heCkgKyAxKTsKKyAgRVhQRUNUX0VRKDAsIGt1aW50MzJtYXggKyAxKTsKKyAgRVhQRUNUX0VRKDAsIGt1aW50NjRtYXggKyAxKTsKK30KKwordmVjdG9yPHN0cmluZz4gY2FwdHVyZWRfbWVzc2FnZXNfOworCit2b2lkIENhcHR1cmVMb2coTG9nTGV2ZWwgbGV2ZWwsIGNvbnN0IGNoYXIqIGZpbGVuYW1lLCBpbnQgbGluZSwKKyAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIG1lc3NhZ2UpIHsKKyAgY2FwdHVyZWRfbWVzc2FnZXNfLnB1c2hfYmFjaygKKyAgICBzdHJpbmdzOjpTdWJzdGl0dXRlKCIkMCAkMTokMjogJDMiLAorICAgICAgaW1wbGljaXRfY2FzdDxpbnQ+KGxldmVsKSwgZmlsZW5hbWUsIGxpbmUsIG1lc3NhZ2UpKTsKK30KKworVEVTVChMb2dnaW5nVGVzdCwgRGVmYXVsdExvZ2dpbmcpIHsKKyAgQ2FwdHVyZVRlc3RTdGRlcnIoKTsKKyAgaW50IGxpbmUgPSBfX0xJTkVfXzsKKyAgR09PR0xFX0xPRyhJTkZPICAgKSA8PCAiQSBtZXNzYWdlLiI7CisgIEdPT0dMRV9MT0coV0FSTklORykgPDwgIkEgd2FybmluZy4iOworICBHT09HTEVfTE9HKEVSUk9SICApIDw8ICJBbiBlcnJvci4iOworCisgIHN0cmluZyB0ZXh0ID0gR2V0Q2FwdHVyZWRUZXN0U3RkZXJyKCk7CisgIEVYUEVDVF9FUSgKKyAgICAiW2xpYnByb3RvYnVmIElORk8gIiBfX0ZJTEVfXyAiOiIgKyBTaW1wbGVJdG9hKGxpbmUgKyAxKSArICJdIEEgbWVzc2FnZS5cbiIKKyAgICAiW2xpYnByb3RvYnVmIFdBUk5JTkcgIiBfX0ZJTEVfXyAiOiIgKyBTaW1wbGVJdG9hKGxpbmUgKyAyKSArICJdIEEgd2FybmluZy5cbiIKKyAgICAiW2xpYnByb3RvYnVmIEVSUk9SICIgX19GSUxFX18gIjoiICsgU2ltcGxlSXRvYShsaW5lICsgMykgKyAiXSBBbiBlcnJvci5cbiIsCisgICAgdGV4dCk7Cit9CisKK1RFU1QoTG9nZ2luZ1Rlc3QsIE51bGxMb2dnaW5nKSB7CisgIExvZ0hhbmRsZXIqIG9sZF9oYW5kbGVyID0gU2V0TG9nSGFuZGxlcihOVUxMKTsKKworICBDYXB0dXJlVGVzdFN0ZGVycigpOworICBHT09HTEVfTE9HKElORk8gICApIDw8ICJBIG1lc3NhZ2UuIjsKKyAgR09PR0xFX0xPRyhXQVJOSU5HKSA8PCAiQSB3YXJuaW5nLiI7CisgIEdPT0dMRV9MT0coRVJST1IgICkgPDwgIkFuIGVycm9yLiI7CisKKyAgRVhQRUNUX1RSVUUoU2V0TG9nSGFuZGxlcihvbGRfaGFuZGxlcikgPT0gTlVMTCk7CisKKyAgc3RyaW5nIHRleHQgPSBHZXRDYXB0dXJlZFRlc3RTdGRlcnIoKTsKKyAgRVhQRUNUX0VRKCIiLCB0ZXh0KTsKK30KKworVEVTVChMb2dnaW5nVGVzdCwgQ2FwdHVyZUxvZ2dpbmcpIHsKKyAgY2FwdHVyZWRfbWVzc2FnZXNfLmNsZWFyKCk7CisKKyAgTG9nSGFuZGxlciogb2xkX2hhbmRsZXIgPSBTZXRMb2dIYW5kbGVyKCZDYXB0dXJlTG9nKTsKKworICBpbnQgc3RhcnRfbGluZSA9IF9fTElORV9fOworICBHT09HTEVfTE9HKEVSUk9SKSA8PCAiQW4gZXJyb3IuIjsKKyAgR09PR0xFX0xPRyhXQVJOSU5HKSA8PCAiQSB3YXJuaW5nLiI7CisKKyAgRVhQRUNUX1RSVUUoU2V0TG9nSGFuZGxlcihvbGRfaGFuZGxlcikgPT0gJkNhcHR1cmVMb2cpOworCisgIEFTU0VSVF9FUSgyLCBjYXB0dXJlZF9tZXNzYWdlc18uc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKAorICAgICIyICIgX19GSUxFX18gIjoiICsgU2ltcGxlSXRvYShzdGFydF9saW5lICsgMSkgKyAiOiBBbiBlcnJvci4iLAorICAgIGNhcHR1cmVkX21lc3NhZ2VzX1swXSk7CisgIEVYUEVDVF9FUSgKKyAgICAiMSAiIF9fRklMRV9fICI6IiArIFNpbXBsZUl0b2Eoc3RhcnRfbGluZSArIDIpICsgIjogQSB3YXJuaW5nLiIsCisgICAgY2FwdHVyZWRfbWVzc2FnZXNfWzFdKTsKK30KKworVEVTVChMb2dnaW5nVGVzdCwgU2lsZW5jZUxvZ2dpbmcpIHsKKyAgY2FwdHVyZWRfbWVzc2FnZXNfLmNsZWFyKCk7CisKKyAgTG9nSGFuZGxlciogb2xkX2hhbmRsZXIgPSBTZXRMb2dIYW5kbGVyKCZDYXB0dXJlTG9nKTsKKworICBpbnQgbGluZTEgPSBfX0xJTkVfXzsgR09PR0xFX0xPRyhJTkZPKSA8PCAiVmlzaWJsZTEiOworICBMb2dTaWxlbmNlciogc2lsZW5jZXIxID0gbmV3IExvZ1NpbGVuY2VyOworICBHT09HTEVfTE9HKElORk8pIDw8ICJOb3QgdmlzaWJsZS4iOworICBMb2dTaWxlbmNlciogc2lsZW5jZXIyID0gbmV3IExvZ1NpbGVuY2VyOworICBHT09HTEVfTE9HKElORk8pIDw8ICJOb3QgdmlzaWJsZS4iOworICBkZWxldGUgc2lsZW5jZXIxOworICBHT09HTEVfTE9HKElORk8pIDw8ICJOb3QgdmlzaWJsZS4iOworICBkZWxldGUgc2lsZW5jZXIyOworICBpbnQgbGluZTIgPSBfX0xJTkVfXzsgR09PR0xFX0xPRyhJTkZPKSA8PCAiVmlzaWJsZTIiOworCisgIEVYUEVDVF9UUlVFKFNldExvZ0hhbmRsZXIob2xkX2hhbmRsZXIpID09ICZDYXB0dXJlTG9nKTsKKworICBBU1NFUlRfRVEoMiwgY2FwdHVyZWRfbWVzc2FnZXNfLnNpemUoKSk7CisgIEVYUEVDVF9FUSgKKyAgICAiMCAiIF9fRklMRV9fICI6IiArIFNpbXBsZUl0b2EobGluZTEpICsgIjogVmlzaWJsZTEiLAorICAgIGNhcHR1cmVkX21lc3NhZ2VzX1swXSk7CisgIEVYUEVDVF9FUSgKKyAgICAiMCAiIF9fRklMRV9fICI6IiArIFNpbXBsZUl0b2EobGluZTIpICsgIjogVmlzaWJsZTIiLAorICAgIGNhcHR1cmVkX21lc3NhZ2VzX1sxXSk7Cit9CisKK2NsYXNzIENsb3N1cmVUZXN0IDogcHVibGljIHRlc3Rpbmc6OlRlc3QgeworIHB1YmxpYzoKKyAgdm9pZCBTZXRBMTIzTWV0aG9kKCkgICB7IGFfID0gMTIzOyB9CisgIHN0YXRpYyB2b2lkIFNldEExMjNGdW5jdGlvbigpIHsgY3VycmVudF9pbnN0YW5jZV8tPmFfID0gMTIzOyB9CisKKyAgdm9pZCBTZXRBTWV0aG9kKGludCBhKSAgICAgICAgIHsgYV8gPSBhOyB9CisgIHZvaWQgU2V0Q01ldGhvZChzdHJpbmcgYykgICAgICB7IGNfID0gYzsgfQorCisgIHN0YXRpYyB2b2lkIFNldEFGdW5jdGlvbihpbnQgYSkgICAgICAgICB7IGN1cnJlbnRfaW5zdGFuY2VfLT5hXyA9IGE7IH0KKyAgc3RhdGljIHZvaWQgU2V0Q0Z1bmN0aW9uKHN0cmluZyBjKSAgICAgIHsgY3VycmVudF9pbnN0YW5jZV8tPmNfID0gYzsgfQorCisgIHZvaWQgU2V0QUJNZXRob2QoaW50IGEsIGNvbnN0IGNoYXIqIGIpICB7IGFfID0gYTsgYl8gPSBiOyB9CisgIHN0YXRpYyB2b2lkIFNldEFCRnVuY3Rpb24oaW50IGEsIGNvbnN0IGNoYXIqIGIpIHsKKyAgICBjdXJyZW50X2luc3RhbmNlXy0+YV8gPSBhOworICAgIGN1cnJlbnRfaW5zdGFuY2VfLT5iXyA9IGI7CisgIH0KKworICB2aXJ0dWFsIHZvaWQgU2V0VXAoKSB7CisgICAgY3VycmVudF9pbnN0YW5jZV8gPSB0aGlzOworICAgIGFfID0gMDsKKyAgICBiXyA9IE5VTEw7CisgICAgY18uY2xlYXIoKTsKKyAgICBwZXJtYW5lbnRfY2xvc3VyZV8gPSBOVUxMOworICB9CisKKyAgdm9pZCBEZWxldGVDbG9zdXJlSW5DYWxsYmFjaygpIHsKKyAgICBkZWxldGUgcGVybWFuZW50X2Nsb3N1cmVfOworICB9CisKKyAgaW50IGFfOworICBjb25zdCBjaGFyKiBiXzsKKyAgc3RyaW5nIGNfOworICBDbG9zdXJlKiBwZXJtYW5lbnRfY2xvc3VyZV87CisKKyAgc3RhdGljIENsb3N1cmVUZXN0KiBjdXJyZW50X2luc3RhbmNlXzsKK307CisKK0Nsb3N1cmVUZXN0KiBDbG9zdXJlVGVzdDo6Y3VycmVudF9pbnN0YW5jZV8gPSBOVUxMOworCitURVNUX0YoQ2xvc3VyZVRlc3QsIFRlc3RDbG9zdXJlRnVuY3Rpb24wKSB7CisgIENsb3N1cmUqIGNsb3N1cmUgPSBOZXdDYWxsYmFjaygmU2V0QTEyM0Z1bmN0aW9uKTsKKyAgRVhQRUNUX05FKDEyMywgYV8pOworICBjbG9zdXJlLT5SdW4oKTsKKyAgRVhQRUNUX0VRKDEyMywgYV8pOworfQorCitURVNUX0YoQ2xvc3VyZVRlc3QsIFRlc3RDbG9zdXJlTWV0aG9kMCkgeworICBDbG9zdXJlKiBjbG9zdXJlID0gTmV3Q2FsbGJhY2soY3VycmVudF9pbnN0YW5jZV8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmQ2xvc3VyZVRlc3Q6OlNldEExMjNNZXRob2QpOworICBFWFBFQ1RfTkUoMTIzLCBhXyk7CisgIGNsb3N1cmUtPlJ1bigpOworICBFWFBFQ1RfRVEoMTIzLCBhXyk7Cit9CisKK1RFU1RfRihDbG9zdXJlVGVzdCwgVGVzdENsb3N1cmVGdW5jdGlvbjEpIHsKKyAgQ2xvc3VyZSogY2xvc3VyZSA9IE5ld0NhbGxiYWNrKCZTZXRBRnVuY3Rpb24sIDQ1Nik7CisgIEVYUEVDVF9ORSg0NTYsIGFfKTsKKyAgY2xvc3VyZS0+UnVuKCk7CisgIEVYUEVDVF9FUSg0NTYsIGFfKTsKK30KKworVEVTVF9GKENsb3N1cmVUZXN0LCBUZXN0Q2xvc3VyZU1ldGhvZDEpIHsKKyAgQ2xvc3VyZSogY2xvc3VyZSA9IE5ld0NhbGxiYWNrKGN1cnJlbnRfaW5zdGFuY2VfLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJkNsb3N1cmVUZXN0OjpTZXRBTWV0aG9kLCA0NTYpOworICBFWFBFQ1RfTkUoNDU2LCBhXyk7CisgIGNsb3N1cmUtPlJ1bigpOworICBFWFBFQ1RfRVEoNDU2LCBhXyk7Cit9CisKK1RFU1RfRihDbG9zdXJlVGVzdCwgVGVzdENsb3N1cmVGdW5jdGlvbjFTdHJpbmcpIHsKKyAgQ2xvc3VyZSogY2xvc3VyZSA9IE5ld0NhbGxiYWNrKCZTZXRDRnVuY3Rpb24sIHN0cmluZygidGVzdCIpKTsKKyAgRVhQRUNUX05FKCJ0ZXN0IiwgY18pOworICBjbG9zdXJlLT5SdW4oKTsKKyAgRVhQRUNUX0VRKCJ0ZXN0IiwgY18pOworfQorCitURVNUX0YoQ2xvc3VyZVRlc3QsIFRlc3RDbG9zdXJlTWV0aG9kMVN0cmluZykgeworICBDbG9zdXJlKiBjbG9zdXJlID0gTmV3Q2FsbGJhY2soY3VycmVudF9pbnN0YW5jZV8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmQ2xvc3VyZVRlc3Q6OlNldENNZXRob2QsIHN0cmluZygidGVzdCIpKTsKKyAgRVhQRUNUX05FKCJ0ZXN0IiwgY18pOworICBjbG9zdXJlLT5SdW4oKTsKKyAgRVhQRUNUX0VRKCJ0ZXN0IiwgY18pOworfQorCitURVNUX0YoQ2xvc3VyZVRlc3QsIFRlc3RDbG9zdXJlRnVuY3Rpb24yKSB7CisgIGNvbnN0IGNoYXIqIGNzdHIgPSAiaGVsbG8iOworICBDbG9zdXJlKiBjbG9zdXJlID0gTmV3Q2FsbGJhY2soJlNldEFCRnVuY3Rpb24sIDc4OSwgY3N0cik7CisgIEVYUEVDVF9ORSg3ODksIGFfKTsKKyAgRVhQRUNUX05FKGNzdHIsIGJfKTsKKyAgY2xvc3VyZS0+UnVuKCk7CisgIEVYUEVDVF9FUSg3ODksIGFfKTsKKyAgRVhQRUNUX0VRKGNzdHIsIGJfKTsKK30KKworVEVTVF9GKENsb3N1cmVUZXN0LCBUZXN0Q2xvc3VyZU1ldGhvZDIpIHsKKyAgY29uc3QgY2hhciogY3N0ciA9ICJoZWxsbyI7CisgIENsb3N1cmUqIGNsb3N1cmUgPSBOZXdDYWxsYmFjayhjdXJyZW50X2luc3RhbmNlXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZDbG9zdXJlVGVzdDo6U2V0QUJNZXRob2QsIDc4OSwgY3N0cik7CisgIEVYUEVDVF9ORSg3ODksIGFfKTsKKyAgRVhQRUNUX05FKGNzdHIsIGJfKTsKKyAgY2xvc3VyZS0+UnVuKCk7CisgIEVYUEVDVF9FUSg3ODksIGFfKTsKKyAgRVhQRUNUX0VRKGNzdHIsIGJfKTsKK30KKworLy8gUmVwZWF0IGFsbCBvZiB0aGUgYWJvdmUgd2l0aCBOZXdQZXJtYW5lbnRDYWxsYmFjaygpCisKK1RFU1RfRihDbG9zdXJlVGVzdCwgVGVzdFBlcm1hbmVudENsb3N1cmVGdW5jdGlvbjApIHsKKyAgQ2xvc3VyZSogY2xvc3VyZSA9IE5ld1Blcm1hbmVudENhbGxiYWNrKCZTZXRBMTIzRnVuY3Rpb24pOworICBFWFBFQ1RfTkUoMTIzLCBhXyk7CisgIGNsb3N1cmUtPlJ1bigpOworICBFWFBFQ1RfRVEoMTIzLCBhXyk7CisgIGFfID0gMDsKKyAgY2xvc3VyZS0+UnVuKCk7CisgIEVYUEVDVF9FUSgxMjMsIGFfKTsKKyAgZGVsZXRlIGNsb3N1cmU7Cit9CisKK1RFU1RfRihDbG9zdXJlVGVzdCwgVGVzdFBlcm1hbmVudENsb3N1cmVNZXRob2QwKSB7CisgIENsb3N1cmUqIGNsb3N1cmUgPSBOZXdQZXJtYW5lbnRDYWxsYmFjayhjdXJyZW50X2luc3RhbmNlXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZDbG9zdXJlVGVzdDo6U2V0QTEyM01ldGhvZCk7CisgIEVYUEVDVF9ORSgxMjMsIGFfKTsKKyAgY2xvc3VyZS0+UnVuKCk7CisgIEVYUEVDVF9FUSgxMjMsIGFfKTsKKyAgYV8gPSAwOworICBjbG9zdXJlLT5SdW4oKTsKKyAgRVhQRUNUX0VRKDEyMywgYV8pOworICBkZWxldGUgY2xvc3VyZTsKK30KKworVEVTVF9GKENsb3N1cmVUZXN0LCBUZXN0UGVybWFuZW50Q2xvc3VyZUZ1bmN0aW9uMSkgeworICBDbG9zdXJlKiBjbG9zdXJlID0gTmV3UGVybWFuZW50Q2FsbGJhY2soJlNldEFGdW5jdGlvbiwgNDU2KTsKKyAgRVhQRUNUX05FKDQ1NiwgYV8pOworICBjbG9zdXJlLT5SdW4oKTsKKyAgRVhQRUNUX0VRKDQ1NiwgYV8pOworICBhXyA9IDA7CisgIGNsb3N1cmUtPlJ1bigpOworICBFWFBFQ1RfRVEoNDU2LCBhXyk7CisgIGRlbGV0ZSBjbG9zdXJlOworfQorCitURVNUX0YoQ2xvc3VyZVRlc3QsIFRlc3RQZXJtYW5lbnRDbG9zdXJlTWV0aG9kMSkgeworICBDbG9zdXJlKiBjbG9zdXJlID0gTmV3UGVybWFuZW50Q2FsbGJhY2soY3VycmVudF9pbnN0YW5jZV8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmQ2xvc3VyZVRlc3Q6OlNldEFNZXRob2QsIDQ1Nik7CisgIEVYUEVDVF9ORSg0NTYsIGFfKTsKKyAgY2xvc3VyZS0+UnVuKCk7CisgIEVYUEVDVF9FUSg0NTYsIGFfKTsKKyAgYV8gPSAwOworICBjbG9zdXJlLT5SdW4oKTsKKyAgRVhQRUNUX0VRKDQ1NiwgYV8pOworICBkZWxldGUgY2xvc3VyZTsKK30KKworVEVTVF9GKENsb3N1cmVUZXN0LCBUZXN0UGVybWFuZW50Q2xvc3VyZUZ1bmN0aW9uMikgeworICBjb25zdCBjaGFyKiBjc3RyID0gImhlbGxvIjsKKyAgQ2xvc3VyZSogY2xvc3VyZSA9IE5ld1Blcm1hbmVudENhbGxiYWNrKCZTZXRBQkZ1bmN0aW9uLCA3ODksIGNzdHIpOworICBFWFBFQ1RfTkUoNzg5LCBhXyk7CisgIEVYUEVDVF9ORShjc3RyLCBiXyk7CisgIGNsb3N1cmUtPlJ1bigpOworICBFWFBFQ1RfRVEoNzg5LCBhXyk7CisgIEVYUEVDVF9FUShjc3RyLCBiXyk7CisgIGFfID0gMDsKKyAgYl8gPSBOVUxMOworICBjbG9zdXJlLT5SdW4oKTsKKyAgRVhQRUNUX0VRKDc4OSwgYV8pOworICBFWFBFQ1RfRVEoY3N0ciwgYl8pOworICBkZWxldGUgY2xvc3VyZTsKK30KKworVEVTVF9GKENsb3N1cmVUZXN0LCBUZXN0UGVybWFuZW50Q2xvc3VyZU1ldGhvZDIpIHsKKyAgY29uc3QgY2hhciogY3N0ciA9ICJoZWxsbyI7CisgIENsb3N1cmUqIGNsb3N1cmUgPSBOZXdQZXJtYW5lbnRDYWxsYmFjayhjdXJyZW50X2luc3RhbmNlXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZDbG9zdXJlVGVzdDo6U2V0QUJNZXRob2QsIDc4OSwgY3N0cik7CisgIEVYUEVDVF9ORSg3ODksIGFfKTsKKyAgRVhQRUNUX05FKGNzdHIsIGJfKTsKKyAgY2xvc3VyZS0+UnVuKCk7CisgIEVYUEVDVF9FUSg3ODksIGFfKTsKKyAgRVhQRUNUX0VRKGNzdHIsIGJfKTsKKyAgYV8gPSAwOworICBiXyA9IE5VTEw7CisgIGNsb3N1cmUtPlJ1bigpOworICBFWFBFQ1RfRVEoNzg5LCBhXyk7CisgIEVYUEVDVF9FUShjc3RyLCBiXyk7CisgIGRlbGV0ZSBjbG9zdXJlOworfQorCitURVNUX0YoQ2xvc3VyZVRlc3QsIFRlc3RQZXJtYW5lbnRDbG9zdXJlRGVsZXRlSW5DYWxsYmFjaykgeworICBwZXJtYW5lbnRfY2xvc3VyZV8gPSBOZXdQZXJtYW5lbnRDYWxsYmFjaygoQ2xvc3VyZVRlc3QqKSB0aGlzLAorICAgICAgJkNsb3N1cmVUZXN0OjpEZWxldGVDbG9zdXJlSW5DYWxsYmFjayk7CisgIHBlcm1hbmVudF9jbG9zdXJlXy0+UnVuKCk7Cit9CisKK30gIC8vIGFub255bW91cyBuYW1lc3BhY2UKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9mYXN0bWVtLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2Zhc3RtZW0uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NjNhNmU2Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9mYXN0bWVtLmgKQEAgLTAsMCArMSwxNTIgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMTQgR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBGYXN0IG1lbW9yeSBjb3B5aW5nIGFuZCBjb21wYXJpc29uIHJvdXRpbmVzLgorLy8gICBzdHJpbmdzOjpmYXN0bWVtY21wX2lubGluZWQoKSByZXBsYWNlcyBtZW1jbXAoKQorLy8gICBzdHJpbmdzOjptZW1jcHlfaW5saW5lZCgpIHJlcGxhY2VzIG1lbWNweSgpCisvLyAgIHN0cmluZ3M6Om1lbWVxKGEsIGIsIG4pIHJlcGxhY2VzIG1lbWNtcChhLCBiLCBuKSA9PSAwCisvLworLy8gc3RyaW5nczo6Kl9pbmxpbmVkKCkgcm91dGluZXMgYXJlIGlubGluZSB2ZXJzaW9ucyBvZiB0aGUKKy8vIHJvdXRpbmVzIGV4cG9ydGVkIGJ5IHRoaXMgbW9kdWxlLiAgU29tZXRpbWVzIHVzaW5nIHRoZSBpbmxpbmVkCisvLyB2ZXJzaW9ucyBpcyBmYXN0ZXIuICBNZWFzdXJlIGJlZm9yZSB1c2luZyB0aGUgaW5saW5lZCB2ZXJzaW9ucy4KKy8vCisvLyBQZXJmb3JtYW5jZSBtZWFzdXJlbWVudDoKKy8vICAgc3RyaW5nczo6ZmFzdG1lbWNtcF9pbmxpbmVkCisvLyAgICAgQW5hbHlzaXM6IG1lbWNtcCwgZmFzdG1lbWNtcF9pbmxpbmVkLCBmYXN0bWVtY21wCisvLyAgICAgMjAxMi0wMS0zMAorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9TVFVCU19GQVNUTUVNX0hfCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9TVFVCU19GQVNUTUVNX0hfCisKKyNpbmNsdWRlIDxzdGRkZWYuaD4KKyNpbmNsdWRlIDxzdGRpby5oPgorI2luY2x1ZGUgPHN0cmluZy5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW50ZXJuYWwgeworCisvLyBSZXR1cm4gdHJ1ZSBpZiB0aGUgbiBieXRlcyBhdCBhIGVxdWFsIHRoZSBuIGJ5dGVzIGF0IGIuCisvLyBUaGUgcmVnaW9ucyBhcmUgYWxsb3dlZCB0byBvdmVybGFwLgorLy8KKy8vIFRoZSBwZXJmb3JtYW5jZSBpcyBzaW1pbGFyIHRvIHRoZSBwZXJmb3JtYW5jZSBtZW1jbXAoKSwgYnV0IGZhc3RlciBmb3IKKy8vIG1vZGVyYXRlbHktc2l6ZWQgaW5wdXRzLCBvciBpbnB1dHMgdGhhdCBzaGFyZSBhIGNvbW1vbiBwcmVmaXggYW5kIGRpZmZlcgorLy8gc29tZXdoZXJlIGluIHRoZWlyIGxhc3QgOCBieXRlcy4gRnVydGhlciBvcHRpbWl6YXRpb25zIGNhbiBiZSBhZGRlZCBsYXRlcgorLy8gaWYgaXQgbWFrZXMgc2Vuc2UgdG8gZG8gc28uOncKK2lubGluZSBib29sIG1lbWVxKGNvbnN0IGNoYXIqIGEsIGNvbnN0IGNoYXIqIGIsIHNpemVfdCBuKSB7CisgIHNpemVfdCBuX3JvdW5kZWRfZG93biA9IG4gJiB+c3RhdGljX2Nhc3Q8c2l6ZV90Pig3KTsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKG5fcm91bmRlZF9kb3duID09IDApKSB7ICAvLyBuIDw9IDcKKyAgICByZXR1cm4gbWVtY21wKGEsIGIsIG4pID09IDA7CisgIH0KKyAgLy8gbiA+PSA4CisgIHVpbnQ2NCB1ID0gR09PR0xFX1VOQUxJR05FRF9MT0FENjQoYSkgXiBHT09HTEVfVU5BTElHTkVEX0xPQUQ2NChiKTsKKyAgdWludDY0IHYgPSBHT09HTEVfVU5BTElHTkVEX0xPQUQ2NChhICsgbiAtIDgpIF4gR09PR0xFX1VOQUxJR05FRF9MT0FENjQoYiArIG4gLSA4KTsKKyAgaWYgKCh1IHwgdikgIT0gMCkgeyAgLy8gVGhlIGZpcnN0IG9yIGxhc3QgOCBieXRlcyBkaWZmZXIuCisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIGEgKz0gODsKKyAgYiArPSA4OworICBuID0gbl9yb3VuZGVkX2Rvd24gLSA4OworICBpZiAobiA+IDEyOCkgeworICAgIC8vIEFzIG9mIDIwMTIsIG1lbWNtcCBvbiB4ODYtNjQgdXNlcyBhIGJpZyB1bnJvbGxlZCBsb29wIHdpdGggU1NFMgorICAgIC8vIGluc3RydWN0aW9ucywgYW5kIHdoaWxlIHdlIGNvdWxkIHRyeSB0byBkbyBzb21ldGhpbmcgZmFzdGVyLCBpdAorICAgIC8vIGRvZXNuJ3Qgc2VlbSB3b3J0aCBwdXJzdWluZy4KKyAgICByZXR1cm4gbWVtY21wKGEsIGIsIG4pID09IDA7CisgIH0KKyAgZm9yICg7IG4gPj0gMTY7IG4gLT0gMTYpIHsKKyAgICB1aW50NjQgeCA9IEdPT0dMRV9VTkFMSUdORURfTE9BRDY0KGEpIF4gR09PR0xFX1VOQUxJR05FRF9MT0FENjQoYik7CisgICAgdWludDY0IHkgPSBHT09HTEVfVU5BTElHTkVEX0xPQUQ2NChhICsgOCkgXiBHT09HTEVfVU5BTElHTkVEX0xPQUQ2NChiICsgOCk7CisgICAgaWYgKCh4IHwgeSkgIT0gMCkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBhICs9IDE2OworICAgIGIgKz0gMTY7CisgIH0KKyAgLy8gbiBtdXN0IGJlIDAgb3IgOCBub3cgYmVjYXVzZSBpdCB3YXMgYSBtdWx0aXBsZSBvZiA4IGF0IHRoZSB0b3Agb2YgdGhlIGxvb3AuCisgIHJldHVybiBuID09IDAgfHwgR09PR0xFX1VOQUxJR05FRF9MT0FENjQoYSkgPT0gR09PR0xFX1VOQUxJR05FRF9MT0FENjQoYik7Cit9CisKK2lubGluZSBpbnQgZmFzdG1lbWNtcF9pbmxpbmVkKGNvbnN0IGNoYXIgKmEsIGNvbnN0IGNoYXIgKmIsIHNpemVfdCBuKSB7CisgIGlmIChuID49IDY0KSB7CisgICAgcmV0dXJuIG1lbWNtcChhLCBiLCBuKTsKKyAgfQorICBjb25zdCBjaGFyKiBhX2xpbWl0ID0gYSArIG47CisgIHdoaWxlIChhICsgc2l6ZW9mKHVpbnQ2NCkgPD0gYV9saW1pdCAmJgorICAgICAgICAgR09PR0xFX1VOQUxJR05FRF9MT0FENjQoYSkgPT0gR09PR0xFX1VOQUxJR05FRF9MT0FENjQoYikpIHsKKyAgICBhICs9IHNpemVvZih1aW50NjQpOworICAgIGIgKz0gc2l6ZW9mKHVpbnQ2NCk7CisgIH0KKyAgaWYgKGEgKyBzaXplb2YodWludDMyKSA8PSBhX2xpbWl0ICYmCisgICAgICBHT09HTEVfVU5BTElHTkVEX0xPQUQzMihhKSA9PSBHT09HTEVfVU5BTElHTkVEX0xPQUQzMihiKSkgeworICAgIGEgKz0gc2l6ZW9mKHVpbnQzMik7CisgICAgYiArPSBzaXplb2YodWludDMyKTsKKyAgfQorICB3aGlsZSAoYSA8IGFfbGltaXQpIHsKKyAgICBpbnQgZCA9IHN0YXRpY19jYXN0PHVpbnQzMj4oKmErKykgLSBzdGF0aWNfY2FzdDx1aW50MzI+KCpiKyspOworICAgIGlmIChkKSByZXR1cm4gZDsKKyAgfQorICByZXR1cm4gMDsKK30KKworLy8gVGhlIHN0YW5kYXJkIG1lbWNweSBvcGVyYXRpb24gaXMgc2xvdyBmb3IgdmFyaWFibGUgc21hbGwgc2l6ZXMuCisvLyBUaGlzIGltcGxlbWVudGF0aW9uIGlubGluZXMgdGhlIG9wdGltYWwgcmVhbGl6YXRpb24gZm9yIHNpemVzIDEgdG8gMTYuCisvLyBUbyBhdm9pZCBjb2RlIGJsb2F0IGRvbid0IHVzZSBpdCBpbiBjYXNlIG9mIG5vdCBwZXJmb3JtYW5jZS1jcml0aWNhbCBzcG90cywKKy8vIG5vciB3aGVuIHlvdSBkb24ndCBleHBlY3QgdmVyeSBmcmVxdWVudCB2YWx1ZXMgb2Ygc2l6ZSA8PSAxNi4KK2lubGluZSB2b2lkIG1lbWNweV9pbmxpbmVkKGNoYXIgKmRzdCwgY29uc3QgY2hhciAqc3JjLCBzaXplX3Qgc2l6ZSkgeworICAvLyBDb21waWxlciBpbmxpbmVzIGNvZGUgd2l0aCBtaW5pbWFsIGFtb3VudCBvZiBkYXRhIG1vdmVtZW50IHdoZW4gdGhpcmQKKyAgLy8gcGFyYW1ldGVyIG9mIG1lbWNweSBpcyBhIGNvbnN0YW50LgorICBzd2l0Y2ggKHNpemUpIHsKKyAgICBjYXNlICAxOiBtZW1jcHkoZHN0LCBzcmMsIDEpOyBicmVhazsKKyAgICBjYXNlICAyOiBtZW1jcHkoZHN0LCBzcmMsIDIpOyBicmVhazsKKyAgICBjYXNlICAzOiBtZW1jcHkoZHN0LCBzcmMsIDMpOyBicmVhazsKKyAgICBjYXNlICA0OiBtZW1jcHkoZHN0LCBzcmMsIDQpOyBicmVhazsKKyAgICBjYXNlICA1OiBtZW1jcHkoZHN0LCBzcmMsIDUpOyBicmVhazsKKyAgICBjYXNlICA2OiBtZW1jcHkoZHN0LCBzcmMsIDYpOyBicmVhazsKKyAgICBjYXNlICA3OiBtZW1jcHkoZHN0LCBzcmMsIDcpOyBicmVhazsKKyAgICBjYXNlICA4OiBtZW1jcHkoZHN0LCBzcmMsIDgpOyBicmVhazsKKyAgICBjYXNlICA5OiBtZW1jcHkoZHN0LCBzcmMsIDkpOyBicmVhazsKKyAgICBjYXNlIDEwOiBtZW1jcHkoZHN0LCBzcmMsIDEwKTsgYnJlYWs7CisgICAgY2FzZSAxMTogbWVtY3B5KGRzdCwgc3JjLCAxMSk7IGJyZWFrOworICAgIGNhc2UgMTI6IG1lbWNweShkc3QsIHNyYywgMTIpOyBicmVhazsKKyAgICBjYXNlIDEzOiBtZW1jcHkoZHN0LCBzcmMsIDEzKTsgYnJlYWs7CisgICAgY2FzZSAxNDogbWVtY3B5KGRzdCwgc3JjLCAxNCk7IGJyZWFrOworICAgIGNhc2UgMTU6IG1lbWNweShkc3QsIHNyYywgMTUpOyBicmVhazsKKyAgICBjYXNlIDE2OiBtZW1jcHkoZHN0LCBzcmMsIDE2KTsgYnJlYWs7CisgICAgZGVmYXVsdDogbWVtY3B5KGRzdCwgc3JjLCBzaXplKTsgYnJlYWs7CisgIH0KK30KKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfU1RVQlNfRkFTVE1FTV9IXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9oYXNoLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2hhc2guaApuZXcgZmlsZSBtb2RlIDEwMDc1NQppbmRleCAwMDAwMDAwLi41ODMzNDMyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9oYXNoLmgKQEAgLTAsMCArMSwzNzQgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLworLy8gRGVhbHMgd2l0aCB0aGUgZmFjdCB0aGF0IGhhc2hfbWFwIGlzIG5vdCBkZWZpbmVkIGV2ZXJ5d2hlcmUuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX1NUVUJTX0hBU0hfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9TVFVCU19IQVNIX0hfXworCisjaW5jbHVkZSA8c3RyaW5nLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9IQVZFX0hBU0hfTUFQIDEKKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0hBVkVfSEFTSF9TRVQgMQorCisvLyBBbmRyb2lkCisjaWYgZGVmaW5lZChfX0FORFJPSURfXykKKyMgdW5kZWYgR09PR0xFX1BST1RPQlVGX0hBVkVfSEFTSF9NQVAKKyMgdW5kZWYgR09PR0xFX1BST1RPQlVGX0hBVkVfSEFTSF9NQVAKKworLy8gVXNlIEMrKzExIHVub3JkZXJlZF97bWFwfHNldH0gaWYgYXZhaWxhYmxlLgorI2VsaWYgKChfTElCQ1BQX1NURF9WRVIgPj0gMTEpIHx8IFwKKyAgICAgICgoKF9fY3BsdXNwbHVzID49IDIwMTEwM0wpIHx8IGRlZmluZWQoX19HWFhfRVhQRVJJTUVOVEFMX0NYWDBYKSkgJiYgXAorICAgICAgKF9fR0xJQkNYWF9fID4gMjAwOTA0MjEpKSkKKyMgZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9IQVNfQ1hYMTFfSEFTSAorCisvLyBGb3IgWENvZGUgPj0gNC42OiAgdGhlIGNvbXBpbGVyIGlzIGNsYW5nIHdpdGggbGliYysrLgorLy8gRm9yIGVhcmxpZXIgWENvZGUgdmVyc2lvbjogdGhlIGNvbXBpbGVyIGlzIGdjYy00LjIuMSB3aXRoIGxpYnN0ZGMrKy4KKy8vIGxpYmMrKyBwcm92aWRlcyA8dW5vcmRlcmVkX21hcD4gYW5kIGZyaWVuZHMgZXZlbiBpbiBub24gQysrMTEgbW9kZSwKKy8vIGFuZCBpdCBkb2VzIG5vdCBwcm92aWRlIHRoZSB0cjEgbGlicmFyeS4gVGhlcmVmb3JlIHRoZSBmb2xsb3dpbmcgbWFjcm8KKy8vIGNoZWNrcyBhZ2FpbnN0IHRoaXMgc3BlY2lhbCBjYXNlLgorLy8gTm90ZSB0aGF0IHdlIHNob3VsZCBub3QgdGVzdCB0aGUgX19BUFBMRV9DQ19fIHZlcnNpb24gbnVtYmVyIG9yIHRoZQorLy8gX19jbGFuZ19fIG1hY3JvLCBzaW5jZSB0aGUgbmV3IGNvbXBpbGVyIGNhbiBzdGlsbCB1c2UgLXN0ZGxpYj1saWJzdGRjKyssIGluCisvLyB3aGljaCBjYXNlIDx1bm9yZGVyZWRfbWFwPiBpcyBub3QgY29tcGlsYWJsZSB3aXRob3V0IC1zdGQ9YysrMTEKKyNlbGlmIGRlZmluZWQoX19BUFBMRV9DQ19fKQorIyBpZiBfX0dOVUNfXyA+PSA0CisjICBkZWZpbmUgR09PR0xFX1BST1RPQlVGX0hBU19UUjEKKyMgZWxzZQorLy8gTm90IHRlc3RlZCBmb3IgZ2NjIDwgNC4uLiBUaGVzZSBzZXR0aW5nIGNhbiBjb21waWxlIHVuZGVyIDQuMi4xIHRob3VnaC4KKyMgIGRlZmluZSBHT09HTEVfUFJPVE9CVUZfSEFTSF9OQU1FU1BBQ0UgX19nbnVfY3h4CisjICBpbmNsdWRlIDxleHQvaGFzaF9tYXA+CisjICBkZWZpbmUgR09PR0xFX1BST1RPQlVGX0hBU0hfTUFQX0NMQVNTIGhhc2hfbWFwCisjICBpbmNsdWRlIDxleHQvaGFzaF9zZXQ+CisjICBkZWZpbmUgR09PR0xFX1BST1RPQlVGX0hBU0hfU0VUX0NMQVNTIGhhc2hfc2V0CisjIGVuZGlmCisKKy8vIFZlcnNpb24gY2hlY2tzIGZvciBnY2MuCisjZWxpZiBkZWZpbmVkKF9fR05VQ19fKQorLy8gRm9yIEdDQyA0LngrLCB1c2UgdHIxOjp1bm9yZGVyZWRfbWFwL3NldDsgb3RoZXJ3aXNlLCBmb2xsb3cgdGhlCisvLyBpbnN0cnVjdGlvbnMgZnJvbToKKy8vIGh0dHBzOi8vZ2NjLmdudS5vcmcvb25saW5lZG9jcy9saWJzdGRjKysvbWFudWFsL2JhY2t3YXJkcy5odG1sCisjIGlmIF9fR05VQ19fID49IDQKKyMgIGRlZmluZSBHT09HTEVfUFJPVE9CVUZfSEFTX1RSMQorIyBlbGlmIF9fR05VQ19fID49IDMKKyMgIGluY2x1ZGUgPGJhY2t3YXJkL2hhc2hfbWFwPgorIyAgZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9IQVNIX01BUF9DTEFTUyBoYXNoX21hcAorIyAgaW5jbHVkZSA8YmFja3dhcmQvaGFzaF9zZXQ+CisjICBkZWZpbmUgR09PR0xFX1BST1RPQlVGX0hBU0hfU0VUX0NMQVNTIGhhc2hfc2V0CisjICBpZiBfX0dOVUNfXyA9PSAzICYmIF9fR05VQ19NSU5PUl9fID09IDAKKyMgICBkZWZpbmUgR09PR0xFX1BST1RPQlVGX0hBU0hfTkFNRVNQQUNFIHN0ZCAgICAgICAvLyBHQ0MgMy4wCisjICBlbHNlCisjICAgZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9IQVNIX05BTUVTUEFDRSBfX2dudV9jeHggLy8gR0NDIDMuMSBhbmQgbGF0ZXIKKyMgIGVuZGlmCisjIGVsc2UKKyMgIGRlZmluZSBHT09HTEVfUFJPVE9CVUZfSEFTSF9OQU1FU1BBQ0UKKyMgIGluY2x1ZGUgPGhhc2hfbWFwPgorIyAgZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9IQVNIX01BUF9DTEFTUyBoYXNoX21hcAorIyAgaW5jbHVkZSA8aGFzaF9zZXQ+CisjICBkZWZpbmUgR09PR0xFX1BST1RPQlVGX0hBU0hfU0VUX0NMQVNTIGhhc2hfc2V0CisjIGVuZGlmCisKKy8vIFZlcnNpb24gY2hlY2tzIGZvciBNU0MuCisvLyBBcHBhcmVudGx5IE1pY3Jvc29mdCBkZWNpZGVkIHRvIG1vdmUgaGFzaF9tYXAgKmJhY2sqIHRvIHRoZSBzdGQgbmFtZXNwYWNlIGluCisvLyBNU1ZDIDIwMTA6CisvLyBodHRwOi8vYmxvZ3MubXNkbi5jb20vdmNibG9nL2FyY2hpdmUvMjAwOS8wNS8yNS9zdGwtYnJlYWtpbmctY2hhbmdlcy1pbi12aXN1YWwtc3R1ZGlvLTIwMTAtYmV0YS0xLmFzcHgKKy8vIEFuZC4uIHRoZXkgYXJlIG1vdmVkIGJhY2sgdG8gc3RkZXh0IGluIE1TVkMgMjAxMyAoaGF2ZW4ndCBjaGVja2VkIDIwMTIpLiBUaGF0CisvLyBzYWlkLCB1c2UgdW5vcmRlcmVkX21hcCBmb3IgTVNWQyAyMDEwIGFuZCBiZXlvbmQgaXMgb3VyIHNhZmVzdCBiZXQuCisjZWxpZiBkZWZpbmVkKF9NU0NfVkVSKQorIyBpZiBfTVNDX1ZFUiA+PSAxNjAwICAvLyBTaW5jZSBWaXN1YWwgU3R1ZGlvIDIwMTAKKyMgIGRlZmluZSBHT09HTEVfUFJPVE9CVUZfSEFTX0NYWDExX0hBU0gKKyMgIGRlZmluZSBHT09HTEVfUFJPVE9CVUZfSEFTSF9DT01QQVJFIHN0ZDo6aGFzaF9jb21wYXJlCisjIGVsaWYgX01TQ19WRVIgPj0gMTUwMCAgLy8gU2luY2UgVmlzdWFsIFN0dWRpbyAyMDA4CisjICB1bmRlZiBHT09HTEVfUFJPVE9CVUZfSEFWRV9IQVNIX01BUAorIyAgdW5kZWYgR09PR0xFX1BST1RPQlVGX0hBVkVfSEFTSF9TRVQKKyMgZWxpZiBfTVNDX1ZFUiA+PSAxMzEwCisjICBkZWZpbmUgR09PR0xFX1BST1RPQlVGX0hBU0hfTkFNRVNQQUNFIHN0ZGV4dAorIyAgaW5jbHVkZSA8aGFzaF9tYXA+CisjICBkZWZpbmUgR09PR0xFX1BST1RPQlVGX0hBU0hfTUFQX0NMQVNTIGhhc2hfbWFwCisjICBpbmNsdWRlIDxoYXNoX3NldD4KKyMgIGRlZmluZSBHT09HTEVfUFJPVE9CVUZfSEFTSF9TRVRfQ0xBU1MgaGFzaF9zZXQKKyMgIGRlZmluZSBHT09HTEVfUFJPVE9CVUZfSEFTSF9DT01QQVJFIHN0ZGV4dDo6aGFzaF9jb21wYXJlCisjIGVsc2UKKyMgIGRlZmluZSBHT09HTEVfUFJPVE9CVUZfSEFTSF9OQU1FU1BBQ0Ugc3RkCisjICBpbmNsdWRlIDxoYXNoX21hcD4KKyMgIGRlZmluZSBHT09HTEVfUFJPVE9CVUZfSEFTSF9NQVBfQ0xBU1MgaGFzaF9tYXAKKyMgIGluY2x1ZGUgPGhhc2hfc2V0PgorIyAgZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9IQVNIX1NFVF9DTEFTUyBoYXNoX3NldAorIyAgZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9IQVNIX0NPTVBBUkUgc3RkZXh0OjpoYXNoX2NvbXBhcmUKKyMgZW5kaWYKKworLy8gKipBREQgTkVXIENPTVBJTEVSUyBTVVBQT1JUIEhFUkUuKioKKy8vIEZvciBvdGhlciBjb21waWxlcnMsIHVuZGVmaW5lIHRoZSBtYWNybyBhbmQgZmFsbGJhY2sgdG8gdXNlIHN0ZDo6bWFwLCBpbgorLy8gZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2hhc2guaAorI2Vsc2UKKyMgdW5kZWYgR09PR0xFX1BST1RPQlVGX0hBVkVfSEFTSF9NQVAKKyMgdW5kZWYgR09PR0xFX1BST1RPQlVGX0hBVkVfSEFTSF9TRVQKKyNlbmRpZgorCisjaWYgZGVmaW5lZChHT09HTEVfUFJPVE9CVUZfSEFTX0NYWDExX0hBU0gpCisjIGRlZmluZSBHT09HTEVfUFJPVE9CVUZfSEFTSF9OQU1FU1BBQ0Ugc3RkCisjIGluY2x1ZGUgPHVub3JkZXJlZF9tYXA+CisjIGRlZmluZSBHT09HTEVfUFJPVE9CVUZfSEFTSF9NQVBfQ0xBU1MgdW5vcmRlcmVkX21hcAorIyBpbmNsdWRlIDx1bm9yZGVyZWRfc2V0PgorIyBkZWZpbmUgR09PR0xFX1BST1RPQlVGX0hBU0hfU0VUX0NMQVNTIHVub3JkZXJlZF9zZXQKKyNlbGlmIGRlZmluZWQoR09PR0xFX1BST1RPQlVGX0hBU19UUjEpCisjIGRlZmluZSBHT09HTEVfUFJPVE9CVUZfSEFTSF9OQU1FU1BBQ0Ugc3RkOjp0cjEKKyMgaW5jbHVkZSA8dHIxL3Vub3JkZXJlZF9tYXA+CisjIGRlZmluZSBHT09HTEVfUFJPVE9CVUZfSEFTSF9NQVBfQ0xBU1MgdW5vcmRlcmVkX21hcAorIyBpbmNsdWRlIDx0cjEvdW5vcmRlcmVkX3NldD4KKyMgZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9IQVNIX1NFVF9DTEFTUyB1bm9yZGVyZWRfc2V0CisjZW5kaWYKKworIyBkZWZpbmUgR09PR0xFX1BST1RPQlVGX0hBU0hfTkFNRVNQQUNFX0RFQ0xBUkFUSU9OX1NUQVJUIFwKKyAgbmFtZXNwYWNlIGdvb2dsZSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIG5hbWVzcGFjZSBwcm90b2J1ZiB7CisjIGRlZmluZSBHT09HTEVfUFJPVE9CVUZfSEFTSF9OQU1FU1BBQ0VfREVDTEFSQVRJT05fRU5EIH19CisKKyN1bmRlZiBHT09HTEVfUFJPVE9CVUZfSEFTX0NYWDExX0hBU0gKKyN1bmRlZiBHT09HTEVfUFJPVE9CVUZfSEFTX1RSMQorCisjaWYgZGVmaW5lZChHT09HTEVfUFJPVE9CVUZfSEFWRV9IQVNIX01BUCkgJiYgXAorICAgIGRlZmluZWQoR09PR0xFX1BST1RPQlVGX0hBVkVfSEFTSF9TRVQpCisjZWxzZQorI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfTUlTU0lOR19IQVNICisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHNldD4KKyNlbmRpZgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKKyNpZmRlZiBHT09HTEVfUFJPVE9CVUZfTUlTU0lOR19IQVNICisjdW5kZWYgR09PR0xFX1BST1RPQlVGX01JU1NJTkdfSEFTSAorCisvLyBUaGlzIHN5c3RlbSBkb2Vzbid0IGhhdmUgaGFzaF9tYXAgb3IgaGFzaF9zZXQuICBFbXVsYXRlIHRoZW0gdXNpbmcgbWFwIGFuZAorLy8gc2V0LgorCisvLyBNYWtlIGhhc2g8VD4gYmUgdGhlIHNhbWUgYXMgbGVzczxUPi4gIE5vdGUgdGhhdCBldmVyeXdoZXJlIHdoZXJlIGN1c3RvbQorLy8gaGFzaCBmdW5jdGlvbnMgYXJlIGRlZmluZWQgaW4gdGhlIHByb3RvYnVmIGNvZGUsIHRoZXkgYXJlIGFsc28gZGVmaW5lZCBzdWNoCisvLyB0aGF0IHRoZXkgY2FuIGJlIHVzZWQgYXMgImxlc3MiIGZ1bmN0aW9ucywgd2hpY2ggaXMgcmVxdWlyZWQgYnkgTVNWQyBhbnl3YXkuCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5Pgorc3RydWN0IGhhc2ggeworICAvLyBEdW1teSwganVzdCB0byBtYWtlIGRlcml2YXRpdmUgaGFzaCBmdW5jdGlvbnMgY29tcGlsZS4KKyAgaW50IG9wZXJhdG9yKCkoY29uc3QgS2V5JiBrZXkpIHsKKyAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiU2hvdWxkIG5ldmVyIGJlIGNhbGxlZC4iOworICAgIHJldHVybiAwOworICB9CisKKyAgaW5saW5lIGJvb2wgb3BlcmF0b3IoKShjb25zdCBLZXkmIGEsIGNvbnN0IEtleSYgYikgY29uc3QgeworICAgIHJldHVybiBhIDwgYjsKKyAgfQorfTsKKworLy8gTWFrZSBzdXJlIGNoYXIqIGlzIGNvbXBhcmVkIGJ5IHZhbHVlLgordGVtcGxhdGUgPD4KK3N0cnVjdCBoYXNoPGNvbnN0IGNoYXIqPiB7CisgIC8vIER1bW15LCBqdXN0IHRvIG1ha2UgZGVyaXZhdGl2ZSBoYXNoIGZ1bmN0aW9ucyBjb21waWxlLgorICBpbnQgb3BlcmF0b3IoKShjb25zdCBjaGFyKiBrZXkpIHsKKyAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiU2hvdWxkIG5ldmVyIGJlIGNhbGxlZC4iOworICAgIHJldHVybiAwOworICB9CisKKyAgaW5saW5lIGJvb2wgb3BlcmF0b3IoKShjb25zdCBjaGFyKiBhLCBjb25zdCBjaGFyKiBiKSBjb25zdCB7CisgICAgcmV0dXJuIHN0cmNtcChhLCBiKSA8IDA7CisgIH0KK307CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIERhdGEsCisgICAgICAgICAgdHlwZW5hbWUgSGFzaEZjbiA9IGhhc2g8S2V5PiwKKyAgICAgICAgICB0eXBlbmFtZSBFcXVhbEtleSA9IHN0ZDo6ZXF1YWxfdG88S2V5PiwKKyAgICAgICAgICB0eXBlbmFtZSBBbGxvYyA9IHN0ZDo6YWxsb2NhdG9yPCBzdGQ6OnBhaXI8Y29uc3QgS2V5LCBEYXRhPiA+ID4KK2NsYXNzIGhhc2hfbWFwIDogcHVibGljIHN0ZDo6bWFwPEtleSwgRGF0YSwgSGFzaEZjbiwgQWxsb2M+IHsKKyAgdHlwZWRlZiBzdGQ6Om1hcDxLZXksIERhdGEsIEhhc2hGY24sIEFsbG9jPiBCYXNlQ2xhc3M7CisKKyBwdWJsaWM6CisgIGhhc2hfbWFwKGludCBhID0gMCwgY29uc3QgSGFzaEZjbiYgYiA9IEhhc2hGY24oKSwKKyAgICAgICAgICAgY29uc3QgRXF1YWxLZXkmIGMgPSBFcXVhbEtleSgpLAorICAgICAgICAgICBjb25zdCBBbGxvYyYgZCA9IEFsbG9jKCkpIDogQmFzZUNsYXNzKGIsIGQpIHt9Cit9OworCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LAorICAgICAgICAgIHR5cGVuYW1lIEhhc2hGY24gPSBoYXNoPEtleT4sCisgICAgICAgICAgdHlwZW5hbWUgRXF1YWxLZXkgPSBzdGQ6OmVxdWFsX3RvPEtleT4gPgorY2xhc3MgaGFzaF9zZXQgOiBwdWJsaWMgc3RkOjpzZXQ8S2V5LCBIYXNoRmNuPiB7CisgcHVibGljOgorICBoYXNoX3NldChpbnQgPSAwKSB7fQorfTsKKworI2VsaWYgZGVmaW5lZChfTVNDX1ZFUikgJiYgIWRlZmluZWQoX1NUTFBPUlRfVkVSU0lPTikKKwordGVtcGxhdGUgPHR5cGVuYW1lIEtleT4KK3N0cnVjdCBoYXNoIDogcHVibGljIEdPT0dMRV9QUk9UT0JVRl9IQVNIX0NPTVBBUkU8S2V5PiB7Cit9OworCisvLyBNU1ZDJ3MgaGFzaF9jb21wYXJlPGNvbnN0IGNoYXIqPiBoYXNoZXMgYmFzZWQgb24gdGhlIHN0cmluZyBjb250ZW50cyBidXQKKy8vIGNvbXBhcmVzIGJhc2VkIG9uIHRoZSBzdHJpbmcgcG9pbnRlci4gIFdURj8KK2NsYXNzIENzdHJpbmdMZXNzIHsKKyBwdWJsaWM6CisgIGlubGluZSBib29sIG9wZXJhdG9yKCkoY29uc3QgY2hhciogYSwgY29uc3QgY2hhciogYikgY29uc3QgeworICAgIHJldHVybiBzdHJjbXAoYSwgYikgPCAwOworICB9Cit9OworCit0ZW1wbGF0ZSA8Pgorc3RydWN0IGhhc2g8Y29uc3QgY2hhcio+CisgICAgOiBwdWJsaWMgR09PR0xFX1BST1RPQlVGX0hBU0hfQ09NUEFSRTxjb25zdCBjaGFyKiwgQ3N0cmluZ0xlc3M+IHt9OworCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBEYXRhLAorICAgICAgICAgIHR5cGVuYW1lIEhhc2hGY24gPSBoYXNoPEtleT4sCisgICAgICAgICAgdHlwZW5hbWUgRXF1YWxLZXkgPSBzdGQ6OmVxdWFsX3RvPEtleT4sCisgICAgICAgICAgdHlwZW5hbWUgQWxsb2MgPSBzdGQ6OmFsbG9jYXRvcjwgc3RkOjpwYWlyPGNvbnN0IEtleSwgRGF0YT4gPiA+CitjbGFzcyBoYXNoX21hcAorICAgIDogcHVibGljIEdPT0dMRV9QUk9UT0JVRl9IQVNIX05BTUVTUEFDRTo6R09PR0xFX1BST1RPQlVGX0hBU0hfTUFQX0NMQVNTPAorICAgICAgICAgIEtleSwgRGF0YSwgSGFzaEZjbiwgRXF1YWxLZXksIEFsbG9jPiB7CisgIHR5cGVkZWYgR09PR0xFX1BST1RPQlVGX0hBU0hfTkFNRVNQQUNFOjpHT09HTEVfUFJPVE9CVUZfSEFTSF9NQVBfQ0xBU1M8CisgICAgICBLZXksIERhdGEsIEhhc2hGY24sIEVxdWFsS2V5LCBBbGxvYz4gQmFzZUNsYXNzOworCisgcHVibGljOgorICBoYXNoX21hcChpbnQgYSA9IDAsIGNvbnN0IEhhc2hGY24mIGIgPSBIYXNoRmNuKCksCisgICAgICAgICAgIGNvbnN0IEVxdWFsS2V5JiBjID0gRXF1YWxLZXkoKSwKKyAgICAgICAgICAgY29uc3QgQWxsb2MmIGQgPSBBbGxvYygpKSA6IEJhc2VDbGFzcyhhLCBiLCBjLCBkKSB7fQorfTsKKwordGVtcGxhdGUgPHR5cGVuYW1lIEtleSwgdHlwZW5hbWUgSGFzaEZjbiA9IGhhc2g8S2V5PiwKKyAgICAgICAgICB0eXBlbmFtZSBFcXVhbEtleSA9IHN0ZDo6ZXF1YWxfdG88S2V5PiA+CitjbGFzcyBoYXNoX3NldAorICAgIDogcHVibGljIEdPT0dMRV9QUk9UT0JVRl9IQVNIX05BTUVTUEFDRTo6R09PR0xFX1BST1RPQlVGX0hBU0hfU0VUX0NMQVNTPAorICAgICAgICAgIEtleSwgSGFzaEZjbiwgRXF1YWxLZXk+IHsKKyBwdWJsaWM6CisgIGhhc2hfc2V0KGludCA9IDApIHt9Cit9OworCisjZWxzZQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5Pgorc3RydWN0IGhhc2ggOiBwdWJsaWMgR09PR0xFX1BST1RPQlVGX0hBU0hfTkFNRVNQQUNFOjpoYXNoPEtleT4geworfTsKKwordGVtcGxhdGUgPHR5cGVuYW1lIEtleT4KK3N0cnVjdCBoYXNoPGNvbnN0IEtleSo+IHsKKyAgaW5saW5lIHNpemVfdCBvcGVyYXRvcigpKGNvbnN0IEtleSoga2V5KSBjb25zdCB7CisgICAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8c2l6ZV90PihrZXkpOworICB9Cit9OworCisvLyBVbmxpa2UgdGhlIG9sZCBTR0kgdmVyc2lvbiwgdGhlIFRSMSAiaGFzaCIgZG9lcyBub3Qgc3BlY2lhbC1jYXNlIGNoYXIqLiAgU28sCisvLyB3ZSBnbyBhaGVhZCBhbmQgcHJvdmlkZSBvdXIgb3duIGltcGxlbWVudGF0aW9uLgordGVtcGxhdGUgPD4KK3N0cnVjdCBoYXNoPGNvbnN0IGNoYXIqPiB7CisgIGlubGluZSBzaXplX3Qgb3BlcmF0b3IoKShjb25zdCBjaGFyKiBzdHIpIGNvbnN0IHsKKyAgICBzaXplX3QgcmVzdWx0ID0gMDsKKyAgICBmb3IgKDsgKnN0ciAhPSAnXDAnOyBzdHIrKykgeworICAgICAgcmVzdWx0ID0gNSAqIHJlc3VsdCArICpzdHI7CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7CisgIH0KK307CisKK3RlbXBsYXRlPD4KK3N0cnVjdCBoYXNoPGJvb2w+IHsKKyAgc2l6ZV90IG9wZXJhdG9yKCkoYm9vbCB4KSBjb25zdCB7CisgICAgcmV0dXJuIHN0YXRpY19jYXN0PHNpemVfdD4oeCk7CisgIH0KK307CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBLZXksIHR5cGVuYW1lIERhdGEsCisgICAgICAgICAgdHlwZW5hbWUgSGFzaEZjbiA9IGhhc2g8S2V5PiwKKyAgICAgICAgICB0eXBlbmFtZSBFcXVhbEtleSA9IHN0ZDo6ZXF1YWxfdG88S2V5PiwKKyAgICAgICAgICB0eXBlbmFtZSBBbGxvYyA9IHN0ZDo6YWxsb2NhdG9yPCBzdGQ6OnBhaXI8Y29uc3QgS2V5LCBEYXRhPiA+ID4KK2NsYXNzIGhhc2hfbWFwCisgICAgOiBwdWJsaWMgR09PR0xFX1BST1RPQlVGX0hBU0hfTkFNRVNQQUNFOjpHT09HTEVfUFJPVE9CVUZfSEFTSF9NQVBfQ0xBU1M8CisgICAgICAgICAgS2V5LCBEYXRhLCBIYXNoRmNuLCBFcXVhbEtleSwgQWxsb2M+IHsKKyAgdHlwZWRlZiBHT09HTEVfUFJPVE9CVUZfSEFTSF9OQU1FU1BBQ0U6OkdPT0dMRV9QUk9UT0JVRl9IQVNIX01BUF9DTEFTUzwKKyAgICAgIEtleSwgRGF0YSwgSGFzaEZjbiwgRXF1YWxLZXksIEFsbG9jPiBCYXNlQ2xhc3M7CisKKyBwdWJsaWM6CisgIGhhc2hfbWFwKGludCBhID0gMCwgY29uc3QgSGFzaEZjbiYgYiA9IEhhc2hGY24oKSwKKyAgICAgICAgICAgY29uc3QgRXF1YWxLZXkmIGMgPSBFcXVhbEtleSgpLAorICAgICAgICAgICBjb25zdCBBbGxvYyYgZCA9IEFsbG9jKCkpIDogQmFzZUNsYXNzKGEsIGIsIGMsIGQpIHt9Cit9OworCit0ZW1wbGF0ZSA8dHlwZW5hbWUgS2V5LCB0eXBlbmFtZSBIYXNoRmNuID0gaGFzaDxLZXk+LAorICAgICAgICAgIHR5cGVuYW1lIEVxdWFsS2V5ID0gc3RkOjplcXVhbF90bzxLZXk+ID4KK2NsYXNzIGhhc2hfc2V0CisgICAgOiBwdWJsaWMgR09PR0xFX1BST1RPQlVGX0hBU0hfTkFNRVNQQUNFOjpHT09HTEVfUFJPVE9CVUZfSEFTSF9TRVRfQ0xBU1M8CisgICAgICAgICAgS2V5LCBIYXNoRmNuLCBFcXVhbEtleT4geworIHB1YmxpYzoKKyAgaGFzaF9zZXQoaW50ID0gMCkge30KK307CisKKyNlbmRpZiAgLy8gIUdPT0dMRV9QUk9UT0JVRl9NSVNTSU5HX0hBU0gKKwordGVtcGxhdGUgPD4KK3N0cnVjdCBoYXNoPHN0cmluZz4geworICBpbmxpbmUgc2l6ZV90IG9wZXJhdG9yKCkoY29uc3Qgc3RyaW5nJiBrZXkpIGNvbnN0IHsKKyAgICByZXR1cm4gaGFzaDxjb25zdCBjaGFyKj4oKShrZXkuY19zdHIoKSk7CisgIH0KKworICBzdGF0aWMgY29uc3Qgc2l6ZV90IGJ1Y2tldF9zaXplID0gNDsKKyAgc3RhdGljIGNvbnN0IHNpemVfdCBtaW5fYnVja2V0cyA9IDg7CisgIGlubGluZSBib29sIG9wZXJhdG9yKCkoY29uc3Qgc3RyaW5nJiBhLCBjb25zdCBzdHJpbmcmIGIpIGNvbnN0IHsKKyAgICByZXR1cm4gYSA8IGI7CisgIH0KK307CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBGaXJzdCwgdHlwZW5hbWUgU2Vjb25kPgorc3RydWN0IGhhc2g8cGFpcjxGaXJzdCwgU2Vjb25kPiA+IHsKKyAgaW5saW5lIHNpemVfdCBvcGVyYXRvcigpKGNvbnN0IHBhaXI8Rmlyc3QsIFNlY29uZD4mIGtleSkgY29uc3QgeworICAgIHNpemVfdCBmaXJzdF9oYXNoID0gaGFzaDxGaXJzdD4oKShrZXkuZmlyc3QpOworICAgIHNpemVfdCBzZWNvbmRfaGFzaCA9IGhhc2g8U2Vjb25kPigpKGtleS5zZWNvbmQpOworCisgICAgLy8gRklYTUUoa2VudG9uKTogIFdoYXQgaXMgdGhlIGJlc3Qgd2F5IHRvIGNvbXB1dGUgdGhpcyBoYXNoPyAgSSBoYXZlCisgICAgLy8gbm8gaWRlYSEgIFRoaXMgc2VlbXMgYSBiaXQgYmV0dGVyIHRoYW4gYW4gWE9SLgorICAgIHJldHVybiBmaXJzdF9oYXNoICogKCgxIDw8IDE2KSAtIDEpICsgc2Vjb25kX2hhc2g7CisgIH0KKworICBzdGF0aWMgY29uc3Qgc2l6ZV90IGJ1Y2tldF9zaXplID0gNDsKKyAgc3RhdGljIGNvbnN0IHNpemVfdCBtaW5fYnVja2V0cyA9IDg7CisgIGlubGluZSBib29sIG9wZXJhdG9yKCkoY29uc3QgcGFpcjxGaXJzdCwgU2Vjb25kPiYgYSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHBhaXI8Rmlyc3QsIFNlY29uZD4mIGIpIGNvbnN0IHsKKyAgICByZXR1cm4gYSA8IGI7CisgIH0KK307CisKKy8vIFVzZWQgYnkgR0NDL1NHSSBTVEwgb25seS4gIChXaHkgaXNuJ3QgdGhpcyBwcm92aWRlZCBieSB0aGUgc3RhbmRhcmQKKy8vIGxpYnJhcnk/ICA6KCApCitzdHJ1Y3Qgc3RyZXEgeworICBpbmxpbmUgYm9vbCBvcGVyYXRvcigpKGNvbnN0IGNoYXIqIGEsIGNvbnN0IGNoYXIqIGIpIGNvbnN0IHsKKyAgICByZXR1cm4gc3RyY21wKGEsIGIpID09IDA7CisgIH0KK307CisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9TVFVCU19IQVNIX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9pbnQxMjguY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL2ludDEyOC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kODBjNjRmCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9pbnQxMjguY2MKQEAgLTAsMCArMSwyMDEgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2ludDEyOC5oPgorCisjaW5jbHVkZSA8aW9tYW5pcD4KKyNpbmNsdWRlIDxpb3N0cmVhbT4gIC8vIE5PTElOVChyZWFkYWJpbGl0eS9zdHJlYW1zKQorI2luY2x1ZGUgPHNzdHJlYW0+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworY29uc3QgdWludDEyOF9wb2Qga3VpbnQxMjhtYXggPSB7CisgICAgc3RhdGljX2Nhc3Q8dWludDY0PihHT09HTEVfTE9OR0xPTkcoMHhGRkZGRkZGRkZGRkZGRkZGKSksCisgICAgc3RhdGljX2Nhc3Q8dWludDY0PihHT09HTEVfTE9OR0xPTkcoMHhGRkZGRkZGRkZGRkZGRkZGKSkKK307CisKKy8vIFJldHVybnMgdGhlIDAtYmFzZWQgcG9zaXRpb24gb2YgdGhlIGxhc3Qgc2V0IGJpdCAoaS5lLiwgbW9zdCBzaWduaWZpY2FudCBiaXQpCisvLyBpbiB0aGUgZ2l2ZW4gdWludDY0LiBUaGUgYXJndW1lbnQgbWF5IG5vdCBiZSAwLgorLy8KKy8vIEZvciBleGFtcGxlOgorLy8gICBHaXZlbjogNSAoZGVjaW1hbCkgPT0gMTAxIChiaW5hcnkpCisvLyAgIFJldHVybnM6IDIKKyNkZWZpbmUgU1RFUChULCBuLCBwb3MsIHNoKSAgICAgICAgICAgICAgICAgICBcCisgIGRvIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGlmICgobikgPj0gKHN0YXRpY19jYXN0PFQ+KDEpIDw8IChzaCkpKSB7IFwKKyAgICAgIChuKSA9IChuKSA+PiAoc2gpOyAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAocG9zKSB8PSAoc2gpOyAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgfSB3aGlsZSAoMCkKK3N0YXRpYyBpbmxpbmUgaW50IEZsczY0KHVpbnQ2NCBuKSB7CisgIEdPT0dMRV9EQ0hFQ0tfTkUoMCwgbik7CisgIGludCBwb3MgPSAwOworICBTVEVQKHVpbnQ2NCwgbiwgcG9zLCAweDIwKTsKKyAgdWludDMyIG4zMiA9IG47CisgIFNURVAodWludDMyLCBuMzIsIHBvcywgMHgxMCk7CisgIFNURVAodWludDMyLCBuMzIsIHBvcywgMHgwOCk7CisgIFNURVAodWludDMyLCBuMzIsIHBvcywgMHgwNCk7CisgIHJldHVybiBwb3MgKyAoKEdPT0dMRV9VTE9OR0xPTkcoMHgzMzMzMzMzMzIyMjIxMTAwKSA+PiAobjMyIDw8IDIpKSAmIDB4Myk7Cit9CisjdW5kZWYgU1RFUAorCisvLyBMaWtlIEZsczY0KCkgYWJvdmUsIGJ1dCByZXR1cm5zIHRoZSAwLWJhc2VkIHBvc2l0aW9uIG9mIHRoZSBsYXN0IHNldCBiaXQKKy8vIChpLmUuLCBtb3N0IHNpZ25pZmljYW50IGJpdCkgaW4gdGhlIGdpdmVuIHVpbnQxMjguIFRoZSBhcmd1bWVudCBtYXkgbm90IGJlIDAuCitzdGF0aWMgaW5saW5lIGludCBGbHMxMjgodWludDEyOCBuKSB7CisgIGlmICh1aW50NjQgaGkgPSBVaW50MTI4SGlnaDY0KG4pKSB7CisgICAgcmV0dXJuIEZsczY0KGhpKSArIDY0OworICB9CisgIHJldHVybiBGbHM2NChVaW50MTI4TG93NjQobikpOworfQorCisvLyBMb25nIGRpdmlzaW9uL21vZHVsbyBmb3IgdWludDEyOCBpbXBsZW1lbnRlZCB1c2luZyB0aGUgc2hpZnQtc3VidHJhY3QKKy8vIGRpdmlzaW9uIGFsZ29yaXRobSBhZGFwdGVkIGZyb206CisvLyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzUzODYzNzcvZGl2aXNpb24td2l0aG91dC11c2luZwordm9pZCB1aW50MTI4OjpEaXZNb2RJbXBsKHVpbnQxMjggZGl2aWRlbmQsIHVpbnQxMjggZGl2aXNvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MTI4KiBxdW90aWVudF9yZXQsIHVpbnQxMjgqIHJlbWFpbmRlcl9yZXQpIHsKKyAgaWYgKGRpdmlzb3IgPT0gMCkgeworICAgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJEaXZpc2lvbiBvciBtb2QgYnkgemVybzogZGl2aWRlbmQuaGk9IiA8PCBkaXZpZGVuZC5oaV8KKyAgICAgICAgICAgICAgICAgICAgICA8PCAiLCBsbz0iIDw8IGRpdmlkZW5kLmxvXzsKKyAgfQorCisgIGlmIChkaXZpc29yID4gZGl2aWRlbmQpIHsKKyAgICAqcXVvdGllbnRfcmV0ID0gMDsKKyAgICAqcmVtYWluZGVyX3JldCA9IGRpdmlkZW5kOworICAgIHJldHVybjsKKyAgfQorCisgIGlmIChkaXZpc29yID09IGRpdmlkZW5kKSB7CisgICAgKnF1b3RpZW50X3JldCA9IDE7CisgICAgKnJlbWFpbmRlcl9yZXQgPSAwOworICAgIHJldHVybjsKKyAgfQorCisgIHVpbnQxMjggZGVub21pbmF0b3IgPSBkaXZpc29yOworICB1aW50MTI4IHBvc2l0aW9uID0gMTsKKyAgdWludDEyOCBxdW90aWVudCA9IDA7CisKKyAgLy8gTGVmdCBhbGlnbnMgdGhlIE1TQiBvZiB0aGUgZGVub21pbmF0b3IgYW5kIHRoZSBkaXZpZGVuZC4KKyAgaW50IHNoaWZ0ID0gRmxzMTI4KGRpdmlkZW5kKSAtIEZsczEyOChkZW5vbWluYXRvcik7CisgIGRlbm9taW5hdG9yIDw8PSBzaGlmdDsKKyAgcG9zaXRpb24gPDw9IHNoaWZ0OworCisgIC8vIFVzZXMgc2hpZnQtc3VidHJhY3QgYWxnb3JpdGhtIHRvIGRpdmlkZSBkaXZpZGVuZCBieSBkZW5vbWluYXRvci4gVGhlCisgIC8vIHJlbWFpbmRlciB3aWxsIGJlIGxlZnQgaW4gZGl2aWRlbmQuCisgIHdoaWxlIChwb3NpdGlvbiA+IDApIHsKKyAgICBpZiAoZGl2aWRlbmQgPj0gZGVub21pbmF0b3IpIHsKKyAgICAgIGRpdmlkZW5kIC09IGRlbm9taW5hdG9yOworICAgICAgcXVvdGllbnQgfD0gcG9zaXRpb247CisgICAgfQorICAgIHBvc2l0aW9uID4+PSAxOworICAgIGRlbm9taW5hdG9yID4+PSAxOworICB9CisKKyAgKnF1b3RpZW50X3JldCA9IHF1b3RpZW50OworICAqcmVtYWluZGVyX3JldCA9IGRpdmlkZW5kOworfQorCit1aW50MTI4JiB1aW50MTI4OjpvcGVyYXRvci89KGNvbnN0IHVpbnQxMjgmIGRpdmlzb3IpIHsKKyAgdWludDEyOCBxdW90aWVudCA9IDA7CisgIHVpbnQxMjggcmVtYWluZGVyID0gMDsKKyAgRGl2TW9kSW1wbCgqdGhpcywgZGl2aXNvciwgJnF1b3RpZW50LCAmcmVtYWluZGVyKTsKKyAgKnRoaXMgPSBxdW90aWVudDsKKyAgcmV0dXJuICp0aGlzOworfQordWludDEyOCYgdWludDEyODo6b3BlcmF0b3IlPShjb25zdCB1aW50MTI4JiBkaXZpc29yKSB7CisgIHVpbnQxMjggcXVvdGllbnQgPSAwOworICB1aW50MTI4IHJlbWFpbmRlciA9IDA7CisgIERpdk1vZEltcGwoKnRoaXMsIGRpdmlzb3IsICZxdW90aWVudCwgJnJlbWFpbmRlcik7CisgICp0aGlzID0gcmVtYWluZGVyOworICByZXR1cm4gKnRoaXM7Cit9CisKK3N0ZDo6b3N0cmVhbSYgb3BlcmF0b3I8PChzdGQ6Om9zdHJlYW0mIG8sIGNvbnN0IHVpbnQxMjgmIGIpIHsKKyAgc3RkOjppb3NfYmFzZTo6Zm10ZmxhZ3MgZmxhZ3MgPSBvLmZsYWdzKCk7CisKKyAgLy8gU2VsZWN0IGEgZGl2aXNvciB3aGljaCBpcyB0aGUgbGFyZ2VzdCBwb3dlciBvZiB0aGUgYmFzZSA8IDJeNjQuCisgIHVpbnQxMjggZGl2OworICBzdGQ6OnN0cmVhbXNpemUgZGl2X2Jhc2VfbG9nOworICBzd2l0Y2ggKGZsYWdzICYgc3RkOjppb3M6OmJhc2VmaWVsZCkgeworICAgIGNhc2Ugc3RkOjppb3M6OmhleDoKKyAgICAgIGRpdiA9IEdPT0dMRV9VTE9OR0xPTkcoMHgxMDAwMDAwMDAwMDAwMDAwKTsgIC8vIDE2XjE1CisgICAgICBkaXZfYmFzZV9sb2cgPSAxNTsKKyAgICAgIGJyZWFrOworICAgIGNhc2Ugc3RkOjppb3M6Om9jdDoKKyAgICAgIGRpdiA9IEdPT0dMRV9VTE9OR0xPTkcoMDEwMDAwMDAwMDAwMDAwMDAwMDAwMDApOyAgLy8gOF4yMQorICAgICAgZGl2X2Jhc2VfbG9nID0gMjE7CisgICAgICBicmVhazsKKyAgICBkZWZhdWx0OiAgLy8gc3RkOjppb3M6OmRlYworICAgICAgZGl2ID0gR09PR0xFX1VMT05HTE9ORygxMDAwMDAwMDAwMDAwMDAwMDAwMCk7ICAvLyAxMF4xOQorICAgICAgZGl2X2Jhc2VfbG9nID0gMTk7CisgICAgICBicmVhazsKKyAgfQorCisgIC8vIE5vdyBwaWVjZSB0b2dldGhlciB0aGUgdWludDEyOCByZXByZXNlbnRhdGlvbiBmcm9tIHRocmVlIGNodW5rcyBvZgorICAvLyB0aGUgb3JpZ2luYWwgdmFsdWUsIGVhY2ggbGVzcyB0aGFuICJkaXYiIGFuZCB0aGVyZWZvcmUgcmVwcmVzZW50YWJsZQorICAvLyBhcyBhIHVpbnQ2NC4KKyAgc3RkOjpvc3RyaW5nc3RyZWFtIG9zOworICBzdGQ6Omlvc19iYXNlOjpmbXRmbGFncyBjb3B5X21hc2sgPQorICAgICAgc3RkOjppb3M6OmJhc2VmaWVsZCB8IHN0ZDo6aW9zOjpzaG93YmFzZSB8IHN0ZDo6aW9zOjp1cHBlcmNhc2U7CisgIG9zLnNldGYoZmxhZ3MgJiBjb3B5X21hc2ssIGNvcHlfbWFzayk7CisgIHVpbnQxMjggaGlnaCA9IGI7CisgIHVpbnQxMjggbG93OworICB1aW50MTI4OjpEaXZNb2RJbXBsKGhpZ2gsIGRpdiwgJmhpZ2gsICZsb3cpOworICB1aW50MTI4IG1pZDsKKyAgdWludDEyODo6RGl2TW9kSW1wbChoaWdoLCBkaXYsICZoaWdoLCAmbWlkKTsKKyAgaWYgKGhpZ2gubG9fICE9IDApIHsKKyAgICBvcyA8PCBoaWdoLmxvXzsKKyAgICBvcyA8PCBzdGQ6Om5vc2hvd2Jhc2UgPDwgc3RkOjpzZXRmaWxsKCcwJykgPDwgc3RkOjpzZXR3KGRpdl9iYXNlX2xvZyk7CisgICAgb3MgPDwgbWlkLmxvXzsKKyAgICBvcyA8PCBzdGQ6OnNldHcoZGl2X2Jhc2VfbG9nKTsKKyAgfSBlbHNlIGlmIChtaWQubG9fICE9IDApIHsKKyAgICBvcyA8PCBtaWQubG9fOworICAgIG9zIDw8IHN0ZDo6bm9zaG93YmFzZSA8PCBzdGQ6OnNldGZpbGwoJzAnKSA8PCBzdGQ6OnNldHcoZGl2X2Jhc2VfbG9nKTsKKyAgfQorICBvcyA8PCBsb3cubG9fOworICBzdGQ6OnN0cmluZyByZXAgPSBvcy5zdHIoKTsKKworICAvLyBBZGQgdGhlIHJlcXVpc2l0ZSBwYWRkaW5nLgorICBzdGQ6OnN0cmVhbXNpemUgd2lkdGggPSBvLndpZHRoKDApOworICBpZiAod2lkdGggPiByZXAuc2l6ZSgpKSB7CisgICAgaWYgKChmbGFncyAmIHN0ZDo6aW9zOjphZGp1c3RmaWVsZCkgPT0gc3RkOjppb3M6OmxlZnQpIHsKKyAgICAgIHJlcC5hcHBlbmQod2lkdGggLSByZXAuc2l6ZSgpLCBvLmZpbGwoKSk7CisgICAgfSBlbHNlIHsKKyAgICAgIHJlcC5pbnNlcnQoc3RhdGljX2Nhc3Q8c3RkOjpzdHJpbmc6OnNpemVfdHlwZT4oMCksCisgICAgICAgICAgICAgICAgIHdpZHRoIC0gcmVwLnNpemUoKSwgby5maWxsKCkpOworICAgIH0KKyAgfQorCisgIC8vIFN0cmVhbSB0aGUgZmluYWwgcmVwcmVzZW50YXRpb24gaW4gYSBzaW5nbGUgIjw8IiBjYWxsLgorICByZXR1cm4gbyA8PCByZXA7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9pbnQxMjguaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvaW50MTI4LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTQ5OWJiNwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvaW50MTI4LmgKQEAgLTAsMCArMSwzODMgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfU1RVQlNfSU5UMTI4X0hfCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9TVFVCU19JTlQxMjhfSF8KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKworI2luY2x1ZGUgPGlvc2Z3ZD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCitzdHJ1Y3QgdWludDEyOF9wb2Q7CisKKy8vIFRPRE8oeGlhb2ZlbmcpOiBEZWZpbmUgR09PR0xFX1BST1RPQlVGX0hBU19DT05TVEVYUFIgd2hlbiBjb25zdGV4cHIgaXMKKy8vIGF2YWlsYWJsZS4KKyNpZmRlZiBHT09HTEVfUFJPVE9CVUZfSEFTX0NPTlNURVhQUgorIyBkZWZpbmUgVUlOVDEyOF9DT05TVEVYUFIgY29uc3RleHByCisjZWxzZQorIyBkZWZpbmUgVUlOVDEyOF9DT05TVEVYUFIKKyNlbmRpZgorCisvLyBBbiB1bnNpZ25lZCAxMjgtYml0IGludGVnZXIgdHlwZS4gVGhyZWFkLWNvbXBhdGlibGUuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgdWludDEyOCB7CisgcHVibGljOgorICBVSU5UMTI4X0NPTlNURVhQUiB1aW50MTI4KCk7ICAvLyBTZXRzIHRvIDAsIGJ1dCBkb24ndCB0cnVzdCBvbiB0aGlzIGJlaGF2aW9yLgorICBVSU5UMTI4X0NPTlNURVhQUiB1aW50MTI4KHVpbnQ2NCB0b3AsIHVpbnQ2NCBib3R0b20pOworI2lmbmRlZiBTV0lHCisgIFVJTlQxMjhfQ09OU1RFWFBSIHVpbnQxMjgoaW50IGJvdHRvbSk7CisgIFVJTlQxMjhfQ09OU1RFWFBSIHVpbnQxMjgodWludDMyIGJvdHRvbSk7ICAgLy8gVG9wIDk2IGJpdHMgPSAwCisjZW5kaWYKKyAgVUlOVDEyOF9DT05TVEVYUFIgdWludDEyOCh1aW50NjQgYm90dG9tKTsgICAvLyBoaV8gPSAwCisgIFVJTlQxMjhfQ09OU1RFWFBSIHVpbnQxMjgoY29uc3QgdWludDEyOF9wb2QgJnZhbCk7CisKKyAgLy8gVHJpdmlhbCBjb3B5IGNvbnN0cnVjdG9yLCBhc3NpZ25tZW50IG9wZXJhdG9yIGFuZCBkZXN0cnVjdG9yLgorCisgIHZvaWQgSW5pdGlhbGl6ZSh1aW50NjQgdG9wLCB1aW50NjQgYm90dG9tKTsKKworICAvLyBBcml0aG1ldGljIG9wZXJhdG9ycy4KKyAgdWludDEyOCYgb3BlcmF0b3IrPShjb25zdCB1aW50MTI4JiBiKTsKKyAgdWludDEyOCYgb3BlcmF0b3ItPShjb25zdCB1aW50MTI4JiBiKTsKKyAgdWludDEyOCYgb3BlcmF0b3IqPShjb25zdCB1aW50MTI4JiBiKTsKKyAgLy8gTG9uZyBkaXZpc2lvbi9tb2R1bG8gZm9yIHVpbnQxMjguCisgIHVpbnQxMjgmIG9wZXJhdG9yLz0oY29uc3QgdWludDEyOCYgYik7CisgIHVpbnQxMjgmIG9wZXJhdG9yJT0oY29uc3QgdWludDEyOCYgYik7CisgIHVpbnQxMjggb3BlcmF0b3IrKyhpbnQpOworICB1aW50MTI4IG9wZXJhdG9yLS0oaW50KTsKKyAgdWludDEyOCYgb3BlcmF0b3I8PD0oaW50KTsKKyAgdWludDEyOCYgb3BlcmF0b3I+Pj0oaW50KTsKKyAgdWludDEyOCYgb3BlcmF0b3ImPShjb25zdCB1aW50MTI4JiBiKTsKKyAgdWludDEyOCYgb3BlcmF0b3J8PShjb25zdCB1aW50MTI4JiBiKTsKKyAgdWludDEyOCYgb3BlcmF0b3JePShjb25zdCB1aW50MTI4JiBiKTsKKyAgdWludDEyOCYgb3BlcmF0b3IrKygpOworICB1aW50MTI4JiBvcGVyYXRvci0tKCk7CisKKyAgZnJpZW5kIHVpbnQ2NCBVaW50MTI4TG93NjQoY29uc3QgdWludDEyOCYgdik7CisgIGZyaWVuZCB1aW50NjQgVWludDEyOEhpZ2g2NChjb25zdCB1aW50MTI4JiB2KTsKKworICAvLyBXZSBhZGQgInN0ZDo6IiB0byBhdm9pZCBpbmNsdWRpbmcgYWxsIG9mIHBvcnQuaC4KKyAgTElCUFJPVE9CVUZfRVhQT1JUIGZyaWVuZCBzdGQ6Om9zdHJlYW0mIG9wZXJhdG9yPDwoc3RkOjpvc3RyZWFtJiBvLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1aW50MTI4JiBiKTsKKworIHByaXZhdGU6CisgIHN0YXRpYyB2b2lkIERpdk1vZEltcGwodWludDEyOCBkaXZpZGVuZCwgdWludDEyOCBkaXZpc29yLAorICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQxMjgqIHF1b3RpZW50X3JldCwgdWludDEyOCogcmVtYWluZGVyX3JldCk7CisKKyAgLy8gTGl0dGxlLWVuZGlhbiBtZW1vcnkgb3JkZXIgb3B0aW1pemF0aW9ucyBjYW4gYmVuZWZpdCBmcm9tCisgIC8vIGhhdmluZyBsb18gZmlyc3QsIGhpXyBsYXN0LgorICAvLyBTZWUgdXRpbC9lbmRpYW4vZW5kaWFuLmggYW5kIExvYWQxMjgvU3RvcmUxMjggZm9yIHN0b3JpbmcgYSB1aW50MTI4LgorICB1aW50NjQgICAgICAgIGxvXzsKKyAgdWludDY0ICAgICAgICBoaV87CisKKyAgLy8gTm90IGltcGxlbWVudGVkLCBqdXN0IGRlY2xhcmVkIGZvciBjYXRjaGluZyBhdXRvbWF0aWMgdHlwZSBjb252ZXJzaW9ucy4KKyAgdWludDEyOCh1aW50OCk7CisgIHVpbnQxMjgodWludDE2KTsKKyAgdWludDEyOChmbG9hdCB2KTsKKyAgdWludDEyOChkb3VibGUgdik7Cit9OworCisvLyBUaGlzIGlzIGEgUE9EIGZvcm0gb2YgdWludDEyOCB3aGljaCBjYW4gYmUgdXNlZCBmb3Igc3RhdGljIHZhcmlhYmxlcyB3aGljaAorLy8gbmVlZCB0byBiZSBvcGVyYXRlZCBvbiBhcyB1aW50MTI4Lgorc3RydWN0IHVpbnQxMjhfcG9kIHsKKyAgLy8gTm90ZTogVGhlIG9yZGVyaW5nIG9mIGZpZWxkcyBpcyBkaWZmZXJlbnQgdGhhbiAnY2xhc3MgdWludDEyOCcgYnV0IHRoZQorICAvLyBzYW1lIGFzIGl0cyAyLWFyZyBjb25zdHJ1Y3Rvci4gIFRoaXMgZW5hYmxlcyBtb3JlIG9idmlvdXMgaW5pdGlhbGl6YXRpb24KKyAgLy8gb2Ygc3RhdGljIGluc3RhbmNlcywgd2hpY2ggaXMgdGhlIHByaW1hcnkgcmVhc29uIGZvciB0aGlzIHN0cnVjdCBpbiB0aGUKKyAgLy8gZmlyc3QgcGxhY2UuICBUaGlzIGRvZXMgbm90IHNlZW0gdG8gZGVmZWF0IGFueSBvcHRpbWl6YXRpb25zIHdydAorICAvLyBvcGVyYXRpb25zIGludm9sdmluZyB0aGlzIHN0cnVjdC4KKyAgdWludDY0IGhpOworICB1aW50NjQgbG87Cit9OworCitMSUJQUk9UT0JVRl9FWFBPUlQgZXh0ZXJuIGNvbnN0IHVpbnQxMjhfcG9kIGt1aW50MTI4bWF4OworCisvLyBhbGxvdyB1aW50MTI4IHRvIGJlIGxvZ2dlZAorTElCUFJPVE9CVUZfRVhQT1JUIGV4dGVybiBzdGQ6Om9zdHJlYW0mIG9wZXJhdG9yPDwoc3RkOjpvc3RyZWFtJiBvLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdWludDEyOCYgYik7CisKKy8vIE1ldGhvZHMgdG8gYWNjZXNzIGxvdyBhbmQgaGlnaCBwaWVjZXMgb2YgMTI4LWJpdCB2YWx1ZS4KKy8vIERlZmluZWQgZXh0ZXJuYWxseSBmcm9tIHVpbnQxMjggdG8gZmFjaWxpdGF0ZSBjb252ZXJzaW9uCisvLyB0byBuYXRpdmUgMTI4LWJpdCB0eXBlcyB3aGVuIGNvbXBpbGVycyBzdXBwb3J0IHRoZW0uCitpbmxpbmUgdWludDY0IFVpbnQxMjhMb3c2NChjb25zdCB1aW50MTI4JiB2KSB7IHJldHVybiB2LmxvXzsgfQoraW5saW5lIHVpbnQ2NCBVaW50MTI4SGlnaDY0KGNvbnN0IHVpbnQxMjgmIHYpIHsgcmV0dXJuIHYuaGlfOyB9CisKKy8vIFRPRE86IHBlcmhhcHMgaXQgd291bGQgYmUgbmljZSB0byBoYXZlIGludDEyOCwgYSBzaWduZWQgMTI4LWJpdCB0eXBlPworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gICAgICAgICAgICAgICAgICAgICAgSW1wbGVtZW50YXRpb24gZGV0YWlscyBmb2xsb3cKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCitpbmxpbmUgYm9vbCBvcGVyYXRvcj09KGNvbnN0IHVpbnQxMjgmIGxocywgY29uc3QgdWludDEyOCYgcmhzKSB7CisgIHJldHVybiAoVWludDEyOExvdzY0KGxocykgPT0gVWludDEyOExvdzY0KHJocykgJiYKKyAgICAgICAgICBVaW50MTI4SGlnaDY0KGxocykgPT0gVWludDEyOEhpZ2g2NChyaHMpKTsKK30KK2lubGluZSBib29sIG9wZXJhdG9yIT0oY29uc3QgdWludDEyOCYgbGhzLCBjb25zdCB1aW50MTI4JiByaHMpIHsKKyAgcmV0dXJuICEobGhzID09IHJocyk7Cit9CisKK2lubGluZSBVSU5UMTI4X0NPTlNURVhQUiB1aW50MTI4Ojp1aW50MTI4KCkgOiBsb18oMCksIGhpXygwKSB7fQoraW5saW5lIFVJTlQxMjhfQ09OU1RFWFBSIHVpbnQxMjg6OnVpbnQxMjgodWludDY0IHRvcCwgdWludDY0IGJvdHRvbSkKKyAgICA6IGxvXyhib3R0b20pLCBoaV8odG9wKSB7fQoraW5saW5lIFVJTlQxMjhfQ09OU1RFWFBSIHVpbnQxMjg6OnVpbnQxMjgoY29uc3QgdWludDEyOF9wb2QmIHYpCisgICAgOiBsb18odi5sbyksIGhpXyh2LmhpKSB7fQoraW5saW5lIFVJTlQxMjhfQ09OU1RFWFBSIHVpbnQxMjg6OnVpbnQxMjgodWludDY0IGJvdHRvbSkKKyAgICA6IGxvXyhib3R0b20pLCBoaV8oMCkge30KKyNpZm5kZWYgU1dJRworaW5saW5lIFVJTlQxMjhfQ09OU1RFWFBSIHVpbnQxMjg6OnVpbnQxMjgodWludDMyIGJvdHRvbSkKKyAgICA6IGxvXyhib3R0b20pLCBoaV8oMCkge30KK2lubGluZSBVSU5UMTI4X0NPTlNURVhQUiB1aW50MTI4Ojp1aW50MTI4KGludCBib3R0b20pCisgICAgOiBsb18oYm90dG9tKSwgaGlfKHN0YXRpY19jYXN0PGludDY0PigoYm90dG9tIDwgMCkgPyAtMSA6IDApKSB7fQorI2VuZGlmCisKKyN1bmRlZiBVSU5UMTI4X0NPTlNURVhQUgorCitpbmxpbmUgdm9pZCB1aW50MTI4OjpJbml0aWFsaXplKHVpbnQ2NCB0b3AsIHVpbnQ2NCBib3R0b20pIHsKKyAgaGlfID0gdG9wOworICBsb18gPSBib3R0b207Cit9CisKKy8vIENvbXBhcmlzb24gb3BlcmF0b3JzLgorCisjZGVmaW5lIENNUDEyOChvcCkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCitpbmxpbmUgYm9vbCBvcGVyYXRvciBvcChjb25zdCB1aW50MTI4JiBsaHMsIGNvbnN0IHVpbnQxMjgmIHJocykgeyBcCisgIHJldHVybiAoVWludDEyOEhpZ2g2NChsaHMpID09IFVpbnQxMjhIaWdoNjQocmhzKSkgPyAgICAgICAgICAgICBcCisgICAgICAoVWludDEyOExvdzY0KGxocykgb3AgVWludDEyOExvdzY0KHJocykpIDogICAgICAgICAgICAgICAgICBcCisgICAgICAoVWludDEyOEhpZ2g2NChsaHMpIG9wIFVpbnQxMjhIaWdoNjQocmhzKSk7ICAgICAgICAgICAgICAgICBcCit9CisKK0NNUDEyOCg8KQorQ01QMTI4KD4pCitDTVAxMjgoPj0pCitDTVAxMjgoPD0pCisKKyN1bmRlZiBDTVAxMjgKKworLy8gVW5hcnkgb3BlcmF0b3JzCisKK2lubGluZSB1aW50MTI4IG9wZXJhdG9yLShjb25zdCB1aW50MTI4JiB2YWwpIHsKKyAgY29uc3QgdWludDY0IGhpX2ZsaXAgPSB+VWludDEyOEhpZ2g2NCh2YWwpOworICBjb25zdCB1aW50NjQgbG9fZmxpcCA9IH5VaW50MTI4TG93NjQodmFsKTsKKyAgY29uc3QgdWludDY0IGxvX2FkZCA9IGxvX2ZsaXAgKyAxOworICBpZiAobG9fYWRkIDwgbG9fZmxpcCkgeworICAgIHJldHVybiB1aW50MTI4KGhpX2ZsaXAgKyAxLCBsb19hZGQpOworICB9CisgIHJldHVybiB1aW50MTI4KGhpX2ZsaXAsIGxvX2FkZCk7Cit9CisKK2lubGluZSBib29sIG9wZXJhdG9yIShjb25zdCB1aW50MTI4JiB2YWwpIHsKKyAgcmV0dXJuICFVaW50MTI4SGlnaDY0KHZhbCkgJiYgIVVpbnQxMjhMb3c2NCh2YWwpOworfQorCisvLyBMb2dpY2FsIG9wZXJhdG9ycy4KKworaW5saW5lIHVpbnQxMjggb3BlcmF0b3J+KGNvbnN0IHVpbnQxMjgmIHZhbCkgeworICByZXR1cm4gdWludDEyOCh+VWludDEyOEhpZ2g2NCh2YWwpLCB+VWludDEyOExvdzY0KHZhbCkpOworfQorCisjZGVmaW5lIExPR0lDMTI4KG9wKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCitpbmxpbmUgdWludDEyOCBvcGVyYXRvciBvcChjb25zdCB1aW50MTI4JiBsaHMsIGNvbnN0IHVpbnQxMjgmIHJocykgeyBcCisgIHJldHVybiB1aW50MTI4KFVpbnQxMjhIaWdoNjQobGhzKSBvcCBVaW50MTI4SGlnaDY0KHJocyksICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgIFVpbnQxMjhMb3c2NChsaHMpIG9wIFVpbnQxMjhMb3c2NChyaHMpKTsgICAgICAgICAgICBcCit9CisKK0xPR0lDMTI4KHwpCitMT0dJQzEyOCgmKQorTE9HSUMxMjgoXikKKworI3VuZGVmIExPR0lDMTI4CisKKyNkZWZpbmUgTE9HSUNBU1NJR04xMjgob3ApICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCitpbmxpbmUgdWludDEyOCYgdWludDEyODo6b3BlcmF0b3Igb3AoY29uc3QgdWludDEyOCYgb3RoZXIpIHsgXAorICBoaV8gb3Agb3RoZXIuaGlfOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgbG9fIG9wIG90aGVyLmxvXzsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHJldHVybiAqdGhpczsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorfQorCitMT0dJQ0FTU0lHTjEyOCh8PSkKK0xPR0lDQVNTSUdOMTI4KCY9KQorTE9HSUNBU1NJR04xMjgoXj0pCisKKyN1bmRlZiBMT0dJQ0FTU0lHTjEyOAorCisvLyBTaGlmdCBvcGVyYXRvcnMuCisKK2lubGluZSB1aW50MTI4IG9wZXJhdG9yPDwoY29uc3QgdWludDEyOCYgdmFsLCBpbnQgYW1vdW50KSB7CisgIC8vIHVpbnQ2NCBzaGlmdHMgb2YgPj0gNjQgYXJlIHVuZGVmaW5lZCwgc28gd2Ugd2lsbCBuZWVkIHNvbWUgc3BlY2lhbC1jYXNpbmcuCisgIGlmIChhbW91bnQgPCA2NCkgeworICAgIGlmIChhbW91bnQgPT0gMCkgeworICAgICAgcmV0dXJuIHZhbDsKKyAgICB9CisgICAgdWludDY0IG5ld19oaSA9IChVaW50MTI4SGlnaDY0KHZhbCkgPDwgYW1vdW50KSB8CisgICAgICAgICAgICAgICAgICAgIChVaW50MTI4TG93NjQodmFsKSA+PiAoNjQgLSBhbW91bnQpKTsKKyAgICB1aW50NjQgbmV3X2xvID0gVWludDEyOExvdzY0KHZhbCkgPDwgYW1vdW50OworICAgIHJldHVybiB1aW50MTI4KG5ld19oaSwgbmV3X2xvKTsKKyAgfSBlbHNlIGlmIChhbW91bnQgPCAxMjgpIHsKKyAgICByZXR1cm4gdWludDEyOChVaW50MTI4TG93NjQodmFsKSA8PCAoYW1vdW50IC0gNjQpLCAwKTsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gdWludDEyOCgwLCAwKTsKKyAgfQorfQorCitpbmxpbmUgdWludDEyOCBvcGVyYXRvcj4+KGNvbnN0IHVpbnQxMjgmIHZhbCwgaW50IGFtb3VudCkgeworICAvLyB1aW50NjQgc2hpZnRzIG9mID49IDY0IGFyZSB1bmRlZmluZWQsIHNvIHdlIHdpbGwgbmVlZCBzb21lIHNwZWNpYWwtY2FzaW5nLgorICBpZiAoYW1vdW50IDwgNjQpIHsKKyAgICBpZiAoYW1vdW50ID09IDApIHsKKyAgICAgIHJldHVybiB2YWw7CisgICAgfQorICAgIHVpbnQ2NCBuZXdfaGkgPSBVaW50MTI4SGlnaDY0KHZhbCkgPj4gYW1vdW50OworICAgIHVpbnQ2NCBuZXdfbG8gPSAoVWludDEyOExvdzY0KHZhbCkgPj4gYW1vdW50KSB8CisgICAgICAgICAgICAgICAgICAgIChVaW50MTI4SGlnaDY0KHZhbCkgPDwgKDY0IC0gYW1vdW50KSk7CisgICAgcmV0dXJuIHVpbnQxMjgobmV3X2hpLCBuZXdfbG8pOworICB9IGVsc2UgaWYgKGFtb3VudCA8IDEyOCkgeworICAgIHJldHVybiB1aW50MTI4KDAsIFVpbnQxMjhIaWdoNjQodmFsKSA+PiAoYW1vdW50IC0gNjQpKTsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gdWludDEyOCgwLCAwKTsKKyAgfQorfQorCitpbmxpbmUgdWludDEyOCYgdWludDEyODo6b3BlcmF0b3I8PD0oaW50IGFtb3VudCkgeworICAvLyB1aW50NjQgc2hpZnRzIG9mID49IDY0IGFyZSB1bmRlZmluZWQsIHNvIHdlIHdpbGwgbmVlZCBzb21lIHNwZWNpYWwtY2FzaW5nLgorICBpZiAoYW1vdW50IDwgNjQpIHsKKyAgICBpZiAoYW1vdW50ICE9IDApIHsKKyAgICAgIGhpXyA9IChoaV8gPDwgYW1vdW50KSB8IChsb18gPj4gKDY0IC0gYW1vdW50KSk7CisgICAgICBsb18gPSBsb18gPDwgYW1vdW50OworICAgIH0KKyAgfSBlbHNlIGlmIChhbW91bnQgPCAxMjgpIHsKKyAgICBoaV8gPSBsb18gPDwgKGFtb3VudCAtIDY0KTsKKyAgICBsb18gPSAwOworICB9IGVsc2UgeworICAgIGhpXyA9IDA7CisgICAgbG9fID0gMDsKKyAgfQorICByZXR1cm4gKnRoaXM7Cit9CisKK2lubGluZSB1aW50MTI4JiB1aW50MTI4OjpvcGVyYXRvcj4+PShpbnQgYW1vdW50KSB7CisgIC8vIHVpbnQ2NCBzaGlmdHMgb2YgPj0gNjQgYXJlIHVuZGVmaW5lZCwgc28gd2Ugd2lsbCBuZWVkIHNvbWUgc3BlY2lhbC1jYXNpbmcuCisgIGlmIChhbW91bnQgPCA2NCkgeworICAgIGlmIChhbW91bnQgIT0gMCkgeworICAgICAgbG9fID0gKGxvXyA+PiBhbW91bnQpIHwgKGhpXyA8PCAoNjQgLSBhbW91bnQpKTsKKyAgICAgIGhpXyA9IGhpXyA+PiBhbW91bnQ7CisgICAgfQorICB9IGVsc2UgaWYgKGFtb3VudCA8IDEyOCkgeworICAgIGxvXyA9IGhpXyA+PiAoYW1vdW50IC0gNjQpOworICAgIGhpXyA9IDA7CisgIH0gZWxzZSB7CisgICAgbG9fID0gMDsKKyAgICBoaV8gPSAwOworICB9CisgIHJldHVybiAqdGhpczsKK30KKworaW5saW5lIHVpbnQxMjggb3BlcmF0b3IrKGNvbnN0IHVpbnQxMjgmIGxocywgY29uc3QgdWludDEyOCYgcmhzKSB7CisgIHJldHVybiB1aW50MTI4KGxocykgKz0gcmhzOworfQorCitpbmxpbmUgdWludDEyOCBvcGVyYXRvci0oY29uc3QgdWludDEyOCYgbGhzLCBjb25zdCB1aW50MTI4JiByaHMpIHsKKyAgcmV0dXJuIHVpbnQxMjgobGhzKSAtPSByaHM7Cit9CisKK2lubGluZSB1aW50MTI4IG9wZXJhdG9yKihjb25zdCB1aW50MTI4JiBsaHMsIGNvbnN0IHVpbnQxMjgmIHJocykgeworICByZXR1cm4gdWludDEyOChsaHMpICo9IHJoczsKK30KKworaW5saW5lIHVpbnQxMjggb3BlcmF0b3IvKGNvbnN0IHVpbnQxMjgmIGxocywgY29uc3QgdWludDEyOCYgcmhzKSB7CisgIHJldHVybiB1aW50MTI4KGxocykgLz0gcmhzOworfQorCitpbmxpbmUgdWludDEyOCBvcGVyYXRvciUoY29uc3QgdWludDEyOCYgbGhzLCBjb25zdCB1aW50MTI4JiByaHMpIHsKKyAgcmV0dXJuIHVpbnQxMjgobGhzKSAlPSByaHM7Cit9CisKK2lubGluZSB1aW50MTI4JiB1aW50MTI4OjpvcGVyYXRvcis9KGNvbnN0IHVpbnQxMjgmIGIpIHsKKyAgaGlfICs9IGIuaGlfOworICB1aW50NjQgbG9sbyA9IGxvXyArIGIubG9fOworICBpZiAobG9sbyA8IGxvXykKKyAgICArK2hpXzsKKyAgbG9fID0gbG9sbzsKKyAgcmV0dXJuICp0aGlzOworfQorCitpbmxpbmUgdWludDEyOCYgdWludDEyODo6b3BlcmF0b3ItPShjb25zdCB1aW50MTI4JiBiKSB7CisgIGhpXyAtPSBiLmhpXzsKKyAgaWYgKGIubG9fID4gbG9fKQorICAgIC0taGlfOworICBsb18gLT0gYi5sb187CisgIHJldHVybiAqdGhpczsKK30KKworaW5saW5lIHVpbnQxMjgmIHVpbnQxMjg6Om9wZXJhdG9yKj0oY29uc3QgdWludDEyOCYgYikgeworICB1aW50NjQgYTk2ID0gaGlfID4+IDMyOworICB1aW50NjQgYTY0ID0gaGlfICYgMHhmZmZmZmZmZnU7CisgIHVpbnQ2NCBhMzIgPSBsb18gPj4gMzI7CisgIHVpbnQ2NCBhMDAgPSBsb18gJiAweGZmZmZmZmZmdTsKKyAgdWludDY0IGI5NiA9IGIuaGlfID4+IDMyOworICB1aW50NjQgYjY0ID0gYi5oaV8gJiAweGZmZmZmZmZmdTsKKyAgdWludDY0IGIzMiA9IGIubG9fID4+IDMyOworICB1aW50NjQgYjAwID0gYi5sb18gJiAweGZmZmZmZmZmdTsKKyAgLy8gbXVsdGlwbHkgW2E5NiAuLiBhMDBdIHggW2I5NiAuLiBiMDBdCisgIC8vIHRlcm1zIGhpZ2hlciB0aGFuIGM5NiBkaXNhcHBlYXIgb2ZmIHRoZSBoaWdoIHNpZGUKKyAgLy8gdGVybXMgYzk2IGFuZCBjNjQgYXJlIHNhZmUgdG8gaWdub3JlIGNhcnJ5IGJpdAorICB1aW50NjQgYzk2ID0gYTk2ICogYjAwICsgYTY0ICogYjMyICsgYTMyICogYjY0ICsgYTAwICogYjk2OworICB1aW50NjQgYzY0ID0gYTY0ICogYjAwICsgYTMyICogYjMyICsgYTAwICogYjY0OworICB0aGlzLT5oaV8gPSAoYzk2IDw8IDMyKSArIGM2NDsKKyAgdGhpcy0+bG9fID0gMDsKKyAgLy8gYWRkIHRlcm1zIGFmdGVyIHRoaXMgb25lIGF0IGEgdGltZSB0byBjYXB0dXJlIGNhcnJ5CisgICp0aGlzICs9IHVpbnQxMjgoYTMyICogYjAwKSA8PCAzMjsKKyAgKnRoaXMgKz0gdWludDEyOChhMDAgKiBiMzIpIDw8IDMyOworICAqdGhpcyArPSBhMDAgKiBiMDA7CisgIHJldHVybiAqdGhpczsKK30KKworaW5saW5lIHVpbnQxMjggdWludDEyODo6b3BlcmF0b3IrKyhpbnQpIHsKKyAgdWludDEyOCB0bXAoKnRoaXMpOworICAqdGhpcyArPSAxOworICByZXR1cm4gdG1wOworfQorCitpbmxpbmUgdWludDEyOCB1aW50MTI4OjpvcGVyYXRvci0tKGludCkgeworICB1aW50MTI4IHRtcCgqdGhpcyk7CisgICp0aGlzIC09IDE7CisgIHJldHVybiB0bXA7Cit9CisKK2lubGluZSB1aW50MTI4JiB1aW50MTI4OjpvcGVyYXRvcisrKCkgeworICAqdGhpcyArPSAxOworICByZXR1cm4gKnRoaXM7Cit9CisKK2lubGluZSB1aW50MTI4JiB1aW50MTI4OjpvcGVyYXRvci0tKCkgeworICAqdGhpcyAtPSAxOworICByZXR1cm4gKnRoaXM7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9TVFVCU19JTlQxMjhfSF8KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvaW50MTI4X3VuaXR0ZXN0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9pbnQxMjhfdW5pdHRlc3QuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWQzMzI5MgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvaW50MTI4X3VuaXR0ZXN0LmNjCkBAIC0wLDAgKzEsNTEzIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9pbnQxMjguaD4KKworI2luY2x1ZGUgPGFsZ29yaXRobT4KKyNpbmNsdWRlIDxzc3RyZWFtPgorI2luY2x1ZGUgPHV0aWxpdHk+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0Lmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCitURVNUKEludDEyOCwgQWxsVGVzdHMpIHsKKyAgdWludDEyOCB6ZXJvKDApOworICB1aW50MTI4IG9uZSgxKTsKKyAgdWludDEyOCBvbmVfMmFyZygwLCAxKTsKKyAgdWludDEyOCB0d28oMCwgMik7CisgIHVpbnQxMjggdGhyZWUoMCwgMyk7CisgIHVpbnQxMjggYmlnKDIwMDAsIDIpOworICB1aW50MTI4IGJpZ19taW51c19vbmUoMjAwMCwgMSk7CisgIHVpbnQxMjggYmlnZ2VyKDIwMDEsIDEpOworICB1aW50MTI4IGJpZ2dlc3Qoa3VpbnQxMjhtYXgpOworICB1aW50MTI4IGhpZ2hfbG93KDEsIDApOworICB1aW50MTI4IGxvd19oaWdoKDAsIGt1aW50NjRtYXgpOworICBFWFBFQ1RfTFQob25lLCB0d28pOworICBFWFBFQ1RfR1QodHdvLCBvbmUpOworICBFWFBFQ1RfTFQob25lLCBiaWcpOworICBFWFBFQ1RfTFQob25lLCBiaWcpOworICBFWFBFQ1RfRVEob25lLCBvbmVfMmFyZyk7CisgIEVYUEVDVF9ORShvbmUsIHR3byk7CisgIEVYUEVDVF9HVChiaWcsIG9uZSk7CisgIEVYUEVDVF9HRShiaWcsIHR3byk7CisgIEVYUEVDVF9HRShiaWcsIGJpZ19taW51c19vbmUpOworICBFWFBFQ1RfR1QoYmlnLCBiaWdfbWludXNfb25lKTsKKyAgRVhQRUNUX0xUKGJpZ19taW51c19vbmUsIGJpZyk7CisgIEVYUEVDVF9MRShiaWdfbWludXNfb25lLCBiaWcpOworICBFWFBFQ1RfTkUoYmlnX21pbnVzX29uZSwgYmlnKTsKKyAgRVhQRUNUX0xUKGJpZywgYmlnZ2VzdCk7CisgIEVYUEVDVF9MRShiaWcsIGJpZ2dlc3QpOworICBFWFBFQ1RfR1QoYmlnZ2VzdCwgYmlnKTsKKyAgRVhQRUNUX0dFKGJpZ2dlc3QsIGJpZyk7CisgIEVYUEVDVF9FUShiaWcsIH5+YmlnKTsKKyAgRVhQRUNUX0VRKG9uZSwgb25lIHwgb25lKTsKKyAgRVhQRUNUX0VRKGJpZywgYmlnIHwgYmlnKTsKKyAgRVhQRUNUX0VRKG9uZSwgb25lIHwgemVybyk7CisgIEVYUEVDVF9FUShvbmUsIG9uZSAmIG9uZSk7CisgIEVYUEVDVF9FUShiaWcsIGJpZyAmIGJpZyk7CisgIEVYUEVDVF9FUSh6ZXJvLCBvbmUgJiB6ZXJvKTsKKyAgRVhQRUNUX0VRKHplcm8sIGJpZyAmIH5iaWcpOworICBFWFBFQ1RfRVEoemVybywgb25lIF4gb25lKTsKKyAgRVhQRUNUX0VRKHplcm8sIGJpZyBeIGJpZyk7CisgIEVYUEVDVF9FUShvbmUsIG9uZSBeIHplcm8pOworCisgIC8vIFNoaWZ0IG9wZXJhdG9ycy4KKyAgRVhQRUNUX0VRKGJpZywgYmlnIDw8IDApOworICBFWFBFQ1RfRVEoYmlnLCBiaWcgPj4gMCk7CisgIEVYUEVDVF9HVChiaWcgPDwgMSwgYmlnKTsKKyAgRVhQRUNUX0xUKGJpZyA+PiAxLCBiaWcpOworICBFWFBFQ1RfRVEoYmlnLCAoYmlnIDw8IDEwKSA+PiAxMCk7CisgIEVYUEVDVF9FUShiaWcsIChiaWcgPj4gMSkgPDwgMSk7CisgIEVYUEVDVF9FUShvbmUsIChvbmUgPDwgODApID4+IDgwKTsKKyAgRVhQRUNUX0VRKHplcm8sIChvbmUgPj4gODApIDw8IDgwKTsKKyAgRVhQRUNUX0VRKHplcm8sIGJpZyA+PiAxMjgpOworICBFWFBFQ1RfRVEoemVybywgYmlnIDw8IDEyOCk7CisKKyAgLy8gU2hpZnQgYXNzaWdubWVudHMuCisgIHVpbnQxMjggYmlnX2NvcHkgPSBiaWc7CisgIEVYUEVDVF9FUShiaWcgPDwgMCwgYmlnX2NvcHkgPDw9IDApOworICBiaWdfY29weSA9IGJpZzsKKyAgRVhQRUNUX0VRKGJpZyA+PiAwLCBiaWdfY29weSA+Pj0gMCk7CisgIGJpZ19jb3B5ID0gYmlnOworICBFWFBFQ1RfRVEoYmlnIDw8IDEsIGJpZ19jb3B5IDw8PSAxKTsKKyAgYmlnX2NvcHkgPSBiaWc7CisgIEVYUEVDVF9FUShiaWcgPj4gMSwgYmlnX2NvcHkgPj49IDEpOworICBiaWdfY29weSA9IGJpZzsKKyAgRVhQRUNUX0VRKGJpZyA8PCAxMCwgYmlnX2NvcHkgPDw9IDEwKTsKKyAgYmlnX2NvcHkgPSBiaWc7CisgIEVYUEVDVF9FUShiaWcgPj4gMTAsIGJpZ19jb3B5ID4+PSAxMCk7CisgIGJpZ19jb3B5ID0gYmlnOworICBFWFBFQ1RfRVEoYmlnIDw8IDY0LCBiaWdfY29weSA8PD0gNjQpOworICBiaWdfY29weSA9IGJpZzsKKyAgRVhQRUNUX0VRKGJpZyA+PiA2NCwgYmlnX2NvcHkgPj49IDY0KTsKKyAgYmlnX2NvcHkgPSBiaWc7CisgIEVYUEVDVF9FUShiaWcgPDwgNzMsIGJpZ19jb3B5IDw8PSA3Myk7CisgIGJpZ19jb3B5ID0gYmlnOworICBFWFBFQ1RfRVEoYmlnID4+IDczLCBiaWdfY29weSA+Pj0gNzMpOworICBiaWdfY29weSA9IGJpZzsKKyAgRVhQRUNUX0VRKGJpZyA8PCAxMjgsIGJpZ19jb3B5IDw8PSAxMjgpOworICBiaWdfY29weSA9IGJpZzsKKyAgRVhQRUNUX0VRKGJpZyA+PiAxMjgsIGJpZ19jb3B5ID4+PSAxMjgpOworCisgIEVYUEVDVF9FUShVaW50MTI4SGlnaDY0KGJpZ2dlc3QpLCBrdWludDY0bWF4KTsKKyAgRVhQRUNUX0VRKFVpbnQxMjhMb3c2NChiaWdnZXN0KSwga3VpbnQ2NG1heCk7CisgIEVYUEVDVF9FUSh6ZXJvICsgb25lLCBvbmUpOworICBFWFBFQ1RfRVEob25lICsgb25lLCB0d28pOworICBFWFBFQ1RfRVEoYmlnX21pbnVzX29uZSArIG9uZSwgYmlnKTsKKyAgRVhQRUNUX0VRKG9uZSAtIG9uZSwgemVybyk7CisgIEVYUEVDVF9FUShvbmUgLSB6ZXJvLCBvbmUpOworICBFWFBFQ1RfRVEoemVybyAtIG9uZSwgYmlnZ2VzdCk7CisgIEVYUEVDVF9FUShiaWcgLSBiaWcsIHplcm8pOworICBFWFBFQ1RfRVEoYmlnIC0gb25lLCBiaWdfbWludXNfb25lKTsKKyAgRVhQRUNUX0VRKGJpZyArIGt1aW50NjRtYXgsIGJpZ2dlcik7CisgIEVYUEVDVF9FUShiaWdnZXN0ICsgMSwgemVybyk7CisgIEVYUEVDVF9FUSh6ZXJvIC0gMSwgYmlnZ2VzdCk7CisgIEVYUEVDVF9FUShoaWdoX2xvdyAtIG9uZSwgbG93X2hpZ2gpOworICBFWFBFQ1RfRVEobG93X2hpZ2ggKyBvbmUsIGhpZ2hfbG93KTsKKyAgRVhQRUNUX0VRKFVpbnQxMjhIaWdoNjQoKHVpbnQxMjgoMSkgPDwgNjQpIC0gMSksIDApOworICBFWFBFQ1RfRVEoVWludDEyOExvdzY0KCh1aW50MTI4KDEpIDw8IDY0KSAtIDEpLCBrdWludDY0bWF4KTsKKyAgRVhQRUNUX1RSVUUoISFvbmUpOworICBFWFBFQ1RfVFJVRSghIWhpZ2hfbG93KTsKKyAgRVhQRUNUX0ZBTFNFKCEhemVybyk7CisgIEVYUEVDVF9GQUxTRSghb25lKTsKKyAgRVhQRUNUX0ZBTFNFKCFoaWdoX2xvdyk7CisgIEVYUEVDVF9UUlVFKCF6ZXJvKTsKKyAgRVhQRUNUX1RSVUUoemVybyA9PSAwKTsKKyAgRVhQRUNUX0ZBTFNFKHplcm8gIT0gMCk7CisgIEVYUEVDVF9GQUxTRShvbmUgPT0gMCk7CisgIEVYUEVDVF9UUlVFKG9uZSAhPSAwKTsKKworICB1aW50MTI4IHRlc3QgPSB6ZXJvOworICBFWFBFQ1RfRVEoKyt0ZXN0LCBvbmUpOworICBFWFBFQ1RfRVEodGVzdCwgb25lKTsKKyAgRVhQRUNUX0VRKHRlc3QrKywgb25lKTsKKyAgRVhQRUNUX0VRKHRlc3QsIHR3byk7CisgIEVYUEVDVF9FUSh0ZXN0IC09IDIsIHplcm8pOworICBFWFBFQ1RfRVEodGVzdCwgemVybyk7CisgIEVYUEVDVF9FUSh0ZXN0ICs9IDIsIHR3byk7CisgIEVYUEVDVF9FUSh0ZXN0LCB0d28pOworICBFWFBFQ1RfRVEoLS10ZXN0LCBvbmUpOworICBFWFBFQ1RfRVEodGVzdCwgb25lKTsKKyAgRVhQRUNUX0VRKHRlc3QtLSwgb25lKTsKKyAgRVhQRUNUX0VRKHRlc3QsIHplcm8pOworICBFWFBFQ1RfRVEodGVzdCB8PSB0aHJlZSwgdGhyZWUpOworICBFWFBFQ1RfRVEodGVzdCAmPSBvbmUsIG9uZSk7CisgIEVYUEVDVF9FUSh0ZXN0IF49IHRocmVlLCB0d28pOworICBFWFBFQ1RfRVEodGVzdCA+Pj0gMSwgb25lKTsKKyAgRVhQRUNUX0VRKHRlc3QgPDw9IDEsIHR3byk7CisKKyAgRVhQRUNUX0VRKGJpZywgLSgtYmlnKSk7CisgIEVYUEVDVF9FUSh0d28sIC0oKC1vbmUpIC0gMSkpOworICBFWFBFQ1RfRVEoa3VpbnQxMjhtYXgsIC1vbmUpOworICBFWFBFQ1RfRVEoemVybywgLXplcm8pOworCisgIEdPT0dMRV9MT0coSU5GTykgPDwgb25lOworICBHT09HTEVfTE9HKElORk8pIDw8IGJpZ19taW51c19vbmU7Cit9CisKK1RFU1QoSW50MTI4LCBQb2RUZXN0cykgeworICB1aW50MTI4X3BvZCBwb2QgPSB7IDEyMzQ1LCA2Nzg5MCB9OworICB1aW50MTI4IGZyb21fcG9kKHBvZCk7CisgIEVYUEVDVF9FUSgxMjM0NSwgVWludDEyOEhpZ2g2NChmcm9tX3BvZCkpOworICBFWFBFQ1RfRVEoNjc4OTAsIFVpbnQxMjhMb3c2NChmcm9tX3BvZCkpOworCisgIHVpbnQxMjggemVybygwKTsKKyAgdWludDEyOF9wb2QgemVyb19wb2QgPSB7MCwgMH07CisgIHVpbnQxMjggb25lKDEpOworICB1aW50MTI4X3BvZCBvbmVfcG9kID0gezAsIDF9OworICB1aW50MTI4IHR3bygyKTsKKyAgdWludDEyOF9wb2QgdHdvX3BvZCA9IHswLCAyfTsKKyAgdWludDEyOCB0aHJlZSgzKTsKKyAgdWludDEyOF9wb2QgdGhyZWVfcG9kID0gezAsIDN9OworICB1aW50MTI4IGJpZygxLCAwKTsKKyAgdWludDEyOF9wb2QgYmlnX3BvZCA9IHsxLCAwfTsKKworICBFWFBFQ1RfRVEoemVybywgemVyb19wb2QpOworICBFWFBFQ1RfRVEoemVyb19wb2QsIHplcm8pOworICBFWFBFQ1RfRVEoemVyb19wb2QsIHplcm9fcG9kKTsKKyAgRVhQRUNUX0VRKG9uZSwgb25lX3BvZCk7CisgIEVYUEVDVF9FUShvbmVfcG9kLCBvbmUpOworICBFWFBFQ1RfRVEob25lX3BvZCwgb25lX3BvZCk7CisgIEVYUEVDVF9FUSh0d28sIHR3b19wb2QpOworICBFWFBFQ1RfRVEodHdvX3BvZCwgdHdvKTsKKyAgRVhQRUNUX0VRKHR3b19wb2QsIHR3b19wb2QpOworCisgIEVYUEVDVF9ORShvbmUsIHR3b19wb2QpOworICBFWFBFQ1RfTkUob25lX3BvZCwgdHdvKTsKKyAgRVhQRUNUX05FKG9uZV9wb2QsIHR3b19wb2QpOworCisgIEVYUEVDVF9MVChvbmUsIHR3b19wb2QpOworICBFWFBFQ1RfTFQob25lX3BvZCwgdHdvKTsKKyAgRVhQRUNUX0xUKG9uZV9wb2QsIHR3b19wb2QpOworICBFWFBFQ1RfTEUob25lLCBvbmVfcG9kKTsKKyAgRVhQRUNUX0xFKG9uZV9wb2QsIG9uZSk7CisgIEVYUEVDVF9MRShvbmVfcG9kLCBvbmVfcG9kKTsKKyAgRVhQRUNUX0xFKG9uZSwgdHdvX3BvZCk7CisgIEVYUEVDVF9MRShvbmVfcG9kLCB0d28pOworICBFWFBFQ1RfTEUob25lX3BvZCwgdHdvX3BvZCk7CisKKyAgRVhQRUNUX0dUKHR3bywgb25lX3BvZCk7CisgIEVYUEVDVF9HVCh0d29fcG9kLCBvbmUpOworICBFWFBFQ1RfR1QodHdvX3BvZCwgb25lX3BvZCk7CisgIEVYUEVDVF9HRSh0d28sIHR3b19wb2QpOworICBFWFBFQ1RfR0UodHdvX3BvZCwgdHdvKTsKKyAgRVhQRUNUX0dFKHR3b19wb2QsIHR3b19wb2QpOworICBFWFBFQ1RfR0UodHdvLCBvbmVfcG9kKTsKKyAgRVhQRUNUX0dFKHR3b19wb2QsIG9uZSk7CisgIEVYUEVDVF9HRSh0d29fcG9kLCBvbmVfcG9kKTsKKworICBFWFBFQ1RfRVEodGhyZWUsIG9uZSB8IHR3b19wb2QpOworICBFWFBFQ1RfRVEodGhyZWUsIG9uZV9wb2QgfCB0d28pOworICBFWFBFQ1RfRVEodGhyZWUsIG9uZV9wb2QgfCB0d29fcG9kKTsKKyAgRVhQRUNUX0VRKG9uZSwgdGhyZWUgJiBvbmVfcG9kKTsKKyAgRVhQRUNUX0VRKG9uZSwgdGhyZWVfcG9kICYgb25lKTsKKyAgRVhQRUNUX0VRKG9uZSwgdGhyZWVfcG9kICYgb25lX3BvZCk7CisgIEVYUEVDVF9FUSh0d28sIHRocmVlIF4gb25lX3BvZCk7CisgIEVYUEVDVF9FUSh0d28sIHRocmVlX3BvZCBeIG9uZSk7CisgIEVYUEVDVF9FUSh0d28sIHRocmVlX3BvZCBeIG9uZV9wb2QpOworICBFWFBFQ1RfRVEodHdvLCB0aHJlZSAmICh+b25lKSk7CisgIEVYUEVDVF9FUSh0aHJlZSwgfn50aHJlZSk7CisKKyAgRVhQRUNUX0VRKHR3bywgdHdvX3BvZCA8PCAwKTsKKyAgRVhQRUNUX0VRKHR3bywgb25lX3BvZCA8PCAxKTsKKyAgRVhQRUNUX0VRKGJpZywgb25lX3BvZCA8PCA2NCk7CisgIEVYUEVDVF9FUSh6ZXJvLCBvbmVfcG9kIDw8IDEyOCk7CisgIEVYUEVDVF9FUSh0d28sIHR3b19wb2QgPj4gMCk7CisgIEVYUEVDVF9FUShvbmUsIHR3b19wb2QgPj4gMSk7CisgIEVYUEVDVF9FUShvbmUsIGJpZ19wb2QgPj4gNjQpOworCisgIEVYUEVDVF9FUShvbmUsIHplcm8gKyBvbmVfcG9kKTsKKyAgRVhQRUNUX0VRKG9uZSwgemVyb19wb2QgKyBvbmUpOworICBFWFBFQ1RfRVEob25lLCB6ZXJvX3BvZCArIG9uZV9wb2QpOworICBFWFBFQ1RfRVEob25lLCB0d28gLSBvbmVfcG9kKTsKKyAgRVhQRUNUX0VRKG9uZSwgdHdvX3BvZCAtIG9uZSk7CisgIEVYUEVDVF9FUShvbmUsIHR3b19wb2QgLSBvbmVfcG9kKTsKK30KKworVEVTVChJbnQxMjgsIE9wZXJhdG9yQXNzaWduUmV0dXJuUmVmKSB7CisgIHVpbnQxMjggdigxKTsKKyAgKHYgKz0gNCkgLT0gMzsKKyAgRVhQRUNUX0VRKDIsIHYpOworfQorCitURVNUKEludDEyOCwgTXVsdGlwbHkpIHsKKyAgdWludDEyOCBhLCBiLCBjOworCisgIC8vIFplcm8gdGVzdC4KKyAgYSA9IDA7CisgIGIgPSAwOworICBjID0gYSAqIGI7CisgIEVYUEVDVF9FUSgwLCBjKTsKKworICAvLyBNYXggY2Fycmllcy4KKyAgYSA9IHVpbnQxMjgoMCkgLSAxOworICBiID0gdWludDEyOCgwKSAtIDE7CisgIGMgPSBhICogYjsKKyAgRVhQRUNUX0VRKDEsIGMpOworCisgIC8vIFNlbGYtb3BlcmF0aW9uIHdpdGggbWF4IGNhcnJpZXMuCisgIGMgPSB1aW50MTI4KDApIC0gMTsKKyAgYyAqPSBjOworICBFWFBFQ1RfRVEoMSwgYyk7CisKKyAgLy8gMS1iaXQgeCAxLWJpdC4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCA2NDsgKytpKSB7CisgICAgZm9yIChpbnQgaiA9IDA7IGogPCA2NDsgKytqKSB7CisgICAgICBhID0gdWludDEyOCgxKSA8PCBpOworICAgICAgYiA9IHVpbnQxMjgoMSkgPDwgajsKKyAgICAgIGMgPSBhICogYjsKKyAgICAgIEVYUEVDVF9FUSh1aW50MTI4KDEpIDw8IChpK2opLCBjKTsKKyAgICB9CisgIH0KKworICAvLyBWZXJpZmllZCB3aXRoIGRjLgorICBhID0gdWludDEyOChHT09HTEVfVUxPTkdMT05HKDB4ZmZmZmVlZWVkZGRkY2NjYyksCisgICAgICAgICAgICAgIEdPT0dMRV9VTE9OR0xPTkcoMHhiYmJiYWFhYTk5OTk4ODg4KSk7CisgIGIgPSB1aW50MTI4KEdPT0dMRV9VTE9OR0xPTkcoMHg3Nzc3NjY2NjU1NTU0NDQ0KSwKKyAgICAgICAgICAgICAgR09PR0xFX1VMT05HTE9ORygweDMzMzMyMjIyMTExMTAwMDApKTsKKyAgYyA9IGEgKiBiOworICBFWFBFQ1RfRVEodWludDEyOChHT09HTEVfVUxPTkdMT05HKDB4NTMwRURBNzQxQzcxRDRDMyksCisgICAgICAgICAgICAgICAgICAgIEdPT0dMRV9VTE9OR0xPTkcoMHhCRjI1OTc1MzE5MDgwMDAwKSksIGMpOworICBFWFBFQ1RfRVEoMCwgYyAtIGIgKiBhKTsKKyAgRVhQRUNUX0VRKGEqYSAtIGIqYiwgKGErYikgKiAoYS1iKSk7CisKKyAgLy8gVmVyaWZpZWQgd2l0aCBkYy4KKyAgYSA9IHVpbnQxMjgoR09PR0xFX1VMT05HTE9ORygweDAxMjM0NTY3ODlhYmNkZWYpLAorICAgICAgICAgICAgICBHT09HTEVfVUxPTkdMT05HKDB4ZmVkY2JhOTg3NjU0MzIxMCkpOworICBiID0gdWludDEyOChHT09HTEVfVUxPTkdMT05HKDB4MDI0NjhhY2UxMzU3OWJkZiksCisgICAgICAgICAgICAgIEdPT0dMRV9VTE9OR0xPTkcoMHhmZGI5NzUzMWVjYTg2NDIwKSk7CisgIGMgPSBhICogYjsKKyAgRVhQRUNUX0VRKHVpbnQxMjgoR09PR0xFX1VMT05HTE9ORygweDk3YTg3ZjRmMjYxYmEzZjIpLAorICAgICAgICAgICAgICAgICAgICBHT09HTEVfVUxPTkdMT05HKDB4MzQyZDBiYmY0ODk0ODIwMCkpLCBjKTsKKyAgRVhQRUNUX0VRKDAsIGMgLSBiICogYSk7CisgIEVYUEVDVF9FUShhKmEgLSBiKmIsIChhK2IpICogKGEtYikpOworfQorCitURVNUKEludDEyOCwgQWxpYXNUZXN0cykgeworICB1aW50MTI4IHgxKDEsIDIpOworICB1aW50MTI4IHgyKDIsIDQpOworICB4MSArPSB4MTsKKyAgRVhQRUNUX0VRKHgyLCB4MSk7CisKKyAgdWludDEyOCB4MygxLCBzdGF0aWNfY2FzdDx1aW50NjQ+KDEpIDw8IDYzKTsKKyAgdWludDEyOCB4NCgzLCAwKTsKKyAgeDMgKz0geDM7CisgIEVYUEVDVF9FUSh4NCwgeDMpOworfQorCisjaWZkZWYgUFJPVE9CVUZfSEFTX0RFQVRIX1RFU1QKK1RFU1QoSW50MTI4LCBEaXZpZGVCeVplcm9DaGVja0ZhaWxzKSB7CisgIHVpbnQxMjggYSA9IDA7CisgIHVpbnQxMjggYiA9IDA7CisgIEVYUEVDVF9ERUFUSChhIC8gYiwgIkRpdmlzaW9uIG9yIG1vZCBieSB6ZXJvOiIpOworICBhID0gMTIzOworICBFWFBFQ1RfREVBVEgoYSAvIGIsICJEaXZpc2lvbiBvciBtb2QgYnkgemVybzoiKTsKK30KKworVEVTVChJbnQxMjgsIE1vZEJ5WmVyb0NoZWNrRmFpbHMpIHsKKyAgdWludDEyOCBhID0gMDsKKyAgdWludDEyOCBiID0gMDsKKyAgRVhQRUNUX0RFQVRIKGEgJSBiLCAiRGl2aXNpb24gb3IgbW9kIGJ5IHplcm86Iik7CisgIGEgPSAxMjM7CisgIEVYUEVDVF9ERUFUSChhICUgYiwgIkRpdmlzaW9uIG9yIG1vZCBieSB6ZXJvOiIpOworfQorI2VuZGlmICAvLyBQUk9UT0JVRl9IQVNfREVBVEhfVEVTVAorCitURVNUKEludDEyOCwgRGl2aWRlQW5kTW9kKSB7CisgIC8vIGEgOj0gcSAqIGIgKyByCisgIHVpbnQxMjggYSwgYiwgcSwgcjsKKworICAvLyBaZXJvIHRlc3QuCisgIGEgPSAwOworICBiID0gMTIzOworICBxID0gYSAvIGI7CisgIHIgPSBhICUgYjsKKyAgRVhQRUNUX0VRKDAsIHEpOworICBFWFBFQ1RfRVEoMCwgcik7CisKKyAgYSA9IHVpbnQxMjgoR09PR0xFX1VMT05HTE9ORygweDUzMGVkYTc0MWM3MWQ0YzMpLAorICAgICAgICAgICAgICBHT09HTEVfVUxPTkdMT05HKDB4YmYyNTk3NTMxOTA4MDAwMCkpOworICBxID0gdWludDEyOChHT09HTEVfVUxPTkdMT05HKDB4NGRlMmNhYjA4MSksCisgICAgICAgICAgICAgIEdPT0dMRV9VTE9OR0xPTkcoMHgxNGMzNGFiNDY3NmU0YmFiKSk7CisgIGIgPSB1aW50MTI4KDB4MTExMDAwMSk7CisgIHIgPSB1aW50MTI4KDB4M2ViNDU1KTsKKyAgQVNTRVJUX0VRKGEsIHEgKiBiICsgcik7ICAvLyBTYW5pdHktY2hlY2suCisKKyAgdWludDEyOCByZXN1bHRfcSwgcmVzdWx0X3I7CisgIHJlc3VsdF9xID0gYSAvIGI7CisgIHJlc3VsdF9yID0gYSAlIGI7CisgIEVYUEVDVF9FUShxLCByZXN1bHRfcSk7CisgIEVYUEVDVF9FUShyLCByZXN1bHRfcik7CisKKyAgLy8gVHJ5IHRoZSBvdGhlciB3YXkgYXJvdW5kLgorICBzd2FwKHEsIGIpOworICByZXN1bHRfcSA9IGEgLyBiOworICByZXN1bHRfciA9IGEgJSBiOworICBFWFBFQ1RfRVEocSwgcmVzdWx0X3EpOworICBFWFBFQ1RfRVEociwgcmVzdWx0X3IpOworICAvLyBSZXN0b3JlLgorICBzd2FwKGIsIHEpOworCisgIC8vIERpdmlkZW5kIDwgZGl2aXNvcjsgcmVzdWx0IHNob3VsZCBiZSBxOjAgcjo8ZGl2aWRlbmQ+LgorICBzd2FwKGEsIGIpOworICByZXN1bHRfcSA9IGEgLyBiOworICByZXN1bHRfciA9IGEgJSBiOworICBFWFBFQ1RfRVEoMCwgcmVzdWx0X3EpOworICBFWFBFQ1RfRVEoYSwgcmVzdWx0X3IpOworICAvLyBUcnkgdGhlIG90aGVyIHdheSBhcm91bmQuCisgIHN3YXAoYSwgcSk7CisgIHJlc3VsdF9xID0gYSAvIGI7CisgIHJlc3VsdF9yID0gYSAlIGI7CisgIEVYUEVDVF9FUSgwLCByZXN1bHRfcSk7CisgIEVYUEVDVF9FUShhLCByZXN1bHRfcik7CisgIC8vIFJlc3RvcmUuCisgIHN3YXAocSwgYSk7CisgIHN3YXAoYiwgYSk7CisKKyAgLy8gVHJ5IGEgbGFyZ2UgcmVtYWluZGVyLgorICBiID0gYSAvIDIgKyAxOworICB1aW50MTI4IGV4cGVjdGVkX3IoR09PR0xFX1VMT05HTE9ORygweDI5ODc2ZDNhMGUzOGVhNjEpLAorICAgICAgICAgICAgICAgICAgICAgR09PR0xFX1VMT05HTE9ORygweGRmOTJjYmE5OGM4M2ZmZmYpKTsKKyAgLy8gU2FuaXR5IGNoZWNrcy4KKyAgQVNTRVJUX0VRKGEgLyAyIC0gMSwgZXhwZWN0ZWRfcik7CisgIEFTU0VSVF9FUShhLCBiICsgZXhwZWN0ZWRfcik7CisgIHJlc3VsdF9xID0gYSAvIGI7CisgIHJlc3VsdF9yID0gYSAlIGI7CisgIEVYUEVDVF9FUSgxLCByZXN1bHRfcSk7CisgIEVYUEVDVF9FUShleHBlY3RlZF9yLCByZXN1bHRfcik7Cit9CisKK3N0YXRpYyB1aW50NjQgUmFuZG9tVWludDY0KCkgeworICB1aW50NjQgdjEgPSByYW5kKCk7CisgIHVpbnQ2NCB2MiA9IHJhbmQoKTsKKyAgdWludDY0IHYzID0gcmFuZCgpOworICByZXR1cm4gdjEgKiB2MiArIHYzOworfQorCitURVNUKEludDEyOCwgRGl2aWRlQW5kTW9kUmFuZG9tSW5wdXRzKSB7CisgIGNvbnN0IGludCBrTnVtSXRlcnMgPSAxIDw8IDE4OworICBmb3IgKGludCBpID0gMDsgaSA8IGtOdW1JdGVyczsgKytpKSB7CisgICAgY29uc3QgdWludDEyOCBhKFJhbmRvbVVpbnQ2NCgpLCBSYW5kb21VaW50NjQoKSk7CisgICAgY29uc3QgdWludDEyOCBiKFJhbmRvbVVpbnQ2NCgpLCBSYW5kb21VaW50NjQoKSk7CisgICAgaWYgKGIgPT0gMCkgeworICAgICAgY29udGludWU7ICAvLyBBdm9pZCBhIGRpdi1ieS16ZXJvLgorICAgIH0KKyAgICBjb25zdCB1aW50MTI4IHEgPSBhIC8gYjsKKyAgICBjb25zdCB1aW50MTI4IHIgPSBhICUgYjsKKyAgICBBU1NFUlRfRVEoYSwgYiAqIHEgKyByKTsKKyAgfQorfQorCisjaWZkZWYgR09PR0xFX1BST1RPQlVGX0hBU19DT05TVEVYUFIKK1RFU1QoSW50MTI4LCBDb25zdGV4cHJUZXN0KSB7CisgIGNvbnN0ZXhwciB1aW50MTI4IHplcm87CisgIGNvbnN0ZXhwciB1aW50MTI4IG9uZSA9IDE7CisgIGNvbnN0ZXhwciB1aW50MTI4X3BvZCBwb2QgPSB7MiwgM307CisgIGNvbnN0ZXhwciB1aW50MTI4IGZyb21fcG9kID0gcG9kOworICBjb25zdGV4cHIgdWludDEyOCBtaW51c190d28gPSAtMjsKKyAgRVhQRUNUX0VRKG9uZSwgdWludDEyOCgxKSk7CisgIEVYUEVDVF9FUShmcm9tX3BvZCwgdWludDEyOCgyLCAzKSk7CisgIEVYUEVDVF9FUShtaW51c190d28sIHVpbnQxMjgoLTFVTEwsIC0yVUxMKSk7Cit9CisKK1RFU1QoSW50MTI4LCBUcmFpdHMpIHsKKyAgRVhQRUNUX1RSVUUoc3RkOjppc190cml2aWFsbHlfY29weV9jb25zdHJ1Y3RpYmxlPHVpbnQxMjg+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKHN0ZDo6aXNfdHJpdmlhbGx5X2NvcHlfYXNzaWduYWJsZTx1aW50MTI4Pjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShzdGQ6OmlzX3RyaXZpYWxseV9kZXN0cnVjdGlibGU8dWludDEyOD46OnZhbHVlKTsKK30KKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX0hBU19DT05TVEVYUFIKKworVEVTVChJbnQxMjgsIE9TdHJlYW0pIHsKKyAgc3RydWN0IHsKKyAgICB1aW50MTI4IHZhbDsKKyAgICBzdGQ6Omlvc19iYXNlOjpmbXRmbGFncyBmbGFnczsKKyAgICBzdGQ6OnN0cmVhbXNpemUgd2lkdGg7CisgICAgY2hhciBmaWxsOworICAgIGNvbnN0IGNoYXIqIHJlcDsKKyAgfSBjYXNlc1tdID0geworICAgICAgICAvLyB6ZXJvIHdpdGggZGlmZmVyZW50IGJhc2VzCisgICAgICAgIHt1aW50MTI4KDApLCBzdGQ6Omlvczo6ZGVjLCAwLCAnXycsICIwIn0sCisgICAgICAgIHt1aW50MTI4KDApLCBzdGQ6Omlvczo6b2N0LCAwLCAnXycsICIwIn0sCisgICAgICAgIHt1aW50MTI4KDApLCBzdGQ6Omlvczo6aGV4LCAwLCAnXycsICIwIn0sCisgICAgICAgIC8vIGNyb3Nzb3ZlciBiZXR3ZWVuIGxvXyBhbmQgaGlfCisgICAgICAgIHt1aW50MTI4KDAsIC0xKSwgc3RkOjppb3M6OmRlYywgMCwgJ18nLCAiMTg0NDY3NDQwNzM3MDk1NTE2MTUifSwKKyAgICAgICAge3VpbnQxMjgoMCwgLTEpLCBzdGQ6Omlvczo6b2N0LCAwLCAnXycsICIxNzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3In0sCisgICAgICAgIHt1aW50MTI4KDAsIC0xKSwgc3RkOjppb3M6OmhleCwgMCwgJ18nLCAiZmZmZmZmZmZmZmZmZmZmZiJ9LAorICAgICAgICB7dWludDEyOCgxLCAwKSwgc3RkOjppb3M6OmRlYywgMCwgJ18nLCAiMTg0NDY3NDQwNzM3MDk1NTE2MTYifSwKKyAgICAgICAge3VpbnQxMjgoMSwgMCksIHN0ZDo6aW9zOjpvY3QsIDAsICdfJywgIjIwMDAwMDAwMDAwMDAwMDAwMDAwMDAifSwKKyAgICAgICAge3VpbnQxMjgoMSwgMCksIHN0ZDo6aW9zOjpoZXgsIDAsICdfJywgIjEwMDAwMDAwMDAwMDAwMDAwIn0sCisgICAgICAgIC8vIGp1c3QgdGhlIHRvcCBiaXQKKyAgICAgICAge3VpbnQxMjgoR09PR0xFX1VMT05HTE9ORygweDgwMDAwMDAwMDAwMDAwMDApLCAwKSwgc3RkOjppb3M6OmRlYywgMCwgJ18nLAorICAgICAgICAgIjE3MDE0MTE4MzQ2MDQ2OTIzMTczMTY4NzMwMzcxNTg4NDEwNTcyOCJ9LAorICAgICAgICB7dWludDEyOChHT09HTEVfVUxPTkdMT05HKDB4ODAwMDAwMDAwMDAwMDAwMCksIDApLCBzdGQ6Omlvczo6b2N0LCAwLCAnXycsCisgICAgICAgICAiMjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCJ9LAorICAgICAgICB7dWludDEyOChHT09HTEVfVUxPTkdMT05HKDB4ODAwMDAwMDAwMDAwMDAwMCksIDApLCBzdGQ6Omlvczo6aGV4LCAwLCAnXycsCisgICAgICAgICAiODAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAifSwKKyAgICAgICAgLy8gbWF4aW11bSB1aW50MTI4IHZhbHVlCisgICAgICAgIHt1aW50MTI4KC0xLCAtMSksIHN0ZDo6aW9zOjpkZWMsIDAsICdfJywKKyAgICAgICAgICIzNDAyODIzNjY5MjA5Mzg0NjM0NjMzNzQ2MDc0MzE3NjgyMTE0NTUifSwKKyAgICAgICAge3VpbnQxMjgoLTEsIC0xKSwgc3RkOjppb3M6Om9jdCwgMCwgJ18nLAorICAgICAgICAgIjM3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3NzcifSwKKyAgICAgICAge3VpbnQxMjgoLTEsIC0xKSwgc3RkOjppb3M6OmhleCwgMCwgJ18nLAorICAgICAgICAgImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmIn0sCisgICAgICAgIC8vIHVwcGVyY2FzZQorICAgICAgICB7dWludDEyOCgtMSwgLTEpLCBzdGQ6Omlvczo6aGV4IHwgc3RkOjppb3M6OnVwcGVyY2FzZSwgMCwgJ18nLAorICAgICAgICAgIkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGIn0sCisgICAgICAgIC8vIHNob3diYXNlCisgICAgICAgIHt1aW50MTI4KDEpLCBzdGQ6Omlvczo6ZGVjIHwgc3RkOjppb3M6OnNob3diYXNlLCAwLCAnXycsICIxIn0sCisgICAgICAgIHt1aW50MTI4KDEpLCBzdGQ6Omlvczo6b2N0IHwgc3RkOjppb3M6OnNob3diYXNlLCAwLCAnXycsICIwMSJ9LAorICAgICAgICB7dWludDEyOCgxKSwgc3RkOjppb3M6OmhleCB8IHN0ZDo6aW9zOjpzaG93YmFzZSwgMCwgJ18nLCAiMHgxIn0sCisgICAgICAgIC8vIHNob3diYXNlIGRvZXMgbm90aGluZyBvbiB6ZXJvCisgICAgICAgIHt1aW50MTI4KDApLCBzdGQ6Omlvczo6ZGVjIHwgc3RkOjppb3M6OnNob3diYXNlLCAwLCAnXycsICIwIn0sCisgICAgICAgIHt1aW50MTI4KDApLCBzdGQ6Omlvczo6b2N0IHwgc3RkOjppb3M6OnNob3diYXNlLCAwLCAnXycsICIwIn0sCisgICAgICAgIHt1aW50MTI4KDApLCBzdGQ6Omlvczo6aGV4IHwgc3RkOjppb3M6OnNob3diYXNlLCAwLCAnXycsICIwIn0sCisgICAgICAgIC8vIHNob3dwb3MgZG9lcyBub3RoaW5nIG9uIHVuc2lnbmVkIHR5cGVzCisgICAgICAgIHt1aW50MTI4KDEpLCBzdGQ6Omlvczo6ZGVjIHwgc3RkOjppb3M6OnNob3dwb3MsIDAsICdfJywgIjEifSwKKyAgICAgICAgLy8gcGFkZGluZworICAgICAgICB7dWludDEyOCg5KSwgc3RkOjppb3M6OmRlYywgNiwgJ18nLCAiX19fX185In0sCisgICAgICAgIHt1aW50MTI4KDEyMzQ1KSwgc3RkOjppb3M6OmRlYywgNiwgJ18nLCAiXzEyMzQ1In0sCisgICAgICAgIC8vIGxlZnQgYWRqdXN0bWVudAorICAgICAgICB7dWludDEyOCg5KSwgc3RkOjppb3M6OmRlYyB8IHN0ZDo6aW9zOjpsZWZ0LCA2LCAnXycsICI5X19fX18ifSwKKyAgICAgICAge3VpbnQxMjgoMTIzNDUpLCBzdGQ6Omlvczo6ZGVjIHwgc3RkOjppb3M6OmxlZnQsIDYsICdfJywgIjEyMzQ1XyJ9LAorICB9OworICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IEdPT0dMRV9BUlJBWVNJWkUoY2FzZXMpOyArK2kpIHsKKyAgICBvc3RyaW5nc3RyZWFtIG9zOworICAgIG9zLmZsYWdzKGNhc2VzW2ldLmZsYWdzKTsKKyAgICBvcy53aWR0aChjYXNlc1tpXS53aWR0aCk7CisgICAgb3MuZmlsbChjYXNlc1tpXS5maWxsKTsKKyAgICBvcyA8PCBjYXNlc1tpXS52YWw7CisgICAgRVhQRUNUX0VRKGNhc2VzW2ldLnJlcCwgb3Muc3RyKCkpOworICB9Cit9Cit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvbG9nZ2luZy5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9sb2dnaW5nLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzEwOGRiOAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvbG9nZ2luZy5oCkBAIC0wLDAgKzEsMjM3IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfU1RVQlNfTE9HR0lOR19IXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfU1RVQlNfTE9HR0lOR19IXworCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL21hY3Jvcy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9wb3J0Lmg+CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKy8vIGVtdWxhdGVzIGdvb2dsZTMvYmFzZS9sb2dnaW5nLmgKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCitlbnVtIExvZ0xldmVsIHsKKyAgTE9HTEVWRUxfSU5GTywgICAgIC8vIEluZm9ybWF0aW9uYWwuICBUaGlzIGlzIG5ldmVyIGFjdHVhbGx5IHVzZWQgYnkKKyAgICAgICAgICAgICAgICAgICAgIC8vIGxpYnByb3RvYnVmLgorICBMT0dMRVZFTF9XQVJOSU5HLCAgLy8gV2FybnMgYWJvdXQgaXNzdWVzIHRoYXQsIGFsdGhvdWdoIG5vdCB0ZWNobmljYWxseSBhCisgICAgICAgICAgICAgICAgICAgICAvLyBwcm9ibGVtIG5vdywgY291bGQgY2F1c2UgcHJvYmxlbXMgaW4gdGhlIGZ1dHVyZS4gIEZvcgorICAgICAgICAgICAgICAgICAgICAgLy8gZXhhbXBsZSwgYSAvLyB3YXJuaW5nIHdpbGwgYmUgcHJpbnRlZCB3aGVuIHBhcnNpbmcgYQorICAgICAgICAgICAgICAgICAgICAgLy8gbWVzc2FnZSB0aGF0IGlzIG5lYXIgdGhlIG1lc3NhZ2Ugc2l6ZSBsaW1pdC4KKyAgTE9HTEVWRUxfRVJST1IsICAgIC8vIEFuIGVycm9yIG9jY3VycmVkIHdoaWNoIHNob3VsZCBuZXZlciBoYXBwZW4gZHVyaW5nCisgICAgICAgICAgICAgICAgICAgICAvLyBub3JtYWwgdXNlLgorICBMT0dMRVZFTF9GQVRBTCwgICAgLy8gQW4gZXJyb3Igb2NjdXJyZWQgZnJvbSB3aGljaCB0aGUgbGlicmFyeSBjYW5ub3QKKyAgICAgICAgICAgICAgICAgICAgIC8vIHJlY292ZXIuICBUaGlzIHVzdWFsbHkgaW5kaWNhdGVzIGEgcHJvZ3JhbW1pbmcgZXJyb3IKKyAgICAgICAgICAgICAgICAgICAgIC8vIGluIHRoZSBjb2RlIHdoaWNoIGNhbGxzIHRoZSBsaWJyYXJ5LCBlc3BlY2lhbGx5IHdoZW4KKyAgICAgICAgICAgICAgICAgICAgIC8vIGNvbXBpbGVkIGluIGRlYnVnIG1vZGUuCisKKyNpZmRlZiBOREVCVUcKKyAgTE9HTEVWRUxfREZBVEFMID0gTE9HTEVWRUxfRVJST1IKKyNlbHNlCisgIExPR0xFVkVMX0RGQVRBTCA9IExPR0xFVkVMX0ZBVEFMCisjZW5kaWYKK307CisKK2NsYXNzIFN0cmluZ1BpZWNlOworbmFtZXNwYWNlIHV0aWwgeworY2xhc3MgU3RhdHVzOworfQorY2xhc3MgdWludDEyODsKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKK2NsYXNzIExvZ0ZpbmlzaGVyOworCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgTG9nTWVzc2FnZSB7CisgcHVibGljOgorICBMb2dNZXNzYWdlKExvZ0xldmVsIGxldmVsLCBjb25zdCBjaGFyKiBmaWxlbmFtZSwgaW50IGxpbmUpOworICB+TG9nTWVzc2FnZSgpOworCisgIExvZ01lc3NhZ2UmIG9wZXJhdG9yPDwoY29uc3Qgc3RkOjpzdHJpbmcmIHZhbHVlKTsKKyAgTG9nTWVzc2FnZSYgb3BlcmF0b3I8PChjb25zdCBjaGFyKiB2YWx1ZSk7CisgIExvZ01lc3NhZ2UmIG9wZXJhdG9yPDwoY2hhciB2YWx1ZSk7CisgIExvZ01lc3NhZ2UmIG9wZXJhdG9yPDwoaW50IHZhbHVlKTsKKyAgTG9nTWVzc2FnZSYgb3BlcmF0b3I8PCh1aW50IHZhbHVlKTsKKyAgTG9nTWVzc2FnZSYgb3BlcmF0b3I8PChsb25nIHZhbHVlKTsKKyAgTG9nTWVzc2FnZSYgb3BlcmF0b3I8PCh1bnNpZ25lZCBsb25nIHZhbHVlKTsKKyAgTG9nTWVzc2FnZSYgb3BlcmF0b3I8PChsb25nIGxvbmcgdmFsdWUpOworICBMb2dNZXNzYWdlJiBvcGVyYXRvcjw8KHVuc2lnbmVkIGxvbmcgbG9uZyB2YWx1ZSk7CisgIExvZ01lc3NhZ2UmIG9wZXJhdG9yPDwoZG91YmxlIHZhbHVlKTsKKyAgTG9nTWVzc2FnZSYgb3BlcmF0b3I8PCh2b2lkKiB2YWx1ZSk7CisgIExvZ01lc3NhZ2UmIG9wZXJhdG9yPDwoY29uc3QgU3RyaW5nUGllY2UmIHZhbHVlKTsKKyAgTG9nTWVzc2FnZSYgb3BlcmF0b3I8PChjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OnV0aWw6OlN0YXR1cyYgc3RhdHVzKTsKKyAgTG9nTWVzc2FnZSYgb3BlcmF0b3I8PChjb25zdCB1aW50MTI4JiB2YWx1ZSk7CisKKyBwcml2YXRlOgorICBmcmllbmQgY2xhc3MgTG9nRmluaXNoZXI7CisgIHZvaWQgRmluaXNoKCk7CisKKyAgTG9nTGV2ZWwgbGV2ZWxfOworICBjb25zdCBjaGFyKiBmaWxlbmFtZV87CisgIGludCBsaW5lXzsKKyAgc3RkOjpzdHJpbmcgbWVzc2FnZV87Cit9OworCisvLyBVc2VkIHRvIG1ha2UgdGhlIGVudGlyZSAiTE9HKEJMQUgpIDw8IGV0Yy4iIGV4cHJlc3Npb24gaGF2ZSBhIHZvaWQgcmV0dXJuCisvLyB0eXBlIGFuZCBwcmludCBhIG5ld2xpbmUgYWZ0ZXIgZWFjaCBtZXNzYWdlLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIExvZ0ZpbmlzaGVyIHsKKyBwdWJsaWM6CisgIHZvaWQgb3BlcmF0b3I9KExvZ01lc3NhZ2UmIG90aGVyKTsKK307CisKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+Citib29sIElzT2soVCBzdGF0dXMpIHsgcmV0dXJuIHN0YXR1cy5vaygpOyB9Cit0ZW1wbGF0ZTw+CitpbmxpbmUgYm9vbCBJc09rKGJvb2wgc3RhdHVzKSB7IHJldHVybiBzdGF0dXM7IH0KKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCisKKy8vIFVuZGVmIGV2ZXJ5dGhpbmcgaW4gY2FzZSB3ZSdyZSBiZWluZyBtaXhlZCB3aXRoIHNvbWUgb3RoZXIgR29vZ2xlIGxpYnJhcnkKKy8vIHdoaWNoIGFscmVhZHkgZGVmaW5lZCB0aGVtIGl0c2VsZi4gIFByZXN1bWFibHkgYWxsIEdvb2dsZSBsaWJyYXJpZXMgd2lsbAorLy8gc3VwcG9ydCB0aGUgc2FtZSBzeW50YXggZm9yIHRoZXNlIHNvIGl0IHNob3VsZCBub3QgYmUgYSBiaWcgZGVhbCBpZiB0aGV5CisvLyBlbmQgdXAgdXNpbmcgb3VyIGRlZmluaXRpb25zIGluc3RlYWQuCisjdW5kZWYgR09PR0xFX0xPRworI3VuZGVmIEdPT0dMRV9MT0dfSUYKKworI3VuZGVmIEdPT0dMRV9DSEVDSworI3VuZGVmIEdPT0dMRV9DSEVDS19PSworI3VuZGVmIEdPT0dMRV9DSEVDS19FUQorI3VuZGVmIEdPT0dMRV9DSEVDS19ORQorI3VuZGVmIEdPT0dMRV9DSEVDS19MVAorI3VuZGVmIEdPT0dMRV9DSEVDS19MRQorI3VuZGVmIEdPT0dMRV9DSEVDS19HVAorI3VuZGVmIEdPT0dMRV9DSEVDS19HRQorI3VuZGVmIEdPT0dMRV9DSEVDS19OT1ROVUxMCisKKyN1bmRlZiBHT09HTEVfRExPRworI3VuZGVmIEdPT0dMRV9EQ0hFQ0sKKyN1bmRlZiBHT09HTEVfRENIRUNLX09LCisjdW5kZWYgR09PR0xFX0RDSEVDS19FUQorI3VuZGVmIEdPT0dMRV9EQ0hFQ0tfTkUKKyN1bmRlZiBHT09HTEVfRENIRUNLX0xUCisjdW5kZWYgR09PR0xFX0RDSEVDS19MRQorI3VuZGVmIEdPT0dMRV9EQ0hFQ0tfR1QKKyN1bmRlZiBHT09HTEVfRENIRUNLX0dFCisKKyNkZWZpbmUgR09PR0xFX0xPRyhMRVZFTCkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpMb2dGaW5pc2hlcigpID0gICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6TG9nTWVzc2FnZSggICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TE9HTEVWRUxfIyNMRVZFTCwgX19GSUxFX18sIF9fTElORV9fKQorI2RlZmluZSBHT09HTEVfTE9HX0lGKExFVkVMLCBDT05ESVRJT04pIFwKKyAgIShDT05ESVRJT04pID8gKHZvaWQpMCA6IEdPT0dMRV9MT0coTEVWRUwpCisKKyNkZWZpbmUgR09PR0xFX0NIRUNLKEVYUFJFU1NJT04pIFwKKyAgR09PR0xFX0xPR19JRihGQVRBTCwgIShFWFBSRVNTSU9OKSkgPDwgIkNIRUNLIGZhaWxlZDogIiAjRVhQUkVTU0lPTiAiOiAiCisjZGVmaW5lIEdPT0dMRV9DSEVDS19PSyhBKSBHT09HTEVfQ0hFQ0soOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6SXNPayhBKSkKKyNkZWZpbmUgR09PR0xFX0NIRUNLX0VRKEEsIEIpIEdPT0dMRV9DSEVDSygoQSkgPT0gKEIpKQorI2RlZmluZSBHT09HTEVfQ0hFQ0tfTkUoQSwgQikgR09PR0xFX0NIRUNLKChBKSAhPSAoQikpCisjZGVmaW5lIEdPT0dMRV9DSEVDS19MVChBLCBCKSBHT09HTEVfQ0hFQ0soKEEpIDwgIChCKSkKKyNkZWZpbmUgR09PR0xFX0NIRUNLX0xFKEEsIEIpIEdPT0dMRV9DSEVDSygoQSkgPD0gKEIpKQorI2RlZmluZSBHT09HTEVfQ0hFQ0tfR1QoQSwgQikgR09PR0xFX0NIRUNLKChBKSA+ICAoQikpCisjZGVmaW5lIEdPT0dMRV9DSEVDS19HRShBLCBCKSBHT09HTEVfQ0hFQ0soKEEpID49IChCKSkKKworbmFtZXNwYWNlIGludGVybmFsIHsKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+CitUKiBDaGVja05vdE51bGwoY29uc3QgY2hhciogLyogZmlsZSAqLywgaW50IC8qIGxpbmUgKi8sCisgICAgICAgICAgICAgICAgY29uc3QgY2hhciogbmFtZSwgVCogdmFsKSB7CisgIGlmICh2YWwgPT0gTlVMTCkgeworICAgIEdPT0dMRV9MT0coRkFUQUwpIDw8IG5hbWU7CisgIH0KKyAgcmV0dXJuIHZhbDsKK30KK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorI2RlZmluZSBHT09HTEVfQ0hFQ0tfTk9UTlVMTChBKSBcCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkNoZWNrTm90TnVsbChcCisgICAgICBfX0ZJTEVfXywgX19MSU5FX18sICInIiAjQSAiJyBtdXN0IG5vdCBiZSBOVUxMIiwgKEEpKQorCisjaWZkZWYgTkRFQlVHCisKKyNkZWZpbmUgR09PR0xFX0RMT0cgR09PR0xFX0xPR19JRihJTkZPLCBmYWxzZSkKKworI2RlZmluZSBHT09HTEVfRENIRUNLKEVYUFJFU1NJT04pIHdoaWxlKGZhbHNlKSBHT09HTEVfQ0hFQ0soRVhQUkVTU0lPTikKKyNkZWZpbmUgR09PR0xFX0RDSEVDS19PSyhFKSBHT09HTEVfRENIRUNLKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OklzT2soRSkpCisjZGVmaW5lIEdPT0dMRV9EQ0hFQ0tfRVEoQSwgQikgR09PR0xFX0RDSEVDSygoQSkgPT0gKEIpKQorI2RlZmluZSBHT09HTEVfRENIRUNLX05FKEEsIEIpIEdPT0dMRV9EQ0hFQ0soKEEpICE9IChCKSkKKyNkZWZpbmUgR09PR0xFX0RDSEVDS19MVChBLCBCKSBHT09HTEVfRENIRUNLKChBKSA8ICAoQikpCisjZGVmaW5lIEdPT0dMRV9EQ0hFQ0tfTEUoQSwgQikgR09PR0xFX0RDSEVDSygoQSkgPD0gKEIpKQorI2RlZmluZSBHT09HTEVfRENIRUNLX0dUKEEsIEIpIEdPT0dMRV9EQ0hFQ0soKEEpID4gIChCKSkKKyNkZWZpbmUgR09PR0xFX0RDSEVDS19HRShBLCBCKSBHT09HTEVfRENIRUNLKChBKSA+PSAoQikpCisKKyNlbHNlICAvLyBOREVCVUcKKworI2RlZmluZSBHT09HTEVfRExPRyBHT09HTEVfTE9HCisKKyNkZWZpbmUgR09PR0xFX0RDSEVDSyAgICBHT09HTEVfQ0hFQ0sKKyNkZWZpbmUgR09PR0xFX0RDSEVDS19PSyBHT09HTEVfQ0hFQ0tfT0sKKyNkZWZpbmUgR09PR0xFX0RDSEVDS19FUSBHT09HTEVfQ0hFQ0tfRVEKKyNkZWZpbmUgR09PR0xFX0RDSEVDS19ORSBHT09HTEVfQ0hFQ0tfTkUKKyNkZWZpbmUgR09PR0xFX0RDSEVDS19MVCBHT09HTEVfQ0hFQ0tfTFQKKyNkZWZpbmUgR09PR0xFX0RDSEVDS19MRSBHT09HTEVfQ0hFQ0tfTEUKKyNkZWZpbmUgR09PR0xFX0RDSEVDS19HVCBHT09HTEVfQ0hFQ0tfR1QKKyNkZWZpbmUgR09PR0xFX0RDSEVDS19HRSBHT09HTEVfQ0hFQ0tfR0UKKworI2VuZGlmICAvLyAhTkRFQlVHCisKK3R5cGVkZWYgdm9pZCBMb2dIYW5kbGVyKExvZ0xldmVsIGxldmVsLCBjb25zdCBjaGFyKiBmaWxlbmFtZSwgaW50IGxpbmUsCisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdGQ6OnN0cmluZyYgbWVzc2FnZSk7CisKKy8vIFRoZSBwcm90b2J1ZiBsaWJyYXJ5IHNvbWV0aW1lcyB3cml0ZXMgd2FybmluZyBhbmQgZXJyb3IgbWVzc2FnZXMgdG8KKy8vIHN0ZGVyci4gIFRoZXNlIG1lc3NhZ2VzIGFyZSBwcmltYXJpbHkgdXNlZnVsIGZvciBkZXZlbG9wZXJzLCBidXQgbWF5CisvLyBhbHNvIGhlbHAgZW5kIHVzZXJzIGZpZ3VyZSBvdXQgYSBwcm9ibGVtLiAgSWYgeW91IHdvdWxkIHByZWZlciB0aGF0CisvLyB0aGVzZSBtZXNzYWdlcyBiZSBzZW50IHNvbWV3aGVyZSBvdGhlciB0aGFuIHN0ZGVyciwgY2FsbCBTZXRMb2dIYW5kbGVyKCkKKy8vIHRvIHNldCB5b3VyIG93biBoYW5kbGVyLiAgVGhpcyByZXR1cm5zIHRoZSBvbGQgaGFuZGxlci4gIFNldCB0aGUgaGFuZGxlcgorLy8gdG8gTlVMTCB0byBpZ25vcmUgbG9nIG1lc3NhZ2VzIChidXQgc2VlIGFsc28gTG9nU2lsZW5jZXIsIGJlbG93KS4KKy8vCisvLyBPYnZpb3VzbHksIFNldExvZ0hhbmRsZXIgaXMgbm90IHRocmVhZC1zYWZlLiAgWW91IHNob3VsZCBvbmx5IGNhbGwgaXQKKy8vIGF0IGluaXRpYWxpemF0aW9uIHRpbWUsIGFuZCBwcm9iYWJseSBub3QgZnJvbSBsaWJyYXJ5IGNvZGUuICBJZiB5b3UKKy8vIHNpbXBseSB3YW50IHRvIHN1cHByZXNzIGxvZyBtZXNzYWdlcyB0ZW1wb3JhcmlseSAoZS5nLiBiZWNhdXNlIHlvdQorLy8gaGF2ZSBzb21lIGNvZGUgdGhhdCB0ZW5kcyB0byB0cmlnZ2VyIHRoZW0gZnJlcXVlbnRseSBhbmQgeW91IGtub3cKKy8vIHRoZSB3YXJuaW5ncyBhcmUgbm90IGltcG9ydGFudCB0byB5b3UpLCB1c2UgdGhlIExvZ1NpbGVuY2VyIGNsYXNzCisvLyBiZWxvdy4KK0xJQlBST1RPQlVGX0VYUE9SVCBMb2dIYW5kbGVyKiBTZXRMb2dIYW5kbGVyKExvZ0hhbmRsZXIqIG5ld19mdW5jKTsKKworLy8gQ3JlYXRlIGEgTG9nU2lsZW5jZXIgaWYgeW91IHdhbnQgdG8gdGVtcG9yYXJpbHkgc3VwcHJlc3MgYWxsIGxvZworLy8gbWVzc2FnZXMuICBBcyBsb25nIGFzIGFueSBMb2dTaWxlbmNlciBvYmplY3RzIGV4aXN0LCBub24tZmF0YWwKKy8vIGxvZyBtZXNzYWdlcyB3aWxsIGJlIGRpc2NhcmRlZCAodGhlIGN1cnJlbnQgTG9nSGFuZGxlciB3aWxsICpub3QqCisvLyBiZSBjYWxsZWQpLiAgQ29uc3RydWN0aW5nIGEgTG9nU2lsZW5jZXIgaXMgdGhyZWFkLXNhZmUuICBZb3UgbWF5CisvLyBhY2NpZGVudGFsbHkgc3VwcHJlc3MgbG9nIG1lc3NhZ2VzIG9jY3VycmluZyBpbiBhbm90aGVyIHRocmVhZCwgYnV0CisvLyBzaW5jZSBtZXNzYWdlcyBhcmUgZ2VuZXJhbGx5IGZvciBkZWJ1Z2dpbmcgcHVycG9zZXMgb25seSwgdGhpcyBpc24ndAorLy8gYSBiaWcgZGVhbC4gIElmIHlvdSB3YW50IHRvIGludGVyY2VwdCBsb2cgbWVzc2FnZXMsIHVzZSBTZXRMb2dIYW5kbGVyKCkuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgTG9nU2lsZW5jZXIgeworIHB1YmxpYzoKKyAgTG9nU2lsZW5jZXIoKTsKKyAgfkxvZ1NpbGVuY2VyKCk7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfU1RVQlNfTE9HR0lOR19IXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9tYWNyb3MuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvbWFjcm9zLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGU5YTllYwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvbWFjcm9zLmgKQEAgLTAsMCArMSwxNjggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9NQUNST1NfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9NQUNST1NfSF9fCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvcG9ydC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKKyN1bmRlZiBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMKKyNkZWZpbmUgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFR5cGVOYW1lKSAgICBcCisgIFR5cGVOYW1lKGNvbnN0IFR5cGVOYW1lJik7ICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB2b2lkIG9wZXJhdG9yPShjb25zdCBUeXBlTmFtZSYpCisKKyN1bmRlZiBHT09HTEVfRElTQUxMT1dfSU1QTElDSVRfQ09OU1RSVUNUT1JTCisjZGVmaW5lIEdPT0dMRV9ESVNBTExPV19JTVBMSUNJVF9DT05TVFJVQ1RPUlMoVHlwZU5hbWUpIFwKKyAgVHlwZU5hbWUoKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBUeXBlTmFtZShjb25zdCBUeXBlTmFtZSYpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHZvaWQgb3BlcmF0b3I9KGNvbnN0IFR5cGVOYW1lJikKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorLy8gZnJvbSBnb29nbGUzL2Jhc2UvYmFzaWN0eXBlcy5oCisKKy8vIFRoZSBHT09HTEVfQVJSQVlTSVpFKGFycikgbWFjcm8gcmV0dXJucyB0aGUgIyBvZiBlbGVtZW50cyBpbiBhbiBhcnJheSBhcnIuCisvLyBUaGUgZXhwcmVzc2lvbiBpcyBhIGNvbXBpbGUtdGltZSBjb25zdGFudCwgYW5kIHRoZXJlZm9yZSBjYW4gYmUKKy8vIHVzZWQgaW4gZGVmaW5pbmcgbmV3IGFycmF5cywgZm9yIGV4YW1wbGUuCisvLworLy8gR09PR0xFX0FSUkFZU0laRSBjYXRjaGVzIGEgZmV3IHR5cGUgZXJyb3JzLiAgSWYgeW91IHNlZSBhIGNvbXBpbGVyIGVycm9yCisvLworLy8gICAid2FybmluZzogZGl2aXNpb24gYnkgemVybyBpbiAuLi4iCisvLworLy8gd2hlbiB1c2luZyBHT09HTEVfQVJSQVlTSVpFLCB5b3UgYXJlICh3cm9uZ2Z1bGx5KSBnaXZpbmcgaXQgYSBwb2ludGVyLgorLy8gWW91IHNob3VsZCBvbmx5IHVzZSBHT09HTEVfQVJSQVlTSVpFIG9uIHN0YXRpY2FsbHkgYWxsb2NhdGVkIGFycmF5cy4KKy8vCisvLyBUaGUgZm9sbG93aW5nIGNvbW1lbnRzIGFyZSBvbiB0aGUgaW1wbGVtZW50YXRpb24gZGV0YWlscywgYW5kIGNhbgorLy8gYmUgaWdub3JlZCBieSB0aGUgdXNlcnMuCisvLworLy8gQVJSQVlTSVpFKGFycikgd29ya3MgYnkgaW5zcGVjdGluZyBzaXplb2YoYXJyKSAodGhlICMgb2YgYnl0ZXMgaW4KKy8vIHRoZSBhcnJheSkgYW5kIHNpemVvZigqKGFycikpICh0aGUgIyBvZiBieXRlcyBpbiBvbmUgYXJyYXkKKy8vIGVsZW1lbnQpLiAgSWYgdGhlIGZvcm1lciBpcyBkaXZpc2libGUgYnkgdGhlIGxhdHRlciwgcGVyaGFwcyBhcnIgaXMKKy8vIGluZGVlZCBhbiBhcnJheSwgaW4gd2hpY2ggY2FzZSB0aGUgZGl2aXNpb24gcmVzdWx0IGlzIHRoZSAjIG9mCisvLyBlbGVtZW50cyBpbiB0aGUgYXJyYXkuICBPdGhlcndpc2UsIGFyciBjYW5ub3QgcG9zc2libHkgYmUgYW4gYXJyYXksCisvLyBhbmQgd2UgZ2VuZXJhdGUgYSBjb21waWxlciBlcnJvciB0byBwcmV2ZW50IHRoZSBjb2RlIGZyb20KKy8vIGNvbXBpbGluZy4KKy8vCisvLyBTaW5jZSB0aGUgc2l6ZSBvZiBib29sIGlzIGltcGxlbWVudGF0aW9uLWRlZmluZWQsIHdlIG5lZWQgdG8gY2FzdAorLy8gIShzaXplb2YoYSkgJiBzaXplb2YoKihhKSkpIHRvIHNpemVfdCBpbiBvcmRlciB0byBlbnN1cmUgdGhlIGZpbmFsCisvLyByZXN1bHQgaGFzIHR5cGUgc2l6ZV90LgorLy8KKy8vIFRoaXMgbWFjcm8gaXMgbm90IHBlcmZlY3QgYXMgaXQgd3JvbmdmdWxseSBhY2NlcHRzIGNlcnRhaW4KKy8vIHBvaW50ZXJzLCBuYW1lbHkgd2hlcmUgdGhlIHBvaW50ZXIgc2l6ZSBpcyBkaXZpc2libGUgYnkgdGhlIHBvaW50ZWUKKy8vIHNpemUuICBTaW5jZSBhbGwgb3VyIGNvZGUgaGFzIHRvIGdvIHRocm91Z2ggYSAzMi1iaXQgY29tcGlsZXIsCisvLyB3aGVyZSBhIHBvaW50ZXIgaXMgNCBieXRlcywgdGhpcyBtZWFucyBhbGwgcG9pbnRlcnMgdG8gYSB0eXBlIHdob3NlCisvLyBzaXplIGlzIDMgb3IgZ3JlYXRlciB0aGFuIDQgd2lsbCBiZSAocmlnaHRlb3VzbHkpIHJlamVjdGVkLgorLy8KKy8vIEt1ZG9zIHRvIEpvcmcgQnJvd24gZm9yIHRoaXMgc2ltcGxlIGFuZCBlbGVnYW50IGltcGxlbWVudGF0aW9uLgorCisjdW5kZWYgR09PR0xFX0FSUkFZU0laRQorI2RlZmluZSBHT09HTEVfQVJSQVlTSVpFKGEpIFwKKyAgKChzaXplb2YoYSkgLyBzaXplb2YoKihhKSkpIC8gXAorICAgc3RhdGljX2Nhc3Q8c2l6ZV90PighKHNpemVvZihhKSAlIHNpemVvZigqKGEpKSkpKQorCisvLyBUaGUgQ09NUElMRV9BU1NFUlQgbWFjcm8gY2FuIGJlIHVzZWQgdG8gdmVyaWZ5IHRoYXQgYSBjb21waWxlIHRpbWUKKy8vIGV4cHJlc3Npb24gaXMgdHJ1ZS4gRm9yIGV4YW1wbGUsIHlvdSBjb3VsZCB1c2UgaXQgdG8gdmVyaWZ5IHRoZQorLy8gc2l6ZSBvZiBhIHN0YXRpYyBhcnJheToKKy8vCisvLyAgIENPTVBJTEVfQVNTRVJUKEFSUkFZU0laRShjb250ZW50X3R5cGVfbmFtZXMpID09IENPTlRFTlRfTlVNX1RZUEVTLAorLy8gICAgICAgICAgICAgICAgICBjb250ZW50X3R5cGVfbmFtZXNfaW5jb3JyZWN0X3NpemUpOworLy8KKy8vIG9yIHRvIG1ha2Ugc3VyZSBhIHN0cnVjdCBpcyBzbWFsbGVyIHRoYW4gYSBjZXJ0YWluIHNpemU6CisvLworLy8gICBDT01QSUxFX0FTU0VSVChzaXplb2YoZm9vKSA8IDEyOCwgZm9vX3Rvb19sYXJnZSk7CisvLworLy8gVGhlIHNlY29uZCBhcmd1bWVudCB0byB0aGUgbWFjcm8gaXMgdGhlIG5hbWUgb2YgdGhlIHZhcmlhYmxlLiBJZgorLy8gdGhlIGV4cHJlc3Npb24gaXMgZmFsc2UsIG1vc3QgY29tcGlsZXJzIHdpbGwgaXNzdWUgYSB3YXJuaW5nL2Vycm9yCisvLyBjb250YWluaW5nIHRoZSBuYW1lIG9mIHRoZSB2YXJpYWJsZS4KKworbmFtZXNwYWNlIGludGVybmFsIHsKKwordGVtcGxhdGUgPGJvb2w+CitzdHJ1Y3QgQ29tcGlsZUFzc2VydCB7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKKworI3VuZGVmIEdPT0dMRV9DT01QSUxFX0FTU0VSVAorI2lmIF9fY3BsdXNwbHVzID49IDIwMTEwM0wKKyNkZWZpbmUgR09PR0xFX0NPTVBJTEVfQVNTRVJUKGV4cHIsIG1zZykgc3RhdGljX2Fzc2VydChleHByLCAjbXNnKQorI2Vsc2UKKyNkZWZpbmUgR09PR0xFX0NPTVBJTEVfQVNTRVJUKGV4cHIsIG1zZykgXAorICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpDb21waWxlQXNzZXJ0PChib29sKGV4cHIpKT4gXAorICAgICAgICAgIG1zZ1tib29sKGV4cHIpID8gMSA6IC0xXTsgXAorICAodm9pZCltc2cKKy8vIEltcGxlbWVudGF0aW9uIGRldGFpbHMgb2YgQ09NUElMRV9BU1NFUlQ6CisvLworLy8gLSBDT01QSUxFX0FTU0VSVCB3b3JrcyBieSBkZWZpbmluZyBhbiBhcnJheSB0eXBlIHRoYXQgaGFzIC0xCisvLyAgIGVsZW1lbnRzIChhbmQgdGh1cyBpcyBpbnZhbGlkKSB3aGVuIHRoZSBleHByZXNzaW9uIGlzIGZhbHNlLgorLy8KKy8vIC0gVGhlIHNpbXBsZXIgZGVmaW5pdGlvbgorLy8KKy8vICAgICAjZGVmaW5lIENPTVBJTEVfQVNTRVJUKGV4cHIsIG1zZykgdHlwZWRlZiBjaGFyIG1zZ1soZXhwcikgPyAxIDogLTFdCisvLworLy8gICBkb2VzIG5vdCB3b3JrLCBhcyBnY2Mgc3VwcG9ydHMgdmFyaWFibGUtbGVuZ3RoIGFycmF5cyB3aG9zZSBzaXplcworLy8gICBhcmUgZGV0ZXJtaW5lZCBhdCBydW4tdGltZSAodGhpcyBpcyBnY2MncyBleHRlbnNpb24gYW5kIG5vdCBwYXJ0CisvLyAgIG9mIHRoZSBDKysgc3RhbmRhcmQpLiAgQXMgYSByZXN1bHQsIGdjYyBmYWlscyB0byByZWplY3QgdGhlCisvLyAgIGZvbGxvd2luZyBjb2RlIHdpdGggdGhlIHNpbXBsZSBkZWZpbml0aW9uOgorLy8KKy8vICAgICBpbnQgZm9vOworLy8gICAgIENPTVBJTEVfQVNTRVJUKGZvbywgbXNnKTsgLy8gbm90IHN1cHBvc2VkIHRvIGNvbXBpbGUgYXMgZm9vIGlzCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBub3QgYSBjb21waWxlLXRpbWUgY29uc3RhbnQuCisvLworLy8gLSBCeSB1c2luZyB0aGUgdHlwZSBDb21waWxlQXNzZXJ0PChib29sKGV4cHIpKT4sIHdlIGVuc3VyZXMgdGhhdAorLy8gICBleHByIGlzIGEgY29tcGlsZS10aW1lIGNvbnN0YW50LiAgKFRlbXBsYXRlIGFyZ3VtZW50cyBtdXN0IGJlCisvLyAgIGRldGVybWluZWQgYXQgY29tcGlsZS10aW1lLikKKy8vCisvLyAtIFRoZSBvdXR0ZXIgcGFyZW50aGVzZXMgaW4gQ29tcGlsZUFzc2VydDwoYm9vbChleHByKSk+IGFyZSBuZWNlc3NhcnkKKy8vICAgdG8gd29yayBhcm91bmQgYSBidWcgaW4gZ2NjIDMuNC40IGFuZCA0LjAuMS4gIElmIHdlIGhhZCB3cml0dGVuCisvLworLy8gICAgIENvbXBpbGVBc3NlcnQ8Ym9vbChleHByKT4KKy8vCisvLyAgIGluc3RlYWQsIHRoZXNlIGNvbXBpbGVycyB3aWxsIHJlZnVzZSB0byBjb21waWxlCisvLworLy8gICAgIENPTVBJTEVfQVNTRVJUKDUgPiAwLCBzb21lX21lc3NhZ2UpOworLy8KKy8vICAgKFRoZXkgc2VlbSB0byB0aGluayB0aGUgIj4iIGluICI1ID4gMCIgbWFya3MgdGhlIGVuZCBvZiB0aGUKKy8vICAgdGVtcGxhdGUgYXJndW1lbnQgbGlzdC4pCisvLworLy8gLSBUaGUgYXJyYXkgc2l6ZSBpcyAoYm9vbChleHByKSA/IDEgOiAtMSksIGluc3RlYWQgb2Ygc2ltcGx5CisvLworLy8gICAgICgoZXhwcikgPyAxIDogLTEpLgorLy8KKy8vICAgVGhpcyBpcyB0byBhdm9pZCBydW5uaW5nIGludG8gYSBidWcgaW4gTVMgVkMgNy4xLCB3aGljaAorLy8gICBjYXVzZXMgKCgwLjApID8gMSA6IC0xKSB0byBpbmNvcnJlY3RseSBldmFsdWF0ZSB0byAxLgorI2VuZGlmICAvLyBfX2NwbHVzcGx1cyA+PSAyMDExMDNMCisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9NQUNST1NfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL21hcF91dGlsLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL21hcF91dGlsLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGNjY2JiZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvbWFwX3V0aWwuaApAQCAtMCwwICsxLDc2OSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAxNCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIGZyb20gZ29vZ2xlMy91dGlsL2d0bC9tYXBfdXRpbC5oCisvLyBBdXRob3I6IEFudG9uIENhcnZlcgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9TVFVCU19NQVBfVVRJTF9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1NUVUJTX01BUF9VVElMX0hfXworCisjaW5jbHVkZSA8c3RkZGVmLmg+CisjaW5jbHVkZSA8aXRlcmF0b3I+CisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPHV0aWxpdHk+CisjaW5jbHVkZSA8dmVjdG9yPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW50ZXJuYWwgeworLy8gTG9jYWwgaW1wbGVtZW50YXRpb24gb2YgUmVtb3ZlQ29uc3QgdG8gYXZvaWQgaW5jbHVkaW5nIGJhc2UvdHlwZV90cmFpdHMuaC4KK3RlbXBsYXRlIDxjbGFzcyBUPiBzdHJ1Y3QgUmVtb3ZlQ29uc3QgeyB0eXBlZGVmIFQgdHlwZTsgfTsKK3RlbXBsYXRlIDxjbGFzcyBUPiBzdHJ1Y3QgUmVtb3ZlQ29uc3Q8Y29uc3QgVD4gOiBSZW1vdmVDb25zdDxUPiB7fTsKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorCisvLworLy8gRmluZCooKQorLy8KKworLy8gUmV0dXJucyBhIGNvbnN0IHJlZmVyZW5jZSB0byB0aGUgdmFsdWUgYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBrZXkgaWYgaXQKKy8vIGV4aXN0cy4gQ3Jhc2hlcyBvdGhlcndpc2UuCisvLworLy8gVGhpcyBpcyBpbnRlbmRlZCBhcyBhIHJlcGxhY2VtZW50IGZvciBvcGVyYXRvcltdIGFzIGFuIHJ2YWx1ZSAoZm9yIHJlYWRpbmcpCisvLyB3aGVuIHRoZSBrZXkgaXMgZ3VhcmFudGVlZCB0byBleGlzdC4KKy8vCisvLyBvcGVyYXRvcltdIGZvciBsb29rdXAgaXMgZGlzY291cmFnZWQgZm9yIHNldmVyYWwgcmVhc29uczoKKy8vICAqIEl0IGhhcyBhIHNpZGUtZWZmZWN0IG9mIGluc2VydGluZyBtaXNzaW5nIGtleXMKKy8vICAqIEl0IGlzIG5vdCB0aHJlYWQtc2FmZSAoZXZlbiB3aGVuIGl0IGlzIG5vdCBpbnNlcnRpbmcsIGl0IGNhbiBzdGlsbAorLy8gICAgICBjaG9vc2UgdG8gcmVzaXplIHRoZSB1bmRlcmx5aW5nIHN0b3JhZ2UpCisvLyAgKiBJdCBpbnZhbGlkYXRlcyBpdGVyYXRvcnMgKHdoZW4gaXQgY2hvb3NlcyB0byByZXNpemUpCisvLyAgKiBJdCBkZWZhdWx0IGNvbnN0cnVjdHMgYSB2YWx1ZSBvYmplY3QgZXZlbiBpZiBpdCBkb2Vzbid0IG5lZWQgdG8KKy8vCisvLyBUaGlzIHZlcnNpb24gYXNzdW1lcyB0aGUga2V5IGlzIHByaW50YWJsZSwgYW5kIGluY2x1ZGVzIGl0IGluIHRoZSBmYXRhbCBsb2cKKy8vIG1lc3NhZ2UuCit0ZW1wbGF0ZSA8Y2xhc3MgQ29sbGVjdGlvbj4KK2NvbnN0IHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OnNlY29uZF90eXBlJgorRmluZE9yRGllKGNvbnN0IENvbGxlY3Rpb24mIGNvbGxlY3Rpb24sCisgICAgICAgICAgY29uc3QgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6Zmlyc3RfdHlwZSYga2V5KSB7CisgIHR5cGVuYW1lIENvbGxlY3Rpb246OmNvbnN0X2l0ZXJhdG9yIGl0ID0gY29sbGVjdGlvbi5maW5kKGtleSk7CisgIEdPT0dMRV9DSEVDSyhpdCAhPSBjb2xsZWN0aW9uLmVuZCgpKSA8PCAiTWFwIGtleSBub3QgZm91bmQ6ICIgPDwga2V5OworICByZXR1cm4gaXQtPnNlY29uZDsKK30KKworLy8gU2FtZSBhcyBhYm92ZSwgYnV0IHJldHVybnMgYSBub24tY29uc3QgcmVmZXJlbmNlLgordGVtcGxhdGUgPGNsYXNzIENvbGxlY3Rpb24+Cit0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpzZWNvbmRfdHlwZSYKK0ZpbmRPckRpZShDb2xsZWN0aW9uJiBjb2xsZWN0aW9uLCAgLy8gTk9MSU5UCisgICAgICAgICAgY29uc3QgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6Zmlyc3RfdHlwZSYga2V5KSB7CisgIHR5cGVuYW1lIENvbGxlY3Rpb246Oml0ZXJhdG9yIGl0ID0gY29sbGVjdGlvbi5maW5kKGtleSk7CisgIEdPT0dMRV9DSEVDSyhpdCAhPSBjb2xsZWN0aW9uLmVuZCgpKSA8PCAiTWFwIGtleSBub3QgZm91bmQ6ICIgPDwga2V5OworICByZXR1cm4gaXQtPnNlY29uZDsKK30KKworLy8gU2FtZSBhcyBGaW5kT3JEaWUgYWJvdmUsIGJ1dCBkb2Vzbid0IGxvZyB0aGUga2V5IG9uIGZhaWx1cmUuCit0ZW1wbGF0ZSA8Y2xhc3MgQ29sbGVjdGlvbj4KK2NvbnN0IHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OnNlY29uZF90eXBlJgorRmluZE9yRGllTm9QcmludChjb25zdCBDb2xsZWN0aW9uJiBjb2xsZWN0aW9uLAorICAgICAgICAgICAgICAgICBjb25zdCB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpmaXJzdF90eXBlJiBrZXkpIHsKKyAgdHlwZW5hbWUgQ29sbGVjdGlvbjo6Y29uc3RfaXRlcmF0b3IgaXQgPSBjb2xsZWN0aW9uLmZpbmQoa2V5KTsKKyAgR09PR0xFX0NIRUNLKGl0ICE9IGNvbGxlY3Rpb24uZW5kKCkpIDw8ICJNYXAga2V5IG5vdCBmb3VuZCI7CisgIHJldHVybiBpdC0+c2Vjb25kOworfQorCisvLyBTYW1lIGFzIGFib3ZlLCBidXQgcmV0dXJucyBhIG5vbi1jb25zdCByZWZlcmVuY2UuCit0ZW1wbGF0ZSA8Y2xhc3MgQ29sbGVjdGlvbj4KK3R5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OnNlY29uZF90eXBlJgorRmluZE9yRGllTm9QcmludChDb2xsZWN0aW9uJiBjb2xsZWN0aW9uLCAgLy8gTk9MSU5UCisgICAgICAgICAgICAgICAgIGNvbnN0IHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OmZpcnN0X3R5cGUmIGtleSkgeworICB0eXBlbmFtZSBDb2xsZWN0aW9uOjppdGVyYXRvciBpdCA9IGNvbGxlY3Rpb24uZmluZChrZXkpOworICBHT09HTEVfQ0hFQ0soaXQgIT0gY29sbGVjdGlvbi5lbmQoKSkgPDwgIk1hcCBrZXkgbm90IGZvdW5kIjsKKyAgcmV0dXJuIGl0LT5zZWNvbmQ7Cit9CisKKy8vIFJldHVybnMgYSBjb25zdCByZWZlcmVuY2UgdG8gdGhlIHZhbHVlIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4ga2V5IGlmIGl0CisvLyBleGlzdHMsIG90aGVyd2lzZSByZXR1cm5zIGEgY29uc3QgcmVmZXJlbmNlIHRvIHRoZSBwcm92aWRlZCBkZWZhdWx0IHZhbHVlLgorLy8KKy8vIFdBUk5JTkc6IElmIGEgdGVtcG9yYXJ5IG9iamVjdCBpcyBwYXNzZWQgYXMgdGhlIGRlZmF1bHQgInZhbHVlLCIKKy8vIHRoaXMgZnVuY3Rpb24gd2lsbCByZXR1cm4gYSByZWZlcmVuY2UgdG8gdGhhdCB0ZW1wb3Jhcnkgb2JqZWN0LAorLy8gd2hpY2ggd2lsbCBiZSBkZXN0cm95ZWQgYXQgdGhlIGVuZCBvZiB0aGUgc3RhdGVtZW50LiBBIGNvbW1vbgorLy8gZXhhbXBsZTogaWYgeW91IGhhdmUgYSBtYXAgd2l0aCBzdHJpbmcgdmFsdWVzLCBhbmQgeW91IHBhc3MgYSBjaGFyKgorLy8gYXMgdGhlIGRlZmF1bHQgInZhbHVlLCIgZWl0aGVyIHVzZSB0aGUgcmV0dXJuZWQgdmFsdWUgaW1tZWRpYXRlbHkKKy8vIG9yIHN0b3JlIGl0IGluIGEgc3RyaW5nIChub3Qgc3RyaW5nJikuCisvLyBEZXRhaWxzOiBodHRwOi8vZ28vZmluZHdpdGhkZWZhdWx0Cit0ZW1wbGF0ZSA8Y2xhc3MgQ29sbGVjdGlvbj4KK2NvbnN0IHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OnNlY29uZF90eXBlJgorRmluZFdpdGhEZWZhdWx0KGNvbnN0IENvbGxlY3Rpb24mIGNvbGxlY3Rpb24sCisgICAgICAgICAgICAgICAgY29uc3QgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6Zmlyc3RfdHlwZSYga2V5LAorICAgICAgICAgICAgICAgIGNvbnN0IHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OnNlY29uZF90eXBlJiB2YWx1ZSkgeworICB0eXBlbmFtZSBDb2xsZWN0aW9uOjpjb25zdF9pdGVyYXRvciBpdCA9IGNvbGxlY3Rpb24uZmluZChrZXkpOworICBpZiAoaXQgPT0gY29sbGVjdGlvbi5lbmQoKSkgeworICAgIHJldHVybiB2YWx1ZTsKKyAgfQorICByZXR1cm4gaXQtPnNlY29uZDsKK30KKworLy8gUmV0dXJucyBhIHBvaW50ZXIgdG8gdGhlIGNvbnN0IHZhbHVlIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4ga2V5IGlmIGl0CisvLyBleGlzdHMsIG9yIE5VTEwgb3RoZXJ3aXNlLgordGVtcGxhdGUgPGNsYXNzIENvbGxlY3Rpb24+Citjb25zdCB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpzZWNvbmRfdHlwZSoKK0ZpbmRPck51bGwoY29uc3QgQ29sbGVjdGlvbiYgY29sbGVjdGlvbiwKKyAgICAgICAgICAgY29uc3QgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6Zmlyc3RfdHlwZSYga2V5KSB7CisgIHR5cGVuYW1lIENvbGxlY3Rpb246OmNvbnN0X2l0ZXJhdG9yIGl0ID0gY29sbGVjdGlvbi5maW5kKGtleSk7CisgIGlmIChpdCA9PSBjb2xsZWN0aW9uLmVuZCgpKSB7CisgICAgcmV0dXJuIDA7CisgIH0KKyAgcmV0dXJuICZpdC0+c2Vjb25kOworfQorCisvLyBTYW1lIGFzIGFib3ZlIGJ1dCByZXR1cm5zIGEgcG9pbnRlciB0byB0aGUgbm9uLWNvbnN0IHZhbHVlLgordGVtcGxhdGUgPGNsYXNzIENvbGxlY3Rpb24+Cit0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpzZWNvbmRfdHlwZSoKK0ZpbmRPck51bGwoQ29sbGVjdGlvbiYgY29sbGVjdGlvbiwgIC8vIE5PTElOVAorICAgICAgICAgICBjb25zdCB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpmaXJzdF90eXBlJiBrZXkpIHsKKyAgdHlwZW5hbWUgQ29sbGVjdGlvbjo6aXRlcmF0b3IgaXQgPSBjb2xsZWN0aW9uLmZpbmQoa2V5KTsKKyAgaWYgKGl0ID09IGNvbGxlY3Rpb24uZW5kKCkpIHsKKyAgICByZXR1cm4gMDsKKyAgfQorICByZXR1cm4gJml0LT5zZWNvbmQ7Cit9CisKKy8vIFJldHVybnMgdGhlIHBvaW50ZXIgdmFsdWUgYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBrZXkuIElmIG5vbmUgaXMgZm91bmQsCisvLyBOVUxMIGlzIHJldHVybmVkLiBUaGUgZnVuY3Rpb24gaXMgZGVzaWduZWQgdG8gYmUgdXNlZCB3aXRoIGEgbWFwIG9mIGtleXMgdG8KKy8vIHBvaW50ZXJzLgorLy8KKy8vIFRoaXMgZnVuY3Rpb24gZG9lcyBub3QgZGlzdGluZ3Vpc2ggYmV0d2VlbiBhIG1pc3Npbmcga2V5IGFuZCBhIGtleSBtYXBwZWQKKy8vIHRvIGEgTlVMTCB2YWx1ZS4KK3RlbXBsYXRlIDxjbGFzcyBDb2xsZWN0aW9uPgordHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6c2Vjb25kX3R5cGUKK0ZpbmRQdHJPck51bGwoY29uc3QgQ29sbGVjdGlvbiYgY29sbGVjdGlvbiwKKyAgICAgICAgICAgICAgY29uc3QgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6Zmlyc3RfdHlwZSYga2V5KSB7CisgIHR5cGVuYW1lIENvbGxlY3Rpb246OmNvbnN0X2l0ZXJhdG9yIGl0ID0gY29sbGVjdGlvbi5maW5kKGtleSk7CisgIGlmIChpdCA9PSBjb2xsZWN0aW9uLmVuZCgpKSB7CisgICAgcmV0dXJuIHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OnNlY29uZF90eXBlKCk7CisgIH0KKyAgcmV0dXJuIGl0LT5zZWNvbmQ7Cit9CisKKy8vIFNhbWUgYXMgYWJvdmUsIGV4Y2VwdCB0YWtlcyBub24tY29uc3QgcmVmZXJlbmNlIHRvIGNvbGxlY3Rpb24uCisvLworLy8gVGhpcyBmdW5jdGlvbiBpcyBuZWVkZWQgZm9yIGNvbnRhaW5lcnMgdGhhdCBwcm9wYWdhdGUgY29uc3RuZXNzIHRvIHRoZQorLy8gcG9pbnRlZSwgc3VjaCBhcyBib29zdDo6cHRyX21hcC4KK3RlbXBsYXRlIDxjbGFzcyBDb2xsZWN0aW9uPgordHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6c2Vjb25kX3R5cGUKK0ZpbmRQdHJPck51bGwoQ29sbGVjdGlvbiYgY29sbGVjdGlvbiwgIC8vIE5PTElOVAorICAgICAgICAgICAgICBjb25zdCB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpmaXJzdF90eXBlJiBrZXkpIHsKKyAgdHlwZW5hbWUgQ29sbGVjdGlvbjo6aXRlcmF0b3IgaXQgPSBjb2xsZWN0aW9uLmZpbmQoa2V5KTsKKyAgaWYgKGl0ID09IGNvbGxlY3Rpb24uZW5kKCkpIHsKKyAgICByZXR1cm4gdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6c2Vjb25kX3R5cGUoKTsKKyAgfQorICByZXR1cm4gaXQtPnNlY29uZDsKK30KKworLy8gRmluZHMgdGhlIHBvaW50ZXIgdmFsdWUgYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBrZXkgaW4gYSBtYXAgd2hvc2UgdmFsdWVzCisvLyBhcmUgbGlua2VkX3B0cnMuIFJldHVybnMgTlVMTCBpZiBrZXkgaXMgbm90IGZvdW5kLgordGVtcGxhdGUgPGNsYXNzIENvbGxlY3Rpb24+Cit0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpzZWNvbmRfdHlwZTo6ZWxlbWVudF90eXBlKgorRmluZExpbmtlZFB0ck9yTnVsbChjb25zdCBDb2xsZWN0aW9uJiBjb2xsZWN0aW9uLAorICAgICAgICAgICAgICAgICAgICBjb25zdCB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpmaXJzdF90eXBlJiBrZXkpIHsKKyAgdHlwZW5hbWUgQ29sbGVjdGlvbjo6Y29uc3RfaXRlcmF0b3IgaXQgPSBjb2xsZWN0aW9uLmZpbmQoa2V5KTsKKyAgaWYgKGl0ID09IGNvbGxlY3Rpb24uZW5kKCkpIHsKKyAgICByZXR1cm4gMDsKKyAgfQorICAvLyBTaW5jZSBsaW5rZWRfcHRyOjpnZXQoKSBpcyBhIGNvbnN0IG1lbWJlciByZXR1cm5pbmcgYSBub24gY29uc3QsCisgIC8vIHdlIGRvIG5vdCBuZWVkIGEgdmVyc2lvbiBvZiB0aGlzIGZ1bmN0aW9uIHRha2luZyBhIG5vbiBjb25zdCBjb2xsZWN0aW9uLgorICByZXR1cm4gaXQtPnNlY29uZC5nZXQoKTsKK30KKworLy8gU2FtZSBhcyBhYm92ZSwgYnV0IGRpZXMgaWYgdGhlIGtleSBpcyBub3QgZm91bmQuCit0ZW1wbGF0ZSA8Y2xhc3MgQ29sbGVjdGlvbj4KK3R5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OnNlY29uZF90eXBlOjplbGVtZW50X3R5cGUmCitGaW5kTGlua2VkUHRyT3JEaWUoY29uc3QgQ29sbGVjdGlvbiYgY29sbGVjdGlvbiwKKyAgICAgICAgICAgICAgICAgICBjb25zdCB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpmaXJzdF90eXBlJiBrZXkpIHsKKyAgdHlwZW5hbWUgQ29sbGVjdGlvbjo6Y29uc3RfaXRlcmF0b3IgaXQgPSBjb2xsZWN0aW9uLmZpbmQoa2V5KTsKKyAgQ0hFQ0soaXQgIT0gY29sbGVjdGlvbi5lbmQoKSkgPDwgICJrZXkgbm90IGZvdW5kOiAiIDw8IGtleTsKKyAgLy8gU2luY2UgbGlua2VkX3B0cjo6b3BlcmF0b3IqKCkgaXMgYSBjb25zdCBtZW1iZXIgcmV0dXJuaW5nIGEgbm9uIGNvbnN0LAorICAvLyB3ZSBkbyBub3QgbmVlZCBhIHZlcnNpb24gb2YgdGhpcyBmdW5jdGlvbiB0YWtpbmcgYSBub24gY29uc3QgY29sbGVjdGlvbi4KKyAgcmV0dXJuICppdC0+c2Vjb25kOworfQorCisvLyBGaW5kcyB0aGUgdmFsdWUgYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBrZXkgYW5kIGNvcGllcyBpdCB0byAqdmFsdWUgKGlmIG5vdAorLy8gTlVMTCkuIFJldHVybnMgZmFsc2UgaWYgdGhlIGtleSB3YXMgbm90IGZvdW5kLCB0cnVlIG90aGVyd2lzZS4KK3RlbXBsYXRlIDxjbGFzcyBDb2xsZWN0aW9uLCBjbGFzcyBLZXksIGNsYXNzIFZhbHVlPgorYm9vbCBGaW5kQ29weShjb25zdCBDb2xsZWN0aW9uJiBjb2xsZWN0aW9uLAorICAgICAgICAgICAgICBjb25zdCBLZXkmIGtleSwKKyAgICAgICAgICAgICAgVmFsdWUqIGNvbnN0IHZhbHVlKSB7CisgIHR5cGVuYW1lIENvbGxlY3Rpb246OmNvbnN0X2l0ZXJhdG9yIGl0ID0gY29sbGVjdGlvbi5maW5kKGtleSk7CisgIGlmIChpdCA9PSBjb2xsZWN0aW9uLmVuZCgpKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIGlmICh2YWx1ZSkgeworICAgICp2YWx1ZSA9IGl0LT5zZWNvbmQ7CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKKy8vCisvLyBDb250YWlucyooKQorLy8KKworLy8gUmV0dXJucyB0cnVlIGlmIGFuZCBvbmx5IGlmIHRoZSBnaXZlbiBjb2xsZWN0aW9uIGNvbnRhaW5zIHRoZSBnaXZlbiBrZXkuCit0ZW1wbGF0ZSA8Y2xhc3MgQ29sbGVjdGlvbiwgY2xhc3MgS2V5PgorYm9vbCBDb250YWluc0tleShjb25zdCBDb2xsZWN0aW9uJiBjb2xsZWN0aW9uLCBjb25zdCBLZXkmIGtleSkgeworICByZXR1cm4gY29sbGVjdGlvbi5maW5kKGtleSkgIT0gY29sbGVjdGlvbi5lbmQoKTsKK30KKworLy8gUmV0dXJucyB0cnVlIGlmIGFuZCBvbmx5IGlmIHRoZSBnaXZlbiBjb2xsZWN0aW9uIGNvbnRhaW5zIHRoZSBnaXZlbiBrZXktdmFsdWUKKy8vIHBhaXIuCit0ZW1wbGF0ZSA8Y2xhc3MgQ29sbGVjdGlvbiwgY2xhc3MgS2V5LCBjbGFzcyBWYWx1ZT4KK2Jvb2wgQ29udGFpbnNLZXlWYWx1ZVBhaXIoY29uc3QgQ29sbGVjdGlvbiYgY29sbGVjdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgS2V5JiBrZXksCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFZhbHVlJiB2YWx1ZSkgeworICB0eXBlZGVmIHR5cGVuYW1lIENvbGxlY3Rpb246OmNvbnN0X2l0ZXJhdG9yIGNvbnN0X2l0ZXJhdG9yOworICBzdGQ6OnBhaXI8Y29uc3RfaXRlcmF0b3IsIGNvbnN0X2l0ZXJhdG9yPiByYW5nZSA9IGNvbGxlY3Rpb24uZXF1YWxfcmFuZ2Uoa2V5KTsKKyAgZm9yIChjb25zdF9pdGVyYXRvciBpdCA9IHJhbmdlLmZpcnN0OyBpdCAhPSByYW5nZS5zZWNvbmQ7ICsraXQpIHsKKyAgICBpZiAoaXQtPnNlY29uZCA9PSB2YWx1ZSkgeworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICB9CisgIHJldHVybiBmYWxzZTsKK30KKworLy8KKy8vIEluc2VydCooKQorLy8KKworLy8gSW5zZXJ0cyB0aGUgZ2l2ZW4ga2V5LXZhbHVlIHBhaXIgaW50byB0aGUgY29sbGVjdGlvbi4gUmV0dXJucyB0cnVlIGlmIGFuZAorLy8gb25seSBpZiB0aGUga2V5IGZyb20gdGhlIGdpdmVuIHBhaXIgZGlkbid0IHByZXZpb3VzbHkgZXhpc3QuIE90aGVyd2lzZSwgdGhlCisvLyB2YWx1ZSBpbiB0aGUgbWFwIGlzIHJlcGxhY2VkIHdpdGggdGhlIHZhbHVlIGZyb20gdGhlIGdpdmVuIHBhaXIuCit0ZW1wbGF0ZSA8Y2xhc3MgQ29sbGVjdGlvbj4KK2Jvb2wgSW5zZXJ0T3JVcGRhdGUoQ29sbGVjdGlvbiogY29uc3QgY29sbGVjdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgY29uc3QgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZSYgdnQpIHsKKyAgc3RkOjpwYWlyPHR5cGVuYW1lIENvbGxlY3Rpb246Oml0ZXJhdG9yLCBib29sPiByZXQgPSBjb2xsZWN0aW9uLT5pbnNlcnQodnQpOworICBpZiAoIXJldC5zZWNvbmQpIHsKKyAgICAvLyB1cGRhdGUKKyAgICByZXQuZmlyc3QtPnNlY29uZCA9IHZ0LnNlY29uZDsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKKy8vIFNhbWUgYXMgYWJvdmUsIGV4Y2VwdCB0aGF0IHRoZSBrZXkgYW5kIHZhbHVlIGFyZSBwYXNzZWQgc2VwYXJhdGVseS4KK3RlbXBsYXRlIDxjbGFzcyBDb2xsZWN0aW9uPgorYm9vbCBJbnNlcnRPclVwZGF0ZShDb2xsZWN0aW9uKiBjb25zdCBjb2xsZWN0aW9uLAorICAgICAgICAgICAgICAgICAgICBjb25zdCB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpmaXJzdF90eXBlJiBrZXksCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OnNlY29uZF90eXBlJiB2YWx1ZSkgeworICByZXR1cm4gSW5zZXJ0T3JVcGRhdGUoCisgICAgICBjb2xsZWN0aW9uLCB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlKGtleSwgdmFsdWUpKTsKK30KKworLy8gSW5zZXJ0cy91cGRhdGVzIGFsbCB0aGUga2V5LXZhbHVlIHBhaXJzIGZyb20gdGhlIHJhbmdlIGRlZmluZWQgYnkgdGhlCisvLyBpdGVyYXRvcnMgImZpcnN0IiBhbmQgImxhc3QiIGludG8gdGhlIGdpdmVuIGNvbGxlY3Rpb24uCit0ZW1wbGF0ZSA8Y2xhc3MgQ29sbGVjdGlvbiwgY2xhc3MgSW5wdXRJdGVyYXRvcj4KK3ZvaWQgSW5zZXJ0T3JVcGRhdGVNYW55KENvbGxlY3Rpb24qIGNvbnN0IGNvbGxlY3Rpb24sCisgICAgICAgICAgICAgICAgICAgICAgICBJbnB1dEl0ZXJhdG9yIGZpcnN0LCBJbnB1dEl0ZXJhdG9yIGxhc3QpIHsKKyAgZm9yICg7IGZpcnN0ICE9IGxhc3Q7ICsrZmlyc3QpIHsKKyAgICBJbnNlcnRPclVwZGF0ZShjb2xsZWN0aW9uLCAqZmlyc3QpOworICB9Cit9CisKKy8vIENoYW5nZSB0aGUgdmFsdWUgYXNzb2NpYXRlZCB3aXRoIGEgcGFydGljdWxhciBrZXkgaW4gYSBtYXAgb3IgaGFzaF9tYXAKKy8vIG9mIHRoZSBmb3JtIG1hcDxLZXksIFZhbHVlKj4gd2hpY2ggb3ducyB0aGUgb2JqZWN0cyBwb2ludGVkIHRvIGJ5IHRoZQorLy8gdmFsdWUgcG9pbnRlcnMuICBJZiB0aGVyZSB3YXMgYW4gZXhpc3RpbmcgdmFsdWUgZm9yIHRoZSBrZXksIGl0IGlzIGRlbGV0ZWQuCisvLyBUcnVlIGluZGljYXRlcyBhbiBpbnNlcnQgdG9vayBwbGFjZSwgZmFsc2UgaW5kaWNhdGVzIGFuIHVwZGF0ZSArIGRlbGV0ZS4KK3RlbXBsYXRlIDxjbGFzcyBDb2xsZWN0aW9uPgorYm9vbCBJbnNlcnRBbmREZWxldGVFeGlzdGluZygKKyAgICBDb2xsZWN0aW9uKiBjb25zdCBjb2xsZWN0aW9uLAorICAgIGNvbnN0IHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OmZpcnN0X3R5cGUmIGtleSwKKyAgICBjb25zdCB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpzZWNvbmRfdHlwZSYgdmFsdWUpIHsKKyAgc3RkOjpwYWlyPHR5cGVuYW1lIENvbGxlY3Rpb246Oml0ZXJhdG9yLCBib29sPiByZXQgPQorICAgICAgY29sbGVjdGlvbi0+aW5zZXJ0KHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGUoa2V5LCB2YWx1ZSkpOworICBpZiAoIXJldC5zZWNvbmQpIHsKKyAgICBkZWxldGUgcmV0LmZpcnN0LT5zZWNvbmQ7CisgICAgcmV0LmZpcnN0LT5zZWNvbmQgPSB2YWx1ZTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKKy8vIEluc2VydHMgdGhlIGdpdmVuIGtleSBhbmQgdmFsdWUgaW50byB0aGUgZ2l2ZW4gY29sbGVjdGlvbiBpZiBhbmQgb25seSBpZiB0aGUKKy8vIGdpdmVuIGtleSBkaWQgTk9UIGFscmVhZHkgZXhpc3QgaW4gdGhlIGNvbGxlY3Rpb24uIElmIHRoZSBrZXkgcHJldmlvdXNseQorLy8gZXhpc3RlZCBpbiB0aGUgY29sbGVjdGlvbiwgdGhlIHZhbHVlIGlzIG5vdCBjaGFuZ2VkLiBSZXR1cm5zIHRydWUgaWYgdGhlCisvLyBrZXktdmFsdWUgcGFpciB3YXMgaW5zZXJ0ZWQ7IHJldHVybnMgZmFsc2UgaWYgdGhlIGtleSB3YXMgYWxyZWFkeSBwcmVzZW50LgordGVtcGxhdGUgPGNsYXNzIENvbGxlY3Rpb24+Citib29sIEluc2VydElmTm90UHJlc2VudChDb2xsZWN0aW9uKiBjb25zdCBjb2xsZWN0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZSYgdnQpIHsKKyAgcmV0dXJuIGNvbGxlY3Rpb24tPmluc2VydCh2dCkuc2Vjb25kOworfQorCisvLyBTYW1lIGFzIGFib3ZlIGV4Y2VwdCB0aGUga2V5IGFuZCB2YWx1ZSBhcmUgcGFzc2VkIHNlcGFyYXRlbHkuCit0ZW1wbGF0ZSA8Y2xhc3MgQ29sbGVjdGlvbj4KK2Jvb2wgSW5zZXJ0SWZOb3RQcmVzZW50KAorICAgIENvbGxlY3Rpb24qIGNvbnN0IGNvbGxlY3Rpb24sCisgICAgY29uc3QgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6Zmlyc3RfdHlwZSYga2V5LAorICAgIGNvbnN0IHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OnNlY29uZF90eXBlJiB2YWx1ZSkgeworICByZXR1cm4gSW5zZXJ0SWZOb3RQcmVzZW50KAorICAgICAgY29sbGVjdGlvbiwgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZShrZXksIHZhbHVlKSk7Cit9CisKKy8vIFNhbWUgYXMgYWJvdmUgZXhjZXB0IGRpZXMgaWYgdGhlIGtleSBhbHJlYWR5IGV4aXN0cyBpbiB0aGUgY29sbGVjdGlvbi4KK3RlbXBsYXRlIDxjbGFzcyBDb2xsZWN0aW9uPgordm9pZCBJbnNlcnRPckRpZShDb2xsZWN0aW9uKiBjb25zdCBjb2xsZWN0aW9uLAorICAgICAgICAgICAgICAgICBjb25zdCB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlJiB2YWx1ZSkgeworICBDSEVDSyhJbnNlcnRJZk5vdFByZXNlbnQoY29sbGVjdGlvbiwgdmFsdWUpKSA8PCAiZHVwbGljYXRlIHZhbHVlOiAiIDw8IHZhbHVlOworfQorCisvLyBTYW1lIGFzIGFib3ZlIGV4Y2VwdCBkb2Vzbid0IGxvZyB0aGUgdmFsdWUgb24gZXJyb3IuCit0ZW1wbGF0ZSA8Y2xhc3MgQ29sbGVjdGlvbj4KK3ZvaWQgSW5zZXJ0T3JEaWVOb1ByaW50KENvbGxlY3Rpb24qIGNvbnN0IGNvbGxlY3Rpb24sCisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlJiB2YWx1ZSkgeworICBDSEVDSyhJbnNlcnRJZk5vdFByZXNlbnQoY29sbGVjdGlvbiwgdmFsdWUpKSA8PCAiZHVwbGljYXRlIHZhbHVlLiI7Cit9CisKKy8vIEluc2VydHMgdGhlIGtleS12YWx1ZSBwYWlyIGludG8gdGhlIGNvbGxlY3Rpb24uIERpZXMgaWYga2V5IHdhcyBhbHJlYWR5CisvLyBwcmVzZW50LgordGVtcGxhdGUgPGNsYXNzIENvbGxlY3Rpb24+Cit2b2lkIEluc2VydE9yRGllKENvbGxlY3Rpb24qIGNvbnN0IGNvbGxlY3Rpb24sCisgICAgICAgICAgICAgICAgIGNvbnN0IHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OmZpcnN0X3R5cGUmIGtleSwKKyAgICAgICAgICAgICAgICAgY29uc3QgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6c2Vjb25kX3R5cGUmIGRhdGEpIHsKKyAgR09PR0xFX0NIRUNLKEluc2VydElmTm90UHJlc2VudChjb2xsZWN0aW9uLCBrZXksIGRhdGEpKQorICAgICAgPDwgImR1cGxpY2F0ZSBrZXk6ICIgPDwga2V5OworfQorCisvLyBTYW1lIGFzIGFib3ZlIGV4Y2VwdCBkb2Vzbid0IGxvZyB0aGUga2V5IG9uIGVycm9yLgordGVtcGxhdGUgPGNsYXNzIENvbGxlY3Rpb24+Cit2b2lkIEluc2VydE9yRGllTm9QcmludCgKKyAgICBDb2xsZWN0aW9uKiBjb25zdCBjb2xsZWN0aW9uLAorICAgIGNvbnN0IHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OmZpcnN0X3R5cGUmIGtleSwKKyAgICBjb25zdCB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpzZWNvbmRfdHlwZSYgZGF0YSkgeworICBHT09HTEVfQ0hFQ0soSW5zZXJ0SWZOb3RQcmVzZW50KGNvbGxlY3Rpb24sIGtleSwgZGF0YSkpIDw8ICJkdXBsaWNhdGUga2V5LiI7Cit9CisKKy8vIEluc2VydHMgYSBuZXcga2V5IGFuZCBkZWZhdWx0LWluaXRpYWxpemVkIHZhbHVlLiBEaWVzIGlmIHRoZSBrZXkgd2FzIGFscmVhZHkKKy8vIHByZXNlbnQuIFJldHVybnMgYSByZWZlcmVuY2UgdG8gdGhlIHZhbHVlLiBFeGFtcGxlIHVzYWdlOgorLy8KKy8vIG1hcDxpbnQsIFNvbWVQcm90bz4gbTsKKy8vIFNvbWVQcm90byYgcHJvdG8gPSBJbnNlcnRLZXlPckRpZSgmbSwgMyk7CisvLyBwcm90by5zZXRfZmllbGQoImZvbyIpOwordGVtcGxhdGUgPGNsYXNzIENvbGxlY3Rpb24+Cit0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpzZWNvbmRfdHlwZSYgSW5zZXJ0S2V5T3JEaWUoCisgICAgQ29sbGVjdGlvbiogY29uc3QgY29sbGVjdGlvbiwKKyAgICBjb25zdCB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpmaXJzdF90eXBlJiBrZXkpIHsKKyAgdHlwZWRlZiB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlIHZhbHVlX3R5cGU7CisgIHN0ZDo6cGFpcjx0eXBlbmFtZSBDb2xsZWN0aW9uOjppdGVyYXRvciwgYm9vbD4gcmVzID0KKyAgICAgIGNvbGxlY3Rpb24tPmluc2VydCh2YWx1ZV90eXBlKGtleSwgdHlwZW5hbWUgdmFsdWVfdHlwZTo6c2Vjb25kX3R5cGUoKSkpOworICBHT09HTEVfQ0hFQ0socmVzLnNlY29uZCkgPDwgImR1cGxpY2F0ZSBrZXk6ICIgPDwga2V5OworICByZXR1cm4gcmVzLmZpcnN0LT5zZWNvbmQ7Cit9CisKKy8vCisvLyBMb29rdXAqKCkKKy8vCisKKy8vIExvb2tzIHVwIGEgZ2l2ZW4ga2V5IGFuZCB2YWx1ZSBwYWlyIGluIGEgY29sbGVjdGlvbiBhbmQgaW5zZXJ0cyB0aGUga2V5LXZhbHVlCisvLyBwYWlyIGlmIGl0J3Mgbm90IGFscmVhZHkgcHJlc2VudC4gUmV0dXJucyBhIHJlZmVyZW5jZSB0byB0aGUgdmFsdWUgYXNzb2NpYXRlZAorLy8gd2l0aCB0aGUga2V5LgordGVtcGxhdGUgPGNsYXNzIENvbGxlY3Rpb24+Cit0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpzZWNvbmRfdHlwZSYKK0xvb2t1cE9ySW5zZXJ0KENvbGxlY3Rpb24qIGNvbnN0IGNvbGxlY3Rpb24sCisgICAgICAgICAgICAgICBjb25zdCB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlJiB2dCkgeworICByZXR1cm4gY29sbGVjdGlvbi0+aW5zZXJ0KHZ0KS5maXJzdC0+c2Vjb25kOworfQorCisvLyBTYW1lIGFzIGFib3ZlIGV4Y2VwdCB0aGUga2V5LXZhbHVlIGFyZSBwYXNzZWQgc2VwYXJhdGVseS4KK3RlbXBsYXRlIDxjbGFzcyBDb2xsZWN0aW9uPgordHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6c2Vjb25kX3R5cGUmCitMb29rdXBPckluc2VydChDb2xsZWN0aW9uKiBjb25zdCBjb2xsZWN0aW9uLAorICAgICAgICAgICAgICAgY29uc3QgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6Zmlyc3RfdHlwZSYga2V5LAorICAgICAgICAgICAgICAgY29uc3QgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6c2Vjb25kX3R5cGUmIHZhbHVlKSB7CisgIHJldHVybiBMb29rdXBPckluc2VydCgKKyAgICAgIGNvbGxlY3Rpb24sIHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGUoa2V5LCB2YWx1ZSkpOworfQorCisvLyBDb3VudHMgdGhlIG51bWJlciBvZiBlcXVpdmFsZW50IGVsZW1lbnRzIGluIHRoZSBnaXZlbiAic2VxdWVuY2UiLCBhbmQgc3RvcmVzCisvLyB0aGUgcmVzdWx0cyBpbiAiY291bnRfbWFwIiB3aXRoIGVsZW1lbnQgYXMgdGhlIGtleSBhbmQgY291bnQgYXMgdGhlIHZhbHVlLgorLy8KKy8vIEV4YW1wbGU6CisvLyAgIHZlY3RvcjxzdHJpbmc+IHYgPSB7ImEiLCAiYiIsICJjIiwgImEiLCAiYiJ9OworLy8gICBtYXA8c3RyaW5nLCBpbnQ+IG07CisvLyAgIEFkZFRva2VuQ291bnRzKHYsIDEsICZtKTsKKy8vICAgYXNzZXJ0KG1bImEiXSA9PSAyKTsKKy8vICAgYXNzZXJ0KG1bImIiXSA9PSAyKTsKKy8vICAgYXNzZXJ0KG1bImMiXSA9PSAxKTsKK3RlbXBsYXRlIDx0eXBlbmFtZSBTZXF1ZW5jZSwgdHlwZW5hbWUgQ29sbGVjdGlvbj4KK3ZvaWQgQWRkVG9rZW5Db3VudHMoCisgICAgY29uc3QgU2VxdWVuY2UmIHNlcXVlbmNlLAorICAgIGNvbnN0IHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OnNlY29uZF90eXBlJiBpbmNyZW1lbnQsCisgICAgQ29sbGVjdGlvbiogY29uc3QgY291bnRfbWFwKSB7CisgIGZvciAodHlwZW5hbWUgU2VxdWVuY2U6OmNvbnN0X2l0ZXJhdG9yIGl0ID0gc2VxdWVuY2UuYmVnaW4oKTsKKyAgICAgICBpdCAhPSBzZXF1ZW5jZS5lbmQoKTsgKytpdCkgeworICAgIHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OnNlY29uZF90eXBlJiB2YWx1ZSA9CisgICAgICAgIExvb2t1cE9ySW5zZXJ0KGNvdW50X21hcCwgKml0LAorICAgICAgICAgICAgICAgICAgICAgICB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpzZWNvbmRfdHlwZSgpKTsKKyAgICB2YWx1ZSArPSBpbmNyZW1lbnQ7CisgIH0KK30KKworLy8gUmV0dXJucyBhIHJlZmVyZW5jZSB0byB0aGUgdmFsdWUgYXNzb2NpYXRlZCB3aXRoIGtleS4gSWYgbm90IGZvdW5kLCBhIHZhbHVlCisvLyBpcyBkZWZhdWx0IGNvbnN0cnVjdGVkIG9uIHRoZSBoZWFwIGFuZCBhZGRlZCB0byB0aGUgbWFwLgorLy8KKy8vIFRoaXMgZnVuY3Rpb24gaXMgdXNlZnVsIGZvciBjb250YWluZXJzIG9mIHRoZSBmb3JtIG1hcDxLZXksIFZhbHVlKj4sIHdoZXJlCisvLyBpbnNlcnRpbmcgYSBuZXcga2V5LCB2YWx1ZSBwYWlyIGludm9sdmVzIGNvbnN0cnVjdGluZyBhIG5ldyBoZWFwLWFsbG9jYXRlZAorLy8gVmFsdWUsIGFuZCBzdG9yaW5nIGEgcG9pbnRlciB0byB0aGF0IGluIHRoZSBjb2xsZWN0aW9uLgordGVtcGxhdGUgPGNsYXNzIENvbGxlY3Rpb24+Cit0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpzZWNvbmRfdHlwZSYKK0xvb2t1cE9ySW5zZXJ0TmV3KENvbGxlY3Rpb24qIGNvbnN0IGNvbGxlY3Rpb24sCisgICAgICAgICAgICAgICAgICBjb25zdCB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpmaXJzdF90eXBlJiBrZXkpIHsKKyAgdHlwZWRlZiB0eXBlbmFtZSBzdGQ6Oml0ZXJhdG9yX3RyYWl0czwKKyAgICB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpzZWNvbmRfdHlwZT46OnZhbHVlX3R5cGUgRWxlbWVudDsKKyAgc3RkOjpwYWlyPHR5cGVuYW1lIENvbGxlY3Rpb246Oml0ZXJhdG9yLCBib29sPiByZXQgPQorICAgICAgY29sbGVjdGlvbi0+aW5zZXJ0KHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGUoCisgICAgICAgICAga2V5LAorICAgICAgICAgIHN0YXRpY19jYXN0PHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OnNlY29uZF90eXBlPihOVUxMKSkpOworICBpZiAocmV0LnNlY29uZCkgeworICAgIHJldC5maXJzdC0+c2Vjb25kID0gbmV3IEVsZW1lbnQoKTsKKyAgfQorICByZXR1cm4gcmV0LmZpcnN0LT5zZWNvbmQ7Cit9CisKKy8vIFNhbWUgYXMgYWJvdmUgYnV0IGNvbnN0cnVjdHMgdGhlIHZhbHVlIHVzaW5nIHRoZSBzaW5nbGUtYXJndW1lbnQgY29uc3RydWN0b3IKKy8vIGFuZCB0aGUgZ2l2ZW4gImFyZyIuCit0ZW1wbGF0ZSA8Y2xhc3MgQ29sbGVjdGlvbiwgY2xhc3MgQXJnPgordHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6c2Vjb25kX3R5cGUmCitMb29rdXBPckluc2VydE5ldyhDb2xsZWN0aW9uKiBjb25zdCBjb2xsZWN0aW9uLAorICAgICAgICAgICAgICAgICAgY29uc3QgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6Zmlyc3RfdHlwZSYga2V5LAorICAgICAgICAgICAgICAgICAgY29uc3QgQXJnJiBhcmcpIHsKKyAgdHlwZWRlZiB0eXBlbmFtZSBzdGQ6Oml0ZXJhdG9yX3RyYWl0czwKKyAgICB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpzZWNvbmRfdHlwZT46OnZhbHVlX3R5cGUgRWxlbWVudDsKKyAgc3RkOjpwYWlyPHR5cGVuYW1lIENvbGxlY3Rpb246Oml0ZXJhdG9yLCBib29sPiByZXQgPQorICAgICAgY29sbGVjdGlvbi0+aW5zZXJ0KHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGUoCisgICAgICAgICAga2V5LAorICAgICAgICAgIHN0YXRpY19jYXN0PHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OnNlY29uZF90eXBlPihOVUxMKSkpOworICBpZiAocmV0LnNlY29uZCkgeworICAgIHJldC5maXJzdC0+c2Vjb25kID0gbmV3IEVsZW1lbnQoYXJnKTsKKyAgfQorICByZXR1cm4gcmV0LmZpcnN0LT5zZWNvbmQ7Cit9CisKKy8vIExvb2t1cCBvZiBsaW5rZWQvc2hhcmVkIHBvaW50ZXJzIGlzIHVzZWQgaW4gdHdvIHNjZW5hcmlvczoKKy8vCisvLyBVc2UgTG9va3VwT3JJbnNlcnROZXdMaW5rZWRQdHIgaWYgdGhlIGNvbnRhaW5lciBvd25zIHRoZSBlbGVtZW50cy4KKy8vIEluIHRoaXMgY2FzZSBpdCBpcyBmaW5lIHdvcmtpbmcgd2l0aCB0aGUgcmF3IHBvaW50ZXIgYXMgbG9uZyBhcyBpdCBpcworLy8gZ3VhcmFudGVlZCB0aGF0IG5vIG90aGVyIHRocmVhZCBjYW4gZGVsZXRlL3VwZGF0ZSBhbiBhY2Nlc3NlZCBlbGVtZW50LgorLy8gQSBtdXRleCB3aWxsIG5lZWQgdG8gbG9jayB0aGUgY29udGFpbmVyIG9wZXJhdGlvbiBhcyB3ZWxsIGFzIHRoZSB1c2UKKy8vIG9mIHRoZSByZXR1cm5lZCBlbGVtZW50cy4gRmluZGluZyBhbiBlbGVtZW50IG1heSBiZSBwZXJmb3JtZWQgdXNpbmcKKy8vIEZpbmRMaW5rZWRQdHIqKCkuCisvLworLy8gVXNlIExvb2t1cE9ySW5zZXJ0TmV3U2hhcmVkUHRyIGlmIHRoZSBjb250YWluZXIgZG9lcyBub3Qgb3duIHRoZSBlbGVtZW50cworLy8gZm9yIHRoZWlyIHdob2xlIGxpZmV0aW1lLiBUaGlzIGlzIHR5cGljYWxseSB0aGUgY2FzZSB3aGVuIGEgcmVhZGVyIGFsbG93cworLy8gcGFyYWxsZWwgdXBkYXRlcyB0byB0aGUgY29udGFpbmVyLiBJbiB0aGlzIGNhc2UgYSBNdXRleCBvbmx5IG5lZWRzIHRvIGxvY2sKKy8vIGNvbnRhaW5lciBvcGVyYXRpb25zLCBidXQgYWxsIGVsZW1lbnQgb3BlcmF0aW9ucyBtdXN0IGJlIHBlcmZvcm1lZCBvbiB0aGUKKy8vIHNoYXJlZCBwb2ludGVyLiBGaW5kaW5nIGFuIGVsZW1lbnQgbXVzdCBiZSBwZXJmb3JtZWQgdXNpbmcgRmluZFB0ciooKSBhbmQKKy8vIGNhbm5vdCBiZSBkb25lIHdpdGggRmluZExpbmtlZFB0ciooKSBldmVuIHRob3VnaCBpdCBjb21waWxlcy4KKworLy8gTG9va3VwIGEga2V5IGluIGEgbWFwIG9yIGhhc2hfbWFwIHdob3NlIHZhbHVlcyBhcmUgbGlua2VkX3B0cnMuICBJZiBpdCBpcworLy8gbWlzc2luZywgc2V0IGNvbGxlY3Rpb25ba2V5XS5yZXNldChuZXcgVmFsdWU6OmVsZW1lbnRfdHlwZSkgYW5kIHJldHVybiB0aGF0LgorLy8gVmFsdWU6OmVsZW1lbnRfdHlwZSBtdXN0IGJlIGRlZmF1bHQgY29uc3RydWN0YWJsZS4KK3RlbXBsYXRlIDxjbGFzcyBDb2xsZWN0aW9uPgordHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6c2Vjb25kX3R5cGU6OmVsZW1lbnRfdHlwZSoKK0xvb2t1cE9ySW5zZXJ0TmV3TGlua2VkUHRyKAorICAgIENvbGxlY3Rpb24qIGNvbnN0IGNvbGxlY3Rpb24sCisgICAgY29uc3QgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6Zmlyc3RfdHlwZSYga2V5KSB7CisgIHR5cGVkZWYgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6c2Vjb25kX3R5cGUgVmFsdWU7CisgIHN0ZDo6cGFpcjx0eXBlbmFtZSBDb2xsZWN0aW9uOjppdGVyYXRvciwgYm9vbD4gcmV0ID0KKyAgICAgIGNvbGxlY3Rpb24tPmluc2VydCh0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlKGtleSwgVmFsdWUoKSkpOworICBpZiAocmV0LnNlY29uZCkgeworICAgIHJldC5maXJzdC0+c2Vjb25kLnJlc2V0KG5ldyB0eXBlbmFtZSBWYWx1ZTo6ZWxlbWVudF90eXBlKTsKKyAgfQorICByZXR1cm4gcmV0LmZpcnN0LT5zZWNvbmQuZ2V0KCk7Cit9CisKKy8vIEEgdmFyaWFudCBvZiBMb29rdXBPckluc2VydE5ld0xpbmtlZFB0ciB3aGVyZSB0aGUgdmFsdWUgaXMgY29uc3RydWN0ZWQgdXNpbmcKKy8vIGEgc2luZ2xlLXBhcmFtZXRlciBjb25zdHJ1Y3Rvci4gIE5vdGU6IHRoZSBjb25zdHJ1Y3RvciBhcmd1bWVudCBpcyBjb21wdXRlZAorLy8gZXZlbiBpZiBpdCB3aWxsIG5vdCBiZSB1c2VkLCBzbyBvbmx5IHZhbHVlcyBjaGVhcCB0byBjb21wdXRlIHNob3VsZCBiZSBwYXNzZWQKKy8vIGhlcmUuICBPbiB0aGUgb3RoZXIgaGFuZCBpdCBkb2VzIG5vdCBtYXR0ZXIgaG93IGV4cGVuc2l2ZSB0aGUgY29uc3RydWN0aW9uIG9mCisvLyB0aGUgYWN0dWFsIHN0b3JlZCB2YWx1ZSBpcywgYXMgdGhhdCBvbmx5IG9jY3VycyBpZiBuZWNlc3NhcnkuCit0ZW1wbGF0ZSA8Y2xhc3MgQ29sbGVjdGlvbiwgY2xhc3MgQXJnPgordHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6c2Vjb25kX3R5cGU6OmVsZW1lbnRfdHlwZSoKK0xvb2t1cE9ySW5zZXJ0TmV3TGlua2VkUHRyKAorICAgIENvbGxlY3Rpb24qIGNvbnN0IGNvbGxlY3Rpb24sCisgICAgY29uc3QgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6Zmlyc3RfdHlwZSYga2V5LAorICAgIGNvbnN0IEFyZyYgYXJnKSB7CisgIHR5cGVkZWYgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6c2Vjb25kX3R5cGUgVmFsdWU7CisgIHN0ZDo6cGFpcjx0eXBlbmFtZSBDb2xsZWN0aW9uOjppdGVyYXRvciwgYm9vbD4gcmV0ID0KKyAgICAgIGNvbGxlY3Rpb24tPmluc2VydCh0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlKGtleSwgVmFsdWUoKSkpOworICBpZiAocmV0LnNlY29uZCkgeworICAgIHJldC5maXJzdC0+c2Vjb25kLnJlc2V0KG5ldyB0eXBlbmFtZSBWYWx1ZTo6ZWxlbWVudF90eXBlKGFyZykpOworICB9CisgIHJldHVybiByZXQuZmlyc3QtPnNlY29uZC5nZXQoKTsKK30KKworLy8gTG9va3VwIGEga2V5IGluIGEgbWFwIG9yIGhhc2hfbWFwIHdob3NlIHZhbHVlcyBhcmUgc2hhcmVkX3B0cnMuICBJZiBpdCBpcworLy8gbWlzc2luZywgc2V0IGNvbGxlY3Rpb25ba2V5XS5yZXNldChuZXcgVmFsdWU6OmVsZW1lbnRfdHlwZSkuIFVubGlrZQorLy8gTG9va3VwT3JJbnNlcnROZXdMaW5rZWRQdHIsIHRoaXMgZnVuY3Rpb24gcmV0dXJucyB0aGUgc2hhcmVkX3B0ciBpbnN0ZWFkIG9mCisvLyB0aGUgcmF3IHBvaW50ZXIuIFZhbHVlOjplbGVtZW50X3R5cGUgbXVzdCBiZSBkZWZhdWx0IGNvbnN0cnVjdGFibGUuCit0ZW1wbGF0ZSA8Y2xhc3MgQ29sbGVjdGlvbj4KK3R5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OnNlY29uZF90eXBlJgorTG9va3VwT3JJbnNlcnROZXdTaGFyZWRQdHIoCisgICAgQ29sbGVjdGlvbiogY29uc3QgY29sbGVjdGlvbiwKKyAgICBjb25zdCB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpmaXJzdF90eXBlJiBrZXkpIHsKKyAgdHlwZWRlZiB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpzZWNvbmRfdHlwZSBTaGFyZWRQdHI7CisgIHR5cGVkZWYgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6c2Vjb25kX3R5cGU6OmVsZW1lbnRfdHlwZSBFbGVtZW50OworICBzdGQ6OnBhaXI8dHlwZW5hbWUgQ29sbGVjdGlvbjo6aXRlcmF0b3IsIGJvb2w+IHJldCA9CisgICAgICBjb2xsZWN0aW9uLT5pbnNlcnQodHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZShrZXksIFNoYXJlZFB0cigpKSk7CisgIGlmIChyZXQuc2Vjb25kKSB7CisgICAgcmV0LmZpcnN0LT5zZWNvbmQucmVzZXQobmV3IEVsZW1lbnQoKSk7CisgIH0KKyAgcmV0dXJuIHJldC5maXJzdC0+c2Vjb25kOworfQorCisvLyBBIHZhcmlhbnQgb2YgTG9va3VwT3JJbnNlcnROZXdTaGFyZWRQdHIgd2hlcmUgdGhlIHZhbHVlIGlzIGNvbnN0cnVjdGVkIHVzaW5nCisvLyBhIHNpbmdsZS1wYXJhbWV0ZXIgY29uc3RydWN0b3IuICBOb3RlOiB0aGUgY29uc3RydWN0b3IgYXJndW1lbnQgaXMgY29tcHV0ZWQKKy8vIGV2ZW4gaWYgaXQgd2lsbCBub3QgYmUgdXNlZCwgc28gb25seSB2YWx1ZXMgY2hlYXAgdG8gY29tcHV0ZSBzaG91bGQgYmUgcGFzc2VkCisvLyBoZXJlLiAgT24gdGhlIG90aGVyIGhhbmQgaXQgZG9lcyBub3QgbWF0dGVyIGhvdyBleHBlbnNpdmUgdGhlIGNvbnN0cnVjdGlvbiBvZgorLy8gdGhlIGFjdHVhbCBzdG9yZWQgdmFsdWUgaXMsIGFzIHRoYXQgb25seSBvY2N1cnMgaWYgbmVjZXNzYXJ5LgordGVtcGxhdGUgPGNsYXNzIENvbGxlY3Rpb24sIGNsYXNzIEFyZz4KK3R5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OnNlY29uZF90eXBlJgorTG9va3VwT3JJbnNlcnROZXdTaGFyZWRQdHIoCisgICAgQ29sbGVjdGlvbiogY29uc3QgY29sbGVjdGlvbiwKKyAgICBjb25zdCB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpmaXJzdF90eXBlJiBrZXksCisgICAgY29uc3QgQXJnJiBhcmcpIHsKKyAgdHlwZWRlZiB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpzZWNvbmRfdHlwZSBTaGFyZWRQdHI7CisgIHR5cGVkZWYgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6c2Vjb25kX3R5cGU6OmVsZW1lbnRfdHlwZSBFbGVtZW50OworICBzdGQ6OnBhaXI8dHlwZW5hbWUgQ29sbGVjdGlvbjo6aXRlcmF0b3IsIGJvb2w+IHJldCA9CisgICAgICBjb2xsZWN0aW9uLT5pbnNlcnQodHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZShrZXksIFNoYXJlZFB0cigpKSk7CisgIGlmIChyZXQuc2Vjb25kKSB7CisgICAgcmV0LmZpcnN0LT5zZWNvbmQucmVzZXQobmV3IEVsZW1lbnQoYXJnKSk7CisgIH0KKyAgcmV0dXJuIHJldC5maXJzdC0+c2Vjb25kOworfQorCisvLworLy8gTWlzYyBVdGlsaXR5IEZ1bmN0aW9ucworLy8KKworLy8gVXBkYXRlcyB0aGUgdmFsdWUgYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBrZXkuIElmIHRoZSBrZXkgd2FzIG5vdCBhbHJlYWR5CisvLyBwcmVzZW50LCB0aGVuIHRoZSBrZXktdmFsdWUgcGFpciBhcmUgaW5zZXJ0ZWQgYW5kICJwcmV2aW91cyIgaXMgdW5jaGFuZ2VkLiBJZgorLy8gdGhlIGtleSB3YXMgYWxyZWFkeSBwcmVzZW50LCB0aGUgdmFsdWUgaXMgdXBkYXRlZCBhbmQgIipwcmV2aW91cyIgd2lsbAorLy8gY29udGFpbiBhIGNvcHkgb2YgdGhlIG9sZCB2YWx1ZS4KKy8vCisvLyBJbnNlcnRPclJldHVybkV4aXN0aW5nIGhhcyBjb21wbGVtZW50YXJ5IGJlaGF2aW9yIHRoYXQgcmV0dXJucyB0aGUKKy8vIGFkZHJlc3Mgb2YgYW4gYWxyZWFkeSBleGlzdGluZyB2YWx1ZSwgcmF0aGVyIHRoYW4gdXBkYXRpbmcgaXQuCit0ZW1wbGF0ZSA8Y2xhc3MgQ29sbGVjdGlvbj4KK2Jvb2wgVXBkYXRlUmV0dXJuQ29weShDb2xsZWN0aW9uKiBjb25zdCBjb2xsZWN0aW9uLAorICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OmZpcnN0X3R5cGUmIGtleSwKKyAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpzZWNvbmRfdHlwZSYgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6c2Vjb25kX3R5cGUqIHByZXZpb3VzKSB7CisgIHN0ZDo6cGFpcjx0eXBlbmFtZSBDb2xsZWN0aW9uOjppdGVyYXRvciwgYm9vbD4gcmV0ID0KKyAgICAgIGNvbGxlY3Rpb24tPmluc2VydCh0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlKGtleSwgdmFsdWUpKTsKKyAgaWYgKCFyZXQuc2Vjb25kKSB7CisgICAgLy8gdXBkYXRlCisgICAgaWYgKHByZXZpb3VzKSB7CisgICAgICAqcHJldmlvdXMgPSByZXQuZmlyc3QtPnNlY29uZDsKKyAgICB9CisgICAgcmV0LmZpcnN0LT5zZWNvbmQgPSB2YWx1ZTsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorICByZXR1cm4gZmFsc2U7Cit9CisKKy8vIFNhbWUgYXMgYWJvdmUgZXhjZXB0IHRoYXQgdGhlIGtleSBhbmQgdmFsdWUgYXJlIHBhc3NlZCBhcyBhIHBhaXIuCit0ZW1wbGF0ZSA8Y2xhc3MgQ29sbGVjdGlvbj4KK2Jvb2wgVXBkYXRlUmV0dXJuQ29weShDb2xsZWN0aW9uKiBjb25zdCBjb2xsZWN0aW9uLAorICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGUmIHZ0LAorICAgICAgICAgICAgICAgICAgICAgIHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OnNlY29uZF90eXBlKiBwcmV2aW91cykgeworICBzdGQ6OnBhaXI8dHlwZW5hbWUgQ29sbGVjdGlvbjo6aXRlcmF0b3IsIGJvb2w+IHJldCA9IGNvbGxlY3Rpb24tPmluc2VydCh2dCk7CisgIGlmICghcmV0LnNlY29uZCkgeworICAgIC8vIHVwZGF0ZQorICAgIGlmIChwcmV2aW91cykgeworICAgICAgKnByZXZpb3VzID0gcmV0LmZpcnN0LT5zZWNvbmQ7CisgICAgfQorICAgIHJldC5maXJzdC0+c2Vjb25kID0gdnQuc2Vjb25kOworICAgIHJldHVybiB0cnVlOworICB9CisgIHJldHVybiBmYWxzZTsKK30KKworLy8gVHJpZXMgdG8gaW5zZXJ0IHRoZSBnaXZlbiBrZXktdmFsdWUgcGFpciBpbnRvIHRoZSBjb2xsZWN0aW9uLiBSZXR1cm5zIE5VTEwgaWYKKy8vIHRoZSBpbnNlcnQgc3VjY2VlZHMuIE90aGVyd2lzZSwgcmV0dXJucyBhIHBvaW50ZXIgdG8gdGhlIGV4aXN0aW5nIHZhbHVlLgorLy8KKy8vIFRoaXMgY29tcGxlbWVudHMgVXBkYXRlUmV0dXJuQ29weSBpbiB0aGF0IGl0IGFsbG93cyB0byB1cGRhdGUgb25seSBhZnRlcgorLy8gdmVyaWZ5aW5nIHRoZSBvbGQgdmFsdWUgYW5kIHN0aWxsIGluc2VydCBxdWlja2x5IHdpdGhvdXQgaGF2aW5nIHRvIGxvb2sgdXAKKy8vIHR3aWNlLiBVbmxpa2UgVXBkYXRlUmV0dXJuQ29weSB0aGlzIGFsc28gZG9lcyBub3QgY29tZSB3aXRoIHRoZSBpc3N1ZSBvZiBhbgorLy8gdW5kZWZpbmVkIHByZXZpb3VzKiBpbiBjYXNlIG5ldyBkYXRhIHdhcyBpbnNlcnRlZC4KK3RlbXBsYXRlIDxjbGFzcyBDb2xsZWN0aW9uPgordHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6c2Vjb25kX3R5cGUqIGNvbnN0CitJbnNlcnRPclJldHVybkV4aXN0aW5nKENvbGxlY3Rpb24qIGNvbnN0IGNvbGxlY3Rpb24sCisgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGUmIHZ0KSB7CisgIHN0ZDo6cGFpcjx0eXBlbmFtZSBDb2xsZWN0aW9uOjppdGVyYXRvciwgYm9vbD4gcmV0ID0gY29sbGVjdGlvbi0+aW5zZXJ0KHZ0KTsKKyAgaWYgKHJldC5zZWNvbmQpIHsKKyAgICByZXR1cm4gTlVMTDsgIC8vIEluc2VydGVkLCBubyBleGlzdGluZyBwcmV2aW91cyB2YWx1ZS4KKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gJnJldC5maXJzdC0+c2Vjb25kOyAgLy8gUmV0dXJuIGFkZHJlc3Mgb2YgYWxyZWFkeSBleGlzdGluZyB2YWx1ZS4KKyAgfQorfQorCisvLyBTYW1lIGFzIGFib3ZlLCBleGNlcHQgZm9yIGV4cGxpY2l0IGtleSBhbmQgZGF0YS4KK3RlbXBsYXRlIDxjbGFzcyBDb2xsZWN0aW9uPgordHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6c2Vjb25kX3R5cGUqIGNvbnN0CitJbnNlcnRPclJldHVybkV4aXN0aW5nKAorICAgIENvbGxlY3Rpb24qIGNvbnN0IGNvbGxlY3Rpb24sCisgICAgY29uc3QgdHlwZW5hbWUgQ29sbGVjdGlvbjo6dmFsdWVfdHlwZTo6Zmlyc3RfdHlwZSYga2V5LAorICAgIGNvbnN0IHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OnNlY29uZF90eXBlJiBkYXRhKSB7CisgIHJldHVybiBJbnNlcnRPclJldHVybkV4aXN0aW5nKGNvbGxlY3Rpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGUoa2V5LCBkYXRhKSk7Cit9CisKKy8vIEVyYXNlcyB0aGUgY29sbGVjdGlvbiBpdGVtIGlkZW50aWZpZWQgYnkgdGhlIGdpdmVuIGtleSwgYW5kIHJldHVybnMgdGhlIHZhbHVlCisvLyBhc3NvY2lhdGVkIHdpdGggdGhhdCBrZXkuIEl0IGlzIGFzc3VtZWQgdGhhdCB0aGUgdmFsdWUgKGkuZS4sIHRoZQorLy8gbWFwcGVkX3R5cGUpIGlzIGEgcG9pbnRlci4gUmV0dXJucyBOVUxMIGlmIHRoZSBrZXkgd2FzIG5vdCBmb3VuZCBpbiB0aGUKKy8vIGNvbGxlY3Rpb24uCisvLworLy8gRXhhbXBsZXM6CisvLyAgIG1hcDxzdHJpbmcsIE15VHlwZSo+IG15X21hcDsKKy8vCisvLyBPbmUgbGluZSBjbGVhbnVwOgorLy8gICAgIGRlbGV0ZSBFcmFzZUtleVJldHVyblZhbHVlUHRyKCZteV9tYXAsICJhYmMiKTsKKy8vCisvLyBVc2UgcmV0dXJuZWQgdmFsdWU6CisvLyAgICAgc2NvcGVkX3B0cjxNeVR5cGU+IHZhbHVlX3B0cihFcmFzZUtleVJldHVyblZhbHVlUHRyKCZteV9tYXAsICJhYmMiKSk7CisvLyAgICAgaWYgKHZhbHVlX3B0ci5nZXQoKSkKKy8vICAgICAgIHZhbHVlX3B0ci0+RG9Tb21ldGhpbmcoKTsKKy8vCit0ZW1wbGF0ZSA8Y2xhc3MgQ29sbGVjdGlvbj4KK3R5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OnNlY29uZF90eXBlIEVyYXNlS2V5UmV0dXJuVmFsdWVQdHIoCisgICAgQ29sbGVjdGlvbiogY29uc3QgY29sbGVjdGlvbiwKKyAgICBjb25zdCB0eXBlbmFtZSBDb2xsZWN0aW9uOjp2YWx1ZV90eXBlOjpmaXJzdF90eXBlJiBrZXkpIHsKKyAgdHlwZW5hbWUgQ29sbGVjdGlvbjo6aXRlcmF0b3IgaXQgPSBjb2xsZWN0aW9uLT5maW5kKGtleSk7CisgIGlmIChpdCA9PSBjb2xsZWN0aW9uLT5lbmQoKSkgeworICAgIHJldHVybiBOVUxMOworICB9CisgIHR5cGVuYW1lIENvbGxlY3Rpb246OnZhbHVlX3R5cGU6OnNlY29uZF90eXBlIHYgPSBpdC0+c2Vjb25kOworICBjb2xsZWN0aW9uLT5lcmFzZShpdCk7CisgIHJldHVybiB2OworfQorCisvLyBJbnNlcnRzIGFsbCB0aGUga2V5cyBmcm9tIG1hcF9jb250YWluZXIgaW50byBrZXlfY29udGFpbmVyLCB3aGljaCBtdXN0CisvLyBzdXBwb3J0IGluc2VydChNYXBDb250YWluZXI6OmtleV90eXBlKS4KKy8vCisvLyBOb3RlOiBhbnkgaW5pdGlhbCBjb250ZW50cyBvZiB0aGUga2V5X2NvbnRhaW5lciBhcmUgbm90IGNsZWFyZWQuCit0ZW1wbGF0ZSA8Y2xhc3MgTWFwQ29udGFpbmVyLCBjbGFzcyBLZXlDb250YWluZXI+Cit2b2lkIEluc2VydEtleXNGcm9tTWFwKGNvbnN0IE1hcENvbnRhaW5lciYgbWFwX2NvbnRhaW5lciwKKyAgICAgICAgICAgICAgICAgICAgICAgS2V5Q29udGFpbmVyKiBrZXlfY29udGFpbmVyKSB7CisgIEdPT0dMRV9DSEVDSyhrZXlfY29udGFpbmVyICE9IE5VTEwpOworICBmb3IgKHR5cGVuYW1lIE1hcENvbnRhaW5lcjo6Y29uc3RfaXRlcmF0b3IgaXQgPSBtYXBfY29udGFpbmVyLmJlZ2luKCk7CisgICAgICAgaXQgIT0gbWFwX2NvbnRhaW5lci5lbmQoKTsgKytpdCkgeworICAgIGtleV9jb250YWluZXItPmluc2VydChpdC0+Zmlyc3QpOworICB9Cit9CisKKy8vIEFwcGVuZHMgYWxsIHRoZSBrZXlzIGZyb20gbWFwX2NvbnRhaW5lciBpbnRvIGtleV9jb250YWluZXIsIHdoaWNoIG11c3QKKy8vIHN1cHBvcnQgcHVzaF9iYWNrKE1hcENvbnRhaW5lcjo6a2V5X3R5cGUpLgorLy8KKy8vIE5vdGU6IGFueSBpbml0aWFsIGNvbnRlbnRzIG9mIHRoZSBrZXlfY29udGFpbmVyIGFyZSBub3QgY2xlYXJlZC4KK3RlbXBsYXRlIDxjbGFzcyBNYXBDb250YWluZXIsIGNsYXNzIEtleUNvbnRhaW5lcj4KK3ZvaWQgQXBwZW5kS2V5c0Zyb21NYXAoY29uc3QgTWFwQ29udGFpbmVyJiBtYXBfY29udGFpbmVyLAorICAgICAgICAgICAgICAgICAgICAgICBLZXlDb250YWluZXIqIGtleV9jb250YWluZXIpIHsKKyAgR09PR0xFX0NIRUNLKGtleV9jb250YWluZXIgIT0gTlVMTCk7CisgIGZvciAodHlwZW5hbWUgTWFwQ29udGFpbmVyOjpjb25zdF9pdGVyYXRvciBpdCA9IG1hcF9jb250YWluZXIuYmVnaW4oKTsKKyAgICAgICBpdCAhPSBtYXBfY29udGFpbmVyLmVuZCgpOyArK2l0KSB7CisgICAga2V5X2NvbnRhaW5lci0+cHVzaF9iYWNrKGl0LT5maXJzdCk7CisgIH0KK30KKworLy8gQSBtb3JlIHNwZWNpYWxpemVkIG92ZXJsb2FkIG9mIEFwcGVuZEtleXNGcm9tTWFwIHRvIG9wdGltaXplIHJlYWxsb2NhdGlvbnMKKy8vIGZvciB0aGUgY29tbW9uIGNhc2UgaW4gd2hpY2ggd2UncmUgYXBwZW5kaW5nIGtleXMgdG8gYSB2ZWN0b3IgYW5kIGhlbmNlIGNhbgorLy8gKGFuZCBzb21ldGltZXMgc2hvdWxkKSBjYWxsIHJlc2VydmUoKSBmaXJzdC4KKy8vCisvLyAoSXQgd291bGQgYmUgcG9zc2libGUgdG8gcGxheSBTRklOQUUgZ2FtZXMgdG8gY2FsbCByZXNlcnZlKCkgZm9yIGFueQorLy8gY29udGFpbmVyIHRoYXQgc3VwcG9ydHMgaXQsIGJ1dCB0aGlzIHNlZW1zIHRvIGdldCB1cyA5OSUgb2Ygd2hhdCB3ZSBuZWVkCisvLyB3aXRob3V0IHRoZSBjb21wbGV4aXR5IG9mIGEgU0ZJTkFFLWJhc2VkIHNvbHV0aW9uLikKK3RlbXBsYXRlIDxjbGFzcyBNYXBDb250YWluZXIsIGNsYXNzIEtleVR5cGU+Cit2b2lkIEFwcGVuZEtleXNGcm9tTWFwKGNvbnN0IE1hcENvbnRhaW5lciYgbWFwX2NvbnRhaW5lciwKKyAgICAgICAgICAgICAgICAgICAgICAgdmVjdG9yPEtleVR5cGU+KiBrZXlfY29udGFpbmVyKSB7CisgIEdPT0dMRV9DSEVDSyhrZXlfY29udGFpbmVyICE9IE5VTEwpOworICAvLyBXZSBub3cgaGF2ZSB0aGUgb3Bwb3J0dW5pdHkgdG8gY2FsbCByZXNlcnZlKCkuIENhbGxpbmcgcmVzZXJ2ZSgpIGV2ZXJ5CisgIC8vIHRpbWUgaXMgYSBiYWQgaWRlYSBmb3Igc29tZSB1c2UgY2FzZXM6IGxpYnN0ZGMrKydzIGltcGxlbWVudGF0aW9uIG9mCisgIC8vIHZlY3Rvcjw+OjpyZXNlcnZlKCkgcmVzaXplcyB0aGUgdmVjdG9yJ3MgYmFja2luZyBzdG9yZSB0byBleGFjdGx5IHRoZQorICAvLyBnaXZlbiBzaXplICh1bmxlc3MgaXQncyBhbHJlYWR5IGF0IGxlYXN0IHRoYXQgYmlnKS4gQmVjYXVzZSBvZiB0aGlzLAorICAvLyB0aGUgdXNlIGNhc2UgdGhhdCBpbnZvbHZlcyBhcHBlbmRpbmcgYSBsb3Qgb2Ygc21hbGwgbWFwcyAodG90YWwgc2l6ZQorICAvLyBOKSBvbmUgYnkgb25lIHRvIGEgdmVjdG9yIHdvdWxkIGJlIE8oTl4yKS4gQnV0IG5ldmVyIGNhbGxpbmcgcmVzZXJ2ZSgpCisgIC8vIGxvc2VzIHRoZSBvcHBvcnR1bml0eSB0byBpbXByb3ZlIHRoZSB1c2UgY2FzZSBvZiBhZGRpbmcgZnJvbSBhIGxhcmdlCisgIC8vIG1hcCB0byBhbiBlbXB0eSB2ZWN0b3IgKHRoaXMgaW1wcm92ZXMgcGVyZm9ybWFuY2UgYnkgdXAgdG8gMzMlKS4gQQorICAvLyBudW1iZXIgb2YgaGV1cmlzdGljcyBhcmUgcG9zc2libGU7IHNlZSB0aGUgZGlzY3Vzc2lvbiBpbgorICAvLyBjbC8zNDA4MTY5Ni4gSGVyZSB3ZSB1c2UgdGhlIHNpbXBsZXN0IG9uZS4KKyAgaWYgKGtleV9jb250YWluZXItPmVtcHR5KCkpIHsKKyAgICBrZXlfY29udGFpbmVyLT5yZXNlcnZlKG1hcF9jb250YWluZXIuc2l6ZSgpKTsKKyAgfQorICBmb3IgKHR5cGVuYW1lIE1hcENvbnRhaW5lcjo6Y29uc3RfaXRlcmF0b3IgaXQgPSBtYXBfY29udGFpbmVyLmJlZ2luKCk7CisgICAgICAgaXQgIT0gbWFwX2NvbnRhaW5lci5lbmQoKTsgKytpdCkgeworICAgIGtleV9jb250YWluZXItPnB1c2hfYmFjayhpdC0+Zmlyc3QpOworICB9Cit9CisKKy8vIEluc2VydHMgYWxsIHRoZSB2YWx1ZXMgZnJvbSBtYXBfY29udGFpbmVyIGludG8gdmFsdWVfY29udGFpbmVyLCB3aGljaCBtdXN0CisvLyBzdXBwb3J0IHB1c2hfYmFjayhNYXBDb250YWluZXI6Om1hcHBlZF90eXBlKS4KKy8vCisvLyBOb3RlOiBhbnkgaW5pdGlhbCBjb250ZW50cyBvZiB0aGUgdmFsdWVfY29udGFpbmVyIGFyZSBub3QgY2xlYXJlZC4KK3RlbXBsYXRlIDxjbGFzcyBNYXBDb250YWluZXIsIGNsYXNzIFZhbHVlQ29udGFpbmVyPgordm9pZCBBcHBlbmRWYWx1ZXNGcm9tTWFwKGNvbnN0IE1hcENvbnRhaW5lciYgbWFwX2NvbnRhaW5lciwKKyAgICAgICAgICAgICAgICAgICAgICAgICBWYWx1ZUNvbnRhaW5lciogdmFsdWVfY29udGFpbmVyKSB7CisgIEdPT0dMRV9DSEVDSyh2YWx1ZV9jb250YWluZXIgIT0gTlVMTCk7CisgIGZvciAodHlwZW5hbWUgTWFwQ29udGFpbmVyOjpjb25zdF9pdGVyYXRvciBpdCA9IG1hcF9jb250YWluZXIuYmVnaW4oKTsKKyAgICAgICBpdCAhPSBtYXBfY29udGFpbmVyLmVuZCgpOyArK2l0KSB7CisgICAgdmFsdWVfY29udGFpbmVyLT5wdXNoX2JhY2soaXQtPnNlY29uZCk7CisgIH0KK30KKworLy8gQSBtb3JlIHNwZWNpYWxpemVkIG92ZXJsb2FkIG9mIEFwcGVuZFZhbHVlc0Zyb21NYXAgdG8gb3B0aW1pemUgcmVhbGxvY2F0aW9ucworLy8gZm9yIHRoZSBjb21tb24gY2FzZSBpbiB3aGljaCB3ZSdyZSBhcHBlbmRpbmcgdmFsdWVzIHRvIGEgdmVjdG9yIGFuZCBoZW5jZQorLy8gY2FuIChhbmQgc29tZXRpbWVzIHNob3VsZCkgY2FsbCByZXNlcnZlKCkgZmlyc3QuCisvLworLy8gKEl0IHdvdWxkIGJlIHBvc3NpYmxlIHRvIHBsYXkgU0ZJTkFFIGdhbWVzIHRvIGNhbGwgcmVzZXJ2ZSgpIGZvciBhbnkKKy8vIGNvbnRhaW5lciB0aGF0IHN1cHBvcnRzIGl0LCBidXQgdGhpcyBzZWVtcyB0byBnZXQgdXMgOTklIG9mIHdoYXQgd2UgbmVlZAorLy8gd2l0aG91dCB0aGUgY29tcGxleGl0eSBvZiBhIFNGSU5BRS1iYXNlZCBzb2x1dGlvbi4pCit0ZW1wbGF0ZSA8Y2xhc3MgTWFwQ29udGFpbmVyLCBjbGFzcyBWYWx1ZVR5cGU+Cit2b2lkIEFwcGVuZFZhbHVlc0Zyb21NYXAoY29uc3QgTWFwQ29udGFpbmVyJiBtYXBfY29udGFpbmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgIHZlY3RvcjxWYWx1ZVR5cGU+KiB2YWx1ZV9jb250YWluZXIpIHsKKyAgR09PR0xFX0NIRUNLKHZhbHVlX2NvbnRhaW5lciAhPSBOVUxMKTsKKyAgLy8gU2VlIEFwcGVuZEtleXNGcm9tTWFwIGZvciB3aHkgdGhpcyBpcyBkb25lLgorICBpZiAodmFsdWVfY29udGFpbmVyLT5lbXB0eSgpKSB7CisgICAgdmFsdWVfY29udGFpbmVyLT5yZXNlcnZlKG1hcF9jb250YWluZXIuc2l6ZSgpKTsKKyAgfQorICBmb3IgKHR5cGVuYW1lIE1hcENvbnRhaW5lcjo6Y29uc3RfaXRlcmF0b3IgaXQgPSBtYXBfY29udGFpbmVyLmJlZ2luKCk7CisgICAgICAgaXQgIT0gbWFwX2NvbnRhaW5lci5lbmQoKTsgKytpdCkgeworICAgIHZhbHVlX2NvbnRhaW5lci0+cHVzaF9iYWNrKGl0LT5zZWNvbmQpOworICB9Cit9CisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9TVFVCU19NQVBfVVRJTF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvbWF0aGxpbWl0cy5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvbWF0aGxpbWl0cy5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMzczYjJiCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9tYXRobGltaXRzLmNjCkBAIC0wLDAgKzEsMTQ0IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKy8vCisvLyBBdXRob3I6IE1heGltIExpZmFudHNldgorLy8KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9tYXRobGltaXRzLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworLy8gTVNWQysrIDIwMDUgYW5kIG9sZGVyIGNvbXBpbGVycyB0aGluayB0aGUgaGVhZGVyIGRlY2xhcmF0aW9uIHdhcyBhCisvLyBkZWZpbml0aW9uLCBhbmQgZXJyb25lb3VzbHkgZmxhZyB0aGVzZSBhcyBhIGR1cGxpY2F0ZSBkZWZpbml0aW9uLgorI2lmIGRlZmluZWQoQ09NUElMRVJfTVNWQykgfHwgX19jcGx1c2NwbHVzIDwgMjAxMTAzTAorCisjZGVmaW5lIERFRl9DT01NT05fTElNSVRTKFR5cGUpCisjZGVmaW5lIERFRl9VTlNJR05FRF9JTlRfTElNSVRTKFR5cGUpCisjZGVmaW5lIERFRl9TSUdORURfSU5UX0xJTUlUUyhUeXBlKQorI2RlZmluZSBERUZfUFJFQ0lTSU9OX0xJTUlUUyhUeXBlKQorCisjZWxzZQorCisjZGVmaW5lIERFRl9DT01NT05fTElNSVRTKFR5cGUpIFwKK2NvbnN0IGJvb2wgTWF0aExpbWl0czxUeXBlPjo6a0lzU2lnbmVkOyBcCitjb25zdCBib29sIE1hdGhMaW1pdHM8VHlwZT46OmtJc0ludGVnZXI7IFwKK2NvbnN0IGludCBNYXRoTGltaXRzPFR5cGU+OjprTWluMTBFeHA7IFwKK2NvbnN0IGludCBNYXRoTGltaXRzPFR5cGU+OjprTWF4MTBFeHA7CisKKyNkZWZpbmUgREVGX1VOU0lHTkVEX0lOVF9MSU1JVFMoVHlwZSkgXAorREVGX0NPTU1PTl9MSU1JVFMoVHlwZSkgXAorY29uc3QgVHlwZSBNYXRoTGltaXRzPFR5cGU+OjprUG9zTWluOyBcCitjb25zdCBUeXBlIE1hdGhMaW1pdHM8VHlwZT46OmtQb3NNYXg7IFwKK2NvbnN0IFR5cGUgTWF0aExpbWl0czxUeXBlPjo6a01pbjsgXAorY29uc3QgVHlwZSBNYXRoTGltaXRzPFR5cGU+OjprTWF4OyBcCitjb25zdCBUeXBlIE1hdGhMaW1pdHM8VHlwZT46OmtFcHNpbG9uOyBcCitjb25zdCBUeXBlIE1hdGhMaW1pdHM8VHlwZT46OmtTdGRFcnJvcjsKKworI2RlZmluZSBERUZfU0lHTkVEX0lOVF9MSU1JVFMoVHlwZSkgXAorREVGX1VOU0lHTkVEX0lOVF9MSU1JVFMoVHlwZSkgXAorY29uc3QgVHlwZSBNYXRoTGltaXRzPFR5cGU+OjprTmVnTWluOyBcCitjb25zdCBUeXBlIE1hdGhMaW1pdHM8VHlwZT46OmtOZWdNYXg7CisKKyNkZWZpbmUgREVGX1BSRUNJU0lPTl9MSU1JVFMoVHlwZSkgXAorY29uc3QgaW50IE1hdGhMaW1pdHM8VHlwZT46OmtQcmVjaXNpb25EaWdpdHM7CisKKyNlbmRpZiAgLy8gbm90IENPTVBJTEVSX01TVkMKKworLy8gaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9RdWFkcnVwbGVfcHJlY2lzaW9uX2Zsb2F0aW5nLXBvaW50X2Zvcm1hdCNEb3VibGUtZG91YmxlX2FyaXRobWV0aWMKKy8vIFdpdGggc29tZSBjb21waWxlcnMgKGdjYyA0LjYueCkgb24gc29tZSBwbGF0Zm9ybXMgKHBvd2VycGM2NCksCisvLyAibG9uZyBkb3VibGUiIGlzIGltcGxlbWVudGVkIGFzIGEgcGFpciBvZiBkb3VibGU6ICJkb3VibGUgZG91YmxlIiBmb3JtYXQuCisvLyBUaGlzIGNhdXNlcyBhIHByb2JsZW0gd2l0aCBlcHNpbG9uIChlcHMpLgorLy8gZXBzIGlzIHRoZSBzbWFsbGVzdCBwb3NpdGl2ZSBudW1iZXIgc3VjaCB0aGF0IDEuMCArIGVwcyA+IDEuMAorLy8KKy8vIE5vcm1hbCBmb3JtYXQ6ICAxLjAgKyBlID0gMS4wLi4uMDEgICAgICAvLyBOLTEgemVyb3MgZm9yIE4gZnJhY3Rpb24gYml0cworLy8gRC1EIGZvcm1hdDogICAgIDEuMCArIGUgPSAxLjAwMC4uLjAwMDEgIC8vIGVwc2lsb24gY2FuIGJlIHZlcnkgc21hbGwKKy8vCisvLyBJbiB0aGUgbm9ybWFsIGZvcm1hdCwgMS4wICsgZSBoYXMgdG8gZml0IGluIG9uZSBzdHJldGNoIG9mIGJpdHMuCisvLyBUaGUgbWF4aW11bSByb3VuZGluZyBlcnJvciBpcyBoYWxmIG9mIGVwcy4KKy8vCisvLyBJbiB0aGUgZG91YmxlLWRvdWJsZSBmb3JtYXQsIDEuMCArIGUgc3BsaXRzIGFjcm9zcyB0d28gZG91YmxlczoKKy8vIDEuMCBpbiB0aGUgaGlnaCBkb3VibGUsIGUgaW4gdGhlIGxvdyBkb3VibGUsIGFuZCB0aGV5IGRvIG5vdCBoYXZlIHRvCisvLyBiZSBjb250aWd1b3VzLiAgVGhlIG1heGltdW0gcm91bmRpbmcgZXJyb3Igb24gYSB2YWx1ZSBjbG9zZSB0byAxLjAgaXMKKy8vIG11Y2ggbGFyZ2VyIHRoYW4gZXBzLgorLy8KKy8vIFNvbWUgY29kZSBjaGVja3MgZm9yIGVycm9ycyBieSBjb21wYXJpbmcgYSBjb21wdXRlZCB2YWx1ZSB0byBhIGdvbGRlbgorLy8gdmFsdWUgKy8tIHNvbWUgbXVsdGlwbGUgb2YgdGhlIG1heGltdW0gcm91bmRpbmcgZXJyb3IuICBUaGUgbWF4aW11bQorLy8gcm91bmRpbmcgZXJyb3IgaXMgbm90IGF2YWlsYWJsZSBzbyB3ZSB1c2UgZXBzIGFzIGFuIGFwcHJveGltYXRpb24KKy8vIGluc3RlYWQuICBUaGF0IGZhaWxzIHdoZW4gbG9uZyBkb3VibGUgaXMgaW4gdGhlIGRvdWJsZS1kb3VibGUgZm9ybWF0LgorLy8gVGhlcmVmb3JlLCB3ZSBkZWZpbmUga1N0ZEVycm9yIGFzIGEgbXVsdGlwbGUgb2YKKy8vIG1heChEQkxfRVBTSUxPTiAqIERCTF9FUFNJTE9OLCBrRXBzaWxvbikgcmF0aGVyIHRoYW4gYSBtdWx0aXBsZSBvZiBrRXBzaWxvbi4KKworI2RlZmluZSBERUZfRlBfTElNSVRTKFR5cGUsIFBSRUZJWCkgXAorREVGX0NPTU1PTl9MSU1JVFMoVHlwZSkgXAorY29uc3QgVHlwZSBNYXRoTGltaXRzPFR5cGU+OjprUG9zTWluID0gUFJFRklYIyNfTUlOOyBcCitjb25zdCBUeXBlIE1hdGhMaW1pdHM8VHlwZT46OmtQb3NNYXggPSBQUkVGSVgjI19NQVg7IFwKK2NvbnN0IFR5cGUgTWF0aExpbWl0czxUeXBlPjo6a01pbiA9IC1NYXRoTGltaXRzPFR5cGU+OjprUG9zTWF4OyBcCitjb25zdCBUeXBlIE1hdGhMaW1pdHM8VHlwZT46OmtNYXggPSBNYXRoTGltaXRzPFR5cGU+OjprUG9zTWF4OyBcCitjb25zdCBUeXBlIE1hdGhMaW1pdHM8VHlwZT46OmtOZWdNaW4gPSAtTWF0aExpbWl0czxUeXBlPjo6a1Bvc01pbjsgXAorY29uc3QgVHlwZSBNYXRoTGltaXRzPFR5cGU+OjprTmVnTWF4ID0gLU1hdGhMaW1pdHM8VHlwZT46OmtQb3NNYXg7IFwKK2NvbnN0IFR5cGUgTWF0aExpbWl0czxUeXBlPjo6a0Vwc2lsb24gPSBQUkVGSVgjI19FUFNJTE9OOyBcCisvKiAzMiBpcyA1IGJpdHMgb2YgbWFudGlzc2EgZXJyb3I7IHNob3VsZCBiZSBhZGVxdWF0ZSBmb3IgY29tbW9uIGVycm9ycyAqLyBcCitjb25zdCBUeXBlIE1hdGhMaW1pdHM8VHlwZT46OmtTdGRFcnJvciA9IFwKKyAgMzIgKiAoREJMX0VQU0lMT04gKiBEQkxfRVBTSUxPTiA+IE1hdGhMaW1pdHM8VHlwZT46OmtFcHNpbG9uIFwKKyAgICAgID8gREJMX0VQU0lMT04gKiBEQkxfRVBTSUxPTiA6IE1hdGhMaW1pdHM8VHlwZT46OmtFcHNpbG9uKTsgXAorREVGX1BSRUNJU0lPTl9MSU1JVFMoVHlwZSkgXAorY29uc3QgVHlwZSBNYXRoTGltaXRzPFR5cGU+OjprTmFOID0gSFVHRV9WQUwgLSBIVUdFX1ZBTDsgXAorY29uc3QgVHlwZSBNYXRoTGltaXRzPFR5cGU+OjprUG9zSW5mID0gSFVHRV9WQUw7IFwKK2NvbnN0IFR5cGUgTWF0aExpbWl0czxUeXBlPjo6a05lZ0luZiA9IC1IVUdFX1ZBTDsKKworLy8gVGhlIGZvbGxvd2luZyBhcmUgKm5vdCogY2FzdHMhCitERUZfU0lHTkVEX0lOVF9MSU1JVFMoaW50OCkKK0RFRl9TSUdORURfSU5UX0xJTUlUUyhpbnQxNikgIC8vIE5PTElOVChyZWFkYWJpbGl0eS9jYXN0aW5nKQorREVGX1NJR05FRF9JTlRfTElNSVRTKGludDMyKSAgLy8gTk9MSU5UKHJlYWRhYmlsaXR5L2Nhc3RpbmcpCitERUZfU0lHTkVEX0lOVF9MSU1JVFMoaW50NjQpICAvLyBOT0xJTlQocmVhZGFiaWxpdHkvY2FzdGluZykKK0RFRl9VTlNJR05FRF9JTlRfTElNSVRTKHVpbnQ4KQorREVGX1VOU0lHTkVEX0lOVF9MSU1JVFModWludDE2KSAgLy8gTk9MSU5UKHJlYWRhYmlsaXR5L2Nhc3RpbmcpCitERUZfVU5TSUdORURfSU5UX0xJTUlUUyh1aW50MzIpICAvLyBOT0xJTlQocmVhZGFiaWxpdHkvY2FzdGluZykKK0RFRl9VTlNJR05FRF9JTlRfTElNSVRTKHVpbnQ2NCkgIC8vIE5PTElOVChyZWFkYWJpbGl0eS9jYXN0aW5nKQorCitERUZfU0lHTkVEX0lOVF9MSU1JVFMobG9uZyBpbnQpCitERUZfVU5TSUdORURfSU5UX0xJTUlUUyh1bnNpZ25lZCBsb25nIGludCkKKworREVGX0ZQX0xJTUlUUyhmbG9hdCwgRkxUKQorREVGX0ZQX0xJTUlUUyhkb3VibGUsIERCTCkKK0RFRl9GUF9MSU1JVFMobG9uZyBkb3VibGUsIExEQkwpOworCisjdW5kZWYgREVGX0NPTU1PTl9MSU1JVFMKKyN1bmRlZiBERUZfU0lHTkVEX0lOVF9MSU1JVFMKKyN1bmRlZiBERUZfVU5TSUdORURfSU5UX0xJTUlUUworI3VuZGVmIERFRl9GUF9MSU1JVFMKKyN1bmRlZiBERUZfUFJFQ0lTSU9OX0xJTUlUUworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL21hdGhsaW1pdHMuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvbWF0aGxpbWl0cy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ5ODQ2OTQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL21hdGhsaW1pdHMuaApAQCAtMCwwICsxLDI3OSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCisvLworLy8gQXV0aG9yOiBNYXhpbSBMaWZhbnRzZXYKKy8vCisvLyBVc2VmdWwgaW50ZWdlciBhbmQgZmxvYXRpbmcgcG9pbnQgbGltaXRzIGFuZCB0eXBlIHRyYWl0cy4KKy8vCisvLyBUaGlzIHBhcnRpYWxseSByZXBsYWNlcy9kdXBsaWN0ZXMgbnVtZXJpY19saW1pdHM8PiBmcm9tIDxsaW1pdHM+LgorLy8gV2UgZ2V0IGEgR29vZ2xlLXN0eWxlIGNsYXNzIHRoYXQgd2UgaGF2ZSBhIGdyZWF0ZXIgY29udHJvbCBvdmVyCisvLyBhbmQgdGh1cyBjYW4gYWRkIG5ldyBmZWF0dXJlcyB0byBpdCBvciBmaXggd2hhdGV2ZXIgaGFwcGVucyB0byBiZSBicm9rZW4gaW4KKy8vIG51bWVyaWNfbGltaXRzIGZvciB0aGUgY29tcGlsZXJzIHdlIHVzZS4KKy8vCisKKyNpZm5kZWYgVVRJTF9NQVRIX01BVEhMSU1JVFNfSF9fCisjZGVmaW5lIFVUSUxfTUFUSF9NQVRITElNSVRTX0hfXworCisvLyA8bWF0aC5oPiBsYWNrcyBhIGxvdCBvZiBwcm90b3R5cGVzLiBIb3dldmVyLCB0aGlzIGZpbGUgbmVlZHMgPG1hdGguaD4gdG8KKy8vIGFjY2VzcyBvbGQtZmFzaGlvbmVkIGlzaW5mIGV0IGFsLiBFdmVuIHdvcnNlIG1vcmU6IHRoaXMgZmlsZSBtdXN0IG5vdAorLy8gaW5jbHVkZSA8Y21hdGg+IGJlY2F1c2UgdGhhdCBicmVha3MgdGhlIGRlZmluaXRpb24gb2YgaXNpbmYgd2l0aCBnY2MgNC45LgorLy8KKy8vIFRPRE8obWVjKTogYWZ0ZXIgQysrMTEgZXZlcnl3aGVyZSwgdXNlIDxjbWF0aD4gYW5kIHN0ZDo6aXNpbmYgaW4gdGhpcyBmaWxlLgorI2luY2x1ZGUgPG1hdGguaD4KKyNpbmNsdWRlIDxzdHJpbmcuaD4KKworI2luY2x1ZGUgPGNmbG9hdD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAvLworCisvLyBVc2VmdWwgaW50ZWdlciBhbmQgZmxvYXRpbmcgcG9pbnQgbGltaXRzIGFuZCB0eXBlIHRyYWl0cy4KKy8vIFRoaXMgaXMganVzdCBmb3IgdGhlIGRvY3VtZW50YXRpb247CisvLyByZWFsIG1lbWJlcnMgYXJlIGRlZmluZWQgaW4gb3VyIHNwZWNpYWxpemF0aW9ucyBiZWxvdy4KK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+IHN0cnVjdCBNYXRoTGltaXRzIHsKKyAgLy8gVHlwZSBuYW1lLgorICB0eXBlZGVmIFQgVHlwZTsKKyAgLy8gVW5zaWduZWQgdmVyc2lvbiBvZiB0aGUgVHlwZSB3aXRoIHRoZSBzYW1lIGJ5dGUgc2l6ZS4KKyAgLy8gU2FtZSBhcyBUeXBlIGZvciBmbG9hdGluZyBwb2ludCBhbmQgdW5zaWduZWQgdHlwZXMuCisgIHR5cGVkZWYgVCBVbnNpZ25lZFR5cGU7CisgIC8vIElmIHRoZSB0eXBlIHN1cHBvcnRzIG5lZ2F0aXZlIHZhbHVlcy4KKyAgc3RhdGljIGNvbnN0IGJvb2wga0lzU2lnbmVkOworICAvLyBJZiB0aGUgdHlwZSBzdXBwb3J0cyBvbmx5IGludGVnZXIgdmFsdWVzLgorICBzdGF0aWMgY29uc3QgYm9vbCBrSXNJbnRlZ2VyOworICAvLyBNYWduaXR1ZGUtd2lzZSBzbWFsbGVzdCByZXByZXNlbnRhYmxlIHBvc2l0aXZlIHZhbHVlLgorICBzdGF0aWMgY29uc3QgVHlwZSBrUG9zTWluOworICAvLyBNYWduaXR1ZGUtd2lzZSBsYXJnZXN0IHJlcHJlc2VudGFibGUgcG9zaXRpdmUgdmFsdWUuCisgIHN0YXRpYyBjb25zdCBUeXBlIGtQb3NNYXg7CisgIC8vIFNtYWxsZXN0IHJlcHJlc2VudGFibGUgdmFsdWUuCisgIHN0YXRpYyBjb25zdCBUeXBlIGtNaW47CisgIC8vIExhcmdlc3QgcmVwcmVzZW50YWJsZSB2YWx1ZS4KKyAgc3RhdGljIGNvbnN0IFR5cGUga01heDsKKyAgLy8gTWFnbml0dWRlLXdpc2Ugc21hbGxlc3QgcmVwcmVzZW50YWJsZSBuZWdhdGl2ZSB2YWx1ZS4KKyAgLy8gUHJlc2VudCBvbmx5IGlmIGtJc1NpZ25lZC4KKyAgc3RhdGljIGNvbnN0IFR5cGUga05lZ01pbjsKKyAgLy8gTWFnbml0dWRlLXdpc2UgbGFyZ2VzdCByZXByZXNlbnRhYmxlIG5lZ2F0aXZlIHZhbHVlLgorICAvLyBQcmVzZW50IG9ubHkgaWYga0lzU2lnbmVkLgorICBzdGF0aWMgY29uc3QgVHlwZSBrTmVnTWF4OworICAvLyBTbWFsbGVzdCBpbnRlZ2VyIHggc3VjaCB0aGF0IDEwXnggaXMgcmVwcmVzZW50YWJsZS4KKyAgc3RhdGljIGNvbnN0IGludCBrTWluMTBFeHA7CisgIC8vIExhcmdlc3QgaW50ZWdlciB4IHN1Y2ggdGhhdCAxMF54IGlzIHJlcHJlc2VudGFibGUuCisgIHN0YXRpYyBjb25zdCBpbnQga01heDEwRXhwOworICAvLyBTbWFsbGVzdCBwb3NpdGl2ZSB2YWx1ZSBzdWNoIHRoYXQgVHlwZSgxKSArIGtFcHNpbG9uICE9IFR5cGUoMSkKKyAgc3RhdGljIGNvbnN0IFR5cGUga0Vwc2lsb247CisgIC8vIFR5cGljYWwgcm91bmRpbmcgZXJyb3IgdGhhdCBpcyBlbm91Z2ggdG8gY292ZXIKKyAgLy8gYSBmZXcgc2ltcGxlIGZsb2F0aW5nLXBvaW50IG9wZXJhdGlvbnMuCisgIC8vIFNsaWdodGx5IGxhcmdlciB0aGFuIGtFcHNpbG9uIHRvIGFjY291bnQgZm9yIGEgZmV3IHJvdW5kaW5nIGVycm9ycy4KKyAgLy8gSXMgemVybyBpZiBrSXNJbnRlZ2VyLgorICBzdGF0aWMgY29uc3QgVHlwZSBrU3RkRXJyb3I7CisgIC8vIE51bWJlciBvZiBkZWNpbWFsIGRpZ2l0cyBvZiBtYW50aXNzYSBwcmVjaXNpb24uCisgIC8vIFByZXNlbnQgb25seSBpZiAha0lzSW50ZWdlci4KKyAgc3RhdGljIGNvbnN0IGludCBrUHJlY2lzaW9uRGlnaXRzOworICAvLyBOb3QgYSBudW1iZXIsIGkuZS4gcmVzdWx0IG9mIDAvMC4KKyAgLy8gUHJlc2VudCBvbmx5IGlmICFrSXNJbnRlZ2VyLgorICBzdGF0aWMgY29uc3QgVHlwZSBrTmFOOworICAvLyBQb3NpdGl2ZSBpbmZpbml0eSwgaS5lLiByZXN1bHQgb2YgMS8wLgorICAvLyBQcmVzZW50IG9ubHkgaWYgIWtJc0ludGVnZXIuCisgIHN0YXRpYyBjb25zdCBUeXBlIGtQb3NJbmY7CisgIC8vIE5lZ2F0aXZlIGluZmluaXR5LCBpLmUuIHJlc3VsdCBvZiAtMS8wLgorICAvLyBQcmVzZW50IG9ubHkgaWYgIWtJc0ludGVnZXIuCisgIHN0YXRpYyBjb25zdCBUeXBlIGtOZWdJbmY7CisKKyAgLy8gTk9URTogU3BlY2lhbCBmbG9hdGluZyBwb2ludCB2YWx1ZXMgYmVoYXZlCisgIC8vIGluIGEgc3BlY2lhbCAoYnV0IG1hdGhlbWF0aWNhbGx5LWxvZ2ljYWwpIHdheQorICAvLyBpbiB0ZXJtcyBvZiAoaW4pZXF1YWx0eSBjb21wYXJpc29uIGFuZCBtYXRoZW1hdGljYWwgb3BlcmF0aW9ucworICAvLyAtLSBzZWUgb3V0IHVuaXR0ZXN0IGZvciBleGFtcGxlcy4KKworICAvLyBTcGVjaWFsIGZsb2F0aW5nIHBvaW50IHZhbHVlIHRlc3RlcnMuCisgIC8vIFByZXNlbnQgaW4gaW50ZWdlciB0eXBlcyBmb3IgY29udmVuaWVuY2UuCisgIHN0YXRpYyBib29sIElzRmluaXRlKGNvbnN0IFR5cGUgeCk7CisgIHN0YXRpYyBib29sIElzTmFOKGNvbnN0IFR5cGUgeCk7CisgIHN0YXRpYyBib29sIElzSW5mKGNvbnN0IFR5cGUgeCk7CisgIHN0YXRpYyBib29sIElzUG9zSW5mKGNvbnN0IFR5cGUgeCk7CisgIHN0YXRpYyBib29sIElzTmVnSW5mKGNvbnN0IFR5cGUgeCk7Cit9OworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IC8vCisKKy8vIEFsbCAjZGVmaW5lLXMgYmVsb3cgYXJlIHNpbXBseSB0byByZWZhY3RvciB0aGUgZGVjbGFyYXRpb25zIG9mCisvLyBNYXRoTGltaXRzIHRlbXBsYXRlIHNwZWNpYWxpemF0aW9ucy4KKy8vIFRoZXkgYXJlIGFsbCAjdW5kZWYtaW5lZCBiZWxvdy4KKworLy8gVGhlIGhvb3AtanVtcGluZyBpbiAqX0lOVF8oTUFYfE1JTikgYmVsb3cgaXMgc28gdGhhdCB0aGUgY29tcGlsZXIgZG9lcyBub3QKKy8vIGdldCBhbiBvdmVyZmxvdyB3aGlsZSBjb21wdXRpbmcgdGhlIGNvbnN0YW50cy4KKworI2RlZmluZSBTSUdORURfSU5UX01BWChUeXBlKSBcCisgICgoKFR5cGUoMSkgPDwgKHNpemVvZihUeXBlKSo4IC0gMikpIC0gMSkgKyAoVHlwZSgxKSA8PCAoc2l6ZW9mKFR5cGUpKjggLSAyKSkpCisKKyNkZWZpbmUgU0lHTkVEX0lOVF9NSU4oVHlwZSkgXAorICAoLShUeXBlKDEpIDw8IChzaXplb2YoVHlwZSkqOCAtIDIpKSAtIChUeXBlKDEpIDw8IChzaXplb2YoVHlwZSkqOCAtIDIpKSkKKworI2RlZmluZSBVTlNJR05FRF9JTlRfTUFYKFR5cGUpIFwKKyAgKCgoVHlwZSgxKSA8PCAoc2l6ZW9mKFR5cGUpKjggLSAxKSkgLSAxKSArIChUeXBlKDEpIDw8IChzaXplb2YoVHlwZSkqOCAtIDEpKSkKKworLy8gQ29tcGlsZS10aW1lIHNlbGVjdGVkIGxvZzEwLXJlbGF0ZWQgY29uc3RhbnRzIGZvciBpbnRlZ2VyIHR5cGVzLgorI2RlZmluZSBTSUdORURfTUFYXzEwX0VYUChUeXBlKSBcCisgIChzaXplb2YoVHlwZSkgPT0gMSA/IDIgOiAoIFwKKyAgICBzaXplb2YoVHlwZSkgPT0gMiA/IDQgOiAoIFwKKyAgICAgIHNpemVvZihUeXBlKSA9PSA0ID8gOSA6ICggXAorICAgICAgICBzaXplb2YoVHlwZSkgPT0gOCA/IDE4IDogLTEpKSkpCisKKyNkZWZpbmUgVU5TSUdORURfTUFYXzEwX0VYUChUeXBlKSBcCisgIChzaXplb2YoVHlwZSkgPT0gMSA/IDIgOiAoIFwKKyAgICBzaXplb2YoVHlwZSkgPT0gMiA/IDQgOiAoIFwKKyAgICAgIHNpemVvZihUeXBlKSA9PSA0ID8gOSA6ICggXAorICAgICAgICBzaXplb2YoVHlwZSkgPT0gOCA/IDE5IDogLTEpKSkpCisKKyNkZWZpbmUgREVDTF9JTlRfTElNSVRfRlVOQ1MgXAorICBzdGF0aWMgYm9vbCBJc0Zpbml0ZShjb25zdCBUeXBlIC8qeCovKSB7IHJldHVybiB0cnVlOyB9IFwKKyAgc3RhdGljIGJvb2wgSXNOYU4oY29uc3QgVHlwZSAvKngqLykgeyByZXR1cm4gZmFsc2U7IH0gXAorICBzdGF0aWMgYm9vbCBJc0luZihjb25zdCBUeXBlIC8qeCovKSB7IHJldHVybiBmYWxzZTsgfSBcCisgIHN0YXRpYyBib29sIElzUG9zSW5mKGNvbnN0IFR5cGUgLyp4Ki8pIHsgcmV0dXJuIGZhbHNlOyB9IFwKKyAgc3RhdGljIGJvb2wgSXNOZWdJbmYoY29uc3QgVHlwZSAvKngqLykgeyByZXR1cm4gZmFsc2U7IH0KKworI2RlZmluZSBERUNMX1NJR05FRF9JTlRfTElNSVRTKEludFR5cGUsIFVuc2lnbmVkSW50VHlwZSkgXAordGVtcGxhdGU8PiBcCitzdHJ1Y3QgTElCUFJPVE9CVUZfRVhQT1JUIE1hdGhMaW1pdHM8SW50VHlwZT4geyBcCisgIHR5cGVkZWYgSW50VHlwZSBUeXBlOyBcCisgIHR5cGVkZWYgVW5zaWduZWRJbnRUeXBlIFVuc2lnbmVkVHlwZTsgXAorICBzdGF0aWMgY29uc3QgYm9vbCBrSXNTaWduZWQgPSB0cnVlOyBcCisgIHN0YXRpYyBjb25zdCBib29sIGtJc0ludGVnZXIgPSB0cnVlOyBcCisgIHN0YXRpYyBjb25zdCBUeXBlIGtQb3NNaW4gPSAxOyBcCisgIHN0YXRpYyBjb25zdCBUeXBlIGtQb3NNYXggPSBTSUdORURfSU5UX01BWChUeXBlKTsgXAorICBzdGF0aWMgY29uc3QgVHlwZSBrTWluID0gU0lHTkVEX0lOVF9NSU4oVHlwZSk7IFwKKyAgc3RhdGljIGNvbnN0IFR5cGUga01heCA9IGtQb3NNYXg7IFwKKyAgc3RhdGljIGNvbnN0IFR5cGUga05lZ01pbiA9IC0xOyBcCisgIHN0YXRpYyBjb25zdCBUeXBlIGtOZWdNYXggPSBrTWluOyBcCisgIHN0YXRpYyBjb25zdCBpbnQga01pbjEwRXhwID0gMDsgXAorICBzdGF0aWMgY29uc3QgaW50IGtNYXgxMEV4cCA9IFNJR05FRF9NQVhfMTBfRVhQKFR5cGUpOyBcCisgIHN0YXRpYyBjb25zdCBUeXBlIGtFcHNpbG9uID0gMTsgXAorICBzdGF0aWMgY29uc3QgVHlwZSBrU3RkRXJyb3IgPSAwOyBcCisgIERFQ0xfSU5UX0xJTUlUX0ZVTkNTIFwKK307CisKKyNkZWZpbmUgREVDTF9VTlNJR05FRF9JTlRfTElNSVRTKEludFR5cGUpIFwKK3RlbXBsYXRlPD4gXAorc3RydWN0IExJQlBST1RPQlVGX0VYUE9SVCBNYXRoTGltaXRzPEludFR5cGU+IHsgXAorICB0eXBlZGVmIEludFR5cGUgVHlwZTsgXAorICB0eXBlZGVmIEludFR5cGUgVW5zaWduZWRUeXBlOyBcCisgIHN0YXRpYyBjb25zdCBib29sIGtJc1NpZ25lZCA9IGZhbHNlOyBcCisgIHN0YXRpYyBjb25zdCBib29sIGtJc0ludGVnZXIgPSB0cnVlOyBcCisgIHN0YXRpYyBjb25zdCBUeXBlIGtQb3NNaW4gPSAxOyBcCisgIHN0YXRpYyBjb25zdCBUeXBlIGtQb3NNYXggPSBVTlNJR05FRF9JTlRfTUFYKFR5cGUpOyBcCisgIHN0YXRpYyBjb25zdCBUeXBlIGtNaW4gPSAwOyBcCisgIHN0YXRpYyBjb25zdCBUeXBlIGtNYXggPSBrUG9zTWF4OyBcCisgIHN0YXRpYyBjb25zdCBpbnQga01pbjEwRXhwID0gMDsgXAorICBzdGF0aWMgY29uc3QgaW50IGtNYXgxMEV4cCA9IFVOU0lHTkVEX01BWF8xMF9FWFAoVHlwZSk7IFwKKyAgc3RhdGljIGNvbnN0IFR5cGUga0Vwc2lsb24gPSAxOyBcCisgIHN0YXRpYyBjb25zdCBUeXBlIGtTdGRFcnJvciA9IDA7IFwKKyAgREVDTF9JTlRfTElNSVRfRlVOQ1MgXAorfTsKKworREVDTF9TSUdORURfSU5UX0xJTUlUUyhzaWduZWQgY2hhciwgdW5zaWduZWQgY2hhcikKK0RFQ0xfU0lHTkVEX0lOVF9MSU1JVFMoc2lnbmVkIHNob3J0IGludCwgdW5zaWduZWQgc2hvcnQgaW50KQorREVDTF9TSUdORURfSU5UX0xJTUlUUyhzaWduZWQgaW50LCB1bnNpZ25lZCBpbnQpCitERUNMX1NJR05FRF9JTlRfTElNSVRTKHNpZ25lZCBsb25nIGludCwgdW5zaWduZWQgbG9uZyBpbnQpCitERUNMX1NJR05FRF9JTlRfTElNSVRTKHNpZ25lZCBsb25nIGxvbmcgaW50LCB1bnNpZ25lZCBsb25nIGxvbmcgaW50KQorREVDTF9VTlNJR05FRF9JTlRfTElNSVRTKHVuc2lnbmVkIGNoYXIpCitERUNMX1VOU0lHTkVEX0lOVF9MSU1JVFModW5zaWduZWQgc2hvcnQgaW50KQorREVDTF9VTlNJR05FRF9JTlRfTElNSVRTKHVuc2lnbmVkIGludCkKK0RFQ0xfVU5TSUdORURfSU5UX0xJTUlUUyh1bnNpZ25lZCBsb25nIGludCkKK0RFQ0xfVU5TSUdORURfSU5UX0xJTUlUUyh1bnNpZ25lZCBsb25nIGxvbmcgaW50KQorCisjdW5kZWYgREVDTF9TSUdORURfSU5UX0xJTUlUUworI3VuZGVmIERFQ0xfVU5TSUdORURfSU5UX0xJTUlUUworI3VuZGVmIFNJR05FRF9JTlRfTUFYCisjdW5kZWYgU0lHTkVEX0lOVF9NSU4KKyN1bmRlZiBVTlNJR05FRF9JTlRfTUFYCisjdW5kZWYgU0lHTkVEX01BWF8xMF9FWFAKKyN1bmRlZiBVTlNJR05FRF9NQVhfMTBfRVhQCisjdW5kZWYgREVDTF9JTlRfTElNSVRfRlVOQ1MKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAvLworI2lmZGVmIFdJTjMyICAvLyBMYWNrcyBidWlsdC1pbiBpc25hbigpIGFuZCBpc2luZigpCisjZGVmaW5lIERFQ0xfRlBfTElNSVRfRlVOQ1MgXAorICBzdGF0aWMgYm9vbCBJc0Zpbml0ZShjb25zdCBUeXBlIHgpIHsgcmV0dXJuIF9maW5pdGUoeCk7IH0gXAorICBzdGF0aWMgYm9vbCBJc05hTihjb25zdCBUeXBlIHgpIHsgcmV0dXJuIF9pc25hbih4KTsgfSBcCisgIHN0YXRpYyBib29sIElzSW5mKGNvbnN0IFR5cGUgeCkgeyByZXR1cm4gKF9mcGNsYXNzKHgpICYgKF9GUENMQVNTX05JTkYgfCBfRlBDTEFTU19QSU5GKSkgIT0gMDsgfSBcCisgIHN0YXRpYyBib29sIElzUG9zSW5mKGNvbnN0IFR5cGUgeCkgeyByZXR1cm4gX2ZwY2xhc3MoeCkgPT0gX0ZQQ0xBU1NfUElORjsgfSBcCisgIHN0YXRpYyBib29sIElzTmVnSW5mKGNvbnN0IFR5cGUgeCkgeyByZXR1cm4gX2ZwY2xhc3MoeCkgPT0gX0ZQQ0xBU1NfTklORjsgfQorI2Vsc2UKKyNkZWZpbmUgREVDTF9GUF9MSU1JVF9GVU5DUyBcCisgIHN0YXRpYyBib29sIElzRmluaXRlKGNvbnN0IFR5cGUgeCkgeyByZXR1cm4gIWlzaW5mKHgpICAmJiAgIWlzbmFuKHgpOyB9IFwKKyAgc3RhdGljIGJvb2wgSXNOYU4oY29uc3QgVHlwZSB4KSB7IHJldHVybiBpc25hbih4KTsgfSBcCisgIHN0YXRpYyBib29sIElzSW5mKGNvbnN0IFR5cGUgeCkgeyByZXR1cm4gaXNpbmYoeCk7IH0gXAorICBzdGF0aWMgYm9vbCBJc1Bvc0luZihjb25zdCBUeXBlIHgpIHsgcmV0dXJuIGlzaW5mKHgpICAmJiAgeCA+IDA7IH0gXAorICBzdGF0aWMgYm9vbCBJc05lZ0luZihjb25zdCBUeXBlIHgpIHsgcmV0dXJuIGlzaW5mKHgpICAmJiAgeCA8IDA7IH0KKyNlbmRpZgorCisvLyBXZSBjYW4ndCBwdXQgZmxvYXRpbmctcG9pbnQgY29uc3RhbnQgdmFsdWVzIGluIHRoZSBoZWFkZXIgaGVyZSBiZWNhdXNlCisvLyBzdWNoIGNvbnN0YW50cyBhcmUgbm90IGNvbnNpZGVyZWQgdG8gYmUgcHJpbWl0aXZlLXR5cGUgY29uc3RhbnRzIGJ5IGdjYy4KKy8vIENBVkVBVDogSGVuY2UsIHRoZXkgYXJlIGdvaW5nIHRvIGJlIGluaXRpYWxpemVkIG9ubHkgZHVyaW5nCisvLyB0aGUgZ2xvYmFsIG9iamVjdHMgY29uc3RydWN0aW9uIHRpbWUuCisjZGVmaW5lIERFQ0xfRlBfTElNSVRTKEZQX1R5cGUsIFBSRUZJWCkgXAordGVtcGxhdGU8PiBcCitzdHJ1Y3QgTElCUFJPVE9CVUZfRVhQT1JUIE1hdGhMaW1pdHM8RlBfVHlwZT4geyBcCisgIHR5cGVkZWYgRlBfVHlwZSBUeXBlOyBcCisgIHR5cGVkZWYgRlBfVHlwZSBVbnNpZ25lZFR5cGU7IFwKKyAgc3RhdGljIGNvbnN0IGJvb2wga0lzU2lnbmVkID0gdHJ1ZTsgXAorICBzdGF0aWMgY29uc3QgYm9vbCBrSXNJbnRlZ2VyID0gZmFsc2U7IFwKKyAgc3RhdGljIGNvbnN0IFR5cGUga1Bvc01pbjsgXAorICBzdGF0aWMgY29uc3QgVHlwZSBrUG9zTWF4OyBcCisgIHN0YXRpYyBjb25zdCBUeXBlIGtNaW47IFwKKyAgc3RhdGljIGNvbnN0IFR5cGUga01heDsgXAorICBzdGF0aWMgY29uc3QgVHlwZSBrTmVnTWluOyBcCisgIHN0YXRpYyBjb25zdCBUeXBlIGtOZWdNYXg7IFwKKyAgc3RhdGljIGNvbnN0IGludCBrTWluMTBFeHAgPSBQUkVGSVgjI19NSU5fMTBfRVhQOyBcCisgIHN0YXRpYyBjb25zdCBpbnQga01heDEwRXhwID0gUFJFRklYIyNfTUFYXzEwX0VYUDsgXAorICBzdGF0aWMgY29uc3QgVHlwZSBrRXBzaWxvbjsgXAorICBzdGF0aWMgY29uc3QgVHlwZSBrU3RkRXJyb3I7IFwKKyAgc3RhdGljIGNvbnN0IGludCBrUHJlY2lzaW9uRGlnaXRzID0gUFJFRklYIyNfRElHOyBcCisgIHN0YXRpYyBjb25zdCBUeXBlIGtOYU47IFwKKyAgc3RhdGljIGNvbnN0IFR5cGUga1Bvc0luZjsgXAorICBzdGF0aWMgY29uc3QgVHlwZSBrTmVnSW5mOyBcCisgIERFQ0xfRlBfTElNSVRfRlVOQ1MgXAorfTsKKworREVDTF9GUF9MSU1JVFMoZmxvYXQsIEZMVCkKK0RFQ0xfRlBfTElNSVRTKGRvdWJsZSwgREJMKQorREVDTF9GUF9MSU1JVFMobG9uZyBkb3VibGUsIExEQkwpCisKKyN1bmRlZiBERUNMX0ZQX0xJTUlUUworI3VuZGVmIERFQ0xfRlBfTElNSVRfRlVOQ1MKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAvLworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKyNlbmRpZiAgLy8gVVRJTF9NQVRIX01BVEhMSU1JVFNfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL21hdGh1dGlsLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL21hdGh1dGlsLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2ExZWY4YQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvbWF0aHV0aWwuaApAQCAtMCwwICsxLDE2MiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9TVFVCU19NQVRIVVRJTF9IXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfU1RVQlNfTUFUSFVUSUxfSF8KKworI2luY2x1ZGUgPGZsb2F0Lmg+CisjaW5jbHVkZSA8bWF0aC5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9sb2dnaW5nLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL21hdGhsaW1pdHMuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+Citib29sIElzTmFuKFQgdmFsdWUpIHsKKyAgcmV0dXJuIGZhbHNlOworfQordGVtcGxhdGU8PgoraW5saW5lIGJvb2wgSXNOYW4oZmxvYXQgdmFsdWUpIHsKKyNpZmRlZiBfTVNDX1ZFUgorICByZXR1cm4gX2lzbmFuKHZhbHVlKTsKKyNlbHNlCisgIHJldHVybiBpc25hbih2YWx1ZSk7CisjZW5kaWYKK30KK3RlbXBsYXRlPD4KK2lubGluZSBib29sIElzTmFuKGRvdWJsZSB2YWx1ZSkgeworI2lmZGVmIF9NU0NfVkVSCisgIHJldHVybiBfaXNuYW4odmFsdWUpOworI2Vsc2UKKyAgcmV0dXJuIGlzbmFuKHZhbHVlKTsKKyNlbmRpZgorfQorCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorYm9vbCBBbG1vc3RFcXVhbHMoVCBhLCBUIGIpIHsKKyAgcmV0dXJuIGEgPT0gYjsKK30KK3RlbXBsYXRlPD4KK2lubGluZSBib29sIEFsbW9zdEVxdWFscyhmbG9hdCBhLCBmbG9hdCBiKSB7CisgIHJldHVybiBmYWJzKGEgLSBiKSA8IDMyICogRkxUX0VQU0lMT047Cit9CisKK3RlbXBsYXRlPD4KK2lubGluZSBib29sIEFsbW9zdEVxdWFscyhkb3VibGUgYSwgZG91YmxlIGIpIHsKKyAgcmV0dXJuIGZhYnMoYSAtIGIpIDwgMzIgKiBEQkxfRVBTSUxPTjsKK30KK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorCitjbGFzcyBNYXRoVXRpbCB7CisgcHVibGljOgorICB0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorICBzdGF0aWMgVCBTaWduKFQgdmFsdWUpIHsKKyAgICBpZiAodmFsdWUgPT0gVCgwKSB8fCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpJc05hbjxUPih2YWx1ZSkpIHsKKyAgICAgIHJldHVybiB2YWx1ZTsKKyAgICB9CisgICAgcmV0dXJuIHZhbHVlID4gVCgwKSA/IHZhbHVlIDogLXZhbHVlOworICB9CisKKyAgdGVtcGxhdGU8dHlwZW5hbWUgVD4KKyAgc3RhdGljIGJvb2wgQWxtb3N0RXF1YWxzKFQgYSwgVCBiKSB7CisgICAgcmV0dXJuIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFsbW9zdEVxdWFscyhhLCBiKTsKKyAgfQorCisgIC8vIExhcmdlc3Qgb2YgdHdvIHZhbHVlcy4KKyAgLy8gV29ya3MgY29ycmVjdGx5IGZvciBzcGVjaWFsIGZsb2F0aW5nIHBvaW50IHZhbHVlcy4KKyAgLy8gTm90ZTogMC4wIGFuZCAtMC4wIGFyZSBub3QgZGlmZmVyZW50aWF0ZWQgYnkgTWF4IChNYXgoMC4wLCAtMC4wKSBpcyAtMC4wKSwKKyAgLy8gd2hpY2ggc2hvdWxkIGJlIE9LIGJlY2F1c2UsIGFsdGhvdWdoIHRoZXkgKGNhbikgaGF2ZSBkaWZmZXJlbnQKKyAgLy8gYml0IHJlcHJlc2VudGF0aW9uLCB0aGV5IGFyZSBvYnNlcnZhYmx5IHRoZSBzYW1lIHdoZW4gZXhhbWluZWQKKyAgLy8gd2l0aCBhcml0aG1ldGljIGFuZCAoaW4pZXF1YWxpdHkgb3BlcmF0b3JzLgorICB0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorICBzdGF0aWMgVCBNYXgoY29uc3QgVCB4LCBjb25zdCBUIHkpIHsKKyAgICByZXR1cm4gTWF0aExpbWl0czxUPjo6SXNOYU4oeCkgfHwgeCA+IHkgPyB4IDogeTsKKyAgfQorCisgIC8vIEFic29sdXRlIHZhbHVlIG9mIHgKKyAgLy8gV29ya3MgY29ycmVjdGx5IGZvciB1bnNpZ25lZCB0eXBlcyBhbmQKKyAgLy8gZm9yIHNwZWNpYWwgZmxvYXRpbmcgcG9pbnQgdmFsdWVzLgorICAvLyBOb3RlOiAwLjAgYW5kIC0wLjAgYXJlIG5vdCBkaWZmZXJlbnRpYXRlZCBieSBBYnMgKEFicygwLjApIGlzIC0wLjApLAorICAvLyB3aGljaCBzaG91bGQgYmUgT0s6IHNlZSB0aGUgY29tbWVudCBmb3IgTWF4IGFib3ZlLgorICB0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorICBzdGF0aWMgVCBBYnMoY29uc3QgVCB4KSB7CisgICAgcmV0dXJuIHggPiBUKDApID8geCA6IC14OworICB9CisKKyAgLy8gQWJzb2x1dGUgdmFsdWUgb2YgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0d28gbnVtYmVycy4KKyAgLy8gV29ya3MgY29ycmVjdGx5IGZvciBzaWduZWQgdHlwZXMgYW5kIHNwZWNpYWwgZmxvYXRpbmcgcG9pbnQgdmFsdWVzLgorICB0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorICBzdGF0aWMgdHlwZW5hbWUgTWF0aExpbWl0czxUPjo6VW5zaWduZWRUeXBlIEFic0RpZmYoY29uc3QgVCB4LCBjb25zdCBUIHkpIHsKKyAgICAvLyBDYXJyaWVzIG91dCBhcml0aG1ldGljIGFzIHVuc2lnbmVkIHRvIGF2b2lkIG92ZXJmbG93LgorICAgIHR5cGVkZWYgdHlwZW5hbWUgTWF0aExpbWl0czxUPjo6VW5zaWduZWRUeXBlIFI7CisgICAgcmV0dXJuIHggPiB5ID8gUih4KSAtIFIoeSkgOiBSKHkpIC0gUih4KTsKKyAgfQorCisgIC8vIElmIHR3byAodXN1YWxseSBmbG9hdGluZyBwb2ludCkgbnVtYmVycyBhcmUgd2l0aGluIGEgY2VydGFpbgorICAvLyBmcmFjdGlvbiBvZiB0aGVpciBtYWduaXR1ZGUgb3Igd2l0aGluIGEgY2VydGFpbiBhYnNvbHV0ZSBtYXJnaW4gb2YgZXJyb3IuCisgIC8vIFRoaXMgaXMgdGhlIHNhbWUgYXMgdGhlIGZvbGxvd2luZyBidXQgZmFzdGVyOgorICAvLyAgIFdpdGhpbkZyYWN0aW9uKHgsIHksIGZyYWN0aW9uKSAgfHwgIFdpdGhpbk1hcmdpbih4LCB5LCBtYXJnaW4pCisgIC8vIEUuZy4gV2l0aGluRnJhY3Rpb24oMC4wLCAxZS0xMCwgMWUtNSkgaXMgZmFsc2UgYnV0CisgIC8vICAgICAgV2l0aGluRnJhY3Rpb25Pck1hcmdpbigwLjAsIDFlLTEwLCAxZS01LCAxZS01KSBpcyB0cnVlLgorICB0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorICBzdGF0aWMgYm9vbCBXaXRoaW5GcmFjdGlvbk9yTWFyZ2luKGNvbnN0IFQgeCwgY29uc3QgVCB5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFQgZnJhY3Rpb24sIGNvbnN0IFQgbWFyZ2luKTsKK307CisKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+Citib29sIE1hdGhVdGlsOjpXaXRoaW5GcmFjdGlvbk9yTWFyZ2luKGNvbnN0IFQgeCwgY29uc3QgVCB5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUIGZyYWN0aW9uLCBjb25zdCBUIG1hcmdpbikgeworICAvLyBOb3QganVzdCAiMCA8PSBmcmFjdGlvbiIgdG8gZm9vbCB0aGUgY29tcGlsZXIgZm9yIHVuc2lnbmVkIHR5cGVzLgorICBHT09HTEVfRENIRUNLKChUKDApIDwgZnJhY3Rpb24gfHwgVCgwKSA9PSBmcmFjdGlvbikgJiYKKyAgICAgICAgIGZyYWN0aW9uIDwgVCgxKSAmJgorICAgICAgICAgbWFyZ2luID49IFQoMCkpOworCisgIC8vIFRlbXBsYXRlIHNwZWNpYWxpemF0aW9uIHdpbGwgY29udmVydCB0aGUgaWYoKSBjb25kaXRpb24gdG8gYSBjb25zdGFudCwKKyAgLy8gd2hpY2ggd2lsbCBjYXVzZSB0aGUgY29tcGlsZXIgdG8gZ2VuZXJhdGUgY29kZSBmb3IgZWl0aGVyIHRoZSAiaWYiIHBhcnQKKyAgLy8gb3IgdGhlICJ0aGVuIiBwYXJ0LiAgSW4gdGhpcyB3YXkgd2UgYXZvaWQgYSBjb21waWxlciB3YXJuaW5nCisgIC8vIGFib3V0IGEgcG90ZW50aWFsIGludGVnZXIgb3ZlcmZsb3cgaW4gY3Jvc3N0b29sIHYxMiAoZ2NjIDQuMy4xKS4KKyAgaWYgKE1hdGhMaW1pdHM8VD46OmtJc0ludGVnZXIpIHsKKyAgICByZXR1cm4geCA9PSB5OworICB9IGVsc2UgeworICAgIC8vIElzRmluaXRlIGNoZWNrcyBhcmUgdG8gbWFrZSBrUG9zSW5mIGFuZCBrTmVnSW5mIG5vdCB3aXRoaW4gZnJhY3Rpb24KKyAgICBpZiAoIU1hdGhMaW1pdHM8VD46OklzRmluaXRlKHgpICYmICFNYXRoTGltaXRzPFQ+OjpJc0Zpbml0ZSh5KSkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBUIHJlbGF0aXZlX21hcmdpbiA9IHN0YXRpY19jYXN0PFQ+KGZyYWN0aW9uICogTWF4KEFicyh4KSwgQWJzKHkpKSk7CisgICAgcmV0dXJuIEFic0RpZmYoeCwgeSkgPD0gTWF4KG1hcmdpbiwgcmVsYXRpdmVfbWFyZ2luKTsKKyAgfQorfQorCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfU1RVQlNfTUFUSFVUSUxfSF8KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvbXV0ZXguaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvbXV0ZXguaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ZWYxY2I2Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9tdXRleC5oCkBAIC0wLDAgKzEsMTQ4IEBACisvLyBDb3B5cmlnaHQgKGMpIDIwMDYsIEdvb2dsZSBJbmMuCisvLyBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9TVFVCU19NVVRFWF9IXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfU1RVQlNfTVVURVhfSF8KKworI2lmZGVmIEdPT0dMRV9QUk9UT0JVRl9OT19USFJFQURMT0NBTAorI2luY2x1ZGUgPHB0aHJlYWQuaD4KKyNlbmRpZgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL21hY3Jvcy5oPgorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisvLyBlbXVsYXRlcyBnb29nbGUzL2Jhc2UvbXV0ZXguaAorbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKworLy8gQSBNdXRleCBpcyBhIG5vbi1yZWVudHJhbnQgKGFrYSBub24tcmVjdXJzaXZlKSBtdXRleC4gIEF0IG1vc3Qgb25lIHRocmVhZCBUCisvLyBtYXkgaG9sZCBhIG11dGV4IGF0IGEgZ2l2ZW4gdGltZS4gIElmIFQgYXR0ZW1wdHMgdG8gTG9jaygpIHRoZSBzYW1lIE11dGV4CisvLyB3aGlsZSBob2xkaW5nIGl0LCBUIHdpbGwgZGVhZGxvY2suCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgTXV0ZXggeworIHB1YmxpYzoKKyAgLy8gQ3JlYXRlIGEgTXV0ZXggdGhhdCBpcyBub3QgaGVsZCBieSBhbnlib2R5LgorICBNdXRleCgpOworCisgIC8vIERlc3RydWN0b3IKKyAgfk11dGV4KCk7CisKKyAgLy8gQmxvY2sgaWYgbmVjZXNzYXJ5IHVudGlsIHRoaXMgTXV0ZXggaXMgZnJlZSwgdGhlbiBhY3F1aXJlIGl0IGV4Y2x1c2l2ZWx5LgorICB2b2lkIExvY2soKTsKKworICAvLyBSZWxlYXNlIHRoaXMgTXV0ZXguICBDYWxsZXIgbXVzdCBob2xkIGl0IGV4Y2x1c2l2ZWx5LgorICB2b2lkIFVubG9jaygpOworCisgIC8vIENyYXNoIGlmIHRoaXMgTXV0ZXggaXMgbm90IGhlbGQgZXhjbHVzaXZlbHkgYnkgdGhpcyB0aHJlYWQuCisgIC8vIE1heSBmYWlsIHRvIGNyYXNoIHdoZW4gaXQgc2hvdWxkOyB3aWxsIG5ldmVyIGNyYXNoIHdoZW4gaXQgc2hvdWxkIG5vdC4KKyAgdm9pZCBBc3NlcnRIZWxkKCk7CisKKyBwcml2YXRlOgorICBzdHJ1Y3QgSW50ZXJuYWw7CisgIEludGVybmFsKiBtSW50ZXJuYWw7CisKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKE11dGV4KTsKK307CisKKy8vIFVuZGVmaW5lIHRoZSBtYWNyb3MgIHRvIHdvcmthcm91bmQgdGhlIGNvbmZsaWN0cyB3aXRoIEdvb2dsZSBpbnRlcm5hbAorLy8gTXV0ZXhMb2NrIGltcGxlbWVudGF0aW9uLgorLy8gVE9ETyhsaXVqaXNpKTogUmVtb3ZlIHRoZSB1bmRlZiBvbmNlIGludGVybmFsIG1hY3JvcyBhcmUgcmVtb3ZlZC4KKyN1bmRlZiBNdXRleExvY2sKKyN1bmRlZiBSZWFkZXJNdXRleExvY2sKKyN1bmRlZiBXcml0ZXJNdXRleExvY2sKKyN1bmRlZiBNdXRleExvY2tNYXliZQorCisvLyBNdXRleExvY2sobXUpIGFjcXVpcmVzIG11IHdoZW4gY29uc3RydWN0ZWQgYW5kIHJlbGVhc2VzIGl0IHdoZW4gZGVzdHJveWVkLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIE11dGV4TG9jayB7CisgcHVibGljOgorICBleHBsaWNpdCBNdXRleExvY2soTXV0ZXggKm11KSA6IG11XyhtdSkgeyB0aGlzLT5tdV8tPkxvY2soKTsgfQorICB+TXV0ZXhMb2NrKCkgeyB0aGlzLT5tdV8tPlVubG9jaygpOyB9CisgcHJpdmF0ZToKKyAgTXV0ZXggKmNvbnN0IG11XzsKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKE11dGV4TG9jayk7Cit9OworCisvLyBUT0RPKGtlbnRvbik6ICBJbXBsZW1lbnQgdGhlc2U/ICBIYXJkIHRvIGltcGxlbWVudCBwb3J0YWJseS4KK3R5cGVkZWYgTXV0ZXhMb2NrIFJlYWRlck11dGV4TG9jazsKK3R5cGVkZWYgTXV0ZXhMb2NrIFdyaXRlck11dGV4TG9jazsKKworLy8gTXV0ZXhMb2NrTWF5YmUgaXMgbGlrZSBNdXRleExvY2ssIGJ1dCBpcyBhIG5vLW9wIHdoZW4gbXUgaXMgTlVMTC4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBNdXRleExvY2tNYXliZSB7CisgcHVibGljOgorICBleHBsaWNpdCBNdXRleExvY2tNYXliZShNdXRleCAqbXUpIDoKKyAgICBtdV8obXUpIHsgaWYgKHRoaXMtPm11XyAhPSBOVUxMKSB7IHRoaXMtPm11Xy0+TG9jaygpOyB9IH0KKyAgfk11dGV4TG9ja01heWJlKCkgeyBpZiAodGhpcy0+bXVfICE9IE5VTEwpIHsgdGhpcy0+bXVfLT5VbmxvY2soKTsgfSB9CisgcHJpdmF0ZToKKyAgTXV0ZXggKmNvbnN0IG11XzsKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKE11dGV4TG9ja01heWJlKTsKK307CisKKyNpZiBkZWZpbmVkKEdPT0dMRV9QUk9UT0JVRl9OT19USFJFQURMT0NBTCkKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+CitjbGFzcyBUaHJlYWRMb2NhbFN0b3JhZ2UgeworIHB1YmxpYzoKKyAgVGhyZWFkTG9jYWxTdG9yYWdlKCkgeworICAgIHB0aHJlYWRfa2V5X2NyZWF0ZSgma2V5XywgJlRocmVhZExvY2FsU3RvcmFnZTo6RGVsZXRlKTsKKyAgfQorICB+VGhyZWFkTG9jYWxTdG9yYWdlKCkgeworICAgIHB0aHJlYWRfa2V5X2RlbGV0ZShrZXlfKTsKKyAgfQorICBUKiBHZXQoKSB7CisgICAgVCogcmVzdWx0ID0gc3RhdGljX2Nhc3Q8VCo+KHB0aHJlYWRfZ2V0c3BlY2lmaWMoa2V5XykpOworICAgIGlmIChyZXN1bHQgPT0gTlVMTCkgeworICAgICAgcmVzdWx0ID0gbmV3IFQoKTsKKyAgICAgIHB0aHJlYWRfc2V0c3BlY2lmaWMoa2V5XywgcmVzdWx0KTsKKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorIHByaXZhdGU6CisgIHN0YXRpYyB2b2lkIERlbGV0ZSh2b2lkKiB2YWx1ZSkgeworICAgIGRlbGV0ZSBzdGF0aWNfY2FzdDxUKj4odmFsdWUpOworICB9CisgIHB0aHJlYWRfa2V5X3Qga2V5XzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoVGhyZWFkTG9jYWxTdG9yYWdlKTsKK307CisjZW5kaWYKKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCisKKy8vIFdlIG1hZGUgdGhlc2UgaW50ZXJuYWwgc28gdGhhdCB0aGV5IHdvdWxkIHNob3cgdXAgYXMgc3VjaCBpbiB0aGUgZG9jcywKKy8vIGJ1dCB3ZSBkb24ndCB3YW50IHRvIHN0aWNrICJpbnRlcm5hbDo6IiBpbiBmcm9udCBvZiB0aGVtIGV2ZXJ5d2hlcmUuCit1c2luZyBpbnRlcm5hbDo6TXV0ZXg7Cit1c2luZyBpbnRlcm5hbDo6TXV0ZXhMb2NrOwordXNpbmcgaW50ZXJuYWw6OlJlYWRlck11dGV4TG9jazsKK3VzaW5nIGludGVybmFsOjpXcml0ZXJNdXRleExvY2s7Cit1c2luZyBpbnRlcm5hbDo6TXV0ZXhMb2NrTWF5YmU7CisKKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX1NUVUJTX01VVEVYX0hfCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL29uY2UuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL29uY2UuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODg5YzY0NwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvb25jZS5jYwpAQCAtMCwwICsxLDk5IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8KKy8vIGVtdWxhdGVzIGdvb2dsZTMvYmFzZS9vbmNlLmgKKy8vCisvLyBUaGlzIGhlYWRlciBpcyBpbnRlbmRlZCB0byBiZSBpbmNsdWRlZCBvbmx5IGJ5IGludGVybmFsIC5jYyBmaWxlcyBhbmQKKy8vIGdlbmVyYXRlZCAucGIuY2MgZmlsZXMuICBVc2VycyBzaG91bGQgbm90IHVzZSB0aGlzIGRpcmVjdGx5LgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL29uY2UuaD4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfTk9fVEhSRUFEX1NBRkVUWQorCisjaWZkZWYgX1dJTjMyCisjaW5jbHVkZSA8d2luZG93cy5oPgorI2Vsc2UKKyNpbmNsdWRlIDxzY2hlZC5oPgorI2VuZGlmCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvYXRvbWljb3BzLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworbmFtZXNwYWNlIHsKKwordm9pZCBTY2hlZFlpZWxkKCkgeworI2lmZGVmIF9XSU4zMgorICBTbGVlcCgwKTsKKyNlbHNlICAvLyBQT1NJWAorICBzY2hlZF95aWVsZCgpOworI2VuZGlmCit9CisKK30gIC8vIG5hbWVzcGFjZQorCit2b2lkIEdvb2dsZU9uY2VJbml0SW1wbChQcm90b2J1Zk9uY2VUeXBlKiBvbmNlLCBDbG9zdXJlKiBjbG9zdXJlKSB7CisgIGludGVybmFsOjpBdG9taWNXb3JkIHN0YXRlID0gaW50ZXJuYWw6OkFjcXVpcmVfTG9hZChvbmNlKTsKKyAgLy8gRmFzdCBwYXRoLiBUaGUgcHJvdmlkZWQgY2xvc3VyZSB3YXMgYWxyZWFkeSBleGVjdXRlZC4KKyAgaWYgKHN0YXRlID09IE9OQ0VfU1RBVEVfRE9ORSkgeworICAgIHJldHVybjsKKyAgfQorICAvLyBUaGUgY2xvc3VyZSBleGVjdXRpb24gZGlkIG5vdCBjb21wbGV0ZSB5ZXQuIFRoZSBvbmNlIG9iamVjdCBjYW4gYmUgaW4gb25lCisgIC8vIG9mIHRoZSB0d28gZm9sbG93aW5nIHN0YXRlczoKKyAgLy8gICAtIFVOSU5JVElBTElaRUQ6IFdlIGFyZSB0aGUgZmlyc3QgdGhyZWFkIGNhbGxpbmcgdGhpcyBmdW5jdGlvbi4KKyAgLy8gICAtIEVYRUNVVElOR19DTE9TVVJFOiBBbm90aGVyIHRocmVhZCBpcyBhbHJlYWR5IGV4ZWN1dGluZyB0aGUgY2xvc3VyZS4KKyAgLy8KKyAgLy8gRmlyc3QsIHRyeSB0byBjaGFuZ2UgdGhlIHN0YXRlIGZyb20gVU5JTklUSUFMSVpFRCB0byBFWEVDVVRJTkdfQ0xPU1VSRQorICAvLyBhdG9taWNhbGx5LgorICBzdGF0ZSA9IGludGVybmFsOjpBY3F1aXJlX0NvbXBhcmVBbmRTd2FwKAorICAgICAgb25jZSwgT05DRV9TVEFURV9VTklOSVRJQUxJWkVELCBPTkNFX1NUQVRFX0VYRUNVVElOR19DTE9TVVJFKTsKKyAgaWYgKHN0YXRlID09IE9OQ0VfU1RBVEVfVU5JTklUSUFMSVpFRCkgeworICAgIC8vIFdlIGFyZSB0aGUgZmlyc3QgdGhyZWFkIHRvIGNhbGwgdGhpcyBmdW5jdGlvbiwgc28gd2UgaGF2ZSB0byBjYWxsIHRoZQorICAgIC8vIGNsb3N1cmUuCisgICAgY2xvc3VyZS0+UnVuKCk7CisgICAgaW50ZXJuYWw6OlJlbGVhc2VfU3RvcmUob25jZSwgT05DRV9TVEFURV9ET05FKTsKKyAgfSBlbHNlIHsKKyAgICAvLyBBbm90aGVyIHRocmVhZCBoYXMgYWxyZWFkeSBzdGFydGVkIGV4ZWN1dGluZyB0aGUgY2xvc3VyZS4gV2UgbmVlZCB0bworICAgIC8vIHdhaXQgdW50aWwgaXQgY29tcGxldGVzIHRoZSBpbml0aWFsaXphdGlvbi4KKyAgICB3aGlsZSAoc3RhdGUgPT0gT05DRV9TVEFURV9FWEVDVVRJTkdfQ0xPU1VSRSkgeworICAgICAgLy8gTm90ZSB0aGF0IGZ1dGV4KCkgY291bGQgYmUgdXNlZCBoZXJlIG9uIExpbnV4IGFzIGFuIGltcHJvdmVtZW50LgorICAgICAgU2NoZWRZaWVsZCgpOworICAgICAgc3RhdGUgPSBpbnRlcm5hbDo6QWNxdWlyZV9Mb2FkKG9uY2UpOworICAgIH0KKyAgfQorfQorCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfTk9fVEhSRUFEX1NBRkVUWQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9vbmNlLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL29uY2UuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZjA4MmMzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9vbmNlLmgKQEAgLTAsMCArMSwxNjcgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLworLy8gZW11bGF0ZXMgZ29vZ2xlMy9iYXNlL29uY2UuaAorLy8KKy8vIFRoaXMgaGVhZGVyIGlzIGludGVuZGVkIHRvIGJlIGluY2x1ZGVkIG9ubHkgYnkgaW50ZXJuYWwgLmNjIGZpbGVzIGFuZAorLy8gZ2VuZXJhdGVkIC5wYi5jYyBmaWxlcy4gIFVzZXJzIHNob3VsZCBub3QgdXNlIHRoaXMgZGlyZWN0bHkuCisvLworLy8gVGhpcyBpcyBiYXNpY2FsbHkgYSBwb3J0YWJsZSB2ZXJzaW9uIG9mIHB0aHJlYWRfb25jZSgpLgorLy8KKy8vIFRoaXMgaGVhZGVyIGRlY2xhcmVzOgorLy8gKiBBIHR5cGUgY2FsbGVkIFByb3RvYnVmT25jZVR5cGUuCisvLyAqIEEgbWFjcm8gR09PR0xFX1BST1RPQlVGX0RFQ0xBUkVfT05DRSgpIHdoaWNoIGRlY2xhcmVzIGEgdmFyaWFibGUgb2YgdHlwZQorLy8gICBQcm90b2J1Zk9uY2VUeXBlLiAgVGhpcyBpcyB0aGUgb25seSBsZWdhbCB3YXkgdG8gZGVjbGFyZSBzdWNoIGEgdmFyaWFibGUuCisvLyAgIFRoZSBtYWNybyBtYXkgb25seSBiZSB1c2VkIGF0IHRoZSBnbG9iYWwgc2NvcGUgKHlvdSBjYW5ub3QgY3JlYXRlIGxvY2FsIG9yCisvLyAgIGNsYXNzIG1lbWJlciB2YXJpYWJsZXMgb2YgdGhpcyB0eXBlKS4KKy8vICogQSBmdW5jdGlvbiBHb29nbGVPbmNlSW5pdChQcm90b2J1Zk9uY2VUeXBlKiBvbmNlLCB2b2lkICgqaW5pdF9mdW5jKSgpKS4KKy8vICAgVGhpcyBmdW5jdGlvbiwgd2hlbiBpbnZva2VkIG11bHRpcGxlIHRpbWVzIGdpdmVuIHRoZSBzYW1lIFByb3RvYnVmT25jZVR5cGUKKy8vICAgb2JqZWN0LCB3aWxsIGludm9rZSBpbml0X2Z1bmMgb24gdGhlIGZpcnN0IGNhbGwgb25seSwgYW5kIHdpbGwgbWFrZSBzdXJlCisvLyAgIG5vbmUgb2YgdGhlIGNhbGxzIHJldHVybiBiZWZvcmUgdGhhdCBmaXJzdCBjYWxsIHRvIGluaXRfZnVuYyBoYXMgZmluaXNoZWQuCisvLyAqIFRoZSB1c2VyIGNhbiBwcm92aWRlIGEgcGFyYW1ldGVyIHdoaWNoIEdvb2dsZU9uY2VJbml0KCkgZm9yd2FyZHMgdG8gdGhlCisvLyAgIHVzZXItcHJvdmlkZWQgZnVuY3Rpb24gd2hlbiBpdCBpcyBjYWxsZWQuIFVzYWdlIGV4YW1wbGU6CisvLyAgICAgaW50IGEgPSAxMDsKKy8vICAgICBHb29nbGVPbmNlSW5pdCgmbXlfb25jZSwgJk15RnVuY3Rpb25FeHBlY3RpbmdJbnRBcmd1bWVudCwgJmEpOworLy8gKiBUaGlzIGltcGxlbWVudGF0aW9uIGd1YXJhbnRlZXMgdGhhdCBQcm90b2J1Zk9uY2VUeXBlIGlzIGEgUE9EIChpLmUuIG5vCisvLyAgIHN0YXRpYyBpbml0aWFsaXplciBnZW5lcmF0ZWQpLgorLy8KKy8vIFRoaXMgaW1wbGVtZW50cyBhIHdheSB0byBwZXJmb3JtIGxhenkgaW5pdGlhbGl6YXRpb24uICBJdCdzIG1vcmUgZWZmaWNpZW50CisvLyB0aGFuIHVzaW5nIG11dGV4ZXMgYXMgbm8gbG9jayBpcyBuZWVkZWQgaWYgaW5pdGlhbGl6YXRpb24gaGFzIGFscmVhZHkKKy8vIGhhcHBlbmVkLgorLy8KKy8vIEV4YW1wbGUgdXNhZ2U6CisvLyAgIHZvaWQgSW5pdCgpOworLy8gICBHT09HTEVfUFJPVE9CVUZfREVDTEFSRV9PTkNFKG9uY2VfaW5pdCk7CisvLworLy8gICAvLyBDYWxscyBJbml0KCkgZXhhY3RseSBvbmNlLgorLy8gICB2b2lkIEluaXRPbmNlKCkgeworLy8gICAgIEdvb2dsZU9uY2VJbml0KCZvbmNlX2luaXQsICZJbml0KTsKKy8vICAgfQorLy8KKy8vIE5vdGUgdGhhdCBpZiBHb29nbGVPbmNlSW5pdCgpIGlzIGNhbGxlZCBiZWZvcmUgbWFpbigpIGhhcyBiZWd1biwgaXQgbXVzdAorLy8gb25seSBiZSBjYWxsZWQgYnkgdGhlIHRocmVhZCB0aGF0IHdpbGwgZXZlbnR1YWxseSBjYWxsIG1haW4oKSAtLSB0aGF0IGlzLAorLy8gdGhlIHRocmVhZCB0aGF0IHBlcmZvcm1zIGR5bmFtaWMgaW5pdGlhbGl6YXRpb24uICBJbiBnZW5lcmFsIHRoaXMgaXMgYSBzYWZlCisvLyBhc3N1bXB0aW9uIHNpbmNlIHBlb3BsZSBkb24ndCB1c3VhbGx5IGNvbnN0cnVjdCB0aHJlYWRzIGJlZm9yZSBtYWluKCkgc3RhcnRzLAorLy8gYnV0IGl0IGlzIHRlY2huaWNhbGx5IG5vdCBndWFyYW50ZWVkLiAgVW5mb3J0dW5hdGVseSwgV2luMzIgcHJvdmlkZXMgbm8gd2F5CisvLyB3aGF0c29ldmVyIHRvIHN0YXRpY2FsbHktaW5pdGlhbGl6ZSBpdHMgc3luY2hyb25pemF0aW9uIHByaW1pdGl2ZXMsIHNvIG91cgorLy8gb25seSBjaG9pY2UgaXMgdG8gYXNzdW1lIHRoYXQgZHluYW1pYyBpbml0aWFsaXphdGlvbiBpcyBzaW5nbGUtdGhyZWFkZWQuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX1NUVUJTX09OQ0VfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9TVFVCU19PTkNFX0hfXworCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wcy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jYWxsYmFjay5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCisjaWZkZWYgR09PR0xFX1BST1RPQlVGX05PX1RIUkVBRF9TQUZFVFkKKwordHlwZWRlZiBib29sIFByb3RvYnVmT25jZVR5cGU7CisKKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX09OQ0VfSU5JVCBmYWxzZQorCitpbmxpbmUgdm9pZCBHb29nbGVPbmNlSW5pdChQcm90b2J1Zk9uY2VUeXBlKiBvbmNlLCB2b2lkICgqaW5pdF9mdW5jKSgpKSB7CisgIGlmICghKm9uY2UpIHsKKyAgICAqb25jZSA9IHRydWU7CisgICAgaW5pdF9mdW5jKCk7CisgIH0KK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEFyZz4KK2lubGluZSB2b2lkIEdvb2dsZU9uY2VJbml0KFByb3RvYnVmT25jZVR5cGUqIG9uY2UsIHZvaWQgKCppbml0X2Z1bmMpKEFyZyksCisgICAgQXJnIGFyZykgeworICBpZiAoISpvbmNlKSB7CisgICAgKm9uY2UgPSB0cnVlOworICAgIGluaXRfZnVuYyhhcmcpOworICB9Cit9CisKKyNlbHNlCisKK2VudW0geworICBPTkNFX1NUQVRFX1VOSU5JVElBTElaRUQgPSAwLAorICBPTkNFX1NUQVRFX0VYRUNVVElOR19DTE9TVVJFID0gMSwKKyAgT05DRV9TVEFURV9ET05FID0gMgorfTsKKwordHlwZWRlZiBpbnRlcm5hbDo6QXRvbWljV29yZCBQcm90b2J1Zk9uY2VUeXBlOworCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9PTkNFX0lOSVQgOjpnb29nbGU6OnByb3RvYnVmOjpPTkNFX1NUQVRFX1VOSU5JVElBTElaRUQKKworTElCUFJPVE9CVUZfRVhQT1JUCit2b2lkIEdvb2dsZU9uY2VJbml0SW1wbChQcm90b2J1Zk9uY2VUeXBlKiBvbmNlLCBDbG9zdXJlKiBjbG9zdXJlKTsKKworaW5saW5lIHZvaWQgR29vZ2xlT25jZUluaXQoUHJvdG9idWZPbmNlVHlwZSogb25jZSwgdm9pZCAoKmluaXRfZnVuYykoKSkgeworICBpZiAoaW50ZXJuYWw6OkFjcXVpcmVfTG9hZChvbmNlKSAhPSBPTkNFX1NUQVRFX0RPTkUpIHsKKyAgICBpbnRlcm5hbDo6RnVuY3Rpb25DbG9zdXJlMCBmdW5jKGluaXRfZnVuYywgZmFsc2UpOworICAgIEdvb2dsZU9uY2VJbml0SW1wbChvbmNlLCAmZnVuYyk7CisgIH0KK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEFyZz4KK2lubGluZSB2b2lkIEdvb2dsZU9uY2VJbml0KFByb3RvYnVmT25jZVR5cGUqIG9uY2UsIHZvaWQgKCppbml0X2Z1bmMpKEFyZyopLAorICAgIEFyZyogYXJnKSB7CisgIGlmIChpbnRlcm5hbDo6QWNxdWlyZV9Mb2FkKG9uY2UpICE9IE9OQ0VfU1RBVEVfRE9ORSkgeworICAgIGludGVybmFsOjpGdW5jdGlvbkNsb3N1cmUxPEFyZyo+IGZ1bmMoaW5pdF9mdW5jLCBmYWxzZSwgYXJnKTsKKyAgICBHb29nbGVPbmNlSW5pdEltcGwob25jZSwgJmZ1bmMpOworICB9Cit9CisKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX05PX1RIUkVBRF9TQUZFVFkKKworY2xhc3MgR29vZ2xlT25jZUR5bmFtaWMgeworIHB1YmxpYzoKKyAgR29vZ2xlT25jZUR5bmFtaWMoKSA6IHN0YXRlXyhHT09HTEVfUFJPVE9CVUZfT05DRV9JTklUKSB7IH0KKworICAvLyBJZiB0aGlzLT5Jbml0KCkgaGFzIG5vdCBiZWVuIGNhbGxlZCBiZWZvcmUgYnkgYW55IHRocmVhZCwKKyAgLy8gZXhlY3V0ZSAoKmZ1bmNfd2l0aF9hcmcpKGFyZykgdGhlbiByZXR1cm4uCisgIC8vIE90aGVyd2lzZSwgd2FpdCB1bnRpbCB0aGF0IHByaW9yIGludm9jYXRpb24gaGFzIGZpbmlzaGVkCisgIC8vIGV4ZWN1dGluZyBpdHMgZnVuY3Rpb24sIHRoZW4gcmV0dXJuLgorICB0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorICB2b2lkIEluaXQodm9pZCAoKmZ1bmNfd2l0aF9hcmcpKFQqKSwgVCogYXJnKSB7CisgICAgR29vZ2xlT25jZUluaXQ8VD4oJnRoaXMtPnN0YXRlXywKKyAgICAgICAgICAgICAgICAgICAgICBmdW5jX3dpdGhfYXJnLAorICAgICAgICAgICAgICAgICAgICAgIGFyZyk7CisgIH0KKyBwcml2YXRlOgorICBQcm90b2J1Zk9uY2VUeXBlIHN0YXRlXzsKK307CisKKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0RFQ0xBUkVfT05DRShOQU1FKSBcCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UHJvdG9idWZPbmNlVHlwZSBOQU1FID0gR09PR0xFX1BST1RPQlVGX09OQ0VfSU5JVAorCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfU1RVQlNfT05DRV9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvb25jZV91bml0dGVzdC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvb25jZV91bml0dGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zN2RlZjU4Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9vbmNlX3VuaXR0ZXN0LmNjCkBAIC0wLDAgKzEsMjU1IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorCisjaWZkZWYgX1dJTjMyCisjaW5jbHVkZSA8d2luZG93cy5oPgorI2Vsc2UKKyNpbmNsdWRlIDx1bmlzdGQuaD4KKyNpbmNsdWRlIDxwdGhyZWFkLmg+CisjZW5kaWYKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9vbmNlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZ29vZ2xldGVzdC5oPgorI2luY2x1ZGUgPGd0ZXN0L2d0ZXN0Lmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK3VzaW5nIGludGVybmFsOjpOZXdDYWxsYmFjazsKK25hbWVzcGFjZSB7CisKK2NsYXNzIE9uY2VJbml0VGVzdCA6IHB1YmxpYyB0ZXN0aW5nOjpUZXN0IHsKKyBwcm90ZWN0ZWQ6CisgIHZvaWQgU2V0VXAoKSB7CisgICAgc3RhdGVfID0gSU5JVF9OT1RfU1RBUlRFRDsKKyAgICBjdXJyZW50X3Rlc3RfID0gdGhpczsKKyAgfQorCisgIC8vIFNpbmNlIFByb3RvYnVmT25jZVR5cGUgaXMgb25seSBhbGxvd2VkIHRvIGJlIGFsbG9jYXRlZCBpbiBzdGF0aWMgc3RvcmFnZSwKKyAgLy8gZWFjaCB0ZXN0IG11c3QgdXNlIGEgZGlmZmVyZW50IHBhaXIgb2YgUHJvdG9idWZPbmNlVHlwZSBvYmplY3RzIHdoaWNoIGl0CisgIC8vIG11c3QgZGVjbGFyZSBpdHNlbGYuCisgIHZvaWQgU2V0T25jZXMoUHJvdG9idWZPbmNlVHlwZSogb25jZSwgUHJvdG9idWZPbmNlVHlwZSogcmVjdXJzaXZlX29uY2UpIHsKKyAgICBvbmNlXyA9IG9uY2U7CisgICAgcmVjdXJzaXZlX29uY2VfID0gcmVjdXJzaXZlX29uY2U7CisgIH0KKworICB2b2lkIEluaXRPbmNlKCkgeworICAgIEdvb2dsZU9uY2VJbml0KG9uY2VfLCAmSW5pdFN0YXRpYyk7CisgIH0KKyAgdm9pZCBJbml0UmVjdXJzaXZlT25jZSgpIHsKKyAgICBHb29nbGVPbmNlSW5pdChyZWN1cnNpdmVfb25jZV8sICZJbml0UmVjdXJzaXZlU3RhdGljKTsKKyAgfQorCisgIHZvaWQgQmxvY2tJbml0KCkgeyBpbml0X2Jsb2NrZXJfLkxvY2soKTsgfQorICB2b2lkIFVuYmxvY2tJbml0KCkgeyBpbml0X2Jsb2NrZXJfLlVubG9jaygpOyB9CisKKyAgY2xhc3MgVGVzdFRocmVhZCB7CisgICBwdWJsaWM6CisgICAgVGVzdFRocmVhZChDbG9zdXJlKiBjYWxsYmFjaykKKyAgICAgICAgOiBkb25lXyhmYWxzZSksIGpvaW5lZF8oZmFsc2UpLCBjYWxsYmFja18oY2FsbGJhY2spIHsKKyNpZmRlZiBfV0lOMzIKKyAgICAgIHRocmVhZF8gPSBDcmVhdGVUaHJlYWQoTlVMTCwgMCwgJlN0YXJ0LCB0aGlzLCAwLCBOVUxMKTsKKyNlbHNlCisgICAgICBwdGhyZWFkX2NyZWF0ZSgmdGhyZWFkXywgTlVMTCwgJlN0YXJ0LCB0aGlzKTsKKyNlbmRpZgorICAgIH0KKyAgICB+VGVzdFRocmVhZCgpIHsKKyAgICAgIGlmICgham9pbmVkXykgSm9pbigpOworICAgIH0KKworICAgIGJvb2wgSXNEb25lKCkgeworICAgICAgTXV0ZXhMb2NrIGxvY2soJmRvbmVfbXV0ZXhfKTsKKyAgICAgIHJldHVybiBkb25lXzsKKyAgICB9CisgICAgdm9pZCBKb2luKCkgeworICAgICAgam9pbmVkXyA9IHRydWU7CisjaWZkZWYgX1dJTjMyCisgICAgICBXYWl0Rm9yU2luZ2xlT2JqZWN0KHRocmVhZF8sIElORklOSVRFKTsKKyAgICAgIENsb3NlSGFuZGxlKHRocmVhZF8pOworI2Vsc2UKKyAgICAgIHB0aHJlYWRfam9pbih0aHJlYWRfLCBOVUxMKTsKKyNlbmRpZgorICAgIH0KKworICAgcHJpdmF0ZToKKyNpZmRlZiBfV0lOMzIKKyAgICBIQU5ETEUgdGhyZWFkXzsKKyNlbHNlCisgICAgcHRocmVhZF90IHRocmVhZF87CisjZW5kaWYKKworICAgIE11dGV4IGRvbmVfbXV0ZXhfOworICAgIGJvb2wgZG9uZV87CisgICAgYm9vbCBqb2luZWRfOworICAgIENsb3N1cmUqIGNhbGxiYWNrXzsKKworI2lmZGVmIF9XSU4zMgorICAgIHN0YXRpYyBEV09SRCBXSU5BUEkgU3RhcnQoTFBWT0lEIGFyZykgeworI2Vsc2UKKyAgICBzdGF0aWMgdm9pZCogU3RhcnQodm9pZCogYXJnKSB7CisjZW5kaWYKKyAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8VGVzdFRocmVhZCo+KGFyZyktPlJ1bigpOworICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgdm9pZCBSdW4oKSB7CisgICAgICBjYWxsYmFja18tPlJ1bigpOworICAgICAgTXV0ZXhMb2NrIGxvY2soJmRvbmVfbXV0ZXhfKTsKKyAgICAgIGRvbmVfID0gdHJ1ZTsKKyAgICB9CisgIH07CisKKyAgVGVzdFRocmVhZCogUnVuSW5pdE9uY2VJbk5ld1RocmVhZCgpIHsKKyAgICByZXR1cm4gbmV3IFRlc3RUaHJlYWQoaW50ZXJuYWw6Ok5ld0NhbGxiYWNrKHRoaXMsICZPbmNlSW5pdFRlc3Q6OkluaXRPbmNlKSk7CisgIH0KKyAgVGVzdFRocmVhZCogUnVuSW5pdFJlY3Vyc2l2ZU9uY2VJbk5ld1RocmVhZCgpIHsKKyAgICByZXR1cm4gbmV3IFRlc3RUaHJlYWQoCisgICAgICAgIGludGVybmFsOjpOZXdDYWxsYmFjayh0aGlzLCAmT25jZUluaXRUZXN0OjpJbml0UmVjdXJzaXZlT25jZSkpOworICB9CisKKyAgZW51bSBTdGF0ZSB7CisgICAgSU5JVF9OT1RfU1RBUlRFRCwKKyAgICBJTklUX1NUQVJURUQsCisgICAgSU5JVF9ET05FCisgIH07CisgIFN0YXRlIEN1cnJlbnRTdGF0ZSgpIHsKKyAgICBNdXRleExvY2sgbG9jaygmbXV0ZXhfKTsKKyAgICByZXR1cm4gc3RhdGVfOworICB9CisKKyAgdm9pZCBXYWl0QUJpdCgpIHsKKyNpZmRlZiBfV0lOMzIKKyAgICBTbGVlcCgxMDAwKTsKKyNlbHNlCisgICAgc2xlZXAoMSk7CisjZW5kaWYKKyAgfQorCisgcHJpdmF0ZToKKyAgTXV0ZXggbXV0ZXhfOworICBNdXRleCBpbml0X2Jsb2NrZXJfOworICBTdGF0ZSBzdGF0ZV87CisgIFByb3RvYnVmT25jZVR5cGUqIG9uY2VfOworICBQcm90b2J1Zk9uY2VUeXBlKiByZWN1cnNpdmVfb25jZV87CisKKyAgdm9pZCBJbml0KCkgeworICAgIE11dGV4TG9jayBsb2NrKCZtdXRleF8pOworICAgIEVYUEVDVF9FUShJTklUX05PVF9TVEFSVEVELCBzdGF0ZV8pOworICAgIHN0YXRlXyA9IElOSVRfU1RBUlRFRDsKKyAgICBtdXRleF8uVW5sb2NrKCk7CisgICAgaW5pdF9ibG9ja2VyXy5Mb2NrKCk7CisgICAgaW5pdF9ibG9ja2VyXy5VbmxvY2soKTsKKyAgICBtdXRleF8uTG9jaygpOworICAgIHN0YXRlXyA9IElOSVRfRE9ORTsKKyAgfQorCisgIHN0YXRpYyBPbmNlSW5pdFRlc3QqIGN1cnJlbnRfdGVzdF87CisgIHN0YXRpYyB2b2lkIEluaXRTdGF0aWMoKSB7IGN1cnJlbnRfdGVzdF8tPkluaXQoKTsgfQorICBzdGF0aWMgdm9pZCBJbml0UmVjdXJzaXZlU3RhdGljKCkgeyBjdXJyZW50X3Rlc3RfLT5Jbml0T25jZSgpOyB9Cit9OworCitPbmNlSW5pdFRlc3QqIE9uY2VJbml0VGVzdDo6Y3VycmVudF90ZXN0XyA9IE5VTEw7CisKK0dPT0dMRV9QUk9UT0JVRl9ERUNMQVJFX09OQ0Uoc2ltcGxlX29uY2UpOworCitURVNUX0YoT25jZUluaXRUZXN0LCBTaW1wbGUpIHsKKyAgU2V0T25jZXMoJnNpbXBsZV9vbmNlLCBOVUxMKTsKKworICBFWFBFQ1RfRVEoSU5JVF9OT1RfU1RBUlRFRCwgQ3VycmVudFN0YXRlKCkpOworICBJbml0T25jZSgpOworICBFWFBFQ1RfRVEoSU5JVF9ET05FLCBDdXJyZW50U3RhdGUoKSk7CisKKyAgLy8gQ2FsbGluZyBhZ2FpbiBoYXMgbm8gZWZmZWN0LgorICBJbml0T25jZSgpOworICBFWFBFQ1RfRVEoSU5JVF9ET05FLCBDdXJyZW50U3RhdGUoKSk7Cit9CisKK0dPT0dMRV9QUk9UT0JVRl9ERUNMQVJFX09OQ0UocmVjdXJzaXZlX29uY2UxKTsKK0dPT0dMRV9QUk9UT0JVRl9ERUNMQVJFX09OQ0UocmVjdXJzaXZlX29uY2UyKTsKKworVEVTVF9GKE9uY2VJbml0VGVzdCwgUmVjdXJzaXZlKSB7CisgIFNldE9uY2VzKCZyZWN1cnNpdmVfb25jZTEsICZyZWN1cnNpdmVfb25jZTIpOworCisgIEVYUEVDVF9FUShJTklUX05PVF9TVEFSVEVELCBDdXJyZW50U3RhdGUoKSk7CisgIEluaXRSZWN1cnNpdmVPbmNlKCk7CisgIEVYUEVDVF9FUShJTklUX0RPTkUsIEN1cnJlbnRTdGF0ZSgpKTsKK30KKworR09PR0xFX1BST1RPQlVGX0RFQ0xBUkVfT05DRShtdWx0aXBsZV90aHJlYWRzX29uY2UpOworCitURVNUX0YoT25jZUluaXRUZXN0LCBNdWx0aXBsZVRocmVhZHMpIHsKKyAgU2V0T25jZXMoJm11bHRpcGxlX3RocmVhZHNfb25jZSwgTlVMTCk7CisKKyAgc2NvcGVkX3B0cjxUZXN0VGhyZWFkPiB0aHJlYWRzWzRdOworICBFWFBFQ1RfRVEoSU5JVF9OT1RfU1RBUlRFRCwgQ3VycmVudFN0YXRlKCkpOworICBmb3IgKGludCBpID0gMDsgaSA8IDQ7IGkrKykgeworICAgIHRocmVhZHNbaV0ucmVzZXQoUnVuSW5pdE9uY2VJbk5ld1RocmVhZCgpKTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IDQ7IGkrKykgeworICAgIHRocmVhZHNbaV0tPkpvaW4oKTsKKyAgfQorICBFWFBFQ1RfRVEoSU5JVF9ET05FLCBDdXJyZW50U3RhdGUoKSk7Cit9CisKK0dPT0dMRV9QUk9UT0JVRl9ERUNMQVJFX09OQ0UobXVsdGlwbGVfdGhyZWFkc19ibG9ja2VkX29uY2UxKTsKK0dPT0dMRV9QUk9UT0JVRl9ERUNMQVJFX09OQ0UobXVsdGlwbGVfdGhyZWFkc19ibG9ja2VkX29uY2UyKTsKKworVEVTVF9GKE9uY2VJbml0VGVzdCwgTXVsdGlwbGVUaHJlYWRzQmxvY2tlZCkgeworICBTZXRPbmNlcygmbXVsdGlwbGVfdGhyZWFkc19ibG9ja2VkX29uY2UxLCAmbXVsdGlwbGVfdGhyZWFkc19ibG9ja2VkX29uY2UyKTsKKworICBzY29wZWRfcHRyPFRlc3RUaHJlYWQ+IHRocmVhZHNbOF07CisgIEVYUEVDVF9FUShJTklUX05PVF9TVEFSVEVELCBDdXJyZW50U3RhdGUoKSk7CisKKyAgQmxvY2tJbml0KCk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgNDsgaSsrKSB7CisgICAgdGhyZWFkc1tpXS5yZXNldChSdW5Jbml0T25jZUluTmV3VGhyZWFkKCkpOworICB9CisgIGZvciAoaW50IGkgPSA0OyBpIDwgODsgaSsrKSB7CisgICAgdGhyZWFkc1tpXS5yZXNldChSdW5Jbml0UmVjdXJzaXZlT25jZUluTmV3VGhyZWFkKCkpOworICB9CisKKyAgV2FpdEFCaXQoKTsKKworICAvLyBXZSBzaG91bGQgbm93IGhhdmUgb25lIHRocmVhZCBibG9ja2VkIGluc2lkZSBJbml0KCksIGZvdXIgYmxvY2tlZCB3YWl0aW5nCisgIC8vIGZvciBJbml0KCkgdG8gY29tcGxldGUsIGFuZCB0aHJlZSBibG9ja2VkIHdhaXRpbmcgZm9yIEluaXRSZWN1cnNpdmUoKSB0bworICAvLyBjb21wbGV0ZS4KKyAgRVhQRUNUX0VRKElOSVRfU1RBUlRFRCwgQ3VycmVudFN0YXRlKCkpOworICBVbmJsb2NrSW5pdCgpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgODsgaSsrKSB7CisgICAgdGhyZWFkc1tpXS0+Sm9pbigpOworICB9CisgIEVYUEVDVF9FUShJTklUX0RPTkUsIEN1cnJlbnRTdGF0ZSgpKTsKK30KKworfSAgLy8gYW5vbnltb3VzIG5hbWVzcGFjZQorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3BsYXRmb3JtX21hY3Jvcy5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9wbGF0Zm9ybV9tYWNyb3MuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMmIzNTcyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9wbGF0Zm9ybV9tYWNyb3MuaApAQCAtMCwwICsxLDEyMiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAxMiBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX1BMQVRGT1JNX01BQ1JPU19IXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfUExBVEZPUk1fTUFDUk9TX0hfCisKKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1BMQVRGT1JNX0VSUk9SIFwKKyNlcnJvciAiSG9zdCBwbGF0Zm9ybSB3YXMgbm90IGRldGVjdGVkIGFzIHN1cHBvcnRlZCBieSBwcm90b2J1ZiIKKworLy8gUHJvY2Vzc29yIGFyY2hpdGVjdHVyZSBkZXRlY3Rpb24uICBGb3IgbW9yZSBpbmZvIG9uIHdoYXQncyBkZWZpbmVkLCBzZWU6CisvLyAgIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9iMDA4NGtheS5hc3B4CisvLyAgIGh0dHA6Ly93d3cuYWduZXIub3JnL29wdGltaXplL2NhbGxpbmdfY29udmVudGlvbnMucGRmCisvLyAgIG9yIHdpdGggZ2NjLCBydW46ICJlY2hvIHwgZ2NjIC1FIC1kTSAtIgorI2lmIGRlZmluZWQoX01fWDY0KSB8fCBkZWZpbmVkKF9feDg2XzY0X18pCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9BUkNIX1g2NCAxCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9BUkNIXzY0X0JJVCAxCisjZWxpZiBkZWZpbmVkKF9NX0lYODYpIHx8IGRlZmluZWQoX19pMzg2X18pCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9BUkNIX0lBMzIgMQorI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQVJDSF8zMl9CSVQgMQorI2VsaWYgZGVmaW5lZChfX1FOWF9fKQorI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQVJDSF9BUk1fUU5YIDEKKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0FSQ0hfMzJfQklUIDEKKyNlbGlmIGRlZmluZWQoX19BUk1FTF9fKQorI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQVJDSF9BUk0gMQorI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQVJDSF8zMl9CSVQgMQorI2VsaWYgZGVmaW5lZChfX2FhcmNoNjRfXykKKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0FSQ0hfQUFSQ0g2NCAxCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9BUkNIXzY0X0JJVCAxCisjZWxpZiBkZWZpbmVkKF9fTUlQU0VMX18pCisjaWYgZGVmaW5lZChfX0xQNjRfXykKKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0FSQ0hfTUlQUzY0IDEKKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0FSQ0hfNjRfQklUIDEKKyNlbHNlCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9BUkNIX01JUFMgMQorI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQVJDSF8zMl9CSVQgMQorI2VuZGlmCisjZWxpZiBkZWZpbmVkKF9fcG5hY2xfXykKKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0FSQ0hfMzJfQklUIDEKKyNlbGlmIGRlZmluZWQoc3BhcmMpCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9BUkNIX1NQQVJDIDEKKyNpZiBkZWZpbmVkKF9fc3BhcmNfdjlfXykgfHwgZGVmaW5lZChfX3NwYXJjdjkpIHx8IGRlZmluZWQoX19hcmNoNjRfXykKKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX0FSQ0hfNjRfQklUIDEKKyNlbHNlCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9BUkNIXzMyX0JJVCAxCisjZW5kaWYKKyNlbGlmIGRlZmluZWQoX1BPV0VSKSB8fCBkZWZpbmVkKF9fcG93ZXJwYzY0X18pIHx8IGRlZmluZWQoX19QUEM2NF9fKQorI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfQVJDSF9QT1dFUiAxCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9BUkNIXzY0X0JJVCAxCisjZWxpZiBkZWZpbmVkKF9fR05VQ19fKQorIyBpZiAoKChfX0dOVUNfXyA9PSA0KSAmJiAoX19HTlVDX01JTk9SX18gPj0gNykpIHx8IChfX0dOVUNfXyA+IDQpKQorLy8gV2UgZmFsbGJhY2sgdG8gdGhlIGdlbmVyaWMgQ2xhbmcvR0NDID49IDQuNyBpbXBsZW1lbnRhdGlvbiBpbiBhdG9taWNvcHMuaAorIyBlbGlmIGRlZmluZWQoX19jbGFuZ19fKQorIyAgaWYgIV9faGFzX2V4dGVuc2lvbihjX2F0b21pYykKK0dPT0dMRV9QUk9UT0JVRl9QTEFURk9STV9FUlJPUgorIyAgZW5kaWYKKy8vIFdlIGZhbGxiYWNrIHRvIHRoZSBnZW5lcmljIENsYW5nL0dDQyA+PSA0LjcgaW1wbGVtZW50YXRpb24gaW4gYXRvbWljb3BzLmgKKyMgZW5kaWYKKyMgaWYgX19MUDY0X18KKyMgIGRlZmluZSBHT09HTEVfUFJPVE9CVUZfQVJDSF82NF9CSVQgMQorIyBlbHNlCisjICBkZWZpbmUgR09PR0xFX1BST1RPQlVGX0FSQ0hfMzJfQklUIDEKKyMgZW5kaWYKKyNlbHNlCitHT09HTEVfUFJPVE9CVUZfUExBVEZPUk1fRVJST1IKKyNlbmRpZgorCisjaWYgZGVmaW5lZChfX0FQUExFX18pCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9PU19BUFBMRQorI2luY2x1ZGUgPFRhcmdldENvbmRpdGlvbmFscy5oPgorI2lmIFRBUkdFVF9PU19JUEhPTkUKKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX09TX0lQSE9ORQorI2VuZGlmCisjZWxpZiBkZWZpbmVkKF9fRU1TQ1JJUFRFTl9fKQorI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfT1NfRU1TQ1JJUFRFTgorI2VsaWYgZGVmaW5lZChfX25hdGl2ZV9jbGllbnRfXykKKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX09TX05BQ0wKKyNlbGlmIGRlZmluZWQoc3VuKQorI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfT1NfU09MQVJJUworI2VsaWYgZGVmaW5lZChfQUlYKQorI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfT1NfQUlYCisjZWxpZiBkZWZpbmVkKF9fQU5EUk9JRF9fKQorI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfT1NfQU5EUk9JRAorI2VuZGlmCisKKyN1bmRlZiBHT09HTEVfUFJPVE9CVUZfUExBVEZPUk1fRVJST1IKKworI2lmIGRlZmluZWQoR09PR0xFX1BST1RPQlVGX09TX0FORFJPSUQpIHx8IGRlZmluZWQoR09PR0xFX1BST1RPQlVGX09TX0lQSE9ORSkKKy8vIEFuZHJvaWQgbmRrIGRvZXMgbm90IHN1cHBvcnQgdGhlIF9fdGhyZWFkIGtleXdvcmQgdmVyeSB3ZWxsIHlldC4gSGVyZQorLy8gd2UgdXNlIHB0aHJlYWRfa2V5X2NyZWF0ZSgpL3B0aHJlYWRfZ2V0c3BlY2lmaWMoKS8uLi4gbWV0aG9kcyBmb3IKKy8vIFRMUyBzdXBwb3J0IG9uIGFuZHJvaWQuCisvLyBpT1MgYWxzbyBkb2VzIG5vdCBzdXBwb3J0IHRoZSBfX3RocmVhZCBrZXl3b3JkLgorI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfTk9fVEhSRUFETE9DQUwKKyNlbmRpZgorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9QTEFURk9STV9NQUNST1NfSF8KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvcG9ydC5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9wb3J0LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTAzNmRmZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvcG9ydC5oCkBAIC0wLDAgKzEsMzg0IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfU1RVQlNfUE9SVF9IXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfU1RVQlNfUE9SVF9IXworCisjaW5jbHVkZSA8YXNzZXJ0Lmg+CisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSA8Y3N0ZGRlZj4KKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8c3RyaW5nLmg+CisjaWYgZGVmaW5lZChfX29zZl9fKQorLy8gVHJ1NjQgbGFja3Mgc3RkaW50LmgsIGJ1dCBoYXMgaW50dHlwZXMuaCB3aGljaCBkZWZpbmVzIGEgc3VwZXJzZXQgb2YKKy8vIHdoYXQgc3RkaW50Lmggd291bGQgZGVmaW5lLgorI2luY2x1ZGUgPGludHR5cGVzLmg+CisjZWxpZiAhZGVmaW5lZChfTVNDX1ZFUikKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNlbmRpZgorCisjdW5kZWYgUFJPVE9CVUZfTElUVExFX0VORElBTgorI2lmZGVmIF9XSU4zMgorICAvLyBBc3N1bWluZyB3aW5kb3dzIGlzIGFsd2F5cyBsaXR0bGUtZW5kaWFuLgorICAvLyBUT0RPKHhpYW9mZW5nKTogVGhlIFBST1RPQlVGX0xJVFRMRV9FTkRJQU4gaXMgbm90IG9ubHkgdXNlZCBmb3IKKyAgLy8gb3B0aW1pemF0aW9uIGJ1dCBhbHNvIGZvciBjb3JyZWN0bmVzcy4gV2Ugc2hvdWxkIGRlZmluZSBhbgorICAvLyBkaWZmZXJlbnQgbWFjcm8gdG8gdGVzdCB0aGUgYmlnLWVuZGlhbiBjb2RlIHBhdGggaW4gY29kZWRfc3RyZWFtLgorICAjaWYgIWRlZmluZWQoUFJPVE9CVUZfRElTQUJMRV9MSVRUTEVfRU5ESUFOX09QVF9GT1JfVEVTVCkKKyAgICAjZGVmaW5lIFBST1RPQlVGX0xJVFRMRV9FTkRJQU4gMQorICAjZW5kaWYKKyAgI2lmIF9NU0NfVkVSID49IDEzMDAgJiYgIWRlZmluZWQoX19JTlRFTF9DT01QSUxFUikKKyAgICAvLyBJZiBNU1ZDIGhhcyAiL1JUQ2MiIHNldCwgaXQgd2lsbCBjb21wbGFpbiBhYm91dCB0cnVuY2F0aW5nIGNhc3RzIGF0CisgICAgLy8gcnVudGltZS4gIFRoaXMgZmlsZSBjb250YWlucyBzb21lIGludGVudGlvbmFsIHRydW5jYXRpbmcgY2FzdHMuCisgICAgI3ByYWdtYSBydW50aW1lX2NoZWNrcygiYyIsIG9mZikKKyAgI2VuZGlmCisjZWxzZQorICAjaW5jbHVkZSA8c3lzL3BhcmFtLmg+ICAgLy8gX19CWVRFX09SREVSCisgICNpZiAoKGRlZmluZWQoX19MSVRUTEVfRU5ESUFOX18pICYmICFkZWZpbmVkKF9fQklHX0VORElBTl9fKSkgfHwgXAorICAgICAgICAgKGRlZmluZWQoX19CWVRFX09SREVSKSAmJiBfX0JZVEVfT1JERVIgPT0gX19MSVRUTEVfRU5ESUFOKSkgJiYgXAorICAgICAgIWRlZmluZWQoUFJPVE9CVUZfRElTQUJMRV9MSVRUTEVfRU5ESUFOX09QVF9GT1JfVEVTVCkKKyAgICAjZGVmaW5lIFBST1RPQlVGX0xJVFRMRV9FTkRJQU4gMQorICAjZW5kaWYKKyNlbmRpZgorI2lmIGRlZmluZWQoX01TQ19WRVIpICYmIGRlZmluZWQoUFJPVE9CVUZfVVNFX0RMTFMpCisgICNpZmRlZiBMSUJQUk9UT0JVRl9FWFBPUlRTCisgICAgI2RlZmluZSBMSUJQUk9UT0JVRl9FWFBPUlQgX19kZWNsc3BlYyhkbGxleHBvcnQpCisgICNlbHNlCisgICAgI2RlZmluZSBMSUJQUk9UT0JVRl9FWFBPUlQgX19kZWNsc3BlYyhkbGxpbXBvcnQpCisgICNlbmRpZgorICAjaWZkZWYgTElCUFJPVE9DX0VYUE9SVFMKKyAgICAjZGVmaW5lIExJQlBST1RPQ19FWFBPUlQgICBfX2RlY2xzcGVjKGRsbGV4cG9ydCkKKyAgI2Vsc2UKKyAgICAjZGVmaW5lIExJQlBST1RPQ19FWFBPUlQgICBfX2RlY2xzcGVjKGRsbGltcG9ydCkKKyAgI2VuZGlmCisjZWxzZQorICAjZGVmaW5lIExJQlBST1RPQlVGX0VYUE9SVAorICAjZGVmaW5lIExJQlBST1RPQ19FWFBPUlQKKyNlbmRpZgorCisvLyBUaGVzZSAjaW5jbHVkZXMgYXJlIGZvciB0aGUgYnl0ZSBzd2FwIGZ1bmN0aW9ucyBkZWNsYXJlZCBsYXRlciBvbi4KKyNpZmRlZiBfTVNDX1ZFUgorI2luY2x1ZGUgPHN0ZGxpYi5oPiAgLy8gTk9MSU5UKGJ1aWxkL2luY2x1ZGUpCisjZWxpZiBkZWZpbmVkKF9fQVBQTEVfXykKKyNpbmNsdWRlIDxsaWJrZXJuL09TQnl0ZU9yZGVyLmg+CisjZWxpZiBkZWZpbmVkKF9fR0xJQkNfXykgfHwgZGVmaW5lZChfX0NZR1dJTl9fKQorI2luY2x1ZGUgPGJ5dGVzd2FwLmg+ICAvLyBJV1lVIHByYWdtYTogZXhwb3J0CisjZW5kaWYKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorLy8gZnJvbSBnb29nbGUzL2Jhc2UvcG9ydC5oCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKK3R5cGVkZWYgdW5zaWduZWQgaW50IHVpbnQ7CisKKyNpZmRlZiBfTVNDX1ZFUgordHlwZWRlZiBzaWduZWQgX19pbnQ4ICBpbnQ4OwordHlwZWRlZiBfX2ludDE2IGludDE2OwordHlwZWRlZiBfX2ludDMyIGludDMyOwordHlwZWRlZiBfX2ludDY0IGludDY0OworCit0eXBlZGVmIHVuc2lnbmVkIF9faW50OCAgdWludDg7Cit0eXBlZGVmIHVuc2lnbmVkIF9faW50MTYgdWludDE2OwordHlwZWRlZiB1bnNpZ25lZCBfX2ludDMyIHVpbnQzMjsKK3R5cGVkZWYgdW5zaWduZWQgX19pbnQ2NCB1aW50NjQ7CisjZWxzZQordHlwZWRlZiBzaWduZWQgY2hhciAgaW50ODsKK3R5cGVkZWYgc2hvcnQgaW50MTY7Cit0eXBlZGVmIGludCBpbnQzMjsKK3R5cGVkZWYgbG9uZyBsb25nIGludDY0OworCit0eXBlZGVmIHVuc2lnbmVkIGNoYXIgIHVpbnQ4OwordHlwZWRlZiB1bnNpZ25lZCBzaG9ydCB1aW50MTY7Cit0eXBlZGVmIHVuc2lnbmVkIGludCB1aW50MzI7Cit0eXBlZGVmIHVuc2lnbmVkIGxvbmcgbG9uZyB1aW50NjQ7CisjZW5kaWYKKworLy8gbG9uZyBsb25nIG1hY3JvcyB0byBiZSB1c2VkIGJlY2F1c2UgZ2NjIGFuZCB2YysrIHVzZSBkaWZmZXJlbnQgc3VmZml4ZXMsCisvLyBhbmQgZGlmZmVyZW50IHNpemUgc3BlY2lmaWVycyBpbiBmb3JtYXQgc3RyaW5ncworI3VuZGVmIEdPT0dMRV9MT05HTE9ORworI3VuZGVmIEdPT0dMRV9VTE9OR0xPTkcKKyN1bmRlZiBHT09HTEVfTExfRk9STUFUCisKKyNpZmRlZiBfTVNDX1ZFUgorI2RlZmluZSBHT09HTEVfTE9OR0xPTkcoeCkgeCMjSTY0CisjZGVmaW5lIEdPT0dMRV9VTE9OR0xPTkcoeCkgeCMjVUk2NAorI2RlZmluZSBHT09HTEVfTExfRk9STUFUICJJNjQiICAvLyBBcyBpbiBwcmludGYoIiVJNjRkIiwgLi4uKQorI2Vsc2UKKyNkZWZpbmUgR09PR0xFX0xPTkdMT05HKHgpIHgjI0xMCisjZGVmaW5lIEdPT0dMRV9VTE9OR0xPTkcoeCkgeCMjVUxMCisjZGVmaW5lIEdPT0dMRV9MTF9GT1JNQVQgImxsIiAgLy8gQXMgaW4gIiVsbGQiLiBOb3RlIHRoYXQgInEiIGlzIHBvb3IgZm9ybSBhbHNvLgorI2VuZGlmCisKK3N0YXRpYyBjb25zdCBpbnQzMiBraW50MzJtYXggPSAweDdGRkZGRkZGOworc3RhdGljIGNvbnN0IGludDMyIGtpbnQzMm1pbiA9IC1raW50MzJtYXggLSAxOworc3RhdGljIGNvbnN0IGludDY0IGtpbnQ2NG1heCA9IEdPT0dMRV9MT05HTE9ORygweDdGRkZGRkZGRkZGRkZGRkYpOworc3RhdGljIGNvbnN0IGludDY0IGtpbnQ2NG1pbiA9IC1raW50NjRtYXggLSAxOworc3RhdGljIGNvbnN0IHVpbnQzMiBrdWludDMybWF4ID0gMHhGRkZGRkZGRnU7CitzdGF0aWMgY29uc3QgdWludDY0IGt1aW50NjRtYXggPSBHT09HTEVfVUxPTkdMT05HKDB4RkZGRkZGRkZGRkZGRkZGRik7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIEFubm90YXRpb25zOiAgU29tZSBwYXJ0cyBvZiB0aGUgY29kZSBoYXZlIGJlZW4gYW5ub3RhdGVkIGluIHdheXMgdGhhdCBtaWdodAorLy8gICBiZSB1c2VmdWwgdG8gc29tZSBjb21waWxlcnMgb3IgdG9vbHMsIGJ1dCBhcmUgbm90IHN1cHBvcnRlZCB1bml2ZXJzYWxseS4KKy8vICAgWW91IGNhbiAjZGVmaW5lIHRoZXNlIGFubm90YXRpb25zIHlvdXJzZWxmIGlmIHRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uCisvLyAgIGlzIG5vdCByaWdodCBmb3IgeW91LgorCisjaWZuZGVmIEdPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORQorI2lmIGRlZmluZWQoX19HTlVDX18pICYmIChfX0dOVUNfXyA+IDMgfHwoX19HTlVDX18gPT0gMyAmJiBfX0dOVUNfTUlOT1JfXyA+PSAxKSkKKy8vIEZvciBmdW5jdGlvbnMgd2Ugd2FudCB0byBmb3JjZSBpbmxpbmUuCisvLyBJbnRyb2R1Y2VkIGluIGdjYyAzLjEuCisjZGVmaW5lIEdPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORSBfX2F0dHJpYnV0ZV9fICgoYWx3YXlzX2lubGluZSkpCisjZWxzZQorLy8gT3RoZXIgY29tcGlsZXJzIHdpbGwgaGF2ZSB0byBmaWd1cmUgaXQgb3V0IGZvciB0aGVtc2VsdmVzLgorI2RlZmluZSBHT09HTEVfQVRUUklCVVRFX0FMV0FZU19JTkxJTkUKKyNlbmRpZgorI2VuZGlmCisKKyNpZm5kZWYgR09PR0xFX0FUVFJJQlVURV9OT0lOTElORQorI2lmIGRlZmluZWQoX19HTlVDX18pICYmIChfX0dOVUNfXyA+IDMgfHwoX19HTlVDX18gPT0gMyAmJiBfX0dOVUNfTUlOT1JfXyA+PSAxKSkKKy8vIEZvciBmdW5jdGlvbnMgd2Ugd2FudCB0byBmb3JjZSBub3QgaW5saW5lLgorLy8gSW50cm9kdWNlZCBpbiBnY2MgMy4xLgorI2RlZmluZSBHT09HTEVfQVRUUklCVVRFX05PSU5MSU5FIF9fYXR0cmlidXRlX18gKChub2lubGluZSkpCisjZWxpZiBkZWZpbmVkKF9NU0NfVkVSKSAmJiAoX01TQ19WRVIgPj0gMTQwMCkKKy8vIFNlZW1zIHRvIGhhdmUgYmVlbiBhcm91bmQgc2luY2UgYXQgbGVhc3QgVmlzdWFsIFN0dWRpbyAyMDA1CisjZGVmaW5lIEdPT0dMRV9BVFRSSUJVVEVfTk9JTkxJTkUgX19kZWNsc3BlYyhub2lubGluZSkKKyNlbHNlCisvLyBPdGhlciBjb21waWxlcnMgd2lsbCBoYXZlIHRvIGZpZ3VyZSBpdCBvdXQgZm9yIHRoZW1zZWx2ZXMuCisjZGVmaW5lIEdPT0dMRV9BVFRSSUJVVEVfTk9JTkxJTkUKKyNlbmRpZgorI2VuZGlmCisKKyNpZm5kZWYgR09PR0xFX0FUVFJJQlVURV9ERVBSRUNBVEVECisjaWZkZWYgX19HTlVDX18KKy8vIElmIHRoZSBtZXRob2QvdmFyaWFibGUvdHlwZSBpcyB1c2VkIGFueXdoZXJlLCBwcm9kdWNlIGEgd2FybmluZy4KKyNkZWZpbmUgR09PR0xFX0FUVFJJQlVURV9ERVBSRUNBVEVEIF9fYXR0cmlidXRlX18oKGRlcHJlY2F0ZWQpKQorI2Vsc2UKKyNkZWZpbmUgR09PR0xFX0FUVFJJQlVURV9ERVBSRUNBVEVECisjZW5kaWYKKyNlbmRpZgorCisjaWZuZGVmIEdPT0dMRV9QUkVESUNUX1RSVUUKKyNpZmRlZiBfX0dOVUNfXworLy8gUHJvdmlkZWQgYXQgbGVhc3Qgc2luY2UgR0NDIDMuMC4KKyNkZWZpbmUgR09PR0xFX1BSRURJQ1RfVFJVRSh4KSAoX19idWlsdGluX2V4cGVjdCghISh4KSwgMSkpCisjZWxzZQorI2RlZmluZSBHT09HTEVfUFJFRElDVF9UUlVFKHgpICh4KQorI2VuZGlmCisjZW5kaWYKKworI2lmbmRlZiBHT09HTEVfUFJFRElDVF9GQUxTRQorI2lmZGVmIF9fR05VQ19fCisvLyBQcm92aWRlZCBhdCBsZWFzdCBzaW5jZSBHQ0MgMy4wLgorI2RlZmluZSBHT09HTEVfUFJFRElDVF9GQUxTRSh4KSAoX19idWlsdGluX2V4cGVjdCh4LCAwKSkKKyNlbHNlCisjZGVmaW5lIEdPT0dMRV9QUkVESUNUX0ZBTFNFKHgpICh4KQorI2VuZGlmCisjZW5kaWYKKworLy8gRGVsaW1pdHMgYSBibG9jayBvZiBjb2RlIHdoaWNoIG1heSB3cml0ZSB0byBtZW1vcnkgd2hpY2ggaXMgc2ltdWx0YW5lb3VzbHkKKy8vIHdyaXR0ZW4gYnkgb3RoZXIgdGhyZWFkcywgYnV0IHdoaWNoIGhhcyBiZWVuIGRldGVybWluZWQgdG8gYmUgdGhyZWFkLXNhZmUKKy8vIChlLmcuIGJlY2F1c2UgaXQgaXMgYW4gaWRlbXBvdGVudCB3cml0ZSkuCisjaWZuZGVmIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOCisjZGVmaW5lIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCkKKyNlbmRpZgorI2lmbmRlZiBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQKKyNkZWZpbmUgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCkKKyNlbmRpZgorCisjaWYgZGVmaW5lZChfX2NsYW5nX18pICYmIGRlZmluZWQoX19oYXNfY3BwX2F0dHJpYnV0ZSkgXAorICAgICYmICFkZWZpbmVkKEdPT0dMRV9QUk9UT0JVRl9PU19BUFBMRSkKKyMgaWYgZGVmaW5lZChHT09HTEVfUFJPVE9CVUZfT1NfTkFDTCkgfHwgZGVmaW5lZChFTVNDUklQVEVOKSB8fCBcCisgICAgIF9faGFzX2NwcF9hdHRyaWJ1dGUoY2xhbmc6OmZhbGx0aHJvdWdoKQorIyAgZGVmaW5lIEdPT0dMRV9GQUxMVEhST1VHSF9JTlRFTkRFRCBbW2NsYW5nOjpmYWxsdGhyb3VnaF1dCisjIGVuZGlmCisjZW5kaWYKKworI2lmbmRlZiBHT09HTEVfRkFMTFRIUk9VR0hfSU5URU5ERUQKKyMgZGVmaW5lIEdPT0dMRV9GQUxMVEhST1VHSF9JTlRFTkRFRAorI2VuZGlmCisKKyNkZWZpbmUgR09PR0xFX0dVQVJERURfQlkoeCkKKyNkZWZpbmUgR09PR0xFX0FUVFJJQlVURV9DT0xECisKKy8vIHg4NiBhbmQgeDg2LTY0IGNhbiBwZXJmb3JtIHVuYWxpZ25lZCBsb2Fkcy9zdG9yZXMgZGlyZWN0bHkuCisjaWYgZGVmaW5lZChfTV9YNjQpIHx8IGRlZmluZWQoX194ODZfNjRfXykgfHwgXAorICAgIGRlZmluZWQoX01fSVg4NikgfHwgZGVmaW5lZChfX2kzODZfXykKKworI2RlZmluZSBHT09HTEVfVU5BTElHTkVEX0xPQUQxNihfcCkgKCpyZWludGVycHJldF9jYXN0PGNvbnN0IHVpbnQxNiAqPihfcCkpCisjZGVmaW5lIEdPT0dMRV9VTkFMSUdORURfTE9BRDMyKF9wKSAoKnJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgdWludDMyICo+KF9wKSkKKyNkZWZpbmUgR09PR0xFX1VOQUxJR05FRF9MT0FENjQoX3ApICgqcmVpbnRlcnByZXRfY2FzdDxjb25zdCB1aW50NjQgKj4oX3ApKQorCisjZGVmaW5lIEdPT0dMRV9VTkFMSUdORURfU1RPUkUxNihfcCwgX3ZhbCkgKCpyZWludGVycHJldF9jYXN0PHVpbnQxNiAqPihfcCkgPSAoX3ZhbCkpCisjZGVmaW5lIEdPT0dMRV9VTkFMSUdORURfU1RPUkUzMihfcCwgX3ZhbCkgKCpyZWludGVycHJldF9jYXN0PHVpbnQzMiAqPihfcCkgPSAoX3ZhbCkpCisjZGVmaW5lIEdPT0dMRV9VTkFMSUdORURfU1RPUkU2NChfcCwgX3ZhbCkgKCpyZWludGVycHJldF9jYXN0PHVpbnQ2NCAqPihfcCkgPSAoX3ZhbCkpCisKKyNlbHNlCitpbmxpbmUgdWludDE2IEdPT0dMRV9VTkFMSUdORURfTE9BRDE2KGNvbnN0IHZvaWQgKnApIHsKKyAgdWludDE2IHQ7CisgIG1lbWNweSgmdCwgcCwgc2l6ZW9mIHQpOworICByZXR1cm4gdDsKK30KKworaW5saW5lIHVpbnQzMiBHT09HTEVfVU5BTElHTkVEX0xPQUQzMihjb25zdCB2b2lkICpwKSB7CisgIHVpbnQzMiB0OworICBtZW1jcHkoJnQsIHAsIHNpemVvZiB0KTsKKyAgcmV0dXJuIHQ7Cit9CisKK2lubGluZSB1aW50NjQgR09PR0xFX1VOQUxJR05FRF9MT0FENjQoY29uc3Qgdm9pZCAqcCkgeworICB1aW50NjQgdDsKKyAgbWVtY3B5KCZ0LCBwLCBzaXplb2YgdCk7CisgIHJldHVybiB0OworfQorCitpbmxpbmUgdm9pZCBHT09HTEVfVU5BTElHTkVEX1NUT1JFMTYodm9pZCAqcCwgdWludDE2IHYpIHsKKyAgbWVtY3B5KHAsICZ2LCBzaXplb2Ygdik7Cit9CisKK2lubGluZSB2b2lkIEdPT0dMRV9VTkFMSUdORURfU1RPUkUzMih2b2lkICpwLCB1aW50MzIgdikgeworICBtZW1jcHkocCwgJnYsIHNpemVvZiB2KTsKK30KKworaW5saW5lIHZvaWQgR09PR0xFX1VOQUxJR05FRF9TVE9SRTY0KHZvaWQgKnAsIHVpbnQ2NCB2KSB7CisgIG1lbWNweShwLCAmdiwgc2l6ZW9mIHYpOworfQorI2VuZGlmCisKKyNpZiBkZWZpbmVkKF9NU0NfVkVSKQorI2RlZmluZSBHT09HTEVfVEhSRUFEX0xPQ0FMIF9fZGVjbHNwZWModGhyZWFkKQorI2Vsc2UKKyNkZWZpbmUgR09PR0xFX1RIUkVBRF9MT0NBTCBfX3RocmVhZAorI2VuZGlmCisKKy8vIFRoZSBmb2xsb3dpbmcgZ3VhcmFudGVlcyBkZWNsYXJhdGlvbiBvZiB0aGUgYnl0ZSBzd2FwIGZ1bmN0aW9ucywgYW5kCisvLyBkZWZpbmVzIF9fQllURV9PUkRFUiBmb3IgTVNWQworI2lmZGVmIF9NU0NfVkVSCisjZGVmaW5lIF9fQllURV9PUkRFUiBfX0xJVFRMRV9FTkRJQU4KKyNkZWZpbmUgYnN3YXBfMTYoeCkgX2J5dGVzd2FwX3VzaG9ydCh4KQorI2RlZmluZSBic3dhcF8zMih4KSBfYnl0ZXN3YXBfdWxvbmcoeCkKKyNkZWZpbmUgYnN3YXBfNjQoeCkgX2J5dGVzd2FwX3VpbnQ2NCh4KQorCisjZWxpZiBkZWZpbmVkKF9fQVBQTEVfXykKKy8vIE1hYyBPUyBYIC8gRGFyd2luIGZlYXR1cmVzCisjZGVmaW5lIGJzd2FwXzE2KHgpIE9TU3dhcEludDE2KHgpCisjZGVmaW5lIGJzd2FwXzMyKHgpIE9TU3dhcEludDMyKHgpCisjZGVmaW5lIGJzd2FwXzY0KHgpIE9TU3dhcEludDY0KHgpCisKKyNlbGlmICFkZWZpbmVkKF9fR0xJQkNfXykgJiYgIWRlZmluZWQoX19DWUdXSU5fXykKKworc3RhdGljIGlubGluZSB1aW50MTYgYnN3YXBfMTYodWludDE2IHgpIHsKKyAgcmV0dXJuIHN0YXRpY19jYXN0PHVpbnQxNj4oKCh4ICYgMHhGRikgPDwgOCkgfCAoKHggJiAweEZGMDApID4+IDgpKTsKK30KKyNkZWZpbmUgYnN3YXBfMTYoeCkgYnN3YXBfMTYoeCkKK3N0YXRpYyBpbmxpbmUgdWludDMyIGJzd2FwXzMyKHVpbnQzMiB4KSB7CisgIHJldHVybiAoKCh4ICYgMHhGRikgPDwgMjQpIHwKKyAgICAgICAgICAoKHggJiAweEZGMDApIDw8IDgpIHwKKyAgICAgICAgICAoKHggJiAweEZGMDAwMCkgPj4gOCkgfAorICAgICAgICAgICgoeCAmIDB4RkYwMDAwMDApID4+IDI0KSk7Cit9CisjZGVmaW5lIGJzd2FwXzMyKHgpIGJzd2FwXzMyKHgpCitzdGF0aWMgaW5saW5lIHVpbnQ2NCBic3dhcF82NCh1aW50NjQgeCkgeworICByZXR1cm4gKCgoeCAmIEdPT0dMRV9VTE9OR0xPTkcoMHhGRikpIDw8IDU2KSB8CisgICAgICAgICAgKCh4ICYgR09PR0xFX1VMT05HTE9ORygweEZGMDApKSA8PCA0MCkgfAorICAgICAgICAgICgoeCAmIEdPT0dMRV9VTE9OR0xPTkcoMHhGRjAwMDApKSA8PCAyNCkgfAorICAgICAgICAgICgoeCAmIEdPT0dMRV9VTE9OR0xPTkcoMHhGRjAwMDAwMCkpIDw8IDgpIHwKKyAgICAgICAgICAoKHggJiBHT09HTEVfVUxPTkdMT05HKDB4RkYwMDAwMDAwMCkpID4+IDgpIHwKKyAgICAgICAgICAoKHggJiBHT09HTEVfVUxPTkdMT05HKDB4RkYwMDAwMDAwMDAwKSkgPj4gMjQpIHwKKyAgICAgICAgICAoKHggJiBHT09HTEVfVUxPTkdMT05HKDB4RkYwMDAwMDAwMDAwMDApKSA+PiA0MCkgfAorICAgICAgICAgICgoeCAmIEdPT0dMRV9VTE9OR0xPTkcoMHhGRjAwMDAwMDAwMDAwMDAwKSkgPj4gNTYpKTsKK30KKyNkZWZpbmUgYnN3YXBfNjQoeCkgYnN3YXBfNjQoeCkKKworI2VuZGlmCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKy8vIGZyb20gZ29vZ2xlMy91dGlsL2VuZGlhbi9lbmRpYW4uaAorTElCUFJPVE9CVUZfRVhQT1JUIHVpbnQzMiBnaHRvbmwodWludDMyIHgpOworCitjbGFzcyBCaWdFbmRpYW4geworIHB1YmxpYzoKKyNpZmRlZiBQUk9UT0JVRl9MSVRUTEVfRU5ESUFOCisKKyAgc3RhdGljIHVpbnQxNiBGcm9tSG9zdDE2KHVpbnQxNiB4KSB7IHJldHVybiBic3dhcF8xNih4KTsgfQorICBzdGF0aWMgdWludDE2IFRvSG9zdDE2KHVpbnQxNiB4KSB7IHJldHVybiBic3dhcF8xNih4KTsgfQorCisgIHN0YXRpYyB1aW50MzIgRnJvbUhvc3QzMih1aW50MzIgeCkgeyByZXR1cm4gYnN3YXBfMzIoeCk7IH0KKyAgc3RhdGljIHVpbnQzMiBUb0hvc3QzMih1aW50MzIgeCkgeyByZXR1cm4gYnN3YXBfMzIoeCk7IH0KKworICBzdGF0aWMgdWludDY0IEZyb21Ib3N0NjQodWludDY0IHgpIHsgcmV0dXJuIGJzd2FwXzY0KHgpOyB9CisgIHN0YXRpYyB1aW50NjQgVG9Ib3N0NjQodWludDY0IHgpIHsgcmV0dXJuIGJzd2FwXzY0KHgpOyB9CisKKyAgc3RhdGljIGJvb2wgSXNMaXR0bGVFbmRpYW4oKSB7IHJldHVybiB0cnVlOyB9CisKKyNlbHNlCisKKyAgc3RhdGljIHVpbnQxNiBGcm9tSG9zdDE2KHVpbnQxNiB4KSB7IHJldHVybiB4OyB9CisgIHN0YXRpYyB1aW50MTYgVG9Ib3N0MTYodWludDE2IHgpIHsgcmV0dXJuIHg7IH0KKworICBzdGF0aWMgdWludDMyIEZyb21Ib3N0MzIodWludDMyIHgpIHsgcmV0dXJuIHg7IH0KKyAgc3RhdGljIHVpbnQzMiBUb0hvc3QzMih1aW50MzIgeCkgeyByZXR1cm4geDsgfQorCisgIHN0YXRpYyB1aW50NjQgRnJvbUhvc3Q2NCh1aW50NjQgeCkgeyByZXR1cm4geDsgfQorICBzdGF0aWMgdWludDY0IFRvSG9zdDY0KHVpbnQ2NCB4KSB7IHJldHVybiB4OyB9CisKKyAgc3RhdGljIGJvb2wgSXNMaXR0bGVFbmRpYW4oKSB7IHJldHVybiBmYWxzZTsgfQorCisjZW5kaWYgLyogRU5ESUFOICovCisKKyAgLy8gRnVuY3Rpb25zIHRvIGRvIHVuYWxpZ25lZCBsb2FkcyBhbmQgc3RvcmVzIGluIGJpZy1lbmRpYW4gb3JkZXIuCisgIHN0YXRpYyB1aW50MTYgTG9hZDE2KGNvbnN0IHZvaWQgKnApIHsKKyAgICByZXR1cm4gVG9Ib3N0MTYoR09PR0xFX1VOQUxJR05FRF9MT0FEMTYocCkpOworICB9CisKKyAgc3RhdGljIHZvaWQgU3RvcmUxNih2b2lkICpwLCB1aW50MTYgdikgeworICAgIEdPT0dMRV9VTkFMSUdORURfU1RPUkUxNihwLCBGcm9tSG9zdDE2KHYpKTsKKyAgfQorCisgIHN0YXRpYyB1aW50MzIgTG9hZDMyKGNvbnN0IHZvaWQgKnApIHsKKyAgICByZXR1cm4gVG9Ib3N0MzIoR09PR0xFX1VOQUxJR05FRF9MT0FEMzIocCkpOworICB9CisKKyAgc3RhdGljIHZvaWQgU3RvcmUzMih2b2lkICpwLCB1aW50MzIgdikgeworICAgIEdPT0dMRV9VTkFMSUdORURfU1RPUkUzMihwLCBGcm9tSG9zdDMyKHYpKTsKKyAgfQorCisgIHN0YXRpYyB1aW50NjQgTG9hZDY0KGNvbnN0IHZvaWQgKnApIHsKKyAgICByZXR1cm4gVG9Ib3N0NjQoR09PR0xFX1VOQUxJR05FRF9MT0FENjQocCkpOworICB9CisKKyAgc3RhdGljIHZvaWQgU3RvcmU2NCh2b2lkICpwLCB1aW50NjQgdikgeworICAgIEdPT0dMRV9VTkFMSUdORURfU1RPUkU2NChwLCBGcm9tSG9zdDY0KHYpKTsKKyAgfQorfTsKKworCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfU1RVQlNfUE9SVF9IXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zY29wZWRfcHRyLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3Njb3BlZF9wdHIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NDIzYzExCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zY29wZWRfcHRyLmgKQEAgLTAsMCArMSwyMzYgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9TVFVCU19TQ09QRURfUFRSX0hfCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9TVFVCU19TQ09QRURfUFRSX0hfCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvcG9ydC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKy8vIGZyb20gZ29vZ2xlMy9iYXNlL3Njb3BlZF9wdHIuaAorCituYW1lc3BhY2UgaW50ZXJuYWwgeworCisvLyAgVGhpcyBpcyBhbiBpbXBsZW1lbnRhdGlvbiBkZXNpZ25lZCB0byBtYXRjaCB0aGUgYW50aWNpcGF0ZWQgZnV0dXJlIFRSMgorLy8gIGltcGxlbWVudGF0aW9uIG9mIHRoZSBzY29wZWRfcHRyIGNsYXNzLCBhbmQgaXRzIGNsb3NlbHktcmVsYXRlZCBicmV0aHJlbiwKKy8vICBzY29wZWRfYXJyYXksIHNjb3BlZF9wdHJfbWFsbG9jLCBhbmQgbWFrZV9zY29wZWRfcHRyLgorCit0ZW1wbGF0ZSA8Y2xhc3MgQz4gY2xhc3Mgc2NvcGVkX3B0cjsKK3RlbXBsYXRlIDxjbGFzcyBDPiBjbGFzcyBzY29wZWRfYXJyYXk7CisKKy8vIEEgc2NvcGVkX3B0cjxUPiBpcyBsaWtlIGEgVCosIGV4Y2VwdCB0aGF0IHRoZSBkZXN0cnVjdG9yIG9mIHNjb3BlZF9wdHI8VD4KKy8vIGF1dG9tYXRpY2FsbHkgZGVsZXRlcyB0aGUgcG9pbnRlciBpdCBob2xkcyAoaWYgYW55KS4KKy8vIFRoYXQgaXMsIHNjb3BlZF9wdHI8VD4gb3ducyB0aGUgVCBvYmplY3QgdGhhdCBpdCBwb2ludHMgdG8uCisvLyBMaWtlIGEgVCosIGEgc2NvcGVkX3B0cjxUPiBtYXkgaG9sZCBlaXRoZXIgTlVMTCBvciBhIHBvaW50ZXIgdG8gYSBUIG9iamVjdC4KKy8vCisvLyBUaGUgc2l6ZSBvZiBhIHNjb3BlZF9wdHIgaXMgc21hbGw6CisvLyBzaXplb2Yoc2NvcGVkX3B0cjxDPikgPT0gc2l6ZW9mKEMqKQordGVtcGxhdGUgPGNsYXNzIEM+CitjbGFzcyBzY29wZWRfcHRyIHsKKyBwdWJsaWM6CisKKyAgLy8gVGhlIGVsZW1lbnQgdHlwZQorICB0eXBlZGVmIEMgZWxlbWVudF90eXBlOworCisgIC8vIENvbnN0cnVjdG9yLiAgRGVmYXVsdHMgdG8gaW5pdGlhbGl6aW5nIHdpdGggTlVMTC4KKyAgLy8gVGhlcmUgaXMgbm8gd2F5IHRvIGNyZWF0ZSBhbiB1bmluaXRpYWxpemVkIHNjb3BlZF9wdHIuCisgIC8vIFRoZSBpbnB1dCBwYXJhbWV0ZXIgbXVzdCBiZSBhbGxvY2F0ZWQgd2l0aCBuZXcuCisgIGV4cGxpY2l0IHNjb3BlZF9wdHIoQyogcCA9IE5VTEwpIDogcHRyXyhwKSB7IH0KKworICAvLyBEZXN0cnVjdG9yLiAgSWYgdGhlcmUgaXMgYSBDIG9iamVjdCwgZGVsZXRlIGl0LgorICAvLyBXZSBkb24ndCBuZWVkIHRvIHRlc3QgcHRyXyA9PSBOVUxMIGJlY2F1c2UgQysrIGRvZXMgdGhhdCBmb3IgdXMuCisgIH5zY29wZWRfcHRyKCkgeworICAgIGVudW0geyB0eXBlX211c3RfYmVfY29tcGxldGUgPSBzaXplb2YoQykgfTsKKyAgICBkZWxldGUgcHRyXzsKKyAgfQorCisgIC8vIFJlc2V0LiAgRGVsZXRlcyB0aGUgY3VycmVudCBvd25lZCBvYmplY3QsIGlmIGFueS4KKyAgLy8gVGhlbiB0YWtlcyBvd25lcnNoaXAgb2YgYSBuZXcgb2JqZWN0LCBpZiBnaXZlbi4KKyAgLy8gdGhpcy0+cmVzZXQodGhpcy0+Z2V0KCkpIHdvcmtzLgorICB2b2lkIHJlc2V0KEMqIHAgPSBOVUxMKSB7CisgICAgaWYgKHAgIT0gcHRyXykgeworICAgICAgZW51bSB7IHR5cGVfbXVzdF9iZV9jb21wbGV0ZSA9IHNpemVvZihDKSB9OworICAgICAgZGVsZXRlIHB0cl87CisgICAgICBwdHJfID0gcDsKKyAgICB9CisgIH0KKworICAvLyBBY2Nlc3NvcnMgdG8gZ2V0IHRoZSBvd25lZCBvYmplY3QuCisgIC8vIG9wZXJhdG9yKiBhbmQgb3BlcmF0b3ItPiB3aWxsIGFzc2VydCgpIGlmIHRoZXJlIGlzIG5vIGN1cnJlbnQgb2JqZWN0LgorICBDJiBvcGVyYXRvciooKSBjb25zdCB7CisgICAgYXNzZXJ0KHB0cl8gIT0gTlVMTCk7CisgICAgcmV0dXJuICpwdHJfOworICB9CisgIEMqIG9wZXJhdG9yLT4oKSBjb25zdCAgeworICAgIGFzc2VydChwdHJfICE9IE5VTEwpOworICAgIHJldHVybiBwdHJfOworICB9CisgIEMqIGdldCgpIGNvbnN0IHsgcmV0dXJuIHB0cl87IH0KKworICAvLyBDb21wYXJpc29uIG9wZXJhdG9ycy4KKyAgLy8gVGhlc2UgcmV0dXJuIHdoZXRoZXIgdHdvIHNjb3BlZF9wdHIgcmVmZXIgdG8gdGhlIHNhbWUgb2JqZWN0LCBub3QganVzdCB0bworICAvLyB0d28gZGlmZmVyZW50IGJ1dCBlcXVhbCBvYmplY3RzLgorICBib29sIG9wZXJhdG9yPT0oQyogcCkgY29uc3QgeyByZXR1cm4gcHRyXyA9PSBwOyB9CisgIGJvb2wgb3BlcmF0b3IhPShDKiBwKSBjb25zdCB7IHJldHVybiBwdHJfICE9IHA7IH0KKworICAvLyBTd2FwIHR3byBzY29wZWQgcG9pbnRlcnMuCisgIHZvaWQgc3dhcChzY29wZWRfcHRyJiBwMikgeworICAgIEMqIHRtcCA9IHB0cl87CisgICAgcHRyXyA9IHAyLnB0cl87CisgICAgcDIucHRyXyA9IHRtcDsKKyAgfQorCisgIC8vIFJlbGVhc2UgYSBwb2ludGVyLgorICAvLyBUaGUgcmV0dXJuIHZhbHVlIGlzIHRoZSBjdXJyZW50IHBvaW50ZXIgaGVsZCBieSB0aGlzIG9iamVjdC4KKyAgLy8gSWYgdGhpcyBvYmplY3QgaG9sZHMgYSBOVUxMIHBvaW50ZXIsIHRoZSByZXR1cm4gdmFsdWUgaXMgTlVMTC4KKyAgLy8gQWZ0ZXIgdGhpcyBvcGVyYXRpb24sIHRoaXMgb2JqZWN0IHdpbGwgaG9sZCBhIE5VTEwgcG9pbnRlciwKKyAgLy8gYW5kIHdpbGwgbm90IG93biB0aGUgb2JqZWN0IGFueSBtb3JlLgorICBDKiByZWxlYXNlKCkgeworICAgIEMqIHJldFZhbCA9IHB0cl87CisgICAgcHRyXyA9IE5VTEw7CisgICAgcmV0dXJuIHJldFZhbDsKKyAgfQorCisgcHJpdmF0ZToKKyAgQyogcHRyXzsKKworICAvLyBGb3JiaWQgY29tcGFyaXNvbiBvZiBzY29wZWRfcHRyIHR5cGVzLiAgSWYgQzIgIT0gQywgaXQgdG90YWxseSBkb2Vzbid0CisgIC8vIG1ha2Ugc2Vuc2UsIGFuZCBpZiBDMiA9PSBDLCBpdCBzdGlsbCBkb2Vzbid0IG1ha2Ugc2Vuc2UgYmVjYXVzZSB5b3Ugc2hvdWxkCisgIC8vIG5ldmVyIGhhdmUgdGhlIHNhbWUgb2JqZWN0IG93bmVkIGJ5IHR3byBkaWZmZXJlbnQgc2NvcGVkX3B0cnMuCisgIHRlbXBsYXRlIDxjbGFzcyBDMj4gYm9vbCBvcGVyYXRvcj09KHNjb3BlZF9wdHI8QzI+IGNvbnN0JiBwMikgY29uc3Q7CisgIHRlbXBsYXRlIDxjbGFzcyBDMj4gYm9vbCBvcGVyYXRvciE9KHNjb3BlZF9wdHI8QzI+IGNvbnN0JiBwMikgY29uc3Q7CisKKyAgLy8gRGlzYWxsb3cgZXZpbCBjb25zdHJ1Y3RvcnMKKyAgc2NvcGVkX3B0cihjb25zdCBzY29wZWRfcHRyJik7CisgIHZvaWQgb3BlcmF0b3I9KGNvbnN0IHNjb3BlZF9wdHImKTsKK307CisKKy8vIHNjb3BlZF9hcnJheTxDPiBpcyBsaWtlIHNjb3BlZF9wdHI8Qz4sIGV4Y2VwdCB0aGF0IHRoZSBjYWxsZXIgbXVzdCBhbGxvY2F0ZQorLy8gd2l0aCBuZXcgW10gYW5kIHRoZSBkZXN0cnVjdG9yIGRlbGV0ZXMgb2JqZWN0cyB3aXRoIGRlbGV0ZSBbXS4KKy8vCisvLyBBcyB3aXRoIHNjb3BlZF9wdHI8Qz4sIGEgc2NvcGVkX2FycmF5PEM+IGVpdGhlciBwb2ludHMgdG8gYW4gb2JqZWN0CisvLyBvciBpcyBOVUxMLiAgQSBzY29wZWRfYXJyYXk8Qz4gb3ducyB0aGUgb2JqZWN0IHRoYXQgaXQgcG9pbnRzIHRvLgorLy8KKy8vIFNpemU6IHNpemVvZihzY29wZWRfYXJyYXk8Qz4pID09IHNpemVvZihDKikKK3RlbXBsYXRlIDxjbGFzcyBDPgorY2xhc3Mgc2NvcGVkX2FycmF5IHsKKyBwdWJsaWM6CisKKyAgLy8gVGhlIGVsZW1lbnQgdHlwZQorICB0eXBlZGVmIEMgZWxlbWVudF90eXBlOworCisgIC8vIENvbnN0cnVjdG9yLiAgRGVmYXVsdHMgdG8gaW5pdGlhbGl6aW5nIHdpdGggTlVMTC4KKyAgLy8gVGhlcmUgaXMgbm8gd2F5IHRvIGNyZWF0ZSBhbiB1bmluaXRpYWxpemVkIHNjb3BlZF9hcnJheS4KKyAgLy8gVGhlIGlucHV0IHBhcmFtZXRlciBtdXN0IGJlIGFsbG9jYXRlZCB3aXRoIG5ldyBbXS4KKyAgZXhwbGljaXQgc2NvcGVkX2FycmF5KEMqIHAgPSBOVUxMKSA6IGFycmF5XyhwKSB7IH0KKworICAvLyBEZXN0cnVjdG9yLiAgSWYgdGhlcmUgaXMgYSBDIG9iamVjdCwgZGVsZXRlIGl0LgorICAvLyBXZSBkb24ndCBuZWVkIHRvIHRlc3QgcHRyXyA9PSBOVUxMIGJlY2F1c2UgQysrIGRvZXMgdGhhdCBmb3IgdXMuCisgIH5zY29wZWRfYXJyYXkoKSB7CisgICAgZW51bSB7IHR5cGVfbXVzdF9iZV9jb21wbGV0ZSA9IHNpemVvZihDKSB9OworICAgIGRlbGV0ZVtdIGFycmF5XzsKKyAgfQorCisgIC8vIFJlc2V0LiAgRGVsZXRlcyB0aGUgY3VycmVudCBvd25lZCBvYmplY3QsIGlmIGFueS4KKyAgLy8gVGhlbiB0YWtlcyBvd25lcnNoaXAgb2YgYSBuZXcgb2JqZWN0LCBpZiBnaXZlbi4KKyAgLy8gdGhpcy0+cmVzZXQodGhpcy0+Z2V0KCkpIHdvcmtzLgorICB2b2lkIHJlc2V0KEMqIHAgPSBOVUxMKSB7CisgICAgaWYgKHAgIT0gYXJyYXlfKSB7CisgICAgICBlbnVtIHsgdHlwZV9tdXN0X2JlX2NvbXBsZXRlID0gc2l6ZW9mKEMpIH07CisgICAgICBkZWxldGVbXSBhcnJheV87CisgICAgICBhcnJheV8gPSBwOworICAgIH0KKyAgfQorCisgIC8vIEdldCBvbmUgZWxlbWVudCBvZiB0aGUgY3VycmVudCBvYmplY3QuCisgIC8vIFdpbGwgYXNzZXJ0KCkgaWYgdGhlcmUgaXMgbm8gY3VycmVudCBvYmplY3QsIG9yIGluZGV4IGkgaXMgbmVnYXRpdmUuCisgIEMmIG9wZXJhdG9yW10oc3RkOjpwdHJkaWZmX3QgaSkgY29uc3QgeworICAgIGFzc2VydChpID49IDApOworICAgIGFzc2VydChhcnJheV8gIT0gTlVMTCk7CisgICAgcmV0dXJuIGFycmF5X1tpXTsKKyAgfQorCisgIC8vIEdldCBhIHBvaW50ZXIgdG8gdGhlIHplcm90aCBlbGVtZW50IG9mIHRoZSBjdXJyZW50IG9iamVjdC4KKyAgLy8gSWYgdGhlcmUgaXMgbm8gY3VycmVudCBvYmplY3QsIHJldHVybiBOVUxMLgorICBDKiBnZXQoKSBjb25zdCB7CisgICAgcmV0dXJuIGFycmF5XzsKKyAgfQorCisgIC8vIENvbXBhcmlzb24gb3BlcmF0b3JzLgorICAvLyBUaGVzZSByZXR1cm4gd2hldGhlciB0d28gc2NvcGVkX2FycmF5IHJlZmVyIHRvIHRoZSBzYW1lIG9iamVjdCwgbm90IGp1c3QgdG8KKyAgLy8gdHdvIGRpZmZlcmVudCBidXQgZXF1YWwgb2JqZWN0cy4KKyAgYm9vbCBvcGVyYXRvcj09KEMqIHApIGNvbnN0IHsgcmV0dXJuIGFycmF5XyA9PSBwOyB9CisgIGJvb2wgb3BlcmF0b3IhPShDKiBwKSBjb25zdCB7IHJldHVybiBhcnJheV8gIT0gcDsgfQorCisgIC8vIFN3YXAgdHdvIHNjb3BlZCBhcnJheXMuCisgIHZvaWQgc3dhcChzY29wZWRfYXJyYXkmIHAyKSB7CisgICAgQyogdG1wID0gYXJyYXlfOworICAgIGFycmF5XyA9IHAyLmFycmF5XzsKKyAgICBwMi5hcnJheV8gPSB0bXA7CisgIH0KKworICAvLyBSZWxlYXNlIGFuIGFycmF5LgorICAvLyBUaGUgcmV0dXJuIHZhbHVlIGlzIHRoZSBjdXJyZW50IHBvaW50ZXIgaGVsZCBieSB0aGlzIG9iamVjdC4KKyAgLy8gSWYgdGhpcyBvYmplY3QgaG9sZHMgYSBOVUxMIHBvaW50ZXIsIHRoZSByZXR1cm4gdmFsdWUgaXMgTlVMTC4KKyAgLy8gQWZ0ZXIgdGhpcyBvcGVyYXRpb24sIHRoaXMgb2JqZWN0IHdpbGwgaG9sZCBhIE5VTEwgcG9pbnRlciwKKyAgLy8gYW5kIHdpbGwgbm90IG93biB0aGUgb2JqZWN0IGFueSBtb3JlLgorICBDKiByZWxlYXNlKCkgeworICAgIEMqIHJldFZhbCA9IGFycmF5XzsKKyAgICBhcnJheV8gPSBOVUxMOworICAgIHJldHVybiByZXRWYWw7CisgIH0KKworIHByaXZhdGU6CisgIEMqIGFycmF5XzsKKworICAvLyBGb3JiaWQgY29tcGFyaXNvbiBvZiBkaWZmZXJlbnQgc2NvcGVkX2FycmF5IHR5cGVzLgorICB0ZW1wbGF0ZSA8Y2xhc3MgQzI+IGJvb2wgb3BlcmF0b3I9PShzY29wZWRfYXJyYXk8QzI+IGNvbnN0JiBwMikgY29uc3Q7CisgIHRlbXBsYXRlIDxjbGFzcyBDMj4gYm9vbCBvcGVyYXRvciE9KHNjb3BlZF9hcnJheTxDMj4gY29uc3QmIHAyKSBjb25zdDsKKworICAvLyBEaXNhbGxvdyBldmlsIGNvbnN0cnVjdG9ycworICBzY29wZWRfYXJyYXkoY29uc3Qgc2NvcGVkX2FycmF5Jik7CisgIHZvaWQgb3BlcmF0b3I9KGNvbnN0IHNjb3BlZF9hcnJheSYpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCisKKy8vIFdlIG1hZGUgdGhlc2UgaW50ZXJuYWwgc28gdGhhdCB0aGV5IHdvdWxkIHNob3cgdXAgYXMgc3VjaCBpbiB0aGUgZG9jcywKKy8vIGJ1dCB3ZSBkb24ndCB3YW50IHRvIHN0aWNrICJpbnRlcm5hbDo6IiBpbiBmcm9udCBvZiB0aGVtIGV2ZXJ5d2hlcmUuCit1c2luZyBpbnRlcm5hbDo6c2NvcGVkX3B0cjsKK3VzaW5nIGludGVybmFsOjpzY29wZWRfYXJyYXk7CisKKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX1NUVUJTX1NDT1BFRF9QVFJfSF8KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvc2hhcmVkX3B0ci5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zaGFyZWRfcHRyLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDI1MGJmNAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvc2hhcmVkX3B0ci5oCkBAIC0wLDAgKzEsNDcwIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDE0IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gZnJvbSBnb29nbGUzL3V0aWwvZ3RsL3NoYXJlZF9wdHIuaAorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9TVFVCU19TSEFSRURfUFRSX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfU1RVQlNfU0hBUkVEX1BUUl9IX18KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9hdG9taWNvcHMuaD4KKworI2luY2x1ZGUgPGFsZ29yaXRobT4gIC8vIGZvciBzd2FwCisjaW5jbHVkZSA8c3RkZGVmLmg+CisjaW5jbHVkZSA8bWVtb3J5PgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW50ZXJuYWwgeworCisvLyBBbGlhcyB0byBzdGQ6OnNoYXJlZF9wdHIgZm9yIGFueSBDKysxMSBwbGF0Zm9ybSwKKy8vIGFuZCBmb3IgYW55IHN1cHBvcnRlZCBNU1ZDIGNvbXBpbGVyLgorI2lmICFkZWZpbmVkKFVUSUxfR1RMX1VTRV9TVERfU0hBUkVEX1BUUikgJiYgXAorICAgIChkZWZpbmVkKENPTVBJTEVSX01TVkMpIHx8IGRlZmluZWQoTEFOR19DWFgxMSkpCisjZGVmaW5lIFVUSUxfR1RMX1VTRV9TVERfU0hBUkVEX1BUUiAxCisjZW5kaWYKKworI2lmIGRlZmluZWQoVVRJTF9HVExfVVNFX1NURF9TSEFSRURfUFRSKSAmJiBVVElMX0dUTF9VU0VfU1REX1NIQVJFRF9QVFIKKworLy8gVGhlc2UgYXJlIHRyYW5zaXRpb25hbC4gIFRoZXkgd2lsbCBiZSBnb2luZyBhd2F5IHNvb24uCisvLyBQbGVhc2UganVzdCAjaW5jbHVkZSA8bWVtb3J5PiBhbmQganVzdCB0eXBlIHN0ZDo6c2hhcmVkX3B0ciB5b3Vyc2VsZiwgaW5zdGVhZAorLy8gb2YgcmVseWluZyBvbiB0aGlzIGZpbGUuCisvLworLy8gTWlncmF0aW9uIGRvYzogaHR0cDovL2dvL3N0ZC1zaGFyZWQtcHRyLWxzYwordXNpbmcgc3RkOjplbmFibGVfc2hhcmVkX2Zyb21fdGhpczsKK3VzaW5nIHN0ZDo6c2hhcmVkX3B0cjsKK3VzaW5nIHN0ZDo6c3RhdGljX3BvaW50ZXJfY2FzdDsKK3VzaW5nIHN0ZDo6d2Vha19wdHI7CisKKyNlbHNlICAvLyBiZWxvdywgVVRJTF9HVExfVVNFX1NURF9TSEFSRURfUFRSIG5vdCBzZXQgb3Igc2V0IHRvIDAuCisKKy8vIEZvciBldmVyeXRoaW5nIGVsc2UgdGhlcmUgaXMgdGhlIGdvb2dsZTMgaW1wbGVtZW50YXRpb24uCitpbmxpbmUgYm9vbCBSZWZDb3VudERlYyh2b2xhdGlsZSBBdG9taWMzMiAqcHRyKSB7CisgIHJldHVybiBCYXJyaWVyX0F0b21pY0luY3JlbWVudChwdHIsIC0xKSAhPSAwOworfQorCitpbmxpbmUgdm9pZCBSZWZDb3VudEluYyh2b2xhdGlsZSBBdG9taWMzMiAqcHRyKSB7CisgIE5vQmFycmllcl9BdG9taWNJbmNyZW1lbnQocHRyLCAxKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIFQ+IGNsYXNzIHNoYXJlZF9wdHI7Cit0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4gY2xhc3Mgd2Vha19wdHI7CisKKy8vIFRoaXMgY2xhc3MgaXMgYW4gaW50ZXJuYWwgaW1wbGVtZW50YXRpb24gZGV0YWlsIGZvciBzaGFyZWRfcHRyLiBJZiB0d28KKy8vIHNoYXJlZF9wdHJzIHBvaW50IHRvIHRoZSBzYW1lIG9iamVjdCwgdGhleSBhbHNvIHNoYXJlIGEgY29udHJvbCBibG9jay4KKy8vIEFuICJlbXB0eSIgc2hhcmVkX3BvaW50ZXIgcmVmZXJzIHRvIE5VTEwgYW5kIGFsc28gaGFzIGEgTlVMTCBjb250cm9sIGJsb2NrLgorLy8gSXQgY29udGFpbnMgYWxsIG9mIHRoZSBzdGF0ZSB0aGF0J3MgbmVlZGVkIGZvciByZWZlcmVuY2UgY291bnRpbmcgb3IgYW55CisvLyBvdGhlciBraW5kIG9mIHJlc291cmNlIG1hbmFnZW1lbnQuIEluIHRoaXMgaW1wbGVtZW50YXRpb24gdGhlIGNvbnRyb2wgYmxvY2sKKy8vIGhhcHBlbnMgdG8gY29uc2lzdCBvZiB0d28gYXRvbWljIHdvcmRzLCB0aGUgcmVmZXJlbmNlIGNvdW50ICh0aGUgbnVtYmVyCisvLyBvZiBzaGFyZWRfcHRycyB0aGF0IHNoYXJlIG93bmVyc2hpcCBvZiB0aGUgb2JqZWN0KSBhbmQgdGhlIHdlYWsgY291bnQKKy8vICh0aGUgbnVtYmVyIG9mIHdlYWtfcHRycyB0aGF0IG9ic2VydmUgdGhlIG9iamVjdCwgcGx1cyAxIGlmIHRoZQorLy8gcmVmY291bnQgaXMgbm9uemVybykuCisvLworLy8gVGhlICJwbHVzIDEiIGlzIHRvIHByZXZlbnQgYSByYWNlIGNvbmRpdGlvbiBpbiB0aGUgc2hhcmVkX3B0ciBhbmQKKy8vIHdlYWtfcHRyIGRlc3RydWN0b3JzLiBXZSBuZWVkIHRvIG1ha2Ugc3VyZSB0aGUgY29udHJvbCBibG9jayBpcworLy8gb25seSBkZWxldGVkIG9uY2UsIHNvIHdlIG5lZWQgdG8gbWFrZSBzdXJlIHRoYXQgYXQgbW9zdCBvbmUKKy8vIG9iamVjdCBzZWVzIHRoZSB3ZWFrIGNvdW50IGRlY3JlbWVudGVkIGZyb20gMSB0byAwLgorY2xhc3MgU2hhcmVkUHRyQ29udHJvbEJsb2NrIHsKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFQ+IGZyaWVuZCBjbGFzcyBzaGFyZWRfcHRyOworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4gZnJpZW5kIGNsYXNzIHdlYWtfcHRyOworIHByaXZhdGU6CisgIFNoYXJlZFB0ckNvbnRyb2xCbG9jaygpIDogcmVmY291bnRfKDEpLCB3ZWFrX2NvdW50XygxKSB7IH0KKyAgQXRvbWljMzIgcmVmY291bnRfOworICBBdG9taWMzMiB3ZWFrX2NvdW50XzsKK307CisKKy8vIEZvcndhcmQgZGVjbGFyYXRpb24uIFRoZSBjbGFzcyBpcyBkZWZpbmVkIGJlbG93LgordGVtcGxhdGUgPHR5cGVuYW1lIFQ+IGNsYXNzIGVuYWJsZV9zaGFyZWRfZnJvbV90aGlzOworCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4KK2NsYXNzIHNoYXJlZF9wdHIgeworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVT4gZnJpZW5kIGNsYXNzIHdlYWtfcHRyOworIHB1YmxpYzoKKyAgdHlwZWRlZiBUIGVsZW1lbnRfdHlwZTsKKworICBzaGFyZWRfcHRyKCkgOiBwdHJfKE5VTEwpLCBjb250cm9sX2Jsb2NrXyhOVUxMKSB7fQorCisgIGV4cGxpY2l0IHNoYXJlZF9wdHIoVCogcHRyKQorICAgICAgOiBwdHJfKHB0ciksCisgICAgICAgIGNvbnRyb2xfYmxvY2tfKHB0ciAhPSBOVUxMID8gbmV3IFNoYXJlZFB0ckNvbnRyb2xCbG9jayA6IE5VTEwpIHsKKyAgICAvLyBJZiBwIGlzIG5vbi1udWxsIGFuZCBUIGluaGVyaXRzIGZyb20gZW5hYmxlX3NoYXJlZF9mcm9tX3RoaXMsIHdlCisgICAgLy8gc2V0IHVwIHRoZSBkYXRhIHRoYXQgc2hhcmVkX2Zyb21fdGhpcyBuZWVkcy4KKyAgICBNYXliZVNldHVwV2Vha1RoaXMocHRyKTsKKyAgfQorCisgIC8vIENvcHkgY29uc3RydWN0b3I6IG1ha2VzIHRoaXMgb2JqZWN0IGEgY29weSBvZiBwdHIsIGFuZCBpbmNyZW1lbnRzCisgIC8vIHRoZSByZWZlcmVuY2UgY291bnQuCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBVPgorICBzaGFyZWRfcHRyKGNvbnN0IHNoYXJlZF9wdHI8VT4mIHB0cikKKyAgICAgIDogcHRyXyhOVUxMKSwKKyAgICAgICAgY29udHJvbF9ibG9ja18oTlVMTCkgeworICAgIEluaXRpYWxpemUocHRyKTsKKyAgfQorICAvLyBOZWVkIG5vbi10ZW1wbGF0ZWQgdmVyc2lvbiB0byBwcmV2ZW50IHRoZSBjb21waWxlci1nZW5lcmF0ZWQgZGVmYXVsdAorICBzaGFyZWRfcHRyKGNvbnN0IHNoYXJlZF9wdHI8VD4mIHB0cikKKyAgICAgIDogcHRyXyhOVUxMKSwKKyAgICAgICAgY29udHJvbF9ibG9ja18oTlVMTCkgeworICAgIEluaXRpYWxpemUocHRyKTsKKyAgfQorCisgIC8vIEFzc2lnbm1lbnQgb3BlcmF0b3IuIFJlcGxhY2VzIHRoZSBleGlzdGluZyBzaGFyZWRfcHRyIHdpdGggcHRyLgorICAvLyBJbmNyZW1lbnQgcHRyJ3MgcmVmZXJlbmNlIGNvdW50IGFuZCBkZWNyZW1lbnQgdGhlIG9uZSBiZWluZyByZXBsYWNlZC4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFU+CisgIHNoYXJlZF9wdHI8VD4mIG9wZXJhdG9yPShjb25zdCBzaGFyZWRfcHRyPFU+JiBwdHIpIHsKKyAgICBpZiAocHRyXyAhPSBwdHIucHRyXykgeworICAgICAgc2hhcmVkX3B0cjxUPiBtZShwdHIpOyAgIC8vIHdpbGwgaG9sZCBvdXIgcHJldmlvdXMgc3RhdGUgdG8gYmUgZGVzdHJveWVkLgorICAgICAgc3dhcChtZSk7CisgICAgfQorICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIC8vIE5lZWQgbm9uLXRlbXBsYXRlZCB2ZXJzaW9uIHRvIHByZXZlbnQgdGhlIGNvbXBpbGVyLWdlbmVyYXRlZCBkZWZhdWx0CisgIHNoYXJlZF9wdHI8VD4mIG9wZXJhdG9yPShjb25zdCBzaGFyZWRfcHRyPFQ+JiBwdHIpIHsKKyAgICBpZiAocHRyXyAhPSBwdHIucHRyXykgeworICAgICAgc2hhcmVkX3B0cjxUPiBtZShwdHIpOyAgIC8vIHdpbGwgaG9sZCBvdXIgcHJldmlvdXMgc3RhdGUgdG8gYmUgZGVzdHJveWVkLgorICAgICAgc3dhcChtZSk7CisgICAgfQorICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIC8vIFRPRE8oYXVzdGVybik6IENvbnNpZGVyIHByb3ZpZGluZyB0aGlzIGNvbnN0cnVjdG9yLiBUaGUgZHJhZnQgQysrIHN0YW5kYXJkCisgIC8vICgyMC44LjEwLjIuMSkgaW5jbHVkZXMgaXQuIEhvd2V2ZXIsIGl0IHNheXMgdGhhdCB0aGlzIGNvbnN0cnVjdG9yIHRocm93cworICAvLyBhIGJhZF93ZWFrX3B0ciBleGNlcHRpb24gd2hlbiBwdHIgaXMgZXhwaXJlZC4gSXMgaXQgYmV0dGVyIHRvIHByb3ZpZGUgdGhpcworICAvLyBjb25zdHJ1Y3RvciBhbmQgbWFrZSBpdCBkbyBzb21ldGhpbmcgZWxzZSwgbGlrZSBmYWlsIHdpdGggYSBDSEVDSywgb3IgdG8KKyAgLy8gbGVhdmUgdGhpcyBjb25zdHJ1Y3RvciBvdXQgZW50aXJlbHk/CisgIC8vCisgIC8vIHRlbXBsYXRlIDx0eXBlbmFtZSBVPgorICAvLyBzaGFyZWRfcHRyKGNvbnN0IHdlYWtfcHRyPFU+JiBwdHIpOworCisgIH5zaGFyZWRfcHRyKCkgeworICAgIGlmIChwdHJfICE9IE5VTEwpIHsKKyAgICAgIGlmICghUmVmQ291bnREZWMoJmNvbnRyb2xfYmxvY2tfLT5yZWZjb3VudF8pKSB7CisgICAgICAgIGRlbGV0ZSBwdHJfOworCisgICAgICAgIC8vIHdlYWtfY291bnRfIGlzIGRlZmluZWQgYXMgdGhlIG51bWJlciBvZiB3ZWFrX3B0cnMgdGhhdCBvYnNlcnZlCisgICAgICAgIC8vIHB0cl8sIHBsdXMgMSBpZiByZWZjb3VudF8gaXMgbm9uemVyby4KKyAgICAgICAgaWYgKCFSZWZDb3VudERlYygmY29udHJvbF9ibG9ja18tPndlYWtfY291bnRfKSkgeworICAgICAgICAgIGRlbGV0ZSBjb250cm9sX2Jsb2NrXzsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgfQorCisgIC8vIFJlcGxhY2VzIHVuZGVybHlpbmcgcmF3IHBvaW50ZXIgd2l0aCB0aGUgb25lIHBhc3NlZCBpbi4gIFRoZSByZWZlcmVuY2UKKyAgLy8gY291bnQgaXMgc2V0IHRvIG9uZSAob3IgemVybyBpZiB0aGUgcG9pbnRlciBpcyBOVUxMKSBmb3IgdGhlIHBvaW50ZXIKKyAgLy8gYmVpbmcgcGFzc2VkIGluIGFuZCBkZWNyZW1lbnRlZCBmb3IgdGhlIG9uZSBiZWluZyByZXBsYWNlZC4KKyAgLy8KKyAgLy8gSWYgeW91IGhhdmUgYSBjb21waWxhdGlvbiBlcnJvciB3aXRoIHRoaXMgY29kZSwgbWFrZSBzdXJlIHlvdSBhcmVuJ3QKKyAgLy8gcGFzc2luZyBOVUxMLCBudWxscHRyLCBvciAwIHRvIHRoaXMgZnVuY3Rpb24uICBDYWxsIHJlc2V0IHdpdGhvdXQgYW4KKyAgLy8gYXJndW1lbnQgdG8gcmVzZXQgdG8gYSBudWxsIHB0ci4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFk+CisgIHZvaWQgcmVzZXQoWSogcCkgeworICAgIGlmIChwICE9IHB0cl8pIHsKKyAgICAgIHNoYXJlZF9wdHI8VD4gdG1wKHApOworICAgICAgdG1wLnN3YXAoKnRoaXMpOworICAgIH0KKyAgfQorCisgIHZvaWQgcmVzZXQoKSB7CisgICAgcmVzZXQoc3RhdGljX2Nhc3Q8VCo+KE5VTEwpKTsKKyAgfQorCisgIC8vIEV4Y2hhbmdlcyB0aGUgY29udGVudHMgb2YgdGhpcyB3aXRoIHRoZSBjb250ZW50cyBvZiByLiAgVGhpcyBmdW5jdGlvbgorICAvLyBzdXBwb3J0cyBtb3JlIGVmZmljaWVudCBzd2FwcGluZyBzaW5jZSBpdCBlbGltaW5hdGVzIHRoZSBuZWVkIGZvciBhCisgIC8vIHRlbXBvcmFyeSBzaGFyZWRfcHRyIG9iamVjdC4KKyAgdm9pZCBzd2FwKHNoYXJlZF9wdHI8VD4mIHIpIHsKKyAgICB1c2luZyBzdGQ6OnN3YXA7ICAvLyBodHRwOi8vZ28vdXNpbmctc3RkLXN3YXAKKyAgICBzd2FwKHB0cl8sIHIucHRyXyk7CisgICAgc3dhcChjb250cm9sX2Jsb2NrXywgci5jb250cm9sX2Jsb2NrXyk7CisgIH0KKworICAvLyBUaGUgZm9sbG93aW5nIGZ1bmN0aW9uIGlzIHVzZWZ1bCBmb3IgZ2FpbmluZyBhY2Nlc3MgdG8gdGhlIHVuZGVybHlpbmcKKyAgLy8gcG9pbnRlciB3aGVuIGEgc2hhcmVkX3B0ciByZW1haW5zIGluIHNjb3BlIHNvIHRoZSByZWZlcmVuY2UtY291bnQgaXMKKyAgLy8ga25vd24gdG8gYmUgPiAwIChlLmcuIGZvciBwYXJhbWV0ZXIgcGFzc2luZykuCisgIFQqIGdldCgpIGNvbnN0IHsKKyAgICByZXR1cm4gcHRyXzsKKyAgfQorCisgIFQmIG9wZXJhdG9yKigpIGNvbnN0IHsKKyAgICByZXR1cm4gKnB0cl87CisgIH0KKworICBUKiBvcGVyYXRvci0+KCkgY29uc3QgeworICAgIHJldHVybiBwdHJfOworICB9CisKKyAgbG9uZyB1c2VfY291bnQoKSBjb25zdCB7CisgICAgcmV0dXJuIGNvbnRyb2xfYmxvY2tfID8gY29udHJvbF9ibG9ja18tPnJlZmNvdW50XyA6IDE7CisgIH0KKworICBib29sIHVuaXF1ZSgpIGNvbnN0IHsKKyAgICByZXR1cm4gdXNlX2NvdW50KCkgPT0gMTsKKyAgfQorCisgcHJpdmF0ZToKKyAgLy8gSWYgciBpcyBub24tZW1wdHksIGluaXRpYWxpemUgKnRoaXMgdG8gc2hhcmUgb3duZXJzaGlwIHdpdGggciwKKyAgLy8gaW5jcmVhc2luZyB0aGUgdW5kZXJseWluZyByZWZlcmVuY2UgY291bnQuCisgIC8vIElmIHIgaXMgZW1wdHksICp0aGlzIHJlbWFpbnMgZW1wdHkuCisgIC8vIFJlcXVpcmVzOiB0aGlzIGlzIGVtcHR5LCBuYW1lbHkgdGhpcy0+cHRyXyA9PSBOVUxMLgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVT4KKyAgdm9pZCBJbml0aWFsaXplKGNvbnN0IHNoYXJlZF9wdHI8VT4mIHIpIHsKKyAgICAvLyBUaGlzIHBlcmZvcm1zIGEgc3RhdGljX2Nhc3Qgb24gci5wdHJfIHRvIFUqLCB3aGljaCBpcyBhIG5vLW9wIHNpbmNlIGl0CisgICAgLy8gaXMgYWxyZWFkeSBhIFUqLiBTbyBpbml0aWFsaXphdGlvbiBoZXJlIHJlcXVpcmVzIHRoYXQgci5wdHJfIGlzCisgICAgLy8gaW1wbGljaXRseSBjb252ZXJ0aWJsZSB0byBUKi4KKyAgICBJbml0aWFsaXplV2l0aFN0YXRpY0Nhc3Q8VT4ocik7CisgIH0KKworICAvLyBJbml0aWFsaXplcyAqdGhpcyBhcyBkZXNjcmliZWQgaW4gSW5pdGlhbGl6ZSwgYnV0IGFkZGl0aW9uYWxseSBwZXJmb3JtcyBhCisgIC8vIHN0YXRpY19jYXN0IGZyb20gci5wdHJfIChWKikgdG8gVSouCisgIC8vIE5PVEUoZ2ZjKTogV2UnZCBuZWVkIGEgbW9yZSBnZW5lcmFsIGZvcm0gdG8gc3VwcG9ydCBjb25zdF9wb2ludGVyX2Nhc3QgYW5kCisgIC8vIGR5bmFtaWNfcG9pbnRlcl9jYXN0LCBidXQgdGhvc2Ugb3BlcmF0aW9ucyBhcmUgc3VmZmljaWVudGx5IGRpc2NvdXJhZ2VkCisgIC8vIHRoYXQgc3VwcG9ydGluZyBzdGF0aWNfcG9pbnRlcl9jYXN0IGlzIHN1ZmZpY2llbnQuCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBVLCB0eXBlbmFtZSBWPgorICB2b2lkIEluaXRpYWxpemVXaXRoU3RhdGljQ2FzdChjb25zdCBzaGFyZWRfcHRyPFY+JiByKSB7CisgICAgaWYgKHIuY29udHJvbF9ibG9ja18gIT0gTlVMTCkgeworICAgICAgUmVmQ291bnRJbmMoJnIuY29udHJvbF9ibG9ja18tPnJlZmNvdW50Xyk7CisKKyAgICAgIHB0cl8gPSBzdGF0aWNfY2FzdDxVKj4oci5wdHJfKTsKKyAgICAgIGNvbnRyb2xfYmxvY2tfID0gci5jb250cm9sX2Jsb2NrXzsKKyAgICB9CisgIH0KKworICAvLyBIZWxwZXIgZnVuY3Rpb24gZm9yIHRoZSBjb25zdHJ1Y3RvciB0aGF0IHRha2VzIGEgcmF3IHBvaW50ZXIuIElmIFQKKyAgLy8gZG9lc24ndCBpbmhlcml0IGZyb20gZW5hYmxlX3NoYXJlZF9mcm9tX3RoaXM8VD4gdGhlbiB3ZSBoYXZlIG5vdGhpbmcgdG8KKyAgLy8gZG8sIHNvIHRoaXMgZnVuY3Rpb24gaXMgdHJpdmlhbCBhbmQgaW5saW5lLiBUaGUgb3RoZXIgdmVyc2lvbiBpcyBkZWNsYXJlZAorICAvLyBvdXQgb2YgbGluZSwgYWZ0ZXIgdGhlIGNsYXNzIGRlZmluaXRpb24gb2YgZW5hYmxlX3NoYXJlZF9mcm9tX3RoaXMuCisgIHZvaWQgTWF5YmVTZXR1cFdlYWtUaGlzKGVuYWJsZV9zaGFyZWRfZnJvbV90aGlzPFQ+KiBwdHIpOworICB2b2lkIE1heWJlU2V0dXBXZWFrVGhpcyguLi4pIHsgfQorCisgIFQqIHB0cl87CisgIFNoYXJlZFB0ckNvbnRyb2xCbG9jayogY29udHJvbF9ibG9ja187CisKKyNpZm5kZWYgU1dJRworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVT4KKyAgZnJpZW5kIGNsYXNzIHNoYXJlZF9wdHI7CisKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFUsIHR5cGVuYW1lIFY+CisgIGZyaWVuZCBzaGFyZWRfcHRyPFU+IHN0YXRpY19wb2ludGVyX2Nhc3QoY29uc3Qgc2hhcmVkX3B0cjxWPiYgcmhzKTsKKyNlbmRpZgorfTsKKworLy8gTWF0Y2hlcyB0aGUgaW50ZXJmYWNlIG9mIHN0ZDo6c3dhcCBhcyBhbiBhaWQgdG8gZ2VuZXJpYyBwcm9ncmFtbWluZy4KK3RlbXBsYXRlIDx0eXBlbmFtZSBUPiB2b2lkIHN3YXAoc2hhcmVkX3B0cjxUPiYgciwgc2hhcmVkX3B0cjxUPiYgcykgeworICByLnN3YXAocyk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBULCB0eXBlbmFtZSBVPgorc2hhcmVkX3B0cjxUPiBzdGF0aWNfcG9pbnRlcl9jYXN0KGNvbnN0IHNoYXJlZF9wdHI8VT4mIHJocykgeworICBzaGFyZWRfcHRyPFQ+IGxoczsKKyAgbGhzLnRlbXBsYXRlIEluaXRpYWxpemVXaXRoU3RhdGljQ2FzdDxUPihyaHMpOworICByZXR1cm4gbGhzOworfQorCisvLyBTZWUgY29tbWVudHMgYXQgdGhlIHRvcCBvZiB0aGUgZmlsZSBmb3IgYSBkZXNjcmlwdGlvbiBvZiB3aHkgdGhpcworLy8gY2xhc3MgZXhpc3RzLCBhbmQgdGhlIGRyYWZ0IEMrKyBzdGFuZGFyZCAoYXMgb2YgSnVseSAyMDA5IHRoZQorLy8gbGF0ZXN0IGRyYWZ0IGlzIE4yOTE0KSBmb3IgdGhlIGRldGFpbGVkIHNwZWNpZmljYXRpb24uCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4KK2NsYXNzIHdlYWtfcHRyIHsKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFU+IGZyaWVuZCBjbGFzcyB3ZWFrX3B0cjsKKyBwdWJsaWM6CisgIHR5cGVkZWYgVCBlbGVtZW50X3R5cGU7CisKKyAgLy8gQ3JlYXRlIGFuIGVtcHR5IChpLmUuIGFscmVhZHkgZXhwaXJlZCkgd2Vha19wdHIuCisgIHdlYWtfcHRyKCkgOiBwdHJfKE5VTEwpLCBjb250cm9sX2Jsb2NrXyhOVUxMKSB7IH0KKworICAvLyBDcmVhdGUgYSB3ZWFrX3B0ciB0aGF0IG9ic2VydmVzIHRoZSBzYW1lIG9iamVjdCB0aGF0IHB0ciBwb2ludHMKKyAgLy8gdG8uICBOb3RlIHRoYXQgdGhlcmUgaXMgbm8gcmFjZSBjb25kaXRpb24gaGVyZTogd2Uga25vdyB0aGF0IHRoZQorICAvLyBjb250cm9sIGJsb2NrIGNhbid0IGRpc2FwcGVhciB3aGlsZSB3ZSdyZSBsb29raW5nIGF0IGl0IGJlY2F1c2UKKyAgLy8gaXQgaXMgb3duZWQgYnkgYXQgbGVhc3Qgb25lIHNoYXJlZF9wdHIsIHB0ci4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFU+IHdlYWtfcHRyKGNvbnN0IHNoYXJlZF9wdHI8VT4mIHB0cikgeworICAgIENvcHlGcm9tKHB0ci5wdHJfLCBwdHIuY29udHJvbF9ibG9ja18pOworICB9CisKKyAgLy8gQ29weSBhIHdlYWtfcHRyLiBUaGUgb2JqZWN0IGl0IHBvaW50cyB0byBtaWdodCBkaXNhcHBlYXIsIGJ1dCB3ZQorICAvLyBkb24ndCBjYXJlOiB3ZSdyZSBvbmx5IHdvcmtpbmcgd2l0aCB0aGUgY29udHJvbCBibG9jaywgYW5kIGl0IGNhbid0CisgIC8vIGRpc2FwcGVhciB3aGlsZSB3ZSdyZSBsb29raW5nIGF0IGJlY2F1c2UgaXQncyBvd25lZCBieSBhdCBsZWFzdCBvbmUKKyAgLy8gd2Vha19wdHIsIHB0ci4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFU+IHdlYWtfcHRyKGNvbnN0IHdlYWtfcHRyPFU+JiBwdHIpIHsKKyAgICBDb3B5RnJvbShwdHIucHRyXywgcHRyLmNvbnRyb2xfYmxvY2tfKTsKKyAgfQorCisgIC8vIE5lZWQgbm9uLXRlbXBsYXRlZCB2ZXJzaW9uIHRvIHByZXZlbnQgZGVmYXVsdCBjb3B5IGNvbnN0cnVjdG9yCisgIHdlYWtfcHRyKGNvbnN0IHdlYWtfcHRyJiBwdHIpIHsKKyAgICBDb3B5RnJvbShwdHIucHRyXywgcHRyLmNvbnRyb2xfYmxvY2tfKTsKKyAgfQorCisgIC8vIERlc3Ryb3kgdGhlIHdlYWtfcHRyLiBJZiBubyBzaGFyZWRfcHRyIG93bnMgdGhlIGNvbnRyb2wgYmxvY2ssIGFuZCBpZgorICAvLyB3ZSBhcmUgdGhlIGxhc3Qgd2Vha19wdHIgdG8gb3duIGl0LCB0aGVuIGl0IGNhbiBiZSBkZWxldGVkLiBOb3RlIHRoYXQKKyAgLy8gd2Vha19jb3VudF8gaXMgZGVmaW5lZCBhcyB0aGUgbnVtYmVyIG9mIHdlYWtfcHRycyBzaGFyaW5nIHRoaXMgY29udHJvbAorICAvLyBibG9jaywgcGx1cyAxIGlmIHRoZXJlIGFyZSBhbnkgc2hhcmVkX3B0cnMuIFdlIHRoZXJlZm9yZSBrbm93IHRoYXQgaXQncworICAvLyBzYWZlIHRvIGRlbGV0ZSB0aGUgY29udHJvbCBibG9jayB3aGVuIHdlYWtfY291bnRfIHJlYWNoZXMgMCwgd2l0aG91dAorICAvLyBoYXZpbmcgdG8gcGVyZm9ybSBhbnkgYWRkaXRpb25hbCB0ZXN0cy4KKyAgfndlYWtfcHRyKCkgeworICAgIGlmIChjb250cm9sX2Jsb2NrXyAhPSBOVUxMICYmCisgICAgICAgICFSZWZDb3VudERlYygmY29udHJvbF9ibG9ja18tPndlYWtfY291bnRfKSkgeworICAgICAgZGVsZXRlIGNvbnRyb2xfYmxvY2tfOworICAgIH0KKyAgfQorCisgIHdlYWtfcHRyJiBvcGVyYXRvcj0oY29uc3Qgd2Vha19wdHImIHB0cikgeworICAgIGlmICgmcHRyICE9IHRoaXMpIHsKKyAgICAgIHdlYWtfcHRyIHRtcChwdHIpOworICAgICAgdG1wLnN3YXAoKnRoaXMpOworICAgIH0KKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFU+IHdlYWtfcHRyJiBvcGVyYXRvcj0oY29uc3Qgd2Vha19wdHI8VT4mIHB0cikgeworICAgIHdlYWtfcHRyIHRtcChwdHIpOworICAgIHRtcC5zd2FwKCp0aGlzKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFU+IHdlYWtfcHRyJiBvcGVyYXRvcj0oY29uc3Qgc2hhcmVkX3B0cjxVPiYgcHRyKSB7CisgICAgd2Vha19wdHIgdG1wKHB0cik7CisgICAgdG1wLnN3YXAoKnRoaXMpOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIHZvaWQgc3dhcCh3ZWFrX3B0ciYgcHRyKSB7CisgICAgdXNpbmcgc3RkOjpzd2FwOyAgLy8gaHR0cDovL2dvL3VzaW5nLXN0ZC1zd2FwCisgICAgc3dhcChwdHJfLCBwdHIucHRyXyk7CisgICAgc3dhcChjb250cm9sX2Jsb2NrXywgcHRyLmNvbnRyb2xfYmxvY2tfKTsKKyAgfQorCisgIHZvaWQgcmVzZXQoKSB7CisgICAgd2Vha19wdHIgdG1wOworICAgIHRtcC5zd2FwKCp0aGlzKTsKKyAgfQorCisgIC8vIFJldHVybiB0aGUgbnVtYmVyIG9mIHNoYXJlZF9wdHJzIHRoYXQgb3duIHRoZSBvYmplY3Qgd2UgYXJlIG9ic2VydmluZy4KKyAgLy8gTm90ZSB0aGF0IHRoaXMgbnVtYmVyIGNhbiBiZSAwIChpZiB0aGlzIHBvaW50ZXIgaGFzIGV4cGlyZWQpLgorICBsb25nIHVzZV9jb3VudCgpIGNvbnN0IHsKKyAgICByZXR1cm4gY29udHJvbF9ibG9ja18gIT0gTlVMTCA/IGNvbnRyb2xfYmxvY2tfLT5yZWZjb3VudF8gOiAwOworICB9CisKKyAgYm9vbCBleHBpcmVkKCkgY29uc3QgeyByZXR1cm4gdXNlX2NvdW50KCkgPT0gMDsgfQorCisgIC8vIFJldHVybiBhIHNoYXJlZF9wdHIgdGhhdCBvd25zIHRoZSBvYmplY3Qgd2UgYXJlIG9ic2VydmluZy4gSWYgd2UKKyAgLy8gaGF2ZSBleHBpcmVkLCB0aGUgc2hhcmVkX3B0ciB3aWxsIGJlIGVtcHR5LiBXZSBoYXZlIHRvIGJlIGNhcmVmdWwKKyAgLy8gYWJvdXQgY29uY3VycmVuY3ksIHRob3VnaCwgc2luY2Ugc29tZSBvdGhlciB0aHJlYWQgbWlnaHQgYmUKKyAgLy8gZGVzdHJveWluZyB0aGUgbGFzdCBvd25pbmcgc2hhcmVkX3B0ciB3aGlsZSB3ZSdyZSBpbiB0aGlzCisgIC8vIGZ1bmN0aW9uLiAgV2Ugd2FudCB0byBpbmNyZW1lbnQgdGhlIHJlZmNvdW50IG9ubHkgaWYgaXQncyBub256ZXJvCisgIC8vIGFuZCBnZXQgdGhlIG5ldyB2YWx1ZSwgYW5kIHdlIHdhbnQgdGhhdCB3aG9sZSBvcGVyYXRpb24gdG8gYmUKKyAgLy8gYXRvbWljLgorICBzaGFyZWRfcHRyPFQ+IGxvY2soKSBjb25zdCB7CisgICAgc2hhcmVkX3B0cjxUPiByZXN1bHQ7CisgICAgaWYgKGNvbnRyb2xfYmxvY2tfICE9IE5VTEwpIHsKKyAgICAgIEF0b21pYzMyIG9sZF9yZWZjb3VudDsKKyAgICAgIGRvIHsKKyAgICAgICAgb2xkX3JlZmNvdW50ID0gY29udHJvbF9ibG9ja18tPnJlZmNvdW50XzsKKyAgICAgICAgaWYgKG9sZF9yZWZjb3VudCA9PSAwKQorICAgICAgICAgIGJyZWFrOworICAgICAgfSB3aGlsZSAob2xkX3JlZmNvdW50ICE9CisgICAgICAgICAgICAgICBOb0JhcnJpZXJfQ29tcGFyZUFuZFN3YXAoCisgICAgICAgICAgICAgICAgICAgJmNvbnRyb2xfYmxvY2tfLT5yZWZjb3VudF8sIG9sZF9yZWZjb3VudCwKKyAgICAgICAgICAgICAgICAgICBvbGRfcmVmY291bnQgKyAxKSk7CisgICAgICBpZiAob2xkX3JlZmNvdW50ID4gMCkgeworICAgICAgICByZXN1bHQucHRyXyA9IHB0cl87CisgICAgICAgIHJlc3VsdC5jb250cm9sX2Jsb2NrXyA9IGNvbnRyb2xfYmxvY2tfOworICAgICAgfQorICAgIH0KKworICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworIHByaXZhdGU6CisgIHZvaWQgQ29weUZyb20oVCogcHRyLCBTaGFyZWRQdHJDb250cm9sQmxvY2sqIGNvbnRyb2xfYmxvY2spIHsKKyAgICBwdHJfID0gcHRyOworICAgIGNvbnRyb2xfYmxvY2tfID0gY29udHJvbF9ibG9jazsKKyAgICBpZiAoY29udHJvbF9ibG9ja18gIT0gTlVMTCkKKyAgICAgIFJlZkNvdW50SW5jKCZjb250cm9sX2Jsb2NrXy0+d2Vha19jb3VudF8pOworICB9CisKKyBwcml2YXRlOgorICBlbGVtZW50X3R5cGUqIHB0cl87CisgIFNoYXJlZFB0ckNvbnRyb2xCbG9jayogY29udHJvbF9ibG9ja187Cit9OworCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4gdm9pZCBzd2FwKHdlYWtfcHRyPFQ+JiByLCB3ZWFrX3B0cjxUPiYgcykgeworICByLnN3YXAocyk7Cit9CisKKy8vIFNlZSBjb21tZW50cyBhdCB0aGUgdG9wIG9mIHRoZSBmaWxlIGZvciBhIGRlc2NyaXB0aW9uIG9mIHdoeSB0aGlzIGNsYXNzCisvLyBleGlzdHMsIGFuZCBzZWN0aW9uIDIwLjguMTAuNSBvZiB0aGUgZHJhZnQgQysrIHN0YW5kYXJkIChhcyBvZiBKdWx5IDIwMDkKKy8vIHRoZSBsYXRlc3QgZHJhZnQgaXMgTjI5MTQpIGZvciB0aGUgZGV0YWlsZWQgc3BlY2lmaWNhdGlvbi4KK3RlbXBsYXRlIDx0eXBlbmFtZSBUPgorY2xhc3MgZW5hYmxlX3NoYXJlZF9mcm9tX3RoaXMgeworICBmcmllbmQgY2xhc3Mgc2hhcmVkX3B0cjxUPjsKKyBwdWJsaWM6CisgIC8vIFByZWNvbmRpdGlvbjogdGhlcmUgbXVzdCBiZSBhIHNoYXJlZF9wdHIgdGhhdCBvd25zICp0aGlzIGFuZCB0aGF0IHdhcworICAvLyBjcmVhdGVkLCBkaXJlY3RseSBvciBpbmRpcmVjdGx5LCBmcm9tIGEgcmF3IHBvaW50ZXIgb2YgdHlwZSBUKi4gKFRoZQorICAvLyBsYXR0ZXIgcGFydCBvZiB0aGUgY29uZGl0aW9uIGlzIHRlY2huaWNhbCBidXQgbm90IHF1aXRlIHJlZHVuZGFudDsgaXQKKyAgLy8gcnVsZXMgb3V0IHNvbWUgY29tcGxpY2F0ZWQgdXNlcyBpbnZvbHZpbmcgaW5oZXJpdGFuY2UgaGllcmFyY2hpZXMuKQorICBzaGFyZWRfcHRyPFQ+IHNoYXJlZF9mcm9tX3RoaXMoKSB7CisgICAgLy8gQmVoYXZpb3IgaXMgdW5kZWZpbmVkIGlmIHRoZSBwcmVjb25kaXRpb24gaXNuJ3Qgc2F0aXNmaWVkOyB3ZSBjaG9vc2UKKyAgICAvLyB0byBkaWUgd2l0aCBhIENIRUNLIGZhaWx1cmUuCisgICAgQ0hFQ0soIXdlYWtfdGhpc18uZXhwaXJlZCgpKSA8PCAiTm8gc2hhcmVkX3B0ciBvd25zIHRoaXMgb2JqZWN0IjsKKyAgICByZXR1cm4gd2Vha190aGlzXy5sb2NrKCk7CisgIH0KKyAgc2hhcmVkX3B0cjxjb25zdCBUPiBzaGFyZWRfZnJvbV90aGlzKCkgY29uc3QgeworICAgIENIRUNLKCF3ZWFrX3RoaXNfLmV4cGlyZWQoKSkgPDwgIk5vIHNoYXJlZF9wdHIgb3ducyB0aGlzIG9iamVjdCI7CisgICAgcmV0dXJuIHdlYWtfdGhpc18ubG9jaygpOworICB9CisKKyBwcm90ZWN0ZWQ6CisgIGVuYWJsZV9zaGFyZWRfZnJvbV90aGlzKCkgeyB9CisgIGVuYWJsZV9zaGFyZWRfZnJvbV90aGlzKGNvbnN0IGVuYWJsZV9zaGFyZWRfZnJvbV90aGlzJiBvdGhlcikgeyB9CisgIGVuYWJsZV9zaGFyZWRfZnJvbV90aGlzJiBvcGVyYXRvcj0oY29uc3QgZW5hYmxlX3NoYXJlZF9mcm9tX3RoaXMmIG90aGVyKSB7CisgICAgcmV0dXJuICp0aGlzOworICB9CisgIH5lbmFibGVfc2hhcmVkX2Zyb21fdGhpcygpIHsgfQorCisgcHJpdmF0ZToKKyAgd2Vha19wdHI8VD4gd2Vha190aGlzXzsKK307CisKKy8vIFRoaXMgaXMgYSBoZWxwZXIgZnVuY3Rpb24gY2FsbGVkIGJ5IHNoYXJlZF9wdHIncyBjb25zdHJ1Y3RvciBmcm9tIGEgcmF3CisvLyBwb2ludGVyLiBJZiBUIGluaGVyaXRzIGZyb20gZW5hYmxlX3NoYXJlZF9mcm9tX3RoaXM8VD4sIGl0IHNldHMgdXAKKy8vIHdlYWtfdGhpc18gc28gdGhhdCBzaGFyZWRfZnJvbV90aGlzIHdvcmtzIGNvcnJlY3RseS4gSWYgVCBkb2VzIG5vdCBpbmhlcml0CisvLyBmcm9tIHdlYWtfdGhpcyB3ZSBnZXQgYSBkaWZmZXJlbnQgb3ZlcmxvYWQsIGRlZmluZWQgaW5saW5lLCB3aGljaCBkb2VzCisvLyBub3RoaW5nLgordGVtcGxhdGU8dHlwZW5hbWUgVD4KK3ZvaWQgc2hhcmVkX3B0cjxUPjo6TWF5YmVTZXR1cFdlYWtUaGlzKGVuYWJsZV9zaGFyZWRfZnJvbV90aGlzPFQ+KiBwdHIpIHsKKyAgaWYgKHB0cikgeworICAgIENIRUNLKHB0ci0+d2Vha190aGlzXy5leHBpcmVkKCkpIDw8ICJPYmplY3QgYWxyZWFkeSBvd25lZCBieSBhIHNoYXJlZF9wdHIiOworICAgIHB0ci0+d2Vha190aGlzXyA9ICp0aGlzOworICB9Cit9CisKKyNlbmRpZiAgLy8gVVRJTF9HVExfVVNFX1NURF9TSEFSRURfUFRSCisKK30gIC8vIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfU1RVQlNfU0hBUkVEX1BUUl9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvc2luZ2xldG9uLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NpbmdsZXRvbi5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkzMDFmNTQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NpbmdsZXRvbi5oCkBAIC0wLDAgKzEsNjggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMTQgR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfU1RVQlNfU0lOR0xFVE9OX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfU1RVQlNfU0lOR0xFVE9OX0hfXworCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2F0b21pY29wcy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvb25jZS5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW50ZXJuYWwgewordGVtcGxhdGU8dHlwZW5hbWUgVD4KK2NsYXNzIFNpbmdsZXRvbiB7CisgcHVibGljOgorICBzdGF0aWMgVCogZ2V0KCkgeworICAgIEdvb2dsZU9uY2VJbml0KCZvbmNlXywgJlNpbmdsZXRvbjxUPjo6SW5pdCk7CisgICAgcmV0dXJuIGluc3RhbmNlXzsKKyAgfQorICBzdGF0aWMgdm9pZCBTaHV0RG93bigpIHsKKyAgICBkZWxldGUgaW5zdGFuY2VfOworICAgIGluc3RhbmNlXyA9IE5VTEw7CisgIH0KKyBwcml2YXRlOgorICBzdGF0aWMgdm9pZCBJbml0KCkgeworICAgIGluc3RhbmNlXyA9IG5ldyBUKCk7CisgIH0KKyAgc3RhdGljIFByb3RvYnVmT25jZVR5cGUgb25jZV87CisgIHN0YXRpYyBUKiBpbnN0YW5jZV87Cit9OworCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorUHJvdG9idWZPbmNlVHlwZSBTaW5nbGV0b248VD46Om9uY2VfOworCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorVCogU2luZ2xldG9uPFQ+OjppbnN0YW5jZV8gPSBOVUxMOworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfU1RVQlNfU0lOR0xFVE9OX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdGF0dXMuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0YXR1cy5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZDFiZDYxCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdGF0dXMuY2MKQEAgLTAsMCArMSwxMzQgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdGF0dXMuaD4KKworI2luY2x1ZGUgPG9zdHJlYW0+CisjaW5jbHVkZSA8c3RkaW8uaD4KKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8dXRpbGl0eT4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIHV0aWwgeworbmFtZXNwYWNlIGVycm9yIHsKK2lubGluZSBzdHJpbmcgQ29kZUVudW1Ub1N0cmluZyhlcnJvcjo6Q29kZSBjb2RlKSB7CisgIHN3aXRjaCAoY29kZSkgeworICAgIGNhc2UgT0s6CisgICAgICByZXR1cm4gIk9LIjsKKyAgICBjYXNlIENBTkNFTExFRDoKKyAgICAgIHJldHVybiAiQ0FOQ0VMTEVEIjsKKyAgICBjYXNlIFVOS05PV046CisgICAgICByZXR1cm4gIlVOS05PV04iOworICAgIGNhc2UgSU5WQUxJRF9BUkdVTUVOVDoKKyAgICAgIHJldHVybiAiSU5WQUxJRF9BUkdVTUVOVCI7CisgICAgY2FzZSBERUFETElORV9FWENFRURFRDoKKyAgICAgIHJldHVybiAiREVBRExJTkVfRVhDRUVERUQiOworICAgIGNhc2UgTk9UX0ZPVU5EOgorICAgICAgcmV0dXJuICJOT1RfRk9VTkQiOworICAgIGNhc2UgQUxSRUFEWV9FWElTVFM6CisgICAgICByZXR1cm4gIkFMUkVBRFlfRVhJU1RTIjsKKyAgICBjYXNlIFBFUk1JU1NJT05fREVOSUVEOgorICAgICAgcmV0dXJuICJQRVJNSVNTSU9OX0RFTklFRCI7CisgICAgY2FzZSBVTkFVVEhFTlRJQ0FURUQ6CisgICAgICByZXR1cm4gIlVOQVVUSEVOVElDQVRFRCI7CisgICAgY2FzZSBSRVNPVVJDRV9FWEhBVVNURUQ6CisgICAgICByZXR1cm4gIlJFU09VUkNFX0VYSEFVU1RFRCI7CisgICAgY2FzZSBGQUlMRURfUFJFQ09ORElUSU9OOgorICAgICAgcmV0dXJuICJGQUlMRURfUFJFQ09ORElUSU9OIjsKKyAgICBjYXNlIEFCT1JURUQ6CisgICAgICByZXR1cm4gIkFCT1JURUQiOworICAgIGNhc2UgT1VUX09GX1JBTkdFOgorICAgICAgcmV0dXJuICJPVVRfT0ZfUkFOR0UiOworICAgIGNhc2UgVU5JTVBMRU1FTlRFRDoKKyAgICAgIHJldHVybiAiVU5JTVBMRU1FTlRFRCI7CisgICAgY2FzZSBJTlRFUk5BTDoKKyAgICAgIHJldHVybiAiSU5URVJOQUwiOworICAgIGNhc2UgVU5BVkFJTEFCTEU6CisgICAgICByZXR1cm4gIlVOQVZBSUxBQkxFIjsKKyAgICBjYXNlIERBVEFfTE9TUzoKKyAgICAgIHJldHVybiAiREFUQV9MT1NTIjsKKyAgfQorCisgIC8vIE5vIGRlZmF1bHQgY2xhdXNlLCBjbGFuZyB3aWxsIGFib3J0IGlmIGEgY29kZSBpcyBtaXNzaW5nIGZyb20KKyAgLy8gYWJvdmUgc3dpdGNoLgorICByZXR1cm4gIlVOS05PV04iOworfQorfSAgLy8gbmFtZXNwYWNlIGVycm9yLgorCitjb25zdCBTdGF0dXMgU3RhdHVzOjpPSyA9IFN0YXR1cygpOworY29uc3QgU3RhdHVzIFN0YXR1czo6Q0FOQ0VMTEVEID0gU3RhdHVzKGVycm9yOjpDQU5DRUxMRUQsICIiKTsKK2NvbnN0IFN0YXR1cyBTdGF0dXM6OlVOS05PV04gPSBTdGF0dXMoZXJyb3I6OlVOS05PV04sICIiKTsKKworU3RhdHVzOjpTdGF0dXMoKSA6IGVycm9yX2NvZGVfKGVycm9yOjpPSykgeworfQorCitTdGF0dXM6OlN0YXR1cyhlcnJvcjo6Q29kZSBlcnJvcl9jb2RlLCBTdHJpbmdQaWVjZSBlcnJvcl9tZXNzYWdlKQorICAgIDogZXJyb3JfY29kZV8oZXJyb3JfY29kZSkgeworICBpZiAoZXJyb3JfY29kZSAhPSBlcnJvcjo6T0spIHsKKyAgICBlcnJvcl9tZXNzYWdlXyA9IGVycm9yX21lc3NhZ2UuVG9TdHJpbmcoKTsKKyAgfQorfQorCitTdGF0dXM6OlN0YXR1cyhjb25zdCBTdGF0dXMmIG90aGVyKQorICAgIDogZXJyb3JfY29kZV8ob3RoZXIuZXJyb3JfY29kZV8pLCBlcnJvcl9tZXNzYWdlXyhvdGhlci5lcnJvcl9tZXNzYWdlXykgeworfQorCitTdGF0dXMmIFN0YXR1czo6b3BlcmF0b3I9KGNvbnN0IFN0YXR1cyYgb3RoZXIpIHsKKyAgZXJyb3JfY29kZV8gPSBvdGhlci5lcnJvcl9jb2RlXzsKKyAgZXJyb3JfbWVzc2FnZV8gPSBvdGhlci5lcnJvcl9tZXNzYWdlXzsKKyAgcmV0dXJuICp0aGlzOworfQorCitib29sIFN0YXR1czo6b3BlcmF0b3I9PShjb25zdCBTdGF0dXMmIHgpIGNvbnN0IHsKKyAgcmV0dXJuIGVycm9yX2NvZGVfID09IHguZXJyb3JfY29kZV8gJiYKKyAgICAgIGVycm9yX21lc3NhZ2VfID09IHguZXJyb3JfbWVzc2FnZV87Cit9CisKK3N0cmluZyBTdGF0dXM6OlRvU3RyaW5nKCkgY29uc3QgeworICBpZiAoZXJyb3JfY29kZV8gPT0gZXJyb3I6Ok9LKSB7CisgICAgcmV0dXJuICJPSyI7CisgIH0gZWxzZSB7CisgICAgaWYgKGVycm9yX21lc3NhZ2VfLmVtcHR5KCkpIHsKKyAgICAgIHJldHVybiBlcnJvcjo6Q29kZUVudW1Ub1N0cmluZyhlcnJvcl9jb2RlXyk7CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiBlcnJvcjo6Q29kZUVudW1Ub1N0cmluZyhlcnJvcl9jb2RlXykgKyAiOiIgKworICAgICAgICAgIGVycm9yX21lc3NhZ2VfOworICAgIH0KKyAgfQorfQorCitvc3RyZWFtJiBvcGVyYXRvcjw8KG9zdHJlYW0mIG9zLCBjb25zdCBTdGF0dXMmIHgpIHsKKyAgb3MgPDwgeC5Ub1N0cmluZygpOworICByZXR1cm4gb3M7Cit9CisKK30gIC8vIG5hbWVzcGFjZSB1dGlsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvc3RhdHVzLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0YXR1cy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYxNGFiOTkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0YXR1cy5oCkBAIC0wLDAgKzEsMTE2IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX1NUVUJTX1NUQVRVU19IXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfU1RVQlNfU1RBVFVTX0hfCisKKyNpbmNsdWRlIDxpb3Nmd2Q+CisjaW5jbHVkZSA8c3RyaW5nPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJpbmdwaWVjZS5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgdXRpbCB7CituYW1lc3BhY2UgZXJyb3IgeworLy8gVGhlc2UgdmFsdWVzIG11c3QgbWF0Y2ggZXJyb3IgY29kZXMgZGVmaW5lZCBpbiBnb29nbGUvcnBjL2NvZGUucHJvdG8uCitlbnVtIENvZGUgeworICBPSyA9IDAsCisgIENBTkNFTExFRCA9IDEsCisgIFVOS05PV04gPSAyLAorICBJTlZBTElEX0FSR1VNRU5UID0gMywKKyAgREVBRExJTkVfRVhDRUVERUQgPSA0LAorICBOT1RfRk9VTkQgPSA1LAorICBBTFJFQURZX0VYSVNUUyA9IDYsCisgIFBFUk1JU1NJT05fREVOSUVEID0gNywKKyAgVU5BVVRIRU5USUNBVEVEID0gMTYsCisgIFJFU09VUkNFX0VYSEFVU1RFRCA9IDgsCisgIEZBSUxFRF9QUkVDT05ESVRJT04gPSA5LAorICBBQk9SVEVEID0gMTAsCisgIE9VVF9PRl9SQU5HRSA9IDExLAorICBVTklNUExFTUVOVEVEID0gMTIsCisgIElOVEVSTkFMID0gMTMsCisgIFVOQVZBSUxBQkxFID0gMTQsCisgIERBVEFfTE9TUyA9IDE1LAorfTsKK30gIC8vIG5hbWVzcGFjZSBlcnJvcgorCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgU3RhdHVzIHsKKyBwdWJsaWM6CisgIC8vIENyZWF0ZXMgYSAic3VjY2Vzc2Z1bCIgc3RhdHVzLgorICBTdGF0dXMoKTsKKworICAvLyBDcmVhdGUgYSBzdGF0dXMgaW4gdGhlIGNhbm9uaWNhbCBlcnJvciBzcGFjZSB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgLy8gY29kZSwgYW5kIGVycm9yIG1lc3NhZ2UuICBJZiAiY29kZSA9PSAwIiwgZXJyb3JfbWVzc2FnZSBpcworICAvLyBpZ25vcmVkIGFuZCBhIFN0YXR1cyBvYmplY3QgaWRlbnRpY2FsIHRvIFN0YXR1czo6T0sgaXMKKyAgLy8gY29uc3RydWN0ZWQuCisgIFN0YXR1cyhlcnJvcjo6Q29kZSBlcnJvcl9jb2RlLCBTdHJpbmdQaWVjZSBlcnJvcl9tZXNzYWdlKTsKKyAgU3RhdHVzKGNvbnN0IFN0YXR1cyYpOworICBTdGF0dXMmIG9wZXJhdG9yPShjb25zdCBTdGF0dXMmIHgpOworICB+U3RhdHVzKCkge30KKworICAvLyBTb21lIHByZS1kZWZpbmVkIFN0YXR1cyBvYmplY3RzCisgIHN0YXRpYyBjb25zdCBTdGF0dXMgT0s7ICAgICAgICAgICAgIC8vIElkZW50aWNhbCB0byAwLWFyZyBjb25zdHJ1Y3RvcgorICBzdGF0aWMgY29uc3QgU3RhdHVzIENBTkNFTExFRDsKKyAgc3RhdGljIGNvbnN0IFN0YXR1cyBVTktOT1dOOworCisgIC8vIEFjY2Vzc29yCisgIGJvb2wgb2soKSBjb25zdCB7CisgICAgcmV0dXJuIGVycm9yX2NvZGVfID09IGVycm9yOjpPSzsKKyAgfQorICBpbnQgZXJyb3JfY29kZSgpIGNvbnN0IHsKKyAgICByZXR1cm4gZXJyb3JfY29kZV87CisgIH0KKyAgU3RyaW5nUGllY2UgZXJyb3JfbWVzc2FnZSgpIGNvbnN0IHsKKyAgICByZXR1cm4gZXJyb3JfbWVzc2FnZV87CisgIH0KKworICBib29sIG9wZXJhdG9yPT0oY29uc3QgU3RhdHVzJiB4KSBjb25zdDsKKyAgYm9vbCBvcGVyYXRvciE9KGNvbnN0IFN0YXR1cyYgeCkgY29uc3QgeworICAgIHJldHVybiAhb3BlcmF0b3I9PSh4KTsKKyAgfQorCisgIC8vIFJldHVybiBhIGNvbWJpbmF0aW9uIG9mIHRoZSBlcnJvciBjb2RlIG5hbWUgYW5kIG1lc3NhZ2UuCisgIHN0cmluZyBUb1N0cmluZygpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgZXJyb3I6OkNvZGUgZXJyb3JfY29kZV87CisgIHN0cmluZyBlcnJvcl9tZXNzYWdlXzsKK307CisKKy8vIFByaW50cyBhIGh1bWFuLXJlYWRhYmxlIHJlcHJlc2VudGF0aW9uIG9mICd4JyB0byAnb3MnLgorTElCUFJPVE9CVUZfRVhQT1JUIG9zdHJlYW0mIG9wZXJhdG9yPDwob3N0cmVhbSYgb3MsIGNvbnN0IFN0YXR1cyYgeCk7CisKKyNkZWZpbmUgRVhQRUNUX09LKHZhbHVlKSBFWFBFQ1RfVFJVRSgodmFsdWUpLm9rKCkpCisKK30gIC8vIG5hbWVzcGFjZSB1dGlsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX1NUVUJTX1NUQVRVU19IXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdGF0dXNfbWFjcm9zLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0YXR1c19tYWNyb3MuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NDNlNzlhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdGF0dXNfbWFjcm9zLmgKQEAgLTAsMCArMSw4OSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEZyb206IHV0aWwvdGFzay9jb250cmliL3N0YXR1c19tYWNyb3Mvc3RhdHVzX21hY3Jvcy5oCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX1NUVUJTX1NUQVRVU19NQUNST1NfSF8KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1NUVUJTX1NUQVRVU19NQUNST1NfSF8KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RhdHVzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0YXR1c29yLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSB1dGlsIHsKKworLy8gUnVuIGEgY29tbWFuZCB0aGF0IHJldHVybnMgYSB1dGlsOjpTdGF0dXMuICBJZiB0aGUgY2FsbGVkIGNvZGUgcmV0dXJucyBhbgorLy8gZXJyb3Igc3RhdHVzLCByZXR1cm4gdGhhdCBzdGF0dXMgdXAgb3V0IG9mIHRoaXMgbWV0aG9kIHRvby4KKy8vCisvLyBFeGFtcGxlOgorLy8gICBSRVRVUk5fSUZfRVJST1IoRG9UaGluZ3MoNCkpOworI2RlZmluZSBSRVRVUk5fSUZfRVJST1IoZXhwcikgXAorICBkbyB7IFwKKyAgICAvKiBVc2luZyBfc3RhdHVzIGJlbG93IHRvIGF2b2lkIGNhcHR1cmUgcHJvYmxlbXMgaWYgZXhwciBpcyAic3RhdHVzIi4gKi8gXAorICAgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6dXRpbDo6U3RhdHVzIF9zdGF0dXMgPSAoZXhwcik7IFwKKyAgICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoIV9zdGF0dXMub2soKSkpIHJldHVybiBfc3RhdHVzOyBcCisgIH0gd2hpbGUgKDApCisKKy8vIEludGVybmFsIGhlbHBlciBmb3IgY29uY2F0ZW5hdGluZyBtYWNybyB2YWx1ZXMuCisjZGVmaW5lIFNUQVRVU19NQUNST1NfQ09OQ0FUX05BTUVfSU5ORVIoeCwgeSkgeCMjeQorI2RlZmluZSBTVEFUVVNfTUFDUk9TX0NPTkNBVF9OQU1FKHgsIHkpIFNUQVRVU19NQUNST1NfQ09OQ0FUX05BTUVfSU5ORVIoeCwgeSkKKwordGVtcGxhdGU8dHlwZW5hbWUgVD4KK1N0YXR1cyBEb0Fzc2lnbk9yUmV0dXJuKFQmIGxocywgU3RhdHVzT3I8VD4gcmVzdWx0KSB7CisgIGlmIChyZXN1bHQub2soKSkgeworICAgIGxocyA9IHJlc3VsdC5WYWx1ZU9yRGllKCk7CisgIH0KKyAgcmV0dXJuIHJlc3VsdC5zdGF0dXMoKTsKK30KKworI2RlZmluZSBBU1NJR05fT1JfUkVUVVJOX0lNUEwoc3RhdHVzLCBsaHMsIHJleHByKSBcCisgIFN0YXR1cyBzdGF0dXMgPSBEb0Fzc2lnbk9yUmV0dXJuKGxocywgKHJleHByKSk7IFwKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCFzdGF0dXMub2soKSkpIHJldHVybiBzdGF0dXM7CisKKy8vIEV4ZWN1dGVzIGFuIGV4cHJlc3Npb24gdGhhdCByZXR1cm5zIGEgdXRpbDo6U3RhdHVzT3IsIGV4dHJhY3RpbmcgaXRzIHZhbHVlCisvLyBpbnRvIHRoZSB2YXJpYWJsZSBkZWZpbmVkIGJ5IGxocyAob3IgcmV0dXJuaW5nIG9uIGVycm9yKS4KKy8vCisvLyBFeGFtcGxlOiBBc3NpZ25pbmcgdG8gYW4gZXhpc3RpbmcgdmFsdWUKKy8vICAgVmFsdWVUeXBlIHZhbHVlOworLy8gICBBU1NJR05fT1JfUkVUVVJOKHZhbHVlLCBNYXliZUdldFZhbHVlKGFyZykpOworLy8KKy8vIFdBUk5JTkc6IEFTU0lHTl9PUl9SRVRVUk4gZXhwYW5kcyBpbnRvIG11bHRpcGxlIHN0YXRlbWVudHM7IGl0IGNhbm5vdCBiZSB1c2VkCisvLyAgaW4gYSBzaW5nbGUgc3RhdGVtZW50IChlLmcuIGFzIHRoZSBib2R5IG9mIGFuIGlmIHN0YXRlbWVudCB3aXRob3V0IHt9KSEKKyNkZWZpbmUgQVNTSUdOX09SX1JFVFVSTihsaHMsIHJleHByKSBcCisgIEFTU0lHTl9PUl9SRVRVUk5fSU1QTCggXAorICAgICAgU1RBVFVTX01BQ1JPU19DT05DQVRfTkFNRShfc3RhdHVzX29yX3ZhbHVlLCBfX0NPVU5URVJfXyksIGxocywgcmV4cHIpOworCit9ICAvLyBuYW1lc3BhY2UgdXRpbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX1NUVUJTX1NUQVRVU19IXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdGF0dXNfdGVzdC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvc3RhdHVzX3Rlc3QuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzcwYzMzYwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvc3RhdHVzX3Rlc3QuY2MKQEAgLTAsMCArMSwxMzEgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdGF0dXMuaD4KKworI2luY2x1ZGUgPHN0ZGlvLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0Lmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIHsKK1RFU1QoU3RhdHVzLCBFbXB0eSkgeworICB1dGlsOjpTdGF0dXMgc3RhdHVzOworICBFWFBFQ1RfRVEodXRpbDo6ZXJyb3I6Ok9LLCB1dGlsOjpTdGF0dXM6Ok9LLmVycm9yX2NvZGUoKSk7CisgIEVYUEVDVF9FUSgiT0siLCB1dGlsOjpTdGF0dXM6Ok9LLlRvU3RyaW5nKCkpOworfQorCitURVNUKFN0YXR1cywgR2VuZXJpY0NvZGVzKSB7CisgIEVYUEVDVF9FUSh1dGlsOjplcnJvcjo6T0ssIHV0aWw6OlN0YXR1czo6T0suZXJyb3JfY29kZSgpKTsKKyAgRVhQRUNUX0VRKHV0aWw6OmVycm9yOjpDQU5DRUxMRUQsIHV0aWw6OlN0YXR1czo6Q0FOQ0VMTEVELmVycm9yX2NvZGUoKSk7CisgIEVYUEVDVF9FUSh1dGlsOjplcnJvcjo6VU5LTk9XTiwgdXRpbDo6U3RhdHVzOjpVTktOT1dOLmVycm9yX2NvZGUoKSk7Cit9CisKK1RFU1QoU3RhdHVzLCBDb25zdHJ1Y3Rvclplcm8pIHsKKyAgdXRpbDo6U3RhdHVzIHN0YXR1cyh1dGlsOjplcnJvcjo6T0ssICJtc2ciKTsKKyAgRVhQRUNUX1RSVUUoc3RhdHVzLm9rKCkpOworICBFWFBFQ1RfRVEoIk9LIiwgc3RhdHVzLlRvU3RyaW5nKCkpOworfQorCitURVNUKFN0YXR1cywgQ2hlY2tPSykgeworICB1dGlsOjpTdGF0dXMgc3RhdHVzOworICBHT09HTEVfQ0hFQ0tfT0soc3RhdHVzKTsKKyAgR09PR0xFX0NIRUNLX09LKHN0YXR1cykgPDwgIkZhaWxlZCI7CisgIEdPT0dMRV9EQ0hFQ0tfT0soc3RhdHVzKSA8PCAiRmFpbGVkIjsKK30KKworVEVTVChTdGF0dXMsIEVycm9yTWVzc2FnZSkgeworICB1dGlsOjpTdGF0dXMgc3RhdHVzKHV0aWw6OmVycm9yOjpJTlZBTElEX0FSR1VNRU5ULCAiIik7CisgIEVYUEVDVF9GQUxTRShzdGF0dXMub2soKSk7CisgIEVYUEVDVF9FUSgiIiwgc3RhdHVzLmVycm9yX21lc3NhZ2UoKS5Ub1N0cmluZygpKTsKKyAgRVhQRUNUX0VRKCJJTlZBTElEX0FSR1VNRU5UIiwgc3RhdHVzLlRvU3RyaW5nKCkpOworICBzdGF0dXMgPSB1dGlsOjpTdGF0dXModXRpbDo6ZXJyb3I6OklOVkFMSURfQVJHVU1FTlQsICJtc2ciKTsKKyAgRVhQRUNUX0ZBTFNFKHN0YXR1cy5vaygpKTsKKyAgRVhQRUNUX0VRKCJtc2ciLCBzdGF0dXMuZXJyb3JfbWVzc2FnZSgpLlRvU3RyaW5nKCkpOworICBFWFBFQ1RfRVEoIklOVkFMSURfQVJHVU1FTlQ6bXNnIiwgc3RhdHVzLlRvU3RyaW5nKCkpOworICBzdGF0dXMgPSB1dGlsOjpTdGF0dXModXRpbDo6ZXJyb3I6Ok9LLCAibXNnIik7CisgIEVYUEVDVF9UUlVFKHN0YXR1cy5vaygpKTsKKyAgRVhQRUNUX0VRKCIiLCBzdGF0dXMuZXJyb3JfbWVzc2FnZSgpLlRvU3RyaW5nKCkpOworICBFWFBFQ1RfRVEoIk9LIiwgc3RhdHVzLlRvU3RyaW5nKCkpOworfQorCitURVNUKFN0YXR1cywgQ29weSkgeworICB1dGlsOjpTdGF0dXMgYSh1dGlsOjplcnJvcjo6VU5LTk9XTiwgIm1lc3NhZ2UiKTsKKyAgdXRpbDo6U3RhdHVzIGIoYSk7CisgIEFTU0VSVF9FUShhLlRvU3RyaW5nKCksIGIuVG9TdHJpbmcoKSk7Cit9CisKK1RFU1QoU3RhdHVzLCBBc3NpZ24pIHsKKyAgdXRpbDo6U3RhdHVzIGEodXRpbDo6ZXJyb3I6OlVOS05PV04sICJtZXNzYWdlIik7CisgIHV0aWw6OlN0YXR1cyBiOworICBiID0gYTsKKyAgQVNTRVJUX0VRKGEuVG9TdHJpbmcoKSwgYi5Ub1N0cmluZygpKTsKK30KKworVEVTVChTdGF0dXMsIEFzc2lnbkVtcHR5KSB7CisgIHV0aWw6OlN0YXR1cyBhKHV0aWw6OmVycm9yOjpVTktOT1dOLCAibWVzc2FnZSIpOworICB1dGlsOjpTdGF0dXMgYjsKKyAgYSA9IGI7CisgIEFTU0VSVF9FUShzdHJpbmcoIk9LIiksIGEuVG9TdHJpbmcoKSk7CisgIEFTU0VSVF9UUlVFKGIub2soKSk7CisgIEFTU0VSVF9UUlVFKGEub2soKSk7Cit9CisKK1RFU1QoU3RhdHVzLCBFcXVhbHNPSykgeworICBBU1NFUlRfRVEodXRpbDo6U3RhdHVzOjpPSywgdXRpbDo6U3RhdHVzKCkpOworfQorCitURVNUKFN0YXR1cywgRXF1YWxzU2FtZSkgeworICBjb25zdCB1dGlsOjpTdGF0dXMgYSA9IHV0aWw6OlN0YXR1cyh1dGlsOjplcnJvcjo6Q0FOQ0VMTEVELCAibWVzc2FnZSIpOworICBjb25zdCB1dGlsOjpTdGF0dXMgYiA9IHV0aWw6OlN0YXR1cyh1dGlsOjplcnJvcjo6Q0FOQ0VMTEVELCAibWVzc2FnZSIpOworICBBU1NFUlRfRVEoYSwgYik7Cit9CisKK1RFU1QoU3RhdHVzLCBFcXVhbHNDb3B5KSB7CisgIGNvbnN0IHV0aWw6OlN0YXR1cyBhID0gdXRpbDo6U3RhdHVzKHV0aWw6OmVycm9yOjpDQU5DRUxMRUQsICJtZXNzYWdlIik7CisgIGNvbnN0IHV0aWw6OlN0YXR1cyBiID0gYTsKKyAgQVNTRVJUX0VRKGEsIGIpOworfQorCitURVNUKFN0YXR1cywgRXF1YWxzRGlmZmVyZW50Q29kZSkgeworICBjb25zdCB1dGlsOjpTdGF0dXMgYSA9IHV0aWw6OlN0YXR1cyh1dGlsOjplcnJvcjo6Q0FOQ0VMTEVELCAibWVzc2FnZSIpOworICBjb25zdCB1dGlsOjpTdGF0dXMgYiA9IHV0aWw6OlN0YXR1cyh1dGlsOjplcnJvcjo6VU5LTk9XTiwgIm1lc3NhZ2UiKTsKKyAgQVNTRVJUX05FKGEsIGIpOworfQorCitURVNUKFN0YXR1cywgRXF1YWxzRGlmZmVyZW50TWVzc2FnZSkgeworICBjb25zdCB1dGlsOjpTdGF0dXMgYSA9IHV0aWw6OlN0YXR1cyh1dGlsOjplcnJvcjo6Q0FOQ0VMTEVELCAibWVzc2FnZSIpOworICBjb25zdCB1dGlsOjpTdGF0dXMgYiA9IHV0aWw6OlN0YXR1cyh1dGlsOjplcnJvcjo6Q0FOQ0VMTEVELCAiYW5vdGhlciIpOworICBBU1NFUlRfTkUoYSwgYik7Cit9Cit9ICAvLyBuYW1lc3BhY2UKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdGF0dXNvci5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvc3RhdHVzb3IuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDhkMTQwMgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvc3RhdHVzb3IuY2MKQEAgLTAsMCArMSw0NiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RhdHVzb3IuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIHV0aWwgeworbmFtZXNwYWNlIGludGVybmFsIHsKKwordm9pZCBTdGF0dXNPckhlbHBlcjo6Q3Jhc2goY29uc3QgU3RhdHVzJiBzdGF0dXMpIHsKKyAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkF0dGVtcHRpbmcgdG8gZmV0Y2ggdmFsdWUgaW5zdGVhZCBvZiBoYW5kbGluZyBlcnJvciAiCisgICAgICAgICAgICAgICAgICAgIDw8IHN0YXR1cy5Ub1N0cmluZygpOworfQorCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSB1dGlsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvc3RhdHVzb3IuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvc3RhdHVzb3IuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hZDg0ODcwCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdGF0dXNvci5oCkBAIC0wLDAgKzEsMjU5IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gU3RhdHVzT3I8VD4gaXMgdGhlIHVuaW9uIG9mIGEgU3RhdHVzIG9iamVjdCBhbmQgYSBUCisvLyBvYmplY3QuIFN0YXR1c09yIG1vZGVscyB0aGUgY29uY2VwdCBvZiBhbiBvYmplY3QgdGhhdCBpcyBlaXRoZXIgYQorLy8gdXNhYmxlIHZhbHVlLCBvciBhbiBlcnJvciBTdGF0dXMgZXhwbGFpbmluZyB3aHkgc3VjaCBhIHZhbHVlIGlzCisvLyBub3QgcHJlc2VudC4gVG8gdGhpcyBlbmQsIFN0YXR1c09yPFQ+IGRvZXMgbm90IGFsbG93IGl0cyBTdGF0dXMKKy8vIHZhbHVlIHRvIGJlIFN0YXR1czo6T0suIEZ1cnRoZXIsIFN0YXR1c09yPFQqPiBkb2VzIG5vdCBhbGxvdyB0aGUKKy8vIGNvbnRhaW5lZCBwb2ludGVyIHRvIGJlIE5VTEwuCisvLworLy8gVGhlIHByaW1hcnkgdXNlLWNhc2UgZm9yIFN0YXR1c09yPFQ+IGlzIGFzIHRoZSByZXR1cm4gdmFsdWUgb2YgYQorLy8gZnVuY3Rpb24gd2hpY2ggbWF5IGZhaWwuCisvLworLy8gRXhhbXBsZSBjbGllbnQgdXNhZ2UgZm9yIGEgU3RhdHVzT3I8VD4sIHdoZXJlIFQgaXMgbm90IGEgcG9pbnRlcjoKKy8vCisvLyAgU3RhdHVzT3I8ZmxvYXQ+IHJlc3VsdCA9IERvQmlnQ2FsY3VsYXRpb25UaGF0Q291bGRGYWlsKCk7CisvLyAgaWYgKHJlc3VsdC5vaygpKSB7CisvLyAgICBmbG9hdCBhbnN3ZXIgPSByZXN1bHQuVmFsdWVPckRpZSgpOworLy8gICAgcHJpbnRmKCJCaWcgY2FsY3VsYXRpb24geWllbGRlZDogJWYiLCBhbnN3ZXIpOworLy8gIH0gZWxzZSB7CisvLyAgICBMT0coRVJST1IpIDw8IHJlc3VsdC5zdGF0dXMoKTsKKy8vICB9CisvLworLy8gRXhhbXBsZSBjbGllbnQgdXNhZ2UgZm9yIGEgU3RhdHVzT3I8VCo+OgorLy8KKy8vICBTdGF0dXNPcjxGb28qPiByZXN1bHQgPSBGb29GYWN0b3J5OjpNYWtlTmV3Rm9vKGFyZyk7CisvLyAgaWYgKHJlc3VsdC5vaygpKSB7CisvLyAgICBzdGQ6OnVuaXF1ZV9wdHI8Rm9vPiBmb28ocmVzdWx0LlZhbHVlT3JEaWUoKSk7CisvLyAgICBmb28tPkRvU29tZXRoaW5nQ29vbCgpOworLy8gIH0gZWxzZSB7CisvLyAgICBMT0coRVJST1IpIDw8IHJlc3VsdC5zdGF0dXMoKTsKKy8vICB9CisvLworLy8gRXhhbXBsZSBjbGllbnQgdXNhZ2UgZm9yIGEgU3RhdHVzT3I8c3RkOjp1bmlxdWVfcHRyPFQ+PjoKKy8vCisvLyAgU3RhdHVzT3I8c3RkOjp1bmlxdWVfcHRyPEZvbz4+IHJlc3VsdCA9IEZvb0ZhY3Rvcnk6Ok1ha2VOZXdGb28oYXJnKTsKKy8vICBpZiAocmVzdWx0Lm9rKCkpIHsKKy8vICAgIHN0ZDo6dW5pcXVlX3B0cjxGb28+IGZvbyA9IHJlc3VsdC5Db25zdW1lVmFsdWVPckRpZSgpOworLy8gICAgZm9vLT5Eb1NvbWV0aGluZ0Nvb2woKTsKKy8vICB9IGVsc2UgeworLy8gICAgTE9HKEVSUk9SKSA8PCByZXN1bHQuc3RhdHVzKCk7CisvLyAgfQorLy8KKy8vIEV4YW1wbGUgZmFjdG9yeSBpbXBsZW1lbnRhdGlvbiByZXR1cm5pbmcgU3RhdHVzT3I8VCo+OgorLy8KKy8vICBTdGF0dXNPcjxGb28qPiBGb29GYWN0b3J5OjpNYWtlTmV3Rm9vKGludCBhcmcpIHsKKy8vICAgIGlmIChhcmcgPD0gMCkgeworLy8gICAgICByZXR1cm4gOjp1dGlsOjpTdGF0dXMoOjp1dGlsOjplcnJvcjo6SU5WQUxJRF9BUkdVTUVOVCwKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBcmcgbXVzdCBiZSBwb3NpdGl2ZSIpOworLy8gICAgfSBlbHNlIHsKKy8vICAgICAgcmV0dXJuIG5ldyBGb28oYXJnKTsKKy8vICAgIH0KKy8vICB9CisvLworCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9TVFVCU19TVEFUVVNPUl9IXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfU1RVQlNfU1RBVFVTT1JfSF8KKworI2luY2x1ZGUgPG5ldz4KKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8dXRpbGl0eT4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdGF0dXMuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIHV0aWwgeworCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorY2xhc3MgU3RhdHVzT3IgeworICB0ZW1wbGF0ZTx0eXBlbmFtZSBVPiBmcmllbmQgY2xhc3MgU3RhdHVzT3I7CisKKyBwdWJsaWM6CisgIC8vIENvbnN0cnVjdCBhIG5ldyBTdGF0dXNPciB3aXRoIFN0YXR1czo6VU5LTk9XTiBzdGF0dXMKKyAgU3RhdHVzT3IoKTsKKworICAvLyBDb25zdHJ1Y3QgYSBuZXcgU3RhdHVzT3Igd2l0aCB0aGUgZ2l2ZW4gbm9uLW9rIHN0YXR1cy4gQWZ0ZXIgY2FsbGluZworICAvLyB0aGlzIGNvbnN0cnVjdG9yLCBjYWxscyB0byBWYWx1ZU9yRGllKCkgd2lsbCBDSEVDSy1mYWlsLgorICAvLworICAvLyBOT1RFOiBOb3QgZXhwbGljaXQgLSB3ZSB3YW50IHRvIHVzZSBTdGF0dXNPcjxUPiBhcyBhIHJldHVybgorICAvLyB2YWx1ZSwgc28gaXQgaXMgY29udmVuaWVudCBhbmQgc2Vuc2libGUgdG8gYmUgYWJsZSB0byBkbyAncmV0dXJuCisgIC8vIFN0YXR1cygpJyB3aGVuIHRoZSByZXR1cm4gdHlwZSBpcyBTdGF0dXNPcjxUPi4KKyAgLy8KKyAgLy8gUkVRVUlSRVM6IHN0YXR1cyAhPSBTdGF0dXM6Ok9LLiBUaGlzIHJlcXVpcmVtZW50IGlzIERDSEVDS2VkLgorICAvLyBJbiBvcHRpbWl6ZWQgYnVpbGRzLCBwYXNzaW5nIFN0YXR1czo6T0sgaGVyZSB3aWxsIGhhdmUgdGhlIGVmZmVjdAorICAvLyBvZiBwYXNzaW5nIFBvc2l4RXJyb3JTcGFjZTo6RUlOVkFMIGFzIGEgZmFsbGJhY2suCisgIFN0YXR1c09yKGNvbnN0IFN0YXR1cyYgc3RhdHVzKTsgIC8vIE5PTElOVAorCisgIC8vIENvbnN0cnVjdCBhIG5ldyBTdGF0dXNPciB3aXRoIHRoZSBnaXZlbiB2YWx1ZS4gSWYgVCBpcyBhIHBsYWluIHBvaW50ZXIsCisgIC8vIHZhbHVlIG11c3Qgbm90IGJlIE5VTEwuIEFmdGVyIGNhbGxpbmcgdGhpcyBjb25zdHJ1Y3RvciwgY2FsbHMgdG8KKyAgLy8gVmFsdWVPckRpZSgpIHdpbGwgc3VjY2VlZCwgYW5kIGNhbGxzIHRvIHN0YXR1cygpIHdpbGwgcmV0dXJuIE9LLgorICAvLworICAvLyBOT1RFOiBOb3QgZXhwbGljaXQgLSB3ZSB3YW50IHRvIHVzZSBTdGF0dXNPcjxUPiBhcyBhIHJldHVybiB0eXBlCisgIC8vIHNvIGl0IGlzIGNvbnZlbmllbnQgYW5kIHNlbnNpYmxlIHRvIGJlIGFibGUgdG8gZG8gJ3JldHVybiBUKCknCisgIC8vIHdoZW4gd2hlbiB0aGUgcmV0dXJuIHR5cGUgaXMgU3RhdHVzT3I8VD4uCisgIC8vCisgIC8vIFJFUVVJUkVTOiBpZiBUIGlzIGEgcGxhaW4gcG9pbnRlciwgdmFsdWUgIT0gTlVMTC4gVGhpcyByZXF1aXJlbWVudCBpcworICAvLyBEQ0hFQ0tlZC4gSW4gb3B0aW1pemVkIGJ1aWxkcywgcGFzc2luZyBhIE5VTEwgcG9pbnRlciBoZXJlIHdpbGwgaGF2ZQorICAvLyB0aGUgZWZmZWN0IG9mIHBhc3NpbmcgUG9zaXhFcnJvclNwYWNlOjpFSU5WQUwgYXMgYSBmYWxsYmFjay4KKyAgU3RhdHVzT3IoY29uc3QgVCYgdmFsdWUpOyAgLy8gTk9MSU5UCisKKyAgLy8gQ29weSBjb25zdHJ1Y3Rvci4KKyAgU3RhdHVzT3IoY29uc3QgU3RhdHVzT3ImIG90aGVyKTsKKworICAvLyBDb252ZXJzaW9uIGNvcHkgY29uc3RydWN0b3IsIFQgbXVzdCBiZSBjb3B5IGNvbnN0cnVjdGlibGUgZnJvbSBVCisgIHRlbXBsYXRlPHR5cGVuYW1lIFU+CisgIFN0YXR1c09yKGNvbnN0IFN0YXR1c09yPFU+JiBvdGhlcik7CisKKyAgLy8gQXNzaWdubWVudCBvcGVyYXRvci4KKyAgU3RhdHVzT3ImIG9wZXJhdG9yPShjb25zdCBTdGF0dXNPciYgb3RoZXIpOworCisgIC8vIENvbnZlcnNpb24gYXNzaWdubWVudCBvcGVyYXRvciwgVCBtdXN0IGJlIGFzc2lnbmFibGUgZnJvbSBVCisgIHRlbXBsYXRlPHR5cGVuYW1lIFU+CisgIFN0YXR1c09yJiBvcGVyYXRvcj0oY29uc3QgU3RhdHVzT3I8VT4mIG90aGVyKTsKKworICAvLyBSZXR1cm5zIGEgcmVmZXJlbmNlIHRvIG91ciBzdGF0dXMuIElmIHRoaXMgY29udGFpbnMgYSBULCB0aGVuCisgIC8vIHJldHVybnMgU3RhdHVzOjpPSy4KKyAgY29uc3QgU3RhdHVzJiBzdGF0dXMoKSBjb25zdDsKKworICAvLyBSZXR1cm5zIHRoaXMtPnN0YXR1cygpLm9rKCkKKyAgYm9vbCBvaygpIGNvbnN0OworCisgIC8vIFJldHVybnMgYSByZWZlcmVuY2UgdG8gb3VyIGN1cnJlbnQgdmFsdWUsIG9yIENIRUNLLWZhaWxzIGlmICF0aGlzLT5vaygpLgorICAvLyBJZiB5b3UgbmVlZCB0byBpbml0aWFsaXplIGEgVCBvYmplY3QgZnJvbSB0aGUgc3RvcmVkIHZhbHVlLAorICAvLyBDb25zdW1lVmFsdWVPckRpZSgpIG1heSBiZSBtb3JlIGVmZmljaWVudC4KKyAgY29uc3QgVCYgVmFsdWVPckRpZSgpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgU3RhdHVzIHN0YXR1c187CisgIFQgdmFsdWVfOworfTsKKworLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKy8vIEltcGxlbWVudGF0aW9uIGRldGFpbHMgZm9yIFN0YXR1c09yPFQ+CisKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBTdGF0dXNPckhlbHBlciB7CisgcHVibGljOgorICAvLyBNb3ZlIHR5cGUtYWdub3N0aWMgZXJyb3IgaGFuZGxpbmcgdG8gdGhlIC5jYy4KKyAgc3RhdGljIHZvaWQgQ3Jhc2goY29uc3QgdXRpbDo6U3RhdHVzJiBzdGF0dXMpOworCisgIC8vIEN1c3RvbWl6ZWQgYmVoYXZpb3IgZm9yIFN0YXR1c09yPFQ+IHZzLiBTdGF0dXNPcjxUKj4KKyAgdGVtcGxhdGU8dHlwZW5hbWUgVD4KKyAgc3RydWN0IFNwZWNpYWxpemU7Cit9OworCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorc3RydWN0IFN0YXR1c09ySGVscGVyOjpTcGVjaWFsaXplIHsKKyAgLy8gRm9yIG5vbi1wb2ludGVyIFQsIGEgcmVmZXJlbmNlIGNhbiBuZXZlciBiZSBOVUxMLgorICBzdGF0aWMgaW5saW5lIGJvb2wgSXNWYWx1ZU51bGwoY29uc3QgVCYgdCkgeyByZXR1cm4gZmFsc2U7IH0KK307CisKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+CitzdHJ1Y3QgU3RhdHVzT3JIZWxwZXI6OlNwZWNpYWxpemU8VCo+IHsKKyAgc3RhdGljIGlubGluZSBib29sIElzVmFsdWVOdWxsKGNvbnN0IFQqIHQpIHsgcmV0dXJuIHQgPT0gTlVMTDsgfQorfTsKKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCisKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+CitpbmxpbmUgU3RhdHVzT3I8VD46OlN0YXR1c09yKCkKKyAgICA6IHN0YXR1c18odXRpbDo6U3RhdHVzOjpVTktOT1dOKSB7Cit9CisKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+CitpbmxpbmUgU3RhdHVzT3I8VD46OlN0YXR1c09yKGNvbnN0IFN0YXR1cyYgc3RhdHVzKSB7CisgIGlmIChzdGF0dXMub2soKSkgeworICAgIHN0YXR1c18gPSBTdGF0dXMoZXJyb3I6OklOVEVSTkFMLCAiU3RhdHVzOjpPSyBpcyBub3QgYSB2YWxpZCBhcmd1bWVudC4iKTsKKyAgfSBlbHNlIHsKKyAgICBzdGF0dXNfID0gc3RhdHVzOworICB9Cit9CisKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+CitpbmxpbmUgU3RhdHVzT3I8VD46OlN0YXR1c09yKGNvbnN0IFQmIHZhbHVlKSB7CisgIGlmIChpbnRlcm5hbDo6U3RhdHVzT3JIZWxwZXI6OlNwZWNpYWxpemU8VD46OklzVmFsdWVOdWxsKHZhbHVlKSkgeworICAgIHN0YXR1c18gPSBTdGF0dXMoZXJyb3I6OklOVEVSTkFMLCAiTlVMTCBpcyBub3QgYSB2YWlsZCBhcmd1bWVudC4iKTsKKyAgfSBlbHNlIHsKKyAgICBzdGF0dXNfID0gU3RhdHVzOjpPSzsKKyAgICB2YWx1ZV8gPSB2YWx1ZTsKKyAgfQorfQorCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPgoraW5saW5lIFN0YXR1c09yPFQ+OjpTdGF0dXNPcihjb25zdCBTdGF0dXNPcjxUPiYgb3RoZXIpCisgICAgOiBzdGF0dXNfKG90aGVyLnN0YXR1c18pLCB2YWx1ZV8ob3RoZXIudmFsdWVfKSB7Cit9CisKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+CitpbmxpbmUgU3RhdHVzT3I8VD4mIFN0YXR1c09yPFQ+OjpvcGVyYXRvcj0oY29uc3QgU3RhdHVzT3I8VD4mIG90aGVyKSB7CisgIHN0YXR1c18gPSBvdGhlci5zdGF0dXNfOworICB2YWx1ZV8gPSBvdGhlci52YWx1ZV87CisgIHJldHVybiAqdGhpczsKK30KKwordGVtcGxhdGU8dHlwZW5hbWUgVD4KK3RlbXBsYXRlPHR5cGVuYW1lIFU+CitpbmxpbmUgU3RhdHVzT3I8VD46OlN0YXR1c09yKGNvbnN0IFN0YXR1c09yPFU+JiBvdGhlcikKKyAgICA6IHN0YXR1c18ob3RoZXIuc3RhdHVzXyksIHZhbHVlXyhvdGhlci5zdGF0dXNfLm9rKCkgPyBvdGhlci52YWx1ZV8gOiBOVUxMKSB7Cit9CisKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+Cit0ZW1wbGF0ZTx0eXBlbmFtZSBVPgoraW5saW5lIFN0YXR1c09yPFQ+JiBTdGF0dXNPcjxUPjo6b3BlcmF0b3I9KGNvbnN0IFN0YXR1c09yPFU+JiBvdGhlcikgeworICBzdGF0dXNfID0gb3RoZXIuc3RhdHVzXzsKKyAgaWYgKHN0YXR1c18ub2soKSkgdmFsdWVfID0gb3RoZXIudmFsdWVfOworICByZXR1cm4gKnRoaXM7Cit9CisKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+CitpbmxpbmUgY29uc3QgU3RhdHVzJiBTdGF0dXNPcjxUPjo6c3RhdHVzKCkgY29uc3QgeworICByZXR1cm4gc3RhdHVzXzsKK30KKwordGVtcGxhdGU8dHlwZW5hbWUgVD4KK2lubGluZSBib29sIFN0YXR1c09yPFQ+OjpvaygpIGNvbnN0IHsKKyAgcmV0dXJuIHN0YXR1cygpLm9rKCk7Cit9CisKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+CitpbmxpbmUgY29uc3QgVCYgU3RhdHVzT3I8VD46OlZhbHVlT3JEaWUoKSBjb25zdCB7CisgIGlmICghc3RhdHVzXy5vaygpKSB7CisgICAgaW50ZXJuYWw6OlN0YXR1c09ySGVscGVyOjpDcmFzaChzdGF0dXNfKTsKKyAgfQorICByZXR1cm4gdmFsdWVfOworfQorfSAgLy8gbmFtZXNwYWNlIHV0aWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9TVFVCU19TVEFUVVNPUl9IXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdGF0dXNvcl90ZXN0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdGF0dXNvcl90ZXN0LmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZlMmE5ZTUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0YXR1c29yX3Rlc3QuY2MKQEAgLTAsMCArMSwyNzQgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0YXR1c29yLmg+CisKKyNpbmNsdWRlIDxlcnJuby5oPgorI2luY2x1ZGUgPG1lbW9yeT4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2dvb2dsZXRlc3QuaD4KKyNpbmNsdWRlIDxndGVzdC9ndGVzdC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgdXRpbCB7CituYW1lc3BhY2UgeworCitjbGFzcyBCYXNlMSB7CisgcHVibGljOgorICB2aXJ0dWFsIH5CYXNlMSgpIHt9CisgIGludCBwYWQ7Cit9OworCitjbGFzcyBCYXNlMiB7CisgcHVibGljOgorICB2aXJ0dWFsIH5CYXNlMigpIHt9CisgIGludCB5ZXRvdGhlcnBhZDsKK307CisKK2NsYXNzIERlcml2ZWQgOiBwdWJsaWMgQmFzZTEsIHB1YmxpYyBCYXNlMiB7CisgcHVibGljOgorICB2aXJ0dWFsIH5EZXJpdmVkKCkge30KKyAgaW50IGV2ZW5tb3JlcGFkOworfTsKKworY2xhc3MgQ29weU5vQXNzaWduIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IENvcHlOb0Fzc2lnbihpbnQgdmFsdWUpIDogZm9vKHZhbHVlKSB7fQorICBDb3B5Tm9Bc3NpZ24oY29uc3QgQ29weU5vQXNzaWduJiBvdGhlcikgOiBmb28ob3RoZXIuZm9vKSB7fQorICBpbnQgZm9vOworIHByaXZhdGU6CisgIGNvbnN0IENvcHlOb0Fzc2lnbiYgb3BlcmF0b3I9KGNvbnN0IENvcHlOb0Fzc2lnbiYpOworfTsKKworVEVTVChTdGF0dXNPciwgVGVzdERlZmF1bHRDdG9yKSB7CisgIFN0YXR1c09yPGludD4gdGhpbmc7CisgIEVYUEVDVF9GQUxTRSh0aGluZy5vaygpKTsKKyAgRVhQRUNUX0VRKFN0YXR1czo6VU5LTk9XTiwgdGhpbmcuc3RhdHVzKCkpOworfQorCitURVNUKFN0YXR1c09yLCBUZXN0U3RhdHVzQ3RvcikgeworICBTdGF0dXNPcjxpbnQ+IHRoaW5nKFN0YXR1czo6Q0FOQ0VMTEVEKTsKKyAgRVhQRUNUX0ZBTFNFKHRoaW5nLm9rKCkpOworICBFWFBFQ1RfRVEoU3RhdHVzOjpDQU5DRUxMRUQsIHRoaW5nLnN0YXR1cygpKTsKK30KKworVEVTVChTdGF0dXNPciwgVGVzdFZhbHVlQ3RvcikgeworICBjb25zdCBpbnQga0kgPSA0OworICBTdGF0dXNPcjxpbnQ+IHRoaW5nKGtJKTsKKyAgRVhQRUNUX1RSVUUodGhpbmcub2soKSk7CisgIEVYUEVDVF9FUShrSSwgdGhpbmcuVmFsdWVPckRpZSgpKTsKK30KKworVEVTVChTdGF0dXNPciwgVGVzdENvcHlDdG9yU3RhdHVzT2spIHsKKyAgY29uc3QgaW50IGtJID0gNDsKKyAgU3RhdHVzT3I8aW50PiBvcmlnaW5hbChrSSk7CisgIFN0YXR1c09yPGludD4gY29weShvcmlnaW5hbCk7CisgIEVYUEVDVF9FUShvcmlnaW5hbC5zdGF0dXMoKSwgY29weS5zdGF0dXMoKSk7CisgIEVYUEVDVF9FUShvcmlnaW5hbC5WYWx1ZU9yRGllKCksIGNvcHkuVmFsdWVPckRpZSgpKTsKK30KKworVEVTVChTdGF0dXNPciwgVGVzdENvcHlDdG9yU3RhdHVzTm90T2spIHsKKyAgU3RhdHVzT3I8aW50PiBvcmlnaW5hbChTdGF0dXM6OkNBTkNFTExFRCk7CisgIFN0YXR1c09yPGludD4gY29weShvcmlnaW5hbCk7CisgIEVYUEVDVF9FUShvcmlnaW5hbC5zdGF0dXMoKSwgY29weS5zdGF0dXMoKSk7Cit9CisKK1RFU1QoU3RhdHVzT3IsIFRlc3RDb3B5Q3RvclN0YXR1c09LQ29udmVydGluZykgeworICBjb25zdCBpbnQga0kgPSA0OworICBTdGF0dXNPcjxpbnQ+ICAgIG9yaWdpbmFsKGtJKTsKKyAgU3RhdHVzT3I8ZG91YmxlPiBjb3B5KG9yaWdpbmFsKTsKKyAgRVhQRUNUX0VRKG9yaWdpbmFsLnN0YXR1cygpLCBjb3B5LnN0YXR1cygpKTsKKyAgRVhQRUNUX0VRKG9yaWdpbmFsLlZhbHVlT3JEaWUoKSwgY29weS5WYWx1ZU9yRGllKCkpOworfQorCitURVNUKFN0YXR1c09yLCBUZXN0Q29weUN0b3JTdGF0dXNOb3RPa0NvbnZlcnRpbmcpIHsKKyAgU3RhdHVzT3I8aW50PiAgICBvcmlnaW5hbChTdGF0dXM6OkNBTkNFTExFRCk7CisgIFN0YXR1c09yPGRvdWJsZT4gY29weShvcmlnaW5hbCk7CisgIEVYUEVDVF9FUShvcmlnaW5hbC5zdGF0dXMoKSwgY29weS5zdGF0dXMoKSk7Cit9CisKK1RFU1QoU3RhdHVzT3IsIFRlc3RBc3NpZ25tZW50U3RhdHVzT2spIHsKKyAgY29uc3QgaW50IGtJID0gNDsKKyAgU3RhdHVzT3I8aW50PiBzb3VyY2Uoa0kpOworICBTdGF0dXNPcjxpbnQ+IHRhcmdldDsKKyAgdGFyZ2V0ID0gc291cmNlOworICBFWFBFQ1RfRVEoc291cmNlLnN0YXR1cygpLCB0YXJnZXQuc3RhdHVzKCkpOworICBFWFBFQ1RfRVEoc291cmNlLlZhbHVlT3JEaWUoKSwgdGFyZ2V0LlZhbHVlT3JEaWUoKSk7Cit9CisKK1RFU1QoU3RhdHVzT3IsIFRlc3RBc3NpZ25tZW50U3RhdHVzTm90T2spIHsKKyAgU3RhdHVzT3I8aW50PiBzb3VyY2UoU3RhdHVzOjpDQU5DRUxMRUQpOworICBTdGF0dXNPcjxpbnQ+IHRhcmdldDsKKyAgdGFyZ2V0ID0gc291cmNlOworICBFWFBFQ1RfRVEoc291cmNlLnN0YXR1cygpLCB0YXJnZXQuc3RhdHVzKCkpOworfQorCitURVNUKFN0YXR1c09yLCBUZXN0QXNzaWdubWVudFN0YXR1c09LQ29udmVydGluZykgeworICBjb25zdCBpbnQga0kgPSA0OworICBTdGF0dXNPcjxpbnQ+ICAgIHNvdXJjZShrSSk7CisgIFN0YXR1c09yPGRvdWJsZT4gdGFyZ2V0OworICB0YXJnZXQgPSBzb3VyY2U7CisgIEVYUEVDVF9FUShzb3VyY2Uuc3RhdHVzKCksIHRhcmdldC5zdGF0dXMoKSk7CisgIEVYUEVDVF9ET1VCTEVfRVEoc291cmNlLlZhbHVlT3JEaWUoKSwgdGFyZ2V0LlZhbHVlT3JEaWUoKSk7Cit9CisKK1RFU1QoU3RhdHVzT3IsIFRlc3RBc3NpZ25tZW50U3RhdHVzTm90T2tDb252ZXJ0aW5nKSB7CisgIFN0YXR1c09yPGludD4gICAgc291cmNlKFN0YXR1czo6Q0FOQ0VMTEVEKTsKKyAgU3RhdHVzT3I8ZG91YmxlPiB0YXJnZXQ7CisgIHRhcmdldCA9IHNvdXJjZTsKKyAgRVhQRUNUX0VRKHNvdXJjZS5zdGF0dXMoKSwgdGFyZ2V0LnN0YXR1cygpKTsKK30KKworVEVTVChTdGF0dXNPciwgVGVzdFN0YXR1cykgeworICBTdGF0dXNPcjxpbnQ+IGdvb2QoNCk7CisgIEVYUEVDVF9UUlVFKGdvb2Qub2soKSk7CisgIFN0YXR1c09yPGludD4gYmFkKFN0YXR1czo6Q0FOQ0VMTEVEKTsKKyAgRVhQRUNUX0ZBTFNFKGJhZC5vaygpKTsKKyAgRVhQRUNUX0VRKFN0YXR1czo6Q0FOQ0VMTEVELCBiYWQuc3RhdHVzKCkpOworfQorCitURVNUKFN0YXR1c09yLCBUZXN0VmFsdWUpIHsKKyAgY29uc3QgaW50IGtJID0gNDsKKyAgU3RhdHVzT3I8aW50PiB0aGluZyhrSSk7CisgIEVYUEVDVF9FUShrSSwgdGhpbmcuVmFsdWVPckRpZSgpKTsKK30KKworVEVTVChTdGF0dXNPciwgVGVzdFZhbHVlQ29uc3QpIHsKKyAgY29uc3QgaW50IGtJID0gNDsKKyAgY29uc3QgU3RhdHVzT3I8aW50PiB0aGluZyhrSSk7CisgIEVYUEVDVF9FUShrSSwgdGhpbmcuVmFsdWVPckRpZSgpKTsKK30KKworVEVTVChTdGF0dXNPciwgVGVzdFBvaW50ZXJEZWZhdWx0Q3RvcikgeworICBTdGF0dXNPcjxpbnQqPiB0aGluZzsKKyAgRVhQRUNUX0ZBTFNFKHRoaW5nLm9rKCkpOworICBFWFBFQ1RfRVEoU3RhdHVzOjpVTktOT1dOLCB0aGluZy5zdGF0dXMoKSk7Cit9CisKK1RFU1QoU3RhdHVzT3IsIFRlc3RQb2ludGVyU3RhdHVzQ3RvcikgeworICBTdGF0dXNPcjxpbnQqPiB0aGluZyhTdGF0dXM6OkNBTkNFTExFRCk7CisgIEVYUEVDVF9GQUxTRSh0aGluZy5vaygpKTsKKyAgRVhQRUNUX0VRKFN0YXR1czo6Q0FOQ0VMTEVELCB0aGluZy5zdGF0dXMoKSk7Cit9CisKK1RFU1QoU3RhdHVzT3IsIFRlc3RQb2ludGVyVmFsdWVDdG9yKSB7CisgIGNvbnN0IGludCBrSSA9IDQ7CisgIFN0YXR1c09yPGNvbnN0IGludCo+IHRoaW5nKCZrSSk7CisgIEVYUEVDVF9UUlVFKHRoaW5nLm9rKCkpOworICBFWFBFQ1RfRVEoJmtJLCB0aGluZy5WYWx1ZU9yRGllKCkpOworfQorCitURVNUKFN0YXR1c09yLCBUZXN0UG9pbnRlckNvcHlDdG9yU3RhdHVzT2spIHsKKyAgY29uc3QgaW50IGtJID0gMDsKKyAgU3RhdHVzT3I8Y29uc3QgaW50Kj4gb3JpZ2luYWwoJmtJKTsKKyAgU3RhdHVzT3I8Y29uc3QgaW50Kj4gY29weShvcmlnaW5hbCk7CisgIEVYUEVDVF9FUShvcmlnaW5hbC5zdGF0dXMoKSwgY29weS5zdGF0dXMoKSk7CisgIEVYUEVDVF9FUShvcmlnaW5hbC5WYWx1ZU9yRGllKCksIGNvcHkuVmFsdWVPckRpZSgpKTsKK30KKworVEVTVChTdGF0dXNPciwgVGVzdFBvaW50ZXJDb3B5Q3RvclN0YXR1c05vdE9rKSB7CisgIFN0YXR1c09yPGludCo+IG9yaWdpbmFsKFN0YXR1czo6Q0FOQ0VMTEVEKTsKKyAgU3RhdHVzT3I8aW50Kj4gY29weShvcmlnaW5hbCk7CisgIEVYUEVDVF9FUShvcmlnaW5hbC5zdGF0dXMoKSwgY29weS5zdGF0dXMoKSk7Cit9CisKK1RFU1QoU3RhdHVzT3IsIFRlc3RQb2ludGVyQ29weUN0b3JTdGF0dXNPS0NvbnZlcnRpbmcpIHsKKyAgRGVyaXZlZCBkZXJpdmVkOworICBTdGF0dXNPcjxEZXJpdmVkKj4gb3JpZ2luYWwoJmRlcml2ZWQpOworICBTdGF0dXNPcjxCYXNlMio+ICAgY29weShvcmlnaW5hbCk7CisgIEVYUEVDVF9FUShvcmlnaW5hbC5zdGF0dXMoKSwgY29weS5zdGF0dXMoKSk7CisgIEVYUEVDVF9FUShzdGF0aWNfY2FzdDxjb25zdCBCYXNlMio+KG9yaWdpbmFsLlZhbHVlT3JEaWUoKSksCisgICAgICAgICAgICBjb3B5LlZhbHVlT3JEaWUoKSk7Cit9CisKK1RFU1QoU3RhdHVzT3IsIFRlc3RQb2ludGVyQ29weUN0b3JTdGF0dXNOb3RPa0NvbnZlcnRpbmcpIHsKKyAgU3RhdHVzT3I8RGVyaXZlZCo+IG9yaWdpbmFsKFN0YXR1czo6Q0FOQ0VMTEVEKTsKKyAgU3RhdHVzT3I8QmFzZTIqPiAgIGNvcHkob3JpZ2luYWwpOworICBFWFBFQ1RfRVEob3JpZ2luYWwuc3RhdHVzKCksIGNvcHkuc3RhdHVzKCkpOworfQorCitURVNUKFN0YXR1c09yLCBUZXN0UG9pbnRlckFzc2lnbm1lbnRTdGF0dXNPaykgeworICBjb25zdCBpbnQga0kgPSAwOworICBTdGF0dXNPcjxjb25zdCBpbnQqPiBzb3VyY2UoJmtJKTsKKyAgU3RhdHVzT3I8Y29uc3QgaW50Kj4gdGFyZ2V0OworICB0YXJnZXQgPSBzb3VyY2U7CisgIEVYUEVDVF9FUShzb3VyY2Uuc3RhdHVzKCksIHRhcmdldC5zdGF0dXMoKSk7CisgIEVYUEVDVF9FUShzb3VyY2UuVmFsdWVPckRpZSgpLCB0YXJnZXQuVmFsdWVPckRpZSgpKTsKK30KKworVEVTVChTdGF0dXNPciwgVGVzdFBvaW50ZXJBc3NpZ25tZW50U3RhdHVzTm90T2spIHsKKyAgU3RhdHVzT3I8aW50Kj4gc291cmNlKFN0YXR1czo6Q0FOQ0VMTEVEKTsKKyAgU3RhdHVzT3I8aW50Kj4gdGFyZ2V0OworICB0YXJnZXQgPSBzb3VyY2U7CisgIEVYUEVDVF9FUShzb3VyY2Uuc3RhdHVzKCksIHRhcmdldC5zdGF0dXMoKSk7Cit9CisKK1RFU1QoU3RhdHVzT3IsIFRlc3RQb2ludGVyQXNzaWdubWVudFN0YXR1c09LQ29udmVydGluZykgeworICBEZXJpdmVkIGRlcml2ZWQ7CisgIFN0YXR1c09yPERlcml2ZWQqPiBzb3VyY2UoJmRlcml2ZWQpOworICBTdGF0dXNPcjxCYXNlMio+ICAgdGFyZ2V0OworICB0YXJnZXQgPSBzb3VyY2U7CisgIEVYUEVDVF9FUShzb3VyY2Uuc3RhdHVzKCksIHRhcmdldC5zdGF0dXMoKSk7CisgIEVYUEVDVF9FUShzdGF0aWNfY2FzdDxjb25zdCBCYXNlMio+KHNvdXJjZS5WYWx1ZU9yRGllKCkpLAorICAgICAgICAgICAgdGFyZ2V0LlZhbHVlT3JEaWUoKSk7Cit9CisKK1RFU1QoU3RhdHVzT3IsIFRlc3RQb2ludGVyQXNzaWdubWVudFN0YXR1c05vdE9rQ29udmVydGluZykgeworICBTdGF0dXNPcjxEZXJpdmVkKj4gc291cmNlKFN0YXR1czo6Q0FOQ0VMTEVEKTsKKyAgU3RhdHVzT3I8QmFzZTIqPiAgIHRhcmdldDsKKyAgdGFyZ2V0ID0gc291cmNlOworICBFWFBFQ1RfRVEoc291cmNlLnN0YXR1cygpLCB0YXJnZXQuc3RhdHVzKCkpOworfQorCitURVNUKFN0YXR1c09yLCBUZXN0UG9pbnRlclN0YXR1cykgeworICBjb25zdCBpbnQga0kgPSAwOworICBTdGF0dXNPcjxjb25zdCBpbnQqPiBnb29kKCZrSSk7CisgIEVYUEVDVF9UUlVFKGdvb2Qub2soKSk7CisgIFN0YXR1c09yPGNvbnN0IGludCo+IGJhZChTdGF0dXM6OkNBTkNFTExFRCk7CisgIEVYUEVDVF9FUShTdGF0dXM6OkNBTkNFTExFRCwgYmFkLnN0YXR1cygpKTsKK30KKworVEVTVChTdGF0dXNPciwgVGVzdFBvaW50ZXJWYWx1ZSkgeworICBjb25zdCBpbnQga0kgPSAwOworICBTdGF0dXNPcjxjb25zdCBpbnQqPiB0aGluZygma0kpOworICBFWFBFQ1RfRVEoJmtJLCB0aGluZy5WYWx1ZU9yRGllKCkpOworfQorCitURVNUKFN0YXR1c09yLCBUZXN0UG9pbnRlclZhbHVlQ29uc3QpIHsKKyAgY29uc3QgaW50IGtJID0gMDsKKyAgY29uc3QgU3RhdHVzT3I8Y29uc3QgaW50Kj4gdGhpbmcoJmtJKTsKKyAgRVhQRUNUX0VRKCZrSSwgdGhpbmcuVmFsdWVPckRpZSgpKTsKK30KKworfSAgLy8gbmFtZXNwYWNlCit9ICAvLyBuYW1lc3BhY2UgdXRpbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0bF91dGlsLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0bF91dGlsLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWU0YzgyYQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvc3RsX3V0aWwuaApAQCAtMCwwICsxLDEyMSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIGZyb20gZ29vZ2xlMy91dGlsL2d0bC9zdGxfdXRpbC5oCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX1NUVUJTX1NUTF9VVElMX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfU1RVQlNfU1RMX1VUSUxfSF9fCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworLy8gU1RMRGVsZXRlQ29udGFpbmVyUG9pbnRlcnMoKQorLy8gIEZvciBhIHJhbmdlIHdpdGhpbiBhIGNvbnRhaW5lciBvZiBwb2ludGVycywgY2FsbHMgZGVsZXRlCisvLyAgKG5vbi1hcnJheSB2ZXJzaW9uKSBvbiB0aGVzZSBwb2ludGVycy4KKy8vIE5PVEU6IGZvciB0aGVzZSB0aHJlZSBmdW5jdGlvbnMsIHdlIGNvdWxkIGp1c3QgaW1wbGVtZW50IGEgRGVsZXRlT2JqZWN0CisvLyBmdW5jdG9yIGFuZCB0aGVuIGNhbGwgZm9yX2VhY2goKSBvbiB0aGUgcmFuZ2UgYW5kIGZ1bmN0b3IsIGJ1dCB0aGlzCisvLyByZXF1aXJlcyB1cyB0byBwdWxsIGluIGFsbCBvZiBhbGdvcml0aG0uaCwgd2hpY2ggc2VlbXMgZXhwZW5zaXZlLgorLy8gRm9yIGhhc2hfW211bHRpXXNldCwgaXQgaXMgaW1wb3J0YW50IHRoYXQgdGhpcyBkZWxldGVzIGJlaGluZCB0aGUgaXRlcmF0b3IKKy8vIGJlY2F1c2UgdGhlIGhhc2hfc2V0IG1heSBjYWxsIHRoZSBoYXNoIGZ1bmN0aW9uIG9uIHRoZSBpdGVyYXRvciB3aGVuIGl0IGlzCisvLyBhZHZhbmNlZCwgd2hpY2ggY291bGQgcmVzdWx0IGluIHRoZSBoYXNoIGZ1bmN0aW9uIHRyeWluZyB0byBkZWZlcmVuY2UgYQorLy8gc3RhbGUgcG9pbnRlci4KK3RlbXBsYXRlIDxjbGFzcyBGb3J3YXJkSXRlcmF0b3I+Cit2b2lkIFNUTERlbGV0ZUNvbnRhaW5lclBvaW50ZXJzKEZvcndhcmRJdGVyYXRvciBiZWdpbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRm9yd2FyZEl0ZXJhdG9yIGVuZCkgeworICB3aGlsZSAoYmVnaW4gIT0gZW5kKSB7CisgICAgRm9yd2FyZEl0ZXJhdG9yIHRlbXAgPSBiZWdpbjsKKyAgICArK2JlZ2luOworICAgIGRlbGV0ZSAqdGVtcDsKKyAgfQorfQorCisvLyBJbnNpZGUgR29vZ2xlLCB0aGlzIGZ1bmN0aW9uIGltcGxlbWVudHMgYSBob3JyaWJsZSwgZGlzZ3VzdGluZyBoYWNrIGluIHdoaWNoCisvLyB3ZSByZWFjaCBpbnRvIHRoZSBzdHJpbmcncyBwcml2YXRlIGltcGxlbWVudGF0aW9uIGFuZCByZXNpemUgaXQgd2l0aG91dAorLy8gaW5pdGlhbGl6aW5nIHRoZSBuZXcgYnl0ZXMuICBJbiBzb21lIGNhc2VzIGRvaW5nIHRoaXMgY2FuIHNpZ25pZmljYW50bHkKKy8vIGltcHJvdmUgcGVyZm9ybWFuY2UuICBIb3dldmVyLCBzaW5jZSBpdCdzIHRvdGFsbHkgbm9uLXBvcnRhYmxlIGl0IGhhcyBubworLy8gcGxhY2UgaW4gb3BlbiBzb3VyY2UgY29kZS4gIEZlZWwgZnJlZSB0byBmaWxsIHRoaXMgZnVuY3Rpb24gaW4gd2l0aCB5b3VyCisvLyBvd24gZGlzZ3VzdGluZyBoYWNrIGlmIHlvdSB3YW50IHRoZSBwZXJmIGJvb3N0LgoraW5saW5lIHZvaWQgU1RMU3RyaW5nUmVzaXplVW5pbml0aWFsaXplZChzdHJpbmcqIHMsIHNpemVfdCBuZXdfc2l6ZSkgeworICBzLT5yZXNpemUobmV3X3NpemUpOworfQorCisvLyBSZXR1cm4gYSBtdXRhYmxlIGNoYXIqIHBvaW50aW5nIHRvIGEgc3RyaW5nJ3MgaW50ZXJuYWwgYnVmZmVyLAorLy8gd2hpY2ggbWF5IG5vdCBiZSBudWxsLXRlcm1pbmF0ZWQuIFdyaXRpbmcgdGhyb3VnaCB0aGlzIHBvaW50ZXIgd2lsbAorLy8gbW9kaWZ5IHRoZSBzdHJpbmcuCisvLworLy8gc3RyaW5nX2FzX2FycmF5KCZzdHIpW2ldIGlzIHZhbGlkIGZvciAwIDw9IGkgPCBzdHIuc2l6ZSgpIHVudGlsIHRoZQorLy8gbmV4dCBjYWxsIHRvIGEgc3RyaW5nIG1ldGhvZCB0aGF0IGludmFsaWRhdGVzIGl0ZXJhdG9ycy4KKy8vCisvLyBBcyBvZiAyMDA2LTA0LCB0aGVyZSBpcyBubyBzdGFuZGFyZC1ibGVzc2VkIHdheSBvZiBnZXR0aW5nIGEKKy8vIG11dGFibGUgcmVmZXJlbmNlIHRvIGEgc3RyaW5nJ3MgaW50ZXJuYWwgYnVmZmVyLiBIb3dldmVyLCBpc3N1ZSA1MzAKKy8vIChodHRwOi8vd3d3Lm9wZW4tc3RkLm9yZy9KVEMxL1NDMjIvV0cyMS9kb2NzL2x3Zy1hY3RpdmUuaHRtbCM1MzApCisvLyBwcm9wb3NlcyB0aGlzIGFzIHRoZSBtZXRob2QuIEFjY29yZGluZyB0byBNYXR0IEF1c3Rlcm4sIHRoaXMgc2hvdWxkCisvLyBhbHJlYWR5IHdvcmsgb24gYWxsIGN1cnJlbnQgaW1wbGVtZW50YXRpb25zLgoraW5saW5lIGNoYXIqIHN0cmluZ19hc19hcnJheShzdHJpbmcqIHN0cikgeworICAvLyBETyBOT1QgVVNFIGNvbnN0X2Nhc3Q8Y2hhcio+KHN0ci0+ZGF0YSgpKSEgU2VlIHRoZSB1bml0dGVzdCBmb3Igd2h5LgorICByZXR1cm4gc3RyLT5lbXB0eSgpID8gTlVMTCA6ICYqc3RyLT5iZWdpbigpOworfQorCisvLyBTVExEZWxldGVFbGVtZW50cygpIGRlbGV0ZXMgYWxsIHRoZSBlbGVtZW50cyBpbiBhbiBTVEwgY29udGFpbmVyIGFuZCBjbGVhcnMKKy8vIHRoZSBjb250YWluZXIuICBUaGlzIGZ1bmN0aW9uIGlzIHN1aXRhYmxlIGZvciB1c2Ugd2l0aCBhIHZlY3Rvciwgc2V0LAorLy8gaGFzaF9zZXQsIG9yIGFueSBvdGhlciBTVEwgY29udGFpbmVyIHdoaWNoIGRlZmluZXMgc2Vuc2libGUgYmVnaW4oKSwgZW5kKCksCisvLyBhbmQgY2xlYXIoKSBtZXRob2RzLgorLy8KKy8vIElmIGNvbnRhaW5lciBpcyBOVUxMLCB0aGlzIGZ1bmN0aW9uIGlzIGEgbm8tb3AuCisvLworLy8gQXMgYW4gYWx0ZXJuYXRpdmUgdG8gY2FsbGluZyBTVExEZWxldGVFbGVtZW50cygpIGRpcmVjdGx5LCBjb25zaWRlcgorLy8gRWxlbWVudERlbGV0ZXIgKGRlZmluZWQgYmVsb3cpLCB3aGljaCBlbnN1cmVzIHRoYXQgeW91ciBjb250YWluZXIncyBlbGVtZW50cworLy8gYXJlIGRlbGV0ZWQgd2hlbiB0aGUgRWxlbWVudERlbGV0ZXIgZ29lcyBvdXQgb2Ygc2NvcGUuCit0ZW1wbGF0ZSA8Y2xhc3MgVD4KK3ZvaWQgU1RMRGVsZXRlRWxlbWVudHMoVCAqY29udGFpbmVyKSB7CisgIGlmICghY29udGFpbmVyKSByZXR1cm47CisgIFNUTERlbGV0ZUNvbnRhaW5lclBvaW50ZXJzKGNvbnRhaW5lci0+YmVnaW4oKSwgY29udGFpbmVyLT5lbmQoKSk7CisgIGNvbnRhaW5lci0+Y2xlYXIoKTsKK30KKworLy8gR2l2ZW4gYW4gU1RMIGNvbnRhaW5lciBjb25zaXN0aW5nIG9mIChrZXksIHZhbHVlKSBwYWlycywgU1RMRGVsZXRlVmFsdWVzCisvLyBkZWxldGVzIGFsbCB0aGUgInZhbHVlIiBjb21wb25lbnRzIGFuZCBjbGVhcnMgdGhlIGNvbnRhaW5lci4gIERvZXMgbm90aGluZworLy8gaW4gdGhlIGNhc2UgaXQncyBnaXZlbiBhIE5VTEwgcG9pbnRlci4KKwordGVtcGxhdGUgPGNsYXNzIFQ+Cit2b2lkIFNUTERlbGV0ZVZhbHVlcyhUICp2KSB7CisgIGlmICghdikgcmV0dXJuOworICBmb3IgKHR5cGVuYW1lIFQ6Oml0ZXJhdG9yIGkgPSB2LT5iZWdpbigpOyBpICE9IHYtPmVuZCgpOyArK2kpIHsKKyAgICBkZWxldGUgaS0+c2Vjb25kOworICB9CisgIHYtPmNsZWFyKCk7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9TVFVCU19TVExfVVRJTF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvc3RyaW5ncGllY2UuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cmluZ3BpZWNlLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk4OTQ3NGIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cmluZ3BpZWNlLmNjCkBAIC0wLDAgKzEsMjY4IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RyaW5ncGllY2UuaD4KKworI2luY2x1ZGUgPHN0cmluZy5oPgorI2luY2x1ZGUgPGFsZ29yaXRobT4KKyNpbmNsdWRlIDxjbGltaXRzPgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxvc3RyZWFtPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CitzdGQ6Om9zdHJlYW0mIG9wZXJhdG9yPDwoc3RkOjpvc3RyZWFtJiBvLCBTdHJpbmdQaWVjZSBwaWVjZSkgeworICBvLndyaXRlKHBpZWNlLmRhdGEoKSwgcGllY2Uuc2l6ZSgpKTsKKyAgcmV0dXJuIG87Cit9CisKKy8vIE91dC1vZi1saW5lIGVycm9yIHBhdGguCit2b2lkIFN0cmluZ1BpZWNlOjpMb2dGYXRhbFNpemVUb29CaWcoc2l6ZV90IHNpemUsIGNvbnN0IGNoYXIqIGRldGFpbHMpIHsKKyAgR09PR0xFX0xPRyhGQVRBTCkgPDwgInNpemUgdG9vIGJpZzogIiA8PCBzaXplIDw8ICIgZGV0YWlsczogIiA8PCBkZXRhaWxzOworfQorCitTdHJpbmdQaWVjZTo6U3RyaW5nUGllY2UoU3RyaW5nUGllY2UgeCwgc3RyaW5ncGllY2Vfc3NpemVfdHlwZSBwb3MpCisgICAgOiBwdHJfKHgucHRyXyArIHBvcyksIGxlbmd0aF8oeC5sZW5ndGhfIC0gcG9zKSB7CisgIEdPT0dMRV9EQ0hFQ0tfTEUoMCwgcG9zKTsKKyAgR09PR0xFX0RDSEVDS19MRShwb3MsIHgubGVuZ3RoXyk7Cit9CisKK1N0cmluZ1BpZWNlOjpTdHJpbmdQaWVjZShTdHJpbmdQaWVjZSB4LAorICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ3BpZWNlX3NzaXplX3R5cGUgcG9zLAorICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ3BpZWNlX3NzaXplX3R5cGUgbGVuKQorICAgIDogcHRyXyh4LnB0cl8gKyBwb3MpLCBsZW5ndGhfKHN0ZDo6bWluKGxlbiwgeC5sZW5ndGhfIC0gcG9zKSkgeworICBHT09HTEVfRENIRUNLX0xFKDAsIHBvcyk7CisgIEdPT0dMRV9EQ0hFQ0tfTEUocG9zLCB4Lmxlbmd0aF8pOworICBHT09HTEVfRENIRUNLX0dFKGxlbiwgMCk7Cit9CisKK3ZvaWQgU3RyaW5nUGllY2U6OkNvcHlUb1N0cmluZyhzdHJpbmcqIHRhcmdldCkgY29uc3QgeworICB0YXJnZXQtPmFzc2lnbihwdHJfLCBsZW5ndGhfKTsKK30KKwordm9pZCBTdHJpbmdQaWVjZTo6QXBwZW5kVG9TdHJpbmcoc3RyaW5nKiB0YXJnZXQpIGNvbnN0IHsKKyAgdGFyZ2V0LT5hcHBlbmQocHRyXywgbGVuZ3RoXyk7Cit9CisKK2Jvb2wgU3RyaW5nUGllY2U6OkNvbnN1bWUoU3RyaW5nUGllY2UgeCkgeworICBpZiAoc3RhcnRzX3dpdGgoeCkpIHsKKyAgICBwdHJfICs9IHgubGVuZ3RoXzsKKyAgICBsZW5ndGhfIC09IHgubGVuZ3RoXzsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorICByZXR1cm4gZmFsc2U7Cit9CisKK2Jvb2wgU3RyaW5nUGllY2U6OkNvbnN1bWVGcm9tRW5kKFN0cmluZ1BpZWNlIHgpIHsKKyAgaWYgKGVuZHNfd2l0aCh4KSkgeworICAgIGxlbmd0aF8gLT0geC5sZW5ndGhfOworICAgIHJldHVybiB0cnVlOworICB9CisgIHJldHVybiBmYWxzZTsKK30KKworc3RyaW5ncGllY2Vfc3NpemVfdHlwZSBTdHJpbmdQaWVjZTo6Y29weShjaGFyKiBidWYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdHlwZSBuLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3R5cGUgcG9zKSBjb25zdCB7CisgIHN0cmluZ3BpZWNlX3NzaXplX3R5cGUgcmV0ID0gc3RkOjptaW4obGVuZ3RoXyAtIHBvcywgbik7CisgIG1lbWNweShidWYsIHB0cl8gKyBwb3MsIHJldCk7CisgIHJldHVybiByZXQ7Cit9CisKK2Jvb2wgU3RyaW5nUGllY2U6OmNvbnRhaW5zKFN0cmluZ1BpZWNlIHMpIGNvbnN0IHsKKyAgcmV0dXJuIGZpbmQocywgMCkgIT0gbnBvczsKK30KKworc3RyaW5ncGllY2Vfc3NpemVfdHlwZSBTdHJpbmdQaWVjZTo6ZmluZChTdHJpbmdQaWVjZSBzLCBzaXplX3R5cGUgcG9zKSBjb25zdCB7CisgIGlmIChsZW5ndGhfIDw9IDAgfHwgcG9zID4gc3RhdGljX2Nhc3Q8c2l6ZV90eXBlPihsZW5ndGhfKSkgeworICAgIGlmIChsZW5ndGhfID09IDAgJiYgcG9zID09IDAgJiYgcy5sZW5ndGhfID09IDApIHJldHVybiAwOworICAgIHJldHVybiBucG9zOworICB9CisgIGNvbnN0IGNoYXIgKnJlc3VsdCA9IHN0ZDo6c2VhcmNoKHB0cl8gKyBwb3MsIHB0cl8gKyBsZW5ndGhfLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzLnB0cl8sIHMucHRyXyArIHMubGVuZ3RoXyk7CisgIHJldHVybiByZXN1bHQgPT0gcHRyXyArIGxlbmd0aF8gPyBucG9zIDogcmVzdWx0IC0gcHRyXzsKK30KKworc3RyaW5ncGllY2Vfc3NpemVfdHlwZSBTdHJpbmdQaWVjZTo6ZmluZChjaGFyIGMsIHNpemVfdHlwZSBwb3MpIGNvbnN0IHsKKyAgaWYgKGxlbmd0aF8gPD0gMCB8fCBwb3MgPj0gc3RhdGljX2Nhc3Q8c2l6ZV90eXBlPihsZW5ndGhfKSkgeworICAgIHJldHVybiBucG9zOworICB9CisgIGNvbnN0IGNoYXIqIHJlc3VsdCA9IHN0YXRpY19jYXN0PGNvbnN0IGNoYXIqPigKKyAgICAgIG1lbWNocihwdHJfICsgcG9zLCBjLCBsZW5ndGhfIC0gcG9zKSk7CisgIHJldHVybiByZXN1bHQgIT0gTlVMTCA/IHJlc3VsdCAtIHB0cl8gOiBucG9zOworfQorCitzdHJpbmdwaWVjZV9zc2l6ZV90eXBlIFN0cmluZ1BpZWNlOjpyZmluZChTdHJpbmdQaWVjZSBzLCBzaXplX3R5cGUgcG9zKSBjb25zdCB7CisgIGlmIChsZW5ndGhfIDwgcy5sZW5ndGhfKSByZXR1cm4gbnBvczsKKyAgY29uc3Qgc2l6ZV90IHVsZW4gPSBsZW5ndGhfOworICBpZiAocy5sZW5ndGhfID09IDApIHJldHVybiBzdGQ6Om1pbih1bGVuLCBwb3MpOworCisgIGNvbnN0IGNoYXIqIGxhc3QgPSBwdHJfICsgc3RkOjptaW4odWxlbiAtIHMubGVuZ3RoXywgcG9zKSArIHMubGVuZ3RoXzsKKyAgY29uc3QgY2hhciogcmVzdWx0ID0gc3RkOjpmaW5kX2VuZChwdHJfLCBsYXN0LCBzLnB0cl8sIHMucHRyXyArIHMubGVuZ3RoXyk7CisgIHJldHVybiByZXN1bHQgIT0gbGFzdCA/IHJlc3VsdCAtIHB0cl8gOiBucG9zOworfQorCisvLyBTZWFyY2ggcmFuZ2UgaXMgWzAuLnBvc10gaW5jbHVzaXZlLiAgSWYgcG9zID09IG5wb3MsIHNlYXJjaCBldmVyeXRoaW5nLgorc3RyaW5ncGllY2Vfc3NpemVfdHlwZSBTdHJpbmdQaWVjZTo6cmZpbmQoY2hhciBjLCBzaXplX3R5cGUgcG9zKSBjb25zdCB7CisgIC8vIE5vdGU6IG1lbXJjaHIoKSBpcyBub3QgYXZhaWxhYmxlIG9uIFdpbmRvd3MuCisgIGlmIChsZW5ndGhfIDw9IDApIHJldHVybiBucG9zOworICBmb3IgKHN0cmluZ3BpZWNlX3NzaXplX3R5cGUgaSA9CisgICAgICBzdGQ6Om1pbihwb3MsIHN0YXRpY19jYXN0PHNpemVfdHlwZT4obGVuZ3RoXyAtIDEpKTsKKyAgICAgICBpID49IDA7IC0taSkgeworICAgIGlmIChwdHJfW2ldID09IGMpIHsKKyAgICAgIHJldHVybiBpOworICAgIH0KKyAgfQorICByZXR1cm4gbnBvczsKK30KKworLy8gRm9yIGVhY2ggY2hhcmFjdGVyIGluIGNoYXJhY3RlcnNfd2FudGVkLCBzZXRzIHRoZSBpbmRleCBjb3JyZXNwb25kaW5nCisvLyB0byB0aGUgQVNDSUkgY29kZSBvZiB0aGF0IGNoYXJhY3RlciB0byAxIGluIHRhYmxlLiAgVGhpcyBpcyB1c2VkIGJ5CisvLyB0aGUgZmluZF8uKl9vZiBtZXRob2RzIGJlbG93IHRvIHRlbGwgd2hldGhlciBvciBub3QgYSBjaGFyYWN0ZXIgaXMgaW4KKy8vIHRoZSBsb29rdXAgdGFibGUgaW4gY29uc3RhbnQgdGltZS4KKy8vIFRoZSBhcmd1bWVudCBgdGFibGUnIG11c3QgYmUgYW4gYXJyYXkgdGhhdCBpcyBsYXJnZSBlbm91Z2ggdG8gaG9sZCBhbGwKKy8vIHRoZSBwb3NzaWJsZSB2YWx1ZXMgb2YgYW4gdW5zaWduZWQgY2hhci4gIFRodXMgaXQgc2hvdWxkIGJlIGJlIGRlY2xhcmVkCisvLyBhcyBmb2xsb3dzOgorLy8gICBib29sIHRhYmxlW1VDSEFSX01BWCArIDFdCitzdGF0aWMgaW5saW5lIHZvaWQgQnVpbGRMb29rdXBUYWJsZShTdHJpbmdQaWVjZSBjaGFyYWN0ZXJzX3dhbnRlZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wqIHRhYmxlKSB7CisgIGNvbnN0IHN0cmluZ3BpZWNlX3NzaXplX3R5cGUgbGVuZ3RoID0gY2hhcmFjdGVyc193YW50ZWQubGVuZ3RoKCk7CisgIGNvbnN0IGNoYXIqIGNvbnN0IGRhdGEgPSBjaGFyYWN0ZXJzX3dhbnRlZC5kYXRhKCk7CisgIGZvciAoc3RyaW5ncGllY2Vfc3NpemVfdHlwZSBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7CisgICAgdGFibGVbc3RhdGljX2Nhc3Q8dW5zaWduZWQgY2hhcj4oZGF0YVtpXSldID0gdHJ1ZTsKKyAgfQorfQorCitzdHJpbmdwaWVjZV9zc2l6ZV90eXBlIFN0cmluZ1BpZWNlOjpmaW5kX2ZpcnN0X29mKFN0cmluZ1BpZWNlIHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdHlwZSBwb3MpIGNvbnN0IHsKKyAgaWYgKGxlbmd0aF8gPD0gMCB8fCBzLmxlbmd0aF8gPD0gMCkgeworICAgIHJldHVybiBucG9zOworICB9CisgIC8vIEF2b2lkIHRoZSBjb3N0IG9mIEJ1aWxkTG9va3VwVGFibGUoKSBmb3IgYSBzaW5nbGUtY2hhcmFjdGVyIHNlYXJjaC4KKyAgaWYgKHMubGVuZ3RoXyA9PSAxKSByZXR1cm4gZmluZF9maXJzdF9vZihzLnB0cl9bMF0sIHBvcyk7CisKKyAgYm9vbCBsb29rdXBbVUNIQVJfTUFYICsgMV0gPSB7IGZhbHNlIH07CisgIEJ1aWxkTG9va3VwVGFibGUocywgbG9va3VwKTsKKyAgZm9yIChzdHJpbmdwaWVjZV9zc2l6ZV90eXBlIGkgPSBwb3M7IGkgPCBsZW5ndGhfOyArK2kpIHsKKyAgICBpZiAobG9va3VwW3N0YXRpY19jYXN0PHVuc2lnbmVkIGNoYXI+KHB0cl9baV0pXSkgeworICAgICAgcmV0dXJuIGk7CisgICAgfQorICB9CisgIHJldHVybiBucG9zOworfQorCitzdHJpbmdwaWVjZV9zc2l6ZV90eXBlIFN0cmluZ1BpZWNlOjpmaW5kX2ZpcnN0X25vdF9vZihTdHJpbmdQaWVjZSBzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90eXBlIHBvcykgY29uc3QgeworICBpZiAobGVuZ3RoXyA8PSAwKSByZXR1cm4gbnBvczsKKyAgaWYgKHMubGVuZ3RoXyA8PSAwKSByZXR1cm4gMDsKKyAgLy8gQXZvaWQgdGhlIGNvc3Qgb2YgQnVpbGRMb29rdXBUYWJsZSgpIGZvciBhIHNpbmdsZS1jaGFyYWN0ZXIgc2VhcmNoLgorICBpZiAocy5sZW5ndGhfID09IDEpIHJldHVybiBmaW5kX2ZpcnN0X25vdF9vZihzLnB0cl9bMF0sIHBvcyk7CisKKyAgYm9vbCBsb29rdXBbVUNIQVJfTUFYICsgMV0gPSB7IGZhbHNlIH07CisgIEJ1aWxkTG9va3VwVGFibGUocywgbG9va3VwKTsKKyAgZm9yIChzdHJpbmdwaWVjZV9zc2l6ZV90eXBlIGkgPSBwb3M7IGkgPCBsZW5ndGhfOyArK2kpIHsKKyAgICBpZiAoIWxvb2t1cFtzdGF0aWNfY2FzdDx1bnNpZ25lZCBjaGFyPihwdHJfW2ldKV0pIHsKKyAgICAgIHJldHVybiBpOworICAgIH0KKyAgfQorICByZXR1cm4gbnBvczsKK30KKworc3RyaW5ncGllY2Vfc3NpemVfdHlwZSBTdHJpbmdQaWVjZTo6ZmluZF9maXJzdF9ub3Rfb2YoY2hhciBjLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90eXBlIHBvcykgY29uc3QgeworICBpZiAobGVuZ3RoXyA8PSAwKSByZXR1cm4gbnBvczsKKworICBmb3IgKDsgcG9zIDwgc3RhdGljX2Nhc3Q8c2l6ZV90eXBlPihsZW5ndGhfKTsgKytwb3MpIHsKKyAgICBpZiAocHRyX1twb3NdICE9IGMpIHsKKyAgICAgIHJldHVybiBwb3M7CisgICAgfQorICB9CisgIHJldHVybiBucG9zOworfQorCitzdHJpbmdwaWVjZV9zc2l6ZV90eXBlIFN0cmluZ1BpZWNlOjpmaW5kX2xhc3Rfb2YoU3RyaW5nUGllY2UgcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3R5cGUgcG9zKSBjb25zdCB7CisgIGlmIChsZW5ndGhfIDw9IDAgfHwgcy5sZW5ndGhfIDw9IDApIHJldHVybiBucG9zOworICAvLyBBdm9pZCB0aGUgY29zdCBvZiBCdWlsZExvb2t1cFRhYmxlKCkgZm9yIGEgc2luZ2xlLWNoYXJhY3RlciBzZWFyY2guCisgIGlmIChzLmxlbmd0aF8gPT0gMSkgcmV0dXJuIGZpbmRfbGFzdF9vZihzLnB0cl9bMF0sIHBvcyk7CisKKyAgYm9vbCBsb29rdXBbVUNIQVJfTUFYICsgMV0gPSB7IGZhbHNlIH07CisgIEJ1aWxkTG9va3VwVGFibGUocywgbG9va3VwKTsKKyAgZm9yIChzdHJpbmdwaWVjZV9zc2l6ZV90eXBlIGkgPQorICAgICAgIHN0ZDo6bWluKHBvcywgc3RhdGljX2Nhc3Q8c2l6ZV90eXBlPihsZW5ndGhfIC0gMSkpOyBpID49IDA7IC0taSkgeworICAgIGlmIChsb29rdXBbc3RhdGljX2Nhc3Q8dW5zaWduZWQgY2hhcj4ocHRyX1tpXSldKSB7CisgICAgICByZXR1cm4gaTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIG5wb3M7Cit9CisKK3N0cmluZ3BpZWNlX3NzaXplX3R5cGUgU3RyaW5nUGllY2U6OmZpbmRfbGFzdF9ub3Rfb2YoU3RyaW5nUGllY2UgcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90eXBlIHBvcykgY29uc3QgeworICBpZiAobGVuZ3RoXyA8PSAwKSByZXR1cm4gbnBvczsKKworICBzdHJpbmdwaWVjZV9zc2l6ZV90eXBlIGkgPSBzdGQ6Om1pbihwb3MsIHN0YXRpY19jYXN0PHNpemVfdHlwZT4obGVuZ3RoXyAtIDEpKTsKKyAgaWYgKHMubGVuZ3RoXyA8PSAwKSByZXR1cm4gaTsKKworICAvLyBBdm9pZCB0aGUgY29zdCBvZiBCdWlsZExvb2t1cFRhYmxlKCkgZm9yIGEgc2luZ2xlLWNoYXJhY3RlciBzZWFyY2guCisgIGlmIChzLmxlbmd0aF8gPT0gMSkgcmV0dXJuIGZpbmRfbGFzdF9ub3Rfb2Yocy5wdHJfWzBdLCBwb3MpOworCisgIGJvb2wgbG9va3VwW1VDSEFSX01BWCArIDFdID0geyBmYWxzZSB9OworICBCdWlsZExvb2t1cFRhYmxlKHMsIGxvb2t1cCk7CisgIGZvciAoOyBpID49IDA7IC0taSkgeworICAgIGlmICghbG9va3VwW3N0YXRpY19jYXN0PHVuc2lnbmVkIGNoYXI+KHB0cl9baV0pXSkgeworICAgICAgcmV0dXJuIGk7CisgICAgfQorICB9CisgIHJldHVybiBucG9zOworfQorCitzdHJpbmdwaWVjZV9zc2l6ZV90eXBlIFN0cmluZ1BpZWNlOjpmaW5kX2xhc3Rfbm90X29mKGNoYXIgYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90eXBlIHBvcykgY29uc3QgeworICBpZiAobGVuZ3RoXyA8PSAwKSByZXR1cm4gbnBvczsKKworICBmb3IgKHN0cmluZ3BpZWNlX3NzaXplX3R5cGUgaSA9CisgICAgICAgc3RkOjptaW4ocG9zLCBzdGF0aWNfY2FzdDxzaXplX3R5cGU+KGxlbmd0aF8gLSAxKSk7IGkgPj0gMDsgLS1pKSB7CisgICAgaWYgKHB0cl9baV0gIT0gYykgeworICAgICAgcmV0dXJuIGk7CisgICAgfQorICB9CisgIHJldHVybiBucG9zOworfQorCitTdHJpbmdQaWVjZSBTdHJpbmdQaWVjZTo6c3Vic3RyKHNpemVfdHlwZSBwb3MsIHNpemVfdHlwZSBuKSBjb25zdCB7CisgIGlmIChwb3MgPiBsZW5ndGhfKSBwb3MgPSBsZW5ndGhfOworICBpZiAobiA+IGxlbmd0aF8gLSBwb3MpIG4gPSBsZW5ndGhfIC0gcG9zOworICByZXR1cm4gU3RyaW5nUGllY2UocHRyXyArIHBvcywgbik7Cit9CisKK2NvbnN0IFN0cmluZ1BpZWNlOjpzaXplX3R5cGUgU3RyaW5nUGllY2U6Om5wb3MgPSBzaXplX3R5cGUoLTEpOworCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvc3RyaW5ncGllY2UuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvc3RyaW5ncGllY2UuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lYzNmZmQ1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJpbmdwaWVjZS5oCkBAIC0wLDAgKzEsNDUzIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQSBTdHJpbmdQaWVjZSBwb2ludHMgdG8gcGFydCBvciBhbGwgb2YgYSBzdHJpbmcsIENvcmQsIGRvdWJsZS1xdW90ZWQgc3RyaW5nCisvLyBsaXRlcmFsLCBvciBvdGhlciBzdHJpbmctbGlrZSBvYmplY3QuICBBIFN0cmluZ1BpZWNlIGRvZXMgKm5vdCogb3duIHRoZQorLy8gc3RyaW5nIHRvIHdoaWNoIGl0IHBvaW50cy4gIEEgU3RyaW5nUGllY2UgaXMgbm90IG51bGwtdGVybWluYXRlZC4KKy8vCisvLyBZb3UgY2FuIHVzZSBTdHJpbmdQaWVjZSBhcyBhIGZ1bmN0aW9uIG9yIG1ldGhvZCBwYXJhbWV0ZXIuICBBIFN0cmluZ1BpZWNlCisvLyBwYXJhbWV0ZXIgY2FuIHJlY2VpdmUgYSBkb3VibGUtcXVvdGVkIHN0cmluZyBsaXRlcmFsIGFyZ3VtZW50LCBhICJjb25zdAorLy8gY2hhcioiIGFyZ3VtZW50LCBhIHN0cmluZyBhcmd1bWVudCwgb3IgYSBTdHJpbmdQaWVjZSBhcmd1bWVudCB3aXRoIG5vIGRhdGEKKy8vIGNvcHlpbmcuICBTeXN0ZW1hdGljIHVzZSBvZiBTdHJpbmdQaWVjZSBmb3IgYXJndW1lbnRzIHJlZHVjZXMgZGF0YQorLy8gY29waWVzIGFuZCBzdHJsZW4oKSBjYWxscy4KKy8vCisvLyBQcmVmZXIgcGFzc2luZyBTdHJpbmdQaWVjZXMgYnkgdmFsdWU6CisvLyAgIHZvaWQgTXlGdW5jdGlvbihTdHJpbmdQaWVjZSBhcmcpOworLy8gSWYgY2lyY3Vtc3RhbmNlcyByZXF1aXJlLCB5b3UgbWF5IGFsc28gcGFzcyBieSBjb25zdCByZWZlcmVuY2U6CisvLyAgIHZvaWQgTXlGdW5jdGlvbihjb25zdCBTdHJpbmdQaWVjZSYgYXJnKTsgIC8vIG5vdCBwcmVmZXJyZWQKKy8vIEJvdGggb2YgdGhlc2UgaGF2ZSB0aGUgc2FtZSBsaWZldGltZSBzZW1hbnRpY3MuICBQYXNzaW5nIGJ5IHZhbHVlCisvLyBnZW5lcmF0ZXMgc2xpZ2h0bHkgc21hbGxlciBjb2RlLiAgRm9yIG1vcmUgZGlzY3Vzc2lvbiwgc2VlIHRoZSB0aHJlYWQKKy8vIGdvL3N0cmluZ3BpZWNlYnl2YWx1ZSBvbiBjLXVzZXJzLgorLy8KKy8vIFN0cmluZ1BpZWNlIGlzIGFsc28gc3VpdGFibGUgZm9yIGxvY2FsIHZhcmlhYmxlcyBpZiB5b3Uga25vdyB0aGF0CisvLyB0aGUgbGlmZXRpbWUgb2YgdGhlIHVuZGVybHlpbmcgb2JqZWN0IGlzIGxvbmdlciB0aGFuIHRoZSBsaWZldGltZQorLy8gb2YgeW91ciBTdHJpbmdQaWVjZSB2YXJpYWJsZS4KKy8vCisvLyBCZXdhcmUgb2YgYmluZGluZyBhIFN0cmluZ1BpZWNlIHRvIGEgdGVtcG9yYXJ5OgorLy8gICBTdHJpbmdQaWVjZSBzcCA9IG9iai5NZXRob2RSZXR1cm5pbmdTdHJpbmcoKTsgIC8vIEJBRDogbGlmZXRpbWUgcHJvYmxlbQorLy8KKy8vIFRoaXMgY29kZSBpcyBva2F5OgorLy8gICBzdHJpbmcgc3RyID0gb2JqLk1ldGhvZFJldHVybmluZ1N0cmluZygpOyAgLy8gc3RyIG93bnMgaXRzIGNvbnRlbnRzCisvLyAgIFN0cmluZ1BpZWNlIHNwKHN0cik7ICAvLyBHT09ELCBiZWNhdXNlIHN0ciBvdXRsaXZlcyBzcAorLy8KKy8vIFN0cmluZ1BpZWNlIGlzIHNvbWV0aW1lcyBhIHBvb3IgY2hvaWNlIGZvciBhIHJldHVybiB2YWx1ZSBhbmQgdXN1YWxseSBhIHBvb3IKKy8vIGNob2ljZSBmb3IgYSBkYXRhIG1lbWJlci4gIElmIHlvdSBkbyB1c2UgYSBTdHJpbmdQaWVjZSB0aGlzIHdheSwgaXQgaXMgeW91cgorLy8gcmVzcG9uc2liaWxpdHkgdG8gZW5zdXJlIHRoYXQgdGhlIG9iamVjdCBwb2ludGVkIHRvIGJ5IHRoZSBTdHJpbmdQaWVjZQorLy8gb3V0bGl2ZXMgdGhlIFN0cmluZ1BpZWNlLgorLy8KKy8vIEEgU3RyaW5nUGllY2UgbWF5IHJlcHJlc2VudCBqdXN0IHBhcnQgb2YgYSBzdHJpbmc7IHRodXMgdGhlIG5hbWUgIlBpZWNlIi4KKy8vIEZvciBleGFtcGxlLCB3aGVuIHNwbGl0dGluZyBhIHN0cmluZywgdmVjdG9yPFN0cmluZ1BpZWNlPiBpcyBhIG5hdHVyYWwgZGF0YQorLy8gdHlwZSBmb3IgdGhlIG91dHB1dC4gIEZvciBhbm90aGVyIGV4YW1wbGUsIGEgQ29yZCBpcyBhIG5vbi1jb250aWd1b3VzLAorLy8gcG90ZW50aWFsbHkgdmVyeSBsb25nIHN0cmluZy1saWtlIG9iamVjdC4gIFRoZSBDb3JkIGNsYXNzIGhhcyBhbiBpbnRlcmZhY2UKKy8vIHRoYXQgaXRlcmF0aXZlbHkgcHJvdmlkZXMgU3RyaW5nUGllY2Ugb2JqZWN0cyB0aGF0IHBvaW50IHRvIHRoZQorLy8gc3VjY2Vzc2l2ZSBwaWVjZXMgb2YgYSBDb3JkIG9iamVjdC4KKy8vCisvLyBBIFN0cmluZ1BpZWNlIGlzIG5vdCBudWxsLXRlcm1pbmF0ZWQuICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IHNjYW5zIGEKKy8vIFN0cmluZ1BpZWNlLCB5b3UgbXVzdCBjaGVjayBpdHMgbGVuZ3RoIGJlZm9yZSByZWFkaW5nIGFueSBjaGFyYWN0ZXJzLgorLy8gQ29tbW9uIGlkaW9tcyB0aGF0IHdvcmsgb24gbnVsbC10ZXJtaW5hdGVkIHN0cmluZ3MgZG8gbm90IHdvcmsgb24KKy8vIFN0cmluZ1BpZWNlIG9iamVjdHMuCisvLworLy8gVGhlcmUgYXJlIHNldmVyYWwgd2F5cyB0byBjcmVhdGUgYSBudWxsIFN0cmluZ1BpZWNlOgorLy8gICBTdHJpbmdQaWVjZSgpCisvLyAgIFN0cmluZ1BpZWNlKE5VTEwpCisvLyAgIFN0cmluZ1BpZWNlKE5VTEwsIDApCisvLyBGb3IgYWxsIG9mIHRoZSBhYm92ZSwgc3AuZGF0YSgpID09IE5VTEwsIHNwLmxlbmd0aCgpID09IDAsCisvLyBhbmQgc3AuZW1wdHkoKSA9PSB0cnVlLiAgQWxzbywgaWYgeW91IGNyZWF0ZSBhIFN0cmluZ1BpZWNlIHdpdGgKKy8vIGEgbm9uLU5VTEwgcG9pbnRlciB0aGVuIHNwLmRhdGEoKSAhPSBOVUxMLiAgT25jZSBjcmVhdGVkLAorLy8gc3AuZGF0YSgpIHdpbGwgc3RheSBlaXRoZXIgTlVMTCBvciBub3QtTlVMTCwgZXhjZXB0IGlmIHlvdSBjYWxsCisvLyBzcC5jbGVhcigpIG9yIHNwLnNldCgpLgorLy8KKy8vIFRodXMsIHlvdSBjYW4gdXNlIFN0cmluZ1BpZWNlKE5VTEwpIHRvIHNpZ25hbCBhbiBvdXQtb2YtYmFuZCB2YWx1ZQorLy8gdGhhdCBpcyBkaWZmZXJlbnQgZnJvbSBvdGhlciBTdHJpbmdQaWVjZSB2YWx1ZXMuICBUaGlzIGlzIHNpbWlsYXIKKy8vIHRvIHRoZSB3YXkgdGhhdCBjb25zdCBjaGFyKiBwMSA9IE5VTEw7IGlzIGRpZmZlcmVudCBmcm9tCisvLyBjb25zdCBjaGFyKiBwMiA9ICIiOy4KKy8vCisvLyBUaGVyZSBhcmUgbWFueSB3YXlzIHRvIGNyZWF0ZSBhbiBlbXB0eSBTdHJpbmdQaWVjZToKKy8vICAgU3RyaW5nUGllY2UoKQorLy8gICBTdHJpbmdQaWVjZShOVUxMKQorLy8gICBTdHJpbmdQaWVjZShOVUxMLCAwKQorLy8gICBTdHJpbmdQaWVjZSgiIikKKy8vICAgU3RyaW5nUGllY2UoIiIsIDApCisvLyAgIFN0cmluZ1BpZWNlKCJhYmNkZWYiLCAwKQorLy8gICBTdHJpbmdQaWVjZSgiYWJjZGVmIis2LCAwKQorLy8gRm9yIGFsbCBvZiB0aGUgYWJvdmUsIHNwLmxlbmd0aCgpIHdpbGwgYmUgMCBhbmQgc3AuZW1wdHkoKSB3aWxsIGJlIHRydWUuCisvLyBGb3Igc29tZSBlbXB0eSBTdHJpbmdQaWVjZSB2YWx1ZXMsIHNwLmRhdGEoKSB3aWxsIGJlIE5VTEwuCisvLyBGb3Igc29tZSBlbXB0eSBTdHJpbmdQaWVjZSB2YWx1ZXMsIHNwLmRhdGEoKSB3aWxsIG5vdCBiZSBOVUxMLgorLy8KKy8vIEJlIGNhcmVmdWwgbm90IHRvIGNvbmZ1c2U6IG51bGwgU3RyaW5nUGllY2UgYW5kIGVtcHR5IFN0cmluZ1BpZWNlLgorLy8gVGhlIHNldCBvZiBlbXB0eSBTdHJpbmdQaWVjZXMgcHJvcGVybHkgaW5jbHVkZXMgdGhlIHNldCBvZiBudWxsIFN0cmluZ1BpZWNlcy4KKy8vIFRoYXQgaXMsIGV2ZXJ5IG51bGwgU3RyaW5nUGllY2UgaXMgYW4gZW1wdHkgU3RyaW5nUGllY2UsCisvLyBidXQgc29tZSBub24tbnVsbCBTdHJpbmdQaWVjZXMgYXJlIGVtcHR5IFN0cmluZ3BpZWNlcyB0b28uCisvLworLy8gQWxsIGVtcHR5IFN0cmluZ1BpZWNlIHZhbHVlcyBjb21wYXJlIGVxdWFsIHRvIGVhY2ggb3RoZXIuCisvLyBFdmVuIGEgbnVsbCBTdHJpbmdQaWVjZXMgY29tcGFyZXMgZXF1YWwgdG8gYSBub24tbnVsbCBlbXB0eSBTdHJpbmdQaWVjZToKKy8vICBTdHJpbmdQaWVjZSgpID09IFN0cmluZ1BpZWNlKCIiLCAwKQorLy8gIFN0cmluZ1BpZWNlKE5VTEwpID09IFN0cmluZ1BpZWNlKCJhYmMiLCAwKQorLy8gIFN0cmluZ1BpZWNlKE5VTEwsIDApID09IFN0cmluZ1BpZWNlKCJhYmNkZWYiKzYsIDApCisvLworLy8gTG9vayBjYXJlZnVsbHkgYXQgdGhpcyBleGFtcGxlOgorLy8gICBTdHJpbmdQaWVjZSgiIikgPT0gTlVMTAorLy8gVHJ1ZSBvciBmYWxzZT8gIFRSVUUsIGJlY2F1c2UgU3RyaW5nUGllY2U6Om9wZXJhdG9yPT0gY29udmVydHMKKy8vIHRoZSByaWdodC1oYW5kIHNpZGUgZnJvbSBOVUxMIHRvIFN0cmluZ1BpZWNlKE5VTEwpLAorLy8gYW5kIHRoZW4gY29tcGFyZXMgdHdvIHplcm8tbGVuZ3RoIHNwYW5zIG9mIGNoYXJhY3RlcnMuCisvLyBIb3dldmVyLCB3ZSBhcmUgd29ya2luZyB0byBtYWtlIHRoaXMgZXhhbXBsZSBwcm9kdWNlIGEgY29tcGlsZSBlcnJvci4KKy8vCisvLyBTdXBwb3NlIHlvdSB3YW50IHRvIHdyaXRlOgorLy8gICBib29sIFRlc3RXaGF0PyhTdHJpbmdQaWVjZSBzcCkgeyByZXR1cm4gc3AgPT0gTlVMTDsgfSAgLy8gQkFECisvLyBEbyBub3QgZG8gdGhhdC4gIFdyaXRlIG9uZSBvZiB0aGVzZSBpbnN0ZWFkOgorLy8gICBib29sIFRlc3ROdWxsKFN0cmluZ1BpZWNlIHNwKSB7IHJldHVybiBzcC5kYXRhKCkgPT0gTlVMTDsgfQorLy8gICBib29sIFRlc3RFbXB0eShTdHJpbmdQaWVjZSBzcCkgeyByZXR1cm4gc3AuZW1wdHkoKTsgfQorLy8gVGhlIGludGVudCBvZiBUZXN0V2hhdD8gaXMgdW5jbGVhci4gIERpZCB5b3UgbWVhbiBUZXN0TnVsbCBvciBUZXN0RW1wdHk/CisvLyBSaWdodCBub3csIFRlc3RXaGF0PyBiZWhhdmVzIGxpa2VzIFRlc3RFbXB0eS4KKy8vIFdlIGFyZSB3b3JraW5nIHRvIG1ha2UgVGVzdFdoYXQ/IHByb2R1Y2UgYSBjb21waWxlIGVycm9yLgorLy8gVGVzdE51bGwgaXMgZ29vZCB0byB0ZXN0IGZvciBhbiBvdXQtb2YtYmFuZCBzaWduYWwuCisvLyBUZXN0RW1wdHkgaXMgZ29vZCB0byB0ZXN0IGZvciBhbiBlbXB0eSBTdHJpbmdQaWVjZS4KKy8vCisvLyBDYXZlYXRzIChhZ2Fpbik6CisvLyAoMSkgVGhlIGxpZmV0aW1lIG9mIHRoZSBwb2ludGVkLXRvIHN0cmluZyAob3IgcGllY2Ugb2YgYSBzdHJpbmcpCisvLyAgICAgbXVzdCBiZSBsb25nZXIgdGhhbiB0aGUgbGlmZXRpbWUgb2YgdGhlIFN0cmluZ1BpZWNlLgorLy8gKDIpIFRoZXJlIG1heSBvciBtYXkgbm90IGJlIGEgJ1wwJyBjaGFyYWN0ZXIgYWZ0ZXIgdGhlIGVuZCBvZgorLy8gICAgIFN0cmluZ1BpZWNlIGRhdGEuCisvLyAoMykgQSBudWxsIFN0cmluZ1BpZWNlIGlzIGVtcHR5LgorLy8gICAgIEFuIGVtcHR5IFN0cmluZ1BpZWNlIG1heSBvciBtYXkgbm90IGJlIGEgbnVsbCBTdHJpbmdQaWVjZS4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfU1RVQlNfU1RSSU5HUElFQ0VfSF8KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1NUVUJTX1NUUklOR1BJRUNFX0hfCisKKyNpbmNsdWRlIDxhc3NlcnQuaD4KKyNpbmNsdWRlIDxzdGRkZWYuaD4KKyNpbmNsdWRlIDxzdHJpbmcuaD4KKyNpbmNsdWRlIDxpb3Nmd2Q+CisjaW5jbHVkZSA8bGltaXRzPgorI2luY2x1ZGUgPHN0cmluZz4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvaGFzaC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisvLyBTdHJpbmdQaWVjZSBoYXMgKnR3byogc2l6ZSB0eXBlcy4KKy8vIFN0cmluZ1BpZWNlOjpzaXplX3R5cGUKKy8vICAgaXMgdW5zaWduZWQKKy8vICAgaXMgMzIgYml0cyBpbiBMUDMyLCA2NCBiaXRzIGluIExQNjQsIDY0IGJpdHMgaW4gTExQNjQKKy8vICAgbm8gZnV0dXJlIGNoYW5nZXMgaW50ZW5kZWQKKy8vIHN0cmluZ3BpZWNlX3NzaXplX3R5cGUKKy8vICAgaXMgc2lnbmVkCisvLyAgIGlzIDMyIGJpdHMgaW4gTFAzMiwgNjQgYml0cyBpbiBMUDY0LCA2NCBiaXRzIGluIExMUDY0CisvLyAgIGZ1dHVyZSBjaGFuZ2VzIGludGVuZGVkOiBodHRwOi8vZ28vNjRCaXRTdHJpbmdQaWVjZQorLy8KK3R5cGVkZWYgc3RyaW5nOjpkaWZmZXJlbmNlX3R5cGUgc3RyaW5ncGllY2Vfc3NpemVfdHlwZTsKKworLy8gU1RSSU5HUElFQ0VfQ0hFQ0tfU0laRSBwcm90ZWN0cyB1cyBmcm9tIDMyLWJpdCBvdmVyZmxvd3MuCisvLyBUT0RPKG1lYyk6IGRlbGV0ZSB0aGlzIGFmdGVyIHN0cmluZ3BpZWNlX3NzaXplX3R5cGUgZ29lcyA2NCBiaXQuCisjaWYgIWRlZmluZWQoTkRFQlVHKQorI2RlZmluZSBTVFJJTkdQSUVDRV9DSEVDS19TSVpFIDEKKyNlbGlmIGRlZmluZWQoX0ZPUlRJRllfU09VUkNFKSAmJiBfRk9SVElGWV9TT1VSQ0UgPiAwCisjZGVmaW5lIFNUUklOR1BJRUNFX0NIRUNLX1NJWkUgMQorI2Vsc2UKKyNkZWZpbmUgU1RSSU5HUElFQ0VfQ0hFQ0tfU0laRSAwCisjZW5kaWYKKworY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFN0cmluZ1BpZWNlIHsKKyBwcml2YXRlOgorICBjb25zdCBjaGFyKiBwdHJfOworICBzdHJpbmdwaWVjZV9zc2l6ZV90eXBlIGxlbmd0aF87CisKKyAgLy8gUHJldmVudCBvdmVyZmxvdyBpbiBkZWJ1ZyBtb2RlIG9yIGZvcnRpZmllZCBtb2RlLgorICAvLyBzaXplb2Yoc3RyaW5ncGllY2Vfc3NpemVfdHlwZSkgbWF5IGJlIHNtYWxsZXIgdGhhbiBzaXplb2Yoc2l6ZV90KS4KKyAgc3RhdGljIHN0cmluZ3BpZWNlX3NzaXplX3R5cGUgQ2hlY2tlZFNzaXplVEZyb21TaXplVChzaXplX3Qgc2l6ZSkgeworI2lmIFNUUklOR1BJRUNFX0NIRUNLX1NJWkUgPiAwCisjaWZkZWYgbWF4CisjdW5kZWYgbWF4CisjZW5kaWYKKyAgICBpZiAoc2l6ZSA+IHN0YXRpY19jYXN0PHNpemVfdD4oCisgICAgICAgIHN0ZDo6bnVtZXJpY19saW1pdHM8c3RyaW5ncGllY2Vfc3NpemVfdHlwZT46Om1heCgpKSkgeworICAgICAgLy8gU29tZSBwZW9wbGUgZ3JlcCBmb3IgdGhpcyBtZXNzYWdlIGluIGxvZ3MKKyAgICAgIC8vIHNvIHRha2UgY2FyZSBpZiB5b3UgZXZlciBjaGFuZ2UgaXQuCisgICAgICBMb2dGYXRhbFNpemVUb29CaWcoc2l6ZSwgInNpemVfdCB0byBpbnQgY29udmVyc2lvbiIpOworICAgIH0KKyNlbmRpZgorICAgIHJldHVybiBzdGF0aWNfY2FzdDxzdHJpbmdwaWVjZV9zc2l6ZV90eXBlPihzaXplKTsKKyAgfQorCisgIC8vIE91dC1vZi1saW5lIGVycm9yIHBhdGguCisgIHN0YXRpYyB2b2lkIExvZ0ZhdGFsU2l6ZVRvb0JpZyhzaXplX3Qgc2l6ZSwgY29uc3QgY2hhciogZGV0YWlscyk7CisKKyBwdWJsaWM6CisgIC8vIFdlIHByb3ZpZGUgbm9uLWV4cGxpY2l0IHNpbmdsZXRvbiBjb25zdHJ1Y3RvcnMgc28gdXNlcnMgY2FuIHBhc3MKKyAgLy8gaW4gYSAiY29uc3QgY2hhcioiIG9yIGEgInN0cmluZyIgd2hlcmV2ZXIgYSAiU3RyaW5nUGllY2UiIGlzCisgIC8vIGV4cGVjdGVkLgorICAvLworICAvLyBTdHlsZSBndWlkZSBleGNlcHRpb24gZ3JhbnRlZDoKKyAgLy8gaHR0cDovL2dvdG8vc3R5bGUtZ3VpZGUtZXhjZXB0aW9uLTIwOTc4Mjg4CisgIFN0cmluZ1BpZWNlKCkgOiBwdHJfKE5VTEwpLCBsZW5ndGhfKDApIHt9CisKKyAgU3RyaW5nUGllY2UoY29uc3QgY2hhciogc3RyKSAgLy8gTk9MSU5UKHJ1bnRpbWUvZXhwbGljaXQpCisgICAgICA6IHB0cl8oc3RyKSwgbGVuZ3RoXygwKSB7CisgICAgaWYgKHN0ciAhPSBOVUxMKSB7CisgICAgICBsZW5ndGhfID0gQ2hlY2tlZFNzaXplVEZyb21TaXplVChzdHJsZW4oc3RyKSk7CisgICAgfQorICB9CisKKyAgdGVtcGxhdGUgPGNsYXNzIEFsbG9jYXRvcj4KKyAgU3RyaW5nUGllY2UoICAvLyBOT0xJTlQocnVudGltZS9leHBsaWNpdCkKKyAgICAgIGNvbnN0IHN0ZDo6YmFzaWNfc3RyaW5nPGNoYXIsIHN0ZDo6Y2hhcl90cmFpdHM8Y2hhcj4sIEFsbG9jYXRvcj4mIHN0cikKKyAgICAgIDogcHRyXyhzdHIuZGF0YSgpKSwgbGVuZ3RoXygwKSB7CisgICAgbGVuZ3RoXyA9IENoZWNrZWRTc2l6ZVRGcm9tU2l6ZVQoc3RyLnNpemUoKSk7CisgIH0KKyNpZiBkZWZpbmVkKEhBU19HTE9CQUxfU1RSSU5HKQorICB0ZW1wbGF0ZSA8Y2xhc3MgQWxsb2NhdG9yPgorICBTdHJpbmdQaWVjZSggIC8vIE5PTElOVChydW50aW1lL2V4cGxpY2l0KQorICAgICAgY29uc3QgYmFzaWNfc3RyaW5nPGNoYXIsIHN0ZDo6Y2hhcl90cmFpdHM8Y2hhcj4sIEFsbG9jYXRvcj4mIHN0cikKKyAgICAgIDogcHRyXyhzdHIuZGF0YSgpKSwgbGVuZ3RoXygwKSB7CisgICAgbGVuZ3RoXyA9IENoZWNrZWRTc2l6ZVRGcm9tU2l6ZVQoc3RyLnNpemUoKSk7CisgIH0KKyNlbmRpZgorCisgIFN0cmluZ1BpZWNlKGNvbnN0IGNoYXIqIG9mZnNldCwgc3RyaW5ncGllY2Vfc3NpemVfdHlwZSBsZW4pCisgICAgICA6IHB0cl8ob2Zmc2V0KSwgbGVuZ3RoXyhsZW4pIHsKKyAgICBhc3NlcnQobGVuID49IDApOworICB9CisKKyAgLy8gU3Vic3RyaW5nIG9mIGFub3RoZXIgU3RyaW5nUGllY2UuCisgIC8vIHBvcyBtdXN0IGJlIG5vbi1uZWdhdGl2ZSBhbmQgPD0geC5sZW5ndGgoKS4KKyAgU3RyaW5nUGllY2UoU3RyaW5nUGllY2UgeCwgc3RyaW5ncGllY2Vfc3NpemVfdHlwZSBwb3MpOworICAvLyBTdWJzdHJpbmcgb2YgYW5vdGhlciBTdHJpbmdQaWVjZS4KKyAgLy8gcG9zIG11c3QgYmUgbm9uLW5lZ2F0aXZlIGFuZCA8PSB4Lmxlbmd0aCgpLgorICAvLyBsZW4gbXVzdCBiZSBub24tbmVnYXRpdmUgYW5kIHdpbGwgYmUgcGlubmVkIHRvIGF0IG1vc3QgeC5sZW5ndGgoKSAtIHBvcy4KKyAgU3RyaW5nUGllY2UoU3RyaW5nUGllY2UgeCwKKyAgICAgICAgICAgICAgc3RyaW5ncGllY2Vfc3NpemVfdHlwZSBwb3MsCisgICAgICAgICAgICAgIHN0cmluZ3BpZWNlX3NzaXplX3R5cGUgbGVuKTsKKworICAvLyBkYXRhKCkgbWF5IHJldHVybiBhIHBvaW50ZXIgdG8gYSBidWZmZXIgd2l0aCBlbWJlZGRlZCBOVUxzLCBhbmQgdGhlCisgIC8vIHJldHVybmVkIGJ1ZmZlciBtYXkgb3IgbWF5IG5vdCBiZSBudWxsIHRlcm1pbmF0ZWQuICBUaGVyZWZvcmUgaXQgaXMKKyAgLy8gdHlwaWNhbGx5IGEgbWlzdGFrZSB0byBwYXNzIGRhdGEoKSB0byBhIHJvdXRpbmUgdGhhdCBleHBlY3RzIGEgTlVMCisgIC8vIHRlcm1pbmF0ZWQgc3RyaW5nLgorICBjb25zdCBjaGFyKiBkYXRhKCkgY29uc3QgeyByZXR1cm4gcHRyXzsgfQorICBzdHJpbmdwaWVjZV9zc2l6ZV90eXBlIHNpemUoKSBjb25zdCB7IHJldHVybiBsZW5ndGhfOyB9CisgIHN0cmluZ3BpZWNlX3NzaXplX3R5cGUgbGVuZ3RoKCkgY29uc3QgeyByZXR1cm4gbGVuZ3RoXzsgfQorICBib29sIGVtcHR5KCkgY29uc3QgeyByZXR1cm4gbGVuZ3RoXyA9PSAwOyB9CisKKyAgdm9pZCBjbGVhcigpIHsKKyAgICBwdHJfID0gTlVMTDsKKyAgICBsZW5ndGhfID0gMDsKKyAgfQorCisgIHZvaWQgc2V0KGNvbnN0IGNoYXIqIGRhdGEsIHN0cmluZ3BpZWNlX3NzaXplX3R5cGUgbGVuKSB7CisgICAgYXNzZXJ0KGxlbiA+PSAwKTsKKyAgICBwdHJfID0gZGF0YTsKKyAgICBsZW5ndGhfID0gbGVuOworICB9CisKKyAgdm9pZCBzZXQoY29uc3QgY2hhciogc3RyKSB7CisgICAgcHRyXyA9IHN0cjsKKyAgICBpZiAoc3RyICE9IE5VTEwpCisgICAgICBsZW5ndGhfID0gQ2hlY2tlZFNzaXplVEZyb21TaXplVChzdHJsZW4oc3RyKSk7CisgICAgZWxzZQorICAgICAgbGVuZ3RoXyA9IDA7CisgIH0KKworICB2b2lkIHNldChjb25zdCB2b2lkKiBkYXRhLCBzdHJpbmdwaWVjZV9zc2l6ZV90eXBlIGxlbikgeworICAgIHB0cl8gPSByZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPihkYXRhKTsKKyAgICBsZW5ndGhfID0gbGVuOworICB9CisKKyAgY2hhciBvcGVyYXRvcltdKHN0cmluZ3BpZWNlX3NzaXplX3R5cGUgaSkgY29uc3QgeworICAgIGFzc2VydCgwIDw9IGkpOworICAgIGFzc2VydChpIDwgbGVuZ3RoXyk7CisgICAgcmV0dXJuIHB0cl9baV07CisgIH0KKworICB2b2lkIHJlbW92ZV9wcmVmaXgoc3RyaW5ncGllY2Vfc3NpemVfdHlwZSBuKSB7CisgICAgYXNzZXJ0KGxlbmd0aF8gPj0gbik7CisgICAgcHRyXyArPSBuOworICAgIGxlbmd0aF8gLT0gbjsKKyAgfQorCisgIHZvaWQgcmVtb3ZlX3N1ZmZpeChzdHJpbmdwaWVjZV9zc2l6ZV90eXBlIG4pIHsKKyAgICBhc3NlcnQobGVuZ3RoXyA+PSBuKTsKKyAgICBsZW5ndGhfIC09IG47CisgIH0KKworICAvLyByZXR1cm5zIHstMSwgMCwgMX0KKyAgaW50IGNvbXBhcmUoU3RyaW5nUGllY2UgeCkgY29uc3QgeworICAgIGNvbnN0IHN0cmluZ3BpZWNlX3NzaXplX3R5cGUgbWluX3NpemUgPQorICAgICAgICBsZW5ndGhfIDwgeC5sZW5ndGhfID8gbGVuZ3RoXyA6IHgubGVuZ3RoXzsKKyAgICBpbnQgciA9IG1lbWNtcChwdHJfLCB4LnB0cl8sIG1pbl9zaXplKTsKKyAgICBpZiAociA8IDApIHJldHVybiAtMTsKKyAgICBpZiAociA+IDApIHJldHVybiAxOworICAgIGlmIChsZW5ndGhfIDwgeC5sZW5ndGhfKSByZXR1cm4gLTE7CisgICAgaWYgKGxlbmd0aF8gPiB4Lmxlbmd0aF8pIHJldHVybiAxOworICAgIHJldHVybiAwOworICB9CisKKyAgc3RyaW5nIGFzX3N0cmluZygpIGNvbnN0IHsKKyAgICByZXR1cm4gVG9TdHJpbmcoKTsKKyAgfQorICAvLyBXZSBhbHNvIGRlZmluZSBUb1N0cmluZygpIGhlcmUsIHNpbmNlIG1hbnkgb3RoZXIgc3RyaW5nLWxpa2UKKyAgLy8gaW50ZXJmYWNlcyBuYW1lIHRoZSByb3V0aW5lIHRoYXQgY29udmVydHMgdG8gYSBDKysgc3RyaW5nCisgIC8vICJUb1N0cmluZyIsIGFuZCBpdCdzIGNvbmZ1c2luZyB0byBoYXZlIHRoZSBtZXRob2QgdGhhdCBkb2VzIHRoYXQKKyAgLy8gZm9yIGEgU3RyaW5nUGllY2UgYmUgY2FsbGVkICJhc19zdHJpbmcoKSIuICBXZSBhbHNvIGxlYXZlIHRoZQorICAvLyAiYXNfc3RyaW5nKCkiIG1ldGhvZCBkZWZpbmVkIGhlcmUgZm9yIGV4aXN0aW5nIGNvZGUuCisgIHN0cmluZyBUb1N0cmluZygpIGNvbnN0IHsKKyAgICBpZiAocHRyXyA9PSBOVUxMKSByZXR1cm4gc3RyaW5nKCk7CisgICAgcmV0dXJuIHN0cmluZyhkYXRhKCksIHNpemUoKSk7CisgIH0KKworICBvcGVyYXRvciBzdHJpbmcoKSBjb25zdCB7CisgICAgcmV0dXJuIFRvU3RyaW5nKCk7CisgIH0KKworICB2b2lkIENvcHlUb1N0cmluZyhzdHJpbmcqIHRhcmdldCkgY29uc3Q7CisgIHZvaWQgQXBwZW5kVG9TdHJpbmcoc3RyaW5nKiB0YXJnZXQpIGNvbnN0OworCisgIGJvb2wgc3RhcnRzX3dpdGgoU3RyaW5nUGllY2UgeCkgY29uc3QgeworICAgIHJldHVybiAobGVuZ3RoXyA+PSB4Lmxlbmd0aF8pICYmIChtZW1jbXAocHRyXywgeC5wdHJfLCB4Lmxlbmd0aF8pID09IDApOworICB9CisKKyAgYm9vbCBlbmRzX3dpdGgoU3RyaW5nUGllY2UgeCkgY29uc3QgeworICAgIHJldHVybiAoKGxlbmd0aF8gPj0geC5sZW5ndGhfKSAmJgorICAgICAgICAgICAgKG1lbWNtcChwdHJfICsgKGxlbmd0aF8teC5sZW5ndGhfKSwgeC5wdHJfLCB4Lmxlbmd0aF8pID09IDApKTsKKyAgfQorCisgIC8vIENoZWNrcyB3aGV0aGVyIFN0cmluZ1BpZWNlIHN0YXJ0cyB3aXRoIHggYW5kIGlmIHNvIGFkdmFuY2VzIHRoZSBiZWdpbm5pbmcKKyAgLy8gb2YgaXQgdG8gcGFzdCB0aGUgbWF0Y2guICBJdCdzIGJhc2ljYWxseSBhIHNob3J0Y3V0IGZvciBzdGFydHNfd2l0aAorICAvLyBmb2xsb3dlZCBieSByZW1vdmVfcHJlZml4LgorICBib29sIENvbnN1bWUoU3RyaW5nUGllY2UgeCk7CisgIC8vIExpa2UgYWJvdmUgYnV0IGZvciB0aGUgZW5kIG9mIHRoZSBzdHJpbmcuCisgIGJvb2wgQ29uc3VtZUZyb21FbmQoU3RyaW5nUGllY2UgeCk7CisKKyAgLy8gc3RhbmRhcmQgU1RMIGNvbnRhaW5lciBib2lsZXJwbGF0ZQorICB0eXBlZGVmIGNoYXIgdmFsdWVfdHlwZTsKKyAgdHlwZWRlZiBjb25zdCBjaGFyKiBwb2ludGVyOworICB0eXBlZGVmIGNvbnN0IGNoYXImIHJlZmVyZW5jZTsKKyAgdHlwZWRlZiBjb25zdCBjaGFyJiBjb25zdF9yZWZlcmVuY2U7CisgIHR5cGVkZWYgc2l6ZV90IHNpemVfdHlwZTsKKyAgdHlwZWRlZiBwdHJkaWZmX3QgZGlmZmVyZW5jZV90eXBlOworICBzdGF0aWMgY29uc3Qgc2l6ZV90eXBlIG5wb3M7CisgIHR5cGVkZWYgY29uc3QgY2hhciogY29uc3RfaXRlcmF0b3I7CisgIHR5cGVkZWYgY29uc3QgY2hhciogaXRlcmF0b3I7CisgIHR5cGVkZWYgc3RkOjpyZXZlcnNlX2l0ZXJhdG9yPGNvbnN0X2l0ZXJhdG9yPiBjb25zdF9yZXZlcnNlX2l0ZXJhdG9yOworICB0eXBlZGVmIHN0ZDo6cmV2ZXJzZV9pdGVyYXRvcjxpdGVyYXRvcj4gcmV2ZXJzZV9pdGVyYXRvcjsKKyAgaXRlcmF0b3IgYmVnaW4oKSBjb25zdCB7IHJldHVybiBwdHJfOyB9CisgIGl0ZXJhdG9yIGVuZCgpIGNvbnN0IHsgcmV0dXJuIHB0cl8gKyBsZW5ndGhfOyB9CisgIGNvbnN0X3JldmVyc2VfaXRlcmF0b3IgcmJlZ2luKCkgY29uc3QgeworICAgIHJldHVybiBjb25zdF9yZXZlcnNlX2l0ZXJhdG9yKHB0cl8gKyBsZW5ndGhfKTsKKyAgfQorICBjb25zdF9yZXZlcnNlX2l0ZXJhdG9yIHJlbmQoKSBjb25zdCB7CisgICAgcmV0dXJuIGNvbnN0X3JldmVyc2VfaXRlcmF0b3IocHRyXyk7CisgIH0KKyAgc3RyaW5ncGllY2Vfc3NpemVfdHlwZSBtYXhfc2l6ZSgpIGNvbnN0IHsgcmV0dXJuIGxlbmd0aF87IH0KKyAgc3RyaW5ncGllY2Vfc3NpemVfdHlwZSBjYXBhY2l0eSgpIGNvbnN0IHsgcmV0dXJuIGxlbmd0aF87IH0KKworICAvLyBjcHBsaW50LnB5IGVtaXRzIGEgZmFsc2UgcG9zaXRpdmUgW2J1aWxkL2luY2x1ZGVfd2hhdF95b3VfdXNlXQorICBzdHJpbmdwaWVjZV9zc2l6ZV90eXBlIGNvcHkoY2hhciogYnVmLCBzaXplX3R5cGUgbiwgc2l6ZV90eXBlIHBvcyA9IDApIGNvbnN0OyAgLy8gTk9MSU5UCisKKyAgYm9vbCBjb250YWlucyhTdHJpbmdQaWVjZSBzKSBjb25zdDsKKworICBzdHJpbmdwaWVjZV9zc2l6ZV90eXBlIGZpbmQoU3RyaW5nUGllY2Ugcywgc2l6ZV90eXBlIHBvcyA9IDApIGNvbnN0OworICBzdHJpbmdwaWVjZV9zc2l6ZV90eXBlIGZpbmQoY2hhciBjLCBzaXplX3R5cGUgcG9zID0gMCkgY29uc3Q7CisgIHN0cmluZ3BpZWNlX3NzaXplX3R5cGUgcmZpbmQoU3RyaW5nUGllY2Ugcywgc2l6ZV90eXBlIHBvcyA9IG5wb3MpIGNvbnN0OworICBzdHJpbmdwaWVjZV9zc2l6ZV90eXBlIHJmaW5kKGNoYXIgYywgc2l6ZV90eXBlIHBvcyA9IG5wb3MpIGNvbnN0OworCisgIHN0cmluZ3BpZWNlX3NzaXplX3R5cGUgZmluZF9maXJzdF9vZihTdHJpbmdQaWVjZSBzLCBzaXplX3R5cGUgcG9zID0gMCkgY29uc3Q7CisgIHN0cmluZ3BpZWNlX3NzaXplX3R5cGUgZmluZF9maXJzdF9vZihjaGFyIGMsIHNpemVfdHlwZSBwb3MgPSAwKSBjb25zdCB7CisgICAgcmV0dXJuIGZpbmQoYywgcG9zKTsKKyAgfQorICBzdHJpbmdwaWVjZV9zc2l6ZV90eXBlIGZpbmRfZmlyc3Rfbm90X29mKFN0cmluZ1BpZWNlIHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90eXBlIHBvcyA9IDApIGNvbnN0OworICBzdHJpbmdwaWVjZV9zc2l6ZV90eXBlIGZpbmRfZmlyc3Rfbm90X29mKGNoYXIgYywgc2l6ZV90eXBlIHBvcyA9IDApIGNvbnN0OworICBzdHJpbmdwaWVjZV9zc2l6ZV90eXBlIGZpbmRfbGFzdF9vZihTdHJpbmdQaWVjZSBzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3R5cGUgcG9zID0gbnBvcykgY29uc3Q7CisgIHN0cmluZ3BpZWNlX3NzaXplX3R5cGUgZmluZF9sYXN0X29mKGNoYXIgYywgc2l6ZV90eXBlIHBvcyA9IG5wb3MpIGNvbnN0IHsKKyAgICByZXR1cm4gcmZpbmQoYywgcG9zKTsKKyAgfQorICBzdHJpbmdwaWVjZV9zc2l6ZV90eXBlIGZpbmRfbGFzdF9ub3Rfb2YoU3RyaW5nUGllY2UgcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdHlwZSBwb3MgPSBucG9zKSBjb25zdDsKKyAgc3RyaW5ncGllY2Vfc3NpemVfdHlwZSBmaW5kX2xhc3Rfbm90X29mKGNoYXIgYywgc2l6ZV90eXBlIHBvcyA9IG5wb3MpIGNvbnN0OworCisgIFN0cmluZ1BpZWNlIHN1YnN0cihzaXplX3R5cGUgcG9zLCBzaXplX3R5cGUgbiA9IG5wb3MpIGNvbnN0OworfTsKKworLy8gVGhpcyBsYXJnZSBmdW5jdGlvbiBpcyBkZWZpbmVkIGlubGluZSBzbyB0aGF0IGluIGEgZmFpcmx5IGNvbW1vbiBjYXNlIHdoZXJlCisvLyBvbmUgb2YgdGhlIGFyZ3VtZW50cyBpcyBhIGxpdGVyYWwsIHRoZSBjb21waWxlciBjYW4gZWxpZGUgYSBsb3Qgb2YgdGhlCisvLyBmb2xsb3dpbmcgY29tcGFyaXNvbnMuCitpbmxpbmUgYm9vbCBvcGVyYXRvcj09KFN0cmluZ1BpZWNlIHgsIFN0cmluZ1BpZWNlIHkpIHsKKyAgc3RyaW5ncGllY2Vfc3NpemVfdHlwZSBsZW4gPSB4LnNpemUoKTsKKyAgaWYgKGxlbiAhPSB5LnNpemUoKSkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIHJldHVybiB4LmRhdGEoKSA9PSB5LmRhdGEoKSB8fCBsZW4gPD0gMCB8fAorICAgICAgbWVtY21wKHguZGF0YSgpLCB5LmRhdGEoKSwgbGVuKSA9PSAwOworfQorCitpbmxpbmUgYm9vbCBvcGVyYXRvciE9KFN0cmluZ1BpZWNlIHgsIFN0cmluZ1BpZWNlIHkpIHsKKyAgcmV0dXJuICEoeCA9PSB5KTsKK30KKworaW5saW5lIGJvb2wgb3BlcmF0b3I8KFN0cmluZ1BpZWNlIHgsIFN0cmluZ1BpZWNlIHkpIHsKKyAgY29uc3Qgc3RyaW5ncGllY2Vfc3NpemVfdHlwZSBtaW5fc2l6ZSA9CisgICAgICB4LnNpemUoKSA8IHkuc2l6ZSgpID8geC5zaXplKCkgOiB5LnNpemUoKTsKKyAgY29uc3QgaW50IHIgPSBtZW1jbXAoeC5kYXRhKCksIHkuZGF0YSgpLCBtaW5fc2l6ZSk7CisgIHJldHVybiAociA8IDApIHx8IChyID09IDAgJiYgeC5zaXplKCkgPCB5LnNpemUoKSk7Cit9CisKK2lubGluZSBib29sIG9wZXJhdG9yPihTdHJpbmdQaWVjZSB4LCBTdHJpbmdQaWVjZSB5KSB7CisgIHJldHVybiB5IDwgeDsKK30KKworaW5saW5lIGJvb2wgb3BlcmF0b3I8PShTdHJpbmdQaWVjZSB4LCBTdHJpbmdQaWVjZSB5KSB7CisgIHJldHVybiAhKHggPiB5KTsKK30KKworaW5saW5lIGJvb2wgb3BlcmF0b3I+PShTdHJpbmdQaWVjZSB4LCBTdHJpbmdQaWVjZSB5KSB7CisgIHJldHVybiAhKHggPCB5KTsKK30KKworLy8gYWxsb3cgU3RyaW5nUGllY2UgdG8gYmUgbG9nZ2VkCitleHRlcm4gc3RkOjpvc3RyZWFtJiBvcGVyYXRvcjw8KHN0ZDo6b3N0cmVhbSYgbywgU3RyaW5nUGllY2UgcGllY2UpOworCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworR09PR0xFX1BST1RPQlVGX0hBU0hfTkFNRVNQQUNFX0RFQ0xBUkFUSU9OX1NUQVJUCit0ZW1wbGF0ZTw+IHN0cnVjdCBoYXNoPFN0cmluZ1BpZWNlPiB7CisgIHNpemVfdCBvcGVyYXRvcigpKGNvbnN0IFN0cmluZ1BpZWNlJiBzKSBjb25zdCB7CisgICAgc2l6ZV90IHJlc3VsdCA9IDA7CisgICAgZm9yIChjb25zdCBjaGFyICpzdHIgPSBzLmRhdGEoKSwgKmVuZCA9IHN0ciArIHMuc2l6ZSgpOyBzdHIgPCBlbmQ7IHN0cisrKSB7ICAKKyAgICAgIHJlc3VsdCA9IDUgKiByZXN1bHQgKyAqc3RyOworICAgIH0KKyAgICByZXR1cm4gcmVzdWx0OworICB9Cit9OworR09PR0xFX1BST1RPQlVGX0hBU0hfTkFNRVNQQUNFX0RFQ0xBUkFUSU9OX0VORAorCisjZW5kaWYgIC8vIFNUUklOR1NfU1RSSU5HUElFQ0VfSF8KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvc3RyaW5ncGllY2VfdW5pdHRlc3QuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cmluZ3BpZWNlX3VuaXR0ZXN0LmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE1MmQ4MWYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cmluZ3BpZWNlX3VuaXR0ZXN0LmNjCkBAIC0wLDAgKzEsNzk0IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RyaW5ncGllY2UuaD4KKworI2luY2x1ZGUgPGl0ZXJhdG9yPgorI2luY2x1ZGUgPG1hcD4KKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8dXRpbGl0eT4KKyNpbmNsdWRlIDx2ZWN0b3I+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2hhc2guaD4KKyNpbmNsdWRlIDxndGVzdC9ndGVzdC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgeworVEVTVChTdHJpbmdQaWVjZSwgQ3RvcikgeworICB7CisgICAgLy8gTnVsbC4KKyAgICBTdHJpbmdQaWVjZSBzMTA7CisgICAgRVhQRUNUX1RSVUUoczEwLmRhdGEoKSA9PSBOVUxMKTsKKyAgICBFWFBFQ1RfRVEoMCwgczEwLmxlbmd0aCgpKTsKKyAgfQorCisgIHsKKyAgICAvLyBjb25zdCBjaGFyKiB3aXRob3V0IGxlbmd0aC4KKyAgICBjb25zdCBjaGFyKiBoZWxsbyA9ICJoZWxsbyI7CisgICAgU3RyaW5nUGllY2UgczIwKGhlbGxvKTsKKyAgICBFWFBFQ1RfVFJVRShzMjAuZGF0YSgpID09IGhlbGxvKTsKKyAgICBFWFBFQ1RfRVEoNSwgczIwLmxlbmd0aCgpKTsKKworICAgIC8vIGNvbnN0IGNoYXIqIHdpdGggbGVuZ3RoLgorICAgIFN0cmluZ1BpZWNlIHMyMShoZWxsbywgNCk7CisgICAgRVhQRUNUX1RSVUUoczIxLmRhdGEoKSA9PSBoZWxsbyk7CisgICAgRVhQRUNUX0VRKDQsIHMyMS5sZW5ndGgoKSk7CisKKyAgICAvLyBOb3QgcmVjb21tZW5kZWQsIGJ1dCB2YWxpZCBDKysKKyAgICBTdHJpbmdQaWVjZSBzMjIoaGVsbG8sIDYpOworICAgIEVYUEVDVF9UUlVFKHMyMi5kYXRhKCkgPT0gaGVsbG8pOworICAgIEVYUEVDVF9FUSg2LCBzMjIubGVuZ3RoKCkpOworICB9CisKKyAgeworICAgIC8vIHN0ZDo6c3RyaW5nLgorICAgIHN0ZDo6c3RyaW5nIGhvbGEgPSAiaG9sYSI7CisgICAgU3RyaW5nUGllY2UgczMwKGhvbGEpOworICAgIEVYUEVDVF9UUlVFKHMzMC5kYXRhKCkgPT0gaG9sYS5kYXRhKCkpOworICAgIEVYUEVDVF9FUSg0LCBzMzAubGVuZ3RoKCkpOworCisgICAgLy8gc3RkOjpzdHJpbmcgd2l0aCBlbWJlZGRlZCAnXDAnLgorICAgIGhvbGEucHVzaF9iYWNrKCdcMCcpOworICAgIGhvbGEuYXBwZW5kKCJoMiIpOworICAgIGhvbGEucHVzaF9iYWNrKCdcMCcpOworICAgIFN0cmluZ1BpZWNlIHMzMShob2xhKTsKKyAgICBFWFBFQ1RfVFJVRShzMzEuZGF0YSgpID09IGhvbGEuZGF0YSgpKTsKKyAgICBFWFBFQ1RfRVEoOCwgczMxLmxlbmd0aCgpKTsKKyAgfQorCisjaWYgZGVmaW5lZChIQVNfR0xPQkFMX1NUUklORykKKyAgeworICAgIC8vIDo6c3RyaW5nCisgICAgc3RyaW5nIGJvbmpvdXIgPSAiYm9uam91ciI7CisgICAgU3RyaW5nUGllY2UgczQwKGJvbmpvdXIpOworICAgIEVYUEVDVF9UUlVFKHM0MC5kYXRhKCkgPT0gYm9uam91ci5kYXRhKCkpOworICAgIEVYUEVDVF9FUSg3LCBzNDAubGVuZ3RoKCkpOworICB9CisjZW5kaWYKKworICAvLyBUT0RPKG1lYyk6IFN0cmluZ1BpZWNlKFN0cmluZ1BpZWNlIHgsIGludCBwb3MpOworICAvLyBUT0RPKG1lYyk6IFN0cmluZ1BpZWNlKFN0cmluZ1BpZWNlIHgsIGludCBwb3MsIGludCBsZW4pOworICAvLyBUT0RPKG1lYyk6IFN0cmluZ1BpZWNlKGNvbnN0IFN0cmluZ1BpZWNlJik7Cit9CisKK1RFU1QoU3RyaW5nUGllY2UsIFNUTENvbXBhcmF0b3IpIHsKKyAgc3RyaW5nIHMxKCJmb28iKTsKKyAgc3RyaW5nIHMyKCJiYXIiKTsKKyAgc3RyaW5nIHMzKCJiYXoiKTsKKworICBTdHJpbmdQaWVjZSBwMShzMSk7CisgIFN0cmluZ1BpZWNlIHAyKHMyKTsKKyAgU3RyaW5nUGllY2UgcDMoczMpOworCisgIHR5cGVkZWYgc3RkOjptYXA8U3RyaW5nUGllY2UsIGludD4gVGVzdE1hcDsKKyAgVGVzdE1hcCBtYXA7CisKKyAgbWFwLmluc2VydChzdGQ6Om1ha2VfcGFpcihwMSwgMCkpOworICBtYXAuaW5zZXJ0KHN0ZDo6bWFrZV9wYWlyKHAyLCAxKSk7CisgIG1hcC5pbnNlcnQoc3RkOjptYWtlX3BhaXIocDMsIDIpKTsKKyAgRVhQRUNUX0VRKG1hcC5zaXplKCksIDMpOworCisgIFRlc3RNYXA6OmNvbnN0X2l0ZXJhdG9yIGl0ZXIgPSBtYXAuYmVnaW4oKTsKKyAgRVhQRUNUX0VRKGl0ZXItPnNlY29uZCwgMSk7CisgICsraXRlcjsKKyAgRVhQRUNUX0VRKGl0ZXItPnNlY29uZCwgMik7CisgICsraXRlcjsKKyAgRVhQRUNUX0VRKGl0ZXItPnNlY29uZCwgMCk7CisgICsraXRlcjsKKyAgRVhQRUNUX1RSVUUoaXRlciA9PSBtYXAuZW5kKCkpOworCisgIFRlc3RNYXA6Oml0ZXJhdG9yIG5ld19pdGVyID0gbWFwLmZpbmQoInpvdCIpOworICBFWFBFQ1RfVFJVRShuZXdfaXRlciA9PSBtYXAuZW5kKCkpOworCisgIG5ld19pdGVyID0gbWFwLmZpbmQoImJhciIpOworICBFWFBFQ1RfVFJVRShuZXdfaXRlciAhPSBtYXAuZW5kKCkpOworCisgIG1hcC5lcmFzZShuZXdfaXRlcik7CisgIEVYUEVDVF9FUShtYXAuc2l6ZSgpLCAyKTsKKworICBpdGVyID0gbWFwLmJlZ2luKCk7CisgIEVYUEVDVF9FUShpdGVyLT5zZWNvbmQsIDIpOworICArK2l0ZXI7CisgIEVYUEVDVF9FUShpdGVyLT5zZWNvbmQsIDApOworICArK2l0ZXI7CisgIEVYUEVDVF9UUlVFKGl0ZXIgPT0gbWFwLmVuZCgpKTsKK30KKworVEVTVChTdHJpbmdQaWVjZSwgQ29tcGFyaXNvbk9wZXJhdG9ycykgeworI2RlZmluZSBDT01QQVJFKHJlc3VsdCwgb3AsIHgsIHkpIFwKKyAgRVhQRUNUX0VRKHJlc3VsdCwgU3RyaW5nUGllY2UoKHgpKSBvcCBTdHJpbmdQaWVjZSgoeSkpKTsgXAorICBFWFBFQ1RfRVEocmVzdWx0LCBTdHJpbmdQaWVjZSgoeCkpLmNvbXBhcmUoU3RyaW5nUGllY2UoKHkpKSkgb3AgMCkKKworICBDT01QQVJFKHRydWUsID09LCAiIiwgICAiIik7CisgIENPTVBBUkUodHJ1ZSwgPT0sICIiLCBOVUxMKTsKKyAgQ09NUEFSRSh0cnVlLCA9PSwgTlVMTCwgIiIpOworICBDT01QQVJFKHRydWUsID09LCAiYSIsICAiYSIpOworICBDT01QQVJFKHRydWUsID09LCAiYWEiLCAiYWEiKTsKKyAgQ09NUEFSRShmYWxzZSwgPT0sICJhIiwgICIiKTsKKyAgQ09NUEFSRShmYWxzZSwgPT0sICIiLCAgICJhIik7CisgIENPTVBBUkUoZmFsc2UsID09LCAiYSIsICAiYiIpOworICBDT01QQVJFKGZhbHNlLCA9PSwgImEiLCAgImFhIik7CisgIENPTVBBUkUoZmFsc2UsID09LCAiYWEiLCAiYSIpOworCisgIENPTVBBUkUoZmFsc2UsICE9LCAiIiwgICAiIik7CisgIENPTVBBUkUoZmFsc2UsICE9LCAiYSIsICAiYSIpOworICBDT01QQVJFKGZhbHNlLCAhPSwgImFhIiwgImFhIik7CisgIENPTVBBUkUodHJ1ZSwgIT0sICJhIiwgICIiKTsKKyAgQ09NUEFSRSh0cnVlLCAhPSwgIiIsICAgImEiKTsKKyAgQ09NUEFSRSh0cnVlLCAhPSwgImEiLCAgImIiKTsKKyAgQ09NUEFSRSh0cnVlLCAhPSwgImEiLCAgImFhIik7CisgIENPTVBBUkUodHJ1ZSwgIT0sICJhYSIsICJhIik7CisKKyAgQ09NUEFSRSh0cnVlLCA8LCAiYSIsICAiYiIpOworICBDT01QQVJFKHRydWUsIDwsICJhIiwgICJhYSIpOworICBDT01QQVJFKHRydWUsIDwsICJhYSIsICJiIik7CisgIENPTVBBUkUodHJ1ZSwgPCwgImFhIiwgImJiIik7CisgIENPTVBBUkUoZmFsc2UsIDwsICJhIiwgICJhIik7CisgIENPTVBBUkUoZmFsc2UsIDwsICJiIiwgICJhIik7CisgIENPTVBBUkUoZmFsc2UsIDwsICJhYSIsICJhIik7CisgIENPTVBBUkUoZmFsc2UsIDwsICJiIiwgICJhYSIpOworICBDT01QQVJFKGZhbHNlLCA8LCAiYmIiLCAiYWEiKTsKKworICBDT01QQVJFKHRydWUsIDw9LCAiYSIsICAiYSIpOworICBDT01QQVJFKHRydWUsIDw9LCAiYSIsICAiYiIpOworICBDT01QQVJFKHRydWUsIDw9LCAiYSIsICAiYWEiKTsKKyAgQ09NUEFSRSh0cnVlLCA8PSwgImFhIiwgImIiKTsKKyAgQ09NUEFSRSh0cnVlLCA8PSwgImFhIiwgImJiIik7CisgIENPTVBBUkUoZmFsc2UsIDw9LCAiYiIsICAiYSIpOworICBDT01QQVJFKGZhbHNlLCA8PSwgImFhIiwgImEiKTsKKyAgQ09NUEFSRShmYWxzZSwgPD0sICJiIiwgICJhYSIpOworICBDT01QQVJFKGZhbHNlLCA8PSwgImJiIiwgImFhIik7CisKKyAgQ09NUEFSRShmYWxzZSwgPj0sICJhIiwgICJiIik7CisgIENPTVBBUkUoZmFsc2UsID49LCAiYSIsICAiYWEiKTsKKyAgQ09NUEFSRShmYWxzZSwgPj0sICJhYSIsICJiIik7CisgIENPTVBBUkUoZmFsc2UsID49LCAiYWEiLCAiYmIiKTsKKyAgQ09NUEFSRSh0cnVlLCA+PSwgImEiLCAgImEiKTsKKyAgQ09NUEFSRSh0cnVlLCA+PSwgImIiLCAgImEiKTsKKyAgQ09NUEFSRSh0cnVlLCA+PSwgImFhIiwgImEiKTsKKyAgQ09NUEFSRSh0cnVlLCA+PSwgImIiLCAgImFhIik7CisgIENPTVBBUkUodHJ1ZSwgPj0sICJiYiIsICJhYSIpOworCisgIENPTVBBUkUoZmFsc2UsID4sICJhIiwgICJhIik7CisgIENPTVBBUkUoZmFsc2UsID4sICJhIiwgICJiIik7CisgIENPTVBBUkUoZmFsc2UsID4sICJhIiwgICJhYSIpOworICBDT01QQVJFKGZhbHNlLCA+LCAiYWEiLCAiYiIpOworICBDT01QQVJFKGZhbHNlLCA+LCAiYWEiLCAiYmIiKTsKKyAgQ09NUEFSRSh0cnVlLCA+LCAiYiIsICAiYSIpOworICBDT01QQVJFKHRydWUsID4sICJhYSIsICJhIik7CisgIENPTVBBUkUodHJ1ZSwgPiwgImIiLCAgImFhIik7CisgIENPTVBBUkUodHJ1ZSwgPiwgImJiIiwgImFhIik7CisKKyAgc3RyaW5nIHg7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgMjU2OyBpKyspIHsKKyAgICB4ICs9ICdhJzsKKyAgICBzdHJpbmcgeSA9IHg7CisgICAgQ09NUEFSRSh0cnVlLCA9PSwgeCwgeSk7CisgICAgZm9yIChpbnQgaiA9IDA7IGogPCBpOyBqKyspIHsKKyAgICAgIHN0cmluZyB6ID0geDsKKyAgICAgIHpbal0gPSAnYic7ICAgICAgIC8vIERpZmZlcnMgaW4gcG9zaXRpb24gJ2onCisgICAgICBDT01QQVJFKGZhbHNlLCA9PSwgeCwgeik7CisgICAgICBDT01QQVJFKHRydWUsIDwsIHgsIHopOworICAgICAgQ09NUEFSRSh0cnVlLCA+LCB6LCB4KTsKKyAgICAgIGlmIChqICsgMSA8IGkpIHsKKyAgICAgICAgeltqICsgMV0gPSAnQSc7ICAvLyBEaWZmZXJzIGluIHBvc2l0aW9uICdqKzEnIGFzIHdlbGwKKyAgICAgICAgQ09NUEFSRShmYWxzZSwgPT0sIHgsIHopOworICAgICAgICBDT01QQVJFKHRydWUsIDwsIHgsIHopOworICAgICAgICBDT01QQVJFKHRydWUsID4sIHosIHgpOworICAgICAgICB6W2ogKyAxXSA9ICd6JzsgIC8vIERpZmZlcnMgaW4gcG9zaXRpb24gJ2orMScgYXMgd2VsbAorICAgICAgICBDT01QQVJFKGZhbHNlLCA9PSwgeCwgeik7CisgICAgICAgIENPTVBBUkUodHJ1ZSwgPCwgeCwgeik7CisgICAgICAgIENPTVBBUkUodHJ1ZSwgPiwgeiwgeCk7CisgICAgICB9CisgICAgfQorICB9CisKKyN1bmRlZiBDT01QQVJFCit9CisKK1RFU1QoU3RyaW5nUGllY2UsIFNUTDEpIHsKKyAgY29uc3QgU3RyaW5nUGllY2UgYSgiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoiKTsKKyAgY29uc3QgU3RyaW5nUGllY2UgYigiYWJjIik7CisgIGNvbnN0IFN0cmluZ1BpZWNlIGMoInh5eiIpOworICBjb25zdCBTdHJpbmdQaWVjZSBkKCJmb29iYXIiKTsKKyAgY29uc3QgU3RyaW5nUGllY2UgZTsKKyAgc3RyaW5nIHRlbXAoIjEyMyIpOworICB0ZW1wICs9ICdcMCc7CisgIHRlbXAgKz0gIjQ1NiI7CisgIGNvbnN0IFN0cmluZ1BpZWNlIGYodGVtcCk7CisKKyAgRVhQRUNUX0VRKGFbNl0sICdnJyk7CisgIEVYUEVDVF9FUShiWzBdLCAnYScpOworICBFWFBFQ1RfRVEoY1syXSwgJ3onKTsKKyAgRVhQRUNUX0VRKGZbM10sICdcMCcpOworICBFWFBFQ1RfRVEoZls1XSwgJzUnKTsKKworICBFWFBFQ1RfRVEoKmQuZGF0YSgpLCAnZicpOworICBFWFBFQ1RfRVEoZC5kYXRhKClbNV0sICdyJyk7CisgIEVYUEVDVF9UUlVFKGUuZGF0YSgpID09IE5VTEwpOworCisgIEVYUEVDVF9FUSgqYS5iZWdpbigpLCAnYScpOworICBFWFBFQ1RfRVEoKihiLmJlZ2luKCkgKyAyKSwgJ2MnKTsKKyAgRVhQRUNUX0VRKCooYy5lbmQoKSAtIDEpLCAneicpOworCisgIEVYUEVDVF9FUSgqYS5yYmVnaW4oKSwgJ3onKTsKKyAgRVhQRUNUX0VRKCooYi5yYmVnaW4oKSArIDIpLCAnYScpOworICBFWFBFQ1RfRVEoKihjLnJlbmQoKSAtIDEpLCAneCcpOworICBFWFBFQ1RfVFJVRShhLnJiZWdpbigpICsgMjYgPT0gYS5yZW5kKCkpOworCisgIEVYUEVDVF9FUShhLnNpemUoKSwgMjYpOworICBFWFBFQ1RfRVEoYi5zaXplKCksIDMpOworICBFWFBFQ1RfRVEoYy5zaXplKCksIDMpOworICBFWFBFQ1RfRVEoZC5zaXplKCksIDYpOworICBFWFBFQ1RfRVEoZS5zaXplKCksIDApOworICBFWFBFQ1RfRVEoZi5zaXplKCksIDcpOworCisgIEVYUEVDVF9UUlVFKCFkLmVtcHR5KCkpOworICBFWFBFQ1RfVFJVRShkLmJlZ2luKCkgIT0gZC5lbmQoKSk7CisgIEVYUEVDVF9UUlVFKGQuYmVnaW4oKSArIDYgPT0gZC5lbmQoKSk7CisKKyAgRVhQRUNUX1RSVUUoZS5lbXB0eSgpKTsKKyAgRVhQRUNUX1RSVUUoZS5iZWdpbigpID09IGUuZW5kKCkpOworCisgIEVYUEVDVF9HRShhLm1heF9zaXplKCksIGEuY2FwYWNpdHkoKSk7CisgIEVYUEVDVF9HRShhLmNhcGFjaXR5KCksIGEuc2l6ZSgpKTsKKworICBjaGFyIGJ1Zls0XSA9IHsgJyUnLCAnJScsICclJywgJyUnIH07CisgIEVYUEVDVF9FUShhLmNvcHkoYnVmLCA0KSwgNCk7CisgIEVYUEVDVF9FUShidWZbMF0sIGFbMF0pOworICBFWFBFQ1RfRVEoYnVmWzFdLCBhWzFdKTsKKyAgRVhQRUNUX0VRKGJ1ZlsyXSwgYVsyXSk7CisgIEVYUEVDVF9FUShidWZbM10sIGFbM10pOworICBFWFBFQ1RfRVEoYS5jb3B5KGJ1ZiwgMywgNyksIDMpOworICBFWFBFQ1RfRVEoYnVmWzBdLCBhWzddKTsKKyAgRVhQRUNUX0VRKGJ1ZlsxXSwgYVs4XSk7CisgIEVYUEVDVF9FUShidWZbMl0sIGFbOV0pOworICBFWFBFQ1RfRVEoYnVmWzNdLCBhWzNdKTsKKyAgRVhQRUNUX0VRKGMuY29weShidWYsIDk5KSwgMyk7CisgIEVYUEVDVF9FUShidWZbMF0sIGNbMF0pOworICBFWFBFQ1RfRVEoYnVmWzFdLCBjWzFdKTsKKyAgRVhQRUNUX0VRKGJ1ZlsyXSwgY1syXSk7CisgIEVYUEVDVF9FUShidWZbM10sIGFbM10pOworfQorCisvLyBTZXBhcmF0ZWQgZnJvbSBTVEwxKCkgYmVjYXVzZSBzb21lIGNvbXBpbGVycyBwcm9kdWNlIGFuIG92ZXJseQorLy8gbGFyZ2Ugc3RhY2sgZnJhbWUgZm9yIHRoZSBjb21iaW5lZCBmdW5jdGlvbi4KK1RFU1QoU3RyaW5nUGllY2UsIFNUTDIpIHsKKyAgY29uc3QgU3RyaW5nUGllY2UgYSgiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoiKTsKKyAgY29uc3QgU3RyaW5nUGllY2UgYigiYWJjIik7CisgIGNvbnN0IFN0cmluZ1BpZWNlIGMoInh5eiIpOworICBTdHJpbmdQaWVjZSBkKCJmb29iYXIiKTsKKyAgY29uc3QgU3RyaW5nUGllY2UgZTsKKyAgY29uc3QgU3RyaW5nUGllY2UgZigiMTIzIiAiXDAiICI0NTYiLCA3KTsKKworICBkLmNsZWFyKCk7CisgIEVYUEVDVF9FUShkLnNpemUoKSwgMCk7CisgIEVYUEVDVF9UUlVFKGQuZW1wdHkoKSk7CisgIEVYUEVDVF9UUlVFKGQuZGF0YSgpID09IE5VTEwpOworICBFWFBFQ1RfVFJVRShkLmJlZ2luKCkgPT0gZC5lbmQoKSk7CisKKyAgRVhQRUNUX0VRKFN0cmluZ1BpZWNlOjpucG9zLCBzdHJpbmc6Om5wb3MpOworCisgIEVYUEVDVF9FUShhLmZpbmQoYiksIDApOworICBFWFBFQ1RfRVEoYS5maW5kKGIsIDEpLCBTdHJpbmdQaWVjZTo6bnBvcyk7CisgIEVYUEVDVF9FUShhLmZpbmQoYyksIDIzKTsKKyAgRVhQRUNUX0VRKGEuZmluZChjLCA5KSwgMjMpOworICBFWFBFQ1RfRVEoYS5maW5kKGMsIFN0cmluZ1BpZWNlOjpucG9zKSwgU3RyaW5nUGllY2U6Om5wb3MpOworICBFWFBFQ1RfRVEoYi5maW5kKGMpLCBTdHJpbmdQaWVjZTo6bnBvcyk7CisgIEVYUEVDVF9FUShiLmZpbmQoYywgU3RyaW5nUGllY2U6Om5wb3MpLCBTdHJpbmdQaWVjZTo6bnBvcyk7CisgIEVYUEVDVF9FUShhLmZpbmQoZCksIDApOworICBFWFBFQ1RfRVEoYS5maW5kKGUpLCAwKTsKKyAgRVhQRUNUX0VRKGEuZmluZChkLCAxMiksIDEyKTsKKyAgRVhQRUNUX0VRKGEuZmluZChlLCAxNyksIDE3KTsKKyAgU3RyaW5nUGllY2UgZygieHggbm90IGZvdW5kIGJiIik7CisgIEVYUEVDVF9FUShhLmZpbmQoZyksIFN0cmluZ1BpZWNlOjpucG9zKTsKKyAgLy8gZW1wdHkgc3RyaW5nIG5vbnNlbnNlCisgIEVYUEVDVF9FUShkLmZpbmQoYiksIFN0cmluZ1BpZWNlOjpucG9zKTsKKyAgRVhQRUNUX0VRKGUuZmluZChiKSwgU3RyaW5nUGllY2U6Om5wb3MpOworICBFWFBFQ1RfRVEoZC5maW5kKGIsIDQpLCBTdHJpbmdQaWVjZTo6bnBvcyk7CisgIEVYUEVDVF9FUShlLmZpbmQoYiwgNyksIFN0cmluZ1BpZWNlOjpucG9zKTsKKworICBzaXplX3QgZW1wdHlfc2VhcmNoX3BvcyA9IHN0cmluZygpLmZpbmQoc3RyaW5nKCkpOworICBFWFBFQ1RfRVEoZC5maW5kKGQpLCBlbXB0eV9zZWFyY2hfcG9zKTsKKyAgRVhQRUNUX0VRKGQuZmluZChlKSwgZW1wdHlfc2VhcmNoX3Bvcyk7CisgIEVYUEVDVF9FUShlLmZpbmQoZCksIGVtcHR5X3NlYXJjaF9wb3MpOworICBFWFBFQ1RfRVEoZS5maW5kKGUpLCBlbXB0eV9zZWFyY2hfcG9zKTsKKyAgRVhQRUNUX0VRKGQuZmluZChkLCA0KSwgc3RyaW5nKCkuZmluZChzdHJpbmcoKSwgNCkpOworICBFWFBFQ1RfRVEoZC5maW5kKGUsIDQpLCBzdHJpbmcoKS5maW5kKHN0cmluZygpLCA0KSk7CisgIEVYUEVDVF9FUShlLmZpbmQoZCwgNCksIHN0cmluZygpLmZpbmQoc3RyaW5nKCksIDQpKTsKKyAgRVhQRUNUX0VRKGUuZmluZChlLCA0KSwgc3RyaW5nKCkuZmluZChzdHJpbmcoKSwgNCkpOworCisgIEVYUEVDVF9FUShhLmZpbmQoJ2EnKSwgMCk7CisgIEVYUEVDVF9FUShhLmZpbmQoJ2MnKSwgMik7CisgIEVYUEVDVF9FUShhLmZpbmQoJ3onKSwgMjUpOworICBFWFBFQ1RfRVEoYS5maW5kKCckJyksIFN0cmluZ1BpZWNlOjpucG9zKTsKKyAgRVhQRUNUX0VRKGEuZmluZCgnXDAnKSwgU3RyaW5nUGllY2U6Om5wb3MpOworICBFWFBFQ1RfRVEoZi5maW5kKCdcMCcpLCAzKTsKKyAgRVhQRUNUX0VRKGYuZmluZCgnMycpLCAyKTsKKyAgRVhQRUNUX0VRKGYuZmluZCgnNScpLCA1KTsKKyAgRVhQRUNUX0VRKGcuZmluZCgnbycpLCA0KTsKKyAgRVhQRUNUX0VRKGcuZmluZCgnbycsIDQpLCA0KTsKKyAgRVhQRUNUX0VRKGcuZmluZCgnbycsIDUpLCA4KTsKKyAgRVhQRUNUX0VRKGEuZmluZCgnYicsIDUpLCBTdHJpbmdQaWVjZTo6bnBvcyk7CisgIC8vIGVtcHR5IHN0cmluZyBub25zZW5zZQorICBFWFBFQ1RfRVEoZC5maW5kKCdcMCcpLCBTdHJpbmdQaWVjZTo6bnBvcyk7CisgIEVYUEVDVF9FUShlLmZpbmQoJ1wwJyksIFN0cmluZ1BpZWNlOjpucG9zKTsKKyAgRVhQRUNUX0VRKGQuZmluZCgnXDAnLCA0KSwgU3RyaW5nUGllY2U6Om5wb3MpOworICBFWFBFQ1RfRVEoZS5maW5kKCdcMCcsIDcpLCBTdHJpbmdQaWVjZTo6bnBvcyk7CisgIEVYUEVDVF9FUShkLmZpbmQoJ3gnKSwgU3RyaW5nUGllY2U6Om5wb3MpOworICBFWFBFQ1RfRVEoZS5maW5kKCd4JyksIFN0cmluZ1BpZWNlOjpucG9zKTsKKyAgRVhQRUNUX0VRKGQuZmluZCgneCcsIDQpLCBTdHJpbmdQaWVjZTo6bnBvcyk7CisgIEVYUEVDVF9FUShlLmZpbmQoJ3gnLCA3KSwgU3RyaW5nUGllY2U6Om5wb3MpOworCisgIEVYUEVDVF9FUShhLnJmaW5kKGIpLCAwKTsKKyAgRVhQRUNUX0VRKGEucmZpbmQoYiwgMSksIDApOworICBFWFBFQ1RfRVEoYS5yZmluZChjKSwgMjMpOworICBFWFBFQ1RfRVEoYS5yZmluZChjLCAyMiksIFN0cmluZ1BpZWNlOjpucG9zKTsKKyAgRVhQRUNUX0VRKGEucmZpbmQoYywgMSksIFN0cmluZ1BpZWNlOjpucG9zKTsKKyAgRVhQRUNUX0VRKGEucmZpbmQoYywgMCksIFN0cmluZ1BpZWNlOjpucG9zKTsKKyAgRVhQRUNUX0VRKGIucmZpbmQoYyksIFN0cmluZ1BpZWNlOjpucG9zKTsKKyAgRVhQRUNUX0VRKGIucmZpbmQoYywgMCksIFN0cmluZ1BpZWNlOjpucG9zKTsKKyAgRVhQRUNUX0VRKGEucmZpbmQoZCksIGEuYXNfc3RyaW5nKCkucmZpbmQoc3RyaW5nKCkpKTsKKyAgRVhQRUNUX0VRKGEucmZpbmQoZSksIGEuYXNfc3RyaW5nKCkucmZpbmQoc3RyaW5nKCkpKTsKKyAgRVhQRUNUX0VRKGEucmZpbmQoZCwgMTIpLCAxMik7CisgIEVYUEVDVF9FUShhLnJmaW5kKGUsIDE3KSwgMTcpOworICBFWFBFQ1RfRVEoYS5yZmluZChnKSwgU3RyaW5nUGllY2U6Om5wb3MpOworICBFWFBFQ1RfRVEoZC5yZmluZChiKSwgU3RyaW5nUGllY2U6Om5wb3MpOworICBFWFBFQ1RfRVEoZS5yZmluZChiKSwgU3RyaW5nUGllY2U6Om5wb3MpOworICBFWFBFQ1RfRVEoZC5yZmluZChiLCA0KSwgU3RyaW5nUGllY2U6Om5wb3MpOworICBFWFBFQ1RfRVEoZS5yZmluZChiLCA3KSwgU3RyaW5nUGllY2U6Om5wb3MpOworICAvLyBlbXB0eSBzdHJpbmcgbm9uc2Vuc2UKKyAgRVhQRUNUX0VRKGQucmZpbmQoZCwgNCksIHN0cmluZygpLnJmaW5kKHN0cmluZygpKSk7CisgIEVYUEVDVF9FUShlLnJmaW5kKGQsIDcpLCBzdHJpbmcoKS5yZmluZChzdHJpbmcoKSkpOworICBFWFBFQ1RfRVEoZC5yZmluZChlLCA0KSwgc3RyaW5nKCkucmZpbmQoc3RyaW5nKCkpKTsKKyAgRVhQRUNUX0VRKGUucmZpbmQoZSwgNyksIHN0cmluZygpLnJmaW5kKHN0cmluZygpKSk7CisgIEVYUEVDVF9FUShkLnJmaW5kKGQpLCBzdHJpbmcoKS5yZmluZChzdHJpbmcoKSkpOworICBFWFBFQ1RfRVEoZS5yZmluZChkKSwgc3RyaW5nKCkucmZpbmQoc3RyaW5nKCkpKTsKKyAgRVhQRUNUX0VRKGQucmZpbmQoZSksIHN0cmluZygpLnJmaW5kKHN0cmluZygpKSk7CisgIEVYUEVDVF9FUShlLnJmaW5kKGUpLCBzdHJpbmcoKS5yZmluZChzdHJpbmcoKSkpOworCisgIEVYUEVDVF9FUShnLnJmaW5kKCdvJyksIDgpOworICBFWFBFQ1RfRVEoZy5yZmluZCgncScpLCBTdHJpbmdQaWVjZTo6bnBvcyk7CisgIEVYUEVDVF9FUShnLnJmaW5kKCdvJywgOCksIDgpOworICBFWFBFQ1RfRVEoZy5yZmluZCgnbycsIDcpLCA0KTsKKyAgRVhQRUNUX0VRKGcucmZpbmQoJ28nLCAzKSwgU3RyaW5nUGllY2U6Om5wb3MpOworICBFWFBFQ1RfRVEoZi5yZmluZCgnXDAnKSwgMyk7CisgIEVYUEVDVF9FUShmLnJmaW5kKCdcMCcsIDEyKSwgMyk7CisgIEVYUEVDVF9FUShmLnJmaW5kKCczJyksIDIpOworICBFWFBFQ1RfRVEoZi5yZmluZCgnNScpLCA1KTsKKyAgLy8gZW1wdHkgc3RyaW5nIG5vbnNlbnNlCisgIEVYUEVDVF9FUShkLnJmaW5kKCdvJyksIFN0cmluZ1BpZWNlOjpucG9zKTsKKyAgRVhQRUNUX0VRKGUucmZpbmQoJ28nKSwgU3RyaW5nUGllY2U6Om5wb3MpOworICBFWFBFQ1RfRVEoZC5yZmluZCgnbycsIDQpLCBTdHJpbmdQaWVjZTo6bnBvcyk7CisgIEVYUEVDVF9FUShlLnJmaW5kKCdvJywgNyksIFN0cmluZ1BpZWNlOjpucG9zKTsKKworICBFWFBFQ1RfRVEoYS5maW5kX2ZpcnN0X29mKGIpLCAwKTsKKyAgRVhQRUNUX0VRKGEuZmluZF9maXJzdF9vZihiLCAwKSwgMCk7CisgIEVYUEVDVF9FUShhLmZpbmRfZmlyc3Rfb2YoYiwgMSksIDEpOworICBFWFBFQ1RfRVEoYS5maW5kX2ZpcnN0X29mKGIsIDIpLCAyKTsKKyAgRVhQRUNUX0VRKGEuZmluZF9maXJzdF9vZihiLCAzKSwgU3RyaW5nUGllY2U6Om5wb3MpOworICBFWFBFQ1RfRVEoYS5maW5kX2ZpcnN0X29mKGMpLCAyMyk7CisgIEVYUEVDVF9FUShhLmZpbmRfZmlyc3Rfb2YoYywgMjMpLCAyMyk7CisgIEVYUEVDVF9FUShhLmZpbmRfZmlyc3Rfb2YoYywgMjQpLCAyNCk7CisgIEVYUEVDVF9FUShhLmZpbmRfZmlyc3Rfb2YoYywgMjUpLCAyNSk7CisgIEVYUEVDVF9FUShhLmZpbmRfZmlyc3Rfb2YoYywgMjYpLCBTdHJpbmdQaWVjZTo6bnBvcyk7CisgIEVYUEVDVF9FUShnLmZpbmRfZmlyc3Rfb2YoYiksIDEzKTsKKyAgRVhQRUNUX0VRKGcuZmluZF9maXJzdF9vZihjKSwgMCk7CisgIEVYUEVDVF9FUShhLmZpbmRfZmlyc3Rfb2YoZiksIFN0cmluZ1BpZWNlOjpucG9zKTsKKyAgRVhQRUNUX0VRKGYuZmluZF9maXJzdF9vZihhKSwgU3RyaW5nUGllY2U6Om5wb3MpOworICAvLyBlbXB0eSBzdHJpbmcgbm9uc2Vuc2UKKyAgRVhQRUNUX0VRKGEuZmluZF9maXJzdF9vZihkKSwgU3RyaW5nUGllY2U6Om5wb3MpOworICBFWFBFQ1RfRVEoYS5maW5kX2ZpcnN0X29mKGUpLCBTdHJpbmdQaWVjZTo6bnBvcyk7CisgIEVYUEVDVF9FUShkLmZpbmRfZmlyc3Rfb2YoYiksIFN0cmluZ1BpZWNlOjpucG9zKTsKKyAgRVhQRUNUX0VRKGUuZmluZF9maXJzdF9vZihiKSwgU3RyaW5nUGllY2U6Om5wb3MpOworICBFWFBFQ1RfRVEoZC5maW5kX2ZpcnN0X29mKGQpLCBTdHJpbmdQaWVjZTo6bnBvcyk7CisgIEVYUEVDVF9FUShlLmZpbmRfZmlyc3Rfb2YoZCksIFN0cmluZ1BpZWNlOjpucG9zKTsKKyAgRVhQRUNUX0VRKGQuZmluZF9maXJzdF9vZihlKSwgU3RyaW5nUGllY2U6Om5wb3MpOworICBFWFBFQ1RfRVEoZS5maW5kX2ZpcnN0X29mKGUpLCBTdHJpbmdQaWVjZTo6bnBvcyk7CisKKyAgRVhQRUNUX0VRKGEuZmluZF9maXJzdF9ub3Rfb2YoYiksIDMpOworICBFWFBFQ1RfRVEoYS5maW5kX2ZpcnN0X25vdF9vZihjKSwgMCk7CisgIEVYUEVDVF9FUShiLmZpbmRfZmlyc3Rfbm90X29mKGEpLCBTdHJpbmdQaWVjZTo6bnBvcyk7CisgIEVYUEVDVF9FUShjLmZpbmRfZmlyc3Rfbm90X29mKGEpLCBTdHJpbmdQaWVjZTo6bnBvcyk7CisgIEVYUEVDVF9FUShmLmZpbmRfZmlyc3Rfbm90X29mKGEpLCAwKTsKKyAgRVhQRUNUX0VRKGEuZmluZF9maXJzdF9ub3Rfb2YoZiksIDApOworICBFWFBFQ1RfRVEoYS5maW5kX2ZpcnN0X25vdF9vZihkKSwgMCk7CisgIEVYUEVDVF9FUShhLmZpbmRfZmlyc3Rfbm90X29mKGUpLCAwKTsKKyAgLy8gZW1wdHkgc3RyaW5nIG5vbnNlbnNlCisgIEVYUEVDVF9FUShkLmZpbmRfZmlyc3Rfbm90X29mKGEpLCBTdHJpbmdQaWVjZTo6bnBvcyk7CisgIEVYUEVDVF9FUShlLmZpbmRfZmlyc3Rfbm90X29mKGEpLCBTdHJpbmdQaWVjZTo6bnBvcyk7CisgIEVYUEVDVF9FUShkLmZpbmRfZmlyc3Rfbm90X29mKGQpLCBTdHJpbmdQaWVjZTo6bnBvcyk7CisgIEVYUEVDVF9FUShlLmZpbmRfZmlyc3Rfbm90X29mKGQpLCBTdHJpbmdQaWVjZTo6bnBvcyk7CisgIEVYUEVDVF9FUShkLmZpbmRfZmlyc3Rfbm90X29mKGUpLCBTdHJpbmdQaWVjZTo6bnBvcyk7CisgIEVYUEVDVF9FUShlLmZpbmRfZmlyc3Rfbm90X29mKGUpLCBTdHJpbmdQaWVjZTo6bnBvcyk7CisKKyAgU3RyaW5nUGllY2UgaCgiPT09PSIpOworICBFWFBFQ1RfRVEoaC5maW5kX2ZpcnN0X25vdF9vZignPScpLCBTdHJpbmdQaWVjZTo6bnBvcyk7CisgIEVYUEVDVF9FUShoLmZpbmRfZmlyc3Rfbm90X29mKCc9JywgMyksIFN0cmluZ1BpZWNlOjpucG9zKTsKKyAgRVhQRUNUX0VRKGguZmluZF9maXJzdF9ub3Rfb2YoJ1wwJyksIDApOworICBFWFBFQ1RfRVEoZy5maW5kX2ZpcnN0X25vdF9vZigneCcpLCAyKTsKKyAgRVhQRUNUX0VRKGYuZmluZF9maXJzdF9ub3Rfb2YoJ1wwJyksIDApOworICBFWFBFQ1RfRVEoZi5maW5kX2ZpcnN0X25vdF9vZignXDAnLCAzKSwgNCk7CisgIEVYUEVDVF9FUShmLmZpbmRfZmlyc3Rfbm90X29mKCdcMCcsIDIpLCAyKTsKKyAgLy8gZW1wdHkgc3RyaW5nIG5vbnNlbnNlCisgIEVYUEVDVF9FUShkLmZpbmRfZmlyc3Rfbm90X29mKCd4JyksIFN0cmluZ1BpZWNlOjpucG9zKTsKKyAgRVhQRUNUX0VRKGUuZmluZF9maXJzdF9ub3Rfb2YoJ3gnKSwgU3RyaW5nUGllY2U6Om5wb3MpOworICBFWFBFQ1RfRVEoZC5maW5kX2ZpcnN0X25vdF9vZignXDAnKSwgU3RyaW5nUGllY2U6Om5wb3MpOworICBFWFBFQ1RfRVEoZS5maW5kX2ZpcnN0X25vdF9vZignXDAnKSwgU3RyaW5nUGllY2U6Om5wb3MpOworCisgIC8vICBTdHJpbmdQaWVjZSBnKCJ4eCBub3QgZm91bmQgYmIiKTsKKyAgU3RyaW5nUGllY2UgaSgiNTYiKTsKKyAgRVhQRUNUX0VRKGguZmluZF9sYXN0X29mKGEpLCBTdHJpbmdQaWVjZTo6bnBvcyk7CisgIEVYUEVDVF9FUShnLmZpbmRfbGFzdF9vZihhKSwgZy5zaXplKCktMSk7CisgIEVYUEVDVF9FUShhLmZpbmRfbGFzdF9vZihiKSwgMik7CisgIEVYUEVDVF9FUShhLmZpbmRfbGFzdF9vZihjKSwgYS5zaXplKCktMSk7CisgIEVYUEVDVF9FUShmLmZpbmRfbGFzdF9vZihpKSwgNik7CisgIEVYUEVDVF9FUShhLmZpbmRfbGFzdF9vZignYScpLCAwKTsKKyAgRVhQRUNUX0VRKGEuZmluZF9sYXN0X29mKCdiJyksIDEpOworICBFWFBFQ1RfRVEoYS5maW5kX2xhc3Rfb2YoJ3onKSwgMjUpOworICBFWFBFQ1RfRVEoYS5maW5kX2xhc3Rfb2YoJ2EnLCA1KSwgMCk7CisgIEVYUEVDVF9FUShhLmZpbmRfbGFzdF9vZignYicsIDUpLCAxKTsKKyAgRVhQRUNUX0VRKGEuZmluZF9sYXN0X29mKCdiJywgMCksIFN0cmluZ1BpZWNlOjpucG9zKTsKKyAgRVhQRUNUX0VRKGEuZmluZF9sYXN0X29mKCd6JywgMjUpLCAyNSk7CisgIEVYUEVDVF9FUShhLmZpbmRfbGFzdF9vZigneicsIDI0KSwgU3RyaW5nUGllY2U6Om5wb3MpOworICBFWFBFQ1RfRVEoZi5maW5kX2xhc3Rfb2YoaSwgNSksIDUpOworICBFWFBFQ1RfRVEoZi5maW5kX2xhc3Rfb2YoaSwgNiksIDYpOworICBFWFBFQ1RfRVEoZi5maW5kX2xhc3Rfb2YoYSwgNCksIFN0cmluZ1BpZWNlOjpucG9zKTsKKyAgLy8gZW1wdHkgc3RyaW5nIG5vbnNlbnNlCisgIEVYUEVDVF9FUShmLmZpbmRfbGFzdF9vZihkKSwgU3RyaW5nUGllY2U6Om5wb3MpOworICBFWFBFQ1RfRVEoZi5maW5kX2xhc3Rfb2YoZSksIFN0cmluZ1BpZWNlOjpucG9zKTsKKyAgRVhQRUNUX0VRKGYuZmluZF9sYXN0X29mKGQsIDQpLCBTdHJpbmdQaWVjZTo6bnBvcyk7CisgIEVYUEVDVF9FUShmLmZpbmRfbGFzdF9vZihlLCA0KSwgU3RyaW5nUGllY2U6Om5wb3MpOworICBFWFBFQ1RfRVEoZC5maW5kX2xhc3Rfb2YoZCksIFN0cmluZ1BpZWNlOjpucG9zKTsKKyAgRVhQRUNUX0VRKGQuZmluZF9sYXN0X29mKGUpLCBTdHJpbmdQaWVjZTo6bnBvcyk7CisgIEVYUEVDVF9FUShlLmZpbmRfbGFzdF9vZihkKSwgU3RyaW5nUGllY2U6Om5wb3MpOworICBFWFBFQ1RfRVEoZS5maW5kX2xhc3Rfb2YoZSksIFN0cmluZ1BpZWNlOjpucG9zKTsKKyAgRVhQRUNUX0VRKGQuZmluZF9sYXN0X29mKGYpLCBTdHJpbmdQaWVjZTo6bnBvcyk7CisgIEVYUEVDVF9FUShlLmZpbmRfbGFzdF9vZihmKSwgU3RyaW5nUGllY2U6Om5wb3MpOworICBFWFBFQ1RfRVEoZC5maW5kX2xhc3Rfb2YoZCwgNCksIFN0cmluZ1BpZWNlOjpucG9zKTsKKyAgRVhQRUNUX0VRKGQuZmluZF9sYXN0X29mKGUsIDQpLCBTdHJpbmdQaWVjZTo6bnBvcyk7CisgIEVYUEVDVF9FUShlLmZpbmRfbGFzdF9vZihkLCA0KSwgU3RyaW5nUGllY2U6Om5wb3MpOworICBFWFBFQ1RfRVEoZS5maW5kX2xhc3Rfb2YoZSwgNCksIFN0cmluZ1BpZWNlOjpucG9zKTsKKyAgRVhQRUNUX0VRKGQuZmluZF9sYXN0X29mKGYsIDQpLCBTdHJpbmdQaWVjZTo6bnBvcyk7CisgIEVYUEVDVF9FUShlLmZpbmRfbGFzdF9vZihmLCA0KSwgU3RyaW5nUGllY2U6Om5wb3MpOworCisgIEVYUEVDVF9FUShhLmZpbmRfbGFzdF9ub3Rfb2YoYiksIGEuc2l6ZSgpLTEpOworICBFWFBFQ1RfRVEoYS5maW5kX2xhc3Rfbm90X29mKGMpLCAyMik7CisgIEVYUEVDVF9FUShiLmZpbmRfbGFzdF9ub3Rfb2YoYSksIFN0cmluZ1BpZWNlOjpucG9zKTsKKyAgRVhQRUNUX0VRKGIuZmluZF9sYXN0X25vdF9vZihiKSwgU3RyaW5nUGllY2U6Om5wb3MpOworICBFWFBFQ1RfRVEoZi5maW5kX2xhc3Rfbm90X29mKGkpLCA0KTsKKyAgRVhQRUNUX0VRKGEuZmluZF9sYXN0X25vdF9vZihjLCAyNCksIDIyKTsKKyAgRVhQRUNUX0VRKGEuZmluZF9sYXN0X25vdF9vZihiLCAzKSwgMyk7CisgIEVYUEVDVF9FUShhLmZpbmRfbGFzdF9ub3Rfb2YoYiwgMiksIFN0cmluZ1BpZWNlOjpucG9zKTsKKyAgLy8gZW1wdHkgc3RyaW5nIG5vbnNlbnNlCisgIEVYUEVDVF9FUShmLmZpbmRfbGFzdF9ub3Rfb2YoZCksIGYuc2l6ZSgpLTEpOworICBFWFBFQ1RfRVEoZi5maW5kX2xhc3Rfbm90X29mKGUpLCBmLnNpemUoKS0xKTsKKyAgRVhQRUNUX0VRKGYuZmluZF9sYXN0X25vdF9vZihkLCA0KSwgNCk7CisgIEVYUEVDVF9FUShmLmZpbmRfbGFzdF9ub3Rfb2YoZSwgNCksIDQpOworICBFWFBFQ1RfRVEoZC5maW5kX2xhc3Rfbm90X29mKGQpLCBTdHJpbmdQaWVjZTo6bnBvcyk7CisgIEVYUEVDVF9FUShkLmZpbmRfbGFzdF9ub3Rfb2YoZSksIFN0cmluZ1BpZWNlOjpucG9zKTsKKyAgRVhQRUNUX0VRKGUuZmluZF9sYXN0X25vdF9vZihkKSwgU3RyaW5nUGllY2U6Om5wb3MpOworICBFWFBFQ1RfRVEoZS5maW5kX2xhc3Rfbm90X29mKGUpLCBTdHJpbmdQaWVjZTo6bnBvcyk7CisgIEVYUEVDVF9FUShkLmZpbmRfbGFzdF9ub3Rfb2YoZiksIFN0cmluZ1BpZWNlOjpucG9zKTsKKyAgRVhQRUNUX0VRKGUuZmluZF9sYXN0X25vdF9vZihmKSwgU3RyaW5nUGllY2U6Om5wb3MpOworICBFWFBFQ1RfRVEoZC5maW5kX2xhc3Rfbm90X29mKGQsIDQpLCBTdHJpbmdQaWVjZTo6bnBvcyk7CisgIEVYUEVDVF9FUShkLmZpbmRfbGFzdF9ub3Rfb2YoZSwgNCksIFN0cmluZ1BpZWNlOjpucG9zKTsKKyAgRVhQRUNUX0VRKGUuZmluZF9sYXN0X25vdF9vZihkLCA0KSwgU3RyaW5nUGllY2U6Om5wb3MpOworICBFWFBFQ1RfRVEoZS5maW5kX2xhc3Rfbm90X29mKGUsIDQpLCBTdHJpbmdQaWVjZTo6bnBvcyk7CisgIEVYUEVDVF9FUShkLmZpbmRfbGFzdF9ub3Rfb2YoZiwgNCksIFN0cmluZ1BpZWNlOjpucG9zKTsKKyAgRVhQRUNUX0VRKGUuZmluZF9sYXN0X25vdF9vZihmLCA0KSwgU3RyaW5nUGllY2U6Om5wb3MpOworCisgIEVYUEVDVF9FUShoLmZpbmRfbGFzdF9ub3Rfb2YoJ3gnKSwgaC5zaXplKCkgLSAxKTsKKyAgRVhQRUNUX0VRKGguZmluZF9sYXN0X25vdF9vZignPScpLCBTdHJpbmdQaWVjZTo6bnBvcyk7CisgIEVYUEVDVF9FUShiLmZpbmRfbGFzdF9ub3Rfb2YoJ2MnKSwgMSk7CisgIEVYUEVDVF9FUShoLmZpbmRfbGFzdF9ub3Rfb2YoJ3gnLCAyKSwgMik7CisgIEVYUEVDVF9FUShoLmZpbmRfbGFzdF9ub3Rfb2YoJz0nLCAyKSwgU3RyaW5nUGllY2U6Om5wb3MpOworICBFWFBFQ1RfRVEoYi5maW5kX2xhc3Rfbm90X29mKCdiJywgMSksIDApOworICAvLyBlbXB0eSBzdHJpbmcgbm9uc2Vuc2UKKyAgRVhQRUNUX0VRKGQuZmluZF9sYXN0X25vdF9vZigneCcpLCBTdHJpbmdQaWVjZTo6bnBvcyk7CisgIEVYUEVDVF9FUShlLmZpbmRfbGFzdF9ub3Rfb2YoJ3gnKSwgU3RyaW5nUGllY2U6Om5wb3MpOworICBFWFBFQ1RfRVEoZC5maW5kX2xhc3Rfbm90X29mKCdcMCcpLCBTdHJpbmdQaWVjZTo6bnBvcyk7CisgIEVYUEVDVF9FUShlLmZpbmRfbGFzdF9ub3Rfb2YoJ1wwJyksIFN0cmluZ1BpZWNlOjpucG9zKTsKKworICBFWFBFQ1RfRVEoYS5zdWJzdHIoMCwgMyksIGIpOworICBFWFBFQ1RfRVEoYS5zdWJzdHIoMjMpLCBjKTsKKyAgRVhQRUNUX0VRKGEuc3Vic3RyKDIzLCAzKSwgYyk7CisgIEVYUEVDVF9FUShhLnN1YnN0cigyMywgOTkpLCBjKTsKKyAgRVhQRUNUX0VRKGEuc3Vic3RyKDApLCBhKTsKKyAgRVhQRUNUX0VRKGEuc3Vic3RyKDMsIDIpLCAiZGUiKTsKKyAgLy8gZW1wdHkgc3RyaW5nIG5vbnNlbnNlCisgIEVYUEVDVF9FUShhLnN1YnN0cig5OSwgMiksIGUpOworICBFWFBFQ1RfRVEoZC5zdWJzdHIoOTkpLCBlKTsKKyAgRVhQRUNUX0VRKGQuc3Vic3RyKDAsIDk5KSwgZSk7CisgIEVYUEVDVF9FUShkLnN1YnN0cig5OSwgOTkpLCBlKTsKKyAgLy8gdXNlIG9mIG5wb3MKKyAgRVhQRUNUX0VRKGEuc3Vic3RyKDAsIFN0cmluZ1BpZWNlOjpucG9zKSwgYSk7CisgIEVYUEVDVF9FUShhLnN1YnN0cigyMywgU3RyaW5nUGllY2U6Om5wb3MpLCBjKTsKKyAgRVhQRUNUX0VRKGEuc3Vic3RyKFN0cmluZ1BpZWNlOjpucG9zLCAwKSwgZSk7CisgIEVYUEVDVF9FUShhLnN1YnN0cihTdHJpbmdQaWVjZTo6bnBvcywgMSksIGUpOworICBFWFBFQ1RfRVEoYS5zdWJzdHIoU3RyaW5nUGllY2U6Om5wb3MsIFN0cmluZ1BpZWNlOjpucG9zKSwgZSk7CisKKyAgLy8gU3Vic3RyaW5nIGNvbnN0cnVjdG9ycy4KKyAgRVhQRUNUX0VRKFN0cmluZ1BpZWNlKGEsIDAsIDMpLCBiKTsKKyAgRVhQRUNUX0VRKFN0cmluZ1BpZWNlKGEsIDIzKSwgYyk7CisgIEVYUEVDVF9FUShTdHJpbmdQaWVjZShhLCAyMywgMyksIGMpOworICBFWFBFQ1RfRVEoU3RyaW5nUGllY2UoYSwgMjMsIDk5KSwgYyk7CisgIEVYUEVDVF9FUShTdHJpbmdQaWVjZShhLCAwKSwgYSk7CisgIEVYUEVDVF9FUShTdHJpbmdQaWVjZShhLCAzLCAyKSwgImRlIik7CisgIC8vIGVtcHR5IHN0cmluZyBub25zZW5zZQorICBFWFBFQ1RfRVEoU3RyaW5nUGllY2UoZCwgMCwgOTkpLCBlKTsKKyAgLy8gVmVyaWZ5IHRoYXQgdGhleSB3b3JrIHRha2luZyBhbiBhY3R1YWwgc3RyaW5nLCBub3QganVzdCBhIFN0cmluZ1BpZWNlLgorICBzdHJpbmcgYTIgPSBhLmFzX3N0cmluZygpOworICBFWFBFQ1RfRVEoU3RyaW5nUGllY2UoYTIsIDAsIDMpLCBiKTsKKyAgRVhQRUNUX0VRKFN0cmluZ1BpZWNlKGEyLCAyMyksIGMpOworICBFWFBFQ1RfRVEoU3RyaW5nUGllY2UoYTIsIDIzLCAzKSwgYyk7CisgIEVYUEVDVF9FUShTdHJpbmdQaWVjZShhMiwgMjMsIDk5KSwgYyk7CisgIEVYUEVDVF9FUShTdHJpbmdQaWVjZShhMiwgMCksIGEpOworICBFWFBFQ1RfRVEoU3RyaW5nUGllY2UoYTIsIDMsIDIpLCAiZGUiKTsKK30KKworVEVTVChTdHJpbmdQaWVjZSwgQ3VzdG9tKSB7CisgIFN0cmluZ1BpZWNlIGEoImZvb2JhciIpOworICBzdHJpbmcgczEoIjEyMyIpOworICBzMSArPSAnXDAnOworICBzMSArPSAiNDU2IjsKKyAgU3RyaW5nUGllY2UgYihzMSk7CisgIFN0cmluZ1BpZWNlIGU7CisgIHN0cmluZyBzMjsKKworICAvLyBDb3B5VG9TdHJpbmcKKyAgYS5Db3B5VG9TdHJpbmcoJnMyKTsKKyAgRVhQRUNUX0VRKHMyLnNpemUoKSwgNik7CisgIEVYUEVDVF9FUShzMiwgImZvb2JhciIpOworICBiLkNvcHlUb1N0cmluZygmczIpOworICBFWFBFQ1RfRVEoczIuc2l6ZSgpLCA3KTsKKyAgRVhQRUNUX0VRKHMxLCBzMik7CisgIGUuQ29weVRvU3RyaW5nKCZzMik7CisgIEVYUEVDVF9UUlVFKHMyLmVtcHR5KCkpOworCisgIC8vIEFwcGVuZFRvU3RyaW5nCisgIHMyLmVyYXNlKCk7CisgIGEuQXBwZW5kVG9TdHJpbmcoJnMyKTsKKyAgRVhQRUNUX0VRKHMyLnNpemUoKSwgNik7CisgIEVYUEVDVF9FUShzMiwgImZvb2JhciIpOworICBhLkFwcGVuZFRvU3RyaW5nKCZzMik7CisgIEVYUEVDVF9FUShzMi5zaXplKCksIDEyKTsKKyAgRVhQRUNUX0VRKHMyLCAiZm9vYmFyZm9vYmFyIik7CisKKyAgLy8gc3RhcnRzX3dpdGgKKyAgRVhQRUNUX1RSVUUoYS5zdGFydHNfd2l0aChhKSk7CisgIEVYUEVDVF9UUlVFKGEuc3RhcnRzX3dpdGgoImZvbyIpKTsKKyAgRVhQRUNUX1RSVUUoYS5zdGFydHNfd2l0aChlKSk7CisgIEVYUEVDVF9UUlVFKGIuc3RhcnRzX3dpdGgoczEpKTsKKyAgRVhQRUNUX1RSVUUoYi5zdGFydHNfd2l0aChiKSk7CisgIEVYUEVDVF9UUlVFKGIuc3RhcnRzX3dpdGgoZSkpOworICBFWFBFQ1RfVFJVRShlLnN0YXJ0c193aXRoKCIiKSk7CisgIEVYUEVDVF9UUlVFKCFhLnN0YXJ0c193aXRoKGIpKTsKKyAgRVhQRUNUX1RSVUUoIWIuc3RhcnRzX3dpdGgoYSkpOworICBFWFBFQ1RfVFJVRSghZS5zdGFydHNfd2l0aChhKSk7CisKKyAgLy8gZW5kcyB3aXRoCisgIEVYUEVDVF9UUlVFKGEuZW5kc193aXRoKGEpKTsKKyAgRVhQRUNUX1RSVUUoYS5lbmRzX3dpdGgoImJhciIpKTsKKyAgRVhQRUNUX1RSVUUoYS5lbmRzX3dpdGgoZSkpOworICBFWFBFQ1RfVFJVRShiLmVuZHNfd2l0aChzMSkpOworICBFWFBFQ1RfVFJVRShiLmVuZHNfd2l0aChiKSk7CisgIEVYUEVDVF9UUlVFKGIuZW5kc193aXRoKGUpKTsKKyAgRVhQRUNUX1RSVUUoZS5lbmRzX3dpdGgoIiIpKTsKKyAgRVhQRUNUX1RSVUUoIWEuZW5kc193aXRoKGIpKTsKKyAgRVhQRUNUX1RSVUUoIWIuZW5kc193aXRoKGEpKTsKKyAgRVhQRUNUX1RSVUUoIWUuZW5kc193aXRoKGEpKTsKKworICAvLyByZW1vdmVfcHJlZml4CisgIFN0cmluZ1BpZWNlIGMoYSk7CisgIGMucmVtb3ZlX3ByZWZpeCgzKTsKKyAgRVhQRUNUX0VRKGMsICJiYXIiKTsKKyAgYyA9IGE7CisgIGMucmVtb3ZlX3ByZWZpeCgwKTsKKyAgRVhQRUNUX0VRKGMsIGEpOworICBjLnJlbW92ZV9wcmVmaXgoYy5zaXplKCkpOworICBFWFBFQ1RfRVEoYywgZSk7CisKKyAgLy8gcmVtb3ZlX3N1ZmZpeAorICBjID0gYTsKKyAgYy5yZW1vdmVfc3VmZml4KDMpOworICBFWFBFQ1RfRVEoYywgImZvbyIpOworICBjID0gYTsKKyAgYy5yZW1vdmVfc3VmZml4KDApOworICBFWFBFQ1RfRVEoYywgYSk7CisgIGMucmVtb3ZlX3N1ZmZpeChjLnNpemUoKSk7CisgIEVYUEVDVF9FUShjLCBlKTsKKworICAvLyBzZXQKKyAgYy5zZXQoImZvb2JhciIsIDYpOworICBFWFBFQ1RfRVEoYywgYSk7CisgIGMuc2V0KCJmb29iYXIiLCAwKTsKKyAgRVhQRUNUX0VRKGMsIGUpOworICBjLnNldCgiZm9vYmFyIiwgNyk7CisgIEVYUEVDVF9ORShjLCBhKTsKKworICBjLnNldCgiZm9vYmFyIik7CisgIEVYUEVDVF9FUShjLCBhKTsKKworICBjLnNldChzdGF0aWNfY2FzdDxjb25zdCB2b2lkKj4oImZvb2JhciIpLCA2KTsKKyAgRVhQRUNUX0VRKGMsIGEpOworICBjLnNldChzdGF0aWNfY2FzdDxjb25zdCB2b2lkKj4oImZvb2JhciIpLCAwKTsKKyAgRVhQRUNUX0VRKGMsIGUpOworICBjLnNldChzdGF0aWNfY2FzdDxjb25zdCB2b2lkKj4oImZvb2JhciIpLCA3KTsKKyAgRVhQRUNUX05FKGMsIGEpOworCisgIC8vIGFzX3N0cmluZworICBzdHJpbmcgczMoYS5hc19zdHJpbmcoKS5jX3N0cigpLCA3KTsKKyAgRVhQRUNUX0VRKGMsIHMzKTsKKyAgc3RyaW5nIHM0KGUuYXNfc3RyaW5nKCkpOworICBFWFBFQ1RfVFJVRShzNC5lbXB0eSgpKTsKKworICAvLyBUb1N0cmluZworICB7CisgICAgc3RyaW5nIHM1KGEuVG9TdHJpbmcoKS5jX3N0cigpLCA3KTsKKyAgICBFWFBFQ1RfRVEoYywgczUpOworICAgIHN0cmluZyBzNihlLlRvU3RyaW5nKCkpOworICAgIEVYUEVDVF9UUlVFKHM2LmVtcHR5KCkpOworICB9CisKKyAgLy8gQ29uc3VtZQorICBhLnNldCgiZm9vYmFyIik7CisgIEVYUEVDVF9UUlVFKGEuQ29uc3VtZSgiZm9vIikpOworICBFWFBFQ1RfRVEoYSwgImJhciIpOworICBFWFBFQ1RfRkFMU0UoYS5Db25zdW1lKCJmb28iKSk7CisgIEVYUEVDVF9GQUxTRShhLkNvbnN1bWUoImJhcmJhciIpKTsKKyAgRVhQRUNUX0ZBTFNFKGEuQ29uc3VtZSgiYXIiKSk7CisgIEVYUEVDVF9FUShhLCAiYmFyIik7CisKKyAgYS5zZXQoImZvb2JhciIpOworICBFWFBFQ1RfVFJVRShhLkNvbnN1bWVGcm9tRW5kKCJiYXIiKSk7CisgIEVYUEVDVF9FUShhLCAiZm9vIik7CisgIEVYUEVDVF9GQUxTRShhLkNvbnN1bWVGcm9tRW5kKCJiYXIiKSk7CisgIEVYUEVDVF9GQUxTRShhLkNvbnN1bWVGcm9tRW5kKCJmb29mb28iKSk7CisgIEVYUEVDVF9GQUxTRShhLkNvbnN1bWVGcm9tRW5kKCJmbyIpKTsKKyAgRVhQRUNUX0VRKGEsICJmb28iKTsKK30KKworVEVTVChTdHJpbmdQaWVjZSwgQ29udGFpbnMpIHsKKyAgU3RyaW5nUGllY2UgYSgiYWJjZGVmZyIpOworICBTdHJpbmdQaWVjZSBiKCJhYmNkIik7CisgIFN0cmluZ1BpZWNlIGMoImVmZyIpOworICBTdHJpbmdQaWVjZSBkKCJnaCIpOworICBFWFBFQ1RfVFJVRShhLmNvbnRhaW5zKGIpKTsKKyAgRVhQRUNUX1RSVUUoYS5jb250YWlucyhjKSk7CisgIEVYUEVDVF9UUlVFKCFhLmNvbnRhaW5zKGQpKTsKK30KKworVEVTVChTdHJpbmdQaWVjZSwgTlVMTElucHV0KSB7CisgIC8vIHdlIHVzZWQgdG8gY3Jhc2ggaGVyZSwgYnV0IG5vdyB3ZSBkb24ndC4KKyAgU3RyaW5nUGllY2UgcyhOVUxMKTsKKyAgRVhQRUNUX0VRKHMuZGF0YSgpLCAoY29uc3QgY2hhciopTlVMTCk7CisgIEVYUEVDVF9FUShzLnNpemUoKSwgMCk7CisKKyAgcy5zZXQoTlVMTCk7CisgIEVYUEVDVF9FUShzLmRhdGEoKSwgKGNvbnN0IGNoYXIqKU5VTEwpOworICBFWFBFQ1RfRVEocy5zaXplKCksIDApOworCisgIC8vIC5Ub1N0cmluZygpIG9uIGEgU3RyaW5nUGllY2Ugd2l0aCBOVUxMIHNob3VsZCBwcm9kdWNlIHRoZSBlbXB0eSBzdHJpbmcuCisgIEVYUEVDVF9FUSgiIiwgcy5Ub1N0cmluZygpKTsKKyAgRVhQRUNUX0VRKCIiLCBzLmFzX3N0cmluZygpKTsKK30KKworVEVTVChTdHJpbmdQaWVjZSwgQ29tcGFyaXNvbnMyKSB7CisgIFN0cmluZ1BpZWNlIGFiYygiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoiKTsKKworICAvLyBjaGVjayBjb21wYXJpc29uIG9wZXJhdGlvbnMgb24gc3RyaW5ncyBsb25nZXIgdGhhbiA0IGJ5dGVzLgorICBFWFBFQ1RfRVEoYWJjLCBTdHJpbmdQaWVjZSgiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoiKSk7CisgIEVYUEVDVF9FUShhYmMuY29tcGFyZShTdHJpbmdQaWVjZSgiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoiKSksIDApOworCisgIEVYUEVDVF9MVChhYmMsIFN0cmluZ1BpZWNlKCJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h6eiIpKTsKKyAgRVhQRUNUX0xUKGFiYy5jb21wYXJlKFN0cmluZ1BpZWNlKCJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h6eiIpKSwgMCk7CisKKyAgRVhQRUNUX0dUKGFiYywgU3RyaW5nUGllY2UoImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl5IikpOworICBFWFBFQ1RfR1QoYWJjLmNvbXBhcmUoU3RyaW5nUGllY2UoImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl5IikpLCAwKTsKKworICAvLyBzdGFydHNfd2l0aAorICBFWFBFQ1RfVFJVRShhYmMuc3RhcnRzX3dpdGgoYWJjKSk7CisgIEVYUEVDVF9UUlVFKGFiYy5zdGFydHNfd2l0aCgiYWJjZGVmZ2hpamtsbSIpKTsKKyAgRVhQRUNUX1RSVUUoIWFiYy5zdGFydHNfd2l0aCgiYWJjZGVmZ3V2d3h5eiIpKTsKKworICAvLyBlbmRzX3dpdGgKKyAgRVhQRUNUX1RSVUUoYWJjLmVuZHNfd2l0aChhYmMpKTsKKyAgRVhQRUNUX1RSVUUoIWFiYy5lbmRzX3dpdGgoImFiY2RlZmd1dnd4eXoiKSk7CisgIEVYUEVDVF9UUlVFKGFiYy5lbmRzX3dpdGgoIm5vcHFyc3R1dnd4eXoiKSk7Cit9CisKK1RFU1QoQ29tcGFyaXNvbk9wc1Rlc3QsIFN0cmluZ0NvbXBhcmVOb3RBbWJpZ3VvdXMpIHsKKyAgRVhQRUNUX0VRKCJoZWxsbyIsIHN0cmluZygiaGVsbG8iKSk7CisgIEVYUEVDVF9MVCgiaGVsbG8iLCBzdHJpbmcoIndvcmxkIikpOworfQorCitURVNUKENvbXBhcmlzb25PcHNUZXN0LCBIZXRlcm9nZW5vdXNTdHJpbmdQaWVjZUVxdWFscykgeworICBFWFBFQ1RfRVEoU3RyaW5nUGllY2UoImhlbGxvIiksIHN0cmluZygiaGVsbG8iKSk7CisgIEVYUEVDVF9FUSgiaGVsbG8iLCBTdHJpbmdQaWVjZSgiaGVsbG8iKSk7Cit9CisKK1RFU1QoRmluZE9uZUNoYXJUZXN0LCBFZGdlQ2FzZXMpIHsKKyAgU3RyaW5nUGllY2UgYSgieHh5eXl4eCIpOworCisgIC8vIFNldCBhID0gInh5eXl4Ii4KKyAgYS5yZW1vdmVfcHJlZml4KDEpOworICBhLnJlbW92ZV9zdWZmaXgoMSk7CisKKyAgRVhQRUNUX0VRKDAsIGEuZmluZCgneCcpKTsKKyAgRVhQRUNUX0VRKDAsIGEuZmluZCgneCcsIDApKTsKKyAgRVhQRUNUX0VRKDQsIGEuZmluZCgneCcsIDEpKTsKKyAgRVhQRUNUX0VRKDQsIGEuZmluZCgneCcsIDQpKTsKKyAgRVhQRUNUX0VRKFN0cmluZ1BpZWNlOjpucG9zLCBhLmZpbmQoJ3gnLCA1KSk7CisKKyAgRVhQRUNUX0VRKDQsIGEucmZpbmQoJ3gnKSk7CisgIEVYUEVDVF9FUSg0LCBhLnJmaW5kKCd4JywgNSkpOworICBFWFBFQ1RfRVEoNCwgYS5yZmluZCgneCcsIDQpKTsKKyAgRVhQRUNUX0VRKDAsIGEucmZpbmQoJ3gnLCAzKSk7CisgIEVYUEVDVF9FUSgwLCBhLnJmaW5kKCd4JywgMCkpOworCisgIC8vIFNldCBhID0gInl5eSIuCisgIGEucmVtb3ZlX3ByZWZpeCgxKTsKKyAgYS5yZW1vdmVfc3VmZml4KDEpOworCisgIEVYUEVDVF9FUShTdHJpbmdQaWVjZTo6bnBvcywgYS5maW5kKCd4JykpOworICBFWFBFQ1RfRVEoU3RyaW5nUGllY2U6Om5wb3MsIGEucmZpbmQoJ3gnKSk7Cit9CisKKyNpZm5kZWYgTkRFQlVHCitURVNUKE5vbk5lZ2F0aXZlTGVuVGVzdCwgTm9uTmVnYXRpdmVMZW4pIHsKKyAgRVhQRUNUX0RFQVRIKFN0cmluZ1BpZWNlKCJ4eXoiLCAtMSksICJsZW4gPj0gMCIpOworfQorI2VuZGlmICAvLyBuZGVmIERFQlVHCisKK30gIC8vIG5hbWVzcGFjZQorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cmluZ3ByaW50Zi5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvc3RyaW5ncHJpbnRmLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMyNzJkOGUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cmluZ3ByaW50Zi5jYwpAQCAtMCwwICsxLDE3NSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAxMiBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIGZyb20gZ29vZ2xlMy9iYXNlL3N0cmluZ3ByaW50Zi5jYworCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cmluZ3ByaW50Zi5oPgorCisjaW5jbHVkZSA8ZXJybm8uaD4KKyNpbmNsdWRlIDxzdGRhcmcuaD4gLy8gRm9yIHZhX2xpc3QgYW5kIHJlbGF0ZWQgb3BlcmF0aW9ucworI2luY2x1ZGUgPHN0ZGlvLmg+IC8vIE1TVkMgcmVxdWlyZXMgdGhpcyBmb3IgX3ZzbnByaW50ZgorI2luY2x1ZGUgPHZlY3Rvcj4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZ29vZ2xldGVzdC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKKyNpZmRlZiBfTVNDX1ZFUgorZW51bSB7IElTX0NPTVBJTEVSX01TVkMgPSAxIH07CisjaWZuZGVmIHZhX2NvcHkKKy8vIERlZmluZSB2YV9jb3B5IGZvciBNU1ZDLiBUaGlzIGlzIGEgaGFjaywgYXNzdW1pbmcgdmFfbGlzdCBpcyBzaW1wbHkgYQorLy8gcG9pbnRlciBpbnRvIHRoZSBzdGFjayBhbmQgaXMgc2FmZSB0byBjb3B5LgorI2RlZmluZSB2YV9jb3B5KGRlc3QsIHNyYykgKChkZXN0KSA9IChzcmMpKQorI2VuZGlmCisjZWxzZQorZW51bSB7IElTX0NPTVBJTEVSX01TVkMgPSAwIH07CisjZW5kaWYKKwordm9pZCBTdHJpbmdBcHBlbmRWKHN0cmluZyogZHN0LCBjb25zdCBjaGFyKiBmb3JtYXQsIHZhX2xpc3QgYXApIHsKKyAgLy8gRmlyc3QgdHJ5IHdpdGggYSBzbWFsbCBmaXhlZCBzaXplIGJ1ZmZlcgorICBzdGF0aWMgY29uc3QgaW50IGtTcGFjZUxlbmd0aCA9IDEwMjQ7CisgIGNoYXIgc3BhY2Vba1NwYWNlTGVuZ3RoXTsKKworICAvLyBJdCdzIHBvc3NpYmxlIGZvciBtZXRob2RzIHRoYXQgdXNlIGEgdmFfbGlzdCB0byBpbnZhbGlkYXRlCisgIC8vIHRoZSBkYXRhIGluIGl0IHVwb24gdXNlLiAgVGhlIGZpeCBpcyB0byBtYWtlIGEgY29weQorICAvLyBvZiB0aGUgc3RydWN0dXJlIGJlZm9yZSB1c2luZyBpdCBhbmQgdXNlIHRoYXQgY29weSBpbnN0ZWFkLgorICB2YV9saXN0IGJhY2t1cF9hcDsKKyAgdmFfY29weShiYWNrdXBfYXAsIGFwKTsKKyAgaW50IHJlc3VsdCA9IHZzbnByaW50ZihzcGFjZSwga1NwYWNlTGVuZ3RoLCBmb3JtYXQsIGJhY2t1cF9hcCk7CisgIHZhX2VuZChiYWNrdXBfYXApOworCisgIGlmIChyZXN1bHQgPCBrU3BhY2VMZW5ndGgpIHsKKyAgICBpZiAocmVzdWx0ID49IDApIHsKKyAgICAgIC8vIE5vcm1hbCBjYXNlIC0tIGV2ZXJ5dGhpbmcgZml0LgorICAgICAgZHN0LT5hcHBlbmQoc3BhY2UsIHJlc3VsdCk7CisgICAgICByZXR1cm47CisgICAgfQorCisgICAgaWYgKElTX0NPTVBJTEVSX01TVkMpIHsKKyAgICAgIC8vIEVycm9yIG9yIE1TVkMgcnVubmluZyBvdXQgb2Ygc3BhY2UuICBNU1ZDIDguMCBhbmQgaGlnaGVyCisgICAgICAvLyBjYW4gYmUgYXNrZWQgYWJvdXQgc3BhY2UgbmVlZGVkIHdpdGggdGhlIHNwZWNpYWwgaWRpb20gYmVsb3c6CisgICAgICB2YV9jb3B5KGJhY2t1cF9hcCwgYXApOworICAgICAgcmVzdWx0ID0gdnNucHJpbnRmKE5VTEwsIDAsIGZvcm1hdCwgYmFja3VwX2FwKTsKKyAgICAgIHZhX2VuZChiYWNrdXBfYXApOworICAgIH0KKworICAgIGlmIChyZXN1bHQgPCAwKSB7CisgICAgICAvLyBKdXN0IGFuIGVycm9yLgorICAgICAgcmV0dXJuOworICAgIH0KKyAgfQorCisgIC8vIEluY3JlYXNlIHRoZSBidWZmZXIgc2l6ZSB0byB0aGUgc2l6ZSByZXF1ZXN0ZWQgYnkgdnNucHJpbnRmLAorICAvLyBwbHVzIG9uZSBmb3IgdGhlIGNsb3NpbmcgXDAuCisgIGludCBsZW5ndGggPSByZXN1bHQrMTsKKyAgY2hhciogYnVmID0gbmV3IGNoYXJbbGVuZ3RoXTsKKworICAvLyBSZXN0b3JlIHRoZSB2YV9saXN0IGJlZm9yZSB3ZSB1c2UgaXQgYWdhaW4KKyAgdmFfY29weShiYWNrdXBfYXAsIGFwKTsKKyAgcmVzdWx0ID0gdnNucHJpbnRmKGJ1ZiwgbGVuZ3RoLCBmb3JtYXQsIGJhY2t1cF9hcCk7CisgIHZhX2VuZChiYWNrdXBfYXApOworCisgIGlmIChyZXN1bHQgPj0gMCAmJiByZXN1bHQgPCBsZW5ndGgpIHsKKyAgICAvLyBJdCBmaXQKKyAgICBkc3QtPmFwcGVuZChidWYsIHJlc3VsdCk7CisgIH0KKyAgZGVsZXRlW10gYnVmOworfQorCisKK3N0cmluZyBTdHJpbmdQcmludGYoY29uc3QgY2hhciogZm9ybWF0LCAuLi4pIHsKKyAgdmFfbGlzdCBhcDsKKyAgdmFfc3RhcnQoYXAsIGZvcm1hdCk7CisgIHN0cmluZyByZXN1bHQ7CisgIFN0cmluZ0FwcGVuZFYoJnJlc3VsdCwgZm9ybWF0LCBhcCk7CisgIHZhX2VuZChhcCk7CisgIHJldHVybiByZXN1bHQ7Cit9CisKK2NvbnN0IHN0cmluZyYgU1N0cmluZ1ByaW50ZihzdHJpbmcqIGRzdCwgY29uc3QgY2hhciogZm9ybWF0LCAuLi4pIHsKKyAgdmFfbGlzdCBhcDsKKyAgdmFfc3RhcnQoYXAsIGZvcm1hdCk7CisgIGRzdC0+Y2xlYXIoKTsKKyAgU3RyaW5nQXBwZW5kVihkc3QsIGZvcm1hdCwgYXApOworICB2YV9lbmQoYXApOworICByZXR1cm4gKmRzdDsKK30KKwordm9pZCBTdHJpbmdBcHBlbmRGKHN0cmluZyogZHN0LCBjb25zdCBjaGFyKiBmb3JtYXQsIC4uLikgeworICB2YV9saXN0IGFwOworICB2YV9zdGFydChhcCwgZm9ybWF0KTsKKyAgU3RyaW5nQXBwZW5kVihkc3QsIGZvcm1hdCwgYXApOworICB2YV9lbmQoYXApOworfQorCisvLyBNYXggYXJndW1lbnRzIHN1cHBvcnRlZCBieSBTdHJpbmdQcmludFZlY3RvcgorY29uc3QgaW50IGtTdHJpbmdQcmludGZWZWN0b3JNYXhBcmdzID0gMzI7CisKKy8vIEFuIGVtcHR5IGJsb2NrIG9mIHplcm8gZm9yIGZpbGxlciBhcmd1bWVudHMuICBUaGlzIGlzIGNvbnN0IHNvIHRoYXQgaWYKKy8vIHByaW50ZiB0cmllcyB0byB3cml0ZSB0byBpdCAodmlhICVuKSB0aGVuIHRoZSBwcm9ncmFtIGdldHMgYSBTSUdTRUdWCisvLyBhbmQgd2UgY2FuIGZpeCB0aGUgcHJvYmxlbSBvciBwcm90ZWN0IGFnYWluc3QgYW4gYXR0YWNrLgorc3RhdGljIGNvbnN0IGNoYXIgc3RyaW5nX3ByaW50Zl9lbXB0eV9ibG9ja1syNTZdID0geyAnXDAnIH07CisKK3N0cmluZyBTdHJpbmdQcmludGZWZWN0b3IoY29uc3QgY2hhciogZm9ybWF0LCBjb25zdCB2ZWN0b3I8c3RyaW5nPiYgdikgeworICBHT09HTEVfQ0hFQ0tfTEUodi5zaXplKCksIGtTdHJpbmdQcmludGZWZWN0b3JNYXhBcmdzKQorICAgICAgPDwgIlN0cmluZ1ByaW50ZlZlY3RvciBjdXJyZW50bHkgb25seSBzdXBwb3J0cyB1cCB0byAiCisgICAgICA8PCBrU3RyaW5nUHJpbnRmVmVjdG9yTWF4QXJncyA8PCAiIGFyZ3VtZW50cy4gIgorICAgICAgPDwgIkZlZWwgZnJlZSB0byBhZGQgc3VwcG9ydCBmb3IgbW9yZSBpZiB5b3UgbmVlZCBpdC4iOworCisgIC8vIEFkZCBmaWxsZXIgYXJndW1lbnRzIHNvIHRoYXQgYm9ndXMgZm9ybWF0K2FyZ3MgaGF2ZSBhIGhhcmRlciB0aW1lCisgIC8vIGNyYXNoaW5nIHRoZSBwcm9ncmFtLCBjb3JydXB0aW5nIHRoZSBwcm9ncmFtICglbiksCisgIC8vIG9yIGRpc3BsYXlpbmcgcmFuZG9tIGNodW5rcyBvZiBtZW1vcnkgdG8gdXNlcnMuCisKKyAgY29uc3QgY2hhciogY3N0cltrU3RyaW5nUHJpbnRmVmVjdG9yTWF4QXJnc107CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdi5zaXplKCk7ICsraSkgeworICAgIGNzdHJbaV0gPSB2W2ldLmNfc3RyKCk7CisgIH0KKyAgZm9yIChpbnQgaSA9IHYuc2l6ZSgpOyBpIDwgR09PR0xFX0FSUkFZU0laRShjc3RyKTsgKytpKSB7CisgICAgY3N0cltpXSA9ICZzdHJpbmdfcHJpbnRmX2VtcHR5X2Jsb2NrWzBdOworICB9CisKKyAgLy8gSSBkbyBub3Qga25vdyBhbnkgd2F5IHRvIHBhc3Mga1N0cmluZ1ByaW50ZlZlY3Rvck1heEFyZ3MgYXJndW1lbnRzLAorICAvLyBvciBhbnkgd2F5IHRvIGJ1aWxkIGEgdmFfbGlzdCBieSBoYW5kLCBvciBhbnkgQVBJIGZvciBwcmludGYKKyAgLy8gdGhhdCBhY2NlcHRzIGFuIGFycmF5IG9mIGFyZ3VtZW50cy4gIFRoZSBiZXN0IEkgY2FuIGRvIGlzIHN0aWNrCisgIC8vIHRoaXMgQ09NUElMRV9BU1NFUlQgcmlnaHQgbmV4dCB0byB0aGUgYWN0dWFsIHN0YXRlbWVudC4KKworICBHT09HTEVfQ09NUElMRV9BU1NFUlQoa1N0cmluZ1ByaW50ZlZlY3Rvck1heEFyZ3MgPT0gMzIsIGFyZ19jb3VudF9taXNtYXRjaCk7CisgIHJldHVybiBTdHJpbmdQcmludGYoZm9ybWF0LAorICAgICAgICAgICAgICAgICAgICAgIGNzdHJbMF0sIGNzdHJbMV0sIGNzdHJbMl0sIGNzdHJbM10sIGNzdHJbNF0sCisgICAgICAgICAgICAgICAgICAgICAgY3N0cls1XSwgY3N0cls2XSwgY3N0cls3XSwgY3N0cls4XSwgY3N0cls5XSwKKyAgICAgICAgICAgICAgICAgICAgICBjc3RyWzEwXSwgY3N0clsxMV0sIGNzdHJbMTJdLCBjc3RyWzEzXSwgY3N0clsxNF0sCisgICAgICAgICAgICAgICAgICAgICAgY3N0clsxNV0sIGNzdHJbMTZdLCBjc3RyWzE3XSwgY3N0clsxOF0sIGNzdHJbMTldLAorICAgICAgICAgICAgICAgICAgICAgIGNzdHJbMjBdLCBjc3RyWzIxXSwgY3N0clsyMl0sIGNzdHJbMjNdLCBjc3RyWzI0XSwKKyAgICAgICAgICAgICAgICAgICAgICBjc3RyWzI1XSwgY3N0clsyNl0sIGNzdHJbMjddLCBjc3RyWzI4XSwgY3N0clsyOV0sCisgICAgICAgICAgICAgICAgICAgICAgY3N0clszMF0sIGNzdHJbMzFdKTsKK30KK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJpbmdwcmludGYuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvc3RyaW5ncHJpbnRmLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWIxYWI1NQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvc3RyaW5ncHJpbnRmLmgKQEAgLTAsMCArMSw3NiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAxMiBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIGZyb20gZ29vZ2xlMy9iYXNlL3N0cmluZ3ByaW50Zi5oCisvLworLy8gUHJpbnRmIHZhcmlhbnRzIHRoYXQgcGxhY2UgdGhlaXIgb3V0cHV0IGluIGEgQysrIHN0cmluZy4KKy8vCisvLyBVc2FnZToKKy8vICAgICAgc3RyaW5nIHJlc3VsdCA9IFN0cmluZ1ByaW50ZigiJWQgJXNcbiIsIDEwLCAiaGVsbG8iKTsKKy8vICAgICAgU1N0cmluZ1ByaW50ZigmcmVzdWx0LCAiJWQgJXNcbiIsIDEwLCAiaGVsbG8iKTsKKy8vICAgICAgU3RyaW5nQXBwZW5kRigmcmVzdWx0LCAiJWQgJXNcbiIsIDIwLCAidGhlcmUiKTsKKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfU1RVQlNfU1RSSU5HUFJJTlRGX0gKKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1NUVUJTX1NUUklOR1BSSU5URl9ICisKKyNpbmNsdWRlIDxzdGRhcmcuaD4KKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8dmVjdG9yPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKKy8vIFJldHVybiBhIEMrKyBzdHJpbmcKK0xJQlBST1RPQlVGX0VYUE9SVCBleHRlcm4gc3RyaW5nIFN0cmluZ1ByaW50Zihjb25zdCBjaGFyKiBmb3JtYXQsIC4uLik7CisKKy8vIFN0b3JlIHJlc3VsdCBpbnRvIGEgc3VwcGxpZWQgc3RyaW5nIGFuZCByZXR1cm4gaXQKK0xJQlBST1RPQlVGX0VYUE9SVCBleHRlcm4gY29uc3Qgc3RyaW5nJiBTU3RyaW5nUHJpbnRmKHN0cmluZyogZHN0LCBjb25zdCBjaGFyKiBmb3JtYXQsIC4uLik7CisKKy8vIEFwcGVuZCByZXN1bHQgdG8gYSBzdXBwbGllZCBzdHJpbmcKK0xJQlBST1RPQlVGX0VYUE9SVCBleHRlcm4gdm9pZCBTdHJpbmdBcHBlbmRGKHN0cmluZyogZHN0LCBjb25zdCBjaGFyKiBmb3JtYXQsIC4uLik7CisKKy8vIExvd2VyLWxldmVsIHJvdXRpbmUgdGhhdCB0YWtlcyBhIHZhX2xpc3QgYW5kIGFwcGVuZHMgdG8gYSBzcGVjaWZpZWQKKy8vIHN0cmluZy4gIEFsbCBvdGhlciByb3V0aW5lcyBhcmUganVzdCBjb252ZW5pZW5jZSB3cmFwcGVycyBhcm91bmQgaXQuCitMSUJQUk9UT0JVRl9FWFBPUlQgZXh0ZXJuIHZvaWQgU3RyaW5nQXBwZW5kVihzdHJpbmcqIGRzdCwgY29uc3QgY2hhciogZm9ybWF0LCB2YV9saXN0IGFwKTsKKworLy8gVGhlIG1heCBhcmd1bWVudHMgc3VwcG9ydGVkIGJ5IFN0cmluZ1ByaW50ZlZlY3RvcgorTElCUFJPVE9CVUZfRVhQT1JUIGV4dGVybiBjb25zdCBpbnQga1N0cmluZ1ByaW50ZlZlY3Rvck1heEFyZ3M7CisKKy8vIFlvdSBjYW4gdXNlIHRoaXMgdmVyc2lvbiB3aGVuIGFsbCB5b3VyIGFyZ3VtZW50cyBhcmUgc3RyaW5ncywgYnV0CisvLyB5b3UgZG9uJ3Qga25vdyBob3cgbWFueSBhcmd1bWVudHMgeW91J2xsIGhhdmUgYXQgY29tcGlsZSB0aW1lLgorLy8gU3RyaW5nUHJpbnRmVmVjdG9yIHdpbGwgTE9HKEZBVEFMKSBpZiB2LnNpemUoKSA+IGtTdHJpbmdQcmludGZWZWN0b3JNYXhBcmdzCitMSUJQUk9UT0JVRl9FWFBPUlQgZXh0ZXJuIHN0cmluZyBTdHJpbmdQcmludGZWZWN0b3IoY29uc3QgY2hhciogZm9ybWF0LCBjb25zdCB2ZWN0b3I8c3RyaW5nPiYgdik7CisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9TVFVCU19TVFJJTkdQUklOVEZfSApkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJpbmdwcmludGZfdW5pdHRlc3QuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cmluZ3ByaW50Zl91bml0dGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNTg5NWU1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJpbmdwcmludGZfdW5pdHRlc3QuY2MKQEAgLTAsMCArMSwxNTIgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMTIgR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBmcm9tIGdvb2dsZTMvYmFzZS9zdHJpbmdwcmludGZfdW5pdHRlc3QuY2MKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJpbmdwcmludGYuaD4KKworI2luY2x1ZGUgPGNlcnJubz4KKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0Lmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIHsKKworVEVTVChTdHJpbmdQcmludGZUZXN0LCBFbXB0eSkgeworI2lmIDAKKyAgLy8gZ2NjIDIuOTUuMywgZ2NjIDQuMS4wLCBhbmQgZ2NjIDQuMi4yIGFsbCB3YXJuIGFib3V0IHRoaXM6CisgIC8vIHdhcm5pbmc6IHplcm8tbGVuZ3RoIHByaW50ZiBmb3JtYXQgc3RyaW5nLgorICAvLyBzbyB3ZSBkbyBub3QgYWxsb3cgdGhlbSBpbiBnb29nbGUzLgorICBFWFBFQ1RfRVEoIiIsIFN0cmluZ1ByaW50ZigiIikpOworI2VuZGlmCisgIEVYUEVDVF9FUSgiIiwgU3RyaW5nUHJpbnRmKCIlcyIsIHN0cmluZygpLmNfc3RyKCkpKTsKKyAgRVhQRUNUX0VRKCIiLCBTdHJpbmdQcmludGYoIiVzIiwgIiIpKTsKK30KKworVEVTVChTdHJpbmdQcmludGZUZXN0LCBNaXNjKSB7CisvLyBNU1ZDIGFuZCBtaW5ndyBkb2VzIG5vdCBzdXBwb3J0ICQgZm9ybWF0IHNwZWNpZmllci4KKyNpZiAhZGVmaW5lZChfTVNDX1ZFUikgJiYgIWRlZmluZWQoX19NSU5HVzMyX18pCisgIEVYUEVDVF9FUSgiMTIzaGVsbG8gdyIsIFN0cmluZ1ByaW50ZigiJTMkZCUyJHMgJTEkYyIsICd3JywgImhlbGxvIiwgMTIzKSk7CisjZW5kaWYgIC8vICFfTVNDX1ZFUgorfQorCitURVNUKFN0cmluZ0FwcGVuZEZUZXN0LCBFbXB0eSkgeworICBzdHJpbmcgdmFsdWUoIkhlbGxvIik7CisgIGNvbnN0IGNoYXIqIGVtcHR5ID0gIiI7CisgIFN0cmluZ0FwcGVuZEYoJnZhbHVlLCAiJXMiLCBlbXB0eSk7CisgIEVYUEVDVF9FUSgiSGVsbG8iLCB2YWx1ZSk7Cit9CisKK1RFU1QoU3RyaW5nQXBwZW5kRlRlc3QsIEVtcHR5U3RyaW5nKSB7CisgIHN0cmluZyB2YWx1ZSgiSGVsbG8iKTsKKyAgU3RyaW5nQXBwZW5kRigmdmFsdWUsICIlcyIsICIiKTsKKyAgRVhQRUNUX0VRKCJIZWxsbyIsIHZhbHVlKTsKK30KKworVEVTVChTdHJpbmdBcHBlbmRGVGVzdCwgU3RyaW5nKSB7CisgIHN0cmluZyB2YWx1ZSgiSGVsbG8iKTsKKyAgU3RyaW5nQXBwZW5kRigmdmFsdWUsICIgJXMiLCAiV29ybGQiKTsKKyAgRVhQRUNUX0VRKCJIZWxsbyBXb3JsZCIsIHZhbHVlKTsKK30KKworVEVTVChTdHJpbmdBcHBlbmRGVGVzdCwgSW50KSB7CisgIHN0cmluZyB2YWx1ZSgiSGVsbG8iKTsKKyAgU3RyaW5nQXBwZW5kRigmdmFsdWUsICIgJWQiLCAxMjMpOworICBFWFBFQ1RfRVEoIkhlbGxvIDEyMyIsIHZhbHVlKTsKK30KKworVEVTVChTdHJpbmdQcmludGZUZXN0LCBNdWx0aWJ5dGUpIHsKKyAgLy8gSWYgd2UgYXJlIGluIG11bHRpYnl0ZSBtb2RlIGFuZCBmZWVkIGludmFsaWQgbXVsdGlieXRlIHNlcXVlbmNlLAorICAvLyBTdHJpbmdQcmludGYgc2hvdWxkIHJldHVybiBhbiBlbXB0eSBzdHJpbmcgaW5zdGVhZCBvZiBydW5uaW5nCisgIC8vIG91dCBvZiBtZW1vcnkgd2hpbGUgdHJ5aW5nIHRvIGRldGVybWluZSBkZXN0aW5hdGlvbiBidWZmZXIgc2l6ZS4KKyAgLy8gc2VlIGIvNDE5NDU0My4KKworICBjaGFyKiBvbGRfbG9jYWxlID0gc2V0bG9jYWxlKExDX0NUWVBFLCBOVUxMKTsKKyAgLy8gUHVzaCBsb2NhbGUgd2l0aCBtdWx0aWJ5dGUgbW9kZQorICBzZXRsb2NhbGUoTENfQ1RZUEUsICJlbl9VUy51dGY4Iik7CisKKyAgY29uc3QgY2hhciBrSW52YWxpZENvZGVQb2ludFtdID0gIlwzNzVcMDY3cyI7CisgIHN0cmluZyB2YWx1ZSA9IFN0cmluZ1ByaW50ZigiJS4qcyIsIDMsIGtJbnZhbGlkQ29kZVBvaW50KTsKKworICAvLyBJbiBzb21lIHZlcnNpb25zIG9mIGdsaWJjIChlLmcuIGVnbGliYy0yLjExLjEsIGFrYSBHUlRFdjIpLCBzbnByaW50ZgorICAvLyByZXR1cm5zIGVycm9yIGdpdmVuIGFuIGludmFsaWQgY29kZXBvaW50LiBPdGhlciB2ZXJzaW9ucworICAvLyAoZS5nLiBlZ2xpYmMtMi4xNSwgYWthIHByZS1HUlRFdjMpIGVtaXQgdGhlIGNvZGVwb2ludCB2ZXJiYXRpbS4KKyAgLy8gV2UgdGVzdCB0aGF0IHRoZSBvdXRwdXQgaXMgb25lIG9mIHRoZSBhYm92ZS4KKyAgRVhQRUNUX1RSVUUodmFsdWUuZW1wdHkoKSB8fCB2YWx1ZSA9PSBrSW52YWxpZENvZGVQb2ludCk7CisKKyAgLy8gUmVwZWF0IHdpdGggbG9uZ2VyIHN0cmluZywgdG8gbWFrZSBzdXJlIHRoYXQgdGhlIGR5bmFtaWNhbGx5CisgIC8vIGFsbG9jYXRlZCBwYXRoIGluIFN0cmluZ0FwcGVuZFYgaXMgaGFuZGxlZCBjb3JyZWN0bHkuCisgIGludCBuID0gMjA0ODsKKyAgY2hhciogYnVmID0gbmV3IGNoYXJbbisxXTsKKyAgbWVtc2V0KGJ1ZiwgJyAnLCBuLTMpOworICBtZW1jcHkoYnVmICsgbiAtIDMsIGtJbnZhbGlkQ29kZVBvaW50LCA0KTsKKyAgdmFsdWUgPSAgU3RyaW5nUHJpbnRmKCIlLipzIiwgbiwgYnVmKTsKKyAgLy8gU2VlIEdSVEV2MiB2cy4gR1JURXYzIGNvbW1lbnQgYWJvdmUuCisgIEVYUEVDVF9UUlVFKHZhbHVlLmVtcHR5KCkgfHwgdmFsdWUgPT0gYnVmKTsKKyAgZGVsZXRlW10gYnVmOworCisgIHNldGxvY2FsZShMQ19DVFlQRSwgb2xkX2xvY2FsZSk7Cit9CisKK1RFU1QoU3RyaW5nUHJpbnRmVGVzdCwgTm9NdWx0aWJ5dGUpIHsKKyAgLy8gTm8gbXVsdGlieXRlIGhhbmRsaW5nLCBidXQgdGhlIHN0cmluZyBjb250YWlucyBmdW5ueSBjaGFycy4KKyAgY2hhciogb2xkX2xvY2FsZSA9IHNldGxvY2FsZShMQ19DVFlQRSwgTlVMTCk7CisgIHNldGxvY2FsZShMQ19DVFlQRSwgIlBPU0lYIik7CisgIHN0cmluZyB2YWx1ZSA9IFN0cmluZ1ByaW50ZigiJS4qcyIsIDMsICJcMzc1XDA2N3MiKTsKKyAgc2V0bG9jYWxlKExDX0NUWVBFLCBvbGRfbG9jYWxlKTsKKyAgRVhQRUNUX0VRKCJcMzc1XDA2N3MiLCB2YWx1ZSk7Cit9CisKK1RFU1QoU3RyaW5nUHJpbnRmVGVzdCwgRG9udE92ZXJ3cml0ZUVycm5vKSB7CisgIC8vIENoZWNrIHRoYXQgZXJybm8gaXNuJ3Qgb3ZlcndyaXR0ZW4gdW5sZXNzIHdlJ3JlIHByaW50aW5nCisgIC8vIHNvbWV0aGluZyBzaWduaWZpY2FudGx5IGxhcmdlciB0aGFuIHdoYXQgcGVvcGxlIGFyZSBub3JtYWxseQorICAvLyBwcmludGluZyBpbiB0aGVpciBiYWRseSB3cml0dGVuIFBMT0coKSBzdGF0ZW1lbnRzLgorICBlcnJubyA9IEVDSElMRDsKKyAgc3RyaW5nIHZhbHVlID0gU3RyaW5nUHJpbnRmKCJIZWxsbywgJXMhIiwgIldvcmxkIik7CisgIEVYUEVDVF9FUShFQ0hJTEQsIGVycm5vKTsKK30KKworVEVTVChTdHJpbmdQcmludGZUZXN0LCBMYXJnZUJ1ZikgeworICAvLyBDaGVjayB0aGF0IHRoZSBsYXJnZSBidWZmZXIgaXMgaGFuZGxlZCBjb3JyZWN0bHkuCisgIGludCBuID0gMjA0ODsKKyAgY2hhciogYnVmID0gbmV3IGNoYXJbbisxXTsKKyAgbWVtc2V0KGJ1ZiwgJyAnLCBuKTsKKyAgYnVmW25dID0gMDsKKyAgc3RyaW5nIHZhbHVlID0gU3RyaW5nUHJpbnRmKCIlcyIsIGJ1Zik7CisgIEVYUEVDVF9FUShidWYsIHZhbHVlKTsKKyAgZGVsZXRlW10gYnVmOworfQorCit9ICAvLyBhbm9ueW1vdXMgbmFtZXNwYWNlCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydWN0dXJhbGx5X3ZhbGlkLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1Y3R1cmFsbHlfdmFsaWQuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDc5YTZlZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydWN0dXJhbGx5X3ZhbGlkLmNjCkBAIC0wLDAgKzEsNTg4IEBACisvLyBDb3B5cmlnaHQgMjAwNS0yMDA4IEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCisvLyBBdXRob3I6IGpybUBnb29nbGUuY29tIChKaW0gTWVlaGFuKQorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cmluZ3BpZWNlLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKKy8vIFRoZXNlIGZvdXItYnl0ZSBlbnRyaWVzIGNvbXBhY3RseSBlbmNvZGUgaG93IG1hbnkgYnl0ZXMgMC4uMjU1IHRvIGRlbGV0ZQorLy8gaW4gbWFraW5nIGEgc3RyaW5nIHJlcGxhY2VtZW50LCBob3cgbWFueSBieXRlcyB0byBhZGQgMC4uMjU1LCBhbmQgdGhlIG9mZnNldAorLy8gMC4uNjRrLTEgb2YgdGhlIHJlcGxhY2VtZW50IHN0cmluZyBpbiByZW1hcF9zdHJpbmcuCitzdHJ1Y3QgUmVtYXBFbnRyeSB7CisgIHVpbnQ4IGRlbGV0ZV9ieXRlczsKKyAgdWludDggYWRkX2J5dGVzOworICB1aW50MTYgYnl0ZXNfb2Zmc2V0OworfTsKKworLy8gRXhpdCB0eXBlIGNvZGVzIGZvciBzdGF0ZSB0YWJsZXMuIEFsbCBidXQgdGhlIGZpcnN0IGdldCBzdHVmZmVkIGludG8KKy8vIHNpZ25lZCBvbmUtYnl0ZSBlbnRyaWVzLiBUaGUgZmlyc3QgaXMgb25seSBnZW5lcmF0ZWQgYnkgZXhlY3V0YWJsZSBjb2RlLgorLy8gVG8gZGlzdGluZ3Vpc2ggZnJvbSBuZXh0LXN0YXRlIGVudHJpZXMsIHRoZXNlIG11c3QgYmUgY29udGlndW91cyBhbmQKKy8vIGFsbCA8PSBrRXhpdE5vbmUKK3R5cGVkZWYgZW51bSB7CisgIGtFeGl0RHN0U3BhY2VGdWxsID0gMjM5LAorICBrRXhpdElsbGVnYWxTdHJ1Y3R1cmUsICAvLyAyNDAKKyAga0V4aXRPSywgICAgICAgICAgICAgICAgLy8gMjQxCisgIGtFeGl0UmVqZWN0LCAgICAgICAgICAgIC8vIC4uLgorICBrRXhpdFJlcGxhY2UxLAorICBrRXhpdFJlcGxhY2UyLAorICBrRXhpdFJlcGxhY2UzLAorICBrRXhpdFJlcGxhY2UyMSwKKyAga0V4aXRSZXBsYWNlMzEsCisgIGtFeGl0UmVwbGFjZTMyLAorICBrRXhpdFJlcGxhY2VPZmZzZXQxLAorICBrRXhpdFJlcGxhY2VPZmZzZXQyLAorICBrRXhpdFJlcGxhY2UxUzAsCisgIGtFeGl0U3BlY2lhbCwKKyAga0V4aXREb0FnYWluLAorICBrRXhpdFJlamVjdEFsdCwKKyAga0V4aXROb25lICAgICAgICAgICAgICAgLy8gMjU1Cit9IEV4aXRSZWFzb247CisKKworLy8gVGhpcyBzdHJ1Y3QgcmVwcmVzZW50cyBvbmUgZW50aXJlIHN0YXRlIHRhYmxlLiBUaGUgdGhyZWUgaW5pdGlhbGl6ZWQgYnl0ZQorLy8gYXJlYXMgYXJlIHN0YXRlX3RhYmxlLCByZW1hcF9iYXNlLCBhbmQgcmVtYXBfc3RyaW5nLiBzdGF0ZTAgYW5kIHN0YXRlMF9zaXplCisvLyBnaXZlIHRoZSBieXRlIG9mZnNldCBhbmQgbGVuZ3RoIHdpdGhpbiBzdGF0ZV90YWJsZSBvZiB0aGUgaW5pdGlhbCBzdGF0ZSAtLQorLy8gdGFibGUgbG9va3VwcyBhcmUgZXhwZWN0ZWQgdG8gc3RhcnQgYW5kIGVuZCBpbiB0aGlzIHN0YXRlLCBidXQgZm9yCisvLyB0cnVuY2F0ZWQgVVRGLTggc3RyaW5ncywgbWF5IGVuZCBpbiBhIGRpZmZlcmVudCBzdGF0ZS4gVGhlc2UgYWxsb3cgYSBxdWljaworLy8gdGVzdCBmb3IgdGhhdCBjb25kaXRpb24uIGVudHJ5X3NoaWZ0IGlzIDggZm9yIHRhYmxlcyBzdWJzY3JpcHRlZCBieSBhIGZ1bGwKKy8vIGJ5dGUgdmFsdWUgYW5kIDYgZm9yIHNwYWNlLW9wdGltaXplZCB0YWJsZXMgc3Vic2NyaXB0ZWQgYnkgb25seSBzaXgKKy8vIHNpZ25pZmljYW50IGJpdHMgaW4gVVRGLTggY29udGludWF0aW9uIGJ5dGVzLgordHlwZWRlZiBzdHJ1Y3QgeworICBjb25zdCB1aW50MzIgc3RhdGUwOworICBjb25zdCB1aW50MzIgc3RhdGUwX3NpemU7CisgIGNvbnN0IHVpbnQzMiB0b3RhbF9zaXplOworICBjb25zdCBpbnQgbWF4X2V4cGFuZDsKKyAgY29uc3QgaW50IGVudHJ5X3NoaWZ0OworICBjb25zdCBpbnQgYnl0ZXNfcGVyX2VudHJ5OworICBjb25zdCB1aW50MzIgbG9zdWI7CisgIGNvbnN0IHVpbnQzMiBoaWFkZDsKKyAgY29uc3QgdWludDgqIHN0YXRlX3RhYmxlOworICBjb25zdCBSZW1hcEVudHJ5KiByZW1hcF9iYXNlOworICBjb25zdCB1aW50OCogcmVtYXBfc3RyaW5nOworICBjb25zdCB1aW50OCogZmFzdF9zdGF0ZTsKK30gVVRGOFN0YXRlTWFjaGluZU9iajsKKwordHlwZWRlZiBVVEY4U3RhdGVNYWNoaW5lT2JqIFVURjhTY2FuT2JqOworCisjZGVmaW5lIFhfXyAoa0V4aXRJbGxlZ2FsU3RydWN0dXJlKQorI2RlZmluZSBSSl8gKGtFeGl0UmVqZWN0KQorI2RlZmluZSBTMV8gKGtFeGl0UmVwbGFjZTEpCisjZGVmaW5lIFMyXyAoa0V4aXRSZXBsYWNlMikKKyNkZWZpbmUgUzNfIChrRXhpdFJlcGxhY2UzKQorI2RlZmluZSBTMjEgKGtFeGl0UmVwbGFjZTIxKQorI2RlZmluZSBTMzEgKGtFeGl0UmVwbGFjZTMxKQorI2RlZmluZSBTMzIgKGtFeGl0UmVwbGFjZTMyKQorI2RlZmluZSBUMV8gKGtFeGl0UmVwbGFjZU9mZnNldDEpCisjZGVmaW5lIFQyXyAoa0V4aXRSZXBsYWNlT2Zmc2V0MikKKyNkZWZpbmUgUzExIChrRXhpdFJlcGxhY2UxUzApCisjZGVmaW5lIFNQXyAoa0V4aXRTcGVjaWFsKQorI2RlZmluZSBEX18gKGtFeGl0RG9BZ2FpbikKKyNkZWZpbmUgUkpBIChrRXhpdFJlamVjdEFsdCkKKworLy8gIEVudGlyZSB0YWJsZSBoYXMgOSBzdGF0ZSBibG9ja3Mgb2YgMjU2IGVudHJpZXMgZWFjaAorc3RhdGljIGNvbnN0IHVuc2lnbmVkIGludCB1dGY4YWNjZXB0bm9uc3Vycm9nYXRlc19TVEFURTAgPSAwOyAgICAgLy8gc3RhdGVbMF0KK3N0YXRpYyBjb25zdCB1bnNpZ25lZCBpbnQgdXRmOGFjY2VwdG5vbnN1cnJvZ2F0ZXNfU1RBVEUwX1NJWkUgPSAyNTY7ICAvLyA9WzFdCitzdGF0aWMgY29uc3QgdW5zaWduZWQgaW50IHV0ZjhhY2NlcHRub25zdXJyb2dhdGVzX1RPVEFMX1NJWkUgPSAyMzA0Oworc3RhdGljIGNvbnN0IHVuc2lnbmVkIGludCB1dGY4YWNjZXB0bm9uc3Vycm9nYXRlc19NQVhfRVhQQU5EX1g0ID0gMDsKK3N0YXRpYyBjb25zdCB1bnNpZ25lZCBpbnQgdXRmOGFjY2VwdG5vbnN1cnJvZ2F0ZXNfU0hJRlQgPSA4Oworc3RhdGljIGNvbnN0IHVuc2lnbmVkIGludCB1dGY4YWNjZXB0bm9uc3Vycm9nYXRlc19CWVRFUyA9IDE7CitzdGF0aWMgY29uc3QgdW5zaWduZWQgaW50IHV0ZjhhY2NlcHRub25zdXJyb2dhdGVzX0xPU1VCID0gMHgyMDIwMjAyMDsKK3N0YXRpYyBjb25zdCB1bnNpZ25lZCBpbnQgdXRmOGFjY2VwdG5vbnN1cnJvZ2F0ZXNfSElBREQgPSAweDAwMDAwMDAwOworCitzdGF0aWMgY29uc3QgdWludDggdXRmOGFjY2VwdG5vbnN1cnJvZ2F0ZXNbXSA9IHsKKy8vIHN0YXRlWzBdIDB4MDAwMDAwIEJ5dGUgMQorICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwKKyAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsCisgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLAorICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwKKworICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwKKyAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsCisgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLAorICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwKKworWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKKworWF9fLCBYX18sICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwKKyAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsCisgIDIsICAgMywgICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgMywgICAgMywgICAzLCAgIDMsICAgMywgICAzLCAgIDcsICAgMywgICAzLAorICA0LCAgIDUsICAgNSwgICA1LCAgIDYsIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKKworLy8gc3RhdGVbMV0gMHgwMDAwODAgQnl0ZSAyIG9mIDIKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCisKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCisKKyAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsCisgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLAorICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwKKyAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsICAgMCwgICAwLCAgIDAsCisKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCisKKy8vIHN0YXRlWzJdIDB4MDAwMDAwIEJ5dGUgMiBvZiAzCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKKyAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsCisgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAxLAorCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorCisvLyBzdGF0ZVszXSAweDAwMTAwMCBCeXRlIDIgb2YgMworWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKKworWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKKworICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwKKyAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsCisgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAxLAorICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwKKworWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKKworLy8gc3RhdGVbNF0gMHgwMDAwMDAgQnl0ZSAyIG9mIDQKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCisKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCisKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCisgIDMsICAgMywgICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgMywgICAgMywgICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgMywgICAzLAorICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgIDMsICAgMywgICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgMywKKyAgMywgICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgMywgICAzLCAgICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgMywgICAzLCAgIDMsCisKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCisKKy8vIHN0YXRlWzVdIDB4MDQwMDAwIEJ5dGUgMiBvZiA0CitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorCisgIDMsICAgMywgICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgMywgICAgMywgICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgMywgICAzLAorICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgIDMsICAgMywgICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgMywKKyAgMywgICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgMywgICAzLCAgICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgMywgICAzLCAgIDMsCisgIDMsICAgMywgICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgMywgICAgMywgICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgMywgICAzLAorCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorCisvLyBzdGF0ZVs2XSAweDEwMDAwMCBCeXRlIDIgb2YgNAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKKworWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKKworICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgIDMsICAgMywgICAzLCAgIDMsICAgMywgICAzLCAgIDMsICAgMywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKKworWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKKworLy8gc3RhdGVbN10gMHgwMGQwMDAgQnl0ZSAyIG9mIDMKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCisKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCisKKyAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsCisgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAgMSwgICAxLCAgIDEsICAgMSwgICAxLCAgIDEsICAgMSwgICAxLAorICA4LCAgIDgsICAgOCwgICA4LCAgIDgsICAgOCwgICA4LCAgIDgsICAgIDgsICAgOCwgICA4LCAgIDgsICAgOCwgICA4LCAgIDgsICAgOCwKKyAgOCwgICA4LCAgIDgsICAgOCwgICA4LCAgIDgsICAgOCwgICA4LCAgICA4LCAgIDgsICAgOCwgICA4LCAgIDgsICAgOCwgICA4LCAgIDgsCisKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCisKKy8vIHN0YXRlWzhdIDB4MDBkODAwIEJ5dGUgMyBvZiAzCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorCitSSl8sIFJKXywgUkpfLCBSSl8sIFJKXywgUkpfLCBSSl8sIFJKXywgIFJKXywgUkpfLCBSSl8sIFJKXywgUkpfLCBSSl8sIFJKXywgUkpfLAorUkpfLCBSSl8sIFJKXywgUkpfLCBSSl8sIFJKXywgUkpfLCBSSl8sICBSSl8sIFJKXywgUkpfLCBSSl8sIFJKXywgUkpfLCBSSl8sIFJKXywKK1JKXywgUkpfLCBSSl8sIFJKXywgUkpfLCBSSl8sIFJKXywgUkpfLCAgUkpfLCBSSl8sIFJKXywgUkpfLCBSSl8sIFJKXywgUkpfLCBSSl8sCitSSl8sIFJKXywgUkpfLCBSSl8sIFJKXywgUkpfLCBSSl8sIFJKXywgIFJKXywgUkpfLCBSSl8sIFJKXywgUkpfLCBSSl8sIFJKXywgUkpfLAorCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sICBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywKK1hfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCAgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sCitYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLCBYX18sIFhfXywgWF9fLAorfTsKKworLy8gUmVtYXAgYmFzZVswXSA9IChkZWwsIGFkZCwgc3RyaW5nX29mZnNldCkKK3N0YXRpYyBjb25zdCBSZW1hcEVudHJ5IHV0ZjhhY2NlcHRub25zdXJyb2dhdGVzX3JlbWFwX2Jhc2VbXSA9IHsKK3swLCAwLCAwfSB9OworCisvLyBSZW1hcCBzdHJpbmdbMF0KK3N0YXRpYyBjb25zdCB1bnNpZ25lZCBjaGFyIHV0ZjhhY2NlcHRub25zdXJyb2dhdGVzX3JlbWFwX3N0cmluZ1tdID0geworMCB9OworCitzdGF0aWMgY29uc3QgdW5zaWduZWQgY2hhciB1dGY4YWNjZXB0bm9uc3Vycm9nYXRlc19mYXN0WzI1Nl0gPSB7CiswLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKzAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCiswLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKworMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCiswLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKzAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisKKzEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLAorMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsCisxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwKKzEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLAorCisxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwKKzEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLAorMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsCisxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwKK307CisKK3N0YXRpYyBjb25zdCBVVEY4U2Nhbk9iaiB1dGY4YWNjZXB0bm9uc3Vycm9nYXRlc19vYmogPSB7CisgIHV0ZjhhY2NlcHRub25zdXJyb2dhdGVzX1NUQVRFMCwKKyAgdXRmOGFjY2VwdG5vbnN1cnJvZ2F0ZXNfU1RBVEUwX1NJWkUsCisgIHV0ZjhhY2NlcHRub25zdXJyb2dhdGVzX1RPVEFMX1NJWkUsCisgIHV0ZjhhY2NlcHRub25zdXJyb2dhdGVzX01BWF9FWFBBTkRfWDQsCisgIHV0ZjhhY2NlcHRub25zdXJyb2dhdGVzX1NISUZULAorICB1dGY4YWNjZXB0bm9uc3Vycm9nYXRlc19CWVRFUywKKyAgdXRmOGFjY2VwdG5vbnN1cnJvZ2F0ZXNfTE9TVUIsCisgIHV0ZjhhY2NlcHRub25zdXJyb2dhdGVzX0hJQURELAorICB1dGY4YWNjZXB0bm9uc3Vycm9nYXRlcywKKyAgdXRmOGFjY2VwdG5vbnN1cnJvZ2F0ZXNfcmVtYXBfYmFzZSwKKyAgdXRmOGFjY2VwdG5vbnN1cnJvZ2F0ZXNfcmVtYXBfc3RyaW5nLAorICB1dGY4YWNjZXB0bm9uc3Vycm9nYXRlc19mYXN0Cit9OworCisKKyN1bmRlZiBYX18KKyN1bmRlZiBSSl8KKyN1bmRlZiBTMV8KKyN1bmRlZiBTMl8KKyN1bmRlZiBTM18KKyN1bmRlZiBTMjEKKyN1bmRlZiBTMzEKKyN1bmRlZiBTMzIKKyN1bmRlZiBUMV8KKyN1bmRlZiBUMl8KKyN1bmRlZiBTMTEKKyN1bmRlZiBTUF8KKyN1bmRlZiBEX18KKyN1bmRlZiBSSkEKKworLy8gUmV0dXJuIHRydWUgaWYgY3VycmVudCBUYmwgcG9pbnRlciBpcyB3aXRoaW4gc3RhdGUwIHJhbmdlCisvLyBOb3RlIHRoYXQgdW5zaWduZWQgY29tcGFyZSBjaGVja3MgYm90aCBlbmRzIG9mIHJhbmdlIHNpbXVsdGFuZW91c2x5CitzdGF0aWMgaW5saW5lIGJvb2wgSW5TdGF0ZVplcm8oY29uc3QgVVRGOFNjYW5PYmoqIHN0LCBjb25zdCB1aW50OCogVGJsKSB7CisgIGNvbnN0IHVpbnQ4KiBUYmwwID0gJnN0LT5zdGF0ZV90YWJsZVtzdC0+c3RhdGUwXTsKKyAgcmV0dXJuIChzdGF0aWNfY2FzdDx1aW50MzI+KFRibCAtIFRibDApIDwgc3QtPnN0YXRlMF9zaXplKTsKK30KKworLy8gU2NhbiBhIFVURi04IHN0cmluZyBiYXNlZCBvbiBzdGF0ZSB0YWJsZS4KKy8vIEFsd2F5cyBzY2FuIGNvbXBsZXRlIFVURi04IGNoYXJhY3RlcnMKKy8vIFNldCBudW1iZXIgb2YgYnl0ZXMgc2Nhbm5lZC4gUmV0dXJuIHJlYXNvbiBmb3IgZXhpdGluZworaW50IFVURjhHZW5lcmljU2Nhbihjb25zdCBVVEY4U2Nhbk9iaiogc3QsCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKiBzdHIsCisgICAgICAgICAgICAgICAgICAgIGludCBzdHJfbGVuZ3RoLAorICAgICAgICAgICAgICAgICAgICBpbnQqIGJ5dGVzX2NvbnN1bWVkKSB7CisgICpieXRlc19jb25zdW1lZCA9IDA7CisgIGlmIChzdHJfbGVuZ3RoID09IDApIHJldHVybiBrRXhpdE9LOworCisgIGludCBlc2hpZnQgPSBzdC0+ZW50cnlfc2hpZnQ7CisgIGNvbnN0IHVpbnQ4KiBpc3JjID0gcmVpbnRlcnByZXRfY2FzdDxjb25zdCB1aW50OCo+KHN0cik7CisgIGNvbnN0IHVpbnQ4KiBzcmMgPSBpc3JjOworICBjb25zdCB1aW50OCogc3JjbGltaXQgPSBpc3JjICsgc3RyX2xlbmd0aDsKKyAgY29uc3QgdWludDgqIHNyY2xpbWl0OCA9IHNyY2xpbWl0IC0gNzsKKyAgY29uc3QgdWludDgqIFRibF8wID0gJnN0LT5zdGF0ZV90YWJsZVtzdC0+c3RhdGUwXTsKKworIERvQWdhaW46CisgIC8vIERvIHN0YXRlLXRhYmxlIHNjYW4KKyAgaW50IGUgPSAwOworICB1aW50OCBjOworICBjb25zdCB1aW50OCogVGJsMiA9ICZzdC0+ZmFzdF9zdGF0ZVswXTsKKyAgY29uc3QgdWludDMyIGxvc3ViID0gc3QtPmxvc3ViOworICBjb25zdCB1aW50MzIgaGlhZGQgPSBzdC0+aGlhZGQ7CisgIC8vIENoZWNrIGluaXRpYWwgZmV3IGJ5dGVzIG9uZSBhdCBhIHRpbWUgdW50aWwgOC1ieXRlIGFsaWduZWQKKyAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIHdoaWxlICgoKCh1aW50cHRyX3Qpc3JjICYgMHgwNykgIT0gMCkgJiYKKyAgICAgICAgIChzcmMgPCBzcmNsaW1pdCkgJiYKKyAgICAgICAgIFRibDJbc3JjWzBdXSA9PSAwKSB7CisgICAgc3JjKys7CisgIH0KKyAgaWYgKCgodWludHB0cl90KXNyYyAmIDB4MDcpID09IDApIHsKKyAgICAvLyBEbyBmYXN0IGZvciBncm91cHMgb2YgOCBpZGVudGl0eSBieXRlcy4KKyAgICAvLyBUaGlzIGNvdmVycyBhIGxvdCBvZiA3LWJpdCBBU0NJSSB+OHggZmFzdGVyIHRoZW4gdGhlIDEtYnl0ZSBsb29wLAorICAgIC8vIGluY2x1ZGluZyBzbG93aW5nIHNsaWdodGx5IG9uIGNyL2xmL2h0CisgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgd2hpbGUgKHNyYyA8IHNyY2xpbWl0OCkgeworICAgICAgdWludDMyIHMwMTIzID0gKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgdWludDMyICo+KHNyYykpWzBdOworICAgICAgdWludDMyIHM0NTY3ID0gKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgdWludDMyICo+KHNyYykpWzFdOworICAgICAgc3JjICs9IDg7CisgICAgICAvLyBUaGlzIGlzIGEgZmFzdCByYW5nZSBjaGVjayBmb3IgYWxsIGJ5dGVzIGluIFtsb3dzdWIuLjB4ODAtaGlhZGQpCisgICAgICB1aW50MzIgdGVtcCA9IChzMDEyMyAtIGxvc3ViKSB8IChzMDEyMyArIGhpYWRkKSB8CisgICAgICAgICAgICAgICAgICAgIChzNDU2NyAtIGxvc3ViKSB8IChzNDU2NyArIGhpYWRkKTsKKyAgICAgIGlmICgodGVtcCAmIDB4ODA4MDgwODApICE9IDApIHsKKyAgICAgICAgLy8gV2UgdHlwaWNhbGx5IGVuZCB1cCBoZXJlIG9uIGNyL2xmL2h0OyBzcmMgd2FzIGluY3JlbWVudGVkCisgICAgICAgIGludCBlMDEyMyA9IChUYmwyW3NyY1stOF1dIHwgVGJsMltzcmNbLTddXSkgfAorICAgICAgICAgICAgICAgICAgICAoVGJsMltzcmNbLTZdXSB8IFRibDJbc3JjWy01XV0pOworICAgICAgICBpZiAoZTAxMjMgIT0gMCkgeworICAgICAgICAgIHNyYyAtPSA4OworICAgICAgICAgIGJyZWFrOworICAgICAgICB9ICAgIC8vIEV4aXQgb24gTm9uLWludGVyY2hhbmdlCisgICAgICAgIGUwMTIzID0gKFRibDJbc3JjWy00XV0gfCBUYmwyW3NyY1stM11dKSB8CisgICAgICAgICAgICAgICAgKFRibDJbc3JjWy0yXV0gfCBUYmwyW3NyY1stMV1dKTsKKyAgICAgICAgaWYgKGUwMTIzICE9IDApIHsKKyAgICAgICAgICBzcmMgLT0gNDsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfSAgICAvLyBFeGl0IG9uIE5vbi1pbnRlcmNoYW5nZQorICAgICAgICAvLyBFbHNlIE9LLCBnbyBhcm91bmQgYWdhaW4KKyAgICAgIH0KKyAgICB9CisgIH0KKyAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gQnl0ZS1hdC1hLXRpbWUgc2NhbgorICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgY29uc3QgdWludDgqIFRibCA9IFRibF8wOworICB3aGlsZSAoc3JjIDwgc3JjbGltaXQpIHsKKyAgICBjID0gKnNyYzsKKyAgICBlID0gVGJsW2NdOworICAgIHNyYysrOworICAgIGlmIChlID49IGtFeGl0SWxsZWdhbFN0cnVjdHVyZSkge2JyZWFrO30KKyAgICBUYmwgPSAmVGJsXzBbZSA8PCBlc2hpZnRdOworICB9CisgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisKKyAgLy8gRXhpdCBwb3NpYmlsaXRpZXM6CisgIC8vICBTb21lIGV4aXQgY29kZSwgIXN0YXRlMCwgYmFjayB1cCBvdmVyIGxhc3QgY2hhcgorICAvLyAgU29tZSBleGl0IGNvZGUsIHN0YXRlMCwgYmFjayB1cCBvbmUgYnl0ZSBleGFjdGx5CisgIC8vICBzb3VyY2UgY29uc3VtZWQsICFzdGF0ZTAsIGJhY2sgdXAgb3ZlciBwYXJ0aWFsIGNoYXIKKyAgLy8gIHNvdXJjZSBjb25zdW1lZCwgc3RhdGUwLCBleGl0IE9LCisgIC8vIEZvciBpbGxlZ2FsIGJ5dGUgaW4gc3RhdGUwLCBhdm9pZCBiYWNrdXAgdXAgb3ZlciBQUkVWSU9VUyBjaGFyCisgIC8vIEZvciB0cnVuY2F0ZWQgbGFzdCBjaGFyLCBiYWNrIHVwIHRvIGJlZ2lubmluZyBvZiBpdAorCisgIGlmIChlID49IGtFeGl0SWxsZWdhbFN0cnVjdHVyZSkgeworICAgIC8vIEJhY2sgdXAgb3ZlciBleGFjdGx5IG9uZSBieXRlIG9mIHJlamVjdGVkL2lsbGVnYWwgVVRGLTggY2hhcmFjdGVyCisgICAgc3JjLS07CisgICAgLy8gQmFjayB1cCBtb3JlIGlmIG5lZWRlZAorICAgIGlmICghSW5TdGF0ZVplcm8oc3QsIFRibCkpIHsKKyAgICAgIGRvIHsKKyAgICAgICAgc3JjLS07CisgICAgICB9IHdoaWxlICgoc3JjID4gaXNyYykgJiYgKChzcmNbMF0gJiAweGMwKSA9PSAweDgwKSk7CisgICAgfQorICB9IGVsc2UgaWYgKCFJblN0YXRlWmVybyhzdCwgVGJsKSkgeworICAgIC8vIEJhY2sgdXAgb3ZlciB0cnVuY2F0ZWQgVVRGLTggY2hhcmFjdGVyCisgICAgZSA9IGtFeGl0SWxsZWdhbFN0cnVjdHVyZTsKKyAgICBkbyB7CisgICAgICBzcmMtLTsKKyAgICB9IHdoaWxlICgoc3JjID4gaXNyYykgJiYgKChzcmNbMF0gJiAweGMwKSA9PSAweDgwKSk7CisgIH0gZWxzZSB7CisgICAgLy8gTm9ybWFsIHRlcm1pbmF0aW9uLCBzb3VyY2UgZnVsbHkgY29uc3VtZWQKKyAgICBlID0ga0V4aXRPSzsKKyAgfQorCisgIGlmIChlID09IGtFeGl0RG9BZ2FpbikgeworICAgIC8vIExvb3AgYmFjayB1cCB0byB0aGUgZmFzdCBzY2FuCisgICAgZ290byBEb0FnYWluOworICB9CisKKyAgKmJ5dGVzX2NvbnN1bWVkID0gc3JjIC0gaXNyYzsKKyAgcmV0dXJuIGU7Cit9CisKK2ludCBVVEY4R2VuZXJpY1NjYW5GYXN0QXNjaWkoY29uc3QgVVRGOFNjYW5PYmoqIHN0LAorICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICogc3RyLAorICAgICAgICAgICAgICAgICAgICBpbnQgc3RyX2xlbmd0aCwKKyAgICAgICAgICAgICAgICAgICAgaW50KiBieXRlc19jb25zdW1lZCkgeworICAqYnl0ZXNfY29uc3VtZWQgPSAwOworICBpZiAoc3RyX2xlbmd0aCA9PSAwKSByZXR1cm4ga0V4aXRPSzsKKworICBjb25zdCB1aW50OCogaXNyYyA9ICByZWludGVycHJldF9jYXN0PGNvbnN0IHVpbnQ4Kj4oc3RyKTsKKyAgY29uc3QgdWludDgqIHNyYyA9IGlzcmM7CisgIGNvbnN0IHVpbnQ4KiBzcmNsaW1pdCA9IGlzcmMgKyBzdHJfbGVuZ3RoOworICBjb25zdCB1aW50OCogc3JjbGltaXQ4ID0gc3JjbGltaXQgLSA3OworICBpbnQgbjsKKyAgaW50IHJlc3RfY29uc3VtZWQ7CisgIGludCBleGl0X3JlYXNvbjsKKyAgZG8geworICAgIC8vIENoZWNrIGluaXRpYWwgZmV3IGJ5dGVzIG9uZSBhdCBhIHRpbWUgdW50aWwgOC1ieXRlIGFsaWduZWQKKyAgICB3aGlsZSAoKCgodWludHB0cl90KXNyYyAmIDB4MDcpICE9IDApICYmCisgICAgICAgICAgIChzcmMgPCBzcmNsaW1pdCkgJiYgKHNyY1swXSA8IDB4ODApKSB7CisgICAgICBzcmMrKzsKKyAgICB9CisgICAgaWYgKCgodWludHB0cl90KXNyYyAmIDB4MDcpID09IDApIHsKKyAgICAgIHdoaWxlICgoc3JjIDwgc3JjbGltaXQ4KSAmJgorICAgICAgICAgICAgICgoKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgdWludDMyKj4oc3JjKVswXSB8CisgICAgICAgICAgICAgICAgcmVpbnRlcnByZXRfY2FzdDxjb25zdCB1aW50MzIqPihzcmMpWzFdKSAmIDB4ODA4MDgwODApID09IDApKSB7CisgICAgICAgIHNyYyArPSA4OworICAgICAgfQorICAgIH0KKyAgICB3aGlsZSAoKHNyYyA8IHNyY2xpbWl0KSAmJiAoc3JjWzBdIDwgMHg4MCkpIHsKKyAgICAgIHNyYysrOworICAgIH0KKyAgICAvLyBSdW4gc3RhdGUgdGFibGUgb24gdGhlIHJlc3QKKyAgICBuID0gc3JjIC0gaXNyYzsKKyAgICBleGl0X3JlYXNvbiA9IFVURjhHZW5lcmljU2NhbihzdCwgc3RyICsgbiwgc3RyX2xlbmd0aCAtIG4sICZyZXN0X2NvbnN1bWVkKTsKKyAgICBzcmMgKz0gcmVzdF9jb25zdW1lZDsKKyAgfSB3aGlsZSAoIGV4aXRfcmVhc29uID09IGtFeGl0RG9BZ2FpbiApOworCisgICpieXRlc19jb25zdW1lZCA9IHNyYyAtIGlzcmM7CisgIHJldHVybiBleGl0X3JlYXNvbjsKK30KKworLy8gSGFjazogIE9uIHNvbWUgY29tcGlsZXJzIHRoZSBzdGF0aWMgdGFibGVzIGFyZSBpbml0aWFsaXplZCBhdCBzdGFydHVwLgorLy8gICBXZSBjYW4ndCB1c2UgdGhlbSB1bnRpbCB0aGV5IGFyZSBpbml0aWFsaXplZC4gIEhvd2V2ZXIsIHNvbWUgUHJvdG9jb2wKKy8vICAgQnVmZmVyIHBhcnNpbmcgaGFwcGVucyBhdCBzdGF0aWMgaW5pdCB0aW1lIGFuZCBtYXkgdHJ5IHRvIHZhbGlkYXRlCisvLyAgIFVURi04IHN0cmluZ3MuICBTaW5jZSBVVEYtOCB2YWxpZGF0aW9uIGlzIG9ubHkgdXNlZCBmb3IgZGVidWdnaW5nCisvLyAgIGFueXdheSwgd2Ugc2ltcGx5IGFsd2F5cyByZXR1cm4gc3VjY2VzcyBpZiBpbml0aWFsaXphdGlvbiBoYXNuJ3QKKy8vICAgb2NjdXJyZWQgeWV0LgorbmFtZXNwYWNlIHsKKworYm9vbCBtb2R1bGVfaW5pdGlhbGl6ZWRfID0gZmFsc2U7CisKK3N0cnVjdCBJbml0RGV0ZWN0b3IgeworICBJbml0RGV0ZWN0b3IoKSB7CisgICAgbW9kdWxlX2luaXRpYWxpemVkXyA9IHRydWU7CisgIH0KK307CitJbml0RGV0ZWN0b3IgaW5pdF9kZXRlY3RvcjsKKworfSAgLy8gbmFtZXNwYWNlCisKK2Jvb2wgSXNTdHJ1Y3R1cmFsbHlWYWxpZFVURjgoY29uc3QgY2hhciogYnVmLCBpbnQgbGVuKSB7CisgIGlmICghbW9kdWxlX2luaXRpYWxpemVkXykgcmV0dXJuIHRydWU7CisgIAorICBpbnQgYnl0ZXNfY29uc3VtZWQgPSAwOworICBVVEY4R2VuZXJpY1NjYW5GYXN0QXNjaWkoJnV0ZjhhY2NlcHRub25zdXJyb2dhdGVzX29iaiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZiwgbGVuLCAmYnl0ZXNfY29uc3VtZWQpOworICByZXR1cm4gKGJ5dGVzX2NvbnN1bWVkID09IGxlbik7Cit9CisKK2ludCBVVEY4U3BuU3RydWN0dXJhbGx5VmFsaWQoY29uc3QgU3RyaW5nUGllY2UmIHN0cikgeworICBpZiAoIW1vZHVsZV9pbml0aWFsaXplZF8pIHJldHVybiBzdHIuc2l6ZSgpOworCisgIGludCBieXRlc19jb25zdW1lZCA9IDA7CisgIFVURjhHZW5lcmljU2NhbkZhc3RBc2NpaSgmdXRmOGFjY2VwdG5vbnN1cnJvZ2F0ZXNfb2JqLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyLmRhdGEoKSwgc3RyLnNpemUoKSwgJmJ5dGVzX2NvbnN1bWVkKTsKKyAgcmV0dXJuIGJ5dGVzX2NvbnN1bWVkOworfQorCisvLyBDb2VyY2UgVVRGLTggYnl0ZSBzdHJpbmcgaW4gc3JjX3N0ciB0byBiZQorLy8gYSBzdHJ1Y3R1cmFsbHktdmFsaWQgZXF1YWwtbGVuZ3RoIHN0cmluZyBieSBzZWxlY3RpdmVseQorLy8gb3ZlcndyaXRpbmcgaWxsZWdhbCBieXRlcyB3aXRoIHJlcGxhY2VfY2hhciAodHlwaWNhbGx5IGJsYW5rKS4KKy8vIHJlcGxhY2VfY2hhciBtdXN0IGJlIGxlZ2FsIHByaW50YWJsZSA3LWJpdCBBc2NpaSAweDIwLi4weDdlLgorLy8gc3JjX3N0ciBpcyByZWFkLW9ubHkuIElmIGFueSBvdmVyd3JpdGluZyBpcyBuZWVkZWQsIGEgbW9kaWZpZWQgYnl0ZSBzdHJpbmcKKy8vIGlzIGNyZWF0ZWQgaW4gaWRzdCwgbGVuZ3RoIGlzcmNsZW4uCisvLworLy8gUmV0dXJucyBwb2ludGVyIHRvIG91dHB1dCBidWZmZXIsIGlzcmMgaWYgbm8gY2hhbmdlcyB3ZXJlIG1hZGUsCisvLyAgb3IgaWRzdCBpZiBzb21lIGJ5dGVzIHdlcmUgY2hhbmdlZC4KKy8vCisvLyBGYXN0IGNhc2U6IGFsbCBpcyBzdHJ1Y3R1cmFsbHkgdmFsaWQgYW5kIG5vIGJ5dGUgY29weWluZyBpcyBkb25lLgorLy8KK2NoYXIqIFVURjhDb2VyY2VUb1N0cnVjdHVyYWxseVZhbGlkKGNvbnN0IFN0cmluZ1BpZWNlJiBzcmNfc3RyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhciogaWRzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgcmVwbGFjZV9jaGFyKSB7CisgIGNvbnN0IGNoYXIqIGlzcmMgPSBzcmNfc3RyLmRhdGEoKTsKKyAgY29uc3QgaW50IGxlbiA9IHNyY19zdHIubGVuZ3RoKCk7CisgIGludCBuID0gVVRGOFNwblN0cnVjdHVyYWxseVZhbGlkKHNyY19zdHIpOworICBpZiAobiA9PSBsZW4pIHsgICAgICAgICAgICAgICAvLyBOb3JtYWwgY2FzZSAtLSBhbGwgaXMgY29vbCwgcmV0dXJuCisgICAgcmV0dXJuIGNvbnN0X2Nhc3Q8Y2hhcio+KGlzcmMpOworICB9IGVsc2UgeyAgICAgICAgICAgICAgICAgICAgICAvLyBVbnVzdWFsIGNhc2UgLS0gY29weSB3L28gYmFkIGJ5dGVzCisgICAgY29uc3QgY2hhciogc3JjID0gaXNyYzsKKyAgICBjb25zdCBjaGFyKiBzcmNsaW1pdCA9IGlzcmMgKyBsZW47CisgICAgY2hhciogZHN0ID0gaWRzdDsKKyAgICBtZW1tb3ZlKGRzdCwgc3JjLCBuKTsgICAgICAgLy8gQ29weSBpbml0aWFsIGdvb2QgY2h1bmsKKyAgICBzcmMgKz0gbjsKKyAgICBkc3QgKz0gbjsKKyAgICB3aGlsZSAoc3JjIDwgc3JjbGltaXQpIHsgICAgLy8gc3JjIHBvaW50cyB0byBib2d1cyBieXRlIG9yIGlzIG9mZiB0aGUgZW5kCisgICAgICBkc3RbMF0gPSByZXBsYWNlX2NoYXI7ICAgICAgICAgICAgICAgICAgICAvLyByZXBsYWNlIG9uZSBiYWQgYnl0ZQorICAgICAgc3JjKys7CisgICAgICBkc3QrKzsKKyAgICAgIFN0cmluZ1BpZWNlIHN0cjIoc3JjLCBzcmNsaW1pdCAtIHNyYyk7CisgICAgICBuID0gVVRGOFNwblN0cnVjdHVyYWxseVZhbGlkKHN0cjIpOyAgICAgICAvLyBzY2FuIHRoZSByZW1haW5kZXIKKyAgICAgIG1lbW1vdmUoZHN0LCBzcmMsIG4pOyAgICAgICAgICAgICAgICAgICAgIC8vIGNvcHkgbmV4dCBnb29kIGNodW5rCisgICAgICBzcmMgKz0gbjsKKyAgICAgIGRzdCArPSBuOworICAgIH0KKyAgfQorICByZXR1cm4gaWRzdDsKK30KKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydWN0dXJhbGx5X3ZhbGlkX3VuaXR0ZXN0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1Y3R1cmFsbHlfdmFsaWRfdW5pdHRlc3QuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTA4ODg4OAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydWN0dXJhbGx5X3ZhbGlkX3VuaXR0ZXN0LmNjCkBAIC0wLDAgKzEsNDAgQEAKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCisvLyBBdXRob3I6IHhwZW5nQGdvb2dsZS5jb20gKFBldGVyIFBlbmcpCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKK25hbWVzcGFjZSB7CisKK1RFU1QoU3RydWN0dXJhbGx5VmFsaWRUZXN0LCBWYWxpZFVURjhTdHJpbmcpIHsKKyAgLy8gT24gR0NDLCB0aGlzIHN0cmluZyBjYW4gYmUgd3JpdHRlbiBhczoKKyAgLy8gICAiYWJjZCAxMjM0IC0gXHUyMDE0XHUyMDEzXHUyMjEyIgorICAvLyBNU1ZDIHNlZW1zIHRvIGludGVycHJldCBcdSBkaWZmZXJlbnRseS4KKyAgc3RyaW5nIHZhbGlkX3N0cigiYWJjZCAxMjM0IC0gXDM0MlwyMDBcMjI0XDM0MlwyMDBcMjIzXDM0MlwyMTBcMjIyIC0geHl6Nzg5Iik7CisgIEVYUEVDVF9UUlVFKElzU3RydWN0dXJhbGx5VmFsaWRVVEY4KHZhbGlkX3N0ci5kYXRhKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkX3N0ci5zaXplKCkpKTsKKyAgLy8gQWRkaXRpb25hbCBjaGVjayBmb3IgcG9pbnRlciBhbGlnbm1lbnQKKyAgZm9yIChpbnQgaSA9IDE7IGkgPCA4OyArK2kpIHsKKyAgICBFWFBFQ1RfVFJVRShJc1N0cnVjdHVyYWxseVZhbGlkVVRGOCh2YWxpZF9zdHIuZGF0YSgpICsgaSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWxpZF9zdHIuc2l6ZSgpIC0gaSkpOworICB9Cit9CisKK1RFU1QoU3RydWN0dXJhbGx5VmFsaWRUZXN0LCBJbnZhbGlkVVRGOFN0cmluZykgeworICBjb25zdCBzdHJpbmcgaW52YWxpZF9zdHIoImFiY2RceEEwXHhCMFx4QTBceEIwXHhBMFx4QjAgLSB4eXo3ODkiKTsKKyAgRVhQRUNUX0ZBTFNFKElzU3RydWN0dXJhbGx5VmFsaWRVVEY4KGludmFsaWRfc3RyLmRhdGEoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludmFsaWRfc3RyLnNpemUoKSkpOworICAvLyBBZGRpdGlvbmFsIGNoZWNrIGZvciBwb2ludGVyIGFsaWdubWVudAorICBmb3IgKGludCBpID0gMTsgaSA8IDg7ICsraSkgeworICAgIEVYUEVDVF9GQUxTRShJc1N0cnVjdHVyYWxseVZhbGlkVVRGOChpbnZhbGlkX3N0ci5kYXRhKCkgKyBpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnZhbGlkX3N0ci5zaXplKCkgLSBpKSk7CisgIH0KK30KKworfSAgLy8gbmFtZXNwYWNlCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdiYTkyZTgKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuY2MKQEAgLTAsMCArMSwyMjg5IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gZnJvbSBnb29nbGUzL3N0cmluZ3Mvc3RydXRpbC5jYworCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbWF0aGxpbWl0cy5oPgorCisjaW5jbHVkZSA8ZXJybm8uaD4KKyNpbmNsdWRlIDxmbG9hdC5oPiAgICAvLyBGTFRfRElHIGFuZCBEQkxfRElHCisjaW5jbHVkZSA8bGltaXRzPgorI2luY2x1ZGUgPGxpbWl0cy5oPgorI2luY2x1ZGUgPHN0ZGlvLmg+CisjaW5jbHVkZSA8aXRlcmF0b3I+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RsX3V0aWwuaD4KKworI2lmZGVmIF9XSU4zMgorLy8gTVNWQyBoYXMgb25seSBfc25wcmludGYsIG5vdCBzbnByaW50Zi4KKy8vCisvLyBNaW5HVyBoYXMgYm90aCBzbnByaW50ZiBhbmQgX3NucHJpbnRmLCBidXQgdGhleSBhcHBlYXIgdG8gYmUgZGlmZmVyZW50CisvLyBmdW5jdGlvbnMuICBUaGUgZm9ybWVyIGlzIGJ1Z2d5LiAgV2hlbiBpbnZva2VkIGxpa2Ugc286CisvLyAgIGNoYXIgYnVmZmVyWzMyXTsKKy8vICAgc25wcmludGYoYnVmZmVyLCAzMiwgIiUuKmdcbiIsIEZMVF9ESUcsIDEuMjNlMTBmKTsKKy8vIGl0IHByaW50cyAiMS4yMzAwMGUrMTAiLiAgVGhpcyBpcyBwbGFpbmx5IHdyb25nOiAgJWcgc2hvdWxkIG5ldmVyIHByaW50CisvLyB0cmFpbGluZyB6ZXJvcyBhZnRlciB0aGUgZGVjaW1hbCBwb2ludC4gIEZvciBzb21lIHJlYXNvbiB0aGlzIGJ1ZyBvbmx5CisvLyBvY2N1cnMgd2l0aCBzb21lIGlucHV0IHZhbHVlcywgbm90IGFsbC4gIEluIGFueSBjYXNlLCBfc25wcmludGYgZG9lcyB0aGUKKy8vIHJpZ2h0IHRoaW5nLCBzbyB3ZSB1c2UgaXQuCisjZGVmaW5lIHNucHJpbnRmIF9zbnByaW50ZgorI2VuZGlmCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworLy8gVGhlc2UgYXJlIGRlZmluZWQgYXMgbWFjcm9zIG9uIHNvbWUgcGxhdGZvcm1zLiAgI3VuZGVmIHRoZW0gc28gdGhhdCB3ZSBjYW4KKy8vIHJlZGVmaW5lIHRoZW0uCisjdW5kZWYgaXN4ZGlnaXQKKyN1bmRlZiBpc3ByaW50CisKKy8vIFRoZSBkZWZpbml0aW9ucyBvZiB0aGVzZSBpbiBjdHlwZS5oIGNoYW5nZSBiYXNlZCBvbiBsb2NhbGUuICBTaW5jZSBvdXIKKy8vIHN0cmluZyBtYW5pcHVsYXRpb24gaXMgYWxsIGluIHJlbGF0aW9uIHRvIHRoZSBwcm90b2NvbCBidWZmZXIgYW5kIEMrKworLy8gbGFuZ3VhZ2VzLCB3ZSBhbHdheXMgd2FudCB0byB1c2UgdGhlIEMgbG9jYWxlLiAgU28sIHdlIHJlLWRlZmluZSB0aGVzZQorLy8gZXhhY3RseSBhcyB3ZSB3YW50IHRoZW0uCitpbmxpbmUgYm9vbCBpc3hkaWdpdChjaGFyIGMpIHsKKyAgcmV0dXJuICgnMCcgPD0gYyAmJiBjIDw9ICc5JykgfHwKKyAgICAgICAgICgnYScgPD0gYyAmJiBjIDw9ICdmJykgfHwKKyAgICAgICAgICgnQScgPD0gYyAmJiBjIDw9ICdGJyk7Cit9CisKK2lubGluZSBib29sIGlzcHJpbnQoY2hhciBjKSB7CisgIHJldHVybiBjID49IDB4MjAgJiYgYyA8PSAweDdFOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBTdHJpcFN0cmluZworLy8gICAgUmVwbGFjZXMgYW55IG9jY3VycmVuY2Ugb2YgdGhlIGNoYXJhY3RlciAncmVtb3ZlJyAob3IgdGhlIGNoYXJhY3RlcnMKKy8vICAgIGluICdyZW1vdmUnKSB3aXRoIHRoZSBjaGFyYWN0ZXIgJ3JlcGxhY2V3aXRoJy4KKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK3ZvaWQgU3RyaXBTdHJpbmcoc3RyaW5nKiBzLCBjb25zdCBjaGFyKiByZW1vdmUsIGNoYXIgcmVwbGFjZXdpdGgpIHsKKyAgY29uc3QgY2hhciAqIHN0cl9zdGFydCA9IHMtPmNfc3RyKCk7CisgIGNvbnN0IGNoYXIgKiBzdHIgPSBzdHJfc3RhcnQ7CisgIGZvciAoc3RyID0gc3RycGJyayhzdHIsIHJlbW92ZSk7CisgICAgICAgc3RyICE9IE5VTEw7CisgICAgICAgc3RyID0gc3RycGJyayhzdHIgKyAxLCByZW1vdmUpKSB7CisgICAgKCpzKVtzdHIgLSBzdHJfc3RhcnRdID0gcmVwbGFjZXdpdGg7CisgIH0KK30KKwordm9pZCBTdHJpcFdoaXRlc3BhY2Uoc3RyaW5nKiBzdHIpIHsKKyAgaW50IHN0cl9sZW5ndGggPSBzdHItPmxlbmd0aCgpOworCisgIC8vIFN0cmlwIG9mZiBsZWFkaW5nIHdoaXRlc3BhY2UuCisgIGludCBmaXJzdCA9IDA7CisgIHdoaWxlIChmaXJzdCA8IHN0cl9sZW5ndGggJiYgYXNjaWlfaXNzcGFjZShzdHItPmF0KGZpcnN0KSkpIHsKKyAgICArK2ZpcnN0OworICB9CisgIC8vIElmIGVudGlyZSBzdHJpbmcgaXMgd2hpdGUgc3BhY2UuCisgIGlmIChmaXJzdCA9PSBzdHJfbGVuZ3RoKSB7CisgICAgc3RyLT5jbGVhcigpOworICAgIHJldHVybjsKKyAgfQorICBpZiAoZmlyc3QgPiAwKSB7CisgICAgc3RyLT5lcmFzZSgwLCBmaXJzdCk7CisgICAgc3RyX2xlbmd0aCAtPSBmaXJzdDsKKyAgfQorCisgIC8vIFN0cmlwIG9mZiB0cmFpbGluZyB3aGl0ZXNwYWNlLgorICBpbnQgbGFzdCA9IHN0cl9sZW5ndGggLSAxOworICB3aGlsZSAobGFzdCA+PSAwICYmIGFzY2lpX2lzc3BhY2Uoc3RyLT5hdChsYXN0KSkpIHsKKyAgICAtLWxhc3Q7CisgIH0KKyAgaWYgKGxhc3QgIT0gKHN0cl9sZW5ndGggLSAxKSAmJiBsYXN0ID49IDApIHsKKyAgICBzdHItPmVyYXNlKGxhc3QgKyAxLCBzdHJpbmc6Om5wb3MpOworICB9Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIFN0cmluZ1JlcGxhY2UoKQorLy8gICAgUmVwbGFjZSB0aGUgIm9sZCIgcGF0dGVybiB3aXRoIHRoZSAibmV3IiBwYXR0ZXJuIGluIGEgc3RyaW5nLAorLy8gICAgYW5kIGFwcGVuZCB0aGUgcmVzdWx0IHRvICJyZXMiLiAgSWYgcmVwbGFjZV9hbGwgaXMgZmFsc2UsCisvLyAgICBpdCBvbmx5IHJlcGxhY2VzIHRoZSBmaXJzdCBpbnN0YW5jZSBvZiAib2xkLiIKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBTdHJpbmdSZXBsYWNlKGNvbnN0IHN0cmluZyYgcywgY29uc3Qgc3RyaW5nJiBvbGRzdWIsCisgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBuZXdzdWIsIGJvb2wgcmVwbGFjZV9hbGwsCisgICAgICAgICAgICAgICAgICAgc3RyaW5nKiByZXMpIHsKKyAgaWYgKG9sZHN1Yi5lbXB0eSgpKSB7CisgICAgcmVzLT5hcHBlbmQocyk7ICAvLyBpZiBlbXB0eSwgYXBwZW5kIHRoZSBnaXZlbiBzdHJpbmcuCisgICAgcmV0dXJuOworICB9CisKKyAgc3RyaW5nOjpzaXplX3R5cGUgc3RhcnRfcG9zID0gMDsKKyAgc3RyaW5nOjpzaXplX3R5cGUgcG9zOworICBkbyB7CisgICAgcG9zID0gcy5maW5kKG9sZHN1Yiwgc3RhcnRfcG9zKTsKKyAgICBpZiAocG9zID09IHN0cmluZzo6bnBvcykgeworICAgICAgYnJlYWs7CisgICAgfQorICAgIHJlcy0+YXBwZW5kKHMsIHN0YXJ0X3BvcywgcG9zIC0gc3RhcnRfcG9zKTsKKyAgICByZXMtPmFwcGVuZChuZXdzdWIpOworICAgIHN0YXJ0X3BvcyA9IHBvcyArIG9sZHN1Yi5zaXplKCk7ICAvLyBzdGFydCBzZWFyY2hpbmcgYWdhaW4gYWZ0ZXIgdGhlICJvbGQiCisgIH0gd2hpbGUgKHJlcGxhY2VfYWxsKTsKKyAgcmVzLT5hcHBlbmQocywgc3RhcnRfcG9zLCBzLmxlbmd0aCgpIC0gc3RhcnRfcG9zKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gU3RyaW5nUmVwbGFjZSgpCisvLyAgICBHaXZlIG1lIGEgc3RyaW5nIGFuZCB0d28gcGF0dGVybnMgIm9sZCIgYW5kICJuZXciLCBhbmQgSSByZXBsYWNlCisvLyAgICB0aGUgZmlyc3QgaW5zdGFuY2Ugb2YgIm9sZCIgaW4gdGhlIHN0cmluZyB3aXRoICJuZXciLCBpZiBpdAorLy8gICAgZXhpc3RzLiAgSWYgImdsb2JhbCIgaXMgdHJ1ZTsgY2FsbCB0aGlzIHJlcGVhdGVkbHkgdW50aWwgaXQKKy8vICAgIGZhaWxzLiAgUkVUVVJOIGEgbmV3IHN0cmluZywgcmVnYXJkbGVzcyBvZiB3aGV0aGVyIHRoZSByZXBsYWNlbWVudAorLy8gICAgaGFwcGVuZWQgb3Igbm90LgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitzdHJpbmcgU3RyaW5nUmVwbGFjZShjb25zdCBzdHJpbmcmIHMsIGNvbnN0IHN0cmluZyYgb2xkc3ViLAorICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBuZXdzdWIsIGJvb2wgcmVwbGFjZV9hbGwpIHsKKyAgc3RyaW5nIHJldDsKKyAgU3RyaW5nUmVwbGFjZShzLCBvbGRzdWIsIG5ld3N1YiwgcmVwbGFjZV9hbGwsICZyZXQpOworICByZXR1cm4gcmV0OworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBTcGxpdFN0cmluZ1VzaW5nKCkKKy8vICAgIFNwbGl0IGEgc3RyaW5nIHVzaW5nIGEgY2hhcmFjdGVyIGRlbGltaXRlci4gQXBwZW5kIHRoZSBjb21wb25lbnRzCisvLyAgICB0byAncmVzdWx0Jy4KKy8vCisvLyBOb3RlOiBGb3IgbXVsdGktY2hhcmFjdGVyIGRlbGltaXRlcnMsIHRoaXMgcm91dGluZSB3aWxsIHNwbGl0IG9uICpBTlkqIG9mCisvLyB0aGUgY2hhcmFjdGVycyBpbiB0aGUgc3RyaW5nLCBub3QgdGhlIGVudGlyZSBzdHJpbmcgYXMgYSBzaW5nbGUgZGVsaW1pdGVyLgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQordGVtcGxhdGUgPHR5cGVuYW1lIElUUj4KK3N0YXRpYyBpbmxpbmUKK3ZvaWQgU3BsaXRTdHJpbmdUb0l0ZXJhdG9yVXNpbmcoY29uc3Qgc3RyaW5nJiBmdWxsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiBkZWxpbSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVRSJiByZXN1bHQpIHsKKyAgLy8gT3B0aW1pemUgdGhlIGNvbW1vbiBjYXNlIHdoZXJlIGRlbGltIGlzIGEgc2luZ2xlIGNoYXJhY3Rlci4KKyAgaWYgKGRlbGltWzBdICE9ICdcMCcgJiYgZGVsaW1bMV0gPT0gJ1wwJykgeworICAgIGNoYXIgYyA9IGRlbGltWzBdOworICAgIGNvbnN0IGNoYXIqIHAgPSBmdWxsLmRhdGEoKTsKKyAgICBjb25zdCBjaGFyKiBlbmQgPSBwICsgZnVsbC5zaXplKCk7CisgICAgd2hpbGUgKHAgIT0gZW5kKSB7CisgICAgICBpZiAoKnAgPT0gYykgeworICAgICAgICArK3A7CisgICAgICB9IGVsc2UgeworICAgICAgICBjb25zdCBjaGFyKiBzdGFydCA9IHA7CisgICAgICAgIHdoaWxlICgrK3AgIT0gZW5kICYmICpwICE9IGMpOworICAgICAgICAqcmVzdWx0KysgPSBzdHJpbmcoc3RhcnQsIHAgLSBzdGFydCk7CisgICAgICB9CisgICAgfQorICAgIHJldHVybjsKKyAgfQorCisgIHN0cmluZzo6c2l6ZV90eXBlIGJlZ2luX2luZGV4LCBlbmRfaW5kZXg7CisgIGJlZ2luX2luZGV4ID0gZnVsbC5maW5kX2ZpcnN0X25vdF9vZihkZWxpbSk7CisgIHdoaWxlIChiZWdpbl9pbmRleCAhPSBzdHJpbmc6Om5wb3MpIHsKKyAgICBlbmRfaW5kZXggPSBmdWxsLmZpbmRfZmlyc3Rfb2YoZGVsaW0sIGJlZ2luX2luZGV4KTsKKyAgICBpZiAoZW5kX2luZGV4ID09IHN0cmluZzo6bnBvcykgeworICAgICAgKnJlc3VsdCsrID0gZnVsbC5zdWJzdHIoYmVnaW5faW5kZXgpOworICAgICAgcmV0dXJuOworICAgIH0KKyAgICAqcmVzdWx0KysgPSBmdWxsLnN1YnN0cihiZWdpbl9pbmRleCwgKGVuZF9pbmRleCAtIGJlZ2luX2luZGV4KSk7CisgICAgYmVnaW5faW5kZXggPSBmdWxsLmZpbmRfZmlyc3Rfbm90X29mKGRlbGltLCBlbmRfaW5kZXgpOworICB9Cit9CisKK3ZvaWQgU3BsaXRTdHJpbmdVc2luZyhjb25zdCBzdHJpbmcmIGZ1bGwsCisgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogZGVsaW0sCisgICAgICAgICAgICAgICAgICAgICAgdmVjdG9yPHN0cmluZz4qIHJlc3VsdCkgeworICBiYWNrX2luc2VydF9pdGVyYXRvcjwgdmVjdG9yPHN0cmluZz4gPiBpdCgqcmVzdWx0KTsKKyAgU3BsaXRTdHJpbmdUb0l0ZXJhdG9yVXNpbmcoZnVsbCwgZGVsaW0sIGl0KTsKK30KKworLy8gU3BsaXQgYSBzdHJpbmcgdXNpbmcgYSBjaGFyYWN0ZXIgZGVsaW1pdGVyLiBBcHBlbmQgdGhlIGNvbXBvbmVudHMKKy8vIHRvICdyZXN1bHQnLiAgSWYgdGhlcmUgYXJlIGNvbnNlY3V0aXZlIGRlbGltaXRlcnMsIHRoaXMgZnVuY3Rpb24KKy8vIHdpbGwgcmV0dXJuIGNvcnJlc3BvbmRpbmcgZW1wdHkgc3RyaW5ncy4gVGhlIHN0cmluZyBpcyBzcGxpdCBpbnRvCisvLyBhdCBtb3N0IHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mIHBpZWNlcyBncmVlZGlseS4gVGhpcyBtZWFucyB0aGF0IHRoZQorLy8gbGFzdCBwaWVjZSBtYXkgcG9zc2libHkgYmUgc3BsaXQgZnVydGhlci4gVG8gc3BsaXQgaW50byBhcyBtYW55IHBpZWNlcworLy8gYXMgcG9zc2libGUsIHNwZWNpZnkgMCBhcyB0aGUgbnVtYmVyIG9mIHBpZWNlcy4KKy8vCisvLyBJZiAiZnVsbCIgaXMgdGhlIGVtcHR5IHN0cmluZywgeWllbGRzIGFuIGVtcHR5IHN0cmluZyBhcyB0aGUgb25seSB2YWx1ZS4KKy8vCisvLyBJZiAicGllY2VzIiBpcyBuZWdhdGl2ZSBmb3Igc29tZSByZWFzb24sIGl0IHJldHVybnMgdGhlIHdob2xlIHN0cmluZworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQordGVtcGxhdGUgPHR5cGVuYW1lIFN0cmluZ1R5cGUsIHR5cGVuYW1lIElUUj4KK3N0YXRpYyBpbmxpbmUKK3ZvaWQgU3BsaXRTdHJpbmdUb0l0ZXJhdG9yQWxsb3dFbXB0eShjb25zdCBTdHJpbmdUeXBlJiBmdWxsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIGRlbGltLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBwaWVjZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVRSJiByZXN1bHQpIHsKKyAgc3RyaW5nOjpzaXplX3R5cGUgYmVnaW5faW5kZXgsIGVuZF9pbmRleDsKKyAgYmVnaW5faW5kZXggPSAwOworCisgIGZvciAoaW50IGkgPSAwOyAoaSA8IHBpZWNlcy0xKSB8fCAocGllY2VzID09IDApOyBpKyspIHsKKyAgICBlbmRfaW5kZXggPSBmdWxsLmZpbmRfZmlyc3Rfb2YoZGVsaW0sIGJlZ2luX2luZGV4KTsKKyAgICBpZiAoZW5kX2luZGV4ID09IHN0cmluZzo6bnBvcykgeworICAgICAgKnJlc3VsdCsrID0gZnVsbC5zdWJzdHIoYmVnaW5faW5kZXgpOworICAgICAgcmV0dXJuOworICAgIH0KKyAgICAqcmVzdWx0KysgPSBmdWxsLnN1YnN0cihiZWdpbl9pbmRleCwgKGVuZF9pbmRleCAtIGJlZ2luX2luZGV4KSk7CisgICAgYmVnaW5faW5kZXggPSBlbmRfaW5kZXggKyAxOworICB9CisgICpyZXN1bHQrKyA9IGZ1bGwuc3Vic3RyKGJlZ2luX2luZGV4KTsKK30KKwordm9pZCBTcGxpdFN0cmluZ0FsbG93RW1wdHkoY29uc3Qgc3RyaW5nJiBmdWxsLCBjb25zdCBjaGFyKiBkZWxpbSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlY3RvcjxzdHJpbmc+KiByZXN1bHQpIHsKKyAgYmFja19pbnNlcnRfaXRlcmF0b3I8dmVjdG9yPHN0cmluZz4gPiBpdCgqcmVzdWx0KTsKKyAgU3BsaXRTdHJpbmdUb0l0ZXJhdG9yQWxsb3dFbXB0eShmdWxsLCBkZWxpbSwgMCwgaXQpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBKb2luU3RyaW5ncygpCisvLyAgICBUaGlzIG1lcmdlcyBhIHZlY3RvciBvZiBzdHJpbmcgY29tcG9uZW50cyB3aXRoIGRlbGltIGluc2VydGVkCisvLyAgICBhcyBzZXBhcmF0ZXJzIGJldHdlZW4gY29tcG9uZW50cy4KKy8vCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCit0ZW1wbGF0ZSA8Y2xhc3MgSVRFUkFUT1I+CitzdGF0aWMgdm9pZCBKb2luU3RyaW5nc0l0ZXJhdG9yKGNvbnN0IElURVJBVE9SJiBzdGFydCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgSVRFUkFUT1ImIGVuZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogZGVsaW0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyogcmVzdWx0KSB7CisgIEdPT0dMRV9DSEVDSyhyZXN1bHQgIT0gTlVMTCk7CisgIHJlc3VsdC0+Y2xlYXIoKTsKKyAgaW50IGRlbGltX2xlbmd0aCA9IHN0cmxlbihkZWxpbSk7CisKKyAgLy8gUHJlY29tcHV0ZSByZXN1bHRpbmcgbGVuZ3RoIHNvIHdlIGNhbiByZXNlcnZlKCkgbWVtb3J5IGluIG9uZSBzaG90LgorICBpbnQgbGVuZ3RoID0gMDsKKyAgZm9yIChJVEVSQVRPUiBpdGVyID0gc3RhcnQ7IGl0ZXIgIT0gZW5kOyArK2l0ZXIpIHsKKyAgICBpZiAoaXRlciAhPSBzdGFydCkgeworICAgICAgbGVuZ3RoICs9IGRlbGltX2xlbmd0aDsKKyAgICB9CisgICAgbGVuZ3RoICs9IGl0ZXItPnNpemUoKTsKKyAgfQorICByZXN1bHQtPnJlc2VydmUobGVuZ3RoKTsKKworICAvLyBOb3cgY29tYmluZSBldmVyeXRoaW5nLgorICBmb3IgKElURVJBVE9SIGl0ZXIgPSBzdGFydDsgaXRlciAhPSBlbmQ7ICsraXRlcikgeworICAgIGlmIChpdGVyICE9IHN0YXJ0KSB7CisgICAgICByZXN1bHQtPmFwcGVuZChkZWxpbSwgZGVsaW1fbGVuZ3RoKTsKKyAgICB9CisgICAgcmVzdWx0LT5hcHBlbmQoaXRlci0+ZGF0YSgpLCBpdGVyLT5zaXplKCkpOworICB9Cit9CisKK3ZvaWQgSm9pblN0cmluZ3MoY29uc3QgdmVjdG9yPHN0cmluZz4mIGNvbXBvbmVudHMsCisgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIGRlbGltLAorICAgICAgICAgICAgICAgICBzdHJpbmcgKiByZXN1bHQpIHsKKyAgSm9pblN0cmluZ3NJdGVyYXRvcihjb21wb25lbnRzLmJlZ2luKCksIGNvbXBvbmVudHMuZW5kKCksIGRlbGltLCByZXN1bHQpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBVbmVzY2FwZUNFc2NhcGVTZXF1ZW5jZXMoKQorLy8gICAgVGhpcyBkb2VzIGFsbCB0aGUgdW5lc2NhcGluZyB0aGF0IEMgZG9lczogXG9vbywgXHIsIFxuLCBldGMKKy8vICAgIFJldHVybnMgbGVuZ3RoIG9mIHJlc3VsdGluZyBzdHJpbmcuCisvLyAgICBUaGUgaW1wbGVtZW50YXRpb24gb2YgXHggcGFyc2VzIGFueSBwb3NpdGl2ZSBudW1iZXIgb2YgaGV4IGRpZ2l0cywKKy8vICAgIGJ1dCBpdCBpcyBhbiBlcnJvciBpZiB0aGUgdmFsdWUgcmVxdWlyZXMgbW9yZSB0aGFuIDggYml0cywgYW5kIHRoZQorLy8gICAgcmVzdWx0IGlzIHRydW5jYXRlZCB0byA4IGJpdHMuCisvLworLy8gICAgVGhlIHNlY29uZCBjYWxsIHN0b3JlcyBpdHMgZXJyb3JzIGluIGEgc3VwcGxpZWQgc3RyaW5nIHZlY3Rvci4KKy8vICAgIElmIHRoZSBzdHJpbmcgdmVjdG9yIHBvaW50ZXIgaXMgTlVMTCwgaXQgcmVwb3J0cyB0aGUgZXJyb3JzIHdpdGggTE9HKCkuCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyNkZWZpbmUgSVNfT0NUQUxfRElHSVQoYykgKCgoYykgPj0gJzAnKSAmJiAoKGMpIDw9ICc3JykpCisKKy8vIFByb3RvY29sIGJ1ZmZlcnMgZG9lc24ndCBldmVyIGNhcmUgYWJvdXQgZXJyb3JzLCBidXQgSSBkb24ndCB3YW50IHRvIHJlbW92ZQorLy8gdGhlIGNvZGUuCisjZGVmaW5lIExPR19TVFJJTkcoTEVWRUwsIFZFQ1RPUikgR09PR0xFX0xPR19JRihMRVZFTCwgZmFsc2UpCisKK2ludCBVbmVzY2FwZUNFc2NhcGVTZXF1ZW5jZXMoY29uc3QgY2hhciogc291cmNlLCBjaGFyKiBkZXN0KSB7CisgIHJldHVybiBVbmVzY2FwZUNFc2NhcGVTZXF1ZW5jZXMoc291cmNlLCBkZXN0LCBOVUxMKTsKK30KKworaW50IFVuZXNjYXBlQ0VzY2FwZVNlcXVlbmNlcyhjb25zdCBjaGFyKiBzb3VyY2UsIGNoYXIqIGRlc3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlY3RvcjxzdHJpbmc+ICplcnJvcnMpIHsKKyAgR09PR0xFX0RDSEVDSyhlcnJvcnMgPT0gTlVMTCkgPDwgIkVycm9yIHJlcG9ydGluZyBub3QgaW1wbGVtZW50ZWQuIjsKKworICBjaGFyKiBkID0gZGVzdDsKKyAgY29uc3QgY2hhciogcCA9IHNvdXJjZTsKKworICAvLyBTbWFsbCBvcHRpbWl6YXRpb24gZm9yIGNhc2Ugd2hlcmUgc291cmNlID0gZGVzdCBhbmQgdGhlcmUncyBubyBlc2NhcGluZworICB3aGlsZSAoIHAgPT0gZCAmJiAqcCAhPSAnXDAnICYmICpwICE9ICdcXCcgKQorICAgIHArKywgZCsrOworCisgIHdoaWxlICgqcCAhPSAnXDAnKSB7CisgICAgaWYgKCpwICE9ICdcXCcpIHsKKyAgICAgICpkKysgPSAqcCsrOworICAgIH0gZWxzZSB7CisgICAgICBzd2l0Y2ggKCAqKytwICkgeyAgICAgICAgICAgICAgICAgICAgLy8gc2tpcCBwYXN0IHRoZSAnXFwnCisgICAgICAgIGNhc2UgJ1wwJzoKKyAgICAgICAgICBMT0dfU1RSSU5HKEVSUk9SLCBlcnJvcnMpIDw8ICJTdHJpbmcgY2Fubm90IGVuZCB3aXRoIFxcIjsKKyAgICAgICAgICAqZCA9ICdcMCc7CisgICAgICAgICAgcmV0dXJuIGQgLSBkZXN0OyAgIC8vIHdlJ3JlIGRvbmUgd2l0aCBwCisgICAgICAgIGNhc2UgJ2EnOiAgKmQrKyA9ICdcYSc7ICBicmVhazsKKyAgICAgICAgY2FzZSAnYic6ICAqZCsrID0gJ1xiJzsgIGJyZWFrOworICAgICAgICBjYXNlICdmJzogICpkKysgPSAnXGYnOyAgYnJlYWs7CisgICAgICAgIGNhc2UgJ24nOiAgKmQrKyA9ICdcbic7ICBicmVhazsKKyAgICAgICAgY2FzZSAncic6ICAqZCsrID0gJ1xyJzsgIGJyZWFrOworICAgICAgICBjYXNlICd0JzogICpkKysgPSAnXHQnOyAgYnJlYWs7CisgICAgICAgIGNhc2UgJ3YnOiAgKmQrKyA9ICdcdic7ICBicmVhazsKKyAgICAgICAgY2FzZSAnXFwnOiAqZCsrID0gJ1xcJzsgIGJyZWFrOworICAgICAgICBjYXNlICc/JzogICpkKysgPSAnXD8nOyAgYnJlYWs7ICAgIC8vIFw/ICBXaG8ga25ldz8KKyAgICAgICAgY2FzZSAnXCcnOiAqZCsrID0gJ1wnJzsgIGJyZWFrOworICAgICAgICBjYXNlICciJzogICpkKysgPSAnXCInOyAgYnJlYWs7CisgICAgICAgIGNhc2UgJzAnOiBjYXNlICcxJzogY2FzZSAnMic6IGNhc2UgJzMnOiAgLy8gb2N0YWwgZGlnaXQ6IDEgdG8gMyBkaWdpdHMKKyAgICAgICAgY2FzZSAnNCc6IGNhc2UgJzUnOiBjYXNlICc2JzogY2FzZSAnNyc6IHsKKyAgICAgICAgICBjaGFyIGNoID0gKnAgLSAnMCc7CisgICAgICAgICAgaWYgKCBJU19PQ1RBTF9ESUdJVChwWzFdKSApCisgICAgICAgICAgICBjaCA9IGNoICogOCArICorK3AgLSAnMCc7CisgICAgICAgICAgaWYgKCBJU19PQ1RBTF9ESUdJVChwWzFdKSApICAgICAgLy8gc2FmZSAoYW5kIGVhc3kpIHRvIGRvIHRoaXMgdHdpY2UKKyAgICAgICAgICAgIGNoID0gY2ggKiA4ICsgKisrcCAtICcwJzsgICAgICAvLyBub3cgcG9pbnRzIGF0IGxhc3QgZGlnaXQKKyAgICAgICAgICAqZCsrID0gY2g7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgY2FzZSAneCc6IGNhc2UgJ1gnOiB7CisgICAgICAgICAgaWYgKCFpc3hkaWdpdChwWzFdKSkgeworICAgICAgICAgICAgaWYgKHBbMV0gPT0gJ1wwJykgeworICAgICAgICAgICAgICBMT0dfU1RSSU5HKEVSUk9SLCBlcnJvcnMpIDw8ICJTdHJpbmcgY2Fubm90IGVuZCB3aXRoIFxceCI7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICBMT0dfU1RSSU5HKEVSUk9SLCBlcnJvcnMpIDw8CisgICAgICAgICAgICAgICAgIlxceCBjYW5ub3QgYmUgZm9sbG93ZWQgYnkgbm9uLWhleCBkaWdpdDogXFwiIDw8ICpwIDw8IHBbMV07CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICB9CisgICAgICAgICAgdW5zaWduZWQgaW50IGNoID0gMDsKKyAgICAgICAgICBjb25zdCBjaGFyICpoZXhfc3RhcnQgPSBwOworICAgICAgICAgIHdoaWxlIChpc3hkaWdpdChwWzFdKSkgIC8vIGFyYml0cmFyaWx5IG1hbnkgaGV4IGRpZ2l0cworICAgICAgICAgICAgY2ggPSAoY2ggPDwgNCkgKyBoZXhfZGlnaXRfdG9faW50KCorK3ApOworICAgICAgICAgIGlmIChjaCA+IDB4RkYpCisgICAgICAgICAgICBMT0dfU1RSSU5HKEVSUk9SLCBlcnJvcnMpIDw8ICJWYWx1ZSBvZiAiIDw8CisgICAgICAgICAgICAgICJcXCIgPDwgc3RyaW5nKGhleF9zdGFydCwgcCsxLWhleF9zdGFydCkgPDwgIiBleGNlZWRzIDggYml0cyI7CisgICAgICAgICAgKmQrKyA9IGNoOworICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisjaWYgMCAgLy8gVE9ETyhrZW50b24pOiAgU3VwcG9ydCBcdSBhbmQgXFU/ICBSZXF1aXJlcyBydW5ldG9jaGFyKCkuCisgICAgICAgIGNhc2UgJ3UnOiB7CisgICAgICAgICAgLy8gXHVoaGhoID0+IGNvbnZlcnQgNCBoZXggZGlnaXRzIHRvIFVURi04CisgICAgICAgICAgY2hhcjMyIHJ1bmUgPSAwOworICAgICAgICAgIGNvbnN0IGNoYXIgKmhleF9zdGFydCA9IHA7CisgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA0OyArK2kpIHsKKyAgICAgICAgICAgIGlmIChpc3hkaWdpdChwWzFdKSkgeyAgLy8gTG9vayBvbmUgY2hhciBhaGVhZC4KKyAgICAgICAgICAgICAgcnVuZSA9IChydW5lIDw8IDQpICsgaGV4X2RpZ2l0X3RvX2ludCgqKytwKTsgIC8vIEFkdmFuY2UgcC4KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgIExPR19TVFJJTkcoRVJST1IsIGVycm9ycykKKyAgICAgICAgICAgICAgICA8PCAiXFx1IG11c3QgYmUgZm9sbG93ZWQgYnkgNCBoZXggZGlnaXRzOiBcXCIKKyAgICAgICAgICAgICAgICA8PCAgc3RyaW5nKGhleF9zdGFydCwgcCsxLWhleF9zdGFydCk7CisgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgIH0KKyAgICAgICAgICBkICs9IHJ1bmV0b2NoYXIoZCwgJnJ1bmUpOworICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGNhc2UgJ1UnOiB7CisgICAgICAgICAgLy8gXFVoaGhoaGhoaCA9PiBjb252ZXJ0IDggaGV4IGRpZ2l0cyB0byBVVEYtOAorICAgICAgICAgIGNoYXIzMiBydW5lID0gMDsKKyAgICAgICAgICBjb25zdCBjaGFyICpoZXhfc3RhcnQgPSBwOworICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgODsgKytpKSB7CisgICAgICAgICAgICBpZiAoaXN4ZGlnaXQocFsxXSkpIHsgIC8vIExvb2sgb25lIGNoYXIgYWhlYWQuCisgICAgICAgICAgICAgIC8vIERvbid0IGNoYW5nZSBydW5lIHVudGlsIHdlJ3JlIHN1cmUgdGhpcworICAgICAgICAgICAgICAvLyBpcyB3aXRoaW4gdGhlIFVuaWNvZGUgbGltaXQsIGJ1dCBkbyBhZHZhbmNlIHAuCisgICAgICAgICAgICAgIGNoYXIzMiBuZXdydW5lID0gKHJ1bmUgPDwgNCkgKyBoZXhfZGlnaXRfdG9faW50KCorK3ApOworICAgICAgICAgICAgICBpZiAobmV3cnVuZSA+IDB4MTBGRkZGKSB7CisgICAgICAgICAgICAgICAgTE9HX1NUUklORyhFUlJPUiwgZXJyb3JzKQorICAgICAgICAgICAgICAgICAgPDwgIlZhbHVlIG9mIFxcIgorICAgICAgICAgICAgICAgICAgPDwgc3RyaW5nKGhleF9zdGFydCwgcCArIDEgLSBoZXhfc3RhcnQpCisgICAgICAgICAgICAgICAgICA8PCAiIGV4Y2VlZHMgVW5pY29kZSBsaW1pdCAoMHgxMEZGRkYpIjsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBydW5lID0gbmV3cnVuZTsKKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgTE9HX1NUUklORyhFUlJPUiwgZXJyb3JzKQorICAgICAgICAgICAgICAgIDw8ICJcXFUgbXVzdCBiZSBmb2xsb3dlZCBieSA4IGhleCBkaWdpdHM6IFxcIgorICAgICAgICAgICAgICAgIDw8ICBzdHJpbmcoaGV4X3N0YXJ0LCBwKzEtaGV4X3N0YXJ0KTsKKyAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgfQorICAgICAgICAgIGQgKz0gcnVuZXRvY2hhcihkLCAmcnVuZSk7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyNlbmRpZgorICAgICAgICBkZWZhdWx0OgorICAgICAgICAgIExPR19TVFJJTkcoRVJST1IsIGVycm9ycykgPDwgIlVua25vd24gZXNjYXBlIHNlcXVlbmNlOiBcXCIgPDwgKnA7CisgICAgICB9CisgICAgICBwKys7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVhZCBwYXN0IGxldHRlciB3ZSBlc2NhcGVkCisgICAgfQorICB9CisgICpkID0gJ1wwJzsKKyAgcmV0dXJuIGQgLSBkZXN0OworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBVbmVzY2FwZUNFc2NhcGVTdHJpbmcoKQorLy8gICAgVGhpcyBkb2VzIHRoZSBzYW1lIHRoaW5nIGFzIFVuZXNjYXBlQ0VzY2FwZVNlcXVlbmNlcywgYnV0IGNyZWF0ZXMKKy8vICAgIGEgbmV3IHN0cmluZy4gVGhlIGNhbGxlciBkb2VzIG5vdCBuZWVkIHRvIHdvcnJ5IGFib3V0IGFsbG9jYXRpbmcKKy8vICAgIGEgZGVzdCBidWZmZXIuIFRoaXMgc2hvdWxkIGJlIHVzZWQgZm9yIG5vbiBwZXJmb3JtYW5jZSBjcml0aWNhbAorLy8gICAgdGFza3Mgc3VjaCBhcyBwcmludGluZyBkZWJ1ZyBtZXNzYWdlcy4gSXQgaXMgc2FmZSBmb3Igc3JjIGFuZCBkZXN0CisvLyAgICB0byBiZSB0aGUgc2FtZS4KKy8vCisvLyAgICBUaGUgc2Vjb25kIGNhbGwgc3RvcmVzIGl0cyBlcnJvcnMgaW4gYSBzdXBwbGllZCBzdHJpbmcgdmVjdG9yLgorLy8gICAgSWYgdGhlIHN0cmluZyB2ZWN0b3IgcG9pbnRlciBpcyBOVUxMLCBpdCByZXBvcnRzIHRoZSBlcnJvcnMgd2l0aCBMT0coKS4KKy8vCisvLyAgICBJbiB0aGUgZmlyc3QgYW5kIHNlY29uZCBjYWxscywgdGhlIGxlbmd0aCBvZiBkZXN0IGlzIHJldHVybmVkLiBJbiB0aGUKKy8vICAgIHRoZSB0aGlyZCBjYWxsLCB0aGUgbmV3IHN0cmluZyBpcyByZXR1cm5lZC4KKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK2ludCBVbmVzY2FwZUNFc2NhcGVTdHJpbmcoY29uc3Qgc3RyaW5nJiBzcmMsIHN0cmluZyogZGVzdCkgeworICByZXR1cm4gVW5lc2NhcGVDRXNjYXBlU3RyaW5nKHNyYywgZGVzdCwgTlVMTCk7Cit9CisKK2ludCBVbmVzY2FwZUNFc2NhcGVTdHJpbmcoY29uc3Qgc3RyaW5nJiBzcmMsIHN0cmluZyogZGVzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjdG9yPHN0cmluZz4gKmVycm9ycykgeworICBzY29wZWRfYXJyYXk8Y2hhcj4gdW5lc2NhcGVkKG5ldyBjaGFyW3NyYy5zaXplKCkgKyAxXSk7CisgIGludCBsZW4gPSBVbmVzY2FwZUNFc2NhcGVTZXF1ZW5jZXMoc3JjLmNfc3RyKCksIHVuZXNjYXBlZC5nZXQoKSwgZXJyb3JzKTsKKyAgR09PR0xFX0NIRUNLKGRlc3QpOworICBkZXN0LT5hc3NpZ24odW5lc2NhcGVkLmdldCgpLCBsZW4pOworICByZXR1cm4gbGVuOworfQorCitzdHJpbmcgVW5lc2NhcGVDRXNjYXBlU3RyaW5nKGNvbnN0IHN0cmluZyYgc3JjKSB7CisgIHNjb3BlZF9hcnJheTxjaGFyPiB1bmVzY2FwZWQobmV3IGNoYXJbc3JjLnNpemUoKSArIDFdKTsKKyAgaW50IGxlbiA9IFVuZXNjYXBlQ0VzY2FwZVNlcXVlbmNlcyhzcmMuY19zdHIoKSwgdW5lc2NhcGVkLmdldCgpLCBOVUxMKTsKKyAgcmV0dXJuIHN0cmluZyh1bmVzY2FwZWQuZ2V0KCksIGxlbik7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIENFc2NhcGVTdHJpbmcoKQorLy8gQ0hleEVzY2FwZVN0cmluZygpCisvLyAgICBDb3BpZXMgJ3NyYycgdG8gJ2Rlc3QnLCBlc2NhcGluZyBkYW5nZXJvdXMgY2hhcmFjdGVycyB1c2luZworLy8gICAgQy1zdHlsZSBlc2NhcGUgc2VxdWVuY2VzLiBUaGlzIGlzIHZlcnkgdXNlZnVsIGZvciBwcmVwYXJpbmcgcXVlcnkKKy8vICAgIGZsYWdzLiAnc3JjJyBhbmQgJ2Rlc3QnIHNob3VsZCBub3Qgb3ZlcmxhcC4gVGhlICdIZXgnIHZlcnNpb24gdXNlcworLy8gICAgaGV4YWRlY2ltYWwgcmF0aGVyIHRoYW4gb2N0YWwgc2VxdWVuY2VzLgorLy8gICAgUmV0dXJucyB0aGUgbnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW4gdG8gJ2Rlc3QnIChub3QgaW5jbHVkaW5nIHRoZSBcMCkKKy8vICAgIG9yIC0xIGlmIHRoZXJlIHdhcyBpbnN1ZmZpY2llbnQgc3BhY2UuCisvLworLy8gICAgQ3VycmVudGx5IG9ubHkgXG4sIFxyLCBcdCwgIiwgJywgXCBhbmQgIWlzcHJpbnQoKSBjaGFycyBhcmUgZXNjYXBlZC4KKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK2ludCBDRXNjYXBlSW50ZXJuYWwoY29uc3QgY2hhciogc3JjLCBpbnQgc3JjX2xlbiwgY2hhciogZGVzdCwKKyAgICAgICAgICAgICAgICAgICAgaW50IGRlc3RfbGVuLCBib29sIHVzZV9oZXgsIGJvb2wgdXRmOF9zYWZlKSB7CisgIGNvbnN0IGNoYXIqIHNyY19lbmQgPSBzcmMgKyBzcmNfbGVuOworICBpbnQgdXNlZCA9IDA7CisgIGJvb2wgbGFzdF9oZXhfZXNjYXBlID0gZmFsc2U7IC8vIHRydWUgaWYgbGFzdCBvdXRwdXQgY2hhciB3YXMgXHhOTgorCisgIGZvciAoOyBzcmMgPCBzcmNfZW5kOyBzcmMrKykgeworICAgIGlmIChkZXN0X2xlbiAtIHVzZWQgPCAyKSAgIC8vIE5lZWQgc3BhY2UgZm9yIHR3byBsZXR0ZXIgZXNjYXBlCisgICAgICByZXR1cm4gLTE7CisKKyAgICBib29sIGlzX2hleF9lc2NhcGUgPSBmYWxzZTsKKyAgICBzd2l0Y2ggKCpzcmMpIHsKKyAgICAgIGNhc2UgJ1xuJzogZGVzdFt1c2VkKytdID0gJ1xcJzsgZGVzdFt1c2VkKytdID0gJ24nOyAgYnJlYWs7CisgICAgICBjYXNlICdccic6IGRlc3RbdXNlZCsrXSA9ICdcXCc7IGRlc3RbdXNlZCsrXSA9ICdyJzsgIGJyZWFrOworICAgICAgY2FzZSAnXHQnOiBkZXN0W3VzZWQrK10gPSAnXFwnOyBkZXN0W3VzZWQrK10gPSAndCc7ICBicmVhazsKKyAgICAgIGNhc2UgJ1wiJzogZGVzdFt1c2VkKytdID0gJ1xcJzsgZGVzdFt1c2VkKytdID0gJ1wiJzsgYnJlYWs7CisgICAgICBjYXNlICdcJyc6IGRlc3RbdXNlZCsrXSA9ICdcXCc7IGRlc3RbdXNlZCsrXSA9ICdcJyc7IGJyZWFrOworICAgICAgY2FzZSAnXFwnOiBkZXN0W3VzZWQrK10gPSAnXFwnOyBkZXN0W3VzZWQrK10gPSAnXFwnOyBicmVhazsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIC8vIE5vdGUgdGhhdCBpZiB3ZSBlbWl0IFx4Tk4gYW5kIHRoZSBzcmMgY2hhcmFjdGVyIGFmdGVyIHRoYXQgaXMgYSBoZXgKKyAgICAgICAgLy8gZGlnaXQgdGhlbiB0aGF0IGRpZ2l0IG11c3QgYmUgZXNjYXBlZCB0b28gdG8gcHJldmVudCBpdCBiZWluZworICAgICAgICAvLyBpbnRlcnByZXRlZCBhcyBwYXJ0IG9mIHRoZSBjaGFyYWN0ZXIgY29kZSBieSBDLgorICAgICAgICBpZiAoKCF1dGY4X3NhZmUgfHwgc3RhdGljX2Nhc3Q8dWludDg+KCpzcmMpIDwgMHg4MCkgJiYKKyAgICAgICAgICAgICghaXNwcmludCgqc3JjKSB8fAorICAgICAgICAgICAgIChsYXN0X2hleF9lc2NhcGUgJiYgaXN4ZGlnaXQoKnNyYykpKSkgeworICAgICAgICAgIGlmIChkZXN0X2xlbiAtIHVzZWQgPCA0KSAvLyBuZWVkIHNwYWNlIGZvciA0IGxldHRlciBlc2NhcGUKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICBzcHJpbnRmKGRlc3QgKyB1c2VkLCAodXNlX2hleCA/ICJcXHglMDJ4IiA6ICJcXCUwM28iKSwKKyAgICAgICAgICAgICAgICAgIHN0YXRpY19jYXN0PHVpbnQ4Pigqc3JjKSk7CisgICAgICAgICAgaXNfaGV4X2VzY2FwZSA9IHVzZV9oZXg7CisgICAgICAgICAgdXNlZCArPSA0OworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGRlc3RbdXNlZCsrXSA9ICpzcmM7IGJyZWFrOworICAgICAgICB9CisgICAgfQorICAgIGxhc3RfaGV4X2VzY2FwZSA9IGlzX2hleF9lc2NhcGU7CisgIH0KKworICBpZiAoZGVzdF9sZW4gLSB1c2VkIDwgMSkgICAvLyBtYWtlIHN1cmUgdGhhdCB0aGVyZSBpcyByb29tIGZvciBcMAorICAgIHJldHVybiAtMTsKKworICBkZXN0W3VzZWRdID0gJ1wwJzsgICAvLyBkb2Vzbid0IGNvdW50IHRvd2FyZHMgcmV0dXJuIHZhbHVlIHRob3VnaAorICByZXR1cm4gdXNlZDsKK30KKworLy8gQ2FsY3VsYXRlcyB0aGUgbGVuZ3RoIG9mIHRoZSBDLXN0eWxlIGVzY2FwZWQgdmVyc2lvbiBvZiAnc3JjJy4KKy8vIEFzc3VtZXMgdGhhdCBub24tcHJpbnRhYmxlIGNoYXJhY3RlcnMgYXJlIGVzY2FwZWQgdXNpbmcgb2N0YWwgc2VxdWVuY2VzLCBhbmQKKy8vIHRoYXQgVVRGLTggYnl0ZXMgYXJlIG5vdCBoYW5kbGVkIHNwZWNpYWxseS4KK3N0YXRpYyBpbmxpbmUgc2l6ZV90IENFc2NhcGVkTGVuZ3RoKFN0cmluZ1BpZWNlIHNyYykgeworICBzdGF0aWMgY2hhciBjX2VzY2FwZWRfbGVuWzI1Nl0gPSB7CisgICAgNCwgNCwgNCwgNCwgNCwgNCwgNCwgNCwgNCwgMiwgMiwgNCwgNCwgMiwgNCwgNCwgIC8vIFx0LCBcbiwgXHIKKyAgICA0LCA0LCA0LCA0LCA0LCA0LCA0LCA0LCA0LCA0LCA0LCA0LCA0LCA0LCA0LCA0LAorICAgIDEsIDEsIDIsIDEsIDEsIDEsIDEsIDIsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsICAvLyAiLCAnCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgIC8vICcwJy4uJzknCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgIC8vICdBJy4uJ08nCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMiwgMSwgMSwgMSwgIC8vICdQJy4uJ1onLCAnXCcKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAgLy8gJ2EnLi4nbycKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCA0LCAgLy8gJ3AnLi4neicsIERFTAorICAgIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsCisgICAgNCwgNCwgNCwgNCwgNCwgNCwgNCwgNCwgNCwgNCwgNCwgNCwgNCwgNCwgNCwgNCwKKyAgICA0LCA0LCA0LCA0LCA0LCA0LCA0LCA0LCA0LCA0LCA0LCA0LCA0LCA0LCA0LCA0LAorICAgIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsCisgICAgNCwgNCwgNCwgNCwgNCwgNCwgNCwgNCwgNCwgNCwgNCwgNCwgNCwgNCwgNCwgNCwKKyAgICA0LCA0LCA0LCA0LCA0LCA0LCA0LCA0LCA0LCA0LCA0LCA0LCA0LCA0LCA0LCA0LAorICAgIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsCisgICAgNCwgNCwgNCwgNCwgNCwgNCwgNCwgNCwgNCwgNCwgNCwgNCwgNCwgNCwgNCwgNCwKKyAgfTsKKworICBzaXplX3QgZXNjYXBlZF9sZW4gPSAwOworICBmb3IgKGludCBpID0gMDsgaSA8IHNyYy5zaXplKCk7ICsraSkgeworICAgIHVuc2lnbmVkIGNoYXIgYyA9IHN0YXRpY19jYXN0PHVuc2lnbmVkIGNoYXI+KHNyY1tpXSk7CisgICAgZXNjYXBlZF9sZW4gKz0gY19lc2NhcGVkX2xlbltjXTsKKyAgfQorICByZXR1cm4gZXNjYXBlZF9sZW47Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIEVzY2FwZXMgJ3NyYycgdXNpbmcgQy1zdHlsZSBlc2NhcGUgc2VxdWVuY2VzLCBhbmQgYXBwZW5kcyB0aGUgZXNjYXBlZCBzdHJpbmcKKy8vIHRvICdkZXN0Jy4gVGhpcyB2ZXJzaW9uIGlzIGZhc3RlciB0aGFuIGNhbGxpbmcgQ0VzY2FwZUludGVybmFsIGFzIGl0IGNvbXB1dGVzCisvLyB0aGUgcmVxdWlyZWQgc3BhY2UgdXNpbmcgYSBsb29rdXAgdGFibGUsIGFuZCBhbHNvIGRvZXMgbm90IGRvIGFueSBzcGVjaWFsCisvLyBoYW5kbGluZyBmb3IgSGV4IG9yIFVURi04IGNoYXJhY3RlcnMuCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCit2b2lkIENFc2NhcGVBbmRBcHBlbmQoU3RyaW5nUGllY2Ugc3JjLCBzdHJpbmcqIGRlc3QpIHsKKyAgc2l6ZV90IGVzY2FwZWRfbGVuID0gQ0VzY2FwZWRMZW5ndGgoc3JjKTsKKyAgaWYgKGVzY2FwZWRfbGVuID09IHNyYy5zaXplKCkpIHsKKyAgICBkZXN0LT5hcHBlbmQoc3JjLmRhdGEoKSwgc3JjLnNpemUoKSk7CisgICAgcmV0dXJuOworICB9CisKKyAgc2l6ZV90IGN1cl9kZXN0X2xlbiA9IGRlc3QtPnNpemUoKTsKKyAgZGVzdC0+cmVzaXplKGN1cl9kZXN0X2xlbiArIGVzY2FwZWRfbGVuKTsKKyAgY2hhciogYXBwZW5kX3B0ciA9ICYoKmRlc3QpW2N1cl9kZXN0X2xlbl07CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBzcmMuc2l6ZSgpOyArK2kpIHsKKyAgICB1bnNpZ25lZCBjaGFyIGMgPSBzdGF0aWNfY2FzdDx1bnNpZ25lZCBjaGFyPihzcmNbaV0pOworICAgIHN3aXRjaCAoYykgeworICAgICAgY2FzZSAnXG4nOiAqYXBwZW5kX3B0cisrID0gJ1xcJzsgKmFwcGVuZF9wdHIrKyA9ICduJzsgYnJlYWs7CisgICAgICBjYXNlICdccic6ICphcHBlbmRfcHRyKysgPSAnXFwnOyAqYXBwZW5kX3B0cisrID0gJ3InOyBicmVhazsKKyAgICAgIGNhc2UgJ1x0JzogKmFwcGVuZF9wdHIrKyA9ICdcXCc7ICphcHBlbmRfcHRyKysgPSAndCc7IGJyZWFrOworICAgICAgY2FzZSAnXCInOiAqYXBwZW5kX3B0cisrID0gJ1xcJzsgKmFwcGVuZF9wdHIrKyA9ICdcIic7IGJyZWFrOworICAgICAgY2FzZSAnXCcnOiAqYXBwZW5kX3B0cisrID0gJ1xcJzsgKmFwcGVuZF9wdHIrKyA9ICdcJyc7IGJyZWFrOworICAgICAgY2FzZSAnXFwnOiAqYXBwZW5kX3B0cisrID0gJ1xcJzsgKmFwcGVuZF9wdHIrKyA9ICdcXCc7IGJyZWFrOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgaWYgKCFpc3ByaW50KGMpKSB7CisgICAgICAgICAgKmFwcGVuZF9wdHIrKyA9ICdcXCc7CisgICAgICAgICAgKmFwcGVuZF9wdHIrKyA9ICcwJyArIGMgLyA2NDsKKyAgICAgICAgICAqYXBwZW5kX3B0cisrID0gJzAnICsgKGMgJSA2NCkgLyA4OworICAgICAgICAgICphcHBlbmRfcHRyKysgPSAnMCcgKyBjICUgODsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAqYXBwZW5kX3B0cisrID0gYzsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICB9CisgIH0KK30KKworc3RyaW5nIENFc2NhcGUoY29uc3Qgc3RyaW5nJiBzcmMpIHsKKyAgc3RyaW5nIGRlc3Q7CisgIENFc2NhcGVBbmRBcHBlbmQoc3JjLCAmZGVzdCk7CisgIHJldHVybiBkZXN0OworfQorCituYW1lc3BhY2Ugc3RyaW5ncyB7CisKK3N0cmluZyBVdGY4U2FmZUNFc2NhcGUoY29uc3Qgc3RyaW5nJiBzcmMpIHsKKyAgY29uc3QgaW50IGRlc3RfbGVuZ3RoID0gc3JjLnNpemUoKSAqIDQgKyAxOyAvLyBNYXhpbXVtIHBvc3NpYmxlIGV4cGFuc2lvbgorICBzY29wZWRfYXJyYXk8Y2hhcj4gZGVzdChuZXcgY2hhcltkZXN0X2xlbmd0aF0pOworICBjb25zdCBpbnQgbGVuID0gQ0VzY2FwZUludGVybmFsKHNyYy5kYXRhKCksIHNyYy5zaXplKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzdC5nZXQoKSwgZGVzdF9sZW5ndGgsIGZhbHNlLCB0cnVlKTsKKyAgR09PR0xFX0RDSEVDS19HRShsZW4sIDApOworICByZXR1cm4gc3RyaW5nKGRlc3QuZ2V0KCksIGxlbik7Cit9CisKK3N0cmluZyBDSGV4RXNjYXBlKGNvbnN0IHN0cmluZyYgc3JjKSB7CisgIGNvbnN0IGludCBkZXN0X2xlbmd0aCA9IHNyYy5zaXplKCkgKiA0ICsgMTsgLy8gTWF4aW11bSBwb3NzaWJsZSBleHBhbnNpb24KKyAgc2NvcGVkX2FycmF5PGNoYXI+IGRlc3QobmV3IGNoYXJbZGVzdF9sZW5ndGhdKTsKKyAgY29uc3QgaW50IGxlbiA9IENFc2NhcGVJbnRlcm5hbChzcmMuZGF0YSgpLCBzcmMuc2l6ZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc3QuZ2V0KCksIGRlc3RfbGVuZ3RoLCB0cnVlLCBmYWxzZSk7CisgIEdPT0dMRV9EQ0hFQ0tfR0UobGVuLCAwKTsKKyAgcmV0dXJuIHN0cmluZyhkZXN0LmdldCgpLCBsZW4pOworfQorCit9ICAvLyBuYW1lc3BhY2Ugc3RyaW5ncworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBzdHJ0bzMyX2FkYXB0b3IoKQorLy8gc3RydG91MzJfYWRhcHRvcigpCisvLyAgICBJbXBsZW1lbnRhdGlvbiBvZiBzdHJ0b1t1XWwgcmVwbGFjZW1lbnRzIHRoYXQgaGF2ZSBpZGVudGljYWwKKy8vICAgIG92ZXJmbG93IGFuZCB1bmRlcmZsb3cgY2hhcmFjdGVyaXN0aWNzIGZvciBib3RoIElMUC0zMiBhbmQgTFAtNjQKKy8vICAgIHBsYXRmb3JtcywgaW5jbHVkaW5nIGVycm5vIHByZXNlcnZhdGlvbiBpbiBlcnJvci1mcmVlIGNhbGxzLgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitpbnQzMiBzdHJ0bzMyX2FkYXB0b3IoY29uc3QgY2hhciAqbnB0ciwgY2hhciAqKmVuZHB0ciwgaW50IGJhc2UpIHsKKyAgY29uc3QgaW50IHNhdmVkX2Vycm5vID0gZXJybm87CisgIGVycm5vID0gMDsKKyAgY29uc3QgbG9uZyByZXN1bHQgPSBzdHJ0b2wobnB0ciwgZW5kcHRyLCBiYXNlKTsKKyAgaWYgKGVycm5vID09IEVSQU5HRSAmJiByZXN1bHQgPT0gTE9OR19NSU4pIHsKKyAgICByZXR1cm4ga2ludDMybWluOworICB9IGVsc2UgaWYgKGVycm5vID09IEVSQU5HRSAmJiByZXN1bHQgPT0gTE9OR19NQVgpIHsKKyAgICByZXR1cm4ga2ludDMybWF4OworICB9IGVsc2UgaWYgKGVycm5vID09IDAgJiYgcmVzdWx0IDwga2ludDMybWluKSB7CisgICAgZXJybm8gPSBFUkFOR0U7CisgICAgcmV0dXJuIGtpbnQzMm1pbjsKKyAgfSBlbHNlIGlmIChlcnJubyA9PSAwICYmIHJlc3VsdCA+IGtpbnQzMm1heCkgeworICAgIGVycm5vID0gRVJBTkdFOworICAgIHJldHVybiBraW50MzJtYXg7CisgIH0KKyAgaWYgKGVycm5vID09IDApCisgICAgZXJybm8gPSBzYXZlZF9lcnJubzsKKyAgcmV0dXJuIHN0YXRpY19jYXN0PGludDMyPihyZXN1bHQpOworfQorCit1aW50MzIgc3RydG91MzJfYWRhcHRvcihjb25zdCBjaGFyICpucHRyLCBjaGFyICoqZW5kcHRyLCBpbnQgYmFzZSkgeworICBjb25zdCBpbnQgc2F2ZWRfZXJybm8gPSBlcnJubzsKKyAgZXJybm8gPSAwOworICBjb25zdCB1bnNpZ25lZCBsb25nIHJlc3VsdCA9IHN0cnRvdWwobnB0ciwgZW5kcHRyLCBiYXNlKTsKKyAgaWYgKGVycm5vID09IEVSQU5HRSAmJiByZXN1bHQgPT0gVUxPTkdfTUFYKSB7CisgICAgcmV0dXJuIGt1aW50MzJtYXg7CisgIH0gZWxzZSBpZiAoZXJybm8gPT0gMCAmJiByZXN1bHQgPiBrdWludDMybWF4KSB7CisgICAgZXJybm8gPSBFUkFOR0U7CisgICAgcmV0dXJuIGt1aW50MzJtYXg7CisgIH0KKyAgaWYgKGVycm5vID09IDApCisgICAgZXJybm8gPSBzYXZlZF9lcnJubzsKKyAgcmV0dXJuIHN0YXRpY19jYXN0PHVpbnQzMj4ocmVzdWx0KTsKK30KKworaW5saW5lIGJvb2wgc2FmZV9wYXJzZV9zaWduKHN0cmluZyogdGV4dCAgLyppbm91dCovLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wqIG5lZ2F0aXZlX3B0ciAgLypvdXRwdXQqLykgeworICBjb25zdCBjaGFyKiBzdGFydCA9IHRleHQtPmRhdGEoKTsKKyAgY29uc3QgY2hhciogZW5kID0gc3RhcnQgKyB0ZXh0LT5zaXplKCk7CisKKyAgLy8gQ29uc3VtZSB3aGl0ZXNwYWNlLgorICB3aGlsZSAoc3RhcnQgPCBlbmQgJiYgKHN0YXJ0WzBdID09ICcgJykpIHsKKyAgICArK3N0YXJ0OworICB9CisgIHdoaWxlIChzdGFydCA8IGVuZCAmJiAoZW5kWy0xXSA9PSAnICcpKSB7CisgICAgLS1lbmQ7CisgIH0KKyAgaWYgKHN0YXJ0ID49IGVuZCkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vIENvbnN1bWUgc2lnbi4KKyAgKm5lZ2F0aXZlX3B0ciA9IChzdGFydFswXSA9PSAnLScpOworICBpZiAoKm5lZ2F0aXZlX3B0ciB8fCBzdGFydFswXSA9PSAnKycpIHsKKyAgICArK3N0YXJ0OworICAgIGlmIChzdGFydCA+PSBlbmQpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0KKyAgKnRleHQgPSB0ZXh0LT5zdWJzdHIoc3RhcnQgLSB0ZXh0LT5kYXRhKCksIGVuZCAtIHN0YXJ0KTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK3RlbXBsYXRlPHR5cGVuYW1lIEludFR5cGU+Citib29sIHNhZmVfcGFyc2VfcG9zaXRpdmVfaW50KAorICAgIHN0cmluZyB0ZXh0LCBJbnRUeXBlKiB2YWx1ZV9wKSB7CisgIGludCBiYXNlID0gMTA7CisgIEludFR5cGUgdmFsdWUgPSAwOworICBjb25zdCBJbnRUeXBlIHZtYXggPSBzdGQ6Om51bWVyaWNfbGltaXRzPEludFR5cGU+OjptYXgoKTsKKyAgYXNzZXJ0KHZtYXggPiAwKTsKKyAgYXNzZXJ0KHZtYXggPj0gYmFzZSk7CisgIGNvbnN0IEludFR5cGUgdm1heF9vdmVyX2Jhc2UgPSB2bWF4IC8gYmFzZTsKKyAgY29uc3QgY2hhciogc3RhcnQgPSB0ZXh0LmRhdGEoKTsKKyAgY29uc3QgY2hhciogZW5kID0gc3RhcnQgKyB0ZXh0LnNpemUoKTsKKyAgLy8gbG9vcCBvdmVyIGRpZ2l0cworICBmb3IgKDsgc3RhcnQgPCBlbmQ7ICsrc3RhcnQpIHsKKyAgICB1bnNpZ25lZCBjaGFyIGMgPSBzdGF0aWNfY2FzdDx1bnNpZ25lZCBjaGFyPihzdGFydFswXSk7CisgICAgaW50IGRpZ2l0ID0gYyAtICcwJzsKKyAgICBpZiAoZGlnaXQgPj0gYmFzZSB8fCBkaWdpdCA8IDApIHsKKyAgICAgICp2YWx1ZV9wID0gdmFsdWU7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIGlmICh2YWx1ZSA+IHZtYXhfb3Zlcl9iYXNlKSB7CisgICAgICAqdmFsdWVfcCA9IHZtYXg7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIHZhbHVlICo9IGJhc2U7CisgICAgaWYgKHZhbHVlID4gdm1heCAtIGRpZ2l0KSB7CisgICAgICAqdmFsdWVfcCA9IHZtYXg7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIHZhbHVlICs9IGRpZ2l0OworICB9CisgICp2YWx1ZV9wID0gdmFsdWU7CisgIHJldHVybiB0cnVlOworfQorCit0ZW1wbGF0ZTx0eXBlbmFtZSBJbnRUeXBlPgorYm9vbCBzYWZlX3BhcnNlX25lZ2F0aXZlX2ludCgKKyAgICBjb25zdCBzdHJpbmcmIHRleHQsIEludFR5cGUqIHZhbHVlX3ApIHsKKyAgaW50IGJhc2UgPSAxMDsKKyAgSW50VHlwZSB2YWx1ZSA9IDA7CisgIGNvbnN0IEludFR5cGUgdm1pbiA9IHN0ZDo6bnVtZXJpY19saW1pdHM8SW50VHlwZT46Om1pbigpOworICBhc3NlcnQodm1pbiA8IDApOworICBhc3NlcnQodm1pbiA8PSAwIC0gYmFzZSk7CisgIEludFR5cGUgdm1pbl9vdmVyX2Jhc2UgPSB2bWluIC8gYmFzZTsKKyAgLy8gMjAwMyBjKysgc3RhbmRhcmQgW2V4cHIubXVsXQorICAvLyAiLi4uIHRoZSBzaWduIG9mIHRoZSByZW1haW5kZXIgaXMgaW1wbGVtZW50YXRpb24tZGVmaW5lZC4iCisgIC8vIEFsdGhvdWdoICh2bWluL2Jhc2UpKmJhc2UgKyB2bWluJWJhc2UgaXMgYWx3YXlzIHZtaW4uCisgIC8vIDIwMTEgYysrIHN0YW5kYXJkIHRpZ2h0ZW5zIHRoZSBzcGVjIGJ1dCB3ZSBjYW5ub3QgcmVseSBvbiBpdC4KKyAgaWYgKHZtaW4gJSBiYXNlID4gMCkgeworICAgIHZtaW5fb3Zlcl9iYXNlICs9IDE7CisgIH0KKyAgY29uc3QgY2hhciogc3RhcnQgPSB0ZXh0LmRhdGEoKTsKKyAgY29uc3QgY2hhciogZW5kID0gc3RhcnQgKyB0ZXh0LnNpemUoKTsKKyAgLy8gbG9vcCBvdmVyIGRpZ2l0cworICBmb3IgKDsgc3RhcnQgPCBlbmQ7ICsrc3RhcnQpIHsKKyAgICB1bnNpZ25lZCBjaGFyIGMgPSBzdGF0aWNfY2FzdDx1bnNpZ25lZCBjaGFyPihzdGFydFswXSk7CisgICAgaW50IGRpZ2l0ID0gYyAtICcwJzsKKyAgICBpZiAoZGlnaXQgPj0gYmFzZSB8fCBkaWdpdCA8IDApIHsKKyAgICAgICp2YWx1ZV9wID0gdmFsdWU7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIGlmICh2YWx1ZSA8IHZtaW5fb3Zlcl9iYXNlKSB7CisgICAgICAqdmFsdWVfcCA9IHZtaW47CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIHZhbHVlICo9IGJhc2U7CisgICAgaWYgKHZhbHVlIDwgdm1pbiArIGRpZ2l0KSB7CisgICAgICAqdmFsdWVfcCA9IHZtaW47CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIHZhbHVlIC09IGRpZ2l0OworICB9CisgICp2YWx1ZV9wID0gdmFsdWU7CisgIHJldHVybiB0cnVlOworfQorCit0ZW1wbGF0ZTx0eXBlbmFtZSBJbnRUeXBlPgorYm9vbCBzYWZlX2ludF9pbnRlcm5hbChzdHJpbmcgdGV4dCwgSW50VHlwZSogdmFsdWVfcCkgeworICAqdmFsdWVfcCA9IDA7CisgIGJvb2wgbmVnYXRpdmU7CisgIGlmICghc2FmZV9wYXJzZV9zaWduKCZ0ZXh0LCAmbmVnYXRpdmUpKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIGlmICghbmVnYXRpdmUpIHsKKyAgICByZXR1cm4gc2FmZV9wYXJzZV9wb3NpdGl2ZV9pbnQodGV4dCwgdmFsdWVfcCk7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIHNhZmVfcGFyc2VfbmVnYXRpdmVfaW50KHRleHQsIHZhbHVlX3ApOworICB9Cit9CisKK3RlbXBsYXRlPHR5cGVuYW1lIEludFR5cGU+Citib29sIHNhZmVfdWludF9pbnRlcm5hbChzdHJpbmcgdGV4dCwgSW50VHlwZSogdmFsdWVfcCkgeworICAqdmFsdWVfcCA9IDA7CisgIGJvb2wgbmVnYXRpdmU7CisgIGlmICghc2FmZV9wYXJzZV9zaWduKCZ0ZXh0LCAmbmVnYXRpdmUpIHx8IG5lZ2F0aXZlKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIHJldHVybiBzYWZlX3BhcnNlX3Bvc2l0aXZlX2ludCh0ZXh0LCB2YWx1ZV9wKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gRmFzdEludFRvQnVmZmVyKCkKKy8vIEZhc3RJbnQ2NFRvQnVmZmVyKCkKKy8vIEZhc3RIZXhUb0J1ZmZlcigpCisvLyBGYXN0SGV4NjRUb0J1ZmZlcigpCisvLyBGYXN0SGV4MzJUb0J1ZmZlcigpCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIE9mZnNldCBpbnRvIGJ1ZmZlciB3aGVyZSBGYXN0SW50NjRUb0J1ZmZlciBwbGFjZXMgdGhlIGVuZCBvZiBzdHJpbmcKKy8vIG51bGwgY2hhcmFjdGVyLiAgQWxzbyB1c2VkIGJ5IEZhc3RJbnQ2NFRvQnVmZmVyTGVmdC4KK3N0YXRpYyBjb25zdCBpbnQga0Zhc3RJbnQ2NFRvQnVmZmVyT2Zmc2V0ID0gMjE7CisKK2NoYXIgKkZhc3RJbnQ2NFRvQnVmZmVyKGludDY0IGksIGNoYXIqIGJ1ZmZlcikgeworICAvLyBXZSBjb3VsZCBjb2xsYXBzZSB0aGUgcG9zaXRpdmUgYW5kIG5lZ2F0aXZlIHNlY3Rpb25zLCBidXQgdGhhdAorICAvLyB3b3VsZCBiZSBzbGlnaHRseSBzbG93ZXIgZm9yIHBvc2l0aXZlIG51bWJlcnMuLi4KKyAgLy8gMjIgYnl0ZXMgaXMgZW5vdWdoIHRvIHN0b3JlIC0yKio2NCwgLTE4NDQ2NzQ0MDczNzA5NTUxNjE2LgorICBjaGFyKiBwID0gYnVmZmVyICsga0Zhc3RJbnQ2NFRvQnVmZmVyT2Zmc2V0OworICAqcC0tID0gJ1wwJzsKKyAgaWYgKGkgPj0gMCkgeworICAgIGRvIHsKKyAgICAgICpwLS0gPSAnMCcgKyBpICUgMTA7CisgICAgICBpIC89IDEwOworICAgIH0gd2hpbGUgKGkgPiAwKTsKKyAgICByZXR1cm4gcCArIDE7CisgIH0gZWxzZSB7CisgICAgLy8gT24gZGlmZmVyZW50IHBsYXRmb3JtcywgJSBhbmQgLyBoYXZlIGRpZmZlcmVudCBiZWhhdmlvcnMgZm9yCisgICAgLy8gbmVnYXRpdmUgbnVtYmVycywgc28gd2UgbmVlZCB0byBqdW1wIHRocm91Z2ggaG9vcHMgdG8gbWFrZSBzdXJlCisgICAgLy8gd2UgZG9uJ3QgZGl2aWRlIG5lZ2F0aXZlIG51bWJlcnMuCisgICAgaWYgKGkgPiAtMTApIHsKKyAgICAgIGkgPSAtaTsKKyAgICAgICpwLS0gPSAnMCcgKyBpOworICAgICAgKnAgPSAnLSc7CisgICAgICByZXR1cm4gcDsKKyAgICB9IGVsc2UgeworICAgICAgLy8gTWFrZSBzdXJlIHdlIGFyZW4ndCBhdCBNSU5fSU5ULCBpbiB3aGljaCBjYXNlIHdlIGNhbid0IHNheSBpID0gLWkKKyAgICAgIGkgPSBpICsgMTA7CisgICAgICBpID0gLWk7CisgICAgICAqcC0tID0gJzAnICsgaSAlIDEwOworICAgICAgLy8gVW5kbyB3aGF0IHdlIGRpZCBhIG1vbWVudCBhZ28KKyAgICAgIGkgPSBpIC8gMTAgKyAxOworICAgICAgZG8geworICAgICAgICAqcC0tID0gJzAnICsgaSAlIDEwOworICAgICAgICBpIC89IDEwOworICAgICAgfSB3aGlsZSAoaSA+IDApOworICAgICAgKnAgPSAnLSc7CisgICAgICByZXR1cm4gcDsKKyAgICB9CisgIH0KK30KKworLy8gT2Zmc2V0IGludG8gYnVmZmVyIHdoZXJlIEZhc3RJbnQzMlRvQnVmZmVyIHBsYWNlcyB0aGUgZW5kIG9mIHN0cmluZworLy8gbnVsbCBjaGFyYWN0ZXIuICBBbHNvIHVzZWQgYnkgRmFzdEludDMyVG9CdWZmZXJMZWZ0CitzdGF0aWMgY29uc3QgaW50IGtGYXN0SW50MzJUb0J1ZmZlck9mZnNldCA9IDExOworCisvLyBZZXMsIHRoaXMgaXMgYSBkdXBsaWNhdGUgb2YgRmFzdEludDY0VG9CdWZmZXIuICBCdXQsIHdlIG5lZWQgdGhpcyBmb3IgdGhlCisvLyBjb21waWxlciB0byBnZW5lcmF0ZSAzMiBiaXQgYXJpdGhtZXRpYyBpbnN0cnVjdGlvbnMuICBJdCdzIG11Y2ggZmFzdGVyLCBhdAorLy8gbGVhc3Qgd2l0aCAzMiBiaXQgYmluYXJpZXMuCitjaGFyICpGYXN0SW50MzJUb0J1ZmZlcihpbnQzMiBpLCBjaGFyKiBidWZmZXIpIHsKKyAgLy8gV2UgY291bGQgY29sbGFwc2UgdGhlIHBvc2l0aXZlIGFuZCBuZWdhdGl2ZSBzZWN0aW9ucywgYnV0IHRoYXQKKyAgLy8gd291bGQgYmUgc2xpZ2h0bHkgc2xvd2VyIGZvciBwb3NpdGl2ZSBudW1iZXJzLi4uCisgIC8vIDEyIGJ5dGVzIGlzIGVub3VnaCB0byBzdG9yZSAtMioqMzIsIC00Mjk0OTY3Mjk2LgorICBjaGFyKiBwID0gYnVmZmVyICsga0Zhc3RJbnQzMlRvQnVmZmVyT2Zmc2V0OworICAqcC0tID0gJ1wwJzsKKyAgaWYgKGkgPj0gMCkgeworICAgIGRvIHsKKyAgICAgICpwLS0gPSAnMCcgKyBpICUgMTA7CisgICAgICBpIC89IDEwOworICAgIH0gd2hpbGUgKGkgPiAwKTsKKyAgICByZXR1cm4gcCArIDE7CisgIH0gZWxzZSB7CisgICAgLy8gT24gZGlmZmVyZW50IHBsYXRmb3JtcywgJSBhbmQgLyBoYXZlIGRpZmZlcmVudCBiZWhhdmlvcnMgZm9yCisgICAgLy8gbmVnYXRpdmUgbnVtYmVycywgc28gd2UgbmVlZCB0byBqdW1wIHRocm91Z2ggaG9vcHMgdG8gbWFrZSBzdXJlCisgICAgLy8gd2UgZG9uJ3QgZGl2aWRlIG5lZ2F0aXZlIG51bWJlcnMuCisgICAgaWYgKGkgPiAtMTApIHsKKyAgICAgIGkgPSAtaTsKKyAgICAgICpwLS0gPSAnMCcgKyBpOworICAgICAgKnAgPSAnLSc7CisgICAgICByZXR1cm4gcDsKKyAgICB9IGVsc2UgeworICAgICAgLy8gTWFrZSBzdXJlIHdlIGFyZW4ndCBhdCBNSU5fSU5ULCBpbiB3aGljaCBjYXNlIHdlIGNhbid0IHNheSBpID0gLWkKKyAgICAgIGkgPSBpICsgMTA7CisgICAgICBpID0gLWk7CisgICAgICAqcC0tID0gJzAnICsgaSAlIDEwOworICAgICAgLy8gVW5kbyB3aGF0IHdlIGRpZCBhIG1vbWVudCBhZ28KKyAgICAgIGkgPSBpIC8gMTAgKyAxOworICAgICAgZG8geworICAgICAgICAqcC0tID0gJzAnICsgaSAlIDEwOworICAgICAgICBpIC89IDEwOworICAgICAgfSB3aGlsZSAoaSA+IDApOworICAgICAgKnAgPSAnLSc7CisgICAgICByZXR1cm4gcDsKKyAgICB9CisgIH0KK30KKworY2hhciAqRmFzdEhleFRvQnVmZmVyKGludCBpLCBjaGFyKiBidWZmZXIpIHsKKyAgR09PR0xFX0NIRUNLKGkgPj0gMCkgPDwgIkZhc3RIZXhUb0J1ZmZlcigpIHdhbnRzIG5vbi1uZWdhdGl2ZSBpbnRlZ2Vycywgbm90ICIgPDwgaTsKKworICBzdGF0aWMgY29uc3QgY2hhciAqaGV4ZGlnaXRzID0gIjAxMjM0NTY3ODlhYmNkZWYiOworICBjaGFyICpwID0gYnVmZmVyICsgMjE7CisgICpwLS0gPSAnXDAnOworICBkbyB7CisgICAgKnAtLSA9IGhleGRpZ2l0c1tpICYgMTVdOyAgIC8vIG1vZCBieSAxNgorICAgIGkgPj49IDQ7ICAgICAgICAgICAgICAgICAgICAvLyBkaXZpZGUgYnkgMTYKKyAgfSB3aGlsZSAoaSA+IDApOworICByZXR1cm4gcCArIDE7Cit9CisKK2NoYXIgKkludGVybmFsRmFzdEhleFRvQnVmZmVyKHVpbnQ2NCB2YWx1ZSwgY2hhciogYnVmZmVyLCBpbnQgbnVtX2J5dGUpIHsKKyAgc3RhdGljIGNvbnN0IGNoYXIgKmhleGRpZ2l0cyA9ICIwMTIzNDU2Nzg5YWJjZGVmIjsKKyAgYnVmZmVyW251bV9ieXRlXSA9ICdcMCc7CisgIGZvciAoaW50IGkgPSBudW1fYnl0ZSAtIDE7IGkgPj0gMDsgaS0tKSB7CisjaWZkZWYgX01fWDY0CisgICAgLy8gTVNWQyB4NjQgcGxhdGZvcm0gaGFzIGEgYnVnIG9wdGltaXppbmcgdGhlIHVpbnQzMih2YWx1ZSkgaW4gdGhlICNlbHNlCisgICAgLy8gYmxvY2suIEdpdmVuIHRoYXQgdGhlIHVpbnQzMiBjYXN0IHdhcyB0byBpbXByb3ZlIHBlcmZvcm1hbmNlIG9uIDMyLWJpdAorICAgIC8vIHBsYXRmb3Jtcywgd2UgdXNlIDY0LWJpdCAnJicgZGlyZWN0bHkuCisgICAgYnVmZmVyW2ldID0gaGV4ZGlnaXRzW3ZhbHVlICYgMHhmXTsKKyNlbHNlCisgICAgYnVmZmVyW2ldID0gaGV4ZGlnaXRzW3VpbnQzMih2YWx1ZSkgJiAweGZdOworI2VuZGlmCisgICAgdmFsdWUgPj49IDQ7CisgIH0KKyAgcmV0dXJuIGJ1ZmZlcjsKK30KKworY2hhciAqRmFzdEhleDY0VG9CdWZmZXIodWludDY0IHZhbHVlLCBjaGFyKiBidWZmZXIpIHsKKyAgcmV0dXJuIEludGVybmFsRmFzdEhleFRvQnVmZmVyKHZhbHVlLCBidWZmZXIsIDE2KTsKK30KKworY2hhciAqRmFzdEhleDMyVG9CdWZmZXIodWludDMyIHZhbHVlLCBjaGFyKiBidWZmZXIpIHsKKyAgcmV0dXJuIEludGVybmFsRmFzdEhleFRvQnVmZmVyKHZhbHVlLCBidWZmZXIsIDgpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBGYXN0SW50MzJUb0J1ZmZlckxlZnQoKQorLy8gRmFzdFVJbnQzMlRvQnVmZmVyTGVmdCgpCisvLyBGYXN0SW50NjRUb0J1ZmZlckxlZnQoKQorLy8gRmFzdFVJbnQ2NFRvQnVmZmVyTGVmdCgpCisvLworLy8gTGlrZSB0aGUgRmFzdCpUb0J1ZmZlcigpIGZ1bmN0aW9ucyBhYm92ZSwgdGhlc2UgYXJlIGludGVuZGVkIGZvciBzcGVlZC4KKy8vIFVubGlrZSB0aGUgRmFzdCpUb0J1ZmZlcigpIGZ1bmN0aW9ucywgaG93ZXZlciwgdGhlc2UgZnVuY3Rpb25zIHdyaXRlCisvLyB0aGVpciBvdXRwdXQgdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgYnVmZmVyIChoZW5jZSB0aGUgbmFtZSwgYXMgdGhlCisvLyBvdXRwdXQgaXMgbGVmdC1hbGlnbmVkKS4gIFRoZSBjYWxsZXIgaXMgcmVzcG9uc2libGUgZm9yIGVuc3VyaW5nIHRoYXQKKy8vIHRoZSBidWZmZXIgaGFzIGVub3VnaCBzcGFjZSB0byBob2xkIHRoZSBvdXRwdXQuCisvLworLy8gUmV0dXJucyBhIHBvaW50ZXIgdG8gdGhlIGVuZCBvZiB0aGUgc3RyaW5nIChpLmUuIHRoZSBudWxsIGNoYXJhY3RlcgorLy8gdGVybWluYXRpbmcgdGhlIHN0cmluZykuCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3N0YXRpYyBjb25zdCBjaGFyIHR3b19BU0NJSV9kaWdpdHNbMTAwXVsyXSA9IHsKKyAgeycwJywnMCd9LCB7JzAnLCcxJ30sIHsnMCcsJzInfSwgeycwJywnMyd9LCB7JzAnLCc0J30sCisgIHsnMCcsJzUnfSwgeycwJywnNid9LCB7JzAnLCc3J30sIHsnMCcsJzgnfSwgeycwJywnOSd9LAorICB7JzEnLCcwJ30sIHsnMScsJzEnfSwgeycxJywnMid9LCB7JzEnLCczJ30sIHsnMScsJzQnfSwKKyAgeycxJywnNSd9LCB7JzEnLCc2J30sIHsnMScsJzcnfSwgeycxJywnOCd9LCB7JzEnLCc5J30sCisgIHsnMicsJzAnfSwgeycyJywnMSd9LCB7JzInLCcyJ30sIHsnMicsJzMnfSwgeycyJywnNCd9LAorICB7JzInLCc1J30sIHsnMicsJzYnfSwgeycyJywnNyd9LCB7JzInLCc4J30sIHsnMicsJzknfSwKKyAgeyczJywnMCd9LCB7JzMnLCcxJ30sIHsnMycsJzInfSwgeyczJywnMyd9LCB7JzMnLCc0J30sCisgIHsnMycsJzUnfSwgeyczJywnNid9LCB7JzMnLCc3J30sIHsnMycsJzgnfSwgeyczJywnOSd9LAorICB7JzQnLCcwJ30sIHsnNCcsJzEnfSwgeyc0JywnMid9LCB7JzQnLCczJ30sIHsnNCcsJzQnfSwKKyAgeyc0JywnNSd9LCB7JzQnLCc2J30sIHsnNCcsJzcnfSwgeyc0JywnOCd9LCB7JzQnLCc5J30sCisgIHsnNScsJzAnfSwgeyc1JywnMSd9LCB7JzUnLCcyJ30sIHsnNScsJzMnfSwgeyc1JywnNCd9LAorICB7JzUnLCc1J30sIHsnNScsJzYnfSwgeyc1JywnNyd9LCB7JzUnLCc4J30sIHsnNScsJzknfSwKKyAgeyc2JywnMCd9LCB7JzYnLCcxJ30sIHsnNicsJzInfSwgeyc2JywnMyd9LCB7JzYnLCc0J30sCisgIHsnNicsJzUnfSwgeyc2JywnNid9LCB7JzYnLCc3J30sIHsnNicsJzgnfSwgeyc2JywnOSd9LAorICB7JzcnLCcwJ30sIHsnNycsJzEnfSwgeyc3JywnMid9LCB7JzcnLCczJ30sIHsnNycsJzQnfSwKKyAgeyc3JywnNSd9LCB7JzcnLCc2J30sIHsnNycsJzcnfSwgeyc3JywnOCd9LCB7JzcnLCc5J30sCisgIHsnOCcsJzAnfSwgeyc4JywnMSd9LCB7JzgnLCcyJ30sIHsnOCcsJzMnfSwgeyc4JywnNCd9LAorICB7JzgnLCc1J30sIHsnOCcsJzYnfSwgeyc4JywnNyd9LCB7JzgnLCc4J30sIHsnOCcsJzknfSwKKyAgeyc5JywnMCd9LCB7JzknLCcxJ30sIHsnOScsJzInfSwgeyc5JywnMyd9LCB7JzknLCc0J30sCisgIHsnOScsJzUnfSwgeyc5JywnNid9LCB7JzknLCc3J30sIHsnOScsJzgnfSwgeyc5JywnOSd9Cit9OworCitjaGFyKiBGYXN0VUludDMyVG9CdWZmZXJMZWZ0KHVpbnQzMiB1LCBjaGFyKiBidWZmZXIpIHsKKyAgaW50IGRpZ2l0czsKKyAgY29uc3QgY2hhciAqQVNDSUlfZGlnaXRzID0gTlVMTDsKKyAgLy8gVGhlIGlkZWEgb2YgdGhpcyBpbXBsZW1lbnRhdGlvbiBpcyB0byB0cmltIHRoZSBudW1iZXIgb2YgZGl2aWRlcyB0byBhcyBmZXcKKyAgLy8gYXMgcG9zc2libGUgYnkgdXNpbmcgbXVsdGlwbGljYXRpb24gYW5kIHN1YnRyYWN0aW9uIHJhdGhlciB0aGFuIG1vZCAoJSksCisgIC8vIGFuZCBieSBvdXRwdXR0aW5nIHR3byBkaWdpdHMgYXQgYSB0aW1lIHJhdGhlciB0aGFuIG9uZS4KKyAgLy8gVGhlIGh1Z2UtbnVtYmVyIGNhc2UgaXMgZmlyc3QsIGluIHRoZSBob3BlcyB0aGF0IHRoZSBjb21waWxlciB3aWxsIG91dHB1dAorICAvLyB0aGF0IGNhc2UgaW4gb25lIGJyYW5jaC1mcmVlIGJsb2NrIG9mIGNvZGUsIGFuZCBvbmx5IG91dHB1dCBjb25kaXRpb25hbAorICAvLyBicmFuY2hlcyBpbnRvIGl0IGZyb20gYmVsb3cuCisgIGlmICh1ID49IDEwMDAwMDAwMDApIHsgIC8vID49IDEsMDAwLDAwMCwwMDAKKyAgICBkaWdpdHMgPSB1IC8gMTAwMDAwMDAwOyAgLy8gMTAwLDAwMCwwMDAKKyAgICBBU0NJSV9kaWdpdHMgPSB0d29fQVNDSUlfZGlnaXRzW2RpZ2l0c107CisgICAgYnVmZmVyWzBdID0gQVNDSUlfZGlnaXRzWzBdOworICAgIGJ1ZmZlclsxXSA9IEFTQ0lJX2RpZ2l0c1sxXTsKKyAgICBidWZmZXIgKz0gMjsKK3N1Ymx0MTAwXzAwMF8wMDA6CisgICAgdSAtPSBkaWdpdHMgKiAxMDAwMDAwMDA7ICAvLyAxMDAsMDAwLDAwMAorbHQxMDBfMDAwXzAwMDoKKyAgICBkaWdpdHMgPSB1IC8gMTAwMDAwMDsgIC8vIDEsMDAwLDAwMAorICAgIEFTQ0lJX2RpZ2l0cyA9IHR3b19BU0NJSV9kaWdpdHNbZGlnaXRzXTsKKyAgICBidWZmZXJbMF0gPSBBU0NJSV9kaWdpdHNbMF07CisgICAgYnVmZmVyWzFdID0gQVNDSUlfZGlnaXRzWzFdOworICAgIGJ1ZmZlciArPSAyOworc3VibHQxXzAwMF8wMDA6CisgICAgdSAtPSBkaWdpdHMgKiAxMDAwMDAwOyAgLy8gMSwwMDAsMDAwCitsdDFfMDAwXzAwMDoKKyAgICBkaWdpdHMgPSB1IC8gMTAwMDA7ICAvLyAxMCwwMDAKKyAgICBBU0NJSV9kaWdpdHMgPSB0d29fQVNDSUlfZGlnaXRzW2RpZ2l0c107CisgICAgYnVmZmVyWzBdID0gQVNDSUlfZGlnaXRzWzBdOworICAgIGJ1ZmZlclsxXSA9IEFTQ0lJX2RpZ2l0c1sxXTsKKyAgICBidWZmZXIgKz0gMjsKK3N1Ymx0MTBfMDAwOgorICAgIHUgLT0gZGlnaXRzICogMTAwMDA7ICAvLyAxMCwwMDAKK2x0MTBfMDAwOgorICAgIGRpZ2l0cyA9IHUgLyAxMDA7CisgICAgQVNDSUlfZGlnaXRzID0gdHdvX0FTQ0lJX2RpZ2l0c1tkaWdpdHNdOworICAgIGJ1ZmZlclswXSA9IEFTQ0lJX2RpZ2l0c1swXTsKKyAgICBidWZmZXJbMV0gPSBBU0NJSV9kaWdpdHNbMV07CisgICAgYnVmZmVyICs9IDI7CitzdWJsdDEwMDoKKyAgICB1IC09IGRpZ2l0cyAqIDEwMDsKK2x0MTAwOgorICAgIGRpZ2l0cyA9IHU7CisgICAgQVNDSUlfZGlnaXRzID0gdHdvX0FTQ0lJX2RpZ2l0c1tkaWdpdHNdOworICAgIGJ1ZmZlclswXSA9IEFTQ0lJX2RpZ2l0c1swXTsKKyAgICBidWZmZXJbMV0gPSBBU0NJSV9kaWdpdHNbMV07CisgICAgYnVmZmVyICs9IDI7Citkb25lOgorICAgICpidWZmZXIgPSAwOworICAgIHJldHVybiBidWZmZXI7CisgIH0KKworICBpZiAodSA8IDEwMCkgeworICAgIGRpZ2l0cyA9IHU7CisgICAgaWYgKHUgPj0gMTApIGdvdG8gbHQxMDA7CisgICAgKmJ1ZmZlcisrID0gJzAnICsgZGlnaXRzOworICAgIGdvdG8gZG9uZTsKKyAgfQorICBpZiAodSAgPCAgMTAwMDApIHsgICAvLyAxMCwwMDAKKyAgICBpZiAodSA+PSAxMDAwKSBnb3RvIGx0MTBfMDAwOworICAgIGRpZ2l0cyA9IHUgLyAxMDA7CisgICAgKmJ1ZmZlcisrID0gJzAnICsgZGlnaXRzOworICAgIGdvdG8gc3VibHQxMDA7CisgIH0KKyAgaWYgKHUgIDwgIDEwMDAwMDApIHsgICAvLyAxLDAwMCwwMDAKKyAgICBpZiAodSA+PSAxMDAwMDApIGdvdG8gbHQxXzAwMF8wMDA7CisgICAgZGlnaXRzID0gdSAvIDEwMDAwOyAgLy8gICAgMTAsMDAwCisgICAgKmJ1ZmZlcisrID0gJzAnICsgZGlnaXRzOworICAgIGdvdG8gc3VibHQxMF8wMDA7CisgIH0KKyAgaWYgKHUgIDwgIDEwMDAwMDAwMCkgeyAgIC8vIDEwMCwwMDAsMDAwCisgICAgaWYgKHUgPj0gMTAwMDAwMDApIGdvdG8gbHQxMDBfMDAwXzAwMDsKKyAgICBkaWdpdHMgPSB1IC8gMTAwMDAwMDsgIC8vICAgMSwwMDAsMDAwCisgICAgKmJ1ZmZlcisrID0gJzAnICsgZGlnaXRzOworICAgIGdvdG8gc3VibHQxXzAwMF8wMDA7CisgIH0KKyAgLy8gd2UgYWxyZWFkeSBrbm93IHRoYXQgdSA8IDEsMDAwLDAwMCwwMDAKKyAgZGlnaXRzID0gdSAvIDEwMDAwMDAwMDsgICAvLyAxMDAsMDAwLDAwMAorICAqYnVmZmVyKysgPSAnMCcgKyBkaWdpdHM7CisgIGdvdG8gc3VibHQxMDBfMDAwXzAwMDsKK30KKworY2hhciogRmFzdEludDMyVG9CdWZmZXJMZWZ0KGludDMyIGksIGNoYXIqIGJ1ZmZlcikgeworICB1aW50MzIgdSA9IGk7CisgIGlmIChpIDwgMCkgeworICAgICpidWZmZXIrKyA9ICctJzsKKyAgICB1ID0gLWk7CisgIH0KKyAgcmV0dXJuIEZhc3RVSW50MzJUb0J1ZmZlckxlZnQodSwgYnVmZmVyKTsKK30KKworY2hhciogRmFzdFVJbnQ2NFRvQnVmZmVyTGVmdCh1aW50NjQgdTY0LCBjaGFyKiBidWZmZXIpIHsKKyAgaW50IGRpZ2l0czsKKyAgY29uc3QgY2hhciAqQVNDSUlfZGlnaXRzID0gTlVMTDsKKworICB1aW50MzIgdSA9IHN0YXRpY19jYXN0PHVpbnQzMj4odTY0KTsKKyAgaWYgKHUgPT0gdTY0KSByZXR1cm4gRmFzdFVJbnQzMlRvQnVmZmVyTGVmdCh1LCBidWZmZXIpOworCisgIHVpbnQ2NCB0b3BfMTFfZGlnaXRzID0gdTY0IC8gMTAwMDAwMDAwMDsKKyAgYnVmZmVyID0gRmFzdFVJbnQ2NFRvQnVmZmVyTGVmdCh0b3BfMTFfZGlnaXRzLCBidWZmZXIpOworICB1ID0gdTY0IC0gKHRvcF8xMV9kaWdpdHMgKiAxMDAwMDAwMDAwKTsKKworICBkaWdpdHMgPSB1IC8gMTAwMDAwMDA7ICAvLyAxMCwwMDAsMDAwCisgIEdPT0dMRV9EQ0hFQ0tfTFQoZGlnaXRzLCAxMDApOworICBBU0NJSV9kaWdpdHMgPSB0d29fQVNDSUlfZGlnaXRzW2RpZ2l0c107CisgIGJ1ZmZlclswXSA9IEFTQ0lJX2RpZ2l0c1swXTsKKyAgYnVmZmVyWzFdID0gQVNDSUlfZGlnaXRzWzFdOworICBidWZmZXIgKz0gMjsKKyAgdSAtPSBkaWdpdHMgKiAxMDAwMDAwMDsgIC8vIDEwLDAwMCwwMDAKKyAgZGlnaXRzID0gdSAvIDEwMDAwMDsgIC8vIDEwMCwwMDAKKyAgQVNDSUlfZGlnaXRzID0gdHdvX0FTQ0lJX2RpZ2l0c1tkaWdpdHNdOworICBidWZmZXJbMF0gPSBBU0NJSV9kaWdpdHNbMF07CisgIGJ1ZmZlclsxXSA9IEFTQ0lJX2RpZ2l0c1sxXTsKKyAgYnVmZmVyICs9IDI7CisgIHUgLT0gZGlnaXRzICogMTAwMDAwOyAgLy8gMTAwLDAwMAorICBkaWdpdHMgPSB1IC8gMTAwMDsgIC8vIDEsMDAwCisgIEFTQ0lJX2RpZ2l0cyA9IHR3b19BU0NJSV9kaWdpdHNbZGlnaXRzXTsKKyAgYnVmZmVyWzBdID0gQVNDSUlfZGlnaXRzWzBdOworICBidWZmZXJbMV0gPSBBU0NJSV9kaWdpdHNbMV07CisgIGJ1ZmZlciArPSAyOworICB1IC09IGRpZ2l0cyAqIDEwMDA7ICAvLyAxLDAwMAorICBkaWdpdHMgPSB1IC8gMTA7CisgIEFTQ0lJX2RpZ2l0cyA9IHR3b19BU0NJSV9kaWdpdHNbZGlnaXRzXTsKKyAgYnVmZmVyWzBdID0gQVNDSUlfZGlnaXRzWzBdOworICBidWZmZXJbMV0gPSBBU0NJSV9kaWdpdHNbMV07CisgIGJ1ZmZlciArPSAyOworICB1IC09IGRpZ2l0cyAqIDEwOworICBkaWdpdHMgPSB1OworICAqYnVmZmVyKysgPSAnMCcgKyBkaWdpdHM7CisgICpidWZmZXIgPSAwOworICByZXR1cm4gYnVmZmVyOworfQorCitjaGFyKiBGYXN0SW50NjRUb0J1ZmZlckxlZnQoaW50NjQgaSwgY2hhciogYnVmZmVyKSB7CisgIHVpbnQ2NCB1ID0gaTsKKyAgaWYgKGkgPCAwKSB7CisgICAgKmJ1ZmZlcisrID0gJy0nOworICAgIHUgPSAtaTsKKyAgfQorICByZXR1cm4gRmFzdFVJbnQ2NFRvQnVmZmVyTGVmdCh1LCBidWZmZXIpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBTaW1wbGVJdG9hKCkKKy8vICAgIERlc2NyaXB0aW9uOiBjb252ZXJ0cyBhbiBpbnRlZ2VyIHRvIGEgc3RyaW5nLgorLy8KKy8vICAgIFJldHVybiB2YWx1ZTogc3RyaW5nCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3N0cmluZyBTaW1wbGVJdG9hKGludCBpKSB7CisgIGNoYXIgYnVmZmVyW2tGYXN0VG9CdWZmZXJTaXplXTsKKyAgcmV0dXJuIChzaXplb2YoaSkgPT0gNCkgPworICAgIEZhc3RJbnQzMlRvQnVmZmVyKGksIGJ1ZmZlcikgOgorICAgIEZhc3RJbnQ2NFRvQnVmZmVyKGksIGJ1ZmZlcik7Cit9CisKK3N0cmluZyBTaW1wbGVJdG9hKHVuc2lnbmVkIGludCBpKSB7CisgIGNoYXIgYnVmZmVyW2tGYXN0VG9CdWZmZXJTaXplXTsKKyAgcmV0dXJuIHN0cmluZyhidWZmZXIsIChzaXplb2YoaSkgPT0gNCkgPworICAgIEZhc3RVSW50MzJUb0J1ZmZlckxlZnQoaSwgYnVmZmVyKSA6CisgICAgRmFzdFVJbnQ2NFRvQnVmZmVyTGVmdChpLCBidWZmZXIpKTsKK30KKworc3RyaW5nIFNpbXBsZUl0b2EobG9uZyBpKSB7CisgIGNoYXIgYnVmZmVyW2tGYXN0VG9CdWZmZXJTaXplXTsKKyAgcmV0dXJuIChzaXplb2YoaSkgPT0gNCkgPworICAgIEZhc3RJbnQzMlRvQnVmZmVyKGksIGJ1ZmZlcikgOgorICAgIEZhc3RJbnQ2NFRvQnVmZmVyKGksIGJ1ZmZlcik7Cit9CisKK3N0cmluZyBTaW1wbGVJdG9hKHVuc2lnbmVkIGxvbmcgaSkgeworICBjaGFyIGJ1ZmZlcltrRmFzdFRvQnVmZmVyU2l6ZV07CisgIHJldHVybiBzdHJpbmcoYnVmZmVyLCAoc2l6ZW9mKGkpID09IDQpID8KKyAgICBGYXN0VUludDMyVG9CdWZmZXJMZWZ0KGksIGJ1ZmZlcikgOgorICAgIEZhc3RVSW50NjRUb0J1ZmZlckxlZnQoaSwgYnVmZmVyKSk7Cit9CisKK3N0cmluZyBTaW1wbGVJdG9hKGxvbmcgbG9uZyBpKSB7CisgIGNoYXIgYnVmZmVyW2tGYXN0VG9CdWZmZXJTaXplXTsKKyAgcmV0dXJuIChzaXplb2YoaSkgPT0gNCkgPworICAgIEZhc3RJbnQzMlRvQnVmZmVyKGksIGJ1ZmZlcikgOgorICAgIEZhc3RJbnQ2NFRvQnVmZmVyKGksIGJ1ZmZlcik7Cit9CisKK3N0cmluZyBTaW1wbGVJdG9hKHVuc2lnbmVkIGxvbmcgbG9uZyBpKSB7CisgIGNoYXIgYnVmZmVyW2tGYXN0VG9CdWZmZXJTaXplXTsKKyAgcmV0dXJuIHN0cmluZyhidWZmZXIsIChzaXplb2YoaSkgPT0gNCkgPworICAgIEZhc3RVSW50MzJUb0J1ZmZlckxlZnQoaSwgYnVmZmVyKSA6CisgICAgRmFzdFVJbnQ2NFRvQnVmZmVyTGVmdChpLCBidWZmZXIpKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gU2ltcGxlRHRvYSgpCisvLyBTaW1wbGVGdG9hKCkKKy8vIERvdWJsZVRvQnVmZmVyKCkKKy8vIEZsb2F0VG9CdWZmZXIoKQorLy8gICAgV2Ugd2FudCB0byBwcmludCB0aGUgdmFsdWUgd2l0aG91dCBsb3NpbmcgcHJlY2lzaW9uLCBidXQgd2UgYWxzbyBkbworLy8gICAgbm90IHdhbnQgdG8gcHJpbnQgbW9yZSBkaWdpdHMgdGhhbiBuZWNlc3NhcnkuICBUaGlzIHR1cm5zIG91dCB0byBiZQorLy8gICAgdHJpY2tpZXIgdGhhbiBpdCBzb3VuZHMuICBOdW1iZXJzIGxpa2UgMC4yIGNhbm5vdCBiZSByZXByZXNlbnRlZAorLy8gICAgZXhhY3RseSBpbiBiaW5hcnkuICBJZiB3ZSBwcmludCAwLjIgd2l0aCBhIHZlcnkgbGFyZ2UgcHJlY2lzaW9uLAorLy8gICAgZS5nLiAiJS41MGciLCB3ZSBnZXQgIjAuMjAwMDAwMDAwMDAwMDAwMDExMTAyMjMwMjQ2MjUxNTY1NDA0MjM2MzE2NyIuCisvLyAgICBPbiB0aGUgb3RoZXIgaGFuZCwgaWYgd2Ugc2V0IHRoZSBwcmVjaXNpb24gdG9vIGxvdywgd2UgbG9zZQorLy8gICAgc2lnbmlmaWNhbnQgZGlnaXRzIHdoZW4gcHJpbnRpbmcgbnVtYmVycyB0aGF0IGFjdHVhbGx5IG5lZWQgdGhlbS4KKy8vICAgIEl0IHR1cm5zIG91dCB0aGVyZSBpcyBubyBwcmVjaXNpb24gdmFsdWUgdGhhdCBkb2VzIHRoZSByaWdodCB0aGluZworLy8gICAgZm9yIGFsbCBudW1iZXJzLgorLy8KKy8vICAgIE91ciBzdHJhdGVneSBpcyB0byBmaXJzdCB0cnkgcHJpbnRpbmcgd2l0aCBhIHByZWNpc2lvbiB0aGF0IGlzIG5ldmVyCisvLyAgICBvdmVyLXByZWNpc2UsIHRoZW4gcGFyc2UgdGhlIHJlc3VsdCB3aXRoIHN0cnRvZCgpIHRvIHNlZSBpZiBpdAorLy8gICAgbWF0Y2hlcy4gIElmIG5vdCwgd2UgcHJpbnQgYWdhaW4gd2l0aCBhIHByZWNpc2lvbiB0aGF0IHdpbGwgYWx3YXlzCisvLyAgICBnaXZlIGEgcHJlY2lzZSByZXN1bHQsIGJ1dCBtYXkgdXNlIG1vcmUgZGlnaXRzIHRoYW4gbmVjZXNzYXJ5LgorLy8KKy8vICAgIEFuIGFyZ3VhYmx5IGJldHRlciBzdHJhdGVneSB3b3VsZCBiZSB0byB1c2UgdGhlIGFsZ29yaXRobSBkZXNjcmliZWQKKy8vICAgIGluICJIb3cgdG8gUHJpbnQgRmxvYXRpbmctUG9pbnQgTnVtYmVycyBBY2N1cmF0ZWx5IiBieSBTdGVlbGUgJgorLy8gICAgV2hpdGUsIGUuZy4gYXMgaW1wbGVtZW50ZWQgYnkgRGF2aWQgTS4gR2F5J3MgZHRvYSgpLiAgSXQgdHVybnMgb3V0LAorLy8gICAgaG93ZXZlciwgdGhhdCB0aGUgZm9sbG93aW5nIGltcGxlbWVudGF0aW9uIGlzIGFib3V0IGFzIGZhc3QgYXMKKy8vICAgIERNRydzIGNvZGUuICBGdXJ0aGVybW9yZSwgRE1HJ3MgY29kZSBsb2NrcyBtdXRleGVzLCB3aGljaCBtZWFucyBpdAorLy8gICAgd2lsbCBub3Qgc2NhbGUgd2VsbCBvbiBtdWx0aS1jb3JlIG1hY2hpbmVzLiAgRE1HJ3MgY29kZSBpcyBzbGlnaHRseQorLy8gICAgbW9yZSBhY2N1cmF0ZSAoaW4gdGhhdCBpdCB3aWxsIG5ldmVyIHVzZSBtb3JlIGRpZ2l0cyB0aGFuCisvLyAgICBuZWNlc3NhcnkpLCBidXQgdGhpcyBpcyBwcm9iYWJseSBpcnJlbGV2YW50IGZvciBtb3N0IHVzZXJzLgorLy8KKy8vICAgIFJvYiBQaWtlIGFuZCBLZW4gVGhvbXBzb24gYWxzbyBoYXZlIGFuIGltcGxlbWVudGF0aW9uIG9mIGR0b2EoKSBpbgorLy8gICAgdGhpcmRfcGFydHkvZm10L2ZsdGZtdC5jYy4gIFRoZWlyIGltcGxlbWVudGF0aW9uIGlzIHNpbWlsYXIgdG8gdGhpcworLy8gICAgb25lIGluIHRoYXQgaXQgbWFrZXMgZ3Vlc3NlcyBhbmQgdGhlbiB1c2VzIHN0cnRvZCgpIHRvIGNoZWNrIHRoZW0uCisvLyAgICBUaGVpciBpbXBsZW1lbnRhdGlvbiBpcyBmYXN0ZXIgYmVjYXVzZSB0aGV5IHVzZSB0aGVpciBvd24gY29kZSB0bworLy8gICAgZ2VuZXJhdGUgdGhlIGRpZ2l0cyBpbiB0aGUgZmlyc3QgcGxhY2UgcmF0aGVyIHRoYW4gdXNlIHNucHJpbnRmKCksCisvLyAgICB0aHVzIGF2b2lkaW5nIGZvcm1hdCBzdHJpbmcgcGFyc2luZyBvdmVyaGVhZC4gIEhvd2V2ZXIsIHRoaXMgbWFrZXMKKy8vICAgIGl0IGNvbnNpZGVyYWJseSBtb3JlIGNvbXBsaWNhdGVkIHRoYW4gdGhlIGZvbGxvd2luZyBpbXBsZW1lbnRhdGlvbiwKKy8vICAgIGFuZCBpdCBpcyBlbWJlZGRlZCBpbiBhIGxhcmdlciBsaWJyYXJ5LiAgSWYgc3BlZWQgdHVybnMgb3V0IHRvIGJlCisvLyAgICBhbiBpc3N1ZSwgd2UgY291bGQgcmUtaW1wbGVtZW50IHRoaXMgaW4gdGVybXMgb2YgdGhlaXIKKy8vICAgIGltcGxlbWVudGF0aW9uLgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitzdHJpbmcgU2ltcGxlRHRvYShkb3VibGUgdmFsdWUpIHsKKyAgY2hhciBidWZmZXJba0RvdWJsZVRvQnVmZmVyU2l6ZV07CisgIHJldHVybiBEb3VibGVUb0J1ZmZlcih2YWx1ZSwgYnVmZmVyKTsKK30KKworc3RyaW5nIFNpbXBsZUZ0b2EoZmxvYXQgdmFsdWUpIHsKKyAgY2hhciBidWZmZXJba0Zsb2F0VG9CdWZmZXJTaXplXTsKKyAgcmV0dXJuIEZsb2F0VG9CdWZmZXIodmFsdWUsIGJ1ZmZlcik7Cit9CisKK3N0YXRpYyBpbmxpbmUgYm9vbCBJc1ZhbGlkRmxvYXRDaGFyKGNoYXIgYykgeworICByZXR1cm4gKCcwJyA8PSBjICYmIGMgPD0gJzknKSB8fAorICAgICAgICAgYyA9PSAnZScgfHwgYyA9PSAnRScgfHwKKyAgICAgICAgIGMgPT0gJysnIHx8IGMgPT0gJy0nOworfQorCit2b2lkIERlbG9jYWxpemVSYWRpeChjaGFyKiBidWZmZXIpIHsKKyAgLy8gRmFzdCBjaGVjazogIGlmIHRoZSBidWZmZXIgaGFzIGEgbm9ybWFsIGRlY2ltYWwgcG9pbnQsIGFzc3VtZSBubworICAvLyB0cmFuc2xhdGlvbiBpcyBuZWVkZWQuCisgIGlmIChzdHJjaHIoYnVmZmVyLCAnLicpICE9IE5VTEwpIHJldHVybjsKKworICAvLyBGaW5kIHRoZSBmaXJzdCB1bmtub3duIGNoYXJhY3Rlci4KKyAgd2hpbGUgKElzVmFsaWRGbG9hdENoYXIoKmJ1ZmZlcikpICsrYnVmZmVyOworCisgIGlmICgqYnVmZmVyID09ICdcMCcpIHsKKyAgICAvLyBObyByYWRpeCBjaGFyYWN0ZXIgZm91bmQuCisgICAgcmV0dXJuOworICB9CisKKyAgLy8gV2UgYXJlIG5vdyBwb2ludGluZyBhdCB0aGUgbG9jYWxlLXNwZWNpZmljIHJhZGl4IGNoYXJhY3Rlci4gIFJlcGxhY2UgaXQKKyAgLy8gd2l0aCAnLicuCisgICpidWZmZXIgPSAnLic7CisgICsrYnVmZmVyOworCisgIGlmICghSXNWYWxpZEZsb2F0Q2hhcigqYnVmZmVyKSAmJiAqYnVmZmVyICE9ICdcMCcpIHsKKyAgICAvLyBJdCBhcHBlYXJzIHRoZSByYWRpeCB3YXMgYSBtdWx0aS1ieXRlIGNoYXJhY3Rlci4gIFdlIG5lZWQgdG8gcmVtb3ZlIHRoZQorICAgIC8vIGV4dHJhIGJ5dGVzLgorICAgIGNoYXIqIHRhcmdldCA9IGJ1ZmZlcjsKKyAgICBkbyB7ICsrYnVmZmVyOyB9IHdoaWxlICghSXNWYWxpZEZsb2F0Q2hhcigqYnVmZmVyKSAmJiAqYnVmZmVyICE9ICdcMCcpOworICAgIG1lbW1vdmUodGFyZ2V0LCBidWZmZXIsIHN0cmxlbihidWZmZXIpICsgMSk7CisgIH0KK30KKworY2hhciogRG91YmxlVG9CdWZmZXIoZG91YmxlIHZhbHVlLCBjaGFyKiBidWZmZXIpIHsKKyAgLy8gREJMX0RJRyBpcyAxNSBmb3IgSUVFRS03NTQgZG91Ymxlcywgd2hpY2ggYXJlIHVzZWQgb24gYWxtb3N0IGFsbAorICAvLyBwbGF0Zm9ybXMgdGhlc2UgZGF5cy4gIEp1c3QgaW4gY2FzZSBzb21lIHN5c3RlbSBleGlzdHMgd2hlcmUgREJMX0RJRworICAvLyBpcyBzaWduaWZpY2FudGx5IGxhcmdlciAtLSBhbmQgcmlza3Mgb3ZlcmZsb3dpbmcgb3VyIGJ1ZmZlciAtLSB3ZSBoYXZlCisgIC8vIHRoaXMgYXNzZXJ0LgorICBHT09HTEVfQ09NUElMRV9BU1NFUlQoREJMX0RJRyA8IDIwLCBEQkxfRElHX2lzX3Rvb19iaWcpOworCisgIGlmICh2YWx1ZSA9PSBudW1lcmljX2xpbWl0czxkb3VibGU+OjppbmZpbml0eSgpKSB7CisgICAgc3RyY3B5KGJ1ZmZlciwgImluZiIpOworICAgIHJldHVybiBidWZmZXI7CisgIH0gZWxzZSBpZiAodmFsdWUgPT0gLW51bWVyaWNfbGltaXRzPGRvdWJsZT46OmluZmluaXR5KCkpIHsKKyAgICBzdHJjcHkoYnVmZmVyLCAiLWluZiIpOworICAgIHJldHVybiBidWZmZXI7CisgIH0gZWxzZSBpZiAoTWF0aExpbWl0czxkb3VibGU+OjpJc05hTih2YWx1ZSkpIHsKKyAgICBzdHJjcHkoYnVmZmVyLCAibmFuIik7CisgICAgcmV0dXJuIGJ1ZmZlcjsKKyAgfQorCisgIGludCBzbnByaW50Zl9yZXN1bHQgPQorICAgIHNucHJpbnRmKGJ1ZmZlciwga0RvdWJsZVRvQnVmZmVyU2l6ZSwgIiUuKmciLCBEQkxfRElHLCB2YWx1ZSk7CisKKyAgLy8gVGhlIHNucHJpbnRmIHNob3VsZCBuZXZlciBvdmVyZmxvdyBiZWNhdXNlIHRoZSBidWZmZXIgaXMgc2lnbmlmaWNhbnRseQorICAvLyBsYXJnZXIgdGhhbiB0aGUgcHJlY2lzaW9uIHdlIGFza2VkIGZvci4KKyAgR09PR0xFX0RDSEVDSyhzbnByaW50Zl9yZXN1bHQgPiAwICYmIHNucHJpbnRmX3Jlc3VsdCA8IGtEb3VibGVUb0J1ZmZlclNpemUpOworCisgIC8vIFdlIG5lZWQgdG8gbWFrZSBwYXJzZWRfdmFsdWUgdm9sYXRpbGUgaW4gb3JkZXIgdG8gZm9yY2UgdGhlIGNvbXBpbGVyIHRvCisgIC8vIHdyaXRlIGl0IG91dCB0byB0aGUgc3RhY2suICBPdGhlcndpc2UsIGl0IG1heSBrZWVwIHRoZSB2YWx1ZSBpbiBhCisgIC8vIHJlZ2lzdGVyLCBhbmQgaWYgaXQgZG9lcyB0aGF0LCBpdCBtYXkga2VlcCBpdCBhcyBhIGxvbmcgZG91YmxlIGluc3RlYWQKKyAgLy8gb2YgYSBkb3VibGUuICBUaGlzIGxvbmcgZG91YmxlIG1heSBoYXZlIGV4dHJhIGJpdHMgdGhhdCBtYWtlIGl0IGNvbXBhcmUKKyAgLy8gdW5lcXVhbCB0byAidmFsdWUiIGV2ZW4gdGhvdWdoIGl0IHdvdWxkIGJlIGV4YWN0bHkgZXF1YWwgaWYgaXQgd2VyZQorICAvLyB0cnVuY2F0ZWQgdG8gYSBkb3VibGUuCisgIHZvbGF0aWxlIGRvdWJsZSBwYXJzZWRfdmFsdWUgPSBzdHJ0b2QoYnVmZmVyLCBOVUxMKTsKKyAgaWYgKHBhcnNlZF92YWx1ZSAhPSB2YWx1ZSkgeworICAgIGludCBzbnByaW50Zl9yZXN1bHQgPQorICAgICAgc25wcmludGYoYnVmZmVyLCBrRG91YmxlVG9CdWZmZXJTaXplLCAiJS4qZyIsIERCTF9ESUcrMiwgdmFsdWUpOworCisgICAgLy8gU2hvdWxkIG5ldmVyIG92ZXJmbG93OyBzZWUgYWJvdmUuCisgICAgR09PR0xFX0RDSEVDSyhzbnByaW50Zl9yZXN1bHQgPiAwICYmIHNucHJpbnRmX3Jlc3VsdCA8IGtEb3VibGVUb0J1ZmZlclNpemUpOworICB9CisKKyAgRGVsb2NhbGl6ZVJhZGl4KGJ1ZmZlcik7CisgIHJldHVybiBidWZmZXI7Cit9CisKK3N0YXRpYyBpbnQgbWVtY2FzZWNtcChjb25zdCBjaGFyICpzMSwgY29uc3QgY2hhciAqczIsIHNpemVfdCBsZW4pIHsKKyAgY29uc3QgdW5zaWduZWQgY2hhciAqdXMxID0gcmVpbnRlcnByZXRfY2FzdDxjb25zdCB1bnNpZ25lZCBjaGFyICo+KHMxKTsKKyAgY29uc3QgdW5zaWduZWQgY2hhciAqdXMyID0gcmVpbnRlcnByZXRfY2FzdDxjb25zdCB1bnNpZ25lZCBjaGFyICo+KHMyKTsKKworICBmb3IgKCBpbnQgaSA9IDA7IGkgPCBsZW47IGkrKyApIHsKKyAgICBjb25zdCBpbnQgZGlmZiA9CisgICAgICBzdGF0aWNfY2FzdDxpbnQ+KHN0YXRpY19jYXN0PHVuc2lnbmVkIGNoYXI+KGFzY2lpX3RvbG93ZXIodXMxW2ldKSkpIC0KKyAgICAgIHN0YXRpY19jYXN0PGludD4oc3RhdGljX2Nhc3Q8dW5zaWduZWQgY2hhcj4oYXNjaWlfdG9sb3dlcih1czJbaV0pKSk7CisgICAgaWYgKGRpZmYgIT0gMCkgcmV0dXJuIGRpZmY7CisgIH0KKyAgcmV0dXJuIDA7Cit9CisKK2lubGluZSBib29sIENhc2VFcXVhbChTdHJpbmdQaWVjZSBzMSwgU3RyaW5nUGllY2UgczIpIHsKKyAgaWYgKHMxLnNpemUoKSAhPSBzMi5zaXplKCkpIHJldHVybiBmYWxzZTsKKyAgcmV0dXJuIG1lbWNhc2VjbXAoczEuZGF0YSgpLCBzMi5kYXRhKCksIHMxLnNpemUoKSkgPT0gMDsKK30KKworYm9vbCBzYWZlX3N0cnRvYihTdHJpbmdQaWVjZSBzdHIsIGJvb2wqIHZhbHVlKSB7CisgIEdPT0dMRV9DSEVDSyh2YWx1ZSAhPSBOVUxMKSA8PCAiTlVMTCBvdXRwdXQgYm9vbGVhbiBnaXZlbi4iOworICBpZiAoQ2FzZUVxdWFsKHN0ciwgInRydWUiKSB8fCBDYXNlRXF1YWwoc3RyLCAidCIpIHx8CisgICAgICBDYXNlRXF1YWwoc3RyLCAieWVzIikgfHwgQ2FzZUVxdWFsKHN0ciwgInkiKSB8fAorICAgICAgQ2FzZUVxdWFsKHN0ciwgIjEiKSkgeworICAgICp2YWx1ZSA9IHRydWU7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKyAgaWYgKENhc2VFcXVhbChzdHIsICJmYWxzZSIpIHx8IENhc2VFcXVhbChzdHIsICJmIikgfHwKKyAgICAgIENhc2VFcXVhbChzdHIsICJubyIpIHx8IENhc2VFcXVhbChzdHIsICJuIikgfHwKKyAgICAgIENhc2VFcXVhbChzdHIsICIwIikpIHsKKyAgICAqdmFsdWUgPSBmYWxzZTsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorICByZXR1cm4gZmFsc2U7Cit9CisKK2Jvb2wgc2FmZV9zdHJ0b2YoY29uc3QgY2hhciogc3RyLCBmbG9hdCogdmFsdWUpIHsKKyAgY2hhciogZW5kcHRyOworICBlcnJubyA9IDA7ICAvLyBlcnJubyBvbmx5IGdldHMgc2V0IG9uIGVycm9ycworI2lmIGRlZmluZWQoX1dJTjMyKSB8fCBkZWZpbmVkIChfX2hwdXgpICAvLyBoYXMgbm8gc3RydG9mKCkKKyAgKnZhbHVlID0gc3RydG9kKHN0ciwgJmVuZHB0cik7CisjZWxzZQorICAqdmFsdWUgPSBzdHJ0b2Yoc3RyLCAmZW5kcHRyKTsKKyNlbmRpZgorICByZXR1cm4gKnN0ciAhPSAwICYmICplbmRwdHIgPT0gMCAmJiBlcnJubyA9PSAwOworfQorCitib29sIHNhZmVfc3RydG9kKGNvbnN0IGNoYXIqIHN0ciwgZG91YmxlKiB2YWx1ZSkgeworICBjaGFyKiBlbmRwdHI7CisgICp2YWx1ZSA9IHN0cnRvZChzdHIsICZlbmRwdHIpOworICBpZiAoZW5kcHRyICE9IHN0cikgeworICAgIHdoaWxlIChhc2NpaV9pc3NwYWNlKCplbmRwdHIpKSArK2VuZHB0cjsKKyAgfQorICAvLyBJZ25vcmUgcmFuZ2UgZXJyb3JzIGZyb20gc3RydG9kLiAgVGhlIHZhbHVlcyBpdAorICAvLyByZXR1cm5zIG9uIHVuZGVyZmxvdyBhbmQgb3ZlcmZsb3cgYXJlIHRoZSByaWdodAorICAvLyBmYWxsYmFjayBpbiBhIHJvYnVzdCBzZXR0aW5nLgorICByZXR1cm4gKnN0ciAhPSAnXDAnICYmICplbmRwdHIgPT0gJ1wwJzsKK30KKworYm9vbCBzYWZlX3N0cnRvMzIoY29uc3Qgc3RyaW5nJiBzdHIsIGludDMyKiB2YWx1ZSkgeworICByZXR1cm4gc2FmZV9pbnRfaW50ZXJuYWwoc3RyLCB2YWx1ZSk7Cit9CisKK2Jvb2wgc2FmZV9zdHJ0b3UzMihjb25zdCBzdHJpbmcmIHN0ciwgdWludDMyKiB2YWx1ZSkgeworICByZXR1cm4gc2FmZV91aW50X2ludGVybmFsKHN0ciwgdmFsdWUpOworfQorCitib29sIHNhZmVfc3RydG82NChjb25zdCBzdHJpbmcmIHN0ciwgaW50NjQqIHZhbHVlKSB7CisgIHJldHVybiBzYWZlX2ludF9pbnRlcm5hbChzdHIsIHZhbHVlKTsKK30KKworYm9vbCBzYWZlX3N0cnRvdTY0KGNvbnN0IHN0cmluZyYgc3RyLCB1aW50NjQqIHZhbHVlKSB7CisgIHJldHVybiBzYWZlX3VpbnRfaW50ZXJuYWwoc3RyLCB2YWx1ZSk7Cit9CisKK2NoYXIqIEZsb2F0VG9CdWZmZXIoZmxvYXQgdmFsdWUsIGNoYXIqIGJ1ZmZlcikgeworICAvLyBGTFRfRElHIGlzIDYgZm9yIElFRUUtNzU0IGZsb2F0cywgd2hpY2ggYXJlIHVzZWQgb24gYWxtb3N0IGFsbAorICAvLyBwbGF0Zm9ybXMgdGhlc2UgZGF5cy4gIEp1c3QgaW4gY2FzZSBzb21lIHN5c3RlbSBleGlzdHMgd2hlcmUgRkxUX0RJRworICAvLyBpcyBzaWduaWZpY2FudGx5IGxhcmdlciAtLSBhbmQgcmlza3Mgb3ZlcmZsb3dpbmcgb3VyIGJ1ZmZlciAtLSB3ZSBoYXZlCisgIC8vIHRoaXMgYXNzZXJ0LgorICBHT09HTEVfQ09NUElMRV9BU1NFUlQoRkxUX0RJRyA8IDEwLCBGTFRfRElHX2lzX3Rvb19iaWcpOworCisgIGlmICh2YWx1ZSA9PSBudW1lcmljX2xpbWl0czxkb3VibGU+OjppbmZpbml0eSgpKSB7CisgICAgc3RyY3B5KGJ1ZmZlciwgImluZiIpOworICAgIHJldHVybiBidWZmZXI7CisgIH0gZWxzZSBpZiAodmFsdWUgPT0gLW51bWVyaWNfbGltaXRzPGRvdWJsZT46OmluZmluaXR5KCkpIHsKKyAgICBzdHJjcHkoYnVmZmVyLCAiLWluZiIpOworICAgIHJldHVybiBidWZmZXI7CisgIH0gZWxzZSBpZiAoTWF0aExpbWl0czxmbG9hdD46OklzTmFOKHZhbHVlKSkgeworICAgIHN0cmNweShidWZmZXIsICJuYW4iKTsKKyAgICByZXR1cm4gYnVmZmVyOworICB9CisKKyAgaW50IHNucHJpbnRmX3Jlc3VsdCA9CisgICAgc25wcmludGYoYnVmZmVyLCBrRmxvYXRUb0J1ZmZlclNpemUsICIlLipnIiwgRkxUX0RJRywgdmFsdWUpOworCisgIC8vIFRoZSBzbnByaW50ZiBzaG91bGQgbmV2ZXIgb3ZlcmZsb3cgYmVjYXVzZSB0aGUgYnVmZmVyIGlzIHNpZ25pZmljYW50bHkKKyAgLy8gbGFyZ2VyIHRoYW4gdGhlIHByZWNpc2lvbiB3ZSBhc2tlZCBmb3IuCisgIEdPT0dMRV9EQ0hFQ0soc25wcmludGZfcmVzdWx0ID4gMCAmJiBzbnByaW50Zl9yZXN1bHQgPCBrRmxvYXRUb0J1ZmZlclNpemUpOworCisgIGZsb2F0IHBhcnNlZF92YWx1ZTsKKyAgaWYgKCFzYWZlX3N0cnRvZihidWZmZXIsICZwYXJzZWRfdmFsdWUpIHx8IHBhcnNlZF92YWx1ZSAhPSB2YWx1ZSkgeworICAgIGludCBzbnByaW50Zl9yZXN1bHQgPQorICAgICAgc25wcmludGYoYnVmZmVyLCBrRmxvYXRUb0J1ZmZlclNpemUsICIlLipnIiwgRkxUX0RJRysyLCB2YWx1ZSk7CisKKyAgICAvLyBTaG91bGQgbmV2ZXIgb3ZlcmZsb3c7IHNlZSBhYm92ZS4KKyAgICBHT09HTEVfRENIRUNLKHNucHJpbnRmX3Jlc3VsdCA+IDAgJiYgc25wcmludGZfcmVzdWx0IDwga0Zsb2F0VG9CdWZmZXJTaXplKTsKKyAgfQorCisgIERlbG9jYWxpemVSYWRpeChidWZmZXIpOworICByZXR1cm4gYnVmZmVyOworfQorCituYW1lc3BhY2Ugc3RyaW5ncyB7CisKK0FscGhhTnVtOjpBbHBoYU51bShzdHJpbmdzOjpIZXggaGV4KSB7CisgIGNoYXIgKmNvbnN0IGVuZCA9ICZkaWdpdHNba0Zhc3RUb0J1ZmZlclNpemVdOworICBjaGFyICp3cml0ZXIgPSBlbmQ7CisgIHVpbnQ2NCB2YWx1ZSA9IGhleC52YWx1ZTsKKyAgdWludDY0IHdpZHRoID0gaGV4LnNwZWM7CisgIC8vIFdlIGFjY29tcGxpc2ggbWluaW11bSB3aWR0aCBieSBPUidpbmcgaW4gMHgxMDAwMCB0byB0aGUgdXNlcidzIHZhbHVlLAorICAvLyB3aGVyZSAweDEwMDAwIGlzIHRoZSBzbWFsbGVzdCBoZXggbnVtYmVyIHRoYXQgaXMgYXMgd2lkZSBhcyB0aGUgdXNlcgorICAvLyBhc2tlZCBmb3IuCisgIHVpbnQ2NCBtYXNrID0gKChzdGF0aWNfY2FzdDx1aW50NjQ+KDEpIDw8ICh3aWR0aCAtIDEpICogNCkpIHwgdmFsdWU7CisgIHN0YXRpYyBjb25zdCBjaGFyIGhleGRpZ2l0c1tdID0gIjAxMjM0NTY3ODlhYmNkZWYiOworICBkbyB7CisgICAgKi0td3JpdGVyID0gaGV4ZGlnaXRzW3ZhbHVlICYgMHhGXTsKKyAgICB2YWx1ZSA+Pj0gNDsKKyAgICBtYXNrID4+PSA0OworICB9IHdoaWxlIChtYXNrICE9IDApOworICBwaWVjZV9kYXRhXyA9IHdyaXRlcjsKKyAgcGllY2Vfc2l6ZV8gPSBlbmQgLSB3cml0ZXI7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBzdHJpbmdzCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIFN0ckNhdCgpCisvLyAgICBUaGlzIG1lcmdlcyB0aGUgZ2l2ZW4gc3RyaW5ncyBvciBpbnRlZ2Vycywgd2l0aCBubyBkZWxpbWl0ZXIuICBUaGlzCisvLyAgICBpcyBkZXNpZ25lZCB0byBiZSB0aGUgZmFzdGVzdCBwb3NzaWJsZSB3YXkgdG8gY29uc3RydWN0IGEgc3RyaW5nIG91dAorLy8gICAgb2YgYSBtaXggb2YgcmF3IEMgc3RyaW5ncywgQysrIHN0cmluZ3MsIGFuZCBpbnRlZ2VyIHZhbHVlcy4KKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gQXBwZW5kIGlzIG1lcmVseSBhIHZlcnNpb24gb2YgbWVtY3B5IHRoYXQgcmV0dXJucyB0aGUgYWRkcmVzcyBvZiB0aGUgYnl0ZQorLy8gYWZ0ZXIgdGhlIGFyZWEganVzdCBvdmVyd3JpdHRlbi4gIEl0IGNvbWVzIGluIG11bHRpcGxlIGZsYXZvcnMgdG8gbWluaW1pemUKKy8vIGNhbGwgb3ZlcmhlYWQuCitzdGF0aWMgY2hhciAqQXBwZW5kMShjaGFyICpvdXQsIGNvbnN0IEFscGhhTnVtICZ4KSB7CisgIG1lbWNweShvdXQsIHguZGF0YSgpLCB4LnNpemUoKSk7CisgIHJldHVybiBvdXQgKyB4LnNpemUoKTsKK30KKworc3RhdGljIGNoYXIgKkFwcGVuZDIoY2hhciAqb3V0LCBjb25zdCBBbHBoYU51bSAmeDEsIGNvbnN0IEFscGhhTnVtICZ4MikgeworICBtZW1jcHkob3V0LCB4MS5kYXRhKCksIHgxLnNpemUoKSk7CisgIG91dCArPSB4MS5zaXplKCk7CisKKyAgbWVtY3B5KG91dCwgeDIuZGF0YSgpLCB4Mi5zaXplKCkpOworICByZXR1cm4gb3V0ICsgeDIuc2l6ZSgpOworfQorCitzdGF0aWMgY2hhciAqQXBwZW5kNChjaGFyICpvdXQsCisgICAgICAgICAgICAgICAgICAgICBjb25zdCBBbHBoYU51bSAmeDEsIGNvbnN0IEFscGhhTnVtICZ4MiwKKyAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFscGhhTnVtICZ4MywgY29uc3QgQWxwaGFOdW0gJng0KSB7CisgIG1lbWNweShvdXQsIHgxLmRhdGEoKSwgeDEuc2l6ZSgpKTsKKyAgb3V0ICs9IHgxLnNpemUoKTsKKworICBtZW1jcHkob3V0LCB4Mi5kYXRhKCksIHgyLnNpemUoKSk7CisgIG91dCArPSB4Mi5zaXplKCk7CisKKyAgbWVtY3B5KG91dCwgeDMuZGF0YSgpLCB4My5zaXplKCkpOworICBvdXQgKz0geDMuc2l6ZSgpOworCisgIG1lbWNweShvdXQsIHg0LmRhdGEoKSwgeDQuc2l6ZSgpKTsKKyAgcmV0dXJuIG91dCArIHg0LnNpemUoKTsKK30KKworc3RyaW5nIFN0ckNhdChjb25zdCBBbHBoYU51bSAmYSwgY29uc3QgQWxwaGFOdW0gJmIpIHsKKyAgc3RyaW5nIHJlc3VsdDsKKyAgcmVzdWx0LnJlc2l6ZShhLnNpemUoKSArIGIuc2l6ZSgpKTsKKyAgY2hhciAqY29uc3QgYmVnaW4gPSAmKnJlc3VsdC5iZWdpbigpOworICBjaGFyICpvdXQgPSBBcHBlbmQyKGJlZ2luLCBhLCBiKTsKKyAgR09PR0xFX0RDSEVDS19FUShvdXQsIGJlZ2luICsgcmVzdWx0LnNpemUoKSk7CisgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0cmluZyBTdHJDYXQoY29uc3QgQWxwaGFOdW0gJmEsIGNvbnN0IEFscGhhTnVtICZiLCBjb25zdCBBbHBoYU51bSAmYykgeworICBzdHJpbmcgcmVzdWx0OworICByZXN1bHQucmVzaXplKGEuc2l6ZSgpICsgYi5zaXplKCkgKyBjLnNpemUoKSk7CisgIGNoYXIgKmNvbnN0IGJlZ2luID0gJipyZXN1bHQuYmVnaW4oKTsKKyAgY2hhciAqb3V0ID0gQXBwZW5kMihiZWdpbiwgYSwgYik7CisgIG91dCA9IEFwcGVuZDEob3V0LCBjKTsKKyAgR09PR0xFX0RDSEVDS19FUShvdXQsIGJlZ2luICsgcmVzdWx0LnNpemUoKSk7CisgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0cmluZyBTdHJDYXQoY29uc3QgQWxwaGFOdW0gJmEsIGNvbnN0IEFscGhhTnVtICZiLCBjb25zdCBBbHBoYU51bSAmYywKKyAgICAgICAgICAgICAgY29uc3QgQWxwaGFOdW0gJmQpIHsKKyAgc3RyaW5nIHJlc3VsdDsKKyAgcmVzdWx0LnJlc2l6ZShhLnNpemUoKSArIGIuc2l6ZSgpICsgYy5zaXplKCkgKyBkLnNpemUoKSk7CisgIGNoYXIgKmNvbnN0IGJlZ2luID0gJipyZXN1bHQuYmVnaW4oKTsKKyAgY2hhciAqb3V0ID0gQXBwZW5kNChiZWdpbiwgYSwgYiwgYywgZCk7CisgIEdPT0dMRV9EQ0hFQ0tfRVEob3V0LCBiZWdpbiArIHJlc3VsdC5zaXplKCkpOworICByZXR1cm4gcmVzdWx0OworfQorCitzdHJpbmcgU3RyQ2F0KGNvbnN0IEFscGhhTnVtICZhLCBjb25zdCBBbHBoYU51bSAmYiwgY29uc3QgQWxwaGFOdW0gJmMsCisgICAgICAgICAgICAgIGNvbnN0IEFscGhhTnVtICZkLCBjb25zdCBBbHBoYU51bSAmZSkgeworICBzdHJpbmcgcmVzdWx0OworICByZXN1bHQucmVzaXplKGEuc2l6ZSgpICsgYi5zaXplKCkgKyBjLnNpemUoKSArIGQuc2l6ZSgpICsgZS5zaXplKCkpOworICBjaGFyICpjb25zdCBiZWdpbiA9ICYqcmVzdWx0LmJlZ2luKCk7CisgIGNoYXIgKm91dCA9IEFwcGVuZDQoYmVnaW4sIGEsIGIsIGMsIGQpOworICBvdXQgPSBBcHBlbmQxKG91dCwgZSk7CisgIEdPT0dMRV9EQ0hFQ0tfRVEob3V0LCBiZWdpbiArIHJlc3VsdC5zaXplKCkpOworICByZXR1cm4gcmVzdWx0OworfQorCitzdHJpbmcgU3RyQ2F0KGNvbnN0IEFscGhhTnVtICZhLCBjb25zdCBBbHBoYU51bSAmYiwgY29uc3QgQWxwaGFOdW0gJmMsCisgICAgICAgICAgICAgIGNvbnN0IEFscGhhTnVtICZkLCBjb25zdCBBbHBoYU51bSAmZSwgY29uc3QgQWxwaGFOdW0gJmYpIHsKKyAgc3RyaW5nIHJlc3VsdDsKKyAgcmVzdWx0LnJlc2l6ZShhLnNpemUoKSArIGIuc2l6ZSgpICsgYy5zaXplKCkgKyBkLnNpemUoKSArIGUuc2l6ZSgpICsKKyAgICAgICAgICAgICAgICBmLnNpemUoKSk7CisgIGNoYXIgKmNvbnN0IGJlZ2luID0gJipyZXN1bHQuYmVnaW4oKTsKKyAgY2hhciAqb3V0ID0gQXBwZW5kNChiZWdpbiwgYSwgYiwgYywgZCk7CisgIG91dCA9IEFwcGVuZDIob3V0LCBlLCBmKTsKKyAgR09PR0xFX0RDSEVDS19FUShvdXQsIGJlZ2luICsgcmVzdWx0LnNpemUoKSk7CisgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0cmluZyBTdHJDYXQoY29uc3QgQWxwaGFOdW0gJmEsIGNvbnN0IEFscGhhTnVtICZiLCBjb25zdCBBbHBoYU51bSAmYywKKyAgICAgICAgICAgICAgY29uc3QgQWxwaGFOdW0gJmQsIGNvbnN0IEFscGhhTnVtICZlLCBjb25zdCBBbHBoYU51bSAmZiwKKyAgICAgICAgICAgICAgY29uc3QgQWxwaGFOdW0gJmcpIHsKKyAgc3RyaW5nIHJlc3VsdDsKKyAgcmVzdWx0LnJlc2l6ZShhLnNpemUoKSArIGIuc2l6ZSgpICsgYy5zaXplKCkgKyBkLnNpemUoKSArIGUuc2l6ZSgpICsKKyAgICAgICAgICAgICAgICBmLnNpemUoKSArIGcuc2l6ZSgpKTsKKyAgY2hhciAqY29uc3QgYmVnaW4gPSAmKnJlc3VsdC5iZWdpbigpOworICBjaGFyICpvdXQgPSBBcHBlbmQ0KGJlZ2luLCBhLCBiLCBjLCBkKTsKKyAgb3V0ID0gQXBwZW5kMihvdXQsIGUsIGYpOworICBvdXQgPSBBcHBlbmQxKG91dCwgZyk7CisgIEdPT0dMRV9EQ0hFQ0tfRVEob3V0LCBiZWdpbiArIHJlc3VsdC5zaXplKCkpOworICByZXR1cm4gcmVzdWx0OworfQorCitzdHJpbmcgU3RyQ2F0KGNvbnN0IEFscGhhTnVtICZhLCBjb25zdCBBbHBoYU51bSAmYiwgY29uc3QgQWxwaGFOdW0gJmMsCisgICAgICAgICAgICAgIGNvbnN0IEFscGhhTnVtICZkLCBjb25zdCBBbHBoYU51bSAmZSwgY29uc3QgQWxwaGFOdW0gJmYsCisgICAgICAgICAgICAgIGNvbnN0IEFscGhhTnVtICZnLCBjb25zdCBBbHBoYU51bSAmaCkgeworICBzdHJpbmcgcmVzdWx0OworICByZXN1bHQucmVzaXplKGEuc2l6ZSgpICsgYi5zaXplKCkgKyBjLnNpemUoKSArIGQuc2l6ZSgpICsgZS5zaXplKCkgKworICAgICAgICAgICAgICAgIGYuc2l6ZSgpICsgZy5zaXplKCkgKyBoLnNpemUoKSk7CisgIGNoYXIgKmNvbnN0IGJlZ2luID0gJipyZXN1bHQuYmVnaW4oKTsKKyAgY2hhciAqb3V0ID0gQXBwZW5kNChiZWdpbiwgYSwgYiwgYywgZCk7CisgIG91dCA9IEFwcGVuZDQob3V0LCBlLCBmLCBnLCBoKTsKKyAgR09PR0xFX0RDSEVDS19FUShvdXQsIGJlZ2luICsgcmVzdWx0LnNpemUoKSk7CisgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0cmluZyBTdHJDYXQoY29uc3QgQWxwaGFOdW0gJmEsIGNvbnN0IEFscGhhTnVtICZiLCBjb25zdCBBbHBoYU51bSAmYywKKyAgICAgICAgICAgICAgY29uc3QgQWxwaGFOdW0gJmQsIGNvbnN0IEFscGhhTnVtICZlLCBjb25zdCBBbHBoYU51bSAmZiwKKyAgICAgICAgICAgICAgY29uc3QgQWxwaGFOdW0gJmcsIGNvbnN0IEFscGhhTnVtICZoLCBjb25zdCBBbHBoYU51bSAmaSkgeworICBzdHJpbmcgcmVzdWx0OworICByZXN1bHQucmVzaXplKGEuc2l6ZSgpICsgYi5zaXplKCkgKyBjLnNpemUoKSArIGQuc2l6ZSgpICsgZS5zaXplKCkgKworICAgICAgICAgICAgICAgIGYuc2l6ZSgpICsgZy5zaXplKCkgKyBoLnNpemUoKSArIGkuc2l6ZSgpKTsKKyAgY2hhciAqY29uc3QgYmVnaW4gPSAmKnJlc3VsdC5iZWdpbigpOworICBjaGFyICpvdXQgPSBBcHBlbmQ0KGJlZ2luLCBhLCBiLCBjLCBkKTsKKyAgb3V0ID0gQXBwZW5kNChvdXQsIGUsIGYsIGcsIGgpOworICBvdXQgPSBBcHBlbmQxKG91dCwgaSk7CisgIEdPT0dMRV9EQ0hFQ0tfRVEob3V0LCBiZWdpbiArIHJlc3VsdC5zaXplKCkpOworICByZXR1cm4gcmVzdWx0OworfQorCisvLyBJdCdzIHBvc3NpYmxlIHRvIGNhbGwgU3RyQXBwZW5kIHdpdGggYSBjaGFyICogcG9pbnRlciB0aGF0IGlzIHBhcnR3YXkgaW50bworLy8gdGhlIHN0cmluZyB3ZSdyZSBhcHBlbmRpbmcgdG8uICBIb3dldmVyIHRoZSByZXN1bHRzIG9mIHRoaXMgYXJlIHJhbmRvbS4KKy8vIFRoZXJlZm9yZSwgY2hlY2sgZm9yIHRoaXMgaW4gZGVidWcgbW9kZS4gIFVzZSB1bnNpZ25lZCBtYXRoIHNvIHdlIG9ubHkgaGF2ZQorLy8gdG8gZG8gb25lIGNvbXBhcmlzb24uCisjZGVmaW5lIEdPT0dMRV9EQ0hFQ0tfTk9fT1ZFUkxBUChkZXN0LCBzcmMpIFwKKyAgICBHT09HTEVfRENIRUNLX0dUKHVpbnRwdHJfdCgoc3JjKS5kYXRhKCkgLSAoZGVzdCkuZGF0YSgpKSwgXAorICAgICAgICAgICAgICAgICAgICAgdWludHB0cl90KChkZXN0KS5zaXplKCkpKQorCit2b2lkIFN0ckFwcGVuZChzdHJpbmcgKnJlc3VsdCwgY29uc3QgQWxwaGFOdW0gJmEpIHsKKyAgR09PR0xFX0RDSEVDS19OT19PVkVSTEFQKCpyZXN1bHQsIGEpOworICByZXN1bHQtPmFwcGVuZChhLmRhdGEoKSwgYS5zaXplKCkpOworfQorCit2b2lkIFN0ckFwcGVuZChzdHJpbmcgKnJlc3VsdCwgY29uc3QgQWxwaGFOdW0gJmEsIGNvbnN0IEFscGhhTnVtICZiKSB7CisgIEdPT0dMRV9EQ0hFQ0tfTk9fT1ZFUkxBUCgqcmVzdWx0LCBhKTsKKyAgR09PR0xFX0RDSEVDS19OT19PVkVSTEFQKCpyZXN1bHQsIGIpOworICBzdHJpbmc6OnNpemVfdHlwZSBvbGRfc2l6ZSA9IHJlc3VsdC0+c2l6ZSgpOworICByZXN1bHQtPnJlc2l6ZShvbGRfc2l6ZSArIGEuc2l6ZSgpICsgYi5zaXplKCkpOworICBjaGFyICpjb25zdCBiZWdpbiA9ICYqcmVzdWx0LT5iZWdpbigpOworICBjaGFyICpvdXQgPSBBcHBlbmQyKGJlZ2luICsgb2xkX3NpemUsIGEsIGIpOworICBHT09HTEVfRENIRUNLX0VRKG91dCwgYmVnaW4gKyByZXN1bHQtPnNpemUoKSk7Cit9CisKK3ZvaWQgU3RyQXBwZW5kKHN0cmluZyAqcmVzdWx0LAorICAgICAgICAgICAgICAgY29uc3QgQWxwaGFOdW0gJmEsIGNvbnN0IEFscGhhTnVtICZiLCBjb25zdCBBbHBoYU51bSAmYykgeworICBHT09HTEVfRENIRUNLX05PX09WRVJMQVAoKnJlc3VsdCwgYSk7CisgIEdPT0dMRV9EQ0hFQ0tfTk9fT1ZFUkxBUCgqcmVzdWx0LCBiKTsKKyAgR09PR0xFX0RDSEVDS19OT19PVkVSTEFQKCpyZXN1bHQsIGMpOworICBzdHJpbmc6OnNpemVfdHlwZSBvbGRfc2l6ZSA9IHJlc3VsdC0+c2l6ZSgpOworICByZXN1bHQtPnJlc2l6ZShvbGRfc2l6ZSArIGEuc2l6ZSgpICsgYi5zaXplKCkgKyBjLnNpemUoKSk7CisgIGNoYXIgKmNvbnN0IGJlZ2luID0gJipyZXN1bHQtPmJlZ2luKCk7CisgIGNoYXIgKm91dCA9IEFwcGVuZDIoYmVnaW4gKyBvbGRfc2l6ZSwgYSwgYik7CisgIG91dCA9IEFwcGVuZDEob3V0LCBjKTsKKyAgR09PR0xFX0RDSEVDS19FUShvdXQsIGJlZ2luICsgcmVzdWx0LT5zaXplKCkpOworfQorCit2b2lkIFN0ckFwcGVuZChzdHJpbmcgKnJlc3VsdCwKKyAgICAgICAgICAgICAgIGNvbnN0IEFscGhhTnVtICZhLCBjb25zdCBBbHBoYU51bSAmYiwKKyAgICAgICAgICAgICAgIGNvbnN0IEFscGhhTnVtICZjLCBjb25zdCBBbHBoYU51bSAmZCkgeworICBHT09HTEVfRENIRUNLX05PX09WRVJMQVAoKnJlc3VsdCwgYSk7CisgIEdPT0dMRV9EQ0hFQ0tfTk9fT1ZFUkxBUCgqcmVzdWx0LCBiKTsKKyAgR09PR0xFX0RDSEVDS19OT19PVkVSTEFQKCpyZXN1bHQsIGMpOworICBHT09HTEVfRENIRUNLX05PX09WRVJMQVAoKnJlc3VsdCwgZCk7CisgIHN0cmluZzo6c2l6ZV90eXBlIG9sZF9zaXplID0gcmVzdWx0LT5zaXplKCk7CisgIHJlc3VsdC0+cmVzaXplKG9sZF9zaXplICsgYS5zaXplKCkgKyBiLnNpemUoKSArIGMuc2l6ZSgpICsgZC5zaXplKCkpOworICBjaGFyICpjb25zdCBiZWdpbiA9ICYqcmVzdWx0LT5iZWdpbigpOworICBjaGFyICpvdXQgPSBBcHBlbmQ0KGJlZ2luICsgb2xkX3NpemUsIGEsIGIsIGMsIGQpOworICBHT09HTEVfRENIRUNLX0VRKG91dCwgYmVnaW4gKyByZXN1bHQtPnNpemUoKSk7Cit9CisKK2ludCBHbG9iYWxSZXBsYWNlU3Vic3RyaW5nKGNvbnN0IHN0cmluZyYgc3Vic3RyaW5nLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiByZXBsYWNlbWVudCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyogcykgeworICBHT09HTEVfQ0hFQ0socyAhPSBOVUxMKTsKKyAgaWYgKHMtPmVtcHR5KCkgfHwgc3Vic3RyaW5nLmVtcHR5KCkpCisgICAgcmV0dXJuIDA7CisgIHN0cmluZyB0bXA7CisgIGludCBudW1fcmVwbGFjZW1lbnRzID0gMDsKKyAgaW50IHBvcyA9IDA7CisgIGZvciAoaW50IG1hdGNoX3BvcyA9IHMtPmZpbmQoc3Vic3RyaW5nLmRhdGEoKSwgcG9zLCBzdWJzdHJpbmcubGVuZ3RoKCkpOworICAgICAgIG1hdGNoX3BvcyAhPSBzdHJpbmc6Om5wb3M7CisgICAgICAgcG9zID0gbWF0Y2hfcG9zICsgc3Vic3RyaW5nLmxlbmd0aCgpLAorICAgICAgICAgICBtYXRjaF9wb3MgPSBzLT5maW5kKHN1YnN0cmluZy5kYXRhKCksIHBvcywgc3Vic3RyaW5nLmxlbmd0aCgpKSkgeworICAgICsrbnVtX3JlcGxhY2VtZW50czsKKyAgICAvLyBBcHBlbmQgdGhlIG9yaWdpbmFsIGNvbnRlbnQgYmVmb3JlIHRoZSBtYXRjaC4KKyAgICB0bXAuYXBwZW5kKCpzLCBwb3MsIG1hdGNoX3BvcyAtIHBvcyk7CisgICAgLy8gQXBwZW5kIHRoZSByZXBsYWNlbWVudCBmb3IgdGhlIG1hdGNoLgorICAgIHRtcC5hcHBlbmQocmVwbGFjZW1lbnQuYmVnaW4oKSwgcmVwbGFjZW1lbnQuZW5kKCkpOworICB9CisgIC8vIEFwcGVuZCB0aGUgY29udGVudCBhZnRlciB0aGUgbGFzdCBtYXRjaC4gSWYgbm8gcmVwbGFjZW1lbnRzIHdlcmUgbWFkZSwgdGhlCisgIC8vIG9yaWdpbmFsIHN0cmluZyBpcyBsZWZ0IHVudG91Y2hlZC4KKyAgaWYgKG51bV9yZXBsYWNlbWVudHMgPiAwKSB7CisgICAgdG1wLmFwcGVuZCgqcywgcG9zLCBzLT5sZW5ndGgoKSAtIHBvcyk7CisgICAgcy0+c3dhcCh0bXApOworICB9CisgIHJldHVybiBudW1fcmVwbGFjZW1lbnRzOworfQorCitpbnQgQ2FsY3VsYXRlQmFzZTY0RXNjYXBlZExlbihpbnQgaW5wdXRfbGVuLCBib29sIGRvX3BhZGRpbmcpIHsKKyAgLy8gQmFzZTY0IGVuY29kZXMgdGhyZWUgYnl0ZXMgb2YgaW5wdXQgYXQgYSB0aW1lLiBJZiB0aGUgaW5wdXQgaXMgbm90CisgIC8vIGRpdmlzaWJsZSBieSB0aHJlZSwgd2UgcGFkIGFzIGFwcHJvcHJpYXRlLgorICAvLworICAvLyAoZnJvbSBodHRwOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmMzNTQ4KQorICAvLyBTcGVjaWFsIHByb2Nlc3NpbmcgaXMgcGVyZm9ybWVkIGlmIGZld2VyIHRoYW4gMjQgYml0cyBhcmUgYXZhaWxhYmxlCisgIC8vIGF0IHRoZSBlbmQgb2YgdGhlIGRhdGEgYmVpbmcgZW5jb2RlZC4gIEEgZnVsbCBlbmNvZGluZyBxdWFudHVtIGlzCisgIC8vIGFsd2F5cyBjb21wbGV0ZWQgYXQgdGhlIGVuZCBvZiBhIHF1YW50aXR5LiAgV2hlbiBmZXdlciB0aGFuIDI0IGlucHV0CisgIC8vIGJpdHMgYXJlIGF2YWlsYWJsZSBpbiBhbiBpbnB1dCBncm91cCwgemVybyBiaXRzIGFyZSBhZGRlZCAob24gdGhlCisgIC8vIHJpZ2h0KSB0byBmb3JtIGFuIGludGVncmFsIG51bWJlciBvZiA2LWJpdCBncm91cHMuICBQYWRkaW5nIGF0IHRoZQorICAvLyBlbmQgb2YgdGhlIGRhdGEgaXMgcGVyZm9ybWVkIHVzaW5nIHRoZSAnPScgY2hhcmFjdGVyLiAgU2luY2UgYWxsIGJhc2UKKyAgLy8gNjQgaW5wdXQgaXMgYW4gaW50ZWdyYWwgbnVtYmVyIG9mIG9jdGV0cywgb25seSB0aGUgZm9sbG93aW5nIGNhc2VzCisgIC8vIGNhbiBhcmlzZToKKworCisgIC8vIEJhc2U2NCBlbmNvZGVzIGVhY2ggdGhyZWUgYnl0ZXMgb2YgaW5wdXQgaW50byBmb3VyIGJ5dGVzIG9mIG91dHB1dC4KKyAgaW50IGxlbiA9IChpbnB1dF9sZW4gLyAzKSAqIDQ7CisKKyAgaWYgKGlucHV0X2xlbiAlIDMgPT0gMCkgeworICAgIC8vIChmcm9tIGh0dHA6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzM1NDgpCisgICAgLy8gKDEpIHRoZSBmaW5hbCBxdWFudHVtIG9mIGVuY29kaW5nIGlucHV0IGlzIGFuIGludGVncmFsIG11bHRpcGxlIG9mIDI0CisgICAgLy8gYml0czsgaGVyZSwgdGhlIGZpbmFsIHVuaXQgb2YgZW5jb2RlZCBvdXRwdXQgd2lsbCBiZSBhbiBpbnRlZ3JhbAorICAgIC8vIG11bHRpcGxlIG9mIDQgY2hhcmFjdGVycyB3aXRoIG5vICI9IiBwYWRkaW5nLAorICB9IGVsc2UgaWYgKGlucHV0X2xlbiAlIDMgPT0gMSkgeworICAgIC8vIChmcm9tIGh0dHA6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzM1NDgpCisgICAgLy8gKDIpIHRoZSBmaW5hbCBxdWFudHVtIG9mIGVuY29kaW5nIGlucHV0IGlzIGV4YWN0bHkgOCBiaXRzOyBoZXJlLCB0aGUKKyAgICAvLyBmaW5hbCB1bml0IG9mIGVuY29kZWQgb3V0cHV0IHdpbGwgYmUgdHdvIGNoYXJhY3RlcnMgZm9sbG93ZWQgYnkgdHdvCisgICAgLy8gIj0iIHBhZGRpbmcgY2hhcmFjdGVycywgb3IKKyAgICBsZW4gKz0gMjsKKyAgICBpZiAoZG9fcGFkZGluZykgeworICAgICAgbGVuICs9IDI7CisgICAgfQorICB9IGVsc2UgeyAgLy8gKGlucHV0X2xlbiAlIDMgPT0gMikKKyAgICAvLyAoZnJvbSBodHRwOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmMzNTQ4KQorICAgIC8vICgzKSB0aGUgZmluYWwgcXVhbnR1bSBvZiBlbmNvZGluZyBpbnB1dCBpcyBleGFjdGx5IDE2IGJpdHM7IGhlcmUsIHRoZQorICAgIC8vIGZpbmFsIHVuaXQgb2YgZW5jb2RlZCBvdXRwdXQgd2lsbCBiZSB0aHJlZSBjaGFyYWN0ZXJzIGZvbGxvd2VkIGJ5IG9uZQorICAgIC8vICI9IiBwYWRkaW5nIGNoYXJhY3Rlci4KKyAgICBsZW4gKz0gMzsKKyAgICBpZiAoZG9fcGFkZGluZykgeworICAgICAgbGVuICs9IDE7CisgICAgfQorICB9CisKKyAgYXNzZXJ0KGxlbiA+PSBpbnB1dF9sZW4pOyAgLy8gbWFrZSBzdXJlIHdlIGRpZG4ndCBvdmVyZmxvdworICByZXR1cm4gbGVuOworfQorCisvLyBCYXNlNjRFc2NhcGUgZG9lcyBwYWRkaW5nLCBzbyB0aGlzIGNhbGN1bGF0aW9uIGluY2x1ZGVzIHBhZGRpbmcuCitpbnQgQ2FsY3VsYXRlQmFzZTY0RXNjYXBlZExlbihpbnQgaW5wdXRfbGVuKSB7CisgIHJldHVybiBDYWxjdWxhdGVCYXNlNjRFc2NhcGVkTGVuKGlucHV0X2xlbiwgdHJ1ZSk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIGludCBCYXNlNjRVbmVzY2FwZSgpIC0gYmFzZTY0IGRlY29kZXIKKy8vIGludCBCYXNlNjRFc2NhcGUoKSAtIGJhc2U2NCBlbmNvZGVyCisvLyBpbnQgV2ViU2FmZUJhc2U2NFVuZXNjYXBlKCkgLSBHb29nbGUncyB2YXJpYXRpb24gb2YgYmFzZTY0IGRlY29kZXIKKy8vIGludCBXZWJTYWZlQmFzZTY0RXNjYXBlKCkgLSBHb29nbGUncyB2YXJpYXRpb24gb2YgYmFzZTY0IGVuY29kZXIKKy8vCisvLyBDaGVjayBvdXQKKy8vIGh0dHA6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzIwNDUgZm9yIGZvcm1hbCBkZXNjcmlwdGlvbiwgYnV0IHdoYXQgd2UKKy8vIGNhcmUgYWJvdXQgaXMgdGhhdC4uLgorLy8gICBUYWtlIHRoZSBlbmNvZGVkIHN0dWZmIGluIGdyb3VwcyBvZiA0IGNoYXJhY3RlcnMgYW5kIHR1cm4gZWFjaAorLy8gICBjaGFyYWN0ZXIgaW50byBhIGNvZGUgMCB0byA2MyB0aHVzOgorLy8gICAgICAgICAgIEEtWiBtYXAgdG8gMCB0byAyNQorLy8gICAgICAgICAgIGEteiBtYXAgdG8gMjYgdG8gNTEKKy8vICAgICAgICAgICAwLTkgbWFwIHRvIDUyIHRvIDYxCisvLyAgICAgICAgICAgKygtIGZvciBXZWJTYWZlKSBtYXBzIHRvIDYyCisvLyAgICAgICAgICAgLyhfIGZvciBXZWJTYWZlKSBtYXBzIHRvIDYzCisvLyAgIFRoZXJlIHdpbGwgYmUgZm91ciBudW1iZXJzLCBhbGwgbGVzcyB0aGFuIDY0IHdoaWNoIGNhbiBiZSByZXByZXNlbnRlZAorLy8gICBieSBhIDYgZGlnaXQgYmluYXJ5IG51bWJlciAoYWFhYWFhLCBiYmJiYmIsIGNjY2NjYywgZGRkZGRkIHJlc3BlY3RpdmVseSkuCisvLyAgIEFycmFuZ2UgdGhlIDYgZGlnaXQgYmluYXJ5IG51bWJlcnMgaW50byB0aHJlZSBieXRlcyBhcyBzdWNoOgorLy8gICBhYWFhYWFiYiBiYmJiY2NjYyBjY2RkZGRkZAorLy8gICBFcXVhbHMgc2lnbnMgKG9uZSBvciB0d28pIGFyZSB1c2VkIGF0IHRoZSBlbmQgb2YgdGhlIGVuY29kZWQgYmxvY2sgdG8KKy8vICAgaW5kaWNhdGUgdGhhdCB0aGUgdGV4dCB3YXMgbm90IGFuIGludGVnZXIgbXVsdGlwbGUgb2YgdGhyZWUgYnl0ZXMgbG9uZy4KKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworaW50IEJhc2U2NFVuZXNjYXBlSW50ZXJuYWwoY29uc3QgY2hhciAqc3JjX3BhcmFtLCBpbnQgc3pzcmMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyICpkZXN0LCBpbnQgc3pkZXN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2lnbmVkIGNoYXIqIHVuYmFzZTY0KSB7CisgIHN0YXRpYyBjb25zdCBjaGFyIGtQYWQ2NEVxdWFscyA9ICc9JzsKKyAgc3RhdGljIGNvbnN0IGNoYXIga1BhZDY0RG90ID0gJy4nOworCisgIGludCBkZWNvZGUgPSAwOworICBpbnQgZGVzdGlkeCA9IDA7CisgIGludCBzdGF0ZSA9IDA7CisgIHVuc2lnbmVkIGludCBjaCA9IDA7CisgIHVuc2lnbmVkIGludCB0ZW1wID0gMDsKKworICAvLyBJZiAiY2hhciIgaXMgc2lnbmVkIGJ5IGRlZmF1bHQsIHVzaW5nICpzcmMgYXMgYW4gYXJyYXkgaW5kZXggcmVzdWx0cyBpbgorICAvLyBhY2Nlc3NpbmcgbmVnYXRpdmUgYXJyYXkgZWxlbWVudHMuIFRyZWF0IHRoZSBpbnB1dCBhcyBhIHBvaW50ZXIgdG8KKyAgLy8gdW5zaWduZWQgY2hhciB0byBhdm9pZCB0aGlzLgorICBjb25zdCB1bnNpZ25lZCBjaGFyICpzcmMgPSByZWludGVycHJldF9jYXN0PGNvbnN0IHVuc2lnbmVkIGNoYXIqPihzcmNfcGFyYW0pOworCisgIC8vIFRoZSBHRVRfSU5QVVQgbWFjcm8gZ2V0cyB0aGUgbmV4dCBpbnB1dCBjaGFyYWN0ZXIsIHNraXBwaW5nCisgIC8vIG92ZXIgYW55IHdoaXRlc3BhY2UsIGFuZCBzdG9wcGluZyB3aGVuIHdlIHJlYWNoIHRoZSBlbmQgb2YgdGhlCisgIC8vIHN0cmluZyBvciB3aGVuIHdlIHJlYWQgYW55IG5vbi1kYXRhIGNoYXJhY3Rlci4gIFRoZSBhcmd1bWVudHMgYXJlCisgIC8vIGFuIGFyYml0cmFyeSBpZGVudGlmaWVyICh1c2VkIGFzIGEgbGFiZWwgZm9yIGdvdG8pIGFuZCB0aGUgbnVtYmVyCisgIC8vIG9mIGRhdGEgYnl0ZXMgdGhhdCBtdXN0IHJlbWFpbiBpbiB0aGUgaW5wdXQgdG8gYXZvaWQgYWJvcnRpbmcgdGhlCisgIC8vIGxvb3AuCisjZGVmaW5lIEdFVF9JTlBVVChsYWJlbCwgcmVtYWluKSAgICAgICAgICAgICAgICAgXAorICBsYWJlbDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAtLXN6c3JjOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgY2ggPSAqc3JjKys7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGRlY29kZSA9IHVuYmFzZTY0W2NoXTsgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBpZiAoZGVjb2RlIDwgMCkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICBpZiAoYXNjaWlfaXNzcGFjZShjaCkgJiYgc3pzcmMgPj0gcmVtYWluKSAgXAorICAgICAgICBnb3RvIGxhYmVsOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIHN0YXRlID0gNCAtIHJlbWFpbjsgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICBicmVhazsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIH0KKworICAvLyBpZiBkZXN0IGlzIG51bGwsIHdlJ3JlIGp1c3QgY2hlY2tpbmcgdG8gc2VlIGlmIGl0J3MgbGVnYWwgaW5wdXQKKyAgLy8gcmF0aGVyIHRoYW4gcHJvZHVjaW5nIG91dHB1dC4gIChJIHN1c3BlY3QgdGhpcyBjb3VsZCBqdXN0IGJlIGRvbmUKKyAgLy8gd2l0aCBhIHJlZ2V4cC4uLikuICBXZSBkdXBsaWNhdGUgdGhlIGxvb3Agc28gdGhpcyB0ZXN0IGNhbiBiZQorICAvLyBvdXRzaWRlIGl0IGluc3RlYWQgb2YgaW4gZXZlcnkgaXRlcmF0aW9uLgorCisgIGlmIChkZXN0KSB7CisgICAgLy8gVGhpcyBsb29wIGNvbnN1bWVzIDQgaW5wdXQgYnl0ZXMgYW5kIHByb2R1Y2VzIDMgb3V0cHV0IGJ5dGVzCisgICAgLy8gcGVyIGl0ZXJhdGlvbi4gIFdlIGNhbid0IGtub3cgYXQgdGhlIHN0YXJ0IHRoYXQgdGhlcmUgaXMgZW5vdWdoCisgICAgLy8gZGF0YSBsZWZ0IGluIHRoZSBzdHJpbmcgZm9yIGEgZnVsbCBpdGVyYXRpb24sIHNvIHRoZSBsb29wIG1heQorICAgIC8vIGJyZWFrIG91dCBpbiB0aGUgbWlkZGxlOyBpZiBzbyAnc3RhdGUnIHdpbGwgYmUgc2V0IHRvIHRoZQorICAgIC8vIG51bWJlciBvZiBpbnB1dCBieXRlcyByZWFkLgorCisgICAgd2hpbGUgKHN6c3JjID49IDQpICB7CisgICAgICAvLyBXZSdsbCBzdGFydCBieSBvcHRpbWlzdGljYWxseSBhc3N1bWluZyB0aGF0IHRoZSBuZXh0IGZvdXIKKyAgICAgIC8vIGJ5dGVzIG9mIHRoZSBzdHJpbmcgKHNyY1swLi4zXSkgYXJlIGZvdXIgZ29vZCBkYXRhIGJ5dGVzCisgICAgICAvLyAodGhhdCBpcywgbm8gbnVsbHMsIHdoaXRlc3BhY2UsIHBhZGRpbmcgY2hhcnMsIG9yIGlsbGVnYWwKKyAgICAgIC8vIGNoYXJzKS4gIFdlIG5lZWQgdG8gdGVzdCBzcmNbMC4uMl0gZm9yIG51bGxzIGluZGl2aWR1YWxseQorICAgICAgLy8gYmVmb3JlIGNvbnN0cnVjdGluZyB0ZW1wIHRvIHByZXNlcnZlIHRoZSBwcm9wZXJ0eSB0aGF0IHdlCisgICAgICAvLyBuZXZlciByZWFkIHBhc3QgYSBudWxsIGluIHRoZSBzdHJpbmcgKG5vIG1hdHRlciBob3cgbG9uZworICAgICAgLy8gc3pzcmMgY2xhaW1zIHRoZSBzdHJpbmcgaXMpLgorCisgICAgICBpZiAoIXNyY1swXSB8fCAhc3JjWzFdIHx8ICFzcmNbMl0gfHwKKyAgICAgICAgICAodGVtcCA9ICgodW5zaWduZWQodW5iYXNlNjRbc3JjWzBdXSkgPDwgMTgpIHwKKyAgICAgICAgICAgICAgICAgICAodW5zaWduZWQodW5iYXNlNjRbc3JjWzFdXSkgPDwgMTIpIHwKKyAgICAgICAgICAgICAgICAgICAodW5zaWduZWQodW5iYXNlNjRbc3JjWzJdXSkgPDwgNikgfAorICAgICAgICAgICAgICAgICAgICh1bnNpZ25lZCh1bmJhc2U2NFtzcmNbM11dKSkpKSAmIDB4ODAwMDAwMDApIHsKKyAgICAgICAgLy8gSWZmIGFueSBvZiB0aG9zZSBmb3VyIGNoYXJhY3RlcnMgd2FzIGJhZCAobnVsbCwgaWxsZWdhbCwKKyAgICAgICAgLy8gd2hpdGVzcGFjZSwgcGFkZGluZyksIHRoZW4gdGVtcCdzIGhpZ2ggYml0IHdpbGwgYmUgc2V0CisgICAgICAgIC8vIChiZWNhdXNlIHVuYmFzZTY0W10gaXMgLTEgZm9yIGFsbCBiYWQgY2hhcmFjdGVycykuCisgICAgICAgIC8vCisgICAgICAgIC8vIFdlJ2xsIGJhY2sgdXAgYW5kIHJlc29ydCB0byB0aGUgc2xvd2VyIGRlY29kZXIsIHdoaWNoIGtub3dzCisgICAgICAgIC8vIGhvdyB0byBoYW5kbGUgdGhvc2UgY2FzZXMuCisKKyAgICAgICAgR0VUX0lOUFVUKGZpcnN0LCA0KTsKKyAgICAgICAgdGVtcCA9IGRlY29kZTsKKyAgICAgICAgR0VUX0lOUFVUKHNlY29uZCwgMyk7CisgICAgICAgIHRlbXAgPSAodGVtcCA8PCA2KSB8IGRlY29kZTsKKyAgICAgICAgR0VUX0lOUFVUKHRoaXJkLCAyKTsKKyAgICAgICAgdGVtcCA9ICh0ZW1wIDw8IDYpIHwgZGVjb2RlOworICAgICAgICBHRVRfSU5QVVQoZm91cnRoLCAxKTsKKyAgICAgICAgdGVtcCA9ICh0ZW1wIDw8IDYpIHwgZGVjb2RlOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgLy8gV2UgcmVhbGx5IGRpZCBoYXZlIGZvdXIgZ29vZCBkYXRhIGJ5dGVzLCBzbyBhZHZhbmNlIGZvdXIKKyAgICAgICAgLy8gY2hhcmFjdGVycyBpbiB0aGUgc3RyaW5nLgorCisgICAgICAgIHN6c3JjIC09IDQ7CisgICAgICAgIHNyYyArPSA0OworICAgICAgICBkZWNvZGUgPSAtMTsKKyAgICAgICAgY2ggPSAnXDAnOworICAgICAgfQorCisgICAgICAvLyB0ZW1wIGhhcyAyNCBiaXRzIG9mIGlucHV0LCBzbyB3cml0ZSB0aGF0IG91dCBhcyB0aHJlZSBieXRlcy4KKworICAgICAgaWYgKGRlc3RpZHgrMyA+IHN6ZGVzdCkgcmV0dXJuIC0xOworICAgICAgZGVzdFtkZXN0aWR4KzJdID0gdGVtcDsKKyAgICAgIHRlbXAgPj49IDg7CisgICAgICBkZXN0W2Rlc3RpZHgrMV0gPSB0ZW1wOworICAgICAgdGVtcCA+Pj0gODsKKyAgICAgIGRlc3RbZGVzdGlkeF0gPSB0ZW1wOworICAgICAgZGVzdGlkeCArPSAzOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICB3aGlsZSAoc3pzcmMgPj0gNCkgIHsKKyAgICAgIGlmICghc3JjWzBdIHx8ICFzcmNbMV0gfHwgIXNyY1syXSB8fAorICAgICAgICAgICh0ZW1wID0gKCh1bnNpZ25lZCh1bmJhc2U2NFtzcmNbMF1dKSA8PCAxOCkgfAorICAgICAgICAgICAgICAgICAgICh1bnNpZ25lZCh1bmJhc2U2NFtzcmNbMV1dKSA8PCAxMikgfAorICAgICAgICAgICAgICAgICAgICh1bnNpZ25lZCh1bmJhc2U2NFtzcmNbMl1dKSA8PCA2KSB8CisgICAgICAgICAgICAgICAgICAgKHVuc2lnbmVkKHVuYmFzZTY0W3NyY1szXV0pKSkpICYgMHg4MDAwMDAwMCkgeworICAgICAgICBHRVRfSU5QVVQoZmlyc3Rfbm9fZGVzdCwgNCk7CisgICAgICAgIEdFVF9JTlBVVChzZWNvbmRfbm9fZGVzdCwgMyk7CisgICAgICAgIEdFVF9JTlBVVCh0aGlyZF9ub19kZXN0LCAyKTsKKyAgICAgICAgR0VUX0lOUFVUKGZvdXJ0aF9ub19kZXN0LCAxKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHN6c3JjIC09IDQ7CisgICAgICAgIHNyYyArPSA0OworICAgICAgICBkZWNvZGUgPSAtMTsKKyAgICAgICAgY2ggPSAnXDAnOworICAgICAgfQorICAgICAgZGVzdGlkeCArPSAzOworICAgIH0KKyAgfQorCisjdW5kZWYgR0VUX0lOUFVUCisKKyAgLy8gaWYgdGhlIGxvb3AgdGVybWluYXRlZCBiZWNhdXNlIHdlIHJlYWQgYSBiYWQgY2hhcmFjdGVyLCByZXR1cm4KKyAgLy8gbm93LgorICBpZiAoZGVjb2RlIDwgMCAmJiBjaCAhPSAnXDAnICYmCisgICAgICBjaCAhPSBrUGFkNjRFcXVhbHMgJiYgY2ggIT0ga1BhZDY0RG90ICYmICFhc2NpaV9pc3NwYWNlKGNoKSkKKyAgICByZXR1cm4gLTE7CisKKyAgaWYgKGNoID09IGtQYWQ2NEVxdWFscyB8fCBjaCA9PSBrUGFkNjREb3QpIHsKKyAgICAvLyBpZiB3ZSBzdG9wcGVkIGJ5IGhpdHRpbmcgYW4gJz0nIG9yICcuJywgdW4tcmVhZCB0aGF0IGNoYXJhY3RlciAtLSB3ZSdsbAorICAgIC8vIGxvb2sgYXQgaXQgYWdhaW4gd2hlbiB3ZSBjb3VudCB0byBjaGVjayBmb3IgdGhlIHByb3BlciBudW1iZXIgb2YKKyAgICAvLyBlcXVhbHMgc2lnbnMgYXQgdGhlIGVuZC4KKyAgICArK3N6c3JjOworICAgIC0tc3JjOworICB9IGVsc2UgeworICAgIC8vIFRoaXMgbG9vcCBjb25zdW1lcyAxIGlucHV0IGJ5dGUgcGVyIGl0ZXJhdGlvbi4gIEl0J3MgdXNlZCB0bworICAgIC8vIGNsZWFuIHVwIHRoZSAwLTMgaW5wdXQgYnl0ZXMgcmVtYWluaW5nIHdoZW4gdGhlIGZpcnN0LCBmYXN0ZXIKKyAgICAvLyBsb29wIGZpbmlzaGVzLiAgJ3RlbXAnIGNvbnRhaW5zIHRoZSBkYXRhIGZyb20gJ3N0YXRlJyBpbnB1dAorICAgIC8vIGNoYXJhY3RlcnMgcmVhZCBieSB0aGUgZmlyc3QgbG9vcC4KKyAgICB3aGlsZSAoc3pzcmMgPiAwKSAgeworICAgICAgLS1zenNyYzsKKyAgICAgIGNoID0gKnNyYysrOworICAgICAgZGVjb2RlID0gdW5iYXNlNjRbY2hdOworICAgICAgaWYgKGRlY29kZSA8IDApIHsKKyAgICAgICAgaWYgKGFzY2lpX2lzc3BhY2UoY2gpKSB7CisgICAgICAgICAgY29udGludWU7CisgICAgICAgIH0gZWxzZSBpZiAoY2ggPT0gJ1wwJykgeworICAgICAgICAgIGJyZWFrOworICAgICAgICB9IGVsc2UgaWYgKGNoID09IGtQYWQ2NEVxdWFscyB8fCBjaCA9PSBrUGFkNjREb3QpIHsKKyAgICAgICAgICAvLyBiYWNrIHVwIG9uZSBjaGFyYWN0ZXI7IHdlJ2xsIHJlYWQgaXQgYWdhaW4gd2hlbiB3ZSBjaGVjaworICAgICAgICAgIC8vIGZvciB0aGUgY29ycmVjdCBudW1iZXIgb2YgcGFkIGNoYXJhY3RlcnMgYXQgdGhlIGVuZC4KKyAgICAgICAgICArK3N6c3JjOworICAgICAgICAgIC0tc3JjOworICAgICAgICAgIGJyZWFrOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgICAgfQorCisgICAgICAvLyBFYWNoIGlucHV0IGNoYXJhY3RlciBnaXZlcyB1cyBzaXggYml0cyBvZiBvdXRwdXQuCisgICAgICB0ZW1wID0gKHRlbXAgPDwgNikgfCBkZWNvZGU7CisgICAgICArK3N0YXRlOworICAgICAgaWYgKHN0YXRlID09IDQpIHsKKyAgICAgICAgLy8gSWYgd2UndmUgYWNjdW11bGF0ZWQgMjQgYml0cyBvZiBvdXRwdXQsIHdyaXRlIHRoYXQgb3V0IGFzCisgICAgICAgIC8vIHRocmVlIGJ5dGVzLgorICAgICAgICBpZiAoZGVzdCkgeworICAgICAgICAgIGlmIChkZXN0aWR4KzMgPiBzemRlc3QpIHJldHVybiAtMTsKKyAgICAgICAgICBkZXN0W2Rlc3RpZHgrMl0gPSB0ZW1wOworICAgICAgICAgIHRlbXAgPj49IDg7CisgICAgICAgICAgZGVzdFtkZXN0aWR4KzFdID0gdGVtcDsKKyAgICAgICAgICB0ZW1wID4+PSA4OworICAgICAgICAgIGRlc3RbZGVzdGlkeF0gPSB0ZW1wOworICAgICAgICB9CisgICAgICAgIGRlc3RpZHggKz0gMzsKKyAgICAgICAgc3RhdGUgPSAwOworICAgICAgICB0ZW1wID0gMDsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvLyBQcm9jZXNzIHRoZSBsZWZ0b3ZlciBkYXRhIGNvbnRhaW5lZCBpbiAndGVtcCcgYXQgdGhlIGVuZCBvZiB0aGUgaW5wdXQuCisgIGludCBleHBlY3RlZF9lcXVhbHMgPSAwOworICBzd2l0Y2ggKHN0YXRlKSB7CisgICAgY2FzZSAwOgorICAgICAgLy8gTm90aGluZyBsZWZ0IG92ZXI7IG91dHB1dCBpcyBhIG11bHRpcGxlIG9mIDMgYnl0ZXMuCisgICAgICBicmVhazsKKworICAgIGNhc2UgMToKKyAgICAgIC8vIEJhZCBpbnB1dDsgd2UgaGF2ZSA2IGJpdHMgbGVmdCBvdmVyLgorICAgICAgcmV0dXJuIC0xOworCisgICAgY2FzZSAyOgorICAgICAgLy8gUHJvZHVjZSBvbmUgbW9yZSBvdXRwdXQgYnl0ZSBmcm9tIHRoZSAxMiBpbnB1dCBiaXRzIHdlIGhhdmUgbGVmdC4KKyAgICAgIGlmIChkZXN0KSB7CisgICAgICAgIGlmIChkZXN0aWR4KzEgPiBzemRlc3QpIHJldHVybiAtMTsKKyAgICAgICAgdGVtcCA+Pj0gNDsKKyAgICAgICAgZGVzdFtkZXN0aWR4XSA9IHRlbXA7CisgICAgICB9CisgICAgICArK2Rlc3RpZHg7CisgICAgICBleHBlY3RlZF9lcXVhbHMgPSAyOworICAgICAgYnJlYWs7CisKKyAgICBjYXNlIDM6CisgICAgICAvLyBQcm9kdWNlIHR3byBtb3JlIG91dHB1dCBieXRlcyBmcm9tIHRoZSAxOCBpbnB1dCBiaXRzIHdlIGhhdmUgbGVmdC4KKyAgICAgIGlmIChkZXN0KSB7CisgICAgICAgIGlmIChkZXN0aWR4KzIgPiBzemRlc3QpIHJldHVybiAtMTsKKyAgICAgICAgdGVtcCA+Pj0gMjsKKyAgICAgICAgZGVzdFtkZXN0aWR4KzFdID0gdGVtcDsKKyAgICAgICAgdGVtcCA+Pj0gODsKKyAgICAgICAgZGVzdFtkZXN0aWR4XSA9IHRlbXA7CisgICAgICB9CisgICAgICBkZXN0aWR4ICs9IDI7CisgICAgICBleHBlY3RlZF9lcXVhbHMgPSAxOworICAgICAgYnJlYWs7CisKKyAgICBkZWZhdWx0OgorICAgICAgLy8gc3RhdGUgc2hvdWxkIGhhdmUgbm8gb3RoZXIgdmFsdWVzIGF0IHRoaXMgcG9pbnQuCisgICAgICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiVGhpcyBjYW4ndCBoYXBwZW47IGJhc2U2NCBkZWNvZGVyIHN0YXRlID0gIiA8PCBzdGF0ZTsKKyAgfQorCisgIC8vIFRoZSByZW1haW5kZXIgb2YgdGhlIHN0cmluZyBzaG91bGQgYmUgYWxsIHdoaXRlc3BhY2UsIG1peGVkIHdpdGgKKyAgLy8gZXhhY3RseSAwIGVxdWFscyBzaWducywgb3IgZXhhY3RseSAnZXhwZWN0ZWRfZXF1YWxzJyBlcXVhbHMKKyAgLy8gc2lnbnMuICAoQWx3YXlzIGFjY2VwdGluZyAwIGVxdWFscyBzaWducyBpcyBhIGdvb2dsZSBleHRlbnNpb24KKyAgLy8gbm90IGNvdmVyZWQgaW4gdGhlIFJGQywgYXMgaXMgYWNjZXB0aW5nIGRvdCBhcyB0aGUgcGFkIGNoYXJhY3Rlci4pCisKKyAgaW50IGVxdWFscyA9IDA7CisgIHdoaWxlIChzenNyYyA+IDAgJiYgKnNyYykgeworICAgIGlmICgqc3JjID09IGtQYWQ2NEVxdWFscyB8fCAqc3JjID09IGtQYWQ2NERvdCkKKyAgICAgICsrZXF1YWxzOworICAgIGVsc2UgaWYgKCFhc2NpaV9pc3NwYWNlKCpzcmMpKQorICAgICAgcmV0dXJuIC0xOworICAgIC0tc3pzcmM7CisgICAgKytzcmM7CisgIH0KKworICByZXR1cm4gKGVxdWFscyA9PSAwIHx8IGVxdWFscyA9PSBleHBlY3RlZF9lcXVhbHMpID8gZGVzdGlkeCA6IC0xOworfQorCisvLyBUaGUgYXJyYXlzIGJlbG93IHdlcmUgZ2VuZXJhdGVkIGJ5IHRoZSBmb2xsb3dpbmcgY29kZQorLy8gI2luY2x1ZGUgPHN5cy90aW1lLmg+CisvLyAjaW5jbHVkZSA8c3RkbGliLmg+CisvLyAjaW5jbHVkZSA8c3RyaW5nLmg+CisvLyBtYWluKCkKKy8vIHsKKy8vICAgc3RhdGljIGNvbnN0IGNoYXIgQmFzZTY0W10gPQorLy8gICAgICJBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvIjsKKy8vICAgY2hhciAqcG9zOworLy8gICBpbnQgaWR4LCBpLCBqOworLy8gICBwcmludGYoIiAgICAiKTsKKy8vICAgZm9yIChpID0gMDsgaSA8IDI1NTsgaSArPSA4KSB7CisvLyAgICAgZm9yIChqID0gaTsgaiA8IGkgKyA4OyBqKyspIHsKKy8vICAgICAgIHBvcyA9IHN0cmNocihCYXNlNjQsIGopOworLy8gICAgICAgaWYgKChwb3MgPT0gTlVMTCkgfHwgKGogPT0gMCkpCisvLyAgICAgICAgIGlkeCA9IC0xOworLy8gICAgICAgZWxzZQorLy8gICAgICAgICBpZHggPSBwb3MgLSBCYXNlNjQ7CisvLyAgICAgICBpZiAoaWR4ID09IC0xKQorLy8gICAgICAgICBwcmludGYoIiAlMmQsICAgICAiLCBpZHgpOworLy8gICAgICAgZWxzZQorLy8gICAgICAgICBwcmludGYoIiAlMmQvKiVjKi8sIiwgaWR4LCBqKTsKKy8vICAgICB9CisvLyAgICAgcHJpbnRmKCJcbiAgICAiKTsKKy8vICAgfQorLy8gfQorLy8KKy8vIHdoZXJlIHRoZSB2YWx1ZSBvZiAiQmFzZTY0W10iIHdhcyByZXBsYWNlZCBieSBvbmUgb2YgdGhlIGJhc2UtNjQgY29udmVyc2lvbgorLy8gdGFibGVzIGZyb20gdGhlIGZ1bmN0aW9ucyBiZWxvdy4KK3N0YXRpYyBjb25zdCBzaWduZWQgY2hhciBrVW5CYXNlNjRbXSA9IHsKKyAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsCisgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLAorICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwKKyAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsCisgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLAorICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICA2Mi8qKyovLCAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICA2My8qLyAqLywKKyAgNTIvKjAqLywgNTMvKjEqLywgNTQvKjIqLywgNTUvKjMqLywgNTYvKjQqLywgNTcvKjUqLywgNTgvKjYqLywgNTkvKjcqLywKKyAgNjAvKjgqLywgNjEvKjkqLywgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsCisgIC0xLCAgICAgICAwLypBKi8sICAxLypCKi8sICAyLypDKi8sICAzLypEKi8sICA0LypFKi8sICA1LypGKi8sICA2LypHKi8sCisgIDA3LypIKi8sICA4LypJKi8sICA5LypKKi8sIDEwLypLKi8sIDExLypMKi8sIDEyLypNKi8sIDEzLypOKi8sIDE0LypPKi8sCisgIDE1LypQKi8sIDE2LypRKi8sIDE3LypSKi8sIDE4LypTKi8sIDE5LypUKi8sIDIwLypVKi8sIDIxLypWKi8sIDIyLypXKi8sCisgIDIzLypYKi8sIDI0LypZKi8sIDI1LypaKi8sIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLAorICAtMSwgICAgICAyNi8qYSovLCAyNy8qYiovLCAyOC8qYyovLCAyOS8qZCovLCAzMC8qZSovLCAzMS8qZiovLCAzMi8qZyovLAorICAzMy8qaCovLCAzNC8qaSovLCAzNS8qaiovLCAzNi8qayovLCAzNy8qbCovLCAzOC8qbSovLCAzOS8qbiovLCA0MC8qbyovLAorICA0MS8qcCovLCA0Mi8qcSovLCA0My8qciovLCA0NC8qcyovLCA0NS8qdCovLCA0Ni8qdSovLCA0Ny8qdiovLCA0OC8qdyovLAorICA0OS8qeCovLCA1MC8qeSovLCA1MS8qeiovLCAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwKKyAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsCisgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLAorICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwKKyAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsCisgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLAorICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwKKyAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsCisgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLAorICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwKKyAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsCisgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLAorICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwKKyAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsCisgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLAorICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwKKyAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEKK307CitzdGF0aWMgY29uc3Qgc2lnbmVkIGNoYXIga1VuV2ViU2FmZUJhc2U2NFtdID0geworICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwKKyAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsCisgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLAorICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwKKyAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsCisgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIDYyLyotKi8sIC0xLCAgICAgIC0xLAorICA1Mi8qMCovLCA1My8qMSovLCA1NC8qMiovLCA1NS8qMyovLCA1Ni8qNCovLCA1Ny8qNSovLCA1OC8qNiovLCA1OS8qNyovLAorICA2MC8qOCovLCA2MS8qOSovLCAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwKKyAgLTEsICAgICAgIDAvKkEqLywgIDEvKkIqLywgIDIvKkMqLywgIDMvKkQqLywgIDQvKkUqLywgIDUvKkYqLywgIDYvKkcqLywKKyAgMDcvKkgqLywgIDgvKkkqLywgIDkvKkoqLywgMTAvKksqLywgMTEvKkwqLywgMTIvKk0qLywgMTMvKk4qLywgMTQvKk8qLywKKyAgMTUvKlAqLywgMTYvKlEqLywgMTcvKlIqLywgMTgvKlMqLywgMTkvKlQqLywgMjAvKlUqLywgMjEvKlYqLywgMjIvKlcqLywKKyAgMjMvKlgqLywgMjQvKlkqLywgMjUvKloqLywgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgNjMvKl8qLywKKyAgLTEsICAgICAgMjYvKmEqLywgMjcvKmIqLywgMjgvKmMqLywgMjkvKmQqLywgMzAvKmUqLywgMzEvKmYqLywgMzIvKmcqLywKKyAgMzMvKmgqLywgMzQvKmkqLywgMzUvKmoqLywgMzYvKmsqLywgMzcvKmwqLywgMzgvKm0qLywgMzkvKm4qLywgNDAvKm8qLywKKyAgNDEvKnAqLywgNDIvKnEqLywgNDMvKnIqLywgNDQvKnMqLywgNDUvKnQqLywgNDYvKnUqLywgNDcvKnYqLywgNDgvKncqLywKKyAgNDkvKngqLywgNTAvKnkqLywgNTEvKnoqLywgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsCisgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLAorICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwKKyAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsCisgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLAorICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwKKyAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsCisgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLAorICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwKKyAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsCisgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLAorICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwKKyAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsCisgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLAorICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwgICAgICAtMSwKKyAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsICAgICAgLTEsCisgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xLCAgICAgIC0xCit9OworCitpbnQgV2ViU2FmZUJhc2U2NFVuZXNjYXBlKGNvbnN0IGNoYXIgKnNyYywgaW50IHN6c3JjLCBjaGFyICpkZXN0LCBpbnQgc3pkZXN0KSB7CisgIHJldHVybiBCYXNlNjRVbmVzY2FwZUludGVybmFsKHNyYywgc3pzcmMsIGRlc3QsIHN6ZGVzdCwga1VuV2ViU2FmZUJhc2U2NCk7Cit9CisKK3N0YXRpYyBib29sIEJhc2U2NFVuZXNjYXBlSW50ZXJuYWwoY29uc3QgY2hhciogc3JjLCBpbnQgc2xlbiwgc3RyaW5nKiBkZXN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzaWduZWQgY2hhciogdW5iYXNlNjQpIHsKKyAgLy8gRGV0ZXJtaW5lIHRoZSBzaXplIG9mIHRoZSBvdXRwdXQgc3RyaW5nLiAgQmFzZTY0IGVuY29kZXMgZXZlcnkgMyBieXRlcyBpbnRvCisgIC8vIDQgY2hhcmFjdGVycy4gIGFueSBsZWZ0b3ZlciBjaGFycyBhcmUgYWRkZWQgZGlyZWN0bHkgZm9yIGdvb2QgbWVhc3VyZS4KKyAgLy8gVGhpcyBpcyBkb2N1bWVudGVkIGluIHRoZSBiYXNlNjQgUkZDOiBodHRwOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmMzNTQ4CisgIGNvbnN0IGludCBkZXN0X2xlbiA9IDMgKiAoc2xlbiAvIDQpICsgKHNsZW4gJSA0KTsKKworICBkZXN0LT5yZXNpemUoZGVzdF9sZW4pOworCisgIC8vIFdlIGFyZSBnZXR0aW5nIHRoZSBkZXN0aW5hdGlvbiBidWZmZXIgYnkgZ2V0dGluZyB0aGUgYmVnaW5uaW5nIG9mIHRoZQorICAvLyBzdHJpbmcgYW5kIGNvbnZlcnRpbmcgaXQgaW50byBhIGNoYXIgKi4KKyAgY29uc3QgaW50IGxlbiA9IEJhc2U2NFVuZXNjYXBlSW50ZXJuYWwoc3JjLCBzbGVuLCBzdHJpbmdfYXNfYXJyYXkoZGVzdCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc3RfbGVuLCB1bmJhc2U2NCk7CisgIGlmIChsZW4gPCAwKSB7CisgICAgZGVzdC0+Y2xlYXIoKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLyBjb3VsZCBiZSBzaG9ydGVyIGlmIHRoZXJlIHdhcyBwYWRkaW5nCisgIEdPT0dMRV9EQ0hFQ0tfTEUobGVuLCBkZXN0X2xlbik7CisgIGRlc3QtPmVyYXNlKGxlbik7CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgQmFzZTY0VW5lc2NhcGUoU3RyaW5nUGllY2Ugc3JjLCBzdHJpbmcqIGRlc3QpIHsKKyAgcmV0dXJuIEJhc2U2NFVuZXNjYXBlSW50ZXJuYWwoc3JjLmRhdGEoKSwgc3JjLnNpemUoKSwgZGVzdCwga1VuQmFzZTY0KTsKK30KKworYm9vbCBXZWJTYWZlQmFzZTY0VW5lc2NhcGUoU3RyaW5nUGllY2Ugc3JjLCBzdHJpbmcqIGRlc3QpIHsKKyAgcmV0dXJuIEJhc2U2NFVuZXNjYXBlSW50ZXJuYWwoc3JjLmRhdGEoKSwgc3JjLnNpemUoKSwgZGVzdCwga1VuV2ViU2FmZUJhc2U2NCk7Cit9CisKK2ludCBCYXNlNjRFc2NhcGVJbnRlcm5hbChjb25zdCB1bnNpZ25lZCBjaGFyICpzcmMsIGludCBzenNyYywKKyAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyICpkZXN0LCBpbnQgc3pkZXN0LCBjb25zdCBjaGFyICpiYXNlNjQsCisgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBkb19wYWRkaW5nKSB7CisgIHN0YXRpYyBjb25zdCBjaGFyIGtQYWQ2NCA9ICc9JzsKKworICBpZiAoc3pzcmMgPD0gMCkgcmV0dXJuIDA7CisKKyAgaWYgKHN6c3JjICogNCA+IHN6ZGVzdCAqIDMpIHJldHVybiAwOworCisgIGNoYXIgKmN1cl9kZXN0ID0gZGVzdDsKKyAgY29uc3QgdW5zaWduZWQgY2hhciAqY3VyX3NyYyA9IHNyYzsKKworICBjaGFyICpsaW1pdF9kZXN0ID0gZGVzdCArIHN6ZGVzdDsKKyAgY29uc3QgdW5zaWduZWQgY2hhciAqbGltaXRfc3JjID0gc3JjICsgc3pzcmM7CisKKyAgLy8gVGhyZWUgYnl0ZXMgb2YgZGF0YSBlbmNvZGVzIHRvIGZvdXIgY2hhcmFjdGVycyBvZiBjeXBoZXJ0ZXh0LgorICAvLyBTbyB3ZSBjYW4gcHVtcCB0aHJvdWdoIHRocmVlLWJ5dGUgY2h1bmtzIGF0b21pY2FsbHkuCisgIHdoaWxlIChjdXJfc3JjIDwgbGltaXRfc3JjIC0gMykgeyAgLy8ga2VlcCBnb2luZyBhcyBsb25nIGFzIHdlIGhhdmUgPj0gMzIgYml0cworICAgIHVpbnQzMiBpbiA9IEJpZ0VuZGlhbjo6TG9hZDMyKGN1cl9zcmMpID4+IDg7CisKKyAgICBjdXJfZGVzdFswXSA9IGJhc2U2NFtpbiA+PiAxOF07CisgICAgaW4gJj0gMHgzRkZGRjsKKyAgICBjdXJfZGVzdFsxXSA9IGJhc2U2NFtpbiA+PiAxMl07CisgICAgaW4gJj0gMHhGRkY7CisgICAgY3VyX2Rlc3RbMl0gPSBiYXNlNjRbaW4gPj4gNl07CisgICAgaW4gJj0gMHgzRjsKKyAgICBjdXJfZGVzdFszXSA9IGJhc2U2NFtpbl07CisKKyAgICBjdXJfZGVzdCArPSA0OworICAgIGN1cl9zcmMgKz0gMzsKKyAgfQorICAvLyBUbyBzYXZlIHRpbWUsIHdlIGRpZG4ndCB1cGRhdGUgc3pkZXN0IG9yIHN6c3JjIGluIHRoZSBsb29wLiAgU28gZG8gaXQgbm93LgorICBzemRlc3QgPSBsaW1pdF9kZXN0IC0gY3VyX2Rlc3Q7CisgIHN6c3JjID0gbGltaXRfc3JjIC0gY3VyX3NyYzsKKworICAvKiBub3cgZGVhbCB3aXRoIHRoZSB0YWlsICg8PTMgYnl0ZXMpICovCisgIHN3aXRjaCAoc3pzcmMpIHsKKyAgICBjYXNlIDA6CisgICAgICAvLyBOb3RoaW5nIGxlZnQ7IG5vdGhpbmcgbW9yZSB0byBkby4KKyAgICAgIGJyZWFrOworICAgIGNhc2UgMTogeworICAgICAgLy8gT25lIGJ5dGUgbGVmdDogdGhpcyBlbmNvZGVzIHRvIHR3byBjaGFyYWN0ZXJzLCBhbmQgKG9wdGlvbmFsbHkpCisgICAgICAvLyB0d28gcGFkIGNoYXJhY3RlcnMgdG8gcm91bmQgb3V0IHRoZSBmb3VyLWNoYXJhY3RlciBjeXBoZXJibG9jay4KKyAgICAgIGlmICgoc3pkZXN0IC09IDIpIDwgMCkgcmV0dXJuIDA7CisgICAgICB1aW50MzIgaW4gPSBjdXJfc3JjWzBdOworICAgICAgY3VyX2Rlc3RbMF0gPSBiYXNlNjRbaW4gPj4gMl07CisgICAgICBpbiAmPSAweDM7CisgICAgICBjdXJfZGVzdFsxXSA9IGJhc2U2NFtpbiA8PCA0XTsKKyAgICAgIGN1cl9kZXN0ICs9IDI7CisgICAgICBpZiAoZG9fcGFkZGluZykgeworICAgICAgICBpZiAoKHN6ZGVzdCAtPSAyKSA8IDApIHJldHVybiAwOworICAgICAgICBjdXJfZGVzdFswXSA9IGtQYWQ2NDsKKyAgICAgICAgY3VyX2Rlc3RbMV0gPSBrUGFkNjQ7CisgICAgICAgIGN1cl9kZXN0ICs9IDI7CisgICAgICB9CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAyOiB7CisgICAgICAvLyBUd28gYnl0ZXMgbGVmdDogdGhpcyBlbmNvZGVzIHRvIHRocmVlIGNoYXJhY3RlcnMsIGFuZCAob3B0aW9uYWxseSkKKyAgICAgIC8vIG9uZSBwYWQgY2hhcmFjdGVyIHRvIHJvdW5kIG91dCB0aGUgZm91ci1jaGFyYWN0ZXIgY3lwaGVyYmxvY2suCisgICAgICBpZiAoKHN6ZGVzdCAtPSAzKSA8IDApIHJldHVybiAwOworICAgICAgdWludDMyIGluID0gQmlnRW5kaWFuOjpMb2FkMTYoY3VyX3NyYyk7CisgICAgICBjdXJfZGVzdFswXSA9IGJhc2U2NFtpbiA+PiAxMF07CisgICAgICBpbiAmPSAweDNGRjsKKyAgICAgIGN1cl9kZXN0WzFdID0gYmFzZTY0W2luID4+IDRdOworICAgICAgaW4gJj0gMHgwMEY7CisgICAgICBjdXJfZGVzdFsyXSA9IGJhc2U2NFtpbiA8PCAyXTsKKyAgICAgIGN1cl9kZXN0ICs9IDM7CisgICAgICBpZiAoZG9fcGFkZGluZykgeworICAgICAgICBpZiAoKHN6ZGVzdCAtPSAxKSA8IDApIHJldHVybiAwOworICAgICAgICBjdXJfZGVzdFswXSA9IGtQYWQ2NDsKKyAgICAgICAgY3VyX2Rlc3QgKz0gMTsKKyAgICAgIH0KKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIDM6IHsKKyAgICAgIC8vIFRocmVlIGJ5dGVzIGxlZnQ6IHNhbWUgYXMgaW4gdGhlIGJpZyBsb29wIGFib3ZlLiAgV2UgY2FuJ3QgZG8gdGhpcyBpbgorICAgICAgLy8gdGhlIGxvb3AgYmVjYXVzZSB0aGUgbG9vcCBhYm92ZSBhbHdheXMgcmVhZHMgNCBieXRlcywgYW5kIHRoZSBmb3VydGgKKyAgICAgIC8vIGJ5dGUgaXMgcGFzdCB0aGUgZW5kIG9mIHRoZSBpbnB1dC4KKyAgICAgIGlmICgoc3pkZXN0IC09IDQpIDwgMCkgcmV0dXJuIDA7CisgICAgICB1aW50MzIgaW4gPSAoY3VyX3NyY1swXSA8PCAxNikgKyBCaWdFbmRpYW46OkxvYWQxNihjdXJfc3JjICsgMSk7CisgICAgICBjdXJfZGVzdFswXSA9IGJhc2U2NFtpbiA+PiAxOF07CisgICAgICBpbiAmPSAweDNGRkZGOworICAgICAgY3VyX2Rlc3RbMV0gPSBiYXNlNjRbaW4gPj4gMTJdOworICAgICAgaW4gJj0gMHhGRkY7CisgICAgICBjdXJfZGVzdFsyXSA9IGJhc2U2NFtpbiA+PiA2XTsKKyAgICAgIGluICY9IDB4M0Y7CisgICAgICBjdXJfZGVzdFszXSA9IGJhc2U2NFtpbl07CisgICAgICBjdXJfZGVzdCArPSA0OworICAgICAgYnJlYWs7CisgICAgfQorICAgIGRlZmF1bHQ6CisgICAgICAvLyBTaG91bGQgbm90IGJlIHJlYWNoZWQ6IGJsb2NrcyBvZiA0IGJ5dGVzIGFyZSBoYW5kbGVkCisgICAgICAvLyBpbiB0aGUgd2hpbGUgbG9vcCBiZWZvcmUgdGhpcyBzd2l0Y2ggc3RhdGVtZW50LgorICAgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIkxvZ2ljIHByb2JsZW0/IHN6c3JjID0gIiA8PCBzenNyYzsKKyAgICAgIGJyZWFrOworICB9CisgIHJldHVybiAoY3VyX2Rlc3QgLSBkZXN0KTsKK30KKworc3RhdGljIGNvbnN0IGNoYXIga0Jhc2U2NENoYXJzW10gPQorIkFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky8iOworCitzdGF0aWMgY29uc3QgY2hhciBrV2ViU2FmZUJhc2U2NENoYXJzW10gPQorIkFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5LV8iOworCitpbnQgQmFzZTY0RXNjYXBlKGNvbnN0IHVuc2lnbmVkIGNoYXIgKnNyYywgaW50IHN6c3JjLCBjaGFyICpkZXN0LCBpbnQgc3pkZXN0KSB7CisgIHJldHVybiBCYXNlNjRFc2NhcGVJbnRlcm5hbChzcmMsIHN6c3JjLCBkZXN0LCBzemRlc3QsIGtCYXNlNjRDaGFycywgdHJ1ZSk7Cit9CitpbnQgV2ViU2FmZUJhc2U2NEVzY2FwZShjb25zdCB1bnNpZ25lZCBjaGFyICpzcmMsIGludCBzenNyYywgY2hhciAqZGVzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgIGludCBzemRlc3QsIGJvb2wgZG9fcGFkZGluZykgeworICByZXR1cm4gQmFzZTY0RXNjYXBlSW50ZXJuYWwoc3JjLCBzenNyYywgZGVzdCwgc3pkZXN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga1dlYlNhZmVCYXNlNjRDaGFycywgZG9fcGFkZGluZyk7Cit9CisKK3ZvaWQgQmFzZTY0RXNjYXBlSW50ZXJuYWwoY29uc3QgdW5zaWduZWQgY2hhciogc3JjLCBpbnQgc3pzcmMsCisgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyogZGVzdCwgYm9vbCBkb19wYWRkaW5nLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiBiYXNlNjRfY2hhcnMpIHsKKyAgY29uc3QgaW50IGNhbGNfZXNjYXBlZF9zaXplID0KKyAgICBDYWxjdWxhdGVCYXNlNjRFc2NhcGVkTGVuKHN6c3JjLCBkb19wYWRkaW5nKTsKKyAgZGVzdC0+cmVzaXplKGNhbGNfZXNjYXBlZF9zaXplKTsKKyAgY29uc3QgaW50IGVzY2FwZWRfbGVuID0gQmFzZTY0RXNjYXBlSW50ZXJuYWwoc3JjLCBzenNyYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nX2FzX2FycmF5KGRlc3QpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXN0LT5zaXplKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhc2U2NF9jaGFycywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9fcGFkZGluZyk7CisgIEdPT0dMRV9EQ0hFQ0tfRVEoY2FsY19lc2NhcGVkX3NpemUsIGVzY2FwZWRfbGVuKTsKKyAgZGVzdC0+ZXJhc2UoZXNjYXBlZF9sZW4pOworfQorCit2b2lkIEJhc2U2NEVzY2FwZShjb25zdCB1bnNpZ25lZCBjaGFyICpzcmMsIGludCBzenNyYywKKyAgICAgICAgICAgICAgICAgIHN0cmluZyogZGVzdCwgYm9vbCBkb19wYWRkaW5nKSB7CisgIEJhc2U2NEVzY2FwZUludGVybmFsKHNyYywgc3pzcmMsIGRlc3QsIGRvX3BhZGRpbmcsIGtCYXNlNjRDaGFycyk7Cit9CisKK3ZvaWQgV2ViU2FmZUJhc2U2NEVzY2FwZShjb25zdCB1bnNpZ25lZCBjaGFyICpzcmMsIGludCBzenNyYywKKyAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcgKmRlc3QsIGJvb2wgZG9fcGFkZGluZykgeworICBCYXNlNjRFc2NhcGVJbnRlcm5hbChzcmMsIHN6c3JjLCBkZXN0LCBkb19wYWRkaW5nLCBrV2ViU2FmZUJhc2U2NENoYXJzKTsKK30KKwordm9pZCBCYXNlNjRFc2NhcGUoU3RyaW5nUGllY2Ugc3JjLCBzdHJpbmcqIGRlc3QpIHsKKyAgQmFzZTY0RXNjYXBlKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgdW5zaWduZWQgY2hhcio+KHNyYy5kYXRhKCkpLAorICAgICAgICAgICAgICAgc3JjLnNpemUoKSwgZGVzdCwgdHJ1ZSk7Cit9CisKK3ZvaWQgV2ViU2FmZUJhc2U2NEVzY2FwZShTdHJpbmdQaWVjZSBzcmMsIHN0cmluZyogZGVzdCkgeworICBXZWJTYWZlQmFzZTY0RXNjYXBlKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgdW5zaWduZWQgY2hhcio+KHNyYy5kYXRhKCkpLAorICAgICAgICAgICAgICAgICAgICAgIHNyYy5zaXplKCksIGRlc3QsIGZhbHNlKTsKK30KKwordm9pZCBXZWJTYWZlQmFzZTY0RXNjYXBlV2l0aFBhZGRpbmcoU3RyaW5nUGllY2Ugc3JjLCBzdHJpbmcqIGRlc3QpIHsKKyAgV2ViU2FmZUJhc2U2NEVzY2FwZShyZWludGVycHJldF9jYXN0PGNvbnN0IHVuc2lnbmVkIGNoYXIqPihzcmMuZGF0YSgpKSwKKyAgICAgICAgICAgICAgICAgICAgICBzcmMuc2l6ZSgpLCBkZXN0LCB0cnVlKTsKK30KKworLy8gSGVscGVyIHRvIGFwcGVuZCBhIFVuaWNvZGUgY29kZSBwb2ludCB0byBhIHN0cmluZyBhcyBVVEY4LCB3aXRob3V0IGJyaW5naW5nCisvLyBpbiBhbnkgZXh0ZXJuYWwgZGVwZW5kZW5jaWVzLgoraW50IEVuY29kZUFzVVRGOENoYXIodWludDMyIGNvZGVfcG9pbnQsIGNoYXIqIG91dHB1dCkgeworICB1aW50MzIgdG1wID0gMDsKKyAgaW50IGxlbiA9IDA7CisgIGlmIChjb2RlX3BvaW50IDw9IDB4N2YpIHsKKyAgICB0bXAgPSBjb2RlX3BvaW50OworICAgIGxlbiA9IDE7CisgIH0gZWxzZSBpZiAoY29kZV9wb2ludCA8PSAweDA3ZmYpIHsKKyAgICB0bXAgPSAweDAwMDBjMDgwIHwKKyAgICAgICAgKChjb2RlX3BvaW50ICYgMHgwN2MwKSA8PCAyKSB8CisgICAgICAgIChjb2RlX3BvaW50ICYgMHgwMDNmKTsKKyAgICBsZW4gPSAyOworICB9IGVsc2UgaWYgKGNvZGVfcG9pbnQgPD0gMHhmZmZmKSB7CisgICAgdG1wID0gMHgwMGUwODA4MCB8CisgICAgICAgICgoY29kZV9wb2ludCAmIDB4ZjAwMCkgPDwgNCkgfAorICAgICAgICAoKGNvZGVfcG9pbnQgJiAweDBmYzApIDw8IDIpIHwKKyAgICAgICAgKGNvZGVfcG9pbnQgJiAweDAwM2YpOworICAgIGxlbiA9IDM7CisgIH0gZWxzZSB7CisgICAgLy8gVVRGLTE2IGlzIG9ubHkgZGVmaW5lZCBmb3IgY29kZSBwb2ludHMgdXAgdG8gMHgxMEZGRkYsIGFuZCBVVEYtOCBpcworICAgIC8vIG5vcm1hbGx5IG9ubHkgZGVmaW5lZCB1cCB0byB0aGVyZSBhcyB3ZWxsLgorICAgIHRtcCA9IDB4ZjA4MDgwODAgfAorICAgICAgICAoKGNvZGVfcG9pbnQgJiAweDFjMDAwMCkgPDwgNikgfAorICAgICAgICAoKGNvZGVfcG9pbnQgJiAweDAzZjAwMCkgPDwgNCkgfAorICAgICAgICAoKGNvZGVfcG9pbnQgJiAweDAwMGZjMCkgPDwgMikgfAorICAgICAgICAoY29kZV9wb2ludCAmIDB4MDAzZik7CisgICAgbGVuID0gNDsKKyAgfQorICB0bXAgPSBnaHRvbmwodG1wKTsKKyAgbWVtY3B5KG91dHB1dCwgcmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4oJnRtcCkgKyBzaXplb2YodG1wKSAtIGxlbiwgbGVuKTsKKyAgcmV0dXJuIGxlbjsKK30KKworLy8gVGFibGUgb2YgVVRGLTggY2hhcmFjdGVyIGxlbmd0aHMsIGJhc2VkIG9uIGZpcnN0IGJ5dGUKK3N0YXRpYyBjb25zdCB1bnNpZ25lZCBjaGFyIGtVVEY4TGVuVGJsWzI1Nl0gPSB7CisgIDEsMSwxLDEsMSwxLDEsMSwgMSwxLDEsMSwxLDEsMSwxLCAxLDEsMSwxLDEsMSwxLDEsIDEsMSwxLDEsMSwxLDEsMSwKKyAgMSwxLDEsMSwxLDEsMSwxLCAxLDEsMSwxLDEsMSwxLDEsIDEsMSwxLDEsMSwxLDEsMSwgMSwxLDEsMSwxLDEsMSwxLAorICAxLDEsMSwxLDEsMSwxLDEsIDEsMSwxLDEsMSwxLDEsMSwgMSwxLDEsMSwxLDEsMSwxLCAxLDEsMSwxLDEsMSwxLDEsCisgIDEsMSwxLDEsMSwxLDEsMSwgMSwxLDEsMSwxLDEsMSwxLCAxLDEsMSwxLDEsMSwxLDEsIDEsMSwxLDEsMSwxLDEsMSwKKworICAxLDEsMSwxLDEsMSwxLDEsIDEsMSwxLDEsMSwxLDEsMSwgMSwxLDEsMSwxLDEsMSwxLCAxLDEsMSwxLDEsMSwxLDEsCisgIDEsMSwxLDEsMSwxLDEsMSwgMSwxLDEsMSwxLDEsMSwxLCAxLDEsMSwxLDEsMSwxLDEsIDEsMSwxLDEsMSwxLDEsMSwKKyAgMiwyLDIsMiwyLDIsMiwyLCAyLDIsMiwyLDIsMiwyLDIsIDIsMiwyLDIsMiwyLDIsMiwgMiwyLDIsMiwyLDIsMiwyLAorICAzLDMsMywzLDMsMywzLDMsIDMsMywzLDMsMywzLDMsMywgNCw0LDQsNCw0LDQsNCw0LCA0LDQsNCw0LDQsNCw0LDQKK307CisKKy8vIFJldHVybiBsZW5ndGggb2YgYSBzaW5nbGUgVVRGLTggc291cmNlIGNoYXJhY3RlcgoraW50IFVURjhGaXJzdExldHRlck51bUJ5dGVzKGNvbnN0IGNoYXIqIHNyYywgaW50IGxlbikgeworICBpZiAobGVuID09IDApIHsKKyAgICByZXR1cm4gMDsKKyAgfQorICByZXR1cm4ga1VURjhMZW5UYmxbKnJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgdWludDgqPihzcmMpXTsKK30KKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI3ZDQ3NTcKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaApAQCAtMCwwICsxLDg2OCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIGZyb20gZ29vZ2xlMy9zdHJpbmdzL3N0cnV0aWwuaAorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9TVFVCU19TVFJVVElMX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfU1RVQlNfU1RSVVRJTF9IX18KKworI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2luY2x1ZGUgPHZlY3Rvcj4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cmluZ3BpZWNlLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworI2lmZGVmIF9NU0NfVkVSCisjZGVmaW5lIHN0cnRvbGwgIF9zdHJ0b2k2NAorI2RlZmluZSBzdHJ0b3VsbCBfc3RydG91aTY0CisjZWxpZiBkZWZpbmVkKF9fREVDQ1hYKSAmJiBkZWZpbmVkKF9fb3NmX18pCisvLyBIUCBDKysgb24gVHJ1NjQgZG9lcyBub3QgaGF2ZSBzdHJ0b2xsLCBidXQgc3RydG9sIGlzIGFscmVhZHkgNjQtYml0LgorI2RlZmluZSBzdHJ0b2xsIHN0cnRvbAorI2RlZmluZSBzdHJ0b3VsbCBzdHJ0b3VsCisjZW5kaWYKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gYXNjaWlfaXNhbG51bSgpCisvLyAgICBDaGVjayBpZiBhbiBBU0NJSSBjaGFyYWN0ZXIgaXMgYWxwaGFudW1lcmljLiAgV2UgY2FuJ3QgdXNlIGN0eXBlJ3MKKy8vICAgIGlzYWxudW0oKSBiZWNhdXNlIGl0IGlzIGFmZmVjdGVkIGJ5IGxvY2FsZS4gIFRoaXMgZnVuY3Rpb24gaXMgYXBwbGllZAorLy8gICAgdG8gaWRlbnRpZmllcnMgaW4gdGhlIHByb3RvY29sIGJ1ZmZlciBsYW5ndWFnZSwgbm90IHRvIG5hdHVyYWwtbGFuZ3VhZ2UKKy8vICAgIHN0cmluZ3MsIHNvIGxvY2FsZSBzaG91bGQgbm90IGJlIHRha2VuIGludG8gYWNjb3VudC4KKy8vIGFzY2lpX2lzZGlnaXQoKQorLy8gICAgTGlrZSBhYm92ZSwgYnV0IG9ubHkgYWNjZXB0cyBkaWdpdHMuCisvLyBhc2NpaV9pc3NwYWNlKCkKKy8vICAgIENoZWNrIGlmIHRoZSBjaGFyYWN0ZXIgaXMgYSBzcGFjZSBjaGFyYWN0ZXIuCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2lubGluZSBib29sIGFzY2lpX2lzYWxudW0oY2hhciBjKSB7CisgIHJldHVybiAoJ2EnIDw9IGMgJiYgYyA8PSAneicpIHx8CisgICAgICAgICAoJ0EnIDw9IGMgJiYgYyA8PSAnWicpIHx8CisgICAgICAgICAoJzAnIDw9IGMgJiYgYyA8PSAnOScpOworfQorCitpbmxpbmUgYm9vbCBhc2NpaV9pc2RpZ2l0KGNoYXIgYykgeworICByZXR1cm4gKCcwJyA8PSBjICYmIGMgPD0gJzknKTsKK30KKworaW5saW5lIGJvb2wgYXNjaWlfaXNzcGFjZShjaGFyIGMpIHsKKyAgcmV0dXJuIGMgPT0gJyAnIHx8IGMgPT0gJ1x0JyB8fCBjID09ICdcbicgfHwgYyA9PSAnXHYnIHx8IGMgPT0gJ1xmJyB8fAorICAgICAgYyA9PSAnXHInOworfQorCitpbmxpbmUgYm9vbCBhc2NpaV9pc3VwcGVyKGNoYXIgYykgeworICByZXR1cm4gYyA+PSAnQScgJiYgYyA8PSAnWic7Cit9CisKK2lubGluZSBib29sIGFzY2lpX2lzbG93ZXIoY2hhciBjKSB7CisgIHJldHVybiBjID49ICdhJyAmJiBjIDw9ICd6JzsKK30KKworaW5saW5lIGNoYXIgYXNjaWlfdG91cHBlcihjaGFyIGMpIHsKKyAgcmV0dXJuIGFzY2lpX2lzbG93ZXIoYykgPyBjIC0gKCdhJyAtICdBJykgOiBjOworfQorCitpbmxpbmUgY2hhciBhc2NpaV90b2xvd2VyKGNoYXIgYykgeworICByZXR1cm4gYXNjaWlfaXN1cHBlcihjKSA/IGMgKyAoJ2EnIC0gJ0EnKSA6IGM7Cit9CisKK2lubGluZSBpbnQgaGV4X2RpZ2l0X3RvX2ludChjaGFyIGMpIHsKKyAgLyogQXNzdW1lIEFTQ0lJLiAqLworICBpbnQgeCA9IHN0YXRpY19jYXN0PHVuc2lnbmVkIGNoYXI+KGMpOworICBpZiAoeCA+ICc5JykgeworICAgIHggKz0gOTsKKyAgfQorICByZXR1cm4geCAmIDB4ZjsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gSGFzUHJlZml4U3RyaW5nKCkKKy8vICAgIENoZWNrIGlmIGEgc3RyaW5nIGJlZ2lucyB3aXRoIGEgZ2l2ZW4gcHJlZml4LgorLy8gU3RyaXBQcmVmaXhTdHJpbmcoKQorLy8gICAgR2l2ZW4gYSBzdHJpbmcgYW5kIGEgcHV0YXRpdmUgcHJlZml4LCByZXR1cm5zIHRoZSBzdHJpbmcgbWludXMgdGhlCisvLyAgICBwcmVmaXggc3RyaW5nIGlmIHRoZSBwcmVmaXggbWF0Y2hlcywgb3RoZXJ3aXNlIHRoZSBvcmlnaW5hbAorLy8gICAgc3RyaW5nLgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoraW5saW5lIGJvb2wgSGFzUHJlZml4U3RyaW5nKGNvbnN0IHN0cmluZyYgc3RyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgcHJlZml4KSB7CisgIHJldHVybiBzdHIuc2l6ZSgpID49IHByZWZpeC5zaXplKCkgJiYKKyAgICAgICAgIHN0ci5jb21wYXJlKDAsIHByZWZpeC5zaXplKCksIHByZWZpeCkgPT0gMDsKK30KKworaW5saW5lIHN0cmluZyBTdHJpcFByZWZpeFN0cmluZyhjb25zdCBzdHJpbmcmIHN0ciwgY29uc3Qgc3RyaW5nJiBwcmVmaXgpIHsKKyAgaWYgKEhhc1ByZWZpeFN0cmluZyhzdHIsIHByZWZpeCkpIHsKKyAgICByZXR1cm4gc3RyLnN1YnN0cihwcmVmaXguc2l6ZSgpKTsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gc3RyOworICB9Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIEhhc1N1ZmZpeFN0cmluZygpCisvLyAgICBSZXR1cm4gdHJ1ZSBpZiBzdHIgZW5kcyBpbiBzdWZmaXguCisvLyBTdHJpcFN1ZmZpeFN0cmluZygpCisvLyAgICBHaXZlbiBhIHN0cmluZyBhbmQgYSBwdXRhdGl2ZSBzdWZmaXgsIHJldHVybnMgdGhlIHN0cmluZyBtaW51cyB0aGUKKy8vICAgIHN1ZmZpeCBzdHJpbmcgaWYgdGhlIHN1ZmZpeCBtYXRjaGVzLCBvdGhlcndpc2UgdGhlIG9yaWdpbmFsCisvLyAgICBzdHJpbmcuCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCitpbmxpbmUgYm9vbCBIYXNTdWZmaXhTdHJpbmcoY29uc3Qgc3RyaW5nJiBzdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBzdWZmaXgpIHsKKyAgcmV0dXJuIHN0ci5zaXplKCkgPj0gc3VmZml4LnNpemUoKSAmJgorICAgICAgICAgc3RyLmNvbXBhcmUoc3RyLnNpemUoKSAtIHN1ZmZpeC5zaXplKCksIHN1ZmZpeC5zaXplKCksIHN1ZmZpeCkgPT0gMDsKK30KKworaW5saW5lIHN0cmluZyBTdHJpcFN1ZmZpeFN0cmluZyhjb25zdCBzdHJpbmcmIHN0ciwgY29uc3Qgc3RyaW5nJiBzdWZmaXgpIHsKKyAgaWYgKEhhc1N1ZmZpeFN0cmluZyhzdHIsIHN1ZmZpeCkpIHsKKyAgICByZXR1cm4gc3RyLnN1YnN0cigwLCBzdHIuc2l6ZSgpIC0gc3VmZml4LnNpemUoKSk7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIHN0cjsKKyAgfQorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBTdHJpcFN0cmluZworLy8gICAgUmVwbGFjZXMgYW55IG9jY3VycmVuY2Ugb2YgdGhlIGNoYXJhY3RlciAncmVtb3ZlJyAob3IgdGhlIGNoYXJhY3RlcnMKKy8vICAgIGluICdyZW1vdmUnKSB3aXRoIHRoZSBjaGFyYWN0ZXIgJ3JlcGxhY2V3aXRoJy4KKy8vICAgIEdvb2QgZm9yIGtlZXBpbmcgaHRtbCBjaGFyYWN0ZXJzIG9yIHByb3RvY29sIGNoYXJhY3RlcnMgKFx0KSBvdXQKKy8vICAgIG9mIHBsYWNlcyB3aGVyZSB0aGV5IG1pZ2h0IGNhdXNlIGEgcHJvYmxlbS4KKy8vIFN0cmlwV2hpdGVzcGFjZQorLy8gICAgUmVtb3ZlcyB3aGl0ZXNwYWNlcyBmcm9tIGJvdGggZW5kcyBvZiB0aGUgZ2l2ZW4gc3RyaW5nLgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorTElCUFJPVE9CVUZfRVhQT1JUIHZvaWQgU3RyaXBTdHJpbmcoc3RyaW5nKiBzLCBjb25zdCBjaGFyKiByZW1vdmUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyIHJlcGxhY2V3aXRoKTsKKworTElCUFJPVE9CVUZfRVhQT1JUIHZvaWQgU3RyaXBXaGl0ZXNwYWNlKHN0cmluZyogcyk7CisKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gTG93ZXJTdHJpbmcoKQorLy8gVXBwZXJTdHJpbmcoKQorLy8gVG9VcHBlcigpCisvLyAgICBDb252ZXJ0IHRoZSBjaGFyYWN0ZXJzIGluICJzIiB0byBsb3dlcmNhc2Ugb3IgdXBwZXJjYXNlLiAgQVNDSUktb25seToKKy8vICAgIHRoZXNlIGZ1bmN0aW9ucyBpbnRlbnRpb25hbGx5IGlnbm9yZSBsb2NhbGUgYmVjYXVzZSB0aGV5IGFyZSBhcHBsaWVkIHRvCisvLyAgICBpZGVudGlmaWVycyB1c2VkIGluIHRoZSBQcm90b2NvbCBCdWZmZXIgbGFuZ3VhZ2UsIG5vdCB0byBuYXR1cmFsLWxhbmd1YWdlCisvLyAgICBzdHJpbmdzLgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitpbmxpbmUgdm9pZCBMb3dlclN0cmluZyhzdHJpbmcgKiBzKSB7CisgIHN0cmluZzo6aXRlcmF0b3IgZW5kID0gcy0+ZW5kKCk7CisgIGZvciAoc3RyaW5nOjppdGVyYXRvciBpID0gcy0+YmVnaW4oKTsgaSAhPSBlbmQ7ICsraSkgeworICAgIC8vIHRvbG93ZXIoKSBjaGFuZ2VzIGJhc2VkIG9uIGxvY2FsZS4gIFdlIGRvbid0IHdhbnQgdGhpcyEKKyAgICBpZiAoJ0EnIDw9ICppICYmICppIDw9ICdaJykgKmkgKz0gJ2EnIC0gJ0EnOworICB9Cit9CisKK2lubGluZSB2b2lkIFVwcGVyU3RyaW5nKHN0cmluZyAqIHMpIHsKKyAgc3RyaW5nOjppdGVyYXRvciBlbmQgPSBzLT5lbmQoKTsKKyAgZm9yIChzdHJpbmc6Oml0ZXJhdG9yIGkgPSBzLT5iZWdpbigpOyBpICE9IGVuZDsgKytpKSB7CisgICAgLy8gdG91cHBlcigpIGNoYW5nZXMgYmFzZWQgb24gbG9jYWxlLiAgV2UgZG9uJ3Qgd2FudCB0aGlzIQorICAgIGlmICgnYScgPD0gKmkgJiYgKmkgPD0gJ3onKSAqaSArPSAnQScgLSAnYSc7CisgIH0KK30KKworaW5saW5lIHN0cmluZyBUb1VwcGVyKGNvbnN0IHN0cmluZyYgcykgeworICBzdHJpbmcgb3V0ID0gczsKKyAgVXBwZXJTdHJpbmcoJm91dCk7CisgIHJldHVybiBvdXQ7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIFN0cmluZ1JlcGxhY2UoKQorLy8gICAgR2l2ZSBtZSBhIHN0cmluZyBhbmQgdHdvIHBhdHRlcm5zICJvbGQiIGFuZCAibmV3IiwgYW5kIEkgcmVwbGFjZQorLy8gICAgdGhlIGZpcnN0IGluc3RhbmNlIG9mICJvbGQiIGluIHRoZSBzdHJpbmcgd2l0aCAibmV3IiwgaWYgaXQKKy8vICAgIGV4aXN0cy4gIFJFVFVSTiBhIG5ldyBzdHJpbmcsIHJlZ2FyZGxlc3Mgb2Ygd2hldGhlciB0aGUgcmVwbGFjZW1lbnQKKy8vICAgIGhhcHBlbmVkIG9yIG5vdC4KKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworTElCUFJPVE9CVUZfRVhQT1JUIHN0cmluZyBTdHJpbmdSZXBsYWNlKGNvbnN0IHN0cmluZyYgcywgY29uc3Qgc3RyaW5nJiBvbGRzdWIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBuZXdzdWIsIGJvb2wgcmVwbGFjZV9hbGwpOworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBTcGxpdFN0cmluZ1VzaW5nKCkKKy8vICAgIFNwbGl0IGEgc3RyaW5nIHVzaW5nIGEgY2hhcmFjdGVyIGRlbGltaXRlci4gQXBwZW5kIHRoZSBjb21wb25lbnRzCisvLyAgICB0byAncmVzdWx0Jy4gIElmIHRoZXJlIGFyZSBjb25zZWN1dGl2ZSBkZWxpbWl0ZXJzLCB0aGlzIGZ1bmN0aW9uIHNraXBzCisvLyAgICBvdmVyIGFsbCBvZiB0aGVtLgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorTElCUFJPVE9CVUZfRVhQT1JUIHZvaWQgU3BsaXRTdHJpbmdVc2luZyhjb25zdCBzdHJpbmcmIGZ1bGwsIGNvbnN0IGNoYXIqIGRlbGltLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWN0b3I8c3RyaW5nPiogcmVzKTsKKworLy8gU3BsaXQgYSBzdHJpbmcgdXNpbmcgb25lIG9yIG1vcmUgYnl0ZSBkZWxpbWl0ZXJzLCBwcmVzZW50ZWQKKy8vIGFzIGEgbnVsLXRlcm1pbmF0ZWQgYyBzdHJpbmcuIEFwcGVuZCB0aGUgY29tcG9uZW50cyB0byAncmVzdWx0Jy4KKy8vIElmIHRoZXJlIGFyZSBjb25zZWN1dGl2ZSBkZWxpbWl0ZXJzLCB0aGlzIGZ1bmN0aW9uIHdpbGwgcmV0dXJuCisvLyBjb3JyZXNwb25kaW5nIGVtcHR5IHN0cmluZ3MuICBJZiB5b3Ugd2FudCB0byBkcm9wIHRoZSBlbXB0eQorLy8gc3RyaW5ncywgdHJ5IFNwbGl0U3RyaW5nVXNpbmcoKS4KKy8vCisvLyBJZiAiZnVsbCIgaXMgdGhlIGVtcHR5IHN0cmluZywgeWllbGRzIGFuIGVtcHR5IHN0cmluZyBhcyB0aGUgb25seSB2YWx1ZS4KKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK0xJQlBST1RPQlVGX0VYUE9SVCB2b2lkIFNwbGl0U3RyaW5nQWxsb3dFbXB0eShjb25zdCBzdHJpbmcmIGZ1bGwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogZGVsaW0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjdG9yPHN0cmluZz4qIHJlc3VsdCk7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIFNwbGl0KCkKKy8vICAgIFNwbGl0IGEgc3RyaW5nIHVzaW5nIGEgY2hhcmFjdGVyIGRlbGltaXRlci4KKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK2lubGluZSB2ZWN0b3I8c3RyaW5nPiBTcGxpdCgKKyAgICBjb25zdCBzdHJpbmcmIGZ1bGwsIGNvbnN0IGNoYXIqIGRlbGltLCBib29sIHNraXBfZW1wdHkgPSB0cnVlKSB7CisgIHZlY3RvcjxzdHJpbmc+IHJlc3VsdDsKKyAgaWYgKHNraXBfZW1wdHkpIHsKKyAgICBTcGxpdFN0cmluZ1VzaW5nKGZ1bGwsIGRlbGltLCAmcmVzdWx0KTsKKyAgfSBlbHNlIHsKKyAgICBTcGxpdFN0cmluZ0FsbG93RW1wdHkoZnVsbCwgZGVsaW0sICZyZXN1bHQpOworICB9CisgIHJldHVybiByZXN1bHQ7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIEpvaW5TdHJpbmdzKCkKKy8vICAgIFRoZXNlIG1ldGhvZHMgY29uY2F0ZW5hdGUgYSB2ZWN0b3Igb2Ygc3RyaW5ncyBpbnRvIGEgQysrIHN0cmluZywgdXNpbmcKKy8vICAgIHRoZSBDLXN0cmluZyAiZGVsaW0iIGFzIGEgc2VwYXJhdG9yIGJldHdlZW4gY29tcG9uZW50cy4gVGhlcmUgYXJlIHR3bworLy8gICAgZmxhdm9ycyBvZiB0aGUgZnVuY3Rpb24sIG9uZSBmbGF2b3IgcmV0dXJucyB0aGUgY29uY2F0ZW5hdGVkIHN0cmluZywKKy8vICAgIGFub3RoZXIgdGFrZXMgYSBwb2ludGVyIHRvIHRoZSB0YXJnZXQgc3RyaW5nLiBJbiB0aGUgbGF0dGVyIGNhc2UgdGhlCisvLyAgICB0YXJnZXQgc3RyaW5nIGlzIGNsZWFyZWQgYW5kIG92ZXJ3cml0dGVuLgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorTElCUFJPVE9CVUZfRVhQT1JUIHZvaWQgSm9pblN0cmluZ3MoY29uc3QgdmVjdG9yPHN0cmluZz4mIGNvbXBvbmVudHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiBkZWxpbSwgc3RyaW5nKiByZXN1bHQpOworCitpbmxpbmUgc3RyaW5nIEpvaW5TdHJpbmdzKGNvbnN0IHZlY3RvcjxzdHJpbmc+JiBjb21wb25lbnRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiBkZWxpbSkgeworICBzdHJpbmcgcmVzdWx0OworICBKb2luU3RyaW5ncyhjb21wb25lbnRzLCBkZWxpbSwgJnJlc3VsdCk7CisgIHJldHVybiByZXN1bHQ7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIFVuZXNjYXBlQ0VzY2FwZVNlcXVlbmNlcygpCisvLyAgICBDb3BpZXMgInNvdXJjZSIgdG8gImRlc3QiLCByZXdyaXRpbmcgQy1zdHlsZSBlc2NhcGUgc2VxdWVuY2VzCisvLyAgICAtLSAnXG4nLCAnXHInLCAnXFwnLCAnXG9vbycsIGV0YyAtLSB0byB0aGVpciBBU0NJSQorLy8gICAgZXF1aXZhbGVudHMuICAiZGVzdCIgbXVzdCBiZSBzdWZmaWNpZW50bHkgbGFyZ2UgdG8gaG9sZCBhbGwKKy8vICAgIHRoZSBjaGFyYWN0ZXJzIGluIHRoZSByZXdyaXR0ZW4gc3RyaW5nIChpLmUuIGF0IGxlYXN0IGFzIGxhcmdlCisvLyAgICBhcyBzdHJsZW4oc291cmNlKSArIDEgc2hvdWxkIGJlIHNhZmUsIHNpbmNlIHRoZSByZXBsYWNlbWVudHMKKy8vICAgIGFyZSBhbHdheXMgc2hvcnRlciB0aGFuIHRoZSBvcmlnaW5hbCBlc2NhcGVkIHNlcXVlbmNlcykuICBJdCdzCisvLyAgICBzYWZlIGZvciBzb3VyY2UgYW5kIGRlc3QgdG8gYmUgdGhlIHNhbWUuICBSRVRVUk5TIHRoZSBsZW5ndGgKKy8vICAgIG9mIGRlc3QuCisvLworLy8gICAgSXQgYWxsb3dzIGhleCBzZXF1ZW5jZXMgXHhoaCwgb3IgZ2VuZXJhbGx5IFx4aGhoaGggd2l0aCBhbgorLy8gICAgYXJiaXRyYXJ5IG51bWJlciBvZiBoZXggZGlnaXRzLCBidXQgYWxsIG9mIHRoZW0gdG9nZXRoZXIgbXVzdAorLy8gICAgc3BlY2lmeSBhIHZhbHVlIG9mIGEgc2luZ2xlIGJ5dGUgKGUuZy4gXHgwMDQ1IGlzIGVxdWl2YWxlbnQKKy8vICAgIHRvIFx4NDUsIGFuZCBceDEyMzQgaXMgZXJyb25lb3VzKS4KKy8vCisvLyAgICBJdCBhbHNvIGFsbG93cyBlc2NhcGUgc2VxdWVuY2VzIG9mIHRoZSBmb3JtIFx1aGhoaCAoZXhhY3RseSBmb3VyCisvLyAgICBoZXggZGlnaXRzLCB1cHBlciBvciBsb3dlciBjYXNlKSBvciBcVWhoaGhoaGhoIChleGFjdGx5IGVpZ2h0CisvLyAgICBoZXggZGlnaXRzLCB1cHBlciBvciBsb3dlciBjYXNlKSB0byBzcGVjaWZ5IGEgVW5pY29kZSBjb2RlCisvLyAgICBwb2ludC4gVGhlIGRlc3QgYXJyYXkgd2lsbCBjb250YWluIHRoZSBVVEY4LWVuY29kZWQgdmVyc2lvbiBvZgorLy8gICAgdGhhdCBjb2RlLXBvaW50IChlLmcuLCBpZiBzb3VyY2UgY29udGFpbnMgXHUyMDE5LCB0aGVuIGRlc3Qgd2lsbAorLy8gICAgY29udGFpbiB0aGUgdGhyZWUgYnl0ZXMgMHhFMiwgMHg4MCwgYW5kIDB4OTkpLgorLy8KKy8vICAgIEVycm9yczogSW4gdGhlIGZpcnN0IGZvcm0gb2YgdGhlIGNhbGwsIGVycm9ycyBhcmUgcmVwb3J0ZWQgd2l0aAorLy8gICAgTE9HKEVSUk9SKS4gVGhlIHNhbWUgaXMgdHJ1ZSBmb3IgdGhlIHNlY29uZCBmb3JtIG9mIHRoZSBjYWxsIGlmCisvLyAgICB0aGUgcG9pbnRlciB0byB0aGUgc3RyaW5nIHZlY3RvciBpcyBOVUxMOyBvdGhlcndpc2UsIGVycm9yCisvLyAgICBtZXNzYWdlcyBhcmUgc3RvcmVkIGluIHRoZSB2ZWN0b3IuIEluIGVpdGhlciBjYXNlLCB0aGUgZWZmZWN0IG9uCisvLyAgICB0aGUgZGVzdCBhcnJheSBpcyBub3QgZGVmaW5lZCwgYnV0IHJlc3Qgb2YgdGhlIHNvdXJjZSB3aWxsIGJlCisvLyAgICBwcm9jZXNzZWQuCisvLyAgICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0xJQlBST1RPQlVGX0VYUE9SVCBpbnQgVW5lc2NhcGVDRXNjYXBlU2VxdWVuY2VzKGNvbnN0IGNoYXIqIHNvdXJjZSwgY2hhciogZGVzdCk7CitMSUJQUk9UT0JVRl9FWFBPUlQgaW50IFVuZXNjYXBlQ0VzY2FwZVNlcXVlbmNlcyhjb25zdCBjaGFyKiBzb3VyY2UsIGNoYXIqIGRlc3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWN0b3I8c3RyaW5nPiAqZXJyb3JzKTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gVW5lc2NhcGVDRXNjYXBlU3RyaW5nKCkKKy8vICAgIFRoaXMgZG9lcyB0aGUgc2FtZSB0aGluZyBhcyBVbmVzY2FwZUNFc2NhcGVTZXF1ZW5jZXMsIGJ1dCBjcmVhdGVzCisvLyAgICBhIG5ldyBzdHJpbmcuIFRoZSBjYWxsZXIgZG9lcyBub3QgbmVlZCB0byB3b3JyeSBhYm91dCBhbGxvY2F0aW5nCisvLyAgICBhIGRlc3QgYnVmZmVyLiBUaGlzIHNob3VsZCBiZSB1c2VkIGZvciBub24gcGVyZm9ybWFuY2UgY3JpdGljYWwKKy8vICAgIHRhc2tzIHN1Y2ggYXMgcHJpbnRpbmcgZGVidWcgbWVzc2FnZXMuIEl0IGlzIHNhZmUgZm9yIHNyYyBhbmQgZGVzdAorLy8gICAgdG8gYmUgdGhlIHNhbWUuCisvLworLy8gICAgVGhlIHNlY29uZCBjYWxsIHN0b3JlcyBpdHMgZXJyb3JzIGluIGEgc3VwcGxpZWQgc3RyaW5nIHZlY3Rvci4KKy8vICAgIElmIHRoZSBzdHJpbmcgdmVjdG9yIHBvaW50ZXIgaXMgTlVMTCwgaXQgcmVwb3J0cyB0aGUgZXJyb3JzIHdpdGggTE9HKCkuCisvLworLy8gICAgSW4gdGhlIGZpcnN0IGFuZCBzZWNvbmQgY2FsbHMsIHRoZSBsZW5ndGggb2YgZGVzdCBpcyByZXR1cm5lZC4gSW4gdGhlCisvLyAgICB0aGUgdGhpcmQgY2FsbCwgdGhlIG5ldyBzdHJpbmcgaXMgcmV0dXJuZWQuCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0xJQlBST1RPQlVGX0VYUE9SVCBpbnQgVW5lc2NhcGVDRXNjYXBlU3RyaW5nKGNvbnN0IHN0cmluZyYgc3JjLCBzdHJpbmcqIGRlc3QpOworTElCUFJPVE9CVUZfRVhQT1JUIGludCBVbmVzY2FwZUNFc2NhcGVTdHJpbmcoY29uc3Qgc3RyaW5nJiBzcmMsIHN0cmluZyogZGVzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlY3RvcjxzdHJpbmc+ICplcnJvcnMpOworTElCUFJPVE9CVUZfRVhQT1JUIHN0cmluZyBVbmVzY2FwZUNFc2NhcGVTdHJpbmcoY29uc3Qgc3RyaW5nJiBzcmMpOworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBDRXNjYXBlKCkKKy8vICAgIEVzY2FwZXMgJ3NyYycgdXNpbmcgQy1zdHlsZSBlc2NhcGUgc2VxdWVuY2VzIGFuZCByZXR1cm5zIHRoZSByZXN1bHRpbmcKKy8vICAgIHN0cmluZy4KKy8vCisvLyAgICBFc2NhcGVkIGNoYXJzOiBcbiwgXHIsIFx0LCAiLCAnLCBcLCBhbmQgIWlzcHJpbnQoKS4KKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK0xJQlBST1RPQlVGX0VYUE9SVCBzdHJpbmcgQ0VzY2FwZShjb25zdCBzdHJpbmcmIHNyYyk7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIENFc2NhcGVBbmRBcHBlbmQoKQorLy8gICAgRXNjYXBlcyAnc3JjJyB1c2luZyBDLXN0eWxlIGVzY2FwZSBzZXF1ZW5jZXMsIGFuZCBhcHBlbmRzIHRoZSBlc2NhcGVkCisvLyAgICBzdHJpbmcgdG8gJ2Rlc3QnLgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorTElCUFJPVE9CVUZfRVhQT1JUIHZvaWQgQ0VzY2FwZUFuZEFwcGVuZChTdHJpbmdQaWVjZSBzcmMsIHN0cmluZyogZGVzdCk7CisKK25hbWVzcGFjZSBzdHJpbmdzIHsKKy8vIExpa2UgQ0VzY2FwZSgpIGJ1dCBkb2VzIG5vdCBlc2NhcGUgYnl0ZXMgd2l0aCB0aGUgdXBwZXIgYml0IHNldC4KK0xJQlBST1RPQlVGX0VYUE9SVCBzdHJpbmcgVXRmOFNhZmVDRXNjYXBlKGNvbnN0IHN0cmluZyYgc3JjKTsKKworLy8gTGlrZSBDRXNjYXBlKCkgYnV0IHVzZXMgaGV4IChceCkgZXNjYXBlcyBpbnN0ZWFkIG9mIG9jdGFscy4KK0xJQlBST1RPQlVGX0VYUE9SVCBzdHJpbmcgQ0hleEVzY2FwZShjb25zdCBzdHJpbmcmIHNyYyk7Cit9ICAvLyBuYW1lc3BhY2Ugc3RyaW5ncworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBzdHJ0bzMyKCkKKy8vIHN0cnRvdTMyKCkKKy8vIHN0cnRvNjQoKQorLy8gc3RydG91NjQoKQorLy8gICAgQXJjaGl0ZWN0dXJlLW5ldXRyYWwgcGx1ZyBjb21wYXRpYmxlIHJlcGxhY2VtZW50cyBmb3Igc3RydG9sKCkgYW5kCisvLyAgICBzdHJ0b3VsKCkuICBMb25nJ3MgaGF2ZSBkaWZmZXJlbnQgbGVuZ3RocyBvbiBJTFAtMzIgYW5kIExQLTY0CisvLyAgICBwbGF0Zm9ybXMsIHNvIHVzaW5nIHRoZXNlIGlzIHNhZmVyLCBmcm9tIHRoZSBwb2ludCBvZiB2aWV3IG9mCisvLyAgICBvdmVyZmxvdyBiZWhhdmlvciwgdGhhbiB1c2luZyB0aGUgc3RhbmRhcmQgbGliYyBmdW5jdGlvbnMuCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCitMSUJQUk9UT0JVRl9FWFBPUlQgaW50MzIgc3RydG8zMl9hZGFwdG9yKGNvbnN0IGNoYXIgKm5wdHIsIGNoYXIgKiplbmRwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBiYXNlKTsKK0xJQlBST1RPQlVGX0VYUE9SVCB1aW50MzIgc3RydG91MzJfYWRhcHRvcihjb25zdCBjaGFyICpucHRyLCBjaGFyICoqZW5kcHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBiYXNlKTsKKworaW5saW5lIGludDMyIHN0cnRvMzIoY29uc3QgY2hhciAqbnB0ciwgY2hhciAqKmVuZHB0ciwgaW50IGJhc2UpIHsKKyAgaWYgKHNpemVvZihpbnQzMikgPT0gc2l6ZW9mKGxvbmcpKQorICAgIHJldHVybiBzdHJ0b2wobnB0ciwgZW5kcHRyLCBiYXNlKTsKKyAgZWxzZQorICAgIHJldHVybiBzdHJ0bzMyX2FkYXB0b3IobnB0ciwgZW5kcHRyLCBiYXNlKTsKK30KKworaW5saW5lIHVpbnQzMiBzdHJ0b3UzMihjb25zdCBjaGFyICpucHRyLCBjaGFyICoqZW5kcHRyLCBpbnQgYmFzZSkgeworICBpZiAoc2l6ZW9mKHVpbnQzMikgPT0gc2l6ZW9mKHVuc2lnbmVkIGxvbmcpKQorICAgIHJldHVybiBzdHJ0b3VsKG5wdHIsIGVuZHB0ciwgYmFzZSk7CisgIGVsc2UKKyAgICByZXR1cm4gc3RydG91MzJfYWRhcHRvcihucHRyLCBlbmRwdHIsIGJhc2UpOworfQorCisvLyBGb3Igbm93LCBsb25nIGxvbmcgaXMgNjQtYml0IG9uIGFsbCB0aGUgcGxhdGZvcm1zIHdlIGNhcmUgYWJvdXQsIHNvIHRoZXNlCisvLyBmdW5jdGlvbnMgY2FuIHNpbXBseSBwYXNzIHRoZSBjYWxsIHRvIHN0cnRvW3VdbGwuCitpbmxpbmUgaW50NjQgc3RydG82NChjb25zdCBjaGFyICpucHRyLCBjaGFyICoqZW5kcHRyLCBpbnQgYmFzZSkgeworICBHT09HTEVfQ09NUElMRV9BU1NFUlQoc2l6ZW9mKGludDY0KSA9PSBzaXplb2YobG9uZyBsb25nKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZl9pbnQ2NF9pc19ub3Rfc2l6ZW9mX2xvbmdfbG9uZyk7CisgIHJldHVybiBzdHJ0b2xsKG5wdHIsIGVuZHB0ciwgYmFzZSk7Cit9CisKK2lubGluZSB1aW50NjQgc3RydG91NjQoY29uc3QgY2hhciAqbnB0ciwgY2hhciAqKmVuZHB0ciwgaW50IGJhc2UpIHsKKyAgR09PR0xFX0NPTVBJTEVfQVNTRVJUKHNpemVvZih1aW50NjQpID09IHNpemVvZih1bnNpZ25lZCBsb25nIGxvbmcpLAorICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mX3VpbnQ2NF9pc19ub3Rfc2l6ZW9mX2xvbmdfbG9uZyk7CisgIHJldHVybiBzdHJ0b3VsbChucHRyLCBlbmRwdHIsIGJhc2UpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBzYWZlX3N0cnRvYigpCisvLyBzYWZlX3N0cnRvMzIoKQorLy8gc2FmZV9zdHJ0b3UzMigpCisvLyBzYWZlX3N0cnRvNjQoKQorLy8gc2FmZV9zdHJ0b3U2NCgpCisvLyBzYWZlX3N0cnRvZigpCisvLyBzYWZlX3N0cnRvZCgpCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCitMSUJQUk9UT0JVRl9FWFBPUlQgYm9vbCBzYWZlX3N0cnRvYihTdHJpbmdQaWVjZSBzdHIsIGJvb2wqIHZhbHVlKTsKKworTElCUFJPVE9CVUZfRVhQT1JUIGJvb2wgc2FmZV9zdHJ0bzMyKGNvbnN0IHN0cmluZyYgc3RyLCBpbnQzMiogdmFsdWUpOworTElCUFJPVE9CVUZfRVhQT1JUIGJvb2wgc2FmZV9zdHJ0b3UzMihjb25zdCBzdHJpbmcmIHN0ciwgdWludDMyKiB2YWx1ZSk7CitpbmxpbmUgYm9vbCBzYWZlX3N0cnRvMzIoY29uc3QgY2hhciogc3RyLCBpbnQzMiogdmFsdWUpIHsKKyAgcmV0dXJuIHNhZmVfc3RydG8zMihzdHJpbmcoc3RyKSwgdmFsdWUpOworfQoraW5saW5lIGJvb2wgc2FmZV9zdHJ0bzMyKFN0cmluZ1BpZWNlIHN0ciwgaW50MzIqIHZhbHVlKSB7CisgIHJldHVybiBzYWZlX3N0cnRvMzIoc3RyLlRvU3RyaW5nKCksIHZhbHVlKTsKK30KK2lubGluZSBib29sIHNhZmVfc3RydG91MzIoY29uc3QgY2hhciogc3RyLCB1aW50MzIqIHZhbHVlKSB7CisgIHJldHVybiBzYWZlX3N0cnRvdTMyKHN0cmluZyhzdHIpLCB2YWx1ZSk7Cit9CitpbmxpbmUgYm9vbCBzYWZlX3N0cnRvdTMyKFN0cmluZ1BpZWNlIHN0ciwgdWludDMyKiB2YWx1ZSkgeworICByZXR1cm4gc2FmZV9zdHJ0b3UzMihzdHIuVG9TdHJpbmcoKSwgdmFsdWUpOworfQorCitMSUJQUk9UT0JVRl9FWFBPUlQgYm9vbCBzYWZlX3N0cnRvNjQoY29uc3Qgc3RyaW5nJiBzdHIsIGludDY0KiB2YWx1ZSk7CitMSUJQUk9UT0JVRl9FWFBPUlQgYm9vbCBzYWZlX3N0cnRvdTY0KGNvbnN0IHN0cmluZyYgc3RyLCB1aW50NjQqIHZhbHVlKTsKK2lubGluZSBib29sIHNhZmVfc3RydG82NChjb25zdCBjaGFyKiBzdHIsIGludDY0KiB2YWx1ZSkgeworICByZXR1cm4gc2FmZV9zdHJ0bzY0KHN0cmluZyhzdHIpLCB2YWx1ZSk7Cit9CitpbmxpbmUgYm9vbCBzYWZlX3N0cnRvNjQoU3RyaW5nUGllY2Ugc3RyLCBpbnQ2NCogdmFsdWUpIHsKKyAgcmV0dXJuIHNhZmVfc3RydG82NChzdHIuVG9TdHJpbmcoKSwgdmFsdWUpOworfQoraW5saW5lIGJvb2wgc2FmZV9zdHJ0b3U2NChjb25zdCBjaGFyKiBzdHIsIHVpbnQ2NCogdmFsdWUpIHsKKyAgcmV0dXJuIHNhZmVfc3RydG91NjQoc3RyaW5nKHN0ciksIHZhbHVlKTsKK30KK2lubGluZSBib29sIHNhZmVfc3RydG91NjQoU3RyaW5nUGllY2Ugc3RyLCB1aW50NjQqIHZhbHVlKSB7CisgIHJldHVybiBzYWZlX3N0cnRvdTY0KHN0ci5Ub1N0cmluZygpLCB2YWx1ZSk7Cit9CisKK0xJQlBST1RPQlVGX0VYUE9SVCBib29sIHNhZmVfc3RydG9mKGNvbnN0IGNoYXIqIHN0ciwgZmxvYXQqIHZhbHVlKTsKK0xJQlBST1RPQlVGX0VYUE9SVCBib29sIHNhZmVfc3RydG9kKGNvbnN0IGNoYXIqIHN0ciwgZG91YmxlKiB2YWx1ZSk7CitpbmxpbmUgYm9vbCBzYWZlX3N0cnRvZihjb25zdCBzdHJpbmcmIHN0ciwgZmxvYXQqIHZhbHVlKSB7CisgIHJldHVybiBzYWZlX3N0cnRvZihzdHIuY19zdHIoKSwgdmFsdWUpOworfQoraW5saW5lIGJvb2wgc2FmZV9zdHJ0b2QoY29uc3Qgc3RyaW5nJiBzdHIsIGRvdWJsZSogdmFsdWUpIHsKKyAgcmV0dXJuIHNhZmVfc3RydG9kKHN0ci5jX3N0cigpLCB2YWx1ZSk7Cit9CitpbmxpbmUgYm9vbCBzYWZlX3N0cnRvZihTdHJpbmdQaWVjZSBzdHIsIGZsb2F0KiB2YWx1ZSkgeworICByZXR1cm4gc2FmZV9zdHJ0b2Yoc3RyLlRvU3RyaW5nKCksIHZhbHVlKTsKK30KK2lubGluZSBib29sIHNhZmVfc3RydG9kKFN0cmluZ1BpZWNlIHN0ciwgZG91YmxlKiB2YWx1ZSkgeworICByZXR1cm4gc2FmZV9zdHJ0b2Qoc3RyLlRvU3RyaW5nKCksIHZhbHVlKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gRmFzdEludFRvQnVmZmVyKCkKKy8vIEZhc3RIZXhUb0J1ZmZlcigpCisvLyBGYXN0SGV4NjRUb0J1ZmZlcigpCisvLyBGYXN0SGV4MzJUb0J1ZmZlcigpCisvLyBGYXN0VGltZVRvQnVmZmVyKCkKKy8vICAgIFRoZXNlIGFyZSBpbnRlbmRlZCBmb3Igc3BlZWQuICBGYXN0SW50VG9CdWZmZXIoKSBhc3N1bWVzIHRoZQorLy8gICAgaW50ZWdlciBpcyBub24tbmVnYXRpdmUuICBGYXN0SGV4VG9CdWZmZXIoKSBwdXRzIG91dHB1dCBpbgorLy8gICAgaGV4IHJhdGhlciB0aGFuIGRlY2ltYWwuICBGYXN0VGltZVRvQnVmZmVyKCkgcHV0cyB0aGUgb3V0cHV0CisvLyAgICBpbnRvIFJGQzgyMiBmb3JtYXQuCisvLworLy8gICAgRmFzdEhleDY0VG9CdWZmZXIoKSBwdXRzIGEgNjQtYml0IHVuc2lnbmVkIHZhbHVlIGluIGhleC1mb3JtYXQsCisvLyAgICBwYWRkZWQgdG8gZXhhY3RseSAxNiBieXRlcyAocGx1cyBvbmUgYnl0ZSBmb3IgJ1wwJykKKy8vCisvLyAgICBGYXN0SGV4MzJUb0J1ZmZlcigpIHB1dHMgYSAzMi1iaXQgdW5zaWduZWQgdmFsdWUgaW4gaGV4LWZvcm1hdCwKKy8vICAgIHBhZGRlZCB0byBleGFjdGx5IDggYnl0ZXMgKHBsdXMgb25lIGJ5dGUgZm9yICdcMCcpCisvLworLy8gICAgICAgQWxsIGZ1bmN0aW9ucyB0YWtlIHRoZSBvdXRwdXQgYnVmZmVyIGFzIGFuIGFyZy4KKy8vICAgIFRoZXkgYWxsIHJldHVybiBhIHBvaW50ZXIgdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgb3V0cHV0LAorLy8gICAgd2hpY2ggbWF5IG5vdCBiZSB0aGUgYmVnaW5uaW5nIG9mIHRoZSBpbnB1dCBidWZmZXIuCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIFN1Z2dlc3RlZCBidWZmZXIgc2l6ZSBmb3IgRmFzdFRvQnVmZmVyIGZ1bmN0aW9ucy4gIEFsc28gd29ya3Mgd2l0aAorLy8gRG91YmxlVG9CdWZmZXIoKSBhbmQgRmxvYXRUb0J1ZmZlcigpLgorc3RhdGljIGNvbnN0IGludCBrRmFzdFRvQnVmZmVyU2l6ZSA9IDMyOworCitMSUJQUk9UT0JVRl9FWFBPUlQgY2hhciogRmFzdEludDMyVG9CdWZmZXIoaW50MzIgaSwgY2hhciogYnVmZmVyKTsKK0xJQlBST1RPQlVGX0VYUE9SVCBjaGFyKiBGYXN0SW50NjRUb0J1ZmZlcihpbnQ2NCBpLCBjaGFyKiBidWZmZXIpOworY2hhciogRmFzdFVJbnQzMlRvQnVmZmVyKHVpbnQzMiBpLCBjaGFyKiBidWZmZXIpOyAgLy8gaW5saW5lIGJlbG93CitjaGFyKiBGYXN0VUludDY0VG9CdWZmZXIodWludDY0IGksIGNoYXIqIGJ1ZmZlcik7ICAvLyBpbmxpbmUgYmVsb3cKK0xJQlBST1RPQlVGX0VYUE9SVCBjaGFyKiBGYXN0SGV4VG9CdWZmZXIoaW50IGksIGNoYXIqIGJ1ZmZlcik7CitMSUJQUk9UT0JVRl9FWFBPUlQgY2hhciogRmFzdEhleDY0VG9CdWZmZXIodWludDY0IGksIGNoYXIqIGJ1ZmZlcik7CitMSUJQUk9UT0JVRl9FWFBPUlQgY2hhciogRmFzdEhleDMyVG9CdWZmZXIodWludDMyIGksIGNoYXIqIGJ1ZmZlcik7CisKKy8vIGF0IGxlYXN0IDIyIGJ5dGVzIGxvbmcKK2lubGluZSBjaGFyKiBGYXN0SW50VG9CdWZmZXIoaW50IGksIGNoYXIqIGJ1ZmZlcikgeworICByZXR1cm4gKHNpemVvZihpKSA9PSA0ID8KKyAgICAgICAgICBGYXN0SW50MzJUb0J1ZmZlcihpLCBidWZmZXIpIDogRmFzdEludDY0VG9CdWZmZXIoaSwgYnVmZmVyKSk7Cit9CitpbmxpbmUgY2hhciogRmFzdFVJbnRUb0J1ZmZlcih1bnNpZ25lZCBpbnQgaSwgY2hhciogYnVmZmVyKSB7CisgIHJldHVybiAoc2l6ZW9mKGkpID09IDQgPworICAgICAgICAgIEZhc3RVSW50MzJUb0J1ZmZlcihpLCBidWZmZXIpIDogRmFzdFVJbnQ2NFRvQnVmZmVyKGksIGJ1ZmZlcikpOworfQoraW5saW5lIGNoYXIqIEZhc3RMb25nVG9CdWZmZXIobG9uZyBpLCBjaGFyKiBidWZmZXIpIHsKKyAgcmV0dXJuIChzaXplb2YoaSkgPT0gNCA/CisgICAgICAgICAgRmFzdEludDMyVG9CdWZmZXIoaSwgYnVmZmVyKSA6IEZhc3RJbnQ2NFRvQnVmZmVyKGksIGJ1ZmZlcikpOworfQoraW5saW5lIGNoYXIqIEZhc3RVTG9uZ1RvQnVmZmVyKHVuc2lnbmVkIGxvbmcgaSwgY2hhciogYnVmZmVyKSB7CisgIHJldHVybiAoc2l6ZW9mKGkpID09IDQgPworICAgICAgICAgIEZhc3RVSW50MzJUb0J1ZmZlcihpLCBidWZmZXIpIDogRmFzdFVJbnQ2NFRvQnVmZmVyKGksIGJ1ZmZlcikpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBGYXN0SW50MzJUb0J1ZmZlckxlZnQoKQorLy8gRmFzdFVJbnQzMlRvQnVmZmVyTGVmdCgpCisvLyBGYXN0SW50NjRUb0J1ZmZlckxlZnQoKQorLy8gRmFzdFVJbnQ2NFRvQnVmZmVyTGVmdCgpCisvLworLy8gTGlrZSB0aGUgRmFzdCpUb0J1ZmZlcigpIGZ1bmN0aW9ucyBhYm92ZSwgdGhlc2UgYXJlIGludGVuZGVkIGZvciBzcGVlZC4KKy8vIFVubGlrZSB0aGUgRmFzdCpUb0J1ZmZlcigpIGZ1bmN0aW9ucywgaG93ZXZlciwgdGhlc2UgZnVuY3Rpb25zIHdyaXRlCisvLyB0aGVpciBvdXRwdXQgdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgYnVmZmVyIChoZW5jZSB0aGUgbmFtZSwgYXMgdGhlCisvLyBvdXRwdXQgaXMgbGVmdC1hbGlnbmVkKS4gIFRoZSBjYWxsZXIgaXMgcmVzcG9uc2libGUgZm9yIGVuc3VyaW5nIHRoYXQKKy8vIHRoZSBidWZmZXIgaGFzIGVub3VnaCBzcGFjZSB0byBob2xkIHRoZSBvdXRwdXQuCisvLworLy8gUmV0dXJucyBhIHBvaW50ZXIgdG8gdGhlIGVuZCBvZiB0aGUgc3RyaW5nIChpLmUuIHRoZSBudWxsIGNoYXJhY3RlcgorLy8gdGVybWluYXRpbmcgdGhlIHN0cmluZykuCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0xJQlBST1RPQlVGX0VYUE9SVCBjaGFyKiBGYXN0SW50MzJUb0J1ZmZlckxlZnQoaW50MzIgaSwgY2hhciogYnVmZmVyKTsKK0xJQlBST1RPQlVGX0VYUE9SVCBjaGFyKiBGYXN0VUludDMyVG9CdWZmZXJMZWZ0KHVpbnQzMiBpLCBjaGFyKiBidWZmZXIpOworTElCUFJPVE9CVUZfRVhQT1JUIGNoYXIqIEZhc3RJbnQ2NFRvQnVmZmVyTGVmdChpbnQ2NCBpLCBjaGFyKiBidWZmZXIpOworTElCUFJPVE9CVUZfRVhQT1JUIGNoYXIqIEZhc3RVSW50NjRUb0J1ZmZlckxlZnQodWludDY0IGksIGNoYXIqIGJ1ZmZlcik7CisKKy8vIEp1c3QgZGVmaW5lIHRoZXNlIGluIHRlcm1zIG9mIHRoZSBhYm92ZS4KK2lubGluZSBjaGFyKiBGYXN0VUludDMyVG9CdWZmZXIodWludDMyIGksIGNoYXIqIGJ1ZmZlcikgeworICBGYXN0VUludDMyVG9CdWZmZXJMZWZ0KGksIGJ1ZmZlcik7CisgIHJldHVybiBidWZmZXI7Cit9CitpbmxpbmUgY2hhciogRmFzdFVJbnQ2NFRvQnVmZmVyKHVpbnQ2NCBpLCBjaGFyKiBidWZmZXIpIHsKKyAgRmFzdFVJbnQ2NFRvQnVmZmVyTGVmdChpLCBidWZmZXIpOworICByZXR1cm4gYnVmZmVyOworfQorCitpbmxpbmUgc3RyaW5nIFNpbXBsZUJ0b2EoYm9vbCB2YWx1ZSkgeworICByZXR1cm4gdmFsdWUgPyAidHJ1ZSIgOiAiZmFsc2UiOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBTaW1wbGVJdG9hKCkKKy8vICAgIERlc2NyaXB0aW9uOiBjb252ZXJ0cyBhbiBpbnRlZ2VyIHRvIGEgc3RyaW5nLgorLy8KKy8vICAgIFJldHVybiB2YWx1ZTogc3RyaW5nCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCitMSUJQUk9UT0JVRl9FWFBPUlQgc3RyaW5nIFNpbXBsZUl0b2EoaW50IGkpOworTElCUFJPVE9CVUZfRVhQT1JUIHN0cmluZyBTaW1wbGVJdG9hKHVuc2lnbmVkIGludCBpKTsKK0xJQlBST1RPQlVGX0VYUE9SVCBzdHJpbmcgU2ltcGxlSXRvYShsb25nIGkpOworTElCUFJPVE9CVUZfRVhQT1JUIHN0cmluZyBTaW1wbGVJdG9hKHVuc2lnbmVkIGxvbmcgaSk7CitMSUJQUk9UT0JVRl9FWFBPUlQgc3RyaW5nIFNpbXBsZUl0b2EobG9uZyBsb25nIGkpOworTElCUFJPVE9CVUZfRVhQT1JUIHN0cmluZyBTaW1wbGVJdG9hKHVuc2lnbmVkIGxvbmcgbG9uZyBpKTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gU2ltcGxlRHRvYSgpCisvLyBTaW1wbGVGdG9hKCkKKy8vIERvdWJsZVRvQnVmZmVyKCkKKy8vIEZsb2F0VG9CdWZmZXIoKQorLy8gICAgRGVzY3JpcHRpb246IGNvbnZlcnRzIGEgZG91YmxlIG9yIGZsb2F0IHRvIGEgc3RyaW5nIHdoaWNoLCBpZgorLy8gICAgcGFzc2VkIHRvIE5vTG9jYWxlU3RydG9kKCksIHdpbGwgcHJvZHVjZSB0aGUgZXhhY3Qgc2FtZSBvcmlnaW5hbCBkb3VibGUKKy8vICAgIChleGNlcHQgaW4gY2FzZSBvZiBOYU47IGFsbCBOYU5zIGFyZSBjb25zaWRlcmVkIHRoZSBzYW1lIHZhbHVlKS4KKy8vICAgIFdlIHRyeSB0byBrZWVwIHRoZSBzdHJpbmcgc2hvcnQgYnV0IGl0J3Mgbm90IGd1YXJhbnRlZWQgdG8gYmUgYXMKKy8vICAgIHNob3J0IGFzIHBvc3NpYmxlLgorLy8KKy8vICAgIERvdWJsZVRvQnVmZmVyKCkgYW5kIEZsb2F0VG9CdWZmZXIoKSB3cml0ZSB0aGUgdGV4dCB0byB0aGUgZ2l2ZW4KKy8vICAgIGJ1ZmZlciBhbmQgcmV0dXJuIGl0LiAgVGhlIGJ1ZmZlciBtdXN0IGJlIGF0IGxlYXN0CisvLyAgICBrRG91YmxlVG9CdWZmZXJTaXplIGJ5dGVzIGZvciBkb3VibGVzIGFuZCBrRmxvYXRUb0J1ZmZlclNpemUKKy8vICAgIGJ5dGVzIGZvciBmbG9hdHMuICBrRmFzdFRvQnVmZmVyU2l6ZSBpcyBhbHNvIGd1YXJhbnRlZWQgdG8gYmUgbGFyZ2UKKy8vICAgIGVub3VnaCB0byBob2xkIGVpdGhlci4KKy8vCisvLyAgICBSZXR1cm4gdmFsdWU6IHN0cmluZworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorTElCUFJPVE9CVUZfRVhQT1JUIHN0cmluZyBTaW1wbGVEdG9hKGRvdWJsZSB2YWx1ZSk7CitMSUJQUk9UT0JVRl9FWFBPUlQgc3RyaW5nIFNpbXBsZUZ0b2EoZmxvYXQgdmFsdWUpOworCitMSUJQUk9UT0JVRl9FWFBPUlQgY2hhciogRG91YmxlVG9CdWZmZXIoZG91YmxlIGksIGNoYXIqIGJ1ZmZlcik7CitMSUJQUk9UT0JVRl9FWFBPUlQgY2hhciogRmxvYXRUb0J1ZmZlcihmbG9hdCBpLCBjaGFyKiBidWZmZXIpOworCisvLyBJbiBwcmFjdGljZSwgZG91YmxlcyBzaG91bGQgbmV2ZXIgbmVlZCBtb3JlIHRoYW4gMjQgYnl0ZXMgYW5kIGZsb2F0cworLy8gc2hvdWxkIG5ldmVyIG5lZWQgbW9yZSB0aGFuIDE0IChpbmNsdWRpbmcgbnVsbCB0ZXJtaW5hdG9ycyksIGJ1dCB3ZQorLy8gb3ZlcmVzdGltYXRlIHRvIGJlIHNhZmUuCitzdGF0aWMgY29uc3QgaW50IGtEb3VibGVUb0J1ZmZlclNpemUgPSAzMjsKK3N0YXRpYyBjb25zdCBpbnQga0Zsb2F0VG9CdWZmZXJTaXplID0gMjQ7CisKK25hbWVzcGFjZSBzdHJpbmdzIHsKKworZW51bSBQYWRTcGVjIHsKKyAgTk9fUEFEID0gMSwKKyAgWkVST19QQURfMiwKKyAgWkVST19QQURfMywKKyAgWkVST19QQURfNCwKKyAgWkVST19QQURfNSwKKyAgWkVST19QQURfNiwKKyAgWkVST19QQURfNywKKyAgWkVST19QQURfOCwKKyAgWkVST19QQURfOSwKKyAgWkVST19QQURfMTAsCisgIFpFUk9fUEFEXzExLAorICBaRVJPX1BBRF8xMiwKKyAgWkVST19QQURfMTMsCisgIFpFUk9fUEFEXzE0LAorICBaRVJPX1BBRF8xNSwKKyAgWkVST19QQURfMTYsCit9OworCitzdHJ1Y3QgSGV4IHsKKyAgdWludDY0IHZhbHVlOworICBlbnVtIFBhZFNwZWMgc3BlYzsKKyAgdGVtcGxhdGUgPGNsYXNzIEludD4KKyAgZXhwbGljaXQgSGV4KEludCB2LCBQYWRTcGVjIHMgPSBOT19QQUQpCisgICAgICA6IHNwZWMocykgeworICAgIC8vIFByZXZlbnQgc2lnbi1leHRlbnNpb24gYnkgY2FzdGluZyBpbnRlZ2VycyB0bworICAgIC8vIHRoZWlyIHVuc2lnbmVkIGNvdW50ZXJwYXJ0cy4KKyNpZmRlZiBMQU5HX0NYWDExCisgICAgc3RhdGljX2Fzc2VydCgKKyAgICAgICAgc2l6ZW9mKHYpID09IDEgfHwgc2l6ZW9mKHYpID09IDIgfHwgc2l6ZW9mKHYpID09IDQgfHwgc2l6ZW9mKHYpID09IDgsCisgICAgICAgICJVbmtub3duIGludGVnZXIgdHlwZSIpOworI2VuZGlmCisgICAgdmFsdWUgPSBzaXplb2YodikgPT0gMSA/IHN0YXRpY19jYXN0PHVpbnQ4Pih2KQorICAgICAgICAgIDogc2l6ZW9mKHYpID09IDIgPyBzdGF0aWNfY2FzdDx1aW50MTY+KHYpCisgICAgICAgICAgOiBzaXplb2YodikgPT0gNCA/IHN0YXRpY19jYXN0PHVpbnQzMj4odikKKyAgICAgICAgICA6IHN0YXRpY19jYXN0PHVpbnQ2ND4odik7CisgIH0KK307CisKK3N0cnVjdCBMSUJQUk9UT0JVRl9FWFBPUlQgQWxwaGFOdW0geworICBjb25zdCBjaGFyICpwaWVjZV9kYXRhXzsgIC8vIG1vdmUgdGhlc2UgdG8gc3RyaW5nX3JlZiBldmVudHVhbGx5CisgIHNpemVfdCBwaWVjZV9zaXplXzsgICAgICAgLy8gbW92ZSB0aGVzZSB0byBzdHJpbmdfcmVmIGV2ZW50dWFsbHkKKworICBjaGFyIGRpZ2l0c1trRmFzdFRvQnVmZmVyU2l6ZV07CisKKyAgLy8gTm8gYm9vbCBjdG9yIC0tIGJvb2xzIGNvbnZlcnQgdG8gYW4gaW50ZWdyYWwgdHlwZS4KKyAgLy8gQSBib29sIGN0b3Igd291bGQgYWxzbyBjb252ZXJ0IGluY29taW5nIHBvaW50ZXJzIChibGV0Y2gpLgorCisgIEFscGhhTnVtKGludDMyIGkzMikKKyAgICAgIDogcGllY2VfZGF0YV8oZGlnaXRzKSwKKyAgICAgICAgcGllY2Vfc2l6ZV8oRmFzdEludDMyVG9CdWZmZXJMZWZ0KGkzMiwgZGlnaXRzKSAtICZkaWdpdHNbMF0pIHt9CisgIEFscGhhTnVtKHVpbnQzMiB1MzIpCisgICAgICA6IHBpZWNlX2RhdGFfKGRpZ2l0cyksCisgICAgICAgIHBpZWNlX3NpemVfKEZhc3RVSW50MzJUb0J1ZmZlckxlZnQodTMyLCBkaWdpdHMpIC0gJmRpZ2l0c1swXSkge30KKyAgQWxwaGFOdW0oaW50NjQgaTY0KQorICAgICAgOiBwaWVjZV9kYXRhXyhkaWdpdHMpLAorICAgICAgICBwaWVjZV9zaXplXyhGYXN0SW50NjRUb0J1ZmZlckxlZnQoaTY0LCBkaWdpdHMpIC0gJmRpZ2l0c1swXSkge30KKyAgQWxwaGFOdW0odWludDY0IHU2NCkKKyAgICAgIDogcGllY2VfZGF0YV8oZGlnaXRzKSwKKyAgICAgICAgcGllY2Vfc2l6ZV8oRmFzdFVJbnQ2NFRvQnVmZmVyTGVmdCh1NjQsIGRpZ2l0cykgLSAmZGlnaXRzWzBdKSB7fQorCisgIEFscGhhTnVtKGZsb2F0IGYpCisgICAgOiBwaWVjZV9kYXRhXyhkaWdpdHMpLCBwaWVjZV9zaXplXyhzdHJsZW4oRmxvYXRUb0J1ZmZlcihmLCBkaWdpdHMpKSkge30KKyAgQWxwaGFOdW0oZG91YmxlIGYpCisgICAgOiBwaWVjZV9kYXRhXyhkaWdpdHMpLCBwaWVjZV9zaXplXyhzdHJsZW4oRG91YmxlVG9CdWZmZXIoZiwgZGlnaXRzKSkpIHt9CisKKyAgQWxwaGFOdW0oSGV4IGhleCk7CisKKyAgQWxwaGFOdW0oY29uc3QgY2hhciogY19zdHIpCisgICAgICA6IHBpZWNlX2RhdGFfKGNfc3RyKSwgcGllY2Vfc2l6ZV8oc3RybGVuKGNfc3RyKSkge30KKyAgLy8gVE9ETzogQWRkIGEgc3RyaW5nX3JlZiBjb25zdHJ1Y3RvciwgZXZlbnR1YWxseQorICAvLyBBbHBoYU51bShjb25zdCBTdHJpbmdQaWVjZSAmcGMpIDogcGllY2UocGMpIHt9CisKKyAgQWxwaGFOdW0oY29uc3Qgc3RyaW5nJiBzdHIpCisgICAgICA6IHBpZWNlX2RhdGFfKHN0ci5kYXRhKCkpLCBwaWVjZV9zaXplXyhzdHIuc2l6ZSgpKSB7fQorCisgIEFscGhhTnVtKFN0cmluZ1BpZWNlIHN0cikKKyAgICAgIDogcGllY2VfZGF0YV8oc3RyLmRhdGEoKSksIHBpZWNlX3NpemVfKHN0ci5zaXplKCkpIHt9CisKKyAgc2l6ZV90IHNpemUoKSBjb25zdCB7IHJldHVybiBwaWVjZV9zaXplXzsgfQorICBjb25zdCBjaGFyICpkYXRhKCkgY29uc3QgeyByZXR1cm4gcGllY2VfZGF0YV87IH0KKworIHByaXZhdGU6CisgIC8vIFVzZSAiOiIgbm90ICc6JworICBBbHBoYU51bShjaGFyIGMpOyAgLy8gTk9MSU5UKHJ1bnRpbWUvZXhwbGljaXQpCisKKyAgLy8gRGlzYWxsb3cgY29weSBhbmQgYXNzaWduLgorICBBbHBoYU51bShjb25zdCBBbHBoYU51bSYpOworICB2b2lkIG9wZXJhdG9yPShjb25zdCBBbHBoYU51bSYpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIHN0cmluZ3MKKwordXNpbmcgc3RyaW5nczo6QWxwaGFOdW07CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIFN0ckNhdCgpCisvLyAgICBUaGlzIG1lcmdlcyB0aGUgZ2l2ZW4gc3RyaW5ncyBvciBudW1iZXJzLCB3aXRoIG5vIGRlbGltaXRlci4gIFRoaXMKKy8vICAgIGlzIGRlc2lnbmVkIHRvIGJlIHRoZSBmYXN0ZXN0IHBvc3NpYmxlIHdheSB0byBjb25zdHJ1Y3QgYSBzdHJpbmcgb3V0CisvLyAgICBvZiBhIG1peCBvZiByYXcgQyBzdHJpbmdzLCBzdHJpbmdzLCBib29sIHZhbHVlcywKKy8vICAgIGFuZCBudW1lcmljIHZhbHVlcy4KKy8vCisvLyAgICBEb24ndCB1c2UgdGhpcyBmb3IgdXNlci12aXNpYmxlIHN0cmluZ3MuICBUaGUgbG9jYWxpemF0aW9uIHByb2Nlc3MKKy8vICAgIHdvcmtzIHBvb3JseSBvbiBzdHJpbmdzIGJ1aWx0IHVwIG91dCBvZiBmcmFnbWVudHMuCisvLworLy8gICAgRm9yIGNsYXJpdHkgYW5kIHBlcmZvcm1hbmNlLCBkb24ndCB1c2UgU3RyQ2F0IHdoZW4gYXBwZW5kaW5nIHRvIGEKKy8vICAgIHN0cmluZy4gIEluIHBhcnRpY3VsYXIsIGF2b2lkIHVzaW5nIGFueSBvZiB0aGVzZSAoYW50aS0pcGF0dGVybnM6CisvLyAgICAgIHN0ci5hcHBlbmQoU3RyQ2F0KC4uLikKKy8vICAgICAgc3RyICs9IFN0ckNhdCguLi4pCisvLyAgICAgIHN0ciA9IFN0ckNhdChzdHIsIC4uLikKKy8vICAgIHdoZXJlIHRoZSBsYXN0IGlzIHRoZSB3b3JzZSwgd2l0aCB0aGUgcG90ZW50aWFsIHRvIGNoYW5nZSBhIGxvb3AKKy8vICAgIGZyb20gYSBsaW5lYXIgdGltZSBvcGVyYXRpb24gd2l0aCBPKDEpIGR5bmFtaWMgYWxsb2NhdGlvbnMgaW50byBhCisvLyAgICBxdWFkcmF0aWMgdGltZSBvcGVyYXRpb24gd2l0aCBPKG4pIGR5bmFtaWMgYWxsb2NhdGlvbnMuICBTdHJBcHBlbmQKKy8vICAgIGlzIGEgYmV0dGVyIGNob2ljZSB0aGFuIGFueSBvZiB0aGUgYWJvdmUsIHN1YmplY3QgdG8gdGhlIHJlc3RyaWN0aW9uCisvLyAgICBvZiBTdHJBcHBlbmQoJnN0ciwgYSwgYiwgYywgLi4uKSB0aGF0IG5vbmUgb2YgdGhlIGEsIGIsIGMsIC4uLiBtYXkKKy8vICAgIGJlIGEgcmVmZXJlbmNlIGludG8gc3RyLgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitMSUJQUk9UT0JVRl9FWFBPUlQgc3RyaW5nIFN0ckNhdChjb25zdCBBbHBoYU51bSYgYSwgY29uc3QgQWxwaGFOdW0mIGIpOworTElCUFJPVE9CVUZfRVhQT1JUIHN0cmluZyBTdHJDYXQoY29uc3QgQWxwaGFOdW0mIGEsIGNvbnN0IEFscGhhTnVtJiBiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQWxwaGFOdW0mIGMpOworTElCUFJPVE9CVUZfRVhQT1JUIHN0cmluZyBTdHJDYXQoY29uc3QgQWxwaGFOdW0mIGEsIGNvbnN0IEFscGhhTnVtJiBiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQWxwaGFOdW0mIGMsIGNvbnN0IEFscGhhTnVtJiBkKTsKK0xJQlBST1RPQlVGX0VYUE9SVCBzdHJpbmcgU3RyQ2F0KGNvbnN0IEFscGhhTnVtJiBhLCBjb25zdCBBbHBoYU51bSYgYiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFscGhhTnVtJiBjLCBjb25zdCBBbHBoYU51bSYgZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFscGhhTnVtJiBlKTsKK0xJQlBST1RPQlVGX0VYUE9SVCBzdHJpbmcgU3RyQ2F0KGNvbnN0IEFscGhhTnVtJiBhLCBjb25zdCBBbHBoYU51bSYgYiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFscGhhTnVtJiBjLCBjb25zdCBBbHBoYU51bSYgZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFscGhhTnVtJiBlLCBjb25zdCBBbHBoYU51bSYgZik7CitMSUJQUk9UT0JVRl9FWFBPUlQgc3RyaW5nIFN0ckNhdChjb25zdCBBbHBoYU51bSYgYSwgY29uc3QgQWxwaGFOdW0mIGIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBBbHBoYU51bSYgYywgY29uc3QgQWxwaGFOdW0mIGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBBbHBoYU51bSYgZSwgY29uc3QgQWxwaGFOdW0mIGYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBBbHBoYU51bSYgZyk7CitMSUJQUk9UT0JVRl9FWFBPUlQgc3RyaW5nIFN0ckNhdChjb25zdCBBbHBoYU51bSYgYSwgY29uc3QgQWxwaGFOdW0mIGIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBBbHBoYU51bSYgYywgY29uc3QgQWxwaGFOdW0mIGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBBbHBoYU51bSYgZSwgY29uc3QgQWxwaGFOdW0mIGYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBBbHBoYU51bSYgZywgY29uc3QgQWxwaGFOdW0mIGgpOworTElCUFJPVE9CVUZfRVhQT1JUIHN0cmluZyBTdHJDYXQoY29uc3QgQWxwaGFOdW0mIGEsIGNvbnN0IEFscGhhTnVtJiBiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQWxwaGFOdW0mIGMsIGNvbnN0IEFscGhhTnVtJiBkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQWxwaGFOdW0mIGUsIGNvbnN0IEFscGhhTnVtJiBmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQWxwaGFOdW0mIGcsIGNvbnN0IEFscGhhTnVtJiBoLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQWxwaGFOdW0mIGkpOworCitpbmxpbmUgc3RyaW5nIFN0ckNhdChjb25zdCBBbHBoYU51bSYgYSkgeyByZXR1cm4gc3RyaW5nKGEuZGF0YSgpLCBhLnNpemUoKSk7IH0KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gU3RyQXBwZW5kKCkKKy8vICAgIFNhbWUgYXMgYWJvdmUsIGJ1dCBhZGRzIHRoZSBvdXRwdXQgdG8gdGhlIGdpdmVuIHN0cmluZy4KKy8vICAgIFdBUk5JTkc6IEZvciBzcGVlZCwgU3RyQXBwZW5kIGRvZXMgbm90IHRyeSB0byBjaGVjayBlYWNoIG9mIGl0cyBpbnB1dAorLy8gICAgYXJndW1lbnRzIHRvIGJlIHN1cmUgdGhhdCB0aGV5IGFyZSBub3QgYSBzdWJzZXQgb2YgdGhlIHN0cmluZyBiZWluZworLy8gICAgYXBwZW5kZWQgdG8uICBUaGF0IGlzLCB3aGlsZSB0aGlzIHdpbGwgd29yazoKKy8vCisvLyAgICBzdHJpbmcgcyA9ICJmb28iOworLy8gICAgcyArPSBzOworLy8KKy8vICAgIFRoaXMgd2lsbCBub3QgKG5lY2Vzc2FyaWx5KSB3b3JrOgorLy8KKy8vICAgIHN0cmluZyBzID0gImZvbyI7CisvLyAgICBTdHJBcHBlbmQoJnMsIHMpOworLy8KKy8vICAgIE5vdGU6IHdoaWxlIFN0ckNhdCBzdXBwb3J0cyBhcHBlbmRpbmcgdXAgdG8gOSBhcmd1bWVudHMsIFN0ckFwcGVuZAorLy8gICAgaXMgY3VycmVudGx5IGxpbWl0ZWQgdG8gNC4gIFRoYXQncyByYXJlbHkgYW4gaXNzdWUgZXhjZXB0IHdoZW4KKy8vICAgIGF1dG9tYXRpY2FsbHkgdHJhbnNmb3JtaW5nIFN0ckNhdCB0byBTdHJBcHBlbmQsIGFuZCBjYW4gZWFzaWx5IGJlCisvLyAgICB3b3JrZWQgYXJvdW5kIGFzIGNvbnNlY3V0aXZlIGNhbGxzIHRvIFN0ckFwcGVuZCBhcmUgcXVpdGUgZWZmaWNpZW50LgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitMSUJQUk9UT0JVRl9FWFBPUlQgdm9pZCBTdHJBcHBlbmQoc3RyaW5nKiBkZXN0LCBjb25zdCBBbHBoYU51bSYgYSk7CitMSUJQUk9UT0JVRl9FWFBPUlQgdm9pZCBTdHJBcHBlbmQoc3RyaW5nKiBkZXN0LCBjb25zdCBBbHBoYU51bSYgYSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBBbHBoYU51bSYgYik7CitMSUJQUk9UT0JVRl9FWFBPUlQgdm9pZCBTdHJBcHBlbmQoc3RyaW5nKiBkZXN0LCBjb25zdCBBbHBoYU51bSYgYSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBBbHBoYU51bSYgYiwgY29uc3QgQWxwaGFOdW0mIGMpOworTElCUFJPVE9CVUZfRVhQT1JUIHZvaWQgU3RyQXBwZW5kKHN0cmluZyogZGVzdCwgY29uc3QgQWxwaGFOdW0mIGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQWxwaGFOdW0mIGIsIGNvbnN0IEFscGhhTnVtJiBjLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFscGhhTnVtJiBkKTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gSm9pbigpCisvLyAgICBUaGVzZSBtZXRob2RzIGNvbmNhdGVuYXRlIGEgcmFuZ2Ugb2YgY29tcG9uZW50cyBpbnRvIGEgQysrIHN0cmluZywgdXNpbmcKKy8vICAgIHRoZSBDLXN0cmluZyAiZGVsaW0iIGFzIGEgc2VwYXJhdG9yIGJldHdlZW4gY29tcG9uZW50cy4KKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK3RlbXBsYXRlIDx0eXBlbmFtZSBJdGVyYXRvcj4KK3ZvaWQgSm9pbihJdGVyYXRvciBzdGFydCwgSXRlcmF0b3IgZW5kLAorICAgICAgICAgIGNvbnN0IGNoYXIqIGRlbGltLCBzdHJpbmcqIHJlc3VsdCkgeworICBmb3IgKEl0ZXJhdG9yIGl0ID0gc3RhcnQ7IGl0ICE9IGVuZDsgKytpdCkgeworICAgIGlmIChpdCAhPSBzdGFydCkgeworICAgICAgcmVzdWx0LT5hcHBlbmQoZGVsaW0pOworICAgIH0KKyAgICBTdHJBcHBlbmQocmVzdWx0LCAqaXQpOworICB9Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBSYW5nZT4KK3N0cmluZyBKb2luKGNvbnN0IFJhbmdlJiBjb21wb25lbnRzLAorICAgICAgICAgICAgY29uc3QgY2hhciogZGVsaW0pIHsKKyAgc3RyaW5nIHJlc3VsdDsKKyAgSm9pbihjb21wb25lbnRzLmJlZ2luKCksIGNvbXBvbmVudHMuZW5kKCksIGRlbGltLCAmcmVzdWx0KTsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gVG9IZXgoKQorLy8gICAgUmV0dXJuIGEgbG93ZXItY2FzZSBoZXggc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBnaXZlbiBpbnRlZ2VyLgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorTElCUFJPVE9CVUZfRVhQT1JUIHN0cmluZyBUb0hleCh1aW50NjQgbnVtKTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gR2xvYmFsUmVwbGFjZVN1YnN0cmluZygpCisvLyAgICBSZXBsYWNlcyBhbGwgaW5zdGFuY2VzIG9mIGEgc3Vic3RyaW5nIGluIGEgc3RyaW5nLiAgRG9lcyBub3RoaW5nCisvLyAgICBpZiAnc3Vic3RyaW5nJyBpcyBlbXB0eS4gIFJldHVybnMgdGhlIG51bWJlciBvZiByZXBsYWNlbWVudHMuCisvLworLy8gICAgTk9URTogVGhlIHN0cmluZyBwaWVjZXMgbXVzdCBub3Qgb3ZlcmxhcCBzLgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorTElCUFJPVE9CVUZfRVhQT1JUIGludCBHbG9iYWxSZXBsYWNlU3Vic3RyaW5nKGNvbnN0IHN0cmluZyYgc3Vic3RyaW5nLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgcmVwbGFjZW1lbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nKiBzKTsKKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gQmFzZTY0VW5lc2NhcGUoKQorLy8gICAgQ29udmVydHMgInNyYyIgd2hpY2ggaXMgZW5jb2RlZCBpbiBCYXNlNjQgdG8gaXRzIGJpbmFyeSBlcXVpdmFsZW50IGFuZAorLy8gICAgd3JpdGVzIGl0IHRvICJkZXN0Ii4gSWYgc3JjIGNvbnRhaW5zIGludmFsaWQgY2hhcmFjdGVycywgZGVzdCBpcyBjbGVhcmVkCisvLyAgICBhbmQgdGhlIGZ1bmN0aW9uIHJldHVybnMgZmFsc2UuIFJldHVybnMgdHJ1ZSBvbiBzdWNjZXNzLgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorTElCUFJPVE9CVUZfRVhQT1JUIGJvb2wgQmFzZTY0VW5lc2NhcGUoU3RyaW5nUGllY2Ugc3JjLCBzdHJpbmcqIGRlc3QpOworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBXZWJTYWZlQmFzZTY0VW5lc2NhcGUoKQorLy8gICAgVGhpcyBpcyBhIHZhcmlhdGlvbiBvZiBCYXNlNjRVbmVzY2FwZSB3aGljaCB1c2VzICctJyBpbnN0ZWFkIG9mICcrJywgYW5kCisvLyAgICAnXycgaW5zdGVhZCBvZiAnLycuIHNyYyBpcyBub3QgbnVsbCB0ZXJtaW5hdGVkLCBpbnN0ZWFkIHNwZWNpZnkgbGVuLiBJCisvLyAgICByZWNvbW1lbmQgdGhhdCBzbGVuPHN6ZGVzdCwgYnV0IHdlIGhvbm9yIHN6ZGVzdCBhbnl3YXkuCisvLyAgICBSRVRVUk5TIHRoZSBsZW5ndGggb2YgZGVzdCwgb3IgLTEgaWYgc3JjIGNvbnRhaW5zIGludmFsaWQgY2hhcnMuCisKKy8vICAgIFRoZSB2YXJpYXRpb24gdGhhdCBzdG9yZXMgaW50byBhIHN0cmluZyBjbGVhcnMgdGhlIHN0cmluZyBmaXJzdCwgYW5kCisvLyAgICByZXR1cm5zIGZhbHNlICh3aXRoIGRlc3QgZW1wdHkpIGlmIHNyYyBjb250YWlucyBpbnZhbGlkIGNoYXJzOyBmb3IKKy8vICAgIHRoaXMgdmVyc2lvbiBzcmMgYW5kIGRlc3QgbXVzdCBiZSBkaWZmZXJlbnQgc3RyaW5ncy4KKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK0xJQlBST1RPQlVGX0VYUE9SVCBpbnQgV2ViU2FmZUJhc2U2NFVuZXNjYXBlKGNvbnN0IGNoYXIqIHNyYywgaW50IHNsZW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyKiBkZXN0LCBpbnQgc3pkZXN0KTsKK0xJQlBST1RPQlVGX0VYUE9SVCBib29sIFdlYlNhZmVCYXNlNjRVbmVzY2FwZShTdHJpbmdQaWVjZSBzcmMsIHN0cmluZyogZGVzdCk7CisKKy8vIFJldHVybiB0aGUgbGVuZ3RoIHRvIHVzZSBmb3IgdGhlIG91dHB1dCBidWZmZXIgZ2l2ZW4gdG8gdGhlIGJhc2U2NCBlc2NhcGUKKy8vIHJvdXRpbmVzLiBNYWtlIHN1cmUgdG8gdXNlIHRoZSBzYW1lIHZhbHVlIGZvciBkb19wYWRkaW5nIGluIGJvdGguCisvLyBUaGlzIGZ1bmN0aW9uIG1heSByZXR1cm4gaW5jb3JyZWN0IHJlc3VsdHMgaWYgZ2l2ZW4gaW5wdXRfbGVuIHZhbHVlcyB0aGF0CisvLyBhcmUgZXh0cmVtZWx5IGhpZ2gsIHdoaWNoIHNob3VsZCBoYXBwZW4gcmFyZWx5LgorTElCUFJPVE9CVUZfRVhQT1JUIGludCBDYWxjdWxhdGVCYXNlNjRFc2NhcGVkTGVuKGludCBpbnB1dF9sZW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBkb19wYWRkaW5nKTsKKy8vIFVzZSB0aGlzIHZlcnNpb24gd2hlbiBjYWxsaW5nIEJhc2U2NEVzY2FwZSB3aXRob3V0IGEgZG9fcGFkZGluZyBhcmcuCitMSUJQUk9UT0JVRl9FWFBPUlQgaW50IENhbGN1bGF0ZUJhc2U2NEVzY2FwZWRMZW4oaW50IGlucHV0X2xlbik7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIEJhc2U2NEVzY2FwZSgpCisvLyBXZWJTYWZlQmFzZTY0RXNjYXBlKCkKKy8vICAgIEVuY29kZSAic3JjIiB0byAiZGVzdCIgdXNpbmcgYmFzZTY0IGVuY29kaW5nLgorLy8gICAgc3JjIGlzIG5vdCBudWxsIHRlcm1pbmF0ZWQsIGluc3RlYWQgc3BlY2lmeSBsZW4uCisvLyAgICAnZGVzdCcgc2hvdWxkIGhhdmUgYXQgbGVhc3QgQ2FsY3VsYXRlQmFzZTY0RXNjYXBlZExlbigpIGxlbmd0aC4KKy8vICAgIFJFVFVSTlMgdGhlIGxlbmd0aCBvZiBkZXN0LgorLy8gICAgVGhlIFdlYlNhZmUgdmFyaWF0aW9uIHVzZSAnLScgaW5zdGVhZCBvZiAnKycgYW5kICdfJyBpbnN0ZWFkIG9mICcvJworLy8gICAgc28gdGhhdCB3ZSBjYW4gcGxhY2UgdGhlIG91dCBpbiB0aGUgVVJMIG9yIGNvb2tpZXMgd2l0aG91dCBoYXZpbmcKKy8vICAgIHRvIGVzY2FwZSB0aGVtLiAgSXQgYWxzbyBoYXMgYW4gZXh0cmEgcGFyYW1ldGVyICJkb19wYWRkaW5nIiwKKy8vICAgIHdoaWNoIHdoZW4gc2V0IHRvIGZhbHNlIHdpbGwgcHJldmVudCBwYWRkaW5nIHdpdGggIj0iLgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorTElCUFJPVE9CVUZfRVhQT1JUIGludCBCYXNlNjRFc2NhcGUoY29uc3QgdW5zaWduZWQgY2hhciogc3JjLCBpbnQgc2xlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIqIGRlc3QsIGludCBzemRlc3QpOworTElCUFJPVE9CVUZfRVhQT1JUIGludCBXZWJTYWZlQmFzZTY0RXNjYXBlKAorICAgIGNvbnN0IHVuc2lnbmVkIGNoYXIqIHNyYywgaW50IHNsZW4sIGNoYXIqIGRlc3QsCisgICAgaW50IHN6ZGVzdCwgYm9vbCBkb19wYWRkaW5nKTsKKy8vIEVuY29kZSBzcmMgaW50byBkZXN0IHdpdGggcGFkZGluZy4KK0xJQlBST1RPQlVGX0VYUE9SVCB2b2lkIEJhc2U2NEVzY2FwZShTdHJpbmdQaWVjZSBzcmMsIHN0cmluZyogZGVzdCk7CisvLyBFbmNvZGUgc3JjIGludG8gZGVzdCB3ZWItc2FmZWx5IHdpdGhvdXQgcGFkZGluZy4KK0xJQlBST1RPQlVGX0VYUE9SVCB2b2lkIFdlYlNhZmVCYXNlNjRFc2NhcGUoU3RyaW5nUGllY2Ugc3JjLCBzdHJpbmcqIGRlc3QpOworLy8gRW5jb2RlIHNyYyBpbnRvIGRlc3Qgd2ViLXNhZmVseSB3aXRoIHBhZGRpbmcuCitMSUJQUk9UT0JVRl9FWFBPUlQgdm9pZCBXZWJTYWZlQmFzZTY0RXNjYXBlV2l0aFBhZGRpbmcoU3RyaW5nUGllY2Ugc3JjLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyogZGVzdCk7CisKK0xJQlBST1RPQlVGX0VYUE9SVCB2b2lkIEJhc2U2NEVzY2FwZShjb25zdCB1bnNpZ25lZCBjaGFyKiBzcmMsIGludCBzenNyYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcqIGRlc3QsIGJvb2wgZG9fcGFkZGluZyk7CitMSUJQUk9UT0JVRl9FWFBPUlQgdm9pZCBXZWJTYWZlQmFzZTY0RXNjYXBlKGNvbnN0IHVuc2lnbmVkIGNoYXIqIHNyYywgaW50IHN6c3JjLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcqIGRlc3QsIGJvb2wgZG9fcGFkZGluZyk7CisKK3N0YXRpYyBjb25zdCBpbnQgVVRGbWF4ID0gNDsKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIEVuY29kZUFzVVRGOENoYXIoKQorLy8gIEhlbHBlciB0byBhcHBlbmQgYSBVbmljb2RlIGNvZGUgcG9pbnQgdG8gYSBzdHJpbmcgYXMgVVRGOCwgd2l0aG91dCBicmluZ2luZworLy8gIGluIGFueSBleHRlcm5hbCBkZXBlbmRlbmNpZXMuIFRoZSBvdXRwdXQgYnVmZmVyIG11c3QgYmUgYXMgbGVhc3QgNCBieXRlcworLy8gIGxhcmdlLgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorTElCUFJPVE9CVUZfRVhQT1JUIGludCBFbmNvZGVBc1VURjhDaGFyKHVpbnQzMiBjb2RlX3BvaW50LCBjaGFyKiBvdXRwdXQpOworCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBVVEY4Rmlyc3RMZXR0ZXJOdW1CeXRlcygpCisvLyAgIExlbmd0aCBvZiB0aGUgZmlyc3QgVVRGLTggY2hhcmFjdGVyLgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorTElCUFJPVE9CVUZfRVhQT1JUIGludCBVVEY4Rmlyc3RMZXR0ZXJOdW1CeXRlcyhjb25zdCBjaGFyKiBzcmMsIGludCBsZW4pOworCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfU1RVQlNfU1RSVVRJTF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbF91bml0dGVzdC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbF91bml0dGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ZDYyZmM0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsX3VuaXR0ZXN0LmNjCkBAIC0wLDAgKzEsODEwIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKworI2luY2x1ZGUgPGxvY2FsZS5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0bF91dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZ29vZ2xldGVzdC5oPgorI2luY2x1ZGUgPGd0ZXN0L2d0ZXN0Lmg+CisKKyNpZmRlZiBfV0lOMzIKKyNkZWZpbmUgc25wcmludGYgX3NucHJpbnRmCisjZW5kaWYKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIHsKKworLy8gVE9ETyhrZW50b24pOiAgQ29weSBzdHJ1dGlsIHRlc3RzIGZyb20gZ29vZ2xlMz8KKworVEVTVChTdHJpbmdVdGlsaXR5VGVzdCwgSW1tdW5lVG9Mb2NhbGVzKSB7CisgIC8vIFJlbWVtYmVyIHRoZSBvbGQgbG9jYWxlLgorICBjaGFyKiBvbGRfbG9jYWxlX2NzdHIgPSBzZXRsb2NhbGUoTENfTlVNRVJJQywgTlVMTCk7CisgIEFTU0VSVF9UUlVFKG9sZF9sb2NhbGVfY3N0ciAhPSBOVUxMKTsKKyAgc3RyaW5nIG9sZF9sb2NhbGUgPSBvbGRfbG9jYWxlX2NzdHI7CisKKyAgLy8gU2V0IHRoZSBsb2NhbGUgdG8gIkMiLgorICBBU1NFUlRfVFJVRShzZXRsb2NhbGUoTENfTlVNRVJJQywgIkMiKSAhPSBOVUxMKTsKKworICBFWFBFQ1RfRVEoIjEuNSIsIFNpbXBsZUR0b2EoMS41KSk7CisgIEVYUEVDVF9FUSgiMS41IiwgU2ltcGxlRnRvYSgxLjUpKTsKKworICBpZiAoc2V0bG9jYWxlKExDX05VTUVSSUMsICJlc19FUyIpID09IE5VTEwgJiYKKyAgICAgIHNldGxvY2FsZShMQ19OVU1FUklDLCAiZXNfRVMudXRmOCIpID09IE5VTEwpIHsKKyAgICAvLyBTb21lIHN5c3RlbXMgbWF5IG5vdCBoYXZlIHRoZSBkZXNpcmVkIGxvY2FsZSBhdmFpbGFibGUuCisgICAgR09PR0xFX0xPRyhXQVJOSU5HKQorICAgICAgPDwgIkNvdWxkbid0IHNldCBsb2NhbGUgdG8gZXNfRVMuICBTa2lwcGluZyB0aGlzIHRlc3QuIjsKKyAgfSBlbHNlIHsKKyAgICBFWFBFQ1RfRVEoIjEuNSIsIFNpbXBsZUR0b2EoMS41KSk7CisgICAgRVhQRUNUX0VRKCIxLjUiLCBTaW1wbGVGdG9hKDEuNSkpOworICB9CisKKyAgLy8gUmV0dXJuIHRvIG9yaWdpbmFsIGxvY2FsZS4KKyAgc2V0bG9jYWxlKExDX05VTUVSSUMsIG9sZF9sb2NhbGUuY19zdHIoKSk7Cit9CisKKyNkZWZpbmUgRVhQRUNUX0VRX0FSUkFZKGxlbiwgeCwgeSwgbXNnKSAgICAgICAgICAgICAgICAgICAgIFwKKyAgZm9yIChpbnQgaiA9IDA7IGogPCBsZW47ICsraikgeyAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBFWFBFQ1RfRVEoeFtqXSwgeVtqXSkgPDwgIiIgIyB4IDw8ICIgIT0gIiAjIHkgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgPDwgIiBieXRlICIgPDwgaiA8PCAiOiAiIDw8IG1zZzsgIFwKKyAgfQorCitzdGF0aWMgc3RydWN0IHsKKyAgaW50IHBsYWluX2xlbmd0aDsKKyAgY29uc3QgY2hhciogcGxhaW50ZXh0OworICBjb25zdCBjaGFyKiBjeXBoZXJ0ZXh0OworfSBiYXNlNjRfdGVzdHNbXSA9IHsKKyAgLy8gRW1wdHkgc3RyaW5nLgorICB7IDAsICIiLCAiIn0sCisKKyAgLy8gQmFzaWMgYml0IHBhdHRlcm5zOworICAvLyB2YWx1ZXMgb2J0YWluZWQgd2l0aCAiZWNobyAtbiAnLi4uJyB8IHV1ZW5jb2RlIC1tIHRlc3QiCisKKyAgeyAxLCAiXDAwMCIsICJBQT09IiB9LAorICB7IDEsICJcMDAxIiwgIkFRPT0iIH0sCisgIHsgMSwgIlwwMDIiLCAiQWc9PSIgfSwKKyAgeyAxLCAiXDAwNCIsICJCQT09IiB9LAorICB7IDEsICJcMDEwIiwgIkNBPT0iIH0sCisgIHsgMSwgIlwwMjAiLCAiRUE9PSIgfSwKKyAgeyAxLCAiXDA0MCIsICJJQT09IiB9LAorICB7IDEsICJcMTAwIiwgIlFBPT0iIH0sCisgIHsgMSwgIlwyMDAiLCAiZ0E9PSIgfSwKKworICB7IDEsICJcMzc3IiwgIi93PT0iIH0sCisgIHsgMSwgIlwzNzYiLCAiL2c9PSIgfSwKKyAgeyAxLCAiXDM3NSIsICIvUT09IiB9LAorICB7IDEsICJcMzczIiwgIit3PT0iIH0sCisgIHsgMSwgIlwzNjciLCAiOXc9PSIgfSwKKyAgeyAxLCAiXDM1NyIsICI3dz09IiB9LAorICB7IDEsICJcMzM3IiwgIjN3PT0iIH0sCisgIHsgMSwgIlwyNzciLCAidnc9PSIgfSwKKyAgeyAxLCAiXDE3NyIsICJmdz09IiB9LAorICB7IDIsICJcMDAwXDAwMCIsICJBQUE9IiB9LAorICB7IDIsICJcMDAwXDAwMSIsICJBQUU9IiB9LAorICB7IDIsICJcMDAwXDAwMiIsICJBQUk9IiB9LAorICB7IDIsICJcMDAwXDAwNCIsICJBQVE9IiB9LAorICB7IDIsICJcMDAwXDAxMCIsICJBQWc9IiB9LAorICB7IDIsICJcMDAwXDAyMCIsICJBQkE9IiB9LAorICB7IDIsICJcMDAwXDA0MCIsICJBQ0E9IiB9LAorICB7IDIsICJcMDAwXDEwMCIsICJBRUE9IiB9LAorICB7IDIsICJcMDAwXDIwMCIsICJBSUE9IiB9LAorICB7IDIsICJcMDAxXDAwMCIsICJBUUE9IiB9LAorICB7IDIsICJcMDAyXDAwMCIsICJBZ0E9IiB9LAorICB7IDIsICJcMDA0XDAwMCIsICJCQUE9IiB9LAorICB7IDIsICJcMDEwXDAwMCIsICJDQUE9IiB9LAorICB7IDIsICJcMDIwXDAwMCIsICJFQUE9IiB9LAorICB7IDIsICJcMDQwXDAwMCIsICJJQUE9IiB9LAorICB7IDIsICJcMTAwXDAwMCIsICJRQUE9IiB9LAorICB7IDIsICJcMjAwXDAwMCIsICJnQUE9IiB9LAorCisgIHsgMiwgIlwzNzdcMzc3IiwgIi8vOD0iIH0sCisgIHsgMiwgIlwzNzdcMzc2IiwgIi8vND0iIH0sCisgIHsgMiwgIlwzNzdcMzc1IiwgIi8vMD0iIH0sCisgIHsgMiwgIlwzNzdcMzczIiwgIi8vcz0iIH0sCisgIHsgMiwgIlwzNzdcMzY3IiwgIi8vYz0iIH0sCisgIHsgMiwgIlwzNzdcMzU3IiwgIi8rOD0iIH0sCisgIHsgMiwgIlwzNzdcMzM3IiwgIi85OD0iIH0sCisgIHsgMiwgIlwzNzdcMjc3IiwgIi83OD0iIH0sCisgIHsgMiwgIlwzNzdcMTc3IiwgIi8zOD0iIH0sCisgIHsgMiwgIlwzNzZcMzc3IiwgIi92OD0iIH0sCisgIHsgMiwgIlwzNzVcMzc3IiwgIi9mOD0iIH0sCisgIHsgMiwgIlwzNzNcMzc3IiwgIisvOD0iIH0sCisgIHsgMiwgIlwzNjdcMzc3IiwgIjkvOD0iIH0sCisgIHsgMiwgIlwzNTdcMzc3IiwgIjcvOD0iIH0sCisgIHsgMiwgIlwzMzdcMzc3IiwgIjMvOD0iIH0sCisgIHsgMiwgIlwyNzdcMzc3IiwgInYvOD0iIH0sCisgIHsgMiwgIlwxNzdcMzc3IiwgImYvOD0iIH0sCisKKyAgeyAzLCAiXDAwMFwwMDBcMDAwIiwgIkFBQUEiIH0sCisgIHsgMywgIlwwMDBcMDAwXDAwMSIsICJBQUFCIiB9LAorICB7IDMsICJcMDAwXDAwMFwwMDIiLCAiQUFBQyIgfSwKKyAgeyAzLCAiXDAwMFwwMDBcMDA0IiwgIkFBQUUiIH0sCisgIHsgMywgIlwwMDBcMDAwXDAxMCIsICJBQUFJIiB9LAorICB7IDMsICJcMDAwXDAwMFwwMjAiLCAiQUFBUSIgfSwKKyAgeyAzLCAiXDAwMFwwMDBcMDQwIiwgIkFBQWciIH0sCisgIHsgMywgIlwwMDBcMDAwXDEwMCIsICJBQUJBIiB9LAorICB7IDMsICJcMDAwXDAwMFwyMDAiLCAiQUFDQSIgfSwKKyAgeyAzLCAiXDAwMFwwMDFcMDAwIiwgIkFBRUEiIH0sCisgIHsgMywgIlwwMDBcMDAyXDAwMCIsICJBQUlBIiB9LAorICB7IDMsICJcMDAwXDAwNFwwMDAiLCAiQUFRQSIgfSwKKyAgeyAzLCAiXDAwMFwwMTBcMDAwIiwgIkFBZ0EiIH0sCisgIHsgMywgIlwwMDBcMDIwXDAwMCIsICJBQkFBIiB9LAorICB7IDMsICJcMDAwXDA0MFwwMDAiLCAiQUNBQSIgfSwKKyAgeyAzLCAiXDAwMFwxMDBcMDAwIiwgIkFFQUEiIH0sCisgIHsgMywgIlwwMDBcMjAwXDAwMCIsICJBSUFBIiB9LAorICB7IDMsICJcMDAxXDAwMFwwMDAiLCAiQVFBQSIgfSwKKyAgeyAzLCAiXDAwMlwwMDBcMDAwIiwgIkFnQUEiIH0sCisgIHsgMywgIlwwMDRcMDAwXDAwMCIsICJCQUFBIiB9LAorICB7IDMsICJcMDEwXDAwMFwwMDAiLCAiQ0FBQSIgfSwKKyAgeyAzLCAiXDAyMFwwMDBcMDAwIiwgIkVBQUEiIH0sCisgIHsgMywgIlwwNDBcMDAwXDAwMCIsICJJQUFBIiB9LAorICB7IDMsICJcMTAwXDAwMFwwMDAiLCAiUUFBQSIgfSwKKyAgeyAzLCAiXDIwMFwwMDBcMDAwIiwgImdBQUEiIH0sCisKKyAgeyAzLCAiXDM3N1wzNzdcMzc3IiwgIi8vLy8iIH0sCisgIHsgMywgIlwzNzdcMzc3XDM3NiIsICIvLy8rIiB9LAorICB7IDMsICJcMzc3XDM3N1wzNzUiLCAiLy8vOSIgfSwKKyAgeyAzLCAiXDM3N1wzNzdcMzczIiwgIi8vLzciIH0sCisgIHsgMywgIlwzNzdcMzc3XDM2NyIsICIvLy8zIiB9LAorICB7IDMsICJcMzc3XDM3N1wzNTciLCAiLy8vdiIgfSwKKyAgeyAzLCAiXDM3N1wzNzdcMzM3IiwgIi8vL2YiIH0sCisgIHsgMywgIlwzNzdcMzc3XDI3NyIsICIvLysvIiB9LAorICB7IDMsICJcMzc3XDM3N1wxNzciLCAiLy85LyIgfSwKKyAgeyAzLCAiXDM3N1wzNzZcMzc3IiwgIi8vNy8iIH0sCisgIHsgMywgIlwzNzdcMzc1XDM3NyIsICIvLzMvIiB9LAorICB7IDMsICJcMzc3XDM3M1wzNzciLCAiLy92LyIgfSwKKyAgeyAzLCAiXDM3N1wzNjdcMzc3IiwgIi8vZi8iIH0sCisgIHsgMywgIlwzNzdcMzU3XDM3NyIsICIvKy8vIiB9LAorICB7IDMsICJcMzc3XDMzN1wzNzciLCAiLzkvLyIgfSwKKyAgeyAzLCAiXDM3N1wyNzdcMzc3IiwgIi83Ly8iIH0sCisgIHsgMywgIlwzNzdcMTc3XDM3NyIsICIvMy8vIiB9LAorICB7IDMsICJcMzc2XDM3N1wzNzciLCAiL3YvLyIgfSwKKyAgeyAzLCAiXDM3NVwzNzdcMzc3IiwgIi9mLy8iIH0sCisgIHsgMywgIlwzNzNcMzc3XDM3NyIsICIrLy8vIiB9LAorICB7IDMsICJcMzY3XDM3N1wzNzciLCAiOS8vLyIgfSwKKyAgeyAzLCAiXDM1N1wzNzdcMzc3IiwgIjcvLy8iIH0sCisgIHsgMywgIlwzMzdcMzc3XDM3NyIsICIzLy8vIiB9LAorICB7IDMsICJcMjc3XDM3N1wzNzciLCAidi8vLyIgfSwKKyAgeyAzLCAiXDE3N1wzNzdcMzc3IiwgImYvLy8iIH0sCisKKyAgLy8gUmFuZG9tIG51bWJlcnM6IHZhbHVlcyBvYnRhaW5lZCB3aXRoCisgIC8vCisgIC8vICAjISAvYmluL2Jhc2gKKyAgLy8gIGRkIGJzPSQxIGNvdW50PTEgaWY9L2Rldi9yYW5kb20gb2Y9L3RtcC9iYXIucmFuZG9tCisgIC8vICBvZCAtTiAkMSAtdCBvMSAvdG1wL2Jhci5yYW5kb20KKyAgLy8gIHV1ZW5jb2RlIC1tIHRlc3QgPCAvdG1wL2Jhci5yYW5kb20KKyAgLy8KKyAgLy8gd2hlcmUgJDEgaXMgdGhlIG51bWJlciBvZiBieXRlcyAoMiwgMykKKworICB7IDIsICJcMjQzXDM2MSIsICJvL0U9IiB9LAorICB7IDIsICJcMDI0XDE2NyIsICJGSGM9IiB9LAorICB7IDIsICJcMzEzXDI1MiIsICJ5Nm89IiB9LAorICB7IDIsICJcMDQ2XDA0MSIsICJKaUU9IiB9LAorICB7IDIsICJcMTQ1XDIzNiIsICJaWjQ9IiB9LAorICB7IDIsICJcMjU0XDMyNSIsICJyTlU9IiB9LAorICB7IDIsICJcMDYxXDMzMCIsICJNZGc9IiB9LAorICB7IDIsICJcMjQ1XDAzMiIsICJwUm89IiB9LAorICB7IDIsICJcMDA2XDAwMCIsICJCZ0E9IiB9LAorICB7IDIsICJcMzc1XDEzMSIsICIvVms9IiB9LAorICB7IDIsICJcMzAzXDIxMCIsICJ3NGc9IiB9LAorICB7IDIsICJcMDQwXDAzNyIsICJJQjg9IiB9LAorICB7IDIsICJcMjYxXDM3MiIsICJzZm89IiB9LAorICB7IDIsICJcMzM1XDAxNCIsICIzUXc9IiB9LAorICB7IDIsICJcMjMzXDIxNyIsICJtNDg9IiB9LAorICB7IDIsICJcMzczXDA1NiIsICIreTQ9IiB9LAorICB7IDIsICJcMjQ3XDIzMiIsICJwNW89IiB9LAorICB7IDIsICJcMTA3XDA1MyIsICJSeXM9IiB9LAorICB7IDIsICJcMjA0XDA3NyIsICJoRDg9IiB9LAorICB7IDIsICJcMjc2XDIxMSIsICJ2b2s9IiB9LAorICB7IDIsICJcMzEzXDExMCIsICJ5MGc9IiB9LAorICB7IDIsICJcMzYzXDM3NiIsICI4LzQ9IiB9LAorICB7IDIsICJcMjUxXDIzNCIsICJxWnc9IiB9LAorICB7IDIsICJcMTAzXDI2MiIsICJRN0k9IiB9LAorICB7IDIsICJcMTQyXDMxMiIsICJZc289IiB9LAorICB7IDIsICJcMDY3XDIxMSIsICJONGs9IiB9LAorICB7IDIsICJcMjIwXDAwMSIsICJrQUU9IiB9LAorICB7IDIsICJcMTUyXDI0MCIsICJhcUE9IiB9LAorICB7IDIsICJcMzY3XDA2MSIsICI5ekU9IiB9LAorICB7IDIsICJcMTMzXDI1NSIsICJXNjA9IiB9LAorICB7IDIsICJcMTc2XDAzNSIsICJmaDA9IiB9LAorICB7IDIsICJcMDMyXDIzMSIsICJHcGs9IiB9LAorCisgIHsgMywgIlwwMTNcMDA3XDE0NCIsICJDd2RrIiB9LAorICB7IDMsICJcMDMwXDExMlwxMDYiLCAiR0VwRyIgfSwKKyAgeyAzLCAiXDA0N1wzMjVcMDQ2IiwgIko5VW0iIH0sCisgIHsgMywgIlwzMTBcMTYwXDAyMiIsICJ5SEFTIiB9LAorICB7IDMsICJcMTMxXDEwMFwyMzciLCAiV1VDZiIgfSwKKyAgeyAzLCAiXDA2NFwzNDJcMTM0IiwgIk5PSmMiIH0sCisgIHsgMywgIlwwMTBcMTc3XDAwNCIsICJDSDhFIiB9LAorICB7IDMsICJcMzQ1XDE0N1wyMDUiLCAiNVdlRiIgfSwKKyAgeyAzLCAiXDMwMFwzNDNcMzYwIiwgIndPUHciIH0sCisgIHsgMywgIlwwNjFcMjQwXDIwMSIsICJNYUNCIiB9LAorICB7IDMsICJcMjI1XDMzM1wwNDQiLCAibGRzayIgfSwKKyAgeyAzLCAiXDIxNVwxMzdcMzUyIiwgImpWL3EiIH0sCisgIHsgMywgIlwzNzFcMTQ3XDE2MCIsICIrV2R3IiB9LAorICB7IDMsICJcMDMwXDMyMFwwNTEiLCAiR05BcCIgfSwKKyAgeyAzLCAiXDA0NFwxNzRcMjQxIiwgIkpIeWgiIH0sCisgIHsgMywgIlwyNjBcMTI3XDAzNyIsICJzRmNmIiB9LAorICB7IDMsICJcMTExXDA0NVwwMzMiLCAiU1NVYiIgfSwKKyAgeyAzLCAiXDIwMlwxMTRcMTA3IiwgImdreEgiIH0sCisgIHsgMywgIlwwNTdcMzcxXDA0MiIsICJML2tpIiB9LAorICB7IDMsICJcMjIzXDI0N1wyNDQiLCAiazZlayIgfSwKKyAgeyAzLCAiXDA0N1wyMTZcMTQ0IiwgIko0NWsiIH0sCisgIHsgMywgIlwyMDNcMDcwXDMyNyIsICJnempYIiB9LAorICB7IDMsICJcMjQ3XDE0MFwwNzIiLCAicDJBNiIgfSwKKyAgeyAzLCAiXDEyNFwxMTVcMTE2IiwgIlZFMU8iIH0sCisgIHsgMywgIlwxNTdcMTYyXDA1MCIsICJiM0lvIiB9LAorICB7IDMsICJcMzU3XDIyM1wwMDQiLCAiNzVNRSIgfSwKKyAgeyAzLCAiXDA1MlwxMTdcMTU2IiwgIktrOXUiIH0sCisgIHsgMywgIlwzNDdcMTU0XDAwMCIsICI1MndBIiB9LAorICB7IDMsICJcMzAzXDAxMlwxNDIiLCAid3dwaSIgfSwKKyAgeyAzLCAiXDA2MFwwMzVcMzYyIiwgIk1CM3kiIH0sCisgIHsgMywgIlwxMzBcMjI2XDM2MSIsICJXSmJ4IiB9LAorICB7IDMsICJcMTczXDAxM1wwNzEiLCAiZXdzNSIgfSwKKyAgeyAzLCAiXDMzNlwwMDRcMDI3IiwgIjNnUVgiIH0sCisgIHsgMywgIlwzNTdcMzY2XDIzNCIsICI3L2FjIiB9LAorICB7IDMsICJcMzUzXDMwNFwxMTEiLCAiNjhSSiIgfSwKKyAgeyAzLCAiXDAyNFwyNjRcMTMxIiwgIkZMUloiIH0sCisgIHsgMywgIlwwNzVcMTE0XDI1MSIsICJQVXlwIiB9LAorICB7IDMsICJcMzE1XDAzMVwyMjUiLCAielJtViIgfSwKKyAgeyAzLCAiXDE1NFwyMDFcMjc2IiwgImJJRysiIH0sCisgIHsgMywgIlwyMDBcMDY2XDA3MiIsICJnRFk2IiB9LAorICB7IDMsICJcMTQyXDM1MFwyNjciLCAiWXVpMyIgfSwKKyAgeyAzLCAiXDAzM1wwMDBcMTY2IiwgIkd3QjIiIH0sCisgIHsgMywgIlwyMTBcMDU1XDA3NyIsICJpQzAvIiB9LAorICB7IDMsICJcMzQxXDAzN1wxMjQiLCAiNFI5VSIgfSwKKyAgeyAzLCAiXDE2MVwxMDNcMTUyIiwgImNVTnEiIH0sCisgIHsgMywgIlwyNzBcMTQyXDEzMSIsICJ1R0paIiB9LAorICB7IDMsICJcMzM3XDA3NlwwNzQiLCAiM3o0OCIgfSwKKyAgeyAzLCAiXDM3NVwxMDZcMzYyIiwgIi9VYnkiIH0sCisgIHsgMywgIlwyMjdcMzAxXDEyNyIsICJsOEZYIiB9LAorICB7IDMsICJcMzQwXDAwMlwyMzQiLCAiNEFLYyIgfSwKKyAgeyAzLCAiXDEyMVwwNjRcMDMzIiwgIlVUUWIiIH0sCisgIHsgMywgIlwxNTdcMTM0XDE0MyIsICJiMXhqIiB9LAorICB7IDMsICJcMjQ3XDA1NVwzMjciLCAicHkzWCIgfSwKKyAgeyAzLCAiXDM0MFwxNDJcMDA1IiwgIjRHSUYiIH0sCisgIHsgMywgIlwwNjBcMjYwXDE0MyIsICJNTEJqIiB9LAorICB7IDMsICJcMDc1XDIwM1wxNzAiLCAiUFlONCIgfSwKKyAgeyAzLCAiXDE0M1wxNjBcMDE2IiwgIlkzQU8iIH0sCisgIHsgMywgIlwzMTNcMDEzXDA2MyIsICJ5d3N6IiB9LAorICB7IDMsICJcMTc0XDIzNlwxMzUiLCAiZko1ZCIgfSwKKyAgeyAzLCAiXDEwM1wwNDdcMDI2IiwgIlF5Y1ciIH0sCisgIHsgMywgIlwzNjVcMDA1XDM0MyIsICI5UVhqIiB9LAorICB7IDMsICJcMjcxXDE2MFwyMjMiLCAidVhDVCIgfSwKKyAgeyAzLCAiXDM2MlwyNTVcMTcyIiwgIjhxMTYiIH0sCisgIHsgMywgIlwxMTNcMDEyXDAxNSIsICJTd29OIiB9LAorCisgIC8vIHZhcmlvdXMgbGVuZ3RocywgZ2VuZXJhdGVkIGJ5IHRoaXMgcHl0aG9uIHNjcmlwdDoKKyAgLy8KKyAgLy8gZnJvbSBzdHJpbmcgaW1wb3J0IGxvd2VyY2FzZSBhcyBsYworICAvLyBmb3IgaSBpbiByYW5nZSgyNyk6CisgIC8vICAgcHJpbnQgJ3sgJTJkLCAiJXMiLCVzICIlcyIgfSwnICUgKGksIGxjWzppXSwgJyAnICogKDI2LWkpLAorICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsY1s6aV0uZW5jb2RlKCdiYXNlNjQnKS5zdHJpcCgpKQorCisgIHsgIDAsICIiLCAgICAgICAgICAgICAgICAgICAgICAgICAgICIiIH0sCisgIHsgIDEsICJhIiwgICAgICAgICAgICAgICAgICAgICAgICAgICJZUT09IiB9LAorICB7ICAyLCAiYWIiLCAgICAgICAgICAgICAgICAgICAgICAgICAiWVdJPSIgfSwKKyAgeyAgMywgImFiYyIsICAgICAgICAgICAgICAgICAgICAgICAgIllXSmoiIH0sCisgIHsgIDQsICJhYmNkIiwgICAgICAgICAgICAgICAgICAgICAgICJZV0pqWkE9PSIgfSwKKyAgeyAgNSwgImFiY2RlIiwgICAgICAgICAgICAgICAgICAgICAgIllXSmpaR1U9IiB9LAorICB7ICA2LCAiYWJjZGVmIiwgICAgICAgICAgICAgICAgICAgICAiWVdKalpHVm0iIH0sCisgIHsgIDcsICJhYmNkZWZnIiwgICAgICAgICAgICAgICAgICAgICJZV0pqWkdWbVp3PT0iIH0sCisgIHsgIDgsICJhYmNkZWZnaCIsICAgICAgICAgICAgICAgICAgICJZV0pqWkdWbVoyZz0iIH0sCisgIHsgIDksICJhYmNkZWZnaGkiLCAgICAgICAgICAgICAgICAgICJZV0pqWkdWbVoyaHAiIH0sCisgIHsgMTAsICJhYmNkZWZnaGlqIiwgICAgICAgICAgICAgICAgICJZV0pqWkdWbVoyaHBhZz09IiB9LAorICB7IDExLCAiYWJjZGVmZ2hpamsiLCAgICAgICAgICAgICAgICAiWVdKalpHVm1aMmhwYW1zPSIgfSwKKyAgeyAxMiwgImFiY2RlZmdoaWprbCIsICAgICAgICAgICAgICAgIllXSmpaR1ZtWjJocGFtdHMiIH0sCisgIHsgMTMsICJhYmNkZWZnaGlqa2xtIiwgICAgICAgICAgICAgICJZV0pqWkdWbVoyaHBhbXRzYlE9PSIgfSwKKyAgeyAxNCwgImFiY2RlZmdoaWprbG1uIiwgICAgICAgICAgICAgIllXSmpaR1ZtWjJocGFtdHNiVzQ9IiB9LAorICB7IDE1LCAiYWJjZGVmZ2hpamtsbW5vIiwgICAgICAgICAgICAiWVdKalpHVm1aMmhwYW10c2JXNXYiIH0sCisgIHsgMTYsICJhYmNkZWZnaGlqa2xtbm9wIiwgICAgICAgICAgICJZV0pqWkdWbVoyaHBhbXRzYlc1dmNBPT0iIH0sCisgIHsgMTcsICJhYmNkZWZnaGlqa2xtbm9wcSIsICAgICAgICAgICJZV0pqWkdWbVoyaHBhbXRzYlc1dmNIRT0iIH0sCisgIHsgMTgsICJhYmNkZWZnaGlqa2xtbm9wcXIiLCAgICAgICAgICJZV0pqWkdWbVoyaHBhbXRzYlc1dmNIRnkiIH0sCisgIHsgMTksICJhYmNkZWZnaGlqa2xtbm9wcXJzIiwgICAgICAgICJZV0pqWkdWbVoyaHBhbXRzYlc1dmNIRnljdz09IiB9LAorICB7IDIwLCAiYWJjZGVmZ2hpamtsbW5vcHFyc3QiLCAgICAgICAiWVdKalpHVm1aMmhwYW10c2JXNXZjSEZ5YzNRPSIgfSwKKyAgeyAyMSwgImFiY2RlZmdoaWprbG1ub3BxcnN0dSIsICAgICAgIllXSmpaR1ZtWjJocGFtdHNiVzV2Y0hGeWMzUjEiIH0sCisgIHsgMjIsICJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2IiwgICAgICJZV0pqWkdWbVoyaHBhbXRzYlc1dmNIRnljM1IxZGc9PSIgfSwKKyAgeyAyMywgImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3IiwgICAgIllXSmpaR1ZtWjJocGFtdHNiVzV2Y0hGeWMzUjFkbmM9IiB9LAorICB7IDI0LCAiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4IiwgICAiWVdKalpHVm1aMmhwYW10c2JXNXZjSEZ5YzNSMWRuZDQiIH0sCisgIHsgMjUsICJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5IiwgICJZV0pqWkdWbVoyaHBhbXRzYlc1dmNIRnljM1IxZG5kNGVRPT0iIH0sCisgIHsgMjYsICJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5eiIsICJZV0pqWkdWbVoyaHBhbXRzYlc1dmNIRnljM1IxZG5kNGVYbz0iIH0sCit9OworCitzdGF0aWMgc3RydWN0IHsKKyAgY29uc3QgY2hhciogcGxhaW50ZXh0OworICBjb25zdCBjaGFyKiBjeXBoZXJ0ZXh0OworfSBiYXNlNjRfc3RyaW5nc1tdID0geworICAvLyBTb21lIGdvb2dsZSBxdW90ZXMKKyAgLy8gQ3lwaGVydGV4dCBjcmVhdGVkIHdpdGggInV1ZW5jb2RlIChHTlUgc2hhcnV0aWxzKSA0LjYuMyIKKyAgLy8gKE5vdGUgdGhhdCB3ZSdyZSB0ZXN0aW5nIHRoZSB3ZWJzYWZlIGVuY29kaW5nLCB0aG91Z2gsIHNvIGlmCisgIC8vIHlvdSBhZGQgbWVzc2FnZXMsIGJlIHN1cmUgdG8gcnVuICJ0ciAtLSAnKy8nICctXyciIG9uIHRoZSBvdXRwdXQpCisgIHsgIkkgd2FzIGFsd2F5cyBnb29kIGF0IG1hdGggYW5kIHNjaWVuY2UsIGFuZCBJIG5ldmVyIHJlYWxpemVkICIKKyAgICAidGhhdCB3YXMgdW51c3VhbCBvciBzb21laG93IHVuZGVzaXJhYmxlLiBTbyBvbmUgb2YgdGhlIHRoaW5ncyAiCisgICAgIkkgY2FyZSBhIGxvdCBhYm91dCBpcyBoZWxwaW5nIHRvIHJlbW92ZSB0aGF0IHN0aWdtYSwgIgorICAgICJ0byBzaG93IGdpcmxzIHRoYXQgeW91IGNhbiBiZSBmZW1pbmluZSwgeW91IGNhbiBsaWtlIHRoZSB0aGluZ3MgIgorICAgICJ0aGF0IGdpcmxzIGxpa2UsIGJ1dCB5b3UgY2FuIGFsc28gYmUgcmVhbGx5IGdvb2QgYXQgdGVjaG5vbG9neS4gIgorICAgICJZb3UgY2FuIGJlIHJlYWxseSBnb29kIGF0IGJ1aWxkaW5nIHRoaW5ncy4iCisgICAgIiAtIE1hcmlzc2EgTWV5ZXIsIE5ld3N3ZWVrLCAyMDEwLTEyLTIyIiAiXG4iLAorCisgICAgIlNTQjNZWE1nWVd4M1lYbHpJR2R2YjJRZ1lYUWdiV0YwYUNCaGJtUWdjMk5wWlc1alpTd2dZVzVrSUVrZyIKKyAgICAiYm1WMlpYSWdjbVZoYkdsNlpXUWdkR2hoZENCM1lYTWdkVzUxYzNWaGJDQnZjaUJ6YjIxbGFHOTNJSFZ1IgorICAgICJaR1Z6YVhKaFlteGxMaUJUYnlCdmJtVWdiMllnZEdobElIUm9hVzVuY3lCSklHTmhjbVVnWVNCc2IzUWciCisgICAgIllXSnZkWFFnYVhNZ2FHVnNjR2x1WnlCMGJ5QnlaVzF2ZG1VZ2RHaGhkQ0J6ZEdsbmJXRXNJSFJ2SUhObyIKKyAgICAiYjNjZ1oybHliSE1nZEdoaGRDQjViM1VnWTJGdUlHSmxJR1psYldsdWFXNWxMQ0I1YjNVZ1kyRnVJR3hwIgorICAgICJhMlVnZEdobElIUm9hVzVuY3lCMGFHRjBJR2RwY214eklHeHBhMlVzSUdKMWRDQjViM1VnWTJGdUlHRnMiCisgICAgImMyOGdZbVVnY21WaGJHeDVJR2R2YjJRZ1lYUWdkR1ZqYUc1dmJHOW5lUzRnV1c5MUlHTmhiaUJpWlNCeSIKKyAgICAiWldGc2JIa2daMjl2WkNCaGRDQmlkV2xzWkdsdVp5QjBhR2x1WjNNdUlDMGdUV0Z5YVhOellTQk5aWGxsIgorICAgICJjaXdnVG1WM2MzZGxaV3NzSURJd01UQXRNVEl0TWpJSyIgfSwKKworICB7ICJUeXBpY2FsIGZpcnN0IHllYXIgZm9yIGEgbmV3IGNsdXN0ZXI6ICIKKyAgICAifjAuNSBvdmVyaGVhdGluZyAiCisgICAgIn4xIFBEVSBmYWlsdXJlICIKKyAgICAifjEgcmFjay1tb3ZlICIKKyAgICAifjEgbmV0d29yayByZXdpcmluZyAiCisgICAgIn4yMCByYWNrIGZhaWx1cmVzICIKKyAgICAifjUgcmFja3MgZ28gd29ua3kgIgorICAgICJ+OCBuZXR3b3JrIG1haW50ZW5hbmNlcyAiCisgICAgIn4xMiByb3V0ZXIgcmVsb2FkcyAiCisgICAgIn4zIHJvdXRlciBmYWlsdXJlcyAiCisgICAgIn5kb3plbnMgb2YgbWlub3IgMzAtc2Vjb25kIGJsaXBzIGZvciBkbnMgIgorICAgICJ+MTAwMCBpbmRpdmlkdWFsIG1hY2hpbmUgZmFpbHVyZXMgIgorICAgICJ+dGhvdXNhbmRzIG9mIGhhcmQgZHJpdmUgZmFpbHVyZXMgIgorICAgICJzbG93IGRpc2tzLCBiYWQgbWVtb3J5LCBtaXNjb25maWd1cmVkIG1hY2hpbmVzLCBmbGFreSBtYWNoaW5lcywgZXRjLiIKKyAgICAiIC0gSmVmZiBEZWFuLCBUaGUgSm95cyBvZiBSZWFsIEhhcmR3YXJlIiAiXG4iLAorCisgICAgIlZIbHdhV05oYkNCbWFYSnpkQ0I1WldGeUlHWnZjaUJoSUc1bGR5QmpiSFZ6ZEdWeU9pQi1NQzQxSUc5MiIKKyAgICAiWlhKb1pXRjBhVzVuSUg0eElGQkVWU0JtWVdsc2RYSmxJSDR4SUhKaFkyc3RiVzkyWlNCLU1TQnVaWFIzIgorICAgICJiM0pySUhKbGQybHlhVzVuSUg0eU1DQnlZV05ySUdaaGFXeDFjbVZ6SUg0MUlISmhZMnR6SUdkdklIZHYiCisgICAgImJtdDVJSDQ0SUc1bGRIZHZjbXNnYldGcGJuUmxibUZ1WTJWeklINHhNaUJ5YjNWMFpYSWdjbVZzYjJGayIKKyAgICAiY3lCLU15QnliM1YwWlhJZ1ptRnBiSFZ5WlhNZ2ZtUnZlbVZ1Y3lCdlppQnRhVzV2Y2lBek1DMXpaV052IgorICAgICJibVFnWW14cGNITWdabTl5SUdSdWN5Qi1NVEF3TUNCcGJtUnBkbWxrZFdGc0lHMWhZMmhwYm1VZ1ptRnAiCisgICAgImJIVnlaWE1nZm5Sb2IzVnpZVzVrY3lCdlppQm9ZWEprSUdSeWFYWmxJR1poYVd4MWNtVnpJSE5zYjNjZyIKKyAgICAiWkdsemEzTXNJR0poWkNCdFpXMXZjbmtzSUcxcGMyTnZibVpwWjNWeVpXUWdiV0ZqYUdsdVpYTXNJR1pzIgorICAgICJZV3Q1SUcxaFkyaHBibVZ6TENCbGRHTXVJQzBnU21WbVppQkVaV0Z1TENCVWFHVWdTbTk1Y3lCdlppQlMiCisgICAgIlpXRnNJRWhoY21SM1lYSmxDZyIgfSwKKworICB7ICJJJ20gdGhlIGhlYWQgb2YgdGhlIHdlYnNwYW0gdGVhbSBhdCBHb29nbGUuICAiCisgICAgIlRoYXQgbWVhbnMgdGhhdCBpZiB5b3UgdHlwZSB5b3VyIG5hbWUgaW50byBHb29nbGUgYW5kIGdldCBwb3JuIGJhY2ssICIKKyAgICAiaXQncyBteSBmYXVsdC4gVW5sZXNzIHlvdSdyZSBhIHBvcm4gc3RhciwgaW4gd2hpY2ggY2FzZSBwb3JuIGlzIGEgIgorICAgICJjb21wbGV0ZWx5IHJlYXNvbmFibGUgcmVzcG9uc2UuIgorICAgICIgLSBNYXR0IEN1dHRzLCBHb29nbGUgUGx1cyIgIlxuIiwKKworICAgICJTU2R0SUhSb1pTQm9aV0ZrSUc5bUlIUm9aU0IzWldKemNHRnRJSFJsWVcwZ1lYUWdSMjl2WjJ4bExpQWciCisgICAgIlZHaGhkQ0J0WldGdWN5QjBhR0YwSUdsbUlIbHZkU0IwZVhCbElIbHZkWElnYm1GdFpTQnBiblJ2SUVkdiIKKyAgICAiYjJkc1pTQmhibVFnWjJWMElIQnZjbTRnWW1GamF5d2dhWFFuY3lCdGVTQm1ZWFZzZEM0Z1ZXNXNaWE56IgorICAgICJJSGx2ZFNkeVpTQmhJSEJ2Y200Z2MzUmhjaXdnYVc0Z2QyaHBZMmdnWTJGelpTQndiM0p1SUdseklHRWciCisgICAgIlkyOXRjR3hsZEdWc2VTQnlaV0Z6YjI1aFlteGxJSEpsYzNCdmJuTmxMaUF0SUUxaGRIUWdRM1YwZEhNcyIKKyAgICAiSUVkdmIyZHNaU0JRYkhWekNnIiB9LAorCisgIHsgIkl0IHdpbGwgc3RpbGwgYmUgYSBsb25nIHRpbWUgYmVmb3JlIG1hY2hpbmVzIGFwcHJvYWNoIGh1bWFuIGludGVsbGlnZW5jZS4gIgorICAgICJCdXQgbHVja2lseSwgbWFjaGluZXMgZG9uJ3QgYWN0dWFsbHkgaGF2ZSB0byBiZSBpbnRlbGxpZ2VudDsgIgorICAgICJ0aGV5IGp1c3QgaGF2ZSB0byBmYWtlIGl0LiBBY2Nlc3MgdG8gYSB3ZWFsdGggb2YgaW5mb3JtYXRpb24sICIKKyAgICAiY29tYmluZWQgd2l0aCBhIHJ1ZGltZW50YXJ5IGRlY2lzaW9uLW1ha2luZyBjYXBhY2l0eSwgIgorICAgICJjYW4gb2Z0ZW4gYmUgYWxtb3N0IGFzIHVzZWZ1bC4gT2YgY291cnNlLCB0aGUgcmVzdWx0cyBhcmUgYmV0dGVyIHlldCAiCisgICAgIndoZW4gY291cGxlZCB3aXRoIGludGVsbGlnZW5jZS4gQSByZWZlcmVuY2UgbGlicmFyaWFuIHdpdGggYWNjZXNzIHRvICIKKyAgICAiYSBnb29kIHNlYXJjaCBlbmdpbmUgaXMgYSBmb3JtaWRhYmxlIHRvb2wuIgorICAgICIgLSBDcmFpZyBTaWx2ZXJzdGVpbiwgU2llbWVucyBQaWN0dXJlcyBvZiB0aGUgRnV0dXJlLCBTcHJpbmcgMjAwNCIgIlxuIiwKKworICAgICJTWFFnZDJsc2JDQnpkR2xzYkNCaVpTQmhJR3h2Ym1jZ2RHbHRaU0JpWldadmNtVWdiV0ZqYUdsdVpYTWciCisgICAgIllYQndjbTloWTJnZ2FIVnRZVzRnYVc1MFpXeHNhV2RsYm1ObExpQkNkWFFnYkhWamEybHNlU3dnYldGaiIKKyAgICAiYUdsdVpYTWdaRzl1SjNRZ1lXTjBkV0ZzYkhrZ2FHRjJaU0IwYnlCaVpTQnBiblJsYkd4cFoyVnVkRHNnIgorICAgICJkR2hsZVNCcWRYTjBJR2hoZG1VZ2RHOGdabUZyWlNCcGRDNGdRV05qWlhOeklIUnZJR0VnZDJWaGJIUm8iCisgICAgIklHOW1JR2x1Wm05eWJXRjBhVzl1TENCamIyMWlhVzVsWkNCM2FYUm9JR0VnY25Wa2FXMWxiblJoY25rZyIKKyAgICAiWkdWamFYTnBiMjR0YldGcmFXNW5JR05oY0dGamFYUjVMQ0JqWVc0Z2IyWjBaVzRnWW1VZ1lXeHRiM04wIgorICAgICJJR0Z6SUhWelpXWjFiQzRnVDJZZ1kyOTFjbk5sTENCMGFHVWdjbVZ6ZFd4MGN5QmhjbVVnWW1WMGRHVnkiCisgICAgIklIbGxkQ0IzYUdWdUlHTnZkWEJzWldRZ2QybDBhQ0JwYm5SbGJHeHBaMlZ1WTJVdUlFRWdjbVZtWlhKbCIKKyAgICAiYm1ObElHeHBZbkpoY21saGJpQjNhWFJvSUdGalkyVnpjeUIwYnlCaElHZHZiMlFnYzJWaGNtTm9JR1Z1IgorICAgICJaMmx1WlNCcGN5QmhJR1p2Y20xcFpHRmliR1VnZEc5dmJDNGdMU0JEY21GcFp5QlRhV3gyWlhKemRHVnAiCisgICAgImJpd2dVMmxsYldWdWN5QlFhV04wZFhKbGN5QnZaaUIwYUdVZ1JuVjBkWEpsTENCVGNISnBibWNnTWpBdyIKKyAgICAiTkFvIiB9LAorCisgIC8vIERlZ2VuZXJhdGUgZWRnZSBjYXNlCisgIHsgIiIsCisgICAgIiIgfSwKK307CisKK1RFU1QoQmFzZTY0LCBFc2NhcGVBbmRVbmVzY2FwZSkgeworICAvLyBDaGVjayB0aGUgc2hvcnQgc3RyaW5nczsgdGhpcyB0ZXN0cyB0aGUgbWF0aCAoYW5kIGJvdW5kYXJpZXMpCisgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZW9mKGJhc2U2NF90ZXN0cykgLyBzaXplb2YoYmFzZTY0X3Rlc3RzWzBdKTsgKytpKSB7CisgICAgY2hhciBlbmNvZGVfYnVmZmVyWzEwMF07CisgICAgaW50IGVuY29kZV9sZW5ndGg7CisgICAgY2hhciBkZWNvZGVfYnVmZmVyWzEwMF07CisgICAgaW50IGRlY29kZV9sZW5ndGg7CisgICAgaW50IGN5cGhlcl9sZW5ndGg7CisgICAgc3RyaW5nIGRlY29kZV9zdHI7CisKKyAgICBjb25zdCB1bnNpZ25lZCBjaGFyKiB1bnNpZ25lZF9wbGFpbnRleHQgPQorICAgICAgcmVpbnRlcnByZXRfY2FzdDxjb25zdCB1bnNpZ25lZCBjaGFyKj4oYmFzZTY0X3Rlc3RzW2ldLnBsYWludGV4dCk7CisKKyAgICBTdHJpbmdQaWVjZSBwbGFpbnRleHQoYmFzZTY0X3Rlc3RzW2ldLnBsYWludGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgYmFzZTY0X3Rlc3RzW2ldLnBsYWluX2xlbmd0aCk7CisKKyAgICBjeXBoZXJfbGVuZ3RoID0gc3RybGVuKGJhc2U2NF90ZXN0c1tpXS5jeXBoZXJ0ZXh0KTsKKworICAgIC8vIFRoZSBiYXNpYyBlc2NhcGUgZnVuY3Rpb246CisgICAgbWVtc2V0KGVuY29kZV9idWZmZXIsIDAsIHNpemVvZihlbmNvZGVfYnVmZmVyKSk7CisgICAgZW5jb2RlX2xlbmd0aCA9IEJhc2U2NEVzY2FwZSh1bnNpZ25lZF9wbGFpbnRleHQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXNlNjRfdGVzdHNbaV0ucGxhaW5fbGVuZ3RoLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5jb2RlX2J1ZmZlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihlbmNvZGVfYnVmZmVyKSk7CisgICAgLy8gICAgSXMgaXQgb2YgdGhlIGV4cGVjdGVkIGxlbmd0aD8KKyAgICBFWFBFQ1RfRVEoZW5jb2RlX2xlbmd0aCwgY3lwaGVyX2xlbmd0aCk7CisgICAgLy8gV291bGQgaXQgaGF2ZSBiZWVuIG9rYXkgdG8gYWxsb2NhdGUgb25seSBDYWxjdWxhdGVCYXNlNjRFc2NhcGVMZW4oKT8KKyAgICBFWFBFQ1RfRVEoQ2FsY3VsYXRlQmFzZTY0RXNjYXBlZExlbihiYXNlNjRfdGVzdHNbaV0ucGxhaW5fbGVuZ3RoKSwKKyAgICAgICAgICAgICAgZW5jb2RlX2xlbmd0aCk7CisKKyAgICAvLyAgICBJcyBpdCB0aGUgZXhwZWN0ZWQgZW5jb2RlZCB2YWx1ZT8KKyAgICBBU1NFUlRfU1RSRVEoZW5jb2RlX2J1ZmZlciwgYmFzZTY0X3Rlc3RzW2ldLmN5cGhlcnRleHQpOworCisgICAgLy8gSWYgd2UgZW5jb2RlIGl0IGludG8gYSBidWZmZXIgb2YgZXhhY3RseSB0aGUgcmlnaHQgbGVuZ3RoLi4uCisgICAgbWVtc2V0KGVuY29kZV9idWZmZXIsIDAsIHNpemVvZihlbmNvZGVfYnVmZmVyKSk7CisgICAgZW5jb2RlX2xlbmd0aCA9IEJhc2U2NEVzY2FwZSh1bnNpZ25lZF9wbGFpbnRleHQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXNlNjRfdGVzdHNbaV0ucGxhaW5fbGVuZ3RoLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5jb2RlX2J1ZmZlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN5cGhlcl9sZW5ndGgpOworICAgIC8vICAgIElzIGl0IHN0aWxsIG9mIHRoZSBleHBlY3RlZCBsZW5ndGg/CisgICAgRVhQRUNUX0VRKGVuY29kZV9sZW5ndGgsIGN5cGhlcl9sZW5ndGgpOworCisgICAgLy8gICAgQW5kIGlzIHRoZSB2YWx1ZSBzdGlsbCBjb3JyZWN0PyAgKGkuZS4sIG5vdCBsb3NpbmcgdGhlIGxhc3QgYnl0ZSkKKyAgICBFWFBFQ1RfU1RSRVEoZW5jb2RlX2J1ZmZlciwgYmFzZTY0X3Rlc3RzW2ldLmN5cGhlcnRleHQpOworCisgICAgLy8gSWYgd2UgZGVjb2RlIGl0IGJhY2s6CisgICAgZGVjb2RlX3N0ci5jbGVhcigpOworICAgIEVYUEVDVF9UUlVFKEJhc2U2NFVuZXNjYXBlKAorICAgICAgICBTdHJpbmdQaWVjZShlbmNvZGVfYnVmZmVyLCBjeXBoZXJfbGVuZ3RoKSwgJmRlY29kZV9zdHIpKTsKKworICAgIC8vICAgIElzIGl0IG9mIHRoZSBleHBlY3RlZCBsZW5ndGg/CisgICAgRVhQRUNUX0VRKGJhc2U2NF90ZXN0c1tpXS5wbGFpbl9sZW5ndGgsIGRlY29kZV9zdHIubGVuZ3RoKCkpOworCisgICAgLy8gICAgSXMgaXQgdGhlIGV4cGVjdGVkIGRlY29kZWQgdmFsdWU/CisgICAgRVhQRUNUX0VRKHBsYWludGV4dCwgZGVjb2RlX3N0cik7CisKKyAgICAvLyBMZXQncyB0cnkgd2l0aCBhIHByZS1wb3B1bGF0ZWQgc3RyaW5nLgorICAgIHN0cmluZyBlbmNvZGVkKCJ0aGlzIGp1bmsgc2hvdWxkIGJlIGlnbm9yZWQiKTsKKyAgICBCYXNlNjRFc2NhcGUoc3RyaW5nKGJhc2U2NF90ZXN0c1tpXS5wbGFpbnRleHQsCisgICAgICAgICAgICAgICAgICAgICAgICBiYXNlNjRfdGVzdHNbaV0ucGxhaW5fbGVuZ3RoKSwKKyAgICAgICAgICAgICAgICAgJmVuY29kZWQpOworICAgIEVYUEVDVF9FUShlbmNvZGVkLCBzdHJpbmcoZW5jb2RlX2J1ZmZlciwgY3lwaGVyX2xlbmd0aCkpOworCisgICAgc3RyaW5nIGRlY29kZWQoInRoaXMganVuayBzaG91bGQgYmUgaWdub3JlZCIpOworICAgIEVYUEVDVF9UUlVFKEJhc2U2NFVuZXNjYXBlKAorICAgICAgICBTdHJpbmdQaWVjZShlbmNvZGVfYnVmZmVyLCBjeXBoZXJfbGVuZ3RoKSwgJmRlY29kZWQpKTsKKyAgICBFWFBFQ1RfRVEoZGVjb2RlZC5zaXplKCksIGJhc2U2NF90ZXN0c1tpXS5wbGFpbl9sZW5ndGgpOworICAgIEVYUEVDVF9FUV9BUlJBWShkZWNvZGVkLnNpemUoKSwgZGVjb2RlZCwgYmFzZTY0X3Rlc3RzW2ldLnBsYWludGV4dCwgaSk7CisKKyAgICAvLyBPdXIgZGVjb2RlciB0cmVhdHMgdGhlIHBhZGRpbmcgJz0nIGNoYXJhY3RlcnMgYXQgdGhlIGVuZCBhcworICAgIC8vIG9wdGlvbmFsIChidXQgaWYgdGhlcmUgYXJlIGFueSwgdGhlcmUgbXVzdCBiZSB0aGUgY29ycmVjdAorICAgIC8vIG51bWJlciBvZiB0aGVtLikgIElmIGVuY29kZV9idWZmZXIgaGFzIGFueSwgcnVuIHNvbWUgYWRkaXRpb25hbAorICAgIC8vIHRlc3RzIHRoYXQgZmlkZGxlIHdpdGggdGhlbS4KKyAgICBjaGFyKiBmaXJzdF9lcXVhbHMgPSBzdHJjaHIoZW5jb2RlX2J1ZmZlciwgJz0nKTsKKyAgICBpZiAoZmlyc3RfZXF1YWxzKSB7CisgICAgICAvLyBIb3cgbWFueSBlcXVhbHMgc2lnbnMgZG9lcyB0aGUgc3RyaW5nIHN0YXJ0IHdpdGg/CisgICAgICBpbnQgZXF1YWxzID0gKCooZmlyc3RfZXF1YWxzKzEpID09ICc9JykgPyAyIDogMTsKKworICAgICAgLy8gVHJ5IGNob3BwaW5nIG9mZiB0aGUgZXF1YWxzIHNpZ24ocykgZW50aXJlbHkuICBUaGUgZGVjb2RlcgorICAgICAgLy8gc2hvdWxkIHN0aWxsIGJlIG9rYXkgd2l0aCB0aGlzLgorICAgICAgc3RyaW5nIGRlY29kZWQyKCJ0aGlzIGp1bmsgc2hvdWxkIGFsc28gYmUgaWdub3JlZCIpOworICAgICAgKmZpcnN0X2VxdWFscyA9ICdcMCc7CisgICAgICBFWFBFQ1RfVFJVRShCYXNlNjRVbmVzY2FwZSgKKyAgICAgICAgICBTdHJpbmdQaWVjZShlbmNvZGVfYnVmZmVyLCBmaXJzdF9lcXVhbHMgLSBlbmNvZGVfYnVmZmVyKSwgJmRlY29kZWQyKSk7CisgICAgICBFWFBFQ1RfRVEoZGVjb2RlZC5zaXplKCksIGJhc2U2NF90ZXN0c1tpXS5wbGFpbl9sZW5ndGgpOworICAgICAgRVhQRUNUX0VRX0FSUkFZKGRlY29kZWQuc2l6ZSgpLCBkZWNvZGVkLCBiYXNlNjRfdGVzdHNbaV0ucGxhaW50ZXh0LCBpKTsKKworICAgICAgLy8gTm93IHRlc3QgY2hvcHBpbmcgb2ZmIHRoZSBlcXVhbHMgc2lnbihzKSBhbmQgYWRkaW5nCisgICAgICAvLyB3aGl0ZXNwYWNlLiAgT3VyIGRlY29kZXIgc2hvdWxkIHN0aWxsIGFjY2VwdCB0aGlzLgorICAgICAgZGVjb2RlZDIuYXNzaWduKCJ0aGlzIGp1bmsgc2hvdWxkIGJlIGlnbm9yZWQiKTsKKyAgICAgICpmaXJzdF9lcXVhbHMgPSAnICc7CisgICAgICAqKGZpcnN0X2VxdWFscysxKSA9ICdcMCc7CisgICAgICBFWFBFQ1RfVFJVRShCYXNlNjRVbmVzY2FwZSgKKyAgICAgICAgICBTdHJpbmdQaWVjZShlbmNvZGVfYnVmZmVyLCBmaXJzdF9lcXVhbHMgLSBlbmNvZGVfYnVmZmVyICsgMSksCisgICAgICAgICAgJmRlY29kZWQyKSk7CisgICAgICBFWFBFQ1RfRVEoZGVjb2RlZC5zaXplKCksIGJhc2U2NF90ZXN0c1tpXS5wbGFpbl9sZW5ndGgpOworICAgICAgRVhQRUNUX0VRX0FSUkFZKGRlY29kZWQuc2l6ZSgpLCBkZWNvZGVkLCBiYXNlNjRfdGVzdHNbaV0ucGxhaW50ZXh0LCBpKTsKKworICAgICAgLy8gTm93IHN0aWNrIGEgYmFkIGNoYXJhY3RlciBhdCB0aGUgZW5kIG9mIHRoZSBzdHJpbmcuICBUaGUgZGVjb2RlcgorICAgICAgLy8gc2hvdWxkIHJlZnVzZSB0aGlzIHN0cmluZy4KKyAgICAgIGRlY29kZWQyLmFzc2lnbigidGhpcyBqdW5rIHNob3VsZCBiZSBpZ25vcmVkIik7CisgICAgICAqZmlyc3RfZXF1YWxzID0gJz8nOworICAgICAgKihmaXJzdF9lcXVhbHMrMSkgPSAnXDAnOworICAgICAgRVhQRUNUX1RSVUUoCisgICAgICAgICAgIUJhc2U2NFVuZXNjYXBlKAorICAgICAgICAgICAgICBTdHJpbmdQaWVjZShlbmNvZGVfYnVmZmVyLCBmaXJzdF9lcXVhbHMgLSBlbmNvZGVfYnVmZmVyICsgMSksCisgICAgICAgICAgICAgICZkZWNvZGVkMikpOworCisgICAgICBpbnQgbGVuOworCisgICAgICAvLyBUZXN0IHdoaXRlc3BhY2UgbWl4ZWQgd2l0aCB0aGUgcGFkZGluZy4gIChlZyAiQUEgPSA9ICIpICBUaGUKKyAgICAgIC8vIGRlY29kZXIgc2hvdWxkIGFjY2VwdCB0aGlzLgorICAgICAgaWYgKGVxdWFscyA9PSAyKSB7CisgICAgICAgIHNucHJpbnRmKGZpcnN0X2VxdWFscywgNiwgIiA9ID0gIik7CisgICAgICAgIGxlbiA9IGZpcnN0X2VxdWFscyAtIGVuY29kZV9idWZmZXIgKyA1OworICAgICAgfSBlbHNlIHsKKyAgICAgICAgc25wcmludGYoZmlyc3RfZXF1YWxzLCA2LCAiID0gIik7CisgICAgICAgIGxlbiA9IGZpcnN0X2VxdWFscyAtIGVuY29kZV9idWZmZXIgKyAzOworICAgICAgfQorICAgICAgZGVjb2RlZDIuYXNzaWduKCJ0aGlzIGp1bmsgc2hvdWxkIGJlIGlnbm9yZWQiKTsKKyAgICAgIEVYUEVDVF9UUlVFKAorICAgICAgICAgIEJhc2U2NFVuZXNjYXBlKFN0cmluZ1BpZWNlKGVuY29kZV9idWZmZXIsIGxlbiksICZkZWNvZGVkMikpOworICAgICAgRVhQRUNUX0VRKGRlY29kZWQuc2l6ZSgpLCBiYXNlNjRfdGVzdHNbaV0ucGxhaW5fbGVuZ3RoKTsKKyAgICAgIEVYUEVDVF9FUV9BUlJBWShkZWNvZGVkLnNpemUoKSwgZGVjb2RlZCwgYmFzZTY0X3Rlc3RzW2ldLnBsYWludGV4dCwgaSk7CisKKyAgICAgIC8vIFRlc3Qgd2hpdGVzcGFjZSBtaXhlZCB3aXRoIHRoZSBwYWRkaW5nLCBidXQgd2l0aCB0aGUgd3JvbmcKKyAgICAgIC8vIG51bWJlciBvZiBlcXVhbHMgc2lnbnMgKGVnICJBQSA9ICIpLiAgVGhlIGRlY29kZXIgc2hvdWxkCisgICAgICAvLyByZWZ1c2UgdGhlc2Ugc3RyaW5ncy4KKyAgICAgIGlmIChlcXVhbHMgPT0gMSkgeworICAgICAgICBzbnByaW50ZihmaXJzdF9lcXVhbHMsIDYsICIgPSA9ICIpOworICAgICAgICBsZW4gPSBmaXJzdF9lcXVhbHMgLSBlbmNvZGVfYnVmZmVyICsgNTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHNucHJpbnRmKGZpcnN0X2VxdWFscywgNiwgIiA9ICIpOworICAgICAgICBsZW4gPSBmaXJzdF9lcXVhbHMgLSBlbmNvZGVfYnVmZmVyICsgMzsKKyAgICAgIH0KKyAgICAgIEVYUEVDVF9UUlVFKAorICAgICAgICAgICFCYXNlNjRVbmVzY2FwZShTdHJpbmdQaWVjZShlbmNvZGVfYnVmZmVyLCBsZW4pLCAmZGVjb2RlZDIpKTsKKyAgICB9CisKKyAgICAvLyBDb29sISB0aGUgYmFzaWMgQmFzZTY0IGVuY29kZXIvZGVjb2RlciB3b3Jrcy4KKyAgICAvLyBMZXQncyB0cnkgdGhlIGFsdGVybmF0ZSBhbHBoYWJldDogdHIgLS0gJysvJyAnLV8nCisKKyAgICBjaGFyIHdlYnNhZmVbMTAwXTsKKyAgICBtZW1zZXQod2Vic2FmZSwgMCwgc2l6ZW9mKHdlYnNhZmUpKTsKKyAgICBzdHJuY3B5KHdlYnNhZmUsIGJhc2U2NF90ZXN0c1tpXS5jeXBoZXJ0ZXh0LCBjeXBoZXJfbGVuZ3RoKTsKKyAgICBmb3IgKGludCBjID0gMDsgYyA8IHNpemVvZih3ZWJzYWZlKTsgKytjKSB7CisgICAgICBpZiAoJysnID09IHdlYnNhZmVbY10pIHsgd2Vic2FmZVtjXSA9ICctJzsgfQorICAgICAgaWYgKCcvJyA9PSB3ZWJzYWZlW2NdKSB7IHdlYnNhZmVbY10gPSAnXyc7IH0KKyAgICB9CisKKyAgICAvLyBUaGUgd2Vic2FmZSBlc2NhcGUgZnVuY3Rpb246CisgICAgbWVtc2V0KGVuY29kZV9idWZmZXIsIDAsIHNpemVvZihlbmNvZGVfYnVmZmVyKSk7CisgICAgZW5jb2RlX2xlbmd0aCA9IFdlYlNhZmVCYXNlNjRFc2NhcGUodW5zaWduZWRfcGxhaW50ZXh0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhc2U2NF90ZXN0c1tpXS5wbGFpbl9sZW5ndGgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5jb2RlX2J1ZmZlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YoZW5jb2RlX2J1ZmZlciksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSk7CisgICAgLy8gICAgSXMgaXQgb2YgdGhlIGV4cGVjdGVkIGxlbmd0aD8KKyAgICBFWFBFQ1RfRVEoZW5jb2RlX2xlbmd0aCwgY3lwaGVyX2xlbmd0aCk7CisgICAgRVhQRUNUX0VRKAorICAgICAgICBDYWxjdWxhdGVCYXNlNjRFc2NhcGVkTGVuKGJhc2U2NF90ZXN0c1tpXS5wbGFpbl9sZW5ndGgsIHRydWUpLAorICAgICAgICBlbmNvZGVfbGVuZ3RoKTsKKworICAgIC8vICAgIElzIGl0IHRoZSBleHBlY3RlZCBlbmNvZGVkIHZhbHVlPworICAgIEVYUEVDVF9TVFJFUShlbmNvZGVfYnVmZmVyLCB3ZWJzYWZlKTsKKworICAgIC8vICAgIElmIHdlIGVuY29kZSBpdCBpbnRvIGEgYnVmZmVyIG9mIGV4YWN0bHkgdGhlIHJpZ2h0IGxlbmd0aC4uLgorICAgIG1lbXNldChlbmNvZGVfYnVmZmVyLCAwLCBzaXplb2YoZW5jb2RlX2J1ZmZlcikpOworICAgIGVuY29kZV9sZW5ndGggPSBXZWJTYWZlQmFzZTY0RXNjYXBlKHVuc2lnbmVkX3BsYWludGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXNlNjRfdGVzdHNbaV0ucGxhaW5fbGVuZ3RoLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuY29kZV9idWZmZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3lwaGVyX2xlbmd0aCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlKTsKKyAgICAvLyAgICBJcyBpdCBzdGlsbCBvZiB0aGUgZXhwZWN0ZWQgbGVuZ3RoPworICAgIEVYUEVDVF9FUShlbmNvZGVfbGVuZ3RoLCBjeXBoZXJfbGVuZ3RoKTsKKworICAgIC8vICAgIEFuZCBpcyB0aGUgdmFsdWUgc3RpbGwgY29ycmVjdD8gIChpLmUuLCBub3QgbG9zaW5nIHRoZSBsYXN0IGJ5dGUpCisgICAgRVhQRUNUX1NUUkVRKGVuY29kZV9idWZmZXIsIHdlYnNhZmUpOworCisgICAgLy8gICAgTGV0J3MgdHJ5IHRoZSBzdHJpbmcgdmVyc2lvbiBvZiB0aGUgZW5jb2RlcgorICAgIGVuY29kZWQgPSAidGhpcyBqdW5rIHNob3VsZCBiZSBpZ25vcmVkIjsKKyAgICBXZWJTYWZlQmFzZTY0RXNjYXBlKAorICAgICAgICB1bnNpZ25lZF9wbGFpbnRleHQsIGJhc2U2NF90ZXN0c1tpXS5wbGFpbl9sZW5ndGgsCisgICAgICAgICZlbmNvZGVkLCB0cnVlKTsKKyAgICBFWFBFQ1RfRVEoZW5jb2RlZC5zaXplKCksIGN5cGhlcl9sZW5ndGgpOworICAgIEVYUEVDVF9TVFJFUShlbmNvZGVkLmNfc3RyKCksIHdlYnNhZmUpOworCisgICAgLy8gICAgSWYgd2UgZGVjb2RlIGl0IGJhY2s6CisgICAgbWVtc2V0KGRlY29kZV9idWZmZXIsIDAsIHNpemVvZihkZWNvZGVfYnVmZmVyKSk7CisgICAgZGVjb2RlX2xlbmd0aCA9IFdlYlNhZmVCYXNlNjRVbmVzY2FwZShlbmNvZGVfYnVmZmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3lwaGVyX2xlbmd0aCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlY29kZV9idWZmZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YoZGVjb2RlX2J1ZmZlcikpOworCisgICAgLy8gICAgSXMgaXQgb2YgdGhlIGV4cGVjdGVkIGxlbmd0aD8KKyAgICBFWFBFQ1RfRVEoZGVjb2RlX2xlbmd0aCwgYmFzZTY0X3Rlc3RzW2ldLnBsYWluX2xlbmd0aCk7CisKKyAgICAvLyAgICBJcyBpdCB0aGUgZXhwZWN0ZWQgZGVjb2RlZCB2YWx1ZT8KKyAgICBFWFBFQ1RfRVEoMCwKKyAgICAgICAgICAgICAgbWVtY21wKGRlY29kZV9idWZmZXIsIGJhc2U2NF90ZXN0c1tpXS5wbGFpbnRleHQsIGRlY29kZV9sZW5ndGgpKTsKKworICAgIC8vICAgIElmIHdlIGRlY29kZSBpdCBpbnRvIGEgYnVmZmVyIG9mIGV4YWN0bHkgdGhlIHJpZ2h0IGxlbmd0aC4uLgorICAgIG1lbXNldChkZWNvZGVfYnVmZmVyLCAwLCBzaXplb2YoZGVjb2RlX2J1ZmZlcikpOworICAgIGRlY29kZV9sZW5ndGggPSBXZWJTYWZlQmFzZTY0VW5lc2NhcGUoZW5jb2RlX2J1ZmZlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN5cGhlcl9sZW5ndGgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWNvZGVfYnVmZmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVjb2RlX2xlbmd0aCk7CisKKyAgICAvLyAgICBJcyBpdCBzdGlsbCBvZiB0aGUgZXhwZWN0ZWQgbGVuZ3RoPworICAgIEVYUEVDVF9FUShkZWNvZGVfbGVuZ3RoLCBiYXNlNjRfdGVzdHNbaV0ucGxhaW5fbGVuZ3RoKTsKKworICAgIC8vICAgIEFuZCBpcyBpdCB0aGUgZXhwZWN0ZWQgZGVjb2RlZCB2YWx1ZT8KKyAgICBFWFBFQ1RfRVEoMCwKKyAgICAgICAgICAgICAgbWVtY21wKGRlY29kZV9idWZmZXIsIGJhc2U2NF90ZXN0c1tpXS5wbGFpbnRleHQsIGRlY29kZV9sZW5ndGgpKTsKKworICAgIC8vIFRyeSB1c2luZyAnLicgZm9yIHRoZSBwYWQgY2hhcmFjdGVyLgorICAgIGZvciAoaW50IGMgPSBjeXBoZXJfbGVuZ3RoIC0gMTsgYyA+PSAwICYmICc9JyA9PSBlbmNvZGVfYnVmZmVyW2NdOyAtLWMpIHsKKyAgICAgIGVuY29kZV9idWZmZXJbY10gPSAnLic7CisgICAgfQorCisgICAgLy8gSWYgd2UgZGVjb2RlIGl0IGJhY2s6CisgICAgbWVtc2V0KGRlY29kZV9idWZmZXIsIDAsIHNpemVvZihkZWNvZGVfYnVmZmVyKSk7CisgICAgZGVjb2RlX2xlbmd0aCA9IFdlYlNhZmVCYXNlNjRVbmVzY2FwZShlbmNvZGVfYnVmZmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3lwaGVyX2xlbmd0aCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlY29kZV9idWZmZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YoZGVjb2RlX2J1ZmZlcikpOworCisgICAgLy8gSXMgaXQgb2YgdGhlIGV4cGVjdGVkIGxlbmd0aD8KKyAgICBFWFBFQ1RfRVEoZGVjb2RlX2xlbmd0aCwgYmFzZTY0X3Rlc3RzW2ldLnBsYWluX2xlbmd0aCk7CisKKyAgICAvLyBJcyBpdCB0aGUgZXhwZWN0ZWQgZGVjb2RlZCB2YWx1ZT8KKyAgICBFWFBFQ1RfRVEoMCwKKyAgICAgICAgICAgICAgbWVtY21wKGRlY29kZV9idWZmZXIsIGJhc2U2NF90ZXN0c1tpXS5wbGFpbnRleHQsIGRlY29kZV9sZW5ndGgpKTsKKworICAgIC8vIElmIHdlIGRlY29kZSBpdCBpbnRvIGEgYnVmZmVyIG9mIGV4YWN0bHkgdGhlIHJpZ2h0IGxlbmd0aC4uLgorICAgIG1lbXNldChkZWNvZGVfYnVmZmVyLCAwLCBzaXplb2YoZGVjb2RlX2J1ZmZlcikpOworICAgIGRlY29kZV9sZW5ndGggPSBXZWJTYWZlQmFzZTY0VW5lc2NhcGUoZW5jb2RlX2J1ZmZlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN5cGhlcl9sZW5ndGgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWNvZGVfYnVmZmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVjb2RlX2xlbmd0aCk7CisKKyAgICAvLyBJcyBpdCBzdGlsbCBvZiB0aGUgZXhwZWN0ZWQgbGVuZ3RoPworICAgIEVYUEVDVF9FUShkZWNvZGVfbGVuZ3RoLCBiYXNlNjRfdGVzdHNbaV0ucGxhaW5fbGVuZ3RoKTsKKworICAgIC8vIEFuZCBpcyBpdCB0aGUgZXhwZWN0ZWQgZGVjb2RlZCB2YWx1ZT8KKyAgICBFWFBFQ1RfRVEoMCwKKyAgICAgICAgICAgICAgbWVtY21wKGRlY29kZV9idWZmZXIsIGJhc2U2NF90ZXN0c1tpXS5wbGFpbnRleHQsIGRlY29kZV9sZW5ndGgpKTsKKworICAgIC8vIExldCdzIHRyeSB0aGUgc3RyaW5nIHZlcnNpb24gb2YgdGhlIGRlY29kZXIKKyAgICBkZWNvZGVkID0gInRoaXMganVuayBzaG91bGQgYmUgaWdub3JlZCI7CisgICAgRVhQRUNUX1RSVUUoV2ViU2FmZUJhc2U2NFVuZXNjYXBlKAorICAgICAgICBTdHJpbmdQaWVjZShlbmNvZGVfYnVmZmVyLCBjeXBoZXJfbGVuZ3RoKSwgJmRlY29kZWQpKTsKKyAgICBFWFBFQ1RfRVEoZGVjb2RlZC5zaXplKCksIGJhc2U2NF90ZXN0c1tpXS5wbGFpbl9sZW5ndGgpOworICAgIEVYUEVDVF9FUV9BUlJBWShkZWNvZGVkLnNpemUoKSwgZGVjb2RlZCwgYmFzZTY0X3Rlc3RzW2ldLnBsYWludGV4dCwgaSk7CisKKyAgICAvLyBPa2F5ISB0aGUgd2Vic2FmZSBCYXNlNjQgZW5jb2Rlci9kZWNvZGVyIHdvcmtzLgorICAgIC8vIExldCdzIHRyeSB0aGUgdW5wYWRkZWQgdmVyc2lvbgorCisgICAgZm9yIChpbnQgYyA9IDA7IGMgPCBzaXplb2Yod2Vic2FmZSk7ICsrYykgeworICAgICAgaWYgKCc9JyA9PSB3ZWJzYWZlW2NdKSB7CisgICAgICAgIHdlYnNhZmVbY10gPSAnXDAnOworICAgICAgICBjeXBoZXJfbGVuZ3RoID0gYzsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorCisgICAgLy8gVGhlIHdlYnNhZmUgZXNjYXBlIGZ1bmN0aW9uOgorICAgIG1lbXNldChlbmNvZGVfYnVmZmVyLCAwLCBzaXplb2YoZW5jb2RlX2J1ZmZlcikpOworICAgIGVuY29kZV9sZW5ndGggPSBXZWJTYWZlQmFzZTY0RXNjYXBlKHVuc2lnbmVkX3BsYWludGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXNlNjRfdGVzdHNbaV0ucGxhaW5fbGVuZ3RoLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuY29kZV9idWZmZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKGVuY29kZV9idWZmZXIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlKTsKKyAgICAvLyAgICBJcyBpdCBvZiB0aGUgZXhwZWN0ZWQgbGVuZ3RoPworICAgIEVYUEVDVF9FUShlbmNvZGVfbGVuZ3RoLCBjeXBoZXJfbGVuZ3RoKTsKKyAgICBFWFBFQ1RfRVEoCisgICAgICAgIENhbGN1bGF0ZUJhc2U2NEVzY2FwZWRMZW4oYmFzZTY0X3Rlc3RzW2ldLnBsYWluX2xlbmd0aCwgZmFsc2UpLAorICAgICAgICBlbmNvZGVfbGVuZ3RoKTsKKworICAgIC8vICAgIElzIGl0IHRoZSBleHBlY3RlZCBlbmNvZGVkIHZhbHVlPworICAgIEVYUEVDVF9TVFJFUShlbmNvZGVfYnVmZmVyLCB3ZWJzYWZlKTsKKworICAgIC8vICAgIElmIHdlIGVuY29kZSBpdCBpbnRvIGEgYnVmZmVyIG9mIGV4YWN0bHkgdGhlIHJpZ2h0IGxlbmd0aC4uLgorICAgIG1lbXNldChlbmNvZGVfYnVmZmVyLCAwLCBzaXplb2YoZW5jb2RlX2J1ZmZlcikpOworICAgIGVuY29kZV9sZW5ndGggPSBXZWJTYWZlQmFzZTY0RXNjYXBlKHVuc2lnbmVkX3BsYWludGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXNlNjRfdGVzdHNbaV0ucGxhaW5fbGVuZ3RoLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuY29kZV9idWZmZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3lwaGVyX2xlbmd0aCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSk7CisgICAgLy8gICAgSXMgaXQgc3RpbGwgb2YgdGhlIGV4cGVjdGVkIGxlbmd0aD8KKyAgICBFWFBFQ1RfRVEoZW5jb2RlX2xlbmd0aCwgY3lwaGVyX2xlbmd0aCk7CisKKyAgICAvLyAgICBBbmQgaXMgdGhlIHZhbHVlIHN0aWxsIGNvcnJlY3Q/ICAoaS5lLiwgbm90IGxvc2luZyB0aGUgbGFzdCBieXRlKQorICAgIEVYUEVDVF9TVFJFUShlbmNvZGVfYnVmZmVyLCB3ZWJzYWZlKTsKKworICAgIC8vIExldCdzIHRyeSB0aGUgKG90aGVyKSBzdHJpbmcgdmVyc2lvbiBvZiB0aGUgZW5jb2RlcgorICAgIHN0cmluZyBwbGFpbihiYXNlNjRfdGVzdHNbaV0ucGxhaW50ZXh0LCBiYXNlNjRfdGVzdHNbaV0ucGxhaW5fbGVuZ3RoKTsKKyAgICBlbmNvZGVkID0gInRoaXMganVuayBzaG91bGQgYmUgaWdub3JlZCI7CisgICAgV2ViU2FmZUJhc2U2NEVzY2FwZShwbGFpbiwgJmVuY29kZWQpOworICAgIEVYUEVDVF9FUShlbmNvZGVkLnNpemUoKSwgY3lwaGVyX2xlbmd0aCk7CisgICAgRVhQRUNUX1NUUkVRKGVuY29kZWQuY19zdHIoKSwgd2Vic2FmZSk7CisKKyAgICAvLyAgICBJZiB3ZSBkZWNvZGUgaXQgYmFjazoKKyAgICBtZW1zZXQoZGVjb2RlX2J1ZmZlciwgMCwgc2l6ZW9mKGRlY29kZV9idWZmZXIpKTsKKyAgICBkZWNvZGVfbGVuZ3RoID0gV2ViU2FmZUJhc2U2NFVuZXNjYXBlKGVuY29kZV9idWZmZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjeXBoZXJfbGVuZ3RoLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVjb2RlX2J1ZmZlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihkZWNvZGVfYnVmZmVyKSk7CisKKyAgICAvLyAgICBJcyBpdCBvZiB0aGUgZXhwZWN0ZWQgbGVuZ3RoPworICAgIEVYUEVDVF9FUShkZWNvZGVfbGVuZ3RoLCBiYXNlNjRfdGVzdHNbaV0ucGxhaW5fbGVuZ3RoKTsKKworICAgIC8vICAgIElzIGl0IHRoZSBleHBlY3RlZCBkZWNvZGVkIHZhbHVlPworICAgIEVYUEVDVF9FUSgwLAorICAgICAgICAgICAgICBtZW1jbXAoZGVjb2RlX2J1ZmZlciwgYmFzZTY0X3Rlc3RzW2ldLnBsYWludGV4dCwgZGVjb2RlX2xlbmd0aCkpOworCisgICAgLy8gICAgSWYgd2UgZGVjb2RlIGl0IGludG8gYSBidWZmZXIgb2YgZXhhY3RseSB0aGUgcmlnaHQgbGVuZ3RoLi4uCisgICAgbWVtc2V0KGRlY29kZV9idWZmZXIsIDAsIHNpemVvZihkZWNvZGVfYnVmZmVyKSk7CisgICAgZGVjb2RlX2xlbmd0aCA9IFdlYlNhZmVCYXNlNjRVbmVzY2FwZShlbmNvZGVfYnVmZmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3lwaGVyX2xlbmd0aCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlY29kZV9idWZmZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWNvZGVfbGVuZ3RoKTsKKworICAgIC8vICAgIElzIGl0IHN0aWxsIG9mIHRoZSBleHBlY3RlZCBsZW5ndGg/CisgICAgRVhQRUNUX0VRKGRlY29kZV9sZW5ndGgsIGJhc2U2NF90ZXN0c1tpXS5wbGFpbl9sZW5ndGgpOworCisgICAgLy8gICAgQW5kIGlzIGl0IHRoZSBleHBlY3RlZCBkZWNvZGVkIHZhbHVlPworICAgIEVYUEVDVF9FUSgwLAorICAgICAgICAgICAgICBtZW1jbXAoZGVjb2RlX2J1ZmZlciwgYmFzZTY0X3Rlc3RzW2ldLnBsYWludGV4dCwgZGVjb2RlX2xlbmd0aCkpOworCisKKyAgICAvLyBMZXQncyB0cnkgdGhlIHN0cmluZyB2ZXJzaW9uIG9mIHRoZSBkZWNvZGVyCisgICAgZGVjb2RlZCA9ICJ0aGlzIGp1bmsgc2hvdWxkIGJlIGlnbm9yZWQiOworICAgIEVYUEVDVF9UUlVFKFdlYlNhZmVCYXNlNjRVbmVzY2FwZSgKKyAgICAgICAgU3RyaW5nUGllY2UoZW5jb2RlX2J1ZmZlciwgY3lwaGVyX2xlbmd0aCksICZkZWNvZGVkKSk7CisgICAgRVhQRUNUX0VRKGRlY29kZWQuc2l6ZSgpLCBiYXNlNjRfdGVzdHNbaV0ucGxhaW5fbGVuZ3RoKTsKKyAgICBFWFBFQ1RfRVFfQVJSQVkoZGVjb2RlZC5zaXplKCksIGRlY29kZWQsIGJhc2U2NF90ZXN0c1tpXS5wbGFpbnRleHQsIGkpOworCisgICAgLy8gVGhpcyB2YWx1ZSB3b3Jrcy4gIFRyeSB0aGUgbmV4dC4KKyAgfQorCisgIC8vIE5vdyB0cnkgdGhlIGxvbmcgc3RyaW5ncywgdGhpcyB0ZXN0cyB0aGUgc3RyZWFtaW5nCisgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZW9mKGJhc2U2NF9zdHJpbmdzKSAvIHNpemVvZihiYXNlNjRfc3RyaW5nc1swXSk7CisgICAgICAgKytpKSB7CisgICAgY29uc3QgdW5zaWduZWQgY2hhciogdW5zaWduZWRfcGxhaW50ZXh0ID0KKyAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgdW5zaWduZWQgY2hhcio+KGJhc2U2NF9zdHJpbmdzW2ldLnBsYWludGV4dCk7CisgICAgaW50IHBsYWluX2xlbmd0aCA9IHN0cmxlbihiYXNlNjRfc3RyaW5nc1tpXS5wbGFpbnRleHQpOworICAgIGludCBjeXBoZXJfbGVuZ3RoID0gc3RybGVuKGJhc2U2NF9zdHJpbmdzW2ldLmN5cGhlcnRleHQpOworICAgIHZlY3RvcjxjaGFyPiBidWZmZXIoY3lwaGVyX2xlbmd0aCsxKTsKKyAgICBpbnQgZW5jb2RlX2xlbmd0aCA9IFdlYlNhZmVCYXNlNjRFc2NhcGUodW5zaWduZWRfcGxhaW50ZXh0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbGFpbl9sZW5ndGgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZidWZmZXJbMF0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5zaXplKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlKTsKKyAgICBFWFBFQ1RfRVEoY3lwaGVyX2xlbmd0aCwgZW5jb2RlX2xlbmd0aCk7CisgICAgRVhQRUNUX0VRKAorICAgICAgICBDYWxjdWxhdGVCYXNlNjRFc2NhcGVkTGVuKHBsYWluX2xlbmd0aCwgZmFsc2UpLCBlbmNvZGVfbGVuZ3RoKTsKKyAgICBidWZmZXJbIGVuY29kZV9sZW5ndGggXSA9ICdcMCc7CisgICAgRVhQRUNUX1NUUkVRKGJhc2U2NF9zdHJpbmdzW2ldLmN5cGhlcnRleHQsICZidWZmZXJbMF0pOworICB9CisKKyAgLy8gVmVyaWZ5IHRoZSBiZWhhdmlvciB3aGVuIGRlY29kaW5nIGJhZCBkYXRhCisgIHsKKyAgICBjb25zdCBjaGFyKiBiYWRfZGF0YSA9ICJhYi0vIjsKKyAgICBzdHJpbmcgYnVmOworICAgIEVYUEVDVF9GQUxTRShCYXNlNjRVbmVzY2FwZShTdHJpbmdQaWVjZShiYWRfZGF0YSksICZidWYpKTsKKyAgICBFWFBFQ1RfVFJVRSghV2ViU2FmZUJhc2U2NFVuZXNjYXBlKGJhZF9kYXRhLCAmYnVmKSk7CisgICAgRVhQRUNUX1RSVUUoYnVmLmVtcHR5KCkpOworICB9Cit9CisKK30gIC8vIGFub255bW91cyBuYW1lc3BhY2UKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdWJzdGl0dXRlLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdWJzdGl0dXRlLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM5ZDk1ODkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N1YnN0aXR1dGUuY2MKQEAgLTAsMCArMSwxMzQgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3Vic3RpdHV0ZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0bF91dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBzdHJpbmdzIHsKKwordXNpbmcgaW50ZXJuYWw6OlN1YnN0aXR1dGVBcmc7CisKKy8vIFJldHVybnMgdGhlIG51bWJlciBvZiBhcmdzIGluIGFyZ19hcnJheSB3aGljaCB3ZXJlIHBhc3NlZCBleHBsaWNpdGx5CisvLyB0byBTdWJzdGl0dXRlKCkuCitzdGF0aWMgaW50IENvdW50U3Vic3RpdHV0ZUFyZ3MoY29uc3QgU3Vic3RpdHV0ZUFyZyogY29uc3QqIGFyZ3NfYXJyYXkpIHsKKyAgaW50IGNvdW50ID0gMDsKKyAgd2hpbGUgKGFyZ3NfYXJyYXlbY291bnRdICE9IE5VTEwgJiYgYXJnc19hcnJheVtjb3VudF0tPnNpemUoKSAhPSAtMSkgeworICAgICsrY291bnQ7CisgIH0KKyAgcmV0dXJuIGNvdW50OworfQorCitzdHJpbmcgU3Vic3RpdHV0ZSgKKyAgICBjb25zdCBjaGFyKiBmb3JtYXQsCisgICAgY29uc3QgU3Vic3RpdHV0ZUFyZyYgYXJnMCwgY29uc3QgU3Vic3RpdHV0ZUFyZyYgYXJnMSwKKyAgICBjb25zdCBTdWJzdGl0dXRlQXJnJiBhcmcyLCBjb25zdCBTdWJzdGl0dXRlQXJnJiBhcmczLAorICAgIGNvbnN0IFN1YnN0aXR1dGVBcmcmIGFyZzQsIGNvbnN0IFN1YnN0aXR1dGVBcmcmIGFyZzUsCisgICAgY29uc3QgU3Vic3RpdHV0ZUFyZyYgYXJnNiwgY29uc3QgU3Vic3RpdHV0ZUFyZyYgYXJnNywKKyAgICBjb25zdCBTdWJzdGl0dXRlQXJnJiBhcmc4LCBjb25zdCBTdWJzdGl0dXRlQXJnJiBhcmc5KSB7CisgIHN0cmluZyByZXN1bHQ7CisgIFN1YnN0aXR1dGVBbmRBcHBlbmQoJnJlc3VsdCwgZm9ybWF0LCBhcmcwLCBhcmcxLCBhcmcyLCBhcmczLCBhcmc0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJnNSwgYXJnNiwgYXJnNywgYXJnOCwgYXJnOSk7CisgIHJldHVybiByZXN1bHQ7Cit9CisKK3ZvaWQgU3Vic3RpdHV0ZUFuZEFwcGVuZCgKKyAgICBzdHJpbmcqIG91dHB1dCwgY29uc3QgY2hhciogZm9ybWF0LAorICAgIGNvbnN0IFN1YnN0aXR1dGVBcmcmIGFyZzAsIGNvbnN0IFN1YnN0aXR1dGVBcmcmIGFyZzEsCisgICAgY29uc3QgU3Vic3RpdHV0ZUFyZyYgYXJnMiwgY29uc3QgU3Vic3RpdHV0ZUFyZyYgYXJnMywKKyAgICBjb25zdCBTdWJzdGl0dXRlQXJnJiBhcmc0LCBjb25zdCBTdWJzdGl0dXRlQXJnJiBhcmc1LAorICAgIGNvbnN0IFN1YnN0aXR1dGVBcmcmIGFyZzYsIGNvbnN0IFN1YnN0aXR1dGVBcmcmIGFyZzcsCisgICAgY29uc3QgU3Vic3RpdHV0ZUFyZyYgYXJnOCwgY29uc3QgU3Vic3RpdHV0ZUFyZyYgYXJnOSkgeworICBjb25zdCBTdWJzdGl0dXRlQXJnKiBjb25zdCBhcmdzX2FycmF5W10gPSB7CisgICAgJmFyZzAsICZhcmcxLCAmYXJnMiwgJmFyZzMsICZhcmc0LCAmYXJnNSwgJmFyZzYsICZhcmc3LCAmYXJnOCwgJmFyZzksIE5VTEwKKyAgfTsKKworICAvLyBEZXRlcm1pbmUgdG90YWwgc2l6ZSBuZWVkZWQuCisgIGludCBzaXplID0gMDsKKyAgZm9yIChpbnQgaSA9IDA7IGZvcm1hdFtpXSAhPSAnXDAnOyBpKyspIHsKKyAgICBpZiAoZm9ybWF0W2ldID09ICckJykgeworICAgICAgaWYgKGFzY2lpX2lzZGlnaXQoZm9ybWF0W2krMV0pKSB7CisgICAgICAgIGludCBpbmRleCA9IGZvcm1hdFtpKzFdIC0gJzAnOworICAgICAgICBpZiAoYXJnc19hcnJheVtpbmRleF0tPnNpemUoKSA9PSAtMSkgeworICAgICAgICAgIEdPT0dMRV9MT0coREZBVEFMKQorICAgICAgICAgICAgPDwgInN0cmluZ3M6OlN1YnN0aXR1dGUgZm9ybWF0IHN0cmluZyBpbnZhbGlkOiBhc2tlZCBmb3IgXCIkIgorICAgICAgICAgICAgPDwgaW5kZXggPDwgIlwiLCBidXQgb25seSAiIDw8IENvdW50U3Vic3RpdHV0ZUFyZ3MoYXJnc19hcnJheSkKKyAgICAgICAgICAgIDw8ICIgYXJncyB3ZXJlIGdpdmVuLiAgRnVsbCBmb3JtYXQgc3RyaW5nIHdhczogXCIiCisgICAgICAgICAgICA8PCBDRXNjYXBlKGZvcm1hdCkgPDwgIlwiLiI7CisgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIHNpemUgKz0gYXJnc19hcnJheVtpbmRleF0tPnNpemUoKTsKKyAgICAgICAgKytpOyAgLy8gU2tpcCBuZXh0IGNoYXIuCisgICAgICB9IGVsc2UgaWYgKGZvcm1hdFtpKzFdID09ICckJykgeworICAgICAgICArK3NpemU7CisgICAgICAgICsraTsgIC8vIFNraXAgbmV4dCBjaGFyLgorICAgICAgfSBlbHNlIHsKKyAgICAgICAgR09PR0xFX0xPRyhERkFUQUwpCisgICAgICAgICAgPDwgIkludmFsaWQgc3RyaW5nczo6U3Vic3RpdHV0ZSgpIGZvcm1hdCBzdHJpbmc6IFwiIgorICAgICAgICAgIDw8IENFc2NhcGUoZm9ybWF0KSA8PCAiXCIuIjsKKyAgICAgICAgcmV0dXJuOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICArK3NpemU7CisgICAgfQorICB9CisKKyAgaWYgKHNpemUgPT0gMCkgcmV0dXJuOworCisgIC8vIEJ1aWxkIHRoZSBzdHJpbmcuCisgIGludCBvcmlnaW5hbF9zaXplID0gb3V0cHV0LT5zaXplKCk7CisgIFNUTFN0cmluZ1Jlc2l6ZVVuaW5pdGlhbGl6ZWQob3V0cHV0LCBvcmlnaW5hbF9zaXplICsgc2l6ZSk7CisgIGNoYXIqIHRhcmdldCA9IHN0cmluZ19hc19hcnJheShvdXRwdXQpICsgb3JpZ2luYWxfc2l6ZTsKKyAgZm9yIChpbnQgaSA9IDA7IGZvcm1hdFtpXSAhPSAnXDAnOyBpKyspIHsKKyAgICBpZiAoZm9ybWF0W2ldID09ICckJykgeworICAgICAgaWYgKGFzY2lpX2lzZGlnaXQoZm9ybWF0W2krMV0pKSB7CisgICAgICAgIGNvbnN0IFN1YnN0aXR1dGVBcmcqIHNyYyA9IGFyZ3NfYXJyYXlbZm9ybWF0W2krMV0gLSAnMCddOworICAgICAgICBtZW1jcHkodGFyZ2V0LCBzcmMtPmRhdGEoKSwgc3JjLT5zaXplKCkpOworICAgICAgICB0YXJnZXQgKz0gc3JjLT5zaXplKCk7CisgICAgICAgICsraTsgIC8vIFNraXAgbmV4dCBjaGFyLgorICAgICAgfSBlbHNlIGlmIChmb3JtYXRbaSsxXSA9PSAnJCcpIHsKKyAgICAgICAgKnRhcmdldCsrID0gJyQnOworICAgICAgICArK2k7ICAvLyBTa2lwIG5leHQgY2hhci4KKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgKnRhcmdldCsrID0gZm9ybWF0W2ldOworICAgIH0KKyAgfQorCisgIEdPT0dMRV9EQ0hFQ0tfRVEodGFyZ2V0IC0gb3V0cHV0LT5kYXRhKCksIG91dHB1dC0+c2l6ZSgpKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIHN0cmluZ3MKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdWJzdGl0dXRlLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N1YnN0aXR1dGUuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ZWU0NDJhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9zdWJzdGl0dXRlLmgKQEAgLTAsMCArMSwxNzAgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyBmcm9tIGdvb2dsZTMvc3RyaW5ncy9zdWJzdGl0dXRlLmgKKworI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfU1RVQlNfU1VCU1RJVFVURV9IXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfU1RVQlNfU1VCU1RJVFVURV9IXworCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2Ugc3RyaW5ncyB7CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIHN0cmluZ3M6OlN1YnN0aXR1dGUoKQorLy8gc3RyaW5nczo6U3Vic3RpdHV0ZUFuZEFwcGVuZCgpCisvLyAgIEtpbmQgb2YgbGlrZSBTdHJpbmdQcmludGYsIGJ1dCBkaWZmZXJlbnQuCisvLworLy8gICBFeGFtcGxlOgorLy8gICAgIHN0cmluZyBHZXRNZXNzYWdlKHN0cmluZyBmaXJzdF9uYW1lLCBzdHJpbmcgbGFzdF9uYW1lLCBpbnQgYWdlKSB7CisvLyAgICAgICByZXR1cm4gc3RyaW5nczo6U3Vic3RpdHV0ZSgiTXkgbmFtZSBpcyAkMCAkMSBhbmQgSSBhbSAkMiB5ZWFycyBvbGQuIiwKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpcnN0X25hbWUsIGxhc3RfbmFtZSwgYWdlKTsKKy8vICAgICB9CisvLworLy8gICBEaWZmZXJlbmNlcyBmcm9tIFN0cmluZ1ByaW50ZjoKKy8vICAgKiBUaGUgZm9ybWF0IHN0cmluZyBkb2VzIG5vdCBpZGVudGlmeSB0aGUgdHlwZXMgb2YgYXJndW1lbnRzLgorLy8gICAgIEluc3RlYWQsIHRoZSBtYWdpYyBvZiBDKysgZGVhbHMgd2l0aCB0aGlzIGZvciB1cy4gIFNlZSBiZWxvdworLy8gICAgIGZvciBhIGxpc3Qgb2YgYWNjZXB0ZWQgdHlwZXMuCisvLyAgICogU3Vic3RpdHV0aW9ucyBpbiB0aGUgZm9ybWF0IHN0cmluZyBhcmUgaWRlbnRpZmllZCBieSBhICckJworLy8gICAgIGZvbGxvd2VkIGJ5IGEgZGlnaXQuICBTbywgeW91IGNhbiB1c2UgYXJndW1lbnRzIG91dC1vZi1vcmRlciBhbmQKKy8vICAgICB1c2UgdGhlIHNhbWUgYXJndW1lbnQgbXVsdGlwbGUgdGltZXMuCisvLyAgICogSXQncyBtdWNoIGZhc3RlciB0aGFuIFN0cmluZ1ByaW50Zi4KKy8vCisvLyAgIFN1cHBvcnRlZCB0eXBlczoKKy8vICAgKiBTdHJpbmdzIChjb25zdCBjaGFyKiwgY29uc3Qgc3RyaW5nJikKKy8vICAgICAqIE5vdGUgdGhhdCB0aGlzIG1lYW5zIHlvdSBkbyBub3QgaGF2ZSB0byBhZGQgLmNfc3RyKCkgdG8gYWxsIG9mCisvLyAgICAgICB5b3VyIHN0cmluZ3MuICBJbiBmYWN0LCB5b3Ugc2hvdWxkbid0OyBpdCB3aWxsIGJlIHNsb3dlci4KKy8vICAgKiBpbnQzMiwgaW50NjQsIHVpbnQzMiwgdWludDY0OiAgRm9ybWF0dGVkIHVzaW5nIFNpbXBsZUl0b2EoKS4KKy8vICAgKiBmbG9hdCwgZG91YmxlOiAgRm9ybWF0dGVkIHVzaW5nIFNpbXBsZUZ0b2EoKSBhbmQgU2ltcGxlRHRvYSgpLgorLy8gICAqIGJvb2w6ICBQcmludGVkIGFzICJ0cnVlIiBvciAiZmFsc2UiLgorLy8KKy8vICAgU3Vic3RpdHV0ZUFuZEFwcGVuZCgpIGlzIGxpa2UgU3Vic3RpdHV0ZSgpIGJ1dCBhcHBlbmRzIHRoZSByZXN1bHQgdG8KKy8vICAgKm91dHB1dC4gIEV4YW1wbGU6CisvLworLy8gICAgIHN0cmluZyBzdHI7CisvLyAgICAgc3RyaW5nczo6U3Vic3RpdHV0ZUFuZEFwcGVuZCgmc3RyLAorLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk15IG5hbWUgaXMgJDAgJDEgYW5kIEkgYW0gJDIgeWVhcnMgb2xkLiIsCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaXJzdF9uYW1lLCBsYXN0X25hbWUsIGFnZSk7CisvLworLy8gICBTdWJzdGl0dXRlKCkgaXMgc2lnbmlmaWNhbnRseSBmYXN0ZXIgdGhhbiBTdHJpbmdQcmludGYoKS4gIEZvciB2ZXJ5CisvLyAgIGxhcmdlIHN0cmluZ3MsIGl0IG1heSBiZSBvcmRlcnMgb2YgbWFnbml0dWRlIGZhc3Rlci4KKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworbmFtZXNwYWNlIGludGVybmFsIHsgIC8vIEltcGxlbWVudGF0aW9uIGRldGFpbHMuCisKK2NsYXNzIFN1YnN0aXR1dGVBcmcgeworIHB1YmxpYzoKKyAgaW5saW5lIFN1YnN0aXR1dGVBcmcoY29uc3QgY2hhciogdmFsdWUpCisgICAgOiB0ZXh0Xyh2YWx1ZSksIHNpemVfKHN0cmxlbih0ZXh0XykpIHt9CisgIGlubGluZSBTdWJzdGl0dXRlQXJnKGNvbnN0IHN0cmluZyYgdmFsdWUpCisgICAgOiB0ZXh0Xyh2YWx1ZS5kYXRhKCkpLCBzaXplXyh2YWx1ZS5zaXplKCkpIHt9CisKKyAgLy8gSW5kaWNhdGVzIHRoYXQgbm8gYXJndW1lbnQgd2FzIGdpdmVuLgorICBpbmxpbmUgZXhwbGljaXQgU3Vic3RpdHV0ZUFyZygpCisgICAgOiB0ZXh0XyhOVUxMKSwgc2l6ZV8oLTEpIHt9CisKKyAgLy8gUHJpbWl0aXZlcworICAvLyBXZSBkb24ndCBvdmVybG9hZCBmb3Igc2lnbmVkIGFuZCB1bnNpZ25lZCBjaGFyIGJlY2F1c2UgaWYgcGVvcGxlIGFyZQorICAvLyBleHBsaWNpdGx5IGRlY2xhcmluZyB0aGVpciBjaGFycyBhcyBzaWduZWQgb3IgdW5zaWduZWQgdGhlbiB0aGV5IGFyZQorICAvLyBwcm9iYWJseSBhY3R1YWxseSB1c2luZyB0aGVtIGFzIDgtYml0IGludGVnZXJzIGFuZCB3b3VsZCBwcm9iYWJseQorICAvLyBwcmVmZXIgYW4gaW50ZWdlciByZXByZXNlbnRhdGlvbi4gIEJ1dCwgd2UgZG9uJ3QgcmVhbGx5IGtub3cuICBTbywgd2UKKyAgLy8gbWFrZSB0aGUgY2FsbGVyIGRlY2lkZSB3aGF0IHRvIGRvLgorICBpbmxpbmUgU3Vic3RpdHV0ZUFyZyhjaGFyIHZhbHVlKQorICAgIDogdGV4dF8oc2NyYXRjaF8pLCBzaXplXygxKSB7IHNjcmF0Y2hfWzBdID0gdmFsdWU7IH0KKyAgaW5saW5lIFN1YnN0aXR1dGVBcmcoc2hvcnQgdmFsdWUpCisgICAgOiB0ZXh0XyhGYXN0SW50MzJUb0J1ZmZlcih2YWx1ZSwgc2NyYXRjaF8pKSwgc2l6ZV8oc3RybGVuKHRleHRfKSkge30KKyAgaW5saW5lIFN1YnN0aXR1dGVBcmcodW5zaWduZWQgc2hvcnQgdmFsdWUpCisgICAgOiB0ZXh0XyhGYXN0VUludDMyVG9CdWZmZXIodmFsdWUsIHNjcmF0Y2hfKSksIHNpemVfKHN0cmxlbih0ZXh0XykpIHt9CisgIGlubGluZSBTdWJzdGl0dXRlQXJnKGludCB2YWx1ZSkKKyAgICA6IHRleHRfKEZhc3RJbnQzMlRvQnVmZmVyKHZhbHVlLCBzY3JhdGNoXykpLCBzaXplXyhzdHJsZW4odGV4dF8pKSB7fQorICBpbmxpbmUgU3Vic3RpdHV0ZUFyZyh1bnNpZ25lZCBpbnQgdmFsdWUpCisgICAgOiB0ZXh0XyhGYXN0VUludDMyVG9CdWZmZXIodmFsdWUsIHNjcmF0Y2hfKSksIHNpemVfKHN0cmxlbih0ZXh0XykpIHt9CisgIGlubGluZSBTdWJzdGl0dXRlQXJnKGxvbmcgdmFsdWUpCisgICAgOiB0ZXh0XyhGYXN0TG9uZ1RvQnVmZmVyKHZhbHVlLCBzY3JhdGNoXykpLCBzaXplXyhzdHJsZW4odGV4dF8pKSB7fQorICBpbmxpbmUgU3Vic3RpdHV0ZUFyZyh1bnNpZ25lZCBsb25nIHZhbHVlKQorICAgIDogdGV4dF8oRmFzdFVMb25nVG9CdWZmZXIodmFsdWUsIHNjcmF0Y2hfKSksIHNpemVfKHN0cmxlbih0ZXh0XykpIHt9CisgIGlubGluZSBTdWJzdGl0dXRlQXJnKGxvbmcgbG9uZyB2YWx1ZSkKKyAgICA6IHRleHRfKEZhc3RJbnQ2NFRvQnVmZmVyKHZhbHVlLCBzY3JhdGNoXykpLCBzaXplXyhzdHJsZW4odGV4dF8pKSB7fQorICBpbmxpbmUgU3Vic3RpdHV0ZUFyZyh1bnNpZ25lZCBsb25nIGxvbmcgdmFsdWUpCisgICAgOiB0ZXh0XyhGYXN0VUludDY0VG9CdWZmZXIodmFsdWUsIHNjcmF0Y2hfKSksIHNpemVfKHN0cmxlbih0ZXh0XykpIHt9CisgIGlubGluZSBTdWJzdGl0dXRlQXJnKGZsb2F0IHZhbHVlKQorICAgIDogdGV4dF8oRmxvYXRUb0J1ZmZlcih2YWx1ZSwgc2NyYXRjaF8pKSwgc2l6ZV8oc3RybGVuKHRleHRfKSkge30KKyAgaW5saW5lIFN1YnN0aXR1dGVBcmcoZG91YmxlIHZhbHVlKQorICAgIDogdGV4dF8oRG91YmxlVG9CdWZmZXIodmFsdWUsIHNjcmF0Y2hfKSksIHNpemVfKHN0cmxlbih0ZXh0XykpIHt9CisgIGlubGluZSBTdWJzdGl0dXRlQXJnKGJvb2wgdmFsdWUpCisgICAgOiB0ZXh0Xyh2YWx1ZSA/ICJ0cnVlIiA6ICJmYWxzZSIpLCBzaXplXyhzdHJsZW4odGV4dF8pKSB7fQorCisgIGlubGluZSBjb25zdCBjaGFyKiBkYXRhKCkgY29uc3QgeyByZXR1cm4gdGV4dF87IH0KKyAgaW5saW5lIGludCBzaXplKCkgY29uc3QgeyByZXR1cm4gc2l6ZV87IH0KKworIHByaXZhdGU6CisgIGNvbnN0IGNoYXIqIHRleHRfOworICBpbnQgc2l6ZV87CisgIGNoYXIgc2NyYXRjaF9ba0Zhc3RUb0J1ZmZlclNpemVdOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCisKK0xJQlBST1RPQlVGX0VYUE9SVCBzdHJpbmcgU3Vic3RpdHV0ZSgKKyAgY29uc3QgY2hhciogZm9ybWF0LAorICBjb25zdCBpbnRlcm5hbDo6U3Vic3RpdHV0ZUFyZyYgYXJnMCA9IGludGVybmFsOjpTdWJzdGl0dXRlQXJnKCksCisgIGNvbnN0IGludGVybmFsOjpTdWJzdGl0dXRlQXJnJiBhcmcxID0gaW50ZXJuYWw6OlN1YnN0aXR1dGVBcmcoKSwKKyAgY29uc3QgaW50ZXJuYWw6OlN1YnN0aXR1dGVBcmcmIGFyZzIgPSBpbnRlcm5hbDo6U3Vic3RpdHV0ZUFyZygpLAorICBjb25zdCBpbnRlcm5hbDo6U3Vic3RpdHV0ZUFyZyYgYXJnMyA9IGludGVybmFsOjpTdWJzdGl0dXRlQXJnKCksCisgIGNvbnN0IGludGVybmFsOjpTdWJzdGl0dXRlQXJnJiBhcmc0ID0gaW50ZXJuYWw6OlN1YnN0aXR1dGVBcmcoKSwKKyAgY29uc3QgaW50ZXJuYWw6OlN1YnN0aXR1dGVBcmcmIGFyZzUgPSBpbnRlcm5hbDo6U3Vic3RpdHV0ZUFyZygpLAorICBjb25zdCBpbnRlcm5hbDo6U3Vic3RpdHV0ZUFyZyYgYXJnNiA9IGludGVybmFsOjpTdWJzdGl0dXRlQXJnKCksCisgIGNvbnN0IGludGVybmFsOjpTdWJzdGl0dXRlQXJnJiBhcmc3ID0gaW50ZXJuYWw6OlN1YnN0aXR1dGVBcmcoKSwKKyAgY29uc3QgaW50ZXJuYWw6OlN1YnN0aXR1dGVBcmcmIGFyZzggPSBpbnRlcm5hbDo6U3Vic3RpdHV0ZUFyZygpLAorICBjb25zdCBpbnRlcm5hbDo6U3Vic3RpdHV0ZUFyZyYgYXJnOSA9IGludGVybmFsOjpTdWJzdGl0dXRlQXJnKCkpOworCitMSUJQUk9UT0JVRl9FWFBPUlQgdm9pZCBTdWJzdGl0dXRlQW5kQXBwZW5kKAorICBzdHJpbmcqIG91dHB1dCwgY29uc3QgY2hhciogZm9ybWF0LAorICBjb25zdCBpbnRlcm5hbDo6U3Vic3RpdHV0ZUFyZyYgYXJnMCA9IGludGVybmFsOjpTdWJzdGl0dXRlQXJnKCksCisgIGNvbnN0IGludGVybmFsOjpTdWJzdGl0dXRlQXJnJiBhcmcxID0gaW50ZXJuYWw6OlN1YnN0aXR1dGVBcmcoKSwKKyAgY29uc3QgaW50ZXJuYWw6OlN1YnN0aXR1dGVBcmcmIGFyZzIgPSBpbnRlcm5hbDo6U3Vic3RpdHV0ZUFyZygpLAorICBjb25zdCBpbnRlcm5hbDo6U3Vic3RpdHV0ZUFyZyYgYXJnMyA9IGludGVybmFsOjpTdWJzdGl0dXRlQXJnKCksCisgIGNvbnN0IGludGVybmFsOjpTdWJzdGl0dXRlQXJnJiBhcmc0ID0gaW50ZXJuYWw6OlN1YnN0aXR1dGVBcmcoKSwKKyAgY29uc3QgaW50ZXJuYWw6OlN1YnN0aXR1dGVBcmcmIGFyZzUgPSBpbnRlcm5hbDo6U3Vic3RpdHV0ZUFyZygpLAorICBjb25zdCBpbnRlcm5hbDo6U3Vic3RpdHV0ZUFyZyYgYXJnNiA9IGludGVybmFsOjpTdWJzdGl0dXRlQXJnKCksCisgIGNvbnN0IGludGVybmFsOjpTdWJzdGl0dXRlQXJnJiBhcmc3ID0gaW50ZXJuYWw6OlN1YnN0aXR1dGVBcmcoKSwKKyAgY29uc3QgaW50ZXJuYWw6OlN1YnN0aXR1dGVBcmcmIGFyZzggPSBpbnRlcm5hbDo6U3Vic3RpdHV0ZUFyZygpLAorICBjb25zdCBpbnRlcm5hbDo6U3Vic3RpdHV0ZUFyZyYgYXJnOSA9IGludGVybmFsOjpTdWJzdGl0dXRlQXJnKCkpOworCit9ICAvLyBuYW1lc3BhY2Ugc3RyaW5ncworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKyNlbmRpZiAvLyBHT09HTEVfUFJPVE9CVUZfU1RVQlNfU1VCU1RJVFVURV9IXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy90ZW1wbGF0ZV91dGlsLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3RlbXBsYXRlX3V0aWwuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mZWVmOTA0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy90ZW1wbGF0ZV91dGlsLmgKQEAgLTAsMCArMSwxMzggQEAKKy8vIENvcHlyaWdodCAyMDA1IEdvb2dsZSBJbmMuCisvLyBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyAtLS0tCisvLyBBdXRob3I6IGxhckBnb29nbGUuY29tIChMYXJhbWllIExlYXZpdHQpCisvLworLy8gVGVtcGxhdGUgbWV0YXByb2dyYW1taW5nIHV0aWxpdHkgZnVuY3Rpb25zLgorLy8KKy8vIFRoaXMgY29kZSBpcyBjb21waWxlZCBkaXJlY3RseSBvbiBtYW55IHBsYXRmb3JtcywgaW5jbHVkaW5nIGNsaWVudAorLy8gcGxhdGZvcm1zIGxpa2UgV2luZG93cywgTWFjLCBhbmQgZW1iZWRkZWQgc3lzdGVtcy4gIEJlZm9yZSBtYWtpbmcKKy8vIGFueSBjaGFuZ2VzIGhlcmUsIG1ha2Ugc3VyZSB0aGF0IHlvdSdyZSBub3QgYnJlYWtpbmcgYW55IHBsYXRmb3Jtcy4KKy8vCisvLworLy8gVGhlIG5hbWVzIGNob3NlbiBoZXJlIHJlZmxlY3QgdGhvc2UgdXNlZCBpbiB0cjEgYW5kIHRoZSBib29zdDo6bXBsCisvLyBsaWJyYXJ5LCB0aGVyZSBhcmUgc2ltaWxhciBvcGVyYXRpb25zIHVzZWQgaW4gdGhlIExva2kgbGlicmFyeSBhcworLy8gd2VsbC4gIEkgcHJlZmVyIHRoZSBib29zdCBuYW1lcyBmb3IgMiByZWFzb25zOgorLy8gMS4gIEkgdGhpbmsgdGhhdCBwb3J0aW9ucyBvZiB0aGUgQm9vc3QgbGlicmFyaWVzIGFyZSBtb3JlIGxpa2VseSB0bworLy8gYmUgaW5jbHVkZWQgaW4gdGhlIGMrKyBzdGFuZGFyZC4KKy8vIDIuICBJdCBpcyBub3QgaW1wb3NzaWJsZSB0aGF0IHNvbWUgb2YgdGhlIGJvb3N0IGxpYnJhcmllcyB3aWxsIGJlCisvLyBpbmNsdWRlZCBpbiBvdXIgb3duIGJ1aWxkIGluIHRoZSBmdXR1cmUuCisvLyBCb3RoIG9mIHRoZXNlIG91dGNvbWVzIG1lYW5zIHRoYXQgd2UgbWF5IGJlIGFibGUgdG8gZGlyZWN0bHkgcmVwbGFjZQorLy8gc29tZSBvZiB0aGVzZSB3aXRoIGJvb3N0IGVxdWl2YWxlbnRzLgorLy8KKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX1RFTVBMQVRFX1VUSUxfSF8KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1RFTVBMQVRFX1VUSUxfSF8KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKworLy8gVHlwZXMgc21hbGxfIGFuZCBiaWdfIGFyZSBndWFyYW50ZWVkIHN1Y2ggdGhhdCBzaXplb2Yoc21hbGxfKSA8CisvLyBzaXplb2YoYmlnXykKK3R5cGVkZWYgY2hhciBzbWFsbF87CisKK3N0cnVjdCBiaWdfIHsKKyAgY2hhciBkdW1teVsyXTsKK307CisKKy8vIElkZW50aXR5IG1ldGFmdW5jdGlvbi4KK3RlbXBsYXRlIDxjbGFzcyBUPgorc3RydWN0IGlkZW50aXR5XyB7CisgIHR5cGVkZWYgVCB0eXBlOworfTsKKworLy8gaW50ZWdyYWxfY29uc3RhbnQsIGRlZmluZWQgaW4gdHIxLCBpcyBhIHdyYXBwZXIgZm9yIGFuIGludGVnZXIKKy8vIHZhbHVlLiBXZSBkb24ndCByZWFsbHkgbmVlZCB0aGlzIGdlbmVyYWxpdHk7IHdlIGNvdWxkIGdldCBhd2F5CisvLyB3aXRoIGhhcmRjb2RpbmcgdGhlIGludGVnZXIgdHlwZSB0byBib29sLiBXZSB1c2UgdGhlIGZ1bGx5CisvLyBnZW5lcmFsIGludGVnZXJfY29uc3RhbnQgZm9yIGNvbXBhdGliaWxpdHkgd2l0aCB0cjEuCisKK3RlbXBsYXRlPGNsYXNzIFQsIFQgdj4KK3N0cnVjdCBpbnRlZ3JhbF9jb25zdGFudCB7CisgIHN0YXRpYyBjb25zdCBUIHZhbHVlID0gdjsKKyAgdHlwZWRlZiBUIHZhbHVlX3R5cGU7CisgIHR5cGVkZWYgaW50ZWdyYWxfY29uc3RhbnQ8VCwgdj4gdHlwZTsKK307CisKK3RlbXBsYXRlIDxjbGFzcyBULCBUIHY+IGNvbnN0IFQgaW50ZWdyYWxfY29uc3RhbnQ8VCwgdj46OnZhbHVlOworCisKKy8vIEFiYnJldmlhdGlvbnM6IHRydWVfdHlwZSBhbmQgZmFsc2VfdHlwZSBhcmUgc3RydWN0cyB0aGF0IHJlcHJlc2VudCBib29sZWFuCisvLyB0cnVlIGFuZCBmYWxzZSB2YWx1ZXMuIEFsc28gZGVmaW5lIHRoZSBib29zdDo6bXBsIHZlcnNpb25zIG9mIHRob3NlIG5hbWVzLAorLy8gdHJ1ZV8gYW5kIGZhbHNlXy4KK3R5cGVkZWYgaW50ZWdyYWxfY29uc3RhbnQ8Ym9vbCwgdHJ1ZT4gIHRydWVfdHlwZTsKK3R5cGVkZWYgaW50ZWdyYWxfY29uc3RhbnQ8Ym9vbCwgZmFsc2U+IGZhbHNlX3R5cGU7Cit0eXBlZGVmIHRydWVfdHlwZSAgdHJ1ZV87Cit0eXBlZGVmIGZhbHNlX3R5cGUgZmFsc2VfOworCisvLyBpZl8gaXMgYSB0ZW1wbGF0aXplZCBjb25kaXRpb25hbCBzdGF0ZW1lbnQuCisvLyBpZl88Y29uZCwgQSwgQj4gaXMgYSBjb21waWxlIHRpbWUgZXZhbHVhdGlvbiBvZiBjb25kLgorLy8gaWZfPD46OnR5cGUgY29udGFpbnMgQSBpZiBjb25kIGlzIHRydWUsIEIgb3RoZXJ3aXNlLgordGVtcGxhdGU8Ym9vbCBjb25kLCB0eXBlbmFtZSBBLCB0eXBlbmFtZSBCPgorc3RydWN0IGlmX3sKKyAgdHlwZWRlZiBBIHR5cGU7Cit9OworCit0ZW1wbGF0ZTx0eXBlbmFtZSBBLCB0eXBlbmFtZSBCPgorc3RydWN0IGlmXzxmYWxzZSwgQSwgQj4geworICB0eXBlZGVmIEIgdHlwZTsKK307CisKKworLy8gdHlwZV9lcXVhbHNfIGlzIGEgdGVtcGxhdGUgdHlwZSBjb21wYXJhdG9yLCBzaW1pbGFyIHRvIExva2kgSXNTYW1lVHlwZS4KKy8vIHR5cGVfZXF1YWxzXzxBLCBCPjo6dmFsdWUgaXMgdHJ1ZSBpZmYgIkEiIGlzIHRoZSBzYW1lIHR5cGUgYXMgIkIiLgorLy8KKy8vIE5ldyBjb2RlIHNob3VsZCBwcmVmZXIgYmFzZTo6aXNfc2FtZSwgZGVmaW5lZCBpbiBiYXNlL3R5cGVfdHJhaXRzLmguCisvLyBJdCBpcyBmdW5jdGlvbmFsbHkgaWRlbnRpY2FsLCBidXQgaXNfc2FtZSBpcyB0aGUgc3RhbmRhcmQgc3BlbGxpbmcuCit0ZW1wbGF0ZTx0eXBlbmFtZSBBLCB0eXBlbmFtZSBCPgorc3RydWN0IHR5cGVfZXF1YWxzXyA6IHB1YmxpYyBmYWxzZV8geworfTsKKwordGVtcGxhdGU8dHlwZW5hbWUgQT4KK3N0cnVjdCB0eXBlX2VxdWFsc188QSwgQT4gOiBwdWJsaWMgdHJ1ZV8geworfTsKKworLy8gYW5kXyBpcyBhIHRlbXBsYXRlICYmIG9wZXJhdG9yLgorLy8gYW5kXzxBLCBCPjo6dmFsdWUgZXZhbHVhdGVzICJBOjp2YWx1ZSAmJiBCOjp2YWx1ZSIuCit0ZW1wbGF0ZTx0eXBlbmFtZSBBLCB0eXBlbmFtZSBCPgorc3RydWN0IGFuZF8gOiBwdWJsaWMgaW50ZWdyYWxfY29uc3RhbnQ8Ym9vbCwgKEE6OnZhbHVlICYmIEI6OnZhbHVlKT4geworfTsKKworLy8gb3JfIGlzIGEgdGVtcGxhdGUgfHwgb3BlcmF0b3IuCisvLyBvcl88QSwgQj46OnZhbHVlIGV2YWx1YXRlcyAiQTo6dmFsdWUgfHwgQjo6dmFsdWUiLgordGVtcGxhdGU8dHlwZW5hbWUgQSwgdHlwZW5hbWUgQj4KK3N0cnVjdCBvcl8gOiBwdWJsaWMgaW50ZWdyYWxfY29uc3RhbnQ8Ym9vbCwgKEE6OnZhbHVlIHx8IEI6OnZhbHVlKT4geworfTsKKworCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9URU1QTEFURV9VVElMX0hfCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3RlbXBsYXRlX3V0aWxfdW5pdHRlc3QuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3RlbXBsYXRlX3V0aWxfdW5pdHRlc3QuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjE3NDVlMgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvdGVtcGxhdGVfdXRpbF91bml0dGVzdC5jYwpAQCAtMCwwICsxLDEzMCBAQAorLy8gQ29weXJpZ2h0IDIwMDUgR29vZ2xlIEluYy4KKy8vIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIC0tLS0KKy8vIEF1dGhvcjogbGFyQGdvb2dsZS5jb20gKExhcmFtaWUgTGVhdml0dCkKKy8vCisvLyBUaGVzZSB0ZXN0cyBhcmUgcmVhbGx5IGNvbXBpbGUgdGltZSB0ZXN0cy4KKy8vIElmIHlvdSB0cnkgdG8gc3RlcCB0aHJvdWdoIHRoaXMgaW4gYSBkZWJ1Z2dlcgorLy8geW91IHdpbGwgbm90IHNlZSBhbnkgZXZhbHVhdGlvbnMsIG1lcmVseSB0aGF0CisvLyB2YWx1ZSBpcyBhc3NpZ25lZCB0cnVlIG9yIGZhbHNlIHNlcXVlbnRpYWxseS4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy90ZW1wbGF0ZV91dGlsLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0Lmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKworbmFtZXNwYWNlIEdPT0dMRV9OQU1FU1BBQ0UgPSBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDsKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKK25hbWVzcGFjZSB7CisKK1RFU1QoVGVtcGxhdGVVdGlsVGVzdCwgVGVzdFNpemUpIHsKKyAgRVhQRUNUX0dUKHNpemVvZihHT09HTEVfTkFNRVNQQUNFOjpiaWdfKSwgc2l6ZW9mKEdPT0dMRV9OQU1FU1BBQ0U6OnNtYWxsXykpOworfQorCitURVNUKFRlbXBsYXRlVXRpbFRlc3QsIFRlc3RJbnRlZ3JhbENvbnN0YW50cykgeworICAvLyB0ZXN0IHRoZSBidWlsdC1pbiB0eXBlcy4KKyAgRVhQRUNUX1RSVUUodHJ1ZV90eXBlOjp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShmYWxzZV90eXBlOjp2YWx1ZSk7CisKKyAgdHlwZWRlZiBpbnRlZ3JhbF9jb25zdGFudDxpbnQsIDE+IG9uZV90eXBlOworICBFWFBFQ1RfRVEoMSwgb25lX3R5cGU6OnZhbHVlKTsKK30KKworVEVTVChUZW1wbGF0ZVV0aWxUZXN0LCBUZXN0VGVtcGxhdGVJZikgeworICB0eXBlZGVmIGlmXzx0cnVlLCB0cnVlX3R5cGUsIGZhbHNlX3R5cGU+Ojp0eXBlIGlmX3RydWU7CisgIEVYUEVDVF9UUlVFKGlmX3RydWU6OnZhbHVlKTsKKworICB0eXBlZGVmIGlmXzxmYWxzZSwgdHJ1ZV90eXBlLCBmYWxzZV90eXBlPjo6dHlwZSBpZl9mYWxzZTsKKyAgRVhQRUNUX0ZBTFNFKGlmX2ZhbHNlOjp2YWx1ZSk7Cit9CisKK1RFU1QoVGVtcGxhdGVVdGlsVGVzdCwgVGVzdFRlbXBsYXRlVHlwZUVxdWFscykgeworICAvLyBDaGVjayB0aGF0IHRoZSBUZW1wbGF0ZVR5cGVFcXVhbHMgd29ya3MgY29ycmVjdGx5LgorICBib29sIHZhbHVlID0gZmFsc2U7CisKKyAgLy8gVGVzdCB0aGUgc2FtZSB0eXBlIGlzIHRydWUuCisgIHZhbHVlID0gdHlwZV9lcXVhbHNfPGludCwgaW50Pjo6dmFsdWU7CisgIEVYUEVDVF9UUlVFKHZhbHVlKTsKKworICAvLyBUZXN0IGRpZmZlcmVudCB0eXBlcyBhcmUgZmFsc2UuCisgIHZhbHVlID0gdHlwZV9lcXVhbHNfPGZsb2F0LCBpbnQ+Ojp2YWx1ZTsKKyAgRVhQRUNUX0ZBTFNFKHZhbHVlKTsKKworICAvLyBUZXN0IHR5cGUgYWxpYXNpbmcuCisgIHR5cGVkZWYgY29uc3QgaW50IGZvbzsKKyAgdmFsdWUgPSB0eXBlX2VxdWFsc188Y29uc3QgZm9vLCBjb25zdCBpbnQ+Ojp2YWx1ZTsKKyAgRVhQRUNUX1RSVUUodmFsdWUpOworfQorCitURVNUKFRlbXBsYXRlVXRpbFRlc3QsIFRlc3RUZW1wbGF0ZUFuZE9yKSB7CisgIC8vIENoZWNrIHRoYXQgdGhlIFRlbXBsYXRlVHlwZUVxdWFscyB3b3JrcyBjb3JyZWN0bHkuCisgIGJvb2wgdmFsdWUgPSBmYWxzZTsKKworICAvLyBZZXMgJiYgWWVzID09IHRydWUuCisgIHZhbHVlID0gYW5kXzx0cnVlXywgdHJ1ZV8+Ojp2YWx1ZTsKKyAgRVhQRUNUX1RSVUUodmFsdWUpOworICAvLyBZZXMgJiYgTm8gPT0gZmFsc2UuCisgIHZhbHVlID0gYW5kXzx0cnVlXywgZmFsc2VfPjo6dmFsdWU7CisgIEVYUEVDVF9GQUxTRSh2YWx1ZSk7CisgIC8vIE5vICYmIFllcyA9PSBmYWxzZS4KKyAgdmFsdWUgPSBhbmRfPGZhbHNlXywgdHJ1ZV8+Ojp2YWx1ZTsKKyAgRVhQRUNUX0ZBTFNFKHZhbHVlKTsKKyAgLy8gTm8gJiYgTm8gPT0gZmFsc2UuCisgIHZhbHVlID0gYW5kXzxmYWxzZV8sIGZhbHNlXz46OnZhbHVlOworICBFWFBFQ1RfRkFMU0UodmFsdWUpOworCisgIC8vIFllcyB8fCBZZXMgPT0gdHJ1ZS4KKyAgdmFsdWUgPSBvcl88dHJ1ZV8sIHRydWVfPjo6dmFsdWU7CisgIEVYUEVDVF9UUlVFKHZhbHVlKTsKKyAgLy8gWWVzIHx8IE5vID09IHRydWUuCisgIHZhbHVlID0gb3JfPHRydWVfLCBmYWxzZV8+Ojp2YWx1ZTsKKyAgRVhQRUNUX1RSVUUodmFsdWUpOworICAvLyBObyB8fCBZZXMgPT0gdHJ1ZS4KKyAgdmFsdWUgPSBvcl88ZmFsc2VfLCB0cnVlXz46OnZhbHVlOworICBFWFBFQ1RfVFJVRSh2YWx1ZSk7CisgIC8vIE5vIHx8IE5vID09IGZhbHNlLgorICB2YWx1ZSA9IG9yXzxmYWxzZV8sIGZhbHNlXz46OnZhbHVlOworICBFWFBFQ1RfRkFMU0UodmFsdWUpOworfQorCitURVNUKFRlbXBsYXRlVXRpbFRlc3QsIFRlc3RJZGVudGl0eSkgeworICBFWFBFQ1RfVFJVRSgKKyAgICAgICh0eXBlX2VxdWFsc188R09PR0xFX05BTUVTUEFDRTo6aWRlbnRpdHlfPGludD46OnR5cGUsIGludD46OnZhbHVlKSk7CisgIEVYUEVDVF9UUlVFKAorICAgICAgKHR5cGVfZXF1YWxzXzxHT09HTEVfTkFNRVNQQUNFOjppZGVudGl0eV88dm9pZD46OnR5cGUsIHZvaWQ+Ojp2YWx1ZSkpOworfQorCit9ICAvLyBhbm9ueW1vdXMgbmFtZXNwYWNlCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy90aW1lLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy90aW1lLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ5YzA0MTIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3RpbWUuY2MKQEAgLTAsMCArMSwzNjUgQEAKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvdGltZS5oPgorCisjaW5jbHVkZSA8Y3RpbWU+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RyaW5ncHJpbnRmLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKworbmFtZXNwYWNlIHsKK3N0YXRpYyBjb25zdCBpbnQ2NCBrU2Vjb25kc1Blck1pbnV0ZSA9IDYwOworc3RhdGljIGNvbnN0IGludDY0IGtTZWNvbmRzUGVySG91ciA9IDM2MDA7CitzdGF0aWMgY29uc3QgaW50NjQga1NlY29uZHNQZXJEYXkgPSBrU2Vjb25kc1BlckhvdXIgKiAyNDsKK3N0YXRpYyBjb25zdCBpbnQ2NCBrU2Vjb25kc1BlcjQwMFllYXJzID0KKyAgICBrU2Vjb25kc1BlckRheSAqICg0MDAgKiAzNjUgKyA0MDAgLyA0IC0gMyk7CisvLyBTZWNvbmRzIGZyb20gMDAwMS0wMS0wMVQwMDowMDowMCB0byAxOTcwLTAxLTAxVDowMDowMDowMAorc3RhdGljIGNvbnN0IGludDY0IGtTZWNvbmRzRnJvbUVyYVRvRXBvY2ggPSA2MjEzNTU5NjgwMExMOworLy8gVGhlIHJhbmdlIG9mIHRpbWVzdGFtcCB2YWx1ZXMgd2Ugc3VwcG9ydC4KK3N0YXRpYyBjb25zdCBpbnQ2NCBrTWluVGltZSA9IC02MjEzNTU5NjgwMExMOyAgLy8gMDAwMS0wMS0wMVQwMDowMDowMAorc3RhdGljIGNvbnN0IGludDY0IGtNYXhUaW1lID0gMjUzNDAyMzAwNzk5TEw7ICAvLyA5OTk5LTEyLTMxVDIzOjU5OjU5CisKK3N0YXRpYyBjb25zdCBpbnQga05hbm9zUGVyTWlsbGlzZWNvbmQgPSAxMDAwMDAwOworc3RhdGljIGNvbnN0IGludCBrTmFub3NQZXJNaWNyb3NlY29uZCA9IDEwMDA7CisKKy8vIENvdW50IHRoZSBzZWNvbmRzIGZyb20gdGhlIGdpdmVuIHllYXIgKHN0YXJ0IGF0IEphbiAxLCAwMDowMCkgdG8gMTAwIHllYXJzCisvLyBhZnRlci4KK2ludDY0IFNlY29uZHNQZXIxMDBZZWFycyhpbnQgeWVhcikgeworICBpZiAoeWVhciAlIDQwMCA9PSAwIHx8IHllYXIgJSA0MDAgPiAzMDApIHsKKyAgICByZXR1cm4ga1NlY29uZHNQZXJEYXkgKiAoMTAwICogMzY1ICsgMTAwIC8gNCk7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIGtTZWNvbmRzUGVyRGF5ICogKDEwMCAqIDM2NSArIDEwMCAvIDQgLSAxKTsKKyAgfQorfQorCisvLyBDb3VudCB0aGUgc2Vjb25kcyBmcm9tIHRoZSBnaXZlbiB5ZWFyIChzdGFydCBhdCBKYW4gMSwgMDA6MDApIHRvIDQgeWVhcnMKKy8vIGFmdGVyLgoraW50NjQgU2Vjb25kc1BlcjRZZWFycyhpbnQgeWVhcikgeworICBpZiAoKHllYXIgJSAxMDAgPT0gMCB8fCB5ZWFyICUgMTAwID4gOTYpICYmCisgICAgICAhKHllYXIgJSA0MDAgPT0gMCB8fCB5ZWFyICUgNDAwID4gMzk2KSkgeworICAgIC8vIE5vIGxlYXAgeWVhcnMuCisgICAgcmV0dXJuIGtTZWNvbmRzUGVyRGF5ICogKDQgKiAzNjUpOworICB9IGVsc2UgeworICAgIC8vIE9uZSBsZWFwIHllYXJzLgorICAgIHJldHVybiBrU2Vjb25kc1BlckRheSAqICg0ICogMzY1ICsgMSk7CisgIH0KK30KKworYm9vbCBJc0xlYXBZZWFyKGludCB5ZWFyKSB7CisgIHJldHVybiB5ZWFyICUgNDAwID09IDAgfHwgKHllYXIgJSA0ID09IDAgJiYgeWVhciAlIDEwMCAhPSAwKTsKK30KKworaW50NjQgU2Vjb25kc1BlclllYXIoaW50IHllYXIpIHsKKyAgcmV0dXJuIGtTZWNvbmRzUGVyRGF5ICogKElzTGVhcFllYXIoeWVhcikgPyAzNjYgOiAzNjUpOworfQorCitzdGF0aWMgY29uc3QgaW50IGtEYXlzSW5Nb250aFsxM10gPSB7CisgIDAsIDMxLCAyOCwgMzEsIDMwLCAzMSwgMzAsIDMxLCAzMSwgMzAsIDMxLCAzMCwgMzEKK307CisKK2ludDY0IFNlY29uZHNQZXJNb250aChpbnQgbW9udGgsIGJvb2wgbGVhcCkgeworICBpZiAobW9udGggPT0gMiAmJiBsZWFwKSB7CisgICAgcmV0dXJuIGtTZWNvbmRzUGVyRGF5ICogKGtEYXlzSW5Nb250aFttb250aF0gKyAxKTsKKyAgfQorICByZXR1cm4ga1NlY29uZHNQZXJEYXkgKiBrRGF5c0luTW9udGhbbW9udGhdOworfQorCitzdGF0aWMgY29uc3QgaW50IGtEYXlzU2luY2VKYW5bMTNdID0geworICAwLCAwLCAzMSwgNTksIDkwLCAxMjAsIDE1MSwgMTgxLCAyMTIsIDI0MywgMjczLCAzMDQsIDMzNCwKK307CisKK2Jvb2wgVmFsaWRhdGVEYXRlVGltZShjb25zdCBEYXRlVGltZSYgdGltZSkgeworICBpZiAodGltZS55ZWFyIDwgMSB8fCB0aW1lLnllYXIgPiA5OTk5IHx8CisgICAgICB0aW1lLm1vbnRoIDwgMSB8fCB0aW1lLm1vbnRoID4gMTIgfHwKKyAgICAgIHRpbWUuZGF5IDwgMSB8fCB0aW1lLmRheSA+IDMxIHx8CisgICAgICB0aW1lLmhvdXIgPCAwIHx8IHRpbWUuaG91ciA+IDIzIHx8CisgICAgICB0aW1lLm1pbnV0ZSA8IDAgfHwgdGltZS5taW51dGUgPiA1OSB8fAorICAgICAgdGltZS5zZWNvbmQgPCAwIHx8IHRpbWUuc2Vjb25kID4gNTkpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgaWYgKHRpbWUubW9udGggPT0gMiAmJiBJc0xlYXBZZWFyKHRpbWUueWVhcikpIHsKKyAgICByZXR1cm4gdGltZS5tb250aCA8PSBrRGF5c0luTW9udGhbdGltZS5tb250aF0gKyAxOworICB9IGVsc2UgeworICAgIHJldHVybiB0aW1lLm1vbnRoIDw9IGtEYXlzSW5Nb250aFt0aW1lLm1vbnRoXTsKKyAgfQorfQorCisvLyBDb3VudCB0aGUgbnVtYmVyIG9mIHNlY29uZHMgZWxhcHNlZCBmcm9tIDAwMDEtMDEtMDFUMDA6MDA6MDAgdG8gdGhlIGdpdmVuCisvLyB0aW1lLgoraW50NjQgU2Vjb25kc1NpbmNlQ29tbW9uRXJhKGNvbnN0IERhdGVUaW1lJiB0aW1lKSB7CisgIGludDY0IHJlc3VsdCA9IDA7CisgIC8vIFllYXJzIHNob3VsZCBiZSBiZXR3ZWVuIDEgYW5kIDk5OTkuCisgIGFzc2VydCh0aW1lLnllYXIgPj0gMSAmJiB0aW1lLnllYXIgPD0gOTk5OSk7CisgIGludCB5ZWFyID0gMTsKKyAgaWYgKCh0aW1lLnllYXIgLSB5ZWFyKSA+PSA0MDApIHsKKyAgICBpbnQgY291bnRfNDAweWVhcnMgPSAodGltZS55ZWFyIC0geWVhcikgLyA0MDA7CisgICAgcmVzdWx0ICs9IGtTZWNvbmRzUGVyNDAwWWVhcnMgKiBjb3VudF80MDB5ZWFyczsKKyAgICB5ZWFyICs9IGNvdW50XzQwMHllYXJzICogNDAwOworICB9CisgIHdoaWxlICgodGltZS55ZWFyIC0geWVhcikgPj0gMTAwKSB7CisgICAgcmVzdWx0ICs9IFNlY29uZHNQZXIxMDBZZWFycyh5ZWFyKTsKKyAgICB5ZWFyICs9IDEwMDsKKyAgfQorICB3aGlsZSAoKHRpbWUueWVhciAtIHllYXIpID49IDQpIHsKKyAgICByZXN1bHQgKz0gU2Vjb25kc1BlcjRZZWFycyh5ZWFyKTsKKyAgICB5ZWFyICs9IDQ7CisgIH0KKyAgd2hpbGUgKHRpbWUueWVhciA+IHllYXIpIHsKKyAgICByZXN1bHQgKz0gU2Vjb25kc1BlclllYXIoeWVhcik7CisgICAgKyt5ZWFyOworICB9CisgIC8vIE1vbnRocyBzaG91bGQgYmUgYmV0d2VlbiAxIGFuZCAxMi4KKyAgYXNzZXJ0KHRpbWUubW9udGggPj0gMSAmJiB0aW1lLm1vbnRoIDw9IDEyKTsKKyAgaW50IG1vbnRoID0gdGltZS5tb250aDsKKyAgcmVzdWx0ICs9IGtTZWNvbmRzUGVyRGF5ICoga0RheXNTaW5jZUphblttb250aF07CisgIGlmIChtb250aCA+IDIgJiYgSXNMZWFwWWVhcih5ZWFyKSkgeworICAgIHJlc3VsdCArPSBrU2Vjb25kc1BlckRheTsKKyAgfQorICBhc3NlcnQodGltZS5kYXkgPj0gMSAmJgorICAgICAgICAgdGltZS5kYXkgPD0gKG1vbnRoID09IDIgJiYgSXNMZWFwWWVhcih5ZWFyKQorICAgICAgICAgICAgICAgICAgICAgICAgICA/IGtEYXlzSW5Nb250aFttb250aF0gKyAxCisgICAgICAgICAgICAgICAgICAgICAgICAgIDoga0RheXNJbk1vbnRoW21vbnRoXSkpOworICByZXN1bHQgKz0ga1NlY29uZHNQZXJEYXkgKiAodGltZS5kYXkgLSAxKTsKKyAgcmVzdWx0ICs9IGtTZWNvbmRzUGVySG91ciAqIHRpbWUuaG91ciArCisgICAgICBrU2Vjb25kc1Blck1pbnV0ZSAqIHRpbWUubWludXRlICsKKyAgICAgIHRpbWUuc2Vjb25kOworICByZXR1cm4gcmVzdWx0OworfQorCisvLyBGb3JtYXQgbmFub3NlY29uZHMgd2l0aCBlaXRoZXIgMywgNiwgb3IgOSBkaWdpdHMgZGVwZW5kaW5nIG9uIHRoZSByZXF1aXJlZAorLy8gcHJlY2lzaW9uIHRvIHJlcHJlc2VudCB0aGUgZXhhY3QgdmFsdWUuCitzdHJpbmcgRm9ybWF0TmFub3MoaW50MzIgbmFub3MpIHsKKyAgaWYgKG5hbm9zICUga05hbm9zUGVyTWlsbGlzZWNvbmQgPT0gMCkgeworICAgIHJldHVybiBTdHJpbmdQcmludGYoIiUwM2QiLCBuYW5vcyAvIGtOYW5vc1Blck1pbGxpc2Vjb25kKTsKKyAgfSBlbHNlIGlmIChuYW5vcyAlIGtOYW5vc1Blck1pY3Jvc2Vjb25kID09IDApIHsKKyAgICByZXR1cm4gU3RyaW5nUHJpbnRmKCIlMDZkIiwgbmFub3MgLyBrTmFub3NQZXJNaWNyb3NlY29uZCk7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIFN0cmluZ1ByaW50ZigiJTA5ZCIsIG5hbm9zKTsKKyAgfQorfQorCisvLyBQYXJzZXMgYW4gaW50ZWdlciBmcm9tIGEgbnVsbC10ZXJtaW5hdGVkIGNoYXIgc2VxdWVuY2UuIFRoZSBtZXRob2QKKy8vIGNvbnN1bWVzIGF0IG1vc3QgIndpZHRoIiBjaGFycy4gUmV0dXJucyBhIHBvaW50ZXIgYWZ0ZXIgdGhlIGNvbnN1bWVkCisvLyBpbnRlZ2VyLCBvciBOVUxMIGlmIHRoZSBkYXRhIGRvZXMgbm90IHN0YXJ0IHdpdGggYW4gaW50ZWdlciBvciB0aGUKKy8vIGludGVnZXIgdmFsdWUgZG9lcyBub3QgZmFsbCBpbiB0aGUgcmFuZ2Ugb2YgW21pbl92YWx1ZSwgbWF4X3ZhbHVlXS4KK2NvbnN0IGNoYXIqIFBhcnNlSW50KGNvbnN0IGNoYXIqIGRhdGEsIGludCB3aWR0aCwgaW50IG1pbl92YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgIGludCBtYXhfdmFsdWUsIGludCogcmVzdWx0KSB7CisgIGlmICghYXNjaWlfaXNkaWdpdCgqZGF0YSkpIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICBpbnQgdmFsdWUgPSAwOworICBmb3IgKGludCBpID0gMDsgaSA8IHdpZHRoOyArK2ksICsrZGF0YSkgeworICAgIGlmIChhc2NpaV9pc2RpZ2l0KCpkYXRhKSkgeworICAgICAgdmFsdWUgPSB2YWx1ZSAqIDEwICsgKCpkYXRhIC0gJzAnKTsKKyAgICB9IGVsc2UgeworICAgICAgYnJlYWs7CisgICAgfQorICB9CisgIGlmICh2YWx1ZSA+PSBtaW5fdmFsdWUgJiYgdmFsdWUgPD0gbWF4X3ZhbHVlKSB7CisgICAgKnJlc3VsdCA9IHZhbHVlOworICAgIHJldHVybiBkYXRhOworICB9IGVsc2UgeworICAgIHJldHVybiBOVUxMOworICB9Cit9CisKKy8vIENvbnN1bWVzIHRoZSBmcmFjdGlvbmFsIHBhcnRzIG9mIGEgc2Vjb25kIGludG8gbmFub3MuIEZvciBleGFtcGxlLAorLy8gIjAxMCIgd2lsbCBiZSBwYXJzZWQgdG8gMTAwMDAwMDAgbmFub3MuCitjb25zdCBjaGFyKiBQYXJzZU5hbm9zKGNvbnN0IGNoYXIqIGRhdGEsIGludDMyKiBuYW5vcykgeworICBpZiAoIWFzY2lpX2lzZGlnaXQoKmRhdGEpKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgaW50IHZhbHVlID0gMDsKKyAgaW50IGxlbiA9IDA7CisgIC8vIENvbnN1bWUgYXMgbWFueSBkaWdpdHMgYXMgdGhlcmUgYXJlIGJ1dCBvbmx5IHRha2UgdGhlIGZpcnN0IDkgaW50bworICAvLyBhY2NvdW50LgorICB3aGlsZSAoYXNjaWlfaXNkaWdpdCgqZGF0YSkpIHsKKyAgICBpZiAobGVuIDwgOSkgeworICAgICAgdmFsdWUgPSB2YWx1ZSAqIDEwICsgKmRhdGEgLSAnMCc7CisgICAgfQorICAgICsrbGVuOworICAgICsrZGF0YTsKKyAgfQorICB3aGlsZSAobGVuIDwgOSkgeworICAgIHZhbHVlID0gdmFsdWUgKiAxMDsKKyAgICArK2xlbjsKKyAgfQorICAqbmFub3MgPSB2YWx1ZTsKKyAgcmV0dXJuIGRhdGE7Cit9CisKK2NvbnN0IGNoYXIqIFBhcnNlVGltZXpvbmVPZmZzZXQoY29uc3QgY2hhciogZGF0YSwgaW50NjQqIG9mZnNldCkgeworICAvLyBBY2NlcHQgZm9ybWF0ICJISDpNTSIuIEUuZy4sICIwODowMCIKKyAgaW50IGhvdXI7CisgIGlmICgoZGF0YSA9IFBhcnNlSW50KGRhdGEsIDIsIDAsIDIzLCAmaG91cikpID09IE5VTEwpIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICBpZiAoKmRhdGErKyAhPSAnOicpIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICBpbnQgbWludXRlOworICBpZiAoKGRhdGEgPSBQYXJzZUludChkYXRhLCAyLCAwLCA1OSwgJm1pbnV0ZSkpID09IE5VTEwpIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICAqb2Zmc2V0ID0gKGhvdXIgKiA2MCArIG1pbnV0ZSkgKiA2MDsKKyAgcmV0dXJuIGRhdGE7Cit9Cit9ICAvLyBuYW1lc3BhY2UKKworYm9vbCBTZWNvbmRzVG9EYXRlVGltZShpbnQ2NCBzZWNvbmRzLCBEYXRlVGltZSogdGltZSkgeworICBpZiAoc2Vjb25kcyA8IGtNaW5UaW1lIHx8IHNlY29uZHMgPiBrTWF4VGltZSkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICAvLyBJdCdzIGVhc2llciB0byBjYWxjdWF0ZSB0aGUgRGF0ZVRpbWUgc3RhcnRpbmcgZnJvbSAwMDAxLTAxLTAxVDAwOjAwOjAwCisgIHNlY29uZHMgPSBzZWNvbmRzICsga1NlY29uZHNGcm9tRXJhVG9FcG9jaDsKKyAgaW50IHllYXIgPSAxOworICBpZiAoc2Vjb25kcyA+PSBrU2Vjb25kc1BlcjQwMFllYXJzKSB7CisgICAgaW50IGNvdW50XzQwMHllYXJzID0gc2Vjb25kcyAvIGtTZWNvbmRzUGVyNDAwWWVhcnM7CisgICAgeWVhciArPSA0MDAgKiBjb3VudF80MDB5ZWFyczsKKyAgICBzZWNvbmRzICU9IGtTZWNvbmRzUGVyNDAwWWVhcnM7CisgIH0KKyAgd2hpbGUgKHNlY29uZHMgPj0gU2Vjb25kc1BlcjEwMFllYXJzKHllYXIpKSB7CisgICAgc2Vjb25kcyAtPSBTZWNvbmRzUGVyMTAwWWVhcnMoeWVhcik7CisgICAgeWVhciArPSAxMDA7CisgIH0KKyAgd2hpbGUgKHNlY29uZHMgPj0gU2Vjb25kc1BlcjRZZWFycyh5ZWFyKSkgeworICAgIHNlY29uZHMgLT0gU2Vjb25kc1BlcjRZZWFycyh5ZWFyKTsKKyAgICB5ZWFyICs9IDQ7CisgIH0KKyAgd2hpbGUgKHNlY29uZHMgPj0gU2Vjb25kc1BlclllYXIoeWVhcikpIHsKKyAgICBzZWNvbmRzIC09IFNlY29uZHNQZXJZZWFyKHllYXIpOworICAgIHllYXIgKz0gMTsKKyAgfQorICBib29sIGxlYXAgPSBJc0xlYXBZZWFyKHllYXIpOworICBpbnQgbW9udGggPSAxOworICB3aGlsZSAoc2Vjb25kcyA+PSBTZWNvbmRzUGVyTW9udGgobW9udGgsIGxlYXApKSB7CisgICAgc2Vjb25kcyAtPSBTZWNvbmRzUGVyTW9udGgobW9udGgsIGxlYXApOworICAgICsrbW9udGg7CisgIH0KKyAgaW50IGRheSA9IDEgKyBzZWNvbmRzIC8ga1NlY29uZHNQZXJEYXk7CisgIHNlY29uZHMgJT0ga1NlY29uZHNQZXJEYXk7CisgIGludCBob3VyID0gc2Vjb25kcyAvIGtTZWNvbmRzUGVySG91cjsKKyAgc2Vjb25kcyAlPSBrU2Vjb25kc1BlckhvdXI7CisgIGludCBtaW51dGUgPSBzZWNvbmRzIC8ga1NlY29uZHNQZXJNaW51dGU7CisgIHNlY29uZHMgJT0ga1NlY29uZHNQZXJNaW51dGU7CisgIHRpbWUtPnllYXIgPSB5ZWFyOworICB0aW1lLT5tb250aCA9IG1vbnRoOworICB0aW1lLT5kYXkgPSBkYXk7CisgIHRpbWUtPmhvdXIgPSBob3VyOworICB0aW1lLT5taW51dGUgPSBtaW51dGU7CisgIHRpbWUtPnNlY29uZCA9IHN0YXRpY19jYXN0PGludD4oc2Vjb25kcyk7CisgIHJldHVybiB0cnVlOworfQorCitib29sIERhdGVUaW1lVG9TZWNvbmRzKGNvbnN0IERhdGVUaW1lJiB0aW1lLCBpbnQ2NCogc2Vjb25kcykgeworICBpZiAoIVZhbGlkYXRlRGF0ZVRpbWUodGltZSkpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgKnNlY29uZHMgPSBTZWNvbmRzU2luY2VDb21tb25FcmEodGltZSkgLSBrU2Vjb25kc0Zyb21FcmFUb0Vwb2NoOworICByZXR1cm4gdHJ1ZTsKK30KKwordm9pZCBHZXRDdXJyZW50VGltZShpbnQ2NCogc2Vjb25kcywgaW50MzIqIG5hbm9zKSB7CisgIC8vIFRPRE8oeGlhb2ZlbmcpOiBJbXByb3ZlIHRoZSBhY2N1cmFjeSBvZiB0aGlzIGltcGxlbWVudGF0aW9uIChvciBqdXN0CisgIC8vIHJlbW92ZSB0aGlzIG1ldGhvZCBmcm9tIHByb3RvYnVmKS4KKyAgKnNlY29uZHMgPSB0aW1lKE5VTEwpOworICAqbmFub3MgPSAwOworfQorCitzdHJpbmcgRm9ybWF0VGltZShpbnQ2NCBzZWNvbmRzLCBpbnQzMiBuYW5vcykgeworICBEYXRlVGltZSB0aW1lOworICBpZiAobmFub3MgPCAwIHx8IG5hbm9zID4gOTk5OTk5OTk5IHx8ICFTZWNvbmRzVG9EYXRlVGltZShzZWNvbmRzLCAmdGltZSkpIHsKKyAgICByZXR1cm4gIkludmFsaWRUaW1lIjsKKyAgfQorICBzdHJpbmcgcmVzdWx0ID0gU3RyaW5nUHJpbnRmKCIlMDRkLSUwMmQtJTAyZFQlMDJkOiUwMmQ6JTAyZCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGltZS55ZWFyLCB0aW1lLm1vbnRoLCB0aW1lLmRheSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lLmhvdXIsIHRpbWUubWludXRlLCB0aW1lLnNlY29uZCk7CisgIGlmIChuYW5vcyAhPSAwKSB7CisgICAgcmVzdWx0ICs9ICIuIiArIEZvcm1hdE5hbm9zKG5hbm9zKTsKKyAgfQorICByZXR1cm4gcmVzdWx0ICsgIloiOworfQorCitib29sIFBhcnNlVGltZShjb25zdCBzdHJpbmcmIHZhbHVlLCBpbnQ2NCogc2Vjb25kcywgaW50MzIqIG5hbm9zKSB7CisgIERhdGVUaW1lIHRpbWU7CisgIGNvbnN0IGNoYXIqIGRhdGEgPSB2YWx1ZS5jX3N0cigpOworICAvLyBXZSBvbmx5IGFjY2VwdDoKKyAgLy8gICBaLW5vcm1hbGl6ZWQ6IDIwMTUtMDUtMjBUMTM6Mjk6MzUuMTIwWgorICAvLyAgIFdpdGggVVRDIG9mZnNldDogMjAxNS0wNS0yMFQxMzoyOTozNS4xMjAtMDg6MDAKKworICAvLyBQYXJzZSB5ZWFyCisgIGlmICgoZGF0YSA9IFBhcnNlSW50KGRhdGEsIDQsIDEsIDk5OTksICZ0aW1lLnllYXIpKSA9PSBOVUxMKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIC8vIEV4cGVjdCAnLScKKyAgaWYgKCpkYXRhKysgIT0gJy0nKSByZXR1cm4gZmFsc2U7CisgIC8vIFBhcnNlIG1vbnRoCisgIGlmICgoZGF0YSA9IFBhcnNlSW50KGRhdGEsIDIsIDEsIDEyLCAmdGltZS5tb250aCkpID09IE5VTEwpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgLy8gRXhwZWN0ICctJworICBpZiAoKmRhdGErKyAhPSAnLScpIHJldHVybiBmYWxzZTsKKyAgLy8gUGFyc2UgZGF5CisgIGlmICgoZGF0YSA9IFBhcnNlSW50KGRhdGEsIDIsIDEsIDMxLCAmdGltZS5kYXkpKSA9PSBOVUxMKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIC8vIEV4cGVjdCAnVCcKKyAgaWYgKCpkYXRhKysgIT0gJ1QnKSByZXR1cm4gZmFsc2U7CisgIC8vIFBhcnNlIGhvdXIKKyAgaWYgKChkYXRhID0gUGFyc2VJbnQoZGF0YSwgMiwgMCwgMjMsICZ0aW1lLmhvdXIpKSA9PSBOVUxMKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIC8vIEV4cGVjdCAnOicKKyAgaWYgKCpkYXRhKysgIT0gJzonKSByZXR1cm4gZmFsc2U7CisgIC8vIFBhcnNlIG1pbnV0ZQorICBpZiAoKGRhdGEgPSBQYXJzZUludChkYXRhLCAyLCAwLCA1OSwgJnRpbWUubWludXRlKSkgPT0gTlVMTCkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICAvLyBFeHBlY3QgJzonCisgIGlmICgqZGF0YSsrICE9ICc6JykgcmV0dXJuIGZhbHNlOworICAvLyBQYXJzZSBzZWNvbmQKKyAgaWYgKChkYXRhID0gUGFyc2VJbnQoZGF0YSwgMiwgMCwgNTksICZ0aW1lLnNlY29uZCkpID09IE5VTEwpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgaWYgKCFEYXRlVGltZVRvU2Vjb25kcyh0aW1lLCBzZWNvbmRzKSkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICAvLyBQYXJzZSBuYW5vc2Vjb25kcy4KKyAgaWYgKCpkYXRhID09ICcuJykgeworICAgICsrZGF0YTsKKyAgICAvLyBQYXJzZSBuYW5vc2Vjb25kcy4KKyAgICBpZiAoKGRhdGEgPSBQYXJzZU5hbm9zKGRhdGEsIG5hbm9zKSkgPT0gTlVMTCkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICAqbmFub3MgPSAwOworICB9CisgIC8vIFBhcnNlIFVUQyBvZmZzZXRzLgorICBpZiAoKmRhdGEgPT0gJ1onKSB7CisgICAgKytkYXRhOworICB9IGVsc2UgaWYgKCpkYXRhID09ICcrJykgeworICAgICsrZGF0YTsKKyAgICBpbnQ2NCBvZmZzZXQ7CisgICAgaWYgKChkYXRhID0gUGFyc2VUaW1lem9uZU9mZnNldChkYXRhLCAmb2Zmc2V0KSkgPT0gTlVMTCkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICAqc2Vjb25kcyAtPSBvZmZzZXQ7CisgIH0gZWxzZSBpZiAoKmRhdGEgPT0gJy0nKSB7CisgICAgKytkYXRhOworICAgIGludDY0IG9mZnNldDsKKyAgICBpZiAoKGRhdGEgPSBQYXJzZVRpbWV6b25lT2Zmc2V0KGRhdGEsICZvZmZzZXQpKSA9PSBOVUxMKSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgICpzZWNvbmRzICs9IG9mZnNldDsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgLy8gRG9uZSB3aXRoIHBhcnNpbmcuCisgIHJldHVybiAqZGF0YSA9PSAwOworfQorCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy90aW1lLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3RpbWUuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMGE2YjU2Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy90aW1lLmgKQEAgLTAsMCArMSw3NSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9TVFVCU19USU1FX0hfCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9TVFVCU19USU1FX0hfCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKK3N0cnVjdCBEYXRlVGltZSB7CisgIGludCB5ZWFyOworICBpbnQgbW9udGg7CisgIGludCBkYXk7CisgIGludCBob3VyOworICBpbnQgbWludXRlOworICBpbnQgc2Vjb25kOworfTsKKworLy8gQ29udmVydHMgYSB0aW1lc3RhbXAgKHNlY29uZHMgZWxhcHNlZCBzaW5jZSAxOTcwLTAxLTAxVDAwOjAwOjAwLCBjb3VsZCBiZQorLy8gbmVnYXRpdmUgdG8gcmVwcmVzZW50IHRpbWUgYmVmb3JlIDE5NzAtMDEtMDEpIHRvIERhdGVUaW1lLiBSZXR1cm5zIGZhbHNlCisvLyBpZiB0aGUgdGltZXN0YW1wIGlzIG5vdCBpbiB0aGUgcmFuZ2UgYmV0d2VlbiAwMDAxLTAxLTAxVDAwOjAwOjAwIGFuZAorLy8gOTk5OS0xMi0zMVQyMzo1OTo1OS4KK2Jvb2wgTElCUFJPVE9CVUZfRVhQT1JUIFNlY29uZHNUb0RhdGVUaW1lKGludDY0IHNlY29uZHMsIERhdGVUaW1lKiB0aW1lKTsKKy8vIENvbnZlcnRzIERhdGVUaW1lIHRvIGEgdGltZXN0YW1wIChzZWNvbmRzIHNpbmNlIDE5NzAtMDEtMDFUMDA6MDA6MDApLgorLy8gUmV0dXJucyBmYWxzZSBpZiB0aGUgRGF0ZVRpbWUgaXMgbm90IHZhbGlkIG9yIGlzIG5vdCBpbiB0aGUgdmFsaWQgcmFuZ2UuCitib29sIExJQlBST1RPQlVGX0VYUE9SVCBEYXRlVGltZVRvU2Vjb25kcyhjb25zdCBEYXRlVGltZSYgdGltZSwgaW50NjQqIHNlY29uZHMpOworCit2b2lkIExJQlBST1RPQlVGX0VYUE9SVCBHZXRDdXJyZW50VGltZShpbnQ2NCogc2Vjb25kcywgaW50MzIqIG5hbm9zKTsKKworLy8gRm9ybWF0cyBhIHRpbWUgc3RyaW5nIGluIFJGQzMzMzkgZnJvbWF0LgorLy8KKy8vIEZvciBleGFtcGxlLCAiMjAxNS0wNS0yMFQxMzoyOTozNS4xMjBaIi4gRm9yIG5hbm9zLCAwLCAzLCA2IG9yIDkgZnJhY3Rpb25hbAorLy8gZGlnaXRzIHdpbGwgYmUgdXNlZCBkZXBlbmRpbmcgb24gaG93IG1hbnkgYXJlIHJlcXVpcmVkIHRvIHJlcHJlc2VudCB0aGUgZXhhY3QKKy8vIHZhbHVlLgorLy8KKy8vIE5vdGUgdGhhdCAibmFub3MiIG11c3QgaW4gdGhlIHJhbmdlIG9mIFswLCA5OTk5OTk5OTldLgorc3RyaW5nIExJQlBST1RPQlVGX0VYUE9SVCBGb3JtYXRUaW1lKGludDY0IHNlY29uZHMsIGludDMyIG5hbm9zKTsKKy8vIFBhcnNlcyBhIHRpbWUgc3RyaW5nLiBUaGlzIG1ldGhvZCBhY2NlcHRzIFJGQzMzMzkgZGF0ZS90aW1lIHN0cmluZyB3aXRoIFVUQworLy8gb2Zmc2V0LiBGb3IgZXhhbXBsZSwgIjIwMTUtMDUtMjBUMTM6Mjk6MzUuMTIwLTA4OjAwIi4KK2Jvb2wgTElCUFJPVE9CVUZfRVhQT1JUIFBhcnNlVGltZShjb25zdCBzdHJpbmcmIHZhdWxlLCBpbnQ2NCogc2Vjb25kcywgaW50MzIqIG5hbm9zKTsKKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfU1RVQlNfVElNRV9IXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy90aW1lX3Rlc3QuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3RpbWVfdGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41OWU5ZDFjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy90aW1lX3Rlc3QuY2MKQEAgLTAsMCArMSwyMDggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy90aW1lLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0Lmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKK25hbWVzcGFjZSB7CitzdGF0aWMgY29uc3QgaW50NjQga1NlY29uZHNQZXJEYXkgPSAzNjAwICogMjQ7CisKKy8vIEZvciBEYXRlVGltZSwgdGVzdHMgd2lsbCBtb3N0bHkgZm9jdXNlIG9uIHRoZSBkYXRlIHBhcnQgYmVjYXVzZSB0aGF0J3MKKy8vIHRoZSB0cmlja3kgb25lLgoraW50NjQgQ3JlYXRlVGltZXN0YW1wKGludCB5ZWFyLCBpbnQgbW9udGgsIGludCBkYXkpIHsKKyAgRGF0ZVRpbWUgdGltZTsKKyAgdGltZS55ZWFyID0geWVhcjsKKyAgdGltZS5tb250aCA9IG1vbnRoOworICB0aW1lLmRheSA9IGRheTsKKyAgdGltZS5ob3VyID0gdGltZS5taW51dGUgPSB0aW1lLnNlY29uZCA9IDA7CisgIGludDY0IHJlc3VsdDsKKyAgR09PR0xFX0NIRUNLKERhdGVUaW1lVG9TZWNvbmRzKHRpbWUsICZyZXN1bHQpKTsKKyAgLy8gQ2hlY2sgdGhhdCBhIHJvdW5kdHJpcCBwcm9kdWNlcyB0aGUgc2FtZSByZXN1bHQuCisgIEdPT0dMRV9DSEVDSyhTZWNvbmRzVG9EYXRlVGltZShyZXN1bHQsICZ0aW1lKSk7CisgIEdPT0dMRV9DSEVDSyh0aW1lLnllYXIgPT0geWVhcik7CisgIEdPT0dMRV9DSEVDSyh0aW1lLm1vbnRoID09IG1vbnRoKTsKKyAgR09PR0xFX0NIRUNLKHRpbWUuZGF5ID09IGRheSk7CisgIHJldHVybiByZXN1bHQ7Cit9CisKK1RFU1QoRGF0ZVRpbWVUZXN0LCBTaW1wbGVUaW1lKSB7CisgIERhdGVUaW1lIHRpbWU7CisgIEFTU0VSVF9UUlVFKFNlY29uZHNUb0RhdGVUaW1lKDEsICZ0aW1lKSk7CisgIEVYUEVDVF9FUSgxOTcwLCB0aW1lLnllYXIpOworICBFWFBFQ1RfRVEoMSwgdGltZS5tb250aCk7CisgIEVYUEVDVF9FUSgxLCB0aW1lLmRheSk7CisgIEVYUEVDVF9FUSgwLCB0aW1lLmhvdXIpOworICBFWFBFQ1RfRVEoMCwgdGltZS5taW51dGUpOworICBFWFBFQ1RfRVEoMSwgdGltZS5zZWNvbmQpOworICBpbnQ2NCBzZWNvbmRzOworICBBU1NFUlRfVFJVRShEYXRlVGltZVRvU2Vjb25kcyh0aW1lLCAmc2Vjb25kcykpOworICBFWFBFQ1RfRVEoMSwgc2Vjb25kcyk7CisKKyAgQVNTRVJUX1RSVUUoU2Vjb25kc1RvRGF0ZVRpbWUoLTEsICZ0aW1lKSk7CisgIEVYUEVDVF9FUSgxOTY5LCB0aW1lLnllYXIpOworICBFWFBFQ1RfRVEoMTIsIHRpbWUubW9udGgpOworICBFWFBFQ1RfRVEoMzEsIHRpbWUuZGF5KTsKKyAgRVhQRUNUX0VRKDIzLCB0aW1lLmhvdXIpOworICBFWFBFQ1RfRVEoNTksIHRpbWUubWludXRlKTsKKyAgRVhQRUNUX0VRKDU5LCB0aW1lLnNlY29uZCk7CisgIEFTU0VSVF9UUlVFKERhdGVUaW1lVG9TZWNvbmRzKHRpbWUsICZzZWNvbmRzKSk7CisgIEVYUEVDVF9FUSgtMSwgc2Vjb25kcyk7CisKKyAgRGF0ZVRpbWUgc3RhcnQsIGVuZDsKKyAgc3RhcnQueWVhciA9IDE7CisgIHN0YXJ0Lm1vbnRoID0gMTsKKyAgc3RhcnQuZGF5ID0gMTsKKyAgc3RhcnQuaG91ciA9IDA7CisgIHN0YXJ0Lm1pbnV0ZSA9IDA7CisgIHN0YXJ0LnNlY29uZCA9IDA7CisgIGVuZC55ZWFyID0gOTk5OTsKKyAgZW5kLm1vbnRoID0gMTI7CisgIGVuZC5kYXkgPSAzMTsKKyAgZW5kLmhvdXIgPSAyMzsKKyAgZW5kLm1pbnV0ZSA9IDU5OworICBlbmQuc2Vjb25kID0gNTk7CisgIGludDY0IHN0YXJ0X3RpbWUsIGVuZF90aW1lOworICBBU1NFUlRfVFJVRShEYXRlVGltZVRvU2Vjb25kcyhzdGFydCwgJnN0YXJ0X3RpbWUpKTsKKyAgQVNTRVJUX1RSVUUoRGF0ZVRpbWVUb1NlY29uZHMoZW5kLCAmZW5kX3RpbWUpKTsKKyAgRVhQRUNUX0VRKDMxNTUzNzg5NzU5OUxMLCBlbmRfdGltZSAtIHN0YXJ0X3RpbWUpOworICBBU1NFUlRfVFJVRShTZWNvbmRzVG9EYXRlVGltZShzdGFydF90aW1lLCAmdGltZSkpOworICBBU1NFUlRfVFJVRShEYXRlVGltZVRvU2Vjb25kcyh0aW1lLCAmc2Vjb25kcykpOworICBFWFBFQ1RfRVEoc3RhcnRfdGltZSwgc2Vjb25kcyk7CisgIEFTU0VSVF9UUlVFKFNlY29uZHNUb0RhdGVUaW1lKGVuZF90aW1lLCAmdGltZSkpOworICBBU1NFUlRfVFJVRShEYXRlVGltZVRvU2Vjb25kcyh0aW1lLCAmc2Vjb25kcykpOworICBFWFBFQ1RfRVEoZW5kX3RpbWUsIHNlY29uZHMpOworfQorCitURVNUKERhdGVUaW1lVGVzdCwgRGF5SW5Nb250aHMpIHsKKyAgLy8gQ2hlY2sgdGhhdCBtb250aCBib3VuZGFyaWVzIGFyZSBoYW5kbGVkIGNvcnJlY3RseS4KKyAgRVhQRUNUX0VRKGtTZWNvbmRzUGVyRGF5LAorICAgICAgICAgICAgQ3JlYXRlVGltZXN0YW1wKDIwMTUsIDEsIDEpIC0gQ3JlYXRlVGltZXN0YW1wKDIwMTQsIDEyLCAzMSkpOworICBFWFBFQ1RfRVEoa1NlY29uZHNQZXJEYXksCisgICAgICAgICAgICBDcmVhdGVUaW1lc3RhbXAoMjAxNSwgMiwgMSkgLSBDcmVhdGVUaW1lc3RhbXAoMjAxNSwgMSwgMzEpKTsKKyAgRVhQRUNUX0VRKGtTZWNvbmRzUGVyRGF5LAorICAgICAgICAgICAgQ3JlYXRlVGltZXN0YW1wKDIwMTUsIDMsIDEpIC0gQ3JlYXRlVGltZXN0YW1wKDIwMTUsIDIsIDI4KSk7CisgIEVYUEVDVF9FUShrU2Vjb25kc1BlckRheSwKKyAgICAgICAgICAgIENyZWF0ZVRpbWVzdGFtcCgyMDE1LCA0LCAxKSAtIENyZWF0ZVRpbWVzdGFtcCgyMDE1LCAzLCAzMSkpOworICBFWFBFQ1RfRVEoa1NlY29uZHNQZXJEYXksCisgICAgICAgICAgICBDcmVhdGVUaW1lc3RhbXAoMjAxNSwgNSwgMSkgLSBDcmVhdGVUaW1lc3RhbXAoMjAxNSwgNCwgMzApKTsKKyAgRVhQRUNUX0VRKGtTZWNvbmRzUGVyRGF5LAorICAgICAgICAgICAgQ3JlYXRlVGltZXN0YW1wKDIwMTUsIDYsIDEpIC0gQ3JlYXRlVGltZXN0YW1wKDIwMTUsIDUsIDMxKSk7CisgIEVYUEVDVF9FUShrU2Vjb25kc1BlckRheSwKKyAgICAgICAgICAgIENyZWF0ZVRpbWVzdGFtcCgyMDE1LCA3LCAxKSAtIENyZWF0ZVRpbWVzdGFtcCgyMDE1LCA2LCAzMCkpOworICBFWFBFQ1RfRVEoa1NlY29uZHNQZXJEYXksCisgICAgICAgICAgICBDcmVhdGVUaW1lc3RhbXAoMjAxNSwgOCwgMSkgLSBDcmVhdGVUaW1lc3RhbXAoMjAxNSwgNywgMzEpKTsKKyAgRVhQRUNUX0VRKGtTZWNvbmRzUGVyRGF5LAorICAgICAgICAgICAgQ3JlYXRlVGltZXN0YW1wKDIwMTUsIDksIDEpIC0gQ3JlYXRlVGltZXN0YW1wKDIwMTUsIDgsIDMxKSk7CisgIEVYUEVDVF9FUShrU2Vjb25kc1BlckRheSwKKyAgICAgICAgICAgIENyZWF0ZVRpbWVzdGFtcCgyMDE1LCAxMCwgMSkgLSBDcmVhdGVUaW1lc3RhbXAoMjAxNSwgOSwgMzApKTsKKyAgRVhQRUNUX0VRKGtTZWNvbmRzUGVyRGF5LAorICAgICAgICAgICAgQ3JlYXRlVGltZXN0YW1wKDIwMTUsIDExLCAxKSAtIENyZWF0ZVRpbWVzdGFtcCgyMDE1LCAxMCwgMzEpKTsKKyAgRVhQRUNUX0VRKGtTZWNvbmRzUGVyRGF5LAorICAgICAgICAgICAgQ3JlYXRlVGltZXN0YW1wKDIwMTUsIDEyLCAxKSAtIENyZWF0ZVRpbWVzdGFtcCgyMDE1LCAxMSwgMzApKTsKKyAgRVhQRUNUX0VRKGtTZWNvbmRzUGVyRGF5LAorICAgICAgICAgICAgQ3JlYXRlVGltZXN0YW1wKDIwMTYsIDEsIDEpIC0gQ3JlYXRlVGltZXN0YW1wKDIwMTUsIDEyLCAzMSkpOworfQorCitURVNUKERhdGVUaW1lVGVzdCwgTGVhcFllYXIpIHsKKyAgLy8gTm9uLWxlYXAgeWVhci4KKyAgRVhQRUNUX0VRKGtTZWNvbmRzUGVyRGF5LAorICAgICAgICAgICAgQ3JlYXRlVGltZXN0YW1wKDIwMTUsIDMsIDEpIC0gQ3JlYXRlVGltZXN0YW1wKDIwMTUsIDIsIDI4KSk7CisgIC8vIExlYXAgeWVhci4KKyAgRVhQRUNUX0VRKGtTZWNvbmRzUGVyRGF5LAorICAgICAgICAgICAgQ3JlYXRlVGltZXN0YW1wKDIwMTYsIDMsIDEpIC0gQ3JlYXRlVGltZXN0YW1wKDIwMTYsIDIsIDI5KSk7CisgIC8vIE5vbi1sZWFwIHllYXIuCisgIEVYUEVDVF9FUShrU2Vjb25kc1BlckRheSwKKyAgICAgICAgICAgIENyZWF0ZVRpbWVzdGFtcCgyMTAwLCAzLCAxKSAtIENyZWF0ZVRpbWVzdGFtcCgyMTAwLCAyLCAyOCkpOworICAvLyBMZWFwIHllYXIuCisgIEVYUEVDVF9FUShrU2Vjb25kc1BlckRheSwKKyAgICAgICAgICAgIENyZWF0ZVRpbWVzdGFtcCgyNDAwLCAzLCAxKSAtIENyZWF0ZVRpbWVzdGFtcCgyNDAwLCAyLCAyOSkpOworfQorCitURVNUKERhdGVUaW1lVGVzdCwgU3RyaW5nRm9ybWF0KSB7CisgIERhdGVUaW1lIHN0YXJ0LCBlbmQ7CisgIHN0YXJ0LnllYXIgPSAxOworICBzdGFydC5tb250aCA9IDE7CisgIHN0YXJ0LmRheSA9IDE7CisgIHN0YXJ0LmhvdXIgPSAwOworICBzdGFydC5taW51dGUgPSAwOworICBzdGFydC5zZWNvbmQgPSAwOworICBlbmQueWVhciA9IDk5OTk7CisgIGVuZC5tb250aCA9IDEyOworICBlbmQuZGF5ID0gMzE7CisgIGVuZC5ob3VyID0gMjM7CisgIGVuZC5taW51dGUgPSA1OTsKKyAgZW5kLnNlY29uZCA9IDU5OworICBpbnQ2NCBzdGFydF90aW1lLCBlbmRfdGltZTsKKyAgQVNTRVJUX1RSVUUoRGF0ZVRpbWVUb1NlY29uZHMoc3RhcnQsICZzdGFydF90aW1lKSk7CisgIEFTU0VSVF9UUlVFKERhdGVUaW1lVG9TZWNvbmRzKGVuZCwgJmVuZF90aW1lKSk7CisKKyAgRVhQRUNUX0VRKCIwMDAxLTAxLTAxVDAwOjAwOjAwWiIsIEZvcm1hdFRpbWUoc3RhcnRfdGltZSwgMCkpOworICBFWFBFQ1RfRVEoIjk5OTktMTItMzFUMjM6NTk6NTlaIiwgRm9ybWF0VGltZShlbmRfdGltZSwgMCkpOworCisgIC8vIE1ha2Ugc3VyZSB0aGUgbmFub3NlY29uZHMgcGFydCBpcyBmb3JtYXRlZCBjb3JyZWN0bHkuCisgIEVYUEVDVF9FUSgiMTk3MC0wMS0wMVQwMDowMDowMC4wMTBaIiwgRm9ybWF0VGltZSgwLCAxMDAwMDAwMCkpOworICBFWFBFQ1RfRVEoIjE5NzAtMDEtMDFUMDA6MDA6MDAuMDAwMDEwWiIsIEZvcm1hdFRpbWUoMCwgMTAwMDApKTsKKyAgRVhQRUNUX0VRKCIxOTcwLTAxLTAxVDAwOjAwOjAwLjAwMDAwMDAxMFoiLCBGb3JtYXRUaW1lKDAsIDEwKSk7Cit9CisKK1RFU1QoRGF0ZVRpbWVUZXN0LCBQYXJzZVN0cmluZykgeworICBpbnQ2NCBzZWNvbmRzOworICBpbnQzMiBuYW5vczsKKyAgQVNTRVJUX1RSVUUoUGFyc2VUaW1lKCIwMDAxLTAxLTAxVDAwOjAwOjAwWiIsICZzZWNvbmRzLCAmbmFub3MpKTsKKyAgRVhQRUNUX0VRKCIwMDAxLTAxLTAxVDAwOjAwOjAwWiIsIEZvcm1hdFRpbWUoc2Vjb25kcywgbmFub3MpKTsKKyAgQVNTRVJUX1RSVUUoUGFyc2VUaW1lKCI5OTk5LTEyLTMxVDIzOjU5OjU5Ljk5OTk5OTk5OVoiLCAmc2Vjb25kcywgJm5hbm9zKSk7CisgIEVYUEVDVF9FUSgiOTk5OS0xMi0zMVQyMzo1OTo1OS45OTk5OTk5OTlaIiwgRm9ybWF0VGltZShzZWNvbmRzLCBuYW5vcykpOworCisgIC8vIFRlc3QgdGltZSB6b25lIG9mZnNldHMuCisgIEFTU0VSVF9UUlVFKFBhcnNlVGltZSgiMTk3MC0wMS0wMVQwMDowMDowMC0wODowMCIsICZzZWNvbmRzLCAmbmFub3MpKTsKKyAgRVhQRUNUX0VRKCIxOTcwLTAxLTAxVDA4OjAwOjAwWiIsIEZvcm1hdFRpbWUoc2Vjb25kcywgbmFub3MpKTsKKyAgQVNTRVJUX1RSVUUoUGFyc2VUaW1lKCIxOTcwLTAxLTAxVDAwOjAwOjAwKzA4OjAwIiwgJnNlY29uZHMsICZuYW5vcykpOworICBFWFBFQ1RfRVEoIjE5NjktMTItMzFUMTY6MDA6MDBaIiwgRm9ybWF0VGltZShzZWNvbmRzLCBuYW5vcykpOworCisgIC8vIFRlc3QgbmFub3NlY29uZHMuCisgIEFTU0VSVF9UUlVFKFBhcnNlVGltZSgiMTk3MC0wMS0wMVQwMDowMDowMC4wMVoiLCAmc2Vjb25kcywgJm5hbm9zKSk7CisgIEVYUEVDVF9FUSgiMTk3MC0wMS0wMVQwMDowMDowMC4wMTBaIiwgRm9ybWF0VGltZShzZWNvbmRzLCBuYW5vcykpOworICBBU1NFUlRfVFJVRShQYXJzZVRpbWUoIjE5NzAtMDEtMDFUMDA6MDA6MDAuMDAwMDEtMDg6MDAiLCAmc2Vjb25kcywgJm5hbm9zKSk7CisgIEVYUEVDVF9FUSgiMTk3MC0wMS0wMVQwODowMDowMC4wMDAwMTBaIiwgRm9ybWF0VGltZShzZWNvbmRzLCBuYW5vcykpOworICBBU1NFUlRfVFJVRShQYXJzZVRpbWUoIjE5NzAtMDEtMDFUMDA6MDA6MDAuMDAwMDAwMDErMDg6MDAiLCAmc2Vjb25kcywgJm5hbm9zKSk7CisgIEVYUEVDVF9FUSgiMTk2OS0xMi0zMVQxNjowMDowMC4wMDAwMDAwMTBaIiwgRm9ybWF0VGltZShzZWNvbmRzLCBuYW5vcykpOworICAvLyBGcmFjdGlvbmFsIHBhcnRzIGxlc3MgdGhhbiAxIG5hbm9zZWNvbmQgd2lsbCBiZSBpZ25vcmVkLgorICBBU1NFUlRfVFJVRShQYXJzZVRpbWUoIjE5NzAtMDEtMDFUMDA6MDA6MDAuMDEyMzQ1Njc4OVoiLCAmc2Vjb25kcywgJm5hbm9zKSk7CisgIEVYUEVDVF9FUSgiMTk3MC0wMS0wMVQwMDowMDowMC4wMTIzNDU2NzhaIiwgRm9ybWF0VGltZShzZWNvbmRzLCBuYW5vcykpOworfQorCit9ICAvLyBuYW1lc3BhY2UKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3R5cGVfdHJhaXRzLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3N0dWJzL3R5cGVfdHJhaXRzLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGQ4MTI3ZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvdHlwZV90cmFpdHMuaApAQCAtMCwwICsxLDM2NCBAQAorLy8gQ29weXJpZ2h0IChjKSAyMDA2LCBHb29nbGUgSW5jLgorLy8gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gLS0tLQorLy8gQXV0aG9yOiBNYXR0IEF1c3Rlcm4KKy8vCisvLyBUaGlzIGNvZGUgaXMgY29tcGlsZWQgZGlyZWN0bHkgb24gbWFueSBwbGF0Zm9ybXMsIGluY2x1ZGluZyBjbGllbnQKKy8vIHBsYXRmb3JtcyBsaWtlIFdpbmRvd3MsIE1hYywgYW5kIGVtYmVkZGVkIHN5c3RlbXMuICBCZWZvcmUgbWFraW5nCisvLyBhbnkgY2hhbmdlcyBoZXJlLCBtYWtlIHN1cmUgdGhhdCB5b3UncmUgbm90IGJyZWFraW5nIGFueSBwbGF0Zm9ybXMuCisvLworLy8gRGVmaW5lIGEgc21hbGwgc3Vic2V0IG9mIHRyMSB0eXBlIHRyYWl0cy4gVGhlIHRyYWl0cyB3ZSBkZWZpbmUgYXJlOgorLy8gICBlbmFibGVfaWYKKy8vICAgaXNfaW50ZWdyYWwKKy8vICAgaXNfZmxvYXRpbmdfcG9pbnQKKy8vICAgaXNfcG9pbnRlcgorLy8gICBpc19lbnVtCisvLyAgIGlzX3JlZmVyZW5jZQorLy8gICBpc19wb2QKKy8vICAgaGFzX3RyaXZpYWxfY29uc3RydWN0b3IKKy8vICAgaGFzX3RyaXZpYWxfY29weQorLy8gICBoYXNfdHJpdmlhbF9hc3NpZ24KKy8vICAgaGFzX3RyaXZpYWxfZGVzdHJ1Y3RvcgorLy8gICByZW1vdmVfY29uc3QKKy8vICAgcmVtb3ZlX3ZvbGF0aWxlCisvLyAgIHJlbW92ZV9jdgorLy8gICByZW1vdmVfcmVmZXJlbmNlCisvLyAgIGFkZF9yZWZlcmVuY2UKKy8vICAgcmVtb3ZlX3BvaW50ZXIKKy8vICAgaXNfc2FtZQorLy8gICBpc19jb252ZXJ0aWJsZQorLy8gV2UgY2FuIGFkZCBtb3JlIHR5cGUgdHJhaXRzIGFzIHJlcXVpcmVkLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9UWVBFX1RSQUlUU19IXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfVFlQRV9UUkFJVFNfSF8KKworI2luY2x1ZGUgPGNzdGRkZWY+ICAgICAgICAgICAgICAgICAgLy8gZm9yIE5VTEwKKyNpbmNsdWRlIDx1dGlsaXR5PiAgICAgICAgICAgICAgICAgIC8vIEZvciBwYWlyCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvdGVtcGxhdGVfdXRpbC5oPiAgLy8gRm9yIHRydWVfdHlwZSBhbmQgZmFsc2VfdHlwZQorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW50ZXJuYWwgeworCit0ZW1wbGF0ZTx0eXBlbmFtZSBCLCB0eXBlbmFtZSBEPgorc3RydWN0IGlzX2Jhc2Vfb2YgeworICB0eXBlZGVmIGNoYXIgKCZ5ZXMpWzFdOworICB0eXBlZGVmIGNoYXIgKCZubylbMl07CisKKyAgLy8gQkVHSU4gR09PR0xFIExPQ0FMIE1PRElGSUNBVElPTiAtLSBjaGVjayBpcyBhICNkZWZpbmUgb24gTWFjLgorICAjdW5kZWYgY2hlY2sKKyAgLy8gRU5EIEdPT0dMRSBMT0NBTCBNT0RJRklDQVRJT04KKworICBzdGF0aWMgeWVzIGNoZWNrKGNvbnN0IEIqKTsKKyAgc3RhdGljIG5vIGNoZWNrKGNvbnN0IHZvaWQqKTsKKworICBlbnVtIHsKKyAgICB2YWx1ZSA9IHNpemVvZihjaGVjayhzdGF0aWNfY2FzdDxjb25zdCBEKj4oTlVMTCkpKSA9PSBzaXplb2YoeWVzKSwKKyAgfTsKK307CisKK3RlbXBsYXRlIDxib29sIGNvbmQsIGNsYXNzIFQgPSB2b2lkPiBzdHJ1Y3QgZW5hYmxlX2lmOwordGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCBpc19pbnRlZ3JhbDsKK3RlbXBsYXRlIDxjbGFzcyBUPiBzdHJ1Y3QgaXNfZmxvYXRpbmdfcG9pbnQ7Cit0ZW1wbGF0ZSA8Y2xhc3MgVD4gc3RydWN0IGlzX3BvaW50ZXI7CisvLyBNU1ZDIGNhbid0IGNvbXBpbGUgdGhpcyBjb3JyZWN0bHksIGFuZCBuZWl0aGVyIGNhbiBnY2MgMy4zLjUgKGF0IGxlYXN0KQorI2lmICFkZWZpbmVkKF9NU0NfVkVSKSAmJiAhKGRlZmluZWQoX19HTlVDX18pICYmIF9fR05VQ19fIDw9IDMpCisvLyBpc19lbnVtIHVzZXMgaXNfY29udmVydGlibGUsIHdoaWNoIGlzIG5vdCBhdmFpbGFibGUgb24gTVNWQy4KK3RlbXBsYXRlIDxjbGFzcyBUPiBzdHJ1Y3QgaXNfZW51bTsKKyNlbmRpZgordGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCBpc19yZWZlcmVuY2U7Cit0ZW1wbGF0ZSA8Y2xhc3MgVD4gc3RydWN0IGlzX3BvZDsKK3RlbXBsYXRlIDxjbGFzcyBUPiBzdHJ1Y3QgaGFzX3RyaXZpYWxfY29uc3RydWN0b3I7Cit0ZW1wbGF0ZSA8Y2xhc3MgVD4gc3RydWN0IGhhc190cml2aWFsX2NvcHk7Cit0ZW1wbGF0ZSA8Y2xhc3MgVD4gc3RydWN0IGhhc190cml2aWFsX2Fzc2lnbjsKK3RlbXBsYXRlIDxjbGFzcyBUPiBzdHJ1Y3QgaGFzX3RyaXZpYWxfZGVzdHJ1Y3RvcjsKK3RlbXBsYXRlIDxjbGFzcyBUPiBzdHJ1Y3QgcmVtb3ZlX2NvbnN0OwordGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCByZW1vdmVfdm9sYXRpbGU7Cit0ZW1wbGF0ZSA8Y2xhc3MgVD4gc3RydWN0IHJlbW92ZV9jdjsKK3RlbXBsYXRlIDxjbGFzcyBUPiBzdHJ1Y3QgcmVtb3ZlX3JlZmVyZW5jZTsKK3RlbXBsYXRlIDxjbGFzcyBUPiBzdHJ1Y3QgYWRkX3JlZmVyZW5jZTsKK3RlbXBsYXRlIDxjbGFzcyBUPiBzdHJ1Y3QgcmVtb3ZlX3BvaW50ZXI7Cit0ZW1wbGF0ZSA8Y2xhc3MgVCwgY2xhc3MgVT4gc3RydWN0IGlzX3NhbWU7CisjaWYgIShkZWZpbmVkKF9fR05VQ19fKSAmJiBfX0dOVUNfXyA8PSAzKQordGVtcGxhdGUgPGNsYXNzIEZyb20sIGNsYXNzIFRvPiBzdHJ1Y3QgaXNfY29udmVydGlibGU7CisjZW5kaWYKKworLy8gZW5hYmxlX2lmLCBlcXVpdmFsZW50IHNlbWFudGljcyB0byBjKysxMSBzdGQ6OmVuYWJsZV9pZiwgc3BlY2lmaWNhbGx5OgorLy8gICAiSWYgQiBpcyB0cnVlLCB0aGUgbWVtYmVyIHR5cGVkZWYgdHlwZSBzaGFsbCBlcXVhbCBUOyBvdGhlcndpc2UsIHRoZXJlCisvLyAgICBzaGFsbCBiZSBubyBtZW1iZXIgdHlwZWRlZiB0eXBlLiIKKy8vIFNwZWNpZmllZCBieSAyMC45LjcuNiBbT3RoZXIgdHJhbnNmb3JtYXRpb25zXQorCit0ZW1wbGF0ZTxib29sIGNvbmQsIGNsYXNzIFQ+IHN0cnVjdCBlbmFibGVfaWYgeyB0eXBlZGVmIFQgdHlwZTsgfTsKK3RlbXBsYXRlPGNsYXNzIFQ+IHN0cnVjdCBlbmFibGVfaWY8ZmFsc2UsIFQ+IHt9OworLy8gaXNfaW50ZWdyYWwgaXMgZmFsc2UgZXhjZXB0IGZvciB0aGUgYnVpbHQtaW4gaW50ZWdlciB0eXBlcy4gQQorLy8gY3YtcXVhbGlmaWVkIHR5cGUgaXMgaW50ZWdyYWwgaWYgYW5kIG9ubHkgaWYgdGhlIHVuZGVybHlpbmcgdHlwZSBpcy4KK3RlbXBsYXRlIDxjbGFzcyBUPiBzdHJ1Y3QgaXNfaW50ZWdyYWwgOiBmYWxzZV90eXBlIHsgfTsKK3RlbXBsYXRlPD4gc3RydWN0IGlzX2ludGVncmFsPGJvb2w+IDogdHJ1ZV90eXBlIHsgfTsKK3RlbXBsYXRlPD4gc3RydWN0IGlzX2ludGVncmFsPGNoYXI+IDogdHJ1ZV90eXBlIHsgfTsKK3RlbXBsYXRlPD4gc3RydWN0IGlzX2ludGVncmFsPHVuc2lnbmVkIGNoYXI+IDogdHJ1ZV90eXBlIHsgfTsKK3RlbXBsYXRlPD4gc3RydWN0IGlzX2ludGVncmFsPHNpZ25lZCBjaGFyPiA6IHRydWVfdHlwZSB7IH07CisjaWYgZGVmaW5lZChfTVNDX1ZFUikKKy8vIHdjaGFyX3QgaXMgbm90IGJ5IGRlZmF1bHQgYSBkaXN0aW5jdCB0eXBlIGZyb20gdW5zaWduZWQgc2hvcnQgaW4KKy8vIE1pY3Jvc29mdCBDLgorLy8gU2VlIGh0dHA6Ly9tc2RuMi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvZGg4Y2hlN3MoVlMuODApLmFzcHgKK3RlbXBsYXRlPD4gc3RydWN0IGlzX2ludGVncmFsPF9fd2NoYXJfdD4gOiB0cnVlX3R5cGUgeyB9OworI2Vsc2UKK3RlbXBsYXRlPD4gc3RydWN0IGlzX2ludGVncmFsPHdjaGFyX3Q+IDogdHJ1ZV90eXBlIHsgfTsKKyNlbmRpZgordGVtcGxhdGU8PiBzdHJ1Y3QgaXNfaW50ZWdyYWw8c2hvcnQ+IDogdHJ1ZV90eXBlIHsgfTsKK3RlbXBsYXRlPD4gc3RydWN0IGlzX2ludGVncmFsPHVuc2lnbmVkIHNob3J0PiA6IHRydWVfdHlwZSB7IH07Cit0ZW1wbGF0ZTw+IHN0cnVjdCBpc19pbnRlZ3JhbDxpbnQ+IDogdHJ1ZV90eXBlIHsgfTsKK3RlbXBsYXRlPD4gc3RydWN0IGlzX2ludGVncmFsPHVuc2lnbmVkIGludD4gOiB0cnVlX3R5cGUgeyB9OwordGVtcGxhdGU8PiBzdHJ1Y3QgaXNfaW50ZWdyYWw8bG9uZz4gOiB0cnVlX3R5cGUgeyB9OwordGVtcGxhdGU8PiBzdHJ1Y3QgaXNfaW50ZWdyYWw8dW5zaWduZWQgbG9uZz4gOiB0cnVlX3R5cGUgeyB9OworI2lmZGVmIEhBVkVfTE9OR19MT05HCit0ZW1wbGF0ZTw+IHN0cnVjdCBpc19pbnRlZ3JhbDxsb25nIGxvbmc+IDogdHJ1ZV90eXBlIHsgfTsKK3RlbXBsYXRlPD4gc3RydWN0IGlzX2ludGVncmFsPHVuc2lnbmVkIGxvbmcgbG9uZz4gOiB0cnVlX3R5cGUgeyB9OworI2VuZGlmCit0ZW1wbGF0ZSA8Y2xhc3MgVD4gc3RydWN0IGlzX2ludGVncmFsPGNvbnN0IFQ+IDogaXNfaW50ZWdyYWw8VD4geyB9OwordGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCBpc19pbnRlZ3JhbDx2b2xhdGlsZSBUPiA6IGlzX2ludGVncmFsPFQ+IHsgfTsKK3RlbXBsYXRlIDxjbGFzcyBUPiBzdHJ1Y3QgaXNfaW50ZWdyYWw8Y29uc3Qgdm9sYXRpbGUgVD4gOiBpc19pbnRlZ3JhbDxUPiB7IH07CisKKy8vIGlzX2Zsb2F0aW5nX3BvaW50IGlzIGZhbHNlIGV4Y2VwdCBmb3IgdGhlIGJ1aWx0LWluIGZsb2F0aW5nLXBvaW50IHR5cGVzLgorLy8gQSBjdi1xdWFsaWZpZWQgdHlwZSBpcyBpbnRlZ3JhbCBpZiBhbmQgb25seSBpZiB0aGUgdW5kZXJseWluZyB0eXBlIGlzLgordGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCBpc19mbG9hdGluZ19wb2ludCA6IGZhbHNlX3R5cGUgeyB9OwordGVtcGxhdGU8PiBzdHJ1Y3QgaXNfZmxvYXRpbmdfcG9pbnQ8ZmxvYXQ+IDogdHJ1ZV90eXBlIHsgfTsKK3RlbXBsYXRlPD4gc3RydWN0IGlzX2Zsb2F0aW5nX3BvaW50PGRvdWJsZT4gOiB0cnVlX3R5cGUgeyB9OwordGVtcGxhdGU8PiBzdHJ1Y3QgaXNfZmxvYXRpbmdfcG9pbnQ8bG9uZyBkb3VibGU+IDogdHJ1ZV90eXBlIHsgfTsKK3RlbXBsYXRlIDxjbGFzcyBUPiBzdHJ1Y3QgaXNfZmxvYXRpbmdfcG9pbnQ8Y29uc3QgVD4KKyAgICA6IGlzX2Zsb2F0aW5nX3BvaW50PFQ+IHsgfTsKK3RlbXBsYXRlIDxjbGFzcyBUPiBzdHJ1Y3QgaXNfZmxvYXRpbmdfcG9pbnQ8dm9sYXRpbGUgVD4KKyAgICA6IGlzX2Zsb2F0aW5nX3BvaW50PFQ+IHsgfTsKK3RlbXBsYXRlIDxjbGFzcyBUPiBzdHJ1Y3QgaXNfZmxvYXRpbmdfcG9pbnQ8Y29uc3Qgdm9sYXRpbGUgVD4KKyAgICA6IGlzX2Zsb2F0aW5nX3BvaW50PFQ+IHsgfTsKKworLy8gaXNfcG9pbnRlciBpcyBmYWxzZSBleGNlcHQgZm9yIHBvaW50ZXIgdHlwZXMuIEEgY3YtcXVhbGlmaWVkIHR5cGUgKGUuZy4KKy8vICJpbnQqIGNvbnN0IiwgYXMgb3Bwb3NlZCB0byAiaW50IGNvbnN0KiIpIGlzIGN2LXF1YWxpZmllZCBpZiBhbmQgb25seSBpZgorLy8gdGhlIHVuZGVybHlpbmcgdHlwZSBpcy4KK3RlbXBsYXRlIDxjbGFzcyBUPiBzdHJ1Y3QgaXNfcG9pbnRlciA6IGZhbHNlX3R5cGUgeyB9OwordGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCBpc19wb2ludGVyPFQqPiA6IHRydWVfdHlwZSB7IH07Cit0ZW1wbGF0ZSA8Y2xhc3MgVD4gc3RydWN0IGlzX3BvaW50ZXI8Y29uc3QgVD4gOiBpc19wb2ludGVyPFQ+IHsgfTsKK3RlbXBsYXRlIDxjbGFzcyBUPiBzdHJ1Y3QgaXNfcG9pbnRlcjx2b2xhdGlsZSBUPiA6IGlzX3BvaW50ZXI8VD4geyB9OwordGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCBpc19wb2ludGVyPGNvbnN0IHZvbGF0aWxlIFQ+IDogaXNfcG9pbnRlcjxUPiB7IH07CisKKyNpZiAhZGVmaW5lZChfTVNDX1ZFUikgJiYgIShkZWZpbmVkKF9fR05VQ19fKSAmJiBfX0dOVUNfXyA8PSAzKQorCituYW1lc3BhY2UgdHlwZV90cmFpdHNfaW50ZXJuYWwgeworCit0ZW1wbGF0ZSA8Y2xhc3MgVD4gc3RydWN0IGlzX2NsYXNzX29yX3VuaW9uIHsKKyAgdGVtcGxhdGUgPGNsYXNzIFU+IHN0YXRpYyBzbWFsbF8gdGVzdGVyKHZvaWQgKFU6OiopKCkpOworICB0ZW1wbGF0ZSA8Y2xhc3MgVT4gc3RhdGljIGJpZ18gdGVzdGVyKC4uLik7CisgIHN0YXRpYyBjb25zdCBib29sIHZhbHVlID0gc2l6ZW9mKHRlc3RlcjxUPigwKSkgPT0gc2l6ZW9mKHNtYWxsXyk7Cit9OworCisvLyBpc19jb252ZXJ0aWJsZSBjaG9rZXMgaWYgdGhlIGZpcnN0IGFyZ3VtZW50IGlzIGFuIGFycmF5LiBUaGF0J3Mgd2h5CisvLyB3ZSB1c2UgYWRkX3JlZmVyZW5jZSBoZXJlLgordGVtcGxhdGUgPGJvb2wgTm90VW51bSwgY2xhc3MgVD4gc3RydWN0IGlzX2VudW1faW1wbAorICAgIDogaXNfY29udmVydGlibGU8dHlwZW5hbWUgYWRkX3JlZmVyZW5jZTxUPjo6dHlwZSwgaW50PiB7IH07CisKK3RlbXBsYXRlIDxjbGFzcyBUPiBzdHJ1Y3QgaXNfZW51bV9pbXBsPHRydWUsIFQ+IDogZmFsc2VfdHlwZSB7IH07CisKK30gIC8vIG5hbWVzcGFjZSB0eXBlX3RyYWl0c19pbnRlcm5hbAorCisvLyBTcGVjaWZpZWQgYnkgVFIxIFs0LjUuMV0gcHJpbWFyeSB0eXBlIGNhdGVnb3JpZXMuCisKKy8vIEltcGxlbWVudGF0aW9uIG5vdGU6CisvLworLy8gRWFjaCB0eXBlIGlzIGVpdGhlciB2b2lkLCBpbnRlZ3JhbCwgZmxvYXRpbmcgcG9pbnQsIGFycmF5LCBwb2ludGVyLAorLy8gcmVmZXJlbmNlLCBtZW1iZXIgb2JqZWN0IHBvaW50ZXIsIG1lbWJlciBmdW5jdGlvbiBwb2ludGVyLCBlbnVtLAorLy8gdW5pb24gb3IgY2xhc3MuIE91dCBvZiB0aGVzZSwgb25seSBpbnRlZ3JhbCwgZmxvYXRpbmcgcG9pbnQsIHJlZmVyZW5jZSwKKy8vIGNsYXNzIGFuZCBlbnVtIHR5cGVzIGFyZSBwb3RlbnRpYWxseSBjb252ZXJ0aWJsZSB0byBpbnQuIFRoZXJlZm9yZSwKKy8vIGlmIGEgdHlwZSBpcyBub3QgYSByZWZlcmVuY2UsIGludGVncmFsLCBmbG9hdGluZyBwb2ludCBvciBjbGFzcyBhbmQKKy8vIGlzIGNvbnZlcnRpYmxlIHRvIGludCwgaXQncyBhIGVudW0uIEFkZGluZyBjdi1xdWFsaWZpY2F0aW9uIHRvIGEgdHlwZQorLy8gZG9lcyBub3QgY2hhbmdlIHdoZXRoZXIgaXQncyBhbiBlbnVtLgorLy8KKy8vIElzLWNvbnZlcnRpYmxlLXRvLWludCBjaGVjayBpcyBkb25lIG9ubHkgaWYgYWxsIG90aGVyIGNoZWNrcyBwYXNzLAorLy8gYmVjYXVzZSBpdCBjYW4ndCBiZSB1c2VkIHdpdGggc29tZSB0eXBlcyAoZS5nLiB2b2lkIG9yIGNsYXNzZXMgd2l0aAorLy8gaW5hY2Nlc3NpYmxlIGNvbnZlcnNpb24gb3BlcmF0b3JzKS4KK3RlbXBsYXRlIDxjbGFzcyBUPiBzdHJ1Y3QgaXNfZW51bQorICAgIDogdHlwZV90cmFpdHNfaW50ZXJuYWw6OmlzX2VudW1faW1wbDwKKyAgICAgICAgICBpc19zYW1lPFQsIHZvaWQ+Ojp2YWx1ZSB8fAorICAgICAgICAgICAgICBpc19pbnRlZ3JhbDxUPjo6dmFsdWUgfHwKKyAgICAgICAgICAgICAgaXNfZmxvYXRpbmdfcG9pbnQ8VD46OnZhbHVlIHx8CisgICAgICAgICAgICAgIGlzX3JlZmVyZW5jZTxUPjo6dmFsdWUgfHwKKyAgICAgICAgICAgICAgdHlwZV90cmFpdHNfaW50ZXJuYWw6OmlzX2NsYXNzX29yX3VuaW9uPFQ+Ojp2YWx1ZSwKKyAgICAgICAgICBUPiB7IH07CisKK3RlbXBsYXRlIDxjbGFzcyBUPiBzdHJ1Y3QgaXNfZW51bTxjb25zdCBUPiA6IGlzX2VudW08VD4geyB9OwordGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCBpc19lbnVtPHZvbGF0aWxlIFQ+IDogaXNfZW51bTxUPiB7IH07Cit0ZW1wbGF0ZSA8Y2xhc3MgVD4gc3RydWN0IGlzX2VudW08Y29uc3Qgdm9sYXRpbGUgVD4gOiBpc19lbnVtPFQ+IHsgfTsKKworI2VuZGlmCisKKy8vIGlzX3JlZmVyZW5jZSBpcyBmYWxzZSBleGNlcHQgZm9yIHJlZmVyZW5jZSB0eXBlcy4KK3RlbXBsYXRlPHR5cGVuYW1lIFQ+IHN0cnVjdCBpc19yZWZlcmVuY2UgOiBmYWxzZV90eXBlIHt9OwordGVtcGxhdGU8dHlwZW5hbWUgVD4gc3RydWN0IGlzX3JlZmVyZW5jZTxUJj4gOiB0cnVlX3R5cGUge307CisKKworLy8gV2UgY2FuJ3QgZ2V0IGlzX3BvZCByaWdodCB3aXRob3V0IGNvbXBpbGVyIGhlbHAsIHNvIGZhaWwgY29uc2VydmF0aXZlbHkuCisvLyBXZSB3aWxsIGFzc3VtZSBpdCdzIGZhbHNlIGV4Y2VwdCBmb3IgYXJpdGhtZXRpYyB0eXBlcywgZW51bWVyYXRpb25zLAorLy8gcG9pbnRlcnMgYW5kIGN2LXF1YWxpZmllZCB2ZXJzaW9ucyB0aGVyZW9mLiBOb3RlIHRoYXQgc3RkOjpwYWlyPFQsVT4KKy8vIGlzIG5vdCBhIFBPRCBldmVuIGlmIFQgYW5kIFUgYXJlIFBPRHMuCit0ZW1wbGF0ZSA8Y2xhc3MgVD4gc3RydWN0IGlzX3BvZAorIDogaW50ZWdyYWxfY29uc3RhbnQ8Ym9vbCwgKGlzX2ludGVncmFsPFQ+Ojp2YWx1ZSB8fAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzX2Zsb2F0aW5nX3BvaW50PFQ+Ojp2YWx1ZSB8fAorI2lmICFkZWZpbmVkKF9NU0NfVkVSKSAmJiAhKGRlZmluZWQoX19HTlVDX18pICYmIF9fR05VQ19fIDw9IDMpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaXNfZW51bSBpcyBub3QgYXZhaWxhYmxlIG9uIE1TVkMuCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNfZW51bTxUPjo6dmFsdWUgfHwKKyNlbmRpZgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzX3BvaW50ZXI8VD46OnZhbHVlKT4geyB9OwordGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCBpc19wb2Q8Y29uc3QgVD4gOiBpc19wb2Q8VD4geyB9OwordGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCBpc19wb2Q8dm9sYXRpbGUgVD4gOiBpc19wb2Q8VD4geyB9OwordGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCBpc19wb2Q8Y29uc3Qgdm9sYXRpbGUgVD4gOiBpc19wb2Q8VD4geyB9OworCisKKy8vIFdlIGNhbid0IGdldCBoYXNfdHJpdmlhbF9jb25zdHJ1Y3RvciByaWdodCB3aXRob3V0IGNvbXBpbGVyIGhlbHAsIHNvCisvLyBmYWlsIGNvbnNlcnZhdGl2ZWx5LiBXZSB3aWxsIGFzc3VtZSBpdCdzIGZhbHNlIGV4Y2VwdCBmb3I6ICgxKSB0eXBlcworLy8gZm9yIHdoaWNoIGlzX3BvZCBpcyB0cnVlLiAoMikgc3RkOjpwYWlyIG9mIHR5cGVzIHdpdGggdHJpdmlhbAorLy8gY29uc3RydWN0b3JzLiAoMykgYXJyYXkgb2YgYSB0eXBlIHdpdGggYSB0cml2aWFsIGNvbnN0cnVjdG9yLgorLy8gKDQpIGNvbnN0IHZlcnNpb25zIHRoZXJlb2YuCit0ZW1wbGF0ZSA8Y2xhc3MgVD4gc3RydWN0IGhhc190cml2aWFsX2NvbnN0cnVjdG9yIDogaXNfcG9kPFQ+IHsgfTsKK3RlbXBsYXRlIDxjbGFzcyBULCBjbGFzcyBVPiBzdHJ1Y3QgaGFzX3RyaXZpYWxfY29uc3RydWN0b3I8c3RkOjpwYWlyPFQsIFU+ID4KKyAgOiBpbnRlZ3JhbF9jb25zdGFudDxib29sLAorICAgICAgICAgICAgICAgICAgICAgIChoYXNfdHJpdmlhbF9jb25zdHJ1Y3RvcjxUPjo6dmFsdWUgJiYKKyAgICAgICAgICAgICAgICAgICAgICAgaGFzX3RyaXZpYWxfY29uc3RydWN0b3I8VT46OnZhbHVlKT4geyB9OwordGVtcGxhdGUgPGNsYXNzIEEsIGludCBOPiBzdHJ1Y3QgaGFzX3RyaXZpYWxfY29uc3RydWN0b3I8QVtOXT4KKyAgOiBoYXNfdHJpdmlhbF9jb25zdHJ1Y3RvcjxBPiB7IH07Cit0ZW1wbGF0ZSA8Y2xhc3MgVD4gc3RydWN0IGhhc190cml2aWFsX2NvbnN0cnVjdG9yPGNvbnN0IFQ+CisgIDogaGFzX3RyaXZpYWxfY29uc3RydWN0b3I8VD4geyB9OworCisvLyBXZSBjYW4ndCBnZXQgaGFzX3RyaXZpYWxfY29weSByaWdodCB3aXRob3V0IGNvbXBpbGVyIGhlbHAsIHNvIGZhaWwKKy8vIGNvbnNlcnZhdGl2ZWx5LiBXZSB3aWxsIGFzc3VtZSBpdCdzIGZhbHNlIGV4Y2VwdCBmb3I6ICgxKSB0eXBlcworLy8gZm9yIHdoaWNoIGlzX3BvZCBpcyB0cnVlLiAoMikgc3RkOjpwYWlyIG9mIHR5cGVzIHdpdGggdHJpdmlhbCBjb3B5CisvLyBjb25zdHJ1Y3RvcnMuICgzKSBhcnJheSBvZiBhIHR5cGUgd2l0aCBhIHRyaXZpYWwgY29weSBjb25zdHJ1Y3Rvci4KKy8vICg0KSBjb25zdCB2ZXJzaW9ucyB0aGVyZW9mLgordGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCBoYXNfdHJpdmlhbF9jb3B5IDogaXNfcG9kPFQ+IHsgfTsKK3RlbXBsYXRlIDxjbGFzcyBULCBjbGFzcyBVPiBzdHJ1Y3QgaGFzX3RyaXZpYWxfY29weTxzdGQ6OnBhaXI8VCwgVT4gPgorICA6IGludGVncmFsX2NvbnN0YW50PGJvb2wsCisgICAgICAgICAgICAgICAgICAgICAgKGhhc190cml2aWFsX2NvcHk8VD46OnZhbHVlICYmCisgICAgICAgICAgICAgICAgICAgICAgIGhhc190cml2aWFsX2NvcHk8VT46OnZhbHVlKT4geyB9OwordGVtcGxhdGUgPGNsYXNzIEEsIGludCBOPiBzdHJ1Y3QgaGFzX3RyaXZpYWxfY29weTxBW05dPgorICA6IGhhc190cml2aWFsX2NvcHk8QT4geyB9OwordGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCBoYXNfdHJpdmlhbF9jb3B5PGNvbnN0IFQ+IDogaGFzX3RyaXZpYWxfY29weTxUPiB7IH07CisKKy8vIFdlIGNhbid0IGdldCBoYXNfdHJpdmlhbF9hc3NpZ24gcmlnaHQgd2l0aG91dCBjb21waWxlciBoZWxwLCBzbyBmYWlsCisvLyBjb25zZXJ2YXRpdmVseS4gV2Ugd2lsbCBhc3N1bWUgaXQncyBmYWxzZSBleGNlcHQgZm9yOiAoMSkgdHlwZXMKKy8vIGZvciB3aGljaCBpc19wb2QgaXMgdHJ1ZS4gKDIpIHN0ZDo6cGFpciBvZiB0eXBlcyB3aXRoIHRyaXZpYWwgY29weQorLy8gY29uc3RydWN0b3JzLiAoMykgYXJyYXkgb2YgYSB0eXBlIHdpdGggYSB0cml2aWFsIGFzc2lnbiBjb25zdHJ1Y3Rvci4KK3RlbXBsYXRlIDxjbGFzcyBUPiBzdHJ1Y3QgaGFzX3RyaXZpYWxfYXNzaWduIDogaXNfcG9kPFQ+IHsgfTsKK3RlbXBsYXRlIDxjbGFzcyBULCBjbGFzcyBVPiBzdHJ1Y3QgaGFzX3RyaXZpYWxfYXNzaWduPHN0ZDo6cGFpcjxULCBVPiA+CisgIDogaW50ZWdyYWxfY29uc3RhbnQ8Ym9vbCwKKyAgICAgICAgICAgICAgICAgICAgICAoaGFzX3RyaXZpYWxfYXNzaWduPFQ+Ojp2YWx1ZSAmJgorICAgICAgICAgICAgICAgICAgICAgICBoYXNfdHJpdmlhbF9hc3NpZ248VT46OnZhbHVlKT4geyB9OwordGVtcGxhdGUgPGNsYXNzIEEsIGludCBOPiBzdHJ1Y3QgaGFzX3RyaXZpYWxfYXNzaWduPEFbTl0+CisgIDogaGFzX3RyaXZpYWxfYXNzaWduPEE+IHsgfTsKKworLy8gV2UgY2FuJ3QgZ2V0IGhhc190cml2aWFsX2Rlc3RydWN0b3IgcmlnaHQgd2l0aG91dCBjb21waWxlciBoZWxwLCBzbworLy8gZmFpbCBjb25zZXJ2YXRpdmVseS4gV2Ugd2lsbCBhc3N1bWUgaXQncyBmYWxzZSBleGNlcHQgZm9yOiAoMSkgdHlwZXMKKy8vIGZvciB3aGljaCBpc19wb2QgaXMgdHJ1ZS4gKDIpIHN0ZDo6cGFpciBvZiB0eXBlcyB3aXRoIHRyaXZpYWwKKy8vIGRlc3RydWN0b3JzLiAoMykgYXJyYXkgb2YgYSB0eXBlIHdpdGggYSB0cml2aWFsIGRlc3RydWN0b3IuCisvLyAoNCkgY29uc3QgdmVyc2lvbnMgdGhlcmVvZi4KK3RlbXBsYXRlIDxjbGFzcyBUPiBzdHJ1Y3QgaGFzX3RyaXZpYWxfZGVzdHJ1Y3RvciA6IGlzX3BvZDxUPiB7IH07Cit0ZW1wbGF0ZSA8Y2xhc3MgVCwgY2xhc3MgVT4gc3RydWN0IGhhc190cml2aWFsX2Rlc3RydWN0b3I8c3RkOjpwYWlyPFQsIFU+ID4KKyAgOiBpbnRlZ3JhbF9jb25zdGFudDxib29sLAorICAgICAgICAgICAgICAgICAgICAgIChoYXNfdHJpdmlhbF9kZXN0cnVjdG9yPFQ+Ojp2YWx1ZSAmJgorICAgICAgICAgICAgICAgICAgICAgICBoYXNfdHJpdmlhbF9kZXN0cnVjdG9yPFU+Ojp2YWx1ZSk+IHsgfTsKK3RlbXBsYXRlIDxjbGFzcyBBLCBpbnQgTj4gc3RydWN0IGhhc190cml2aWFsX2Rlc3RydWN0b3I8QVtOXT4KKyAgOiBoYXNfdHJpdmlhbF9kZXN0cnVjdG9yPEE+IHsgfTsKK3RlbXBsYXRlIDxjbGFzcyBUPiBzdHJ1Y3QgaGFzX3RyaXZpYWxfZGVzdHJ1Y3Rvcjxjb25zdCBUPgorICA6IGhhc190cml2aWFsX2Rlc3RydWN0b3I8VD4geyB9OworCisvLyBTcGVjaWZpZWQgYnkgVFIxIFs0LjcuMV0KK3RlbXBsYXRlPHR5cGVuYW1lIFQ+IHN0cnVjdCByZW1vdmVfY29uc3QgeyB0eXBlZGVmIFQgdHlwZTsgfTsKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+IHN0cnVjdCByZW1vdmVfY29uc3Q8VCBjb25zdD4geyB0eXBlZGVmIFQgdHlwZTsgfTsKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+IHN0cnVjdCByZW1vdmVfdm9sYXRpbGUgeyB0eXBlZGVmIFQgdHlwZTsgfTsKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+IHN0cnVjdCByZW1vdmVfdm9sYXRpbGU8VCB2b2xhdGlsZT4geyB0eXBlZGVmIFQgdHlwZTsgfTsKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+IHN0cnVjdCByZW1vdmVfY3YgeworICB0eXBlZGVmIHR5cGVuYW1lIHJlbW92ZV9jb25zdDx0eXBlbmFtZSByZW1vdmVfdm9sYXRpbGU8VD46OnR5cGU+Ojp0eXBlIHR5cGU7Cit9OworCisKKy8vIFNwZWNpZmllZCBieSBUUjEgWzQuNy4yXSBSZWZlcmVuY2UgbW9kaWZpY2F0aW9ucy4KK3RlbXBsYXRlPHR5cGVuYW1lIFQ+IHN0cnVjdCByZW1vdmVfcmVmZXJlbmNlIHsgdHlwZWRlZiBUIHR5cGU7IH07Cit0ZW1wbGF0ZTx0eXBlbmFtZSBUPiBzdHJ1Y3QgcmVtb3ZlX3JlZmVyZW5jZTxUJj4geyB0eXBlZGVmIFQgdHlwZTsgfTsKKwordGVtcGxhdGUgPHR5cGVuYW1lIFQ+IHN0cnVjdCBhZGRfcmVmZXJlbmNlIHsgdHlwZWRlZiBUJiB0eXBlOyB9OwordGVtcGxhdGUgPHR5cGVuYW1lIFQ+IHN0cnVjdCBhZGRfcmVmZXJlbmNlPFQmPiB7IHR5cGVkZWYgVCYgdHlwZTsgfTsKKworLy8gU3BlY2lmaWVkIGJ5IFRSMSBbNC43LjRdIFBvaW50ZXIgbW9kaWZpY2F0aW9ucy4KK3RlbXBsYXRlPHR5cGVuYW1lIFQ+IHN0cnVjdCByZW1vdmVfcG9pbnRlciB7IHR5cGVkZWYgVCB0eXBlOyB9OwordGVtcGxhdGU8dHlwZW5hbWUgVD4gc3RydWN0IHJlbW92ZV9wb2ludGVyPFQqPiB7IHR5cGVkZWYgVCB0eXBlOyB9OwordGVtcGxhdGU8dHlwZW5hbWUgVD4gc3RydWN0IHJlbW92ZV9wb2ludGVyPFQqIGNvbnN0PiB7IHR5cGVkZWYgVCB0eXBlOyB9OwordGVtcGxhdGU8dHlwZW5hbWUgVD4gc3RydWN0IHJlbW92ZV9wb2ludGVyPFQqIHZvbGF0aWxlPiB7IHR5cGVkZWYgVCB0eXBlOyB9OwordGVtcGxhdGU8dHlwZW5hbWUgVD4gc3RydWN0IHJlbW92ZV9wb2ludGVyPFQqIGNvbnN0IHZvbGF0aWxlPiB7CisgIHR5cGVkZWYgVCB0eXBlOyB9OworCisvLyBTcGVjaWZpZWQgYnkgVFIxIFs0LjZdIFJlbGF0aW9uc2hpcHMgYmV0d2VlbiB0eXBlcwordGVtcGxhdGU8dHlwZW5hbWUgVCwgdHlwZW5hbWUgVT4gc3RydWN0IGlzX3NhbWUgOiBwdWJsaWMgZmFsc2VfdHlwZSB7IH07Cit0ZW1wbGF0ZTx0eXBlbmFtZSBUPiBzdHJ1Y3QgaXNfc2FtZTxULCBUPiA6IHB1YmxpYyB0cnVlX3R5cGUgeyB9OworCisvLyBTcGVjaWZpZWQgYnkgVFIxIFs0LjZdIFJlbGF0aW9uc2hpcHMgYmV0d2VlbiB0eXBlcworI2lmICEoZGVmaW5lZChfX0dOVUNfXykgJiYgX19HTlVDX18gPD0gMykKK25hbWVzcGFjZSB0eXBlX3RyYWl0c19pbnRlcm5hbCB7CisKKy8vIFRoaXMgY2xhc3MgaXMgYW4gaW1wbGVtZW50YXRpb24gZGV0YWlsIGZvciBpc19jb252ZXJ0aWJsZSwgYW5kIHlvdQorLy8gZG9uJ3QgbmVlZCB0byBrbm93IGhvdyBpdCB3b3JrcyB0byB1c2UgaXNfY29udmVydGlibGUuIEZvciB0aG9zZQorLy8gd2hvIGNhcmU6IHdlIGRlY2xhcmUgdHdvIGRpZmZlcmVudCBmdW5jdGlvbnMsIG9uZSB3aG9zZSBhcmd1bWVudCBpcworLy8gb2YgdHlwZSBUbyBhbmQgb25lIHdpdGggYSB2YXJpYWRpYyBhcmd1bWVudCBsaXN0LiBXZSBnaXZlIHRoZW0KKy8vIHJldHVybiB0eXBlcyBvZiBkaWZmZXJlbnQgc2l6ZSwgc28gd2UgY2FuIHVzZSBzaXplb2YgdG8gdHJpY2sgdGhlCisvLyBjb21waWxlciBpbnRvIHRlbGxpbmcgdXMgd2hpY2ggZnVuY3Rpb24gaXQgd291bGQgaGF2ZSBjaG9zZW4gaWYgd2UKKy8vIGhhZCBjYWxsZWQgaXQgd2l0aCBhbiBhcmd1bWVudCBvZiB0eXBlIEZyb20uICBTZWUgQWxleGFuZHJlc2N1J3MKKy8vIF9Nb2Rlcm4gQysrIERlc2lnbl8gZm9yIG1vcmUgZGV0YWlscyBvbiB0aGlzIHNvcnQgb2YgdHJpY2suCisKK3RlbXBsYXRlIDx0eXBlbmFtZSBGcm9tLCB0eXBlbmFtZSBUbz4KK3N0cnVjdCBDb252ZXJ0SGVscGVyIHsKKyAgc3RhdGljIHNtYWxsXyBUZXN0KFRvKTsKKyAgc3RhdGljIGJpZ18gVGVzdCguLi4pOworICBzdGF0aWMgRnJvbSBDcmVhdGUoKTsKKyAgZW51bSB7CisgICAgdmFsdWUgPSBzaXplb2YoVGVzdChDcmVhdGUoKSkpID09IHNpemVvZihzbWFsbF8pCisgIH07Cit9OworfSAgLy8gbmFtZXNwYWNlIHR5cGVfdHJhaXRzX2ludGVybmFsCisKKy8vIEluaGVyaXRzIGZyb20gdHJ1ZV90eXBlIGlmIEZyb20gaXMgY29udmVydGlibGUgdG8gVG8sIGZhbHNlX3R5cGUgb3RoZXJ3aXNlLgordGVtcGxhdGUgPHR5cGVuYW1lIEZyb20sIHR5cGVuYW1lIFRvPgorc3RydWN0IGlzX2NvbnZlcnRpYmxlCisgICAgOiBpbnRlZ3JhbF9jb25zdGFudDxib29sLAorICAgICAgICAgICAgICAgICAgICAgICAgdHlwZV90cmFpdHNfaW50ZXJuYWw6OkNvbnZlcnRIZWxwZXI8RnJvbSwgVG8+Ojp2YWx1ZT4geworfTsKKyNlbmRpZgorCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9UWVBFX1RSQUlUU19IXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy90eXBlX3RyYWl0c191bml0dGVzdC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvdHlwZV90cmFpdHNfdW5pdHRlc3QuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDljMTBhYwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvc3R1YnMvdHlwZV90cmFpdHNfdW5pdHRlc3QuY2MKQEAgLTAsMCArMSw2MzEgQEAKKy8vIENvcHlyaWdodCAoYykgMjAwNiwgR29vZ2xlIEluYy4KKy8vIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIC0tLS0KKy8vIEF1dGhvcjogTWF0dCBBdXN0ZXJuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvdHlwZV90cmFpdHMuaD4KKworI2luY2x1ZGUgPHN0ZGxpYi5oPiAgIC8vIGZvciBleGl0KCkKKyNpbmNsdWRlIDxzdGRpby5oPgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDx2ZWN0b3I+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0Lmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKwordHlwZWRlZiBpbnQgaW50MzI7CisvLyBJQk0gQUlYIHR5cGVkZWZzIGBpbnQ2NGAgaW4gYHN5cy9pbnR0eXBlcy5oYCwgaW5jbHVkZWQgdHJhbnNpdGl2ZWx5IGFib3ZlLgorI2lmbmRlZiBfQUlYCit0eXBlZGVmIGxvbmcgaW50NjQ7CisjZW5kaWYKKwordXNpbmcgc3RkOjpzdHJpbmc7Cit1c2luZyBzdGQ6OnZlY3RvcjsKK3VzaW5nIHN0ZDo6cGFpcjsKKworCisvLyBUaGlzIGFzc2VydGlvbiBwcm9kdWNlcyBlcnJvcnMgbGlrZSAiZXJyb3I6IGludmFsaWQgdXNlIG9mCisvLyBpbmNvbXBsZXRlIHR5cGUgJ3N0cnVjdCA8dW5uYW1lZD46OkFzc2VydFR5cGVzRXE8Y29uc3QgaW50LCBpbnQ+JyIKKy8vIHdoZW4gaXQgZmFpbHMuCit0ZW1wbGF0ZTx0eXBlbmFtZSBULCB0eXBlbmFtZSBVPiBzdHJ1Y3QgQXNzZXJ0VHlwZXNFcTsKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+IHN0cnVjdCBBc3NlcnRUeXBlc0VxPFQsIFQ+IHt9OworI2RlZmluZSBDT01QSUxFX0FTU0VSVF9UWVBFU19FUShULCBVKSBzdGF0aWNfY2FzdDx2b2lkPihBc3NlcnRUeXBlc0VxPFQsIFU+KCkpCisKKy8vIEEgdXNlci1kZWZpbmVkIFBPRCB0eXBlLgorc3RydWN0IEEgeworICBpbnQgbl87Cit9OworCisvLyBBIHVzZXItZGVmaW5lZCBub24tUE9EIHR5cGUgd2l0aCBhIHRyaXZpYWwgY29weSBjb25zdHJ1Y3Rvci4KK2NsYXNzIEIgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgQihpbnQgbikgOiBuXyhuKSB7IH0KKyBwcml2YXRlOgorICBpbnQgbl87Cit9OworCisvLyBBbm90aGVyIHVzZXItZGVmaW5lZCBub24tUE9EIHR5cGUgd2l0aCBhIHRyaXZpYWwgY29weSBjb25zdHJ1Y3Rvci4KKy8vIFdlIHdpbGwgZXhwbGljaXRseSBkZWNsYXJlIEMgdG8gaGF2ZSBhIHRyaXZpYWwgY29weSBjb25zdHJ1Y3RvcgorLy8gYnkgc3BlY2lhbGl6aW5nIGhhc190cml2aWFsX2NvcHkuCitjbGFzcyBDIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IEMoaW50IG4pIDogbl8obikgeyB9CisgcHJpdmF0ZToKKyAgaW50IG5fOworfTsKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKK3RlbXBsYXRlPD4gc3RydWN0IGhhc190cml2aWFsX2NvcHk8Qz4gOiB0cnVlX3R5cGUgeyB9OworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworLy8gQW5vdGhlciB1c2VyLWRlZmluZWQgbm9uLVBPRCB0eXBlIHdpdGggYSB0cml2aWFsIGFzc2lnbm1lbnQgb3BlcmF0b3IuCisvLyBXZSB3aWxsIGV4cGxpY2l0bHkgZGVjbGFyZSBDIHRvIGhhdmUgYSB0cml2aWFsIGFzc2lnbm1lbnQgb3BlcmF0b3IKKy8vIGJ5IHNwZWNpYWxpemluZyBoYXNfdHJpdmlhbF9hc3NpZ24uCitjbGFzcyBEIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IEQoaW50IG4pIDogbl8obikgeyB9CisgcHJpdmF0ZToKKyAgaW50IG5fOworfTsKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKK3RlbXBsYXRlPD4gc3RydWN0IGhhc190cml2aWFsX2Fzc2lnbjxEPiA6IHRydWVfdHlwZSB7IH07Cit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisvLyBBbm90aGVyIHVzZXItZGVmaW5lZCBub24tUE9EIHR5cGUgd2l0aCBhIHRyaXZpYWwgY29uc3RydWN0b3IuCisvLyBXZSB3aWxsIGV4cGxpY2l0bHkgZGVjbGFyZSBFIHRvIGhhdmUgYSB0cml2aWFsIGNvbnN0cnVjdG9yCisvLyBieSBzcGVjaWFsaXppbmcgaGFzX3RyaXZpYWxfY29uc3RydWN0b3IuCitjbGFzcyBFIHsKKyBwdWJsaWM6CisgIGludCBuXzsKK307CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7Cit0ZW1wbGF0ZTw+IHN0cnVjdCBoYXNfdHJpdmlhbF9jb25zdHJ1Y3RvcjxFPiA6IHRydWVfdHlwZSB7IH07Cit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisvLyBBbm90aGVyIHVzZXItZGVmaW5lZCBub24tUE9EIHR5cGUgd2l0aCBhIHRyaXZpYWwgZGVzdHJ1Y3Rvci4KKy8vIFdlIHdpbGwgZXhwbGljaXRseSBkZWNsYXJlIEUgdG8gaGF2ZSBhIHRyaXZpYWwgZGVzdHJ1Y3RvcgorLy8gYnkgc3BlY2lhbGl6aW5nIGhhc190cml2aWFsX2Rlc3RydWN0b3IuCitjbGFzcyBGIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IEYoaW50IG4pIDogbl8obikgeyB9CisgcHJpdmF0ZToKKyAgaW50IG5fOworfTsKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKK3RlbXBsYXRlPD4gc3RydWN0IGhhc190cml2aWFsX2Rlc3RydWN0b3I8Rj4gOiB0cnVlX3R5cGUgeyB9OworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKworZW51bSBHIHt9OworCit1bmlvbiBIIHt9OworCitjbGFzcyBJIHsKKyBwdWJsaWM6CisgIG9wZXJhdG9yIGludCgpIGNvbnN0OworfTsKKworY2xhc3MgSiB7CisgcHJpdmF0ZToKKyAgb3BlcmF0b3IgaW50KCkgY29uc3Q7Cit9OworCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW50ZXJuYWwgeworbmFtZXNwYWNlIHsKKworLy8gQSBiYXNlIGNsYXNzIGFuZCBhIGRlcml2ZWQgY2xhc3MgdGhhdCBpbmhlcml0cyBmcm9tIGl0LCB1c2VkIGZvcgorLy8gdGVzdGluZyBjb252ZXJzaW9uIHR5cGUgdHJhaXRzLgorY2xhc3MgQmFzZSB7CisgcHVibGljOgorICB2aXJ0dWFsIH5CYXNlKCkgeyB9Cit9OworCitjbGFzcyBEZXJpdmVkIDogcHVibGljIEJhc2UgeworfTsKKworVEVTVChUeXBlVHJhaXRzVGVzdCwgVGVzdElzSW50ZWdlcikgeworICAvLyBWZXJpZnkgdGhhdCBpc19pbnRlZ3JhbCBpcyB0cnVlIGZvciBhbGwgaW50ZWdlciB0eXBlcy4KKyAgRVhQRUNUX1RSVUUoaXNfaW50ZWdyYWw8Ym9vbD46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfaW50ZWdyYWw8Y2hhcj46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfaW50ZWdyYWw8dW5zaWduZWQgY2hhcj46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfaW50ZWdyYWw8c2lnbmVkIGNoYXI+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGlzX2ludGVncmFsPHdjaGFyX3Q+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGlzX2ludGVncmFsPGludD46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfaW50ZWdyYWw8dW5zaWduZWQgaW50Pjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShpc19pbnRlZ3JhbDxzaG9ydD46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfaW50ZWdyYWw8dW5zaWduZWQgc2hvcnQ+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGlzX2ludGVncmFsPGxvbmc+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGlzX2ludGVncmFsPHVuc2lnbmVkIGxvbmc+Ojp2YWx1ZSk7CisKKyAgLy8gVmVyaWZ5IHRoYXQgaXNfaW50ZWdyYWwgaXMgZmFsc2UgZm9yIGEgZmV3IG5vbi1pbnRlZ2VyIHR5cGVzLgorICBFWFBFQ1RfRkFMU0UoaXNfaW50ZWdyYWw8dm9pZD46OnZhbHVlKTsKKyAgRVhQRUNUX0ZBTFNFKGlzX2ludGVncmFsPGZsb2F0Pjo6dmFsdWUpOworICBFWFBFQ1RfRkFMU0UoaXNfaW50ZWdyYWw8c3RyaW5nPjo6dmFsdWUpOworICBFWFBFQ1RfRkFMU0UoaXNfaW50ZWdyYWw8aW50Kj46OnZhbHVlKTsKKyAgRVhQRUNUX0ZBTFNFKGlzX2ludGVncmFsPEE+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRSgoaXNfaW50ZWdyYWw8cGFpcjxpbnQsIGludD4gPjo6dmFsdWUpKTsKKworICAvLyBWZXJpZnkgdGhhdCBjdi1xdWFsaWZpZWQgaW50ZWdyYWwgdHlwZXMgYXJlIHN0aWxsIGludGVncmFsLCBhbmQKKyAgLy8gY3YtcXVhbGlmaWVkIG5vbi1pbnRlZ3JhbCB0eXBlcyBhcmUgc3RpbGwgbm9uLWludGVncmFsLgorICBFWFBFQ1RfVFJVRShpc19pbnRlZ3JhbDxjb25zdCBjaGFyPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShpc19pbnRlZ3JhbDx2b2xhdGlsZSBib29sPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShpc19pbnRlZ3JhbDxjb25zdCB2b2xhdGlsZSB1bnNpZ25lZCBpbnQ+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19pbnRlZ3JhbDxjb25zdCBmbG9hdD46OnZhbHVlKTsKKyAgRVhQRUNUX0ZBTFNFKGlzX2ludGVncmFsPGludCogdm9sYXRpbGU+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19pbnRlZ3JhbDxjb25zdCB2b2xhdGlsZSBzdHJpbmc+Ojp2YWx1ZSk7Cit9CisKK1RFU1QoVHlwZVRyYWl0c1Rlc3QsIFRlc3RJc0Zsb2F0aW5nKSB7CisgIC8vIFZlcmlmeSB0aGF0IGlzX2Zsb2F0aW5nX3BvaW50IGlzIHRydWUgZm9yIGFsbCBmbG9hdGluZy1wb2ludCB0eXBlcy4KKyAgRVhQRUNUX1RSVUUoaXNfZmxvYXRpbmdfcG9pbnQ8ZmxvYXQ+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGlzX2Zsb2F0aW5nX3BvaW50PGRvdWJsZT46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfZmxvYXRpbmdfcG9pbnQ8bG9uZyBkb3VibGU+Ojp2YWx1ZSk7CisKKyAgLy8gVmVyaWZ5IHRoYXQgaXNfZmxvYXRpbmdfcG9pbnQgaXMgZmFsc2UgZm9yIGEgZmV3IG5vbi1mbG9hdCB0eXBlcy4KKyAgRVhQRUNUX0ZBTFNFKGlzX2Zsb2F0aW5nX3BvaW50PHZvaWQ+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19mbG9hdGluZ19wb2ludDxsb25nPjo6dmFsdWUpOworICBFWFBFQ1RfRkFMU0UoaXNfZmxvYXRpbmdfcG9pbnQ8c3RyaW5nPjo6dmFsdWUpOworICBFWFBFQ1RfRkFMU0UoaXNfZmxvYXRpbmdfcG9pbnQ8ZmxvYXQqPjo6dmFsdWUpOworICBFWFBFQ1RfRkFMU0UoaXNfZmxvYXRpbmdfcG9pbnQ8QT46OnZhbHVlKTsKKyAgRVhQRUNUX0ZBTFNFKChpc19mbG9hdGluZ19wb2ludDxwYWlyPGludCwgaW50PiA+Ojp2YWx1ZSkpOworCisgIC8vIFZlcmlmeSB0aGF0IGN2LXF1YWxpZmllZCBmbG9hdGluZyBwb2ludCB0eXBlcyBhcmUgc3RpbGwgZmxvYXRpbmcsIGFuZAorICAvLyBjdi1xdWFsaWZpZWQgbm9uLWZsb2F0aW5nIHR5cGVzIGFyZSBzdGlsbCBub24tZmxvYXRpbmcuCisgIEVYUEVDVF9UUlVFKGlzX2Zsb2F0aW5nX3BvaW50PGNvbnN0IGZsb2F0Pjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShpc19mbG9hdGluZ19wb2ludDx2b2xhdGlsZSBkb3VibGU+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGlzX2Zsb2F0aW5nX3BvaW50PGNvbnN0IHZvbGF0aWxlIGxvbmcgZG91YmxlPjo6dmFsdWUpOworICBFWFBFQ1RfRkFMU0UoaXNfZmxvYXRpbmdfcG9pbnQ8Y29uc3QgaW50Pjo6dmFsdWUpOworICBFWFBFQ1RfRkFMU0UoaXNfZmxvYXRpbmdfcG9pbnQ8dm9sYXRpbGUgc3RyaW5nPjo6dmFsdWUpOworICBFWFBFQ1RfRkFMU0UoaXNfZmxvYXRpbmdfcG9pbnQ8Y29uc3Qgdm9sYXRpbGUgY2hhcj46OnZhbHVlKTsKK30KKworVEVTVChUeXBlVHJhaXRzVGVzdCwgVGVzdElzUG9pbnRlcikgeworICAvLyBWZXJpZnkgdGhhdCBpc19wb2ludGVyIGlzIHRydWUgZm9yIHNvbWUgcG9pbnRlciB0eXBlcy4KKyAgRVhQRUNUX1RSVUUoaXNfcG9pbnRlcjxpbnQqPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShpc19wb2ludGVyPHZvaWQqPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShpc19wb2ludGVyPHN0cmluZyo+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGlzX3BvaW50ZXI8Y29uc3Qgdm9pZCo+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGlzX3BvaW50ZXI8dm9sYXRpbGUgZmxvYXQqIGNvbnN0Kj46OnZhbHVlKTsKKworICAvLyBWZXJpZnkgdGhhdCBpc19wb2ludGVyIGlzIGZhbHNlIGZvciBzb21lIG5vbi1wb2ludGVyIHR5cGVzLgorICBFWFBFQ1RfRkFMU0UoaXNfcG9pbnRlcjx2b2lkPjo6dmFsdWUpOworICBFWFBFQ1RfRkFMU0UoaXNfcG9pbnRlcjxmbG9hdCY+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19wb2ludGVyPGxvbmc+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19wb2ludGVyPHZlY3RvcjxpbnQqPiA+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19wb2ludGVyPGludFs1XT46OnZhbHVlKTsKKworICAvLyBBIGZ1bmN0aW9uIHBvaW50ZXIgaXMgYSBwb2ludGVyLCBidXQgYSBmdW5jdGlvbiB0eXBlLCBvciBhIGZ1bmN0aW9uCisgIC8vIHJlZmVyZW5jZSB0eXBlLCBpcyBub3QuCisgIEVYUEVDVF9UUlVFKGlzX3BvaW50ZXI8aW50ICgqKShpbnQgeCk+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19wb2ludGVyPHZvaWQoY2hhciB4KT46OnZhbHVlKTsKKyAgRVhQRUNUX0ZBTFNFKGlzX3BvaW50ZXI8ZG91YmxlICgmKShzdHJpbmcgeCk+Ojp2YWx1ZSk7CisKKyAgLy8gVmVyaWZ5IHRoYXQgaXNfcG9pbnRlcjxUPiBpcyB0cnVlIGZvciBzb21lIGN2LXF1YWxpZmllZCBwb2ludGVyIHR5cGVzLAorICAvLyBhbmQgZmFsc2UgZm9yIHNvbWUgY3YtcXVhbGlmaWVkIG5vbi1wb2ludGVyIHR5cGVzLgorICBFWFBFQ1RfVFJVRShpc19wb2ludGVyPGludCogY29uc3Q+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGlzX3BvaW50ZXI8Y29uc3Qgdm9pZCogdm9sYXRpbGU+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGlzX3BvaW50ZXI8Y2hhcioqIGNvbnN0IHZvbGF0aWxlPjo6dmFsdWUpOworICBFWFBFQ1RfRkFMU0UoaXNfcG9pbnRlcjxjb25zdCBpbnQ+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19wb2ludGVyPHZvbGF0aWxlIHZlY3RvcjxpbnQqPiA+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19wb2ludGVyPGNvbnN0IHZvbGF0aWxlIGRvdWJsZT46OnZhbHVlKTsKK30KKworVEVTVChUeXBlVHJhaXRzVGVzdCwgVGVzdElzRW51bSkgeworLy8gaXNfZW51bSBpc24ndCBzdXBwb3J0ZWQgb24gTVNWQyBvciBnY2MgMy54CisjaWYgIWRlZmluZWQoX01TQ19WRVIpICYmICEoZGVmaW5lZChfX0dOVUNfXykgJiYgX19HTlVDX18gPD0gMykKKyAgLy8gVmVyaWZ5IHRoYXQgaXNfZW51bSBpcyB0cnVlIGZvciBlbnVtIHR5cGVzLgorICBFWFBFQ1RfVFJVRShpc19lbnVtPEc+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGlzX2VudW08Y29uc3QgRz46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfZW51bTx2b2xhdGlsZSBHPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShpc19lbnVtPGNvbnN0IHZvbGF0aWxlIEc+Ojp2YWx1ZSk7CisKKyAgLy8gVmVyaWZ5IHRoYXQgaXNfZW51bSBpcyBmYWxzZSBmb3IgYSBmZXcgbm9uLWVudW0gdHlwZXMuCisgIEVYUEVDVF9GQUxTRShpc19lbnVtPHZvaWQ+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19lbnVtPEcmPjo6dmFsdWUpOworICBFWFBFQ1RfRkFMU0UoaXNfZW51bTxHWzFdPjo6dmFsdWUpOworICBFWFBFQ1RfRkFMU0UoaXNfZW51bTxjb25zdCBHWzFdPjo6dmFsdWUpOworICBFWFBFQ1RfRkFMU0UoaXNfZW51bTxHW10+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19lbnVtPGludD46OnZhbHVlKTsKKyAgRVhQRUNUX0ZBTFNFKGlzX2VudW08ZmxvYXQ+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19lbnVtPEE+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19lbnVtPEEqPjo6dmFsdWUpOworICBFWFBFQ1RfRkFMU0UoaXNfZW51bTxjb25zdCBBPjo6dmFsdWUpOworICBFWFBFQ1RfRkFMU0UoaXNfZW51bTxIPjo6dmFsdWUpOworICBFWFBFQ1RfRkFMU0UoaXNfZW51bTxJPjo6dmFsdWUpOworICBFWFBFQ1RfRkFMU0UoaXNfZW51bTxKPjo6dmFsdWUpOworICBFWFBFQ1RfRkFMU0UoaXNfZW51bTx2b2lkKCk+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19lbnVtPHZvaWQoKikoKT46OnZhbHVlKTsKKyAgRVhQRUNUX0ZBTFNFKGlzX2VudW08aW50IEE6Oio+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19lbnVtPHZvaWQgKEE6OiopKCk+Ojp2YWx1ZSk7CisjZW5kaWYKK30KKworVEVTVChUeXBlVHJhaXRzVGVzdCwgVGVzdElzUmVmZXJlbmNlKSB7CisgIC8vIFZlcmlmaWVzIHRoYXQgaXNfcmVmZXJlbmNlIGlzIHRydWUgZm9yIGFsbCByZWZlcmVuY2UgdHlwZXMuCisgIHR5cGVkZWYgZmxvYXQmIFJlZkZsb2F0OworICBFWFBFQ1RfVFJVRShpc19yZWZlcmVuY2U8ZmxvYXQmPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShpc19yZWZlcmVuY2U8Y29uc3QgaW50Jj46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfcmVmZXJlbmNlPGNvbnN0IGludComPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShpc19yZWZlcmVuY2U8aW50ICgmKShib29sKT46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfcmVmZXJlbmNlPFJlZkZsb2F0Pjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShpc19yZWZlcmVuY2U8Y29uc3QgUmVmRmxvYXQ+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGlzX3JlZmVyZW5jZTx2b2xhdGlsZSBSZWZGbG9hdD46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfcmVmZXJlbmNlPGNvbnN0IHZvbGF0aWxlIFJlZkZsb2F0Pjo6dmFsdWUpOworCisKKyAgLy8gVmVyaWZpZXMgdGhhdCBpc19yZWZlcmVuY2UgaXMgZmFsc2UgZm9yIGFsbCBub24tcmVmZXJlbmNlIHR5cGVzLgorICBFWFBFQ1RfRkFMU0UoaXNfcmVmZXJlbmNlPGZsb2F0Pjo6dmFsdWUpOworICBFWFBFQ1RfRkFMU0UoaXNfcmVmZXJlbmNlPGNvbnN0IGZsb2F0Pjo6dmFsdWUpOworICBFWFBFQ1RfRkFMU0UoaXNfcmVmZXJlbmNlPHZvbGF0aWxlIGZsb2F0Pjo6dmFsdWUpOworICBFWFBFQ1RfRkFMU0UoaXNfcmVmZXJlbmNlPGNvbnN0IHZvbGF0aWxlIGZsb2F0Pjo6dmFsdWUpOworICBFWFBFQ1RfRkFMU0UoaXNfcmVmZXJlbmNlPGNvbnN0IGludCo+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19yZWZlcmVuY2U8aW50KCk+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19yZWZlcmVuY2U8dm9pZCgqKShjb25zdCBjaGFyJik+Ojp2YWx1ZSk7Cit9CisKK1RFU1QoVHlwZVRyYWl0c1Rlc3QsIFRlc3RBZGRSZWZlcmVuY2UpIHsKKyAgQ09NUElMRV9BU1NFUlRfVFlQRVNfRVEoaW50JiwgYWRkX3JlZmVyZW5jZTxpbnQ+Ojp0eXBlKTsKKyAgQ09NUElMRV9BU1NFUlRfVFlQRVNfRVEoY29uc3QgaW50JiwgYWRkX3JlZmVyZW5jZTxjb25zdCBpbnQ+Ojp0eXBlKTsKKyAgQ09NUElMRV9BU1NFUlRfVFlQRVNfRVEodm9sYXRpbGUgaW50JiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkX3JlZmVyZW5jZTx2b2xhdGlsZSBpbnQ+Ojp0eXBlKTsKKyAgQ09NUElMRV9BU1NFUlRfVFlQRVNfRVEoY29uc3Qgdm9sYXRpbGUgaW50JiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkX3JlZmVyZW5jZTxjb25zdCB2b2xhdGlsZSBpbnQ+Ojp0eXBlKTsKKyAgQ09NUElMRV9BU1NFUlRfVFlQRVNfRVEoaW50JiwgYWRkX3JlZmVyZW5jZTxpbnQmPjo6dHlwZSk7CisgIENPTVBJTEVfQVNTRVJUX1RZUEVTX0VRKGNvbnN0IGludCYsIGFkZF9yZWZlcmVuY2U8Y29uc3QgaW50Jj46OnR5cGUpOworICBDT01QSUxFX0FTU0VSVF9UWVBFU19FUSh2b2xhdGlsZSBpbnQmLAorICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRfcmVmZXJlbmNlPHZvbGF0aWxlIGludCY+Ojp0eXBlKTsKKyAgQ09NUElMRV9BU1NFUlRfVFlQRVNfRVEoY29uc3Qgdm9sYXRpbGUgaW50JiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkX3JlZmVyZW5jZTxjb25zdCB2b2xhdGlsZSBpbnQmPjo6dHlwZSk7Cit9CisKK1RFU1QoVHlwZVRyYWl0c1Rlc3QsIFRlc3RJc1BvZCkgeworICAvLyBWZXJpZnkgdGhhdCBhcml0aG1ldGljIHR5cGVzIGFuZCBwb2ludGVycyBhcmUgbWFya2VkIGFzIFBPRHMuCisgIEVYUEVDVF9UUlVFKGlzX3BvZDxib29sPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShpc19wb2Q8Y2hhcj46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfcG9kPHVuc2lnbmVkIGNoYXI+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGlzX3BvZDxzaWduZWQgY2hhcj46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfcG9kPHdjaGFyX3Q+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGlzX3BvZDxpbnQ+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGlzX3BvZDx1bnNpZ25lZCBpbnQ+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGlzX3BvZDxzaG9ydD46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfcG9kPHVuc2lnbmVkIHNob3J0Pjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShpc19wb2Q8bG9uZz46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfcG9kPHVuc2lnbmVkIGxvbmc+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGlzX3BvZDxmbG9hdD46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfcG9kPGRvdWJsZT46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfcG9kPGxvbmcgZG91YmxlPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShpc19wb2Q8c3RyaW5nKj46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfcG9kPEEqPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShpc19wb2Q8Y29uc3QgQio+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGlzX3BvZDxDKio+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGlzX3BvZDxjb25zdCBpbnQ+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGlzX3BvZDxjaGFyKiB2b2xhdGlsZT46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfcG9kPGNvbnN0IHZvbGF0aWxlIGRvdWJsZT46OnZhbHVlKTsKKyNpZiAhZGVmaW5lZChfTVNDX1ZFUikgJiYgIShkZWZpbmVkKF9fR05VQ19fKSAmJiBfX0dOVUNfXyA8PSAzKQorICBFWFBFQ1RfVFJVRShpc19wb2Q8Rz46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaXNfcG9kPGNvbnN0IEc+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGlzX3BvZDx2b2xhdGlsZSBHPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShpc19wb2Q8Y29uc3Qgdm9sYXRpbGUgRz46OnZhbHVlKTsKKyNlbmRpZgorCisgIC8vIFZlcmlmeSB0aGF0IHNvbWUgbm9uLVBPRCB0eXBlcyBhcmUgbm90IG1hcmtlZCBhcyBQT0RzLgorICBFWFBFQ1RfRkFMU0UoaXNfcG9kPHZvaWQ+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19wb2Q8c3RyaW5nPjo6dmFsdWUpOworICBFWFBFQ1RfRkFMU0UoKGlzX3BvZDxwYWlyPGludCwgaW50PiA+Ojp2YWx1ZSkpOworICBFWFBFQ1RfRkFMU0UoaXNfcG9kPEE+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShpc19wb2Q8Qj46OnZhbHVlKTsKKyAgRVhQRUNUX0ZBTFNFKGlzX3BvZDxDPjo6dmFsdWUpOworICBFWFBFQ1RfRkFMU0UoaXNfcG9kPGNvbnN0IHN0cmluZz46OnZhbHVlKTsKKyAgRVhQRUNUX0ZBTFNFKGlzX3BvZDx2b2xhdGlsZSBBPjo6dmFsdWUpOworICBFWFBFQ1RfRkFMU0UoaXNfcG9kPGNvbnN0IHZvbGF0aWxlIEI+Ojp2YWx1ZSk7Cit9CisKK1RFU1QoVHlwZVRyYWl0c1Rlc3QsIFRlc3RIYXNUcml2aWFsQ29uc3RydWN0b3IpIHsKKyAgLy8gVmVyaWZ5IHRoYXQgYXJpdGhtZXRpYyB0eXBlcyBhbmQgcG9pbnRlcnMgaGF2ZSB0cml2aWFsIGNvbnN0cnVjdG9ycy4KKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfY29uc3RydWN0b3I8Ym9vbD46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfY29uc3RydWN0b3I8Y2hhcj46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfY29uc3RydWN0b3I8dW5zaWduZWQgY2hhcj46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfY29uc3RydWN0b3I8c2lnbmVkIGNoYXI+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2NvbnN0cnVjdG9yPHdjaGFyX3Q+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2NvbnN0cnVjdG9yPGludD46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfY29uc3RydWN0b3I8dW5zaWduZWQgaW50Pjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9jb25zdHJ1Y3RvcjxzaG9ydD46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfY29uc3RydWN0b3I8dW5zaWduZWQgc2hvcnQ+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2NvbnN0cnVjdG9yPGxvbmc+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2NvbnN0cnVjdG9yPHVuc2lnbmVkIGxvbmc+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2NvbnN0cnVjdG9yPGZsb2F0Pjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9jb25zdHJ1Y3Rvcjxkb3VibGU+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2NvbnN0cnVjdG9yPGxvbmcgZG91YmxlPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9jb25zdHJ1Y3RvcjxzdHJpbmcqPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9jb25zdHJ1Y3RvcjxBKj46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfY29uc3RydWN0b3I8Y29uc3QgQio+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2NvbnN0cnVjdG9yPEMqKj46OnZhbHVlKTsKKworICAvLyBWZXJpZnkgdGhhdCBwYWlycyBhbmQgYXJyYXlzIG9mIHN1Y2ggdHlwZXMgaGF2ZSB0cml2aWFsCisgIC8vIGNvbnN0cnVjdG9ycy4KKyAgdHlwZWRlZiBpbnQgaW50MTBbMTBdOworICBFWFBFQ1RfVFJVRSgoaGFzX3RyaXZpYWxfY29uc3RydWN0b3I8cGFpcjxpbnQsIGNoYXIqPiA+Ojp2YWx1ZSkpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9jb25zdHJ1Y3RvcjxpbnQxMD46OnZhbHVlKTsKKworICAvLyBWZXJpZnkgdGhhdCBwYWlycyBvZiB0eXBlcyB3aXRob3V0IHRyaXZpYWwgY29uc3RydWN0b3JzCisgIC8vIGFyZSBub3QgbWFya2VkIGFzIHRyaXZpYWwuCisgIEVYUEVDVF9GQUxTRSgoaGFzX3RyaXZpYWxfY29uc3RydWN0b3I8cGFpcjxpbnQsIHN0cmluZz4gPjo6dmFsdWUpKTsKKyAgRVhQRUNUX0ZBTFNFKChoYXNfdHJpdmlhbF9jb25zdHJ1Y3RvcjxwYWlyPHN0cmluZywgaW50PiA+Ojp2YWx1ZSkpOworCisgIC8vIFZlcmlmeSB0aGF0IHR5cGVzIHdpdGhvdXQgdHJpdmlhbCBjb25zdHJ1Y3RvcnMgYXJlCisgIC8vIGNvcnJlY3RseSBtYXJrZWQgYXMgc3VjaC4KKyAgRVhQRUNUX0ZBTFNFKGhhc190cml2aWFsX2NvbnN0cnVjdG9yPHN0cmluZz46OnZhbHVlKTsKKyAgRVhQRUNUX0ZBTFNFKGhhc190cml2aWFsX2NvbnN0cnVjdG9yPHZlY3RvcjxpbnQ+ID46OnZhbHVlKTsKKworICAvLyBWZXJpZnkgdGhhdCBFLCB3aGljaCB3ZSBoYXZlIGRlY2xhcmVkIHRvIGhhdmUgYSB0cml2aWFsCisgIC8vIGNvbnN0cnVjdG9yLCBpcyBjb3JyZWN0bHkgbWFya2VkIGFzIHN1Y2guCisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2NvbnN0cnVjdG9yPEU+Ojp2YWx1ZSk7Cit9CisKK1RFU1QoVHlwZVRyYWl0c1Rlc3QsIFRlc3RIYXNUcml2aWFsQ29weSkgeworICAvLyBWZXJpZnkgdGhhdCBhcml0aG1ldGljIHR5cGVzIGFuZCBwb2ludGVycyBoYXZlIHRyaXZpYWwgY29weQorICAvLyBjb25zdHJ1Y3RvcnMuCisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2NvcHk8Ym9vbD46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfY29weTxjaGFyPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9jb3B5PHVuc2lnbmVkIGNoYXI+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2NvcHk8c2lnbmVkIGNoYXI+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2NvcHk8d2NoYXJfdD46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfY29weTxpbnQ+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2NvcHk8dW5zaWduZWQgaW50Pjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9jb3B5PHNob3J0Pjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9jb3B5PHVuc2lnbmVkIHNob3J0Pjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9jb3B5PGxvbmc+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2NvcHk8dW5zaWduZWQgbG9uZz46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfY29weTxmbG9hdD46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfY29weTxkb3VibGU+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2NvcHk8bG9uZyBkb3VibGU+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2NvcHk8c3RyaW5nKj46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfY29weTxBKj46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfY29weTxjb25zdCBCKj46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfY29weTxDKio+Ojp2YWx1ZSk7CisKKyAgLy8gVmVyaWZ5IHRoYXQgcGFpcnMgYW5kIGFycmF5cyBvZiBzdWNoIHR5cGVzIGhhdmUgdHJpdmlhbAorICAvLyBjb3B5IGNvbnN0cnVjdG9ycy4KKyAgdHlwZWRlZiBpbnQgaW50MTBbMTBdOworICBFWFBFQ1RfVFJVRSgoaGFzX3RyaXZpYWxfY29weTxwYWlyPGludCwgY2hhcio+ID46OnZhbHVlKSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2NvcHk8aW50MTA+Ojp2YWx1ZSk7CisKKyAgLy8gVmVyaWZ5IHRoYXQgcGFpcnMgb2YgdHlwZXMgd2l0aG91dCB0cml2aWFsIGNvcHkgY29uc3RydWN0b3JzCisgIC8vIGFyZSBub3QgbWFya2VkIGFzIHRyaXZpYWwuCisgIEVYUEVDVF9GQUxTRSgoaGFzX3RyaXZpYWxfY29weTxwYWlyPGludCwgc3RyaW5nPiA+Ojp2YWx1ZSkpOworICBFWFBFQ1RfRkFMU0UoKGhhc190cml2aWFsX2NvcHk8cGFpcjxzdHJpbmcsIGludD4gPjo6dmFsdWUpKTsKKworICAvLyBWZXJpZnkgdGhhdCB0eXBlcyB3aXRob3V0IHRyaXZpYWwgY29weSBjb25zdHJ1Y3RvcnMgYXJlCisgIC8vIGNvcnJlY3RseSBtYXJrZWQgYXMgc3VjaC4KKyAgRVhQRUNUX0ZBTFNFKGhhc190cml2aWFsX2NvcHk8c3RyaW5nPjo6dmFsdWUpOworICBFWFBFQ1RfRkFMU0UoaGFzX3RyaXZpYWxfY29weTx2ZWN0b3I8aW50PiA+Ojp2YWx1ZSk7CisKKyAgLy8gVmVyaWZ5IHRoYXQgQywgd2hpY2ggd2UgaGF2ZSBkZWNsYXJlZCB0byBoYXZlIGEgdHJpdmlhbAorICAvLyBjb3B5IGNvbnN0cnVjdG9yLCBpcyBjb3JyZWN0bHkgbWFya2VkIGFzIHN1Y2guCisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2NvcHk8Qz46OnZhbHVlKTsKK30KKworVEVTVChUeXBlVHJhaXRzVGVzdCwgVGVzdEhhc1RyaXZpYWxBc3NpZ24pIHsKKyAgLy8gVmVyaWZ5IHRoYXQgYXJpdGhtZXRpYyB0eXBlcyBhbmQgcG9pbnRlcnMgaGF2ZSB0cml2aWFsIGFzc2lnbm1lbnQKKyAgLy8gb3BlcmF0b3JzLgorICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9hc3NpZ248Ym9vbD46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfYXNzaWduPGNoYXI+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2Fzc2lnbjx1bnNpZ25lZCBjaGFyPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9hc3NpZ248c2lnbmVkIGNoYXI+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2Fzc2lnbjx3Y2hhcl90Pjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9hc3NpZ248aW50Pjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9hc3NpZ248dW5zaWduZWQgaW50Pjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9hc3NpZ248c2hvcnQ+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2Fzc2lnbjx1bnNpZ25lZCBzaG9ydD46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfYXNzaWduPGxvbmc+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2Fzc2lnbjx1bnNpZ25lZCBsb25nPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9hc3NpZ248ZmxvYXQ+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2Fzc2lnbjxkb3VibGU+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2Fzc2lnbjxsb25nIGRvdWJsZT46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfYXNzaWduPHN0cmluZyo+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2Fzc2lnbjxBKj46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfYXNzaWduPGNvbnN0IEIqPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9hc3NpZ248QyoqPjo6dmFsdWUpOworCisgIC8vIFZlcmlmeSB0aGF0IHBhaXJzIGFuZCBhcnJheXMgb2Ygc3VjaCB0eXBlcyBoYXZlIHRyaXZpYWwKKyAgLy8gYXNzaWdubWVudCBvcGVyYXRvcnMuCisgIHR5cGVkZWYgaW50IGludDEwWzEwXTsKKyAgRVhQRUNUX1RSVUUoKGhhc190cml2aWFsX2Fzc2lnbjxwYWlyPGludCwgY2hhcio+ID46OnZhbHVlKSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2Fzc2lnbjxpbnQxMD46OnZhbHVlKTsKKworICAvLyBWZXJpZnkgdGhhdCBwYWlycyBvZiB0eXBlcyB3aXRob3V0IHRyaXZpYWwgYXNzaWdubWVudCBvcGVyYXRvcnMKKyAgLy8gYXJlIG5vdCBtYXJrZWQgYXMgdHJpdmlhbC4KKyAgRVhQRUNUX0ZBTFNFKChoYXNfdHJpdmlhbF9hc3NpZ248cGFpcjxpbnQsIHN0cmluZz4gPjo6dmFsdWUpKTsKKyAgRVhQRUNUX0ZBTFNFKChoYXNfdHJpdmlhbF9hc3NpZ248cGFpcjxzdHJpbmcsIGludD4gPjo6dmFsdWUpKTsKKworICAvLyBWZXJpZnkgdGhhdCB0eXBlcyB3aXRob3V0IHRyaXZpYWwgYXNzaWdubWVudCBvcGVyYXRvcnMgYXJlCisgIC8vIGNvcnJlY3RseSBtYXJrZWQgYXMgc3VjaC4KKyAgRVhQRUNUX0ZBTFNFKGhhc190cml2aWFsX2Fzc2lnbjxzdHJpbmc+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShoYXNfdHJpdmlhbF9hc3NpZ248dmVjdG9yPGludD4gPjo6dmFsdWUpOworCisgIC8vIFZlcmlmeSB0aGF0IEQsIHdoaWNoIHdlIGhhdmUgZGVjbGFyZWQgdG8gaGF2ZSBhIHRyaXZpYWwKKyAgLy8gYXNzaWdubWVudCBvcGVyYXRvciwgaXMgY29ycmVjdGx5IG1hcmtlZCBhcyBzdWNoLgorICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9hc3NpZ248RD46OnZhbHVlKTsKK30KKworVEVTVChUeXBlVHJhaXRzVGVzdCwgVGVzdEhhc1RyaXZpYWxEZXN0cnVjdG9yKSB7CisgIC8vIFZlcmlmeSB0aGF0IGFyaXRobWV0aWMgdHlwZXMgYW5kIHBvaW50ZXJzIGhhdmUgdHJpdmlhbCBkZXN0cnVjdG9ycy4KKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfZGVzdHJ1Y3Rvcjxib29sPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9kZXN0cnVjdG9yPGNoYXI+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2Rlc3RydWN0b3I8dW5zaWduZWQgY2hhcj46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfZGVzdHJ1Y3RvcjxzaWduZWQgY2hhcj46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfZGVzdHJ1Y3Rvcjx3Y2hhcl90Pjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9kZXN0cnVjdG9yPGludD46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfZGVzdHJ1Y3Rvcjx1bnNpZ25lZCBpbnQ+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2Rlc3RydWN0b3I8c2hvcnQ+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2Rlc3RydWN0b3I8dW5zaWduZWQgc2hvcnQ+Ojp2YWx1ZSk7CisgIEVYUEVDVF9UUlVFKGhhc190cml2aWFsX2Rlc3RydWN0b3I8bG9uZz46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfZGVzdHJ1Y3Rvcjx1bnNpZ25lZCBsb25nPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9kZXN0cnVjdG9yPGZsb2F0Pjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9kZXN0cnVjdG9yPGRvdWJsZT46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfZGVzdHJ1Y3Rvcjxsb25nIGRvdWJsZT46OnZhbHVlKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfZGVzdHJ1Y3RvcjxzdHJpbmcqPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9kZXN0cnVjdG9yPEEqPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9kZXN0cnVjdG9yPGNvbnN0IEIqPjo6dmFsdWUpOworICBFWFBFQ1RfVFJVRShoYXNfdHJpdmlhbF9kZXN0cnVjdG9yPEMqKj46OnZhbHVlKTsKKworICAvLyBWZXJpZnkgdGhhdCBwYWlycyBhbmQgYXJyYXlzIG9mIHN1Y2ggdHlwZXMgaGF2ZSB0cml2aWFsCisgIC8vIGRlc3RydWN0b3JzLgorICB0eXBlZGVmIGludCBpbnQxMFsxMF07CisgIEVYUEVDVF9UUlVFKChoYXNfdHJpdmlhbF9kZXN0cnVjdG9yPHBhaXI8aW50LCBjaGFyKj4gPjo6dmFsdWUpKTsKKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfZGVzdHJ1Y3RvcjxpbnQxMD46OnZhbHVlKTsKKworICAvLyBWZXJpZnkgdGhhdCBwYWlycyBvZiB0eXBlcyB3aXRob3V0IHRyaXZpYWwgZGVzdHJ1Y3RvcnMKKyAgLy8gYXJlIG5vdCBtYXJrZWQgYXMgdHJpdmlhbC4KKyAgRVhQRUNUX0ZBTFNFKChoYXNfdHJpdmlhbF9kZXN0cnVjdG9yPHBhaXI8aW50LCBzdHJpbmc+ID46OnZhbHVlKSk7CisgIEVYUEVDVF9GQUxTRSgoaGFzX3RyaXZpYWxfZGVzdHJ1Y3RvcjxwYWlyPHN0cmluZywgaW50PiA+Ojp2YWx1ZSkpOworCisgIC8vIFZlcmlmeSB0aGF0IHR5cGVzIHdpdGhvdXQgdHJpdmlhbCBkZXN0cnVjdG9ycyBhcmUKKyAgLy8gY29ycmVjdGx5IG1hcmtlZCBhcyBzdWNoLgorICBFWFBFQ1RfRkFMU0UoaGFzX3RyaXZpYWxfZGVzdHJ1Y3RvcjxzdHJpbmc+Ojp2YWx1ZSk7CisgIEVYUEVDVF9GQUxTRShoYXNfdHJpdmlhbF9kZXN0cnVjdG9yPHZlY3RvcjxpbnQ+ID46OnZhbHVlKTsKKworICAvLyBWZXJpZnkgdGhhdCBGLCB3aGljaCB3ZSBoYXZlIGRlY2xhcmVkIHRvIGhhdmUgYSB0cml2aWFsCisgIC8vIGRlc3RydWN0b3IsIGlzIGNvcnJlY3RseSBtYXJrZWQgYXMgc3VjaC4KKyAgRVhQRUNUX1RSVUUoaGFzX3RyaXZpYWxfZGVzdHJ1Y3RvcjxGPjo6dmFsdWUpOworfQorCisvLyBUZXN0cyByZW1vdmVfcG9pbnRlci4KK1RFU1QoVHlwZVRyYWl0c1Rlc3QsIFRlc3RSZW1vdmVQb2ludGVyKSB7CisgIENPTVBJTEVfQVNTRVJUX1RZUEVTX0VRKGludCwgcmVtb3ZlX3BvaW50ZXI8aW50Pjo6dHlwZSk7CisgIENPTVBJTEVfQVNTRVJUX1RZUEVTX0VRKGludCwgcmVtb3ZlX3BvaW50ZXI8aW50Kj46OnR5cGUpOworICBDT01QSUxFX0FTU0VSVF9UWVBFU19FUShjb25zdCBpbnQsIHJlbW92ZV9wb2ludGVyPGNvbnN0IGludCo+Ojp0eXBlKTsKKyAgQ09NUElMRV9BU1NFUlRfVFlQRVNfRVEoaW50LCByZW1vdmVfcG9pbnRlcjxpbnQqIGNvbnN0Pjo6dHlwZSk7CisgIENPTVBJTEVfQVNTRVJUX1RZUEVTX0VRKGludCwgcmVtb3ZlX3BvaW50ZXI8aW50KiB2b2xhdGlsZT46OnR5cGUpOworfQorCitURVNUKFR5cGVUcmFpdHNUZXN0LCBUZXN0UmVtb3ZlQ29uc3QpIHsKKyAgQ09NUElMRV9BU1NFUlRfVFlQRVNfRVEoaW50LCByZW1vdmVfY29uc3Q8aW50Pjo6dHlwZSk7CisgIENPTVBJTEVfQVNTRVJUX1RZUEVTX0VRKGludCwgcmVtb3ZlX2NvbnN0PGNvbnN0IGludD46OnR5cGUpOworICBDT01QSUxFX0FTU0VSVF9UWVBFU19FUShpbnQgKiwgcmVtb3ZlX2NvbnN0PGludCAqIGNvbnN0Pjo6dHlwZSk7CisgIC8vIFRSMSBleGFtcGxlcy4KKyAgQ09NUElMRV9BU1NFUlRfVFlQRVNfRVEoY29uc3QgaW50ICosIHJlbW92ZV9jb25zdDxjb25zdCBpbnQgKj46OnR5cGUpOworICBDT01QSUxFX0FTU0VSVF9UWVBFU19FUSh2b2xhdGlsZSBpbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZV9jb25zdDxjb25zdCB2b2xhdGlsZSBpbnQ+Ojp0eXBlKTsKK30KKworVEVTVChUeXBlVHJhaXRzVGVzdCwgVGVzdFJlbW92ZVZvbGF0aWxlKSB7CisgIENPTVBJTEVfQVNTRVJUX1RZUEVTX0VRKGludCwgcmVtb3ZlX3ZvbGF0aWxlPGludD46OnR5cGUpOworICBDT01QSUxFX0FTU0VSVF9UWVBFU19FUShpbnQsIHJlbW92ZV92b2xhdGlsZTx2b2xhdGlsZSBpbnQ+Ojp0eXBlKTsKKyAgQ09NUElMRV9BU1NFUlRfVFlQRVNfRVEoaW50ICosIHJlbW92ZV92b2xhdGlsZTxpbnQgKiB2b2xhdGlsZT46OnR5cGUpOworICAvLyBUUjEgZXhhbXBsZXMuCisgIENPTVBJTEVfQVNTRVJUX1RZUEVTX0VRKHZvbGF0aWxlIGludCAqLAorICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVfdm9sYXRpbGU8dm9sYXRpbGUgaW50ICo+Ojp0eXBlKTsKKyAgQ09NUElMRV9BU1NFUlRfVFlQRVNfRVEoY29uc3QgaW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVfdm9sYXRpbGU8Y29uc3Qgdm9sYXRpbGUgaW50Pjo6dHlwZSk7Cit9CisKK1RFU1QoVHlwZVRyYWl0c1Rlc3QsIFRlc3RSZW1vdmVDVikgeworICBDT01QSUxFX0FTU0VSVF9UWVBFU19FUShpbnQsIHJlbW92ZV9jdjxpbnQ+Ojp0eXBlKTsKKyAgQ09NUElMRV9BU1NFUlRfVFlQRVNfRVEoaW50LCByZW1vdmVfY3Y8dm9sYXRpbGUgaW50Pjo6dHlwZSk7CisgIENPTVBJTEVfQVNTRVJUX1RZUEVTX0VRKGludCwgcmVtb3ZlX2N2PGNvbnN0IGludD46OnR5cGUpOworICBDT01QSUxFX0FTU0VSVF9UWVBFU19FUShpbnQgKiwgcmVtb3ZlX2N2PGludCAqIGNvbnN0IHZvbGF0aWxlPjo6dHlwZSk7CisgIC8vIFRSMSBleGFtcGxlcy4KKyAgQ09NUElMRV9BU1NFUlRfVFlQRVNfRVEoY29uc3Qgdm9sYXRpbGUgaW50ICosCisgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZV9jdjxjb25zdCB2b2xhdGlsZSBpbnQgKj46OnR5cGUpOworICBDT01QSUxFX0FTU0VSVF9UWVBFU19FUShpbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZV9jdjxjb25zdCB2b2xhdGlsZSBpbnQ+Ojp0eXBlKTsKK30KKworVEVTVChUeXBlVHJhaXRzVGVzdCwgVGVzdFJlbW92ZVJlZmVyZW5jZSkgeworICBDT01QSUxFX0FTU0VSVF9UWVBFU19FUShpbnQsIHJlbW92ZV9yZWZlcmVuY2U8aW50Pjo6dHlwZSk7CisgIENPTVBJTEVfQVNTRVJUX1RZUEVTX0VRKGludCwgcmVtb3ZlX3JlZmVyZW5jZTxpbnQmPjo6dHlwZSk7CisgIENPTVBJTEVfQVNTRVJUX1RZUEVTX0VRKGNvbnN0IGludCwgcmVtb3ZlX3JlZmVyZW5jZTxjb25zdCBpbnQmPjo6dHlwZSk7CisgIENPTVBJTEVfQVNTRVJUX1RZUEVTX0VRKGludCosIHJlbW92ZV9yZWZlcmVuY2U8aW50ICogJj46OnR5cGUpOworfQorCitURVNUKFR5cGVUcmFpdHNUZXN0LCBUZXN0SXNTYW1lKSB7CisgIEVYUEVDVF9UUlVFKChpc19zYW1lPGludDMyLCBpbnQzMj46OnZhbHVlKSk7CisgIEVYUEVDVF9GQUxTRSgoaXNfc2FtZTxpbnQzMiwgaW50NjQ+Ojp2YWx1ZSkpOworICBFWFBFQ1RfRkFMU0UoKGlzX3NhbWU8aW50NjQsIGludDMyPjo6dmFsdWUpKTsKKyAgRVhQRUNUX0ZBTFNFKChpc19zYW1lPGludCwgY29uc3QgaW50Pjo6dmFsdWUpKTsKKworICBFWFBFQ1RfVFJVRSgoaXNfc2FtZTx2b2lkLCB2b2lkPjo6dmFsdWUpKTsKKyAgRVhQRUNUX0ZBTFNFKChpc19zYW1lPHZvaWQsIGludD46OnZhbHVlKSk7CisgIEVYUEVDVF9GQUxTRSgoaXNfc2FtZTxpbnQsIHZvaWQ+Ojp2YWx1ZSkpOworCisgIEVYUEVDVF9UUlVFKChpc19zYW1lPGludCosIGludCo+Ojp2YWx1ZSkpOworICBFWFBFQ1RfVFJVRSgoaXNfc2FtZTx2b2lkKiwgdm9pZCo+Ojp2YWx1ZSkpOworICBFWFBFQ1RfRkFMU0UoKGlzX3NhbWU8aW50Kiwgdm9pZCo+Ojp2YWx1ZSkpOworICBFWFBFQ1RfRkFMU0UoKGlzX3NhbWU8dm9pZCosIGludCo+Ojp2YWx1ZSkpOworICBFWFBFQ1RfRkFMU0UoKGlzX3NhbWU8dm9pZCosIGNvbnN0IHZvaWQqPjo6dmFsdWUpKTsKKyAgRVhQRUNUX0ZBTFNFKChpc19zYW1lPHZvaWQqLCB2b2lkKiBjb25zdD46OnZhbHVlKSk7CisKKyAgRVhQRUNUX1RSVUUoKGlzX3NhbWU8QmFzZSosIEJhc2UqPjo6dmFsdWUpKTsKKyAgRVhQRUNUX1RSVUUoKGlzX3NhbWU8RGVyaXZlZCosIERlcml2ZWQqPjo6dmFsdWUpKTsKKyAgRVhQRUNUX0ZBTFNFKChpc19zYW1lPEJhc2UqLCBEZXJpdmVkKj46OnZhbHVlKSk7CisgIEVYUEVDVF9GQUxTRSgoaXNfc2FtZTxEZXJpdmVkKiwgQmFzZSo+Ojp2YWx1ZSkpOworfQorCitURVNUKFR5cGVUcmFpdHNUZXN0LCBUZXN0Q29udmVydGlibGUpIHsKKyNpZiAhKGRlZmluZWQoX19HTlVDX18pICYmIF9fR05VQ19fIDw9IDMpCisgIEVYUEVDVF9UUlVFKChpc19jb252ZXJ0aWJsZTxpbnQsIGludD46OnZhbHVlKSk7CisgIEVYUEVDVF9UUlVFKChpc19jb252ZXJ0aWJsZTxpbnQsIGxvbmc+Ojp2YWx1ZSkpOworICBFWFBFQ1RfVFJVRSgoaXNfY29udmVydGlibGU8bG9uZywgaW50Pjo6dmFsdWUpKTsKKworICBFWFBFQ1RfVFJVRSgoaXNfY29udmVydGlibGU8aW50Kiwgdm9pZCo+Ojp2YWx1ZSkpOworICBFWFBFQ1RfRkFMU0UoKGlzX2NvbnZlcnRpYmxlPHZvaWQqLCBpbnQqPjo6dmFsdWUpKTsKKworICBFWFBFQ1RfVFJVRSgoaXNfY29udmVydGlibGU8RGVyaXZlZCosIEJhc2UqPjo6dmFsdWUpKTsKKyAgRVhQRUNUX0ZBTFNFKChpc19jb252ZXJ0aWJsZTxCYXNlKiwgRGVyaXZlZCo+Ojp2YWx1ZSkpOworICBFWFBFQ1RfVFJVRSgoaXNfY29udmVydGlibGU8RGVyaXZlZCosIGNvbnN0IEJhc2UqPjo6dmFsdWUpKTsKKyAgRVhQRUNUX0ZBTFNFKChpc19jb252ZXJ0aWJsZTxjb25zdCBEZXJpdmVkKiwgQmFzZSo+Ojp2YWx1ZSkpOworI2VuZGlmCit9CisKK30gIC8vIGFub255bW91cyBuYW1lc3BhY2UKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RfdXRpbC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdF91dGlsLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA3YWExZDcKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RfdXRpbC5jYwpAQCAtMCwwICsxLDMzNDYgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2lmZGVmIF9XSU4zMgorLy8gVmVyaWZ5IHRoYXQgI2luY2x1ZGluZyB3aW5kb3dzLmggZG9lcyBub3QgYnJlYWsgYW55dGhpbmcgKGUuZy4gYmVjYXVzZQorLy8gd2luZG93cy5oICNkZWZpbmVzIEdldE1lc3NhZ2UoKSBhcyBhIG1hY3JvKS4KKyNpbmNsdWRlIDx3aW5kb3dzLmg+CisjZW5kaWYKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXN0X3V0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tZXNzYWdlLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbG9nZ2luZy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0Lmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCit2b2lkIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHModW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyogbWVzc2FnZSkgeworICBTZXRPcHRpb25hbEZpZWxkcyhtZXNzYWdlKTsKKyAgQWRkUmVwZWF0ZWRGaWVsZHMxKG1lc3NhZ2UpOworICBBZGRSZXBlYXRlZEZpZWxkczIobWVzc2FnZSk7CisgIFNldERlZmF1bHRGaWVsZHMobWVzc2FnZSk7CisgIFNldE9uZW9mRmllbGRzKG1lc3NhZ2UpOworfQorCit2b2lkIFRlc3RVdGlsOjpTZXRPcHRpb25hbEZpZWxkcyh1bml0dGVzdDo6VGVzdEFsbFR5cGVzKiBtZXNzYWdlKSB7CisgIG1lc3NhZ2UtPnNldF9vcHRpb25hbF9pbnQzMiAgICgxMDEpOworICBtZXNzYWdlLT5zZXRfb3B0aW9uYWxfaW50NjQgICAoMTAyKTsKKyAgbWVzc2FnZS0+c2V0X29wdGlvbmFsX3VpbnQzMiAgKDEwMyk7CisgIG1lc3NhZ2UtPnNldF9vcHRpb25hbF91aW50NjQgICgxMDQpOworICBtZXNzYWdlLT5zZXRfb3B0aW9uYWxfc2ludDMyICAoMTA1KTsKKyAgbWVzc2FnZS0+c2V0X29wdGlvbmFsX3NpbnQ2NCAgKDEwNik7CisgIG1lc3NhZ2UtPnNldF9vcHRpb25hbF9maXhlZDMyICgxMDcpOworICBtZXNzYWdlLT5zZXRfb3B0aW9uYWxfZml4ZWQ2NCAoMTA4KTsKKyAgbWVzc2FnZS0+c2V0X29wdGlvbmFsX3NmaXhlZDMyKDEwOSk7CisgIG1lc3NhZ2UtPnNldF9vcHRpb25hbF9zZml4ZWQ2NCgxMTApOworICBtZXNzYWdlLT5zZXRfb3B0aW9uYWxfZmxvYXQgICAoMTExKTsKKyAgbWVzc2FnZS0+c2V0X29wdGlvbmFsX2RvdWJsZSAgKDExMik7CisgIG1lc3NhZ2UtPnNldF9vcHRpb25hbF9ib29sICAgICh0cnVlKTsKKyAgbWVzc2FnZS0+c2V0X29wdGlvbmFsX3N0cmluZyAgKCIxMTUiKTsKKyAgbWVzc2FnZS0+c2V0X29wdGlvbmFsX2J5dGVzICAgKCIxMTYiKTsKKworICBtZXNzYWdlLT5tdXRhYmxlX29wdGlvbmFsZ3JvdXAgICAgICAgICAgICAgICAgICgpLT5zZXRfYSgxMTcpOworICBtZXNzYWdlLT5tdXRhYmxlX29wdGlvbmFsX25lc3RlZF9tZXNzYWdlICAgICAgICgpLT5zZXRfYmIoMTE4KTsKKyAgbWVzc2FnZS0+bXV0YWJsZV9vcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgICAgICAoKS0+c2V0X2MoMTE5KTsKKyAgbWVzc2FnZS0+bXV0YWJsZV9vcHRpb25hbF9pbXBvcnRfbWVzc2FnZSAgICAgICAoKS0+c2V0X2QoMTIwKTsKKyAgbWVzc2FnZS0+bXV0YWJsZV9vcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UoKS0+c2V0X2UoMTI2KTsKKyAgbWVzc2FnZS0+bXV0YWJsZV9vcHRpb25hbF9sYXp5X21lc3NhZ2UgICAgICAgICAoKS0+c2V0X2JiKDEyNyk7CisKKyAgbWVzc2FnZS0+c2V0X29wdGlvbmFsX25lc3RlZF9lbnVtICh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpCQVopOworICBtZXNzYWdlLT5zZXRfb3B0aW9uYWxfZm9yZWlnbl9lbnVtKHVuaXR0ZXN0OjpGT1JFSUdOX0JBWiAgICAgICk7CisgIG1lc3NhZ2UtPnNldF9vcHRpb25hbF9pbXBvcnRfZW51bSAodW5pdHRlc3RfaW1wb3J0OjpJTVBPUlRfQkFaKTsKKworICAvLyBTdHJpbmdQaWVjZSBhbmQgQ29yZCBmaWVsZHMgYXJlIG9ubHkgYWNjZXNzaWJsZSB2aWEgcmVmbGVjdGlvbiBpbiB0aGUKKyAgLy8gb3BlbiBzb3VyY2UgcmVsZWFzZTsgc2VlIGNvbW1lbnRzIGluIGNvbXBpbGVyL2NwcC9zdHJpbmdfZmllbGQuY2MuCisjaWZuZGVmIFBST1RPQlVGX1RFU1RfTk9fREVTQ1JJUFRPUlMKKyAgbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5TZXRTdHJpbmcoCisgICAgbWVzc2FnZSwKKyAgICBtZXNzYWdlLT5HZXREZXNjcmlwdG9yKCktPkZpbmRGaWVsZEJ5TmFtZSgib3B0aW9uYWxfc3RyaW5nX3BpZWNlIiksCisgICAgIjEyNCIpOworICBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlNldFN0cmluZygKKyAgICBtZXNzYWdlLAorICAgIG1lc3NhZ2UtPkdldERlc2NyaXB0b3IoKS0+RmluZEZpZWxkQnlOYW1lKCJvcHRpb25hbF9jb3JkIiksCisgICAgIjEyNSIpOworI2VuZGlmICAvLyAhUFJPVE9CVUZfVEVTVF9OT19ERVNDUklQVE9SUworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3ZvaWQgVGVzdFV0aWw6OkFkZFJlcGVhdGVkRmllbGRzMSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzKiBtZXNzYWdlKSB7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9pbnQzMiAgICgyMDEpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfaW50NjQgICAoMjAyKTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX3VpbnQzMiAgKDIwMyk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF91aW50NjQgICgyMDQpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfc2ludDMyICAoMjA1KTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX3NpbnQ2NCAgKDIwNik7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9maXhlZDMyICgyMDcpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfZml4ZWQ2NCAoMjA4KTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX3NmaXhlZDMyKDIwOSk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9zZml4ZWQ2NCgyMTApOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfZmxvYXQgICAoMjExKTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2RvdWJsZSAgKDIxMik7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9ib29sICAgICh0cnVlKTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX3N0cmluZyAgKCIyMTUiKTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2J5dGVzICAgKCIyMTYiKTsKKworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRncm91cCAgICAgICAgICAgKCktPnNldF9hKDIxNyk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSAoKS0+c2V0X2JiKDIxOCk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UoKS0+c2V0X2MoMjE5KTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2ltcG9ydF9tZXNzYWdlICgpLT5zZXRfZCgyMjApOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfbGF6eV9tZXNzYWdlICAgKCktPnNldF9iYigyMjcpOworCisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9uZXN0ZWRfZW51bSAodW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6QkFSKTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2ZvcmVpZ25fZW51bSh1bml0dGVzdDo6Rk9SRUlHTl9CQVIgICAgICApOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfaW1wb3J0X2VudW0gKHVuaXR0ZXN0X2ltcG9ydDo6SU1QT1JUX0JBUik7CisKKyNpZm5kZWYgUFJPVE9CVUZfVEVTVF9OT19ERVNDUklQVE9SUworICBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkFkZFN0cmluZygKKyAgICBtZXNzYWdlLAorICAgIG1lc3NhZ2UtPkdldERlc2NyaXB0b3IoKS0+RmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF9zdHJpbmdfcGllY2UiKSwKKyAgICAiMjI0Iik7CisgIG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+QWRkU3RyaW5nKAorICAgIG1lc3NhZ2UsCisgICAgbWVzc2FnZS0+R2V0RGVzY3JpcHRvcigpLT5GaW5kRmllbGRCeU5hbWUoInJlcGVhdGVkX2NvcmQiKSwKKyAgICAiMjI1Iik7CisjZW5kaWYgIC8vICFQUk9UT0JVRl9URVNUX05PX0RFU0NSSVBUT1JTCit9CisKK3ZvaWQgVGVzdFV0aWw6OkFkZFJlcGVhdGVkRmllbGRzMih1bml0dGVzdDo6VGVzdEFsbFR5cGVzKiBtZXNzYWdlKSB7CisgIC8vIEFkZCBhIHNlY29uZCBvbmUgb2YgZWFjaCBmaWVsZC4KKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2ludDMyICAgKDMwMSk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9pbnQ2NCAgICgzMDIpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfdWludDMyICAoMzAzKTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX3VpbnQ2NCAgKDMwNCk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9zaW50MzIgICgzMDUpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfc2ludDY0ICAoMzA2KTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2ZpeGVkMzIgKDMwNyk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9maXhlZDY0ICgzMDgpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfc2ZpeGVkMzIoMzA5KTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX3NmaXhlZDY0KDMxMCk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9mbG9hdCAgICgzMTEpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfZG91YmxlICAoMzEyKTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2Jvb2wgICAgKGZhbHNlKTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX3N0cmluZyAgKCIzMTUiKTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2J5dGVzICAgKCIzMTYiKTsKKworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRncm91cCAgICAgICAgICAgKCktPnNldF9hKDMxNyk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSAoKS0+c2V0X2JiKDMxOCk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UoKS0+c2V0X2MoMzE5KTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2ltcG9ydF9tZXNzYWdlICgpLT5zZXRfZCgzMjApOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfbGF6eV9tZXNzYWdlICAgKCktPnNldF9iYigzMjcpOworCisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9uZXN0ZWRfZW51bSAodW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6QkFaKTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2ZvcmVpZ25fZW51bSh1bml0dGVzdDo6Rk9SRUlHTl9CQVogICAgICApOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfaW1wb3J0X2VudW0gKHVuaXR0ZXN0X2ltcG9ydDo6SU1QT1JUX0JBWik7CisKKyNpZm5kZWYgUFJPVE9CVUZfVEVTVF9OT19ERVNDUklQVE9SUworICBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkFkZFN0cmluZygKKyAgICBtZXNzYWdlLAorICAgIG1lc3NhZ2UtPkdldERlc2NyaXB0b3IoKS0+RmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF9zdHJpbmdfcGllY2UiKSwKKyAgICAiMzI0Iik7CisgIG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+QWRkU3RyaW5nKAorICAgIG1lc3NhZ2UsCisgICAgbWVzc2FnZS0+R2V0RGVzY3JpcHRvcigpLT5GaW5kRmllbGRCeU5hbWUoInJlcGVhdGVkX2NvcmQiKSwKKyAgICAiMzI1Iik7CisjZW5kaWYgIC8vICFQUk9UT0JVRl9URVNUX05PX0RFU0NSSVBUT1JTCit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBUZXN0VXRpbDo6U2V0RGVmYXVsdEZpZWxkcyh1bml0dGVzdDo6VGVzdEFsbFR5cGVzKiBtZXNzYWdlKSB7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X2ludDMyICAgKDQwMSk7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X2ludDY0ICAgKDQwMik7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X3VpbnQzMiAgKDQwMyk7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X3VpbnQ2NCAgKDQwNCk7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X3NpbnQzMiAgKDQwNSk7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X3NpbnQ2NCAgKDQwNik7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X2ZpeGVkMzIgKDQwNyk7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X2ZpeGVkNjQgKDQwOCk7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X3NmaXhlZDMyKDQwOSk7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X3NmaXhlZDY0KDQxMCk7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X2Zsb2F0ICAgKDQxMSk7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X2RvdWJsZSAgKDQxMik7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X2Jvb2wgICAgKGZhbHNlKTsKKyAgbWVzc2FnZS0+c2V0X2RlZmF1bHRfc3RyaW5nICAoIjQxNSIpOworICBtZXNzYWdlLT5zZXRfZGVmYXVsdF9ieXRlcyAgICgiNDE2Iik7CisKKyAgbWVzc2FnZS0+c2V0X2RlZmF1bHRfbmVzdGVkX2VudW0gKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkZPTyk7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X2ZvcmVpZ25fZW51bSh1bml0dGVzdDo6Rk9SRUlHTl9GT08gICAgICApOworICBtZXNzYWdlLT5zZXRfZGVmYXVsdF9pbXBvcnRfZW51bSAodW5pdHRlc3RfaW1wb3J0OjpJTVBPUlRfRk9PKTsKKworI2lmbmRlZiBQUk9UT0JVRl9URVNUX05PX0RFU0NSSVBUT1JTCisgIG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+U2V0U3RyaW5nKAorICAgIG1lc3NhZ2UsCisgICAgbWVzc2FnZS0+R2V0RGVzY3JpcHRvcigpLT5GaW5kRmllbGRCeU5hbWUoImRlZmF1bHRfc3RyaW5nX3BpZWNlIiksCisgICAgIjQyNCIpOworICBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlNldFN0cmluZygKKyAgICBtZXNzYWdlLAorICAgIG1lc3NhZ2UtPkdldERlc2NyaXB0b3IoKS0+RmluZEZpZWxkQnlOYW1lKCJkZWZhdWx0X2NvcmQiKSwKKyAgICAiNDI1Iik7CisjZW5kaWYgIC8vICFQUk9UT0JVRl9URVNUX05PX0RFU0NSSVBUT1JTCit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBUZXN0VXRpbDo6TW9kaWZ5UmVwZWF0ZWRGaWVsZHModW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyogbWVzc2FnZSkgeworICBtZXNzYWdlLT5zZXRfcmVwZWF0ZWRfaW50MzIgICAoMSwgNTAxKTsKKyAgbWVzc2FnZS0+c2V0X3JlcGVhdGVkX2ludDY0ICAgKDEsIDUwMik7CisgIG1lc3NhZ2UtPnNldF9yZXBlYXRlZF91aW50MzIgICgxLCA1MDMpOworICBtZXNzYWdlLT5zZXRfcmVwZWF0ZWRfdWludDY0ICAoMSwgNTA0KTsKKyAgbWVzc2FnZS0+c2V0X3JlcGVhdGVkX3NpbnQzMiAgKDEsIDUwNSk7CisgIG1lc3NhZ2UtPnNldF9yZXBlYXRlZF9zaW50NjQgICgxLCA1MDYpOworICBtZXNzYWdlLT5zZXRfcmVwZWF0ZWRfZml4ZWQzMiAoMSwgNTA3KTsKKyAgbWVzc2FnZS0+c2V0X3JlcGVhdGVkX2ZpeGVkNjQgKDEsIDUwOCk7CisgIG1lc3NhZ2UtPnNldF9yZXBlYXRlZF9zZml4ZWQzMigxLCA1MDkpOworICBtZXNzYWdlLT5zZXRfcmVwZWF0ZWRfc2ZpeGVkNjQoMSwgNTEwKTsKKyAgbWVzc2FnZS0+c2V0X3JlcGVhdGVkX2Zsb2F0ICAgKDEsIDUxMSk7CisgIG1lc3NhZ2UtPnNldF9yZXBlYXRlZF9kb3VibGUgICgxLCA1MTIpOworICBtZXNzYWdlLT5zZXRfcmVwZWF0ZWRfYm9vbCAgICAoMSwgdHJ1ZSk7CisgIG1lc3NhZ2UtPnNldF9yZXBlYXRlZF9zdHJpbmcgICgxLCAiNTE1Iik7CisgIG1lc3NhZ2UtPnNldF9yZXBlYXRlZF9ieXRlcyAgICgxLCAiNTE2Iik7CisKKyAgbWVzc2FnZS0+bXV0YWJsZV9yZXBlYXRlZGdyb3VwICAgICAgICAgICAoMSktPnNldF9hKDUxNyk7CisgIG1lc3NhZ2UtPm11dGFibGVfcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgKDEpLT5zZXRfYmIoNTE4KTsKKyAgbWVzc2FnZS0+bXV0YWJsZV9yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UoMSktPnNldF9jKDUxOSk7CisgIG1lc3NhZ2UtPm11dGFibGVfcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgKDEpLT5zZXRfZCg1MjApOworICBtZXNzYWdlLT5tdXRhYmxlX3JlcGVhdGVkX2xhenlfbWVzc2FnZSAgICgxKS0+c2V0X2JiKDUyNyk7CisKKyAgbWVzc2FnZS0+c2V0X3JlcGVhdGVkX25lc3RlZF9lbnVtICgxLCB1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpGT08pOworICBtZXNzYWdlLT5zZXRfcmVwZWF0ZWRfZm9yZWlnbl9lbnVtKDEsIHVuaXR0ZXN0OjpGT1JFSUdOX0ZPTyAgICAgICk7CisgIG1lc3NhZ2UtPnNldF9yZXBlYXRlZF9pbXBvcnRfZW51bSAoMSwgdW5pdHRlc3RfaW1wb3J0OjpJTVBPUlRfRk9PKTsKKworI2lmbmRlZiBQUk9UT0JVRl9URVNUX05PX0RFU0NSSVBUT1JTCisgIG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+U2V0UmVwZWF0ZWRTdHJpbmcoCisgICAgbWVzc2FnZSwKKyAgICBtZXNzYWdlLT5HZXREZXNjcmlwdG9yKCktPkZpbmRGaWVsZEJ5TmFtZSgicmVwZWF0ZWRfc3RyaW5nX3BpZWNlIiksCisgICAgMSwgIjUyNCIpOworICBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlNldFJlcGVhdGVkU3RyaW5nKAorICAgIG1lc3NhZ2UsCisgICAgbWVzc2FnZS0+R2V0RGVzY3JpcHRvcigpLT5GaW5kRmllbGRCeU5hbWUoInJlcGVhdGVkX2NvcmQiKSwKKyAgICAxLCAiNTI1Iik7CisjZW5kaWYgIC8vICFQUk9UT0JVRl9URVNUX05PX0RFU0NSSVBUT1JTCit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQordm9pZCBUZXN0VXRpbDo6U2V0T25lb2ZGaWVsZHModW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyogbWVzc2FnZSkgeworICBtZXNzYWdlLT5zZXRfb25lb2ZfdWludDMyKDYwMSk7CisgIG1lc3NhZ2UtPm11dGFibGVfb25lb2ZfbmVzdGVkX21lc3NhZ2UoKS0+c2V0X2JiKDYwMik7CisgIG1lc3NhZ2UtPnNldF9vbmVvZl9zdHJpbmcoIjYwMyIpOworICBtZXNzYWdlLT5zZXRfb25lb2ZfYnl0ZXMoIjYwNCIpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3ZvaWQgVGVzdFV0aWw6OkV4cGVjdEFsbEZpZWxkc1NldChjb25zdCB1bml0dGVzdDo6VGVzdEFsbFR5cGVzJiBtZXNzYWdlKSB7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX2ludDMyICAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vcHRpb25hbF9pbnQ2NCAgICgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfb3B0aW9uYWxfdWludDMyICAoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX3VpbnQ2NCAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vcHRpb25hbF9zaW50MzIgICgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfb3B0aW9uYWxfc2ludDY0ICAoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX2ZpeGVkMzIgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vcHRpb25hbF9maXhlZDY0ICgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfb3B0aW9uYWxfc2ZpeGVkMzIoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX3NmaXhlZDY0KCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vcHRpb25hbF9mbG9hdCAgICgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfb3B0aW9uYWxfZG91YmxlICAoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX2Jvb2wgICAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vcHRpb25hbF9zdHJpbmcgICgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfb3B0aW9uYWxfYnl0ZXMgICAoKSk7CisKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfb3B0aW9uYWxncm91cCAgICAgICAgICAgICAgICAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSAgICAgICAoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSAgICAgICgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfb3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgICAgICAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX2xhenlfbWVzc2FnZSAgICAgICAgICgpKTsKKworICBFWFBFQ1RfVFJVRShtZXNzYWdlLm9wdGlvbmFsZ3JvdXAgICAgICAgICAgICAgICAgICgpLmhhc19hKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlICAgICAgICgpLmhhc19iYigpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5vcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgICAgICAoKS5oYXNfYygpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5vcHRpb25hbF9pbXBvcnRfbWVzc2FnZSAgICAgICAoKS5oYXNfZCgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5vcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UoKS5oYXNfZSgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5vcHRpb25hbF9sYXp5X21lc3NhZ2UgICAgICAgICAoKS5oYXNfYmIoKSk7CisKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfb3B0aW9uYWxfbmVzdGVkX2VudW0gKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vcHRpb25hbF9mb3JlaWduX2VudW0oKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX2ltcG9ydF9lbnVtICgpKTsKKworI2lmbmRlZiBQUk9UT0JVRl9URVNUX05PX0RFU0NSSVBUT1JTCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX3N0cmluZ19waWVjZSgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfb3B0aW9uYWxfY29yZCgpKTsKKyNlbmRpZgorCisgIEVYUEVDVF9FUSgxMDEgICwgbWVzc2FnZS5vcHRpb25hbF9pbnQzMiAgICgpKTsKKyAgRVhQRUNUX0VRKDEwMiAgLCBtZXNzYWdlLm9wdGlvbmFsX2ludDY0ICAgKCkpOworICBFWFBFQ1RfRVEoMTAzICAsIG1lc3NhZ2Uub3B0aW9uYWxfdWludDMyICAoKSk7CisgIEVYUEVDVF9FUSgxMDQgICwgbWVzc2FnZS5vcHRpb25hbF91aW50NjQgICgpKTsKKyAgRVhQRUNUX0VRKDEwNSAgLCBtZXNzYWdlLm9wdGlvbmFsX3NpbnQzMiAgKCkpOworICBFWFBFQ1RfRVEoMTA2ICAsIG1lc3NhZ2Uub3B0aW9uYWxfc2ludDY0ICAoKSk7CisgIEVYUEVDVF9FUSgxMDcgICwgbWVzc2FnZS5vcHRpb25hbF9maXhlZDMyICgpKTsKKyAgRVhQRUNUX0VRKDEwOCAgLCBtZXNzYWdlLm9wdGlvbmFsX2ZpeGVkNjQgKCkpOworICBFWFBFQ1RfRVEoMTA5ICAsIG1lc3NhZ2Uub3B0aW9uYWxfc2ZpeGVkMzIoKSk7CisgIEVYUEVDVF9FUSgxMTAgICwgbWVzc2FnZS5vcHRpb25hbF9zZml4ZWQ2NCgpKTsKKyAgRVhQRUNUX0VRKDExMSAgLCBtZXNzYWdlLm9wdGlvbmFsX2Zsb2F0ICAgKCkpOworICBFWFBFQ1RfRVEoMTEyICAsIG1lc3NhZ2Uub3B0aW9uYWxfZG91YmxlICAoKSk7CisgIEVYUEVDVF9UUlVFKCAgICAgbWVzc2FnZS5vcHRpb25hbF9ib29sICAgICgpKTsKKyAgRVhQRUNUX0VRKCIxMTUiLCBtZXNzYWdlLm9wdGlvbmFsX3N0cmluZyAgKCkpOworICBFWFBFQ1RfRVEoIjExNiIsIG1lc3NhZ2Uub3B0aW9uYWxfYnl0ZXMgICAoKSk7CisKKyAgRVhQRUNUX0VRKDExNywgbWVzc2FnZS5vcHRpb25hbGdyb3VwICAgICAgICAgICAgICAgICAgKCkuYSgpKTsKKyAgRVhQRUNUX0VRKDExOCwgbWVzc2FnZS5vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSAgICAgICAgKCkuYmIoKSk7CisgIEVYUEVDVF9FUSgxMTksIG1lc3NhZ2Uub3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlICAgICAgICgpLmMoKSk7CisgIEVYUEVDVF9FUSgxMjAsIG1lc3NhZ2Uub3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgICAgICAgICgpLmQoKSk7CisgIEVYUEVDVF9FUSgxMjYsIG1lc3NhZ2Uub3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlICgpLmUoKSk7CisgIEVYUEVDVF9FUSgxMjcsIG1lc3NhZ2Uub3B0aW9uYWxfbGF6eV9tZXNzYWdlICAgICAgICAgICgpLmJiKCkpOworCisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpCQVosIG1lc3NhZ2Uub3B0aW9uYWxfbmVzdGVkX2VudW0gKCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fQkFaICAgICAgLCBtZXNzYWdlLm9wdGlvbmFsX2ZvcmVpZ25fZW51bSgpKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0X2ltcG9ydDo6SU1QT1JUX0JBWiwgbWVzc2FnZS5vcHRpb25hbF9pbXBvcnRfZW51bSAoKSk7CisKKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ludDMyX3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ludDY0X3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3VpbnQzMl9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3VpbnQ2NF9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3NpbnQzMl9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3NpbnQ2NF9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ZpeGVkMzJfc2l6ZSAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ZpeGVkNjRfc2l6ZSAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3NmaXhlZDMyX3NpemUoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3NmaXhlZDY0X3NpemUoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2Zsb2F0X3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2RvdWJsZV9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2Jvb2xfc2l6ZSAgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3N0cmluZ19zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2J5dGVzX3NpemUgICAoKSk7CisKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRncm91cF9zaXplICAgICAgICAgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX3NpemUgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2Vfc2l6ZSgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2Vfc2l6ZSAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2xhenlfbWVzc2FnZV9zaXplICAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfZW51bV9zaXplICAgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9lbnVtX3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9lbnVtX3NpemUgICAgKCkpOworCisjaWZuZGVmIFBST1RPQlVGX1RFU1RfTk9fREVTQ1JJUFRPUlMKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nX3BpZWNlX3NpemUoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2NvcmRfc2l6ZSgpKTsKKyNlbmRpZgorCisgIEVYUEVDVF9FUSgyMDEgICwgbWVzc2FnZS5yZXBlYXRlZF9pbnQzMiAgICgwKSk7CisgIEVYUEVDVF9FUSgyMDIgICwgbWVzc2FnZS5yZXBlYXRlZF9pbnQ2NCAgICgwKSk7CisgIEVYUEVDVF9FUSgyMDMgICwgbWVzc2FnZS5yZXBlYXRlZF91aW50MzIgICgwKSk7CisgIEVYUEVDVF9FUSgyMDQgICwgbWVzc2FnZS5yZXBlYXRlZF91aW50NjQgICgwKSk7CisgIEVYUEVDVF9FUSgyMDUgICwgbWVzc2FnZS5yZXBlYXRlZF9zaW50MzIgICgwKSk7CisgIEVYUEVDVF9FUSgyMDYgICwgbWVzc2FnZS5yZXBlYXRlZF9zaW50NjQgICgwKSk7CisgIEVYUEVDVF9FUSgyMDcgICwgbWVzc2FnZS5yZXBlYXRlZF9maXhlZDMyICgwKSk7CisgIEVYUEVDVF9FUSgyMDggICwgbWVzc2FnZS5yZXBlYXRlZF9maXhlZDY0ICgwKSk7CisgIEVYUEVDVF9FUSgyMDkgICwgbWVzc2FnZS5yZXBlYXRlZF9zZml4ZWQzMigwKSk7CisgIEVYUEVDVF9FUSgyMTAgICwgbWVzc2FnZS5yZXBlYXRlZF9zZml4ZWQ2NCgwKSk7CisgIEVYUEVDVF9FUSgyMTEgICwgbWVzc2FnZS5yZXBlYXRlZF9mbG9hdCAgICgwKSk7CisgIEVYUEVDVF9FUSgyMTIgICwgbWVzc2FnZS5yZXBlYXRlZF9kb3VibGUgICgwKSk7CisgIEVYUEVDVF9UUlVFKCAgICAgbWVzc2FnZS5yZXBlYXRlZF9ib29sICAgICgwKSk7CisgIEVYUEVDVF9FUSgiMjE1IiwgbWVzc2FnZS5yZXBlYXRlZF9zdHJpbmcgICgwKSk7CisgIEVYUEVDVF9FUSgiMjE2IiwgbWVzc2FnZS5yZXBlYXRlZF9ieXRlcyAgICgwKSk7CisKKyAgRVhQRUNUX0VRKDIxNywgbWVzc2FnZS5yZXBlYXRlZGdyb3VwICAgICAgICAgICAoMCkuYSgpKTsKKyAgRVhQRUNUX0VRKDIxOCwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSAoMCkuYmIoKSk7CisgIEVYUEVDVF9FUSgyMTksIG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKDApLmMoKSk7CisgIEVYUEVDVF9FUSgyMjAsIG1lc3NhZ2UucmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgKDApLmQoKSk7CisgIEVYUEVDVF9FUSgyMjcsIG1lc3NhZ2UucmVwZWF0ZWRfbGF6eV9tZXNzYWdlICAgKDApLmJiKCkpOworCisKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkJBUiwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfZW51bSAoMCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fQkFSICAgICAgLCBtZXNzYWdlLnJlcGVhdGVkX2ZvcmVpZ25fZW51bSgwKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9CQVIsIG1lc3NhZ2UucmVwZWF0ZWRfaW1wb3J0X2VudW0gKDApKTsKKworICBFWFBFQ1RfRVEoMzAxICAsIG1lc3NhZ2UucmVwZWF0ZWRfaW50MzIgICAoMSkpOworICBFWFBFQ1RfRVEoMzAyICAsIG1lc3NhZ2UucmVwZWF0ZWRfaW50NjQgICAoMSkpOworICBFWFBFQ1RfRVEoMzAzICAsIG1lc3NhZ2UucmVwZWF0ZWRfdWludDMyICAoMSkpOworICBFWFBFQ1RfRVEoMzA0ICAsIG1lc3NhZ2UucmVwZWF0ZWRfdWludDY0ICAoMSkpOworICBFWFBFQ1RfRVEoMzA1ICAsIG1lc3NhZ2UucmVwZWF0ZWRfc2ludDMyICAoMSkpOworICBFWFBFQ1RfRVEoMzA2ICAsIG1lc3NhZ2UucmVwZWF0ZWRfc2ludDY0ICAoMSkpOworICBFWFBFQ1RfRVEoMzA3ICAsIG1lc3NhZ2UucmVwZWF0ZWRfZml4ZWQzMiAoMSkpOworICBFWFBFQ1RfRVEoMzA4ICAsIG1lc3NhZ2UucmVwZWF0ZWRfZml4ZWQ2NCAoMSkpOworICBFWFBFQ1RfRVEoMzA5ICAsIG1lc3NhZ2UucmVwZWF0ZWRfc2ZpeGVkMzIoMSkpOworICBFWFBFQ1RfRVEoMzEwICAsIG1lc3NhZ2UucmVwZWF0ZWRfc2ZpeGVkNjQoMSkpOworICBFWFBFQ1RfRVEoMzExICAsIG1lc3NhZ2UucmVwZWF0ZWRfZmxvYXQgICAoMSkpOworICBFWFBFQ1RfRVEoMzEyICAsIG1lc3NhZ2UucmVwZWF0ZWRfZG91YmxlICAoMSkpOworICBFWFBFQ1RfRkFMU0UoICAgIG1lc3NhZ2UucmVwZWF0ZWRfYm9vbCAgICAoMSkpOworICBFWFBFQ1RfRVEoIjMxNSIsIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nICAoMSkpOworICBFWFBFQ1RfRVEoIjMxNiIsIG1lc3NhZ2UucmVwZWF0ZWRfYnl0ZXMgICAoMSkpOworCisgIEVYUEVDVF9FUSgzMTcsIG1lc3NhZ2UucmVwZWF0ZWRncm91cCAgICAgICAgICAgKDEpLmEoKSk7CisgIEVYUEVDVF9FUSgzMTgsIG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgKDEpLmJiKCkpOworICBFWFBFQ1RfRVEoMzE5LCBtZXNzYWdlLnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSgxKS5jKCkpOworICBFWFBFQ1RfRVEoMzIwLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlICgxKS5kKCkpOworICBFWFBFQ1RfRVEoMzI3LCBtZXNzYWdlLnJlcGVhdGVkX2xhenlfbWVzc2FnZSAgICgxKS5iYigpKTsKKworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6QkFaLCBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9lbnVtICgxKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9SRUlHTl9CQVogICAgICAsIG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9lbnVtKDEpKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0X2ltcG9ydDo6SU1QT1JUX0JBWiwgbWVzc2FnZS5yZXBlYXRlZF9pbXBvcnRfZW51bSAoMSkpOworCisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X2ludDMyICAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X2ludDY0ICAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X3VpbnQzMiAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X3VpbnQ2NCAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X3NpbnQzMiAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X3NpbnQ2NCAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X2ZpeGVkMzIgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X2ZpeGVkNjQgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X3NmaXhlZDMyKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X3NmaXhlZDY0KCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X2Zsb2F0ICAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X2RvdWJsZSAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X2Jvb2wgICAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X3N0cmluZyAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X2J5dGVzICAgKCkpOworCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfbmVzdGVkX2VudW0gKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X2ZvcmVpZ25fZW51bSgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfZGVmYXVsdF9pbXBvcnRfZW51bSAoKSk7CisKKworICBFWFBFQ1RfRVEoNDAxICAsIG1lc3NhZ2UuZGVmYXVsdF9pbnQzMiAgICgpKTsKKyAgRVhQRUNUX0VRKDQwMiAgLCBtZXNzYWdlLmRlZmF1bHRfaW50NjQgICAoKSk7CisgIEVYUEVDVF9FUSg0MDMgICwgbWVzc2FnZS5kZWZhdWx0X3VpbnQzMiAgKCkpOworICBFWFBFQ1RfRVEoNDA0ICAsIG1lc3NhZ2UuZGVmYXVsdF91aW50NjQgICgpKTsKKyAgRVhQRUNUX0VRKDQwNSAgLCBtZXNzYWdlLmRlZmF1bHRfc2ludDMyICAoKSk7CisgIEVYUEVDVF9FUSg0MDYgICwgbWVzc2FnZS5kZWZhdWx0X3NpbnQ2NCAgKCkpOworICBFWFBFQ1RfRVEoNDA3ICAsIG1lc3NhZ2UuZGVmYXVsdF9maXhlZDMyICgpKTsKKyAgRVhQRUNUX0VRKDQwOCAgLCBtZXNzYWdlLmRlZmF1bHRfZml4ZWQ2NCAoKSk7CisgIEVYUEVDVF9FUSg0MDkgICwgbWVzc2FnZS5kZWZhdWx0X3NmaXhlZDMyKCkpOworICBFWFBFQ1RfRVEoNDEwICAsIG1lc3NhZ2UuZGVmYXVsdF9zZml4ZWQ2NCgpKTsKKyAgRVhQRUNUX0VRKDQxMSAgLCBtZXNzYWdlLmRlZmF1bHRfZmxvYXQgICAoKSk7CisgIEVYUEVDVF9FUSg0MTIgICwgbWVzc2FnZS5kZWZhdWx0X2RvdWJsZSAgKCkpOworICBFWFBFQ1RfRkFMU0UoICAgIG1lc3NhZ2UuZGVmYXVsdF9ib29sICAgICgpKTsKKyAgRVhQRUNUX0VRKCI0MTUiLCBtZXNzYWdlLmRlZmF1bHRfc3RyaW5nICAoKSk7CisgIEVYUEVDVF9FUSgiNDE2IiwgbWVzc2FnZS5kZWZhdWx0X2J5dGVzICAgKCkpOworCisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpGT08sIG1lc3NhZ2UuZGVmYXVsdF9uZXN0ZWRfZW51bSAoKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9SRUlHTl9GT08gICAgICAsIG1lc3NhZ2UuZGVmYXVsdF9mb3JlaWduX2VudW0oKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9GT08sIG1lc3NhZ2UuZGVmYXVsdF9pbXBvcnRfZW51bSAoKSk7CisKKworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb25lb2ZfdWludDMyICAgICAgICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vbmVvZl9uZXN0ZWRfbWVzc2FnZSgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29uZW9mX3N0cmluZyAgICAgICAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vbmVvZl9ieXRlcyAgICAgICAgICAoKSk7CisKKyAgRVhQRUNUX0VRKCI2MDQiLCBtZXNzYWdlLm9uZW9mX2J5dGVzKCkpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3ZvaWQgVGVzdFV0aWw6OkV4cGVjdENsZWFyKGNvbnN0IHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMmIG1lc3NhZ2UpIHsKKyAgLy8gaGFzX2JsYWgoKSBzaG91bGQgaW5pdGlhbGx5IGJlIGZhbHNlIGZvciBhbGwgb3B0aW9uYWwgZmllbGRzLgorICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb3B0aW9uYWxfaW50MzIgICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9pbnQ2NCAgICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX3VpbnQzMiAgKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb3B0aW9uYWxfdWludDY0ICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9zaW50MzIgICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX3NpbnQ2NCAgKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb3B0aW9uYWxfZml4ZWQzMiAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9maXhlZDY0ICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX3NmaXhlZDMyKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb3B0aW9uYWxfc2ZpeGVkNjQoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9mbG9hdCAgICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX2RvdWJsZSAgKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb3B0aW9uYWxfYm9vbCAgICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9zdHJpbmcgICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX2J5dGVzICAgKCkpOworCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbGdyb3VwICAgICAgICAgICAgICAgICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSAgICAgICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgICAgICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9pbXBvcnRfbWVzc2FnZSAgICAgICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9sYXp5X21lc3NhZ2UgICAgICAgICAoKSk7CisKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX25lc3RlZF9lbnVtICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX2ZvcmVpZ25fZW51bSgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX2ltcG9ydF9lbnVtICgpKTsKKworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb3B0aW9uYWxfc3RyaW5nX3BpZWNlKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb3B0aW9uYWxfY29yZCgpKTsKKworICAvLyBPcHRpb25hbCBmaWVsZHMgd2l0aG91dCBkZWZhdWx0cyBhcmUgc2V0IHRvIHplcm8gb3Igc29tZXRoaW5nIGxpa2UgaXQuCisgIEVYUEVDVF9FUSgwICAgICwgbWVzc2FnZS5vcHRpb25hbF9pbnQzMiAgICgpKTsKKyAgRVhQRUNUX0VRKDAgICAgLCBtZXNzYWdlLm9wdGlvbmFsX2ludDY0ICAgKCkpOworICBFWFBFQ1RfRVEoMCAgICAsIG1lc3NhZ2Uub3B0aW9uYWxfdWludDMyICAoKSk7CisgIEVYUEVDVF9FUSgwICAgICwgbWVzc2FnZS5vcHRpb25hbF91aW50NjQgICgpKTsKKyAgRVhQRUNUX0VRKDAgICAgLCBtZXNzYWdlLm9wdGlvbmFsX3NpbnQzMiAgKCkpOworICBFWFBFQ1RfRVEoMCAgICAsIG1lc3NhZ2Uub3B0aW9uYWxfc2ludDY0ICAoKSk7CisgIEVYUEVDVF9FUSgwICAgICwgbWVzc2FnZS5vcHRpb25hbF9maXhlZDMyICgpKTsKKyAgRVhQRUNUX0VRKDAgICAgLCBtZXNzYWdlLm9wdGlvbmFsX2ZpeGVkNjQgKCkpOworICBFWFBFQ1RfRVEoMCAgICAsIG1lc3NhZ2Uub3B0aW9uYWxfc2ZpeGVkMzIoKSk7CisgIEVYUEVDVF9FUSgwICAgICwgbWVzc2FnZS5vcHRpb25hbF9zZml4ZWQ2NCgpKTsKKyAgRVhQRUNUX0VRKDAgICAgLCBtZXNzYWdlLm9wdGlvbmFsX2Zsb2F0ICAgKCkpOworICBFWFBFQ1RfRVEoMCAgICAsIG1lc3NhZ2Uub3B0aW9uYWxfZG91YmxlICAoKSk7CisgIEVYUEVDVF9GQUxTRSggICAgbWVzc2FnZS5vcHRpb25hbF9ib29sICAgICgpKTsKKyAgRVhQRUNUX0VRKCIiICAgLCBtZXNzYWdlLm9wdGlvbmFsX3N0cmluZyAgKCkpOworICBFWFBFQ1RfRVEoIiIgICAsIG1lc3NhZ2Uub3B0aW9uYWxfYnl0ZXMgICAoKSk7CisKKyAgLy8gRW1iZWRkZWQgbWVzc2FnZXMgc2hvdWxkIGFsc28gYmUgY2xlYXIuCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLm9wdGlvbmFsZ3JvdXAgICAgICAgICAgICAgICAgICgpLmhhc19hKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSAgICAgICAoKS5oYXNfYmIoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLm9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSAgICAgICgpLmhhc19jKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5vcHRpb25hbF9pbXBvcnRfbWVzc2FnZSAgICAgICAoKS5oYXNfZCgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2Uub3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlKCkuaGFzX2UoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLm9wdGlvbmFsX2xhenlfbWVzc2FnZSAgICAgICAgICgpLmhhc19iYigpKTsKKworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5vcHRpb25hbGdyb3VwICAgICAgICAgICAgICAgICAoKS5hKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSAgICAgICAoKS5iYigpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2Uub3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlICAgICAgKCkuYygpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2Uub3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgICAgICAgKCkuZCgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2Uub3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlKCkuZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2Uub3B0aW9uYWxfbGF6eV9tZXNzYWdlICAgICAgICAgKCkuYmIoKSk7CisKKyAgLy8gRW51bXMgd2l0aG91dCBkZWZhdWx0cyBhcmUgc2V0IHRvIHRoZSBmaXJzdCB2YWx1ZSBpbiB0aGUgZW51bS4KKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkZPTywgbWVzc2FnZS5vcHRpb25hbF9uZXN0ZWRfZW51bSAoKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9SRUlHTl9GT08gICAgICAsIG1lc3NhZ2Uub3B0aW9uYWxfZm9yZWlnbl9lbnVtKCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3RfaW1wb3J0OjpJTVBPUlRfRk9PLCBtZXNzYWdlLm9wdGlvbmFsX2ltcG9ydF9lbnVtICgpKTsKKworCisgIC8vIFJlcGVhdGVkIGZpZWxkcyBhcmUgZW1wdHkuCisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX2ludDMyX3NpemUgICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX2ludDY0X3NpemUgICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX3VpbnQzMl9zaXplICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX3VpbnQ2NF9zaXplICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX3NpbnQzMl9zaXplICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX3NpbnQ2NF9zaXplICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX2ZpeGVkMzJfc2l6ZSAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX2ZpeGVkNjRfc2l6ZSAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX3NmaXhlZDMyX3NpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX3NmaXhlZDY0X3NpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX2Zsb2F0X3NpemUgICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX2RvdWJsZV9zaXplICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX2Jvb2xfc2l6ZSAgICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX3N0cmluZ19zaXplICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX2J5dGVzX3NpemUgICAoKSk7CisKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucmVwZWF0ZWRncm91cF9zaXplICAgICAgICAgICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX3NpemUgKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2Vfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2Vfc2l6ZSAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX2xhenlfbWVzc2FnZV9zaXplICAgKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfZW51bV9zaXplICAgICgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9lbnVtX3NpemUgICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9lbnVtX3NpemUgICAgKCkpOworCisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX3N0cmluZ19waWVjZV9zaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5yZXBlYXRlZF9jb3JkX3NpemUoKSk7CisKKyAgLy8gaGFzX2JsYWgoKSBzaG91bGQgYWxzbyBiZSBmYWxzZSBmb3IgYWxsIGRlZmF1bHQgZmllbGRzLgorICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZGVmYXVsdF9pbnQzMiAgICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfaW50NjQgICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19kZWZhdWx0X3VpbnQzMiAgKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZGVmYXVsdF91aW50NjQgICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfc2ludDMyICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19kZWZhdWx0X3NpbnQ2NCAgKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZGVmYXVsdF9maXhlZDMyICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfZml4ZWQ2NCAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19kZWZhdWx0X3NmaXhlZDMyKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZGVmYXVsdF9zZml4ZWQ2NCgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfZmxvYXQgICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19kZWZhdWx0X2RvdWJsZSAgKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZGVmYXVsdF9ib29sICAgICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfc3RyaW5nICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19kZWZhdWx0X2J5dGVzICAgKCkpOworCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19kZWZhdWx0X25lc3RlZF9lbnVtICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfZm9yZWlnbl9lbnVtKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZGVmYXVsdF9pbXBvcnRfZW51bSAoKSk7CisKKworICAvLyBGaWVsZHMgd2l0aCBkZWZhdWx0cyBoYXZlIHRoZWlyIGRlZmF1bHQgdmFsdWVzIChkdWgpLgorICBFWFBFQ1RfRVEoIDQxICAgICwgbWVzc2FnZS5kZWZhdWx0X2ludDMyICAgKCkpOworICBFWFBFQ1RfRVEoIDQyICAgICwgbWVzc2FnZS5kZWZhdWx0X2ludDY0ICAgKCkpOworICBFWFBFQ1RfRVEoIDQzICAgICwgbWVzc2FnZS5kZWZhdWx0X3VpbnQzMiAgKCkpOworICBFWFBFQ1RfRVEoIDQ0ICAgICwgbWVzc2FnZS5kZWZhdWx0X3VpbnQ2NCAgKCkpOworICBFWFBFQ1RfRVEoLTQ1ICAgICwgbWVzc2FnZS5kZWZhdWx0X3NpbnQzMiAgKCkpOworICBFWFBFQ1RfRVEoIDQ2ICAgICwgbWVzc2FnZS5kZWZhdWx0X3NpbnQ2NCAgKCkpOworICBFWFBFQ1RfRVEoIDQ3ICAgICwgbWVzc2FnZS5kZWZhdWx0X2ZpeGVkMzIgKCkpOworICBFWFBFQ1RfRVEoIDQ4ICAgICwgbWVzc2FnZS5kZWZhdWx0X2ZpeGVkNjQgKCkpOworICBFWFBFQ1RfRVEoIDQ5ICAgICwgbWVzc2FnZS5kZWZhdWx0X3NmaXhlZDMyKCkpOworICBFWFBFQ1RfRVEoLTUwICAgICwgbWVzc2FnZS5kZWZhdWx0X3NmaXhlZDY0KCkpOworICBFWFBFQ1RfRVEoIDUxLjUgICwgbWVzc2FnZS5kZWZhdWx0X2Zsb2F0ICAgKCkpOworICBFWFBFQ1RfRVEoIDUyZTMgICwgbWVzc2FnZS5kZWZhdWx0X2RvdWJsZSAgKCkpOworICBFWFBFQ1RfVFJVRSggICAgICAgbWVzc2FnZS5kZWZhdWx0X2Jvb2wgICAgKCkpOworICBFWFBFQ1RfRVEoImhlbGxvIiwgbWVzc2FnZS5kZWZhdWx0X3N0cmluZyAgKCkpOworICBFWFBFQ1RfRVEoIndvcmxkIiwgbWVzc2FnZS5kZWZhdWx0X2J5dGVzICAgKCkpOworCisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpCQVIsIG1lc3NhZ2UuZGVmYXVsdF9uZXN0ZWRfZW51bSAoKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9SRUlHTl9CQVIgICAgICAsIG1lc3NhZ2UuZGVmYXVsdF9mb3JlaWduX2VudW0oKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9CQVIsIG1lc3NhZ2UuZGVmYXVsdF9pbXBvcnRfZW51bSAoKSk7CisKKworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb25lb2ZfdWludDMyICAgICAgICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vbmVvZl9uZXN0ZWRfbWVzc2FnZSgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29uZW9mX3N0cmluZyAgICAgICAgKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb25lb2ZfYnl0ZXMgICAgICAgICAoKSk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBUZXN0VXRpbDo6RXhwZWN0UmVwZWF0ZWRGaWVsZHNNb2RpZmllZCgKKyAgICBjb25zdCB1bml0dGVzdDo6VGVzdEFsbFR5cGVzJiBtZXNzYWdlKSB7CisgIC8vIE1vZGlmeVJlcGVhdGVkRmllbGRzIG9ubHkgc2V0cyB0aGUgc2Vjb25kIHJlcGVhdGVkIGVsZW1lbnQgb2YgZWFjaAorICAvLyBmaWVsZC4gIEluIGFkZGl0aW9uIHRvIHZlcmlmeWluZyB0aGlzLCB3ZSBhbHNvIHZlcmlmeSB0aGF0IHRoZSBmaXJzdAorICAvLyBlbGVtZW50IGFuZCBzaXplIHdlcmUgKm5vdCogbW9kaWZpZWQuCisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ludDMyX3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ludDY0X3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3VpbnQzMl9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3VpbnQ2NF9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3NpbnQzMl9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3NpbnQ2NF9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ZpeGVkMzJfc2l6ZSAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ZpeGVkNjRfc2l6ZSAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3NmaXhlZDMyX3NpemUoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3NmaXhlZDY0X3NpemUoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2Zsb2F0X3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2RvdWJsZV9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2Jvb2xfc2l6ZSAgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3N0cmluZ19zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2J5dGVzX3NpemUgICAoKSk7CisKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRncm91cF9zaXplICAgICAgICAgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX3NpemUgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2Vfc2l6ZSgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2Vfc2l6ZSAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2xhenlfbWVzc2FnZV9zaXplICAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfZW51bV9zaXplICAgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9lbnVtX3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9lbnVtX3NpemUgICAgKCkpOworCisjaWZuZGVmIFBST1RPQlVGX1RFU1RfTk9fREVTQ1JJUFRPUlMKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nX3BpZWNlX3NpemUoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2NvcmRfc2l6ZSgpKTsKKyNlbmRpZgorCisgIEVYUEVDVF9FUSgyMDEgICwgbWVzc2FnZS5yZXBlYXRlZF9pbnQzMiAgICgwKSk7CisgIEVYUEVDVF9FUSgyMDIgICwgbWVzc2FnZS5yZXBlYXRlZF9pbnQ2NCAgICgwKSk7CisgIEVYUEVDVF9FUSgyMDMgICwgbWVzc2FnZS5yZXBlYXRlZF91aW50MzIgICgwKSk7CisgIEVYUEVDVF9FUSgyMDQgICwgbWVzc2FnZS5yZXBlYXRlZF91aW50NjQgICgwKSk7CisgIEVYUEVDVF9FUSgyMDUgICwgbWVzc2FnZS5yZXBlYXRlZF9zaW50MzIgICgwKSk7CisgIEVYUEVDVF9FUSgyMDYgICwgbWVzc2FnZS5yZXBlYXRlZF9zaW50NjQgICgwKSk7CisgIEVYUEVDVF9FUSgyMDcgICwgbWVzc2FnZS5yZXBlYXRlZF9maXhlZDMyICgwKSk7CisgIEVYUEVDVF9FUSgyMDggICwgbWVzc2FnZS5yZXBlYXRlZF9maXhlZDY0ICgwKSk7CisgIEVYUEVDVF9FUSgyMDkgICwgbWVzc2FnZS5yZXBlYXRlZF9zZml4ZWQzMigwKSk7CisgIEVYUEVDVF9FUSgyMTAgICwgbWVzc2FnZS5yZXBlYXRlZF9zZml4ZWQ2NCgwKSk7CisgIEVYUEVDVF9FUSgyMTEgICwgbWVzc2FnZS5yZXBlYXRlZF9mbG9hdCAgICgwKSk7CisgIEVYUEVDVF9FUSgyMTIgICwgbWVzc2FnZS5yZXBlYXRlZF9kb3VibGUgICgwKSk7CisgIEVYUEVDVF9UUlVFKCAgICAgbWVzc2FnZS5yZXBlYXRlZF9ib29sICAgICgwKSk7CisgIEVYUEVDVF9FUSgiMjE1IiwgbWVzc2FnZS5yZXBlYXRlZF9zdHJpbmcgICgwKSk7CisgIEVYUEVDVF9FUSgiMjE2IiwgbWVzc2FnZS5yZXBlYXRlZF9ieXRlcyAgICgwKSk7CisKKyAgRVhQRUNUX0VRKDIxNywgbWVzc2FnZS5yZXBlYXRlZGdyb3VwICAgICAgICAgICAoMCkuYSgpKTsKKyAgRVhQRUNUX0VRKDIxOCwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSAoMCkuYmIoKSk7CisgIEVYUEVDVF9FUSgyMTksIG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKDApLmMoKSk7CisgIEVYUEVDVF9FUSgyMjAsIG1lc3NhZ2UucmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgKDApLmQoKSk7CisgIEVYUEVDVF9FUSgyMjcsIG1lc3NhZ2UucmVwZWF0ZWRfbGF6eV9tZXNzYWdlICAgKDApLmJiKCkpOworCisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpCQVIsIG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX2VudW0gKDApKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0JBUiAgICAgICwgbWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX2VudW0oMCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3RfaW1wb3J0OjpJTVBPUlRfQkFSLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9lbnVtICgwKSk7CisKKworICAvLyBBY3R1YWxseSB2ZXJpZnkgdGhlIHNlY29uZCAobW9kaWZpZWQpIGVsZW1lbnRzIG5vdy4KKyAgRVhQRUNUX0VRKDUwMSAgLCBtZXNzYWdlLnJlcGVhdGVkX2ludDMyICAgKDEpKTsKKyAgRVhQRUNUX0VRKDUwMiAgLCBtZXNzYWdlLnJlcGVhdGVkX2ludDY0ICAgKDEpKTsKKyAgRVhQRUNUX0VRKDUwMyAgLCBtZXNzYWdlLnJlcGVhdGVkX3VpbnQzMiAgKDEpKTsKKyAgRVhQRUNUX0VRKDUwNCAgLCBtZXNzYWdlLnJlcGVhdGVkX3VpbnQ2NCAgKDEpKTsKKyAgRVhQRUNUX0VRKDUwNSAgLCBtZXNzYWdlLnJlcGVhdGVkX3NpbnQzMiAgKDEpKTsKKyAgRVhQRUNUX0VRKDUwNiAgLCBtZXNzYWdlLnJlcGVhdGVkX3NpbnQ2NCAgKDEpKTsKKyAgRVhQRUNUX0VRKDUwNyAgLCBtZXNzYWdlLnJlcGVhdGVkX2ZpeGVkMzIgKDEpKTsKKyAgRVhQRUNUX0VRKDUwOCAgLCBtZXNzYWdlLnJlcGVhdGVkX2ZpeGVkNjQgKDEpKTsKKyAgRVhQRUNUX0VRKDUwOSAgLCBtZXNzYWdlLnJlcGVhdGVkX3NmaXhlZDMyKDEpKTsKKyAgRVhQRUNUX0VRKDUxMCAgLCBtZXNzYWdlLnJlcGVhdGVkX3NmaXhlZDY0KDEpKTsKKyAgRVhQRUNUX0VRKDUxMSAgLCBtZXNzYWdlLnJlcGVhdGVkX2Zsb2F0ICAgKDEpKTsKKyAgRVhQRUNUX0VRKDUxMiAgLCBtZXNzYWdlLnJlcGVhdGVkX2RvdWJsZSAgKDEpKTsKKyAgRVhQRUNUX1RSVUUoICAgICBtZXNzYWdlLnJlcGVhdGVkX2Jvb2wgICAgKDEpKTsKKyAgRVhQRUNUX0VRKCI1MTUiLCBtZXNzYWdlLnJlcGVhdGVkX3N0cmluZyAgKDEpKTsKKyAgRVhQRUNUX0VRKCI1MTYiLCBtZXNzYWdlLnJlcGVhdGVkX2J5dGVzICAgKDEpKTsKKworICBFWFBFQ1RfRVEoNTE3LCBtZXNzYWdlLnJlcGVhdGVkZ3JvdXAgICAgICAgICAgICgxKS5hKCkpOworICBFWFBFQ1RfRVEoNTE4LCBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlICgxKS5iYigpKTsKKyAgRVhQRUNUX0VRKDUxOSwgbWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UoMSkuYygpKTsKKyAgRVhQRUNUX0VRKDUyMCwgbWVzc2FnZS5yZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSAoMSkuZCgpKTsKKyAgRVhQRUNUX0VRKDUyNywgbWVzc2FnZS5yZXBlYXRlZF9sYXp5X21lc3NhZ2UgICAoMSkuYmIoKSk7CisKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkZPTywgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfZW51bSAoMSkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fRk9PICAgICAgLCBtZXNzYWdlLnJlcGVhdGVkX2ZvcmVpZ25fZW51bSgxKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9GT08sIG1lc3NhZ2UucmVwZWF0ZWRfaW1wb3J0X2VudW0gKDEpKTsKKworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3ZvaWQgVGVzdFV0aWw6OlNldFBhY2tlZEZpZWxkcyh1bml0dGVzdDo6VGVzdFBhY2tlZFR5cGVzKiBtZXNzYWdlKSB7CisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfaW50MzIgICAoNjAxKTsKKyAgbWVzc2FnZS0+YWRkX3BhY2tlZF9pbnQ2NCAgICg2MDIpOworICBtZXNzYWdlLT5hZGRfcGFja2VkX3VpbnQzMiAgKDYwMyk7CisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfdWludDY0ICAoNjA0KTsKKyAgbWVzc2FnZS0+YWRkX3BhY2tlZF9zaW50MzIgICg2MDUpOworICBtZXNzYWdlLT5hZGRfcGFja2VkX3NpbnQ2NCAgKDYwNik7CisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfZml4ZWQzMiAoNjA3KTsKKyAgbWVzc2FnZS0+YWRkX3BhY2tlZF9maXhlZDY0ICg2MDgpOworICBtZXNzYWdlLT5hZGRfcGFja2VkX3NmaXhlZDMyKDYwOSk7CisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfc2ZpeGVkNjQoNjEwKTsKKyAgbWVzc2FnZS0+YWRkX3BhY2tlZF9mbG9hdCAgICg2MTEpOworICBtZXNzYWdlLT5hZGRfcGFja2VkX2RvdWJsZSAgKDYxMik7CisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfYm9vbCAgICAodHJ1ZSk7CisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfZW51bSAgICAodW5pdHRlc3Q6OkZPUkVJR05fQkFSKTsKKyAgLy8gYWRkIGEgc2Vjb25kIG9uZSBvZiBlYWNoIGZpZWxkCisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfaW50MzIgICAoNzAxKTsKKyAgbWVzc2FnZS0+YWRkX3BhY2tlZF9pbnQ2NCAgICg3MDIpOworICBtZXNzYWdlLT5hZGRfcGFja2VkX3VpbnQzMiAgKDcwMyk7CisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfdWludDY0ICAoNzA0KTsKKyAgbWVzc2FnZS0+YWRkX3BhY2tlZF9zaW50MzIgICg3MDUpOworICBtZXNzYWdlLT5hZGRfcGFja2VkX3NpbnQ2NCAgKDcwNik7CisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfZml4ZWQzMiAoNzA3KTsKKyAgbWVzc2FnZS0+YWRkX3BhY2tlZF9maXhlZDY0ICg3MDgpOworICBtZXNzYWdlLT5hZGRfcGFja2VkX3NmaXhlZDMyKDcwOSk7CisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfc2ZpeGVkNjQoNzEwKTsKKyAgbWVzc2FnZS0+YWRkX3BhY2tlZF9mbG9hdCAgICg3MTEpOworICBtZXNzYWdlLT5hZGRfcGFja2VkX2RvdWJsZSAgKDcxMik7CisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfYm9vbCAgICAoZmFsc2UpOworICBtZXNzYWdlLT5hZGRfcGFja2VkX2VudW0gICAgKHVuaXR0ZXN0OjpGT1JFSUdOX0JBWik7Cit9CisKK3ZvaWQgVGVzdFV0aWw6OlNldFVucGFja2VkRmllbGRzKHVuaXR0ZXN0OjpUZXN0VW5wYWNrZWRUeXBlcyogbWVzc2FnZSkgeworICAvLyBUaGUgdmFsdWVzIGFwcGxpZWQgaGVyZSBtdXN0IG1hdGNoIHRob3NlIG9mIFNldFBhY2tlZEZpZWxkcy4KKworICBtZXNzYWdlLT5hZGRfdW5wYWNrZWRfaW50MzIgICAoNjAxKTsKKyAgbWVzc2FnZS0+YWRkX3VucGFja2VkX2ludDY0ICAgKDYwMik7CisgIG1lc3NhZ2UtPmFkZF91bnBhY2tlZF91aW50MzIgICg2MDMpOworICBtZXNzYWdlLT5hZGRfdW5wYWNrZWRfdWludDY0ICAoNjA0KTsKKyAgbWVzc2FnZS0+YWRkX3VucGFja2VkX3NpbnQzMiAgKDYwNSk7CisgIG1lc3NhZ2UtPmFkZF91bnBhY2tlZF9zaW50NjQgICg2MDYpOworICBtZXNzYWdlLT5hZGRfdW5wYWNrZWRfZml4ZWQzMiAoNjA3KTsKKyAgbWVzc2FnZS0+YWRkX3VucGFja2VkX2ZpeGVkNjQgKDYwOCk7CisgIG1lc3NhZ2UtPmFkZF91bnBhY2tlZF9zZml4ZWQzMig2MDkpOworICBtZXNzYWdlLT5hZGRfdW5wYWNrZWRfc2ZpeGVkNjQoNjEwKTsKKyAgbWVzc2FnZS0+YWRkX3VucGFja2VkX2Zsb2F0ICAgKDYxMSk7CisgIG1lc3NhZ2UtPmFkZF91bnBhY2tlZF9kb3VibGUgICg2MTIpOworICBtZXNzYWdlLT5hZGRfdW5wYWNrZWRfYm9vbCAgICAodHJ1ZSk7CisgIG1lc3NhZ2UtPmFkZF91bnBhY2tlZF9lbnVtICAgICh1bml0dGVzdDo6Rk9SRUlHTl9CQVIpOworICAvLyBhZGQgYSBzZWNvbmQgb25lIG9mIGVhY2ggZmllbGQKKyAgbWVzc2FnZS0+YWRkX3VucGFja2VkX2ludDMyICAgKDcwMSk7CisgIG1lc3NhZ2UtPmFkZF91bnBhY2tlZF9pbnQ2NCAgICg3MDIpOworICBtZXNzYWdlLT5hZGRfdW5wYWNrZWRfdWludDMyICAoNzAzKTsKKyAgbWVzc2FnZS0+YWRkX3VucGFja2VkX3VpbnQ2NCAgKDcwNCk7CisgIG1lc3NhZ2UtPmFkZF91bnBhY2tlZF9zaW50MzIgICg3MDUpOworICBtZXNzYWdlLT5hZGRfdW5wYWNrZWRfc2ludDY0ICAoNzA2KTsKKyAgbWVzc2FnZS0+YWRkX3VucGFja2VkX2ZpeGVkMzIgKDcwNyk7CisgIG1lc3NhZ2UtPmFkZF91bnBhY2tlZF9maXhlZDY0ICg3MDgpOworICBtZXNzYWdlLT5hZGRfdW5wYWNrZWRfc2ZpeGVkMzIoNzA5KTsKKyAgbWVzc2FnZS0+YWRkX3VucGFja2VkX3NmaXhlZDY0KDcxMCk7CisgIG1lc3NhZ2UtPmFkZF91bnBhY2tlZF9mbG9hdCAgICg3MTEpOworICBtZXNzYWdlLT5hZGRfdW5wYWNrZWRfZG91YmxlICAoNzEyKTsKKyAgbWVzc2FnZS0+YWRkX3VucGFja2VkX2Jvb2wgICAgKGZhbHNlKTsKKyAgbWVzc2FnZS0+YWRkX3VucGFja2VkX2VudW0gICAgKHVuaXR0ZXN0OjpGT1JFSUdOX0JBWik7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBUZXN0VXRpbDo6TW9kaWZ5UGFja2VkRmllbGRzKHVuaXR0ZXN0OjpUZXN0UGFja2VkVHlwZXMqIG1lc3NhZ2UpIHsKKyAgbWVzc2FnZS0+c2V0X3BhY2tlZF9pbnQzMiAgICgxLCA4MDEpOworICBtZXNzYWdlLT5zZXRfcGFja2VkX2ludDY0ICAgKDEsIDgwMik7CisgIG1lc3NhZ2UtPnNldF9wYWNrZWRfdWludDMyICAoMSwgODAzKTsKKyAgbWVzc2FnZS0+c2V0X3BhY2tlZF91aW50NjQgICgxLCA4MDQpOworICBtZXNzYWdlLT5zZXRfcGFja2VkX3NpbnQzMiAgKDEsIDgwNSk7CisgIG1lc3NhZ2UtPnNldF9wYWNrZWRfc2ludDY0ICAoMSwgODA2KTsKKyAgbWVzc2FnZS0+c2V0X3BhY2tlZF9maXhlZDMyICgxLCA4MDcpOworICBtZXNzYWdlLT5zZXRfcGFja2VkX2ZpeGVkNjQgKDEsIDgwOCk7CisgIG1lc3NhZ2UtPnNldF9wYWNrZWRfc2ZpeGVkMzIoMSwgODA5KTsKKyAgbWVzc2FnZS0+c2V0X3BhY2tlZF9zZml4ZWQ2NCgxLCA4MTApOworICBtZXNzYWdlLT5zZXRfcGFja2VkX2Zsb2F0ICAgKDEsIDgxMSk7CisgIG1lc3NhZ2UtPnNldF9wYWNrZWRfZG91YmxlICAoMSwgODEyKTsKKyAgbWVzc2FnZS0+c2V0X3BhY2tlZF9ib29sICAgICgxLCB0cnVlKTsKKyAgbWVzc2FnZS0+c2V0X3BhY2tlZF9lbnVtICAgICgxLCB1bml0dGVzdDo6Rk9SRUlHTl9GT08pOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3ZvaWQgVGVzdFV0aWw6OkV4cGVjdFBhY2tlZEZpZWxkc1NldChjb25zdCB1bml0dGVzdDo6VGVzdFBhY2tlZFR5cGVzJiBtZXNzYWdlKSB7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnBhY2tlZF9pbnQzMl9zaXplICAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfaW50NjRfc2l6ZSAgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucGFja2VkX3VpbnQzMl9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnBhY2tlZF91aW50NjRfc2l6ZSAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfc2ludDMyX3NpemUgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucGFja2VkX3NpbnQ2NF9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnBhY2tlZF9maXhlZDMyX3NpemUgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfZml4ZWQ2NF9zaXplICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucGFja2VkX3NmaXhlZDMyX3NpemUoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnBhY2tlZF9zZml4ZWQ2NF9zaXplKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfZmxvYXRfc2l6ZSAgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucGFja2VkX2RvdWJsZV9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnBhY2tlZF9ib29sX3NpemUgICAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfZW51bV9zaXplICAgICgpKTsKKworICBFWFBFQ1RfRVEoNjAxICAsIG1lc3NhZ2UucGFja2VkX2ludDMyICAgKDApKTsKKyAgRVhQRUNUX0VRKDYwMiAgLCBtZXNzYWdlLnBhY2tlZF9pbnQ2NCAgICgwKSk7CisgIEVYUEVDVF9FUSg2MDMgICwgbWVzc2FnZS5wYWNrZWRfdWludDMyICAoMCkpOworICBFWFBFQ1RfRVEoNjA0ICAsIG1lc3NhZ2UucGFja2VkX3VpbnQ2NCAgKDApKTsKKyAgRVhQRUNUX0VRKDYwNSAgLCBtZXNzYWdlLnBhY2tlZF9zaW50MzIgICgwKSk7CisgIEVYUEVDVF9FUSg2MDYgICwgbWVzc2FnZS5wYWNrZWRfc2ludDY0ICAoMCkpOworICBFWFBFQ1RfRVEoNjA3ICAsIG1lc3NhZ2UucGFja2VkX2ZpeGVkMzIgKDApKTsKKyAgRVhQRUNUX0VRKDYwOCAgLCBtZXNzYWdlLnBhY2tlZF9maXhlZDY0ICgwKSk7CisgIEVYUEVDVF9FUSg2MDkgICwgbWVzc2FnZS5wYWNrZWRfc2ZpeGVkMzIoMCkpOworICBFWFBFQ1RfRVEoNjEwICAsIG1lc3NhZ2UucGFja2VkX3NmaXhlZDY0KDApKTsKKyAgRVhQRUNUX0VRKDYxMSAgLCBtZXNzYWdlLnBhY2tlZF9mbG9hdCAgICgwKSk7CisgIEVYUEVDVF9FUSg2MTIgICwgbWVzc2FnZS5wYWNrZWRfZG91YmxlICAoMCkpOworICBFWFBFQ1RfVFJVRSggICAgIG1lc3NhZ2UucGFja2VkX2Jvb2wgICAgKDApKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0JBUiwgbWVzc2FnZS5wYWNrZWRfZW51bSgwKSk7CisKKyAgRVhQRUNUX0VRKDcwMSAgLCBtZXNzYWdlLnBhY2tlZF9pbnQzMiAgICgxKSk7CisgIEVYUEVDVF9FUSg3MDIgICwgbWVzc2FnZS5wYWNrZWRfaW50NjQgICAoMSkpOworICBFWFBFQ1RfRVEoNzAzICAsIG1lc3NhZ2UucGFja2VkX3VpbnQzMiAgKDEpKTsKKyAgRVhQRUNUX0VRKDcwNCAgLCBtZXNzYWdlLnBhY2tlZF91aW50NjQgICgxKSk7CisgIEVYUEVDVF9FUSg3MDUgICwgbWVzc2FnZS5wYWNrZWRfc2ludDMyICAoMSkpOworICBFWFBFQ1RfRVEoNzA2ICAsIG1lc3NhZ2UucGFja2VkX3NpbnQ2NCAgKDEpKTsKKyAgRVhQRUNUX0VRKDcwNyAgLCBtZXNzYWdlLnBhY2tlZF9maXhlZDMyICgxKSk7CisgIEVYUEVDVF9FUSg3MDggICwgbWVzc2FnZS5wYWNrZWRfZml4ZWQ2NCAoMSkpOworICBFWFBFQ1RfRVEoNzA5ICAsIG1lc3NhZ2UucGFja2VkX3NmaXhlZDMyKDEpKTsKKyAgRVhQRUNUX0VRKDcxMCAgLCBtZXNzYWdlLnBhY2tlZF9zZml4ZWQ2NCgxKSk7CisgIEVYUEVDVF9FUSg3MTEgICwgbWVzc2FnZS5wYWNrZWRfZmxvYXQgICAoMSkpOworICBFWFBFQ1RfRVEoNzEyICAsIG1lc3NhZ2UucGFja2VkX2RvdWJsZSAgKDEpKTsKKyAgRVhQRUNUX0ZBTFNFKCAgICBtZXNzYWdlLnBhY2tlZF9ib29sICAgICgxKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9SRUlHTl9CQVosIG1lc3NhZ2UucGFja2VkX2VudW0oMSkpOworfQorCit2b2lkIFRlc3RVdGlsOjpFeHBlY3RVbnBhY2tlZEZpZWxkc1NldCgKKyAgICBjb25zdCB1bml0dGVzdDo6VGVzdFVucGFja2VkVHlwZXMmIG1lc3NhZ2UpIHsKKyAgLy8gVGhlIHZhbHVlcyBleHBlY3RlZCBoZXJlIG11c3QgbWF0Y2ggdGhvc2Ugb2YgRXhwZWN0UGFja2VkRmllbGRzU2V0LgorCisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnVucGFja2VkX2ludDMyX3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnVucGFja2VkX2ludDY0X3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnVucGFja2VkX3VpbnQzMl9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnVucGFja2VkX3VpbnQ2NF9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnVucGFja2VkX3NpbnQzMl9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnVucGFja2VkX3NpbnQ2NF9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnVucGFja2VkX2ZpeGVkMzJfc2l6ZSAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnVucGFja2VkX2ZpeGVkNjRfc2l6ZSAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnVucGFja2VkX3NmaXhlZDMyX3NpemUoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnVucGFja2VkX3NmaXhlZDY0X3NpemUoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnVucGFja2VkX2Zsb2F0X3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnVucGFja2VkX2RvdWJsZV9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnVucGFja2VkX2Jvb2xfc2l6ZSAgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnVucGFja2VkX2VudW1fc2l6ZSAgICAoKSk7CisKKyAgRVhQRUNUX0VRKDYwMSAgLCBtZXNzYWdlLnVucGFja2VkX2ludDMyICAgKDApKTsKKyAgRVhQRUNUX0VRKDYwMiAgLCBtZXNzYWdlLnVucGFja2VkX2ludDY0ICAgKDApKTsKKyAgRVhQRUNUX0VRKDYwMyAgLCBtZXNzYWdlLnVucGFja2VkX3VpbnQzMiAgKDApKTsKKyAgRVhQRUNUX0VRKDYwNCAgLCBtZXNzYWdlLnVucGFja2VkX3VpbnQ2NCAgKDApKTsKKyAgRVhQRUNUX0VRKDYwNSAgLCBtZXNzYWdlLnVucGFja2VkX3NpbnQzMiAgKDApKTsKKyAgRVhQRUNUX0VRKDYwNiAgLCBtZXNzYWdlLnVucGFja2VkX3NpbnQ2NCAgKDApKTsKKyAgRVhQRUNUX0VRKDYwNyAgLCBtZXNzYWdlLnVucGFja2VkX2ZpeGVkMzIgKDApKTsKKyAgRVhQRUNUX0VRKDYwOCAgLCBtZXNzYWdlLnVucGFja2VkX2ZpeGVkNjQgKDApKTsKKyAgRVhQRUNUX0VRKDYwOSAgLCBtZXNzYWdlLnVucGFja2VkX3NmaXhlZDMyKDApKTsKKyAgRVhQRUNUX0VRKDYxMCAgLCBtZXNzYWdlLnVucGFja2VkX3NmaXhlZDY0KDApKTsKKyAgRVhQRUNUX0VRKDYxMSAgLCBtZXNzYWdlLnVucGFja2VkX2Zsb2F0ICAgKDApKTsKKyAgRVhQRUNUX0VRKDYxMiAgLCBtZXNzYWdlLnVucGFja2VkX2RvdWJsZSAgKDApKTsKKyAgRVhQRUNUX1RSVUUoICAgICBtZXNzYWdlLnVucGFja2VkX2Jvb2wgICAgKDApKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0JBUiwgbWVzc2FnZS51bnBhY2tlZF9lbnVtKDApKTsKKworICBFWFBFQ1RfRVEoNzAxICAsIG1lc3NhZ2UudW5wYWNrZWRfaW50MzIgICAoMSkpOworICBFWFBFQ1RfRVEoNzAyICAsIG1lc3NhZ2UudW5wYWNrZWRfaW50NjQgICAoMSkpOworICBFWFBFQ1RfRVEoNzAzICAsIG1lc3NhZ2UudW5wYWNrZWRfdWludDMyICAoMSkpOworICBFWFBFQ1RfRVEoNzA0ICAsIG1lc3NhZ2UudW5wYWNrZWRfdWludDY0ICAoMSkpOworICBFWFBFQ1RfRVEoNzA1ICAsIG1lc3NhZ2UudW5wYWNrZWRfc2ludDMyICAoMSkpOworICBFWFBFQ1RfRVEoNzA2ICAsIG1lc3NhZ2UudW5wYWNrZWRfc2ludDY0ICAoMSkpOworICBFWFBFQ1RfRVEoNzA3ICAsIG1lc3NhZ2UudW5wYWNrZWRfZml4ZWQzMiAoMSkpOworICBFWFBFQ1RfRVEoNzA4ICAsIG1lc3NhZ2UudW5wYWNrZWRfZml4ZWQ2NCAoMSkpOworICBFWFBFQ1RfRVEoNzA5ICAsIG1lc3NhZ2UudW5wYWNrZWRfc2ZpeGVkMzIoMSkpOworICBFWFBFQ1RfRVEoNzEwICAsIG1lc3NhZ2UudW5wYWNrZWRfc2ZpeGVkNjQoMSkpOworICBFWFBFQ1RfRVEoNzExICAsIG1lc3NhZ2UudW5wYWNrZWRfZmxvYXQgICAoMSkpOworICBFWFBFQ1RfRVEoNzEyICAsIG1lc3NhZ2UudW5wYWNrZWRfZG91YmxlICAoMSkpOworICBFWFBFQ1RfRkFMU0UoICAgIG1lc3NhZ2UudW5wYWNrZWRfYm9vbCAgICAoMSkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fQkFaLCBtZXNzYWdlLnVucGFja2VkX2VudW0oMSkpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3ZvaWQgVGVzdFV0aWw6OkV4cGVjdFBhY2tlZENsZWFyKAorICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0UGFja2VkVHlwZXMmIG1lc3NhZ2UpIHsKKyAgLy8gUGFja2VkIHJlcGVhdGVkIGZpZWxkcyBhcmUgZW1wdHkuCisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnBhY2tlZF9pbnQzMl9zaXplICAgKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5wYWNrZWRfaW50NjRfc2l6ZSAgICgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucGFja2VkX3VpbnQzMl9zaXplICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnBhY2tlZF91aW50NjRfc2l6ZSAgKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5wYWNrZWRfc2ludDMyX3NpemUgICgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucGFja2VkX3NpbnQ2NF9zaXplICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnBhY2tlZF9maXhlZDMyX3NpemUgKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5wYWNrZWRfZml4ZWQ2NF9zaXplICgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucGFja2VkX3NmaXhlZDMyX3NpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnBhY2tlZF9zZml4ZWQ2NF9zaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5wYWNrZWRfZmxvYXRfc2l6ZSAgICgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucGFja2VkX2RvdWJsZV9zaXplICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnBhY2tlZF9ib29sX3NpemUgICAgKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5wYWNrZWRfZW51bV9zaXplICAgICgpKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIFRlc3RVdGlsOjpFeHBlY3RQYWNrZWRGaWVsZHNNb2RpZmllZCgKKyAgICBjb25zdCB1bml0dGVzdDo6VGVzdFBhY2tlZFR5cGVzJiBtZXNzYWdlKSB7CisgIC8vIERvIHRoZSBzYW1lIGZvciBwYWNrZWQgcmVwZWF0ZWQgZmllbGRzLgorICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfaW50MzJfc2l6ZSAgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucGFja2VkX2ludDY0X3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnBhY2tlZF91aW50MzJfc2l6ZSAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfdWludDY0X3NpemUgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucGFja2VkX3NpbnQzMl9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnBhY2tlZF9zaW50NjRfc2l6ZSAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfZml4ZWQzMl9zaXplICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucGFja2VkX2ZpeGVkNjRfc2l6ZSAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnBhY2tlZF9zZml4ZWQzMl9zaXplKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfc2ZpeGVkNjRfc2l6ZSgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucGFja2VkX2Zsb2F0X3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnBhY2tlZF9kb3VibGVfc2l6ZSAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfYm9vbF9zaXplICAgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucGFja2VkX2VudW1fc2l6ZSAgICAoKSk7CisKKyAgRVhQRUNUX0VRKDYwMSAgLCBtZXNzYWdlLnBhY2tlZF9pbnQzMiAgICgwKSk7CisgIEVYUEVDVF9FUSg2MDIgICwgbWVzc2FnZS5wYWNrZWRfaW50NjQgICAoMCkpOworICBFWFBFQ1RfRVEoNjAzICAsIG1lc3NhZ2UucGFja2VkX3VpbnQzMiAgKDApKTsKKyAgRVhQRUNUX0VRKDYwNCAgLCBtZXNzYWdlLnBhY2tlZF91aW50NjQgICgwKSk7CisgIEVYUEVDVF9FUSg2MDUgICwgbWVzc2FnZS5wYWNrZWRfc2ludDMyICAoMCkpOworICBFWFBFQ1RfRVEoNjA2ICAsIG1lc3NhZ2UucGFja2VkX3NpbnQ2NCAgKDApKTsKKyAgRVhQRUNUX0VRKDYwNyAgLCBtZXNzYWdlLnBhY2tlZF9maXhlZDMyICgwKSk7CisgIEVYUEVDVF9FUSg2MDggICwgbWVzc2FnZS5wYWNrZWRfZml4ZWQ2NCAoMCkpOworICBFWFBFQ1RfRVEoNjA5ICAsIG1lc3NhZ2UucGFja2VkX3NmaXhlZDMyKDApKTsKKyAgRVhQRUNUX0VRKDYxMCAgLCBtZXNzYWdlLnBhY2tlZF9zZml4ZWQ2NCgwKSk7CisgIEVYUEVDVF9FUSg2MTEgICwgbWVzc2FnZS5wYWNrZWRfZmxvYXQgICAoMCkpOworICBFWFBFQ1RfRVEoNjEyICAsIG1lc3NhZ2UucGFja2VkX2RvdWJsZSAgKDApKTsKKyAgRVhQRUNUX1RSVUUoICAgICBtZXNzYWdlLnBhY2tlZF9ib29sICAgICgwKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9SRUlHTl9CQVIsIG1lc3NhZ2UucGFja2VkX2VudW0oMCkpOworICAvLyBBY3R1YWxseSB2ZXJpZnkgdGhlIHNlY29uZCAobW9kaWZpZWQpIGVsZW1lbnRzIG5vdy4KKyAgRVhQRUNUX0VRKDgwMSAgLCBtZXNzYWdlLnBhY2tlZF9pbnQzMiAgICgxKSk7CisgIEVYUEVDVF9FUSg4MDIgICwgbWVzc2FnZS5wYWNrZWRfaW50NjQgICAoMSkpOworICBFWFBFQ1RfRVEoODAzICAsIG1lc3NhZ2UucGFja2VkX3VpbnQzMiAgKDEpKTsKKyAgRVhQRUNUX0VRKDgwNCAgLCBtZXNzYWdlLnBhY2tlZF91aW50NjQgICgxKSk7CisgIEVYUEVDVF9FUSg4MDUgICwgbWVzc2FnZS5wYWNrZWRfc2ludDMyICAoMSkpOworICBFWFBFQ1RfRVEoODA2ICAsIG1lc3NhZ2UucGFja2VkX3NpbnQ2NCAgKDEpKTsKKyAgRVhQRUNUX0VRKDgwNyAgLCBtZXNzYWdlLnBhY2tlZF9maXhlZDMyICgxKSk7CisgIEVYUEVDVF9FUSg4MDggICwgbWVzc2FnZS5wYWNrZWRfZml4ZWQ2NCAoMSkpOworICBFWFBFQ1RfRVEoODA5ICAsIG1lc3NhZ2UucGFja2VkX3NmaXhlZDMyKDEpKTsKKyAgRVhQRUNUX0VRKDgxMCAgLCBtZXNzYWdlLnBhY2tlZF9zZml4ZWQ2NCgxKSk7CisgIEVYUEVDVF9FUSg4MTEgICwgbWVzc2FnZS5wYWNrZWRfZmxvYXQgICAoMSkpOworICBFWFBFQ1RfRVEoODEyICAsIG1lc3NhZ2UucGFja2VkX2RvdWJsZSAgKDEpKTsKKyAgRVhQRUNUX1RSVUUoICAgICBtZXNzYWdlLnBhY2tlZF9ib29sICAgICgxKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9SRUlHTl9GT08sIG1lc3NhZ2UucGFja2VkX2VudW0oMSkpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisvLyBFeHRlbnNpb25zCisvLworLy8gQWxsIHRoaXMgY29kZSBpcyBleGFjdGx5IGVxdWl2YWxlbnQgdG8gdGhlIGFib3ZlIGNvZGUgZXhjZXB0IHRoYXQgaXQncworLy8gbWFuaXB1bGF0aW5nIGV4dGVuc2lvbiBmaWVsZHMgaW5zdGVhZCBvZiBub3JtYWwgb25lcy4KKy8vCisvLyBJIGdhdmUgdXAgb24gdGhlIDgwLWNoYXIgbGltaXQgaGVyZS4gIFNvcnJ5LgorCit2b2lkIFRlc3RVdGlsOjpTZXRBbGxFeHRlbnNpb25zKHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyogbWVzc2FnZSkgeworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ludDMyX2V4dGVuc2lvbiAgICwgMTAxKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbnQ2NF9leHRlbnNpb24gICAsIDEwMik7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfdWludDMyX2V4dGVuc2lvbiAgLCAxMDMpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3VpbnQ2NF9leHRlbnNpb24gICwgMTA0KTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9zaW50MzJfZXh0ZW5zaW9uICAsIDEwNSk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc2ludDY0X2V4dGVuc2lvbiAgLCAxMDYpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ZpeGVkMzJfZXh0ZW5zaW9uICwgMTA3KTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9maXhlZDY0X2V4dGVuc2lvbiAsIDEwOCk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc2ZpeGVkMzJfZXh0ZW5zaW9uLCAxMDkpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3NmaXhlZDY0X2V4dGVuc2lvbiwgMTEwKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9mbG9hdF9leHRlbnNpb24gICAsIDExMSk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZG91YmxlX2V4dGVuc2lvbiAgLCAxMTIpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2Jvb2xfZXh0ZW5zaW9uICAgICwgdHJ1ZSk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc3RyaW5nX2V4dGVuc2lvbiAgLCAiMTE1Iik7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfYnl0ZXNfZXh0ZW5zaW9uICAgLCAiMTE2Iik7CisKKyAgbWVzc2FnZS0+TXV0YWJsZUV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxncm91cF9leHRlbnNpb24gICAgICAgICAgICktPnNldF9hKDExNyk7CisgIG1lc3NhZ2UtPk11dGFibGVFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiApLT5zZXRfYmIoMTE4KTsKKyAgbWVzc2FnZS0+TXV0YWJsZUV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbiktPnNldF9jKDExOSk7CisgIG1lc3NhZ2UtPk11dGFibGVFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbiApLT5zZXRfZCgxMjApOworCisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfbmVzdGVkX2VudW1fZXh0ZW5zaW9uICwgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6QkFaKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uLCB1bml0dGVzdDo6Rk9SRUlHTl9CQVogICAgICApOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ltcG9ydF9lbnVtX2V4dGVuc2lvbiAsIHVuaXR0ZXN0X2ltcG9ydDo6SU1QT1JUX0JBWik7CisKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9zdHJpbmdfcGllY2VfZXh0ZW5zaW9uLCAiMTI0Iik7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfY29yZF9leHRlbnNpb24sICIxMjUiKTsKKworICBtZXNzYWdlLT5NdXRhYmxlRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uKS0+c2V0X2UoMTI2KTsKKyAgbWVzc2FnZS0+TXV0YWJsZUV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfbGF6eV9tZXNzYWdlX2V4dGVuc2lvbiktPnNldF9iYigxMjcpOworCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbnQzMl9leHRlbnNpb24gICAsIDIwMSk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW50NjRfZXh0ZW5zaW9uICAgLCAyMDIpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3VpbnQzMl9leHRlbnNpb24gICwgMjAzKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF91aW50NjRfZXh0ZW5zaW9uICAsIDIwNCk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ludDMyX2V4dGVuc2lvbiAgLCAyMDUpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NpbnQ2NF9leHRlbnNpb24gICwgMjA2KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9maXhlZDMyX2V4dGVuc2lvbiAsIDIwNyk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZml4ZWQ2NF9leHRlbnNpb24gLCAyMDgpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NmaXhlZDMyX2V4dGVuc2lvbiwgMjA5KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zZml4ZWQ2NF9leHRlbnNpb24sIDIxMCk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZmxvYXRfZXh0ZW5zaW9uICAgLCAyMTEpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2RvdWJsZV9leHRlbnNpb24gICwgMjEyKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9ib29sX2V4dGVuc2lvbiAgICAsIHRydWUpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb24gICwgIjIxNSIpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2J5dGVzX2V4dGVuc2lvbiAgICwgIjIxNiIpOworCisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRncm91cF9leHRlbnNpb24gICAgICAgICAgICktPnNldF9hKDIxNyk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uICktPnNldF9iYigyMTgpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb24pLT5zZXRfYygyMTkpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbiApLT5zZXRfZCgyMjApOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2xhenlfbWVzc2FnZV9leHRlbnNpb24gICApLT5zZXRfYmIoMjI3KTsKKworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9lbnVtX2V4dGVuc2lvbiAsIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkJBUik7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbiwgdW5pdHRlc3Q6OkZPUkVJR05fQkFSICAgICAgKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbXBvcnRfZW51bV9leHRlbnNpb24gLCB1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9CQVIpOworCisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc3RyaW5nX3BpZWNlX2V4dGVuc2lvbiwgIjIyNCIpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2NvcmRfZXh0ZW5zaW9uLCAiMjI1Iik7CisKKyAgLy8gQWRkIGEgc2Vjb25kIG9uZSBvZiBlYWNoIGZpZWxkLgorICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ludDMyX2V4dGVuc2lvbiAgICwgMzAxKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbnQ2NF9leHRlbnNpb24gICAsIDMwMik7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfdWludDMyX2V4dGVuc2lvbiAgLCAzMDMpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3VpbnQ2NF9leHRlbnNpb24gICwgMzA0KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50MzJfZXh0ZW5zaW9uICAsIDMwNSk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ludDY0X2V4dGVuc2lvbiAgLCAzMDYpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkMzJfZXh0ZW5zaW9uICwgMzA3KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9maXhlZDY0X2V4dGVuc2lvbiAsIDMwOCk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uLCAzMDkpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NmaXhlZDY0X2V4dGVuc2lvbiwgMzEwKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9mbG9hdF9leHRlbnNpb24gICAsIDMxMSk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZG91YmxlX2V4dGVuc2lvbiAgLCAzMTIpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2Jvb2xfZXh0ZW5zaW9uICAgICwgZmFsc2UpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb24gICwgIjMxNSIpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2J5dGVzX2V4dGVuc2lvbiAgICwgIjMxNiIpOworCisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRncm91cF9leHRlbnNpb24gICAgICAgICAgICktPnNldF9hKDMxNyk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uICktPnNldF9iYigzMTgpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb24pLT5zZXRfYygzMTkpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbiApLT5zZXRfZCgzMjApOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2xhenlfbWVzc2FnZV9leHRlbnNpb24gICApLT5zZXRfYmIoMzI3KTsKKworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9lbnVtX2V4dGVuc2lvbiAsIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkJBWik7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbiwgdW5pdHRlc3Q6OkZPUkVJR05fQkFaICAgICAgKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbXBvcnRfZW51bV9leHRlbnNpb24gLCB1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9CQVopOworCisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc3RyaW5nX3BpZWNlX2V4dGVuc2lvbiwgIjMyNCIpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2NvcmRfZXh0ZW5zaW9uLCAiMzI1Iik7CisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfaW50MzJfZXh0ZW5zaW9uICAgLCA0MDEpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfaW50NjRfZXh0ZW5zaW9uICAgLCA0MDIpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfdWludDMyX2V4dGVuc2lvbiAgLCA0MDMpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfdWludDY0X2V4dGVuc2lvbiAgLCA0MDQpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfc2ludDMyX2V4dGVuc2lvbiAgLCA0MDUpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfc2ludDY0X2V4dGVuc2lvbiAgLCA0MDYpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfZml4ZWQzMl9leHRlbnNpb24gLCA0MDcpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfZml4ZWQ2NF9leHRlbnNpb24gLCA0MDgpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfc2ZpeGVkMzJfZXh0ZW5zaW9uLCA0MDkpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfc2ZpeGVkNjRfZXh0ZW5zaW9uLCA0MTApOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfZmxvYXRfZXh0ZW5zaW9uICAgLCA0MTEpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfZG91YmxlX2V4dGVuc2lvbiAgLCA0MTIpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfYm9vbF9leHRlbnNpb24gICAgLCBmYWxzZSk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zdHJpbmdfZXh0ZW5zaW9uICAsICI0MTUiKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2J5dGVzX2V4dGVuc2lvbiAgICwgIjQxNiIpOworCisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9uZXN0ZWRfZW51bV9leHRlbnNpb24gLCB1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpGT08pOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbiwgdW5pdHRlc3Q6OkZPUkVJR05fRk9PICAgICAgKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2ltcG9ydF9lbnVtX2V4dGVuc2lvbiAsIHVuaXR0ZXN0X2ltcG9ydDo6SU1QT1JUX0ZPTyk7CisKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3N0cmluZ19waWVjZV9leHRlbnNpb24sICI0MjQiKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2NvcmRfZXh0ZW5zaW9uLCAiNDI1Iik7CisKKyAgU2V0T25lb2ZGaWVsZHMobWVzc2FnZSk7Cit9CisKK3ZvaWQgVGVzdFV0aWw6OlNldE9uZW9mRmllbGRzKHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyogbWVzc2FnZSkgeworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9uZW9mX3VpbnQzMl9leHRlbnNpb24sIDYwMSk7CisgIG1lc3NhZ2UtPk11dGFibGVFeHRlbnNpb24odW5pdHRlc3Q6Om9uZW9mX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiktPnNldF9iYig2MDIpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9uZW9mX3N0cmluZ19leHRlbnNpb24sICI2MDMiKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvbmVvZl9ieXRlc19leHRlbnNpb24sICI2MDQiKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHNBbmRFeHRlbnNpb25zKAorICAgIHVuaXR0ZXN0OjpUZXN0RmllbGRPcmRlcmluZ3MqIG1lc3NhZ2UpIHsKKyAgR09PR0xFX0NIRUNLKG1lc3NhZ2UpOworICBtZXNzYWdlLT5zZXRfbXlfaW50KDEpOworICBtZXNzYWdlLT5zZXRfbXlfc3RyaW5nKCJmb28iKTsKKyAgbWVzc2FnZS0+c2V0X215X2Zsb2F0KDEuMCk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6bXlfZXh0ZW5zaW9uX2ludCwgMjMpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om15X2V4dGVuc2lvbl9zdHJpbmcsICJiYXIiKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIFRlc3RVdGlsOjpNb2RpZnlSZXBlYXRlZEV4dGVuc2lvbnModW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zKiBtZXNzYWdlKSB7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9uICAgLCAxLCA1MDEpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ludDY0X2V4dGVuc2lvbiAgICwgMSwgNTAyKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF91aW50MzJfZXh0ZW5zaW9uICAsIDEsIDUwMyk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfdWludDY0X2V4dGVuc2lvbiAgLCAxLCA1MDQpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NpbnQzMl9leHRlbnNpb24gICwgMSwgNTA1KTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50NjRfZXh0ZW5zaW9uICAsIDEsIDUwNik7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZml4ZWQzMl9leHRlbnNpb24gLCAxLCA1MDcpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkNjRfZXh0ZW5zaW9uICwgMSwgNTA4KTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zZml4ZWQzMl9leHRlbnNpb24sIDEsIDUwOSk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ZpeGVkNjRfZXh0ZW5zaW9uLCAxLCA1MTApOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2Zsb2F0X2V4dGVuc2lvbiAgICwgMSwgNTExKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9kb3VibGVfZXh0ZW5zaW9uICAsIDEsIDUxMik7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfYm9vbF9leHRlbnNpb24gICAgLCAxLCB0cnVlKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zdHJpbmdfZXh0ZW5zaW9uICAsIDEsICI1MTUiKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9ieXRlc19leHRlbnNpb24gICAsIDEsICI1MTYiKTsKKworICBtZXNzYWdlLT5NdXRhYmxlRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZGdyb3VwX2V4dGVuc2lvbiAgICAgICAgICAgLCAxKS0+c2V0X2EoNTE3KTsKKyAgbWVzc2FnZS0+TXV0YWJsZUV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uICwgMSktPnNldF9iYig1MTgpOworICBtZXNzYWdlLT5NdXRhYmxlRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uLCAxKS0+c2V0X2MoNTE5KTsKKyAgbWVzc2FnZS0+TXV0YWJsZUV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uICwgMSktPnNldF9kKDUyMCk7CisgIG1lc3NhZ2UtPk11dGFibGVFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2xhenlfbWVzc2FnZV9leHRlbnNpb24gICAsIDEpLT5zZXRfYmIoNTI3KTsKKworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9lbnVtX2V4dGVuc2lvbiAsIDEsIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkZPTyk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbiwgMSwgdW5pdHRlc3Q6OkZPUkVJR05fRk9PICAgICAgKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbXBvcnRfZW51bV9leHRlbnNpb24gLCAxLCB1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9GT08pOworCisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc3RyaW5nX3BpZWNlX2V4dGVuc2lvbiwgMSwgIjUyNCIpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2NvcmRfZXh0ZW5zaW9uLCAxLCAiNTI1Iik7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBUZXN0VXRpbDo6RXhwZWN0QWxsRXh0ZW5zaW9uc1NldCgKKyAgICBjb25zdCB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMmIG1lc3NhZ2UpIHsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ludDMyX2V4dGVuc2lvbiAgICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW50NjRfZXh0ZW5zaW9uICAgKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF91aW50MzJfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3VpbnQ2NF9leHRlbnNpb24gICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc2ludDMyX2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9zaW50NjRfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ZpeGVkMzJfZXh0ZW5zaW9uICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZml4ZWQ2NF9leHRlbnNpb24gKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9zZml4ZWQzMl9leHRlbnNpb24pKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3NmaXhlZDY0X2V4dGVuc2lvbikpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZmxvYXRfZXh0ZW5zaW9uICAgKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9kb3VibGVfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2Jvb2xfZXh0ZW5zaW9uICAgICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc3RyaW5nX2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9ieXRlc19leHRlbnNpb24gICApKTsKKworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxncm91cF9leHRlbnNpb24gICAgICAgICAgICAgICAgICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uICAgICAgICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbiAgICAgICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uICAgICAgICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbikpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfbGF6eV9tZXNzYWdlX2V4dGVuc2lvbiAgICAgICAgICkpOworCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbGdyb3VwX2V4dGVuc2lvbiAgICAgICAgICAgICAgICAgKS5oYXNfYSgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiAgICAgICApLmhhc19iYigpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb24gICAgICApLmhhc19jKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uICAgICAgICkuaGFzX2QoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uKS5oYXNfZSgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2xhenlfbWVzc2FnZV9leHRlbnNpb24gICAgICAgICApLmhhc19iYigpKTsKKworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfbmVzdGVkX2VudW1fZXh0ZW5zaW9uICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbikpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW1wb3J0X2VudW1fZXh0ZW5zaW9uICkpOworCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9zdHJpbmdfcGllY2VfZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9jb3JkX2V4dGVuc2lvbikpOworCisgIEVYUEVDVF9FUSgxMDEgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ludDMyX2V4dGVuc2lvbiAgICkpOworICBFWFBFQ1RfRVEoMTAyICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbnQ2NF9leHRlbnNpb24gICApKTsKKyAgRVhQRUNUX0VRKDEwMyAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfdWludDMyX2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9FUSgxMDQgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3VpbnQ2NF9leHRlbnNpb24gICkpOworICBFWFBFQ1RfRVEoMTA1ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9zaW50MzJfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX0VRKDEwNiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc2ludDY0X2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9FUSgxMDcgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ZpeGVkMzJfZXh0ZW5zaW9uICkpOworICBFWFBFQ1RfRVEoMTA4ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9maXhlZDY0X2V4dGVuc2lvbiApKTsKKyAgRVhQRUNUX0VRKDEwOSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc2ZpeGVkMzJfZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9FUSgxMTAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3NmaXhlZDY0X2V4dGVuc2lvbikpOworICBFWFBFQ1RfRVEoMTExICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9mbG9hdF9leHRlbnNpb24gICApKTsKKyAgRVhQRUNUX0VRKDExMiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZG91YmxlX2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9UUlVFKCAgICAgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2Jvb2xfZXh0ZW5zaW9uICAgICkpOworICBFWFBFQ1RfRVEoIjExNSIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9zdHJpbmdfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX0VRKCIxMTYiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfYnl0ZXNfZXh0ZW5zaW9uICAgKSk7CisKKyAgRVhQRUNUX0VRKDExNywgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsZ3JvdXBfZXh0ZW5zaW9uICAgICAgICAgICApLmEoKSk7CisgIEVYUEVDVF9FUSgxMTgsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb24gKS5iYigpKTsKKyAgRVhQRUNUX0VRKDExOSwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb24pLmMoKSk7CisgIEVYUEVDVF9FUSgxMjAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb24gKS5kKCkpOworCisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpCQVosIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9uZXN0ZWRfZW51bV9leHRlbnNpb24gKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9SRUlHTl9CQVogICAgICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9CQVosIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbXBvcnRfZW51bV9leHRlbnNpb24gKSk7CisKKyAgRVhQRUNUX0VRKCIxMjQiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc3RyaW5nX3BpZWNlX2V4dGVuc2lvbikpOworICBFWFBFQ1RfRVEoIjEyNSIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9jb3JkX2V4dGVuc2lvbikpOworICBFWFBFQ1RfRVEoMTI2LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbiApLmUoKSk7CisgIEVYUEVDVF9FUSgxMjcsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9sYXp5X21lc3NhZ2VfZXh0ZW5zaW9uKS5iYigpKTsKKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ludDMyX2V4dGVuc2lvbiAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbnQ2NF9leHRlbnNpb24gICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfdWludDMyX2V4dGVuc2lvbiAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3VpbnQ2NF9leHRlbnNpb24gICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50MzJfZXh0ZW5zaW9uICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfc2ludDY0X2V4dGVuc2lvbiAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkMzJfZXh0ZW5zaW9uICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9maXhlZDY0X2V4dGVuc2lvbiApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3NmaXhlZDY0X2V4dGVuc2lvbikpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9mbG9hdF9leHRlbnNpb24gICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfZG91YmxlX2V4dGVuc2lvbiAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2Jvb2xfZXh0ZW5zaW9uICAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9zdHJpbmdfZXh0ZW5zaW9uICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfYnl0ZXNfZXh0ZW5zaW9uICAgKSk7CisKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRncm91cF9leHRlbnNpb24gICAgICAgICAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb24gKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb24pKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9sYXp5X21lc3NhZ2VfZXh0ZW5zaW9uICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9lbnVtX2V4dGVuc2lvbiAgICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbiAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbXBvcnRfZW51bV9leHRlbnNpb24gICAgKSk7CisKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfc3RyaW5nX3BpZWNlX2V4dGVuc2lvbikpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9jb3JkX2V4dGVuc2lvbikpOworCisgIEVYUEVDVF9FUSgyMDEgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ludDMyX2V4dGVuc2lvbiAgICwgMCkpOworICBFWFBFQ1RfRVEoMjAyICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbnQ2NF9leHRlbnNpb24gICAsIDApKTsKKyAgRVhQRUNUX0VRKDIwMyAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfdWludDMyX2V4dGVuc2lvbiAgLCAwKSk7CisgIEVYUEVDVF9FUSgyMDQgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3VpbnQ2NF9leHRlbnNpb24gICwgMCkpOworICBFWFBFQ1RfRVEoMjA1ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50MzJfZXh0ZW5zaW9uICAsIDApKTsKKyAgRVhQRUNUX0VRKDIwNiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ludDY0X2V4dGVuc2lvbiAgLCAwKSk7CisgIEVYUEVDVF9FUSgyMDcgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkMzJfZXh0ZW5zaW9uICwgMCkpOworICBFWFBFQ1RfRVEoMjA4ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9maXhlZDY0X2V4dGVuc2lvbiAsIDApKTsKKyAgRVhQRUNUX0VRKDIwOSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uLCAwKSk7CisgIEVYUEVDVF9FUSgyMTAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NmaXhlZDY0X2V4dGVuc2lvbiwgMCkpOworICBFWFBFQ1RfRVEoMjExICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9mbG9hdF9leHRlbnNpb24gICAsIDApKTsKKyAgRVhQRUNUX0VRKDIxMiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZG91YmxlX2V4dGVuc2lvbiAgLCAwKSk7CisgIEVYUEVDVF9UUlVFKCAgICAgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2Jvb2xfZXh0ZW5zaW9uICAgICwgMCkpOworICBFWFBFQ1RfRVEoIjIxNSIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zdHJpbmdfZXh0ZW5zaW9uICAsIDApKTsKKyAgRVhQRUNUX0VRKCIyMTYiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfYnl0ZXNfZXh0ZW5zaW9uICAgLCAwKSk7CisKKyAgRVhQRUNUX0VRKDIxNywgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkZ3JvdXBfZXh0ZW5zaW9uICAgICAgICAgICAsIDApLmEoKSk7CisgIEVYUEVDVF9FUSgyMTgsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb24gLCAwKS5iYigpKTsKKyAgRVhQRUNUX0VRKDIxOSwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb24sIDApLmMoKSk7CisgIEVYUEVDVF9FUSgyMjAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb24gLCAwKS5kKCkpOworICBFWFBFQ1RfRVEoMjI3LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbGF6eV9tZXNzYWdlX2V4dGVuc2lvbiAgICwgMCkuYmIoKSk7CisKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkJBUiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9lbnVtX2V4dGVuc2lvbiAsIDApKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0JBUiAgICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZvcmVpZ25fZW51bV9leHRlbnNpb24sIDApKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0X2ltcG9ydDo6SU1QT1JUX0JBUiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ltcG9ydF9lbnVtX2V4dGVuc2lvbiAsIDApKTsKKworICBFWFBFQ1RfRVEoIjIyNCIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zdHJpbmdfcGllY2VfZXh0ZW5zaW9uLCAwKSk7CisgIEVYUEVDVF9FUSgiMjI1IiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2NvcmRfZXh0ZW5zaW9uLCAwKSk7CisKKyAgRVhQRUNUX0VRKDMwMSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9uICAgLCAxKSk7CisgIEVYUEVDVF9FUSgzMDIgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ludDY0X2V4dGVuc2lvbiAgICwgMSkpOworICBFWFBFQ1RfRVEoMzAzICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF91aW50MzJfZXh0ZW5zaW9uICAsIDEpKTsKKyAgRVhQRUNUX0VRKDMwNCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfdWludDY0X2V4dGVuc2lvbiAgLCAxKSk7CisgIEVYUEVDVF9FUSgzMDUgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NpbnQzMl9leHRlbnNpb24gICwgMSkpOworICBFWFBFQ1RfRVEoMzA2ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50NjRfZXh0ZW5zaW9uICAsIDEpKTsKKyAgRVhQRUNUX0VRKDMwNyAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZml4ZWQzMl9leHRlbnNpb24gLCAxKSk7CisgIEVYUEVDVF9FUSgzMDggICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkNjRfZXh0ZW5zaW9uICwgMSkpOworICBFWFBFQ1RfRVEoMzA5ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zZml4ZWQzMl9leHRlbnNpb24sIDEpKTsKKyAgRVhQRUNUX0VRKDMxMCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ZpeGVkNjRfZXh0ZW5zaW9uLCAxKSk7CisgIEVYUEVDVF9FUSgzMTEgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2Zsb2F0X2V4dGVuc2lvbiAgICwgMSkpOworICBFWFBFQ1RfRVEoMzEyICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9kb3VibGVfZXh0ZW5zaW9uICAsIDEpKTsKKyAgRVhQRUNUX0ZBTFNFKCAgICBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfYm9vbF9leHRlbnNpb24gICAgLCAxKSk7CisgIEVYUEVDVF9FUSgiMzE1IiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb24gICwgMSkpOworICBFWFBFQ1RfRVEoIjMxNiIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9ieXRlc19leHRlbnNpb24gICAsIDEpKTsKKworICBFWFBFQ1RfRVEoMzE3LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRncm91cF9leHRlbnNpb24gICAgICAgICAgICwgMSkuYSgpKTsKKyAgRVhQRUNUX0VRKDMxOCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiAsIDEpLmJiKCkpOworICBFWFBFQ1RfRVEoMzE5LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbiwgMSkuYygpKTsKKyAgRVhQRUNUX0VRKDMyMCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbiAsIDEpLmQoKSk7CisgIEVYUEVDVF9FUSgzMjcsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9sYXp5X21lc3NhZ2VfZXh0ZW5zaW9uICAgLCAxKS5iYigpKTsKKworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6QkFaLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uICwgMSkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fQkFaICAgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbiwgMSkpOworICBFWFBFQ1RfRVEodW5pdHRlc3RfaW1wb3J0OjpJTVBPUlRfQkFaLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW1wb3J0X2VudW1fZXh0ZW5zaW9uICwgMSkpOworCisgIEVYUEVDVF9FUSgiMzI0IiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19waWVjZV9leHRlbnNpb24sIDEpKTsKKyAgRVhQRUNUX0VRKCIzMjUiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfY29yZF9leHRlbnNpb24sIDEpKTsKKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2ludDMyX2V4dGVuc2lvbiAgICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9pbnQ2NF9leHRlbnNpb24gICApKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfdWludDMyX2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3VpbnQ2NF9leHRlbnNpb24gICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zaW50MzJfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfc2ludDY0X2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2ZpeGVkMzJfZXh0ZW5zaW9uICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9maXhlZDY0X2V4dGVuc2lvbiApKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfc2ZpeGVkMzJfZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3NmaXhlZDY0X2V4dGVuc2lvbikpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9mbG9hdF9leHRlbnNpb24gICApKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfZG91YmxlX2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2Jvb2xfZXh0ZW5zaW9uICAgICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zdHJpbmdfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfYnl0ZXNfZXh0ZW5zaW9uICAgKSk7CisKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2ltcG9ydF9lbnVtX2V4dGVuc2lvbiApKTsKKworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zdHJpbmdfcGllY2VfZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2NvcmRfZXh0ZW5zaW9uKSk7CisKKyAgRVhQRUNUX0VRKDQwMSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9pbnQzMl9leHRlbnNpb24gICApKTsKKyAgRVhQRUNUX0VRKDQwMiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9pbnQ2NF9leHRlbnNpb24gICApKTsKKyAgRVhQRUNUX0VRKDQwMyAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF91aW50MzJfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX0VRKDQwNCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF91aW50NjRfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX0VRKDQwNSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zaW50MzJfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX0VRKDQwNiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zaW50NjRfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX0VRKDQwNyAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9maXhlZDMyX2V4dGVuc2lvbiApKTsKKyAgRVhQRUNUX0VRKDQwOCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9maXhlZDY0X2V4dGVuc2lvbiApKTsKKyAgRVhQRUNUX0VRKDQwOSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zZml4ZWQzMl9leHRlbnNpb24pKTsKKyAgRVhQRUNUX0VRKDQxMCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zZml4ZWQ2NF9leHRlbnNpb24pKTsKKyAgRVhQRUNUX0VRKDQxMSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9mbG9hdF9leHRlbnNpb24gICApKTsKKyAgRVhQRUNUX0VRKDQxMiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9kb3VibGVfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX0ZBTFNFKCAgICBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9ib29sX2V4dGVuc2lvbiAgICApKTsKKyAgRVhQRUNUX0VRKCI0MTUiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zdHJpbmdfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX0VRKCI0MTYiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9ieXRlc19leHRlbnNpb24gICApKTsKKworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6Rk9PLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9uZXN0ZWRfZW51bV9leHRlbnNpb24gKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9SRUlHTl9GT08gICAgICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2ZvcmVpZ25fZW51bV9leHRlbnNpb24pKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0X2ltcG9ydDo6SU1QT1JUX0ZPTywgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfaW1wb3J0X2VudW1fZXh0ZW5zaW9uICkpOworCisgIEVYUEVDVF9FUSgiNDI0IiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfc3RyaW5nX3BpZWNlX2V4dGVuc2lvbikpOworICBFWFBFQ1RfRVEoIjQyNSIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2NvcmRfZXh0ZW5zaW9uKSk7CisKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9uZW9mX3VpbnQzMl9leHRlbnNpb24pKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9uZW9mX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbikuaGFzX2JiKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b25lb2Zfc3RyaW5nX2V4dGVuc2lvbikpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b25lb2ZfYnl0ZXNfZXh0ZW5zaW9uKSk7CisKKyAgRVhQRUNUX0VRKDYwMSwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9uZW9mX3VpbnQzMl9leHRlbnNpb24pKTsKKyAgRVhQRUNUX0VRKDYwMiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9uZW9mX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbikuYmIoKSk7CisgIEVYUEVDVF9FUSgiNjAzIiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9uZW9mX3N0cmluZ19leHRlbnNpb24pKTsKKyAgRVhQRUNUX0VRKCI2MDQiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b25lb2ZfYnl0ZXNfZXh0ZW5zaW9uKSk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBUZXN0VXRpbDo6RXhwZWN0RXh0ZW5zaW9uc0NsZWFyKAorICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyYgbWVzc2FnZSkgeworICBzdHJpbmcgc2VyaWFsaXplZDsKKyAgQVNTRVJUX1RSVUUobWVzc2FnZS5TZXJpYWxpemVUb1N0cmluZygmc2VyaWFsaXplZCkpOworICBFWFBFQ1RfRVEoIiIsIHNlcmlhbGl6ZWQpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5CeXRlU2l6ZSgpKTsKKworICAvLyBoYXNfYmxhaCgpIHNob3VsZCBpbml0aWFsbHkgYmUgZmFsc2UgZm9yIGFsbCBvcHRpb25hbCBmaWVsZHMuCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW50MzJfZXh0ZW5zaW9uICAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW50NjRfZXh0ZW5zaW9uICAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfdWludDMyX2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfdWludDY0X2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc2ludDMyX2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc2ludDY0X2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZml4ZWQzMl9leHRlbnNpb24gKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZml4ZWQ2NF9leHRlbnNpb24gKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc2ZpeGVkMzJfZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc2ZpeGVkNjRfZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZmxvYXRfZXh0ZW5zaW9uICAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZG91YmxlX2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfYm9vbF9leHRlbnNpb24gICAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc3RyaW5nX2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfYnl0ZXNfZXh0ZW5zaW9uICAgKSk7CisKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbGdyb3VwX2V4dGVuc2lvbiAgICAgICAgICAgICAgICAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uICAgICAgICkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb24gICAgICApKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb24gICAgICAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbikpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2xhenlfbWVzc2FnZV9leHRlbnNpb24gICAgICAgICApKTsKKworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX25lc3RlZF9lbnVtX2V4dGVuc2lvbiApKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW1wb3J0X2VudW1fZXh0ZW5zaW9uICkpOworCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc3RyaW5nX3BpZWNlX2V4dGVuc2lvbikpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2NvcmRfZXh0ZW5zaW9uKSk7CisKKyAgLy8gT3B0aW9uYWwgZmllbGRzIHdpdGhvdXQgZGVmYXVsdHMgYXJlIHNldCB0byB6ZXJvIG9yIHNvbWV0aGluZyBsaWtlIGl0LgorICBFWFBFQ1RfRVEoMCAgICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbnQzMl9leHRlbnNpb24gICApKTsKKyAgRVhQRUNUX0VRKDAgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW50NjRfZXh0ZW5zaW9uICAgKSk7CisgIEVYUEVDVF9FUSgwICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3VpbnQzMl9leHRlbnNpb24gICkpOworICBFWFBFQ1RfRVEoMCAgICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF91aW50NjRfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX0VRKDAgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc2ludDMyX2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9FUSgwICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3NpbnQ2NF9leHRlbnNpb24gICkpOworICBFWFBFQ1RfRVEoMCAgICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9maXhlZDMyX2V4dGVuc2lvbiApKTsKKyAgRVhQRUNUX0VRKDAgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZml4ZWQ2NF9leHRlbnNpb24gKSk7CisgIEVYUEVDVF9FUSgwICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3NmaXhlZDMyX2V4dGVuc2lvbikpOworICBFWFBFQ1RfRVEoMCAgICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9zZml4ZWQ2NF9leHRlbnNpb24pKTsKKyAgRVhQRUNUX0VRKDAgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZmxvYXRfZXh0ZW5zaW9uICAgKSk7CisgIEVYUEVDVF9FUSgwICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2RvdWJsZV9leHRlbnNpb24gICkpOworICBFWFBFQ1RfRkFMU0UoICAgIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9ib29sX2V4dGVuc2lvbiAgICApKTsKKyAgRVhQRUNUX0VRKCIiICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc3RyaW5nX2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9FUSgiIiAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2J5dGVzX2V4dGVuc2lvbiAgICkpOworCisgIC8vIEVtYmVkZGVkIG1lc3NhZ2VzIHNob3VsZCBhbHNvIGJlIGNsZWFyLgorICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsZ3JvdXBfZXh0ZW5zaW9uICAgICAgICAgICAgICAgICApLmhhc19hKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiAgICAgICApLmhhc19iYigpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uICAgICAgKS5oYXNfYygpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb24gICAgICAgKS5oYXNfZCgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uKS5oYXNfZSgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9sYXp5X21lc3NhZ2VfZXh0ZW5zaW9uICAgICAgICAgKS5oYXNfYmIoKSk7CisKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbGdyb3VwX2V4dGVuc2lvbiAgICAgICAgICAgICAgICAgKS5hKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiAgICAgICApLmJiKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb24gICAgICApLmMoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uICAgICAgICkuZCgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uKS5lKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2xhenlfbWVzc2FnZV9leHRlbnNpb24gICAgICAgICApLmJiKCkpOworCisgIC8vIEVudW1zIHdpdGhvdXQgZGVmYXVsdHMgYXJlIHNldCB0byB0aGUgZmlyc3QgdmFsdWUgaW4gdGhlIGVudW0uCisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpGT08sIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9uZXN0ZWRfZW51bV9leHRlbnNpb24gKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9SRUlHTl9GT08gICAgICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9GT08sIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbXBvcnRfZW51bV9leHRlbnNpb24gKSk7CisKKyAgRVhQRUNUX0VRKCIiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc3RyaW5nX3BpZWNlX2V4dGVuc2lvbikpOworICBFWFBFQ1RfRVEoIiIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9jb3JkX2V4dGVuc2lvbikpOworCisgIC8vIFJlcGVhdGVkIGZpZWxkcyBhcmUgZW1wdHkuCisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ludDMyX2V4dGVuc2lvbiAgICkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbnQ2NF9leHRlbnNpb24gICApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfdWludDMyX2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3VpbnQ2NF9leHRlbnNpb24gICkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50MzJfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfc2ludDY0X2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkMzJfZXh0ZW5zaW9uICkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9maXhlZDY0X2V4dGVuc2lvbiApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3NmaXhlZDY0X2V4dGVuc2lvbikpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9mbG9hdF9leHRlbnNpb24gICApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfZG91YmxlX2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2Jvb2xfZXh0ZW5zaW9uICAgICkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9zdHJpbmdfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfYnl0ZXNfZXh0ZW5zaW9uICAgKSk7CisKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRncm91cF9leHRlbnNpb24gICAgICAgICAgICkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb24gKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb24pKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uICkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9sYXp5X21lc3NhZ2VfZXh0ZW5zaW9uICAgKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9lbnVtX2V4dGVuc2lvbiAgICApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbiAgICkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbXBvcnRfZW51bV9leHRlbnNpb24gICAgKSk7CisKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfc3RyaW5nX3BpZWNlX2V4dGVuc2lvbikpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9jb3JkX2V4dGVuc2lvbikpOworCisgIC8vIGhhc19ibGFoKCkgc2hvdWxkIGFsc28gYmUgZmFsc2UgZm9yIGFsbCBkZWZhdWx0IGZpZWxkcy4KKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2ludDMyX2V4dGVuc2lvbiAgICkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfaW50NjRfZXh0ZW5zaW9uICAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF91aW50MzJfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3VpbnQ2NF9leHRlbnNpb24gICkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfc2ludDMyX2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zaW50NjRfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2ZpeGVkMzJfZXh0ZW5zaW9uICkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfZml4ZWQ2NF9leHRlbnNpb24gKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zZml4ZWQzMl9leHRlbnNpb24pKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3NmaXhlZDY0X2V4dGVuc2lvbikpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfZmxvYXRfZXh0ZW5zaW9uICAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9kb3VibGVfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2Jvb2xfZXh0ZW5zaW9uICAgICkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfc3RyaW5nX2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9ieXRlc19leHRlbnNpb24gICApKTsKKworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uICkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbikpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfaW1wb3J0X2VudW1fZXh0ZW5zaW9uICkpOworCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zdHJpbmdfcGllY2VfZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9jb3JkX2V4dGVuc2lvbikpOworCisgIC8vIEZpZWxkcyB3aXRoIGRlZmF1bHRzIGhhdmUgdGhlaXIgZGVmYXVsdCB2YWx1ZXMgKGR1aCkuCisgIEVYUEVDVF9FUSggNDEgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9pbnQzMl9leHRlbnNpb24gICApKTsKKyAgRVhQRUNUX0VRKCA0MiAgICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2ludDY0X2V4dGVuc2lvbiAgICkpOworICBFWFBFQ1RfRVEoIDQzICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfdWludDMyX2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9FUSggNDQgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF91aW50NjRfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX0VRKC00NSAgICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3NpbnQzMl9leHRlbnNpb24gICkpOworICBFWFBFQ1RfRVEoIDQ2ICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfc2ludDY0X2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9FUSggNDcgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9maXhlZDMyX2V4dGVuc2lvbiApKTsKKyAgRVhQRUNUX0VRKCA0OCAgICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2ZpeGVkNjRfZXh0ZW5zaW9uICkpOworICBFWFBFQ1RfRVEoIDQ5ICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfc2ZpeGVkMzJfZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9FUSgtNTAgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zZml4ZWQ2NF9leHRlbnNpb24pKTsKKyAgRVhQRUNUX0VRKCA1MS41ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2Zsb2F0X2V4dGVuc2lvbiAgICkpOworICBFWFBFQ1RfRVEoIDUyZTMgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfZG91YmxlX2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9UUlVFKCAgICAgICBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9ib29sX2V4dGVuc2lvbiAgICApKTsKKyAgRVhQRUNUX0VRKCJoZWxsbyIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3N0cmluZ19leHRlbnNpb24gICkpOworICBFWFBFQ1RfRVEoIndvcmxkIiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfYnl0ZXNfZXh0ZW5zaW9uICAgKSk7CisKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkJBUiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uICkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fQkFSICAgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9CQVIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2ltcG9ydF9lbnVtX2V4dGVuc2lvbiApKTsKKworICBFWFBFQ1RfRVEoImFiYyIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3N0cmluZ19waWVjZV9leHRlbnNpb24pKTsKKyAgRVhQRUNUX0VRKCIxMjMiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9jb3JkX2V4dGVuc2lvbikpOworCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b25lb2ZfdWludDMyX2V4dGVuc2lvbikpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9uZW9mX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbikuaGFzX2JiKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9uZW9mX3N0cmluZ19leHRlbnNpb24pKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvbmVvZl9ieXRlc19leHRlbnNpb24pKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIFRlc3RVdGlsOjpFeHBlY3RSZXBlYXRlZEV4dGVuc2lvbnNNb2RpZmllZCgKKyAgICBjb25zdCB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMmIG1lc3NhZ2UpIHsKKyAgLy8gTW9kaWZ5UmVwZWF0ZWRGaWVsZHMgb25seSBzZXRzIHRoZSBzZWNvbmQgcmVwZWF0ZWQgZWxlbWVudCBvZiBlYWNoCisgIC8vIGZpZWxkLiAgSW4gYWRkaXRpb24gdG8gdmVyaWZ5aW5nIHRoaXMsIHdlIGFsc28gdmVyaWZ5IHRoYXQgdGhlIGZpcnN0CisgIC8vIGVsZW1lbnQgYW5kIHNpemUgd2VyZSAqbm90KiBtb2RpZmllZC4KKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9uICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ludDY0X2V4dGVuc2lvbiAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF91aW50MzJfZXh0ZW5zaW9uICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfdWludDY0X2V4dGVuc2lvbiAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3NpbnQzMl9leHRlbnNpb24gICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50NjRfZXh0ZW5zaW9uICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfZml4ZWQzMl9leHRlbnNpb24gKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkNjRfZXh0ZW5zaW9uICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9zZml4ZWQzMl9leHRlbnNpb24pKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfc2ZpeGVkNjRfZXh0ZW5zaW9uKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2Zsb2F0X2V4dGVuc2lvbiAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9kb3VibGVfZXh0ZW5zaW9uICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfYm9vbF9leHRlbnNpb24gICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb24gICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9ieXRlc19leHRlbnNpb24gICApKTsKKworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZGdyb3VwX2V4dGVuc2lvbiAgICAgICAgICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbikpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb24gKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2xhenlfbWVzc2FnZV9leHRlbnNpb24gICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uICAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ltcG9ydF9lbnVtX2V4dGVuc2lvbiAgICApKTsKKworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9zdHJpbmdfcGllY2VfZXh0ZW5zaW9uKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2NvcmRfZXh0ZW5zaW9uKSk7CisKKyAgRVhQRUNUX0VRKDIwMSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9uICAgLCAwKSk7CisgIEVYUEVDVF9FUSgyMDIgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ludDY0X2V4dGVuc2lvbiAgICwgMCkpOworICBFWFBFQ1RfRVEoMjAzICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF91aW50MzJfZXh0ZW5zaW9uICAsIDApKTsKKyAgRVhQRUNUX0VRKDIwNCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfdWludDY0X2V4dGVuc2lvbiAgLCAwKSk7CisgIEVYUEVDVF9FUSgyMDUgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NpbnQzMl9leHRlbnNpb24gICwgMCkpOworICBFWFBFQ1RfRVEoMjA2ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50NjRfZXh0ZW5zaW9uICAsIDApKTsKKyAgRVhQRUNUX0VRKDIwNyAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZml4ZWQzMl9leHRlbnNpb24gLCAwKSk7CisgIEVYUEVDVF9FUSgyMDggICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkNjRfZXh0ZW5zaW9uICwgMCkpOworICBFWFBFQ1RfRVEoMjA5ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zZml4ZWQzMl9leHRlbnNpb24sIDApKTsKKyAgRVhQRUNUX0VRKDIxMCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ZpeGVkNjRfZXh0ZW5zaW9uLCAwKSk7CisgIEVYUEVDVF9FUSgyMTEgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2Zsb2F0X2V4dGVuc2lvbiAgICwgMCkpOworICBFWFBFQ1RfRVEoMjEyICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9kb3VibGVfZXh0ZW5zaW9uICAsIDApKTsKKyAgRVhQRUNUX1RSVUUoICAgICBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfYm9vbF9leHRlbnNpb24gICAgLCAwKSk7CisgIEVYUEVDVF9FUSgiMjE1IiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb24gICwgMCkpOworICBFWFBFQ1RfRVEoIjIxNiIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9ieXRlc19leHRlbnNpb24gICAsIDApKTsKKworICBFWFBFQ1RfRVEoMjE3LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRncm91cF9leHRlbnNpb24gICAgICAgICAgICwgMCkuYSgpKTsKKyAgRVhQRUNUX0VRKDIxOCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiAsIDApLmJiKCkpOworICBFWFBFQ1RfRVEoMjE5LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbiwgMCkuYygpKTsKKyAgRVhQRUNUX0VRKDIyMCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbiAsIDApLmQoKSk7CisgIEVYUEVDVF9FUSgyMjcsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9sYXp5X21lc3NhZ2VfZXh0ZW5zaW9uICAgLCAwKS5iYigpKTsKKworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6QkFSLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uICwgMCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fQkFSICAgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbiwgMCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3RfaW1wb3J0OjpJTVBPUlRfQkFSLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW1wb3J0X2VudW1fZXh0ZW5zaW9uICwgMCkpOworCisgIEVYUEVDVF9FUSgiMjI0IiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19waWVjZV9leHRlbnNpb24sIDApKTsKKyAgRVhQRUNUX0VRKCIyMjUiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfY29yZF9leHRlbnNpb24sIDApKTsKKworICAvLyBBY3R1YWxseSB2ZXJpZnkgdGhlIHNlY29uZCAobW9kaWZpZWQpIGVsZW1lbnRzIG5vdy4KKyAgRVhQRUNUX0VRKDUwMSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9uICAgLCAxKSk7CisgIEVYUEVDVF9FUSg1MDIgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ludDY0X2V4dGVuc2lvbiAgICwgMSkpOworICBFWFBFQ1RfRVEoNTAzICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF91aW50MzJfZXh0ZW5zaW9uICAsIDEpKTsKKyAgRVhQRUNUX0VRKDUwNCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfdWludDY0X2V4dGVuc2lvbiAgLCAxKSk7CisgIEVYUEVDVF9FUSg1MDUgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NpbnQzMl9leHRlbnNpb24gICwgMSkpOworICBFWFBFQ1RfRVEoNTA2ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50NjRfZXh0ZW5zaW9uICAsIDEpKTsKKyAgRVhQRUNUX0VRKDUwNyAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZml4ZWQzMl9leHRlbnNpb24gLCAxKSk7CisgIEVYUEVDVF9FUSg1MDggICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkNjRfZXh0ZW5zaW9uICwgMSkpOworICBFWFBFQ1RfRVEoNTA5ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zZml4ZWQzMl9leHRlbnNpb24sIDEpKTsKKyAgRVhQRUNUX0VRKDUxMCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ZpeGVkNjRfZXh0ZW5zaW9uLCAxKSk7CisgIEVYUEVDVF9FUSg1MTEgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2Zsb2F0X2V4dGVuc2lvbiAgICwgMSkpOworICBFWFBFQ1RfRVEoNTEyICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9kb3VibGVfZXh0ZW5zaW9uICAsIDEpKTsKKyAgRVhQRUNUX1RSVUUoICAgICBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfYm9vbF9leHRlbnNpb24gICAgLCAxKSk7CisgIEVYUEVDVF9FUSgiNTE1IiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb24gICwgMSkpOworICBFWFBFQ1RfRVEoIjUxNiIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9ieXRlc19leHRlbnNpb24gICAsIDEpKTsKKworICBFWFBFQ1RfRVEoNTE3LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRncm91cF9leHRlbnNpb24gICAgICAgICAgICwgMSkuYSgpKTsKKyAgRVhQRUNUX0VRKDUxOCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiAsIDEpLmJiKCkpOworICBFWFBFQ1RfRVEoNTE5LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbiwgMSkuYygpKTsKKyAgRVhQRUNUX0VRKDUyMCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbiAsIDEpLmQoKSk7CisgIEVYUEVDVF9FUSg1MjcsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9sYXp5X21lc3NhZ2VfZXh0ZW5zaW9uICAgLCAxKS5iYigpKTsKKworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6Rk9PLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uICwgMSkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fRk9PICAgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbiwgMSkpOworICBFWFBFQ1RfRVEodW5pdHRlc3RfaW1wb3J0OjpJTVBPUlRfRk9PLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW1wb3J0X2VudW1fZXh0ZW5zaW9uICwgMSkpOworCisgIEVYUEVDVF9FUSgiNTI0IiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19waWVjZV9leHRlbnNpb24sIDEpKTsKKyAgRVhQRUNUX0VRKCI1MjUiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfY29yZF9leHRlbnNpb24sIDEpKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIFRlc3RVdGlsOjpTZXRQYWNrZWRFeHRlbnNpb25zKHVuaXR0ZXN0OjpUZXN0UGFja2VkRXh0ZW5zaW9ucyogbWVzc2FnZSkgeworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9pbnQzMl9leHRlbnNpb24gICAsIDYwMSk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ludDY0X2V4dGVuc2lvbiAgICwgNjAyKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfdWludDMyX2V4dGVuc2lvbiAgLCA2MDMpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF91aW50NjRfZXh0ZW5zaW9uICAsIDYwNCk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3NpbnQzMl9leHRlbnNpb24gICwgNjA1KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfc2ludDY0X2V4dGVuc2lvbiAgLCA2MDYpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9maXhlZDMyX2V4dGVuc2lvbiAsIDYwNyk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ZpeGVkNjRfZXh0ZW5zaW9uICwgNjA4KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uLCA2MDkpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9zZml4ZWQ2NF9leHRlbnNpb24sIDYxMCk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2Zsb2F0X2V4dGVuc2lvbiAgICwgNjExKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZG91YmxlX2V4dGVuc2lvbiAgLCA2MTIpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9ib29sX2V4dGVuc2lvbiAgICAsIHRydWUpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9lbnVtX2V4dGVuc2lvbiwgdW5pdHRlc3Q6OkZPUkVJR05fQkFSKTsKKyAgLy8gYWRkIGEgc2Vjb25kIG9uZSBvZiBlYWNoIGZpZWxkCisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ludDMyX2V4dGVuc2lvbiAgICwgNzAxKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfaW50NjRfZXh0ZW5zaW9uICAgLCA3MDIpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF91aW50MzJfZXh0ZW5zaW9uICAsIDcwMyk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3VpbnQ2NF9leHRlbnNpb24gICwgNzA0KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfc2ludDMyX2V4dGVuc2lvbiAgLCA3MDUpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9zaW50NjRfZXh0ZW5zaW9uICAsIDcwNik7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ZpeGVkMzJfZXh0ZW5zaW9uICwgNzA3KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZml4ZWQ2NF9leHRlbnNpb24gLCA3MDgpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9zZml4ZWQzMl9leHRlbnNpb24sIDcwOSk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3NmaXhlZDY0X2V4dGVuc2lvbiwgNzEwKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZmxvYXRfZXh0ZW5zaW9uICAgLCA3MTEpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9kb3VibGVfZXh0ZW5zaW9uICAsIDcxMik7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2Jvb2xfZXh0ZW5zaW9uICAgICwgZmFsc2UpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9lbnVtX2V4dGVuc2lvbiwgdW5pdHRlc3Q6OkZPUkVJR05fQkFaKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIFRlc3RVdGlsOjpNb2RpZnlQYWNrZWRFeHRlbnNpb25zKHVuaXR0ZXN0OjpUZXN0UGFja2VkRXh0ZW5zaW9ucyogbWVzc2FnZSkgeworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9pbnQzMl9leHRlbnNpb24gICAsIDEsIDgwMSk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ludDY0X2V4dGVuc2lvbiAgICwgMSwgODAyKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfdWludDMyX2V4dGVuc2lvbiAgLCAxLCA4MDMpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF91aW50NjRfZXh0ZW5zaW9uICAsIDEsIDgwNCk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3NpbnQzMl9leHRlbnNpb24gICwgMSwgODA1KTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfc2ludDY0X2V4dGVuc2lvbiAgLCAxLCA4MDYpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9maXhlZDMyX2V4dGVuc2lvbiAsIDEsIDgwNyk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ZpeGVkNjRfZXh0ZW5zaW9uICwgMSwgODA4KTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uLCAxLCA4MDkpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9zZml4ZWQ2NF9leHRlbnNpb24sIDEsIDgxMCk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2Zsb2F0X2V4dGVuc2lvbiAgICwgMSwgODExKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZG91YmxlX2V4dGVuc2lvbiAgLCAxLCA4MTIpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9ib29sX2V4dGVuc2lvbiAgICAsIDEsIHRydWUpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9lbnVtX2V4dGVuc2lvbiAgICAsIDEsCisgICAgICAgICAgICAgICAgICAgICAgICB1bml0dGVzdDo6Rk9SRUlHTl9GT08pOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3ZvaWQgVGVzdFV0aWw6OkV4cGVjdFBhY2tlZEV4dGVuc2lvbnNTZXQoCisgICAgY29uc3QgdW5pdHRlc3Q6OlRlc3RQYWNrZWRFeHRlbnNpb25zJiBtZXNzYWdlKSB7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9pbnQzMl9leHRlbnNpb24gICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX2ludDY0X2V4dGVuc2lvbiAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfdWludDMyX2V4dGVuc2lvbiAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF91aW50NjRfZXh0ZW5zaW9uICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX3NpbnQzMl9leHRlbnNpb24gICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfc2ludDY0X2V4dGVuc2lvbiAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9maXhlZDMyX2V4dGVuc2lvbiApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX2ZpeGVkNjRfZXh0ZW5zaW9uICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9zZml4ZWQ2NF9leHRlbnNpb24pKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX2Zsb2F0X2V4dGVuc2lvbiAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfZG91YmxlX2V4dGVuc2lvbiAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9ib29sX2V4dGVuc2lvbiAgICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX2VudW1fZXh0ZW5zaW9uICAgICkpOworCisgIEVYUEVDVF9FUSg2MDEgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9pbnQzMl9leHRlbnNpb24gICAsIDApKTsKKyAgRVhQRUNUX0VRKDYwMiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ludDY0X2V4dGVuc2lvbiAgICwgMCkpOworICBFWFBFQ1RfRVEoNjAzICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfdWludDMyX2V4dGVuc2lvbiAgLCAwKSk7CisgIEVYUEVDVF9FUSg2MDQgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF91aW50NjRfZXh0ZW5zaW9uICAsIDApKTsKKyAgRVhQRUNUX0VRKDYwNSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3NpbnQzMl9leHRlbnNpb24gICwgMCkpOworICBFWFBFQ1RfRVEoNjA2ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfc2ludDY0X2V4dGVuc2lvbiAgLCAwKSk7CisgIEVYUEVDVF9FUSg2MDcgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9maXhlZDMyX2V4dGVuc2lvbiAsIDApKTsKKyAgRVhQRUNUX0VRKDYwOCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ZpeGVkNjRfZXh0ZW5zaW9uICwgMCkpOworICBFWFBFQ1RfRVEoNjA5ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uLCAwKSk7CisgIEVYUEVDVF9FUSg2MTAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9zZml4ZWQ2NF9leHRlbnNpb24sIDApKTsKKyAgRVhQRUNUX0VRKDYxMSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2Zsb2F0X2V4dGVuc2lvbiAgICwgMCkpOworICBFWFBFQ1RfRVEoNjEyICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZG91YmxlX2V4dGVuc2lvbiAgLCAwKSk7CisgIEVYUEVDVF9UUlVFKCAgICAgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9ib29sX2V4dGVuc2lvbiAgICAsIDApKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0JBUiwKKyAgICAgICAgICAgIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZW51bV9leHRlbnNpb24sIDApKTsKKyAgRVhQRUNUX0VRKDcwMSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ludDMyX2V4dGVuc2lvbiAgICwgMSkpOworICBFWFBFQ1RfRVEoNzAyICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfaW50NjRfZXh0ZW5zaW9uICAgLCAxKSk7CisgIEVYUEVDVF9FUSg3MDMgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF91aW50MzJfZXh0ZW5zaW9uICAsIDEpKTsKKyAgRVhQRUNUX0VRKDcwNCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3VpbnQ2NF9leHRlbnNpb24gICwgMSkpOworICBFWFBFQ1RfRVEoNzA1ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfc2ludDMyX2V4dGVuc2lvbiAgLCAxKSk7CisgIEVYUEVDVF9FUSg3MDYgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9zaW50NjRfZXh0ZW5zaW9uICAsIDEpKTsKKyAgRVhQRUNUX0VRKDcwNyAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ZpeGVkMzJfZXh0ZW5zaW9uICwgMSkpOworICBFWFBFQ1RfRVEoNzA4ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZml4ZWQ2NF9leHRlbnNpb24gLCAxKSk7CisgIEVYUEVDVF9FUSg3MDkgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9zZml4ZWQzMl9leHRlbnNpb24sIDEpKTsKKyAgRVhQRUNUX0VRKDcxMCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3NmaXhlZDY0X2V4dGVuc2lvbiwgMSkpOworICBFWFBFQ1RfRVEoNzExICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZmxvYXRfZXh0ZW5zaW9uICAgLCAxKSk7CisgIEVYUEVDVF9FUSg3MTIgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9kb3VibGVfZXh0ZW5zaW9uICAsIDEpKTsKKyAgRVhQRUNUX0ZBTFNFKCAgICBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2Jvb2xfZXh0ZW5zaW9uICAgICwgMSkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fQkFaLAorICAgICAgICAgICAgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9lbnVtX2V4dGVuc2lvbiwgMSkpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3ZvaWQgVGVzdFV0aWw6OkV4cGVjdFBhY2tlZEV4dGVuc2lvbnNDbGVhcigKKyAgICBjb25zdCB1bml0dGVzdDo6VGVzdFBhY2tlZEV4dGVuc2lvbnMmIG1lc3NhZ2UpIHsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX2ludDMyX2V4dGVuc2lvbiAgICkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfaW50NjRfZXh0ZW5zaW9uICAgKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF91aW50MzJfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX3VpbnQ2NF9leHRlbnNpb24gICkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfc2ludDMyX2V4dGVuc2lvbiAgKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9zaW50NjRfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX2ZpeGVkMzJfZXh0ZW5zaW9uICkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfZml4ZWQ2NF9leHRlbnNpb24gKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9zZml4ZWQzMl9leHRlbnNpb24pKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX3NmaXhlZDY0X2V4dGVuc2lvbikpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfZmxvYXRfZXh0ZW5zaW9uICAgKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9kb3VibGVfZXh0ZW5zaW9uICApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX2Jvb2xfZXh0ZW5zaW9uICAgICkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfZW51bV9leHRlbnNpb24gICAgKSk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBUZXN0VXRpbDo6RXhwZWN0UGFja2VkRXh0ZW5zaW9uc01vZGlmaWVkKAorICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0UGFja2VkRXh0ZW5zaW9ucyYgbWVzc2FnZSkgeworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfaW50MzJfZXh0ZW5zaW9uICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9pbnQ2NF9leHRlbnNpb24gICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX3VpbnQzMl9leHRlbnNpb24gICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfdWludDY0X2V4dGVuc2lvbiAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9zaW50MzJfZXh0ZW5zaW9uICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX3NpbnQ2NF9leHRlbnNpb24gICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfZml4ZWQzMl9leHRlbnNpb24gKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9maXhlZDY0X2V4dGVuc2lvbiApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX3NmaXhlZDMyX2V4dGVuc2lvbikpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfc2ZpeGVkNjRfZXh0ZW5zaW9uKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9mbG9hdF9leHRlbnNpb24gICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX2RvdWJsZV9leHRlbnNpb24gICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfYm9vbF9leHRlbnNpb24gICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9lbnVtX2V4dGVuc2lvbiAgICApKTsKKyAgRVhQRUNUX0VRKDYwMSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ludDMyX2V4dGVuc2lvbiAgICwgMCkpOworICBFWFBFQ1RfRVEoNjAyICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfaW50NjRfZXh0ZW5zaW9uICAgLCAwKSk7CisgIEVYUEVDVF9FUSg2MDMgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF91aW50MzJfZXh0ZW5zaW9uICAsIDApKTsKKyAgRVhQRUNUX0VRKDYwNCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3VpbnQ2NF9leHRlbnNpb24gICwgMCkpOworICBFWFBFQ1RfRVEoNjA1ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfc2ludDMyX2V4dGVuc2lvbiAgLCAwKSk7CisgIEVYUEVDVF9FUSg2MDYgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9zaW50NjRfZXh0ZW5zaW9uICAsIDApKTsKKyAgRVhQRUNUX0VRKDYwNyAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ZpeGVkMzJfZXh0ZW5zaW9uICwgMCkpOworICBFWFBFQ1RfRVEoNjA4ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZml4ZWQ2NF9leHRlbnNpb24gLCAwKSk7CisgIEVYUEVDVF9FUSg2MDkgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9zZml4ZWQzMl9leHRlbnNpb24sIDApKTsKKyAgRVhQRUNUX0VRKDYxMCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3NmaXhlZDY0X2V4dGVuc2lvbiwgMCkpOworICBFWFBFQ1RfRVEoNjExICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZmxvYXRfZXh0ZW5zaW9uICAgLCAwKSk7CisgIEVYUEVDVF9FUSg2MTIgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9kb3VibGVfZXh0ZW5zaW9uICAsIDApKTsKKyAgRVhQRUNUX1RSVUUoICAgICBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2Jvb2xfZXh0ZW5zaW9uICAgICwgMCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fQkFSLAorICAgICAgICAgICAgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9lbnVtX2V4dGVuc2lvbiwgMCkpOworCisgIC8vIEFjdHVhbGx5IHZlcmlmeSB0aGUgc2Vjb25kIChtb2RpZmllZCkgZWxlbWVudHMgbm93LgorICBFWFBFQ1RfRVEoODAxICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfaW50MzJfZXh0ZW5zaW9uICAgLCAxKSk7CisgIEVYUEVDVF9FUSg4MDIgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9pbnQ2NF9leHRlbnNpb24gICAsIDEpKTsKKyAgRVhQRUNUX0VRKDgwMyAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3VpbnQzMl9leHRlbnNpb24gICwgMSkpOworICBFWFBFQ1RfRVEoODA0ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfdWludDY0X2V4dGVuc2lvbiAgLCAxKSk7CisgIEVYUEVDVF9FUSg4MDUgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9zaW50MzJfZXh0ZW5zaW9uICAsIDEpKTsKKyAgRVhQRUNUX0VRKDgwNiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3NpbnQ2NF9leHRlbnNpb24gICwgMSkpOworICBFWFBFQ1RfRVEoODA3ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZml4ZWQzMl9leHRlbnNpb24gLCAxKSk7CisgIEVYUEVDVF9FUSg4MDggICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9maXhlZDY0X2V4dGVuc2lvbiAsIDEpKTsKKyAgRVhQRUNUX0VRKDgwOSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3NmaXhlZDMyX2V4dGVuc2lvbiwgMSkpOworICBFWFBFQ1RfRVEoODEwICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfc2ZpeGVkNjRfZXh0ZW5zaW9uLCAxKSk7CisgIEVYUEVDVF9FUSg4MTEgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9mbG9hdF9leHRlbnNpb24gICAsIDEpKTsKKyAgRVhQRUNUX0VRKDgxMiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2RvdWJsZV9leHRlbnNpb24gICwgMSkpOworICBFWFBFQ1RfVFJVRSggICAgIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfYm9vbF9leHRlbnNpb24gICAgLCAxKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9SRUlHTl9GT08sCisgICAgICAgICAgICBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2VudW1fZXh0ZW5zaW9uLCAxKSk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBUZXN0VXRpbDo6RXhwZWN0VW5wYWNrZWRFeHRlbnNpb25zU2V0KAorICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0VW5wYWNrZWRFeHRlbnNpb25zJiBtZXNzYWdlKSB7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnVucGFja2VkX2ludDMyX2V4dGVuc2lvbiAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0Ojp1bnBhY2tlZF9pbnQ2NF9leHRlbnNpb24gICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6dW5wYWNrZWRfdWludDMyX2V4dGVuc2lvbiAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnVucGFja2VkX3VpbnQ2NF9leHRlbnNpb24gICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0Ojp1bnBhY2tlZF9zaW50MzJfZXh0ZW5zaW9uICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6dW5wYWNrZWRfc2ludDY0X2V4dGVuc2lvbiAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnVucGFja2VkX2ZpeGVkMzJfZXh0ZW5zaW9uICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0Ojp1bnBhY2tlZF9maXhlZDY0X2V4dGVuc2lvbiApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6dW5wYWNrZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnVucGFja2VkX3NmaXhlZDY0X2V4dGVuc2lvbikpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0Ojp1bnBhY2tlZF9mbG9hdF9leHRlbnNpb24gICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6dW5wYWNrZWRfZG91YmxlX2V4dGVuc2lvbiAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnVucGFja2VkX2Jvb2xfZXh0ZW5zaW9uICAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0Ojp1bnBhY2tlZF9lbnVtX2V4dGVuc2lvbiAgICApKTsKKworICBFWFBFQ1RfRVEoNjAxICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0Ojp1bnBhY2tlZF9pbnQzMl9leHRlbnNpb24gICAsIDApKTsKKyAgRVhQRUNUX0VRKDYwMiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6dW5wYWNrZWRfaW50NjRfZXh0ZW5zaW9uICAgLCAwKSk7CisgIEVYUEVDVF9FUSg2MDMgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnVucGFja2VkX3VpbnQzMl9leHRlbnNpb24gICwgMCkpOworICBFWFBFQ1RfRVEoNjA0ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0Ojp1bnBhY2tlZF91aW50NjRfZXh0ZW5zaW9uICAsIDApKTsKKyAgRVhQRUNUX0VRKDYwNSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6dW5wYWNrZWRfc2ludDMyX2V4dGVuc2lvbiAgLCAwKSk7CisgIEVYUEVDVF9FUSg2MDYgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnVucGFja2VkX3NpbnQ2NF9leHRlbnNpb24gICwgMCkpOworICBFWFBFQ1RfRVEoNjA3ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0Ojp1bnBhY2tlZF9maXhlZDMyX2V4dGVuc2lvbiAsIDApKTsKKyAgRVhQRUNUX0VRKDYwOCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6dW5wYWNrZWRfZml4ZWQ2NF9leHRlbnNpb24gLCAwKSk7CisgIEVYUEVDVF9FUSg2MDkgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnVucGFja2VkX3NmaXhlZDMyX2V4dGVuc2lvbiwgMCkpOworICBFWFBFQ1RfRVEoNjEwICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0Ojp1bnBhY2tlZF9zZml4ZWQ2NF9leHRlbnNpb24sIDApKTsKKyAgRVhQRUNUX0VRKDYxMSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6dW5wYWNrZWRfZmxvYXRfZXh0ZW5zaW9uICAgLCAwKSk7CisgIEVYUEVDVF9FUSg2MTIgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnVucGFja2VkX2RvdWJsZV9leHRlbnNpb24gICwgMCkpOworICBFWFBFQ1RfRVEodHJ1ZSAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0Ojp1bnBhY2tlZF9ib29sX2V4dGVuc2lvbiAgICAsIDApKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0JBUiwKKyAgICAgICAgICAgIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0Ojp1bnBhY2tlZF9lbnVtX2V4dGVuc2lvbiwgMCkpOworICBFWFBFQ1RfRVEoNzAxICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0Ojp1bnBhY2tlZF9pbnQzMl9leHRlbnNpb24gICAsIDEpKTsKKyAgRVhQRUNUX0VRKDcwMiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6dW5wYWNrZWRfaW50NjRfZXh0ZW5zaW9uICAgLCAxKSk7CisgIEVYUEVDVF9FUSg3MDMgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnVucGFja2VkX3VpbnQzMl9leHRlbnNpb24gICwgMSkpOworICBFWFBFQ1RfRVEoNzA0ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0Ojp1bnBhY2tlZF91aW50NjRfZXh0ZW5zaW9uICAsIDEpKTsKKyAgRVhQRUNUX0VRKDcwNSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6dW5wYWNrZWRfc2ludDMyX2V4dGVuc2lvbiAgLCAxKSk7CisgIEVYUEVDVF9FUSg3MDYgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnVucGFja2VkX3NpbnQ2NF9leHRlbnNpb24gICwgMSkpOworICBFWFBFQ1RfRVEoNzA3ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0Ojp1bnBhY2tlZF9maXhlZDMyX2V4dGVuc2lvbiAsIDEpKTsKKyAgRVhQRUNUX0VRKDcwOCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6dW5wYWNrZWRfZml4ZWQ2NF9leHRlbnNpb24gLCAxKSk7CisgIEVYUEVDVF9FUSg3MDkgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnVucGFja2VkX3NmaXhlZDMyX2V4dGVuc2lvbiwgMSkpOworICBFWFBFQ1RfRVEoNzEwICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0Ojp1bnBhY2tlZF9zZml4ZWQ2NF9leHRlbnNpb24sIDEpKTsKKyAgRVhQRUNUX0VRKDcxMSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6dW5wYWNrZWRfZmxvYXRfZXh0ZW5zaW9uICAgLCAxKSk7CisgIEVYUEVDVF9FUSg3MTIgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnVucGFja2VkX2RvdWJsZV9leHRlbnNpb24gICwgMSkpOworICBFWFBFQ1RfRVEoZmFsc2UsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0Ojp1bnBhY2tlZF9ib29sX2V4dGVuc2lvbiAgICAsIDEpKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0JBWiwKKyAgICAgICAgICAgIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0Ojp1bnBhY2tlZF9lbnVtX2V4dGVuc2lvbiwgMSkpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3ZvaWQgVGVzdFV0aWw6OkV4cGVjdEFsbEZpZWxkc0FuZEV4dGVuc2lvbnNJbk9yZGVyKGNvbnN0IHN0cmluZyYgc2VyaWFsaXplZCkgeworICAvLyBXZSBzZXQgZWFjaCBmaWVsZCBpbmRpdmlkdWFsbHksIHNlcmlhbGl6ZSBzZXBhcmF0ZWx5LCBhbmQgY29uY2F0ZW5hdGUgYWxsCisgIC8vIHRoZSBzdHJpbmdzIGluIGNhbm9uaWNhbCBvcmRlciB0byBkZXRlcm1pbmUgdGhlIGV4cGVjdGVkIHNlcmlhbGl6YXRpb24uCisgIHN0cmluZyBleHBlY3RlZDsKKyAgdW5pdHRlc3Q6OlRlc3RGaWVsZE9yZGVyaW5ncyBtZXNzYWdlOworICBtZXNzYWdlLnNldF9teV9pbnQoMSk7ICAvLyBGaWVsZCAxLgorICBtZXNzYWdlLkFwcGVuZFRvU3RyaW5nKCZleHBlY3RlZCk7CisgIG1lc3NhZ2UuQ2xlYXIoKTsKKyAgbWVzc2FnZS5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om15X2V4dGVuc2lvbl9pbnQsIDIzKTsgIC8vIEZpZWxkIDUuCisgIG1lc3NhZ2UuQXBwZW5kVG9TdHJpbmcoJmV4cGVjdGVkKTsKKyAgbWVzc2FnZS5DbGVhcigpOworICBtZXNzYWdlLnNldF9teV9zdHJpbmcoImZvbyIpOyAgLy8gRmllbGQgMTEuCisgIG1lc3NhZ2UuQXBwZW5kVG9TdHJpbmcoJmV4cGVjdGVkKTsKKyAgbWVzc2FnZS5DbGVhcigpOworICBtZXNzYWdlLlNldEV4dGVuc2lvbih1bml0dGVzdDo6bXlfZXh0ZW5zaW9uX3N0cmluZywgImJhciIpOyAgLy8gRmllbGQgNTAuCisgIG1lc3NhZ2UuQXBwZW5kVG9TdHJpbmcoJmV4cGVjdGVkKTsKKyAgbWVzc2FnZS5DbGVhcigpOworICBtZXNzYWdlLnNldF9teV9mbG9hdCgxLjApOyAgLy8gRmllbGQgMTAxLgorICBtZXNzYWdlLkFwcGVuZFRvU3RyaW5nKCZleHBlY3RlZCk7CisgIG1lc3NhZ2UuQ2xlYXIoKTsKKworICAvLyBXZSBkb24ndCBFWFBFQ1RfRVEoKSBzaW5jZSB3ZSBkb24ndCB3YW50IHRvIHByaW50IHJhdyBieXRlcyB0byBzdGRvdXQuCisgIEVYUEVDVF9UUlVFKHNlcmlhbGl6ZWQgPT0gZXhwZWN0ZWQpOworfQorCit2b2lkIFRlc3RVdGlsOjpFeHBlY3RMYXN0UmVwZWF0ZWRzUmVtb3ZlZCgKKyAgICBjb25zdCB1bml0dGVzdDo6VGVzdEFsbFR5cGVzJiBtZXNzYWdlKSB7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX2ludDMyX3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX2ludDY0X3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX3VpbnQzMl9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX3VpbnQ2NF9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX3NpbnQzMl9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX3NpbnQ2NF9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX2ZpeGVkMzJfc2l6ZSAoKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX2ZpeGVkNjRfc2l6ZSAoKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX3NmaXhlZDMyX3NpemUoKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX3NmaXhlZDY0X3NpemUoKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX2Zsb2F0X3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX2RvdWJsZV9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX2Jvb2xfc2l6ZSAgICAoKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX3N0cmluZ19zaXplICAoKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX2J5dGVzX3NpemUgICAoKSk7CisKKyAgQVNTRVJUX0VRKDEsIG1lc3NhZ2UucmVwZWF0ZWRncm91cF9zaXplICAgICAgICAgICAoKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX3NpemUgKCkpOworICBBU1NFUlRfRVEoMSwgbWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2Vfc2l6ZSgpKTsKKyAgQVNTRVJUX0VRKDEsIG1lc3NhZ2UucmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2Vfc2l6ZSAoKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlX3NpemUgKCkpOworICBBU1NFUlRfRVEoMSwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfZW51bV9zaXplICAgICgpKTsKKyAgQVNTRVJUX0VRKDEsIG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9lbnVtX3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9lbnVtX3NpemUgICAgKCkpOworCisjaWZuZGVmIFBST1RPQlVGX1RFU1RfTk9fREVTQ1JJUFRPUlMKKyAgQVNTRVJUX0VRKDEsIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nX3BpZWNlX3NpemUoKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX2NvcmRfc2l6ZSgpKTsKKyNlbmRpZgorCisgIC8vIFRlc3QgdGhhdCB0aGUgcmVtYWluaW5nIGVsZW1lbnQgaXMgdGhlIGNvcnJlY3Qgb25lLgorICBFWFBFQ1RfRVEoMjAxICAsIG1lc3NhZ2UucmVwZWF0ZWRfaW50MzIgICAoMCkpOworICBFWFBFQ1RfRVEoMjAyICAsIG1lc3NhZ2UucmVwZWF0ZWRfaW50NjQgICAoMCkpOworICBFWFBFQ1RfRVEoMjAzICAsIG1lc3NhZ2UucmVwZWF0ZWRfdWludDMyICAoMCkpOworICBFWFBFQ1RfRVEoMjA0ICAsIG1lc3NhZ2UucmVwZWF0ZWRfdWludDY0ICAoMCkpOworICBFWFBFQ1RfRVEoMjA1ICAsIG1lc3NhZ2UucmVwZWF0ZWRfc2ludDMyICAoMCkpOworICBFWFBFQ1RfRVEoMjA2ICAsIG1lc3NhZ2UucmVwZWF0ZWRfc2ludDY0ICAoMCkpOworICBFWFBFQ1RfRVEoMjA3ICAsIG1lc3NhZ2UucmVwZWF0ZWRfZml4ZWQzMiAoMCkpOworICBFWFBFQ1RfRVEoMjA4ICAsIG1lc3NhZ2UucmVwZWF0ZWRfZml4ZWQ2NCAoMCkpOworICBFWFBFQ1RfRVEoMjA5ICAsIG1lc3NhZ2UucmVwZWF0ZWRfc2ZpeGVkMzIoMCkpOworICBFWFBFQ1RfRVEoMjEwICAsIG1lc3NhZ2UucmVwZWF0ZWRfc2ZpeGVkNjQoMCkpOworICBFWFBFQ1RfRVEoMjExICAsIG1lc3NhZ2UucmVwZWF0ZWRfZmxvYXQgICAoMCkpOworICBFWFBFQ1RfRVEoMjEyICAsIG1lc3NhZ2UucmVwZWF0ZWRfZG91YmxlICAoMCkpOworICBFWFBFQ1RfVFJVRSggICAgIG1lc3NhZ2UucmVwZWF0ZWRfYm9vbCAgICAoMCkpOworICBFWFBFQ1RfRVEoIjIxNSIsIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nICAoMCkpOworICBFWFBFQ1RfRVEoIjIxNiIsIG1lc3NhZ2UucmVwZWF0ZWRfYnl0ZXMgICAoMCkpOworCisgIEVYUEVDVF9FUSgyMTcsIG1lc3NhZ2UucmVwZWF0ZWRncm91cCAgICAgICAgICAgKDApLmEoKSk7CisgIEVYUEVDVF9FUSgyMTgsIG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgKDApLmJiKCkpOworICBFWFBFQ1RfRVEoMjE5LCBtZXNzYWdlLnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSgwKS5jKCkpOworICBFWFBFQ1RfRVEoMjIwLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlICgwKS5kKCkpOworICBFWFBFQ1RfRVEoMjIwLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlICgwKS5kKCkpOworCisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpCQVIsIG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX2VudW0gKDApKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0JBUiAgICAgICwgbWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX2VudW0oMCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3RfaW1wb3J0OjpJTVBPUlRfQkFSLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9lbnVtICgwKSk7Cit9CisKK3ZvaWQgVGVzdFV0aWw6OkV4cGVjdExhc3RSZXBlYXRlZEV4dGVuc2lvbnNSZW1vdmVkKAorICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyYgbWVzc2FnZSkgeworCisgIC8vIFRlc3QgdGhhdCBvbmUgZWxlbWVudCB3YXMgcmVtb3ZlZC4KKyAgQVNTRVJUX0VRKDEsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9uICAgKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ludDY0X2V4dGVuc2lvbiAgICkpOworICBBU1NFUlRfRVEoMSwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF91aW50MzJfZXh0ZW5zaW9uICApKTsKKyAgQVNTRVJUX0VRKDEsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfdWludDY0X2V4dGVuc2lvbiAgKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3NpbnQzMl9leHRlbnNpb24gICkpOworICBBU1NFUlRfRVEoMSwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50NjRfZXh0ZW5zaW9uICApKTsKKyAgQVNTRVJUX0VRKDEsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfZml4ZWQzMl9leHRlbnNpb24gKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkNjRfZXh0ZW5zaW9uICkpOworICBBU1NFUlRfRVEoMSwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9zZml4ZWQzMl9leHRlbnNpb24pKTsKKyAgQVNTRVJUX0VRKDEsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfc2ZpeGVkNjRfZXh0ZW5zaW9uKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2Zsb2F0X2V4dGVuc2lvbiAgICkpOworICBBU1NFUlRfRVEoMSwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9kb3VibGVfZXh0ZW5zaW9uICApKTsKKyAgQVNTRVJUX0VRKDEsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfYm9vbF9leHRlbnNpb24gICAgKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb24gICkpOworICBBU1NFUlRfRVEoMSwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9ieXRlc19leHRlbnNpb24gICApKTsKKworICBBU1NFUlRfRVEoMSwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZGdyb3VwX2V4dGVuc2lvbiAgICAgICAgICAgKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiApKTsKKyAgQVNTRVJUX0VRKDEsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbikpOworICBBU1NFUlRfRVEoMSwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb24gKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2xhenlfbWVzc2FnZV9leHRlbnNpb24gICApKTsKKyAgQVNTRVJUX0VRKDEsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uICAgICkpOworICBBU1NFUlRfRVEoMSwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uICAgKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ltcG9ydF9lbnVtX2V4dGVuc2lvbiAgICApKTsKKworICBBU1NFUlRfRVEoMSwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9zdHJpbmdfcGllY2VfZXh0ZW5zaW9uKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2NvcmRfZXh0ZW5zaW9uKSk7CisKKyAgLy8gVGVzdCB0aGF0IHRoZSByZW1haW5pbmcgZWxlbWVudCBpcyB0aGUgY29ycmVjdCBvbmUuCisgIEVYUEVDVF9FUSgyMDEgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ludDMyX2V4dGVuc2lvbiAgICwgMCkpOworICBFWFBFQ1RfRVEoMjAyICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbnQ2NF9leHRlbnNpb24gICAsIDApKTsKKyAgRVhQRUNUX0VRKDIwMyAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfdWludDMyX2V4dGVuc2lvbiAgLCAwKSk7CisgIEVYUEVDVF9FUSgyMDQgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3VpbnQ2NF9leHRlbnNpb24gICwgMCkpOworICBFWFBFQ1RfRVEoMjA1ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50MzJfZXh0ZW5zaW9uICAsIDApKTsKKyAgRVhQRUNUX0VRKDIwNiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ludDY0X2V4dGVuc2lvbiAgLCAwKSk7CisgIEVYUEVDVF9FUSgyMDcgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkMzJfZXh0ZW5zaW9uICwgMCkpOworICBFWFBFQ1RfRVEoMjA4ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9maXhlZDY0X2V4dGVuc2lvbiAsIDApKTsKKyAgRVhQRUNUX0VRKDIwOSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uLCAwKSk7CisgIEVYUEVDVF9FUSgyMTAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NmaXhlZDY0X2V4dGVuc2lvbiwgMCkpOworICBFWFBFQ1RfRVEoMjExICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9mbG9hdF9leHRlbnNpb24gICAsIDApKTsKKyAgRVhQRUNUX0VRKDIxMiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZG91YmxlX2V4dGVuc2lvbiAgLCAwKSk7CisgIEVYUEVDVF9UUlVFKCAgICAgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2Jvb2xfZXh0ZW5zaW9uICAgICwgMCkpOworICBFWFBFQ1RfRVEoIjIxNSIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zdHJpbmdfZXh0ZW5zaW9uICAsIDApKTsKKyAgRVhQRUNUX0VRKCIyMTYiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfYnl0ZXNfZXh0ZW5zaW9uICAgLCAwKSk7CisKKyAgRVhQRUNUX0VRKDIxNywgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkZ3JvdXBfZXh0ZW5zaW9uICAgICAgICAgICAsIDApLmEoKSk7CisgIEVYUEVDVF9FUSgyMTgsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb24gLCAwKS5iYigpKTsKKyAgRVhQRUNUX0VRKDIxOSwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb24sIDApLmMoKSk7CisgIEVYUEVDVF9FUSgyMjAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb24gLCAwKS5kKCkpOworICBFWFBFQ1RfRVEoMjI3LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbGF6eV9tZXNzYWdlX2V4dGVuc2lvbiAgICwgMCkuYmIoKSk7CisKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkJBUiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9lbnVtX2V4dGVuc2lvbiAsIDApKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0JBUiAgICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZvcmVpZ25fZW51bV9leHRlbnNpb24sIDApKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0X2ltcG9ydDo6SU1QT1JUX0JBUiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ltcG9ydF9lbnVtX2V4dGVuc2lvbiAsIDApKTsKKworICBFWFBFQ1RfRVEoIjIyNCIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zdHJpbmdfcGllY2VfZXh0ZW5zaW9uLCAwKSk7CisgIEVYUEVDVF9FUSgiMjI1IiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2NvcmRfZXh0ZW5zaW9uLCAwKSk7Cit9CisKK3ZvaWQgVGVzdFV0aWw6OkV4cGVjdExhc3RSZXBlYXRlZHNSZWxlYXNlZCgKKyAgICBjb25zdCB1bml0dGVzdDo6VGVzdEFsbFR5cGVzJiBtZXNzYWdlKSB7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkZ3JvdXBfc2l6ZSAgICAgICAgICAgKCkpOworICBBU1NFUlRfRVEoMSwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9zaXplICgpKTsKKyAgQVNTRVJUX0VRKDEsIG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX3NpemUoKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlX3NpemUgKCkpOworICBBU1NFUlRfRVEoMSwgbWVzc2FnZS5yZXBlYXRlZF9pbXBvcnRfbWVzc2FnZV9zaXplICgpKTsKKworICBFWFBFQ1RfRVEoMjE3LCBtZXNzYWdlLnJlcGVhdGVkZ3JvdXAgICAgICAgICAgICgwKS5hKCkpOworICBFWFBFQ1RfRVEoMjE4LCBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlICgwKS5iYigpKTsKKyAgRVhQRUNUX0VRKDIxOSwgbWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UoMCkuYygpKTsKKyAgRVhQRUNUX0VRKDIyMCwgbWVzc2FnZS5yZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSAoMCkuZCgpKTsKKyAgRVhQRUNUX0VRKDIyMCwgbWVzc2FnZS5yZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSAoMCkuZCgpKTsKK30KKwordm9pZCBUZXN0VXRpbDo6RXhwZWN0TGFzdFJlcGVhdGVkRXh0ZW5zaW9uc1JlbGVhc2VkKAorICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyYgbWVzc2FnZSkgeworICBBU1NFUlRfRVEoMSwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZGdyb3VwX2V4dGVuc2lvbiAgICAgICAgICAgKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiApKTsKKyAgQVNTRVJUX0VRKDEsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbikpOworICBBU1NFUlRfRVEoMSwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb24gKSk7CisgIEFTU0VSVF9FUSgxLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2xhenlfbWVzc2FnZV9leHRlbnNpb24gICApKTsKKworICBFWFBFQ1RfRVEoMjE3LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRncm91cF9leHRlbnNpb24gICAgICAgICAgICwgMCkuYSgpKTsKKyAgRVhQRUNUX0VRKDIxOCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiAsIDApLmJiKCkpOworICBFWFBFQ1RfRVEoMjE5LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbiwgMCkuYygpKTsKKyAgRVhQRUNUX0VRKDIyMCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbiAsIDApLmQoKSk7CisgIEVYUEVDVF9FUSgyMjcsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9sYXp5X21lc3NhZ2VfZXh0ZW5zaW9uICAgLCAwKS5iYigpKTsKK30KKwordm9pZCBUZXN0VXRpbDo6RXhwZWN0UmVwZWF0ZWRzU3dhcHBlZCgKKyAgICBjb25zdCB1bml0dGVzdDo6VGVzdEFsbFR5cGVzJiBtZXNzYWdlKSB7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ludDMyX3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ludDY0X3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3VpbnQzMl9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3VpbnQ2NF9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3NpbnQzMl9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3NpbnQ2NF9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ZpeGVkMzJfc2l6ZSAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ZpeGVkNjRfc2l6ZSAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3NmaXhlZDMyX3NpemUoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3NmaXhlZDY0X3NpemUoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2Zsb2F0X3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2RvdWJsZV9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2Jvb2xfc2l6ZSAgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3N0cmluZ19zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2J5dGVzX3NpemUgICAoKSk7CisKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRncm91cF9zaXplICAgICAgICAgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX3NpemUgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2Vfc2l6ZSgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2Vfc2l6ZSAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlX3NpemUgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfZW51bV9zaXplICAgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9lbnVtX3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9lbnVtX3NpemUgICAgKCkpOworCisjaWZuZGVmIFBST1RPQlVGX1RFU1RfTk9fREVTQ1JJUFRPUlMKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nX3BpZWNlX3NpemUoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2NvcmRfc2l6ZSgpKTsKKyNlbmRpZgorCisgIC8vIFRlc3QgdGhhdCB0aGUgZmlyc3QgZWxlbWVudCBhbmQgc2Vjb25kIGVsZW1lbnQgYXJlIGZsaXBwZWQuCisgIEVYUEVDVF9FUSgyMDEgICwgbWVzc2FnZS5yZXBlYXRlZF9pbnQzMiAgICgxKSk7CisgIEVYUEVDVF9FUSgyMDIgICwgbWVzc2FnZS5yZXBlYXRlZF9pbnQ2NCAgICgxKSk7CisgIEVYUEVDVF9FUSgyMDMgICwgbWVzc2FnZS5yZXBlYXRlZF91aW50MzIgICgxKSk7CisgIEVYUEVDVF9FUSgyMDQgICwgbWVzc2FnZS5yZXBlYXRlZF91aW50NjQgICgxKSk7CisgIEVYUEVDVF9FUSgyMDUgICwgbWVzc2FnZS5yZXBlYXRlZF9zaW50MzIgICgxKSk7CisgIEVYUEVDVF9FUSgyMDYgICwgbWVzc2FnZS5yZXBlYXRlZF9zaW50NjQgICgxKSk7CisgIEVYUEVDVF9FUSgyMDcgICwgbWVzc2FnZS5yZXBlYXRlZF9maXhlZDMyICgxKSk7CisgIEVYUEVDVF9FUSgyMDggICwgbWVzc2FnZS5yZXBlYXRlZF9maXhlZDY0ICgxKSk7CisgIEVYUEVDVF9FUSgyMDkgICwgbWVzc2FnZS5yZXBlYXRlZF9zZml4ZWQzMigxKSk7CisgIEVYUEVDVF9FUSgyMTAgICwgbWVzc2FnZS5yZXBlYXRlZF9zZml4ZWQ2NCgxKSk7CisgIEVYUEVDVF9FUSgyMTEgICwgbWVzc2FnZS5yZXBlYXRlZF9mbG9hdCAgICgxKSk7CisgIEVYUEVDVF9FUSgyMTIgICwgbWVzc2FnZS5yZXBlYXRlZF9kb3VibGUgICgxKSk7CisgIEVYUEVDVF9UUlVFKCAgICAgbWVzc2FnZS5yZXBlYXRlZF9ib29sICAgICgxKSk7CisgIEVYUEVDVF9FUSgiMjE1IiwgbWVzc2FnZS5yZXBlYXRlZF9zdHJpbmcgICgxKSk7CisgIEVYUEVDVF9FUSgiMjE2IiwgbWVzc2FnZS5yZXBlYXRlZF9ieXRlcyAgICgxKSk7CisKKyAgRVhQRUNUX0VRKDIxNywgbWVzc2FnZS5yZXBlYXRlZGdyb3VwICAgICAgICAgICAoMSkuYSgpKTsKKyAgRVhQRUNUX0VRKDIxOCwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSAoMSkuYmIoKSk7CisgIEVYUEVDVF9FUSgyMTksIG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKDEpLmMoKSk7CisgIEVYUEVDVF9FUSgyMjAsIG1lc3NhZ2UucmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgKDEpLmQoKSk7CisgIEVYUEVDVF9FUSgyMjAsIG1lc3NhZ2UucmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgKDEpLmQoKSk7CisKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkJBUiwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfZW51bSAoMSkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fQkFSICAgICAgLCBtZXNzYWdlLnJlcGVhdGVkX2ZvcmVpZ25fZW51bSgxKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9CQVIsIG1lc3NhZ2UucmVwZWF0ZWRfaW1wb3J0X2VudW0gKDEpKTsKKworICBFWFBFQ1RfRVEoMzAxICAsIG1lc3NhZ2UucmVwZWF0ZWRfaW50MzIgICAoMCkpOworICBFWFBFQ1RfRVEoMzAyICAsIG1lc3NhZ2UucmVwZWF0ZWRfaW50NjQgICAoMCkpOworICBFWFBFQ1RfRVEoMzAzICAsIG1lc3NhZ2UucmVwZWF0ZWRfdWludDMyICAoMCkpOworICBFWFBFQ1RfRVEoMzA0ICAsIG1lc3NhZ2UucmVwZWF0ZWRfdWludDY0ICAoMCkpOworICBFWFBFQ1RfRVEoMzA1ICAsIG1lc3NhZ2UucmVwZWF0ZWRfc2ludDMyICAoMCkpOworICBFWFBFQ1RfRVEoMzA2ICAsIG1lc3NhZ2UucmVwZWF0ZWRfc2ludDY0ICAoMCkpOworICBFWFBFQ1RfRVEoMzA3ICAsIG1lc3NhZ2UucmVwZWF0ZWRfZml4ZWQzMiAoMCkpOworICBFWFBFQ1RfRVEoMzA4ICAsIG1lc3NhZ2UucmVwZWF0ZWRfZml4ZWQ2NCAoMCkpOworICBFWFBFQ1RfRVEoMzA5ICAsIG1lc3NhZ2UucmVwZWF0ZWRfc2ZpeGVkMzIoMCkpOworICBFWFBFQ1RfRVEoMzEwICAsIG1lc3NhZ2UucmVwZWF0ZWRfc2ZpeGVkNjQoMCkpOworICBFWFBFQ1RfRVEoMzExICAsIG1lc3NhZ2UucmVwZWF0ZWRfZmxvYXQgICAoMCkpOworICBFWFBFQ1RfRVEoMzEyICAsIG1lc3NhZ2UucmVwZWF0ZWRfZG91YmxlICAoMCkpOworICBFWFBFQ1RfRkFMU0UoICAgIG1lc3NhZ2UucmVwZWF0ZWRfYm9vbCAgICAoMCkpOworICBFWFBFQ1RfRVEoIjMxNSIsIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nICAoMCkpOworICBFWFBFQ1RfRVEoIjMxNiIsIG1lc3NhZ2UucmVwZWF0ZWRfYnl0ZXMgICAoMCkpOworCisgIEVYUEVDVF9FUSgzMTcsIG1lc3NhZ2UucmVwZWF0ZWRncm91cCAgICAgICAgICAgKDApLmEoKSk7CisgIEVYUEVDVF9FUSgzMTgsIG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgKDApLmJiKCkpOworICBFWFBFQ1RfRVEoMzE5LCBtZXNzYWdlLnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSgwKS5jKCkpOworICBFWFBFQ1RfRVEoMzIwLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlICgwKS5kKCkpOworICBFWFBFQ1RfRVEoMzIwLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlICgwKS5kKCkpOworCisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpCQVosIG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX2VudW0gKDApKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0JBWiAgICAgICwgbWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX2VudW0oMCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3RfaW1wb3J0OjpJTVBPUlRfQkFaLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9lbnVtICgwKSk7Cit9CisKK3ZvaWQgVGVzdFV0aWw6OkV4cGVjdFJlcGVhdGVkRXh0ZW5zaW9uc1N3YXBwZWQoCisgICAgY29uc3QgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zJiBtZXNzYWdlKSB7CisKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9uICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ludDY0X2V4dGVuc2lvbiAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF91aW50MzJfZXh0ZW5zaW9uICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfdWludDY0X2V4dGVuc2lvbiAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3NpbnQzMl9leHRlbnNpb24gICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50NjRfZXh0ZW5zaW9uICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfZml4ZWQzMl9leHRlbnNpb24gKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkNjRfZXh0ZW5zaW9uICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9zZml4ZWQzMl9leHRlbnNpb24pKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfc2ZpeGVkNjRfZXh0ZW5zaW9uKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2Zsb2F0X2V4dGVuc2lvbiAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9kb3VibGVfZXh0ZW5zaW9uICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfYm9vbF9leHRlbnNpb24gICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb24gICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9ieXRlc19leHRlbnNpb24gICApKTsKKworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZGdyb3VwX2V4dGVuc2lvbiAgICAgICAgICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbikpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb24gKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2xhenlfbWVzc2FnZV9leHRlbnNpb24gICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uICAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ltcG9ydF9lbnVtX2V4dGVuc2lvbiAgICApKTsKKworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9zdHJpbmdfcGllY2VfZXh0ZW5zaW9uKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2NvcmRfZXh0ZW5zaW9uKSk7CisKKyAgRVhQRUNUX0VRKDIwMSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9uICAgLCAxKSk7CisgIEVYUEVDVF9FUSgyMDIgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ludDY0X2V4dGVuc2lvbiAgICwgMSkpOworICBFWFBFQ1RfRVEoMjAzICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF91aW50MzJfZXh0ZW5zaW9uICAsIDEpKTsKKyAgRVhQRUNUX0VRKDIwNCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfdWludDY0X2V4dGVuc2lvbiAgLCAxKSk7CisgIEVYUEVDVF9FUSgyMDUgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NpbnQzMl9leHRlbnNpb24gICwgMSkpOworICBFWFBFQ1RfRVEoMjA2ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50NjRfZXh0ZW5zaW9uICAsIDEpKTsKKyAgRVhQRUNUX0VRKDIwNyAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZml4ZWQzMl9leHRlbnNpb24gLCAxKSk7CisgIEVYUEVDVF9FUSgyMDggICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkNjRfZXh0ZW5zaW9uICwgMSkpOworICBFWFBFQ1RfRVEoMjA5ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zZml4ZWQzMl9leHRlbnNpb24sIDEpKTsKKyAgRVhQRUNUX0VRKDIxMCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ZpeGVkNjRfZXh0ZW5zaW9uLCAxKSk7CisgIEVYUEVDVF9FUSgyMTEgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2Zsb2F0X2V4dGVuc2lvbiAgICwgMSkpOworICBFWFBFQ1RfRVEoMjEyICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9kb3VibGVfZXh0ZW5zaW9uICAsIDEpKTsKKyAgRVhQRUNUX1RSVUUoICAgICBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfYm9vbF9leHRlbnNpb24gICAgLCAxKSk7CisgIEVYUEVDVF9FUSgiMjE1IiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb24gICwgMSkpOworICBFWFBFQ1RfRVEoIjIxNiIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9ieXRlc19leHRlbnNpb24gICAsIDEpKTsKKworICBFWFBFQ1RfRVEoMjE3LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRncm91cF9leHRlbnNpb24gICAgICAgICAgICwgMSkuYSgpKTsKKyAgRVhQRUNUX0VRKDIxOCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiAsIDEpLmJiKCkpOworICBFWFBFQ1RfRVEoMjE5LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbiwgMSkuYygpKTsKKyAgRVhQRUNUX0VRKDIyMCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbiAsIDEpLmQoKSk7CisgIEVYUEVDVF9FUSgyMjcsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9sYXp5X21lc3NhZ2VfZXh0ZW5zaW9uICAgLCAxKS5iYigpKTsKKworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6QkFSLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uICwgMSkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fQkFSICAgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbiwgMSkpOworICBFWFBFQ1RfRVEodW5pdHRlc3RfaW1wb3J0OjpJTVBPUlRfQkFSLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW1wb3J0X2VudW1fZXh0ZW5zaW9uICwgMSkpOworCisgIEVYUEVDVF9FUSgiMjI0IiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19waWVjZV9leHRlbnNpb24sIDEpKTsKKyAgRVhQRUNUX0VRKCIyMjUiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfY29yZF9leHRlbnNpb24sIDEpKTsKKworICBFWFBFQ1RfRVEoMzAxICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbnQzMl9leHRlbnNpb24gICAsIDApKTsKKyAgRVhQRUNUX0VRKDMwMiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW50NjRfZXh0ZW5zaW9uICAgLCAwKSk7CisgIEVYUEVDVF9FUSgzMDMgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3VpbnQzMl9leHRlbnNpb24gICwgMCkpOworICBFWFBFQ1RfRVEoMzA0ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF91aW50NjRfZXh0ZW5zaW9uICAsIDApKTsKKyAgRVhQRUNUX0VRKDMwNSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ludDMyX2V4dGVuc2lvbiAgLCAwKSk7CisgIEVYUEVDVF9FUSgzMDYgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NpbnQ2NF9leHRlbnNpb24gICwgMCkpOworICBFWFBFQ1RfRVEoMzA3ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9maXhlZDMyX2V4dGVuc2lvbiAsIDApKTsKKyAgRVhQRUNUX0VRKDMwOCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZml4ZWQ2NF9leHRlbnNpb24gLCAwKSk7CisgIEVYUEVDVF9FUSgzMDkgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NmaXhlZDMyX2V4dGVuc2lvbiwgMCkpOworICBFWFBFQ1RfRVEoMzEwICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zZml4ZWQ2NF9leHRlbnNpb24sIDApKTsKKyAgRVhQRUNUX0VRKDMxMSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZmxvYXRfZXh0ZW5zaW9uICAgLCAwKSk7CisgIEVYUEVDVF9FUSgzMTIgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2RvdWJsZV9leHRlbnNpb24gICwgMCkpOworICBFWFBFQ1RfRkFMU0UoICAgIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9ib29sX2V4dGVuc2lvbiAgICAsIDApKTsKKyAgRVhQRUNUX0VRKCIzMTUiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc3RyaW5nX2V4dGVuc2lvbiAgLCAwKSk7CisgIEVYUEVDVF9FUSgiMzE2IiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2J5dGVzX2V4dGVuc2lvbiAgICwgMCkpOworCisgIEVYUEVDVF9FUSgzMTcsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZGdyb3VwX2V4dGVuc2lvbiAgICAgICAgICAgLCAwKS5hKCkpOworICBFWFBFQ1RfRVEoMzE4LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uICwgMCkuYmIoKSk7CisgIEVYUEVDVF9FUSgzMTksIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uLCAwKS5jKCkpOworICBFWFBFQ1RfRVEoMzIwLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uICwgMCkuZCgpKTsKKyAgRVhQRUNUX0VRKDMyNywgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2xhenlfbWVzc2FnZV9leHRlbnNpb24gICAsIDApLmJiKCkpOworCisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpCQVosIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9uZXN0ZWRfZW51bV9leHRlbnNpb24gLCAwKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9SRUlHTl9CQVogICAgICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uLCAwKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9CQVosIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbXBvcnRfZW51bV9leHRlbnNpb24gLCAwKSk7CisKKyAgRVhQRUNUX0VRKCIzMjQiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc3RyaW5nX3BpZWNlX2V4dGVuc2lvbiwgMCkpOworICBFWFBFQ1RfRVEoIjMyNSIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9jb3JkX2V4dGVuc2lvbiwgMCkpOworfQorCit2b2lkIFRlc3RVdGlsOjpTZXRPbmVvZjEodW5pdHRlc3Q6OlRlc3RPbmVvZjIqIG1lc3NhZ2UpIHsKKyAgbWVzc2FnZS0+bXV0YWJsZV9mb29fbGF6eV9tZXNzYWdlKCktPnNldF9xdXhfaW50KDEwMCk7CisgIG1lc3NhZ2UtPnNldF9iYXJfc3RyaW5nKCIxMDEiKTsKKyAgbWVzc2FnZS0+c2V0X2Jhel9pbnQoMTAyKTsKKyAgbWVzc2FnZS0+c2V0X2Jhel9zdHJpbmcoIjEwMyIpOworfQorCit2b2lkIFRlc3RVdGlsOjpTZXRPbmVvZjIodW5pdHRlc3Q6OlRlc3RPbmVvZjIqIG1lc3NhZ2UpIHsKKyAgbWVzc2FnZS0+c2V0X2Zvb19pbnQoMjAwKTsKKyAgbWVzc2FnZS0+c2V0X2Jhcl9lbnVtKHVuaXR0ZXN0OjpUZXN0T25lb2YyOjpCQVopOworICBtZXNzYWdlLT5zZXRfYmF6X2ludCgyMDIpOworICBtZXNzYWdlLT5zZXRfYmF6X3N0cmluZygiMjAzIik7Cit9CisKK3ZvaWQgVGVzdFV0aWw6OkV4cGVjdE9uZW9mU2V0MShjb25zdCB1bml0dGVzdDo6VGVzdE9uZW9mMiYgbWVzc2FnZSkgeworICBFeHBlY3RBdE1vc3RPbmVGaWVsZFNldEluT25lb2YobWVzc2FnZSk7CisKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfZm9vX2xhenlfbWVzc2FnZSAgICAgICAgICAoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuZm9vX2xhenlfbWVzc2FnZSgpLmhhc19xdXhfaW50KCkpOworCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2Jhcl9zdHJpbmcoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2Jhel9pbnQgICAoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2Jhel9zdHJpbmcoKSk7CisKKyAgQVNTRVJUX0VRKDAsIG1lc3NhZ2UuZm9vX2xhenlfbWVzc2FnZSgpLmNvcmdlX2ludF9zaXplKCkpOworCisgIEVYUEVDVF9FUSgxMDAgICwgbWVzc2FnZS5mb29fbGF6eV9tZXNzYWdlKCkucXV4X2ludCgpKTsKKyAgRVhQRUNUX0VRKCIxMDEiLCBtZXNzYWdlLmJhcl9zdHJpbmcgICAgICAgICAgICAgICAgKCkpOworICBFWFBFQ1RfRVEoMTAyICAsIG1lc3NhZ2UuYmF6X2ludCAgICAgICAgICAgICAgICAgICAoKSk7CisgIEVYUEVDVF9FUSgiMTAzIiwgbWVzc2FnZS5iYXpfc3RyaW5nICAgICAgICAgICAgICAgICgpKTsKK30KKwordm9pZCBUZXN0VXRpbDo6RXhwZWN0T25lb2ZTZXQyKGNvbnN0IHVuaXR0ZXN0OjpUZXN0T25lb2YyJiBtZXNzYWdlKSB7CisgIEV4cGVjdEF0TW9zdE9uZUZpZWxkU2V0SW5PbmVvZihtZXNzYWdlKTsKKworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19mb29faW50ICAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19iYXJfZW51bSAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19iYXpfaW50ICAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19iYXpfc3RyaW5nKCkpOworCisgIEVYUEVDVF9FUSgyMDAgICAgICAgICAgICAgICAgICAgICAgLCBtZXNzYWdlLmZvb19pbnQgICAoKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdE9uZW9mMjo6QkFaLCBtZXNzYWdlLmJhcl9lbnVtICAoKSk7CisgIEVYUEVDVF9FUSgyMDIgICAgICAgICAgICAgICAgICAgICAgLCBtZXNzYWdlLmJhel9pbnQgICAoKSk7CisgIEVYUEVDVF9FUSgiMjAzIiAgICAgICAgICAgICAgICAgICAgLCBtZXNzYWdlLmJhel9zdHJpbmcoKSk7Cit9CisKK3ZvaWQgVGVzdFV0aWw6OkV4cGVjdE9uZW9mQ2xlYXIoY29uc3QgdW5pdHRlc3Q6OlRlc3RPbmVvZjImIG1lc3NhZ2UpIHsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2Zvb19pbnQoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19mb29fc3RyaW5nKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZm9vX2J5dGVzKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZm9vX2VudW0oKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19mb29fbWVzc2FnZSgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2Zvb2dyb3VwKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZm9vX2xhenlfbWVzc2FnZSgpKTsKKworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfYmFyX2ludCgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2Jhcl9zdHJpbmcoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19iYXJfYnl0ZXMoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19iYXJfZW51bSgpKTsKKworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfYmF6X2ludCgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2Jhel9zdHJpbmcoKSk7CisKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0T25lb2YyOjpGT09fTk9UX1NFVCwgbWVzc2FnZS5mb29fY2FzZSgpKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0T25lb2YyOjpCQVJfTk9UX1NFVCwgbWVzc2FnZS5iYXJfY2FzZSgpKTsKK30KKwordm9pZCBUZXN0VXRpbDo6RXhwZWN0QXRNb3N0T25lRmllbGRTZXRJbk9uZW9mKAorICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0T25lb2YyJiBtZXNzYWdlKSB7CisgIGludCBjb3VudCA9IDA7CisgIGlmIChtZXNzYWdlLmhhc19mb29faW50KCkpIGNvdW50Kys7CisgIGlmIChtZXNzYWdlLmhhc19mb29fc3RyaW5nKCkpIGNvdW50Kys7CisgIGlmIChtZXNzYWdlLmhhc19mb29fYnl0ZXMoKSkgY291bnQrKzsKKyAgaWYgKG1lc3NhZ2UuaGFzX2Zvb19lbnVtKCkpIGNvdW50Kys7CisgIGlmIChtZXNzYWdlLmhhc19mb29fbWVzc2FnZSgpKSBjb3VudCsrOworICBpZiAobWVzc2FnZS5oYXNfZm9vZ3JvdXAoKSkgY291bnQrKzsKKyAgaWYgKG1lc3NhZ2UuaGFzX2Zvb19sYXp5X21lc3NhZ2UoKSkgY291bnQrKzsKKyAgRVhQRUNUX0xFKGNvdW50LCAxKTsKKyAgY291bnQgPSAwOworICBpZiAobWVzc2FnZS5oYXNfYmFyX2ludCgpKSBjb3VudCsrOworICBpZiAobWVzc2FnZS5oYXNfYmFyX3N0cmluZygpKSBjb3VudCsrOworICBpZiAobWVzc2FnZS5oYXNfYmFyX2J5dGVzKCkpIGNvdW50Kys7CisgIGlmIChtZXNzYWdlLmhhc19iYXJfZW51bSgpKSBjb3VudCsrOworICBFWFBFQ1RfVFJVRShjb3VudCA9PSAwIHx8IGNvdW50ID09IDEpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK1Rlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyOjpSZWZsZWN0aW9uVGVzdGVyKAorICAgIGNvbnN0IERlc2NyaXB0b3IqIGJhc2VfZGVzY3JpcHRvcikKKyAgOiBiYXNlX2Rlc2NyaXB0b3JfKGJhc2VfZGVzY3JpcHRvcikgeworCisgIGNvbnN0IERlc2NyaXB0b3JQb29sKiBwb29sID0gYmFzZV9kZXNjcmlwdG9yLT5maWxlKCktPnBvb2woKTsKKworICBuZXN0ZWRfYl8gPQorICAgIHBvb2wtPkZpbmRGaWVsZEJ5TmFtZSgicHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuYmIiKTsKKyAgZm9yZWlnbl9jXyA9CisgICAgcG9vbC0+RmluZEZpZWxkQnlOYW1lKCJwcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZS5jIik7CisgIGltcG9ydF9kXyA9CisgICAgcG9vbC0+RmluZEZpZWxkQnlOYW1lKCJwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZS5kIik7CisgIGltcG9ydF9lXyA9CisgICAgcG9vbC0+RmluZEZpZWxkQnlOYW1lKCJwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVzc2FnZS5lIik7CisgIG5lc3RlZF9mb29fID0KKyAgICBwb29sLT5GaW5kRW51bVZhbHVlQnlOYW1lKCJwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuRk9PIik7CisgIG5lc3RlZF9iYXJfID0KKyAgICBwb29sLT5GaW5kRW51bVZhbHVlQnlOYW1lKCJwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuQkFSIik7CisgIG5lc3RlZF9iYXpfID0KKyAgICBwb29sLT5GaW5kRW51bVZhbHVlQnlOYW1lKCJwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuQkFaIik7CisgIGZvcmVpZ25fZm9vXyA9CisgICAgcG9vbC0+RmluZEVudW1WYWx1ZUJ5TmFtZSgicHJvdG9idWZfdW5pdHRlc3QuRk9SRUlHTl9GT08iKTsKKyAgZm9yZWlnbl9iYXJfID0KKyAgICBwb29sLT5GaW5kRW51bVZhbHVlQnlOYW1lKCJwcm90b2J1Zl91bml0dGVzdC5GT1JFSUdOX0JBUiIpOworICBmb3JlaWduX2Jhel8gPQorICAgIHBvb2wtPkZpbmRFbnVtVmFsdWVCeU5hbWUoInByb3RvYnVmX3VuaXR0ZXN0LkZPUkVJR05fQkFaIik7CisgIGltcG9ydF9mb29fID0KKyAgICBwb29sLT5GaW5kRW51bVZhbHVlQnlOYW1lKCJwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSU1QT1JUX0ZPTyIpOworICBpbXBvcnRfYmFyXyA9CisgICAgcG9vbC0+RmluZEVudW1WYWx1ZUJ5TmFtZSgicHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LklNUE9SVF9CQVIiKTsKKyAgaW1wb3J0X2Jhel8gPQorICAgIHBvb2wtPkZpbmRFbnVtVmFsdWVCeU5hbWUoInByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JTVBPUlRfQkFaIik7CisKKyAgaWYgKGJhc2VfZGVzY3JpcHRvcl8tPm5hbWUoKSA9PSAiVGVzdEFsbEV4dGVuc2lvbnMiKSB7CisgICAgZ3JvdXBfYV8gPQorICAgICAgcG9vbC0+RmluZEZpZWxkQnlOYW1lKCJwcm90b2J1Zl91bml0dGVzdC5PcHRpb25hbEdyb3VwX2V4dGVuc2lvbi5hIik7CisgICAgcmVwZWF0ZWRfZ3JvdXBfYV8gPQorICAgICAgcG9vbC0+RmluZEZpZWxkQnlOYW1lKCJwcm90b2J1Zl91bml0dGVzdC5SZXBlYXRlZEdyb3VwX2V4dGVuc2lvbi5hIik7CisgIH0gZWxzZSB7CisgICAgZ3JvdXBfYV8gPQorICAgICAgcG9vbC0+RmluZEZpZWxkQnlOYW1lKCJwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuT3B0aW9uYWxHcm91cC5hIik7CisgICAgcmVwZWF0ZWRfZ3JvdXBfYV8gPQorICAgICAgcG9vbC0+RmluZEZpZWxkQnlOYW1lKCJwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuUmVwZWF0ZWRHcm91cC5hIik7CisgIH0KKworICBFWFBFQ1RfVFJVRShncm91cF9hXyAgICAgICAgICAhPSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUocmVwZWF0ZWRfZ3JvdXBfYV8gIT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKG5lc3RlZF9iXyAgICAgICAgICE9IE5VTEwpOworICBFWFBFQ1RfVFJVRShmb3JlaWduX2NfICAgICAgICAhPSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUoaW1wb3J0X2RfICAgICAgICAgIT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKGltcG9ydF9lXyAgICAgICAgICE9IE5VTEwpOworICBFWFBFQ1RfVFJVRShuZXN0ZWRfZm9vXyAgICAgICAhPSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUobmVzdGVkX2Jhcl8gICAgICAgIT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKG5lc3RlZF9iYXpfICAgICAgICE9IE5VTEwpOworICBFWFBFQ1RfVFJVRShmb3JlaWduX2Zvb18gICAgICAhPSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUoZm9yZWlnbl9iYXJfICAgICAgIT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKGZvcmVpZ25fYmF6XyAgICAgICE9IE5VTEwpOworICBFWFBFQ1RfVFJVRShpbXBvcnRfZm9vXyAgICAgICAhPSBOVUxMKTsKKyAgRVhQRUNUX1RSVUUoaW1wb3J0X2Jhcl8gICAgICAgIT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKGltcG9ydF9iYXpfICAgICAgICE9IE5VTEwpOworfQorCisvLyBTaG9ydGhhbmQgdG8gZ2V0IGEgRmllbGREZXNjcmlwdG9yIGZvciBhIGZpZWxkIG9mIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMuCitjb25zdCBGaWVsZERlc2NyaXB0b3IqIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyOjpGKGNvbnN0IHN0cmluZyYgbmFtZSkgeworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHJlc3VsdCA9IE5VTEw7CisgIGlmIChiYXNlX2Rlc2NyaXB0b3JfLT5uYW1lKCkgPT0gIlRlc3RBbGxFeHRlbnNpb25zIiB8fAorICAgICAgYmFzZV9kZXNjcmlwdG9yXy0+bmFtZSgpID09ICJUZXN0UGFja2VkRXh0ZW5zaW9ucyIpIHsKKyAgICByZXN1bHQgPSBiYXNlX2Rlc2NyaXB0b3JfLT5maWxlKCktPkZpbmRFeHRlbnNpb25CeU5hbWUobmFtZSArICJfZXh0ZW5zaW9uIik7CisgIH0gZWxzZSB7CisgICAgcmVzdWx0ID0gYmFzZV9kZXNjcmlwdG9yXy0+RmluZEZpZWxkQnlOYW1lKG5hbWUpOworICB9CisgIEdPT0dMRV9DSEVDSyhyZXN1bHQgIT0gTlVMTCk7CisgIHJldHVybiByZXN1bHQ7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBUZXN0VXRpbDo6UmVmbGVjdGlvblRlc3Rlcjo6U2V0QWxsRmllbGRzVmlhUmVmbGVjdGlvbihNZXNzYWdlKiBtZXNzYWdlKSB7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCk7CisgIE1lc3NhZ2UqIHN1Yl9tZXNzYWdlOworCisgIHJlZmxlY3Rpb24tPlNldEludDMyIChtZXNzYWdlLCBGKCJvcHRpb25hbF9pbnQzMiIgICApLCAxMDEpOworICByZWZsZWN0aW9uLT5TZXRJbnQ2NCAobWVzc2FnZSwgRigib3B0aW9uYWxfaW50NjQiICAgKSwgMTAyKTsKKyAgcmVmbGVjdGlvbi0+U2V0VUludDMyKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX3VpbnQzMiIgICksIDEwMyk7CisgIHJlZmxlY3Rpb24tPlNldFVJbnQ2NChtZXNzYWdlLCBGKCJvcHRpb25hbF91aW50NjQiICApLCAxMDQpOworICByZWZsZWN0aW9uLT5TZXRJbnQzMiAobWVzc2FnZSwgRigib3B0aW9uYWxfc2ludDMyIiAgKSwgMTA1KTsKKyAgcmVmbGVjdGlvbi0+U2V0SW50NjQgKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX3NpbnQ2NCIgICksIDEwNik7CisgIHJlZmxlY3Rpb24tPlNldFVJbnQzMihtZXNzYWdlLCBGKCJvcHRpb25hbF9maXhlZDMyIiApLCAxMDcpOworICByZWZsZWN0aW9uLT5TZXRVSW50NjQobWVzc2FnZSwgRigib3B0aW9uYWxfZml4ZWQ2NCIgKSwgMTA4KTsKKyAgcmVmbGVjdGlvbi0+U2V0SW50MzIgKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX3NmaXhlZDMyIiksIDEwOSk7CisgIHJlZmxlY3Rpb24tPlNldEludDY0IChtZXNzYWdlLCBGKCJvcHRpb25hbF9zZml4ZWQ2NCIpLCAxMTApOworICByZWZsZWN0aW9uLT5TZXRGbG9hdCAobWVzc2FnZSwgRigib3B0aW9uYWxfZmxvYXQiICAgKSwgMTExKTsKKyAgcmVmbGVjdGlvbi0+U2V0RG91YmxlKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2RvdWJsZSIgICksIDExMik7CisgIHJlZmxlY3Rpb24tPlNldEJvb2wgIChtZXNzYWdlLCBGKCJvcHRpb25hbF9ib29sIiAgICApLCB0cnVlKTsKKyAgcmVmbGVjdGlvbi0+U2V0U3RyaW5nKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX3N0cmluZyIgICksICIxMTUiKTsKKyAgcmVmbGVjdGlvbi0+U2V0U3RyaW5nKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2J5dGVzIiAgICksICIxMTYiKTsKKworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPk11dGFibGVNZXNzYWdlKG1lc3NhZ2UsIEYoIm9wdGlvbmFsZ3JvdXAiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlNldEludDMyKHN1Yl9tZXNzYWdlLCBncm91cF9hXywgMTE3KTsKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5NdXRhYmxlTWVzc2FnZShtZXNzYWdlLCBGKCJvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSIpKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+U2V0SW50MzIoc3ViX21lc3NhZ2UsIG5lc3RlZF9iXywgMTE4KTsKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5NdXRhYmxlTWVzc2FnZShtZXNzYWdlLCBGKCJvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlNldEludDMyKHN1Yl9tZXNzYWdlLCBmb3JlaWduX2NfLCAxMTkpOworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPk11dGFibGVNZXNzYWdlKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlIikpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5TZXRJbnQzMihzdWJfbWVzc2FnZSwgaW1wb3J0X2RfLCAxMjApOworCisgIHJlZmxlY3Rpb24tPlNldEVudW0obWVzc2FnZSwgRigib3B0aW9uYWxfbmVzdGVkX2VudW0iICksICBuZXN0ZWRfYmF6Xyk7CisgIHJlZmxlY3Rpb24tPlNldEVudW0obWVzc2FnZSwgRigib3B0aW9uYWxfZm9yZWlnbl9lbnVtIiksIGZvcmVpZ25fYmF6Xyk7CisgIHJlZmxlY3Rpb24tPlNldEVudW0obWVzc2FnZSwgRigib3B0aW9uYWxfaW1wb3J0X2VudW0iICksICBpbXBvcnRfYmF6Xyk7CisKKyAgcmVmbGVjdGlvbi0+U2V0U3RyaW5nKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX3N0cmluZ19waWVjZSIpLCAiMTI0Iik7CisgIHJlZmxlY3Rpb24tPlNldFN0cmluZyhtZXNzYWdlLCBGKCJvcHRpb25hbF9jb3JkIiksICIxMjUiKTsKKworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPk11dGFibGVNZXNzYWdlKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZSIpKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+U2V0SW50MzIoc3ViX21lc3NhZ2UsIGltcG9ydF9lXywgMTI2KTsKKworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPk11dGFibGVNZXNzYWdlKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2xhenlfbWVzc2FnZSIpKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+U2V0SW50MzIoc3ViX21lc3NhZ2UsIG5lc3RlZF9iXywgMTI3KTsKKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIHJlZmxlY3Rpb24tPkFkZEludDMyIChtZXNzYWdlLCBGKCJyZXBlYXRlZF9pbnQzMiIgICApLCAyMDEpOworICByZWZsZWN0aW9uLT5BZGRJbnQ2NCAobWVzc2FnZSwgRigicmVwZWF0ZWRfaW50NjQiICAgKSwgMjAyKTsKKyAgcmVmbGVjdGlvbi0+QWRkVUludDMyKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3VpbnQzMiIgICksIDIwMyk7CisgIHJlZmxlY3Rpb24tPkFkZFVJbnQ2NChtZXNzYWdlLCBGKCJyZXBlYXRlZF91aW50NjQiICApLCAyMDQpOworICByZWZsZWN0aW9uLT5BZGRJbnQzMiAobWVzc2FnZSwgRigicmVwZWF0ZWRfc2ludDMyIiAgKSwgMjA1KTsKKyAgcmVmbGVjdGlvbi0+QWRkSW50NjQgKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3NpbnQ2NCIgICksIDIwNik7CisgIHJlZmxlY3Rpb24tPkFkZFVJbnQzMihtZXNzYWdlLCBGKCJyZXBlYXRlZF9maXhlZDMyIiApLCAyMDcpOworICByZWZsZWN0aW9uLT5BZGRVSW50NjQobWVzc2FnZSwgRigicmVwZWF0ZWRfZml4ZWQ2NCIgKSwgMjA4KTsKKyAgcmVmbGVjdGlvbi0+QWRkSW50MzIgKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3NmaXhlZDMyIiksIDIwOSk7CisgIHJlZmxlY3Rpb24tPkFkZEludDY0IChtZXNzYWdlLCBGKCJyZXBlYXRlZF9zZml4ZWQ2NCIpLCAyMTApOworICByZWZsZWN0aW9uLT5BZGRGbG9hdCAobWVzc2FnZSwgRigicmVwZWF0ZWRfZmxvYXQiICAgKSwgMjExKTsKKyAgcmVmbGVjdGlvbi0+QWRkRG91YmxlKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2RvdWJsZSIgICksIDIxMik7CisgIHJlZmxlY3Rpb24tPkFkZEJvb2wgIChtZXNzYWdlLCBGKCJyZXBlYXRlZF9ib29sIiAgICApLCB0cnVlKTsKKyAgcmVmbGVjdGlvbi0+QWRkU3RyaW5nKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3N0cmluZyIgICksICIyMTUiKTsKKyAgcmVmbGVjdGlvbi0+QWRkU3RyaW5nKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2J5dGVzIiAgICksICIyMTYiKTsKKworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigicmVwZWF0ZWRncm91cCIpKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+U2V0SW50MzIoc3ViX21lc3NhZ2UsIHJlcGVhdGVkX2dyb3VwX2FfLCAyMTcpOworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigicmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlNldEludDMyKHN1Yl9tZXNzYWdlLCBuZXN0ZWRfYl8sIDIxOCk7CisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlNldEludDMyKHN1Yl9tZXNzYWdlLCBmb3JlaWduX2NfLCAyMTkpOworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigicmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlNldEludDMyKHN1Yl9tZXNzYWdlLCBpbXBvcnRfZF8sIDIyMCk7CisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9sYXp5X21lc3NhZ2UiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlNldEludDMyKHN1Yl9tZXNzYWdlLCBuZXN0ZWRfYl8sIDIyNyk7CisKKyAgcmVmbGVjdGlvbi0+QWRkRW51bShtZXNzYWdlLCBGKCJyZXBlYXRlZF9uZXN0ZWRfZW51bSIgKSwgIG5lc3RlZF9iYXJfKTsKKyAgcmVmbGVjdGlvbi0+QWRkRW51bShtZXNzYWdlLCBGKCJyZXBlYXRlZF9mb3JlaWduX2VudW0iKSwgZm9yZWlnbl9iYXJfKTsKKyAgcmVmbGVjdGlvbi0+QWRkRW51bShtZXNzYWdlLCBGKCJyZXBlYXRlZF9pbXBvcnRfZW51bSIgKSwgIGltcG9ydF9iYXJfKTsKKworICByZWZsZWN0aW9uLT5BZGRTdHJpbmcobWVzc2FnZSwgRigicmVwZWF0ZWRfc3RyaW5nX3BpZWNlIiksICIyMjQiKTsKKyAgcmVmbGVjdGlvbi0+QWRkU3RyaW5nKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2NvcmQiKSwgIjIyNSIpOworCisgIC8vIEFkZCBhIHNlY29uZCBvbmUgb2YgZWFjaCBmaWVsZC4KKyAgcmVmbGVjdGlvbi0+QWRkSW50MzIgKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2ludDMyIiAgICksIDMwMSk7CisgIHJlZmxlY3Rpb24tPkFkZEludDY0IChtZXNzYWdlLCBGKCJyZXBlYXRlZF9pbnQ2NCIgICApLCAzMDIpOworICByZWZsZWN0aW9uLT5BZGRVSW50MzIobWVzc2FnZSwgRigicmVwZWF0ZWRfdWludDMyIiAgKSwgMzAzKTsKKyAgcmVmbGVjdGlvbi0+QWRkVUludDY0KG1lc3NhZ2UsIEYoInJlcGVhdGVkX3VpbnQ2NCIgICksIDMwNCk7CisgIHJlZmxlY3Rpb24tPkFkZEludDMyIChtZXNzYWdlLCBGKCJyZXBlYXRlZF9zaW50MzIiICApLCAzMDUpOworICByZWZsZWN0aW9uLT5BZGRJbnQ2NCAobWVzc2FnZSwgRigicmVwZWF0ZWRfc2ludDY0IiAgKSwgMzA2KTsKKyAgcmVmbGVjdGlvbi0+QWRkVUludDMyKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2ZpeGVkMzIiICksIDMwNyk7CisgIHJlZmxlY3Rpb24tPkFkZFVJbnQ2NChtZXNzYWdlLCBGKCJyZXBlYXRlZF9maXhlZDY0IiApLCAzMDgpOworICByZWZsZWN0aW9uLT5BZGRJbnQzMiAobWVzc2FnZSwgRigicmVwZWF0ZWRfc2ZpeGVkMzIiKSwgMzA5KTsKKyAgcmVmbGVjdGlvbi0+QWRkSW50NjQgKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3NmaXhlZDY0IiksIDMxMCk7CisgIHJlZmxlY3Rpb24tPkFkZEZsb2F0IChtZXNzYWdlLCBGKCJyZXBlYXRlZF9mbG9hdCIgICApLCAzMTEpOworICByZWZsZWN0aW9uLT5BZGREb3VibGUobWVzc2FnZSwgRigicmVwZWF0ZWRfZG91YmxlIiAgKSwgMzEyKTsKKyAgcmVmbGVjdGlvbi0+QWRkQm9vbCAgKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2Jvb2wiICAgICksIGZhbHNlKTsKKyAgcmVmbGVjdGlvbi0+QWRkU3RyaW5nKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3N0cmluZyIgICksICIzMTUiKTsKKyAgcmVmbGVjdGlvbi0+QWRkU3RyaW5nKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2J5dGVzIiAgICksICIzMTYiKTsKKworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigicmVwZWF0ZWRncm91cCIpKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+U2V0SW50MzIoc3ViX21lc3NhZ2UsIHJlcGVhdGVkX2dyb3VwX2FfLCAzMTcpOworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigicmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlNldEludDMyKHN1Yl9tZXNzYWdlLCBuZXN0ZWRfYl8sIDMxOCk7CisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlNldEludDMyKHN1Yl9tZXNzYWdlLCBmb3JlaWduX2NfLCAzMTkpOworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgRigicmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlNldEludDMyKHN1Yl9tZXNzYWdlLCBpbXBvcnRfZF8sIDMyMCk7CisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9sYXp5X21lc3NhZ2UiKSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlNldEludDMyKHN1Yl9tZXNzYWdlLCBuZXN0ZWRfYl8sIDMyNyk7CisKKyAgcmVmbGVjdGlvbi0+QWRkRW51bShtZXNzYWdlLCBGKCJyZXBlYXRlZF9uZXN0ZWRfZW51bSIgKSwgIG5lc3RlZF9iYXpfKTsKKyAgcmVmbGVjdGlvbi0+QWRkRW51bShtZXNzYWdlLCBGKCJyZXBlYXRlZF9mb3JlaWduX2VudW0iKSwgZm9yZWlnbl9iYXpfKTsKKyAgcmVmbGVjdGlvbi0+QWRkRW51bShtZXNzYWdlLCBGKCJyZXBlYXRlZF9pbXBvcnRfZW51bSIgKSwgIGltcG9ydF9iYXpfKTsKKworICByZWZsZWN0aW9uLT5BZGRTdHJpbmcobWVzc2FnZSwgRigicmVwZWF0ZWRfc3RyaW5nX3BpZWNlIiksICIzMjQiKTsKKyAgcmVmbGVjdGlvbi0+QWRkU3RyaW5nKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2NvcmQiKSwgIjMyNSIpOworCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgcmVmbGVjdGlvbi0+U2V0SW50MzIgKG1lc3NhZ2UsIEYoImRlZmF1bHRfaW50MzIiICAgKSwgNDAxKTsKKyAgcmVmbGVjdGlvbi0+U2V0SW50NjQgKG1lc3NhZ2UsIEYoImRlZmF1bHRfaW50NjQiICAgKSwgNDAyKTsKKyAgcmVmbGVjdGlvbi0+U2V0VUludDMyKG1lc3NhZ2UsIEYoImRlZmF1bHRfdWludDMyIiAgKSwgNDAzKTsKKyAgcmVmbGVjdGlvbi0+U2V0VUludDY0KG1lc3NhZ2UsIEYoImRlZmF1bHRfdWludDY0IiAgKSwgNDA0KTsKKyAgcmVmbGVjdGlvbi0+U2V0SW50MzIgKG1lc3NhZ2UsIEYoImRlZmF1bHRfc2ludDMyIiAgKSwgNDA1KTsKKyAgcmVmbGVjdGlvbi0+U2V0SW50NjQgKG1lc3NhZ2UsIEYoImRlZmF1bHRfc2ludDY0IiAgKSwgNDA2KTsKKyAgcmVmbGVjdGlvbi0+U2V0VUludDMyKG1lc3NhZ2UsIEYoImRlZmF1bHRfZml4ZWQzMiIgKSwgNDA3KTsKKyAgcmVmbGVjdGlvbi0+U2V0VUludDY0KG1lc3NhZ2UsIEYoImRlZmF1bHRfZml4ZWQ2NCIgKSwgNDA4KTsKKyAgcmVmbGVjdGlvbi0+U2V0SW50MzIgKG1lc3NhZ2UsIEYoImRlZmF1bHRfc2ZpeGVkMzIiKSwgNDA5KTsKKyAgcmVmbGVjdGlvbi0+U2V0SW50NjQgKG1lc3NhZ2UsIEYoImRlZmF1bHRfc2ZpeGVkNjQiKSwgNDEwKTsKKyAgcmVmbGVjdGlvbi0+U2V0RmxvYXQgKG1lc3NhZ2UsIEYoImRlZmF1bHRfZmxvYXQiICAgKSwgNDExKTsKKyAgcmVmbGVjdGlvbi0+U2V0RG91YmxlKG1lc3NhZ2UsIEYoImRlZmF1bHRfZG91YmxlIiAgKSwgNDEyKTsKKyAgcmVmbGVjdGlvbi0+U2V0Qm9vbCAgKG1lc3NhZ2UsIEYoImRlZmF1bHRfYm9vbCIgICAgKSwgZmFsc2UpOworICByZWZsZWN0aW9uLT5TZXRTdHJpbmcobWVzc2FnZSwgRigiZGVmYXVsdF9zdHJpbmciICApLCAiNDE1Iik7CisgIHJlZmxlY3Rpb24tPlNldFN0cmluZyhtZXNzYWdlLCBGKCJkZWZhdWx0X2J5dGVzIiAgICksICI0MTYiKTsKKworICByZWZsZWN0aW9uLT5TZXRFbnVtKG1lc3NhZ2UsIEYoImRlZmF1bHRfbmVzdGVkX2VudW0iICksICBuZXN0ZWRfZm9vXyk7CisgIHJlZmxlY3Rpb24tPlNldEVudW0obWVzc2FnZSwgRigiZGVmYXVsdF9mb3JlaWduX2VudW0iKSwgZm9yZWlnbl9mb29fKTsKKyAgcmVmbGVjdGlvbi0+U2V0RW51bShtZXNzYWdlLCBGKCJkZWZhdWx0X2ltcG9ydF9lbnVtIiApLCAgaW1wb3J0X2Zvb18pOworCisgIHJlZmxlY3Rpb24tPlNldFN0cmluZyhtZXNzYWdlLCBGKCJkZWZhdWx0X3N0cmluZ19waWVjZSIpLCAiNDI0Iik7CisgIHJlZmxlY3Rpb24tPlNldFN0cmluZyhtZXNzYWdlLCBGKCJkZWZhdWx0X2NvcmQiKSwgIjQyNSIpOworCisgIHJlZmxlY3Rpb24tPlNldFVJbnQzMihtZXNzYWdlLCBGKCJvbmVvZl91aW50MzIiICAgKSwgNjAxKTsKKyAgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5NdXRhYmxlTWVzc2FnZShtZXNzYWdlLCBGKCJvbmVvZl9uZXN0ZWRfbWVzc2FnZSIpKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+U2V0SW50MzIoc3ViX21lc3NhZ2UsIG5lc3RlZF9iXywgNjAyKTsKKyAgcmVmbGVjdGlvbi0+U2V0U3RyaW5nKG1lc3NhZ2UsIEYoIm9uZW9mX3N0cmluZyIpLCAiNjAzIik7CisgIHJlZmxlY3Rpb24tPlNldFN0cmluZyhtZXNzYWdlLCBGKCJvbmVvZl9ieXRlcyIgKSwgIjYwNCIpOworfQorCit2b2lkIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyOjpTZXRPbmVvZlZpYVJlZmxlY3Rpb24oTWVzc2FnZSogbWVzc2FnZSkgeworICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yID0gbWVzc2FnZS0+R2V0RGVzY3JpcHRvcigpOworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpOworICBNZXNzYWdlKiBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPk11dGFibGVNZXNzYWdlKAorICAgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJmb29fbGF6eV9tZXNzYWdlIikpOworICBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5TZXRJbnQ2NCgKKyAgICAgIHN1Yl9tZXNzYWdlLAorICAgICAgZGVzY3JpcHRvci0+ZmlsZSgpLT5wb29sKCktPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICAgICAicHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlLnF1eF9pbnQiKSwKKyAgICAgIDEwMCk7CisKKyAgcmVmbGVjdGlvbi0+U2V0U3RyaW5nKG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImJhcl9jb3JkIiksCisgICAgICAgICAgICAgICAgICAgICAgICAiMTAxIik7CisgIHJlZmxlY3Rpb24tPlNldEludDMyKG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImJhel9pbnQiKSwKKyAgICAgICAgICAgICAgICAgICAgICAgMTAyKTsKKyAgcmVmbGVjdGlvbi0+U2V0U3RyaW5nKG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImJhel9zdHJpbmciKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICIxMDMiKTsKK30KKwordm9pZCBUZXN0VXRpbDo6UmVmbGVjdGlvblRlc3Rlcjo6RXhwZWN0T25lb2ZTZXRWaWFSZWZsZWN0aW9uKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UpIHsKKyAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciA9IG1lc3NhZ2UuR2V0RGVzY3JpcHRvcigpOworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCk7CisgIHN0cmluZyBzY3JhdGNoOworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5IYXNGaWVsZCgKKyAgICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgiZm9vX2xhenlfbWVzc2FnZSIpKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKAorICAgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJiYXJfY29yZCIpKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKAorICAgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJiYXpfaW50IikpKTsKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+SGFzRmllbGQoCisgICAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImJhel9zdHJpbmciKSkpOworCisgIGNvbnN0IE1lc3NhZ2UqIHN1Yl9tZXNzYWdlID0gJnJlZmxlY3Rpb24tPkdldE1lc3NhZ2UoCisgICAgICBtZXNzYWdlLCBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU5hbWUoImZvb19sYXp5X21lc3NhZ2UiKSk7CisgIEVYUEVDVF9FUSgxMDAsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDY0KAorICAgICAgKnN1Yl9tZXNzYWdlLAorICAgICAgZGVzY3JpcHRvci0+ZmlsZSgpLT5wb29sKCktPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICAgICAicHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlLnF1eF9pbnQiKSkpOworCisgIEVYUEVDVF9FUSgiMTAxIiwgcmVmbGVjdGlvbi0+R2V0U3RyaW5nKAorICAgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJiYXJfY29yZCIpKSk7CisgIEVYUEVDVF9FUSgiMTAxIiwgcmVmbGVjdGlvbi0+R2V0U3RyaW5nUmVmZXJlbmNlKAorICAgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJiYXJfY29yZCIpLCAmc2NyYXRjaCkpOworCisgIEVYUEVDVF9FUSgxMDIsIHJlZmxlY3Rpb24tPkdldEludDMyKAorICAgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJiYXpfaW50IikpKTsKKworICBFWFBFQ1RfRVEoIjEwMyIsIHJlZmxlY3Rpb24tPkdldFN0cmluZygKKyAgICAgIG1lc3NhZ2UsIGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgiYmF6X3N0cmluZyIpKSk7CisgIEVYUEVDVF9FUSgiMTAzIiwgcmVmbGVjdGlvbi0+R2V0U3RyaW5nUmVmZXJlbmNlKAorICAgICAgbWVzc2FnZSwgZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJiYXpfc3RyaW5nIiksICZzY3JhdGNoKSk7Cit9CisKK3ZvaWQgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXI6OlNldFBhY2tlZEZpZWxkc1ZpYVJlZmxlY3Rpb24oCisgICAgTWVzc2FnZSogbWVzc2FnZSkgeworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpOworICByZWZsZWN0aW9uLT5BZGRJbnQzMiAobWVzc2FnZSwgRigicGFja2VkX2ludDMyIiAgICksIDYwMSk7CisgIHJlZmxlY3Rpb24tPkFkZEludDY0IChtZXNzYWdlLCBGKCJwYWNrZWRfaW50NjQiICAgKSwgNjAyKTsKKyAgcmVmbGVjdGlvbi0+QWRkVUludDMyKG1lc3NhZ2UsIEYoInBhY2tlZF91aW50MzIiICApLCA2MDMpOworICByZWZsZWN0aW9uLT5BZGRVSW50NjQobWVzc2FnZSwgRigicGFja2VkX3VpbnQ2NCIgICksIDYwNCk7CisgIHJlZmxlY3Rpb24tPkFkZEludDMyIChtZXNzYWdlLCBGKCJwYWNrZWRfc2ludDMyIiAgKSwgNjA1KTsKKyAgcmVmbGVjdGlvbi0+QWRkSW50NjQgKG1lc3NhZ2UsIEYoInBhY2tlZF9zaW50NjQiICApLCA2MDYpOworICByZWZsZWN0aW9uLT5BZGRVSW50MzIobWVzc2FnZSwgRigicGFja2VkX2ZpeGVkMzIiICksIDYwNyk7CisgIHJlZmxlY3Rpb24tPkFkZFVJbnQ2NChtZXNzYWdlLCBGKCJwYWNrZWRfZml4ZWQ2NCIgKSwgNjA4KTsKKyAgcmVmbGVjdGlvbi0+QWRkSW50MzIgKG1lc3NhZ2UsIEYoInBhY2tlZF9zZml4ZWQzMiIpLCA2MDkpOworICByZWZsZWN0aW9uLT5BZGRJbnQ2NCAobWVzc2FnZSwgRigicGFja2VkX3NmaXhlZDY0IiksIDYxMCk7CisgIHJlZmxlY3Rpb24tPkFkZEZsb2F0IChtZXNzYWdlLCBGKCJwYWNrZWRfZmxvYXQiICAgKSwgNjExKTsKKyAgcmVmbGVjdGlvbi0+QWRkRG91YmxlKG1lc3NhZ2UsIEYoInBhY2tlZF9kb3VibGUiICApLCA2MTIpOworICByZWZsZWN0aW9uLT5BZGRCb29sICAobWVzc2FnZSwgRigicGFja2VkX2Jvb2wiICAgICksIHRydWUpOworICByZWZsZWN0aW9uLT5BZGRFbnVtICAobWVzc2FnZSwgRigicGFja2VkX2VudW0iICAgICksIGZvcmVpZ25fYmFyXyk7CisKKyAgcmVmbGVjdGlvbi0+QWRkSW50MzIgKG1lc3NhZ2UsIEYoInBhY2tlZF9pbnQzMiIgICApLCA3MDEpOworICByZWZsZWN0aW9uLT5BZGRJbnQ2NCAobWVzc2FnZSwgRigicGFja2VkX2ludDY0IiAgICksIDcwMik7CisgIHJlZmxlY3Rpb24tPkFkZFVJbnQzMihtZXNzYWdlLCBGKCJwYWNrZWRfdWludDMyIiAgKSwgNzAzKTsKKyAgcmVmbGVjdGlvbi0+QWRkVUludDY0KG1lc3NhZ2UsIEYoInBhY2tlZF91aW50NjQiICApLCA3MDQpOworICByZWZsZWN0aW9uLT5BZGRJbnQzMiAobWVzc2FnZSwgRigicGFja2VkX3NpbnQzMiIgICksIDcwNSk7CisgIHJlZmxlY3Rpb24tPkFkZEludDY0IChtZXNzYWdlLCBGKCJwYWNrZWRfc2ludDY0IiAgKSwgNzA2KTsKKyAgcmVmbGVjdGlvbi0+QWRkVUludDMyKG1lc3NhZ2UsIEYoInBhY2tlZF9maXhlZDMyIiApLCA3MDcpOworICByZWZsZWN0aW9uLT5BZGRVSW50NjQobWVzc2FnZSwgRigicGFja2VkX2ZpeGVkNjQiICksIDcwOCk7CisgIHJlZmxlY3Rpb24tPkFkZEludDMyIChtZXNzYWdlLCBGKCJwYWNrZWRfc2ZpeGVkMzIiKSwgNzA5KTsKKyAgcmVmbGVjdGlvbi0+QWRkSW50NjQgKG1lc3NhZ2UsIEYoInBhY2tlZF9zZml4ZWQ2NCIpLCA3MTApOworICByZWZsZWN0aW9uLT5BZGRGbG9hdCAobWVzc2FnZSwgRigicGFja2VkX2Zsb2F0IiAgICksIDcxMSk7CisgIHJlZmxlY3Rpb24tPkFkZERvdWJsZShtZXNzYWdlLCBGKCJwYWNrZWRfZG91YmxlIiAgKSwgNzEyKTsKKyAgcmVmbGVjdGlvbi0+QWRkQm9vbCAgKG1lc3NhZ2UsIEYoInBhY2tlZF9ib29sIiAgICApLCBmYWxzZSk7CisgIHJlZmxlY3Rpb24tPkFkZEVudW0gIChtZXNzYWdlLCBGKCJwYWNrZWRfZW51bSIgICAgKSwgZm9yZWlnbl9iYXpfKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyOjpFeHBlY3RBbGxGaWVsZHNTZXRWaWFSZWZsZWN0aW9uKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UpIHsKKyAgLy8gV2UgaGF2ZSB0byBzcGxpdCB0aGlzIGludG8gdGhyZWUgZnVuY3Rpb24gb3RoZXJ3aXNlIGl0IGNyZWF0ZXMgYSBzdGFjaworICAvLyBmcmFtZSBzbyBsYXJnZSB0aGF0IGl0IHRyaWdnZXJzIGEgd2FybmluZy4KKyAgRXhwZWN0QWxsRmllbGRzU2V0VmlhUmVmbGVjdGlvbjEobWVzc2FnZSk7CisgIEV4cGVjdEFsbEZpZWxkc1NldFZpYVJlZmxlY3Rpb24yKG1lc3NhZ2UpOworICBFeHBlY3RBbGxGaWVsZHNTZXRWaWFSZWZsZWN0aW9uMyhtZXNzYWdlKTsKK30KKwordm9pZCBUZXN0VXRpbDo6UmVmbGVjdGlvblRlc3Rlcjo6RXhwZWN0QWxsRmllbGRzU2V0VmlhUmVmbGVjdGlvbjEoCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSkgeworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCk7CisgIHN0cmluZyBzY3JhdGNoOworICBjb25zdCBNZXNzYWdlKiBzdWJfbWVzc2FnZTsKKworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJvcHRpb25hbF9pbnQzMiIgICApKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2ludDY0IiAgICkpKTsKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfdWludDMyIiAgKSkpOworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJvcHRpb25hbF91aW50NjQiICApKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX3NpbnQzMiIgICkpKTsKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfc2ludDY0IiAgKSkpOworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJvcHRpb25hbF9maXhlZDMyIiApKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2ZpeGVkNjQiICkpKTsKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfc2ZpeGVkMzIiKSkpOworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJvcHRpb25hbF9zZml4ZWQ2NCIpKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2Zsb2F0IiAgICkpKTsKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfZG91YmxlIiAgKSkpOworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJvcHRpb25hbF9ib29sIiAgICApKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX3N0cmluZyIgICkpKTsKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfYnl0ZXMiICAgKSkpOworCisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoIm9wdGlvbmFsZ3JvdXAiICAgICAgICAgICAgICAgICApKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlIiAgICAgICApKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSIgICAgICApKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlIiAgICAgICApKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZSIpKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2xhenlfbWVzc2FnZSIgICAgICAgICApKSk7CisKKyAgc3ViX21lc3NhZ2UgPSAmcmVmbGVjdGlvbi0+R2V0TWVzc2FnZShtZXNzYWdlLCBGKCJvcHRpb25hbGdyb3VwIikpOworICBFWFBFQ1RfVFJVRShzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5IYXNGaWVsZCgqc3ViX21lc3NhZ2UsIGdyb3VwX2FfKSk7CisgIHN1Yl9tZXNzYWdlID0gJnJlZmxlY3Rpb24tPkdldE1lc3NhZ2UobWVzc2FnZSwgRigib3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UiKSk7CisgIEVYUEVDVF9UUlVFKHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkhhc0ZpZWxkKCpzdWJfbWVzc2FnZSwgbmVzdGVkX2JfKSk7CisgIHN1Yl9tZXNzYWdlID0gJnJlZmxlY3Rpb24tPkdldE1lc3NhZ2UobWVzc2FnZSwgRigib3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlIikpOworICBFWFBFQ1RfVFJVRShzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5IYXNGaWVsZCgqc3ViX21lc3NhZ2UsIGZvcmVpZ25fY18pKTsKKyAgc3ViX21lc3NhZ2UgPSAmcmVmbGVjdGlvbi0+R2V0TWVzc2FnZShtZXNzYWdlLCBGKCJvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSIpKTsKKyAgRVhQRUNUX1RSVUUoc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+SGFzRmllbGQoKnN1Yl9tZXNzYWdlLCBpbXBvcnRfZF8pKTsKKyAgc3ViX21lc3NhZ2UgPSAmcmVmbGVjdGlvbi0+R2V0TWVzc2FnZShtZXNzYWdlLCBGKCJvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UiKSk7CisgIEVYUEVDVF9UUlVFKHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkhhc0ZpZWxkKCpzdWJfbWVzc2FnZSwgaW1wb3J0X2VfKSk7CisgIHN1Yl9tZXNzYWdlID0gJnJlZmxlY3Rpb24tPkdldE1lc3NhZ2UobWVzc2FnZSwgRigib3B0aW9uYWxfbGF6eV9tZXNzYWdlIikpOworICBFWFBFQ1RfVFJVRShzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5IYXNGaWVsZCgqc3ViX21lc3NhZ2UsIG5lc3RlZF9iXykpOworCisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX25lc3RlZF9lbnVtIiApKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2ZvcmVpZ25fZW51bSIpKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2ltcG9ydF9lbnVtIiApKSk7CisKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfc3RyaW5nX3BpZWNlIikpKTsKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfY29yZCIpKSk7CisKKyAgRVhQRUNUX0VRKDEwMSAgLCByZWZsZWN0aW9uLT5HZXRJbnQzMiAobWVzc2FnZSwgRigib3B0aW9uYWxfaW50MzIiICAgKSkpOworICBFWFBFQ1RfRVEoMTAyICAsIHJlZmxlY3Rpb24tPkdldEludDY0IChtZXNzYWdlLCBGKCJvcHRpb25hbF9pbnQ2NCIgICApKSk7CisgIEVYUEVDVF9FUSgxMDMgICwgcmVmbGVjdGlvbi0+R2V0VUludDMyKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX3VpbnQzMiIgICkpKTsKKyAgRVhQRUNUX0VRKDEwNCAgLCByZWZsZWN0aW9uLT5HZXRVSW50NjQobWVzc2FnZSwgRigib3B0aW9uYWxfdWludDY0IiAgKSkpOworICBFWFBFQ1RfRVEoMTA1ICAsIHJlZmxlY3Rpb24tPkdldEludDMyIChtZXNzYWdlLCBGKCJvcHRpb25hbF9zaW50MzIiICApKSk7CisgIEVYUEVDVF9FUSgxMDYgICwgcmVmbGVjdGlvbi0+R2V0SW50NjQgKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX3NpbnQ2NCIgICkpKTsKKyAgRVhQRUNUX0VRKDEwNyAgLCByZWZsZWN0aW9uLT5HZXRVSW50MzIobWVzc2FnZSwgRigib3B0aW9uYWxfZml4ZWQzMiIgKSkpOworICBFWFBFQ1RfRVEoMTA4ICAsIHJlZmxlY3Rpb24tPkdldFVJbnQ2NChtZXNzYWdlLCBGKCJvcHRpb25hbF9maXhlZDY0IiApKSk7CisgIEVYUEVDVF9FUSgxMDkgICwgcmVmbGVjdGlvbi0+R2V0SW50MzIgKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX3NmaXhlZDMyIikpKTsKKyAgRVhQRUNUX0VRKDExMCAgLCByZWZsZWN0aW9uLT5HZXRJbnQ2NCAobWVzc2FnZSwgRigib3B0aW9uYWxfc2ZpeGVkNjQiKSkpOworICBFWFBFQ1RfRVEoMTExICAsIHJlZmxlY3Rpb24tPkdldEZsb2F0IChtZXNzYWdlLCBGKCJvcHRpb25hbF9mbG9hdCIgICApKSk7CisgIEVYUEVDVF9FUSgxMTIgICwgcmVmbGVjdGlvbi0+R2V0RG91YmxlKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2RvdWJsZSIgICkpKTsKKyAgRVhQRUNUX1RSVUUoICAgICByZWZsZWN0aW9uLT5HZXRCb29sICAobWVzc2FnZSwgRigib3B0aW9uYWxfYm9vbCIgICAgKSkpOworICBFWFBFQ1RfRVEoIjExNSIsIHJlZmxlY3Rpb24tPkdldFN0cmluZyhtZXNzYWdlLCBGKCJvcHRpb25hbF9zdHJpbmciICApKSk7CisgIEVYUEVDVF9FUSgiMTE2IiwgcmVmbGVjdGlvbi0+R2V0U3RyaW5nKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2J5dGVzIiAgICkpKTsKKworICBFWFBFQ1RfRVEoIjExNSIsIHJlZmxlY3Rpb24tPkdldFN0cmluZ1JlZmVyZW5jZShtZXNzYWdlLCBGKCJvcHRpb25hbF9zdHJpbmciKSwgJnNjcmF0Y2gpKTsKKyAgRVhQRUNUX0VRKCIxMTYiLCByZWZsZWN0aW9uLT5HZXRTdHJpbmdSZWZlcmVuY2UobWVzc2FnZSwgRigib3B0aW9uYWxfYnl0ZXMiICksICZzY3JhdGNoKSk7CisKKyAgc3ViX21lc3NhZ2UgPSAmcmVmbGVjdGlvbi0+R2V0TWVzc2FnZShtZXNzYWdlLCBGKCJvcHRpb25hbGdyb3VwIikpOworICBFWFBFQ1RfRVEoMTE3LCBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigqc3ViX21lc3NhZ2UsIGdyb3VwX2FfKSk7CisgIHN1Yl9tZXNzYWdlID0gJnJlZmxlY3Rpb24tPkdldE1lc3NhZ2UobWVzc2FnZSwgRigib3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UiKSk7CisgIEVYUEVDVF9FUSgxMTgsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKCpzdWJfbWVzc2FnZSwgbmVzdGVkX2JfKSk7CisgIHN1Yl9tZXNzYWdlID0gJnJlZmxlY3Rpb24tPkdldE1lc3NhZ2UobWVzc2FnZSwgRigib3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlIikpOworICBFWFBFQ1RfRVEoMTE5LCBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigqc3ViX21lc3NhZ2UsIGZvcmVpZ25fY18pKTsKKyAgc3ViX21lc3NhZ2UgPSAmcmVmbGVjdGlvbi0+R2V0TWVzc2FnZShtZXNzYWdlLCBGKCJvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSIpKTsKKyAgRVhQRUNUX0VRKDEyMCwgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIoKnN1Yl9tZXNzYWdlLCBpbXBvcnRfZF8pKTsKKyAgc3ViX21lc3NhZ2UgPSAmcmVmbGVjdGlvbi0+R2V0TWVzc2FnZShtZXNzYWdlLCBGKCJvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UiKSk7CisgIEVYUEVDVF9FUSgxMjYsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKCpzdWJfbWVzc2FnZSwgaW1wb3J0X2VfKSk7CisgIHN1Yl9tZXNzYWdlID0gJnJlZmxlY3Rpb24tPkdldE1lc3NhZ2UobWVzc2FnZSwgRigib3B0aW9uYWxfbGF6eV9tZXNzYWdlIikpOworICBFWFBFQ1RfRVEoMTI3LCBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigqc3ViX21lc3NhZ2UsIG5lc3RlZF9iXykpOworCisgIEVYUEVDVF9FUSggbmVzdGVkX2Jhel8sIHJlZmxlY3Rpb24tPkdldEVudW0obWVzc2FnZSwgRigib3B0aW9uYWxfbmVzdGVkX2VudW0iICkpKTsKKyAgRVhQRUNUX0VRKGZvcmVpZ25fYmF6XywgcmVmbGVjdGlvbi0+R2V0RW51bShtZXNzYWdlLCBGKCJvcHRpb25hbF9mb3JlaWduX2VudW0iKSkpOworICBFWFBFQ1RfRVEoIGltcG9ydF9iYXpfLCByZWZsZWN0aW9uLT5HZXRFbnVtKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2ltcG9ydF9lbnVtIiApKSk7CisKKyAgRVhQRUNUX0VRKCIxMjQiLCByZWZsZWN0aW9uLT5HZXRTdHJpbmcobWVzc2FnZSwgRigib3B0aW9uYWxfc3RyaW5nX3BpZWNlIikpKTsKKyAgRVhQRUNUX0VRKCIxMjQiLCByZWZsZWN0aW9uLT5HZXRTdHJpbmdSZWZlcmVuY2UobWVzc2FnZSwgRigib3B0aW9uYWxfc3RyaW5nX3BpZWNlIiksICZzY3JhdGNoKSk7CisKKyAgRVhQRUNUX0VRKCIxMjUiLCByZWZsZWN0aW9uLT5HZXRTdHJpbmcobWVzc2FnZSwgRigib3B0aW9uYWxfY29yZCIpKSk7CisgIEVYUEVDVF9FUSgiMTI1IiwgcmVmbGVjdGlvbi0+R2V0U3RyaW5nUmVmZXJlbmNlKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2NvcmQiKSwgJnNjcmF0Y2gpKTsKKworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJvbmVvZl9ieXRlcyIgKSkpOworICBFWFBFQ1RfRVEoIjYwNCIsIHJlZmxlY3Rpb24tPkdldFN0cmluZyhtZXNzYWdlLCBGKCJvbmVvZl9ieXRlcyIgICApKSk7CisKKyAgaWYgKGJhc2VfZGVzY3JpcHRvcl8tPm5hbWUoKSA9PSAiVGVzdEFsbFR5cGVzIikgeworICAgIEVYUEVDVF9GQUxTRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJvbmVvZl91aW50MzIiKSkpOworICAgIEVYUEVDVF9GQUxTRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJvbmVvZl9zdHJpbmciKSkpOworICB9IGVsc2UgeworICAgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoIm9uZW9mX3VpbnQzMiIpKSk7CisgICAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib25lb2Zfc3RyaW5nIikpKTsKKyAgICBFWFBFQ1RfRVEoNjAxICAsIHJlZmxlY3Rpb24tPkdldFVJbnQzMihtZXNzYWdlLCBGKCJvbmVvZl91aW50MzIiKSkpOworICAgIEVYUEVDVF9FUSgiNjAzIiwgcmVmbGVjdGlvbi0+R2V0U3RyaW5nKG1lc3NhZ2UsIEYoIm9uZW9mX3N0cmluZyIpKSk7CisgICAgc3ViX21lc3NhZ2UgPSAmcmVmbGVjdGlvbi0+R2V0TWVzc2FnZShtZXNzYWdlLCBGKCJvbmVvZl9uZXN0ZWRfbWVzc2FnZSIpKTsKKyAgICBFWFBFQ1RfRVEoNjAyLCBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigqc3ViX21lc3NhZ2UsIG5lc3RlZF9iXykpOworICB9Cit9CisKK3ZvaWQgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXI6OkV4cGVjdEFsbEZpZWxkc1NldFZpYVJlZmxlY3Rpb24yKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UpIHsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpOworICBzdHJpbmcgc2NyYXRjaDsKKyAgY29uc3QgTWVzc2FnZSogc3ViX21lc3NhZ2U7CisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2ludDMyIiAgICkpKTsKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9pbnQ2NCIgICApKSk7CisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicmVwZWF0ZWRfdWludDMyIiAgKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3VpbnQ2NCIgICkpKTsKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9zaW50MzIiICApKSk7CisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicmVwZWF0ZWRfc2ludDY0IiAgKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2ZpeGVkMzIiICkpKTsKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9maXhlZDY0IiApKSk7CisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicmVwZWF0ZWRfc2ZpeGVkMzIiKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3NmaXhlZDY0IikpKTsKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9mbG9hdCIgICApKSk7CisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicmVwZWF0ZWRfZG91YmxlIiAgKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2Jvb2wiICAgICkpKTsKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9zdHJpbmciICApKSk7CisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicmVwZWF0ZWRfYnl0ZXMiICAgKSkpOworCisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicmVwZWF0ZWRncm91cCIgICAgICAgICAgICkpKTsKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSIgKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSIpKSk7CisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UiICkpKTsKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9sYXp5X21lc3NhZ2UiICAgKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInJlcGVhdGVkX25lc3RlZF9lbnVtIiAgICApKSk7CisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicmVwZWF0ZWRfZm9yZWlnbl9lbnVtIiAgICkpKTsKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9pbXBvcnRfZW51bSIgICAgKSkpOworCisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicmVwZWF0ZWRfc3RyaW5nX3BpZWNlIikpKTsKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9jb3JkIikpKTsKKworICBFWFBFQ1RfRVEoMjAxICAsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkSW50MzIgKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2ludDMyIiAgICksIDApKTsKKyAgRVhQRUNUX0VRKDIwMiAgLCByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZEludDY0IChtZXNzYWdlLCBGKCJyZXBlYXRlZF9pbnQ2NCIgICApLCAwKSk7CisgIEVYUEVDVF9FUSgyMDMgICwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRVSW50MzIobWVzc2FnZSwgRigicmVwZWF0ZWRfdWludDMyIiAgKSwgMCkpOworICBFWFBFQ1RfRVEoMjA0ICAsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkVUludDY0KG1lc3NhZ2UsIEYoInJlcGVhdGVkX3VpbnQ2NCIgICksIDApKTsKKyAgRVhQRUNUX0VRKDIwNSAgLCByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZEludDMyIChtZXNzYWdlLCBGKCJyZXBlYXRlZF9zaW50MzIiICApLCAwKSk7CisgIEVYUEVDVF9FUSgyMDYgICwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRJbnQ2NCAobWVzc2FnZSwgRigicmVwZWF0ZWRfc2ludDY0IiAgKSwgMCkpOworICBFWFBFQ1RfRVEoMjA3ICAsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkVUludDMyKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2ZpeGVkMzIiICksIDApKTsKKyAgRVhQRUNUX0VRKDIwOCAgLCByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZFVJbnQ2NChtZXNzYWdlLCBGKCJyZXBlYXRlZF9maXhlZDY0IiApLCAwKSk7CisgIEVYUEVDVF9FUSgyMDkgICwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRJbnQzMiAobWVzc2FnZSwgRigicmVwZWF0ZWRfc2ZpeGVkMzIiKSwgMCkpOworICBFWFBFQ1RfRVEoMjEwICAsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkSW50NjQgKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3NmaXhlZDY0IiksIDApKTsKKyAgRVhQRUNUX0VRKDIxMSAgLCByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZEZsb2F0IChtZXNzYWdlLCBGKCJyZXBlYXRlZF9mbG9hdCIgICApLCAwKSk7CisgIEVYUEVDVF9FUSgyMTIgICwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWREb3VibGUobWVzc2FnZSwgRigicmVwZWF0ZWRfZG91YmxlIiAgKSwgMCkpOworICBFWFBFQ1RfVFJVRSggICAgIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkQm9vbCAgKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2Jvb2wiICAgICksIDApKTsKKyAgRVhQRUNUX0VRKCIyMTUiLCByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZFN0cmluZyhtZXNzYWdlLCBGKCJyZXBlYXRlZF9zdHJpbmciICApLCAwKSk7CisgIEVYUEVDVF9FUSgiMjE2IiwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRTdHJpbmcobWVzc2FnZSwgRigicmVwZWF0ZWRfYnl0ZXMiICAgKSwgMCkpOworCisgIEVYUEVDVF9FUSgiMjE1IiwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRTdHJpbmdSZWZlcmVuY2UobWVzc2FnZSwgRigicmVwZWF0ZWRfc3RyaW5nIiksIDAsICZzY3JhdGNoKSk7CisgIEVYUEVDVF9FUSgiMjE2IiwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRTdHJpbmdSZWZlcmVuY2UobWVzc2FnZSwgRigicmVwZWF0ZWRfYnl0ZXMiKSwgMCwgJnNjcmF0Y2gpKTsKKworICBzdWJfbWVzc2FnZSA9ICZyZWZsZWN0aW9uLT5HZXRSZXBlYXRlZE1lc3NhZ2UobWVzc2FnZSwgRigicmVwZWF0ZWRncm91cCIpLCAwKTsKKyAgRVhQRUNUX0VRKDIxNywgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIoKnN1Yl9tZXNzYWdlLCByZXBlYXRlZF9ncm91cF9hXykpOworICBzdWJfbWVzc2FnZSA9ICZyZWZsZWN0aW9uLT5HZXRSZXBlYXRlZE1lc3NhZ2UobWVzc2FnZSwgRigicmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UiKSwgMCk7CisgIEVYUEVDVF9FUSgyMTgsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKCpzdWJfbWVzc2FnZSwgbmVzdGVkX2JfKSk7CisgIHN1Yl9tZXNzYWdlID0gJnJlZmxlY3Rpb24tPkdldFJlcGVhdGVkTWVzc2FnZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UiKSwgMCk7CisgIEVYUEVDVF9FUSgyMTksIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKCpzdWJfbWVzc2FnZSwgZm9yZWlnbl9jXykpOworICBzdWJfbWVzc2FnZSA9ICZyZWZsZWN0aW9uLT5HZXRSZXBlYXRlZE1lc3NhZ2UobWVzc2FnZSwgRigicmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UiKSwgMCk7CisgIEVYUEVDVF9FUSgyMjAsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKCpzdWJfbWVzc2FnZSwgaW1wb3J0X2RfKSk7CisgIHN1Yl9tZXNzYWdlID0gJnJlZmxlY3Rpb24tPkdldFJlcGVhdGVkTWVzc2FnZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9sYXp5X21lc3NhZ2UiKSwgMCk7CisgIEVYUEVDVF9FUSgyMjcsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKCpzdWJfbWVzc2FnZSwgbmVzdGVkX2JfKSk7CisKKyAgRVhQRUNUX0VRKCBuZXN0ZWRfYmFyXywgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRFbnVtKG1lc3NhZ2UsIEYoInJlcGVhdGVkX25lc3RlZF9lbnVtIiApLDApKTsKKyAgRVhQRUNUX0VRKGZvcmVpZ25fYmFyXywgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRFbnVtKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2ZvcmVpZ25fZW51bSIpLDApKTsKKyAgRVhQRUNUX0VRKCBpbXBvcnRfYmFyXywgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRFbnVtKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2ltcG9ydF9lbnVtIiApLDApKTsKKworICBFWFBFQ1RfRVEoIjIyNCIsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkU3RyaW5nKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3N0cmluZ19waWVjZSIpLCAwKSk7CisgIEVYUEVDVF9FUSgiMjI0IiwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRTdHJpbmdSZWZlcmVuY2UoCisgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLCBGKCJyZXBlYXRlZF9zdHJpbmdfcGllY2UiKSwgMCwgJnNjcmF0Y2gpKTsKKworICBFWFBFQ1RfRVEoIjIyNSIsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkU3RyaW5nKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2NvcmQiKSwgMCkpOworICBFWFBFQ1RfRVEoIjIyNSIsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkU3RyaW5nUmVmZXJlbmNlKAorICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSwgRigicmVwZWF0ZWRfY29yZCIpLCAwLCAmc2NyYXRjaCkpOworCisgIEVYUEVDVF9FUSgzMDEgICwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRJbnQzMiAobWVzc2FnZSwgRigicmVwZWF0ZWRfaW50MzIiICAgKSwgMSkpOworICBFWFBFQ1RfRVEoMzAyICAsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkSW50NjQgKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2ludDY0IiAgICksIDEpKTsKKyAgRVhQRUNUX0VRKDMwMyAgLCByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZFVJbnQzMihtZXNzYWdlLCBGKCJyZXBlYXRlZF91aW50MzIiICApLCAxKSk7CisgIEVYUEVDVF9FUSgzMDQgICwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRVSW50NjQobWVzc2FnZSwgRigicmVwZWF0ZWRfdWludDY0IiAgKSwgMSkpOworICBFWFBFQ1RfRVEoMzA1ICAsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkSW50MzIgKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3NpbnQzMiIgICksIDEpKTsKKyAgRVhQRUNUX0VRKDMwNiAgLCByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZEludDY0IChtZXNzYWdlLCBGKCJyZXBlYXRlZF9zaW50NjQiICApLCAxKSk7CisgIEVYUEVDVF9FUSgzMDcgICwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRVSW50MzIobWVzc2FnZSwgRigicmVwZWF0ZWRfZml4ZWQzMiIgKSwgMSkpOworICBFWFBFQ1RfRVEoMzA4ICAsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkVUludDY0KG1lc3NhZ2UsIEYoInJlcGVhdGVkX2ZpeGVkNjQiICksIDEpKTsKKyAgRVhQRUNUX0VRKDMwOSAgLCByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZEludDMyIChtZXNzYWdlLCBGKCJyZXBlYXRlZF9zZml4ZWQzMiIpLCAxKSk7CisgIEVYUEVDVF9FUSgzMTAgICwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRJbnQ2NCAobWVzc2FnZSwgRigicmVwZWF0ZWRfc2ZpeGVkNjQiKSwgMSkpOworICBFWFBFQ1RfRVEoMzExICAsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkRmxvYXQgKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2Zsb2F0IiAgICksIDEpKTsKKyAgRVhQRUNUX0VRKDMxMiAgLCByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZERvdWJsZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9kb3VibGUiICApLCAxKSk7CisgIEVYUEVDVF9GQUxTRSggICAgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRCb29sICAobWVzc2FnZSwgRigicmVwZWF0ZWRfYm9vbCIgICAgKSwgMSkpOworICBFWFBFQ1RfRVEoIjMxNSIsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkU3RyaW5nKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3N0cmluZyIgICksIDEpKTsKKyAgRVhQRUNUX0VRKCIzMTYiLCByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZFN0cmluZyhtZXNzYWdlLCBGKCJyZXBlYXRlZF9ieXRlcyIgICApLCAxKSk7CisKKyAgRVhQRUNUX0VRKCIzMTUiLCByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZFN0cmluZ1JlZmVyZW5jZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9zdHJpbmciKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLCAmc2NyYXRjaCkpOworICBFWFBFQ1RfRVEoIjMxNiIsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkU3RyaW5nUmVmZXJlbmNlKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2J5dGVzIiksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMSwgJnNjcmF0Y2gpKTsKKworICBzdWJfbWVzc2FnZSA9ICZyZWZsZWN0aW9uLT5HZXRSZXBlYXRlZE1lc3NhZ2UobWVzc2FnZSwgRigicmVwZWF0ZWRncm91cCIpLCAxKTsKKyAgRVhQRUNUX0VRKDMxNywgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIoKnN1Yl9tZXNzYWdlLCByZXBlYXRlZF9ncm91cF9hXykpOworICBzdWJfbWVzc2FnZSA9ICZyZWZsZWN0aW9uLT5HZXRSZXBlYXRlZE1lc3NhZ2UobWVzc2FnZSwgRigicmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UiKSwgMSk7CisgIEVYUEVDVF9FUSgzMTgsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKCpzdWJfbWVzc2FnZSwgbmVzdGVkX2JfKSk7CisgIHN1Yl9tZXNzYWdlID0gJnJlZmxlY3Rpb24tPkdldFJlcGVhdGVkTWVzc2FnZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UiKSwgMSk7CisgIEVYUEVDVF9FUSgzMTksIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKCpzdWJfbWVzc2FnZSwgZm9yZWlnbl9jXykpOworICBzdWJfbWVzc2FnZSA9ICZyZWZsZWN0aW9uLT5HZXRSZXBlYXRlZE1lc3NhZ2UobWVzc2FnZSwgRigicmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UiKSwgMSk7CisgIEVYUEVDVF9FUSgzMjAsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKCpzdWJfbWVzc2FnZSwgaW1wb3J0X2RfKSk7CisgIHN1Yl9tZXNzYWdlID0gJnJlZmxlY3Rpb24tPkdldFJlcGVhdGVkTWVzc2FnZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9sYXp5X21lc3NhZ2UiKSwgMSk7CisgIEVYUEVDVF9FUSgzMjcsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKCpzdWJfbWVzc2FnZSwgbmVzdGVkX2JfKSk7CisKKyAgRVhQRUNUX0VRKCBuZXN0ZWRfYmF6XywgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRFbnVtKG1lc3NhZ2UsIEYoInJlcGVhdGVkX25lc3RlZF9lbnVtIiApLDEpKTsKKyAgRVhQRUNUX0VRKGZvcmVpZ25fYmF6XywgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRFbnVtKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2ZvcmVpZ25fZW51bSIpLDEpKTsKKyAgRVhQRUNUX0VRKCBpbXBvcnRfYmF6XywgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRFbnVtKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2ltcG9ydF9lbnVtIiApLDEpKTsKKworICBFWFBFQ1RfRVEoIjMyNCIsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkU3RyaW5nKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3N0cmluZ19waWVjZSIpLCAxKSk7CisgIEVYUEVDVF9FUSgiMzI0IiwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRTdHJpbmdSZWZlcmVuY2UoCisgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLCBGKCJyZXBlYXRlZF9zdHJpbmdfcGllY2UiKSwgMSwgJnNjcmF0Y2gpKTsKKworICBFWFBFQ1RfRVEoIjMyNSIsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkU3RyaW5nKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2NvcmQiKSwgMSkpOworICBFWFBFQ1RfRVEoIjMyNSIsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkU3RyaW5nUmVmZXJlbmNlKAorICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSwgRigicmVwZWF0ZWRfY29yZCIpLCAxLCAmc2NyYXRjaCkpOworfQorCit2b2lkIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyOjpFeHBlY3RBbGxGaWVsZHNTZXRWaWFSZWZsZWN0aW9uMygKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlKSB7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKTsKKyAgc3RyaW5nIHNjcmF0Y2g7CisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJkZWZhdWx0X2ludDMyIiAgICkpKTsKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigiZGVmYXVsdF9pbnQ2NCIgICApKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoImRlZmF1bHRfdWludDMyIiAgKSkpOworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJkZWZhdWx0X3VpbnQ2NCIgICkpKTsKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigiZGVmYXVsdF9zaW50MzIiICApKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoImRlZmF1bHRfc2ludDY0IiAgKSkpOworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJkZWZhdWx0X2ZpeGVkMzIiICkpKTsKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigiZGVmYXVsdF9maXhlZDY0IiApKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoImRlZmF1bHRfc2ZpeGVkMzIiKSkpOworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJkZWZhdWx0X3NmaXhlZDY0IikpKTsKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigiZGVmYXVsdF9mbG9hdCIgICApKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoImRlZmF1bHRfZG91YmxlIiAgKSkpOworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJkZWZhdWx0X2Jvb2wiICAgICkpKTsKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigiZGVmYXVsdF9zdHJpbmciICApKSk7CisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoImRlZmF1bHRfYnl0ZXMiICAgKSkpOworCisgIEVYUEVDVF9UUlVFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoImRlZmF1bHRfbmVzdGVkX2VudW0iICkpKTsKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigiZGVmYXVsdF9mb3JlaWduX2VudW0iKSkpOworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJkZWZhdWx0X2ltcG9ydF9lbnVtIiApKSk7CisKKyAgRVhQRUNUX1RSVUUocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigiZGVmYXVsdF9zdHJpbmdfcGllY2UiKSkpOworICBFWFBFQ1RfVFJVRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJkZWZhdWx0X2NvcmQiKSkpOworCisgIEVYUEVDVF9FUSg0MDEgICwgcmVmbGVjdGlvbi0+R2V0SW50MzIgKG1lc3NhZ2UsIEYoImRlZmF1bHRfaW50MzIiICAgKSkpOworICBFWFBFQ1RfRVEoNDAyICAsIHJlZmxlY3Rpb24tPkdldEludDY0IChtZXNzYWdlLCBGKCJkZWZhdWx0X2ludDY0IiAgICkpKTsKKyAgRVhQRUNUX0VRKDQwMyAgLCByZWZsZWN0aW9uLT5HZXRVSW50MzIobWVzc2FnZSwgRigiZGVmYXVsdF91aW50MzIiICApKSk7CisgIEVYUEVDVF9FUSg0MDQgICwgcmVmbGVjdGlvbi0+R2V0VUludDY0KG1lc3NhZ2UsIEYoImRlZmF1bHRfdWludDY0IiAgKSkpOworICBFWFBFQ1RfRVEoNDA1ICAsIHJlZmxlY3Rpb24tPkdldEludDMyIChtZXNzYWdlLCBGKCJkZWZhdWx0X3NpbnQzMiIgICkpKTsKKyAgRVhQRUNUX0VRKDQwNiAgLCByZWZsZWN0aW9uLT5HZXRJbnQ2NCAobWVzc2FnZSwgRigiZGVmYXVsdF9zaW50NjQiICApKSk7CisgIEVYUEVDVF9FUSg0MDcgICwgcmVmbGVjdGlvbi0+R2V0VUludDMyKG1lc3NhZ2UsIEYoImRlZmF1bHRfZml4ZWQzMiIgKSkpOworICBFWFBFQ1RfRVEoNDA4ICAsIHJlZmxlY3Rpb24tPkdldFVJbnQ2NChtZXNzYWdlLCBGKCJkZWZhdWx0X2ZpeGVkNjQiICkpKTsKKyAgRVhQRUNUX0VRKDQwOSAgLCByZWZsZWN0aW9uLT5HZXRJbnQzMiAobWVzc2FnZSwgRigiZGVmYXVsdF9zZml4ZWQzMiIpKSk7CisgIEVYUEVDVF9FUSg0MTAgICwgcmVmbGVjdGlvbi0+R2V0SW50NjQgKG1lc3NhZ2UsIEYoImRlZmF1bHRfc2ZpeGVkNjQiKSkpOworICBFWFBFQ1RfRVEoNDExICAsIHJlZmxlY3Rpb24tPkdldEZsb2F0IChtZXNzYWdlLCBGKCJkZWZhdWx0X2Zsb2F0IiAgICkpKTsKKyAgRVhQRUNUX0VRKDQxMiAgLCByZWZsZWN0aW9uLT5HZXREb3VibGUobWVzc2FnZSwgRigiZGVmYXVsdF9kb3VibGUiICApKSk7CisgIEVYUEVDVF9GQUxTRSggICAgcmVmbGVjdGlvbi0+R2V0Qm9vbCAgKG1lc3NhZ2UsIEYoImRlZmF1bHRfYm9vbCIgICAgKSkpOworICBFWFBFQ1RfRVEoIjQxNSIsIHJlZmxlY3Rpb24tPkdldFN0cmluZyhtZXNzYWdlLCBGKCJkZWZhdWx0X3N0cmluZyIgICkpKTsKKyAgRVhQRUNUX0VRKCI0MTYiLCByZWZsZWN0aW9uLT5HZXRTdHJpbmcobWVzc2FnZSwgRigiZGVmYXVsdF9ieXRlcyIgICApKSk7CisKKyAgRVhQRUNUX0VRKCI0MTUiLCByZWZsZWN0aW9uLT5HZXRTdHJpbmdSZWZlcmVuY2UobWVzc2FnZSwgRigiZGVmYXVsdF9zdHJpbmciKSwgJnNjcmF0Y2gpKTsKKyAgRVhQRUNUX0VRKCI0MTYiLCByZWZsZWN0aW9uLT5HZXRTdHJpbmdSZWZlcmVuY2UobWVzc2FnZSwgRigiZGVmYXVsdF9ieXRlcyIgKSwgJnNjcmF0Y2gpKTsKKworICBFWFBFQ1RfRVEoIG5lc3RlZF9mb29fLCByZWZsZWN0aW9uLT5HZXRFbnVtKG1lc3NhZ2UsIEYoImRlZmF1bHRfbmVzdGVkX2VudW0iICkpKTsKKyAgRVhQRUNUX0VRKGZvcmVpZ25fZm9vXywgcmVmbGVjdGlvbi0+R2V0RW51bShtZXNzYWdlLCBGKCJkZWZhdWx0X2ZvcmVpZ25fZW51bSIpKSk7CisgIEVYUEVDVF9FUSggaW1wb3J0X2Zvb18sIHJlZmxlY3Rpb24tPkdldEVudW0obWVzc2FnZSwgRigiZGVmYXVsdF9pbXBvcnRfZW51bSIgKSkpOworCisgIEVYUEVDVF9FUSgiNDI0IiwgcmVmbGVjdGlvbi0+R2V0U3RyaW5nKG1lc3NhZ2UsIEYoImRlZmF1bHRfc3RyaW5nX3BpZWNlIikpKTsKKyAgRVhQRUNUX0VRKCI0MjQiLCByZWZsZWN0aW9uLT5HZXRTdHJpbmdSZWZlcmVuY2UobWVzc2FnZSwgRigiZGVmYXVsdF9zdHJpbmdfcGllY2UiKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnNjcmF0Y2gpKTsKKworICBFWFBFQ1RfRVEoIjQyNSIsIHJlZmxlY3Rpb24tPkdldFN0cmluZyhtZXNzYWdlLCBGKCJkZWZhdWx0X2NvcmQiKSkpOworICBFWFBFQ1RfRVEoIjQyNSIsIHJlZmxlY3Rpb24tPkdldFN0cmluZ1JlZmVyZW5jZShtZXNzYWdlLCBGKCJkZWZhdWx0X2NvcmQiKSwgJnNjcmF0Y2gpKTsKK30KKwordm9pZCBUZXN0VXRpbDo6UmVmbGVjdGlvblRlc3Rlcjo6RXhwZWN0UGFja2VkRmllbGRzU2V0VmlhUmVmbGVjdGlvbigKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlKSB7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKTsKKworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInBhY2tlZF9pbnQzMiIgICApKSk7CisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicGFja2VkX2ludDY0IiAgICkpKTsKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJwYWNrZWRfdWludDMyIiAgKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInBhY2tlZF91aW50NjQiICApKSk7CisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicGFja2VkX3NpbnQzMiIgICkpKTsKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJwYWNrZWRfc2ludDY0IiAgKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInBhY2tlZF9maXhlZDMyIiApKSk7CisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicGFja2VkX2ZpeGVkNjQiICkpKTsKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJwYWNrZWRfc2ZpeGVkMzIiKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInBhY2tlZF9zZml4ZWQ2NCIpKSk7CisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicGFja2VkX2Zsb2F0IiAgICkpKTsKKyAgQVNTRVJUX0VRKDIsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJwYWNrZWRfZG91YmxlIiAgKSkpOworICBBU1NFUlRfRVEoMiwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInBhY2tlZF9ib29sIiAgICApKSk7CisgIEFTU0VSVF9FUSgyLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicGFja2VkX2VudW0iICAgICkpKTsKKworICBFWFBFQ1RfRVEoNjAxICAsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkSW50MzIgKG1lc3NhZ2UsIEYoInBhY2tlZF9pbnQzMiIgICApLCAwKSk7CisgIEVYUEVDVF9FUSg2MDIgICwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRJbnQ2NCAobWVzc2FnZSwgRigicGFja2VkX2ludDY0IiAgICksIDApKTsKKyAgRVhQRUNUX0VRKDYwMyAgLCByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZFVJbnQzMihtZXNzYWdlLCBGKCJwYWNrZWRfdWludDMyIiAgKSwgMCkpOworICBFWFBFQ1RfRVEoNjA0ICAsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkVUludDY0KG1lc3NhZ2UsIEYoInBhY2tlZF91aW50NjQiICApLCAwKSk7CisgIEVYUEVDVF9FUSg2MDUgICwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRJbnQzMiAobWVzc2FnZSwgRigicGFja2VkX3NpbnQzMiIgICksIDApKTsKKyAgRVhQRUNUX0VRKDYwNiAgLCByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZEludDY0IChtZXNzYWdlLCBGKCJwYWNrZWRfc2ludDY0IiAgKSwgMCkpOworICBFWFBFQ1RfRVEoNjA3ICAsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkVUludDMyKG1lc3NhZ2UsIEYoInBhY2tlZF9maXhlZDMyIiApLCAwKSk7CisgIEVYUEVDVF9FUSg2MDggICwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRVSW50NjQobWVzc2FnZSwgRigicGFja2VkX2ZpeGVkNjQiICksIDApKTsKKyAgRVhQRUNUX0VRKDYwOSAgLCByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZEludDMyIChtZXNzYWdlLCBGKCJwYWNrZWRfc2ZpeGVkMzIiKSwgMCkpOworICBFWFBFQ1RfRVEoNjEwICAsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkSW50NjQgKG1lc3NhZ2UsIEYoInBhY2tlZF9zZml4ZWQ2NCIpLCAwKSk7CisgIEVYUEVDVF9FUSg2MTEgICwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRGbG9hdCAobWVzc2FnZSwgRigicGFja2VkX2Zsb2F0IiAgICksIDApKTsKKyAgRVhQRUNUX0VRKDYxMiAgLCByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZERvdWJsZShtZXNzYWdlLCBGKCJwYWNrZWRfZG91YmxlIiAgKSwgMCkpOworICBFWFBFQ1RfVFJVRSggICAgIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkQm9vbCAgKG1lc3NhZ2UsIEYoInBhY2tlZF9ib29sIiAgICApLCAwKSk7CisgIEVYUEVDVF9FUShmb3JlaWduX2Jhcl8sCisgICAgICAgICAgICByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZEVudW0obWVzc2FnZSwgRigicGFja2VkX2VudW0iKSwgMCkpOworCisgIEVYUEVDVF9FUSg3MDEgICwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRJbnQzMiAobWVzc2FnZSwgRigicGFja2VkX2ludDMyIiAgICksIDEpKTsKKyAgRVhQRUNUX0VRKDcwMiAgLCByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZEludDY0IChtZXNzYWdlLCBGKCJwYWNrZWRfaW50NjQiICAgKSwgMSkpOworICBFWFBFQ1RfRVEoNzAzICAsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkVUludDMyKG1lc3NhZ2UsIEYoInBhY2tlZF91aW50MzIiICApLCAxKSk7CisgIEVYUEVDVF9FUSg3MDQgICwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRVSW50NjQobWVzc2FnZSwgRigicGFja2VkX3VpbnQ2NCIgICksIDEpKTsKKyAgRVhQRUNUX0VRKDcwNSAgLCByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZEludDMyIChtZXNzYWdlLCBGKCJwYWNrZWRfc2ludDMyIiAgKSwgMSkpOworICBFWFBFQ1RfRVEoNzA2ICAsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkSW50NjQgKG1lc3NhZ2UsIEYoInBhY2tlZF9zaW50NjQiICApLCAxKSk7CisgIEVYUEVDVF9FUSg3MDcgICwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRVSW50MzIobWVzc2FnZSwgRigicGFja2VkX2ZpeGVkMzIiICksIDEpKTsKKyAgRVhQRUNUX0VRKDcwOCAgLCByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZFVJbnQ2NChtZXNzYWdlLCBGKCJwYWNrZWRfZml4ZWQ2NCIgKSwgMSkpOworICBFWFBFQ1RfRVEoNzA5ICAsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkSW50MzIgKG1lc3NhZ2UsIEYoInBhY2tlZF9zZml4ZWQzMiIpLCAxKSk7CisgIEVYUEVDVF9FUSg3MTAgICwgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRJbnQ2NCAobWVzc2FnZSwgRigicGFja2VkX3NmaXhlZDY0IiksIDEpKTsKKyAgRVhQRUNUX0VRKDcxMSAgLCByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZEZsb2F0IChtZXNzYWdlLCBGKCJwYWNrZWRfZmxvYXQiICAgKSwgMSkpOworICBFWFBFQ1RfRVEoNzEyICAsIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkRG91YmxlKG1lc3NhZ2UsIEYoInBhY2tlZF9kb3VibGUiICApLCAxKSk7CisgIEVYUEVDVF9GQUxTRSggICAgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRCb29sICAobWVzc2FnZSwgRigicGFja2VkX2Jvb2wiICAgICksIDEpKTsKKyAgRVhQRUNUX0VRKGZvcmVpZ25fYmF6XywKKyAgICAgICAgICAgIHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkRW51bShtZXNzYWdlLCBGKCJwYWNrZWRfZW51bSIpLCAxKSk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBUZXN0VXRpbDo6UmVmbGVjdGlvblRlc3Rlcjo6RXhwZWN0Q2xlYXJWaWFSZWZsZWN0aW9uKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UpIHsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpOworICBzdHJpbmcgc2NyYXRjaDsKKyAgY29uc3QgTWVzc2FnZSogc3ViX21lc3NhZ2U7CisKKyAgLy8gaGFzX2JsYWgoKSBzaG91bGQgaW5pdGlhbGx5IGJlIGZhbHNlIGZvciBhbGwgb3B0aW9uYWwgZmllbGRzLgorICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfaW50MzIiICAgKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfaW50NjQiICAgKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfdWludDMyIiAgKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfdWludDY0IiAgKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfc2ludDMyIiAgKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfc2ludDY0IiAgKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfZml4ZWQzMiIgKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfZml4ZWQ2NCIgKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfc2ZpeGVkMzIiKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfc2ZpeGVkNjQiKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfZmxvYXQiICAgKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfZG91YmxlIiAgKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfYm9vbCIgICAgKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfc3RyaW5nIiAgKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfYnl0ZXMiICAgKSkpOworCisgIEVYUEVDVF9GQUxTRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJvcHRpb25hbGdyb3VwIiAgICAgICAgICAgKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UiICkpKTsKKyAgRVhQRUNUX0ZBTFNFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSIpKSk7CisgIEVYUEVDVF9GQUxTRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSIgKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlIikpKTsKKyAgRVhQRUNUX0ZBTFNFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2xhenlfbWVzc2FnZSIpKSk7CisKKyAgRVhQRUNUX0ZBTFNFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX25lc3RlZF9lbnVtIiApKSk7CisgIEVYUEVDVF9GQUxTRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJvcHRpb25hbF9mb3JlaWduX2VudW0iKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfaW1wb3J0X2VudW0iICkpKTsKKworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigib3B0aW9uYWxfc3RyaW5nX3BpZWNlIikpKTsKKyAgRVhQRUNUX0ZBTFNFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2NvcmQiKSkpOworCisgIC8vIE9wdGlvbmFsIGZpZWxkcyB3aXRob3V0IGRlZmF1bHRzIGFyZSBzZXQgdG8gemVybyBvciBzb21ldGhpbmcgbGlrZSBpdC4KKyAgRVhQRUNUX0VRKDAgICAgLCByZWZsZWN0aW9uLT5HZXRJbnQzMiAobWVzc2FnZSwgRigib3B0aW9uYWxfaW50MzIiICAgKSkpOworICBFWFBFQ1RfRVEoMCAgICAsIHJlZmxlY3Rpb24tPkdldEludDY0IChtZXNzYWdlLCBGKCJvcHRpb25hbF9pbnQ2NCIgICApKSk7CisgIEVYUEVDVF9FUSgwICAgICwgcmVmbGVjdGlvbi0+R2V0VUludDMyKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX3VpbnQzMiIgICkpKTsKKyAgRVhQRUNUX0VRKDAgICAgLCByZWZsZWN0aW9uLT5HZXRVSW50NjQobWVzc2FnZSwgRigib3B0aW9uYWxfdWludDY0IiAgKSkpOworICBFWFBFQ1RfRVEoMCAgICAsIHJlZmxlY3Rpb24tPkdldEludDMyIChtZXNzYWdlLCBGKCJvcHRpb25hbF9zaW50MzIiICApKSk7CisgIEVYUEVDVF9FUSgwICAgICwgcmVmbGVjdGlvbi0+R2V0SW50NjQgKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX3NpbnQ2NCIgICkpKTsKKyAgRVhQRUNUX0VRKDAgICAgLCByZWZsZWN0aW9uLT5HZXRVSW50MzIobWVzc2FnZSwgRigib3B0aW9uYWxfZml4ZWQzMiIgKSkpOworICBFWFBFQ1RfRVEoMCAgICAsIHJlZmxlY3Rpb24tPkdldFVJbnQ2NChtZXNzYWdlLCBGKCJvcHRpb25hbF9maXhlZDY0IiApKSk7CisgIEVYUEVDVF9FUSgwICAgICwgcmVmbGVjdGlvbi0+R2V0SW50MzIgKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX3NmaXhlZDMyIikpKTsKKyAgRVhQRUNUX0VRKDAgICAgLCByZWZsZWN0aW9uLT5HZXRJbnQ2NCAobWVzc2FnZSwgRigib3B0aW9uYWxfc2ZpeGVkNjQiKSkpOworICBFWFBFQ1RfRVEoMCAgICAsIHJlZmxlY3Rpb24tPkdldEZsb2F0IChtZXNzYWdlLCBGKCJvcHRpb25hbF9mbG9hdCIgICApKSk7CisgIEVYUEVDVF9FUSgwICAgICwgcmVmbGVjdGlvbi0+R2V0RG91YmxlKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2RvdWJsZSIgICkpKTsKKyAgRVhQRUNUX0ZBTFNFKCAgICByZWZsZWN0aW9uLT5HZXRCb29sICAobWVzc2FnZSwgRigib3B0aW9uYWxfYm9vbCIgICAgKSkpOworICBFWFBFQ1RfRVEoIiIgICAsIHJlZmxlY3Rpb24tPkdldFN0cmluZyhtZXNzYWdlLCBGKCJvcHRpb25hbF9zdHJpbmciICApKSk7CisgIEVYUEVDVF9FUSgiIiAgICwgcmVmbGVjdGlvbi0+R2V0U3RyaW5nKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2J5dGVzIiAgICkpKTsKKworICBFWFBFQ1RfRVEoIiIsIHJlZmxlY3Rpb24tPkdldFN0cmluZ1JlZmVyZW5jZShtZXNzYWdlLCBGKCJvcHRpb25hbF9zdHJpbmciKSwgJnNjcmF0Y2gpKTsKKyAgRVhQRUNUX0VRKCIiLCByZWZsZWN0aW9uLT5HZXRTdHJpbmdSZWZlcmVuY2UobWVzc2FnZSwgRigib3B0aW9uYWxfYnl0ZXMiICksICZzY3JhdGNoKSk7CisKKyAgLy8gRW1iZWRkZWQgbWVzc2FnZXMgc2hvdWxkIGFsc28gYmUgY2xlYXIuCisgIHN1Yl9tZXNzYWdlID0gJnJlZmxlY3Rpb24tPkdldE1lc3NhZ2UobWVzc2FnZSwgRigib3B0aW9uYWxncm91cCIpKTsKKyAgRVhQRUNUX0ZBTFNFKHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkhhc0ZpZWxkKCpzdWJfbWVzc2FnZSwgZ3JvdXBfYV8pKTsKKyAgRVhQRUNUX0VRKDAsIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkdldEludDMyKCpzdWJfbWVzc2FnZSwgZ3JvdXBfYV8pKTsKKyAgc3ViX21lc3NhZ2UgPSAmcmVmbGVjdGlvbi0+R2V0TWVzc2FnZShtZXNzYWdlLCBGKCJvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSIpKTsKKyAgRVhQRUNUX0ZBTFNFKHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkhhc0ZpZWxkKCpzdWJfbWVzc2FnZSwgbmVzdGVkX2JfKSk7CisgIEVYUEVDVF9FUSgwLCBzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5HZXRJbnQzMigqc3ViX21lc3NhZ2UsIG5lc3RlZF9iXykpOworICBzdWJfbWVzc2FnZSA9ICZyZWZsZWN0aW9uLT5HZXRNZXNzYWdlKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSIpKTsKKyAgRVhQRUNUX0ZBTFNFKHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPkhhc0ZpZWxkKCpzdWJfbWVzc2FnZSwgZm9yZWlnbl9jXykpOworICBFWFBFQ1RfRVEoMCwgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIoKnN1Yl9tZXNzYWdlLCBmb3JlaWduX2NfKSk7CisgIHN1Yl9tZXNzYWdlID0gJnJlZmxlY3Rpb24tPkdldE1lc3NhZ2UobWVzc2FnZSwgRigib3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UiKSk7CisgIEVYUEVDVF9GQUxTRShzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5IYXNGaWVsZCgqc3ViX21lc3NhZ2UsIGltcG9ydF9kXykpOworICBFWFBFQ1RfRVEoMCwgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIoKnN1Yl9tZXNzYWdlLCBpbXBvcnRfZF8pKTsKKyAgc3ViX21lc3NhZ2UgPSAmcmVmbGVjdGlvbi0+R2V0TWVzc2FnZShtZXNzYWdlLCBGKCJvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UiKSk7CisgIEVYUEVDVF9GQUxTRShzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5IYXNGaWVsZCgqc3ViX21lc3NhZ2UsIGltcG9ydF9lXykpOworICBFWFBFQ1RfRVEoMCwgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIoKnN1Yl9tZXNzYWdlLCBpbXBvcnRfZV8pKTsKKyAgc3ViX21lc3NhZ2UgPSAmcmVmbGVjdGlvbi0+R2V0TWVzc2FnZShtZXNzYWdlLCBGKCJvcHRpb25hbF9sYXp5X21lc3NhZ2UiKSk7CisgIEVYUEVDVF9GQUxTRShzdWJfbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpLT5IYXNGaWVsZCgqc3ViX21lc3NhZ2UsIG5lc3RlZF9iXykpOworICBFWFBFQ1RfRVEoMCwgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+R2V0SW50MzIoKnN1Yl9tZXNzYWdlLCBuZXN0ZWRfYl8pKTsKKworICAvLyBFbnVtcyB3aXRob3V0IGRlZmF1bHRzIGFyZSBzZXQgdG8gdGhlIGZpcnN0IHZhbHVlIGluIHRoZSBlbnVtLgorICBFWFBFQ1RfRVEoIG5lc3RlZF9mb29fLCByZWZsZWN0aW9uLT5HZXRFbnVtKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX25lc3RlZF9lbnVtIiApKSk7CisgIEVYUEVDVF9FUShmb3JlaWduX2Zvb18sIHJlZmxlY3Rpb24tPkdldEVudW0obWVzc2FnZSwgRigib3B0aW9uYWxfZm9yZWlnbl9lbnVtIikpKTsKKyAgRVhQRUNUX0VRKCBpbXBvcnRfZm9vXywgcmVmbGVjdGlvbi0+R2V0RW51bShtZXNzYWdlLCBGKCJvcHRpb25hbF9pbXBvcnRfZW51bSIgKSkpOworCisgIEVYUEVDVF9FUSgiIiwgcmVmbGVjdGlvbi0+R2V0U3RyaW5nKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX3N0cmluZ19waWVjZSIpKSk7CisgIEVYUEVDVF9FUSgiIiwgcmVmbGVjdGlvbi0+R2V0U3RyaW5nUmVmZXJlbmNlKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX3N0cmluZ19waWVjZSIpLCAmc2NyYXRjaCkpOworCisgIEVYUEVDVF9FUSgiIiwgcmVmbGVjdGlvbi0+R2V0U3RyaW5nKG1lc3NhZ2UsIEYoIm9wdGlvbmFsX2NvcmQiKSkpOworICBFWFBFQ1RfRVEoIiIsIHJlZmxlY3Rpb24tPkdldFN0cmluZ1JlZmVyZW5jZShtZXNzYWdlLCBGKCJvcHRpb25hbF9jb3JkIiksICZzY3JhdGNoKSk7CisKKyAgLy8gUmVwZWF0ZWQgZmllbGRzIGFyZSBlbXB0eS4KKyAgRVhQRUNUX0VRKDAsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9pbnQzMiIgICApKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicmVwZWF0ZWRfaW50NjQiICAgKSkpOworICBFWFBFQ1RfRVEoMCwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3VpbnQzMiIgICkpKTsKKyAgRVhQRUNUX0VRKDAsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJyZXBlYXRlZF91aW50NjQiICApKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicmVwZWF0ZWRfc2ludDMyIiAgKSkpOworICBFWFBFQ1RfRVEoMCwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3NpbnQ2NCIgICkpKTsKKyAgRVhQRUNUX0VRKDAsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9maXhlZDMyIiApKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicmVwZWF0ZWRfZml4ZWQ2NCIgKSkpOworICBFWFBFQ1RfRVEoMCwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3NmaXhlZDMyIikpKTsKKyAgRVhQRUNUX0VRKDAsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9zZml4ZWQ2NCIpKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicmVwZWF0ZWRfZmxvYXQiICAgKSkpOworICBFWFBFQ1RfRVEoMCwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2RvdWJsZSIgICkpKTsKKyAgRVhQRUNUX0VRKDAsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9ib29sIiAgICApKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicmVwZWF0ZWRfc3RyaW5nIiAgKSkpOworICBFWFBFQ1RfRVEoMCwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2J5dGVzIiAgICkpKTsKKworICBFWFBFQ1RfRVEoMCwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInJlcGVhdGVkZ3JvdXAiICAgICAgICAgICApKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UiICkpKTsKKyAgRVhQRUNUX0VRKDAsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UiKSkpOworICBFWFBFQ1RfRVEoMCwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlIiApKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicmVwZWF0ZWRfbGF6eV9tZXNzYWdlIiAgICkpKTsKKyAgRVhQRUNUX0VRKDAsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9uZXN0ZWRfZW51bSIgICAgKSkpOworICBFWFBFQ1RfRVEoMCwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2ZvcmVpZ25fZW51bSIgICApKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicmVwZWF0ZWRfaW1wb3J0X2VudW0iICAgICkpKTsKKworICBFWFBFQ1RfRVEoMCwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3N0cmluZ19waWVjZSIpKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicmVwZWF0ZWRfY29yZCIpKSk7CisKKyAgLy8gaGFzX2JsYWgoKSBzaG91bGQgYWxzbyBiZSBmYWxzZSBmb3IgYWxsIGRlZmF1bHQgZmllbGRzLgorICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigiZGVmYXVsdF9pbnQzMiIgICApKSk7CisgIEVYUEVDVF9GQUxTRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJkZWZhdWx0X2ludDY0IiAgICkpKTsKKyAgRVhQRUNUX0ZBTFNFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoImRlZmF1bHRfdWludDMyIiAgKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigiZGVmYXVsdF91aW50NjQiICApKSk7CisgIEVYUEVDVF9GQUxTRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJkZWZhdWx0X3NpbnQzMiIgICkpKTsKKyAgRVhQRUNUX0ZBTFNFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoImRlZmF1bHRfc2ludDY0IiAgKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigiZGVmYXVsdF9maXhlZDMyIiApKSk7CisgIEVYUEVDVF9GQUxTRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJkZWZhdWx0X2ZpeGVkNjQiICkpKTsKKyAgRVhQRUNUX0ZBTFNFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoImRlZmF1bHRfc2ZpeGVkMzIiKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigiZGVmYXVsdF9zZml4ZWQ2NCIpKSk7CisgIEVYUEVDVF9GQUxTRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJkZWZhdWx0X2Zsb2F0IiAgICkpKTsKKyAgRVhQRUNUX0ZBTFNFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoImRlZmF1bHRfZG91YmxlIiAgKSkpOworICBFWFBFQ1RfRkFMU0UocmVmbGVjdGlvbi0+SGFzRmllbGQobWVzc2FnZSwgRigiZGVmYXVsdF9ib29sIiAgICApKSk7CisgIEVYUEVDVF9GQUxTRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJkZWZhdWx0X3N0cmluZyIgICkpKTsKKyAgRVhQRUNUX0ZBTFNFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoImRlZmF1bHRfYnl0ZXMiICAgKSkpOworCisgIEVYUEVDVF9GQUxTRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJkZWZhdWx0X25lc3RlZF9lbnVtIiApKSk7CisgIEVYUEVDVF9GQUxTRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJkZWZhdWx0X2ZvcmVpZ25fZW51bSIpKSk7CisgIEVYUEVDVF9GQUxTRShyZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBGKCJkZWZhdWx0X2ltcG9ydF9lbnVtIiApKSk7CisKKyAgRVhQRUNUX0ZBTFNFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoImRlZmF1bHRfc3RyaW5nX3BpZWNlIikpKTsKKyAgRVhQRUNUX0ZBTFNFKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIEYoImRlZmF1bHRfY29yZCIpKSk7CisKKyAgLy8gRmllbGRzIHdpdGggZGVmYXVsdHMgaGF2ZSB0aGVpciBkZWZhdWx0IHZhbHVlcyAoZHVoKS4KKyAgRVhQRUNUX0VRKCA0MSAgICAsIHJlZmxlY3Rpb24tPkdldEludDMyIChtZXNzYWdlLCBGKCJkZWZhdWx0X2ludDMyIiAgICkpKTsKKyAgRVhQRUNUX0VRKCA0MiAgICAsIHJlZmxlY3Rpb24tPkdldEludDY0IChtZXNzYWdlLCBGKCJkZWZhdWx0X2ludDY0IiAgICkpKTsKKyAgRVhQRUNUX0VRKCA0MyAgICAsIHJlZmxlY3Rpb24tPkdldFVJbnQzMihtZXNzYWdlLCBGKCJkZWZhdWx0X3VpbnQzMiIgICkpKTsKKyAgRVhQRUNUX0VRKCA0NCAgICAsIHJlZmxlY3Rpb24tPkdldFVJbnQ2NChtZXNzYWdlLCBGKCJkZWZhdWx0X3VpbnQ2NCIgICkpKTsKKyAgRVhQRUNUX0VRKC00NSAgICAsIHJlZmxlY3Rpb24tPkdldEludDMyIChtZXNzYWdlLCBGKCJkZWZhdWx0X3NpbnQzMiIgICkpKTsKKyAgRVhQRUNUX0VRKCA0NiAgICAsIHJlZmxlY3Rpb24tPkdldEludDY0IChtZXNzYWdlLCBGKCJkZWZhdWx0X3NpbnQ2NCIgICkpKTsKKyAgRVhQRUNUX0VRKCA0NyAgICAsIHJlZmxlY3Rpb24tPkdldFVJbnQzMihtZXNzYWdlLCBGKCJkZWZhdWx0X2ZpeGVkMzIiICkpKTsKKyAgRVhQRUNUX0VRKCA0OCAgICAsIHJlZmxlY3Rpb24tPkdldFVJbnQ2NChtZXNzYWdlLCBGKCJkZWZhdWx0X2ZpeGVkNjQiICkpKTsKKyAgRVhQRUNUX0VRKCA0OSAgICAsIHJlZmxlY3Rpb24tPkdldEludDMyIChtZXNzYWdlLCBGKCJkZWZhdWx0X3NmaXhlZDMyIikpKTsKKyAgRVhQRUNUX0VRKC01MCAgICAsIHJlZmxlY3Rpb24tPkdldEludDY0IChtZXNzYWdlLCBGKCJkZWZhdWx0X3NmaXhlZDY0IikpKTsKKyAgRVhQRUNUX0VRKCA1MS41ICAsIHJlZmxlY3Rpb24tPkdldEZsb2F0IChtZXNzYWdlLCBGKCJkZWZhdWx0X2Zsb2F0IiAgICkpKTsKKyAgRVhQRUNUX0VRKCA1MmUzICAsIHJlZmxlY3Rpb24tPkdldERvdWJsZShtZXNzYWdlLCBGKCJkZWZhdWx0X2RvdWJsZSIgICkpKTsKKyAgRVhQRUNUX1RSVUUoICAgICAgIHJlZmxlY3Rpb24tPkdldEJvb2wgIChtZXNzYWdlLCBGKCJkZWZhdWx0X2Jvb2wiICAgICkpKTsKKyAgRVhQRUNUX0VRKCJoZWxsbyIsIHJlZmxlY3Rpb24tPkdldFN0cmluZyhtZXNzYWdlLCBGKCJkZWZhdWx0X3N0cmluZyIgICkpKTsKKyAgRVhQRUNUX0VRKCJ3b3JsZCIsIHJlZmxlY3Rpb24tPkdldFN0cmluZyhtZXNzYWdlLCBGKCJkZWZhdWx0X2J5dGVzIiAgICkpKTsKKworICBFWFBFQ1RfRVEoImhlbGxvIiwgcmVmbGVjdGlvbi0+R2V0U3RyaW5nUmVmZXJlbmNlKG1lc3NhZ2UsIEYoImRlZmF1bHRfc3RyaW5nIiksICZzY3JhdGNoKSk7CisgIEVYUEVDVF9FUSgid29ybGQiLCByZWZsZWN0aW9uLT5HZXRTdHJpbmdSZWZlcmVuY2UobWVzc2FnZSwgRigiZGVmYXVsdF9ieXRlcyIgKSwgJnNjcmF0Y2gpKTsKKworICBFWFBFQ1RfRVEoIG5lc3RlZF9iYXJfLCByZWZsZWN0aW9uLT5HZXRFbnVtKG1lc3NhZ2UsIEYoImRlZmF1bHRfbmVzdGVkX2VudW0iICkpKTsKKyAgRVhQRUNUX0VRKGZvcmVpZ25fYmFyXywgcmVmbGVjdGlvbi0+R2V0RW51bShtZXNzYWdlLCBGKCJkZWZhdWx0X2ZvcmVpZ25fZW51bSIpKSk7CisgIEVYUEVDVF9FUSggaW1wb3J0X2Jhcl8sIHJlZmxlY3Rpb24tPkdldEVudW0obWVzc2FnZSwgRigiZGVmYXVsdF9pbXBvcnRfZW51bSIgKSkpOworCisgIEVYUEVDVF9FUSgiYWJjIiwgcmVmbGVjdGlvbi0+R2V0U3RyaW5nKG1lc3NhZ2UsIEYoImRlZmF1bHRfc3RyaW5nX3BpZWNlIikpKTsKKyAgRVhQRUNUX0VRKCJhYmMiLCByZWZsZWN0aW9uLT5HZXRTdHJpbmdSZWZlcmVuY2UobWVzc2FnZSwgRigiZGVmYXVsdF9zdHJpbmdfcGllY2UiKSwgJnNjcmF0Y2gpKTsKKworICBFWFBFQ1RfRVEoIjEyMyIsIHJlZmxlY3Rpb24tPkdldFN0cmluZyhtZXNzYWdlLCBGKCJkZWZhdWx0X2NvcmQiKSkpOworICBFWFBFQ1RfRVEoIjEyMyIsIHJlZmxlY3Rpb24tPkdldFN0cmluZ1JlZmVyZW5jZShtZXNzYWdlLCBGKCJkZWZhdWx0X2NvcmQiKSwgJnNjcmF0Y2gpKTsKK30KKwordm9pZCBUZXN0VXRpbDo6UmVmbGVjdGlvblRlc3Rlcjo6RXhwZWN0UGFja2VkQ2xlYXJWaWFSZWZsZWN0aW9uKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UpIHsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpOworCisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicGFja2VkX2ludDMyIiAgICkpKTsKKyAgRVhQRUNUX0VRKDAsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJwYWNrZWRfaW50NjQiICAgKSkpOworICBFWFBFQ1RfRVEoMCwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInBhY2tlZF91aW50MzIiICApKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicGFja2VkX3VpbnQ2NCIgICkpKTsKKyAgRVhQRUNUX0VRKDAsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJwYWNrZWRfc2ludDMyIiAgKSkpOworICBFWFBFQ1RfRVEoMCwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInBhY2tlZF9zaW50NjQiICApKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicGFja2VkX2ZpeGVkMzIiICkpKTsKKyAgRVhQRUNUX0VRKDAsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJwYWNrZWRfZml4ZWQ2NCIgKSkpOworICBFWFBFQ1RfRVEoMCwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInBhY2tlZF9zZml4ZWQzMiIpKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicGFja2VkX3NmaXhlZDY0IikpKTsKKyAgRVhQRUNUX0VRKDAsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJwYWNrZWRfZmxvYXQiICAgKSkpOworICBFWFBFQ1RfRVEoMCwgcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIEYoInBhY2tlZF9kb3VibGUiICApKSk7CisgIEVYUEVDVF9FUSgwLCByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgRigicGFja2VkX2Jvb2wiICAgICkpKTsKKyAgRVhQRUNUX0VRKDAsIHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBGKCJwYWNrZWRfZW51bSIgICAgKSkpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3ZvaWQgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXI6Ok1vZGlmeVJlcGVhdGVkRmllbGRzVmlhUmVmbGVjdGlvbigKKyAgICBNZXNzYWdlKiBtZXNzYWdlKSB7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCk7CisgIE1lc3NhZ2UqIHN1Yl9tZXNzYWdlOworCisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkSW50MzIgKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2ludDMyIiAgICksIDEsIDUwMSk7CisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkSW50NjQgKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2ludDY0IiAgICksIDEsIDUwMik7CisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkVUludDMyKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3VpbnQzMiIgICksIDEsIDUwMyk7CisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkVUludDY0KG1lc3NhZ2UsIEYoInJlcGVhdGVkX3VpbnQ2NCIgICksIDEsIDUwNCk7CisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkSW50MzIgKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3NpbnQzMiIgICksIDEsIDUwNSk7CisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkSW50NjQgKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3NpbnQ2NCIgICksIDEsIDUwNik7CisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkVUludDMyKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2ZpeGVkMzIiICksIDEsIDUwNyk7CisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkVUludDY0KG1lc3NhZ2UsIEYoInJlcGVhdGVkX2ZpeGVkNjQiICksIDEsIDUwOCk7CisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkSW50MzIgKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3NmaXhlZDMyIiksIDEsIDUwOSk7CisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkSW50NjQgKG1lc3NhZ2UsIEYoInJlcGVhdGVkX3NmaXhlZDY0IiksIDEsIDUxMCk7CisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkRmxvYXQgKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2Zsb2F0IiAgICksIDEsIDUxMSk7CisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkRG91YmxlKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2RvdWJsZSIgICksIDEsIDUxMik7CisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkQm9vbCAgKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2Jvb2wiICAgICksIDEsIHRydWUpOworICByZWZsZWN0aW9uLT5TZXRSZXBlYXRlZFN0cmluZyhtZXNzYWdlLCBGKCJyZXBlYXRlZF9zdHJpbmciICApLCAxLCAiNTE1Iik7CisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkU3RyaW5nKG1lc3NhZ2UsIEYoInJlcGVhdGVkX2J5dGVzIiAgICksIDEsICI1MTYiKTsKKworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPk11dGFibGVSZXBlYXRlZE1lc3NhZ2UobWVzc2FnZSwgRigicmVwZWF0ZWRncm91cCIpLCAxKTsKKyAgc3ViX21lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKS0+U2V0SW50MzIoc3ViX21lc3NhZ2UsIHJlcGVhdGVkX2dyb3VwX2FfLCA1MTcpOworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPk11dGFibGVSZXBlYXRlZE1lc3NhZ2UobWVzc2FnZSwgRigicmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UiKSwgMSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlNldEludDMyKHN1Yl9tZXNzYWdlLCBuZXN0ZWRfYl8sIDUxOCk7CisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+TXV0YWJsZVJlcGVhdGVkTWVzc2FnZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UiKSwgMSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlNldEludDMyKHN1Yl9tZXNzYWdlLCBmb3JlaWduX2NfLCA1MTkpOworICBzdWJfbWVzc2FnZSA9IHJlZmxlY3Rpb24tPk11dGFibGVSZXBlYXRlZE1lc3NhZ2UobWVzc2FnZSwgRigicmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UiKSwgMSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlNldEludDMyKHN1Yl9tZXNzYWdlLCBpbXBvcnRfZF8sIDUyMCk7CisgIHN1Yl9tZXNzYWdlID0gcmVmbGVjdGlvbi0+TXV0YWJsZVJlcGVhdGVkTWVzc2FnZShtZXNzYWdlLCBGKCJyZXBlYXRlZF9sYXp5X21lc3NhZ2UiKSwgMSk7CisgIHN1Yl9tZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCktPlNldEludDMyKHN1Yl9tZXNzYWdlLCBuZXN0ZWRfYl8sIDUyNyk7CisKKyAgcmVmbGVjdGlvbi0+U2V0UmVwZWF0ZWRFbnVtKG1lc3NhZ2UsIEYoInJlcGVhdGVkX25lc3RlZF9lbnVtIiApLCAxLCAgbmVzdGVkX2Zvb18pOworICByZWZsZWN0aW9uLT5TZXRSZXBlYXRlZEVudW0obWVzc2FnZSwgRigicmVwZWF0ZWRfZm9yZWlnbl9lbnVtIiksIDEsIGZvcmVpZ25fZm9vXyk7CisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkRW51bShtZXNzYWdlLCBGKCJyZXBlYXRlZF9pbXBvcnRfZW51bSIgKSwgMSwgIGltcG9ydF9mb29fKTsKKworICByZWZsZWN0aW9uLT5TZXRSZXBlYXRlZFN0cmluZyhtZXNzYWdlLCBGKCJyZXBlYXRlZF9zdHJpbmdfcGllY2UiKSwgMSwgIjUyNCIpOworICByZWZsZWN0aW9uLT5TZXRSZXBlYXRlZFN0cmluZyhtZXNzYWdlLCBGKCJyZXBlYXRlZF9jb3JkIiksIDEsICI1MjUiKTsKK30KKwordm9pZCBUZXN0VXRpbDo6UmVmbGVjdGlvblRlc3Rlcjo6TW9kaWZ5UGFja2VkRmllbGRzVmlhUmVmbGVjdGlvbigKKyAgICBNZXNzYWdlKiBtZXNzYWdlKSB7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCk7CisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkSW50MzIgKG1lc3NhZ2UsIEYoInBhY2tlZF9pbnQzMiIgICApLCAxLCA4MDEpOworICByZWZsZWN0aW9uLT5TZXRSZXBlYXRlZEludDY0IChtZXNzYWdlLCBGKCJwYWNrZWRfaW50NjQiICAgKSwgMSwgODAyKTsKKyAgcmVmbGVjdGlvbi0+U2V0UmVwZWF0ZWRVSW50MzIobWVzc2FnZSwgRigicGFja2VkX3VpbnQzMiIgICksIDEsIDgwMyk7CisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkVUludDY0KG1lc3NhZ2UsIEYoInBhY2tlZF91aW50NjQiICApLCAxLCA4MDQpOworICByZWZsZWN0aW9uLT5TZXRSZXBlYXRlZEludDMyIChtZXNzYWdlLCBGKCJwYWNrZWRfc2ludDMyIiAgKSwgMSwgODA1KTsKKyAgcmVmbGVjdGlvbi0+U2V0UmVwZWF0ZWRJbnQ2NCAobWVzc2FnZSwgRigicGFja2VkX3NpbnQ2NCIgICksIDEsIDgwNik7CisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkVUludDMyKG1lc3NhZ2UsIEYoInBhY2tlZF9maXhlZDMyIiApLCAxLCA4MDcpOworICByZWZsZWN0aW9uLT5TZXRSZXBlYXRlZFVJbnQ2NChtZXNzYWdlLCBGKCJwYWNrZWRfZml4ZWQ2NCIgKSwgMSwgODA4KTsKKyAgcmVmbGVjdGlvbi0+U2V0UmVwZWF0ZWRJbnQzMiAobWVzc2FnZSwgRigicGFja2VkX3NmaXhlZDMyIiksIDEsIDgwOSk7CisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkSW50NjQgKG1lc3NhZ2UsIEYoInBhY2tlZF9zZml4ZWQ2NCIpLCAxLCA4MTApOworICByZWZsZWN0aW9uLT5TZXRSZXBlYXRlZEZsb2F0IChtZXNzYWdlLCBGKCJwYWNrZWRfZmxvYXQiICAgKSwgMSwgODExKTsKKyAgcmVmbGVjdGlvbi0+U2V0UmVwZWF0ZWREb3VibGUobWVzc2FnZSwgRigicGFja2VkX2RvdWJsZSIgICksIDEsIDgxMik7CisgIHJlZmxlY3Rpb24tPlNldFJlcGVhdGVkQm9vbCAgKG1lc3NhZ2UsIEYoInBhY2tlZF9ib29sIiAgICApLCAxLCB0cnVlKTsKKyAgcmVmbGVjdGlvbi0+U2V0UmVwZWF0ZWRFbnVtICAobWVzc2FnZSwgRigicGFja2VkX2VudW0iICAgICksIDEsIGZvcmVpZ25fZm9vXyk7Cit9CisKK3ZvaWQgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXI6OlJlbW92ZUxhc3RSZXBlYXRlZHNWaWFSZWZsZWN0aW9uKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UpIHsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKTsKKworICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4gb3V0cHV0OworICByZWZsZWN0aW9uLT5MaXN0RmllbGRzKCptZXNzYWdlLCAmb3V0cHV0KTsKKyAgZm9yIChpbnQgaT0wOyBpPG91dHB1dC5zaXplKCk7ICsraSkgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBvdXRwdXRbaV07CisgICAgaWYgKCFmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgY29udGludWU7CisKKyAgICByZWZsZWN0aW9uLT5SZW1vdmVMYXN0KG1lc3NhZ2UsIGZpZWxkKTsKKyAgfQorfQorCit2b2lkIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyOjpSZWxlYXNlTGFzdFJlcGVhdGVkc1ZpYVJlZmxlY3Rpb24oCisgICAgTWVzc2FnZSogbWVzc2FnZSwgYm9vbCBleHBlY3RfZXh0ZW5zaW9uc19ub3RudWxsKSB7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCk7CisKKyAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+IG91dHB1dDsKKyAgcmVmbGVjdGlvbi0+TGlzdEZpZWxkcygqbWVzc2FnZSwgJm91dHB1dCk7CisgIGZvciAoaW50IGk9MDsgaTxvdXRwdXQuc2l6ZSgpOyArK2kpIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gb3V0cHV0W2ldOworICAgIGlmICghZmllbGQtPmlzX3JlcGVhdGVkKCkpIGNvbnRpbnVlOworICAgIGlmIChmaWVsZC0+Y3BwX3R5cGUoKSAhPSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSkgY29udGludWU7CisKKyAgICBNZXNzYWdlKiByZWxlYXNlZCA9IHJlZmxlY3Rpb24tPlJlbGVhc2VMYXN0KG1lc3NhZ2UsIGZpZWxkKTsKKyAgICBpZiAoIWZpZWxkLT5pc19leHRlbnNpb24oKSB8fCBleHBlY3RfZXh0ZW5zaW9uc19ub3RudWxsKSB7CisgICAgICBBU1NFUlRfVFJVRShyZWxlYXNlZCAhPSBOVUxMKSA8PCAiUmVsZWFzZUxhc3QgcmV0dXJuZWQgTlVMTCBmb3I6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDw8IGZpZWxkLT5uYW1lKCk7CisgICAgfQorICAgIGRlbGV0ZSByZWxlYXNlZDsKKyAgfQorfQorCit2b2lkIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyOjpTd2FwUmVwZWF0ZWRzVmlhUmVmbGVjdGlvbihNZXNzYWdlKiBtZXNzYWdlKSB7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLT5HZXRSZWZsZWN0aW9uKCk7CisKKyAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+IG91dHB1dDsKKyAgcmVmbGVjdGlvbi0+TGlzdEZpZWxkcygqbWVzc2FnZSwgJm91dHB1dCk7CisgIGZvciAoaW50IGk9MDsgaTxvdXRwdXQuc2l6ZSgpOyArK2kpIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gb3V0cHV0W2ldOworICAgIGlmICghZmllbGQtPmlzX3JlcGVhdGVkKCkpIGNvbnRpbnVlOworCisgICAgcmVmbGVjdGlvbi0+U3dhcEVsZW1lbnRzKG1lc3NhZ2UsIGZpZWxkLCAwLCAxKTsKKyAgfQorfQorCit2b2lkIFRlc3RVdGlsOjpSZWZsZWN0aW9uVGVzdGVyOjoKK1NldEFsbG9jYXRlZE9wdGlvbmFsTWVzc2FnZUZpZWxkc1RvTnVsbFZpYVJlZmxlY3Rpb24oCisgICAgTWVzc2FnZSogbWVzc2FnZSkgeworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpOworCisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBmaWVsZHM7CisgIHJlZmxlY3Rpb24tPkxpc3RGaWVsZHMoKm1lc3NhZ2UsICZmaWVsZHMpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRzLnNpemUoKTsgKytpKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGZpZWxkc1tpXTsKKyAgICBpZiAoIWZpZWxkLT5pc19vcHRpb25hbCgpIHx8CisgICAgICAgIGZpZWxkLT5jcHBfdHlwZSgpICE9IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFKSBjb250aW51ZTsKKworICAgIHJlZmxlY3Rpb24tPlNldEFsbG9jYXRlZE1lc3NhZ2UobWVzc2FnZSwgTlVMTCwgZmllbGQpOworICB9Cit9CisKK3ZvaWQgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXI6OgorU2V0QWxsb2NhdGVkT3B0aW9uYWxNZXNzYWdlRmllbGRzVG9NZXNzYWdlVmlhUmVmbGVjdGlvbigKKyAgICBNZXNzYWdlKiBmcm9tX21lc3NhZ2UsCisgICAgTWVzc2FnZSogdG9fbWVzc2FnZSkgeworICBFWFBFQ1RfRVEoZnJvbV9tZXNzYWdlLT5HZXREZXNjcmlwdG9yKCksIHRvX21lc3NhZ2UtPkdldERlc2NyaXB0b3IoKSk7CisgIGNvbnN0IFJlZmxlY3Rpb24qIGZyb21fcmVmbGVjdGlvbiA9IGZyb21fbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpOworICBjb25zdCBSZWZsZWN0aW9uKiB0b19yZWZsZWN0aW9uID0gdG9fbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpOworCisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBmaWVsZHM7CisgIGZyb21fcmVmbGVjdGlvbi0+TGlzdEZpZWxkcygqZnJvbV9tZXNzYWdlLCAmZmllbGRzKTsKKworICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkcy5zaXplKCk7ICsraSkgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBmaWVsZHNbaV07CisgICAgaWYgKCFmaWVsZC0+aXNfb3B0aW9uYWwoKSB8fAorICAgICAgICBmaWVsZC0+Y3BwX3R5cGUoKSAhPSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSkgY29udGludWU7CisKKyAgICBNZXNzYWdlKiBzdWJfbWVzc2FnZSA9CisgICAgICAgIGZyb21fcmVmbGVjdGlvbi0+UmVsZWFzZU1lc3NhZ2UoZnJvbV9tZXNzYWdlLCBmaWVsZCk7CisgICAgdG9fcmVmbGVjdGlvbi0+U2V0QWxsb2NhdGVkTWVzc2FnZSh0b19tZXNzYWdlLCBzdWJfbWVzc2FnZSwgZmllbGQpOworICB9Cit9CisKK3ZvaWQgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXI6OkV4cGVjdE1lc3NhZ2VzUmVsZWFzZWRWaWFSZWZsZWN0aW9uKAorICAgIE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgVGVzdFV0aWw6OlJlZmxlY3Rpb25UZXN0ZXI6Ok1lc3NhZ2VSZWxlYXNlU3RhdGUgZXhwZWN0ZWRfcmVsZWFzZV9zdGF0ZSkgeworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpOworCisgIHN0YXRpYyBjb25zdCBjaGFyKiBmaWVsZHNbXSA9IHsKKyAgICAib3B0aW9uYWxncm91cCIsCisgICAgIm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlIiwKKyAgICAib3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlIiwKKyAgICAib3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UiLAorICB9OworICBmb3IgKGludCBpID0gMDsgaSA8IEdPT0dMRV9BUlJBWVNJWkUoZmllbGRzKTsgaSsrKSB7CisgICAgY29uc3QgTWVzc2FnZSYgc3ViX21lc3NhZ2UgPSByZWZsZWN0aW9uLT5HZXRNZXNzYWdlKCptZXNzYWdlLCBGKGZpZWxkc1tpXSkpOworICAgIE1lc3NhZ2UqIHJlbGVhc2VkID0gcmVmbGVjdGlvbi0+UmVsZWFzZU1lc3NhZ2UobWVzc2FnZSwgRihmaWVsZHNbaV0pKTsKKyAgICBzd2l0Y2ggKGV4cGVjdGVkX3JlbGVhc2Vfc3RhdGUpIHsKKyAgICAgIGNhc2UgSVNfTlVMTDoKKyAgICAgICAgRVhQRUNUX1RSVUUocmVsZWFzZWQgPT0gTlVMTCk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBOT1RfTlVMTDoKKyAgICAgICAgRVhQRUNUX1RSVUUocmVsZWFzZWQgIT0gTlVMTCk7CisgICAgICAgIEVYUEVDVF9FUSgmc3ViX21lc3NhZ2UsIHJlbGVhc2VkKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIENBTl9CRV9OVUxMOgorICAgICAgICBicmVhazsKKyAgICB9CisgICAgZGVsZXRlIHJlbGVhc2VkOworICAgIEVYUEVDVF9GQUxTRShyZWZsZWN0aW9uLT5IYXNGaWVsZCgqbWVzc2FnZSwgRihmaWVsZHNbaV0pKSk7CisgIH0KK30KKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RfdXRpbC5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0X3V0aWwuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xYzEzYTFhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0X3V0aWwuaApAQCAtMCwwICsxLDIxNSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9URVNUX1VUSUxfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9URVNUX1VUSUxfSF9fCisKKyNpbmNsdWRlIDxzdGFjaz4KKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21lc3NhZ2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucGIuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCituYW1lc3BhY2UgdW5pdHRlc3QgPSA6OnByb3RvYnVmX3VuaXR0ZXN0OworbmFtZXNwYWNlIHVuaXR0ZXN0X2ltcG9ydCA9IHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydDsKKworY2xhc3MgVGVzdFV0aWwgeworIHB1YmxpYzoKKyAgLy8gU2V0IGV2ZXJ5IGZpZWxkIGluIHRoZSBtZXNzYWdlIHRvIGEgdW5pcXVlIHZhbHVlLgorICBzdGF0aWMgdm9pZCBTZXRBbGxGaWVsZHModW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyogbWVzc2FnZSk7CisgIHN0YXRpYyB2b2lkIFNldE9wdGlvbmFsRmllbGRzKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMqIG1lc3NhZ2UpOworICBzdGF0aWMgdm9pZCBBZGRSZXBlYXRlZEZpZWxkczEodW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyogbWVzc2FnZSk7CisgIHN0YXRpYyB2b2lkIEFkZFJlcGVhdGVkRmllbGRzMih1bml0dGVzdDo6VGVzdEFsbFR5cGVzKiBtZXNzYWdlKTsKKyAgc3RhdGljIHZvaWQgU2V0RGVmYXVsdEZpZWxkcyh1bml0dGVzdDo6VGVzdEFsbFR5cGVzKiBtZXNzYWdlKTsKKyAgc3RhdGljIHZvaWQgU2V0T25lb2ZGaWVsZHModW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyogbWVzc2FnZSk7CisgIHN0YXRpYyB2b2lkIFNldEFsbEV4dGVuc2lvbnModW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zKiBtZXNzYWdlKTsKKyAgc3RhdGljIHZvaWQgU2V0T25lb2ZGaWVsZHModW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zKiBtZXNzYWdlKTsKKyAgc3RhdGljIHZvaWQgU2V0QWxsRmllbGRzQW5kRXh0ZW5zaW9ucyh1bml0dGVzdDo6VGVzdEZpZWxkT3JkZXJpbmdzKiBtZXNzYWdlKTsKKyAgc3RhdGljIHZvaWQgU2V0UGFja2VkRmllbGRzKHVuaXR0ZXN0OjpUZXN0UGFja2VkVHlwZXMqIG1lc3NhZ2UpOworICBzdGF0aWMgdm9pZCBTZXRQYWNrZWRFeHRlbnNpb25zKHVuaXR0ZXN0OjpUZXN0UGFja2VkRXh0ZW5zaW9ucyogbWVzc2FnZSk7CisgIHN0YXRpYyB2b2lkIFNldFVucGFja2VkRmllbGRzKHVuaXR0ZXN0OjpUZXN0VW5wYWNrZWRUeXBlcyogbWVzc2FnZSk7CisgIHN0YXRpYyB2b2lkIFNldE9uZW9mMSh1bml0dGVzdDo6VGVzdE9uZW9mMiogbWVzc2FnZSk7CisgIHN0YXRpYyB2b2lkIFNldE9uZW9mMih1bml0dGVzdDo6VGVzdE9uZW9mMiogbWVzc2FnZSk7CisKKyAgLy8gVXNlIHRoZSByZXBlYXRlZCB2ZXJzaW9ucyBvZiB0aGUgc2V0XyooKSBhY2Nlc3NvcnMgdG8gbW9kaWZ5IGFsbCB0aGUKKyAgLy8gcmVwZWF0ZWQgZmllbGRzIG9mIHRoZSBtZXNzYWdlICh3aGljaCBzaG91bGQgYWxyZWFkeSBoYXZlIGJlZW4KKyAgLy8gaW5pdGlhbGl6ZWQgd2l0aCBTZXQqRmllbGRzKCkpLiAgU2V0KkZpZWxkcygpIGl0c2VsZiBvbmx5IHRlc3RzCisgIC8vIHRoZSBhZGRfKigpIGFjY2Vzc29ycy4KKyAgc3RhdGljIHZvaWQgTW9kaWZ5UmVwZWF0ZWRGaWVsZHModW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyogbWVzc2FnZSk7CisgIHN0YXRpYyB2b2lkIE1vZGlmeVJlcGVhdGVkRXh0ZW5zaW9ucyh1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMqIG1lc3NhZ2UpOworICBzdGF0aWMgdm9pZCBNb2RpZnlQYWNrZWRGaWVsZHModW5pdHRlc3Q6OlRlc3RQYWNrZWRUeXBlcyogbWVzc2FnZSk7CisgIHN0YXRpYyB2b2lkIE1vZGlmeVBhY2tlZEV4dGVuc2lvbnModW5pdHRlc3Q6OlRlc3RQYWNrZWRFeHRlbnNpb25zKiBtZXNzYWdlKTsKKworICAvLyBDaGVjayB0aGF0IGFsbCBmaWVsZHMgaGF2ZSB0aGUgdmFsdWVzIHRoYXQgdGhleSBzaG91bGQgaGF2ZSBhZnRlcgorICAvLyBTZXQqRmllbGRzKCkgaXMgY2FsbGVkLgorICBzdGF0aWMgdm9pZCBFeHBlY3RBbGxGaWVsZHNTZXQoY29uc3QgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyYgbWVzc2FnZSk7CisgIHN0YXRpYyB2b2lkIEV4cGVjdEFsbEV4dGVuc2lvbnNTZXQoCisgICAgICBjb25zdCB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMmIG1lc3NhZ2UpOworICBzdGF0aWMgdm9pZCBFeHBlY3RQYWNrZWRGaWVsZHNTZXQoY29uc3QgdW5pdHRlc3Q6OlRlc3RQYWNrZWRUeXBlcyYgbWVzc2FnZSk7CisgIHN0YXRpYyB2b2lkIEV4cGVjdFBhY2tlZEV4dGVuc2lvbnNTZXQoCisgICAgICBjb25zdCB1bml0dGVzdDo6VGVzdFBhY2tlZEV4dGVuc2lvbnMmIG1lc3NhZ2UpOworICBzdGF0aWMgdm9pZCBFeHBlY3RVbnBhY2tlZEZpZWxkc1NldCgKKyAgICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0VW5wYWNrZWRUeXBlcyYgbWVzc2FnZSk7CisgIHN0YXRpYyB2b2lkIEV4cGVjdFVucGFja2VkRXh0ZW5zaW9uc1NldCgKKyAgICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0VW5wYWNrZWRFeHRlbnNpb25zJiBtZXNzYWdlKTsKKyAgc3RhdGljIHZvaWQgRXhwZWN0T25lb2ZTZXQxKGNvbnN0IHVuaXR0ZXN0OjpUZXN0T25lb2YyJiBtZXNzYWdlKTsKKyAgc3RhdGljIHZvaWQgRXhwZWN0T25lb2ZTZXQyKGNvbnN0IHVuaXR0ZXN0OjpUZXN0T25lb2YyJiBtZXNzYWdlKTsKKworICAvLyBFeHBlY3QgdGhhdCB0aGUgbWVzc2FnZSBpcyBtb2RpZmllZCBhcyB3b3VsZCBiZSBleHBlY3RlZCBmcm9tCisgIC8vIE1vZGlmeSpGaWVsZHMoKS4KKyAgc3RhdGljIHZvaWQgRXhwZWN0UmVwZWF0ZWRGaWVsZHNNb2RpZmllZCgKKyAgICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMmIG1lc3NhZ2UpOworICBzdGF0aWMgdm9pZCBFeHBlY3RSZXBlYXRlZEV4dGVuc2lvbnNNb2RpZmllZCgKKyAgICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyYgbWVzc2FnZSk7CisgIHN0YXRpYyB2b2lkIEV4cGVjdFBhY2tlZEZpZWxkc01vZGlmaWVkKAorICAgICAgY29uc3QgdW5pdHRlc3Q6OlRlc3RQYWNrZWRUeXBlcyYgbWVzc2FnZSk7CisgIHN0YXRpYyB2b2lkIEV4cGVjdFBhY2tlZEV4dGVuc2lvbnNNb2RpZmllZCgKKyAgICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0UGFja2VkRXh0ZW5zaW9ucyYgbWVzc2FnZSk7CisKKyAgLy8gQ2hlY2sgdGhhdCBhbGwgZmllbGRzIGhhdmUgdGhlaXIgZGVmYXVsdCB2YWx1ZXMuCisgIHN0YXRpYyB2b2lkIEV4cGVjdENsZWFyKGNvbnN0IHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMmIG1lc3NhZ2UpOworICBzdGF0aWMgdm9pZCBFeHBlY3RFeHRlbnNpb25zQ2xlYXIoY29uc3QgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zJiBtZXNzYWdlKTsKKyAgc3RhdGljIHZvaWQgRXhwZWN0UGFja2VkQ2xlYXIoY29uc3QgdW5pdHRlc3Q6OlRlc3RQYWNrZWRUeXBlcyYgbWVzc2FnZSk7CisgIHN0YXRpYyB2b2lkIEV4cGVjdFBhY2tlZEV4dGVuc2lvbnNDbGVhcigKKyAgICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0UGFja2VkRXh0ZW5zaW9ucyYgbWVzc2FnZSk7CisgIHN0YXRpYyB2b2lkIEV4cGVjdE9uZW9mQ2xlYXIoY29uc3QgdW5pdHRlc3Q6OlRlc3RPbmVvZjImIG1lc3NhZ2UpOworCisgIC8vIENoZWNrIHRoYXQgdGhlIHBhc3NlZC1pbiBzZXJpYWxpemF0aW9uIGlzIHRoZSBjYW5vbmljYWwgc2VyaWFsaXphdGlvbiB3ZQorICAvLyBleHBlY3QgZm9yIGEgVGVzdEZpZWxkT3JkZXJpbmdzIG1lc3NhZ2UgZmlsbGVkIGluIGJ5CisgIC8vIFNldEFsbEZpZWxkc0FuZEV4dGVuc2lvbnMoKS4KKyAgc3RhdGljIHZvaWQgRXhwZWN0QWxsRmllbGRzQW5kRXh0ZW5zaW9uc0luT3JkZXIoY29uc3Qgc3RyaW5nJiBzZXJpYWxpemVkKTsKKworICAvLyBDaGVjayB0aGF0IGFsbCByZXBlYXRlZCBmaWVsZHMgaGF2ZSBoYWQgdGhlaXIgbGFzdCBlbGVtZW50cyByZW1vdmVkLgorICBzdGF0aWMgdm9pZCBFeHBlY3RMYXN0UmVwZWF0ZWRzUmVtb3ZlZCgKKyAgICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMmIG1lc3NhZ2UpOworICBzdGF0aWMgdm9pZCBFeHBlY3RMYXN0UmVwZWF0ZWRFeHRlbnNpb25zUmVtb3ZlZCgKKyAgICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyYgbWVzc2FnZSk7CisgIHN0YXRpYyB2b2lkIEV4cGVjdExhc3RSZXBlYXRlZHNSZWxlYXNlZCgKKyAgICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMmIG1lc3NhZ2UpOworICBzdGF0aWMgdm9pZCBFeHBlY3RMYXN0UmVwZWF0ZWRFeHRlbnNpb25zUmVsZWFzZWQoCisgICAgICBjb25zdCB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMmIG1lc3NhZ2UpOworCisgIC8vIENoZWNrIHRoYXQgYWxsIHJlcGVhdGVkIGZpZWxkcyBoYXZlIGhhZCB0aGVpciBmaXJzdCBhbmQgbGFzdCBlbGVtZW50cworICAvLyBzd2FwcGVkLgorICBzdGF0aWMgdm9pZCBFeHBlY3RSZXBlYXRlZHNTd2FwcGVkKGNvbnN0IHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMmIG1lc3NhZ2UpOworICBzdGF0aWMgdm9pZCBFeHBlY3RSZXBlYXRlZEV4dGVuc2lvbnNTd2FwcGVkKAorICAgICAgY29uc3QgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zJiBtZXNzYWdlKTsKKworICBzdGF0aWMgdm9pZCBFeHBlY3RBdE1vc3RPbmVGaWVsZFNldEluT25lb2YoCisgICAgICBjb25zdCB1bml0dGVzdDo6VGVzdE9uZW9mMiAmbWVzc2FnZSk7CisKKyAgLy8gTGlrZSBhYm92ZSwgYnV0IHVzZSB0aGUgcmVmbGVjdGlvbiBpbnRlcmZhY2UuCisgIGNsYXNzIFJlZmxlY3Rpb25UZXN0ZXIgeworICAgcHVibGljOgorICAgIC8vIGJhc2VfZGVzY3JpcHRvciBtdXN0IGJlIGEgZGVzY3JpcHRvciBmb3IgVGVzdEFsbFR5cGVzIG9yCisgICAgLy8gVGVzdEFsbEV4dGVuc2lvbnMuICBJbiB0aGUgZm9ybWVyIGNhc2UsIFJlZmxlY3Rpb25UZXN0ZXIgZmV0Y2hlcyBmcm9tCisgICAgLy8gaXQgdGhlIEZpZWxkRGVzY3JpcHRvcnMgbmVlZGVkIHRvIHVzZSB0aGUgcmVmbGVjdGlvbiBpbnRlcmZhY2UuICBJbgorICAgIC8vIHRoZSBsYXR0ZXIgY2FzZSwgUmVmbGVjdGlvblRlc3RlciBzZWFyY2hlcyBmb3IgZXh0ZW5zaW9uIGZpZWxkcyBpbgorICAgIC8vIGl0cyBmaWxlLgorICAgIGV4cGxpY2l0IFJlZmxlY3Rpb25UZXN0ZXIoY29uc3QgRGVzY3JpcHRvciogYmFzZV9kZXNjcmlwdG9yKTsKKworICAgIHZvaWQgU2V0QWxsRmllbGRzVmlhUmVmbGVjdGlvbihNZXNzYWdlKiBtZXNzYWdlKTsKKyAgICB2b2lkIE1vZGlmeVJlcGVhdGVkRmllbGRzVmlhUmVmbGVjdGlvbihNZXNzYWdlKiBtZXNzYWdlKTsKKyAgICB2b2lkIEV4cGVjdEFsbEZpZWxkc1NldFZpYVJlZmxlY3Rpb24oY29uc3QgTWVzc2FnZSYgbWVzc2FnZSk7CisgICAgdm9pZCBFeHBlY3RDbGVhclZpYVJlZmxlY3Rpb24oY29uc3QgTWVzc2FnZSYgbWVzc2FnZSk7CisKKyAgICB2b2lkIFNldFBhY2tlZEZpZWxkc1ZpYVJlZmxlY3Rpb24oTWVzc2FnZSogbWVzc2FnZSk7CisgICAgdm9pZCBNb2RpZnlQYWNrZWRGaWVsZHNWaWFSZWZsZWN0aW9uKE1lc3NhZ2UqIG1lc3NhZ2UpOworICAgIHZvaWQgRXhwZWN0UGFja2VkRmllbGRzU2V0VmlhUmVmbGVjdGlvbihjb25zdCBNZXNzYWdlJiBtZXNzYWdlKTsKKyAgICB2b2lkIEV4cGVjdFBhY2tlZENsZWFyVmlhUmVmbGVjdGlvbihjb25zdCBNZXNzYWdlJiBtZXNzYWdlKTsKKworICAgIHZvaWQgUmVtb3ZlTGFzdFJlcGVhdGVkc1ZpYVJlZmxlY3Rpb24oTWVzc2FnZSogbWVzc2FnZSk7CisgICAgdm9pZCBSZWxlYXNlTGFzdFJlcGVhdGVkc1ZpYVJlZmxlY3Rpb24oCisgICAgICAgIE1lc3NhZ2UqIG1lc3NhZ2UsIGJvb2wgZXhwZWN0X2V4dGVuc2lvbnNfbm90bnVsbCk7CisgICAgdm9pZCBTd2FwUmVwZWF0ZWRzVmlhUmVmbGVjdGlvbihNZXNzYWdlKiBtZXNzYWdlKTsKKyAgICB2b2lkIFNldEFsbG9jYXRlZE9wdGlvbmFsTWVzc2FnZUZpZWxkc1RvTnVsbFZpYVJlZmxlY3Rpb24oCisgICAgICAgIE1lc3NhZ2UqIG1lc3NhZ2UpOworICAgIHN0YXRpYyB2b2lkIFNldEFsbG9jYXRlZE9wdGlvbmFsTWVzc2FnZUZpZWxkc1RvTWVzc2FnZVZpYVJlZmxlY3Rpb24oCisgICAgICAgIE1lc3NhZ2UqIGZyb21fbWVzc2FnZSwKKyAgICAgICAgTWVzc2FnZSogdG9fbWVzc2FnZSk7CisKKyAgICBlbnVtIE1lc3NhZ2VSZWxlYXNlU3RhdGUgeworICAgICAgSVNfTlVMTCwKKyAgICAgIENBTl9CRV9OVUxMLAorICAgICAgTk9UX05VTEwsCisgICAgfTsKKyAgICB2b2lkIEV4cGVjdE1lc3NhZ2VzUmVsZWFzZWRWaWFSZWZsZWN0aW9uKAorICAgICAgICBNZXNzYWdlKiBtZXNzYWdlLCBNZXNzYWdlUmVsZWFzZVN0YXRlIGV4cGVjdGVkX3JlbGVhc2Vfc3RhdGUpOworCisgICAgLy8gU2V0IGFuZCBjaGVjayBmdW5jdGlvbnMgZm9yIFRlc3RPbmVvZjIgbWVzc2FnZXMuIE5vIG5lZWQgdG8gY29uc3RydWN0CisgICAgLy8gdGhlIFJlZmxlY3Rpb25UZXN0ZXIgYnkgVGVzdEFsbFR5cGVzIG5vciBUZXN0QWxsRXh0ZW5zaW9ucy4KKyAgICBzdGF0aWMgdm9pZCBTZXRPbmVvZlZpYVJlZmxlY3Rpb24oTWVzc2FnZSogbWVzc2FnZSk7CisgICAgc3RhdGljIHZvaWQgRXhwZWN0T25lb2ZTZXRWaWFSZWZsZWN0aW9uKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UpOworCisgICBwcml2YXRlOgorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogRihjb25zdCBzdHJpbmcmIG5hbWUpOworCisgICAgY29uc3QgRGVzY3JpcHRvciogYmFzZV9kZXNjcmlwdG9yXzsKKworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZ3JvdXBfYV87CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiByZXBlYXRlZF9ncm91cF9hXzsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIG5lc3RlZF9iXzsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZvcmVpZ25fY187CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBpbXBvcnRfZF87CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBpbXBvcnRfZV87CisKKyAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBuZXN0ZWRfZm9vXzsKKyAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBuZXN0ZWRfYmFyXzsKKyAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBuZXN0ZWRfYmF6XzsKKyAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBmb3JlaWduX2Zvb187CisgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogZm9yZWlnbl9iYXJfOworICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIGZvcmVpZ25fYmF6XzsKKyAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBpbXBvcnRfZm9vXzsKKyAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBpbXBvcnRfYmFyXzsKKyAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBpbXBvcnRfYmF6XzsKKworICAgIC8vIFdlIGhhdmUgdG8gc3BsaXQgdGhpcyBpbnRvIHRocmVlIGZ1bmN0aW9uIG90aGVyd2lzZSBpdCBjcmVhdGVzIGEgc3RhY2sKKyAgICAvLyBmcmFtZSBzbyBsYXJnZSB0aGF0IGl0IHRyaWdnZXJzIGEgd2FybmluZy4KKyAgICB2b2lkIEV4cGVjdEFsbEZpZWxkc1NldFZpYVJlZmxlY3Rpb24xKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UpOworICAgIHZvaWQgRXhwZWN0QWxsRmllbGRzU2V0VmlhUmVmbGVjdGlvbjIoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSk7CisgICAgdm9pZCBFeHBlY3RBbGxGaWVsZHNTZXRWaWFSZWZsZWN0aW9uMyhjb25zdCBNZXNzYWdlJiBtZXNzYWdlKTsKKworICAgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhSZWZsZWN0aW9uVGVzdGVyKTsKKyAgfTsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhUZXN0VXRpbCk7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfVEVTVF9VVElMX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0X3V0aWxfbGl0ZS5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdF91dGlsX2xpdGUuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzg4YzBjYgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdF91dGlsX2xpdGUuY2MKQEAgLTAsMCArMSwxNTg2IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdF91dGlsX2xpdGUuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbG9nZ2luZy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKworCisjZGVmaW5lIEVYUEVDVF9UUlVFIEdPT0dMRV9DSEVDSworI2RlZmluZSBBU1NFUlRfVFJVRSBHT09HTEVfQ0hFQ0sKKyNkZWZpbmUgRVhQRUNUX0ZBTFNFKENPTkQpIEdPT0dMRV9DSEVDSyghKENPTkQpKQorI2RlZmluZSBFWFBFQ1RfRVEgR09PR0xFX0NIRUNLX0VRCisjZGVmaW5lIEFTU0VSVF9FUSBHT09HTEVfQ0hFQ0tfRVEKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCit2b2lkIFRlc3RVdGlsTGl0ZTo6U2V0QWxsRmllbGRzKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlKiBtZXNzYWdlKSB7CisgIG1lc3NhZ2UtPnNldF9vcHRpb25hbF9pbnQzMiAgICgxMDEpOworICBtZXNzYWdlLT5zZXRfb3B0aW9uYWxfaW50NjQgICAoMTAyKTsKKyAgbWVzc2FnZS0+c2V0X29wdGlvbmFsX3VpbnQzMiAgKDEwMyk7CisgIG1lc3NhZ2UtPnNldF9vcHRpb25hbF91aW50NjQgICgxMDQpOworICBtZXNzYWdlLT5zZXRfb3B0aW9uYWxfc2ludDMyICAoMTA1KTsKKyAgbWVzc2FnZS0+c2V0X29wdGlvbmFsX3NpbnQ2NCAgKDEwNik7CisgIG1lc3NhZ2UtPnNldF9vcHRpb25hbF9maXhlZDMyICgxMDcpOworICBtZXNzYWdlLT5zZXRfb3B0aW9uYWxfZml4ZWQ2NCAoMTA4KTsKKyAgbWVzc2FnZS0+c2V0X29wdGlvbmFsX3NmaXhlZDMyKDEwOSk7CisgIG1lc3NhZ2UtPnNldF9vcHRpb25hbF9zZml4ZWQ2NCgxMTApOworICBtZXNzYWdlLT5zZXRfb3B0aW9uYWxfZmxvYXQgICAoMTExKTsKKyAgbWVzc2FnZS0+c2V0X29wdGlvbmFsX2RvdWJsZSAgKDExMik7CisgIG1lc3NhZ2UtPnNldF9vcHRpb25hbF9ib29sICAgICh0cnVlKTsKKyAgbWVzc2FnZS0+c2V0X29wdGlvbmFsX3N0cmluZyAgKCIxMTUiKTsKKyAgbWVzc2FnZS0+c2V0X29wdGlvbmFsX2J5dGVzICAgKCIxMTYiKTsKKworICBtZXNzYWdlLT5tdXRhYmxlX29wdGlvbmFsZ3JvdXAgICAgICAgICAgICAgICAgICgpLT5zZXRfYSgxMTcpOworICBtZXNzYWdlLT5tdXRhYmxlX29wdGlvbmFsX25lc3RlZF9tZXNzYWdlICAgICAgICgpLT5zZXRfYmIoMTE4KTsKKyAgbWVzc2FnZS0+bXV0YWJsZV9vcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgICAgICAoKS0+c2V0X2MoMTE5KTsKKyAgbWVzc2FnZS0+bXV0YWJsZV9vcHRpb25hbF9pbXBvcnRfbWVzc2FnZSAgICAgICAoKS0+c2V0X2QoMTIwKTsKKyAgbWVzc2FnZS0+bXV0YWJsZV9vcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UoKS0+c2V0X2UoMTI2KTsKKyAgbWVzc2FnZS0+bXV0YWJsZV9vcHRpb25hbF9sYXp5X21lc3NhZ2UgICAgICAgICAoKS0+c2V0X2JiKDEyNyk7CisKKyAgbWVzc2FnZS0+c2V0X29wdGlvbmFsX25lc3RlZF9lbnVtICh1bml0dGVzdDo6VGVzdEFsbFR5cGVzTGl0ZTo6QkFaICk7CisgIG1lc3NhZ2UtPnNldF9vcHRpb25hbF9mb3JlaWduX2VudW0odW5pdHRlc3Q6OkZPUkVJR05fTElURV9CQVogICAgICApOworICBtZXNzYWdlLT5zZXRfb3B0aW9uYWxfaW1wb3J0X2VudW0gKHVuaXR0ZXN0X2ltcG9ydDo6SU1QT1JUX0xJVEVfQkFaKTsKKworCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2ludDMyICAgKDIwMSk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9pbnQ2NCAgICgyMDIpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfdWludDMyICAoMjAzKTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX3VpbnQ2NCAgKDIwNCk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9zaW50MzIgICgyMDUpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfc2ludDY0ICAoMjA2KTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2ZpeGVkMzIgKDIwNyk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9maXhlZDY0ICgyMDgpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfc2ZpeGVkMzIoMjA5KTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX3NmaXhlZDY0KDIxMCk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9mbG9hdCAgICgyMTEpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfZG91YmxlICAoMjEyKTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2Jvb2wgICAgKHRydWUpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfc3RyaW5nICAoIjIxNSIpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfYnl0ZXMgICAoIjIxNiIpOworCisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZGdyb3VwICAgICAgICAgICAoKS0+c2V0X2EoMjE3KTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX25lc3RlZF9tZXNzYWdlICgpLT5zZXRfYmIoMjE4KTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSgpLT5zZXRfYygyMTkpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgKCktPnNldF9kKDIyMCk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9sYXp5X21lc3NhZ2UgICAoKS0+c2V0X2JiKDIyNyk7CisKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX25lc3RlZF9lbnVtICh1bml0dGVzdDo6VGVzdEFsbFR5cGVzTGl0ZTo6QkFSICk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9mb3JlaWduX2VudW0odW5pdHRlc3Q6OkZPUkVJR05fTElURV9CQVIgICAgICApOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfaW1wb3J0X2VudW0gKHVuaXR0ZXN0X2ltcG9ydDo6SU1QT1JUX0xJVEVfQkFSKTsKKworCisgIC8vIEFkZCBhIHNlY29uZCBvbmUgb2YgZWFjaCBmaWVsZC4KKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2ludDMyICAgKDMwMSk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9pbnQ2NCAgICgzMDIpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfdWludDMyICAoMzAzKTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX3VpbnQ2NCAgKDMwNCk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9zaW50MzIgICgzMDUpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfc2ludDY0ICAoMzA2KTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2ZpeGVkMzIgKDMwNyk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9maXhlZDY0ICgzMDgpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfc2ZpeGVkMzIoMzA5KTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX3NmaXhlZDY0KDMxMCk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9mbG9hdCAgICgzMTEpOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfZG91YmxlICAoMzEyKTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2Jvb2wgICAgKGZhbHNlKTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX3N0cmluZyAgKCIzMTUiKTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2J5dGVzICAgKCIzMTYiKTsKKworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRncm91cCAgICAgICAgICAgKCktPnNldF9hKDMxNyk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSAoKS0+c2V0X2JiKDMxOCk7CisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UoKS0+c2V0X2MoMzE5KTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2ltcG9ydF9tZXNzYWdlICgpLT5zZXRfZCgzMjApOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfbGF6eV9tZXNzYWdlICAgKCktPnNldF9iYigzMjcpOworCisgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9uZXN0ZWRfZW51bSAodW5pdHRlc3Q6OlRlc3RBbGxUeXBlc0xpdGU6OkJBWiApOworICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfZm9yZWlnbl9lbnVtKHVuaXR0ZXN0OjpGT1JFSUdOX0xJVEVfQkFaICAgICAgKTsKKyAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX2ltcG9ydF9lbnVtICh1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9MSVRFX0JBWik7CisKKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X2ludDMyICAgKDQwMSk7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X2ludDY0ICAgKDQwMik7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X3VpbnQzMiAgKDQwMyk7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X3VpbnQ2NCAgKDQwNCk7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X3NpbnQzMiAgKDQwNSk7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X3NpbnQ2NCAgKDQwNik7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X2ZpeGVkMzIgKDQwNyk7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X2ZpeGVkNjQgKDQwOCk7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X3NmaXhlZDMyKDQwOSk7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X3NmaXhlZDY0KDQxMCk7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X2Zsb2F0ICAgKDQxMSk7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X2RvdWJsZSAgKDQxMik7CisgIG1lc3NhZ2UtPnNldF9kZWZhdWx0X2Jvb2wgICAgKGZhbHNlKTsKKyAgbWVzc2FnZS0+c2V0X2RlZmF1bHRfc3RyaW5nICAoIjQxNSIpOworICBtZXNzYWdlLT5zZXRfZGVmYXVsdF9ieXRlcyAgICgiNDE2Iik7CisKKyAgbWVzc2FnZS0+c2V0X2RlZmF1bHRfbmVzdGVkX2VudW0gKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlOjpGT08gKTsKKyAgbWVzc2FnZS0+c2V0X2RlZmF1bHRfZm9yZWlnbl9lbnVtKHVuaXR0ZXN0OjpGT1JFSUdOX0xJVEVfRk9PICAgICAgKTsKKyAgbWVzc2FnZS0+c2V0X2RlZmF1bHRfaW1wb3J0X2VudW0gKHVuaXR0ZXN0X2ltcG9ydDo6SU1QT1JUX0xJVEVfRk9PKTsKKworCisgIG1lc3NhZ2UtPnNldF9vbmVvZl91aW50MzIoNjAxKTsKKyAgbWVzc2FnZS0+bXV0YWJsZV9vbmVvZl9uZXN0ZWRfbWVzc2FnZSgpLT5zZXRfYmIoNjAyKTsKKyAgbWVzc2FnZS0+c2V0X29uZW9mX3N0cmluZygiNjAzIik7CisgIG1lc3NhZ2UtPnNldF9vbmVvZl9ieXRlcygiNjA0Iik7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBUZXN0VXRpbExpdGU6Ok1vZGlmeVJlcGVhdGVkRmllbGRzKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlKiBtZXNzYWdlKSB7CisgIG1lc3NhZ2UtPnNldF9yZXBlYXRlZF9pbnQzMiAgICgxLCA1MDEpOworICBtZXNzYWdlLT5zZXRfcmVwZWF0ZWRfaW50NjQgICAoMSwgNTAyKTsKKyAgbWVzc2FnZS0+c2V0X3JlcGVhdGVkX3VpbnQzMiAgKDEsIDUwMyk7CisgIG1lc3NhZ2UtPnNldF9yZXBlYXRlZF91aW50NjQgICgxLCA1MDQpOworICBtZXNzYWdlLT5zZXRfcmVwZWF0ZWRfc2ludDMyICAoMSwgNTA1KTsKKyAgbWVzc2FnZS0+c2V0X3JlcGVhdGVkX3NpbnQ2NCAgKDEsIDUwNik7CisgIG1lc3NhZ2UtPnNldF9yZXBlYXRlZF9maXhlZDMyICgxLCA1MDcpOworICBtZXNzYWdlLT5zZXRfcmVwZWF0ZWRfZml4ZWQ2NCAoMSwgNTA4KTsKKyAgbWVzc2FnZS0+c2V0X3JlcGVhdGVkX3NmaXhlZDMyKDEsIDUwOSk7CisgIG1lc3NhZ2UtPnNldF9yZXBlYXRlZF9zZml4ZWQ2NCgxLCA1MTApOworICBtZXNzYWdlLT5zZXRfcmVwZWF0ZWRfZmxvYXQgICAoMSwgNTExKTsKKyAgbWVzc2FnZS0+c2V0X3JlcGVhdGVkX2RvdWJsZSAgKDEsIDUxMik7CisgIG1lc3NhZ2UtPnNldF9yZXBlYXRlZF9ib29sICAgICgxLCB0cnVlKTsKKyAgbWVzc2FnZS0+c2V0X3JlcGVhdGVkX3N0cmluZyAgKDEsICI1MTUiKTsKKyAgbWVzc2FnZS0+c2V0X3JlcGVhdGVkX2J5dGVzICAgKDEsICI1MTYiKTsKKworICBtZXNzYWdlLT5tdXRhYmxlX3JlcGVhdGVkZ3JvdXAgICAgICAgICAgICgxKS0+c2V0X2EoNTE3KTsKKyAgbWVzc2FnZS0+bXV0YWJsZV9yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSAoMSktPnNldF9iYig1MTgpOworICBtZXNzYWdlLT5tdXRhYmxlX3JlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSgxKS0+c2V0X2MoNTE5KTsKKyAgbWVzc2FnZS0+bXV0YWJsZV9yZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSAoMSktPnNldF9kKDUyMCk7CisgIG1lc3NhZ2UtPm11dGFibGVfcmVwZWF0ZWRfbGF6eV9tZXNzYWdlICAgKDEpLT5zZXRfYmIoNTI3KTsKKworICBtZXNzYWdlLT5zZXRfcmVwZWF0ZWRfbmVzdGVkX2VudW0gKDEsIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlOjpGT08gKTsKKyAgbWVzc2FnZS0+c2V0X3JlcGVhdGVkX2ZvcmVpZ25fZW51bSgxLCB1bml0dGVzdDo6Rk9SRUlHTl9MSVRFX0ZPTyAgICAgICk7CisgIG1lc3NhZ2UtPnNldF9yZXBlYXRlZF9pbXBvcnRfZW51bSAoMSwgdW5pdHRlc3RfaW1wb3J0OjpJTVBPUlRfTElURV9GT08pOworCit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBUZXN0VXRpbExpdGU6OkV4cGVjdEFsbEZpZWxkc1NldCgKKyAgICBjb25zdCB1bml0dGVzdDo6VGVzdEFsbFR5cGVzTGl0ZSYgbWVzc2FnZSkgeworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vcHRpb25hbF9pbnQzMiAgICgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfb3B0aW9uYWxfaW50NjQgICAoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX3VpbnQzMiAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vcHRpb25hbF91aW50NjQgICgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfb3B0aW9uYWxfc2ludDMyICAoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX3NpbnQ2NCAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vcHRpb25hbF9maXhlZDMyICgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfb3B0aW9uYWxfZml4ZWQ2NCAoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX3NmaXhlZDMyKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vcHRpb25hbF9zZml4ZWQ2NCgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfb3B0aW9uYWxfZmxvYXQgICAoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX2RvdWJsZSAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vcHRpb25hbF9ib29sICAgICgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfb3B0aW9uYWxfc3RyaW5nICAoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX2J5dGVzICAgKCkpOworCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29wdGlvbmFsZ3JvdXAgICAgICAgICAgICAgICAgICgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgICAgICAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgICAgICAoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX2ltcG9ydF9tZXNzYWdlICAgICAgICgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfb3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vcHRpb25hbF9sYXp5X21lc3NhZ2UgICAgICAgICAoKSk7CisKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5vcHRpb25hbGdyb3VwICAgICAgICAgICAgICAgICAoKS5oYXNfYSgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSAgICAgICAoKS5oYXNfYmIoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2Uub3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlICAgICAgKCkuaGFzX2MoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2Uub3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgICAgICAgKCkuaGFzX2QoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2Uub3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlKCkuaGFzX2UoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2Uub3B0aW9uYWxfbGF6eV9tZXNzYWdlICAgICAgICAgKCkuaGFzX2JiKCkpOworCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX25lc3RlZF9lbnVtICgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfb3B0aW9uYWxfZm9yZWlnbl9lbnVtKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vcHRpb25hbF9pbXBvcnRfZW51bSAoKSk7CisKKworICBFWFBFQ1RfRVEoMTAxICAsIG1lc3NhZ2Uub3B0aW9uYWxfaW50MzIgICAoKSk7CisgIEVYUEVDVF9FUSgxMDIgICwgbWVzc2FnZS5vcHRpb25hbF9pbnQ2NCAgICgpKTsKKyAgRVhQRUNUX0VRKDEwMyAgLCBtZXNzYWdlLm9wdGlvbmFsX3VpbnQzMiAgKCkpOworICBFWFBFQ1RfRVEoMTA0ICAsIG1lc3NhZ2Uub3B0aW9uYWxfdWludDY0ICAoKSk7CisgIEVYUEVDVF9FUSgxMDUgICwgbWVzc2FnZS5vcHRpb25hbF9zaW50MzIgICgpKTsKKyAgRVhQRUNUX0VRKDEwNiAgLCBtZXNzYWdlLm9wdGlvbmFsX3NpbnQ2NCAgKCkpOworICBFWFBFQ1RfRVEoMTA3ICAsIG1lc3NhZ2Uub3B0aW9uYWxfZml4ZWQzMiAoKSk7CisgIEVYUEVDVF9FUSgxMDggICwgbWVzc2FnZS5vcHRpb25hbF9maXhlZDY0ICgpKTsKKyAgRVhQRUNUX0VRKDEwOSAgLCBtZXNzYWdlLm9wdGlvbmFsX3NmaXhlZDMyKCkpOworICBFWFBFQ1RfRVEoMTEwICAsIG1lc3NhZ2Uub3B0aW9uYWxfc2ZpeGVkNjQoKSk7CisgIEVYUEVDVF9FUSgxMTEgICwgbWVzc2FnZS5vcHRpb25hbF9mbG9hdCAgICgpKTsKKyAgRVhQRUNUX0VRKDExMiAgLCBtZXNzYWdlLm9wdGlvbmFsX2RvdWJsZSAgKCkpOworICBFWFBFQ1RfRVEodHJ1ZSAsIG1lc3NhZ2Uub3B0aW9uYWxfYm9vbCAgICAoKSk7CisgIEVYUEVDVF9FUSgiMTE1IiwgbWVzc2FnZS5vcHRpb25hbF9zdHJpbmcgICgpKTsKKyAgRVhQRUNUX0VRKCIxMTYiLCBtZXNzYWdlLm9wdGlvbmFsX2J5dGVzICAgKCkpOworCisgIEVYUEVDVF9FUSgxMTcsIG1lc3NhZ2Uub3B0aW9uYWxncm91cCAgICAgICAgICAgICAgICAgKCkuYSgpKTsKKyAgRVhQRUNUX0VRKDExOCwgbWVzc2FnZS5vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSAgICAgICAoKS5iYigpKTsKKyAgRVhQRUNUX0VRKDExOSwgbWVzc2FnZS5vcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgICAgICAoKS5jKCkpOworICBFWFBFQ1RfRVEoMTIwLCBtZXNzYWdlLm9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlICAgICAgICgpLmQoKSk7CisgIEVYUEVDVF9FUSgxMjYsIG1lc3NhZ2Uub3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlKCkuZSgpKTsKKyAgRVhQRUNUX0VRKDEyNywgbWVzc2FnZS5vcHRpb25hbF9sYXp5X21lc3NhZ2UgICAgICAgICAoKS5iYigpKTsKKworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RBbGxUeXBlc0xpdGU6OkJBWiAsIG1lc3NhZ2Uub3B0aW9uYWxfbmVzdGVkX2VudW0gKCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fTElURV9CQVogICAgICAsIG1lc3NhZ2Uub3B0aW9uYWxfZm9yZWlnbl9lbnVtKCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3RfaW1wb3J0OjpJTVBPUlRfTElURV9CQVosIG1lc3NhZ2Uub3B0aW9uYWxfaW1wb3J0X2VudW0gKCkpOworCisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9pbnQzMl9zaXplICAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9pbnQ2NF9zaXplICAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF91aW50MzJfc2l6ZSAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF91aW50NjRfc2l6ZSAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9zaW50MzJfc2l6ZSAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9zaW50NjRfc2l6ZSAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9maXhlZDMyX3NpemUgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9maXhlZDY0X3NpemUgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9zZml4ZWQzMl9zaXplKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9zZml4ZWQ2NF9zaXplKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9mbG9hdF9zaXplICAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9kb3VibGVfc2l6ZSAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9ib29sX3NpemUgICAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9zdHJpbmdfc2l6ZSAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9ieXRlc19zaXplICAgKCkpOworCisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkZ3JvdXBfc2l6ZSAgICAgICAgICAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9zaXplICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX3NpemUoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlX3NpemUgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9sYXp5X21lc3NhZ2Vfc2l6ZSAgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX2VudW1fc2l6ZSAgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ZvcmVpZ25fZW51bV9zaXplICAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9pbXBvcnRfZW51bV9zaXplICAgICgpKTsKKworCisgIEVYUEVDVF9FUSgyMDEgICwgbWVzc2FnZS5yZXBlYXRlZF9pbnQzMiAgICgwKSk7CisgIEVYUEVDVF9FUSgyMDIgICwgbWVzc2FnZS5yZXBlYXRlZF9pbnQ2NCAgICgwKSk7CisgIEVYUEVDVF9FUSgyMDMgICwgbWVzc2FnZS5yZXBlYXRlZF91aW50MzIgICgwKSk7CisgIEVYUEVDVF9FUSgyMDQgICwgbWVzc2FnZS5yZXBlYXRlZF91aW50NjQgICgwKSk7CisgIEVYUEVDVF9FUSgyMDUgICwgbWVzc2FnZS5yZXBlYXRlZF9zaW50MzIgICgwKSk7CisgIEVYUEVDVF9FUSgyMDYgICwgbWVzc2FnZS5yZXBlYXRlZF9zaW50NjQgICgwKSk7CisgIEVYUEVDVF9FUSgyMDcgICwgbWVzc2FnZS5yZXBlYXRlZF9maXhlZDMyICgwKSk7CisgIEVYUEVDVF9FUSgyMDggICwgbWVzc2FnZS5yZXBlYXRlZF9maXhlZDY0ICgwKSk7CisgIEVYUEVDVF9FUSgyMDkgICwgbWVzc2FnZS5yZXBlYXRlZF9zZml4ZWQzMigwKSk7CisgIEVYUEVDVF9FUSgyMTAgICwgbWVzc2FnZS5yZXBlYXRlZF9zZml4ZWQ2NCgwKSk7CisgIEVYUEVDVF9FUSgyMTEgICwgbWVzc2FnZS5yZXBlYXRlZF9mbG9hdCAgICgwKSk7CisgIEVYUEVDVF9FUSgyMTIgICwgbWVzc2FnZS5yZXBlYXRlZF9kb3VibGUgICgwKSk7CisgIEVYUEVDVF9FUSh0cnVlICwgbWVzc2FnZS5yZXBlYXRlZF9ib29sICAgICgwKSk7CisgIEVYUEVDVF9FUSgiMjE1IiwgbWVzc2FnZS5yZXBlYXRlZF9zdHJpbmcgICgwKSk7CisgIEVYUEVDVF9FUSgiMjE2IiwgbWVzc2FnZS5yZXBlYXRlZF9ieXRlcyAgICgwKSk7CisKKyAgRVhQRUNUX0VRKDIxNywgbWVzc2FnZS5yZXBlYXRlZGdyb3VwICAgICAgICAgICAoMCkuYSgpKTsKKyAgRVhQRUNUX0VRKDIxOCwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSAoMCkuYmIoKSk7CisgIEVYUEVDVF9FUSgyMTksIG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKDApLmMoKSk7CisgIEVYUEVDVF9FUSgyMjAsIG1lc3NhZ2UucmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgKDApLmQoKSk7CisgIEVYUEVDVF9FUSgyMjcsIG1lc3NhZ2UucmVwZWF0ZWRfbGF6eV9tZXNzYWdlICAgKDApLmJiKCkpOworCisKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlOjpCQVIgLCBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9lbnVtICgwKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9SRUlHTl9MSVRFX0JBUiAgICAgICwgbWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX2VudW0oMCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3RfaW1wb3J0OjpJTVBPUlRfTElURV9CQVIsIG1lc3NhZ2UucmVwZWF0ZWRfaW1wb3J0X2VudW0gKDApKTsKKworICBFWFBFQ1RfRVEoMzAxICAsIG1lc3NhZ2UucmVwZWF0ZWRfaW50MzIgICAoMSkpOworICBFWFBFQ1RfRVEoMzAyICAsIG1lc3NhZ2UucmVwZWF0ZWRfaW50NjQgICAoMSkpOworICBFWFBFQ1RfRVEoMzAzICAsIG1lc3NhZ2UucmVwZWF0ZWRfdWludDMyICAoMSkpOworICBFWFBFQ1RfRVEoMzA0ICAsIG1lc3NhZ2UucmVwZWF0ZWRfdWludDY0ICAoMSkpOworICBFWFBFQ1RfRVEoMzA1ICAsIG1lc3NhZ2UucmVwZWF0ZWRfc2ludDMyICAoMSkpOworICBFWFBFQ1RfRVEoMzA2ICAsIG1lc3NhZ2UucmVwZWF0ZWRfc2ludDY0ICAoMSkpOworICBFWFBFQ1RfRVEoMzA3ICAsIG1lc3NhZ2UucmVwZWF0ZWRfZml4ZWQzMiAoMSkpOworICBFWFBFQ1RfRVEoMzA4ICAsIG1lc3NhZ2UucmVwZWF0ZWRfZml4ZWQ2NCAoMSkpOworICBFWFBFQ1RfRVEoMzA5ICAsIG1lc3NhZ2UucmVwZWF0ZWRfc2ZpeGVkMzIoMSkpOworICBFWFBFQ1RfRVEoMzEwICAsIG1lc3NhZ2UucmVwZWF0ZWRfc2ZpeGVkNjQoMSkpOworICBFWFBFQ1RfRVEoMzExICAsIG1lc3NhZ2UucmVwZWF0ZWRfZmxvYXQgICAoMSkpOworICBFWFBFQ1RfRVEoMzEyICAsIG1lc3NhZ2UucmVwZWF0ZWRfZG91YmxlICAoMSkpOworICBFWFBFQ1RfRVEoZmFsc2UsIG1lc3NhZ2UucmVwZWF0ZWRfYm9vbCAgICAoMSkpOworICBFWFBFQ1RfRVEoIjMxNSIsIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nICAoMSkpOworICBFWFBFQ1RfRVEoIjMxNiIsIG1lc3NhZ2UucmVwZWF0ZWRfYnl0ZXMgICAoMSkpOworCisgIEVYUEVDVF9FUSgzMTcsIG1lc3NhZ2UucmVwZWF0ZWRncm91cCAgICAgICAgICAgKDEpLmEoKSk7CisgIEVYUEVDVF9FUSgzMTgsIG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgKDEpLmJiKCkpOworICBFWFBFQ1RfRVEoMzE5LCBtZXNzYWdlLnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSgxKS5jKCkpOworICBFWFBFQ1RfRVEoMzIwLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlICgxKS5kKCkpOworICBFWFBFQ1RfRVEoMzI3LCBtZXNzYWdlLnJlcGVhdGVkX2xhenlfbWVzc2FnZSAgICgxKS5iYigpKTsKKworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RBbGxUeXBlc0xpdGU6OkJBWiAsIG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX2VudW0gKDEpKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0xJVEVfQkFaICAgICAgLCBtZXNzYWdlLnJlcGVhdGVkX2ZvcmVpZ25fZW51bSgxKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9MSVRFX0JBWiwgbWVzc2FnZS5yZXBlYXRlZF9pbXBvcnRfZW51bSAoMSkpOworCisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X2ludDMyICAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X2ludDY0ICAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X3VpbnQzMiAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X3VpbnQ2NCAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X3NpbnQzMiAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X3NpbnQ2NCAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X2ZpeGVkMzIgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X2ZpeGVkNjQgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X3NmaXhlZDMyKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X3NmaXhlZDY0KCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X2Zsb2F0ICAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X2RvdWJsZSAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X2Jvb2wgICAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X3N0cmluZyAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X2J5dGVzICAgKCkpOworCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfbmVzdGVkX2VudW0gKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19kZWZhdWx0X2ZvcmVpZ25fZW51bSgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5oYXNfZGVmYXVsdF9pbXBvcnRfZW51bSAoKSk7CisKKworICBFWFBFQ1RfRVEoNDAxICAsIG1lc3NhZ2UuZGVmYXVsdF9pbnQzMiAgICgpKTsKKyAgRVhQRUNUX0VRKDQwMiAgLCBtZXNzYWdlLmRlZmF1bHRfaW50NjQgICAoKSk7CisgIEVYUEVDVF9FUSg0MDMgICwgbWVzc2FnZS5kZWZhdWx0X3VpbnQzMiAgKCkpOworICBFWFBFQ1RfRVEoNDA0ICAsIG1lc3NhZ2UuZGVmYXVsdF91aW50NjQgICgpKTsKKyAgRVhQRUNUX0VRKDQwNSAgLCBtZXNzYWdlLmRlZmF1bHRfc2ludDMyICAoKSk7CisgIEVYUEVDVF9FUSg0MDYgICwgbWVzc2FnZS5kZWZhdWx0X3NpbnQ2NCAgKCkpOworICBFWFBFQ1RfRVEoNDA3ICAsIG1lc3NhZ2UuZGVmYXVsdF9maXhlZDMyICgpKTsKKyAgRVhQRUNUX0VRKDQwOCAgLCBtZXNzYWdlLmRlZmF1bHRfZml4ZWQ2NCAoKSk7CisgIEVYUEVDVF9FUSg0MDkgICwgbWVzc2FnZS5kZWZhdWx0X3NmaXhlZDMyKCkpOworICBFWFBFQ1RfRVEoNDEwICAsIG1lc3NhZ2UuZGVmYXVsdF9zZml4ZWQ2NCgpKTsKKyAgRVhQRUNUX0VRKDQxMSAgLCBtZXNzYWdlLmRlZmF1bHRfZmxvYXQgICAoKSk7CisgIEVYUEVDVF9FUSg0MTIgICwgbWVzc2FnZS5kZWZhdWx0X2RvdWJsZSAgKCkpOworICBFWFBFQ1RfRVEoZmFsc2UsIG1lc3NhZ2UuZGVmYXVsdF9ib29sICAgICgpKTsKKyAgRVhQRUNUX0VRKCI0MTUiLCBtZXNzYWdlLmRlZmF1bHRfc3RyaW5nICAoKSk7CisgIEVYUEVDVF9FUSgiNDE2IiwgbWVzc2FnZS5kZWZhdWx0X2J5dGVzICAgKCkpOworCisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzTGl0ZTo6Rk9PICwgbWVzc2FnZS5kZWZhdWx0X25lc3RlZF9lbnVtICgpKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0xJVEVfRk9PICAgICAgLCBtZXNzYWdlLmRlZmF1bHRfZm9yZWlnbl9lbnVtKCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3RfaW1wb3J0OjpJTVBPUlRfTElURV9GT08sIG1lc3NhZ2UuZGVmYXVsdF9pbXBvcnRfZW51bSAoKSk7CisKKworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb25lb2ZfdWludDMyICAgICAgICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vbmVvZl9uZXN0ZWRfbWVzc2FnZSgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29uZW9mX3N0cmluZyAgICAgICAgKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLmhhc19vbmVvZl9ieXRlcyAgICAgICAgICAoKSk7CisKKyAgRVhQRUNUX0VRKCI2MDQiLCBtZXNzYWdlLm9uZW9mX2J5dGVzKCkpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3ZvaWQgVGVzdFV0aWxMaXRlOjpFeHBlY3RDbGVhcihjb25zdCB1bml0dGVzdDo6VGVzdEFsbFR5cGVzTGl0ZSYgbWVzc2FnZSkgeworICAvLyBoYXNfYmxhaCgpIHNob3VsZCBpbml0aWFsbHkgYmUgZmFsc2UgZm9yIGFsbCBvcHRpb25hbCBmaWVsZHMuCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9pbnQzMiAgICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX2ludDY0ICAgKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb3B0aW9uYWxfdWludDMyICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF91aW50NjQgICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX3NpbnQzMiAgKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb3B0aW9uYWxfc2ludDY0ICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9maXhlZDMyICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX2ZpeGVkNjQgKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb3B0aW9uYWxfc2ZpeGVkMzIoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9zZml4ZWQ2NCgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX2Zsb2F0ICAgKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb3B0aW9uYWxfZG91YmxlICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vcHRpb25hbF9ib29sICAgICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX3N0cmluZyAgKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb3B0aW9uYWxfYnl0ZXMgICAoKSk7CisKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29wdGlvbmFsZ3JvdXAgICAgICAgICAgICAgICAgICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX25lc3RlZF9tZXNzYWdlICAgICAgICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSAgICAgICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX2ltcG9ydF9tZXNzYWdlICAgICAgICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZSgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29wdGlvbmFsX2xhenlfbWVzc2FnZSAgICAgICAgICgpKTsKKworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb3B0aW9uYWxfbmVzdGVkX2VudW0gKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb3B0aW9uYWxfZm9yZWlnbl9lbnVtKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb3B0aW9uYWxfaW1wb3J0X2VudW0gKCkpOworCisKKyAgLy8gT3B0aW9uYWwgZmllbGRzIHdpdGhvdXQgZGVmYXVsdHMgYXJlIHNldCB0byB6ZXJvIG9yIHNvbWV0aGluZyBsaWtlIGl0LgorICBFWFBFQ1RfRVEoMCAgICAsIG1lc3NhZ2Uub3B0aW9uYWxfaW50MzIgICAoKSk7CisgIEVYUEVDVF9FUSgwICAgICwgbWVzc2FnZS5vcHRpb25hbF9pbnQ2NCAgICgpKTsKKyAgRVhQRUNUX0VRKDAgICAgLCBtZXNzYWdlLm9wdGlvbmFsX3VpbnQzMiAgKCkpOworICBFWFBFQ1RfRVEoMCAgICAsIG1lc3NhZ2Uub3B0aW9uYWxfdWludDY0ICAoKSk7CisgIEVYUEVDVF9FUSgwICAgICwgbWVzc2FnZS5vcHRpb25hbF9zaW50MzIgICgpKTsKKyAgRVhQRUNUX0VRKDAgICAgLCBtZXNzYWdlLm9wdGlvbmFsX3NpbnQ2NCAgKCkpOworICBFWFBFQ1RfRVEoMCAgICAsIG1lc3NhZ2Uub3B0aW9uYWxfZml4ZWQzMiAoKSk7CisgIEVYUEVDVF9FUSgwICAgICwgbWVzc2FnZS5vcHRpb25hbF9maXhlZDY0ICgpKTsKKyAgRVhQRUNUX0VRKDAgICAgLCBtZXNzYWdlLm9wdGlvbmFsX3NmaXhlZDMyKCkpOworICBFWFBFQ1RfRVEoMCAgICAsIG1lc3NhZ2Uub3B0aW9uYWxfc2ZpeGVkNjQoKSk7CisgIEVYUEVDVF9FUSgwICAgICwgbWVzc2FnZS5vcHRpb25hbF9mbG9hdCAgICgpKTsKKyAgRVhQRUNUX0VRKDAgICAgLCBtZXNzYWdlLm9wdGlvbmFsX2RvdWJsZSAgKCkpOworICBFWFBFQ1RfRVEoZmFsc2UsIG1lc3NhZ2Uub3B0aW9uYWxfYm9vbCAgICAoKSk7CisgIEVYUEVDVF9FUSgiIiAgICwgbWVzc2FnZS5vcHRpb25hbF9zdHJpbmcgICgpKTsKKyAgRVhQRUNUX0VRKCIiICAgLCBtZXNzYWdlLm9wdGlvbmFsX2J5dGVzICAgKCkpOworCisgIC8vIEVtYmVkZGVkIG1lc3NhZ2VzIHNob3VsZCBhbHNvIGJlIGNsZWFyLgorICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5vcHRpb25hbGdyb3VwICAgICAgICAgICAgICAgICAoKS5oYXNfYSgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2Uub3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgICAgICAgKCkuaGFzX2JiKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5vcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgICAgICAoKS5oYXNfYygpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2Uub3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgICAgICAgKCkuaGFzX2QoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLm9wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZSgpLmhhc19lKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5vcHRpb25hbF9sYXp5X21lc3NhZ2UgICAgICAgICAoKS5oYXNfYmIoKSk7CisKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2Uub3B0aW9uYWxncm91cCAgICAgICAgICAgKCkuYSgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2Uub3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgKCkuYmIoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSgpLmMoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLm9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlICgpLmQoKSk7CisKKyAgLy8gRW51bXMgd2l0aG91dCBkZWZhdWx0cyBhcmUgc2V0IHRvIHRoZSBmaXJzdCB2YWx1ZSBpbiB0aGUgZW51bS4KKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlOjpGT08gLCBtZXNzYWdlLm9wdGlvbmFsX25lc3RlZF9lbnVtICgpKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0xJVEVfRk9PICAgICAgLCBtZXNzYWdlLm9wdGlvbmFsX2ZvcmVpZ25fZW51bSgpKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0X2ltcG9ydDo6SU1QT1JUX0xJVEVfRk9PLCBtZXNzYWdlLm9wdGlvbmFsX2ltcG9ydF9lbnVtICgpKTsKKworCisgIC8vIFJlcGVhdGVkIGZpZWxkcyBhcmUgZW1wdHkuCisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX2ludDMyX3NpemUgICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX2ludDY0X3NpemUgICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX3VpbnQzMl9zaXplICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX3VpbnQ2NF9zaXplICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX3NpbnQzMl9zaXplICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX3NpbnQ2NF9zaXplICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX2ZpeGVkMzJfc2l6ZSAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX2ZpeGVkNjRfc2l6ZSAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX3NmaXhlZDMyX3NpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX3NmaXhlZDY0X3NpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX2Zsb2F0X3NpemUgICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX2RvdWJsZV9zaXplICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX2Jvb2xfc2l6ZSAgICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX3N0cmluZ19zaXplICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX2J5dGVzX3NpemUgICAoKSk7CisKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucmVwZWF0ZWRncm91cF9zaXplICAgICAgICAgICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX3NpemUgKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX21lc3NhZ2Vfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2Vfc2l6ZSAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX2xhenlfbWVzc2FnZV9zaXplICAgKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfZW51bV9zaXplICAgICgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9lbnVtX3NpemUgICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9lbnVtX3NpemUgICAgKCkpOworCisKKyAgLy8gaGFzX2JsYWgoKSBzaG91bGQgYWxzbyBiZSBmYWxzZSBmb3IgYWxsIGRlZmF1bHQgZmllbGRzLgorICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZGVmYXVsdF9pbnQzMiAgICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfaW50NjQgICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19kZWZhdWx0X3VpbnQzMiAgKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZGVmYXVsdF91aW50NjQgICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfc2ludDMyICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19kZWZhdWx0X3NpbnQ2NCAgKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZGVmYXVsdF9maXhlZDMyICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfZml4ZWQ2NCAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19kZWZhdWx0X3NmaXhlZDMyKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZGVmYXVsdF9zZml4ZWQ2NCgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfZmxvYXQgICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19kZWZhdWx0X2RvdWJsZSAgKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZGVmYXVsdF9ib29sICAgICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfc3RyaW5nICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19kZWZhdWx0X2J5dGVzICAgKCkpOworCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19kZWZhdWx0X25lc3RlZF9lbnVtICgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2RlZmF1bHRfZm9yZWlnbl9lbnVtKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfZGVmYXVsdF9pbXBvcnRfZW51bSAoKSk7CisKKworICAvLyBGaWVsZHMgd2l0aCBkZWZhdWx0cyBoYXZlIHRoZWlyIGRlZmF1bHQgdmFsdWVzIChkdWgpLgorICBFWFBFQ1RfRVEoIDQxICAgICwgbWVzc2FnZS5kZWZhdWx0X2ludDMyICAgKCkpOworICBFWFBFQ1RfRVEoIDQyICAgICwgbWVzc2FnZS5kZWZhdWx0X2ludDY0ICAgKCkpOworICBFWFBFQ1RfRVEoIDQzICAgICwgbWVzc2FnZS5kZWZhdWx0X3VpbnQzMiAgKCkpOworICBFWFBFQ1RfRVEoIDQ0ICAgICwgbWVzc2FnZS5kZWZhdWx0X3VpbnQ2NCAgKCkpOworICBFWFBFQ1RfRVEoLTQ1ICAgICwgbWVzc2FnZS5kZWZhdWx0X3NpbnQzMiAgKCkpOworICBFWFBFQ1RfRVEoIDQ2ICAgICwgbWVzc2FnZS5kZWZhdWx0X3NpbnQ2NCAgKCkpOworICBFWFBFQ1RfRVEoIDQ3ICAgICwgbWVzc2FnZS5kZWZhdWx0X2ZpeGVkMzIgKCkpOworICBFWFBFQ1RfRVEoIDQ4ICAgICwgbWVzc2FnZS5kZWZhdWx0X2ZpeGVkNjQgKCkpOworICBFWFBFQ1RfRVEoIDQ5ICAgICwgbWVzc2FnZS5kZWZhdWx0X3NmaXhlZDMyKCkpOworICBFWFBFQ1RfRVEoLTUwICAgICwgbWVzc2FnZS5kZWZhdWx0X3NmaXhlZDY0KCkpOworICBFWFBFQ1RfRVEoIDUxLjUgICwgbWVzc2FnZS5kZWZhdWx0X2Zsb2F0ICAgKCkpOworICBFWFBFQ1RfRVEoIDUyZTMgICwgbWVzc2FnZS5kZWZhdWx0X2RvdWJsZSAgKCkpOworICBFWFBFQ1RfRVEodHJ1ZSAgICwgbWVzc2FnZS5kZWZhdWx0X2Jvb2wgICAgKCkpOworICBFWFBFQ1RfRVEoImhlbGxvIiwgbWVzc2FnZS5kZWZhdWx0X3N0cmluZyAgKCkpOworICBFWFBFQ1RfRVEoIndvcmxkIiwgbWVzc2FnZS5kZWZhdWx0X2J5dGVzICAgKCkpOworCisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzTGl0ZTo6QkFSICwgbWVzc2FnZS5kZWZhdWx0X25lc3RlZF9lbnVtICgpKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0xJVEVfQkFSICAgICAgLCBtZXNzYWdlLmRlZmF1bHRfZm9yZWlnbl9lbnVtKCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3RfaW1wb3J0OjpJTVBPUlRfTElURV9CQVIsIG1lc3NhZ2UuZGVmYXVsdF9pbXBvcnRfZW51bSAoKSk7CisKKworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb25lb2ZfdWludDMyICAgICAgICAoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLmhhc19vbmVvZl9uZXN0ZWRfbWVzc2FnZSgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX29uZW9mX3N0cmluZyAgICAgICAgKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfb25lb2ZfYnl0ZXMgICAgICAgICAoKSk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBUZXN0VXRpbExpdGU6OkV4cGVjdFJlcGVhdGVkRmllbGRzTW9kaWZpZWQoCisgICAgY29uc3QgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlc0xpdGUmIG1lc3NhZ2UpIHsKKyAgLy8gTW9kaWZ5UmVwZWF0ZWRGaWVsZHMgb25seSBzZXRzIHRoZSBzZWNvbmQgcmVwZWF0ZWQgZWxlbWVudCBvZiBlYWNoCisgIC8vIGZpZWxkLiAgSW4gYWRkaXRpb24gdG8gdmVyaWZ5aW5nIHRoaXMsIHdlIGFsc28gdmVyaWZ5IHRoYXQgdGhlIGZpcnN0CisgIC8vIGVsZW1lbnQgYW5kIHNpemUgd2VyZSAqbm90KiBtb2RpZmllZC4KKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfaW50MzJfc2l6ZSAgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfaW50NjRfc2l6ZSAgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfdWludDMyX3NpemUgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfdWludDY0X3NpemUgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfc2ludDMyX3NpemUgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfc2ludDY0X3NpemUgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfZml4ZWQzMl9zaXplICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfZml4ZWQ2NF9zaXplICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfc2ZpeGVkMzJfc2l6ZSgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfc2ZpeGVkNjRfc2l6ZSgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfZmxvYXRfc2l6ZSAgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfZG91YmxlX3NpemUgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfYm9vbF9zaXplICAgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nX3NpemUgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfYnl0ZXNfc2l6ZSAgICgpKTsKKworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZGdyb3VwX3NpemUgICAgICAgICAgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2Vfc2l6ZSAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZV9zaXplKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9pbXBvcnRfbWVzc2FnZV9zaXplICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfbGF6eV9tZXNzYWdlX3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9lbnVtX3NpemUgICAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5yZXBlYXRlZF9mb3JlaWduX2VudW1fc2l6ZSAgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfaW1wb3J0X2VudW1fc2l6ZSAgICAoKSk7CisKKworICBFWFBFQ1RfRVEoMjAxICAsIG1lc3NhZ2UucmVwZWF0ZWRfaW50MzIgICAoMCkpOworICBFWFBFQ1RfRVEoMjAyICAsIG1lc3NhZ2UucmVwZWF0ZWRfaW50NjQgICAoMCkpOworICBFWFBFQ1RfRVEoMjAzICAsIG1lc3NhZ2UucmVwZWF0ZWRfdWludDMyICAoMCkpOworICBFWFBFQ1RfRVEoMjA0ICAsIG1lc3NhZ2UucmVwZWF0ZWRfdWludDY0ICAoMCkpOworICBFWFBFQ1RfRVEoMjA1ICAsIG1lc3NhZ2UucmVwZWF0ZWRfc2ludDMyICAoMCkpOworICBFWFBFQ1RfRVEoMjA2ICAsIG1lc3NhZ2UucmVwZWF0ZWRfc2ludDY0ICAoMCkpOworICBFWFBFQ1RfRVEoMjA3ICAsIG1lc3NhZ2UucmVwZWF0ZWRfZml4ZWQzMiAoMCkpOworICBFWFBFQ1RfRVEoMjA4ICAsIG1lc3NhZ2UucmVwZWF0ZWRfZml4ZWQ2NCAoMCkpOworICBFWFBFQ1RfRVEoMjA5ICAsIG1lc3NhZ2UucmVwZWF0ZWRfc2ZpeGVkMzIoMCkpOworICBFWFBFQ1RfRVEoMjEwICAsIG1lc3NhZ2UucmVwZWF0ZWRfc2ZpeGVkNjQoMCkpOworICBFWFBFQ1RfRVEoMjExICAsIG1lc3NhZ2UucmVwZWF0ZWRfZmxvYXQgICAoMCkpOworICBFWFBFQ1RfRVEoMjEyICAsIG1lc3NhZ2UucmVwZWF0ZWRfZG91YmxlICAoMCkpOworICBFWFBFQ1RfRVEodHJ1ZSAsIG1lc3NhZ2UucmVwZWF0ZWRfYm9vbCAgICAoMCkpOworICBFWFBFQ1RfRVEoIjIxNSIsIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nICAoMCkpOworICBFWFBFQ1RfRVEoIjIxNiIsIG1lc3NhZ2UucmVwZWF0ZWRfYnl0ZXMgICAoMCkpOworCisgIEVYUEVDVF9FUSgyMTcsIG1lc3NhZ2UucmVwZWF0ZWRncm91cCAgICAgICAgICAgKDApLmEoKSk7CisgIEVYUEVDVF9FUSgyMTgsIG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgKDApLmJiKCkpOworICBFWFBFQ1RfRVEoMjE5LCBtZXNzYWdlLnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSgwKS5jKCkpOworICBFWFBFQ1RfRVEoMjIwLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlICgwKS5kKCkpOworICBFWFBFQ1RfRVEoMjI3LCBtZXNzYWdlLnJlcGVhdGVkX2xhenlfbWVzc2FnZSAgICgwKS5iYigpKTsKKworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RBbGxUeXBlc0xpdGU6OkJBUiAsIG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX2VudW0gKDApKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0xJVEVfQkFSICAgICAgLCBtZXNzYWdlLnJlcGVhdGVkX2ZvcmVpZ25fZW51bSgwKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9MSVRFX0JBUiwgbWVzc2FnZS5yZXBlYXRlZF9pbXBvcnRfZW51bSAoMCkpOworCisKKyAgLy8gQWN0dWFsbHkgdmVyaWZ5IHRoZSBzZWNvbmQgKG1vZGlmaWVkKSBlbGVtZW50cyBub3cuCisgIEVYUEVDVF9FUSg1MDEgICwgbWVzc2FnZS5yZXBlYXRlZF9pbnQzMiAgICgxKSk7CisgIEVYUEVDVF9FUSg1MDIgICwgbWVzc2FnZS5yZXBlYXRlZF9pbnQ2NCAgICgxKSk7CisgIEVYUEVDVF9FUSg1MDMgICwgbWVzc2FnZS5yZXBlYXRlZF91aW50MzIgICgxKSk7CisgIEVYUEVDVF9FUSg1MDQgICwgbWVzc2FnZS5yZXBlYXRlZF91aW50NjQgICgxKSk7CisgIEVYUEVDVF9FUSg1MDUgICwgbWVzc2FnZS5yZXBlYXRlZF9zaW50MzIgICgxKSk7CisgIEVYUEVDVF9FUSg1MDYgICwgbWVzc2FnZS5yZXBlYXRlZF9zaW50NjQgICgxKSk7CisgIEVYUEVDVF9FUSg1MDcgICwgbWVzc2FnZS5yZXBlYXRlZF9maXhlZDMyICgxKSk7CisgIEVYUEVDVF9FUSg1MDggICwgbWVzc2FnZS5yZXBlYXRlZF9maXhlZDY0ICgxKSk7CisgIEVYUEVDVF9FUSg1MDkgICwgbWVzc2FnZS5yZXBlYXRlZF9zZml4ZWQzMigxKSk7CisgIEVYUEVDVF9FUSg1MTAgICwgbWVzc2FnZS5yZXBlYXRlZF9zZml4ZWQ2NCgxKSk7CisgIEVYUEVDVF9FUSg1MTEgICwgbWVzc2FnZS5yZXBlYXRlZF9mbG9hdCAgICgxKSk7CisgIEVYUEVDVF9FUSg1MTIgICwgbWVzc2FnZS5yZXBlYXRlZF9kb3VibGUgICgxKSk7CisgIEVYUEVDVF9FUSh0cnVlICwgbWVzc2FnZS5yZXBlYXRlZF9ib29sICAgICgxKSk7CisgIEVYUEVDVF9FUSgiNTE1IiwgbWVzc2FnZS5yZXBlYXRlZF9zdHJpbmcgICgxKSk7CisgIEVYUEVDVF9FUSgiNTE2IiwgbWVzc2FnZS5yZXBlYXRlZF9ieXRlcyAgICgxKSk7CisKKyAgRVhQRUNUX0VRKDUxNywgbWVzc2FnZS5yZXBlYXRlZGdyb3VwICAgICAgICAgICAoMSkuYSgpKTsKKyAgRVhQRUNUX0VRKDUxOCwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSAoMSkuYmIoKSk7CisgIEVYUEVDVF9FUSg1MTksIG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlKDEpLmMoKSk7CisgIEVYUEVDVF9FUSg1MjAsIG1lc3NhZ2UucmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgKDEpLmQoKSk7CisgIEVYUEVDVF9FUSg1MjcsIG1lc3NhZ2UucmVwZWF0ZWRfbGF6eV9tZXNzYWdlICAgKDEpLmJiKCkpOworCisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzTGl0ZTo6Rk9PICwgbWVzc2FnZS5yZXBlYXRlZF9uZXN0ZWRfZW51bSAoMSkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fTElURV9GT08gICAgICAsIG1lc3NhZ2UucmVwZWF0ZWRfZm9yZWlnbl9lbnVtKDEpKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0X2ltcG9ydDo6SU1QT1JUX0xJVEVfRk9PLCBtZXNzYWdlLnJlcGVhdGVkX2ltcG9ydF9lbnVtICgxKSk7CisKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIFRlc3RVdGlsTGl0ZTo6U2V0UGFja2VkRmllbGRzKHVuaXR0ZXN0OjpUZXN0UGFja2VkVHlwZXNMaXRlKiBtZXNzYWdlKSB7CisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfaW50MzIgICAoNjAxKTsKKyAgbWVzc2FnZS0+YWRkX3BhY2tlZF9pbnQ2NCAgICg2MDIpOworICBtZXNzYWdlLT5hZGRfcGFja2VkX3VpbnQzMiAgKDYwMyk7CisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfdWludDY0ICAoNjA0KTsKKyAgbWVzc2FnZS0+YWRkX3BhY2tlZF9zaW50MzIgICg2MDUpOworICBtZXNzYWdlLT5hZGRfcGFja2VkX3NpbnQ2NCAgKDYwNik7CisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfZml4ZWQzMiAoNjA3KTsKKyAgbWVzc2FnZS0+YWRkX3BhY2tlZF9maXhlZDY0ICg2MDgpOworICBtZXNzYWdlLT5hZGRfcGFja2VkX3NmaXhlZDMyKDYwOSk7CisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfc2ZpeGVkNjQoNjEwKTsKKyAgbWVzc2FnZS0+YWRkX3BhY2tlZF9mbG9hdCAgICg2MTEpOworICBtZXNzYWdlLT5hZGRfcGFja2VkX2RvdWJsZSAgKDYxMik7CisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfYm9vbCAgICAodHJ1ZSk7CisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfZW51bSAgICAodW5pdHRlc3Q6OkZPUkVJR05fTElURV9CQVIpOworICAvLyBhZGQgYSBzZWNvbmQgb25lIG9mIGVhY2ggZmllbGQKKyAgbWVzc2FnZS0+YWRkX3BhY2tlZF9pbnQzMiAgICg3MDEpOworICBtZXNzYWdlLT5hZGRfcGFja2VkX2ludDY0ICAgKDcwMik7CisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfdWludDMyICAoNzAzKTsKKyAgbWVzc2FnZS0+YWRkX3BhY2tlZF91aW50NjQgICg3MDQpOworICBtZXNzYWdlLT5hZGRfcGFja2VkX3NpbnQzMiAgKDcwNSk7CisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfc2ludDY0ICAoNzA2KTsKKyAgbWVzc2FnZS0+YWRkX3BhY2tlZF9maXhlZDMyICg3MDcpOworICBtZXNzYWdlLT5hZGRfcGFja2VkX2ZpeGVkNjQgKDcwOCk7CisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfc2ZpeGVkMzIoNzA5KTsKKyAgbWVzc2FnZS0+YWRkX3BhY2tlZF9zZml4ZWQ2NCg3MTApOworICBtZXNzYWdlLT5hZGRfcGFja2VkX2Zsb2F0ICAgKDcxMSk7CisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfZG91YmxlICAoNzEyKTsKKyAgbWVzc2FnZS0+YWRkX3BhY2tlZF9ib29sICAgIChmYWxzZSk7CisgIG1lc3NhZ2UtPmFkZF9wYWNrZWRfZW51bSAgICAodW5pdHRlc3Q6OkZPUkVJR05fTElURV9CQVopOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3ZvaWQgVGVzdFV0aWxMaXRlOjpNb2RpZnlQYWNrZWRGaWVsZHModW5pdHRlc3Q6OlRlc3RQYWNrZWRUeXBlc0xpdGUqIG1lc3NhZ2UpIHsKKyAgbWVzc2FnZS0+c2V0X3BhY2tlZF9pbnQzMiAgICgxLCA4MDEpOworICBtZXNzYWdlLT5zZXRfcGFja2VkX2ludDY0ICAgKDEsIDgwMik7CisgIG1lc3NhZ2UtPnNldF9wYWNrZWRfdWludDMyICAoMSwgODAzKTsKKyAgbWVzc2FnZS0+c2V0X3BhY2tlZF91aW50NjQgICgxLCA4MDQpOworICBtZXNzYWdlLT5zZXRfcGFja2VkX3NpbnQzMiAgKDEsIDgwNSk7CisgIG1lc3NhZ2UtPnNldF9wYWNrZWRfc2ludDY0ICAoMSwgODA2KTsKKyAgbWVzc2FnZS0+c2V0X3BhY2tlZF9maXhlZDMyICgxLCA4MDcpOworICBtZXNzYWdlLT5zZXRfcGFja2VkX2ZpeGVkNjQgKDEsIDgwOCk7CisgIG1lc3NhZ2UtPnNldF9wYWNrZWRfc2ZpeGVkMzIoMSwgODA5KTsKKyAgbWVzc2FnZS0+c2V0X3BhY2tlZF9zZml4ZWQ2NCgxLCA4MTApOworICBtZXNzYWdlLT5zZXRfcGFja2VkX2Zsb2F0ICAgKDEsIDgxMSk7CisgIG1lc3NhZ2UtPnNldF9wYWNrZWRfZG91YmxlICAoMSwgODEyKTsKKyAgbWVzc2FnZS0+c2V0X3BhY2tlZF9ib29sICAgICgxLCB0cnVlKTsKKyAgbWVzc2FnZS0+c2V0X3BhY2tlZF9lbnVtICAgICgxLCB1bml0dGVzdDo6Rk9SRUlHTl9MSVRFX0ZPTyk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBUZXN0VXRpbExpdGU6OkV4cGVjdFBhY2tlZEZpZWxkc1NldCgKKyAgICBjb25zdCB1bml0dGVzdDo6VGVzdFBhY2tlZFR5cGVzTGl0ZSYgbWVzc2FnZSkgeworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfaW50MzJfc2l6ZSAgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucGFja2VkX2ludDY0X3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnBhY2tlZF91aW50MzJfc2l6ZSAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfdWludDY0X3NpemUgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucGFja2VkX3NpbnQzMl9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnBhY2tlZF9zaW50NjRfc2l6ZSAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfZml4ZWQzMl9zaXplICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucGFja2VkX2ZpeGVkNjRfc2l6ZSAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnBhY2tlZF9zZml4ZWQzMl9zaXplKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfc2ZpeGVkNjRfc2l6ZSgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucGFja2VkX2Zsb2F0X3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnBhY2tlZF9kb3VibGVfc2l6ZSAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfYm9vbF9zaXplICAgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucGFja2VkX2VudW1fc2l6ZSAgICAoKSk7CisKKyAgRVhQRUNUX0VRKDYwMSAgLCBtZXNzYWdlLnBhY2tlZF9pbnQzMiAgICgwKSk7CisgIEVYUEVDVF9FUSg2MDIgICwgbWVzc2FnZS5wYWNrZWRfaW50NjQgICAoMCkpOworICBFWFBFQ1RfRVEoNjAzICAsIG1lc3NhZ2UucGFja2VkX3VpbnQzMiAgKDApKTsKKyAgRVhQRUNUX0VRKDYwNCAgLCBtZXNzYWdlLnBhY2tlZF91aW50NjQgICgwKSk7CisgIEVYUEVDVF9FUSg2MDUgICwgbWVzc2FnZS5wYWNrZWRfc2ludDMyICAoMCkpOworICBFWFBFQ1RfRVEoNjA2ICAsIG1lc3NhZ2UucGFja2VkX3NpbnQ2NCAgKDApKTsKKyAgRVhQRUNUX0VRKDYwNyAgLCBtZXNzYWdlLnBhY2tlZF9maXhlZDMyICgwKSk7CisgIEVYUEVDVF9FUSg2MDggICwgbWVzc2FnZS5wYWNrZWRfZml4ZWQ2NCAoMCkpOworICBFWFBFQ1RfRVEoNjA5ICAsIG1lc3NhZ2UucGFja2VkX3NmaXhlZDMyKDApKTsKKyAgRVhQRUNUX0VRKDYxMCAgLCBtZXNzYWdlLnBhY2tlZF9zZml4ZWQ2NCgwKSk7CisgIEVYUEVDVF9FUSg2MTEgICwgbWVzc2FnZS5wYWNrZWRfZmxvYXQgICAoMCkpOworICBFWFBFQ1RfRVEoNjEyICAsIG1lc3NhZ2UucGFja2VkX2RvdWJsZSAgKDApKTsKKyAgRVhQRUNUX0VRKHRydWUgLCBtZXNzYWdlLnBhY2tlZF9ib29sICAgICgwKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9SRUlHTl9MSVRFX0JBUiwgbWVzc2FnZS5wYWNrZWRfZW51bSgwKSk7CisKKyAgRVhQRUNUX0VRKDcwMSAgLCBtZXNzYWdlLnBhY2tlZF9pbnQzMiAgICgxKSk7CisgIEVYUEVDVF9FUSg3MDIgICwgbWVzc2FnZS5wYWNrZWRfaW50NjQgICAoMSkpOworICBFWFBFQ1RfRVEoNzAzICAsIG1lc3NhZ2UucGFja2VkX3VpbnQzMiAgKDEpKTsKKyAgRVhQRUNUX0VRKDcwNCAgLCBtZXNzYWdlLnBhY2tlZF91aW50NjQgICgxKSk7CisgIEVYUEVDVF9FUSg3MDUgICwgbWVzc2FnZS5wYWNrZWRfc2ludDMyICAoMSkpOworICBFWFBFQ1RfRVEoNzA2ICAsIG1lc3NhZ2UucGFja2VkX3NpbnQ2NCAgKDEpKTsKKyAgRVhQRUNUX0VRKDcwNyAgLCBtZXNzYWdlLnBhY2tlZF9maXhlZDMyICgxKSk7CisgIEVYUEVDVF9FUSg3MDggICwgbWVzc2FnZS5wYWNrZWRfZml4ZWQ2NCAoMSkpOworICBFWFBFQ1RfRVEoNzA5ICAsIG1lc3NhZ2UucGFja2VkX3NmaXhlZDMyKDEpKTsKKyAgRVhQRUNUX0VRKDcxMCAgLCBtZXNzYWdlLnBhY2tlZF9zZml4ZWQ2NCgxKSk7CisgIEVYUEVDVF9FUSg3MTEgICwgbWVzc2FnZS5wYWNrZWRfZmxvYXQgICAoMSkpOworICBFWFBFQ1RfRVEoNzEyICAsIG1lc3NhZ2UucGFja2VkX2RvdWJsZSAgKDEpKTsKKyAgRVhQRUNUX0VRKGZhbHNlLCBtZXNzYWdlLnBhY2tlZF9ib29sICAgICgxKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9SRUlHTl9MSVRFX0JBWiwgbWVzc2FnZS5wYWNrZWRfZW51bSgxKSk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBUZXN0VXRpbExpdGU6OkV4cGVjdFBhY2tlZENsZWFyKAorICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0UGFja2VkVHlwZXNMaXRlJiBtZXNzYWdlKSB7CisgIC8vIFBhY2tlZCByZXBlYXRlZCBmaWVsZHMgYXJlIGVtcHR5LgorICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5wYWNrZWRfaW50MzJfc2l6ZSAgICgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucGFja2VkX2ludDY0X3NpemUgICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnBhY2tlZF91aW50MzJfc2l6ZSAgKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5wYWNrZWRfdWludDY0X3NpemUgICgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucGFja2VkX3NpbnQzMl9zaXplICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnBhY2tlZF9zaW50NjRfc2l6ZSAgKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5wYWNrZWRfZml4ZWQzMl9zaXplICgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucGFja2VkX2ZpeGVkNjRfc2l6ZSAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnBhY2tlZF9zZml4ZWQzMl9zaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5wYWNrZWRfc2ZpeGVkNjRfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucGFja2VkX2Zsb2F0X3NpemUgICAoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnBhY2tlZF9kb3VibGVfc2l6ZSAgKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5wYWNrZWRfYm9vbF9zaXplICAgICgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UucGFja2VkX2VudW1fc2l6ZSAgICAoKSk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBUZXN0VXRpbExpdGU6OkV4cGVjdFBhY2tlZEZpZWxkc01vZGlmaWVkKAorICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0UGFja2VkVHlwZXNMaXRlJiBtZXNzYWdlKSB7CisgIC8vIERvIHRoZSBzYW1lIGZvciBwYWNrZWQgcmVwZWF0ZWQgZmllbGRzLgorICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfaW50MzJfc2l6ZSAgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucGFja2VkX2ludDY0X3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnBhY2tlZF91aW50MzJfc2l6ZSAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfdWludDY0X3NpemUgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucGFja2VkX3NpbnQzMl9zaXplICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnBhY2tlZF9zaW50NjRfc2l6ZSAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfZml4ZWQzMl9zaXplICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucGFja2VkX2ZpeGVkNjRfc2l6ZSAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnBhY2tlZF9zZml4ZWQzMl9zaXplKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfc2ZpeGVkNjRfc2l6ZSgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucGFja2VkX2Zsb2F0X3NpemUgICAoKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnBhY2tlZF9kb3VibGVfc2l6ZSAgKCkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5wYWNrZWRfYm9vbF9zaXplICAgICgpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucGFja2VkX2VudW1fc2l6ZSAgICAoKSk7CisKKyAgRVhQRUNUX0VRKDYwMSAgLCBtZXNzYWdlLnBhY2tlZF9pbnQzMiAgICgwKSk7CisgIEVYUEVDVF9FUSg2MDIgICwgbWVzc2FnZS5wYWNrZWRfaW50NjQgICAoMCkpOworICBFWFBFQ1RfRVEoNjAzICAsIG1lc3NhZ2UucGFja2VkX3VpbnQzMiAgKDApKTsKKyAgRVhQRUNUX0VRKDYwNCAgLCBtZXNzYWdlLnBhY2tlZF91aW50NjQgICgwKSk7CisgIEVYUEVDVF9FUSg2MDUgICwgbWVzc2FnZS5wYWNrZWRfc2ludDMyICAoMCkpOworICBFWFBFQ1RfRVEoNjA2ICAsIG1lc3NhZ2UucGFja2VkX3NpbnQ2NCAgKDApKTsKKyAgRVhQRUNUX0VRKDYwNyAgLCBtZXNzYWdlLnBhY2tlZF9maXhlZDMyICgwKSk7CisgIEVYUEVDVF9FUSg2MDggICwgbWVzc2FnZS5wYWNrZWRfZml4ZWQ2NCAoMCkpOworICBFWFBFQ1RfRVEoNjA5ICAsIG1lc3NhZ2UucGFja2VkX3NmaXhlZDMyKDApKTsKKyAgRVhQRUNUX0VRKDYxMCAgLCBtZXNzYWdlLnBhY2tlZF9zZml4ZWQ2NCgwKSk7CisgIEVYUEVDVF9FUSg2MTEgICwgbWVzc2FnZS5wYWNrZWRfZmxvYXQgICAoMCkpOworICBFWFBFQ1RfRVEoNjEyICAsIG1lc3NhZ2UucGFja2VkX2RvdWJsZSAgKDApKTsKKyAgRVhQRUNUX0VRKHRydWUgLCBtZXNzYWdlLnBhY2tlZF9ib29sICAgICgwKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9SRUlHTl9MSVRFX0JBUiwgbWVzc2FnZS5wYWNrZWRfZW51bSgwKSk7CisgIC8vIEFjdHVhbGx5IHZlcmlmeSB0aGUgc2Vjb25kIChtb2RpZmllZCkgZWxlbWVudHMgbm93LgorICBFWFBFQ1RfRVEoODAxICAsIG1lc3NhZ2UucGFja2VkX2ludDMyICAgKDEpKTsKKyAgRVhQRUNUX0VRKDgwMiAgLCBtZXNzYWdlLnBhY2tlZF9pbnQ2NCAgICgxKSk7CisgIEVYUEVDVF9FUSg4MDMgICwgbWVzc2FnZS5wYWNrZWRfdWludDMyICAoMSkpOworICBFWFBFQ1RfRVEoODA0ICAsIG1lc3NhZ2UucGFja2VkX3VpbnQ2NCAgKDEpKTsKKyAgRVhQRUNUX0VRKDgwNSAgLCBtZXNzYWdlLnBhY2tlZF9zaW50MzIgICgxKSk7CisgIEVYUEVDVF9FUSg4MDYgICwgbWVzc2FnZS5wYWNrZWRfc2ludDY0ICAoMSkpOworICBFWFBFQ1RfRVEoODA3ICAsIG1lc3NhZ2UucGFja2VkX2ZpeGVkMzIgKDEpKTsKKyAgRVhQRUNUX0VRKDgwOCAgLCBtZXNzYWdlLnBhY2tlZF9maXhlZDY0ICgxKSk7CisgIEVYUEVDVF9FUSg4MDkgICwgbWVzc2FnZS5wYWNrZWRfc2ZpeGVkMzIoMSkpOworICBFWFBFQ1RfRVEoODEwICAsIG1lc3NhZ2UucGFja2VkX3NmaXhlZDY0KDEpKTsKKyAgRVhQRUNUX0VRKDgxMSAgLCBtZXNzYWdlLnBhY2tlZF9mbG9hdCAgICgxKSk7CisgIEVYUEVDVF9FUSg4MTIgICwgbWVzc2FnZS5wYWNrZWRfZG91YmxlICAoMSkpOworICBFWFBFQ1RfRVEodHJ1ZSAsIG1lc3NhZ2UucGFja2VkX2Jvb2wgICAgKDEpKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0xJVEVfRk9PLCBtZXNzYWdlLnBhY2tlZF9lbnVtKDEpKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorLy8gRXh0ZW5zaW9ucworLy8KKy8vIEFsbCB0aGlzIGNvZGUgaXMgZXhhY3RseSBlcXVpdmFsZW50IHRvIHRoZSBhYm92ZSBjb2RlIGV4Y2VwdCB0aGF0IGl0J3MKKy8vIG1hbmlwdWxhdGluZyBleHRlbnNpb24gZmllbGRzIGluc3RlYWQgb2Ygbm9ybWFsIG9uZXMuCisvLworLy8gSSBnYXZlIHVwIG9uIHRoZSA4MC1jaGFyIGxpbWl0IGhlcmUuICBTb3JyeS4KKwordm9pZCBUZXN0VXRpbExpdGU6OlNldEFsbEV4dGVuc2lvbnModW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zTGl0ZSogbWVzc2FnZSkgeworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ludDMyX2V4dGVuc2lvbl9saXRlICAgLCAxMDEpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ludDY0X2V4dGVuc2lvbl9saXRlICAgLCAxMDIpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3VpbnQzMl9leHRlbnNpb25fbGl0ZSAgLCAxMDMpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3VpbnQ2NF9leHRlbnNpb25fbGl0ZSAgLCAxMDQpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3NpbnQzMl9leHRlbnNpb25fbGl0ZSAgLCAxMDUpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3NpbnQ2NF9leHRlbnNpb25fbGl0ZSAgLCAxMDYpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUgLCAxMDcpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUgLCAxMDgpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3NmaXhlZDMyX2V4dGVuc2lvbl9saXRlLCAxMDkpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3NmaXhlZDY0X2V4dGVuc2lvbl9saXRlLCAxMTApOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2Zsb2F0X2V4dGVuc2lvbl9saXRlICAgLCAxMTEpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2RvdWJsZV9leHRlbnNpb25fbGl0ZSAgLCAxMTIpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2Jvb2xfZXh0ZW5zaW9uX2xpdGUgICAgLCB0cnVlKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9zdHJpbmdfZXh0ZW5zaW9uX2xpdGUgICwgIjExNSIpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2J5dGVzX2V4dGVuc2lvbl9saXRlICAgLCAiMTE2Iik7CisKKyAgbWVzc2FnZS0+TXV0YWJsZUV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxncm91cF9leHRlbnNpb25fbGl0ZSAgICAgICAgICAgICAgICAgKS0+c2V0X2EoMTE3KTsKKyAgbWVzc2FnZS0+TXV0YWJsZUV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUgICAgICAgKS0+c2V0X2JiKDExOCk7CisgIG1lc3NhZ2UtPk11dGFibGVFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb25fbGl0ZSAgICAgICktPnNldF9jKDExOSk7CisgIG1lc3NhZ2UtPk11dGFibGVFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICAgICAgICktPnNldF9kKDEyMCk7CisgIG1lc3NhZ2UtPk11dGFibGVFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSktPnNldF9lKDEyNik7CisgIG1lc3NhZ2UtPk11dGFibGVFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2xhenlfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSAgICAgICAgICktPnNldF9iYigxMjcpOworCisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfbmVzdGVkX2VudW1fZXh0ZW5zaW9uX2xpdGUgLCB1bml0dGVzdDo6VGVzdEFsbFR5cGVzTGl0ZTo6QkFaICk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbl9saXRlLCB1bml0dGVzdDo6Rk9SRUlHTl9MSVRFX0JBWiAgICAgICk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW1wb3J0X2VudW1fZXh0ZW5zaW9uX2xpdGUgLCB1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9MSVRFX0JBWik7CisKKworICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9uX2xpdGUgICAsIDIwMSk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW50NjRfZXh0ZW5zaW9uX2xpdGUgICAsIDIwMik7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfdWludDMyX2V4dGVuc2lvbl9saXRlICAsIDIwMyk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfdWludDY0X2V4dGVuc2lvbl9saXRlICAsIDIwNCk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ludDMyX2V4dGVuc2lvbl9saXRlICAsIDIwNSk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ludDY0X2V4dGVuc2lvbl9saXRlICAsIDIwNik7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZml4ZWQzMl9leHRlbnNpb25fbGl0ZSAsIDIwNyk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSAsIDIwOCk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUsIDIwOSk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUsIDIxMCk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZmxvYXRfZXh0ZW5zaW9uX2xpdGUgICAsIDIxMSk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZG91YmxlX2V4dGVuc2lvbl9saXRlICAsIDIxMik7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfYm9vbF9leHRlbnNpb25fbGl0ZSAgICAsIHRydWUpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb25fbGl0ZSAgLCAiMjE1Iik7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfYnl0ZXNfZXh0ZW5zaW9uX2xpdGUgICAsICIyMTYiKTsKKworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkZ3JvdXBfZXh0ZW5zaW9uX2xpdGUgICAgICAgICAgICktPnNldF9hKDIxNyk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUgKS0+c2V0X2JiKDIxOCk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbl9saXRlKS0+c2V0X2MoMjE5KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSApLT5zZXRfZCgyMjApOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2xhenlfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSAgICktPnNldF9iYigyMjcpOworCisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uX2xpdGUgLCB1bml0dGVzdDo6VGVzdEFsbFR5cGVzTGl0ZTo6QkFSICk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbl9saXRlLCB1bml0dGVzdDo6Rk9SRUlHTl9MSVRFX0JBUiAgICAgICk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW1wb3J0X2VudW1fZXh0ZW5zaW9uX2xpdGUgLCB1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9MSVRFX0JBUik7CisKKworICAvLyBBZGQgYSBzZWNvbmQgb25lIG9mIGVhY2ggZmllbGQuCisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9uX2xpdGUgICAsIDMwMSk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW50NjRfZXh0ZW5zaW9uX2xpdGUgICAsIDMwMik7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfdWludDMyX2V4dGVuc2lvbl9saXRlICAsIDMwMyk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfdWludDY0X2V4dGVuc2lvbl9saXRlICAsIDMwNCk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ludDMyX2V4dGVuc2lvbl9saXRlICAsIDMwNSk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ludDY0X2V4dGVuc2lvbl9saXRlICAsIDMwNik7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZml4ZWQzMl9leHRlbnNpb25fbGl0ZSAsIDMwNyk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSAsIDMwOCk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUsIDMwOSk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUsIDMxMCk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZmxvYXRfZXh0ZW5zaW9uX2xpdGUgICAsIDMxMSk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZG91YmxlX2V4dGVuc2lvbl9saXRlICAsIDMxMik7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfYm9vbF9leHRlbnNpb25fbGl0ZSAgICAsIGZhbHNlKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zdHJpbmdfZXh0ZW5zaW9uX2xpdGUgICwgIjMxNSIpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2J5dGVzX2V4dGVuc2lvbl9saXRlICAgLCAiMzE2Iik7CisKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZGdyb3VwX2V4dGVuc2lvbl9saXRlICAgICAgICAgICApLT5zZXRfYSgzMTcpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICktPnNldF9iYigzMTgpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb25fbGl0ZSktPnNldF9jKDMxOSk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUgKS0+c2V0X2QoMzIwKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9sYXp5X21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUgICApLT5zZXRfYmIoMzI3KTsKKworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9lbnVtX2V4dGVuc2lvbl9saXRlICwgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlc0xpdGU6OkJBWiApOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZvcmVpZ25fZW51bV9leHRlbnNpb25fbGl0ZSwgdW5pdHRlc3Q6OkZPUkVJR05fTElURV9CQVogICAgICApOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ltcG9ydF9lbnVtX2V4dGVuc2lvbl9saXRlICwgdW5pdHRlc3RfaW1wb3J0OjpJTVBPUlRfTElURV9CQVopOworCisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfaW50MzJfZXh0ZW5zaW9uX2xpdGUgICAsIDQwMSk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9pbnQ2NF9leHRlbnNpb25fbGl0ZSAgICwgNDAyKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3VpbnQzMl9leHRlbnNpb25fbGl0ZSAgLCA0MDMpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfdWludDY0X2V4dGVuc2lvbl9saXRlICAsIDQwNCk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zaW50MzJfZXh0ZW5zaW9uX2xpdGUgICwgNDA1KTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3NpbnQ2NF9leHRlbnNpb25fbGl0ZSAgLCA0MDYpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfZml4ZWQzMl9leHRlbnNpb25fbGl0ZSAsIDQwNyk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9maXhlZDY0X2V4dGVuc2lvbl9saXRlICwgNDA4KTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3NmaXhlZDMyX2V4dGVuc2lvbl9saXRlLCA0MDkpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfc2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUsIDQxMCk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9mbG9hdF9leHRlbnNpb25fbGl0ZSAgICwgNDExKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2RvdWJsZV9leHRlbnNpb25fbGl0ZSAgLCA0MTIpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfYm9vbF9leHRlbnNpb25fbGl0ZSAgICAsIGZhbHNlKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3N0cmluZ19leHRlbnNpb25fbGl0ZSAgLCAiNDE1Iik7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9ieXRlc19leHRlbnNpb25fbGl0ZSAgICwgIjQxNiIpOworCisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9uZXN0ZWRfZW51bV9leHRlbnNpb25fbGl0ZSAsIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlOjpGT08gKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2ZvcmVpZ25fZW51bV9leHRlbnNpb25fbGl0ZSwgdW5pdHRlc3Q6OkZPUkVJR05fTElURV9GT08gICAgICApOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfaW1wb3J0X2VudW1fZXh0ZW5zaW9uX2xpdGUgLCB1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9MSVRFX0ZPTyk7CisKKworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9uZW9mX3VpbnQzMl9leHRlbnNpb25fbGl0ZSwgNjAxKTsKKyAgbWVzc2FnZS0+TXV0YWJsZUV4dGVuc2lvbih1bml0dGVzdDo6b25lb2ZfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUpLT5zZXRfYmIoNjAyKTs7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b25lb2Zfc3RyaW5nX2V4dGVuc2lvbl9saXRlLCAiNjAzIik7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6b25lb2ZfYnl0ZXNfZXh0ZW5zaW9uX2xpdGUsICI2MDQiKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIFRlc3RVdGlsTGl0ZTo6TW9kaWZ5UmVwZWF0ZWRFeHRlbnNpb25zKAorICAgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9uc0xpdGUqIG1lc3NhZ2UpIHsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbnQzMl9leHRlbnNpb25fbGl0ZSAgICwgMSwgNTAxKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbnQ2NF9leHRlbnNpb25fbGl0ZSAgICwgMSwgNTAyKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF91aW50MzJfZXh0ZW5zaW9uX2xpdGUgICwgMSwgNTAzKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF91aW50NjRfZXh0ZW5zaW9uX2xpdGUgICwgMSwgNTA0KTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50MzJfZXh0ZW5zaW9uX2xpdGUgICwgMSwgNTA1KTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50NjRfZXh0ZW5zaW9uX2xpdGUgICwgMSwgNTA2KTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9maXhlZDMyX2V4dGVuc2lvbl9saXRlICwgMSwgNTA3KTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9maXhlZDY0X2V4dGVuc2lvbl9saXRlICwgMSwgNTA4KTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zZml4ZWQzMl9leHRlbnNpb25fbGl0ZSwgMSwgNTA5KTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSwgMSwgNTEwKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9mbG9hdF9leHRlbnNpb25fbGl0ZSAgICwgMSwgNTExKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9kb3VibGVfZXh0ZW5zaW9uX2xpdGUgICwgMSwgNTEyKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9ib29sX2V4dGVuc2lvbl9saXRlICAgICwgMSwgdHJ1ZSk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc3RyaW5nX2V4dGVuc2lvbl9saXRlICAsIDEsICI1MTUiKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9ieXRlc19leHRlbnNpb25fbGl0ZSAgICwgMSwgIjUxNiIpOworCisgIG1lc3NhZ2UtPk11dGFibGVFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkZ3JvdXBfZXh0ZW5zaW9uX2xpdGUgICAgICAgICAgICwgMSktPnNldF9hKDUxNyk7CisgIG1lc3NhZ2UtPk11dGFibGVFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICwgMSktPnNldF9iYig1MTgpOworICBtZXNzYWdlLT5NdXRhYmxlRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUsIDEpLT5zZXRfYyg1MTkpOworICBtZXNzYWdlLT5NdXRhYmxlRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSAsIDEpLT5zZXRfZCg1MjApOworICBtZXNzYWdlLT5NdXRhYmxlRXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9sYXp5X21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUgICAsIDEpLT5zZXRfYmIoNTI3KTsKKworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9lbnVtX2V4dGVuc2lvbl9saXRlICwgMSwgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlc0xpdGU6OkZPTyApOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZvcmVpZ25fZW51bV9leHRlbnNpb25fbGl0ZSwgMSwgdW5pdHRlc3Q6OkZPUkVJR05fTElURV9GT08gICAgICApOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ltcG9ydF9lbnVtX2V4dGVuc2lvbl9saXRlICwgMSwgdW5pdHRlc3RfaW1wb3J0OjpJTVBPUlRfTElURV9GT08pOworCit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBUZXN0VXRpbExpdGU6OkV4cGVjdEFsbEV4dGVuc2lvbnNTZXQoCisgICAgY29uc3QgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zTGl0ZSYgbWVzc2FnZSkgeworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW50MzJfZXh0ZW5zaW9uX2xpdGUgICApKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ludDY0X2V4dGVuc2lvbl9saXRlICAgKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF91aW50MzJfZXh0ZW5zaW9uX2xpdGUgICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfdWludDY0X2V4dGVuc2lvbl9saXRlICApKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3NpbnQzMl9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9zaW50NjRfZXh0ZW5zaW9uX2xpdGUgICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZml4ZWQzMl9leHRlbnNpb25fbGl0ZSApKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUgKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9zZml4ZWQzMl9leHRlbnNpb25fbGl0ZSkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2Zsb2F0X2V4dGVuc2lvbl9saXRlICAgKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9kb3VibGVfZXh0ZW5zaW9uX2xpdGUgICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfYm9vbF9leHRlbnNpb25fbGl0ZSAgICApKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3N0cmluZ19leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9ieXRlc19leHRlbnNpb25fbGl0ZSAgICkpOworCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbGdyb3VwX2V4dGVuc2lvbl9saXRlICAgICAgICAgICAgICAgICApKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICAgICAgICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICAgICAgKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSAgICAgICApKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfbGF6eV9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICAgICAgICAgKSk7CisKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsZ3JvdXBfZXh0ZW5zaW9uX2xpdGUgICAgICAgICAgICAgICAgICkuaGFzX2EoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSAgICAgICApLmhhc19iYigpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb25fbGl0ZSAgICAgICkuaGFzX2MoKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSAgICAgICApLmhhc19kKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbl9saXRlKS5oYXNfZSgpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2xhenlfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSAgICAgICAgICkuaGFzX2JiKCkpOworCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9uZXN0ZWRfZW51bV9leHRlbnNpb25fbGl0ZSApKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ZvcmVpZ25fZW51bV9leHRlbnNpb25fbGl0ZSkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW1wb3J0X2VudW1fZXh0ZW5zaW9uX2xpdGUgKSk7CisKKworICBFWFBFQ1RfRVEoMTAxICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbnQzMl9leHRlbnNpb25fbGl0ZSAgICkpOworICBFWFBFQ1RfRVEoMTAyICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbnQ2NF9leHRlbnNpb25fbGl0ZSAgICkpOworICBFWFBFQ1RfRVEoMTAzICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF91aW50MzJfZXh0ZW5zaW9uX2xpdGUgICkpOworICBFWFBFQ1RfRVEoMTA0ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF91aW50NjRfZXh0ZW5zaW9uX2xpdGUgICkpOworICBFWFBFQ1RfRVEoMTA1ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9zaW50MzJfZXh0ZW5zaW9uX2xpdGUgICkpOworICBFWFBFQ1RfRVEoMTA2ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9zaW50NjRfZXh0ZW5zaW9uX2xpdGUgICkpOworICBFWFBFQ1RfRVEoMTA3ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9maXhlZDMyX2V4dGVuc2lvbl9saXRlICkpOworICBFWFBFQ1RfRVEoMTA4ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9maXhlZDY0X2V4dGVuc2lvbl9saXRlICkpOworICBFWFBFQ1RfRVEoMTA5ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9zZml4ZWQzMl9leHRlbnNpb25fbGl0ZSkpOworICBFWFBFQ1RfRVEoMTEwICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9zZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSkpOworICBFWFBFQ1RfRVEoMTExICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9mbG9hdF9leHRlbnNpb25fbGl0ZSAgICkpOworICBFWFBFQ1RfRVEoMTEyICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9kb3VibGVfZXh0ZW5zaW9uX2xpdGUgICkpOworICBFWFBFQ1RfRVEodHJ1ZSAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9ib29sX2V4dGVuc2lvbl9saXRlICAgICkpOworICBFWFBFQ1RfRVEoIjExNSIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9zdHJpbmdfZXh0ZW5zaW9uX2xpdGUgICkpOworICBFWFBFQ1RfRVEoIjExNiIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9ieXRlc19leHRlbnNpb25fbGl0ZSAgICkpOworCisgIEVYUEVDVF9FUSgxMTcsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbGdyb3VwX2V4dGVuc2lvbl9saXRlICAgICAgICAgICAgICAgICApLmEoKSk7CisgIEVYUEVDVF9FUSgxMTgsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSAgICAgICApLmJiKCkpOworICBFWFBFQ1RfRVEoMTE5LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICAgICAgKS5jKCkpOworICBFWFBFQ1RfRVEoMTIwLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUgICAgICAgKS5kKCkpOworICBFWFBFQ1RfRVEoMTI2LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbl9saXRlKS5lKCkpOworICBFWFBFQ1RfRVEoMTI3LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfbGF6eV9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICAgICAgICAgKS5iYigpKTsKKworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RBbGxUeXBlc0xpdGU6OkJBWiAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9uZXN0ZWRfZW51bV9leHRlbnNpb25fbGl0ZSApKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0xJVEVfQkFaICAgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbl9saXRlKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9MSVRFX0JBWiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ltcG9ydF9lbnVtX2V4dGVuc2lvbl9saXRlICkpOworCisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbnQzMl9leHRlbnNpb25fbGl0ZSAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbnQ2NF9leHRlbnNpb25fbGl0ZSAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF91aW50MzJfZXh0ZW5zaW9uX2xpdGUgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF91aW50NjRfZXh0ZW5zaW9uX2xpdGUgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50MzJfZXh0ZW5zaW9uX2xpdGUgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50NjRfZXh0ZW5zaW9uX2xpdGUgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9maXhlZDMyX2V4dGVuc2lvbl9saXRlICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9maXhlZDY0X2V4dGVuc2lvbl9saXRlICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9zZml4ZWQzMl9leHRlbnNpb25fbGl0ZSkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9zZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9mbG9hdF9leHRlbnNpb25fbGl0ZSAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9kb3VibGVfZXh0ZW5zaW9uX2xpdGUgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9ib29sX2V4dGVuc2lvbl9saXRlICAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9zdHJpbmdfZXh0ZW5zaW9uX2xpdGUgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9ieXRlc19leHRlbnNpb25fbGl0ZSAgICkpOworCisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkZ3JvdXBfZXh0ZW5zaW9uX2xpdGUgICAgICAgICAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbl9saXRlKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9sYXp5X21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUgICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uX2xpdGUgICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ZvcmVpZ25fZW51bV9leHRlbnNpb25fbGl0ZSAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbXBvcnRfZW51bV9leHRlbnNpb25fbGl0ZSAgICApKTsKKworCisgIEVYUEVDVF9FUSgyMDEgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ludDMyX2V4dGVuc2lvbl9saXRlICAgLCAwKSk7CisgIEVYUEVDVF9FUSgyMDIgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ludDY0X2V4dGVuc2lvbl9saXRlICAgLCAwKSk7CisgIEVYUEVDVF9FUSgyMDMgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3VpbnQzMl9leHRlbnNpb25fbGl0ZSAgLCAwKSk7CisgIEVYUEVDVF9FUSgyMDQgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3VpbnQ2NF9leHRlbnNpb25fbGl0ZSAgLCAwKSk7CisgIEVYUEVDVF9FUSgyMDUgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NpbnQzMl9leHRlbnNpb25fbGl0ZSAgLCAwKSk7CisgIEVYUEVDVF9FUSgyMDYgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NpbnQ2NF9leHRlbnNpb25fbGl0ZSAgLCAwKSk7CisgIEVYUEVDVF9FUSgyMDcgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUgLCAwKSk7CisgIEVYUEVDVF9FUSgyMDggICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUgLCAwKSk7CisgIEVYUEVDVF9FUSgyMDkgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NmaXhlZDMyX2V4dGVuc2lvbl9saXRlLCAwKSk7CisgIEVYUEVDVF9FUSgyMTAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NmaXhlZDY0X2V4dGVuc2lvbl9saXRlLCAwKSk7CisgIEVYUEVDVF9FUSgyMTEgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2Zsb2F0X2V4dGVuc2lvbl9saXRlICAgLCAwKSk7CisgIEVYUEVDVF9FUSgyMTIgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2RvdWJsZV9leHRlbnNpb25fbGl0ZSAgLCAwKSk7CisgIEVYUEVDVF9FUSh0cnVlICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2Jvb2xfZXh0ZW5zaW9uX2xpdGUgICAgLCAwKSk7CisgIEVYUEVDVF9FUSgiMjE1IiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb25fbGl0ZSAgLCAwKSk7CisgIEVYUEVDVF9FUSgiMjE2IiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2J5dGVzX2V4dGVuc2lvbl9saXRlICAgLCAwKSk7CisKKyAgRVhQRUNUX0VRKDIxNywgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkZ3JvdXBfZXh0ZW5zaW9uX2xpdGUgICAgICAgICAgICwgMCkuYSgpKTsKKyAgRVhQRUNUX0VRKDIxOCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICwgMCkuYmIoKSk7CisgIEVYUEVDVF9FUSgyMTksIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUsIDApLmMoKSk7CisgIEVYUEVDVF9FUSgyMjAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSAsIDApLmQoKSk7CisgIEVYUEVDVF9FUSgyMjcsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9sYXp5X21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUgICAsIDApLmJiKCkpOworCisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzTGl0ZTo6QkFSICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9lbnVtX2V4dGVuc2lvbl9saXRlICwgMCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fTElURV9CQVIgICAgICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uX2xpdGUsIDApKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0X2ltcG9ydDo6SU1QT1JUX0xJVEVfQkFSLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW1wb3J0X2VudW1fZXh0ZW5zaW9uX2xpdGUgLCAwKSk7CisKKworICBFWFBFQ1RfRVEoMzAxICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbnQzMl9leHRlbnNpb25fbGl0ZSAgICwgMSkpOworICBFWFBFQ1RfRVEoMzAyICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbnQ2NF9leHRlbnNpb25fbGl0ZSAgICwgMSkpOworICBFWFBFQ1RfRVEoMzAzICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF91aW50MzJfZXh0ZW5zaW9uX2xpdGUgICwgMSkpOworICBFWFBFQ1RfRVEoMzA0ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF91aW50NjRfZXh0ZW5zaW9uX2xpdGUgICwgMSkpOworICBFWFBFQ1RfRVEoMzA1ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50MzJfZXh0ZW5zaW9uX2xpdGUgICwgMSkpOworICBFWFBFQ1RfRVEoMzA2ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50NjRfZXh0ZW5zaW9uX2xpdGUgICwgMSkpOworICBFWFBFQ1RfRVEoMzA3ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9maXhlZDMyX2V4dGVuc2lvbl9saXRlICwgMSkpOworICBFWFBFQ1RfRVEoMzA4ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9maXhlZDY0X2V4dGVuc2lvbl9saXRlICwgMSkpOworICBFWFBFQ1RfRVEoMzA5ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zZml4ZWQzMl9leHRlbnNpb25fbGl0ZSwgMSkpOworICBFWFBFQ1RfRVEoMzEwICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSwgMSkpOworICBFWFBFQ1RfRVEoMzExICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9mbG9hdF9leHRlbnNpb25fbGl0ZSAgICwgMSkpOworICBFWFBFQ1RfRVEoMzEyICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9kb3VibGVfZXh0ZW5zaW9uX2xpdGUgICwgMSkpOworICBFWFBFQ1RfRVEoZmFsc2UsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9ib29sX2V4dGVuc2lvbl9saXRlICAgICwgMSkpOworICBFWFBFQ1RfRVEoIjMxNSIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9zdHJpbmdfZXh0ZW5zaW9uX2xpdGUgICwgMSkpOworICBFWFBFQ1RfRVEoIjMxNiIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9ieXRlc19leHRlbnNpb25fbGl0ZSAgICwgMSkpOworCisgIEVYUEVDVF9FUSgzMTcsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZGdyb3VwX2V4dGVuc2lvbl9saXRlICAgICAgICAgICAsIDEpLmEoKSk7CisgIEVYUEVDVF9FUSgzMTgsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSAsIDEpLmJiKCkpOworICBFWFBFQ1RfRVEoMzE5LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbl9saXRlLCAxKS5jKCkpOworICBFWFBFQ1RfRVEoMzIwLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUgLCAxKS5kKCkpOworICBFWFBFQ1RfRVEoMzI3LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbGF6eV9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICAgLCAxKS5iYigpKTsKKworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RBbGxUeXBlc0xpdGU6OkJBWiAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9uZXN0ZWRfZW51bV9leHRlbnNpb25fbGl0ZSAsIDEpKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0xJVEVfQkFaICAgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbl9saXRlLCAxKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9MSVRFX0JBWiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ltcG9ydF9lbnVtX2V4dGVuc2lvbl9saXRlICwgMSkpOworCisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9pbnQzMl9leHRlbnNpb25fbGl0ZSAgICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9pbnQ2NF9leHRlbnNpb25fbGl0ZSAgICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF91aW50MzJfZXh0ZW5zaW9uX2xpdGUgICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF91aW50NjRfZXh0ZW5zaW9uX2xpdGUgICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zaW50MzJfZXh0ZW5zaW9uX2xpdGUgICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zaW50NjRfZXh0ZW5zaW9uX2xpdGUgICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9maXhlZDMyX2V4dGVuc2lvbl9saXRlICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9maXhlZDY0X2V4dGVuc2lvbl9saXRlICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zZml4ZWQzMl9leHRlbnNpb25fbGl0ZSkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9mbG9hdF9leHRlbnNpb25fbGl0ZSAgICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9kb3VibGVfZXh0ZW5zaW9uX2xpdGUgICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9ib29sX2V4dGVuc2lvbl9saXRlICAgICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zdHJpbmdfZXh0ZW5zaW9uX2xpdGUgICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9ieXRlc19leHRlbnNpb25fbGl0ZSAgICkpOworCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X25lc3RlZF9lbnVtX2V4dGVuc2lvbl9saXRlICkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uX2xpdGUpKTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfaW1wb3J0X2VudW1fZXh0ZW5zaW9uX2xpdGUgKSk7CisKKworICBFWFBFQ1RfRVEoNDAxICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2ludDMyX2V4dGVuc2lvbl9saXRlICAgKSk7CisgIEVYUEVDVF9FUSg0MDIgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfaW50NjRfZXh0ZW5zaW9uX2xpdGUgICApKTsKKyAgRVhQRUNUX0VRKDQwMyAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF91aW50MzJfZXh0ZW5zaW9uX2xpdGUgICkpOworICBFWFBFQ1RfRVEoNDA0ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3VpbnQ2NF9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9FUSg0MDUgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfc2ludDMyX2V4dGVuc2lvbl9saXRlICApKTsKKyAgRVhQRUNUX0VRKDQwNiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zaW50NjRfZXh0ZW5zaW9uX2xpdGUgICkpOworICBFWFBFQ1RfRVEoNDA3ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUgKSk7CisgIEVYUEVDVF9FUSg0MDggICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSApKTsKKyAgRVhQRUNUX0VRKDQwOSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zZml4ZWQzMl9leHRlbnNpb25fbGl0ZSkpOworICBFWFBFQ1RfRVEoNDEwICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3NmaXhlZDY0X2V4dGVuc2lvbl9saXRlKSk7CisgIEVYUEVDVF9FUSg0MTEgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfZmxvYXRfZXh0ZW5zaW9uX2xpdGUgICApKTsKKyAgRVhQRUNUX0VRKDQxMiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9kb3VibGVfZXh0ZW5zaW9uX2xpdGUgICkpOworICBFWFBFQ1RfRVEoZmFsc2UsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2Jvb2xfZXh0ZW5zaW9uX2xpdGUgICAgKSk7CisgIEVYUEVDVF9FUSgiNDE1IiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfc3RyaW5nX2V4dGVuc2lvbl9saXRlICApKTsKKyAgRVhQRUNUX0VRKCI0MTYiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9ieXRlc19leHRlbnNpb25fbGl0ZSAgICkpOworCisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzTGl0ZTo6Rk9PICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uX2xpdGUgKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9SRUlHTl9MSVRFX0ZPTyAgICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbl9saXRlKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9MSVRFX0ZPTywgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfaW1wb3J0X2VudW1fZXh0ZW5zaW9uX2xpdGUgKSk7CisKKworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b25lb2ZfdWludDMyX2V4dGVuc2lvbl9saXRlKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvbmVvZl9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSkuaGFzX2JiKCkpOworICBFWFBFQ1RfVFJVRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b25lb2Zfc3RyaW5nX2V4dGVuc2lvbl9saXRlKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvbmVvZl9ieXRlc19leHRlbnNpb25fbGl0ZSkpOworCisgIEVYUEVDVF9FUSg2MDEsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvbmVvZl91aW50MzJfZXh0ZW5zaW9uX2xpdGUpKTsKKyAgRVhQRUNUX0VRKDYwMiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9uZW9mX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbl9saXRlKS5iYigpKTsKKyAgRVhQRUNUX0VRKCI2MDMiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b25lb2Zfc3RyaW5nX2V4dGVuc2lvbl9saXRlKSk7CisgIEVYUEVDVF9FUSgiNjA0IiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9uZW9mX2J5dGVzX2V4dGVuc2lvbl9saXRlKSk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBUZXN0VXRpbExpdGU6OkV4cGVjdEV4dGVuc2lvbnNDbGVhcigKKyAgICBjb25zdCB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnNMaXRlJiBtZXNzYWdlKSB7CisgIHN0cmluZyBzZXJpYWxpemVkOworICBBU1NFUlRfVFJVRShtZXNzYWdlLlNlcmlhbGl6ZVRvU3RyaW5nKCZzZXJpYWxpemVkKSk7CisgIEVYUEVDVF9FUSgiIiwgc2VyaWFsaXplZCk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkJ5dGVTaXplKCkpOworCisgIC8vIGhhc19ibGFoKCkgc2hvdWxkIGluaXRpYWxseSBiZSBmYWxzZSBmb3IgYWxsIG9wdGlvbmFsIGZpZWxkcy4KKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbnQzMl9leHRlbnNpb25fbGl0ZSAgICkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ludDY0X2V4dGVuc2lvbl9saXRlICAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfdWludDMyX2V4dGVuc2lvbl9saXRlICApKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF91aW50NjRfZXh0ZW5zaW9uX2xpdGUgICkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3NpbnQzMl9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc2ludDY0X2V4dGVuc2lvbl9saXRlICApKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9maXhlZDMyX2V4dGVuc2lvbl9saXRlICkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfc2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9zZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2Zsb2F0X2V4dGVuc2lvbl9saXRlICAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZG91YmxlX2V4dGVuc2lvbl9saXRlICApKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9ib29sX2V4dGVuc2lvbl9saXRlICAgICkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3N0cmluZ19leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfYnl0ZXNfZXh0ZW5zaW9uX2xpdGUgICApKTsKKworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsZ3JvdXBfZXh0ZW5zaW9uX2xpdGUgICAgICAgICAgICAgICAgICkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICAgICAgICkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb25fbGl0ZSAgICAgICkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICAgICAgICkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2xhenlfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSAgICAgICAgICkpOworCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfbmVzdGVkX2VudW1fZXh0ZW5zaW9uX2xpdGUgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbl9saXRlKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW1wb3J0X2VudW1fZXh0ZW5zaW9uX2xpdGUgKSk7CisKKworICAvLyBPcHRpb25hbCBmaWVsZHMgd2l0aG91dCBkZWZhdWx0cyBhcmUgc2V0IHRvIHplcm8gb3Igc29tZXRoaW5nIGxpa2UgaXQuCisgIEVYUEVDVF9FUSgwICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ludDMyX2V4dGVuc2lvbl9saXRlICAgKSk7CisgIEVYUEVDVF9FUSgwICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ludDY0X2V4dGVuc2lvbl9saXRlICAgKSk7CisgIEVYUEVDVF9FUSgwICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3VpbnQzMl9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9FUSgwICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3VpbnQ2NF9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9FUSgwICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3NpbnQzMl9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9FUSgwICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3NpbnQ2NF9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9FUSgwICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUgKSk7CisgIEVYUEVDVF9FUSgwICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUgKSk7CisgIEVYUEVDVF9FUSgwICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3NmaXhlZDMyX2V4dGVuc2lvbl9saXRlKSk7CisgIEVYUEVDVF9FUSgwICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3NmaXhlZDY0X2V4dGVuc2lvbl9saXRlKSk7CisgIEVYUEVDVF9FUSgwICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2Zsb2F0X2V4dGVuc2lvbl9saXRlICAgKSk7CisgIEVYUEVDVF9FUSgwICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2RvdWJsZV9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9FUShmYWxzZSwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2Jvb2xfZXh0ZW5zaW9uX2xpdGUgICAgKSk7CisgIEVYUEVDVF9FUSgiIiAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX3N0cmluZ19leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9FUSgiIiAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2J5dGVzX2V4dGVuc2lvbl9saXRlICAgKSk7CisKKyAgLy8gRW1iZWRkZWQgbWVzc2FnZXMgc2hvdWxkIGFsc28gYmUgY2xlYXIuCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxncm91cF9leHRlbnNpb25fbGl0ZSAgICAgICAgICAgICAgICAgKS5oYXNfYSgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSAgICAgICApLmhhc19iYigpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUgICAgICApLmhhc19jKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICAgICAgICkuaGFzX2QoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbl9saXRlKS5oYXNfZSgpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9sYXp5X21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUgICAgICAgICApLmhhc19iYigpKTsKKworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsZ3JvdXBfZXh0ZW5zaW9uX2xpdGUgICAgICAgICAgICAgICAgICkuYSgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSAgICAgICApLmJiKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb25fbGl0ZSAgICAgICkuYygpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSAgICAgICApLmQoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbl9saXRlKS5lKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2xhenlfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSAgICAgICAgICkuYmIoKSk7CisKKyAgLy8gRW51bXMgd2l0aG91dCBkZWZhdWx0cyBhcmUgc2V0IHRvIHRoZSBmaXJzdCB2YWx1ZSBpbiB0aGUgZW51bS4KKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlOjpGT08gLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfbmVzdGVkX2VudW1fZXh0ZW5zaW9uX2xpdGUgKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9SRUlHTl9MSVRFX0ZPTyAgICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ZvcmVpZ25fZW51bV9leHRlbnNpb25fbGl0ZSkpOworICBFWFBFQ1RfRVEodW5pdHRlc3RfaW1wb3J0OjpJTVBPUlRfTElURV9GT08sIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbXBvcnRfZW51bV9leHRlbnNpb25fbGl0ZSApKTsKKworCisgIC8vIFJlcGVhdGVkIGZpZWxkcyBhcmUgZW1wdHkuCisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ludDMyX2V4dGVuc2lvbl9saXRlICAgKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ludDY0X2V4dGVuc2lvbl9saXRlICAgKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3VpbnQzMl9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3VpbnQ2NF9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3NpbnQzMl9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3NpbnQ2NF9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUgKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUgKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3NmaXhlZDMyX2V4dGVuc2lvbl9saXRlKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3NmaXhlZDY0X2V4dGVuc2lvbl9saXRlKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2Zsb2F0X2V4dGVuc2lvbl9saXRlICAgKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2RvdWJsZV9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2Jvb2xfZXh0ZW5zaW9uX2xpdGUgICAgKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2J5dGVzX2V4dGVuc2lvbl9saXRlICAgKSk7CisKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRncm91cF9leHRlbnNpb25fbGl0ZSAgICAgICAgICAgKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUgKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2xhenlfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSAgICkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9uZXN0ZWRfZW51bV9leHRlbnNpb25fbGl0ZSAgICApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbl9saXRlICAgKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ltcG9ydF9lbnVtX2V4dGVuc2lvbl9saXRlICAgICkpOworCisKKyAgLy8gaGFzX2JsYWgoKSBzaG91bGQgYWxzbyBiZSBmYWxzZSBmb3IgYWxsIGRlZmF1bHQgZmllbGRzLgorICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfaW50MzJfZXh0ZW5zaW9uX2xpdGUgICApKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2ludDY0X2V4dGVuc2lvbl9saXRlICAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF91aW50MzJfZXh0ZW5zaW9uX2xpdGUgICkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfdWludDY0X2V4dGVuc2lvbl9saXRlICApKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3NpbnQzMl9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zaW50NjRfZXh0ZW5zaW9uX2xpdGUgICkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfZml4ZWQzMl9leHRlbnNpb25fbGl0ZSApKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zZml4ZWQzMl9leHRlbnNpb25fbGl0ZSkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfc2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2Zsb2F0X2V4dGVuc2lvbl9saXRlICAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9kb3VibGVfZXh0ZW5zaW9uX2xpdGUgICkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfYm9vbF9leHRlbnNpb25fbGl0ZSAgICApKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3N0cmluZ19leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9ieXRlc19leHRlbnNpb25fbGl0ZSAgICkpOworCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9uZXN0ZWRfZW51bV9leHRlbnNpb25fbGl0ZSApKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuSGFzRXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2ZvcmVpZ25fZW51bV9leHRlbnNpb25fbGl0ZSkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfaW1wb3J0X2VudW1fZXh0ZW5zaW9uX2xpdGUgKSk7CisKKworICAvLyBGaWVsZHMgd2l0aCBkZWZhdWx0cyBoYXZlIHRoZWlyIGRlZmF1bHQgdmFsdWVzIChkdWgpLgorICBFWFBFQ1RfRVEoIDQxICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfaW50MzJfZXh0ZW5zaW9uX2xpdGUgICApKTsKKyAgRVhQRUNUX0VRKCA0MiAgICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2ludDY0X2V4dGVuc2lvbl9saXRlICAgKSk7CisgIEVYUEVDVF9FUSggNDMgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF91aW50MzJfZXh0ZW5zaW9uX2xpdGUgICkpOworICBFWFBFQ1RfRVEoIDQ0ICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfdWludDY0X2V4dGVuc2lvbl9saXRlICApKTsKKyAgRVhQRUNUX0VRKC00NSAgICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3NpbnQzMl9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9FUSggNDYgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zaW50NjRfZXh0ZW5zaW9uX2xpdGUgICkpOworICBFWFBFQ1RfRVEoIDQ3ICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfZml4ZWQzMl9leHRlbnNpb25fbGl0ZSApKTsKKyAgRVhQRUNUX0VRKCA0OCAgICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUgKSk7CisgIEVYUEVDVF9FUSggNDkgICAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9zZml4ZWQzMl9leHRlbnNpb25fbGl0ZSkpOworICBFWFBFQ1RfRVEoLTUwICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfc2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUpKTsKKyAgRVhQRUNUX0VRKCA1MS41ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X2Zsb2F0X2V4dGVuc2lvbl9saXRlICAgKSk7CisgIEVYUEVDVF9FUSggNTJlMyAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9kb3VibGVfZXh0ZW5zaW9uX2xpdGUgICkpOworICBFWFBFQ1RfRVEodHJ1ZSAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfYm9vbF9leHRlbnNpb25fbGl0ZSAgICApKTsKKyAgRVhQRUNUX0VRKCJoZWxsbyIsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpkZWZhdWx0X3N0cmluZ19leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9FUSgid29ybGQiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6ZGVmYXVsdF9ieXRlc19leHRlbnNpb25fbGl0ZSAgICkpOworCisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzTGl0ZTo6QkFSICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uX2xpdGUgKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9SRUlHTl9MSVRFX0JBUiAgICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbl9saXRlKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdF9pbXBvcnQ6OklNUE9SVF9MSVRFX0JBUiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OmRlZmF1bHRfaW1wb3J0X2VudW1fZXh0ZW5zaW9uX2xpdGUgKSk7CisKKworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5IYXNFeHRlbnNpb24odW5pdHRlc3Q6Om9uZW9mX3VpbnQzMl9leHRlbnNpb25fbGl0ZSkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9uZW9mX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbl9saXRlKS5oYXNfYmIoKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b25lb2Zfc3RyaW5nX2V4dGVuc2lvbl9saXRlKSk7CisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLkhhc0V4dGVuc2lvbih1bml0dGVzdDo6b25lb2ZfYnl0ZXNfZXh0ZW5zaW9uX2xpdGUpKTsKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2b2lkIFRlc3RVdGlsTGl0ZTo6RXhwZWN0UmVwZWF0ZWRFeHRlbnNpb25zTW9kaWZpZWQoCisgICAgY29uc3QgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zTGl0ZSYgbWVzc2FnZSkgeworICAvLyBNb2RpZnlSZXBlYXRlZEZpZWxkcyBvbmx5IHNldHMgdGhlIHNlY29uZCByZXBlYXRlZCBlbGVtZW50IG9mIGVhY2gKKyAgLy8gZmllbGQuICBJbiBhZGRpdGlvbiB0byB2ZXJpZnlpbmcgdGhpcywgd2UgYWxzbyB2ZXJpZnkgdGhhdCB0aGUgZmlyc3QKKyAgLy8gZWxlbWVudCBhbmQgc2l6ZSB3ZXJlICpub3QqIG1vZGlmaWVkLgorICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbnQzMl9leHRlbnNpb25fbGl0ZSAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbnQ2NF9leHRlbnNpb25fbGl0ZSAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF91aW50MzJfZXh0ZW5zaW9uX2xpdGUgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF91aW50NjRfZXh0ZW5zaW9uX2xpdGUgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50MzJfZXh0ZW5zaW9uX2xpdGUgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9zaW50NjRfZXh0ZW5zaW9uX2xpdGUgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9maXhlZDMyX2V4dGVuc2lvbl9saXRlICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9maXhlZDY0X2V4dGVuc2lvbl9saXRlICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9zZml4ZWQzMl9leHRlbnNpb25fbGl0ZSkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9zZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9mbG9hdF9leHRlbnNpb25fbGl0ZSAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9kb3VibGVfZXh0ZW5zaW9uX2xpdGUgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9ib29sX2V4dGVuc2lvbl9saXRlICAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9zdHJpbmdfZXh0ZW5zaW9uX2xpdGUgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9ieXRlc19leHRlbnNpb25fbGl0ZSAgICkpOworCisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkZ3JvdXBfZXh0ZW5zaW9uX2xpdGUgICAgICAgICAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbl9saXRlKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9sYXp5X21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUgICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uX2xpdGUgICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnJlcGVhdGVkX2ZvcmVpZ25fZW51bV9leHRlbnNpb25fbGl0ZSAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbXBvcnRfZW51bV9leHRlbnNpb25fbGl0ZSAgICApKTsKKworCisgIEVYUEVDVF9FUSgyMDEgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ludDMyX2V4dGVuc2lvbl9saXRlICAgLCAwKSk7CisgIEVYUEVDVF9FUSgyMDIgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ludDY0X2V4dGVuc2lvbl9saXRlICAgLCAwKSk7CisgIEVYUEVDVF9FUSgyMDMgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3VpbnQzMl9leHRlbnNpb25fbGl0ZSAgLCAwKSk7CisgIEVYUEVDVF9FUSgyMDQgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3VpbnQ2NF9leHRlbnNpb25fbGl0ZSAgLCAwKSk7CisgIEVYUEVDVF9FUSgyMDUgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NpbnQzMl9leHRlbnNpb25fbGl0ZSAgLCAwKSk7CisgIEVYUEVDVF9FUSgyMDYgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NpbnQ2NF9leHRlbnNpb25fbGl0ZSAgLCAwKSk7CisgIEVYUEVDVF9FUSgyMDcgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUgLCAwKSk7CisgIEVYUEVDVF9FUSgyMDggICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUgLCAwKSk7CisgIEVYUEVDVF9FUSgyMDkgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NmaXhlZDMyX2V4dGVuc2lvbl9saXRlLCAwKSk7CisgIEVYUEVDVF9FUSgyMTAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3NmaXhlZDY0X2V4dGVuc2lvbl9saXRlLCAwKSk7CisgIEVYUEVDVF9FUSgyMTEgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2Zsb2F0X2V4dGVuc2lvbl9saXRlICAgLCAwKSk7CisgIEVYUEVDVF9FUSgyMTIgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2RvdWJsZV9leHRlbnNpb25fbGl0ZSAgLCAwKSk7CisgIEVYUEVDVF9FUSh0cnVlICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2Jvb2xfZXh0ZW5zaW9uX2xpdGUgICAgLCAwKSk7CisgIEVYUEVDVF9FUSgiMjE1IiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX3N0cmluZ19leHRlbnNpb25fbGl0ZSAgLCAwKSk7CisgIEVYUEVDVF9FUSgiMjE2IiwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2J5dGVzX2V4dGVuc2lvbl9saXRlICAgLCAwKSk7CisKKyAgRVhQRUNUX0VRKDIxNywgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkZ3JvdXBfZXh0ZW5zaW9uX2xpdGUgICAgICAgICAgICwgMCkuYSgpKTsKKyAgRVhQRUNUX0VRKDIxOCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICwgMCkuYmIoKSk7CisgIEVYUEVDVF9FUSgyMTksIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUsIDApLmMoKSk7CisgIEVYUEVDVF9FUSgyMjAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSAsIDApLmQoKSk7CisgIEVYUEVDVF9FUSgyMjcsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9sYXp5X21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUgICAsIDApLmJiKCkpOworCisgIEVYUEVDVF9FUSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzTGl0ZTo6QkFSICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9lbnVtX2V4dGVuc2lvbl9saXRlICwgMCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fTElURV9CQVIgICAgICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uX2xpdGUsIDApKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0X2ltcG9ydDo6SU1QT1JUX0xJVEVfQkFSLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW1wb3J0X2VudW1fZXh0ZW5zaW9uX2xpdGUgLCAwKSk7CisKKworICAvLyBBY3R1YWxseSB2ZXJpZnkgdGhlIHNlY29uZCAobW9kaWZpZWQpIGVsZW1lbnRzIG5vdy4KKyAgRVhQRUNUX0VRKDUwMSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9uX2xpdGUgICAsIDEpKTsKKyAgRVhQRUNUX0VRKDUwMiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfaW50NjRfZXh0ZW5zaW9uX2xpdGUgICAsIDEpKTsKKyAgRVhQRUNUX0VRKDUwMyAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfdWludDMyX2V4dGVuc2lvbl9saXRlICAsIDEpKTsKKyAgRVhQRUNUX0VRKDUwNCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfdWludDY0X2V4dGVuc2lvbl9saXRlICAsIDEpKTsKKyAgRVhQRUNUX0VRKDUwNSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ludDMyX2V4dGVuc2lvbl9saXRlICAsIDEpKTsKKyAgRVhQRUNUX0VRKDUwNiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ludDY0X2V4dGVuc2lvbl9saXRlICAsIDEpKTsKKyAgRVhQRUNUX0VRKDUwNyAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZml4ZWQzMl9leHRlbnNpb25fbGl0ZSAsIDEpKTsKKyAgRVhQRUNUX0VRKDUwOCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSAsIDEpKTsKKyAgRVhQRUNUX0VRKDUwOSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUsIDEpKTsKKyAgRVhQRUNUX0VRKDUxMCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUsIDEpKTsKKyAgRVhQRUNUX0VRKDUxMSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZmxvYXRfZXh0ZW5zaW9uX2xpdGUgICAsIDEpKTsKKyAgRVhQRUNUX0VRKDUxMiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfZG91YmxlX2V4dGVuc2lvbl9saXRlICAsIDEpKTsKKyAgRVhQRUNUX0VRKHRydWUgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfYm9vbF9leHRlbnNpb25fbGl0ZSAgICAsIDEpKTsKKyAgRVhQRUNUX0VRKCI1MTUiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfc3RyaW5nX2V4dGVuc2lvbl9saXRlICAsIDEpKTsKKyAgRVhQRUNUX0VRKCI1MTYiLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfYnl0ZXNfZXh0ZW5zaW9uX2xpdGUgICAsIDEpKTsKKworICBFWFBFQ1RfRVEoNTE3LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRncm91cF9leHRlbnNpb25fbGl0ZSAgICAgICAgICAgLCAxKS5hKCkpOworICBFWFBFQ1RfRVEoNTE4LCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uX2xpdGUgLCAxKS5iYigpKTsKKyAgRVhQRUNUX0VRKDUxOSwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb25fbGl0ZSwgMSkuYygpKTsKKyAgRVhQRUNUX0VRKDUyMCwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbl9saXRlICwgMSkuZCgpKTsKKyAgRVhQRUNUX0VRKDUyNywgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2xhenlfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSAgICwgMSkuYmIoKSk7CisKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlOjpGT08gLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uX2xpdGUgLCAxKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9SRUlHTl9MSVRFX0ZPTyAgICAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnJlcGVhdGVkX2ZvcmVpZ25fZW51bV9leHRlbnNpb25fbGl0ZSwgMSkpOworICBFWFBFQ1RfRVEodW5pdHRlc3RfaW1wb3J0OjpJTVBPUlRfTElURV9GT08sIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpyZXBlYXRlZF9pbXBvcnRfZW51bV9leHRlbnNpb25fbGl0ZSAsIDEpKTsKKworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3ZvaWQgVGVzdFV0aWxMaXRlOjpTZXRQYWNrZWRFeHRlbnNpb25zKAorICAgIHVuaXR0ZXN0OjpUZXN0UGFja2VkRXh0ZW5zaW9uc0xpdGUqIG1lc3NhZ2UpIHsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfaW50MzJfZXh0ZW5zaW9uX2xpdGUgICAsIDYwMSk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ludDY0X2V4dGVuc2lvbl9saXRlICAgLCA2MDIpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF91aW50MzJfZXh0ZW5zaW9uX2xpdGUgICwgNjAzKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfdWludDY0X2V4dGVuc2lvbl9saXRlICAsIDYwNCk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3NpbnQzMl9leHRlbnNpb25fbGl0ZSAgLCA2MDUpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9zaW50NjRfZXh0ZW5zaW9uX2xpdGUgICwgNjA2KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZml4ZWQzMl9leHRlbnNpb25fbGl0ZSAsIDYwNyk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUgLCA2MDgpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9zZml4ZWQzMl9leHRlbnNpb25fbGl0ZSwgNjA5KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfc2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUsIDYxMCk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2Zsb2F0X2V4dGVuc2lvbl9saXRlICAgLCA2MTEpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9kb3VibGVfZXh0ZW5zaW9uX2xpdGUgICwgNjEyKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfYm9vbF9leHRlbnNpb25fbGl0ZSAgICAsIHRydWUpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9lbnVtX2V4dGVuc2lvbl9saXRlLCB1bml0dGVzdDo6Rk9SRUlHTl9MSVRFX0JBUik7CisgIC8vIGFkZCBhIHNlY29uZCBvbmUgb2YgZWFjaCBmaWVsZAorICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9pbnQzMl9leHRlbnNpb25fbGl0ZSAgICwgNzAxKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfaW50NjRfZXh0ZW5zaW9uX2xpdGUgICAsIDcwMik7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3VpbnQzMl9leHRlbnNpb25fbGl0ZSAgLCA3MDMpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF91aW50NjRfZXh0ZW5zaW9uX2xpdGUgICwgNzA0KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfc2ludDMyX2V4dGVuc2lvbl9saXRlICAsIDcwNSk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3NpbnQ2NF9leHRlbnNpb25fbGl0ZSAgLCA3MDYpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9maXhlZDMyX2V4dGVuc2lvbl9saXRlICwgNzA3KTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSAsIDcwOCk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3NmaXhlZDMyX2V4dGVuc2lvbl9saXRlLCA3MDkpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9zZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSwgNzEwKTsKKyAgbWVzc2FnZS0+QWRkRXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZmxvYXRfZXh0ZW5zaW9uX2xpdGUgICAsIDcxMSk7CisgIG1lc3NhZ2UtPkFkZEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2RvdWJsZV9leHRlbnNpb25fbGl0ZSAgLCA3MTIpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9ib29sX2V4dGVuc2lvbl9saXRlICAgICwgZmFsc2UpOworICBtZXNzYWdlLT5BZGRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9lbnVtX2V4dGVuc2lvbl9saXRlLCB1bml0dGVzdDo6Rk9SRUlHTl9MSVRFX0JBWik7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBUZXN0VXRpbExpdGU6Ok1vZGlmeVBhY2tlZEV4dGVuc2lvbnMoCisgICAgdW5pdHRlc3Q6OlRlc3RQYWNrZWRFeHRlbnNpb25zTGl0ZSogbWVzc2FnZSkgeworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9pbnQzMl9leHRlbnNpb25fbGl0ZSAgICwgMSwgODAxKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfaW50NjRfZXh0ZW5zaW9uX2xpdGUgICAsIDEsIDgwMik7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3VpbnQzMl9leHRlbnNpb25fbGl0ZSAgLCAxLCA4MDMpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF91aW50NjRfZXh0ZW5zaW9uX2xpdGUgICwgMSwgODA0KTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfc2ludDMyX2V4dGVuc2lvbl9saXRlICAsIDEsIDgwNSk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3NpbnQ2NF9leHRlbnNpb25fbGl0ZSAgLCAxLCA4MDYpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9maXhlZDMyX2V4dGVuc2lvbl9saXRlICwgMSwgODA3KTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSAsIDEsIDgwOCk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3NmaXhlZDMyX2V4dGVuc2lvbl9saXRlLCAxLCA4MDkpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9zZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSwgMSwgODEwKTsKKyAgbWVzc2FnZS0+U2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZmxvYXRfZXh0ZW5zaW9uX2xpdGUgICAsIDEsIDgxMSk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2RvdWJsZV9leHRlbnNpb25fbGl0ZSAgLCAxLCA4MTIpOworICBtZXNzYWdlLT5TZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9ib29sX2V4dGVuc2lvbl9saXRlICAgICwgMSwgdHJ1ZSk7CisgIG1lc3NhZ2UtPlNldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2VudW1fZXh0ZW5zaW9uX2xpdGUgICAgLCAxLAorICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHRlc3Q6OkZPUkVJR05fTElURV9GT08pOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3ZvaWQgVGVzdFV0aWxMaXRlOjpFeHBlY3RQYWNrZWRFeHRlbnNpb25zU2V0KAorICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0UGFja2VkRXh0ZW5zaW9uc0xpdGUmIG1lc3NhZ2UpIHsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX2ludDMyX2V4dGVuc2lvbl9saXRlICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9pbnQ2NF9leHRlbnNpb25fbGl0ZSAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfdWludDMyX2V4dGVuc2lvbl9saXRlICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX3VpbnQ2NF9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9zaW50MzJfZXh0ZW5zaW9uX2xpdGUgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfc2ludDY0X2V4dGVuc2lvbl9saXRlICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9maXhlZDY0X2V4dGVuc2lvbl9saXRlICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUpKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX3NmaXhlZDY0X2V4dGVuc2lvbl9saXRlKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9mbG9hdF9leHRlbnNpb25fbGl0ZSAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfZG91YmxlX2V4dGVuc2lvbl9saXRlICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX2Jvb2xfZXh0ZW5zaW9uX2xpdGUgICAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9lbnVtX2V4dGVuc2lvbl9saXRlICAgICkpOworCisgIEVYUEVDVF9FUSg2MDEgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9pbnQzMl9leHRlbnNpb25fbGl0ZSAgICwgMCkpOworICBFWFBFQ1RfRVEoNjAyICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfaW50NjRfZXh0ZW5zaW9uX2xpdGUgICAsIDApKTsKKyAgRVhQRUNUX0VRKDYwMyAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3VpbnQzMl9leHRlbnNpb25fbGl0ZSAgLCAwKSk7CisgIEVYUEVDVF9FUSg2MDQgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF91aW50NjRfZXh0ZW5zaW9uX2xpdGUgICwgMCkpOworICBFWFBFQ1RfRVEoNjA1ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfc2ludDMyX2V4dGVuc2lvbl9saXRlICAsIDApKTsKKyAgRVhQRUNUX0VRKDYwNiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3NpbnQ2NF9leHRlbnNpb25fbGl0ZSAgLCAwKSk7CisgIEVYUEVDVF9FUSg2MDcgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9maXhlZDMyX2V4dGVuc2lvbl9saXRlICwgMCkpOworICBFWFBFQ1RfRVEoNjA4ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSAsIDApKTsKKyAgRVhQRUNUX0VRKDYwOSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3NmaXhlZDMyX2V4dGVuc2lvbl9saXRlLCAwKSk7CisgIEVYUEVDVF9FUSg2MTAgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9zZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSwgMCkpOworICBFWFBFQ1RfRVEoNjExICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZmxvYXRfZXh0ZW5zaW9uX2xpdGUgICAsIDApKTsKKyAgRVhQRUNUX0VRKDYxMiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2RvdWJsZV9leHRlbnNpb25fbGl0ZSAgLCAwKSk7CisgIEVYUEVDVF9FUSh0cnVlICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9ib29sX2V4dGVuc2lvbl9saXRlICAgICwgMCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OkZPUkVJR05fTElURV9CQVIsCisgICAgICAgICAgICBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2VudW1fZXh0ZW5zaW9uX2xpdGUsIDApKTsKKyAgRVhQRUNUX0VRKDcwMSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ludDMyX2V4dGVuc2lvbl9saXRlICAgLCAxKSk7CisgIEVYUEVDVF9FUSg3MDIgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9pbnQ2NF9leHRlbnNpb25fbGl0ZSAgICwgMSkpOworICBFWFBFQ1RfRVEoNzAzICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfdWludDMyX2V4dGVuc2lvbl9saXRlICAsIDEpKTsKKyAgRVhQRUNUX0VRKDcwNCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3VpbnQ2NF9leHRlbnNpb25fbGl0ZSAgLCAxKSk7CisgIEVYUEVDVF9FUSg3MDUgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9zaW50MzJfZXh0ZW5zaW9uX2xpdGUgICwgMSkpOworICBFWFBFQ1RfRVEoNzA2ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfc2ludDY0X2V4dGVuc2lvbl9saXRlICAsIDEpKTsKKyAgRVhQRUNUX0VRKDcwNyAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUgLCAxKSk7CisgIEVYUEVDVF9FUSg3MDggICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9maXhlZDY0X2V4dGVuc2lvbl9saXRlICwgMSkpOworICBFWFBFQ1RfRVEoNzA5ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUsIDEpKTsKKyAgRVhQRUNUX0VRKDcxMCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3NmaXhlZDY0X2V4dGVuc2lvbl9saXRlLCAxKSk7CisgIEVYUEVDVF9FUSg3MTEgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9mbG9hdF9leHRlbnNpb25fbGl0ZSAgICwgMSkpOworICBFWFBFQ1RfRVEoNzEyICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZG91YmxlX2V4dGVuc2lvbl9saXRlICAsIDEpKTsKKyAgRVhQRUNUX0VRKGZhbHNlLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2Jvb2xfZXh0ZW5zaW9uX2xpdGUgICAgLCAxKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9SRUlHTl9MSVRFX0JBWiwKKyAgICAgICAgICAgIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZW51bV9leHRlbnNpb25fbGl0ZSwgMSkpOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK3ZvaWQgVGVzdFV0aWxMaXRlOjpFeHBlY3RQYWNrZWRFeHRlbnNpb25zQ2xlYXIoCisgICAgY29uc3QgdW5pdHRlc3Q6OlRlc3RQYWNrZWRFeHRlbnNpb25zTGl0ZSYgbWVzc2FnZSkgeworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfaW50MzJfZXh0ZW5zaW9uX2xpdGUgICApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX2ludDY0X2V4dGVuc2lvbl9saXRlICAgKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF91aW50MzJfZXh0ZW5zaW9uX2xpdGUgICkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfdWludDY0X2V4dGVuc2lvbl9saXRlICApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX3NpbnQzMl9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9zaW50NjRfZXh0ZW5zaW9uX2xpdGUgICkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfZml4ZWQzMl9leHRlbnNpb25fbGl0ZSApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUgKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9zZml4ZWQzMl9leHRlbnNpb25fbGl0ZSkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfc2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX2Zsb2F0X2V4dGVuc2lvbl9saXRlICAgKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9kb3VibGVfZXh0ZW5zaW9uX2xpdGUgICkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfYm9vbF9leHRlbnNpb25fbGl0ZSAgICApKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX2VudW1fZXh0ZW5zaW9uX2xpdGUgICAgKSk7Cit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwordm9pZCBUZXN0VXRpbExpdGU6OkV4cGVjdFBhY2tlZEV4dGVuc2lvbnNNb2RpZmllZCgKKyAgICBjb25zdCB1bml0dGVzdDo6VGVzdFBhY2tlZEV4dGVuc2lvbnNMaXRlJiBtZXNzYWdlKSB7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9pbnQzMl9leHRlbnNpb25fbGl0ZSAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfaW50NjRfZXh0ZW5zaW9uX2xpdGUgICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX3VpbnQzMl9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF91aW50NjRfZXh0ZW5zaW9uX2xpdGUgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfc2ludDMyX2V4dGVuc2lvbl9saXRlICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX3NpbnQ2NF9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9maXhlZDMyX2V4dGVuc2lvbl9saXRlICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX3NmaXhlZDMyX2V4dGVuc2lvbl9saXRlKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9zZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfZmxvYXRfZXh0ZW5zaW9uX2xpdGUgICApKTsKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UuRXh0ZW5zaW9uU2l6ZSh1bml0dGVzdDo6cGFja2VkX2RvdWJsZV9leHRlbnNpb25fbGl0ZSAgKSk7CisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLkV4dGVuc2lvblNpemUodW5pdHRlc3Q6OnBhY2tlZF9ib29sX2V4dGVuc2lvbl9saXRlICAgICkpOworICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHVuaXR0ZXN0OjpwYWNrZWRfZW51bV9leHRlbnNpb25fbGl0ZSAgICApKTsKKyAgRVhQRUNUX0VRKDYwMSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ludDMyX2V4dGVuc2lvbl9saXRlICAgLCAwKSk7CisgIEVYUEVDVF9FUSg2MDIgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9pbnQ2NF9leHRlbnNpb25fbGl0ZSAgICwgMCkpOworICBFWFBFQ1RfRVEoNjAzICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfdWludDMyX2V4dGVuc2lvbl9saXRlICAsIDApKTsKKyAgRVhQRUNUX0VRKDYwNCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3VpbnQ2NF9leHRlbnNpb25fbGl0ZSAgLCAwKSk7CisgIEVYUEVDVF9FUSg2MDUgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9zaW50MzJfZXh0ZW5zaW9uX2xpdGUgICwgMCkpOworICBFWFBFQ1RfRVEoNjA2ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfc2ludDY0X2V4dGVuc2lvbl9saXRlICAsIDApKTsKKyAgRVhQRUNUX0VRKDYwNyAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUgLCAwKSk7CisgIEVYUEVDVF9FUSg2MDggICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9maXhlZDY0X2V4dGVuc2lvbl9saXRlICwgMCkpOworICBFWFBFQ1RfRVEoNjA5ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUsIDApKTsKKyAgRVhQRUNUX0VRKDYxMCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3NmaXhlZDY0X2V4dGVuc2lvbl9saXRlLCAwKSk7CisgIEVYUEVDVF9FUSg2MTEgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9mbG9hdF9leHRlbnNpb25fbGl0ZSAgICwgMCkpOworICBFWFBFQ1RfRVEoNjEyICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZG91YmxlX2V4dGVuc2lvbl9saXRlICAsIDApKTsKKyAgRVhQRUNUX0VRKHRydWUgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2Jvb2xfZXh0ZW5zaW9uX2xpdGUgICAgLCAwKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6Rk9SRUlHTl9MSVRFX0JBUiwKKyAgICAgICAgICAgIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZW51bV9leHRlbnNpb25fbGl0ZSwgMCkpOworCisgIC8vIEFjdHVhbGx5IHZlcmlmeSB0aGUgc2Vjb25kIChtb2RpZmllZCkgZWxlbWVudHMgbm93LgorICBFWFBFQ1RfRVEoODAxICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfaW50MzJfZXh0ZW5zaW9uX2xpdGUgICAsIDEpKTsKKyAgRVhQRUNUX0VRKDgwMiAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ludDY0X2V4dGVuc2lvbl9saXRlICAgLCAxKSk7CisgIEVYUEVDVF9FUSg4MDMgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF91aW50MzJfZXh0ZW5zaW9uX2xpdGUgICwgMSkpOworICBFWFBFQ1RfRVEoODA0ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfdWludDY0X2V4dGVuc2lvbl9saXRlICAsIDEpKTsKKyAgRVhQRUNUX0VRKDgwNSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX3NpbnQzMl9leHRlbnNpb25fbGl0ZSAgLCAxKSk7CisgIEVYUEVDVF9FUSg4MDYgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9zaW50NjRfZXh0ZW5zaW9uX2xpdGUgICwgMSkpOworICBFWFBFQ1RfRVEoODA3ICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfZml4ZWQzMl9leHRlbnNpb25fbGl0ZSAsIDEpKTsKKyAgRVhQRUNUX0VRKDgwOCAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUgLCAxKSk7CisgIEVYUEVDVF9FUSg4MDkgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9zZml4ZWQzMl9leHRlbnNpb25fbGl0ZSwgMSkpOworICBFWFBFQ1RfRVEoODEwICAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfc2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUsIDEpKTsKKyAgRVhQRUNUX0VRKDgxMSAgLCBtZXNzYWdlLkdldEV4dGVuc2lvbih1bml0dGVzdDo6cGFja2VkX2Zsb2F0X2V4dGVuc2lvbl9saXRlICAgLCAxKSk7CisgIEVYUEVDVF9FUSg4MTIgICwgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9kb3VibGVfZXh0ZW5zaW9uX2xpdGUgICwgMSkpOworICBFWFBFQ1RfRVEodHJ1ZSAsIG1lc3NhZ2UuR2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpwYWNrZWRfYm9vbF9leHRlbnNpb25fbGl0ZSAgICAsIDEpKTsKKyAgRVhQRUNUX0VRKHVuaXR0ZXN0OjpGT1JFSUdOX0xJVEVfRk9PLAorICAgICAgICAgICAgbWVzc2FnZS5HZXRFeHRlbnNpb24odW5pdHRlc3Q6OnBhY2tlZF9lbnVtX2V4dGVuc2lvbl9saXRlLCAxKSk7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0X3V0aWxfbGl0ZS5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0X3V0aWxfbGl0ZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ3YTIyNjkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RfdXRpbF9saXRlLmgKQEAgLTAsMCArMSwxMDEgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfVEVTVF9VVElMX0xJVEVfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9URVNUX1VUSUxfTElURV9IX18KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9saXRlLnBiLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworbmFtZXNwYWNlIHVuaXR0ZXN0ID0gcHJvdG9idWZfdW5pdHRlc3Q7CituYW1lc3BhY2UgdW5pdHRlc3RfaW1wb3J0ID0gcHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0OworCitjbGFzcyBUZXN0VXRpbExpdGUgeworIHB1YmxpYzoKKyAgLy8gU2V0IGV2ZXJ5IGZpZWxkIGluIHRoZSBtZXNzYWdlIHRvIGEgdW5pcXVlIHZhbHVlLgorICBzdGF0aWMgdm9pZCBTZXRBbGxGaWVsZHModW5pdHRlc3Q6OlRlc3RBbGxUeXBlc0xpdGUqIG1lc3NhZ2UpOworICBzdGF0aWMgdm9pZCBTZXRBbGxFeHRlbnNpb25zKHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9uc0xpdGUqIG1lc3NhZ2UpOworICBzdGF0aWMgdm9pZCBTZXRQYWNrZWRGaWVsZHModW5pdHRlc3Q6OlRlc3RQYWNrZWRUeXBlc0xpdGUqIG1lc3NhZ2UpOworICBzdGF0aWMgdm9pZCBTZXRQYWNrZWRFeHRlbnNpb25zKHVuaXR0ZXN0OjpUZXN0UGFja2VkRXh0ZW5zaW9uc0xpdGUqIG1lc3NhZ2UpOworCisgIC8vIFVzZSB0aGUgcmVwZWF0ZWQgdmVyc2lvbnMgb2YgdGhlIHNldF8qKCkgYWNjZXNzb3JzIHRvIG1vZGlmeSBhbGwgdGhlCisgIC8vIHJlcGVhdGVkIGZpZWxkcyBvZiB0aGUgbWVzc2FnZSAod2hpY2ggc2hvdWxkIGFscmVhZHkgaGF2ZSBiZWVuCisgIC8vIGluaXRpYWxpemVkIHdpdGggU2V0KkZpZWxkcygpKS4gIFNldCpGaWVsZHMoKSBpdHNlbGYgb25seSB0ZXN0cworICAvLyB0aGUgYWRkXyooKSBhY2Nlc3NvcnMuCisgIHN0YXRpYyB2b2lkIE1vZGlmeVJlcGVhdGVkRmllbGRzKHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlKiBtZXNzYWdlKTsKKyAgc3RhdGljIHZvaWQgTW9kaWZ5UmVwZWF0ZWRFeHRlbnNpb25zKAorICAgICAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zTGl0ZSogbWVzc2FnZSk7CisgIHN0YXRpYyB2b2lkIE1vZGlmeVBhY2tlZEZpZWxkcyh1bml0dGVzdDo6VGVzdFBhY2tlZFR5cGVzTGl0ZSogbWVzc2FnZSk7CisgIHN0YXRpYyB2b2lkIE1vZGlmeVBhY2tlZEV4dGVuc2lvbnMoCisgICAgICB1bml0dGVzdDo6VGVzdFBhY2tlZEV4dGVuc2lvbnNMaXRlKiBtZXNzYWdlKTsKKworICAvLyBDaGVjayB0aGF0IGFsbCBmaWVsZHMgaGF2ZSB0aGUgdmFsdWVzIHRoYXQgdGhleSBzaG91bGQgaGF2ZSBhZnRlcgorICAvLyBTZXQqRmllbGRzKCkgaXMgY2FsbGVkLgorICBzdGF0aWMgdm9pZCBFeHBlY3RBbGxGaWVsZHNTZXQoY29uc3QgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlc0xpdGUmIG1lc3NhZ2UpOworICBzdGF0aWMgdm9pZCBFeHBlY3RBbGxFeHRlbnNpb25zU2V0KAorICAgICAgY29uc3QgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zTGl0ZSYgbWVzc2FnZSk7CisgIHN0YXRpYyB2b2lkIEV4cGVjdFBhY2tlZEZpZWxkc1NldCgKKyAgICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0UGFja2VkVHlwZXNMaXRlJiBtZXNzYWdlKTsKKyAgc3RhdGljIHZvaWQgRXhwZWN0UGFja2VkRXh0ZW5zaW9uc1NldCgKKyAgICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0UGFja2VkRXh0ZW5zaW9uc0xpdGUmIG1lc3NhZ2UpOworCisgIC8vIEV4cGVjdCB0aGF0IHRoZSBtZXNzYWdlIGlzIG1vZGlmaWVkIGFzIHdvdWxkIGJlIGV4cGVjdGVkIGZyb20KKyAgLy8gTW9kaWZ5KkZpZWxkcygpLgorICBzdGF0aWMgdm9pZCBFeHBlY3RSZXBlYXRlZEZpZWxkc01vZGlmaWVkKAorICAgICAgY29uc3QgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlc0xpdGUmIG1lc3NhZ2UpOworICBzdGF0aWMgdm9pZCBFeHBlY3RSZXBlYXRlZEV4dGVuc2lvbnNNb2RpZmllZCgKKyAgICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9uc0xpdGUmIG1lc3NhZ2UpOworICBzdGF0aWMgdm9pZCBFeHBlY3RQYWNrZWRGaWVsZHNNb2RpZmllZCgKKyAgICAgIGNvbnN0IHVuaXR0ZXN0OjpUZXN0UGFja2VkVHlwZXNMaXRlJiBtZXNzYWdlKTsKKyAgc3RhdGljIHZvaWQgRXhwZWN0UGFja2VkRXh0ZW5zaW9uc01vZGlmaWVkKAorICAgICAgY29uc3QgdW5pdHRlc3Q6OlRlc3RQYWNrZWRFeHRlbnNpb25zTGl0ZSYgbWVzc2FnZSk7CisKKyAgLy8gQ2hlY2sgdGhhdCBhbGwgZmllbGRzIGhhdmUgdGhlaXIgZGVmYXVsdCB2YWx1ZXMuCisgIHN0YXRpYyB2b2lkIEV4cGVjdENsZWFyKGNvbnN0IHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXNMaXRlJiBtZXNzYWdlKTsKKyAgc3RhdGljIHZvaWQgRXhwZWN0RXh0ZW5zaW9uc0NsZWFyKAorICAgICAgY29uc3QgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zTGl0ZSYgbWVzc2FnZSk7CisgIHN0YXRpYyB2b2lkIEV4cGVjdFBhY2tlZENsZWFyKGNvbnN0IHVuaXR0ZXN0OjpUZXN0UGFja2VkVHlwZXNMaXRlJiBtZXNzYWdlKTsKKyAgc3RhdGljIHZvaWQgRXhwZWN0UGFja2VkRXh0ZW5zaW9uc0NsZWFyKAorICAgICAgY29uc3QgdW5pdHRlc3Q6OlRlc3RQYWNrZWRFeHRlbnNpb25zTGl0ZSYgbWVzc2FnZSk7CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoVGVzdFV0aWxMaXRlKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9URVNUX1VUSUxfTElURV9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGRhdGEvYmFkX3V0Zjhfc3RyaW5nIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0ZGF0YS9iYWRfdXRmOF9zdHJpbmcKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTEzMzdlYwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGRhdGEvYmFkX3V0Zjhfc3RyaW5nCkBAIC0wLDAgKzEgQEAKK3IB/wpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGRhdGEvZ29sZGVuX21lc3NhZ2UgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RkYXRhL2dvbGRlbl9tZXNzYWdlCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBiN2U2NTUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RkYXRhL2dvbGRlbl9tZXNzYWdlCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGRhdGEvZ29sZGVuX21lc3NhZ2Vfb25lb2ZfaW1wbGVtZW50ZWQgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RkYXRhL2dvbGRlbl9tZXNzYWdlX29uZW9mX2ltcGxlbWVudGVkCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI0OGM4OTgKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RkYXRhL2dvbGRlbl9tZXNzYWdlX29uZW9mX2ltcGxlbWVudGVkCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGRhdGEvZ29sZGVuX21lc3NhZ2VfcHJvdG8zIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0ZGF0YS9nb2xkZW5fbWVzc2FnZV9wcm90bzMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmQ2NDZhMAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGRhdGEvZ29sZGVuX21lc3NhZ2VfcHJvdG8zCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGRhdGEvZ29sZGVuX3BhY2tlZF9maWVsZHNfbWVzc2FnZSBiL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGRhdGEvZ29sZGVuX3BhY2tlZF9maWVsZHNfbWVzc2FnZQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lZTI4ZDM4Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0ZGF0YS9nb2xkZW5fcGFja2VkX2ZpZWxkc19tZXNzYWdlCkJpbmFyeSBmaWxlcyBkaWZmZXIKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGRhdGEvbWFwX3Rlc3RfZGF0YS50eHQgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RkYXRhL21hcF90ZXN0X2RhdGEudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJjMjcyMzIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RkYXRhL21hcF90ZXN0X2RhdGEudHh0CkBAIC0wLDAgKzEsMTQwIEBACittYXBfaW50MzJfaW50MzIgeworICBrZXk6IDAKKyAgdmFsdWU6IDAKK30KK21hcF9pbnQzMl9pbnQzMiB7CisgIGtleTogMQorICB2YWx1ZTogMQorfQorbWFwX2ludDY0X2ludDY0IHsKKyAga2V5OiAwCisgIHZhbHVlOiAwCit9CittYXBfaW50NjRfaW50NjQgeworICBrZXk6IDEKKyAgdmFsdWU6IDEKK30KK21hcF91aW50MzJfdWludDMyIHsKKyAga2V5OiAwCisgIHZhbHVlOiAwCit9CittYXBfdWludDMyX3VpbnQzMiB7CisgIGtleTogMQorICB2YWx1ZTogMQorfQorbWFwX3VpbnQ2NF91aW50NjQgeworICBrZXk6IDAKKyAgdmFsdWU6IDAKK30KK21hcF91aW50NjRfdWludDY0IHsKKyAga2V5OiAxCisgIHZhbHVlOiAxCit9CittYXBfc2ludDMyX3NpbnQzMiB7CisgIGtleTogMAorICB2YWx1ZTogMAorfQorbWFwX3NpbnQzMl9zaW50MzIgeworICBrZXk6IDEKKyAgdmFsdWU6IDEKK30KK21hcF9zaW50NjRfc2ludDY0IHsKKyAga2V5OiAwCisgIHZhbHVlOiAwCit9CittYXBfc2ludDY0X3NpbnQ2NCB7CisgIGtleTogMQorICB2YWx1ZTogMQorfQorbWFwX2ZpeGVkMzJfZml4ZWQzMiB7CisgIGtleTogMAorICB2YWx1ZTogMAorfQorbWFwX2ZpeGVkMzJfZml4ZWQzMiB7CisgIGtleTogMQorICB2YWx1ZTogMQorfQorbWFwX2ZpeGVkNjRfZml4ZWQ2NCB7CisgIGtleTogMAorICB2YWx1ZTogMAorfQorbWFwX2ZpeGVkNjRfZml4ZWQ2NCB7CisgIGtleTogMQorICB2YWx1ZTogMQorfQorbWFwX3NmaXhlZDMyX3NmaXhlZDMyIHsKKyAga2V5OiAwCisgIHZhbHVlOiAwCit9CittYXBfc2ZpeGVkMzJfc2ZpeGVkMzIgeworICBrZXk6IDEKKyAgdmFsdWU6IDEKK30KK21hcF9zZml4ZWQ2NF9zZml4ZWQ2NCB7CisgIGtleTogMAorICB2YWx1ZTogMAorfQorbWFwX3NmaXhlZDY0X3NmaXhlZDY0IHsKKyAga2V5OiAxCisgIHZhbHVlOiAxCit9CittYXBfaW50MzJfZmxvYXQgeworICBrZXk6IDAKKyAgdmFsdWU6IDAKK30KK21hcF9pbnQzMl9mbG9hdCB7CisgIGtleTogMQorICB2YWx1ZTogMQorfQorbWFwX2ludDMyX2RvdWJsZSB7CisgIGtleTogMAorICB2YWx1ZTogMAorfQorbWFwX2ludDMyX2RvdWJsZSB7CisgIGtleTogMQorICB2YWx1ZTogMQorfQorbWFwX2Jvb2xfYm9vbCB7CisgIGtleTogZmFsc2UKKyAgdmFsdWU6IGZhbHNlCit9CittYXBfYm9vbF9ib29sIHsKKyAga2V5OiB0cnVlCisgIHZhbHVlOiB0cnVlCit9CittYXBfc3RyaW5nX3N0cmluZyB7CisgIGtleTogIjAiCisgIHZhbHVlOiAiMCIKK30KK21hcF9zdHJpbmdfc3RyaW5nIHsKKyAga2V5OiAiMSIKKyAgdmFsdWU6ICIxIgorfQorbWFwX2ludDMyX2J5dGVzIHsKKyAga2V5OiAwCisgIHZhbHVlOiAiMCIKK30KK21hcF9pbnQzMl9ieXRlcyB7CisgIGtleTogMQorICB2YWx1ZTogIjEiCit9CittYXBfaW50MzJfZW51bSB7CisgIGtleTogMAorICB2YWx1ZTogTUFQX0VOVU1fQkFSCit9CittYXBfaW50MzJfZW51bSB7CisgIGtleTogMQorICB2YWx1ZTogTUFQX0VOVU1fQkFaCit9CittYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlIHsKKyAga2V5OiAwCisgIHZhbHVlIHsKKyAgICBjOiAwCisgIH0KK30KK21hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UgeworICBrZXk6IDEKKyAgdmFsdWUgeworICAgIGM6IDEKKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0ZGF0YS90ZXh0X2Zvcm1hdF91bml0dGVzdF9kYXRhLnR4dCBiL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGRhdGEvdGV4dF9mb3JtYXRfdW5pdHRlc3RfZGF0YS50eHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2E4NzRiNQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGRhdGEvdGV4dF9mb3JtYXRfdW5pdHRlc3RfZGF0YS50eHQKQEAgLTAsMCArMSwxMzQgQEAKK29wdGlvbmFsX2ludDMyOiAxMDEKK29wdGlvbmFsX2ludDY0OiAxMDIKK29wdGlvbmFsX3VpbnQzMjogMTAzCitvcHRpb25hbF91aW50NjQ6IDEwNAorb3B0aW9uYWxfc2ludDMyOiAxMDUKK29wdGlvbmFsX3NpbnQ2NDogMTA2CitvcHRpb25hbF9maXhlZDMyOiAxMDcKK29wdGlvbmFsX2ZpeGVkNjQ6IDEwOAorb3B0aW9uYWxfc2ZpeGVkMzI6IDEwOQorb3B0aW9uYWxfc2ZpeGVkNjQ6IDExMAorb3B0aW9uYWxfZmxvYXQ6IDExMQorb3B0aW9uYWxfZG91YmxlOiAxMTIKK29wdGlvbmFsX2Jvb2w6IHRydWUKK29wdGlvbmFsX3N0cmluZzogIjExNSIKK29wdGlvbmFsX2J5dGVzOiAiMTE2IgorT3B0aW9uYWxHcm91cCB7CisgIGE6IDExNworfQorb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgeworICBiYjogMTE4Cit9CitvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgeworICBjOiAxMTkKK30KK29wdGlvbmFsX2ltcG9ydF9tZXNzYWdlIHsKKyAgZDogMTIwCit9CitvcHRpb25hbF9uZXN0ZWRfZW51bTogQkFaCitvcHRpb25hbF9mb3JlaWduX2VudW06IEZPUkVJR05fQkFaCitvcHRpb25hbF9pbXBvcnRfZW51bTogSU1QT1JUX0JBWgorb3B0aW9uYWxfc3RyaW5nX3BpZWNlOiAiMTI0Igorb3B0aW9uYWxfY29yZDogIjEyNSIKK29wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZSB7CisgIGU6IDEyNgorfQorb3B0aW9uYWxfbGF6eV9tZXNzYWdlIHsKKyAgYmI6IDEyNworfQorcmVwZWF0ZWRfaW50MzI6IDIwMQorcmVwZWF0ZWRfaW50MzI6IDMwMQorcmVwZWF0ZWRfaW50NjQ6IDIwMgorcmVwZWF0ZWRfaW50NjQ6IDMwMgorcmVwZWF0ZWRfdWludDMyOiAyMDMKK3JlcGVhdGVkX3VpbnQzMjogMzAzCityZXBlYXRlZF91aW50NjQ6IDIwNAorcmVwZWF0ZWRfdWludDY0OiAzMDQKK3JlcGVhdGVkX3NpbnQzMjogMjA1CityZXBlYXRlZF9zaW50MzI6IDMwNQorcmVwZWF0ZWRfc2ludDY0OiAyMDYKK3JlcGVhdGVkX3NpbnQ2NDogMzA2CityZXBlYXRlZF9maXhlZDMyOiAyMDcKK3JlcGVhdGVkX2ZpeGVkMzI6IDMwNworcmVwZWF0ZWRfZml4ZWQ2NDogMjA4CityZXBlYXRlZF9maXhlZDY0OiAzMDgKK3JlcGVhdGVkX3NmaXhlZDMyOiAyMDkKK3JlcGVhdGVkX3NmaXhlZDMyOiAzMDkKK3JlcGVhdGVkX3NmaXhlZDY0OiAyMTAKK3JlcGVhdGVkX3NmaXhlZDY0OiAzMTAKK3JlcGVhdGVkX2Zsb2F0OiAyMTEKK3JlcGVhdGVkX2Zsb2F0OiAzMTEKK3JlcGVhdGVkX2RvdWJsZTogMjEyCityZXBlYXRlZF9kb3VibGU6IDMxMgorcmVwZWF0ZWRfYm9vbDogdHJ1ZQorcmVwZWF0ZWRfYm9vbDogZmFsc2UKK3JlcGVhdGVkX3N0cmluZzogIjIxNSIKK3JlcGVhdGVkX3N0cmluZzogIjMxNSIKK3JlcGVhdGVkX2J5dGVzOiAiMjE2IgorcmVwZWF0ZWRfYnl0ZXM6ICIzMTYiCitSZXBlYXRlZEdyb3VwIHsKKyAgYTogMjE3Cit9CitSZXBlYXRlZEdyb3VwIHsKKyAgYTogMzE3Cit9CityZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSB7CisgIGJiOiAyMTgKK30KK3JlcGVhdGVkX25lc3RlZF9tZXNzYWdlIHsKKyAgYmI6IDMxOAorfQorcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlIHsKKyAgYzogMjE5Cit9CityZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgeworICBjOiAzMTkKK30KK3JlcGVhdGVkX2ltcG9ydF9tZXNzYWdlIHsKKyAgZDogMjIwCit9CityZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSB7CisgIGQ6IDMyMAorfQorcmVwZWF0ZWRfbmVzdGVkX2VudW06IEJBUgorcmVwZWF0ZWRfbmVzdGVkX2VudW06IEJBWgorcmVwZWF0ZWRfZm9yZWlnbl9lbnVtOiBGT1JFSUdOX0JBUgorcmVwZWF0ZWRfZm9yZWlnbl9lbnVtOiBGT1JFSUdOX0JBWgorcmVwZWF0ZWRfaW1wb3J0X2VudW06IElNUE9SVF9CQVIKK3JlcGVhdGVkX2ltcG9ydF9lbnVtOiBJTVBPUlRfQkFaCityZXBlYXRlZF9zdHJpbmdfcGllY2U6ICIyMjQiCityZXBlYXRlZF9zdHJpbmdfcGllY2U6ICIzMjQiCityZXBlYXRlZF9jb3JkOiAiMjI1IgorcmVwZWF0ZWRfY29yZDogIjMyNSIKK3JlcGVhdGVkX2xhenlfbWVzc2FnZSB7CisgIGJiOiAyMjcKK30KK3JlcGVhdGVkX2xhenlfbWVzc2FnZSB7CisgIGJiOiAzMjcKK30KK2RlZmF1bHRfaW50MzI6IDQwMQorZGVmYXVsdF9pbnQ2NDogNDAyCitkZWZhdWx0X3VpbnQzMjogNDAzCitkZWZhdWx0X3VpbnQ2NDogNDA0CitkZWZhdWx0X3NpbnQzMjogNDA1CitkZWZhdWx0X3NpbnQ2NDogNDA2CitkZWZhdWx0X2ZpeGVkMzI6IDQwNworZGVmYXVsdF9maXhlZDY0OiA0MDgKK2RlZmF1bHRfc2ZpeGVkMzI6IDQwOQorZGVmYXVsdF9zZml4ZWQ2NDogNDEwCitkZWZhdWx0X2Zsb2F0OiA0MTEKK2RlZmF1bHRfZG91YmxlOiA0MTIKK2RlZmF1bHRfYm9vbDogZmFsc2UKK2RlZmF1bHRfc3RyaW5nOiAiNDE1IgorZGVmYXVsdF9ieXRlczogIjQxNiIKK2RlZmF1bHRfbmVzdGVkX2VudW06IEZPTworZGVmYXVsdF9mb3JlaWduX2VudW06IEZPUkVJR05fRk9PCitkZWZhdWx0X2ltcG9ydF9lbnVtOiBJTVBPUlRfRk9PCitkZWZhdWx0X3N0cmluZ19waWVjZTogIjQyNCIKK2RlZmF1bHRfY29yZDogIjQyNSIKK29uZW9mX3VpbnQzMjogNjAxCitvbmVvZl9uZXN0ZWRfbWVzc2FnZSB7CisgIGJiOiA2MDIKK30KK29uZW9mX3N0cmluZzogIjYwMyIKK29uZW9mX2J5dGVzOiAiNjA0IgpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0ZGF0YS90ZXh0X2Zvcm1hdF91bml0dGVzdF9kYXRhX29uZW9mX2ltcGxlbWVudGVkLnR4dCBiL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGRhdGEvdGV4dF9mb3JtYXRfdW5pdHRlc3RfZGF0YV9vbmVvZl9pbXBsZW1lbnRlZC50eHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWM5NWUxZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGRhdGEvdGV4dF9mb3JtYXRfdW5pdHRlc3RfZGF0YV9vbmVvZl9pbXBsZW1lbnRlZC50eHQKQEAgLTAsMCArMSwxMjkgQEAKK29wdGlvbmFsX2ludDMyOiAxMDEKK29wdGlvbmFsX2ludDY0OiAxMDIKK29wdGlvbmFsX3VpbnQzMjogMTAzCitvcHRpb25hbF91aW50NjQ6IDEwNAorb3B0aW9uYWxfc2ludDMyOiAxMDUKK29wdGlvbmFsX3NpbnQ2NDogMTA2CitvcHRpb25hbF9maXhlZDMyOiAxMDcKK29wdGlvbmFsX2ZpeGVkNjQ6IDEwOAorb3B0aW9uYWxfc2ZpeGVkMzI6IDEwOQorb3B0aW9uYWxfc2ZpeGVkNjQ6IDExMAorb3B0aW9uYWxfZmxvYXQ6IDExMQorb3B0aW9uYWxfZG91YmxlOiAxMTIKK29wdGlvbmFsX2Jvb2w6IHRydWUKK29wdGlvbmFsX3N0cmluZzogIjExNSIKK29wdGlvbmFsX2J5dGVzOiAiMTE2IgorT3B0aW9uYWxHcm91cCB7CisgIGE6IDExNworfQorb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgeworICBiYjogMTE4Cit9CitvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgeworICBjOiAxMTkKK30KK29wdGlvbmFsX2ltcG9ydF9tZXNzYWdlIHsKKyAgZDogMTIwCit9CitvcHRpb25hbF9uZXN0ZWRfZW51bTogQkFaCitvcHRpb25hbF9mb3JlaWduX2VudW06IEZPUkVJR05fQkFaCitvcHRpb25hbF9pbXBvcnRfZW51bTogSU1QT1JUX0JBWgorb3B0aW9uYWxfc3RyaW5nX3BpZWNlOiAiMTI0Igorb3B0aW9uYWxfY29yZDogIjEyNSIKK29wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZSB7CisgIGU6IDEyNgorfQorb3B0aW9uYWxfbGF6eV9tZXNzYWdlIHsKKyAgYmI6IDEyNworfQorcmVwZWF0ZWRfaW50MzI6IDIwMQorcmVwZWF0ZWRfaW50MzI6IDMwMQorcmVwZWF0ZWRfaW50NjQ6IDIwMgorcmVwZWF0ZWRfaW50NjQ6IDMwMgorcmVwZWF0ZWRfdWludDMyOiAyMDMKK3JlcGVhdGVkX3VpbnQzMjogMzAzCityZXBlYXRlZF91aW50NjQ6IDIwNAorcmVwZWF0ZWRfdWludDY0OiAzMDQKK3JlcGVhdGVkX3NpbnQzMjogMjA1CityZXBlYXRlZF9zaW50MzI6IDMwNQorcmVwZWF0ZWRfc2ludDY0OiAyMDYKK3JlcGVhdGVkX3NpbnQ2NDogMzA2CityZXBlYXRlZF9maXhlZDMyOiAyMDcKK3JlcGVhdGVkX2ZpeGVkMzI6IDMwNworcmVwZWF0ZWRfZml4ZWQ2NDogMjA4CityZXBlYXRlZF9maXhlZDY0OiAzMDgKK3JlcGVhdGVkX3NmaXhlZDMyOiAyMDkKK3JlcGVhdGVkX3NmaXhlZDMyOiAzMDkKK3JlcGVhdGVkX3NmaXhlZDY0OiAyMTAKK3JlcGVhdGVkX3NmaXhlZDY0OiAzMTAKK3JlcGVhdGVkX2Zsb2F0OiAyMTEKK3JlcGVhdGVkX2Zsb2F0OiAzMTEKK3JlcGVhdGVkX2RvdWJsZTogMjEyCityZXBlYXRlZF9kb3VibGU6IDMxMgorcmVwZWF0ZWRfYm9vbDogdHJ1ZQorcmVwZWF0ZWRfYm9vbDogZmFsc2UKK3JlcGVhdGVkX3N0cmluZzogIjIxNSIKK3JlcGVhdGVkX3N0cmluZzogIjMxNSIKK3JlcGVhdGVkX2J5dGVzOiAiMjE2IgorcmVwZWF0ZWRfYnl0ZXM6ICIzMTYiCitSZXBlYXRlZEdyb3VwIHsKKyAgYTogMjE3Cit9CitSZXBlYXRlZEdyb3VwIHsKKyAgYTogMzE3Cit9CityZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSB7CisgIGJiOiAyMTgKK30KK3JlcGVhdGVkX25lc3RlZF9tZXNzYWdlIHsKKyAgYmI6IDMxOAorfQorcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlIHsKKyAgYzogMjE5Cit9CityZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgeworICBjOiAzMTkKK30KK3JlcGVhdGVkX2ltcG9ydF9tZXNzYWdlIHsKKyAgZDogMjIwCit9CityZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSB7CisgIGQ6IDMyMAorfQorcmVwZWF0ZWRfbmVzdGVkX2VudW06IEJBUgorcmVwZWF0ZWRfbmVzdGVkX2VudW06IEJBWgorcmVwZWF0ZWRfZm9yZWlnbl9lbnVtOiBGT1JFSUdOX0JBUgorcmVwZWF0ZWRfZm9yZWlnbl9lbnVtOiBGT1JFSUdOX0JBWgorcmVwZWF0ZWRfaW1wb3J0X2VudW06IElNUE9SVF9CQVIKK3JlcGVhdGVkX2ltcG9ydF9lbnVtOiBJTVBPUlRfQkFaCityZXBlYXRlZF9zdHJpbmdfcGllY2U6ICIyMjQiCityZXBlYXRlZF9zdHJpbmdfcGllY2U6ICIzMjQiCityZXBlYXRlZF9jb3JkOiAiMjI1IgorcmVwZWF0ZWRfY29yZDogIjMyNSIKK3JlcGVhdGVkX2xhenlfbWVzc2FnZSB7CisgIGJiOiAyMjcKK30KK3JlcGVhdGVkX2xhenlfbWVzc2FnZSB7CisgIGJiOiAzMjcKK30KK2RlZmF1bHRfaW50MzI6IDQwMQorZGVmYXVsdF9pbnQ2NDogNDAyCitkZWZhdWx0X3VpbnQzMjogNDAzCitkZWZhdWx0X3VpbnQ2NDogNDA0CitkZWZhdWx0X3NpbnQzMjogNDA1CitkZWZhdWx0X3NpbnQ2NDogNDA2CitkZWZhdWx0X2ZpeGVkMzI6IDQwNworZGVmYXVsdF9maXhlZDY0OiA0MDgKK2RlZmF1bHRfc2ZpeGVkMzI6IDQwOQorZGVmYXVsdF9zZml4ZWQ2NDogNDEwCitkZWZhdWx0X2Zsb2F0OiA0MTEKK2RlZmF1bHRfZG91YmxlOiA0MTIKK2RlZmF1bHRfYm9vbDogZmFsc2UKK2RlZmF1bHRfc3RyaW5nOiAiNDE1IgorZGVmYXVsdF9ieXRlczogIjQxNiIKK2RlZmF1bHRfbmVzdGVkX2VudW06IEZPTworZGVmYXVsdF9mb3JlaWduX2VudW06IEZPUkVJR05fRk9PCitkZWZhdWx0X2ltcG9ydF9lbnVtOiBJTVBPUlRfRk9PCitkZWZhdWx0X3N0cmluZ19waWVjZTogIjQyNCIKK2RlZmF1bHRfY29yZDogIjQyNSIKK29uZW9mX2J5dGVzOiAiNjA0IgpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0ZGF0YS90ZXh0X2Zvcm1hdF91bml0dGVzdF9kYXRhX3BvaW50eS50eHQgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RkYXRhL3RleHRfZm9ybWF0X3VuaXR0ZXN0X2RhdGFfcG9pbnR5LnR4dApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMTAxMWViCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0ZGF0YS90ZXh0X2Zvcm1hdF91bml0dGVzdF9kYXRhX3BvaW50eS50eHQKQEAgLTAsMCArMSwxMzQgQEAKK29wdGlvbmFsX2ludDMyOiAxMDEKK29wdGlvbmFsX2ludDY0OiAxMDIKK29wdGlvbmFsX3VpbnQzMjogMTAzCitvcHRpb25hbF91aW50NjQ6IDEwNAorb3B0aW9uYWxfc2ludDMyOiAxMDUKK29wdGlvbmFsX3NpbnQ2NDogMTA2CitvcHRpb25hbF9maXhlZDMyOiAxMDcKK29wdGlvbmFsX2ZpeGVkNjQ6IDEwOAorb3B0aW9uYWxfc2ZpeGVkMzI6IDEwOQorb3B0aW9uYWxfc2ZpeGVkNjQ6IDExMAorb3B0aW9uYWxfZmxvYXQ6IDExMQorb3B0aW9uYWxfZG91YmxlOiAxMTIKK29wdGlvbmFsX2Jvb2w6IHRydWUKK29wdGlvbmFsX3N0cmluZzogIjExNSIKK29wdGlvbmFsX2J5dGVzOiAiMTE2IgorT3B0aW9uYWxHcm91cCA8CisgIGE6IDExNworPgorb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPAorICBiYjogMTE4Cis+CitvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgPAorICBjOiAxMTkKKz4KK29wdGlvbmFsX2ltcG9ydF9tZXNzYWdlIDwKKyAgZDogMTIwCis+CitvcHRpb25hbF9uZXN0ZWRfZW51bTogQkFaCitvcHRpb25hbF9mb3JlaWduX2VudW06IEZPUkVJR05fQkFaCitvcHRpb25hbF9pbXBvcnRfZW51bTogSU1QT1JUX0JBWgorb3B0aW9uYWxfc3RyaW5nX3BpZWNlOiAiMTI0Igorb3B0aW9uYWxfY29yZDogIjEyNSIKK29wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZSA8CisgIGU6IDEyNgorPgorb3B0aW9uYWxfbGF6eV9tZXNzYWdlIDwKKyAgYmI6IDEyNworPgorcmVwZWF0ZWRfaW50MzI6IDIwMQorcmVwZWF0ZWRfaW50MzI6IDMwMQorcmVwZWF0ZWRfaW50NjQ6IDIwMgorcmVwZWF0ZWRfaW50NjQ6IDMwMgorcmVwZWF0ZWRfdWludDMyOiAyMDMKK3JlcGVhdGVkX3VpbnQzMjogMzAzCityZXBlYXRlZF91aW50NjQ6IDIwNAorcmVwZWF0ZWRfdWludDY0OiAzMDQKK3JlcGVhdGVkX3NpbnQzMjogMjA1CityZXBlYXRlZF9zaW50MzI6IDMwNQorcmVwZWF0ZWRfc2ludDY0OiAyMDYKK3JlcGVhdGVkX3NpbnQ2NDogMzA2CityZXBlYXRlZF9maXhlZDMyOiAyMDcKK3JlcGVhdGVkX2ZpeGVkMzI6IDMwNworcmVwZWF0ZWRfZml4ZWQ2NDogMjA4CityZXBlYXRlZF9maXhlZDY0OiAzMDgKK3JlcGVhdGVkX3NmaXhlZDMyOiAyMDkKK3JlcGVhdGVkX3NmaXhlZDMyOiAzMDkKK3JlcGVhdGVkX3NmaXhlZDY0OiAyMTAKK3JlcGVhdGVkX3NmaXhlZDY0OiAzMTAKK3JlcGVhdGVkX2Zsb2F0OiAyMTEKK3JlcGVhdGVkX2Zsb2F0OiAzMTEKK3JlcGVhdGVkX2RvdWJsZTogMjEyCityZXBlYXRlZF9kb3VibGU6IDMxMgorcmVwZWF0ZWRfYm9vbDogdHJ1ZQorcmVwZWF0ZWRfYm9vbDogZmFsc2UKK3JlcGVhdGVkX3N0cmluZzogIjIxNSIKK3JlcGVhdGVkX3N0cmluZzogIjMxNSIKK3JlcGVhdGVkX2J5dGVzOiAiMjE2IgorcmVwZWF0ZWRfYnl0ZXM6ICIzMTYiCitSZXBlYXRlZEdyb3VwIDwKKyAgYTogMjE3Cis+CitSZXBlYXRlZEdyb3VwIDwKKyAgYTogMzE3Cis+CityZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA8CisgIGJiOiAyMTgKKz4KK3JlcGVhdGVkX25lc3RlZF9tZXNzYWdlIDwKKyAgYmI6IDMxOAorPgorcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlIDwKKyAgYzogMjE5Cis+CityZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPAorICBjOiAzMTkKKz4KK3JlcGVhdGVkX2ltcG9ydF9tZXNzYWdlIDwKKyAgZDogMjIwCis+CityZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA8CisgIGQ6IDMyMAorPgorcmVwZWF0ZWRfbmVzdGVkX2VudW06IEJBUgorcmVwZWF0ZWRfbmVzdGVkX2VudW06IEJBWgorcmVwZWF0ZWRfZm9yZWlnbl9lbnVtOiBGT1JFSUdOX0JBUgorcmVwZWF0ZWRfZm9yZWlnbl9lbnVtOiBGT1JFSUdOX0JBWgorcmVwZWF0ZWRfaW1wb3J0X2VudW06IElNUE9SVF9CQVIKK3JlcGVhdGVkX2ltcG9ydF9lbnVtOiBJTVBPUlRfQkFaCityZXBlYXRlZF9zdHJpbmdfcGllY2U6ICIyMjQiCityZXBlYXRlZF9zdHJpbmdfcGllY2U6ICIzMjQiCityZXBlYXRlZF9jb3JkOiAiMjI1IgorcmVwZWF0ZWRfY29yZDogIjMyNSIKK3JlcGVhdGVkX2xhenlfbWVzc2FnZSA8CisgIGJiOiAyMjcKKz4KK3JlcGVhdGVkX2xhenlfbWVzc2FnZSA8CisgIGJiOiAzMjcKKz4KK2RlZmF1bHRfaW50MzI6IDQwMQorZGVmYXVsdF9pbnQ2NDogNDAyCitkZWZhdWx0X3VpbnQzMjogNDAzCitkZWZhdWx0X3VpbnQ2NDogNDA0CitkZWZhdWx0X3NpbnQzMjogNDA1CitkZWZhdWx0X3NpbnQ2NDogNDA2CitkZWZhdWx0X2ZpeGVkMzI6IDQwNworZGVmYXVsdF9maXhlZDY0OiA0MDgKK2RlZmF1bHRfc2ZpeGVkMzI6IDQwOQorZGVmYXVsdF9zZml4ZWQ2NDogNDEwCitkZWZhdWx0X2Zsb2F0OiA0MTEKK2RlZmF1bHRfZG91YmxlOiA0MTIKK2RlZmF1bHRfYm9vbDogZmFsc2UKK2RlZmF1bHRfc3RyaW5nOiAiNDE1IgorZGVmYXVsdF9ieXRlczogIjQxNiIKK2RlZmF1bHRfbmVzdGVkX2VudW06IEZPTworZGVmYXVsdF9mb3JlaWduX2VudW06IEZPUkVJR05fRk9PCitkZWZhdWx0X2ltcG9ydF9lbnVtOiBJTVBPUlRfRk9PCitkZWZhdWx0X3N0cmluZ19waWVjZTogIjQyNCIKK2RlZmF1bHRfY29yZDogIjQyNSIKK29uZW9mX3VpbnQzMjogNjAxCitvbmVvZl9uZXN0ZWRfbWVzc2FnZSA8CisgIGJiOiA2MDIKKz4KK29uZW9mX3N0cmluZzogIjYwMyIKK29uZW9mX2J5dGVzOiAiNjA0IgpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0ZGF0YS90ZXh0X2Zvcm1hdF91bml0dGVzdF9kYXRhX3BvaW50eV9vbmVvZi50eHQgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RkYXRhL3RleHRfZm9ybWF0X3VuaXR0ZXN0X2RhdGFfcG9pbnR5X29uZW9mLnR4dApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NTEwOWY2Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0ZGF0YS90ZXh0X2Zvcm1hdF91bml0dGVzdF9kYXRhX3BvaW50eV9vbmVvZi50eHQKQEAgLTAsMCArMSwxMjkgQEAKK29wdGlvbmFsX2ludDMyOiAxMDEKK29wdGlvbmFsX2ludDY0OiAxMDIKK29wdGlvbmFsX3VpbnQzMjogMTAzCitvcHRpb25hbF91aW50NjQ6IDEwNAorb3B0aW9uYWxfc2ludDMyOiAxMDUKK29wdGlvbmFsX3NpbnQ2NDogMTA2CitvcHRpb25hbF9maXhlZDMyOiAxMDcKK29wdGlvbmFsX2ZpeGVkNjQ6IDEwOAorb3B0aW9uYWxfc2ZpeGVkMzI6IDEwOQorb3B0aW9uYWxfc2ZpeGVkNjQ6IDExMAorb3B0aW9uYWxfZmxvYXQ6IDExMQorb3B0aW9uYWxfZG91YmxlOiAxMTIKK29wdGlvbmFsX2Jvb2w6IHRydWUKK29wdGlvbmFsX3N0cmluZzogIjExNSIKK29wdGlvbmFsX2J5dGVzOiAiMTE2IgorT3B0aW9uYWxHcm91cCA8CisgIGE6IDExNworPgorb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPAorICBiYjogMTE4Cis+CitvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgPAorICBjOiAxMTkKKz4KK29wdGlvbmFsX2ltcG9ydF9tZXNzYWdlIDwKKyAgZDogMTIwCis+CitvcHRpb25hbF9uZXN0ZWRfZW51bTogQkFaCitvcHRpb25hbF9mb3JlaWduX2VudW06IEZPUkVJR05fQkFaCitvcHRpb25hbF9pbXBvcnRfZW51bTogSU1QT1JUX0JBWgorb3B0aW9uYWxfc3RyaW5nX3BpZWNlOiAiMTI0Igorb3B0aW9uYWxfY29yZDogIjEyNSIKK29wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZSA8CisgIGU6IDEyNgorPgorb3B0aW9uYWxfbGF6eV9tZXNzYWdlIDwKKyAgYmI6IDEyNworPgorcmVwZWF0ZWRfaW50MzI6IDIwMQorcmVwZWF0ZWRfaW50MzI6IDMwMQorcmVwZWF0ZWRfaW50NjQ6IDIwMgorcmVwZWF0ZWRfaW50NjQ6IDMwMgorcmVwZWF0ZWRfdWludDMyOiAyMDMKK3JlcGVhdGVkX3VpbnQzMjogMzAzCityZXBlYXRlZF91aW50NjQ6IDIwNAorcmVwZWF0ZWRfdWludDY0OiAzMDQKK3JlcGVhdGVkX3NpbnQzMjogMjA1CityZXBlYXRlZF9zaW50MzI6IDMwNQorcmVwZWF0ZWRfc2ludDY0OiAyMDYKK3JlcGVhdGVkX3NpbnQ2NDogMzA2CityZXBlYXRlZF9maXhlZDMyOiAyMDcKK3JlcGVhdGVkX2ZpeGVkMzI6IDMwNworcmVwZWF0ZWRfZml4ZWQ2NDogMjA4CityZXBlYXRlZF9maXhlZDY0OiAzMDgKK3JlcGVhdGVkX3NmaXhlZDMyOiAyMDkKK3JlcGVhdGVkX3NmaXhlZDMyOiAzMDkKK3JlcGVhdGVkX3NmaXhlZDY0OiAyMTAKK3JlcGVhdGVkX3NmaXhlZDY0OiAzMTAKK3JlcGVhdGVkX2Zsb2F0OiAyMTEKK3JlcGVhdGVkX2Zsb2F0OiAzMTEKK3JlcGVhdGVkX2RvdWJsZTogMjEyCityZXBlYXRlZF9kb3VibGU6IDMxMgorcmVwZWF0ZWRfYm9vbDogdHJ1ZQorcmVwZWF0ZWRfYm9vbDogZmFsc2UKK3JlcGVhdGVkX3N0cmluZzogIjIxNSIKK3JlcGVhdGVkX3N0cmluZzogIjMxNSIKK3JlcGVhdGVkX2J5dGVzOiAiMjE2IgorcmVwZWF0ZWRfYnl0ZXM6ICIzMTYiCitSZXBlYXRlZEdyb3VwIDwKKyAgYTogMjE3Cis+CitSZXBlYXRlZEdyb3VwIDwKKyAgYTogMzE3Cis+CityZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA8CisgIGJiOiAyMTgKKz4KK3JlcGVhdGVkX25lc3RlZF9tZXNzYWdlIDwKKyAgYmI6IDMxOAorPgorcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlIDwKKyAgYzogMjE5Cis+CityZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPAorICBjOiAzMTkKKz4KK3JlcGVhdGVkX2ltcG9ydF9tZXNzYWdlIDwKKyAgZDogMjIwCis+CityZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA8CisgIGQ6IDMyMAorPgorcmVwZWF0ZWRfbmVzdGVkX2VudW06IEJBUgorcmVwZWF0ZWRfbmVzdGVkX2VudW06IEJBWgorcmVwZWF0ZWRfZm9yZWlnbl9lbnVtOiBGT1JFSUdOX0JBUgorcmVwZWF0ZWRfZm9yZWlnbl9lbnVtOiBGT1JFSUdOX0JBWgorcmVwZWF0ZWRfaW1wb3J0X2VudW06IElNUE9SVF9CQVIKK3JlcGVhdGVkX2ltcG9ydF9lbnVtOiBJTVBPUlRfQkFaCityZXBlYXRlZF9zdHJpbmdfcGllY2U6ICIyMjQiCityZXBlYXRlZF9zdHJpbmdfcGllY2U6ICIzMjQiCityZXBlYXRlZF9jb3JkOiAiMjI1IgorcmVwZWF0ZWRfY29yZDogIjMyNSIKK3JlcGVhdGVkX2xhenlfbWVzc2FnZSA8CisgIGJiOiAyMjcKKz4KK3JlcGVhdGVkX2xhenlfbWVzc2FnZSA8CisgIGJiOiAzMjcKKz4KK2RlZmF1bHRfaW50MzI6IDQwMQorZGVmYXVsdF9pbnQ2NDogNDAyCitkZWZhdWx0X3VpbnQzMjogNDAzCitkZWZhdWx0X3VpbnQ2NDogNDA0CitkZWZhdWx0X3NpbnQzMjogNDA1CitkZWZhdWx0X3NpbnQ2NDogNDA2CitkZWZhdWx0X2ZpeGVkMzI6IDQwNworZGVmYXVsdF9maXhlZDY0OiA0MDgKK2RlZmF1bHRfc2ZpeGVkMzI6IDQwOQorZGVmYXVsdF9zZml4ZWQ2NDogNDEwCitkZWZhdWx0X2Zsb2F0OiA0MTEKK2RlZmF1bHRfZG91YmxlOiA0MTIKK2RlZmF1bHRfYm9vbDogZmFsc2UKK2RlZmF1bHRfc3RyaW5nOiAiNDE1IgorZGVmYXVsdF9ieXRlczogIjQxNiIKK2RlZmF1bHRfbmVzdGVkX2VudW06IEZPTworZGVmYXVsdF9mb3JlaWduX2VudW06IEZPUkVJR05fRk9PCitkZWZhdWx0X2ltcG9ydF9lbnVtOiBJTVBPUlRfRk9PCitkZWZhdWx0X3N0cmluZ19waWVjZTogIjQyNCIKK2RlZmF1bHRfY29yZDogIjQyNSIKK29uZW9mX2J5dGVzOiAiNjA0IgpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0ZGF0YS90ZXh0X2Zvcm1hdF91bml0dGVzdF9leHRlbnNpb25zX2RhdGEudHh0IGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0ZGF0YS90ZXh0X2Zvcm1hdF91bml0dGVzdF9leHRlbnNpb25zX2RhdGEudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhjOGIxZWIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RkYXRhL3RleHRfZm9ybWF0X3VuaXR0ZXN0X2V4dGVuc2lvbnNfZGF0YS50eHQKQEAgLTAsMCArMSwxMzQgQEAKK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF9pbnQzMl9leHRlbnNpb25dOiAxMDEKK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF9pbnQ2NF9leHRlbnNpb25dOiAxMDIKK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF91aW50MzJfZXh0ZW5zaW9uXTogMTAzCitbcHJvdG9idWZfdW5pdHRlc3Qub3B0aW9uYWxfdWludDY0X2V4dGVuc2lvbl06IDEwNAorW3Byb3RvYnVmX3VuaXR0ZXN0Lm9wdGlvbmFsX3NpbnQzMl9leHRlbnNpb25dOiAxMDUKK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF9zaW50NjRfZXh0ZW5zaW9uXTogMTA2CitbcHJvdG9idWZfdW5pdHRlc3Qub3B0aW9uYWxfZml4ZWQzMl9leHRlbnNpb25dOiAxMDcKK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF9maXhlZDY0X2V4dGVuc2lvbl06IDEwOAorW3Byb3RvYnVmX3VuaXR0ZXN0Lm9wdGlvbmFsX3NmaXhlZDMyX2V4dGVuc2lvbl06IDEwOQorW3Byb3RvYnVmX3VuaXR0ZXN0Lm9wdGlvbmFsX3NmaXhlZDY0X2V4dGVuc2lvbl06IDExMAorW3Byb3RvYnVmX3VuaXR0ZXN0Lm9wdGlvbmFsX2Zsb2F0X2V4dGVuc2lvbl06IDExMQorW3Byb3RvYnVmX3VuaXR0ZXN0Lm9wdGlvbmFsX2RvdWJsZV9leHRlbnNpb25dOiAxMTIKK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF9ib29sX2V4dGVuc2lvbl06IHRydWUKK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF9zdHJpbmdfZXh0ZW5zaW9uXTogIjExNSIKK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF9ieXRlc19leHRlbnNpb25dOiAiMTE2IgorW3Byb3RvYnVmX3VuaXR0ZXN0Lm9wdGlvbmFsZ3JvdXBfZXh0ZW5zaW9uXSB7CisgIGE6IDExNworfQorW3Byb3RvYnVmX3VuaXR0ZXN0Lm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbl0geworICBiYjogMTE4Cit9CitbcHJvdG9idWZfdW5pdHRlc3Qub3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbl0geworICBjOiAxMTkKK30KK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb25dIHsKKyAgZDogMTIwCit9CitbcHJvdG9idWZfdW5pdHRlc3Qub3B0aW9uYWxfbmVzdGVkX2VudW1fZXh0ZW5zaW9uXTogQkFaCitbcHJvdG9idWZfdW5pdHRlc3Qub3B0aW9uYWxfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbl06IEZPUkVJR05fQkFaCitbcHJvdG9idWZfdW5pdHRlc3Qub3B0aW9uYWxfaW1wb3J0X2VudW1fZXh0ZW5zaW9uXTogSU1QT1JUX0JBWgorW3Byb3RvYnVmX3VuaXR0ZXN0Lm9wdGlvbmFsX3N0cmluZ19waWVjZV9leHRlbnNpb25dOiAiMTI0IgorW3Byb3RvYnVmX3VuaXR0ZXN0Lm9wdGlvbmFsX2NvcmRfZXh0ZW5zaW9uXTogIjEyNSIKK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uXSB7CisgIGU6IDEyNgorfQorW3Byb3RvYnVmX3VuaXR0ZXN0Lm9wdGlvbmFsX2xhenlfbWVzc2FnZV9leHRlbnNpb25dIHsKKyAgYmI6IDEyNworfQorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX2ludDMyX2V4dGVuc2lvbl06IDIwMQorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX2ludDMyX2V4dGVuc2lvbl06IDMwMQorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX2ludDY0X2V4dGVuc2lvbl06IDIwMgorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX2ludDY0X2V4dGVuc2lvbl06IDMwMgorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX3VpbnQzMl9leHRlbnNpb25dOiAyMDMKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF91aW50MzJfZXh0ZW5zaW9uXTogMzAzCitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfdWludDY0X2V4dGVuc2lvbl06IDIwNAorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX3VpbnQ2NF9leHRlbnNpb25dOiAzMDQKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9zaW50MzJfZXh0ZW5zaW9uXTogMjA1CitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfc2ludDMyX2V4dGVuc2lvbl06IDMwNQorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX3NpbnQ2NF9leHRlbnNpb25dOiAyMDYKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9zaW50NjRfZXh0ZW5zaW9uXTogMzA2CitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfZml4ZWQzMl9leHRlbnNpb25dOiAyMDcKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9maXhlZDMyX2V4dGVuc2lvbl06IDMwNworW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX2ZpeGVkNjRfZXh0ZW5zaW9uXTogMjA4CitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfZml4ZWQ2NF9leHRlbnNpb25dOiAzMDgKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9zZml4ZWQzMl9leHRlbnNpb25dOiAyMDkKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9zZml4ZWQzMl9leHRlbnNpb25dOiAzMDkKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9zZml4ZWQ2NF9leHRlbnNpb25dOiAyMTAKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9zZml4ZWQ2NF9leHRlbnNpb25dOiAzMTAKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9mbG9hdF9leHRlbnNpb25dOiAyMTEKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9mbG9hdF9leHRlbnNpb25dOiAzMTEKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9kb3VibGVfZXh0ZW5zaW9uXTogMjEyCitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfZG91YmxlX2V4dGVuc2lvbl06IDMxMgorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX2Jvb2xfZXh0ZW5zaW9uXTogdHJ1ZQorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX2Jvb2xfZXh0ZW5zaW9uXTogZmFsc2UKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9zdHJpbmdfZXh0ZW5zaW9uXTogIjIxNSIKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9zdHJpbmdfZXh0ZW5zaW9uXTogIjMxNSIKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9ieXRlc19leHRlbnNpb25dOiAiMjE2IgorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX2J5dGVzX2V4dGVuc2lvbl06ICIzMTYiCitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRncm91cF9leHRlbnNpb25dIHsKKyAgYTogMjE3Cit9CitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRncm91cF9leHRlbnNpb25dIHsKKyAgYTogMzE3Cit9CitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uXSB7CisgIGJiOiAyMTgKK30KK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb25dIHsKKyAgYmI6IDMxOAorfQorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb25dIHsKKyAgYzogMjE5Cit9CitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbl0geworICBjOiAzMTkKK30KK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb25dIHsKKyAgZDogMjIwCit9CitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uXSB7CisgIGQ6IDMyMAorfQorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX25lc3RlZF9lbnVtX2V4dGVuc2lvbl06IEJBUgorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX25lc3RlZF9lbnVtX2V4dGVuc2lvbl06IEJBWgorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX2ZvcmVpZ25fZW51bV9leHRlbnNpb25dOiBGT1JFSUdOX0JBUgorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX2ZvcmVpZ25fZW51bV9leHRlbnNpb25dOiBGT1JFSUdOX0JBWgorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX2ltcG9ydF9lbnVtX2V4dGVuc2lvbl06IElNUE9SVF9CQVIKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9pbXBvcnRfZW51bV9leHRlbnNpb25dOiBJTVBPUlRfQkFaCitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfc3RyaW5nX3BpZWNlX2V4dGVuc2lvbl06ICIyMjQiCitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfc3RyaW5nX3BpZWNlX2V4dGVuc2lvbl06ICIzMjQiCitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfY29yZF9leHRlbnNpb25dOiAiMjI1IgorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX2NvcmRfZXh0ZW5zaW9uXTogIjMyNSIKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9sYXp5X21lc3NhZ2VfZXh0ZW5zaW9uXSB7CisgIGJiOiAyMjcKK30KK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9sYXp5X21lc3NhZ2VfZXh0ZW5zaW9uXSB7CisgIGJiOiAzMjcKK30KK1twcm90b2J1Zl91bml0dGVzdC5kZWZhdWx0X2ludDMyX2V4dGVuc2lvbl06IDQwMQorW3Byb3RvYnVmX3VuaXR0ZXN0LmRlZmF1bHRfaW50NjRfZXh0ZW5zaW9uXTogNDAyCitbcHJvdG9idWZfdW5pdHRlc3QuZGVmYXVsdF91aW50MzJfZXh0ZW5zaW9uXTogNDAzCitbcHJvdG9idWZfdW5pdHRlc3QuZGVmYXVsdF91aW50NjRfZXh0ZW5zaW9uXTogNDA0CitbcHJvdG9idWZfdW5pdHRlc3QuZGVmYXVsdF9zaW50MzJfZXh0ZW5zaW9uXTogNDA1CitbcHJvdG9idWZfdW5pdHRlc3QuZGVmYXVsdF9zaW50NjRfZXh0ZW5zaW9uXTogNDA2CitbcHJvdG9idWZfdW5pdHRlc3QuZGVmYXVsdF9maXhlZDMyX2V4dGVuc2lvbl06IDQwNworW3Byb3RvYnVmX3VuaXR0ZXN0LmRlZmF1bHRfZml4ZWQ2NF9leHRlbnNpb25dOiA0MDgKK1twcm90b2J1Zl91bml0dGVzdC5kZWZhdWx0X3NmaXhlZDMyX2V4dGVuc2lvbl06IDQwOQorW3Byb3RvYnVmX3VuaXR0ZXN0LmRlZmF1bHRfc2ZpeGVkNjRfZXh0ZW5zaW9uXTogNDEwCitbcHJvdG9idWZfdW5pdHRlc3QuZGVmYXVsdF9mbG9hdF9leHRlbnNpb25dOiA0MTEKK1twcm90b2J1Zl91bml0dGVzdC5kZWZhdWx0X2RvdWJsZV9leHRlbnNpb25dOiA0MTIKK1twcm90b2J1Zl91bml0dGVzdC5kZWZhdWx0X2Jvb2xfZXh0ZW5zaW9uXTogZmFsc2UKK1twcm90b2J1Zl91bml0dGVzdC5kZWZhdWx0X3N0cmluZ19leHRlbnNpb25dOiAiNDE1IgorW3Byb3RvYnVmX3VuaXR0ZXN0LmRlZmF1bHRfYnl0ZXNfZXh0ZW5zaW9uXTogIjQxNiIKK1twcm90b2J1Zl91bml0dGVzdC5kZWZhdWx0X25lc3RlZF9lbnVtX2V4dGVuc2lvbl06IEZPTworW3Byb3RvYnVmX3VuaXR0ZXN0LmRlZmF1bHRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbl06IEZPUkVJR05fRk9PCitbcHJvdG9idWZfdW5pdHRlc3QuZGVmYXVsdF9pbXBvcnRfZW51bV9leHRlbnNpb25dOiBJTVBPUlRfRk9PCitbcHJvdG9idWZfdW5pdHRlc3QuZGVmYXVsdF9zdHJpbmdfcGllY2VfZXh0ZW5zaW9uXTogIjQyNCIKK1twcm90b2J1Zl91bml0dGVzdC5kZWZhdWx0X2NvcmRfZXh0ZW5zaW9uXTogIjQyNSIKK1twcm90b2J1Zl91bml0dGVzdC5vbmVvZl91aW50MzJfZXh0ZW5zaW9uXTogNjAxCitbcHJvdG9idWZfdW5pdHRlc3Qub25lb2ZfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uXSB7CisgIGJiOiA2MDIKK30KK1twcm90b2J1Zl91bml0dGVzdC5vbmVvZl9zdHJpbmdfZXh0ZW5zaW9uXTogIjYwMyIKK1twcm90b2J1Zl91bml0dGVzdC5vbmVvZl9ieXRlc19leHRlbnNpb25dOiAiNjA0IgpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0ZGF0YS90ZXh0X2Zvcm1hdF91bml0dGVzdF9leHRlbnNpb25zX2RhdGFfcG9pbnR5LnR4dCBiL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGRhdGEvdGV4dF9mb3JtYXRfdW5pdHRlc3RfZXh0ZW5zaW9uc19kYXRhX3BvaW50eS50eHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTMyZjc0NAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGRhdGEvdGV4dF9mb3JtYXRfdW5pdHRlc3RfZXh0ZW5zaW9uc19kYXRhX3BvaW50eS50eHQKQEAgLTAsMCArMSwxMzQgQEAKK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF9pbnQzMl9leHRlbnNpb25dOiAxMDEKK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF9pbnQ2NF9leHRlbnNpb25dOiAxMDIKK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF91aW50MzJfZXh0ZW5zaW9uXTogMTAzCitbcHJvdG9idWZfdW5pdHRlc3Qub3B0aW9uYWxfdWludDY0X2V4dGVuc2lvbl06IDEwNAorW3Byb3RvYnVmX3VuaXR0ZXN0Lm9wdGlvbmFsX3NpbnQzMl9leHRlbnNpb25dOiAxMDUKK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF9zaW50NjRfZXh0ZW5zaW9uXTogMTA2CitbcHJvdG9idWZfdW5pdHRlc3Qub3B0aW9uYWxfZml4ZWQzMl9leHRlbnNpb25dOiAxMDcKK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF9maXhlZDY0X2V4dGVuc2lvbl06IDEwOAorW3Byb3RvYnVmX3VuaXR0ZXN0Lm9wdGlvbmFsX3NmaXhlZDMyX2V4dGVuc2lvbl06IDEwOQorW3Byb3RvYnVmX3VuaXR0ZXN0Lm9wdGlvbmFsX3NmaXhlZDY0X2V4dGVuc2lvbl06IDExMAorW3Byb3RvYnVmX3VuaXR0ZXN0Lm9wdGlvbmFsX2Zsb2F0X2V4dGVuc2lvbl06IDExMQorW3Byb3RvYnVmX3VuaXR0ZXN0Lm9wdGlvbmFsX2RvdWJsZV9leHRlbnNpb25dOiAxMTIKK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF9ib29sX2V4dGVuc2lvbl06IHRydWUKK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF9zdHJpbmdfZXh0ZW5zaW9uXTogIjExNSIKK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF9ieXRlc19leHRlbnNpb25dOiAiMTE2IgorW3Byb3RvYnVmX3VuaXR0ZXN0Lm9wdGlvbmFsZ3JvdXBfZXh0ZW5zaW9uXSA8CisgIGE6IDExNworPgorW3Byb3RvYnVmX3VuaXR0ZXN0Lm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbl0gPAorICBiYjogMTE4Cis+CitbcHJvdG9idWZfdW5pdHRlc3Qub3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbl0gPAorICBjOiAxMTkKKz4KK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb25dIDwKKyAgZDogMTIwCis+CitbcHJvdG9idWZfdW5pdHRlc3Qub3B0aW9uYWxfbmVzdGVkX2VudW1fZXh0ZW5zaW9uXTogQkFaCitbcHJvdG9idWZfdW5pdHRlc3Qub3B0aW9uYWxfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbl06IEZPUkVJR05fQkFaCitbcHJvdG9idWZfdW5pdHRlc3Qub3B0aW9uYWxfaW1wb3J0X2VudW1fZXh0ZW5zaW9uXTogSU1QT1JUX0JBWgorW3Byb3RvYnVmX3VuaXR0ZXN0Lm9wdGlvbmFsX3N0cmluZ19waWVjZV9leHRlbnNpb25dOiAiMTI0IgorW3Byb3RvYnVmX3VuaXR0ZXN0Lm9wdGlvbmFsX2NvcmRfZXh0ZW5zaW9uXTogIjEyNSIKK1twcm90b2J1Zl91bml0dGVzdC5vcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uXSA8CisgIGU6IDEyNgorPgorW3Byb3RvYnVmX3VuaXR0ZXN0Lm9wdGlvbmFsX2xhenlfbWVzc2FnZV9leHRlbnNpb25dIDwKKyAgYmI6IDEyNworPgorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX2ludDMyX2V4dGVuc2lvbl06IDIwMQorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX2ludDMyX2V4dGVuc2lvbl06IDMwMQorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX2ludDY0X2V4dGVuc2lvbl06IDIwMgorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX2ludDY0X2V4dGVuc2lvbl06IDMwMgorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX3VpbnQzMl9leHRlbnNpb25dOiAyMDMKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF91aW50MzJfZXh0ZW5zaW9uXTogMzAzCitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfdWludDY0X2V4dGVuc2lvbl06IDIwNAorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX3VpbnQ2NF9leHRlbnNpb25dOiAzMDQKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9zaW50MzJfZXh0ZW5zaW9uXTogMjA1CitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfc2ludDMyX2V4dGVuc2lvbl06IDMwNQorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX3NpbnQ2NF9leHRlbnNpb25dOiAyMDYKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9zaW50NjRfZXh0ZW5zaW9uXTogMzA2CitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfZml4ZWQzMl9leHRlbnNpb25dOiAyMDcKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9maXhlZDMyX2V4dGVuc2lvbl06IDMwNworW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX2ZpeGVkNjRfZXh0ZW5zaW9uXTogMjA4CitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfZml4ZWQ2NF9leHRlbnNpb25dOiAzMDgKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9zZml4ZWQzMl9leHRlbnNpb25dOiAyMDkKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9zZml4ZWQzMl9leHRlbnNpb25dOiAzMDkKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9zZml4ZWQ2NF9leHRlbnNpb25dOiAyMTAKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9zZml4ZWQ2NF9leHRlbnNpb25dOiAzMTAKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9mbG9hdF9leHRlbnNpb25dOiAyMTEKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9mbG9hdF9leHRlbnNpb25dOiAzMTEKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9kb3VibGVfZXh0ZW5zaW9uXTogMjEyCitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfZG91YmxlX2V4dGVuc2lvbl06IDMxMgorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX2Jvb2xfZXh0ZW5zaW9uXTogdHJ1ZQorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX2Jvb2xfZXh0ZW5zaW9uXTogZmFsc2UKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9zdHJpbmdfZXh0ZW5zaW9uXTogIjIxNSIKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9zdHJpbmdfZXh0ZW5zaW9uXTogIjMxNSIKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9ieXRlc19leHRlbnNpb25dOiAiMjE2IgorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX2J5dGVzX2V4dGVuc2lvbl06ICIzMTYiCitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRncm91cF9leHRlbnNpb25dIDwKKyAgYTogMjE3Cis+CitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRncm91cF9leHRlbnNpb25dIDwKKyAgYTogMzE3Cis+CitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uXSA8CisgIGJiOiAyMTgKKz4KK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb25dIDwKKyAgYmI6IDMxOAorPgorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb25dIDwKKyAgYzogMjE5Cis+CitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbl0gPAorICBjOiAzMTkKKz4KK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb25dIDwKKyAgZDogMjIwCis+CitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uXSA8CisgIGQ6IDMyMAorPgorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX25lc3RlZF9lbnVtX2V4dGVuc2lvbl06IEJBUgorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX25lc3RlZF9lbnVtX2V4dGVuc2lvbl06IEJBWgorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX2ZvcmVpZ25fZW51bV9leHRlbnNpb25dOiBGT1JFSUdOX0JBUgorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX2ZvcmVpZ25fZW51bV9leHRlbnNpb25dOiBGT1JFSUdOX0JBWgorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX2ltcG9ydF9lbnVtX2V4dGVuc2lvbl06IElNUE9SVF9CQVIKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9pbXBvcnRfZW51bV9leHRlbnNpb25dOiBJTVBPUlRfQkFaCitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfc3RyaW5nX3BpZWNlX2V4dGVuc2lvbl06ICIyMjQiCitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfc3RyaW5nX3BpZWNlX2V4dGVuc2lvbl06ICIzMjQiCitbcHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfY29yZF9leHRlbnNpb25dOiAiMjI1IgorW3Byb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX2NvcmRfZXh0ZW5zaW9uXTogIjMyNSIKK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9sYXp5X21lc3NhZ2VfZXh0ZW5zaW9uXSA8CisgIGJiOiAyMjcKKz4KK1twcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9sYXp5X21lc3NhZ2VfZXh0ZW5zaW9uXSA8CisgIGJiOiAzMjcKKz4KK1twcm90b2J1Zl91bml0dGVzdC5kZWZhdWx0X2ludDMyX2V4dGVuc2lvbl06IDQwMQorW3Byb3RvYnVmX3VuaXR0ZXN0LmRlZmF1bHRfaW50NjRfZXh0ZW5zaW9uXTogNDAyCitbcHJvdG9idWZfdW5pdHRlc3QuZGVmYXVsdF91aW50MzJfZXh0ZW5zaW9uXTogNDAzCitbcHJvdG9idWZfdW5pdHRlc3QuZGVmYXVsdF91aW50NjRfZXh0ZW5zaW9uXTogNDA0CitbcHJvdG9idWZfdW5pdHRlc3QuZGVmYXVsdF9zaW50MzJfZXh0ZW5zaW9uXTogNDA1CitbcHJvdG9idWZfdW5pdHRlc3QuZGVmYXVsdF9zaW50NjRfZXh0ZW5zaW9uXTogNDA2CitbcHJvdG9idWZfdW5pdHRlc3QuZGVmYXVsdF9maXhlZDMyX2V4dGVuc2lvbl06IDQwNworW3Byb3RvYnVmX3VuaXR0ZXN0LmRlZmF1bHRfZml4ZWQ2NF9leHRlbnNpb25dOiA0MDgKK1twcm90b2J1Zl91bml0dGVzdC5kZWZhdWx0X3NmaXhlZDMyX2V4dGVuc2lvbl06IDQwOQorW3Byb3RvYnVmX3VuaXR0ZXN0LmRlZmF1bHRfc2ZpeGVkNjRfZXh0ZW5zaW9uXTogNDEwCitbcHJvdG9idWZfdW5pdHRlc3QuZGVmYXVsdF9mbG9hdF9leHRlbnNpb25dOiA0MTEKK1twcm90b2J1Zl91bml0dGVzdC5kZWZhdWx0X2RvdWJsZV9leHRlbnNpb25dOiA0MTIKK1twcm90b2J1Zl91bml0dGVzdC5kZWZhdWx0X2Jvb2xfZXh0ZW5zaW9uXTogZmFsc2UKK1twcm90b2J1Zl91bml0dGVzdC5kZWZhdWx0X3N0cmluZ19leHRlbnNpb25dOiAiNDE1IgorW3Byb3RvYnVmX3VuaXR0ZXN0LmRlZmF1bHRfYnl0ZXNfZXh0ZW5zaW9uXTogIjQxNiIKK1twcm90b2J1Zl91bml0dGVzdC5kZWZhdWx0X25lc3RlZF9lbnVtX2V4dGVuc2lvbl06IEZPTworW3Byb3RvYnVmX3VuaXR0ZXN0LmRlZmF1bHRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbl06IEZPUkVJR05fRk9PCitbcHJvdG9idWZfdW5pdHRlc3QuZGVmYXVsdF9pbXBvcnRfZW51bV9leHRlbnNpb25dOiBJTVBPUlRfRk9PCitbcHJvdG9idWZfdW5pdHRlc3QuZGVmYXVsdF9zdHJpbmdfcGllY2VfZXh0ZW5zaW9uXTogIjQyNCIKK1twcm90b2J1Zl91bml0dGVzdC5kZWZhdWx0X2NvcmRfZXh0ZW5zaW9uXTogIjQyNSIKK1twcm90b2J1Zl91bml0dGVzdC5vbmVvZl91aW50MzJfZXh0ZW5zaW9uXTogNjAxCitbcHJvdG9idWZfdW5pdHRlc3Qub25lb2ZfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uXSA8CisgIGJiOiA2MDIKKz4KK1twcm90b2J1Zl91bml0dGVzdC5vbmVvZl9zdHJpbmdfZXh0ZW5zaW9uXTogIjYwMyIKK1twcm90b2J1Zl91bml0dGVzdC5vbmVvZl9ieXRlc19leHRlbnNpb25dOiAiNjA0IgpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2ZpbGUuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZmlsZS5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZDA3YjEyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2ZpbGUuY2MKQEAgLTAsMCArMSwyMDAgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyBlbXVsYXRlcyBnb29nbGUzL2ZpbGUvYmFzZS9maWxlLmNjCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9maWxlLmg+CisjaW5jbHVkZSA8c3RkaW8uaD4KKyNpbmNsdWRlIDxzeXMvc3RhdC5oPgorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorI2lmZGVmIF9NU0NfVkVSCisjZGVmaW5lIFdJTjMyX0xFQU5fQU5EX01FQU4gIC8vIHllYWgsIHJpZ2h0CisjaW5jbHVkZSA8d2luZG93cy5oPiAgICAgICAgIC8vIEZpbmQqRmlsZSgpLiAgOigKKyNpbmNsdWRlIDxpby5oPgorI2luY2x1ZGUgPGRpcmVjdC5oPgorI2Vsc2UKKyNpbmNsdWRlIDxkaXJlbnQuaD4KKyNpbmNsdWRlIDx1bmlzdGQuaD4KKyNlbmRpZgorI2luY2x1ZGUgPGVycm5vLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworI2lmZGVmIF9XSU4zMgorI2RlZmluZSBta2RpcihuYW1lLCBtb2RlKSBta2RpcihuYW1lKQorLy8gV2luZG93cyBkb2Vzbid0IGhhdmUgc3ltYm9saWMgbGlua3MuCisjZGVmaW5lIGxzdGF0IHN0YXQKKyNpZm5kZWYgRl9PSworI2RlZmluZSBGX09LIDAwICAvLyBub3QgZGVmaW5lZCBieSBNU1ZDIGZvciB3aGF0ZXZlciByZWFzb24KKyNlbmRpZgorI2VuZGlmCisKK2Jvb2wgRmlsZTo6RXhpc3RzKGNvbnN0IHN0cmluZyYgbmFtZSkgeworICByZXR1cm4gYWNjZXNzKG5hbWUuY19zdHIoKSwgRl9PSykgPT0gMDsKK30KKworYm9vbCBGaWxlOjpSZWFkRmlsZVRvU3RyaW5nKGNvbnN0IHN0cmluZyYgbmFtZSwgc3RyaW5nKiBvdXRwdXQpIHsKKyAgY2hhciBidWZmZXJbMTAyNF07CisgIEZJTEUqIGZpbGUgPSBmb3BlbihuYW1lLmNfc3RyKCksICJyYiIpOworICBpZiAoZmlsZSA9PSBOVUxMKSByZXR1cm4gZmFsc2U7CisKKyAgd2hpbGUgKHRydWUpIHsKKyAgICBzaXplX3QgbiA9IGZyZWFkKGJ1ZmZlciwgMSwgc2l6ZW9mKGJ1ZmZlciksIGZpbGUpOworICAgIGlmIChuIDw9IDApIGJyZWFrOworICAgIG91dHB1dC0+YXBwZW5kKGJ1ZmZlciwgbik7CisgIH0KKworICBpbnQgZXJyb3IgPSBmZXJyb3IoZmlsZSk7CisgIGlmIChmY2xvc2UoZmlsZSkgIT0gMCkgcmV0dXJuIGZhbHNlOworICByZXR1cm4gZXJyb3IgPT0gMDsKK30KKwordm9pZCBGaWxlOjpSZWFkRmlsZVRvU3RyaW5nT3JEaWUoY29uc3Qgc3RyaW5nJiBuYW1lLCBzdHJpbmcqIG91dHB1dCkgeworICBHT09HTEVfQ0hFQ0soUmVhZEZpbGVUb1N0cmluZyhuYW1lLCBvdXRwdXQpKSA8PCAiQ291bGQgbm90IHJlYWQ6ICIgPDwgbmFtZTsKK30KKworYm9vbCBGaWxlOjpXcml0ZVN0cmluZ1RvRmlsZShjb25zdCBzdHJpbmcmIGNvbnRlbnRzLCBjb25zdCBzdHJpbmcmIG5hbWUpIHsKKyAgRklMRSogZmlsZSA9IGZvcGVuKG5hbWUuY19zdHIoKSwgIndiIik7CisgIGlmIChmaWxlID09IE5VTEwpIHsKKyAgICBHT09HTEVfTE9HKEVSUk9SKSA8PCAiZm9wZW4oIiA8PCBuYW1lIDw8ICIsIFwid2JcIik6ICIgPDwgc3RyZXJyb3IoZXJybm8pOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIGlmIChmd3JpdGUoY29udGVudHMuZGF0YSgpLCAxLCBjb250ZW50cy5zaXplKCksIGZpbGUpICE9IGNvbnRlbnRzLnNpemUoKSkgeworICAgIEdPT0dMRV9MT0coRVJST1IpIDw8ICJmd3JpdGUoIiA8PCBuYW1lIDw8ICIpOiAiIDw8IHN0cmVycm9yKGVycm5vKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBpZiAoZmNsb3NlKGZpbGUpICE9IDApIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgRmlsZTo6V3JpdGVTdHJpbmdUb0ZpbGVPckRpZShjb25zdCBzdHJpbmcmIGNvbnRlbnRzLCBjb25zdCBzdHJpbmcmIG5hbWUpIHsKKyAgRklMRSogZmlsZSA9IGZvcGVuKG5hbWUuY19zdHIoKSwgIndiIik7CisgIEdPT0dMRV9DSEVDSyhmaWxlICE9IE5VTEwpCisgICAgICA8PCAiZm9wZW4oIiA8PCBuYW1lIDw8ICIsIFwid2JcIik6ICIgPDwgc3RyZXJyb3IoZXJybm8pOworICBHT09HTEVfQ0hFQ0tfRVEoZndyaXRlKGNvbnRlbnRzLmRhdGEoKSwgMSwgY29udGVudHMuc2l6ZSgpLCBmaWxlKSwKKyAgICAgICAgICAgICAgICAgIGNvbnRlbnRzLnNpemUoKSkKKyAgICAgIDw8ICJmd3JpdGUoIiA8PCBuYW1lIDw8ICIpOiAiIDw8IHN0cmVycm9yKGVycm5vKTsKKyAgR09PR0xFX0NIRUNLKGZjbG9zZShmaWxlKSA9PSAwKQorICAgICAgPDwgImZjbG9zZSgiIDw8IG5hbWUgPDwgIik6ICIgPDwgc3RyZXJyb3IoZXJybm8pOworfQorCitib29sIEZpbGU6OkNyZWF0ZURpcihjb25zdCBzdHJpbmcmIG5hbWUsIGludCBtb2RlKSB7CisgIHJldHVybiBta2RpcihuYW1lLmNfc3RyKCksIG1vZGUpID09IDA7Cit9CisKK2Jvb2wgRmlsZTo6UmVjdXJzaXZlbHlDcmVhdGVEaXIoY29uc3Qgc3RyaW5nJiBwYXRoLCBpbnQgbW9kZSkgeworICBpZiAoQ3JlYXRlRGlyKHBhdGgsIG1vZGUpKSByZXR1cm4gdHJ1ZTsKKworICBpZiAoRXhpc3RzKHBhdGgpKSByZXR1cm4gZmFsc2U7CisKKyAgLy8gVHJ5IGNyZWF0aW5nIHRoZSBwYXJlbnQuCisgIHN0cmluZzo6c2l6ZV90eXBlIHNsYXNocG9zID0gcGF0aC5maW5kX2xhc3Rfb2YoJy8nKTsKKyAgaWYgKHNsYXNocG9zID09IHN0cmluZzo6bnBvcykgeworICAgIC8vIE5vIHBhcmVudCBnaXZlbi4KKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICByZXR1cm4gUmVjdXJzaXZlbHlDcmVhdGVEaXIocGF0aC5zdWJzdHIoMCwgc2xhc2hwb3MpLCBtb2RlKSAmJgorICAgICAgICAgQ3JlYXRlRGlyKHBhdGgsIG1vZGUpOworfQorCit2b2lkIEZpbGU6OkRlbGV0ZVJlY3Vyc2l2ZWx5KGNvbnN0IHN0cmluZyYgbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCogZHVtbXkxLCB2b2lkKiBkdW1teTIpIHsKKyAgaWYgKG5hbWUuZW1wdHkoKSkgcmV0dXJuOworCisgIC8vIFdlIGRvbid0IGNhcmUgdG9vIG11Y2ggYWJvdXQgZXJyb3IgY2hlY2tpbmcgaGVyZSBzaW5jZSB0aGlzIGlzIG9ubHkgdXNlZAorICAvLyBpbiB0ZXN0cyB0byBkZWxldGUgdGVtcG9yYXJ5IGRpcmVjdG9yaWVzIHRoYXQgYXJlIHVuZGVyIC90bXAgYW55d2F5LgorCisjaWZkZWYgX01TQ19WRVIKKyAgLy8gVGhpcyBpbnRlcmZhY2UgaXMgc28gd2VpcmQuCisgIFdJTjMyX0ZJTkRfREFUQSBmaW5kX2RhdGE7CisgIEhBTkRMRSBmaW5kX2hhbmRsZSA9IEZpbmRGaXJzdEZpbGUoKG5hbWUgKyAiLyoiKS5jX3N0cigpLCAmZmluZF9kYXRhKTsKKyAgaWYgKGZpbmRfaGFuZGxlID09IElOVkFMSURfSEFORExFX1ZBTFVFKSB7CisgICAgLy8gSnVzdCBkZWxldGUgaXQsIHdoYXRldmVyIGl0IGlzLgorICAgIERlbGV0ZUZpbGUobmFtZS5jX3N0cigpKTsKKyAgICBSZW1vdmVEaXJlY3RvcnkobmFtZS5jX3N0cigpKTsKKyAgICByZXR1cm47CisgIH0KKworICBkbyB7CisgICAgc3RyaW5nIGVudHJ5X25hbWUgPSBmaW5kX2RhdGEuY0ZpbGVOYW1lOworICAgIGlmIChlbnRyeV9uYW1lICE9ICIuIiAmJiBlbnRyeV9uYW1lICE9ICIuLiIpIHsKKyAgICAgIHN0cmluZyBwYXRoID0gbmFtZSArICIvIiArIGVudHJ5X25hbWU7CisgICAgICBpZiAoZmluZF9kYXRhLmR3RmlsZUF0dHJpYnV0ZXMgJiBGSUxFX0FUVFJJQlVURV9ESVJFQ1RPUlkpIHsKKyAgICAgICAgRGVsZXRlUmVjdXJzaXZlbHkocGF0aCwgTlVMTCwgTlVMTCk7CisgICAgICAgIFJlbW92ZURpcmVjdG9yeShwYXRoLmNfc3RyKCkpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgRGVsZXRlRmlsZShwYXRoLmNfc3RyKCkpOworICAgICAgfQorICAgIH0KKyAgfSB3aGlsZShGaW5kTmV4dEZpbGUoZmluZF9oYW5kbGUsICZmaW5kX2RhdGEpKTsKKyAgRmluZENsb3NlKGZpbmRfaGFuZGxlKTsKKworICBSZW1vdmVEaXJlY3RvcnkobmFtZS5jX3N0cigpKTsKKyNlbHNlCisgIC8vIFVzZSBvcGVuZGlyKCkhICBZYXkhCisgIC8vIGxzdGF0ID0gRG9uJ3QgZm9sbG93IHN5bWJvbGljIGxpbmtzLgorICBzdHJ1Y3Qgc3RhdCBzdGF0czsKKyAgaWYgKGxzdGF0KG5hbWUuY19zdHIoKSwgJnN0YXRzKSAhPSAwKSByZXR1cm47CisKKyAgaWYgKFNfSVNESVIoc3RhdHMuc3RfbW9kZSkpIHsKKyAgICBESVIqIGRpciA9IG9wZW5kaXIobmFtZS5jX3N0cigpKTsKKyAgICBpZiAoZGlyICE9IE5VTEwpIHsKKyAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgIHN0cnVjdCBkaXJlbnQqIGVudHJ5ID0gcmVhZGRpcihkaXIpOworICAgICAgICBpZiAoZW50cnkgPT0gTlVMTCkgYnJlYWs7CisgICAgICAgIHN0cmluZyBlbnRyeV9uYW1lID0gZW50cnktPmRfbmFtZTsKKyAgICAgICAgaWYgKGVudHJ5X25hbWUgIT0gIi4iICYmIGVudHJ5X25hbWUgIT0gIi4uIikgeworICAgICAgICAgIERlbGV0ZVJlY3Vyc2l2ZWx5KG5hbWUgKyAiLyIgKyBlbnRyeV9uYW1lLCBOVUxMLCBOVUxMKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKworICAgIGNsb3NlZGlyKGRpcik7CisgICAgcm1kaXIobmFtZS5jX3N0cigpKTsKKworICB9IGVsc2UgaWYgKFNfSVNSRUcoc3RhdHMuc3RfbW9kZSkpIHsKKyAgICByZW1vdmUobmFtZS5jX3N0cigpKTsKKyAgfQorI2VuZGlmCit9CisKK2Jvb2wgRmlsZTo6Q2hhbmdlV29ya2luZ0RpcmVjdG9yeShjb25zdCBzdHJpbmcmIG5ld193b3JraW5nX2RpcmVjdG9yeSkgeworICByZXR1cm4gY2hkaXIobmV3X3dvcmtpbmdfZGlyZWN0b3J5LmNfc3RyKCkpID09IDA7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2ZpbGUuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGluZy9maWxlLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmY2M2Y4MAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGluZy9maWxlLmgKQEAgLTAsMCArMSwxMDAgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyBlbXVsYXRlcyBnb29nbGUzL2ZpbGUvYmFzZS9maWxlLmgKKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfVEVTVElOR19GSUxFX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfVEVTVElOR19GSUxFX0hfXworCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKK2NvbnN0IGludCBERUZBVUxUX0ZJTEVfTU9ERSA9IDA3Nzc7CisKKy8vIFByb3RvY29sIGJ1ZmZlciBjb2RlIG9ubHkgdXNlcyBhIGNvdXBsZSBzdGF0aWMgbWV0aG9kcyBvZiBGaWxlLCBhbmQgb25seQorLy8gaW4gdGVzdHMuCitjbGFzcyBGaWxlIHsKKyBwdWJsaWM6CisgIC8vIENoZWNrIGlmIHRoZSBmaWxlIGV4aXN0cy4KKyAgc3RhdGljIGJvb2wgRXhpc3RzKGNvbnN0IHN0cmluZyYgbmFtZSk7CisKKyAgLy8gUmVhZCBhbiBlbnRpcmUgZmlsZSB0byBhIHN0cmluZy4gIFJldHVybiB0cnVlIGlmIHN1Y2Nlc3NmdWwsIGZhbHNlCisgIC8vIG90aGVyd2lzZS4KKyAgc3RhdGljIGJvb2wgUmVhZEZpbGVUb1N0cmluZyhjb25zdCBzdHJpbmcmIG5hbWUsIHN0cmluZyogb3V0cHV0KTsKKworICAvLyBTYW1lIGFzIGFib3ZlLCBidXQgY3Jhc2ggb24gZmFpbHVyZS4KKyAgc3RhdGljIHZvaWQgUmVhZEZpbGVUb1N0cmluZ09yRGllKGNvbnN0IHN0cmluZyYgbmFtZSwgc3RyaW5nKiBvdXRwdXQpOworCisgIC8vIENyZWF0ZSBhIGZpbGUgYW5kIHdyaXRlIGEgc3RyaW5nIHRvIGl0LgorICBzdGF0aWMgYm9vbCBXcml0ZVN0cmluZ1RvRmlsZShjb25zdCBzdHJpbmcmIGNvbnRlbnRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIG5hbWUpOworCisgIC8vIFNhbWUgYXMgYWJvdmUsIGJ1dCBjcmFzaCBvbiBmYWlsdXJlLgorICBzdGF0aWMgdm9pZCBXcml0ZVN0cmluZ1RvRmlsZU9yRGllKGNvbnN0IHN0cmluZyYgY29udGVudHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBuYW1lKTsKKworICAvLyBDcmVhdGUgYSBkaXJlY3RvcnkuCisgIHN0YXRpYyBib29sIENyZWF0ZURpcihjb25zdCBzdHJpbmcmIG5hbWUsIGludCBtb2RlKTsKKworICAvLyBDcmVhdGUgYSBkaXJlY3RvcnkgYW5kIGFsbCBwYXJlbnQgZGlyZWN0b3JpZXMgaWYgbmVjZXNzYXJ5LgorICBzdGF0aWMgYm9vbCBSZWN1cnNpdmVseUNyZWF0ZURpcihjb25zdCBzdHJpbmcmIHBhdGgsIGludCBtb2RlKTsKKworICAvLyBJZiAibmFtZSIgaXMgYSBmaWxlLCB3ZSBkZWxldGUgaXQuICBJZiBpdCBpcyBhIGRpcmVjdG9yeSwgd2UKKyAgLy8gY2FsbCBEZWxldGVSZWN1cnNpdmVseSgpIGZvciBlYWNoIGZpbGUgb3IgZGlyZWN0b3J5IChvdGhlciB0aGFuCisgIC8vIGRvdCBhbmQgZG91YmxlLWRvdCkgd2l0aGluIGl0LCBhbmQgdGhlbiBkZWxldGUgdGhlIGRpcmVjdG9yeSBpdHNlbGYuCisgIC8vIFRoZSAiZHVtbXkiIHBhcmFtZXRlcnMgaGF2ZSBhIG1lYW5pbmcgaW4gdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcworICAvLyBtZXRob2QgYnV0IHRoZXkgYXJlIG5vdCB1c2VkIGFueXdoZXJlIGluIHByb3RvY29sIGJ1ZmZlcnMuCisgIHN0YXRpYyB2b2lkIERlbGV0ZVJlY3Vyc2l2ZWx5KGNvbnN0IHN0cmluZyYgbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCogZHVtbXkxLCB2b2lkKiBkdW1teTIpOworCisgIC8vIENoYW5nZSB3b3JraW5nIGRpcmVjdG9yeSB0byBnaXZlbiBkaXJlY3RvcnkuCisgIHN0YXRpYyBib29sIENoYW5nZVdvcmtpbmdEaXJlY3RvcnkoY29uc3Qgc3RyaW5nJiBuZXdfd29ya2luZ19kaXJlY3RvcnkpOworCisgIHN0YXRpYyBib29sIEdldENvbnRlbnRzKAorICAgICAgY29uc3Qgc3RyaW5nJiBuYW1lLCBzdHJpbmcqIG91dHB1dCwgYm9vbCAvKmlzX2RlZmF1bHQqLykgeworICAgIHJldHVybiBSZWFkRmlsZVRvU3RyaW5nKG5hbWUsIG91dHB1dCk7CisgIH0KKworICBzdGF0aWMgYm9vbCBTZXRDb250ZW50cygKKyAgICAgIGNvbnN0IHN0cmluZyYgbmFtZSwgY29uc3Qgc3RyaW5nJiBjb250ZW50cywgYm9vbCAvKmlzX2RlZmF1bHQqLykgeworICAgIHJldHVybiBXcml0ZVN0cmluZ1RvRmlsZShjb250ZW50cywgbmFtZSk7CisgIH0KKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhGaWxlKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9URVNUSU5HX0ZJTEVfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZ29vZ2xldGVzdC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0LmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJiOWNkZGUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZ29vZ2xldGVzdC5jYwpAQCAtMCwwICsxLDI2NyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vIGVtdWxhdGVzIGdvb2dsZTMvdGVzdGluZy9iYXNlL3B1YmxpYy9nb29nbGV0ZXN0LmNjCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZmlsZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisjaW5jbHVkZSA8c3lzL3N0YXQuaD4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKyNpbmNsdWRlIDxlcnJuby5oPgorI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2lmZGVmIF9NU0NfVkVSCisjaW5jbHVkZSA8aW8uaD4KKyNpbmNsdWRlIDxkaXJlY3QuaD4KKyNlbHNlCisjaW5jbHVkZSA8dW5pc3RkLmg+CisjZW5kaWYKKyNpbmNsdWRlIDxzdGRpby5oPgorI2luY2x1ZGUgPGZjbnRsLmg+CisjaW5jbHVkZSA8aW9zdHJlYW0+CisjaW5jbHVkZSA8ZnN0cmVhbT4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCisjaWZkZWYgX1dJTjMyCisjZGVmaW5lIG1rZGlyKG5hbWUsIG1vZGUpIG1rZGlyKG5hbWUpCisjZW5kaWYKKworI2lmbmRlZiBPX0JJTkFSWQorI2lmZGVmIF9PX0JJTkFSWQorI2RlZmluZSBPX0JJTkFSWSBfT19CSU5BUlkKKyNlbHNlCisjZGVmaW5lIE9fQklOQVJZIDAgICAgIC8vIElmIHRoaXMgaXNuJ3QgZGVmaW5lZCwgdGhlIHBsYXRmb3JtIGRvZXNuJ3QgbmVlZCBpdC4KKyNlbmRpZgorI2VuZGlmCisKK3N0cmluZyBUZXN0U291cmNlRGlyKCkgeworI2lmbmRlZiBHT09HTEVfVEhJUkRfUEFSVFlfUFJPVE9CVUYKKyNpZm5kZWYgX01TQ19WRVIKKyAgLy8gYXV0b21ha2Ugc2V0cyB0aGUgInNyY2RpciIgZW52aXJvbm1lbnQgdmFyaWFibGUuCisgIGNoYXIqIHJlc3VsdCA9IGdldGVudigic3JjZGlyIik7CisgIGlmIChyZXN1bHQgIT0gTlVMTCkgeworICAgIHJldHVybiByZXN1bHQ7CisgIH0KKyNlbmRpZiAgLy8gX01TQ19WRVIKKworICAvLyBMb29rIGZvciB0aGUgInNyYyIgZGlyZWN0b3J5LgorICBzdHJpbmcgcHJlZml4ID0gIi4iOworCisgIHdoaWxlICghRmlsZTo6RXhpc3RzKHByZWZpeCArICIvc3JjL2dvb2dsZS9wcm90b2J1ZiIpKSB7CisgICAgaWYgKCFGaWxlOjpFeGlzdHMocHJlZml4KSkgeworICAgICAgR09PR0xFX0xPRyhGQVRBTCkKKyAgICAgICAgPDwgIkNvdWxkIG5vdCBmaW5kIHByb3RvYnVmIHNvdXJjZSBjb2RlLiAgUGxlYXNlIHJ1biB0ZXN0cyBmcm9tICIKKyAgICAgICAgICAgInNvbWV3aGVyZSB3aXRoaW4gdGhlIHByb3RvYnVmIHNvdXJjZSBwYWNrYWdlLiI7CisgICAgfQorICAgIHByZWZpeCArPSAiLy4uIjsKKyAgfQorICByZXR1cm4gcHJlZml4ICsgIi9zcmMiOworI2Vsc2UKKyAgcmV0dXJuICJ0aGlyZF9wYXJ0eS9wcm90b2J1Zi9zcmMiOworI2VuZGlmICAvLyBHT09HTEVfVEhJUkRfUEFSVFlfUFJPVE9CVUYKK30KKworbmFtZXNwYWNlIHsKKworc3RyaW5nIEdldFRlbXBvcmFyeURpcmVjdG9yeU5hbWUoKSB7CisgIC8vIFRlc3RzIHJ1biB1bmRlciBCYXplbCAic2hvdWxkIG5vdCIgdXNlIC90bXAuIEJhemVsIHNldHMgdGhpcyBlbnZpcm9ubWVudAorICAvLyB2YXJpYWJsZSBmb3IgdGVzdHMgdG8gdXNlIGluc3RlYWQuCisgIGNoYXIgKmZyb21fZW52aXJvbm1lbnQgPSBnZXRlbnYoIlRFU1RfVE1QRElSIik7CisgIGlmIChmcm9tX2Vudmlyb25tZW50ICE9IE5VTEwgJiYgZnJvbV9lbnZpcm9ubWVudFswXSAhPSAnXDAnKSB7CisgICAgcmV0dXJuIHN0cmluZyhmcm9tX2Vudmlyb25tZW50KSArICIvcHJvdG9idWZfdG1wZGlyIjsKKyAgfQorCisgIC8vIHRtcG5hbSgpIGlzIGdlbmVyYWxseSBub3QgY29uc2lkZXJlZCBzYWZlIGJ1dCB3ZSdyZSBvbmx5IHVzaW5nIGl0IGZvcgorICAvLyB0ZXN0aW5nLiAgV2UgY2Fubm90IHVzZSB0bXBmaWxlKCkgb3IgbWtzdGVtcCgpIHNpbmNlIHdlJ3JlIGNyZWF0aW5nIGEKKyAgLy8gZGlyZWN0b3J5LgorICBjaGFyIGJbTF90bXBuYW0gKyAxXTsgICAgIC8vIEhQVVggbXVsdGl0aHJlYWQgcmV0dXJuIDAgaWYgcyBpcyAwCisgIHN0cmluZyByZXN1bHQgPSB0bXBuYW0oYik7CisjaWZkZWYgX1dJTjMyCisgIC8vIE9uIFdpbjMyLCB0bXBuYW0oKSByZXR1cm5zIGEgZmlsZSBwcmVmaXhlZCB3aXRoICdcJywgYnV0IHdoaWNoIGlzIHN1cHBvc2VkCisgIC8vIHRvIGJlIHVzZWQgaW4gdGhlIGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnkuICBXVEY/CisgIGlmIChIYXNQcmVmaXhTdHJpbmcocmVzdWx0LCAiXFwiKSkgeworICAgIHJlc3VsdC5lcmFzZSgwLCAxKTsKKyAgfQorICAvLyBUaGUgV2luMzIgQVBJIGFjY2VwdHMgZm9yd2FyZCBzbGFzaGVzIGFzIGEgcGF0aCBkZWxpbWl0ZXIgZXZlbiB0aG91Z2gKKyAgLy8gYmFja3NsYXNoZXMgYXJlIHN0YW5kYXJkLiAgTGV0J3MgYXZvaWQgY29uZnVzaW9uIGFuZCB1c2Ugb25seSBmb3J3YXJkCisgIC8vIHNsYXNoZXMuCisgIHJlc3VsdCA9IFN0cmluZ1JlcGxhY2UocmVzdWx0LCAiXFwiLCAiLyIsIHRydWUpOworI2VuZGlmICAvLyBfV0lOMzIKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworLy8gQ3JlYXRlcyBhIHRlbXBvcmFyeSBkaXJlY3Rvcnkgb24gZGVtYW5kIGFuZCBkZWxldGVzIGl0IHdoZW4gdGhlIHByb2Nlc3MKKy8vIHF1aXRzLgorY2xhc3MgVGVtcERpckRlbGV0ZXIgeworIHB1YmxpYzoKKyAgVGVtcERpckRlbGV0ZXIoKSB7fQorICB+VGVtcERpckRlbGV0ZXIoKSB7CisgICAgaWYgKCFuYW1lXy5lbXB0eSgpKSB7CisgICAgICBGaWxlOjpEZWxldGVSZWN1cnNpdmVseShuYW1lXywgTlVMTCwgTlVMTCk7CisgICAgfQorICB9CisKKyAgc3RyaW5nIEdldFRlbXBEaXIoKSB7CisgICAgaWYgKG5hbWVfLmVtcHR5KCkpIHsKKyAgICAgIG5hbWVfID0gR2V0VGVtcG9yYXJ5RGlyZWN0b3J5TmFtZSgpOworICAgICAgR09PR0xFX0NIRUNLKG1rZGlyKG5hbWVfLmNfc3RyKCksIDA3NzcpID09IDApIDw8IHN0cmVycm9yKGVycm5vKTsKKworICAgICAgLy8gU3RpY2sgYSBmaWxlIGluIHRoZSBkaXJlY3RvcnkgdGhhdCB0ZWxscyBwZW9wbGUgd2hhdCB0aGlzIGlzLCBpbiBjYXNlCisgICAgICAvLyB3ZSBhYm9ydCBhbmQgZG9uJ3QgZ2V0IGEgY2hhbmNlIHRvIGRlbGV0ZSBpdC4KKyAgICAgIEZpbGU6OldyaXRlU3RyaW5nVG9GaWxlT3JEaWUoIiIsIG5hbWVfICsgIi9URU1QX0RJUl9GT1JfUFJPVE9CVUZfVEVTVFMiKTsKKyAgICB9CisgICAgcmV0dXJuIG5hbWVfOworICB9CisKKyBwcml2YXRlOgorICBzdHJpbmcgbmFtZV87Cit9OworCitUZW1wRGlyRGVsZXRlciB0ZW1wX2Rpcl9kZWxldGVyXzsKKworfSAgLy8gbmFtZXNwYWNlCisKK3N0cmluZyBUZXN0VGVtcERpcigpIHsKKyAgcmV0dXJuIHRlbXBfZGlyX2RlbGV0ZXJfLkdldFRlbXBEaXIoKTsKK30KKworLy8gVE9ETyhrZW50b24pOiAgU2hhcmUgZHVwbGljYXRlZCBjb2RlIGJlbG93LiAgVG9vIGJ1c3kvbGF6eSBmb3Igbm93LgorCitzdGF0aWMgc3RyaW5nIHN0ZG91dF9jYXB0dXJlX2ZpbGVuYW1lXzsKK3N0YXRpYyBzdHJpbmcgc3RkZXJyX2NhcHR1cmVfZmlsZW5hbWVfOworc3RhdGljIGludCBvcmlnaW5hbF9zdGRvdXRfID0gLTE7CitzdGF0aWMgaW50IG9yaWdpbmFsX3N0ZGVycl8gPSAtMTsKKwordm9pZCBDYXB0dXJlVGVzdFN0ZG91dCgpIHsKKyAgR09PR0xFX0NIRUNLX0VRKG9yaWdpbmFsX3N0ZG91dF8sIC0xKSA8PCAiQWxyZWFkeSBjYXB0dXJpbmcuIjsKKworICBzdGRvdXRfY2FwdHVyZV9maWxlbmFtZV8gPSBUZXN0VGVtcERpcigpICsgIi9jYXB0dXJlZF9zdGRvdXQiOworCisgIGludCBmZCA9IG9wZW4oc3Rkb3V0X2NhcHR1cmVfZmlsZW5hbWVfLmNfc3RyKCksCisgICAgICAgICAgICAgICAgT19XUk9OTFkgfCBPX0NSRUFUIHwgT19FWENMIHwgT19CSU5BUlksIDA3NzcpOworICBHT09HTEVfQ0hFQ0soZmQgPj0gMCkgPDwgIm9wZW46ICIgPDwgc3RyZXJyb3IoZXJybm8pOworCisgIG9yaWdpbmFsX3N0ZG91dF8gPSBkdXAoMSk7CisgIGNsb3NlKDEpOworICBkdXAyKGZkLCAxKTsKKyAgY2xvc2UoZmQpOworfQorCit2b2lkIENhcHR1cmVUZXN0U3RkZXJyKCkgeworICBHT09HTEVfQ0hFQ0tfRVEob3JpZ2luYWxfc3RkZXJyXywgLTEpIDw8ICJBbHJlYWR5IGNhcHR1cmluZy4iOworCisgIHN0ZGVycl9jYXB0dXJlX2ZpbGVuYW1lXyA9IFRlc3RUZW1wRGlyKCkgKyAiL2NhcHR1cmVkX3N0ZGVyciI7CisKKyAgaW50IGZkID0gb3BlbihzdGRlcnJfY2FwdHVyZV9maWxlbmFtZV8uY19zdHIoKSwKKyAgICAgICAgICAgICAgICBPX1dST05MWSB8IE9fQ1JFQVQgfCBPX0VYQ0wgfCBPX0JJTkFSWSwgMDc3Nyk7CisgIEdPT0dMRV9DSEVDSyhmZCA+PSAwKSA8PCAib3BlbjogIiA8PCBzdHJlcnJvcihlcnJubyk7CisKKyAgb3JpZ2luYWxfc3RkZXJyXyA9IGR1cCgyKTsKKyAgY2xvc2UoMik7CisgIGR1cDIoZmQsIDIpOworICBjbG9zZShmZCk7Cit9CisKK3N0cmluZyBHZXRDYXB0dXJlZFRlc3RTdGRvdXQoKSB7CisgIEdPT0dMRV9DSEVDS19ORShvcmlnaW5hbF9zdGRvdXRfLCAtMSkgPDwgIk5vdCBjYXB0dXJpbmcuIjsKKworICBjbG9zZSgxKTsKKyAgZHVwMihvcmlnaW5hbF9zdGRvdXRfLCAxKTsKKyAgb3JpZ2luYWxfc3Rkb3V0XyA9IC0xOworCisgIHN0cmluZyByZXN1bHQ7CisgIEZpbGU6OlJlYWRGaWxlVG9TdHJpbmdPckRpZShzdGRvdXRfY2FwdHVyZV9maWxlbmFtZV8sICZyZXN1bHQpOworCisgIHJlbW92ZShzdGRvdXRfY2FwdHVyZV9maWxlbmFtZV8uY19zdHIoKSk7CisKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RyaW5nIEdldENhcHR1cmVkVGVzdFN0ZGVycigpIHsKKyAgR09PR0xFX0NIRUNLX05FKG9yaWdpbmFsX3N0ZGVycl8sIC0xKSA8PCAiTm90IGNhcHR1cmluZy4iOworCisgIGNsb3NlKDIpOworICBkdXAyKG9yaWdpbmFsX3N0ZGVycl8sIDIpOworICBvcmlnaW5hbF9zdGRlcnJfID0gLTE7CisKKyAgc3RyaW5nIHJlc3VsdDsKKyAgRmlsZTo6UmVhZEZpbGVUb1N0cmluZ09yRGllKHN0ZGVycl9jYXB0dXJlX2ZpbGVuYW1lXywgJnJlc3VsdCk7CisKKyAgcmVtb3ZlKHN0ZGVycl9jYXB0dXJlX2ZpbGVuYW1lXy5jX3N0cigpKTsKKworICByZXR1cm4gcmVzdWx0OworfQorCitTY29wZWRNZW1vcnlMb2cqIFNjb3BlZE1lbW9yeUxvZzo6YWN0aXZlX2xvZ18gPSBOVUxMOworCitTY29wZWRNZW1vcnlMb2c6OlNjb3BlZE1lbW9yeUxvZygpIHsKKyAgR09PR0xFX0NIRUNLKGFjdGl2ZV9sb2dfID09IE5VTEwpOworICBhY3RpdmVfbG9nXyA9IHRoaXM7CisgIG9sZF9oYW5kbGVyXyA9IFNldExvZ0hhbmRsZXIoJkhhbmRsZUxvZyk7Cit9CisKK1Njb3BlZE1lbW9yeUxvZzo6flNjb3BlZE1lbW9yeUxvZygpIHsKKyAgU2V0TG9nSGFuZGxlcihvbGRfaGFuZGxlcl8pOworICBhY3RpdmVfbG9nXyA9IE5VTEw7Cit9CisKK2NvbnN0IHZlY3RvcjxzdHJpbmc+JiBTY29wZWRNZW1vcnlMb2c6OkdldE1lc3NhZ2VzKExvZ0xldmVsIGxldmVsKSB7CisgIEdPT0dMRV9DSEVDSyhsZXZlbCA9PSBFUlJPUiB8fAorICAgICAgICAgICAgICAgbGV2ZWwgPT0gV0FSTklORyk7CisgIHJldHVybiBtZXNzYWdlc19bbGV2ZWxdOworfQorCit2b2lkIFNjb3BlZE1lbW9yeUxvZzo6SGFuZGxlTG9nKExvZ0xldmVsIGxldmVsLCBjb25zdCBjaGFyKiBmaWxlbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGxpbmUsIGNvbnN0IHN0cmluZyYgbWVzc2FnZSkgeworICBHT09HTEVfQ0hFQ0soYWN0aXZlX2xvZ18gIT0gTlVMTCk7CisgIGlmIChsZXZlbCA9PSBFUlJPUiB8fCBsZXZlbCA9PSBXQVJOSU5HKSB7CisgICAgYWN0aXZlX2xvZ18tPm1lc3NhZ2VzX1tsZXZlbF0ucHVzaF9iYWNrKG1lc3NhZ2UpOworICB9Cit9CisKK25hbWVzcGFjZSB7CisKKy8vIEZvcmNlIHNodXRkb3duIGF0IHByb2Nlc3MgZXhpdCBzbyB0aGF0IHdlIGNhbiB0ZXN0IGZvciBtZW1vcnkgbGVha3MuICBUbworLy8gYWN0dWFsbHkgY2hlY2sgZm9yIGxlYWtzLCBJIHN1Z2dlc3QgdXNpbmcgdGhlIGhlYXAgY2hlY2tlciBpbmNsdWRlZCB3aXRoCisvLyBnb29nbGUtcGVyZnRvb2xzLiAgU2V0IGl0IHRvICJkcmFjb25pYW4iIG1vZGUgdG8gZW5zdXJlIHRoYXQgZXZlcnkgbGFzdAorLy8gY2FsbCB0byBtYWxsb2MoKSBoYXMgYSBjb3JyZXNwb25kaW5nIGZyZWUoKS4KK3N0cnVjdCBGb3JjZVNodXRkb3duIHsKKyAgfkZvcmNlU2h1dGRvd24oKSB7CisgICAgU2h1dGRvd25Qcm90b2J1ZkxpYnJhcnkoKTsKKyAgfQorfSBmb3JjZV9zaHV0ZG93bjsKKworfSAgLy8gbmFtZXNwYWNlCisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2dvb2dsZXRlc3QuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzBkOTllNgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0LmgKQEAgLTAsMCArMSwxMDIgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyBlbXVsYXRlcyBnb29nbGUzL3Rlc3RpbmcvYmFzZS9wdWJsaWMvZ29vZ2xldGVzdC5oCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX0dPT0dMRVRFU1RfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9HT09HTEVURVNUX0hfXworCisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHZlY3Rvcj4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisKKy8vIERpc2FibGUgZGVhdGggdGVzdHMgaWYgd2UgdXNlIGV4Y2VwdGlvbnMgaW4gQ0hFQ0soKS4KKyNpZiAhUFJPVE9CVUZfVVNFX0VYQ0VQVElPTlMgJiYgZGVmaW5lZChHVEVTVF9IQVNfREVBVEhfVEVTVCkKKyNkZWZpbmUgUFJPVE9CVUZfSEFTX0RFQVRIX1RFU1QKKyNlbmRpZgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKKy8vIFdoZW4gcnVubmluZyB1bml0dGVzdHMsIGdldCB0aGUgZGlyZWN0b3J5IGNvbnRhaW5pbmcgdGhlIHNvdXJjZSBjb2RlLgorc3RyaW5nIFRlc3RTb3VyY2VEaXIoKTsKKworLy8gV2hlbiBydW5uaW5nIHVuaXR0ZXN0cywgZ2V0IGEgZGlyZWN0b3J5IHdoZXJlIHRlbXBvcmFyeSBmaWxlcyBtYXkgYmUKKy8vIHBsYWNlZC4KK3N0cmluZyBUZXN0VGVtcERpcigpOworCisvLyBDYXB0dXJlIGFsbCB0ZXh0IHdyaXR0ZW4gdG8gc3Rkb3V0IG9yIHN0ZGVyci4KK3ZvaWQgQ2FwdHVyZVRlc3RTdGRvdXQoKTsKK3ZvaWQgQ2FwdHVyZVRlc3RTdGRlcnIoKTsKKworLy8gU3RvcCBjYXB0dXJpbmcgc3Rkb3V0IG9yIHN0ZGVyciBhbmQgcmV0dXJuIHRoZSB0ZXh0IGNhcHR1cmVkLgorc3RyaW5nIEdldENhcHR1cmVkVGVzdFN0ZG91dCgpOworc3RyaW5nIEdldENhcHR1cmVkVGVzdFN0ZGVycigpOworCisvLyBGb3IgdXNlIHdpdGggU2NvcGVkTWVtb3J5TG9nOjpHZXRNZXNzYWdlcygpLiAgSW5zaWRlIEdvb2dsZSB0aGUgTG9nTGV2ZWwKKy8vIGNvbnN0YW50cyBkb24ndCBoYXZlIHRoZSBMT0dMRVZFTF8gcHJlZml4LCBzbyB0aGUgY29kZSB0aGF0IHVzZWQKKy8vIFNjb3BlZE1lbW9yeUxvZyByZWZlcnMgdG8gTE9HTEVWRUxfRVJST1IgYXMganVzdCBFUlJPUi4KKyN1bmRlZiBFUlJPUiAgLy8gZGVmZW5kIGFnYWluc3QgcHJvbWlzY3VvdXMgd2luZG93cy5oCitzdGF0aWMgY29uc3QgTG9nTGV2ZWwgRVJST1IgPSBMT0dMRVZFTF9FUlJPUjsKK3N0YXRpYyBjb25zdCBMb2dMZXZlbCBXQVJOSU5HID0gTE9HTEVWRUxfV0FSTklORzsKKworLy8gUmVjZWl2ZXMgY29waWVzIG9mIGFsbCBMT0coRVJST1IpIG1lc3NhZ2VzIHdoaWxlIGluIHNjb3BlLiAgU2FtcGxlIHVzYWdlOgorLy8gICB7CisvLyAgICAgU2NvcGVkTWVtb3J5TG9nIGxvZzsgIC8vIGNvbnN0cnVjdG9yIHJlZ2lzdGVycyBvYmplY3QgYXMgYSBsb2cgc2luaworLy8gICAgIFNvbWVSb3V0aW5lVGhhdE1heUxvZ01lc3NhZ2VzKCk7CisvLyAgICAgY29uc3QgdmVjdG9yPHN0cmluZz4mIHdhcm5pbmdzID0gbG9nLkdldE1lc3NhZ2VzKEVSUk9SKTsKKy8vICAgfSAgLy8gZGVzdHJ1Y3RvciB1bnJlZ2lzdGVycyBvYmplY3QgYXMgYSBsb2cgc2luaworLy8gVGhpcyBpcyBhIGR1bW15IGltcGxlbWVudGF0aW9uIHdoaWNoIGNvdmVycyBvbmx5IHdoYXQgaXMgdXNlZCBieSBwcm90b2NvbAorLy8gYnVmZmVyIHVuaXQgdGVzdHMuCitjbGFzcyBTY29wZWRNZW1vcnlMb2cgeworIHB1YmxpYzoKKyAgU2NvcGVkTWVtb3J5TG9nKCk7CisgIHZpcnR1YWwgflNjb3BlZE1lbW9yeUxvZygpOworCisgIC8vIEZldGNoZXMgYWxsIG1lc3NhZ2VzIHdpdGggdGhlIGdpdmVuIHNldmVyaXR5IGxldmVsLgorICBjb25zdCB2ZWN0b3I8c3RyaW5nPiYgR2V0TWVzc2FnZXMoTG9nTGV2ZWwgZXJyb3IpOworCisgcHJpdmF0ZToKKyAgbWFwPExvZ0xldmVsLCB2ZWN0b3I8c3RyaW5nPiA+IG1lc3NhZ2VzXzsKKyAgTG9nSGFuZGxlciogb2xkX2hhbmRsZXJfOworCisgIHN0YXRpYyB2b2lkIEhhbmRsZUxvZyhMb2dMZXZlbCBsZXZlbCwgY29uc3QgY2hhciogZmlsZW5hbWUsIGludCBsaW5lLAorICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBtZXNzYWdlKTsKKworICBzdGF0aWMgU2NvcGVkTWVtb3J5TG9nKiBhY3RpdmVfbG9nXzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoU2NvcGVkTWVtb3J5TG9nKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9HT09HTEVURVNUX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL3pjZ3VuemlwLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL3pjZ3VuemlwLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc2ZjhjZmUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvemNndW56aXAuY2MKQEAgLTAsMCArMSw4MCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOSBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjogYnJpYW5vbHNvbkBnb29nbGUuY29tIChCcmlhbiBPbHNvbikKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorLy8KKy8vIFRlc3QgcHJvZ3JhbSB0byB2ZXJpZnkgdGhhdCBHemlwSW5wdXRTdHJlYW0gaXMgY29tcGF0aWJsZSB3aXRoIGNvbW1hbmQgbGluZQorLy8gZ3VuemlwIG9yIGphdmEudXRpbC56aXAuR3ppcElucHV0U3RyZWFtCisvLworLy8gUmVhZHMgZ3ppcCBzdHJlYW0gb24gc3RhbmRhcmQgaW5wdXQgYW5kIHdyaXRlcyBkZWNvbXByZXNzZWQgZGF0YSB0byBzdGFuZGFyZAorLy8gb3V0cHV0LgorCisjaW5jbHVkZSA8YXNzZXJ0Lmg+CisjaW5jbHVkZSA8c3RkaW8uaD4KKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlIDxmY250bC5oPgorCisjaWZkZWYgX1dJTjMyCisjaWZuZGVmIFNURElOX0ZJTEVOTworI2RlZmluZSBTVERJTl9GSUxFTk8gMAorI2VuZGlmCisjaWZuZGVmIFNURE9VVF9GSUxFTk8KKyNkZWZpbmUgU1RET1VUX0ZJTEVOTyAxCisjZW5kaWYKKyNlbmRpZgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL2d6aXBfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbC5oPgorCit1c2luZyBnb29nbGU6OnByb3RvYnVmOjppbzo6RmlsZUlucHV0U3RyZWFtOwordXNpbmcgZ29vZ2xlOjpwcm90b2J1Zjo6aW86Okd6aXBJbnB1dFN0cmVhbTsKKworaW50IG1haW4oaW50IGFyZ2MsIGNvbnN0IGNoYXIqKiBhcmd2KSB7CisgIEZpbGVJbnB1dFN0cmVhbSBmaW4oU1RESU5fRklMRU5PKTsKKyAgR3ppcElucHV0U3RyZWFtIGluKCZmaW4pOworCisgIHdoaWxlICh0cnVlKSB7CisgICAgY29uc3Qgdm9pZCogaW5wdHI7CisgICAgaW50IGlubGVuOworICAgIGJvb2wgb2s7CisgICAgb2sgPSBpbi5OZXh0KCZpbnB0ciwgJmlubGVuKTsKKyAgICBpZiAoIW9rKSB7CisgICAgICBicmVhazsKKyAgICB9CisgICAgaWYgKGlubGVuID4gMCkgeworICAgICAgaW50IGVyciA9IHdyaXRlKFNURE9VVF9GSUxFTk8sIGlucHRyLCBpbmxlbik7CisgICAgICBhc3NlcnQoZXJyID09IGlubGVuKTsKKyAgICB9CisgIH0KKworICByZXR1cm4gMDsKK30KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdGVzdGluZy96Y2d6aXAuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvemNnemlwLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk5MmRkYzYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvemNnemlwLmNjCkBAIC0wLDAgKzEsODYgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDkgR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGJyaWFub2xzb25AZ29vZ2xlLmNvbSAoQnJpYW4gT2xzb24pCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBUZXN0IHByb2dyYW0gdG8gdmVyaWZ5IHRoYXQgR3ppcE91dHB1dFN0cmVhbSBpcyBjb21wYXRpYmxlIHdpdGggY29tbWFuZCBsaW5lCisvLyBnemlwIG9yIGphdmEudXRpbC56aXAuR3ppcE91dHB1dFN0cmVhbQorLy8KKy8vIFJlYWRzIGRhdGEgb24gc3RhbmRhcmQgaW5wdXQgYW5kIHdyaXRlcyBjb21wcmVzc2VkIGd6aXAgc3RyZWFtIHRvIHN0YW5kYXJkCisvLyBvdXRwdXQuCisKKyNpbmNsdWRlIDxzdGRpby5oPgorI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2luY2x1ZGUgPGZjbnRsLmg+CisKKyNpZmRlZiBfV0lOMzIKKyNpZm5kZWYgU1RESU5fRklMRU5PCisjZGVmaW5lIFNURElOX0ZJTEVOTyAwCisjZW5kaWYKKyNpZm5kZWYgU1RET1VUX0ZJTEVOTworI2RlZmluZSBTVERPVVRfRklMRU5PIDEKKyNlbmRpZgorI2VuZGlmCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vZ3ppcF9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbV9pbXBsLmg+CisKK3VzaW5nIGdvb2dsZTo6cHJvdG9idWY6OmlvOjpGaWxlT3V0cHV0U3RyZWFtOwordXNpbmcgZ29vZ2xlOjpwcm90b2J1Zjo6aW86Okd6aXBPdXRwdXRTdHJlYW07CisKK2ludCBtYWluKGludCBhcmdjLCBjb25zdCBjaGFyKiogYXJndikgeworICBGaWxlT3V0cHV0U3RyZWFtIGZvdXQoU1RET1VUX0ZJTEVOTyk7CisgIEd6aXBPdXRwdXRTdHJlYW0gb3V0KCZmb3V0KTsKKyAgaW50IHJlYWRsZW47CisKKyAgd2hpbGUgKHRydWUpIHsKKyAgICB2b2lkKiBvdXRwdHI7CisgICAgaW50IG91dGxlbjsKKyAgICBib29sIG9rOworICAgIGRvIHsKKyAgICAgIG9rID0gb3V0Lk5leHQoJm91dHB0ciwgJm91dGxlbik7CisgICAgICBpZiAoIW9rKSB7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0gd2hpbGUgKG91dGxlbiA8PSAwKTsKKyAgICByZWFkbGVuID0gcmVhZChTVERJTl9GSUxFTk8sIG91dHB0ciwgb3V0bGVuKTsKKyAgICBpZiAocmVhZGxlbiA8PSAwKSB7CisgICAgICBvdXQuQmFja1VwKG91dGxlbik7CisgICAgICBicmVhazsKKyAgICB9CisgICAgaWYgKHJlYWRsZW4gPCBvdXRsZW4pIHsKKyAgICAgIG91dC5CYWNrVXAob3V0bGVuIC0gcmVhZGxlbik7CisgICAgfQorICB9CisKKyAgcmV0dXJuIDA7Cit9CmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3RleHRfZm9ybWF0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXh0X2Zvcm1hdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iMGE1Y2U2Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXh0X2Zvcm1hdC5jYwpAQCAtMCwwICsxLDE5NzIgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGpzY2hvcnJAZ29vZ2xlLmNvbSAoSm9zZXBoIFNjaG9ycikKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8YWxnb3JpdGhtPgorI2luY2x1ZGUgPGZsb2F0Lmg+CisjaW5jbHVkZSA8bWF0aC5oPgorI2luY2x1ZGUgPHN0ZGlvLmg+CisjaW5jbHVkZSA8c3RhY2s+CisjaW5jbHVkZSA8bGltaXRzPgorI2luY2x1ZGUgPHZlY3Rvcj4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXh0X2Zvcm1hdC5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZHluYW1pY19tZXNzYWdlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3JlcGVhdGVkX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0X2xpdGUuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vc3RydG9kLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bmtub3duX2ZpZWxkX3NldC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3Rva2VuaXplci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9hbnkuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RyaW5ncHJpbnRmLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbWFwX3V0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RsX3V0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCituYW1lc3BhY2UgeworCitpbmxpbmUgYm9vbCBJc0hleE51bWJlcihjb25zdCBzdHJpbmcmIHN0cikgeworICByZXR1cm4gKHN0ci5sZW5ndGgoKSA+PSAyICYmIHN0clswXSA9PSAnMCcgJiYKKyAgICAgICAgICAoc3RyWzFdID09ICd4JyB8fCBzdHJbMV0gPT0gJ1gnKSk7Cit9CisKK2lubGluZSBib29sIElzT2N0TnVtYmVyKGNvbnN0IHN0cmluZyYgc3RyKSB7CisgIHJldHVybiAoc3RyLmxlbmd0aCgpID49IDIgJiYgc3RyWzBdID09ICcwJyAmJgorICAgICAgICAgIChzdHJbMV0gPj0gJzAnICYmIHN0clsxXSA8ICc4JykpOworfQorCitpbmxpbmUgYm9vbCBHZXRBbnlGaWVsZERlc2NyaXB0b3JzKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvcioqIHR5cGVfdXJsX2ZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqKiB2YWx1ZV9maWVsZCkgeworICAgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBtZXNzYWdlLkdldERlc2NyaXB0b3IoKTsKKyAgICAqdHlwZV91cmxfZmllbGQgPSBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU51bWJlcigxKTsKKyAgICAqdmFsdWVfZmllbGQgPSBkZXNjcmlwdG9yLT5GaW5kRmllbGRCeU51bWJlcigyKTsKKyAgICByZXR1cm4gKCp0eXBlX3VybF9maWVsZCAhPSBOVUxMICYmCisgICAgICAgICAgICAoKnR5cGVfdXJsX2ZpZWxkKS0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TVFJJTkcgJiYKKyAgICAgICAgICAgICp2YWx1ZV9maWVsZCAhPSBOVUxMICYmCisgICAgICAgICAgICAoKnZhbHVlX2ZpZWxkKS0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9CWVRFUyk7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCitzdHJpbmcgTWVzc2FnZTo6RGVidWdTdHJpbmcoKSBjb25zdCB7CisgIHN0cmluZyBkZWJ1Z19zdHJpbmc7CisKKyAgVGV4dEZvcm1hdDo6UHJpbnRUb1N0cmluZygqdGhpcywgJmRlYnVnX3N0cmluZyk7CisKKyAgcmV0dXJuIGRlYnVnX3N0cmluZzsKK30KKworc3RyaW5nIE1lc3NhZ2U6OlNob3J0RGVidWdTdHJpbmcoKSBjb25zdCB7CisgIHN0cmluZyBkZWJ1Z19zdHJpbmc7CisKKyAgVGV4dEZvcm1hdDo6UHJpbnRlciBwcmludGVyOworICBwcmludGVyLlNldFNpbmdsZUxpbmVNb2RlKHRydWUpOworCisgIHByaW50ZXIuUHJpbnRUb1N0cmluZygqdGhpcywgJmRlYnVnX3N0cmluZyk7CisgIC8vIFNpbmdsZSBsaW5lIG1vZGUgY3VycmVudGx5IG1pZ2h0IGhhdmUgYW4gZXh0cmEgc3BhY2UgYXQgdGhlIGVuZC4KKyAgaWYgKGRlYnVnX3N0cmluZy5zaXplKCkgPiAwICYmCisgICAgICBkZWJ1Z19zdHJpbmdbZGVidWdfc3RyaW5nLnNpemUoKSAtIDFdID09ICcgJykgeworICAgIGRlYnVnX3N0cmluZy5yZXNpemUoZGVidWdfc3RyaW5nLnNpemUoKSAtIDEpOworICB9CisKKyAgcmV0dXJuIGRlYnVnX3N0cmluZzsKK30KKworc3RyaW5nIE1lc3NhZ2U6OlV0ZjhEZWJ1Z1N0cmluZygpIGNvbnN0IHsKKyAgc3RyaW5nIGRlYnVnX3N0cmluZzsKKworICBUZXh0Rm9ybWF0OjpQcmludGVyIHByaW50ZXI7CisgIHByaW50ZXIuU2V0VXNlVXRmOFN0cmluZ0VzY2FwaW5nKHRydWUpOworCisgIHByaW50ZXIuUHJpbnRUb1N0cmluZygqdGhpcywgJmRlYnVnX3N0cmluZyk7CisKKyAgcmV0dXJuIGRlYnVnX3N0cmluZzsKK30KKwordm9pZCBNZXNzYWdlOjpQcmludERlYnVnU3RyaW5nKCkgY29uc3QgeworICBwcmludGYoIiVzIiwgRGVidWdTdHJpbmcoKS5jX3N0cigpKTsKK30KKworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKy8vIEltcGxlbWVudGF0aW9uIG9mIHRoZSBwYXJzZSBpbmZvcm1hdGlvbiB0cmVlIGNsYXNzLgorVGV4dEZvcm1hdDo6UGFyc2VJbmZvVHJlZTo6UGFyc2VJbmZvVHJlZSgpIHsgfQorCitUZXh0Rm9ybWF0OjpQYXJzZUluZm9UcmVlOjp+UGFyc2VJbmZvVHJlZSgpIHsKKyAgLy8gUmVtb3ZlIGFueSBuZXN0ZWQgaW5mb3JtYXRpb24gdHJlZXMsIGFzIHRoZXkgYXJlIG93bmVkIGJ5IHRoaXMgdHJlZS4KKyAgZm9yIChOZXN0ZWRNYXA6Oml0ZXJhdG9yIGl0ID0gbmVzdGVkXy5iZWdpbigpOyBpdCAhPSBuZXN0ZWRfLmVuZCgpOyArK2l0KSB7CisgICAgU1RMRGVsZXRlRWxlbWVudHMoJihpdC0+c2Vjb25kKSk7CisgIH0KK30KKwordm9pZCBUZXh0Rm9ybWF0OjpQYXJzZUluZm9UcmVlOjpSZWNvcmRMb2NhdGlvbigKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgIFRleHRGb3JtYXQ6OlBhcnNlTG9jYXRpb24gbG9jYXRpb24pIHsKKyAgbG9jYXRpb25zX1tmaWVsZF0ucHVzaF9iYWNrKGxvY2F0aW9uKTsKK30KKworVGV4dEZvcm1hdDo6UGFyc2VJbmZvVHJlZSogVGV4dEZvcm1hdDo6UGFyc2VJbmZvVHJlZTo6Q3JlYXRlTmVzdGVkKAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgLy8gT3duZWQgYnkgdXMgaW4gdGhlIG1hcC4KKyAgVGV4dEZvcm1hdDo6UGFyc2VJbmZvVHJlZSogaW5zdGFuY2UgPSBuZXcgVGV4dEZvcm1hdDo6UGFyc2VJbmZvVHJlZSgpOworICB2ZWN0b3I8VGV4dEZvcm1hdDo6UGFyc2VJbmZvVHJlZSo+KiB0cmVlcyA9ICZuZXN0ZWRfW2ZpZWxkXTsKKyAgR09PR0xFX0NIRUNLKHRyZWVzKTsKKyAgdHJlZXMtPnB1c2hfYmFjayhpbnN0YW5jZSk7CisgIHJldHVybiBpbnN0YW5jZTsKK30KKwordm9pZCBDaGVja0ZpZWxkSW5kZXgoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50IGluZGV4KSB7CisgIGlmIChmaWVsZCA9PSBOVUxMKSB7IHJldHVybjsgfQorCisgIGlmIChmaWVsZC0+aXNfcmVwZWF0ZWQoKSAmJiBpbmRleCA9PSAtMSkgeworICAgIEdPT0dMRV9MT0coREZBVEFMKSA8PCAiSW5kZXggbXVzdCBiZSBpbiByYW5nZSBvZiByZXBlYXRlZCBmaWVsZCB2YWx1ZXMuICIKKyAgICAgICAgICAgICAgICA8PCAiRmllbGQ6ICIgPDwgZmllbGQtPm5hbWUoKTsKKyAgfSBlbHNlIGlmICghZmllbGQtPmlzX3JlcGVhdGVkKCkgJiYgaW5kZXggIT0gLTEpIHsKKyAgICBHT09HTEVfTE9HKERGQVRBTCkgPDwgIkluZGV4IG11c3QgYmUgLTEgZm9yIHNpbmd1bGFyIGZpZWxkcy4iCisgICAgICAgICAgICAgICAgPDwgIkZpZWxkOiAiIDw8IGZpZWxkLT5uYW1lKCk7CisgIH0KK30KKworVGV4dEZvcm1hdDo6UGFyc2VMb2NhdGlvbiBUZXh0Rm9ybWF0OjpQYXJzZUluZm9UcmVlOjpHZXRMb2NhdGlvbigKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBpbnQgaW5kZXgpIGNvbnN0IHsKKyAgQ2hlY2tGaWVsZEluZGV4KGZpZWxkLCBpbmRleCk7CisgIGlmIChpbmRleCA9PSAtMSkgeyBpbmRleCA9IDA7IH0KKworICBjb25zdCB2ZWN0b3I8VGV4dEZvcm1hdDo6UGFyc2VMb2NhdGlvbj4qIGxvY2F0aW9ucyA9CisgICAgICBGaW5kT3JOdWxsKGxvY2F0aW9uc18sIGZpZWxkKTsKKyAgaWYgKGxvY2F0aW9ucyA9PSBOVUxMIHx8IGluZGV4ID49IGxvY2F0aW9ucy0+c2l6ZSgpKSB7CisgICAgcmV0dXJuIFRleHRGb3JtYXQ6OlBhcnNlTG9jYXRpb24oKTsKKyAgfQorCisgIHJldHVybiAoKmxvY2F0aW9ucylbaW5kZXhdOworfQorCitUZXh0Rm9ybWF0OjpQYXJzZUluZm9UcmVlKiBUZXh0Rm9ybWF0OjpQYXJzZUluZm9UcmVlOjpHZXRUcmVlRm9yTmVzdGVkKAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGludCBpbmRleCkgY29uc3QgeworICBDaGVja0ZpZWxkSW5kZXgoZmllbGQsIGluZGV4KTsKKyAgaWYgKGluZGV4ID09IC0xKSB7IGluZGV4ID0gMDsgfQorCisgIGNvbnN0IHZlY3RvcjxUZXh0Rm9ybWF0OjpQYXJzZUluZm9UcmVlKj4qIHRyZWVzID0gRmluZE9yTnVsbChuZXN0ZWRfLCBmaWVsZCk7CisgIGlmICh0cmVlcyA9PSBOVUxMIHx8IGluZGV4ID49IHRyZWVzLT5zaXplKCkpIHsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorCisgIHJldHVybiAoKnRyZWVzKVtpbmRleF07Cit9CisKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisvLyBJbnRlcm5hbCBjbGFzcyBmb3IgcGFyc2luZyBhbiBBU0NJSSByZXByZXNlbnRhdGlvbiBvZiBhIFByb3RvY29sIE1lc3NhZ2UuCisvLyBUaGlzIGNsYXNzIG1ha2VzIHVzZSBvZiB0aGUgUHJvdG9jb2wgTWVzc2FnZSBjb21waWxlcidzIHRva2VuaXplciBmb3VuZAorLy8gaW4gLy9nb29nbGUvcHJvdG9idWYvaW8vdG9rZW5pemVyLmguIE5vdGUgdGhhdCBjbGFzcydzIFBhcnNlCisvLyBtZXRob2QgaXMgKm5vdCogdGhyZWFkLXNhZmUgYW5kIHNob3VsZCBvbmx5IGJlIHVzZWQgaW4gYSBzaW5nbGUgdGhyZWFkIGF0CisvLyBhIHRpbWUuCisKKy8vIE1ha2VzIGNvZGUgc2xpZ2h0bHkgbW9yZSByZWFkYWJsZS4gIFRoZSBtZWFuaW5nIG9mICJETyhmb28pIiBpcworLy8gIkV4ZWN1dGUgZm9vIGFuZCBmYWlsIGlmIGl0IGZhaWxzLiIsIHdoZXJlIGZhaWx1cmUgaXMgaW5kaWNhdGVkIGJ5CisvLyByZXR1cm5pbmcgZmFsc2UuIEJvcnJvd2VkIGZyb20gcGFyc2VyLmNjIChUaGFua3MgS2VudG9uISkuCisjZGVmaW5lIERPKFNUQVRFTUVOVCkgaWYgKFNUQVRFTUVOVCkge30gZWxzZSByZXR1cm4gZmFsc2UKKworY2xhc3MgVGV4dEZvcm1hdDo6UGFyc2VyOjpQYXJzZXJJbXBsIHsKKyBwdWJsaWM6CisKKyAgLy8gRGV0ZXJtaW5lcyBpZiByZXBlYXRlZCB2YWx1ZXMgZm9yIG5vbi1yZXBlYXRlZCBmaWVsZHMgYW5kCisgIC8vIG9uZW9mcyBhcmUgcGVybWl0dGVkLCBlLmcuLCB0aGUgc3RyaW5nICJmb286IDEgZm9vOiAyIiBmb3IgYQorICAvLyByZXF1aXJlZC9vcHRpb25hbCBmaWVsZCBuYW1lZCAiZm9vIiwgb3IgImJhejogMSBxdXg6IDIiCisgIC8vIHdoZXJlICJiYXoiIGFuZCAicXV4IiBhcmUgbWVtYmVycyBvZiB0aGUgc2FtZSBvbmVvZi4KKyAgZW51bSBTaW5ndWxhck92ZXJ3cml0ZVBvbGljeSB7CisgICAgQUxMT1dfU0lOR1VMQVJfT1ZFUldSSVRFUyA9IDAsICAgLy8gdGhlIGxhc3QgdmFsdWUgaXMgcmV0YWluZWQKKyAgICBGT1JCSURfU0lOR1VMQVJfT1ZFUldSSVRFUyA9IDEsICAvLyBhbiBlcnJvciBpcyBpc3N1ZWQKKyAgfTsKKworICBQYXJzZXJJbXBsKGNvbnN0IERlc2NyaXB0b3IqIHJvb3RfbWVzc2FnZV90eXBlLAorICAgICAgICAgICAgIGlvOjpaZXJvQ29weUlucHV0U3RyZWFtKiBpbnB1dF9zdHJlYW0sCisgICAgICAgICAgICAgaW86OkVycm9yQ29sbGVjdG9yKiBlcnJvcl9jb2xsZWN0b3IsCisgICAgICAgICAgICAgVGV4dEZvcm1hdDo6RmluZGVyKiBmaW5kZXIsCisgICAgICAgICAgICAgUGFyc2VJbmZvVHJlZSogcGFyc2VfaW5mb190cmVlLAorICAgICAgICAgICAgIFNpbmd1bGFyT3ZlcndyaXRlUG9saWN5IHNpbmd1bGFyX292ZXJ3cml0ZV9wb2xpY3ksCisgICAgICAgICAgICAgYm9vbCBhbGxvd19jYXNlX2luc2Vuc2l0aXZlX2ZpZWxkLAorICAgICAgICAgICAgIGJvb2wgYWxsb3dfdW5rbm93bl9maWVsZCwKKyAgICAgICAgICAgICBib29sIGFsbG93X3Vua25vd25fZW51bSwKKyAgICAgICAgICAgICBib29sIGFsbG93X2ZpZWxkX251bWJlciwKKyAgICAgICAgICAgICBib29sIGFsbG93X3JlbGF4ZWRfd2hpdGVzcGFjZSkKKyAgICA6IGVycm9yX2NvbGxlY3Rvcl8oZXJyb3JfY29sbGVjdG9yKSwKKyAgICAgIGZpbmRlcl8oZmluZGVyKSwKKyAgICAgIHBhcnNlX2luZm9fdHJlZV8ocGFyc2VfaW5mb190cmVlKSwKKyAgICAgIHRva2VuaXplcl9lcnJvcl9jb2xsZWN0b3JfKHRoaXMpLAorICAgICAgdG9rZW5pemVyXyhpbnB1dF9zdHJlYW0sICZ0b2tlbml6ZXJfZXJyb3JfY29sbGVjdG9yXyksCisgICAgICByb290X21lc3NhZ2VfdHlwZV8ocm9vdF9tZXNzYWdlX3R5cGUpLAorICAgICAgc2luZ3VsYXJfb3ZlcndyaXRlX3BvbGljeV8oc2luZ3VsYXJfb3ZlcndyaXRlX3BvbGljeSksCisgICAgICBhbGxvd19jYXNlX2luc2Vuc2l0aXZlX2ZpZWxkXyhhbGxvd19jYXNlX2luc2Vuc2l0aXZlX2ZpZWxkKSwKKyAgICAgIGFsbG93X3Vua25vd25fZmllbGRfKGFsbG93X3Vua25vd25fZmllbGQpLAorICAgICAgYWxsb3dfdW5rbm93bl9lbnVtXyhhbGxvd191bmtub3duX2VudW0pLAorICAgICAgYWxsb3dfZmllbGRfbnVtYmVyXyhhbGxvd19maWVsZF9udW1iZXIpLAorICAgICAgaGFkX2Vycm9yc18oZmFsc2UpIHsKKyAgICAvLyBGb3IgYmFja3dhcmRzLWNvbXBhdGliaWxpdHkgd2l0aCBwcm90bzEsIHdlIG5lZWQgdG8gYWxsb3cgdGhlICdmJyBzdWZmaXgKKyAgICAvLyBmb3IgZmxvYXRzLgorICAgIHRva2VuaXplcl8uc2V0X2FsbG93X2ZfYWZ0ZXJfZmxvYXQodHJ1ZSk7CisKKyAgICAvLyAnIycgc3RhcnRzIGEgY29tbWVudC4KKyAgICB0b2tlbml6ZXJfLnNldF9jb21tZW50X3N0eWxlKGlvOjpUb2tlbml6ZXI6OlNIX0NPTU1FTlRfU1RZTEUpOworCisgICAgaWYgKGFsbG93X3JlbGF4ZWRfd2hpdGVzcGFjZSkgeworICAgICAgdG9rZW5pemVyXy5zZXRfcmVxdWlyZV9zcGFjZV9hZnRlcl9udW1iZXIoZmFsc2UpOworICAgICAgdG9rZW5pemVyXy5zZXRfYWxsb3dfbXVsdGlsaW5lX3N0cmluZ3ModHJ1ZSk7CisgICAgfQorCisgICAgLy8gQ29uc3VtZSB0aGUgc3RhcnRpbmcgdG9rZW4uCisgICAgdG9rZW5pemVyXy5OZXh0KCk7CisgIH0KKyAgflBhcnNlckltcGwoKSB7IH0KKworICAvLyBQYXJzZXMgdGhlIEFTQ0lJIHJlcHJlc2VudGF0aW9uIHNwZWNpZmllZCBpbiBpbnB1dCBhbmQgc2F2ZXMgdGhlCisgIC8vIGluZm9ybWF0aW9uIGludG8gdGhlIG91dHB1dCBwb2ludGVyIChhIE1lc3NhZ2UpLiBSZXR1cm5zCisgIC8vIGZhbHNlIGlmIGFuIGVycm9yIG9jY3VycyAoYW4gZXJyb3Igd2lsbCBhbHNvIGJlIGxvZ2dlZCB0bworICAvLyBHT09HTEVfTE9HKEVSUk9SKSkuCisgIGJvb2wgUGFyc2UoTWVzc2FnZSogb3V0cHV0KSB7CisgICAgLy8gQ29uc3VtZSBmaWVsZHMgdW50aWwgd2UgY2Fubm90IGRvIHNvIGFueW1vcmUuCisgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgIGlmIChMb29raW5nQXRUeXBlKGlvOjpUb2tlbml6ZXI6OlRZUEVfRU5EKSkgeworICAgICAgICByZXR1cm4gIWhhZF9lcnJvcnNfOworICAgICAgfQorCisgICAgICBETyhDb25zdW1lRmllbGQob3V0cHV0KSk7CisgICAgfQorICB9CisKKyAgYm9vbCBQYXJzZUZpZWxkKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIE1lc3NhZ2UqIG91dHB1dCkgeworICAgIGJvb2wgc3VjOworICAgIGlmIChmaWVsZC0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSkgeworICAgICAgc3VjID0gQ29uc3VtZUZpZWxkTWVzc2FnZShvdXRwdXQsIG91dHB1dC0+R2V0UmVmbGVjdGlvbigpLCBmaWVsZCk7CisgICAgfSBlbHNlIHsKKyAgICAgIHN1YyA9IENvbnN1bWVGaWVsZFZhbHVlKG91dHB1dCwgb3V0cHV0LT5HZXRSZWZsZWN0aW9uKCksIGZpZWxkKTsKKyAgICB9CisgICAgcmV0dXJuIHN1YyAmJiBMb29raW5nQXRUeXBlKGlvOjpUb2tlbml6ZXI6OlRZUEVfRU5EKTsKKyAgfQorCisgIHZvaWQgUmVwb3J0RXJyb3IoaW50IGxpbmUsIGludCBjb2wsIGNvbnN0IHN0cmluZyYgbWVzc2FnZSkgeworICAgIGhhZF9lcnJvcnNfID0gdHJ1ZTsKKyAgICBpZiAoZXJyb3JfY29sbGVjdG9yXyA9PSBOVUxMKSB7CisgICAgICBpZiAobGluZSA+PSAwKSB7CisgICAgICAgIEdPT0dMRV9MT0coRVJST1IpIDw8ICJFcnJvciBwYXJzaW5nIHRleHQtZm9ybWF0ICIKKyAgICAgICAgICAgICAgICAgICA8PCByb290X21lc3NhZ2VfdHlwZV8tPmZ1bGxfbmFtZSgpCisgICAgICAgICAgICAgICAgICAgPDwgIjogIiA8PCAobGluZSArIDEpIDw8ICI6IgorICAgICAgICAgICAgICAgICAgIDw8IChjb2wgKyAxKSA8PCAiOiAiIDw8IG1lc3NhZ2U7CisgICAgICB9IGVsc2UgeworICAgICAgICBHT09HTEVfTE9HKEVSUk9SKSA8PCAiRXJyb3IgcGFyc2luZyB0ZXh0LWZvcm1hdCAiCisgICAgICAgICAgICAgICAgICAgPDwgcm9vdF9tZXNzYWdlX3R5cGVfLT5mdWxsX25hbWUoKQorICAgICAgICAgICAgICAgICAgIDw8ICI6ICIgPDwgbWVzc2FnZTsKKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgZXJyb3JfY29sbGVjdG9yXy0+QWRkRXJyb3IobGluZSwgY29sLCBtZXNzYWdlKTsKKyAgICB9CisgIH0KKworICB2b2lkIFJlcG9ydFdhcm5pbmcoaW50IGxpbmUsIGludCBjb2wsIGNvbnN0IHN0cmluZyYgbWVzc2FnZSkgeworICAgIGlmIChlcnJvcl9jb2xsZWN0b3JfID09IE5VTEwpIHsKKyAgICAgIGlmIChsaW5lID49IDApIHsKKyAgICAgICAgR09PR0xFX0xPRyhXQVJOSU5HKSA8PCAiV2FybmluZyBwYXJzaW5nIHRleHQtZm9ybWF0ICIKKyAgICAgICAgICAgICAgICAgICAgIDw8IHJvb3RfbWVzc2FnZV90eXBlXy0+ZnVsbF9uYW1lKCkKKyAgICAgICAgICAgICAgICAgICAgIDw8ICI6ICIgPDwgKGxpbmUgKyAxKSA8PCAiOiIKKyAgICAgICAgICAgICAgICAgICAgIDw8IChjb2wgKyAxKSA8PCAiOiAiIDw8IG1lc3NhZ2U7CisgICAgICB9IGVsc2UgeworICAgICAgICBHT09HTEVfTE9HKFdBUk5JTkcpIDw8ICJXYXJuaW5nIHBhcnNpbmcgdGV4dC1mb3JtYXQgIgorICAgICAgICAgICAgICAgICAgICAgPDwgcm9vdF9tZXNzYWdlX3R5cGVfLT5mdWxsX25hbWUoKQorICAgICAgICAgICAgICAgICAgICAgPDwgIjogIiA8PCBtZXNzYWdlOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICBlcnJvcl9jb2xsZWN0b3JfLT5BZGRXYXJuaW5nKGxpbmUsIGNvbCwgbWVzc2FnZSk7CisgICAgfQorICB9CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoUGFyc2VySW1wbCk7CisKKyAgLy8gUmVwb3J0cyBhbiBlcnJvciB3aXRoIHRoZSBnaXZlbiBtZXNzYWdlIHdpdGggaW5mb3JtYXRpb24gaW5kaWNhdGluZworICAvLyB0aGUgcG9zaXRpb24gKGFzIGRlcml2ZWQgZnJvbSB0aGUgY3VycmVudCB0b2tlbikuCisgIHZvaWQgUmVwb3J0RXJyb3IoY29uc3Qgc3RyaW5nJiBtZXNzYWdlKSB7CisgICAgUmVwb3J0RXJyb3IodG9rZW5pemVyXy5jdXJyZW50KCkubGluZSwgdG9rZW5pemVyXy5jdXJyZW50KCkuY29sdW1uLAorICAgICAgICAgICAgICAgIG1lc3NhZ2UpOworICB9CisKKyAgLy8gUmVwb3J0cyBhIHdhcm5pbmcgd2l0aCB0aGUgZ2l2ZW4gbWVzc2FnZSB3aXRoIGluZm9ybWF0aW9uIGluZGljYXRpbmcKKyAgLy8gdGhlIHBvc2l0aW9uIChhcyBkZXJpdmVkIGZyb20gdGhlIGN1cnJlbnQgdG9rZW4pLgorICB2b2lkIFJlcG9ydFdhcm5pbmcoY29uc3Qgc3RyaW5nJiBtZXNzYWdlKSB7CisgICAgUmVwb3J0V2FybmluZyh0b2tlbml6ZXJfLmN1cnJlbnQoKS5saW5lLCB0b2tlbml6ZXJfLmN1cnJlbnQoKS5jb2x1bW4sCisgICAgICAgICAgICAgICAgICBtZXNzYWdlKTsKKyAgfQorCisgIC8vIENvbnN1bWVzIHRoZSBzcGVjaWZpZWQgbWVzc2FnZSB3aXRoIHRoZSBnaXZlbiBzdGFydGluZyBkZWxpbWl0ZXIuCisgIC8vIFRoaXMgbWV0aG9kIGNoZWNrcyB0byBzZWUgdGhhdCB0aGUgZW5kIGRlbGltaXRlciBhdCB0aGUgY29uY2x1c2lvbiBvZgorICAvLyB0aGUgY29uc3VtcHRpb24gbWF0Y2hlcyB0aGUgc3RhcnRpbmcgZGVsaW1pdGVyIHBhc3NlZCBpbiBoZXJlLgorICBib29sIENvbnN1bWVNZXNzYWdlKE1lc3NhZ2UqIG1lc3NhZ2UsIGNvbnN0IHN0cmluZyBkZWxpbWl0ZXIpIHsKKyAgICB3aGlsZSAoIUxvb2tpbmdBdCgiPiIpICYmICAhTG9va2luZ0F0KCJ9IikpIHsKKyAgICAgIERPKENvbnN1bWVGaWVsZChtZXNzYWdlKSk7CisgICAgfQorCisgICAgLy8gQ29uZmlybSB0aGF0IHdlIGhhdmUgYSB2YWxpZCBlbmRpbmcgZGVsaW1pdGVyLgorICAgIERPKENvbnN1bWUoZGVsaW1pdGVyKSk7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICAvLyBDb25zdW1lIGVpdGhlciAiPCIgb3IgInsiLgorICBib29sIENvbnN1bWVNZXNzYWdlRGVsaW1pdGVyKHN0cmluZyogZGVsaW1pdGVyKSB7CisgICAgaWYgKFRyeUNvbnN1bWUoIjwiKSkgeworICAgICAgKmRlbGltaXRlciA9ICI+IjsKKyAgICB9IGVsc2UgeworICAgICAgRE8oQ29uc3VtZSgieyIpKTsKKyAgICAgICpkZWxpbWl0ZXIgPSAifSI7CisgICAgfQorICAgIHJldHVybiB0cnVlOworICB9CisKKworICAvLyBDb25zdW1lcyB0aGUgY3VycmVudCBmaWVsZCAoYXMgcmV0dXJuZWQgYnkgdGhlIHRva2VuaXplcikgb24gdGhlCisgIC8vIHBhc3NlZCBpbiBtZXNzYWdlLgorICBib29sIENvbnN1bWVGaWVsZChNZXNzYWdlKiBtZXNzYWdlKSB7CisgICAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKTsKKyAgICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yID0gbWVzc2FnZS0+R2V0RGVzY3JpcHRvcigpOworCisgICAgc3RyaW5nIGZpZWxkX25hbWU7CisKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gTlVMTDsKKyAgICBpbnQgc3RhcnRfbGluZSA9IHRva2VuaXplcl8uY3VycmVudCgpLmxpbmU7CisgICAgaW50IHN0YXJ0X2NvbHVtbiA9IHRva2VuaXplcl8uY3VycmVudCgpLmNvbHVtbjsKKworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogYW55X3R5cGVfdXJsX2ZpZWxkOworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogYW55X3ZhbHVlX2ZpZWxkOworICAgIGlmIChpbnRlcm5hbDo6R2V0QW55RmllbGREZXNjcmlwdG9ycygqbWVzc2FnZSwgJmFueV90eXBlX3VybF9maWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmFueV92YWx1ZV9maWVsZCkgJiYKKyAgICAgICAgVHJ5Q29uc3VtZSgiWyIpKSB7CisgICAgICBzdHJpbmcgZnVsbF90eXBlX25hbWUsIHByZWZpeDsKKyAgICAgIERPKENvbnN1bWVBbnlUeXBlVXJsKCZmdWxsX3R5cGVfbmFtZSwgJnByZWZpeCkpOworICAgICAgRE8oQ29uc3VtZSgiXSIpKTsKKyAgICAgIFRyeUNvbnN1bWUoIjoiKTsgIC8vICc6JyBpcyBvcHRpb25hbCBiZXR3ZWVuIG1lc3NhZ2UgbGFiZWxzIGFuZCB2YWx1ZXMuCisgICAgICBzdHJpbmcgc2VyaWFsaXplZF92YWx1ZTsKKyAgICAgIERPKENvbnN1bWVBbnlWYWx1ZShmdWxsX3R5cGVfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLT5HZXREZXNjcmlwdG9yKCktPmZpbGUoKS0+cG9vbCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICZzZXJpYWxpemVkX3ZhbHVlKSk7CisgICAgICByZWZsZWN0aW9uLT5TZXRTdHJpbmcoCisgICAgICAgICAgbWVzc2FnZSwgYW55X3R5cGVfdXJsX2ZpZWxkLAorICAgICAgICAgIHN0cmluZyhwcmVmaXggKyBmdWxsX3R5cGVfbmFtZSkpOworICAgICAgcmVmbGVjdGlvbi0+U2V0U3RyaW5nKG1lc3NhZ2UsIGFueV92YWx1ZV9maWVsZCwgc2VyaWFsaXplZF92YWx1ZSk7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgICAgaWYgKFRyeUNvbnN1bWUoIlsiKSkgeworICAgICAgLy8gRXh0ZW5zaW9uLgorICAgICAgRE8oQ29uc3VtZUZ1bGxUeXBlTmFtZSgmZmllbGRfbmFtZSkpOworICAgICAgRE8oQ29uc3VtZSgiXSIpKTsKKworICAgICAgZmllbGQgPSAoZmluZGVyXyAhPSBOVUxMCisgICAgICAgICAgICAgICA/IGZpbmRlcl8tPkZpbmRFeHRlbnNpb24obWVzc2FnZSwgZmllbGRfbmFtZSkKKyAgICAgICAgICAgICAgIDogcmVmbGVjdGlvbi0+RmluZEtub3duRXh0ZW5zaW9uQnlOYW1lKGZpZWxkX25hbWUpKTsKKworICAgICAgaWYgKGZpZWxkID09IE5VTEwpIHsKKyAgICAgICAgaWYgKCFhbGxvd191bmtub3duX2ZpZWxkXykgeworICAgICAgICAgIFJlcG9ydEVycm9yKCJFeHRlbnNpb24gXCIiICsgZmllbGRfbmFtZSArICJcIiBpcyBub3QgZGVmaW5lZCBvciAiCisgICAgICAgICAgICAgICAgICAgICAgImlzIG5vdCBhbiBleHRlbnNpb24gb2YgXCIiICsKKyAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdG9yLT5mdWxsX25hbWUoKSArICJcIi4iKTsKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgUmVwb3J0V2FybmluZygiRXh0ZW5zaW9uIFwiIiArIGZpZWxkX25hbWUgKyAiXCIgaXMgbm90IGRlZmluZWQgb3IgIgorICAgICAgICAgICAgICAgICAgICAgICAgImlzIG5vdCBhbiBleHRlbnNpb24gb2YgXCIiICsKKyAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0b3ItPmZ1bGxfbmFtZSgpICsgIlwiLiIpOworICAgICAgICB9CisgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgIERPKENvbnN1bWVJZGVudGlmaWVyKCZmaWVsZF9uYW1lKSk7CisKKyAgICAgIGludDMyIGZpZWxkX251bWJlcjsKKyAgICAgIGlmIChhbGxvd19maWVsZF9udW1iZXJfICYmIHNhZmVfc3RydG8zMihmaWVsZF9uYW1lLCAmZmllbGRfbnVtYmVyKSkgeworICAgICAgICBpZiAoZGVzY3JpcHRvci0+SXNFeHRlbnNpb25OdW1iZXIoZmllbGRfbnVtYmVyKSkgeworICAgICAgICAgIGZpZWxkID0gcmVmbGVjdGlvbi0+RmluZEtub3duRXh0ZW5zaW9uQnlOdW1iZXIoZmllbGRfbnVtYmVyKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBmaWVsZCA9IGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TnVtYmVyKGZpZWxkX251bWJlcik7CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGZpZWxkID0gZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKGZpZWxkX25hbWUpOworICAgICAgICAvLyBHcm91cCBuYW1lcyBhcmUgZXhwZWN0ZWQgdG8gYmUgY2FwaXRhbGl6ZWQgYXMgdGhleSBhcHBlYXIgaW4gdGhlCisgICAgICAgIC8vIC5wcm90byBmaWxlLCB3aGljaCBhY3R1YWxseSBtYXRjaGVzIHRoZWlyIHR5cGUgbmFtZXMsIG5vdCB0aGVpcgorICAgICAgICAvLyBmaWVsZCBuYW1lcy4KKyAgICAgICAgaWYgKGZpZWxkID09IE5VTEwpIHsKKyAgICAgICAgICBzdHJpbmcgbG93ZXJfZmllbGRfbmFtZSA9IGZpZWxkX25hbWU7CisgICAgICAgICAgTG93ZXJTdHJpbmcoJmxvd2VyX2ZpZWxkX25hbWUpOworICAgICAgICAgIGZpZWxkID0gZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKGxvd2VyX2ZpZWxkX25hbWUpOworICAgICAgICAgIC8vIElmIHRoZSBjYXNlLWluc2Vuc2l0aXZlIG1hdGNoIHdvcmtlZCBidXQgdGhlIGZpZWxkIGlzIE5PVCBhIGdyb3VwLAorICAgICAgICAgIGlmIChmaWVsZCAhPSBOVUxMICYmIGZpZWxkLT50eXBlKCkgIT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQKSB7CisgICAgICAgICAgICBmaWVsZCA9IE5VTEw7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIC8vIEFnYWluLCBzcGVjaWFsLWNhc2UgZ3JvdXAgbmFtZXMgYXMgZGVzY3JpYmVkIGFib3ZlLgorICAgICAgICBpZiAoZmllbGQgIT0gTlVMTCAmJiBmaWVsZC0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9HUk9VUAorICAgICAgICAgICAgJiYgZmllbGQtPm1lc3NhZ2VfdHlwZSgpLT5uYW1lKCkgIT0gZmllbGRfbmFtZSkgeworICAgICAgICAgIGZpZWxkID0gTlVMTDsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChmaWVsZCA9PSBOVUxMICYmIGFsbG93X2Nhc2VfaW5zZW5zaXRpdmVfZmllbGRfKSB7CisgICAgICAgICAgc3RyaW5nIGxvd2VyX2ZpZWxkX25hbWUgPSBmaWVsZF9uYW1lOworICAgICAgICAgIExvd2VyU3RyaW5nKCZsb3dlcl9maWVsZF9uYW1lKTsKKyAgICAgICAgICBmaWVsZCA9IGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TG93ZXJjYXNlTmFtZShsb3dlcl9maWVsZF9uYW1lKTsKKyAgICAgICAgfQorICAgICAgfQorCisgICAgICBpZiAoZmllbGQgPT0gTlVMTCkgeworICAgICAgICBpZiAoIWFsbG93X3Vua25vd25fZmllbGRfKSB7CisgICAgICAgICAgUmVwb3J0RXJyb3IoIk1lc3NhZ2UgdHlwZSBcIiIgKyBkZXNjcmlwdG9yLT5mdWxsX25hbWUoKSArCisgICAgICAgICAgICAgICAgICAgICAgIlwiIGhhcyBubyBmaWVsZCBuYW1lZCBcIiIgKyBmaWVsZF9uYW1lICsgIlwiLiIpOworICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBSZXBvcnRXYXJuaW5nKCJNZXNzYWdlIHR5cGUgXCIiICsgZGVzY3JpcHRvci0+ZnVsbF9uYW1lKCkgKworICAgICAgICAgICAgICAgICAgICAgICAgIlwiIGhhcyBubyBmaWVsZCBuYW1lZCBcIiIgKyBmaWVsZF9uYW1lICsgIlwiLiIpOworICAgICAgICB9CisgICAgICB9CisgICAgfQorCisgICAgLy8gU2tpcHMgdW5rbm93biBmaWVsZC4KKyAgICBpZiAoZmllbGQgPT0gTlVMTCkgeworICAgICAgR09PR0xFX0NIRUNLKGFsbG93X3Vua25vd25fZmllbGRfKTsKKyAgICAgIC8vIFRyeSB0byBndWVzcyB0aGUgdHlwZSBvZiB0aGlzIGZpZWxkLgorICAgICAgLy8gSWYgdGhpcyBmaWVsZCBpcyBub3QgYSBtZXNzYWdlLCB0aGVyZSBzaG91bGQgYmUgYSAiOiIgYmV0d2VlbiB0aGUKKyAgICAgIC8vIGZpZWxkIG5hbWUgYW5kIHRoZSBmaWVsZCB2YWx1ZSBhbmQgYWxzbyB0aGUgZmllbGQgdmFsdWUgc2hvdWxkIG5vdAorICAgICAgLy8gc3RhcnQgd2l0aCAieyIgb3IgIjwiIHdoaWNoIGluZGljYXRlcyB0aGUgYmVnaW5uaW5nIG9mIGEgbWVzc2FnZSBib2R5LgorICAgICAgLy8gSWYgdGhlcmUgaXMgbm8gIjoiIG9yIHRoZXJlIGlzIGEgInsiIG9yICI8IiBhZnRlciAiOiIsIHRoaXMgZmllbGQgaGFzCisgICAgICAvLyB0byBiZSBhIG1lc3NhZ2Ugb3IgdGhlIGlucHV0IGlzIGlsbC1mb3JtZWQuCisgICAgICBpZiAoVHJ5Q29uc3VtZSgiOiIpICYmICFMb29raW5nQXQoInsiKSAmJiAhTG9va2luZ0F0KCI8IikpIHsKKyAgICAgICAgcmV0dXJuIFNraXBGaWVsZFZhbHVlKCk7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gU2tpcEZpZWxkTWVzc2FnZSgpOworICAgICAgfQorICAgIH0KKworICAgIGlmIChzaW5ndWxhcl9vdmVyd3JpdGVfcG9saWN5XyA9PSBGT1JCSURfU0lOR1VMQVJfT1ZFUldSSVRFUykgeworICAgICAgLy8gRmFpbCBpZiB0aGUgZmllbGQgaXMgbm90IHJlcGVhdGVkIGFuZCBpdCBoYXMgYWxyZWFkeSBiZWVuIHNwZWNpZmllZC4KKyAgICAgIGlmICghZmllbGQtPmlzX3JlcGVhdGVkKCkgJiYgcmVmbGVjdGlvbi0+SGFzRmllbGQoKm1lc3NhZ2UsIGZpZWxkKSkgeworICAgICAgICBSZXBvcnRFcnJvcigiTm9uLXJlcGVhdGVkIGZpZWxkIFwiIiArIGZpZWxkX25hbWUgKworICAgICAgICAgICAgICAgICAgICAiXCIgaXMgc3BlY2lmaWVkIG11bHRpcGxlIHRpbWVzLiIpOworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgICAvLyBGYWlsIGlmIHRoZSBmaWVsZCBpcyBhIG1lbWJlciBvZiBhIG9uZW9mIGFuZCBhbm90aGVyIG1lbWJlciBoYXMgYWxyZWFkeQorICAgICAgLy8gYmVlbiBzcGVjaWZpZWQuCisgICAgICBjb25zdCBPbmVvZkRlc2NyaXB0b3IqIG9uZW9mID0gZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKTsKKyAgICAgIGlmIChvbmVvZiAhPSBOVUxMICYmIHJlZmxlY3Rpb24tPkhhc09uZW9mKCptZXNzYWdlLCBvbmVvZikpIHsKKyAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBvdGhlcl9maWVsZCA9CisgICAgICAgICAgICByZWZsZWN0aW9uLT5HZXRPbmVvZkZpZWxkRGVzY3JpcHRvcigqbWVzc2FnZSwgb25lb2YpOworICAgICAgICBSZXBvcnRFcnJvcigiRmllbGQgXCIiICsgZmllbGRfbmFtZSArICJcIiBpcyBzcGVjaWZpZWQgYWxvbmcgd2l0aCAiCisgICAgICAgICAgICAgICAgICAgICJmaWVsZCBcIiIgKyBvdGhlcl9maWVsZC0+bmFtZSgpICsgIlwiLCBhbm90aGVyIG1lbWJlciAiCisgICAgICAgICAgICAgICAgICAgICJvZiBvbmVvZiBcIiIgKyBvbmVvZi0+bmFtZSgpICsgIlwiLiIpOworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgfQorCisgICAgLy8gUGVyZm9ybSBzcGVjaWFsIGhhbmRsaW5nIGZvciBlbWJlZGRlZCBtZXNzYWdlIHR5cGVzLgorICAgIGlmIChmaWVsZC0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSkgeworICAgICAgLy8gJzonIGlzIG9wdGlvbmFsIGhlcmUuCisgICAgICBUcnlDb25zdW1lKCI6Iik7CisgICAgfSBlbHNlIHsKKyAgICAgIC8vICc6JyBpcyByZXF1aXJlZCBoZXJlLgorICAgICAgRE8oQ29uc3VtZSgiOiIpKTsKKyAgICB9CisKKyAgICBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkgJiYgVHJ5Q29uc3VtZSgiWyIpKSB7CisgICAgICAvLyBTaG9ydCByZXBlYXRlZCBmb3JtYXQsIGUuZy4gICJmb286IFsxLCAyLCAzXSIKKyAgICAgIHdoaWxlICh0cnVlKSB7CisgICAgICAgIGlmIChmaWVsZC0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSkgeworICAgICAgICAgIC8vIFBlcmZvcm0gc3BlY2lhbCBoYW5kbGluZyBmb3IgZW1iZWRkZWQgbWVzc2FnZSB0eXBlcy4KKyAgICAgICAgICBETyhDb25zdW1lRmllbGRNZXNzYWdlKG1lc3NhZ2UsIHJlZmxlY3Rpb24sIGZpZWxkKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgRE8oQ29uc3VtZUZpZWxkVmFsdWUobWVzc2FnZSwgcmVmbGVjdGlvbiwgZmllbGQpKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoVHJ5Q29uc3VtZSgiXSIpKSB7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgRE8oQ29uc3VtZSgiLCIpKTsKKyAgICAgIH0KKyAgICB9IGVsc2UgaWYgKGZpZWxkLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFKSB7CisgICAgICBETyhDb25zdW1lRmllbGRNZXNzYWdlKG1lc3NhZ2UsIHJlZmxlY3Rpb24sIGZpZWxkKSk7CisgICAgfSBlbHNlIHsKKyAgICAgIERPKENvbnN1bWVGaWVsZFZhbHVlKG1lc3NhZ2UsIHJlZmxlY3Rpb24sIGZpZWxkKSk7CisgICAgfQorCisgICAgLy8gRm9yIGhpc3RvcmljYWwgcmVhc29ucywgZmllbGRzIG1heSBvcHRpb25hbGx5IGJlIHNlcGFyYXRlZCBieSBjb21tYXMgb3IKKyAgICAvLyBzZW1pY29sb25zLgorICAgIFRyeUNvbnN1bWUoIjsiKSB8fCBUcnlDb25zdW1lKCIsIik7CisKKyAgICBpZiAoZmllbGQtPm9wdGlvbnMoKS5kZXByZWNhdGVkKCkpIHsKKyAgICAgIFJlcG9ydFdhcm5pbmcoInRleHQgZm9ybWF0IGNvbnRhaW5zIGRlcHJlY2F0ZWQgZmllbGQgXCIiCisgICAgICAgICAgICAgICAgICAgICsgZmllbGRfbmFtZSArICJcIiIpOworICAgIH0KKworICAgIC8vIElmIGEgcGFyc2UgaW5mbyB0cmVlIGV4aXN0cywgYWRkIHRoZSBsb2NhdGlvbiBmb3IgdGhlIHBhcnNlZAorICAgIC8vIGZpZWxkLgorICAgIGlmIChwYXJzZV9pbmZvX3RyZWVfICE9IE5VTEwpIHsKKyAgICAgIFJlY29yZExvY2F0aW9uKHBhcnNlX2luZm9fdHJlZV8sIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgUGFyc2VMb2NhdGlvbihzdGFydF9saW5lLCBzdGFydF9jb2x1bW4pKTsKKyAgICB9CisKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIC8vIFNraXBzIHRoZSBuZXh0IGZpZWxkIGluY2x1ZGluZyB0aGUgZmllbGQncyBuYW1lIGFuZCB2YWx1ZS4KKyAgYm9vbCBTa2lwRmllbGQoKSB7CisgICAgc3RyaW5nIGZpZWxkX25hbWU7CisgICAgaWYgKFRyeUNvbnN1bWUoIlsiKSkgeworICAgICAgLy8gRXh0ZW5zaW9uIG5hbWUuCisgICAgICBETyhDb25zdW1lRnVsbFR5cGVOYW1lKCZmaWVsZF9uYW1lKSk7CisgICAgICBETyhDb25zdW1lKCJdIikpOworICAgIH0gZWxzZSB7CisgICAgICBETyhDb25zdW1lSWRlbnRpZmllcigmZmllbGRfbmFtZSkpOworICAgIH0KKworICAgIC8vIFRyeSB0byBndWVzcyB0aGUgdHlwZSBvZiB0aGlzIGZpZWxkLgorICAgIC8vIElmIHRoaXMgZmllbGQgaXMgbm90IGEgbWVzc2FnZSwgdGhlcmUgc2hvdWxkIGJlIGEgIjoiIGJldHdlZW4gdGhlCisgICAgLy8gZmllbGQgbmFtZSBhbmQgdGhlIGZpZWxkIHZhbHVlIGFuZCBhbHNvIHRoZSBmaWVsZCB2YWx1ZSBzaG91bGQgbm90CisgICAgLy8gc3RhcnQgd2l0aCAieyIgb3IgIjwiIHdoaWNoIGluZGljYXRlcyB0aGUgYmVnaW5uaW5nIG9mIGEgbWVzc2FnZSBib2R5LgorICAgIC8vIElmIHRoZXJlIGlzIG5vICI6IiBvciB0aGVyZSBpcyBhICJ7IiBvciAiPCIgYWZ0ZXIgIjoiLCB0aGlzIGZpZWxkIGhhcworICAgIC8vIHRvIGJlIGEgbWVzc2FnZSBvciB0aGUgaW5wdXQgaXMgaWxsLWZvcm1lZC4KKyAgICBpZiAoVHJ5Q29uc3VtZSgiOiIpICYmICFMb29raW5nQXQoInsiKSAmJiAhTG9va2luZ0F0KCI8IikpIHsKKyAgICAgIERPKFNraXBGaWVsZFZhbHVlKCkpOworICAgIH0gZWxzZSB7CisgICAgICBETyhTa2lwRmllbGRNZXNzYWdlKCkpOworICAgIH0KKyAgICAvLyBGb3IgaGlzdG9yaWNhbCByZWFzb25zLCBmaWVsZHMgbWF5IG9wdGlvbmFsbHkgYmUgc2VwYXJhdGVkIGJ5IGNvbW1hcyBvcgorICAgIC8vIHNlbWljb2xvbnMuCisgICAgVHJ5Q29uc3VtZSgiOyIpIHx8IFRyeUNvbnN1bWUoIiwiKTsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIGJvb2wgQ29uc3VtZUZpZWxkTWVzc2FnZShNZXNzYWdlKiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKworICAgIC8vIElmIHRoZSBwYXJzZSBpbmZvcm1hdGlvbiB0cmVlIGlzIG5vdCBOVUxMLCBjcmVhdGUgYSBuZXN0ZWQgb25lCisgICAgLy8gZm9yIHRoZSBuZXN0ZWQgbWVzc2FnZS4KKyAgICBQYXJzZUluZm9UcmVlKiBwYXJlbnQgPSBwYXJzZV9pbmZvX3RyZWVfOworICAgIGlmIChwYXJlbnQgIT0gTlVMTCkgeworICAgICAgcGFyc2VfaW5mb190cmVlXyA9IENyZWF0ZU5lc3RlZChwYXJlbnQsIGZpZWxkKTsKKyAgICB9CisKKyAgICBzdHJpbmcgZGVsaW1pdGVyOworICAgIERPKENvbnN1bWVNZXNzYWdlRGVsaW1pdGVyKCZkZWxpbWl0ZXIpKTsKKyAgICBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkpIHsKKyAgICAgIERPKENvbnN1bWVNZXNzYWdlKHJlZmxlY3Rpb24tPkFkZE1lc3NhZ2UobWVzc2FnZSwgZmllbGQpLCBkZWxpbWl0ZXIpKTsKKyAgICB9IGVsc2UgeworICAgICAgRE8oQ29uc3VtZU1lc3NhZ2UocmVmbGVjdGlvbi0+TXV0YWJsZU1lc3NhZ2UobWVzc2FnZSwgZmllbGQpLAorICAgICAgICAgICAgICAgICAgICAgICAgZGVsaW1pdGVyKSk7CisgICAgfQorCisgICAgLy8gUmVzZXQgdGhlIHBhcnNlIGluZm9ybWF0aW9uIHRyZWUuCisgICAgcGFyc2VfaW5mb190cmVlXyA9IHBhcmVudDsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIC8vIFNraXBzIHRoZSB3aG9sZSBib2R5IG9mIGEgbWVzc2FnZSBpbmNsdWRpbmcgdGhlIGJlZ2lubmluZyBkZWxpbWl0ZXIgYW5kCisgIC8vIHRoZSBlbmRpbmcgZGVsaW1pdGVyLgorICBib29sIFNraXBGaWVsZE1lc3NhZ2UoKSB7CisgICAgc3RyaW5nIGRlbGltaXRlcjsKKyAgICBETyhDb25zdW1lTWVzc2FnZURlbGltaXRlcigmZGVsaW1pdGVyKSk7CisgICAgd2hpbGUgKCFMb29raW5nQXQoIj4iKSAmJiAgIUxvb2tpbmdBdCgifSIpKSB7CisgICAgICBETyhTa2lwRmllbGQoKSk7CisgICAgfQorICAgIERPKENvbnN1bWUoZGVsaW1pdGVyKSk7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICBib29sIENvbnN1bWVGaWVsZFZhbHVlKE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKSB7CisKKy8vIERlZmluZSBhbiBlYXN5IHRvIHVzZSBtYWNybyBmb3Igc2V0dGluZyBmaWVsZHMuIFRoaXMgbWFjcm8gY2hlY2tzCisvLyB0byBzZWUgaWYgdGhlIGZpZWxkIGlzIHJlcGVhdGVkIChpbiB3aGljaCBjYXNlIHdlIG5lZWQgdG8gdXNlIHRoZSBBZGQKKy8vIG1ldGhvZHMgb3Igbm90IChpbiB3aGljaCBjYXNlIHdlIG5lZWQgdG8gdXNlIHRoZSBTZXQgbWV0aG9kcykuCisjZGVmaW5lIFNFVF9GSUVMRChDUFBUWVBFLCBWQUxVRSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICByZWZsZWN0aW9uLT5BZGQjI0NQUFRZUEUobWVzc2FnZSwgZmllbGQsIFZBTFVFKTsgICAgICAgICBcCisgICAgICAgIH0gZWxzZSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgIHJlZmxlY3Rpb24tPlNldCMjQ1BQVFlQRShtZXNzYWdlLCBmaWVsZCwgVkFMVUUpOyAgICAgICAgIFwKKyAgICAgICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisKKyAgICBzd2l0Y2goZmllbGQtPmNwcF90eXBlKCkpIHsKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0lOVDMyOiB7CisgICAgICAgIGludDY0IHZhbHVlOworICAgICAgICBETyhDb25zdW1lU2lnbmVkSW50ZWdlcigmdmFsdWUsIGtpbnQzMm1heCkpOworICAgICAgICBTRVRfRklFTEQoSW50MzIsIHN0YXRpY19jYXN0PGludDMyPih2YWx1ZSkpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDMyOiB7CisgICAgICAgIHVpbnQ2NCB2YWx1ZTsKKyAgICAgICAgRE8oQ29uc3VtZVVuc2lnbmVkSW50ZWdlcigmdmFsdWUsIGt1aW50MzJtYXgpKTsKKyAgICAgICAgU0VUX0ZJRUxEKFVJbnQzMiwgc3RhdGljX2Nhc3Q8dWludDMyPih2YWx1ZSkpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UNjQ6IHsKKyAgICAgICAgaW50NjQgdmFsdWU7CisgICAgICAgIERPKENvbnN1bWVTaWduZWRJbnRlZ2VyKCZ2YWx1ZSwga2ludDY0bWF4KSk7CisgICAgICAgIFNFVF9GSUVMRChJbnQ2NCwgdmFsdWUpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDY0OiB7CisgICAgICAgIHVpbnQ2NCB2YWx1ZTsKKyAgICAgICAgRE8oQ29uc3VtZVVuc2lnbmVkSW50ZWdlcigmdmFsdWUsIGt1aW50NjRtYXgpKTsKKyAgICAgICAgU0VUX0ZJRUxEKFVJbnQ2NCwgdmFsdWUpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRkxPQVQ6IHsKKyAgICAgICAgZG91YmxlIHZhbHVlOworICAgICAgICBETyhDb25zdW1lRG91YmxlKCZ2YWx1ZSkpOworICAgICAgICBTRVRfRklFTEQoRmxvYXQsIGlvOjpTYWZlRG91YmxlVG9GbG9hdCh2YWx1ZSkpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRE9VQkxFOiB7CisgICAgICAgIGRvdWJsZSB2YWx1ZTsKKyAgICAgICAgRE8oQ29uc3VtZURvdWJsZSgmdmFsdWUpKTsKKyAgICAgICAgU0VUX0ZJRUxEKERvdWJsZSwgdmFsdWUpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HOiB7CisgICAgICAgIHN0cmluZyB2YWx1ZTsKKyAgICAgICAgRE8oQ29uc3VtZVN0cmluZygmdmFsdWUpKTsKKyAgICAgICAgU0VUX0ZJRUxEKFN0cmluZywgdmFsdWUpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfQk9PTDogeworICAgICAgICBpZiAoTG9va2luZ0F0VHlwZShpbzo6VG9rZW5pemVyOjpUWVBFX0lOVEVHRVIpKSB7CisgICAgICAgICAgdWludDY0IHZhbHVlOworICAgICAgICAgIERPKENvbnN1bWVVbnNpZ25lZEludGVnZXIoJnZhbHVlLCAxKSk7CisgICAgICAgICAgU0VUX0ZJRUxEKEJvb2wsIHZhbHVlKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzdHJpbmcgdmFsdWU7CisgICAgICAgICAgRE8oQ29uc3VtZUlkZW50aWZpZXIoJnZhbHVlKSk7CisgICAgICAgICAgaWYgKHZhbHVlID09ICJ0cnVlIiB8fCB2YWx1ZSA9PSAiVHJ1ZSIgfHwgdmFsdWUgPT0gInQiKSB7CisgICAgICAgICAgICBTRVRfRklFTEQoQm9vbCwgdHJ1ZSk7CisgICAgICAgICAgfSBlbHNlIGlmICh2YWx1ZSA9PSAiZmFsc2UiIHx8IHZhbHVlID09ICJGYWxzZSIgfHwgdmFsdWUgPT0gImYiKSB7CisgICAgICAgICAgICBTRVRfRklFTEQoQm9vbCwgZmFsc2UpOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBSZXBvcnRFcnJvcigiSW52YWxpZCB2YWx1ZSBmb3IgYm9vbGVhbiBmaWVsZCBcIiIgKyBmaWVsZC0+bmFtZSgpCisgICAgICAgICAgICAgICAgICAgICAgICArICJcIi4gVmFsdWU6IFwiIiArIHZhbHVlICArICJcIi4iKTsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0VOVU06IHsKKyAgICAgICAgc3RyaW5nIHZhbHVlOworICAgICAgICBjb25zdCBFbnVtRGVzY3JpcHRvciogZW51bV90eXBlID0gZmllbGQtPmVudW1fdHlwZSgpOworICAgICAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiBlbnVtX3ZhbHVlID0gTlVMTDsKKworICAgICAgICBpZiAoTG9va2luZ0F0VHlwZShpbzo6VG9rZW5pemVyOjpUWVBFX0lERU5USUZJRVIpKSB7CisgICAgICAgICAgRE8oQ29uc3VtZUlkZW50aWZpZXIoJnZhbHVlKSk7CisgICAgICAgICAgLy8gRmluZCB0aGUgZW51bWVyYXRpb24gdmFsdWUuCisgICAgICAgICAgZW51bV92YWx1ZSA9IGVudW1fdHlwZS0+RmluZFZhbHVlQnlOYW1lKHZhbHVlKTsKKworICAgICAgICB9IGVsc2UgaWYgKExvb2tpbmdBdCgiLSIpIHx8CisgICAgICAgICAgICAgICAgICAgTG9va2luZ0F0VHlwZShpbzo6VG9rZW5pemVyOjpUWVBFX0lOVEVHRVIpKSB7CisgICAgICAgICAgaW50NjQgaW50X3ZhbHVlOworICAgICAgICAgIERPKENvbnN1bWVTaWduZWRJbnRlZ2VyKCZpbnRfdmFsdWUsIGtpbnQzMm1heCkpOworICAgICAgICAgIHZhbHVlID0gU2ltcGxlSXRvYShpbnRfdmFsdWUpOyAgICAgICAgLy8gZm9yIGVycm9yIHJlcG9ydGluZworICAgICAgICAgIGVudW1fdmFsdWUgPSBlbnVtX3R5cGUtPkZpbmRWYWx1ZUJ5TnVtYmVyKGludF92YWx1ZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgUmVwb3J0RXJyb3IoIkV4cGVjdGVkIGludGVnZXIgb3IgaWRlbnRpZmllci4iKTsKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKworICAgICAgICBpZiAoZW51bV92YWx1ZSA9PSBOVUxMKSB7CisgICAgICAgICAgaWYgKCFhbGxvd191bmtub3duX2VudW1fKSB7CisgICAgICAgICAgICBSZXBvcnRFcnJvcigiVW5rbm93biBlbnVtZXJhdGlvbiB2YWx1ZSBvZiBcIiIgKyB2YWx1ZSAgKyAiXCIgZm9yICIKKyAgICAgICAgICAgICAgICAgICAgICAgICJmaWVsZCBcIiIgKyBmaWVsZC0+bmFtZSgpICsgIlwiLiIpOworICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBSZXBvcnRXYXJuaW5nKCJVbmtub3duIGVudW1lcmF0aW9uIHZhbHVlIG9mIFwiIiArIHZhbHVlICArICJcIiBmb3IgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAiZmllbGQgXCIiICsgZmllbGQtPm5hbWUoKSArICJcIi4iKTsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIFNFVF9GSUVMRChFbnVtLCBlbnVtX3ZhbHVlKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0U6IHsKKyAgICAgICAgLy8gV2Ugc2hvdWxkIG5ldmVyIGdldCBoZXJlLiBQdXQgaGVyZSBpbnN0ZWFkIG9mIGEgZGVmYXVsdAorICAgICAgICAvLyBzbyB0aGF0IGlmIG5ldyB0eXBlcyBhcmUgYWRkZWQsIHdlIGdldCBhIG5pY2UgY29tcGlsZXIgd2FybmluZy4KKyAgICAgICAgR09PR0xFX0xPRyhGQVRBTCkgPDwgIlJlYWNoZWQgYW4gdW5pbnRlbmRlZCBzdGF0ZTogQ1BQVFlQRV9NRVNTQUdFIjsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorI3VuZGVmIFNFVF9GSUVMRAorICAgIHJldHVybiB0cnVlOworICB9CisKKyAgYm9vbCBTa2lwRmllbGRWYWx1ZSgpIHsKKyAgICBpZiAoTG9va2luZ0F0VHlwZShpbzo6VG9rZW5pemVyOjpUWVBFX1NUUklORykpIHsKKyAgICAgIHdoaWxlIChMb29raW5nQXRUeXBlKGlvOjpUb2tlbml6ZXI6OlRZUEVfU1RSSU5HKSkgeworICAgICAgICB0b2tlbml6ZXJfLk5leHQoKTsKKyAgICAgIH0KKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgICAvLyBQb3NzaWJsZSBmaWVsZCB2YWx1ZXMgb3RoZXIgdGhhbiBzdHJpbmc6CisgICAgLy8gICAxMjM0NSAgICAgICAgPT4gVFlQRV9JTlRFR0VSCisgICAgLy8gICAtMTIzNDUgICAgICAgPT4gVFlQRV9TWU1CT0wgKyBUWVBFX0lOVEVHRVIKKyAgICAvLyAgIDEuMjM0NSAgICAgICA9PiBUWVBFX0ZMT0FUCisgICAgLy8gICAtMS4yMzQ1ICAgICAgPT4gVFlQRV9TWU1CT0wgKyBUWVBFX0ZMT0FUCisgICAgLy8gICBpbmYgICAgICAgICAgPT4gVFlQRV9JREVOVElGSUVSCisgICAgLy8gICAtaW5mICAgICAgICAgPT4gVFlQRV9TWU1CT0wgKyBUWVBFX0lERU5USUZJRVIKKyAgICAvLyAgIFRZUEVfSU5URUdFUiA9PiBUWVBFX0lERU5USUZJRVIKKyAgICAvLyBEaXZpZGVzIHRoZW0gaW50byB0d28gZ3JvdXAsIG9uZSB3aXRoIFRZUEVfU1lNQk9MCisgICAgLy8gYW5kIHRoZSBvdGhlciB3aXRob3V0OgorICAgIC8vICAgR3JvdXAgb25lOgorICAgIC8vICAgICAxMjM0NSAgICAgICAgPT4gVFlQRV9JTlRFR0VSCisgICAgLy8gICAgIDEuMjM0NSAgICAgICA9PiBUWVBFX0ZMT0FUCisgICAgLy8gICAgIGluZiAgICAgICAgICA9PiBUWVBFX0lERU5USUZJRVIKKyAgICAvLyAgICAgVFlQRV9JTlRFR0VSID0+IFRZUEVfSURFTlRJRklFUgorICAgIC8vICAgR3JvdXAgdHdvOgorICAgIC8vICAgICAtMTIzNDUgICAgICAgPT4gVFlQRV9TWU1CT0wgKyBUWVBFX0lOVEVHRVIKKyAgICAvLyAgICAgLTEuMjM0NSAgICAgID0+IFRZUEVfU1lNQk9MICsgVFlQRV9GTE9BVAorICAgIC8vICAgICAtaW5mICAgICAgICAgPT4gVFlQRV9TWU1CT0wgKyBUWVBFX0lERU5USUZJRVIKKyAgICAvLyBBcyB3ZSBjYW4gc2VlLCB0aGUgZmllbGQgdmFsdWUgY29uc2lzdHMgb2YgYW4gb3B0aW9uYWwgJy0nIGFuZCBvbmUgb2YKKyAgICAvLyBUWVBFX0lOVEVHRVIsIFRZUEVfRkxPQVQgYW5kIFRZUEVfSURFTlRJRklFUi4KKyAgICBib29sIGhhc19taW51cyA9IFRyeUNvbnN1bWUoIi0iKTsKKyAgICBpZiAoIUxvb2tpbmdBdFR5cGUoaW86OlRva2VuaXplcjo6VFlQRV9JTlRFR0VSKSAmJgorICAgICAgICAhTG9va2luZ0F0VHlwZShpbzo6VG9rZW5pemVyOjpUWVBFX0ZMT0FUKSAmJgorICAgICAgICAhTG9va2luZ0F0VHlwZShpbzo6VG9rZW5pemVyOjpUWVBFX0lERU5USUZJRVIpKSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIC8vIENvbWJpbmF0aW9uIG9mICctJyBhbmQgVFlQRV9JREVOVElGSUVSIG1heSByZXN1bHQgaW4gYW4gaW52YWxpZCBmaWVsZAorICAgIC8vIHZhbHVlIHdoaWxlIG90aGVyIGNvbWJpbmF0aW9ucyBhbGwgZ2VuZXJhdGUgdmFsaWQgdmFsdWVzLgorICAgIC8vIFdlIGNoZWNrIGlmIHRoZSB2YWx1ZSBvZiB0aGlzIGNvbWJpbmF0aW9uIGlzIHZhbGlkIGhlcmUuCisgICAgLy8gVFlQRV9JREVOVElGSUVSIGFmdGVyIGEgJy0nIHNob3VsZCBiZSBvbmUgb2YgdGhlIGZsb2F0IHZhbHVlcyBsaXN0ZWQKKyAgICAvLyBiZWxvdzoKKyAgICAvLyAgIGluZiwgaW5mZiwgaW5maW5pdHksIG5hbgorICAgIGlmIChoYXNfbWludXMgJiYgTG9va2luZ0F0VHlwZShpbzo6VG9rZW5pemVyOjpUWVBFX0lERU5USUZJRVIpKSB7CisgICAgICBzdHJpbmcgdGV4dCA9IHRva2VuaXplcl8uY3VycmVudCgpLnRleHQ7CisgICAgICBMb3dlclN0cmluZygmdGV4dCk7CisgICAgICBpZiAodGV4dCAhPSAiaW5mIiAmJgorICAgICAgICAgIHRleHQgIT0gImluZmluaXR5IiAmJgorICAgICAgICAgIHRleHQgIT0gIm5hbiIpIHsKKyAgICAgICAgUmVwb3J0RXJyb3IoIkludmFsaWQgZmxvYXQgbnVtYmVyOiAiICsgdGV4dCk7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICB9CisgICAgdG9rZW5pemVyXy5OZXh0KCk7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICAvLyBSZXR1cm5zIHRydWUgaWYgdGhlIGN1cnJlbnQgdG9rZW4ncyB0ZXh0IGlzIGVxdWFsIHRvIHRoYXQgc3BlY2lmaWVkLgorICBib29sIExvb2tpbmdBdChjb25zdCBzdHJpbmcmIHRleHQpIHsKKyAgICByZXR1cm4gdG9rZW5pemVyXy5jdXJyZW50KCkudGV4dCA9PSB0ZXh0OworICB9CisKKyAgLy8gUmV0dXJucyB0cnVlIGlmIHRoZSBjdXJyZW50IHRva2VuJ3MgdHlwZSBpcyBlcXVhbCB0byB0aGF0IHNwZWNpZmllZC4KKyAgYm9vbCBMb29raW5nQXRUeXBlKGlvOjpUb2tlbml6ZXI6OlRva2VuVHlwZSB0b2tlbl90eXBlKSB7CisgICAgcmV0dXJuIHRva2VuaXplcl8uY3VycmVudCgpLnR5cGUgPT0gdG9rZW5fdHlwZTsKKyAgfQorCisgIC8vIENvbnN1bWVzIGFuIGlkZW50aWZpZXIgYW5kIHNhdmVzIGl0cyB2YWx1ZSBpbiB0aGUgaWRlbnRpZmllciBwYXJhbWV0ZXIuCisgIC8vIFJldHVybnMgZmFsc2UgaWYgdGhlIHRva2VuIGlzIG5vdCBvZiB0eXBlIElERU5URklFUi4KKyAgYm9vbCBDb25zdW1lSWRlbnRpZmllcihzdHJpbmcqIGlkZW50aWZpZXIpIHsKKyAgICBpZiAoTG9va2luZ0F0VHlwZShpbzo6VG9rZW5pemVyOjpUWVBFX0lERU5USUZJRVIpKSB7CisgICAgICAqaWRlbnRpZmllciA9IHRva2VuaXplcl8uY3VycmVudCgpLnRleHQ7CisgICAgICB0b2tlbml6ZXJfLk5leHQoKTsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIC8vIElmIGFsbG93X2ZpZWxkX251bWVyXyBvciBhbGxvd191bmtub3duX2ZpZWxkXyBpcyB0cnVlLCB3ZSBzaG91bGQgYWJsZQorICAgIC8vIHRvIHBhcnNlIGludGVnZXIgaWRlbnRpZmllcnMuCisgICAgaWYgKChhbGxvd19maWVsZF9udW1iZXJfIHx8IGFsbG93X3Vua25vd25fZmllbGRfKQorICAgICAgICAmJiBMb29raW5nQXRUeXBlKGlvOjpUb2tlbml6ZXI6OlRZUEVfSU5URUdFUikpIHsKKyAgICAgICppZGVudGlmaWVyID0gdG9rZW5pemVyXy5jdXJyZW50KCkudGV4dDsKKyAgICAgIHRva2VuaXplcl8uTmV4dCgpOworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgUmVwb3J0RXJyb3IoIkV4cGVjdGVkIGlkZW50aWZpZXIuIik7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8gQ29uc3VtZSBhIHN0cmluZyBvZiBmb3JtICI8aWQxPi48aWQyPi4uLi48aWROPiIuCisgIGJvb2wgQ29uc3VtZUZ1bGxUeXBlTmFtZShzdHJpbmcqIG5hbWUpIHsKKyAgICBETyhDb25zdW1lSWRlbnRpZmllcihuYW1lKSk7CisgICAgd2hpbGUgKFRyeUNvbnN1bWUoIi4iKSkgeworICAgICAgc3RyaW5nIHBhcnQ7CisgICAgICBETyhDb25zdW1lSWRlbnRpZmllcigmcGFydCkpOworICAgICAgKm5hbWUgKz0gIi4iOworICAgICAgKm5hbWUgKz0gcGFydDsKKyAgICB9CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICAvLyBDb25zdW1lcyBhIHN0cmluZyBhbmQgc2F2ZXMgaXRzIHZhbHVlIGluIHRoZSB0ZXh0IHBhcmFtZXRlci4KKyAgLy8gUmV0dXJucyBmYWxzZSBpZiB0aGUgdG9rZW4gaXMgbm90IG9mIHR5cGUgU1RSSU5HLgorICBib29sIENvbnN1bWVTdHJpbmcoc3RyaW5nKiB0ZXh0KSB7CisgICAgaWYgKCFMb29raW5nQXRUeXBlKGlvOjpUb2tlbml6ZXI6OlRZUEVfU1RSSU5HKSkgeworICAgICAgUmVwb3J0RXJyb3IoIkV4cGVjdGVkIHN0cmluZy4iKTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICB0ZXh0LT5jbGVhcigpOworICAgIHdoaWxlIChMb29raW5nQXRUeXBlKGlvOjpUb2tlbml6ZXI6OlRZUEVfU1RSSU5HKSkgeworICAgICAgaW86OlRva2VuaXplcjo6UGFyc2VTdHJpbmdBcHBlbmQodG9rZW5pemVyXy5jdXJyZW50KCkudGV4dCwgdGV4dCk7CisKKyAgICAgIHRva2VuaXplcl8uTmV4dCgpOworICAgIH0KKworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgLy8gQ29uc3VtZXMgYSB1aW50NjQgYW5kIHNhdmVzIGl0cyB2YWx1ZSBpbiB0aGUgdmFsdWUgcGFyYW1ldGVyLgorICAvLyBSZXR1cm5zIGZhbHNlIGlmIHRoZSB0b2tlbiBpcyBub3Qgb2YgdHlwZSBJTlRFR0VSLgorICBib29sIENvbnN1bWVVbnNpZ25lZEludGVnZXIodWludDY0KiB2YWx1ZSwgdWludDY0IG1heF92YWx1ZSkgeworICAgIGlmICghTG9va2luZ0F0VHlwZShpbzo6VG9rZW5pemVyOjpUWVBFX0lOVEVHRVIpKSB7CisgICAgICBSZXBvcnRFcnJvcigiRXhwZWN0ZWQgaW50ZWdlci4iKTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBpZiAoIWlvOjpUb2tlbml6ZXI6OlBhcnNlSW50ZWdlcih0b2tlbml6ZXJfLmN1cnJlbnQoKS50ZXh0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heF92YWx1ZSwgdmFsdWUpKSB7CisgICAgICBSZXBvcnRFcnJvcigiSW50ZWdlciBvdXQgb2YgcmFuZ2UuIik7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgdG9rZW5pemVyXy5OZXh0KCk7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICAvLyBDb25zdW1lcyBhbiBpbnQ2NCBhbmQgc2F2ZXMgaXRzIHZhbHVlIGluIHRoZSB2YWx1ZSBwYXJhbWV0ZXIuCisgIC8vIE5vdGUgdGhhdCBzaW5jZSB0aGUgdG9rZW5pemVyIGRvZXMgbm90IHN1cHBvcnQgbmVnYXRpdmUgbnVtYmVycywKKyAgLy8gd2UgYWN0dWFsbHkgbWF5IGNvbnN1bWUgYW4gYWRkaXRpb25hbCB0b2tlbiAoZm9yIHRoZSBtaW51cyBzaWduKSBpbiB0aGlzCisgIC8vIG1ldGhvZC4gUmV0dXJucyBmYWxzZSBpZiB0aGUgdG9rZW4gaXMgbm90IGFuIGludGVnZXIKKyAgLy8gKHNpZ25lZCBvciBvdGhlcndpc2UpLgorICBib29sIENvbnN1bWVTaWduZWRJbnRlZ2VyKGludDY0KiB2YWx1ZSwgdWludDY0IG1heF92YWx1ZSkgeworICAgIGJvb2wgbmVnYXRpdmUgPSBmYWxzZTsKKworICAgIGlmIChUcnlDb25zdW1lKCItIikpIHsKKyAgICAgIG5lZ2F0aXZlID0gdHJ1ZTsKKyAgICAgIC8vIFR3bydzIGNvbXBsZW1lbnQgYWx3YXlzIGFsbG93cyBvbmUgbW9yZSBuZWdhdGl2ZSBpbnRlZ2VyIHRoYW4KKyAgICAgIC8vIHBvc2l0aXZlLgorICAgICAgKyttYXhfdmFsdWU7CisgICAgfQorCisgICAgdWludDY0IHVuc2lnbmVkX3ZhbHVlOworCisgICAgRE8oQ29uc3VtZVVuc2lnbmVkSW50ZWdlcigmdW5zaWduZWRfdmFsdWUsIG1heF92YWx1ZSkpOworCisgICAgKnZhbHVlID0gc3RhdGljX2Nhc3Q8aW50NjQ+KHVuc2lnbmVkX3ZhbHVlKTsKKworICAgIGlmIChuZWdhdGl2ZSkgeworICAgICAgKnZhbHVlID0gLSp2YWx1ZTsKKyAgICB9CisKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIC8vIENvbnN1bWVzIGEgdWludDY0IGFuZCBzYXZlcyBpdHMgdmFsdWUgaW4gdGhlIHZhbHVlIHBhcmFtZXRlci4KKyAgLy8gQWNjZXB0cyBkZWNpbWFsIG51bWJlcnMgb25seSwgcmVqZWN0cyBoZXggb3Igb2N0IG51bWJlcnMuCisgIGJvb2wgQ29uc3VtZVVuc2lnbmVkRGVjaW1hbEludGVnZXIodWludDY0KiB2YWx1ZSwgdWludDY0IG1heF92YWx1ZSkgeworICAgIGlmICghTG9va2luZ0F0VHlwZShpbzo6VG9rZW5pemVyOjpUWVBFX0lOVEVHRVIpKSB7CisgICAgICBSZXBvcnRFcnJvcigiRXhwZWN0ZWQgaW50ZWdlci4iKTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBjb25zdCBzdHJpbmcmIHRleHQgPSB0b2tlbml6ZXJfLmN1cnJlbnQoKS50ZXh0OworICAgIGlmIChJc0hleE51bWJlcih0ZXh0KSB8fCBJc09jdE51bWJlcih0ZXh0KSkgeworICAgICAgUmVwb3J0RXJyb3IoIkV4cGVjdCBhIGRlY2ltYWwgbnVtYmVyLiIpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIGlmICghaW86OlRva2VuaXplcjo6UGFyc2VJbnRlZ2VyKHRleHQsIG1heF92YWx1ZSwgdmFsdWUpKSB7CisgICAgICBSZXBvcnRFcnJvcigiSW50ZWdlciBvdXQgb2YgcmFuZ2UuIik7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgdG9rZW5pemVyXy5OZXh0KCk7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICAvLyBDb25zdW1lcyBhIGRvdWJsZSBhbmQgc2F2ZXMgaXRzIHZhbHVlIGluIHRoZSB2YWx1ZSBwYXJhbWV0ZXIuCisgIC8vIE5vdGUgdGhhdCBzaW5jZSB0aGUgdG9rZW5pemVyIGRvZXMgbm90IHN1cHBvcnQgbmVnYXRpdmUgbnVtYmVycywKKyAgLy8gd2UgYWN0dWFsbHkgbWF5IGNvbnN1bWUgYW4gYWRkaXRpb25hbCB0b2tlbiAoZm9yIHRoZSBtaW51cyBzaWduKSBpbiB0aGlzCisgIC8vIG1ldGhvZC4gUmV0dXJucyBmYWxzZSBpZiB0aGUgdG9rZW4gaXMgbm90IGEgZG91YmxlCisgIC8vIChzaWduZWQgb3Igb3RoZXJ3aXNlKS4KKyAgYm9vbCBDb25zdW1lRG91YmxlKGRvdWJsZSogdmFsdWUpIHsKKyAgICBib29sIG5lZ2F0aXZlID0gZmFsc2U7CisKKyAgICBpZiAoVHJ5Q29uc3VtZSgiLSIpKSB7CisgICAgICBuZWdhdGl2ZSA9IHRydWU7CisgICAgfQorCisgICAgLy8gQSBkb3VibGUgY2FuIGFjdHVhbGx5IGJlIGFuIGludGVnZXIsIGFjY29yZGluZyB0byB0aGUgdG9rZW5pemVyLgorICAgIC8vIFRoZXJlZm9yZSwgd2UgbXVzdCBjaGVjayBib3RoIGNhc2VzIGhlcmUuCisgICAgaWYgKExvb2tpbmdBdFR5cGUoaW86OlRva2VuaXplcjo6VFlQRV9JTlRFR0VSKSkgeworICAgICAgLy8gV2UgaGF2ZSBmb3VuZCBhbiBpbnRlZ2VyIHZhbHVlIGZvciB0aGUgZG91YmxlLgorICAgICAgdWludDY0IGludGVnZXJfdmFsdWU7CisgICAgICBETyhDb25zdW1lVW5zaWduZWREZWNpbWFsSW50ZWdlcigmaW50ZWdlcl92YWx1ZSwga3VpbnQ2NG1heCkpOworCisgICAgICAqdmFsdWUgPSBzdGF0aWNfY2FzdDxkb3VibGU+KGludGVnZXJfdmFsdWUpOworICAgIH0gZWxzZSBpZiAoTG9va2luZ0F0VHlwZShpbzo6VG9rZW5pemVyOjpUWVBFX0ZMT0FUKSkgeworICAgICAgLy8gV2UgaGF2ZSBmb3VuZCBhIGZsb2F0IHZhbHVlIGZvciB0aGUgZG91YmxlLgorICAgICAgKnZhbHVlID0gaW86OlRva2VuaXplcjo6UGFyc2VGbG9hdCh0b2tlbml6ZXJfLmN1cnJlbnQoKS50ZXh0KTsKKworICAgICAgLy8gTWFyayB0aGUgY3VycmVudCB0b2tlbiBhcyBjb25zdW1lZC4KKyAgICAgIHRva2VuaXplcl8uTmV4dCgpOworICAgIH0gZWxzZSBpZiAoTG9va2luZ0F0VHlwZShpbzo6VG9rZW5pemVyOjpUWVBFX0lERU5USUZJRVIpKSB7CisgICAgICBzdHJpbmcgdGV4dCA9IHRva2VuaXplcl8uY3VycmVudCgpLnRleHQ7CisgICAgICBMb3dlclN0cmluZygmdGV4dCk7CisgICAgICBpZiAodGV4dCA9PSAiaW5mIiB8fAorICAgICAgICAgIHRleHQgPT0gImluZmluaXR5IikgeworICAgICAgICAqdmFsdWUgPSBzdGQ6Om51bWVyaWNfbGltaXRzPGRvdWJsZT46OmluZmluaXR5KCk7CisgICAgICAgIHRva2VuaXplcl8uTmV4dCgpOworICAgICAgfSBlbHNlIGlmICh0ZXh0ID09ICJuYW4iKSB7CisgICAgICAgICp2YWx1ZSA9IHN0ZDo6bnVtZXJpY19saW1pdHM8ZG91YmxlPjo6cXVpZXRfTmFOKCk7CisgICAgICAgIHRva2VuaXplcl8uTmV4dCgpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgUmVwb3J0RXJyb3IoIkV4cGVjdGVkIGRvdWJsZS4iKTsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICBSZXBvcnRFcnJvcigiRXhwZWN0ZWQgZG91YmxlLiIpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIGlmIChuZWdhdGl2ZSkgeworICAgICAgKnZhbHVlID0gLSp2YWx1ZTsKKyAgICB9CisKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIC8vIENvbnN1bWVzIEFueTo6dHlwZV91cmwgdmFsdWUsIG9mIGZvcm0gInR5cGUuZ29vZ2xlYXBpcy5jb20vZnVsbC50eXBlLk5hbWUiCisgIC8vIG9yICJ0eXBlLmdvb2dsZXByb2QuY29tL2Z1bGwudHlwZS5OYW1lIgorICBib29sIENvbnN1bWVBbnlUeXBlVXJsKHN0cmluZyogZnVsbF90eXBlX25hbWUsIHN0cmluZyogcHJlZml4KSB7CisgICAgLy8gVE9ETyhzYWl0bykgRXh0ZW5kIENvbnN1bWUoKSB0byBjb25zdW1lIG11bHRpcGxlIHRva2VucyBhdCBvbmNlLCBzbyB0aGF0CisgICAgLy8gdGhpcyBjb2RlIGNhbiBiZSB3cml0dGVuIGFzIGp1c3QgRE8oQ29uc3VtZShrR29vZ2xlQXBpc1R5cGVQcmVmaXgpKS4KKyAgICBzdHJpbmcgdXJsMSwgdXJsMiwgdXJsMzsKKyAgICBETyhDb25zdW1lSWRlbnRpZmllcigmdXJsMSkpOyAgLy8gdHlwZQorICAgIERPKENvbnN1bWUoIi4iKSk7CisgICAgRE8oQ29uc3VtZUlkZW50aWZpZXIoJnVybDIpKTsgIC8vIGdvb2dsZWFwaXMKKyAgICBETyhDb25zdW1lKCIuIikpOworICAgIERPKENvbnN1bWVJZGVudGlmaWVyKCZ1cmwzKSk7ICAvLyBjb20KKyAgICBETyhDb25zdW1lKCIvIikpOworICAgIERPKENvbnN1bWVGdWxsVHlwZU5hbWUoZnVsbF90eXBlX25hbWUpKTsKKworICAgICpwcmVmaXggPSB1cmwxICsgIi4iICsgdXJsMiArICIuIiArIHVybDMgKyAiLyI7CisgICAgaWYgKCpwcmVmaXggIT0gaW50ZXJuYWw6OmtUeXBlR29vZ2xlQXBpc0NvbVByZWZpeCAmJgorICAgICAgICAqcHJlZml4ICE9IGludGVybmFsOjprVHlwZUdvb2dsZVByb2RDb21QcmVmaXgpIHsKKyAgICAgIFJlcG9ydEVycm9yKCJUZXh0Rm9ybWF0OjpQYXJzZXIgZm9yIEFueSBzdXBwb3J0cyBvbmx5ICIKKyAgICAgICAgICAgICAgICAgICJ0eXBlLmdvb2dsZWFwaXMuY29tIGFuZCB0eXBlLmdvb2dsZXByb2QuY29tLCAiCisgICAgICAgICAgICAgICAgICAiYnV0IGZvdW5kIFwiIiArICpwcmVmaXggKyAiXCIiKTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICAvLyBBIGhlbHBlciBmdW5jdGlvbiBmb3IgcmVjb25zdHJ1Y3RpbmcgQW55Ojp2YWx1ZS4gQ29uc3VtZXMgYSB0ZXh0IG9mCisgIC8vIGZ1bGxfdHlwZV9uYW1lLCB0aGVuIHNlcmlhbGl6ZXMgaXQgaW50byBzZXJpYWxpemVkX3ZhbHVlLiAicG9vbCIgaXMgdXNlZCB0bworICAvLyBsb29rIHVwIGFuZCBjcmVhdGUgYSB0ZW1wb3Jhcnkgb2JqZWN0IHdpdGggZnVsbF90eXBlX25hbWUuCisgIGJvb2wgQ29uc3VtZUFueVZhbHVlKGNvbnN0IHN0cmluZyYgZnVsbF90eXBlX25hbWUsIGNvbnN0IERlc2NyaXB0b3JQb29sKiBwb29sLAorICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcqIHNlcmlhbGl6ZWRfdmFsdWUpIHsKKyAgICBjb25zdCBEZXNjcmlwdG9yKiB2YWx1ZV9kZXNjcmlwdG9yID0KKyAgICAgICAgcG9vbC0+RmluZE1lc3NhZ2VUeXBlQnlOYW1lKGZ1bGxfdHlwZV9uYW1lKTsKKyAgICBpZiAodmFsdWVfZGVzY3JpcHRvciA9PSBOVUxMKSB7CisgICAgICBSZXBvcnRFcnJvcigiQ291bGQgbm90IGZpbmQgdHlwZSBcIiIgKyBmdWxsX3R5cGVfbmFtZSArCisgICAgICAgICAgICAgICAgICAiXCIgc3RvcmVkIGluIGdvb2dsZS5wcm90b2J1Zi5BbnkuIik7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIER5bmFtaWNNZXNzYWdlRmFjdG9yeSBmYWN0b3J5OworICAgIGNvbnN0IE1lc3NhZ2UqIHZhbHVlX3Byb3RvdHlwZSA9IGZhY3RvcnkuR2V0UHJvdG90eXBlKHZhbHVlX2Rlc2NyaXB0b3IpOworICAgIGlmICh2YWx1ZV9wcm90b3R5cGUgPT0gTlVMTCkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPE1lc3NhZ2U+IHZhbHVlKHZhbHVlX3Byb3RvdHlwZS0+TmV3KCkpOworICAgIHN0cmluZyBzdWJfZGVsaW1pdGVyOworICAgIERPKENvbnN1bWVNZXNzYWdlRGVsaW1pdGVyKCZzdWJfZGVsaW1pdGVyKSk7CisgICAgRE8oQ29uc3VtZU1lc3NhZ2UodmFsdWUuZ2V0KCksIHN1Yl9kZWxpbWl0ZXIpKTsKKworICAgIHZhbHVlLT5BcHBlbmRUb1N0cmluZyhzZXJpYWxpemVkX3ZhbHVlKTsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIC8vIENvbnN1bWVzIGEgdG9rZW4gYW5kIGNvbmZpcm1zIHRoYXQgaXQgbWF0Y2hlcyB0aGF0IHNwZWNpZmllZCBpbiB0aGUKKyAgLy8gdmFsdWUgcGFyYW1ldGVyLiBSZXR1cm5zIGZhbHNlIGlmIHRoZSB0b2tlbiBmb3VuZCBkb2VzIG5vdCBtYXRjaCB0aGF0CisgIC8vIHdoaWNoIHdhcyBzcGVjaWZpZWQuCisgIGJvb2wgQ29uc3VtZShjb25zdCBzdHJpbmcmIHZhbHVlKSB7CisgICAgY29uc3Qgc3RyaW5nJiBjdXJyZW50X3ZhbHVlID0gdG9rZW5pemVyXy5jdXJyZW50KCkudGV4dDsKKworICAgIGlmIChjdXJyZW50X3ZhbHVlICE9IHZhbHVlKSB7CisgICAgICBSZXBvcnRFcnJvcigiRXhwZWN0ZWQgXCIiICsgdmFsdWUgKyAiXCIsIGZvdW5kIFwiIiArIGN1cnJlbnRfdmFsdWUKKyAgICAgICAgICAgICAgICAgICsgIlwiLiIpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHRva2VuaXplcl8uTmV4dCgpOworCisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICAvLyBBdHRlbXB0cyB0byBjb25zdW1lIHRoZSBzdXBwbGllZCB2YWx1ZS4gUmV0dXJucyBmYWxzZSBpZiBhIHRoZQorICAvLyB0b2tlbiBmb3VuZCBkb2VzIG5vdCBtYXRjaCB0aGUgdmFsdWUgc3BlY2lmaWVkLgorICBib29sIFRyeUNvbnN1bWUoY29uc3Qgc3RyaW5nJiB2YWx1ZSkgeworICAgIGlmICh0b2tlbml6ZXJfLmN1cnJlbnQoKS50ZXh0ID09IHZhbHVlKSB7CisgICAgICB0b2tlbml6ZXJfLk5leHQoKTsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICB9CisKKyAgLy8gQW4gaW50ZXJuYWwgaW5zdGFuY2Ugb2YgdGhlIFRva2VuaXplcidzIGVycm9yIGNvbGxlY3RvciwgdXNlZCB0bworICAvLyBjb2xsZWN0IGFueSBiYXNlLWxldmVsIHBhcnNlIGVycm9ycyBhbmQgZmVlZCB0aGVtIHRvIHRoZSBQYXJzZXJJbXBsLgorICBjbGFzcyBQYXJzZXJFcnJvckNvbGxlY3RvciA6IHB1YmxpYyBpbzo6RXJyb3JDb2xsZWN0b3IgeworICAgcHVibGljOgorICAgIGV4cGxpY2l0IFBhcnNlckVycm9yQ29sbGVjdG9yKFRleHRGb3JtYXQ6OlBhcnNlcjo6UGFyc2VySW1wbCogcGFyc2VyKSA6CisgICAgICAgIHBhcnNlcl8ocGFyc2VyKSB7IH0KKworICAgIHZpcnR1YWwgflBhcnNlckVycm9yQ29sbGVjdG9yKCkgeyB9CisKKyAgICB2aXJ0dWFsIHZvaWQgQWRkRXJyb3IoaW50IGxpbmUsIGludCBjb2x1bW4sIGNvbnN0IHN0cmluZyYgbWVzc2FnZSkgeworICAgICAgcGFyc2VyXy0+UmVwb3J0RXJyb3IobGluZSwgY29sdW1uLCBtZXNzYWdlKTsKKyAgICB9CisKKyAgICB2aXJ0dWFsIHZvaWQgQWRkV2FybmluZyhpbnQgbGluZSwgaW50IGNvbHVtbiwgY29uc3Qgc3RyaW5nJiBtZXNzYWdlKSB7CisgICAgICBwYXJzZXJfLT5SZXBvcnRXYXJuaW5nKGxpbmUsIGNvbHVtbiwgbWVzc2FnZSk7CisgICAgfQorCisgICBwcml2YXRlOgorICAgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhQYXJzZXJFcnJvckNvbGxlY3Rvcik7CisgICAgVGV4dEZvcm1hdDo6UGFyc2VyOjpQYXJzZXJJbXBsKiBwYXJzZXJfOworICB9OworCisgIGlvOjpFcnJvckNvbGxlY3RvciogZXJyb3JfY29sbGVjdG9yXzsKKyAgVGV4dEZvcm1hdDo6RmluZGVyKiBmaW5kZXJfOworICBQYXJzZUluZm9UcmVlKiBwYXJzZV9pbmZvX3RyZWVfOworICBQYXJzZXJFcnJvckNvbGxlY3RvciB0b2tlbml6ZXJfZXJyb3JfY29sbGVjdG9yXzsKKyAgaW86OlRva2VuaXplciB0b2tlbml6ZXJfOworICBjb25zdCBEZXNjcmlwdG9yKiByb290X21lc3NhZ2VfdHlwZV87CisgIFNpbmd1bGFyT3ZlcndyaXRlUG9saWN5IHNpbmd1bGFyX292ZXJ3cml0ZV9wb2xpY3lfOworICBjb25zdCBib29sIGFsbG93X2Nhc2VfaW5zZW5zaXRpdmVfZmllbGRfOworICBjb25zdCBib29sIGFsbG93X3Vua25vd25fZmllbGRfOworICBjb25zdCBib29sIGFsbG93X3Vua25vd25fZW51bV87CisgIGNvbnN0IGJvb2wgYWxsb3dfZmllbGRfbnVtYmVyXzsKKyAgYm9vbCBoYWRfZXJyb3JzXzsKK307CisKKyN1bmRlZiBETworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKy8vIEludGVybmFsIGNsYXNzIGZvciB3cml0aW5nIHRleHQgdG8gdGhlIGlvOjpaZXJvQ29weU91dHB1dFN0cmVhbS4gQWRhcHRlZAorLy8gZnJvbSB0aGUgUHJpbnRlciBmb3VuZCBpbiAvL2dvb2dsZS9wcm90b2J1Zi9pby9wcmludGVyLmgKK2NsYXNzIFRleHRGb3JtYXQ6OlByaW50ZXI6OlRleHRHZW5lcmF0b3IgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgVGV4dEdlbmVyYXRvcihpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0qIG91dHB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5pdGlhbF9pbmRlbnRfbGV2ZWwpCisgICAgOiBvdXRwdXRfKG91dHB1dCksCisgICAgICBidWZmZXJfKE5VTEwpLAorICAgICAgYnVmZmVyX3NpemVfKDApLAorICAgICAgYXRfc3RhcnRfb2ZfbGluZV8odHJ1ZSksCisgICAgICBmYWlsZWRfKGZhbHNlKSwKKyAgICAgIGluZGVudF8oIiIpLAorICAgICAgaW5pdGlhbF9pbmRlbnRfbGV2ZWxfKGluaXRpYWxfaW5kZW50X2xldmVsKSB7CisgICAgaW5kZW50Xy5yZXNpemUoaW5pdGlhbF9pbmRlbnRfbGV2ZWxfICogMiwgJyAnKTsKKyAgfQorCisgIH5UZXh0R2VuZXJhdG9yKCkgeworICAgIC8vIE9ubHkgQmFja1VwKCkgaWYgd2UncmUgc3VyZSB3ZSd2ZSBzdWNjZXNzZnVsbHkgY2FsbGVkIE5leHQoKSBhdCBsZWFzdAorICAgIC8vIG9uY2UuCisgICAgaWYgKCFmYWlsZWRfICYmIGJ1ZmZlcl9zaXplXyA+IDApIHsKKyAgICAgIG91dHB1dF8tPkJhY2tVcChidWZmZXJfc2l6ZV8pOworICAgIH0KKyAgfQorCisgIC8vIEluZGVudCB0ZXh0IGJ5IHR3byBzcGFjZXMuICBBZnRlciBjYWxsaW5nIEluZGVudCgpLCB0d28gc3BhY2VzIHdpbGwgYmUKKyAgLy8gaW5zZXJ0ZWQgYXQgdGhlIGJlZ2lubmluZyBvZiBlYWNoIGxpbmUgb2YgdGV4dC4gIEluZGVudCgpIG1heSBiZSBjYWxsZWQKKyAgLy8gbXVsdGlwbGUgdGltZXMgdG8gcHJvZHVjZSBkZWVwZXIgaW5kZW50cy4KKyAgdm9pZCBJbmRlbnQoKSB7CisgICAgaW5kZW50XyArPSAiICAiOworICB9CisKKyAgLy8gUmVkdWNlcyB0aGUgY3VycmVudCBpbmRlbnQgbGV2ZWwgYnkgdHdvIHNwYWNlcywgb3IgY3Jhc2hlcyBpZiB0aGUgaW5kZW50CisgIC8vIGxldmVsIGlzIHplcm8uCisgIHZvaWQgT3V0ZGVudCgpIHsKKyAgICBpZiAoaW5kZW50Xy5lbXB0eSgpIHx8CisgICAgICAgIGluZGVudF8uc2l6ZSgpIDwgaW5pdGlhbF9pbmRlbnRfbGV2ZWxfICogMikgeworICAgICAgR09PR0xFX0xPRyhERkFUQUwpIDw8ICIgT3V0ZGVudCgpIHdpdGhvdXQgbWF0Y2hpbmcgSW5kZW50KCkuIjsKKyAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBpbmRlbnRfLnJlc2l6ZShpbmRlbnRfLnNpemUoKSAtIDIpOworICB9CisKKyAgLy8gUHJpbnQgdGV4dCB0byB0aGUgb3V0cHV0IHN0cmVhbS4KKyAgdm9pZCBQcmludChjb25zdCBzdHJpbmcmIHN0cikgeworICAgIFByaW50KHN0ci5kYXRhKCksIHN0ci5zaXplKCkpOworICB9CisKKyAgLy8gUHJpbnQgdGV4dCB0byB0aGUgb3V0cHV0IHN0cmVhbS4KKyAgdm9pZCBQcmludChjb25zdCBjaGFyKiB0ZXh0KSB7CisgICAgUHJpbnQodGV4dCwgc3RybGVuKHRleHQpKTsKKyAgfQorCisgIC8vIFByaW50IHRleHQgdG8gdGhlIG91dHB1dCBzdHJlYW0uCisgIHZvaWQgUHJpbnQoY29uc3QgY2hhciogdGV4dCwgaW50IHNpemUpIHsKKyAgICBpbnQgcG9zID0gMDsgIC8vIFRoZSBudW1iZXIgb2YgYnl0ZXMgd2UndmUgd3JpdHRlbiBzbyBmYXIuCisKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgeworICAgICAgaWYgKHRleHRbaV0gPT0gJ1xuJykgeworICAgICAgICAvLyBTYXcgbmV3bGluZS4gIElmIHRoZXJlIGlzIG1vcmUgdGV4dCwgd2UgbWF5IG5lZWQgdG8gaW5zZXJ0IGFuIGluZGVudAorICAgICAgICAvLyBoZXJlLiAgU28sIHdyaXRlIHdoYXQgd2UgaGF2ZSBzbyBmYXIsIGluY2x1ZGluZyB0aGUgJ1xuJy4KKyAgICAgICAgV3JpdGUodGV4dCArIHBvcywgaSAtIHBvcyArIDEpOworICAgICAgICBwb3MgPSBpICsgMTsKKworICAgICAgICAvLyBTZXR0aW5nIHRoaXMgdHJ1ZSB3aWxsIGNhdXNlIHRoZSBuZXh0IFdyaXRlKCkgdG8gaW5zZXJ0IGFuIGluZGVudAorICAgICAgICAvLyBmaXJzdC4KKyAgICAgICAgYXRfc3RhcnRfb2ZfbGluZV8gPSB0cnVlOworICAgICAgfQorICAgIH0KKworICAgIC8vIFdyaXRlIHRoZSByZXN0LgorICAgIFdyaXRlKHRleHQgKyBwb3MsIHNpemUgLSBwb3MpOworICB9CisKKyAgLy8gVHJ1ZSBpZiBhbnkgd3JpdGUgdG8gdGhlIHVuZGVybHlpbmcgc3RyZWFtIGZhaWxlZC4gIChXZSBkb24ndCBqdXN0CisgIC8vIGNyYXNoIGluIHRoaXMgY2FzZSBiZWNhdXNlIHRoaXMgaXMgYW4gSS9PIGZhaWx1cmUsIG5vdCBhIHByb2dyYW1taW5nCisgIC8vIGVycm9yLikKKyAgYm9vbCBmYWlsZWQoKSBjb25zdCB7IHJldHVybiBmYWlsZWRfOyB9CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoVGV4dEdlbmVyYXRvcik7CisKKyAgdm9pZCBXcml0ZShjb25zdCBjaGFyKiBkYXRhLCBpbnQgc2l6ZSkgeworICAgIGlmIChmYWlsZWRfKSByZXR1cm47CisgICAgaWYgKHNpemUgPT0gMCkgcmV0dXJuOworCisgICAgaWYgKGF0X3N0YXJ0X29mX2xpbmVfKSB7CisgICAgICAvLyBJbnNlcnQgYW4gaW5kZW50LgorICAgICAgYXRfc3RhcnRfb2ZfbGluZV8gPSBmYWxzZTsKKyAgICAgIFdyaXRlKGluZGVudF8uZGF0YSgpLCBpbmRlbnRfLnNpemUoKSk7CisgICAgICBpZiAoZmFpbGVkXykgcmV0dXJuOworICAgIH0KKworICAgIHdoaWxlIChzaXplID4gYnVmZmVyX3NpemVfKSB7CisgICAgICAvLyBEYXRhIGV4Y2VlZHMgc3BhY2UgaW4gdGhlIGJ1ZmZlci4gIENvcHkgd2hhdCB3ZSBjYW4gYW5kIHJlcXVlc3QgYQorICAgICAgLy8gbmV3IGJ1ZmZlci4KKyAgICAgIG1lbWNweShidWZmZXJfLCBkYXRhLCBidWZmZXJfc2l6ZV8pOworICAgICAgZGF0YSArPSBidWZmZXJfc2l6ZV87CisgICAgICBzaXplIC09IGJ1ZmZlcl9zaXplXzsKKyAgICAgIHZvaWQqIHZvaWRfYnVmZmVyOworICAgICAgZmFpbGVkXyA9ICFvdXRwdXRfLT5OZXh0KCZ2b2lkX2J1ZmZlciwgJmJ1ZmZlcl9zaXplXyk7CisgICAgICBpZiAoZmFpbGVkXykgcmV0dXJuOworICAgICAgYnVmZmVyXyA9IHJlaW50ZXJwcmV0X2Nhc3Q8Y2hhcio+KHZvaWRfYnVmZmVyKTsKKyAgICB9CisKKyAgICAvLyBCdWZmZXIgaXMgYmlnIGVub3VnaCB0byByZWNlaXZlIHRoZSBkYXRhOyBjb3B5IGl0LgorICAgIG1lbWNweShidWZmZXJfLCBkYXRhLCBzaXplKTsKKyAgICBidWZmZXJfICs9IHNpemU7CisgICAgYnVmZmVyX3NpemVfIC09IHNpemU7CisgIH0KKworICBpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0qIGNvbnN0IG91dHB1dF87CisgIGNoYXIqIGJ1ZmZlcl87CisgIGludCBidWZmZXJfc2l6ZV87CisgIGJvb2wgYXRfc3RhcnRfb2ZfbGluZV87CisgIGJvb2wgZmFpbGVkXzsKKworICBzdHJpbmcgaW5kZW50XzsKKyAgaW50IGluaXRpYWxfaW5kZW50X2xldmVsXzsKK307CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitUZXh0Rm9ybWF0OjpGaW5kZXI6On5GaW5kZXIoKSB7Cit9CisKK1RleHRGb3JtYXQ6OlBhcnNlcjo6UGFyc2VyKCkKKyAgOiBlcnJvcl9jb2xsZWN0b3JfKE5VTEwpLAorICAgIGZpbmRlcl8oTlVMTCksCisgICAgcGFyc2VfaW5mb190cmVlXyhOVUxMKSwKKyAgICBhbGxvd19wYXJ0aWFsXyhmYWxzZSksCisgICAgYWxsb3dfY2FzZV9pbnNlbnNpdGl2ZV9maWVsZF8oZmFsc2UpLAorICAgIGFsbG93X3Vua25vd25fZmllbGRfKGZhbHNlKSwKKyAgICBhbGxvd191bmtub3duX2VudW1fKGZhbHNlKSwKKyAgICBhbGxvd19maWVsZF9udW1iZXJfKGZhbHNlKSwKKyAgICBhbGxvd19yZWxheGVkX3doaXRlc3BhY2VfKGZhbHNlKSwKKyAgICBhbGxvd19zaW5ndWxhcl9vdmVyd3JpdGVzXyhmYWxzZSkgeworfQorCitUZXh0Rm9ybWF0OjpQYXJzZXI6On5QYXJzZXIoKSB7fQorCitib29sIFRleHRGb3JtYXQ6OlBhcnNlcjo6UGFyc2UoaW86Olplcm9Db3B5SW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UqIG91dHB1dCkgeworICBvdXRwdXQtPkNsZWFyKCk7CisKKyAgUGFyc2VySW1wbDo6U2luZ3VsYXJPdmVyd3JpdGVQb2xpY3kgb3ZlcndyaXRlc19wb2xpY3kgPQorICAgICAgYWxsb3dfc2luZ3VsYXJfb3ZlcndyaXRlc18KKyAgICAgID8gUGFyc2VySW1wbDo6QUxMT1dfU0lOR1VMQVJfT1ZFUldSSVRFUworICAgICAgOiBQYXJzZXJJbXBsOjpGT1JCSURfU0lOR1VMQVJfT1ZFUldSSVRFUzsKKworICBQYXJzZXJJbXBsIHBhcnNlcihvdXRwdXQtPkdldERlc2NyaXB0b3IoKSwgaW5wdXQsIGVycm9yX2NvbGxlY3Rvcl8sCisgICAgICAgICAgICAgICAgICAgIGZpbmRlcl8sIHBhcnNlX2luZm9fdHJlZV8sCisgICAgICAgICAgICAgICAgICAgIG92ZXJ3cml0ZXNfcG9saWN5LAorICAgICAgICAgICAgICAgICAgICBhbGxvd19jYXNlX2luc2Vuc2l0aXZlX2ZpZWxkXywgYWxsb3dfdW5rbm93bl9maWVsZF8sCisgICAgICAgICAgICAgICAgICAgIGFsbG93X3Vua25vd25fZW51bV8sIGFsbG93X2ZpZWxkX251bWJlcl8sCisgICAgICAgICAgICAgICAgICAgIGFsbG93X3JlbGF4ZWRfd2hpdGVzcGFjZV8pOworICByZXR1cm4gTWVyZ2VVc2luZ0ltcGwoaW5wdXQsIG91dHB1dCwgJnBhcnNlcik7Cit9CisKK2Jvb2wgVGV4dEZvcm1hdDo6UGFyc2VyOjpQYXJzZUZyb21TdHJpbmcoY29uc3Qgc3RyaW5nJiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZSogb3V0cHV0KSB7CisgIGlvOjpBcnJheUlucHV0U3RyZWFtIGlucHV0X3N0cmVhbShpbnB1dC5kYXRhKCksIGlucHV0LnNpemUoKSk7CisgIHJldHVybiBQYXJzZSgmaW5wdXRfc3RyZWFtLCBvdXRwdXQpOworfQorCitib29sIFRleHRGb3JtYXQ6OlBhcnNlcjo6TWVyZ2UoaW86Olplcm9Db3B5SW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UqIG91dHB1dCkgeworICBQYXJzZXJJbXBsIHBhcnNlcihvdXRwdXQtPkdldERlc2NyaXB0b3IoKSwgaW5wdXQsIGVycm9yX2NvbGxlY3Rvcl8sCisgICAgICAgICAgICAgICAgICAgIGZpbmRlcl8sIHBhcnNlX2luZm9fdHJlZV8sCisgICAgICAgICAgICAgICAgICAgIFBhcnNlckltcGw6OkFMTE9XX1NJTkdVTEFSX09WRVJXUklURVMsCisgICAgICAgICAgICAgICAgICAgIGFsbG93X2Nhc2VfaW5zZW5zaXRpdmVfZmllbGRfLCBhbGxvd191bmtub3duX2ZpZWxkXywKKyAgICAgICAgICAgICAgICAgICAgYWxsb3dfdW5rbm93bl9lbnVtXywgYWxsb3dfZmllbGRfbnVtYmVyXywKKyAgICAgICAgICAgICAgICAgICAgYWxsb3dfcmVsYXhlZF93aGl0ZXNwYWNlXyk7CisgIHJldHVybiBNZXJnZVVzaW5nSW1wbChpbnB1dCwgb3V0cHV0LCAmcGFyc2VyKTsKK30KKworYm9vbCBUZXh0Rm9ybWF0OjpQYXJzZXI6Ok1lcmdlRnJvbVN0cmluZyhjb25zdCBzdHJpbmcmIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlKiBvdXRwdXQpIHsKKyAgaW86OkFycmF5SW5wdXRTdHJlYW0gaW5wdXRfc3RyZWFtKGlucHV0LmRhdGEoKSwgaW5wdXQuc2l6ZSgpKTsKKyAgcmV0dXJuIE1lcmdlKCZpbnB1dF9zdHJlYW0sIG91dHB1dCk7Cit9CisKK2Jvb2wgVGV4dEZvcm1hdDo6UGFyc2VyOjpNZXJnZVVzaW5nSW1wbChpbzo6WmVyb0NvcHlJbnB1dFN0cmVhbSogLyogaW5wdXQgKi8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZSogb3V0cHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBhcnNlckltcGwqIHBhcnNlcl9pbXBsKSB7CisgIGlmICghcGFyc2VyX2ltcGwtPlBhcnNlKG91dHB1dCkpIHJldHVybiBmYWxzZTsKKyAgaWYgKCFhbGxvd19wYXJ0aWFsXyAmJiAhb3V0cHV0LT5Jc0luaXRpYWxpemVkKCkpIHsKKyAgICB2ZWN0b3I8c3RyaW5nPiBtaXNzaW5nX2ZpZWxkczsKKyAgICBvdXRwdXQtPkZpbmRJbml0aWFsaXphdGlvbkVycm9ycygmbWlzc2luZ19maWVsZHMpOworICAgIHBhcnNlcl9pbXBsLT5SZXBvcnRFcnJvcigtMSwgMCwgIk1lc3NhZ2UgbWlzc2luZyByZXF1aXJlZCBmaWVsZHM6ICIgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEpvaW4obWlzc2luZ19maWVsZHMsICIsICIpKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgVGV4dEZvcm1hdDo6UGFyc2VyOjpQYXJzZUZpZWxkVmFsdWVGcm9tU3RyaW5nKAorICAgIGNvbnN0IHN0cmluZyYgaW5wdXQsCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICBNZXNzYWdlKiBvdXRwdXQpIHsKKyAgaW86OkFycmF5SW5wdXRTdHJlYW0gaW5wdXRfc3RyZWFtKGlucHV0LmRhdGEoKSwgaW5wdXQuc2l6ZSgpKTsKKyAgUGFyc2VySW1wbCBwYXJzZXIob3V0cHV0LT5HZXREZXNjcmlwdG9yKCksICZpbnB1dF9zdHJlYW0sIGVycm9yX2NvbGxlY3Rvcl8sCisgICAgICAgICAgICAgICAgICAgIGZpbmRlcl8sIHBhcnNlX2luZm9fdHJlZV8sCisgICAgICAgICAgICAgICAgICAgIFBhcnNlckltcGw6OkFMTE9XX1NJTkdVTEFSX09WRVJXUklURVMsCisgICAgICAgICAgICAgICAgICAgIGFsbG93X2Nhc2VfaW5zZW5zaXRpdmVfZmllbGRfLCBhbGxvd191bmtub3duX2ZpZWxkXywKKyAgICAgICAgICAgICAgICAgICAgYWxsb3dfdW5rbm93bl9lbnVtXywgYWxsb3dfZmllbGRfbnVtYmVyXywKKyAgICAgICAgICAgICAgICAgICAgYWxsb3dfcmVsYXhlZF93aGl0ZXNwYWNlXyk7CisgIHJldHVybiBwYXJzZXIuUGFyc2VGaWVsZChmaWVsZCwgb3V0cHV0KTsKK30KKworLyogc3RhdGljICovIGJvb2wgVGV4dEZvcm1hdDo6UGFyc2UoaW86Olplcm9Db3B5SW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZSogb3V0cHV0KSB7CisgIHJldHVybiBQYXJzZXIoKS5QYXJzZShpbnB1dCwgb3V0cHV0KTsKK30KKworLyogc3RhdGljICovIGJvb2wgVGV4dEZvcm1hdDo6TWVyZ2UoaW86Olplcm9Db3B5SW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZSogb3V0cHV0KSB7CisgIHJldHVybiBQYXJzZXIoKS5NZXJnZShpbnB1dCwgb3V0cHV0KTsKK30KKworLyogc3RhdGljICovIGJvb2wgVGV4dEZvcm1hdDo6UGFyc2VGcm9tU3RyaW5nKGNvbnN0IHN0cmluZyYgaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZSogb3V0cHV0KSB7CisgIHJldHVybiBQYXJzZXIoKS5QYXJzZUZyb21TdHJpbmcoaW5wdXQsIG91dHB1dCk7Cit9CisKKy8qIHN0YXRpYyAqLyBib29sIFRleHRGb3JtYXQ6Ok1lcmdlRnJvbVN0cmluZyhjb25zdCBzdHJpbmcmIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UqIG91dHB1dCkgeworICByZXR1cm4gUGFyc2VyKCkuTWVyZ2VGcm9tU3RyaW5nKGlucHV0LCBvdXRwdXQpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworLy8gVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gZm9yIEZpZWxkVmFsdWVQcmludGVyLiBUaGUgYmFzZSBjbGFzcyBqdXN0CisvLyBkb2VzIHNpbXBsZSBmb3JtYXR0aW5nLiBUaGF0IHdheSwgZGVyaXZpbmcgY2xhc3NlcyBjb3VsZCBkZWNpZGUgdG8gZmFsbGJhY2sKKy8vIHRvIHRoYXQgYmVoYXZpb3IuCitUZXh0Rm9ybWF0OjpGaWVsZFZhbHVlUHJpbnRlcjo6RmllbGRWYWx1ZVByaW50ZXIoKSB7fQorVGV4dEZvcm1hdDo6RmllbGRWYWx1ZVByaW50ZXI6On5GaWVsZFZhbHVlUHJpbnRlcigpIHt9CitzdHJpbmcgVGV4dEZvcm1hdDo6RmllbGRWYWx1ZVByaW50ZXI6OlByaW50Qm9vbChib29sIHZhbCkgY29uc3QgeworICByZXR1cm4gdmFsID8gInRydWUiIDogImZhbHNlIjsKK30KK3N0cmluZyBUZXh0Rm9ybWF0OjpGaWVsZFZhbHVlUHJpbnRlcjo6UHJpbnRJbnQzMihpbnQzMiB2YWwpIGNvbnN0IHsKKyAgcmV0dXJuIFNpbXBsZUl0b2EodmFsKTsKK30KK3N0cmluZyBUZXh0Rm9ybWF0OjpGaWVsZFZhbHVlUHJpbnRlcjo6UHJpbnRVSW50MzIodWludDMyIHZhbCkgY29uc3QgeworICByZXR1cm4gU2ltcGxlSXRvYSh2YWwpOworfQorc3RyaW5nIFRleHRGb3JtYXQ6OkZpZWxkVmFsdWVQcmludGVyOjpQcmludEludDY0KGludDY0IHZhbCkgY29uc3QgeworICByZXR1cm4gU2ltcGxlSXRvYSh2YWwpOworfQorc3RyaW5nIFRleHRGb3JtYXQ6OkZpZWxkVmFsdWVQcmludGVyOjpQcmludFVJbnQ2NCh1aW50NjQgdmFsKSBjb25zdCB7CisgIHJldHVybiBTaW1wbGVJdG9hKHZhbCk7Cit9CitzdHJpbmcgVGV4dEZvcm1hdDo6RmllbGRWYWx1ZVByaW50ZXI6OlByaW50RmxvYXQoZmxvYXQgdmFsKSBjb25zdCB7CisgIHJldHVybiBTaW1wbGVGdG9hKHZhbCk7Cit9CitzdHJpbmcgVGV4dEZvcm1hdDo6RmllbGRWYWx1ZVByaW50ZXI6OlByaW50RG91YmxlKGRvdWJsZSB2YWwpIGNvbnN0IHsKKyAgcmV0dXJuIFNpbXBsZUR0b2EodmFsKTsKK30KK3N0cmluZyBUZXh0Rm9ybWF0OjpGaWVsZFZhbHVlUHJpbnRlcjo6UHJpbnRTdHJpbmcoY29uc3Qgc3RyaW5nJiB2YWwpIGNvbnN0IHsKKyAgc3RyaW5nIHByaW50ZWQoIlwiIik7CisgIENFc2NhcGVBbmRBcHBlbmQodmFsLCAmcHJpbnRlZCk7CisgIHByaW50ZWQucHVzaF9iYWNrKCdcIicpOworICByZXR1cm4gcHJpbnRlZDsKK30KK3N0cmluZyBUZXh0Rm9ybWF0OjpGaWVsZFZhbHVlUHJpbnRlcjo6UHJpbnRCeXRlcyhjb25zdCBzdHJpbmcmIHZhbCkgY29uc3QgeworICByZXR1cm4gUHJpbnRTdHJpbmcodmFsKTsKK30KK3N0cmluZyBUZXh0Rm9ybWF0OjpGaWVsZFZhbHVlUHJpbnRlcjo6UHJpbnRFbnVtKGludDMyIHZhbCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgbmFtZSkgY29uc3QgeworICByZXR1cm4gbmFtZTsKK30KK3N0cmluZyBUZXh0Rm9ybWF0OjpGaWVsZFZhbHVlUHJpbnRlcjo6UHJpbnRGaWVsZE5hbWUoCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uLAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIGNvbnN0IHsKKyAgaWYgKGZpZWxkLT5pc19leHRlbnNpb24oKSkgeworICAgIC8vIFdlIHNwZWNpYWwtY2FzZSBNZXNzYWdlU2V0IGVsZW1lbnRzIGZvciBjb21wYXRpYmlsaXR5IHdpdGggcHJvdG8xLgorICAgIGlmIChmaWVsZC0+Y29udGFpbmluZ190eXBlKCktPm9wdGlvbnMoKS5tZXNzYWdlX3NldF93aXJlX2Zvcm1hdCgpCisgICAgICAgICYmIGZpZWxkLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX01FU1NBR0UKKyAgICAgICAgJiYgZmllbGQtPmlzX29wdGlvbmFsKCkKKyAgICAgICAgJiYgZmllbGQtPmV4dGVuc2lvbl9zY29wZSgpID09IGZpZWxkLT5tZXNzYWdlX3R5cGUoKSkgeworICAgICAgcmV0dXJuIFN0ckNhdCgiWyIsIGZpZWxkLT5tZXNzYWdlX3R5cGUoKS0+ZnVsbF9uYW1lKCksICJdIik7CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiBTdHJDYXQoIlsiLCBmaWVsZC0+ZnVsbF9uYW1lKCksICJdIik7CisgICAgfQorICB9IGVsc2UgaWYgKGZpZWxkLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX0dST1VQKSB7CisgICAgLy8gR3JvdXBzIG11c3QgYmUgc2VyaWFsaXplZCB3aXRoIHRoZWlyIG9yaWdpbmFsIGNhcGl0YWxpemF0aW9uLgorICAgIHJldHVybiBmaWVsZC0+bWVzc2FnZV90eXBlKCktPm5hbWUoKTsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gZmllbGQtPm5hbWUoKTsKKyAgfQorfQorc3RyaW5nIFRleHRGb3JtYXQ6OkZpZWxkVmFsdWVQcmludGVyOjpQcmludE1lc3NhZ2VTdGFydCgKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgIGludCBmaWVsZF9pbmRleCwKKyAgICBpbnQgZmllbGRfY291bnQsCisgICAgYm9vbCBzaW5nbGVfbGluZV9tb2RlKSBjb25zdCB7CisgIHJldHVybiBzaW5nbGVfbGluZV9tb2RlID8gIiB7ICIgOiAiIHtcbiI7Cit9CitzdHJpbmcgVGV4dEZvcm1hdDo6RmllbGRWYWx1ZVByaW50ZXI6OlByaW50TWVzc2FnZUVuZCgKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgIGludCBmaWVsZF9pbmRleCwKKyAgICBpbnQgZmllbGRfY291bnQsCisgICAgYm9vbCBzaW5nbGVfbGluZV9tb2RlKSBjb25zdCB7CisgIHJldHVybiBzaW5nbGVfbGluZV9tb2RlID8gIn0gIiA6ICJ9XG4iOworfQorCituYW1lc3BhY2UgeworLy8gT3VyIG93biBzcGVjaWFsaXphdGlvbjogZm9yIFVURjggZXNjYXBlZCBzdHJpbmdzLgorY2xhc3MgRmllbGRWYWx1ZVByaW50ZXJVdGY4RXNjYXBpbmcgOiBwdWJsaWMgVGV4dEZvcm1hdDo6RmllbGRWYWx1ZVByaW50ZXIgeworIHB1YmxpYzoKKyAgdmlydHVhbCBzdHJpbmcgUHJpbnRTdHJpbmcoY29uc3Qgc3RyaW5nJiB2YWwpIGNvbnN0IHsKKyAgICByZXR1cm4gU3RyQ2F0KCJcIiIsIHN0cmluZ3M6OlV0ZjhTYWZlQ0VzY2FwZSh2YWwpLCAiXCIiKTsKKyAgfQorICB2aXJ0dWFsIHN0cmluZyBQcmludEJ5dGVzKGNvbnN0IHN0cmluZyYgdmFsKSBjb25zdCB7CisgICAgcmV0dXJuIFRleHRGb3JtYXQ6OkZpZWxkVmFsdWVQcmludGVyOjpQcmludFN0cmluZyh2YWwpOworICB9Cit9OworCit9ICAvLyBuYW1lc3BhY2UKKworVGV4dEZvcm1hdDo6UHJpbnRlcjo6UHJpbnRlcigpCisgIDogaW5pdGlhbF9pbmRlbnRfbGV2ZWxfKDApLAorICAgIHNpbmdsZV9saW5lX21vZGVfKGZhbHNlKSwKKyAgICB1c2VfZmllbGRfbnVtYmVyXyhmYWxzZSksCisgICAgdXNlX3Nob3J0X3JlcGVhdGVkX3ByaW1pdGl2ZXNfKGZhbHNlKSwKKyAgICBoaWRlX3Vua25vd25fZmllbGRzXyhmYWxzZSksCisgICAgcHJpbnRfbWVzc2FnZV9maWVsZHNfaW5faW5kZXhfb3JkZXJfKGZhbHNlKSwKKyAgICBleHBhbmRfYW55XyhmYWxzZSksCisgICAgdHJ1bmNhdGVfc3RyaW5nX2ZpZWxkX2xvbmdlcl90aGFuXygwTEwpIHsKKyAgU2V0VXNlVXRmOFN0cmluZ0VzY2FwaW5nKGZhbHNlKTsKK30KKworVGV4dEZvcm1hdDo6UHJpbnRlcjo6flByaW50ZXIoKSB7CisgIFNUTERlbGV0ZVZhbHVlcygmY3VzdG9tX3ByaW50ZXJzXyk7Cit9CisKK3ZvaWQgVGV4dEZvcm1hdDo6UHJpbnRlcjo6U2V0VXNlVXRmOFN0cmluZ0VzY2FwaW5nKGJvb2wgYXNfdXRmOCkgeworICBTZXREZWZhdWx0RmllbGRWYWx1ZVByaW50ZXIoYXNfdXRmOAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBuZXcgRmllbGRWYWx1ZVByaW50ZXJVdGY4RXNjYXBpbmcoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBuZXcgRmllbGRWYWx1ZVByaW50ZXIoKSk7Cit9CisKK3ZvaWQgVGV4dEZvcm1hdDo6UHJpbnRlcjo6U2V0RGVmYXVsdEZpZWxkVmFsdWVQcmludGVyKAorICAgIGNvbnN0IEZpZWxkVmFsdWVQcmludGVyKiBwcmludGVyKSB7CisgIGRlZmF1bHRfZmllbGRfdmFsdWVfcHJpbnRlcl8ucmVzZXQocHJpbnRlcik7Cit9CisKK2Jvb2wgVGV4dEZvcm1hdDo6UHJpbnRlcjo6UmVnaXN0ZXJGaWVsZFZhbHVlUHJpbnRlcigKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgIGNvbnN0IEZpZWxkVmFsdWVQcmludGVyKiBwcmludGVyKSB7CisgIHJldHVybiBmaWVsZCAhPSBOVUxMICYmIHByaW50ZXIgIT0gTlVMTCAmJgorICAgICAgICAgY3VzdG9tX3ByaW50ZXJzXy5pbnNlcnQoc3RkOjptYWtlX3BhaXIoZmllbGQsIHByaW50ZXIpKS5zZWNvbmQ7Cit9CisKK2Jvb2wgVGV4dEZvcm1hdDo6UHJpbnRlcjo6UHJpbnRUb1N0cmluZyhjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyogb3V0cHV0KSBjb25zdCB7CisgIEdPT0dMRV9EQ0hFQ0sob3V0cHV0KSA8PCAib3V0cHV0IHNwZWNpZmllZCBpcyBOVUxMIjsKKworICBvdXRwdXQtPmNsZWFyKCk7CisgIGlvOjpTdHJpbmdPdXRwdXRTdHJlYW0gb3V0cHV0X3N0cmVhbShvdXRwdXQpOworCisgIHJldHVybiBQcmludChtZXNzYWdlLCAmb3V0cHV0X3N0cmVhbSk7Cit9CisKK2Jvb2wgVGV4dEZvcm1hdDo6UHJpbnRlcjo6UHJpbnRVbmtub3duRmllbGRzVG9TdHJpbmcoCisgICAgY29uc3QgVW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcywKKyAgICBzdHJpbmcqIG91dHB1dCkgY29uc3QgeworICBHT09HTEVfRENIRUNLKG91dHB1dCkgPDwgIm91dHB1dCBzcGVjaWZpZWQgaXMgTlVMTCI7CisKKyAgb3V0cHV0LT5jbGVhcigpOworICBpbzo6U3RyaW5nT3V0cHV0U3RyZWFtIG91dHB1dF9zdHJlYW0ob3V0cHV0KTsKKyAgcmV0dXJuIFByaW50VW5rbm93bkZpZWxkcyh1bmtub3duX2ZpZWxkcywgJm91dHB1dF9zdHJlYW0pOworfQorCitib29sIFRleHRGb3JtYXQ6OlByaW50ZXI6OlByaW50KGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpaZXJvQ29weU91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIFRleHRHZW5lcmF0b3IgZ2VuZXJhdG9yKG91dHB1dCwgaW5pdGlhbF9pbmRlbnRfbGV2ZWxfKTsKKworICBQcmludChtZXNzYWdlLCBnZW5lcmF0b3IpOworCisgIC8vIE91dHB1dCBmYWxzZSBpZiB0aGUgZ2VuZXJhdG9yIGZhaWxlZCBpbnRlcm5hbGx5LgorICByZXR1cm4gIWdlbmVyYXRvci5mYWlsZWQoKTsKK30KKworYm9vbCBUZXh0Rm9ybWF0OjpQcmludGVyOjpQcmludFVua25vd25GaWVsZHMoCisgICAgY29uc3QgVW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcywKKyAgICBpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3QgeworICBUZXh0R2VuZXJhdG9yIGdlbmVyYXRvcihvdXRwdXQsIGluaXRpYWxfaW5kZW50X2xldmVsXyk7CisKKyAgUHJpbnRVbmtub3duRmllbGRzKHVua25vd25fZmllbGRzLCBnZW5lcmF0b3IpOworCisgIC8vIE91dHB1dCBmYWxzZSBpZiB0aGUgZ2VuZXJhdG9yIGZhaWxlZCBpbnRlcm5hbGx5LgorICByZXR1cm4gIWdlbmVyYXRvci5mYWlsZWQoKTsKK30KKworbmFtZXNwYWNlIHsKKy8vIENvbXBhcmlzb24gZnVuY3RvciBmb3Igc29ydGluZyBGaWVsZERlc2NyaXB0b3JzIGJ5IGZpZWxkIGluZGV4Lgorc3RydWN0IEZpZWxkSW5kZXhTb3J0ZXIgeworICBib29sIG9wZXJhdG9yKCkoY29uc3QgRmllbGREZXNjcmlwdG9yKiBsZWZ0LAorICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiByaWdodCkgY29uc3QgeworICAgIHJldHVybiBsZWZ0LT5pbmRleCgpIDwgcmlnaHQtPmluZGV4KCk7CisgIH0KK307CisKK30gIC8vIG5hbWVzcGFjZQorCitib29sIFRleHRGb3JtYXQ6OlByaW50ZXI6OlByaW50QW55KGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRleHRHZW5lcmF0b3ImIGdlbmVyYXRvcikgY29uc3QgeworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHR5cGVfdXJsX2ZpZWxkOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHZhbHVlX2ZpZWxkOworICBpZiAoIWludGVybmFsOjpHZXRBbnlGaWVsZERlc2NyaXB0b3JzKG1lc3NhZ2UsICZ0eXBlX3VybF9maWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmdmFsdWVfZmllbGQpKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpOworCisgIC8vIEV4dHJhY3QgdGhlIGZ1bGwgdHlwZSBuYW1lIGZyb20gdGhlIHR5cGVfdXJsIGZpZWxkLgorICBjb25zdCBzdHJpbmcmIHR5cGVfdXJsID0gcmVmbGVjdGlvbi0+R2V0U3RyaW5nKG1lc3NhZ2UsIHR5cGVfdXJsX2ZpZWxkKTsKKyAgc3RyaW5nIGZ1bGxfdHlwZV9uYW1lOworICBpZiAoIWludGVybmFsOjpQYXJzZUFueVR5cGVVcmwodHlwZV91cmwsICZmdWxsX3R5cGVfbmFtZSkpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLyBQcmludCB0aGUgInZhbHVlIiBpbiB0ZXh0LgorICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiB2YWx1ZV9kZXNjcmlwdG9yID0KKyAgICAgIG1lc3NhZ2UuR2V0RGVzY3JpcHRvcigpLT5maWxlKCktPnBvb2woKS0+RmluZE1lc3NhZ2VUeXBlQnlOYW1lKAorICAgICAgICAgIGZ1bGxfdHlwZV9uYW1lKTsKKyAgaWYgKHZhbHVlX2Rlc2NyaXB0b3IgPT0gTlVMTCkgeworICAgIEdPT0dMRV9MT0coV0FSTklORykgPDwgIlByb3RvIHR5cGUgIiA8PCB0eXBlX3VybCA8PCAiIG5vdCBmb3VuZCI7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIER5bmFtaWNNZXNzYWdlRmFjdG9yeSBmYWN0b3J5OworICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPGdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2U+IHZhbHVlX21lc3NhZ2UoCisgICAgICBmYWN0b3J5LkdldFByb3RvdHlwZSh2YWx1ZV9kZXNjcmlwdG9yKS0+TmV3KCkpOworICBzdHJpbmcgc2VyaWFsaXplZF92YWx1ZSA9IHJlZmxlY3Rpb24tPkdldFN0cmluZyhtZXNzYWdlLCB2YWx1ZV9maWVsZCk7CisgIGlmICghdmFsdWVfbWVzc2FnZS0+UGFyc2VGcm9tU3RyaW5nKHNlcmlhbGl6ZWRfdmFsdWUpKSB7CisgICAgR09PR0xFX0xPRyhXQVJOSU5HKSA8PCB0eXBlX3VybCA8PCAiOiBmYWlsZWQgdG8gcGFyc2UgY29udGVudHMiOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICBnZW5lcmF0b3IuUHJpbnQoU3RyQ2F0KCJbIiwgdHlwZV91cmwsICJdIikpOworICBjb25zdCBGaWVsZFZhbHVlUHJpbnRlciogcHJpbnRlciA9IEZpbmRXaXRoRGVmYXVsdCgKKyAgICAgIGN1c3RvbV9wcmludGVyc18sIHZhbHVlX2ZpZWxkLCBkZWZhdWx0X2ZpZWxkX3ZhbHVlX3ByaW50ZXJfLmdldCgpKTsKKyAgZ2VuZXJhdG9yLlByaW50KAorICAgICAgcHJpbnRlci0+UHJpbnRNZXNzYWdlU3RhcnQobWVzc2FnZSwgLTEsIDAsIHNpbmdsZV9saW5lX21vZGVfKSk7CisgIGdlbmVyYXRvci5JbmRlbnQoKTsKKyAgUHJpbnQoKnZhbHVlX21lc3NhZ2UsIGdlbmVyYXRvcik7CisgIGdlbmVyYXRvci5PdXRkZW50KCk7CisgIGdlbmVyYXRvci5QcmludChwcmludGVyLT5QcmludE1lc3NhZ2VFbmQobWVzc2FnZSwgLTEsIDAsIHNpbmdsZV9saW5lX21vZGVfKSk7CisgIHJldHVybiB0cnVlOworfQorCit2b2lkIFRleHRGb3JtYXQ6OlByaW50ZXI6OlByaW50KGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRleHRHZW5lcmF0b3ImIGdlbmVyYXRvcikgY29uc3QgeworICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yID0gbWVzc2FnZS5HZXREZXNjcmlwdG9yKCk7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKTsKKyAgaWYgKGRlc2NyaXB0b3ItPmZ1bGxfbmFtZSgpID09IGludGVybmFsOjprQW55RnVsbFR5cGVOYW1lICYmIGV4cGFuZF9hbnlfICYmCisgICAgICBQcmludEFueShtZXNzYWdlLCBnZW5lcmF0b3IpKSB7CisgICAgcmV0dXJuOworICB9CisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBmaWVsZHM7CisgIHJlZmxlY3Rpb24tPkxpc3RGaWVsZHMobWVzc2FnZSwgJmZpZWxkcyk7CisgIGlmIChwcmludF9tZXNzYWdlX2ZpZWxkc19pbl9pbmRleF9vcmRlcl8pIHsKKyAgICBzdGQ6OnNvcnQoZmllbGRzLmJlZ2luKCksIGZpZWxkcy5lbmQoKSwgRmllbGRJbmRleFNvcnRlcigpKTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkcy5zaXplKCk7IGkrKykgeworICAgIFByaW50RmllbGQobWVzc2FnZSwgcmVmbGVjdGlvbiwgZmllbGRzW2ldLCBnZW5lcmF0b3IpOworICB9CisgIGlmICghaGlkZV91bmtub3duX2ZpZWxkc18pIHsKKyAgICBQcmludFVua25vd25GaWVsZHMocmVmbGVjdGlvbi0+R2V0VW5rbm93bkZpZWxkcyhtZXNzYWdlKSwgZ2VuZXJhdG9yKTsKKyAgfQorfQorCit2b2lkIFRleHRGb3JtYXQ6OlByaW50ZXI6OlByaW50RmllbGRWYWx1ZVRvU3RyaW5nKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICBpbnQgaW5kZXgsCisgICAgc3RyaW5nKiBvdXRwdXQpIGNvbnN0IHsKKworICBHT09HTEVfRENIRUNLKG91dHB1dCkgPDwgIm91dHB1dCBzcGVjaWZpZWQgaXMgTlVMTCI7CisKKyAgb3V0cHV0LT5jbGVhcigpOworICBpbzo6U3RyaW5nT3V0cHV0U3RyZWFtIG91dHB1dF9zdHJlYW0ob3V0cHV0KTsKKyAgVGV4dEdlbmVyYXRvciBnZW5lcmF0b3IoJm91dHB1dF9zdHJlYW0sIGluaXRpYWxfaW5kZW50X2xldmVsXyk7CisKKyAgUHJpbnRGaWVsZFZhbHVlKG1lc3NhZ2UsIG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpLCBmaWVsZCwgaW5kZXgsIGdlbmVyYXRvcik7Cit9CisKK2NsYXNzIE1hcEVudHJ5TWVzc2FnZUNvbXBhcmF0b3IgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgTWFwRW50cnlNZXNzYWdlQ29tcGFyYXRvcihjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKQorICAgICAgOiBmaWVsZF8oZGVzY3JpcHRvci0+ZmllbGQoMCkpIHt9CisKKyAgYm9vbCBvcGVyYXRvcigpKGNvbnN0IE1lc3NhZ2UqIGEsIGNvbnN0IE1lc3NhZ2UqIGIpIHsKKyAgICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gYS0+R2V0UmVmbGVjdGlvbigpOworICAgIHN3aXRjaCAoZmllbGRfLT5jcHBfdHlwZSgpKSB7CisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9CT09MOiB7CisgICAgICAgICAgYm9vbCBmaXJzdCA9IHJlZmxlY3Rpb24tPkdldEJvb2woKmEsIGZpZWxkXyk7CisgICAgICAgICAgYm9vbCBzZWNvbmQgPSByZWZsZWN0aW9uLT5HZXRCb29sKCpiLCBmaWVsZF8pOworICAgICAgICAgIHJldHVybiBmaXJzdCA8IHNlY29uZDsKKyAgICAgIH0KKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0lOVDMyOiB7CisgICAgICAgICAgaW50MzIgZmlyc3QgPSByZWZsZWN0aW9uLT5HZXRJbnQzMigqYSwgZmllbGRfKTsKKyAgICAgICAgICBpbnQzMiBzZWNvbmQgPSByZWZsZWN0aW9uLT5HZXRJbnQzMigqYiwgZmllbGRfKTsKKyAgICAgICAgICByZXR1cm4gZmlyc3QgPCBzZWNvbmQ7CisgICAgICB9CisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9JTlQ2NDogeworICAgICAgICAgIGludDY0IGZpcnN0ID0gcmVmbGVjdGlvbi0+R2V0SW50NjQoKmEsIGZpZWxkXyk7CisgICAgICAgICAgaW50NjQgc2Vjb25kID0gcmVmbGVjdGlvbi0+R2V0SW50NjQoKmIsIGZpZWxkXyk7CisgICAgICAgICAgcmV0dXJuIGZpcnN0IDwgc2Vjb25kOworICAgICAgfQorICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDMyOiB7CisgICAgICAgICAgdWludDMyIGZpcnN0ID0gcmVmbGVjdGlvbi0+R2V0VUludDMyKCphLCBmaWVsZF8pOworICAgICAgICAgIHVpbnQzMiBzZWNvbmQgPSByZWZsZWN0aW9uLT5HZXRVSW50MzIoKmIsIGZpZWxkXyk7CisgICAgICAgICAgcmV0dXJuIGZpcnN0IDwgc2Vjb25kOworICAgICAgfQorICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDY0OiB7CisgICAgICAgICAgdWludDY0IGZpcnN0ID0gcmVmbGVjdGlvbi0+R2V0VUludDY0KCphLCBmaWVsZF8pOworICAgICAgICAgIHVpbnQ2NCBzZWNvbmQgPSByZWZsZWN0aW9uLT5HZXRVSW50NjQoKmIsIGZpZWxkXyk7CisgICAgICAgICAgcmV0dXJuIGZpcnN0IDwgc2Vjb25kOworICAgICAgfQorICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HOiB7CisgICAgICAgICAgc3RyaW5nIGZpcnN0ID0gcmVmbGVjdGlvbi0+R2V0U3RyaW5nKCphLCBmaWVsZF8pOworICAgICAgICAgIHN0cmluZyBzZWNvbmQgPSByZWZsZWN0aW9uLT5HZXRTdHJpbmcoKmIsIGZpZWxkXyk7CisgICAgICAgICAgcmV0dXJuIGZpcnN0IDwgc2Vjb25kOworICAgICAgfQorICAgICAgZGVmYXVsdDoKKyAgICAgICAgR09PR0xFX0xPRyhERkFUQUwpIDw8ICJJbnZhbGlkIGtleSBmb3IgbWFwIGZpZWxkLiI7CisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgfQorCisgcHJpdmF0ZToKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZF87Cit9OworCit2b2lkIFRleHRGb3JtYXQ6OlByaW50ZXI6OlByaW50RmllbGQoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGV4dEdlbmVyYXRvciYgZ2VuZXJhdG9yKSBjb25zdCB7CisgIGlmICh1c2Vfc2hvcnRfcmVwZWF0ZWRfcHJpbWl0aXZlc18gJiYKKyAgICAgIGZpZWxkLT5pc19yZXBlYXRlZCgpICYmCisgICAgICBmaWVsZC0+Y3BwX3R5cGUoKSAhPSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HICYmCisgICAgICBmaWVsZC0+Y3BwX3R5cGUoKSAhPSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSkgeworICAgIFByaW50U2hvcnRSZXBlYXRlZEZpZWxkKG1lc3NhZ2UsIHJlZmxlY3Rpb24sIGZpZWxkLCBnZW5lcmF0b3IpOworICAgIHJldHVybjsKKyAgfQorCisgIGludCBjb3VudCA9IDA7CisKKyAgaWYgKGZpZWxkLT5pc19yZXBlYXRlZCgpKSB7CisgICAgY291bnQgPSByZWZsZWN0aW9uLT5GaWVsZFNpemUobWVzc2FnZSwgZmllbGQpOworICB9IGVsc2UgaWYgKHJlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIGZpZWxkKSkgeworICAgIGNvdW50ID0gMTsKKyAgfQorCisgIHN0ZDo6dmVjdG9yPGNvbnN0IE1lc3NhZ2UqPiBzb3J0ZWRfbWFwX2ZpZWxkOworICBpZiAoZmllbGQtPmlzX21hcCgpKSB7CisgICAgY29uc3QgUmVwZWF0ZWRQdHJGaWVsZDxNZXNzYWdlPiYgbWFwX2ZpZWxkID0KKyAgICAgICAgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRQdHJGaWVsZDxNZXNzYWdlPihtZXNzYWdlLCBmaWVsZCk7CisgICAgZm9yIChSZXBlYXRlZFB0ckZpZWxkPE1lc3NhZ2U+Ojpjb25zdF9wb2ludGVyX2l0ZXJhdG9yIGl0ID0KKyAgICAgICAgICAgICBtYXBfZmllbGQucG9pbnRlcl9iZWdpbigpOworICAgICAgICAgaXQgIT0gbWFwX2ZpZWxkLnBvaW50ZXJfZW5kKCk7ICsraXQpIHsKKyAgICAgIHNvcnRlZF9tYXBfZmllbGQucHVzaF9iYWNrKCppdCk7CisgICAgfQorCisgICAgTWFwRW50cnlNZXNzYWdlQ29tcGFyYXRvciBjb21wYXJhdG9yKGZpZWxkLT5tZXNzYWdlX3R5cGUoKSk7CisgICAgc3RkOjpzdGFibGVfc29ydChzb3J0ZWRfbWFwX2ZpZWxkLmJlZ2luKCksIHNvcnRlZF9tYXBfZmllbGQuZW5kKCksCisgICAgICAgICAgICAgICAgICAgICBjb21wYXJhdG9yKTsKKyAgfQorCisgIGZvciAoaW50IGogPSAwOyBqIDwgY291bnQ7ICsraikgeworICAgIGNvbnN0IGludCBmaWVsZF9pbmRleCA9IGZpZWxkLT5pc19yZXBlYXRlZCgpID8gaiA6IC0xOworCisgICAgUHJpbnRGaWVsZE5hbWUobWVzc2FnZSwgcmVmbGVjdGlvbiwgZmllbGQsIGdlbmVyYXRvcik7CisKKyAgICBpZiAoZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UpIHsKKyAgICAgIGNvbnN0IEZpZWxkVmFsdWVQcmludGVyKiBwcmludGVyID0gRmluZFdpdGhEZWZhdWx0KAorICAgICAgICAgIGN1c3RvbV9wcmludGVyc18sIGZpZWxkLCBkZWZhdWx0X2ZpZWxkX3ZhbHVlX3ByaW50ZXJfLmdldCgpKTsKKyAgICAgIGNvbnN0IE1lc3NhZ2UmIHN1Yl9tZXNzYWdlID0KKyAgICAgICAgICBmaWVsZC0+aXNfcmVwZWF0ZWQoKQorICAgICAgICAgICAgICA/IChmaWVsZC0+aXNfbWFwKCkKKyAgICAgICAgICAgICAgICAgICAgID8gKnNvcnRlZF9tYXBfZmllbGRbal0KKyAgICAgICAgICAgICAgICAgICAgIDogcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRNZXNzYWdlKG1lc3NhZ2UsIGZpZWxkLCBqKSkKKyAgICAgICAgICAgICAgOiByZWZsZWN0aW9uLT5HZXRNZXNzYWdlKG1lc3NhZ2UsIGZpZWxkKTsKKyAgICAgIGdlbmVyYXRvci5QcmludCgKKyAgICAgICAgICBwcmludGVyLT5QcmludE1lc3NhZ2VTdGFydCgKKyAgICAgICAgICAgICAgc3ViX21lc3NhZ2UsIGZpZWxkX2luZGV4LCBjb3VudCwgc2luZ2xlX2xpbmVfbW9kZV8pKTsKKyAgICAgIGdlbmVyYXRvci5JbmRlbnQoKTsKKyAgICAgIFByaW50KHN1Yl9tZXNzYWdlLCBnZW5lcmF0b3IpOworICAgICAgZ2VuZXJhdG9yLk91dGRlbnQoKTsKKyAgICAgIGdlbmVyYXRvci5QcmludCgKKyAgICAgICAgICBwcmludGVyLT5QcmludE1lc3NhZ2VFbmQoCisgICAgICAgICAgICAgIHN1Yl9tZXNzYWdlLCBmaWVsZF9pbmRleCwgY291bnQsIHNpbmdsZV9saW5lX21vZGVfKSk7CisgICAgfSBlbHNlIHsKKyAgICAgIGdlbmVyYXRvci5QcmludCgiOiAiKTsKKyAgICAgIC8vIFdyaXRlIHRoZSBmaWVsZCB2YWx1ZS4KKyAgICAgIFByaW50RmllbGRWYWx1ZShtZXNzYWdlLCByZWZsZWN0aW9uLCBmaWVsZCwgZmllbGRfaW5kZXgsIGdlbmVyYXRvcik7CisgICAgICBpZiAoc2luZ2xlX2xpbmVfbW9kZV8pIHsKKyAgICAgICAgZ2VuZXJhdG9yLlByaW50KCIgIik7CisgICAgICB9IGVsc2UgeworICAgICAgICBnZW5lcmF0b3IuUHJpbnQoIlxuIik7CisgICAgICB9CisgICAgfQorICB9Cit9CisKK3ZvaWQgVGV4dEZvcm1hdDo6UHJpbnRlcjo6UHJpbnRTaG9ydFJlcGVhdGVkRmllbGQoCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uLAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgVGV4dEdlbmVyYXRvciYgZ2VuZXJhdG9yKSBjb25zdCB7CisgIC8vIFByaW50IHByaW1pdGl2ZSByZXBlYXRlZCBmaWVsZCBpbiBzaG9ydCBmb3JtLgorICBQcmludEZpZWxkTmFtZShtZXNzYWdlLCByZWZsZWN0aW9uLCBmaWVsZCwgZ2VuZXJhdG9yKTsKKworICBpbnQgc2l6ZSA9IHJlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBmaWVsZCk7CisgIGdlbmVyYXRvci5QcmludCgiOiBbIik7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CisgICAgaWYgKGkgPiAwKSBnZW5lcmF0b3IuUHJpbnQoIiwgIik7CisgICAgUHJpbnRGaWVsZFZhbHVlKG1lc3NhZ2UsIHJlZmxlY3Rpb24sIGZpZWxkLCBpLCBnZW5lcmF0b3IpOworICB9CisgIGlmIChzaW5nbGVfbGluZV9tb2RlXykgeworICAgIGdlbmVyYXRvci5QcmludCgiXSAiKTsKKyAgfSBlbHNlIHsKKyAgICBnZW5lcmF0b3IuUHJpbnQoIl1cbiIpOworICB9Cit9CisKK3ZvaWQgVGV4dEZvcm1hdDo6UHJpbnRlcjo6UHJpbnRGaWVsZE5hbWUoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGV4dEdlbmVyYXRvciYgZ2VuZXJhdG9yKSBjb25zdCB7CisgIC8vIGlmIHVzZV9maWVsZF9udW1iZXJfIGlzIHRydWUsIHByaW50cyBmaWVsZCBudW1iZXIgaW5zdGVhZAorICAvLyBvZiBmaWVsZCBuYW1lLgorICBpZiAodXNlX2ZpZWxkX251bWJlcl8pIHsKKyAgICBnZW5lcmF0b3IuUHJpbnQoU2ltcGxlSXRvYShmaWVsZC0+bnVtYmVyKCkpKTsKKyAgICByZXR1cm47CisgIH0KKworICBjb25zdCBGaWVsZFZhbHVlUHJpbnRlciogcHJpbnRlciA9IEZpbmRXaXRoRGVmYXVsdCgKKyAgICAgIGN1c3RvbV9wcmludGVyc18sIGZpZWxkLCBkZWZhdWx0X2ZpZWxkX3ZhbHVlX3ByaW50ZXJfLmdldCgpKTsKKyAgZ2VuZXJhdG9yLlByaW50KHByaW50ZXItPlByaW50RmllbGROYW1lKG1lc3NhZ2UsIHJlZmxlY3Rpb24sIGZpZWxkKSk7Cit9CisKK3ZvaWQgVGV4dEZvcm1hdDo6UHJpbnRlcjo6UHJpbnRGaWVsZFZhbHVlKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiwKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgIGludCBpbmRleCwKKyAgICBUZXh0R2VuZXJhdG9yJiBnZW5lcmF0b3IpIGNvbnN0IHsKKyAgR09PR0xFX0RDSEVDSyhmaWVsZC0+aXNfcmVwZWF0ZWQoKSB8fCAoaW5kZXggPT0gLTEpKQorICAgICAgPDwgIkluZGV4IG11c3QgYmUgLTEgZm9yIG5vbi1yZXBlYXRlZCBmaWVsZHMiOworCisgIGNvbnN0IEZpZWxkVmFsdWVQcmludGVyKiBwcmludGVyCisgICAgICA9IEZpbmRXaXRoRGVmYXVsdChjdXN0b21fcHJpbnRlcnNfLCBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRfZmllbGRfdmFsdWVfcHJpbnRlcl8uZ2V0KCkpOworCisgIHN3aXRjaCAoZmllbGQtPmNwcF90eXBlKCkpIHsKKyNkZWZpbmUgT1VUUFVUX0ZJRUxEKENQUFRZUEUsIE1FVEhPRCkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV8jI0NQUFRZUEU6ICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIGdlbmVyYXRvci5QcmludChwcmludGVyLT5QcmludCMjTUVUSE9EKGZpZWxkLT5pc19yZXBlYXRlZCgpICAgICAgIFwKKyAgICAgICAgICAgICAgID8gcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWQjI01FVEhPRChtZXNzYWdlLCBmaWVsZCwgaW5kZXgpIFwKKyAgICAgICAgICAgICAgIDogcmVmbGVjdGlvbi0+R2V0IyNNRVRIT0QobWVzc2FnZSwgZmllbGQpKSk7ICAgICAgICAgICAgIFwKKyAgICAgICAgYnJlYWsKKworICAgIE9VVFBVVF9GSUVMRCggSU5UMzIsICBJbnQzMik7CisgICAgT1VUUFVUX0ZJRUxEKCBJTlQ2NCwgIEludDY0KTsKKyAgICBPVVRQVVRfRklFTEQoVUlOVDMyLCBVSW50MzIpOworICAgIE9VVFBVVF9GSUVMRChVSU5UNjQsIFVJbnQ2NCk7CisgICAgT1VUUFVUX0ZJRUxEKCBGTE9BVCwgIEZsb2F0KTsKKyAgICBPVVRQVVRfRklFTEQoRE9VQkxFLCBEb3VibGUpOworICAgIE9VVFBVVF9GSUVMRCggIEJPT0wsICAgQm9vbCk7CisjdW5kZWYgT1VUUFVUX0ZJRUxECisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9TVFJJTkc6IHsKKyAgICAgIHN0cmluZyBzY3JhdGNoOworICAgICAgY29uc3Qgc3RyaW5nJiB2YWx1ZSA9IGZpZWxkLT5pc19yZXBlYXRlZCgpCisgICAgICAgICAgPyByZWZsZWN0aW9uLT5HZXRSZXBlYXRlZFN0cmluZ1JlZmVyZW5jZSgKKyAgICAgICAgICAgICAgbWVzc2FnZSwgZmllbGQsIGluZGV4LCAmc2NyYXRjaCkKKyAgICAgICAgICA6IHJlZmxlY3Rpb24tPkdldFN0cmluZ1JlZmVyZW5jZShtZXNzYWdlLCBmaWVsZCwgJnNjcmF0Y2gpOworICAgICAgaW50NjQgc2l6ZSA9IHZhbHVlLnNpemUoKTsKKyAgICAgIGlmICh0cnVuY2F0ZV9zdHJpbmdfZmllbGRfbG9uZ2VyX3RoYW5fID4gMCkgeworICAgICAgICBzaXplID0gc3RkOjptaW4odHJ1bmNhdGVfc3RyaW5nX2ZpZWxkX2xvbmdlcl90aGFuXywKKyAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRpY19jYXN0PGludDY0Pih2YWx1ZS5zaXplKCkpKTsKKyAgICAgIH0KKyAgICAgIHN0cmluZyB0cnVuY2F0ZWRfdmFsdWUodmFsdWUuc3Vic3RyKDAsIHNpemUpICsgIi4uLjx0cnVuY2F0ZWQ+Li4uIik7CisgICAgICBjb25zdCBzdHJpbmcqIHZhbHVlX3RvX3ByaW50ID0gJnZhbHVlOworICAgICAgaWYgKHNpemUgPCB2YWx1ZS5zaXplKCkpIHsKKyAgICAgICAgdmFsdWVfdG9fcHJpbnQgPSAmdHJ1bmNhdGVkX3ZhbHVlOworICAgICAgfQorICAgICAgaWYgKGZpZWxkLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX1NUUklORykgeworICAgICAgICBnZW5lcmF0b3IuUHJpbnQocHJpbnRlci0+UHJpbnRTdHJpbmcoKnZhbHVlX3RvX3ByaW50KSk7CisgICAgICB9IGVsc2UgeworICAgICAgICBHT09HTEVfRENIRUNLX0VRKGZpZWxkLT50eXBlKCksIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9CWVRFUyk7CisgICAgICAgIGdlbmVyYXRvci5QcmludChwcmludGVyLT5QcmludEJ5dGVzKCp2YWx1ZV90b19wcmludCkpOworICAgICAgfQorICAgICAgYnJlYWs7CisgICAgfQorCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRU5VTTogeworICAgICAgaW50IGVudW1fdmFsdWUgPSBmaWVsZC0+aXNfcmVwZWF0ZWQoKQorICAgICAgICAgID8gcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRFbnVtVmFsdWUobWVzc2FnZSwgZmllbGQsIGluZGV4KQorICAgICAgICAgIDogcmVmbGVjdGlvbi0+R2V0RW51bVZhbHVlKG1lc3NhZ2UsIGZpZWxkKTsKKyAgICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIGVudW1fZGVzYyA9CisgICAgICAgICAgZmllbGQtPmVudW1fdHlwZSgpLT5GaW5kVmFsdWVCeU51bWJlcihlbnVtX3ZhbHVlKTsKKyAgICAgIGlmIChlbnVtX2Rlc2MgIT0gTlVMTCkgeworICAgICAgICBnZW5lcmF0b3IuUHJpbnQocHJpbnRlci0+UHJpbnRFbnVtKGVudW1fdmFsdWUsIGVudW1fZGVzYy0+bmFtZSgpKSk7CisgICAgICB9IGVsc2UgeworICAgICAgICAvLyBPcmRpbmFyaWx5LCBlbnVtX2Rlc2Mgc2hvdWxkIG5vdCBiZSBudWxsLCBiZWNhdXNlIHByb3RvMiBoYXMgdGhlCisgICAgICAgIC8vIGludmFyaWFudCB0aGF0IHNldCBlbnVtIGZpZWxkIHZhbHVlcyBtdXN0IGJlIGluLXJhbmdlLCBidXQgd2l0aCB0aGUKKyAgICAgICAgLy8gbmV3IGludGVnZXItYmFzZWQgQVBJIGZvciBlbnVtcyAob3IgdGhlIFJlcGVhdGVkRmllbGQ8aW50PiBsb29waG9sZSksCisgICAgICAgIC8vIGl0IGlzIHBvc3NpYmxlIGZvciB0aGUgdXNlciB0byBmb3JjZSBhbiB1bmtub3duIGludGVnZXIgdmFsdWUuICBTbyB3ZQorICAgICAgICAvLyBzaW1wbHkgdXNlIHRoZSBpbnRlZ2VyIHZhbHVlIGl0c2VsZiBhcyB0aGUgZW51bSB2YWx1ZSBuYW1lIGluIHRoaXMKKyAgICAgICAgLy8gY2FzZS4KKyAgICAgICAgZ2VuZXJhdG9yLlByaW50KHByaW50ZXItPlByaW50RW51bShlbnVtX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1ByaW50ZigiJWQiLCBlbnVtX3ZhbHVlKSkpOworICAgICAgfQorICAgICAgYnJlYWs7CisgICAgfQorCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRToKKyAgICAgIFByaW50KGZpZWxkLT5pc19yZXBlYXRlZCgpCisgICAgICAgICAgICA/IHJlZmxlY3Rpb24tPkdldFJlcGVhdGVkTWVzc2FnZShtZXNzYWdlLCBmaWVsZCwgaW5kZXgpCisgICAgICAgICAgICA6IHJlZmxlY3Rpb24tPkdldE1lc3NhZ2UobWVzc2FnZSwgZmllbGQpLAorICAgICAgICAgICAgZ2VuZXJhdG9yKTsKKyAgICAgIGJyZWFrOworICB9Cit9CisKKy8qIHN0YXRpYyAqLyBib29sIFRleHRGb3JtYXQ6OlByaW50KGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0qIG91dHB1dCkgeworICByZXR1cm4gUHJpbnRlcigpLlByaW50KG1lc3NhZ2UsIG91dHB1dCk7Cit9CisKKy8qIHN0YXRpYyAqLyBib29sIFRleHRGb3JtYXQ6OlByaW50VW5rbm93bkZpZWxkcygKKyAgICBjb25zdCBVbmtub3duRmllbGRTZXQmIHVua25vd25fZmllbGRzLAorICAgIGlvOjpaZXJvQ29weU91dHB1dFN0cmVhbSogb3V0cHV0KSB7CisgIHJldHVybiBQcmludGVyKCkuUHJpbnRVbmtub3duRmllbGRzKHVua25vd25fZmllbGRzLCBvdXRwdXQpOworfQorCisvKiBzdGF0aWMgKi8gYm9vbCBUZXh0Rm9ybWF0OjpQcmludFRvU3RyaW5nKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsIHN0cmluZyogb3V0cHV0KSB7CisgIHJldHVybiBQcmludGVyKCkuUHJpbnRUb1N0cmluZyhtZXNzYWdlLCBvdXRwdXQpOworfQorCisvKiBzdGF0aWMgKi8gYm9vbCBUZXh0Rm9ybWF0OjpQcmludFVua25vd25GaWVsZHNUb1N0cmluZygKKyAgICBjb25zdCBVbmtub3duRmllbGRTZXQmIHVua25vd25fZmllbGRzLCBzdHJpbmcqIG91dHB1dCkgeworICByZXR1cm4gUHJpbnRlcigpLlByaW50VW5rbm93bkZpZWxkc1RvU3RyaW5nKHVua25vd25fZmllbGRzLCBvdXRwdXQpOworfQorCisvKiBzdGF0aWMgKi8gdm9pZCBUZXh0Rm9ybWF0OjpQcmludEZpZWxkVmFsdWVUb1N0cmluZygKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgaW50IGluZGV4LAorICAgIHN0cmluZyogb3V0cHV0KSB7CisgIHJldHVybiBQcmludGVyKCkuUHJpbnRGaWVsZFZhbHVlVG9TdHJpbmcobWVzc2FnZSwgZmllbGQsIGluZGV4LCBvdXRwdXQpOworfQorCisvKiBzdGF0aWMgKi8gYm9vbCBUZXh0Rm9ybWF0OjpQYXJzZUZpZWxkVmFsdWVGcm9tU3RyaW5nKAorICAgIGNvbnN0IHN0cmluZyYgaW5wdXQsCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICBNZXNzYWdlKiBtZXNzYWdlKSB7CisgIHJldHVybiBQYXJzZXIoKS5QYXJzZUZpZWxkVmFsdWVGcm9tU3RyaW5nKGlucHV0LCBmaWVsZCwgbWVzc2FnZSk7Cit9CisKKy8vIFByaW50cyBhbiBpbnRlZ2VyIGFzIGhleCB3aXRoIGEgZml4ZWQgbnVtYmVyIG9mIGRpZ2l0cyBkZXBlbmRlbnQgb24gdGhlCisvLyBpbnRlZ2VyIHR5cGUuCit0ZW1wbGF0ZTx0eXBlbmFtZSBJbnRUeXBlPgorc3RhdGljIHN0cmluZyBQYWRkZWRIZXgoSW50VHlwZSB2YWx1ZSkgeworICBzdHJpbmcgcmVzdWx0OworICByZXN1bHQucmVzZXJ2ZShzaXplb2YodmFsdWUpICogMik7CisgIGZvciAoaW50IGkgPSBzaXplb2YodmFsdWUpICogMiAtIDE7IGkgPj0gMDsgaS0tKSB7CisgICAgcmVzdWx0LnB1c2hfYmFjayhpbnRfdG9faGV4X2RpZ2l0KHZhbHVlID4+IChpKjQpICYgMHgwRikpOworICB9CisgIHJldHVybiByZXN1bHQ7Cit9CisKK3ZvaWQgVGV4dEZvcm1hdDo6UHJpbnRlcjo6UHJpbnRVbmtub3duRmllbGRzKAorICAgIGNvbnN0IFVua25vd25GaWVsZFNldCYgdW5rbm93bl9maWVsZHMsIFRleHRHZW5lcmF0b3ImIGdlbmVyYXRvcikgY29uc3QgeworICBmb3IgKGludCBpID0gMDsgaSA8IHVua25vd25fZmllbGRzLmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IFVua25vd25GaWVsZCYgZmllbGQgPSB1bmtub3duX2ZpZWxkcy5maWVsZChpKTsKKyAgICBzdHJpbmcgZmllbGRfbnVtYmVyID0gU2ltcGxlSXRvYShmaWVsZC5udW1iZXIoKSk7CisKKyAgICBzd2l0Y2ggKGZpZWxkLnR5cGUoKSkgeworICAgICAgY2FzZSBVbmtub3duRmllbGQ6OlRZUEVfVkFSSU5UOgorICAgICAgICBnZW5lcmF0b3IuUHJpbnQoZmllbGRfbnVtYmVyKTsKKyAgICAgICAgZ2VuZXJhdG9yLlByaW50KCI6ICIpOworICAgICAgICBnZW5lcmF0b3IuUHJpbnQoU2ltcGxlSXRvYShmaWVsZC52YXJpbnQoKSkpOworICAgICAgICBpZiAoc2luZ2xlX2xpbmVfbW9kZV8pIHsKKyAgICAgICAgICBnZW5lcmF0b3IuUHJpbnQoIiAiKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnZW5lcmF0b3IuUHJpbnQoIlxuIik7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIFVua25vd25GaWVsZDo6VFlQRV9GSVhFRDMyOiB7CisgICAgICAgIGdlbmVyYXRvci5QcmludChmaWVsZF9udW1iZXIpOworICAgICAgICBnZW5lcmF0b3IuUHJpbnQoIjogMHgiKTsKKyAgICAgICAgZ2VuZXJhdG9yLlByaW50KAorICAgICAgICAgICAgU3RyQ2F0KHN0cmluZ3M6OkhleChmaWVsZC5maXhlZDMyKCksIHN0cmluZ3M6OlpFUk9fUEFEXzgpKSk7CisgICAgICAgIGlmIChzaW5nbGVfbGluZV9tb2RlXykgeworICAgICAgICAgIGdlbmVyYXRvci5QcmludCgiICIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdlbmVyYXRvci5QcmludCgiXG4iKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICAgIGNhc2UgVW5rbm93bkZpZWxkOjpUWVBFX0ZJWEVENjQ6IHsKKyAgICAgICAgZ2VuZXJhdG9yLlByaW50KGZpZWxkX251bWJlcik7CisgICAgICAgIGdlbmVyYXRvci5QcmludCgiOiAweCIpOworICAgICAgICBnZW5lcmF0b3IuUHJpbnQoCisgICAgICAgICAgICBTdHJDYXQoc3RyaW5nczo6SGV4KGZpZWxkLmZpeGVkNjQoKSwgc3RyaW5nczo6WkVST19QQURfMTYpKSk7CisgICAgICAgIGlmIChzaW5nbGVfbGluZV9tb2RlXykgeworICAgICAgICAgIGdlbmVyYXRvci5QcmludCgiICIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdlbmVyYXRvci5QcmludCgiXG4iKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICAgIGNhc2UgVW5rbm93bkZpZWxkOjpUWVBFX0xFTkdUSF9ERUxJTUlURUQ6IHsKKyAgICAgICAgZ2VuZXJhdG9yLlByaW50KGZpZWxkX251bWJlcik7CisgICAgICAgIGNvbnN0IHN0cmluZyYgdmFsdWUgPSBmaWVsZC5sZW5ndGhfZGVsaW1pdGVkKCk7CisgICAgICAgIFVua25vd25GaWVsZFNldCBlbWJlZGRlZF91bmtub3duX2ZpZWxkczsKKyAgICAgICAgaWYgKCF2YWx1ZS5lbXB0eSgpICYmIGVtYmVkZGVkX3Vua25vd25fZmllbGRzLlBhcnNlRnJvbVN0cmluZyh2YWx1ZSkpIHsKKyAgICAgICAgICAvLyBUaGlzIGZpZWxkIGlzIHBhcnNlYWJsZSBhcyBhIE1lc3NhZ2UuCisgICAgICAgICAgLy8gU28gaXQgaXMgcHJvYmFibHkgYW4gZW1iZWRkZWQgbWVzc2FnZS4KKyAgICAgICAgICBpZiAoc2luZ2xlX2xpbmVfbW9kZV8pIHsKKyAgICAgICAgICAgIGdlbmVyYXRvci5QcmludCgiIHsgIik7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGdlbmVyYXRvci5QcmludCgiIHtcbiIpOworICAgICAgICAgICAgZ2VuZXJhdG9yLkluZGVudCgpOworICAgICAgICAgIH0KKyAgICAgICAgICBQcmludFVua25vd25GaWVsZHMoZW1iZWRkZWRfdW5rbm93bl9maWVsZHMsIGdlbmVyYXRvcik7CisgICAgICAgICAgaWYgKHNpbmdsZV9saW5lX21vZGVfKSB7CisgICAgICAgICAgICBnZW5lcmF0b3IuUHJpbnQoIn0gIik7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGdlbmVyYXRvci5PdXRkZW50KCk7CisgICAgICAgICAgICBnZW5lcmF0b3IuUHJpbnQoIn1cbiIpOworICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAvLyBUaGlzIGZpZWxkIGlzIG5vdCBwYXJzZWFibGUgYXMgYSBNZXNzYWdlLgorICAgICAgICAgIC8vIFNvIGl0IGlzIHByb2JhYmx5IGp1c3QgYSBwbGFpbiBzdHJpbmcuCisgICAgICAgICAgc3RyaW5nIHByaW50ZWQoIjogXCIiKTsKKyAgICAgICAgICBDRXNjYXBlQW5kQXBwZW5kKHZhbHVlLCAmcHJpbnRlZCk7CisgICAgICAgICAgcHJpbnRlZC5hcHBlbmQoc2luZ2xlX2xpbmVfbW9kZV8gPyAiXCIgIiA6ICJcIlxuIik7CisgICAgICAgICAgZ2VuZXJhdG9yLlByaW50KHByaW50ZWQpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgY2FzZSBVbmtub3duRmllbGQ6OlRZUEVfR1JPVVA6CisgICAgICAgIGdlbmVyYXRvci5QcmludChmaWVsZF9udW1iZXIpOworICAgICAgICBpZiAoc2luZ2xlX2xpbmVfbW9kZV8pIHsKKyAgICAgICAgICBnZW5lcmF0b3IuUHJpbnQoIiB7ICIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdlbmVyYXRvci5QcmludCgiIHtcbiIpOworICAgICAgICAgIGdlbmVyYXRvci5JbmRlbnQoKTsKKyAgICAgICAgfQorICAgICAgICBQcmludFVua25vd25GaWVsZHMoZmllbGQuZ3JvdXAoKSwgZ2VuZXJhdG9yKTsKKyAgICAgICAgaWYgKHNpbmdsZV9saW5lX21vZGVfKSB7CisgICAgICAgICAgZ2VuZXJhdG9yLlByaW50KCJ9ICIpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdlbmVyYXRvci5PdXRkZW50KCk7CisgICAgICAgICAgZ2VuZXJhdG9yLlByaW50KCJ9XG4iKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICB9CisgIH0KK30KKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3RleHRfZm9ybWF0LmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3RleHRfZm9ybWF0LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWYzZDRhOAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdGV4dF9mb3JtYXQuaApAQCAtMCwwICsxLDUxNyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoganNjaG9yckBnb29nbGUuY29tIChKb3NlcGggU2Nob3JyKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisvLworLy8gVXRpbGl0aWVzIGZvciBwcmludGluZyBhbmQgcGFyc2luZyBwcm90b2NvbCBtZXNzYWdlcyBpbiBhIGh1bWFuLXJlYWRhYmxlLAorLy8gdGV4dC1iYXNlZCBmb3JtYXQuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX1RFWFRfRk9STUFUX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfVEVYVF9GT1JNQVRfSF9fCisKKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDx2ZWN0b3I+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWVzc2FnZS5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKK25hbWVzcGFjZSBpbyB7CisgIGNsYXNzIEVycm9yQ29sbGVjdG9yOyAgICAgIC8vIHRva2VuaXplci5oCit9CisKKy8vIFRoaXMgY2xhc3MgaW1wbGVtZW50cyBwcm90b2NvbCBidWZmZXIgdGV4dCBmb3JtYXQuICBQcmludGluZyBhbmQgcGFyc2luZworLy8gcHJvdG9jb2wgbWVzc2FnZXMgaW4gdGV4dCBmb3JtYXQgaXMgdXNlZnVsIGZvciBkZWJ1Z2dpbmcgYW5kIGh1bWFuIGVkaXRpbmcKKy8vIG9mIG1lc3NhZ2VzLgorLy8KKy8vIFRoaXMgY2xhc3MgaXMgcmVhbGx5IGEgbmFtZXNwYWNlIHRoYXQgY29udGFpbnMgb25seSBzdGF0aWMgbWV0aG9kcy4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBUZXh0Rm9ybWF0IHsKKyBwdWJsaWM6CisgIC8vIE91dHB1dHMgYSB0ZXh0dWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBnaXZlbiBtZXNzYWdlIHRvIHRoZSBnaXZlbgorICAvLyBvdXRwdXQgc3RyZWFtLgorICBzdGF0aWMgYm9vbCBQcmludChjb25zdCBNZXNzYWdlJiBtZXNzYWdlLCBpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0qIG91dHB1dCk7CisKKyAgLy8gUHJpbnQgdGhlIGZpZWxkcyBpbiBhbiBVbmtub3duRmllbGRTZXQuICBUaGV5IGFyZSBwcmludGVkIGJ5IHRhZyBudW1iZXIKKyAgLy8gb25seS4gIEVtYmVkZGVkIG1lc3NhZ2VzIGFyZSBoZXVyaXN0aWNhbGx5IGlkZW50aWZpZWQgYnkgYXR0ZW1wdGluZyB0bworICAvLyBwYXJzZSB0aGVtLgorICBzdGF0aWMgYm9vbCBQcmludFVua25vd25GaWVsZHMoY29uc3QgVW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpaZXJvQ29weU91dHB1dFN0cmVhbSogb3V0cHV0KTsKKworICAvLyBMaWtlIFByaW50KCksIGJ1dCBvdXRwdXRzIGRpcmVjdGx5IHRvIGEgc3RyaW5nLgorICBzdGF0aWMgYm9vbCBQcmludFRvU3RyaW5nKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsIHN0cmluZyogb3V0cHV0KTsKKworICAvLyBMaWtlIFByaW50VW5rbm93bkZpZWxkcygpLCBidXQgb3V0cHV0cyBkaXJlY3RseSB0byBhIHN0cmluZy4KKyAgc3RhdGljIGJvb2wgUHJpbnRVbmtub3duRmllbGRzVG9TdHJpbmcoY29uc3QgVW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nKiBvdXRwdXQpOworCisgIC8vIE91dHB1dHMgYSB0ZXh0dWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB2YWx1ZSBvZiB0aGUgZmllbGQgc3VwcGxpZWQgb24KKyAgLy8gdGhlIG1lc3NhZ2Ugc3VwcGxpZWQuIEZvciBub24tcmVwZWF0ZWQgZmllbGRzLCBhbiBpbmRleCBvZiAtMSBtdXN0CisgIC8vIGJlIHN1cHBsaWVkLiBOb3RlIHRoYXQgdGhpcyBtZXRob2Qgd2lsbCBwcmludCB0aGUgZGVmYXVsdCB2YWx1ZSBmb3IgYQorICAvLyBmaWVsZCBpZiBpdCBpcyBub3Qgc2V0LgorICBzdGF0aWMgdm9pZCBQcmludEZpZWxkVmFsdWVUb1N0cmluZyhjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyogb3V0cHV0KTsKKworICAvLyBUaGUgZGVmYXVsdCBwcmludGVyIHRoYXQgY29udmVydHMgc2NhbGFyIHZhbHVlcyBmcm9tIGZpZWxkcyBpbnRvCisgIC8vIHRoZWlyIHN0cmluZyByZXByZXNlbnRhdGlvbi4KKyAgLy8gWW91IGNhbiBkZXJpdmUgZnJvbSB0aGlzIEZpZWxkVmFsdWVQcmludGVyIGlmIHlvdSB3YW50IHRvIGhhdmUKKyAgLy8gZmllbGRzIHRvIGJlIHByaW50ZWQgaW4gYSBkaWZmZXJlbnQgd2F5IGFuZCByZWdpc3RlciBpdCBhdCB0aGUKKyAgLy8gUHJpbnRlci4KKyAgY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEZpZWxkVmFsdWVQcmludGVyIHsKKyAgIHB1YmxpYzoKKyAgICBGaWVsZFZhbHVlUHJpbnRlcigpOworICAgIHZpcnR1YWwgfkZpZWxkVmFsdWVQcmludGVyKCk7CisgICAgdmlydHVhbCBzdHJpbmcgUHJpbnRCb29sKGJvb2wgdmFsKSBjb25zdDsKKyAgICB2aXJ0dWFsIHN0cmluZyBQcmludEludDMyKGludDMyIHZhbCkgY29uc3Q7CisgICAgdmlydHVhbCBzdHJpbmcgUHJpbnRVSW50MzIodWludDMyIHZhbCkgY29uc3Q7CisgICAgdmlydHVhbCBzdHJpbmcgUHJpbnRJbnQ2NChpbnQ2NCB2YWwpIGNvbnN0OworICAgIHZpcnR1YWwgc3RyaW5nIFByaW50VUludDY0KHVpbnQ2NCB2YWwpIGNvbnN0OworICAgIHZpcnR1YWwgc3RyaW5nIFByaW50RmxvYXQoZmxvYXQgdmFsKSBjb25zdDsKKyAgICB2aXJ0dWFsIHN0cmluZyBQcmludERvdWJsZShkb3VibGUgdmFsKSBjb25zdDsKKyAgICB2aXJ0dWFsIHN0cmluZyBQcmludFN0cmluZyhjb25zdCBzdHJpbmcmIHZhbCkgY29uc3Q7CisgICAgdmlydHVhbCBzdHJpbmcgUHJpbnRCeXRlcyhjb25zdCBzdHJpbmcmIHZhbCkgY29uc3Q7CisgICAgdmlydHVhbCBzdHJpbmcgUHJpbnRFbnVtKGludDMyIHZhbCwgY29uc3Qgc3RyaW5nJiBuYW1lKSBjb25zdDsKKyAgICB2aXJ0dWFsIHN0cmluZyBQcmludEZpZWxkTmFtZShjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgY29uc3Q7CisgICAgdmlydHVhbCBzdHJpbmcgUHJpbnRNZXNzYWdlU3RhcnQoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZmllbGRfaW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGZpZWxkX2NvdW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgc2luZ2xlX2xpbmVfbW9kZSkgY29uc3Q7CisgICAgdmlydHVhbCBzdHJpbmcgUHJpbnRNZXNzYWdlRW5kKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBmaWVsZF9pbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGZpZWxkX2NvdW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIHNpbmdsZV9saW5lX21vZGUpIGNvbnN0OworCisgICBwcml2YXRlOgorICAgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhGaWVsZFZhbHVlUHJpbnRlcik7CisgIH07CisKKyAgLy8gQ2xhc3MgZm9yIHRob3NlIHVzZXJzIHdoaWNoIHJlcXVpcmUgbW9yZSBmaW5lLWdyYWluZWQgY29udHJvbCBvdmVyIGhvdworICAvLyBhIHByb3RvYnVmZmVyIG1lc3NhZ2UgaXMgcHJpbnRlZCBvdXQuCisgIGNsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBQcmludGVyIHsKKyAgIHB1YmxpYzoKKyAgICBQcmludGVyKCk7CisgICAgflByaW50ZXIoKTsKKworICAgIC8vIExpa2UgVGV4dEZvcm1hdDo6UHJpbnQKKyAgICBib29sIFByaW50KGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsIGlvOjpaZXJvQ29weU91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgICAvLyBMaWtlIFRleHRGb3JtYXQ6OlByaW50VW5rbm93bkZpZWxkcworICAgIGJvb2wgUHJpbnRVbmtub3duRmllbGRzKGNvbnN0IFVua25vd25GaWVsZFNldCYgdW5rbm93bl9maWVsZHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86Olplcm9Db3B5T3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0OworICAgIC8vIExpa2UgVGV4dEZvcm1hdDo6UHJpbnRUb1N0cmluZworICAgIGJvb2wgUHJpbnRUb1N0cmluZyhjb25zdCBNZXNzYWdlJiBtZXNzYWdlLCBzdHJpbmcqIG91dHB1dCkgY29uc3Q7CisgICAgLy8gTGlrZSBUZXh0Rm9ybWF0OjpQcmludFVua25vd25GaWVsZHNUb1N0cmluZworICAgIGJvb2wgUHJpbnRVbmtub3duRmllbGRzVG9TdHJpbmcoY29uc3QgVW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyogb3V0cHV0KSBjb25zdDsKKyAgICAvLyBMaWtlIFRleHRGb3JtYXQ6OlByaW50RmllbGRWYWx1ZVRvU3RyaW5nCisgICAgdm9pZCBQcmludEZpZWxkVmFsdWVUb1N0cmluZyhjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyogb3V0cHV0KSBjb25zdDsKKworICAgIC8vIEFkanVzdCB0aGUgaW5pdGlhbCBpbmRlbnQgbGV2ZWwgb2YgYWxsIG91dHB1dC4gIEVhY2ggaW5kZW50IGxldmVsIGlzCisgICAgLy8gZXF1YWwgdG8gdHdvIHNwYWNlcy4KKyAgICB2b2lkIFNldEluaXRpYWxJbmRlbnRMZXZlbChpbnQgaW5kZW50X2xldmVsKSB7CisgICAgICBpbml0aWFsX2luZGVudF9sZXZlbF8gPSBpbmRlbnRfbGV2ZWw7CisgICAgfQorCisgICAgLy8gSWYgcHJpbnRpbmcgaW4gc2luZ2xlIGxpbmUgbW9kZSwgdGhlbiB0aGUgZW50aXJlIG1lc3NhZ2Ugd2lsbCBiZSBvdXRwdXQKKyAgICAvLyBvbiBhIHNpbmdsZSBsaW5lIHdpdGggbm8gbGluZSBicmVha3MuCisgICAgdm9pZCBTZXRTaW5nbGVMaW5lTW9kZShib29sIHNpbmdsZV9saW5lX21vZGUpIHsKKyAgICAgIHNpbmdsZV9saW5lX21vZGVfID0gc2luZ2xlX2xpbmVfbW9kZTsKKyAgICB9CisKKyAgICBib29sIElzSW5TaW5nbGVMaW5lTW9kZSgpIHsKKyAgICAgIHJldHVybiBzaW5nbGVfbGluZV9tb2RlXzsKKyAgICB9CisKKyAgICAvLyBJZiB1c2VfZmllbGRfbnVtYmVyIGlzIHRydWUsIHVzZXMgZmllbGQgbnVtYmVyIGluc3RlYWQgb2YgZmllbGQgbmFtZS4KKyAgICB2b2lkIFNldFVzZUZpZWxkTnVtYmVyKGJvb2wgdXNlX2ZpZWxkX251bWJlcikgeworICAgICAgdXNlX2ZpZWxkX251bWJlcl8gPSB1c2VfZmllbGRfbnVtYmVyOworICAgIH0KKworICAgIC8vIFNldCB0cnVlIHRvIHByaW50IHJlcGVhdGVkIHByaW1pdGl2ZXMgaW4gYSBmb3JtYXQgbGlrZToKKyAgICAvLyAgIGZpZWxkX25hbWU6IFsxLCAyLCAzLCA0XQorICAgIC8vIGluc3RlYWQgb2YgcHJpbnRpbmcgZWFjaCB2YWx1ZSBvbiBpdHMgb3duIGxpbmUuICBTaG9ydCBmb3JtYXQgYXBwbGllcworICAgIC8vIG9ubHkgdG8gcHJpbWl0aXZlIHZhbHVlcyAtLSBpLmUuIGV2ZXJ5dGhpbmcgZXhjZXB0IHN0cmluZ3MgYW5kCisgICAgLy8gc3ViLW1lc3NhZ2VzL2dyb3Vwcy4KKyAgICB2b2lkIFNldFVzZVNob3J0UmVwZWF0ZWRQcmltaXRpdmVzKGJvb2wgdXNlX3Nob3J0X3JlcGVhdGVkX3ByaW1pdGl2ZXMpIHsKKyAgICAgIHVzZV9zaG9ydF9yZXBlYXRlZF9wcmltaXRpdmVzXyA9IHVzZV9zaG9ydF9yZXBlYXRlZF9wcmltaXRpdmVzOworICAgIH0KKworICAgIC8vIFNldCB0cnVlIHRvIG91dHB1dCBVVEYtOCBpbnN0ZWFkIG9mIEFTQ0lJLiAgVGhlIG9ubHkgZGlmZmVyZW5jZQorICAgIC8vIGlzIHRoYXQgYnl0ZXMgPj0gMHg4MCBpbiBzdHJpbmcgZmllbGRzIHdpbGwgbm90IGJlIGVzY2FwZWQsCisgICAgLy8gYmVjYXVzZSB0aGV5IGFyZSBhc3N1bWVkIHRvIGJlIHBhcnQgb2YgVVRGLTggbXVsdGktYnl0ZQorICAgIC8vIHNlcXVlbmNlcy4gVGhpcyB3aWxsIGNoYW5nZSB0aGUgZGVmYXVsdCBGaWVsZFZhbHVlUHJpbnRlci4KKyAgICB2b2lkIFNldFVzZVV0ZjhTdHJpbmdFc2NhcGluZyhib29sIGFzX3V0ZjgpOworCisgICAgLy8gU2V0IHRoZSBkZWZhdWx0IEZpZWxkVmFsdWVQcmludGVyIHRoYXQgaXMgdXNlZCBmb3IgYWxsIGZpZWxkcyB0aGF0CisgICAgLy8gZG9uJ3QgaGF2ZSBhIGZpZWxkLXNwZWNpZmljIHByaW50ZXIgcmVnaXN0ZXJlZC4KKyAgICAvLyBUYWtlcyBvd25lcnNoaXAgb2YgdGhlIHByaW50ZXIuCisgICAgdm9pZCBTZXREZWZhdWx0RmllbGRWYWx1ZVByaW50ZXIoY29uc3QgRmllbGRWYWx1ZVByaW50ZXIqIHByaW50ZXIpOworCisgICAgLy8gU2V0cyB3aGV0aGVyIHdlIHdhbnQgdG8gaGlkZSB1bmtub3duIGZpZWxkcyBvciBub3QuCisgICAgLy8gVXN1YWxseSB1bmtub3duIGZpZWxkcyBhcmUgcHJpbnRlZCBpbiBhIGdlbmVyaWMgd2F5IHRoYXQgaW5jbHVkZXMgdGhlCisgICAgLy8gdGFnIG51bWJlciBvZiB0aGUgZmllbGQgaW5zdGVhZCBvZiBmaWVsZCBuYW1lLiBIb3dldmVyLCBzb21ldGltZXMgaXQKKyAgICAvLyBpcyB1c2VmdWwgdG8gYmUgYWJsZSB0byBwcmludCB0aGUgbWVzc2FnZSB3aXRob3V0IHVua25vd24gZmllbGRzIChlLmcuCisgICAgLy8gZm9yIHRoZSBweXRob24gcHJvdG9idWYgdmVyc2lvbiB0byBtYWludGFpbiBjb25zaXN0ZW5jeSBiZXR3ZWVuIGl0cyBwdXJlCisgICAgLy8gcHl0aG9uIGFuZCBjKysgaW1wbGVtZW50YXRpb25zKS4KKyAgICB2b2lkIFNldEhpZGVVbmtub3duRmllbGRzKGJvb2wgaGlkZSkgeworICAgICAgaGlkZV91bmtub3duX2ZpZWxkc18gPSBoaWRlOworICAgIH0KKworICAgIC8vIElmIHByaW50X21lc3NhZ2VfZmllbGRzX2luX2luZGV4X29yZGVyIGlzIHRydWUsIHByaW50IGZpZWxkcyBvZiBhIHByb3RvCisgICAgLy8gbWVzc2FnZSB1c2luZyB0aGUgb3JkZXIgZGVmaW5lZCBpbiBzb3VyY2UgY29kZSBpbnN0ZWFkIG9mIHRoZSBmaWVsZAorICAgIC8vIG51bWJlci4gQnkgZGVmYXVsdCwgdXNlIHRoZSBmaWVsZCBudW1iZXIgb3JkZXIuCisgICAgdm9pZCBTZXRQcmludE1lc3NhZ2VGaWVsZHNJbkluZGV4T3JkZXIoCisgICAgICAgIGJvb2wgcHJpbnRfbWVzc2FnZV9maWVsZHNfaW5faW5kZXhfb3JkZXIpIHsKKyAgICAgIHByaW50X21lc3NhZ2VfZmllbGRzX2luX2luZGV4X29yZGVyXyA9CisgICAgICAgICAgcHJpbnRfbWVzc2FnZV9maWVsZHNfaW5faW5kZXhfb3JkZXI7CisgICAgfQorCisgICAgLy8gSWYgZXhwYW5kPT10cnVlLCBleHBhbmQgZ29vZ2xlLnByb3RvYnVmLkFueSBwYXlsb2Fkcy4gVGhlIG91dHB1dAorICAgIC8vIHdpbGwgYmUgb2YgZm9ybQorICAgIC8vICAgIFt0eXBlX3VybF0geyA8dmFsdWVfcHJpbnRlZF9pbl90ZXh0PiB9CisgICAgLy8KKyAgICAvLyBJZiBleHBhbmQ9PWZhbHNlLCBwcmludCBBbnkgdXNpbmcgdGhlIGRlZmF1bHQgcHJpbnRlci4gVGhlIG91dHB1dCB3aWxsCisgICAgLy8gbG9vayBsaWtlCisgICAgLy8gICAgdHlwZV91cmw6ICI8dHlwZV91cmw+IiAgdmFsdWU6ICJzZXJpYWxpemVkX2NvbnRlbnQiCisgICAgdm9pZCBTZXRFeHBhbmRBbnkoYm9vbCBleHBhbmQpIHsKKyAgICAgIGV4cGFuZF9hbnlfID0gZXhwYW5kOworICAgIH0KKworICAgIC8vIElmIG5vbi16ZXJvLCB3ZSB0cnVuY2F0ZSBhbGwgc3RyaW5nIGZpZWxkcyB0aGF0IGFyZSAgbG9uZ2VyIHRoYW4gdGhpcworICAgIC8vIHRocmVzaG9sZC4gIFRoaXMgaXMgdXNlZnVsIHdoZW4gdGhlIHByb3RvIG1lc3NhZ2UgaGFzIHZlcnkgbG9uZyBzdHJpbmdzLAorICAgIC8vIGUuZy4sIGR1bXAgb2YgZW5jb2RlZCBpbWFnZSBmaWxlLgorICAgIC8vCisgICAgLy8gTk9URShoZmdvbmcpOiAgU2V0dGluZyBhIG5vbi16ZXJvIHZhbHVlIGJyZWFrcyByb3VuZC10cmlwIHNhZmUKKyAgICAvLyBwcm9wZXJ0eSBvZiBUZXh0Rm9ybWF0OjpQcmludGVyLiAgVGhhdCBpcywgZnJvbSB0aGUgcHJpbnRlZCBtZXNzYWdlLCB3ZQorICAgIC8vIGNhbm5vdCBmdWxseSByZWNvdmVyIHRoZSBvcmlnaW5hbCBzdHJpbmcgZmllbGQgYW55IG1vcmUuCisgICAgdm9pZCBTZXRUcnVuY2F0ZVN0cmluZ0ZpZWxkTG9uZ2VyVGhhbigKKyAgICAgICAgY29uc3QgaW50NjQgdHJ1bmNhdGVfc3RyaW5nX2ZpZWxkX2xvbmdlcl90aGFuKSB7CisgICAgICB0cnVuY2F0ZV9zdHJpbmdfZmllbGRfbG9uZ2VyX3RoYW5fID0gdHJ1bmNhdGVfc3RyaW5nX2ZpZWxkX2xvbmdlcl90aGFuOworICAgIH0KKworICAgIC8vIFJlZ2lzdGVyIGEgY3VzdG9tIGZpZWxkLXNwZWNpZmljIEZpZWxkVmFsdWVQcmludGVyIGZvciBmaWVsZHMKKyAgICAvLyB3aXRoIGEgcGFydGljdWxhciBGaWVsZERlc2NyaXB0b3IuCisgICAgLy8gUmV0dXJucyAidHJ1ZSIgaWYgdGhlIHJlZ2lzdHJhdGlvbiBzdWNjZWVkZWQsIG9yICJmYWxzZSIsIGlmIHRoZXJlIGlzCisgICAgLy8gYWxyZWFkeSBhIHByaW50ZXIgZm9yIHRoYXQgRmllbGREZXNjcmlwdG9yLgorICAgIC8vIFRha2VzIG93bmVyc2hpcCBvZiB0aGUgcHJpbnRlciBvbiBzdWNjZXNzZnVsIHJlZ2lzdHJhdGlvbi4KKyAgICBib29sIFJlZ2lzdGVyRmllbGRWYWx1ZVByaW50ZXIoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGRWYWx1ZVByaW50ZXIqIHByaW50ZXIpOworCisgICBwcml2YXRlOgorICAgIC8vIEZvcndhcmQgZGVjbGFyYXRpb24gb2YgYW4gaW50ZXJuYWwgY2xhc3MgdXNlZCB0byBwcmludCB0aGUgdGV4dAorICAgIC8vIG91dHB1dCB0byB0aGUgT3V0cHV0U3RyZWFtIChzZWUgdGV4dF9mb3JtYXQuY2MgZm9yIGltcGxlbWVudGF0aW9uKS4KKyAgICBjbGFzcyBUZXh0R2VuZXJhdG9yOworCisgICAgLy8gSW50ZXJuYWwgUHJpbnQgbWV0aG9kLCB1c2VkIGZvciB3cml0aW5nIHRvIHRoZSBPdXRwdXRTdHJlYW0gdmlhCisgICAgLy8gdGhlIFRleHRHZW5lcmF0b3IgY2xhc3MuCisgICAgdm9pZCBQcmludChjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgVGV4dEdlbmVyYXRvciYgZ2VuZXJhdG9yKSBjb25zdDsKKworICAgIC8vIFByaW50IGEgc2luZ2xlIGZpZWxkLgorICAgIHZvaWQgUHJpbnRGaWVsZChjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uLAorICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICBUZXh0R2VuZXJhdG9yJiBnZW5lcmF0b3IpIGNvbnN0OworCisgICAgLy8gUHJpbnQgYSByZXBlYXRlZCBwcmltaXRpdmUgZmllbGQgaW4gc2hvcnQgZm9ybS4KKyAgICB2b2lkIFByaW50U2hvcnRSZXBlYXRlZEZpZWxkKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRleHRHZW5lcmF0b3ImIGdlbmVyYXRvcikgY29uc3Q7CisKKyAgICAvLyBQcmludCB0aGUgbmFtZSBvZiBhIGZpZWxkIC0tIGkuZS4gZXZlcnl0aGluZyB0aGF0IGNvbWVzIGJlZm9yZSB0aGUKKyAgICAvLyAnOicgZm9yIGEgc2luZ2xlIG5hbWUvdmFsdWUgcGFpci4KKyAgICB2b2lkIFByaW50RmllbGROYW1lKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgIFRleHRHZW5lcmF0b3ImIGdlbmVyYXRvcikgY29uc3Q7CisKKyAgICAvLyBPdXRwdXRzIGEgdGV4dHVhbCByZXByZXNlbnRhdGlvbiBvZiB0aGUgdmFsdWUgb2YgdGhlIGZpZWxkIHN1cHBsaWVkIG9uCisgICAgLy8gdGhlIG1lc3NhZ2Ugc3VwcGxpZWQgb3IgdGhlIGRlZmF1bHQgdmFsdWUgaWYgbm90IHNldC4KKyAgICB2b2lkIFByaW50RmllbGRWYWx1ZShjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgVGV4dEdlbmVyYXRvciYgZ2VuZXJhdG9yKSBjb25zdDsKKworICAgIC8vIFByaW50IHRoZSBmaWVsZHMgaW4gYW4gVW5rbm93bkZpZWxkU2V0LiAgVGhleSBhcmUgcHJpbnRlZCBieSB0YWcgbnVtYmVyCisgICAgLy8gb25seS4gIEVtYmVkZGVkIG1lc3NhZ2VzIGFyZSBoZXVyaXN0aWNhbGx5IGlkZW50aWZpZWQgYnkgYXR0ZW1wdGluZyB0bworICAgIC8vIHBhcnNlIHRoZW0uCisgICAgdm9pZCBQcmludFVua25vd25GaWVsZHMoY29uc3QgVW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBUZXh0R2VuZXJhdG9yJiBnZW5lcmF0b3IpIGNvbnN0OworCisgICAgYm9vbCBQcmludEFueShjb25zdCBNZXNzYWdlJiBtZXNzYWdlLCBUZXh0R2VuZXJhdG9yJiBnZW5lcmF0b3IpIGNvbnN0OworCisgICAgaW50IGluaXRpYWxfaW5kZW50X2xldmVsXzsKKworICAgIGJvb2wgc2luZ2xlX2xpbmVfbW9kZV87CisKKyAgICBib29sIHVzZV9maWVsZF9udW1iZXJfOworCisgICAgYm9vbCB1c2Vfc2hvcnRfcmVwZWF0ZWRfcHJpbWl0aXZlc187CisKKyAgICBib29sIGhpZGVfdW5rbm93bl9maWVsZHNfOworCisgICAgYm9vbCBwcmludF9tZXNzYWdlX2ZpZWxkc19pbl9pbmRleF9vcmRlcl87CisKKyAgICBib29sIGV4cGFuZF9hbnlfOworCisgICAgaW50NjQgdHJ1bmNhdGVfc3RyaW5nX2ZpZWxkX2xvbmdlcl90aGFuXzsKKworICAgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8Y29uc3QgRmllbGRWYWx1ZVByaW50ZXI+IGRlZmF1bHRfZmllbGRfdmFsdWVfcHJpbnRlcl87CisgICAgdHlwZWRlZiBtYXA8Y29uc3QgRmllbGREZXNjcmlwdG9yKiwKKyAgICAgICAgICAgICAgICBjb25zdCBGaWVsZFZhbHVlUHJpbnRlcio+IEN1c3RvbVByaW50ZXJNYXA7CisgICAgQ3VzdG9tUHJpbnRlck1hcCBjdXN0b21fcHJpbnRlcnNfOworICB9OworCisgIC8vIFBhcnNlcyBhIHRleHQtZm9ybWF0IHByb3RvY29sIG1lc3NhZ2UgZnJvbSB0aGUgZ2l2ZW4gaW5wdXQgc3RyZWFtIHRvCisgIC8vIHRoZSBnaXZlbiBtZXNzYWdlIG9iamVjdC4gVGhpcyBmdW5jdGlvbiBwYXJzZXMgdGhlIGh1bWFuLXJlYWRhYmxlIGZvcm1hdAorICAvLyB3cml0dGVuIGJ5IFByaW50KCkuIFJldHVybnMgdHJ1ZSBvbiBzdWNjZXNzLiBUaGUgbWVzc2FnZSBpcyBjbGVhcmVkIGZpcnN0LAorICAvLyBldmVuIGlmIHRoZSBmdW5jdGlvbiBmYWlscyAtLSBTZWUgTWVyZ2UoKSB0byBhdm9pZCB0aGlzIGJlaGF2aW9yLgorICAvLworICAvLyBFeGFtcGxlIGlucHV0OiAidXNlciB7XG4gaWQ6IDEyMyBleHRyYSB7IGdlbmRlcjogTUFMRSBsYW5ndWFnZTogJ2VuJyB9XG59IgorICAvLworICAvLyBPbmUgdXNlIGZvciB0aGlzIGZ1bmN0aW9uIGlzIHBhcnNpbmcgaGFuZHdyaXR0ZW4gc3RyaW5ncyBpbiB0ZXN0IGNvZGUuCisgIC8vIEFub3RoZXIgdXNlIGlzIHRvIHBhcnNlIHRoZSBvdXRwdXQgZnJvbSBnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlOjpEZWJ1Z1N0cmluZygpCisgIC8vIChvciBTaG9ydERlYnVnU3RyaW5nKCkpLCBiZWNhdXNlIHRoZXNlIGZ1bmN0aW9ucyBvdXRwdXQgdXNpbmcKKyAgLy8gZ29vZ2xlOjpwcm90b2J1Zjo6VGV4dEZvcm1hdDo6UHJpbnQoKS4KKyAgLy8KKyAgLy8gSWYgeW91IHdvdWxkIGxpa2UgdG8gcmVhZCBhIHByb3RvY29sIGJ1ZmZlciBzZXJpYWxpemVkIGluIHRoZQorICAvLyAobm9uLWh1bWFuLXJlYWRhYmxlKSBiaW5hcnkgd2lyZSBmb3JtYXQsIHNlZQorICAvLyBnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlTGl0ZTo6UGFyc2VGcm9tU3RyaW5nKCkuCisgIHN0YXRpYyBib29sIFBhcnNlKGlvOjpaZXJvQ29weUlucHV0U3RyZWFtKiBpbnB1dCwgTWVzc2FnZSogb3V0cHV0KTsKKyAgLy8gTGlrZSBQYXJzZSgpLCBidXQgcmVhZHMgZGlyZWN0bHkgZnJvbSBhIHN0cmluZy4KKyAgc3RhdGljIGJvb2wgUGFyc2VGcm9tU3RyaW5nKGNvbnN0IHN0cmluZyYgaW5wdXQsIE1lc3NhZ2UqIG91dHB1dCk7CisKKyAgLy8gTGlrZSBQYXJzZSgpLCBidXQgdGhlIGRhdGEgaXMgbWVyZ2VkIGludG8gdGhlIGdpdmVuIG1lc3NhZ2UsIGFzIGlmCisgIC8vIHVzaW5nIE1lc3NhZ2U6Ok1lcmdlRnJvbSgpLgorICBzdGF0aWMgYm9vbCBNZXJnZShpbzo6WmVyb0NvcHlJbnB1dFN0cmVhbSogaW5wdXQsIE1lc3NhZ2UqIG91dHB1dCk7CisgIC8vIExpa2UgTWVyZ2UoKSwgYnV0IHJlYWRzIGRpcmVjdGx5IGZyb20gYSBzdHJpbmcuCisgIHN0YXRpYyBib29sIE1lcmdlRnJvbVN0cmluZyhjb25zdCBzdHJpbmcmIGlucHV0LCBNZXNzYWdlKiBvdXRwdXQpOworCisgIC8vIFBhcnNlIHRoZSBnaXZlbiB0ZXh0IGFzIGEgc2luZ2xlIGZpZWxkIHZhbHVlIGFuZCBzdG9yZSBpdCBpbnRvIHRoZQorICAvLyBnaXZlbiBmaWVsZCBvZiB0aGUgZ2l2ZW4gbWVzc2FnZS4gSWYgdGhlIGZpZWxkIGlzIGEgcmVwZWF0ZWQgZmllbGQsCisgIC8vIHRoZSBuZXcgdmFsdWUgd2lsbCBiZSBhZGRlZCB0byB0aGUgZW5kCisgIHN0YXRpYyBib29sIFBhcnNlRmllbGRWYWx1ZUZyb21TdHJpbmcoY29uc3Qgc3RyaW5nJiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UqIG1lc3NhZ2UpOworCisgIC8vIEludGVyZmFjZSB0aGF0IFRleHRGb3JtYXQ6OlBhcnNlciBjYW4gdXNlIHRvIGZpbmQgZXh0ZW5zaW9ucy4KKyAgLy8gVGhpcyBjbGFzcyBtYXkgYmUgZXh0ZW5kZWQgaW4gdGhlIGZ1dHVyZSB0byBmaW5kIG1vcmUgaW5mb3JtYXRpb24KKyAgLy8gbGlrZSBmaWVsZHMsIGV0Yy4KKyAgY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEZpbmRlciB7CisgICBwdWJsaWM6CisgICAgdmlydHVhbCB+RmluZGVyKCk7CisKKyAgICAvLyBUcnkgdG8gZmluZCBhbiBleHRlbnNpb24gb2YgKm1lc3NhZ2UgYnkgZnVsbHktcXVhbGlmaWVkIGZpZWxkCisgICAgLy8gbmFtZS4gIFJldHVybnMgTlVMTCBpZiBubyBleHRlbnNpb24gaXMga25vd24gZm9yIHRoaXMgbmFtZSBvciBudW1iZXIuCisgICAgdmlydHVhbCBjb25zdCBGaWVsZERlc2NyaXB0b3IqIEZpbmRFeHRlbnNpb24oCisgICAgICAgIE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgIGNvbnN0IHN0cmluZyYgbmFtZSkgY29uc3QgPSAwOworICB9OworCisgIC8vIEEgbG9jYXRpb24gaW4gdGhlIHBhcnNlZCB0ZXh0LgorICBzdHJ1Y3QgUGFyc2VMb2NhdGlvbiB7CisgICAgaW50IGxpbmU7CisgICAgaW50IGNvbHVtbjsKKworICAgIFBhcnNlTG9jYXRpb24oKSA6IGxpbmUoLTEpLCBjb2x1bW4oLTEpIHt9CisgICAgUGFyc2VMb2NhdGlvbihpbnQgbGluZV9wYXJhbSwgaW50IGNvbHVtbl9wYXJhbSkKKyAgICAgICAgOiBsaW5lKGxpbmVfcGFyYW0pLCBjb2x1bW4oY29sdW1uX3BhcmFtKSB7fQorICB9OworCisgIC8vIERhdGEgc3RydWN0dXJlIHdoaWNoIGlzIHBvcHVsYXRlZCB3aXRoIHRoZSBsb2NhdGlvbnMgb2YgZWFjaCBmaWVsZAorICAvLyB2YWx1ZSBwYXJzZWQgZnJvbSB0aGUgdGV4dC4KKyAgY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFBhcnNlSW5mb1RyZWUgeworICAgcHVibGljOgorICAgIFBhcnNlSW5mb1RyZWUoKTsKKyAgICB+UGFyc2VJbmZvVHJlZSgpOworCisgICAgLy8gUmV0dXJucyB0aGUgcGFyc2UgbG9jYXRpb24gZm9yIGluZGV4LXRoIHZhbHVlIG9mIHRoZSBmaWVsZCBpbiB0aGUgcGFyc2VkCisgICAgLy8gdGV4dC4gSWYgbm9uZSBleGlzdHMsIHJldHVybnMgYSBsb2NhdGlvbiB3aXRoIGxpbmUgPSAtMS4gSW5kZXggc2hvdWxkIGJlCisgICAgLy8gLTEgZm9yIG5vdC1yZXBlYXRlZCBmaWVsZHMuCisgICAgUGFyc2VMb2NhdGlvbiBHZXRMb2NhdGlvbihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBpbnQgaW5kZXgpIGNvbnN0OworCisgICAgLy8gUmV0dXJucyB0aGUgcGFyc2UgaW5mbyB0cmVlIGZvciB0aGUgZ2l2ZW4gZmllbGQsIHdoaWNoIG11c3QgYmUgYSBtZXNzYWdlCisgICAgLy8gdHlwZS4gVGhlIG5lc3RlZCBpbmZvcm1hdGlvbiB0cmVlIGlzIG93bmVkIGJ5IHRoZSByb290IHRyZWUgYW5kIHdpbGwgYmUKKyAgICAvLyBkZWxldGVkIHdoZW4gaXQgaXMgZGVsZXRlZC4KKyAgICBQYXJzZUluZm9UcmVlKiBHZXRUcmVlRm9yTmVzdGVkKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXgpIGNvbnN0OworCisgICBwcml2YXRlOgorICAgIC8vIEFsbG93IHRoZSB0ZXh0IGZvcm1hdCBwYXJzZXIgdG8gcmVjb3JkIGluZm9ybWF0aW9uIGludG8gdGhlIHRyZWUuCisgICAgZnJpZW5kIGNsYXNzIFRleHRGb3JtYXQ7CisKKyAgICAvLyBSZWNvcmRzIHRoZSBzdGFydGluZyBsb2NhdGlvbiBvZiBhIHNpbmdsZSB2YWx1ZSBmb3IgYSBmaWVsZC4KKyAgICB2b2lkIFJlY29yZExvY2F0aW9uKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIFBhcnNlTG9jYXRpb24gbG9jYXRpb24pOworCisgICAgLy8gQ3JlYXRlIGFuZCByZWNvcmRzIGEgbmVzdGVkIHRyZWUgZm9yIGEgbmVzdGVkIG1lc3NhZ2UgZmllbGQuCisgICAgUGFyc2VJbmZvVHJlZSogQ3JlYXRlTmVzdGVkKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpOworCisgICAgLy8gRGVmaW5lcyB0aGUgbWFwIGZyb20gdGhlIGluZGV4LXRoIGZpZWxkIGRlc2NyaXB0b3IgdG8gaXRzIHBhcnNlIGxvY2F0aW9uLgorICAgIHR5cGVkZWYgbWFwPGNvbnN0IEZpZWxkRGVzY3JpcHRvciosIHZlY3RvcjxQYXJzZUxvY2F0aW9uPiA+IExvY2F0aW9uTWFwOworCisgICAgLy8gRGVmaW5lcyB0aGUgbWFwIGZyb20gdGhlIGluZGV4LXRoIGZpZWxkIGRlc2NyaXB0b3IgdG8gdGhlIG5lc3RlZCBwYXJzZQorICAgIC8vIGluZm8gdHJlZS4KKyAgICB0eXBlZGVmIG1hcDxjb25zdCBGaWVsZERlc2NyaXB0b3IqLCB2ZWN0b3I8UGFyc2VJbmZvVHJlZSo+ID4gTmVzdGVkTWFwOworCisgICAgTG9jYXRpb25NYXAgbG9jYXRpb25zXzsKKyAgICBOZXN0ZWRNYXAgbmVzdGVkXzsKKworICAgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhQYXJzZUluZm9UcmVlKTsKKyAgfTsKKworICAvLyBGb3IgbW9yZSBjb250cm9sIG92ZXIgcGFyc2luZywgdXNlIHRoaXMgY2xhc3MuCisgIGNsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBQYXJzZXIgeworICAgcHVibGljOgorICAgIFBhcnNlcigpOworICAgIH5QYXJzZXIoKTsKKworICAgIC8vIExpa2UgVGV4dEZvcm1hdDo6UGFyc2UoKS4KKyAgICBib29sIFBhcnNlKGlvOjpaZXJvQ29weUlucHV0U3RyZWFtKiBpbnB1dCwgTWVzc2FnZSogb3V0cHV0KTsKKyAgICAvLyBMaWtlIFRleHRGb3JtYXQ6OlBhcnNlRnJvbVN0cmluZygpLgorICAgIGJvb2wgUGFyc2VGcm9tU3RyaW5nKGNvbnN0IHN0cmluZyYgaW5wdXQsIE1lc3NhZ2UqIG91dHB1dCk7CisgICAgLy8gTGlrZSBUZXh0Rm9ybWF0OjpNZXJnZSgpLgorICAgIGJvb2wgTWVyZ2UoaW86Olplcm9Db3B5SW5wdXRTdHJlYW0qIGlucHV0LCBNZXNzYWdlKiBvdXRwdXQpOworICAgIC8vIExpa2UgVGV4dEZvcm1hdDo6TWVyZ2VGcm9tU3RyaW5nKCkuCisgICAgYm9vbCBNZXJnZUZyb21TdHJpbmcoY29uc3Qgc3RyaW5nJiBpbnB1dCwgTWVzc2FnZSogb3V0cHV0KTsKKworICAgIC8vIFNldCB3aGVyZSB0byByZXBvcnQgcGFyc2UgZXJyb3JzLiAgSWYgTlVMTCAodGhlIGRlZmF1bHQpLCBlcnJvcnMgd2lsbAorICAgIC8vIGJlIHByaW50ZWQgdG8gc3RkZXJyLgorICAgIHZvaWQgUmVjb3JkRXJyb3JzVG8oaW86OkVycm9yQ29sbGVjdG9yKiBlcnJvcl9jb2xsZWN0b3IpIHsKKyAgICAgIGVycm9yX2NvbGxlY3Rvcl8gPSBlcnJvcl9jb2xsZWN0b3I7CisgICAgfQorCisgICAgLy8gU2V0IGhvdyBwYXJzZXIgZmluZHMgZXh0ZW5zaW9ucy4gIElmIE5VTEwgKHRoZSBkZWZhdWx0KSwgdGhlCisgICAgLy8gcGFyc2VyIHdpbGwgdXNlIHRoZSBzdGFuZGFyZCBSZWZsZWN0aW9uIG9iamVjdCBhc3NvY2lhdGVkIHdpdGgKKyAgICAvLyB0aGUgbWVzc2FnZSBiZWluZyBwYXJzZWQuCisgICAgdm9pZCBTZXRGaW5kZXIoRmluZGVyKiBmaW5kZXIpIHsKKyAgICAgIGZpbmRlcl8gPSBmaW5kZXI7CisgICAgfQorCisgICAgLy8gU2V0cyB3aGVyZSBsb2NhdGlvbiBpbmZvcm1hdGlvbiBhYm91dCB0aGUgcGFyc2Ugd2lsbCBiZSB3cml0dGVuLiBJZiBOVUxMCisgICAgLy8gKHRoZSBkZWZhdWx0KSwgdGhlbiBubyBsb2NhdGlvbiB3aWxsIGJlIHdyaXR0ZW4uCisgICAgdm9pZCBXcml0ZUxvY2F0aW9uc1RvKFBhcnNlSW5mb1RyZWUqIHRyZWUpIHsKKyAgICAgIHBhcnNlX2luZm9fdHJlZV8gPSB0cmVlOworICAgIH0KKworICAgIC8vIE5vcm1hbGx5IHBhcnNpbmcgZmFpbHMgaWYsIGFmdGVyIHBhcnNpbmcsIG91dHB1dC0+SXNJbml0aWFsaXplZCgpCisgICAgLy8gcmV0dXJucyBmYWxzZS4gIENhbGwgQWxsb3dQYXJ0aWFsTWVzc2FnZSh0cnVlKSB0byBza2lwIHRoaXMgY2hlY2suCisgICAgdm9pZCBBbGxvd1BhcnRpYWxNZXNzYWdlKGJvb2wgYWxsb3cpIHsKKyAgICAgIGFsbG93X3BhcnRpYWxfID0gYWxsb3c7CisgICAgfQorCisgICAgLy8gQWxsb3cgZmllbGQgbmFtZXMgdG8gYmUgbWF0Y2hlZCBjYXNlLWluc2Vuc2l0aXZlbHkuCisgICAgLy8gVGhpcyBpcyBub3QgYWR2aXNhYmxlIGlmIHRoZXJlIGFyZSBmaWVsZHMgdGhhdCBvbmx5IGRpZmZlciBpbiBjYXNlLCBvcgorICAgIC8vIGlmIHlvdSB3YW50IHRvIGVuZm9yY2Ugd3JpdGluZyBpbiB0aGUgY2Fub25pY2FsIGZvcm0uCisgICAgLy8gVGhpcyBpcyAnZmFsc2UnIGJ5IGRlZmF1bHQuCisgICAgdm9pZCBBbGxvd0Nhc2VJbnNlbnNpdGl2ZUZpZWxkKGJvb2wgYWxsb3cpIHsKKyAgICAgIGFsbG93X2Nhc2VfaW5zZW5zaXRpdmVfZmllbGRfID0gYWxsb3c7CisgICAgfQorCisgICAgLy8gTGlrZSBUZXh0Rm9ybWF0OjpQYXJzZUZpZWxkVmFsdWVGcm9tU3RyaW5nCisgICAgYm9vbCBQYXJzZUZpZWxkVmFsdWVGcm9tU3RyaW5nKGNvbnN0IHN0cmluZyYgaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UqIG91dHB1dCk7CisKKworICAgIHZvaWQgQWxsb3dGaWVsZE51bWJlcihib29sIGFsbG93KSB7CisgICAgICBhbGxvd19maWVsZF9udW1iZXJfID0gYWxsb3c7CisgICAgfQorCisgICBwcml2YXRlOgorICAgIC8vIEZvcndhcmQgZGVjbGFyYXRpb24gb2YgYW4gaW50ZXJuYWwgY2xhc3MgdXNlZCB0byBwYXJzZSB0ZXh0CisgICAgLy8gcmVwcmVzZW50YXRpb25zIChzZWUgdGV4dF9mb3JtYXQuY2MgZm9yIGltcGxlbWVudGF0aW9uKS4KKyAgICBjbGFzcyBQYXJzZXJJbXBsOworCisgICAgLy8gTGlrZSBUZXh0Rm9ybWF0OjpNZXJnZSgpLiAgVGhlIHByb3ZpZGVkIGltcGxlbWVudGF0aW9uIGlzIHVzZWQKKyAgICAvLyB0byBkbyB0aGUgcGFyc2luZy4KKyAgICBib29sIE1lcmdlVXNpbmdJbXBsKGlvOjpaZXJvQ29weUlucHV0U3RyZWFtKiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UqIG91dHB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgIFBhcnNlckltcGwqIHBhcnNlcl9pbXBsKTsKKworICAgIGlvOjpFcnJvckNvbGxlY3RvciogZXJyb3JfY29sbGVjdG9yXzsKKyAgICBGaW5kZXIqIGZpbmRlcl87CisgICAgUGFyc2VJbmZvVHJlZSogcGFyc2VfaW5mb190cmVlXzsKKyAgICBib29sIGFsbG93X3BhcnRpYWxfOworICAgIGJvb2wgYWxsb3dfY2FzZV9pbnNlbnNpdGl2ZV9maWVsZF87CisgICAgYm9vbCBhbGxvd191bmtub3duX2ZpZWxkXzsKKyAgICBib29sIGFsbG93X3Vua25vd25fZW51bV87CisgICAgYm9vbCBhbGxvd19maWVsZF9udW1iZXJfOworICAgIGJvb2wgYWxsb3dfcmVsYXhlZF93aGl0ZXNwYWNlXzsKKyAgICBib29sIGFsbG93X3Npbmd1bGFyX292ZXJ3cml0ZXNfOworICB9OworCisKKyBwcml2YXRlOgorICAvLyBIYWNrOiBQYXJzZUluZm9UcmVlIGRlY2xhcmVzIFRleHRGb3JtYXQgYXMgYSBmcmllbmQgd2hpY2ggc2hvdWxkIGV4dGVuZAorICAvLyB0aGUgZnJpZW5kc2hpcCB0byBUZXh0Rm9ybWF0OjpQYXJzZXI6OlBhcnNlckltcGwsIGJ1dCB1bmZvcnR1bmF0ZWx5IHNvbWUKKyAgLy8gb2xkIGNvbXBpbGVycyAoZS5nLiBHQ0MgMy40LjYpIGRvbid0IGltcGxlbWVudCB0aGlzIGNvcnJlY3RseS4gV2UgcHJvdmlkZQorICAvLyBoZWxwZXJzIGZvciBQYXJzZXJJbXBsIHRvIGNhbGwgbWV0aG9kcyBvZiBQYXJzZUluZm9UcmVlLgorICBzdGF0aWMgaW5saW5lIHZvaWQgUmVjb3JkTG9jYXRpb24oUGFyc2VJbmZvVHJlZSogaW5mb190cmVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBhcnNlTG9jYXRpb24gbG9jYXRpb24pOworICBzdGF0aWMgaW5saW5lIFBhcnNlSW5mb1RyZWUqIENyZWF0ZU5lc3RlZChQYXJzZUluZm9UcmVlKiBpbmZvX3RyZWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhUZXh0Rm9ybWF0KTsKK307CisKK2lubGluZSB2b2lkIFRleHRGb3JtYXQ6OlJlY29yZExvY2F0aW9uKFBhcnNlSW5mb1RyZWUqIGluZm9fdHJlZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQYXJzZUxvY2F0aW9uIGxvY2F0aW9uKSB7CisgIGluZm9fdHJlZS0+UmVjb3JkTG9jYXRpb24oZmllbGQsIGxvY2F0aW9uKTsKK30KKworCitpbmxpbmUgVGV4dEZvcm1hdDo6UGFyc2VJbmZvVHJlZSogVGV4dEZvcm1hdDo6Q3JlYXRlTmVzdGVkKAorICAgIFBhcnNlSW5mb1RyZWUqIGluZm9fdHJlZSwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICByZXR1cm4gaW5mb190cmVlLT5DcmVhdGVOZXN0ZWQoZmllbGQpOworfQorCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfVEVYVF9GT1JNQVRfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3RleHRfZm9ybWF0X3VuaXR0ZXN0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXh0X2Zvcm1hdF91bml0dGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ZDYxYmUxCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90ZXh0X2Zvcm1hdF91bml0dGVzdC5jYwpAQCAtMCwwICsxLDE0ODIgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGpzY2hvcnJAZ29vZ2xlLmNvbSAoSm9zZXBoIFNjaG9ycikKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3RleHRfZm9ybWF0Lmg+CisKKyNpbmNsdWRlIDxtYXRoLmg+CisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSA8bGltaXRzPgorI2luY2x1ZGUgPG1lbW9yeT4KKyNpZm5kZWYgX1NIQVJFRF9QVFJfSAorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaGFyZWRfcHRyLmg+CisjZW5kaWYKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9sb2dnaW5nLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2ZpbGUuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdF91dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X21zZXQucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfbXNldF93aXJlX2Zvcm1hdC5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby90b2tlbml6ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbV9pbXBsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbWF0aGxpbWl0cy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdWJzdGl0dXRlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZ29vZ2xldGVzdC5oPgorI2luY2x1ZGUgPGd0ZXN0L2d0ZXN0Lmg+CisKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCisvLyBDYW4ndCB1c2UgYW4gYW5vbnltb3VzIG5hbWVzcGFjZSBoZXJlIGR1ZSB0byBicm9rZW5uZXNzIG9mIFRydTY0IGNvbXBpbGVyLgorbmFtZXNwYWNlIHRleHRfZm9ybWF0X3VuaXR0ZXN0IHsKKworLy8gQSBiYXNpYyBzdHJpbmcgd2l0aCBkaWZmZXJlbnQgZXNjYXBhYmxlIGNoYXJhY3RlcnMgZm9yIHRlc3RpbmcuCitjb25zdCBzdHJpbmcga0VzY2FwZVRlc3RTdHJpbmcgPQorICAiXCJBIHN0cmluZyB3aXRoICcgY2hhcmFjdGVycyBcbiBhbmQgXHIgbmV3bGluZXMgYW5kIFx0IHRhYnMgYW5kIFwwMDEgIgorICAic2xhc2hlcyBcXCBhbmQgIG11bHRpcGxlICAgc3BhY2VzIjsKKworLy8gQSByZXByZXNlbnRhdGlvbiBvZiB0aGUgYWJvdmUgc3RyaW5nIHdpdGggYWxsIHRoZSBjaGFyYWN0ZXJzIGVzY2FwZWQuCitjb25zdCBzdHJpbmcga0VzY2FwZVRlc3RTdHJpbmdFc2NhcGVkID0KKyAgIlwiXFxcIkEgc3RyaW5nIHdpdGggXFwnIGNoYXJhY3RlcnMgXFxuIGFuZCBcXHIgbmV3bGluZXMgIgorICAiYW5kIFxcdCB0YWJzIGFuZCBcXDAwMSBzbGFzaGVzIFxcXFwgYW5kICBtdWx0aXBsZSAgIHNwYWNlc1wiIjsKKworY2xhc3MgVGV4dEZvcm1hdFRlc3QgOiBwdWJsaWMgdGVzdGluZzo6VGVzdCB7CisgcHVibGljOgorICBzdGF0aWMgdm9pZCBTZXRVcFRlc3RDYXNlKCkgeworICAgIEdPT0dMRV9DSEVDS19PSyhGaWxlOjpHZXRDb250ZW50cygKKyAgICAgICAgVGVzdFNvdXJjZURpcigpICsKKyAgICAgICAgICAgICIvZ29vZ2xlL3Byb3RvYnVmLyIKKyAgICAgICAgICAgICJ0ZXN0ZGF0YS90ZXh0X2Zvcm1hdF91bml0dGVzdF9kYXRhX29uZW9mX2ltcGxlbWVudGVkLnR4dCIsCisgICAgICAgICZzdGF0aWNfcHJvdG9fZGVidWdfc3RyaW5nXywgdHJ1ZSkpOworICB9CisKKyAgVGV4dEZvcm1hdFRlc3QoKSA6IHByb3RvX2RlYnVnX3N0cmluZ18oc3RhdGljX3Byb3RvX2RlYnVnX3N0cmluZ18pIHt9CisKKyBwcm90ZWN0ZWQ6CisgIC8vIERlYnVnIHN0cmluZyByZWFkIGZyb20gdGV4dF9mb3JtYXRfdW5pdHRlc3RfZGF0YS50eHQuCisgIGNvbnN0IHN0cmluZyBwcm90b19kZWJ1Z19zdHJpbmdfOworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIHByb3RvXzsKKworIHByaXZhdGU6CisgIHN0YXRpYyBzdHJpbmcgc3RhdGljX3Byb3RvX2RlYnVnX3N0cmluZ187Cit9Oworc3RyaW5nIFRleHRGb3JtYXRUZXN0OjpzdGF0aWNfcHJvdG9fZGVidWdfc3RyaW5nXzsKKworY2xhc3MgVGV4dEZvcm1hdEV4dGVuc2lvbnNUZXN0IDogcHVibGljIHRlc3Rpbmc6OlRlc3QgeworIHB1YmxpYzoKKyAgc3RhdGljIHZvaWQgU2V0VXBUZXN0Q2FzZSgpIHsKKyAgICBHT09HTEVfQ0hFQ0tfT0soRmlsZTo6R2V0Q29udGVudHMoVGVzdFNvdXJjZURpcigpICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIi9nb29nbGUvcHJvdG9idWYvdGVzdGRhdGEvIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGV4dF9mb3JtYXRfdW5pdHRlc3RfZXh0ZW5zaW9uc19kYXRhLnR4dCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnN0YXRpY19wcm90b19kZWJ1Z19zdHJpbmdfLCB0cnVlKSk7CisgIH0KKworICBUZXh0Rm9ybWF0RXh0ZW5zaW9uc1Rlc3QoKQorICAgICAgOiBwcm90b19kZWJ1Z19zdHJpbmdfKHN0YXRpY19wcm90b19kZWJ1Z19zdHJpbmdfKSB7fQorCisgcHJvdGVjdGVkOgorICAvLyBEZWJ1ZyBzdHJpbmcgcmVhZCBmcm9tIHRleHRfZm9ybWF0X3VuaXR0ZXN0X2RhdGEudHh0LgorICBjb25zdCBzdHJpbmcgcHJvdG9fZGVidWdfc3RyaW5nXzsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIHByb3RvXzsKKworIHByaXZhdGU6CisgIHN0YXRpYyBzdHJpbmcgc3RhdGljX3Byb3RvX2RlYnVnX3N0cmluZ187Cit9Oworc3RyaW5nIFRleHRGb3JtYXRFeHRlbnNpb25zVGVzdDo6c3RhdGljX3Byb3RvX2RlYnVnX3N0cmluZ187CisKKworVEVTVF9GKFRleHRGb3JtYXRUZXN0LCBCYXNpYykgeworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZwcm90b18pOworICBFWFBFQ1RfRVEocHJvdG9fZGVidWdfc3RyaW5nXywgcHJvdG9fLkRlYnVnU3RyaW5nKCkpOworfQorCitURVNUX0YoVGV4dEZvcm1hdEV4dGVuc2lvbnNUZXN0LCBFeHRlbnNpb25zKSB7CisgIFRlc3RVdGlsOjpTZXRBbGxFeHRlbnNpb25zKCZwcm90b18pOworICBFWFBFQ1RfRVEocHJvdG9fZGVidWdfc3RyaW5nXywgcHJvdG9fLkRlYnVnU3RyaW5nKCkpOworfQorCitURVNUX0YoVGV4dEZvcm1hdFRlc3QsIFNob3J0RGVidWdTdHJpbmcpIHsKKyAgcHJvdG9fLnNldF9vcHRpb25hbF9pbnQzMigxKTsKKyAgcHJvdG9fLnNldF9vcHRpb25hbF9zdHJpbmcoImhlbGxvIik7CisgIHByb3RvXy5tdXRhYmxlX29wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCktPnNldF9iYigyKTsKKyAgcHJvdG9fLm11dGFibGVfb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlKCk7CisKKyAgRVhQRUNUX0VRKCJvcHRpb25hbF9pbnQzMjogMSBvcHRpb25hbF9zdHJpbmc6IFwiaGVsbG9cIiAiCisgICAgICAgICAgICAib3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgeyBiYjogMiB9ICIKKyAgICAgICAgICAgICJvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgeyB9IiwKKyAgICAgICAgICAgIHByb3RvXy5TaG9ydERlYnVnU3RyaW5nKCkpOworfQorCitURVNUX0YoVGV4dEZvcm1hdFRlc3QsIFNob3J0UHJpbWl0aXZlUmVwZWF0ZWRzKSB7CisgIHByb3RvXy5zZXRfb3B0aW9uYWxfaW50MzIoMTIzKTsKKyAgcHJvdG9fLmFkZF9yZXBlYXRlZF9pbnQzMig0NTYpOworICBwcm90b18uYWRkX3JlcGVhdGVkX2ludDMyKDc4OSk7CisgIHByb3RvXy5hZGRfcmVwZWF0ZWRfc3RyaW5nKCJmb28iKTsKKyAgcHJvdG9fLmFkZF9yZXBlYXRlZF9zdHJpbmcoImJhciIpOworICBwcm90b18uYWRkX3JlcGVhdGVkX25lc3RlZF9tZXNzYWdlKCktPnNldF9iYigyKTsKKyAgcHJvdG9fLmFkZF9yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSgpLT5zZXRfYmIoMyk7CisgIHByb3RvXy5hZGRfcmVwZWF0ZWRfbmVzdGVkX2VudW0odW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6Rk9PKTsKKyAgcHJvdG9fLmFkZF9yZXBlYXRlZF9uZXN0ZWRfZW51bSh1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpCQVIpOworCisgIFRleHRGb3JtYXQ6OlByaW50ZXIgcHJpbnRlcjsKKyAgcHJpbnRlci5TZXRVc2VTaG9ydFJlcGVhdGVkUHJpbWl0aXZlcyh0cnVlKTsKKyAgc3RyaW5nIHRleHQ7CisgIHByaW50ZXIuUHJpbnRUb1N0cmluZyhwcm90b18sICZ0ZXh0KTsKKworICBFWFBFQ1RfRVEoIm9wdGlvbmFsX2ludDMyOiAxMjNcbiIKKyAgICAgICAgICAgICJyZXBlYXRlZF9pbnQzMjogWzQ1NiwgNzg5XVxuIgorICAgICAgICAgICAgInJlcGVhdGVkX3N0cmluZzogXCJmb29cIlxuIgorICAgICAgICAgICAgInJlcGVhdGVkX3N0cmluZzogXCJiYXJcIlxuIgorICAgICAgICAgICAgInJlcGVhdGVkX25lc3RlZF9tZXNzYWdlIHtcbiAgYmI6IDJcbn1cbiIKKyAgICAgICAgICAgICJyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSB7XG4gIGJiOiAzXG59XG4iCisgICAgICAgICAgICAicmVwZWF0ZWRfbmVzdGVkX2VudW06IFtGT08sIEJBUl1cbiIsCisgICAgICAgICAgICB0ZXh0KTsKKworICAvLyBUcnkgaW4gc2luZ2xlLWxpbmUgbW9kZS4KKyAgcHJpbnRlci5TZXRTaW5nbGVMaW5lTW9kZSh0cnVlKTsKKyAgcHJpbnRlci5QcmludFRvU3RyaW5nKHByb3RvXywgJnRleHQpOworCisgIEVYUEVDVF9FUSgib3B0aW9uYWxfaW50MzI6IDEyMyAiCisgICAgICAgICAgICAicmVwZWF0ZWRfaW50MzI6IFs0NTYsIDc4OV0gIgorICAgICAgICAgICAgInJlcGVhdGVkX3N0cmluZzogXCJmb29cIiAiCisgICAgICAgICAgICAicmVwZWF0ZWRfc3RyaW5nOiBcImJhclwiICIKKyAgICAgICAgICAgICJyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSB7IGJiOiAyIH0gIgorICAgICAgICAgICAgInJlcGVhdGVkX25lc3RlZF9tZXNzYWdlIHsgYmI6IDMgfSAiCisgICAgICAgICAgICAicmVwZWF0ZWRfbmVzdGVkX2VudW06IFtGT08sIEJBUl0gIiwKKyAgICAgICAgICAgIHRleHQpOworfQorCisKK1RFU1RfRihUZXh0Rm9ybWF0VGVzdCwgU3RyaW5nRXNjYXBlKSB7CisgIC8vIFNldCB0aGUgc3RyaW5nIHZhbHVlIHRvIHRlc3QuCisgIHByb3RvXy5zZXRfb3B0aW9uYWxfc3RyaW5nKGtFc2NhcGVUZXN0U3RyaW5nKTsKKworICAvLyBHZXQgdGhlIERlYnVnU3RyaW5nIGZyb20gdGhlIHByb3RvLgorICBzdHJpbmcgZGVidWdfc3RyaW5nID0gcHJvdG9fLkRlYnVnU3RyaW5nKCk7CisgIHN0cmluZyB1dGY4X2RlYnVnX3N0cmluZyA9IHByb3RvXy5VdGY4RGVidWdTdHJpbmcoKTsKKworICAvLyBIYXJkY29kZSBhIGNvcnJlY3QgdmFsdWUgdG8gdGVzdCBhZ2FpbnN0LgorICBzdHJpbmcgY29ycmVjdF9zdHJpbmcgPSAib3B0aW9uYWxfc3RyaW5nOiAiCisgICAgICArIGtFc2NhcGVUZXN0U3RyaW5nRXNjYXBlZAorICAgICAgICsgIlxuIjsKKworICAvLyBDb21wYXJlLgorICBFWFBFQ1RfRVEoY29ycmVjdF9zdHJpbmcsIGRlYnVnX3N0cmluZyk7CisgIC8vIFVURi04IHN0cmluZyBpcyB0aGUgc2FtZSBhcyBub24tVVRGLTggYmVjYXVzZQorICAvLyB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbnRhaW5zIG5vIFVURi04IHRleHQuCisgIEVYUEVDVF9FUShjb3JyZWN0X3N0cmluZywgdXRmOF9kZWJ1Z19zdHJpbmcpOworCisgIHN0cmluZyBleHBlY3RlZF9zaG9ydF9kZWJ1Z19zdHJpbmcgPSAib3B0aW9uYWxfc3RyaW5nOiAiCisgICAgICArIGtFc2NhcGVUZXN0U3RyaW5nRXNjYXBlZDsKKyAgRVhQRUNUX0VRKGV4cGVjdGVkX3Nob3J0X2RlYnVnX3N0cmluZywgcHJvdG9fLlNob3J0RGVidWdTdHJpbmcoKSk7Cit9CisKK1RFU1RfRihUZXh0Rm9ybWF0VGVzdCwgVXRmOERlYnVnU3RyaW5nKSB7CisgIC8vIFNldCB0aGUgc3RyaW5nIHZhbHVlIHRvIHRlc3QuCisgIHByb3RvXy5zZXRfb3B0aW9uYWxfc3RyaW5nKCJcMzUwXDI2MFwyNjdcMzQ2XDI1NVwyMTQiKTsKKyAgcHJvdG9fLnNldF9vcHRpb25hbF9ieXRlcygiXDM1MFwyNjBcMjY3XDM0NlwyNTVcMjE0Iik7CisKKyAgLy8gR2V0IHRoZSBEZWJ1Z1N0cmluZyBmcm9tIHRoZSBwcm90by4KKyAgc3RyaW5nIGRlYnVnX3N0cmluZyA9IHByb3RvXy5EZWJ1Z1N0cmluZygpOworICBzdHJpbmcgdXRmOF9kZWJ1Z19zdHJpbmcgPSBwcm90b18uVXRmOERlYnVnU3RyaW5nKCk7CisKKyAgLy8gSGFyZGNvZGUgYSBjb3JyZWN0IHZhbHVlIHRvIHRlc3QgYWdhaW5zdC4KKyAgc3RyaW5nIGNvcnJlY3RfdXRmOF9zdHJpbmcgPQorICAgICAgIm9wdGlvbmFsX3N0cmluZzogIgorICAgICAgIlwiXDM1MFwyNjBcMjY3XDM0NlwyNTVcMjE0XCIiCisgICAgICAiXG4iCisgICAgICAib3B0aW9uYWxfYnl0ZXM6ICIKKyAgICAgICJcIlxcMzUwXFwyNjBcXDI2N1xcMzQ2XFwyNTVcXDIxNFwiIgorICAgICAgIlxuIjsKKyAgc3RyaW5nIGNvcnJlY3Rfc3RyaW5nID0KKyAgICAgICJvcHRpb25hbF9zdHJpbmc6ICIKKyAgICAgICJcIlxcMzUwXFwyNjBcXDI2N1xcMzQ2XFwyNTVcXDIxNFwiIgorICAgICAgIlxuIgorICAgICAgIm9wdGlvbmFsX2J5dGVzOiAiCisgICAgICAiXCJcXDM1MFxcMjYwXFwyNjdcXDM0NlxcMjU1XFwyMTRcIiIKKyAgICAgICJcbiI7CisKKyAgLy8gQ29tcGFyZS4KKyAgRVhQRUNUX0VRKGNvcnJlY3RfdXRmOF9zdHJpbmcsIHV0ZjhfZGVidWdfc3RyaW5nKTsKKyAgRVhQRUNUX0VRKGNvcnJlY3Rfc3RyaW5nLCBkZWJ1Z19zdHJpbmcpOworfQorCitURVNUX0YoVGV4dEZvcm1hdFRlc3QsIFByaW50VW5rbm93bkZpZWxkcykgeworICAvLyBUZXN0IHByaW50aW5nIG9mIHVua25vd24gZmllbGRzIGluIGEgbWVzc2FnZS4KKworICB1bml0dGVzdDo6VGVzdEVtcHR5TWVzc2FnZSBtZXNzYWdlOworICBVbmtub3duRmllbGRTZXQqIHVua25vd25fZmllbGRzID0gbWVzc2FnZS5tdXRhYmxlX3Vua25vd25fZmllbGRzKCk7CisKKyAgdW5rbm93bl9maWVsZHMtPkFkZFZhcmludCg1LCAxKTsKKyAgdW5rbm93bl9maWVsZHMtPkFkZEZpeGVkMzIoNSwgMik7CisgIHVua25vd25fZmllbGRzLT5BZGRGaXhlZDY0KDUsIDMpOworICB1bmtub3duX2ZpZWxkcy0+QWRkTGVuZ3RoRGVsaW1pdGVkKDUsICI0Iik7CisgIHVua25vd25fZmllbGRzLT5BZGRHcm91cCg1KS0+QWRkVmFyaW50KDEwLCA1KTsKKworICB1bmtub3duX2ZpZWxkcy0+QWRkVmFyaW50KDgsIDEpOworICB1bmtub3duX2ZpZWxkcy0+QWRkVmFyaW50KDgsIDIpOworICB1bmtub3duX2ZpZWxkcy0+QWRkVmFyaW50KDgsIDMpOworCisgIEVYUEVDVF9FUSgKKyAgICAiNTogMVxuIgorICAgICI1OiAweDAwMDAwMDAyXG4iCisgICAgIjU6IDB4MDAwMDAwMDAwMDAwMDAwM1xuIgorICAgICI1OiBcIjRcIlxuIgorICAgICI1IHtcbiIKKyAgICAiICAxMDogNVxuIgorICAgICJ9XG4iCisgICAgIjg6IDFcbiIKKyAgICAiODogMlxuIgorICAgICI4OiAzXG4iLAorICAgIG1lc3NhZ2UuRGVidWdTdHJpbmcoKSk7Cit9CisKK1RFU1RfRihUZXh0Rm9ybWF0VGVzdCwgUHJpbnRVbmtub3duRmllbGRzSGlkZGVuKSB7CisgIC8vIFRlc3QgcHJpbnRpbmcgb2YgdW5rbm93biBmaWVsZHMgaW4gYSBtZXNzYWdlIHdoZW4gc3VwcHJlc3NlZC4KKworICB1bml0dGVzdDo6T25lU3RyaW5nIG1lc3NhZ2U7CisgIG1lc3NhZ2Uuc2V0X2RhdGEoImRhdGEiKTsKKyAgVW5rbm93bkZpZWxkU2V0KiB1bmtub3duX2ZpZWxkcyA9IG1lc3NhZ2UubXV0YWJsZV91bmtub3duX2ZpZWxkcygpOworCisgIHVua25vd25fZmllbGRzLT5BZGRWYXJpbnQoNSwgMSk7CisgIHVua25vd25fZmllbGRzLT5BZGRGaXhlZDMyKDUsIDIpOworICB1bmtub3duX2ZpZWxkcy0+QWRkRml4ZWQ2NCg1LCAzKTsKKyAgdW5rbm93bl9maWVsZHMtPkFkZExlbmd0aERlbGltaXRlZCg1LCAiNCIpOworICB1bmtub3duX2ZpZWxkcy0+QWRkR3JvdXAoNSktPkFkZFZhcmludCgxMCwgNSk7CisKKyAgdW5rbm93bl9maWVsZHMtPkFkZFZhcmludCg4LCAxKTsKKyAgdW5rbm93bl9maWVsZHMtPkFkZFZhcmludCg4LCAyKTsKKyAgdW5rbm93bl9maWVsZHMtPkFkZFZhcmludCg4LCAzKTsKKworICBUZXh0Rm9ybWF0OjpQcmludGVyIHByaW50ZXI7CisgIHByaW50ZXIuU2V0SGlkZVVua25vd25GaWVsZHModHJ1ZSk7CisgIHN0cmluZyBvdXRwdXQ7CisgIHByaW50ZXIuUHJpbnRUb1N0cmluZyhtZXNzYWdlLCAmb3V0cHV0KTsKKworICBFWFBFQ1RfRVEoImRhdGE6IFwiZGF0YVwiXG4iLCBvdXRwdXQpOworfQorCitURVNUX0YoVGV4dEZvcm1hdFRlc3QsIFByaW50VW5rbm93bk1lc3NhZ2UpIHsKKyAgLy8gVGVzdCBoZXVyaXN0aWMgcHJpbnRpbmcgb2YgbWVzc2FnZXMgaW4gYW4gVW5rbm93bkZpZWxkU2V0LgorCisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKworICAvLyBDYXNlcyB3aGljaCBzaG91bGQgbm90IGJlIGludGVycHJldGVkIGFzIHN1Yi1tZXNzYWdlcy4KKworICAvLyAnYScgaXMgYSB2YWxpZCBGSVhFRDY0IHRhZywgc28gZm9yIHRoZSBzdHJpbmcgdG8gYmUgcGFyc2VhYmxlIGFzIGEgbWVzc2FnZQorICAvLyBpdCBzaG91bGQgYmUgZm9sbG93ZWQgYnkgOCBieXRlcy4gIFNpbmNlIHRoaXMgc3RyaW5nIG9ubHkgaGFzIHR3bworICAvLyBzdWJzZXF1ZW50IGJ5dGVzLCBpdCBzaG91bGQgYmUgdHJlYXRlZCBhcyBhIHN0cmluZy4KKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfc3RyaW5nKCJhYmMiKTsKKworICAvLyAnZCcgaGFwcGVucyB0byBiZSBhIHZhbGlkIEVOREdST1VQIHRhZy4gIFNvLAorICAvLyBVbmtub3duRmllbGRTZXQ6Ok1lcmdlRnJvbUNvZGVkU3RyZWFtKCkgd2lsbCBzdWNjZXNzZnVsbHkgcGFyc2UgImRlZiIsIGJ1dAorICAvLyB0aGUgQ29uc3VtZWRFbnRpcmVNZXNzYWdlKCkgY2hlY2sgc2hvdWxkIGZhaWwuCisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX3N0cmluZygiZGVmIik7CisKKyAgLy8gQSB6ZXJvLWxlbmd0aCBzdHJpbmcgc2hvdWxkIG5ldmVyIGJlIGludGVycHJldGVkIGFzIGEgbWVzc2FnZSBldmVuIHRob3VnaAorICAvLyBpdCBpcyB0ZWNobmljYWxseSB2YWxpZCBhcyBvbmUuCisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX3N0cmluZygiIik7CisKKyAgLy8gQ2FzZSB3aGljaCBzaG91bGQgYmUgaW50ZXJwcmV0ZWQgYXMgYSBzdWItbWVzc2FnZS4KKworICAvLyBBbiBhY3R1YWwgbmVzdGVkIG1lc3NhZ2Ugd2l0aCBjb250ZW50IHNob3VsZCBhbHdheXMgYmUgaW50ZXJwcmV0ZWQgYXMgYQorICAvLyBuZXN0ZWQgbWVzc2FnZS4KKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UoKS0+c2V0X2JiKDEyMyk7CisKKyAgc3RyaW5nIGRhdGE7CisgIG1lc3NhZ2UuU2VyaWFsaXplVG9TdHJpbmcoJmRhdGEpOworCisgIHN0cmluZyB0ZXh0OworICBVbmtub3duRmllbGRTZXQgdW5rbm93bl9maWVsZHM7CisgIEVYUEVDVF9UUlVFKHVua25vd25fZmllbGRzLlBhcnNlRnJvbVN0cmluZyhkYXRhKSk7CisgIEVYUEVDVF9UUlVFKFRleHRGb3JtYXQ6OlByaW50VW5rbm93bkZpZWxkc1RvU3RyaW5nKHVua25vd25fZmllbGRzLCAmdGV4dCkpOworICBFWFBFQ1RfRVEoCisgICAgIjQ0OiBcImFiY1wiXG4iCisgICAgIjQ0OiBcImRlZlwiXG4iCisgICAgIjQ0OiBcIlwiXG4iCisgICAgIjQ4IHtcbiIKKyAgICAiICAxOiAxMjNcbiIKKyAgICAifVxuIiwKKyAgICB0ZXh0KTsKK30KKworVEVTVF9GKFRleHRGb3JtYXRUZXN0LCBQcmludE1lc3NhZ2VXaXRoSW5kZW50KSB7CisgIC8vIFRlc3QgYWRkaW5nIGFuIGluaXRpYWwgaW5kZW50IHRvIHByaW50aW5nLgorCisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9zdHJpbmcoImFiYyIpOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9zdHJpbmcoImRlZiIpOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSgpLT5zZXRfYmIoMTIzKTsKKworICBzdHJpbmcgdGV4dDsKKyAgVGV4dEZvcm1hdDo6UHJpbnRlciBwcmludGVyOworICBwcmludGVyLlNldEluaXRpYWxJbmRlbnRMZXZlbCgxKTsKKyAgRVhQRUNUX1RSVUUocHJpbnRlci5QcmludFRvU3RyaW5nKG1lc3NhZ2UsICZ0ZXh0KSk7CisgIEVYUEVDVF9FUSgKKyAgICAiICByZXBlYXRlZF9zdHJpbmc6IFwiYWJjXCJcbiIKKyAgICAiICByZXBlYXRlZF9zdHJpbmc6IFwiZGVmXCJcbiIKKyAgICAiICByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSB7XG4iCisgICAgIiAgICBiYjogMTIzXG4iCisgICAgIiAgfVxuIiwKKyAgICB0ZXh0KTsKK30KKworVEVTVF9GKFRleHRGb3JtYXRUZXN0LCBQcmludE1lc3NhZ2VTaW5nbGVMaW5lKSB7CisgIC8vIFRlc3QgcHJpbnRpbmcgYSBtZXNzYWdlIG9uIGEgc2luZ2xlIGxpbmUuCisKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlOworCisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX3N0cmluZygiYWJjIik7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX3N0cmluZygiZGVmIik7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX25lc3RlZF9tZXNzYWdlKCktPnNldF9iYigxMjMpOworCisgIHN0cmluZyB0ZXh0OworICBUZXh0Rm9ybWF0OjpQcmludGVyIHByaW50ZXI7CisgIHByaW50ZXIuU2V0SW5pdGlhbEluZGVudExldmVsKDEpOworICBwcmludGVyLlNldFNpbmdsZUxpbmVNb2RlKHRydWUpOworICBFWFBFQ1RfVFJVRShwcmludGVyLlByaW50VG9TdHJpbmcobWVzc2FnZSwgJnRleHQpKTsKKyAgRVhQRUNUX0VRKAorICAgICIgIHJlcGVhdGVkX3N0cmluZzogXCJhYmNcIiByZXBlYXRlZF9zdHJpbmc6IFwiZGVmXCIgIgorICAgICJyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSB7IGJiOiAxMjMgfSAiLAorICAgIHRleHQpOworfQorCitURVNUX0YoVGV4dEZvcm1hdFRlc3QsIFByaW50QnVmZmVyVG9vU21hbGwpIHsKKyAgLy8gVGVzdCBwcmludGluZyBhIG1lc3NhZ2UgdG8gYSBidWZmZXIgdGhhdCBpcyB0b28gc21hbGwuCisKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlOworCisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX3N0cmluZygiYWJjIik7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX3N0cmluZygiZGVmIik7CisKKyAgY2hhciBidWZmZXJbMV0gPSAiIjsKKyAgaW86OkFycmF5T3V0cHV0U3RyZWFtIG91dHB1dF9zdHJlYW0oYnVmZmVyLCAxKTsKKyAgRVhQRUNUX0ZBTFNFKFRleHRGb3JtYXQ6OlByaW50KG1lc3NhZ2UsICZvdXRwdXRfc3RyZWFtKSk7CisgIEVYUEVDVF9FUShidWZmZXJbMF0sICdyJyk7CisgIEVYUEVDVF9FUShvdXRwdXRfc3RyZWFtLkJ5dGVDb3VudCgpLCAxKTsKK30KKworLy8gQSBwcmludGVyIHRoYXQgYXBwZW5kcyAndScgdG8gYWxsIHVuc2lnbmVkIGludDMyLgorY2xhc3MgQ3VzdG9tVUludDMyRmllbGRWYWx1ZVByaW50ZXIgOiBwdWJsaWMgVGV4dEZvcm1hdDo6RmllbGRWYWx1ZVByaW50ZXIgeworIHB1YmxpYzoKKyAgdmlydHVhbCBzdHJpbmcgUHJpbnRVSW50MzIodWludDMyIHZhbCkgY29uc3QgeworICAgIHJldHVybiBTdHJDYXQoRmllbGRWYWx1ZVByaW50ZXI6OlByaW50VUludDMyKHZhbCksICJ1Iik7CisgIH0KK307CisKK1RFU1RfRihUZXh0Rm9ybWF0VGVzdCwgRGVmYXVsdEN1c3RvbUZpZWxkUHJpbnRlcikgeworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisKKyAgbWVzc2FnZS5zZXRfb3B0aW9uYWxfdWludDMyKDQyKTsKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfdWludDMyKDEpOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF91aW50MzIoMik7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX3VpbnQzMigzKTsKKworICBUZXh0Rm9ybWF0OjpQcmludGVyIHByaW50ZXI7CisgIHByaW50ZXIuU2V0RGVmYXVsdEZpZWxkVmFsdWVQcmludGVyKG5ldyBDdXN0b21VSW50MzJGaWVsZFZhbHVlUHJpbnRlcigpKTsKKyAgLy8gTGV0J3Mgc2VlIGlmIHRoYXQgd29ya3Mgd2VsbCB0b2dldGhlciB3aXRoIHRoZSByZXBlYXRlZCBwcmltaXRpdmVzOgorICBwcmludGVyLlNldFVzZVNob3J0UmVwZWF0ZWRQcmltaXRpdmVzKHRydWUpOworICBzdHJpbmcgdGV4dDsKKyAgcHJpbnRlci5QcmludFRvU3RyaW5nKG1lc3NhZ2UsICZ0ZXh0KTsKKyAgRVhQRUNUX0VRKCJvcHRpb25hbF91aW50MzI6IDQydVxucmVwZWF0ZWRfdWludDMyOiBbMXUsIDJ1LCAzdV1cbiIsIHRleHQpOworfQorCitjbGFzcyBDdXN0b21JbnQzMkZpZWxkVmFsdWVQcmludGVyIDogcHVibGljIFRleHRGb3JtYXQ6OkZpZWxkVmFsdWVQcmludGVyIHsKKyBwdWJsaWM6CisgIHZpcnR1YWwgc3RyaW5nIFByaW50SW50MzIoaW50MzIgdmFsKSBjb25zdCB7CisgICAgcmV0dXJuIFN0ckNhdCgidmFsdWUtaXMoIiwgRmllbGRWYWx1ZVByaW50ZXI6OlByaW50SW50MzIodmFsKSwgIikiKTsKKyAgfQorfTsKKworVEVTVF9GKFRleHRGb3JtYXRUZXN0LCBGaWVsZFNwZWNpZmljQ3VzdG9tUHJpbnRlcikgeworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisKKyAgbWVzc2FnZS5zZXRfb3B0aW9uYWxfaW50MzIoNDIpOyAgLy8gVGhpcyB3aWxsIGJlIGhhbmRsZWQgYnkgb3VyIFByaW50ZXIuCisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX2ludDMyKDQyKTsgIC8vIFRoaXMgd2lsbCBiZSBwcmludGVkIGFzIG51bWJlci4KKworICBUZXh0Rm9ybWF0OjpQcmludGVyIHByaW50ZXI7CisgIEVYUEVDVF9UUlVFKHByaW50ZXIuUmVnaXN0ZXJGaWVsZFZhbHVlUHJpbnRlcigKKyAgICAgIG1lc3NhZ2UuR2V0RGVzY3JpcHRvcigpLT5GaW5kRmllbGRCeU5hbWUoIm9wdGlvbmFsX2ludDMyIiksCisgICAgICBuZXcgQ3VzdG9tSW50MzJGaWVsZFZhbHVlUHJpbnRlcigpKSk7CisgIHN0cmluZyB0ZXh0OworICBwcmludGVyLlByaW50VG9TdHJpbmcobWVzc2FnZSwgJnRleHQpOworICBFWFBFQ1RfRVEoIm9wdGlvbmFsX2ludDMyOiB2YWx1ZS1pcyg0MilcbnJlcGVhdGVkX2ludDMyOiA0MlxuIiwgdGV4dCk7Cit9CisKK1RFU1RfRihUZXh0Rm9ybWF0VGVzdCwgRXJyb3JDYXNlc1JlZ2lzdGVyaW5nRmllbGRWYWx1ZVByaW50ZXJTaG91bGRGYWlsKSB7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKyAgVGV4dEZvcm1hdDo6UHJpbnRlciBwcmludGVyOworICAvLyBOVUxMIHByaW50ZXIuCisgIEVYUEVDVF9GQUxTRShwcmludGVyLlJlZ2lzdGVyRmllbGRWYWx1ZVByaW50ZXIoCisgICAgICBtZXNzYWdlLkdldERlc2NyaXB0b3IoKS0+RmluZEZpZWxkQnlOYW1lKCJvcHRpb25hbF9pbnQzMiIpLAorICAgICAgTlVMTCkpOworICAvLyBCZWNhdXNlIHJlZ2lzdHJhdGlvbiBmYWlscywgdGhlIG93bmVyc2hpcCBvZiB0aGlzIHByaW50ZXIgaXMgbmV2ZXIgdGFrZW4uCisgIFRleHRGb3JtYXQ6OkZpZWxkVmFsdWVQcmludGVyIG15X2ZpZWxkX3ByaW50ZXI7CisgIC8vIE5VTEwgZmllbGQKKyAgRVhQRUNUX0ZBTFNFKHByaW50ZXIuUmVnaXN0ZXJGaWVsZFZhbHVlUHJpbnRlcihOVUxMLCAmbXlfZmllbGRfcHJpbnRlcikpOworfQorCitjbGFzcyBDdXN0b21NZXNzYWdlRmllbGRWYWx1ZVByaW50ZXIgOiBwdWJsaWMgVGV4dEZvcm1hdDo6RmllbGRWYWx1ZVByaW50ZXIgeworIHB1YmxpYzoKKyAgdmlydHVhbCBzdHJpbmcgUHJpbnRJbnQzMihpbnQzMiB2KSBjb25zdCB7CisgICAgcmV0dXJuIFN0ckNhdChGaWVsZFZhbHVlUHJpbnRlcjo6UHJpbnRJbnQzMih2KSwgIiAgIyB4Iiwgc3RyaW5nczo6SGV4KHYpKTsKKyAgfQorCisgIHZpcnR1YWwgc3RyaW5nIFByaW50TWVzc2FnZVN0YXJ0KGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBmaWVsZF9pbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGZpZWxkX2NvdW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIHNpbmdsZV9saW5lX21vZGUpIGNvbnN0IHsKKyAgICBpZiAoc2luZ2xlX2xpbmVfbW9kZSkgeworICAgICAgcmV0dXJuICIgeyAiOworICAgIH0KKyAgICByZXR1cm4gU3RyQ2F0KAorICAgICAgICAiIHsgICMgIiwgbWVzc2FnZS5HZXREZXNjcmlwdG9yKCktPm5hbWUoKSwgIjogIiwgZmllbGRfaW5kZXgsICJcbiIpOworICB9Cit9OworCitURVNUX0YoVGV4dEZvcm1hdFRlc3QsIEN1c3RvbVByaW50ZXJGb3JDb21tZW50cykgeworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisgIG1lc3NhZ2UubXV0YWJsZV9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpOworICBtZXNzYWdlLm11dGFibGVfb3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UoKS0+c2V0X2QoNDIpOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSgpOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSgpOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSgpLT5zZXRfZCg0Myk7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX2ltcG9ydF9tZXNzYWdlKCktPnNldF9kKDQ0KTsKKyAgVGV4dEZvcm1hdDo6UHJpbnRlciBwcmludGVyOworICBDdXN0b21NZXNzYWdlRmllbGRWYWx1ZVByaW50ZXIgbXlfZmllbGRfcHJpbnRlcjsKKyAgcHJpbnRlci5TZXREZWZhdWx0RmllbGRWYWx1ZVByaW50ZXIobmV3IEN1c3RvbU1lc3NhZ2VGaWVsZFZhbHVlUHJpbnRlcigpKTsKKyAgc3RyaW5nIHRleHQ7CisgIHByaW50ZXIuUHJpbnRUb1N0cmluZyhtZXNzYWdlLCAmdGV4dCk7CisgIEVYUEVDVF9FUSgKKyAgICAgICJvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSB7ICAjIE5lc3RlZE1lc3NhZ2U6IC0xXG4iCisgICAgICAifVxuIgorICAgICAgIm9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlIHsgICMgSW1wb3J0TWVzc2FnZTogLTFcbiIKKyAgICAgICIgIGQ6IDQyICAjIHgyYVxuIgorICAgICAgIn1cbiIKKyAgICAgICJyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSB7ICAjIE5lc3RlZE1lc3NhZ2U6IDBcbiIKKyAgICAgICJ9XG4iCisgICAgICAicmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgeyAgIyBOZXN0ZWRNZXNzYWdlOiAxXG4iCisgICAgICAifVxuIgorICAgICAgInJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlIHsgICMgSW1wb3J0TWVzc2FnZTogMFxuIgorICAgICAgIiAgZDogNDMgICMgeDJiXG4iCisgICAgICAifVxuIgorICAgICAgInJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlIHsgICMgSW1wb3J0TWVzc2FnZTogMVxuIgorICAgICAgIiAgZDogNDQgICMgeDJjXG4iCisgICAgICAifVxuIiwKKyAgICAgIHRleHQpOworfQorCitjbGFzcyBDdXN0b21NdWx0aWxpbmVDb21tZW50UHJpbnRlciA6IHB1YmxpYyBUZXh0Rm9ybWF0OjpGaWVsZFZhbHVlUHJpbnRlciB7CisgcHVibGljOgorICB2aXJ0dWFsIHN0cmluZyBQcmludE1lc3NhZ2VTdGFydChjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZmllbGRfaW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBmaWVsZF9jb3VudCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBzaW5nbGVfbGluZV9jb21tZW50KSBjb25zdCB7CisgICAgcmV0dXJuIFN0ckNhdCgiIHsgICMgMVxuIiwgIiAgIyAyXG4iKTsKKyAgfQorfTsKKworVEVTVF9GKFRleHRGb3JtYXRUZXN0LCBDdXN0b21QcmludGVyRm9yTXVsdGlsaW5lQ29tbWVudHMpIHsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlOworICBtZXNzYWdlLm11dGFibGVfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKTsKKyAgbWVzc2FnZS5tdXRhYmxlX29wdGlvbmFsX2ltcG9ydF9tZXNzYWdlKCktPnNldF9kKDQyKTsKKyAgVGV4dEZvcm1hdDo6UHJpbnRlciBwcmludGVyOworICBDdXN0b21NZXNzYWdlRmllbGRWYWx1ZVByaW50ZXIgbXlfZmllbGRfcHJpbnRlcjsKKyAgcHJpbnRlci5TZXREZWZhdWx0RmllbGRWYWx1ZVByaW50ZXIobmV3IEN1c3RvbU11bHRpbGluZUNvbW1lbnRQcmludGVyKCkpOworICBzdHJpbmcgdGV4dDsKKyAgcHJpbnRlci5QcmludFRvU3RyaW5nKG1lc3NhZ2UsICZ0ZXh0KTsKKyAgRVhQRUNUX0VRKAorICAgICAgIm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlIHsgICMgMVxuIgorICAgICAgIiAgIyAyXG4iCisgICAgICAifVxuIgorICAgICAgIm9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlIHsgICMgMVxuIgorICAgICAgIiAgIyAyXG4iCisgICAgICAiICBkOiA0MlxuIgorICAgICAgIn1cbiIsCisgICAgICB0ZXh0KTsKK30KKworVEVTVF9GKFRleHRGb3JtYXRUZXN0LCBQYXJzZUJhc2ljKSB7CisgIGlvOjpBcnJheUlucHV0U3RyZWFtIGlucHV0X3N0cmVhbShwcm90b19kZWJ1Z19zdHJpbmdfLmRhdGEoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3RvX2RlYnVnX3N0cmluZ18uc2l6ZSgpKTsKKyAgVGV4dEZvcm1hdDo6UGFyc2UoJmlucHV0X3N0cmVhbSwgJnByb3RvXyk7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxGaWVsZHNTZXQocHJvdG9fKTsKK30KKworVEVTVF9GKFRleHRGb3JtYXRFeHRlbnNpb25zVGVzdCwgUGFyc2VFeHRlbnNpb25zKSB7CisgIGlvOjpBcnJheUlucHV0U3RyZWFtIGlucHV0X3N0cmVhbShwcm90b19kZWJ1Z19zdHJpbmdfLmRhdGEoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3RvX2RlYnVnX3N0cmluZ18uc2l6ZSgpKTsKKyAgVGV4dEZvcm1hdDo6UGFyc2UoJmlucHV0X3N0cmVhbSwgJnByb3RvXyk7CisgIFRlc3RVdGlsOjpFeHBlY3RBbGxFeHRlbnNpb25zU2V0KHByb3RvXyk7Cit9CisKK1RFU1RfRihUZXh0Rm9ybWF0VGVzdCwgUGFyc2VFbnVtRmllbGRGcm9tTnVtYmVyKSB7CisgIC8vIENyZWF0ZSBhIHBhcnNlIHN0cmluZyB3aXRoIGEgbnVtZXJpY2FsIHZhbHVlIGZvciBhbiBlbnVtIGZpZWxkLgorICBzdHJpbmcgcGFyc2Vfc3RyaW5nID0gc3RyaW5nczo6U3Vic3RpdHV0ZSgib3B0aW9uYWxfbmVzdGVkX2VudW06ICQwIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6QkFaKTsKKyAgRVhQRUNUX1RSVUUoVGV4dEZvcm1hdDo6UGFyc2VGcm9tU3RyaW5nKHBhcnNlX3N0cmluZywgJnByb3RvXykpOworICBFWFBFQ1RfVFJVRShwcm90b18uaGFzX29wdGlvbmFsX25lc3RlZF9lbnVtKCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6QkFaLCBwcm90b18ub3B0aW9uYWxfbmVzdGVkX2VudW0oKSk7Cit9CisKK1RFU1RfRihUZXh0Rm9ybWF0VGVzdCwgUGFyc2VFbnVtRmllbGRGcm9tTmVnYXRpdmVOdW1iZXIpIHsKKyAgQVNTRVJUX0xUKHVuaXR0ZXN0OjpTUEFSU0VfRSwgMCk7CisgIHN0cmluZyBwYXJzZV9zdHJpbmcgPSBzdHJpbmdzOjpTdWJzdGl0dXRlKCJzcGFyc2VfZW51bTogJDAiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0dGVzdDo6U1BBUlNFX0UpOworICB1bml0dGVzdDo6U3BhcnNlRW51bU1lc3NhZ2UgcHJvdG87CisgIEVYUEVDVF9UUlVFKFRleHRGb3JtYXQ6OlBhcnNlRnJvbVN0cmluZyhwYXJzZV9zdHJpbmcsICZwcm90bykpOworICBFWFBFQ1RfVFJVRShwcm90by5oYXNfc3BhcnNlX2VudW0oKSk7CisgIEVYUEVDVF9FUSh1bml0dGVzdDo6U1BBUlNFX0UsIHByb3RvLnNwYXJzZV9lbnVtKCkpOworfQorCitURVNUX0YoVGV4dEZvcm1hdFRlc3QsIFBhcnNlU3RyaW5nRXNjYXBlKSB7CisgIC8vIENyZWF0ZSBhIHBhcnNlIHN0cmluZyB3aXRoIGVzY3BhZWQgY2hhcmFjdGVycyBpbiBpdC4KKyAgc3RyaW5nIHBhcnNlX3N0cmluZyA9ICJvcHRpb25hbF9zdHJpbmc6ICIKKyAgICAgICsga0VzY2FwZVRlc3RTdHJpbmdFc2NhcGVkCisgICAgICArICJcbiI7CisKKyAgaW86OkFycmF5SW5wdXRTdHJlYW0gaW5wdXRfc3RyZWFtKHBhcnNlX3N0cmluZy5kYXRhKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJzZV9zdHJpbmcuc2l6ZSgpKTsKKyAgVGV4dEZvcm1hdDo6UGFyc2UoJmlucHV0X3N0cmVhbSwgJnByb3RvXyk7CisKKyAgLy8gQ29tcGFyZS4KKyAgRVhQRUNUX0VRKGtFc2NhcGVUZXN0U3RyaW5nLCBwcm90b18ub3B0aW9uYWxfc3RyaW5nKCkpOworfQorCitURVNUX0YoVGV4dEZvcm1hdFRlc3QsIFBhcnNlQ29uY2F0ZW5hdGVkU3RyaW5nKSB7CisgIC8vIENyZWF0ZSBhIHBhcnNlIHN0cmluZyB3aXRoIG11bHRpcGxlIHBhcnRzIG9uIG9uZSBsaW5lLgorICBzdHJpbmcgcGFyc2Vfc3RyaW5nID0gIm9wdGlvbmFsX3N0cmluZzogXCJmb29cIiBcImJhclwiXG4iOworCisgIGlvOjpBcnJheUlucHV0U3RyZWFtIGlucHV0X3N0cmVhbTEocGFyc2Vfc3RyaW5nLmRhdGEoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlX3N0cmluZy5zaXplKCkpOworICBUZXh0Rm9ybWF0OjpQYXJzZSgmaW5wdXRfc3RyZWFtMSwgJnByb3RvXyk7CisKKyAgLy8gQ29tcGFyZS4KKyAgRVhQRUNUX0VRKCJmb29iYXIiLCBwcm90b18ub3B0aW9uYWxfc3RyaW5nKCkpOworCisgIC8vIENyZWF0ZSBhIHBhcnNlIHN0cmluZyB3aXRoIG11bHRpcGxlIHBhcnRzIG9uIHNlcGFyYXRlIGxpbmVzLgorICBwYXJzZV9zdHJpbmcgPSAib3B0aW9uYWxfc3RyaW5nOiBcImZvb1wiXG4iCisgICAgICAgICAgICAgICAgICJcImJhclwiXG4iOworCisgIGlvOjpBcnJheUlucHV0U3RyZWFtIGlucHV0X3N0cmVhbTIocGFyc2Vfc3RyaW5nLmRhdGEoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlX3N0cmluZy5zaXplKCkpOworICBUZXh0Rm9ybWF0OjpQYXJzZSgmaW5wdXRfc3RyZWFtMiwgJnByb3RvXyk7CisKKyAgLy8gQ29tcGFyZS4KKyAgRVhQRUNUX0VRKCJmb29iYXIiLCBwcm90b18ub3B0aW9uYWxfc3RyaW5nKCkpOworfQorCitURVNUX0YoVGV4dEZvcm1hdFRlc3QsIFBhcnNlRmxvYXRXaXRoU3VmZml4KSB7CisgIC8vIFRlc3QgdGhhdCB3ZSBjYW4gcGFyc2UgYSBmbG9hdGluZy1wb2ludCB2YWx1ZSB3aXRoICdmJyBhcHBlbmRlZCB0byB0aGUKKyAgLy8gZW5kLiAgVGhpcyBpcyBuZWVkZWQgZm9yIGJhY2t3YXJkcy1jb21wYXRpYmlsaXR5IHdpdGggcHJvdG8xLgorCisgIC8vIEhhdmUgaXQgcGFyc2UgYSBmbG9hdCB3aXRoIHRoZSAnZicgc3VmZml4LgorICBzdHJpbmcgcGFyc2Vfc3RyaW5nID0gIm9wdGlvbmFsX2Zsb2F0OiAxLjBmXG4iOworCisgIGlvOjpBcnJheUlucHV0U3RyZWFtIGlucHV0X3N0cmVhbShwYXJzZV9zdHJpbmcuZGF0YSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2Vfc3RyaW5nLnNpemUoKSk7CisKKyAgVGV4dEZvcm1hdDo6UGFyc2UoJmlucHV0X3N0cmVhbSwgJnByb3RvXyk7CisKKyAgLy8gQ29tcGFyZS4KKyAgRVhQRUNUX0VRKDEuMCwgcHJvdG9fLm9wdGlvbmFsX2Zsb2F0KCkpOworfQorCitURVNUX0YoVGV4dEZvcm1hdFRlc3QsIFBhcnNlU2hvcnRSZXBlYXRlZEZvcm0pIHsKKyAgc3RyaW5nIHBhcnNlX3N0cmluZyA9CisgICAgICAvLyBNaXhlZCBzaG9ydC1mb3JtIGFuZCBsb25nLWZvcm0gYXJlIHNpbXBseSBjb25jYXRlbmF0ZWQuCisgICAgICAicmVwZWF0ZWRfaW50MzI6IDFcbiIKKyAgICAgICJyZXBlYXRlZF9pbnQzMjogWzQ1NiwgNzg5XVxuIgorICAgICAgInJlcGVhdGVkX25lc3RlZF9lbnVtOiBbICBGT08gLEJBUiwgIyBjb21tZW50XG4iCisgICAgICAiICAgICAgICAgICAgICAgICAgICAgICAgIDNdXG4iCisgICAgICAvLyBOb3RlIHRoYXQgd2hpbGUgdGhlIHByaW50ZXIgd29uJ3QgcHJpbnQgcmVwZWF0ZWQgc3RyaW5ncyBpbiBzaG9ydC1mb3JtLAorICAgICAgLy8gdGhlIHBhcnNlciB3aWxsIGFjY2VwdCB0aGVtLgorICAgICAgInJlcGVhdGVkX3N0cmluZzogWyBcImZvb1wiLCAnYmFyJyBdXG4iCisgICAgICAvLyBSZXBlYXRlZCBtZXNzYWdlCisgICAgICAicmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2U6IFsgeyBiYjogMSB9LCB7IGJiIDogMiB9XVxuIgorICAgICAgLy8gUmVwZWF0ZWQgZ3JvdXAKKyAgICAgICJSZXBlYXRlZEdyb3VwIFt7IGE6IDMgfSx7IGE6IDQgfV1cbiI7CisKKyAgQVNTRVJUX1RSVUUoVGV4dEZvcm1hdDo6UGFyc2VGcm9tU3RyaW5nKHBhcnNlX3N0cmluZywgJnByb3RvXykpOworCisgIEFTU0VSVF9FUSgzLCBwcm90b18ucmVwZWF0ZWRfaW50MzJfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEsIHByb3RvXy5yZXBlYXRlZF9pbnQzMigwKSk7CisgIEVYUEVDVF9FUSg0NTYsIHByb3RvXy5yZXBlYXRlZF9pbnQzMigxKSk7CisgIEVYUEVDVF9FUSg3ODksIHByb3RvXy5yZXBlYXRlZF9pbnQzMigyKSk7CisKKyAgQVNTRVJUX0VRKDMsIHByb3RvXy5yZXBlYXRlZF9uZXN0ZWRfZW51bV9zaXplKCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6Rk9PLCBwcm90b18ucmVwZWF0ZWRfbmVzdGVkX2VudW0oMCkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6QkFSLCBwcm90b18ucmVwZWF0ZWRfbmVzdGVkX2VudW0oMSkpOworICBFWFBFQ1RfRVEodW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6QkFaLCBwcm90b18ucmVwZWF0ZWRfbmVzdGVkX2VudW0oMikpOworCisgIEFTU0VSVF9FUSgyLCBwcm90b18ucmVwZWF0ZWRfc3RyaW5nX3NpemUoKSk7CisgIEVYUEVDVF9FUSgiZm9vIiwgcHJvdG9fLnJlcGVhdGVkX3N0cmluZygwKSk7CisgIEVYUEVDVF9FUSgiYmFyIiwgcHJvdG9fLnJlcGVhdGVkX3N0cmluZygxKSk7CisKKyAgQVNTRVJUX0VRKDIsIHByb3RvXy5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9zaXplKCkpOworICBFWFBFQ1RfRVEoMSwgcHJvdG9fLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlKDApLmJiKCkpOworICBFWFBFQ1RfRVEoMiwgcHJvdG9fLnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlKDEpLmJiKCkpOworCisgIEFTU0VSVF9FUSgyLCBwcm90b18ucmVwZWF0ZWRncm91cF9zaXplKCkpOworICBFWFBFQ1RfRVEoMywgcHJvdG9fLnJlcGVhdGVkZ3JvdXAoMCkuYSgpKTsKKyAgRVhQRUNUX0VRKDQsIHByb3RvXy5yZXBlYXRlZGdyb3VwKDEpLmEoKSk7Cit9CisKKworVEVTVF9GKFRleHRGb3JtYXRUZXN0LCBDb21tZW50cykgeworICAvLyBUZXN0IHRoYXQgY29tbWVudHMgYXJlIGlnbm9yZWQuCisKKyAgc3RyaW5nIHBhcnNlX3N0cmluZyA9ICJvcHRpb25hbF9pbnQzMjogMSAgIyBhIGNvbW1lbnRcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICJvcHRpb25hbF9pbnQ2NDogMiAgIyBhbm90aGVyIGNvbW1lbnQiOworCisgIGlvOjpBcnJheUlucHV0U3RyZWFtIGlucHV0X3N0cmVhbShwYXJzZV9zdHJpbmcuZGF0YSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2Vfc3RyaW5nLnNpemUoKSk7CisKKyAgVGV4dEZvcm1hdDo6UGFyc2UoJmlucHV0X3N0cmVhbSwgJnByb3RvXyk7CisKKyAgLy8gQ29tcGFyZS4KKyAgRVhQRUNUX0VRKDEsIHByb3RvXy5vcHRpb25hbF9pbnQzMigpKTsKKyAgRVhQRUNUX0VRKDIsIHByb3RvXy5vcHRpb25hbF9pbnQ2NCgpKTsKK30KKworVEVTVF9GKFRleHRGb3JtYXRUZXN0LCBPcHRpb25hbENvbG9uKSB7CisgIC8vIFRlc3QgdGhhdCB3ZSBjYW4gcGxhY2UgYSAnOicgYWZ0ZXIgdGhlIGZpZWxkIG5hbWUgb2YgYSBuZXN0ZWQgbWVzc2FnZSwKKyAgLy8gZXZlbiB0aG91Z2ggd2UgZG9uJ3QgaGF2ZSB0by4KKworICBzdHJpbmcgcGFyc2Vfc3RyaW5nID0gIm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlOiB7IGJiOiAxfVxuIjsKKworICBpbzo6QXJyYXlJbnB1dFN0cmVhbSBpbnB1dF9zdHJlYW0ocGFyc2Vfc3RyaW5nLmRhdGEoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlX3N0cmluZy5zaXplKCkpOworCisgIFRleHRGb3JtYXQ6OlBhcnNlKCZpbnB1dF9zdHJlYW0sICZwcm90b18pOworCisgIC8vIENvbXBhcmUuCisgIEVYUEVDVF9UUlVFKHByb3RvXy5oYXNfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKSk7CisgIEVYUEVDVF9FUSgxLCBwcm90b18ub3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKS5iYigpKTsKK30KKworLy8gU29tZSBwbGF0Zm9ybXMgKGUuZy4gV2luZG93cykgaW5zaXN0IG9uIHBhZGRpbmcgdGhlIGV4cG9uZW50IHRvIHRocmVlCisvLyBkaWdpdHMgd2hlbiBvbmUgb3IgdHdvIHdvdWxkIGJlIGp1c3QgZmluZS4KK3N0YXRpYyBzdHJpbmcgUmVtb3ZlUmVkdW5kYW50WmVyb3Moc3RyaW5nIHRleHQpIHsKKyAgdGV4dCA9IFN0cmluZ1JlcGxhY2UodGV4dCwgImUrMCIsICJlKyIsIHRydWUpOworICB0ZXh0ID0gU3RyaW5nUmVwbGFjZSh0ZXh0LCAiZS0wIiwgImUtIiwgdHJ1ZSk7CisgIHJldHVybiB0ZXh0OworfQorCitURVNUX0YoVGV4dEZvcm1hdFRlc3QsIFByaW50RXhvdGljKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKworICAvLyBOb3RlOiAgSW4gQywgYSBuZWdhdGl2ZSBpbnRlZ2VyIGxpdGVyYWwgaXMgYWN0dWFsbHkgdGhlIHVuYXJ5IG5lZ2F0aW9uCisgIC8vICAgb3BlcmF0b3IgYmVpbmcgYXBwbGllZCB0byBhIHBvc2l0aXZlIGludGVnZXIgbGl0ZXJhbCwgYW5kCisgIC8vICAgOTIyMzM3MjAzNjg1NDc3NTgwOCBpcyBvdXRzaWRlIHRoZSByYW5nZSBvZiBpbnQ2NC4gIEhvd2V2ZXIsIGl0IGlzIG5vdAorICAvLyAgIG91dHNpZGUgdGhlIHJhbmdlIG9mIHVpbnQ2NC4gIENvbmZ1c2luZ2x5LCB0aGlzIG1lYW5zIHRoYXQgZXZlcnl0aGluZworICAvLyAgIHdvcmtzIGlmIHdlIG1ha2UgdGhlIGxpdGVyYWwgdW5zaWduZWQsIGV2ZW4gdGhvdWdoIHdlIGFyZSBuZWdhdGluZyBpdC4KKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfaW50NjQoLUdPT0dMRV9VTE9OR0xPTkcoOTIyMzM3MjAzNjg1NDc3NTgwOCkpOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF91aW50NjQoR09PR0xFX1VMT05HTE9ORygxODQ0Njc0NDA3MzcwOTU1MTYxNSkpOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9kb3VibGUoMTIzLjQ1Nik7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX2RvdWJsZSgxLjIzZTIxKTsKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZG91YmxlKDEuMjNlLTE4KTsKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZG91YmxlKHN0ZDo6bnVtZXJpY19saW1pdHM8ZG91YmxlPjo6aW5maW5pdHkoKSk7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX2RvdWJsZSgtc3RkOjpudW1lcmljX2xpbWl0czxkb3VibGU+OjppbmZpbml0eSgpKTsKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZG91YmxlKHN0ZDo6bnVtZXJpY19saW1pdHM8ZG91YmxlPjo6cXVpZXRfTmFOKCkpOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9zdHJpbmcoc3RyaW5nKCJcMDAwXDAwMVxhXGJcZlxuXHJcdFx2XFxcJ1wiIiwgMTIpKTsKKworICAvLyBGdW4gc3Rvcnk6ICBXZSB1c2VkIHRvIHVzZSAxLjIzZTIyIGluc3RlYWQgb2YgMS4yM2UyMSBhYm92ZSwgYnV0IHRoaXMKKyAgLy8gICBzZWVtZWQgdG8gdHJpZ2dlciBhbiBvZGQgY2FzZSBvbiBNaW5HVy9HQ0MgMy40LjUgd2hlcmUgR0NDJ3MgcGFyc2luZyBvZgorICAvLyAgIHRoZSB2YWx1ZSBkaWZmZXJlZCBmcm9tIHN0cnRvZCgpJ3MgcGFyc2luZy4gIFRoYXQgaXMgdG8gc2F5LCB0aGUKKyAgLy8gICBmb2xsb3dpbmcgYXNzZXJ0aW9uIGZhaWxzIG9uIE1pbkdXOgorICAvLyAgICAgYXNzZXJ0KDEuMjNlMjIgPT0gc3RydG9kKCIxLjIzZTIyIiwgTlVMTCkpOworICAvLyAgIEFzIGEgcmVzdWx0LCBTaW1wbGVEdG9hKCkgd291bGQgcHJpbnQgdGhlIHZhbHVlIGFzCisgIC8vICAgIjEuMjMwMDAwMDAwMDAwMDAwMWUrMjIiIHRvIG1ha2Ugc3VyZSBzdHJ0b2QoKSBwcm9kdWNlIHRoZSBleGFjdCBzYW1lCisgIC8vICAgcmVzdWx0LiAgT3VyIGdvYWwgaXMgdG8gdGVzdCBydW50aW1lIHBhcnNpbmcsIG5vdCBjb21waWxlLXRpbWUgcGFyc2luZywKKyAgLy8gICBzbyB0aGlzIHdhc24ndCBvdXIgcHJvYmxlbS4gIEl0IHdhcyBmb3VuZCB0aGF0IHVzaW5nIDEuMjNlMjEgZGlkIG5vdAorICAvLyAgIGhhdmUgdGhpcyBwcm9ibGVtLCBzbyB3ZSBzd2l0Y2hlZCB0byB0aGF0IGluc3RlYWQuCisKKyAgRVhQRUNUX0VRKAorICAgICJyZXBlYXRlZF9pbnQ2NDogLTkyMjMzNzIwMzY4NTQ3NzU4MDhcbiIKKyAgICAicmVwZWF0ZWRfdWludDY0OiAxODQ0Njc0NDA3MzcwOTU1MTYxNVxuIgorICAgICJyZXBlYXRlZF9kb3VibGU6IDEyMy40NTZcbiIKKyAgICAicmVwZWF0ZWRfZG91YmxlOiAxLjIzZSsyMVxuIgorICAgICJyZXBlYXRlZF9kb3VibGU6IDEuMjNlLTE4XG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogaW5mXG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogLWluZlxuIgorICAgICJyZXBlYXRlZF9kb3VibGU6IG5hblxuIgorICAgICJyZXBlYXRlZF9zdHJpbmc6IFwiXFwwMDBcXDAwMVxcMDA3XFwwMTBcXDAxNFxcblxcclxcdFxcMDEzXFxcXFxcJ1xcXCJcIlxuIiwKKyAgICBSZW1vdmVSZWR1bmRhbnRaZXJvcyhtZXNzYWdlLkRlYnVnU3RyaW5nKCkpKTsKK30KKworVEVTVF9GKFRleHRGb3JtYXRUZXN0LCBQcmludEZsb2F0UHJlY2lzaW9uKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9mbG9hdCgxLjIpOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9mbG9hdCgxLjIzKTsKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZmxvYXQoMS4yMzQpOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9mbG9hdCgxLjIzNDUpOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9mbG9hdCgxLjIzNDU2KTsKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZmxvYXQoMS4yZTEwKTsKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZmxvYXQoMS4yM2UxMCk7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX2Zsb2F0KDEuMjM0ZTEwKTsKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZmxvYXQoMS4yMzQ1ZTEwKTsKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZmxvYXQoMS4yMzQ1NmUxMCk7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX2RvdWJsZSgxLjIpOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9kb3VibGUoMS4yMyk7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX2RvdWJsZSgxLjIzNCk7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX2RvdWJsZSgxLjIzNDUpOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9kb3VibGUoMS4yMzQ1Nik7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX2RvdWJsZSgxLjIzNDU2Nyk7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX2RvdWJsZSgxLjIzNDU2NzgpOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9kb3VibGUoMS4yMzQ1Njc4OSk7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX2RvdWJsZSgxLjIzNDU2Nzg5OCk7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX2RvdWJsZSgxLjIzNDU2Nzg5ODcpOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9kb3VibGUoMS4yMzQ1Njc4OTg3Nik7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX2RvdWJsZSgxLjIzNDU2Nzg5ODc2NSk7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX2RvdWJsZSgxLjIzNDU2Nzg5ODc2NTQpOworICBtZXNzYWdlLmFkZF9yZXBlYXRlZF9kb3VibGUoMS4yMzQ1Njc4OTg3NjU0Myk7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX2RvdWJsZSgxLjJlMTAwKTsKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZG91YmxlKDEuMjNlMTAwKTsKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZG91YmxlKDEuMjM0ZTEwMCk7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX2RvdWJsZSgxLjIzNDVlMTAwKTsKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZG91YmxlKDEuMjM0NTZlMTAwKTsKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZG91YmxlKDEuMjM0NTY3ZTEwMCk7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX2RvdWJsZSgxLjIzNDU2NzhlMTAwKTsKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZG91YmxlKDEuMjM0NTY3ODllMTAwKTsKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZG91YmxlKDEuMjM0NTY3ODk4ZTEwMCk7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX2RvdWJsZSgxLjIzNDU2Nzg5ODdlMTAwKTsKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZG91YmxlKDEuMjM0NTY3ODk4NzZlMTAwKTsKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZG91YmxlKDEuMjM0NTY3ODk4NzY1ZTEwMCk7CisgIG1lc3NhZ2UuYWRkX3JlcGVhdGVkX2RvdWJsZSgxLjIzNDU2Nzg5ODc2NTRlMTAwKTsKKyAgbWVzc2FnZS5hZGRfcmVwZWF0ZWRfZG91YmxlKDEuMjM0NTY3ODk4NzY1NDNlMTAwKTsKKworICBFWFBFQ1RfRVEoCisgICAgInJlcGVhdGVkX2Zsb2F0OiAxLjJcbiIKKyAgICAicmVwZWF0ZWRfZmxvYXQ6IDEuMjNcbiIKKyAgICAicmVwZWF0ZWRfZmxvYXQ6IDEuMjM0XG4iCisgICAgInJlcGVhdGVkX2Zsb2F0OiAxLjIzNDVcbiIKKyAgICAicmVwZWF0ZWRfZmxvYXQ6IDEuMjM0NTZcbiIKKyAgICAicmVwZWF0ZWRfZmxvYXQ6IDEuMmUrMTBcbiIKKyAgICAicmVwZWF0ZWRfZmxvYXQ6IDEuMjNlKzEwXG4iCisgICAgInJlcGVhdGVkX2Zsb2F0OiAxLjIzNGUrMTBcbiIKKyAgICAicmVwZWF0ZWRfZmxvYXQ6IDEuMjM0NWUrMTBcbiIKKyAgICAicmVwZWF0ZWRfZmxvYXQ6IDEuMjM0NTZlKzEwXG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogMS4yXG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogMS4yM1xuIgorICAgICJyZXBlYXRlZF9kb3VibGU6IDEuMjM0XG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogMS4yMzQ1XG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogMS4yMzQ1NlxuIgorICAgICJyZXBlYXRlZF9kb3VibGU6IDEuMjM0NTY3XG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogMS4yMzQ1Njc4XG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogMS4yMzQ1Njc4OVxuIgorICAgICJyZXBlYXRlZF9kb3VibGU6IDEuMjM0NTY3ODk4XG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogMS4yMzQ1Njc4OTg3XG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogMS4yMzQ1Njc4OTg3NlxuIgorICAgICJyZXBlYXRlZF9kb3VibGU6IDEuMjM0NTY3ODk4NzY1XG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogMS4yMzQ1Njc4OTg3NjU0XG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogMS4yMzQ1Njc4OTg3NjU0M1xuIgorICAgICJyZXBlYXRlZF9kb3VibGU6IDEuMmUrMTAwXG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogMS4yM2UrMTAwXG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogMS4yMzRlKzEwMFxuIgorICAgICJyZXBlYXRlZF9kb3VibGU6IDEuMjM0NWUrMTAwXG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogMS4yMzQ1NmUrMTAwXG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogMS4yMzQ1NjdlKzEwMFxuIgorICAgICJyZXBlYXRlZF9kb3VibGU6IDEuMjM0NTY3OGUrMTAwXG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogMS4yMzQ1Njc4OWUrMTAwXG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogMS4yMzQ1Njc4OThlKzEwMFxuIgorICAgICJyZXBlYXRlZF9kb3VibGU6IDEuMjM0NTY3ODk4N2UrMTAwXG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogMS4yMzQ1Njc4OTg3NmUrMTAwXG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogMS4yMzQ1Njc4OTg3NjVlKzEwMFxuIgorICAgICJyZXBlYXRlZF9kb3VibGU6IDEuMjM0NTY3ODk4NzY1NGUrMTAwXG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogMS4yMzQ1Njc4OTg3NjU0M2UrMTAwXG4iLAorICAgIFJlbW92ZVJlZHVuZGFudFplcm9zKG1lc3NhZ2UuRGVidWdTdHJpbmcoKSkpOworfQorCisKK1RFU1RfRihUZXh0Rm9ybWF0VGVzdCwgQWxsb3dQYXJ0aWFsKSB7CisgIHVuaXR0ZXN0OjpUZXN0UmVxdWlyZWQgbWVzc2FnZTsKKyAgVGV4dEZvcm1hdDo6UGFyc2VyIHBhcnNlcjsKKyAgcGFyc2VyLkFsbG93UGFydGlhbE1lc3NhZ2UodHJ1ZSk7CisgIEVYUEVDVF9UUlVFKHBhcnNlci5QYXJzZUZyb21TdHJpbmcoImE6IDEiLCAmbWVzc2FnZSkpOworICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5hKCkpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5oYXNfYigpKTsKKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuaGFzX2MoKSk7Cit9CisKK1RFU1RfRihUZXh0Rm9ybWF0VGVzdCwgUGFyc2VFeG90aWMpIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtZXNzYWdlOworICBBU1NFUlRfVFJVRShUZXh0Rm9ybWF0OjpQYXJzZUZyb21TdHJpbmcoCisgICAgInJlcGVhdGVkX2ludDMyOiAtMVxuIgorICAgICJyZXBlYXRlZF9pbnQzMjogLTIxNDc0ODM2NDhcbiIKKyAgICAicmVwZWF0ZWRfaW50NjQ6IC0xXG4iCisgICAgInJlcGVhdGVkX2ludDY0OiAtOTIyMzM3MjAzNjg1NDc3NTgwOFxuIgorICAgICJyZXBlYXRlZF91aW50MzI6IDQyOTQ5NjcyOTVcbiIKKyAgICAicmVwZWF0ZWRfdWludDMyOiAyMTQ3NDgzNjQ4XG4iCisgICAgInJlcGVhdGVkX3VpbnQ2NDogMTg0NDY3NDQwNzM3MDk1NTE2MTVcbiIKKyAgICAicmVwZWF0ZWRfdWludDY0OiA5MjIzMzcyMDM2ODU0Nzc1ODA4XG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogMTIzLjBcbiIKKyAgICAicmVwZWF0ZWRfZG91YmxlOiAxMjMuNVxuIgorICAgICJyZXBlYXRlZF9kb3VibGU6IDAuMTI1XG4iCisgICAgInJlcGVhdGVkX2RvdWJsZTogMS4yM0UxN1xuIgorICAgICJyZXBlYXRlZF9kb3VibGU6IDEuMjM1RSsyMlxuIgorICAgICJyZXBlYXRlZF9kb3VibGU6IDEuMjM1ZS0xOFxuIgorICAgICJyZXBlYXRlZF9kb3VibGU6IDEyMy40NTY3ODlcbiIKKyAgICAicmVwZWF0ZWRfZG91YmxlOiBpbmZcbiIKKyAgICAicmVwZWF0ZWRfZG91YmxlOiBJbmZpbml0eVxuIgorICAgICJyZXBlYXRlZF9kb3VibGU6IC1pbmZcbiIKKyAgICAicmVwZWF0ZWRfZG91YmxlOiAtSW5maW5pdHlcbiIKKyAgICAicmVwZWF0ZWRfZG91YmxlOiBuYW5cbiIKKyAgICAicmVwZWF0ZWRfZG91YmxlOiBOYU5cbiIKKyAgICAicmVwZWF0ZWRfc3RyaW5nOiBcIlxcMDAwXFwwMDFcXGFcXGJcXGZcXG5cXHJcXHRcXHZcXFxcXFwnXFxcIlwiXG4iLAorICAgICZtZXNzYWdlKSk7CisKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfaW50MzJfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKC0xLCBtZXNzYWdlLnJlcGVhdGVkX2ludDMyKDApKTsKKyAgLy8gTm90ZTogIEluIEMsIGEgbmVnYXRpdmUgaW50ZWdlciBsaXRlcmFsIGlzIGFjdHVhbGx5IHRoZSB1bmFyeSBuZWdhdGlvbgorICAvLyAgIG9wZXJhdG9yIGJlaW5nIGFwcGxpZWQgdG8gYSBwb3NpdGl2ZSBpbnRlZ2VyIGxpdGVyYWwsIGFuZCAyMTQ3NDgzNjQ4IGlzCisgIC8vICAgb3V0c2lkZSB0aGUgcmFuZ2Ugb2YgaW50MzIuICBIb3dldmVyLCBpdCBpcyBub3Qgb3V0c2lkZSB0aGUgcmFuZ2Ugb2YKKyAgLy8gICB1aW50MzIuICBDb25mdXNpbmdseSwgdGhpcyBtZWFucyB0aGF0IGV2ZXJ5dGhpbmcgd29ya3MgaWYgd2UgbWFrZSB0aGUKKyAgLy8gICBsaXRlcmFsIHVuc2lnbmVkLCBldmVuIHRob3VnaCB3ZSBhcmUgbmVnYXRpbmcgaXQuCisgIEVYUEVDVF9FUSgtMjE0NzQ4MzY0OHUsIG1lc3NhZ2UucmVwZWF0ZWRfaW50MzIoMSkpOworCisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX2ludDY0X3NpemUoKSk7CisgIEVYUEVDVF9FUSgtMSwgbWVzc2FnZS5yZXBlYXRlZF9pbnQ2NCgwKSk7CisgIC8vIE5vdGU6ICBJbiBDLCBhIG5lZ2F0aXZlIGludGVnZXIgbGl0ZXJhbCBpcyBhY3R1YWxseSB0aGUgdW5hcnkgbmVnYXRpb24KKyAgLy8gICBvcGVyYXRvciBiZWluZyBhcHBsaWVkIHRvIGEgcG9zaXRpdmUgaW50ZWdlciBsaXRlcmFsLCBhbmQKKyAgLy8gICA5MjIzMzcyMDM2ODU0Nzc1ODA4IGlzIG91dHNpZGUgdGhlIHJhbmdlIG9mIGludDY0LiAgSG93ZXZlciwgaXQgaXMgbm90CisgIC8vICAgb3V0c2lkZSB0aGUgcmFuZ2Ugb2YgdWludDY0LiAgQ29uZnVzaW5nbHksIHRoaXMgbWVhbnMgdGhhdCBldmVyeXRoaW5nCisgIC8vICAgd29ya3MgaWYgd2UgbWFrZSB0aGUgbGl0ZXJhbCB1bnNpZ25lZCwgZXZlbiB0aG91Z2ggd2UgYXJlIG5lZ2F0aW5nIGl0LgorICBFWFBFQ1RfRVEoLUdPT0dMRV9VTE9OR0xPTkcoOTIyMzM3MjAzNjg1NDc3NTgwOCksIG1lc3NhZ2UucmVwZWF0ZWRfaW50NjQoMSkpOworCisgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX3VpbnQzMl9zaXplKCkpOworICBFWFBFQ1RfRVEoNDI5NDk2NzI5NXUsIG1lc3NhZ2UucmVwZWF0ZWRfdWludDMyKDApKTsKKyAgRVhQRUNUX0VRKDIxNDc0ODM2NDh1LCBtZXNzYWdlLnJlcGVhdGVkX3VpbnQzMigxKSk7CisKKyAgQVNTRVJUX0VRKDIsIG1lc3NhZ2UucmVwZWF0ZWRfdWludDY0X3NpemUoKSk7CisgIEVYUEVDVF9FUShHT09HTEVfVUxPTkdMT05HKDE4NDQ2NzQ0MDczNzA5NTUxNjE1KSwgbWVzc2FnZS5yZXBlYXRlZF91aW50NjQoMCkpOworICBFWFBFQ1RfRVEoR09PR0xFX1VMT05HTE9ORyg5MjIzMzcyMDM2ODU0Nzc1ODA4KSwgbWVzc2FnZS5yZXBlYXRlZF91aW50NjQoMSkpOworCisgIEFTU0VSVF9FUSgxMywgbWVzc2FnZS5yZXBlYXRlZF9kb3VibGVfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDEyMy4wICAgICAsIG1lc3NhZ2UucmVwZWF0ZWRfZG91YmxlKDApKTsKKyAgRVhQRUNUX0VRKDEyMy41ICAgICAsIG1lc3NhZ2UucmVwZWF0ZWRfZG91YmxlKDEpKTsKKyAgRVhQRUNUX0VRKDAuMTI1ICAgICAsIG1lc3NhZ2UucmVwZWF0ZWRfZG91YmxlKDIpKTsKKyAgRVhQRUNUX0VRKDEuMjNFMTcgICAsIG1lc3NhZ2UucmVwZWF0ZWRfZG91YmxlKDMpKTsKKyAgRVhQRUNUX0VRKDEuMjM1RTIyICAsIG1lc3NhZ2UucmVwZWF0ZWRfZG91YmxlKDQpKTsKKyAgRVhQRUNUX0VRKDEuMjM1RS0xOCAsIG1lc3NhZ2UucmVwZWF0ZWRfZG91YmxlKDUpKTsKKyAgRVhQRUNUX0VRKDEyMy40NTY3ODksIG1lc3NhZ2UucmVwZWF0ZWRfZG91YmxlKDYpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UucmVwZWF0ZWRfZG91YmxlKDcpLCBudW1lcmljX2xpbWl0czxkb3VibGU+OjppbmZpbml0eSgpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UucmVwZWF0ZWRfZG91YmxlKDgpLCBudW1lcmljX2xpbWl0czxkb3VibGU+OjppbmZpbml0eSgpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UucmVwZWF0ZWRfZG91YmxlKDkpLCAtbnVtZXJpY19saW1pdHM8ZG91YmxlPjo6aW5maW5pdHkoKSk7CisgIEVYUEVDVF9FUShtZXNzYWdlLnJlcGVhdGVkX2RvdWJsZSgxMCksIC1udW1lcmljX2xpbWl0czxkb3VibGU+OjppbmZpbml0eSgpKTsKKyAgRVhQRUNUX1RSVUUoTWF0aExpbWl0czxkb3VibGU+OjpJc05hTihtZXNzYWdlLnJlcGVhdGVkX2RvdWJsZSgxMSkpKTsKKyAgRVhQRUNUX1RSVUUoTWF0aExpbWl0czxkb3VibGU+OjpJc05hTihtZXNzYWdlLnJlcGVhdGVkX2RvdWJsZSgxMikpKTsKKworICAvLyBOb3RlOiAgU2luY2UgdGhlc2Ugc3RyaW5nIGxpdGVyYWxzIGhhdmUgXDAncyBpbiB0aGVtLCB3ZSBtdXN0IGV4cGxpY2l0bHkKKyAgLy8gICBwYXNzIHRoZWlyIHNpemVzIHRvIHN0cmluZydzIGNvbnN0cnVjdG9yLgorICBBU1NFUlRfRVEoMSwgbWVzc2FnZS5yZXBlYXRlZF9zdHJpbmdfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKHN0cmluZygiXDAwMFwwMDFcYVxiXGZcblxyXHRcdlxcXCdcIiIsIDEyKSwKKyAgICAgICAgICAgIG1lc3NhZ2UucmVwZWF0ZWRfc3RyaW5nKDApKTsKK30KKworVEVTVF9GKFRleHRGb3JtYXRUZXN0LCBQcmludEZpZWxkc0luSW5kZXhPcmRlcikgeworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEZpZWxkT3JkZXJpbmdzIG1lc3NhZ2U7CisgIC8vIEZpZWxkcyBhcmUgbGlzdGVkIGluIGluZGV4IG9yZGVyIGluc3RlYWQgb2YgZmllbGQgbnVtYmVyLgorICBtZXNzYWdlLnNldF9teV9zdHJpbmcoIlRlc3QgU3RyaW5nIik7ICAgLy8gRmllbGQgbnVtYmVyIDExCisgIG1lc3NhZ2Uuc2V0X215X2ludCgxMjM0NSk7ICAgICAgICAgICAgICAvLyBGaWVsZCBudW1iZXIgMQorICBtZXNzYWdlLnNldF9teV9mbG9hdCgwLjk5OSk7ICAgICAgICAgICAgLy8gRmllbGQgbnVtYmVyIDEwMQorICBUZXh0Rm9ybWF0OjpQcmludGVyIHByaW50ZXI7CisgIHN0cmluZyB0ZXh0OworCisgIC8vIEJ5IGRlZmF1bHQsIHByaW50IGluIGZpZWxkIG51bWJlciBvcmRlci4KKyAgcHJpbnRlci5QcmludFRvU3RyaW5nKG1lc3NhZ2UsICZ0ZXh0KTsKKyAgRVhQRUNUX0VRKCJteV9pbnQ6IDEyMzQ1XG5teV9zdHJpbmc6IFwiVGVzdCBTdHJpbmdcIlxubXlfZmxvYXQ6IDAuOTk5XG4iLAorICAgICAgICAgICAgdGV4dCk7CisKKyAgLy8gUHJpbnQgaW4gaW5kZXggb3JkZXIuCisgIHByaW50ZXIuU2V0UHJpbnRNZXNzYWdlRmllbGRzSW5JbmRleE9yZGVyKHRydWUpOworICBwcmludGVyLlByaW50VG9TdHJpbmcobWVzc2FnZSwgJnRleHQpOworICBFWFBFQ1RfRVEoIm15X3N0cmluZzogXCJUZXN0IFN0cmluZ1wiXG5teV9pbnQ6IDEyMzQ1XG5teV9mbG9hdDogMC45OTlcbiIsCisgICAgICAgICAgICB0ZXh0KTsKK30KKworY2xhc3MgVGV4dEZvcm1hdFBhcnNlclRlc3QgOiBwdWJsaWMgdGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICB2b2lkIEV4cGVjdEZhaWx1cmUoY29uc3Qgc3RyaW5nJiBpbnB1dCwgY29uc3Qgc3RyaW5nJiBtZXNzYWdlLCBpbnQgbGluZSwKKyAgICAgICAgICAgICAgICAgICAgIGludCBjb2wpIHsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM+IHByb3RvKG5ldyB1bml0dGVzdDo6VGVzdEFsbFR5cGVzKTsKKyAgICBFeHBlY3RGYWlsdXJlKGlucHV0LCBtZXNzYWdlLCBsaW5lLCBjb2wsIHByb3RvLmdldCgpKTsKKyAgfQorCisgIHZvaWQgRXhwZWN0RmFpbHVyZShjb25zdCBzdHJpbmcmIGlucHV0LCBjb25zdCBzdHJpbmcmIG1lc3NhZ2UsIGludCBsaW5lLAorICAgICAgICAgICAgICAgICAgICAgaW50IGNvbCwgTWVzc2FnZSogcHJvdG8pIHsKKyAgICBFeHBlY3RNZXNzYWdlKGlucHV0LCBtZXNzYWdlLCBsaW5lLCBjb2wsIHByb3RvLCBmYWxzZSk7CisgIH0KKworICB2b2lkIEV4cGVjdE1lc3NhZ2UoY29uc3Qgc3RyaW5nJiBpbnB1dCwgY29uc3Qgc3RyaW5nJiBtZXNzYWdlLCBpbnQgbGluZSwKKyAgICAgICAgICAgICAgICAgICAgIGludCBjb2wsIE1lc3NhZ2UqIHByb3RvLCBib29sIGV4cGVjdGVkX3Jlc3VsdCkgeworICAgIFRleHRGb3JtYXQ6OlBhcnNlciBwYXJzZXI7CisgICAgTW9ja0Vycm9yQ29sbGVjdG9yIGVycm9yX2NvbGxlY3RvcjsKKyAgICBwYXJzZXIuUmVjb3JkRXJyb3JzVG8oJmVycm9yX2NvbGxlY3Rvcik7CisgICAgRVhQRUNUX0VRKGV4cGVjdGVkX3Jlc3VsdCwgcGFyc2VyLlBhcnNlRnJvbVN0cmluZyhpbnB1dCwgcHJvdG8pKQorICAgICAgICA8PCBpbnB1dCA8PCAiIC0+ICIgPDwgcHJvdG8tPkRlYnVnU3RyaW5nKCk7CisgICAgRVhQRUNUX0VRKFNpbXBsZUl0b2EobGluZSkgKyAiOiIgKyBTaW1wbGVJdG9hKGNvbCkgKyAiOiAiICsgbWVzc2FnZSArICJcbiIsCisgICAgICAgICAgICAgIGVycm9yX2NvbGxlY3Rvci50ZXh0Xyk7CisgIH0KKworICB2b2lkIEV4cGVjdFN1Y2Nlc3NBbmRUcmVlKGNvbnN0IHN0cmluZyYgaW5wdXQsIE1lc3NhZ2UqIHByb3RvLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRleHRGb3JtYXQ6OlBhcnNlSW5mb1RyZWUqIGluZm9fdHJlZSkgeworICAgIFRleHRGb3JtYXQ6OlBhcnNlciBwYXJzZXI7CisgICAgTW9ja0Vycm9yQ29sbGVjdG9yIGVycm9yX2NvbGxlY3RvcjsKKyAgICBwYXJzZXIuUmVjb3JkRXJyb3JzVG8oJmVycm9yX2NvbGxlY3Rvcik7CisgICAgcGFyc2VyLldyaXRlTG9jYXRpb25zVG8oaW5mb190cmVlKTsKKworICAgIEVYUEVDVF9UUlVFKHBhcnNlci5QYXJzZUZyb21TdHJpbmcoaW5wdXQsIHByb3RvKSk7CisgIH0KKworICB2b2lkIEV4cGVjdExvY2F0aW9uKFRleHRGb3JtYXQ6OlBhcnNlSW5mb1RyZWUqIHRyZWUsCisgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVzY3JpcHRvciogZCwgY29uc3Qgc3RyaW5nJiBmaWVsZF9uYW1lLAorICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCwgaW50IGxpbmUsIGludCBjb2x1bW4pIHsKKyAgICBUZXh0Rm9ybWF0OjpQYXJzZUxvY2F0aW9uIGxvY2F0aW9uID0gdHJlZS0+R2V0TG9jYXRpb24oCisgICAgICAgIGQtPkZpbmRGaWVsZEJ5TmFtZShmaWVsZF9uYW1lKSwgaW5kZXgpOworICAgIEVYUEVDVF9FUShsaW5lLCBsb2NhdGlvbi5saW5lKTsKKyAgICBFWFBFQ1RfRVEoY29sdW1uLCBsb2NhdGlvbi5jb2x1bW4pOworICB9CisKKyAgLy8gQW4gZXJyb3IgY29sbGVjdG9yIHdoaWNoIHNpbXBseSBjb25jYXRlbmF0ZXMgYWxsIGl0cyBlcnJvcnMgaW50byBhIGJpZworICAvLyBibG9jayBvZiB0ZXh0IHdoaWNoIGNhbiBiZSBjaGVja2VkLgorICBjbGFzcyBNb2NrRXJyb3JDb2xsZWN0b3IgOiBwdWJsaWMgaW86OkVycm9yQ29sbGVjdG9yIHsKKyAgIHB1YmxpYzoKKyAgICBNb2NrRXJyb3JDb2xsZWN0b3IoKSB7fQorICAgIH5Nb2NrRXJyb3JDb2xsZWN0b3IoKSB7fQorCisgICAgc3RyaW5nIHRleHRfOworCisgICAgLy8gaW1wbGVtZW50cyBFcnJvckNvbGxlY3RvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgdm9pZCBBZGRFcnJvcihpbnQgbGluZSwgaW50IGNvbHVtbiwgY29uc3Qgc3RyaW5nJiBtZXNzYWdlKSB7CisgICAgICBzdHJpbmdzOjpTdWJzdGl0dXRlQW5kQXBwZW5kKCZ0ZXh0XywgIiQwOiQxOiAkMlxuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZSArIDEsIGNvbHVtbiArIDEsIG1lc3NhZ2UpOworICAgIH0KKworICAgIHZvaWQgQWRkV2FybmluZyhpbnQgbGluZSwgaW50IGNvbHVtbiwgY29uc3Qgc3RyaW5nJiBtZXNzYWdlKSB7CisgICAgICBBZGRFcnJvcihsaW5lLCBjb2x1bW4sICJXQVJOSU5HOiIgKyBtZXNzYWdlKTsKKyAgICB9CisgIH07Cit9OworCitURVNUX0YoVGV4dEZvcm1hdFBhcnNlclRlc3QsIFBhcnNlSW5mb1RyZWVCdWlsZGluZykgeworICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM+IG1lc3NhZ2UobmV3IHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMpOworICBjb25zdCBEZXNjcmlwdG9yKiBkID0gbWVzc2FnZS0+R2V0RGVzY3JpcHRvcigpOworCisgIHN0cmluZyBzdHJpbmdEYXRhID0KKyAgICAgICJvcHRpb25hbF9pbnQzMjogMVxuIgorICAgICAgIm9wdGlvbmFsX2ludDY0OiAyXG4iCisgICAgICAiICBvcHRpb25hbF9kb3VibGU6IDIuNFxuIgorICAgICAgInJlcGVhdGVkX2ludDMyOiA1XG4iCisgICAgICAicmVwZWF0ZWRfaW50MzI6IDEwXG4iCisgICAgICAib3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPFxuIgorICAgICAgIiAgYmI6IDc4XG4iCisgICAgICAiPlxuIgorICAgICAgInJlcGVhdGVkX25lc3RlZF9tZXNzYWdlIDxcbiIKKyAgICAgICIgIGJiOiA3OVxuIgorICAgICAgIj5cbiIKKyAgICAgICJyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA8XG4iCisgICAgICAiICBiYjogODBcbiIKKyAgICAgICI+IjsKKworCisgIFRleHRGb3JtYXQ6OlBhcnNlSW5mb1RyZWUgdHJlZTsKKyAgRXhwZWN0U3VjY2Vzc0FuZFRyZWUoc3RyaW5nRGF0YSwgbWVzc2FnZS5nZXQoKSwgJnRyZWUpOworCisgIC8vIFZlcmlmeSB0aGF0IHRoZSB0cmVlIGhhcyB0aGUgY29ycmVjdCBwb3NpdGlvbnMuCisgIEV4cGVjdExvY2F0aW9uKCZ0cmVlLCBkLCAib3B0aW9uYWxfaW50MzIiLCAtMSwgMCwgMCk7CisgIEV4cGVjdExvY2F0aW9uKCZ0cmVlLCBkLCAib3B0aW9uYWxfaW50NjQiLCAtMSwgMSwgMCk7CisgIEV4cGVjdExvY2F0aW9uKCZ0cmVlLCBkLCAib3B0aW9uYWxfZG91YmxlIiwgLTEsIDIsIDIpOworCisgIEV4cGVjdExvY2F0aW9uKCZ0cmVlLCBkLCAicmVwZWF0ZWRfaW50MzIiLCAwLCAzLCAwKTsKKyAgRXhwZWN0TG9jYXRpb24oJnRyZWUsIGQsICJyZXBlYXRlZF9pbnQzMiIsIDEsIDQsIDApOworCisgIEV4cGVjdExvY2F0aW9uKCZ0cmVlLCBkLCAib3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UiLCAtMSwgNSwgMCk7CisgIEV4cGVjdExvY2F0aW9uKCZ0cmVlLCBkLCAicmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UiLCAwLCA4LCAwKTsKKyAgRXhwZWN0TG9jYXRpb24oJnRyZWUsIGQsICJyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSIsIDEsIDExLCAwKTsKKworICAvLyBDaGVjayBmb3IgZmllbGRzIG5vdCBzZXQuIEZvciBhbiBpbnZhbGlkIGZpZWxkLCB0aGUgbG9jYXRpb24gcmV0dXJuZWQKKyAgLy8gc2hvdWxkIGJlIC0xLCAtMS4KKyAgRXhwZWN0TG9jYXRpb24oJnRyZWUsIGQsICJyZXBlYXRlZF9pbnQ2NCIsIDAsIC0xLCAtMSk7CisgIEV4cGVjdExvY2F0aW9uKCZ0cmVlLCBkLCAicmVwZWF0ZWRfaW50MzIiLCA2LCAtMSwgLTEpOworICBFeHBlY3RMb2NhdGlvbigmdHJlZSwgZCwgInNvbWVfdW5rbm93bl9maWVsZCIsIC0xLCAtMSwgLTEpOworCisgIC8vIFZlcmlmeSBpbnNpZGUgdGhlIG5lc3RlZCBtZXNzYWdlLgorICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIG5lc3RlZF9maWVsZCA9CisgICAgICBkLT5GaW5kRmllbGRCeU5hbWUoIm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlIik7CisKKyAgVGV4dEZvcm1hdDo6UGFyc2VJbmZvVHJlZSogbmVzdGVkX3RyZWUgPQorICAgICAgdHJlZS5HZXRUcmVlRm9yTmVzdGVkKG5lc3RlZF9maWVsZCwgLTEpOworICBFeHBlY3RMb2NhdGlvbihuZXN0ZWRfdHJlZSwgbmVzdGVkX2ZpZWxkLT5tZXNzYWdlX3R5cGUoKSwgImJiIiwgLTEsIDYsIDIpOworCisgIC8vIFZlcmlmeSBpbnNpZGUgYW5vdGhlciBuZXN0ZWQgbWVzc2FnZS4KKyAgbmVzdGVkX2ZpZWxkID0gZC0+RmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSIpOworICBuZXN0ZWRfdHJlZSA9IHRyZWUuR2V0VHJlZUZvck5lc3RlZChuZXN0ZWRfZmllbGQsIDApOworICBFeHBlY3RMb2NhdGlvbihuZXN0ZWRfdHJlZSwgbmVzdGVkX2ZpZWxkLT5tZXNzYWdlX3R5cGUoKSwgImJiIiwgLTEsIDksIDIpOworCisgIG5lc3RlZF90cmVlID0gdHJlZS5HZXRUcmVlRm9yTmVzdGVkKG5lc3RlZF9maWVsZCwgMSk7CisgIEV4cGVjdExvY2F0aW9uKG5lc3RlZF90cmVlLCBuZXN0ZWRfZmllbGQtPm1lc3NhZ2VfdHlwZSgpLCAiYmIiLCAtMSwgMTIsIDIpOworCisgIC8vIFZlcmlmeSBhIE5VTEwgdHJlZSBmb3IgYW4gdW5rbm93biBuZXN0ZWQgZmllbGQuCisgIFRleHRGb3JtYXQ6OlBhcnNlSW5mb1RyZWUqIHVua25vd25fbmVzdGVkX3RyZWUgPQorICAgICAgdHJlZS5HZXRUcmVlRm9yTmVzdGVkKG5lc3RlZF9maWVsZCwgMik7CisKKyAgRVhQRUNUX0VRKE5VTEwsIHVua25vd25fbmVzdGVkX3RyZWUpOworfQorCitURVNUX0YoVGV4dEZvcm1hdFBhcnNlclRlc3QsIFBhcnNlRmllbGRWYWx1ZUZyb21TdHJpbmcpIHsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjx1bml0dGVzdDo6VGVzdEFsbFR5cGVzPiBtZXNzYWdlKG5ldyB1bml0dGVzdDo6VGVzdEFsbFR5cGVzKTsKKyAgY29uc3QgRGVzY3JpcHRvciogZCA9IG1lc3NhZ2UtPkdldERlc2NyaXB0b3IoKTsKKworI2RlZmluZSBFWFBFQ1RfRklFTEQobmFtZSwgdmFsdWUsIHZhbHVlc3RyaW5nKSBcCisgIEVYUEVDVF9UUlVFKFRleHRGb3JtYXQ6OlBhcnNlRmllbGRWYWx1ZUZyb21TdHJpbmcoIFwKKyAgICB2YWx1ZXN0cmluZywgZC0+RmluZEZpZWxkQnlOYW1lKCJvcHRpb25hbF8iICNuYW1lKSwgbWVzc2FnZS5nZXQoKSkpOyBcCisgIEVYUEVDVF9FUSh2YWx1ZSwgbWVzc2FnZS0+b3B0aW9uYWxfIyNuYW1lKCkpOyBcCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UtPmhhc19vcHRpb25hbF8jI25hbWUoKSk7CisKKyNkZWZpbmUgRVhQRUNUX0JPT0xfRklFTEQobmFtZSwgdmFsdWUsIHZhbHVlc3RyaW5nKSBcCisgIEVYUEVDVF9UUlVFKFRleHRGb3JtYXQ6OlBhcnNlRmllbGRWYWx1ZUZyb21TdHJpbmcoIFwKKyAgICB2YWx1ZXN0cmluZywgZC0+RmluZEZpZWxkQnlOYW1lKCJvcHRpb25hbF8iICNuYW1lKSwgbWVzc2FnZS5nZXQoKSkpOyBcCisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UtPm9wdGlvbmFsXyMjbmFtZSgpID09IHZhbHVlKTsgXAorICBFWFBFQ1RfVFJVRShtZXNzYWdlLT5oYXNfb3B0aW9uYWxfIyNuYW1lKCkpOworCisjZGVmaW5lIEVYUEVDVF9GTE9BVF9GSUVMRChuYW1lLCB2YWx1ZSwgdmFsdWVzdHJpbmcpIFwKKyAgRVhQRUNUX1RSVUUoVGV4dEZvcm1hdDo6UGFyc2VGaWVsZFZhbHVlRnJvbVN0cmluZyggXAorICAgIHZhbHVlc3RyaW5nLCBkLT5GaW5kRmllbGRCeU5hbWUoIm9wdGlvbmFsXyIgI25hbWUpLCBtZXNzYWdlLmdldCgpKSk7IFwKKyAgRVhQRUNUX0ZMT0FUX0VRKHZhbHVlLCBtZXNzYWdlLT5vcHRpb25hbF8jI25hbWUoKSk7IFwKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS0+aGFzX29wdGlvbmFsXyMjbmFtZSgpKTsKKworI2RlZmluZSBFWFBFQ1RfRE9VQkxFX0ZJRUxEKG5hbWUsIHZhbHVlLCB2YWx1ZXN0cmluZykgXAorICBFWFBFQ1RfVFJVRShUZXh0Rm9ybWF0OjpQYXJzZUZpZWxkVmFsdWVGcm9tU3RyaW5nKCBcCisgICAgdmFsdWVzdHJpbmcsIGQtPkZpbmRGaWVsZEJ5TmFtZSgib3B0aW9uYWxfIiAjbmFtZSksIG1lc3NhZ2UuZ2V0KCkpKTsgXAorICBFWFBFQ1RfRE9VQkxFX0VRKHZhbHVlLCBtZXNzYWdlLT5vcHRpb25hbF8jI25hbWUoKSk7IFwKKyAgRVhQRUNUX1RSVUUobWVzc2FnZS0+aGFzX29wdGlvbmFsXyMjbmFtZSgpKTsKKworI2RlZmluZSBFWFBFQ1RfSU5WQUxJRChuYW1lLCB2YWx1ZXN0cmluZykgXAorICBFWFBFQ1RfRkFMU0UoVGV4dEZvcm1hdDo6UGFyc2VGaWVsZFZhbHVlRnJvbVN0cmluZyggXAorICAgIHZhbHVlc3RyaW5nLCBkLT5GaW5kRmllbGRCeU5hbWUoIm9wdGlvbmFsXyIgI25hbWUpLCBtZXNzYWdlLmdldCgpKSk7CisKKyAgLy8gaW50MzIKKyAgRVhQRUNUX0ZJRUxEKGludDMyLCAxLCAiMSIpOworICBFWFBFQ1RfRklFTEQoaW50MzIsIC0xLCAiLTEiKTsKKyAgRVhQRUNUX0ZJRUxEKGludDMyLCAweDEyMzQsICIweDEyMzQiKTsKKyAgRVhQRUNUX0lOVkFMSUQoaW50MzIsICJhIik7CisgIEVYUEVDVF9JTlZBTElEKGludDMyLCAiOTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5Iik7CisgIEVYUEVDVF9JTlZBTElEKGludDMyLCAiMSwyIik7CisKKyAgLy8gaW50NjQKKyAgRVhQRUNUX0ZJRUxEKGludDY0LCAxLCAiMSIpOworICBFWFBFQ1RfRklFTEQoaW50NjQsIC0xLCAiLTEiKTsKKyAgRVhQRUNUX0ZJRUxEKGludDY0LCAweDEyMzQ1Njc4MTIzNDU2NzhMTCwgIjB4MTIzNDU2NzgxMjM0NTY3OCIpOworICBFWFBFQ1RfSU5WQUxJRChpbnQ2NCwgImEiKTsKKyAgRVhQRUNUX0lOVkFMSUQoaW50NjQsICI5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTkiKTsKKyAgRVhQRUNUX0lOVkFMSUQoaW50NjQsICIxLDIiKTsKKworICAvLyB1aW50NjQKKyAgRVhQRUNUX0ZJRUxEKHVpbnQ2NCwgMSwgIjEiKTsKKyAgRVhQRUNUX0ZJRUxEKHVpbnQ2NCwgMHhmMjM0NTY3ODEyMzQ1Njc4VUxMLCAiMHhmMjM0NTY3ODEyMzQ1Njc4Iik7CisgIEVYUEVDVF9JTlZBTElEKHVpbnQ2NCwgIi0xIik7CisgIEVYUEVDVF9JTlZBTElEKHVpbnQ2NCwgImEiKTsKKyAgRVhQRUNUX0lOVkFMSUQodWludDY0LCAiOTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5Iik7CisgIEVYUEVDVF9JTlZBTElEKHVpbnQ2NCwgIjEsMiIpOworCisgIC8vIGZpeGVkMzIKKyAgRVhQRUNUX0ZJRUxEKGZpeGVkMzIsIDEsICIxIik7CisgIEVYUEVDVF9GSUVMRChmaXhlZDMyLCAweDEyMzQ1Njc4LCAiMHgxMjM0NTY3OCIpOworICBFWFBFQ1RfSU5WQUxJRChmaXhlZDMyLCAiLTEiKTsKKyAgRVhQRUNUX0lOVkFMSUQoZml4ZWQzMiwgImEiKTsKKyAgRVhQRUNUX0lOVkFMSUQoZml4ZWQzMiwgIjk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OSIpOworICBFWFBFQ1RfSU5WQUxJRChmaXhlZDMyLCAiMSwyIik7CisKKyAgLy8gZml4ZWQ2NAorICBFWFBFQ1RfRklFTEQoZml4ZWQ2NCwgMSwgIjEiKTsKKyAgRVhQRUNUX0ZJRUxEKGZpeGVkNjQsIDB4MTIzNDU2NzgxMjM0NTY3OFVMTCwgIjB4MTIzNDU2NzgxMjM0NTY3OCIpOworICBFWFBFQ1RfSU5WQUxJRChmaXhlZDY0LCAiLTEiKTsKKyAgRVhQRUNUX0lOVkFMSUQoZml4ZWQ2NCwgImEiKTsKKyAgRVhQRUNUX0lOVkFMSUQoZml4ZWQ2NCwgIjk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OSIpOworICBFWFBFQ1RfSU5WQUxJRChmaXhlZDY0LCAiMSwyIik7CisKKyAgLy8gYm9vbAorICBFWFBFQ1RfQk9PTF9GSUVMRChib29sLCB0cnVlLCAidHJ1ZSIpOworICBFWFBFQ1RfQk9PTF9GSUVMRChib29sLCBmYWxzZSwgImZhbHNlIik7CisgIEVYUEVDVF9CT09MX0ZJRUxEKGJvb2wsIHRydWUsICIxIik7CisgIEVYUEVDVF9CT09MX0ZJRUxEKGJvb2wsIHRydWUsICJ0Iik7CisgIEVYUEVDVF9CT09MX0ZJRUxEKGJvb2wsIGZhbHNlLCAiMCIpOworICBFWFBFQ1RfQk9PTF9GSUVMRChib29sLCBmYWxzZSwgImYiKTsKKyAgRVhQRUNUX0ZJRUxEKGJvb2wsIHRydWUsICJUcnVlIik7CisgIEVYUEVDVF9GSUVMRChib29sLCBmYWxzZSwgIkZhbHNlIik7CisgIEVYUEVDVF9JTlZBTElEKGJvb2wsICJ0UnVlIik7CisgIEVYUEVDVF9JTlZBTElEKGJvb2wsICJmYUxzZSIpOworICBFWFBFQ1RfSU5WQUxJRChib29sLCAiMiIpOworICBFWFBFQ1RfSU5WQUxJRChib29sLCAiLTAiKTsKKyAgRVhQRUNUX0lOVkFMSUQoYm9vbCwgIm9uIik7CisgIEVYUEVDVF9JTlZBTElEKGJvb2wsICJhIik7CisKKyAgLy8gZmxvYXQKKyAgRVhQRUNUX0ZJRUxEKGZsb2F0LCAxLCAiMSIpOworICBFWFBFQ1RfRkxPQVRfRklFTEQoZmxvYXQsIDEuNSwgIjEuNSIpOworICBFWFBFQ1RfRkxPQVRfRklFTEQoZmxvYXQsIDEuNWUzLCAiMS41ZTMiKTsKKyAgRVhQRUNUX0ZMT0FUX0ZJRUxEKGZsb2F0LCAtNC41NSwgIi00LjU1Iik7CisgIEVYUEVDVF9JTlZBTElEKGZsb2F0LCAiYSIpOworICBFWFBFQ1RfSU5WQUxJRChmbG9hdCwgIjEsMiIpOworCisgIC8vIGRvdWJsZQorICBFWFBFQ1RfRklFTEQoZG91YmxlLCAxLCAiMSIpOworICBFWFBFQ1RfRklFTEQoZG91YmxlLCAtMSwgIi0xIik7CisgIEVYUEVDVF9ET1VCTEVfRklFTEQoZG91YmxlLCAyLjMsICIyLjMiKTsKKyAgRVhQRUNUX0RPVUJMRV9GSUVMRChkb3VibGUsIDNlNSwgIjNlNSIpOworICBFWFBFQ1RfSU5WQUxJRChkb3VibGUsICJhIik7CisgIEVYUEVDVF9JTlZBTElEKGRvdWJsZSwgIjEsMiIpOworICAvLyBSZWplY3RzIGhleCBhbmQgb2N0IG51bWJlcnMgZm9yIGEgZG91YmxlIGZpZWxkLgorICBFWFBFQ1RfSU5WQUxJRChkb3VibGUsICIweGYiKTsKKyAgRVhQRUNUX0lOVkFMSUQoZG91YmxlLCAiMDEyIik7CisKKyAgLy8gc3RyaW5nCisgIEVYUEVDVF9GSUVMRChzdHJpbmcsICJoZWxsbyIsICJcImhlbGxvXCIiKTsKKyAgRVhQRUNUX0ZJRUxEKHN0cmluZywgIi0xLjg3IiwgIictMS44NyciKTsKKyAgRVhQRUNUX0lOVkFMSUQoc3RyaW5nLCAiaGVsbG8iKTsgIC8vIHdpdGhvdXQgcXVvdGUgZm9yIHZhbHVlCisKKyAgLy8gZW51bQorICBFWFBFQ1RfRklFTEQobmVzdGVkX2VudW0sIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkJBUiwgIkJBUiIpOworICBFWFBFQ1RfRklFTEQobmVzdGVkX2VudW0sIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OkJBWiwKKyAgICAgICAgICAgICAgIFNpbXBsZUl0b2EodW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6QkFaKSk7CisgIEVYUEVDVF9JTlZBTElEKG5lc3RlZF9lbnVtLCAiRk9PQkFSIik7CisKKyAgLy8gbWVzc2FnZQorICBFWFBFQ1RfVFJVRShUZXh0Rm9ybWF0OjpQYXJzZUZpZWxkVmFsdWVGcm9tU3RyaW5nKAorICAgICI8YmI6MTI+IiwgZC0+RmluZEZpZWxkQnlOYW1lKCJvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSIpLCBtZXNzYWdlLmdldCgpKSk7CisgIEVYUEVDVF9FUSgxMiwgbWVzc2FnZS0+b3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKS5iYigpKTsgXAorICBFWFBFQ1RfVFJVRShtZXNzYWdlLT5oYXNfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKSk7CisgIEVYUEVDVF9JTlZBTElEKG5lc3RlZF9tZXNzYWdlLCAiYW55Iik7CisKKyN1bmRlZiBFWFBFQ1RfRklFTEQKKyN1bmRlZiBFWFBFQ1RfQk9PTF9GSUVMRAorI3VuZGVmIEVYUEVDVF9GTE9BVF9GSUVMRAorI3VuZGVmIEVYUEVDVF9ET1VCTEVfRklFTEQKKyN1bmRlZiBFWFBFQ1RfSU5WQUxJRAorfQorCisKK1RFU1RfRihUZXh0Rm9ybWF0UGFyc2VyVGVzdCwgSW52YWxpZFRva2VuKSB7CisgIEV4cGVjdEZhaWx1cmUoIm9wdGlvbmFsX2Jvb2w6IHRydWVcbi01XG4iLCAiRXhwZWN0ZWQgaWRlbnRpZmllci4iLAorICAgICAgICAgICAgICAgIDIsIDEpOworCisgIEV4cGVjdEZhaWx1cmUoIm9wdGlvbmFsX2Jvb2w6IHRydWUhXG4iLCAiRXhwZWN0ZWQgaWRlbnRpZmllci4iLCAxLCAyMCk7CisgIEV4cGVjdEZhaWx1cmUoIlwic29tZSBzdHJpbmdcIiIsICJFeHBlY3RlZCBpZGVudGlmaWVyLiIsIDEsIDEpOworfQorCitURVNUX0YoVGV4dEZvcm1hdFBhcnNlclRlc3QsIEludmFsaWRGaWVsZE5hbWUpIHsKKyAgRXhwZWN0RmFpbHVyZSgKKyAgICAgICJpbnZhbGlkX2ZpZWxkOiBzb21ldmFsdWVcbiIsCisgICAgICAiTWVzc2FnZSB0eXBlIFwicHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzXCIgaGFzIG5vIGZpZWxkIG5hbWVkICIKKyAgICAgICJcImludmFsaWRfZmllbGRcIi4iLAorICAgICAgMSwgMTQpOworfQorCitURVNUX0YoVGV4dEZvcm1hdFBhcnNlclRlc3QsIEludmFsaWRDYXBpdGFsaXphdGlvbikgeworICAvLyBXZSByZXF1aXJlIHRoYXQgZ3JvdXAgbmFtZXMgYmUgZXhhY3RseSBhcyB0aGV5IGFwcGVhciBpbiB0aGUgLnByb3RvLgorICBFeHBlY3RGYWlsdXJlKAorICAgICAgIm9wdGlvbmFsZ3JvdXAge1xuYTogMTVcbn1cbiIsCisgICAgICAiTWVzc2FnZSB0eXBlIFwicHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzXCIgaGFzIG5vIGZpZWxkIG5hbWVkICIKKyAgICAgICJcIm9wdGlvbmFsZ3JvdXBcIi4iLAorICAgICAgMSwgMTUpOworICBFeHBlY3RGYWlsdXJlKAorICAgICAgIk9QVElPTkFMZ3JvdXAge1xuYTogMTVcbn1cbiIsCisgICAgICAiTWVzc2FnZSB0eXBlIFwicHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzXCIgaGFzIG5vIGZpZWxkIG5hbWVkICIKKyAgICAgICJcIk9QVElPTkFMZ3JvdXBcIi4iLAorICAgICAgMSwgMTUpOworICBFeHBlY3RGYWlsdXJlKAorICAgICAgIk9wdGlvbmFsX0RvdWJsZTogMTAuMFxuIiwKKyAgICAgICJNZXNzYWdlIHR5cGUgXCJwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXNcIiBoYXMgbm8gZmllbGQgbmFtZWQgIgorICAgICAgIlwiT3B0aW9uYWxfRG91YmxlXCIuIiwKKyAgICAgIDEsIDE2KTsKK30KKworVEVTVF9GKFRleHRGb3JtYXRQYXJzZXJUZXN0LCBBbGxvd0lnbm9yZUNhcGl0YWxpemF0aW9uRXJyb3IpIHsKKyAgVGV4dEZvcm1hdDo6UGFyc2VyIHBhcnNlcjsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBwcm90bzsKKworICAvLyBUaGVzZSBmaWVsZHMgaGF2ZSBhIG1pc21hdGNoaW5nIGNhc2UuCisgIEVYUEVDVF9GQUxTRShwYXJzZXIuUGFyc2VGcm9tU3RyaW5nKCJPcHRpb25hbF9Eb3VibGU6IDEwLjAiLCAmcHJvdG8pKTsKKyAgRVhQRUNUX0ZBTFNFKHBhcnNlci5QYXJzZUZyb21TdHJpbmcoIm9QdElvTmFMZ1JvVXAgeyBhOiAxNSB9IiwgJnByb3RvKSk7CisKKyAgLy8gLi4uIGJ1dCBhcmUgcGFyc2VkIGNvcnJlY3RseSBpZiB3ZSBtYXRjaCBjYXNlIGluc2Vuc2l0aXZlLgorICBwYXJzZXIuQWxsb3dDYXNlSW5zZW5zaXRpdmVGaWVsZCh0cnVlKTsKKyAgRVhQRUNUX1RSVUUocGFyc2VyLlBhcnNlRnJvbVN0cmluZygiT3B0aW9uYWxfRG91YmxlOiAxMC4wIiwgJnByb3RvKSk7CisgIEVYUEVDVF9FUSgxMC4wLCBwcm90by5vcHRpb25hbF9kb3VibGUoKSk7CisgIEVYUEVDVF9UUlVFKHBhcnNlci5QYXJzZUZyb21TdHJpbmcoIm9QdElvTmFMZ1JvVXAgeyBhOiAxNSB9IiwgJnByb3RvKSk7CisgIEVYUEVDVF9FUSgxNSwgcHJvdG8ub3B0aW9uYWxncm91cCgpLmEoKSk7Cit9CisKK1RFU1RfRihUZXh0Rm9ybWF0UGFyc2VyVGVzdCwgSW52YWxpZEZpZWxkVmFsdWVzKSB7CisgIC8vIEludmFsaWQgdmFsdWVzIGZvciBhIGRvdWJsZS9mbG9hdCBmaWVsZC4KKyAgRXhwZWN0RmFpbHVyZSgib3B0aW9uYWxfZG91YmxlOiBcImhlbGxvXCJcbiIsICJFeHBlY3RlZCBkb3VibGUuIiwgMSwgMTgpOworICBFeHBlY3RGYWlsdXJlKCJvcHRpb25hbF9kb3VibGU6IHRydWVcbiIsICJFeHBlY3RlZCBkb3VibGUuIiwgMSwgMTgpOworICBFeHBlY3RGYWlsdXJlKCJvcHRpb25hbF9kb3VibGU6ICFcbiIsICJFeHBlY3RlZCBkb3VibGUuIiwgMSwgMTgpOworICBFeHBlY3RGYWlsdXJlKCJvcHRpb25hbF9kb3VibGUge1xuICBcbn1cbiIsICJFeHBlY3RlZCBcIjpcIiwgZm91bmQgXCJ7XCIuIiwKKyAgICAgICAgICAgICAgICAxLCAxNyk7CisKKyAgLy8gSW52YWxpZCB2YWx1ZXMgZm9yIGEgc2lnbmVkIGludGVnZXIgZmllbGQuCisgIEV4cGVjdEZhaWx1cmUoIm9wdGlvbmFsX2ludDMyOiBcImhlbGxvXCJcbiIsICJFeHBlY3RlZCBpbnRlZ2VyLiIsIDEsIDE3KTsKKyAgRXhwZWN0RmFpbHVyZSgib3B0aW9uYWxfaW50MzI6IHRydWVcbiIsICJFeHBlY3RlZCBpbnRlZ2VyLiIsIDEsIDE3KTsKKyAgRXhwZWN0RmFpbHVyZSgib3B0aW9uYWxfaW50MzI6IDQuNVxuIiwgIkV4cGVjdGVkIGludGVnZXIuIiwgMSwgMTcpOworICBFeHBlY3RGYWlsdXJlKCJvcHRpb25hbF9pbnQzMjogIVxuIiwgIkV4cGVjdGVkIGludGVnZXIuIiwgMSwgMTcpOworICBFeHBlY3RGYWlsdXJlKCJvcHRpb25hbF9pbnQzMiB7XG4gXG59XG4iLCAiRXhwZWN0ZWQgXCI6XCIsIGZvdW5kIFwie1wiLiIsCisgICAgICAgICAgICAgICAgMSwgMTYpOworICBFeHBlY3RGYWlsdXJlKCJvcHRpb25hbF9pbnQzMjogMHg4MDAwMDAwMFxuIiwKKyAgICAgICAgICAgICAgICAiSW50ZWdlciBvdXQgb2YgcmFuZ2UuIiwgMSwgMTcpOworICBFeHBlY3RGYWlsdXJlKCJvcHRpb25hbF9pbnQ2NDogMHg4MDAwMDAwMDAwMDAwMDAwXG4iLAorICAgICAgICAgICAgICAgICJJbnRlZ2VyIG91dCBvZiByYW5nZS4iLCAxLCAxNyk7CisgIEV4cGVjdEZhaWx1cmUoIm9wdGlvbmFsX2ludDMyOiAtMHg4MDAwMDAwMVxuIiwKKyAgICAgICAgICAgICAgICAiSW50ZWdlciBvdXQgb2YgcmFuZ2UuIiwgMSwgMTgpOworICBFeHBlY3RGYWlsdXJlKCJvcHRpb25hbF9pbnQ2NDogLTB4ODAwMDAwMDAwMDAwMDAwMVxuIiwKKyAgICAgICAgICAgICAgICAiSW50ZWdlciBvdXQgb2YgcmFuZ2UuIiwgMSwgMTgpOworCisgIC8vIEludmFsaWQgdmFsdWVzIGZvciBhbiB1bnNpZ25lZCBpbnRlZ2VyIGZpZWxkLgorICBFeHBlY3RGYWlsdXJlKCJvcHRpb25hbF91aW50NjQ6IFwiaGVsbG9cIlxuIiwgIkV4cGVjdGVkIGludGVnZXIuIiwgMSwgMTgpOworICBFeHBlY3RGYWlsdXJlKCJvcHRpb25hbF91aW50NjQ6IHRydWVcbiIsICJFeHBlY3RlZCBpbnRlZ2VyLiIsIDEsIDE4KTsKKyAgRXhwZWN0RmFpbHVyZSgib3B0aW9uYWxfdWludDY0OiA0LjVcbiIsICJFeHBlY3RlZCBpbnRlZ2VyLiIsIDEsIDE4KTsKKyAgRXhwZWN0RmFpbHVyZSgib3B0aW9uYWxfdWludDY0OiAtNVxuIiwgIkV4cGVjdGVkIGludGVnZXIuIiwgMSwgMTgpOworICBFeHBlY3RGYWlsdXJlKCJvcHRpb25hbF91aW50NjQ6ICFcbiIsICJFeHBlY3RlZCBpbnRlZ2VyLiIsIDEsIDE4KTsKKyAgRXhwZWN0RmFpbHVyZSgib3B0aW9uYWxfdWludDY0IHtcbiBcbn1cbiIsICJFeHBlY3RlZCBcIjpcIiwgZm91bmQgXCJ7XCIuIiwKKyAgICAgICAgICAgICAgICAxLCAxNyk7CisgIEV4cGVjdEZhaWx1cmUoIm9wdGlvbmFsX3VpbnQzMjogMHgxMDAwMDAwMDBcbiIsCisgICAgICAgICAgICAgICAgIkludGVnZXIgb3V0IG9mIHJhbmdlLiIsIDEsIDE4KTsKKyAgRXhwZWN0RmFpbHVyZSgib3B0aW9uYWxfdWludDY0OiAweDEwMDAwMDAwMDAwMDAwMDAwXG4iLAorICAgICAgICAgICAgICAgICJJbnRlZ2VyIG91dCBvZiByYW5nZS4iLCAxLCAxOCk7CisKKyAgLy8gSW52YWxpZCB2YWx1ZXMgZm9yIGEgYm9vbGVhbiBmaWVsZC4KKyAgRXhwZWN0RmFpbHVyZSgib3B0aW9uYWxfYm9vbDogXCJoZWxsb1wiXG4iLCAiRXhwZWN0ZWQgaWRlbnRpZmllci4iLCAxLCAxNik7CisgIEV4cGVjdEZhaWx1cmUoIm9wdGlvbmFsX2Jvb2w6IDVcbiIsICJJbnRlZ2VyIG91dCBvZiByYW5nZS4iLCAxLCAxNik7CisgIEV4cGVjdEZhaWx1cmUoIm9wdGlvbmFsX2Jvb2w6IC03LjVcbiIsICJFeHBlY3RlZCBpZGVudGlmaWVyLiIsIDEsIDE2KTsKKyAgRXhwZWN0RmFpbHVyZSgib3B0aW9uYWxfYm9vbDogIVxuIiwgIkV4cGVjdGVkIGlkZW50aWZpZXIuIiwgMSwgMTYpOworCisgIEV4cGVjdEZhaWx1cmUoCisgICAgICAib3B0aW9uYWxfYm9vbDogbWVoXG4iLAorICAgICAgIkludmFsaWQgdmFsdWUgZm9yIGJvb2xlYW4gZmllbGQgXCJvcHRpb25hbF9ib29sXCIuIFZhbHVlOiBcIm1laFwiLiIsCisgICAgICAyLCAxKTsKKworICBFeHBlY3RGYWlsdXJlKCJvcHRpb25hbF9ib29sIHtcbiBcbn1cbiIsICJFeHBlY3RlZCBcIjpcIiwgZm91bmQgXCJ7XCIuIiwKKyAgICAgICAgICAgICAgICAxLCAxNSk7CisKKyAgLy8gSW52YWxpZCB2YWx1ZXMgZm9yIGEgc3RyaW5nIGZpZWxkLgorICBFeHBlY3RGYWlsdXJlKCJvcHRpb25hbF9zdHJpbmc6IHRydWVcbiIsICJFeHBlY3RlZCBzdHJpbmcuIiwgMSwgMTgpOworICBFeHBlY3RGYWlsdXJlKCJvcHRpb25hbF9zdHJpbmc6IDVcbiIsICJFeHBlY3RlZCBzdHJpbmcuIiwgMSwgMTgpOworICBFeHBlY3RGYWlsdXJlKCJvcHRpb25hbF9zdHJpbmc6IC03LjVcbiIsICJFeHBlY3RlZCBzdHJpbmcuIiwgMSwgMTgpOworICBFeHBlY3RGYWlsdXJlKCJvcHRpb25hbF9zdHJpbmc6ICFcbiIsICJFeHBlY3RlZCBzdHJpbmcuIiwgMSwgMTgpOworICBFeHBlY3RGYWlsdXJlKCJvcHRpb25hbF9zdHJpbmcge1xuIFxufVxuIiwgIkV4cGVjdGVkIFwiOlwiLCBmb3VuZCBcIntcIi4iLAorICAgICAgICAgICAgICAgIDEsIDE3KTsKKworICAvLyBJbnZhbGlkIHZhbHVlcyBmb3IgYW4gZW51bWVyYXRpb24gZmllbGQuCisgIEV4cGVjdEZhaWx1cmUoIm9wdGlvbmFsX25lc3RlZF9lbnVtOiBcImhlbGxvXCJcbiIsCisgICAgICAgICAgICAgICAgIkV4cGVjdGVkIGludGVnZXIgb3IgaWRlbnRpZmllci4iLCAxLCAyMyk7CisKKyAgLy8gVmFsaWQgdG9rZW4sIGJ1dCBlbnVtIHZhbHVlIGlzIG5vdCBkZWZpbmVkLgorICBFeHBlY3RGYWlsdXJlKCJvcHRpb25hbF9uZXN0ZWRfZW51bTogNVxuIiwKKyAgICAgICAgICAgICAgICAiVW5rbm93biBlbnVtZXJhdGlvbiB2YWx1ZSBvZiBcIjVcIiBmb3IgZmllbGQgIgorICAgICAgICAgICAgICAgICJcIm9wdGlvbmFsX25lc3RlZF9lbnVtXCIuIiwgMiwgMSk7CisgIC8vIFdlIGNvbnN1bWUgdGhlIG5lZ2F0aXZlIHNpZ24sIHNvIHRoZSBlcnJvciBwb3NpdGlvbiBzdGFydHMgb25lIGNoYXJhY3RlcgorICAvLyBsYXRlci4KKyAgRXhwZWN0RmFpbHVyZSgib3B0aW9uYWxfbmVzdGVkX2VudW06IC03LjVcbiIsICJFeHBlY3RlZCBpbnRlZ2VyLiIsIDEsIDI0KTsKKyAgRXhwZWN0RmFpbHVyZSgib3B0aW9uYWxfbmVzdGVkX2VudW06ICFcbiIsCisgICAgICAgICAgICAgICAgIkV4cGVjdGVkIGludGVnZXIgb3IgaWRlbnRpZmllci4iLCAxLCAyMyk7CisKKyAgRXhwZWN0RmFpbHVyZSgKKyAgICAgICJvcHRpb25hbF9uZXN0ZWRfZW51bTogZ3JhaFxuIiwKKyAgICAgICJVbmtub3duIGVudW1lcmF0aW9uIHZhbHVlIG9mIFwiZ3JhaFwiIGZvciBmaWVsZCAiCisgICAgICAiXCJvcHRpb25hbF9uZXN0ZWRfZW51bVwiLiIsIDIsIDEpOworCisgIEV4cGVjdEZhaWx1cmUoCisgICAgICAib3B0aW9uYWxfbmVzdGVkX2VudW0ge1xuIFxufVxuIiwKKyAgICAgICJFeHBlY3RlZCBcIjpcIiwgZm91bmQgXCJ7XCIuIiwgMSwgMjIpOworfQorCitURVNUX0YoVGV4dEZvcm1hdFBhcnNlclRlc3QsIE1lc3NhZ2VEZWxpbWl0ZXJzKSB7CisgIC8vIE5vbi1tYXRjaGluZyBkZWxpbWl0ZXJzLgorICBFeHBlY3RGYWlsdXJlKCJPcHRpb25hbEdyb3VwIDxcbiBcbn1cbiIsICJFeHBlY3RlZCBcIj5cIiwgZm91bmQgXCJ9XCIuIiwKKyAgICAgICAgICAgICAgICAzLCAxKTsKKworICAvLyBJbnZhbGlkIGRlbGltaXRlcnMuCisgIEV4cGVjdEZhaWx1cmUoIk9wdGlvbmFsR3JvdXAgW1xuIFxuXVxuIiwgIkV4cGVjdGVkIFwie1wiLCBmb3VuZCBcIltcIi4iLAorICAgICAgICAgICAgICAgIDEsIDE1KTsKKworICAvLyBVbmVuZGluZyBtZXNzYWdlLgorICBFeHBlY3RGYWlsdXJlKCJvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSB7XG4gXG5iYjogMTE4XG4iLAorICAgICAgICAgICAgICAgICJFeHBlY3RlZCBpZGVudGlmaWVyLiIsCisgICAgICAgICAgICAgICAgNCwgMSk7Cit9CisKK1RFU1RfRihUZXh0Rm9ybWF0UGFyc2VyVGVzdCwgVW5rbm93bkV4dGVuc2lvbikgeworICAvLyBOb24tbWF0Y2hpbmcgZGVsaW1pdGVycy4KKyAgRXhwZWN0RmFpbHVyZSgiW2JsYWhibGFoXTogMTIzIiwKKyAgICAgICAgICAgICAgICAiRXh0ZW5zaW9uIFwiYmxhaGJsYWhcIiBpcyBub3QgZGVmaW5lZCBvciBpcyBub3QgYW4gIgorICAgICAgICAgICAgICAgICJleHRlbnNpb24gb2YgXCJwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXNcIi4iLAorICAgICAgICAgICAgICAgIDEsIDExKTsKK30KKworVEVTVF9GKFRleHRGb3JtYXRQYXJzZXJUZXN0LCBNaXNzaW5nUmVxdWlyZWQpIHsKKyAgdW5pdHRlc3Q6OlRlc3RSZXF1aXJlZCBtZXNzYWdlOworICBFeHBlY3RGYWlsdXJlKCJhOiAxIiwKKyAgICAgICAgICAgICAgICAiTWVzc2FnZSBtaXNzaW5nIHJlcXVpcmVkIGZpZWxkczogYiwgYyIsCisgICAgICAgICAgICAgICAgMCwgMSwgJm1lc3NhZ2UpOworfQorCitURVNUX0YoVGV4dEZvcm1hdFBhcnNlclRlc3QsIFBhcnNlRHVwbGljYXRlUmVxdWlyZWQpIHsKKyAgdW5pdHRlc3Q6OlRlc3RSZXF1aXJlZCBtZXNzYWdlOworICBFeHBlY3RGYWlsdXJlKCJhOiAxIGI6IDIgYzogMyBhOiAxIiwKKyAgICAgICAgICAgICAgICAiTm9uLXJlcGVhdGVkIGZpZWxkIFwiYVwiIGlzIHNwZWNpZmllZCBtdWx0aXBsZSB0aW1lcy4iLAorICAgICAgICAgICAgICAgIDEsIDE3LCAmbWVzc2FnZSk7Cit9CisKK1RFU1RfRihUZXh0Rm9ybWF0UGFyc2VyVGVzdCwgUGFyc2VEdXBsaWNhdGVPcHRpb25hbCkgeworICB1bml0dGVzdDo6Rm9yZWlnbk1lc3NhZ2UgbWVzc2FnZTsKKyAgRXhwZWN0RmFpbHVyZSgiYzogMSBjOiAyIiwKKyAgICAgICAgICAgICAgICAiTm9uLXJlcGVhdGVkIGZpZWxkIFwiY1wiIGlzIHNwZWNpZmllZCBtdWx0aXBsZSB0aW1lcy4iLAorICAgICAgICAgICAgICAgIDEsIDcsICZtZXNzYWdlKTsKK30KKworVEVTVF9GKFRleHRGb3JtYXRQYXJzZXJUZXN0LCBNZXJnZUR1cGxpY2F0ZVJlcXVpcmVkKSB7CisgIHVuaXR0ZXN0OjpUZXN0UmVxdWlyZWQgbWVzc2FnZTsKKyAgVGV4dEZvcm1hdDo6UGFyc2VyIHBhcnNlcjsKKyAgRVhQRUNUX1RSVUUocGFyc2VyLk1lcmdlRnJvbVN0cmluZygiYTogMSBiOiAyIGM6IDMgYTogNCIsICZtZXNzYWdlKSk7CisgIEVYUEVDVF9FUSg0LCBtZXNzYWdlLmEoKSk7Cit9CisKK1RFU1RfRihUZXh0Rm9ybWF0UGFyc2VyVGVzdCwgTWVyZ2VEdXBsaWNhdGVPcHRpb25hbCkgeworICB1bml0dGVzdDo6Rm9yZWlnbk1lc3NhZ2UgbWVzc2FnZTsKKyAgVGV4dEZvcm1hdDo6UGFyc2VyIHBhcnNlcjsKKyAgRVhQRUNUX1RSVUUocGFyc2VyLk1lcmdlRnJvbVN0cmluZygiYzogMSBjOiAyIiwgJm1lc3NhZ2UpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UuYygpKTsKK30KKworVEVTVF9GKFRleHRGb3JtYXRQYXJzZXJUZXN0LCBFeHBsaWNpdERlbGltaXRlcnMpIHsKKyAgdW5pdHRlc3Q6OlRlc3RSZXF1aXJlZCBtZXNzYWdlOworICBFWFBFQ1RfVFJVRShUZXh0Rm9ybWF0OjpQYXJzZUZyb21TdHJpbmcoImE6MSxiOjI7YzozIiwgJm1lc3NhZ2UpKTsKKyAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UuYSgpKTsKKyAgRVhQRUNUX0VRKDIsIG1lc3NhZ2UuYigpKTsKKyAgRVhQRUNUX0VRKDMsIG1lc3NhZ2UuYygpKTsKK30KKworVEVTVF9GKFRleHRGb3JtYXRQYXJzZXJUZXN0LCBQcmludEVycm9yc1RvU3RkZXJyKSB7CisgIHZlY3RvcjxzdHJpbmc+IGVycm9yczsKKworICB7CisgICAgU2NvcGVkTWVtb3J5TG9nIGxvZzsKKyAgICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIHByb3RvOworICAgIEVYUEVDVF9GQUxTRShUZXh0Rm9ybWF0OjpQYXJzZUZyb21TdHJpbmcoIm5vX3N1Y2hfZmllbGQ6IDEiLCAmcHJvdG8pKTsKKyAgICBlcnJvcnMgPSBsb2cuR2V0TWVzc2FnZXMoRVJST1IpOworICB9CisKKyAgQVNTRVJUX0VRKDEsIGVycm9ycy5zaXplKCkpOworICBFWFBFQ1RfRVEoIkVycm9yIHBhcnNpbmcgdGV4dC1mb3JtYXQgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzOiAiCisgICAgICAgICAgICAiMToxNDogTWVzc2FnZSB0eXBlIFwicHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzXCIgaGFzIG5vIGZpZWxkICIKKyAgICAgICAgICAgICJuYW1lZCBcIm5vX3N1Y2hfZmllbGRcIi4iLAorICAgICAgICAgICAgZXJyb3JzWzBdKTsKK30KKworVEVTVF9GKFRleHRGb3JtYXRQYXJzZXJUZXN0LCBGYWlsc09uVG9rZW5pemF0aW9uRXJyb3IpIHsKKyAgdmVjdG9yPHN0cmluZz4gZXJyb3JzOworCisgIHsKKyAgICBTY29wZWRNZW1vcnlMb2cgbG9nOworICAgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgcHJvdG87CisgICAgRVhQRUNUX0ZBTFNFKFRleHRGb3JtYXQ6OlBhcnNlRnJvbVN0cmluZygiXDAyMCIsICZwcm90bykpOworICAgIGVycm9ycyA9IGxvZy5HZXRNZXNzYWdlcyhFUlJPUik7CisgIH0KKworICBBU1NFUlRfRVEoMSwgZXJyb3JzLnNpemUoKSk7CisgIEVYUEVDVF9FUSgiRXJyb3IgcGFyc2luZyB0ZXh0LWZvcm1hdCBwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXM6ICIKKyAgICAgICAgICAgICIxOjE6IEludmFsaWQgY29udHJvbCBjaGFyYWN0ZXJzIGVuY291bnRlcmVkIGluIHRleHQuIiwKKyAgICAgICAgICAgIGVycm9yc1swXSk7Cit9CisKK1RFU1RfRihUZXh0Rm9ybWF0UGFyc2VyVGVzdCwgUGFyc2VEZXByZWNhdGVkRmllbGQpIHsKKyAgdW5pdHRlc3Q6OlRlc3REZXByZWNhdGVkRmllbGRzIG1lc3NhZ2U7CisgIEV4cGVjdE1lc3NhZ2UoImRlcHJlY2F0ZWRfaW50MzI6IDQyIiwKKyAgICAgICAgICAgICAgICAiV0FSTklORzp0ZXh0IGZvcm1hdCBjb250YWlucyBkZXByZWNhdGVkIGZpZWxkICIKKyAgICAgICAgICAgICAgICAiXCJkZXByZWNhdGVkX2ludDMyXCIiLCAxLCAyMSwgJm1lc3NhZ2UsIHRydWUpOworfQorCitjbGFzcyBUZXh0Rm9ybWF0TWVzc2FnZVNldFRlc3QgOiBwdWJsaWMgdGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICBzdGF0aWMgY29uc3QgY2hhciBwcm90b19kZWJ1Z19zdHJpbmdfW107Cit9OworY29uc3QgY2hhciBUZXh0Rm9ybWF0TWVzc2FnZVNldFRlc3Q6OnByb3RvX2RlYnVnX3N0cmluZ19bXSA9CisibWVzc2FnZV9zZXQge1xuIgorIiAgW3Byb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMV0ge1xuIgorIiAgICBpOiAyM1xuIgorIiAgfVxuIgorIiAgW3Byb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMl0ge1xuIgorIiAgICBzdHI6IFwiZm9vXCJcbiIKKyIgIH1cbiIKKyJ9XG4iOworCisKK1RFU1RfRihUZXh0Rm9ybWF0TWVzc2FnZVNldFRlc3QsIFNlcmlhbGl6ZSkgeworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdE1lc3NhZ2VTZXRDb250YWluZXIgcHJvdG87CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjEqIGl0ZW1fYSA9CisgICAgcHJvdG8ubXV0YWJsZV9tZXNzYWdlX3NldCgpLT5NdXRhYmxlRXh0ZW5zaW9uKAorICAgICAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMTo6bWVzc2FnZV9zZXRfZXh0ZW5zaW9uKTsKKyAgaXRlbV9hLT5zZXRfaSgyMyk7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjIqIGl0ZW1fYiA9CisgICAgcHJvdG8ubXV0YWJsZV9tZXNzYWdlX3NldCgpLT5NdXRhYmxlRXh0ZW5zaW9uKAorICAgICAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMjo6bWVzc2FnZV9zZXRfZXh0ZW5zaW9uKTsKKyAgaXRlbV9iLT5zZXRfc3RyKCJmb28iKTsKKyAgRVhQRUNUX0VRKHByb3RvX2RlYnVnX3N0cmluZ18sIHByb3RvLkRlYnVnU3RyaW5nKCkpOworfQorCitURVNUX0YoVGV4dEZvcm1hdE1lc3NhZ2VTZXRUZXN0LCBEZXNlcmlhbGl6ZSkgeworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdE1lc3NhZ2VTZXRDb250YWluZXIgcHJvdG87CisgIEFTU0VSVF9UUlVFKFRleHRGb3JtYXQ6OlBhcnNlRnJvbVN0cmluZyhwcm90b19kZWJ1Z19zdHJpbmdfLCAmcHJvdG8pKTsKKyAgRVhQRUNUX0VRKDIzLCBwcm90by5tZXNzYWdlX3NldCgpLkdldEV4dGVuc2lvbigKKyAgICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xOjptZXNzYWdlX3NldF9leHRlbnNpb24pLmkoKSk7CisgIEVYUEVDVF9FUSgiZm9vIiwgcHJvdG8ubWVzc2FnZV9zZXQoKS5HZXRFeHRlbnNpb24oCisgICAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMjo6bWVzc2FnZV9zZXRfZXh0ZW5zaW9uKS5zdHIoKSk7CisKKyAgLy8gRW5zdXJlIHRoYXQgdGhlc2UgYXJlIHRoZSBvbmx5IGVudHJpZXMgcHJlc2VudC4KKyAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+IGRlc2NyaXB0b3JzOworICBwcm90by5tZXNzYWdlX3NldCgpLkdldFJlZmxlY3Rpb24oKS0+TGlzdEZpZWxkcygKKyAgICBwcm90by5tZXNzYWdlX3NldCgpLCAmZGVzY3JpcHRvcnMpOworICBFWFBFQ1RfRVEoMiwgZGVzY3JpcHRvcnMuc2l6ZSgpKTsKK30KKworCit9ICAvLyBuYW1lc3BhY2UgdGV4dF9mb3JtYXRfdW5pdHRlc3QKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi90aW1lc3RhbXAucGIuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3RpbWVzdGFtcC5wYi5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMWM0NDAyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90aW1lc3RhbXAucGIuY2MKQEAgLTAsMCArMSw0MzQgQEAKKy8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCisvLyBzb3VyY2U6IGdvb2dsZS9wcm90b2J1Zi90aW1lc3RhbXAucHJvdG8KKworI2RlZmluZSBJTlRFUk5BTF9TVVBQUkVTU19QUk9UT0JVRl9GSUVMRF9ERVBSRUNBVElPTgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90aW1lc3RhbXAucGIuaD4KKworI2luY2x1ZGUgPGFsZ29yaXRobT4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvcG9ydC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9vbmNlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdF9saXRlX2lubC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9tZXNzYWdlX3JlZmxlY3Rpb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcmVmbGVjdGlvbl9vcHMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuaD4KKy8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbmNsdWRlcykKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCituYW1lc3BhY2UgeworCitjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIFRpbWVzdGFtcF9kZXNjcmlwdG9yXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbioKKyAgVGltZXN0YW1wX3JlZmxlY3Rpb25fID0gTlVMTDsKKworfSAgLy8gbmFtZXNwYWNlCisKKwordm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmdGltZXN0YW1wXzJlcHJvdG8oKSB7CisgIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZ0aW1lc3RhbXBfMmVwcm90bygpOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVEZXNjcmlwdG9yKiBmaWxlID0KKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQb29sOjpnZW5lcmF0ZWRfcG9vbCgpLT5GaW5kRmlsZUJ5TmFtZSgKKyAgICAgICJnb29nbGUvcHJvdG9idWYvdGltZXN0YW1wLnByb3RvIik7CisgIEdPT0dMRV9DSEVDSyhmaWxlICE9IE5VTEwpOworICBUaW1lc3RhbXBfZGVzY3JpcHRvcl8gPSBmaWxlLT5tZXNzYWdlX3R5cGUoMCk7CisgIHN0YXRpYyBjb25zdCBpbnQgVGltZXN0YW1wX29mZnNldHNfWzJdID0geworICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoVGltZXN0YW1wLCBzZWNvbmRzXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChUaW1lc3RhbXAsIG5hbm9zXyksCisgIH07CisgIFRpbWVzdGFtcF9yZWZsZWN0aW9uXyA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok5ld0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKAorICAgICAgVGltZXN0YW1wX2Rlc2NyaXB0b3JfLAorICAgICAgVGltZXN0YW1wOjpkZWZhdWx0X2luc3RhbmNlXywKKyAgICAgIFRpbWVzdGFtcF9vZmZzZXRzXywKKyAgICAgIC0xLAorICAgICAgLTEsCisgICAgICAtMSwKKyAgICAgIHNpemVvZihUaW1lc3RhbXApLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChUaW1lc3RhbXAsIF9pbnRlcm5hbF9tZXRhZGF0YV8pLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChUaW1lc3RhbXAsIF9pc19kZWZhdWx0X2luc3RhbmNlXykpOworfQorCituYW1lc3BhY2UgeworCitHT09HTEVfUFJPVE9CVUZfREVDTEFSRV9PTkNFKHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzX29uY2VfKTsKK2lubGluZSB2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpIHsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpHb29nbGVPbmNlSW5pdCgmcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNfb25jZV8sCisgICAgICAgICAgICAgICAgICZwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmdGltZXN0YW1wXzJlcHJvdG8pOworfQorCit2b2lkIHByb3RvYnVmX1JlZ2lzdGVyVHlwZXMoY29uc3QgOjpzdGQ6OnN0cmluZyYpIHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZUZhY3Rvcnk6OkludGVybmFsUmVnaXN0ZXJHZW5lcmF0ZWRNZXNzYWdlKAorICAgICAgVGltZXN0YW1wX2Rlc2NyaXB0b3JfLCAmVGltZXN0YW1wOjpkZWZhdWx0X2luc3RhbmNlKCkpOworfQorCit9ICAvLyBuYW1lc3BhY2UKKwordm9pZCBwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZ0aW1lc3RhbXBfMmVwcm90bygpIHsKKyAgZGVsZXRlIFRpbWVzdGFtcDo6ZGVmYXVsdF9pbnN0YW5jZV87CisgIGRlbGV0ZSBUaW1lc3RhbXBfcmVmbGVjdGlvbl87Cit9CisKK3ZvaWQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZnRpbWVzdGFtcF8yZXByb3RvKCkgeworICBzdGF0aWMgYm9vbCBhbHJlYWR5X2hlcmUgPSBmYWxzZTsKKyAgaWYgKGFscmVhZHlfaGVyZSkgcmV0dXJuOworICBhbHJlYWR5X2hlcmUgPSB0cnVlOworICBHT09HTEVfUFJPVE9CVUZfVkVSSUZZX1ZFUlNJT047CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUG9vbDo6SW50ZXJuYWxBZGRHZW5lcmF0ZWRGaWxlKAorICAgICJcblwwMzdnb29nbGUvcHJvdG9idWYvdGltZXN0YW1wLnByb3RvXDAyMlwwMTdnb29nbCIKKyAgICAiZS5wcm90b2J1ZlwiK1xuXHRUaW1lc3RhbXBcMDIyXDAxN1xuXDAwN3NlY29uZHNcMDMwXDAwMSBcMDAxKFwwMDMiCisgICAgIlwwMjJcclxuXDAwNW5hbm9zXDAzMFwwMDIgXDAwMShcMDA1QlRcblwwMjNjb20uZ29vZ2xlLnByb3RvYnVmQlwwMTYiCisgICAgIlRpbWVzdGFtcFByb3RvUFwwMDFcMjQwXDAwMVwwMDFcMzcwXDAwMVwwMDFcMjQyXDAwMlwwMDNHUEJcMjUyXDAwMlwwMzZHb29nbGUuUHIiCisgICAgIm90b2J1Zi5XZWxsS25vd25UeXBlc2JcMDA2cHJvdG8zIiwgMTg5KTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZEZpbGUoCisgICAgImdvb2dsZS9wcm90b2J1Zi90aW1lc3RhbXAucHJvdG8iLCAmcHJvdG9idWZfUmVnaXN0ZXJUeXBlcyk7CisgIFRpbWVzdGFtcDo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBuZXcgVGltZXN0YW1wKCk7CisgIFRpbWVzdGFtcDo6ZGVmYXVsdF9pbnN0YW5jZV8tPkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpPblNodXRkb3duKCZwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZ0aW1lc3RhbXBfMmVwcm90byk7Cit9CisKKy8vIEZvcmNlIEFkZERlc2NyaXB0b3JzKCkgdG8gYmUgY2FsbGVkIGF0IHN0YXRpYyBpbml0aWFsaXphdGlvbiB0aW1lLgorc3RydWN0IFN0YXRpY0Rlc2NyaXB0b3JJbml0aWFsaXplcl9nb29nbGVfMmZwcm90b2J1Zl8yZnRpbWVzdGFtcF8yZXByb3RvIHsKKyAgU3RhdGljRGVzY3JpcHRvckluaXRpYWxpemVyX2dvb2dsZV8yZnByb3RvYnVmXzJmdGltZXN0YW1wXzJlcHJvdG8oKSB7CisgICAgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZnRpbWVzdGFtcF8yZXByb3RvKCk7CisgIH0KK30gc3RhdGljX2Rlc2NyaXB0b3JfaW5pdGlhbGl6ZXJfZ29vZ2xlXzJmcHJvdG9idWZfMmZ0aW1lc3RhbXBfMmVwcm90b187CisKK25hbWVzcGFjZSB7CisKK3N0YXRpYyB2b2lkIE1lcmdlRnJvbUZhaWwoaW50IGxpbmUpIEdPT0dMRV9BVFRSSUJVVEVfQ09MRDsKK3N0YXRpYyB2b2lkIE1lcmdlRnJvbUZhaWwoaW50IGxpbmUpIHsKKyAgR09PR0xFX0NIRUNLKGZhbHNlKSA8PCBfX0ZJTEVfXyA8PCAiOiIgPDwgbGluZTsKK30KKworfSAgLy8gbmFtZXNwYWNlCisKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisjaWYgIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKK2NvbnN0IGludCBUaW1lc3RhbXA6OmtTZWNvbmRzRmllbGROdW1iZXI7Citjb25zdCBpbnQgVGltZXN0YW1wOjprTmFub3NGaWVsZE51bWJlcjsKKyNlbmRpZiAgLy8gIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKKworVGltZXN0YW1wOjpUaW1lc3RhbXAoKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpLCBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCkKK30KKworVGltZXN0YW1wOjpUaW1lc3RhbXAoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksCisgIF9pbnRlcm5hbF9tZXRhZGF0YV8oYXJlbmEpIHsKKyAgU2hhcmVkQ3RvcigpOworICBSZWdpc3RlckFyZW5hRHRvcihhcmVuYSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChhcmVuYV9jb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuVGltZXN0YW1wKQorfQorCit2b2lkIFRpbWVzdGFtcDo6SW5pdEFzRGVmYXVsdEluc3RhbmNlKCkgeworICBfaXNfZGVmYXVsdF9pbnN0YW5jZV8gPSB0cnVlOworfQorCitUaW1lc3RhbXA6OlRpbWVzdGFtcChjb25zdCBUaW1lc3RhbXAmIGZyb20pCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksCisgICAgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29weV9jb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuVGltZXN0YW1wKQorfQorCit2b2lkIFRpbWVzdGFtcDo6U2hhcmVkQ3RvcigpIHsKKyAgICBfaXNfZGVmYXVsdF9pbnN0YW5jZV8gPSBmYWxzZTsKKyAgX2NhY2hlZF9zaXplXyA9IDA7CisgIHNlY29uZHNfID0gR09PR0xFX0xPTkdMT05HKDApOworICBuYW5vc18gPSAwOworfQorCitUaW1lc3RhbXA6On5UaW1lc3RhbXAoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChkZXN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXApCisgIFNoYXJlZER0b3IoKTsKK30KKwordm9pZCBUaW1lc3RhbXA6OlNoYXJlZER0b3IoKSB7CisgIGlmIChHZXRBcmVuYU5vVmlydHVhbCgpICE9IE5VTEwpIHsKKyAgICByZXR1cm47CisgIH0KKworICBpZiAodGhpcyAhPSBkZWZhdWx0X2luc3RhbmNlXykgeworICB9Cit9CisKK3ZvaWQgVGltZXN0YW1wOjpBcmVuYUR0b3Iodm9pZCogb2JqZWN0KSB7CisgIFRpbWVzdGFtcCogX3RoaXMgPSByZWludGVycHJldF9jYXN0PCBUaW1lc3RhbXAqID4ob2JqZWN0KTsKKyAgKHZvaWQpX3RoaXM7Cit9Cit2b2lkIFRpbWVzdGFtcDo6UmVnaXN0ZXJBcmVuYUR0b3IoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIHsKK30KK3ZvaWQgVGltZXN0YW1wOjpTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdCB7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSBzaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogVGltZXN0YW1wOjpkZXNjcmlwdG9yKCkgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgcmV0dXJuIFRpbWVzdGFtcF9kZXNjcmlwdG9yXzsKK30KKworY29uc3QgVGltZXN0YW1wJiBUaW1lc3RhbXA6OmRlZmF1bHRfaW5zdGFuY2UoKSB7CisgIGlmIChkZWZhdWx0X2luc3RhbmNlXyA9PSBOVUxMKSBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmdGltZXN0YW1wXzJlcHJvdG8oKTsKKyAgcmV0dXJuICpkZWZhdWx0X2luc3RhbmNlXzsKK30KKworVGltZXN0YW1wKiBUaW1lc3RhbXA6OmRlZmF1bHRfaW5zdGFuY2VfID0gTlVMTDsKKworVGltZXN0YW1wKiBUaW1lc3RhbXA6Ok5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3QgeworICByZXR1cm4gOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYTo6Q3JlYXRlTWVzc2FnZTxUaW1lc3RhbXA+KGFyZW5hKTsKK30KKwordm9pZCBUaW1lc3RhbXA6OkNsZWFyKCkgeworI2RlZmluZSBaUl9IRUxQRVJfKGYpIHJlaW50ZXJwcmV0X2Nhc3Q8Y2hhcio+KFwKKyAgJnJlaW50ZXJwcmV0X2Nhc3Q8VGltZXN0YW1wKj4oMTYpLT5mKQorCisjZGVmaW5lIFpSXyhmaXJzdCwgbGFzdCkgZG8ge1wKKyAgOjptZW1zZXQoJmZpcnN0LCAwLFwKKyAgICAgICAgICAgWlJfSEVMUEVSXyhsYXN0KSAtIFpSX0hFTFBFUl8oZmlyc3QpICsgc2l6ZW9mKGxhc3QpKTtcCit9IHdoaWxlICgwKQorCisgIFpSXyhzZWNvbmRzXywgbmFub3NfKTsKKworI3VuZGVmIFpSX0hFTFBFUl8KKyN1bmRlZiBaUl8KKworfQorCitib29sIFRpbWVzdGFtcDo6TWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KSB7CisjZGVmaW5lIERPXyhFWFBSRVNTSU9OKSBpZiAoIShFWFBSRVNTSU9OKSkgZ290byBmYWlsdXJlCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIHRhZzsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXApCisgIGZvciAoOzspIHsKKyAgICA6OnN0ZDo6cGFpcjwgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIsIGJvb2w+IHAgPSBpbnB1dC0+UmVhZFRhZ1dpdGhDdXRvZmYoMTI3KTsKKyAgICB0YWcgPSBwLmZpcnN0OworICAgIGlmICghcC5zZWNvbmQpIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgc3dpdGNoICg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnRmllbGROdW1iZXIodGFnKSkgeworICAgICAgLy8gb3B0aW9uYWwgaW50NjQgc2Vjb25kcyA9IDE7CisgICAgICBjYXNlIDE6IHsKKyAgICAgICAgaWYgKHRhZyA9PSA4KSB7CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludDY0LCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9JTlQ2ND4oCisgICAgICAgICAgICAgICAgIGlucHV0LCAmc2Vjb25kc18pKSk7CisKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDE2KSkgZ290byBwYXJzZV9uYW5vczsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIGludDMyIG5hbm9zID0gMjsKKyAgICAgIGNhc2UgMjogeworICAgICAgICBpZiAodGFnID09IDE2KSB7CisgICAgICAgICBwYXJzZV9uYW5vczoKKyAgICAgICAgICBET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPAorICAgICAgICAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0lOVDMyPigKKyAgICAgICAgICAgICAgICAgaW5wdXQsICZuYW5vc18pKSk7CisKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0QXRFbmQoKSkgZ290byBzdWNjZXNzOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgZGVmYXVsdDogeworICAgICAgaGFuZGxlX3VudXN1YWw6CisgICAgICAgIGlmICh0YWcgPT0gMCB8fAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ1dpcmVUeXBlKHRhZykgPT0KKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVApIHsKKyAgICAgICAgICBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIH0KKyAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTa2lwRmllbGQoaW5wdXQsIHRhZykpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KK3N1Y2Nlc3M6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdWNjZXNzOmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXApCisgIHJldHVybiB0cnVlOworZmFpbHVyZToKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX2ZhaWx1cmU6Z29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCkKKyAgcmV0dXJuIGZhbHNlOworI3VuZGVmIERPXworfQorCit2b2lkIFRpbWVzdGFtcDo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9zdGFydDpnb29nbGUucHJvdG9idWYuVGltZXN0YW1wKQorICAvLyBvcHRpb25hbCBpbnQ2NCBzZWNvbmRzID0gMTsKKyAgaWYgKHRoaXMtPnNlY29uZHMoKSAhPSAwKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlSW50NjQoMSwgdGhpcy0+c2Vjb25kcygpLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgaW50MzIgbmFub3MgPSAyOworICBpZiAodGhpcy0+bmFub3MoKSAhPSAwKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlSW50MzIoMiwgdGhpcy0+bmFub3MoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfZW5kOmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXApCit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIFRpbWVzdGFtcDo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiB0YXJnZXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9zdGFydDpnb29nbGUucHJvdG9idWYuVGltZXN0YW1wKQorICAvLyBvcHRpb25hbCBpbnQ2NCBzZWNvbmRzID0gMTsKKyAgaWYgKHRoaXMtPnNlY29uZHMoKSAhPSAwKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlSW50NjRUb0FycmF5KDEsIHRoaXMtPnNlY29uZHMoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGludDMyIG5hbm9zID0gMjsKKyAgaWYgKHRoaXMtPm5hbm9zKCkgIT0gMCkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUludDMyVG9BcnJheSgyLCB0aGlzLT5uYW5vcygpLCB0YXJnZXQpOworICB9CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9lbmQ6Z29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCkKKyAgcmV0dXJuIHRhcmdldDsKK30KKworaW50IFRpbWVzdGFtcDo6Qnl0ZVNpemUoKSBjb25zdCB7CisgIGludCB0b3RhbF9zaXplID0gMDsKKworICAvLyBvcHRpb25hbCBpbnQ2NCBzZWNvbmRzID0gMTsKKyAgaWYgKHRoaXMtPnNlY29uZHMoKSAhPSAwKSB7CisgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpJbnQ2NFNpemUoCisgICAgICAgIHRoaXMtPnNlY29uZHMoKSk7CisgIH0KKworICAvLyBvcHRpb25hbCBpbnQzMiBuYW5vcyA9IDI7CisgIGlmICh0aGlzLT5uYW5vcygpICE9IDApIHsKKyAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkludDMyU2l6ZSgKKyAgICAgICAgdGhpcy0+bmFub3MoKSk7CisgIH0KKworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gdG90YWxfc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7CisgIHJldHVybiB0b3RhbF9zaXplOworfQorCit2b2lkIFRpbWVzdGFtcDo6TWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBjb25zdCBUaW1lc3RhbXAqIHNvdXJjZSA9IAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RHluYW1pY0Nhc3RUb0dlbmVyYXRlZDxjb25zdCBUaW1lc3RhbXA+KAorICAgICAgICAgICZmcm9tKTsKKyAgaWYgKHNvdXJjZSA9PSBOVUxMKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6UmVmbGVjdGlvbk9wczo6TWVyZ2UoZnJvbSwgdGhpcyk7CisgIH0gZWxzZSB7CisgICAgTWVyZ2VGcm9tKCpzb3VyY2UpOworICB9Cit9CisKK3ZvaWQgVGltZXN0YW1wOjpNZXJnZUZyb20oY29uc3QgVGltZXN0YW1wJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGlmIChmcm9tLnNlY29uZHMoKSAhPSAwKSB7CisgICAgc2V0X3NlY29uZHMoZnJvbS5zZWNvbmRzKCkpOworICB9CisgIGlmIChmcm9tLm5hbm9zKCkgIT0gMCkgeworICAgIHNldF9uYW5vcyhmcm9tLm5hbm9zKCkpOworICB9Cit9CisKK3ZvaWQgVGltZXN0YW1wOjpDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCit2b2lkIFRpbWVzdGFtcDo6Q29weUZyb20oY29uc3QgVGltZXN0YW1wJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKworYm9vbCBUaW1lc3RhbXA6OklzSW5pdGlhbGl6ZWQoKSBjb25zdCB7CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgVGltZXN0YW1wOjpTd2FwKFRpbWVzdGFtcCogb3RoZXIpIHsKKyAgaWYgKG90aGVyID09IHRoaXMpIHJldHVybjsKKyAgaWYgKEdldEFyZW5hTm9WaXJ0dWFsKCkgPT0gb3RoZXItPkdldEFyZW5hTm9WaXJ0dWFsKCkpIHsKKyAgICBJbnRlcm5hbFN3YXAob3RoZXIpOworICB9IGVsc2UgeworICAgIFRpbWVzdGFtcCB0ZW1wOworICAgIHRlbXAuTWVyZ2VGcm9tKCp0aGlzKTsKKyAgICBDb3B5RnJvbSgqb3RoZXIpOworICAgIG90aGVyLT5Db3B5RnJvbSh0ZW1wKTsKKyAgfQorfQordm9pZCBUaW1lc3RhbXA6OlVuc2FmZUFyZW5hU3dhcChUaW1lc3RhbXAqIG90aGVyKSB7CisgIGlmIChvdGhlciA9PSB0aGlzKSByZXR1cm47CisgIEdPT0dMRV9EQ0hFQ0soR2V0QXJlbmFOb1ZpcnR1YWwoKSA9PSBvdGhlci0+R2V0QXJlbmFOb1ZpcnR1YWwoKSk7CisgIEludGVybmFsU3dhcChvdGhlcik7Cit9Cit2b2lkIFRpbWVzdGFtcDo6SW50ZXJuYWxTd2FwKFRpbWVzdGFtcCogb3RoZXIpIHsKKyAgc3RkOjpzd2FwKHNlY29uZHNfLCBvdGhlci0+c2Vjb25kc18pOworICBzdGQ6OnN3YXAobmFub3NfLCBvdGhlci0+bmFub3NfKTsKKyAgX2ludGVybmFsX21ldGFkYXRhXy5Td2FwKCZvdGhlci0+X2ludGVybmFsX21ldGFkYXRhXyk7CisgIHN0ZDo6c3dhcChfY2FjaGVkX3NpemVfLCBvdGhlci0+X2NhY2hlZF9zaXplXyk7Cit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgVGltZXN0YW1wOjpHZXRNZXRhZGF0YSgpIGNvbnN0IHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgbWV0YWRhdGE7CisgIG1ldGFkYXRhLmRlc2NyaXB0b3IgPSBUaW1lc3RhbXBfZGVzY3JpcHRvcl87CisgIG1ldGFkYXRhLnJlZmxlY3Rpb24gPSBUaW1lc3RhbXBfcmVmbGVjdGlvbl87CisgIHJldHVybiBtZXRhZGF0YTsKK30KKworI2lmIFBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworLy8gVGltZXN0YW1wCisKKy8vIG9wdGlvbmFsIGludDY0IHNlY29uZHMgPSAxOwordm9pZCBUaW1lc3RhbXA6OmNsZWFyX3NlY29uZHMoKSB7CisgIHNlY29uZHNfID0gR09PR0xFX0xPTkdMT05HKDApOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50NjQgVGltZXN0YW1wOjpzZWNvbmRzKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAuc2Vjb25kcykKKyAgcmV0dXJuIHNlY29uZHNfOworfQorIHZvaWQgVGltZXN0YW1wOjpzZXRfc2Vjb25kcyg6Omdvb2dsZTo6cHJvdG9idWY6OmludDY0IHZhbHVlKSB7CisgIAorICBzZWNvbmRzXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAuc2Vjb25kcykKK30KKworLy8gb3B0aW9uYWwgaW50MzIgbmFub3MgPSAyOwordm9pZCBUaW1lc3RhbXA6OmNsZWFyX25hbm9zKCkgeworICBuYW5vc18gPSAwOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgVGltZXN0YW1wOjpuYW5vcygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuVGltZXN0YW1wLm5hbm9zKQorICByZXR1cm4gbmFub3NfOworfQorIHZvaWQgVGltZXN0YW1wOjpzZXRfbmFub3MoOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiB2YWx1ZSkgeworICAKKyAgbmFub3NfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcC5uYW5vcykKK30KKworI2VuZGlmICAvLyBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKworLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG5hbWVzcGFjZV9zY29wZSkKKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKy8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChnbG9iYWxfc2NvcGUpCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3RpbWVzdGFtcC5wYi5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90aW1lc3RhbXAucGIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43YmY2MjU5Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90aW1lc3RhbXAucGIuaApAQCAtMCwwICsxLDE4NSBAQAorLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCEKKy8vIHNvdXJjZTogZ29vZ2xlL3Byb3RvYnVmL3RpbWVzdGFtcC5wcm90bworCisjaWZuZGVmIFBST1RPQlVGX2dvb2dsZV8yZnByb3RvYnVmXzJmdGltZXN0YW1wXzJlcHJvdG9fX0lOQ0xVREVECisjZGVmaW5lIFBST1RPQlVGX2dvb2dsZV8yZnByb3RvYnVmXzJmdGltZXN0YW1wXzJlcHJvdG9fX0lOQ0xVREVECisKKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisKKyNpZiBHT09HTEVfUFJPVE9CVUZfVkVSU0lPTiA8IDMwMDAwMDAKKyNlcnJvciBUaGlzIGZpbGUgd2FzIGdlbmVyYXRlZCBieSBhIG5ld2VyIHZlcnNpb24gb2YgcHJvdG9jIHdoaWNoIGlzCisjZXJyb3IgaW5jb21wYXRpYmxlIHdpdGggeW91ciBQcm90b2NvbCBCdWZmZXIgaGVhZGVycy4gIFBsZWFzZSB1cGRhdGUKKyNlcnJvciB5b3VyIGhlYWRlcnMuCisjZW5kaWYKKyNpZiAzMDAwMDAwIDwgR09PR0xFX1BST1RPQlVGX01JTl9QUk9UT0NfVkVSU0lPTgorI2Vycm9yIFRoaXMgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IGFuIG9sZGVyIHZlcnNpb24gb2YgcHJvdG9jIHdoaWNoIGlzCisjZXJyb3IgaW5jb21wYXRpYmxlIHdpdGggeW91ciBQcm90b2NvbCBCdWZmZXIgaGVhZGVycy4gIFBsZWFzZQorI2Vycm9yIHJlZ2VuZXJhdGUgdGhpcyBmaWxlIHdpdGggYSBuZXdlciB2ZXJzaW9uIG9mIHByb3RvYy4KKyNlbmRpZgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2FyZW5hLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2FyZW5hc3RyaW5nLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2dlbmVyYXRlZF9tZXNzYWdlX3V0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWV0YWRhdGEuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWVzc2FnZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9yZXBlYXRlZF9maWVsZC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9leHRlbnNpb25fc2V0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Vua25vd25fZmllbGRfc2V0Lmg+CisvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW5jbHVkZXMpCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworLy8gSW50ZXJuYWwgaW1wbGVtZW50YXRpb24gZGV0YWlsIC0tIGRvIG5vdCBjYWxsIHRoZXNlLgordm9pZCBMSUJQUk9UT0JVRl9FWFBPUlQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZnRpbWVzdGFtcF8yZXByb3RvKCk7Cit2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZ0aW1lc3RhbXBfMmVwcm90bygpOwordm9pZCBwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZ0aW1lc3RhbXBfMmVwcm90bygpOworCitjbGFzcyBUaW1lc3RhbXA7CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFRpbWVzdGFtcCA6IHB1YmxpYyA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UgeworIHB1YmxpYzoKKyAgVGltZXN0YW1wKCk7CisgIHZpcnR1YWwgflRpbWVzdGFtcCgpOworCisgIFRpbWVzdGFtcChjb25zdCBUaW1lc3RhbXAmIGZyb20pOworCisgIGlubGluZSBUaW1lc3RhbXAmIG9wZXJhdG9yPShjb25zdCBUaW1lc3RhbXAmIGZyb20pIHsKKyAgICBDb3B5RnJvbShmcm9tKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogR2V0QXJlbmEoKSBjb25zdCB7IHJldHVybiBHZXRBcmVuYU5vVmlydHVhbCgpOyB9CisgIGlubGluZSB2b2lkKiBHZXRNYXliZUFyZW5hUG9pbnRlcigpIGNvbnN0IHsKKyAgICByZXR1cm4gTWF5YmVBcmVuYVB0cigpOworICB9CisgIHN0YXRpYyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIGRlc2NyaXB0b3IoKTsKKyAgc3RhdGljIGNvbnN0IFRpbWVzdGFtcCYgZGVmYXVsdF9pbnN0YW5jZSgpOworCisgIHZvaWQgVW5zYWZlQXJlbmFTd2FwKFRpbWVzdGFtcCogb3RoZXIpOworICB2b2lkIFN3YXAoVGltZXN0YW1wKiBvdGhlcik7CisKKyAgLy8gaW1wbGVtZW50cyBNZXNzYWdlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBpbmxpbmUgVGltZXN0YW1wKiBOZXcoKSBjb25zdCB7IHJldHVybiBOZXcoTlVMTCk7IH0KKworICBUaW1lc3RhbXAqIE5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3Q7CisgIHZvaWQgQ29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCBUaW1lc3RhbXAmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCBUaW1lc3RhbXAmIGZyb20pOworICB2b2lkIENsZWFyKCk7CisgIGJvb2wgSXNJbml0aWFsaXplZCgpIGNvbnN0OworCisgIGludCBCeXRlU2l6ZSgpIGNvbnN0OworICBib29sIE1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KTsKKyAgdm9pZCBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSg6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBvdXRwdXQpIGNvbnN0OworICBpbnQgR2V0Q2FjaGVkU2l6ZSgpIGNvbnN0IHsgcmV0dXJuIF9jYWNoZWRfc2l6ZV87IH0KKyAgcHJpdmF0ZToKKyAgdm9pZCBTaGFyZWRDdG9yKCk7CisgIHZvaWQgU2hhcmVkRHRvcigpOworICB2b2lkIFNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0OworICB2b2lkIEludGVybmFsU3dhcChUaW1lc3RhbXAqIG90aGVyKTsKKyAgcHJvdGVjdGVkOgorICBleHBsaWNpdCBUaW1lc3RhbXAoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpOworICBwcml2YXRlOgorICBzdGF0aWMgdm9pZCBBcmVuYUR0b3Iodm9pZCogb2JqZWN0KTsKKyAgaW5saW5lIHZvaWQgUmVnaXN0ZXJBcmVuYUR0b3IoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpOworICBwcml2YXRlOgorICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogR2V0QXJlbmFOb1ZpcnR1YWwoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8uYXJlbmEoKTsKKyAgfQorICBpbmxpbmUgdm9pZCogTWF5YmVBcmVuYVB0cigpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5yYXdfYXJlbmFfcHRyKCk7CisgIH0KKyAgcHVibGljOgorCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgR2V0TWV0YWRhdGEoKSBjb25zdDsKKworICAvLyBuZXN0ZWQgdHlwZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIGFjY2Vzc29ycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gb3B0aW9uYWwgaW50NjQgc2Vjb25kcyA9IDE7CisgIHZvaWQgY2xlYXJfc2Vjb25kcygpOworICBzdGF0aWMgY29uc3QgaW50IGtTZWNvbmRzRmllbGROdW1iZXIgPSAxOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludDY0IHNlY29uZHMoKSBjb25zdDsKKyAgdm9pZCBzZXRfc2Vjb25kcyg6Omdvb2dsZTo6cHJvdG9idWY6OmludDY0IHZhbHVlKTsKKworICAvLyBvcHRpb25hbCBpbnQzMiBuYW5vcyA9IDI7CisgIHZvaWQgY2xlYXJfbmFub3MoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrTmFub3NGaWVsZE51bWJlciA9IDI7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgbmFub3MoKSBjb25zdDsKKyAgdm9pZCBzZXRfbmFub3MoOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiB2YWx1ZSk7CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXApCisgcHJpdmF0ZToKKworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpJbnRlcm5hbE1ldGFkYXRhV2l0aEFyZW5hIF9pbnRlcm5hbF9tZXRhZGF0YV87CisgIGZyaWVuZCBjbGFzcyA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hOworICB0eXBlZGVmIHZvaWQgSW50ZXJuYWxBcmVuYUNvbnN0cnVjdGFibGVfOworICB0eXBlZGVmIHZvaWQgRGVzdHJ1Y3RvclNraXBwYWJsZV87CisgIGJvb2wgX2lzX2RlZmF1bHRfaW5zdGFuY2VfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludDY0IHNlY29uZHNfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIG5hbm9zXzsKKyAgbXV0YWJsZSBpbnQgX2NhY2hlZF9zaXplXzsKKyAgZnJpZW5kIHZvaWQgTElCUFJPVE9CVUZfRVhQT1JUIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZ0aW1lc3RhbXBfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmdGltZXN0YW1wXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfU2h1dGRvd25GaWxlX2dvb2dsZV8yZnByb3RvYnVmXzJmdGltZXN0YW1wXzJlcHJvdG8oKTsKKworICB2b2lkIEluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICBzdGF0aWMgVGltZXN0YW1wKiBkZWZhdWx0X2luc3RhbmNlXzsKK307CisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisjaWYgIVBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworLy8gVGltZXN0YW1wCisKKy8vIG9wdGlvbmFsIGludDY0IHNlY29uZHMgPSAxOworaW5saW5lIHZvaWQgVGltZXN0YW1wOjpjbGVhcl9zZWNvbmRzKCkgeworICBzZWNvbmRzXyA9IEdPT0dMRV9MT05HTE9ORygwKTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OmludDY0IFRpbWVzdGFtcDo6c2Vjb25kcygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuVGltZXN0YW1wLnNlY29uZHMpCisgIHJldHVybiBzZWNvbmRzXzsKK30KK2lubGluZSB2b2lkIFRpbWVzdGFtcDo6c2V0X3NlY29uZHMoOjpnb29nbGU6OnByb3RvYnVmOjppbnQ2NCB2YWx1ZSkgeworICAKKyAgc2Vjb25kc18gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuVGltZXN0YW1wLnNlY29uZHMpCit9CisKKy8vIG9wdGlvbmFsIGludDMyIG5hbm9zID0gMjsKK2lubGluZSB2b2lkIFRpbWVzdGFtcDo6Y2xlYXJfbmFub3MoKSB7CisgIG5hbm9zXyA9IDA7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiBUaW1lc3RhbXA6Om5hbm9zKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAubmFub3MpCisgIHJldHVybiBuYW5vc187Cit9CitpbmxpbmUgdm9pZCBUaW1lc3RhbXA6OnNldF9uYW5vcyg6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKSB7CisgIAorICBuYW5vc18gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuVGltZXN0YW1wLm5hbm9zKQorfQorCisjZW5kaWYgIC8vICFQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKworLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG5hbWVzcGFjZV9zY29wZSkKKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKy8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChnbG9iYWxfc2NvcGUpCisKKyNlbmRpZiAgLy8gUFJPVE9CVUZfZ29vZ2xlXzJmcHJvdG9idWZfMmZ0aW1lc3RhbXBfMmVwcm90b19fSU5DTFVERUQKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdGltZXN0YW1wLnByb3RvIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90aW1lc3RhbXAucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjUxZmMzZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdGltZXN0YW1wLnByb3RvCkBAIC0wLDAgKzEsMTEwIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworc3ludGF4ID0gInByb3RvMyI7CisKK3BhY2thZ2UgZ29vZ2xlLnByb3RvYnVmOworCitvcHRpb24gY3NoYXJwX25hbWVzcGFjZSA9ICJHb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlwZXMiOworb3B0aW9uIGNjX2VuYWJsZV9hcmVuYXMgPSB0cnVlOworb3B0aW9uIGphdmFfcGFja2FnZSA9ICJjb20uZ29vZ2xlLnByb3RvYnVmIjsKK29wdGlvbiBqYXZhX291dGVyX2NsYXNzbmFtZSA9ICJUaW1lc3RhbXBQcm90byI7CitvcHRpb24gamF2YV9tdWx0aXBsZV9maWxlcyA9IHRydWU7CitvcHRpb24gamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2ggPSB0cnVlOworb3B0aW9uIG9iamNfY2xhc3NfcHJlZml4ID0gIkdQQiI7CisKKy8vIEEgVGltZXN0YW1wIHJlcHJlc2VudHMgYSBwb2ludCBpbiB0aW1lIGluZGVwZW5kZW50IG9mIGFueSB0aW1lIHpvbmUKKy8vIG9yIGNhbGVuZGFyLCByZXByZXNlbnRlZCBhcyBzZWNvbmRzIGFuZCBmcmFjdGlvbnMgb2Ygc2Vjb25kcyBhdAorLy8gbmFub3NlY29uZCByZXNvbHV0aW9uIGluIFVUQyBFcG9jaCB0aW1lLiBJdCBpcyBlbmNvZGVkIHVzaW5nIHRoZQorLy8gUHJvbGVwdGljIEdyZWdvcmlhbiBDYWxlbmRhciB3aGljaCBleHRlbmRzIHRoZSBHcmVnb3JpYW4gY2FsZW5kYXIKKy8vIGJhY2t3YXJkcyB0byB5ZWFyIG9uZS4gSXQgaXMgZW5jb2RlZCBhc3N1bWluZyBhbGwgbWludXRlcyBhcmUgNjAKKy8vIHNlY29uZHMgbG9uZywgaS5lLiBsZWFwIHNlY29uZHMgYXJlICJzbWVhcmVkIiBzbyB0aGF0IG5vIGxlYXAgc2Vjb25kCisvLyB0YWJsZSBpcyBuZWVkZWQgZm9yIGludGVycHJldGF0aW9uLiBSYW5nZSBpcyBmcm9tCisvLyAwMDAxLTAxLTAxVDAwOjAwOjAwWiB0byA5OTk5LTEyLTMxVDIzOjU5OjU5Ljk5OTk5OTk5OVouCisvLyBCeSByZXN0cmljdGluZyB0byB0aGF0IHJhbmdlLCB3ZSBlbnN1cmUgdGhhdCB3ZSBjYW4gY29udmVydCB0bworLy8gYW5kIGZyb20gIFJGQyAzMzM5IGRhdGUgc3RyaW5ncy4KKy8vIFNlZSBbaHR0cHM6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzMzMzkudHh0XShodHRwczovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzMzOS50eHQpLgorLy8KKy8vIEV4YW1wbGUgMTogQ29tcHV0ZSBUaW1lc3RhbXAgZnJvbSBQT1NJWCBgdGltZSgpYC4KKy8vCisvLyAgICAgVGltZXN0YW1wIHRpbWVzdGFtcDsKKy8vICAgICB0aW1lc3RhbXAuc2V0X3NlY29uZHModGltZShOVUxMKSk7CisvLyAgICAgdGltZXN0YW1wLnNldF9uYW5vcygwKTsKKy8vCisvLyBFeGFtcGxlIDI6IENvbXB1dGUgVGltZXN0YW1wIGZyb20gUE9TSVggYGdldHRpbWVvZmRheSgpYC4KKy8vCisvLyAgICAgc3RydWN0IHRpbWV2YWwgdHY7CisvLyAgICAgZ2V0dGltZW9mZGF5KCZ0diwgTlVMTCk7CisvLworLy8gICAgIFRpbWVzdGFtcCB0aW1lc3RhbXA7CisvLyAgICAgdGltZXN0YW1wLnNldF9zZWNvbmRzKHR2LnR2X3NlYyk7CisvLyAgICAgdGltZXN0YW1wLnNldF9uYW5vcyh0di50dl91c2VjICogMTAwMCk7CisvLworLy8gRXhhbXBsZSAzOiBDb21wdXRlIFRpbWVzdGFtcCBmcm9tIFdpbjMyIGBHZXRTeXN0ZW1UaW1lQXNGaWxlVGltZSgpYC4KKy8vCisvLyAgICAgRklMRVRJTUUgZnQ7CisvLyAgICAgR2V0U3lzdGVtVGltZUFzRmlsZVRpbWUoJmZ0KTsKKy8vICAgICBVSU5UNjQgdGlja3MgPSAoKChVSU5UNjQpZnQuZHdIaWdoRGF0ZVRpbWUpIDw8IDMyKSB8IGZ0LmR3TG93RGF0ZVRpbWU7CisvLworLy8gICAgIC8vIEEgV2luZG93cyB0aWNrIGlzIDEwMCBuYW5vc2Vjb25kcy4gV2luZG93cyBlcG9jaCAxNjAxLTAxLTAxVDAwOjAwOjAwWgorLy8gICAgIC8vIGlzIDExNjQ0NDczNjAwIHNlY29uZHMgYmVmb3JlIFVuaXggZXBvY2ggMTk3MC0wMS0wMVQwMDowMDowMFouCisvLyAgICAgVGltZXN0YW1wIHRpbWVzdGFtcDsKKy8vICAgICB0aW1lc3RhbXAuc2V0X3NlY29uZHMoKElOVDY0KSAoKHRpY2tzIC8gMTAwMDAwMDApIC0gMTE2NDQ0NzM2MDBMTCkpOworLy8gICAgIHRpbWVzdGFtcC5zZXRfbmFub3MoKElOVDMyKSAoKHRpY2tzICUgMTAwMDAwMDApICogMTAwKSk7CisvLworLy8gRXhhbXBsZSA0OiBDb21wdXRlIFRpbWVzdGFtcCBmcm9tIEphdmEgYFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpYC4KKy8vCisvLyAgICAgbG9uZyBtaWxsaXMgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKy8vCisvLyAgICAgVGltZXN0YW1wIHRpbWVzdGFtcCA9IFRpbWVzdGFtcC5uZXdCdWlsZGVyKCkuc2V0U2Vjb25kcyhtaWxsaXMgLyAxMDAwKQorLy8gICAgICAgICAuc2V0TmFub3MoKGludCkgKChtaWxsaXMgJSAxMDAwKSAqIDEwMDAwMDApKS5idWlsZCgpOworLy8KKy8vCisvLyBFeGFtcGxlIDU6IENvbXB1dGUgVGltZXN0YW1wIGZyb20gY3VycmVudCB0aW1lIGluIFB5dGhvbi4KKy8vCisvLyAgICAgbm93ID0gdGltZS50aW1lKCkKKy8vICAgICBzZWNvbmRzID0gaW50KG5vdykKKy8vICAgICBuYW5vcyA9IGludCgobm93IC0gc2Vjb25kcykgKiAxMCoqOSkKKy8vICAgICB0aW1lc3RhbXAgPSBUaW1lc3RhbXAoc2Vjb25kcz1zZWNvbmRzLCBuYW5vcz1uYW5vcykKKy8vCisvLworbWVzc2FnZSBUaW1lc3RhbXAgeworCisgIC8vIFJlcHJlc2VudHMgc2Vjb25kcyBvZiBVVEMgdGltZSBzaW5jZSBVbml4IGVwb2NoCisgIC8vIDE5NzAtMDEtMDFUMDA6MDA6MDBaLiBNdXN0IGJlIGZyb20gZnJvbSAwMDAxLTAxLTAxVDAwOjAwOjAwWiB0bworICAvLyA5OTk5LTEyLTMxVDIzOjU5OjU5WiBpbmNsdXNpdmUuCisgIGludDY0IHNlY29uZHMgPSAxOworCisgIC8vIE5vbi1uZWdhdGl2ZSBmcmFjdGlvbnMgb2YgYSBzZWNvbmQgYXQgbmFub3NlY29uZCByZXNvbHV0aW9uLiBOZWdhdGl2ZQorICAvLyBzZWNvbmQgdmFsdWVzIHdpdGggZnJhY3Rpb25zIG11c3Qgc3RpbGwgaGF2ZSBub24tbmVnYXRpdmUgbmFub3MgdmFsdWVzCisgIC8vIHRoYXQgY291bnQgZm9yd2FyZCBpbiB0aW1lLiBNdXN0IGJlIGZyb20gMCB0byA5OTksOTk5LDk5OQorICAvLyBpbmNsdXNpdmUuCisgIGludDMyIG5hbm9zID0gMjsKK30KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdHlwZS5wYi5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdHlwZS5wYi5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43YjQ3YjNiCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90eXBlLnBiLmNjCkBAIC0wLDAgKzEsMzIzMSBAQAorLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCEKKy8vIHNvdXJjZTogZ29vZ2xlL3Byb3RvYnVmL3R5cGUucHJvdG8KKworI2RlZmluZSBJTlRFUk5BTF9TVVBQUkVTU19QUk9UT0JVRl9GSUVMRF9ERVBSRUNBVElPTgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90eXBlLnBiLmg+CisKKyNpbmNsdWRlIDxhbGdvcml0aG0+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3BvcnQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvb25jZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZV9pbmwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfbWVzc2FnZV9yZWZsZWN0aW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3JlZmxlY3Rpb25fb3BzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0Lmg+CisvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW5jbHVkZXMpCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworbmFtZXNwYWNlIHsKKworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBUeXBlX2Rlc2NyaXB0b3JfID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKgorICBUeXBlX3JlZmxlY3Rpb25fID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogRmllbGRfZGVzY3JpcHRvcl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24qCisgIEZpZWxkX3JlZmxlY3Rpb25fID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bURlc2NyaXB0b3IqIEZpZWxkX0tpbmRfZGVzY3JpcHRvcl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvciogRmllbGRfQ2FyZGluYWxpdHlfZGVzY3JpcHRvcl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBFbnVtX2Rlc2NyaXB0b3JfID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKgorICBFbnVtX3JlZmxlY3Rpb25fID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogRW51bVZhbHVlX2Rlc2NyaXB0b3JfID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKgorICBFbnVtVmFsdWVfcmVmbGVjdGlvbl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBPcHRpb25fZGVzY3JpcHRvcl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24qCisgIE9wdGlvbl9yZWZsZWN0aW9uXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yKiBTeW50YXhfZGVzY3JpcHRvcl8gPSBOVUxMOworCit9ICAvLyBuYW1lc3BhY2UKKworCit2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZ0eXBlXzJlcHJvdG8oKSB7CisgIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZ0eXBlXzJlcHJvdG8oKTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpGaWxlRGVzY3JpcHRvciogZmlsZSA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUG9vbDo6Z2VuZXJhdGVkX3Bvb2woKS0+RmluZEZpbGVCeU5hbWUoCisgICAgICAiZ29vZ2xlL3Byb3RvYnVmL3R5cGUucHJvdG8iKTsKKyAgR09PR0xFX0NIRUNLKGZpbGUgIT0gTlVMTCk7CisgIFR5cGVfZGVzY3JpcHRvcl8gPSBmaWxlLT5tZXNzYWdlX3R5cGUoMCk7CisgIHN0YXRpYyBjb25zdCBpbnQgVHlwZV9vZmZzZXRzX1s2XSA9IHsKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKFR5cGUsIG5hbWVfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKFR5cGUsIGZpZWxkc18pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoVHlwZSwgb25lb2ZzXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChUeXBlLCBvcHRpb25zXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChUeXBlLCBzb3VyY2VfY29udGV4dF8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoVHlwZSwgc3ludGF4XyksCisgIH07CisgIFR5cGVfcmVmbGVjdGlvbl8gPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpOZXdHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbigKKyAgICAgIFR5cGVfZGVzY3JpcHRvcl8sCisgICAgICBUeXBlOjpkZWZhdWx0X2luc3RhbmNlXywKKyAgICAgIFR5cGVfb2Zmc2V0c18sCisgICAgICAtMSwKKyAgICAgIC0xLAorICAgICAgLTEsCisgICAgICBzaXplb2YoVHlwZSksCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKFR5cGUsIF9pbnRlcm5hbF9tZXRhZGF0YV8pLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChUeXBlLCBfaXNfZGVmYXVsdF9pbnN0YW5jZV8pKTsKKyAgRmllbGRfZGVzY3JpcHRvcl8gPSBmaWxlLT5tZXNzYWdlX3R5cGUoMSk7CisgIHN0YXRpYyBjb25zdCBpbnQgRmllbGRfb2Zmc2V0c19bMTBdID0geworICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRmllbGQsIGtpbmRfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpZWxkLCBjYXJkaW5hbGl0eV8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRmllbGQsIG51bWJlcl8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRmllbGQsIG5hbWVfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpZWxkLCB0eXBlX3VybF8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRmllbGQsIG9uZW9mX2luZGV4XyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWVsZCwgcGFja2VkXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWVsZCwgb3B0aW9uc18pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRmllbGQsIGpzb25fbmFtZV8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRmllbGQsIGRlZmF1bHRfdmFsdWVfKSwKKyAgfTsKKyAgRmllbGRfcmVmbGVjdGlvbl8gPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpOZXdHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbigKKyAgICAgIEZpZWxkX2Rlc2NyaXB0b3JfLAorICAgICAgRmllbGQ6OmRlZmF1bHRfaW5zdGFuY2VfLAorICAgICAgRmllbGRfb2Zmc2V0c18sCisgICAgICAtMSwKKyAgICAgIC0xLAorICAgICAgLTEsCisgICAgICBzaXplb2YoRmllbGQpLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGaWVsZCwgX2ludGVybmFsX21ldGFkYXRhXyksCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZpZWxkLCBfaXNfZGVmYXVsdF9pbnN0YW5jZV8pKTsKKyAgRmllbGRfS2luZF9kZXNjcmlwdG9yXyA9IEZpZWxkX2Rlc2NyaXB0b3JfLT5lbnVtX3R5cGUoMCk7CisgIEZpZWxkX0NhcmRpbmFsaXR5X2Rlc2NyaXB0b3JfID0gRmllbGRfZGVzY3JpcHRvcl8tPmVudW1fdHlwZSgxKTsKKyAgRW51bV9kZXNjcmlwdG9yXyA9IGZpbGUtPm1lc3NhZ2VfdHlwZSgyKTsKKyAgc3RhdGljIGNvbnN0IGludCBFbnVtX29mZnNldHNfWzVdID0geworICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRW51bSwgbmFtZV8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRW51bSwgZW51bXZhbHVlXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChFbnVtLCBvcHRpb25zXyksCisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChFbnVtLCBzb3VyY2VfY29udGV4dF8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRW51bSwgc3ludGF4XyksCisgIH07CisgIEVudW1fcmVmbGVjdGlvbl8gPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpOZXdHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbigKKyAgICAgIEVudW1fZGVzY3JpcHRvcl8sCisgICAgICBFbnVtOjpkZWZhdWx0X2luc3RhbmNlXywKKyAgICAgIEVudW1fb2Zmc2V0c18sCisgICAgICAtMSwKKyAgICAgIC0xLAorICAgICAgLTEsCisgICAgICBzaXplb2YoRW51bSksCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEVudW0sIF9pbnRlcm5hbF9tZXRhZGF0YV8pLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChFbnVtLCBfaXNfZGVmYXVsdF9pbnN0YW5jZV8pKTsKKyAgRW51bVZhbHVlX2Rlc2NyaXB0b3JfID0gZmlsZS0+bWVzc2FnZV90eXBlKDMpOworICBzdGF0aWMgY29uc3QgaW50IEVudW1WYWx1ZV9vZmZzZXRzX1szXSA9IHsKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEVudW1WYWx1ZSwgbmFtZV8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRW51bVZhbHVlLCBudW1iZXJfKSwKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEVudW1WYWx1ZSwgb3B0aW9uc18pLAorICB9OworICBFbnVtVmFsdWVfcmVmbGVjdGlvbl8gPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpOZXdHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbigKKyAgICAgIEVudW1WYWx1ZV9kZXNjcmlwdG9yXywKKyAgICAgIEVudW1WYWx1ZTo6ZGVmYXVsdF9pbnN0YW5jZV8sCisgICAgICBFbnVtVmFsdWVfb2Zmc2V0c18sCisgICAgICAtMSwKKyAgICAgIC0xLAorICAgICAgLTEsCisgICAgICBzaXplb2YoRW51bVZhbHVlKSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRW51bVZhbHVlLCBfaW50ZXJuYWxfbWV0YWRhdGFfKSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRW51bVZhbHVlLCBfaXNfZGVmYXVsdF9pbnN0YW5jZV8pKTsKKyAgT3B0aW9uX2Rlc2NyaXB0b3JfID0gZmlsZS0+bWVzc2FnZV90eXBlKDQpOworICBzdGF0aWMgY29uc3QgaW50IE9wdGlvbl9vZmZzZXRzX1syXSA9IHsKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKE9wdGlvbiwgbmFtZV8pLAorICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoT3B0aW9uLCB2YWx1ZV8pLAorICB9OworICBPcHRpb25fcmVmbGVjdGlvbl8gPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpOZXdHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbigKKyAgICAgIE9wdGlvbl9kZXNjcmlwdG9yXywKKyAgICAgIE9wdGlvbjo6ZGVmYXVsdF9pbnN0YW5jZV8sCisgICAgICBPcHRpb25fb2Zmc2V0c18sCisgICAgICAtMSwKKyAgICAgIC0xLAorICAgICAgLTEsCisgICAgICBzaXplb2YoT3B0aW9uKSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoT3B0aW9uLCBfaW50ZXJuYWxfbWV0YWRhdGFfKSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoT3B0aW9uLCBfaXNfZGVmYXVsdF9pbnN0YW5jZV8pKTsKKyAgU3ludGF4X2Rlc2NyaXB0b3JfID0gZmlsZS0+ZW51bV90eXBlKDApOworfQorCituYW1lc3BhY2UgeworCitHT09HTEVfUFJPVE9CVUZfREVDTEFSRV9PTkNFKHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzX29uY2VfKTsKK2lubGluZSB2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpIHsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpHb29nbGVPbmNlSW5pdCgmcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNfb25jZV8sCisgICAgICAgICAgICAgICAgICZwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmdHlwZV8yZXByb3RvKTsKK30KKwordm9pZCBwcm90b2J1Zl9SZWdpc3RlclR5cGVzKGNvbnN0IDo6c3RkOjpzdHJpbmcmKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VGYWN0b3J5OjpJbnRlcm5hbFJlZ2lzdGVyR2VuZXJhdGVkTWVzc2FnZSgKKyAgICAgIFR5cGVfZGVzY3JpcHRvcl8sICZUeXBlOjpkZWZhdWx0X2luc3RhbmNlKCkpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VGYWN0b3J5OjpJbnRlcm5hbFJlZ2lzdGVyR2VuZXJhdGVkTWVzc2FnZSgKKyAgICAgIEZpZWxkX2Rlc2NyaXB0b3JfLCAmRmllbGQ6OmRlZmF1bHRfaW5zdGFuY2UoKSk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZUZhY3Rvcnk6OkludGVybmFsUmVnaXN0ZXJHZW5lcmF0ZWRNZXNzYWdlKAorICAgICAgRW51bV9kZXNjcmlwdG9yXywgJkVudW06OmRlZmF1bHRfaW5zdGFuY2UoKSk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZUZhY3Rvcnk6OkludGVybmFsUmVnaXN0ZXJHZW5lcmF0ZWRNZXNzYWdlKAorICAgICAgRW51bVZhbHVlX2Rlc2NyaXB0b3JfLCAmRW51bVZhbHVlOjpkZWZhdWx0X2luc3RhbmNlKCkpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VGYWN0b3J5OjpJbnRlcm5hbFJlZ2lzdGVyR2VuZXJhdGVkTWVzc2FnZSgKKyAgICAgIE9wdGlvbl9kZXNjcmlwdG9yXywgJk9wdGlvbjo6ZGVmYXVsdF9pbnN0YW5jZSgpKTsKK30KKworfSAgLy8gbmFtZXNwYWNlCisKK3ZvaWQgcHJvdG9idWZfU2h1dGRvd25GaWxlX2dvb2dsZV8yZnByb3RvYnVmXzJmdHlwZV8yZXByb3RvKCkgeworICBkZWxldGUgVHlwZTo6ZGVmYXVsdF9pbnN0YW5jZV87CisgIGRlbGV0ZSBUeXBlX3JlZmxlY3Rpb25fOworICBkZWxldGUgRmllbGQ6OmRlZmF1bHRfaW5zdGFuY2VfOworICBkZWxldGUgRmllbGRfcmVmbGVjdGlvbl87CisgIGRlbGV0ZSBFbnVtOjpkZWZhdWx0X2luc3RhbmNlXzsKKyAgZGVsZXRlIEVudW1fcmVmbGVjdGlvbl87CisgIGRlbGV0ZSBFbnVtVmFsdWU6OmRlZmF1bHRfaW5zdGFuY2VfOworICBkZWxldGUgRW51bVZhbHVlX3JlZmxlY3Rpb25fOworICBkZWxldGUgT3B0aW9uOjpkZWZhdWx0X2luc3RhbmNlXzsKKyAgZGVsZXRlIE9wdGlvbl9yZWZsZWN0aW9uXzsKK30KKwordm9pZCBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmdHlwZV8yZXByb3RvKCkgeworICBzdGF0aWMgYm9vbCBhbHJlYWR5X2hlcmUgPSBmYWxzZTsKKyAgaWYgKGFscmVhZHlfaGVyZSkgcmV0dXJuOworICBhbHJlYWR5X2hlcmUgPSB0cnVlOworICBHT09HTEVfUFJPVE9CVUZfVkVSSUZZX1ZFUlNJT047CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmYW55XzJlcHJvdG8oKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmc291cmNlXzVmY29udGV4dF8yZXByb3RvKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvclBvb2w6OkludGVybmFsQWRkR2VuZXJhdGVkRmlsZSgKKyAgICAiXG5cMDMyZ29vZ2xlL3Byb3RvYnVmL3R5cGUucHJvdG9cMDIyXDAxN2dvb2dsZS5wcm8iCisgICAgInRvYnVmXDAzMlwwMzFnb29nbGUvcHJvdG9idWYvYW55LnByb3RvXDAzMiRnb29nbGUiCisgICAgIi9wcm90b2J1Zi9zb3VyY2VfY29udGV4dC5wcm90b1wiXDMyN1wwMDFcblwwMDRUeXBlXDAyMiIKKyAgICAiXDAxNFxuXDAwNG5hbWVcMDMwXDAwMSBcMDAxKFx0XDAyMiZcblwwMDZmaWVsZHNcMDMwXDAwMiBcMDAzKFwwMTMyXDAyNi5nb29nbGUucCIKKyAgICAicm90b2J1Zi5GaWVsZFwwMjJcMDE2XG5cMDA2b25lb2ZzXDAzMFwwMDMgXDAwMyhcdFwwMjIoXG5cMDA3b3B0aW9ucyIKKyAgICAiXDAzMFwwMDQgXDAwMyhcMDEzMlwwMjcuZ29vZ2xlLnByb3RvYnVmLk9wdGlvblwwMjI2XG5cMDE2c291cmMiCisgICAgImVfY29udGV4dFwwMzBcMDA1IFwwMDEoXDAxMzJcMDM2Lmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2UiCisgICAgIkNvbnRleHRcMDIyXCdcblwwMDZzeW50YXhcMDMwXDAwNiBcMDAxKFwwMTYyXDAyNy5nb29nbGUucHJvdG9idSIKKyAgICAiZi5TeW50YXhcIlwzMjVcMDA1XG5cMDA1RmllbGRcMDIyKVxuXDAwNGtpbmRcMDMwXDAwMSBcMDAxKFwwMTYyXDAzMy5nb29nbCIKKyAgICAiZS5wcm90b2J1Zi5GaWVsZC5LaW5kXDAyMjdcblwwMTNjYXJkaW5hbGl0eVwwMzBcMDAyIFwwMDEiCisgICAgIihcMDE2MlwiLmdvb2dsZS5wcm90b2J1Zi5GaWVsZC5DYXJkaW5hbGl0eVwwMjJcMDE2IgorICAgICJcblwwMDZudW1iZXJcMDMwXDAwMyBcMDAxKFwwMDVcMDIyXDAxNFxuXDAwNG5hbWVcMDMwXDAwNCBcMDAxKFx0XDAyMlwwMjBcblwwMTB0eXBlX3VybCIKKyAgICAiXDAzMFwwMDYgXDAwMShcdFwwMjJcMDIzXG5cMDEzb25lb2ZfaW5kZXhcMDMwXDAwNyBcMDAxKFwwMDVcMDIyXDAxNlxuXDAwNnBhY2tlZFwwMzBcMDEwICIKKyAgICAiXDAwMShcMDEwXDAyMihcblwwMDdvcHRpb25zXDAzMFx0IFwwMDMoXDAxMzJcMDI3Lmdvb2dsZS5wcm90b2J1Zi5PIgorICAgICJwdGlvblwwMjJcMDIxXG5cdGpzb25fbmFtZVwwMzBcbiBcMDAxKFx0XDAyMlwwMjVcblxyZGVmYXVsdF92YWx1IgorICAgICJlXDAzMFwwMTMgXDAwMShcdFwiXDMxMFwwMDJcblwwMDRLaW5kXDAyMlwwMjBcblwwMTRUWVBFX1VOS05PV05cMDIwXDAwMFwwMjJcMDE3XG5cMDEzVFkiCisgICAgIlBFX0RPVUJMRVwwMjBcMDAxXDAyMlwwMTZcblxuVFlQRV9GTE9BVFwwMjBcMDAyXDAyMlwwMTZcblxuVFlQRV9JTlQ2IgorICAgICI0XDAyMFwwMDNcMDIyXDAxN1xuXDAxM1RZUEVfVUlOVDY0XDAyMFwwMDRcMDIyXDAxNlxuXG5UWVBFX0lOVDMyXDAyMFwwMDVcMDIyXDAyMFxuXDAxNCIKKyAgICAiVFlQRV9GSVhFRDY0XDAyMFwwMDZcMDIyXDAyMFxuXDAxNFRZUEVfRklYRUQzMlwwMjBcMDA3XDAyMlxyXG5cdFRZUEUiCisgICAgIl9CT09MXDAyMFwwMTBcMDIyXDAxN1xuXDAxM1RZUEVfU1RSSU5HXDAyMFx0XDAyMlwwMTZcblxuVFlQRV9HUk9VUFwwMjBcbiIKKyAgICAiXDAyMlwwMjBcblwwMTRUWVBFX01FU1NBR0VcMDIwXDAxM1wwMjJcMDE2XG5cblRZUEVfQllURVNcMDIwXDAxNFwwMjJcMDE3XG5cMDEzVFkiCisgICAgIlBFX1VJTlQzMlwwMjBcclwwMjJcclxuXHRUWVBFX0VOVU1cMDIwXDAxNlwwMjJcMDIxXG5cclRZUEVfU0ZJWEUiCisgICAgIkQzMlwwMjBcMDE3XDAyMlwwMjFcblxyVFlQRV9TRklYRUQ2NFwwMjBcMDIwXDAyMlwwMTdcblwwMTNUWVBFX1NJTlQzMlwwMjAiCisgICAgIlwwMjFcMDIyXDAxN1xuXDAxM1RZUEVfU0lOVDY0XDAyMFwwMjJcInRcblwwMTNDYXJkaW5hbGl0eVwwMjJcMDI3XG5cMDIzQ0FSIgorICAgICJESU5BTElUWV9VTktOT1dOXDAyMFwwMDBcMDIyXDAzMFxuXDAyNENBUkRJTkFMSVRZX09QVElPTiIKKyAgICAiQUxcMDIwXDAwMVwwMjJcMDMwXG5cMDI0Q0FSRElOQUxJVFlfUkVRVUlSRURcMDIwXDAwMlwwMjJcMDMwXG5cMDI0Q0FSRElOIgorICAgICJBTElUWV9SRVBFQVRFRFwwMjBcMDAzXCJcMzE2XDAwMVxuXDAwNEVudW1cMDIyXDAxNFxuXDAwNG5hbWVcMDMwXDAwMSBcMDAxKFx0XDAyMiIKKyAgICAiLVxuXHRlbnVtdmFsdWVcMDMwXDAwMiBcMDAzKFwwMTMyXDAzMi5nb29nbGUucHJvdG9idWYuRW51IgorICAgICJtVmFsdWVcMDIyKFxuXDAwN29wdGlvbnNcMDMwXDAwMyBcMDAzKFwwMTMyXDAyNy5nb29nbGUucHJvdG9idSIKKyAgICAiZi5PcHRpb25cMDIyNlxuXDAxNnNvdXJjZV9jb250ZXh0XDAzMFwwMDQgXDAwMShcMDEzMlwwMzYuZ29vZ2wiCisgICAgImUucHJvdG9idWYuU291cmNlQ29udGV4dFwwMjJcJ1xuXDAwNnN5bnRheFwwMzBcMDA1IFwwMDEoXDAxNiIKKyAgICAiMlwwMjcuZ29vZ2xlLnByb3RvYnVmLlN5bnRheFwiU1xuXHRFbnVtVmFsdWVcMDIyXDAxNCIKKyAgICAiXG5cMDA0bmFtZVwwMzBcMDAxIFwwMDEoXHRcMDIyXDAxNlxuXDAwNm51bWJlclwwMzBcMDAyIFwwMDEoXDAwNVwwMjIoXG5cMDA3b3B0aW9uc1wwMzAiCisgICAgIlwwMDMgXDAwMyhcMDEzMlwwMjcuZ29vZ2xlLnByb3RvYnVmLk9wdGlvblwiO1xuXDAwNk9wdGlvbiIKKyAgICAiXDAyMlwwMTRcblwwMDRuYW1lXDAzMFwwMDEgXDAwMShcdFwwMjIjXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTMyXDAyNC5nb29nbGUucCIKKyAgICAicm90b2J1Zi5BbnkqLlxuXDAwNlN5bnRheFwwMjJcMDIxXG5cclNZTlRBWF9QUk9UTzJcMDIwXDAwMCIKKyAgICAiXDAyMlwwMjFcblxyU1lOVEFYX1BST1RPM1wwMjBcMDAxQkxcblwwMjNjb20uZ29vZ2xlLnByb3RvYiIKKyAgICAidWZCXHRUeXBlUHJvdG9QXDAwMVwyNDBcMDAxXDAwMVwyNDJcMDAyXDAwM0dQQlwyNTJcMDAyXDAzNkdvb2dsZS5Qcm90b2IiCisgICAgInVmLldlbGxLbm93blR5cGVzYlwwMDZwcm90bzMiLCAxNTQ1KTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZEZpbGUoCisgICAgImdvb2dsZS9wcm90b2J1Zi90eXBlLnByb3RvIiwgJnByb3RvYnVmX1JlZ2lzdGVyVHlwZXMpOworICBUeXBlOjpkZWZhdWx0X2luc3RhbmNlXyA9IG5ldyBUeXBlKCk7CisgIEZpZWxkOjpkZWZhdWx0X2luc3RhbmNlXyA9IG5ldyBGaWVsZCgpOworICBFbnVtOjpkZWZhdWx0X2luc3RhbmNlXyA9IG5ldyBFbnVtKCk7CisgIEVudW1WYWx1ZTo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBuZXcgRW51bVZhbHVlKCk7CisgIE9wdGlvbjo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBuZXcgT3B0aW9uKCk7CisgIFR5cGU6OmRlZmF1bHRfaW5zdGFuY2VfLT5Jbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgRmllbGQ6OmRlZmF1bHRfaW5zdGFuY2VfLT5Jbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgRW51bTo6ZGVmYXVsdF9pbnN0YW5jZV8tPkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICBFbnVtVmFsdWU6OmRlZmF1bHRfaW5zdGFuY2VfLT5Jbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgT3B0aW9uOjpkZWZhdWx0X2luc3RhbmNlXy0+SW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6Ok9uU2h1dGRvd24oJnByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZnR5cGVfMmVwcm90byk7Cit9CisKKy8vIEZvcmNlIEFkZERlc2NyaXB0b3JzKCkgdG8gYmUgY2FsbGVkIGF0IHN0YXRpYyBpbml0aWFsaXphdGlvbiB0aW1lLgorc3RydWN0IFN0YXRpY0Rlc2NyaXB0b3JJbml0aWFsaXplcl9nb29nbGVfMmZwcm90b2J1Zl8yZnR5cGVfMmVwcm90byB7CisgIFN0YXRpY0Rlc2NyaXB0b3JJbml0aWFsaXplcl9nb29nbGVfMmZwcm90b2J1Zl8yZnR5cGVfMmVwcm90bygpIHsKKyAgICBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmdHlwZV8yZXByb3RvKCk7CisgIH0KK30gc3RhdGljX2Rlc2NyaXB0b3JfaW5pdGlhbGl6ZXJfZ29vZ2xlXzJmcHJvdG9idWZfMmZ0eXBlXzJlcHJvdG9fOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvciogU3ludGF4X2Rlc2NyaXB0b3IoKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICByZXR1cm4gU3ludGF4X2Rlc2NyaXB0b3JfOworfQorYm9vbCBTeW50YXhfSXNWYWxpZChpbnQgdmFsdWUpIHsKKyAgc3dpdGNoKHZhbHVlKSB7CisgICAgY2FzZSAwOgorICAgIGNhc2UgMToKKyAgICAgIHJldHVybiB0cnVlOworICAgIGRlZmF1bHQ6CisgICAgICByZXR1cm4gZmFsc2U7CisgIH0KK30KKworCituYW1lc3BhY2UgeworCitzdGF0aWMgdm9pZCBNZXJnZUZyb21GYWlsKGludCBsaW5lKSBHT09HTEVfQVRUUklCVVRFX0NPTEQ7CitzdGF0aWMgdm9pZCBNZXJnZUZyb21GYWlsKGludCBsaW5lKSB7CisgIEdPT0dMRV9DSEVDSyhmYWxzZSkgPDwgX19GSUxFX18gPDwgIjoiIDw8IGxpbmU7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworI2lmICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCitjb25zdCBpbnQgVHlwZTo6a05hbWVGaWVsZE51bWJlcjsKK2NvbnN0IGludCBUeXBlOjprRmllbGRzRmllbGROdW1iZXI7Citjb25zdCBpbnQgVHlwZTo6a09uZW9mc0ZpZWxkTnVtYmVyOworY29uc3QgaW50IFR5cGU6OmtPcHRpb25zRmllbGROdW1iZXI7Citjb25zdCBpbnQgVHlwZTo6a1NvdXJjZUNvbnRleHRGaWVsZE51bWJlcjsKK2NvbnN0IGludCBUeXBlOjprU3ludGF4RmllbGROdW1iZXI7CisjZW5kaWYgIC8vICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCisKK1R5cGU6OlR5cGUoKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpLCBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLlR5cGUpCit9CisKK3ZvaWQgVHlwZTo6SW5pdEFzRGVmYXVsdEluc3RhbmNlKCkgeworICBfaXNfZGVmYXVsdF9pbnN0YW5jZV8gPSB0cnVlOworICBzb3VyY2VfY29udGV4dF8gPSBjb25zdF9jYXN0PCA6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvbnRleHQqPigmOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb250ZXh0OjpkZWZhdWx0X2luc3RhbmNlKCkpOworfQorCitUeXBlOjpUeXBlKGNvbnN0IFR5cGUmIGZyb20pCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksCisgICAgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29weV9jb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuVHlwZSkKK30KKwordm9pZCBUeXBlOjpTaGFyZWRDdG9yKCkgeworICAgIF9pc19kZWZhdWx0X2luc3RhbmNlXyA9IGZhbHNlOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZygpOworICBfY2FjaGVkX3NpemVfID0gMDsKKyAgbmFtZV8uVW5zYWZlU2V0RGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBzb3VyY2VfY29udGV4dF8gPSBOVUxMOworICBzeW50YXhfID0gMDsKK30KKworVHlwZTo6flR5cGUoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChkZXN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5UeXBlKQorICBTaGFyZWREdG9yKCk7Cit9CisKK3ZvaWQgVHlwZTo6U2hhcmVkRHRvcigpIHsKKyAgbmFtZV8uRGVzdHJveU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgaWYgKHRoaXMgIT0gZGVmYXVsdF9pbnN0YW5jZV8pIHsKKyAgICBkZWxldGUgc291cmNlX2NvbnRleHRfOworICB9Cit9CisKK3ZvaWQgVHlwZTo6U2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3QgeworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIFR5cGU6OmRlc2NyaXB0b3IoKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICByZXR1cm4gVHlwZV9kZXNjcmlwdG9yXzsKK30KKworY29uc3QgVHlwZSYgVHlwZTo6ZGVmYXVsdF9pbnN0YW5jZSgpIHsKKyAgaWYgKGRlZmF1bHRfaW5zdGFuY2VfID09IE5VTEwpIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZ0eXBlXzJlcHJvdG8oKTsKKyAgcmV0dXJuICpkZWZhdWx0X2luc3RhbmNlXzsKK30KKworVHlwZSogVHlwZTo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBOVUxMOworCitUeXBlKiBUeXBlOjpOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0IHsKKyAgVHlwZSogbiA9IG5ldyBUeXBlOworICBpZiAoYXJlbmEgIT0gTlVMTCkgeworICAgIGFyZW5hLT5Pd24obik7CisgIH0KKyAgcmV0dXJuIG47Cit9CisKK3ZvaWQgVHlwZTo6Q2xlYXIoKSB7CisgIG5hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgaWYgKEdldEFyZW5hTm9WaXJ0dWFsKCkgPT0gTlVMTCAmJiBzb3VyY2VfY29udGV4dF8gIT0gTlVMTCkgZGVsZXRlIHNvdXJjZV9jb250ZXh0XzsKKyAgc291cmNlX2NvbnRleHRfID0gTlVMTDsKKyAgc3ludGF4XyA9IDA7CisgIGZpZWxkc18uQ2xlYXIoKTsKKyAgb25lb2ZzXy5DbGVhcigpOworICBvcHRpb25zXy5DbGVhcigpOworfQorCitib29sIFR5cGU6Ok1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCkgeworI2RlZmluZSBET18oRVhQUkVTU0lPTikgaWYgKCEoRVhQUkVTU0lPTikpIGdvdG8gZmFpbHVyZQorICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiB0YWc7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdGFydDpnb29nbGUucHJvdG9idWYuVHlwZSkKKyAgZm9yICg7OykgeworICAgIDo6c3RkOjpwYWlyPCA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiwgYm9vbD4gcCA9IGlucHV0LT5SZWFkVGFnV2l0aEN1dG9mZigxMjcpOworICAgIHRhZyA9IHAuZmlyc3Q7CisgICAgaWYgKCFwLnNlY29uZCkgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICBzd2l0Y2ggKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdGaWVsZE51bWJlcih0YWcpKSB7CisgICAgICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgICAgICBjYXNlIDE6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAxMCkgeworICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFN0cmluZygKKyAgICAgICAgICAgICAgICBpbnB1dCwgdGhpcy0+bXV0YWJsZV9uYW1lKCkpKTsKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlZlcmlmeVV0ZjhTdHJpbmcoCisgICAgICAgICAgICB0aGlzLT5uYW1lKCkuZGF0YSgpLCB0aGlzLT5uYW1lKCkubGVuZ3RoKCksCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UEFSU0UsCisgICAgICAgICAgICAiZ29vZ2xlLnByb3RvYnVmLlR5cGUubmFtZSIpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDE4KSkgZ290byBwYXJzZV9maWVsZHM7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkIGZpZWxkcyA9IDI7CisgICAgICBjYXNlIDI6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAxOCkgeworICAgICAgICAgcGFyc2VfZmllbGRzOgorICAgICAgICAgIERPXyhpbnB1dC0+SW5jcmVtZW50UmVjdXJzaW9uRGVwdGgoKSk7CisgICAgICAgICBwYXJzZV9sb29wX2ZpZWxkczoKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRNZXNzYWdlTm9WaXJ0dWFsTm9SZWN1cnNpb25EZXB0aCgKKyAgICAgICAgICAgICAgICBpbnB1dCwgYWRkX2ZpZWxkcygpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygxOCkpIGdvdG8gcGFyc2VfbG9vcF9maWVsZHM7CisgICAgICAgIGlucHV0LT5VbnNhZmVEZWNyZW1lbnRSZWN1cnNpb25EZXB0aCgpOworICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygyNikpIGdvdG8gcGFyc2Vfb25lb2ZzOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gcmVwZWF0ZWQgc3RyaW5nIG9uZW9mcyA9IDM7CisgICAgICBjYXNlIDM6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAyNikgeworICAgICAgICAgcGFyc2Vfb25lb2ZzOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFN0cmluZygKKyAgICAgICAgICAgICAgICBpbnB1dCwgdGhpcy0+YWRkX29uZW9mcygpKSk7CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpWZXJpZnlVdGY4U3RyaW5nKAorICAgICAgICAgICAgdGhpcy0+b25lb2ZzKHRoaXMtPm9uZW9mc19zaXplKCkgLSAxKS5kYXRhKCksCisgICAgICAgICAgICB0aGlzLT5vbmVvZnModGhpcy0+b25lb2ZzX3NpemUoKSAtIDEpLmxlbmd0aCgpLAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlBBUlNFLAorICAgICAgICAgICAgImdvb2dsZS5wcm90b2J1Zi5UeXBlLm9uZW9mcyIpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDI2KSkgZ290byBwYXJzZV9vbmVvZnM7CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDM0KSkgZ290byBwYXJzZV9vcHRpb25zOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5PcHRpb24gb3B0aW9ucyA9IDQ7CisgICAgICBjYXNlIDQ6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAzNCkgeworICAgICAgICAgcGFyc2Vfb3B0aW9uczoKKyAgICAgICAgICBET18oaW5wdXQtPkluY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCkpOworICAgICAgICAgcGFyc2VfbG9vcF9vcHRpb25zOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZE1lc3NhZ2VOb1ZpcnR1YWxOb1JlY3Vyc2lvbkRlcHRoKAorICAgICAgICAgICAgICAgIGlucHV0LCBhZGRfb3B0aW9ucygpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygzNCkpIGdvdG8gcGFyc2VfbG9vcF9vcHRpb25zOworICAgICAgICBpbnB1dC0+VW5zYWZlRGVjcmVtZW50UmVjdXJzaW9uRGVwdGgoKTsKKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNDIpKSBnb3RvIHBhcnNlX3NvdXJjZV9jb250ZXh0OworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0IHNvdXJjZV9jb250ZXh0ID0gNTsKKyAgICAgIGNhc2UgNTogeworICAgICAgICBpZiAodGFnID09IDQyKSB7CisgICAgICAgICBwYXJzZV9zb3VyY2VfY29udGV4dDoKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRNZXNzYWdlTm9WaXJ0dWFsKAorICAgICAgICAgICAgICAgaW5wdXQsIG11dGFibGVfc291cmNlX2NvbnRleHQoKSkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNDgpKSBnb3RvIHBhcnNlX3N5bnRheDsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuU3ludGF4IHN5bnRheCA9IDY7CisgICAgICBjYXNlIDY6IHsKKyAgICAgICAgaWYgKHRhZyA9PSA0OCkgeworICAgICAgICAgcGFyc2Vfc3ludGF4OgorICAgICAgICAgIGludCB2YWx1ZTsKKyAgICAgICAgICBET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPAorICAgICAgICAgICAgICAgICAgIGludCwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfRU5VTT4oCisgICAgICAgICAgICAgICAgIGlucHV0LCAmdmFsdWUpKSk7CisgICAgICAgICAgc2V0X3N5bnRheChzdGF0aWNfY2FzdDwgOjpnb29nbGU6OnByb3RvYnVmOjpTeW50YXggPih2YWx1ZSkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RBdEVuZCgpKSBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBkZWZhdWx0OiB7CisgICAgICBoYW5kbGVfdW51c3VhbDoKKyAgICAgICAgaWYgKHRhZyA9PSAwIHx8CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnV2lyZVR5cGUodGFnKSA9PQorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0VORF9HUk9VUCkgeworICAgICAgICAgIGdvdG8gc3VjY2VzczsKKyAgICAgICAgfQorICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlNraXBGaWVsZChpbnB1dCwgdGFnKSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgfQorc3VjY2VzczoKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N1Y2Nlc3M6Z29vZ2xlLnByb3RvYnVmLlR5cGUpCisgIHJldHVybiB0cnVlOworZmFpbHVyZToKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX2ZhaWx1cmU6Z29vZ2xlLnByb3RvYnVmLlR5cGUpCisgIHJldHVybiBmYWxzZTsKKyN1bmRlZiBET18KK30KKwordm9pZCBUeXBlOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5UeXBlKQorICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgIGlmICh0aGlzLT5uYW1lKCkuc2l6ZSgpID4gMCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpWZXJpZnlVdGY4U3RyaW5nKAorICAgICAgdGhpcy0+bmFtZSgpLmRhdGEoKSwgdGhpcy0+bmFtZSgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuVHlwZS5uYW1lIik7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nTWF5YmVBbGlhc2VkKAorICAgICAgMSwgdGhpcy0+bmFtZSgpLCBvdXRwdXQpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZCBmaWVsZHMgPSAyOworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPmZpZWxkc19zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgMiwgdGhpcy0+ZmllbGRzKGkpLCBvdXRwdXQpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgc3RyaW5nIG9uZW9mcyA9IDM7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+b25lb2ZzX3NpemUoKTsgaSsrKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlZlcmlmeVV0ZjhTdHJpbmcoCisgICAgICB0aGlzLT5vbmVvZnMoaSkuZGF0YSgpLCB0aGlzLT5vbmVvZnMoaSkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5UeXBlLm9uZW9mcyIpOworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZygKKyAgICAgIDMsIHRoaXMtPm9uZW9mcyhpKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuT3B0aW9uIG9wdGlvbnMgPSA0OworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPm9wdGlvbnNfc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlTWVzc2FnZU1heWJlVG9BcnJheSgKKyAgICAgIDQsIHRoaXMtPm9wdGlvbnMoaSksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQgc291cmNlX2NvbnRleHQgPSA1OworICBpZiAodGhpcy0+aGFzX3NvdXJjZV9jb250ZXh0KCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgNSwgKnRoaXMtPnNvdXJjZV9jb250ZXh0Xywgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuU3ludGF4IHN5bnRheCA9IDY7CisgIGlmICh0aGlzLT5zeW50YXgoKSAhPSAwKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlRW51bSgKKyAgICAgIDYsIHRoaXMtPnN5bnRheCgpLCBvdXRwdXQpOworICB9CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9lbmQ6Z29vZ2xlLnByb3RvYnVmLlR5cGUpCit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIFR5cGU6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogdGFyZ2V0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLlR5cGUpCisgIC8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKKyAgaWYgKHRoaXMtPm5hbWUoKS5zaXplKCkgPiAwKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlZlcmlmeVV0ZjhTdHJpbmcoCisgICAgICB0aGlzLT5uYW1lKCkuZGF0YSgpLCB0aGlzLT5uYW1lKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5UeXBlLm5hbWUiKTsKKyAgICB0YXJnZXQgPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nVG9BcnJheSgKKyAgICAgICAgMSwgdGhpcy0+bmFtZSgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZCBmaWVsZHMgPSAyOworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPmZpZWxkc19zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6CisgICAgICBXcml0ZU1lc3NhZ2VOb1ZpcnR1YWxUb0FycmF5KAorICAgICAgICAyLCB0aGlzLT5maWVsZHMoaSksIHRhcmdldCk7CisgIH0KKworICAvLyByZXBlYXRlZCBzdHJpbmcgb25lb2ZzID0gMzsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT5vbmVvZnNfc2l6ZSgpOyBpKyspIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VmVyaWZ5VXRmOFN0cmluZygKKyAgICAgIHRoaXMtPm9uZW9mcyhpKS5kYXRhKCksIHRoaXMtPm9uZW9mcyhpKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLlR5cGUub25lb2ZzIik7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OgorICAgICAgV3JpdGVTdHJpbmdUb0FycmF5KDMsIHRoaXMtPm9uZW9mcyhpKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuT3B0aW9uIG9wdGlvbnMgPSA0OworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPm9wdGlvbnNfc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OgorICAgICAgV3JpdGVNZXNzYWdlTm9WaXJ0dWFsVG9BcnJheSgKKyAgICAgICAgNCwgdGhpcy0+b3B0aW9ucyhpKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCBzb3VyY2VfY29udGV4dCA9IDU7CisgIGlmICh0aGlzLT5oYXNfc291cmNlX2NvbnRleHQoKSkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjoKKyAgICAgIFdyaXRlTWVzc2FnZU5vVmlydHVhbFRvQXJyYXkoCisgICAgICAgIDUsICp0aGlzLT5zb3VyY2VfY29udGV4dF8sIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLlN5bnRheCBzeW50YXggPSA2OworICBpZiAodGhpcy0+c3ludGF4KCkgIT0gMCkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUVudW1Ub0FycmF5KAorICAgICAgNiwgdGhpcy0+c3ludGF4KCksIHRhcmdldCk7CisgIH0KKworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X2VuZDpnb29nbGUucHJvdG9idWYuVHlwZSkKKyAgcmV0dXJuIHRhcmdldDsKK30KKworaW50IFR5cGU6OkJ5dGVTaXplKCkgY29uc3QgeworICBpbnQgdG90YWxfc2l6ZSA9IDA7CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICBpZiAodGhpcy0+bmFtZSgpLnNpemUoKSA+IDApIHsKKyAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlN0cmluZ1NpemUoCisgICAgICAgIHRoaXMtPm5hbWUoKSk7CisgIH0KKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQgc291cmNlX2NvbnRleHQgPSA1OworICBpZiAodGhpcy0+aGFzX3NvdXJjZV9jb250ZXh0KCkpIHsKKyAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1lc3NhZ2VTaXplTm9WaXJ0dWFsKAorICAgICAgICAqdGhpcy0+c291cmNlX2NvbnRleHRfKTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuU3ludGF4IHN5bnRheCA9IDY7CisgIGlmICh0aGlzLT5zeW50YXgoKSAhPSAwKSB7CisgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpFbnVtU2l6ZSh0aGlzLT5zeW50YXgoKSk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkIGZpZWxkcyA9IDI7CisgIHRvdGFsX3NpemUgKz0gMSAqIHRoaXMtPmZpZWxkc19zaXplKCk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+ZmllbGRzX3NpemUoKTsgaSsrKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1lc3NhZ2VTaXplTm9WaXJ0dWFsKAorICAgICAgICB0aGlzLT5maWVsZHMoaSkpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgc3RyaW5nIG9uZW9mcyA9IDM7CisgIHRvdGFsX3NpemUgKz0gMSAqIHRoaXMtPm9uZW9mc19zaXplKCk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+b25lb2ZzX3NpemUoKTsgaSsrKSB7CisgICAgdG90YWxfc2l6ZSArPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U3RyaW5nU2l6ZSgKKyAgICAgIHRoaXMtPm9uZW9mcyhpKSk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLk9wdGlvbiBvcHRpb25zID0gNDsKKyAgdG90YWxfc2l6ZSArPSAxICogdGhpcy0+b3B0aW9uc19zaXplKCk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+b3B0aW9uc19zaXplKCk7IGkrKykgeworICAgIHRvdGFsX3NpemUgKz0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpNZXNzYWdlU2l6ZU5vVmlydHVhbCgKKyAgICAgICAgdGhpcy0+b3B0aW9ucyhpKSk7CisgIH0KKworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gdG90YWxfc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7CisgIHJldHVybiB0b3RhbF9zaXplOworfQorCit2b2lkIFR5cGU6Ok1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgY29uc3QgVHlwZSogc291cmNlID0gCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpEeW5hbWljQ2FzdFRvR2VuZXJhdGVkPGNvbnN0IFR5cGU+KAorICAgICAgICAgICZmcm9tKTsKKyAgaWYgKHNvdXJjZSA9PSBOVUxMKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6UmVmbGVjdGlvbk9wczo6TWVyZ2UoZnJvbSwgdGhpcyk7CisgIH0gZWxzZSB7CisgICAgTWVyZ2VGcm9tKCpzb3VyY2UpOworICB9Cit9CisKK3ZvaWQgVHlwZTo6TWVyZ2VGcm9tKGNvbnN0IFR5cGUmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgZmllbGRzXy5NZXJnZUZyb20oZnJvbS5maWVsZHNfKTsKKyAgb25lb2ZzXy5NZXJnZUZyb20oZnJvbS5vbmVvZnNfKTsKKyAgb3B0aW9uc18uTWVyZ2VGcm9tKGZyb20ub3B0aW9uc18pOworICBpZiAoZnJvbS5uYW1lKCkuc2l6ZSgpID4gMCkgeworCisgICAgbmFtZV8uQXNzaWduV2l0aERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBmcm9tLm5hbWVfKTsKKyAgfQorICBpZiAoZnJvbS5oYXNfc291cmNlX2NvbnRleHQoKSkgeworICAgIG11dGFibGVfc291cmNlX2NvbnRleHQoKS0+Ojpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb250ZXh0OjpNZXJnZUZyb20oZnJvbS5zb3VyY2VfY29udGV4dCgpKTsKKyAgfQorICBpZiAoZnJvbS5zeW50YXgoKSAhPSAwKSB7CisgICAgc2V0X3N5bnRheChmcm9tLnN5bnRheCgpKTsKKyAgfQorfQorCit2b2lkIFR5cGU6OkNvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK3ZvaWQgVHlwZTo6Q29weUZyb20oY29uc3QgVHlwZSYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK2Jvb2wgVHlwZTo6SXNJbml0aWFsaXplZCgpIGNvbnN0IHsKKworICByZXR1cm4gdHJ1ZTsKK30KKwordm9pZCBUeXBlOjpTd2FwKFR5cGUqIG90aGVyKSB7CisgIGlmIChvdGhlciA9PSB0aGlzKSByZXR1cm47CisgIEludGVybmFsU3dhcChvdGhlcik7Cit9Cit2b2lkIFR5cGU6OkludGVybmFsU3dhcChUeXBlKiBvdGhlcikgeworICBuYW1lXy5Td2FwKCZvdGhlci0+bmFtZV8pOworICBmaWVsZHNfLlVuc2FmZUFyZW5hU3dhcCgmb3RoZXItPmZpZWxkc18pOworICBvbmVvZnNfLlVuc2FmZUFyZW5hU3dhcCgmb3RoZXItPm9uZW9mc18pOworICBvcHRpb25zXy5VbnNhZmVBcmVuYVN3YXAoJm90aGVyLT5vcHRpb25zXyk7CisgIHN0ZDo6c3dhcChzb3VyY2VfY29udGV4dF8sIG90aGVyLT5zb3VyY2VfY29udGV4dF8pOworICBzdGQ6OnN3YXAoc3ludGF4Xywgb3RoZXItPnN5bnRheF8pOworICBfaW50ZXJuYWxfbWV0YWRhdGFfLlN3YXAoJm90aGVyLT5faW50ZXJuYWxfbWV0YWRhdGFfKTsKKyAgc3RkOjpzd2FwKF9jYWNoZWRfc2l6ZV8sIG90aGVyLT5fY2FjaGVkX3NpemVfKTsKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBUeXBlOjpHZXRNZXRhZGF0YSgpIGNvbnN0IHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgbWV0YWRhdGE7CisgIG1ldGFkYXRhLmRlc2NyaXB0b3IgPSBUeXBlX2Rlc2NyaXB0b3JfOworICBtZXRhZGF0YS5yZWZsZWN0aW9uID0gVHlwZV9yZWZsZWN0aW9uXzsKKyAgcmV0dXJuIG1ldGFkYXRhOworfQorCisjaWYgUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisvLyBUeXBlCisKKy8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKK3ZvaWQgVHlwZTo6Y2xlYXJfbmFtZSgpIHsKKyAgbmFtZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIGNvbnN0IDo6c3RkOjpzdHJpbmcmIFR5cGU6Om5hbWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlR5cGUubmFtZSkKKyAgcmV0dXJuIG5hbWVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIFR5cGU6OnNldF9uYW1lKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIAorICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5UeXBlLm5hbWUpCit9Cisgdm9pZCBUeXBlOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICAKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5UeXBlLm5hbWUpCit9Cisgdm9pZCBUeXBlOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgCisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5UeXBlLm5hbWUpCit9CisgOjpzdGQ6OnN0cmluZyogVHlwZTo6bXV0YWJsZV9uYW1lKCkgeworICAKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLlR5cGUubmFtZSkKKyAgcmV0dXJuIG5hbWVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CisgOjpzdGQ6OnN0cmluZyogVHlwZTo6cmVsZWFzZV9uYW1lKCkgeworICAKKyAgcmV0dXJuIG5hbWVfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBUeXBlOjpzZXRfYWxsb2NhdGVkX25hbWUoOjpzdGQ6OnN0cmluZyogbmFtZSkgeworICBpZiAobmFtZSAhPSBOVUxMKSB7CisgICAgCisgIH0gZWxzZSB7CisgICAgCisgIH0KKyAgbmFtZV8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIG5hbWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuVHlwZS5uYW1lKQorfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkIGZpZWxkcyA9IDI7CitpbnQgVHlwZTo6ZmllbGRzX3NpemUoKSBjb25zdCB7CisgIHJldHVybiBmaWVsZHNfLnNpemUoKTsKK30KK3ZvaWQgVHlwZTo6Y2xlYXJfZmllbGRzKCkgeworICBmaWVsZHNfLkNsZWFyKCk7Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkJiBUeXBlOjpmaWVsZHMoaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlR5cGUuZmllbGRzKQorICByZXR1cm4gZmllbGRzXy5HZXQoaW5kZXgpOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZCogVHlwZTo6bXV0YWJsZV9maWVsZHMoaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5UeXBlLmZpZWxkcykKKyAgcmV0dXJuIGZpZWxkc18uTXV0YWJsZShpbmRleCk7Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkKiBUeXBlOjphZGRfZmllbGRzKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5UeXBlLmZpZWxkcykKKyAgcmV0dXJuIGZpZWxkc18uQWRkKCk7Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGQgPioKK1R5cGU6Om11dGFibGVfZmllbGRzKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5UeXBlLmZpZWxkcykKKyAgcmV0dXJuICZmaWVsZHNfOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkID4mCitUeXBlOjpmaWVsZHMoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5UeXBlLmZpZWxkcykKKyAgcmV0dXJuIGZpZWxkc187Cit9CisKKy8vIHJlcGVhdGVkIHN0cmluZyBvbmVvZnMgPSAzOworaW50IFR5cGU6Om9uZW9mc19zaXplKCkgY29uc3QgeworICByZXR1cm4gb25lb2ZzXy5zaXplKCk7Cit9Cit2b2lkIFR5cGU6OmNsZWFyX29uZW9mcygpIHsKKyAgb25lb2ZzXy5DbGVhcigpOworfQorIGNvbnN0IDo6c3RkOjpzdHJpbmcmIFR5cGU6Om9uZW9mcyhpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuVHlwZS5vbmVvZnMpCisgIHJldHVybiBvbmVvZnNfLkdldChpbmRleCk7Cit9CisgOjpzdGQ6OnN0cmluZyogVHlwZTo6bXV0YWJsZV9vbmVvZnMoaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5UeXBlLm9uZW9mcykKKyAgcmV0dXJuIG9uZW9mc18uTXV0YWJsZShpbmRleCk7Cit9Cisgdm9pZCBUeXBlOjpzZXRfb25lb2ZzKGludCBpbmRleCwgY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuVHlwZS5vbmVvZnMpCisgIG9uZW9mc18uTXV0YWJsZShpbmRleCktPmFzc2lnbih2YWx1ZSk7Cit9Cisgdm9pZCBUeXBlOjpzZXRfb25lb2ZzKGludCBpbmRleCwgY29uc3QgY2hhciogdmFsdWUpIHsKKyAgb25lb2ZzXy5NdXRhYmxlKGluZGV4KS0+YXNzaWduKHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5UeXBlLm9uZW9mcykKK30KKyB2b2lkIFR5cGU6OnNldF9vbmVvZnMoaW50IGluZGV4LCBjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgb25lb2ZzXy5NdXRhYmxlKGluZGV4KS0+YXNzaWduKAorICAgIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuVHlwZS5vbmVvZnMpCit9CisgOjpzdGQ6OnN0cmluZyogVHlwZTo6YWRkX29uZW9mcygpIHsKKyAgcmV0dXJuIG9uZW9mc18uQWRkKCk7Cit9Cisgdm9pZCBUeXBlOjphZGRfb25lb2ZzKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIG9uZW9mc18uQWRkKCktPmFzc2lnbih2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLlR5cGUub25lb2ZzKQorfQorIHZvaWQgVHlwZTo6YWRkX29uZW9mcyhjb25zdCBjaGFyKiB2YWx1ZSkgeworICBvbmVvZnNfLkFkZCgpLT5hc3NpZ24odmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkX2NoYXI6Z29vZ2xlLnByb3RvYnVmLlR5cGUub25lb2ZzKQorfQorIHZvaWQgVHlwZTo6YWRkX29uZW9mcyhjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgb25lb2ZzXy5BZGQoKS0+YXNzaWduKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuVHlwZS5vbmVvZnMpCit9CisgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6OnN0ZDo6c3RyaW5nPiYKK1R5cGU6Om9uZW9mcygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLlR5cGUub25lb2ZzKQorICByZXR1cm4gb25lb2ZzXzsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6c3RkOjpzdHJpbmc+KgorVHlwZTo6bXV0YWJsZV9vbmVvZnMoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLlR5cGUub25lb2ZzKQorICByZXR1cm4gJm9uZW9mc187Cit9CisKKy8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuT3B0aW9uIG9wdGlvbnMgPSA0OworaW50IFR5cGU6Om9wdGlvbnNfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIG9wdGlvbnNfLnNpemUoKTsKK30KK3ZvaWQgVHlwZTo6Y2xlYXJfb3B0aW9ucygpIHsKKyAgb3B0aW9uc18uQ2xlYXIoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6T3B0aW9uJiBUeXBlOjpvcHRpb25zKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5UeXBlLm9wdGlvbnMpCisgIHJldHVybiBvcHRpb25zXy5HZXQoaW5kZXgpOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpPcHRpb24qIFR5cGU6Om11dGFibGVfb3B0aW9ucyhpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLlR5cGUub3B0aW9ucykKKyAgcmV0dXJuIG9wdGlvbnNfLk11dGFibGUoaW5kZXgpOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpPcHRpb24qIFR5cGU6OmFkZF9vcHRpb25zKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5UeXBlLm9wdGlvbnMpCisgIHJldHVybiBvcHRpb25zXy5BZGQoKTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpPcHRpb24gPioKK1R5cGU6Om11dGFibGVfb3B0aW9ucygpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuVHlwZS5vcHRpb25zKQorICByZXR1cm4gJm9wdGlvbnNfOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbiA+JgorVHlwZTo6b3B0aW9ucygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLlR5cGUub3B0aW9ucykKKyAgcmV0dXJuIG9wdGlvbnNfOworfQorCisvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQgc291cmNlX2NvbnRleHQgPSA1OworYm9vbCBUeXBlOjpoYXNfc291cmNlX2NvbnRleHQoKSBjb25zdCB7CisgIHJldHVybiAhX2lzX2RlZmF1bHRfaW5zdGFuY2VfICYmIHNvdXJjZV9jb250ZXh0XyAhPSBOVUxMOworfQordm9pZCBUeXBlOjpjbGVhcl9zb3VyY2VfY29udGV4dCgpIHsKKyAgaWYgKEdldEFyZW5hTm9WaXJ0dWFsKCkgPT0gTlVMTCAmJiBzb3VyY2VfY29udGV4dF8gIT0gTlVMTCkgZGVsZXRlIHNvdXJjZV9jb250ZXh0XzsKKyAgc291cmNlX2NvbnRleHRfID0gTlVMTDsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29udGV4dCYgVHlwZTo6c291cmNlX2NvbnRleHQoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlR5cGUuc291cmNlX2NvbnRleHQpCisgIHJldHVybiBzb3VyY2VfY29udGV4dF8gIT0gTlVMTCA/ICpzb3VyY2VfY29udGV4dF8gOiAqZGVmYXVsdF9pbnN0YW5jZV8tPnNvdXJjZV9jb250ZXh0XzsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29udGV4dCogVHlwZTo6bXV0YWJsZV9zb3VyY2VfY29udGV4dCgpIHsKKyAgCisgIGlmIChzb3VyY2VfY29udGV4dF8gPT0gTlVMTCkgeworICAgIHNvdXJjZV9jb250ZXh0XyA9IG5ldyA6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvbnRleHQ7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLlR5cGUuc291cmNlX2NvbnRleHQpCisgIHJldHVybiBzb3VyY2VfY29udGV4dF87Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvbnRleHQqIFR5cGU6OnJlbGVhc2Vfc291cmNlX2NvbnRleHQoKSB7CisgIAorICA6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvbnRleHQqIHRlbXAgPSBzb3VyY2VfY29udGV4dF87CisgIHNvdXJjZV9jb250ZXh0XyA9IE5VTEw7CisgIHJldHVybiB0ZW1wOworfQordm9pZCBUeXBlOjpzZXRfYWxsb2NhdGVkX3NvdXJjZV9jb250ZXh0KDo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29udGV4dCogc291cmNlX2NvbnRleHQpIHsKKyAgZGVsZXRlIHNvdXJjZV9jb250ZXh0XzsKKyAgc291cmNlX2NvbnRleHRfID0gc291cmNlX2NvbnRleHQ7CisgIGlmIChzb3VyY2VfY29udGV4dCkgeworICAgIAorICB9IGVsc2UgeworICAgIAorICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5UeXBlLnNvdXJjZV9jb250ZXh0KQorfQorCisvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLlN5bnRheCBzeW50YXggPSA2Owordm9pZCBUeXBlOjpjbGVhcl9zeW50YXgoKSB7CisgIHN5bnRheF8gPSAwOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6U3ludGF4IFR5cGU6OnN5bnRheCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuVHlwZS5zeW50YXgpCisgIHJldHVybiBzdGF0aWNfY2FzdDwgOjpnb29nbGU6OnByb3RvYnVmOjpTeW50YXggPihzeW50YXhfKTsKK30KKyB2b2lkIFR5cGU6OnNldF9zeW50YXgoOjpnb29nbGU6OnByb3RvYnVmOjpTeW50YXggdmFsdWUpIHsKKyAgCisgIHN5bnRheF8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuVHlwZS5zeW50YXgpCit9CisKKyNlbmRpZiAgLy8gUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvciogRmllbGRfS2luZF9kZXNjcmlwdG9yKCkgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgcmV0dXJuIEZpZWxkX0tpbmRfZGVzY3JpcHRvcl87Cit9Citib29sIEZpZWxkX0tpbmRfSXNWYWxpZChpbnQgdmFsdWUpIHsKKyAgc3dpdGNoKHZhbHVlKSB7CisgICAgY2FzZSAwOgorICAgIGNhc2UgMToKKyAgICBjYXNlIDI6CisgICAgY2FzZSAzOgorICAgIGNhc2UgNDoKKyAgICBjYXNlIDU6CisgICAgY2FzZSA2OgorICAgIGNhc2UgNzoKKyAgICBjYXNlIDg6CisgICAgY2FzZSA5OgorICAgIGNhc2UgMTA6CisgICAgY2FzZSAxMToKKyAgICBjYXNlIDEyOgorICAgIGNhc2UgMTM6CisgICAgY2FzZSAxNDoKKyAgICBjYXNlIDE1OgorICAgIGNhc2UgMTY6CisgICAgY2FzZSAxNzoKKyAgICBjYXNlIDE4OgorICAgICAgcmV0dXJuIHRydWU7CisgICAgZGVmYXVsdDoKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgfQorfQorCisjaWYgIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKK2NvbnN0IEZpZWxkX0tpbmQgRmllbGQ6OlRZUEVfVU5LTk9XTjsKK2NvbnN0IEZpZWxkX0tpbmQgRmllbGQ6OlRZUEVfRE9VQkxFOworY29uc3QgRmllbGRfS2luZCBGaWVsZDo6VFlQRV9GTE9BVDsKK2NvbnN0IEZpZWxkX0tpbmQgRmllbGQ6OlRZUEVfSU5UNjQ7Citjb25zdCBGaWVsZF9LaW5kIEZpZWxkOjpUWVBFX1VJTlQ2NDsKK2NvbnN0IEZpZWxkX0tpbmQgRmllbGQ6OlRZUEVfSU5UMzI7Citjb25zdCBGaWVsZF9LaW5kIEZpZWxkOjpUWVBFX0ZJWEVENjQ7Citjb25zdCBGaWVsZF9LaW5kIEZpZWxkOjpUWVBFX0ZJWEVEMzI7Citjb25zdCBGaWVsZF9LaW5kIEZpZWxkOjpUWVBFX0JPT0w7Citjb25zdCBGaWVsZF9LaW5kIEZpZWxkOjpUWVBFX1NUUklORzsKK2NvbnN0IEZpZWxkX0tpbmQgRmllbGQ6OlRZUEVfR1JPVVA7Citjb25zdCBGaWVsZF9LaW5kIEZpZWxkOjpUWVBFX01FU1NBR0U7Citjb25zdCBGaWVsZF9LaW5kIEZpZWxkOjpUWVBFX0JZVEVTOworY29uc3QgRmllbGRfS2luZCBGaWVsZDo6VFlQRV9VSU5UMzI7Citjb25zdCBGaWVsZF9LaW5kIEZpZWxkOjpUWVBFX0VOVU07Citjb25zdCBGaWVsZF9LaW5kIEZpZWxkOjpUWVBFX1NGSVhFRDMyOworY29uc3QgRmllbGRfS2luZCBGaWVsZDo6VFlQRV9TRklYRUQ2NDsKK2NvbnN0IEZpZWxkX0tpbmQgRmllbGQ6OlRZUEVfU0lOVDMyOworY29uc3QgRmllbGRfS2luZCBGaWVsZDo6VFlQRV9TSU5UNjQ7Citjb25zdCBGaWVsZF9LaW5kIEZpZWxkOjpLaW5kX01JTjsKK2NvbnN0IEZpZWxkX0tpbmQgRmllbGQ6OktpbmRfTUFYOworY29uc3QgaW50IEZpZWxkOjpLaW5kX0FSUkFZU0laRTsKKyNlbmRpZiAgLy8gIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bURlc2NyaXB0b3IqIEZpZWxkX0NhcmRpbmFsaXR5X2Rlc2NyaXB0b3IoKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICByZXR1cm4gRmllbGRfQ2FyZGluYWxpdHlfZGVzY3JpcHRvcl87Cit9Citib29sIEZpZWxkX0NhcmRpbmFsaXR5X0lzVmFsaWQoaW50IHZhbHVlKSB7CisgIHN3aXRjaCh2YWx1ZSkgeworICAgIGNhc2UgMDoKKyAgICBjYXNlIDE6CisgICAgY2FzZSAyOgorICAgIGNhc2UgMzoKKyAgICAgIHJldHVybiB0cnVlOworICAgIGRlZmF1bHQ6CisgICAgICByZXR1cm4gZmFsc2U7CisgIH0KK30KKworI2lmICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCitjb25zdCBGaWVsZF9DYXJkaW5hbGl0eSBGaWVsZDo6Q0FSRElOQUxJVFlfVU5LTk9XTjsKK2NvbnN0IEZpZWxkX0NhcmRpbmFsaXR5IEZpZWxkOjpDQVJESU5BTElUWV9PUFRJT05BTDsKK2NvbnN0IEZpZWxkX0NhcmRpbmFsaXR5IEZpZWxkOjpDQVJESU5BTElUWV9SRVFVSVJFRDsKK2NvbnN0IEZpZWxkX0NhcmRpbmFsaXR5IEZpZWxkOjpDQVJESU5BTElUWV9SRVBFQVRFRDsKK2NvbnN0IEZpZWxkX0NhcmRpbmFsaXR5IEZpZWxkOjpDYXJkaW5hbGl0eV9NSU47Citjb25zdCBGaWVsZF9DYXJkaW5hbGl0eSBGaWVsZDo6Q2FyZGluYWxpdHlfTUFYOworY29uc3QgaW50IEZpZWxkOjpDYXJkaW5hbGl0eV9BUlJBWVNJWkU7CisjZW5kaWYgIC8vICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCisjaWYgIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKK2NvbnN0IGludCBGaWVsZDo6a0tpbmRGaWVsZE51bWJlcjsKK2NvbnN0IGludCBGaWVsZDo6a0NhcmRpbmFsaXR5RmllbGROdW1iZXI7Citjb25zdCBpbnQgRmllbGQ6OmtOdW1iZXJGaWVsZE51bWJlcjsKK2NvbnN0IGludCBGaWVsZDo6a05hbWVGaWVsZE51bWJlcjsKK2NvbnN0IGludCBGaWVsZDo6a1R5cGVVcmxGaWVsZE51bWJlcjsKK2NvbnN0IGludCBGaWVsZDo6a09uZW9mSW5kZXhGaWVsZE51bWJlcjsKK2NvbnN0IGludCBGaWVsZDo6a1BhY2tlZEZpZWxkTnVtYmVyOworY29uc3QgaW50IEZpZWxkOjprT3B0aW9uc0ZpZWxkTnVtYmVyOworY29uc3QgaW50IEZpZWxkOjprSnNvbk5hbWVGaWVsZE51bWJlcjsKK2NvbnN0IGludCBGaWVsZDo6a0RlZmF1bHRWYWx1ZUZpZWxkTnVtYmVyOworI2VuZGlmICAvLyAhZGVmaW5lZChfTVNDX1ZFUikgfHwgX01TQ19WRVIgPj0gMTkwMAorCitGaWVsZDo6RmllbGQoKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpLCBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLkZpZWxkKQorfQorCit2b2lkIEZpZWxkOjpJbml0QXNEZWZhdWx0SW5zdGFuY2UoKSB7CisgIF9pc19kZWZhdWx0X2luc3RhbmNlXyA9IHRydWU7Cit9CisKK0ZpZWxkOjpGaWVsZChjb25zdCBGaWVsZCYgZnJvbSkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwKKyAgICBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICBNZXJnZUZyb20oZnJvbSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb3B5X2NvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5GaWVsZCkKK30KKwordm9pZCBGaWVsZDo6U2hhcmVkQ3RvcigpIHsKKyAgICBfaXNfZGVmYXVsdF9pbnN0YW5jZV8gPSBmYWxzZTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmcoKTsKKyAgX2NhY2hlZF9zaXplXyA9IDA7CisgIGtpbmRfID0gMDsKKyAgY2FyZGluYWxpdHlfID0gMDsKKyAgbnVtYmVyXyA9IDA7CisgIG5hbWVfLlVuc2FmZVNldERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgdHlwZV91cmxfLlVuc2FmZVNldERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgb25lb2ZfaW5kZXhfID0gMDsKKyAgcGFja2VkXyA9IGZhbHNlOworICBqc29uX25hbWVfLlVuc2FmZVNldERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgZGVmYXVsdF92YWx1ZV8uVW5zYWZlU2V0RGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorCitGaWVsZDo6fkZpZWxkKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZGVzdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuRmllbGQpCisgIFNoYXJlZER0b3IoKTsKK30KKwordm9pZCBGaWVsZDo6U2hhcmVkRHRvcigpIHsKKyAgbmFtZV8uRGVzdHJveU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgdHlwZV91cmxfLkRlc3Ryb3lOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGpzb25fbmFtZV8uRGVzdHJveU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgZGVmYXVsdF92YWx1ZV8uRGVzdHJveU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgaWYgKHRoaXMgIT0gZGVmYXVsdF9pbnN0YW5jZV8pIHsKKyAgfQorfQorCit2b2lkIEZpZWxkOjpTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdCB7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSBzaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogRmllbGQ6OmRlc2NyaXB0b3IoKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICByZXR1cm4gRmllbGRfZGVzY3JpcHRvcl87Cit9CisKK2NvbnN0IEZpZWxkJiBGaWVsZDo6ZGVmYXVsdF9pbnN0YW5jZSgpIHsKKyAgaWYgKGRlZmF1bHRfaW5zdGFuY2VfID09IE5VTEwpIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZ0eXBlXzJlcHJvdG8oKTsKKyAgcmV0dXJuICpkZWZhdWx0X2luc3RhbmNlXzsKK30KKworRmllbGQqIEZpZWxkOjpkZWZhdWx0X2luc3RhbmNlXyA9IE5VTEw7CisKK0ZpZWxkKiBGaWVsZDo6TmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdCB7CisgIEZpZWxkKiBuID0gbmV3IEZpZWxkOworICBpZiAoYXJlbmEgIT0gTlVMTCkgeworICAgIGFyZW5hLT5Pd24obik7CisgIH0KKyAgcmV0dXJuIG47Cit9CisKK3ZvaWQgRmllbGQ6OkNsZWFyKCkgeworI2RlZmluZSBaUl9IRUxQRVJfKGYpIHJlaW50ZXJwcmV0X2Nhc3Q8Y2hhcio+KFwKKyAgJnJlaW50ZXJwcmV0X2Nhc3Q8RmllbGQqPigxNiktPmYpCisKKyNkZWZpbmUgWlJfKGZpcnN0LCBsYXN0KSBkbyB7XAorICA6Om1lbXNldCgmZmlyc3QsIDAsXAorICAgICAgICAgICBaUl9IRUxQRVJfKGxhc3QpIC0gWlJfSEVMUEVSXyhmaXJzdCkgKyBzaXplb2YobGFzdCkpO1wKK30gd2hpbGUgKDApCisKKyAgWlJfKGtpbmRfLCBjYXJkaW5hbGl0eV8pOworICBaUl8obnVtYmVyXywgb25lb2ZfaW5kZXhfKTsKKyAgbmFtZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICB0eXBlX3VybF8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBwYWNrZWRfID0gZmFsc2U7CisgIGpzb25fbmFtZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBkZWZhdWx0X3ZhbHVlXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisKKyN1bmRlZiBaUl9IRUxQRVJfCisjdW5kZWYgWlJfCisKKyAgb3B0aW9uc18uQ2xlYXIoKTsKK30KKworYm9vbCBGaWVsZDo6TWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KSB7CisjZGVmaW5lIERPXyhFWFBSRVNTSU9OKSBpZiAoIShFWFBSRVNTSU9OKSkgZ290byBmYWlsdXJlCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIHRhZzsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZCkKKyAgZm9yICg7OykgeworICAgIDo6c3RkOjpwYWlyPCA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiwgYm9vbD4gcCA9IGlucHV0LT5SZWFkVGFnV2l0aEN1dG9mZigxMjcpOworICAgIHRhZyA9IHAuZmlyc3Q7CisgICAgaWYgKCFwLnNlY29uZCkgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICBzd2l0Y2ggKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdGaWVsZE51bWJlcih0YWcpKSB7CisgICAgICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkLktpbmQga2luZCA9IDE7CisgICAgICBjYXNlIDE6IHsKKyAgICAgICAgaWYgKHRhZyA9PSA4KSB7CisgICAgICAgICAgaW50IHZhbHVlOworICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgaW50LCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9FTlVNPigKKyAgICAgICAgICAgICAgICAgaW5wdXQsICZ2YWx1ZSkpKTsKKyAgICAgICAgICBzZXRfa2luZChzdGF0aWNfY2FzdDwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZF9LaW5kID4odmFsdWUpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDE2KSkgZ290byBwYXJzZV9jYXJkaW5hbGl0eTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmllbGQuQ2FyZGluYWxpdHkgY2FyZGluYWxpdHkgPSAyOworICAgICAgY2FzZSAyOiB7CisgICAgICAgIGlmICh0YWcgPT0gMTYpIHsKKyAgICAgICAgIHBhcnNlX2NhcmRpbmFsaXR5OgorICAgICAgICAgIGludCB2YWx1ZTsKKyAgICAgICAgICBET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPAorICAgICAgICAgICAgICAgICAgIGludCwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfRU5VTT4oCisgICAgICAgICAgICAgICAgIGlucHV0LCAmdmFsdWUpKSk7CisgICAgICAgICAgc2V0X2NhcmRpbmFsaXR5KHN0YXRpY19jYXN0PCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0NhcmRpbmFsaXR5ID4odmFsdWUpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDI0KSkgZ290byBwYXJzZV9udW1iZXI7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCBpbnQzMiBudW1iZXIgPSAzOworICAgICAgY2FzZSAzOiB7CisgICAgICAgIGlmICh0YWcgPT0gMjQpIHsKKyAgICAgICAgIHBhcnNlX251bWJlcjoKKyAgICAgICAgICBET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPAorICAgICAgICAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0lOVDMyPigKKyAgICAgICAgICAgICAgICAgaW5wdXQsICZudW1iZXJfKSkpOworCisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygzNCkpIGdvdG8gcGFyc2VfbmFtZTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gNDsKKyAgICAgIGNhc2UgNDogeworICAgICAgICBpZiAodGFnID09IDM0KSB7CisgICAgICAgICBwYXJzZV9uYW1lOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFN0cmluZygKKyAgICAgICAgICAgICAgICBpbnB1dCwgdGhpcy0+bXV0YWJsZV9uYW1lKCkpKTsKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlZlcmlmeVV0ZjhTdHJpbmcoCisgICAgICAgICAgICB0aGlzLT5uYW1lKCkuZGF0YSgpLCB0aGlzLT5uYW1lKCkubGVuZ3RoKCksCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UEFSU0UsCisgICAgICAgICAgICAiZ29vZ2xlLnByb3RvYnVmLkZpZWxkLm5hbWUiKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg1MCkpIGdvdG8gcGFyc2VfdHlwZV91cmw7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCBzdHJpbmcgdHlwZV91cmwgPSA2OworICAgICAgY2FzZSA2OiB7CisgICAgICAgIGlmICh0YWcgPT0gNTApIHsKKyAgICAgICAgIHBhcnNlX3R5cGVfdXJsOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFN0cmluZygKKyAgICAgICAgICAgICAgICBpbnB1dCwgdGhpcy0+bXV0YWJsZV90eXBlX3VybCgpKSk7CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpWZXJpZnlVdGY4U3RyaW5nKAorICAgICAgICAgICAgdGhpcy0+dHlwZV91cmwoKS5kYXRhKCksIHRoaXMtPnR5cGVfdXJsKCkubGVuZ3RoKCksCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UEFSU0UsCisgICAgICAgICAgICAiZ29vZ2xlLnByb3RvYnVmLkZpZWxkLnR5cGVfdXJsIikpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNTYpKSBnb3RvIHBhcnNlX29uZW9mX2luZGV4OworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgaW50MzIgb25lb2ZfaW5kZXggPSA3OworICAgICAgY2FzZSA3OiB7CisgICAgICAgIGlmICh0YWcgPT0gNTYpIHsKKyAgICAgICAgIHBhcnNlX29uZW9mX2luZGV4OgorICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfSU5UMzI+KAorICAgICAgICAgICAgICAgICBpbnB1dCwgJm9uZW9mX2luZGV4XykpKTsKKworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNjQpKSBnb3RvIHBhcnNlX3BhY2tlZDsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIGJvb2wgcGFja2VkID0gODsKKyAgICAgIGNhc2UgODogeworICAgICAgICBpZiAodGFnID09IDY0KSB7CisgICAgICAgICBwYXJzZV9wYWNrZWQ6CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICBib29sLCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9CT09MPigKKyAgICAgICAgICAgICAgICAgaW5wdXQsICZwYWNrZWRfKSkpOworCisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg3NCkpIGdvdG8gcGFyc2Vfb3B0aW9uczsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuT3B0aW9uIG9wdGlvbnMgPSA5OworICAgICAgY2FzZSA5OiB7CisgICAgICAgIGlmICh0YWcgPT0gNzQpIHsKKyAgICAgICAgIHBhcnNlX29wdGlvbnM6CisgICAgICAgICAgRE9fKGlucHV0LT5JbmNyZW1lbnRSZWN1cnNpb25EZXB0aCgpKTsKKyAgICAgICAgIHBhcnNlX2xvb3Bfb3B0aW9uczoKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRNZXNzYWdlTm9WaXJ0dWFsTm9SZWN1cnNpb25EZXB0aCgKKyAgICAgICAgICAgICAgICBpbnB1dCwgYWRkX29wdGlvbnMoKSkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoNzQpKSBnb3RvIHBhcnNlX2xvb3Bfb3B0aW9uczsKKyAgICAgICAgaW5wdXQtPlVuc2FmZURlY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCk7CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDgyKSkgZ290byBwYXJzZV9qc29uX25hbWU7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCBzdHJpbmcganNvbl9uYW1lID0gMTA7CisgICAgICBjYXNlIDEwOiB7CisgICAgICAgIGlmICh0YWcgPT0gODIpIHsKKyAgICAgICAgIHBhcnNlX2pzb25fbmFtZToKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoCisgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPm11dGFibGVfanNvbl9uYW1lKCkpKTsKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlZlcmlmeVV0ZjhTdHJpbmcoCisgICAgICAgICAgICB0aGlzLT5qc29uX25hbWUoKS5kYXRhKCksIHRoaXMtPmpzb25fbmFtZSgpLmxlbmd0aCgpLAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlBBUlNFLAorICAgICAgICAgICAgImdvb2dsZS5wcm90b2J1Zi5GaWVsZC5qc29uX25hbWUiKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg5MCkpIGdvdG8gcGFyc2VfZGVmYXVsdF92YWx1ZTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIG9wdGlvbmFsIHN0cmluZyBkZWZhdWx0X3ZhbHVlID0gMTE7CisgICAgICBjYXNlIDExOiB7CisgICAgICAgIGlmICh0YWcgPT0gOTApIHsKKyAgICAgICAgIHBhcnNlX2RlZmF1bHRfdmFsdWU6CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkU3RyaW5nKAorICAgICAgICAgICAgICAgIGlucHV0LCB0aGlzLT5tdXRhYmxlX2RlZmF1bHRfdmFsdWUoKSkpOworICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VmVyaWZ5VXRmOFN0cmluZygKKyAgICAgICAgICAgIHRoaXMtPmRlZmF1bHRfdmFsdWUoKS5kYXRhKCksIHRoaXMtPmRlZmF1bHRfdmFsdWUoKS5sZW5ndGgoKSwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpQQVJTRSwKKyAgICAgICAgICAgICJnb29nbGUucHJvdG9idWYuRmllbGQuZGVmYXVsdF92YWx1ZSIpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0QXRFbmQoKSkgZ290byBzdWNjZXNzOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgZGVmYXVsdDogeworICAgICAgaGFuZGxlX3VudXN1YWw6CisgICAgICAgIGlmICh0YWcgPT0gMCB8fAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ1dpcmVUeXBlKHRhZykgPT0KKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVApIHsKKyAgICAgICAgICBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIH0KKyAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTa2lwRmllbGQoaW5wdXQsIHRhZykpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KK3N1Y2Nlc3M6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdWNjZXNzOmdvb2dsZS5wcm90b2J1Zi5GaWVsZCkKKyAgcmV0dXJuIHRydWU7CitmYWlsdXJlOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2VfZmFpbHVyZTpnb29nbGUucHJvdG9idWYuRmllbGQpCisgIHJldHVybiBmYWxzZTsKKyN1bmRlZiBET18KK30KKwordm9pZCBGaWVsZDo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9zdGFydDpnb29nbGUucHJvdG9idWYuRmllbGQpCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmllbGQuS2luZCBraW5kID0gMTsKKyAgaWYgKHRoaXMtPmtpbmQoKSAhPSAwKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlRW51bSgKKyAgICAgIDEsIHRoaXMtPmtpbmQoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmllbGQuQ2FyZGluYWxpdHkgY2FyZGluYWxpdHkgPSAyOworICBpZiAodGhpcy0+Y2FyZGluYWxpdHkoKSAhPSAwKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlRW51bSgKKyAgICAgIDIsIHRoaXMtPmNhcmRpbmFsaXR5KCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBpbnQzMiBudW1iZXIgPSAzOworICBpZiAodGhpcy0+bnVtYmVyKCkgIT0gMCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUludDMyKDMsIHRoaXMtPm51bWJlcigpLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSA0OworICBpZiAodGhpcy0+bmFtZSgpLnNpemUoKSA+IDApIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VmVyaWZ5VXRmOFN0cmluZygKKyAgICAgIHRoaXMtPm5hbWUoKS5kYXRhKCksIHRoaXMtPm5hbWUoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLkZpZWxkLm5hbWUiKTsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdNYXliZUFsaWFzZWQoCisgICAgICA0LCB0aGlzLT5uYW1lKCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgdHlwZV91cmwgPSA2OworICBpZiAodGhpcy0+dHlwZV91cmwoKS5zaXplKCkgPiAwKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlZlcmlmeVV0ZjhTdHJpbmcoCisgICAgICB0aGlzLT50eXBlX3VybCgpLmRhdGEoKSwgdGhpcy0+dHlwZV91cmwoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLkZpZWxkLnR5cGVfdXJsIik7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nTWF5YmVBbGlhc2VkKAorICAgICAgNiwgdGhpcy0+dHlwZV91cmwoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGludDMyIG9uZW9mX2luZGV4ID0gNzsKKyAgaWYgKHRoaXMtPm9uZW9mX2luZGV4KCkgIT0gMCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUludDMyKDcsIHRoaXMtPm9uZW9mX2luZGV4KCksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBib29sIHBhY2tlZCA9IDg7CisgIGlmICh0aGlzLT5wYWNrZWQoKSAhPSAwKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlQm9vbCg4LCB0aGlzLT5wYWNrZWQoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuT3B0aW9uIG9wdGlvbnMgPSA5OworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPm9wdGlvbnNfc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlTWVzc2FnZU1heWJlVG9BcnJheSgKKyAgICAgIDksIHRoaXMtPm9wdGlvbnMoaSksIG91dHB1dCk7CisgIH0KKworICAvLyBvcHRpb25hbCBzdHJpbmcganNvbl9uYW1lID0gMTA7CisgIGlmICh0aGlzLT5qc29uX25hbWUoKS5zaXplKCkgPiAwKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlZlcmlmeVV0ZjhTdHJpbmcoCisgICAgICB0aGlzLT5qc29uX25hbWUoKS5kYXRhKCksIHRoaXMtPmpzb25fbmFtZSgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuRmllbGQuanNvbl9uYW1lIik7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nTWF5YmVBbGlhc2VkKAorICAgICAgMTAsIHRoaXMtPmpzb25fbmFtZSgpLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIGRlZmF1bHRfdmFsdWUgPSAxMTsKKyAgaWYgKHRoaXMtPmRlZmF1bHRfdmFsdWUoKS5zaXplKCkgPiAwKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlZlcmlmeVV0ZjhTdHJpbmcoCisgICAgICB0aGlzLT5kZWZhdWx0X3ZhbHVlKCkuZGF0YSgpLCB0aGlzLT5kZWZhdWx0X3ZhbHVlKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5GaWVsZC5kZWZhdWx0X3ZhbHVlIik7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nTWF5YmVBbGlhc2VkKAorICAgICAgMTEsIHRoaXMtPmRlZmF1bHRfdmFsdWUoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfZW5kOmdvb2dsZS5wcm90b2J1Zi5GaWVsZCkKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogRmllbGQ6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogdGFyZ2V0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkKQorICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkLktpbmQga2luZCA9IDE7CisgIGlmICh0aGlzLT5raW5kKCkgIT0gMCkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUVudW1Ub0FycmF5KAorICAgICAgMSwgdGhpcy0+a2luZCgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZC5DYXJkaW5hbGl0eSBjYXJkaW5hbGl0eSA9IDI7CisgIGlmICh0aGlzLT5jYXJkaW5hbGl0eSgpICE9IDApIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVFbnVtVG9BcnJheSgKKyAgICAgIDIsIHRoaXMtPmNhcmRpbmFsaXR5KCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBpbnQzMiBudW1iZXIgPSAzOworICBpZiAodGhpcy0+bnVtYmVyKCkgIT0gMCkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUludDMyVG9BcnJheSgzLCB0aGlzLT5udW1iZXIoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gNDsKKyAgaWYgKHRoaXMtPm5hbWUoKS5zaXplKCkgPiAwKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlZlcmlmeVV0ZjhTdHJpbmcoCisgICAgICB0aGlzLT5uYW1lKCkuZGF0YSgpLCB0aGlzLT5uYW1lKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5GaWVsZC5uYW1lIik7CisgICAgdGFyZ2V0ID0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ1RvQXJyYXkoCisgICAgICAgIDQsIHRoaXMtPm5hbWUoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIHN0cmluZyB0eXBlX3VybCA9IDY7CisgIGlmICh0aGlzLT50eXBlX3VybCgpLnNpemUoKSA+IDApIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VmVyaWZ5VXRmOFN0cmluZygKKyAgICAgIHRoaXMtPnR5cGVfdXJsKCkuZGF0YSgpLCB0aGlzLT50eXBlX3VybCgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuRmllbGQudHlwZV91cmwiKTsKKyAgICB0YXJnZXQgPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nVG9BcnJheSgKKyAgICAgICAgNiwgdGhpcy0+dHlwZV91cmwoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGludDMyIG9uZW9mX2luZGV4ID0gNzsKKyAgaWYgKHRoaXMtPm9uZW9mX2luZGV4KCkgIT0gMCkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUludDMyVG9BcnJheSg3LCB0aGlzLT5vbmVvZl9pbmRleCgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgYm9vbCBwYWNrZWQgPSA4OworICBpZiAodGhpcy0+cGFja2VkKCkgIT0gMCkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2xUb0FycmF5KDgsIHRoaXMtPnBhY2tlZCgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5PcHRpb24gb3B0aW9ucyA9IDk7CisgIGZvciAodW5zaWduZWQgaW50IGkgPSAwLCBuID0gdGhpcy0+b3B0aW9uc19zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6CisgICAgICBXcml0ZU1lc3NhZ2VOb1ZpcnR1YWxUb0FycmF5KAorICAgICAgICA5LCB0aGlzLT5vcHRpb25zKGkpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIGpzb25fbmFtZSA9IDEwOworICBpZiAodGhpcy0+anNvbl9uYW1lKCkuc2l6ZSgpID4gMCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpWZXJpZnlVdGY4U3RyaW5nKAorICAgICAgdGhpcy0+anNvbl9uYW1lKCkuZGF0YSgpLCB0aGlzLT5qc29uX25hbWUoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLkZpZWxkLmpzb25fbmFtZSIpOworICAgIHRhcmdldCA9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdUb0FycmF5KAorICAgICAgICAxMCwgdGhpcy0+anNvbl9uYW1lKCksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgZGVmYXVsdF92YWx1ZSA9IDExOworICBpZiAodGhpcy0+ZGVmYXVsdF92YWx1ZSgpLnNpemUoKSA+IDApIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VmVyaWZ5VXRmOFN0cmluZygKKyAgICAgIHRoaXMtPmRlZmF1bHRfdmFsdWUoKS5kYXRhKCksIHRoaXMtPmRlZmF1bHRfdmFsdWUoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLkZpZWxkLmRlZmF1bHRfdmFsdWUiKTsKKyAgICB0YXJnZXQgPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nVG9BcnJheSgKKyAgICAgICAgMTEsIHRoaXMtPmRlZmF1bHRfdmFsdWUoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfZW5kOmdvb2dsZS5wcm90b2J1Zi5GaWVsZCkKKyAgcmV0dXJuIHRhcmdldDsKK30KKworaW50IEZpZWxkOjpCeXRlU2l6ZSgpIGNvbnN0IHsKKyAgaW50IHRvdGFsX3NpemUgPSAwOworCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmllbGQuS2luZCBraW5kID0gMTsKKyAgaWYgKHRoaXMtPmtpbmQoKSAhPSAwKSB7CisgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpFbnVtU2l6ZSh0aGlzLT5raW5kKCkpOworICB9CisKKyAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZC5DYXJkaW5hbGl0eSBjYXJkaW5hbGl0eSA9IDI7CisgIGlmICh0aGlzLT5jYXJkaW5hbGl0eSgpICE9IDApIHsKKyAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkVudW1TaXplKHRoaXMtPmNhcmRpbmFsaXR5KCkpOworICB9CisKKyAgLy8gb3B0aW9uYWwgaW50MzIgbnVtYmVyID0gMzsKKyAgaWYgKHRoaXMtPm51bWJlcigpICE9IDApIHsKKyAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkludDMyU2l6ZSgKKyAgICAgICAgdGhpcy0+bnVtYmVyKCkpOworICB9CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSA0OworICBpZiAodGhpcy0+bmFtZSgpLnNpemUoKSA+IDApIHsKKyAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlN0cmluZ1NpemUoCisgICAgICAgIHRoaXMtPm5hbWUoKSk7CisgIH0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgdHlwZV91cmwgPSA2OworICBpZiAodGhpcy0+dHlwZV91cmwoKS5zaXplKCkgPiAwKSB7CisgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTdHJpbmdTaXplKAorICAgICAgICB0aGlzLT50eXBlX3VybCgpKTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGludDMyIG9uZW9mX2luZGV4ID0gNzsKKyAgaWYgKHRoaXMtPm9uZW9mX2luZGV4KCkgIT0gMCkgeworICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6SW50MzJTaXplKAorICAgICAgICB0aGlzLT5vbmVvZl9pbmRleCgpKTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGJvb2wgcGFja2VkID0gODsKKyAgaWYgKHRoaXMtPnBhY2tlZCgpICE9IDApIHsKKyAgICB0b3RhbF9zaXplICs9IDEgKyAxOworICB9CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIGpzb25fbmFtZSA9IDEwOworICBpZiAodGhpcy0+anNvbl9uYW1lKCkuc2l6ZSgpID4gMCkgeworICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U3RyaW5nU2l6ZSgKKyAgICAgICAgdGhpcy0+anNvbl9uYW1lKCkpOworICB9CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIGRlZmF1bHRfdmFsdWUgPSAxMTsKKyAgaWYgKHRoaXMtPmRlZmF1bHRfdmFsdWUoKS5zaXplKCkgPiAwKSB7CisgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTdHJpbmdTaXplKAorICAgICAgICB0aGlzLT5kZWZhdWx0X3ZhbHVlKCkpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5PcHRpb24gb3B0aW9ucyA9IDk7CisgIHRvdGFsX3NpemUgKz0gMSAqIHRoaXMtPm9wdGlvbnNfc2l6ZSgpOworICBmb3IgKGludCBpID0gMDsgaSA8IHRoaXMtPm9wdGlvbnNfc2l6ZSgpOyBpKyspIHsKKyAgICB0b3RhbF9zaXplICs9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6TWVzc2FnZVNpemVOb1ZpcnR1YWwoCisgICAgICAgIHRoaXMtPm9wdGlvbnMoaSkpOworICB9CisKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHRvdGFsX3NpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworICByZXR1cm4gdG90YWxfc2l6ZTsKK30KKwordm9pZCBGaWVsZDo6TWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBjb25zdCBGaWVsZCogc291cmNlID0gCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpEeW5hbWljQ2FzdFRvR2VuZXJhdGVkPGNvbnN0IEZpZWxkPigKKyAgICAgICAgICAmZnJvbSk7CisgIGlmIChzb3VyY2UgPT0gTlVMTCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlJlZmxlY3Rpb25PcHM6Ok1lcmdlKGZyb20sIHRoaXMpOworICB9IGVsc2UgeworICAgIE1lcmdlRnJvbSgqc291cmNlKTsKKyAgfQorfQorCit2b2lkIEZpZWxkOjpNZXJnZUZyb20oY29uc3QgRmllbGQmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgb3B0aW9uc18uTWVyZ2VGcm9tKGZyb20ub3B0aW9uc18pOworICBpZiAoZnJvbS5raW5kKCkgIT0gMCkgeworICAgIHNldF9raW5kKGZyb20ua2luZCgpKTsKKyAgfQorICBpZiAoZnJvbS5jYXJkaW5hbGl0eSgpICE9IDApIHsKKyAgICBzZXRfY2FyZGluYWxpdHkoZnJvbS5jYXJkaW5hbGl0eSgpKTsKKyAgfQorICBpZiAoZnJvbS5udW1iZXIoKSAhPSAwKSB7CisgICAgc2V0X251bWJlcihmcm9tLm51bWJlcigpKTsKKyAgfQorICBpZiAoZnJvbS5uYW1lKCkuc2l6ZSgpID4gMCkgeworCisgICAgbmFtZV8uQXNzaWduV2l0aERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBmcm9tLm5hbWVfKTsKKyAgfQorICBpZiAoZnJvbS50eXBlX3VybCgpLnNpemUoKSA+IDApIHsKKworICAgIHR5cGVfdXJsXy5Bc3NpZ25XaXRoRGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGZyb20udHlwZV91cmxfKTsKKyAgfQorICBpZiAoZnJvbS5vbmVvZl9pbmRleCgpICE9IDApIHsKKyAgICBzZXRfb25lb2ZfaW5kZXgoZnJvbS5vbmVvZl9pbmRleCgpKTsKKyAgfQorICBpZiAoZnJvbS5wYWNrZWQoKSAhPSAwKSB7CisgICAgc2V0X3BhY2tlZChmcm9tLnBhY2tlZCgpKTsKKyAgfQorICBpZiAoZnJvbS5qc29uX25hbWUoKS5zaXplKCkgPiAwKSB7CisKKyAgICBqc29uX25hbWVfLkFzc2lnbldpdGhEZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgZnJvbS5qc29uX25hbWVfKTsKKyAgfQorICBpZiAoZnJvbS5kZWZhdWx0X3ZhbHVlKCkuc2l6ZSgpID4gMCkgeworCisgICAgZGVmYXVsdF92YWx1ZV8uQXNzaWduV2l0aERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBmcm9tLmRlZmF1bHRfdmFsdWVfKTsKKyAgfQorfQorCit2b2lkIEZpZWxkOjpDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCit2b2lkIEZpZWxkOjpDb3B5RnJvbShjb25zdCBGaWVsZCYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK2Jvb2wgRmllbGQ6OklzSW5pdGlhbGl6ZWQoKSBjb25zdCB7CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgRmllbGQ6OlN3YXAoRmllbGQqIG90aGVyKSB7CisgIGlmIChvdGhlciA9PSB0aGlzKSByZXR1cm47CisgIEludGVybmFsU3dhcChvdGhlcik7Cit9Cit2b2lkIEZpZWxkOjpJbnRlcm5hbFN3YXAoRmllbGQqIG90aGVyKSB7CisgIHN0ZDo6c3dhcChraW5kXywgb3RoZXItPmtpbmRfKTsKKyAgc3RkOjpzd2FwKGNhcmRpbmFsaXR5Xywgb3RoZXItPmNhcmRpbmFsaXR5Xyk7CisgIHN0ZDo6c3dhcChudW1iZXJfLCBvdGhlci0+bnVtYmVyXyk7CisgIG5hbWVfLlN3YXAoJm90aGVyLT5uYW1lXyk7CisgIHR5cGVfdXJsXy5Td2FwKCZvdGhlci0+dHlwZV91cmxfKTsKKyAgc3RkOjpzd2FwKG9uZW9mX2luZGV4Xywgb3RoZXItPm9uZW9mX2luZGV4Xyk7CisgIHN0ZDo6c3dhcChwYWNrZWRfLCBvdGhlci0+cGFja2VkXyk7CisgIG9wdGlvbnNfLlVuc2FmZUFyZW5hU3dhcCgmb3RoZXItPm9wdGlvbnNfKTsKKyAganNvbl9uYW1lXy5Td2FwKCZvdGhlci0+anNvbl9uYW1lXyk7CisgIGRlZmF1bHRfdmFsdWVfLlN3YXAoJm90aGVyLT5kZWZhdWx0X3ZhbHVlXyk7CisgIF9pbnRlcm5hbF9tZXRhZGF0YV8uU3dhcCgmb3RoZXItPl9pbnRlcm5hbF9tZXRhZGF0YV8pOworICBzdGQ6OnN3YXAoX2NhY2hlZF9zaXplXywgb3RoZXItPl9jYWNoZWRfc2l6ZV8pOworfQorCis6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEZpZWxkOjpHZXRNZXRhZGF0YSgpIGNvbnN0IHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgbWV0YWRhdGE7CisgIG1ldGFkYXRhLmRlc2NyaXB0b3IgPSBGaWVsZF9kZXNjcmlwdG9yXzsKKyAgbWV0YWRhdGEucmVmbGVjdGlvbiA9IEZpZWxkX3JlZmxlY3Rpb25fOworICByZXR1cm4gbWV0YWRhdGE7Cit9CisKKyNpZiBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKy8vIEZpZWxkCisKKy8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmllbGQuS2luZCBraW5kID0gMTsKK3ZvaWQgRmllbGQ6OmNsZWFyX2tpbmQoKSB7CisgIGtpbmRfID0gMDsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0tpbmQgRmllbGQ6OmtpbmQoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkLmtpbmQpCisgIHJldHVybiBzdGF0aWNfY2FzdDwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZF9LaW5kID4oa2luZF8pOworfQorIHZvaWQgRmllbGQ6OnNldF9raW5kKDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGRfS2luZCB2YWx1ZSkgeworICAKKyAga2luZF8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmllbGQua2luZCkKK30KKworLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZC5DYXJkaW5hbGl0eSBjYXJkaW5hbGl0eSA9IDI7Cit2b2lkIEZpZWxkOjpjbGVhcl9jYXJkaW5hbGl0eSgpIHsKKyAgY2FyZGluYWxpdHlfID0gMDsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0NhcmRpbmFsaXR5IEZpZWxkOjpjYXJkaW5hbGl0eSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmllbGQuY2FyZGluYWxpdHkpCisgIHJldHVybiBzdGF0aWNfY2FzdDwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZF9DYXJkaW5hbGl0eSA+KGNhcmRpbmFsaXR5Xyk7Cit9Cisgdm9pZCBGaWVsZDo6c2V0X2NhcmRpbmFsaXR5KDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGRfQ2FyZGluYWxpdHkgdmFsdWUpIHsKKyAgCisgIGNhcmRpbmFsaXR5XyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZC5jYXJkaW5hbGl0eSkKK30KKworLy8gb3B0aW9uYWwgaW50MzIgbnVtYmVyID0gMzsKK3ZvaWQgRmllbGQ6OmNsZWFyX251bWJlcigpIHsKKyAgbnVtYmVyXyA9IDA7Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiBGaWVsZDo6bnVtYmVyKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZC5udW1iZXIpCisgIHJldHVybiBudW1iZXJfOworfQorIHZvaWQgRmllbGQ6OnNldF9udW1iZXIoOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiB2YWx1ZSkgeworICAKKyAgbnVtYmVyXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZC5udW1iZXIpCit9CisKKy8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gNDsKK3ZvaWQgRmllbGQ6OmNsZWFyX25hbWUoKSB7CisgIG5hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyBjb25zdCA6OnN0ZDo6c3RyaW5nJiBGaWVsZDo6bmFtZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmllbGQubmFtZSkKKyAgcmV0dXJuIG5hbWVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIEZpZWxkOjpzZXRfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICAKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmllbGQubmFtZSkKK30KKyB2b2lkIEZpZWxkOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICAKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5GaWVsZC5uYW1lKQorfQorIHZvaWQgRmllbGQ6OnNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICAKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLkZpZWxkLm5hbWUpCit9CisgOjpzdGQ6OnN0cmluZyogRmllbGQ6Om11dGFibGVfbmFtZSgpIHsKKyAgCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5GaWVsZC5uYW1lKQorICByZXR1cm4gbmFtZV8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyA6OnN0ZDo6c3RyaW5nKiBGaWVsZDo6cmVsZWFzZV9uYW1lKCkgeworICAKKyAgcmV0dXJuIG5hbWVfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBGaWVsZDo6c2V0X2FsbG9jYXRlZF9uYW1lKDo6c3RkOjpzdHJpbmcqIG5hbWUpIHsKKyAgaWYgKG5hbWUgIT0gTlVMTCkgeworICAgIAorICB9IGVsc2UgeworICAgIAorICB9CisgIG5hbWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBuYW1lKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkLm5hbWUpCit9CisKKy8vIG9wdGlvbmFsIHN0cmluZyB0eXBlX3VybCA9IDY7Cit2b2lkIEZpZWxkOjpjbGVhcl90eXBlX3VybCgpIHsKKyAgdHlwZV91cmxfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyBjb25zdCA6OnN0ZDo6c3RyaW5nJiBGaWVsZDo6dHlwZV91cmwoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkLnR5cGVfdXJsKQorICByZXR1cm4gdHlwZV91cmxfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIEZpZWxkOjpzZXRfdHlwZV91cmwoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgCisgIHR5cGVfdXJsXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZC50eXBlX3VybCkKK30KKyB2b2lkIEZpZWxkOjpzZXRfdHlwZV91cmwoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgCisgIHR5cGVfdXJsXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLkZpZWxkLnR5cGVfdXJsKQorfQorIHZvaWQgRmllbGQ6OnNldF90eXBlX3VybChjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgCisgIHR5cGVfdXJsXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuRmllbGQudHlwZV91cmwpCit9CisgOjpzdGQ6OnN0cmluZyogRmllbGQ6Om11dGFibGVfdHlwZV91cmwoKSB7CisgIAorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRmllbGQudHlwZV91cmwpCisgIHJldHVybiB0eXBlX3VybF8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyA6OnN0ZDo6c3RyaW5nKiBGaWVsZDo6cmVsZWFzZV90eXBlX3VybCgpIHsKKyAgCisgIHJldHVybiB0eXBlX3VybF8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIEZpZWxkOjpzZXRfYWxsb2NhdGVkX3R5cGVfdXJsKDo6c3RkOjpzdHJpbmcqIHR5cGVfdXJsKSB7CisgIGlmICh0eXBlX3VybCAhPSBOVUxMKSB7CisgICAgCisgIH0gZWxzZSB7CisgICAgCisgIH0KKyAgdHlwZV91cmxfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB0eXBlX3VybCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5GaWVsZC50eXBlX3VybCkKK30KKworLy8gb3B0aW9uYWwgaW50MzIgb25lb2ZfaW5kZXggPSA3Owordm9pZCBGaWVsZDo6Y2xlYXJfb25lb2ZfaW5kZXgoKSB7CisgIG9uZW9mX2luZGV4XyA9IDA7Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiBGaWVsZDo6b25lb2ZfaW5kZXgoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkLm9uZW9mX2luZGV4KQorICByZXR1cm4gb25lb2ZfaW5kZXhfOworfQorIHZvaWQgRmllbGQ6OnNldF9vbmVvZl9pbmRleCg6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKSB7CisgIAorICBvbmVvZl9pbmRleF8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmllbGQub25lb2ZfaW5kZXgpCit9CisKKy8vIG9wdGlvbmFsIGJvb2wgcGFja2VkID0gODsKK3ZvaWQgRmllbGQ6OmNsZWFyX3BhY2tlZCgpIHsKKyAgcGFja2VkXyA9IGZhbHNlOworfQorIGJvb2wgRmllbGQ6OnBhY2tlZCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmllbGQucGFja2VkKQorICByZXR1cm4gcGFja2VkXzsKK30KKyB2b2lkIEZpZWxkOjpzZXRfcGFja2VkKGJvb2wgdmFsdWUpIHsKKyAgCisgIHBhY2tlZF8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmllbGQucGFja2VkKQorfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLk9wdGlvbiBvcHRpb25zID0gOTsKK2ludCBGaWVsZDo6b3B0aW9uc19zaXplKCkgY29uc3QgeworICByZXR1cm4gb3B0aW9uc18uc2l6ZSgpOworfQordm9pZCBGaWVsZDo6Y2xlYXJfb3B0aW9ucygpIHsKKyAgb3B0aW9uc18uQ2xlYXIoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6T3B0aW9uJiBGaWVsZDo6b3B0aW9ucyhpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmllbGQub3B0aW9ucykKKyAgcmV0dXJuIG9wdGlvbnNfLkdldChpbmRleCk7Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbiogRmllbGQ6Om11dGFibGVfb3B0aW9ucyhpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpZWxkLm9wdGlvbnMpCisgIHJldHVybiBvcHRpb25zXy5NdXRhYmxlKGluZGV4KTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6T3B0aW9uKiBGaWVsZDo6YWRkX29wdGlvbnMoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9hZGQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkLm9wdGlvbnMpCisgIHJldHVybiBvcHRpb25zXy5BZGQoKTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpPcHRpb24gPioKK0ZpZWxkOjptdXRhYmxlX29wdGlvbnMoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkZpZWxkLm9wdGlvbnMpCisgIHJldHVybiAmb3B0aW9uc187Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6T3B0aW9uID4mCitGaWVsZDo6b3B0aW9ucygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkZpZWxkLm9wdGlvbnMpCisgIHJldHVybiBvcHRpb25zXzsKK30KKworLy8gb3B0aW9uYWwgc3RyaW5nIGpzb25fbmFtZSA9IDEwOwordm9pZCBGaWVsZDo6Y2xlYXJfanNvbl9uYW1lKCkgeworICBqc29uX25hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyBjb25zdCA6OnN0ZDo6c3RyaW5nJiBGaWVsZDo6anNvbl9uYW1lKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZC5qc29uX25hbWUpCisgIHJldHVybiBqc29uX25hbWVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIEZpZWxkOjpzZXRfanNvbl9uYW1lKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIAorICBqc29uX25hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkLmpzb25fbmFtZSkKK30KKyB2b2lkIEZpZWxkOjpzZXRfanNvbl9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIAorICBqc29uX25hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuRmllbGQuanNvbl9uYW1lKQorfQorIHZvaWQgRmllbGQ6OnNldF9qc29uX25hbWUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIAorICBqc29uX25hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5GaWVsZC5qc29uX25hbWUpCit9CisgOjpzdGQ6OnN0cmluZyogRmllbGQ6Om11dGFibGVfanNvbl9uYW1lKCkgeworICAKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpZWxkLmpzb25fbmFtZSkKKyAgcmV0dXJuIGpzb25fbmFtZV8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyA6OnN0ZDo6c3RyaW5nKiBGaWVsZDo6cmVsZWFzZV9qc29uX25hbWUoKSB7CisgIAorICByZXR1cm4ganNvbl9uYW1lXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgRmllbGQ6OnNldF9hbGxvY2F0ZWRfanNvbl9uYW1lKDo6c3RkOjpzdHJpbmcqIGpzb25fbmFtZSkgeworICBpZiAoanNvbl9uYW1lICE9IE5VTEwpIHsKKyAgICAKKyAgfSBlbHNlIHsKKyAgICAKKyAgfQorICBqc29uX25hbWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBqc29uX25hbWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuRmllbGQuanNvbl9uYW1lKQorfQorCisvLyBvcHRpb25hbCBzdHJpbmcgZGVmYXVsdF92YWx1ZSA9IDExOwordm9pZCBGaWVsZDo6Y2xlYXJfZGVmYXVsdF92YWx1ZSgpIHsKKyAgZGVmYXVsdF92YWx1ZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEZpZWxkOjpkZWZhdWx0X3ZhbHVlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZC5kZWZhdWx0X3ZhbHVlKQorICByZXR1cm4gZGVmYXVsdF92YWx1ZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgRmllbGQ6OnNldF9kZWZhdWx0X3ZhbHVlKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIAorICBkZWZhdWx0X3ZhbHVlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZC5kZWZhdWx0X3ZhbHVlKQorfQorIHZvaWQgRmllbGQ6OnNldF9kZWZhdWx0X3ZhbHVlKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIAorICBkZWZhdWx0X3ZhbHVlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLkZpZWxkLmRlZmF1bHRfdmFsdWUpCit9Cisgdm9pZCBGaWVsZDo6c2V0X2RlZmF1bHRfdmFsdWUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIAorICBkZWZhdWx0X3ZhbHVlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuRmllbGQuZGVmYXVsdF92YWx1ZSkKK30KKyA6OnN0ZDo6c3RyaW5nKiBGaWVsZDo6bXV0YWJsZV9kZWZhdWx0X3ZhbHVlKCkgeworICAKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpZWxkLmRlZmF1bHRfdmFsdWUpCisgIHJldHVybiBkZWZhdWx0X3ZhbHVlXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIDo6c3RkOjpzdHJpbmcqIEZpZWxkOjpyZWxlYXNlX2RlZmF1bHRfdmFsdWUoKSB7CisgIAorICByZXR1cm4gZGVmYXVsdF92YWx1ZV8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIEZpZWxkOjpzZXRfYWxsb2NhdGVkX2RlZmF1bHRfdmFsdWUoOjpzdGQ6OnN0cmluZyogZGVmYXVsdF92YWx1ZSkgeworICBpZiAoZGVmYXVsdF92YWx1ZSAhPSBOVUxMKSB7CisgICAgCisgIH0gZWxzZSB7CisgICAgCisgIH0KKyAgZGVmYXVsdF92YWx1ZV8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGRlZmF1bHRfdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuRmllbGQuZGVmYXVsdF92YWx1ZSkKK30KKworI2VuZGlmICAvLyBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisjaWYgIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKK2NvbnN0IGludCBFbnVtOjprTmFtZUZpZWxkTnVtYmVyOworY29uc3QgaW50IEVudW06OmtFbnVtdmFsdWVGaWVsZE51bWJlcjsKK2NvbnN0IGludCBFbnVtOjprT3B0aW9uc0ZpZWxkTnVtYmVyOworY29uc3QgaW50IEVudW06OmtTb3VyY2VDb250ZXh0RmllbGROdW1iZXI7Citjb25zdCBpbnQgRW51bTo6a1N5bnRheEZpZWxkTnVtYmVyOworI2VuZGlmICAvLyAhZGVmaW5lZChfTVNDX1ZFUikgfHwgX01TQ19WRVIgPj0gMTkwMAorCitFbnVtOjpFbnVtKCkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5FbnVtKQorfQorCit2b2lkIEVudW06OkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpIHsKKyAgX2lzX2RlZmF1bHRfaW5zdGFuY2VfID0gdHJ1ZTsKKyAgc291cmNlX2NvbnRleHRfID0gY29uc3RfY2FzdDwgOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb250ZXh0Kj4oJjo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29udGV4dDo6ZGVmYXVsdF9pbnN0YW5jZSgpKTsKK30KKworRW51bTo6RW51bShjb25zdCBFbnVtJiBmcm9tKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpLAorICAgIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgeworICBTaGFyZWRDdG9yKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvcHlfY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLkVudW0pCit9CisKK3ZvaWQgRW51bTo6U2hhcmVkQ3RvcigpIHsKKyAgICBfaXNfZGVmYXVsdF9pbnN0YW5jZV8gPSBmYWxzZTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmcoKTsKKyAgX2NhY2hlZF9zaXplXyA9IDA7CisgIG5hbWVfLlVuc2FmZVNldERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKKyAgc291cmNlX2NvbnRleHRfID0gTlVMTDsKKyAgc3ludGF4XyA9IDA7Cit9CisKK0VudW06On5FbnVtKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZGVzdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuRW51bSkKKyAgU2hhcmVkRHRvcigpOworfQorCit2b2lkIEVudW06OlNoYXJlZER0b3IoKSB7CisgIG5hbWVfLkRlc3Ryb3lOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGlmICh0aGlzICE9IGRlZmF1bHRfaW5zdGFuY2VfKSB7CisgICAgZGVsZXRlIHNvdXJjZV9jb250ZXh0XzsKKyAgfQorfQorCit2b2lkIEVudW06OlNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0IHsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHNpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBFbnVtOjpkZXNjcmlwdG9yKCkgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgcmV0dXJuIEVudW1fZGVzY3JpcHRvcl87Cit9CisKK2NvbnN0IEVudW0mIEVudW06OmRlZmF1bHRfaW5zdGFuY2UoKSB7CisgIGlmIChkZWZhdWx0X2luc3RhbmNlXyA9PSBOVUxMKSBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmdHlwZV8yZXByb3RvKCk7CisgIHJldHVybiAqZGVmYXVsdF9pbnN0YW5jZV87Cit9CisKK0VudW0qIEVudW06OmRlZmF1bHRfaW5zdGFuY2VfID0gTlVMTDsKKworRW51bSogRW51bTo6TmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdCB7CisgIEVudW0qIG4gPSBuZXcgRW51bTsKKyAgaWYgKGFyZW5hICE9IE5VTEwpIHsKKyAgICBhcmVuYS0+T3duKG4pOworICB9CisgIHJldHVybiBuOworfQorCit2b2lkIEVudW06OkNsZWFyKCkgeworICBuYW1lXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGlmIChHZXRBcmVuYU5vVmlydHVhbCgpID09IE5VTEwgJiYgc291cmNlX2NvbnRleHRfICE9IE5VTEwpIGRlbGV0ZSBzb3VyY2VfY29udGV4dF87CisgIHNvdXJjZV9jb250ZXh0XyA9IE5VTEw7CisgIHN5bnRheF8gPSAwOworICBlbnVtdmFsdWVfLkNsZWFyKCk7CisgIG9wdGlvbnNfLkNsZWFyKCk7Cit9CisKK2Jvb2wgRW51bTo6TWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KSB7CisjZGVmaW5lIERPXyhFWFBSRVNTSU9OKSBpZiAoIShFWFBSRVNTSU9OKSkgZ290byBmYWlsdXJlCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIHRhZzsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5FbnVtKQorICBmb3IgKDs7KSB7CisgICAgOjpzdGQ6OnBhaXI8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyLCBib29sPiBwID0gaW5wdXQtPlJlYWRUYWdXaXRoQ3V0b2ZmKDEyNyk7CisgICAgdGFnID0gcC5maXJzdDsKKyAgICBpZiAoIXAuc2Vjb25kKSBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgIHN3aXRjaCAoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ0ZpZWxkTnVtYmVyKHRhZykpIHsKKyAgICAgIC8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKKyAgICAgIGNhc2UgMTogeworICAgICAgICBpZiAodGFnID09IDEwKSB7CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkU3RyaW5nKAorICAgICAgICAgICAgICAgIGlucHV0LCB0aGlzLT5tdXRhYmxlX25hbWUoKSkpOworICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VmVyaWZ5VXRmOFN0cmluZygKKyAgICAgICAgICAgIHRoaXMtPm5hbWUoKS5kYXRhKCksIHRoaXMtPm5hbWUoKS5sZW5ndGgoKSwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpQQVJTRSwKKyAgICAgICAgICAgICJnb29nbGUucHJvdG9idWYuRW51bS5uYW1lIikpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMTgpKSBnb3RvIHBhcnNlX2VudW12YWx1ZTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRW51bVZhbHVlIGVudW12YWx1ZSA9IDI7CisgICAgICBjYXNlIDI6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAxOCkgeworICAgICAgICAgcGFyc2VfZW51bXZhbHVlOgorICAgICAgICAgIERPXyhpbnB1dC0+SW5jcmVtZW50UmVjdXJzaW9uRGVwdGgoKSk7CisgICAgICAgICBwYXJzZV9sb29wX2VudW12YWx1ZToKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRNZXNzYWdlTm9WaXJ0dWFsTm9SZWN1cnNpb25EZXB0aCgKKyAgICAgICAgICAgICAgICBpbnB1dCwgYWRkX2VudW12YWx1ZSgpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygxOCkpIGdvdG8gcGFyc2VfbG9vcF9lbnVtdmFsdWU7CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDI2KSkgZ290byBwYXJzZV9sb29wX29wdGlvbnM7CisgICAgICAgIGlucHV0LT5VbnNhZmVEZWNyZW1lbnRSZWN1cnNpb25EZXB0aCgpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5PcHRpb24gb3B0aW9ucyA9IDM7CisgICAgICBjYXNlIDM6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAyNikgeworICAgICAgICAgIERPXyhpbnB1dC0+SW5jcmVtZW50UmVjdXJzaW9uRGVwdGgoKSk7CisgICAgICAgICBwYXJzZV9sb29wX29wdGlvbnM6CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkTWVzc2FnZU5vVmlydHVhbE5vUmVjdXJzaW9uRGVwdGgoCisgICAgICAgICAgICAgICAgaW5wdXQsIGFkZF9vcHRpb25zKCkpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDI2KSkgZ290byBwYXJzZV9sb29wX29wdGlvbnM7CisgICAgICAgIGlucHV0LT5VbnNhZmVEZWNyZW1lbnRSZWN1cnNpb25EZXB0aCgpOworICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygzNCkpIGdvdG8gcGFyc2Vfc291cmNlX2NvbnRleHQ7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQgc291cmNlX2NvbnRleHQgPSA0OworICAgICAgY2FzZSA0OiB7CisgICAgICAgIGlmICh0YWcgPT0gMzQpIHsKKyAgICAgICAgIHBhcnNlX3NvdXJjZV9jb250ZXh0OgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZE1lc3NhZ2VOb1ZpcnR1YWwoCisgICAgICAgICAgICAgICBpbnB1dCwgbXV0YWJsZV9zb3VyY2VfY29udGV4dCgpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZyg0MCkpIGdvdG8gcGFyc2Vfc3ludGF4OworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5TeW50YXggc3ludGF4ID0gNTsKKyAgICAgIGNhc2UgNTogeworICAgICAgICBpZiAodGFnID09IDQwKSB7CisgICAgICAgICBwYXJzZV9zeW50YXg6CisgICAgICAgICAgaW50IHZhbHVlOworICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgaW50LCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9FTlVNPigKKyAgICAgICAgICAgICAgICAgaW5wdXQsICZ2YWx1ZSkpKTsKKyAgICAgICAgICBzZXRfc3ludGF4KHN0YXRpY19jYXN0PCA6Omdvb2dsZTo6cHJvdG9idWY6OlN5bnRheCA+KHZhbHVlKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdEF0RW5kKCkpIGdvdG8gc3VjY2VzczsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGRlZmF1bHQ6IHsKKyAgICAgIGhhbmRsZV91bnVzdWFsOgorICAgICAgICBpZiAodGFnID09IDAgfHwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdXaXJlVHlwZSh0YWcpID09CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRU5EX0dST1VQKSB7CisgICAgICAgICAgZ290byBzdWNjZXNzOworICAgICAgICB9CisgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U2tpcEZpZWxkKGlucHV0LCB0YWcpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CitzdWNjZXNzOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3VjY2Vzczpnb29nbGUucHJvdG9idWYuRW51bSkKKyAgcmV0dXJuIHRydWU7CitmYWlsdXJlOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2VfZmFpbHVyZTpnb29nbGUucHJvdG9idWYuRW51bSkKKyAgcmV0dXJuIGZhbHNlOworI3VuZGVmIERPXworfQorCit2b2lkIEVudW06OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkVudW0pCisgIC8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKKyAgaWYgKHRoaXMtPm5hbWUoKS5zaXplKCkgPiAwKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlZlcmlmeVV0ZjhTdHJpbmcoCisgICAgICB0aGlzLT5uYW1lKCkuZGF0YSgpLCB0aGlzLT5uYW1lKCkubGVuZ3RoKCksCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U0VSSUFMSVpFLAorICAgICAgImdvb2dsZS5wcm90b2J1Zi5FbnVtLm5hbWUiKTsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdNYXliZUFsaWFzZWQoCisgICAgICAxLCB0aGlzLT5uYW1lKCksIG91dHB1dCk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZSBlbnVtdmFsdWUgPSAyOworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPmVudW12YWx1ZV9zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgMiwgdGhpcy0+ZW51bXZhbHVlKGkpLCBvdXRwdXQpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5PcHRpb24gb3B0aW9ucyA9IDM7CisgIGZvciAodW5zaWduZWQgaW50IGkgPSAwLCBuID0gdGhpcy0+b3B0aW9uc19zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgMywgdGhpcy0+b3B0aW9ucyhpKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCBzb3VyY2VfY29udGV4dCA9IDQ7CisgIGlmICh0aGlzLT5oYXNfc291cmNlX2NvbnRleHQoKSkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZU1lc3NhZ2VNYXliZVRvQXJyYXkoCisgICAgICA0LCAqdGhpcy0+c291cmNlX2NvbnRleHRfLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5TeW50YXggc3ludGF4ID0gNTsKKyAgaWYgKHRoaXMtPnN5bnRheCgpICE9IDApIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVFbnVtKAorICAgICAgNSwgdGhpcy0+c3ludGF4KCksIG91dHB1dCk7CisgIH0KKworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX2VuZDpnb29nbGUucHJvdG9idWYuRW51bSkKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogRW51bTo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiB0YXJnZXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9zdGFydDpnb29nbGUucHJvdG9idWYuRW51bSkKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICBpZiAodGhpcy0+bmFtZSgpLnNpemUoKSA+IDApIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VmVyaWZ5VXRmOFN0cmluZygKKyAgICAgIHRoaXMtPm5hbWUoKS5kYXRhKCksIHRoaXMtPm5hbWUoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLkVudW0ubmFtZSIpOworICAgIHRhcmdldCA9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdUb0FycmF5KAorICAgICAgICAxLCB0aGlzLT5uYW1lKCksIHRhcmdldCk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZSBlbnVtdmFsdWUgPSAyOworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPmVudW12YWx1ZV9zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6CisgICAgICBXcml0ZU1lc3NhZ2VOb1ZpcnR1YWxUb0FycmF5KAorICAgICAgICAyLCB0aGlzLT5lbnVtdmFsdWUoaSksIHRhcmdldCk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLk9wdGlvbiBvcHRpb25zID0gMzsKKyAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDAsIG4gPSB0aGlzLT5vcHRpb25zX3NpemUoKTsgaSA8IG47IGkrKykgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjoKKyAgICAgIFdyaXRlTWVzc2FnZU5vVmlydHVhbFRvQXJyYXkoCisgICAgICAgIDMsIHRoaXMtPm9wdGlvbnMoaSksIHRhcmdldCk7CisgIH0KKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQgc291cmNlX2NvbnRleHQgPSA0OworICBpZiAodGhpcy0+aGFzX3NvdXJjZV9jb250ZXh0KCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6CisgICAgICBXcml0ZU1lc3NhZ2VOb1ZpcnR1YWxUb0FycmF5KAorICAgICAgICA0LCAqdGhpcy0+c291cmNlX2NvbnRleHRfLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5TeW50YXggc3ludGF4ID0gNTsKKyAgaWYgKHRoaXMtPnN5bnRheCgpICE9IDApIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVFbnVtVG9BcnJheSgKKyAgICAgIDUsIHRoaXMtPnN5bnRheCgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9lbmQ6Z29vZ2xlLnByb3RvYnVmLkVudW0pCisgIHJldHVybiB0YXJnZXQ7Cit9CisKK2ludCBFbnVtOjpCeXRlU2l6ZSgpIGNvbnN0IHsKKyAgaW50IHRvdGFsX3NpemUgPSAwOworCisgIC8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKKyAgaWYgKHRoaXMtPm5hbWUoKS5zaXplKCkgPiAwKSB7CisgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTdHJpbmdTaXplKAorICAgICAgICB0aGlzLT5uYW1lKCkpOworICB9CisKKyAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0IHNvdXJjZV9jb250ZXh0ID0gNDsKKyAgaWYgKHRoaXMtPmhhc19zb3VyY2VfY29udGV4dCgpKSB7CisgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpNZXNzYWdlU2l6ZU5vVmlydHVhbCgKKyAgICAgICAgKnRoaXMtPnNvdXJjZV9jb250ZXh0Xyk7CisgIH0KKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLlN5bnRheCBzeW50YXggPSA1OworICBpZiAodGhpcy0+c3ludGF4KCkgIT0gMCkgeworICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6RW51bVNpemUodGhpcy0+c3ludGF4KCkpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWUgZW51bXZhbHVlID0gMjsKKyAgdG90YWxfc2l6ZSArPSAxICogdGhpcy0+ZW51bXZhbHVlX3NpemUoKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT5lbnVtdmFsdWVfc2l6ZSgpOyBpKyspIHsKKyAgICB0b3RhbF9zaXplICs9CisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6TWVzc2FnZVNpemVOb1ZpcnR1YWwoCisgICAgICAgIHRoaXMtPmVudW12YWx1ZShpKSk7CisgIH0KKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLk9wdGlvbiBvcHRpb25zID0gMzsKKyAgdG90YWxfc2l6ZSArPSAxICogdGhpcy0+b3B0aW9uc19zaXplKCk7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhpcy0+b3B0aW9uc19zaXplKCk7IGkrKykgeworICAgIHRvdGFsX3NpemUgKz0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpNZXNzYWdlU2l6ZU5vVmlydHVhbCgKKyAgICAgICAgdGhpcy0+b3B0aW9ucyhpKSk7CisgIH0KKworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gdG90YWxfc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7CisgIHJldHVybiB0b3RhbF9zaXplOworfQorCit2b2lkIEVudW06Ok1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgY29uc3QgRW51bSogc291cmNlID0gCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpEeW5hbWljQ2FzdFRvR2VuZXJhdGVkPGNvbnN0IEVudW0+KAorICAgICAgICAgICZmcm9tKTsKKyAgaWYgKHNvdXJjZSA9PSBOVUxMKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6UmVmbGVjdGlvbk9wczo6TWVyZ2UoZnJvbSwgdGhpcyk7CisgIH0gZWxzZSB7CisgICAgTWVyZ2VGcm9tKCpzb3VyY2UpOworICB9Cit9CisKK3ZvaWQgRW51bTo6TWVyZ2VGcm9tKGNvbnN0IEVudW0mIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgZW51bXZhbHVlXy5NZXJnZUZyb20oZnJvbS5lbnVtdmFsdWVfKTsKKyAgb3B0aW9uc18uTWVyZ2VGcm9tKGZyb20ub3B0aW9uc18pOworICBpZiAoZnJvbS5uYW1lKCkuc2l6ZSgpID4gMCkgeworCisgICAgbmFtZV8uQXNzaWduV2l0aERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBmcm9tLm5hbWVfKTsKKyAgfQorICBpZiAoZnJvbS5oYXNfc291cmNlX2NvbnRleHQoKSkgeworICAgIG11dGFibGVfc291cmNlX2NvbnRleHQoKS0+Ojpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb250ZXh0OjpNZXJnZUZyb20oZnJvbS5zb3VyY2VfY29udGV4dCgpKTsKKyAgfQorICBpZiAoZnJvbS5zeW50YXgoKSAhPSAwKSB7CisgICAgc2V0X3N5bnRheChmcm9tLnN5bnRheCgpKTsKKyAgfQorfQorCit2b2lkIEVudW06OkNvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK3ZvaWQgRW51bTo6Q29weUZyb20oY29uc3QgRW51bSYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK2Jvb2wgRW51bTo6SXNJbml0aWFsaXplZCgpIGNvbnN0IHsKKworICByZXR1cm4gdHJ1ZTsKK30KKwordm9pZCBFbnVtOjpTd2FwKEVudW0qIG90aGVyKSB7CisgIGlmIChvdGhlciA9PSB0aGlzKSByZXR1cm47CisgIEludGVybmFsU3dhcChvdGhlcik7Cit9Cit2b2lkIEVudW06OkludGVybmFsU3dhcChFbnVtKiBvdGhlcikgeworICBuYW1lXy5Td2FwKCZvdGhlci0+bmFtZV8pOworICBlbnVtdmFsdWVfLlVuc2FmZUFyZW5hU3dhcCgmb3RoZXItPmVudW12YWx1ZV8pOworICBvcHRpb25zXy5VbnNhZmVBcmVuYVN3YXAoJm90aGVyLT5vcHRpb25zXyk7CisgIHN0ZDo6c3dhcChzb3VyY2VfY29udGV4dF8sIG90aGVyLT5zb3VyY2VfY29udGV4dF8pOworICBzdGQ6OnN3YXAoc3ludGF4Xywgb3RoZXItPnN5bnRheF8pOworICBfaW50ZXJuYWxfbWV0YWRhdGFfLlN3YXAoJm90aGVyLT5faW50ZXJuYWxfbWV0YWRhdGFfKTsKKyAgc3RkOjpzd2FwKF9jYWNoZWRfc2l6ZV8sIG90aGVyLT5fY2FjaGVkX3NpemVfKTsKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBFbnVtOjpHZXRNZXRhZGF0YSgpIGNvbnN0IHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgbWV0YWRhdGE7CisgIG1ldGFkYXRhLmRlc2NyaXB0b3IgPSBFbnVtX2Rlc2NyaXB0b3JfOworICBtZXRhZGF0YS5yZWZsZWN0aW9uID0gRW51bV9yZWZsZWN0aW9uXzsKKyAgcmV0dXJuIG1ldGFkYXRhOworfQorCisjaWYgUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisvLyBFbnVtCisKKy8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKK3ZvaWQgRW51bTo6Y2xlYXJfbmFtZSgpIHsKKyAgbmFtZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEVudW06Om5hbWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkVudW0ubmFtZSkKKyAgcmV0dXJuIG5hbWVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIEVudW06OnNldF9uYW1lKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIAorICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5FbnVtLm5hbWUpCit9Cisgdm9pZCBFbnVtOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICAKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5FbnVtLm5hbWUpCit9Cisgdm9pZCBFbnVtOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgCisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5FbnVtLm5hbWUpCit9CisgOjpzdGQ6OnN0cmluZyogRW51bTo6bXV0YWJsZV9uYW1lKCkgeworICAKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkVudW0ubmFtZSkKKyAgcmV0dXJuIG5hbWVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CisgOjpzdGQ6OnN0cmluZyogRW51bTo6cmVsZWFzZV9uYW1lKCkgeworICAKKyAgcmV0dXJuIG5hbWVfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBFbnVtOjpzZXRfYWxsb2NhdGVkX25hbWUoOjpzdGQ6OnN0cmluZyogbmFtZSkgeworICBpZiAobmFtZSAhPSBOVUxMKSB7CisgICAgCisgIH0gZWxzZSB7CisgICAgCisgIH0KKyAgbmFtZV8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIG5hbWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuRW51bS5uYW1lKQorfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZSBlbnVtdmFsdWUgPSAyOworaW50IEVudW06OmVudW12YWx1ZV9zaXplKCkgY29uc3QgeworICByZXR1cm4gZW51bXZhbHVlXy5zaXplKCk7Cit9Cit2b2lkIEVudW06OmNsZWFyX2VudW12YWx1ZSgpIHsKKyAgZW51bXZhbHVlXy5DbGVhcigpOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtVmFsdWUmIEVudW06OmVudW12YWx1ZShpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRW51bS5lbnVtdmFsdWUpCisgIHJldHVybiBlbnVtdmFsdWVfLkdldChpbmRleCk7Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZSogRW51bTo6bXV0YWJsZV9lbnVtdmFsdWUoaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5FbnVtLmVudW12YWx1ZSkKKyAgcmV0dXJuIGVudW12YWx1ZV8uTXV0YWJsZShpbmRleCk7Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZSogRW51bTo6YWRkX2VudW12YWx1ZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuRW51bS5lbnVtdmFsdWUpCisgIHJldHVybiBlbnVtdmFsdWVfLkFkZCgpOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZSA+KgorRW51bTo6bXV0YWJsZV9lbnVtdmFsdWUoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkVudW0uZW51bXZhbHVlKQorICByZXR1cm4gJmVudW12YWx1ZV87Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlID4mCitFbnVtOjplbnVtdmFsdWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5FbnVtLmVudW12YWx1ZSkKKyAgcmV0dXJuIGVudW12YWx1ZV87Cit9CisKKy8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuT3B0aW9uIG9wdGlvbnMgPSAzOworaW50IEVudW06Om9wdGlvbnNfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIG9wdGlvbnNfLnNpemUoKTsKK30KK3ZvaWQgRW51bTo6Y2xlYXJfb3B0aW9ucygpIHsKKyAgb3B0aW9uc18uQ2xlYXIoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6T3B0aW9uJiBFbnVtOjpvcHRpb25zKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5FbnVtLm9wdGlvbnMpCisgIHJldHVybiBvcHRpb25zXy5HZXQoaW5kZXgpOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpPcHRpb24qIEVudW06Om11dGFibGVfb3B0aW9ucyhpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkVudW0ub3B0aW9ucykKKyAgcmV0dXJuIG9wdGlvbnNfLk11dGFibGUoaW5kZXgpOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpPcHRpb24qIEVudW06OmFkZF9vcHRpb25zKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5FbnVtLm9wdGlvbnMpCisgIHJldHVybiBvcHRpb25zXy5BZGQoKTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpPcHRpb24gPioKK0VudW06Om11dGFibGVfb3B0aW9ucygpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuRW51bS5vcHRpb25zKQorICByZXR1cm4gJm9wdGlvbnNfOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbiA+JgorRW51bTo6b3B0aW9ucygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkVudW0ub3B0aW9ucykKKyAgcmV0dXJuIG9wdGlvbnNfOworfQorCisvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQgc291cmNlX2NvbnRleHQgPSA0OworYm9vbCBFbnVtOjpoYXNfc291cmNlX2NvbnRleHQoKSBjb25zdCB7CisgIHJldHVybiAhX2lzX2RlZmF1bHRfaW5zdGFuY2VfICYmIHNvdXJjZV9jb250ZXh0XyAhPSBOVUxMOworfQordm9pZCBFbnVtOjpjbGVhcl9zb3VyY2VfY29udGV4dCgpIHsKKyAgaWYgKEdldEFyZW5hTm9WaXJ0dWFsKCkgPT0gTlVMTCAmJiBzb3VyY2VfY29udGV4dF8gIT0gTlVMTCkgZGVsZXRlIHNvdXJjZV9jb250ZXh0XzsKKyAgc291cmNlX2NvbnRleHRfID0gTlVMTDsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29udGV4dCYgRW51bTo6c291cmNlX2NvbnRleHQoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkVudW0uc291cmNlX2NvbnRleHQpCisgIHJldHVybiBzb3VyY2VfY29udGV4dF8gIT0gTlVMTCA/ICpzb3VyY2VfY29udGV4dF8gOiAqZGVmYXVsdF9pbnN0YW5jZV8tPnNvdXJjZV9jb250ZXh0XzsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29udGV4dCogRW51bTo6bXV0YWJsZV9zb3VyY2VfY29udGV4dCgpIHsKKyAgCisgIGlmIChzb3VyY2VfY29udGV4dF8gPT0gTlVMTCkgeworICAgIHNvdXJjZV9jb250ZXh0XyA9IG5ldyA6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvbnRleHQ7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkVudW0uc291cmNlX2NvbnRleHQpCisgIHJldHVybiBzb3VyY2VfY29udGV4dF87Cit9Cis6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvbnRleHQqIEVudW06OnJlbGVhc2Vfc291cmNlX2NvbnRleHQoKSB7CisgIAorICA6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvbnRleHQqIHRlbXAgPSBzb3VyY2VfY29udGV4dF87CisgIHNvdXJjZV9jb250ZXh0XyA9IE5VTEw7CisgIHJldHVybiB0ZW1wOworfQordm9pZCBFbnVtOjpzZXRfYWxsb2NhdGVkX3NvdXJjZV9jb250ZXh0KDo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29udGV4dCogc291cmNlX2NvbnRleHQpIHsKKyAgZGVsZXRlIHNvdXJjZV9jb250ZXh0XzsKKyAgc291cmNlX2NvbnRleHRfID0gc291cmNlX2NvbnRleHQ7CisgIGlmIChzb3VyY2VfY29udGV4dCkgeworICAgIAorICB9IGVsc2UgeworICAgIAorICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5FbnVtLnNvdXJjZV9jb250ZXh0KQorfQorCisvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLlN5bnRheCBzeW50YXggPSA1Owordm9pZCBFbnVtOjpjbGVhcl9zeW50YXgoKSB7CisgIHN5bnRheF8gPSAwOworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6U3ludGF4IEVudW06OnN5bnRheCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRW51bS5zeW50YXgpCisgIHJldHVybiBzdGF0aWNfY2FzdDwgOjpnb29nbGU6OnByb3RvYnVmOjpTeW50YXggPihzeW50YXhfKTsKK30KKyB2b2lkIEVudW06OnNldF9zeW50YXgoOjpnb29nbGU6OnByb3RvYnVmOjpTeW50YXggdmFsdWUpIHsKKyAgCisgIHN5bnRheF8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRW51bS5zeW50YXgpCit9CisKKyNlbmRpZiAgLy8gUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworI2lmICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCitjb25zdCBpbnQgRW51bVZhbHVlOjprTmFtZUZpZWxkTnVtYmVyOworY29uc3QgaW50IEVudW1WYWx1ZTo6a051bWJlckZpZWxkTnVtYmVyOworY29uc3QgaW50IEVudW1WYWx1ZTo6a09wdGlvbnNGaWVsZE51bWJlcjsKKyNlbmRpZiAgLy8gIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKKworRW51bVZhbHVlOjpFbnVtVmFsdWUoKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpLCBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZSkKK30KKwordm9pZCBFbnVtVmFsdWU6OkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpIHsKKyAgX2lzX2RlZmF1bHRfaW5zdGFuY2VfID0gdHJ1ZTsKK30KKworRW51bVZhbHVlOjpFbnVtVmFsdWUoY29uc3QgRW51bVZhbHVlJiBmcm9tKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpLAorICAgIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgeworICBTaGFyZWRDdG9yKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvcHlfY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZSkKK30KKwordm9pZCBFbnVtVmFsdWU6OlNoYXJlZEN0b3IoKSB7CisgICAgX2lzX2RlZmF1bHRfaW5zdGFuY2VfID0gZmFsc2U7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSAwOworICBuYW1lXy5VbnNhZmVTZXREZWZhdWx0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIG51bWJlcl8gPSAwOworfQorCitFbnVtVmFsdWU6On5FbnVtVmFsdWUoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChkZXN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWUpCisgIFNoYXJlZER0b3IoKTsKK30KKwordm9pZCBFbnVtVmFsdWU6OlNoYXJlZER0b3IoKSB7CisgIG5hbWVfLkRlc3Ryb3lOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGlmICh0aGlzICE9IGRlZmF1bHRfaW5zdGFuY2VfKSB7CisgIH0KK30KKwordm9pZCBFbnVtVmFsdWU6OlNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0IHsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHNpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBFbnVtVmFsdWU6OmRlc2NyaXB0b3IoKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICByZXR1cm4gRW51bVZhbHVlX2Rlc2NyaXB0b3JfOworfQorCitjb25zdCBFbnVtVmFsdWUmIEVudW1WYWx1ZTo6ZGVmYXVsdF9pbnN0YW5jZSgpIHsKKyAgaWYgKGRlZmF1bHRfaW5zdGFuY2VfID09IE5VTEwpIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZ0eXBlXzJlcHJvdG8oKTsKKyAgcmV0dXJuICpkZWZhdWx0X2luc3RhbmNlXzsKK30KKworRW51bVZhbHVlKiBFbnVtVmFsdWU6OmRlZmF1bHRfaW5zdGFuY2VfID0gTlVMTDsKKworRW51bVZhbHVlKiBFbnVtVmFsdWU6Ok5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3QgeworICBFbnVtVmFsdWUqIG4gPSBuZXcgRW51bVZhbHVlOworICBpZiAoYXJlbmEgIT0gTlVMTCkgeworICAgIGFyZW5hLT5Pd24obik7CisgIH0KKyAgcmV0dXJuIG47Cit9CisKK3ZvaWQgRW51bVZhbHVlOjpDbGVhcigpIHsKKyAgbmFtZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICBudW1iZXJfID0gMDsKKyAgb3B0aW9uc18uQ2xlYXIoKTsKK30KKworYm9vbCBFbnVtVmFsdWU6Ok1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCkgeworI2RlZmluZSBET18oRVhQUkVTU0lPTikgaWYgKCEoRVhQUkVTU0lPTikpIGdvdG8gZmFpbHVyZQorICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiB0YWc7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdGFydDpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlKQorICBmb3IgKDs7KSB7CisgICAgOjpzdGQ6OnBhaXI8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyLCBib29sPiBwID0gaW5wdXQtPlJlYWRUYWdXaXRoQ3V0b2ZmKDEyNyk7CisgICAgdGFnID0gcC5maXJzdDsKKyAgICBpZiAoIXAuc2Vjb25kKSBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgIHN3aXRjaCAoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ0ZpZWxkTnVtYmVyKHRhZykpIHsKKyAgICAgIC8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKKyAgICAgIGNhc2UgMTogeworICAgICAgICBpZiAodGFnID09IDEwKSB7CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkU3RyaW5nKAorICAgICAgICAgICAgICAgIGlucHV0LCB0aGlzLT5tdXRhYmxlX25hbWUoKSkpOworICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VmVyaWZ5VXRmOFN0cmluZygKKyAgICAgICAgICAgIHRoaXMtPm5hbWUoKS5kYXRhKCksIHRoaXMtPm5hbWUoKS5sZW5ndGgoKSwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpQQVJTRSwKKyAgICAgICAgICAgICJnb29nbGUucHJvdG9idWYuRW51bVZhbHVlLm5hbWUiKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdFRhZygxNikpIGdvdG8gcGFyc2VfbnVtYmVyOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgaW50MzIgbnVtYmVyID0gMjsKKyAgICAgIGNhc2UgMjogeworICAgICAgICBpZiAodGFnID09IDE2KSB7CisgICAgICAgICBwYXJzZV9udW1iZXI6CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyLCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9JTlQzMj4oCisgICAgICAgICAgICAgICAgIGlucHV0LCAmbnVtYmVyXykpKTsKKworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMjYpKSBnb3RvIHBhcnNlX29wdGlvbnM7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLk9wdGlvbiBvcHRpb25zID0gMzsKKyAgICAgIGNhc2UgMzogeworICAgICAgICBpZiAodGFnID09IDI2KSB7CisgICAgICAgICBwYXJzZV9vcHRpb25zOgorICAgICAgICAgIERPXyhpbnB1dC0+SW5jcmVtZW50UmVjdXJzaW9uRGVwdGgoKSk7CisgICAgICAgICBwYXJzZV9sb29wX29wdGlvbnM6CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkTWVzc2FnZU5vVmlydHVhbE5vUmVjdXJzaW9uRGVwdGgoCisgICAgICAgICAgICAgICAgaW5wdXQsIGFkZF9vcHRpb25zKCkpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0VGFnKDI2KSkgZ290byBwYXJzZV9sb29wX29wdGlvbnM7CisgICAgICAgIGlucHV0LT5VbnNhZmVEZWNyZW1lbnRSZWN1cnNpb25EZXB0aCgpOworICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdEF0RW5kKCkpIGdvdG8gc3VjY2VzczsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGRlZmF1bHQ6IHsKKyAgICAgIGhhbmRsZV91bnVzdWFsOgorICAgICAgICBpZiAodGFnID09IDAgfHwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdXaXJlVHlwZSh0YWcpID09CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRU5EX0dST1VQKSB7CisgICAgICAgICAgZ290byBzdWNjZXNzOworICAgICAgICB9CisgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U2tpcEZpZWxkKGlucHV0LCB0YWcpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CitzdWNjZXNzOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3VjY2Vzczpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlKQorICByZXR1cm4gdHJ1ZTsKK2ZhaWx1cmU6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9mYWlsdXJlOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWUpCisgIHJldHVybiBmYWxzZTsKKyN1bmRlZiBET18KK30KKwordm9pZCBFbnVtVmFsdWU6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZSkKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICBpZiAodGhpcy0+bmFtZSgpLnNpemUoKSA+IDApIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VmVyaWZ5VXRmOFN0cmluZygKKyAgICAgIHRoaXMtPm5hbWUoKS5kYXRhKCksIHRoaXMtPm5hbWUoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZS5uYW1lIik7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nTWF5YmVBbGlhc2VkKAorICAgICAgMSwgdGhpcy0+bmFtZSgpLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgaW50MzIgbnVtYmVyID0gMjsKKyAgaWYgKHRoaXMtPm51bWJlcigpICE9IDApIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVJbnQzMigyLCB0aGlzLT5udW1iZXIoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuT3B0aW9uIG9wdGlvbnMgPSAzOworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMCwgbiA9IHRoaXMtPm9wdGlvbnNfc2l6ZSgpOyBpIDwgbjsgaSsrKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlTWVzc2FnZU1heWJlVG9BcnJheSgKKyAgICAgIDMsIHRoaXMtPm9wdGlvbnMoaSksIG91dHB1dCk7CisgIH0KKworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX2VuZDpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlKQorfQorCis6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBFbnVtVmFsdWU6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogdGFyZ2V0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZSkKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICBpZiAodGhpcy0+bmFtZSgpLnNpemUoKSA+IDApIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VmVyaWZ5VXRmOFN0cmluZygKKyAgICAgIHRoaXMtPm5hbWUoKS5kYXRhKCksIHRoaXMtPm5hbWUoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZS5uYW1lIik7CisgICAgdGFyZ2V0ID0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZ1RvQXJyYXkoCisgICAgICAgIDEsIHRoaXMtPm5hbWUoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGludDMyIG51bWJlciA9IDI7CisgIGlmICh0aGlzLT5udW1iZXIoKSAhPSAwKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlSW50MzJUb0FycmF5KDIsIHRoaXMtPm51bWJlcigpLCB0YXJnZXQpOworICB9CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5PcHRpb24gb3B0aW9ucyA9IDM7CisgIGZvciAodW5zaWduZWQgaW50IGkgPSAwLCBuID0gdGhpcy0+b3B0aW9uc19zaXplKCk7IGkgPCBuOyBpKyspIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6CisgICAgICBXcml0ZU1lc3NhZ2VOb1ZpcnR1YWxUb0FycmF5KAorICAgICAgICAzLCB0aGlzLT5vcHRpb25zKGkpLCB0YXJnZXQpOworICB9CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9lbmQ6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZSkKKyAgcmV0dXJuIHRhcmdldDsKK30KKworaW50IEVudW1WYWx1ZTo6Qnl0ZVNpemUoKSBjb25zdCB7CisgIGludCB0b3RhbF9zaXplID0gMDsKKworICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgIGlmICh0aGlzLT5uYW1lKCkuc2l6ZSgpID4gMCkgeworICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U3RyaW5nU2l6ZSgKKyAgICAgICAgdGhpcy0+bmFtZSgpKTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIGludDMyIG51bWJlciA9IDI7CisgIGlmICh0aGlzLT5udW1iZXIoKSAhPSAwKSB7CisgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpJbnQzMlNpemUoCisgICAgICAgIHRoaXMtPm51bWJlcigpKTsKKyAgfQorCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuT3B0aW9uIG9wdGlvbnMgPSAzOworICB0b3RhbF9zaXplICs9IDEgKiB0aGlzLT5vcHRpb25zX3NpemUoKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGlzLT5vcHRpb25zX3NpemUoKTsgaSsrKSB7CisgICAgdG90YWxfc2l6ZSArPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6Ok1lc3NhZ2VTaXplTm9WaXJ0dWFsKAorICAgICAgICB0aGlzLT5vcHRpb25zKGkpKTsKKyAgfQorCisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSB0b3RhbF9zaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKKyAgcmV0dXJuIHRvdGFsX3NpemU7Cit9CisKK3ZvaWQgRW51bVZhbHVlOjpNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGNvbnN0IEVudW1WYWx1ZSogc291cmNlID0gCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpEeW5hbWljQ2FzdFRvR2VuZXJhdGVkPGNvbnN0IEVudW1WYWx1ZT4oCisgICAgICAgICAgJmZyb20pOworICBpZiAoc291cmNlID09IE5VTEwpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpSZWZsZWN0aW9uT3BzOjpNZXJnZShmcm9tLCB0aGlzKTsKKyAgfSBlbHNlIHsKKyAgICBNZXJnZUZyb20oKnNvdXJjZSk7CisgIH0KK30KKwordm9pZCBFbnVtVmFsdWU6Ok1lcmdlRnJvbShjb25zdCBFbnVtVmFsdWUmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgb3B0aW9uc18uTWVyZ2VGcm9tKGZyb20ub3B0aW9uc18pOworICBpZiAoZnJvbS5uYW1lKCkuc2l6ZSgpID4gMCkgeworCisgICAgbmFtZV8uQXNzaWduV2l0aERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBmcm9tLm5hbWVfKTsKKyAgfQorICBpZiAoZnJvbS5udW1iZXIoKSAhPSAwKSB7CisgICAgc2V0X251bWJlcihmcm9tLm51bWJlcigpKTsKKyAgfQorfQorCit2b2lkIEVudW1WYWx1ZTo6Q29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKwordm9pZCBFbnVtVmFsdWU6OkNvcHlGcm9tKGNvbnN0IEVudW1WYWx1ZSYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK2Jvb2wgRW51bVZhbHVlOjpJc0luaXRpYWxpemVkKCkgY29uc3QgeworCisgIHJldHVybiB0cnVlOworfQorCit2b2lkIEVudW1WYWx1ZTo6U3dhcChFbnVtVmFsdWUqIG90aGVyKSB7CisgIGlmIChvdGhlciA9PSB0aGlzKSByZXR1cm47CisgIEludGVybmFsU3dhcChvdGhlcik7Cit9Cit2b2lkIEVudW1WYWx1ZTo6SW50ZXJuYWxTd2FwKEVudW1WYWx1ZSogb3RoZXIpIHsKKyAgbmFtZV8uU3dhcCgmb3RoZXItPm5hbWVfKTsKKyAgc3RkOjpzd2FwKG51bWJlcl8sIG90aGVyLT5udW1iZXJfKTsKKyAgb3B0aW9uc18uVW5zYWZlQXJlbmFTd2FwKCZvdGhlci0+b3B0aW9uc18pOworICBfaW50ZXJuYWxfbWV0YWRhdGFfLlN3YXAoJm90aGVyLT5faW50ZXJuYWxfbWV0YWRhdGFfKTsKKyAgc3RkOjpzd2FwKF9jYWNoZWRfc2l6ZV8sIG90aGVyLT5fY2FjaGVkX3NpemVfKTsKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBFbnVtVmFsdWU6OkdldE1ldGFkYXRhKCkgY29uc3QgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBtZXRhZGF0YTsKKyAgbWV0YWRhdGEuZGVzY3JpcHRvciA9IEVudW1WYWx1ZV9kZXNjcmlwdG9yXzsKKyAgbWV0YWRhdGEucmVmbGVjdGlvbiA9IEVudW1WYWx1ZV9yZWZsZWN0aW9uXzsKKyAgcmV0dXJuIG1ldGFkYXRhOworfQorCisjaWYgUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisvLyBFbnVtVmFsdWUKKworLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOwordm9pZCBFbnVtVmFsdWU6OmNsZWFyX25hbWUoKSB7CisgIG5hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyBjb25zdCA6OnN0ZDo6c3RyaW5nJiBFbnVtVmFsdWU6Om5hbWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZS5uYW1lKQorICByZXR1cm4gbmFtZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgRW51bVZhbHVlOjpzZXRfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICAKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlLm5hbWUpCit9Cisgdm9pZCBFbnVtVmFsdWU6OnNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIAorICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZS5uYW1lKQorfQorIHZvaWQgRW51bVZhbHVlOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgCisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWUubmFtZSkKK30KKyA6OnN0ZDo6c3RyaW5nKiBFbnVtVmFsdWU6Om11dGFibGVfbmFtZSgpIHsKKyAgCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWUubmFtZSkKKyAgcmV0dXJuIG5hbWVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CisgOjpzdGQ6OnN0cmluZyogRW51bVZhbHVlOjpyZWxlYXNlX25hbWUoKSB7CisgIAorICByZXR1cm4gbmFtZV8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIEVudW1WYWx1ZTo6c2V0X2FsbG9jYXRlZF9uYW1lKDo6c3RkOjpzdHJpbmcqIG5hbWUpIHsKKyAgaWYgKG5hbWUgIT0gTlVMTCkgeworICAgIAorICB9IGVsc2UgeworICAgIAorICB9CisgIG5hbWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBuYW1lKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZS5uYW1lKQorfQorCisvLyBvcHRpb25hbCBpbnQzMiBudW1iZXIgPSAyOwordm9pZCBFbnVtVmFsdWU6OmNsZWFyX251bWJlcigpIHsKKyAgbnVtYmVyXyA9IDA7Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiBFbnVtVmFsdWU6Om51bWJlcigpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlLm51bWJlcikKKyAgcmV0dXJuIG51bWJlcl87Cit9Cisgdm9pZCBFbnVtVmFsdWU6OnNldF9udW1iZXIoOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiB2YWx1ZSkgeworICAKKyAgbnVtYmVyXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWUubnVtYmVyKQorfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLk9wdGlvbiBvcHRpb25zID0gMzsKK2ludCBFbnVtVmFsdWU6Om9wdGlvbnNfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIG9wdGlvbnNfLnNpemUoKTsKK30KK3ZvaWQgRW51bVZhbHVlOjpjbGVhcl9vcHRpb25zKCkgeworICBvcHRpb25zXy5DbGVhcigpOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpPcHRpb24mIEVudW1WYWx1ZTo6b3B0aW9ucyhpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlLm9wdGlvbnMpCisgIHJldHVybiBvcHRpb25zXy5HZXQoaW5kZXgpOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpPcHRpb24qIEVudW1WYWx1ZTo6bXV0YWJsZV9vcHRpb25zKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlLm9wdGlvbnMpCisgIHJldHVybiBvcHRpb25zXy5NdXRhYmxlKGluZGV4KTsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6T3B0aW9uKiBFbnVtVmFsdWU6OmFkZF9vcHRpb25zKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWUub3B0aW9ucykKKyAgcmV0dXJuIG9wdGlvbnNfLkFkZCgpOworfQorOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbiA+KgorRW51bVZhbHVlOjptdXRhYmxlX29wdGlvbnMoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZS5vcHRpb25zKQorICByZXR1cm4gJm9wdGlvbnNfOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbiA+JgorRW51bVZhbHVlOjpvcHRpb25zKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlLm9wdGlvbnMpCisgIHJldHVybiBvcHRpb25zXzsKK30KKworI2VuZGlmICAvLyBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisjaWYgIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKK2NvbnN0IGludCBPcHRpb246OmtOYW1lRmllbGROdW1iZXI7Citjb25zdCBpbnQgT3B0aW9uOjprVmFsdWVGaWVsZE51bWJlcjsKKyNlbmRpZiAgLy8gIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKKworT3B0aW9uOjpPcHRpb24oKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpLCBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLk9wdGlvbikKK30KKwordm9pZCBPcHRpb246OkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpIHsKKyAgX2lzX2RlZmF1bHRfaW5zdGFuY2VfID0gdHJ1ZTsKKyAgdmFsdWVfID0gY29uc3RfY2FzdDwgOjpnb29nbGU6OnByb3RvYnVmOjpBbnkqPigmOjpnb29nbGU6OnByb3RvYnVmOjpBbnk6OmRlZmF1bHRfaW5zdGFuY2UoKSk7Cit9CisKK09wdGlvbjo6T3B0aW9uKGNvbnN0IE9wdGlvbiYgZnJvbSkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwKKyAgICBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICBNZXJnZUZyb20oZnJvbSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb3B5X2NvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5PcHRpb24pCit9CisKK3ZvaWQgT3B0aW9uOjpTaGFyZWRDdG9yKCkgeworICAgIF9pc19kZWZhdWx0X2luc3RhbmNlXyA9IGZhbHNlOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZygpOworICBfY2FjaGVkX3NpemVfID0gMDsKKyAgbmFtZV8uVW5zYWZlU2V0RGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworICB2YWx1ZV8gPSBOVUxMOworfQorCitPcHRpb246On5PcHRpb24oKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChkZXN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5PcHRpb24pCisgIFNoYXJlZER0b3IoKTsKK30KKwordm9pZCBPcHRpb246OlNoYXJlZER0b3IoKSB7CisgIG5hbWVfLkRlc3Ryb3lOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGlmICh0aGlzICE9IGRlZmF1bHRfaW5zdGFuY2VfKSB7CisgICAgZGVsZXRlIHZhbHVlXzsKKyAgfQorfQorCit2b2lkIE9wdGlvbjo6U2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3QgeworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIE9wdGlvbjo6ZGVzY3JpcHRvcigpIHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIHJldHVybiBPcHRpb25fZGVzY3JpcHRvcl87Cit9CisKK2NvbnN0IE9wdGlvbiYgT3B0aW9uOjpkZWZhdWx0X2luc3RhbmNlKCkgeworICBpZiAoZGVmYXVsdF9pbnN0YW5jZV8gPT0gTlVMTCkgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZnR5cGVfMmVwcm90bygpOworICByZXR1cm4gKmRlZmF1bHRfaW5zdGFuY2VfOworfQorCitPcHRpb24qIE9wdGlvbjo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBOVUxMOworCitPcHRpb24qIE9wdGlvbjo6TmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdCB7CisgIE9wdGlvbiogbiA9IG5ldyBPcHRpb247CisgIGlmIChhcmVuYSAhPSBOVUxMKSB7CisgICAgYXJlbmEtPk93bihuKTsKKyAgfQorICByZXR1cm4gbjsKK30KKwordm9pZCBPcHRpb246OkNsZWFyKCkgeworICBuYW1lXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7CisgIGlmIChHZXRBcmVuYU5vVmlydHVhbCgpID09IE5VTEwgJiYgdmFsdWVfICE9IE5VTEwpIGRlbGV0ZSB2YWx1ZV87CisgIHZhbHVlXyA9IE5VTEw7Cit9CisKK2Jvb2wgT3B0aW9uOjpNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyNkZWZpbmUgRE9fKEVYUFJFU1NJT04pIGlmICghKEVYUFJFU1NJT04pKSBnb3RvIGZhaWx1cmUKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgdGFnOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLk9wdGlvbikKKyAgZm9yICg7OykgeworICAgIDo6c3RkOjpwYWlyPCA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiwgYm9vbD4gcCA9IGlucHV0LT5SZWFkVGFnV2l0aEN1dG9mZigxMjcpOworICAgIHRhZyA9IHAuZmlyc3Q7CisgICAgaWYgKCFwLnNlY29uZCkgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICBzd2l0Y2ggKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdGaWVsZE51bWJlcih0YWcpKSB7CisgICAgICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgICAgICBjYXNlIDE6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAxMCkgeworICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFN0cmluZygKKyAgICAgICAgICAgICAgICBpbnB1dCwgdGhpcy0+bXV0YWJsZV9uYW1lKCkpKTsKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlZlcmlmeVV0ZjhTdHJpbmcoCisgICAgICAgICAgICB0aGlzLT5uYW1lKCkuZGF0YSgpLCB0aGlzLT5uYW1lKCkubGVuZ3RoKCksCisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UEFSU0UsCisgICAgICAgICAgICAiZ29vZ2xlLnByb3RvYnVmLk9wdGlvbi5uYW1lIikpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RUYWcoMTgpKSBnb3RvIHBhcnNlX3ZhbHVlOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5BbnkgdmFsdWUgPSAyOworICAgICAgY2FzZSAyOiB7CisgICAgICAgIGlmICh0YWcgPT0gMTgpIHsKKyAgICAgICAgIHBhcnNlX3ZhbHVlOgorICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZE1lc3NhZ2VOb1ZpcnR1YWwoCisgICAgICAgICAgICAgICBpbnB1dCwgbXV0YWJsZV92YWx1ZSgpKSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdEF0RW5kKCkpIGdvdG8gc3VjY2VzczsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGRlZmF1bHQ6IHsKKyAgICAgIGhhbmRsZV91bnVzdWFsOgorICAgICAgICBpZiAodGFnID09IDAgfHwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdXaXJlVHlwZSh0YWcpID09CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRU5EX0dST1VQKSB7CisgICAgICAgICAgZ290byBzdWNjZXNzOworICAgICAgICB9CisgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U2tpcEZpZWxkKGlucHV0LCB0YWcpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CitzdWNjZXNzOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3VjY2Vzczpnb29nbGUucHJvdG9idWYuT3B0aW9uKQorICByZXR1cm4gdHJ1ZTsKK2ZhaWx1cmU6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9mYWlsdXJlOmdvb2dsZS5wcm90b2J1Zi5PcHRpb24pCisgIHJldHVybiBmYWxzZTsKKyN1bmRlZiBET18KK30KKwordm9pZCBPcHRpb246OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLk9wdGlvbikKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICBpZiAodGhpcy0+bmFtZSgpLnNpemUoKSA+IDApIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VmVyaWZ5VXRmOFN0cmluZygKKyAgICAgIHRoaXMtPm5hbWUoKS5kYXRhKCksIHRoaXMtPm5hbWUoKS5sZW5ndGgoKSwKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTRVJJQUxJWkUsCisgICAgICAiZ29vZ2xlLnByb3RvYnVmLk9wdGlvbi5uYW1lIik7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nTWF5YmVBbGlhc2VkKAorICAgICAgMSwgdGhpcy0+bmFtZSgpLCBvdXRwdXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5BbnkgdmFsdWUgPSAyOworICBpZiAodGhpcy0+aGFzX3ZhbHVlKCkpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTWF5YmVUb0FycmF5KAorICAgICAgMiwgKnRoaXMtPnZhbHVlXywgb3V0cHV0KTsKKyAgfQorCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfZW5kOmdvb2dsZS5wcm90b2J1Zi5PcHRpb24pCit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIE9wdGlvbjo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiB0YXJnZXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9zdGFydDpnb29nbGUucHJvdG9idWYuT3B0aW9uKQorICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgIGlmICh0aGlzLT5uYW1lKCkuc2l6ZSgpID4gMCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpWZXJpZnlVdGY4U3RyaW5nKAorICAgICAgdGhpcy0+bmFtZSgpLmRhdGEoKSwgdGhpcy0+bmFtZSgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuT3B0aW9uLm5hbWUiKTsKKyAgICB0YXJnZXQgPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nVG9BcnJheSgKKyAgICAgICAgMSwgdGhpcy0+bmFtZSgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5BbnkgdmFsdWUgPSAyOworICBpZiAodGhpcy0+aGFzX3ZhbHVlKCkpIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6CisgICAgICBXcml0ZU1lc3NhZ2VOb1ZpcnR1YWxUb0FycmF5KAorICAgICAgICAyLCAqdGhpcy0+dmFsdWVfLCB0YXJnZXQpOworICB9CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9lbmQ6Z29vZ2xlLnByb3RvYnVmLk9wdGlvbikKKyAgcmV0dXJuIHRhcmdldDsKK30KKworaW50IE9wdGlvbjo6Qnl0ZVNpemUoKSBjb25zdCB7CisgIGludCB0b3RhbF9zaXplID0gMDsKKworICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgIGlmICh0aGlzLT5uYW1lKCkuc2l6ZSgpID4gMCkgeworICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U3RyaW5nU2l6ZSgKKyAgICAgICAgdGhpcy0+bmFtZSgpKTsKKyAgfQorCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuQW55IHZhbHVlID0gMjsKKyAgaWYgKHRoaXMtPmhhc192YWx1ZSgpKSB7CisgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpNZXNzYWdlU2l6ZU5vVmlydHVhbCgKKyAgICAgICAgKnRoaXMtPnZhbHVlXyk7CisgIH0KKworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gdG90YWxfc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7CisgIHJldHVybiB0b3RhbF9zaXplOworfQorCit2b2lkIE9wdGlvbjo6TWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBjb25zdCBPcHRpb24qIHNvdXJjZSA9IAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RHluYW1pY0Nhc3RUb0dlbmVyYXRlZDxjb25zdCBPcHRpb24+KAorICAgICAgICAgICZmcm9tKTsKKyAgaWYgKHNvdXJjZSA9PSBOVUxMKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6UmVmbGVjdGlvbk9wczo6TWVyZ2UoZnJvbSwgdGhpcyk7CisgIH0gZWxzZSB7CisgICAgTWVyZ2VGcm9tKCpzb3VyY2UpOworICB9Cit9CisKK3ZvaWQgT3B0aW9uOjpNZXJnZUZyb20oY29uc3QgT3B0aW9uJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGlmIChmcm9tLm5hbWUoKS5zaXplKCkgPiAwKSB7CisKKyAgICBuYW1lXy5Bc3NpZ25XaXRoRGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGZyb20ubmFtZV8pOworICB9CisgIGlmIChmcm9tLmhhc192YWx1ZSgpKSB7CisgICAgbXV0YWJsZV92YWx1ZSgpLT46Omdvb2dsZTo6cHJvdG9idWY6OkFueTo6TWVyZ2VGcm9tKGZyb20udmFsdWUoKSk7CisgIH0KK30KKwordm9pZCBPcHRpb246OkNvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK3ZvaWQgT3B0aW9uOjpDb3B5RnJvbShjb25zdCBPcHRpb24mIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCitib29sIE9wdGlvbjo6SXNJbml0aWFsaXplZCgpIGNvbnN0IHsKKworICByZXR1cm4gdHJ1ZTsKK30KKwordm9pZCBPcHRpb246OlN3YXAoT3B0aW9uKiBvdGhlcikgeworICBpZiAob3RoZXIgPT0gdGhpcykgcmV0dXJuOworICBJbnRlcm5hbFN3YXAob3RoZXIpOworfQordm9pZCBPcHRpb246OkludGVybmFsU3dhcChPcHRpb24qIG90aGVyKSB7CisgIG5hbWVfLlN3YXAoJm90aGVyLT5uYW1lXyk7CisgIHN0ZDo6c3dhcCh2YWx1ZV8sIG90aGVyLT52YWx1ZV8pOworICBfaW50ZXJuYWxfbWV0YWRhdGFfLlN3YXAoJm90aGVyLT5faW50ZXJuYWxfbWV0YWRhdGFfKTsKKyAgc3RkOjpzd2FwKF9jYWNoZWRfc2l6ZV8sIG90aGVyLT5fY2FjaGVkX3NpemVfKTsKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBPcHRpb246OkdldE1ldGFkYXRhKCkgY29uc3QgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBtZXRhZGF0YTsKKyAgbWV0YWRhdGEuZGVzY3JpcHRvciA9IE9wdGlvbl9kZXNjcmlwdG9yXzsKKyAgbWV0YWRhdGEucmVmbGVjdGlvbiA9IE9wdGlvbl9yZWZsZWN0aW9uXzsKKyAgcmV0dXJuIG1ldGFkYXRhOworfQorCisjaWYgUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisvLyBPcHRpb24KKworLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOwordm9pZCBPcHRpb246OmNsZWFyX25hbWUoKSB7CisgIG5hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyBjb25zdCA6OnN0ZDo6c3RyaW5nJiBPcHRpb246Om5hbWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLk9wdGlvbi5uYW1lKQorICByZXR1cm4gbmFtZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgT3B0aW9uOjpzZXRfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICAKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuT3B0aW9uLm5hbWUpCit9Cisgdm9pZCBPcHRpb246OnNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIAorICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLk9wdGlvbi5uYW1lKQorfQorIHZvaWQgT3B0aW9uOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgCisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5PcHRpb24ubmFtZSkKK30KKyA6OnN0ZDo6c3RyaW5nKiBPcHRpb246Om11dGFibGVfbmFtZSgpIHsKKyAgCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5PcHRpb24ubmFtZSkKKyAgcmV0dXJuIG5hbWVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CisgOjpzdGQ6OnN0cmluZyogT3B0aW9uOjpyZWxlYXNlX25hbWUoKSB7CisgIAorICByZXR1cm4gbmFtZV8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKyB2b2lkIE9wdGlvbjo6c2V0X2FsbG9jYXRlZF9uYW1lKDo6c3RkOjpzdHJpbmcqIG5hbWUpIHsKKyAgaWYgKG5hbWUgIT0gTlVMTCkgeworICAgIAorICB9IGVsc2UgeworICAgIAorICB9CisgIG5hbWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBuYW1lKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLk9wdGlvbi5uYW1lKQorfQorCisvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkFueSB2YWx1ZSA9IDI7Citib29sIE9wdGlvbjo6aGFzX3ZhbHVlKCkgY29uc3QgeworICByZXR1cm4gIV9pc19kZWZhdWx0X2luc3RhbmNlXyAmJiB2YWx1ZV8gIT0gTlVMTDsKK30KK3ZvaWQgT3B0aW9uOjpjbGVhcl92YWx1ZSgpIHsKKyAgaWYgKEdldEFyZW5hTm9WaXJ0dWFsKCkgPT0gTlVMTCAmJiB2YWx1ZV8gIT0gTlVMTCkgZGVsZXRlIHZhbHVlXzsKKyAgdmFsdWVfID0gTlVMTDsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6QW55JiBPcHRpb246OnZhbHVlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5PcHRpb24udmFsdWUpCisgIHJldHVybiB2YWx1ZV8gIT0gTlVMTCA/ICp2YWx1ZV8gOiAqZGVmYXVsdF9pbnN0YW5jZV8tPnZhbHVlXzsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6QW55KiBPcHRpb246Om11dGFibGVfdmFsdWUoKSB7CisgIAorICBpZiAodmFsdWVfID09IE5VTEwpIHsKKyAgICB2YWx1ZV8gPSBuZXcgOjpnb29nbGU6OnByb3RvYnVmOjpBbnk7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLk9wdGlvbi52YWx1ZSkKKyAgcmV0dXJuIHZhbHVlXzsKK30KKzo6Z29vZ2xlOjpwcm90b2J1Zjo6QW55KiBPcHRpb246OnJlbGVhc2VfdmFsdWUoKSB7CisgIAorICA6Omdvb2dsZTo6cHJvdG9idWY6OkFueSogdGVtcCA9IHZhbHVlXzsKKyAgdmFsdWVfID0gTlVMTDsKKyAgcmV0dXJuIHRlbXA7Cit9Cit2b2lkIE9wdGlvbjo6c2V0X2FsbG9jYXRlZF92YWx1ZSg6Omdvb2dsZTo6cHJvdG9idWY6OkFueSogdmFsdWUpIHsKKyAgZGVsZXRlIHZhbHVlXzsKKyAgdmFsdWVfID0gdmFsdWU7CisgIGlmICh2YWx1ZSkgeworICAgIAorICB9IGVsc2UgeworICAgIAorICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5PcHRpb24udmFsdWUpCit9CisKKyNlbmRpZiAgLy8gUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisKKy8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChuYW1lc3BhY2Vfc2NvcGUpCisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZ2xvYmFsX3Njb3BlKQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi90eXBlLnBiLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3R5cGUucGIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NmZlOGE2Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90eXBlLnBiLmgKQEAgLTAsMCArMSwxNjk2IEBACisvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQorLy8gc291cmNlOiBnb29nbGUvcHJvdG9idWYvdHlwZS5wcm90bworCisjaWZuZGVmIFBST1RPQlVGX2dvb2dsZV8yZnByb3RvYnVmXzJmdHlwZV8yZXByb3RvX19JTkNMVURFRAorI2RlZmluZSBQUk9UT0JVRl9nb29nbGVfMmZwcm90b2J1Zl8yZnR5cGVfMmVwcm90b19fSU5DTFVERUQKKworI2luY2x1ZGUgPHN0cmluZz4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKworI2lmIEdPT0dMRV9QUk9UT0JVRl9WRVJTSU9OIDwgMzAwMDAwMAorI2Vycm9yIFRoaXMgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IGEgbmV3ZXIgdmVyc2lvbiBvZiBwcm90b2Mgd2hpY2ggaXMKKyNlcnJvciBpbmNvbXBhdGlibGUgd2l0aCB5b3VyIFByb3RvY29sIEJ1ZmZlciBoZWFkZXJzLiAgUGxlYXNlIHVwZGF0ZQorI2Vycm9yIHlvdXIgaGVhZGVycy4KKyNlbmRpZgorI2lmIDMwMDAwMDAgPCBHT09HTEVfUFJPVE9CVUZfTUlOX1BST1RPQ19WRVJTSU9OCisjZXJyb3IgVGhpcyBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgYW4gb2xkZXIgdmVyc2lvbiBvZiBwcm90b2Mgd2hpY2ggaXMKKyNlcnJvciBpbmNvbXBhdGlibGUgd2l0aCB5b3VyIFByb3RvY29sIEJ1ZmZlciBoZWFkZXJzLiAgUGxlYXNlCisjZXJyb3IgcmVnZW5lcmF0ZSB0aGlzIGZpbGUgd2l0aCBhIG5ld2VyIHZlcnNpb24gb2YgcHJvdG9jLgorI2VuZGlmCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvYXJlbmEuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvYXJlbmFzdHJpbmcuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX21lc3NhZ2VfdXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tZXRhZGF0YS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tZXNzYWdlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3JlcGVhdGVkX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2V4dGVuc2lvbl9zZXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX2VudW1fcmVmbGVjdGlvbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bmtub3duX2ZpZWxkX3NldC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9hbnkucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc291cmNlX2NvbnRleHQucGIuaD4KKy8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbmNsdWRlcykKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCisvLyBJbnRlcm5hbCBpbXBsZW1lbnRhdGlvbiBkZXRhaWwgLS0gZG8gbm90IGNhbGwgdGhlc2UuCit2b2lkIExJQlBST1RPQlVGX0VYUE9SVCBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmdHlwZV8yZXByb3RvKCk7Cit2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZ0eXBlXzJlcHJvdG8oKTsKK3ZvaWQgcHJvdG9idWZfU2h1dGRvd25GaWxlX2dvb2dsZV8yZnByb3RvYnVmXzJmdHlwZV8yZXByb3RvKCk7CisKK2NsYXNzIEVudW07CitjbGFzcyBFbnVtVmFsdWU7CitjbGFzcyBGaWVsZDsKK2NsYXNzIE9wdGlvbjsKK2NsYXNzIFR5cGU7CisKK2VudW0gRmllbGRfS2luZCB7CisgIEZpZWxkX0tpbmRfVFlQRV9VTktOT1dOID0gMCwKKyAgRmllbGRfS2luZF9UWVBFX0RPVUJMRSA9IDEsCisgIEZpZWxkX0tpbmRfVFlQRV9GTE9BVCA9IDIsCisgIEZpZWxkX0tpbmRfVFlQRV9JTlQ2NCA9IDMsCisgIEZpZWxkX0tpbmRfVFlQRV9VSU5UNjQgPSA0LAorICBGaWVsZF9LaW5kX1RZUEVfSU5UMzIgPSA1LAorICBGaWVsZF9LaW5kX1RZUEVfRklYRUQ2NCA9IDYsCisgIEZpZWxkX0tpbmRfVFlQRV9GSVhFRDMyID0gNywKKyAgRmllbGRfS2luZF9UWVBFX0JPT0wgPSA4LAorICBGaWVsZF9LaW5kX1RZUEVfU1RSSU5HID0gOSwKKyAgRmllbGRfS2luZF9UWVBFX0dST1VQID0gMTAsCisgIEZpZWxkX0tpbmRfVFlQRV9NRVNTQUdFID0gMTEsCisgIEZpZWxkX0tpbmRfVFlQRV9CWVRFUyA9IDEyLAorICBGaWVsZF9LaW5kX1RZUEVfVUlOVDMyID0gMTMsCisgIEZpZWxkX0tpbmRfVFlQRV9FTlVNID0gMTQsCisgIEZpZWxkX0tpbmRfVFlQRV9TRklYRUQzMiA9IDE1LAorICBGaWVsZF9LaW5kX1RZUEVfU0ZJWEVENjQgPSAxNiwKKyAgRmllbGRfS2luZF9UWVBFX1NJTlQzMiA9IDE3LAorICBGaWVsZF9LaW5kX1RZUEVfU0lOVDY0ID0gMTgsCisgIEZpZWxkX0tpbmRfRmllbGRfS2luZF9JTlRfTUlOX1NFTlRJTkVMX0RPX05PVF9VU0VfID0gOjpnb29nbGU6OnByb3RvYnVmOjpraW50MzJtaW4sCisgIEZpZWxkX0tpbmRfRmllbGRfS2luZF9JTlRfTUFYX1NFTlRJTkVMX0RPX05PVF9VU0VfID0gOjpnb29nbGU6OnByb3RvYnVmOjpraW50MzJtYXgKK307CitMSUJQUk9UT0JVRl9FWFBPUlQgYm9vbCBGaWVsZF9LaW5kX0lzVmFsaWQoaW50IHZhbHVlKTsKK2NvbnN0IEZpZWxkX0tpbmQgRmllbGRfS2luZF9LaW5kX01JTiA9IEZpZWxkX0tpbmRfVFlQRV9VTktOT1dOOworY29uc3QgRmllbGRfS2luZCBGaWVsZF9LaW5kX0tpbmRfTUFYID0gRmllbGRfS2luZF9UWVBFX1NJTlQ2NDsKK2NvbnN0IGludCBGaWVsZF9LaW5kX0tpbmRfQVJSQVlTSVpFID0gRmllbGRfS2luZF9LaW5kX01BWCArIDE7CisKK0xJQlBST1RPQlVGX0VYUE9SVCBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yKiBGaWVsZF9LaW5kX2Rlc2NyaXB0b3IoKTsKK2lubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBGaWVsZF9LaW5kX05hbWUoRmllbGRfS2luZCB2YWx1ZSkgeworICByZXR1cm4gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6TmFtZU9mRW51bSgKKyAgICBGaWVsZF9LaW5kX2Rlc2NyaXB0b3IoKSwgdmFsdWUpOworfQoraW5saW5lIGJvb2wgRmllbGRfS2luZF9QYXJzZSgKKyAgICBjb25zdCA6OnN0ZDo6c3RyaW5nJiBuYW1lLCBGaWVsZF9LaW5kKiB2YWx1ZSkgeworICByZXR1cm4gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6UGFyc2VOYW1lZEVudW08RmllbGRfS2luZD4oCisgICAgRmllbGRfS2luZF9kZXNjcmlwdG9yKCksIG5hbWUsIHZhbHVlKTsKK30KK2VudW0gRmllbGRfQ2FyZGluYWxpdHkgeworICBGaWVsZF9DYXJkaW5hbGl0eV9DQVJESU5BTElUWV9VTktOT1dOID0gMCwKKyAgRmllbGRfQ2FyZGluYWxpdHlfQ0FSRElOQUxJVFlfT1BUSU9OQUwgPSAxLAorICBGaWVsZF9DYXJkaW5hbGl0eV9DQVJESU5BTElUWV9SRVFVSVJFRCA9IDIsCisgIEZpZWxkX0NhcmRpbmFsaXR5X0NBUkRJTkFMSVRZX1JFUEVBVEVEID0gMywKKyAgRmllbGRfQ2FyZGluYWxpdHlfRmllbGRfQ2FyZGluYWxpdHlfSU5UX01JTl9TRU5USU5FTF9ET19OT1RfVVNFXyA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6a2ludDMybWluLAorICBGaWVsZF9DYXJkaW5hbGl0eV9GaWVsZF9DYXJkaW5hbGl0eV9JTlRfTUFYX1NFTlRJTkVMX0RPX05PVF9VU0VfID0gOjpnb29nbGU6OnByb3RvYnVmOjpraW50MzJtYXgKK307CitMSUJQUk9UT0JVRl9FWFBPUlQgYm9vbCBGaWVsZF9DYXJkaW5hbGl0eV9Jc1ZhbGlkKGludCB2YWx1ZSk7Citjb25zdCBGaWVsZF9DYXJkaW5hbGl0eSBGaWVsZF9DYXJkaW5hbGl0eV9DYXJkaW5hbGl0eV9NSU4gPSBGaWVsZF9DYXJkaW5hbGl0eV9DQVJESU5BTElUWV9VTktOT1dOOworY29uc3QgRmllbGRfQ2FyZGluYWxpdHkgRmllbGRfQ2FyZGluYWxpdHlfQ2FyZGluYWxpdHlfTUFYID0gRmllbGRfQ2FyZGluYWxpdHlfQ0FSRElOQUxJVFlfUkVQRUFURUQ7Citjb25zdCBpbnQgRmllbGRfQ2FyZGluYWxpdHlfQ2FyZGluYWxpdHlfQVJSQVlTSVpFID0gRmllbGRfQ2FyZGluYWxpdHlfQ2FyZGluYWxpdHlfTUFYICsgMTsKKworTElCUFJPVE9CVUZfRVhQT1JUIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bURlc2NyaXB0b3IqIEZpZWxkX0NhcmRpbmFsaXR5X2Rlc2NyaXB0b3IoKTsKK2lubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBGaWVsZF9DYXJkaW5hbGl0eV9OYW1lKEZpZWxkX0NhcmRpbmFsaXR5IHZhbHVlKSB7CisgIHJldHVybiA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpOYW1lT2ZFbnVtKAorICAgIEZpZWxkX0NhcmRpbmFsaXR5X2Rlc2NyaXB0b3IoKSwgdmFsdWUpOworfQoraW5saW5lIGJvb2wgRmllbGRfQ2FyZGluYWxpdHlfUGFyc2UoCisgICAgY29uc3QgOjpzdGQ6OnN0cmluZyYgbmFtZSwgRmllbGRfQ2FyZGluYWxpdHkqIHZhbHVlKSB7CisgIHJldHVybiA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpQYXJzZU5hbWVkRW51bTxGaWVsZF9DYXJkaW5hbGl0eT4oCisgICAgRmllbGRfQ2FyZGluYWxpdHlfZGVzY3JpcHRvcigpLCBuYW1lLCB2YWx1ZSk7Cit9CitlbnVtIFN5bnRheCB7CisgIFNZTlRBWF9QUk9UTzIgPSAwLAorICBTWU5UQVhfUFJPVE8zID0gMSwKKyAgU3ludGF4X0lOVF9NSU5fU0VOVElORUxfRE9fTk9UX1VTRV8gPSA6Omdvb2dsZTo6cHJvdG9idWY6OmtpbnQzMm1pbiwKKyAgU3ludGF4X0lOVF9NQVhfU0VOVElORUxfRE9fTk9UX1VTRV8gPSA6Omdvb2dsZTo6cHJvdG9idWY6OmtpbnQzMm1heAorfTsKK0xJQlBST1RPQlVGX0VYUE9SVCBib29sIFN5bnRheF9Jc1ZhbGlkKGludCB2YWx1ZSk7Citjb25zdCBTeW50YXggU3ludGF4X01JTiA9IFNZTlRBWF9QUk9UTzI7Citjb25zdCBTeW50YXggU3ludGF4X01BWCA9IFNZTlRBWF9QUk9UTzM7Citjb25zdCBpbnQgU3ludGF4X0FSUkFZU0laRSA9IFN5bnRheF9NQVggKyAxOworCitMSUJQUk9UT0JVRl9FWFBPUlQgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvciogU3ludGF4X2Rlc2NyaXB0b3IoKTsKK2lubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBTeW50YXhfTmFtZShTeW50YXggdmFsdWUpIHsKKyAgcmV0dXJuIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6Ok5hbWVPZkVudW0oCisgICAgU3ludGF4X2Rlc2NyaXB0b3IoKSwgdmFsdWUpOworfQoraW5saW5lIGJvb2wgU3ludGF4X1BhcnNlKAorICAgIGNvbnN0IDo6c3RkOjpzdHJpbmcmIG5hbWUsIFN5bnRheCogdmFsdWUpIHsKKyAgcmV0dXJuIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlBhcnNlTmFtZWRFbnVtPFN5bnRheD4oCisgICAgU3ludGF4X2Rlc2NyaXB0b3IoKSwgbmFtZSwgdmFsdWUpOworfQorLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgVHlwZSA6IHB1YmxpYyA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UgeworIHB1YmxpYzoKKyAgVHlwZSgpOworICB2aXJ0dWFsIH5UeXBlKCk7CisKKyAgVHlwZShjb25zdCBUeXBlJiBmcm9tKTsKKworICBpbmxpbmUgVHlwZSYgb3BlcmF0b3I9KGNvbnN0IFR5cGUmIGZyb20pIHsKKyAgICBDb3B5RnJvbShmcm9tKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworICBzdGF0aWMgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKCk7CisgIHN0YXRpYyBjb25zdCBUeXBlJiBkZWZhdWx0X2luc3RhbmNlKCk7CisKKyAgdm9pZCBTd2FwKFR5cGUqIG90aGVyKTsKKworICAvLyBpbXBsZW1lbnRzIE1lc3NhZ2UgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIGlubGluZSBUeXBlKiBOZXcoKSBjb25zdCB7IHJldHVybiBOZXcoTlVMTCk7IH0KKworICBUeXBlKiBOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0OworICB2b2lkIENvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgQ29weUZyb20oY29uc3QgVHlwZSYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IFR5cGUmIGZyb20pOworICB2b2lkIENsZWFyKCk7CisgIGJvb2wgSXNJbml0aWFsaXplZCgpIGNvbnN0OworCisgIGludCBCeXRlU2l6ZSgpIGNvbnN0OworICBib29sIE1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KTsKKyAgdm9pZCBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSg6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBvdXRwdXQpIGNvbnN0OworICBpbnQgR2V0Q2FjaGVkU2l6ZSgpIGNvbnN0IHsgcmV0dXJuIF9jYWNoZWRfc2l6ZV87IH0KKyAgcHJpdmF0ZToKKyAgdm9pZCBTaGFyZWRDdG9yKCk7CisgIHZvaWQgU2hhcmVkRHRvcigpOworICB2b2lkIFNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0OworICB2b2lkIEludGVybmFsU3dhcChUeXBlKiBvdGhlcik7CisgIHByaXZhdGU6CisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYU5vVmlydHVhbCgpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5hcmVuYSgpOworICB9CisgIGlubGluZSB2b2lkKiBNYXliZUFyZW5hUHRyKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnJhd19hcmVuYV9wdHIoKTsKKyAgfQorICBwdWJsaWM6CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBHZXRNZXRhZGF0YSgpIGNvbnN0OworCisgIC8vIG5lc3RlZCB0eXBlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gYWNjZXNzb3JzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgIHZvaWQgY2xlYXJfbmFtZSgpOworICBzdGF0aWMgY29uc3QgaW50IGtOYW1lRmllbGROdW1iZXIgPSAxOworICBjb25zdCA6OnN0ZDo6c3RyaW5nJiBuYW1lKCkgY29uc3Q7CisgIHZvaWQgc2V0X25hbWUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpOworICB2b2lkIHNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlKTsKKyAgdm9pZCBzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpOworICA6OnN0ZDo6c3RyaW5nKiBtdXRhYmxlX25hbWUoKTsKKyAgOjpzdGQ6OnN0cmluZyogcmVsZWFzZV9uYW1lKCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF9uYW1lKDo6c3RkOjpzdHJpbmcqIG5hbWUpOworCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmllbGQgZmllbGRzID0gMjsKKyAgaW50IGZpZWxkc19zaXplKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfZmllbGRzKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga0ZpZWxkc0ZpZWxkTnVtYmVyID0gMjsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZCYgZmllbGRzKGludCBpbmRleCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGQqIG11dGFibGVfZmllbGRzKGludCBpbmRleCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGQqIGFkZF9maWVsZHMoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkID4qCisgICAgICBtdXRhYmxlX2ZpZWxkcygpOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGQgPiYKKyAgICAgIGZpZWxkcygpIGNvbnN0OworCisgIC8vIHJlcGVhdGVkIHN0cmluZyBvbmVvZnMgPSAzOworICBpbnQgb25lb2ZzX3NpemUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9vbmVvZnMoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrT25lb2ZzRmllbGROdW1iZXIgPSAzOworICBjb25zdCA6OnN0ZDo6c3RyaW5nJiBvbmVvZnMoaW50IGluZGV4KSBjb25zdDsKKyAgOjpzdGQ6OnN0cmluZyogbXV0YWJsZV9vbmVvZnMoaW50IGluZGV4KTsKKyAgdm9pZCBzZXRfb25lb2ZzKGludCBpbmRleCwgY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpOworICB2b2lkIHNldF9vbmVvZnMoaW50IGluZGV4LCBjb25zdCBjaGFyKiB2YWx1ZSk7CisgIHZvaWQgc2V0X29uZW9mcyhpbnQgaW5kZXgsIGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIDo6c3RkOjpzdHJpbmcqIGFkZF9vbmVvZnMoKTsKKyAgdm9pZCBhZGRfb25lb2ZzKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKTsKKyAgdm9pZCBhZGRfb25lb2ZzKGNvbnN0IGNoYXIqIHZhbHVlKTsKKyAgdm9pZCBhZGRfb25lb2ZzKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpzdGQ6OnN0cmluZz4mIG9uZW9mcygpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6c3RkOjpzdHJpbmc+KiBtdXRhYmxlX29uZW9mcygpOworCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuT3B0aW9uIG9wdGlvbnMgPSA0OworICBpbnQgb3B0aW9uc19zaXplKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfb3B0aW9ucygpOworICBzdGF0aWMgY29uc3QgaW50IGtPcHRpb25zRmllbGROdW1iZXIgPSA0OworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbiYgb3B0aW9ucyhpbnQgaW5kZXgpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbiogbXV0YWJsZV9vcHRpb25zKGludCBpbmRleCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6T3B0aW9uKiBhZGRfb3B0aW9ucygpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6T3B0aW9uID4qCisgICAgICBtdXRhYmxlX29wdGlvbnMoKTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbiA+JgorICAgICAgb3B0aW9ucygpIGNvbnN0OworCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCBzb3VyY2VfY29udGV4dCA9IDU7CisgIGJvb2wgaGFzX3NvdXJjZV9jb250ZXh0KCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfc291cmNlX2NvbnRleHQoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrU291cmNlQ29udGV4dEZpZWxkTnVtYmVyID0gNTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb250ZXh0JiBzb3VyY2VfY29udGV4dCgpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvbnRleHQqIG11dGFibGVfc291cmNlX2NvbnRleHQoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb250ZXh0KiByZWxlYXNlX3NvdXJjZV9jb250ZXh0KCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF9zb3VyY2VfY29udGV4dCg6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvbnRleHQqIHNvdXJjZV9jb250ZXh0KTsKKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLlN5bnRheCBzeW50YXggPSA2OworICB2b2lkIGNsZWFyX3N5bnRheCgpOworICBzdGF0aWMgY29uc3QgaW50IGtTeW50YXhGaWVsZE51bWJlciA9IDY7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6U3ludGF4IHN5bnRheCgpIGNvbnN0OworICB2b2lkIHNldF9zeW50YXgoOjpnb29nbGU6OnByb3RvYnVmOjpTeW50YXggdmFsdWUpOworCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpnb29nbGUucHJvdG9idWYuVHlwZSkKKyBwcml2YXRlOgorCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEgX2ludGVybmFsX21ldGFkYXRhXzsKKyAgYm9vbCBfaXNfZGVmYXVsdF9pbnN0YW5jZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFyZW5hU3RyaW5nUHRyIG5hbWVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGQgPiBmaWVsZHNfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6c3RkOjpzdHJpbmc+IG9uZW9mc187CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpPcHRpb24gPiBvcHRpb25zXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb250ZXh0KiBzb3VyY2VfY29udGV4dF87CisgIGludCBzeW50YXhfOworICBtdXRhYmxlIGludCBfY2FjaGVkX3NpemVfOworICBmcmllbmQgdm9pZCBMSUJQUk9UT0JVRl9FWFBPUlQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZnR5cGVfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmdHlwZV8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZnR5cGVfMmVwcm90bygpOworCisgIHZvaWQgSW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIHN0YXRpYyBUeXBlKiBkZWZhdWx0X2luc3RhbmNlXzsKK307CisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBGaWVsZCA6IHB1YmxpYyA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UgeworIHB1YmxpYzoKKyAgRmllbGQoKTsKKyAgdmlydHVhbCB+RmllbGQoKTsKKworICBGaWVsZChjb25zdCBGaWVsZCYgZnJvbSk7CisKKyAgaW5saW5lIEZpZWxkJiBvcGVyYXRvcj0oY29uc3QgRmllbGQmIGZyb20pIHsKKyAgICBDb3B5RnJvbShmcm9tKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworICBzdGF0aWMgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKCk7CisgIHN0YXRpYyBjb25zdCBGaWVsZCYgZGVmYXVsdF9pbnN0YW5jZSgpOworCisgIHZvaWQgU3dhcChGaWVsZCogb3RoZXIpOworCisgIC8vIGltcGxlbWVudHMgTWVzc2FnZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgaW5saW5lIEZpZWxkKiBOZXcoKSBjb25zdCB7IHJldHVybiBOZXcoTlVMTCk7IH0KKworICBGaWVsZCogTmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdDsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIENvcHlGcm9tKGNvbnN0IEZpZWxkJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgRmllbGQmIGZyb20pOworICB2b2lkIENsZWFyKCk7CisgIGJvb2wgSXNJbml0aWFsaXplZCgpIGNvbnN0OworCisgIGludCBCeXRlU2l6ZSgpIGNvbnN0OworICBib29sIE1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KTsKKyAgdm9pZCBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSg6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBvdXRwdXQpIGNvbnN0OworICBpbnQgR2V0Q2FjaGVkU2l6ZSgpIGNvbnN0IHsgcmV0dXJuIF9jYWNoZWRfc2l6ZV87IH0KKyAgcHJpdmF0ZToKKyAgdm9pZCBTaGFyZWRDdG9yKCk7CisgIHZvaWQgU2hhcmVkRHRvcigpOworICB2b2lkIFNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0OworICB2b2lkIEludGVybmFsU3dhcChGaWVsZCogb3RoZXIpOworICBwcml2YXRlOgorICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogR2V0QXJlbmFOb1ZpcnR1YWwoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8uYXJlbmEoKTsKKyAgfQorICBpbmxpbmUgdm9pZCogTWF5YmVBcmVuYVB0cigpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5yYXdfYXJlbmFfcHRyKCk7CisgIH0KKyAgcHVibGljOgorCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgR2V0TWV0YWRhdGEoKSBjb25zdDsKKworICAvLyBuZXN0ZWQgdHlwZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIHR5cGVkZWYgRmllbGRfS2luZCBLaW5kOworICBzdGF0aWMgY29uc3QgS2luZCBUWVBFX1VOS05PV04gPSBGaWVsZF9LaW5kX1RZUEVfVU5LTk9XTjsKKyAgc3RhdGljIGNvbnN0IEtpbmQgVFlQRV9ET1VCTEUgPSBGaWVsZF9LaW5kX1RZUEVfRE9VQkxFOworICBzdGF0aWMgY29uc3QgS2luZCBUWVBFX0ZMT0FUID0gRmllbGRfS2luZF9UWVBFX0ZMT0FUOworICBzdGF0aWMgY29uc3QgS2luZCBUWVBFX0lOVDY0ID0gRmllbGRfS2luZF9UWVBFX0lOVDY0OworICBzdGF0aWMgY29uc3QgS2luZCBUWVBFX1VJTlQ2NCA9IEZpZWxkX0tpbmRfVFlQRV9VSU5UNjQ7CisgIHN0YXRpYyBjb25zdCBLaW5kIFRZUEVfSU5UMzIgPSBGaWVsZF9LaW5kX1RZUEVfSU5UMzI7CisgIHN0YXRpYyBjb25zdCBLaW5kIFRZUEVfRklYRUQ2NCA9IEZpZWxkX0tpbmRfVFlQRV9GSVhFRDY0OworICBzdGF0aWMgY29uc3QgS2luZCBUWVBFX0ZJWEVEMzIgPSBGaWVsZF9LaW5kX1RZUEVfRklYRUQzMjsKKyAgc3RhdGljIGNvbnN0IEtpbmQgVFlQRV9CT09MID0gRmllbGRfS2luZF9UWVBFX0JPT0w7CisgIHN0YXRpYyBjb25zdCBLaW5kIFRZUEVfU1RSSU5HID0gRmllbGRfS2luZF9UWVBFX1NUUklORzsKKyAgc3RhdGljIGNvbnN0IEtpbmQgVFlQRV9HUk9VUCA9IEZpZWxkX0tpbmRfVFlQRV9HUk9VUDsKKyAgc3RhdGljIGNvbnN0IEtpbmQgVFlQRV9NRVNTQUdFID0gRmllbGRfS2luZF9UWVBFX01FU1NBR0U7CisgIHN0YXRpYyBjb25zdCBLaW5kIFRZUEVfQllURVMgPSBGaWVsZF9LaW5kX1RZUEVfQllURVM7CisgIHN0YXRpYyBjb25zdCBLaW5kIFRZUEVfVUlOVDMyID0gRmllbGRfS2luZF9UWVBFX1VJTlQzMjsKKyAgc3RhdGljIGNvbnN0IEtpbmQgVFlQRV9FTlVNID0gRmllbGRfS2luZF9UWVBFX0VOVU07CisgIHN0YXRpYyBjb25zdCBLaW5kIFRZUEVfU0ZJWEVEMzIgPSBGaWVsZF9LaW5kX1RZUEVfU0ZJWEVEMzI7CisgIHN0YXRpYyBjb25zdCBLaW5kIFRZUEVfU0ZJWEVENjQgPSBGaWVsZF9LaW5kX1RZUEVfU0ZJWEVENjQ7CisgIHN0YXRpYyBjb25zdCBLaW5kIFRZUEVfU0lOVDMyID0gRmllbGRfS2luZF9UWVBFX1NJTlQzMjsKKyAgc3RhdGljIGNvbnN0IEtpbmQgVFlQRV9TSU5UNjQgPSBGaWVsZF9LaW5kX1RZUEVfU0lOVDY0OworICBzdGF0aWMgaW5saW5lIGJvb2wgS2luZF9Jc1ZhbGlkKGludCB2YWx1ZSkgeworICAgIHJldHVybiBGaWVsZF9LaW5kX0lzVmFsaWQodmFsdWUpOworICB9CisgIHN0YXRpYyBjb25zdCBLaW5kIEtpbmRfTUlOID0KKyAgICBGaWVsZF9LaW5kX0tpbmRfTUlOOworICBzdGF0aWMgY29uc3QgS2luZCBLaW5kX01BWCA9CisgICAgRmllbGRfS2luZF9LaW5kX01BWDsKKyAgc3RhdGljIGNvbnN0IGludCBLaW5kX0FSUkFZU0laRSA9CisgICAgRmllbGRfS2luZF9LaW5kX0FSUkFZU0laRTsKKyAgc3RhdGljIGlubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yKgorICBLaW5kX2Rlc2NyaXB0b3IoKSB7CisgICAgcmV0dXJuIEZpZWxkX0tpbmRfZGVzY3JpcHRvcigpOworICB9CisgIHN0YXRpYyBpbmxpbmUgY29uc3QgOjpzdGQ6OnN0cmluZyYgS2luZF9OYW1lKEtpbmQgdmFsdWUpIHsKKyAgICByZXR1cm4gRmllbGRfS2luZF9OYW1lKHZhbHVlKTsKKyAgfQorICBzdGF0aWMgaW5saW5lIGJvb2wgS2luZF9QYXJzZShjb25zdCA6OnN0ZDo6c3RyaW5nJiBuYW1lLAorICAgICAgS2luZCogdmFsdWUpIHsKKyAgICByZXR1cm4gRmllbGRfS2luZF9QYXJzZShuYW1lLCB2YWx1ZSk7CisgIH0KKworICB0eXBlZGVmIEZpZWxkX0NhcmRpbmFsaXR5IENhcmRpbmFsaXR5OworICBzdGF0aWMgY29uc3QgQ2FyZGluYWxpdHkgQ0FSRElOQUxJVFlfVU5LTk9XTiA9IEZpZWxkX0NhcmRpbmFsaXR5X0NBUkRJTkFMSVRZX1VOS05PV047CisgIHN0YXRpYyBjb25zdCBDYXJkaW5hbGl0eSBDQVJESU5BTElUWV9PUFRJT05BTCA9IEZpZWxkX0NhcmRpbmFsaXR5X0NBUkRJTkFMSVRZX09QVElPTkFMOworICBzdGF0aWMgY29uc3QgQ2FyZGluYWxpdHkgQ0FSRElOQUxJVFlfUkVRVUlSRUQgPSBGaWVsZF9DYXJkaW5hbGl0eV9DQVJESU5BTElUWV9SRVFVSVJFRDsKKyAgc3RhdGljIGNvbnN0IENhcmRpbmFsaXR5IENBUkRJTkFMSVRZX1JFUEVBVEVEID0gRmllbGRfQ2FyZGluYWxpdHlfQ0FSRElOQUxJVFlfUkVQRUFURUQ7CisgIHN0YXRpYyBpbmxpbmUgYm9vbCBDYXJkaW5hbGl0eV9Jc1ZhbGlkKGludCB2YWx1ZSkgeworICAgIHJldHVybiBGaWVsZF9DYXJkaW5hbGl0eV9Jc1ZhbGlkKHZhbHVlKTsKKyAgfQorICBzdGF0aWMgY29uc3QgQ2FyZGluYWxpdHkgQ2FyZGluYWxpdHlfTUlOID0KKyAgICBGaWVsZF9DYXJkaW5hbGl0eV9DYXJkaW5hbGl0eV9NSU47CisgIHN0YXRpYyBjb25zdCBDYXJkaW5hbGl0eSBDYXJkaW5hbGl0eV9NQVggPQorICAgIEZpZWxkX0NhcmRpbmFsaXR5X0NhcmRpbmFsaXR5X01BWDsKKyAgc3RhdGljIGNvbnN0IGludCBDYXJkaW5hbGl0eV9BUlJBWVNJWkUgPQorICAgIEZpZWxkX0NhcmRpbmFsaXR5X0NhcmRpbmFsaXR5X0FSUkFZU0laRTsKKyAgc3RhdGljIGlubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1EZXNjcmlwdG9yKgorICBDYXJkaW5hbGl0eV9kZXNjcmlwdG9yKCkgeworICAgIHJldHVybiBGaWVsZF9DYXJkaW5hbGl0eV9kZXNjcmlwdG9yKCk7CisgIH0KKyAgc3RhdGljIGlubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBDYXJkaW5hbGl0eV9OYW1lKENhcmRpbmFsaXR5IHZhbHVlKSB7CisgICAgcmV0dXJuIEZpZWxkX0NhcmRpbmFsaXR5X05hbWUodmFsdWUpOworICB9CisgIHN0YXRpYyBpbmxpbmUgYm9vbCBDYXJkaW5hbGl0eV9QYXJzZShjb25zdCA6OnN0ZDo6c3RyaW5nJiBuYW1lLAorICAgICAgQ2FyZGluYWxpdHkqIHZhbHVlKSB7CisgICAgcmV0dXJuIEZpZWxkX0NhcmRpbmFsaXR5X1BhcnNlKG5hbWUsIHZhbHVlKTsKKyAgfQorCisgIC8vIGFjY2Vzc29ycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZC5LaW5kIGtpbmQgPSAxOworICB2b2lkIGNsZWFyX2tpbmQoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrS2luZEZpZWxkTnVtYmVyID0gMTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZF9LaW5kIGtpbmQoKSBjb25zdDsKKyAgdm9pZCBzZXRfa2luZCg6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0tpbmQgdmFsdWUpOworCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmllbGQuQ2FyZGluYWxpdHkgY2FyZGluYWxpdHkgPSAyOworICB2b2lkIGNsZWFyX2NhcmRpbmFsaXR5KCk7CisgIHN0YXRpYyBjb25zdCBpbnQga0NhcmRpbmFsaXR5RmllbGROdW1iZXIgPSAyOworICA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0NhcmRpbmFsaXR5IGNhcmRpbmFsaXR5KCkgY29uc3Q7CisgIHZvaWQgc2V0X2NhcmRpbmFsaXR5KDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGRfQ2FyZGluYWxpdHkgdmFsdWUpOworCisgIC8vIG9wdGlvbmFsIGludDMyIG51bWJlciA9IDM7CisgIHZvaWQgY2xlYXJfbnVtYmVyKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga051bWJlckZpZWxkTnVtYmVyID0gMzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiBudW1iZXIoKSBjb25zdDsKKyAgdm9pZCBzZXRfbnVtYmVyKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgdmFsdWUpOworCisgIC8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gNDsKKyAgdm9pZCBjbGVhcl9uYW1lKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga05hbWVGaWVsZE51bWJlciA9IDQ7CisgIGNvbnN0IDo6c3RkOjpzdHJpbmcmIG5hbWUoKSBjb25zdDsKKyAgdm9pZCBzZXRfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUpOworICB2b2lkIHNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIDo6c3RkOjpzdHJpbmcqIG11dGFibGVfbmFtZSgpOworICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlX25hbWUoKTsKKyAgdm9pZCBzZXRfYWxsb2NhdGVkX25hbWUoOjpzdGQ6OnN0cmluZyogbmFtZSk7CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIHR5cGVfdXJsID0gNjsKKyAgdm9pZCBjbGVhcl90eXBlX3VybCgpOworICBzdGF0aWMgY29uc3QgaW50IGtUeXBlVXJsRmllbGROdW1iZXIgPSA2OworICBjb25zdCA6OnN0ZDo6c3RyaW5nJiB0eXBlX3VybCgpIGNvbnN0OworICB2b2lkIHNldF90eXBlX3VybChjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X3R5cGVfdXJsKGNvbnN0IGNoYXIqIHZhbHVlKTsKKyAgdm9pZCBzZXRfdHlwZV91cmwoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKTsKKyAgOjpzdGQ6OnN0cmluZyogbXV0YWJsZV90eXBlX3VybCgpOworICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlX3R5cGVfdXJsKCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF90eXBlX3VybCg6OnN0ZDo6c3RyaW5nKiB0eXBlX3VybCk7CisKKyAgLy8gb3B0aW9uYWwgaW50MzIgb25lb2ZfaW5kZXggPSA3OworICB2b2lkIGNsZWFyX29uZW9mX2luZGV4KCk7CisgIHN0YXRpYyBjb25zdCBpbnQga09uZW9mSW5kZXhGaWVsZE51bWJlciA9IDc7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgb25lb2ZfaW5kZXgoKSBjb25zdDsKKyAgdm9pZCBzZXRfb25lb2ZfaW5kZXgoOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiB2YWx1ZSk7CisKKyAgLy8gb3B0aW9uYWwgYm9vbCBwYWNrZWQgPSA4OworICB2b2lkIGNsZWFyX3BhY2tlZCgpOworICBzdGF0aWMgY29uc3QgaW50IGtQYWNrZWRGaWVsZE51bWJlciA9IDg7CisgIGJvb2wgcGFja2VkKCkgY29uc3Q7CisgIHZvaWQgc2V0X3BhY2tlZChib29sIHZhbHVlKTsKKworICAvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLk9wdGlvbiBvcHRpb25zID0gOTsKKyAgaW50IG9wdGlvbnNfc2l6ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX29wdGlvbnMoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrT3B0aW9uc0ZpZWxkTnVtYmVyID0gOTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpPcHRpb24mIG9wdGlvbnMoaW50IGluZGV4KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpPcHRpb24qIG11dGFibGVfb3B0aW9ucyhpbnQgaW5kZXgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbiogYWRkX29wdGlvbnMoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbiA+KgorICAgICAgbXV0YWJsZV9vcHRpb25zKCk7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpPcHRpb24gPiYKKyAgICAgIG9wdGlvbnMoKSBjb25zdDsKKworICAvLyBvcHRpb25hbCBzdHJpbmcganNvbl9uYW1lID0gMTA7CisgIHZvaWQgY2xlYXJfanNvbl9uYW1lKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga0pzb25OYW1lRmllbGROdW1iZXIgPSAxMDsKKyAgY29uc3QgOjpzdGQ6OnN0cmluZyYganNvbl9uYW1lKCkgY29uc3Q7CisgIHZvaWQgc2V0X2pzb25fbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X2pzb25fbmFtZShjb25zdCBjaGFyKiB2YWx1ZSk7CisgIHZvaWQgc2V0X2pzb25fbmFtZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpOworICA6OnN0ZDo6c3RyaW5nKiBtdXRhYmxlX2pzb25fbmFtZSgpOworICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlX2pzb25fbmFtZSgpOworICB2b2lkIHNldF9hbGxvY2F0ZWRfanNvbl9uYW1lKDo6c3RkOjpzdHJpbmcqIGpzb25fbmFtZSk7CisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIGRlZmF1bHRfdmFsdWUgPSAxMTsKKyAgdm9pZCBjbGVhcl9kZWZhdWx0X3ZhbHVlKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga0RlZmF1bHRWYWx1ZUZpZWxkTnVtYmVyID0gMTE7CisgIGNvbnN0IDo6c3RkOjpzdHJpbmcmIGRlZmF1bHRfdmFsdWUoKSBjb25zdDsKKyAgdm9pZCBzZXRfZGVmYXVsdF92YWx1ZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X2RlZmF1bHRfdmFsdWUoY29uc3QgY2hhciogdmFsdWUpOworICB2b2lkIHNldF9kZWZhdWx0X3ZhbHVlKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIDo6c3RkOjpzdHJpbmcqIG11dGFibGVfZGVmYXVsdF92YWx1ZSgpOworICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlX2RlZmF1bHRfdmFsdWUoKTsKKyAgdm9pZCBzZXRfYWxsb2NhdGVkX2RlZmF1bHRfdmFsdWUoOjpzdGQ6OnN0cmluZyogZGVmYXVsdF92YWx1ZSk7CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmdvb2dsZS5wcm90b2J1Zi5GaWVsZCkKKyBwcml2YXRlOgorCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEgX2ludGVybmFsX21ldGFkYXRhXzsKKyAgYm9vbCBfaXNfZGVmYXVsdF9pbnN0YW5jZV87CisgIGludCBraW5kXzsKKyAgaW50IGNhcmRpbmFsaXR5XzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6QXJlbmFTdHJpbmdQdHIgbmFtZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgbnVtYmVyXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiBvbmVvZl9pbmRleF87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFyZW5hU3RyaW5nUHRyIHR5cGVfdXJsXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbiA+IG9wdGlvbnNfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBcmVuYVN0cmluZ1B0ciBqc29uX25hbWVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBcmVuYVN0cmluZ1B0ciBkZWZhdWx0X3ZhbHVlXzsKKyAgYm9vbCBwYWNrZWRfOworICBtdXRhYmxlIGludCBfY2FjaGVkX3NpemVfOworICBmcmllbmQgdm9pZCBMSUJQUk9UT0JVRl9FWFBPUlQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZnR5cGVfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmdHlwZV8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZnR5cGVfMmVwcm90bygpOworCisgIHZvaWQgSW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIHN0YXRpYyBGaWVsZCogZGVmYXVsdF9pbnN0YW5jZV87Cit9OworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgRW51bSA6IHB1YmxpYyA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UgeworIHB1YmxpYzoKKyAgRW51bSgpOworICB2aXJ0dWFsIH5FbnVtKCk7CisKKyAgRW51bShjb25zdCBFbnVtJiBmcm9tKTsKKworICBpbmxpbmUgRW51bSYgb3BlcmF0b3I9KGNvbnN0IEVudW0mIGZyb20pIHsKKyAgICBDb3B5RnJvbShmcm9tKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworICBzdGF0aWMgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKCk7CisgIHN0YXRpYyBjb25zdCBFbnVtJiBkZWZhdWx0X2luc3RhbmNlKCk7CisKKyAgdm9pZCBTd2FwKEVudW0qIG90aGVyKTsKKworICAvLyBpbXBsZW1lbnRzIE1lc3NhZ2UgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIGlubGluZSBFbnVtKiBOZXcoKSBjb25zdCB7IHJldHVybiBOZXcoTlVMTCk7IH0KKworICBFbnVtKiBOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0OworICB2b2lkIENvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgQ29weUZyb20oY29uc3QgRW51bSYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IEVudW0mIGZyb20pOworICB2b2lkIENsZWFyKCk7CisgIGJvb2wgSXNJbml0aWFsaXplZCgpIGNvbnN0OworCisgIGludCBCeXRlU2l6ZSgpIGNvbnN0OworICBib29sIE1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KTsKKyAgdm9pZCBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSg6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBvdXRwdXQpIGNvbnN0OworICBpbnQgR2V0Q2FjaGVkU2l6ZSgpIGNvbnN0IHsgcmV0dXJuIF9jYWNoZWRfc2l6ZV87IH0KKyAgcHJpdmF0ZToKKyAgdm9pZCBTaGFyZWRDdG9yKCk7CisgIHZvaWQgU2hhcmVkRHRvcigpOworICB2b2lkIFNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0OworICB2b2lkIEludGVybmFsU3dhcChFbnVtKiBvdGhlcik7CisgIHByaXZhdGU6CisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYU5vVmlydHVhbCgpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5hcmVuYSgpOworICB9CisgIGlubGluZSB2b2lkKiBNYXliZUFyZW5hUHRyKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnJhd19hcmVuYV9wdHIoKTsKKyAgfQorICBwdWJsaWM6CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBHZXRNZXRhZGF0YSgpIGNvbnN0OworCisgIC8vIG5lc3RlZCB0eXBlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gYWNjZXNzb3JzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisgIHZvaWQgY2xlYXJfbmFtZSgpOworICBzdGF0aWMgY29uc3QgaW50IGtOYW1lRmllbGROdW1iZXIgPSAxOworICBjb25zdCA6OnN0ZDo6c3RyaW5nJiBuYW1lKCkgY29uc3Q7CisgIHZvaWQgc2V0X25hbWUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpOworICB2b2lkIHNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlKTsKKyAgdm9pZCBzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpOworICA6OnN0ZDo6c3RyaW5nKiBtdXRhYmxlX25hbWUoKTsKKyAgOjpzdGQ6OnN0cmluZyogcmVsZWFzZV9uYW1lKCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF9uYW1lKDo6c3RkOjpzdHJpbmcqIG5hbWUpOworCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRW51bVZhbHVlIGVudW12YWx1ZSA9IDI7CisgIGludCBlbnVtdmFsdWVfc2l6ZSgpIGNvbnN0OworICB2b2lkIGNsZWFyX2VudW12YWx1ZSgpOworICBzdGF0aWMgY29uc3QgaW50IGtFbnVtdmFsdWVGaWVsZE51bWJlciA9IDI7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlJiBlbnVtdmFsdWUoaW50IGluZGV4KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtVmFsdWUqIG11dGFibGVfZW51bXZhbHVlKGludCBpbmRleCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlKiBhZGRfZW51bXZhbHVlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtVmFsdWUgPioKKyAgICAgIG11dGFibGVfZW51bXZhbHVlKCk7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtVmFsdWUgPiYKKyAgICAgIGVudW12YWx1ZSgpIGNvbnN0OworCisgIC8vIHJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuT3B0aW9uIG9wdGlvbnMgPSAzOworICBpbnQgb3B0aW9uc19zaXplKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfb3B0aW9ucygpOworICBzdGF0aWMgY29uc3QgaW50IGtPcHRpb25zRmllbGROdW1iZXIgPSAzOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbiYgb3B0aW9ucyhpbnQgaW5kZXgpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbiogbXV0YWJsZV9vcHRpb25zKGludCBpbmRleCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6T3B0aW9uKiBhZGRfb3B0aW9ucygpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6T3B0aW9uID4qCisgICAgICBtdXRhYmxlX29wdGlvbnMoKTsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbiA+JgorICAgICAgb3B0aW9ucygpIGNvbnN0OworCisgIC8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCBzb3VyY2VfY29udGV4dCA9IDQ7CisgIGJvb2wgaGFzX3NvdXJjZV9jb250ZXh0KCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfc291cmNlX2NvbnRleHQoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrU291cmNlQ29udGV4dEZpZWxkTnVtYmVyID0gNDsKKyAgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb250ZXh0JiBzb3VyY2VfY29udGV4dCgpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvbnRleHQqIG11dGFibGVfc291cmNlX2NvbnRleHQoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb250ZXh0KiByZWxlYXNlX3NvdXJjZV9jb250ZXh0KCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF9zb3VyY2VfY29udGV4dCg6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvbnRleHQqIHNvdXJjZV9jb250ZXh0KTsKKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLlN5bnRheCBzeW50YXggPSA1OworICB2b2lkIGNsZWFyX3N5bnRheCgpOworICBzdGF0aWMgY29uc3QgaW50IGtTeW50YXhGaWVsZE51bWJlciA9IDU7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6U3ludGF4IHN5bnRheCgpIGNvbnN0OworICB2b2lkIHNldF9zeW50YXgoOjpnb29nbGU6OnByb3RvYnVmOjpTeW50YXggdmFsdWUpOworCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpnb29nbGUucHJvdG9idWYuRW51bSkKKyBwcml2YXRlOgorCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEgX2ludGVybmFsX21ldGFkYXRhXzsKKyAgYm9vbCBfaXNfZGVmYXVsdF9pbnN0YW5jZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFyZW5hU3RyaW5nUHRyIG5hbWVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlID4gZW51bXZhbHVlXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbiA+IG9wdGlvbnNfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvbnRleHQqIHNvdXJjZV9jb250ZXh0XzsKKyAgaW50IHN5bnRheF87CisgIG11dGFibGUgaW50IF9jYWNoZWRfc2l6ZV87CisgIGZyaWVuZCB2b2lkIExJQlBST1RPQlVGX0VYUE9SVCBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmdHlwZV8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZ0eXBlXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfU2h1dGRvd25GaWxlX2dvb2dsZV8yZnByb3RvYnVmXzJmdHlwZV8yZXByb3RvKCk7CisKKyAgdm9pZCBJbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgc3RhdGljIEVudW0qIGRlZmF1bHRfaW5zdGFuY2VfOworfTsKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEVudW1WYWx1ZSA6IHB1YmxpYyA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UgeworIHB1YmxpYzoKKyAgRW51bVZhbHVlKCk7CisgIHZpcnR1YWwgfkVudW1WYWx1ZSgpOworCisgIEVudW1WYWx1ZShjb25zdCBFbnVtVmFsdWUmIGZyb20pOworCisgIGlubGluZSBFbnVtVmFsdWUmIG9wZXJhdG9yPShjb25zdCBFbnVtVmFsdWUmIGZyb20pIHsKKyAgICBDb3B5RnJvbShmcm9tKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworICBzdGF0aWMgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKCk7CisgIHN0YXRpYyBjb25zdCBFbnVtVmFsdWUmIGRlZmF1bHRfaW5zdGFuY2UoKTsKKworICB2b2lkIFN3YXAoRW51bVZhbHVlKiBvdGhlcik7CisKKyAgLy8gaW1wbGVtZW50cyBNZXNzYWdlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBpbmxpbmUgRW51bVZhbHVlKiBOZXcoKSBjb25zdCB7IHJldHVybiBOZXcoTlVMTCk7IH0KKworICBFbnVtVmFsdWUqIE5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3Q7CisgIHZvaWQgQ29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCBFbnVtVmFsdWUmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCBFbnVtVmFsdWUmIGZyb20pOworICB2b2lkIENsZWFyKCk7CisgIGJvb2wgSXNJbml0aWFsaXplZCgpIGNvbnN0OworCisgIGludCBCeXRlU2l6ZSgpIGNvbnN0OworICBib29sIE1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KTsKKyAgdm9pZCBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSg6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBvdXRwdXQpIGNvbnN0OworICBpbnQgR2V0Q2FjaGVkU2l6ZSgpIGNvbnN0IHsgcmV0dXJuIF9jYWNoZWRfc2l6ZV87IH0KKyAgcHJpdmF0ZToKKyAgdm9pZCBTaGFyZWRDdG9yKCk7CisgIHZvaWQgU2hhcmVkRHRvcigpOworICB2b2lkIFNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0OworICB2b2lkIEludGVybmFsU3dhcChFbnVtVmFsdWUqIG90aGVyKTsKKyAgcHJpdmF0ZToKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hTm9WaXJ0dWFsKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLmFyZW5hKCk7CisgIH0KKyAgaW5saW5lIHZvaWQqIE1heWJlQXJlbmFQdHIoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ucmF3X2FyZW5hX3B0cigpOworICB9CisgIHB1YmxpYzoKKworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEdldE1ldGFkYXRhKCkgY29uc3Q7CisKKyAgLy8gbmVzdGVkIHR5cGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBhY2Nlc3NvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKKyAgdm9pZCBjbGVhcl9uYW1lKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga05hbWVGaWVsZE51bWJlciA9IDE7CisgIGNvbnN0IDo6c3RkOjpzdHJpbmcmIG5hbWUoKSBjb25zdDsKKyAgdm9pZCBzZXRfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUpOworICB2b2lkIHNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIDo6c3RkOjpzdHJpbmcqIG11dGFibGVfbmFtZSgpOworICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlX25hbWUoKTsKKyAgdm9pZCBzZXRfYWxsb2NhdGVkX25hbWUoOjpzdGQ6OnN0cmluZyogbmFtZSk7CisKKyAgLy8gb3B0aW9uYWwgaW50MzIgbnVtYmVyID0gMjsKKyAgdm9pZCBjbGVhcl9udW1iZXIoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrTnVtYmVyRmllbGROdW1iZXIgPSAyOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIG51bWJlcigpIGNvbnN0OworICB2b2lkIHNldF9udW1iZXIoOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiB2YWx1ZSk7CisKKyAgLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5PcHRpb24gb3B0aW9ucyA9IDM7CisgIGludCBvcHRpb25zX3NpemUoKSBjb25zdDsKKyAgdm9pZCBjbGVhcl9vcHRpb25zKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga09wdGlvbnNGaWVsZE51bWJlciA9IDM7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6T3B0aW9uJiBvcHRpb25zKGludCBpbmRleCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6T3B0aW9uKiBtdXRhYmxlX29wdGlvbnMoaW50IGluZGV4KTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpPcHRpb24qIGFkZF9vcHRpb25zKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpPcHRpb24gPioKKyAgICAgIG11dGFibGVfb3B0aW9ucygpOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6T3B0aW9uID4mCisgICAgICBvcHRpb25zKCkgY29uc3Q7CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWUpCisgcHJpdmF0ZToKKworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpJbnRlcm5hbE1ldGFkYXRhV2l0aEFyZW5hIF9pbnRlcm5hbF9tZXRhZGF0YV87CisgIGJvb2wgX2lzX2RlZmF1bHRfaW5zdGFuY2VfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpBcmVuYVN0cmluZ1B0ciBuYW1lXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbiA+IG9wdGlvbnNfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIG51bWJlcl87CisgIG11dGFibGUgaW50IF9jYWNoZWRfc2l6ZV87CisgIGZyaWVuZCB2b2lkIExJQlBST1RPQlVGX0VYUE9SVCBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmdHlwZV8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZ0eXBlXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfU2h1dGRvd25GaWxlX2dvb2dsZV8yZnByb3RvYnVmXzJmdHlwZV8yZXByb3RvKCk7CisKKyAgdm9pZCBJbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgc3RhdGljIEVudW1WYWx1ZSogZGVmYXVsdF9pbnN0YW5jZV87Cit9OworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgT3B0aW9uIDogcHVibGljIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSB7CisgcHVibGljOgorICBPcHRpb24oKTsKKyAgdmlydHVhbCB+T3B0aW9uKCk7CisKKyAgT3B0aW9uKGNvbnN0IE9wdGlvbiYgZnJvbSk7CisKKyAgaW5saW5lIE9wdGlvbiYgb3BlcmF0b3I9KGNvbnN0IE9wdGlvbiYgZnJvbSkgeworICAgIENvcHlGcm9tKGZyb20pOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIHN0YXRpYyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIGRlc2NyaXB0b3IoKTsKKyAgc3RhdGljIGNvbnN0IE9wdGlvbiYgZGVmYXVsdF9pbnN0YW5jZSgpOworCisgIHZvaWQgU3dhcChPcHRpb24qIG90aGVyKTsKKworICAvLyBpbXBsZW1lbnRzIE1lc3NhZ2UgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIGlubGluZSBPcHRpb24qIE5ldygpIGNvbnN0IHsgcmV0dXJuIE5ldyhOVUxMKTsgfQorCisgIE9wdGlvbiogTmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdDsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIENvcHlGcm9tKGNvbnN0IE9wdGlvbiYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IE9wdGlvbiYgZnJvbSk7CisgIHZvaWQgQ2xlYXIoKTsKKyAgYm9vbCBJc0luaXRpYWxpemVkKCkgY29uc3Q7CisKKyAgaW50IEJ5dGVTaXplKCkgY29uc3Q7CisgIGJvb2wgTWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpOworICB2b2lkIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIG91dHB1dCkgY29uc3Q7CisgIGludCBHZXRDYWNoZWRTaXplKCkgY29uc3QgeyByZXR1cm4gX2NhY2hlZF9zaXplXzsgfQorICBwcml2YXRlOgorICB2b2lkIFNoYXJlZEN0b3IoKTsKKyAgdm9pZCBTaGFyZWREdG9yKCk7CisgIHZvaWQgU2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3Q7CisgIHZvaWQgSW50ZXJuYWxTd2FwKE9wdGlvbiogb3RoZXIpOworICBwcml2YXRlOgorICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogR2V0QXJlbmFOb1ZpcnR1YWwoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8uYXJlbmEoKTsKKyAgfQorICBpbmxpbmUgdm9pZCogTWF5YmVBcmVuYVB0cigpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5yYXdfYXJlbmFfcHRyKCk7CisgIH0KKyAgcHVibGljOgorCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgR2V0TWV0YWRhdGEoKSBjb25zdDsKKworICAvLyBuZXN0ZWQgdHlwZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIGFjY2Vzc29ycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSAxOworICB2b2lkIGNsZWFyX25hbWUoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrTmFtZUZpZWxkTnVtYmVyID0gMTsKKyAgY29uc3QgOjpzdGQ6OnN0cmluZyYgbmFtZSgpIGNvbnN0OworICB2b2lkIHNldF9uYW1lKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKTsKKyAgdm9pZCBzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSk7CisgIHZvaWQgc2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKTsKKyAgOjpzdGQ6OnN0cmluZyogbXV0YWJsZV9uYW1lKCk7CisgIDo6c3RkOjpzdHJpbmcqIHJlbGVhc2VfbmFtZSgpOworICB2b2lkIHNldF9hbGxvY2F0ZWRfbmFtZSg6OnN0ZDo6c3RyaW5nKiBuYW1lKTsKKworICAvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkFueSB2YWx1ZSA9IDI7CisgIGJvb2wgaGFzX3ZhbHVlKCkgY29uc3Q7CisgIHZvaWQgY2xlYXJfdmFsdWUoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrVmFsdWVGaWVsZE51bWJlciA9IDI7CisgIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6QW55JiB2YWx1ZSgpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OkFueSogbXV0YWJsZV92YWx1ZSgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6OkFueSogcmVsZWFzZV92YWx1ZSgpOworICB2b2lkIHNldF9hbGxvY2F0ZWRfdmFsdWUoOjpnb29nbGU6OnByb3RvYnVmOjpBbnkqIHZhbHVlKTsKKworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6Z29vZ2xlLnByb3RvYnVmLk9wdGlvbikKKyBwcml2YXRlOgorCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEgX2ludGVybmFsX21ldGFkYXRhXzsKKyAgYm9vbCBfaXNfZGVmYXVsdF9pbnN0YW5jZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFyZW5hU3RyaW5nUHRyIG5hbWVfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OkFueSogdmFsdWVfOworICBtdXRhYmxlIGludCBfY2FjaGVkX3NpemVfOworICBmcmllbmQgdm9pZCBMSUJQUk9UT0JVRl9FWFBPUlQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZnR5cGVfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmdHlwZV8yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZnR5cGVfMmVwcm90bygpOworCisgIHZvaWQgSW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIHN0YXRpYyBPcHRpb24qIGRlZmF1bHRfaW5zdGFuY2VfOworfTsKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKyNpZiAhUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisvLyBUeXBlCisKKy8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKK2lubGluZSB2b2lkIFR5cGU6OmNsZWFyX25hbWUoKSB7CisgIG5hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBUeXBlOjpuYW1lKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5UeXBlLm5hbWUpCisgIHJldHVybiBuYW1lXy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBUeXBlOjpzZXRfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICAKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuVHlwZS5uYW1lKQorfQoraW5saW5lIHZvaWQgVHlwZTo6c2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgCisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuVHlwZS5uYW1lKQorfQoraW5saW5lIHZvaWQgVHlwZTo6c2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIAorICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuVHlwZS5uYW1lKQorfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIFR5cGU6Om11dGFibGVfbmFtZSgpIHsKKyAgCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5UeXBlLm5hbWUpCisgIHJldHVybiBuYW1lXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIFR5cGU6OnJlbGVhc2VfbmFtZSgpIHsKKyAgCisgIHJldHVybiBuYW1lXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgVHlwZTo6c2V0X2FsbG9jYXRlZF9uYW1lKDo6c3RkOjpzdHJpbmcqIG5hbWUpIHsKKyAgaWYgKG5hbWUgIT0gTlVMTCkgeworICAgIAorICB9IGVsc2UgeworICAgIAorICB9CisgIG5hbWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBuYW1lKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLlR5cGUubmFtZSkKK30KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZCBmaWVsZHMgPSAyOworaW5saW5lIGludCBUeXBlOjpmaWVsZHNfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIGZpZWxkc18uc2l6ZSgpOworfQoraW5saW5lIHZvaWQgVHlwZTo6Y2xlYXJfZmllbGRzKCkgeworICBmaWVsZHNfLkNsZWFyKCk7Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZCYgVHlwZTo6ZmllbGRzKGludCBpbmRleCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5UeXBlLmZpZWxkcykKKyAgcmV0dXJuIGZpZWxkc18uR2V0KGluZGV4KTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkKiBUeXBlOjptdXRhYmxlX2ZpZWxkcyhpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLlR5cGUuZmllbGRzKQorICByZXR1cm4gZmllbGRzXy5NdXRhYmxlKGluZGV4KTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkKiBUeXBlOjphZGRfZmllbGRzKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5UeXBlLmZpZWxkcykKKyAgcmV0dXJuIGZpZWxkc18uQWRkKCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkID4qCitUeXBlOjptdXRhYmxlX2ZpZWxkcygpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGVfbGlzdDpnb29nbGUucHJvdG9idWYuVHlwZS5maWVsZHMpCisgIHJldHVybiAmZmllbGRzXzsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGQgPiYKK1R5cGU6OmZpZWxkcygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLlR5cGUuZmllbGRzKQorICByZXR1cm4gZmllbGRzXzsKK30KKworLy8gcmVwZWF0ZWQgc3RyaW5nIG9uZW9mcyA9IDM7CitpbmxpbmUgaW50IFR5cGU6Om9uZW9mc19zaXplKCkgY29uc3QgeworICByZXR1cm4gb25lb2ZzXy5zaXplKCk7Cit9CitpbmxpbmUgdm9pZCBUeXBlOjpjbGVhcl9vbmVvZnMoKSB7CisgIG9uZW9mc18uQ2xlYXIoKTsKK30KK2lubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBUeXBlOjpvbmVvZnMoaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlR5cGUub25lb2ZzKQorICByZXR1cm4gb25lb2ZzXy5HZXQoaW5kZXgpOworfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIFR5cGU6Om11dGFibGVfb25lb2ZzKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuVHlwZS5vbmVvZnMpCisgIHJldHVybiBvbmVvZnNfLk11dGFibGUoaW5kZXgpOworfQoraW5saW5lIHZvaWQgVHlwZTo6c2V0X29uZW9mcyhpbnQgaW5kZXgsIGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLlR5cGUub25lb2ZzKQorICBvbmVvZnNfLk11dGFibGUoaW5kZXgpLT5hc3NpZ24odmFsdWUpOworfQoraW5saW5lIHZvaWQgVHlwZTo6c2V0X29uZW9mcyhpbnQgaW5kZXgsIGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIG9uZW9mc18uTXV0YWJsZShpbmRleCktPmFzc2lnbih2YWx1ZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuVHlwZS5vbmVvZnMpCit9CitpbmxpbmUgdm9pZCBUeXBlOjpzZXRfb25lb2ZzKGludCBpbmRleCwgY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIG9uZW9mc18uTXV0YWJsZShpbmRleCktPmFzc2lnbigKKyAgICByZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLlR5cGUub25lb2ZzKQorfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIFR5cGU6OmFkZF9vbmVvZnMoKSB7CisgIHJldHVybiBvbmVvZnNfLkFkZCgpOworfQoraW5saW5lIHZvaWQgVHlwZTo6YWRkX29uZW9mcyhjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICBvbmVvZnNfLkFkZCgpLT5hc3NpZ24odmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5UeXBlLm9uZW9mcykKK30KK2lubGluZSB2b2lkIFR5cGU6OmFkZF9vbmVvZnMoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgb25lb2ZzXy5BZGQoKS0+YXNzaWduKHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5UeXBlLm9uZW9mcykKK30KK2lubGluZSB2b2lkIFR5cGU6OmFkZF9vbmVvZnMoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIG9uZW9mc18uQWRkKCktPmFzc2lnbihyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkX3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLlR5cGUub25lb2ZzKQorfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpzdGQ6OnN0cmluZz4mCitUeXBlOjpvbmVvZnMoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5UeXBlLm9uZW9mcykKKyAgcmV0dXJuIG9uZW9mc187Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6OnN0ZDo6c3RyaW5nPioKK1R5cGU6Om11dGFibGVfb25lb2ZzKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5UeXBlLm9uZW9mcykKKyAgcmV0dXJuICZvbmVvZnNfOworfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLk9wdGlvbiBvcHRpb25zID0gNDsKK2lubGluZSBpbnQgVHlwZTo6b3B0aW9uc19zaXplKCkgY29uc3QgeworICByZXR1cm4gb3B0aW9uc18uc2l6ZSgpOworfQoraW5saW5lIHZvaWQgVHlwZTo6Y2xlYXJfb3B0aW9ucygpIHsKKyAgb3B0aW9uc18uQ2xlYXIoKTsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbiYgVHlwZTo6b3B0aW9ucyhpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuVHlwZS5vcHRpb25zKQorICByZXR1cm4gb3B0aW9uc18uR2V0KGluZGV4KTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbiogVHlwZTo6bXV0YWJsZV9vcHRpb25zKGludCBpbmRleCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuVHlwZS5vcHRpb25zKQorICByZXR1cm4gb3B0aW9uc18uTXV0YWJsZShpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpPcHRpb24qIFR5cGU6OmFkZF9vcHRpb25zKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5UeXBlLm9wdGlvbnMpCisgIHJldHVybiBvcHRpb25zXy5BZGQoKTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6T3B0aW9uID4qCitUeXBlOjptdXRhYmxlX29wdGlvbnMoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLlR5cGUub3B0aW9ucykKKyAgcmV0dXJuICZvcHRpb25zXzsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6T3B0aW9uID4mCitUeXBlOjpvcHRpb25zKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbGlzdDpnb29nbGUucHJvdG9idWYuVHlwZS5vcHRpb25zKQorICByZXR1cm4gb3B0aW9uc187Cit9CisKKy8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCBzb3VyY2VfY29udGV4dCA9IDU7CitpbmxpbmUgYm9vbCBUeXBlOjpoYXNfc291cmNlX2NvbnRleHQoKSBjb25zdCB7CisgIHJldHVybiAhX2lzX2RlZmF1bHRfaW5zdGFuY2VfICYmIHNvdXJjZV9jb250ZXh0XyAhPSBOVUxMOworfQoraW5saW5lIHZvaWQgVHlwZTo6Y2xlYXJfc291cmNlX2NvbnRleHQoKSB7CisgIGlmIChHZXRBcmVuYU5vVmlydHVhbCgpID09IE5VTEwgJiYgc291cmNlX2NvbnRleHRfICE9IE5VTEwpIGRlbGV0ZSBzb3VyY2VfY29udGV4dF87CisgIHNvdXJjZV9jb250ZXh0XyA9IE5VTEw7Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb250ZXh0JiBUeXBlOjpzb3VyY2VfY29udGV4dCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuVHlwZS5zb3VyY2VfY29udGV4dCkKKyAgcmV0dXJuIHNvdXJjZV9jb250ZXh0XyAhPSBOVUxMID8gKnNvdXJjZV9jb250ZXh0XyA6ICpkZWZhdWx0X2luc3RhbmNlXy0+c291cmNlX2NvbnRleHRfOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29udGV4dCogVHlwZTo6bXV0YWJsZV9zb3VyY2VfY29udGV4dCgpIHsKKyAgCisgIGlmIChzb3VyY2VfY29udGV4dF8gPT0gTlVMTCkgeworICAgIHNvdXJjZV9jb250ZXh0XyA9IG5ldyA6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvbnRleHQ7CisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLlR5cGUuc291cmNlX2NvbnRleHQpCisgIHJldHVybiBzb3VyY2VfY29udGV4dF87Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb250ZXh0KiBUeXBlOjpyZWxlYXNlX3NvdXJjZV9jb250ZXh0KCkgeworICAKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb250ZXh0KiB0ZW1wID0gc291cmNlX2NvbnRleHRfOworICBzb3VyY2VfY29udGV4dF8gPSBOVUxMOworICByZXR1cm4gdGVtcDsKK30KK2lubGluZSB2b2lkIFR5cGU6OnNldF9hbGxvY2F0ZWRfc291cmNlX2NvbnRleHQoOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb250ZXh0KiBzb3VyY2VfY29udGV4dCkgeworICBkZWxldGUgc291cmNlX2NvbnRleHRfOworICBzb3VyY2VfY29udGV4dF8gPSBzb3VyY2VfY29udGV4dDsKKyAgaWYgKHNvdXJjZV9jb250ZXh0KSB7CisgICAgCisgIH0gZWxzZSB7CisgICAgCisgIH0KKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLlR5cGUuc291cmNlX2NvbnRleHQpCit9CisKKy8vIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuU3ludGF4IHN5bnRheCA9IDY7CitpbmxpbmUgdm9pZCBUeXBlOjpjbGVhcl9zeW50YXgoKSB7CisgIHN5bnRheF8gPSAwOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6U3ludGF4IFR5cGU6OnN5bnRheCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuVHlwZS5zeW50YXgpCisgIHJldHVybiBzdGF0aWNfY2FzdDwgOjpnb29nbGU6OnByb3RvYnVmOjpTeW50YXggPihzeW50YXhfKTsKK30KK2lubGluZSB2b2lkIFR5cGU6OnNldF9zeW50YXgoOjpnb29nbGU6OnByb3RvYnVmOjpTeW50YXggdmFsdWUpIHsKKyAgCisgIHN5bnRheF8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuVHlwZS5zeW50YXgpCit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gRmllbGQKKworLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZC5LaW5kIGtpbmQgPSAxOworaW5saW5lIHZvaWQgRmllbGQ6OmNsZWFyX2tpbmQoKSB7CisgIGtpbmRfID0gMDsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0tpbmQgRmllbGQ6OmtpbmQoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkLmtpbmQpCisgIHJldHVybiBzdGF0aWNfY2FzdDwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZF9LaW5kID4oa2luZF8pOworfQoraW5saW5lIHZvaWQgRmllbGQ6OnNldF9raW5kKDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGRfS2luZCB2YWx1ZSkgeworICAKKyAga2luZF8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmllbGQua2luZCkKK30KKworLy8gb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZC5DYXJkaW5hbGl0eSBjYXJkaW5hbGl0eSA9IDI7CitpbmxpbmUgdm9pZCBGaWVsZDo6Y2xlYXJfY2FyZGluYWxpdHkoKSB7CisgIGNhcmRpbmFsaXR5XyA9IDA7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZF9DYXJkaW5hbGl0eSBGaWVsZDo6Y2FyZGluYWxpdHkoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkLmNhcmRpbmFsaXR5KQorICByZXR1cm4gc3RhdGljX2Nhc3Q8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGRfQ2FyZGluYWxpdHkgPihjYXJkaW5hbGl0eV8pOworfQoraW5saW5lIHZvaWQgRmllbGQ6OnNldF9jYXJkaW5hbGl0eSg6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0NhcmRpbmFsaXR5IHZhbHVlKSB7CisgIAorICBjYXJkaW5hbGl0eV8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmllbGQuY2FyZGluYWxpdHkpCit9CisKKy8vIG9wdGlvbmFsIGludDMyIG51bWJlciA9IDM7CitpbmxpbmUgdm9pZCBGaWVsZDo6Y2xlYXJfbnVtYmVyKCkgeworICBudW1iZXJfID0gMDsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIEZpZWxkOjpudW1iZXIoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkLm51bWJlcikKKyAgcmV0dXJuIG51bWJlcl87Cit9CitpbmxpbmUgdm9pZCBGaWVsZDo6c2V0X251bWJlcig6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKSB7CisgIAorICBudW1iZXJfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkLm51bWJlcikKK30KKworLy8gb3B0aW9uYWwgc3RyaW5nIG5hbWUgPSA0OworaW5saW5lIHZvaWQgRmllbGQ6OmNsZWFyX25hbWUoKSB7CisgIG5hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBGaWVsZDo6bmFtZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmllbGQubmFtZSkKKyAgcmV0dXJuIG5hbWVfLkdldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIEZpZWxkOjpzZXRfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICAKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmllbGQubmFtZSkKK30KK2lubGluZSB2b2lkIEZpZWxkOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSkgeworICAKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5GaWVsZC5uYW1lKQorfQoraW5saW5lIHZvaWQgRmllbGQ6OnNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlLCBzaXplX3Qgc2l6ZSkgeworICAKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLkZpZWxkLm5hbWUpCit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogRmllbGQ6Om11dGFibGVfbmFtZSgpIHsKKyAgCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5GaWVsZC5uYW1lKQorICByZXR1cm4gbmFtZV8uTXV0YWJsZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBGaWVsZDo6cmVsZWFzZV9uYW1lKCkgeworICAKKyAgcmV0dXJuIG5hbWVfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBGaWVsZDo6c2V0X2FsbG9jYXRlZF9uYW1lKDo6c3RkOjpzdHJpbmcqIG5hbWUpIHsKKyAgaWYgKG5hbWUgIT0gTlVMTCkgeworICAgIAorICB9IGVsc2UgeworICAgIAorICB9CisgIG5hbWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBuYW1lKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkLm5hbWUpCit9CisKKy8vIG9wdGlvbmFsIHN0cmluZyB0eXBlX3VybCA9IDY7CitpbmxpbmUgdm9pZCBGaWVsZDo6Y2xlYXJfdHlwZV91cmwoKSB7CisgIHR5cGVfdXJsXy5DbGVhclRvRW1wdHlOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgY29uc3QgOjpzdGQ6OnN0cmluZyYgRmllbGQ6OnR5cGVfdXJsKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZC50eXBlX3VybCkKKyAgcmV0dXJuIHR5cGVfdXJsXy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBGaWVsZDo6c2V0X3R5cGVfdXJsKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIAorICB0eXBlX3VybF8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmllbGQudHlwZV91cmwpCit9CitpbmxpbmUgdm9pZCBGaWVsZDo6c2V0X3R5cGVfdXJsKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIAorICB0eXBlX3VybF8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5GaWVsZC50eXBlX3VybCkKK30KK2lubGluZSB2b2lkIEZpZWxkOjpzZXRfdHlwZV91cmwoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIAorICB0eXBlX3VybF8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLkZpZWxkLnR5cGVfdXJsKQorfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIEZpZWxkOjptdXRhYmxlX3R5cGVfdXJsKCkgeworICAKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpZWxkLnR5cGVfdXJsKQorICByZXR1cm4gdHlwZV91cmxfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogRmllbGQ6OnJlbGVhc2VfdHlwZV91cmwoKSB7CisgIAorICByZXR1cm4gdHlwZV91cmxfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBGaWVsZDo6c2V0X2FsbG9jYXRlZF90eXBlX3VybCg6OnN0ZDo6c3RyaW5nKiB0eXBlX3VybCkgeworICBpZiAodHlwZV91cmwgIT0gTlVMTCkgeworICAgIAorICB9IGVsc2UgeworICAgIAorICB9CisgIHR5cGVfdXJsXy5TZXRBbGxvY2F0ZWROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdHlwZV91cmwpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuRmllbGQudHlwZV91cmwpCit9CisKKy8vIG9wdGlvbmFsIGludDMyIG9uZW9mX2luZGV4ID0gNzsKK2lubGluZSB2b2lkIEZpZWxkOjpjbGVhcl9vbmVvZl9pbmRleCgpIHsKKyAgb25lb2ZfaW5kZXhfID0gMDsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIEZpZWxkOjpvbmVvZl9pbmRleCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmllbGQub25lb2ZfaW5kZXgpCisgIHJldHVybiBvbmVvZl9pbmRleF87Cit9CitpbmxpbmUgdm9pZCBGaWVsZDo6c2V0X29uZW9mX2luZGV4KDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgdmFsdWUpIHsKKyAgCisgIG9uZW9mX2luZGV4XyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZC5vbmVvZl9pbmRleCkKK30KKworLy8gb3B0aW9uYWwgYm9vbCBwYWNrZWQgPSA4OworaW5saW5lIHZvaWQgRmllbGQ6OmNsZWFyX3BhY2tlZCgpIHsKKyAgcGFja2VkXyA9IGZhbHNlOworfQoraW5saW5lIGJvb2wgRmllbGQ6OnBhY2tlZCgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmllbGQucGFja2VkKQorICByZXR1cm4gcGFja2VkXzsKK30KK2lubGluZSB2b2lkIEZpZWxkOjpzZXRfcGFja2VkKGJvb2wgdmFsdWUpIHsKKyAgCisgIHBhY2tlZF8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmllbGQucGFja2VkKQorfQorCisvLyByZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLk9wdGlvbiBvcHRpb25zID0gOTsKK2lubGluZSBpbnQgRmllbGQ6Om9wdGlvbnNfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIG9wdGlvbnNfLnNpemUoKTsKK30KK2lubGluZSB2b2lkIEZpZWxkOjpjbGVhcl9vcHRpb25zKCkgeworICBvcHRpb25zXy5DbGVhcigpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6T3B0aW9uJiBGaWVsZDo6b3B0aW9ucyhpbnQgaW5kZXgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRmllbGQub3B0aW9ucykKKyAgcmV0dXJuIG9wdGlvbnNfLkdldChpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpPcHRpb24qIEZpZWxkOjptdXRhYmxlX29wdGlvbnMoaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5GaWVsZC5vcHRpb25zKQorICByZXR1cm4gb3B0aW9uc18uTXV0YWJsZShpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpPcHRpb24qIEZpZWxkOjphZGRfb3B0aW9ucygpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuRmllbGQub3B0aW9ucykKKyAgcmV0dXJuIG9wdGlvbnNfLkFkZCgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpPcHRpb24gPioKK0ZpZWxkOjptdXRhYmxlX29wdGlvbnMoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkZpZWxkLm9wdGlvbnMpCisgIHJldHVybiAmb3B0aW9uc187Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbiA+JgorRmllbGQ6Om9wdGlvbnMoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZC5vcHRpb25zKQorICByZXR1cm4gb3B0aW9uc187Cit9CisKKy8vIG9wdGlvbmFsIHN0cmluZyBqc29uX25hbWUgPSAxMDsKK2lubGluZSB2b2lkIEZpZWxkOjpjbGVhcl9qc29uX25hbWUoKSB7CisgIGpzb25fbmFtZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEZpZWxkOjpqc29uX25hbWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZpZWxkLmpzb25fbmFtZSkKKyAgcmV0dXJuIGpzb25fbmFtZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgRmllbGQ6OnNldF9qc29uX25hbWUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgCisgIGpzb25fbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmllbGQuanNvbl9uYW1lKQorfQoraW5saW5lIHZvaWQgRmllbGQ6OnNldF9qc29uX25hbWUoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgCisgIGpzb25fbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcodmFsdWUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9jaGFyOmdvb2dsZS5wcm90b2J1Zi5GaWVsZC5qc29uX25hbWUpCit9CitpbmxpbmUgdm9pZCBGaWVsZDo6c2V0X2pzb25fbmFtZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgCisgIGpzb25fbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICA6OnN0ZDo6c3RyaW5nKHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLkZpZWxkLmpzb25fbmFtZSkKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBGaWVsZDo6bXV0YWJsZV9qc29uX25hbWUoKSB7CisgIAorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuRmllbGQuanNvbl9uYW1lKQorICByZXR1cm4ganNvbl9uYW1lXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIEZpZWxkOjpyZWxlYXNlX2pzb25fbmFtZSgpIHsKKyAgCisgIHJldHVybiBqc29uX25hbWVfLlJlbGVhc2VOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBGaWVsZDo6c2V0X2FsbG9jYXRlZF9qc29uX25hbWUoOjpzdGQ6OnN0cmluZyoganNvbl9uYW1lKSB7CisgIGlmIChqc29uX25hbWUgIT0gTlVMTCkgeworICAgIAorICB9IGVsc2UgeworICAgIAorICB9CisgIGpzb25fbmFtZV8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGpzb25fbmFtZSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5GaWVsZC5qc29uX25hbWUpCit9CisKKy8vIG9wdGlvbmFsIHN0cmluZyBkZWZhdWx0X3ZhbHVlID0gMTE7CitpbmxpbmUgdm9pZCBGaWVsZDo6Y2xlYXJfZGVmYXVsdF92YWx1ZSgpIHsKKyAgZGVmYXVsdF92YWx1ZV8uQ2xlYXJUb0VtcHR5Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIEZpZWxkOjpkZWZhdWx0X3ZhbHVlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZC5kZWZhdWx0X3ZhbHVlKQorICByZXR1cm4gZGVmYXVsdF92YWx1ZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgRmllbGQ6OnNldF9kZWZhdWx0X3ZhbHVlKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIAorICBkZWZhdWx0X3ZhbHVlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GaWVsZC5kZWZhdWx0X3ZhbHVlKQorfQoraW5saW5lIHZvaWQgRmllbGQ6OnNldF9kZWZhdWx0X3ZhbHVlKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIAorICBkZWZhdWx0X3ZhbHVlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLkZpZWxkLmRlZmF1bHRfdmFsdWUpCit9CitpbmxpbmUgdm9pZCBGaWVsZDo6c2V0X2RlZmF1bHRfdmFsdWUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIAorICBkZWZhdWx0X3ZhbHVlXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuRmllbGQuZGVmYXVsdF92YWx1ZSkKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBGaWVsZDo6bXV0YWJsZV9kZWZhdWx0X3ZhbHVlKCkgeworICAKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkZpZWxkLmRlZmF1bHRfdmFsdWUpCisgIHJldHVybiBkZWZhdWx0X3ZhbHVlXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIEZpZWxkOjpyZWxlYXNlX2RlZmF1bHRfdmFsdWUoKSB7CisgIAorICByZXR1cm4gZGVmYXVsdF92YWx1ZV8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIEZpZWxkOjpzZXRfYWxsb2NhdGVkX2RlZmF1bHRfdmFsdWUoOjpzdGQ6OnN0cmluZyogZGVmYXVsdF92YWx1ZSkgeworICBpZiAoZGVmYXVsdF92YWx1ZSAhPSBOVUxMKSB7CisgICAgCisgIH0gZWxzZSB7CisgICAgCisgIH0KKyAgZGVmYXVsdF92YWx1ZV8uU2V0QWxsb2NhdGVkTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIGRlZmF1bHRfdmFsdWUpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuRmllbGQuZGVmYXVsdF92YWx1ZSkKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBFbnVtCisKKy8vIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKK2lubGluZSB2b2lkIEVudW06OmNsZWFyX25hbWUoKSB7CisgIG5hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBFbnVtOjpuYW1lKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5FbnVtLm5hbWUpCisgIHJldHVybiBuYW1lXy5HZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBFbnVtOjpzZXRfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICAKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRW51bS5uYW1lKQorfQoraW5saW5lIHZvaWQgRW51bTo6c2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgCisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuRW51bS5uYW1lKQorfQoraW5saW5lIHZvaWQgRW51bTo6c2V0X25hbWUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKSB7CisgIAorICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIDo6c3RkOjpzdHJpbmcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4odmFsdWUpLCBzaXplKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfcG9pbnRlcjpnb29nbGUucHJvdG9idWYuRW51bS5uYW1lKQorfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIEVudW06Om11dGFibGVfbmFtZSgpIHsKKyAgCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5FbnVtLm5hbWUpCisgIHJldHVybiBuYW1lXy5NdXRhYmxlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIEVudW06OnJlbGVhc2VfbmFtZSgpIHsKKyAgCisgIHJldHVybiBuYW1lXy5SZWxlYXNlTm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgRW51bTo6c2V0X2FsbG9jYXRlZF9uYW1lKDo6c3RkOjpzdHJpbmcqIG5hbWUpIHsKKyAgaWYgKG5hbWUgIT0gTlVMTCkgeworICAgIAorICB9IGVsc2UgeworICAgIAorICB9CisgIG5hbWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBuYW1lKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkVudW0ubmFtZSkKK30KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWUgZW51bXZhbHVlID0gMjsKK2lubGluZSBpbnQgRW51bTo6ZW51bXZhbHVlX3NpemUoKSBjb25zdCB7CisgIHJldHVybiBlbnVtdmFsdWVfLnNpemUoKTsKK30KK2lubGluZSB2b2lkIEVudW06OmNsZWFyX2VudW12YWx1ZSgpIHsKKyAgZW51bXZhbHVlXy5DbGVhcigpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlJiBFbnVtOjplbnVtdmFsdWUoaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkVudW0uZW51bXZhbHVlKQorICByZXR1cm4gZW51bXZhbHVlXy5HZXQoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlKiBFbnVtOjptdXRhYmxlX2VudW12YWx1ZShpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkVudW0uZW51bXZhbHVlKQorICByZXR1cm4gZW51bXZhbHVlXy5NdXRhYmxlKGluZGV4KTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZSogRW51bTo6YWRkX2VudW12YWx1ZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuRW51bS5lbnVtdmFsdWUpCisgIHJldHVybiBlbnVtdmFsdWVfLkFkZCgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtVmFsdWUgPioKK0VudW06Om11dGFibGVfZW51bXZhbHVlKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5FbnVtLmVudW12YWx1ZSkKKyAgcmV0dXJuICZlbnVtdmFsdWVfOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpFbnVtVmFsdWUgPiYKK0VudW06OmVudW12YWx1ZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkVudW0uZW51bXZhbHVlKQorICByZXR1cm4gZW51bXZhbHVlXzsKK30KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5PcHRpb24gb3B0aW9ucyA9IDM7CitpbmxpbmUgaW50IEVudW06Om9wdGlvbnNfc2l6ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIG9wdGlvbnNfLnNpemUoKTsKK30KK2lubGluZSB2b2lkIEVudW06OmNsZWFyX29wdGlvbnMoKSB7CisgIG9wdGlvbnNfLkNsZWFyKCk7Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpPcHRpb24mIEVudW06Om9wdGlvbnMoaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkVudW0ub3B0aW9ucykKKyAgcmV0dXJuIG9wdGlvbnNfLkdldChpbmRleCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpPcHRpb24qIEVudW06Om11dGFibGVfb3B0aW9ucyhpbnQgaW5kZXgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLkVudW0ub3B0aW9ucykKKyAgcmV0dXJuIG9wdGlvbnNfLk11dGFibGUoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6T3B0aW9uKiBFbnVtOjphZGRfb3B0aW9ucygpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2FkZDpnb29nbGUucHJvdG9idWYuRW51bS5vcHRpb25zKQorICByZXR1cm4gb3B0aW9uc18uQWRkKCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbiA+KgorRW51bTo6bXV0YWJsZV9vcHRpb25zKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5FbnVtLm9wdGlvbnMpCisgIHJldHVybiAmb3B0aW9uc187Cit9CitpbmxpbmUgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPCA6Omdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbiA+JgorRW51bTo6b3B0aW9ucygpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2xpc3Q6Z29vZ2xlLnByb3RvYnVmLkVudW0ub3B0aW9ucykKKyAgcmV0dXJuIG9wdGlvbnNfOworfQorCisvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQgc291cmNlX2NvbnRleHQgPSA0OworaW5saW5lIGJvb2wgRW51bTo6aGFzX3NvdXJjZV9jb250ZXh0KCkgY29uc3QgeworICByZXR1cm4gIV9pc19kZWZhdWx0X2luc3RhbmNlXyAmJiBzb3VyY2VfY29udGV4dF8gIT0gTlVMTDsKK30KK2lubGluZSB2b2lkIEVudW06OmNsZWFyX3NvdXJjZV9jb250ZXh0KCkgeworICBpZiAoR2V0QXJlbmFOb1ZpcnR1YWwoKSA9PSBOVUxMICYmIHNvdXJjZV9jb250ZXh0XyAhPSBOVUxMKSBkZWxldGUgc291cmNlX2NvbnRleHRfOworICBzb3VyY2VfY29udGV4dF8gPSBOVUxMOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29udGV4dCYgRW51bTo6c291cmNlX2NvbnRleHQoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkVudW0uc291cmNlX2NvbnRleHQpCisgIHJldHVybiBzb3VyY2VfY29udGV4dF8gIT0gTlVMTCA/ICpzb3VyY2VfY29udGV4dF8gOiAqZGVmYXVsdF9pbnN0YW5jZV8tPnNvdXJjZV9jb250ZXh0XzsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlNvdXJjZUNvbnRleHQqIEVudW06Om11dGFibGVfc291cmNlX2NvbnRleHQoKSB7CisgIAorICBpZiAoc291cmNlX2NvbnRleHRfID09IE5VTEwpIHsKKyAgICBzb3VyY2VfY29udGV4dF8gPSBuZXcgOjpnb29nbGU6OnByb3RvYnVmOjpTb3VyY2VDb250ZXh0OworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5FbnVtLnNvdXJjZV9jb250ZXh0KQorICByZXR1cm4gc291cmNlX2NvbnRleHRfOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29udGV4dCogRW51bTo6cmVsZWFzZV9zb3VyY2VfY29udGV4dCgpIHsKKyAgCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29udGV4dCogdGVtcCA9IHNvdXJjZV9jb250ZXh0XzsKKyAgc291cmNlX2NvbnRleHRfID0gTlVMTDsKKyAgcmV0dXJuIHRlbXA7Cit9CitpbmxpbmUgdm9pZCBFbnVtOjpzZXRfYWxsb2NhdGVkX3NvdXJjZV9jb250ZXh0KDo6Z29vZ2xlOjpwcm90b2J1Zjo6U291cmNlQ29udGV4dCogc291cmNlX2NvbnRleHQpIHsKKyAgZGVsZXRlIHNvdXJjZV9jb250ZXh0XzsKKyAgc291cmNlX2NvbnRleHRfID0gc291cmNlX2NvbnRleHQ7CisgIGlmIChzb3VyY2VfY29udGV4dCkgeworICAgIAorICB9IGVsc2UgeworICAgIAorICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5FbnVtLnNvdXJjZV9jb250ZXh0KQorfQorCisvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLlN5bnRheCBzeW50YXggPSA1OworaW5saW5lIHZvaWQgRW51bTo6Y2xlYXJfc3ludGF4KCkgeworICBzeW50YXhfID0gMDsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OlN5bnRheCBFbnVtOjpzeW50YXgoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkVudW0uc3ludGF4KQorICByZXR1cm4gc3RhdGljX2Nhc3Q8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6U3ludGF4ID4oc3ludGF4Xyk7Cit9CitpbmxpbmUgdm9pZCBFbnVtOjpzZXRfc3ludGF4KDo6Z29vZ2xlOjpwcm90b2J1Zjo6U3ludGF4IHZhbHVlKSB7CisgIAorICBzeW50YXhfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkVudW0uc3ludGF4KQorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIEVudW1WYWx1ZQorCisvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CitpbmxpbmUgdm9pZCBFbnVtVmFsdWU6OmNsZWFyX25hbWUoKSB7CisgIG5hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBFbnVtVmFsdWU6Om5hbWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZS5uYW1lKQorICByZXR1cm4gbmFtZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgRW51bVZhbHVlOjpzZXRfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICAKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlLm5hbWUpCit9CitpbmxpbmUgdm9pZCBFbnVtVmFsdWU6OnNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIAorICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZS5uYW1lKQorfQoraW5saW5lIHZvaWQgRW51bVZhbHVlOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgCisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWUubmFtZSkKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBFbnVtVmFsdWU6Om11dGFibGVfbmFtZSgpIHsKKyAgCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWUubmFtZSkKKyAgcmV0dXJuIG5hbWVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogRW51bVZhbHVlOjpyZWxlYXNlX25hbWUoKSB7CisgIAorICByZXR1cm4gbmFtZV8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIEVudW1WYWx1ZTo6c2V0X2FsbG9jYXRlZF9uYW1lKDo6c3RkOjpzdHJpbmcqIG5hbWUpIHsKKyAgaWYgKG5hbWUgIT0gTlVMTCkgeworICAgIAorICB9IGVsc2UgeworICAgIAorICB9CisgIG5hbWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBuYW1lKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZS5uYW1lKQorfQorCisvLyBvcHRpb25hbCBpbnQzMiBudW1iZXIgPSAyOworaW5saW5lIHZvaWQgRW51bVZhbHVlOjpjbGVhcl9udW1iZXIoKSB7CisgIG51bWJlcl8gPSAwOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgRW51bVZhbHVlOjpudW1iZXIoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZS5udW1iZXIpCisgIHJldHVybiBudW1iZXJfOworfQoraW5saW5lIHZvaWQgRW51bVZhbHVlOjpzZXRfbnVtYmVyKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgdmFsdWUpIHsKKyAgCisgIG51bWJlcl8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRW51bVZhbHVlLm51bWJlcikKK30KKworLy8gcmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5PcHRpb24gb3B0aW9ucyA9IDM7CitpbmxpbmUgaW50IEVudW1WYWx1ZTo6b3B0aW9uc19zaXplKCkgY29uc3QgeworICByZXR1cm4gb3B0aW9uc18uc2l6ZSgpOworfQoraW5saW5lIHZvaWQgRW51bVZhbHVlOjpjbGVhcl9vcHRpb25zKCkgeworICBvcHRpb25zXy5DbGVhcigpOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6T3B0aW9uJiBFbnVtVmFsdWU6Om9wdGlvbnMoaW50IGluZGV4KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZS5vcHRpb25zKQorICByZXR1cm4gb3B0aW9uc18uR2V0KGluZGV4KTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbiogRW51bVZhbHVlOjptdXRhYmxlX29wdGlvbnMoaW50IGluZGV4KSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWUub3B0aW9ucykKKyAgcmV0dXJuIG9wdGlvbnNfLk11dGFibGUoaW5kZXgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6T3B0aW9uKiBFbnVtVmFsdWU6OmFkZF9vcHRpb25zKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfYWRkOmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWUub3B0aW9ucykKKyAgcmV0dXJuIG9wdGlvbnNfLkFkZCgpOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6UmVwZWF0ZWRQdHJGaWVsZDwgOjpnb29nbGU6OnByb3RvYnVmOjpPcHRpb24gPioKK0VudW1WYWx1ZTo6bXV0YWJsZV9vcHRpb25zKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZV9saXN0Omdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWUub3B0aW9ucykKKyAgcmV0dXJuICZvcHRpb25zXzsKK30KK2lubGluZSBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6T3B0aW9uID4mCitFbnVtVmFsdWU6Om9wdGlvbnMoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9saXN0Omdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWUub3B0aW9ucykKKyAgcmV0dXJuIG9wdGlvbnNfOworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIE9wdGlvbgorCisvLyBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CitpbmxpbmUgdm9pZCBPcHRpb246OmNsZWFyX25hbWUoKSB7CisgIG5hbWVfLkNsZWFyVG9FbXB0eU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSBjb25zdCA6OnN0ZDo6c3RyaW5nJiBPcHRpb246Om5hbWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLk9wdGlvbi5uYW1lKQorICByZXR1cm4gbmFtZV8uR2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQoraW5saW5lIHZvaWQgT3B0aW9uOjpzZXRfbmFtZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICAKKyAgbmFtZV8uU2V0Tm9BcmVuYSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuT3B0aW9uLm5hbWUpCit9CitpbmxpbmUgdm9pZCBPcHRpb246OnNldF9uYW1lKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIAorICBuYW1lXy5TZXROb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLk9wdGlvbi5uYW1lKQorfQoraW5saW5lIHZvaWQgT3B0aW9uOjpzZXRfbmFtZShjb25zdCBjaGFyKiB2YWx1ZSwgc2l6ZV90IHNpemUpIHsKKyAgCisgIG5hbWVfLlNldE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgOjpzdGQ6OnN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5PcHRpb24ubmFtZSkKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBPcHRpb246Om11dGFibGVfbmFtZSgpIHsKKyAgCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5PcHRpb24ubmFtZSkKKyAgcmV0dXJuIG5hbWVfLk11dGFibGVOb0FyZW5hKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogT3B0aW9uOjpyZWxlYXNlX25hbWUoKSB7CisgIAorICByZXR1cm4gbmFtZV8uUmVsZWFzZU5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KK2lubGluZSB2b2lkIE9wdGlvbjo6c2V0X2FsbG9jYXRlZF9uYW1lKDo6c3RkOjpzdHJpbmcqIG5hbWUpIHsKKyAgaWYgKG5hbWUgIT0gTlVMTCkgeworICAgIAorICB9IGVsc2UgeworICAgIAorICB9CisgIG5hbWVfLlNldEFsbG9jYXRlZE5vQXJlbmEoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBuYW1lKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLk9wdGlvbi5uYW1lKQorfQorCisvLyBvcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkFueSB2YWx1ZSA9IDI7CitpbmxpbmUgYm9vbCBPcHRpb246Omhhc192YWx1ZSgpIGNvbnN0IHsKKyAgcmV0dXJuICFfaXNfZGVmYXVsdF9pbnN0YW5jZV8gJiYgdmFsdWVfICE9IE5VTEw7Cit9CitpbmxpbmUgdm9pZCBPcHRpb246OmNsZWFyX3ZhbHVlKCkgeworICBpZiAoR2V0QXJlbmFOb1ZpcnR1YWwoKSA9PSBOVUxMICYmIHZhbHVlXyAhPSBOVUxMKSBkZWxldGUgdmFsdWVfOworICB2YWx1ZV8gPSBOVUxMOworfQoraW5saW5lIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6QW55JiBPcHRpb246OnZhbHVlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5PcHRpb24udmFsdWUpCisgIHJldHVybiB2YWx1ZV8gIT0gTlVMTCA/ICp2YWx1ZV8gOiAqZGVmYXVsdF9pbnN0YW5jZV8tPnZhbHVlXzsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkFueSogT3B0aW9uOjptdXRhYmxlX3ZhbHVlKCkgeworICAKKyAgaWYgKHZhbHVlXyA9PSBOVUxMKSB7CisgICAgdmFsdWVfID0gbmV3IDo6Z29vZ2xlOjpwcm90b2J1Zjo6QW55OworICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5PcHRpb24udmFsdWUpCisgIHJldHVybiB2YWx1ZV87Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpBbnkqIE9wdGlvbjo6cmVsZWFzZV92YWx1ZSgpIHsKKyAgCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QW55KiB0ZW1wID0gdmFsdWVfOworICB2YWx1ZV8gPSBOVUxMOworICByZXR1cm4gdGVtcDsKK30KK2lubGluZSB2b2lkIE9wdGlvbjo6c2V0X2FsbG9jYXRlZF92YWx1ZSg6Omdvb2dsZTo6cHJvdG9idWY6OkFueSogdmFsdWUpIHsKKyAgZGVsZXRlIHZhbHVlXzsKKyAgdmFsdWVfID0gdmFsdWU7CisgIGlmICh2YWx1ZSkgeworICAgIAorICB9IGVsc2UgeworICAgIAorICB9CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5PcHRpb24udmFsdWUpCit9CisKKyNlbmRpZiAgLy8gIVBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisKKy8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChuYW1lc3BhY2Vfc2NvcGUpCisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisjaWZuZGVmIFNXSUcKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKwordGVtcGxhdGUgPD4gc3RydWN0IGlzX3Byb3RvX2VudW08IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGRfS2luZD4gOiA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjp0cnVlX3R5cGUge307Cit0ZW1wbGF0ZSA8PgoraW5saW5lIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBHZXRFbnVtRGVzY3JpcHRvcjwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZF9LaW5kPigpIHsKKyAgcmV0dXJuIDo6Z29vZ2xlOjpwcm90b2J1Zjo6RmllbGRfS2luZF9kZXNjcmlwdG9yKCk7Cit9Cit0ZW1wbGF0ZSA8PiBzdHJ1Y3QgaXNfcHJvdG9fZW51bTwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZF9DYXJkaW5hbGl0eT4gOiA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjp0cnVlX3R5cGUge307Cit0ZW1wbGF0ZSA8PgoraW5saW5lIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBHZXRFbnVtRGVzY3JpcHRvcjwgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZF9DYXJkaW5hbGl0eT4oKSB7CisgIHJldHVybiA6Omdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0NhcmRpbmFsaXR5X2Rlc2NyaXB0b3IoKTsKK30KK3RlbXBsYXRlIDw+IHN0cnVjdCBpc19wcm90b19lbnVtPCA6Omdvb2dsZTo6cHJvdG9idWY6OlN5bnRheD4gOiA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjp0cnVlX3R5cGUge307Cit0ZW1wbGF0ZSA8PgoraW5saW5lIGNvbnN0IEVudW1EZXNjcmlwdG9yKiBHZXRFbnVtRGVzY3JpcHRvcjwgOjpnb29nbGU6OnByb3RvYnVmOjpTeW50YXg+KCkgeworICByZXR1cm4gOjpnb29nbGU6OnByb3RvYnVmOjpTeW50YXhfZGVzY3JpcHRvcigpOworfQorCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gU1dJRworCisvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZ2xvYmFsX3Njb3BlKQorCisjZW5kaWYgIC8vIFBST1RPQlVGX2dvb2dsZV8yZnByb3RvYnVmXzJmdHlwZV8yZXByb3RvX19JTkNMVURFRApkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi90eXBlLnByb3RvIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi90eXBlLnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFjOWNmNTMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3R5cGUucHJvdG8KQEAgLTAsMCArMSwxODAgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitzeW50YXggPSAicHJvdG8zIjsKKworcGFja2FnZSBnb29nbGUucHJvdG9idWY7CisKK2ltcG9ydCAiZ29vZ2xlL3Byb3RvYnVmL2FueS5wcm90byI7CitpbXBvcnQgImdvb2dsZS9wcm90b2J1Zi9zb3VyY2VfY29udGV4dC5wcm90byI7CisKK29wdGlvbiBjc2hhcnBfbmFtZXNwYWNlID0gIkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlcyI7CitvcHRpb24gamF2YV9wYWNrYWdlID0gImNvbS5nb29nbGUucHJvdG9idWYiOworb3B0aW9uIGphdmFfb3V0ZXJfY2xhc3NuYW1lID0gIlR5cGVQcm90byI7CitvcHRpb24gamF2YV9tdWx0aXBsZV9maWxlcyA9IHRydWU7CitvcHRpb24gamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2ggPSB0cnVlOworb3B0aW9uIG9iamNfY2xhc3NfcHJlZml4ID0gIkdQQiI7CisKKy8vIEEgcHJvdG9jb2wgYnVmZmVyIG1lc3NhZ2UgdHlwZS4KK21lc3NhZ2UgVHlwZSB7CisgIC8vIFRoZSBmdWxseSBxdWFsaWZpZWQgbWVzc2FnZSBuYW1lLgorICBzdHJpbmcgbmFtZSA9IDE7CisgIC8vIFRoZSBsaXN0IG9mIGZpZWxkcy4KKyAgcmVwZWF0ZWQgRmllbGQgZmllbGRzID0gMjsKKyAgLy8gVGhlIGxpc3Qgb2YgdHlwZXMgYXBwZWFyaW5nIGluIGBvbmVvZmAgZGVmaW5pdGlvbnMgaW4gdGhpcyB0eXBlLgorICByZXBlYXRlZCBzdHJpbmcgb25lb2ZzID0gMzsKKyAgLy8gVGhlIHByb3RvY29sIGJ1ZmZlciBvcHRpb25zLgorICByZXBlYXRlZCBPcHRpb24gb3B0aW9ucyA9IDQ7CisgIC8vIFRoZSBzb3VyY2UgY29udGV4dC4KKyAgU291cmNlQ29udGV4dCBzb3VyY2VfY29udGV4dCA9IDU7CisgIC8vIFRoZSBzb3VyY2Ugc3ludGF4LgorICBTeW50YXggc3ludGF4ID0gNjsKK30KKworLy8gQSBzaW5nbGUgZmllbGQgb2YgYSBtZXNzYWdlIHR5cGUuCittZXNzYWdlIEZpZWxkIHsKKyAgLy8gQmFzaWMgZmllbGQgdHlwZXMuCisgIGVudW0gS2luZCB7CisgICAgLy8gRmllbGQgdHlwZSB1bmtub3duLgorICAgIFRZUEVfVU5LTk9XTiAgICAgICAgPSAwOworICAgIC8vIEZpZWxkIHR5cGUgZG91YmxlLgorICAgIFRZUEVfRE9VQkxFICAgICAgICAgPSAxOworICAgIC8vIEZpZWxkIHR5cGUgZmxvYXQuCisgICAgVFlQRV9GTE9BVCAgICAgICAgICA9IDI7CisgICAgLy8gRmllbGQgdHlwZSBpbnQ2NC4KKyAgICBUWVBFX0lOVDY0ICAgICAgICAgID0gMzsKKyAgICAvLyBGaWVsZCB0eXBlIHVpbnQ2NC4KKyAgICBUWVBFX1VJTlQ2NCAgICAgICAgID0gNDsKKyAgICAvLyBGaWVsZCB0eXBlIGludDMyLgorICAgIFRZUEVfSU5UMzIgICAgICAgICAgPSA1OworICAgIC8vIEZpZWxkIHR5cGUgZml4ZWQ2NC4KKyAgICBUWVBFX0ZJWEVENjQgICAgICAgID0gNjsKKyAgICAvLyBGaWVsZCB0eXBlIGZpeGVkMzIuCisgICAgVFlQRV9GSVhFRDMyICAgICAgICA9IDc7CisgICAgLy8gRmllbGQgdHlwZSBib29sLgorICAgIFRZUEVfQk9PTCAgICAgICAgICAgPSA4OworICAgIC8vIEZpZWxkIHR5cGUgc3RyaW5nLgorICAgIFRZUEVfU1RSSU5HICAgICAgICAgPSA5OworICAgIC8vIEZpZWxkIHR5cGUgZ3JvdXAuIFByb3RvMiBzeW50YXggb25seSwgYW5kIGRlcHJlY2F0ZWQuCisgICAgVFlQRV9HUk9VUCAgICAgICAgICA9IDEwOworICAgIC8vIEZpZWxkIHR5cGUgbWVzc2FnZS4KKyAgICBUWVBFX01FU1NBR0UgICAgICAgID0gMTE7CisgICAgLy8gRmllbGQgdHlwZSBieXRlcy4KKyAgICBUWVBFX0JZVEVTICAgICAgICAgID0gMTI7CisgICAgLy8gRmllbGQgdHlwZSB1aW50MzIuCisgICAgVFlQRV9VSU5UMzIgICAgICAgICA9IDEzOworICAgIC8vIEZpZWxkIHR5cGUgZW51bS4KKyAgICBUWVBFX0VOVU0gICAgICAgICAgID0gMTQ7CisgICAgLy8gRmllbGQgdHlwZSBzZml4ZWQzMi4KKyAgICBUWVBFX1NGSVhFRDMyICAgICAgID0gMTU7CisgICAgLy8gRmllbGQgdHlwZSBzZml4ZWQ2NC4KKyAgICBUWVBFX1NGSVhFRDY0ICAgICAgID0gMTY7CisgICAgLy8gRmllbGQgdHlwZSBzaW50MzIuCisgICAgVFlQRV9TSU5UMzIgICAgICAgICA9IDE3OworICAgIC8vIEZpZWxkIHR5cGUgc2ludDY0LgorICAgIFRZUEVfU0lOVDY0ICAgICAgICAgPSAxODsKKyAgfTsKKworICAvLyBXaGV0aGVyIGEgZmllbGQgaXMgb3B0aW9uYWwsIHJlcXVpcmVkLCBvciByZXBlYXRlZC4KKyAgZW51bSBDYXJkaW5hbGl0eSB7CisgICAgLy8gRm9yIGZpZWxkcyB3aXRoIHVua25vd24gY2FyZGluYWxpdHkuCisgICAgQ0FSRElOQUxJVFlfVU5LTk9XTiA9IDA7CisgICAgLy8gRm9yIG9wdGlvbmFsIGZpZWxkcy4KKyAgICBDQVJESU5BTElUWV9PUFRJT05BTCA9IDE7CisgICAgLy8gRm9yIHJlcXVpcmVkIGZpZWxkcy4gUHJvdG8yIHN5bnRheCBvbmx5LgorICAgIENBUkRJTkFMSVRZX1JFUVVJUkVEID0gMjsKKyAgICAvLyBGb3IgcmVwZWF0ZWQgZmllbGRzLgorICAgIENBUkRJTkFMSVRZX1JFUEVBVEVEID0gMzsKKyAgfTsKKworICAvLyBUaGUgZmllbGQgdHlwZS4KKyAgS2luZCBraW5kID0gMTsKKyAgLy8gVGhlIGZpZWxkIGNhcmRpbmFsaXR5LgorICBDYXJkaW5hbGl0eSBjYXJkaW5hbGl0eSA9IDI7CisgIC8vIFRoZSBmaWVsZCBudW1iZXIuCisgIGludDMyIG51bWJlciA9IDM7CisgIC8vIFRoZSBmaWVsZCBuYW1lLgorICBzdHJpbmcgbmFtZSA9IDQ7CisgIC8vIFRoZSBmaWVsZCB0eXBlIFVSTCwgd2l0aG91dCB0aGUgc2NoZW1lLCBmb3IgbWVzc2FnZSBvciBlbnVtZXJhdGlvbgorICAvLyB0eXBlcy4gRXhhbXBsZTogYCJ0eXBlLmdvb2dsZWFwaXMuY29tL2dvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAiYC4KKyAgc3RyaW5nIHR5cGVfdXJsID0gNjsKKyAgLy8gVGhlIGluZGV4IG9mIHRoZSBmaWVsZCB0eXBlIGluIGBUeXBlLm9uZW9mc2AsIGZvciBtZXNzYWdlIG9yIGVudW1lcmF0aW9uCisgIC8vIHR5cGVzLiBUaGUgZmlyc3QgdHlwZSBoYXMgaW5kZXggMTsgemVybyBtZWFucyB0aGUgdHlwZSBpcyBub3QgaW4gdGhlIGxpc3QuCisgIGludDMyIG9uZW9mX2luZGV4ID0gNzsKKyAgLy8gV2hldGhlciB0byB1c2UgYWx0ZXJuYXRpdmUgcGFja2VkIHdpcmUgcmVwcmVzZW50YXRpb24uCisgIGJvb2wgcGFja2VkID0gODsKKyAgLy8gVGhlIHByb3RvY29sIGJ1ZmZlciBvcHRpb25zLgorICByZXBlYXRlZCBPcHRpb24gb3B0aW9ucyA9IDk7CisgIC8vIFRoZSBmaWVsZCBKU09OIG5hbWUuCisgIHN0cmluZyBqc29uX25hbWUgPSAxMDsKKyAgLy8gVGhlIHN0cmluZyB2YWx1ZSBvZiB0aGUgZGVmYXVsdCB2YWx1ZSBvZiB0aGlzIGZpZWxkLiBQcm90bzIgc3ludGF4IG9ubHkuCisgIHN0cmluZyBkZWZhdWx0X3ZhbHVlID0gMTE7Cit9CisKKy8vIEVudW0gdHlwZSBkZWZpbml0aW9uLgorbWVzc2FnZSBFbnVtIHsKKyAgLy8gRW51bSB0eXBlIG5hbWUuCisgIHN0cmluZyBuYW1lID0gMTsKKyAgLy8gRW51bSB2YWx1ZSBkZWZpbml0aW9ucy4KKyAgcmVwZWF0ZWQgRW51bVZhbHVlIGVudW12YWx1ZSA9IDI7CisgIC8vIFByb3RvY29sIGJ1ZmZlciBvcHRpb25zLgorICByZXBlYXRlZCBPcHRpb24gb3B0aW9ucyA9IDM7CisgIC8vIFRoZSBzb3VyY2UgY29udGV4dC4KKyAgU291cmNlQ29udGV4dCBzb3VyY2VfY29udGV4dCA9IDQ7CisgIC8vIFRoZSBzb3VyY2Ugc3ludGF4LgorICBTeW50YXggc3ludGF4ID0gNTsKK30KKworLy8gRW51bSB2YWx1ZSBkZWZpbml0aW9uLgorbWVzc2FnZSBFbnVtVmFsdWUgeworICAvLyBFbnVtIHZhbHVlIG5hbWUuCisgIHN0cmluZyBuYW1lID0gMTsKKyAgLy8gRW51bSB2YWx1ZSBudW1iZXIuCisgIGludDMyIG51bWJlciA9IDI7CisgIC8vIFByb3RvY29sIGJ1ZmZlciBvcHRpb25zLgorICByZXBlYXRlZCBPcHRpb24gb3B0aW9ucyA9IDM7Cit9CisKKy8vIEEgcHJvdG9jb2wgYnVmZmVyIG9wdGlvbiwgd2hpY2ggY2FuIGJlIGF0dGFjaGVkIHRvIGEgbWVzc2FnZSwgZmllbGQsCisvLyBlbnVtZXJhdGlvbiwgZXRjLgorbWVzc2FnZSBPcHRpb24geworICAvLyBUaGUgb3B0aW9uJ3MgbmFtZS4gRm9yIGV4YW1wbGUsIGAiamF2YV9wYWNrYWdlImAuCisgIHN0cmluZyBuYW1lID0gMTsKKyAgLy8gVGhlIG9wdGlvbidzIHZhbHVlLiBGb3IgZXhhbXBsZSwgYCJjb20uZ29vZ2xlLnByb3RvYnVmImAuCisgIEFueSB2YWx1ZSA9IDI7Cit9CisKKy8vIFRoZSBzeW50YXggaW4gd2hpY2ggYSBwcm90b2NvbCBidWZmZXIgZWxlbWVudCBpcyBkZWZpbmVkLgorZW51bSBTeW50YXggeworICAvLyBTeW50YXggYHByb3RvMmAuCisgIFNZTlRBWF9QUk9UTzIgPSAwOworICAvLyBTeW50YXggYHByb3RvM2AuCisgIFNZTlRBWF9QUk9UTzMgPSAxOworfQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wcm90byBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODVmZTYxNQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucHJvdG8KQEAgLTAsMCArMSw4NzggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBBIHByb3RvIGZpbGUgd2Ugd2lsbCB1c2UgZm9yIHVuaXQgdGVzdGluZy4KKworc3ludGF4ID0gInByb3RvMiI7CisKKy8vIFNvbWUgZ2VuZXJpY19zZXJ2aWNlcyBvcHRpb24ocykgYWRkZWQgYXV0b21hdGljYWxseS4KKy8vIFNlZTogIGh0dHA6Ly9nby9wcm90bzItZ2VuZXJpYy1zZXJ2aWNlcy1kZWZhdWx0CitvcHRpb24gY2NfZ2VuZXJpY19zZXJ2aWNlcyA9IHRydWU7ICAgICAvLyBhdXRvLWFkZGVkCitvcHRpb24gamF2YV9nZW5lcmljX3NlcnZpY2VzID0gdHJ1ZTsgICAvLyBhdXRvLWFkZGVkCitvcHRpb24gcHlfZ2VuZXJpY19zZXJ2aWNlcyA9IHRydWU7ICAgICAvLyBhdXRvLWFkZGVkCitvcHRpb24gY2NfZW5hYmxlX2FyZW5hcyA9IHRydWU7CisKK2ltcG9ydCAiZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2ltcG9ydC5wcm90byI7CisKKy8vIFdlIGRvbid0IHB1dCB0aGlzIGluIGEgcGFja2FnZSB3aXRoaW4gcHJvdG8yIGJlY2F1c2Ugd2UgbmVlZCB0byBtYWtlIHN1cmUKKy8vIHRoYXQgdGhlIGdlbmVyYXRlZCBjb2RlIGRvZXNuJ3QgZGVwZW5kIG9uIGJlaW5nIGluIHRoZSBwcm90bzIgbmFtZXNwYWNlLgorLy8gSW4gdGVzdF91dGlsLmggd2UgZG8gInVzaW5nIG5hbWVzcGFjZSB1bml0dGVzdCA9IHByb3RvYnVmX3VuaXR0ZXN0Ii4KK3BhY2thZ2UgcHJvdG9idWZfdW5pdHRlc3Q7CisKKy8vIFByb3RvcyBvcHRpbWl6ZWQgZm9yIFNQRUVEIHVzZSBhIHN0cmljdCBzdXBlcnNldCBvZiB0aGUgZ2VuZXJhdGVkIGNvZGUKKy8vIG9mIGVxdWl2YWxlbnQgb25lcyBvcHRpbWl6ZWQgZm9yIENPREVfU0laRSwgc28gd2Ugc2hvdWxkIG9wdGltaXplIGFsbCBvdXIKKy8vIHRlc3RzIGZvciBzcGVlZCB1bmxlc3MgZXhwbGljaXRseSB0ZXN0aW5nIGNvZGUgc2l6ZSBvcHRpbWl6YXRpb24uCitvcHRpb24gb3B0aW1pemVfZm9yID0gU1BFRUQ7CisKK29wdGlvbiBqYXZhX291dGVyX2NsYXNzbmFtZSA9ICJVbml0dGVzdFByb3RvIjsKKworLy8gVGhpcyBwcm90byBpbmNsdWRlcyBldmVyeSB0eXBlIG9mIGZpZWxkIGluIGJvdGggc2luZ3VsYXIgYW5kIHJlcGVhdGVkCisvLyBmb3Jtcy4KK21lc3NhZ2UgVGVzdEFsbFR5cGVzIHsKKyAgbWVzc2FnZSBOZXN0ZWRNZXNzYWdlIHsKKyAgICAvLyBUaGUgZmllbGQgbmFtZSAiYiIgZmFpbHMgdG8gY29tcGlsZSBpbiBwcm90bzEgYmVjYXVzZSBpdCBjb25mbGljdHMgd2l0aAorICAgIC8vIGEgbG9jYWwgdmFyaWFibGUgbmFtZWQgImIiIGluIG9uZSBvZiB0aGUgZ2VuZXJhdGVkIG1ldGhvZHMuICBEb2guCisgICAgLy8gVGhpcyBmaWxlIG5lZWRzIHRvIGNvbXBpbGUgaW4gcHJvdG8xIHRvIHRlc3QgYmFja3dhcmRzLWNvbXBhdGliaWxpdHkuCisgICAgb3B0aW9uYWwgaW50MzIgYmIgPSAxOworICB9CisKKyAgZW51bSBOZXN0ZWRFbnVtIHsKKyAgICBGT08gPSAxOworICAgIEJBUiA9IDI7CisgICAgQkFaID0gMzsKKyAgICBORUcgPSAtMTsgIC8vIEludGVudGlvbmFsbHkgbmVnYXRpdmUuCisgIH0KKworICAvLyBTaW5ndWxhcgorICBvcHRpb25hbCAgICBpbnQzMiBvcHRpb25hbF9pbnQzMiAgICA9ICAxOworICBvcHRpb25hbCAgICBpbnQ2NCBvcHRpb25hbF9pbnQ2NCAgICA9ICAyOworICBvcHRpb25hbCAgIHVpbnQzMiBvcHRpb25hbF91aW50MzIgICA9ICAzOworICBvcHRpb25hbCAgIHVpbnQ2NCBvcHRpb25hbF91aW50NjQgICA9ICA0OworICBvcHRpb25hbCAgIHNpbnQzMiBvcHRpb25hbF9zaW50MzIgICA9ICA1OworICBvcHRpb25hbCAgIHNpbnQ2NCBvcHRpb25hbF9zaW50NjQgICA9ICA2OworICBvcHRpb25hbCAgZml4ZWQzMiBvcHRpb25hbF9maXhlZDMyICA9ICA3OworICBvcHRpb25hbCAgZml4ZWQ2NCBvcHRpb25hbF9maXhlZDY0ICA9ICA4OworICBvcHRpb25hbCBzZml4ZWQzMiBvcHRpb25hbF9zZml4ZWQzMiA9ICA5OworICBvcHRpb25hbCBzZml4ZWQ2NCBvcHRpb25hbF9zZml4ZWQ2NCA9IDEwOworICBvcHRpb25hbCAgICBmbG9hdCBvcHRpb25hbF9mbG9hdCAgICA9IDExOworICBvcHRpb25hbCAgIGRvdWJsZSBvcHRpb25hbF9kb3VibGUgICA9IDEyOworICBvcHRpb25hbCAgICAgYm9vbCBvcHRpb25hbF9ib29sICAgICA9IDEzOworICBvcHRpb25hbCAgIHN0cmluZyBvcHRpb25hbF9zdHJpbmcgICA9IDE0OworICBvcHRpb25hbCAgICBieXRlcyBvcHRpb25hbF9ieXRlcyAgICA9IDE1OworCisgIG9wdGlvbmFsIGdyb3VwIE9wdGlvbmFsR3JvdXAgPSAxNiB7CisgICAgb3B0aW9uYWwgaW50MzIgYSA9IDE3OworICB9CisKKyAgb3B0aW9uYWwgTmVzdGVkTWVzc2FnZSAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlICA9IDE4OworICBvcHRpb25hbCBGb3JlaWduTWVzc2FnZSAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlID0gMTk7CisgIG9wdGlvbmFsIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlICA9IDIwOworCisgIG9wdGlvbmFsIE5lc3RlZEVudW0gICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25hbF9uZXN0ZWRfZW51bSAgICAgPSAyMTsKKyAgb3B0aW9uYWwgRm9yZWlnbkVudW0gICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbmFsX2ZvcmVpZ25fZW51bSAgICA9IDIyOworICBvcHRpb25hbCBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0RW51bSAgICBvcHRpb25hbF9pbXBvcnRfZW51bSAgICAgPSAyMzsKKworICBvcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nX3BpZWNlID0gMjQgW2N0eXBlPVNUUklOR19QSUVDRV07CisgIG9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9jb3JkID0gMjUgW2N0eXBlPUNPUkRdOworCisgIC8vIERlZmluZWQgaW4gdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wcm90bworICBvcHRpb25hbCBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVzc2FnZQorICAgICAgb3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlID0gMjY7CisKKyAgb3B0aW9uYWwgTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSAyNyBbbGF6eT10cnVlXTsKKworICAvLyBSZXBlYXRlZAorICByZXBlYXRlZCAgICBpbnQzMiByZXBlYXRlZF9pbnQzMiAgICA9IDMxOworICByZXBlYXRlZCAgICBpbnQ2NCByZXBlYXRlZF9pbnQ2NCAgICA9IDMyOworICByZXBlYXRlZCAgIHVpbnQzMiByZXBlYXRlZF91aW50MzIgICA9IDMzOworICByZXBlYXRlZCAgIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgICA9IDM0OworICByZXBlYXRlZCAgIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgICA9IDM1OworICByZXBlYXRlZCAgIHNpbnQ2NCByZXBlYXRlZF9zaW50NjQgICA9IDM2OworICByZXBlYXRlZCAgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyICA9IDM3OworICByZXBlYXRlZCAgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ICA9IDM4OworICByZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDM5OworICByZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDQwOworICByZXBlYXRlZCAgICBmbG9hdCByZXBlYXRlZF9mbG9hdCAgICA9IDQxOworICByZXBlYXRlZCAgIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgICA9IDQyOworICByZXBlYXRlZCAgICAgYm9vbCByZXBlYXRlZF9ib29sICAgICA9IDQzOworICByZXBlYXRlZCAgIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgICA9IDQ0OworICByZXBlYXRlZCAgICBieXRlcyByZXBlYXRlZF9ieXRlcyAgICA9IDQ1OworCisgIHJlcGVhdGVkIGdyb3VwIFJlcGVhdGVkR3JvdXAgPSA0NiB7CisgICAgb3B0aW9uYWwgaW50MzIgYSA9IDQ3OworICB9CisKKyAgcmVwZWF0ZWQgTmVzdGVkTWVzc2FnZSAgICAgICAgICAgICAgICAgICAgICAgIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlICA9IDQ4OworICByZXBlYXRlZCBGb3JlaWduTWVzc2FnZSAgICAgICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlID0gNDk7CisgIHJlcGVhdGVkIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlICA9IDUwOworCisgIHJlcGVhdGVkIE5lc3RlZEVudW0gICAgICAgICAgICAgICAgICAgICAgICAgICByZXBlYXRlZF9uZXN0ZWRfZW51bSAgICAgPSA1MTsKKyAgcmVwZWF0ZWQgRm9yZWlnbkVudW0gICAgICAgICAgICAgICAgICAgICAgICAgIHJlcGVhdGVkX2ZvcmVpZ25fZW51bSAgICA9IDUyOworICByZXBlYXRlZCBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0RW51bSAgICByZXBlYXRlZF9pbXBvcnRfZW51bSAgICAgPSA1MzsKKworICByZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlPVNUUklOR19QSUVDRV07CisgIHJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9jb3JkID0gNTUgW2N0eXBlPUNPUkRdOworCisgIHJlcGVhdGVkIE5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenk9dHJ1ZV07CisKKyAgLy8gU2luZ3VsYXIgd2l0aCBkZWZhdWx0cworICBvcHRpb25hbCAgICBpbnQzMiBkZWZhdWx0X2ludDMyICAgID0gNjEgW2RlZmF1bHQgPSAgNDEgICAgXTsKKyAgb3B0aW9uYWwgICAgaW50NjQgZGVmYXVsdF9pbnQ2NCAgICA9IDYyIFtkZWZhdWx0ID0gIDQyICAgIF07CisgIG9wdGlvbmFsICAgdWludDMyIGRlZmF1bHRfdWludDMyICAgPSA2MyBbZGVmYXVsdCA9ICA0MyAgICBdOworICBvcHRpb25hbCAgIHVpbnQ2NCBkZWZhdWx0X3VpbnQ2NCAgID0gNjQgW2RlZmF1bHQgPSAgNDQgICAgXTsKKyAgb3B0aW9uYWwgICBzaW50MzIgZGVmYXVsdF9zaW50MzIgICA9IDY1IFtkZWZhdWx0ID0gLTQ1ICAgIF07CisgIG9wdGlvbmFsICAgc2ludDY0IGRlZmF1bHRfc2ludDY0ICAgPSA2NiBbZGVmYXVsdCA9ICA0NiAgICBdOworICBvcHRpb25hbCAgZml4ZWQzMiBkZWZhdWx0X2ZpeGVkMzIgID0gNjcgW2RlZmF1bHQgPSAgNDcgICAgXTsKKyAgb3B0aW9uYWwgIGZpeGVkNjQgZGVmYXVsdF9maXhlZDY0ICA9IDY4IFtkZWZhdWx0ID0gIDQ4ICAgIF07CisgIG9wdGlvbmFsIHNmaXhlZDMyIGRlZmF1bHRfc2ZpeGVkMzIgPSA2OSBbZGVmYXVsdCA9ICA0OSAgICBdOworICBvcHRpb25hbCBzZml4ZWQ2NCBkZWZhdWx0X3NmaXhlZDY0ID0gNzAgW2RlZmF1bHQgPSAtNTAgICAgXTsKKyAgb3B0aW9uYWwgICAgZmxvYXQgZGVmYXVsdF9mbG9hdCAgICA9IDcxIFtkZWZhdWx0ID0gIDUxLjUgIF07CisgIG9wdGlvbmFsICAgZG91YmxlIGRlZmF1bHRfZG91YmxlICAgPSA3MiBbZGVmYXVsdCA9ICA1MmUzICBdOworICBvcHRpb25hbCAgICAgYm9vbCBkZWZhdWx0X2Jvb2wgICAgID0gNzMgW2RlZmF1bHQgPSB0cnVlICAgXTsKKyAgb3B0aW9uYWwgICBzdHJpbmcgZGVmYXVsdF9zdHJpbmcgICA9IDc0IFtkZWZhdWx0ID0gImhlbGxvIl07CisgIG9wdGlvbmFsICAgIGJ5dGVzIGRlZmF1bHRfYnl0ZXMgICAgPSA3NSBbZGVmYXVsdCA9ICJ3b3JsZCJdOworCisgIG9wdGlvbmFsIE5lc3RlZEVudW0gIGRlZmF1bHRfbmVzdGVkX2VudW0gID0gODEgW2RlZmF1bHQgPSBCQVIgICAgICAgIF07CisgIG9wdGlvbmFsIEZvcmVpZ25FbnVtIGRlZmF1bHRfZm9yZWlnbl9lbnVtID0gODIgW2RlZmF1bHQgPSBGT1JFSUdOX0JBUl07CisgIG9wdGlvbmFsIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtCisgICAgICBkZWZhdWx0X2ltcG9ydF9lbnVtID0gODMgW2RlZmF1bHQgPSBJTVBPUlRfQkFSXTsKKworICBvcHRpb25hbCBzdHJpbmcgZGVmYXVsdF9zdHJpbmdfcGllY2UgPSA4NCBbY3R5cGU9U1RSSU5HX1BJRUNFLGRlZmF1bHQ9ImFiYyJdOworICBvcHRpb25hbCBzdHJpbmcgZGVmYXVsdF9jb3JkID0gODUgW2N0eXBlPUNPUkQsZGVmYXVsdD0iMTIzIl07CisKKyAgLy8gRm9yIG9uZW9mIHRlc3QKKyAgb25lb2Ygb25lb2ZfZmllbGQgeworICAgIHVpbnQzMiBvbmVvZl91aW50MzIgPSAxMTE7CisgICAgTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDExMjsKKyAgICBzdHJpbmcgb25lb2Zfc3RyaW5nID0gMTEzOworICAgIGJ5dGVzIG9uZW9mX2J5dGVzID0gMTE0OworICB9Cit9CisKKy8vIFRoaXMgcHJvdG8gaW5jbHVkZXMgYSByZWN1c2l2ZWx5IG5lc3RlZCBtZXNzYWdlLgorbWVzc2FnZSBOZXN0ZWRUZXN0QWxsVHlwZXMgeworICBvcHRpb25hbCBOZXN0ZWRUZXN0QWxsVHlwZXMgY2hpbGQgPSAxOworICBvcHRpb25hbCBUZXN0QWxsVHlwZXMgcGF5bG9hZCA9IDI7CisgIHJlcGVhdGVkIE5lc3RlZFRlc3RBbGxUeXBlcyByZXBlYXRlZF9jaGlsZCA9IDM7Cit9CisKK21lc3NhZ2UgVGVzdERlcHJlY2F0ZWRGaWVsZHMgeworICBvcHRpb25hbCBpbnQzMiBkZXByZWNhdGVkX2ludDMyID0gMSBbZGVwcmVjYXRlZD10cnVlXTsKK30KKworLy8gRGVmaW5lIHRoZXNlIGFmdGVyIFRlc3RBbGxUeXBlcyB0byBtYWtlIHN1cmUgdGhlIGNvbXBpbGVyIGNhbiBoYW5kbGUKKy8vIHRoYXQuCittZXNzYWdlIEZvcmVpZ25NZXNzYWdlIHsKKyAgb3B0aW9uYWwgaW50MzIgYyA9IDE7Cit9CisKK2VudW0gRm9yZWlnbkVudW0geworICBGT1JFSUdOX0ZPTyA9IDQ7CisgIEZPUkVJR05fQkFSID0gNTsKKyAgRk9SRUlHTl9CQVogPSA2OworfQorCittZXNzYWdlIFRlc3RSZXNlcnZlZEZpZWxkcyB7CisgIHJlc2VydmVkIDIsIDE1LCA5IHRvIDExOworICByZXNlcnZlZCAiYmFyIiwgImJheiI7Cit9CisKK21lc3NhZ2UgVGVzdEFsbEV4dGVuc2lvbnMgeworICBleHRlbnNpb25zIDEgdG8gbWF4OworfQorCitleHRlbmQgVGVzdEFsbEV4dGVuc2lvbnMgeworICAvLyBTaW5ndWxhcgorICBvcHRpb25hbCAgICBpbnQzMiBvcHRpb25hbF9pbnQzMl9leHRlbnNpb24gICAgPSAgMTsKKyAgb3B0aW9uYWwgICAgaW50NjQgb3B0aW9uYWxfaW50NjRfZXh0ZW5zaW9uICAgID0gIDI7CisgIG9wdGlvbmFsICAgdWludDMyIG9wdGlvbmFsX3VpbnQzMl9leHRlbnNpb24gICA9ICAzOworICBvcHRpb25hbCAgIHVpbnQ2NCBvcHRpb25hbF91aW50NjRfZXh0ZW5zaW9uICAgPSAgNDsKKyAgb3B0aW9uYWwgICBzaW50MzIgb3B0aW9uYWxfc2ludDMyX2V4dGVuc2lvbiAgID0gIDU7CisgIG9wdGlvbmFsICAgc2ludDY0IG9wdGlvbmFsX3NpbnQ2NF9leHRlbnNpb24gICA9ICA2OworICBvcHRpb25hbCAgZml4ZWQzMiBvcHRpb25hbF9maXhlZDMyX2V4dGVuc2lvbiAgPSAgNzsKKyAgb3B0aW9uYWwgIGZpeGVkNjQgb3B0aW9uYWxfZml4ZWQ2NF9leHRlbnNpb24gID0gIDg7CisgIG9wdGlvbmFsIHNmaXhlZDMyIG9wdGlvbmFsX3NmaXhlZDMyX2V4dGVuc2lvbiA9ICA5OworICBvcHRpb25hbCBzZml4ZWQ2NCBvcHRpb25hbF9zZml4ZWQ2NF9leHRlbnNpb24gPSAxMDsKKyAgb3B0aW9uYWwgICAgZmxvYXQgb3B0aW9uYWxfZmxvYXRfZXh0ZW5zaW9uICAgID0gMTE7CisgIG9wdGlvbmFsICAgZG91YmxlIG9wdGlvbmFsX2RvdWJsZV9leHRlbnNpb24gICA9IDEyOworICBvcHRpb25hbCAgICAgYm9vbCBvcHRpb25hbF9ib29sX2V4dGVuc2lvbiAgICAgPSAxMzsKKyAgb3B0aW9uYWwgICBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nX2V4dGVuc2lvbiAgID0gMTQ7CisgIG9wdGlvbmFsICAgIGJ5dGVzIG9wdGlvbmFsX2J5dGVzX2V4dGVuc2lvbiAgICA9IDE1OworCisgIG9wdGlvbmFsIGdyb3VwIE9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uID0gMTYgeworICAgIG9wdGlvbmFsIGludDMyIGEgPSAxNzsKKyAgfQorCisgIG9wdGlvbmFsIFRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiA9IDE4OworICBvcHRpb25hbCBGb3JlaWduTWVzc2FnZSBvcHRpb25hbF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uID0gMTk7CisgIG9wdGlvbmFsIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlCisgICAgb3B0aW9uYWxfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uID0gMjA7CisKKyAgb3B0aW9uYWwgVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gb3B0aW9uYWxfbmVzdGVkX2VudW1fZXh0ZW5zaW9uID0gMjE7CisgIG9wdGlvbmFsIEZvcmVpZ25FbnVtIG9wdGlvbmFsX2ZvcmVpZ25fZW51bV9leHRlbnNpb24gPSAyMjsKKyAgb3B0aW9uYWwgcHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydEVudW0KKyAgICBvcHRpb25hbF9pbXBvcnRfZW51bV9leHRlbnNpb24gPSAyMzsKKworICBvcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nX3BpZWNlX2V4dGVuc2lvbiA9IDI0IFtjdHlwZT1TVFJJTkdfUElFQ0VdOworICBvcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfY29yZF9leHRlbnNpb24gPSAyNSBbY3R5cGU9Q09SRF07CisKKyAgb3B0aW9uYWwgcHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LlB1YmxpY0ltcG9ydE1lc3NhZ2UKKyAgICBvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uID0gMjY7CisKKyAgb3B0aW9uYWwgVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UKKyAgICBvcHRpb25hbF9sYXp5X21lc3NhZ2VfZXh0ZW5zaW9uID0gMjcgW2xhenk9dHJ1ZV07CisKKyAgLy8gUmVwZWF0ZWQKKyAgcmVwZWF0ZWQgICAgaW50MzIgcmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9uICAgID0gMzE7CisgIHJlcGVhdGVkICAgIGludDY0IHJlcGVhdGVkX2ludDY0X2V4dGVuc2lvbiAgICA9IDMyOworICByZXBlYXRlZCAgIHVpbnQzMiByZXBlYXRlZF91aW50MzJfZXh0ZW5zaW9uICAgPSAzMzsKKyAgcmVwZWF0ZWQgICB1aW50NjQgcmVwZWF0ZWRfdWludDY0X2V4dGVuc2lvbiAgID0gMzQ7CisgIHJlcGVhdGVkICAgc2ludDMyIHJlcGVhdGVkX3NpbnQzMl9leHRlbnNpb24gICA9IDM1OworICByZXBlYXRlZCAgIHNpbnQ2NCByZXBlYXRlZF9zaW50NjRfZXh0ZW5zaW9uICAgPSAzNjsKKyAgcmVwZWF0ZWQgIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMl9leHRlbnNpb24gID0gMzc7CisgIHJlcGVhdGVkICBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjRfZXh0ZW5zaW9uICA9IDM4OworICByZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMl9leHRlbnNpb24gPSAzOTsKKyAgcmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjRfZXh0ZW5zaW9uID0gNDA7CisgIHJlcGVhdGVkICAgIGZsb2F0IHJlcGVhdGVkX2Zsb2F0X2V4dGVuc2lvbiAgICA9IDQxOworICByZXBlYXRlZCAgIGRvdWJsZSByZXBlYXRlZF9kb3VibGVfZXh0ZW5zaW9uICAgPSA0MjsKKyAgcmVwZWF0ZWQgICAgIGJvb2wgcmVwZWF0ZWRfYm9vbF9leHRlbnNpb24gICAgID0gNDM7CisgIHJlcGVhdGVkICAgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19leHRlbnNpb24gICA9IDQ0OworICByZXBlYXRlZCAgICBieXRlcyByZXBlYXRlZF9ieXRlc19leHRlbnNpb24gICAgPSA0NTsKKworICByZXBlYXRlZCBncm91cCBSZXBlYXRlZEdyb3VwX2V4dGVuc2lvbiA9IDQ2IHsKKyAgICBvcHRpb25hbCBpbnQzMiBhID0gNDc7CisgIH0KKworICByZXBlYXRlZCBUZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb24gPSA0ODsKKyAgcmVwZWF0ZWQgRm9yZWlnbk1lc3NhZ2UgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbiA9IDQ5OworICByZXBlYXRlZCBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZQorICAgIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbiA9IDUwOworCisgIHJlcGVhdGVkIFRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtX2V4dGVuc2lvbiA9IDUxOworICByZXBlYXRlZCBGb3JlaWduRW51bSByZXBlYXRlZF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uID0gNTI7CisgIHJlcGVhdGVkIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtCisgICAgcmVwZWF0ZWRfaW1wb3J0X2VudW1fZXh0ZW5zaW9uID0gNTM7CisKKyAgcmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19waWVjZV9leHRlbnNpb24gPSA1NCBbY3R5cGU9U1RSSU5HX1BJRUNFXTsKKyAgcmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX2NvcmRfZXh0ZW5zaW9uID0gNTUgW2N0eXBlPUNPUkRdOworCisgIHJlcGVhdGVkIFRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlCisgICAgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlX2V4dGVuc2lvbiA9IDU3IFtsYXp5PXRydWVdOworCisgIC8vIFNpbmd1bGFyIHdpdGggZGVmYXVsdHMKKyAgb3B0aW9uYWwgICAgaW50MzIgZGVmYXVsdF9pbnQzMl9leHRlbnNpb24gICAgPSA2MSBbZGVmYXVsdCA9ICA0MSAgICBdOworICBvcHRpb25hbCAgICBpbnQ2NCBkZWZhdWx0X2ludDY0X2V4dGVuc2lvbiAgICA9IDYyIFtkZWZhdWx0ID0gIDQyICAgIF07CisgIG9wdGlvbmFsICAgdWludDMyIGRlZmF1bHRfdWludDMyX2V4dGVuc2lvbiAgID0gNjMgW2RlZmF1bHQgPSAgNDMgICAgXTsKKyAgb3B0aW9uYWwgICB1aW50NjQgZGVmYXVsdF91aW50NjRfZXh0ZW5zaW9uICAgPSA2NCBbZGVmYXVsdCA9ICA0NCAgICBdOworICBvcHRpb25hbCAgIHNpbnQzMiBkZWZhdWx0X3NpbnQzMl9leHRlbnNpb24gICA9IDY1IFtkZWZhdWx0ID0gLTQ1ICAgIF07CisgIG9wdGlvbmFsICAgc2ludDY0IGRlZmF1bHRfc2ludDY0X2V4dGVuc2lvbiAgID0gNjYgW2RlZmF1bHQgPSAgNDYgICAgXTsKKyAgb3B0aW9uYWwgIGZpeGVkMzIgZGVmYXVsdF9maXhlZDMyX2V4dGVuc2lvbiAgPSA2NyBbZGVmYXVsdCA9ICA0NyAgICBdOworICBvcHRpb25hbCAgZml4ZWQ2NCBkZWZhdWx0X2ZpeGVkNjRfZXh0ZW5zaW9uICA9IDY4IFtkZWZhdWx0ID0gIDQ4ICAgIF07CisgIG9wdGlvbmFsIHNmaXhlZDMyIGRlZmF1bHRfc2ZpeGVkMzJfZXh0ZW5zaW9uID0gNjkgW2RlZmF1bHQgPSAgNDkgICAgXTsKKyAgb3B0aW9uYWwgc2ZpeGVkNjQgZGVmYXVsdF9zZml4ZWQ2NF9leHRlbnNpb24gPSA3MCBbZGVmYXVsdCA9IC01MCAgICBdOworICBvcHRpb25hbCAgICBmbG9hdCBkZWZhdWx0X2Zsb2F0X2V4dGVuc2lvbiAgICA9IDcxIFtkZWZhdWx0ID0gIDUxLjUgIF07CisgIG9wdGlvbmFsICAgZG91YmxlIGRlZmF1bHRfZG91YmxlX2V4dGVuc2lvbiAgID0gNzIgW2RlZmF1bHQgPSAgNTJlMyAgXTsKKyAgb3B0aW9uYWwgICAgIGJvb2wgZGVmYXVsdF9ib29sX2V4dGVuc2lvbiAgICAgPSA3MyBbZGVmYXVsdCA9IHRydWUgICBdOworICBvcHRpb25hbCAgIHN0cmluZyBkZWZhdWx0X3N0cmluZ19leHRlbnNpb24gICA9IDc0IFtkZWZhdWx0ID0gImhlbGxvIl07CisgIG9wdGlvbmFsICAgIGJ5dGVzIGRlZmF1bHRfYnl0ZXNfZXh0ZW5zaW9uICAgID0gNzUgW2RlZmF1bHQgPSAid29ybGQiXTsKKworICBvcHRpb25hbCBUZXN0QWxsVHlwZXMuTmVzdGVkRW51bQorICAgIGRlZmF1bHRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uID0gODEgW2RlZmF1bHQgPSBCQVJdOworICBvcHRpb25hbCBGb3JlaWduRW51bQorICAgIGRlZmF1bHRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbiA9IDgyIFtkZWZhdWx0ID0gRk9SRUlHTl9CQVJdOworICBvcHRpb25hbCBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0RW51bQorICAgIGRlZmF1bHRfaW1wb3J0X2VudW1fZXh0ZW5zaW9uID0gODMgW2RlZmF1bHQgPSBJTVBPUlRfQkFSXTsKKworICBvcHRpb25hbCBzdHJpbmcgZGVmYXVsdF9zdHJpbmdfcGllY2VfZXh0ZW5zaW9uID0gODQgW2N0eXBlPVNUUklOR19QSUVDRSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0PSJhYmMiXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGRlZmF1bHRfY29yZF9leHRlbnNpb24gPSA4NSBbY3R5cGU9Q09SRCwgZGVmYXVsdD0iMTIzIl07CisKKyAgLy8gRm9yIG9uZW9mIHRlc3QKKyAgb3B0aW9uYWwgdWludDMyIG9uZW9mX3VpbnQzMl9leHRlbnNpb24gPSAxMTE7CisgIG9wdGlvbmFsIFRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9uZW9mX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbiA9IDExMjsKKyAgb3B0aW9uYWwgc3RyaW5nIG9uZW9mX3N0cmluZ19leHRlbnNpb24gPSAxMTM7CisgIG9wdGlvbmFsIGJ5dGVzIG9uZW9mX2J5dGVzX2V4dGVuc2lvbiA9IDExNDsKK30KKworbWVzc2FnZSBUZXN0TmVzdGVkRXh0ZW5zaW9uIHsKKyAgZXh0ZW5kIFRlc3RBbGxFeHRlbnNpb25zIHsKKyAgICAvLyBDaGVjayBmb3IgYnVnIHdoZXJlIHN0cmluZyBleHRlbnNpb25zIGRlY2xhcmVkIGluIHRlc3RlZCBzY29wZSBkaWQgbm90CisgICAgLy8gY29tcGlsZS4KKyAgICBvcHRpb25hbCBzdHJpbmcgdGVzdCA9IDEwMDIgW2RlZmF1bHQ9InRlc3QiXTsKKyAgICAvLyBVc2VkIHRvIHRlc3QgaWYgZ2VuZXJhdGVkIGV4dGVuc2lvbiBuYW1lIGlzIGNvcnJlY3Qgd2hlbiB0aGVyZSBhcmUKKyAgICAvLyB1bmRlcnNjb3Jlcy4KKyAgICBvcHRpb25hbCBzdHJpbmcgbmVzdGVkX3N0cmluZ19leHRlbnNpb24gPSAxMDAzOworICB9Cit9CisKKy8vIFdlIGhhdmUgc2VwYXJhdGUgbWVzc2FnZXMgZm9yIHRlc3RpbmcgcmVxdWlyZWQgZmllbGRzIGJlY2F1c2UgaXQncworLy8gYW5ub3lpbmcgdG8gaGF2ZSB0byBmaWxsIGluIHJlcXVpcmVkIGZpZWxkcyBpbiBUZXN0UHJvdG8gaW4gb3JkZXIgdG8KKy8vIGRvIGFueXRoaW5nIHdpdGggaXQuICBOb3RlIHRoYXQgd2UgZG9uJ3QgbmVlZCB0byB0ZXN0IGV2ZXJ5IHR5cGUgb2YKKy8vIHJlcXVpcmVkIGZpbGVkIGJlY2F1c2UgdGhlIGNvZGUgb3V0cHV0IGlzIGJhc2ljYWxseSBpZGVudGljYWwgdG8KKy8vIG9wdGlvbmFsIGZpZWxkcyBmb3IgYWxsIHR5cGVzLgorbWVzc2FnZSBUZXN0UmVxdWlyZWQgeworICByZXF1aXJlZCBpbnQzMiBhID0gMTsKKyAgb3B0aW9uYWwgaW50MzIgZHVtbXkyID0gMjsKKyAgcmVxdWlyZWQgaW50MzIgYiA9IDM7CisKKyAgZXh0ZW5kIFRlc3RBbGxFeHRlbnNpb25zIHsKKyAgICBvcHRpb25hbCBUZXN0UmVxdWlyZWQgc2luZ2xlID0gMTAwMDsKKyAgICByZXBlYXRlZCBUZXN0UmVxdWlyZWQgbXVsdGkgID0gMTAwMTsKKyAgfQorCisgIC8vIFBhZCB0aGUgZmllbGQgY291bnQgdG8gMzIgc28gdGhhdCB3ZSBjYW4gdGVzdCB0aGF0IElzSW5pdGlhbGl6ZWQoKQorICAvLyBwcm9wZXJseSBjaGVja3MgbXVsdGlwbGUgZWxlbWVudHMgb2YgaGFzX2JpdHNfLgorICBvcHRpb25hbCBpbnQzMiBkdW1teTQgID0gIDQ7CisgIG9wdGlvbmFsIGludDMyIGR1bW15NSAgPSAgNTsKKyAgb3B0aW9uYWwgaW50MzIgZHVtbXk2ICA9ICA2OworICBvcHRpb25hbCBpbnQzMiBkdW1teTcgID0gIDc7CisgIG9wdGlvbmFsIGludDMyIGR1bW15OCAgPSAgODsKKyAgb3B0aW9uYWwgaW50MzIgZHVtbXk5ICA9ICA5OworICBvcHRpb25hbCBpbnQzMiBkdW1teTEwID0gMTA7CisgIG9wdGlvbmFsIGludDMyIGR1bW15MTEgPSAxMTsKKyAgb3B0aW9uYWwgaW50MzIgZHVtbXkxMiA9IDEyOworICBvcHRpb25hbCBpbnQzMiBkdW1teTEzID0gMTM7CisgIG9wdGlvbmFsIGludDMyIGR1bW15MTQgPSAxNDsKKyAgb3B0aW9uYWwgaW50MzIgZHVtbXkxNSA9IDE1OworICBvcHRpb25hbCBpbnQzMiBkdW1teTE2ID0gMTY7CisgIG9wdGlvbmFsIGludDMyIGR1bW15MTcgPSAxNzsKKyAgb3B0aW9uYWwgaW50MzIgZHVtbXkxOCA9IDE4OworICBvcHRpb25hbCBpbnQzMiBkdW1teTE5ID0gMTk7CisgIG9wdGlvbmFsIGludDMyIGR1bW15MjAgPSAyMDsKKyAgb3B0aW9uYWwgaW50MzIgZHVtbXkyMSA9IDIxOworICBvcHRpb25hbCBpbnQzMiBkdW1teTIyID0gMjI7CisgIG9wdGlvbmFsIGludDMyIGR1bW15MjMgPSAyMzsKKyAgb3B0aW9uYWwgaW50MzIgZHVtbXkyNCA9IDI0OworICBvcHRpb25hbCBpbnQzMiBkdW1teTI1ID0gMjU7CisgIG9wdGlvbmFsIGludDMyIGR1bW15MjYgPSAyNjsKKyAgb3B0aW9uYWwgaW50MzIgZHVtbXkyNyA9IDI3OworICBvcHRpb25hbCBpbnQzMiBkdW1teTI4ID0gMjg7CisgIG9wdGlvbmFsIGludDMyIGR1bW15MjkgPSAyOTsKKyAgb3B0aW9uYWwgaW50MzIgZHVtbXkzMCA9IDMwOworICBvcHRpb25hbCBpbnQzMiBkdW1teTMxID0gMzE7CisgIG9wdGlvbmFsIGludDMyIGR1bW15MzIgPSAzMjsKKworICByZXF1aXJlZCBpbnQzMiBjID0gMzM7Cit9CisKK21lc3NhZ2UgVGVzdFJlcXVpcmVkRm9yZWlnbiB7CisgIG9wdGlvbmFsIFRlc3RSZXF1aXJlZCBvcHRpb25hbF9tZXNzYWdlID0gMTsKKyAgcmVwZWF0ZWQgVGVzdFJlcXVpcmVkIHJlcGVhdGVkX21lc3NhZ2UgPSAyOworICBvcHRpb25hbCBpbnQzMiBkdW1teSA9IDM7Cit9CisKKy8vIFRlc3QgdGhhdCB3ZSBjYW4gdXNlIE5lc3RlZE1lc3NhZ2UgZnJvbSBvdXRzaWRlIFRlc3RBbGxUeXBlcy4KK21lc3NhZ2UgVGVzdEZvcmVpZ25OZXN0ZWQgeworICBvcHRpb25hbCBUZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBmb3JlaWduX25lc3RlZCA9IDE7Cit9CisKKy8vIFRlc3RFbXB0eU1lc3NhZ2UgaXMgdXNlZCB0byB0ZXN0IHVua25vd24gZmllbGQgc3VwcG9ydC4KK21lc3NhZ2UgVGVzdEVtcHR5TWVzc2FnZSB7Cit9CisKKy8vIExpa2UgYWJvdmUsIGJ1dCBkZWNsYXJlIGFsbCBmaWVsZCBudW1iZXJzIGFzIHBvdGVudGlhbCBleHRlbnNpb25zLiAgTm8KKy8vIGFjdHVhbCBleHRlbnNpb25zIHNob3VsZCBldmVyIGJlIGRlZmluZWQgZm9yIHRoaXMgdHlwZS4KK21lc3NhZ2UgVGVzdEVtcHR5TWVzc2FnZVdpdGhFeHRlbnNpb25zIHsKKyAgZXh0ZW5zaW9ucyAxIHRvIG1heDsKK30KKworbWVzc2FnZSBUZXN0TXVsdGlwbGVFeHRlbnNpb25SYW5nZXMgeworICBleHRlbnNpb25zIDQyOworICBleHRlbnNpb25zIDQxNDMgdG8gNDI0MzsKKyAgZXh0ZW5zaW9ucyA2NTUzNiB0byBtYXg7Cit9CisKKy8vIFRlc3QgdGhhdCByZWFsbHkgbGFyZ2UgdGFnIG51bWJlcnMgZG9uJ3QgYnJlYWsgYW55dGhpbmcuCittZXNzYWdlIFRlc3RSZWFsbHlMYXJnZVRhZ051bWJlciB7CisgIC8vIFRoZSBsYXJnZXN0IHBvc3NpYmxlIHRhZyBudW1iZXIgaXMgMl4yOCAtIDEsIHNpbmNlIHRoZSB3aXJlIGZvcm1hdCB1c2VzCisgIC8vIHRocmVlIGJpdHMgdG8gY29tbXVuaWNhdGUgd2lyZSB0eXBlLgorICBvcHRpb25hbCBpbnQzMiBhID0gMTsKKyAgb3B0aW9uYWwgaW50MzIgYmIgPSAyNjg0MzU0NTU7Cit9CisKK21lc3NhZ2UgVGVzdFJlY3Vyc2l2ZU1lc3NhZ2UgeworICBvcHRpb25hbCBUZXN0UmVjdXJzaXZlTWVzc2FnZSBhID0gMTsKKyAgb3B0aW9uYWwgaW50MzIgaSA9IDI7Cit9CisKKy8vIFRlc3QgdGhhdCBtdXR1YWwgcmVjdXJzaW9uIHdvcmtzLgorbWVzc2FnZSBUZXN0TXV0dWFsUmVjdXJzaW9uQSB7CisgIG9wdGlvbmFsIFRlc3RNdXR1YWxSZWN1cnNpb25CIGJiID0gMTsKK30KKworbWVzc2FnZSBUZXN0TXV0dWFsUmVjdXJzaW9uQiB7CisgIG9wdGlvbmFsIFRlc3RNdXR1YWxSZWN1cnNpb25BIGEgPSAxOworICBvcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMiA9IDI7Cit9CisKKy8vIFRlc3QgdGhhdCBncm91cHMgaGF2ZSBkaXNqb2ludCBmaWVsZCBudW1iZXJzIGZyb20gdGhlaXIgc2libGluZ3MgYW5kCisvLyBwYXJlbnRzLiAgVGhpcyBpcyBOT1QgcG9zc2libGUgaW4gcHJvdG8xOyBvbmx5IGdvb2dsZS5wcm90b2J1Zi4gIFdoZW4gYXR0ZW1wdGluZworLy8gdG8gY29tcGlsZSB3aXRoIHByb3RvMSwgdGhpcyB3aWxsIGVtaXQgYW4gZXJyb3I7IHNvIHdlIG9ubHkgaW5jbHVkZSBpdAorLy8gaW4gcHJvdG9idWZfdW5pdHRlc3RfcHJvdG8uCittZXNzYWdlIFRlc3REdXBGaWVsZE51bWJlciB7ICAgICAgICAgICAgICAgICAgICAgICAgLy8gTk9fUFJPVE8xCisgIG9wdGlvbmFsIGludDMyIGEgPSAxOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTk9fUFJPVE8xCisgIG9wdGlvbmFsIGdyb3VwIEZvbyA9IDIgeyBvcHRpb25hbCBpbnQzMiBhID0gMTsgfSAgLy8gTk9fUFJPVE8xCisgIG9wdGlvbmFsIGdyb3VwIEJhciA9IDMgeyBvcHRpb25hbCBpbnQzMiBhID0gMTsgfSAgLy8gTk9fUFJPVE8xCit9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTk9fUFJPVE8xCisKKy8vIEFkZGl0aW9uYWwgbWVzc2FnZXMgZm9yIHRlc3RpbmcgbGF6eSBmaWVsZHMuCittZXNzYWdlIFRlc3RFYWdlck1lc3NhZ2UgeworICBvcHRpb25hbCBUZXN0QWxsVHlwZXMgc3ViX21lc3NhZ2UgPSAxIFtsYXp5PWZhbHNlXTsKK30KK21lc3NhZ2UgVGVzdExhenlNZXNzYWdlIHsKKyAgb3B0aW9uYWwgVGVzdEFsbFR5cGVzIHN1Yl9tZXNzYWdlID0gMSBbbGF6eT10cnVlXTsKK30KKworLy8gTmVlZGVkIGZvciBhIFB5dGhvbiB0ZXN0LgorbWVzc2FnZSBUZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMgeworICBtZXNzYWdlIE5lc3RlZE1lc3NhZ2UgeworICAgIHJlcGVhdGVkIGludDMyIG5lc3RlZG1lc3NhZ2VfcmVwZWF0ZWRfaW50MzIgPSAxOworICAgIHJlcGVhdGVkIEZvcmVpZ25NZXNzYWdlIG5lc3RlZG1lc3NhZ2VfcmVwZWF0ZWRfZm9yZWlnbm1lc3NhZ2UgPSAyOworICB9CisgIG9wdGlvbmFsIE5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxOworfQorCisKKy8vIFRlc3QgYW4gZW51bSB0aGF0IGhhcyBtdWx0aXBsZSB2YWx1ZXMgd2l0aCB0aGUgc2FtZSBudW1iZXIuCitlbnVtIFRlc3RFbnVtV2l0aER1cFZhbHVlIHsKKyAgb3B0aW9uIGFsbG93X2FsaWFzID0gdHJ1ZTsKKworICBGT08xID0gMTsKKyAgQkFSMSA9IDI7CisgIEJBWiA9IDM7CisgIEZPTzIgPSAxOworICBCQVIyID0gMjsKK30KKworLy8gVGVzdCBhbiBlbnVtIHdpdGggbGFyZ2UsIHVub3JkZXJlZCB2YWx1ZXMuCitlbnVtIFRlc3RTcGFyc2VFbnVtIHsKKyAgU1BBUlNFX0EgPSAxMjM7CisgIFNQQVJTRV9CID0gNjIzNzQ7CisgIFNQQVJTRV9DID0gMTI1ODkyMzQ7CisgIFNQQVJTRV9EID0gLTE1OworICBTUEFSU0VfRSA9IC01MzQ1MjsKKyAgU1BBUlNFX0YgPSAwOworICBTUEFSU0VfRyA9IDI7Cit9CisKKy8vIFRlc3QgbWVzc2FnZSB3aXRoIENhbWVsQ2FzZSBmaWVsZCBuYW1lcy4gIFRoaXMgdmlvbGF0ZXMgUHJvdG9jb2wgQnVmZmVyCisvLyBzdGFuZGFyZCBzdHlsZS4KK21lc3NhZ2UgVGVzdENhbWVsQ2FzZUZpZWxkTmFtZXMgeworICBvcHRpb25hbCBpbnQzMiBQcmltaXRpdmVGaWVsZCA9IDE7CisgIG9wdGlvbmFsIHN0cmluZyBTdHJpbmdGaWVsZCA9IDI7CisgIG9wdGlvbmFsIEZvcmVpZ25FbnVtIEVudW1GaWVsZCA9IDM7CisgIG9wdGlvbmFsIEZvcmVpZ25NZXNzYWdlIE1lc3NhZ2VGaWVsZCA9IDQ7CisgIG9wdGlvbmFsIHN0cmluZyBTdHJpbmdQaWVjZUZpZWxkID0gNSBbY3R5cGU9U1RSSU5HX1BJRUNFXTsKKyAgb3B0aW9uYWwgc3RyaW5nIENvcmRGaWVsZCA9IDYgW2N0eXBlPUNPUkRdOworCisgIHJlcGVhdGVkIGludDMyIFJlcGVhdGVkUHJpbWl0aXZlRmllbGQgPSA3OworICByZXBlYXRlZCBzdHJpbmcgUmVwZWF0ZWRTdHJpbmdGaWVsZCA9IDg7CisgIHJlcGVhdGVkIEZvcmVpZ25FbnVtIFJlcGVhdGVkRW51bUZpZWxkID0gOTsKKyAgcmVwZWF0ZWQgRm9yZWlnbk1lc3NhZ2UgUmVwZWF0ZWRNZXNzYWdlRmllbGQgPSAxMDsKKyAgcmVwZWF0ZWQgc3RyaW5nIFJlcGVhdGVkU3RyaW5nUGllY2VGaWVsZCA9IDExIFtjdHlwZT1TVFJJTkdfUElFQ0VdOworICByZXBlYXRlZCBzdHJpbmcgUmVwZWF0ZWRDb3JkRmllbGQgPSAxMiBbY3R5cGU9Q09SRF07Cit9CisKKworLy8gV2UgbGlzdCBmaWVsZHMgb3V0IG9mIG9yZGVyLCB0byBlbnN1cmUgdGhhdCB3ZSdyZSB1c2luZyBmaWVsZCBudW1iZXIgYW5kIG5vdAorLy8gZmllbGQgaW5kZXggdG8gZGV0ZXJtaW5lIHNlcmlhbGl6YXRpb24gb3JkZXIuCittZXNzYWdlIFRlc3RGaWVsZE9yZGVyaW5ncyB7CisgIG9wdGlvbmFsIHN0cmluZyBteV9zdHJpbmcgPSAxMTsKKyAgZXh0ZW5zaW9ucyAyIHRvIDEwOworICBvcHRpb25hbCBpbnQ2NCBteV9pbnQgPSAxOworICBleHRlbnNpb25zIDEyIHRvIDEwMDsKKyAgb3B0aW9uYWwgZmxvYXQgbXlfZmxvYXQgPSAxMDE7CisgIG1lc3NhZ2UgTmVzdGVkTWVzc2FnZSB7CisgICAgb3B0aW9uYWwgaW50NjQgb28gPSAyOworICAgIC8vIFRoZSBmaWVsZCBuYW1lICJiIiBmYWlscyB0byBjb21waWxlIGluIHByb3RvMSBiZWNhdXNlIGl0IGNvbmZsaWN0cyB3aXRoCisgICAgLy8gYSBsb2NhbCB2YXJpYWJsZSBuYW1lZCAiYiIgaW4gb25lIG9mIHRoZSBnZW5lcmF0ZWQgbWV0aG9kcy4gIERvaC4KKyAgICAvLyBUaGlzIGZpbGUgbmVlZHMgdG8gY29tcGlsZSBpbiBwcm90bzEgdG8gdGVzdCBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eS4KKyAgICBvcHRpb25hbCBpbnQzMiBiYiA9IDE7CisgIH0KKworICBvcHRpb25hbCBOZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlICA9IDIwMDsKK30KKworCitleHRlbmQgVGVzdEZpZWxkT3JkZXJpbmdzIHsKKyAgb3B0aW9uYWwgc3RyaW5nIG15X2V4dGVuc2lvbl9zdHJpbmcgPSA1MDsKKyAgb3B0aW9uYWwgaW50MzIgbXlfZXh0ZW5zaW9uX2ludCA9IDU7Cit9CisKKworbWVzc2FnZSBUZXN0RXh0cmVtZURlZmF1bHRWYWx1ZXMgeworICBvcHRpb25hbCBieXRlcyBlc2NhcGVkX2J5dGVzID0gMSBbZGVmYXVsdCA9ICJcMFwwMDFcYVxiXGZcblxyXHRcdlxcXCdcIlx4ZmUiXTsKKyAgb3B0aW9uYWwgdWludDMyIGxhcmdlX3VpbnQzMiA9IDIgW2RlZmF1bHQgPSAweEZGRkZGRkZGXTsKKyAgb3B0aW9uYWwgdWludDY0IGxhcmdlX3VpbnQ2NCA9IDMgW2RlZmF1bHQgPSAweEZGRkZGRkZGRkZGRkZGRkZdOworICBvcHRpb25hbCAgaW50MzIgc21hbGxfaW50MzIgID0gNCBbZGVmYXVsdCA9IC0weDdGRkZGRkZGXTsKKyAgb3B0aW9uYWwgIGludDY0IHNtYWxsX2ludDY0ICA9IDUgW2RlZmF1bHQgPSAtMHg3RkZGRkZGRkZGRkZGRkZGXTsKKyAgb3B0aW9uYWwgIGludDMyIHJlYWxseV9zbWFsbF9pbnQzMiA9IDIxIFtkZWZhdWx0ID0gLTB4ODAwMDAwMDBdOworICBvcHRpb25hbCAgaW50NjQgcmVhbGx5X3NtYWxsX2ludDY0ID0gMjIgW2RlZmF1bHQgPSAtMHg4MDAwMDAwMDAwMDAwMDAwXTsKKworICAvLyBUaGUgZGVmYXVsdCB2YWx1ZSBoZXJlIGlzIFVURi04IGZvciAiXHUxMjM0Ii4gIChXZSBjb3VsZCBhbHNvIGp1c3QgdHlwZQorICAvLyB0aGUgVVRGLTggdGV4dCBkaXJlY3RseSBpbnRvIHRoaXMgdGV4dCBmaWxlIHJhdGhlciB0aGFuIGVzY2FwZSBpdCwgYnV0CisgIC8vIGxvdHMgb2YgcGVvcGxlIHVzZSBlZGl0b3JzIHRoYXQgd291bGQgYmUgY29uZnVzZWQgYnkgdGhpcy4pCisgIG9wdGlvbmFsIHN0cmluZyB1dGY4X3N0cmluZyA9IDYgW2RlZmF1bHQgPSAiXDM0MVwyMTBcMjY0Il07CisKKyAgLy8gVGVzdHMgZm9yIHNpbmdsZS1wcmVjaXNpb24gZmxvYXRpbmctcG9pbnQgdmFsdWVzLgorICBvcHRpb25hbCBmbG9hdCB6ZXJvX2Zsb2F0ID0gNyBbZGVmYXVsdCA9IDBdOworICBvcHRpb25hbCBmbG9hdCBvbmVfZmxvYXQgPSA4IFtkZWZhdWx0ID0gMV07CisgIG9wdGlvbmFsIGZsb2F0IHNtYWxsX2Zsb2F0ID0gOSBbZGVmYXVsdCA9IDEuNV07CisgIG9wdGlvbmFsIGZsb2F0IG5lZ2F0aXZlX29uZV9mbG9hdCA9IDEwIFtkZWZhdWx0ID0gLTFdOworICBvcHRpb25hbCBmbG9hdCBuZWdhdGl2ZV9mbG9hdCA9IDExIFtkZWZhdWx0ID0gLTEuNV07CisgIC8vIFVzaW5nIGV4cG9uZW50cworICBvcHRpb25hbCBmbG9hdCBsYXJnZV9mbG9hdCA9IDEyIFtkZWZhdWx0ID0gMkU4XTsKKyAgb3B0aW9uYWwgZmxvYXQgc21hbGxfbmVnYXRpdmVfZmxvYXQgPSAxMyBbZGVmYXVsdCA9IC04ZS0yOF07CisKKyAgLy8gVGV4dCBmb3Igbm9uZmluaXRlIGZsb2F0aW5nLXBvaW50IHZhbHVlcy4KKyAgb3B0aW9uYWwgZG91YmxlIGluZl9kb3VibGUgPSAxNCBbZGVmYXVsdCA9IGluZl07CisgIG9wdGlvbmFsIGRvdWJsZSBuZWdfaW5mX2RvdWJsZSA9IDE1IFtkZWZhdWx0ID0gLWluZl07CisgIG9wdGlvbmFsIGRvdWJsZSBuYW5fZG91YmxlID0gMTYgW2RlZmF1bHQgPSBuYW5dOworICBvcHRpb25hbCBmbG9hdCBpbmZfZmxvYXQgPSAxNyBbZGVmYXVsdCA9IGluZl07CisgIG9wdGlvbmFsIGZsb2F0IG5lZ19pbmZfZmxvYXQgPSAxOCBbZGVmYXVsdCA9IC1pbmZdOworICBvcHRpb25hbCBmbG9hdCBuYW5fZmxvYXQgPSAxOSBbZGVmYXVsdCA9IG5hbl07CisKKyAgLy8gVGVzdHMgZm9yIEMrKyB0cmlncmFwaHMuCisgIC8vIFRyaWdyYXBocyBzaG91bGQgYmUgZXNjYXBlZCBpbiBDKysgZ2VuZXJhdGVkIGZpbGVzLCBidXQgdGhleSBzaG91bGQgbm90IGJlCisgIC8vIGVzY2FwZWQgZm9yIG90aGVyIGxhbmd1YWdlcy4KKyAgLy8gTm90ZSB0aGF0IGluIC5wcm90byBmaWxlLCAiXD8iIGlzIGEgdmFsaWQgd2F5IHRvIGVzY2FwZSA/IGluIHN0cmluZworICAvLyBsaXRlcmFscy4KKyAgb3B0aW9uYWwgc3RyaW5nIGNwcF90cmlncmFwaCA9IDIwIFtkZWZhdWx0ID0gIj8gXD8gPz8gXD8/IFw/Pz8gPz8vID9cPy0iXTsKKworICAvLyBTdHJpbmcgZGVmYXVsdHMgY29udGFpbmluZyB0aGUgY2hhcmFjdGVyICdcMDAwJworICBvcHRpb25hbCBzdHJpbmcgc3RyaW5nX3dpdGhfemVybyAgICAgICA9IDIzIFtkZWZhdWx0ID0gImhlbFwwMDBsbyJdOworICBvcHRpb25hbCAgYnl0ZXMgYnl0ZXNfd2l0aF96ZXJvICAgICAgICA9IDI0IFtkZWZhdWx0ID0gIndvclwwMDBsZCJdOworICBvcHRpb25hbCBzdHJpbmcgc3RyaW5nX3BpZWNlX3dpdGhfemVybyA9IDI1IFtjdHlwZT1TVFJJTkdfUElFQ0UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ9ImFiXDAwMGMiXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGNvcmRfd2l0aF96ZXJvICAgICAgICAgPSAyNiBbY3R5cGU9Q09SRCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdD0iMTJcMDAwMyJdOworICBvcHRpb25hbCBzdHJpbmcgcmVwbGFjZW1lbnRfc3RyaW5nICAgICA9IDI3IFtkZWZhdWx0PSIke3Vua25vd259Il07Cit9CisKK21lc3NhZ2UgU3BhcnNlRW51bU1lc3NhZ2UgeworICBvcHRpb25hbCBUZXN0U3BhcnNlRW51bSBzcGFyc2VfZW51bSA9IDE7Cit9CisKKy8vIFRlc3QgU3RyaW5nIGFuZCBCeXRlczogc3RyaW5nIGlzIGZvciB2YWxpZCBVVEYtOCBzdHJpbmdzCittZXNzYWdlIE9uZVN0cmluZyB7CisgIG9wdGlvbmFsIHN0cmluZyBkYXRhID0gMTsKK30KKworbWVzc2FnZSBNb3JlU3RyaW5nIHsKKyAgcmVwZWF0ZWQgc3RyaW5nIGRhdGEgPSAxOworfQorCittZXNzYWdlIE9uZUJ5dGVzIHsKKyAgb3B0aW9uYWwgYnl0ZXMgZGF0YSA9IDE7Cit9CisKK21lc3NhZ2UgTW9yZUJ5dGVzIHsKKyAgcmVwZWF0ZWQgYnl0ZXMgZGF0YSA9IDE7Cit9CisKKy8vIFRlc3QgaW50MzIsIHVpbnQzMiwgaW50NjQsIHVpbnQ2NCwgYW5kIGJvb2wgYXJlIGFsbCBjb21wYXRpYmxlCittZXNzYWdlIEludDMyTWVzc2FnZSB7CisgIG9wdGlvbmFsIGludDMyIGRhdGEgPSAxOworfQorCittZXNzYWdlIFVpbnQzMk1lc3NhZ2UgeworICBvcHRpb25hbCB1aW50MzIgZGF0YSA9IDE7Cit9CisKK21lc3NhZ2UgSW50NjRNZXNzYWdlIHsKKyAgb3B0aW9uYWwgaW50NjQgZGF0YSA9IDE7Cit9CisKK21lc3NhZ2UgVWludDY0TWVzc2FnZSB7CisgIG9wdGlvbmFsIHVpbnQ2NCBkYXRhID0gMTsKK30KKworbWVzc2FnZSBCb29sTWVzc2FnZSB7CisgIG9wdGlvbmFsIGJvb2wgZGF0YSA9IDE7Cit9CisKKy8vIFRlc3Qgb25lb2ZzLgorbWVzc2FnZSBUZXN0T25lb2YgeworICBvbmVvZiBmb28geworICAgIGludDMyIGZvb19pbnQgPSAxOworICAgIHN0cmluZyBmb29fc3RyaW5nID0gMjsKKyAgICBUZXN0QWxsVHlwZXMgZm9vX21lc3NhZ2UgPSAzOworICAgIGdyb3VwIEZvb0dyb3VwID0gNCB7CisgICAgICBvcHRpb25hbCBpbnQzMiBhID0gNTsKKyAgICAgIG9wdGlvbmFsIHN0cmluZyBiID0gNjsKKyAgICB9CisgIH0KK30KKworbWVzc2FnZSBUZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlIHsKKyAgb3B0aW9uYWwgaW50MzIgZm9vX2ludCA9IDE7CisgIG9wdGlvbmFsIHN0cmluZyBmb29fc3RyaW5nID0gMjsKKyAgb3B0aW9uYWwgVGVzdEFsbFR5cGVzIGZvb19tZXNzYWdlID0gMzsKKyAgb3B0aW9uYWwgZ3JvdXAgRm9vR3JvdXAgPSA0IHsKKyAgICBvcHRpb25hbCBpbnQzMiBhID0gNTsKKyAgICBvcHRpb25hbCBzdHJpbmcgYiA9IDY7CisgIH0KK30KKworbWVzc2FnZSBUZXN0T25lb2YyIHsKKyAgb25lb2YgZm9vIHsKKyAgICBpbnQzMiBmb29faW50ID0gMTsKKyAgICBzdHJpbmcgZm9vX3N0cmluZyA9IDI7CisgICAgc3RyaW5nIGZvb19jb3JkID0gMyBbY3R5cGU9Q09SRF07CisgICAgc3RyaW5nIGZvb19zdHJpbmdfcGllY2UgPSA0IFtjdHlwZT1TVFJJTkdfUElFQ0VdOworICAgIGJ5dGVzIGZvb19ieXRlcyA9IDU7CisgICAgTmVzdGVkRW51bSBmb29fZW51bSA9IDY7CisgICAgTmVzdGVkTWVzc2FnZSBmb29fbWVzc2FnZSA9IDc7CisgICAgZ3JvdXAgRm9vR3JvdXAgPSA4IHsKKyAgICAgIG9wdGlvbmFsIGludDMyIGEgPSA5OworICAgICAgb3B0aW9uYWwgc3RyaW5nIGIgPSAxMDsKKyAgICB9CisgICAgTmVzdGVkTWVzc2FnZSBmb29fbGF6eV9tZXNzYWdlID0gMTEgW2xhenk9dHJ1ZV07CisgIH0KKworICBvbmVvZiBiYXIgeworICAgIGludDMyIGJhcl9pbnQgPSAxMiBbZGVmYXVsdCA9IDVdOworICAgIHN0cmluZyBiYXJfc3RyaW5nID0gMTMgW2RlZmF1bHQgPSAiU1RSSU5HIl07CisgICAgc3RyaW5nIGJhcl9jb3JkID0gMTQgW2N0eXBlPUNPUkQsIGRlZmF1bHQgPSAiQ09SRCJdOworICAgIHN0cmluZyBiYXJfc3RyaW5nX3BpZWNlID0gMTUgW2N0eXBlPVNUUklOR19QSUVDRSwgZGVmYXVsdCA9ICJTUElFQ0UiXTsKKyAgICBieXRlcyBiYXJfYnl0ZXMgPSAxNiBbZGVmYXVsdCA9ICJCWVRFUyJdOworICAgIE5lc3RlZEVudW0gYmFyX2VudW0gPSAxNyBbZGVmYXVsdCA9IEJBUl07CisgIH0KKworICBvcHRpb25hbCBpbnQzMiBiYXpfaW50ID0gMTg7CisgIG9wdGlvbmFsIHN0cmluZyBiYXpfc3RyaW5nID0gMTkgW2RlZmF1bHQgPSAiQkFaIl07CisKKyAgbWVzc2FnZSBOZXN0ZWRNZXNzYWdlIHsKKyAgICBvcHRpb25hbCBpbnQ2NCBxdXhfaW50ID0gMTsKKyAgICByZXBlYXRlZCBpbnQzMiBjb3JnZV9pbnQgPSAyOworICB9CisKKyAgZW51bSBOZXN0ZWRFbnVtIHsKKyAgICBGT08gPSAxOworICAgIEJBUiA9IDI7CisgICAgQkFaID0gMzsKKyAgfQorfQorCittZXNzYWdlIFRlc3RSZXF1aXJlZE9uZW9mIHsKKyAgb25lb2YgZm9vIHsKKyAgICBpbnQzMiBmb29faW50ID0gMTsKKyAgICBzdHJpbmcgZm9vX3N0cmluZyA9IDI7CisgICAgTmVzdGVkTWVzc2FnZSBmb29fbWVzc2FnZSA9IDM7CisgIH0KKyAgbWVzc2FnZSBOZXN0ZWRNZXNzYWdlIHsKKyAgICByZXF1aXJlZCBkb3VibGUgcmVxdWlyZWRfZG91YmxlID0gMTsKKyAgfQorfQorCisvLyBUZXN0IG1lc3NhZ2VzIGZvciBwYWNrZWQgZmllbGRzCisKK21lc3NhZ2UgVGVzdFBhY2tlZFR5cGVzIHsKKyAgcmVwZWF0ZWQgICAgaW50MzIgcGFja2VkX2ludDMyICAgID0gIDkwIFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgICAgaW50NjQgcGFja2VkX2ludDY0ICAgID0gIDkxIFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgICB1aW50MzIgcGFja2VkX3VpbnQzMiAgID0gIDkyIFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgICB1aW50NjQgcGFja2VkX3VpbnQ2NCAgID0gIDkzIFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgICBzaW50MzIgcGFja2VkX3NpbnQzMiAgID0gIDk0IFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgICBzaW50NjQgcGFja2VkX3NpbnQ2NCAgID0gIDk1IFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgIGZpeGVkMzIgcGFja2VkX2ZpeGVkMzIgID0gIDk2IFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgIGZpeGVkNjQgcGFja2VkX2ZpeGVkNjQgID0gIDk3IFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgc2ZpeGVkMzIgcGFja2VkX3NmaXhlZDMyID0gIDk4IFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgc2ZpeGVkNjQgcGFja2VkX3NmaXhlZDY0ID0gIDk5IFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgICAgZmxvYXQgcGFja2VkX2Zsb2F0ICAgID0gMTAwIFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgICBkb3VibGUgcGFja2VkX2RvdWJsZSAgID0gMTAxIFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgICAgIGJvb2wgcGFja2VkX2Jvb2wgICAgID0gMTAyIFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgRm9yZWlnbkVudW0gcGFja2VkX2VudW0gID0gMTAzIFtwYWNrZWQgPSB0cnVlXTsKK30KKworLy8gQSBtZXNzYWdlIHdpdGggdGhlIHNhbWUgZmllbGRzIGFzIFRlc3RQYWNrZWRUeXBlcywgYnV0IHdpdGhvdXQgcGFja2luZy4gVXNlZAorLy8gdG8gdGVzdCBwYWNrZWQgPC0+IHVucGFja2VkIHdpcmUgY29tcGF0aWJpbGl0eS4KK21lc3NhZ2UgVGVzdFVucGFja2VkVHlwZXMgeworICByZXBlYXRlZCAgICBpbnQzMiB1bnBhY2tlZF9pbnQzMiAgICA9ICA5MCBbcGFja2VkID0gZmFsc2VdOworICByZXBlYXRlZCAgICBpbnQ2NCB1bnBhY2tlZF9pbnQ2NCAgICA9ICA5MSBbcGFja2VkID0gZmFsc2VdOworICByZXBlYXRlZCAgIHVpbnQzMiB1bnBhY2tlZF91aW50MzIgICA9ICA5MiBbcGFja2VkID0gZmFsc2VdOworICByZXBlYXRlZCAgIHVpbnQ2NCB1bnBhY2tlZF91aW50NjQgICA9ICA5MyBbcGFja2VkID0gZmFsc2VdOworICByZXBlYXRlZCAgIHNpbnQzMiB1bnBhY2tlZF9zaW50MzIgICA9ICA5NCBbcGFja2VkID0gZmFsc2VdOworICByZXBlYXRlZCAgIHNpbnQ2NCB1bnBhY2tlZF9zaW50NjQgICA9ICA5NSBbcGFja2VkID0gZmFsc2VdOworICByZXBlYXRlZCAgZml4ZWQzMiB1bnBhY2tlZF9maXhlZDMyICA9ICA5NiBbcGFja2VkID0gZmFsc2VdOworICByZXBlYXRlZCAgZml4ZWQ2NCB1bnBhY2tlZF9maXhlZDY0ICA9ICA5NyBbcGFja2VkID0gZmFsc2VdOworICByZXBlYXRlZCBzZml4ZWQzMiB1bnBhY2tlZF9zZml4ZWQzMiA9ICA5OCBbcGFja2VkID0gZmFsc2VdOworICByZXBlYXRlZCBzZml4ZWQ2NCB1bnBhY2tlZF9zZml4ZWQ2NCA9ICA5OSBbcGFja2VkID0gZmFsc2VdOworICByZXBlYXRlZCAgICBmbG9hdCB1bnBhY2tlZF9mbG9hdCAgICA9IDEwMCBbcGFja2VkID0gZmFsc2VdOworICByZXBlYXRlZCAgIGRvdWJsZSB1bnBhY2tlZF9kb3VibGUgICA9IDEwMSBbcGFja2VkID0gZmFsc2VdOworICByZXBlYXRlZCAgICAgYm9vbCB1bnBhY2tlZF9ib29sICAgICA9IDEwMiBbcGFja2VkID0gZmFsc2VdOworICByZXBlYXRlZCBGb3JlaWduRW51bSB1bnBhY2tlZF9lbnVtICA9IDEwMyBbcGFja2VkID0gZmFsc2VdOworfQorCittZXNzYWdlIFRlc3RQYWNrZWRFeHRlbnNpb25zIHsKKyAgZXh0ZW5zaW9ucyAxIHRvIG1heDsKK30KKworZXh0ZW5kIFRlc3RQYWNrZWRFeHRlbnNpb25zIHsKKyAgcmVwZWF0ZWQgICAgaW50MzIgcGFja2VkX2ludDMyX2V4dGVuc2lvbiAgICA9ICA5MCBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkICAgIGludDY0IHBhY2tlZF9pbnQ2NF9leHRlbnNpb24gICAgPSAgOTEgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCAgIHVpbnQzMiBwYWNrZWRfdWludDMyX2V4dGVuc2lvbiAgID0gIDkyIFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgICB1aW50NjQgcGFja2VkX3VpbnQ2NF9leHRlbnNpb24gICA9ICA5MyBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkICAgc2ludDMyIHBhY2tlZF9zaW50MzJfZXh0ZW5zaW9uICAgPSAgOTQgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCAgIHNpbnQ2NCBwYWNrZWRfc2ludDY0X2V4dGVuc2lvbiAgID0gIDk1IFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgIGZpeGVkMzIgcGFja2VkX2ZpeGVkMzJfZXh0ZW5zaW9uICA9ICA5NiBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkICBmaXhlZDY0IHBhY2tlZF9maXhlZDY0X2V4dGVuc2lvbiAgPSAgOTcgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCBzZml4ZWQzMiBwYWNrZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uID0gIDk4IFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgc2ZpeGVkNjQgcGFja2VkX3NmaXhlZDY0X2V4dGVuc2lvbiA9ICA5OSBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkICAgIGZsb2F0IHBhY2tlZF9mbG9hdF9leHRlbnNpb24gICAgPSAxMDAgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCAgIGRvdWJsZSBwYWNrZWRfZG91YmxlX2V4dGVuc2lvbiAgID0gMTAxIFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgICAgIGJvb2wgcGFja2VkX2Jvb2xfZXh0ZW5zaW9uICAgICA9IDEwMiBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkIEZvcmVpZ25FbnVtIHBhY2tlZF9lbnVtX2V4dGVuc2lvbiAgPSAxMDMgW3BhY2tlZCA9IHRydWVdOworfQorCittZXNzYWdlIFRlc3RVbnBhY2tlZEV4dGVuc2lvbnMgeworICBleHRlbnNpb25zIDEgdG8gbWF4OworfQorCitleHRlbmQgVGVzdFVucGFja2VkRXh0ZW5zaW9ucyB7CisgIHJlcGVhdGVkICAgIGludDMyIHVucGFja2VkX2ludDMyX2V4dGVuc2lvbiAgICA9ICA5MCBbcGFja2VkID0gZmFsc2VdOworICByZXBlYXRlZCAgICBpbnQ2NCB1bnBhY2tlZF9pbnQ2NF9leHRlbnNpb24gICAgPSAgOTEgW3BhY2tlZCA9IGZhbHNlXTsKKyAgcmVwZWF0ZWQgICB1aW50MzIgdW5wYWNrZWRfdWludDMyX2V4dGVuc2lvbiAgID0gIDkyIFtwYWNrZWQgPSBmYWxzZV07CisgIHJlcGVhdGVkICAgdWludDY0IHVucGFja2VkX3VpbnQ2NF9leHRlbnNpb24gICA9ICA5MyBbcGFja2VkID0gZmFsc2VdOworICByZXBlYXRlZCAgIHNpbnQzMiB1bnBhY2tlZF9zaW50MzJfZXh0ZW5zaW9uICAgPSAgOTQgW3BhY2tlZCA9IGZhbHNlXTsKKyAgcmVwZWF0ZWQgICBzaW50NjQgdW5wYWNrZWRfc2ludDY0X2V4dGVuc2lvbiAgID0gIDk1IFtwYWNrZWQgPSBmYWxzZV07CisgIHJlcGVhdGVkICBmaXhlZDMyIHVucGFja2VkX2ZpeGVkMzJfZXh0ZW5zaW9uICA9ICA5NiBbcGFja2VkID0gZmFsc2VdOworICByZXBlYXRlZCAgZml4ZWQ2NCB1bnBhY2tlZF9maXhlZDY0X2V4dGVuc2lvbiAgPSAgOTcgW3BhY2tlZCA9IGZhbHNlXTsKKyAgcmVwZWF0ZWQgc2ZpeGVkMzIgdW5wYWNrZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uID0gIDk4IFtwYWNrZWQgPSBmYWxzZV07CisgIHJlcGVhdGVkIHNmaXhlZDY0IHVucGFja2VkX3NmaXhlZDY0X2V4dGVuc2lvbiA9ICA5OSBbcGFja2VkID0gZmFsc2VdOworICByZXBlYXRlZCAgICBmbG9hdCB1bnBhY2tlZF9mbG9hdF9leHRlbnNpb24gICAgPSAxMDAgW3BhY2tlZCA9IGZhbHNlXTsKKyAgcmVwZWF0ZWQgICBkb3VibGUgdW5wYWNrZWRfZG91YmxlX2V4dGVuc2lvbiAgID0gMTAxIFtwYWNrZWQgPSBmYWxzZV07CisgIHJlcGVhdGVkICAgICBib29sIHVucGFja2VkX2Jvb2xfZXh0ZW5zaW9uICAgICA9IDEwMiBbcGFja2VkID0gZmFsc2VdOworICByZXBlYXRlZCBGb3JlaWduRW51bSB1bnBhY2tlZF9lbnVtX2V4dGVuc2lvbiAgPSAxMDMgW3BhY2tlZCA9IGZhbHNlXTsKK30KKworLy8gVXNlZCBieSBFeHRlbnNpb25TZXRUZXN0L0R5bmFtaWNFeHRlbnNpb25zLiAgVGhlIHRlc3QgYWN0dWFsbHkgYnVpbGRzCisvLyBhIHNldCBvZiBleHRlbnNpb25zIHRvIFRlc3RBbGxFeHRlbnNpb25zIGR5bmFtaWNhbGx5LCBiYXNlZCBvbiB0aGUgZmllbGRzCisvLyBvZiB0aGlzIG1lc3NhZ2UgdHlwZS4KK21lc3NhZ2UgVGVzdER5bmFtaWNFeHRlbnNpb25zIHsKKyAgZW51bSBEeW5hbWljRW51bVR5cGUgeworICAgIERZTkFNSUNfRk9PID0gMjIwMDsKKyAgICBEWU5BTUlDX0JBUiA9IDIyMDE7CisgICAgRFlOQU1JQ19CQVogPSAyMjAyOworICB9CisgIG1lc3NhZ2UgRHluYW1pY01lc3NhZ2VUeXBlIHsKKyAgICBvcHRpb25hbCBpbnQzMiBkeW5hbWljX2ZpZWxkID0gMjEwMDsKKyAgfQorCisgIG9wdGlvbmFsIGZpeGVkMzIgc2NhbGFyX2V4dGVuc2lvbiA9IDIwMDA7CisgIG9wdGlvbmFsIEZvcmVpZ25FbnVtIGVudW1fZXh0ZW5zaW9uID0gMjAwMTsKKyAgb3B0aW9uYWwgRHluYW1pY0VudW1UeXBlIGR5bmFtaWNfZW51bV9leHRlbnNpb24gPSAyMDAyOworCisgIG9wdGlvbmFsIEZvcmVpZ25NZXNzYWdlIG1lc3NhZ2VfZXh0ZW5zaW9uID0gMjAwMzsKKyAgb3B0aW9uYWwgRHluYW1pY01lc3NhZ2VUeXBlIGR5bmFtaWNfbWVzc2FnZV9leHRlbnNpb24gPSAyMDA0OworCisgIHJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9leHRlbnNpb24gPSAyMDA1OworICByZXBlYXRlZCBzaW50MzIgcGFja2VkX2V4dGVuc2lvbiA9IDIwMDYgW3BhY2tlZCA9IHRydWVdOworfQorCittZXNzYWdlIFRlc3RSZXBlYXRlZFNjYWxhckRpZmZlcmVudFRhZ1NpemVzIHsKKyAgLy8gUGFyc2luZyByZXBlYXRlZCBmaXhlZCBzaXplIHZhbHVlcyB1c2VkIHRvIGZhaWwuIFRoaXMgbWVzc2FnZSBuZWVkcyB0byBiZQorICAvLyB1c2VkIGluIG9yZGVyIHRvIGdldCBhIHRhZyBvZiB0aGUgcmlnaHQgc2l6ZTsgYWxsIG9mIHRoZSByZXBlYXRlZCBmaWVsZHMKKyAgLy8gaW4gVGVzdEFsbFR5cGVzIGRpZG4ndCB0cmlnZ2VyIHRoZSBjaGVjay4KKyAgcmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gMTI7CisgIC8vIENoZWNrIGZvciBhIHZhcmludCB0eXBlLCBqdXN0IGZvciBnb29kIG1lYXN1cmUuCisgIHJlcGVhdGVkIGludDMyICAgcmVwZWF0ZWRfaW50MzIgICA9IDEzOworCisgIC8vIFRoZXNlIGhhdmUgdHdvLWJ5dGUgdGFncy4KKyAgcmVwZWF0ZWQgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ID0gMjA0NjsKKyAgcmVwZWF0ZWQgaW50NjQgICByZXBlYXRlZF9pbnQ2NCAgID0gMjA0NzsKKworICAvLyBUaHJlZSBieXRlIHRhZ3MuCisgIHJlcGVhdGVkIGZsb2F0ICAgcmVwZWF0ZWRfZmxvYXQgICA9IDI2MjE0MjsKKyAgcmVwZWF0ZWQgdWludDY0ICByZXBlYXRlZF91aW50NjQgID0gMjYyMTQzOworfQorCisvLyBUZXN0IHRoYXQgaWYgYW4gb3B0aW9uYWwgb3IgcmVxdWlyZWQgbWVzc2FnZS9ncm91cCBmaWVsZCBhcHBlYXJzIG11bHRpcGxlCisvLyB0aW1lcyBpbiB0aGUgaW5wdXQsIHRoZXkgbmVlZCB0byBiZSBtZXJnZWQuCittZXNzYWdlIFRlc3RQYXJzaW5nTWVyZ2UgeworICAvLyBSZXBlYXRlZEZpZWxkc0dlbmVyYXRvciBkZWZpbmVzIG1hdGNoaW5nIGZpZWxkIHR5cGVzIGFzIFRlc3RQYXJzaW5nTWVyZ2UsCisgIC8vIGV4Y2VwdCB0aGF0IGFsbCBmaWVsZHMgYXJlIHJlcGVhdGVkLiBJbiB0aGUgdGVzdHMsIHdlIHdpbGwgc2VyaWFsaXplIHRoZQorICAvLyBSZXBlYXRlZEZpZWxkc0dlbmVyYXRvciB0byBieXRlcywgYW5kIHBhcnNlIHRoZSBieXRlcyB0byBUZXN0UGFyc2luZ01lcmdlLgorICAvLyBSZXBlYXRlZCBmaWVsZHMgaW4gUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IgYXJlIGV4cGVjdGVkIHRvIGJlIG1lcmdlZCBpbnRvCisgIC8vIHRoZSBjb3JyZXNwb25kaW5nIHJlcXVpcmVkL29wdGlvbmFsIGZpZWxkcyBpbiBUZXN0UGFyc2luZ01lcmdlLgorICBtZXNzYWdlIFJlcGVhdGVkRmllbGRzR2VuZXJhdG9yIHsKKyAgICByZXBlYXRlZCBUZXN0QWxsVHlwZXMgZmllbGQxID0gMTsKKyAgICByZXBlYXRlZCBUZXN0QWxsVHlwZXMgZmllbGQyID0gMjsKKyAgICByZXBlYXRlZCBUZXN0QWxsVHlwZXMgZmllbGQzID0gMzsKKyAgICByZXBlYXRlZCBncm91cCBHcm91cDEgPSAxMCB7CisgICAgICBvcHRpb25hbCBUZXN0QWxsVHlwZXMgZmllbGQxID0gMTE7CisgICAgfQorICAgIHJlcGVhdGVkIGdyb3VwIEdyb3VwMiA9IDIwIHsKKyAgICAgIG9wdGlvbmFsIFRlc3RBbGxUeXBlcyBmaWVsZDEgPSAyMTsKKyAgICB9CisgICAgcmVwZWF0ZWQgVGVzdEFsbFR5cGVzIGV4dDEgPSAxMDAwOworICAgIHJlcGVhdGVkIFRlc3RBbGxUeXBlcyBleHQyID0gMTAwMTsKKyAgfQorICByZXF1aXJlZCBUZXN0QWxsVHlwZXMgcmVxdWlyZWRfYWxsX3R5cGVzID0gMTsKKyAgb3B0aW9uYWwgVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDI7CisgIHJlcGVhdGVkIFRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAzOworICBvcHRpb25hbCBncm91cCBPcHRpb25hbEdyb3VwID0gMTAgeworICAgIG9wdGlvbmFsIFRlc3RBbGxUeXBlcyBvcHRpb25hbF9ncm91cF9hbGxfdHlwZXMgPSAxMTsKKyAgfQorICByZXBlYXRlZCBncm91cCBSZXBlYXRlZEdyb3VwID0gMjAgeworICAgIG9wdGlvbmFsIFRlc3RBbGxUeXBlcyByZXBlYXRlZF9ncm91cF9hbGxfdHlwZXMgPSAyMTsKKyAgfQorICBleHRlbnNpb25zIDEwMDAgdG8gbWF4OworICBleHRlbmQgVGVzdFBhcnNpbmdNZXJnZSB7CisgICAgb3B0aW9uYWwgVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2V4dCA9IDEwMDA7CisgICAgcmVwZWF0ZWQgVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2V4dCA9IDEwMDE7CisgIH0KK30KKworbWVzc2FnZSBUZXN0Q29tbWVudEluamVjdGlvbk1lc3NhZ2UgeworICAvLyAqLyA8LSBUaGlzIHNob3VsZCBub3QgY2xvc2UgdGhlIGdlbmVyYXRlZCBkb2MgY29tbWVudAorICBvcHRpb25hbCBzdHJpbmcgYSA9IDEgW2RlZmF1bHQ9IiovIDwtIE5laXRoZXIgc2hvdWxkIHRoaXMuIl07Cit9CisKKworLy8gVGVzdCB0aGF0IFJQQyBzZXJ2aWNlcyB3b3JrLgorbWVzc2FnZSBGb29SZXF1ZXN0ICB7fQorbWVzc2FnZSBGb29SZXNwb25zZSB7fQorCittZXNzYWdlIEZvb0NsaWVudE1lc3NhZ2Uge30KK21lc3NhZ2UgRm9vU2VydmVyTWVzc2FnZXt9CisKK3NlcnZpY2UgVGVzdFNlcnZpY2UgeworICBycGMgRm9vKEZvb1JlcXVlc3QpIHJldHVybnMgKEZvb1Jlc3BvbnNlKTsKKyAgcnBjIEJhcihCYXJSZXF1ZXN0KSByZXR1cm5zIChCYXJSZXNwb25zZSk7Cit9CisKKworbWVzc2FnZSBCYXJSZXF1ZXN0ICB7fQorbWVzc2FnZSBCYXJSZXNwb25zZSB7fQorCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2FyZW5hLnByb3RvIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9hcmVuYS5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jZDdlNDM3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9hcmVuYS5wcm90bwpAQCAtMCwwICsxLDQ2IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworc3ludGF4ID0gInByb3RvMiI7CisKK2ltcG9ydCAiZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X25vX2FyZW5hX2ltcG9ydC5wcm90byI7CisKK3BhY2thZ2UgcHJvdG8yX2FyZW5hX3VuaXR0ZXN0OworCitvcHRpb24gY2NfZW5hYmxlX2FyZW5hcyA9IHRydWU7CisKK21lc3NhZ2UgTmVzdGVkTWVzc2FnZSB7CisgIG9wdGlvbmFsIGludDMyIGQgPSAxOworfQorCittZXNzYWdlIEFyZW5hTWVzc2FnZSB7CisgIHJlcGVhdGVkIE5lc3RlZE1lc3NhZ2UgIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gMTsKKyAgcmVwZWF0ZWQgSW1wb3J0Tm9BcmVuYU5lc3RlZE1lc3NhZ2UgIHJlcGVhdGVkX2ltcG9ydF9ub19hcmVuYV9tZXNzYWdlID0gMjsKK307CmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2N1c3RvbV9vcHRpb25zLnByb3RvIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9jdXN0b21fb3B0aW9ucy5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40Y2MwZTM2Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9jdXN0b21fb3B0aW9ucy5wcm90bwpAQCAtMCwwICsxLDQyMSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjogYmVuanlAZ29vZ2xlLmNvbSAoQmVuankgV2VpbmJlcmdlcikKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorLy8KKy8vIEEgcHJvdG8gZmlsZSB1c2VkIHRvIHRlc3QgdGhlICJjdXN0b20gb3B0aW9ucyIgZmVhdHVyZSBvZiBnb29nbGUucHJvdG9idWYuCisKK3N5bnRheCA9ICJwcm90bzIiOworCisvLyBTb21lIGdlbmVyaWNfc2VydmljZXMgb3B0aW9uKHMpIGFkZGVkIGF1dG9tYXRpY2FsbHkuCisvLyBTZWU6ICBodHRwOi8vZ28vcHJvdG8yLWdlbmVyaWMtc2VydmljZXMtZGVmYXVsdAorb3B0aW9uIGNjX2dlbmVyaWNfc2VydmljZXMgPSB0cnVlOyAgICAgLy8gYXV0by1hZGRlZAorb3B0aW9uIGphdmFfZ2VuZXJpY19zZXJ2aWNlcyA9IHRydWU7ICAgLy8gYXV0by1hZGRlZAorb3B0aW9uIHB5X2dlbmVyaWNfc2VydmljZXMgPSB0cnVlOworCisvLyBBIGN1c3RvbSBmaWxlIG9wdGlvbiAoZGVmaW5lZCBiZWxvdykuCitvcHRpb24gKGZpbGVfb3B0MSkgPSA5ODc2NTQzMjEwOworCitpbXBvcnQgImdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvIjsKKworLy8gV2UgZG9uJ3QgcHV0IHRoaXMgaW4gYSBwYWNrYWdlIHdpdGhpbiBwcm90bzIgYmVjYXVzZSB3ZSBuZWVkIHRvIG1ha2Ugc3VyZQorLy8gdGhhdCB0aGUgZ2VuZXJhdGVkIGNvZGUgZG9lc24ndCBkZXBlbmQgb24gYmVpbmcgaW4gdGhlIHByb3RvMiBuYW1lc3BhY2UuCitwYWNrYWdlIHByb3RvYnVmX3VuaXR0ZXN0OworCisKKy8vIFNvbWUgc2ltcGxlIHRlc3QgY3VzdG9tIG9wdGlvbnMgb2YgdmFyaW91cyB0eXBlcy4KKworZXh0ZW5kIGdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucyB7CisgIG9wdGlvbmFsIHVpbnQ2NCBmaWxlX29wdDEgPSA3NzM2OTc0OworfQorCitleHRlbmQgZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zIHsKKyAgb3B0aW9uYWwgaW50MzIgbWVzc2FnZV9vcHQxID0gNzczOTAzNjsKK30KKworZXh0ZW5kIGdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMgeworICBvcHRpb25hbCBmaXhlZDY0IGZpZWxkX29wdDEgPSA3NzQwOTM2OworICAvLyBUaGlzIGlzIHVzZWZ1bCBmb3IgdGVzdGluZyB0aGF0IHdlIGNvcnJlY3RseSByZWdpc3RlciBkZWZhdWx0IHZhbHVlcyBmb3IKKyAgLy8gZXh0ZW5zaW9uIG9wdGlvbnMuCisgIG9wdGlvbmFsIGludDMyIGZpZWxkX29wdDIgPSA3NzUzOTEzIFtkZWZhdWx0PTQyXTsKK30KKworZXh0ZW5kIGdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucyB7CisgIG9wdGlvbmFsIHNmaXhlZDMyIGVudW1fb3B0MSA9IDc3NTM1NzY7Cit9CisKK2V4dGVuZCBnb29nbGUucHJvdG9idWYuRW51bVZhbHVlT3B0aW9ucyB7CisgIG9wdGlvbmFsIGludDMyIGVudW1fdmFsdWVfb3B0MSA9IDE1NjA2Nzg7Cit9CisKK2V4dGVuZCBnb29nbGUucHJvdG9idWYuU2VydmljZU9wdGlvbnMgeworICBvcHRpb25hbCBzaW50NjQgc2VydmljZV9vcHQxID0gNzg4NzY1MDsKK30KKworZW51bSBNZXRob2RPcHQxIHsKKyAgTUVUSE9ET1BUMV9WQUwxID0gMTsKKyAgTUVUSE9ET1BUMV9WQUwyID0gMjsKK30KKworZXh0ZW5kIGdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zIHsKKyAgb3B0aW9uYWwgTWV0aG9kT3B0MSBtZXRob2Rfb3B0MSA9IDc4OTA4NjA7Cit9CisKKy8vIEEgdGVzdCBtZXNzYWdlIHdpdGggY3VzdG9tIG9wdGlvbnMgYXQgYWxsIHBvc3NpYmxlIGxvY2F0aW9ucyAoYW5kIGFsc28gc29tZQorLy8gcmVndWxhciBvcHRpb25zLCB0byBtYWtlIHN1cmUgdGhleSBpbnRlcmFjdCBuaWNlbHkpLgorbWVzc2FnZSBUZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zIHsKKyAgb3B0aW9uIG1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0ID0gZmFsc2U7CisKKyAgb3B0aW9uIChtZXNzYWdlX29wdDEpID0gLTU2OworCisgIG9wdGlvbmFsIHN0cmluZyBmaWVsZDEgPSAxIFtjdHlwZT1DT1JELAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZpZWxkX29wdDEpPTg3NjU0MzIxMDldOworCisgIGVudW0gQW5FbnVtIHsKKyAgICBvcHRpb24gKGVudW1fb3B0MSkgPSAtNzg5OworCisgICAgQU5FTlVNX1ZBTDEgPSAxOworICAgIEFORU5VTV9WQUwyID0gMiBbKGVudW1fdmFsdWVfb3B0MSkgPSAxMjNdOworICB9Cit9CisKKworLy8gQSB0ZXN0IFJQQyBzZXJ2aWNlIHdpdGggY3VzdG9tIG9wdGlvbnMgYXQgYWxsIHBvc3NpYmxlIGxvY2F0aW9ucyAoYW5kIGFsc28KKy8vIHNvbWUgcmVndWxhciBvcHRpb25zLCB0byBtYWtlIHN1cmUgdGhleSBpbnRlcmFjdCBuaWNlbHkpLgorbWVzc2FnZSBDdXN0b21PcHRpb25Gb29SZXF1ZXN0IHsKK30KKworbWVzc2FnZSBDdXN0b21PcHRpb25Gb29SZXNwb25zZSB7Cit9CisKK21lc3NhZ2UgQ3VzdG9tT3B0aW9uRm9vQ2xpZW50TWVzc2FnZSB7Cit9CisKK21lc3NhZ2UgQ3VzdG9tT3B0aW9uRm9vU2VydmVyTWVzc2FnZSB7Cit9CisKK3NlcnZpY2UgVGVzdFNlcnZpY2VXaXRoQ3VzdG9tT3B0aW9ucyB7CisgIG9wdGlvbiAoc2VydmljZV9vcHQxKSA9IC05ODc2NTQzMjEwOworCisgIHJwYyBGb28oQ3VzdG9tT3B0aW9uRm9vUmVxdWVzdCkgcmV0dXJucyAoQ3VzdG9tT3B0aW9uRm9vUmVzcG9uc2UpIHsKKyAgICBvcHRpb24gKG1ldGhvZF9vcHQxKSA9IE1FVEhPRE9QVDFfVkFMMjsKKyAgfQorfQorCisKKworLy8gT3B0aW9ucyBvZiBldmVyeSBwb3NzaWJsZSBmaWVsZCB0eXBlLCBzbyB3ZSBjYW4gdGVzdCB0aGVtIGFsbCBleGhhdXN0aXZlbHkuCisKK21lc3NhZ2UgRHVtbXlNZXNzYWdlQ29udGFpbmluZ0VudW0geworICBlbnVtIFRlc3RFbnVtVHlwZSB7CisgICAgVEVTVF9PUFRJT05fRU5VTV9UWVBFMSA9IDIyOworICAgIFRFU1RfT1BUSU9OX0VOVU1fVFlQRTIgPSAtMjM7CisgIH0KK30KKworbWVzc2FnZSBEdW1teU1lc3NhZ2VJbnZhbGlkQXNPcHRpb25UeXBlIHsKK30KKworZXh0ZW5kIGdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucyB7CisgIG9wdGlvbmFsICAgICAgICAgYm9vbCAgICAgYm9vbF9vcHQgPSA3NzA2MDkwOworICBvcHRpb25hbCAgICAgICAgaW50MzIgICAgaW50MzJfb3B0ID0gNzcwNTcwOTsKKyAgb3B0aW9uYWwgICAgICAgIGludDY0ICAgIGludDY0X29wdCA9IDc3MDU1NDI7CisgIG9wdGlvbmFsICAgICAgIHVpbnQzMiAgIHVpbnQzMl9vcHQgPSA3NzA0ODgwOworICBvcHRpb25hbCAgICAgICB1aW50NjQgICB1aW50NjRfb3B0ID0gNzcwMjM2NzsKKyAgb3B0aW9uYWwgICAgICAgc2ludDMyICAgc2ludDMyX29wdCA9IDc3MDE1Njg7CisgIG9wdGlvbmFsICAgICAgIHNpbnQ2NCAgIHNpbnQ2NF9vcHQgPSA3NzAwODYzOworICBvcHRpb25hbCAgICAgIGZpeGVkMzIgIGZpeGVkMzJfb3B0ID0gNzcwMDMwNzsKKyAgb3B0aW9uYWwgICAgICBmaXhlZDY0ICBmaXhlZDY0X29wdCA9IDc3MDAxOTQ7CisgIG9wdGlvbmFsICAgICBzZml4ZWQzMiBzZml4ZWQzMl9vcHQgPSA3Njk4NjQ1OworICBvcHRpb25hbCAgICAgc2ZpeGVkNjQgc2ZpeGVkNjRfb3B0ID0gNzY4NTQ3NTsKKyAgb3B0aW9uYWwgICAgICAgIGZsb2F0ICAgIGZsb2F0X29wdCA9IDc2NzUzOTA7CisgIG9wdGlvbmFsICAgICAgIGRvdWJsZSAgIGRvdWJsZV9vcHQgPSA3NjczMjkzOworICBvcHRpb25hbCAgICAgICBzdHJpbmcgICBzdHJpbmdfb3B0ID0gNzY3MzI4NTsKKyAgb3B0aW9uYWwgICAgICAgIGJ5dGVzICAgIGJ5dGVzX29wdCA9IDc2NzMyMzg7CisgIG9wdGlvbmFsIER1bW15TWVzc2FnZUNvbnRhaW5pbmdFbnVtLlRlc3RFbnVtVHlwZSBlbnVtX29wdCA9IDc2NzMyMzM7CisgIG9wdGlvbmFsIER1bW15TWVzc2FnZUludmFsaWRBc09wdGlvblR5cGUgbWVzc2FnZV90eXBlX29wdCA9IDc2NjU5Njc7Cit9CisKK21lc3NhZ2UgQ3VzdG9tT3B0aW9uTWluSW50ZWdlclZhbHVlcyB7CisgIG9wdGlvbiAgICAgKGJvb2xfb3B0KSA9IGZhbHNlOworICBvcHRpb24gICAgKGludDMyX29wdCkgPSAtMHg4MDAwMDAwMDsKKyAgb3B0aW9uICAgIChpbnQ2NF9vcHQpID0gLTB4ODAwMDAwMDAwMDAwMDAwMDsKKyAgb3B0aW9uICAgKHVpbnQzMl9vcHQpID0gMDsKKyAgb3B0aW9uICAgKHVpbnQ2NF9vcHQpID0gMDsKKyAgb3B0aW9uICAgKHNpbnQzMl9vcHQpID0gLTB4ODAwMDAwMDA7CisgIG9wdGlvbiAgIChzaW50NjRfb3B0KSA9IC0weDgwMDAwMDAwMDAwMDAwMDA7CisgIG9wdGlvbiAgKGZpeGVkMzJfb3B0KSA9IDA7CisgIG9wdGlvbiAgKGZpeGVkNjRfb3B0KSA9IDA7CisgIG9wdGlvbiAoc2ZpeGVkMzJfb3B0KSA9IC0weDgwMDAwMDAwOworICBvcHRpb24gKHNmaXhlZDY0X29wdCkgPSAtMHg4MDAwMDAwMDAwMDAwMDAwOworfQorCittZXNzYWdlIEN1c3RvbU9wdGlvbk1heEludGVnZXJWYWx1ZXMgeworICBvcHRpb24gICAgIChib29sX29wdCkgPSB0cnVlOworICBvcHRpb24gICAgKGludDMyX29wdCkgPSAweDdGRkZGRkZGOworICBvcHRpb24gICAgKGludDY0X29wdCkgPSAweDdGRkZGRkZGRkZGRkZGRkY7CisgIG9wdGlvbiAgICh1aW50MzJfb3B0KSA9IDB4RkZGRkZGRkY7CisgIG9wdGlvbiAgICh1aW50NjRfb3B0KSA9IDB4RkZGRkZGRkZGRkZGRkZGRjsKKyAgb3B0aW9uICAgKHNpbnQzMl9vcHQpID0gMHg3RkZGRkZGRjsKKyAgb3B0aW9uICAgKHNpbnQ2NF9vcHQpID0gMHg3RkZGRkZGRkZGRkZGRkZGOworICBvcHRpb24gIChmaXhlZDMyX29wdCkgPSAweEZGRkZGRkZGOworICBvcHRpb24gIChmaXhlZDY0X29wdCkgPSAweEZGRkZGRkZGRkZGRkZGRkY7CisgIG9wdGlvbiAoc2ZpeGVkMzJfb3B0KSA9IDB4N0ZGRkZGRkY7CisgIG9wdGlvbiAoc2ZpeGVkNjRfb3B0KSA9IDB4N0ZGRkZGRkZGRkZGRkZGRjsKK30KKworbWVzc2FnZSBDdXN0b21PcHRpb25PdGhlclZhbHVlcyB7CisgIG9wdGlvbiAgKGludDMyX29wdCkgPSAtMTAwOyAgLy8gVG8gdGVzdCBzaWduLWV4dGVuc2lvbi4KKyAgb3B0aW9uICAoZmxvYXRfb3B0KSA9IDEyLjM0NTY3ODk7CisgIG9wdGlvbiAoZG91YmxlX29wdCkgPSAxLjIzNDU2Nzg5MDEyMzQ1Njc4OTsKKyAgb3B0aW9uIChzdHJpbmdfb3B0KSA9ICJIZWxsbywgXCJXb3JsZFwiIjsKKyAgb3B0aW9uICAoYnl0ZXNfb3B0KSA9ICJIZWxsb1wwV29ybGQiOworICBvcHRpb24gICAoZW51bV9vcHQpID0gVEVTVF9PUFRJT05fRU5VTV9UWVBFMjsKK30KKworbWVzc2FnZSBTZXR0aW5nUmVhbHNGcm9tUG9zaXRpdmVJbnRzIHsKKyAgb3B0aW9uICAoZmxvYXRfb3B0KSA9IDEyOworICBvcHRpb24gKGRvdWJsZV9vcHQpID0gMTU0OworfQorCittZXNzYWdlIFNldHRpbmdSZWFsc0Zyb21OZWdhdGl2ZUludHMgeworICBvcHRpb24gIChmbG9hdF9vcHQpID0gLTEyOworICBvcHRpb24gIChkb3VibGVfb3B0KSA9IC0xNTQ7Cit9CisKKy8vIE9wdGlvbnMgb2YgY29tcGxleCBtZXNzYWdlIHR5cGVzLCB0aGVtc2VsdmVzIGNvbWJpbmVkIGFuZCBleHRlbmRlZCBpbgorLy8gdmFyaW91cyB3YXlzLgorCittZXNzYWdlIENvbXBsZXhPcHRpb25UeXBlMSB7CisgIG9wdGlvbmFsIGludDMyIGZvbyA9IDE7CisgIG9wdGlvbmFsIGludDMyIGZvbzIgPSAyOworICBvcHRpb25hbCBpbnQzMiBmb28zID0gMzsKKyAgcmVwZWF0ZWQgaW50MzIgZm9vNCA9IDQ7CisKKyAgZXh0ZW5zaW9ucyAxMDAgdG8gbWF4OworfQorCittZXNzYWdlIENvbXBsZXhPcHRpb25UeXBlMiB7CisgIG9wdGlvbmFsIENvbXBsZXhPcHRpb25UeXBlMSBiYXIgPSAxOworICBvcHRpb25hbCBpbnQzMiBiYXogPSAyOworCisgIG1lc3NhZ2UgQ29tcGxleE9wdGlvblR5cGU0IHsKKyAgICBvcHRpb25hbCBpbnQzMiB3YWxkbyA9IDE7CisKKyAgICBleHRlbmQgZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zIHsKKyAgICAgIG9wdGlvbmFsIENvbXBsZXhPcHRpb25UeXBlNCBjb21wbGV4X29wdDQgPSA3NjMzNTQ2OworICAgIH0KKyAgfQorCisgIG9wdGlvbmFsIENvbXBsZXhPcHRpb25UeXBlNCBmcmVkID0gMzsKKyAgcmVwZWF0ZWQgQ29tcGxleE9wdGlvblR5cGU0IGJhcm5leSA9IDQ7CisKKyAgZXh0ZW5zaW9ucyAxMDAgdG8gbWF4OworfQorCittZXNzYWdlIENvbXBsZXhPcHRpb25UeXBlMyB7CisgIG9wdGlvbmFsIGludDMyIHF1eCA9IDE7CisKKyAgb3B0aW9uYWwgZ3JvdXAgQ29tcGxleE9wdGlvblR5cGU1ID0gMiB7CisgICAgb3B0aW9uYWwgaW50MzIgcGx1Z2ggPSAzOworICB9Cit9CisKK2V4dGVuZCBDb21wbGV4T3B0aW9uVHlwZTEgeworICBvcHRpb25hbCBpbnQzMiBxdXV4ID0gNzY2MzcwNzsKKyAgb3B0aW9uYWwgQ29tcGxleE9wdGlvblR5cGUzIGNvcmdlID0gNzY2MzQ0MjsKK30KKworZXh0ZW5kIENvbXBsZXhPcHRpb25UeXBlMiB7CisgIG9wdGlvbmFsIGludDMyIGdyYXVsdCA9IDc2NTA5Mjc7CisgIG9wdGlvbmFsIENvbXBsZXhPcHRpb25UeXBlMSBnYXJwbHkgPSA3NjQ5OTkyOworfQorCitleHRlbmQgZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zIHsKKyAgb3B0aW9uYWwgcHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdGlvblR5cGUxIGNvbXBsZXhfb3B0MSA9IDc2NDY3NTY7CisgIG9wdGlvbmFsIENvbXBsZXhPcHRpb25UeXBlMiBjb21wbGV4X29wdDIgPSA3NjM2OTQ5OworICBvcHRpb25hbCBDb21wbGV4T3B0aW9uVHlwZTMgY29tcGxleF9vcHQzID0gNzYzNjQ2MzsKKyAgb3B0aW9uYWwgZ3JvdXAgQ29tcGxleE9wdDYgPSA3NTk1NDY4IHsKKyAgICBvcHRpb25hbCBpbnQzMiB4eXp6eSA9IDc1OTM5NTE7CisgIH0KK30KKworLy8gTm90ZSB0aGF0IHdlIHRyeSB2YXJpb3VzIGRpZmZlcmVudCB3YXlzIG9mIG5hbWluZyB0aGUgc2FtZSBleHRlbnNpb24uCittZXNzYWdlIFZhcmlvdXNDb21wbGV4T3B0aW9ucyB7CisgIG9wdGlvbiAoLnByb3RvYnVmX3VuaXR0ZXN0LmNvbXBsZXhfb3B0MSkuZm9vID0gNDI7CisgIG9wdGlvbiAocHJvdG9idWZfdW5pdHRlc3QuY29tcGxleF9vcHQxKS4oLnByb3RvYnVmX3VuaXR0ZXN0LnF1dXgpID0gMzI0OworICBvcHRpb24gKC5wcm90b2J1Zl91bml0dGVzdC5jb21wbGV4X29wdDEpLihwcm90b2J1Zl91bml0dGVzdC5jb3JnZSkucXV4ID0gODc2OworICBvcHRpb24gKHByb3RvYnVmX3VuaXR0ZXN0LmNvbXBsZXhfb3B0MSkuZm9vNCA9IDk5OworICBvcHRpb24gKHByb3RvYnVmX3VuaXR0ZXN0LmNvbXBsZXhfb3B0MSkuZm9vNCA9IDg4OworICBvcHRpb24gKGNvbXBsZXhfb3B0MikuYmF6ID0gOTg3OworICBvcHRpb24gKGNvbXBsZXhfb3B0MikuKGdyYXVsdCkgPSA2NTQ7CisgIG9wdGlvbiAoY29tcGxleF9vcHQyKS5iYXIuZm9vID0gNzQzOworICBvcHRpb24gKGNvbXBsZXhfb3B0MikuYmFyLihxdXV4KSA9IDE5OTk7CisgIG9wdGlvbiAoY29tcGxleF9vcHQyKS5iYXIuKHByb3RvYnVmX3VuaXR0ZXN0LmNvcmdlKS5xdXggPSAyMDA4OworICBvcHRpb24gKGNvbXBsZXhfb3B0MikuKGdhcnBseSkuZm9vID0gNzQxOworICBvcHRpb24gKGNvbXBsZXhfb3B0MikuKGdhcnBseSkuKC5wcm90b2J1Zl91bml0dGVzdC5xdXV4KSA9IDE5OTg7CisgIG9wdGlvbiAoY29tcGxleF9vcHQyKS4ocHJvdG9idWZfdW5pdHRlc3QuZ2FycGx5KS4oY29yZ2UpLnF1eCA9IDIxMjE7CisgIG9wdGlvbiAoQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNC5jb21wbGV4X29wdDQpLndhbGRvID0gMTk3MTsKKyAgb3B0aW9uIChjb21wbGV4X29wdDIpLmZyZWQud2FsZG8gPSAzMjE7CisgIG9wdGlvbiAoY29tcGxleF9vcHQyKS5iYXJuZXkgPSB7IHdhbGRvOiAxMDEgfTsKKyAgb3B0aW9uIChjb21wbGV4X29wdDIpLmJhcm5leSA9IHsgd2FsZG86IDIxMiB9OworICBvcHRpb24gKHByb3RvYnVmX3VuaXR0ZXN0LmNvbXBsZXhfb3B0MykucXV4ID0gOTsKKyAgb3B0aW9uIChjb21wbGV4X29wdDMpLmNvbXBsZXhvcHRpb250eXBlNS5wbHVnaCA9IDIyOworICBvcHRpb24gKGNvbXBsZXhvcHQ2KS54eXp6eSA9IDI0OworfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vIERlZmluaXRpb25zIGZvciB0ZXN0aW5nIGFnZ3JlZ2F0ZSBvcHRpb24gcGFyc2luZy4KKy8vIFNlZSBkZXNjcmlwdG9yX3VuaXR0ZXN0LmNjLgorCittZXNzYWdlIEFnZ3JlZ2F0ZU1lc3NhZ2VTZXQgeworICBvcHRpb24gbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQgPSB0cnVlOworICBleHRlbnNpb25zIDQgdG8gbWF4OworfQorCittZXNzYWdlIEFnZ3JlZ2F0ZU1lc3NhZ2VTZXRFbGVtZW50IHsKKyAgZXh0ZW5kIEFnZ3JlZ2F0ZU1lc3NhZ2VTZXQgeworICAgIG9wdGlvbmFsIEFnZ3JlZ2F0ZU1lc3NhZ2VTZXRFbGVtZW50IG1lc3NhZ2Vfc2V0X2V4dGVuc2lvbiA9IDE1NDQ3NTQyOworICB9CisgIG9wdGlvbmFsIHN0cmluZyBzID0gMTsKK30KKworLy8gQSBoZWxwZXIgdHlwZSB1c2VkIHRvIHRlc3QgYWdncmVnYXRlIG9wdGlvbiBwYXJzaW5nCittZXNzYWdlIEFnZ3JlZ2F0ZSB7CisgIG9wdGlvbmFsIGludDMyIGkgPSAxOworICBvcHRpb25hbCBzdHJpbmcgcyA9IDI7CisKKyAgLy8gQSBuZXN0ZWQgb2JqZWN0CisgIG9wdGlvbmFsIEFnZ3JlZ2F0ZSBzdWIgPSAzOworCisgIC8vIFRvIHRlc3QgdGhlIHBhcnNpbmcgb2YgZXh0ZW5zaW9ucyBpbnNpZGUgYWdncmVnYXRlIHZhbHVlcworICBvcHRpb25hbCBnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMgZmlsZSA9IDQ7CisgIGV4dGVuZCBnb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMgeworICAgIG9wdGlvbmFsIEFnZ3JlZ2F0ZSBuZXN0ZWQgPSAxNTQ3NjkwMzsKKyAgfQorCisgIC8vIEFuIGVtYmVkZGVkIG1lc3NhZ2Ugc2V0CisgIG9wdGlvbmFsIEFnZ3JlZ2F0ZU1lc3NhZ2VTZXQgbXNldCA9IDU7Cit9CisKKy8vIEFsbG93IEFnZ3JlZ2F0ZSB0byBiZSB1c2VkIGFzIGFuIG9wdGlvbiBhdCBhbGwgcG9zc2libGUgbG9jYXRpb25zCisvLyBpbiB0aGUgLnByb3RvIGdyYW1tZXIuCitleHRlbmQgZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zICAgICAgeyBvcHRpb25hbCBBZ2dyZWdhdGUgZmlsZW9wdCAgICA9IDE1NDc4NDc5OyB9CitleHRlbmQgZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zICAgeyBvcHRpb25hbCBBZ2dyZWdhdGUgbXNnb3B0ICAgICA9IDE1NDgwMDg4OyB9CitleHRlbmQgZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucyAgICAgeyBvcHRpb25hbCBBZ2dyZWdhdGUgZmllbGRvcHQgICA9IDE1NDgxMzc0OyB9CitleHRlbmQgZ29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zICAgICAgeyBvcHRpb25hbCBBZ2dyZWdhdGUgZW51bW9wdCAgICA9IDE1NDgzMjE4OyB9CitleHRlbmQgZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnMgeyBvcHRpb25hbCBBZ2dyZWdhdGUgZW51bXZhbG9wdCA9IDE1NDg2OTIxOyB9CitleHRlbmQgZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zICAgeyBvcHRpb25hbCBBZ2dyZWdhdGUgc2VydmljZW9wdCA9IDE1NDk3MTQ1OyB9CitleHRlbmQgZ29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMgICAgeyBvcHRpb25hbCBBZ2dyZWdhdGUgbWV0aG9kb3B0ICA9IDE1NTEyNzEzOyB9CisKKy8vIFRyeSB1c2luZyBBZ2dyZWdhdGVPcHRpb24gYXQgZGlmZmVyZW50IHBvaW50cyBpbiB0aGUgcHJvdG8gZ3JhbW1hcgorb3B0aW9uIChmaWxlb3B0KSA9IHsKKyAgczogJ0ZpbGVBbm5vdGF0aW9uJworICAvLyBBbHNvIHRlc3QgdGhlIGhhbmRsaW5nIG9mIGNvbW1lbnRzCisgIC8qIG9mIGJvdGggdHlwZXMgKi8gaTogMTAwCisKKyAgc3ViIHsgczogJ05lc3RlZEZpbGVBbm5vdGF0aW9uJyB9CisKKyAgLy8gSW5jbHVkZSBhIGdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucyBhbmQgcmVjdXJzaXZlbHkgZXh0ZW5kIGl0IHdpdGgKKyAgLy8gYW5vdGhlciBmaWxlb3B0LgorICBmaWxlIHsKKyAgICBbcHJvdG9idWZfdW5pdHRlc3QuZmlsZW9wdF0geworICAgICAgczonRmlsZUV4dGVuc2lvbkFubm90YXRpb24nCisgICAgfQorICB9CisKKyAgLy8gQSBtZXNzYWdlIHNldCBpbnNpZGUgYW4gb3B0aW9uIHZhbHVlCisgIG1zZXQgeworICAgIFtwcm90b2J1Zl91bml0dGVzdC5BZ2dyZWdhdGVNZXNzYWdlU2V0RWxlbWVudC5tZXNzYWdlX3NldF9leHRlbnNpb25dIHsKKyAgICAgIHM6ICdFbWJlZGRlZE1lc3NhZ2VTZXRFbGVtZW50JworICAgIH0KKyAgfQorfTsKKworbWVzc2FnZSBBZ2dyZWdhdGVNZXNzYWdlIHsKKyAgb3B0aW9uIChtc2dvcHQpID0geyBpOjEwMSBzOidNZXNzYWdlQW5ub3RhdGlvbicgfTsKKyAgb3B0aW9uYWwgaW50MzIgZmllbGRuYW1lID0gMSBbKGZpZWxkb3B0KSA9IHsgczonRmllbGRBbm5vdGF0aW9uJyB9XTsKK30KKworc2VydmljZSBBZ2dyZWdhdGVTZXJ2aWNlIHsKKyAgb3B0aW9uIChzZXJ2aWNlb3B0KSA9IHsgczonU2VydmljZUFubm90YXRpb24nIH07CisgIHJwYyBNZXRob2QgKEFnZ3JlZ2F0ZU1lc3NhZ2UpIHJldHVybnMgKEFnZ3JlZ2F0ZU1lc3NhZ2UpIHsKKyAgICBvcHRpb24gKG1ldGhvZG9wdCkgPSB7IHM6J01ldGhvZEFubm90YXRpb24nIH07CisgIH0KK30KKworZW51bSBBZ2dyZWdhdGVFbnVtIHsKKyAgb3B0aW9uIChlbnVtb3B0KSA9IHsgczonRW51bUFubm90YXRpb24nIH07CisgIFZBTFVFID0gMSBbKGVudW12YWxvcHQpID0geyBzOidFbnVtVmFsdWVBbm5vdGF0aW9uJyB9XTsKK30KKworLy8gVGVzdCBjdXN0b20gb3B0aW9ucyBmb3IgbmVzdGVkIHR5cGUuCittZXNzYWdlIE5lc3RlZE9wdGlvblR5cGUgeworICBtZXNzYWdlIE5lc3RlZE1lc3NhZ2UgeworICAgIG9wdGlvbiAobWVzc2FnZV9vcHQxKSA9IDEwMDE7CisgICAgb3B0aW9uYWwgaW50MzIgbmVzdGVkX2ZpZWxkID0gMSBbKGZpZWxkX29wdDEpID0gMTAwMl07CisgIH0KKyAgZW51bSBOZXN0ZWRFbnVtIHsKKyAgICBvcHRpb24gKGVudW1fb3B0MSkgPSAxMDAzOworICAgIE5FU1RFRF9FTlVNX1ZBTFVFID0gMSBbKGVudW1fdmFsdWVfb3B0MSkgPSAxMDA0XTsKKyAgfQorICBleHRlbmQgZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zIHsKKyAgICBvcHRpb25hbCBpbnQzMiBuZXN0ZWRfZXh0ZW5zaW9uID0gNzkxMjU3MyBbKGZpZWxkX29wdDIpID0gMTAwNV07CisgIH0KK30KKworLy8gQ3VzdG9tIG1lc3NhZ2Ugb3B0aW9uIHRoYXQgaGFzIGEgcmVxdWlyZWQgZW51bSBmaWVsZC4KKy8vIFdBUk5JTkc6IHRoaXMgaXMgc3Ryb25nbHkgZGlzY291cmFnZWQhCittZXNzYWdlIE9sZE9wdGlvblR5cGUgeworICBlbnVtIFRlc3RFbnVtIHsKKyAgICBPTERfVkFMVUUgPSAwOworICB9CisgIHJlcXVpcmVkIFRlc3RFbnVtIHZhbHVlID0gMTsKK30KKworLy8gVXBkYXRlZCB2ZXJzaW9uIG9mIHRoZSBjdXN0b20gb3B0aW9uIGFib3ZlLgorbWVzc2FnZSBOZXdPcHRpb25UeXBlIHsKKyAgZW51bSBUZXN0RW51bSB7CisgICAgT0xEX1ZBTFVFID0gMDsKKyAgICBORVdfVkFMVUUgPSAxOworICB9CisgIHJlcXVpcmVkIFRlc3RFbnVtIHZhbHVlID0gMTsKK30KKworZXh0ZW5kIGdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucyB7CisgIG9wdGlvbmFsIE9sZE9wdGlvblR5cGUgcmVxdWlyZWRfZW51bV9vcHQgPSAxMDYxNjE4MDc7Cit9CisKKy8vIFRlc3QgbWVzc2FnZSB1c2luZyB0aGUgInJlcXVpcmVkX2VudW1fb3B0IiBvcHRpb24gZGVmaW5lZCBhYm92ZS4KK21lc3NhZ2UgVGVzdE1lc3NhZ2VXaXRoUmVxdWlyZWRFbnVtT3B0aW9uIHsKKyAgb3B0aW9uIChyZXF1aXJlZF9lbnVtX29wdCkgPSB7IHZhbHVlOiBPTERfVkFMVUUgfTsKK30KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfZHJvcF91bmtub3duX2ZpZWxkcy5wcm90byBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfZHJvcF91bmtub3duX2ZpZWxkcy5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YWEzYTM3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9kcm9wX3Vua25vd25fZmllbGRzLnByb3RvCkBAIC0wLDAgKzEsNTggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitzeW50YXggPSAicHJvdG8zIjsKKworcGFja2FnZSB1bml0dGVzdF9kcm9wX3Vua25vd25fZmllbGRzOworb3B0aW9uIG9iamNfY2xhc3NfcHJlZml4ID0gIkRyb3BVbmtub3ducyI7CisKK29wdGlvbiBjc2hhcnBfbmFtZXNwYWNlID0gIkdvb2dsZS5Qcm90b2J1Zi5UZXN0UHJvdG9zIjsKKworbWVzc2FnZSBGb28geworICBlbnVtIE5lc3RlZEVudW0geworICAgIEZPTyA9IDA7CisgICAgQkFSID0gMTsKKyAgICBCQVogPSAyOworICB9CisgIGludDMyIGludDMyX3ZhbHVlID0gMTsKKyAgTmVzdGVkRW51bSBlbnVtX3ZhbHVlID0gMjsKK30KKworbWVzc2FnZSBGb29XaXRoRXh0cmFGaWVsZHMgeworICBlbnVtIE5lc3RlZEVudW0geworICAgIEZPTyA9IDA7CisgICAgQkFSID0gMTsKKyAgICBCQVogPSAyOworICAgIFFVWCA9IDM7CisgIH0KKyAgaW50MzIgaW50MzJfdmFsdWUgPSAxOworICBOZXN0ZWRFbnVtIGVudW1fdmFsdWUgPSAyOworICBpbnQzMiBleHRyYV9pbnQzMl92YWx1ZSA9IDM7Cit9CmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2VtYmVkX29wdGltaXplX2Zvci5wcm90byBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfZW1iZWRfb3B0aW1pemVfZm9yLnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ4YjBmOWIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2VtYmVkX29wdGltaXplX2Zvci5wcm90bwpAQCAtMCwwICsxLDUxIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisvLworLy8gQSBwcm90byBmaWxlIHdoaWNoIGltcG9ydHMgYSBwcm90byBmaWxlIHRoYXQgdXNlcyBvcHRpbWl6ZV9mb3IgPSBDT0RFX1NJWkUuCisKK3N5bnRheCA9ICJwcm90bzIiOworaW1wb3J0ICJnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfb3B0aW1pemVfZm9yLnByb3RvIjsKKworcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdDsKKworLy8gV2Ugb3B0aW1pemUgZm9yIHNwZWVkIGhlcmUsIGJ1dCB3ZSBhcmUgaW1wb3J0aW5nIGEgcHJvdG8gdGhhdCBpcyBvcHRpbWl6ZWQKKy8vIGZvciBjb2RlIHNpemUuCitvcHRpb24gb3B0aW1pemVfZm9yID0gU1BFRUQ7CisKK21lc3NhZ2UgVGVzdEVtYmVkT3B0aW1pemVkRm9yU2l6ZSB7CisgIC8vIFRlc3QgdGhhdCBlbWJlZGRpbmcgYSBtZXNzYWdlIHdoaWNoIGhhcyBvcHRpbWl6ZV9mb3IgPSBDT0RFX1NJWkUgaW50bworICAvLyBvbmUgb3B0aW1pemVkIGZvciBzcGVlZCB3b3Jrcy4KKyAgb3B0aW9uYWwgVGVzdE9wdGltaXplZEZvclNpemUgb3B0aW9uYWxfbWVzc2FnZSA9IDE7CisgIHJlcGVhdGVkIFRlc3RPcHRpbWl6ZWRGb3JTaXplIHJlcGVhdGVkX21lc3NhZ2UgPSAyOworfQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9lbXB0eS5wcm90byBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfZW1wdHkucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzY0NDNlNwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfZW1wdHkucHJvdG8KQEAgLTAsMCArMSwzOCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorLy8KKy8vIFRoaXMgZmlsZSBpbnRlbnRpb25hbGx5IGxlZnQgYmxhbmsuICAoQXQgb25lIHBvaW50IHRoaXMgd291bGRuJ3QgY29tcGlsZQorLy8gY29ycmVjdGx5LikKKworc3ludGF4ID0gInByb3RvMiI7CmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2Vub3Jtb3VzX2Rlc2NyaXB0b3IucHJvdG8gYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2Vub3Jtb3VzX2Rlc2NyaXB0b3IucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmU2NWRjMQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfZW5vcm1vdXNfZGVzY3JpcHRvci5wcm90bwpAQCAtMCwwICsxLDEwNDggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBBIHByb3RvIGZpbGUgdGhhdCBoYXMgYW4gZXh0cmVtZWx5IGxhcmdlIGRlc2NyaXB0b3IuICBVc2VkIHRvIHRlc3QgdGhhdAorLy8gZGVzY3JpcHRvcnMgb3ZlciA2NGsgZG9uJ3QgYnJlYWsgbGFuZ3VhZ2Utc3BlY2lmaWMgbGltaXRzIGluIGdlbmVyYXRlZCBjb2RlLAorLy8gc3VjaCBhcyB0aGUgc3RyaW5nIGxpdGVyYWwgbGVuZ3RoIGxpbWl0IGluIEphdmEuCisKK3N5bnRheCA9ICJwcm90bzIiOworCitwYWNrYWdlIGdvb2dsZS5wcm90b2J1ZjsKK29wdGlvbiBqYXZhX3BhY2thZ2UgPSAiY29tLmdvb2dsZS5wcm90b2J1ZiI7CisKKy8vIEF2b2lkIGdlbmVyYXRpbmcgaW5zYW5lbHkgbG9uZyBtZXRob2RzLgorb3B0aW9uIG9wdGltaXplX2ZvciA9IENPREVfU0laRTsKKworbWVzc2FnZSBUZXN0RW5vcm1vdXNEZXNjcmlwdG9yIHsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEgPSAxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yID0gMiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMyA9IDMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQgPSA0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ID0gNSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNiA9IDYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcgPSA3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ID0gOCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOSA9IDkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwID0gMTAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExID0gMTEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyID0gMTIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzID0gMTMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0ID0gMTQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1ID0gMTUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2ID0gMTYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3ID0gMTcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4ID0gMTggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5ID0gMTkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwID0gMjAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxID0gMjEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyID0gMjIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzID0gMjMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0ID0gMjQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1ID0gMjUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2ID0gMjYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3ID0gMjcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4ID0gMjggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5ID0gMjkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwID0gMzAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxID0gMzEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyID0gMzIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzID0gMzMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0ID0gMzQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1ID0gMzUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2ID0gMzYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3ID0gMzcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4ID0gMzggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5ID0gMzkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwID0gNDAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxID0gNDEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyID0gNDIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzID0gNDMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0ID0gNDQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1ID0gNDUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2ID0gNDYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3ID0gNDcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4ID0gNDggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5ID0gNDkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwID0gNTAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxID0gNTEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyID0gNTIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzID0gNTMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0ID0gNTQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1ID0gNTUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2ID0gNTYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3ID0gNTcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4ID0gNTggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5ID0gNTkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwID0gNjAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxID0gNjEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyID0gNjIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzID0gNjMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0ID0gNjQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1ID0gNjUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2ID0gNjYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3ID0gNjcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4ID0gNjggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5ID0gNjkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwID0gNzAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxID0gNzEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyID0gNzIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczID0gNzMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0ID0gNzQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1ID0gNzUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2ID0gNzYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3ID0gNzcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4ID0gNzggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5ID0gNzkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwID0gODAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxID0gODEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyID0gODIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzID0gODMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0ID0gODQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1ID0gODUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2ID0gODYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3ID0gODcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4ID0gODggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5ID0gODkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwID0gOTAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxID0gOTEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyID0gOTIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzID0gOTMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0ID0gOTQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1ID0gOTUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2ID0gOTYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3ID0gOTcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4ID0gOTggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5ID0gOTkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwMCA9IDEwMCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTAxID0gMTAxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDIgPSAxMDIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwMyA9IDEwMyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTA0ID0gMTA0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDUgPSAxMDUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwNiA9IDEwNiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTA3ID0gMTA3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDggPSAxMDggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwOSA9IDEwOSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTEwID0gMTEwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTEgPSAxMTEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExMiA9IDExMiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTEzID0gMTEzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTQgPSAxMTQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExNSA9IDExNSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTE2ID0gMTE2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTcgPSAxMTcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExOCA9IDExOCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTE5ID0gMTE5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjAgPSAxMjAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyMSA9IDEyMSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTIyID0gMTIyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjMgPSAxMjMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyNCA9IDEyNCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTI1ID0gMTI1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjYgPSAxMjYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyNyA9IDEyNyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTI4ID0gMTI4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjkgPSAxMjkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzMCA9IDEzMCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTMxID0gMTMxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzIgPSAxMzIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzMyA9IDEzMyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTM0ID0gMTM0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzUgPSAxMzUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzNiA9IDEzNiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTM3ID0gMTM3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzggPSAxMzggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzOSA9IDEzOSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQwID0gMTQwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDEgPSAxNDEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0MiA9IDE0MiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQzID0gMTQzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDQgPSAxNDQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0NSA9IDE0NSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQ2ID0gMTQ2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDcgPSAxNDcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0OCA9IDE0OCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQ5ID0gMTQ5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTAgPSAxNTAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1MSA9IDE1MSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTUyID0gMTUyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTMgPSAxNTMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1NCA9IDE1NCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTU1ID0gMTU1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTYgPSAxNTYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1NyA9IDE1NyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTU4ID0gMTU4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTkgPSAxNTkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2MCA9IDE2MCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTYxID0gMTYxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjIgPSAxNjIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2MyA9IDE2MyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTY0ID0gMTY0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjUgPSAxNjUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2NiA9IDE2NiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTY3ID0gMTY3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjggPSAxNjggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2OSA9IDE2OSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTcwID0gMTcwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzEgPSAxNzEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3MiA9IDE3MiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTczID0gMTczIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzQgPSAxNzQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3NSA9IDE3NSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTc2ID0gMTc2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzcgPSAxNzcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3OCA9IDE3OCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTc5ID0gMTc5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODAgPSAxODAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4MSA9IDE4MSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTgyID0gMTgyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODMgPSAxODMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4NCA9IDE4NCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTg1ID0gMTg1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODYgPSAxODYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4NyA9IDE4NyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTg4ID0gMTg4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODkgPSAxODkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5MCA9IDE5MCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTkxID0gMTkxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTIgPSAxOTIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5MyA9IDE5MyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTk0ID0gMTk0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTUgPSAxOTUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5NiA9IDE5NiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTk3ID0gMTk3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTggPSAxOTggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5OSA9IDE5OSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjAwID0gMjAwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDEgPSAyMDEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwMiA9IDIwMiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjAzID0gMjAzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDQgPSAyMDQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwNSA9IDIwNSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjA2ID0gMjA2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDcgPSAyMDcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwOCA9IDIwOCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjA5ID0gMjA5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTAgPSAyMTAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxMSA9IDIxMSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjEyID0gMjEyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTMgPSAyMTMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxNCA9IDIxNCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjE1ID0gMjE1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTYgPSAyMTYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxNyA9IDIxNyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjE4ID0gMjE4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTkgPSAyMTkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyMCA9IDIyMCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjIxID0gMjIxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjIgPSAyMjIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyMyA9IDIyMyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjI0ID0gMjI0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjUgPSAyMjUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyNiA9IDIyNiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjI3ID0gMjI3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjggPSAyMjggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyOSA9IDIyOSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjMwID0gMjMwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzEgPSAyMzEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzMiA9IDIzMiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjMzID0gMjMzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzQgPSAyMzQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzNSA9IDIzNSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjM2ID0gMjM2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzcgPSAyMzcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzOCA9IDIzOCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjM5ID0gMjM5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDAgPSAyNDAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0MSA9IDI0MSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQyID0gMjQyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDMgPSAyNDMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0NCA9IDI0NCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQ1ID0gMjQ1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDYgPSAyNDYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0NyA9IDI0NyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQ4ID0gMjQ4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDkgPSAyNDkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1MCA9IDI1MCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjUxID0gMjUxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTIgPSAyNTIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1MyA9IDI1MyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjU0ID0gMjU0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTUgPSAyNTUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1NiA9IDI1NiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjU3ID0gMjU3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTggPSAyNTggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1OSA9IDI1OSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjYwID0gMjYwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjEgPSAyNjEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2MiA9IDI2MiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjYzID0gMjYzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjQgPSAyNjQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2NSA9IDI2NSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjY2ID0gMjY2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjcgPSAyNjcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2OCA9IDI2OCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjY5ID0gMjY5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzAgPSAyNzAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3MSA9IDI3MSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjcyID0gMjcyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzMgPSAyNzMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3NCA9IDI3NCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjc1ID0gMjc1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzYgPSAyNzYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3NyA9IDI3NyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjc4ID0gMjc4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzkgPSAyNzkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4MCA9IDI4MCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjgxID0gMjgxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODIgPSAyODIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4MyA9IDI4MyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjg0ID0gMjg0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODUgPSAyODUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4NiA9IDI4NiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjg3ID0gMjg3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODggPSAyODggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4OSA9IDI4OSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjkwID0gMjkwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTEgPSAyOTEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5MiA9IDI5MiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjkzID0gMjkzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTQgPSAyOTQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5NSA9IDI5NSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjk2ID0gMjk2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTcgPSAyOTcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5OCA9IDI5OCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjk5ID0gMjk5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDAgPSAzMDAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwMSA9IDMwMSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzAyID0gMzAyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDMgPSAzMDMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwNCA9IDMwNCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzA1ID0gMzA1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDYgPSAzMDYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwNyA9IDMwNyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzA4ID0gMzA4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDkgPSAzMDkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxMCA9IDMxMCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzExID0gMzExIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTIgPSAzMTIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxMyA9IDMxMyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzE0ID0gMzE0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTUgPSAzMTUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxNiA9IDMxNiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzE3ID0gMzE3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTggPSAzMTggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxOSA9IDMxOSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzIwID0gMzIwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjEgPSAzMjEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyMiA9IDMyMiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzIzID0gMzIzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjQgPSAzMjQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyNSA9IDMyNSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzI2ID0gMzI2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjcgPSAzMjcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyOCA9IDMyOCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzI5ID0gMzI5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzAgPSAzMzAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzMSA9IDMzMSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzMyID0gMzMyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzMgPSAzMzMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzNCA9IDMzNCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzM1ID0gMzM1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzYgPSAzMzYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzNyA9IDMzNyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzM4ID0gMzM4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzkgPSAzMzkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0MCA9IDM0MCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQxID0gMzQxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDIgPSAzNDIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0MyA9IDM0MyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQ0ID0gMzQ0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDUgPSAzNDUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0NiA9IDM0NiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQ3ID0gMzQ3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDggPSAzNDggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0OSA9IDM0OSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzUwID0gMzUwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTEgPSAzNTEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1MiA9IDM1MiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzUzID0gMzUzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTQgPSAzNTQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1NSA9IDM1NSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzU2ID0gMzU2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTcgPSAzNTcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1OCA9IDM1OCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzU5ID0gMzU5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjAgPSAzNjAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2MSA9IDM2MSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzYyID0gMzYyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjMgPSAzNjMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2NCA9IDM2NCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzY1ID0gMzY1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjYgPSAzNjYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2NyA9IDM2NyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzY4ID0gMzY4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjkgPSAzNjkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3MCA9IDM3MCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzcxID0gMzcxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzIgPSAzNzIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3MyA9IDM3MyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzc0ID0gMzc0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzUgPSAzNzUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3NiA9IDM3NiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzc3ID0gMzc3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzggPSAzNzggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3OSA9IDM3OSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzgwID0gMzgwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODEgPSAzODEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4MiA9IDM4MiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzgzID0gMzgzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODQgPSAzODQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4NSA9IDM4NSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzg2ID0gMzg2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODcgPSAzODcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4OCA9IDM4OCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzg5ID0gMzg5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTAgPSAzOTAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5MSA9IDM5MSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzkyID0gMzkyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTMgPSAzOTMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5NCA9IDM5NCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzk1ID0gMzk1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTYgPSAzOTYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5NyA9IDM5NyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzk4ID0gMzk4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTkgPSAzOTkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwMCA9IDQwMCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDAxID0gNDAxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDIgPSA0MDIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwMyA9IDQwMyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDA0ID0gNDA0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDUgPSA0MDUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwNiA9IDQwNiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDA3ID0gNDA3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDggPSA0MDggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwOSA9IDQwOSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDEwID0gNDEwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTEgPSA0MTEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxMiA9IDQxMiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDEzID0gNDEzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTQgPSA0MTQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxNSA9IDQxNSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDE2ID0gNDE2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTcgPSA0MTcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxOCA9IDQxOCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDE5ID0gNDE5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjAgPSA0MjAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyMSA9IDQyMSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDIyID0gNDIyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjMgPSA0MjMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyNCA9IDQyNCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDI1ID0gNDI1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjYgPSA0MjYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyNyA9IDQyNyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDI4ID0gNDI4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjkgPSA0MjkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzMCA9IDQzMCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDMxID0gNDMxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzIgPSA0MzIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzMyA9IDQzMyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDM0ID0gNDM0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzUgPSA0MzUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzNiA9IDQzNiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDM3ID0gNDM3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzggPSA0MzggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzOSA9IDQzOSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQwID0gNDQwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDEgPSA0NDEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0MiA9IDQ0MiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQzID0gNDQzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDQgPSA0NDQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0NSA9IDQ0NSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQ2ID0gNDQ2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDcgPSA0NDcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0OCA9IDQ0OCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQ5ID0gNDQ5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTAgPSA0NTAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1MSA9IDQ1MSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDUyID0gNDUyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTMgPSA0NTMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1NCA9IDQ1NCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDU1ID0gNDU1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTYgPSA0NTYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1NyA9IDQ1NyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDU4ID0gNDU4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTkgPSA0NTkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2MCA9IDQ2MCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDYxID0gNDYxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjIgPSA0NjIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2MyA9IDQ2MyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDY0ID0gNDY0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjUgPSA0NjUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2NiA9IDQ2NiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDY3ID0gNDY3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjggPSA0NjggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2OSA9IDQ2OSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDcwID0gNDcwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzEgPSA0NzEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3MiA9IDQ3MiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDczID0gNDczIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzQgPSA0NzQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3NSA9IDQ3NSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDc2ID0gNDc2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzcgPSA0NzcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3OCA9IDQ3OCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDc5ID0gNDc5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODAgPSA0ODAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4MSA9IDQ4MSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDgyID0gNDgyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODMgPSA0ODMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4NCA9IDQ4NCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDg1ID0gNDg1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODYgPSA0ODYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4NyA9IDQ4NyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDg4ID0gNDg4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODkgPSA0ODkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5MCA9IDQ5MCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDkxID0gNDkxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTIgPSA0OTIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5MyA9IDQ5MyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDk0ID0gNDk0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTUgPSA0OTUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5NiA9IDQ5NiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDk3ID0gNDk3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTggPSA0OTggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5OSA9IDQ5OSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTAwID0gNTAwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDEgPSA1MDEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwMiA9IDUwMiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTAzID0gNTAzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDQgPSA1MDQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwNSA9IDUwNSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTA2ID0gNTA2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDcgPSA1MDcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwOCA9IDUwOCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTA5ID0gNTA5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTAgPSA1MTAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxMSA9IDUxMSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTEyID0gNTEyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTMgPSA1MTMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxNCA9IDUxNCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTE1ID0gNTE1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTYgPSA1MTYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxNyA9IDUxNyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTE4ID0gNTE4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTkgPSA1MTkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyMCA9IDUyMCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTIxID0gNTIxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjIgPSA1MjIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyMyA9IDUyMyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTI0ID0gNTI0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjUgPSA1MjUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyNiA9IDUyNiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTI3ID0gNTI3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjggPSA1MjggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyOSA9IDUyOSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTMwID0gNTMwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzEgPSA1MzEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzMiA9IDUzMiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTMzID0gNTMzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzQgPSA1MzQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzNSA9IDUzNSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTM2ID0gNTM2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzcgPSA1MzcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzOCA9IDUzOCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTM5ID0gNTM5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDAgPSA1NDAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0MSA9IDU0MSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQyID0gNTQyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDMgPSA1NDMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0NCA9IDU0NCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQ1ID0gNTQ1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDYgPSA1NDYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0NyA9IDU0NyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQ4ID0gNTQ4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDkgPSA1NDkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1MCA9IDU1MCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTUxID0gNTUxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTIgPSA1NTIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1MyA9IDU1MyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTU0ID0gNTU0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTUgPSA1NTUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1NiA9IDU1NiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTU3ID0gNTU3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTggPSA1NTggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1OSA9IDU1OSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTYwID0gNTYwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjEgPSA1NjEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2MiA9IDU2MiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTYzID0gNTYzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjQgPSA1NjQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2NSA9IDU2NSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTY2ID0gNTY2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjcgPSA1NjcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2OCA9IDU2OCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTY5ID0gNTY5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzAgPSA1NzAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3MSA9IDU3MSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTcyID0gNTcyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzMgPSA1NzMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3NCA9IDU3NCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTc1ID0gNTc1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzYgPSA1NzYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3NyA9IDU3NyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTc4ID0gNTc4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzkgPSA1NzkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4MCA9IDU4MCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTgxID0gNTgxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODIgPSA1ODIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4MyA9IDU4MyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTg0ID0gNTg0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODUgPSA1ODUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4NiA9IDU4NiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTg3ID0gNTg3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODggPSA1ODggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4OSA9IDU4OSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTkwID0gNTkwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTEgPSA1OTEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5MiA9IDU5MiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTkzID0gNTkzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTQgPSA1OTQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5NSA9IDU5NSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTk2ID0gNTk2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTcgPSA1OTcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5OCA9IDU5OCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTk5ID0gNTk5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDAgPSA2MDAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwMSA9IDYwMSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjAyID0gNjAyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDMgPSA2MDMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwNCA9IDYwNCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjA1ID0gNjA1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDYgPSA2MDYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwNyA9IDYwNyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjA4ID0gNjA4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDkgPSA2MDkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxMCA9IDYxMCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjExID0gNjExIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTIgPSA2MTIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxMyA9IDYxMyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjE0ID0gNjE0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTUgPSA2MTUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxNiA9IDYxNiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjE3ID0gNjE3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTggPSA2MTggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxOSA9IDYxOSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjIwID0gNjIwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjEgPSA2MjEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyMiA9IDYyMiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjIzID0gNjIzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjQgPSA2MjQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyNSA9IDYyNSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjI2ID0gNjI2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjcgPSA2MjcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyOCA9IDYyOCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjI5ID0gNjI5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzAgPSA2MzAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzMSA9IDYzMSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjMyID0gNjMyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzMgPSA2MzMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzNCA9IDYzNCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjM1ID0gNjM1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzYgPSA2MzYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzNyA9IDYzNyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjM4ID0gNjM4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzkgPSA2MzkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0MCA9IDY0MCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQxID0gNjQxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDIgPSA2NDIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0MyA9IDY0MyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQ0ID0gNjQ0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDUgPSA2NDUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0NiA9IDY0NiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQ3ID0gNjQ3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDggPSA2NDggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0OSA9IDY0OSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjUwID0gNjUwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTEgPSA2NTEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1MiA9IDY1MiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjUzID0gNjUzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTQgPSA2NTQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1NSA9IDY1NSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjU2ID0gNjU2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTcgPSA2NTcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1OCA9IDY1OCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjU5ID0gNjU5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjAgPSA2NjAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2MSA9IDY2MSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjYyID0gNjYyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjMgPSA2NjMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2NCA9IDY2NCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjY1ID0gNjY1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjYgPSA2NjYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2NyA9IDY2NyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjY4ID0gNjY4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjkgPSA2NjkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3MCA9IDY3MCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjcxID0gNjcxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzIgPSA2NzIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3MyA9IDY3MyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjc0ID0gNjc0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzUgPSA2NzUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3NiA9IDY3NiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjc3ID0gNjc3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzggPSA2NzggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3OSA9IDY3OSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjgwID0gNjgwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODEgPSA2ODEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4MiA9IDY4MiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjgzID0gNjgzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODQgPSA2ODQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4NSA9IDY4NSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjg2ID0gNjg2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODcgPSA2ODcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4OCA9IDY4OCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjg5ID0gNjg5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTAgPSA2OTAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5MSA9IDY5MSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjkyID0gNjkyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTMgPSA2OTMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5NCA9IDY5NCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjk1ID0gNjk1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTYgPSA2OTYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5NyA9IDY5NyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjk4ID0gNjk4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTkgPSA2OTkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwMCA9IDcwMCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzAxID0gNzAxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDIgPSA3MDIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwMyA9IDcwMyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzA0ID0gNzA0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDUgPSA3MDUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwNiA9IDcwNiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzA3ID0gNzA3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDggPSA3MDggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwOSA9IDcwOSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzEwID0gNzEwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTEgPSA3MTEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxMiA9IDcxMiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzEzID0gNzEzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTQgPSA3MTQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxNSA9IDcxNSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzE2ID0gNzE2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTcgPSA3MTcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxOCA9IDcxOCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzE5ID0gNzE5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjAgPSA3MjAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyMSA9IDcyMSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzIyID0gNzIyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjMgPSA3MjMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyNCA9IDcyNCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzI1ID0gNzI1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjYgPSA3MjYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyNyA9IDcyNyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzI4ID0gNzI4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjkgPSA3MjkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczMCA9IDczMCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzMxID0gNzMxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzIgPSA3MzIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczMyA9IDczMyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzM0ID0gNzM0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzUgPSA3MzUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczNiA9IDczNiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzM3ID0gNzM3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzggPSA3MzggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczOSA9IDczOSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQwID0gNzQwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDEgPSA3NDEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0MiA9IDc0MiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQzID0gNzQzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDQgPSA3NDQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0NSA9IDc0NSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQ2ID0gNzQ2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDcgPSA3NDcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0OCA9IDc0OCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQ5ID0gNzQ5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTAgPSA3NTAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1MSA9IDc1MSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzUyID0gNzUyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTMgPSA3NTMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1NCA9IDc1NCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzU1ID0gNzU1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTYgPSA3NTYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1NyA9IDc1NyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzU4ID0gNzU4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTkgPSA3NTkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2MCA9IDc2MCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzYxID0gNzYxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjIgPSA3NjIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2MyA9IDc2MyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzY0ID0gNzY0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjUgPSA3NjUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2NiA9IDc2NiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzY3ID0gNzY3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjggPSA3NjggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2OSA9IDc2OSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzcwID0gNzcwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzEgPSA3NzEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3MiA9IDc3MiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzczID0gNzczIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzQgPSA3NzQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3NSA9IDc3NSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzc2ID0gNzc2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzcgPSA3NzcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3OCA9IDc3OCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzc5ID0gNzc5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODAgPSA3ODAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4MSA9IDc4MSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzgyID0gNzgyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODMgPSA3ODMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4NCA9IDc4NCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzg1ID0gNzg1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODYgPSA3ODYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4NyA9IDc4NyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzg4ID0gNzg4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODkgPSA3ODkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5MCA9IDc5MCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzkxID0gNzkxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTIgPSA3OTIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5MyA9IDc5MyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzk0ID0gNzk0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTUgPSA3OTUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5NiA9IDc5NiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzk3ID0gNzk3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTggPSA3OTggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5OSA9IDc5OSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODAwID0gODAwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDEgPSA4MDEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwMiA9IDgwMiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODAzID0gODAzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDQgPSA4MDQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwNSA9IDgwNSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODA2ID0gODA2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDcgPSA4MDcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwOCA9IDgwOCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODA5ID0gODA5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTAgPSA4MTAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxMSA9IDgxMSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODEyID0gODEyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTMgPSA4MTMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxNCA9IDgxNCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODE1ID0gODE1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTYgPSA4MTYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxNyA9IDgxNyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODE4ID0gODE4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTkgPSA4MTkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyMCA9IDgyMCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODIxID0gODIxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjIgPSA4MjIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyMyA9IDgyMyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODI0ID0gODI0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjUgPSA4MjUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyNiA9IDgyNiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODI3ID0gODI3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjggPSA4MjggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyOSA9IDgyOSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODMwID0gODMwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzEgPSA4MzEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzMiA9IDgzMiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODMzID0gODMzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzQgPSA4MzQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzNSA9IDgzNSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODM2ID0gODM2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzcgPSA4MzcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzOCA9IDgzOCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODM5ID0gODM5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDAgPSA4NDAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0MSA9IDg0MSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQyID0gODQyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDMgPSA4NDMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0NCA9IDg0NCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQ1ID0gODQ1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDYgPSA4NDYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0NyA9IDg0NyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQ4ID0gODQ4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDkgPSA4NDkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1MCA9IDg1MCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODUxID0gODUxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTIgPSA4NTIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1MyA9IDg1MyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODU0ID0gODU0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTUgPSA4NTUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1NiA9IDg1NiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODU3ID0gODU3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTggPSA4NTggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1OSA9IDg1OSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODYwID0gODYwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjEgPSA4NjEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2MiA9IDg2MiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODYzID0gODYzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjQgPSA4NjQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2NSA9IDg2NSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODY2ID0gODY2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjcgPSA4NjcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2OCA9IDg2OCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODY5ID0gODY5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzAgPSA4NzAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3MSA9IDg3MSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODcyID0gODcyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzMgPSA4NzMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3NCA9IDg3NCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODc1ID0gODc1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzYgPSA4NzYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3NyA9IDg3NyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODc4ID0gODc4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzkgPSA4NzkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4MCA9IDg4MCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODgxID0gODgxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODIgPSA4ODIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4MyA9IDg4MyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODg0ID0gODg0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODUgPSA4ODUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4NiA9IDg4NiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODg3ID0gODg3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODggPSA4ODggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4OSA9IDg4OSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODkwID0gODkwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTEgPSA4OTEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5MiA9IDg5MiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODkzID0gODkzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTQgPSA4OTQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5NSA9IDg5NSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODk2ID0gODk2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTcgPSA4OTcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5OCA9IDg5OCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODk5ID0gODk5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDAgPSA5MDAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwMSA9IDkwMSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTAyID0gOTAyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDMgPSA5MDMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwNCA9IDkwNCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTA1ID0gOTA1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDYgPSA5MDYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwNyA9IDkwNyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTA4ID0gOTA4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDkgPSA5MDkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxMCA9IDkxMCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTExID0gOTExIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTIgPSA5MTIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxMyA9IDkxMyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTE0ID0gOTE0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTUgPSA5MTUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxNiA9IDkxNiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTE3ID0gOTE3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTggPSA5MTggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxOSA9IDkxOSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTIwID0gOTIwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjEgPSA5MjEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyMiA9IDkyMiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTIzID0gOTIzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjQgPSA5MjQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyNSA9IDkyNSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTI2ID0gOTI2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjcgPSA5MjcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyOCA9IDkyOCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTI5ID0gOTI5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzAgPSA5MzAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzMSA9IDkzMSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTMyID0gOTMyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzMgPSA5MzMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzNCA9IDkzNCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTM1ID0gOTM1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzYgPSA5MzYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzNyA9IDkzNyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTM4ID0gOTM4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzkgPSA5MzkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0MCA9IDk0MCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQxID0gOTQxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDIgPSA5NDIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0MyA9IDk0MyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQ0ID0gOTQ0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDUgPSA5NDUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0NiA9IDk0NiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQ3ID0gOTQ3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDggPSA5NDggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0OSA9IDk0OSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTUwID0gOTUwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTEgPSA5NTEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1MiA9IDk1MiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTUzID0gOTUzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTQgPSA5NTQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1NSA9IDk1NSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTU2ID0gOTU2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTcgPSA5NTcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1OCA9IDk1OCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTU5ID0gOTU5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjAgPSA5NjAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2MSA9IDk2MSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTYyID0gOTYyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjMgPSA5NjMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2NCA9IDk2NCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTY1ID0gOTY1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjYgPSA5NjYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2NyA9IDk2NyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTY4ID0gOTY4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjkgPSA5NjkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3MCA9IDk3MCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTcxID0gOTcxIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzIgPSA5NzIgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3MyA9IDk3MyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTc0ID0gOTc0IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzUgPSA5NzUgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3NiA9IDk3NiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTc3ID0gOTc3IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzggPSA5NzggW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3OSA9IDk3OSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTgwID0gOTgwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODEgPSA5ODEgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4MiA9IDk4MiBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTgzID0gOTgzIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODQgPSA5ODQgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4NSA9IDk4NSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTg2ID0gOTg2IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODcgPSA5ODcgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4OCA9IDk4OCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTg5ID0gOTg5IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTAgPSA5OTAgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5MSA9IDk5MSBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTkyID0gOTkyIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTMgPSA5OTMgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5NCA9IDk5NCBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTk1ID0gOTk1IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTYgPSA5OTYgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5NyA9IDk5NyBbZGVmYXVsdD0ibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOworICBvcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTk4ID0gOTk4IFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07CisgIG9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTkgPSA5OTkgW2RlZmF1bHQ9ImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwMDAgPSAxMDAwIFtkZWZhdWx0PSJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07Cit9CmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2ltcG9ydC5wcm90byBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0LnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhkMDNlMzgKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2ltcG9ydC5wcm90bwpAQCAtMCwwICsxLDczIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisvLworLy8gQSBwcm90byBmaWxlIHdoaWNoIGlzIGltcG9ydGVkIGJ5IHVuaXR0ZXN0LnByb3RvIHRvIHRlc3QgaW1wb3J0aW5nLgorCitzeW50YXggPSAicHJvdG8yIjsKKworLy8gV2UgZG9uJ3QgcHV0IHRoaXMgaW4gYSBwYWNrYWdlIHdpdGhpbiBwcm90bzIgYmVjYXVzZSB3ZSBuZWVkIHRvIG1ha2Ugc3VyZQorLy8gdGhhdCB0aGUgZ2VuZXJhdGVkIGNvZGUgZG9lc24ndCBkZXBlbmQgb24gYmVpbmcgaW4gdGhlIHByb3RvMiBuYW1lc3BhY2UuCisvLyBJbiB0ZXN0X3V0aWwuaCB3ZSBkbworLy8gInVzaW5nIG5hbWVzcGFjZSB1bml0dGVzdF9pbXBvcnQgPSBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQiLgorcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQ7CisKK29wdGlvbiBvcHRpbWl6ZV9mb3IgPSBTUEVFRDsKK29wdGlvbiBjY19lbmFibGVfYXJlbmFzID0gdHJ1ZTsKKworLy8gRXhlcmNpc2UgdGhlIGphdmFfcGFja2FnZSBvcHRpb24uCitvcHRpb24gamF2YV9wYWNrYWdlID0gImNvbS5nb29nbGUucHJvdG9idWYudGVzdCI7CisKKy8vIERvIG5vdCBzZXQgYSBqYXZhX291dGVyX2NsYXNzbmFtZSBoZXJlIHRvIHZlcmlmeSB0aGF0IFByb3RvMiB3b3JrcyB3aXRob3V0CisvLyBvbmUuCisKKy8vIFRlc3QgcHVibGljIGltcG9ydAoraW1wb3J0IHB1YmxpYyAiZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucHJvdG8iOworCittZXNzYWdlIEltcG9ydE1lc3NhZ2UgeworICBvcHRpb25hbCBpbnQzMiBkID0gMTsKK30KKworZW51bSBJbXBvcnRFbnVtIHsKKyAgSU1QT1JUX0ZPTyA9IDc7CisgIElNUE9SVF9CQVIgPSA4OworICBJTVBPUlRfQkFaID0gOTsKK30KKworCisvLyBUbyB1c2UgYW4gZW51bSBpbiBhIG1hcCwgaXQgbXVzdCBoYXMgdGhlIGZpcnN0IHZhbHVlIGFzIDAuCitlbnVtIEltcG9ydEVudW1Gb3JNYXAgeworICBVTktOT1dOID0gMDsKKyAgRk9PID0gMTsKKyAgQkFSID0gMjsKK30KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X2xpdGUucHJvdG8gYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2ltcG9ydF9saXRlLnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE3YWZhNDUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2ltcG9ydF9saXRlLnByb3RvCkBAIC0wLDAgKzEsNTIgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLworLy8gVGhpcyBpcyBsaWtlIHVuaXR0ZXN0X2ltcG9ydC5wcm90byBidXQgd2l0aCBvcHRpbWl6ZV9mb3IgPSBMSVRFX1JVTlRJTUUuCisKK3N5bnRheCA9ICJwcm90bzIiOworcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQ7CisKK29wdGlvbiBvcHRpbWl6ZV9mb3IgPSBMSVRFX1JVTlRJTUU7CisKK29wdGlvbiBqYXZhX3BhY2thZ2UgPSAiY29tLmdvb2dsZS5wcm90b2J1ZiI7CisKK2ltcG9ydCBwdWJsaWMgImdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9pbXBvcnRfcHVibGljX2xpdGUucHJvdG8iOworCittZXNzYWdlIEltcG9ydE1lc3NhZ2VMaXRlIHsKKyAgb3B0aW9uYWwgaW50MzIgZCA9IDE7Cit9CisKK2VudW0gSW1wb3J0RW51bUxpdGUgeworICBJTVBPUlRfTElURV9GT08gPSA3OworICBJTVBPUlRfTElURV9CQVIgPSA4OworICBJTVBPUlRfTElURV9CQVogPSA5OworfQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9pbXBvcnRfcHJvdG8zLnByb3RvIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9pbXBvcnRfcHJvdG8zLnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU5NjczZWEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2ltcG9ydF9wcm90bzMucHJvdG8KQEAgLTAsMCArMSw2OCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorLy8KKy8vIEEgcHJvdG8gZmlsZSB3aGljaCBpcyBpbXBvcnRlZCBieSB1bml0dGVzdF9wcm90bzMucHJvdG8gdG8gdGVzdCBpbXBvcnRpbmcuCisKK3N5bnRheCA9ICJwcm90bzMiOworCisvLyBXZSBkb24ndCBwdXQgdGhpcyBpbiBhIHBhY2thZ2Ugd2l0aGluIHByb3RvMiBiZWNhdXNlIHdlIG5lZWQgdG8gbWFrZSBzdXJlCisvLyB0aGF0IHRoZSBnZW5lcmF0ZWQgY29kZSBkb2Vzbid0IGRlcGVuZCBvbiBiZWluZyBpbiB0aGUgcHJvdG8yIG5hbWVzcGFjZS4KKy8vIEluIHRlc3RfdXRpbC5oIHdlIGRvCisvLyAidXNpbmcgbmFtZXNwYWNlIHVuaXR0ZXN0X2ltcG9ydCA9IHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydCIuCitwYWNrYWdlIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydDsKKworb3B0aW9uIG9wdGltaXplX2ZvciA9IFNQRUVEOworb3B0aW9uIGNjX2VuYWJsZV9hcmVuYXMgPSB0cnVlOworCisvLyBFeGVyY2lzZSB0aGUgamF2YV9wYWNrYWdlIG9wdGlvbi4KK29wdGlvbiBqYXZhX3BhY2thZ2UgPSAiY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0IjsKK29wdGlvbiBjc2hhcnBfbmFtZXNwYWNlID0gIkdvb2dsZS5Qcm90b2J1Zi5UZXN0UHJvdG9zIjsKKworLy8gRG8gbm90IHNldCBhIGphdmFfb3V0ZXJfY2xhc3NuYW1lIGhlcmUgdG8gdmVyaWZ5IHRoYXQgUHJvdG8yIHdvcmtzIHdpdGhvdXQKKy8vIG9uZS4KKworLy8gVGVzdCBwdWJsaWMgaW1wb3J0CitpbXBvcnQgcHVibGljICJnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X3B1YmxpY19wcm90bzMucHJvdG8iOworCittZXNzYWdlIEltcG9ydE1lc3NhZ2UgeworICBpbnQzMiBkID0gMTsKK30KKworZW51bSBJbXBvcnRFbnVtIHsKKyAgSU1QT1JUX0VOVU1fVU5TUEVDSUZJRUQgPSAwOworICBJTVBPUlRfRk9PID0gNzsKKyAgSU1QT1JUX0JBUiA9IDg7CisgIElNUE9SVF9CQVogPSA5OworfQorCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucHJvdG8gYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmZhZjc3MwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wcm90bwpAQCAtMCwwICsxLDQxIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBsaXVqaXNpQGdvb2dsZS5jb20gKFBoZXJsIExpdSkKKworc3ludGF4ID0gInByb3RvMiI7CisKK3BhY2thZ2UgcHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0OworCitvcHRpb24gamF2YV9wYWNrYWdlID0gImNvbS5nb29nbGUucHJvdG9idWYudGVzdCI7CisKK21lc3NhZ2UgUHVibGljSW1wb3J0TWVzc2FnZSB7CisgIG9wdGlvbmFsIGludDMyIGUgPSAxOworfQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9pbXBvcnRfcHVibGljX2xpdGUucHJvdG8gYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2ltcG9ydF9wdWJsaWNfbGl0ZS5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zMzU0OWMyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9pbXBvcnRfcHVibGljX2xpdGUucHJvdG8KQEAgLTAsMCArMSw0MyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjogbGl1amlzaUBnb29nbGUuY29tIChQaGVybCBMaXUpCisKK3N5bnRheCA9ICJwcm90bzIiOworCitwYWNrYWdlIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydDsKKworb3B0aW9uIG9wdGltaXplX2ZvciA9IExJVEVfUlVOVElNRTsKKworb3B0aW9uIGphdmFfcGFja2FnZSA9ICJjb20uZ29vZ2xlLnByb3RvYnVmIjsKKworbWVzc2FnZSBQdWJsaWNJbXBvcnRNZXNzYWdlTGl0ZSB7CisgIG9wdGlvbmFsIGludDMyIGUgPSAxOworfQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9pbXBvcnRfcHVibGljX3Byb3RvMy5wcm90byBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X3B1YmxpY19wcm90bzMucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDZmMTFlMgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X3B1YmxpY19wcm90bzMucHJvdG8KQEAgLTAsMCArMSw0MiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjogbGl1amlzaUBnb29nbGUuY29tIChQaGVybCBMaXUpCisKK3N5bnRheCA9ICJwcm90bzMiOworCitwYWNrYWdlIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydDsKKworb3B0aW9uIGphdmFfcGFja2FnZSA9ICJjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QiOworb3B0aW9uIGNzaGFycF9uYW1lc3BhY2UgPSAiR29vZ2xlLlByb3RvYnVmLlRlc3RQcm90b3MiOworCittZXNzYWdlIFB1YmxpY0ltcG9ydE1lc3NhZ2UgeworIGludDMyIGUgPSAxOworfQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9saXRlLnByb3RvIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9saXRlLnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY2MmMwZTQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2xpdGUucHJvdG8KQEAgLTAsMCArMSwzODUgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLworLy8gVGhpcyBpcyBsaWtlIHVuaXR0ZXN0LnByb3RvIGJ1dCB3aXRoIG9wdGltaXplX2ZvciA9IExJVEVfUlVOVElNRS4KKworc3ludGF4ID0gInByb3RvMiI7CitwYWNrYWdlIHByb3RvYnVmX3VuaXR0ZXN0OworCitpbXBvcnQgImdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9pbXBvcnRfbGl0ZS5wcm90byI7CisKK29wdGlvbiBvcHRpbWl6ZV9mb3IgPSBMSVRFX1JVTlRJTUU7CisKK29wdGlvbiBqYXZhX3BhY2thZ2UgPSAiY29tLmdvb2dsZS5wcm90b2J1ZiI7CisKKy8vIFNhbWUgYXMgVGVzdEFsbFR5cGVzIGJ1dCB3aXRoIHRoZSBsaXRlIHJ1bnRpbWUuCittZXNzYWdlIFRlc3RBbGxUeXBlc0xpdGUgeworICBtZXNzYWdlIE5lc3RlZE1lc3NhZ2UgeworICAgIG9wdGlvbmFsIGludDMyIGJiID0gMTsKKyAgfQorCisgIGVudW0gTmVzdGVkRW51bSB7CisgICAgRk9PID0gMTsKKyAgICBCQVIgPSAyOworICAgIEJBWiA9IDM7CisgIH0KKworICAvLyBTaW5ndWxhcgorICBvcHRpb25hbCAgICBpbnQzMiBvcHRpb25hbF9pbnQzMiAgICA9ICAxOworICBvcHRpb25hbCAgICBpbnQ2NCBvcHRpb25hbF9pbnQ2NCAgICA9ICAyOworICBvcHRpb25hbCAgIHVpbnQzMiBvcHRpb25hbF91aW50MzIgICA9ICAzOworICBvcHRpb25hbCAgIHVpbnQ2NCBvcHRpb25hbF91aW50NjQgICA9ICA0OworICBvcHRpb25hbCAgIHNpbnQzMiBvcHRpb25hbF9zaW50MzIgICA9ICA1OworICBvcHRpb25hbCAgIHNpbnQ2NCBvcHRpb25hbF9zaW50NjQgICA9ICA2OworICBvcHRpb25hbCAgZml4ZWQzMiBvcHRpb25hbF9maXhlZDMyICA9ICA3OworICBvcHRpb25hbCAgZml4ZWQ2NCBvcHRpb25hbF9maXhlZDY0ICA9ICA4OworICBvcHRpb25hbCBzZml4ZWQzMiBvcHRpb25hbF9zZml4ZWQzMiA9ICA5OworICBvcHRpb25hbCBzZml4ZWQ2NCBvcHRpb25hbF9zZml4ZWQ2NCA9IDEwOworICBvcHRpb25hbCAgICBmbG9hdCBvcHRpb25hbF9mbG9hdCAgICA9IDExOworICBvcHRpb25hbCAgIGRvdWJsZSBvcHRpb25hbF9kb3VibGUgICA9IDEyOworICBvcHRpb25hbCAgICAgYm9vbCBvcHRpb25hbF9ib29sICAgICA9IDEzOworICBvcHRpb25hbCAgIHN0cmluZyBvcHRpb25hbF9zdHJpbmcgICA9IDE0OworICBvcHRpb25hbCAgICBieXRlcyBvcHRpb25hbF9ieXRlcyAgICA9IDE1OworCisgIG9wdGlvbmFsIGdyb3VwIE9wdGlvbmFsR3JvdXAgPSAxNiB7CisgICAgb3B0aW9uYWwgaW50MzIgYSA9IDE3OworICB9CisKKyAgb3B0aW9uYWwgTmVzdGVkTWVzc2FnZSAgICAgIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlICA9IDE4OworICBvcHRpb25hbCBGb3JlaWduTWVzc2FnZUxpdGUgb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlID0gMTk7CisgIG9wdGlvbmFsIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlTGl0ZQorICAgIG9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlID0gMjA7CisKKyAgb3B0aW9uYWwgTmVzdGVkRW51bSAgICAgIG9wdGlvbmFsX25lc3RlZF9lbnVtICAgICA9IDIxOworICBvcHRpb25hbCBGb3JlaWduRW51bUxpdGUgb3B0aW9uYWxfZm9yZWlnbl9lbnVtICAgID0gMjI7CisgIG9wdGlvbmFsIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtTGl0ZSBvcHRpb25hbF9pbXBvcnRfZW51bSA9IDIzOworCisgIG9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9zdHJpbmdfcGllY2UgPSAyNCBbY3R5cGU9U1RSSU5HX1BJRUNFXTsKKyAgb3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX2NvcmQgPSAyNSBbY3R5cGU9Q09SRF07CisKKyAgLy8gRGVmaW5lZCBpbiB1bml0dGVzdF9pbXBvcnRfcHVibGljLnByb3RvCisgIG9wdGlvbmFsIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5QdWJsaWNJbXBvcnRNZXNzYWdlTGl0ZQorICAgICAgb3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlID0gMjY7CisKKyAgb3B0aW9uYWwgTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSAyNyBbbGF6eT10cnVlXTsKKworICAvLyBSZXBlYXRlZAorICByZXBlYXRlZCAgICBpbnQzMiByZXBlYXRlZF9pbnQzMiAgICA9IDMxOworICByZXBlYXRlZCAgICBpbnQ2NCByZXBlYXRlZF9pbnQ2NCAgICA9IDMyOworICByZXBlYXRlZCAgIHVpbnQzMiByZXBlYXRlZF91aW50MzIgICA9IDMzOworICByZXBlYXRlZCAgIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgICA9IDM0OworICByZXBlYXRlZCAgIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgICA9IDM1OworICByZXBlYXRlZCAgIHNpbnQ2NCByZXBlYXRlZF9zaW50NjQgICA9IDM2OworICByZXBlYXRlZCAgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyICA9IDM3OworICByZXBlYXRlZCAgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ICA9IDM4OworICByZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDM5OworICByZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDQwOworICByZXBlYXRlZCAgICBmbG9hdCByZXBlYXRlZF9mbG9hdCAgICA9IDQxOworICByZXBlYXRlZCAgIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgICA9IDQyOworICByZXBlYXRlZCAgICAgYm9vbCByZXBlYXRlZF9ib29sICAgICA9IDQzOworICByZXBlYXRlZCAgIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgICA9IDQ0OworICByZXBlYXRlZCAgICBieXRlcyByZXBlYXRlZF9ieXRlcyAgICA9IDQ1OworCisgIHJlcGVhdGVkIGdyb3VwIFJlcGVhdGVkR3JvdXAgPSA0NiB7CisgICAgb3B0aW9uYWwgaW50MzIgYSA9IDQ3OworICB9CisKKyAgcmVwZWF0ZWQgTmVzdGVkTWVzc2FnZSAgICAgIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlICA9IDQ4OworICByZXBlYXRlZCBGb3JlaWduTWVzc2FnZUxpdGUgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlID0gNDk7CisgIHJlcGVhdGVkIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlTGl0ZQorICAgIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7CisKKyAgcmVwZWF0ZWQgTmVzdGVkRW51bSAgICAgIHJlcGVhdGVkX25lc3RlZF9lbnVtICA9IDUxOworICByZXBlYXRlZCBGb3JlaWduRW51bUxpdGUgcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7CisgIHJlcGVhdGVkIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtTGl0ZSByZXBlYXRlZF9pbXBvcnRfZW51bSA9IDUzOworCisgIHJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfcGllY2UgPSA1NCBbY3R5cGU9U1RSSU5HX1BJRUNFXTsKKyAgcmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX2NvcmQgPSA1NSBbY3R5cGU9Q09SRF07CisKKyAgcmVwZWF0ZWQgTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eT10cnVlXTsKKworICAvLyBTaW5ndWxhciB3aXRoIGRlZmF1bHRzCisgIG9wdGlvbmFsICAgIGludDMyIGRlZmF1bHRfaW50MzIgICAgPSA2MSBbZGVmYXVsdCA9ICA0MSAgICBdOworICBvcHRpb25hbCAgICBpbnQ2NCBkZWZhdWx0X2ludDY0ICAgID0gNjIgW2RlZmF1bHQgPSAgNDIgICAgXTsKKyAgb3B0aW9uYWwgICB1aW50MzIgZGVmYXVsdF91aW50MzIgICA9IDYzIFtkZWZhdWx0ID0gIDQzICAgIF07CisgIG9wdGlvbmFsICAgdWludDY0IGRlZmF1bHRfdWludDY0ICAgPSA2NCBbZGVmYXVsdCA9ICA0NCAgICBdOworICBvcHRpb25hbCAgIHNpbnQzMiBkZWZhdWx0X3NpbnQzMiAgID0gNjUgW2RlZmF1bHQgPSAtNDUgICAgXTsKKyAgb3B0aW9uYWwgICBzaW50NjQgZGVmYXVsdF9zaW50NjQgICA9IDY2IFtkZWZhdWx0ID0gIDQ2ICAgIF07CisgIG9wdGlvbmFsICBmaXhlZDMyIGRlZmF1bHRfZml4ZWQzMiAgPSA2NyBbZGVmYXVsdCA9ICA0NyAgICBdOworICBvcHRpb25hbCAgZml4ZWQ2NCBkZWZhdWx0X2ZpeGVkNjQgID0gNjggW2RlZmF1bHQgPSAgNDggICAgXTsKKyAgb3B0aW9uYWwgc2ZpeGVkMzIgZGVmYXVsdF9zZml4ZWQzMiA9IDY5IFtkZWZhdWx0ID0gIDQ5ICAgIF07CisgIG9wdGlvbmFsIHNmaXhlZDY0IGRlZmF1bHRfc2ZpeGVkNjQgPSA3MCBbZGVmYXVsdCA9IC01MCAgICBdOworICBvcHRpb25hbCAgICBmbG9hdCBkZWZhdWx0X2Zsb2F0ICAgID0gNzEgW2RlZmF1bHQgPSAgNTEuNSAgXTsKKyAgb3B0aW9uYWwgICBkb3VibGUgZGVmYXVsdF9kb3VibGUgICA9IDcyIFtkZWZhdWx0ID0gIDUyZTMgIF07CisgIG9wdGlvbmFsICAgICBib29sIGRlZmF1bHRfYm9vbCAgICAgPSA3MyBbZGVmYXVsdCA9IHRydWUgICBdOworICBvcHRpb25hbCAgIHN0cmluZyBkZWZhdWx0X3N0cmluZyAgID0gNzQgW2RlZmF1bHQgPSAiaGVsbG8iXTsKKyAgb3B0aW9uYWwgICAgYnl0ZXMgZGVmYXVsdF9ieXRlcyAgICA9IDc1IFtkZWZhdWx0ID0gIndvcmxkIl07CisKKyAgb3B0aW9uYWwgTmVzdGVkRW51bSBkZWZhdWx0X25lc3RlZF9lbnVtID0gODEgW2RlZmF1bHQgPSBCQVJdOworICBvcHRpb25hbCBGb3JlaWduRW51bUxpdGUgZGVmYXVsdF9mb3JlaWduX2VudW0gPSA4MgorICAgICAgW2RlZmF1bHQgPSBGT1JFSUdOX0xJVEVfQkFSXTsKKyAgb3B0aW9uYWwgcHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydEVudW1MaXRlCisgICAgICBkZWZhdWx0X2ltcG9ydF9lbnVtID0gODMgW2RlZmF1bHQgPSBJTVBPUlRfTElURV9CQVJdOworCisgIG9wdGlvbmFsIHN0cmluZyBkZWZhdWx0X3N0cmluZ19waWVjZSA9IDg0IFtjdHlwZT1TVFJJTkdfUElFQ0UsZGVmYXVsdD0iYWJjIl07CisgIG9wdGlvbmFsIHN0cmluZyBkZWZhdWx0X2NvcmQgPSA4NSBbY3R5cGU9Q09SRCxkZWZhdWx0PSIxMjMiXTsKKworICAvLyBGb3Igb25lb2YgdGVzdAorICBvbmVvZiBvbmVvZl9maWVsZCB7CisgICAgdWludDMyIG9uZW9mX3VpbnQzMiA9IDExMTsKKyAgICBOZXN0ZWRNZXNzYWdlIG9uZW9mX25lc3RlZF9tZXNzYWdlID0gMTEyOworICAgIHN0cmluZyBvbmVvZl9zdHJpbmcgPSAxMTM7CisgICAgYnl0ZXMgb25lb2ZfYnl0ZXMgPSAxMTQ7CisgIH0KK30KKworbWVzc2FnZSBGb3JlaWduTWVzc2FnZUxpdGUgeworICBvcHRpb25hbCBpbnQzMiBjID0gMTsKK30KKworZW51bSBGb3JlaWduRW51bUxpdGUgeworICBGT1JFSUdOX0xJVEVfRk9PID0gNDsKKyAgRk9SRUlHTl9MSVRFX0JBUiA9IDU7CisgIEZPUkVJR05fTElURV9CQVogPSA2OworfQorCittZXNzYWdlIFRlc3RQYWNrZWRUeXBlc0xpdGUgeworICByZXBlYXRlZCAgICBpbnQzMiBwYWNrZWRfaW50MzIgICAgPSAgOTAgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCAgICBpbnQ2NCBwYWNrZWRfaW50NjQgICAgPSAgOTEgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCAgIHVpbnQzMiBwYWNrZWRfdWludDMyICAgPSAgOTIgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCAgIHVpbnQ2NCBwYWNrZWRfdWludDY0ICAgPSAgOTMgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCAgIHNpbnQzMiBwYWNrZWRfc2ludDMyICAgPSAgOTQgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCAgIHNpbnQ2NCBwYWNrZWRfc2ludDY0ICAgPSAgOTUgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCAgZml4ZWQzMiBwYWNrZWRfZml4ZWQzMiAgPSAgOTYgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCAgZml4ZWQ2NCBwYWNrZWRfZml4ZWQ2NCAgPSAgOTcgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCBzZml4ZWQzMiBwYWNrZWRfc2ZpeGVkMzIgPSAgOTggW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCBzZml4ZWQ2NCBwYWNrZWRfc2ZpeGVkNjQgPSAgOTkgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCAgICBmbG9hdCBwYWNrZWRfZmxvYXQgICAgPSAxMDAgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCAgIGRvdWJsZSBwYWNrZWRfZG91YmxlICAgPSAxMDEgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCAgICAgYm9vbCBwYWNrZWRfYm9vbCAgICAgPSAxMDIgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCBGb3JlaWduRW51bUxpdGUgcGFja2VkX2VudW0gID0gMTAzIFtwYWNrZWQgPSB0cnVlXTsKK30KKworbWVzc2FnZSBUZXN0QWxsRXh0ZW5zaW9uc0xpdGUgeworICBleHRlbnNpb25zIDEgdG8gbWF4OworfQorCitleHRlbmQgVGVzdEFsbEV4dGVuc2lvbnNMaXRlIHsKKyAgLy8gU2luZ3VsYXIKKyAgb3B0aW9uYWwgICAgaW50MzIgb3B0aW9uYWxfaW50MzJfZXh0ZW5zaW9uX2xpdGUgICAgPSAgMTsKKyAgb3B0aW9uYWwgICAgaW50NjQgb3B0aW9uYWxfaW50NjRfZXh0ZW5zaW9uX2xpdGUgICAgPSAgMjsKKyAgb3B0aW9uYWwgICB1aW50MzIgb3B0aW9uYWxfdWludDMyX2V4dGVuc2lvbl9saXRlICAgPSAgMzsKKyAgb3B0aW9uYWwgICB1aW50NjQgb3B0aW9uYWxfdWludDY0X2V4dGVuc2lvbl9saXRlICAgPSAgNDsKKyAgb3B0aW9uYWwgICBzaW50MzIgb3B0aW9uYWxfc2ludDMyX2V4dGVuc2lvbl9saXRlICAgPSAgNTsKKyAgb3B0aW9uYWwgICBzaW50NjQgb3B0aW9uYWxfc2ludDY0X2V4dGVuc2lvbl9saXRlICAgPSAgNjsKKyAgb3B0aW9uYWwgIGZpeGVkMzIgb3B0aW9uYWxfZml4ZWQzMl9leHRlbnNpb25fbGl0ZSAgPSAgNzsKKyAgb3B0aW9uYWwgIGZpeGVkNjQgb3B0aW9uYWxfZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSAgPSAgODsKKyAgb3B0aW9uYWwgc2ZpeGVkMzIgb3B0aW9uYWxfc2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUgPSAgOTsKKyAgb3B0aW9uYWwgc2ZpeGVkNjQgb3B0aW9uYWxfc2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUgPSAxMDsKKyAgb3B0aW9uYWwgICAgZmxvYXQgb3B0aW9uYWxfZmxvYXRfZXh0ZW5zaW9uX2xpdGUgICAgPSAxMTsKKyAgb3B0aW9uYWwgICBkb3VibGUgb3B0aW9uYWxfZG91YmxlX2V4dGVuc2lvbl9saXRlICAgPSAxMjsKKyAgb3B0aW9uYWwgICAgIGJvb2wgb3B0aW9uYWxfYm9vbF9leHRlbnNpb25fbGl0ZSAgICAgPSAxMzsKKyAgb3B0aW9uYWwgICBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nX2V4dGVuc2lvbl9saXRlICAgPSAxNDsKKyAgb3B0aW9uYWwgICAgYnl0ZXMgb3B0aW9uYWxfYnl0ZXNfZXh0ZW5zaW9uX2xpdGUgICAgPSAxNTsKKworICBvcHRpb25hbCBncm91cCBPcHRpb25hbEdyb3VwX2V4dGVuc2lvbl9saXRlID0gMTYgeworICAgIG9wdGlvbmFsIGludDMyIGEgPSAxNzsKKyAgfQorCisgIG9wdGlvbmFsIFRlc3RBbGxUeXBlc0xpdGUuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb25fbGl0ZQorICAgICAgPSAxODsKKyAgb3B0aW9uYWwgRm9yZWlnbk1lc3NhZ2VMaXRlIG9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb25fbGl0ZSA9IDE5OworICBvcHRpb25hbCBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZUxpdGUKKyAgICBvcHRpb25hbF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSA9IDIwOworCisgIG9wdGlvbmFsIFRlc3RBbGxUeXBlc0xpdGUuTmVzdGVkRW51bSBvcHRpb25hbF9uZXN0ZWRfZW51bV9leHRlbnNpb25fbGl0ZSA9IDIxOworICBvcHRpb25hbCBGb3JlaWduRW51bUxpdGUgb3B0aW9uYWxfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbl9saXRlID0gMjI7CisgIG9wdGlvbmFsIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtTGl0ZQorICAgIG9wdGlvbmFsX2ltcG9ydF9lbnVtX2V4dGVuc2lvbl9saXRlID0gMjM7CisKKyAgb3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3N0cmluZ19waWVjZV9leHRlbnNpb25fbGl0ZSA9IDI0CisgICAgICBbY3R5cGU9U1RSSU5HX1BJRUNFXTsKKyAgb3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX2NvcmRfZXh0ZW5zaW9uX2xpdGUgPSAyNSBbY3R5cGU9Q09SRF07CisKKyAgb3B0aW9uYWwgcHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LlB1YmxpY0ltcG9ydE1lc3NhZ2VMaXRlCisgICAgb3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbl9saXRlID0gMjY7CisKKyAgb3B0aW9uYWwgVGVzdEFsbFR5cGVzTGl0ZS5OZXN0ZWRNZXNzYWdlCisgICAgb3B0aW9uYWxfbGF6eV9tZXNzYWdlX2V4dGVuc2lvbl9saXRlID0gMjcgW2xhenk9dHJ1ZV07CisKKyAgLy8gUmVwZWF0ZWQKKyAgcmVwZWF0ZWQgICAgaW50MzIgcmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9uX2xpdGUgICAgPSAzMTsKKyAgcmVwZWF0ZWQgICAgaW50NjQgcmVwZWF0ZWRfaW50NjRfZXh0ZW5zaW9uX2xpdGUgICAgPSAzMjsKKyAgcmVwZWF0ZWQgICB1aW50MzIgcmVwZWF0ZWRfdWludDMyX2V4dGVuc2lvbl9saXRlICAgPSAzMzsKKyAgcmVwZWF0ZWQgICB1aW50NjQgcmVwZWF0ZWRfdWludDY0X2V4dGVuc2lvbl9saXRlICAgPSAzNDsKKyAgcmVwZWF0ZWQgICBzaW50MzIgcmVwZWF0ZWRfc2ludDMyX2V4dGVuc2lvbl9saXRlICAgPSAzNTsKKyAgcmVwZWF0ZWQgICBzaW50NjQgcmVwZWF0ZWRfc2ludDY0X2V4dGVuc2lvbl9saXRlICAgPSAzNjsKKyAgcmVwZWF0ZWQgIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMl9leHRlbnNpb25fbGl0ZSAgPSAzNzsKKyAgcmVwZWF0ZWQgIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NF9leHRlbnNpb25fbGl0ZSAgPSAzODsKKyAgcmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUgPSAzOTsKKyAgcmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUgPSA0MDsKKyAgcmVwZWF0ZWQgICAgZmxvYXQgcmVwZWF0ZWRfZmxvYXRfZXh0ZW5zaW9uX2xpdGUgICAgPSA0MTsKKyAgcmVwZWF0ZWQgICBkb3VibGUgcmVwZWF0ZWRfZG91YmxlX2V4dGVuc2lvbl9saXRlICAgPSA0MjsKKyAgcmVwZWF0ZWQgICAgIGJvb2wgcmVwZWF0ZWRfYm9vbF9leHRlbnNpb25fbGl0ZSAgICAgPSA0MzsKKyAgcmVwZWF0ZWQgICBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX2V4dGVuc2lvbl9saXRlICAgPSA0NDsKKyAgcmVwZWF0ZWQgICAgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXNfZXh0ZW5zaW9uX2xpdGUgICAgPSA0NTsKKworICByZXBlYXRlZCBncm91cCBSZXBlYXRlZEdyb3VwX2V4dGVuc2lvbl9saXRlID0gNDYgeworICAgIG9wdGlvbmFsIGludDMyIGEgPSA0NzsKKyAgfQorCisgIHJlcGVhdGVkIFRlc3RBbGxUeXBlc0xpdGUuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb25fbGl0ZQorICAgICAgPSA0ODsKKyAgcmVwZWF0ZWQgRm9yZWlnbk1lc3NhZ2VMaXRlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb25fbGl0ZSA9IDQ5OworICByZXBlYXRlZCBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZUxpdGUKKyAgICByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb25fbGl0ZSA9IDUwOworCisgIHJlcGVhdGVkIFRlc3RBbGxUeXBlc0xpdGUuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bV9leHRlbnNpb25fbGl0ZSA9IDUxOworICByZXBlYXRlZCBGb3JlaWduRW51bUxpdGUgcmVwZWF0ZWRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbl9saXRlID0gNTI7CisgIHJlcGVhdGVkIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtTGl0ZQorICAgIHJlcGVhdGVkX2ltcG9ydF9lbnVtX2V4dGVuc2lvbl9saXRlID0gNTM7CisKKyAgcmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19waWVjZV9leHRlbnNpb25fbGl0ZSA9IDU0CisgICAgICBbY3R5cGU9U1RSSU5HX1BJRUNFXTsKKyAgcmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX2NvcmRfZXh0ZW5zaW9uX2xpdGUgPSA1NSBbY3R5cGU9Q09SRF07CisKKyAgcmVwZWF0ZWQgVGVzdEFsbFR5cGVzTGl0ZS5OZXN0ZWRNZXNzYWdlCisgICAgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlX2V4dGVuc2lvbl9saXRlID0gNTcgW2xhenk9dHJ1ZV07CisKKyAgLy8gU2luZ3VsYXIgd2l0aCBkZWZhdWx0cworICBvcHRpb25hbCAgICBpbnQzMiBkZWZhdWx0X2ludDMyX2V4dGVuc2lvbl9saXRlICAgID0gNjEgW2RlZmF1bHQgPSAgNDEgICAgXTsKKyAgb3B0aW9uYWwgICAgaW50NjQgZGVmYXVsdF9pbnQ2NF9leHRlbnNpb25fbGl0ZSAgICA9IDYyIFtkZWZhdWx0ID0gIDQyICAgIF07CisgIG9wdGlvbmFsICAgdWludDMyIGRlZmF1bHRfdWludDMyX2V4dGVuc2lvbl9saXRlICAgPSA2MyBbZGVmYXVsdCA9ICA0MyAgICBdOworICBvcHRpb25hbCAgIHVpbnQ2NCBkZWZhdWx0X3VpbnQ2NF9leHRlbnNpb25fbGl0ZSAgID0gNjQgW2RlZmF1bHQgPSAgNDQgICAgXTsKKyAgb3B0aW9uYWwgICBzaW50MzIgZGVmYXVsdF9zaW50MzJfZXh0ZW5zaW9uX2xpdGUgICA9IDY1IFtkZWZhdWx0ID0gLTQ1ICAgIF07CisgIG9wdGlvbmFsICAgc2ludDY0IGRlZmF1bHRfc2ludDY0X2V4dGVuc2lvbl9saXRlICAgPSA2NiBbZGVmYXVsdCA9ICA0NiAgICBdOworICBvcHRpb25hbCAgZml4ZWQzMiBkZWZhdWx0X2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUgID0gNjcgW2RlZmF1bHQgPSAgNDcgICAgXTsKKyAgb3B0aW9uYWwgIGZpeGVkNjQgZGVmYXVsdF9maXhlZDY0X2V4dGVuc2lvbl9saXRlICA9IDY4IFtkZWZhdWx0ID0gIDQ4ICAgIF07CisgIG9wdGlvbmFsIHNmaXhlZDMyIGRlZmF1bHRfc2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUgPSA2OSBbZGVmYXVsdCA9ICA0OSAgICBdOworICBvcHRpb25hbCBzZml4ZWQ2NCBkZWZhdWx0X3NmaXhlZDY0X2V4dGVuc2lvbl9saXRlID0gNzAgW2RlZmF1bHQgPSAtNTAgICAgXTsKKyAgb3B0aW9uYWwgICAgZmxvYXQgZGVmYXVsdF9mbG9hdF9leHRlbnNpb25fbGl0ZSAgICA9IDcxIFtkZWZhdWx0ID0gIDUxLjUgIF07CisgIG9wdGlvbmFsICAgZG91YmxlIGRlZmF1bHRfZG91YmxlX2V4dGVuc2lvbl9saXRlICAgPSA3MiBbZGVmYXVsdCA9ICA1MmUzICBdOworICBvcHRpb25hbCAgICAgYm9vbCBkZWZhdWx0X2Jvb2xfZXh0ZW5zaW9uX2xpdGUgICAgID0gNzMgW2RlZmF1bHQgPSB0cnVlICAgXTsKKyAgb3B0aW9uYWwgICBzdHJpbmcgZGVmYXVsdF9zdHJpbmdfZXh0ZW5zaW9uX2xpdGUgICA9IDc0IFtkZWZhdWx0ID0gImhlbGxvIl07CisgIG9wdGlvbmFsICAgIGJ5dGVzIGRlZmF1bHRfYnl0ZXNfZXh0ZW5zaW9uX2xpdGUgICAgPSA3NSBbZGVmYXVsdCA9ICJ3b3JsZCJdOworCisgIG9wdGlvbmFsIFRlc3RBbGxUeXBlc0xpdGUuTmVzdGVkRW51bQorICAgIGRlZmF1bHRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uX2xpdGUgPSA4MSBbZGVmYXVsdCA9IEJBUl07CisgIG9wdGlvbmFsIEZvcmVpZ25FbnVtTGl0ZQorICAgIGRlZmF1bHRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbl9saXRlID0gODIgW2RlZmF1bHQgPSBGT1JFSUdOX0xJVEVfQkFSXTsKKyAgb3B0aW9uYWwgcHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydEVudW1MaXRlCisgICAgZGVmYXVsdF9pbXBvcnRfZW51bV9leHRlbnNpb25fbGl0ZSA9IDgzIFtkZWZhdWx0ID0gSU1QT1JUX0xJVEVfQkFSXTsKKworICBvcHRpb25hbCBzdHJpbmcgZGVmYXVsdF9zdHJpbmdfcGllY2VfZXh0ZW5zaW9uX2xpdGUgPSA4NCBbY3R5cGU9U1RSSU5HX1BJRUNFLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdD0iYWJjIl07CisgIG9wdGlvbmFsIHN0cmluZyBkZWZhdWx0X2NvcmRfZXh0ZW5zaW9uX2xpdGUgPSA4NSBbY3R5cGU9Q09SRCwgZGVmYXVsdD0iMTIzIl07CisKKyAgLy8gRm9yIG9uZW9mIHRlc3QKKyAgb3B0aW9uYWwgdWludDMyIG9uZW9mX3VpbnQzMl9leHRlbnNpb25fbGl0ZSA9IDExMTsKKyAgb3B0aW9uYWwgVGVzdEFsbFR5cGVzTGl0ZS5OZXN0ZWRNZXNzYWdlIG9uZW9mX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbl9saXRlID0gMTEyOworICBvcHRpb25hbCBzdHJpbmcgb25lb2Zfc3RyaW5nX2V4dGVuc2lvbl9saXRlID0gMTEzOworICBvcHRpb25hbCBieXRlcyBvbmVvZl9ieXRlc19leHRlbnNpb25fbGl0ZSA9IDExNDsKK30KKworbWVzc2FnZSBUZXN0UGFja2VkRXh0ZW5zaW9uc0xpdGUgeworICBleHRlbnNpb25zIDEgdG8gbWF4OworfQorCitleHRlbmQgVGVzdFBhY2tlZEV4dGVuc2lvbnNMaXRlIHsKKyAgcmVwZWF0ZWQgICAgaW50MzIgcGFja2VkX2ludDMyX2V4dGVuc2lvbl9saXRlICAgID0gIDkwIFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgICAgaW50NjQgcGFja2VkX2ludDY0X2V4dGVuc2lvbl9saXRlICAgID0gIDkxIFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgICB1aW50MzIgcGFja2VkX3VpbnQzMl9leHRlbnNpb25fbGl0ZSAgID0gIDkyIFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgICB1aW50NjQgcGFja2VkX3VpbnQ2NF9leHRlbnNpb25fbGl0ZSAgID0gIDkzIFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgICBzaW50MzIgcGFja2VkX3NpbnQzMl9leHRlbnNpb25fbGl0ZSAgID0gIDk0IFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgICBzaW50NjQgcGFja2VkX3NpbnQ2NF9leHRlbnNpb25fbGl0ZSAgID0gIDk1IFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgIGZpeGVkMzIgcGFja2VkX2ZpeGVkMzJfZXh0ZW5zaW9uX2xpdGUgID0gIDk2IFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgIGZpeGVkNjQgcGFja2VkX2ZpeGVkNjRfZXh0ZW5zaW9uX2xpdGUgID0gIDk3IFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgc2ZpeGVkMzIgcGFja2VkX3NmaXhlZDMyX2V4dGVuc2lvbl9saXRlID0gIDk4IFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgc2ZpeGVkNjQgcGFja2VkX3NmaXhlZDY0X2V4dGVuc2lvbl9saXRlID0gIDk5IFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgICAgZmxvYXQgcGFja2VkX2Zsb2F0X2V4dGVuc2lvbl9saXRlICAgID0gMTAwIFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgICBkb3VibGUgcGFja2VkX2RvdWJsZV9leHRlbnNpb25fbGl0ZSAgID0gMTAxIFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgICAgIGJvb2wgcGFja2VkX2Jvb2xfZXh0ZW5zaW9uX2xpdGUgICAgID0gMTAyIFtwYWNrZWQgPSB0cnVlXTsKKyAgcmVwZWF0ZWQgRm9yZWlnbkVudW1MaXRlIHBhY2tlZF9lbnVtX2V4dGVuc2lvbl9saXRlID0gMTAzIFtwYWNrZWQgPSB0cnVlXTsKK30KKworbWVzc2FnZSBUZXN0TmVzdGVkRXh0ZW5zaW9uTGl0ZSB7CisgIGV4dGVuZCBUZXN0QWxsRXh0ZW5zaW9uc0xpdGUgeworICAgIG9wdGlvbmFsIGludDMyIG5lc3RlZF9leHRlbnNpb24gPSAxMjM0NTsKKyAgfQorfQorCisvLyBUZXN0IHRoYXQgZGVwcmVjYXRlZCBmaWVsZHMgd29yay4gIFdlIG9ubHkgdmVyaWZ5IHRoYXQgdGhleSBjb21waWxlIChhdCBvbmUKKy8vIHBvaW50IHRoaXMgZmFpbGVkKS4KK21lc3NhZ2UgVGVzdERlcHJlY2F0ZWRMaXRlIHsKKyAgb3B0aW9uYWwgaW50MzIgZGVwcmVjYXRlZF9maWVsZCA9IDEgW2RlcHJlY2F0ZWQgPSB0cnVlXTsKK30KKworLy8gU2VlIHRoZSBjb21tZW50cyBvZiB0aGUgc2FtZSB0eXBlIGluIHVuaXR0ZXN0LnByb3RvLgorbWVzc2FnZSBUZXN0UGFyc2luZ01lcmdlTGl0ZSB7CisgIG1lc3NhZ2UgUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IgeworICAgIHJlcGVhdGVkIFRlc3RBbGxUeXBlc0xpdGUgZmllbGQxID0gMTsKKyAgICByZXBlYXRlZCBUZXN0QWxsVHlwZXNMaXRlIGZpZWxkMiA9IDI7CisgICAgcmVwZWF0ZWQgVGVzdEFsbFR5cGVzTGl0ZSBmaWVsZDMgPSAzOworICAgIHJlcGVhdGVkIGdyb3VwIEdyb3VwMSA9IDEwIHsKKyAgICAgIG9wdGlvbmFsIFRlc3RBbGxUeXBlc0xpdGUgZmllbGQxID0gMTE7CisgICAgfQorICAgIHJlcGVhdGVkIGdyb3VwIEdyb3VwMiA9IDIwIHsKKyAgICAgIG9wdGlvbmFsIFRlc3RBbGxUeXBlc0xpdGUgZmllbGQxID0gMjE7CisgICAgfQorICAgIHJlcGVhdGVkIFRlc3RBbGxUeXBlc0xpdGUgZXh0MSA9IDEwMDA7CisgICAgcmVwZWF0ZWQgVGVzdEFsbFR5cGVzTGl0ZSBleHQyID0gMTAwMTsKKyAgfQorICByZXF1aXJlZCBUZXN0QWxsVHlwZXNMaXRlIHJlcXVpcmVkX2FsbF90eXBlcyA9IDE7CisgIG9wdGlvbmFsIFRlc3RBbGxUeXBlc0xpdGUgb3B0aW9uYWxfYWxsX3R5cGVzID0gMjsKKyAgcmVwZWF0ZWQgVGVzdEFsbFR5cGVzTGl0ZSByZXBlYXRlZF9hbGxfdHlwZXMgPSAzOworICBvcHRpb25hbCBncm91cCBPcHRpb25hbEdyb3VwID0gMTAgeworICAgIG9wdGlvbmFsIFRlc3RBbGxUeXBlc0xpdGUgb3B0aW9uYWxfZ3JvdXBfYWxsX3R5cGVzID0gMTE7CisgIH0KKyAgcmVwZWF0ZWQgZ3JvdXAgUmVwZWF0ZWRHcm91cCA9IDIwIHsKKyAgICBvcHRpb25hbCBUZXN0QWxsVHlwZXNMaXRlIHJlcGVhdGVkX2dyb3VwX2FsbF90eXBlcyA9IDIxOworICB9CisgIGV4dGVuc2lvbnMgMTAwMCB0byBtYXg7CisgIGV4dGVuZCBUZXN0UGFyc2luZ01lcmdlTGl0ZSB7CisgICAgb3B0aW9uYWwgVGVzdEFsbFR5cGVzTGl0ZSBvcHRpb25hbF9leHQgPSAxMDAwOworICAgIHJlcGVhdGVkIFRlc3RBbGxUeXBlc0xpdGUgcmVwZWF0ZWRfZXh0ID0gMTAwMTsKKyAgfQorfQorCisvLyBUZXN0RW1wdHlNZXNzYWdlTGl0ZSBpcyB1c2VkIHRvIHRlc3QgdW5rbm93biBmaWVsZHMgc3VwcG9ydCBpbiBsaXRlIG1vZGUuCittZXNzYWdlIFRlc3RFbXB0eU1lc3NhZ2VMaXRleworfQorCisvLyBMaWtlIGFib3ZlLCBidXQgZGVjbGFyZSBhbGwgZmllbGQgbnVtYmVycyBhcyBwb3RlbnRpYWwgZXh0ZW5zaW9ucy4gIE5vCisvLyBhY3R1YWwgZXh0ZW5zaW9ucyBzaG91bGQgZXZlciBiZSBkZWZpbmVkIGZvciB0aGlzIHR5cGUuCittZXNzYWdlIFRlc3RFbXB0eU1lc3NhZ2VXaXRoRXh0ZW5zaW9uc0xpdGUgeworICBleHRlbnNpb25zIDEgdG8gbWF4OworfQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9saXRlX2ltcG9ydHNfbm9ubGl0ZS5wcm90byBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfbGl0ZV9pbXBvcnRzX25vbmxpdGUucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTMyZDZhOAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfbGl0ZV9pbXBvcnRzX25vbmxpdGUucHJvdG8KQEAgLTAsMCArMSw0NCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vCisvLyBUZXN0cyB0aGF0IGEgImxpdGUiIG1lc3NhZ2UgY2FuIGltcG9ydCBhIHJlZ3VsYXIgbWVzc2FnZS4KKworc3ludGF4ID0gInByb3RvMiI7CitwYWNrYWdlIHByb3RvYnVmX3VuaXR0ZXN0OworCitpbXBvcnQgImdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wcm90byI7CisKK29wdGlvbiBvcHRpbWl6ZV9mb3IgPSBMSVRFX1JVTlRJTUU7CisKK21lc3NhZ2UgVGVzdExpdGVJbXBvcnRzTm9ubGl0ZSB7CisgIG9wdGlvbmFsIFRlc3RBbGxUeXBlcyBtZXNzYWdlID0gMTsKK30KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfbXNldC5wcm90byBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfbXNldC5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40OWQ5YWRhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9tc2V0LnByb3RvCkBAIC0wLDAgKzEsODIgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBUaGlzIGZpbGUgaXMgc2ltaWxhciB0byB1bml0dGVzdF9tc2V0X3dpcmVfZm9ybWF0LnByb3RvLCBidXQgZG9lcyBub3QKKy8vIGhhdmUgYSBUZXN0TWVzc2FnZVNldCwgc28gaXQgY2FuIGJlIGRvd25ncmFkZWQgdG8gcHJvdG8xLgorCitzeW50YXggPSAicHJvdG8yIjsKKworaW1wb3J0ICJnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfbXNldF93aXJlX2Zvcm1hdC5wcm90byI7CisKK3BhY2thZ2UgcHJvdG9idWZfdW5pdHRlc3Q7CisKK29wdGlvbiBjY19lbmFibGVfYXJlbmFzID0gdHJ1ZTsKK29wdGlvbiBvcHRpbWl6ZV9mb3IgPSBTUEVFRDsKKworbWVzc2FnZSBUZXN0TWVzc2FnZVNldENvbnRhaW5lciB7CisgIG9wdGlvbmFsIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0IG1lc3NhZ2Vfc2V0ID0gMTsKK30KKworbWVzc2FnZSBUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjEgeworICBleHRlbmQgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXQgeworICAgIG9wdGlvbmFsIFRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMSBtZXNzYWdlX3NldF9leHRlbnNpb24gPSAxNTQ1MDA4OworICB9CisgIG9wdGlvbmFsIGludDMyIGkgPSAxNTsKK30KKworbWVzc2FnZSBUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjIgeworICBleHRlbmQgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXQgeworICAgIG9wdGlvbmFsIFRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMiBtZXNzYWdlX3NldF9leHRlbnNpb24gPSAxNTQ3NzY5OworICB9CisgIG9wdGlvbmFsIHN0cmluZyBzdHIgPSAyNTsKK30KKworLy8gVGhpcyBtZXNzYWdlIHdhcyB1c2VkIHRvIGdlbmVyYXRlCisvLyAvL25ldC9wcm90bzIvcHl0aG9uL2ludGVybmFsL3Rlc3RkYXRhL21lc3NhZ2Vfc2V0X21lc3NhZ2UsIGJ1dCBpcyBjb21tZW50ZWQKKy8vIG91dCBzaW5jZSBpdCBtdXN0IG5vdCBhY3R1YWxseSBleGlzdCBpbiBjb2RlLCB0byBzaW11bGF0ZSBhbiAidW5rbm93biIKKy8vIGV4dGVuc2lvbi4KKy8vIG1lc3NhZ2UgVGVzdE1lc3NhZ2VTZXRVbmtub3duRXh0ZW5zaW9uIHsKKy8vICAgZXh0ZW5kIFRlc3RNZXNzYWdlU2V0IHsKKy8vICAgICBvcHRpb25hbCBUZXN0TWVzc2FnZVNldFVua25vd25FeHRlbnNpb24gbWVzc2FnZV9zZXRfZXh0ZW5zaW9uID0gNTYxNDE0MjE7CisvLyAgIH0KKy8vICAgb3B0aW9uYWwgaW50NjQgYSA9IDE7CisvLyB9CisKKy8vIE1lc3NhZ2VTZXQgd2lyZSBmb3JtYXQgaXMgZXF1aXZhbGVudCB0byB0aGlzLgorbWVzc2FnZSBSYXdNZXNzYWdlU2V0IHsKKyAgcmVwZWF0ZWQgZ3JvdXAgSXRlbSA9IDEgeworICAgIHJlcXVpcmVkIGludDMyIHR5cGVfaWQgPSAyOworICAgIHJlcXVpcmVkIGJ5dGVzIG1lc3NhZ2UgPSAzOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X21zZXRfd2lyZV9mb3JtYXQucHJvdG8gYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X21zZXRfd2lyZV9mb3JtYXQucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDRlNDM1MgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfbXNldF93aXJlX2Zvcm1hdC5wcm90bwpAQCAtMCwwICsxLDUyIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisvLworLy8gVGhpcyBmaWxlIGNvbnRhaW5zIG1lc3NhZ2VzIGZvciB0ZXN0aW5nIG1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0LgorCitzeW50YXggPSAicHJvdG8yIjsKK3BhY2thZ2UgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3Q7CisKK29wdGlvbiBjY19lbmFibGVfYXJlbmFzID0gdHJ1ZTsKK29wdGlvbiBvcHRpbWl6ZV9mb3IgPSBTUEVFRDsKK29wdGlvbiBjc2hhcnBfbmFtZXNwYWNlID0gIkdvb2dsZS5Qcm90b2NvbEJ1ZmZlcnMuVGVzdFByb3RvcyI7CisKKy8vIEEgbWVzc2FnZSB3aXRoIG1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0LgorbWVzc2FnZSBUZXN0TWVzc2FnZVNldCB7CisgIG9wdGlvbiBtZXNzYWdlX3NldF93aXJlX2Zvcm1hdCA9IHRydWU7CisgIGV4dGVuc2lvbnMgNCB0byBtYXg7Cit9CisKK21lc3NhZ2UgVGVzdE1lc3NhZ2VTZXRXaXJlRm9ybWF0Q29udGFpbmVyIHsKKyAgb3B0aW9uYWwgVGVzdE1lc3NhZ2VTZXQgbWVzc2FnZV9zZXQgPSAxOworfQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9ub19hcmVuYS5wcm90byBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fYXJlbmEucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDE1MThkZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fYXJlbmEucHJvdG8KQEAgLTAsMCArMSwyMDIgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBUaGlzIHByb3RvIGZpbGUgY29udGFpbnMgY29waWVzIG9mIFRlc3RBbGxUeXBlcyBhbmQgZnJpZW5kcywgYnV0IHdpdGggYXJlbmEKKy8vIHN1cHBvcnQgZGlzYWJsZWQgaW4gY29kZSBnZW5lcmF0aW9uLiBJdCBhbGxvd3MgdXMgdG8gdGVzdCB0aGUgcGVyZm9ybWFuY2UKKy8vIGltcGFjdCBhZ2FpbnN0IGJhc2VsaW5lIChub24tYXJlbmEpIGdvb2dsZS5wcm90b2J1Zi4KKworc3ludGF4ID0gInByb3RvMiI7CisKKy8vIFNvbWUgZ2VuZXJpY19zZXJ2aWNlcyBvcHRpb24ocykgYWRkZWQgYXV0b21hdGljYWxseS4KKy8vIFNlZTogIGh0dHA6Ly9nby9wcm90bzItZ2VuZXJpYy1zZXJ2aWNlcy1kZWZhdWx0CitvcHRpb24gY2NfZ2VuZXJpY19zZXJ2aWNlcyA9IHRydWU7ICAgICAvLyBhdXRvLWFkZGVkCitvcHRpb24gamF2YV9nZW5lcmljX3NlcnZpY2VzID0gdHJ1ZTsgICAvLyBhdXRvLWFkZGVkCitvcHRpb24gcHlfZ2VuZXJpY19zZXJ2aWNlcyA9IHRydWU7ICAgICAvLyBhdXRvLWFkZGVkCitvcHRpb24gY2NfZW5hYmxlX2FyZW5hcyA9IGZhbHNlOworb3B0aW9uIG9iamNfY2xhc3NfcHJlZml4ID0gIk5PQVJOIjsKKworaW1wb3J0ICJnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0LnByb3RvIjsKK2ltcG9ydCAiZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2FyZW5hLnByb3RvIjsKKworLy8gV2UgZG9uJ3QgcHV0IHRoaXMgaW4gYSBwYWNrYWdlIHdpdGhpbiBwcm90bzIgYmVjYXVzZSB3ZSBuZWVkIHRvIG1ha2Ugc3VyZQorLy8gdGhhdCB0aGUgZ2VuZXJhdGVkIGNvZGUgZG9lc24ndCBkZXBlbmQgb24gYmVpbmcgaW4gdGhlIHByb3RvMiBuYW1lc3BhY2UuCisvLyBJbiB0ZXN0X3V0aWwuaCB3ZSBkbyAidXNpbmcgbmFtZXNwYWNlIHVuaXR0ZXN0ID0gcHJvdG9idWZfdW5pdHRlc3QiLgorcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdF9ub19hcmVuYTsKKworLy8gUHJvdG9zIG9wdGltaXplZCBmb3IgU1BFRUQgdXNlIGEgc3RyaWN0IHN1cGVyc2V0IG9mIHRoZSBnZW5lcmF0ZWQgY29kZQorLy8gb2YgZXF1aXZhbGVudCBvbmVzIG9wdGltaXplZCBmb3IgQ09ERV9TSVpFLCBzbyB3ZSBzaG91bGQgb3B0aW1pemUgYWxsIG91cgorLy8gdGVzdHMgZm9yIHNwZWVkIHVubGVzcyBleHBsaWNpdGx5IHRlc3RpbmcgY29kZSBzaXplIG9wdGltaXphdGlvbi4KK29wdGlvbiBvcHRpbWl6ZV9mb3IgPSBTUEVFRDsKKworb3B0aW9uIGphdmFfb3V0ZXJfY2xhc3NuYW1lID0gIlVuaXR0ZXN0UHJvdG8iOworCisvLyBUaGlzIHByb3RvIGluY2x1ZGVzIGV2ZXJ5IHR5cGUgb2YgZmllbGQgaW4gYm90aCBzaW5ndWxhciBhbmQgcmVwZWF0ZWQKKy8vIGZvcm1zLgorbWVzc2FnZSBUZXN0QWxsVHlwZXMgeworICBtZXNzYWdlIE5lc3RlZE1lc3NhZ2UgeworICAgIC8vIFRoZSBmaWVsZCBuYW1lICJiIiBmYWlscyB0byBjb21waWxlIGluIHByb3RvMSBiZWNhdXNlIGl0IGNvbmZsaWN0cyB3aXRoCisgICAgLy8gYSBsb2NhbCB2YXJpYWJsZSBuYW1lZCAiYiIgaW4gb25lIG9mIHRoZSBnZW5lcmF0ZWQgbWV0aG9kcy4gIERvaC4KKyAgICAvLyBUaGlzIGZpbGUgbmVlZHMgdG8gY29tcGlsZSBpbiBwcm90bzEgdG8gdGVzdCBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eS4KKyAgICBvcHRpb25hbCBpbnQzMiBiYiA9IDE7CisgIH0KKworICBlbnVtIE5lc3RlZEVudW0geworICAgIEZPTyA9IDE7CisgICAgQkFSID0gMjsKKyAgICBCQVogPSAzOworICAgIE5FRyA9IC0xOyAgLy8gSW50ZW50aW9uYWxseSBuZWdhdGl2ZS4KKyAgfQorCisgIC8vIFNpbmd1bGFyCisgIG9wdGlvbmFsICAgIGludDMyIG9wdGlvbmFsX2ludDMyICAgID0gIDE7CisgIG9wdGlvbmFsICAgIGludDY0IG9wdGlvbmFsX2ludDY0ICAgID0gIDI7CisgIG9wdGlvbmFsICAgdWludDMyIG9wdGlvbmFsX3VpbnQzMiAgID0gIDM7CisgIG9wdGlvbmFsICAgdWludDY0IG9wdGlvbmFsX3VpbnQ2NCAgID0gIDQ7CisgIG9wdGlvbmFsICAgc2ludDMyIG9wdGlvbmFsX3NpbnQzMiAgID0gIDU7CisgIG9wdGlvbmFsICAgc2ludDY0IG9wdGlvbmFsX3NpbnQ2NCAgID0gIDY7CisgIG9wdGlvbmFsICBmaXhlZDMyIG9wdGlvbmFsX2ZpeGVkMzIgID0gIDc7CisgIG9wdGlvbmFsICBmaXhlZDY0IG9wdGlvbmFsX2ZpeGVkNjQgID0gIDg7CisgIG9wdGlvbmFsIHNmaXhlZDMyIG9wdGlvbmFsX3NmaXhlZDMyID0gIDk7CisgIG9wdGlvbmFsIHNmaXhlZDY0IG9wdGlvbmFsX3NmaXhlZDY0ID0gMTA7CisgIG9wdGlvbmFsICAgIGZsb2F0IG9wdGlvbmFsX2Zsb2F0ICAgID0gMTE7CisgIG9wdGlvbmFsICAgZG91YmxlIG9wdGlvbmFsX2RvdWJsZSAgID0gMTI7CisgIG9wdGlvbmFsICAgICBib29sIG9wdGlvbmFsX2Jvb2wgICAgID0gMTM7CisgIG9wdGlvbmFsICAgc3RyaW5nIG9wdGlvbmFsX3N0cmluZyAgID0gMTQ7CisgIG9wdGlvbmFsICAgIGJ5dGVzIG9wdGlvbmFsX2J5dGVzICAgID0gMTU7CisKKyAgb3B0aW9uYWwgZ3JvdXAgT3B0aW9uYWxHcm91cCA9IDE2IHsKKyAgICBvcHRpb25hbCBpbnQzMiBhID0gMTc7CisgIH0KKworICBvcHRpb25hbCBOZXN0ZWRNZXNzYWdlICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgID0gMTg7CisgIG9wdGlvbmFsIEZvcmVpZ25NZXNzYWdlICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgPSAxOTsKKyAgb3B0aW9uYWwgcHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgID0gMjA7CisKKyAgb3B0aW9uYWwgTmVzdGVkRW51bSAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbmFsX25lc3RlZF9lbnVtICAgICA9IDIxOworICBvcHRpb25hbCBGb3JlaWduRW51bSAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uYWxfZm9yZWlnbl9lbnVtICAgID0gMjI7CisgIG9wdGlvbmFsIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtICAgIG9wdGlvbmFsX2ltcG9ydF9lbnVtICAgICA9IDIzOworCisgIG9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9zdHJpbmdfcGllY2UgPSAyNCBbY3R5cGU9U1RSSU5HX1BJRUNFXTsKKyAgb3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX2NvcmQgPSAyNSBbY3R5cGU9Q09SRF07CisKKyAgLy8gRGVmaW5lZCBpbiB1bml0dGVzdF9pbXBvcnRfcHVibGljLnByb3RvCisgIG9wdGlvbmFsIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5QdWJsaWNJbXBvcnRNZXNzYWdlCisgICAgICBvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UgPSAyNjsKKworICBvcHRpb25hbCBOZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX21lc3NhZ2UgPSAyNyBbbGF6eT10cnVlXTsKKworICAvLyBSZXBlYXRlZAorICByZXBlYXRlZCAgICBpbnQzMiByZXBlYXRlZF9pbnQzMiAgICA9IDMxOworICByZXBlYXRlZCAgICBpbnQ2NCByZXBlYXRlZF9pbnQ2NCAgICA9IDMyOworICByZXBlYXRlZCAgIHVpbnQzMiByZXBlYXRlZF91aW50MzIgICA9IDMzOworICByZXBlYXRlZCAgIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgICA9IDM0OworICByZXBlYXRlZCAgIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgICA9IDM1OworICByZXBlYXRlZCAgIHNpbnQ2NCByZXBlYXRlZF9zaW50NjQgICA9IDM2OworICByZXBlYXRlZCAgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyICA9IDM3OworICByZXBlYXRlZCAgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ICA9IDM4OworICByZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDM5OworICByZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDQwOworICByZXBlYXRlZCAgICBmbG9hdCByZXBlYXRlZF9mbG9hdCAgICA9IDQxOworICByZXBlYXRlZCAgIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgICA9IDQyOworICByZXBlYXRlZCAgICAgYm9vbCByZXBlYXRlZF9ib29sICAgICA9IDQzOworICByZXBlYXRlZCAgIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgICA9IDQ0OworICByZXBlYXRlZCAgICBieXRlcyByZXBlYXRlZF9ieXRlcyAgICA9IDQ1OworCisgIHJlcGVhdGVkIGdyb3VwIFJlcGVhdGVkR3JvdXAgPSA0NiB7CisgICAgb3B0aW9uYWwgaW50MzIgYSA9IDQ3OworICB9CisKKyAgcmVwZWF0ZWQgTmVzdGVkTWVzc2FnZSAgICAgICAgICAgICAgICAgICAgICAgIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlICA9IDQ4OworICByZXBlYXRlZCBGb3JlaWduTWVzc2FnZSAgICAgICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlID0gNDk7CisgIHJlcGVhdGVkIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlICA9IDUwOworCisgIHJlcGVhdGVkIE5lc3RlZEVudW0gICAgICAgICAgICAgICAgICAgICAgICAgICByZXBlYXRlZF9uZXN0ZWRfZW51bSAgICAgPSA1MTsKKyAgcmVwZWF0ZWQgRm9yZWlnbkVudW0gICAgICAgICAgICAgICAgICAgICAgICAgIHJlcGVhdGVkX2ZvcmVpZ25fZW51bSAgICA9IDUyOworICByZXBlYXRlZCBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0RW51bSAgICByZXBlYXRlZF9pbXBvcnRfZW51bSAgICAgPSA1MzsKKworICByZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlPVNUUklOR19QSUVDRV07CisgIHJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9jb3JkID0gNTUgW2N0eXBlPUNPUkRdOworCisgIHJlcGVhdGVkIE5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenk9dHJ1ZV07CisKKyAgLy8gU2luZ3VsYXIgd2l0aCBkZWZhdWx0cworICBvcHRpb25hbCAgICBpbnQzMiBkZWZhdWx0X2ludDMyICAgID0gNjEgW2RlZmF1bHQgPSAgNDEgICAgXTsKKyAgb3B0aW9uYWwgICAgaW50NjQgZGVmYXVsdF9pbnQ2NCAgICA9IDYyIFtkZWZhdWx0ID0gIDQyICAgIF07CisgIG9wdGlvbmFsICAgdWludDMyIGRlZmF1bHRfdWludDMyICAgPSA2MyBbZGVmYXVsdCA9ICA0MyAgICBdOworICBvcHRpb25hbCAgIHVpbnQ2NCBkZWZhdWx0X3VpbnQ2NCAgID0gNjQgW2RlZmF1bHQgPSAgNDQgICAgXTsKKyAgb3B0aW9uYWwgICBzaW50MzIgZGVmYXVsdF9zaW50MzIgICA9IDY1IFtkZWZhdWx0ID0gLTQ1ICAgIF07CisgIG9wdGlvbmFsICAgc2ludDY0IGRlZmF1bHRfc2ludDY0ICAgPSA2NiBbZGVmYXVsdCA9ICA0NiAgICBdOworICBvcHRpb25hbCAgZml4ZWQzMiBkZWZhdWx0X2ZpeGVkMzIgID0gNjcgW2RlZmF1bHQgPSAgNDcgICAgXTsKKyAgb3B0aW9uYWwgIGZpeGVkNjQgZGVmYXVsdF9maXhlZDY0ICA9IDY4IFtkZWZhdWx0ID0gIDQ4ICAgIF07CisgIG9wdGlvbmFsIHNmaXhlZDMyIGRlZmF1bHRfc2ZpeGVkMzIgPSA2OSBbZGVmYXVsdCA9ICA0OSAgICBdOworICBvcHRpb25hbCBzZml4ZWQ2NCBkZWZhdWx0X3NmaXhlZDY0ID0gNzAgW2RlZmF1bHQgPSAtNTAgICAgXTsKKyAgb3B0aW9uYWwgICAgZmxvYXQgZGVmYXVsdF9mbG9hdCAgICA9IDcxIFtkZWZhdWx0ID0gIDUxLjUgIF07CisgIG9wdGlvbmFsICAgZG91YmxlIGRlZmF1bHRfZG91YmxlICAgPSA3MiBbZGVmYXVsdCA9ICA1MmUzICBdOworICBvcHRpb25hbCAgICAgYm9vbCBkZWZhdWx0X2Jvb2wgICAgID0gNzMgW2RlZmF1bHQgPSB0cnVlICAgXTsKKyAgb3B0aW9uYWwgICBzdHJpbmcgZGVmYXVsdF9zdHJpbmcgICA9IDc0IFtkZWZhdWx0ID0gImhlbGxvIl07CisgIG9wdGlvbmFsICAgIGJ5dGVzIGRlZmF1bHRfYnl0ZXMgICAgPSA3NSBbZGVmYXVsdCA9ICJ3b3JsZCJdOworCisgIG9wdGlvbmFsIE5lc3RlZEVudW0gIGRlZmF1bHRfbmVzdGVkX2VudW0gID0gODEgW2RlZmF1bHQgPSBCQVIgICAgICAgIF07CisgIG9wdGlvbmFsIEZvcmVpZ25FbnVtIGRlZmF1bHRfZm9yZWlnbl9lbnVtID0gODIgW2RlZmF1bHQgPSBGT1JFSUdOX0JBUl07CisgIG9wdGlvbmFsIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtCisgICAgICBkZWZhdWx0X2ltcG9ydF9lbnVtID0gODMgW2RlZmF1bHQgPSBJTVBPUlRfQkFSXTsKKworICBvcHRpb25hbCBzdHJpbmcgZGVmYXVsdF9zdHJpbmdfcGllY2UgPSA4NCBbY3R5cGU9U1RSSU5HX1BJRUNFLGRlZmF1bHQ9ImFiYyJdOworICBvcHRpb25hbCBzdHJpbmcgZGVmYXVsdF9jb3JkID0gODUgW2N0eXBlPUNPUkQsZGVmYXVsdD0iMTIzIl07CisKKyAgLy8gRm9yIG9uZW9mIHRlc3QKKyAgb25lb2Ygb25lb2ZfZmllbGQgeworICAgIHVpbnQzMiBvbmVvZl91aW50MzIgPSAxMTE7CisgICAgTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDExMjsKKyAgICBzdHJpbmcgb25lb2Zfc3RyaW5nID0gMTEzOworICAgIGJ5dGVzIG9uZW9mX2J5dGVzID0gMTE0OworICAgIE5lc3RlZE1lc3NhZ2UgbGF6eV9vbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDExNSBbbGF6eT10cnVlXTsKKyAgfQorfQorCisvLyBEZWZpbmUgdGhlc2UgYWZ0ZXIgVGVzdEFsbFR5cGVzIHRvIG1ha2Ugc3VyZSB0aGUgY29tcGlsZXIgY2FuIGhhbmRsZQorLy8gdGhhdC4KK21lc3NhZ2UgRm9yZWlnbk1lc3NhZ2UgeworICBvcHRpb25hbCBpbnQzMiBjID0gMTsKK30KKworZW51bSBGb3JlaWduRW51bSB7CisgIEZPUkVJR05fRk9PID0gNDsKKyAgRk9SRUlHTl9CQVIgPSA1OworICBGT1JFSUdOX0JBWiA9IDY7Cit9CisKK21lc3NhZ2UgVGVzdE5vQXJlbmFNZXNzYWdlIHsKKyAgb3B0aW9uYWwgcHJvdG8yX2FyZW5hX3VuaXR0ZXN0LkFyZW5hTWVzc2FnZSBhcmVuYV9tZXNzYWdlID0gMTsKK307CmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X25vX2FyZW5hX2ltcG9ydC5wcm90byBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fYXJlbmFfaW1wb3J0LnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA3MmFmNDkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X25vX2FyZW5hX2ltcG9ydC5wcm90bwpAQCAtMCwwICsxLDM3IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworc3ludGF4ID0gInByb3RvMiI7CisKK3BhY2thZ2UgcHJvdG8yX2FyZW5hX3VuaXR0ZXN0OworCittZXNzYWdlIEltcG9ydE5vQXJlbmFOZXN0ZWRNZXNzYWdlIHsKKyAgb3B0aW9uYWwgaW50MzIgZCA9IDE7Cit9OwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9ub19hcmVuYV9saXRlLnByb3RvIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9ub19hcmVuYV9saXRlLnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM0YzdiN2MKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X25vX2FyZW5hX2xpdGUucHJvdG8KQEAgLTAsMCArMSw0MiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3N5bnRheCA9ICJwcm90bzIiOworCitvcHRpb24gb3B0aW1pemVfZm9yID0gTElURV9SVU5USU1FOworCisvLyBXZSBkb24ndCBwdXQgdGhpcyBpbiBhIHBhY2thZ2Ugd2l0aGluIHByb3RvMiBiZWNhdXNlIHdlIG5lZWQgdG8gbWFrZSBzdXJlCisvLyB0aGF0IHRoZSBnZW5lcmF0ZWQgY29kZSBkb2Vzbid0IGRlcGVuZCBvbiBiZWluZyBpbiB0aGUgcHJvdG8yIG5hbWVzcGFjZS4KKy8vIEluIHRlc3RfdXRpbC5oIHdlIGRvICJ1c2luZyBuYW1lc3BhY2UgdW5pdHRlc3QgPSBwcm90b2J1Zl91bml0dGVzdCIuCitwYWNrYWdlIHByb3RvYnVmX3VuaXR0ZXN0X25vX2FyZW5hOworCittZXNzYWdlIEZvcmVpZ25NZXNzYWdlTGl0ZSB7CisgIG9wdGlvbmFsIGludDMyIGMgPSAxOworfQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9ub19maWVsZF9wcmVzZW5jZS5wcm90byBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fZmllbGRfcHJlc2VuY2UucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTk0YWZmZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fZmllbGRfcHJlc2VuY2UucHJvdG8KQEAgLTAsMCArMSwxMzggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBIHByb3RvIGZpbGUgdXNlZCB0byB0ZXN0IGEgbWVzc2FnZSB0eXBlIHdpdGggbm8gZXhwbGljaXQgZmllbGQgcHJlc2VuY2UuCisKK3N5bnRheCA9ICJwcm90bzMiOworCisvLyBXZSB3YW50IHRvIHRlc3QgZW1iZWRkZWQgcHJvdG8yIG1lc3NhZ2VzLCBzbyBpbmNsdWRlIHNvbWUgcHJvdG8yIHR5cGVzLgoraW1wb3J0ICJnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucHJvdG8iOworCitwYWNrYWdlIHByb3RvMl9ub2ZpZWxkcHJlc2VuY2VfdW5pdHRlc3Q7CisKKy8vIFRoaXMgcHJvdG8gaW5jbHVkZXMgZXZlcnkgdHlwZSBvZiBmaWVsZCBpbiBib3RoIHNpbmd1bGFyIGFuZCByZXBlYXRlZAorLy8gZm9ybXMuCittZXNzYWdlIFRlc3RBbGxUeXBlcyB7CisgIG1lc3NhZ2UgTmVzdGVkTWVzc2FnZSB7CisgICAgaW50MzIgYmIgPSAxOworICB9CisKKyAgZW51bSBOZXN0ZWRFbnVtIHsKKyAgICBGT08gPSAwOworICAgIEJBUiA9IDE7CisgICAgQkFaID0gMjsKKyAgfQorCisgIC8vIFNpbmd1bGFyCisgIC8vIFRPRE86IHJlbW92ZSAnb3B0aW9uYWwnIGxhYmVscyBhcyBzb29uIGFzIENMIDY5MTg4MDc3IGlzIExHVE0nZCB0byBtYWtlCisgIC8vICdvcHRpb25hbCcgb3B0aW9uYWwuCisgICAgIGludDMyIG9wdGlvbmFsX2ludDMyICAgID0gIDE7CisgICAgIGludDY0IG9wdGlvbmFsX2ludDY0ICAgID0gIDI7CisgICAgdWludDMyIG9wdGlvbmFsX3VpbnQzMiAgID0gIDM7CisgICAgdWludDY0IG9wdGlvbmFsX3VpbnQ2NCAgID0gIDQ7CisgICAgc2ludDMyIG9wdGlvbmFsX3NpbnQzMiAgID0gIDU7CisgICAgc2ludDY0IG9wdGlvbmFsX3NpbnQ2NCAgID0gIDY7CisgICBmaXhlZDMyIG9wdGlvbmFsX2ZpeGVkMzIgID0gIDc7CisgICBmaXhlZDY0IG9wdGlvbmFsX2ZpeGVkNjQgID0gIDg7CisgIHNmaXhlZDMyIG9wdGlvbmFsX3NmaXhlZDMyID0gIDk7CisgIHNmaXhlZDY0IG9wdGlvbmFsX3NmaXhlZDY0ID0gMTA7CisgICAgIGZsb2F0IG9wdGlvbmFsX2Zsb2F0ICAgID0gMTE7CisgICAgZG91YmxlIG9wdGlvbmFsX2RvdWJsZSAgID0gMTI7CisgICAgICBib29sIG9wdGlvbmFsX2Jvb2wgICAgID0gMTM7CisgICAgc3RyaW5nIG9wdGlvbmFsX3N0cmluZyAgID0gMTQ7CisgICAgIGJ5dGVzIG9wdGlvbmFsX2J5dGVzICAgID0gMTU7CisKKyAgTmVzdGVkTWVzc2FnZSAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlICA9IDE4OworICBGb3JlaWduTWVzc2FnZSAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlID0gMTk7CisgIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyAgICAgICAgIG9wdGlvbmFsX3Byb3RvMl9tZXNzYWdlID0gMjA7CisKKyAgTmVzdGVkRW51bSAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbmFsX25lc3RlZF9lbnVtICAgICA9IDIxOworICBGb3JlaWduRW51bSAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uYWxfZm9yZWlnbl9lbnVtICAgID0gMjI7CisgIC8vIE4uQi46IHByb3RvMi1lbnVtLXR5cGUgZmllbGRzIG5vdCBhbGxvd2VkLCBiZWNhdXNlIHRoZWlyIGRlZmF1bHQgdmFsdWVzCisgIC8vIG1pZ2h0IG5vdCBiZSB6ZXJvLgorICAvL29wdGlvbmFsIHByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtICAgICAgICAgIG9wdGlvbmFsX3Byb3RvMl9lbnVtICAgICA9IDIzOworCisgIHN0cmluZyBvcHRpb25hbF9zdHJpbmdfcGllY2UgPSAyNCBbY3R5cGU9U1RSSU5HX1BJRUNFXTsKKyAgc3RyaW5nIG9wdGlvbmFsX2NvcmQgPSAyNSBbY3R5cGU9Q09SRF07CisKKyAgTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSAzMCBbbGF6eT10cnVlXTsKKworICAvLyBSZXBlYXRlZAorICByZXBlYXRlZCAgICBpbnQzMiByZXBlYXRlZF9pbnQzMiAgICA9IDMxOworICByZXBlYXRlZCAgICBpbnQ2NCByZXBlYXRlZF9pbnQ2NCAgICA9IDMyOworICByZXBlYXRlZCAgIHVpbnQzMiByZXBlYXRlZF91aW50MzIgICA9IDMzOworICByZXBlYXRlZCAgIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgICA9IDM0OworICByZXBlYXRlZCAgIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgICA9IDM1OworICByZXBlYXRlZCAgIHNpbnQ2NCByZXBlYXRlZF9zaW50NjQgICA9IDM2OworICByZXBlYXRlZCAgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyICA9IDM3OworICByZXBlYXRlZCAgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ICA9IDM4OworICByZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDM5OworICByZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDQwOworICByZXBlYXRlZCAgICBmbG9hdCByZXBlYXRlZF9mbG9hdCAgICA9IDQxOworICByZXBlYXRlZCAgIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgICA9IDQyOworICByZXBlYXRlZCAgICAgYm9vbCByZXBlYXRlZF9ib29sICAgICA9IDQzOworICByZXBlYXRlZCAgIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgICA9IDQ0OworICByZXBlYXRlZCAgICBieXRlcyByZXBlYXRlZF9ieXRlcyAgICA9IDQ1OworCisgIHJlcGVhdGVkIE5lc3RlZE1lc3NhZ2UgICAgICAgICAgICAgICAgICAgICAgICByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSAgPSA0ODsKKyAgcmVwZWF0ZWQgRm9yZWlnbk1lc3NhZ2UgICAgICAgICAgICAgICAgICAgICAgIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OworICByZXBlYXRlZCBwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgICAgICAgICByZXBlYXRlZF9wcm90bzJfbWVzc2FnZSAgPSA1MDsKKworICByZXBlYXRlZCBOZXN0ZWRFbnVtICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRfbmVzdGVkX2VudW0gICAgID0gNTE7CisgIHJlcGVhdGVkIEZvcmVpZ25FbnVtICAgICAgICAgICAgICAgICAgICAgICAgICByZXBlYXRlZF9mb3JlaWduX2VudW0gICAgPSA1MjsKKworICByZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlPVNUUklOR19QSUVDRV07CisgIHJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9jb3JkID0gNTUgW2N0eXBlPUNPUkRdOworCisgIHJlcGVhdGVkIE5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenk9dHJ1ZV07CisKKyAgb25lb2Ygb25lb2ZfZmllbGQgeworICAgIHVpbnQzMiBvbmVvZl91aW50MzIgPSAxMTE7CisgICAgTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDExMjsKKyAgICBzdHJpbmcgb25lb2Zfc3RyaW5nID0gMTEzOworICAgIE5lc3RlZEVudW0gb25lb2ZfZW51bSA9IDExNDsKKyAgfQorfQorCittZXNzYWdlIFRlc3RQcm90bzJSZXF1aXJlZCB7CisgIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCBwcm90bzIgPSAxOworfQorCisvLyBEZWZpbmUgdGhlc2UgYWZ0ZXIgVGVzdEFsbFR5cGVzIHRvIG1ha2Ugc3VyZSB0aGUgY29tcGlsZXIgY2FuIGhhbmRsZQorLy8gdGhhdC4KK21lc3NhZ2UgRm9yZWlnbk1lc3NhZ2UgeworICBpbnQzMiBjID0gMTsKK30KKworZW51bSBGb3JlaWduRW51bSB7CisgIEZPUkVJR05fRk9PID0gMDsKKyAgRk9SRUlHTl9CQVIgPSAxOworICBGT1JFSUdOX0JBWiA9IDI7Cit9CmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X25vX2dlbmVyaWNfc2VydmljZXMucHJvdG8gYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X25vX2dlbmVyaWNfc2VydmljZXMucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGZjNzcxMwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fZ2VuZXJpY19zZXJ2aWNlcy5wcm90bwpAQCAtMCwwICsxLDU0IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorCitzeW50YXggPSAicHJvdG8yIjsKK3BhY2thZ2UgZ29vZ2xlLnByb3RvYnVmLm5vX2dlbmVyaWNfc2VydmljZXNfdGVzdDsKKworCisvLyAqX2dlbmVyaWNfc2VydmljZXMgYXJlIGZhbHNlIGJ5IGRlZmF1bHQuCisKK21lc3NhZ2UgVGVzdE1lc3NhZ2UgeworICBvcHRpb25hbCBpbnQzMiBhID0gMTsKKyAgZXh0ZW5zaW9ucyAxMDAwIHRvIG1heDsKK30KKworZW51bSBUZXN0RW51bSB7CisgIEZPTyA9IDE7Cit9CisKK2V4dGVuZCBUZXN0TWVzc2FnZSB7CisgIG9wdGlvbmFsIGludDMyIHRlc3RfZXh0ZW5zaW9uID0gMTAwMDsKK30KKworc2VydmljZSBUZXN0U2VydmljZSB7CisgIHJwYyBGb28oVGVzdE1lc3NhZ2UpIHJldHVybnMoVGVzdE1lc3NhZ2UpOworfQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9vcHRpbWl6ZV9mb3IucHJvdG8gYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X29wdGltaXplX2Zvci5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lZTljYzdiCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9vcHRpbWl6ZV9mb3IucHJvdG8KQEAgLTAsMCArMSw2NyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorLy8KKy8vIEEgcHJvdG8gZmlsZSB3aGljaCB1c2VzIG9wdGltaXplX2ZvciA9IENPREVfU0laRS4KKworc3ludGF4ID0gInByb3RvMiI7CitpbXBvcnQgImdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wcm90byI7CisKK3BhY2thZ2UgcHJvdG9idWZfdW5pdHRlc3Q7CisKK29wdGlvbiBvcHRpbWl6ZV9mb3IgPSBDT0RFX1NJWkU7CisKK21lc3NhZ2UgVGVzdE9wdGltaXplZEZvclNpemUgeworICBvcHRpb25hbCBpbnQzMiBpID0gMTsKKyAgb3B0aW9uYWwgRm9yZWlnbk1lc3NhZ2UgbXNnID0gMTk7CisKKyAgZXh0ZW5zaW9ucyAxMDAwIHRvIG1heDsKKworICBleHRlbmQgVGVzdE9wdGltaXplZEZvclNpemUgeworICAgIG9wdGlvbmFsIGludDMyIHRlc3RfZXh0ZW5zaW9uID0gMTIzNDsKKyAgICBvcHRpb25hbCBUZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplIHRlc3RfZXh0ZW5zaW9uMiA9IDEyMzU7CisgIH0KKworICBvbmVvZiBmb28geworICAgIGludDMyIGludGVnZXJfZmllbGQgPSAyOworICAgIHN0cmluZyBzdHJpbmdfZmllbGQgPSAzOworICB9Cit9CisKK21lc3NhZ2UgVGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yU2l6ZSB7CisgIHJlcXVpcmVkIGludDMyIHggPSAxOworfQorCittZXNzYWdlIFRlc3RPcHRpb25hbE9wdGltaXplZEZvclNpemUgeworICBvcHRpb25hbCBUZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplIG8gPSAxOworfQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9wcmVzZXJ2ZV91bmtub3duX2VudW0ucHJvdG8gYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X3ByZXNlcnZlX3Vua25vd25fZW51bS5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZjkxMzMyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9wcmVzZXJ2ZV91bmtub3duX2VudW0ucHJvdG8KQEAgLTAsMCArMSw3MSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3N5bnRheCA9ICJwcm90bzMiOworCitwYWNrYWdlIHByb3RvM19wcmVzZXJ2ZV91bmtub3duX2VudW1fdW5pdHRlc3Q7CitvcHRpb24gb2JqY19jbGFzc19wcmVmaXggPSAiVW5rbm93bkVudW1zIjsKKworb3B0aW9uIGNzaGFycF9uYW1lc3BhY2UgPSAiR29vZ2xlLlByb3RvYnVmLlRlc3RQcm90b3MiOworCitlbnVtIE15RW51bSB7CisgIEZPTyA9IDA7CisgIEJBUiA9IDE7CisgIEJBWiA9IDI7Cit9CisKK2VudW0gTXlFbnVtUGx1c0V4dHJhIHsKKyAgRV9GT08gPSAwOworICBFX0JBUiA9IDE7CisgIEVfQkFaID0gMjsKKyAgRV9FWFRSQSA9IDM7Cit9CisKK21lc3NhZ2UgTXlNZXNzYWdlIHsKKyAgTXlFbnVtIGUgPSAxOworICByZXBlYXRlZCBNeUVudW0gcmVwZWF0ZWRfZSA9IDI7CisgIHJlcGVhdGVkIE15RW51bSByZXBlYXRlZF9wYWNrZWRfZSA9IDMgW3BhY2tlZD10cnVlXTsKKyAgcmVwZWF0ZWQgTXlFbnVtUGx1c0V4dHJhIHJlcGVhdGVkX3BhY2tlZF91bmV4cGVjdGVkX2UgPSA0OyAgLy8gbm90IHBhY2tlZAorICBvbmVvZiBvIHsKKyAgICBNeUVudW0gb25lb2ZfZV8xID0gNTsKKyAgICBNeUVudW0gb25lb2ZfZV8yID0gNjsKKyAgfQorfQorCittZXNzYWdlIE15TWVzc2FnZVBsdXNFeHRyYSB7CisgIE15RW51bVBsdXNFeHRyYSBlID0gMTsKKyAgcmVwZWF0ZWQgTXlFbnVtUGx1c0V4dHJhIHJlcGVhdGVkX2UgPSAyOworICByZXBlYXRlZCBNeUVudW1QbHVzRXh0cmEgcmVwZWF0ZWRfcGFja2VkX2UgPSAzIFtwYWNrZWQ9dHJ1ZV07CisgIHJlcGVhdGVkIE15RW51bVBsdXNFeHRyYSByZXBlYXRlZF9wYWNrZWRfdW5leHBlY3RlZF9lID0gNCBbcGFja2VkPXRydWVdOworICBvbmVvZiBvIHsKKyAgICBNeUVudW1QbHVzRXh0cmEgb25lb2ZfZV8xID0gNTsKKyAgICBNeUVudW1QbHVzRXh0cmEgb25lb2ZfZV8yID0gNjsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9wcmVzZXJ2ZV91bmtub3duX2VudW0yLnByb3RvIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9wcmVzZXJ2ZV91bmtub3duX2VudW0yLnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFkZjQyOTYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X3ByZXNlcnZlX3Vua25vd25fZW51bTIucHJvdG8KQEAgLTAsMCArMSw1MCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3N5bnRheCA9ICJwcm90bzIiOworCitwYWNrYWdlIHByb3RvMl9wcmVzZXJ2ZV91bmtub3duX2VudW1fdW5pdHRlc3Q7CisKK2VudW0gTXlFbnVtIHsKKyAgRk9PID0gMDsKKyAgQkFSID0gMTsKKyAgQkFaID0gMjsKK30KKworbWVzc2FnZSBNeU1lc3NhZ2UgeworICBvcHRpb25hbCBNeUVudW0gZSA9IDE7CisgIHJlcGVhdGVkIE15RW51bSByZXBlYXRlZF9lID0gMjsKKyAgcmVwZWF0ZWQgTXlFbnVtIHJlcGVhdGVkX3BhY2tlZF9lID0gMyBbcGFja2VkPXRydWVdOworICByZXBlYXRlZCBNeUVudW0gcmVwZWF0ZWRfcGFja2VkX3VuZXhwZWN0ZWRfZSA9IDQ7ICAvLyBub3QgcGFja2VkCisgIG9uZW9mIG8geworICAgIE15RW51bSBvbmVvZl9lXzEgPSA1OworICAgIE15RW51bSBvbmVvZl9lXzIgPSA2OworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X3Byb3RvMy5wcm90byBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJvdG8zLnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY1OWQyMTcKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X3Byb3RvMy5wcm90bwpAQCAtMCwwICsxLDM4OCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorLy8KKy8vIEEgcHJvdG8gZmlsZSB3ZSB3aWxsIHVzZSBmb3IgdW5pdCB0ZXN0aW5nLgorCitzeW50YXggPSAicHJvdG8zIjsKKworLy8gU29tZSBnZW5lcmljX3NlcnZpY2VzIG9wdGlvbihzKSBhZGRlZCBhdXRvbWF0aWNhbGx5LgorLy8gU2VlOiAgaHR0cDovL2dvL3Byb3RvMi1nZW5lcmljLXNlcnZpY2VzLWRlZmF1bHQKK29wdGlvbiBjY19nZW5lcmljX3NlcnZpY2VzID0gdHJ1ZTsgICAgIC8vIGF1dG8tYWRkZWQKK29wdGlvbiBqYXZhX2dlbmVyaWNfc2VydmljZXMgPSB0cnVlOyAgIC8vIGF1dG8tYWRkZWQKK29wdGlvbiBweV9nZW5lcmljX3NlcnZpY2VzID0gdHJ1ZTsgICAgIC8vIGF1dG8tYWRkZWQKK29wdGlvbiBjY19lbmFibGVfYXJlbmFzID0gdHJ1ZTsKK29wdGlvbiBjc2hhcnBfbmFtZXNwYWNlID0gIkdvb2dsZS5Qcm90b2J1Zi5UZXN0UHJvdG9zIjsKKworaW1wb3J0ICJnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X3Byb3RvMy5wcm90byI7CisKKy8vIFdlIGRvbid0IHB1dCB0aGlzIGluIGEgcGFja2FnZSB3aXRoaW4gcHJvdG8yIGJlY2F1c2Ugd2UgbmVlZCB0byBtYWtlIHN1cmUKKy8vIHRoYXQgdGhlIGdlbmVyYXRlZCBjb2RlIGRvZXNuJ3QgZGVwZW5kIG9uIGJlaW5nIGluIHRoZSBwcm90bzIgbmFtZXNwYWNlLgorLy8gSW4gdGVzdF91dGlsLmggd2UgZG8gInVzaW5nIG5hbWVzcGFjZSB1bml0dGVzdCA9IHByb3RvYnVmX3VuaXR0ZXN0Ii4KK3BhY2thZ2UgcHJvdG9idWZfdW5pdHRlc3Q7CisKKy8vIFByb3RvcyBvcHRpbWl6ZWQgZm9yIFNQRUVEIHVzZSBhIHN0cmljdCBzdXBlcnNldCBvZiB0aGUgZ2VuZXJhdGVkIGNvZGUKKy8vIG9mIGVxdWl2YWxlbnQgb25lcyBvcHRpbWl6ZWQgZm9yIENPREVfU0laRSwgc28gd2Ugc2hvdWxkIG9wdGltaXplIGFsbCBvdXIKKy8vIHRlc3RzIGZvciBzcGVlZCB1bmxlc3MgZXhwbGljaXRseSB0ZXN0aW5nIGNvZGUgc2l6ZSBvcHRpbWl6YXRpb24uCitvcHRpb24gb3B0aW1pemVfZm9yID0gU1BFRUQ7CisKK29wdGlvbiBqYXZhX291dGVyX2NsYXNzbmFtZSA9ICJVbml0dGVzdFByb3RvIjsKKworLy8gVGhpcyBwcm90byBpbmNsdWRlcyBldmVyeSB0eXBlIG9mIGZpZWxkIGluIGJvdGggc2luZ3VsYXIgYW5kIHJlcGVhdGVkCisvLyBmb3Jtcy4KK21lc3NhZ2UgVGVzdEFsbFR5cGVzIHsKKyAgbWVzc2FnZSBOZXN0ZWRNZXNzYWdlIHsKKyAgICAvLyBUaGUgZmllbGQgbmFtZSAiYiIgZmFpbHMgdG8gY29tcGlsZSBpbiBwcm90bzEgYmVjYXVzZSBpdCBjb25mbGljdHMgd2l0aAorICAgIC8vIGEgbG9jYWwgdmFyaWFibGUgbmFtZWQgImIiIGluIG9uZSBvZiB0aGUgZ2VuZXJhdGVkIG1ldGhvZHMuICBEb2guCisgICAgLy8gVGhpcyBmaWxlIG5lZWRzIHRvIGNvbXBpbGUgaW4gcHJvdG8xIHRvIHRlc3QgYmFja3dhcmRzLWNvbXBhdGliaWxpdHkuCisgICAgaW50MzIgYmIgPSAxOworICB9CisKKyAgZW51bSBOZXN0ZWRFbnVtIHsKKyAgICBORVNURURfRU5VTV9VTlNQRUNJRklFRCA9IDA7CisgICAgRk9PID0gMTsKKyAgICBCQVIgPSAyOworICAgIEJBWiA9IDM7CisgICAgTkVHID0gLTE7ICAvLyBJbnRlbnRpb25hbGx5IG5lZ2F0aXZlLgorICB9CisKKyAgLy8gU2luZ3VsYXIKKyAgaW50MzIgc2luZ2xlX2ludDMyID0gMTsKKyAgaW50NjQgc2luZ2xlX2ludDY0ID0gMjsKKyAgdWludDMyIHNpbmdsZV91aW50MzIgPSAzOworICB1aW50NjQgc2luZ2xlX3VpbnQ2NCA9IDQ7CisgIHNpbnQzMiBzaW5nbGVfc2ludDMyID0gNTsKKyAgc2ludDY0IHNpbmdsZV9zaW50NjQgPSA2OworICBmaXhlZDMyIHNpbmdsZV9maXhlZDMyID0gNzsKKyAgZml4ZWQ2NCBzaW5nbGVfZml4ZWQ2NCA9IDg7CisgIHNmaXhlZDMyIHNpbmdsZV9zZml4ZWQzMiA9IDk7CisgIHNmaXhlZDY0IHNpbmdsZV9zZml4ZWQ2NCA9IDEwOworICBmbG9hdCBzaW5nbGVfZmxvYXQgPSAxMTsKKyAgZG91YmxlIHNpbmdsZV9kb3VibGUgPSAxMjsKKyAgYm9vbCBzaW5nbGVfYm9vbCA9IDEzOworICBzdHJpbmcgc2luZ2xlX3N0cmluZyA9IDE0OworICBieXRlcyBzaW5nbGVfYnl0ZXMgPSAxNTsKKworICBOZXN0ZWRNZXNzYWdlIHNpbmdsZV9uZXN0ZWRfbWVzc2FnZSA9IDE4OworICBGb3JlaWduTWVzc2FnZSBzaW5nbGVfZm9yZWlnbl9tZXNzYWdlID0gMTk7CisgIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHNpbmdsZV9pbXBvcnRfbWVzc2FnZSA9IDIwOworCisgIE5lc3RlZEVudW0gc2luZ2xlX25lc3RlZF9lbnVtID0gMjE7CisgIEZvcmVpZ25FbnVtIHNpbmdsZV9mb3JlaWduX2VudW0gPSAyMjsKKyAgcHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydEVudW0gc2luZ2xlX2ltcG9ydF9lbnVtID0gMjM7CisKKyAgLy8gRGVmaW5lZCBpbiB1bml0dGVzdF9pbXBvcnRfcHVibGljLnByb3RvCisgIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5QdWJsaWNJbXBvcnRNZXNzYWdlCisgICAgICBzaW5nbGVfcHVibGljX2ltcG9ydF9tZXNzYWdlID0gMjY7CisKKyAgLy8gUmVwZWF0ZWQKKyAgcmVwZWF0ZWQgICAgaW50MzIgcmVwZWF0ZWRfaW50MzIgICAgPSAzMTsKKyAgcmVwZWF0ZWQgICAgaW50NjQgcmVwZWF0ZWRfaW50NjQgICAgPSAzMjsKKyAgcmVwZWF0ZWQgICB1aW50MzIgcmVwZWF0ZWRfdWludDMyICAgPSAzMzsKKyAgcmVwZWF0ZWQgICB1aW50NjQgcmVwZWF0ZWRfdWludDY0ICAgPSAzNDsKKyAgcmVwZWF0ZWQgICBzaW50MzIgcmVwZWF0ZWRfc2ludDMyICAgPSAzNTsKKyAgcmVwZWF0ZWQgICBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ICAgPSAzNjsKKyAgcmVwZWF0ZWQgIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiAgPSAzNzsKKyAgcmVwZWF0ZWQgIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCAgPSAzODsKKyAgcmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSAzOTsKKyAgcmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSA0MDsKKyAgcmVwZWF0ZWQgICAgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgICAgPSA0MTsKKyAgcmVwZWF0ZWQgICBkb3VibGUgcmVwZWF0ZWRfZG91YmxlICAgPSA0MjsKKyAgcmVwZWF0ZWQgICAgIGJvb2wgcmVwZWF0ZWRfYm9vbCAgICAgPSA0MzsKKyAgcmVwZWF0ZWQgICBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nICAgPSA0NDsKKyAgcmVwZWF0ZWQgICAgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMgICAgPSA0NTsKKworICByZXBlYXRlZCBOZXN0ZWRNZXNzYWdlICAgICAgICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgID0gNDg7CisgIHJlcGVhdGVkIEZvcmVpZ25NZXNzYWdlICAgICAgICAgICAgICAgICAgICAgICByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTsKKyAgcmVwZWF0ZWQgcHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgID0gNTA7CisKKyAgcmVwZWF0ZWQgTmVzdGVkRW51bSAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcGVhdGVkX25lc3RlZF9lbnVtICAgICA9IDUxOworICByZXBlYXRlZCBGb3JlaWduRW51bSAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRfZm9yZWlnbl9lbnVtICAgID0gNTI7CisgIHJlcGVhdGVkIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtICAgIHJlcGVhdGVkX2ltcG9ydF9lbnVtICAgICA9IDUzOworICAvLyBEZWZpbmVkIGluIHVuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucHJvdG8KKyAgcmVwZWF0ZWQgcHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LlB1YmxpY0ltcG9ydE1lc3NhZ2UKKyAgICAgIHJlcGVhdGVkX3B1YmxpY19pbXBvcnRfbWVzc2FnZSA9IDU0OworCisgIC8vIEZvciBvbmVvZiB0ZXN0CisgIG9uZW9mIG9uZW9mX2ZpZWxkIHsKKyAgICB1aW50MzIgb25lb2ZfdWludDMyID0gMTExOworICAgIE5lc3RlZE1lc3NhZ2Ugb25lb2ZfbmVzdGVkX21lc3NhZ2UgPSAxMTI7CisgICAgc3RyaW5nIG9uZW9mX3N0cmluZyA9IDExMzsKKyAgICBieXRlcyBvbmVvZl9ieXRlcyA9IDExNDsKKyAgfQorfQorCisvLyBUaGlzIHByb3RvIGluY2x1ZGVzIGEgcmVjdXNpdmVseSBuZXN0ZWQgbWVzc2FnZS4KK21lc3NhZ2UgTmVzdGVkVGVzdEFsbFR5cGVzIHsKKyAgTmVzdGVkVGVzdEFsbFR5cGVzIGNoaWxkID0gMTsKKyAgVGVzdEFsbFR5cGVzIHBheWxvYWQgPSAyOworICByZXBlYXRlZCBOZXN0ZWRUZXN0QWxsVHlwZXMgcmVwZWF0ZWRfY2hpbGQgPSAzOworfQorCittZXNzYWdlIFRlc3REZXByZWNhdGVkRmllbGRzIHsKKyAgaW50MzIgZGVwcmVjYXRlZF9pbnQzMiA9IDEgW2RlcHJlY2F0ZWQ9dHJ1ZV07Cit9CisKKy8vIERlZmluZSB0aGVzZSBhZnRlciBUZXN0QWxsVHlwZXMgdG8gbWFrZSBzdXJlIHRoZSBjb21waWxlciBjYW4gaGFuZGxlCisvLyB0aGF0LgorbWVzc2FnZSBGb3JlaWduTWVzc2FnZSB7CisgIGludDMyIGMgPSAxOworfQorCitlbnVtIEZvcmVpZ25FbnVtIHsKKyAgRk9SRUlHTl9VTlNQRUNJRklFRCA9IDA7CisgIEZPUkVJR05fRk9PID0gNDsKKyAgRk9SRUlHTl9CQVIgPSA1OworICBGT1JFSUdOX0JBWiA9IDY7Cit9CisKK21lc3NhZ2UgVGVzdFJlc2VydmVkRmllbGRzIHsKKyAgcmVzZXJ2ZWQgMiwgMTUsIDkgdG8gMTE7CisgIHJlc2VydmVkICJiYXIiLCAiYmF6IjsKK30KKworCisvLyBUZXN0IHRoYXQgd2UgY2FuIHVzZSBOZXN0ZWRNZXNzYWdlIGZyb20gb3V0c2lkZSBUZXN0QWxsVHlwZXMuCittZXNzYWdlIFRlc3RGb3JlaWduTmVzdGVkIHsKKyAgVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZm9yZWlnbl9uZXN0ZWQgPSAxOworfQorCisvLyBUZXN0IHRoYXQgcmVhbGx5IGxhcmdlIHRhZyBudW1iZXJzIGRvbid0IGJyZWFrIGFueXRoaW5nLgorbWVzc2FnZSBUZXN0UmVhbGx5TGFyZ2VUYWdOdW1iZXIgeworICAvLyBUaGUgbGFyZ2VzdCBwb3NzaWJsZSB0YWcgbnVtYmVyIGlzIDJeMjggLSAxLCBzaW5jZSB0aGUgd2lyZSBmb3JtYXQgdXNlcworICAvLyB0aHJlZSBiaXRzIHRvIGNvbW11bmljYXRlIHdpcmUgdHlwZS4KKyAgaW50MzIgYSA9IDE7CisgIGludDMyIGJiID0gMjY4NDM1NDU1OworfQorCittZXNzYWdlIFRlc3RSZWN1cnNpdmVNZXNzYWdlIHsKKyAgVGVzdFJlY3Vyc2l2ZU1lc3NhZ2UgYSA9IDE7CisgIGludDMyIGkgPSAyOworfQorCisvLyBUZXN0IHRoYXQgbXV0dWFsIHJlY3Vyc2lvbiB3b3Jrcy4KK21lc3NhZ2UgVGVzdE11dHVhbFJlY3Vyc2lvbkEgeworICBUZXN0TXV0dWFsUmVjdXJzaW9uQiBiYiA9IDE7Cit9CisKK21lc3NhZ2UgVGVzdE11dHVhbFJlY3Vyc2lvbkIgeworICBUZXN0TXV0dWFsUmVjdXJzaW9uQSBhID0gMTsKKyAgaW50MzIgb3B0aW9uYWxfaW50MzIgPSAyOworfQorCisKKy8vIFRlc3QgYW4gZW51bSB0aGF0IGhhcyBtdWx0aXBsZSB2YWx1ZXMgd2l0aCB0aGUgc2FtZSBudW1iZXIuCitlbnVtIFRlc3RFbnVtV2l0aER1cFZhbHVlIHsKKyAgVEVTVF9FTlVNX1dJVEhfRFVQX1ZBTFVFX1VOU1BFQ0lGSUVEID0gMDsKKyAgb3B0aW9uIGFsbG93X2FsaWFzID0gdHJ1ZTsKKworICBGT08xID0gMTsKKyAgQkFSMSA9IDI7CisgIEJBWiA9IDM7CisgIEZPTzIgPSAxOworICBCQVIyID0gMjsKK30KKworLy8gVGVzdCBhbiBlbnVtIHdpdGggbGFyZ2UsIHVub3JkZXJlZCB2YWx1ZXMuCitlbnVtIFRlc3RTcGFyc2VFbnVtIHsKKyAgVEVTVF9TUEFSU0VfRU5VTV9VTlNQRUNJRklFRCA9IDA7CisgIFNQQVJTRV9BID0gMTIzOworICBTUEFSU0VfQiA9IDYyMzc0OworICBTUEFSU0VfQyA9IDEyNTg5MjM0OworICBTUEFSU0VfRCA9IC0xNTsKKyAgU1BBUlNFX0UgPSAtNTM0NTI7CisgIC8vIEluIHByb3RvMywgdmFsdWUgMCBtdXN0IGJlIHRoZSBmaXJzdCBvbmUgc3BlY2lmaWVkCisgIC8vIFNQQVJTRV9GID0gMDsKKyAgU1BBUlNFX0cgPSAyOworfQorCisvLyBUZXN0IG1lc3NhZ2Ugd2l0aCBDYW1lbENhc2UgZmllbGQgbmFtZXMuICBUaGlzIHZpb2xhdGVzIFByb3RvY29sIEJ1ZmZlcgorLy8gc3RhbmRhcmQgc3R5bGUuCittZXNzYWdlIFRlc3RDYW1lbENhc2VGaWVsZE5hbWVzIHsKKyAgaW50MzIgUHJpbWl0aXZlRmllbGQgPSAxOworICBzdHJpbmcgU3RyaW5nRmllbGQgPSAyOworICBGb3JlaWduRW51bSBFbnVtRmllbGQgPSAzOworICBGb3JlaWduTWVzc2FnZSBNZXNzYWdlRmllbGQgPSA0OworCisgIHJlcGVhdGVkIGludDMyIFJlcGVhdGVkUHJpbWl0aXZlRmllbGQgPSA3OworICByZXBlYXRlZCBzdHJpbmcgUmVwZWF0ZWRTdHJpbmdGaWVsZCA9IDg7CisgIHJlcGVhdGVkIEZvcmVpZ25FbnVtIFJlcGVhdGVkRW51bUZpZWxkID0gOTsKKyAgcmVwZWF0ZWQgRm9yZWlnbk1lc3NhZ2UgUmVwZWF0ZWRNZXNzYWdlRmllbGQgPSAxMDsKK30KKworCisvLyBXZSBsaXN0IGZpZWxkcyBvdXQgb2Ygb3JkZXIsIHRvIGVuc3VyZSB0aGF0IHdlJ3JlIHVzaW5nIGZpZWxkIG51bWJlciBhbmQgbm90CisvLyBmaWVsZCBpbmRleCB0byBkZXRlcm1pbmUgc2VyaWFsaXphdGlvbiBvcmRlci4KK21lc3NhZ2UgVGVzdEZpZWxkT3JkZXJpbmdzIHsKKyAgc3RyaW5nIG15X3N0cmluZyA9IDExOworICBpbnQ2NCBteV9pbnQgPSAxOworICBmbG9hdCBteV9mbG9hdCA9IDEwMTsKKyAgbWVzc2FnZSBOZXN0ZWRNZXNzYWdlIHsKKyAgICBpbnQ2NCBvbyA9IDI7CisgICAgLy8gVGhlIGZpZWxkIG5hbWUgImIiIGZhaWxzIHRvIGNvbXBpbGUgaW4gcHJvdG8xIGJlY2F1c2UgaXQgY29uZmxpY3RzIHdpdGgKKyAgICAvLyBhIGxvY2FsIHZhcmlhYmxlIG5hbWVkICJiIiBpbiBvbmUgb2YgdGhlIGdlbmVyYXRlZCBtZXRob2RzLiAgRG9oLgorICAgIC8vIFRoaXMgZmlsZSBuZWVkcyB0byBjb21waWxlIGluIHByb3RvMSB0byB0ZXN0IGJhY2t3YXJkcy1jb21wYXRpYmlsaXR5LgorICAgIGludDMyIGJiID0gMTsKKyAgfQorCisgIE5lc3RlZE1lc3NhZ2Ugc2luZ2xlX25lc3RlZF9tZXNzYWdlICA9IDIwMDsKK30KKworbWVzc2FnZSBTcGFyc2VFbnVtTWVzc2FnZSB7CisgIFRlc3RTcGFyc2VFbnVtIHNwYXJzZV9lbnVtID0gMTsKK30KKworLy8gVGVzdCBTdHJpbmcgYW5kIEJ5dGVzOiBzdHJpbmcgaXMgZm9yIHZhbGlkIFVURi04IHN0cmluZ3MKK21lc3NhZ2UgT25lU3RyaW5nIHsKKyAgc3RyaW5nIGRhdGEgPSAxOworfQorCittZXNzYWdlIE1vcmVTdHJpbmcgeworICByZXBlYXRlZCBzdHJpbmcgZGF0YSA9IDE7Cit9CisKK21lc3NhZ2UgT25lQnl0ZXMgeworICBieXRlcyBkYXRhID0gMTsKK30KKworbWVzc2FnZSBNb3JlQnl0ZXMgeworICBieXRlcyBkYXRhID0gMTsKK30KKworLy8gVGVzdCBpbnQzMiwgdWludDMyLCBpbnQ2NCwgdWludDY0LCBhbmQgYm9vbCBhcmUgYWxsIGNvbXBhdGlibGUKK21lc3NhZ2UgSW50MzJNZXNzYWdlIHsKKyAgaW50MzIgZGF0YSA9IDE7Cit9CisKK21lc3NhZ2UgVWludDMyTWVzc2FnZSB7CisgIHVpbnQzMiBkYXRhID0gMTsKK30KKworbWVzc2FnZSBJbnQ2NE1lc3NhZ2UgeworICBpbnQ2NCBkYXRhID0gMTsKK30KKworbWVzc2FnZSBVaW50NjRNZXNzYWdlIHsKKyAgdWludDY0IGRhdGEgPSAxOworfQorCittZXNzYWdlIEJvb2xNZXNzYWdlIHsKKyAgYm9vbCBkYXRhID0gMTsKK30KKworLy8gVGVzdCBvbmVvZnMuCittZXNzYWdlIFRlc3RPbmVvZiB7CisgIG9uZW9mIGZvbyB7CisgICAgaW50MzIgZm9vX2ludCA9IDE7CisgICAgc3RyaW5nIGZvb19zdHJpbmcgPSAyOworICAgIFRlc3RBbGxUeXBlcyBmb29fbWVzc2FnZSA9IDM7CisgIH0KK30KKworLy8gVGVzdCBtZXNzYWdlcyBmb3IgcGFja2VkIGZpZWxkcworCittZXNzYWdlIFRlc3RQYWNrZWRUeXBlcyB7CisgIHJlcGVhdGVkICAgIGludDMyIHBhY2tlZF9pbnQzMiAgICA9ICA5MCBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkICAgIGludDY0IHBhY2tlZF9pbnQ2NCAgICA9ICA5MSBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkICAgdWludDMyIHBhY2tlZF91aW50MzIgICA9ICA5MiBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkICAgdWludDY0IHBhY2tlZF91aW50NjQgICA9ICA5MyBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkICAgc2ludDMyIHBhY2tlZF9zaW50MzIgICA9ICA5NCBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkICAgc2ludDY0IHBhY2tlZF9zaW50NjQgICA9ICA5NSBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkICBmaXhlZDMyIHBhY2tlZF9maXhlZDMyICA9ICA5NiBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkICBmaXhlZDY0IHBhY2tlZF9maXhlZDY0ICA9ICA5NyBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkIHNmaXhlZDMyIHBhY2tlZF9zZml4ZWQzMiA9ICA5OCBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkIHNmaXhlZDY0IHBhY2tlZF9zZml4ZWQ2NCA9ICA5OSBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkICAgIGZsb2F0IHBhY2tlZF9mbG9hdCAgICA9IDEwMCBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkICAgZG91YmxlIHBhY2tlZF9kb3VibGUgICA9IDEwMSBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkICAgICBib29sIHBhY2tlZF9ib29sICAgICA9IDEwMiBbcGFja2VkID0gdHJ1ZV07CisgIHJlcGVhdGVkIEZvcmVpZ25FbnVtIHBhY2tlZF9lbnVtICA9IDEwMyBbcGFja2VkID0gdHJ1ZV07Cit9CisKKy8vIEEgbWVzc2FnZSB3aXRoIHRoZSBzYW1lIGZpZWxkcyBhcyBUZXN0UGFja2VkVHlwZXMsIGJ1dCB3aXRob3V0IHBhY2tpbmcuIFVzZWQKKy8vIHRvIHRlc3QgcGFja2VkIDwtPiB1bnBhY2tlZCB3aXJlIGNvbXBhdGliaWxpdHkuCittZXNzYWdlIFRlc3RVbnBhY2tlZFR5cGVzIHsKKyAgcmVwZWF0ZWQgICAgaW50MzIgdW5wYWNrZWRfaW50MzIgICAgPSAgOTAgW3BhY2tlZCA9IGZhbHNlXTsKKyAgcmVwZWF0ZWQgICAgaW50NjQgdW5wYWNrZWRfaW50NjQgICAgPSAgOTEgW3BhY2tlZCA9IGZhbHNlXTsKKyAgcmVwZWF0ZWQgICB1aW50MzIgdW5wYWNrZWRfdWludDMyICAgPSAgOTIgW3BhY2tlZCA9IGZhbHNlXTsKKyAgcmVwZWF0ZWQgICB1aW50NjQgdW5wYWNrZWRfdWludDY0ICAgPSAgOTMgW3BhY2tlZCA9IGZhbHNlXTsKKyAgcmVwZWF0ZWQgICBzaW50MzIgdW5wYWNrZWRfc2ludDMyICAgPSAgOTQgW3BhY2tlZCA9IGZhbHNlXTsKKyAgcmVwZWF0ZWQgICBzaW50NjQgdW5wYWNrZWRfc2ludDY0ICAgPSAgOTUgW3BhY2tlZCA9IGZhbHNlXTsKKyAgcmVwZWF0ZWQgIGZpeGVkMzIgdW5wYWNrZWRfZml4ZWQzMiAgPSAgOTYgW3BhY2tlZCA9IGZhbHNlXTsKKyAgcmVwZWF0ZWQgIGZpeGVkNjQgdW5wYWNrZWRfZml4ZWQ2NCAgPSAgOTcgW3BhY2tlZCA9IGZhbHNlXTsKKyAgcmVwZWF0ZWQgc2ZpeGVkMzIgdW5wYWNrZWRfc2ZpeGVkMzIgPSAgOTggW3BhY2tlZCA9IGZhbHNlXTsKKyAgcmVwZWF0ZWQgc2ZpeGVkNjQgdW5wYWNrZWRfc2ZpeGVkNjQgPSAgOTkgW3BhY2tlZCA9IGZhbHNlXTsKKyAgcmVwZWF0ZWQgICAgZmxvYXQgdW5wYWNrZWRfZmxvYXQgICAgPSAxMDAgW3BhY2tlZCA9IGZhbHNlXTsKKyAgcmVwZWF0ZWQgICBkb3VibGUgdW5wYWNrZWRfZG91YmxlICAgPSAxMDEgW3BhY2tlZCA9IGZhbHNlXTsKKyAgcmVwZWF0ZWQgICAgIGJvb2wgdW5wYWNrZWRfYm9vbCAgICAgPSAxMDIgW3BhY2tlZCA9IGZhbHNlXTsKKyAgcmVwZWF0ZWQgRm9yZWlnbkVudW0gdW5wYWNrZWRfZW51bSAgPSAxMDMgW3BhY2tlZCA9IGZhbHNlXTsKK30KKworbWVzc2FnZSBUZXN0UmVwZWF0ZWRTY2FsYXJEaWZmZXJlbnRUYWdTaXplcyB7CisgIC8vIFBhcnNpbmcgcmVwZWF0ZWQgZml4ZWQgc2l6ZSB2YWx1ZXMgdXNlZCB0byBmYWlsLiBUaGlzIG1lc3NhZ2UgbmVlZHMgdG8gYmUKKyAgLy8gdXNlZCBpbiBvcmRlciB0byBnZXQgYSB0YWcgb2YgdGhlIHJpZ2h0IHNpemU7IGFsbCBvZiB0aGUgcmVwZWF0ZWQgZmllbGRzCisgIC8vIGluIFRlc3RBbGxUeXBlcyBkaWRuJ3QgdHJpZ2dlciB0aGUgY2hlY2suCisgIHJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDEyOworICAvLyBDaGVjayBmb3IgYSB2YXJpbnQgdHlwZSwganVzdCBmb3IgZ29vZCBtZWFzdXJlLgorICByZXBlYXRlZCBpbnQzMiAgIHJlcGVhdGVkX2ludDMyICAgPSAxMzsKKworICAvLyBUaGVzZSBoYXZlIHR3by1ieXRlIHRhZ3MuCisgIHJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDIwNDY7CisgIHJlcGVhdGVkIGludDY0ICAgcmVwZWF0ZWRfaW50NjQgICA9IDIwNDc7CisKKyAgLy8gVGhyZWUgYnl0ZSB0YWdzLgorICByZXBlYXRlZCBmbG9hdCAgIHJlcGVhdGVkX2Zsb2F0ICAgPSAyNjIxNDI7CisgIHJlcGVhdGVkIHVpbnQ2NCAgcmVwZWF0ZWRfdWludDY0ICA9IDI2MjE0MzsKK30KKworbWVzc2FnZSBUZXN0Q29tbWVudEluamVjdGlvbk1lc3NhZ2UgeworICAvLyAqLyA8LSBUaGlzIHNob3VsZCBub3QgY2xvc2UgdGhlIGdlbmVyYXRlZCBkb2MgY29tbWVudAorICBzdHJpbmcgYSA9IDE7Cit9CisKKworLy8gVGVzdCB0aGF0IFJQQyBzZXJ2aWNlcyB3b3JrLgorbWVzc2FnZSBGb29SZXF1ZXN0ICB7fQorbWVzc2FnZSBGb29SZXNwb25zZSB7fQorCittZXNzYWdlIEZvb0NsaWVudE1lc3NhZ2Uge30KK21lc3NhZ2UgRm9vU2VydmVyTWVzc2FnZXt9CisKK3NlcnZpY2UgVGVzdFNlcnZpY2UgeworICBycGMgRm9vKEZvb1JlcXVlc3QpIHJldHVybnMgKEZvb1Jlc3BvbnNlKTsKKyAgcnBjIEJhcihCYXJSZXF1ZXN0KSByZXR1cm5zIChCYXJSZXNwb25zZSk7Cit9CisKKworbWVzc2FnZSBCYXJSZXF1ZXN0ICB7fQorbWVzc2FnZSBCYXJSZXNwb25zZSB7fQorCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X3Byb3RvM19hcmVuYS5wcm90byBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJvdG8zX2FyZW5hLnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI4MzVhNmIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X3Byb3RvM19hcmVuYS5wcm90bwpAQCAtMCwwICsxLDIwNiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3N5bnRheCA9ICJwcm90bzMiOworCitvcHRpb24gY2NfZW5hYmxlX2FyZW5hcyA9IHRydWU7CisKK2ltcG9ydCAiZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2ltcG9ydC5wcm90byI7CisKK3BhY2thZ2UgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0OworCisvLyBUaGlzIHByb3RvIGluY2x1ZGVzIGV2ZXJ5IHR5cGUgb2YgZmllbGQgaW4gYm90aCBzaW5ndWxhciBhbmQgcmVwZWF0ZWQKKy8vIGZvcm1zLgorbWVzc2FnZSBUZXN0QWxsVHlwZXMgeworICBtZXNzYWdlIE5lc3RlZE1lc3NhZ2UgeworICAgIC8vIFRoZSBmaWVsZCBuYW1lICJiIiBmYWlscyB0byBjb21waWxlIGluIHByb3RvMSBiZWNhdXNlIGl0IGNvbmZsaWN0cyB3aXRoCisgICAgLy8gYSBsb2NhbCB2YXJpYWJsZSBuYW1lZCAiYiIgaW4gb25lIG9mIHRoZSBnZW5lcmF0ZWQgbWV0aG9kcy4gIERvaC4KKyAgICAvLyBUaGlzIGZpbGUgbmVlZHMgdG8gY29tcGlsZSBpbiBwcm90bzEgdG8gdGVzdCBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eS4KKyAgICBpbnQzMiBiYiA9IDE7CisgIH0KKworICBlbnVtIE5lc3RlZEVudW0geworICAgIFpFUk8gPSAwOworICAgIEZPTyA9IDE7CisgICAgQkFSID0gMjsKKyAgICBCQVogPSAzOworICAgIE5FRyA9IC0xOyAgLy8gSW50ZW50aW9uYWxseSBuZWdhdGl2ZS4KKyAgfQorCisgIC8vIFNpbmd1bGFyCisgICAgIGludDMyIG9wdGlvbmFsX2ludDMyICAgID0gIDE7CisgICAgIGludDY0IG9wdGlvbmFsX2ludDY0ICAgID0gIDI7CisgICAgdWludDMyIG9wdGlvbmFsX3VpbnQzMiAgID0gIDM7CisgICAgdWludDY0IG9wdGlvbmFsX3VpbnQ2NCAgID0gIDQ7CisgICAgc2ludDMyIG9wdGlvbmFsX3NpbnQzMiAgID0gIDU7CisgICAgc2ludDY0IG9wdGlvbmFsX3NpbnQ2NCAgID0gIDY7CisgICBmaXhlZDMyIG9wdGlvbmFsX2ZpeGVkMzIgID0gIDc7CisgICBmaXhlZDY0IG9wdGlvbmFsX2ZpeGVkNjQgID0gIDg7CisgIHNmaXhlZDMyIG9wdGlvbmFsX3NmaXhlZDMyID0gIDk7CisgIHNmaXhlZDY0IG9wdGlvbmFsX3NmaXhlZDY0ID0gMTA7CisgICAgIGZsb2F0IG9wdGlvbmFsX2Zsb2F0ICAgID0gMTE7CisgICAgZG91YmxlIG9wdGlvbmFsX2RvdWJsZSAgID0gMTI7CisgICAgICBib29sIG9wdGlvbmFsX2Jvb2wgICAgID0gMTM7CisgICAgc3RyaW5nIG9wdGlvbmFsX3N0cmluZyAgID0gMTQ7CisgICAgIGJ5dGVzIG9wdGlvbmFsX2J5dGVzICAgID0gMTU7CisKKyAgLy8gR3JvdXBzIGFyZSBub3QgYWxsb3dlZCBpbiBwcm90bzMuCisgIC8vIG9wdGlvbmFsIGdyb3VwIE9wdGlvbmFsR3JvdXAgPSAxNiB7CisgIC8vICAgb3B0aW9uYWwgaW50MzIgYSA9IDE3OworICAvLyB9CisKKyAgTmVzdGVkTWVzc2FnZSAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlICA9IDE4OworICBGb3JlaWduTWVzc2FnZSAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlID0gMTk7CisgIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlICA9IDIwOworCisgIE5lc3RlZEVudW0gICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25hbF9uZXN0ZWRfZW51bSAgICAgPSAyMTsKKyAgRm9yZWlnbkVudW0gICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbmFsX2ZvcmVpZ25fZW51bSAgICA9IDIyOworCisgIC8vIE9taXR0ZWQgKGNvbXBhcmVkIHRvIHVuaXR0ZXN0LnByb3RvKSBiZWNhdXNlIHByb3RvMiBlbnVtcyBhcmUgbm90IGFsbG93ZWQKKyAgLy8gaW5zaWRlIHByb3RvMiBtZXNzYWdlcy4KKyAgLy8KKyAgLy8gb3B0aW9uYWwgcHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydEVudW0gICAgb3B0aW9uYWxfaW1wb3J0X2VudW0gID0gMjM7CisKKyAgc3RyaW5nIG9wdGlvbmFsX3N0cmluZ19waWVjZSA9IDI0IFtjdHlwZT1TVFJJTkdfUElFQ0VdOworICBzdHJpbmcgb3B0aW9uYWxfY29yZCA9IDI1IFtjdHlwZT1DT1JEXTsKKworICAvLyBEZWZpbmVkIGluIHVuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucHJvdG8KKyAgcHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LlB1YmxpY0ltcG9ydE1lc3NhZ2UKKyAgICAgIG9wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZSA9IDI2OworCisgIE5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gMjcgW2xhenk9dHJ1ZV07CisKKyAgLy8gUmVwZWF0ZWQKKyAgcmVwZWF0ZWQgICAgaW50MzIgcmVwZWF0ZWRfaW50MzIgICAgPSAzMTsKKyAgcmVwZWF0ZWQgICAgaW50NjQgcmVwZWF0ZWRfaW50NjQgICAgPSAzMjsKKyAgcmVwZWF0ZWQgICB1aW50MzIgcmVwZWF0ZWRfdWludDMyICAgPSAzMzsKKyAgcmVwZWF0ZWQgICB1aW50NjQgcmVwZWF0ZWRfdWludDY0ICAgPSAzNDsKKyAgcmVwZWF0ZWQgICBzaW50MzIgcmVwZWF0ZWRfc2ludDMyICAgPSAzNTsKKyAgcmVwZWF0ZWQgICBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ICAgPSAzNjsKKyAgcmVwZWF0ZWQgIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiAgPSAzNzsKKyAgcmVwZWF0ZWQgIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCAgPSAzODsKKyAgcmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSAzOTsKKyAgcmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSA0MDsKKyAgcmVwZWF0ZWQgICAgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgICAgPSA0MTsKKyAgcmVwZWF0ZWQgICBkb3VibGUgcmVwZWF0ZWRfZG91YmxlICAgPSA0MjsKKyAgcmVwZWF0ZWQgICAgIGJvb2wgcmVwZWF0ZWRfYm9vbCAgICAgPSA0MzsKKyAgcmVwZWF0ZWQgICBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nICAgPSA0NDsKKyAgcmVwZWF0ZWQgICAgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMgICAgPSA0NTsKKworICAvLyBHcm91cHMgYXJlIG5vdCBhbGxvd2VkIGluIHByb3RvMy4KKyAgLy8gcmVwZWF0ZWQgZ3JvdXAgUmVwZWF0ZWRHcm91cCA9IDQ2IHsKKyAgLy8gICBvcHRpb25hbCBpbnQzMiBhID0gNDc7CisgIC8vIH0KKworICByZXBlYXRlZCBOZXN0ZWRNZXNzYWdlICAgICAgICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgID0gNDg7CisgIHJlcGVhdGVkIEZvcmVpZ25NZXNzYWdlICAgICAgICAgICAgICAgICAgICAgICByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTsKKyAgcmVwZWF0ZWQgcHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgID0gNTA7CisKKyAgcmVwZWF0ZWQgTmVzdGVkRW51bSAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcGVhdGVkX25lc3RlZF9lbnVtICAgICA9IDUxOworICByZXBlYXRlZCBGb3JlaWduRW51bSAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRfZm9yZWlnbl9lbnVtICAgID0gNTI7CisKKyAgLy8gT21pdHRlZCAoY29tcGFyZWQgdG8gdW5pdHRlc3QucHJvdG8pIGJlY2F1c2UgcHJvdG8yIGVudW1zIGFyZSBub3QgYWxsb3dlZAorICAvLyBpbnNpZGUgcHJvdG8yIG1lc3NhZ2VzLgorICAvLworICAvLyByZXBlYXRlZCBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0RW51bSAgICByZXBlYXRlZF9pbXBvcnRfZW51bSAgPSA1MzsKKworICByZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlPVNUUklOR19QSUVDRV07CisgIHJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9jb3JkID0gNTUgW2N0eXBlPUNPUkRdOworCisgIHJlcGVhdGVkIE5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenk9dHJ1ZV07CisKKyAgb25lb2Ygb25lb2ZfZmllbGQgeworICAgIHVpbnQzMiBvbmVvZl91aW50MzIgPSAxMTE7CisgICAgTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDExMjsKKyAgICBzdHJpbmcgb25lb2Zfc3RyaW5nID0gMTEzOworICAgIGJ5dGVzIG9uZW9mX2J5dGVzID0gMTE0OworICB9Cit9CisKKy8vIFRlc3QgbWVzc2FnZXMgZm9yIHBhY2tlZCBmaWVsZHMKKworbWVzc2FnZSBUZXN0UGFja2VkVHlwZXMgeworICByZXBlYXRlZCAgICBpbnQzMiBwYWNrZWRfaW50MzIgICAgPSAgOTAgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCAgICBpbnQ2NCBwYWNrZWRfaW50NjQgICAgPSAgOTEgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCAgIHVpbnQzMiBwYWNrZWRfdWludDMyICAgPSAgOTIgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCAgIHVpbnQ2NCBwYWNrZWRfdWludDY0ICAgPSAgOTMgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCAgIHNpbnQzMiBwYWNrZWRfc2ludDMyICAgPSAgOTQgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCAgIHNpbnQ2NCBwYWNrZWRfc2ludDY0ICAgPSAgOTUgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCAgZml4ZWQzMiBwYWNrZWRfZml4ZWQzMiAgPSAgOTYgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCAgZml4ZWQ2NCBwYWNrZWRfZml4ZWQ2NCAgPSAgOTcgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCBzZml4ZWQzMiBwYWNrZWRfc2ZpeGVkMzIgPSAgOTggW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCBzZml4ZWQ2NCBwYWNrZWRfc2ZpeGVkNjQgPSAgOTkgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCAgICBmbG9hdCBwYWNrZWRfZmxvYXQgICAgPSAxMDAgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCAgIGRvdWJsZSBwYWNrZWRfZG91YmxlICAgPSAxMDEgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCAgICAgYm9vbCBwYWNrZWRfYm9vbCAgICAgPSAxMDIgW3BhY2tlZCA9IHRydWVdOworICByZXBlYXRlZCBGb3JlaWduRW51bSBwYWNrZWRfZW51bSAgPSAxMDMgW3BhY2tlZCA9IHRydWVdOworfQorCisvLyBFeHBsaWNpdGx5IHNldCBwYWNrZWQgdG8gZmFsc2UKK21lc3NhZ2UgVGVzdFVucGFja2VkVHlwZXMgeworICByZXBlYXRlZCAgICBpbnQzMiByZXBlYXRlZF9pbnQzMiAgICA9ICAxIFtwYWNrZWQgPSBmYWxzZV07CisgIHJlcGVhdGVkICAgIGludDY0IHJlcGVhdGVkX2ludDY0ICAgID0gIDIgW3BhY2tlZCA9IGZhbHNlXTsKKyAgcmVwZWF0ZWQgICB1aW50MzIgcmVwZWF0ZWRfdWludDMyICAgPSAgMyBbcGFja2VkID0gZmFsc2VdOworICByZXBlYXRlZCAgIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgICA9ICA0IFtwYWNrZWQgPSBmYWxzZV07CisgIHJlcGVhdGVkICAgc2ludDMyIHJlcGVhdGVkX3NpbnQzMiAgID0gIDUgW3BhY2tlZCA9IGZhbHNlXTsKKyAgcmVwZWF0ZWQgICBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ICAgPSAgNiBbcGFja2VkID0gZmFsc2VdOworICByZXBlYXRlZCAgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyICA9ICA3IFtwYWNrZWQgPSBmYWxzZV07CisgIHJlcGVhdGVkICBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgID0gIDggW3BhY2tlZCA9IGZhbHNlXTsKKyAgcmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSAgOSBbcGFja2VkID0gZmFsc2VdOworICByZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDEwIFtwYWNrZWQgPSBmYWxzZV07CisgIHJlcGVhdGVkICAgIGZsb2F0IHJlcGVhdGVkX2Zsb2F0ICAgID0gMTEgW3BhY2tlZCA9IGZhbHNlXTsKKyAgcmVwZWF0ZWQgICBkb3VibGUgcmVwZWF0ZWRfZG91YmxlICAgPSAxMiBbcGFja2VkID0gZmFsc2VdOworICByZXBlYXRlZCAgICAgYm9vbCByZXBlYXRlZF9ib29sICAgICA9IDEzIFtwYWNrZWQgPSBmYWxzZV07CisgIHJlcGVhdGVkIFRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMTQgW3BhY2tlZCA9IGZhbHNlXTsKK30KKworLy8gVGhpcyBwcm90byBpbmNsdWRlcyBhIHJlY3VzaXZlbHkgbmVzdGVkIG1lc3NhZ2UuCittZXNzYWdlIE5lc3RlZFRlc3RBbGxUeXBlcyB7CisgIE5lc3RlZFRlc3RBbGxUeXBlcyBjaGlsZCA9IDE7CisgIFRlc3RBbGxUeXBlcyBwYXlsb2FkID0gMjsKK30KKworLy8gRGVmaW5lIHRoZXNlIGFmdGVyIFRlc3RBbGxUeXBlcyB0byBtYWtlIHN1cmUgdGhlIGNvbXBpbGVyIGNhbiBoYW5kbGUKKy8vIHRoYXQuCittZXNzYWdlIEZvcmVpZ25NZXNzYWdlIHsKKyAgaW50MzIgYyA9IDE7Cit9CisKK2VudW0gRm9yZWlnbkVudW0geworICBGT1JFSUdOX1pFUk8gPSAwOworICBGT1JFSUdOX0ZPTyA9IDQ7CisgIEZPUkVJR05fQkFSID0gNTsKKyAgRk9SRUlHTl9CQVogPSA2OworfQorCisvLyBUZXN0RW1wdHlNZXNzYWdlIGlzIHVzZWQgdG8gdGVzdCBiZWhhdmlvciBvZiB1bmtub3duIGZpZWxkcy4KK21lc3NhZ2UgVGVzdEVtcHR5TWVzc2FnZSB7Cit9CisKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfd2VsbF9rbm93bl90eXBlcy5wcm90byBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfd2VsbF9rbm93bl90eXBlcy5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jOTA3NTI0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF93ZWxsX2tub3duX3R5cGVzLnByb3RvCkBAIC0wLDAgKzEsMTE0IEBACitzeW50YXggPSAicHJvdG8zIjsKKworcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdDsKKworb3B0aW9uIGNzaGFycF9uYW1lc3BhY2UgPSAiR29vZ2xlLlByb3RvYnVmLlRlc3RQcm90b3MiOworb3B0aW9uIGphdmFfbXVsdGlwbGVfZmlsZXMgPSB0cnVlOworb3B0aW9uIGphdmFfcGFja2FnZSA9ICJjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QiOworCitpbXBvcnQgImdvb2dsZS9wcm90b2J1Zi9hbnkucHJvdG8iOworaW1wb3J0ICJnb29nbGUvcHJvdG9idWYvYXBpLnByb3RvIjsKK2ltcG9ydCAiZ29vZ2xlL3Byb3RvYnVmL2R1cmF0aW9uLnByb3RvIjsKK2ltcG9ydCAiZ29vZ2xlL3Byb3RvYnVmL2VtcHR5LnByb3RvIjsKK2ltcG9ydCAiZ29vZ2xlL3Byb3RvYnVmL2ZpZWxkX21hc2sucHJvdG8iOworaW1wb3J0ICJnb29nbGUvcHJvdG9idWYvc291cmNlX2NvbnRleHQucHJvdG8iOworaW1wb3J0ICJnb29nbGUvcHJvdG9idWYvc3RydWN0LnByb3RvIjsKK2ltcG9ydCAiZ29vZ2xlL3Byb3RvYnVmL3RpbWVzdGFtcC5wcm90byI7CitpbXBvcnQgImdvb2dsZS9wcm90b2J1Zi90eXBlLnByb3RvIjsKK2ltcG9ydCAiZ29vZ2xlL3Byb3RvYnVmL3dyYXBwZXJzLnByb3RvIjsKKworLy8gVGVzdCB0aGF0IHdlIGNhbiBpbmNsdWRlIGFsbCB3ZWxsLWtub3duIHR5cGVzLgorLy8gRWFjaCB3cmFwcGVyIHR5cGUgaXMgaW5jbHVkZWQgc2VwYXJhdGVseSwgYXMgbGFuZ3VhZ2VzCisvLyBtYXAgaGFuZGxlIGRpZmZlcmVudCB3cmFwcGVycyBpbiBkaWZmZXJlbnQgd2F5cy4KK21lc3NhZ2UgVGVzdFdlbGxLbm93blR5cGVzIHsKKyAgZ29vZ2xlLnByb3RvYnVmLkFueSBhbnlfZmllbGQgPSAxOworICBnb29nbGUucHJvdG9idWYuQXBpIGFwaV9maWVsZCA9IDI7CisgIGdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiBkdXJhdGlvbl9maWVsZCA9IDM7CisgIGdvb2dsZS5wcm90b2J1Zi5FbXB0eSBlbXB0eV9maWVsZCA9IDQ7CisgIGdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2sgZmllbGRfbWFza19maWVsZCA9IDU7CisgIGdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0IHNvdXJjZV9jb250ZXh0X2ZpZWxkID0gNjsKKyAgZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCBzdHJ1Y3RfZmllbGQgPSA3OworICBnb29nbGUucHJvdG9idWYuVGltZXN0YW1wIHRpbWVzdGFtcF9maWVsZCA9IDg7CisgIGdvb2dsZS5wcm90b2J1Zi5UeXBlIHR5cGVfZmllbGQgPSA5OworICBnb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgZG91YmxlX2ZpZWxkID0gMTA7CisgIGdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlIGZsb2F0X2ZpZWxkID0gMTE7CisgIGdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGludDY0X2ZpZWxkID0gMTI7CisgIGdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSB1aW50NjRfZmllbGQgPSAxMzsKKyAgZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUgaW50MzJfZmllbGQgPSAxNDsKKyAgZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlIHVpbnQzMl9maWVsZCA9IDE1OworICBnb29nbGUucHJvdG9idWYuQm9vbFZhbHVlIGJvb2xfZmllbGQgPSAxNjsKKyAgZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIHN0cmluZ19maWVsZCA9IDE3OworICBnb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSBieXRlc19maWVsZCA9IDE4OworICAvLyBQYXJ0IG9mIHN0cnVjdCwgYnV0IHVzZWZ1bCB0byBiZSBhYmxlIHRvIHRlc3Qgc2VwYXJhdGVseQorICBnb29nbGUucHJvdG9idWYuVmFsdWUgdmFsdWVfZmllbGQgPSAxOTsKK30KKworLy8gQSByZXBlYXRlZCBmaWVsZCBmb3IgZWFjaCB3ZWxsLWtub3duIHR5cGUuCittZXNzYWdlIFJlcGVhdGVkV2VsbEtub3duVHlwZXMgeworICByZXBlYXRlZCBnb29nbGUucHJvdG9idWYuQW55IGFueV9maWVsZCA9IDE7CisgIHJlcGVhdGVkIGdvb2dsZS5wcm90b2J1Zi5BcGkgYXBpX2ZpZWxkID0gMjsKKyAgcmVwZWF0ZWQgZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uIGR1cmF0aW9uX2ZpZWxkID0gMzsKKyAgcmVwZWF0ZWQgZ29vZ2xlLnByb3RvYnVmLkVtcHR5IGVtcHR5X2ZpZWxkID0gNDsKKyAgcmVwZWF0ZWQgZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayBmaWVsZF9tYXNrX2ZpZWxkID0gNTsKKyAgcmVwZWF0ZWQgZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQgc291cmNlX2NvbnRleHRfZmllbGQgPSA2OworICByZXBlYXRlZCBnb29nbGUucHJvdG9idWYuU3RydWN0IHN0cnVjdF9maWVsZCA9IDc7CisgIHJlcGVhdGVkIGdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAgdGltZXN0YW1wX2ZpZWxkID0gODsKKyAgcmVwZWF0ZWQgZ29vZ2xlLnByb3RvYnVmLlR5cGUgdHlwZV9maWVsZCA9IDk7CisgIC8vIFRoZXNlIGRvbid0IGFjdHVhbGx5IG1ha2UgYSBsb3Qgb2Ygc2Vuc2UsIGJ1dCB0aGV5J3JlIG5vdCBwcm9oaWJpdGVkLi4uCisgIHJlcGVhdGVkIGdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBkb3VibGVfZmllbGQgPSAxMDsKKyAgcmVwZWF0ZWQgZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgZmxvYXRfZmllbGQgPSAxMTsKKyAgcmVwZWF0ZWQgZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUgaW50NjRfZmllbGQgPSAxMjsKKyAgcmVwZWF0ZWQgZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIHVpbnQ2NF9maWVsZCA9IDEzOworICByZXBlYXRlZCBnb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBpbnQzMl9maWVsZCA9IDE0OworICByZXBlYXRlZCBnb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgdWludDMyX2ZpZWxkID0gMTU7CisgIHJlcGVhdGVkIGdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgYm9vbF9maWVsZCA9IDE2OworICByZXBlYXRlZCBnb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUgc3RyaW5nX2ZpZWxkID0gMTc7CisgIHJlcGVhdGVkIGdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGJ5dGVzX2ZpZWxkID0gMTg7Cit9CisKK21lc3NhZ2UgT25lb2ZXZWxsS25vd25UeXBlcyB7CisgIG9uZW9mIG9uZW9mX2ZpZWxkIHsKKyAgICBnb29nbGUucHJvdG9idWYuQW55IGFueV9maWVsZCA9IDE7CisgICAgZ29vZ2xlLnByb3RvYnVmLkFwaSBhcGlfZmllbGQgPSAyOworICAgIGdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiBkdXJhdGlvbl9maWVsZCA9IDM7CisgICAgZ29vZ2xlLnByb3RvYnVmLkVtcHR5IGVtcHR5X2ZpZWxkID0gNDsKKyAgICBnb29nbGUucHJvdG9idWYuRmllbGRNYXNrIGZpZWxkX21hc2tfZmllbGQgPSA1OworICAgIGdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0IHNvdXJjZV9jb250ZXh0X2ZpZWxkID0gNjsKKyAgICBnb29nbGUucHJvdG9idWYuU3RydWN0IHN0cnVjdF9maWVsZCA9IDc7CisgICAgZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCB0aW1lc3RhbXBfZmllbGQgPSA4OworICAgIGdvb2dsZS5wcm90b2J1Zi5UeXBlIHR5cGVfZmllbGQgPSA5OworICAgIGdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBkb3VibGVfZmllbGQgPSAxMDsKKyAgICBnb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSBmbG9hdF9maWVsZCA9IDExOworICAgIGdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGludDY0X2ZpZWxkID0gMTI7CisgICAgZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIHVpbnQ2NF9maWVsZCA9IDEzOworICAgIGdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlIGludDMyX2ZpZWxkID0gMTQ7CisgICAgZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlIHVpbnQzMl9maWVsZCA9IDE1OworICAgIGdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgYm9vbF9maWVsZCA9IDE2OworICAgIGdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSBzdHJpbmdfZmllbGQgPSAxNzsKKyAgICBnb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSBieXRlc19maWVsZCA9IDE4OworICB9Cit9CisKKy8vIEEgbWFwIGZpZWxkIGZvciBlYWNoIHdlbGwta25vd24gdHlwZS4gV2Ugb25seQorLy8gbmVlZCB0byB3b3JyeSBhYm91dCB0aGUgdmFsdWUgcGFydCBvZiB0aGUgbWFwIGJlaW5nIHRoZQorLy8gd2VsbC1rbm93biB0eXBlcywgYXMgbWVzc2FnZXMgY2FuJ3QgYmUgbWFwIGtleXMuCittZXNzYWdlIE1hcFdlbGxLbm93blR5cGVzIHsKKyAgbWFwPGludDMyLGdvb2dsZS5wcm90b2J1Zi5Bbnk+IGFueV9maWVsZCA9IDE7CisgIG1hcDxpbnQzMixnb29nbGUucHJvdG9idWYuQXBpPiBhcGlfZmllbGQgPSAyOworICBtYXA8aW50MzIsZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uPiBkdXJhdGlvbl9maWVsZCA9IDM7CisgIG1hcDxpbnQzMixnb29nbGUucHJvdG9idWYuRW1wdHk+IGVtcHR5X2ZpZWxkID0gNDsKKyAgbWFwPGludDMyLGdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2s+IGZpZWxkX21hc2tfZmllbGQgPSA1OworICBtYXA8aW50MzIsZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQ+IHNvdXJjZV9jb250ZXh0X2ZpZWxkID0gNjsKKyAgbWFwPGludDMyLGdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3Q+IHN0cnVjdF9maWVsZCA9IDc7CisgIG1hcDxpbnQzMixnb29nbGUucHJvdG9idWYuVGltZXN0YW1wPiB0aW1lc3RhbXBfZmllbGQgPSA4OworICBtYXA8aW50MzIsZ29vZ2xlLnByb3RvYnVmLlR5cGU+IHR5cGVfZmllbGQgPSA5OworICBtYXA8aW50MzIsZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlPiBkb3VibGVfZmllbGQgPSAxMDsKKyAgbWFwPGludDMyLGdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlPiBmbG9hdF9maWVsZCA9IDExOworICBtYXA8aW50MzIsZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWU+IGludDY0X2ZpZWxkID0gMTI7CisgIG1hcDxpbnQzMixnb29nbGUucHJvdG9idWYuVUludDY0VmFsdWU+IHVpbnQ2NF9maWVsZCA9IDEzOworICBtYXA8aW50MzIsZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWU+IGludDMyX2ZpZWxkID0gMTQ7CisgIG1hcDxpbnQzMixnb29nbGUucHJvdG9idWYuVUludDMyVmFsdWU+IHVpbnQzMl9maWVsZCA9IDE1OworICBtYXA8aW50MzIsZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZT4gYm9vbF9maWVsZCA9IDE2OworICBtYXA8aW50MzIsZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlPiBzdHJpbmdfZmllbGQgPSAxNzsKKyAgbWFwPGludDMyLGdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlPiBieXRlc19maWVsZCA9IDE4OworfQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91bmtub3duX2ZpZWxkX3NldC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5rbm93bl9maWVsZF9zZXQuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDRlMzgzZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdW5rbm93bl9maWVsZF9zZXQuY2MKQEAgLTAsMCArMSwzNDcgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bmtub3duX2ZpZWxkX3NldC5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2xvZ2dpbmcuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdGxfdXRpbC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisKK25hbWVzcGFjZSB7CisvLyBUaGlzIGdsb2JhbCBpbnN0YW5jZSBpcyByZXR1cm5lZCBieSB1bmtub3duX2ZpZWxkcygpIG9uIGFueSBtZXNzYWdlIGNsYXNzCisvLyB3aGVuIHRoZSBvYmplY3QgaGFzIG5vIHVua25vd24gZmllbGRzLiBUaGlzIGlzIG5lY2Vzc2FyeSBiZWNhdXNlIHdlIG5vdworLy8gaW5zdGFudGlhdGUgdGhlIFVua25vd25GaWVsZFNldCBkeW5hbWljYWxseSBvbmx5IHdoZW4gcmVxdWlyZWQuCitVbmtub3duRmllbGRTZXQqIGRlZmF1bHRfdW5rbm93bl9maWVsZF9zZXRfaW5zdGFuY2VfID0gTlVMTDsKKwordm9pZCBEZWxldGVEZWZhdWx0VW5rbm93bkZpZWxkU2V0KCkgeworICBkZWxldGUgZGVmYXVsdF91bmtub3duX2ZpZWxkX3NldF9pbnN0YW5jZV87Cit9CisKK3ZvaWQgSW5pdERlZmF1bHRVbmtub3duRmllbGRTZXQoKSB7CisgIGRlZmF1bHRfdW5rbm93bl9maWVsZF9zZXRfaW5zdGFuY2VfID0gbmV3IFVua25vd25GaWVsZFNldCgpOworICBpbnRlcm5hbDo6T25TaHV0ZG93bigmRGVsZXRlRGVmYXVsdFVua25vd25GaWVsZFNldCk7Cit9CisKK0dPT0dMRV9QUk9UT0JVRl9ERUNMQVJFX09OQ0UoZGVmYXVsdF91bmtub3duX2ZpZWxkX3NldF9vbmNlX2luaXRfKTsKK30KKworY29uc3QgVW5rbm93bkZpZWxkU2V0KiBVbmtub3duRmllbGRTZXQ6OmRlZmF1bHRfaW5zdGFuY2UoKSB7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6R29vZ2xlT25jZUluaXQoJmRlZmF1bHRfdW5rbm93bl9maWVsZF9zZXRfb25jZV9pbml0XywKKyAgICAgICAgICAgICAgICAgJkluaXREZWZhdWx0VW5rbm93bkZpZWxkU2V0KTsKKyAgcmV0dXJuIGRlZmF1bHRfdW5rbm93bl9maWVsZF9zZXRfaW5zdGFuY2VfOworfQorCitVbmtub3duRmllbGRTZXQ6OlVua25vd25GaWVsZFNldCgpCisgICAgOiBmaWVsZHNfKE5VTEwpIHt9CisKK1Vua25vd25GaWVsZFNldDo6flVua25vd25GaWVsZFNldCgpIHsKKyAgQ2xlYXIoKTsKKyAgZGVsZXRlIGZpZWxkc187Cit9CisKK3ZvaWQgVW5rbm93bkZpZWxkU2V0OjpDbGVhckZhbGxiYWNrKCkgeworICBpZiAoZmllbGRzXyAhPSBOVUxMKSB7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZHNfLT5zaXplKCk7IGkrKykgeworICAgICAgKCpmaWVsZHNfKVtpXS5EZWxldGUoKTsKKyAgICB9CisgICAgZGVsZXRlIGZpZWxkc187CisgICAgZmllbGRzXyA9IE5VTEw7CisgIH0KK30KKwordm9pZCBVbmtub3duRmllbGRTZXQ6OkNsZWFyQW5kRnJlZU1lbW9yeSgpIHsKKyAgaWYgKGZpZWxkc18gIT0gTlVMTCkgeworICAgIENsZWFyKCk7CisgIH0KK30KKwordm9pZCBVbmtub3duRmllbGRTZXQ6OkludGVybmFsTWVyZ2VGcm9tKGNvbnN0IFVua25vd25GaWVsZFNldCYgb3RoZXIpIHsKKyAgaW50IG90aGVyX2ZpZWxkX2NvdW50ID0gb3RoZXIuZmllbGRfY291bnQoKTsKKyAgaWYgKG90aGVyX2ZpZWxkX2NvdW50ID4gMCkgeworICAgIGZpZWxkc18gPSBuZXcgdmVjdG9yPFVua25vd25GaWVsZD4oKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IG90aGVyX2ZpZWxkX2NvdW50OyBpKyspIHsKKyAgICAgIGZpZWxkc18tPnB1c2hfYmFjaygoKm90aGVyLmZpZWxkc18pW2ldKTsKKyAgICAgIGZpZWxkc18tPmJhY2soKS5EZWVwQ29weSgoKm90aGVyLmZpZWxkc18pW2ldKTsKKyAgICB9CisgIH0KK30KKwordm9pZCBVbmtub3duRmllbGRTZXQ6Ok1lcmdlRnJvbShjb25zdCBVbmtub3duRmllbGRTZXQmIG90aGVyKSB7CisgIGludCBvdGhlcl9maWVsZF9jb3VudCA9IG90aGVyLmZpZWxkX2NvdW50KCk7CisgIGlmIChvdGhlcl9maWVsZF9jb3VudCA+IDApIHsKKyAgICBpZiAoZmllbGRzXyA9PSBOVUxMKSBmaWVsZHNfID0gbmV3IHZlY3RvcjxVbmtub3duRmllbGQ+KCk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBvdGhlcl9maWVsZF9jb3VudDsgaSsrKSB7CisgICAgICBmaWVsZHNfLT5wdXNoX2JhY2soKCpvdGhlci5maWVsZHNfKVtpXSk7CisgICAgICBmaWVsZHNfLT5iYWNrKCkuRGVlcENvcHkoKCpvdGhlci5maWVsZHNfKVtpXSk7CisgICAgfQorICB9Cit9CisKKy8vIEEgc3BlY2lhbGl6ZWQgTWVyZ2VGcm9tIGZvciBwZXJmb3JtYW5jZSB3aGVuIHdlIGFyZSBtZXJnaW5nIGZyb20gYW4gVUZTIHRoYXQKKy8vIGlzIHRlbXBvcmFyeSBhbmQgY2FuIGJlIGRlc3Ryb3llZCBpbiB0aGUgcHJvY2Vzcy4KK3ZvaWQgVW5rbm93bkZpZWxkU2V0OjpNZXJnZUZyb21BbmREZXN0cm95KFVua25vd25GaWVsZFNldCogb3RoZXIpIHsKKyAgaW50IG90aGVyX2ZpZWxkX2NvdW50ID0gb3RoZXItPmZpZWxkX2NvdW50KCk7CisgIGlmIChvdGhlcl9maWVsZF9jb3VudCA+IDApIHsKKyAgICBpZiAoZmllbGRzXyA9PSBOVUxMKSBmaWVsZHNfID0gbmV3IHZlY3RvcjxVbmtub3duRmllbGQ+KCk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBvdGhlcl9maWVsZF9jb3VudDsgaSsrKSB7CisgICAgICBmaWVsZHNfLT5wdXNoX2JhY2soKCpvdGhlci0+ZmllbGRzXylbaV0pOworICAgICAgKCpvdGhlci0+ZmllbGRzXylbaV0uUmVzZXQoKTsKKyAgICB9CisgIH0KKyAgZGVsZXRlIG90aGVyLT5maWVsZHNfOworICBvdGhlci0+ZmllbGRzXyA9IE5VTEw7Cit9CisKK2ludCBVbmtub3duRmllbGRTZXQ6OlNwYWNlVXNlZEV4Y2x1ZGluZ1NlbGYoKSBjb25zdCB7CisgIGlmIChmaWVsZHNfID09IE5VTEwpIHJldHVybiAwOworCisgIGludCB0b3RhbF9zaXplID0gc2l6ZW9mKCpmaWVsZHNfKSArIHNpemVvZihVbmtub3duRmllbGQpICogZmllbGRzXy0+c2l6ZSgpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRzXy0+c2l6ZSgpOyBpKyspIHsKKyAgICBjb25zdCBVbmtub3duRmllbGQmIGZpZWxkID0gKCpmaWVsZHNfKVtpXTsKKyAgICBzd2l0Y2ggKGZpZWxkLnR5cGUoKSkgeworICAgICAgY2FzZSBVbmtub3duRmllbGQ6OlRZUEVfTEVOR1RIX0RFTElNSVRFRDoKKyAgICAgICAgdG90YWxfc2l6ZSArPSBzaXplb2YoKmZpZWxkLmxlbmd0aF9kZWxpbWl0ZWRfLnN0cmluZ192YWx1ZV8pICsKKyAgICAgICAgICAgICAgICAgICAgICBpbnRlcm5hbDo6U3RyaW5nU3BhY2VVc2VkRXhjbHVkaW5nU2VsZigKKyAgICAgICAgICAgICAgICAgICAgICAgICAgKmZpZWxkLmxlbmd0aF9kZWxpbWl0ZWRfLnN0cmluZ192YWx1ZV8pOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgVW5rbm93bkZpZWxkOjpUWVBFX0dST1VQOgorICAgICAgICB0b3RhbF9zaXplICs9IGZpZWxkLmdyb3VwXy0+U3BhY2VVc2VkKCk7CisgICAgICAgIGJyZWFrOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgYnJlYWs7CisgICAgfQorICB9CisgIHJldHVybiB0b3RhbF9zaXplOworfQorCitpbnQgVW5rbm93bkZpZWxkU2V0OjpTcGFjZVVzZWQoKSBjb25zdCB7CisgIHJldHVybiBzaXplb2YoKnRoaXMpICsgU3BhY2VVc2VkRXhjbHVkaW5nU2VsZigpOworfQorCit2b2lkIFVua25vd25GaWVsZFNldDo6QWRkVmFyaW50KGludCBudW1iZXIsIHVpbnQ2NCB2YWx1ZSkgeworICBVbmtub3duRmllbGQgZmllbGQ7CisgIGZpZWxkLm51bWJlcl8gPSBudW1iZXI7CisgIGZpZWxkLlNldFR5cGUoVW5rbm93bkZpZWxkOjpUWVBFX1ZBUklOVCk7CisgIGZpZWxkLnZhcmludF8gPSB2YWx1ZTsKKyAgaWYgKGZpZWxkc18gPT0gTlVMTCkgZmllbGRzXyA9IG5ldyB2ZWN0b3I8VW5rbm93bkZpZWxkPigpOworICBmaWVsZHNfLT5wdXNoX2JhY2soZmllbGQpOworfQorCit2b2lkIFVua25vd25GaWVsZFNldDo6QWRkRml4ZWQzMihpbnQgbnVtYmVyLCB1aW50MzIgdmFsdWUpIHsKKyAgVW5rbm93bkZpZWxkIGZpZWxkOworICBmaWVsZC5udW1iZXJfID0gbnVtYmVyOworICBmaWVsZC5TZXRUeXBlKFVua25vd25GaWVsZDo6VFlQRV9GSVhFRDMyKTsKKyAgZmllbGQuZml4ZWQzMl8gPSB2YWx1ZTsKKyAgaWYgKGZpZWxkc18gPT0gTlVMTCkgZmllbGRzXyA9IG5ldyB2ZWN0b3I8VW5rbm93bkZpZWxkPigpOworICBmaWVsZHNfLT5wdXNoX2JhY2soZmllbGQpOworfQorCit2b2lkIFVua25vd25GaWVsZFNldDo6QWRkRml4ZWQ2NChpbnQgbnVtYmVyLCB1aW50NjQgdmFsdWUpIHsKKyAgVW5rbm93bkZpZWxkIGZpZWxkOworICBmaWVsZC5udW1iZXJfID0gbnVtYmVyOworICBmaWVsZC5TZXRUeXBlKFVua25vd25GaWVsZDo6VFlQRV9GSVhFRDY0KTsKKyAgZmllbGQuZml4ZWQ2NF8gPSB2YWx1ZTsKKyAgaWYgKGZpZWxkc18gPT0gTlVMTCkgZmllbGRzXyA9IG5ldyB2ZWN0b3I8VW5rbm93bkZpZWxkPigpOworICBmaWVsZHNfLT5wdXNoX2JhY2soZmllbGQpOworfQorCitzdHJpbmcqIFVua25vd25GaWVsZFNldDo6QWRkTGVuZ3RoRGVsaW1pdGVkKGludCBudW1iZXIpIHsKKyAgVW5rbm93bkZpZWxkIGZpZWxkOworICBmaWVsZC5udW1iZXJfID0gbnVtYmVyOworICBmaWVsZC5TZXRUeXBlKFVua25vd25GaWVsZDo6VFlQRV9MRU5HVEhfREVMSU1JVEVEKTsKKyAgZmllbGQubGVuZ3RoX2RlbGltaXRlZF8uc3RyaW5nX3ZhbHVlXyA9IG5ldyBzdHJpbmc7CisgIGlmIChmaWVsZHNfID09IE5VTEwpIGZpZWxkc18gPSBuZXcgdmVjdG9yPFVua25vd25GaWVsZD4oKTsKKyAgZmllbGRzXy0+cHVzaF9iYWNrKGZpZWxkKTsKKyAgcmV0dXJuIGZpZWxkLmxlbmd0aF9kZWxpbWl0ZWRfLnN0cmluZ192YWx1ZV87Cit9CisKKworVW5rbm93bkZpZWxkU2V0KiBVbmtub3duRmllbGRTZXQ6OkFkZEdyb3VwKGludCBudW1iZXIpIHsKKyAgVW5rbm93bkZpZWxkIGZpZWxkOworICBmaWVsZC5udW1iZXJfID0gbnVtYmVyOworICBmaWVsZC5TZXRUeXBlKFVua25vd25GaWVsZDo6VFlQRV9HUk9VUCk7CisgIGZpZWxkLmdyb3VwXyA9IG5ldyBVbmtub3duRmllbGRTZXQ7CisgIGlmIChmaWVsZHNfID09IE5VTEwpIGZpZWxkc18gPSBuZXcgdmVjdG9yPFVua25vd25GaWVsZD4oKTsKKyAgZmllbGRzXy0+cHVzaF9iYWNrKGZpZWxkKTsKKyAgcmV0dXJuIGZpZWxkLmdyb3VwXzsKK30KKwordm9pZCBVbmtub3duRmllbGRTZXQ6OkFkZEZpZWxkKGNvbnN0IFVua25vd25GaWVsZCYgZmllbGQpIHsKKyAgaWYgKGZpZWxkc18gPT0gTlVMTCkgZmllbGRzXyA9IG5ldyB2ZWN0b3I8VW5rbm93bkZpZWxkPigpOworICBmaWVsZHNfLT5wdXNoX2JhY2soZmllbGQpOworICBmaWVsZHNfLT5iYWNrKCkuRGVlcENvcHkoZmllbGQpOworfQorCit2b2lkIFVua25vd25GaWVsZFNldDo6RGVsZXRlU3VicmFuZ2UoaW50IHN0YXJ0LCBpbnQgbnVtKSB7CisgIC8vIERlbGV0ZSB0aGUgc3BlY2lmaWVkIGZpZWxkcy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW07ICsraSkgeworICAgICgqZmllbGRzXylbaSArIHN0YXJ0XS5EZWxldGUoKTsKKyAgfQorICAvLyBTbGlkZSBkb3duIHRoZSByZW1haW5pbmcgZmllbGRzLgorICBmb3IgKGludCBpID0gc3RhcnQgKyBudW07IGkgPCBmaWVsZHNfLT5zaXplKCk7ICsraSkgeworICAgICgqZmllbGRzXylbaSAtIG51bV0gPSAoKmZpZWxkc18pW2ldOworICB9CisgIC8vIFBvcCBvZmYgdGhlICMgb2YgZGVsZXRlZCBmaWVsZHMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtOyArK2kpIHsKKyAgICBmaWVsZHNfLT5wb3BfYmFjaygpOworICB9CisgIGlmIChmaWVsZHNfICYmIGZpZWxkc18tPnNpemUoKSA9PSAwKSB7CisgICAgLy8gbWFpbnRhaW4gaW52YXJpYW50OiBuZXZlciBob2xkIGZpZWxkc18gaWYgZW1wdHkuCisgICAgZGVsZXRlIGZpZWxkc187CisgICAgZmllbGRzXyA9IE5VTEw7CisgIH0KK30KKwordm9pZCBVbmtub3duRmllbGRTZXQ6OkRlbGV0ZUJ5TnVtYmVyKGludCBudW1iZXIpIHsKKyAgaWYgKGZpZWxkc18gPT0gTlVMTCkgcmV0dXJuOworICBpbnQgbGVmdCA9IDA7ICAvLyBUaGUgbnVtYmVyIG9mIGZpZWxkcyBsZWZ0IGFmdGVyIGRlbGV0aW9uLgorICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkc18tPnNpemUoKTsgKytpKSB7CisgICAgVW5rbm93bkZpZWxkKiBmaWVsZCA9ICYoKmZpZWxkc18pW2ldOworICAgIGlmIChmaWVsZC0+bnVtYmVyKCkgPT0gbnVtYmVyKSB7CisgICAgICBmaWVsZC0+RGVsZXRlKCk7CisgICAgfSBlbHNlIHsKKyAgICAgIGlmIChpICE9IGxlZnQpIHsKKyAgICAgICAgKCpmaWVsZHNfKVtsZWZ0XSA9ICgqZmllbGRzXylbaV07CisgICAgICB9CisgICAgICArK2xlZnQ7CisgICAgfQorICB9CisgIGZpZWxkc18tPnJlc2l6ZShsZWZ0KTsKKyAgaWYgKGxlZnQgPT0gMCkgeworICAgIC8vIG1haW50YWluIGludmFyaWFudDogbmV2ZXIgaG9sZCBmaWVsZHNfIGlmIGVtcHR5LgorICAgIGRlbGV0ZSBmaWVsZHNfOworICAgIGZpZWxkc18gPSBOVUxMOworICB9Cit9CisKK2Jvb2wgVW5rbm93bkZpZWxkU2V0OjpNZXJnZUZyb21Db2RlZFN0cmVhbShpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyAgVW5rbm93bkZpZWxkU2V0IG90aGVyOworICBpZiAoaW50ZXJuYWw6OldpcmVGb3JtYXQ6OlNraXBNZXNzYWdlKGlucHV0LCAmb3RoZXIpICYmCisgICAgICBpbnB1dC0+Q29uc3VtZWRFbnRpcmVNZXNzYWdlKCkpIHsKKyAgICBNZXJnZUZyb21BbmREZXN0cm95KCZvdGhlcik7CisgICAgcmV0dXJuIHRydWU7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9Cit9CisKK2Jvb2wgVW5rbm93bkZpZWxkU2V0OjpQYXJzZUZyb21Db2RlZFN0cmVhbShpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyAgQ2xlYXIoKTsKKyAgcmV0dXJuIE1lcmdlRnJvbUNvZGVkU3RyZWFtKGlucHV0KTsKK30KKworYm9vbCBVbmtub3duRmllbGRTZXQ6OlBhcnNlRnJvbVplcm9Db3B5U3RyZWFtKGlvOjpaZXJvQ29weUlucHV0U3RyZWFtKiBpbnB1dCkgeworICBpbzo6Q29kZWRJbnB1dFN0cmVhbSBjb2RlZF9pbnB1dChpbnB1dCk7CisgIHJldHVybiAoUGFyc2VGcm9tQ29kZWRTdHJlYW0oJmNvZGVkX2lucHV0KSAmJgorICAgICAgICAgIGNvZGVkX2lucHV0LkNvbnN1bWVkRW50aXJlTWVzc2FnZSgpKTsKK30KKworYm9vbCBVbmtub3duRmllbGRTZXQ6OlBhcnNlRnJvbUFycmF5KGNvbnN0IHZvaWQqIGRhdGEsIGludCBzaXplKSB7CisgIGlvOjpBcnJheUlucHV0U3RyZWFtIGlucHV0KGRhdGEsIHNpemUpOworICByZXR1cm4gUGFyc2VGcm9tWmVyb0NvcHlTdHJlYW0oJmlucHV0KTsKK30KKwordm9pZCBVbmtub3duRmllbGQ6OkRlbGV0ZSgpIHsKKyAgc3dpdGNoICh0eXBlKCkpIHsKKyAgICBjYXNlIFVua25vd25GaWVsZDo6VFlQRV9MRU5HVEhfREVMSU1JVEVEOgorICAgICAgZGVsZXRlIGxlbmd0aF9kZWxpbWl0ZWRfLnN0cmluZ192YWx1ZV87CisgICAgICBicmVhazsKKyAgICBjYXNlIFVua25vd25GaWVsZDo6VFlQRV9HUk9VUDoKKyAgICAgIGRlbGV0ZSBncm91cF87CisgICAgICBicmVhazsKKyAgICBkZWZhdWx0OgorICAgICAgYnJlYWs7CisgIH0KK30KKworLy8gUmVzZXQgYWxsIG93bmVkIHB0cnMsIGEgc3BlY2lhbCBmdW5jdGlvbiBmb3IgcGVyZm9ybWFuY2UsIHRvIGF2b2lkIGRvdWJsZQorLy8gb3duaW5nIHRoZSBwdHJzLCB3aGVuIHdlIG1lcmdlIGZyb20gYSB0ZW1wb3JhcnkgVW5rbm93bkZpZWxkU2V0IG9iamVjdHMuCit2b2lkIFVua25vd25GaWVsZDo6UmVzZXQoKSB7CisgIHN3aXRjaCAodHlwZSgpKSB7CisgICAgY2FzZSBVbmtub3duRmllbGQ6OlRZUEVfTEVOR1RIX0RFTElNSVRFRDoKKyAgICAgIGxlbmd0aF9kZWxpbWl0ZWRfLnN0cmluZ192YWx1ZV8gPSBOVUxMOworICAgICAgYnJlYWs7CisgICAgY2FzZSBVbmtub3duRmllbGQ6OlRZUEVfR1JPVVA6IHsKKyAgICAgIGdyb3VwXyA9IE5VTEw7CisgICAgICBicmVhazsKKyAgICB9CisgICAgZGVmYXVsdDoKKyAgICAgIGJyZWFrOworICB9Cit9CisKK3ZvaWQgVW5rbm93bkZpZWxkOjpEZWVwQ29weShjb25zdCBVbmtub3duRmllbGQmIG90aGVyKSB7CisgIHN3aXRjaCAodHlwZSgpKSB7CisgICAgY2FzZSBVbmtub3duRmllbGQ6OlRZUEVfTEVOR1RIX0RFTElNSVRFRDoKKyAgICAgIGxlbmd0aF9kZWxpbWl0ZWRfLnN0cmluZ192YWx1ZV8gPSBuZXcgc3RyaW5nKAorICAgICAgICAgICpsZW5ndGhfZGVsaW1pdGVkXy5zdHJpbmdfdmFsdWVfKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgVW5rbm93bkZpZWxkOjpUWVBFX0dST1VQOiB7CisgICAgICBVbmtub3duRmllbGRTZXQqIGdyb3VwID0gbmV3IFVua25vd25GaWVsZFNldCgpOworICAgICAgZ3JvdXAtPkludGVybmFsTWVyZ2VGcm9tKCpncm91cF8pOworICAgICAgZ3JvdXBfID0gZ3JvdXA7CisgICAgICBicmVhazsKKyAgICB9CisgICAgZGVmYXVsdDoKKyAgICAgIGJyZWFrOworICB9Cit9CisKKwordm9pZCBVbmtub3duRmllbGQ6OlNlcmlhbGl6ZUxlbmd0aERlbGltaXRlZE5vVGFnKAorICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIEdPT0dMRV9EQ0hFQ0tfRVEoVFlQRV9MRU5HVEhfREVMSU1JVEVELCB0eXBlKCkpOworICBjb25zdCBzdHJpbmcmIGRhdGEgPSAqbGVuZ3RoX2RlbGltaXRlZF8uc3RyaW5nX3ZhbHVlXzsKKyAgb3V0cHV0LT5Xcml0ZVZhcmludDMyKGRhdGEuc2l6ZSgpKTsKKyAgb3V0cHV0LT5Xcml0ZVJhd01heWJlQWxpYXNlZChkYXRhLmRhdGEoKSwgZGF0YS5zaXplKCkpOworfQorCit1aW50OCogVW5rbm93bkZpZWxkOjpTZXJpYWxpemVMZW5ndGhEZWxpbWl0ZWROb1RhZ1RvQXJyYXkodWludDgqIHRhcmdldCkgY29uc3QgeworICBHT09HTEVfRENIRUNLX0VRKFRZUEVfTEVOR1RIX0RFTElNSVRFRCwgdHlwZSgpKTsKKyAgY29uc3Qgc3RyaW5nJiBkYXRhID0gKmxlbmd0aF9kZWxpbWl0ZWRfLnN0cmluZ192YWx1ZV87CisgIHRhcmdldCA9IGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVWYXJpbnQzMlRvQXJyYXkoZGF0YS5zaXplKCksIHRhcmdldCk7CisgIHRhcmdldCA9IGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVTdHJpbmdUb0FycmF5KGRhdGEsIHRhcmdldCk7CisgIHJldHVybiB0YXJnZXQ7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91bmtub3duX2ZpZWxkX3NldC5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91bmtub3duX2ZpZWxkX3NldC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYxMmE5NDIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Vua25vd25fZmllbGRfc2V0LmgKQEAgLTAsMCArMSwzNDAgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBDb250YWlucyBjbGFzc2VzIHVzZWQgdG8ga2VlcCB0cmFjayBvZiB1bnJlY29nbml6ZWQgZmllbGRzIHNlZW4gd2hpbGUKKy8vIHBhcnNpbmcgYSBwcm90b2NvbCBtZXNzYWdlLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9VTktOT1dOX0ZJRUxEX1NFVF9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1VOS05PV05fRklFTERfU0VUX0hfXworCisjaW5jbHVkZSA8YXNzZXJ0Lmg+CisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPHZlY3Rvcj4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2xvZ2dpbmcuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworICBuYW1lc3BhY2UgaW8geworICAgIGNsYXNzIENvZGVkSW5wdXRTdHJlYW07ICAgICAgICAgLy8gY29kZWRfc3RyZWFtLmgKKyAgICBjbGFzcyBDb2RlZE91dHB1dFN0cmVhbTsgICAgICAgIC8vIGNvZGVkX3N0cmVhbS5oCisgICAgY2xhc3MgWmVyb0NvcHlJbnB1dFN0cmVhbTsgICAgICAvLyB6ZXJvX2NvcHlfc3RyZWFtLmgKKyAgfQorICBuYW1lc3BhY2UgaW50ZXJuYWwgeworICAgIGNsYXNzIFdpcmVGb3JtYXQ7ICAgICAgICAgICAgICAgLy8gd2lyZV9mb3JtYXQuaAorICAgIGNsYXNzIE1lc3NhZ2VTZXRGaWVsZFNraXBwZXJVc2luZ0NvcmQ7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBleHRlbnNpb25fc2V0X2hlYXZ5LmNjCisgIH0KKworY2xhc3MgTWVzc2FnZTsgICAgICAgICAgICAgICAgICAgICAgLy8gbWVzc2FnZS5oCitjbGFzcyBVbmtub3duRmllbGQ7ICAgICAgICAgICAgICAgICAvLyBiZWxvdworCisvLyBBbiBVbmtub3duRmllbGRTZXQgY29udGFpbnMgZmllbGRzIHRoYXQgd2VyZSBlbmNvdW50ZXJlZCB3aGlsZSBwYXJzaW5nIGEKKy8vIG1lc3NhZ2UgYnV0IHdlcmUgbm90IGRlZmluZWQgYnkgaXRzIHR5cGUuICBLZWVwaW5nIHRyYWNrIG9mIHRoZXNlIGNhbiBiZQorLy8gdXNlZnVsLCBlc3BlY2lhbGx5IGluIHRoYXQgdGhleSBtYXkgYmUgd3JpdHRlbiBpZiB0aGUgbWVzc2FnZSBpcyBzZXJpYWxpemVkCisvLyBhZ2FpbiB3aXRob3V0IGJlaW5nIGNsZWFyZWQgaW4gYmV0d2Vlbi4gIFRoaXMgbWVhbnMgdGhhdCBzb2Z0d2FyZSB3aGljaAorLy8gc2ltcGx5IHJlY2VpdmVzIG1lc3NhZ2VzIGFuZCBmb3J3YXJkcyB0aGVtIHRvIG90aGVyIHNlcnZlcnMgZG9lcyBub3QgbmVlZAorLy8gdG8gYmUgdXBkYXRlZCBldmVyeSB0aW1lIGEgbmV3IGZpZWxkIGlzIGFkZGVkIHRvIHRoZSBtZXNzYWdlIGRlZmluaXRpb24uCisvLworLy8gVG8gZ2V0IHRoZSBVbmtub3duRmllbGRTZXQgYXR0YWNoZWQgdG8gYW55IG1lc3NhZ2UsIGNhbGwKKy8vIFJlZmxlY3Rpb246OkdldFVua25vd25GaWVsZHMoKS4KKy8vCisvLyBUaGlzIGNsYXNzIGlzIG5lY2Vzc2FyaWx5IHRpZWQgdG8gdGhlIHByb3RvY29sIGJ1ZmZlciB3aXJlIGZvcm1hdCwgdW5saWtlCisvLyB0aGUgUmVmbGVjdGlvbiBpbnRlcmZhY2Ugd2hpY2ggaXMgaW5kZXBlbmRlbnQgb2YgYW55IHNlcmlhbGl6YXRpb24gc2NoZW1lLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFVua25vd25GaWVsZFNldCB7CisgcHVibGljOgorICBVbmtub3duRmllbGRTZXQoKTsKKyAgflVua25vd25GaWVsZFNldCgpOworCisgIC8vIFJlbW92ZSBhbGwgZmllbGRzLgorICBpbmxpbmUgdm9pZCBDbGVhcigpOworCisgIC8vIFJlbW92ZSBhbGwgZmllbGRzIGFuZCBkZWFsbG9jYXRlIGludGVybmFsIGRhdGEgb2JqZWN0cworICB2b2lkIENsZWFyQW5kRnJlZU1lbW9yeSgpOworCisgIC8vIElzIHRoaXMgc2V0IGVtcHR5PworICBpbmxpbmUgYm9vbCBlbXB0eSgpIGNvbnN0OworCisgIC8vIE1lcmdlIHRoZSBjb250ZW50cyBvZiBzb21lIG90aGVyIFVua25vd25GaWVsZFNldCB3aXRoIHRoaXMgb25lLgorICB2b2lkIE1lcmdlRnJvbShjb25zdCBVbmtub3duRmllbGRTZXQmIG90aGVyKTsKKworICAvLyBTaW1pbGFyIHRvIGFib3ZlLCBidXQgdGhpcyBmdW5jdGlvbiB3aWxsIGRlc3Ryb3kgdGhlIGNvbnRlbnRzIG9mIG90aGVyLgorICB2b2lkIE1lcmdlRnJvbUFuZERlc3Ryb3koVW5rbm93bkZpZWxkU2V0KiBvdGhlcik7CisKKyAgLy8gU3dhcHMgdGhlIGNvbnRlbnRzIG9mIHNvbWUgb3RoZXIgVW5rbm93bkZpZWxkU2V0IHdpdGggdGhpcyBvbmUuCisgIGlubGluZSB2b2lkIFN3YXAoVW5rbm93bkZpZWxkU2V0KiB4KTsKKworICAvLyBDb21wdXRlcyAoYW4gZXN0aW1hdGUgb2YpIHRoZSB0b3RhbCBudW1iZXIgb2YgYnl0ZXMgY3VycmVudGx5IHVzZWQgZm9yCisgIC8vIHN0b3JpbmcgdGhlIHVua25vd24gZmllbGRzIGluIG1lbW9yeS4gRG9lcyBOT1QgaW5jbHVkZQorICAvLyBzaXplb2YoKnRoaXMpIGluIHRoZSBjYWxjdWxhdGlvbi4KKyAgaW50IFNwYWNlVXNlZEV4Y2x1ZGluZ1NlbGYoKSBjb25zdDsKKworICAvLyBWZXJzaW9uIG9mIFNwYWNlVXNlZCgpIGluY2x1ZGluZyBzaXplb2YoKnRoaXMpLgorICBpbnQgU3BhY2VVc2VkKCkgY29uc3Q7CisKKyAgLy8gUmV0dXJucyB0aGUgbnVtYmVyIG9mIGZpZWxkcyBwcmVzZW50IGluIHRoZSBVbmtub3duRmllbGRTZXQuCisgIGlubGluZSBpbnQgZmllbGRfY291bnQoKSBjb25zdDsKKyAgLy8gR2V0IGEgZmllbGQgaW4gdGhlIHNldCwgd2hlcmUgMCA8PSBpbmRleCA8IGZpZWxkX2NvdW50KCkuICBUaGUgZmllbGRzCisgIC8vIGFwcGVhciBpbiB0aGUgb3JkZXIgaW4gd2hpY2ggdGhleSB3ZXJlIGFkZGVkLgorICBpbmxpbmUgY29uc3QgVW5rbm93bkZpZWxkJiBmaWVsZChpbnQgaW5kZXgpIGNvbnN0OworICAvLyBHZXQgYSBtdXRhYmxlIHBvaW50ZXIgdG8gYSBmaWVsZCBpbiB0aGUgc2V0LCB3aGVyZQorICAvLyAwIDw9IGluZGV4IDwgZmllbGRfY291bnQoKS4gIFRoZSBmaWVsZHMgYXBwZWFyIGluIHRoZSBvcmRlciBpbiB3aGljaAorICAvLyB0aGV5IHdlcmUgYWRkZWQuCisgIGlubGluZSBVbmtub3duRmllbGQqIG11dGFibGVfZmllbGQoaW50IGluZGV4KTsKKworICAvLyBBZGRpbmcgZmllbGRzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIHZvaWQgQWRkVmFyaW50KGludCBudW1iZXIsIHVpbnQ2NCB2YWx1ZSk7CisgIHZvaWQgQWRkRml4ZWQzMihpbnQgbnVtYmVyLCB1aW50MzIgdmFsdWUpOworICB2b2lkIEFkZEZpeGVkNjQoaW50IG51bWJlciwgdWludDY0IHZhbHVlKTsKKyAgdm9pZCBBZGRMZW5ndGhEZWxpbWl0ZWQoaW50IG51bWJlciwgY29uc3Qgc3RyaW5nJiB2YWx1ZSk7CisgIHN0cmluZyogQWRkTGVuZ3RoRGVsaW1pdGVkKGludCBudW1iZXIpOworICBVbmtub3duRmllbGRTZXQqIEFkZEdyb3VwKGludCBudW1iZXIpOworCisgIC8vIEFkZHMgYW4gdW5rbm93biBmaWVsZCBmcm9tIGFub3RoZXIgc2V0LgorICB2b2lkIEFkZEZpZWxkKGNvbnN0IFVua25vd25GaWVsZCYgZmllbGQpOworCisgIC8vIERlbGV0ZSBmaWVsZHMgd2l0aCBpbmRpY2VzIGluIHRoZSByYW5nZSBbc3RhcnQgLi4gc3RhcnQrbnVtLTFdLgorICAvLyBDYXV0aW9uOiBpbXBsZW1lbnRhdGlvbiBtb3ZlcyBhbGwgZmllbGRzIHdpdGggaW5kaWNlcyBbc3RhcnQrbnVtIC4uIF0uCisgIHZvaWQgRGVsZXRlU3VicmFuZ2UoaW50IHN0YXJ0LCBpbnQgbnVtKTsKKworICAvLyBEZWxldGUgYWxsIGZpZWxkcyB3aXRoIGEgc3BlY2lmaWMgZmllbGQgbnVtYmVyLiBUaGUgb3JkZXIgb2YgbGVmdCBmaWVsZHMKKyAgLy8gaXMgcHJlc2VydmVkLgorICAvLyBDYXV0aW9uOiBpbXBsZW1lbnRhdGlvbiBtb3ZlcyBhbGwgZmllbGRzIGFmdGVyIHRoZSBmaXJzdCBkZWxldGVkIGZpZWxkLgorICB2b2lkIERlbGV0ZUJ5TnVtYmVyKGludCBudW1iZXIpOworCisgIC8vIFBhcnNpbmcgaGVscGVycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8vIFRoZXNlIHdvcmsgZXhhY3RseSBsaWtlIHRoZSBzaW1pbGFybHktbmFtZWQgbWV0aG9kcyBvZiBNZXNzYWdlLgorCisgIGJvb2wgTWVyZ2VGcm9tQ29kZWRTdHJlYW0oaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KTsKKyAgYm9vbCBQYXJzZUZyb21Db2RlZFN0cmVhbShpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpOworICBib29sIFBhcnNlRnJvbVplcm9Db3B5U3RyZWFtKGlvOjpaZXJvQ29weUlucHV0U3RyZWFtKiBpbnB1dCk7CisgIGJvb2wgUGFyc2VGcm9tQXJyYXkoY29uc3Qgdm9pZCogZGF0YSwgaW50IHNpemUpOworICBpbmxpbmUgYm9vbCBQYXJzZUZyb21TdHJpbmcoY29uc3Qgc3RyaW5nJiBkYXRhKSB7CisgICAgcmV0dXJuIFBhcnNlRnJvbUFycmF5KGRhdGEuZGF0YSgpLCBzdGF0aWNfY2FzdDxpbnQ+KGRhdGEuc2l6ZSgpKSk7CisgIH0KKworICBzdGF0aWMgY29uc3QgVW5rbm93bkZpZWxkU2V0KiBkZWZhdWx0X2luc3RhbmNlKCk7CisgcHJpdmF0ZToKKyAgLy8gRm9yIEludGVybmFsTWVyZ2VGcm9tCisgIGZyaWVuZCBjbGFzcyBVbmtub3duRmllbGQ7CisgIC8vIE1lcmdlcyBmcm9tIG90aGVyIFVua25vd25GaWVsZFNldC4gVGhpcyBtZXRob2QgYXNzdW1lcywgdGhhdCB0aGlzIG9iamVjdAorICAvLyBpcyBuZXdseSBjcmVhdGVkIGFuZCBoYXMgZmllbGRzXyA9PSBOVUxMOworICB2b2lkIEludGVybmFsTWVyZ2VGcm9tKGNvbnN0IFVua25vd25GaWVsZFNldCYgb3RoZXIpOworICB2b2lkIENsZWFyRmFsbGJhY2soKTsKKworICAvLyBmaWVsZHNfIGlzIGVpdGhlciBOVUxMLCBvciBhIHBvaW50ZXIgdG8gYSB2ZWN0b3IgdGhhdCBpcyAqbm9uLWVtcHR5Ki4gV2UKKyAgLy8gbmV2ZXIgaG9sZCB0aGUgZW1wdHkgdmVjdG9yIGJlY2F1c2Ugd2Ugd2FudCB0aGUgJ2RvIHdlIGhhdmUgYW55IHVua25vd24KKyAgLy8gZmllbGRzJyBjaGVjayB0byBiZSBmYXN0LCBhbmQgYXZvaWQgYSBjYWNoZSBtaXNzOiB0aGUgVUZTIGluc3RhbmNlIGdldHMKKyAgLy8gZW1iZWRkZWQgaW4gdGhlIG1lc3NhZ2Ugb2JqZWN0LCBzbyAnZmllbGRzXyAhPSBOVUxMJyB0ZXN0cyBhIG1lbWJlcgorICAvLyB2YXJpYWJsZSBob3QgaW4gdGhlIGNhY2hlLCB3aXRob3V0IHRoZSBuZWVkIHRvIGdvIHRvdWNoIGEgdmVjdG9yIHNvbWV3aGVyZQorICAvLyBlbHNlIGluIG1lbW9yeS4KKyAgc3RkOjp2ZWN0b3I8VW5rbm93bkZpZWxkPiogZmllbGRzXzsKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFVua25vd25GaWVsZFNldCk7Cit9OworCisvLyBSZXByZXNlbnRzIG9uZSBmaWVsZCBpbiBhbiBVbmtub3duRmllbGRTZXQuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgVW5rbm93bkZpZWxkIHsKKyBwdWJsaWM6CisgIGVudW0gVHlwZSB7CisgICAgVFlQRV9WQVJJTlQsCisgICAgVFlQRV9GSVhFRDMyLAorICAgIFRZUEVfRklYRUQ2NCwKKyAgICBUWVBFX0xFTkdUSF9ERUxJTUlURUQsCisgICAgVFlQRV9HUk9VUAorICB9OworCisgIC8vIFRoZSBmaWVsZCdzIHRhZyBudW1iZXIsIGFzIHNlZW4gb24gdGhlIHdpcmUuCisgIGlubGluZSBpbnQgbnVtYmVyKCkgY29uc3Q7CisKKyAgLy8gVGhlIGZpZWxkIHR5cGUuCisgIGlubGluZSBUeXBlIHR5cGUoKSBjb25zdDsKKworICAvLyBBY2Nlc3NvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAvLyBFYWNoIG1ldGhvZCB3b3JrcyBvbmx5IGZvciBVbmtub3duRmllbGRzIG9mIHRoZSBjb3JyZXNwb25kaW5nIHR5cGUuCisKKyAgaW5saW5lIHVpbnQ2NCB2YXJpbnQoKSBjb25zdDsKKyAgaW5saW5lIHVpbnQzMiBmaXhlZDMyKCkgY29uc3Q7CisgIGlubGluZSB1aW50NjQgZml4ZWQ2NCgpIGNvbnN0OworICBpbmxpbmUgY29uc3Qgc3RyaW5nJiBsZW5ndGhfZGVsaW1pdGVkKCkgY29uc3Q7CisgIGlubGluZSBjb25zdCBVbmtub3duRmllbGRTZXQmIGdyb3VwKCkgY29uc3Q7CisKKyAgaW5saW5lIHZvaWQgc2V0X3ZhcmludCh1aW50NjQgdmFsdWUpOworICBpbmxpbmUgdm9pZCBzZXRfZml4ZWQzMih1aW50MzIgdmFsdWUpOworICBpbmxpbmUgdm9pZCBzZXRfZml4ZWQ2NCh1aW50NjQgdmFsdWUpOworICBpbmxpbmUgdm9pZCBzZXRfbGVuZ3RoX2RlbGltaXRlZChjb25zdCBzdHJpbmcmIHZhbHVlKTsKKyAgaW5saW5lIHN0cmluZyogbXV0YWJsZV9sZW5ndGhfZGVsaW1pdGVkKCk7CisgIGlubGluZSBVbmtub3duRmllbGRTZXQqIG11dGFibGVfZ3JvdXAoKTsKKworICAvLyBTZXJpYWxpemF0aW9uIEFQSS4KKyAgLy8gVGhlc2UgbWV0aG9kcyBjYW4gdGFrZSBhZHZhbnRhZ2Ugb2YgdGhlIHVuZGVybHlpbmcgaW1wbGVtZW50YXRpb24gYW5kIG1heQorICAvLyBhcmNoaWV2ZSBhIGJldHRlciBwZXJmb3JtYW5jZSB0aGFuIHVzaW5nIGdldHRlcnMgdG8gcmV0cmlldmUgdGhlIGRhdGEgYW5kCisgIC8vIGRvIHRoZSBzZXJpYWxpemF0aW9uIHlvdXJzZWxmLgorICB2b2lkIFNlcmlhbGl6ZUxlbmd0aERlbGltaXRlZE5vVGFnKGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgdWludDgqIFNlcmlhbGl6ZUxlbmd0aERlbGltaXRlZE5vVGFnVG9BcnJheSh1aW50OCogdGFyZ2V0KSBjb25zdDsKKworICBpbmxpbmUgaW50IEdldExlbmd0aERlbGltaXRlZFNpemUoKSBjb25zdDsKKworIHByaXZhdGU6CisgIGZyaWVuZCBjbGFzcyBVbmtub3duRmllbGRTZXQ7CisKKyAgLy8gSWYgdGhpcyBVbmtub3duRmllbGQgY29udGFpbnMgYSBwb2ludGVyLCBkZWxldGUgaXQuCisgIHZvaWQgRGVsZXRlKCk7CisKKyAgLy8gUmVzZXQgYWxsIHRoZSB1bmRlcmx5aW5nIHBvaW50ZXJzIHRvIE5VTEwuIEEgc3BlY2lhbCBmdW5jdGlvbiB0byBiZSBvbmx5CisgIC8vIHVzZWQgd2hpbGUgbWVyZ2luZyBmcm9tIGEgdGVtcG9yYXJ5IFVGUy4KKyAgdm9pZCBSZXNldCgpOworCisgIC8vIE1ha2UgYSBkZWVwIGNvcHkgb2YgYW55IHBvaW50ZXJzIGluIHRoaXMgVW5rbm93bkZpZWxkLgorICB2b2lkIERlZXBDb3B5KGNvbnN0IFVua25vd25GaWVsZCYgb3RoZXIpOworCisgIC8vIFNldCB0aGUgd2lyZSB0eXBlIG9mIHRoaXMgVW5rbm93bkZpZWxkLiBTaG91bGQgb25seSBiZSB1c2VkIHdoZW4gdGhpcworICAvLyBVbmtub3duRmllbGQgaXMgYmVpbmcgY3JlYXRlZC4KKyAgaW5saW5lIHZvaWQgU2V0VHlwZShUeXBlIHR5cGUpOworCisgIHVuaW9uIExlbmd0aERlbGltaXRlZCB7CisgICAgc3RyaW5nKiBzdHJpbmdfdmFsdWVfOworICB9OworCisgIHVpbnQzMiBudW1iZXJfOworICB1aW50MzIgdHlwZV87CisgIHVuaW9uIHsKKyAgICB1aW50NjQgdmFyaW50XzsKKyAgICB1aW50MzIgZml4ZWQzMl87CisgICAgdWludDY0IGZpeGVkNjRfOworICAgIG11dGFibGUgdW5pb24gTGVuZ3RoRGVsaW1pdGVkIGxlbmd0aF9kZWxpbWl0ZWRfOworICAgIFVua25vd25GaWVsZFNldCogZ3JvdXBfOworICB9OworfTsKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorLy8gaW5saW5lIGltcGxlbWVudGF0aW9ucworCitpbmxpbmUgdm9pZCBVbmtub3duRmllbGRTZXQ6OkNsZWFyKCkgeworICBpZiAoZmllbGRzXykgeworICAgIENsZWFyRmFsbGJhY2soKTsKKyAgfQorfQorCitpbmxpbmUgYm9vbCBVbmtub3duRmllbGRTZXQ6OmVtcHR5KCkgY29uc3QgeworICAvLyBJbnZhcmlhbnQ6IGZpZWxkc18gaXMgbmV2ZXIgZW1wdHkgaWYgcHJlc2VudC4KKyAgcmV0dXJuICFmaWVsZHNfOworfQorCitpbmxpbmUgdm9pZCBVbmtub3duRmllbGRTZXQ6OlN3YXAoVW5rbm93bkZpZWxkU2V0KiB4KSB7CisgIHN0ZDo6c3dhcChmaWVsZHNfLCB4LT5maWVsZHNfKTsKK30KKworaW5saW5lIGludCBVbmtub3duRmllbGRTZXQ6OmZpZWxkX2NvdW50KCkgY29uc3QgeworICByZXR1cm4gZmllbGRzXyA/IHN0YXRpY19jYXN0PGludD4oZmllbGRzXy0+c2l6ZSgpKSA6IDA7Cit9CitpbmxpbmUgY29uc3QgVW5rbm93bkZpZWxkJiBVbmtub3duRmllbGRTZXQ6OmZpZWxkKGludCBpbmRleCkgY29uc3QgeworICBHT09HTEVfRENIRUNLKGZpZWxkc18gIT0gTlVMTCk7CisgIHJldHVybiAoKmZpZWxkc18pW2luZGV4XTsKK30KK2lubGluZSBVbmtub3duRmllbGQqIFVua25vd25GaWVsZFNldDo6bXV0YWJsZV9maWVsZChpbnQgaW5kZXgpIHsKKyAgcmV0dXJuICYoKmZpZWxkc18pW2luZGV4XTsKK30KKworaW5saW5lIHZvaWQgVW5rbm93bkZpZWxkU2V0OjpBZGRMZW5ndGhEZWxpbWl0ZWQoCisgICAgaW50IG51bWJlciwgY29uc3Qgc3RyaW5nJiB2YWx1ZSkgeworICBBZGRMZW5ndGhEZWxpbWl0ZWQobnVtYmVyKS0+YXNzaWduKHZhbHVlKTsKK30KKworCitpbmxpbmUgaW50IFVua25vd25GaWVsZDo6bnVtYmVyKCkgY29uc3QgeyByZXR1cm4gbnVtYmVyXzsgfQoraW5saW5lIFVua25vd25GaWVsZDo6VHlwZSBVbmtub3duRmllbGQ6OnR5cGUoKSBjb25zdCB7CisgIHJldHVybiBzdGF0aWNfY2FzdDxUeXBlPih0eXBlXyk7Cit9CisKK2lubGluZSB1aW50NjQgVW5rbm93bkZpZWxkOjp2YXJpbnQoKSBjb25zdCB7CisgIGFzc2VydCh0eXBlKCkgPT0gVFlQRV9WQVJJTlQpOworICByZXR1cm4gdmFyaW50XzsKK30KK2lubGluZSB1aW50MzIgVW5rbm93bkZpZWxkOjpmaXhlZDMyKCkgY29uc3QgeworICBhc3NlcnQodHlwZSgpID09IFRZUEVfRklYRUQzMik7CisgIHJldHVybiBmaXhlZDMyXzsKK30KK2lubGluZSB1aW50NjQgVW5rbm93bkZpZWxkOjpmaXhlZDY0KCkgY29uc3QgeworICBhc3NlcnQodHlwZSgpID09IFRZUEVfRklYRUQ2NCk7CisgIHJldHVybiBmaXhlZDY0XzsKK30KK2lubGluZSBjb25zdCBzdHJpbmcmIFVua25vd25GaWVsZDo6bGVuZ3RoX2RlbGltaXRlZCgpIGNvbnN0IHsKKyAgYXNzZXJ0KHR5cGUoKSA9PSBUWVBFX0xFTkdUSF9ERUxJTUlURUQpOworICByZXR1cm4gKmxlbmd0aF9kZWxpbWl0ZWRfLnN0cmluZ192YWx1ZV87Cit9CitpbmxpbmUgY29uc3QgVW5rbm93bkZpZWxkU2V0JiBVbmtub3duRmllbGQ6Omdyb3VwKCkgY29uc3QgeworICBhc3NlcnQodHlwZSgpID09IFRZUEVfR1JPVVApOworICByZXR1cm4gKmdyb3VwXzsKK30KKworaW5saW5lIHZvaWQgVW5rbm93bkZpZWxkOjpzZXRfdmFyaW50KHVpbnQ2NCB2YWx1ZSkgeworICBhc3NlcnQodHlwZSgpID09IFRZUEVfVkFSSU5UKTsKKyAgdmFyaW50XyA9IHZhbHVlOworfQoraW5saW5lIHZvaWQgVW5rbm93bkZpZWxkOjpzZXRfZml4ZWQzMih1aW50MzIgdmFsdWUpIHsKKyAgYXNzZXJ0KHR5cGUoKSA9PSBUWVBFX0ZJWEVEMzIpOworICBmaXhlZDMyXyA9IHZhbHVlOworfQoraW5saW5lIHZvaWQgVW5rbm93bkZpZWxkOjpzZXRfZml4ZWQ2NCh1aW50NjQgdmFsdWUpIHsKKyAgYXNzZXJ0KHR5cGUoKSA9PSBUWVBFX0ZJWEVENjQpOworICBmaXhlZDY0XyA9IHZhbHVlOworfQoraW5saW5lIHZvaWQgVW5rbm93bkZpZWxkOjpzZXRfbGVuZ3RoX2RlbGltaXRlZChjb25zdCBzdHJpbmcmIHZhbHVlKSB7CisgIGFzc2VydCh0eXBlKCkgPT0gVFlQRV9MRU5HVEhfREVMSU1JVEVEKTsKKyAgbGVuZ3RoX2RlbGltaXRlZF8uc3RyaW5nX3ZhbHVlXy0+YXNzaWduKHZhbHVlKTsKK30KK2lubGluZSBzdHJpbmcqIFVua25vd25GaWVsZDo6bXV0YWJsZV9sZW5ndGhfZGVsaW1pdGVkKCkgeworICBhc3NlcnQodHlwZSgpID09IFRZUEVfTEVOR1RIX0RFTElNSVRFRCk7CisgIHJldHVybiBsZW5ndGhfZGVsaW1pdGVkXy5zdHJpbmdfdmFsdWVfOworfQoraW5saW5lIFVua25vd25GaWVsZFNldCogVW5rbm93bkZpZWxkOjptdXRhYmxlX2dyb3VwKCkgeworICBhc3NlcnQodHlwZSgpID09IFRZUEVfR1JPVVApOworICByZXR1cm4gZ3JvdXBfOworfQorCitpbmxpbmUgaW50IFVua25vd25GaWVsZDo6R2V0TGVuZ3RoRGVsaW1pdGVkU2l6ZSgpIGNvbnN0IHsKKyAgR09PR0xFX0RDSEVDS19FUShUWVBFX0xFTkdUSF9ERUxJTUlURUQsIHR5cGUoKSk7CisgIHJldHVybiBzdGF0aWNfY2FzdDxpbnQ+KGxlbmd0aF9kZWxpbWl0ZWRfLnN0cmluZ192YWx1ZV8tPnNpemUoKSk7Cit9CisKK2lubGluZSB2b2lkIFVua25vd25GaWVsZDo6U2V0VHlwZShUeXBlIHR5cGUpIHsKKyAgdHlwZV8gPSB0eXBlOworfQorCisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9VTktOT1dOX0ZJRUxEX1NFVF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdW5rbm93bl9maWVsZF9zZXRfdW5pdHRlc3QuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Vua25vd25fZmllbGRfc2V0X3VuaXR0ZXN0LmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVkZTcyNjMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3Vua25vd25fZmllbGRfc2V0X3VuaXR0ZXN0LmNjCkBAIC0wLDAgKzEsNjA5IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisvLworLy8gVGhpcyB0ZXN0IGlzIHRlc3RpbmcgYSBsb3QgbW9yZSB0aGFuIGp1c3QgdGhlIFVua25vd25GaWVsZFNldCBjbGFzcy4gIEl0CisvLyB0ZXN0cyBoYW5kbGluZyBvZiB1bmtub3duIGZpZWxkcyB0aHJvdWdob3V0IHRoZSBzeXN0ZW0uCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdW5rbm93bl9maWVsZF9zZXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbV9pbXBsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RfdXRpbC5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NhbGxiYWNrLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9sb2dnaW5nLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL211dGV4Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvZ29vZ2xldGVzdC5oPgorI2luY2x1ZGUgPGd0ZXN0L2d0ZXN0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0bF91dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKwordXNpbmcgaW50ZXJuYWw6OldpcmVGb3JtYXQ7CisKK2NsYXNzIFVua25vd25GaWVsZFNldFRlc3QgOiBwdWJsaWMgdGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICB2aXJ0dWFsIHZvaWQgU2V0VXAoKSB7CisgICAgZGVzY3JpcHRvcl8gPSB1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpkZXNjcmlwdG9yKCk7CisgICAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmYWxsX2ZpZWxkc18pOworICAgIGFsbF9maWVsZHNfLlNlcmlhbGl6ZVRvU3RyaW5nKCZhbGxfZmllbGRzX2RhdGFfKTsKKyAgICBBU1NFUlRfVFJVRShlbXB0eV9tZXNzYWdlXy5QYXJzZUZyb21TdHJpbmcoYWxsX2ZpZWxkc19kYXRhXykpOworICAgIHVua25vd25fZmllbGRzXyA9IGVtcHR5X21lc3NhZ2VfLm11dGFibGVfdW5rbm93bl9maWVsZHMoKTsKKyAgfQorCisgIGNvbnN0IFVua25vd25GaWVsZCogR2V0RmllbGQoY29uc3Qgc3RyaW5nJiBuYW1lKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3JfLT5GaW5kRmllbGRCeU5hbWUobmFtZSk7CisgICAgaWYgKGZpZWxkID09IE5VTEwpIHJldHVybiBOVUxMOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdW5rbm93bl9maWVsZHNfLT5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICAgIGlmICh1bmtub3duX2ZpZWxkc18tPmZpZWxkKGkpLm51bWJlcigpID09IGZpZWxkLT5udW1iZXIoKSkgeworICAgICAgICByZXR1cm4gJnVua25vd25fZmllbGRzXy0+ZmllbGQoaSk7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBOVUxMOworICB9CisKKyAgLy8gQ29uc3RydWN0cyBhIHByb3RvY29sIGJ1ZmZlciB3aGljaCBjb250YWlucyBmaWVsZHMgd2l0aCBhbGwgdGhlIHNhbWUKKyAgLy8gbnVtYmVycyBhcyBhbGxfZmllbGRzX2RhdGFfIGV4Y2VwdCB0aGF0IGVhY2ggZmllbGQgaXMgc29tZSBvdGhlciB3aXJlCisgIC8vIHR5cGUuCisgIHN0cmluZyBHZXRCaXphcnJvRGF0YSgpIHsKKyAgICB1bml0dGVzdDo6VGVzdEVtcHR5TWVzc2FnZSBiaXphcnJvX21lc3NhZ2U7CisgICAgVW5rbm93bkZpZWxkU2V0KiBiaXphcnJvX3Vua25vd25fZmllbGRzID0KKyAgICAgIGJpemFycm9fbWVzc2FnZS5tdXRhYmxlX3Vua25vd25fZmllbGRzKCk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB1bmtub3duX2ZpZWxkc18tPmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgICAgY29uc3QgVW5rbm93bkZpZWxkJiB1bmtub3duX2ZpZWxkID0gdW5rbm93bl9maWVsZHNfLT5maWVsZChpKTsKKyAgICAgIGlmICh1bmtub3duX2ZpZWxkLnR5cGUoKSA9PSBVbmtub3duRmllbGQ6OlRZUEVfVkFSSU5UKSB7CisgICAgICAgIGJpemFycm9fdW5rbm93bl9maWVsZHMtPkFkZEZpeGVkMzIodW5rbm93bl9maWVsZC5udW1iZXIoKSwgMSk7CisgICAgICB9IGVsc2UgeworICAgICAgICBiaXphcnJvX3Vua25vd25fZmllbGRzLT5BZGRWYXJpbnQodW5rbm93bl9maWVsZC5udW1iZXIoKSwgMSk7CisgICAgICB9CisgICAgfQorCisgICAgc3RyaW5nIGRhdGE7CisgICAgRVhQRUNUX1RSVUUoYml6YXJyb19tZXNzYWdlLlNlcmlhbGl6ZVRvU3RyaW5nKCZkYXRhKSk7CisgICAgcmV0dXJuIGRhdGE7CisgIH0KKworICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yXzsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBhbGxfZmllbGRzXzsKKyAgc3RyaW5nIGFsbF9maWVsZHNfZGF0YV87CisKKyAgLy8gQW4gZW1wdHkgbWVzc2FnZSB0aGF0IGhhcyBiZWVuIHBhcnNlZCBmcm9tIGFsbF9maWVsZHNfZGF0YV8uICBTbywgaXQgaGFzCisgIC8vIHVua25vd24gZmllbGRzIG9mIGV2ZXJ5IHR5cGUuCisgIHVuaXR0ZXN0OjpUZXN0RW1wdHlNZXNzYWdlIGVtcHR5X21lc3NhZ2VfOworICBVbmtub3duRmllbGRTZXQqIHVua25vd25fZmllbGRzXzsKK307CisKK25hbWVzcGFjZSB7CisKK1RFU1RfRihVbmtub3duRmllbGRTZXRUZXN0LCBBbGxGaWVsZHNQcmVzZW50KSB7CisgIC8vIEFsbCBmaWVsZHMgb2YgVGVzdEFsbFR5cGVzIHNob3VsZCBiZSBwcmVzZW50LCBpbiBudW1lcmljIG9yZGVyIChiZWNhdXNlCisgIC8vIHRoYXQncyB0aGUgb3JkZXIgd2UgcGFyc2VkIHRoZW0gaW4pLiAgRmllbGRzIHRoYXQgYXJlIG5vdCB2YWxpZCBmaWVsZAorICAvLyBudW1iZXJzIG9mIFRlc3RBbGxUeXBlcyBzaG91bGQgTk9UIGJlIHByZXNlbnQuCisKKyAgaW50IHBvcyA9IDA7CisKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDAwOyBpKyspIHsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvcl8tPkZpbmRGaWVsZEJ5TnVtYmVyKGkpOworICAgIGlmIChmaWVsZCAhPSBOVUxMKSB7CisgICAgICBBU1NFUlRfTFQocG9zLCB1bmtub3duX2ZpZWxkc18tPmZpZWxkX2NvdW50KCkpOworICAgICAgLy8gRG8gbm90IGNoZWNrIG9uZW9mIGZpZWxkIGlmIGl0IGlzIG5vdCBzZXQuCisgICAgICBpZiAoZmllbGQtPmNvbnRhaW5pbmdfb25lb2YoKSA9PSBOVUxMKSB7CisgICAgICAgIEVYUEVDVF9FUShpLCB1bmtub3duX2ZpZWxkc18tPmZpZWxkKHBvcysrKS5udW1iZXIoKSk7CisgICAgICB9IGVsc2UgaWYgKGkgPT0gdW5rbm93bl9maWVsZHNfLT5maWVsZChwb3MpLm51bWJlcigpKSB7CisgICAgICAgIHBvcysrOworICAgICAgfQorICAgICAgaWYgKGZpZWxkLT5pc19yZXBlYXRlZCgpKSB7CisgICAgICAgIC8vIFNob3VsZCBoYXZlIGEgc2Vjb25kIGluc3RhbmNlLgorICAgICAgICBBU1NFUlRfTFQocG9zLCB1bmtub3duX2ZpZWxkc18tPmZpZWxkX2NvdW50KCkpOworICAgICAgICBFWFBFQ1RfRVEoaSwgdW5rbm93bl9maWVsZHNfLT5maWVsZChwb3MrKykubnVtYmVyKCkpOworICAgICAgfQorICAgIH0KKyAgfQorICBFWFBFQ1RfRVEodW5rbm93bl9maWVsZHNfLT5maWVsZF9jb3VudCgpLCBwb3MpOworfQorCitURVNUX0YoVW5rbm93bkZpZWxkU2V0VGVzdCwgVmFyaW50KSB7CisgIGNvbnN0IFVua25vd25GaWVsZCogZmllbGQgPSBHZXRGaWVsZCgib3B0aW9uYWxfaW50MzIiKTsKKyAgQVNTRVJUX1RSVUUoZmllbGQgIT0gTlVMTCk7CisKKyAgQVNTRVJUX0VRKFVua25vd25GaWVsZDo6VFlQRV9WQVJJTlQsIGZpZWxkLT50eXBlKCkpOworICBFWFBFQ1RfRVEoYWxsX2ZpZWxkc18ub3B0aW9uYWxfaW50MzIoKSwgZmllbGQtPnZhcmludCgpKTsKK30KKworVEVTVF9GKFVua25vd25GaWVsZFNldFRlc3QsIEZpeGVkMzIpIHsKKyAgY29uc3QgVW5rbm93bkZpZWxkKiBmaWVsZCA9IEdldEZpZWxkKCJvcHRpb25hbF9maXhlZDMyIik7CisgIEFTU0VSVF9UUlVFKGZpZWxkICE9IE5VTEwpOworCisgIEFTU0VSVF9FUShVbmtub3duRmllbGQ6OlRZUEVfRklYRUQzMiwgZmllbGQtPnR5cGUoKSk7CisgIEVYUEVDVF9FUShhbGxfZmllbGRzXy5vcHRpb25hbF9maXhlZDMyKCksIGZpZWxkLT5maXhlZDMyKCkpOworfQorCitURVNUX0YoVW5rbm93bkZpZWxkU2V0VGVzdCwgRml4ZWQ2NCkgeworICBjb25zdCBVbmtub3duRmllbGQqIGZpZWxkID0gR2V0RmllbGQoIm9wdGlvbmFsX2ZpeGVkNjQiKTsKKyAgQVNTRVJUX1RSVUUoZmllbGQgIT0gTlVMTCk7CisKKyAgQVNTRVJUX0VRKFVua25vd25GaWVsZDo6VFlQRV9GSVhFRDY0LCBmaWVsZC0+dHlwZSgpKTsKKyAgRVhQRUNUX0VRKGFsbF9maWVsZHNfLm9wdGlvbmFsX2ZpeGVkNjQoKSwgZmllbGQtPmZpeGVkNjQoKSk7Cit9CisKK1RFU1RfRihVbmtub3duRmllbGRTZXRUZXN0LCBMZW5ndGhEZWxpbWl0ZWQpIHsKKyAgY29uc3QgVW5rbm93bkZpZWxkKiBmaWVsZCA9IEdldEZpZWxkKCJvcHRpb25hbF9zdHJpbmciKTsKKyAgQVNTRVJUX1RSVUUoZmllbGQgIT0gTlVMTCk7CisKKyAgQVNTRVJUX0VRKFVua25vd25GaWVsZDo6VFlQRV9MRU5HVEhfREVMSU1JVEVELCBmaWVsZC0+dHlwZSgpKTsKKyAgRVhQRUNUX0VRKGFsbF9maWVsZHNfLm9wdGlvbmFsX3N0cmluZygpLCBmaWVsZC0+bGVuZ3RoX2RlbGltaXRlZCgpKTsKK30KKworVEVTVF9GKFVua25vd25GaWVsZFNldFRlc3QsIEdyb3VwKSB7CisgIGNvbnN0IFVua25vd25GaWVsZCogZmllbGQgPSBHZXRGaWVsZCgib3B0aW9uYWxncm91cCIpOworICBBU1NFUlRfVFJVRShmaWVsZCAhPSBOVUxMKTsKKworICBBU1NFUlRfRVEoVW5rbm93bkZpZWxkOjpUWVBFX0dST1VQLCBmaWVsZC0+dHlwZSgpKTsKKyAgQVNTRVJUX0VRKDEsIGZpZWxkLT5ncm91cCgpLmZpZWxkX2NvdW50KCkpOworCisgIGNvbnN0IFVua25vd25GaWVsZCYgbmVzdGVkX2ZpZWxkID0gZmllbGQtPmdyb3VwKCkuZmllbGQoMCk7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogbmVzdGVkX2ZpZWxkX2Rlc2NyaXB0b3IgPQorICAgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok9wdGlvbmFsR3JvdXA6OmRlc2NyaXB0b3IoKS0+RmluZEZpZWxkQnlOYW1lKCJhIik7CisgIEFTU0VSVF9UUlVFKG5lc3RlZF9maWVsZF9kZXNjcmlwdG9yICE9IE5VTEwpOworCisgIEVYUEVDVF9FUShuZXN0ZWRfZmllbGRfZGVzY3JpcHRvci0+bnVtYmVyKCksIG5lc3RlZF9maWVsZC5udW1iZXIoKSk7CisgIEFTU0VSVF9FUShVbmtub3duRmllbGQ6OlRZUEVfVkFSSU5ULCBuZXN0ZWRfZmllbGQudHlwZSgpKTsKKyAgRVhQRUNUX0VRKGFsbF9maWVsZHNfLm9wdGlvbmFsZ3JvdXAoKS5hKCksIG5lc3RlZF9maWVsZC52YXJpbnQoKSk7Cit9CisKK1RFU1RfRihVbmtub3duRmllbGRTZXRUZXN0LCBTZXJpYWxpemVGYXN0QW5kU2xvd0FyZUVxdWl2YWxlbnQpIHsKKyAgaW50IHNpemUgPSBXaXJlRm9ybWF0OjpDb21wdXRlVW5rbm93bkZpZWxkc1NpemUoCisgICAgICBlbXB0eV9tZXNzYWdlXy51bmtub3duX2ZpZWxkcygpKTsKKyAgc3RyaW5nIHNsb3dfYnVmZmVyOworICBzdHJpbmcgZmFzdF9idWZmZXI7CisgIHNsb3dfYnVmZmVyLnJlc2l6ZShzaXplKTsKKyAgZmFzdF9idWZmZXIucmVzaXplKHNpemUpOworCisgIHVpbnQ4KiB0YXJnZXQgPSByZWludGVycHJldF9jYXN0PHVpbnQ4Kj4oc3RyaW5nX2FzX2FycmF5KCZmYXN0X2J1ZmZlcikpOworICB1aW50OCogcmVzdWx0ID0gV2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bkZpZWxkc1RvQXJyYXkoCisgICAgICAgICAgZW1wdHlfbWVzc2FnZV8udW5rbm93bl9maWVsZHMoKSwgdGFyZ2V0KTsKKyAgRVhQRUNUX0VRKHNpemUsIHJlc3VsdCAtIHRhcmdldCk7CisKKyAgeworICAgIGlvOjpBcnJheU91dHB1dFN0cmVhbSByYXdfc3RyZWFtKHN0cmluZ19hc19hcnJheSgmc2xvd19idWZmZXIpLCBzaXplLCAxKTsKKyAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0X3N0cmVhbSgmcmF3X3N0cmVhbSk7CisgICAgV2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bkZpZWxkcyhlbXB0eV9tZXNzYWdlXy51bmtub3duX2ZpZWxkcygpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJm91dHB1dF9zdHJlYW0pOworICAgIEFTU0VSVF9GQUxTRShvdXRwdXRfc3RyZWFtLkhhZEVycm9yKCkpOworICB9CisgIEVYUEVDVF9UUlVFKGZhc3RfYnVmZmVyID09IHNsb3dfYnVmZmVyKTsKK30KKworVEVTVF9GKFVua25vd25GaWVsZFNldFRlc3QsIFNlcmlhbGl6ZSkgeworICAvLyBDaGVjayB0aGF0IHNlcmlhbGl6aW5nIHRoZSBVbmtub3duRmllbGRTZXQgcHJvZHVjZXMgdGhlIG9yaWdpbmFsIGRhdGEKKyAgLy8gYWdhaW4uCisKKyAgc3RyaW5nIGRhdGE7CisgIGVtcHR5X21lc3NhZ2VfLlNlcmlhbGl6ZVRvU3RyaW5nKCZkYXRhKTsKKworICAvLyBEb24ndCB1c2UgRVhQRUNUX0VRIGJlY2F1c2Ugd2UgZG9uJ3Qgd2FudCB0byBkdW1wIHJhdyBiaW5hcnkgZGF0YSB0bworICAvLyBzdGRvdXQuCisgIEVYUEVDVF9UUlVFKGRhdGEgPT0gYWxsX2ZpZWxkc19kYXRhXyk7Cit9CisKK1RFU1RfRihVbmtub3duRmllbGRTZXRUZXN0LCBQYXJzZVZpYVJlZmxlY3Rpb24pIHsKKyAgLy8gTWFrZSBzdXJlIGZpZWxkcyBhcmUgcHJvcGVybHkgcGFyc2VkIHRvIHRoZSBVbmtub3duRmllbGRTZXQgd2hlbiBwYXJzaW5nCisgIC8vIHZpYSByZWZsZWN0aW9uLgorCisgIHVuaXR0ZXN0OjpUZXN0RW1wdHlNZXNzYWdlIG1lc3NhZ2U7CisgIGlvOjpBcnJheUlucHV0U3RyZWFtIHJhd19pbnB1dChhbGxfZmllbGRzX2RhdGFfLmRhdGEoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsbF9maWVsZHNfZGF0YV8uc2l6ZSgpKTsKKyAgaW86OkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQoJnJhd19pbnB1dCk7CisgIEFTU0VSVF9UUlVFKFdpcmVGb3JtYXQ6OlBhcnNlQW5kTWVyZ2VQYXJ0aWFsKCZpbnB1dCwgJm1lc3NhZ2UpKTsKKworICBFWFBFQ1RfRVEobWVzc2FnZS5EZWJ1Z1N0cmluZygpLCBlbXB0eV9tZXNzYWdlXy5EZWJ1Z1N0cmluZygpKTsKK30KKworVEVTVF9GKFVua25vd25GaWVsZFNldFRlc3QsIFNlcmlhbGl6ZVZpYVJlZmxlY3Rpb24pIHsKKyAgLy8gTWFrZSBzdXJlIGZpZWxkcyBhcmUgcHJvcGVybHkgd3JpdHRlbiBmcm9tIHRoZSBVbmtub3duRmllbGRTZXQgd2hlbgorICAvLyBzZXJpYWxpemluZyB2aWEgcmVmbGVjdGlvbi4KKworICBzdHJpbmcgZGF0YTsKKworICB7CisgICAgaW86OlN0cmluZ091dHB1dFN0cmVhbSByYXdfb3V0cHV0KCZkYXRhKTsKKyAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KCZyYXdfb3V0cHV0KTsKKyAgICBpbnQgc2l6ZSA9IFdpcmVGb3JtYXQ6OkJ5dGVTaXplKGVtcHR5X21lc3NhZ2VfKTsKKyAgICBXaXJlRm9ybWF0OjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoZW1wdHlfbWVzc2FnZV8sIHNpemUsICZvdXRwdXQpOworICAgIEFTU0VSVF9GQUxTRShvdXRwdXQuSGFkRXJyb3IoKSk7CisgIH0KKworICAvLyBEb24ndCB1c2UgRVhQRUNUX0VRIGJlY2F1c2Ugd2UgZG9uJ3Qgd2FudCB0byBkdW1wIHJhdyBiaW5hcnkgZGF0YSB0bworICAvLyBzdGRvdXQuCisgIEVYUEVDVF9UUlVFKGRhdGEgPT0gYWxsX2ZpZWxkc19kYXRhXyk7Cit9CisKK1RFU1RfRihVbmtub3duRmllbGRTZXRUZXN0LCBDb3B5RnJvbSkgeworICB1bml0dGVzdDo6VGVzdEVtcHR5TWVzc2FnZSBtZXNzYWdlOworCisgIG1lc3NhZ2UuQ29weUZyb20oZW1wdHlfbWVzc2FnZV8pOworCisgIEVYUEVDVF9FUShlbXB0eV9tZXNzYWdlXy5EZWJ1Z1N0cmluZygpLCBtZXNzYWdlLkRlYnVnU3RyaW5nKCkpOworfQorCitURVNUX0YoVW5rbm93bkZpZWxkU2V0VGVzdCwgU3dhcCkgeworICB1bml0dGVzdDo6VGVzdEVtcHR5TWVzc2FnZSBvdGhlcl9tZXNzYWdlOworICBBU1NFUlRfVFJVRShvdGhlcl9tZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhHZXRCaXphcnJvRGF0YSgpKSk7CisKKyAgRVhQRUNUX0dUKGVtcHR5X21lc3NhZ2VfLnVua25vd25fZmllbGRzKCkuZmllbGRfY291bnQoKSwgMCk7CisgIEVYUEVDVF9HVChvdGhlcl9tZXNzYWdlLnVua25vd25fZmllbGRzKCkuZmllbGRfY291bnQoKSwgMCk7CisgIGNvbnN0IHN0cmluZyBkZWJ1Z19zdHJpbmcgPSBlbXB0eV9tZXNzYWdlXy5EZWJ1Z1N0cmluZygpOworICBjb25zdCBzdHJpbmcgb3RoZXJfZGVidWdfc3RyaW5nID0gb3RoZXJfbWVzc2FnZS5EZWJ1Z1N0cmluZygpOworICBFWFBFQ1RfTkUoZGVidWdfc3RyaW5nLCBvdGhlcl9kZWJ1Z19zdHJpbmcpOworCisgIGVtcHR5X21lc3NhZ2VfLlN3YXAoJm90aGVyX21lc3NhZ2UpOworICBFWFBFQ1RfRVEoZGVidWdfc3RyaW5nLCBvdGhlcl9tZXNzYWdlLkRlYnVnU3RyaW5nKCkpOworICBFWFBFQ1RfRVEob3RoZXJfZGVidWdfc3RyaW5nLCBlbXB0eV9tZXNzYWdlXy5EZWJ1Z1N0cmluZygpKTsKK30KKworVEVTVF9GKFVua25vd25GaWVsZFNldFRlc3QsIFN3YXBXaXRoU2VsZikgeworICBjb25zdCBzdHJpbmcgZGVidWdfc3RyaW5nID0gZW1wdHlfbWVzc2FnZV8uRGVidWdTdHJpbmcoKTsKKyAgRVhQRUNUX0dUKGVtcHR5X21lc3NhZ2VfLnVua25vd25fZmllbGRzKCkuZmllbGRfY291bnQoKSwgMCk7CisKKyAgZW1wdHlfbWVzc2FnZV8uU3dhcCgmZW1wdHlfbWVzc2FnZV8pOworICBFWFBFQ1RfR1QoZW1wdHlfbWVzc2FnZV8udW5rbm93bl9maWVsZHMoKS5maWVsZF9jb3VudCgpLCAwKTsKKyAgRVhQRUNUX0VRKGRlYnVnX3N0cmluZywgZW1wdHlfbWVzc2FnZV8uRGVidWdTdHJpbmcoKSk7Cit9CisKK1RFU1RfRihVbmtub3duRmllbGRTZXRUZXN0LCBNZXJnZUZyb20pIHsKKyAgdW5pdHRlc3Q6OlRlc3RFbXB0eU1lc3NhZ2Ugc291cmNlLCBkZXN0aW5hdGlvbjsKKworICBkZXN0aW5hdGlvbi5tdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkFkZFZhcmludCgxLCAxKTsKKyAgZGVzdGluYXRpb24ubXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5BZGRWYXJpbnQoMywgMik7CisgIHNvdXJjZS5tdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkFkZFZhcmludCgyLCAzKTsKKyAgc291cmNlLm11dGFibGVfdW5rbm93bl9maWVsZHMoKS0+QWRkVmFyaW50KDMsIDQpOworCisgIGRlc3RpbmF0aW9uLk1lcmdlRnJvbShzb3VyY2UpOworCisgIEVYUEVDVF9FUSgKKyAgICAvLyBOb3RlOiAgVGhlIG9yZGVyaW5nIG9mIGZpZWxkcyBoZXJlIGRlcGVuZHMgb24gdGhlIG9yZGVyaW5nIG9mIGFkZHMKKyAgICAvLyAgIGFuZCBtZXJnaW5nLCBhYm92ZS4KKyAgICAiMTogMVxuIgorICAgICIzOiAyXG4iCisgICAgIjI6IDNcbiIKKyAgICAiMzogNFxuIiwKKyAgICBkZXN0aW5hdGlvbi5EZWJ1Z1N0cmluZygpKTsKK30KKworCitURVNUX0YoVW5rbm93bkZpZWxkU2V0VGVzdCwgQ2xlYXIpIHsKKyAgLy8gQ2xlYXIgdGhlIHNldC4KKyAgZW1wdHlfbWVzc2FnZV8uQ2xlYXIoKTsKKyAgRVhQRUNUX0VRKDAsIHVua25vd25fZmllbGRzXy0+ZmllbGRfY291bnQoKSk7Cit9CisKK1RFU1RfRihVbmtub3duRmllbGRTZXRUZXN0LCBDbGVhckFuZEZyZWVNZW1vcnkpIHsKKyAgRVhQRUNUX0dUKHVua25vd25fZmllbGRzXy0+ZmllbGRfY291bnQoKSwgMCk7CisgIHVua25vd25fZmllbGRzXy0+Q2xlYXJBbmRGcmVlTWVtb3J5KCk7CisgIEVYUEVDVF9FUSgwLCB1bmtub3duX2ZpZWxkc18tPmZpZWxkX2NvdW50KCkpOworICB1bmtub3duX2ZpZWxkc18tPkFkZFZhcmludCgxMjM0NTYsIDY1NDMyMSk7CisgIEVYUEVDVF9FUSgxLCB1bmtub3duX2ZpZWxkc18tPmZpZWxkX2NvdW50KCkpOworfQorCitURVNUX0YoVW5rbm93bkZpZWxkU2V0VGVzdCwgUGFyc2VLbm93bkFuZFVua25vd24pIHsKKyAgLy8gVGVzdCBtaXhpbmcga25vd24gYW5kIHVua25vd24gZmllbGRzIHdoZW4gcGFyc2luZy4KKworICB1bml0dGVzdDo6VGVzdEVtcHR5TWVzc2FnZSBzb3VyY2U7CisgIHNvdXJjZS5tdXRhYmxlX3Vua25vd25fZmllbGRzKCktPkFkZFZhcmludCgxMjM0NTYsIDY1NDMyMSk7CisgIHN0cmluZyBkYXRhOworICBBU1NFUlRfVFJVRShzb3VyY2UuU2VyaWFsaXplVG9TdHJpbmcoJmRhdGEpKTsKKworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIGRlc3RpbmF0aW9uOworICBBU1NFUlRfVFJVRShkZXN0aW5hdGlvbi5QYXJzZUZyb21TdHJpbmcoYWxsX2ZpZWxkc19kYXRhXyArIGRhdGEpKTsKKworICBUZXN0VXRpbDo6RXhwZWN0QWxsRmllbGRzU2V0KGRlc3RpbmF0aW9uKTsKKyAgQVNTRVJUX0VRKDEsIGRlc3RpbmF0aW9uLnVua25vd25fZmllbGRzKCkuZmllbGRfY291bnQoKSk7CisgIEFTU0VSVF9FUShVbmtub3duRmllbGQ6OlRZUEVfVkFSSU5ULAorICAgICAgICAgICAgZGVzdGluYXRpb24udW5rbm93bl9maWVsZHMoKS5maWVsZCgwKS50eXBlKCkpOworICBFWFBFQ1RfRVEoNjU0MzIxLCBkZXN0aW5hdGlvbi51bmtub3duX2ZpZWxkcygpLmZpZWxkKDApLnZhcmludCgpKTsKK30KKworVEVTVF9GKFVua25vd25GaWVsZFNldFRlc3QsIFdyb25nVHlwZVRyZWF0ZWRBc1Vua25vd24pIHsKKyAgLy8gVGVzdCB0aGF0IGZpZWxkcyBvZiB0aGUgd3Jvbmcgd2lyZSB0eXBlIGFyZSB0cmVhdGVkIGxpa2UgdW5rbm93biBmaWVsZHMKKyAgLy8gd2hlbiBwYXJzaW5nLgorCisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgYWxsX3R5cGVzX21lc3NhZ2U7CisgIHVuaXR0ZXN0OjpUZXN0RW1wdHlNZXNzYWdlIGVtcHR5X21lc3NhZ2U7CisgIHN0cmluZyBiaXphcnJvX2RhdGEgPSBHZXRCaXphcnJvRGF0YSgpOworICBBU1NFUlRfVFJVRShhbGxfdHlwZXNfbWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoYml6YXJyb19kYXRhKSk7CisgIEFTU0VSVF9UUlVFKGVtcHR5X21lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKGJpemFycm9fZGF0YSkpOworCisgIC8vIEFsbCBmaWVsZHMgc2hvdWxkIGhhdmUgYmVlbiBpbnRlcnByZXRlZCBhcyB1bmtub3duLCBzbyB0aGUgZGVidWcgc3RyaW5ncworICAvLyBzaG91bGQgYmUgdGhlIHNhbWUuCisgIEVYUEVDVF9FUShlbXB0eV9tZXNzYWdlLkRlYnVnU3RyaW5nKCksIGFsbF90eXBlc19tZXNzYWdlLkRlYnVnU3RyaW5nKCkpOworfQorCitURVNUX0YoVW5rbm93bkZpZWxkU2V0VGVzdCwgV3JvbmdUeXBlVHJlYXRlZEFzVW5rbm93blZpYVJlZmxlY3Rpb24pIHsKKyAgLy8gU2FtZSBhcyBXcm9uZ1R5cGVUcmVhdGVkQXNVbmtub3duIGJ1dCB2aWEgdGhlIHJlZmxlY3Rpb24gaW50ZXJmYWNlLgorCisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgYWxsX3R5cGVzX21lc3NhZ2U7CisgIHVuaXR0ZXN0OjpUZXN0RW1wdHlNZXNzYWdlIGVtcHR5X21lc3NhZ2U7CisgIHN0cmluZyBiaXphcnJvX2RhdGEgPSBHZXRCaXphcnJvRGF0YSgpOworICBpbzo6QXJyYXlJbnB1dFN0cmVhbSByYXdfaW5wdXQoYml6YXJyb19kYXRhLmRhdGEoKSwgYml6YXJyb19kYXRhLnNpemUoKSk7CisgIGlvOjpDb2RlZElucHV0U3RyZWFtIGlucHV0KCZyYXdfaW5wdXQpOworICBBU1NFUlRfVFJVRShXaXJlRm9ybWF0OjpQYXJzZUFuZE1lcmdlUGFydGlhbCgmaW5wdXQsICZhbGxfdHlwZXNfbWVzc2FnZSkpOworICBBU1NFUlRfVFJVRShlbXB0eV9tZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhiaXphcnJvX2RhdGEpKTsKKworICBFWFBFQ1RfRVEoZW1wdHlfbWVzc2FnZS5EZWJ1Z1N0cmluZygpLCBhbGxfdHlwZXNfbWVzc2FnZS5EZWJ1Z1N0cmluZygpKTsKK30KKworVEVTVF9GKFVua25vd25GaWVsZFNldFRlc3QsIFVua25vd25FeHRlbnNpb25zKSB7CisgIC8vIE1ha2Ugc3VyZSBmaWVsZHMgYXJlIHByb3Blcmx5IHBhcnNlZCB0byB0aGUgVW5rbm93bkZpZWxkU2V0IGV2ZW4gd2hlbgorICAvLyB0aGV5IGFyZSBkZWNsYXJlZCBhcyBleHRlbnNpb24gbnVtYmVycy4KKworICB1bml0dGVzdDo6VGVzdEVtcHR5TWVzc2FnZVdpdGhFeHRlbnNpb25zIG1lc3NhZ2U7CisgIEFTU0VSVF9UUlVFKG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKGFsbF9maWVsZHNfZGF0YV8pKTsKKworICBFWFBFQ1RfRVEobWVzc2FnZS5EZWJ1Z1N0cmluZygpLCBlbXB0eV9tZXNzYWdlXy5EZWJ1Z1N0cmluZygpKTsKK30KKworVEVTVF9GKFVua25vd25GaWVsZFNldFRlc3QsIFVua25vd25FeHRlbnNpb25zUmVmbGVjdGlvbikgeworICAvLyBTYW1lIGFzIFVua25vd25FeHRlbnNpb25zIGV4Y2VwdCBwYXJzaW5nIHZpYSByZWZsZWN0aW9uLgorCisgIHVuaXR0ZXN0OjpUZXN0RW1wdHlNZXNzYWdlV2l0aEV4dGVuc2lvbnMgbWVzc2FnZTsKKyAgaW86OkFycmF5SW5wdXRTdHJlYW0gcmF3X2lucHV0KGFsbF9maWVsZHNfZGF0YV8uZGF0YSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxsX2ZpZWxkc19kYXRhXy5zaXplKCkpOworICBpbzo6Q29kZWRJbnB1dFN0cmVhbSBpbnB1dCgmcmF3X2lucHV0KTsKKyAgQVNTRVJUX1RSVUUoV2lyZUZvcm1hdDo6UGFyc2VBbmRNZXJnZVBhcnRpYWwoJmlucHV0LCAmbWVzc2FnZSkpOworCisgIEVYUEVDVF9FUShtZXNzYWdlLkRlYnVnU3RyaW5nKCksIGVtcHR5X21lc3NhZ2VfLkRlYnVnU3RyaW5nKCkpOworfQorCitURVNUX0YoVW5rbm93bkZpZWxkU2V0VGVzdCwgV3JvbmdFeHRlbnNpb25UeXBlVHJlYXRlZEFzVW5rbm93bikgeworICAvLyBUZXN0IHRoYXQgZmllbGRzIG9mIHRoZSB3cm9uZyB3aXJlIHR5cGUgYXJlIHRyZWF0ZWQgbGlrZSB1bmtub3duIGZpZWxkcworICAvLyB3aGVuIHBhcnNpbmcgZXh0ZW5zaW9ucy4KKworICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgYWxsX2V4dGVuc2lvbnNfbWVzc2FnZTsKKyAgdW5pdHRlc3Q6OlRlc3RFbXB0eU1lc3NhZ2UgZW1wdHlfbWVzc2FnZTsKKyAgc3RyaW5nIGJpemFycm9fZGF0YSA9IEdldEJpemFycm9EYXRhKCk7CisgIEFTU0VSVF9UUlVFKGFsbF9leHRlbnNpb25zX21lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKGJpemFycm9fZGF0YSkpOworICBBU1NFUlRfVFJVRShlbXB0eV9tZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhiaXphcnJvX2RhdGEpKTsKKworICAvLyBBbGwgZmllbGRzIHNob3VsZCBoYXZlIGJlZW4gaW50ZXJwcmV0ZWQgYXMgdW5rbm93biwgc28gdGhlIGRlYnVnIHN0cmluZ3MKKyAgLy8gc2hvdWxkIGJlIHRoZSBzYW1lLgorICBFWFBFQ1RfRVEoZW1wdHlfbWVzc2FnZS5EZWJ1Z1N0cmluZygpLCBhbGxfZXh0ZW5zaW9uc19tZXNzYWdlLkRlYnVnU3RyaW5nKCkpOworfQorCitURVNUX0YoVW5rbm93bkZpZWxkU2V0VGVzdCwgVW5rbm93bkVudW1WYWx1ZSkgeworICB1c2luZyB1bml0dGVzdDo6VGVzdEFsbFR5cGVzOworICB1c2luZyB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnM7CisgIHVzaW5nIHVuaXR0ZXN0OjpUZXN0RW1wdHlNZXNzYWdlOworCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogc2luZ3VsYXJfZmllbGQgPQorICAgIFRlc3RBbGxUeXBlczo6ZGVzY3JpcHRvcigpLT5GaW5kRmllbGRCeU5hbWUoIm9wdGlvbmFsX25lc3RlZF9lbnVtIik7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogcmVwZWF0ZWRfZmllbGQgPQorICAgIFRlc3RBbGxUeXBlczo6ZGVzY3JpcHRvcigpLT5GaW5kRmllbGRCeU5hbWUoInJlcGVhdGVkX25lc3RlZF9lbnVtIik7CisgIEFTU0VSVF9UUlVFKHNpbmd1bGFyX2ZpZWxkICE9IE5VTEwpOworICBBU1NFUlRfVFJVRShyZXBlYXRlZF9maWVsZCAhPSBOVUxMKTsKKworICBzdHJpbmcgZGF0YTsKKworICB7CisgICAgVGVzdEVtcHR5TWVzc2FnZSBlbXB0eV9tZXNzYWdlOworICAgIFVua25vd25GaWVsZFNldCogdW5rbm93bl9maWVsZHMgPSBlbXB0eV9tZXNzYWdlLm11dGFibGVfdW5rbm93bl9maWVsZHMoKTsKKyAgICB1bmtub3duX2ZpZWxkcy0+QWRkVmFyaW50KHNpbmd1bGFyX2ZpZWxkLT5udW1iZXIoKSwgVGVzdEFsbFR5cGVzOjpCQVIpOworICAgIHVua25vd25fZmllbGRzLT5BZGRWYXJpbnQoc2luZ3VsYXJfZmllbGQtPm51bWJlcigpLCA1KTsgIC8vIG5vdCB2YWxpZAorICAgIHVua25vd25fZmllbGRzLT5BZGRWYXJpbnQocmVwZWF0ZWRfZmllbGQtPm51bWJlcigpLCBUZXN0QWxsVHlwZXM6OkZPTyk7CisgICAgdW5rbm93bl9maWVsZHMtPkFkZFZhcmludChyZXBlYXRlZF9maWVsZC0+bnVtYmVyKCksIDQpOyAgLy8gbm90IHZhbGlkCisgICAgdW5rbm93bl9maWVsZHMtPkFkZFZhcmludChyZXBlYXRlZF9maWVsZC0+bnVtYmVyKCksIFRlc3RBbGxUeXBlczo6QkFaKTsKKyAgICB1bmtub3duX2ZpZWxkcy0+QWRkVmFyaW50KHJlcGVhdGVkX2ZpZWxkLT5udW1iZXIoKSwgNik7ICAvLyBub3QgdmFsaWQKKyAgICBlbXB0eV9tZXNzYWdlLlNlcmlhbGl6ZVRvU3RyaW5nKCZkYXRhKTsKKyAgfQorCisgIHsKKyAgICBUZXN0QWxsVHlwZXMgbWVzc2FnZTsKKyAgICBBU1NFUlRfVFJVRShtZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhkYXRhKSk7CisgICAgRVhQRUNUX0VRKFRlc3RBbGxUeXBlczo6QkFSLCBtZXNzYWdlLm9wdGlvbmFsX25lc3RlZF9lbnVtKCkpOworICAgIEFTU0VSVF9FUSgyLCBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9lbnVtX3NpemUoKSk7CisgICAgRVhQRUNUX0VRKFRlc3RBbGxUeXBlczo6Rk9PLCBtZXNzYWdlLnJlcGVhdGVkX25lc3RlZF9lbnVtKDApKTsKKyAgICBFWFBFQ1RfRVEoVGVzdEFsbFR5cGVzOjpCQVosIG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX2VudW0oMSkpOworCisgICAgY29uc3QgVW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcyA9IG1lc3NhZ2UudW5rbm93bl9maWVsZHMoKTsKKyAgICBBU1NFUlRfRVEoMywgdW5rbm93bl9maWVsZHMuZmllbGRfY291bnQoKSk7CisKKyAgICBFWFBFQ1RfRVEoc2luZ3VsYXJfZmllbGQtPm51bWJlcigpLCB1bmtub3duX2ZpZWxkcy5maWVsZCgwKS5udW1iZXIoKSk7CisgICAgQVNTRVJUX0VRKFVua25vd25GaWVsZDo6VFlQRV9WQVJJTlQsIHVua25vd25fZmllbGRzLmZpZWxkKDApLnR5cGUoKSk7CisgICAgRVhQRUNUX0VRKDUsIHVua25vd25fZmllbGRzLmZpZWxkKDApLnZhcmludCgpKTsKKworICAgIEVYUEVDVF9FUShyZXBlYXRlZF9maWVsZC0+bnVtYmVyKCksIHVua25vd25fZmllbGRzLmZpZWxkKDEpLm51bWJlcigpKTsKKyAgICBBU1NFUlRfRVEoVW5rbm93bkZpZWxkOjpUWVBFX1ZBUklOVCwgdW5rbm93bl9maWVsZHMuZmllbGQoMSkudHlwZSgpKTsKKyAgICBFWFBFQ1RfRVEoNCwgdW5rbm93bl9maWVsZHMuZmllbGQoMSkudmFyaW50KCkpOworCisgICAgRVhQRUNUX0VRKHJlcGVhdGVkX2ZpZWxkLT5udW1iZXIoKSwgdW5rbm93bl9maWVsZHMuZmllbGQoMikubnVtYmVyKCkpOworICAgIEFTU0VSVF9FUShVbmtub3duRmllbGQ6OlRZUEVfVkFSSU5ULCB1bmtub3duX2ZpZWxkcy5maWVsZCgyKS50eXBlKCkpOworICAgIEVYUEVDVF9FUSg2LCB1bmtub3duX2ZpZWxkcy5maWVsZCgyKS52YXJpbnQoKSk7CisgIH0KKworICB7CisgICAgdXNpbmcgdW5pdHRlc3Q6Om9wdGlvbmFsX25lc3RlZF9lbnVtX2V4dGVuc2lvbjsKKyAgICB1c2luZyB1bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uOworCisgICAgVGVzdEFsbEV4dGVuc2lvbnMgbWVzc2FnZTsKKyAgICBBU1NFUlRfVFJVRShtZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhkYXRhKSk7CisgICAgRVhQRUNUX0VRKFRlc3RBbGxUeXBlczo6QkFSLAorICAgICAgICAgICAgICBtZXNzYWdlLkdldEV4dGVuc2lvbihvcHRpb25hbF9uZXN0ZWRfZW51bV9leHRlbnNpb24pKTsKKyAgICBBU1NFUlRfRVEoMiwgbWVzc2FnZS5FeHRlbnNpb25TaXplKHJlcGVhdGVkX25lc3RlZF9lbnVtX2V4dGVuc2lvbikpOworICAgIEVYUEVDVF9FUShUZXN0QWxsVHlwZXM6OkZPTywKKyAgICAgICAgICAgICAgbWVzc2FnZS5HZXRFeHRlbnNpb24ocmVwZWF0ZWRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uLCAwKSk7CisgICAgRVhQRUNUX0VRKFRlc3RBbGxUeXBlczo6QkFaLAorICAgICAgICAgICAgICBtZXNzYWdlLkdldEV4dGVuc2lvbihyZXBlYXRlZF9uZXN0ZWRfZW51bV9leHRlbnNpb24sIDEpKTsKKworICAgIGNvbnN0IFVua25vd25GaWVsZFNldCYgdW5rbm93bl9maWVsZHMgPSBtZXNzYWdlLnVua25vd25fZmllbGRzKCk7CisgICAgQVNTRVJUX0VRKDMsIHVua25vd25fZmllbGRzLmZpZWxkX2NvdW50KCkpOworCisgICAgRVhQRUNUX0VRKHNpbmd1bGFyX2ZpZWxkLT5udW1iZXIoKSwgdW5rbm93bl9maWVsZHMuZmllbGQoMCkubnVtYmVyKCkpOworICAgIEFTU0VSVF9FUShVbmtub3duRmllbGQ6OlRZUEVfVkFSSU5ULCB1bmtub3duX2ZpZWxkcy5maWVsZCgwKS50eXBlKCkpOworICAgIEVYUEVDVF9FUSg1LCB1bmtub3duX2ZpZWxkcy5maWVsZCgwKS52YXJpbnQoKSk7CisKKyAgICBFWFBFQ1RfRVEocmVwZWF0ZWRfZmllbGQtPm51bWJlcigpLCB1bmtub3duX2ZpZWxkcy5maWVsZCgxKS5udW1iZXIoKSk7CisgICAgQVNTRVJUX0VRKFVua25vd25GaWVsZDo6VFlQRV9WQVJJTlQsIHVua25vd25fZmllbGRzLmZpZWxkKDEpLnR5cGUoKSk7CisgICAgRVhQRUNUX0VRKDQsIHVua25vd25fZmllbGRzLmZpZWxkKDEpLnZhcmludCgpKTsKKworICAgIEVYUEVDVF9FUShyZXBlYXRlZF9maWVsZC0+bnVtYmVyKCksIHVua25vd25fZmllbGRzLmZpZWxkKDIpLm51bWJlcigpKTsKKyAgICBBU1NFUlRfRVEoVW5rbm93bkZpZWxkOjpUWVBFX1ZBUklOVCwgdW5rbm93bl9maWVsZHMuZmllbGQoMikudHlwZSgpKTsKKyAgICBFWFBFQ1RfRVEoNiwgdW5rbm93bl9maWVsZHMuZmllbGQoMikudmFyaW50KCkpOworICB9Cit9CisKK1RFU1RfRihVbmtub3duRmllbGRTZXRUZXN0LCBTcGFjZVVzZWRFeGNsdWRpbmdTZWxmKSB7CisgIFVua25vd25GaWVsZFNldCBlbXB0eTsKKyAgZW1wdHkuQWRkVmFyaW50KDEsIDApOworICBFWFBFQ1RfRVEoc2l6ZW9mKHZlY3RvcjxVbmtub3duRmllbGQ+KSArIHNpemVvZihVbmtub3duRmllbGQpLAorICAgICAgICAgICAgZW1wdHkuU3BhY2VVc2VkRXhjbHVkaW5nU2VsZigpKTsKK30KKworVEVTVF9GKFVua25vd25GaWVsZFNldFRlc3QsIFNwYWNlVXNlZCkgeworICB1bml0dGVzdDo6VGVzdEVtcHR5TWVzc2FnZSBlbXB0eV9tZXNzYWdlOworCisgIC8vIE1ha2Ugc3VyZSBhbiB1bmtub3duIGZpZWxkIHNldCBoYXMgemVybyBzcGFjZSB1c2VkIHVudGlsIGEgZmllbGQgaXMKKyAgLy8gYWN0dWFsbHkgYWRkZWQuCisgIGludCBiYXNlX3NpemUgPSBlbXB0eV9tZXNzYWdlLlNwYWNlVXNlZCgpOworICBVbmtub3duRmllbGRTZXQqIHVua25vd25fZmllbGRzID0gZW1wdHlfbWVzc2FnZS5tdXRhYmxlX3Vua25vd25fZmllbGRzKCk7CisgIEVYUEVDVF9FUShiYXNlX3NpemUsIGVtcHR5X21lc3NhZ2UuU3BhY2VVc2VkKCkpOworCisgIC8vIE1ha2Ugc3VyZSBlYWNoIHRoaW5nIHdlIGFkZCB0byB0aGUgc2V0IGluY3JlYXNlcyB0aGUgU3BhY2VVc2VkKCkuCisgIHVua25vd25fZmllbGRzLT5BZGRWYXJpbnQoMSwgMCk7CisgIEVYUEVDVF9MVChiYXNlX3NpemUsIGVtcHR5X21lc3NhZ2UuU3BhY2VVc2VkKCkpOworICBiYXNlX3NpemUgPSBlbXB0eV9tZXNzYWdlLlNwYWNlVXNlZCgpOworCisgIHN0cmluZyogc3RyID0gdW5rbm93bl9maWVsZHMtPkFkZExlbmd0aERlbGltaXRlZCgxKTsKKyAgRVhQRUNUX0xUKGJhc2Vfc2l6ZSwgZW1wdHlfbWVzc2FnZS5TcGFjZVVzZWQoKSk7CisgIGJhc2Vfc2l6ZSA9IGVtcHR5X21lc3NhZ2UuU3BhY2VVc2VkKCk7CisKKyAgc3RyLT5hc3NpZ24oc2l6ZW9mKHN0cmluZykgKyAxLCAneCcpOworICBFWFBFQ1RfTFQoYmFzZV9zaXplLCBlbXB0eV9tZXNzYWdlLlNwYWNlVXNlZCgpKTsKKyAgYmFzZV9zaXplID0gZW1wdHlfbWVzc2FnZS5TcGFjZVVzZWQoKTsKKworICBVbmtub3duRmllbGRTZXQqIGdyb3VwID0gdW5rbm93bl9maWVsZHMtPkFkZEdyb3VwKDEpOworICBFWFBFQ1RfTFQoYmFzZV9zaXplLCBlbXB0eV9tZXNzYWdlLlNwYWNlVXNlZCgpKTsKKyAgYmFzZV9zaXplID0gZW1wdHlfbWVzc2FnZS5TcGFjZVVzZWQoKTsKKworICBncm91cC0+QWRkVmFyaW50KDEsIDApOworICBFWFBFQ1RfTFQoYmFzZV9zaXplLCBlbXB0eV9tZXNzYWdlLlNwYWNlVXNlZCgpKTsKK30KKworCitURVNUX0YoVW5rbm93bkZpZWxkU2V0VGVzdCwgRW1wdHkpIHsKKyAgVW5rbm93bkZpZWxkU2V0IHVua25vd25fZmllbGRzOworICBFWFBFQ1RfVFJVRSh1bmtub3duX2ZpZWxkcy5lbXB0eSgpKTsKKyAgdW5rbm93bl9maWVsZHMuQWRkVmFyaW50KDYsIDEyMyk7CisgIEVYUEVDVF9GQUxTRSh1bmtub3duX2ZpZWxkcy5lbXB0eSgpKTsKKyAgdW5rbm93bl9maWVsZHMuQ2xlYXIoKTsKKyAgRVhQRUNUX1RSVUUodW5rbm93bl9maWVsZHMuZW1wdHkoKSk7Cit9CisKK1RFU1RfRihVbmtub3duRmllbGRTZXRUZXN0LCBEZWxldGVTdWJyYW5nZSkgeworICAvLyBFeGhhdXN0aXZlbHkgdGVzdCB0aGUgZGVsZXRpb24gb2YgZXZlcnkgcG9zc2libGUgc3VicmFuZ2UgaW4gYXJyYXlzIG9mIGFsbAorICAvLyBzaXplcyBmcm9tIDAgdGhyb3VnaCA5LgorICBmb3IgKGludCBzaXplID0gMDsgc2l6ZSA8IDEwOyArK3NpemUpIHsKKyAgICBmb3IgKGludCBudW0gPSAwOyBudW0gPD0gc2l6ZTsgKytudW0pIHsKKyAgICAgIGZvciAoaW50IHN0YXJ0ID0gMDsgc3RhcnQgPCBzaXplIC0gbnVtOyArK3N0YXJ0KSB7CisgICAgICAgIC8vIENyZWF0ZSBhIHNldCB3aXRoICJzaXplIiBmaWVsZHMuCisgICAgICAgIFVua25vd25GaWVsZFNldCB1bmtub3duOworICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNpemU7ICsraSkgeworICAgICAgICAgIHVua25vd24uQWRkRml4ZWQzMihpLCBpKTsKKyAgICAgICAgfQorICAgICAgICAvLyBEZWxldGUgdGhlIHNwZWNpZmllZCBzdWJyYW5nZS4KKyAgICAgICAgdW5rbm93bi5EZWxldGVTdWJyYW5nZShzdGFydCwgbnVtKTsKKyAgICAgICAgLy8gTWFrZSBzdXJlIHRoZSByZXN1bHRpbmcgZmllbGQgdmFsdWVzIGFyZSBzdGlsbCBjb3JyZWN0LgorICAgICAgICBFWFBFQ1RfRVEoc2l6ZSAtIG51bSwgdW5rbm93bi5maWVsZF9jb3VudCgpKTsKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB1bmtub3duLmZpZWxkX2NvdW50KCk7ICsraSkgeworICAgICAgICAgIGlmIChpIDwgc3RhcnQpIHsKKyAgICAgICAgICAgIEVYUEVDVF9FUShpLCB1bmtub3duLmZpZWxkKGkpLmZpeGVkMzIoKSk7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIEVYUEVDVF9FUShpICsgbnVtLCB1bmtub3duLmZpZWxkKGkpLmZpeGVkMzIoKSk7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9CisgICAgfQorICB9Cit9CisKK3ZvaWQgQ2hlY2tEZWxldGVCeU51bWJlcihjb25zdCB2ZWN0b3I8aW50PiYgZmllbGRfbnVtYmVycywgaW50IGRlbGV0ZWRfbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmVjdG9yPGludD4mIGV4cGVjdGVkX2ZpZWxkX251Ym1lcnMpIHsKKyAgVW5rbm93bkZpZWxkU2V0IHVua25vd25fZmllbGRzOworICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkX251bWJlcnMuc2l6ZSgpOyArK2kpIHsKKyAgICB1bmtub3duX2ZpZWxkcy5BZGRGaXhlZDMyKGZpZWxkX251bWJlcnNbaV0sIGkpOworICB9CisgIHVua25vd25fZmllbGRzLkRlbGV0ZUJ5TnVtYmVyKGRlbGV0ZWRfbnVtYmVyKTsKKyAgQVNTRVJUX0VRKGV4cGVjdGVkX2ZpZWxkX251Ym1lcnMuc2l6ZSgpLCB1bmtub3duX2ZpZWxkcy5maWVsZF9jb3VudCgpKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBleHBlY3RlZF9maWVsZF9udWJtZXJzLnNpemUoKTsgKytpKSB7CisgICAgRVhQRUNUX0VRKGV4cGVjdGVkX2ZpZWxkX251Ym1lcnNbaV0sCisgICAgICAgICAgICAgIHVua25vd25fZmllbGRzLmZpZWxkKGkpLm51bWJlcigpKTsKKyAgfQorfQorCisjZGVmaW5lIE1BS0VfVkVDVE9SKHgpIHZlY3RvcjxpbnQ+KHgsIHggKyBHT09HTEVfQVJSQVlTSVpFKHgpKQorVEVTVF9GKFVua25vd25GaWVsZFNldFRlc3QsIERlbGV0ZUJ5TnVtYmVyKSB7CisgIENoZWNrRGVsZXRlQnlOdW1iZXIodmVjdG9yPGludD4oKSwgMSwgdmVjdG9yPGludD4oKSk7CisgIHN0YXRpYyBjb25zdCBpbnQga1Rlc3RGaWVsZE51bWJlcnMxW10gPSB7MSwgMiwgM307CisgIHN0YXRpYyBjb25zdCBpbnQga0ZpZWxkTnVtYmVyVG9EZWxldGUxID0gMTsKKyAgc3RhdGljIGNvbnN0IGludCBrRXhwZWN0ZWRGaWVsZE51bWJlcnMxW10gPSB7MiwgM307CisgIENoZWNrRGVsZXRlQnlOdW1iZXIoTUFLRV9WRUNUT1Ioa1Rlc3RGaWVsZE51bWJlcnMxKSwga0ZpZWxkTnVtYmVyVG9EZWxldGUxLAorICAgICAgICAgICAgICAgICAgICAgIE1BS0VfVkVDVE9SKGtFeHBlY3RlZEZpZWxkTnVtYmVyczEpKTsKKyAgc3RhdGljIGNvbnN0IGludCBrVGVzdEZpZWxkTnVtYmVyczJbXSA9IHsxLCAyLCAzfTsKKyAgc3RhdGljIGNvbnN0IGludCBrRmllbGROdW1iZXJUb0RlbGV0ZTIgPSAyOworICBzdGF0aWMgY29uc3QgaW50IGtFeHBlY3RlZEZpZWxkTnVtYmVyczJbXSA9IHsxLCAzfTsKKyAgQ2hlY2tEZWxldGVCeU51bWJlcihNQUtFX1ZFQ1RPUihrVGVzdEZpZWxkTnVtYmVyczIpLCBrRmllbGROdW1iZXJUb0RlbGV0ZTIsCisgICAgICAgICAgICAgICAgICAgICAgTUFLRV9WRUNUT1Ioa0V4cGVjdGVkRmllbGROdW1iZXJzMikpOworICBzdGF0aWMgY29uc3QgaW50IGtUZXN0RmllbGROdW1iZXJzM1tdID0gezEsIDIsIDN9OworICBzdGF0aWMgY29uc3QgaW50IGtGaWVsZE51bWJlclRvRGVsZXRlMyA9IDM7CisgIHN0YXRpYyBjb25zdCBpbnQga0V4cGVjdGVkRmllbGROdW1iZXJzM1tdID0gezEsIDJ9OworICBDaGVja0RlbGV0ZUJ5TnVtYmVyKE1BS0VfVkVDVE9SKGtUZXN0RmllbGROdW1iZXJzMyksIGtGaWVsZE51bWJlclRvRGVsZXRlMywKKyAgICAgICAgICAgICAgICAgICAgICBNQUtFX1ZFQ1RPUihrRXhwZWN0ZWRGaWVsZE51bWJlcnMzKSk7CisgIHN0YXRpYyBjb25zdCBpbnQga1Rlc3RGaWVsZE51bWJlcnM0W10gPSB7MSwgMiwgMSwgNCwgMX07CisgIHN0YXRpYyBjb25zdCBpbnQga0ZpZWxkTnVtYmVyVG9EZWxldGU0ID0gMTsKKyAgc3RhdGljIGNvbnN0IGludCBrRXhwZWN0ZWRGaWVsZE51bWJlcnM0W10gPSB7MiwgNH07CisgIENoZWNrRGVsZXRlQnlOdW1iZXIoTUFLRV9WRUNUT1Ioa1Rlc3RGaWVsZE51bWJlcnM0KSwga0ZpZWxkTnVtYmVyVG9EZWxldGU0LAorICAgICAgICAgICAgICAgICAgICAgIE1BS0VfVkVDVE9SKGtFeHBlY3RlZEZpZWxkTnVtYmVyczQpKTsKKyAgc3RhdGljIGNvbnN0IGludCBrVGVzdEZpZWxkTnVtYmVyczVbXSA9IHsxLCAyLCAzLCA0LCA1fTsKKyAgc3RhdGljIGNvbnN0IGludCBrRmllbGROdW1iZXJUb0RlbGV0ZTUgPSA2OworICBzdGF0aWMgY29uc3QgaW50IGtFeHBlY3RlZEZpZWxkTnVtYmVyczVbXSA9IHsxLCAyLCAzLCA0LCA1fTsKKyAgQ2hlY2tEZWxldGVCeU51bWJlcihNQUtFX1ZFQ1RPUihrVGVzdEZpZWxkTnVtYmVyczUpLCBrRmllbGROdW1iZXJUb0RlbGV0ZTUsCisgICAgICAgICAgICAgICAgICAgICAgTUFLRV9WRUNUT1Ioa0V4cGVjdGVkRmllbGROdW1iZXJzNSkpOworfQorI3VuZGVmIE1BS0VfVkVDVE9SCit9ICAvLyBuYW1lc3BhY2UKKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvZmllbGRfY29tcGFyYXRvci5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9maWVsZF9jb21wYXJhdG9yLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlmNjEzMjYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvZmllbGRfY29tcGFyYXRvci5jYwpAQCAtMCwwICsxLDE4OCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga3Nyb2thQGdvb2dsZS5jb20gKEtyenlzenRvZiBTcm9rYSkKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2ZpZWxkX2NvbXBhcmF0b3IuaD4KKworI2luY2x1ZGUgPHN0cmluZz4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21lc3NhZ2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbWFwX3V0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbWF0aGxpbWl0cy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9tYXRodXRpbC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgdXRpbCB7CisKK0ZpZWxkQ29tcGFyYXRvcjo6RmllbGRDb21wYXJhdG9yKCkge30KK0ZpZWxkQ29tcGFyYXRvcjo6fkZpZWxkQ29tcGFyYXRvcigpIHt9CisKK0RlZmF1bHRGaWVsZENvbXBhcmF0b3I6OkRlZmF1bHRGaWVsZENvbXBhcmF0b3IoKQorICAgIDogZmxvYXRfY29tcGFyaXNvbl8oRVhBQ1QpLAorICAgICAgdHJlYXRfbmFuX2FzX2VxdWFsXyhmYWxzZSksCisgICAgICBoYXNfZGVmYXVsdF90b2xlcmFuY2VfKGZhbHNlKSB7Cit9CisKK0RlZmF1bHRGaWVsZENvbXBhcmF0b3I6On5EZWZhdWx0RmllbGRDb21wYXJhdG9yKCkge30KKworRmllbGRDb21wYXJhdG9yOjpDb21wYXJpc29uUmVzdWx0IERlZmF1bHRGaWVsZENvbXBhcmF0b3I6OkNvbXBhcmUoCisgICAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBtZXNzYWdlXzEsCisgICAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBtZXNzYWdlXzIsCisgICAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgaW50IGluZGV4XzEsIGludCBpbmRleF8yLAorICAgICAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6dXRpbDo6RmllbGRDb250ZXh0KiBmaWVsZF9jb250ZXh0KSB7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb25fMSA9IG1lc3NhZ2VfMS5HZXRSZWZsZWN0aW9uKCk7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb25fMiA9IG1lc3NhZ2VfMi5HZXRSZWZsZWN0aW9uKCk7CisKKyAgc3dpdGNoIChmaWVsZC0+Y3BwX3R5cGUoKSkgeworI2RlZmluZSBDT01QQVJFX0ZJRUxEKE1FVEhPRCkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGlmIChmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgcmV0dXJuIFJlc3VsdEZyb21Cb29sZWFuKENvbXBhcmUjI01FVEhPRCggICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICpmaWVsZCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgIHJlZmxlY3Rpb25fMS0+R2V0UmVwZWF0ZWQjI01FVEhPRChtZXNzYWdlXzEsIGZpZWxkLCBpbmRleF8xKSwgICAgXAorICAgICAgICAgIHJlZmxlY3Rpb25fMi0+R2V0UmVwZWF0ZWQjI01FVEhPRChtZXNzYWdlXzIsIGZpZWxkLCBpbmRleF8yKSkpOyAgXAorICAgIH0gZWxzZSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgcmV0dXJuIFJlc3VsdEZyb21Cb29sZWFuKENvbXBhcmUjI01FVEhPRCggICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICpmaWVsZCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgIHJlZmxlY3Rpb25fMS0+R2V0IyNNRVRIT0QobWVzc2FnZV8xLCBmaWVsZCksICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgIHJlZmxlY3Rpb25fMi0+R2V0IyNNRVRIT0QobWVzc2FnZV8yLCBmaWVsZCkpKTsgICAgICAgICAgICAgICAgICAgXAorICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGJyZWFrOyAgLy8gTWFrZSBzdXJlIG5vIGZhbGwtdGhyb3VnaCBpcyBpbnRyb2R1Y2VkLgorCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfQk9PTDoKKyAgICAgIENPTVBBUkVfRklFTEQoQm9vbCk7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRE9VQkxFOgorICAgICAgQ09NUEFSRV9GSUVMRChEb3VibGUpOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0VOVU06CisgICAgICBDT01QQVJFX0ZJRUxEKEVudW0pOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0ZMT0FUOgorICAgICAgQ09NUEFSRV9GSUVMRChGbG9hdCk7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfSU5UMzI6CisgICAgICBDT01QQVJFX0ZJRUxEKEludDMyKTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9JTlQ2NDoKKyAgICAgIENPTVBBUkVfRklFTEQoSW50NjQpOworICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1NUUklORzoKKyAgICAgIENPTVBBUkVfRklFTEQoU3RyaW5nKTsKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9VSU5UMzI6CisgICAgICBDT01QQVJFX0ZJRUxEKFVJbnQzMik7CisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDY0OgorICAgICAgQ09NUEFSRV9GSUVMRChVSW50NjQpOworCisjdW5kZWYgQ09NUEFSRV9GSUVMRAorCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRToKKyAgICAgIHJldHVybiBSRUNVUlNFOworCisgICAgZGVmYXVsdDoKKyAgICAgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJObyBjb21wYXJpc29uIGNvZGUgZm9yIGZpZWxkICIgPDwgZmllbGQtPmZ1bGxfbmFtZSgpCisgICAgICAgICAgICAgICAgIDw8ICIgb2YgQ3BwVHlwZSA9ICIgPDwgZmllbGQtPmNwcF90eXBlKCk7CisgICAgICByZXR1cm4gRElGRkVSRU5UOworICB9Cit9CisKK3ZvaWQgRGVmYXVsdEZpZWxkQ29tcGFyYXRvcjo6U2V0RGVmYXVsdEZyYWN0aW9uQW5kTWFyZ2luKGRvdWJsZSBmcmFjdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvdWJsZSBtYXJnaW4pIHsKKyAgZGVmYXVsdF90b2xlcmFuY2VfID0gVG9sZXJhbmNlKGZyYWN0aW9uLCBtYXJnaW4pOworICBoYXNfZGVmYXVsdF90b2xlcmFuY2VfID0gdHJ1ZTsKK30KKwordm9pZCBEZWZhdWx0RmllbGRDb21wYXJhdG9yOjpTZXRGcmFjdGlvbkFuZE1hcmdpbihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb3VibGUgZnJhY3Rpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvdWJsZSBtYXJnaW4pIHsKKyAgR09PR0xFX0NIRUNLKEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9GTE9BVCA9PSBmaWVsZC0+Y3BwX3R5cGUoKSB8fAorICAgICAgICBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRE9VQkxFID09IGZpZWxkLT5jcHBfdHlwZSgpKQorICAgICAgPDwgIkZpZWxkIGhhcyB0byBiZSBmbG9hdCBvciBkb3VibGUgdHlwZS4gRmllbGQgbmFtZSBpczogIgorICAgICAgPDwgZmllbGQtPmZ1bGxfbmFtZSgpOworICBtYXBfdG9sZXJhbmNlX1tmaWVsZF0gPSBUb2xlcmFuY2UoZnJhY3Rpb24sIG1hcmdpbik7Cit9CisKK2Jvb2wgRGVmYXVsdEZpZWxkQ29tcGFyYXRvcjo6Q29tcGFyZURvdWJsZShjb25zdCBGaWVsZERlc2NyaXB0b3ImIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvdWJsZSB2YWx1ZV8xLCBkb3VibGUgdmFsdWVfMikgeworICByZXR1cm4gQ29tcGFyZURvdWJsZU9yRmxvYXQoZmllbGQsIHZhbHVlXzEsIHZhbHVlXzIpOworfQorCitib29sIERlZmF1bHRGaWVsZENvbXBhcmF0b3I6OkNvbXBhcmVFbnVtKGNvbnN0IEZpZWxkRGVzY3JpcHRvciYgZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIHZhbHVlXzEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIHZhbHVlXzIpIHsKKyAgcmV0dXJuIHZhbHVlXzEtPm51bWJlcigpID09IHZhbHVlXzItPm51bWJlcigpOworfQorCitib29sIERlZmF1bHRGaWVsZENvbXBhcmF0b3I6OkNvbXBhcmVGbG9hdChjb25zdCBGaWVsZERlc2NyaXB0b3ImIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmxvYXQgdmFsdWVfMSwgZmxvYXQgdmFsdWVfMikgeworICByZXR1cm4gQ29tcGFyZURvdWJsZU9yRmxvYXQoZmllbGQsIHZhbHVlXzEsIHZhbHVlXzIpOworfQorCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorYm9vbCBEZWZhdWx0RmllbGRDb21wYXJhdG9yOjpDb21wYXJlRG91YmxlT3JGbG9hdChjb25zdCBGaWVsZERlc2NyaXB0b3ImIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUIHZhbHVlXzEsIFQgdmFsdWVfMikgeworICBpZiAodmFsdWVfMSA9PSB2YWx1ZV8yKSB7CisgICAgLy8gQ292ZXJzICtpbmYgYW5kIC1pbmYgKHdoaWNoIGFyZSBub3Qgd2l0aGluIG1hcmdpbiBvciBmcmFjdGlvbiBvZgorICAgIC8vIHRoZW1zZWx2ZXMpLCBhbmQgaXMgYSBzaG9ydGN1dCBmb3IgZmluaXRlIHZhbHVlcy4KKyAgICByZXR1cm4gdHJ1ZTsKKyAgfSBlbHNlIGlmIChmbG9hdF9jb21wYXJpc29uXyA9PSBFWEFDVCkgeworICAgIGlmICh0cmVhdF9uYW5fYXNfZXF1YWxfICYmCisgICAgICAgIE1hdGhMaW1pdHM8VD46OklzTmFOKHZhbHVlXzEpICYmIE1hdGhMaW1pdHM8VD46OklzTmFOKHZhbHVlXzIpKSB7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgICAgcmV0dXJuIGZhbHNlOworICB9IGVsc2UgeworICAgIGlmICh0cmVhdF9uYW5fYXNfZXF1YWxfICYmCisgICAgICAgIE1hdGhMaW1pdHM8VD46OklzTmFOKHZhbHVlXzEpICYmIE1hdGhMaW1pdHM8VD46OklzTmFOKHZhbHVlXzIpKSB7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgICAgLy8gZmxvYXRfY29tcGFyaXNvbl8gPT0gQVBQUk9YSU1BVEUgY292ZXJzIHR3byB1c2UgY2FzZXMuCisgICAgVG9sZXJhbmNlKiB0b2xlcmFuY2UgPSBGaW5kT3JOdWxsKG1hcF90b2xlcmFuY2VfLCAmZmllbGQpOworICAgIGlmICh0b2xlcmFuY2UgPT0gTlVMTCAmJiBoYXNfZGVmYXVsdF90b2xlcmFuY2VfKSB7CisgICAgICB0b2xlcmFuY2UgPSAmZGVmYXVsdF90b2xlcmFuY2VfOworICAgIH0KKyAgICBpZiAodG9sZXJhbmNlID09IE5VTEwpIHsKKyAgICAgIHJldHVybiBNYXRoVXRpbDo6QWxtb3N0RXF1YWxzKHZhbHVlXzEsIHZhbHVlXzIpOworICAgIH0gZWxzZSB7CisgICAgICAvLyBVc2UgdXNlci1wcm92aWRlZCBmcmFjdGlvbiBhbmQgbWFyZ2luLiBTaW5jZSB0aGV5IGFyZSBzdG9yZWQgYXMKKyAgICAgIC8vIGRvdWJsZXMsIHdlIGV4cGxpY2l0ZWx5IGNhc3QgdGhlbSB0byB0eXBlcyBvZiB2YWx1ZXMgcHJvdmlkZWQuIFRoaXMKKyAgICAgIC8vIGlzIHZlcnkgbGlrZWx5IHRvIGZhaWwgaWYgcHJvdmlkZWQgdmFsdWVzIGFyZSBub3QgbnVtZXJpYy4KKyAgICAgIHJldHVybiBNYXRoVXRpbDo6V2l0aGluRnJhY3Rpb25Pck1hcmdpbigKKyAgICAgICAgICB2YWx1ZV8xLCB2YWx1ZV8yLCBzdGF0aWNfY2FzdDxUPih0b2xlcmFuY2UtPmZyYWN0aW9uKSwKKyAgICAgICAgICBzdGF0aWNfY2FzdDxUPih0b2xlcmFuY2UtPm1hcmdpbikpOworICAgIH0KKyAgfQorfQorCitGaWVsZENvbXBhcmF0b3I6OkNvbXBhcmlzb25SZXN1bHQgRGVmYXVsdEZpZWxkQ29tcGFyYXRvcjo6UmVzdWx0RnJvbUJvb2xlYW4oCisgICAgYm9vbCBib29sZWFuX3Jlc3VsdCkgY29uc3QgeworICByZXR1cm4gYm9vbGVhbl9yZXN1bHQgPyBGaWVsZENvbXBhcmF0b3I6OlNBTUUgOiBGaWVsZENvbXBhcmF0b3I6OkRJRkZFUkVOVDsKK30KKworfSAgLy8gbmFtZXNwYWNlIHV0aWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ZpZWxkX2NvbXBhcmF0b3IuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9maWVsZF9jb21wYXJhdG9yLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGI4M2M2OQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9maWVsZF9jb21wYXJhdG9yLmgKQEAgLTAsMCArMSwyNTkgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtzcm9rYUBnb29nbGUuY29tIChLcnp5c3p0b2YgU3Jva2EpCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX1VUSUxfRklFTERfQ09NUEFSQVRPUl9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1VUSUxfRklFTERfQ09NUEFSQVRPUl9IX18KKworI2luY2x1ZGUgPG1hcD4KKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworY2xhc3MgTWVzc2FnZTsKK2NsYXNzIEVudW1WYWx1ZURlc2NyaXB0b3I7CitjbGFzcyBGaWVsZERlc2NyaXB0b3I7CisKK25hbWVzcGFjZSB1dGlsIHsKKworY2xhc3MgRmllbGRDb250ZXh0OworCisvLyBCYXNlIGNsYXNzIHNwZWNpZnlpbmcgdGhlIGludGVyZmFjZSBmb3IgY29tcGFyaW5nIHByb3RvY29sIGJ1ZmZlciBmaWVsZHMuCisvLyBSZWd1bGFyIHVzZXJzIHNob3VsZCBjb25zaWRlciB1c2luZyBvciBzdWJjbGFzc2luZyBEZWZhdWx0RmllbGRDb21wYXJhdG9yCisvLyByYXRoZXIgdGhhbiB0aGlzIGludGVyZmFjZS4KKy8vIEN1cnJlbnRseSwgdGhpcyBkb2VzIG5vdCBzdXBwb3J0IGNvbXBhcmluZyB1bmtub3duIGZpZWxkcy4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBGaWVsZENvbXBhcmF0b3IgeworIHB1YmxpYzoKKyAgRmllbGRDb21wYXJhdG9yKCk7CisgIHZpcnR1YWwgfkZpZWxkQ29tcGFyYXRvcigpOworCisgIGVudW0gQ29tcGFyaXNvblJlc3VsdCB7CisgICAgU0FNRSwgICAgICAgLy8gQ29tcGFyZWQgZmllbGRzIGFyZSBlcXVhbC4gSW4gY2FzZSBvZiBjb21wYXJpbmcgc3VibWVzc2FnZXMsCisgICAgICAgICAgICAgICAgLy8gdXNlciBzaG91bGQgbm90IHJlY3Vyc2l2ZWx5IGNvbXBhcmUgdGhlaXIgY29udGVudHMuCisgICAgRElGRkVSRU5ULCAgLy8gQ29tcGFyZWQgZmllbGRzIGFyZSBkaWZmZXJlbnQuIEluIGNhc2Ugb2YgY29tcGFyaW5nCisgICAgICAgICAgICAgICAgLy8gc3VibWVzc2FnZXMsIHVzZXIgc2hvdWxkIG5vdCByZWN1cnNpdmVseSBjb21wYXJlIHRoZWlyCisgICAgICAgICAgICAgICAgLy8gY29udGVudHMuCisgICAgUkVDVVJTRSwgICAgLy8gQ29tcGFyZWQgc3VibWVzc2FnZXMgbmVlZCB0byBiZSBjb21wYXJlZCByZWN1cnNpdmVseS4KKyAgICAgICAgICAgICAgICAvLyBGaWVsZENvbXBhcmF0b3IgZG9lcyBub3Qgc3BlY2lmeSB0aGUgc2VtYW50aWNzIG9mIHJlY3Vyc2l2ZQorICAgICAgICAgICAgICAgIC8vIGNvbXBhcmlzb24uIFRoaXMgdmFsdWUgc2hvdWxkIG5vdCBiZSByZXR1cm5lZCBmb3Igc2ltcGxlCisgICAgICAgICAgICAgICAgLy8gdmFsdWVzLgorICB9OworCisgIC8vIENvbXBhcmVzIHRoZSB2YWx1ZXMgb2YgYSBmaWVsZCBpbiB0d28gcHJvdG9jb2wgYnVmZmVyIG1lc3NhZ2VzLgorICAvLyBSZXR1cm5zIFNBTUUgb3IgRElGRkVSRU5UIGZvciBzaW1wbGUgdmFsdWVzLCBhbmQgU0FNRSwgRElGRkVSRU5UIG9yIFJFQ1VSU0UKKyAgLy8gZm9yIHN1Ym1lc3NhZ2VzLiBSZXR1cm5pbmcgUkVDVVJTRSBmb3IgZmllbGRzIG5vdCBiZWluZyBzdWJtZXNzYWdlcyBpcworICAvLyBpbGxlZ2FsLgorICAvLyBJbiBjYXNlIHRoZSBnaXZlbiBGaWVsZERlc2NyaXB0b3IgcG9pbnRzIHRvIGEgcmVwZWF0ZWQgZmllbGQsIHRoZSBpbmRpY2VzCisgIC8vIG5lZWQgdG8gYmUgdmFsaWQuIE90aGVyd2lzZSB0aGV5IHNob3VsZCBiZSBpZ25vcmVkLgorICAvLworICAvLyBGaWVsZENvbnRleHQgY29udGFpbnMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHNwZWNpZmljIGluc3RhbmNlcyBvZiB0aGUKKyAgLy8gZmllbGRzIGJlaW5nIGNvbXBhcmVkLCB2ZXJzdXMgRmllbGREZXNjcmlwdG9yIHdoaWNoIG9ubHkgY29udGFpbnMgZ2VuZXJhbAorICAvLyB0eXBlIGluZm9ybWF0aW9uIGFib3V0IHRoZSBmaWVsZHMuCisgIHZpcnR1YWwgQ29tcGFyaXNvblJlc3VsdCBDb21wYXJlKAorICAgICAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgbWVzc2FnZV8xLAorICAgICAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgbWVzc2FnZV8yLAorICAgICAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgIGludCBpbmRleF8xLCBpbnQgaW5kZXhfMiwKKyAgICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OnV0aWw6OkZpZWxkQ29udGV4dCogZmllbGRfY29udGV4dCkgPSAwOworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEZpZWxkQ29tcGFyYXRvcik7Cit9OworCisvLyBCYXNpYyBpbXBsZW1lbnRhdGlvbiBvZiBGaWVsZENvbXBhcmF0b3IuICBTdXBwb3J0cyBmb3VyIG1vZGVzIG9mIGZsb2F0aW5nCisvLyBwb2ludCB2YWx1ZSBjb21wYXJpc29uOiBleGFjdCwgYXBwcm94aW1hdGUgdXNpbmcgTWF0aFV0aWw6OkFsbW9zdEVxdWFsCisvLyBtZXRob2QsIGFuZCBhcmJpdHJhcmlsbHkgcHJlY2lzZSB1c2luZyBNYXRoVXRpbDo6V2l0aGluRnJhY3Rpb25Pck1hcmdpbi4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBEZWZhdWx0RmllbGRDb21wYXJhdG9yIDogcHVibGljIEZpZWxkQ29tcGFyYXRvciB7CisgcHVibGljOgorICBlbnVtIEZsb2F0Q29tcGFyaXNvbiB7CisgICAgIEVYQUNULCAgICAgICAgICAgICAgIC8vIEZsb2F0cyBhbmQgZG91YmxlcyBhcmUgY29tcGFyZWQgZXhhY3RseS4KKyAgICAgQVBQUk9YSU1BVEUsICAgICAgICAgLy8gRmxvYXRzIGFuZCBkb3VibGVzIGFyZSBjb21wYXJlZCB1c2luZyB0aGUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTWF0aFV0aWw6OkFsbW9zdEVxdWFsIG1ldGhvZCBvcgorICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBNYXRoVXRpbDo6V2l0aGluRnJhY3Rpb25Pck1hcmdpbiBtZXRob2QuCisgICAgIC8vIFRPRE8oa3Nyb2thKTogSW50cm9kdWNlIHRoaXJkIHZhbHVlIHRvIGRpZmZlcmVuY2lhdGUgdXNlcyBvZiBBbG1vc3RFcXVhbAorICAgICAvLyAgICAgICAgICAgICAgIGFuZCBXaXRoaW5GcmFjdGlvbk9yTWFyZ2luLgorICB9OworCisgIC8vIENyZWF0ZXMgbmV3IGNvbXBhcmF0b3Igd2l0aCBmbG9hdCBjb21wYXJpc29uIHNldCB0byBFWEFDVC4KKyAgRGVmYXVsdEZpZWxkQ29tcGFyYXRvcigpOworCisgIHZpcnR1YWwgfkRlZmF1bHRGaWVsZENvbXBhcmF0b3IoKTsKKworICB2aXJ0dWFsIENvbXBhcmlzb25SZXN1bHQgQ29tcGFyZSgKKyAgICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIG1lc3NhZ2VfMSwKKyAgICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIG1lc3NhZ2VfMiwKKyAgICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICBpbnQgaW5kZXhfMSwgaW50IGluZGV4XzIsCisgICAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjp1dGlsOjpGaWVsZENvbnRleHQqIGZpZWxkX2NvbnRleHQpOworCisgIHZvaWQgc2V0X2Zsb2F0X2NvbXBhcmlzb24oRmxvYXRDb21wYXJpc29uIGZsb2F0X2NvbXBhcmlzb24pIHsKKyAgICBmbG9hdF9jb21wYXJpc29uXyA9IGZsb2F0X2NvbXBhcmlzb247CisgIH0KKworICBGbG9hdENvbXBhcmlzb24gZmxvYXRfY29tcGFyaXNvbigpIGNvbnN0IHsKKyAgICByZXR1cm4gZmxvYXRfY29tcGFyaXNvbl87CisgIH0KKworICAvLyBTZXQgd2hldGhlciB0aGUgRmllbGRDb21wYXJhdG9yIHNoYWxsIHRyZWF0IGZsb2F0cyBvciBkb3VibGVzIHRoYXQgYXJlIGJvdGgKKyAgLy8gTmFOIGFzIGVxdWFsICh0cmVhdF9uYW5fYXNfZXF1YWwgPSB0cnVlKSBvciBhcyBkaWZmZXJlbnQKKyAgLy8gKHRyZWF0X25hbl9hc19lcXVhbCA9IGZhbHNlKS4gRGVmYXVsdCBpcyB0cmVhdGluZyBOYU5zIGFsd2F5cyBhcyBkaWZmZXJlbnQuCisgIHZvaWQgc2V0X3RyZWF0X25hbl9hc19lcXVhbChib29sIHRyZWF0X25hbl9hc19lcXVhbCkgeworICAgIHRyZWF0X25hbl9hc19lcXVhbF8gPSB0cmVhdF9uYW5fYXNfZXF1YWw7CisgIH0KKworICBib29sIHRyZWF0X25hbl9hc19lcXVhbCgpIGNvbnN0IHsKKyAgICByZXR1cm4gdHJlYXRfbmFuX2FzX2VxdWFsXzsKKyAgfQorCisgIC8vIFNldHMgdGhlIGZyYWN0aW9uIGFuZCBtYXJnaW4gZm9yIHRoZSBmbG9hdCBjb21wYXJpc29uIG9mIGEgZ2l2ZW4gZmllbGQuCisgIC8vIFVzZXMgTWF0aFV0aWw6OldpdGhpbkZyYWN0aW9uT3JNYXJnaW4gdG8gY29tcGFyZSB0aGUgdmFsdWVzLgorICAvLworICAvLyBSRVFVSVJFUzogZmllbGQtPmNwcF90eXBlID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9ET1VCTEUgb3IKKyAgLy8gICAgICAgICAgIGZpZWxkLT5jcHBfdHlwZSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRkxPQVQKKyAgLy8gUkVRVUlSRVM6IGZsb2F0X2NvbXBhcmlzb25fID09IEFQUFJPWElNQVRFCisgIHZvaWQgU2V0RnJhY3Rpb25BbmRNYXJnaW4oY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgZG91YmxlIGZyYWN0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvdWJsZSBtYXJnaW4pOworCisgIC8vIFNldHMgdGhlIGZyYWN0aW9uIGFuZCBtYXJnaW4gZm9yIHRoZSBmbG9hdCBjb21wYXJpc29uIG9mIGFsbCBmbG9hdCBhbmQKKyAgLy8gZG91YmxlIGZpZWxkcywgdW5sZXNzIGEgZmllbGQgaGFzIGJlZW4gZ2l2ZW4gYSBzcGVjaWZpYyBzZXR0aW5nIHZpYQorICAvLyBTZXRGcmFjdGlvbkFuZE1hcmdpbigpIGFib3ZlLgorICAvLyBVc2VzIE1hdGhVdGlsOjpXaXRoaW5GcmFjdGlvbk9yTWFyZ2luIHRvIGNvbXBhcmUgdGhlIHZhbHVlcy4KKyAgLy8KKyAgLy8gUkVRVUlSRVM6IGZsb2F0X2NvbXBhcmlzb25fID09IEFQUFJPWElNQVRFCisgIHZvaWQgU2V0RGVmYXVsdEZyYWN0aW9uQW5kTWFyZ2luKGRvdWJsZSBmcmFjdGlvbiwgZG91YmxlIG1hcmdpbik7CisKKyBwcml2YXRlOgorICAvLyBEZWZpbmVzIHRoZSB0b2xlcmFuY2UgZm9yIGZsb2F0aW5nIHBvaW50IGNvbXBhcmlzb24gKGZyYWN0aW9uIGFuZCBtYXJnaW4pLgorICBzdHJ1Y3QgVG9sZXJhbmNlIHsKKyAgICBkb3VibGUgZnJhY3Rpb247CisgICAgZG91YmxlIG1hcmdpbjsKKyAgICBUb2xlcmFuY2UoKQorICAgICAgICA6IGZyYWN0aW9uKDAuMCksCisgICAgICAgICAgbWFyZ2luKDAuMCkge30KKyAgICBUb2xlcmFuY2UoZG91YmxlIGYsIGRvdWJsZSBtKQorICAgICAgICA6IGZyYWN0aW9uKGYpLAorICAgICAgICAgIG1hcmdpbihtKSB7fQorICB9OworCisgIC8vIERlZmluZXMgdGhlIG1hcCB0byBzdG9yZSB0aGUgdG9sZXJhbmNlcyBmb3IgZmxvYXRpbmcgcG9pbnQgY29tcGFyaXNvbi4KKyAgdHlwZWRlZiBtYXA8Y29uc3QgRmllbGREZXNjcmlwdG9yKiwgVG9sZXJhbmNlPiBUb2xlcmFuY2VNYXA7CisKKyAgLy8gVGhlIGZvbGxvd2luZyBtZXRob2RzIGdldCBleGVjdXRlZCB3aGVuIENvbXBhcmVGaWVsZHMgaXMgY2FsbGVkIGZvciB0aGUKKyAgLy8gYmFzaWMgdHlwZXMgKGluc3RlYWQgb2Ygc3VibWVzc2FnZXMpLiBUaGV5IHJldHVybiB0cnVlIG9uIHN1Y2Nlc3MuIE9uZQorICAvLyBjYW4gdXNlIFJlc3VsdEZyb21Cb29sZWFuKCkgdG8gY29udmVydCB0aGF0IGJvb2xlYW4gdG8gYSBDb21wYXJpc29uUmVzdWx0CisgIC8vIHZhbHVlLgorICBib29sIENvbXBhcmVCb29sKGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvciYgZmllbGQsCisgICAgICAgICAgICAgICAgICAgYm9vbCB2YWx1ZV8xLCBib29sIHZhbHVlXzIpIHsKKyAgICByZXR1cm4gdmFsdWVfMSA9PSB2YWx1ZV8yOworICB9CisKKyAgLy8gVXNlcyBDb21wYXJlRG91YmxlT3JGbG9hdCwgYSBoZWxwZXIgZnVuY3Rpb24gdXNlZCBieSBib3RoIENvbXBhcmVEb3VibGUgYW5kCisgIC8vIENvbXBhcmVGbG9hdC4KKyAgYm9vbCBDb21wYXJlRG91YmxlKGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvciYgZmllbGQsCisgICAgICAgICAgICAgICAgICAgICBkb3VibGUgdmFsdWVfMSwgZG91YmxlIHZhbHVlXzIpOworCisgIGJvb2wgQ29tcGFyZUVudW0oY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yJiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiB2YWx1ZV8xLAorICAgICAgICAgICAgICAgICAgIGNvbnN0IEVudW1WYWx1ZURlc2NyaXB0b3IqIHZhbHVlXzIpOworCisgIC8vIFVzZXMgQ29tcGFyZURvdWJsZU9yRmxvYXQsIGEgaGVscGVyIGZ1bmN0aW9uIHVzZWQgYnkgYm90aCBDb21wYXJlRG91YmxlIGFuZAorICAvLyBDb21wYXJlRmxvYXQuCisgIGJvb2wgQ29tcGFyZUZsb2F0KGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvciYgZmllbGQsCisgICAgICAgICAgICAgICAgICAgIGZsb2F0IHZhbHVlXzEsIGZsb2F0IHZhbHVlXzIpOworCisgIGJvb2wgQ29tcGFyZUludDMyKGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvciYgZmllbGQsCisgICAgICAgICAgICAgICAgICAgIGludDMyIHZhbHVlXzEsIGludDMyIHZhbHVlXzIpIHsKKyAgICByZXR1cm4gdmFsdWVfMSA9PSB2YWx1ZV8yOworICB9CisKKyAgYm9vbCBDb21wYXJlSW50NjQoY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yJiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgaW50NjQgdmFsdWVfMSwgaW50NjQgdmFsdWVfMikgeworICAgIHJldHVybiB2YWx1ZV8xID09IHZhbHVlXzI7CisgIH0KKworICBib29sIENvbXBhcmVTdHJpbmcoY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yJiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgdmFsdWVfMSwgY29uc3Qgc3RyaW5nJiB2YWx1ZV8yKSB7CisgICAgcmV0dXJuIHZhbHVlXzEgPT0gdmFsdWVfMjsKKyAgfQorCisgIGJvb2wgQ29tcGFyZVVJbnQzMihjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3ImIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgdWludDMyIHZhbHVlXzEsIHVpbnQzMiB2YWx1ZV8yKSB7CisgICAgcmV0dXJuIHZhbHVlXzEgPT0gdmFsdWVfMjsKKyAgfQorCisgIGJvb2wgQ29tcGFyZVVJbnQ2NChjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3ImIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgdWludDY0IHZhbHVlXzEsIHVpbnQ2NCB2YWx1ZV8yKSB7CisgICAgcmV0dXJuIHZhbHVlXzEgPT0gdmFsdWVfMjsKKyAgfQorCisgIC8vIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCBieSBDb21wYXJlRG91YmxlIGFuZCBDb21wYXJlRmxvYXQgdG8gYXZvaWQgY29kZQorICAvLyBkdXBsaWNhdGlvbi4gVGhlcmUgYXJlIG5vIGNoZWNrcyBkb25lIGFnYWluc3QgdHlwZXMgb2YgdGhlIHZhbHVlcyBwYXNzZWQsCisgIC8vIGJ1dCBpdCdzIGxpa2VseSB0byBmYWlsIGlmIHBhc3NlZCBub24tbnVtZXJpYyBhcmd1bWVudHMuCisgIHRlbXBsYXRlPHR5cGVuYW1lIFQ+CisgIGJvb2wgQ29tcGFyZURvdWJsZU9yRmxvYXQoY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yJiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBUIHZhbHVlXzEsIFQgdmFsdWVfMik7CisKKyAgLy8gUmV0dXJucyBGaWVsZENvbXBhcmF0b3I6OlNBTUUgaWYgYm9vbGVhbl9yZXN1bHQgaXMgdHJ1ZSBhbmQKKyAgLy8gRmllbGRDb21wYXJhdG9yOjpESUZGRVJFTlQgb3RoZXJ3aXNlLgorICBDb21wYXJpc29uUmVzdWx0IFJlc3VsdEZyb21Cb29sZWFuKGJvb2wgYm9vbGVhbl9yZXN1bHQpIGNvbnN0OworCisgIEZsb2F0Q29tcGFyaXNvbiBmbG9hdF9jb21wYXJpc29uXzsKKworICAvLyBJZiB0cnVlLCBmbG9hdHMgYW5kIGRvdWJsZXMgdGhhdCBhcmUgYm90aCBOYU4gYXJlIGNvbnNpZGVyZWQgdG8gYmUKKyAgLy8gZXF1YWwuIE90aGVyd2lzZSwgdHdvIGZsb2F0cyBvciBkb3VibGVzIHRoYXQgYXJlIE5hTiBhcmUgY29uc2lkZXJlZCB0byBiZQorICAvLyBkaWZmZXJlbnQuCisgIGJvb2wgdHJlYXRfbmFuX2FzX2VxdWFsXzsKKworICAvLyBUcnVlIGlmZiBkZWZhdWx0X3RvbGVyYW5jZV8gaGFzIGJlZW4gZXhwbGljaXRseSBzZXQuCisgIC8vCisgIC8vIElmIGZhbHNlLCB0aGVuIHRoZSBkZWZhdWx0IHRvbGVyYW5jZSBmb3IgZmxhb3RzIGFuZCBkb3VibGVzIGlzIHRoYXQgd2hpY2gKKyAgLy8gaXMgdXNlZCBieSBNYXRoVXRpbDo6QWxtb3N0RXF1YWxzKCkuCisgIGJvb2wgaGFzX2RlZmF1bHRfdG9sZXJhbmNlXzsKKworICAvLyBEZWZhdWx0IGZsb2F0L2RvdWJsZSB0b2xlcmFuY2UuIE9ubHkgbWVhbmluZ2Z1bCBpZgorICAvLyBoYXNfZGVmYXVsdF90b2xlcmFuY2VfID09IHRydWUuCisgIFRvbGVyYW5jZSBkZWZhdWx0X3RvbGVyYW5jZV87CisKKyAgLy8gRmllbGQtc3BlY2lmaWMgZmxvYXQvZG91YmxlIHRvbGVyYW5jZXMsIHdoaWNoIG92ZXJyaWRlIGFueSBkZWZhdWx0IGZvcgorICAvLyB0aG9zZSBwYXJ0aWN1bGFyIGZpZWxkcy4KKyAgVG9sZXJhbmNlTWFwIG1hcF90b2xlcmFuY2VfOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhEZWZhdWx0RmllbGRDb21wYXJhdG9yKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSB1dGlsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfVVRJTF9GSUVMRF9DT01QQVJBVE9SX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ZpZWxkX2NvbXBhcmF0b3JfdGVzdC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9maWVsZF9jb21wYXJhdG9yX3Rlc3QuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjNmN2Q1MQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9maWVsZF9jb21wYXJhdG9yX3Rlc3QuY2MKQEAgLTAsMCArMSw0ODkgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtzcm9rYUBnb29nbGUuY29tIChLcnp5c3p0b2YgU3Jva2EpCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9maWVsZF9jb21wYXJhdG9yLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9tYXRodXRpbC5oPgorLy8gVGhpcyBndGVzdCBoZWFkZXIgaXMgcHV0IGFmdGVyIG1hdGh1dGlsLmggaW50ZW50aW9uYWxseS4gV2UgaGF2ZSB0byBkbworLy8gdGhpcyBiZWNhdXNlIG1hdGh1dGlsLmggaW5jbHVkZXMgbWF0aGxpbWl0cy5oIHdoaWNoIHJlcXVpcmVzIGNtYXRoIG5vdAorLy8gYmVpbmcgaW5jbHVkZWQgdG8gY29tcGlsZSBvbiBzb21lIHZlcnNpb25zIG9mIGdjYzoKKy8vICAgaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9wcm90b2J1Zi9ibG9iLzgxOGM1ZWVlMDg4NDAzNTVkNzBkMmYzYmRmMWEyZjE3OTg2YTVlNzAvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHVicy9tYXRobGltaXRzLmgjTDQ4CisvLyBhbmQgdGhlIG9wZW5zb3VyY2UgdmVyc2lvbiBndGVzdC5oIGhlYWRlciBpbmNsdWRlcyBjbWF0aCB0cmFuc2l0aXZlbHkKKy8vIHNvbWVob3cuCisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIHV0aWwgeworbmFtZXNwYWNlIHsKKwordXNpbmcgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlczsKKworY2xhc3MgRGVmYXVsdEZpZWxkQ29tcGFyYXRvclRlc3QgOiBwdWJsaWMgOjp0ZXN0aW5nOjpUZXN0IHsKKyBwcm90ZWN0ZWQ6CisgIHZvaWQgU2V0VXAoKSB7CisgICAgZGVzY3JpcHRvcl8gPSBUZXN0QWxsVHlwZXM6OmRlc2NyaXB0b3IoKTsKKyAgfQorCisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3JfOworICBEZWZhdWx0RmllbGRDb21wYXJhdG9yIGNvbXBhcmF0b3JfOworICBUZXN0QWxsVHlwZXMgbWVzc2FnZV8xXzsKKyAgVGVzdEFsbFR5cGVzIG1lc3NhZ2VfMl87Cit9OworCitURVNUX0YoRGVmYXVsdEZpZWxkQ29tcGFyYXRvclRlc3QsIFJlY3Vyc2VzSW50b0dyb3VwKSB7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPQorICAgICAgZGVzY3JpcHRvcl8tPkZpbmRGaWVsZEJ5TmFtZSgib3B0aW9uYWxncm91cCIpOworICBFWFBFQ1RfRVEoRmllbGRDb21wYXJhdG9yOjpSRUNVUlNFLAorICAgICAgICAgICAgY29tcGFyYXRvcl8uQ29tcGFyZShtZXNzYWdlXzFfLCBtZXNzYWdlXzJfLCBmaWVsZCwgLTEsIC0xLCBOVUxMKSk7Cit9CisKK1RFU1RfRihEZWZhdWx0RmllbGRDb21wYXJhdG9yVGVzdCwgUmVjdXJzZXNJbnRvTmVzdGVkTWVzc2FnZSkgeworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0KKyAgICAgIGRlc2NyaXB0b3JfLT5GaW5kRmllbGRCeU5hbWUoIm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlIik7CisgIEVYUEVDVF9FUShGaWVsZENvbXBhcmF0b3I6OlJFQ1VSU0UsCisgICAgICAgICAgICBjb21wYXJhdG9yXy5Db21wYXJlKG1lc3NhZ2VfMV8sIG1lc3NhZ2VfMl8sIGZpZWxkLCAtMSwgLTEsIE5VTEwpKTsKK30KKworVEVTVF9GKERlZmF1bHRGaWVsZENvbXBhcmF0b3JUZXN0LCBSZWN1cnNlc0ludG9Gb3JlaWduTWVzc2FnZSkgeworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0KKyAgICAgIGRlc2NyaXB0b3JfLT5GaW5kRmllbGRCeU5hbWUoIm9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSIpOworICBFWFBFQ1RfRVEoRmllbGRDb21wYXJhdG9yOjpSRUNVUlNFLAorICAgICAgICAgICAgY29tcGFyYXRvcl8uQ29tcGFyZShtZXNzYWdlXzFfLCBtZXNzYWdlXzJfLCBmaWVsZCwgLTEsIC0xLCBOVUxMKSk7Cit9CisKK1RFU1RfRihEZWZhdWx0RmllbGRDb21wYXJhdG9yVGVzdCwgSW50MzJDb21wYXJpc29uKSB7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBkZXNjcmlwdG9yXy0+RmluZEZpZWxkQnlOYW1lKCJvcHRpb25hbF9pbnQzMiIpOworICBtZXNzYWdlXzFfLnNldF9vcHRpb25hbF9pbnQzMigxKTsKKyAgbWVzc2FnZV8yXy5zZXRfb3B0aW9uYWxfaW50MzIoMSk7CisKKyAgRVhQRUNUX0VRKEZpZWxkQ29tcGFyYXRvcjo6U0FNRSwKKyAgICAgICAgICAgIGNvbXBhcmF0b3JfLkNvbXBhcmUobWVzc2FnZV8xXywgbWVzc2FnZV8yXywgZmllbGQsIC0xLCAtMSwgTlVMTCkpOworCisgIG1lc3NhZ2VfMl8uc2V0X29wdGlvbmFsX2ludDMyKC0xKTsKKyAgRVhQRUNUX0VRKEZpZWxkQ29tcGFyYXRvcjo6RElGRkVSRU5ULAorICAgICAgICAgICAgY29tcGFyYXRvcl8uQ29tcGFyZShtZXNzYWdlXzFfLCBtZXNzYWdlXzJfLCBmaWVsZCwgLTEsIC0xLCBOVUxMKSk7Cit9CisKK1RFU1RfRihEZWZhdWx0RmllbGRDb21wYXJhdG9yVGVzdCwgSW50NjRDb21wYXJpc29uKSB7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBkZXNjcmlwdG9yXy0+RmluZEZpZWxkQnlOYW1lKCJvcHRpb25hbF9pbnQ2NCIpOworICBtZXNzYWdlXzFfLnNldF9vcHRpb25hbF9pbnQ2NCgxTCk7CisgIG1lc3NhZ2VfMl8uc2V0X29wdGlvbmFsX2ludDY0KDFMKTsKKworICBFWFBFQ1RfRVEoRmllbGRDb21wYXJhdG9yOjpTQU1FLAorICAgICAgICAgICAgY29tcGFyYXRvcl8uQ29tcGFyZShtZXNzYWdlXzFfLCBtZXNzYWdlXzJfLCBmaWVsZCwgLTEsIC0xLCBOVUxMKSk7CisKKyAgbWVzc2FnZV8yXy5zZXRfb3B0aW9uYWxfaW50NjQoLTFMKTsKKyAgRVhQRUNUX0VRKEZpZWxkQ29tcGFyYXRvcjo6RElGRkVSRU5ULAorICAgICAgICAgICAgY29tcGFyYXRvcl8uQ29tcGFyZShtZXNzYWdlXzFfLCBtZXNzYWdlXzJfLCBmaWVsZCwgLTEsIC0xLCBOVUxMKSk7Cit9CisKK1RFU1RfRihEZWZhdWx0RmllbGRDb21wYXJhdG9yVGVzdCwgVUludDMyQ29tcGFyaXNvbikgeworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0KKyAgICAgIGRlc2NyaXB0b3JfLT5GaW5kRmllbGRCeU5hbWUoIm9wdGlvbmFsX3VpbnQzMiIpOworICBtZXNzYWdlXzFfLnNldF9vcHRpb25hbF91aW50MzIoMSk7CisgIG1lc3NhZ2VfMl8uc2V0X29wdGlvbmFsX3VpbnQzMigxKTsKKworICBFWFBFQ1RfRVEoRmllbGRDb21wYXJhdG9yOjpTQU1FLAorICAgICAgICAgICAgY29tcGFyYXRvcl8uQ29tcGFyZShtZXNzYWdlXzFfLCBtZXNzYWdlXzJfLCBmaWVsZCwgLTEsIC0xLCBOVUxMKSk7CisKKyAgbWVzc2FnZV8yXy5zZXRfb3B0aW9uYWxfdWludDMyKDIpOworICBFWFBFQ1RfRVEoRmllbGRDb21wYXJhdG9yOjpESUZGRVJFTlQsCisgICAgICAgICAgICBjb21wYXJhdG9yXy5Db21wYXJlKG1lc3NhZ2VfMV8sIG1lc3NhZ2VfMl8sIGZpZWxkLCAtMSwgLTEsIE5VTEwpKTsKK30KKworVEVTVF9GKERlZmF1bHRGaWVsZENvbXBhcmF0b3JUZXN0LCBVSW50NjRDb21wYXJpc29uKSB7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPQorICAgICAgZGVzY3JpcHRvcl8tPkZpbmRGaWVsZEJ5TmFtZSgib3B0aW9uYWxfdWludDY0Iik7CisgIG1lc3NhZ2VfMV8uc2V0X29wdGlvbmFsX3VpbnQ2NCgxTCk7CisgIG1lc3NhZ2VfMl8uc2V0X29wdGlvbmFsX3VpbnQ2NCgxTCk7CisKKyAgRVhQRUNUX0VRKEZpZWxkQ29tcGFyYXRvcjo6U0FNRSwKKyAgICAgICAgICAgIGNvbXBhcmF0b3JfLkNvbXBhcmUobWVzc2FnZV8xXywgbWVzc2FnZV8yXywgZmllbGQsIC0xLCAtMSwgTlVMTCkpOworCisgIG1lc3NhZ2VfMl8uc2V0X29wdGlvbmFsX3VpbnQ2NCgyTCk7CisgIEVYUEVDVF9FUShGaWVsZENvbXBhcmF0b3I6OkRJRkZFUkVOVCwKKyAgICAgICAgICAgIGNvbXBhcmF0b3JfLkNvbXBhcmUobWVzc2FnZV8xXywgbWVzc2FnZV8yXywgZmllbGQsIC0xLCAtMSwgTlVMTCkpOworfQorCitURVNUX0YoRGVmYXVsdEZpZWxkQ29tcGFyYXRvclRlc3QsIEJvb2xlYW5Db21wYXJpc29uKSB7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPQorICAgICAgZGVzY3JpcHRvcl8tPkZpbmRGaWVsZEJ5TmFtZSgib3B0aW9uYWxfYm9vbCIpOworICBtZXNzYWdlXzFfLnNldF9vcHRpb25hbF9ib29sKHRydWUpOworICBtZXNzYWdlXzJfLnNldF9vcHRpb25hbF9ib29sKHRydWUpOworCisgIEVYUEVDVF9FUShGaWVsZENvbXBhcmF0b3I6OlNBTUUsCisgICAgICAgICAgICBjb21wYXJhdG9yXy5Db21wYXJlKG1lc3NhZ2VfMV8sIG1lc3NhZ2VfMl8sIGZpZWxkLCAtMSwgLTEsIE5VTEwpKTsKKworICBtZXNzYWdlXzJfLnNldF9vcHRpb25hbF9ib29sKGZhbHNlKTsKKyAgRVhQRUNUX0VRKEZpZWxkQ29tcGFyYXRvcjo6RElGRkVSRU5ULAorICAgICAgICAgICAgY29tcGFyYXRvcl8uQ29tcGFyZShtZXNzYWdlXzFfLCBtZXNzYWdlXzJfLCBmaWVsZCwgLTEsIC0xLCBOVUxMKSk7Cit9CisKK1RFU1RfRihEZWZhdWx0RmllbGRDb21wYXJhdG9yVGVzdCwgRW51bUNvbXBhcmlzb24pIHsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9CisgICAgICBkZXNjcmlwdG9yXy0+RmluZEZpZWxkQnlOYW1lKCJvcHRpb25hbF9uZXN0ZWRfZW51bSIpOworICBtZXNzYWdlXzFfLnNldF9vcHRpb25hbF9uZXN0ZWRfZW51bShUZXN0QWxsVHlwZXM6OkJBUik7CisgIG1lc3NhZ2VfMl8uc2V0X29wdGlvbmFsX25lc3RlZF9lbnVtKFRlc3RBbGxUeXBlczo6QkFSKTsKKworICBFWFBFQ1RfRVEoRmllbGRDb21wYXJhdG9yOjpTQU1FLAorICAgICAgICAgICAgY29tcGFyYXRvcl8uQ29tcGFyZShtZXNzYWdlXzFfLCBtZXNzYWdlXzJfLCBmaWVsZCwgLTEsIC0xLCBOVUxMKSk7CisKKyAgbWVzc2FnZV8yXy5zZXRfb3B0aW9uYWxfbmVzdGVkX2VudW0oVGVzdEFsbFR5cGVzOjpCQVopOworICBFWFBFQ1RfRVEoRmllbGRDb21wYXJhdG9yOjpESUZGRVJFTlQsCisgICAgICAgICAgICBjb21wYXJhdG9yXy5Db21wYXJlKG1lc3NhZ2VfMV8sIG1lc3NhZ2VfMl8sIGZpZWxkLCAtMSwgLTEsIE5VTEwpKTsKK30KKworVEVTVF9GKERlZmF1bHRGaWVsZENvbXBhcmF0b3JUZXN0LCBTdHJpbmdDb21wYXJpc29uKSB7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPQorICAgICAgZGVzY3JpcHRvcl8tPkZpbmRGaWVsZEJ5TmFtZSgib3B0aW9uYWxfc3RyaW5nIik7CisgIG1lc3NhZ2VfMV8uc2V0X29wdGlvbmFsX3N0cmluZygiZm9vIik7CisgIG1lc3NhZ2VfMl8uc2V0X29wdGlvbmFsX3N0cmluZygiZm9vIik7CisKKyAgRVhQRUNUX0VRKEZpZWxkQ29tcGFyYXRvcjo6U0FNRSwKKyAgICAgICAgICAgIGNvbXBhcmF0b3JfLkNvbXBhcmUobWVzc2FnZV8xXywgbWVzc2FnZV8yXywgZmllbGQsIC0xLCAtMSwgTlVMTCkpOworCisgIG1lc3NhZ2VfMl8uc2V0X29wdGlvbmFsX3N0cmluZygiYmFyIik7CisgIEVYUEVDVF9FUShGaWVsZENvbXBhcmF0b3I6OkRJRkZFUkVOVCwKKyAgICAgICAgICAgIGNvbXBhcmF0b3JfLkNvbXBhcmUobWVzc2FnZV8xXywgbWVzc2FnZV8yXywgZmllbGQsIC0xLCAtMSwgTlVMTCkpOworfQorCitURVNUX0YoRGVmYXVsdEZpZWxkQ29tcGFyYXRvclRlc3QsIEZsb2F0aW5nUG9pbnRDb21wYXJpc29uRXhhY3QpIHsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZF9mbG9hdCA9CisgICAgICBkZXNjcmlwdG9yXy0+RmluZEZpZWxkQnlOYW1lKCJvcHRpb25hbF9mbG9hdCIpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkX2RvdWJsZSA9CisgICAgICBkZXNjcmlwdG9yXy0+RmluZEZpZWxkQnlOYW1lKCJvcHRpb25hbF9kb3VibGUiKTsKKworICBtZXNzYWdlXzFfLnNldF9vcHRpb25hbF9mbG9hdCgwLjFmKTsKKyAgbWVzc2FnZV8yXy5zZXRfb3B0aW9uYWxfZmxvYXQoMC4xZik7CisgIG1lc3NhZ2VfMV8uc2V0X29wdGlvbmFsX2RvdWJsZSgwLjEpOworICBtZXNzYWdlXzJfLnNldF9vcHRpb25hbF9kb3VibGUoMC4xKTsKKworICBFWFBFQ1RfRVEoRmllbGRDb21wYXJhdG9yOjpTQU1FLAorICAgICAgICAgICAgY29tcGFyYXRvcl8uQ29tcGFyZShtZXNzYWdlXzFfLCBtZXNzYWdlXzJfLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZF9mbG9hdCwgLTEsIC0xLCBOVUxMKSk7CisgIEVYUEVDVF9FUShGaWVsZENvbXBhcmF0b3I6OlNBTUUsCisgICAgICAgICAgICBjb21wYXJhdG9yXy5Db21wYXJlKG1lc3NhZ2VfMV8sIG1lc3NhZ2VfMl8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkX2RvdWJsZSwgLTEsIC0xLCBOVUxMKSk7CisKKyAgbWVzc2FnZV8yXy5zZXRfb3B0aW9uYWxfZmxvYXQoMC4yZik7CisgIG1lc3NhZ2VfMl8uc2V0X29wdGlvbmFsX2RvdWJsZSgwLjIpOworCisgIEVYUEVDVF9FUShGaWVsZENvbXBhcmF0b3I6OkRJRkZFUkVOVCwKKyAgICAgICAgICAgIGNvbXBhcmF0b3JfLkNvbXBhcmUobWVzc2FnZV8xXywgbWVzc2FnZV8yXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGRfZmxvYXQsIC0xLCAtMSwgTlVMTCkpOworICBFWFBFQ1RfRVEoRmllbGRDb21wYXJhdG9yOjpESUZGRVJFTlQsCisgICAgICAgICAgICBjb21wYXJhdG9yXy5Db21wYXJlKG1lc3NhZ2VfMV8sIG1lc3NhZ2VfMl8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkX2RvdWJsZSwgLTEsIC0xLCBOVUxMKSk7Cit9CisKK1RFU1RfRihEZWZhdWx0RmllbGRDb21wYXJhdG9yVGVzdCwgRmxvYXRpbmdQb2ludENvbXBhcmlzb25BcHByb3hpbWF0ZSkgeworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkX2Zsb2F0ID0KKyAgICAgIGRlc2NyaXB0b3JfLT5GaW5kRmllbGRCeU5hbWUoIm9wdGlvbmFsX2Zsb2F0Iik7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGRfZG91YmxlID0KKyAgICAgIGRlc2NyaXB0b3JfLT5GaW5kRmllbGRCeU5hbWUoIm9wdGlvbmFsX2RvdWJsZSIpOworCisgIG1lc3NhZ2VfMV8uc2V0X29wdGlvbmFsX2Zsb2F0KDIuMzAwMDA1Zik7CisgIG1lc3NhZ2VfMl8uc2V0X29wdGlvbmFsX2Zsb2F0KDIuMzAwMDA2Zik7CisgIG1lc3NhZ2VfMV8uc2V0X29wdGlvbmFsX2RvdWJsZSgyLjMwMDAwMDAwMDAwMDAwMDMpOworICBtZXNzYWdlXzJfLnNldF9vcHRpb25hbF9kb3VibGUoMi4zMDAwMDAwMDAwMDAwMDA3KTsKKworICAvLyBBcHByb3hpbWF0ZSBjb21wYXJpc29uIGRlcGVuZHMgb24gTWF0aFV0aWwsIHNvIHdlIGFzc2VydCBvbiBNYXRoVXRpbAorICAvLyByZXN1bHRzIGZpcnN0IHRvIGNoZWNrIGlmIHRoYXQncyB3aGVyZSB0aGUgZmFpbHVyZSB3YXMgaW50cm9kdWNlZC4KKyAgQVNTRVJUX05FKG1lc3NhZ2VfMV8ub3B0aW9uYWxfZmxvYXQoKSwgbWVzc2FnZV8yXy5vcHRpb25hbF9mbG9hdCgpKTsKKyAgQVNTRVJUX05FKG1lc3NhZ2VfMV8ub3B0aW9uYWxfZG91YmxlKCksIG1lc3NhZ2VfMl8ub3B0aW9uYWxfZG91YmxlKCkpOworICBBU1NFUlRfVFJVRShNYXRoVXRpbDo6QWxtb3N0RXF1YWxzKG1lc3NhZ2VfMV8ub3B0aW9uYWxfZmxvYXQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlXzJfLm9wdGlvbmFsX2Zsb2F0KCkpKTsKKyAgQVNTRVJUX1RSVUUoTWF0aFV0aWw6OkFsbW9zdEVxdWFscyhtZXNzYWdlXzFfLm9wdGlvbmFsX2RvdWJsZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2VfMl8ub3B0aW9uYWxfZG91YmxlKCkpKTsKKworICAvLyBEZWZhdWx0RmllbGRDb21wYXJhdG9yJ3MgZGVmYXVsdCBmbG9hdCBjb21wYXJpc29uIG1vZGUgaXMgRVhBQ1QuCisgIEFTU0VSVF9FUShEZWZhdWx0RmllbGRDb21wYXJhdG9yOjpFWEFDVCwgY29tcGFyYXRvcl8uZmxvYXRfY29tcGFyaXNvbigpKTsKKyAgRVhQRUNUX0VRKEZpZWxkQ29tcGFyYXRvcjo6RElGRkVSRU5ULAorICAgICAgICAgICAgY29tcGFyYXRvcl8uQ29tcGFyZShtZXNzYWdlXzFfLCBtZXNzYWdlXzJfLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZF9mbG9hdCwgLTEsIC0xLCBOVUxMKSk7CisgIEVYUEVDVF9FUShGaWVsZENvbXBhcmF0b3I6OkRJRkZFUkVOVCwKKyAgICAgICAgICAgIGNvbXBhcmF0b3JfLkNvbXBhcmUobWVzc2FnZV8xXywgbWVzc2FnZV8yXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGRfZG91YmxlLCAtMSwgLTEsIE5VTEwpKTsKKworICBjb21wYXJhdG9yXy5zZXRfZmxvYXRfY29tcGFyaXNvbihEZWZhdWx0RmllbGRDb21wYXJhdG9yOjpBUFBST1hJTUFURSk7CisKKyAgRVhQRUNUX0VRKEZpZWxkQ29tcGFyYXRvcjo6U0FNRSwKKyAgICAgICAgICAgIGNvbXBhcmF0b3JfLkNvbXBhcmUobWVzc2FnZV8xXywgbWVzc2FnZV8yXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGRfZmxvYXQsIC0xLCAtMSwgTlVMTCkpOworICBFWFBFQ1RfRVEoRmllbGRDb21wYXJhdG9yOjpTQU1FLAorICAgICAgICAgICAgY29tcGFyYXRvcl8uQ29tcGFyZShtZXNzYWdlXzFfLCBtZXNzYWdlXzJfLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZF9kb3VibGUsIC0xLCAtMSwgTlVMTCkpOworfQorCitURVNUX0YoRGVmYXVsdEZpZWxkQ29tcGFyYXRvclRlc3QsIEZsb2F0aW5nUG9pbnRDb21wYXJpc29uVHJlYXROYU5zQXNFcXVhbCkgeworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkX2Zsb2F0ID0KKyAgICAgIGRlc2NyaXB0b3JfLT5GaW5kRmllbGRCeU5hbWUoIm9wdGlvbmFsX2Zsb2F0Iik7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGRfZG91YmxlID0KKyAgICAgIGRlc2NyaXB0b3JfLT5GaW5kRmllbGRCeU5hbWUoIm9wdGlvbmFsX2RvdWJsZSIpOworCisgIG1lc3NhZ2VfMV8uc2V0X29wdGlvbmFsX2Zsb2F0KE1hdGhMaW1pdHM8ZmxvYXQ+OjprTmFOKTsKKyAgbWVzc2FnZV8yXy5zZXRfb3B0aW9uYWxfZmxvYXQoTWF0aExpbWl0czxmbG9hdD46OmtOYU4pOworICBtZXNzYWdlXzFfLnNldF9vcHRpb25hbF9kb3VibGUoTWF0aExpbWl0czxkb3VibGU+OjprTmFOKTsKKyAgbWVzc2FnZV8yXy5zZXRfb3B0aW9uYWxfZG91YmxlKE1hdGhMaW1pdHM8ZG91YmxlPjo6a05hTik7CisKKyAgLy8gRGVmYXVsdEZpZWxkQ29tcGFyYXRvcidzIGRlZmF1bHQgZmxvYXQgY29tcGFyaXNvbiBtb2RlIGlzIEVYQUNUIHdpdGgKKyAgLy8gdHJlYXRpbmcgTmFOcyBhcyBkaWZmZXJlbnQuCisgIEFTU0VSVF9FUShEZWZhdWx0RmllbGRDb21wYXJhdG9yOjpFWEFDVCwgY29tcGFyYXRvcl8uZmxvYXRfY29tcGFyaXNvbigpKTsKKyAgQVNTRVJUX0VRKGZhbHNlLCBjb21wYXJhdG9yXy50cmVhdF9uYW5fYXNfZXF1YWwoKSk7CisgIEVYUEVDVF9FUShGaWVsZENvbXBhcmF0b3I6OkRJRkZFUkVOVCwKKyAgICAgICAgICAgIGNvbXBhcmF0b3JfLkNvbXBhcmUobWVzc2FnZV8xXywgbWVzc2FnZV8yXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGRfZmxvYXQsIC0xLCAtMSwgTlVMTCkpOworICBFWFBFQ1RfRVEoRmllbGRDb21wYXJhdG9yOjpESUZGRVJFTlQsCisgICAgICAgICAgICBjb21wYXJhdG9yXy5Db21wYXJlKG1lc3NhZ2VfMV8sIG1lc3NhZ2VfMl8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkX2RvdWJsZSwgLTEsIC0xLCBOVUxMKSk7CisgIGNvbXBhcmF0b3JfLnNldF9mbG9hdF9jb21wYXJpc29uKERlZmF1bHRGaWVsZENvbXBhcmF0b3I6OkFQUFJPWElNQVRFKTsKKyAgRVhQRUNUX0VRKEZpZWxkQ29tcGFyYXRvcjo6RElGRkVSRU5ULAorICAgICAgICAgICAgY29tcGFyYXRvcl8uQ29tcGFyZShtZXNzYWdlXzFfLCBtZXNzYWdlXzJfLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZF9mbG9hdCwgLTEsIC0xLCBOVUxMKSk7CisgIEVYUEVDVF9FUShGaWVsZENvbXBhcmF0b3I6OkRJRkZFUkVOVCwKKyAgICAgICAgICAgIGNvbXBhcmF0b3JfLkNvbXBhcmUobWVzc2FnZV8xXywgbWVzc2FnZV8yXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGRfZG91YmxlLCAtMSwgLTEsIE5VTEwpKTsKKworICBjb21wYXJhdG9yXy5zZXRfdHJlYXRfbmFuX2FzX2VxdWFsKHRydWUpOworICBBU1NFUlRfRVEodHJ1ZSwgY29tcGFyYXRvcl8udHJlYXRfbmFuX2FzX2VxdWFsKCkpOworICBjb21wYXJhdG9yXy5zZXRfZmxvYXRfY29tcGFyaXNvbihEZWZhdWx0RmllbGRDb21wYXJhdG9yOjpFWEFDVCk7CisgIEVYUEVDVF9FUShGaWVsZENvbXBhcmF0b3I6OlNBTUUsCisgICAgICAgICAgICBjb21wYXJhdG9yXy5Db21wYXJlKG1lc3NhZ2VfMV8sIG1lc3NhZ2VfMl8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkX2Zsb2F0LCAtMSwgLTEsIE5VTEwpKTsKKyAgRVhQRUNUX0VRKEZpZWxkQ29tcGFyYXRvcjo6U0FNRSwKKyAgICAgICAgICAgIGNvbXBhcmF0b3JfLkNvbXBhcmUobWVzc2FnZV8xXywgbWVzc2FnZV8yXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGRfZG91YmxlLCAtMSwgLTEsIE5VTEwpKTsKKyAgY29tcGFyYXRvcl8uc2V0X2Zsb2F0X2NvbXBhcmlzb24oRGVmYXVsdEZpZWxkQ29tcGFyYXRvcjo6QVBQUk9YSU1BVEUpOworICBFWFBFQ1RfRVEoRmllbGRDb21wYXJhdG9yOjpTQU1FLAorICAgICAgICAgICAgY29tcGFyYXRvcl8uQ29tcGFyZShtZXNzYWdlXzFfLCBtZXNzYWdlXzJfLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZF9mbG9hdCwgLTEsIC0xLCBOVUxMKSk7CisgIEVYUEVDVF9FUShGaWVsZENvbXBhcmF0b3I6OlNBTUUsCisgICAgICAgICAgICBjb21wYXJhdG9yXy5Db21wYXJlKG1lc3NhZ2VfMV8sIG1lc3NhZ2VfMl8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkX2RvdWJsZSwgLTEsIC0xLCBOVUxMKSk7Cit9CisKK1RFU1RfRihEZWZhdWx0RmllbGRDb21wYXJhdG9yVGVzdCwKKyAgICAgICBGbG9hdGluZ1BvaW50Q29tcGFyaXNvbldpdGhpbkZyYWN0aW9uT3JNYXJnaW4pIHsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZF9mbG9hdCA9CisgICAgICBkZXNjcmlwdG9yXy0+RmluZEZpZWxkQnlOYW1lKCJvcHRpb25hbF9mbG9hdCIpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkX2RvdWJsZSA9CisgICAgICBkZXNjcmlwdG9yXy0+RmluZEZpZWxkQnlOYW1lKCJvcHRpb25hbF9kb3VibGUiKTsKKworICBtZXNzYWdlXzFfLnNldF9vcHRpb25hbF9mbG9hdCgxMDAuMGYpOworICBtZXNzYWdlXzJfLnNldF9vcHRpb25hbF9mbG9hdCgxMDkuOWYpOworICBtZXNzYWdlXzFfLnNldF9vcHRpb25hbF9kb3VibGUoMTAwLjApOworICBtZXNzYWdlXzJfLnNldF9vcHRpb25hbF9kb3VibGUoMTA5LjkpOworCisgIGNvbXBhcmF0b3JfLnNldF9mbG9hdF9jb21wYXJpc29uKERlZmF1bHRGaWVsZENvbXBhcmF0b3I6OkFQUFJPWElNQVRFKTsKKyAgRVhQRUNUX0VRKEZpZWxkQ29tcGFyYXRvcjo6RElGRkVSRU5ULAorICAgICAgICAgICAgY29tcGFyYXRvcl8uQ29tcGFyZShtZXNzYWdlXzFfLCBtZXNzYWdlXzJfLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZF9mbG9hdCwgLTEsIC0xLCBOVUxMKSk7CisgIEVYUEVDVF9FUShGaWVsZENvbXBhcmF0b3I6OkRJRkZFUkVOVCwKKyAgICAgICAgICAgIGNvbXBhcmF0b3JfLkNvbXBhcmUobWVzc2FnZV8xXywgbWVzc2FnZV8yXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGRfZG91YmxlLCAtMSwgLTEsIE5VTEwpKTsKKworICAvLyBTaG91bGQgZmFpbCBzaW5jZSB0aGUgZnJhY3Rpb24gaXMgdG9vIGxvdy4KKyAgY29tcGFyYXRvcl8uU2V0RnJhY3Rpb25BbmRNYXJnaW4oZmllbGRfZmxvYXQsIDAuMDEsIDAuMCk7CisgIGNvbXBhcmF0b3JfLlNldEZyYWN0aW9uQW5kTWFyZ2luKGZpZWxkX2RvdWJsZSwgMC4wMSwgMC4wKTsKKworICBFWFBFQ1RfRVEoRmllbGRDb21wYXJhdG9yOjpESUZGRVJFTlQsCisgICAgICAgICAgICBjb21wYXJhdG9yXy5Db21wYXJlKG1lc3NhZ2VfMV8sIG1lc3NhZ2VfMl8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkX2Zsb2F0LCAtMSwgLTEsIE5VTEwpKTsKKyAgRVhQRUNUX0VRKEZpZWxkQ29tcGFyYXRvcjo6RElGRkVSRU5ULAorICAgICAgICAgICAgY29tcGFyYXRvcl8uQ29tcGFyZShtZXNzYWdlXzFfLCBtZXNzYWdlXzJfLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZF9kb3VibGUsIC0xLCAtMSwgTlVMTCkpOworCisgIC8vIFNob3VsZCBmYWlsIHNpbmNlIHRoZSBtYXJnaW4gaXMgdG9vIGxvdy4KKyAgY29tcGFyYXRvcl8uU2V0RnJhY3Rpb25BbmRNYXJnaW4oZmllbGRfZmxvYXQsIDAuMCwgOS4wKTsKKyAgY29tcGFyYXRvcl8uU2V0RnJhY3Rpb25BbmRNYXJnaW4oZmllbGRfZG91YmxlLCAwLjAsIDkuMCk7CisgIEVYUEVDVF9FUShGaWVsZENvbXBhcmF0b3I6OkRJRkZFUkVOVCwKKyAgICAgICAgICAgIGNvbXBhcmF0b3JfLkNvbXBhcmUobWVzc2FnZV8xXywgbWVzc2FnZV8yXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGRfZmxvYXQsIC0xLCAtMSwgTlVMTCkpOworICBFWFBFQ1RfRVEoRmllbGRDb21wYXJhdG9yOjpESUZGRVJFTlQsCisgICAgICAgICAgICBjb21wYXJhdG9yXy5Db21wYXJlKG1lc3NhZ2VfMV8sIG1lc3NhZ2VfMl8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkX2RvdWJsZSwgLTEsIC0xLCBOVUxMKSk7CisKKyAgLy8gU2hvdWxkIHN1Y2NlZWQgc2luY2UgdGhlIGZyYWN0aW9uIGlzIGhpZ2ggZW5vdWdoLgorICBjb21wYXJhdG9yXy5TZXRGcmFjdGlvbkFuZE1hcmdpbihmaWVsZF9mbG9hdCwgMC4yLCAwLjApOworICBjb21wYXJhdG9yXy5TZXRGcmFjdGlvbkFuZE1hcmdpbihmaWVsZF9kb3VibGUsIDAuMiwgMC4wKTsKKyAgRVhQRUNUX0VRKEZpZWxkQ29tcGFyYXRvcjo6U0FNRSwKKyAgICAgICAgICAgIGNvbXBhcmF0b3JfLkNvbXBhcmUobWVzc2FnZV8xXywgbWVzc2FnZV8yXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGRfZmxvYXQsIC0xLCAtMSwgTlVMTCkpOworICBFWFBFQ1RfRVEoRmllbGRDb21wYXJhdG9yOjpTQU1FLAorICAgICAgICAgICAgY29tcGFyYXRvcl8uQ29tcGFyZShtZXNzYWdlXzFfLCBtZXNzYWdlXzJfLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZF9kb3VibGUsIC0xLCAtMSwgTlVMTCkpOworCisgIC8vIFNob3VsZCBzdWNjZWVkIHNpbmNlIHRoZSBtYXJnaW4gaXMgaGlnaCBlbm91Z2guCisgIGNvbXBhcmF0b3JfLlNldEZyYWN0aW9uQW5kTWFyZ2luKGZpZWxkX2Zsb2F0LCAwLjAsIDEwLjApOworICBjb21wYXJhdG9yXy5TZXRGcmFjdGlvbkFuZE1hcmdpbihmaWVsZF9kb3VibGUsIDAuMCwgMTAuMCk7CisgIEVYUEVDVF9FUShGaWVsZENvbXBhcmF0b3I6OlNBTUUsCisgICAgICAgICAgICBjb21wYXJhdG9yXy5Db21wYXJlKG1lc3NhZ2VfMV8sIG1lc3NhZ2VfMl8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkX2Zsb2F0LCAtMSwgLTEsIE5VTEwpKTsKKyAgRVhQRUNUX0VRKEZpZWxkQ29tcGFyYXRvcjo6U0FNRSwKKyAgICAgICAgICAgIGNvbXBhcmF0b3JfLkNvbXBhcmUobWVzc2FnZV8xXywgbWVzc2FnZV8yXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGRfZG91YmxlLCAtMSwgLTEsIE5VTEwpKTsKKworICAvLyBTZXR0aW5nIHZhbHVlcyBmb3Igb25lIG9mIHRoZSBmaWVsZHMgc2hvdWxkIG5vdCBhZmZlY3QgdGhlIG90aGVyLgorICBjb21wYXJhdG9yXy5TZXRGcmFjdGlvbkFuZE1hcmdpbihmaWVsZF9kb3VibGUsIDAuMCwgMC4wKTsKKyAgRVhQRUNUX0VRKEZpZWxkQ29tcGFyYXRvcjo6U0FNRSwKKyAgICAgICAgICAgIGNvbXBhcmF0b3JfLkNvbXBhcmUobWVzc2FnZV8xXywgbWVzc2FnZV8yXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGRfZmxvYXQsIC0xLCAtMSwgTlVMTCkpOworICBFWFBFQ1RfRVEoRmllbGRDb21wYXJhdG9yOjpESUZGRVJFTlQsCisgICAgICAgICAgICBjb21wYXJhdG9yXy5Db21wYXJlKG1lc3NhZ2VfMV8sIG1lc3NhZ2VfMl8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkX2RvdWJsZSwgLTEsIC0xLCBOVUxMKSk7CisKKyAgLy8gK2luZiBzaG91bGQgYmUgZXF1YWwgZXZlbiB0aG91Z2ggdGhleSBhcmUgbm90IHRlY2huaWNhbGx5IHdpdGhpbiBtYXJnaW4gb3IKKyAgLy8gZnJhY3Rpb24uCisgIG1lc3NhZ2VfMV8uc2V0X29wdGlvbmFsX2Zsb2F0KG51bWVyaWNfbGltaXRzPGZsb2F0Pjo6aW5maW5pdHkoKSk7CisgIG1lc3NhZ2VfMl8uc2V0X29wdGlvbmFsX2Zsb2F0KG51bWVyaWNfbGltaXRzPGZsb2F0Pjo6aW5maW5pdHkoKSk7CisgIG1lc3NhZ2VfMV8uc2V0X29wdGlvbmFsX2RvdWJsZShudW1lcmljX2xpbWl0czxkb3VibGU+OjppbmZpbml0eSgpKTsKKyAgbWVzc2FnZV8yXy5zZXRfb3B0aW9uYWxfZG91YmxlKG51bWVyaWNfbGltaXRzPGRvdWJsZT46OmluZmluaXR5KCkpOworICBjb21wYXJhdG9yXy5TZXRGcmFjdGlvbkFuZE1hcmdpbihmaWVsZF9mbG9hdCwgMC4wLCAwLjApOworICBjb21wYXJhdG9yXy5TZXRGcmFjdGlvbkFuZE1hcmdpbihmaWVsZF9kb3VibGUsIDAuMCwgMC4wKTsKKyAgRVhQRUNUX0VRKEZpZWxkQ29tcGFyYXRvcjo6U0FNRSwKKyAgICAgICAgICAgIGNvbXBhcmF0b3JfLkNvbXBhcmUobWVzc2FnZV8xXywgbWVzc2FnZV8yXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGRfZmxvYXQsIC0xLCAtMSwgTlVMTCkpOworICBFWFBFQ1RfRVEoRmllbGRDb21wYXJhdG9yOjpTQU1FLAorICAgICAgICAgICAgY29tcGFyYXRvcl8uQ29tcGFyZShtZXNzYWdlXzFfLCBtZXNzYWdlXzJfLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZF9kb3VibGUsIC0xLCAtMSwgTlVMTCkpOworCisgIC8vIC1pbmYgc2hvdWxkIGJlIGVxdWFsIGV2ZW4gdGhvdWdoIHRoZXkgYXJlIG5vdCB0ZWNobmljYWxseSB3aXRoaW4gbWFyZ2luIG9yCisgIC8vIGZyYWN0aW9uLgorICBtZXNzYWdlXzFfLnNldF9vcHRpb25hbF9mbG9hdCgtbnVtZXJpY19saW1pdHM8ZmxvYXQ+OjppbmZpbml0eSgpKTsKKyAgbWVzc2FnZV8yXy5zZXRfb3B0aW9uYWxfZmxvYXQoLW51bWVyaWNfbGltaXRzPGZsb2F0Pjo6aW5maW5pdHkoKSk7CisgIG1lc3NhZ2VfMV8uc2V0X29wdGlvbmFsX2RvdWJsZSgtbnVtZXJpY19saW1pdHM8ZG91YmxlPjo6aW5maW5pdHkoKSk7CisgIG1lc3NhZ2VfMl8uc2V0X29wdGlvbmFsX2RvdWJsZSgtbnVtZXJpY19saW1pdHM8ZG91YmxlPjo6aW5maW5pdHkoKSk7CisgIGNvbXBhcmF0b3JfLlNldEZyYWN0aW9uQW5kTWFyZ2luKGZpZWxkX2Zsb2F0LCAwLjAsIDAuMCk7CisgIGNvbXBhcmF0b3JfLlNldEZyYWN0aW9uQW5kTWFyZ2luKGZpZWxkX2RvdWJsZSwgMC4wLCAwLjApOworICBFWFBFQ1RfRVEoRmllbGRDb21wYXJhdG9yOjpTQU1FLAorICAgICAgICAgICAgY29tcGFyYXRvcl8uQ29tcGFyZShtZXNzYWdlXzFfLCBtZXNzYWdlXzJfLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZF9mbG9hdCwgLTEsIC0xLCBOVUxMKSk7CisgIEVYUEVDVF9FUShGaWVsZENvbXBhcmF0b3I6OlNBTUUsCisgICAgICAgICAgICBjb21wYXJhdG9yXy5Db21wYXJlKG1lc3NhZ2VfMV8sIG1lc3NhZ2VfMl8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkX2RvdWJsZSwgLTEsIC0xLCBOVUxMKSk7Cit9CisKK1RFU1RfRihEZWZhdWx0RmllbGRDb21wYXJhdG9yVGVzdCwKKyAgICAgICBGbG9hdGluZ1BvaW50Q29tcGFyaXNvbldpdGhpbkRlZmF1bHRGcmFjdGlvbk9yTWFyZ2luKSB7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGRfZmxvYXQgPQorICAgICAgZGVzY3JpcHRvcl8tPkZpbmRGaWVsZEJ5TmFtZSgib3B0aW9uYWxfZmxvYXQiKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZF9kb3VibGUgPQorICAgICAgZGVzY3JpcHRvcl8tPkZpbmRGaWVsZEJ5TmFtZSgib3B0aW9uYWxfZG91YmxlIik7CisKKyAgbWVzc2FnZV8xXy5zZXRfb3B0aW9uYWxfZmxvYXQoMTAwLjBmKTsKKyAgbWVzc2FnZV8yXy5zZXRfb3B0aW9uYWxfZmxvYXQoMTA5LjlmKTsKKyAgbWVzc2FnZV8xXy5zZXRfb3B0aW9uYWxfZG91YmxlKDEwMC4wKTsKKyAgbWVzc2FnZV8yXy5zZXRfb3B0aW9uYWxfZG91YmxlKDEwOS45KTsKKworICBjb21wYXJhdG9yXy5zZXRfZmxvYXRfY29tcGFyaXNvbihEZWZhdWx0RmllbGRDb21wYXJhdG9yOjpBUFBST1hJTUFURSk7CisgIEVYUEVDVF9FUShGaWVsZENvbXBhcmF0b3I6OkRJRkZFUkVOVCwKKyAgICAgICAgICAgIGNvbXBhcmF0b3JfLkNvbXBhcmUobWVzc2FnZV8xXywgbWVzc2FnZV8yXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGRfZmxvYXQsIC0xLCAtMSwgTlVMTCkpOworICBFWFBFQ1RfRVEoRmllbGRDb21wYXJhdG9yOjpESUZGRVJFTlQsCisgICAgICAgICAgICBjb21wYXJhdG9yXy5Db21wYXJlKG1lc3NhZ2VfMV8sIG1lc3NhZ2VfMl8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkX2RvdWJsZSwgLTEsIC0xLCBOVUxMKSk7CisKKyAgLy8gU2V0IGRlZmF1bHQgZnJhY3Rpb24gYW5kIG1hcmdpbi4KKyAgY29tcGFyYXRvcl8uU2V0RGVmYXVsdEZyYWN0aW9uQW5kTWFyZ2luKDAuMDEsIDAuMCk7CisKKyAgLy8gRmxvYXQgY29tcGFyaXNvbnMgc2hvdWxkIGZhaWwgc2luY2UgdGhlIGZyYWN0aW9uIGlzIHRvbyBsb3cuCisgIEVYUEVDVF9FUShGaWVsZENvbXBhcmF0b3I6OkRJRkZFUkVOVCwKKyAgICAgICAgICAgIGNvbXBhcmF0b3JfLkNvbXBhcmUobWVzc2FnZV8xXywgbWVzc2FnZV8yXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGRfZmxvYXQsIC0xLCAtMSwgTlVMTCkpOworICBFWFBFQ1RfRVEoRmllbGRDb21wYXJhdG9yOjpESUZGRVJFTlQsCisgICAgICAgICAgICBjb21wYXJhdG9yXy5Db21wYXJlKG1lc3NhZ2VfMV8sIG1lc3NhZ2VfMl8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkX2RvdWJsZSwgLTEsIC0xLCBOVUxMKSk7CisKKyAgLy8gU2V0IGZpZWxkLXNwZWNpZmljIGZyYWN0aW9uIGFuZCBtYXJnaW4gZm9yIG9uZSBmaWVsZCAoZmllbGRfZmxvYXQpIGJ1dCBub3QKKyAgLy8gdGhlIG90aGVyIChmaWVsZF9kb3VibGUpCisgIGNvbXBhcmF0b3JfLlNldEZyYWN0aW9uQW5kTWFyZ2luKGZpZWxkX2Zsb2F0LCAwLjIsIDAuMCk7CisKKyAgLy8gVGhlIGZpZWxkIHdpdGggdGhlIG92ZXJyaWRlIHNob3VsZCBzdWNjZWVkLCBzaW5jZSBpdHMgZmllbGQtc3BlY2lmaWMKKyAgLy8gZnJhY3Rpb24gaXMgaGlnaCBlbm91Z2guCisgIEVYUEVDVF9FUShGaWVsZENvbXBhcmF0b3I6OlNBTUUsCisgICAgICAgICAgICBjb21wYXJhdG9yXy5Db21wYXJlKG1lc3NhZ2VfMV8sIG1lc3NhZ2VfMl8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkX2Zsb2F0LCAtMSwgLTEsIE5VTEwpKTsKKyAgLy8gVGhlIGZpZWxkIHdpdGggbm8gb3ZlcnJpZGUgc2hvdWxkIGZhaWwsIHNpbmNlIHRoZSBkZWZhdWx0IGZyYWN0aW9uIGlzIHRvbworICAvLyBsb3cKKyAgRVhQRUNUX0VRKEZpZWxkQ29tcGFyYXRvcjo6RElGRkVSRU5ULAorICAgICAgICAgICAgY29tcGFyYXRvcl8uQ29tcGFyZShtZXNzYWdlXzFfLCBtZXNzYWdlXzJfLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZF9kb3VibGUsIC0xLCAtMSwgTlVMTCkpOworCisgIC8vIFNldCB0aGUgZGVmYXVsdCBmcmFjdGlvbiBhbmQgbWFyZ2luIGhpZ2ggZW5vdWdoIHNvIHRoYXQgZmllbGRzIHRoYXQgdXNlCisgIC8vIHRoZSBkZWZhdWx0IHNob3VsZCBzdWNjZWVkCisgIGNvbXBhcmF0b3JfLlNldERlZmF1bHRGcmFjdGlvbkFuZE1hcmdpbigwLjIsIDAuMCk7CisgIEVYUEVDVF9FUShGaWVsZENvbXBhcmF0b3I6OlNBTUUsCisgICAgICAgICAgICBjb21wYXJhdG9yXy5Db21wYXJlKG1lc3NhZ2VfMV8sIG1lc3NhZ2VfMl8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkX2RvdWJsZSwgLTEsIC0xLCBOVUxMKSk7CisKKyAgLy8gVGhlIGZpZWxkIHdpdGggYW4gb3ZlcnJpZGUgc2hvdWxkIHN0aWxsIGJlIE9LCisgIEVYUEVDVF9FUShGaWVsZENvbXBhcmF0b3I6OlNBTUUsCisgICAgICAgICAgICBjb21wYXJhdG9yXy5Db21wYXJlKG1lc3NhZ2VfMV8sIG1lc3NhZ2VfMl8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkX2Zsb2F0LCAtMSwgLTEsIE5VTEwpKTsKKworICAvLyBTZXQgZnJhY3Rpb24gYW5kIG1hcmdpbiBmb3IgdGhlIGZpZWxkIHdpdGggYW4gb3ZlcnJpZGUgdG8gYmUgdG9vIGxvdworICBjb21wYXJhdG9yXy5TZXRGcmFjdGlvbkFuZE1hcmdpbihmaWVsZF9mbG9hdCwgMC4wMSwgMC4wKTsKKworICAvLyBOb3cgb3VyIGRlZmF1bHQgaXMgaGlnaCBlbm91Z2ggYnV0IGZpZWxkX2Zsb2F0J3Mgb3ZlcnJpZGUgaXMgdG9vIGxvdy4KKyAgRVhQRUNUX0VRKEZpZWxkQ29tcGFyYXRvcjo6RElGRkVSRU5ULAorICAgICAgICAgICAgY29tcGFyYXRvcl8uQ29tcGFyZShtZXNzYWdlXzFfLCBtZXNzYWdlXzJfLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZF9mbG9hdCwgLTEsIC0xLCBOVUxMKSk7CisgIEVYUEVDVF9FUShGaWVsZENvbXBhcmF0b3I6OlNBTUUsCisgICAgICAgICAgICBjb21wYXJhdG9yXy5Db21wYXJlKG1lc3NhZ2VfMV8sIG1lc3NhZ2VfMl8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkX2RvdWJsZSwgLTEsIC0xLCBOVUxMKSk7Cit9CisKKy8vIFNpbXBsZSB0ZXN0IGNoZWNraW5nIHdoZXRoZXIgd2UgY29tcGFyZSB2YWx1ZXMgYXQgY29ycmVjdCBpbmRpY2VzLgorVEVTVF9GKERlZmF1bHRGaWVsZENvbXBhcmF0b3JUZXN0LCBSZXBlYXRlZEZpZWxkQ29tcGFyaXNvbikgeworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0KKyAgICAgIGRlc2NyaXB0b3JfLT5GaW5kRmllbGRCeU5hbWUoInJlcGVhdGVkX3N0cmluZyIpOworCisgIG1lc3NhZ2VfMV8uYWRkX3JlcGVhdGVkX3N0cmluZygiZm9vIik7CisgIG1lc3NhZ2VfMV8uYWRkX3JlcGVhdGVkX3N0cmluZygiYmFyIik7CisgIG1lc3NhZ2VfMl8uYWRkX3JlcGVhdGVkX3N0cmluZygiYmFyIik7CisgIG1lc3NhZ2VfMl8uYWRkX3JlcGVhdGVkX3N0cmluZygiYmF6Iik7CisKKyAgRVhQRUNUX0VRKEZpZWxkQ29tcGFyYXRvcjo6RElGRkVSRU5ULAorICAgICAgICAgICAgY29tcGFyYXRvcl8uQ29tcGFyZShtZXNzYWdlXzFfLCBtZXNzYWdlXzJfLCBmaWVsZCwgMCwgMCwgTlVMTCkpOworICBFWFBFQ1RfRVEoRmllbGRDb21wYXJhdG9yOjpESUZGRVJFTlQsCisgICAgICAgICAgICBjb21wYXJhdG9yXy5Db21wYXJlKG1lc3NhZ2VfMV8sIG1lc3NhZ2VfMl8sIGZpZWxkLCAxLCAxLCBOVUxMKSk7CisgIEVYUEVDVF9FUShGaWVsZENvbXBhcmF0b3I6OlNBTUUsCisgICAgICAgICAgICBjb21wYXJhdG9yXy5Db21wYXJlKG1lc3NhZ2VfMV8sIG1lc3NhZ2VfMl8sIGZpZWxkLCAxLCAwLCBOVUxMKSk7Cit9CisKK30gIC8vIG5hbWVzcGFjZSB1dGlsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZQorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ZpZWxkX21hc2tfdXRpbC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9maWVsZF9tYXNrX3V0aWwuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzU5ZjQzYWEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvZmllbGRfbWFza191dGlsLmNjCkBAIC0wLDAgKzEsNDE4IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2ZpZWxkX21hc2tfdXRpbC5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbWFwX3V0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIHV0aWwgeworCit1c2luZyBnb29nbGU6OnByb3RvYnVmOjpGaWVsZE1hc2s7CisKK3N0cmluZyBGaWVsZE1hc2tVdGlsOjpUb1N0cmluZyhjb25zdCBGaWVsZE1hc2smIG1hc2spIHsKKyAgcmV0dXJuIEpvaW4obWFzay5wYXRocygpLCAiLCIpOworfQorCit2b2lkIEZpZWxkTWFza1V0aWw6OkZyb21TdHJpbmcoU3RyaW5nUGllY2Ugc3RyLCBGaWVsZE1hc2sqIG91dCkgeworICBvdXQtPkNsZWFyKCk7CisgIHZlY3RvcjxzdHJpbmc+IHBhdGhzID0gU3BsaXQoc3RyLCAiLCIpOworICBmb3IgKGludCBpID0gMDsgaSA8IHBhdGhzLnNpemUoKTsgKytpKSB7CisgICAgaWYgKHBhdGhzW2ldLmVtcHR5KCkpIGNvbnRpbnVlOworICAgIG91dC0+YWRkX3BhdGhzKHBhdGhzW2ldKTsKKyAgfQorfQorCitib29sIEZpZWxkTWFza1V0aWw6OkludGVybmFsSXNWYWxpZFBhdGgoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdQaWVjZSBwYXRoKSB7CisgIHZlY3RvcjxzdHJpbmc+IHBhcnRzID0gU3BsaXQocGF0aCwgIi4iKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYXJ0cy5zaXplKCk7ICsraSkgeworICAgIGNvbnN0IHN0cmluZyYgZmllbGRfbmFtZSA9IHBhcnRzW2ldOworICAgIGlmIChkZXNjcmlwdG9yID09IE5VTEwpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZShmaWVsZF9uYW1lKTsKKyAgICBpZiAoZmllbGQgPT0gTlVMTCkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBpZiAoIWZpZWxkLT5pc19yZXBlYXRlZCgpICYmCisgICAgICAgIGZpZWxkLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFKSB7CisgICAgICBkZXNjcmlwdG9yID0gZmllbGQtPm1lc3NhZ2VfdHlwZSgpOworICAgIH0gZWxzZSB7CisgICAgICBkZXNjcmlwdG9yID0gTlVMTDsKKyAgICB9CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgRmllbGRNYXNrVXRpbDo6SW50ZXJuYWxHZXRGaWVsZE1hc2tGb3JBbGxGaWVsZHMoCisgICAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwgRmllbGRNYXNrKiBvdXQpIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXNjcmlwdG9yLT5maWVsZF9jb3VudCgpOyArK2kpIHsKKyAgICBvdXQtPmFkZF9wYXRocyhkZXNjcmlwdG9yLT5maWVsZChpKS0+bmFtZSgpKTsKKyAgfQorfQorCituYW1lc3BhY2UgeworLy8gQSBGaWVsZE1hc2tUcmVlIHJlcHJlc2VudHMgYSBGaWVsZE1hc2sgaW4gYSB0cmVlIHN0cnVjdHVyZS4gRm9yIGV4YW1wbGUsCisvLyBnaXZlbiBhIEZpZWxkTWFzayAiZm9vLmJhcixmb28uYmF6LGJhci5iYXoiLCB0aGUgRmllbGRNYXNrVHJlZSB3aWxsIGJlOgorLy8KKy8vICAgW3Jvb3RdIC0rLSBmb28gLSstIGJhcgorLy8gICAgICAgICAgIHwgICAgICAgfAorLy8gICAgICAgICAgIHwgICAgICAgKy0gYmF6CisvLyAgICAgICAgICAgfAorLy8gICAgICAgICAgICstIGJhciAtLS0gYmF6CisvLworLy8gSW4gdGhlIHRyZWUsIGVhY2ggbGVhZiBub2RlIHJlcHJlc2VudHMgYSBmaWVsZCBwYXRoLgorY2xhc3MgRmllbGRNYXNrVHJlZSB7CisgcHVibGljOgorICBGaWVsZE1hc2tUcmVlKCk7CisgIH5GaWVsZE1hc2tUcmVlKCk7CisKKyAgdm9pZCBNZXJnZUZyb21GaWVsZE1hc2soY29uc3QgRmllbGRNYXNrJiBtYXNrKTsKKyAgdm9pZCBNZXJnZVRvRmllbGRNYXNrKEZpZWxkTWFzayogbWFzayk7CisKKyAgLy8gQWRkIGEgZmllbGQgcGF0aCBpbnRvIHRoZSB0cmVlLiBJbiBhIEZpZWxkTWFzaywgZWFjaCBmaWVsZCBwYXRoIG1hdGNoZXMKKyAgLy8gdGhlIHNwZWNpZmllZCBmaWVsZCBhbmQgYWxzbyBhbGwgaXRzIHN1Yi1maWVsZHMuIElmIHRoZSBmaWVsZCBwYXRoIHRvCisgIC8vIGFkZCBpcyBhIHN1Yi1wYXRoIG9mIGFuIGV4aXN0aW5nIGZpZWxkIHBhdGggaW4gdGhlIHRyZWUgKGkuZS4sIGEgbGVhZgorICAvLyBub2RlKSwgaXQgbWVhbnMgdGhlIHRyZWUgYWxyZWFkeSBtYXRjaGVzIHRoZSBnaXZlbiBwYXRoIHNvIG5vdGhpbmcgd2lsbAorICAvLyBiZSBhZGRlZCB0byB0aGUgdHJlZS4gSWYgdGhlIHBhdGggbWF0Y2hlcyBhbiBleGlzdGluZyBub24tbGVhZiBub2RlIGluIHRoZQorICAvLyB0cmVlLCB0aGF0IG5vbi1sZWFmIG5vZGUgd2lsbCBiZSB0dXJuZWQgaW50byBhIGxlYWYgbm9kZSB3aXRoIGFsbCBpdHMKKyAgLy8gY2hpbGRyZW4gcmVtb3ZlZCBiZWNhdXNlIHRoZSBwYXRoIG1hdGNoZXMgYWxsIHRoZSBub2RlJ3MgY2hpbGRyZW4uCisgIHZvaWQgQWRkUGF0aChjb25zdCBzdHJpbmcmIHBhdGgpOworCisgIC8vIENhbGN1bGF0ZSB0aGUgaW50ZXJzZWN0aW9uIHBhcnQgb2YgYSBmaWVsZCBwYXRoIHdpdGggdGhpcyB0cmVlIGFuZCBhZGQKKyAgLy8gdGhlIGludGVyc2VjdGlvbiBmaWVsZCBwYXRoIGludG8gb3V0LgorICB2b2lkIEludGVyc2VjdFBhdGgoY29uc3Qgc3RyaW5nJiBwYXRoLCBGaWVsZE1hc2tUcmVlKiBvdXQpOworCisgIC8vIE1lcmdlIGFsbCBmaWVsZHMgc3BlY2lmaWVkIGJ5IHRoaXMgdHJlZSBmcm9tIG9uZSBtZXNzYWdlIHRvIGFub3RoZXIuCisgIHZvaWQgTWVyZ2VNZXNzYWdlKGNvbnN0IE1lc3NhZ2UmIHNvdXJjZSwKKyAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGRNYXNrVXRpbDo6TWVyZ2VPcHRpb25zJiBvcHRpb25zLAorICAgICAgICAgICAgICAgICAgICBNZXNzYWdlKiBkZXN0aW5hdGlvbikgeworICAgIC8vIERvIG5vdGhpbmcgaWYgdGhlIHRyZWUgaXMgZW1wdHkuCisgICAgaWYgKHJvb3RfLmNoaWxkcmVuLmVtcHR5KCkpIHsKKyAgICAgIHJldHVybjsKKyAgICB9CisgICAgTWVyZ2VNZXNzYWdlKCZyb290Xywgc291cmNlLCBvcHRpb25zLCBkZXN0aW5hdGlvbik7CisgIH0KKworIHByaXZhdGU6CisgIHN0cnVjdCBOb2RlIHsKKyAgICBOb2RlKCkge30KKworICAgIH5Ob2RlKCkgeyBDbGVhckNoaWxkcmVuKCk7IH0KKworICAgIHZvaWQgQ2xlYXJDaGlsZHJlbigpIHsKKyAgICAgIGZvciAobWFwPHN0cmluZywgTm9kZSo+OjppdGVyYXRvciBpdCA9IGNoaWxkcmVuLmJlZ2luKCk7CisgICAgICAgICAgIGl0ICE9IGNoaWxkcmVuLmVuZCgpOyArK2l0KSB7CisgICAgICAgIGRlbGV0ZSBpdC0+c2Vjb25kOworICAgICAgfQorICAgICAgY2hpbGRyZW4uY2xlYXIoKTsKKyAgICB9CisKKyAgICBtYXA8c3RyaW5nLCBOb2RlKj4gY2hpbGRyZW47CisKKyAgIHByaXZhdGU6CisgICAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKE5vZGUpOworICB9OworCisgIC8vIE1lcmdlIGEgc3ViLXRyZWUgdG8gbWFzay4gVGhpcyBtZXRob2QgYWRkcyB0aGUgZmllbGQgcGF0aHMgcmVwcmVzZW50ZWQKKyAgLy8gYnkgYWxsIGxlYWYgbm9kZXMgZGVzY2VuZGVkIGZyb20gIm5vZGUiIHRvIG1hc2suCisgIHZvaWQgTWVyZ2VUb0ZpZWxkTWFzayhjb25zdCBzdHJpbmcmIHByZWZpeCwgY29uc3QgTm9kZSogbm9kZSwgRmllbGRNYXNrKiBvdXQpOworCisgIC8vIE1lcmdlIGFsbCBsZWFmIG5vZGVzIG9mIGEgc3ViLXRyZWUgdG8gYW5vdGhlciB0cmVlLgorICB2b2lkIE1lcmdlTGVhZk5vZGVzVG9UcmVlKGNvbnN0IHN0cmluZyYgcHJlZml4LCBjb25zdCBOb2RlKiBub2RlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkTWFza1RyZWUqIG91dCk7CisKKyAgLy8gTWVyZ2UgYWxsIGZpZWxkcyBzcGVjaWZpZWQgYnkgYSBzdWItdHJlZSBmcm9tIG9uZSBtZXNzYWdlIHRvIGFub3RoZXIuCisgIHZvaWQgTWVyZ2VNZXNzYWdlKGNvbnN0IE5vZGUqIG5vZGUsIGNvbnN0IE1lc3NhZ2UmIHNvdXJjZSwKKyAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGRNYXNrVXRpbDo6TWVyZ2VPcHRpb25zJiBvcHRpb25zLAorICAgICAgICAgICAgICAgICAgICBNZXNzYWdlKiBkZXN0aW5hdGlvbik7CisKKyAgTm9kZSByb290XzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoRmllbGRNYXNrVHJlZSk7Cit9OworCitGaWVsZE1hc2tUcmVlOjpGaWVsZE1hc2tUcmVlKCkge30KKworRmllbGRNYXNrVHJlZTo6fkZpZWxkTWFza1RyZWUoKSB7fQorCit2b2lkIEZpZWxkTWFza1RyZWU6Ok1lcmdlRnJvbUZpZWxkTWFzayhjb25zdCBGaWVsZE1hc2smIG1hc2spIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBtYXNrLnBhdGhzX3NpemUoKTsgKytpKSB7CisgICAgQWRkUGF0aChtYXNrLnBhdGhzKGkpKTsKKyAgfQorfQorCit2b2lkIEZpZWxkTWFza1RyZWU6Ok1lcmdlVG9GaWVsZE1hc2soRmllbGRNYXNrKiBtYXNrKSB7CisgIE1lcmdlVG9GaWVsZE1hc2soIiIsICZyb290XywgbWFzayk7Cit9CisKK3ZvaWQgRmllbGRNYXNrVHJlZTo6TWVyZ2VUb0ZpZWxkTWFzayhjb25zdCBzdHJpbmcmIHByZWZpeCwgY29uc3QgTm9kZSogbm9kZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWVsZE1hc2sqIG91dCkgeworICBpZiAobm9kZS0+Y2hpbGRyZW4uZW1wdHkoKSkgeworICAgIGlmIChwcmVmaXguZW1wdHkoKSkgeworICAgICAgLy8gVGhpcyBpcyB0aGUgcm9vdCBub2RlLgorICAgICAgcmV0dXJuOworICAgIH0KKyAgICBvdXQtPmFkZF9wYXRocyhwcmVmaXgpOworICAgIHJldHVybjsKKyAgfQorICBmb3IgKG1hcDxzdHJpbmcsIE5vZGUqPjo6Y29uc3RfaXRlcmF0b3IgaXQgPSBub2RlLT5jaGlsZHJlbi5iZWdpbigpOworICAgICAgIGl0ICE9IG5vZGUtPmNoaWxkcmVuLmVuZCgpOyArK2l0KSB7CisgICAgc3RyaW5nIGN1cnJlbnRfcGF0aCA9IHByZWZpeC5lbXB0eSgpID8gaXQtPmZpcnN0IDogcHJlZml4ICsgIi4iICsgaXQtPmZpcnN0OworICAgIE1lcmdlVG9GaWVsZE1hc2soY3VycmVudF9wYXRoLCBpdC0+c2Vjb25kLCBvdXQpOworICB9Cit9CisKK3ZvaWQgRmllbGRNYXNrVHJlZTo6QWRkUGF0aChjb25zdCBzdHJpbmcmIHBhdGgpIHsKKyAgdmVjdG9yPHN0cmluZz4gcGFydHMgPSBTcGxpdChwYXRoLCAiLiIpOworICBpZiAocGFydHMuZW1wdHkoKSkgeworICAgIHJldHVybjsKKyAgfQorICBib29sIG5ld19icmFuY2ggPSBmYWxzZTsKKyAgTm9kZSogbm9kZSA9ICZyb290XzsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYXJ0cy5zaXplKCk7ICsraSkgeworICAgIGlmICghbmV3X2JyYW5jaCAmJiBub2RlICE9ICZyb290XyAmJiBub2RlLT5jaGlsZHJlbi5lbXB0eSgpKSB7CisgICAgICAvLyBQYXRoIG1hdGNoZXMgYW4gZXhpc3RpbmcgbGVhZiBub2RlLiBUaGlzIG1lYW5zIHRoZSBwYXRoIGlzIGFscmVhZHkKKyAgICAgIC8vIGNvdmVycmVkIGJ5IHRoaXMgdHJlZSAoZm9yIGV4YW1wbGUsIGFkZGluZyAiZm9vLmJhci5iYXoiIHRvIGEgdHJlZQorICAgICAgLy8gd2hpY2ggYWxyZWFkeSBjb250YWlucyAiZm9vLmJhciIpLgorICAgICAgcmV0dXJuOworICAgIH0KKyAgICBjb25zdCBzdHJpbmcmIG5vZGVfbmFtZSA9IHBhcnRzW2ldOworICAgIE5vZGUqJiBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuW25vZGVfbmFtZV07CisgICAgaWYgKGNoaWxkID09IE5VTEwpIHsKKyAgICAgIG5ld19icmFuY2ggPSB0cnVlOworICAgICAgY2hpbGQgPSBuZXcgTm9kZSgpOworICAgIH0KKyAgICBub2RlID0gY2hpbGQ7CisgIH0KKyAgaWYgKCFub2RlLT5jaGlsZHJlbi5lbXB0eSgpKSB7CisgICAgbm9kZS0+Q2xlYXJDaGlsZHJlbigpOworICB9Cit9CisKK3ZvaWQgRmllbGRNYXNrVHJlZTo6SW50ZXJzZWN0UGF0aChjb25zdCBzdHJpbmcmIHBhdGgsIEZpZWxkTWFza1RyZWUqIG91dCkgeworICB2ZWN0b3I8c3RyaW5nPiBwYXJ0cyA9IFNwbGl0KHBhdGgsICIuIik7CisgIGlmIChwYXJ0cy5lbXB0eSgpKSB7CisgICAgcmV0dXJuOworICB9CisgIGNvbnN0IE5vZGUqIG5vZGUgPSAmcm9vdF87CisgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFydHMuc2l6ZSgpOyArK2kpIHsKKyAgICBpZiAobm9kZS0+Y2hpbGRyZW4uZW1wdHkoKSkgeworICAgICAgaWYgKG5vZGUgIT0gJnJvb3RfKSB7CisgICAgICAgIG91dC0+QWRkUGF0aChwYXRoKTsKKyAgICAgIH0KKyAgICAgIHJldHVybjsKKyAgICB9CisgICAgY29uc3Qgc3RyaW5nJiBub2RlX25hbWUgPSBwYXJ0c1tpXTsKKyAgICBjb25zdCBOb2RlKiByZXN1bHQgPSBGaW5kUHRyT3JOdWxsKG5vZGUtPmNoaWxkcmVuLCBub2RlX25hbWUpOworICAgIGlmIChyZXN1bHQgPT0gTlVMTCkgeworICAgICAgLy8gTm8gaW50ZXJzZWN0aW9uIGZvdW5kLgorICAgICAgcmV0dXJuOworICAgIH0KKyAgICBub2RlID0gcmVzdWx0OworICB9CisgIC8vIE5vdyB3ZSBmb3VuZCBhIG1hdGNoaW5nIG5vZGUgd2l0aCB0aGUgZ2l2ZW4gcGF0aC4gQWRkIGFsbCBsZWFmIG5vZGVzCisgIC8vIHRvIG91dC4KKyAgTWVyZ2VMZWFmTm9kZXNUb1RyZWUocGF0aCwgbm9kZSwgb3V0KTsKK30KKwordm9pZCBGaWVsZE1hc2tUcmVlOjpNZXJnZUxlYWZOb2Rlc1RvVHJlZShjb25zdCBzdHJpbmcmIHByZWZpeCwgY29uc3QgTm9kZSogbm9kZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmllbGRNYXNrVHJlZSogb3V0KSB7CisgIGlmIChub2RlLT5jaGlsZHJlbi5lbXB0eSgpKSB7CisgICAgb3V0LT5BZGRQYXRoKHByZWZpeCk7CisgIH0KKyAgZm9yIChtYXA8c3RyaW5nLCBOb2RlKj46OmNvbnN0X2l0ZXJhdG9yIGl0ID0gbm9kZS0+Y2hpbGRyZW4uYmVnaW4oKTsKKyAgICAgICBpdCAhPSBub2RlLT5jaGlsZHJlbi5lbmQoKTsgKytpdCkgeworICAgIHN0cmluZyBjdXJyZW50X3BhdGggPSBwcmVmaXguZW1wdHkoKSA/IGl0LT5maXJzdCA6IHByZWZpeCArICIuIiArIGl0LT5maXJzdDsKKyAgICBNZXJnZUxlYWZOb2Rlc1RvVHJlZShjdXJyZW50X3BhdGgsIGl0LT5zZWNvbmQsIG91dCk7CisgIH0KK30KKwordm9pZCBGaWVsZE1hc2tUcmVlOjpNZXJnZU1lc3NhZ2UoY29uc3QgTm9kZSogbm9kZSwgY29uc3QgTWVzc2FnZSYgc291cmNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGRNYXNrVXRpbDo6TWVyZ2VPcHRpb25zJiBvcHRpb25zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZSogZGVzdGluYXRpb24pIHsKKyAgR09PR0xFX0RDSEVDSyghbm9kZS0+Y2hpbGRyZW4uZW1wdHkoKSk7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHNvdXJjZV9yZWZsZWN0aW9uID0gc291cmNlLkdldFJlZmxlY3Rpb24oKTsKKyAgY29uc3QgUmVmbGVjdGlvbiogZGVzdGluYXRpb25fcmVmbGVjdGlvbiA9IGRlc3RpbmF0aW9uLT5HZXRSZWZsZWN0aW9uKCk7CisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBzb3VyY2UuR2V0RGVzY3JpcHRvcigpOworICBmb3IgKG1hcDxzdHJpbmcsIE5vZGUqPjo6Y29uc3RfaXRlcmF0b3IgaXQgPSBub2RlLT5jaGlsZHJlbi5iZWdpbigpOworICAgICAgIGl0ICE9IG5vZGUtPmNoaWxkcmVuLmVuZCgpOyArK2l0KSB7CisgICAgY29uc3Qgc3RyaW5nJiBmaWVsZF9uYW1lID0gaXQtPmZpcnN0OworICAgIGNvbnN0IE5vZGUqIGNoaWxkID0gaXQtPnNlY29uZDsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKGZpZWxkX25hbWUpOworICAgIGlmIChmaWVsZCA9PSBOVUxMKSB7CisgICAgICBHT09HTEVfTE9HKEVSUk9SKSA8PCAiQ2Fubm90IGZpbmQgZmllbGQgXCIiIDw8IGZpZWxkX25hbWUgPDwgIlwiIGluIG1lc3NhZ2UgIgorICAgICAgICAgICAgICAgICA8PCBkZXNjcmlwdG9yLT5mdWxsX25hbWUoKTsKKyAgICAgIGNvbnRpbnVlOworICAgIH0KKyAgICBpZiAoIWNoaWxkLT5jaGlsZHJlbi5lbXB0eSgpKSB7CisgICAgICAvLyBTdWItcGF0aHMgYXJlIG9ubHkgYWxsb3dlZCBmb3Igc2luZ3VsYXIgbWVzc2FnZSBmaWVsZHMuCisgICAgICBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkgfHwKKyAgICAgICAgICBmaWVsZC0+Y3BwX3R5cGUoKSAhPSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSkgeworICAgICAgICBHT09HTEVfTE9HKEVSUk9SKSA8PCAiRmllbGQgXCIiIDw8IGZpZWxkX25hbWUgPDwgIlwiIGluIG1lc3NhZ2UgIgorICAgICAgICAgICAgICAgICAgIDw8IGRlc2NyaXB0b3ItPmZ1bGxfbmFtZSgpCisgICAgICAgICAgICAgICAgICAgPDwgIiBpcyBub3QgYSBzaW5ndWxhciBtZXNzYWdlIGZpZWxkIGFuZCBjYW5ub3QgIgorICAgICAgICAgICAgICAgICAgIDw8ICJoYXZlIHN1Yi1maWVsZHMuIjsKKyAgICAgICAgY29udGludWU7CisgICAgICB9CisgICAgICBNZXJnZU1lc3NhZ2UoY2hpbGQsIHNvdXJjZV9yZWZsZWN0aW9uLT5HZXRNZXNzYWdlKHNvdXJjZSwgZmllbGQpLCBvcHRpb25zLAorICAgICAgICAgICAgICAgICAgIGRlc3RpbmF0aW9uX3JlZmxlY3Rpb24tPk11dGFibGVNZXNzYWdlKGRlc3RpbmF0aW9uLCBmaWVsZCkpOworICAgICAgY29udGludWU7CisgICAgfQorICAgIGlmICghZmllbGQtPmlzX3JlcGVhdGVkKCkpIHsKKyAgICAgIHN3aXRjaCAoZmllbGQtPmNwcF90eXBlKCkpIHsKKyNkZWZpbmUgQ09QWV9WQUxVRShUWVBFLCBOYW1lKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV8jI1RZUEU6IHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgZGVzdGluYXRpb25fcmVmbGVjdGlvbi0+U2V0IyNOYW1lKCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgZGVzdGluYXRpb24sIGZpZWxkLCBzb3VyY2VfcmVmbGVjdGlvbi0+R2V0IyNOYW1lKHNvdXJjZSwgZmllbGQpKTsgXAorICAgIGJyZWFrOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIH0KKyAgICAgICAgQ09QWV9WQUxVRShCT09MLCBCb29sKQorICAgICAgICBDT1BZX1ZBTFVFKElOVDMyLCBJbnQzMikKKyAgICAgICAgQ09QWV9WQUxVRShJTlQ2NCwgSW50NjQpCisgICAgICAgIENPUFlfVkFMVUUoVUlOVDMyLCBVSW50MzIpCisgICAgICAgIENPUFlfVkFMVUUoVUlOVDY0LCBVSW50NjQpCisgICAgICAgIENPUFlfVkFMVUUoRkxPQVQsIEZsb2F0KQorICAgICAgICBDT1BZX1ZBTFVFKERPVUJMRSwgRG91YmxlKQorICAgICAgICBDT1BZX1ZBTFVFKEVOVU0sIEVudW0pCisgICAgICAgIENPUFlfVkFMVUUoU1RSSU5HLCBTdHJpbmcpCisjdW5kZWYgQ09QWV9WQUxVRQorICAgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFOiB7CisgICAgICAgICAgaWYgKG9wdGlvbnMucmVwbGFjZV9tZXNzYWdlX2ZpZWxkcygpKSB7CisgICAgICAgICAgICBkZXN0aW5hdGlvbl9yZWZsZWN0aW9uLT5DbGVhckZpZWxkKGRlc3RpbmF0aW9uLCBmaWVsZCk7CisgICAgICAgICAgfQorICAgICAgICAgIGlmIChzb3VyY2VfcmVmbGVjdGlvbi0+SGFzRmllbGQoc291cmNlLCBmaWVsZCkpIHsKKyAgICAgICAgICAgIGRlc3RpbmF0aW9uX3JlZmxlY3Rpb24tPk11dGFibGVNZXNzYWdlKGRlc3RpbmF0aW9uLCBmaWVsZCkKKyAgICAgICAgICAgICAgICAtPk1lcmdlRnJvbShzb3VyY2VfcmVmbGVjdGlvbi0+R2V0TWVzc2FnZShzb3VyY2UsIGZpZWxkKSk7CisgICAgICAgICAgfQorICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgIGlmIChvcHRpb25zLnJlcGxhY2VfcmVwZWF0ZWRfZmllbGRzKCkpIHsKKyAgICAgICAgZGVzdGluYXRpb25fcmVmbGVjdGlvbi0+Q2xlYXJGaWVsZChkZXN0aW5hdGlvbiwgZmllbGQpOworICAgICAgfQorICAgICAgc3dpdGNoIChmaWVsZC0+Y3BwX3R5cGUoKSkgeworI2RlZmluZSBDT1BZX1JFUEVBVEVEX1ZBTFVFKFRZUEUsIE5hbWUpICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfIyNUWVBFOiB7ICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgaW50IHNpemUgPSBzb3VyY2VfcmVmbGVjdGlvbi0+RmllbGRTaXplKHNvdXJjZSwgZmllbGQpOyAgICAgICAgXAorICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgKytpKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIGRlc3RpbmF0aW9uX3JlZmxlY3Rpb24tPkFkZCMjTmFtZSggICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgZGVzdGluYXRpb24sIGZpZWxkLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgIHNvdXJjZV9yZWZsZWN0aW9uLT5HZXRSZXBlYXRlZCMjTmFtZShzb3VyY2UsIGZpZWxkLCBpKSk7IFwKKyAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgYnJlYWs7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICB9CisgICAgICAgIENPUFlfUkVQRUFURURfVkFMVUUoQk9PTCwgQm9vbCkKKyAgICAgICAgQ09QWV9SRVBFQVRFRF9WQUxVRShJTlQzMiwgSW50MzIpCisgICAgICAgIENPUFlfUkVQRUFURURfVkFMVUUoSU5UNjQsIEludDY0KQorICAgICAgICBDT1BZX1JFUEVBVEVEX1ZBTFVFKFVJTlQzMiwgVUludDMyKQorICAgICAgICBDT1BZX1JFUEVBVEVEX1ZBTFVFKFVJTlQ2NCwgVUludDY0KQorICAgICAgICBDT1BZX1JFUEVBVEVEX1ZBTFVFKEZMT0FULCBGbG9hdCkKKyAgICAgICAgQ09QWV9SRVBFQVRFRF9WQUxVRShET1VCTEUsIERvdWJsZSkKKyAgICAgICAgQ09QWV9SRVBFQVRFRF9WQUxVRShFTlVNLCBFbnVtKQorICAgICAgICBDT1BZX1JFUEVBVEVEX1ZBTFVFKFNUUklORywgU3RyaW5nKQorI3VuZGVmIENPUFlfUkVQRUFURURfVkFMVUUKKyAgICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRTogeworICAgICAgICAgIGludCBzaXplID0gc291cmNlX3JlZmxlY3Rpb24tPkZpZWxkU2l6ZShzb3VyY2UsIGZpZWxkKTsKKyAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNpemU7ICsraSkgeworICAgICAgICAgICAgZGVzdGluYXRpb25fcmVmbGVjdGlvbi0+QWRkTWVzc2FnZShkZXN0aW5hdGlvbiwgZmllbGQpCisgICAgICAgICAgICAgICAgLT5NZXJnZUZyb20oCisgICAgICAgICAgICAgICAgICAgIHNvdXJjZV9yZWZsZWN0aW9uLT5HZXRSZXBlYXRlZE1lc3NhZ2Uoc291cmNlLCBmaWVsZCwgaSkpOworICAgICAgICAgIH0KKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgfQorfQorCit9ICAvLyBuYW1lc3BhY2UKKwordm9pZCBGaWVsZE1hc2tVdGlsOjpUb0Nhbm9uaWNhbEZvcm0oY29uc3QgRmllbGRNYXNrJiBtYXNrLCBGaWVsZE1hc2sqIG91dCkgeworICBGaWVsZE1hc2tUcmVlIHRyZWU7CisgIHRyZWUuTWVyZ2VGcm9tRmllbGRNYXNrKG1hc2spOworICBvdXQtPkNsZWFyKCk7CisgIHRyZWUuTWVyZ2VUb0ZpZWxkTWFzayhvdXQpOworfQorCit2b2lkIEZpZWxkTWFza1V0aWw6OlVuaW9uKGNvbnN0IEZpZWxkTWFzayYgbWFzazEsIGNvbnN0IEZpZWxkTWFzayYgbWFzazIsCisgICAgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkTWFzayogb3V0KSB7CisgIEZpZWxkTWFza1RyZWUgdHJlZTsKKyAgdHJlZS5NZXJnZUZyb21GaWVsZE1hc2sobWFzazEpOworICB0cmVlLk1lcmdlRnJvbUZpZWxkTWFzayhtYXNrMik7CisgIG91dC0+Q2xlYXIoKTsKKyAgdHJlZS5NZXJnZVRvRmllbGRNYXNrKG91dCk7Cit9CisKK3ZvaWQgRmllbGRNYXNrVXRpbDo6SW50ZXJzZWN0KGNvbnN0IEZpZWxkTWFzayYgbWFzazEsIGNvbnN0IEZpZWxkTWFzayYgbWFzazIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWVsZE1hc2sqIG91dCkgeworICBGaWVsZE1hc2tUcmVlIHRyZWUsIGludGVyc2VjdGlvbjsKKyAgdHJlZS5NZXJnZUZyb21GaWVsZE1hc2sobWFzazEpOworICBmb3IgKGludCBpID0gMDsgaSA8IG1hc2syLnBhdGhzX3NpemUoKTsgKytpKSB7CisgICAgdHJlZS5JbnRlcnNlY3RQYXRoKG1hc2syLnBhdGhzKGkpLCAmaW50ZXJzZWN0aW9uKTsKKyAgfQorICBvdXQtPkNsZWFyKCk7CisgIGludGVyc2VjdGlvbi5NZXJnZVRvRmllbGRNYXNrKG91dCk7Cit9CisKK2Jvb2wgRmllbGRNYXNrVXRpbDo6SXNQYXRoSW5GaWVsZE1hc2soU3RyaW5nUGllY2UgcGF0aCwgY29uc3QgRmllbGRNYXNrJiBtYXNrKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgbWFzay5wYXRoc19zaXplKCk7ICsraSkgeworICAgIGNvbnN0IHN0cmluZyYgbWFza19wYXRoID0gbWFzay5wYXRocyhpKTsKKyAgICBpZiAocGF0aCA9PSBtYXNrX3BhdGgpIHsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0gZWxzZSBpZiAobWFza19wYXRoLmxlbmd0aCgpIDwgcGF0aC5sZW5ndGgoKSkgeworICAgICAgLy8gQWxzbyBjaGVjayB3aGV0aGVyIG1hc2sucGF0aHMoaSkgaXMgYSBwcmVmaXggb2YgcGF0aC4KKyAgICAgIGlmIChwYXRoLnN1YnN0cigwLCBtYXNrX3BhdGgubGVuZ3RoKCkgKyAxKS5jb21wYXJlKG1hc2tfcGF0aCArICIuIikgPT0KKyAgICAgICAgICAwKSB7CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgfQorICAgIH0KKyAgfQorICByZXR1cm4gZmFsc2U7Cit9CisKK3ZvaWQgRmllbGRNYXNrVXRpbDo6TWVyZ2VNZXNzYWdlVG8oY29uc3QgTWVzc2FnZSYgc291cmNlLCBjb25zdCBGaWVsZE1hc2smIG1hc2ssCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1lcmdlT3B0aW9ucyYgb3B0aW9ucywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZSogZGVzdGluYXRpb24pIHsKKyAgR09PR0xFX0NIRUNLKHNvdXJjZS5HZXREZXNjcmlwdG9yKCkgPT0gZGVzdGluYXRpb24tPkdldERlc2NyaXB0b3IoKSk7CisgIC8vIEJ1aWxkIGEgRmllbGRNYXNrVHJlZSBhbmQgd2FsayB0aHJvdWdoIHRoZSB0cmVlIHRvIG1lcmdlIGFsbCBzcGVjaWZpZWQKKyAgLy8gZmllbGRzLgorICBGaWVsZE1hc2tUcmVlIHRyZWU7CisgIHRyZWUuTWVyZ2VGcm9tRmllbGRNYXNrKG1hc2spOworICB0cmVlLk1lcmdlTWVzc2FnZShzb3VyY2UsIG9wdGlvbnMsIGRlc3RpbmF0aW9uKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIHV0aWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ZpZWxkX21hc2tfdXRpbC5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ZpZWxkX21hc2tfdXRpbC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkyZjY5ODkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvZmllbGRfbWFza191dGlsLmgKQEAgLTAsMCArMSwxNDcgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9VVElMX0ZJRUxEX01BU0tfVVRJTF9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1VUSUxfRklFTERfTUFTS19VVElMX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZmllbGRfbWFzay5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJpbmdwaWVjZS5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgdXRpbCB7CisKK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBGaWVsZE1hc2tVdGlsIHsKKyAgdHlwZWRlZiBnb29nbGU6OnByb3RvYnVmOjpGaWVsZE1hc2sgRmllbGRNYXNrOworCisgcHVibGljOgorICAvLyBDb252ZXJ0cyBGaWVsZE1hc2sgdG8vZnJvbSBzdHJpbmcsIGZvcm1hdHRlZCBhY2NvcmRpbmcgdG8gcHJvdG8zIEpTT04KKyAgLy8gc3BlYyBmb3IgRmllbGRNYXNrIChlLmcuLCAiZm9vLGJhcixiYXoucXV6IikuCisgIHN0YXRpYyBzdHJpbmcgVG9TdHJpbmcoY29uc3QgRmllbGRNYXNrJiBtYXNrKTsKKyAgc3RhdGljIHZvaWQgRnJvbVN0cmluZyhTdHJpbmdQaWVjZSBzdHIsIEZpZWxkTWFzayogb3V0KTsKKworICAvLyBDaGVja3Mgd2hldGhlciB0aGUgZ2l2ZW4gcGF0aCBpcyB2YWxpZCBmb3IgdHlwZSBULgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4KKyAgc3RhdGljIGJvb2wgSXNWYWxpZFBhdGgoU3RyaW5nUGllY2UgcGF0aCkgeworICAgIHJldHVybiBJbnRlcm5hbElzVmFsaWRQYXRoKFQ6OmRlc2NyaXB0b3IoKSwgcGF0aCk7CisgIH0KKworICAvLyBDaGVja3Mgd2hldGhlciB0aGUgZ2l2ZW4gRmllbGRNYXNrIGlzIHZhbGlkIGZvciB0eXBlIFQuCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUPgorICBzdGF0aWMgYm9vbCBJc1ZhbGlkRmllbGRNYXNrKGNvbnN0IEZpZWxkTWFzayYgbWFzaykgeworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWFzay5wYXRoc19zaXplKCk7ICsraSkgeworICAgICAgaWYgKCFJbnRlcm5hbElzVmFsaWRQYXRoKFQ6OmRlc2NyaXB0b3IoKSwgbWFzay5wYXRocyhpKSkpIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICAvLyBBZGRzIGEgcGF0aCB0byBGaWVsZE1hc2sgYWZ0ZXIgY2hlY2tpbmcgd2hldGhlciB0aGUgZ2l2ZW4gcGF0aCBpcyB2YWxpZC4KKyAgLy8gVGhpcyBtZXRob2QgY2hlY2stZmFpbHMgaWYgdGhlIHBhdGggaXMgbm90IGEgdmFsaWQgcGF0aCBmb3IgdHlwZSBULgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4KKyAgc3RhdGljIHZvaWQgQWRkUGF0aFRvRmllbGRNYXNrKFN0cmluZ1BpZWNlIHBhdGgsIEZpZWxkTWFzayogbWFzaykgeworICAgIEdPT0dMRV9DSEVDSyhJc1ZhbGlkUGF0aDxUPihwYXRoKSk7CisgICAgbWFzay0+YWRkX3BhdGhzKHBhdGgpOworICB9CisKKyAgLy8gQ3JlYXRlcyBhIEZpZWxkTWFzayB3aXRoIGFsbCBmaWVsZHMgb2YgdHlwZSBULiBUaGlzIEZpZWxkTWFzayBvbmx5CisgIC8vIGNvbnRhaW5zIGZpZWxkcyBvZiBUIGJ1dCBub3QgYW55IHN1Yi1tZXNzYWdlIGZpZWxkcy4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CisgIHN0YXRpYyB2b2lkIEdldEZpZWxkTWFza0ZvckFsbEZpZWxkcyhGaWVsZE1hc2sqIG91dCkgeworICAgIEludGVybmFsR2V0RmllbGRNYXNrRm9yQWxsRmllbGRzKFQ6OmRlc2NyaXB0b3IoKSwgb3V0KTsKKyAgfQorCisgIC8vIENvbnZlcnRzIGEgRmllbGRNYXNrIHRvIHRoZSBjYW5vbmljYWwgZm9ybS4gSXQgd2lsbDoKKyAgLy8gICAxLiBSZW1vdmUgcGF0aHMgdGhhdCBhcmUgY292ZXJlZCBieSBhbm90aGVyIHBhdGguIEZvciBleGFtcGxlLAorICAvLyAgICAgICJmb28uYmFyIiBpcyBjb3ZlcmVkIGJ5ICJmb28iIGFuZCB3aWxsIGJlIHJlbW92ZWQgaWYgImZvbyIKKyAgLy8gICAgICBpcyBhbHNvIGluIHRoZSBGaWVsZE1hc2suCisgIC8vICAgMi4gU29ydCBhbGwgcGF0aHMgaW4gYWxwaGFiZXRpY2FsIG9yZGVyLgorICBzdGF0aWMgdm9pZCBUb0Nhbm9uaWNhbEZvcm0oY29uc3QgRmllbGRNYXNrJiBtYXNrLCBGaWVsZE1hc2sqIG91dCk7CisKKyAgLy8gQ3JlYXRlcyBhbiB1bmlvbiBvZiB0d28gRmllbGRNYXNrcy4KKyAgc3RhdGljIHZvaWQgVW5pb24oY29uc3QgRmllbGRNYXNrJiBtYXNrMSwgY29uc3QgRmllbGRNYXNrJiBtYXNrMiwKKyAgICAgICAgICAgICAgICAgICAgRmllbGRNYXNrKiBvdXQpOworCisgIC8vIENyZWF0ZXMgYW4gaW50ZXJzZWN0aW9uIG9mIHR3byBGaWVsZE1hc2tzLgorICBzdGF0aWMgdm9pZCBJbnRlcnNlY3QoY29uc3QgRmllbGRNYXNrJiBtYXNrMSwgY29uc3QgRmllbGRNYXNrJiBtYXNrMiwKKyAgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkTWFzayogb3V0KTsKKworICAvLyBSZXR1cm5zIHRydWUgaWYgcGF0aCBpcyBjb3ZlcmVkIGJ5IHRoZSBnaXZlbiBGaWVsZE1hc2suIE5vdGUgdGhhdCBwYXRoCisgIC8vICJmb28uYmFyIiBjb3ZlcnMgYWxsIHBhdGhzIGxpa2UgImZvby5iYXIuYmF6IiwgImZvby5iYXIucXV6LngiLCBldGMuCisgIHN0YXRpYyBib29sIElzUGF0aEluRmllbGRNYXNrKFN0cmluZ1BpZWNlIHBhdGgsIGNvbnN0IEZpZWxkTWFzayYgbWFzayk7CisKKyAgY2xhc3MgTWVyZ2VPcHRpb25zOworICAvLyBNZXJnZXMgZmllbGRzIHNwZWNpZmllZCBpbiBhIEZpZWxkTWFzayBpbnRvIGFub3RoZXIgbWVzc2FnZS4KKyAgc3RhdGljIHZvaWQgTWVyZ2VNZXNzYWdlVG8oY29uc3QgTWVzc2FnZSYgc291cmNlLCBjb25zdCBGaWVsZE1hc2smIG1hc2ssCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1lcmdlT3B0aW9ucyYgb3B0aW9ucywgTWVzc2FnZSogZGVzdGluYXRpb24pOworCisgcHJpdmF0ZToKKyAgc3RhdGljIGJvb2wgSW50ZXJuYWxJc1ZhbGlkUGF0aChjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1BpZWNlIHBhdGgpOworCisgIHN0YXRpYyB2b2lkIEludGVybmFsR2V0RmllbGRNYXNrRm9yQWxsRmllbGRzKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkTWFzayogb3V0KTsKK307CisKK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBGaWVsZE1hc2tVdGlsOjpNZXJnZU9wdGlvbnMgeworIHB1YmxpYzoKKyAgTWVyZ2VPcHRpb25zKCkKKyAgICAgIDogcmVwbGFjZV9tZXNzYWdlX2ZpZWxkc18oZmFsc2UpLCByZXBsYWNlX3JlcGVhdGVkX2ZpZWxkc18oZmFsc2UpIHt9CisgIC8vIFdoZW4gbWVyZ2luZyBtZXNzYWdlIGZpZWxkcywgdGhlIGRlZmF1bHQgYmVoYXZpb3IgaXMgdG8gbWVyZ2UgdGhlCisgIC8vIGNvbnRlbnQgb2YgdHdvIG1lc3NhZ2UgZmllbGRzIHRvZ2V0aGVyLiBJZiB5b3UgaW5zdGVhZCB3YW50IHRvIHVzZQorICAvLyB0aGUgZmllbGQgZnJvbSB0aGUgc291cmNlIG1lc3NhZ2UgdG8gcmVwbGFjZSB0aGUgY29ycmVzcG9uZGluZyBmaWVsZAorICAvLyBpbiB0aGUgZGVzdGluYXRpb24gbWVzc2FnZSwgc2V0IHRoaXMgZmxhZyB0byB0cnVlLiBXaGVuIHRoaXMgZmxhZyBpcyBzZXQsCisgIC8vIHNwZWNpZmllZCBzdWJtZXNzYWdlIGZpZWxkcyB0aGF0IGFyZSBtaXNzaW5nIGluIHNvdXJjZSB3aWxsIGJlIGNsZWFyZWQgaW4KKyAgLy8gZGVzdGluYXRpb24uCisgIHZvaWQgc2V0X3JlcGxhY2VfbWVzc2FnZV9maWVsZHMoYm9vbCB2YWx1ZSkgeworICAgIHJlcGxhY2VfbWVzc2FnZV9maWVsZHNfID0gdmFsdWU7CisgIH0KKyAgYm9vbCByZXBsYWNlX21lc3NhZ2VfZmllbGRzKCkgY29uc3QgeyByZXR1cm4gcmVwbGFjZV9tZXNzYWdlX2ZpZWxkc187IH0KKyAgLy8gVGhlIGRlZmF1bHQgbWVyZ2luZyBiZWhhdmlvciB3aWxsIGFwcGVuZCBlbnRyaWVzIGZyb20gdGhlIHNvdXJjZQorICAvLyByZXBlYXRlZCBmaWVsZCB0byB0aGUgZGVzdGluYXRpb24gcmVwZWF0ZWQgZmllbGQuIElmIHlvdSBvbmx5IHdhbnQKKyAgLy8gdG8ga2VlcCB0aGUgZW50cmllcyBmcm9tIHRoZSBzb3VyY2UgcmVwZWF0ZWQgZmllbGQsIHNldCB0aGlzIGZsYWcKKyAgLy8gdG8gdHJ1ZS4KKyAgdm9pZCBzZXRfcmVwbGFjZV9yZXBlYXRlZF9maWVsZHMoYm9vbCB2YWx1ZSkgeworICAgIHJlcGxhY2VfcmVwZWF0ZWRfZmllbGRzXyA9IHZhbHVlOworICB9CisgIGJvb2wgcmVwbGFjZV9yZXBlYXRlZF9maWVsZHMoKSBjb25zdCB7IHJldHVybiByZXBsYWNlX3JlcGVhdGVkX2ZpZWxkc187IH0KKworIHByaXZhdGU6CisgIGJvb2wgcmVwbGFjZV9tZXNzYWdlX2ZpZWxkc187CisgIGJvb2wgcmVwbGFjZV9yZXBlYXRlZF9maWVsZHNfOworfTsKKworfSAgLy8gbmFtZXNwYWNlIHV0aWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9VVElMX0ZJRUxEX01BU0tfVVRJTF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9maWVsZF9tYXNrX3V0aWxfdGVzdC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9maWVsZF9tYXNrX3V0aWxfdGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hOTUyMzI1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ZpZWxkX21hc2tfdXRpbF90ZXN0LmNjCkBAIC0wLDAgKzEsMzk1IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2ZpZWxkX21hc2tfdXRpbC5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2ZpZWxkX21hc2sucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdF91dGlsLmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIHV0aWwgeworbmFtZXNwYWNlIHsKKwordXNpbmcgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlczsKK3VzaW5nIHByb3RvYnVmX3VuaXR0ZXN0OjpOZXN0ZWRUZXN0QWxsVHlwZXM7Cit1c2luZyBnb29nbGU6OnByb3RvYnVmOjpGaWVsZE1hc2s7CisKK1RFU1QoRmllbGRNYXNrVXRpbFRlc3QsIFN0cmluZ0Zvcm1hdCkgeworICBGaWVsZE1hc2sgbWFzazsKKyAgRVhQRUNUX0VRKCIiLCBGaWVsZE1hc2tVdGlsOjpUb1N0cmluZyhtYXNrKSk7CisgIG1hc2suYWRkX3BhdGhzKCJmb28iKTsKKyAgRVhQRUNUX0VRKCJmb28iLCBGaWVsZE1hc2tVdGlsOjpUb1N0cmluZyhtYXNrKSk7CisgIG1hc2suYWRkX3BhdGhzKCJiYXIiKTsKKyAgRVhQRUNUX0VRKCJmb28sYmFyIiwgRmllbGRNYXNrVXRpbDo6VG9TdHJpbmcobWFzaykpOworCisgIEZpZWxkTWFza1V0aWw6OkZyb21TdHJpbmcoIiIsICZtYXNrKTsKKyAgRVhQRUNUX0VRKDAsIG1hc2sucGF0aHNfc2l6ZSgpKTsKKyAgRmllbGRNYXNrVXRpbDo6RnJvbVN0cmluZygiZm9vIiwgJm1hc2spOworICBFWFBFQ1RfRVEoMSwgbWFzay5wYXRoc19zaXplKCkpOworICBFWFBFQ1RfRVEoImZvbyIsIG1hc2sucGF0aHMoMCkpOworICBGaWVsZE1hc2tVdGlsOjpGcm9tU3RyaW5nKCJmb28sYmFyIiwgJm1hc2spOworICBFWFBFQ1RfRVEoMiwgbWFzay5wYXRoc19zaXplKCkpOworICBFWFBFQ1RfRVEoImZvbyIsIG1hc2sucGF0aHMoMCkpOworICBFWFBFQ1RfRVEoImJhciIsIG1hc2sucGF0aHMoMSkpOworfQorCitURVNUKEZpZWxkTWFza1V0aWxUZXN0LCBUZXN0SXNWYWlsZFBhdGgpIHsKKyAgRVhQRUNUX1RSVUUoRmllbGRNYXNrVXRpbDo6SXNWYWxpZFBhdGg8VGVzdEFsbFR5cGVzPigib3B0aW9uYWxfaW50MzIiKSk7CisgIEVYUEVDVF9GQUxTRShGaWVsZE1hc2tVdGlsOjpJc1ZhbGlkUGF0aDxUZXN0QWxsVHlwZXM+KCJvcHRpb25hbF9ub25leGlzdCIpKTsKKyAgRVhQRUNUX1RSVUUoCisgICAgICBGaWVsZE1hc2tVdGlsOjpJc1ZhbGlkUGF0aDxUZXN0QWxsVHlwZXM+KCJvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZS5iYiIpKTsKKyAgRVhQRUNUX0ZBTFNFKEZpZWxkTWFza1V0aWw6OklzVmFsaWRQYXRoPFRlc3RBbGxUeXBlcz4oCisgICAgICAib3B0aW9uYWxfbmVzdGVkX21lc3NhZ2Uubm9uZXhpc3QiKSk7CisgIC8vIEZpZWxkTWFzayBjYW5ub3QgYmUgdXNlZCB0byBzcGVjaWZ5IHN1Yi1maWVsZHMgb2YgYSByZXBlYXRlZCBtZXNzYWdlLgorICBFWFBFQ1RfRkFMU0UoCisgICAgICBGaWVsZE1hc2tVdGlsOjpJc1ZhbGlkUGF0aDxUZXN0QWxsVHlwZXM+KCJyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZS5iYiIpKTsKK30KKworVEVTVChGaWVsZE1hc2tVdGlsVGVzdCwgVGVzdElzVmFsaWRGaWVsZE1hc2spIHsKKyAgRmllbGRNYXNrIG1hc2s7CisgIEZpZWxkTWFza1V0aWw6OkZyb21TdHJpbmcoIm9wdGlvbmFsX2ludDMyLG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlLmJiIiwgJm1hc2spOworICBFWFBFQ1RfVFJVRShGaWVsZE1hc2tVdGlsOjpJc1ZhbGlkRmllbGRNYXNrPFRlc3RBbGxUeXBlcz4obWFzaykpOworCisgIEZpZWxkTWFza1V0aWw6OkZyb21TdHJpbmcoCisgICAgICAib3B0aW9uYWxfaW50MzIsb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UuYmIsb3B0aW9uYWxfbm9uZXhpc3QiLCAmbWFzayk7CisgIEVYUEVDVF9GQUxTRShGaWVsZE1hc2tVdGlsOjpJc1ZhbGlkRmllbGRNYXNrPFRlc3RBbGxUeXBlcz4obWFzaykpOworfQorCitURVNUKEZpZWxkTWFza1V0aWxUZXN0LCBUZXN0R2V0RmllbGRNYXNrRm9yQWxsRmllbGRzKSB7CisgIEZpZWxkTWFzayBtYXNrOworICBGaWVsZE1hc2tVdGlsOjpHZXRGaWVsZE1hc2tGb3JBbGxGaWVsZHM8VGVzdEFsbFR5cGVzOjpOZXN0ZWRNZXNzYWdlPigmbWFzayk7CisgIEVYUEVDVF9FUSgxLCBtYXNrLnBhdGhzX3NpemUoKSk7CisgIEVYUEVDVF9UUlVFKEZpZWxkTWFza1V0aWw6OklzUGF0aEluRmllbGRNYXNrKCJiYiIsIG1hc2spKTsKKworICBGaWVsZE1hc2tVdGlsOjpHZXRGaWVsZE1hc2tGb3JBbGxGaWVsZHM8VGVzdEFsbFR5cGVzPigmbWFzayk7CisgIEVYUEVDVF9FUSg3NiwgbWFzay5wYXRoc19zaXplKCkpOworICBFWFBFQ1RfVFJVRShGaWVsZE1hc2tVdGlsOjpJc1BhdGhJbkZpZWxkTWFzaygib3B0aW9uYWxfaW50MzIiLCBtYXNrKSk7CisgIEVYUEVDVF9UUlVFKEZpZWxkTWFza1V0aWw6OklzUGF0aEluRmllbGRNYXNrKCJvcHRpb25hbF9pbnQ2NCIsIG1hc2spKTsKKyAgRVhQRUNUX1RSVUUoRmllbGRNYXNrVXRpbDo6SXNQYXRoSW5GaWVsZE1hc2soIm9wdGlvbmFsX3VpbnQzMiIsIG1hc2spKTsKKyAgRVhQRUNUX1RSVUUoRmllbGRNYXNrVXRpbDo6SXNQYXRoSW5GaWVsZE1hc2soIm9wdGlvbmFsX3VpbnQ2NCIsIG1hc2spKTsKKyAgRVhQRUNUX1RSVUUoRmllbGRNYXNrVXRpbDo6SXNQYXRoSW5GaWVsZE1hc2soIm9wdGlvbmFsX3NpbnQzMiIsIG1hc2spKTsKKyAgRVhQRUNUX1RSVUUoRmllbGRNYXNrVXRpbDo6SXNQYXRoSW5GaWVsZE1hc2soIm9wdGlvbmFsX3NpbnQ2NCIsIG1hc2spKTsKKyAgRVhQRUNUX1RSVUUoRmllbGRNYXNrVXRpbDo6SXNQYXRoSW5GaWVsZE1hc2soIm9wdGlvbmFsX2ZpeGVkMzIiLCBtYXNrKSk7CisgIEVYUEVDVF9UUlVFKEZpZWxkTWFza1V0aWw6OklzUGF0aEluRmllbGRNYXNrKCJvcHRpb25hbF9maXhlZDY0IiwgbWFzaykpOworICBFWFBFQ1RfVFJVRShGaWVsZE1hc2tVdGlsOjpJc1BhdGhJbkZpZWxkTWFzaygib3B0aW9uYWxfc2ZpeGVkMzIiLCBtYXNrKSk7CisgIEVYUEVDVF9UUlVFKEZpZWxkTWFza1V0aWw6OklzUGF0aEluRmllbGRNYXNrKCJvcHRpb25hbF9zZml4ZWQ2NCIsIG1hc2spKTsKKyAgRVhQRUNUX1RSVUUoRmllbGRNYXNrVXRpbDo6SXNQYXRoSW5GaWVsZE1hc2soIm9wdGlvbmFsX2Zsb2F0IiwgbWFzaykpOworICBFWFBFQ1RfVFJVRShGaWVsZE1hc2tVdGlsOjpJc1BhdGhJbkZpZWxkTWFzaygib3B0aW9uYWxfZG91YmxlIiwgbWFzaykpOworICBFWFBFQ1RfVFJVRShGaWVsZE1hc2tVdGlsOjpJc1BhdGhJbkZpZWxkTWFzaygib3B0aW9uYWxfYm9vbCIsIG1hc2spKTsKKyAgRVhQRUNUX1RSVUUoRmllbGRNYXNrVXRpbDo6SXNQYXRoSW5GaWVsZE1hc2soIm9wdGlvbmFsX3N0cmluZyIsIG1hc2spKTsKKyAgRVhQRUNUX1RSVUUoRmllbGRNYXNrVXRpbDo6SXNQYXRoSW5GaWVsZE1hc2soIm9wdGlvbmFsX2J5dGVzIiwgbWFzaykpOworICBFWFBFQ1RfVFJVRSgKKyAgICAgIEZpZWxkTWFza1V0aWw6OklzUGF0aEluRmllbGRNYXNrKCJvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSIsIG1hc2spKTsKKyAgRVhQRUNUX1RSVUUoCisgICAgICBGaWVsZE1hc2tVdGlsOjpJc1BhdGhJbkZpZWxkTWFzaygib3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlIiwgbWFzaykpOworICBFWFBFQ1RfVFJVRSgKKyAgICAgIEZpZWxkTWFza1V0aWw6OklzUGF0aEluRmllbGRNYXNrKCJvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSIsIG1hc2spKTsKKyAgRVhQRUNUX1RSVUUoRmllbGRNYXNrVXRpbDo6SXNQYXRoSW5GaWVsZE1hc2soIm9wdGlvbmFsX25lc3RlZF9lbnVtIiwgbWFzaykpOworICBFWFBFQ1RfVFJVRShGaWVsZE1hc2tVdGlsOjpJc1BhdGhJbkZpZWxkTWFzaygib3B0aW9uYWxfZm9yZWlnbl9lbnVtIiwgbWFzaykpOworICBFWFBFQ1RfVFJVRShGaWVsZE1hc2tVdGlsOjpJc1BhdGhJbkZpZWxkTWFzaygib3B0aW9uYWxfaW1wb3J0X2VudW0iLCBtYXNrKSk7CisgIEVYUEVDVF9UUlVFKEZpZWxkTWFza1V0aWw6OklzUGF0aEluRmllbGRNYXNrKCJyZXBlYXRlZF9pbnQzMiIsIG1hc2spKTsKKyAgRVhQRUNUX1RSVUUoRmllbGRNYXNrVXRpbDo6SXNQYXRoSW5GaWVsZE1hc2soInJlcGVhdGVkX2ludDY0IiwgbWFzaykpOworICBFWFBFQ1RfVFJVRShGaWVsZE1hc2tVdGlsOjpJc1BhdGhJbkZpZWxkTWFzaygicmVwZWF0ZWRfdWludDMyIiwgbWFzaykpOworICBFWFBFQ1RfVFJVRShGaWVsZE1hc2tVdGlsOjpJc1BhdGhJbkZpZWxkTWFzaygicmVwZWF0ZWRfdWludDY0IiwgbWFzaykpOworICBFWFBFQ1RfVFJVRShGaWVsZE1hc2tVdGlsOjpJc1BhdGhJbkZpZWxkTWFzaygicmVwZWF0ZWRfc2ludDMyIiwgbWFzaykpOworICBFWFBFQ1RfVFJVRShGaWVsZE1hc2tVdGlsOjpJc1BhdGhJbkZpZWxkTWFzaygicmVwZWF0ZWRfc2ludDY0IiwgbWFzaykpOworICBFWFBFQ1RfVFJVRShGaWVsZE1hc2tVdGlsOjpJc1BhdGhJbkZpZWxkTWFzaygicmVwZWF0ZWRfZml4ZWQzMiIsIG1hc2spKTsKKyAgRVhQRUNUX1RSVUUoRmllbGRNYXNrVXRpbDo6SXNQYXRoSW5GaWVsZE1hc2soInJlcGVhdGVkX2ZpeGVkNjQiLCBtYXNrKSk7CisgIEVYUEVDVF9UUlVFKEZpZWxkTWFza1V0aWw6OklzUGF0aEluRmllbGRNYXNrKCJyZXBlYXRlZF9zZml4ZWQzMiIsIG1hc2spKTsKKyAgRVhQRUNUX1RSVUUoRmllbGRNYXNrVXRpbDo6SXNQYXRoSW5GaWVsZE1hc2soInJlcGVhdGVkX3NmaXhlZDY0IiwgbWFzaykpOworICBFWFBFQ1RfVFJVRShGaWVsZE1hc2tVdGlsOjpJc1BhdGhJbkZpZWxkTWFzaygicmVwZWF0ZWRfZmxvYXQiLCBtYXNrKSk7CisgIEVYUEVDVF9UUlVFKEZpZWxkTWFza1V0aWw6OklzUGF0aEluRmllbGRNYXNrKCJyZXBlYXRlZF9kb3VibGUiLCBtYXNrKSk7CisgIEVYUEVDVF9UUlVFKEZpZWxkTWFza1V0aWw6OklzUGF0aEluRmllbGRNYXNrKCJyZXBlYXRlZF9ib29sIiwgbWFzaykpOworICBFWFBFQ1RfVFJVRShGaWVsZE1hc2tVdGlsOjpJc1BhdGhJbkZpZWxkTWFzaygicmVwZWF0ZWRfc3RyaW5nIiwgbWFzaykpOworICBFWFBFQ1RfVFJVRShGaWVsZE1hc2tVdGlsOjpJc1BhdGhJbkZpZWxkTWFzaygicmVwZWF0ZWRfYnl0ZXMiLCBtYXNrKSk7CisgIEVYUEVDVF9UUlVFKAorICAgICAgRmllbGRNYXNrVXRpbDo6SXNQYXRoSW5GaWVsZE1hc2soInJlcGVhdGVkX25lc3RlZF9tZXNzYWdlIiwgbWFzaykpOworICBFWFBFQ1RfVFJVRSgKKyAgICAgIEZpZWxkTWFza1V0aWw6OklzUGF0aEluRmllbGRNYXNrKCJyZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UiLCBtYXNrKSk7CisgIEVYUEVDVF9UUlVFKAorICAgICAgRmllbGRNYXNrVXRpbDo6SXNQYXRoSW5GaWVsZE1hc2soInJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlIiwgbWFzaykpOworICBFWFBFQ1RfVFJVRShGaWVsZE1hc2tVdGlsOjpJc1BhdGhJbkZpZWxkTWFzaygicmVwZWF0ZWRfbmVzdGVkX2VudW0iLCBtYXNrKSk7CisgIEVYUEVDVF9UUlVFKEZpZWxkTWFza1V0aWw6OklzUGF0aEluRmllbGRNYXNrKCJyZXBlYXRlZF9mb3JlaWduX2VudW0iLCBtYXNrKSk7CisgIEVYUEVDVF9UUlVFKEZpZWxkTWFza1V0aWw6OklzUGF0aEluRmllbGRNYXNrKCJyZXBlYXRlZF9pbXBvcnRfZW51bSIsIG1hc2spKTsKK30KKworVEVTVChGaWVsZE1hc2tVdGlsVGVzdCwgVGVzdFRvQ2Fub25pY2FsRm9ybSkgeworICBGaWVsZE1hc2sgaW4sIG91dDsKKyAgLy8gUGF0aHMgd2lsbCBiZSBzb3J0ZWQuCisgIEZpZWxkTWFza1V0aWw6OkZyb21TdHJpbmcoImJhei5xdXosYmFyLGZvbyIsICZpbik7CisgIEZpZWxkTWFza1V0aWw6OlRvQ2Fub25pY2FsRm9ybShpbiwgJm91dCk7CisgIEVYUEVDVF9FUSgiYmFyLGJhei5xdXosZm9vIiwgRmllbGRNYXNrVXRpbDo6VG9TdHJpbmcob3V0KSk7CisgIC8vIER1cGxpY2F0ZWQgcGF0aHMgd2lsbCBiZSByZW1vdmVkLgorICBGaWVsZE1hc2tVdGlsOjpGcm9tU3RyaW5nKCJmb28sYmFyLGZvbyIsICZpbik7CisgIEZpZWxkTWFza1V0aWw6OlRvQ2Fub25pY2FsRm9ybShpbiwgJm91dCk7CisgIEVYUEVDVF9FUSgiYmFyLGZvbyIsIEZpZWxkTWFza1V0aWw6OlRvU3RyaW5nKG91dCkpOworICAvLyBTdWItcGF0aHMgb2Ygb3RoZXIgcGF0aHMgd2lsbCBiZSByZW1vdmVkLgorICBGaWVsZE1hc2tVdGlsOjpGcm9tU3RyaW5nKCJmb28uYjEsYmFyLmIxLGZvby5iMixiYXIiLCAmaW4pOworICBGaWVsZE1hc2tVdGlsOjpUb0Nhbm9uaWNhbEZvcm0oaW4sICZvdXQpOworICBFWFBFQ1RfRVEoImJhcixmb28uYjEsZm9vLmIyIiwgRmllbGRNYXNrVXRpbDo6VG9TdHJpbmcob3V0KSk7CisKKyAgLy8gVGVzdCBtb3JlIGRlZXBseSBuZXN0ZWQgY2FzZXMuCisgIEZpZWxkTWFza1V0aWw6OkZyb21TdHJpbmcoCisgICAgICAiZm9vLmJhci5iYXoxLCIKKyAgICAgICJmb28uYmFyLmJhejIucXV6LCIKKyAgICAgICJmb28uYmFyLmJhejIiLAorICAgICAgJmluKTsKKyAgRmllbGRNYXNrVXRpbDo6VG9DYW5vbmljYWxGb3JtKGluLCAmb3V0KTsKKyAgRVhQRUNUX0VRKCJmb28uYmFyLmJhejEsZm9vLmJhci5iYXoyIiwgRmllbGRNYXNrVXRpbDo6VG9TdHJpbmcob3V0KSk7CisgIEZpZWxkTWFza1V0aWw6OkZyb21TdHJpbmcoCisgICAgICAiZm9vLmJhci5iYXoxLCIKKyAgICAgICJmb28uYmFyLmJhejIsIgorICAgICAgImZvby5iYXIuYmF6Mi5xdXoiLAorICAgICAgJmluKTsKKyAgRmllbGRNYXNrVXRpbDo6VG9DYW5vbmljYWxGb3JtKGluLCAmb3V0KTsKKyAgRVhQRUNUX0VRKCJmb28uYmFyLmJhejEsZm9vLmJhci5iYXoyIiwgRmllbGRNYXNrVXRpbDo6VG9TdHJpbmcob3V0KSk7CisgIEZpZWxkTWFza1V0aWw6OkZyb21TdHJpbmcoCisgICAgICAiZm9vLmJhci5iYXoxLCIKKyAgICAgICJmb28uYmFyLmJhejIsIgorICAgICAgImZvby5iYXIuYmF6Mi5xdXosIgorICAgICAgImZvby5iYXIiLAorICAgICAgJmluKTsKKyAgRmllbGRNYXNrVXRpbDo6VG9DYW5vbmljYWxGb3JtKGluLCAmb3V0KTsKKyAgRVhQRUNUX0VRKCJmb28uYmFyIiwgRmllbGRNYXNrVXRpbDo6VG9TdHJpbmcob3V0KSk7CisgIEZpZWxkTWFza1V0aWw6OkZyb21TdHJpbmcoCisgICAgICAiZm9vLmJhci5iYXoxLCIKKyAgICAgICJmb28uYmFyLmJhejIsIgorICAgICAgImZvby5iYXIuYmF6Mi5xdXosIgorICAgICAgImZvbyIsCisgICAgICAmaW4pOworICBGaWVsZE1hc2tVdGlsOjpUb0Nhbm9uaWNhbEZvcm0oaW4sICZvdXQpOworICBFWFBFQ1RfRVEoImZvbyIsIEZpZWxkTWFza1V0aWw6OlRvU3RyaW5nKG91dCkpOworfQorCitURVNUKEZpZWxkTWFza1V0aWxUZXN0LCBUZXN0VW5pb24pIHsKKyAgRmllbGRNYXNrIG1hc2sxLCBtYXNrMiwgb3V0OworICAvLyBUZXN0IGNhc2VzIHdpdGhvdXQgb3ZlcmxhcHBpbmcuCisgIEZpZWxkTWFza1V0aWw6OkZyb21TdHJpbmcoImZvbyxiYXoiLCAmbWFzazEpOworICBGaWVsZE1hc2tVdGlsOjpGcm9tU3RyaW5nKCJiYXIscXV6IiwgJm1hc2syKTsKKyAgRmllbGRNYXNrVXRpbDo6VW5pb24obWFzazEsIG1hc2syLCAmb3V0KTsKKyAgRVhQRUNUX0VRKCJiYXIsYmF6LGZvbyxxdXoiLCBGaWVsZE1hc2tVdGlsOjpUb1N0cmluZyhvdXQpKTsKKyAgLy8gT3ZlcmxhcCB3aXRoIGR1cGxpY2F0ZWQgcGF0aHMuCisgIEZpZWxkTWFza1V0aWw6OkZyb21TdHJpbmcoImZvbyxiYXouYmIiLCAmbWFzazEpOworICBGaWVsZE1hc2tVdGlsOjpGcm9tU3RyaW5nKCJiYXouYmIscXV6IiwgJm1hc2syKTsKKyAgRmllbGRNYXNrVXRpbDo6VW5pb24obWFzazEsIG1hc2syLCAmb3V0KTsKKyAgRVhQRUNUX0VRKCJiYXouYmIsZm9vLHF1eiIsIEZpZWxkTWFza1V0aWw6OlRvU3RyaW5nKG91dCkpOworICAvLyBPdmVybGFwIHdpdGggcGF0aHMgY292ZXJpbmcgc29tZSBvdGhlciBwYXRocy4KKyAgRmllbGRNYXNrVXRpbDo6RnJvbVN0cmluZygiZm9vLmJhci5iYXoscXV6IiwgJm1hc2sxKTsKKyAgRmllbGRNYXNrVXRpbDo6RnJvbVN0cmluZygiZm9vLmJhcixiYXIiLCAmbWFzazIpOworICBGaWVsZE1hc2tVdGlsOjpVbmlvbihtYXNrMSwgbWFzazIsICZvdXQpOworICBFWFBFQ1RfRVEoImJhcixmb28uYmFyLHF1eiIsIEZpZWxkTWFza1V0aWw6OlRvU3RyaW5nKG91dCkpOworfQorCitURVNUKEZpZWxkTWFza1V0aWxUZXN0LCBUZXN0SW50ZXJzZWN0KSB7CisgIEZpZWxkTWFzayBtYXNrMSwgbWFzazIsIG91dDsKKyAgLy8gVGVzdCBjYXNlcyB3aXRob3V0IG92ZXJsYXBwaW5nLgorICBGaWVsZE1hc2tVdGlsOjpGcm9tU3RyaW5nKCJmb28sYmF6IiwgJm1hc2sxKTsKKyAgRmllbGRNYXNrVXRpbDo6RnJvbVN0cmluZygiYmFyLHF1eiIsICZtYXNrMik7CisgIEZpZWxkTWFza1V0aWw6OkludGVyc2VjdChtYXNrMSwgbWFzazIsICZvdXQpOworICBFWFBFQ1RfRVEoIiIsIEZpZWxkTWFza1V0aWw6OlRvU3RyaW5nKG91dCkpOworICAvLyBPdmVybGFwIHdpdGggZHVwbGljYXRlZCBwYXRocy4KKyAgRmllbGRNYXNrVXRpbDo6RnJvbVN0cmluZygiZm9vLGJhei5iYiIsICZtYXNrMSk7CisgIEZpZWxkTWFza1V0aWw6OkZyb21TdHJpbmcoImJhei5iYixxdXoiLCAmbWFzazIpOworICBGaWVsZE1hc2tVdGlsOjpJbnRlcnNlY3QobWFzazEsIG1hc2syLCAmb3V0KTsKKyAgRVhQRUNUX0VRKCJiYXouYmIiLCBGaWVsZE1hc2tVdGlsOjpUb1N0cmluZyhvdXQpKTsKKyAgLy8gT3ZlcmxhcCB3aXRoIHBhdGhzIGNvdmVyaW5nIHNvbWUgb3RoZXIgcGF0aHMuCisgIEZpZWxkTWFza1V0aWw6OkZyb21TdHJpbmcoImZvby5iYXIuYmF6LHF1eiIsICZtYXNrMSk7CisgIEZpZWxkTWFza1V0aWw6OkZyb21TdHJpbmcoImZvby5iYXIsYmFyIiwgJm1hc2syKTsKKyAgRmllbGRNYXNrVXRpbDo6SW50ZXJzZWN0KG1hc2sxLCBtYXNrMiwgJm91dCk7CisgIEVYUEVDVF9FUSgiZm9vLmJhci5iYXoiLCBGaWVsZE1hc2tVdGlsOjpUb1N0cmluZyhvdXQpKTsKK30KKworVEVTVChGaWVsZE1hc2tVdGlsVGVzdCwgVGVzdElzcGF0aEluRmllbGRNYXNrKSB7CisgIEZpZWxkTWFzayBtYXNrOworICBGaWVsZE1hc2tVdGlsOjpGcm9tU3RyaW5nKCJmb28uYmFyIiwgJm1hc2spOworICBFWFBFQ1RfRkFMU0UoRmllbGRNYXNrVXRpbDo6SXNQYXRoSW5GaWVsZE1hc2soIiIsIG1hc2spKTsKKyAgRVhQRUNUX0ZBTFNFKEZpZWxkTWFza1V0aWw6OklzUGF0aEluRmllbGRNYXNrKCJmb28iLCBtYXNrKSk7CisgIEVYUEVDVF9UUlVFKEZpZWxkTWFza1V0aWw6OklzUGF0aEluRmllbGRNYXNrKCJmb28uYmFyIiwgbWFzaykpOworICBFWFBFQ1RfVFJVRShGaWVsZE1hc2tVdGlsOjpJc1BhdGhJbkZpZWxkTWFzaygiZm9vLmJhci5iYXoiLCBtYXNrKSk7CisgIEVYUEVDVF9GQUxTRShGaWVsZE1hc2tVdGlsOjpJc1BhdGhJbkZpZWxkTWFzaygiZm9vLmJhcjAuYmF6IiwgbWFzaykpOworfQorCitURVNUKEZpZWxkTWFza1V0aWxUZXN0LCBNZXJnZU1lc3NhZ2UpIHsKKyAgVGVzdEFsbFR5cGVzIHNyYywgZHN0OworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZzcmMpOworICBGaWVsZE1hc2tVdGlsOjpNZXJnZU9wdGlvbnMgb3B0aW9uczsKKworI2RlZmluZSBURVNUX01FUkdFX09ORV9QUklNSVRJVkVfRklFTEQoZmllbGRfbmFtZSkgICAgICAgICAgIFwKKyAgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgVGVzdEFsbFR5cGVzIHRtcDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIHRtcC5zZXRfIyNmaWVsZF9uYW1lKHNyYy5maWVsZF9uYW1lKCkpOyAgICAgICAgICAgICAgICAgIFwKKyAgICBGaWVsZE1hc2sgbWFzazsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgbWFzay5hZGRfcGF0aHMoI2ZpZWxkX25hbWUpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGRzdC5DbGVhcigpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBGaWVsZE1hc2tVdGlsOjpNZXJnZU1lc3NhZ2VUbyhzcmMsIG1hc2ssIG9wdGlvbnMsICZkc3QpOyBcCisgICAgRVhQRUNUX0VRKHRtcC5EZWJ1Z1N0cmluZygpLCBkc3QuRGVidWdTdHJpbmcoKSk7ICAgICAgICAgXAorICB9CisgIFRFU1RfTUVSR0VfT05FX1BSSU1JVElWRV9GSUVMRChvcHRpb25hbF9pbnQzMikKKyAgVEVTVF9NRVJHRV9PTkVfUFJJTUlUSVZFX0ZJRUxEKG9wdGlvbmFsX2ludDY0KQorICBURVNUX01FUkdFX09ORV9QUklNSVRJVkVfRklFTEQob3B0aW9uYWxfdWludDMyKQorICBURVNUX01FUkdFX09ORV9QUklNSVRJVkVfRklFTEQob3B0aW9uYWxfdWludDY0KQorICBURVNUX01FUkdFX09ORV9QUklNSVRJVkVfRklFTEQob3B0aW9uYWxfc2ludDMyKQorICBURVNUX01FUkdFX09ORV9QUklNSVRJVkVfRklFTEQob3B0aW9uYWxfc2ludDY0KQorICBURVNUX01FUkdFX09ORV9QUklNSVRJVkVfRklFTEQob3B0aW9uYWxfZml4ZWQzMikKKyAgVEVTVF9NRVJHRV9PTkVfUFJJTUlUSVZFX0ZJRUxEKG9wdGlvbmFsX2ZpeGVkNjQpCisgIFRFU1RfTUVSR0VfT05FX1BSSU1JVElWRV9GSUVMRChvcHRpb25hbF9zZml4ZWQzMikKKyAgVEVTVF9NRVJHRV9PTkVfUFJJTUlUSVZFX0ZJRUxEKG9wdGlvbmFsX3NmaXhlZDY0KQorICBURVNUX01FUkdFX09ORV9QUklNSVRJVkVfRklFTEQob3B0aW9uYWxfZmxvYXQpCisgIFRFU1RfTUVSR0VfT05FX1BSSU1JVElWRV9GSUVMRChvcHRpb25hbF9kb3VibGUpCisgIFRFU1RfTUVSR0VfT05FX1BSSU1JVElWRV9GSUVMRChvcHRpb25hbF9ib29sKQorICBURVNUX01FUkdFX09ORV9QUklNSVRJVkVfRklFTEQob3B0aW9uYWxfc3RyaW5nKQorICBURVNUX01FUkdFX09ORV9QUklNSVRJVkVfRklFTEQob3B0aW9uYWxfYnl0ZXMpCisgIFRFU1RfTUVSR0VfT05FX1BSSU1JVElWRV9GSUVMRChvcHRpb25hbF9uZXN0ZWRfZW51bSkKKyAgVEVTVF9NRVJHRV9PTkVfUFJJTUlUSVZFX0ZJRUxEKG9wdGlvbmFsX2ZvcmVpZ25fZW51bSkKKyAgVEVTVF9NRVJHRV9PTkVfUFJJTUlUSVZFX0ZJRUxEKG9wdGlvbmFsX2ltcG9ydF9lbnVtKQorI3VuZGVmIFRFU1RfTUVSR0VfT05FX1BSSU1JVElWRV9GSUVMRAorCisjZGVmaW5lIFRFU1RfTUVSR0VfT05FX0ZJRUxEKGZpZWxkX25hbWUpICAgICAgICAgICAgICAgICAgICAgXAorICB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBUZXN0QWxsVHlwZXMgdG1wOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgKnRtcC5tdXRhYmxlXyMjZmllbGRfbmFtZSgpID0gc3JjLmZpZWxkX25hbWUoKTsgICAgICAgICAgXAorICAgIEZpZWxkTWFzayBtYXNrOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBtYXNrLmFkZF9wYXRocygjZmllbGRfbmFtZSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgZHN0LkNsZWFyKCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIEZpZWxkTWFza1V0aWw6Ok1lcmdlTWVzc2FnZVRvKHNyYywgbWFzaywgb3B0aW9ucywgJmRzdCk7IFwKKyAgICBFWFBFQ1RfRVEodG1wLkRlYnVnU3RyaW5nKCksIGRzdC5EZWJ1Z1N0cmluZygpKTsgICAgICAgICBcCisgIH0KKyAgVEVTVF9NRVJHRV9PTkVfRklFTEQob3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UpCisgIFRFU1RfTUVSR0VfT05FX0ZJRUxEKG9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSkKKyAgVEVTVF9NRVJHRV9PTkVfRklFTEQob3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UpCisKKyAgVEVTVF9NRVJHRV9PTkVfRklFTEQocmVwZWF0ZWRfaW50MzIpCisgIFRFU1RfTUVSR0VfT05FX0ZJRUxEKHJlcGVhdGVkX2ludDY0KQorICBURVNUX01FUkdFX09ORV9GSUVMRChyZXBlYXRlZF91aW50MzIpCisgIFRFU1RfTUVSR0VfT05FX0ZJRUxEKHJlcGVhdGVkX3VpbnQ2NCkKKyAgVEVTVF9NRVJHRV9PTkVfRklFTEQocmVwZWF0ZWRfc2ludDMyKQorICBURVNUX01FUkdFX09ORV9GSUVMRChyZXBlYXRlZF9zaW50NjQpCisgIFRFU1RfTUVSR0VfT05FX0ZJRUxEKHJlcGVhdGVkX2ZpeGVkMzIpCisgIFRFU1RfTUVSR0VfT05FX0ZJRUxEKHJlcGVhdGVkX2ZpeGVkNjQpCisgIFRFU1RfTUVSR0VfT05FX0ZJRUxEKHJlcGVhdGVkX3NmaXhlZDMyKQorICBURVNUX01FUkdFX09ORV9GSUVMRChyZXBlYXRlZF9zZml4ZWQ2NCkKKyAgVEVTVF9NRVJHRV9PTkVfRklFTEQocmVwZWF0ZWRfZmxvYXQpCisgIFRFU1RfTUVSR0VfT05FX0ZJRUxEKHJlcGVhdGVkX2RvdWJsZSkKKyAgVEVTVF9NRVJHRV9PTkVfRklFTEQocmVwZWF0ZWRfYm9vbCkKKyAgVEVTVF9NRVJHRV9PTkVfRklFTEQocmVwZWF0ZWRfc3RyaW5nKQorICBURVNUX01FUkdFX09ORV9GSUVMRChyZXBlYXRlZF9ieXRlcykKKyAgVEVTVF9NRVJHRV9PTkVfRklFTEQocmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UpCisgIFRFU1RfTUVSR0VfT05FX0ZJRUxEKHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSkKKyAgVEVTVF9NRVJHRV9PTkVfRklFTEQocmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UpCisgIFRFU1RfTUVSR0VfT05FX0ZJRUxEKHJlcGVhdGVkX25lc3RlZF9lbnVtKQorICBURVNUX01FUkdFX09ORV9GSUVMRChyZXBlYXRlZF9mb3JlaWduX2VudW0pCisgIFRFU1RfTUVSR0VfT05FX0ZJRUxEKHJlcGVhdGVkX2ltcG9ydF9lbnVtKQorI3VuZGVmIFRFU1RfTUVSR0VfT05FX0ZJRUxECisKKyAgLy8gVGVzdCBtZXJnZSBuZXN0ZWQgZmllbGRzLgorICBOZXN0ZWRUZXN0QWxsVHlwZXMgbmVzdGVkX3NyYywgbmVzdGVkX2RzdDsKKyAgbmVzdGVkX3NyYy5tdXRhYmxlX2NoaWxkKCktPm11dGFibGVfcGF5bG9hZCgpLT5zZXRfb3B0aW9uYWxfaW50MzIoMTIzNCk7CisgIG5lc3RlZF9zcmMubXV0YWJsZV9jaGlsZCgpCisgICAgICAtPm11dGFibGVfY2hpbGQoKQorICAgICAgLT5tdXRhYmxlX3BheWxvYWQoKQorICAgICAgLT5zZXRfb3B0aW9uYWxfaW50MzIoNTY3OCk7CisgIEZpZWxkTWFzayBtYXNrOworICBGaWVsZE1hc2tVdGlsOjpGcm9tU3RyaW5nKCJjaGlsZC5wYXlsb2FkIiwgJm1hc2spOworICBGaWVsZE1hc2tVdGlsOjpNZXJnZU1lc3NhZ2VUbyhuZXN0ZWRfc3JjLCBtYXNrLCBvcHRpb25zLCAmbmVzdGVkX2RzdCk7CisgIEVYUEVDVF9FUSgxMjM0LCBuZXN0ZWRfZHN0LmNoaWxkKCkucGF5bG9hZCgpLm9wdGlvbmFsX2ludDMyKCkpOworICBFWFBFQ1RfRVEoMCwgbmVzdGVkX2RzdC5jaGlsZCgpLmNoaWxkKCkucGF5bG9hZCgpLm9wdGlvbmFsX2ludDMyKCkpOworCisgIEZpZWxkTWFza1V0aWw6OkZyb21TdHJpbmcoImNoaWxkLmNoaWxkLnBheWxvYWQiLCAmbWFzayk7CisgIEZpZWxkTWFza1V0aWw6Ok1lcmdlTWVzc2FnZVRvKG5lc3RlZF9zcmMsIG1hc2ssIG9wdGlvbnMsICZuZXN0ZWRfZHN0KTsKKyAgRVhQRUNUX0VRKDEyMzQsIG5lc3RlZF9kc3QuY2hpbGQoKS5wYXlsb2FkKCkub3B0aW9uYWxfaW50MzIoKSk7CisgIEVYUEVDVF9FUSg1Njc4LCBuZXN0ZWRfZHN0LmNoaWxkKCkuY2hpbGQoKS5wYXlsb2FkKCkub3B0aW9uYWxfaW50MzIoKSk7CisKKyAgbmVzdGVkX2RzdC5DbGVhcigpOworICBGaWVsZE1hc2tVdGlsOjpGcm9tU3RyaW5nKCJjaGlsZC5jaGlsZC5wYXlsb2FkIiwgJm1hc2spOworICBGaWVsZE1hc2tVdGlsOjpNZXJnZU1lc3NhZ2VUbyhuZXN0ZWRfc3JjLCBtYXNrLCBvcHRpb25zLCAmbmVzdGVkX2RzdCk7CisgIEVYUEVDVF9FUSgwLCBuZXN0ZWRfZHN0LmNoaWxkKCkucGF5bG9hZCgpLm9wdGlvbmFsX2ludDMyKCkpOworICBFWFBFQ1RfRVEoNTY3OCwgbmVzdGVkX2RzdC5jaGlsZCgpLmNoaWxkKCkucGF5bG9hZCgpLm9wdGlvbmFsX2ludDMyKCkpOworCisgIG5lc3RlZF9kc3QuQ2xlYXIoKTsKKyAgRmllbGRNYXNrVXRpbDo6RnJvbVN0cmluZygiY2hpbGQiLCAmbWFzayk7CisgIEZpZWxkTWFza1V0aWw6Ok1lcmdlTWVzc2FnZVRvKG5lc3RlZF9zcmMsIG1hc2ssIG9wdGlvbnMsICZuZXN0ZWRfZHN0KTsKKyAgRVhQRUNUX0VRKDEyMzQsIG5lc3RlZF9kc3QuY2hpbGQoKS5wYXlsb2FkKCkub3B0aW9uYWxfaW50MzIoKSk7CisgIEVYUEVDVF9FUSg1Njc4LCBuZXN0ZWRfZHN0LmNoaWxkKCkuY2hpbGQoKS5wYXlsb2FkKCkub3B0aW9uYWxfaW50MzIoKSk7CisKKyAgLy8gVGVzdCBNZXJnZU9wdGlvbnMuCisKKyAgbmVzdGVkX2RzdC5DbGVhcigpOworICBuZXN0ZWRfZHN0Lm11dGFibGVfY2hpbGQoKS0+bXV0YWJsZV9wYXlsb2FkKCktPnNldF9vcHRpb25hbF9pbnQ2NCg0MzIxKTsKKyAgLy8gTWVzc2FnZSBmaWVsZHMgd2lsbCBiZSBtZXJnZWQgYnkgZGVmYXVsdC4KKyAgRmllbGRNYXNrVXRpbDo6RnJvbVN0cmluZygiY2hpbGQucGF5bG9hZCIsICZtYXNrKTsKKyAgRmllbGRNYXNrVXRpbDo6TWVyZ2VNZXNzYWdlVG8obmVzdGVkX3NyYywgbWFzaywgb3B0aW9ucywgJm5lc3RlZF9kc3QpOworICBFWFBFQ1RfRVEoMTIzNCwgbmVzdGVkX2RzdC5jaGlsZCgpLnBheWxvYWQoKS5vcHRpb25hbF9pbnQzMigpKTsKKyAgRVhQRUNUX0VRKDQzMjEsIG5lc3RlZF9kc3QuY2hpbGQoKS5wYXlsb2FkKCkub3B0aW9uYWxfaW50NjQoKSk7CisgIC8vIENoYW5nZSB0aGUgYmVoYXZpb3IgdG8gcmVwbGFjZSBtZXNzYWdlIGZpZWxkcy4KKyAgb3B0aW9ucy5zZXRfcmVwbGFjZV9tZXNzYWdlX2ZpZWxkcyh0cnVlKTsKKyAgRmllbGRNYXNrVXRpbDo6RnJvbVN0cmluZygiY2hpbGQucGF5bG9hZCIsICZtYXNrKTsKKyAgRmllbGRNYXNrVXRpbDo6TWVyZ2VNZXNzYWdlVG8obmVzdGVkX3NyYywgbWFzaywgb3B0aW9ucywgJm5lc3RlZF9kc3QpOworICBFWFBFQ1RfRVEoMTIzNCwgbmVzdGVkX2RzdC5jaGlsZCgpLnBheWxvYWQoKS5vcHRpb25hbF9pbnQzMigpKTsKKyAgRVhQRUNUX0VRKDAsIG5lc3RlZF9kc3QuY2hpbGQoKS5wYXlsb2FkKCkub3B0aW9uYWxfaW50NjQoKSk7CisKKyAgLy8gQnkgZGVmYXVsdCwgZmllbGRzIG1pc3NpbmcgaW4gc291cmNlIGFyZSBub3QgY2xlYXJlZCBpbiBkZXN0aW5hdGlvbi4KKyAgb3B0aW9ucy5zZXRfcmVwbGFjZV9tZXNzYWdlX2ZpZWxkcyhmYWxzZSk7CisgIG5lc3RlZF9kc3QubXV0YWJsZV9wYXlsb2FkKCk7CisgIEVYUEVDVF9UUlVFKG5lc3RlZF9kc3QuaGFzX3BheWxvYWQoKSk7CisgIEZpZWxkTWFza1V0aWw6OkZyb21TdHJpbmcoInBheWxvYWQiLCAmbWFzayk7CisgIEZpZWxkTWFza1V0aWw6Ok1lcmdlTWVzc2FnZVRvKG5lc3RlZF9zcmMsIG1hc2ssIG9wdGlvbnMsICZuZXN0ZWRfZHN0KTsKKyAgRVhQRUNUX1RSVUUobmVzdGVkX2RzdC5oYXNfcGF5bG9hZCgpKTsKKyAgLy8gQnV0IHRoZXkgYXJlIGNsZWFyZWQgd2hlbiByZXBsYWNpbmcgbWVzc2FnZSBmaWVsZHMuCisgIG9wdGlvbnMuc2V0X3JlcGxhY2VfbWVzc2FnZV9maWVsZHModHJ1ZSk7CisgIG5lc3RlZF9kc3QuQ2xlYXIoKTsKKyAgbmVzdGVkX2RzdC5tdXRhYmxlX3BheWxvYWQoKTsKKyAgRmllbGRNYXNrVXRpbDo6RnJvbVN0cmluZygicGF5bG9hZCIsICZtYXNrKTsKKyAgRmllbGRNYXNrVXRpbDo6TWVyZ2VNZXNzYWdlVG8obmVzdGVkX3NyYywgbWFzaywgb3B0aW9ucywgJm5lc3RlZF9kc3QpOworICBFWFBFQ1RfRkFMU0UobmVzdGVkX2RzdC5oYXNfcGF5bG9hZCgpKTsKKworICBuZXN0ZWRfc3JjLm11dGFibGVfcGF5bG9hZCgpLT5hZGRfcmVwZWF0ZWRfaW50MzIoMTIzNCk7CisgIG5lc3RlZF9kc3QubXV0YWJsZV9wYXlsb2FkKCktPmFkZF9yZXBlYXRlZF9pbnQzMig1Njc4KTsKKyAgLy8gUmVwZWF0ZWQgZmllbGRzIHdpbGwgYmUgYXBwZW5kZWQgYnkgZGVmYXVsdC4KKyAgRmllbGRNYXNrVXRpbDo6RnJvbVN0cmluZygicGF5bG9hZC5yZXBlYXRlZF9pbnQzMiIsICZtYXNrKTsKKyAgRmllbGRNYXNrVXRpbDo6TWVyZ2VNZXNzYWdlVG8obmVzdGVkX3NyYywgbWFzaywgb3B0aW9ucywgJm5lc3RlZF9kc3QpOworICBBU1NFUlRfRVEoMiwgbmVzdGVkX2RzdC5wYXlsb2FkKCkucmVwZWF0ZWRfaW50MzJfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDU2NzgsIG5lc3RlZF9kc3QucGF5bG9hZCgpLnJlcGVhdGVkX2ludDMyKDApKTsKKyAgRVhQRUNUX0VRKDEyMzQsIG5lc3RlZF9kc3QucGF5bG9hZCgpLnJlcGVhdGVkX2ludDMyKDEpKTsKKyAgLy8gQ2hhbmdlIHRoZSBiZWhhdmlvciB0byByZXBsYWNlIHJlcGVhdGVkIGZpZWxkcy4KKyAgb3B0aW9ucy5zZXRfcmVwbGFjZV9yZXBlYXRlZF9maWVsZHModHJ1ZSk7CisgIEZpZWxkTWFza1V0aWw6OkZyb21TdHJpbmcoInBheWxvYWQucmVwZWF0ZWRfaW50MzIiLCAmbWFzayk7CisgIEZpZWxkTWFza1V0aWw6Ok1lcmdlTWVzc2FnZVRvKG5lc3RlZF9zcmMsIG1hc2ssIG9wdGlvbnMsICZuZXN0ZWRfZHN0KTsKKyAgQVNTRVJUX0VRKDEsIG5lc3RlZF9kc3QucGF5bG9hZCgpLnJlcGVhdGVkX2ludDMyX3NpemUoKSk7CisgIEVYUEVDVF9FUSgxMjM0LCBuZXN0ZWRfZHN0LnBheWxvYWQoKS5yZXBlYXRlZF9pbnQzMigwKSk7Cit9CisKKworfSAgLy8gbmFtZXNwYWNlCit9ICAvLyBuYW1lc3BhY2UgdXRpbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvY29uc3RhbnRzLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvY29uc3RhbnRzLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGNiOGY2ZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9jb25zdGFudHMuaApAQCAtMCwwICsxLDkzIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfVVRJTF9DT05WRVJURVJfQ09OU1RBTlRTX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfVVRJTF9DT05WRVJURVJfQ09OU1RBTlRTX0hfXworCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorCisvLyBUaGlzIGZpbGUgY29udGFpbnMgY29uc3RhbnRzIHVzZWQgYnkgLy9uZXQvcHJvdG8yL3V0aWwvY29udmVydGVyLgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgdXRpbCB7CituYW1lc3BhY2UgY29udmVydGVyIHsKKy8vIFByZWZpeCBmb3IgdHlwZSBVUkxzLgorY29uc3QgY2hhciBrVHlwZVNlcnZpY2VCYXNlVXJsW10gPSAidHlwZS5nb29nbGVhcGlzLmNvbSI7CisKKy8vIEZvcm1hdCBzdHJpbmcgZm9yIFJGQzMzMzkgdGltZXN0YW1wIGZvcm1hdHRpbmcuCitjb25zdCBjaGFyIGtSZmMzMzM5VGltZUZvcm1hdFtdID0gIiVZLSVtLSVkVCVIOiVNOiVTIjsKKworLy8gTWluaW11bSBzZWNvbmRzIGFsbG93ZWQgaW4gYSBnb29nbGUucHJvdG9idWYuVGltZVN0YW1wIG9yIER1cmF0aW9uIHZhbHVlLgorY29uc3QgaW50NjQga01pblNlY29uZHMgPSAtMzE1NTc2MDAwMDAwOworCisvLyBNYXhpbXVtIHNlY29uZHMgYWxsb3dlZCBpbiBhIGdvb2dsZS5wcm90b2J1Zi5UaW1lU3RhbXAgb3IgRHVyYXRpb24gdmFsdWUuCitjb25zdCBpbnQ2NCBrTWF4U2Vjb25kcyA9IDMxNTU3NjAwMDAwMDsKKworLy8gTmFubyBzZWNvbmRzIGluIGEgc2Vjb25kLgorY29uc3QgaW50MzIga05hbm9zUGVyU2Vjb25kID0gMTAwMDAwMDAwMDsKKworLy8gVHlwZSB1cmwgcmVwcmVzZW50aW5nIE5VTEwgdmFsdWVzIGluIGdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QgdHlwZS4KK2NvbnN0IGNoYXIga1N0cnVjdE51bGxWYWx1ZVR5cGVVcmxbXSA9CisgICAgInR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLnByb3RvYnVmLk51bGxWYWx1ZSI7CisKKy8vIFR5cGUgc3RyaW5nIGZvciBnb29nbGUucHJvdG9idWYuU3RydWN0Citjb25zdCBjaGFyIGtTdHJ1Y3RUeXBlW10gPSAiZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCI7CisKKy8vIFR5cGUgc3RyaW5nIGZvciBzdHJ1Y3QucHJvdG8ncyBnb29nbGUucHJvdG9idWYuVmFsdWUgdmFsdWUgdHlwZS4KK2NvbnN0IGNoYXIga1N0cnVjdFZhbHVlVHlwZVtdID0gImdvb2dsZS5wcm90b2J1Zi5WYWx1ZSI7CisKKy8vIFR5cGUgc3RyaW5nIGZvciBzdHJ1Y3QucHJvdG8ncyBnb29nbGUucHJvdG9idWYuTGlzdFZhbHVlIHZhbHVlIHR5cGUuCitjb25zdCBjaGFyIGtTdHJ1Y3RMaXN0VmFsdWVUeXBlW10gPSAiZ29vZ2xlLnByb3RvYnVmLkxpc3RWYWx1ZSI7CisKKy8vIFR5cGUgc3RyaW5nIGZvciBnb29nbGUucHJvdG9idWYuVGltZXN0YW1wCitjb25zdCBjaGFyIGtUaW1lc3RhbXBUeXBlW10gPSAiZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCI7CisKKy8vIFR5cGUgc3RyaW5nIGZvciBnb29nbGUucHJvdG9idWYuRHVyYXRpb24KK2NvbnN0IGNoYXIga0R1cmF0aW9uVHlwZVtdID0gImdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiI7CisKKy8vIFR5cGUgVVJMIGZvciBzdHJ1Y3QgdmFsdWUgdHlwZSBnb29nbGUucHJvdG9idWYuVmFsdWUKK2NvbnN0IGNoYXIga1N0cnVjdFZhbHVlVHlwZVVybFtdID0gInR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLnByb3RvYnVmLlZhbHVlIjsKKworLy8gVHlwZSBVUkwgZm9yIHN0cnVjdCB2YWx1ZSB0eXBlIGdvb2dsZS5wcm90b2J1Zi5WYWx1ZQorY29uc3QgY2hhciBrU3RydWN0VHlwZVVybFtdID0gInR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCI7CisKKy8vIFR5cGUgc3RyaW5nIGZvciBnb29nbGUucHJvdG9idWYuQW55Citjb25zdCBjaGFyIGtBbnlUeXBlW10gPSAiZ29vZ2xlLnByb3RvYnVmLkFueSI7CisKKy8vIFRoZSB0eXBlIFVSTCBvZiBnb29nbGUucHJvdG9idWYuRmllbGRNYXNrOworY29uc3QgY2hhciBrRmllbGRNYXNrVHlwZVVybFtdID0KKyAgICAidHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIjsKKworfSAgLy8gbmFtZXNwYWNlIGNvbnZlcnRlcgorfSAgLy8gbmFtZXNwYWNlIHV0aWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfVVRJTF9DT05WRVJURVJfQ09OU1RBTlRTX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL2RhdGFwaWVjZS5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9kYXRhcGllY2UuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjU1NzQyOQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9kYXRhcGllY2UuY2MKQEAgLTAsMCArMSwzMjQgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvZGF0YXBpZWNlLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3RydWN0LnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3R5cGUucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3V0aWxpdHkuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9tYXRobGltaXRzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL21hdGh1dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSB1dGlsIHsKK25hbWVzcGFjZSBjb252ZXJ0ZXIgeworCit1c2luZyBnb29nbGU6OnByb3RvYnVmOjpFbnVtRGVzY3JpcHRvcjsKK3VzaW5nIGdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZURlc2NyaXB0b3I7Cis7Cis7Cit1c2luZyB1dGlsOjplcnJvcjo6Q29kZTsKK3VzaW5nIHV0aWw6OlN0YXR1czsKK3VzaW5nIHV0aWw6OlN0YXR1c09yOworCituYW1lc3BhY2UgeworCitpbmxpbmUgU3RhdHVzIEludmFsaWRBcmd1bWVudChTdHJpbmdQaWVjZSB2YWx1ZV9zdHIpIHsKKyAgcmV0dXJuIFN0YXR1cyh1dGlsOjplcnJvcjo6SU5WQUxJRF9BUkdVTUVOVCwgdmFsdWVfc3RyKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIFRvLCB0eXBlbmFtZSBGcm9tPgorU3RhdHVzT3I8VG8+IFZhbGlkYXRlTnVtYmVyQ29udmVyc2lvbihUbyBhZnRlciwgRnJvbSBiZWZvcmUpIHsKKyAgaWYgKGFmdGVyID09IGJlZm9yZSAmJgorICAgICAgTWF0aFV0aWw6OlNpZ248RnJvbT4oYmVmb3JlKSA9PSBNYXRoVXRpbDo6U2lnbjxUbz4oYWZ0ZXIpKSB7CisgICAgcmV0dXJuIGFmdGVyOworICB9IGVsc2UgeworICAgIHJldHVybiBJbnZhbGlkQXJndW1lbnQoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6aXNfaW50ZWdyYWw8RnJvbT46OnZhbHVlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBWYWx1ZUFzU3RyaW5nKGJlZm9yZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OmlzX3NhbWU8RnJvbSwgZG91YmxlPjo6dmFsdWUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IERvdWJsZUFzU3RyaW5nKGJlZm9yZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IEZsb2F0QXNTdHJpbmcoYmVmb3JlKSk7CisgIH0KK30KKworLy8gRm9yIGdlbmVyYWwgY29udmVyc2lvbiBiZXR3ZWVuCisvLyAgICAgaW50MzIsIGludDY0LCB1aW50MzIsIHVpbnQ2NCwgZG91YmxlIGFuZCBmbG9hdAorLy8gZXhjZXB0IGNvbnZlcnNpb24gYmV0d2VlbiBkb3VibGUgYW5kIGZsb2F0LgordGVtcGxhdGUgPHR5cGVuYW1lIFRvLCB0eXBlbmFtZSBGcm9tPgorU3RhdHVzT3I8VG8+IE51bWJlckNvbnZlcnRBbmRDaGVjayhGcm9tIGJlZm9yZSkgeworICBpZiAoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6aXNfc2FtZTxGcm9tLCBUbz46OnZhbHVlKSByZXR1cm4gYmVmb3JlOworCisgIFRvIGFmdGVyID0gc3RhdGljX2Nhc3Q8VG8+KGJlZm9yZSk7CisgIHJldHVybiBWYWxpZGF0ZU51bWJlckNvbnZlcnNpb24oYWZ0ZXIsIGJlZm9yZSk7Cit9CisKKy8vIEZvciBjb252ZXJzaW9uIHRvIGludGVnZXIgdHlwZXMgKGludDMyLCBpbnQ2NCwgdWludDMyLCB1aW50NjQpIGZyb20gZmxvYXRpbmcKKy8vIHBvaW50IHR5cGVzIChkb3VibGUsIGZsb2F0KSBvbmx5LgordGVtcGxhdGUgPHR5cGVuYW1lIFRvLCB0eXBlbmFtZSBGcm9tPgorU3RhdHVzT3I8VG8+IEZsb2F0aW5nUG9pbnRUb0ludENvbnZlcnRBbmRDaGVjayhGcm9tIGJlZm9yZSkgeworICBpZiAoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6aXNfc2FtZTxGcm9tLCBUbz46OnZhbHVlKSByZXR1cm4gYmVmb3JlOworCisgIFRvIGFmdGVyID0gc3RhdGljX2Nhc3Q8VG8+KGJlZm9yZSk7CisgIHJldHVybiBWYWxpZGF0ZU51bWJlckNvbnZlcnNpb24oYWZ0ZXIsIGJlZm9yZSk7Cit9CisKKy8vIEZvciBjb252ZXJzaW9uIGJldHdlZW4gZG91YmxlIGFuZCBmbG9hdCBvbmx5LgordGVtcGxhdGUgPHR5cGVuYW1lIFRvLCB0eXBlbmFtZSBGcm9tPgorU3RhdHVzT3I8VG8+IEZsb2F0aW5nUG9pbnRDb252ZXJ0QW5kQ2hlY2soRnJvbSBiZWZvcmUpIHsKKyAgaWYgKE1hdGhMaW1pdHM8RnJvbT46OklzTmFOKGJlZm9yZSkpIHsKKyAgICByZXR1cm4gc3RkOjpudW1lcmljX2xpbWl0czxUbz46OnF1aWV0X05hTigpOworICB9CisKKyAgVG8gYWZ0ZXIgPSBzdGF0aWNfY2FzdDxUbz4oYmVmb3JlKTsKKyAgaWYgKE1hdGhVdGlsOjpBbG1vc3RFcXVhbHM8VG8+KGFmdGVyLCBiZWZvcmUpKSB7CisgICAgcmV0dXJuIGFmdGVyOworICB9IGVsc2UgeworICAgIHJldHVybiBJbnZhbGlkQXJndW1lbnQoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6aXNfc2FtZTxGcm9tLCBkb3VibGU+Ojp2YWx1ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gRG91YmxlQXNTdHJpbmcoYmVmb3JlKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogRmxvYXRBc1N0cmluZyhiZWZvcmUpKTsKKyAgfQorfQorCit9ICAvLyBuYW1lc3BhY2UKKworU3RhdHVzT3I8aW50MzI+IERhdGFQaWVjZTo6VG9JbnQzMigpIGNvbnN0IHsKKyAgaWYgKHR5cGVfID09IFRZUEVfU1RSSU5HKSByZXR1cm4gU3RyaW5nVG9OdW1iZXI8aW50MzI+KHNhZmVfc3RydG8zMik7CisKKyAgaWYgKHR5cGVfID09IFRZUEVfRE9VQkxFKQorICAgIHJldHVybiBGbG9hdGluZ1BvaW50VG9JbnRDb252ZXJ0QW5kQ2hlY2s8aW50MzIsIGRvdWJsZT4oZG91YmxlXyk7CisKKyAgaWYgKHR5cGVfID09IFRZUEVfRkxPQVQpCisgICAgcmV0dXJuIEZsb2F0aW5nUG9pbnRUb0ludENvbnZlcnRBbmRDaGVjazxpbnQzMiwgZmxvYXQ+KGZsb2F0Xyk7CisKKyAgcmV0dXJuIEdlbmVyaWNDb252ZXJ0PGludDMyPigpOworfQorCitTdGF0dXNPcjx1aW50MzI+IERhdGFQaWVjZTo6VG9VaW50MzIoKSBjb25zdCB7CisgIGlmICh0eXBlXyA9PSBUWVBFX1NUUklORykgcmV0dXJuIFN0cmluZ1RvTnVtYmVyPHVpbnQzMj4oc2FmZV9zdHJ0b3UzMik7CisKKyAgaWYgKHR5cGVfID09IFRZUEVfRE9VQkxFKQorICAgIHJldHVybiBGbG9hdGluZ1BvaW50VG9JbnRDb252ZXJ0QW5kQ2hlY2s8dWludDMyLCBkb3VibGU+KGRvdWJsZV8pOworCisgIGlmICh0eXBlXyA9PSBUWVBFX0ZMT0FUKQorICAgIHJldHVybiBGbG9hdGluZ1BvaW50VG9JbnRDb252ZXJ0QW5kQ2hlY2s8dWludDMyLCBmbG9hdD4oZmxvYXRfKTsKKworICByZXR1cm4gR2VuZXJpY0NvbnZlcnQ8dWludDMyPigpOworfQorCitTdGF0dXNPcjxpbnQ2ND4gRGF0YVBpZWNlOjpUb0ludDY0KCkgY29uc3QgeworICBpZiAodHlwZV8gPT0gVFlQRV9TVFJJTkcpIHJldHVybiBTdHJpbmdUb051bWJlcjxpbnQ2ND4oc2FmZV9zdHJ0bzY0KTsKKworICBpZiAodHlwZV8gPT0gVFlQRV9ET1VCTEUpCisgICAgcmV0dXJuIEZsb2F0aW5nUG9pbnRUb0ludENvbnZlcnRBbmRDaGVjazxpbnQ2NCwgZG91YmxlPihkb3VibGVfKTsKKworICBpZiAodHlwZV8gPT0gVFlQRV9GTE9BVCkKKyAgICByZXR1cm4gRmxvYXRpbmdQb2ludFRvSW50Q29udmVydEFuZENoZWNrPGludDY0LCBmbG9hdD4oZmxvYXRfKTsKKworICByZXR1cm4gR2VuZXJpY0NvbnZlcnQ8aW50NjQ+KCk7Cit9CisKK1N0YXR1c09yPHVpbnQ2ND4gRGF0YVBpZWNlOjpUb1VpbnQ2NCgpIGNvbnN0IHsKKyAgaWYgKHR5cGVfID09IFRZUEVfU1RSSU5HKSByZXR1cm4gU3RyaW5nVG9OdW1iZXI8dWludDY0PihzYWZlX3N0cnRvdTY0KTsKKworICBpZiAodHlwZV8gPT0gVFlQRV9ET1VCTEUpCisgICAgcmV0dXJuIEZsb2F0aW5nUG9pbnRUb0ludENvbnZlcnRBbmRDaGVjazx1aW50NjQsIGRvdWJsZT4oZG91YmxlXyk7CisKKyAgaWYgKHR5cGVfID09IFRZUEVfRkxPQVQpCisgICAgcmV0dXJuIEZsb2F0aW5nUG9pbnRUb0ludENvbnZlcnRBbmRDaGVjazx1aW50NjQsIGZsb2F0PihmbG9hdF8pOworCisgIHJldHVybiBHZW5lcmljQ29udmVydDx1aW50NjQ+KCk7Cit9CisKK1N0YXR1c09yPGRvdWJsZT4gRGF0YVBpZWNlOjpUb0RvdWJsZSgpIGNvbnN0IHsKKyAgaWYgKHR5cGVfID09IFRZUEVfRkxPQVQpIHsKKyAgICByZXR1cm4gRmxvYXRpbmdQb2ludENvbnZlcnRBbmRDaGVjazxkb3VibGUsIGZsb2F0PihmbG9hdF8pOworICB9CisgIGlmICh0eXBlXyA9PSBUWVBFX1NUUklORykgeworICAgIGlmIChzdHJfID09ICJJbmZpbml0eSIpIHJldHVybiBzdGQ6Om51bWVyaWNfbGltaXRzPGRvdWJsZT46OmluZmluaXR5KCk7CisgICAgaWYgKHN0cl8gPT0gIi1JbmZpbml0eSIpIHJldHVybiAtc3RkOjpudW1lcmljX2xpbWl0czxkb3VibGU+OjppbmZpbml0eSgpOworICAgIGlmIChzdHJfID09ICJOYU4iKSByZXR1cm4gc3RkOjpudW1lcmljX2xpbWl0czxkb3VibGU+OjpxdWlldF9OYU4oKTsKKyAgICByZXR1cm4gU3RyaW5nVG9OdW1iZXI8ZG91YmxlPihzYWZlX3N0cnRvZCk7CisgIH0KKyAgcmV0dXJuIEdlbmVyaWNDb252ZXJ0PGRvdWJsZT4oKTsKK30KKworU3RhdHVzT3I8ZmxvYXQ+IERhdGFQaWVjZTo6VG9GbG9hdCgpIGNvbnN0IHsKKyAgaWYgKHR5cGVfID09IFRZUEVfRE9VQkxFKSB7CisgICAgcmV0dXJuIEZsb2F0aW5nUG9pbnRDb252ZXJ0QW5kQ2hlY2s8ZmxvYXQsIGRvdWJsZT4oZG91YmxlXyk7CisgIH0KKyAgaWYgKHR5cGVfID09IFRZUEVfU1RSSU5HKSB7CisgICAgaWYgKHN0cl8gPT0gIkluZmluaXR5IikgcmV0dXJuIHN0ZDo6bnVtZXJpY19saW1pdHM8ZmxvYXQ+OjppbmZpbml0eSgpOworICAgIGlmIChzdHJfID09ICItSW5maW5pdHkiKSByZXR1cm4gLXN0ZDo6bnVtZXJpY19saW1pdHM8ZmxvYXQ+OjppbmZpbml0eSgpOworICAgIGlmIChzdHJfID09ICJOYU4iKSByZXR1cm4gc3RkOjpudW1lcmljX2xpbWl0czxmbG9hdD46OnF1aWV0X05hTigpOworICAgIC8vIFNhZmVTdHJUb0Zsb2F0KCkgaXMgdXNlZCBpbnN0ZWFkIG9mIHNhZmVfc3RydG9mKCkgYmVjYXVzZSB0aGUgbGF0ZXIKKyAgICAvLyBkb2VzIG5vdCBmYWlsIG9uIGlucHV0cyBsaWtlIFNpbXBsZUR0b2EoREJMX01BWCkuCisgICAgcmV0dXJuIFN0cmluZ1RvTnVtYmVyPGZsb2F0PihTYWZlU3RyVG9GbG9hdCk7CisgIH0KKyAgcmV0dXJuIEdlbmVyaWNDb252ZXJ0PGZsb2F0PigpOworfQorCitTdGF0dXNPcjxib29sPiBEYXRhUGllY2U6OlRvQm9vbCgpIGNvbnN0IHsKKyAgc3dpdGNoICh0eXBlXykgeworICAgIGNhc2UgVFlQRV9CT09MOgorICAgICAgcmV0dXJuIGJvb2xfOworICAgIGNhc2UgVFlQRV9TVFJJTkc6CisgICAgICByZXR1cm4gU3RyaW5nVG9OdW1iZXI8Ym9vbD4oc2FmZV9zdHJ0b2IpOworICAgIGRlZmF1bHQ6CisgICAgICByZXR1cm4gSW52YWxpZEFyZ3VtZW50KAorICAgICAgICAgIFZhbHVlQXNTdHJpbmdPckRlZmF1bHQoIldyb25nIHR5cGUuIENhbm5vdCBjb252ZXJ0IHRvIEJvb2wuIikpOworICB9Cit9CisKK1N0YXR1c09yPHN0cmluZz4gRGF0YVBpZWNlOjpUb1N0cmluZygpIGNvbnN0IHsKKyAgc3dpdGNoICh0eXBlXykgeworICAgIGNhc2UgVFlQRV9TVFJJTkc6CisgICAgICByZXR1cm4gc3RyXy5Ub1N0cmluZygpOworICAgIGNhc2UgVFlQRV9CWVRFUzogeworICAgICAgc3RyaW5nIGJhc2U2NDsKKyAgICAgIEJhc2U2NEVzY2FwZShzdHJfLCAmYmFzZTY0KTsKKyAgICAgIHJldHVybiBiYXNlNjQ7CisgICAgfQorICAgIGRlZmF1bHQ6CisgICAgICByZXR1cm4gSW52YWxpZEFyZ3VtZW50KAorICAgICAgICAgIFZhbHVlQXNTdHJpbmdPckRlZmF1bHQoIkNhbm5vdCBjb252ZXJ0IHRvIHN0cmluZy4iKSk7CisgIH0KK30KKworc3RyaW5nIERhdGFQaWVjZTo6VmFsdWVBc1N0cmluZ09yRGVmYXVsdChTdHJpbmdQaWVjZSBkZWZhdWx0X3N0cmluZykgY29uc3QgeworICBzd2l0Y2ggKHR5cGVfKSB7CisgICAgY2FzZSBUWVBFX0lOVDMyOgorICAgICAgcmV0dXJuIFNpbXBsZUl0b2EoaTMyXyk7CisgICAgY2FzZSBUWVBFX0lOVDY0OgorICAgICAgcmV0dXJuIFNpbXBsZUl0b2EoaTY0Xyk7CisgICAgY2FzZSBUWVBFX1VJTlQzMjoKKyAgICAgIHJldHVybiBTaW1wbGVJdG9hKHUzMl8pOworICAgIGNhc2UgVFlQRV9VSU5UNjQ6CisgICAgICByZXR1cm4gU2ltcGxlSXRvYSh1NjRfKTsKKyAgICBjYXNlIFRZUEVfRE9VQkxFOgorICAgICAgcmV0dXJuIERvdWJsZUFzU3RyaW5nKGRvdWJsZV8pOworICAgIGNhc2UgVFlQRV9GTE9BVDoKKyAgICAgIHJldHVybiBGbG9hdEFzU3RyaW5nKGZsb2F0Xyk7CisgICAgY2FzZSBUWVBFX0JPT0w6CisgICAgICByZXR1cm4gU2ltcGxlQnRvYShib29sXyk7CisgICAgY2FzZSBUWVBFX1NUUklORzoKKyAgICAgIHJldHVybiBTdHJDYXQoIlwiIiwgc3RyXy5Ub1N0cmluZygpLCAiXCIiKTsKKyAgICBjYXNlIFRZUEVfQllURVM6IHsKKyAgICAgIHN0cmluZyBiYXNlNjQ7CisgICAgICBXZWJTYWZlQmFzZTY0RXNjYXBlKHN0cl8sICZiYXNlNjQpOworICAgICAgcmV0dXJuIFN0ckNhdCgiXCIiLCBiYXNlNjQsICJcIiIpOworICAgIH0KKyAgICBjYXNlIFRZUEVfTlVMTDoKKyAgICAgIHJldHVybiAibnVsbCI7CisgICAgZGVmYXVsdDoKKyAgICAgIHJldHVybiBkZWZhdWx0X3N0cmluZy5Ub1N0cmluZygpOworICB9Cit9CisKK1N0YXR1c09yPHN0cmluZz4gRGF0YVBpZWNlOjpUb0J5dGVzKCkgY29uc3QgeworICBpZiAodHlwZV8gPT0gVFlQRV9CWVRFUykgcmV0dXJuIHN0cl8uVG9TdHJpbmcoKTsKKyAgaWYgKHR5cGVfID09IFRZUEVfU1RSSU5HKSB7CisgICAgc3RyaW5nIGRlY29kZWQ7CisgICAgaWYgKCFXZWJTYWZlQmFzZTY0VW5lc2NhcGUoc3RyXywgJmRlY29kZWQpKSB7CisgICAgICBpZiAoIUJhc2U2NFVuZXNjYXBlKHN0cl8sICZkZWNvZGVkKSkgeworICAgICAgICByZXR1cm4gSW52YWxpZEFyZ3VtZW50KAorICAgICAgICAgICAgVmFsdWVBc1N0cmluZ09yRGVmYXVsdCgiSW52YWxpZCBkYXRhIGluIGlucHV0LiIpKTsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIGRlY29kZWQ7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIEludmFsaWRBcmd1bWVudChWYWx1ZUFzU3RyaW5nT3JEZWZhdWx0KAorICAgICAgICAiV3JvbmcgdHlwZS4gT25seSBTdHJpbmcgb3IgQnl0ZXMgY2FuIGJlIGNvbnZlcnRlZCB0byBCeXRlcy4iKSk7CisgIH0KK30KKworU3RhdHVzT3I8aW50PiBEYXRhUGllY2U6OlRvRW51bShjb25zdCBnb29nbGU6OnByb3RvYnVmOjpFbnVtKiBlbnVtX3R5cGUpIGNvbnN0IHsKKyAgaWYgKHR5cGVfID09IFRZUEVfTlVMTCkgcmV0dXJuIGdvb2dsZTo6cHJvdG9idWY6Ok5VTExfVkFMVUU7CisKKyAgaWYgKHR5cGVfID09IFRZUEVfU1RSSU5HKSB7CisgICAgLy8gRmlyc3QgdHJ5IHRoZSBnaXZlbiB2YWx1ZSBhcyBhIG5hbWUuCisgICAgc3RyaW5nIGVudW1fbmFtZSA9IHN0cl8uVG9TdHJpbmcoKTsKKyAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpFbnVtVmFsdWUqIHZhbHVlID0KKyAgICAgICAgRmluZEVudW1WYWx1ZUJ5TmFtZU9yTnVsbChlbnVtX3R5cGUsIGVudW1fbmFtZSk7CisgICAgaWYgKHZhbHVlICE9IE5VTEwpIHJldHVybiB2YWx1ZS0+bnVtYmVyKCk7CisgICAgLy8gTmV4dCB0cnkgYSBub3JtYWxpemVkIG5hbWUuCisgICAgZm9yIChzdHJpbmc6Oml0ZXJhdG9yIGl0ID0gZW51bV9uYW1lLmJlZ2luKCk7IGl0ICE9IGVudW1fbmFtZS5lbmQoKTsgKytpdCkgeworICAgICAgKml0ID0gKml0ID09ICctJyA/ICdfJyA6IGFzY2lpX3RvdXBwZXIoKml0KTsKKyAgICB9CisgICAgdmFsdWUgPSBGaW5kRW51bVZhbHVlQnlOYW1lT3JOdWxsKGVudW1fdHlwZSwgZW51bV9uYW1lKTsKKyAgICBpZiAodmFsdWUgIT0gTlVMTCkgcmV0dXJuIHZhbHVlLT5udW1iZXIoKTsKKyAgfSBlbHNlIHsKKyAgICBTdGF0dXNPcjxpbnQzMj4gdmFsdWUgPSBUb0ludDMyKCk7CisgICAgaWYgKHZhbHVlLm9rKCkpIHsKKyAgICAgIGlmIChjb25zdCBnb29nbGU6OnByb3RvYnVmOjpFbnVtVmFsdWUqIGVudW1fdmFsdWUgPQorICAgICAgICAgICAgICBGaW5kRW51bVZhbHVlQnlOdW1iZXJPck51bGwoZW51bV90eXBlLCB2YWx1ZS5WYWx1ZU9yRGllKCkpKSB7CisgICAgICAgIHJldHVybiBlbnVtX3ZhbHVlLT5udW1iZXIoKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKyAgcmV0dXJuIEludmFsaWRBcmd1bWVudCgKKyAgICAgIFZhbHVlQXNTdHJpbmdPckRlZmF1bHQoIkNhbm5vdCBmaW5kIGVudW0gd2l0aCBnaXZlbiB2YWx1ZS4iKSk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBUbz4KK1N0YXR1c09yPFRvPiBEYXRhUGllY2U6OkdlbmVyaWNDb252ZXJ0KCkgY29uc3QgeworICBzd2l0Y2ggKHR5cGVfKSB7CisgICAgY2FzZSBUWVBFX0lOVDMyOgorICAgICAgcmV0dXJuIE51bWJlckNvbnZlcnRBbmRDaGVjazxUbywgaW50MzI+KGkzMl8pOworICAgIGNhc2UgVFlQRV9JTlQ2NDoKKyAgICAgIHJldHVybiBOdW1iZXJDb252ZXJ0QW5kQ2hlY2s8VG8sIGludDY0PihpNjRfKTsKKyAgICBjYXNlIFRZUEVfVUlOVDMyOgorICAgICAgcmV0dXJuIE51bWJlckNvbnZlcnRBbmRDaGVjazxUbywgdWludDMyPih1MzJfKTsKKyAgICBjYXNlIFRZUEVfVUlOVDY0OgorICAgICAgcmV0dXJuIE51bWJlckNvbnZlcnRBbmRDaGVjazxUbywgdWludDY0Pih1NjRfKTsKKyAgICBjYXNlIFRZUEVfRE9VQkxFOgorICAgICAgcmV0dXJuIE51bWJlckNvbnZlcnRBbmRDaGVjazxUbywgZG91YmxlPihkb3VibGVfKTsKKyAgICBjYXNlIFRZUEVfRkxPQVQ6CisgICAgICByZXR1cm4gTnVtYmVyQ29udmVydEFuZENoZWNrPFRvLCBmbG9hdD4oZmxvYXRfKTsKKyAgICBkZWZhdWx0OiAgLy8gVFlQRV9FTlVNLCBUWVBFX1NUUklORywgVFlQRV9DT1JELCBUWVBFX0JPT0wKKyAgICAgIHJldHVybiBJbnZhbGlkQXJndW1lbnQoVmFsdWVBc1N0cmluZ09yRGVmYXVsdCgKKyAgICAgICAgICAiV3JvbmcgdHlwZS4gQm9vbCwgRW51bSwgU3RyaW5nIGFuZCBDb3JkIG5vdCBzdXBwb3J0ZWQgaW4gIgorICAgICAgICAgICJHZW5lcmljQ29udmVydC4iKSk7CisgIH0KK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIFRvPgorU3RhdHVzT3I8VG8+IERhdGFQaWVjZTo6U3RyaW5nVG9OdW1iZXIoYm9vbCAoKmZ1bmMpKFN0cmluZ1BpZWNlLCBUbyopKSBjb25zdCB7CisgIFRvIHJlc3VsdDsKKyAgaWYgKGZ1bmMoc3RyXywgJnJlc3VsdCkpIHJldHVybiByZXN1bHQ7CisgIHJldHVybiBJbnZhbGlkQXJndW1lbnQoU3RyQ2F0KCJcIiIsIHN0cl8uVG9TdHJpbmcoKSwgIlwiIikpOworfQorCit9ICAvLyBuYW1lc3BhY2UgY29udmVydGVyCit9ICAvLyBuYW1lc3BhY2UgdXRpbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvZGF0YXBpZWNlLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvZGF0YXBpZWNlLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjIyYmZlNwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9kYXRhcGllY2UuaApAQCAtMCwwICsxLDIxMyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX1VUSUxfQ09OVkVSVEVSX0RBVEFQSUVDRV9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1VUSUxfQ09OVkVSVEVSX0RBVEFQSUVDRV9IX18KKworI2luY2x1ZGUgPHN0cmluZz4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RyaW5ncGllY2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RhdHVzb3IuaD4KKworCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CitjbGFzcyBFbnVtOworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKKworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSB1dGlsIHsKK25hbWVzcGFjZSBjb252ZXJ0ZXIgeworCisvLyBDb250YWluZXIgZm9yIGEgc2luZ2xlIHBpZWNlIG9mIGRhdGEgdG9nZXRoZXIgd2l0aCBpdHMgZGF0YSB0eXBlLgorLy8KKy8vIEZvciBwcmltaXRpdmUgdHlwZXMgKGludDMyLCBpbnQ2NCwgdWludDMyLCB1aW50NjQsIGRvdWJsZSwgZmxvYXQsIGJvb2wpLAorLy8gdGhlIGRhdGEgaXMgc3RvcmVkIGJ5IHZhbHVlLgorLy8KKy8vIEZvciBzdHJpbmcsIGEgU3RyaW5nUGllY2UgaXMgc3RvcmVkLiBGb3IgQ29yZCwgYSBwb2ludGVyIHRvIENvcmQgaXMgc3RvcmVkLgorLy8gSnVzdCBsaWtlIFN0cmluZ1BpZWNlLCB0aGUgRGF0YVBpZWNlIGNsYXNzIGRvZXMgbm90IG93biB0aGUgc3RvcmFnZSBmb3IKKy8vIHRoZSBhY3R1YWwgc3RyaW5nIG9yIENvcmQsIHNvIGl0IGlzIHRoZSB1c2VyJ3MgcmVzcG9uc2libGl0eSB0byBndWFyYW50ZWUKKy8vIHRoYXQgdGhlIHVuZGVybHlpbmcgc3RvcmFnZSBpcyBzdGlsbCB2YWxpZCB3aGVuIHRoZSBEYXRhUGllY2UgaXMgYWNjZXNzZWQuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgRGF0YVBpZWNlIHsKKyBwdWJsaWM6CisgIC8vIElkZW50aWZpZXMgZGF0YSB0eXBlIG9mIHRoZSB2YWx1ZS4KKyAgLy8gVGhlc2UgYXJlIHRoZSB0eXBlcyBzdXBwb3J0ZWQgYnkgRGF0YVBpZWNlLgorICBlbnVtIFR5cGUgeworICAgIFRZUEVfSU5UMzIgPSAxLAorICAgIFRZUEVfSU5UNjQgPSAyLAorICAgIFRZUEVfVUlOVDMyID0gMywKKyAgICBUWVBFX1VJTlQ2NCA9IDQsCisgICAgVFlQRV9ET1VCTEUgPSA1LAorICAgIFRZUEVfRkxPQVQgPSA2LAorICAgIFRZUEVfQk9PTCA9IDcsCisgICAgVFlQRV9FTlVNID0gOCwKKyAgICBUWVBFX1NUUklORyA9IDksCisgICAgVFlQRV9CWVRFUyA9IDEwLAorICAgIFRZUEVfTlVMTCA9IDExLCAgLy8gZXhwbGljaXQgTlVMTCB0eXBlCisgIH07CisKKyAgLy8gQ29uc3RydWN0b3JzIGFuZCBEZXN0cnVjdG9yCisgIGV4cGxpY2l0IERhdGFQaWVjZShjb25zdCBpbnQzMiB2YWx1ZSkgOiB0eXBlXyhUWVBFX0lOVDMyKSwgaTMyXyh2YWx1ZSkge30KKyAgZXhwbGljaXQgRGF0YVBpZWNlKGNvbnN0IGludDY0IHZhbHVlKSA6IHR5cGVfKFRZUEVfSU5UNjQpLCBpNjRfKHZhbHVlKSB7fQorICBleHBsaWNpdCBEYXRhUGllY2UoY29uc3QgdWludDMyIHZhbHVlKSA6IHR5cGVfKFRZUEVfVUlOVDMyKSwgdTMyXyh2YWx1ZSkge30KKyAgZXhwbGljaXQgRGF0YVBpZWNlKGNvbnN0IHVpbnQ2NCB2YWx1ZSkgOiB0eXBlXyhUWVBFX1VJTlQ2NCksIHU2NF8odmFsdWUpIHt9CisgIGV4cGxpY2l0IERhdGFQaWVjZShjb25zdCBkb3VibGUgdmFsdWUpIDogdHlwZV8oVFlQRV9ET1VCTEUpLCBkb3VibGVfKHZhbHVlKSB7fQorICBleHBsaWNpdCBEYXRhUGllY2UoY29uc3QgZmxvYXQgdmFsdWUpIDogdHlwZV8oVFlQRV9GTE9BVCksIGZsb2F0Xyh2YWx1ZSkge30KKyAgZXhwbGljaXQgRGF0YVBpZWNlKGNvbnN0IGJvb2wgdmFsdWUpIDogdHlwZV8oVFlQRV9CT09MKSwgYm9vbF8odmFsdWUpIHt9CisgIGV4cGxpY2l0IERhdGFQaWVjZShTdHJpbmdQaWVjZSB2YWx1ZSkKKyAgICAgIDogdHlwZV8oVFlQRV9TVFJJTkcpLAorICAgICAgICBzdHJfKFN0cmluZ1BpZWNlUG9kOjpDcmVhdGVGcm9tU3RyaW5nUGllY2UodmFsdWUpKSB7fQorICAvLyBDb25zdHJ1Y3RvciBmb3IgYnl0ZXMuIFRoZSBzZWNvbmQgcGFyYW1ldGVyIGlzIG5vdCB1c2VkLgorICBleHBsaWNpdCBEYXRhUGllY2UoU3RyaW5nUGllY2UgdmFsdWUsIGJvb2wgZHVtbXkpCisgICAgICA6IHR5cGVfKFRZUEVfQllURVMpLCBzdHJfKFN0cmluZ1BpZWNlUG9kOjpDcmVhdGVGcm9tU3RyaW5nUGllY2UodmFsdWUpKSB7fQorICBEYXRhUGllY2UoY29uc3QgRGF0YVBpZWNlJiByKSA6IHR5cGVfKHIudHlwZV8pLCBzdHJfKHIuc3RyXykge30KKyAgRGF0YVBpZWNlJiBvcGVyYXRvcj0oY29uc3QgRGF0YVBpZWNlJiB4KSB7CisgICAgdHlwZV8gPSB4LnR5cGVfOworICAgIHN0cl8gPSB4LnN0cl87CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgc3RhdGljIERhdGFQaWVjZSBOdWxsRGF0YSgpIHsgcmV0dXJuIERhdGFQaWVjZShUWVBFX05VTEwsIDApOyB9CisKKyAgdmlydHVhbCB+RGF0YVBpZWNlKCkgeworICB9CisKKyAgLy8gQWNjZXNzb3JzCisgIFR5cGUgdHlwZSgpIGNvbnN0IHsgcmV0dXJuIHR5cGVfOyB9CisKKyAgU3RyaW5nUGllY2Ugc3RyKCkgY29uc3QgeworICAgIEdPT0dMRV9MT0dfSUYoREZBVEFMLCB0eXBlXyAhPSBUWVBFX1NUUklORykgPDwgIk5vdCBhIHN0cmluZyB0eXBlLiI7CisgICAgcmV0dXJuIHN0cl87CisgIH0KKworCisgIC8vIFBhcnNlcywgY2FzdHMgb3IgY29udmVydHMgdGhlIHZhbHVlIHN0b3JlZCBpbiB0aGUgRGF0YVBpZWNlIGludG8gYW4gaW50MzIuCisgIHV0aWw6OlN0YXR1c09yPGludDMyPiBUb0ludDMyKCkgY29uc3Q7CisKKyAgLy8gUGFyc2VzLCBjYXN0cyBvciBjb252ZXJ0cyB0aGUgdmFsdWUgc3RvcmVkIGluIHRoZSBEYXRhUGllY2UgaW50byBhIHVpbnQzMi4KKyAgdXRpbDo6U3RhdHVzT3I8dWludDMyPiBUb1VpbnQzMigpIGNvbnN0OworCisgIC8vIFBhcnNlcywgY2FzdHMgb3IgY29udmVydHMgdGhlIHZhbHVlIHN0b3JlZCBpbiB0aGUgRGF0YVBpZWNlIGludG8gYW4gaW50NjQuCisgIHV0aWw6OlN0YXR1c09yPGludDY0PiBUb0ludDY0KCkgY29uc3Q7CisKKyAgLy8gUGFyc2VzLCBjYXN0cyBvciBjb252ZXJ0cyB0aGUgdmFsdWUgc3RvcmVkIGluIHRoZSBEYXRhUGllY2UgaW50byBhIHVpbnQ2NC4KKyAgdXRpbDo6U3RhdHVzT3I8dWludDY0PiBUb1VpbnQ2NCgpIGNvbnN0OworCisgIC8vIFBhcnNlcywgY2FzdHMgb3IgY29udmVydHMgdGhlIHZhbHVlIHN0b3JlZCBpbiB0aGUgRGF0YVBpZWNlIGludG8gYSBkb3VibGUuCisgIHV0aWw6OlN0YXR1c09yPGRvdWJsZT4gVG9Eb3VibGUoKSBjb25zdDsKKworICAvLyBQYXJzZXMsIGNhc3RzIG9yIGNvbnZlcnRzIHRoZSB2YWx1ZSBzdG9yZWQgaW4gdGhlIERhdGFQaWVjZSBpbnRvIGEgZmxvYXQuCisgIHV0aWw6OlN0YXR1c09yPGZsb2F0PiBUb0Zsb2F0KCkgY29uc3Q7CisKKyAgLy8gUGFyc2VzLCBjYXN0cyBvciBjb252ZXJ0cyB0aGUgdmFsdWUgc3RvcmVkIGluIHRoZSBEYXRhUGllY2UgaW50byBhIGJvb2wuCisgIHV0aWw6OlN0YXR1c09yPGJvb2w+IFRvQm9vbCgpIGNvbnN0OworCisgIC8vIFBhcnNlcywgY2FzdHMgb3IgY29udmVydHMgdGhlIHZhbHVlIHN0b3JlZCBpbiB0aGUgRGF0YVBpZWNlIGludG8gYSBzdHJpbmcuCisgIHV0aWw6OlN0YXR1c09yPHN0cmluZz4gVG9TdHJpbmcoKSBjb25zdDsKKworICAvLyBUcmllcyB0byBjb252ZXJ0IHRoZSB2YWx1ZSBjb250YWluZWQgaW4gdGhpcyBkYXRhcGllY2UgdG8gc3RyaW5nLiBJZiB0aGUKKyAgLy8gY29udmVyc2lvbiBmYWlscywgaXQgcmV0dXJucyB0aGUgZGVmYXVsdF9zdHJpbmcuCisgIHN0cmluZyBWYWx1ZUFzU3RyaW5nT3JEZWZhdWx0KFN0cmluZ1BpZWNlIGRlZmF1bHRfc3RyaW5nKSBjb25zdDsKKworICB1dGlsOjpTdGF0dXNPcjxzdHJpbmc+IFRvQnl0ZXMoKSBjb25zdDsKKworICAvLyBDb252ZXJ0cyBhIHZhbHVlIGludG8gcHJvdG9jb2wgYnVmZmVyIGVudW0gbnVtYmVyLiBJZiB0aGUgdmFsdWUgaXMgYQorICAvLyBzdHJpbmcsIGZpcnN0IGF0dGVtcHRzIGNvbnZlcnNpb24gYnkgbmFtZSwgdHJ5aW5nIG5hbWVzIGFzIGZvbGxvd3M6CisgIC8vICAgMSkgdGhlIGRpcmVjdGx5IHByb3ZpZGVkIHN0cmluZyB2YWx1ZS4KKyAgLy8gICAyKSB0aGUgdmFsdWUgdXBwZXItY2FzZWQgYW5kIHJlcGxhY2luZyAnLScgYnkgJ18nCisgIC8vIElmIHRoZSB2YWx1ZSBpcyBub3QgYSBzdHJpbmcsIGF0dGVtcHRzIHRvIGNvbnZlcnQgdG8gYSAzMi1iaXQgaW50ZWdlci4KKyAgLy8gSWYgbm9uZSBvZiB0aGVzZSBzdWNjZWVkcywgcmV0dXJucyBhIGNvbnZlcnNpb24gZXJyb3Igc3RhdHVzLgorICB1dGlsOjpTdGF0dXNPcjxpbnQ+IFRvRW51bShjb25zdCBnb29nbGU6OnByb3RvYnVmOjpFbnVtKiBlbnVtX3R5cGUpIGNvbnN0OworCisgcHJpdmF0ZToKKyAgLy8gRGlzYWxsb3cgaW1wbGljaXQgY29uc3RydWN0b3IuCisgIERhdGFQaWVjZSgpOworCisgIC8vIEhlbHBlciB0byBjcmVhdGUgTlVMTCBvciBFTlVNIHR5cGVzLgorICBEYXRhUGllY2UoVHlwZSB0eXBlLCBpbnQzMiB2YWwpIDogdHlwZV8odHlwZSksIGkzMl8odmFsKSB7fQorCisgIC8vIEZvciBudW1lcmljIGNvbnZlcnNpb24gYmV0d2VlbgorICAvLyAgICAgaW50MzIsIGludDY0LCB1aW50MzIsIHVpbnQ2NCwgZG91YmxlLCBmbG9hdCBhbmQgYm9vbAorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVG8+CisgIHV0aWw6OlN0YXR1c09yPFRvPiBHZW5lcmljQ29udmVydCgpIGNvbnN0OworCisgIC8vIEZvciBjb252ZXJzaW9uIGZyb20gc3RyaW5nIHRvCisgIC8vICAgICBpbnQzMiwgaW50NjQsIHVpbnQzMiwgdWludDY0LCBkb3VibGUsIGZsb2F0IGFuZCBib29sCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUbz4KKyAgdXRpbDo6U3RhdHVzT3I8VG8+IFN0cmluZ1RvTnVtYmVyKGJvb2wgKCpmdW5jKShTdHJpbmdQaWVjZSwgVG8qKSkgY29uc3Q7CisKKyAgLy8gRGF0YSB0eXBlIGZvciB0aGlzIHBpZWNlIG9mIGRhdGEuCisgIFR5cGUgdHlwZV87CisKKyAgLy8gU3RyaW5nUGllY2UgaXMgbm90IGEgUE9EIGFuZCBjYW4gbm90IGJlIHVzZWQgaW4gYW4gdW5pb24gKHByZSBDKysxMSkuIFdlCisgIC8vIG5lZWQgYSBQT0QgdmVyc2lvbiBvZiBpdC4KKyAgc3RydWN0IFN0cmluZ1BpZWNlUG9kIHsKKyAgICBjb25zdCBjaGFyKiBkYXRhOworICAgIGludCBzaXplOworCisgICAgLy8gQ3JlYXRlIGZyb20gYSBTdHJpbmdQaWVjZS4KKyAgICBzdGF0aWMgU3RyaW5nUGllY2VQb2QgQ3JlYXRlRnJvbVN0cmluZ1BpZWNlKFN0cmluZ1BpZWNlIHN0cikgeworICAgICAgU3RyaW5nUGllY2VQb2QgcG9kOworICAgICAgcG9kLmRhdGEgPSBzdHIuZGF0YSgpOworICAgICAgcG9kLnNpemUgPSBzdHIuc2l6ZSgpOworICAgICAgcmV0dXJuIHBvZDsKKyAgICB9CisKKyAgICAvLyBDYXN0IHRvIFN0cmluZ1BpZWNlLgorICAgIG9wZXJhdG9yIFN0cmluZ1BpZWNlKCkgY29uc3QgeyByZXR1cm4gU3RyaW5nUGllY2UoZGF0YSwgc2l6ZSk7IH0KKworICAgIGJvb2wgb3BlcmF0b3I9PShjb25zdCBjaGFyKiB2YWx1ZSkgY29uc3QgeworICAgICAgcmV0dXJuIFN0cmluZ1BpZWNlKGRhdGEsIHNpemUpID09IFN0cmluZ1BpZWNlKHZhbHVlKTsKKyAgICB9CisKKyAgICBzdHJpbmcgVG9TdHJpbmcoKSBjb25zdCB7IHJldHVybiBzdHJpbmcoZGF0YSwgc2l6ZSk7IH0KKyAgfTsKKworICAvLyBTdG9yZWQgcGllY2Ugb2YgZGF0YS4KKyAgdW5pb24geworICAgIGludDMyIGkzMl87CisgICAgaW50NjQgaTY0XzsKKyAgICB1aW50MzIgdTMyXzsKKyAgICB1aW50NjQgdTY0XzsKKyAgICBkb3VibGUgZG91YmxlXzsKKyAgICBmbG9hdCBmbG9hdF87CisgICAgYm9vbCBib29sXzsKKyAgICBTdHJpbmdQaWVjZVBvZCBzdHJfOworICB9OworfTsKKworfSAgLy8gbmFtZXNwYWNlIGNvbnZlcnRlcgorfSAgLy8gbmFtZXNwYWNlIHV0aWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9VVElMX0NPTlZFUlRFUl9EQVRBUElFQ0VfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvZGVmYXVsdF92YWx1ZV9vYmplY3R3cml0ZXIuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvZGVmYXVsdF92YWx1ZV9vYmplY3R3cml0ZXIuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTYzZTU2MAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9kZWZhdWx0X3ZhbHVlX29iamVjdHdyaXRlci5jYwpAQCAtMCwwICsxLDU1OSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9kZWZhdWx0X3ZhbHVlX29iamVjdHdyaXRlci5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2hhc2guaD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL2NvbnN0YW50cy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3V0aWxpdHkuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbWFwX3V0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIHV0aWwgewordXNpbmcgdXRpbDo6U3RhdHVzOwordXNpbmcgdXRpbDo6U3RhdHVzT3I7CituYW1lc3BhY2UgY29udmVydGVyIHsKKworbmFtZXNwYWNlIHsKKy8vIEhlbHBlciBmdW5jdGlvbiB0byBjb252ZXJ0IHN0cmluZyB2YWx1ZSB0byBnaXZlbiBkYXRhIHR5cGUgYnkgY2FsbGluZyB0aGUKKy8vIHBhc3NlZCBjb252ZXJ0ZXIgZnVuY3Rpb24gb24gdGhlIERhdGFQaWVjZSBjcmVhdGVkIGZyb20gInZhbHVlIiBhcmd1bWVudC4KKy8vIElmIHZhbHVlIGlzIGVtcHR5IG9yIGlmIGNvbnZlcnNpb24gZmFpbHMsIHRoZSBkZWZhdWx0X3ZhbHVlIGlzIHJldHVybmVkLgordGVtcGxhdGUgPHR5cGVuYW1lIFQ+CitUIENvbnZlcnRUbyhTdHJpbmdQaWVjZSB2YWx1ZSwgU3RhdHVzT3I8VD4gKERhdGFQaWVjZTo6KmNvbnZlcnRlcl9mbikoKSBjb25zdCwKKyAgICAgICAgICAgIFQgZGVmYXVsdF92YWx1ZSkgeworICBpZiAodmFsdWUuZW1wdHkoKSkgcmV0dXJuIGRlZmF1bHRfdmFsdWU7CisgIFN0YXR1c09yPFQ+IHJlc3VsdCA9IChEYXRhUGllY2UodmFsdWUpLipjb252ZXJ0ZXJfZm4pKCk7CisgIHJldHVybiByZXN1bHQub2soKSA/IHJlc3VsdC5WYWx1ZU9yRGllKCkgOiBkZWZhdWx0X3ZhbHVlOworfQorfSAgLy8gbmFtZXNwYWNlCisKK0RlZmF1bHRWYWx1ZU9iamVjdFdyaXRlcjo6RGVmYXVsdFZhbHVlT2JqZWN0V3JpdGVyKAorICAgIFR5cGVSZXNvbHZlciogdHlwZV9yZXNvbHZlciwgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6VHlwZSYgdHlwZSwKKyAgICBPYmplY3RXcml0ZXIqIG93KQorICAgIDogdHlwZWluZm9fKFR5cGVJbmZvOjpOZXdUeXBlSW5mbyh0eXBlX3Jlc29sdmVyKSksCisgICAgICBvd25fdHlwZWluZm9fKHRydWUpLAorICAgICAgdHlwZV8odHlwZSksCisgICAgICBjdXJyZW50XyhOVUxMKSwKKyAgICAgIHJvb3RfKE5VTEwpLAorICAgICAgb3dfKG93KSB7fQorCitEZWZhdWx0VmFsdWVPYmplY3RXcml0ZXI6On5EZWZhdWx0VmFsdWVPYmplY3RXcml0ZXIoKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgc3RyaW5nX3ZhbHVlc18uc2l6ZSgpOyArK2kpIHsKKyAgICBkZWxldGUgc3RyaW5nX3ZhbHVlc19baV07CisgIH0KKyAgaWYgKG93bl90eXBlaW5mb18pIHsKKyAgICBkZWxldGUgdHlwZWluZm9fOworICB9Cit9CisKK0RlZmF1bHRWYWx1ZU9iamVjdFdyaXRlciogRGVmYXVsdFZhbHVlT2JqZWN0V3JpdGVyOjpSZW5kZXJCb29sKFN0cmluZ1BpZWNlIG5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIHZhbHVlKSB7CisgIGlmIChjdXJyZW50XyA9PSBOVUxMKSB7CisgICAgb3dfLT5SZW5kZXJCb29sKG5hbWUsIHZhbHVlKTsKKyAgfSBlbHNlIHsKKyAgICBSZW5kZXJEYXRhUGllY2UobmFtZSwgRGF0YVBpZWNlKHZhbHVlKSk7CisgIH0KKyAgcmV0dXJuIHRoaXM7Cit9CisKK0RlZmF1bHRWYWx1ZU9iamVjdFdyaXRlciogRGVmYXVsdFZhbHVlT2JqZWN0V3JpdGVyOjpSZW5kZXJJbnQzMigKKyAgICBTdHJpbmdQaWVjZSBuYW1lLCBpbnQzMiB2YWx1ZSkgeworICBpZiAoY3VycmVudF8gPT0gTlVMTCkgeworICAgIG93Xy0+UmVuZGVySW50MzIobmFtZSwgdmFsdWUpOworICB9IGVsc2UgeworICAgIFJlbmRlckRhdGFQaWVjZShuYW1lLCBEYXRhUGllY2UodmFsdWUpKTsKKyAgfQorICByZXR1cm4gdGhpczsKK30KKworRGVmYXVsdFZhbHVlT2JqZWN0V3JpdGVyKiBEZWZhdWx0VmFsdWVPYmplY3RXcml0ZXI6OlJlbmRlclVpbnQzMigKKyAgICBTdHJpbmdQaWVjZSBuYW1lLCB1aW50MzIgdmFsdWUpIHsKKyAgaWYgKGN1cnJlbnRfID09IE5VTEwpIHsKKyAgICBvd18tPlJlbmRlclVpbnQzMihuYW1lLCB2YWx1ZSk7CisgIH0gZWxzZSB7CisgICAgUmVuZGVyRGF0YVBpZWNlKG5hbWUsIERhdGFQaWVjZSh2YWx1ZSkpOworICB9CisgIHJldHVybiB0aGlzOworfQorCitEZWZhdWx0VmFsdWVPYmplY3RXcml0ZXIqIERlZmF1bHRWYWx1ZU9iamVjdFdyaXRlcjo6UmVuZGVySW50NjQoCisgICAgU3RyaW5nUGllY2UgbmFtZSwgaW50NjQgdmFsdWUpIHsKKyAgaWYgKGN1cnJlbnRfID09IE5VTEwpIHsKKyAgICBvd18tPlJlbmRlckludDY0KG5hbWUsIHZhbHVlKTsKKyAgfSBlbHNlIHsKKyAgICBSZW5kZXJEYXRhUGllY2UobmFtZSwgRGF0YVBpZWNlKHZhbHVlKSk7CisgIH0KKyAgcmV0dXJuIHRoaXM7Cit9CisKK0RlZmF1bHRWYWx1ZU9iamVjdFdyaXRlciogRGVmYXVsdFZhbHVlT2JqZWN0V3JpdGVyOjpSZW5kZXJVaW50NjQoCisgICAgU3RyaW5nUGllY2UgbmFtZSwgdWludDY0IHZhbHVlKSB7CisgIGlmIChjdXJyZW50XyA9PSBOVUxMKSB7CisgICAgb3dfLT5SZW5kZXJVaW50NjQobmFtZSwgdmFsdWUpOworICB9IGVsc2UgeworICAgIFJlbmRlckRhdGFQaWVjZShuYW1lLCBEYXRhUGllY2UodmFsdWUpKTsKKyAgfQorICByZXR1cm4gdGhpczsKK30KKworRGVmYXVsdFZhbHVlT2JqZWN0V3JpdGVyKiBEZWZhdWx0VmFsdWVPYmplY3RXcml0ZXI6OlJlbmRlckRvdWJsZSgKKyAgICBTdHJpbmdQaWVjZSBuYW1lLCBkb3VibGUgdmFsdWUpIHsKKyAgaWYgKGN1cnJlbnRfID09IE5VTEwpIHsKKyAgICBvd18tPlJlbmRlckRvdWJsZShuYW1lLCB2YWx1ZSk7CisgIH0gZWxzZSB7CisgICAgUmVuZGVyRGF0YVBpZWNlKG5hbWUsIERhdGFQaWVjZSh2YWx1ZSkpOworICB9CisgIHJldHVybiB0aGlzOworfQorCitEZWZhdWx0VmFsdWVPYmplY3RXcml0ZXIqIERlZmF1bHRWYWx1ZU9iamVjdFdyaXRlcjo6UmVuZGVyRmxvYXQoCisgICAgU3RyaW5nUGllY2UgbmFtZSwgZmxvYXQgdmFsdWUpIHsKKyAgaWYgKGN1cnJlbnRfID09IE5VTEwpIHsKKyAgICBvd18tPlJlbmRlckJvb2wobmFtZSwgdmFsdWUpOworICB9IGVsc2UgeworICAgIFJlbmRlckRhdGFQaWVjZShuYW1lLCBEYXRhUGllY2UodmFsdWUpKTsKKyAgfQorICByZXR1cm4gdGhpczsKK30KKworRGVmYXVsdFZhbHVlT2JqZWN0V3JpdGVyKiBEZWZhdWx0VmFsdWVPYmplY3RXcml0ZXI6OlJlbmRlclN0cmluZygKKyAgICBTdHJpbmdQaWVjZSBuYW1lLCBTdHJpbmdQaWVjZSB2YWx1ZSkgeworICBpZiAoY3VycmVudF8gPT0gTlVMTCkgeworICAgIG93Xy0+UmVuZGVyU3RyaW5nKG5hbWUsIHZhbHVlKTsKKyAgfSBlbHNlIHsKKyAgICAvLyBTaW5jZSBTdHJpbmdQaWVjZSBpcyBlc3NlbnRpYWxseSBhIHBvaW50ZXIsIHRha2VzIGEgY29weSBvZiAidmFsdWUiIHRvCisgICAgLy8gYXZvaWQgb3duZXJzaGlwIGlzc3Vlcy4KKyAgICBzdHJpbmdfdmFsdWVzXy5wdXNoX2JhY2sobmV3IHN0cmluZyh2YWx1ZS5Ub1N0cmluZygpKSk7CisgICAgUmVuZGVyRGF0YVBpZWNlKG5hbWUsIERhdGFQaWVjZSgqc3RyaW5nX3ZhbHVlc18uYmFjaygpKSk7CisgIH0KKyAgcmV0dXJuIHRoaXM7Cit9CisKK0RlZmF1bHRWYWx1ZU9iamVjdFdyaXRlciogRGVmYXVsdFZhbHVlT2JqZWN0V3JpdGVyOjpSZW5kZXJCeXRlcygKKyAgICBTdHJpbmdQaWVjZSBuYW1lLCBTdHJpbmdQaWVjZSB2YWx1ZSkgeworICBpZiAoY3VycmVudF8gPT0gTlVMTCkgeworICAgIG93Xy0+UmVuZGVyQnl0ZXMobmFtZSwgdmFsdWUpOworICB9IGVsc2UgeworICAgIFJlbmRlckRhdGFQaWVjZShuYW1lLCBEYXRhUGllY2UodmFsdWUpKTsKKyAgfQorICByZXR1cm4gdGhpczsKK30KKworRGVmYXVsdFZhbHVlT2JqZWN0V3JpdGVyKiBEZWZhdWx0VmFsdWVPYmplY3RXcml0ZXI6OlJlbmRlck51bGwoCisgICAgU3RyaW5nUGllY2UgbmFtZSkgeworICBpZiAoY3VycmVudF8gPT0gTlVMTCkgeworICAgIG93Xy0+UmVuZGVyTnVsbChuYW1lKTsKKyAgfSBlbHNlIHsKKyAgICBSZW5kZXJEYXRhUGllY2UobmFtZSwgRGF0YVBpZWNlOjpOdWxsRGF0YSgpKTsKKyAgfQorICByZXR1cm4gdGhpczsKK30KKworRGVmYXVsdFZhbHVlT2JqZWN0V3JpdGVyOjpOb2RlOjpOb2RlKGNvbnN0IHN0cmluZyYgbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlKiB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5vZGVLaW5kIGtpbmQsIGNvbnN0IERhdGFQaWVjZSYgZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGlzX3BsYWNlaG9sZGVyKQorICAgIDogbmFtZV8obmFtZSksCisgICAgICB0eXBlXyh0eXBlKSwKKyAgICAgIGtpbmRfKGtpbmQpLAorICAgICAgaXNfYW55XyhmYWxzZSksCisgICAgICBkYXRhXyhkYXRhKSwKKyAgICAgIGlzX3BsYWNlaG9sZGVyXyhpc19wbGFjZWhvbGRlcikge30KKworRGVmYXVsdFZhbHVlT2JqZWN0V3JpdGVyOjpOb2RlKiBEZWZhdWx0VmFsdWVPYmplY3RXcml0ZXI6Ok5vZGU6OkZpbmRDaGlsZCgKKyAgICBTdHJpbmdQaWVjZSBuYW1lKSB7CisgIGlmIChuYW1lLmVtcHR5KCkgfHwga2luZF8gIT0gT0JKRUNUKSB7CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBjaGlsZHJlbl8uc2l6ZSgpOyArK2kpIHsKKyAgICBOb2RlKiBjaGlsZCA9IGNoaWxkcmVuX1tpXTsKKyAgICBpZiAoY2hpbGQtPm5hbWUoKSA9PSBuYW1lKSB7CisgICAgICByZXR1cm4gY2hpbGQ7CisgICAgfQorICB9CisgIHJldHVybiBOVUxMOworfQorCit2b2lkIERlZmF1bHRWYWx1ZU9iamVjdFdyaXRlcjo6Tm9kZTo6V3JpdGVUbyhPYmplY3RXcml0ZXIqIG93KSB7CisgIGlmIChraW5kXyA9PSBQUklNSVRJVkUpIHsKKyAgICBPYmplY3RXcml0ZXI6OlJlbmRlckRhdGFQaWVjZVRvKGRhdGFfLCBuYW1lXywgb3cpOworICAgIHJldHVybjsKKyAgfQorCisgIC8vIFJlbmRlciBtYXBzLiBFbXB0eSBtYXBzIGFyZSByZW5kZXJlZCBhcyAie30iLgorICBpZiAoa2luZF8gPT0gTUFQKSB7CisgICAgb3ctPlN0YXJ0T2JqZWN0KG5hbWVfKTsKKyAgICBXcml0ZUNoaWxkcmVuKG93KTsKKyAgICBvdy0+RW5kT2JqZWN0KCk7CisgICAgcmV0dXJuOworICB9CisKKyAgLy8gV3JpdGUgb3V0IGxpc3RzLiBJZiB3ZSBkaWRuJ3QgaGF2ZSBhbnkgbGlzdCBpbiByZXNwb25zZSwgd3JpdGUgb3V0IGVtcHR5CisgIC8vIGxpc3QuCisgIGlmIChraW5kXyA9PSBMSVNUKSB7CisgICAgb3ctPlN0YXJ0TGlzdChuYW1lXyk7CisgICAgV3JpdGVDaGlsZHJlbihvdyk7CisgICAgb3ctPkVuZExpc3QoKTsKKyAgICByZXR1cm47CisgIH0KKworICAvLyBJZiBpc19wbGFjZWhvbGRlcl8gPSB0cnVlLCB3ZSBkaWRuJ3Qgc2VlIHRoaXMgbm9kZSBpbiB0aGUgcmVzcG9uc2UsIHNvCisgIC8vIHNraXAgb3V0cHV0LgorICBpZiAoaXNfcGxhY2Vob2xkZXJfKSByZXR1cm47CisKKyAgb3ctPlN0YXJ0T2JqZWN0KG5hbWVfKTsKKyAgV3JpdGVDaGlsZHJlbihvdyk7CisgIG93LT5FbmRPYmplY3QoKTsKK30KKwordm9pZCBEZWZhdWx0VmFsdWVPYmplY3RXcml0ZXI6Ok5vZGU6OldyaXRlQ2hpbGRyZW4oT2JqZWN0V3JpdGVyKiBvdykgeworICBmb3IgKGludCBpID0gMDsgaSA8IGNoaWxkcmVuXy5zaXplKCk7ICsraSkgeworICAgIE5vZGUqIGNoaWxkID0gY2hpbGRyZW5fW2ldOworICAgIGNoaWxkLT5Xcml0ZVRvKG93KTsKKyAgfQorfQorCitjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlKiBEZWZhdWx0VmFsdWVPYmplY3RXcml0ZXI6Ok5vZGU6OkdldE1hcFZhbHVlVHlwZSgKKyAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlJiBmb3VuZF90eXBlLCBjb25zdCBUeXBlSW5mbyogdHlwZWluZm8pIHsKKyAgLy8gSWYgdGhpcyBmaWVsZCBpcyBhIG1hcCwgd2Ugc2hvdWxkIHVzZSB0aGUgdHlwZSBvZiBpdHMgIlZhbHVlIiBhcworICAvLyB0aGUgdHlwZSBvZiB0aGUgY2hpbGQgbm9kZS4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmb3VuZF90eXBlLmZpZWxkc19zaXplKCk7ICsraSkgeworICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkJiBzdWJfZmllbGQgPSBmb3VuZF90eXBlLmZpZWxkcyhpKTsKKyAgICBpZiAoc3ViX2ZpZWxkLm51bWJlcigpICE9IDIpIHsKKyAgICAgIGNvbnRpbnVlOworICAgIH0KKyAgICBpZiAoc3ViX2ZpZWxkLmtpbmQoKSAhPSBnb29nbGU6OnByb3RvYnVmOjpGaWVsZF9LaW5kX1RZUEVfTUVTU0FHRSkgeworICAgICAgLy8gVGhpcyBtYXAncyB2YWx1ZSB0eXBlIGlzIG5vdCBhIG1lc3NhZ2UgdHlwZS4gV2UgZG9uJ3QgbmVlZCB0bworICAgICAgLy8gZ2V0IHRoZSBmaWVsZF90eXBlIGluIHRoaXMgY2FzZS4KKyAgICAgIGJyZWFrOworICAgIH0KKyAgICB1dGlsOjpTdGF0dXNPcjxjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlKj4gc3ViX3R5cGUgPQorICAgICAgICB0eXBlaW5mby0+UmVzb2x2ZVR5cGVVcmwoc3ViX2ZpZWxkLnR5cGVfdXJsKCkpOworICAgIGlmICghc3ViX3R5cGUub2soKSkgeworICAgICAgR09PR0xFX0xPRyhXQVJOSU5HKSA8PCAiQ2Fubm90IHJlc29sdmUgdHlwZSAnIiA8PCBzdWJfZmllbGQudHlwZV91cmwoKSA8PCAiJy4iOworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gc3ViX3R5cGUuVmFsdWVPckRpZSgpOworICAgIH0KKyAgICBicmVhazsKKyAgfQorICByZXR1cm4gTlVMTDsKK30KKwordm9pZCBEZWZhdWx0VmFsdWVPYmplY3RXcml0ZXI6Ok5vZGU6OlBvcHVsYXRlQ2hpbGRyZW4oCisgICAgY29uc3QgVHlwZUluZm8qIHR5cGVpbmZvKSB7CisgIC8vIElnbm9yZXMgd2VsbCBrbm93biB0eXBlcyB0aGF0IGRvbid0IHJlcXVpcmUgYXV0b21hdGljYWxseSBwb3B1bGF0aW5nIHRoZWlyCisgIC8vIHByaW1pdGl2ZSBjaGlsZHJlbi4gRm9yIHR5cGUgIkFueSIsIHdlIG9ubHkgcG9wdWxhdGUgaXRzIGNoaWxkcmVuIHdoZW4gdGhlCisgIC8vICJAdHlwZSIgZmllbGQgaXMgc2V0LgorICAvLyBUT0RPKHRzdW4pOiByZW1vdmUgImtTdHJ1Y3RWYWx1ZVR5cGUiIGZyb20gdGhlIGxpc3QuIEl0J3MgYmVpbmcgY2hlY2tlZAorICAvLyAgICAgbm93IGJlY2F1c2Ugb2YgYSBidWcgaW4gdGhlIHRvb2wtY2hhaW4gdGhhdCBjYXVzZXMgdGhlICJvbmVvZl9pbmRleCIKKyAgLy8gICAgIG9mIGtTdHJ1Y3RWYWx1ZVR5cGUgdG8gbm90IGJlIHNldCBjb3JyZWN0bHkuCisgIGlmICh0eXBlXyA9PSBOVUxMIHx8IHR5cGVfLT5uYW1lKCkgPT0ga0FueVR5cGUgfHwKKyAgICAgIHR5cGVfLT5uYW1lKCkgPT0ga1N0cnVjdFR5cGUgfHwgdHlwZV8tPm5hbWUoKSA9PSBrVGltZXN0YW1wVHlwZSB8fAorICAgICAgdHlwZV8tPm5hbWUoKSA9PSBrRHVyYXRpb25UeXBlIHx8IHR5cGVfLT5uYW1lKCkgPT0ga1N0cnVjdFZhbHVlVHlwZSkgeworICAgIHJldHVybjsKKyAgfQorICBzdGQ6OnZlY3RvcjxOb2RlKj4gbmV3X2NoaWxkcmVuOworICBoYXNoX21hcDxzdHJpbmcsIGludD4gb3JpZ19jaGlsZHJlbl9tYXA7CisKKyAgLy8gQ3JlYXRlcyBhIG1hcCBvZiBjaGlsZCBub2RlcyB0byBzcGVlZCB1cCBsb29rdXAuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgY2hpbGRyZW5fLnNpemUoKTsgKytpKSB7CisgICAgSW5zZXJ0SWZOb3RQcmVzZW50KCZvcmlnX2NoaWxkcmVuX21hcCwgY2hpbGRyZW5fW2ldLT5uYW1lXywgaSk7CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IHR5cGVfLT5maWVsZHNfc2l6ZSgpOyArK2kpIHsKKyAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZCYgZmllbGQgPSB0eXBlXy0+ZmllbGRzKGkpOworICAgIGhhc2hfbWFwPHN0cmluZywgaW50Pjo6aXRlcmF0b3IgZm91bmQgPQorICAgICAgICBvcmlnX2NoaWxkcmVuX21hcC5maW5kKGZpZWxkLm5hbWUoKSk7CisgICAgLy8gSWYgdGhlIGNoaWxkIGZpZWxkIGhhcyBhbHJlYWR5IGJlZW4gc2V0LCB3ZSBqdXN0IGFkZCBpdCB0byB0aGUgbmV3IGxpc3QKKyAgICAvLyBvZiBjaGlsZHJlbi4KKyAgICBpZiAoZm91bmQgIT0gb3JpZ19jaGlsZHJlbl9tYXAuZW5kKCkpIHsKKyAgICAgIG5ld19jaGlsZHJlbi5wdXNoX2JhY2soY2hpbGRyZW5fW2ZvdW5kLT5zZWNvbmRdKTsKKyAgICAgIGNoaWxkcmVuX1tmb3VuZC0+c2Vjb25kXSA9IE5VTEw7CisgICAgICBjb250aW51ZTsKKyAgICB9CisKKyAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlKiBmaWVsZF90eXBlID0gTlVMTDsKKyAgICBib29sIGlzX21hcCA9IGZhbHNlOworICAgIE5vZGVLaW5kIGtpbmQgPSBQUklNSVRJVkU7CisKKyAgICBpZiAoZmllbGQua2luZCgpID09IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0tpbmRfVFlQRV9NRVNTQUdFKSB7CisgICAgICBraW5kID0gT0JKRUNUOworICAgICAgdXRpbDo6U3RhdHVzT3I8Y29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6VHlwZSo+IGZvdW5kX3Jlc3VsdCA9CisgICAgICAgICAgdHlwZWluZm8tPlJlc29sdmVUeXBlVXJsKGZpZWxkLnR5cGVfdXJsKCkpOworICAgICAgaWYgKCFmb3VuZF9yZXN1bHQub2soKSkgeworICAgICAgICAvLyAiZmllbGQiIGlzIG9mIGFuIHVua25vd24gdHlwZS4KKyAgICAgICAgR09PR0xFX0xPRyhXQVJOSU5HKSA8PCAiQ2Fubm90IHJlc29sdmUgdHlwZSAnIiA8PCBmaWVsZC50eXBlX3VybCgpIDw8ICInLiI7CisgICAgICB9IGVsc2UgeworICAgICAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlKiBmb3VuZF90eXBlID0gZm91bmRfcmVzdWx0LlZhbHVlT3JEaWUoKTsKKyAgICAgICAgaXNfbWFwID0gSXNNYXAoZmllbGQsICpmb3VuZF90eXBlKTsKKworICAgICAgICBpZiAoIWlzX21hcCkgeworICAgICAgICAgIGZpZWxkX3R5cGUgPSBmb3VuZF90eXBlOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIC8vIElmIHRoaXMgZmllbGQgaXMgYSBtYXAsIHdlIHNob3VsZCB1c2UgdGhlIHR5cGUgb2YgaXRzICJWYWx1ZSIgYXMKKyAgICAgICAgICAvLyB0aGUgdHlwZSBvZiB0aGUgY2hpbGQgbm9kZS4KKyAgICAgICAgICBmaWVsZF90eXBlID0gR2V0TWFwVmFsdWVUeXBlKCpmb3VuZF90eXBlLCB0eXBlaW5mbyk7CisgICAgICAgICAga2luZCA9IE1BUDsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKworICAgIGlmICghaXNfbWFwICYmCisgICAgICAgIGZpZWxkLmNhcmRpbmFsaXR5KCkgPT0KKyAgICAgICAgICAgIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0NhcmRpbmFsaXR5X0NBUkRJTkFMSVRZX1JFUEVBVEVEKSB7CisgICAgICBraW5kID0gTElTVDsKKyAgICB9CisKKyAgICAvLyBJZiBvbmVvZl9pbmRleCgpICE9IDAsIHRoZSBjaGlsZCBmaWVsZCBpcyBwYXJ0IG9mIGEgIm9uZW9mIiwgd2hpY2ggbWVhbnMKKyAgICAvLyB0aGUgY2hpbGQgZmllbGQgaXMgb3B0aW9uYWwgYW5kIHdlIHNob3VsZG4ndCBwb3B1bGF0ZSBpdHMgZGVmYXVsdCB2YWx1ZS4KKyAgICBpZiAoZmllbGQub25lb2ZfaW5kZXgoKSAhPSAwKSBjb250aW51ZTsKKworICAgIC8vIElmIHRoZSBjaGlsZCBmaWVsZCBpcyBvZiBwcmltaXRpdmUgdHlwZSwgc2V0cyBpdHMgZGF0YSB0byB0aGUgZGVmYXVsdAorICAgIC8vIHZhbHVlIG9mIGl0cyB0eXBlLgorICAgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8Tm9kZT4gY2hpbGQobmV3IE5vZGUoCisgICAgICAgIGZpZWxkLmpzb25fbmFtZSgpLCBmaWVsZF90eXBlLCBraW5kLAorICAgICAgICBraW5kID09IFBSSU1JVElWRSA/IENyZWF0ZURlZmF1bHREYXRhUGllY2VGb3JGaWVsZChmaWVsZCwgdHlwZWluZm8pCisgICAgICAgICAgICAgICAgICAgICAgICAgIDogRGF0YVBpZWNlOjpOdWxsRGF0YSgpLAorICAgICAgICB0cnVlKSk7CisgICAgbmV3X2NoaWxkcmVuLnB1c2hfYmFjayhjaGlsZC5yZWxlYXNlKCkpOworICB9CisgIC8vIEFkZHMgYWxsIGxlZnRvdmVyIG5vZGVzIGluIGNoaWxkcmVuXyB0byB0aGUgYmVnaW5uaW5nIG9mIG5ld19jaGlsZC4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBjaGlsZHJlbl8uc2l6ZSgpOyArK2kpIHsKKyAgICBpZiAoY2hpbGRyZW5fW2ldID09IE5VTEwpIHsKKyAgICAgIGNvbnRpbnVlOworICAgIH0KKyAgICBuZXdfY2hpbGRyZW4uaW5zZXJ0KG5ld19jaGlsZHJlbi5iZWdpbigpLCBjaGlsZHJlbl9baV0pOworICAgIGNoaWxkcmVuX1tpXSA9IE5VTEw7CisgIH0KKyAgY2hpbGRyZW5fLnN3YXAobmV3X2NoaWxkcmVuKTsKK30KKwordm9pZCBEZWZhdWx0VmFsdWVPYmplY3RXcml0ZXI6Ok1heWJlUG9wdWxhdGVDaGlsZHJlbk9mQW55KE5vZGUqIG5vZGUpIHsKKyAgLy8gSWYgdGhpcyBpcyBhbiAiQW55IiBub2RlIHdpdGggIkB0eXBlIiBhbHJlYWR5IGdpdmVuIGFuZCBubyBvdGhlciBjaGlsZHJlbgorICAvLyBoYXZlIGJlZW4gYWRkZWQsIHBvcHVsYXRlcyBpdHMgY2hpbGRyZW4uCisgIGlmIChub2RlICE9IE5VTEwgJiYgbm9kZS0+aXNfYW55KCkgJiYgbm9kZS0+dHlwZSgpICE9IE5VTEwgJiYKKyAgICAgIG5vZGUtPnR5cGUoKS0+bmFtZSgpICE9IGtBbnlUeXBlICYmIG5vZGUtPm51bWJlcl9vZl9jaGlsZHJlbigpID09IDEpIHsKKyAgICBub2RlLT5Qb3B1bGF0ZUNoaWxkcmVuKHR5cGVpbmZvXyk7CisgIH0KK30KKworRGF0YVBpZWNlIERlZmF1bHRWYWx1ZU9iamVjdFdyaXRlcjo6RmluZEVudW1EZWZhdWx0KAorICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkJiBmaWVsZCwgY29uc3QgVHlwZUluZm8qIHR5cGVpbmZvKSB7CisgIGlmICghZmllbGQuZGVmYXVsdF92YWx1ZSgpLmVtcHR5KCkpIHJldHVybiBEYXRhUGllY2UoZmllbGQuZGVmYXVsdF92YWx1ZSgpKTsKKworICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpFbnVtKiBlbnVtX3R5cGUgPQorICAgICAgdHlwZWluZm8tPkdldEVudW1CeVR5cGVVcmwoZmllbGQudHlwZV91cmwoKSk7CisgIGlmICghZW51bV90eXBlKSB7CisgICAgR09PR0xFX0xPRyhXQVJOSU5HKSA8PCAiQ291bGQgbm90IGZpbmQgZW51bSB3aXRoIHR5cGUgJyIgPDwgZmllbGQudHlwZV91cmwoKQorICAgICAgICAgICAgICAgICA8PCAiJyI7CisgICAgcmV0dXJuIERhdGFQaWVjZTo6TnVsbERhdGEoKTsKKyAgfQorICAvLyBXZSB0cmVhdCB0aGUgZmlyc3QgdmFsdWUgYXMgdGhlIGRlZmF1bHQgaWYgbm9uZSBpcyBzcGVjaWZpZWQuCisgIHJldHVybiBlbnVtX3R5cGUtPmVudW12YWx1ZV9zaXplKCkgPiAwCisgICAgICAgICAgICAgPyBEYXRhUGllY2UoZW51bV90eXBlLT5lbnVtdmFsdWUoMCkubmFtZSgpKQorICAgICAgICAgICAgIDogRGF0YVBpZWNlOjpOdWxsRGF0YSgpOworfQorCitEYXRhUGllY2UgRGVmYXVsdFZhbHVlT2JqZWN0V3JpdGVyOjpDcmVhdGVEZWZhdWx0RGF0YVBpZWNlRm9yRmllbGQoCisgICAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGQmIGZpZWxkLCBjb25zdCBUeXBlSW5mbyogdHlwZWluZm8pIHsKKyAgc3dpdGNoIChmaWVsZC5raW5kKCkpIHsKKyAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0tpbmRfVFlQRV9ET1VCTEU6IHsKKyAgICAgIHJldHVybiBEYXRhUGllY2UoQ29udmVydFRvPGRvdWJsZT4oCisgICAgICAgICAgZmllbGQuZGVmYXVsdF92YWx1ZSgpLCAmRGF0YVBpZWNlOjpUb0RvdWJsZSwgc3RhdGljX2Nhc3Q8ZG91YmxlPigwKSkpOworICAgIH0KKyAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0tpbmRfVFlQRV9GTE9BVDogeworICAgICAgcmV0dXJuIERhdGFQaWVjZShDb252ZXJ0VG88ZmxvYXQ+KAorICAgICAgICAgIGZpZWxkLmRlZmF1bHRfdmFsdWUoKSwgJkRhdGFQaWVjZTo6VG9GbG9hdCwgc3RhdGljX2Nhc3Q8ZmxvYXQ+KDApKSk7CisgICAgfQorICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGRfS2luZF9UWVBFX0lOVDY0OgorICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGRfS2luZF9UWVBFX1NJTlQ2NDoKKyAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0tpbmRfVFlQRV9TRklYRUQ2NDogeworICAgICAgcmV0dXJuIERhdGFQaWVjZShDb252ZXJ0VG88aW50NjQ+KAorICAgICAgICAgIGZpZWxkLmRlZmF1bHRfdmFsdWUoKSwgJkRhdGFQaWVjZTo6VG9JbnQ2NCwgc3RhdGljX2Nhc3Q8aW50NjQ+KDApKSk7CisgICAgfQorICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGRfS2luZF9UWVBFX1VJTlQ2NDoKKyAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0tpbmRfVFlQRV9GSVhFRDY0OiB7CisgICAgICByZXR1cm4gRGF0YVBpZWNlKENvbnZlcnRUbzx1aW50NjQ+KAorICAgICAgICAgIGZpZWxkLmRlZmF1bHRfdmFsdWUoKSwgJkRhdGFQaWVjZTo6VG9VaW50NjQsIHN0YXRpY19jYXN0PHVpbnQ2ND4oMCkpKTsKKyAgICB9CisgICAgY2FzZSBnb29nbGU6OnByb3RvYnVmOjpGaWVsZF9LaW5kX1RZUEVfSU5UMzI6CisgICAgY2FzZSBnb29nbGU6OnByb3RvYnVmOjpGaWVsZF9LaW5kX1RZUEVfU0lOVDMyOgorICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGRfS2luZF9UWVBFX1NGSVhFRDMyOiB7CisgICAgICByZXR1cm4gRGF0YVBpZWNlKENvbnZlcnRUbzxpbnQzMj4oCisgICAgICAgICAgZmllbGQuZGVmYXVsdF92YWx1ZSgpLCAmRGF0YVBpZWNlOjpUb0ludDMyLCBzdGF0aWNfY2FzdDxpbnQzMj4oMCkpKTsKKyAgICB9CisgICAgY2FzZSBnb29nbGU6OnByb3RvYnVmOjpGaWVsZF9LaW5kX1RZUEVfQk9PTDogeworICAgICAgcmV0dXJuIERhdGFQaWVjZSgKKyAgICAgICAgICBDb252ZXJ0VG88Ym9vbD4oZmllbGQuZGVmYXVsdF92YWx1ZSgpLCAmRGF0YVBpZWNlOjpUb0Jvb2wsIGZhbHNlKSk7CisgICAgfQorICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGRfS2luZF9UWVBFX1NUUklORzogeworICAgICAgcmV0dXJuIERhdGFQaWVjZShmaWVsZC5kZWZhdWx0X3ZhbHVlKCkpOworICAgIH0KKyAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0tpbmRfVFlQRV9CWVRFUzogeworICAgICAgcmV0dXJuIERhdGFQaWVjZShmaWVsZC5kZWZhdWx0X3ZhbHVlKCksIGZhbHNlKTsKKyAgICB9CisgICAgY2FzZSBnb29nbGU6OnByb3RvYnVmOjpGaWVsZF9LaW5kX1RZUEVfVUlOVDMyOgorICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGRfS2luZF9UWVBFX0ZJWEVEMzI6IHsKKyAgICAgIHJldHVybiBEYXRhUGllY2UoQ29udmVydFRvPHVpbnQzMj4oCisgICAgICAgICAgZmllbGQuZGVmYXVsdF92YWx1ZSgpLCAmRGF0YVBpZWNlOjpUb1VpbnQzMiwgc3RhdGljX2Nhc3Q8dWludDMyPigwKSkpOworICAgIH0KKyAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0tpbmRfVFlQRV9FTlVNOiB7CisgICAgICByZXR1cm4gRmluZEVudW1EZWZhdWx0KGZpZWxkLCB0eXBlaW5mbyk7CisgICAgfQorICAgIGRlZmF1bHQ6IHsgcmV0dXJuIERhdGFQaWVjZTo6TnVsbERhdGEoKTsgfQorICB9Cit9CisKK0RlZmF1bHRWYWx1ZU9iamVjdFdyaXRlciogRGVmYXVsdFZhbHVlT2JqZWN0V3JpdGVyOjpTdGFydE9iamVjdCgKKyAgICBTdHJpbmdQaWVjZSBuYW1lKSB7CisgIGlmIChjdXJyZW50XyA9PSBOVUxMKSB7CisgICAgcm9vdF8ucmVzZXQobmV3IE5vZGUobmFtZS5Ub1N0cmluZygpLCAmdHlwZV8sIE9CSkVDVCwgRGF0YVBpZWNlOjpOdWxsRGF0YSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlKSk7CisgICAgcm9vdF8tPlBvcHVsYXRlQ2hpbGRyZW4odHlwZWluZm9fKTsKKyAgICBjdXJyZW50XyA9IHJvb3RfLmdldCgpOworICAgIHJldHVybiB0aGlzOworICB9CisgIE1heWJlUG9wdWxhdGVDaGlsZHJlbk9mQW55KGN1cnJlbnRfKTsKKyAgTm9kZSogY2hpbGQgPSBjdXJyZW50Xy0+RmluZENoaWxkKG5hbWUpOworICBpZiAoY3VycmVudF8tPmtpbmQoKSA9PSBMSVNUIHx8IGN1cnJlbnRfLT5raW5kKCkgPT0gTUFQIHx8IGNoaWxkID09IE5VTEwpIHsKKyAgICAvLyBJZiBjdXJyZW50XyBpcyBhIGxpc3Qgb3IgYSBtYXAgbm9kZSwgd2Ugc2hvdWxkIGNyZWF0ZSBhIG5ldyBjaGlsZCBhbmQgdXNlCisgICAgLy8gdGhlIHR5cGUgb2YgY3VycmVudF8gYXMgdGhlIHR5cGUgb2YgdGhlIG5ldyBjaGlsZC4KKyAgICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPE5vZGU+IG5vZGUobmV3IE5vZGUoCisgICAgICAgIG5hbWUuVG9TdHJpbmcoKSwgKChjdXJyZW50Xy0+a2luZCgpID09IExJU1QgfHwgY3VycmVudF8tPmtpbmQoKSA9PSBNQVApCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IGN1cnJlbnRfLT50eXBlKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogTlVMTCksCisgICAgICAgIE9CSkVDVCwgRGF0YVBpZWNlOjpOdWxsRGF0YSgpLCBmYWxzZSkpOworICAgIGNoaWxkID0gbm9kZS5nZXQoKTsKKyAgICBjdXJyZW50Xy0+QWRkQ2hpbGQobm9kZS5yZWxlYXNlKCkpOworICB9CisKKyAgY2hpbGQtPnNldF9pc19wbGFjZWhvbGRlcihmYWxzZSk7CisgIGlmIChjaGlsZC0+a2luZCgpID09IE9CSkVDVCAmJiBjaGlsZC0+bnVtYmVyX29mX2NoaWxkcmVuKCkgPT0gMCkgeworICAgIGNoaWxkLT5Qb3B1bGF0ZUNoaWxkcmVuKHR5cGVpbmZvXyk7CisgIH0KKworICBzdGFja18ucHVzaChjdXJyZW50Xyk7CisgIGN1cnJlbnRfID0gY2hpbGQ7CisgIHJldHVybiB0aGlzOworfQorCitEZWZhdWx0VmFsdWVPYmplY3RXcml0ZXIqIERlZmF1bHRWYWx1ZU9iamVjdFdyaXRlcjo6RW5kT2JqZWN0KCkgeworICBpZiAoc3RhY2tfLmVtcHR5KCkpIHsKKyAgICAvLyBUaGUgcm9vdCBvYmplY3QgZW5kcyBoZXJlLiBXcml0ZXMgb3V0IHRoZSB0cmVlLgorICAgIFdyaXRlUm9vdCgpOworICAgIHJldHVybiB0aGlzOworICB9CisgIGN1cnJlbnRfID0gc3RhY2tfLnRvcCgpOworICBzdGFja18ucG9wKCk7CisgIHJldHVybiB0aGlzOworfQorCitEZWZhdWx0VmFsdWVPYmplY3RXcml0ZXIqIERlZmF1bHRWYWx1ZU9iamVjdFdyaXRlcjo6U3RhcnRMaXN0KAorICAgIFN0cmluZ1BpZWNlIG5hbWUpIHsKKyAgaWYgKGN1cnJlbnRfID09IE5VTEwpIHsKKyAgICByb290Xy5yZXNldCgKKyAgICAgICAgbmV3IE5vZGUobmFtZS5Ub1N0cmluZygpLCAmdHlwZV8sIExJU1QsIERhdGFQaWVjZTo6TnVsbERhdGEoKSwgZmFsc2UpKTsKKyAgICBjdXJyZW50XyA9IHJvb3RfLmdldCgpOworICAgIHJldHVybiB0aGlzOworICB9CisgIE1heWJlUG9wdWxhdGVDaGlsZHJlbk9mQW55KGN1cnJlbnRfKTsKKyAgTm9kZSogY2hpbGQgPSBjdXJyZW50Xy0+RmluZENoaWxkKG5hbWUpOworICBpZiAoY2hpbGQgPT0gTlVMTCB8fCBjaGlsZC0+a2luZCgpICE9IExJU1QpIHsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPE5vZGU+IG5vZGUoCisgICAgICAgIG5ldyBOb2RlKG5hbWUuVG9TdHJpbmcoKSwgTlVMTCwgTElTVCwgRGF0YVBpZWNlOjpOdWxsRGF0YSgpLCBmYWxzZSkpOworICAgIGNoaWxkID0gbm9kZS5nZXQoKTsKKyAgICBjdXJyZW50Xy0+QWRkQ2hpbGQobm9kZS5yZWxlYXNlKCkpOworICB9CisgIGNoaWxkLT5zZXRfaXNfcGxhY2Vob2xkZXIoZmFsc2UpOworCisgIHN0YWNrXy5wdXNoKGN1cnJlbnRfKTsKKyAgY3VycmVudF8gPSBjaGlsZDsKKyAgcmV0dXJuIHRoaXM7Cit9CisKK3ZvaWQgRGVmYXVsdFZhbHVlT2JqZWN0V3JpdGVyOjpXcml0ZVJvb3QoKSB7CisgIHJvb3RfLT5Xcml0ZVRvKG93Xyk7CisgIHJvb3RfLnJlc2V0KE5VTEwpOworICBjdXJyZW50XyA9IE5VTEw7Cit9CisKK0RlZmF1bHRWYWx1ZU9iamVjdFdyaXRlciogRGVmYXVsdFZhbHVlT2JqZWN0V3JpdGVyOjpFbmRMaXN0KCkgeworICBpZiAoc3RhY2tfLmVtcHR5KCkpIHsKKyAgICBXcml0ZVJvb3QoKTsKKyAgICByZXR1cm4gdGhpczsKKyAgfQorICBjdXJyZW50XyA9IHN0YWNrXy50b3AoKTsKKyAgc3RhY2tfLnBvcCgpOworICByZXR1cm4gdGhpczsKK30KKwordm9pZCBEZWZhdWx0VmFsdWVPYmplY3RXcml0ZXI6OlJlbmRlckRhdGFQaWVjZShTdHJpbmdQaWVjZSBuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEYXRhUGllY2UmIGRhdGEpIHsKKyAgTWF5YmVQb3B1bGF0ZUNoaWxkcmVuT2ZBbnkoY3VycmVudF8pOworICB1dGlsOjpTdGF0dXNPcjxzdHJpbmc+IGRhdGFfc3RyaW5nID0gZGF0YS5Ub1N0cmluZygpOworICBpZiAoY3VycmVudF8tPnR5cGUoKSAhPSBOVUxMICYmIGN1cnJlbnRfLT50eXBlKCktPm5hbWUoKSA9PSBrQW55VHlwZSAmJgorICAgICAgbmFtZSA9PSAiQHR5cGUiICYmIGRhdGFfc3RyaW5nLm9rKCkpIHsKKyAgICBjb25zdCBzdHJpbmcmIHN0cmluZ192YWx1ZSA9IGRhdGFfc3RyaW5nLlZhbHVlT3JEaWUoKTsKKyAgICAvLyBJZiB0aGUgdHlwZSBvZiBjdXJyZW50XyBpcyAiQW55IiBhbmQgaXRzICJAdHlwZSIgZmllbGQgaXMgYmVpbmcgc2V0IGhlcmUsCisgICAgLy8gc2V0cyB0aGUgdHlwZSBvZiBjdXJyZW50XyB0byBiZSB0aGUgdHlwZSBzcGVjaWZpZWQgYnkgdGhlICJAdHlwZSIuCisgICAgdXRpbDo6U3RhdHVzT3I8Y29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6VHlwZSo+IGZvdW5kX3R5cGUgPQorICAgICAgICB0eXBlaW5mb18tPlJlc29sdmVUeXBlVXJsKHN0cmluZ192YWx1ZSk7CisgICAgaWYgKCFmb3VuZF90eXBlLm9rKCkpIHsKKyAgICAgIEdPT0dMRV9MT0coV0FSTklORykgPDwgIkZhaWxlZCB0byByZXNvbHZlIHR5cGUgJyIgPDwgc3RyaW5nX3ZhbHVlIDw8ICInLiI7CisgICAgfSBlbHNlIHsKKyAgICAgIGN1cnJlbnRfLT5zZXRfdHlwZShmb3VuZF90eXBlLlZhbHVlT3JEaWUoKSk7CisgICAgfQorICAgIGN1cnJlbnRfLT5zZXRfaXNfYW55KHRydWUpOworICAgIC8vIElmIHRoZSAiQHR5cGUiIGZpZWxkIGlzIHBsYWNlZCBhZnRlciBvdGhlciBmaWVsZHMsIHdlIHNob3VsZCBwb3B1bGF0ZQorICAgIC8vIG90aGVyIGNoaWxkcmVuIG9mIHByaW1pdGl2ZSB0eXBlIG5vdy4gT3RoZXJ3aXNlLCB3ZSBzaG91bGQgd2FpdCB1bnRpbCB0aGUKKyAgICAvLyBmaXJzdCB2YWx1ZSBmaWVsZCBpcyByZW5kZXJlZCBiZWZvcmUgd2UgcG9wdWxhdGUgdGhlIGNoaWxkcmVuLCBiZWNhdXNlCisgICAgLy8gdGhlICJ2YWx1ZSIgZmllbGQgb2YgYSBBbnkgbWVzc2FnZSBjb3VsZCBiZSBvbWl0dGVkLgorICAgIGlmIChjdXJyZW50Xy0+bnVtYmVyX29mX2NoaWxkcmVuKCkgPiAxICYmIGN1cnJlbnRfLT50eXBlKCkgIT0gTlVMTCkgeworICAgICAgY3VycmVudF8tPlBvcHVsYXRlQ2hpbGRyZW4odHlwZWluZm9fKTsKKyAgICB9CisgIH0KKyAgTm9kZSogY2hpbGQgPSBjdXJyZW50Xy0+RmluZENoaWxkKG5hbWUpOworICBpZiAoY2hpbGQgPT0gTlVMTCB8fCBjaGlsZC0+a2luZCgpICE9IFBSSU1JVElWRSkgeworICAgIC8vIE5vIGNoaWxkcmVuIGFyZSBmb3VuZCwgY3JlYXRlcyBhIG5ldyBjaGlsZC4KKyAgICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPE5vZGU+IG5vZGUoCisgICAgICAgIG5ldyBOb2RlKG5hbWUuVG9TdHJpbmcoKSwgTlVMTCwgUFJJTUlUSVZFLCBkYXRhLCBmYWxzZSkpOworICAgIGNoaWxkID0gbm9kZS5nZXQoKTsKKyAgICBjdXJyZW50Xy0+QWRkQ2hpbGQobm9kZS5yZWxlYXNlKCkpOworICB9IGVsc2UgeworICAgIGNoaWxkLT5zZXRfZGF0YShkYXRhKTsKKyAgfQorfQorCit9ICAvLyBuYW1lc3BhY2UgY29udmVydGVyCit9ICAvLyBuYW1lc3BhY2UgdXRpbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvZGVmYXVsdF92YWx1ZV9vYmplY3R3cml0ZXIuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9kZWZhdWx0X3ZhbHVlX29iamVjdHdyaXRlci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY5NWI5ZGQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvZGVmYXVsdF92YWx1ZV9vYmplY3R3cml0ZXIuaApAQCAtMCwwICsxLDIzNCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX1VUSUxfQ09OVkVSVEVSX0RFRkFVTFRfVkFMVUVfT0JKRUNUV1JJVEVSX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfVVRJTF9DT05WRVJURVJfREVGQVVMVF9WQUxVRV9PQkpFQ1RXUklURVJfSF9fCisKKyNpbmNsdWRlIDxtZW1vcnk+CisjaWZuZGVmIF9TSEFSRURfUFRSX0gKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc2hhcmVkX3B0ci5oPgorI2VuZGlmCisjaW5jbHVkZSA8c3RhY2s+CisjaW5jbHVkZSA8dmVjdG9yPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3R5cGVfaW5mby5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL2RhdGFwaWVjZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL29iamVjdF93cml0ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC91dGlsaXR5Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3V0aWwvdHlwZV9yZXNvbHZlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJpbmdwaWVjZS5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgdXRpbCB7CituYW1lc3BhY2UgY29udmVydGVyIHsKKworLy8gQW4gT2JqZWN0V3JpdGVyIHRoYXQgcmVuZGVycyBub24tcmVwZWF0ZWQgcHJpbWl0aXZlIGZpZWxkcyBvZiBwcm90byBtZXNzYWdlcworLy8gd2l0aCB0aGVpciBkZWZhdWx0IHZhbHVlcy4gRGVmYXVsdFZhbHVlT2JqZWN0V3JpdGVyIGhvbGRzIG9iamVjdHMsIGxpc3RzIGFuZAorLy8gZmllbGRzIGl0IHJlY2VpdmVzIGluIGEgdHJlZSBzdHJ1Y3R1cmUgYW5kIHdyaXRlcyB0aGVtIG91dCB0byBhbm90aGVyCisvLyBPYmplY3RXcml0ZXIgd2hlbiBFbmRPYmplY3QoKSBpcyBjYWxsZWQgb24gdGhlIHJvb3Qgb2JqZWN0LiBJdCBhbHNvIHdyaXRlcworLy8gb3V0IGFsbCBub24tcmVwZWF0ZWQgcHJpbWl0aXZlIGZpZWxkcyB0aGF0IGhhdmVuJ3QgYmVlbiBleHBsaWNpdGx5IHJlbmRlcmVkCisvLyB3aXRoIHRoZWlyIGRlZmF1bHQgdmFsdWVzICgwIGZvciBudW1iZXJzLCAiIiBmb3Igc3RyaW5ncywgZXRjKS4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBEZWZhdWx0VmFsdWVPYmplY3RXcml0ZXIgOiBwdWJsaWMgT2JqZWN0V3JpdGVyIHsKKyBwdWJsaWM6CisgIERlZmF1bHRWYWx1ZU9iamVjdFdyaXRlcihUeXBlUmVzb2x2ZXIqIHR5cGVfcmVzb2x2ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlJiB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0V3JpdGVyKiBvdyk7CisKKyAgdmlydHVhbCB+RGVmYXVsdFZhbHVlT2JqZWN0V3JpdGVyKCk7CisKKyAgLy8gT2JqZWN0V3JpdGVyIG1ldGhvZHMuCisgIHZpcnR1YWwgRGVmYXVsdFZhbHVlT2JqZWN0V3JpdGVyKiBTdGFydE9iamVjdChTdHJpbmdQaWVjZSBuYW1lKTsKKworICB2aXJ0dWFsIERlZmF1bHRWYWx1ZU9iamVjdFdyaXRlciogRW5kT2JqZWN0KCk7CisKKyAgdmlydHVhbCBEZWZhdWx0VmFsdWVPYmplY3RXcml0ZXIqIFN0YXJ0TGlzdChTdHJpbmdQaWVjZSBuYW1lKTsKKworICB2aXJ0dWFsIERlZmF1bHRWYWx1ZU9iamVjdFdyaXRlciogRW5kTGlzdCgpOworCisgIHZpcnR1YWwgRGVmYXVsdFZhbHVlT2JqZWN0V3JpdGVyKiBSZW5kZXJCb29sKFN0cmluZ1BpZWNlIG5hbWUsIGJvb2wgdmFsdWUpOworCisgIHZpcnR1YWwgRGVmYXVsdFZhbHVlT2JqZWN0V3JpdGVyKiBSZW5kZXJJbnQzMihTdHJpbmdQaWVjZSBuYW1lLCBpbnQzMiB2YWx1ZSk7CisKKyAgdmlydHVhbCBEZWZhdWx0VmFsdWVPYmplY3RXcml0ZXIqIFJlbmRlclVpbnQzMihTdHJpbmdQaWVjZSBuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMiB2YWx1ZSk7CisKKyAgdmlydHVhbCBEZWZhdWx0VmFsdWVPYmplY3RXcml0ZXIqIFJlbmRlckludDY0KFN0cmluZ1BpZWNlIG5hbWUsIGludDY0IHZhbHVlKTsKKworICB2aXJ0dWFsIERlZmF1bHRWYWx1ZU9iamVjdFdyaXRlciogUmVuZGVyVWludDY0KFN0cmluZ1BpZWNlIG5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDY0IHZhbHVlKTsKKworICB2aXJ0dWFsIERlZmF1bHRWYWx1ZU9iamVjdFdyaXRlciogUmVuZGVyRG91YmxlKFN0cmluZ1BpZWNlIG5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG91YmxlIHZhbHVlKTsKKworICB2aXJ0dWFsIERlZmF1bHRWYWx1ZU9iamVjdFdyaXRlciogUmVuZGVyRmxvYXQoU3RyaW5nUGllY2UgbmFtZSwgZmxvYXQgdmFsdWUpOworCisgIHZpcnR1YWwgRGVmYXVsdFZhbHVlT2JqZWN0V3JpdGVyKiBSZW5kZXJTdHJpbmcoU3RyaW5nUGllY2UgbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdQaWVjZSB2YWx1ZSk7CisgIHZpcnR1YWwgRGVmYXVsdFZhbHVlT2JqZWN0V3JpdGVyKiBSZW5kZXJCeXRlcyhTdHJpbmdQaWVjZSBuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UgdmFsdWUpOworCisgIHZpcnR1YWwgRGVmYXVsdFZhbHVlT2JqZWN0V3JpdGVyKiBSZW5kZXJOdWxsKFN0cmluZ1BpZWNlIG5hbWUpOworCisgcHJpdmF0ZToKKyAgZW51bSBOb2RlS2luZCB7CisgICAgUFJJTUlUSVZFID0gMCwKKyAgICBPQkpFQ1QgPSAxLAorICAgIExJU1QgPSAyLAorICAgIE1BUCA9IDMsCisgIH07CisKKyAgLy8gIk5vZGUiIHJlcHJlc2VudHMgYSBub2RlIGluIHRoZSB0cmVlIHRoYXQgaG9sZHMgdGhlIGlucHV0IG9mCisgIC8vIERlZmF1bHRWYWx1ZU9iamVjdFdyaXRlci4KKyAgY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIE5vZGUgeworICAgcHVibGljOgorICAgIE5vZGUoY29uc3Qgc3RyaW5nJiBuYW1lLCBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlKiB0eXBlLCBOb2RlS2luZCBraW5kLAorICAgICAgICAgY29uc3QgRGF0YVBpZWNlJiBkYXRhLCBib29sIGlzX3BsYWNlaG9sZGVyKTsKKyAgICB2aXJ0dWFsIH5Ob2RlKCkgeworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjaGlsZHJlbl8uc2l6ZSgpOyArK2kpIHsKKyAgICAgICAgZGVsZXRlIGNoaWxkcmVuX1tpXTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvLyBBZGRzIGEgY2hpbGQgdG8gdGhpcyBub2RlLiBUYWtlcyBvd25lcnNoaXAgb2YgdGhpcyBjaGlsZC4KKyAgICB2b2lkIEFkZENoaWxkKE5vZGUqIGNoaWxkKSB7IGNoaWxkcmVuXy5wdXNoX2JhY2soY2hpbGQpOyB9CisKKyAgICAvLyBGaW5kcyB0aGUgY2hpbGQgZ2l2ZW4gaXRzIG5hbWUuCisgICAgTm9kZSogRmluZENoaWxkKFN0cmluZ1BpZWNlIG5hbWUpOworCisgICAgLy8gUG9wdWxhdGVzIGNoaWxkcmVuIG9mIHRoaXMgTm9kZSBiYXNlZCBvbiBpdHMgdHlwZS4gSWYgdGhlcmUgYXJlIGFscmVhZHkKKyAgICAvLyBjaGlsZHJlbiBjcmVhdGVkLCB0aGV5IHdpbGwgYmUgbWVyZ2VkIHRvIHRoZSByZXN1bHQuIENhbGxlciBzaG91bGQgcGFzcworICAgIC8vIGluIFR5cGVJbmZvIGZvciBsb29raW5nIHVwIHR5cGVzIG9mIHRoZSBjaGlsZHJlbi4KKyAgICB2b2lkIFBvcHVsYXRlQ2hpbGRyZW4oY29uc3QgVHlwZUluZm8qIHR5cGVpbmZvKTsKKworICAgIC8vIElmIHRoaXMgbm9kZSBpcyBhIGxlYWYgKGhhcyBkYXRhKSwgd3JpdGVzIHRoZSBjdXJyZW50IG5vZGUgdG8gdGhlCisgICAgLy8gT2JqZWN0V3JpdGVyOyBpZiBub3QsIHRoZW4gcmVjdXJzaXZlbHkgd3JpdGVzIHRoZSBjaGlsZHJlbiB0byB0aGUKKyAgICAvLyBPYmplY3RXcml0ZXIuCisgICAgdm9pZCBXcml0ZVRvKE9iamVjdFdyaXRlciogb3cpOworCisgICAgLy8gQWNjZXNzb3JzCisgICAgY29uc3Qgc3RyaW5nJiBuYW1lKCkgY29uc3QgeyByZXR1cm4gbmFtZV87IH0KKworICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlR5cGUqIHR5cGUoKSB7IHJldHVybiB0eXBlXzsgfQorCisgICAgdm9pZCBzZXRfdHlwZShjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlKiB0eXBlKSB7IHR5cGVfID0gdHlwZTsgfQorCisgICAgTm9kZUtpbmQga2luZCgpIHsgcmV0dXJuIGtpbmRfOyB9CisKKyAgICBpbnQgbnVtYmVyX29mX2NoaWxkcmVuKCkgeyByZXR1cm4gY2hpbGRyZW5fLnNpemUoKTsgfQorCisgICAgdm9pZCBzZXRfZGF0YShjb25zdCBEYXRhUGllY2UmIGRhdGEpIHsgZGF0YV8gPSBkYXRhOyB9CisKKyAgICBib29sIGlzX2FueSgpIHsgcmV0dXJuIGlzX2FueV87IH0KKworICAgIHZvaWQgc2V0X2lzX2FueShib29sIGlzX2FueSkgeyBpc19hbnlfID0gaXNfYW55OyB9CisKKyAgICB2b2lkIHNldF9pc19wbGFjZWhvbGRlcihib29sIGlzX3BsYWNlaG9sZGVyKSB7CisgICAgICBpc19wbGFjZWhvbGRlcl8gPSBpc19wbGFjZWhvbGRlcjsKKyAgICB9CisKKyAgIHByaXZhdGU6CisgICAgLy8gUmV0dXJucyB0aGUgVmFsdWUgVHlwZSBvZiBhIG1hcCBnaXZlbiB0aGUgVHlwZSBvZiB0aGUgbWFwIGVudHJ5IGFuZCBhCisgICAgLy8gVHlwZUluZm8gaW5zdGFuY2UuCisgICAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6VHlwZSogR2V0TWFwVmFsdWVUeXBlKAorICAgICAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlJiBlbnRyeV90eXBlLCBjb25zdCBUeXBlSW5mbyogdHlwZWluZm8pOworCisgICAgLy8gQ2FsbHMgV3JpdGVUbygpIG9uIGV2ZXJ5IGNoaWxkIGluIGNoaWxkcmVuXy4KKyAgICB2b2lkIFdyaXRlQ2hpbGRyZW4oT2JqZWN0V3JpdGVyKiBvdyk7CisKKyAgICAvLyBUaGUgbmFtZSBvZiB0aGlzIG5vZGUuCisgICAgc3RyaW5nIG5hbWVfOworICAgIC8vIGdvb2dsZTo6cHJvdG9idWY6OlR5cGUgb2YgdGhpcyBub2RlLiBPd25lZCBieSBUeXBlSW5mby4KKyAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlKiB0eXBlXzsKKyAgICAvLyBUaGUga2luZCBvZiB0aGlzIG5vZGUuCisgICAgTm9kZUtpbmQga2luZF87CisgICAgLy8gV2hldGhlciB0aGlzIGlzIGEgbm9kZSBmb3IgIkFueSIuCisgICAgYm9vbCBpc19hbnlfOworICAgIC8vIFRoZSBkYXRhIG9mIHRoaXMgbm9kZSB3aGVuIGl0IGlzIGEgbGVhZiBub2RlLgorICAgIERhdGFQaWVjZSBkYXRhXzsKKyAgICAvLyBDaGlsZHJlbiBvZiB0aGlzIG5vZGUuCisgICAgc3RkOjp2ZWN0b3I8Tm9kZSo+IGNoaWxkcmVuXzsKKyAgICAvLyBXaGV0aGVyIHRoaXMgbm9kZSBpcyBhIHBsYWNlaG9sZGVyIGZvciBhbiBvYmplY3Qgb3IgbGlzdCBhdXRvbWF0aWNhbGx5CisgICAgLy8gZ2VuZXJhdGVkIHdoZW4gY3JlYXRpbmcgdGhlIHBhcmVudCBub2RlLiBTaG91bGQgYmUgc2V0IHRvIGZhbHNlIGFmdGVyCisgICAgLy8gdGhlIHBhcmVudCBub2RlJ3MgU3RhcnRPYmplY3QoKS9TdGFydExpc3QoKSBtZXRob2QgaXMgY2FsbGVkIHdpdGggdGhpcworICAgIC8vIG5vZGUncyBuYW1lLgorICAgIGJvb2wgaXNfcGxhY2Vob2xkZXJfOworICB9OworCisgIC8vIFBvcHVsYXRlcyBjaGlsZHJlbiBvZiAibm9kZSIgaWYgaXQgaXMgYW4gImFueSIgTm9kZSBhbmQgaXRzIHJlYWwgdHlwZSBoYXMKKyAgLy8gYmVlbiBnaXZlbi4KKyAgdm9pZCBNYXliZVBvcHVsYXRlQ2hpbGRyZW5PZkFueShOb2RlKiBub2RlKTsKKworICAvLyBXcml0ZXMgdGhlIHJvb3RfIG5vZGUgdG8gb3dfIGFuZCByZXNldHMgdGhlIHJvb3RfIGFuZCBjdXJyZW50XyBwb2ludGVyIHRvCisgIC8vIE5VTEwuCisgIHZvaWQgV3JpdGVSb290KCk7CisKKyAgLy8gQ3JlYXRlcyBhIERhdGFQaWVjZSBjb250YWluaW5nIHRoZSBkZWZhdWx0IHZhbHVlIG9mIHRoZSB0eXBlIG9mIHRoZSBmaWVsZC4KKyAgc3RhdGljIERhdGFQaWVjZSBDcmVhdGVEZWZhdWx0RGF0YVBpZWNlRm9yRmllbGQoCisgICAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZCYgZmllbGQsIGNvbnN0IFR5cGVJbmZvKiB0eXBlaW5mbyk7CisKKyAgLy8gQWRkcyBvciByZXBsYWNlcyB0aGUgZGF0YV8gb2YgYSBwcmltaXRpdmUgY2hpbGQgbm9kZS4KKyAgdm9pZCBSZW5kZXJEYXRhUGllY2UoU3RyaW5nUGllY2UgbmFtZSwgY29uc3QgRGF0YVBpZWNlJiBkYXRhKTsKKworICAvLyBSZXR1cm5zIHRoZSBkZWZhdWx0IGVudW0gdmFsdWUgYXMgYSBEYXRhUGllY2UsIG9yIHRoZSBmaXJzdCBlbnVtIHZhbHVlIGlmCisgIC8vIHRoZXJlIGlzIG5vIGRlZmF1bHQuIEZvciBwcm90bzMsIHdoZXJlIHdlIGNhbm5vdCBzcGVjaWZ5IGFuIGV4cGxpY2l0CisgIC8vIGRlZmF1bHQsIGEgemVybyB2YWx1ZSB3aWxsIGFsd2F5cyBiZSByZXR1cm5lZC4KKyAgc3RhdGljIERhdGFQaWVjZSBGaW5kRW51bURlZmF1bHQoY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGQmIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUeXBlSW5mbyogdHlwZWluZm8pOworCisgIC8vIFR5cGUgaW5mb3JtYXRpb24gZm9yIGFsbCB0aGUgdHlwZXMgdXNlZCBpbiB0aGUgZGVzY3JpcHRvci4gVXNlZCB0byBmaW5kCisgIC8vIGdvb2dsZTo6cHJvdG9idWY6OlR5cGUgb2YgbmVzdGVkIG1lc3NhZ2VzL2VudW1zLgorICBjb25zdCBUeXBlSW5mbyogdHlwZWluZm9fOworICAvLyBXaGV0aGVyIHRoZSBUeXBlSW5mbyBvYmplY3QgaXMgb3duZWQgYnkgdGhpcyBjbGFzcy4KKyAgYm9vbCBvd25fdHlwZWluZm9fOworICAvLyBnb29nbGU6OnByb3RvYnVmOjpUeXBlIG9mIHRoZSByb290IG1lc3NhZ2UgdHlwZS4KKyAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6VHlwZSYgdHlwZV87CisgIC8vIEhvbGRzIGNvcGllcyBvZiBzdHJpbmdzIHBhc3NlZCB0byBSZW5kZXJTdHJpbmcuCisgIHZlY3RvcjxzdHJpbmcqPiBzdHJpbmdfdmFsdWVzXzsKKworICAvLyBUaGUgY3VycmVudCBOb2RlLiBPd25lZCBieSBpdHMgcGFyZW50cy4KKyAgTm9kZSogY3VycmVudF87CisgIC8vIFRoZSByb290IE5vZGUuCisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8Tm9kZT4gcm9vdF87CisgIC8vIFRoZSBzdGFjayB0byBob2xkIHRoZSBwYXRoIG9mIE5vZGVzIGZyb20gY3VycmVudF8gdG8gcm9vdF87CisgIHN0ZDo6c3RhY2s8Tm9kZSo+IHN0YWNrXzsKKworICBPYmplY3RXcml0ZXIqIG93XzsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoRGVmYXVsdFZhbHVlT2JqZWN0V3JpdGVyKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBjb252ZXJ0ZXIKK30gIC8vIG5hbWVzcGFjZSB1dGlsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfVVRJTF9DT05WRVJURVJfREVGQVVMVF9WQUxVRV9PQkpFQ1RXUklURVJfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvZGVmYXVsdF92YWx1ZV9vYmplY3R3cml0ZXJfdGVzdC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9kZWZhdWx0X3ZhbHVlX29iamVjdHdyaXRlcl90ZXN0LmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgyNTRjMGYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvZGVmYXVsdF92YWx1ZV9vYmplY3R3cml0ZXJfdGVzdC5jYwpAQCAtMCwwICsxLDE1NiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9kZWZhdWx0X3ZhbHVlX29iamVjdHdyaXRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL2V4cGVjdGluZ19vYmplY3R3cml0ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90ZXN0ZGF0YS9kZWZhdWx0X3ZhbHVlX3Rlc3QucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90eXBlX2luZm9fdGVzdF9oZWxwZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9jb25zdGFudHMuaD4KKyNpbmNsdWRlIDxndGVzdC9ndGVzdC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgdXRpbCB7CituYW1lc3BhY2UgY29udmVydGVyIHsKK25hbWVzcGFjZSB0ZXN0aW5nIHsKKwordXNpbmcgZ29vZ2xlOjpwcm90b2J1Zjo6dGVzdGluZzo6RGVmYXVsdFZhbHVlVGVzdDsKKworLy8gQmFzZSBjbGFzcyBmb3Igc2V0dGluZyB1cCByZXF1aXJlZCBzdGF0ZSBmb3IgcnVubmluZyBkZWZhdWx0IHZhbHVlcyB0ZXN0cyBvbgorLy8gZGlmZmVyZW50IGRlc2NyaXB0b3JzLgorY2xhc3MgQmFzZURlZmF1bHRWYWx1ZU9iamVjdFdyaXRlclRlc3QKKyAgICA6IHB1YmxpYyA6OnRlc3Rpbmc6OlRlc3RXaXRoUGFyYW08dGVzdGluZzo6VHlwZUluZm9Tb3VyY2U+IHsKKyBwcm90ZWN0ZWQ6CisgIGV4cGxpY2l0IEJhc2VEZWZhdWx0VmFsdWVPYmplY3RXcml0ZXJUZXN0KGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpCisgICAgICA6IGhlbHBlcl8oR2V0UGFyYW0oKSksIG1vY2tfKCksIGV4cGVjdHNfKCZtb2NrXykgeworICAgIGhlbHBlcl8uUmVzZXRUeXBlSW5mbyhkZXNjcmlwdG9yKTsKKyAgICB0ZXN0aW5nXy5yZXNldChoZWxwZXJfLk5ld0RlZmF1bHRWYWx1ZVdyaXRlcigKKyAgICAgICAgc3RyaW5nKGtUeXBlU2VydmljZUJhc2VVcmwpICsgIi8iICsgZGVzY3JpcHRvci0+ZnVsbF9uYW1lKCksICZtb2NrXykpOworICB9CisKKyAgdmlydHVhbCB+QmFzZURlZmF1bHRWYWx1ZU9iamVjdFdyaXRlclRlc3QoKSB7fQorCisgIFR5cGVJbmZvVGVzdEhlbHBlciBoZWxwZXJfOworICBNb2NrT2JqZWN0V3JpdGVyIG1vY2tfOworICBFeHBlY3RpbmdPYmplY3RXcml0ZXIgZXhwZWN0c187CisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8RGVmYXVsdFZhbHVlT2JqZWN0V3JpdGVyPiB0ZXN0aW5nXzsKK307CisKKy8vIFRlc3RzIHRvIGNvdmVyIHNvbWUgYmFzaWMgRGVmYXVsdFZhbHVlT2JqZWN0V3JpdGVyIHVzZSBjYXNlcy4gTW9yZSB0ZXN0cyBhcmUKKy8vIGluIHRoZSBtYXJzaGFsbGluZ190ZXN0LmNjIGFuZCB0cmFuc2xhdG9yX2ludGVncmF0aW9uX3Rlc3QuY2MuCitjbGFzcyBEZWZhdWx0VmFsdWVPYmplY3RXcml0ZXJUZXN0IDogcHVibGljIEJhc2VEZWZhdWx0VmFsdWVPYmplY3RXcml0ZXJUZXN0IHsKKyBwcm90ZWN0ZWQ6CisgIERlZmF1bHRWYWx1ZU9iamVjdFdyaXRlclRlc3QoKQorICAgICAgOiBCYXNlRGVmYXVsdFZhbHVlT2JqZWN0V3JpdGVyVGVzdChEZWZhdWx0VmFsdWVUZXN0OjpkZXNjcmlwdG9yKCkpIHt9CisgIHZpcnR1YWwgfkRlZmF1bHRWYWx1ZU9iamVjdFdyaXRlclRlc3QoKSB7fQorfTsKKworSU5TVEFOVElBVEVfVEVTVF9DQVNFX1AoRGlmZmVyZW50VHlwZUluZm9Tb3VyY2VUZXN0LAorICAgICAgICAgICAgICAgICAgICAgICAgRGVmYXVsdFZhbHVlT2JqZWN0V3JpdGVyVGVzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgIDo6dGVzdGluZzo6VmFsdWVzKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlc3Rpbmc6OlVTRV9UWVBFX1JFU09MVkVSKSk7CisKK1RFU1RfUChEZWZhdWx0VmFsdWVPYmplY3RXcml0ZXJUZXN0LCBFbXB0eSkgeworICAvLyBTZXQgZXhwZWN0YXRpb24KKyAgZXhwZWN0c18uU3RhcnRPYmplY3QoIiIpCisgICAgICAtPlJlbmRlckRvdWJsZSgiZG91YmxlVmFsdWUiLCAwLjApCisgICAgICAtPlN0YXJ0TGlzdCgicmVwZWF0ZWREb3VibGUiKQorICAgICAgLT5FbmRMaXN0KCkKKyAgICAgIC0+UmVuZGVyRmxvYXQoImZsb2F0VmFsdWUiLCAwLjApCisgICAgICAtPlJlbmRlckludDY0KCJpbnQ2NFZhbHVlIiwgMCkKKyAgICAgIC0+UmVuZGVyVWludDY0KCJ1aW50NjRWYWx1ZSIsIDApCisgICAgICAtPlJlbmRlckludDMyKCJpbnQzMlZhbHVlIiwgMCkKKyAgICAgIC0+UmVuZGVyVWludDMyKCJ1aW50MzJWYWx1ZSIsIDApCisgICAgICAtPlJlbmRlckJvb2woImJvb2xWYWx1ZSIsIGZhbHNlKQorICAgICAgLT5SZW5kZXJTdHJpbmcoInN0cmluZ1ZhbHVlIiwgIiIpCisgICAgICAtPlJlbmRlckJ5dGVzKCJieXRlc1ZhbHVlIiwgIiIpCisgICAgICAtPlJlbmRlclN0cmluZygiZW51bVZhbHVlIiwgIkVOVU1fRklSU1QiKQorICAgICAgLT5FbmRPYmplY3QoKTsKKworICAvLyBBY3R1YWwgdGVzdGluZworICB0ZXN0aW5nXy0+U3RhcnRPYmplY3QoIiIpLT5FbmRPYmplY3QoKTsKK30KKworVEVTVF9QKERlZmF1bHRWYWx1ZU9iamVjdFdyaXRlclRlc3QsIE5vbkRlZmF1bHREb3VibGUpIHsKKyAgLy8gU2V0IGV4cGVjdGF0aW9uCisgIGV4cGVjdHNfLlN0YXJ0T2JqZWN0KCIiKQorICAgICAgLT5SZW5kZXJEb3VibGUoImRvdWJsZVZhbHVlIiwgMS4wKQorICAgICAgLT5TdGFydExpc3QoInJlcGVhdGVkRG91YmxlIikKKyAgICAgIC0+RW5kTGlzdCgpCisgICAgICAtPlJlbmRlckZsb2F0KCJmbG9hdFZhbHVlIiwgMC4wKQorICAgICAgLT5SZW5kZXJJbnQ2NCgiaW50NjRWYWx1ZSIsIDApCisgICAgICAtPlJlbmRlclVpbnQ2NCgidWludDY0VmFsdWUiLCAwKQorICAgICAgLT5SZW5kZXJJbnQzMigiaW50MzJWYWx1ZSIsIDApCisgICAgICAtPlJlbmRlclVpbnQzMigidWludDMyVmFsdWUiLCAwKQorICAgICAgLT5SZW5kZXJCb29sKCJib29sVmFsdWUiLCBmYWxzZSkKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJzdHJpbmdWYWx1ZSIsICIiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoImVudW1WYWx1ZSIsICJFTlVNX0ZJUlNUIikKKyAgICAgIC0+RW5kT2JqZWN0KCk7CisKKyAgLy8gQWN0dWFsIHRlc3RpbmcKKyAgdGVzdGluZ18tPlN0YXJ0T2JqZWN0KCIiKS0+UmVuZGVyRG91YmxlKCJkb3VibGVWYWx1ZSIsIDEuMCktPkVuZE9iamVjdCgpOworfQorCitURVNUX1AoRGVmYXVsdFZhbHVlT2JqZWN0V3JpdGVyVGVzdCwgU2hvdWxkUmV0YWluVW5rbm93bkZpZWxkKSB7CisgIC8vIFNldCBleHBlY3RhdGlvbgorICBleHBlY3RzXy5TdGFydE9iamVjdCgiIikKKyAgICAgIC0+UmVuZGVyRG91YmxlKCJkb3VibGVWYWx1ZSIsIDEuMCkKKyAgICAgIC0+U3RhcnRMaXN0KCJyZXBlYXRlZERvdWJsZSIpCisgICAgICAtPkVuZExpc3QoKQorICAgICAgLT5SZW5kZXJGbG9hdCgiZmxvYXRWYWx1ZSIsIDAuMCkKKyAgICAgIC0+UmVuZGVySW50NjQoImludDY0VmFsdWUiLCAwKQorICAgICAgLT5SZW5kZXJVaW50NjQoInVpbnQ2NFZhbHVlIiwgMCkKKyAgICAgIC0+UmVuZGVySW50MzIoImludDMyVmFsdWUiLCAwKQorICAgICAgLT5SZW5kZXJVaW50MzIoInVpbnQzMlZhbHVlIiwgMCkKKyAgICAgIC0+UmVuZGVyQm9vbCgiYm9vbFZhbHVlIiwgZmFsc2UpCisgICAgICAtPlJlbmRlclN0cmluZygic3RyaW5nVmFsdWUiLCAiIikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJ1bmtub3duIiwgImFiYyIpCisgICAgICAtPlN0YXJ0T2JqZWN0KCJ1bmtub3duT2JqZWN0IikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJ1bmtub3duIiwgImRlZiIpCisgICAgICAtPkVuZE9iamVjdCgpCisgICAgICAtPlJlbmRlclN0cmluZygiZW51bVZhbHVlIiwgIkVOVU1fRklSU1QiKQorICAgICAgLT5FbmRPYmplY3QoKTsKKworICAvLyBBY3R1YWwgdGVzdGluZworICB0ZXN0aW5nXy0+U3RhcnRPYmplY3QoIiIpCisgICAgICAtPlJlbmRlckRvdWJsZSgiZG91YmxlVmFsdWUiLCAxLjApCisgICAgICAtPlJlbmRlclN0cmluZygidW5rbm93biIsICJhYmMiKQorICAgICAgLT5TdGFydE9iamVjdCgidW5rbm93bk9iamVjdCIpCisgICAgICAtPlJlbmRlclN0cmluZygidW5rbm93biIsICJkZWYiKQorICAgICAgLT5FbmRPYmplY3QoKQorICAgICAgLT5FbmRPYmplY3QoKTsKK30KKworCit9ICAvLyBuYW1lc3BhY2UgdGVzdGluZworfSAgLy8gbmFtZXNwYWNlIGNvbnZlcnRlcgorfSAgLy8gbmFtZXNwYWNlIHV0aWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL2Vycm9yX2xpc3RlbmVyLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL2Vycm9yX2xpc3RlbmVyLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUzODMwN2IKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvZXJyb3JfbGlzdGVuZXIuY2MKQEAgLTAsMCArMSw0MiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9lcnJvcl9saXN0ZW5lci5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgdXRpbCB7CituYW1lc3BhY2UgY29udmVydGVyIHsKKworCit9ICAvLyBuYW1lc3BhY2UgY29udmVydGVyCit9ICAvLyBuYW1lc3BhY2UgdXRpbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvZXJyb3JfbGlzdGVuZXIuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9lcnJvcl9saXN0ZW5lci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNmMDYzOTMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvZXJyb3JfbGlzdGVuZXIuaApAQCAtMCwwICsxLDEwMyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX1VUSUxfQ09OVkVSVEVSX0VSUk9SX0xJU1RFTkVSX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfVVRJTF9DT05WRVJURVJfRVJST1JfTElTVEVORVJfSF9fCisKKyNpbmNsdWRlIDxhbGdvcml0aG0+CisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDx2ZWN0b3I+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY2FsbGJhY2suaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2xvZ2dpbmcuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9sb2NhdGlvbl90cmFja2VyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cmluZ3BpZWNlLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSB1dGlsIHsKK25hbWVzcGFjZSBjb252ZXJ0ZXIgeworCisvLyBJbnRlcmZhY2UgZm9yIGVycm9yIGxpc3RlbmVyLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEVycm9yTGlzdGVuZXIgeworIHB1YmxpYzoKKyAgdmlydHVhbCB+RXJyb3JMaXN0ZW5lcigpIHt9CisKKyAgLy8gUmVwb3J0cyBhbiBpbnZhbGlkIG5hbWUgYXQgdGhlIGdpdmVuIGxvY2F0aW9uLgorICB2aXJ0dWFsIHZvaWQgSW52YWxpZE5hbWUoY29uc3QgTG9jYXRpb25UcmFja2VySW50ZXJmYWNlJiBsb2MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdQaWVjZSB1bmtub3duX25hbWUsIFN0cmluZ1BpZWNlIG1lc3NhZ2UpID0gMDsKKworICAvLyBSZXBvcnRzIGFuIGludmFsaWQgdmFsdWUgZm9yIGEgZmllbGQuCisgIHZpcnR1YWwgdm9pZCBJbnZhbGlkVmFsdWUoY29uc3QgTG9jYXRpb25UcmFja2VySW50ZXJmYWNlJiBsb2MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UgdHlwZV9uYW1lLCBTdHJpbmdQaWVjZSB2YWx1ZSkgPSAwOworCisgIC8vIFJlcG9ydHMgYSBtaXNzaW5nIHJlcXVpcmVkIGZpZWxkLgorICB2aXJ0dWFsIHZvaWQgTWlzc2luZ0ZpZWxkKGNvbnN0IExvY2F0aW9uVHJhY2tlckludGVyZmFjZSYgbG9jLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1BpZWNlIG1pc3NpbmdfbmFtZSkgPSAwOworCisgcHJvdGVjdGVkOgorICBFcnJvckxpc3RlbmVyKCkge30KKworIHByaXZhdGU6CisgIC8vIERvIG5vdCBhZGQgYW55IGRhdGEgbWVtYmVycyB0byB0aGlzIGNsYXNzLgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoRXJyb3JMaXN0ZW5lcik7Cit9OworCisvLyBBbiBlcnJvciBsaXN0ZW5lciB0aGF0IGlnbm9yZXMgYWxsIGVycm9ycy4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBOb29wRXJyb3JMaXN0ZW5lciA6IHB1YmxpYyBFcnJvckxpc3RlbmVyIHsKKyBwdWJsaWM6CisgIE5vb3BFcnJvckxpc3RlbmVyKCkge30KKyAgdmlydHVhbCB+Tm9vcEVycm9yTGlzdGVuZXIoKSB7fQorCisgIHZpcnR1YWwgdm9pZCBJbnZhbGlkTmFtZShjb25zdCBMb2NhdGlvblRyYWNrZXJJbnRlcmZhY2UmIGxvYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1BpZWNlIHVua25vd25fbmFtZSwgU3RyaW5nUGllY2UgbWVzc2FnZSkge30KKworICB2aXJ0dWFsIHZvaWQgSW52YWxpZFZhbHVlKGNvbnN0IExvY2F0aW9uVHJhY2tlckludGVyZmFjZSYgbG9jLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1BpZWNlIHR5cGVfbmFtZSwgU3RyaW5nUGllY2UgdmFsdWUpIHt9CisKKyAgdmlydHVhbCB2b2lkIE1pc3NpbmdGaWVsZChjb25zdCBMb2NhdGlvblRyYWNrZXJJbnRlcmZhY2UmIGxvYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdQaWVjZSBtaXNzaW5nX25hbWUpIHt9CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoTm9vcEVycm9yTGlzdGVuZXIpOworfTsKKworCit9ICAvLyBuYW1lc3BhY2UgY29udmVydGVyCit9ICAvLyBuYW1lc3BhY2UgdXRpbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX1VUSUxfQ09OVkVSVEVSX0VSUk9SX0xJU1RFTkVSX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL2V4cGVjdGluZ19vYmplY3R3cml0ZXIuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9leHBlY3Rpbmdfb2JqZWN0d3JpdGVyLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWU5OGRkZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9leHBlY3Rpbmdfb2JqZWN0d3JpdGVyLmgKQEAgLTAsMCArMSwyMzggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9VVElMX0NPTlZFUlRFUl9FWFBFQ1RJTkdfT0JKRUNUV1JJVEVSX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfVVRJTF9DT05WRVJURVJfRVhQRUNUSU5HX09CSkVDVFdSSVRFUl9IX18KKworLy8gQW4gaW1wbGVtZW50YXRpb24gb2YgT2JqZWN0V3JpdGVyIHRoYXQgYXV0b21hdGljYWxseSBzZXRzIHRoZQorLy8gZ21vY2sgZXhwZWN0YXRpb25zIGZvciB0aGUgcmVzcG9uc2UgdG8gYSBtZXRob2QuIEV2ZXJ5IG1ldGhvZAorLy8gcmV0dXJucyB0aGUgb2JqZWN0IGl0c2VsZiBmb3IgY2hhaW5pbmcuCisvLworLy8gVXNhZ2U6CisvLyAgIC8vIFNldHVwCisvLyAgIE1vY2tPYmplY3RXcml0ZXIgbW9jazsKKy8vICAgRXhwZWN0aW5nT2JqZWN0V3JpdGVyIG93KCZtb2NrKTsKKy8vCisvLyAgIC8vIFNldCBleHBlY3RhdGlvbgorLy8gICBvdy5TdGFydE9iamVjdCgiIikKKy8vICAgICAgIC0+UmVuZGVyU3RyaW5nKCJrZXkiLCAidmFsdWUiKQorLy8gICAgIC0+RW5kT2JqZWN0KCk7CisvLworLy8gICAvLyBBY3R1YWwgdGVzdGluZworLy8gICBtb2NrLlN0YXJ0T2JqZWN0KFN0cmluZ1BpZWNlKCkpCisvLyAgICAgICAgIC0+UmVuZGVyU3RyaW5nKCJrZXkiLCAidmFsdWUiKQorLy8gICAgICAgLT5FbmRPYmplY3QoKTsKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9vYmplY3Rfd3JpdGVyLmg+CisjaW5jbHVkZSA8Z21vY2svZ21vY2suaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIHV0aWwgeworbmFtZXNwYWNlIGNvbnZlcnRlciB7CisKK3VzaW5nIHRlc3Rpbmc6OklzRW1wdHk7Cit1c2luZyB0ZXN0aW5nOjpOYW5TZW5zaXRpdmVEb3VibGVFcTsKK3VzaW5nIHRlc3Rpbmc6Ok5hblNlbnNpdGl2ZUZsb2F0RXE7Cit1c2luZyB0ZXN0aW5nOjpSZXR1cm47Cit1c2luZyB0ZXN0aW5nOjpTdHJFcTsKK3VzaW5nIHRlc3Rpbmc6OlR5cGVkRXE7CisKK2NsYXNzIE1vY2tPYmplY3RXcml0ZXIgOiBwdWJsaWMgT2JqZWN0V3JpdGVyIHsKKyBwdWJsaWM6CisgIE1vY2tPYmplY3RXcml0ZXIoKSB7fQorCisgIE1PQ0tfTUVUSE9EMShTdGFydE9iamVjdCwgT2JqZWN0V3JpdGVyKihTdHJpbmdQaWVjZSkpOworICBNT0NLX01FVEhPRDAoRW5kT2JqZWN0LCBPYmplY3RXcml0ZXIqKCkpOworICBNT0NLX01FVEhPRDEoU3RhcnRMaXN0LCBPYmplY3RXcml0ZXIqKFN0cmluZ1BpZWNlKSk7CisgIE1PQ0tfTUVUSE9EMChFbmRMaXN0LCBPYmplY3RXcml0ZXIqKCkpOworICBNT0NLX01FVEhPRDIoUmVuZGVyQm9vbCwgT2JqZWN0V3JpdGVyKihTdHJpbmdQaWVjZSwgYm9vbCkpOworICBNT0NLX01FVEhPRDIoUmVuZGVySW50MzIsIE9iamVjdFdyaXRlciooU3RyaW5nUGllY2UsIGludDMyKSk7CisgIE1PQ0tfTUVUSE9EMihSZW5kZXJVaW50MzIsIE9iamVjdFdyaXRlciooU3RyaW5nUGllY2UsIHVpbnQzMikpOworICBNT0NLX01FVEhPRDIoUmVuZGVySW50NjQsIE9iamVjdFdyaXRlciooU3RyaW5nUGllY2UsIGludDY0KSk7CisgIE1PQ0tfTUVUSE9EMihSZW5kZXJVaW50NjQsIE9iamVjdFdyaXRlciooU3RyaW5nUGllY2UsIHVpbnQ2NCkpOworICBNT0NLX01FVEhPRDIoUmVuZGVyRG91YmxlLCBPYmplY3RXcml0ZXIqKFN0cmluZ1BpZWNlLCBkb3VibGUpKTsKKyAgTU9DS19NRVRIT0QyKFJlbmRlckZsb2F0LCBPYmplY3RXcml0ZXIqKFN0cmluZ1BpZWNlLCBmbG9hdCkpOworICBNT0NLX01FVEhPRDIoUmVuZGVyU3RyaW5nLCBPYmplY3RXcml0ZXIqKFN0cmluZ1BpZWNlLCBTdHJpbmdQaWVjZSkpOworICBNT0NLX01FVEhPRDIoUmVuZGVyQnl0ZXMsIE9iamVjdFdyaXRlciooU3RyaW5nUGllY2UsIFN0cmluZ1BpZWNlKSk7CisgIE1PQ0tfTUVUSE9EMShSZW5kZXJOdWxsLCBPYmplY3RXcml0ZXIqKFN0cmluZ1BpZWNlKSk7Cit9OworCitjbGFzcyBFeHBlY3RpbmdPYmplY3RXcml0ZXIgOiBwdWJsaWMgT2JqZWN0V3JpdGVyIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IEV4cGVjdGluZ09iamVjdFdyaXRlcihNb2NrT2JqZWN0V3JpdGVyKiBtb2NrKSA6IG1vY2tfKG1vY2spIHt9CisKKyAgdmlydHVhbCBPYmplY3RXcml0ZXIqIFN0YXJ0T2JqZWN0KFN0cmluZ1BpZWNlIG5hbWUpIHsKKyAgICAobmFtZS5lbXB0eSgpCisgICAgICAgICA/IEVYUEVDVF9DQUxMKCptb2NrXywgU3RhcnRPYmplY3QoSXNFbXB0eSgpKSkKKyAgICAgICAgIDogRVhQRUNUX0NBTEwoKm1vY2tfLCBTdGFydE9iamVjdChTdHJFcShuYW1lLlRvU3RyaW5nKCkpKSkpCisgICAgICAgIC5XaWxsT25jZShSZXR1cm4obW9ja18pKQorICAgICAgICAuUmV0aXJlc09uU2F0dXJhdGlvbigpOworICAgIHJldHVybiB0aGlzOworICB9CisKKyAgdmlydHVhbCBPYmplY3RXcml0ZXIqIEVuZE9iamVjdCgpIHsKKyAgICBFWFBFQ1RfQ0FMTCgqbW9ja18sIEVuZE9iamVjdCgpKQorICAgICAgICAuV2lsbE9uY2UoUmV0dXJuKG1vY2tfKSkKKyAgICAgICAgLlJldGlyZXNPblNhdHVyYXRpb24oKTsKKyAgICByZXR1cm4gdGhpczsKKyAgfQorCisgIHZpcnR1YWwgT2JqZWN0V3JpdGVyKiBTdGFydExpc3QoU3RyaW5nUGllY2UgbmFtZSkgeworICAgIChuYW1lLmVtcHR5KCkKKyAgICAgICAgID8gRVhQRUNUX0NBTEwoKm1vY2tfLCBTdGFydExpc3QoSXNFbXB0eSgpKSkKKyAgICAgICAgIDogRVhQRUNUX0NBTEwoKm1vY2tfLCBTdGFydExpc3QoU3RyRXEobmFtZS5Ub1N0cmluZygpKSkpKQorICAgICAgICAuV2lsbE9uY2UoUmV0dXJuKG1vY2tfKSkKKyAgICAgICAgLlJldGlyZXNPblNhdHVyYXRpb24oKTsKKyAgICByZXR1cm4gdGhpczsKKyAgfQorCisgIHZpcnR1YWwgT2JqZWN0V3JpdGVyKiBFbmRMaXN0KCkgeworICAgIEVYUEVDVF9DQUxMKCptb2NrXywgRW5kTGlzdCgpKQorICAgICAgICAuV2lsbE9uY2UoUmV0dXJuKG1vY2tfKSkKKyAgICAgICAgLlJldGlyZXNPblNhdHVyYXRpb24oKTsKKyAgICByZXR1cm4gdGhpczsKKyAgfQorCisgIHZpcnR1YWwgT2JqZWN0V3JpdGVyKiBSZW5kZXJCb29sKFN0cmluZ1BpZWNlIG5hbWUsIGJvb2wgdmFsdWUpIHsKKyAgICAobmFtZS5lbXB0eSgpCisgICAgICAgICA/IEVYUEVDVF9DQUxMKCptb2NrXywgUmVuZGVyQm9vbChJc0VtcHR5KCksIFR5cGVkRXE8Ym9vbD4odmFsdWUpKSkKKyAgICAgICAgIDogRVhQRUNUX0NBTEwoKm1vY2tfLCBSZW5kZXJCb29sKFN0ckVxKG5hbWUuVG9TdHJpbmcoKSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlZEVxPGJvb2w+KHZhbHVlKSkpKQorICAgICAgICAuV2lsbE9uY2UoUmV0dXJuKG1vY2tfKSkKKyAgICAgICAgLlJldGlyZXNPblNhdHVyYXRpb24oKTsKKyAgICByZXR1cm4gdGhpczsKKyAgfQorCisgIHZpcnR1YWwgT2JqZWN0V3JpdGVyKiBSZW5kZXJJbnQzMihTdHJpbmdQaWVjZSBuYW1lLCBpbnQzMiB2YWx1ZSkgeworICAgIChuYW1lLmVtcHR5KCkKKyAgICAgICAgID8gRVhQRUNUX0NBTEwoKm1vY2tfLCBSZW5kZXJJbnQzMihJc0VtcHR5KCksIFR5cGVkRXE8aW50MzI+KHZhbHVlKSkpCisgICAgICAgICA6IEVYUEVDVF9DQUxMKCptb2NrXywgUmVuZGVySW50MzIoU3RyRXEobmFtZS5Ub1N0cmluZygpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlZEVxPGludDMyPih2YWx1ZSkpKSkKKyAgICAgICAgLldpbGxPbmNlKFJldHVybihtb2NrXykpCisgICAgICAgIC5SZXRpcmVzT25TYXR1cmF0aW9uKCk7CisgICAgcmV0dXJuIHRoaXM7CisgIH0KKworICB2aXJ0dWFsIE9iamVjdFdyaXRlciogUmVuZGVyVWludDMyKFN0cmluZ1BpZWNlIG5hbWUsIHVpbnQzMiB2YWx1ZSkgeworICAgIChuYW1lLmVtcHR5KCkKKyAgICAgICAgID8gRVhQRUNUX0NBTEwoKm1vY2tfLCBSZW5kZXJVaW50MzIoSXNFbXB0eSgpLCBUeXBlZEVxPHVpbnQzMj4odmFsdWUpKSkKKyAgICAgICAgIDogRVhQRUNUX0NBTEwoKm1vY2tfLCBSZW5kZXJVaW50MzIoU3RyRXEobmFtZS5Ub1N0cmluZygpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZWRFcTx1aW50MzI+KHZhbHVlKSkpKQorICAgICAgICAuV2lsbE9uY2UoUmV0dXJuKG1vY2tfKSkKKyAgICAgICAgLlJldGlyZXNPblNhdHVyYXRpb24oKTsKKyAgICByZXR1cm4gdGhpczsKKyAgfQorCisgIHZpcnR1YWwgT2JqZWN0V3JpdGVyKiBSZW5kZXJJbnQ2NChTdHJpbmdQaWVjZSBuYW1lLCBpbnQ2NCB2YWx1ZSkgeworICAgIChuYW1lLmVtcHR5KCkKKyAgICAgICAgID8gRVhQRUNUX0NBTEwoKm1vY2tfLCBSZW5kZXJJbnQ2NChJc0VtcHR5KCksIFR5cGVkRXE8aW50NjQ+KHZhbHVlKSkpCisgICAgICAgICA6IEVYUEVDVF9DQUxMKCptb2NrXywgUmVuZGVySW50NjQoU3RyRXEobmFtZS5Ub1N0cmluZygpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlZEVxPGludDY0Pih2YWx1ZSkpKSkKKyAgICAgICAgLldpbGxPbmNlKFJldHVybihtb2NrXykpCisgICAgICAgIC5SZXRpcmVzT25TYXR1cmF0aW9uKCk7CisgICAgcmV0dXJuIHRoaXM7CisgIH0KKworICB2aXJ0dWFsIE9iamVjdFdyaXRlciogUmVuZGVyVWludDY0KFN0cmluZ1BpZWNlIG5hbWUsIHVpbnQ2NCB2YWx1ZSkgeworICAgIChuYW1lLmVtcHR5KCkKKyAgICAgICAgID8gRVhQRUNUX0NBTEwoKm1vY2tfLCBSZW5kZXJVaW50NjQoSXNFbXB0eSgpLCBUeXBlZEVxPHVpbnQ2ND4odmFsdWUpKSkKKyAgICAgICAgIDogRVhQRUNUX0NBTEwoKm1vY2tfLCBSZW5kZXJVaW50NjQoU3RyRXEobmFtZS5Ub1N0cmluZygpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZWRFcTx1aW50NjQ+KHZhbHVlKSkpKQorICAgICAgICAuV2lsbE9uY2UoUmV0dXJuKG1vY2tfKSkKKyAgICAgICAgLlJldGlyZXNPblNhdHVyYXRpb24oKTsKKyAgICByZXR1cm4gdGhpczsKKyAgfQorCisgIHZpcnR1YWwgT2JqZWN0V3JpdGVyKiBSZW5kZXJEb3VibGUoU3RyaW5nUGllY2UgbmFtZSwgZG91YmxlIHZhbHVlKSB7CisgICAgKG5hbWUuZW1wdHkoKQorICAgICAgICAgPyBFWFBFQ1RfQ0FMTCgqbW9ja18sIFJlbmRlckRvdWJsZShJc0VtcHR5KCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5hblNlbnNpdGl2ZURvdWJsZUVxKHZhbHVlKSkpCisgICAgICAgICA6IEVYUEVDVF9DQUxMKCptb2NrXywgUmVuZGVyRG91YmxlKFN0ckVxKG5hbWUuVG9TdHJpbmcoKSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5hblNlbnNpdGl2ZURvdWJsZUVxKHZhbHVlKSkpKQorICAgICAgICAuV2lsbE9uY2UoUmV0dXJuKG1vY2tfKSkKKyAgICAgICAgLlJldGlyZXNPblNhdHVyYXRpb24oKTsKKyAgICByZXR1cm4gdGhpczsKKyAgfQorCisgIHZpcnR1YWwgT2JqZWN0V3JpdGVyKiBSZW5kZXJGbG9hdChTdHJpbmdQaWVjZSBuYW1lLCBmbG9hdCB2YWx1ZSkgeworICAgIChuYW1lLmVtcHR5KCkKKyAgICAgICAgID8gRVhQRUNUX0NBTEwoKm1vY2tfLCBSZW5kZXJGbG9hdChJc0VtcHR5KCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmFuU2Vuc2l0aXZlRmxvYXRFcSh2YWx1ZSkpKQorICAgICAgICAgOiBFWFBFQ1RfQ0FMTCgqbW9ja18sIFJlbmRlckZsb2F0KFN0ckVxKG5hbWUuVG9TdHJpbmcoKSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmFuU2Vuc2l0aXZlRmxvYXRFcSh2YWx1ZSkpKSkKKyAgICAgICAgLldpbGxPbmNlKFJldHVybihtb2NrXykpCisgICAgICAgIC5SZXRpcmVzT25TYXR1cmF0aW9uKCk7CisgICAgcmV0dXJuIHRoaXM7CisgIH0KKworICB2aXJ0dWFsIE9iamVjdFdyaXRlciogUmVuZGVyU3RyaW5nKFN0cmluZ1BpZWNlIG5hbWUsIFN0cmluZ1BpZWNlIHZhbHVlKSB7CisgICAgKG5hbWUuZW1wdHkoKQorICAgICAgICAgPyBFWFBFQ1RfQ0FMTCgqbW9ja18sIFJlbmRlclN0cmluZyhJc0VtcHR5KCksCisgICAgICAgICAgICAgICBUeXBlZEVxPFN0cmluZ1BpZWNlPih2YWx1ZS5Ub1N0cmluZygpKSkpCisgICAgICAgICA6IEVYUEVDVF9DQUxMKCptb2NrXywgUmVuZGVyU3RyaW5nKFN0ckVxKG5hbWUuVG9TdHJpbmcoKSksCisgICAgICAgICAgICAgICBUeXBlZEVxPFN0cmluZ1BpZWNlPih2YWx1ZS5Ub1N0cmluZygpKSkpKQorICAgICAgICAuV2lsbE9uY2UoUmV0dXJuKG1vY2tfKSkKKyAgICAgICAgLlJldGlyZXNPblNhdHVyYXRpb24oKTsKKyAgICByZXR1cm4gdGhpczsKKyAgfQorICB2aXJ0dWFsIE9iamVjdFdyaXRlciogUmVuZGVyQnl0ZXMoU3RyaW5nUGllY2UgbmFtZSwgU3RyaW5nUGllY2UgdmFsdWUpIHsKKyAgICAobmFtZS5lbXB0eSgpCisgICAgICAgICA/IEVYUEVDVF9DQUxMKCptb2NrXywgUmVuZGVyQnl0ZXMoSXNFbXB0eSgpLCBUeXBlZEVxPFN0cmluZ1BpZWNlPigKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZS5Ub1N0cmluZygpKSkpCisgICAgICAgICA6IEVYUEVDVF9DQUxMKCptb2NrXywKKyAgICAgICAgICAgICAgICAgICAgICAgUmVuZGVyQnl0ZXMoU3RyRXEobmFtZS5Ub1N0cmluZygpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZWRFcTxTdHJpbmdQaWVjZT4odmFsdWUuVG9TdHJpbmcoKSkpKSkKKyAgICAgICAgLldpbGxPbmNlKFJldHVybihtb2NrXykpCisgICAgICAgIC5SZXRpcmVzT25TYXR1cmF0aW9uKCk7CisgICAgcmV0dXJuIHRoaXM7CisgIH0KKworICB2aXJ0dWFsIE9iamVjdFdyaXRlciogUmVuZGVyTnVsbChTdHJpbmdQaWVjZSBuYW1lKSB7CisgICAgKG5hbWUuZW1wdHkoKSA/IEVYUEVDVF9DQUxMKCptb2NrXywgUmVuZGVyTnVsbChJc0VtcHR5KCkpKQorICAgICAgICAgICAgICAgICAgOiBFWFBFQ1RfQ0FMTCgqbW9ja18sIFJlbmRlck51bGwoU3RyRXEobmFtZS5Ub1N0cmluZygpKSkpCisgICAgICAgICAgICAgICAgICAgICAgICAuV2lsbE9uY2UoUmV0dXJuKG1vY2tfKSkKKyAgICAgICAgICAgICAgICAgICAgICAgIC5SZXRpcmVzT25TYXR1cmF0aW9uKCkpOworICAgIHJldHVybiB0aGlzOworICB9CisKKyBwcml2YXRlOgorICBNb2NrT2JqZWN0V3JpdGVyKiBtb2NrXzsKKworICBHT09HTEVfRElTQUxMT1dfSU1QTElDSVRfQ09OU1RSVUNUT1JTKEV4cGVjdGluZ09iamVjdFdyaXRlcik7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgY29udmVydGVyCit9ICAvLyBuYW1lc3BhY2UgdXRpbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX1VUSUxfQ09OVkVSVEVSX0VYUEVDVElOR19PQkpFQ1RXUklURVJfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvZmllbGRfbWFza191dGlsaXR5LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL2ZpZWxkX21hc2tfdXRpbGl0eS5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMGU4ZmM4Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL2ZpZWxkX21hc2tfdXRpbGl0eS5jYwpAQCAtMCwwICsxLDIyNSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9maWVsZF9tYXNrX3V0aWxpdHkuaD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0YXR1c19tYWNyb3MuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIHV0aWwgeworbmFtZXNwYWNlIGNvbnZlcnRlciB7CisKK25hbWVzcGFjZSB7CitpbmxpbmUgdXRpbDo6U3RhdHVzIENhbGxQYXRoU2luayhQYXRoU2lua0NhbGxiYWNrIHBhdGhfc2luaywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UgYXJnKSB7CisgIHJldHVybiBwYXRoX3NpbmstPlJ1bihhcmcpOworfQorCit1dGlsOjpTdGF0dXMgQ3JlYXRlUHVibGljRXJyb3IodXRpbDo6ZXJyb3I6OkNvZGUgY29kZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgbWVzc2FnZSkgeworICByZXR1cm4gdXRpbDo6U3RhdHVzKGNvZGUsIG1lc3NhZ2UpOworfQorCisvLyBBcHBlbmRzIGEgRmllbGRNYXNrIHBhdGggc2VnbWVudCB0byBhIHByZWZpeC4KK3N0cmluZyBBcHBlbmRQYXRoU2VnbWVudFRvUHJlZml4KFN0cmluZ1BpZWNlIHByZWZpeCwgU3RyaW5nUGllY2Ugc2VnbWVudCkgeworICBpZiAocHJlZml4LmVtcHR5KCkpIHsKKyAgICByZXR1cm4gc2VnbWVudC5Ub1N0cmluZygpOworICB9CisgIGlmIChzZWdtZW50LmVtcHR5KCkpIHsKKyAgICByZXR1cm4gcHJlZml4LlRvU3RyaW5nKCk7CisgIH0KKyAgLy8gSWYgdGhlIHNlZ21lbnQgaXMgYSBtYXAga2V5LCBhcHBlbmRzIGl0IHRvIHRoZSBwcmVmaXggd2l0aG91dCB0aGUgIi4iLgorICBpZiAoc2VnbWVudC5zdGFydHNfd2l0aCgiW1wiIikpIHsKKyAgICByZXR1cm4gU3RyQ2F0KHByZWZpeCwgc2VnbWVudCk7CisgIH0KKyAgcmV0dXJuIFN0ckNhdChwcmVmaXgsICIuIiwgc2VnbWVudCk7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCitzdHJpbmcgQ29udmVydEZpZWxkTWFza1BhdGgoY29uc3QgU3RyaW5nUGllY2UgcGF0aCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb252ZXJ0ZXJDYWxsYmFjayBjb252ZXJ0ZXIpIHsKKyAgc3RyaW5nIHJlc3VsdDsKKyAgcmVzdWx0LnJlc2VydmUocGF0aC5zaXplKCkgPDwgMSk7CisKKyAgYm9vbCBpc19xdW90ZWQgPSBmYWxzZTsKKyAgYm9vbCBpc19lc2NhcGluZyA9IGZhbHNlOworICBpbnQgY3VycmVudF9zZWdtZW50X3N0YXJ0ID0gMDsKKworICAvLyBMb29wcyB1bnRpbCAxIHBhc3NlZCB0aGUgZW5kIG9mIHRoZSBpbnB1dCB0byBtYWtlIGhhbmRsaW5nIHRoZSBsYXN0CisgIC8vIHNlZ21lbnQgZWFzaWVyLgorICBmb3IgKHNpemVfdCBpID0gMDsgaSA8PSBwYXRoLnNpemUoKTsgKytpKSB7CisgICAgLy8gT3V0cHV0cyBxdW90ZWQgc3RyaW5nIGFzLWlzLgorICAgIGlmIChpc19xdW90ZWQpIHsKKyAgICAgIGlmIChpID09IHBhdGguc2l6ZSgpKSB7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgcmVzdWx0LnB1c2hfYmFjayhwYXRoW2ldKTsKKyAgICAgIGlmIChpc19lc2NhcGluZykgeworICAgICAgICBpc19lc2NhcGluZyA9IGZhbHNlOworICAgICAgfSBlbHNlIGlmIChwYXRoW2ldID09ICdcXCcpIHsKKyAgICAgICAgaXNfZXNjYXBpbmcgPSB0cnVlOworICAgICAgfSBlbHNlIGlmIChwYXRoW2ldID09ICdcIicpIHsKKyAgICAgICAgY3VycmVudF9zZWdtZW50X3N0YXJ0ID0gaSArIDE7CisgICAgICAgIGlzX3F1b3RlZCA9IGZhbHNlOworICAgICAgfQorICAgICAgY29udGludWU7CisgICAgfQorICAgIGlmIChpID09IHBhdGguc2l6ZSgpIHx8IHBhdGhbaV0gPT0gJy4nIHx8IHBhdGhbaV0gPT0gJygnIHx8CisgICAgICAgIHBhdGhbaV0gPT0gJyknIHx8IHBhdGhbaV0gPT0gJ1wiJykgeworICAgICAgcmVzdWx0ICs9IGNvbnZlcnRlcigKKyAgICAgICAgICBwYXRoLnN1YnN0cihjdXJyZW50X3NlZ21lbnRfc3RhcnQsIGkgLSBjdXJyZW50X3NlZ21lbnRfc3RhcnQpKTsKKyAgICAgIGlmIChpIDwgcGF0aC5zaXplKCkpIHsKKyAgICAgICAgcmVzdWx0LnB1c2hfYmFjayhwYXRoW2ldKTsKKyAgICAgIH0KKyAgICAgIGN1cnJlbnRfc2VnbWVudF9zdGFydCA9IGkgKyAxOworICAgIH0KKyAgICBpZiAoaSA8IHBhdGguc2l6ZSgpICYmIHBhdGhbaV0gPT0gJ1wiJykgeworICAgICAgaXNfcXVvdGVkID0gdHJ1ZTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIHJlc3VsdDsKK30KKwordXRpbDo6U3RhdHVzIERlY29kZUNvbXBhY3RGaWVsZE1hc2tQYXRocyhTdHJpbmdQaWVjZSBwYXRocywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQYXRoU2lua0NhbGxiYWNrIHBhdGhfc2luaykgeworICBzdGFjazxzdHJpbmc+IHByZWZpeDsKKyAgaW50IGxlbmd0aCA9IHBhdGhzLmxlbmd0aCgpOworICBpbnQgcHJldmlvdXNfcG9zaXRpb24gPSAwOworICBib29sIGluX21hcF9rZXkgPSBmYWxzZTsKKyAgYm9vbCBpc19lc2NhcGluZyA9IGZhbHNlOworICAvLyBMb29wcyB1bnRpbCAxIHBhc3NlZCB0aGUgZW5kIG9mIHRoZSBpbnB1dCB0byBtYWtlIHRoZSBoYW5kbGUgb2YgdGhlIGxhc3QKKyAgLy8gc2VnbWVudCBlYXNpZXIuCisgIGZvciAoaW50IGkgPSAwOyBpIDw9IGxlbmd0aDsgKytpKSB7CisgICAgaWYgKGkgIT0gbGVuZ3RoKSB7CisgICAgICAvLyBTa2lwcyBldmVyeXRoaW5nIGluIGEgbWFwIGtleSB1bnRpbCB3ZSBoaXQgdGhlIGVuZCBvZiBpdCwgd2hpY2ggaXMKKyAgICAgIC8vIG1hcmtlZCBieSBhbiB1bi1lc2NhcGVkICciJyBpbW1lZGlhdGVseSBmb2xsb3dlZCBieSBhICddJy4KKyAgICAgIGlmIChpbl9tYXBfa2V5KSB7CisgICAgICAgIGlmIChpc19lc2NhcGluZykgeworICAgICAgICAgIGlzX2VzY2FwaW5nID0gZmFsc2U7CisgICAgICAgICAgY29udGludWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHBhdGhzW2ldID09ICdcXCcpIHsKKyAgICAgICAgICBpc19lc2NhcGluZyA9IHRydWU7CisgICAgICAgICAgY29udGludWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHBhdGhzW2ldICE9ICdcIicpIHsKKyAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorICAgICAgICAvLyBVbi1lc2NhcGVkICciJyBtdXN0IGJlIGZvbGxvd2VkIHdpdGggYSAnXScuCisgICAgICAgIGlmIChpID49IGxlbmd0aCAtIDEgfHwgcGF0aHNbaSArIDFdICE9ICddJykgeworICAgICAgICAgIHJldHVybiB1dGlsOjpTdGF0dXMoCisgICAgICAgICAgICAgIHV0aWw6OmVycm9yOjpJTlZBTElEX0FSR1VNRU5ULAorICAgICAgICAgICAgICBTdHJDYXQoIkludmFsaWQgRmllbGRNYXNrICciLCBwYXRocywKKyAgICAgICAgICAgICAgICAgICAgICInLiBNYXAga2V5cyBzaG91bGQgYmUgcmVwcmVzZW50ZWQgYXMgW1wic29tZV9rZXlcIl0uIikpOworICAgICAgICB9CisgICAgICAgIC8vIFRoZSBlbmQgb2YgdGhlIG1hcCBrZXkgKCJcIl0iKSBoYXMgYmVlbiBmb3VuZC4KKyAgICAgICAgaW5fbWFwX2tleSA9IGZhbHNlOworICAgICAgICAvLyBTa2lwcyAnXScuCisgICAgICAgIGkrKzsKKyAgICAgICAgLy8gQ2hlY2tzIHdoZXRoZXIgdGhlIGtleSBlbmRzIGF0IHRoZSBlbmQgb2YgYSBwYXRoIHNlZ21lbnQuCisgICAgICAgIGlmIChpIDwgbGVuZ3RoIC0gMSAmJiBwYXRoc1tpICsgMV0gIT0gJy4nICYmIHBhdGhzW2kgKyAxXSAhPSAnLCcgJiYKKyAgICAgICAgICAgIHBhdGhzW2kgKyAxXSAhPSAnKScgJiYgcGF0aHNbaSArIDFdICE9ICcoJykgeworICAgICAgICAgIHJldHVybiB1dGlsOjpTdGF0dXMoCisgICAgICAgICAgICAgIHV0aWw6OmVycm9yOjpJTlZBTElEX0FSR1VNRU5ULAorICAgICAgICAgICAgICBTdHJDYXQoIkludmFsaWQgRmllbGRNYXNrICciLCBwYXRocywKKyAgICAgICAgICAgICAgICAgICAgICInLiBNYXAga2V5cyBzaG91bGQgYmUgYXQgdGhlIGVuZCBvZiBhIHBhdGggc2VnbWVudC4iKSk7CisgICAgICAgIH0KKyAgICAgICAgaXNfZXNjYXBpbmcgPSBmYWxzZTsKKyAgICAgICAgY29udGludWU7CisgICAgICB9CisKKyAgICAgIC8vIFdlIGFyZSBub3QgaW4gYSBtYXAga2V5LCBsb29rIGZvciB0aGUgc3RhcnQgb2Ygb25lLgorICAgICAgaWYgKHBhdGhzW2ldID09ICdbJykgeworICAgICAgICBpZiAoaSA+PSBsZW5ndGggLSAxIHx8IHBhdGhzW2kgKyAxXSAhPSAnXCInKSB7CisgICAgICAgICAgcmV0dXJuIHV0aWw6OlN0YXR1cygKKyAgICAgICAgICAgICAgdXRpbDo6ZXJyb3I6OklOVkFMSURfQVJHVU1FTlQsCisgICAgICAgICAgICAgIFN0ckNhdCgiSW52YWxpZCBGaWVsZE1hc2sgJyIsIHBhdGhzLAorICAgICAgICAgICAgICAgICAgICAgIicuIE1hcCBrZXlzIHNob3VsZCBiZSByZXByZXNlbnRlZCBhcyBbXCJzb21lX2tleVwiXS4iKSk7CisgICAgICAgIH0KKyAgICAgICAgLy8gIltcIiIgc3RhcnRzIGEgbWFwIGtleS4KKyAgICAgICAgaW5fbWFwX2tleSA9IHRydWU7CisgICAgICAgIGkrKzsgIC8vIFNraXBzIHRoZSAnXCInLgorICAgICAgICBjb250aW51ZTsKKyAgICAgIH0KKyAgICAgIC8vIElmIHRoZSBjdXJyZW50IGNoYXJhY3RlciBpcyBub3QgYSBzcGVjaWFsIGNoYXJhY3RlciAoJywnLCAnKCcgb3IgJyknKSwKKyAgICAgIC8vIGNvbnRpbnVlIHRvIHRoZSBuZXh0LgorICAgICAgaWYgKHBhdGhzW2ldICE9ICcsJyAmJiBwYXRoc1tpXSAhPSAnKScgJiYgcGF0aHNbaV0gIT0gJygnKSB7CisgICAgICAgIGNvbnRpbnVlOworICAgICAgfQorICAgIH0KKyAgICAvLyBHZXRzIHRoZSBjdXJyZW50IHNlZ21lbnQgLSBzdWItc3RyaW5nIGJldHdlZW4gcHJldmlvdXMgcG9zaXRpb24gKGFmdGVyCisgICAgLy8gJygnLCAnKScsICcsJywgb3IgdGhlIGJlZ2lubmluZyBvZiB0aGUgaW5wdXQpIGFuZCB0aGUgY3VycmVudCBwb3NpdGlvbi4KKyAgICBTdHJpbmdQaWVjZSBzZWdtZW50ID0KKyAgICAgICAgcGF0aHMuc3Vic3RyKHByZXZpb3VzX3Bvc2l0aW9uLCBpIC0gcHJldmlvdXNfcG9zaXRpb24pOworICAgIHN0cmluZyBjdXJyZW50X3ByZWZpeCA9IHByZWZpeC5lbXB0eSgpID8gIiIgOiBwcmVmaXgudG9wKCk7CisKKyAgICBpZiAoaSA8IGxlbmd0aCAmJiBwYXRoc1tpXSA9PSAnKCcpIHsKKyAgICAgIC8vIEJ1aWxkcyBhIHByZWZpeCBhbmQgc2F2ZSBpdCBpbnRvIHRoZSBzdGFjay4KKyAgICAgIHByZWZpeC5wdXNoKEFwcGVuZFBhdGhTZWdtZW50VG9QcmVmaXgoY3VycmVudF9wcmVmaXgsIHNlZ21lbnQpKTsKKyAgICB9IGVsc2UgaWYgKCFzZWdtZW50LmVtcHR5KCkpIHsKKyAgICAgIC8vIFdoZW4gdGhlIGN1cnJlbnQgY2hhcmFjdG9yIGlzICcpJywgJywnIG9yIHRoZSBjdXJyZW50IHBvc2l0aW9uIGhhcworICAgICAgLy8gcGFzc2VkIHRoZSBlbmQgb2YgdGhlIGlucHV0LCBidWlsZHMgYW5kIG91dHB1dHMgYSBuZXcgcGF0aHMgYnkKKyAgICAgIC8vIGNvbmNhdGVuYXRpbmcgdGhlIGxhc3QgcHJlZml4IHdpdGggdGhlIGN1cnJlbnQgc2VnbWVudC4KKyAgICAgIFJFVFVSTl9JRl9FUlJPUihDYWxsUGF0aFNpbmsoCisgICAgICAgICAgcGF0aF9zaW5rLCBBcHBlbmRQYXRoU2VnbWVudFRvUHJlZml4KGN1cnJlbnRfcHJlZml4LCBzZWdtZW50KSkpOworICAgIH0KKworICAgIC8vIFJlbW92ZXMgdGhlIGxhc3QgcHJlZml4IGFmdGVyIHNlZWluZyBhICcpJy4KKyAgICBpZiAoaSA8IGxlbmd0aCAmJiBwYXRoc1tpXSA9PSAnKScpIHsKKyAgICAgIGlmIChwcmVmaXguZW1wdHkoKSkgeworICAgICAgICByZXR1cm4gdXRpbDo6U3RhdHVzKAorICAgICAgICAgICAgdXRpbDo6ZXJyb3I6OklOVkFMSURfQVJHVU1FTlQsCisgICAgICAgICAgICBTdHJDYXQoIkludmFsaWQgRmllbGRNYXNrICciLCBwYXRocywKKyAgICAgICAgICAgICAgICAgICAiJy4gQ2Fubm90IGZpbmQgbWF0Y2hpbmcgJygnIGZvciBhbGwgJyknLiIpKTsKKyAgICAgIH0KKyAgICAgIHByZWZpeC5wb3AoKTsKKyAgICB9CisgICAgcHJldmlvdXNfcG9zaXRpb24gPSBpICsgMTsKKyAgfQorICBpZiAoaW5fbWFwX2tleSkgeworICAgIHJldHVybiB1dGlsOjpTdGF0dXModXRpbDo6ZXJyb3I6OklOVkFMSURfQVJHVU1FTlQsCisgICAgICAgICAgICAgICAgICAgICAgICAgIFN0ckNhdCgiSW52YWxpZCBGaWVsZE1hc2sgJyIsIHBhdGhzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIicuIENhbm5vdCBmaW5kIG1hdGNoaW5nICddJyBmb3IgYWxsICdbJy4iKSk7CisgIH0KKyAgaWYgKCFwcmVmaXguZW1wdHkoKSkgeworICAgIHJldHVybiB1dGlsOjpTdGF0dXModXRpbDo6ZXJyb3I6OklOVkFMSURfQVJHVU1FTlQsCisgICAgICAgICAgICAgICAgICAgICAgICAgIFN0ckNhdCgiSW52YWxpZCBGaWVsZE1hc2sgJyIsIHBhdGhzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIicuIENhbm5vdCBmaW5kIG1hdGNoaW5nICcpJyBmb3IgYWxsICcoJy4iKSk7CisgIH0KKyAgcmV0dXJuIHV0aWw6OlN0YXR1czo6T0s7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBjb252ZXJ0ZXIKK30gIC8vIG5hbWVzcGFjZSB1dGlsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9maWVsZF9tYXNrX3V0aWxpdHkuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9maWVsZF9tYXNrX3V0aWxpdHkuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41OWYzNmY3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL2ZpZWxkX21hc2tfdXRpbGl0eS5oCkBAIC0wLDAgKzEsNzIgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBGaWVsZE1hc2sgcmVsYXRlZCB1dGlsaXR5IG1ldGhvZHMuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX1VUSUxfQ09OVkVSVEVSX0ZJRUxEX01BU0tfVVRJTElUWV9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1VUSUxfQ09OVkVSVEVSX0ZJRUxEX01BU0tfVVRJTElUWV9IX18KKworI2luY2x1ZGUgPGZ1bmN0aW9uYWw+CisjaW5jbHVkZSA8c3RhY2s+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cmluZ3BpZWNlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0YXR1cy5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgdXRpbCB7CituYW1lc3BhY2UgY29udmVydGVyIHsKKwordHlwZWRlZiBzdHJpbmcgKCpDb252ZXJ0ZXJDYWxsYmFjaykoU3RyaW5nUGllY2UpOwordHlwZWRlZiBSZXN1bHRDYWxsYmFjazE8dXRpbDo6U3RhdHVzLCBTdHJpbmdQaWVjZT4qIFBhdGhTaW5rQ2FsbGJhY2s7CisKKy8vIEFwcGxpZXMgYSAnY29udmVydGVyJyB0byBlYWNoIHNlZ21lbnQgb2YgYSBGaWVsZE1hc2sgcGF0aCBhbmQgcmV0dXJucyB0aGUKKy8vIHJlc3VsdC4gUXVvdGVkIHN0cmluZ3MgaW4gdGhlICdwYXRoJyBhcmUgY29waWVkIHRvIHRoZSBvdXRwdXQgYXMtaXMgd2l0aG91dAorLy8gY29udmVydGluZyB0aGVpciBjb250ZW50LiBFc2NhcGluZyBpcyBzdXBwb3J0ZWQgd2l0aGluIHF1b3RlZCBzdHJpbmdzLgorLy8gRm9yIGV4YW1wbGUsICJhYlwiX2MiIHdpbGwgYmUgcmV0dXJuZWQgYXMgImFiXCJfYyIgd2l0aG91dCBhbnkgY2hhbmdlcy4KK3N0cmluZyBDb252ZXJ0RmllbGRNYXNrUGF0aChjb25zdCBTdHJpbmdQaWVjZSBwYXRoLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnZlcnRlckNhbGxiYWNrIGNvbnZlcnRlcik7CisKKy8vIERlY29kZXMgYSBjb21wYWN0IGxpc3Qgb2YgRmllbGRNYXNrcy4gRm9yIGV4YW1wbGUsICJhLmIsYS5jLmQsYS5jLmUiIHdpbGwgYmUKKy8vIGRlY29kZWQgaW50byBhIGxpc3Qgb2YgZmllbGQgcGF0aHMgLSAiYS5iIiwgImEuYy5kIiwgImEuYy5lIi4gQW5kIHRoZSByZXN1bHRzCisvLyB3aWxsIGJlIHNlbnQgdG8gJ3BhdGhfc2luaycsIGkuZS4gJ3BhdGhfc2luaycgd2lsbCBiZSBjYWxsZWQgb25jZSBwZXIKKy8vIHJlc3VsdGluZyBwYXRoLgorLy8gTm90ZSB0aGF0IHdlIGFsc28gc3VwcG9ydCBBcGlhcnkgc3R5bGUgRmllbGRNYXNrIGZvcm0uIFRoZSBhYm92ZSBleGFtcGxlIGluCisvLyB0aGUgQXBpYXJ5IHN0eWxlIHdpbGwgbG9vayBsaWtlICJhLmIsYS5jKGQsZSkiLgordXRpbDo6U3RhdHVzIERlY29kZUNvbXBhY3RGaWVsZE1hc2tQYXRocyhTdHJpbmdQaWVjZSBwYXRocywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQYXRoU2lua0NhbGxiYWNrIHBhdGhfc2luayk7CisKK30gIC8vIG5hbWVzcGFjZSBjb252ZXJ0ZXIKK30gIC8vIG5hbWVzcGFjZSB1dGlsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfVVRJTF9DT05WRVJURVJfRklFTERfTUFTS19VVElMSVRZX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL2pzb25fZXNjYXBpbmcuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvanNvbl9lc2NhcGluZy5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNGJkNTU0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL2pzb25fZXNjYXBpbmcuY2MKQEAgLTAsMCArMSw0MDQgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvanNvbl9lc2NhcGluZy5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2xvZ2dpbmcuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSB1dGlsIHsKK25hbWVzcGFjZSBjb252ZXJ0ZXIgeworCituYW1lc3BhY2UgeworCisvLyBBcnJheSBvZiBoZXggY2hhcmFjdGVycyBmb3IgY29udmVyc2lvbiB0byBoZXguCitzdGF0aWMgY29uc3QgY2hhciBrSGV4W10gPSAiMDEyMzQ1Njc4OWFiY2RlZiI7CisKKy8vIENoYXJhY3RlcnMgMHgwMCB0byAweDlmIGFyZSB2ZXJ5IGNvbW1vbmx5IHVzZWQsIHNvIHdlIHByb3ZpZGUgYSBzcGVjaWFsCisvLyB0YWJsZSBsb29rdXAuCisvLworLy8gRm9yIHVuaWNvZGUgY29kZSBwb2ludCBjaCA8IDB4YTA6CisvLyBrQ29tbW9uRXNjYXBlc1tjaF0gaXMgdGhlIGVzY2FwZWQgc3RyaW5nIG9mIGNoLCBpZiBlc2NhcGluZyBpcyBuZWVkZWQ7CisvLyAgICAgICAgICAgICAgICAgICAgb3IgYW4gZW1wdHkgc3RyaW5nLCBpZiBlc2NhcGluZyBpcyBub3QgbmVlZGVkLgorc3RhdGljIGNvbnN0IGNoYXIga0NvbW1vbkVzY2FwZXNbMTYwXVs3XSA9IHsKKyAgLy8gQzAgKEFTQ0lJIGFuZCBkZXJpdmF0aXZlcykgY29udHJvbCBjaGFyYWN0ZXJzCisgICJcXHUwMDAwIiwgIlxcdTAwMDEiLCAiXFx1MDAwMiIsICJcXHUwMDAzIiwgIC8vIDB4MDAKKyAgIlxcdTAwMDQiLCAiXFx1MDAwNSIsICJcXHUwMDA2IiwgIlxcdTAwMDciLAorICAiXFxiIiwgICAgICJcXHQiLCAgICAgIlxcbiIsICAgICAiXFx1MDAwYiIsCisgICJcXGYiLCAgICAgIlxcciIsICAgICAiXFx1MDAwZSIsICJcXHUwMDBmIiwKKyAgIlxcdTAwMTAiLCAiXFx1MDAxMSIsICJcXHUwMDEyIiwgIlxcdTAwMTMiLCAgLy8gMHgxMAorICAiXFx1MDAxNCIsICJcXHUwMDE1IiwgIlxcdTAwMTYiLCAiXFx1MDAxNyIsCisgICJcXHUwMDE4IiwgIlxcdTAwMTkiLCAiXFx1MDAxYSIsICJcXHUwMDFiIiwKKyAgIlxcdTAwMWMiLCAiXFx1MDAxZCIsICJcXHUwMDFlIiwgIlxcdTAwMWYiLAorICAvLyBFc2NhcGluZyBvZiAiIGFuZCBcIGFyZSByZXF1aXJlZCBieSB3d3cuanNvbi5vcmcgc3RyaW5nIGRlZmluaXRpb24uCisgIC8vIEVzY2FwaW5nIG9mIDwgYW5kID4gYXJlIHJlcXVpcmVkIGZvciBIVE1MIHNlY3VyaXR5LgorICAiIiwgIiIsICJcXFwiIiwgIiIsICIiLCAgICAgICAgIiIsICIiLCAgICAgICAgIiIsICAvLyAweDIwCisgICIiLCAiIiwgIiIsICAgICAiIiwgIiIsICAgICAgICAiIiwgIiIsICAgICAgICAiIiwKKyAgIiIsICIiLCAiIiwgICAgICIiLCAiIiwgICAgICAgICIiLCAiIiwgICAgICAgICIiLCAgLy8gMHgzMAorICAiIiwgIiIsICIiLCAgICAgIiIsICJcXHUwMDNjIiwgIiIsICJcXHUwMDNlIiwgIiIsCisgICIiLCAiIiwgIiIsICAgICAiIiwgIiIsICAgICAgICAiIiwgIiIsICAgICAgICAiIiwgIC8vIDB4NDAKKyAgIiIsICIiLCAiIiwgICAgICIiLCAiIiwgICAgICAgICIiLCAiIiwgICAgICAgICIiLAorICAiIiwgIiIsICIiLCAgICAgIiIsICIiLCAgICAgICAgIiIsICIiLCAgICAgICAgIiIsICAvLyAweDUwCisgICIiLCAiIiwgIiIsICAgICAiIiwgIlxcXFwiLCAgICAiIiwgIiIsICAgICAgICAiIiwKKyAgIiIsICIiLCAiIiwgICAgICIiLCAiIiwgICAgICAgICIiLCAiIiwgICAgICAgICIiLCAgLy8gMHg2MAorICAiIiwgIiIsICIiLCAgICAgIiIsICIiLCAgICAgICAgIiIsICIiLCAgICAgICAgIiIsCisgICIiLCAiIiwgIiIsICAgICAiIiwgIiIsICAgICAgICAiIiwgIiIsICAgICAgICAiIiwgIC8vIDB4NzAKKyAgIiIsICIiLCAiIiwgICAgICIiLCAiIiwgICAgICAgICIiLCAiIiwgICAgICAgICJcXHUwMDdmIiwKKyAgLy8gQzEgKElTTyA4ODU5IGFuZCBVbmljb2RlKSBleHRlbmRlZCBjb250cm9sIGNoYXJhY3RlcnMKKyAgIlxcdTAwODAiLCAiXFx1MDA4MSIsICJcXHUwMDgyIiwgIlxcdTAwODMiLCAgLy8gMHg4MAorICAiXFx1MDA4NCIsICJcXHUwMDg1IiwgIlxcdTAwODYiLCAiXFx1MDA4NyIsCisgICJcXHUwMDg4IiwgIlxcdTAwODkiLCAiXFx1MDA4YSIsICJcXHUwMDhiIiwKKyAgIlxcdTAwOGMiLCAiXFx1MDA4ZCIsICJcXHUwMDhlIiwgIlxcdTAwOGYiLAorICAiXFx1MDA5MCIsICJcXHUwMDkxIiwgIlxcdTAwOTIiLCAiXFx1MDA5MyIsICAvLyAweDkwCisgICJcXHUwMDk0IiwgIlxcdTAwOTUiLCAiXFx1MDA5NiIsICJcXHUwMDk3IiwKKyAgIlxcdTAwOTgiLCAiXFx1MDA5OSIsICJcXHUwMDlhIiwgIlxcdTAwOWIiLAorICAiXFx1MDA5YyIsICJcXHUwMDlkIiwgIlxcdTAwOWUiLCAiXFx1MDA5ZiIKK307CisKKy8vIERldGVybWluZXMgaWYgdGhlIGdpdmVuIGNoYXIgdmFsdWUgaXMgYSB1bmljb2RlIGhpZ2gtc3Vycm9nYXRlIGNvZGUgdW5pdC4KKy8vIFN1Y2ggdmFsdWVzIGRvIG5vdCByZXByZXNlbnQgY2hhcmFjdGVycyBieSB0aGVtc2VsdmVzLCBidXQgYXJlIHVzZWQgaW4gdGhlCisvLyByZXByZXNlbnRhdGlvbiBvZiBzdXBwbGVtZW50YXJ5IGNoYXJhY3RlcnMgaW4gdGhlIHV0Zi0xNiBlbmNvZGluZy4KK2lubGluZSBib29sIElzSGlnaFN1cnJvZ2F0ZSh1aW50MTYgYykgeworICAvLyBPcHRpbWl6ZWQgZm9ybSBvZjoKKyAgLy8gcmV0dXJuIGMgPj0ga01pbkhpZ2hTdXJyb2dhdGUgJiYgYyA8PSBrTWF4SGlnaFN1cnJvZ2F0ZTsKKyAgLy8gKFJlZHVjZWQgZnJvbSAzIEFMVSBpbnN0cnVjdGlvbnMgdG8gMiBBTFUgaW5zdHJ1Y3Rpb25zKQorICByZXR1cm4gKGMgJiB+KEpzb25Fc2NhcGluZzo6a01heEhpZ2hTdXJyb2dhdGUgLQorICAgICAgICAgICAgICAgIEpzb25Fc2NhcGluZzo6a01pbkhpZ2hTdXJyb2dhdGUpKQorICAgICAgPT0gSnNvbkVzY2FwaW5nOjprTWluSGlnaFN1cnJvZ2F0ZTsKK30KKworLy8gRGV0ZXJtaW5lcyBpZiB0aGUgZ2l2ZW4gY2hhciB2YWx1ZSBpcyBhIHVuaWNvZGUgbG93LXN1cnJvZ2F0ZSBjb2RlIHVuaXQuCisvLyBTdWNoIHZhbHVlcyBkbyBub3QgcmVwcmVzZW50IGNoYXJhY3RlcnMgYnkgdGhlbXNlbHZlcywgYnV0IGFyZSB1c2VkIGluIHRoZQorLy8gcmVwcmVzZW50YXRpb24gb2Ygc3VwcGxlbWVudGFyeSBjaGFyYWN0ZXJzIGluIHRoZSB1dGYtMTYgZW5jb2RpbmcuCitpbmxpbmUgYm9vbCBJc0xvd1N1cnJvZ2F0ZSh1aW50MTYgYykgeworICAvLyBPcHRpbWl6ZWQgZm9ybSBvZjoKKyAgLy8gcmV0dXJuIGMgPj0ga01pbkxvd1N1cnJvZ2F0ZSAmJiBjIDw9IGtNYXhMb3dTdXJyb2dhdGU7CisgIC8vIChSZWR1Y2VkIGZyb20gMyBBTFUgaW5zdHJ1Y3Rpb25zIHRvIDIgQUxVIGluc3RydWN0aW9ucykKKyAgcmV0dXJuIChjICYgfihKc29uRXNjYXBpbmc6OmtNYXhMb3dTdXJyb2dhdGUgLQorICAgICAgICAgICAgICAgIEpzb25Fc2NhcGluZzo6a01pbkxvd1N1cnJvZ2F0ZSkpCisgICAgICA9PSBKc29uRXNjYXBpbmc6OmtNaW5Mb3dTdXJyb2dhdGU7Cit9CisKKy8vIERldGVybWluZXMgaWYgdGhlIGdpdmVuIGNoYXIgdmFsdWUgaXMgYSB1bmljb2RlIHN1cnJvZ2F0ZSBjb2RlIHVuaXQgKGVpdGhlcgorLy8gaGlnaC1zdXJyb2dhdGUgb3IgbG93LXN1cnJvZ2F0ZSkuCitpbmxpbmUgYm9vbCBJc1N1cnJvZ2F0ZSh1aW50MzIgYykgeworICAvLyBPcHRpbWl6ZWQgZm9ybSBvZjoKKyAgLy8gcmV0dXJuIGMgPj0ga01pbkhpZ2hTdXJyb2dhdGUgJiYgYyA8PSBrTWF4TG93U3Vycm9nYXRlOworICAvLyAoUmVkdWNlZCBmcm9tIDMgQUxVIGluc3RydWN0aW9ucyB0byAyIEFMVSBpbnN0cnVjdGlvbnMpCisgIHJldHVybiAoYyAmIDB4ZmZmZmY4MDApID09IEpzb25Fc2NhcGluZzo6a01pbkhpZ2hTdXJyb2dhdGU7Cit9CisKKy8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gdW5pY29kZSBjb2RlIHBvaW50IGNwIGlzCisvLyBpbiB0aGUgc3VwcGxlbWVudGFyeSBjaGFyYWN0ZXIgcmFuZ2UuCitpbmxpbmUgYm9vbCBJc1N1cHBsZW1lbnRhbENvZGVQb2ludCh1aW50MzIgY3ApIHsKKyAgLy8gT3B0aW1pemVkIGZvcm0gb2Y6CisgIC8vIHJldHVybiBrTWluU3VwcGxlbWVudGFyeUNvZGVQb2ludCA8PSBjcCAmJiBjcCA8PSBrTWF4Q29kZVBvaW50OworICAvLyAoUmVkdWNlZCBmcm9tIDMgQUxVIGluc3RydWN0aW9ucyB0byAyIEFMVSBpbnN0cnVjdGlvbnMpCisgIHJldHVybiAoY3AgJiB+KEpzb25Fc2NhcGluZzo6a01pblN1cHBsZW1lbnRhcnlDb2RlUG9pbnQgLSAxKSkKKyAgICAgIDwgSnNvbkVzY2FwaW5nOjprTWF4Q29kZVBvaW50OworfQorCisvLyBSZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIHVuaWNvZGUgY29kZSBwb2ludCBjcCBpcyBhIHZhbGlkCisvLyB1bmljb2RlIGNvZGUgcG9pbnQgKGkuZS4gaW4gdGhlIHJhbmdlIDAgPD0gY3AgPD0ga01heENvZGVQb2ludCkuCitpbmxpbmUgYm9vbCBJc1ZhbGlkQ29kZVBvaW50KHVpbnQzMiBjcCkgeworICByZXR1cm4gY3AgPD0gSnNvbkVzY2FwaW5nOjprTWF4Q29kZVBvaW50OworfQorCisvLyBDb252ZXJ0cyB0aGUgc3BlY2lmaWVkIHN1cnJvZ2F0ZSBwYWlyIHRvIGl0cyBzdXBwbGVtZW50YXJ5IGNvZGUgcG9pbnQgdmFsdWUuCisvLyBJdCBpcyB0aGUgY2FsbGVycycgcmVzcG9uc2liaWxpdHkgdG8gdmFsaWRhdGUgdGhlIHNwZWNpZmllZCBzdXJyb2dhdGUgcGFpci4KK2lubGluZSB1aW50MzIgVG9Db2RlUG9pbnQodWludDE2IGhpZ2gsIHVpbnQxNiBsb3cpIHsKKyAgLy8gT3B0aW1pemVkIGZvcm0gb2Y6CisgIC8vIHJldHVybiAoKGhpZ2ggLSBrTWluSGlnaFN1cnJvZ2F0ZSkgPDwgMTApCisgIC8vICAgICArIChsb3cgLSBrTWluTG93U3Vycm9nYXRlKQorICAvLyAgICAgKyBrTWluU3VwcGxlbWVudGFyeUNvZGVQb2ludDsKKyAgLy8gKFJlZHVjZWQgZnJvbSA1IEFMVSBpbnN0cnVjdGlvbnMgdG8gMyBBTFUgaW5zdHJ1Y3Rpb25zKQorICByZXR1cm4gKGhpZ2ggPDwgMTApICsgbG93ICsKKyAgICAgIChKc29uRXNjYXBpbmc6OmtNaW5TdXBwbGVtZW50YXJ5Q29kZVBvaW50CisgICAgICAgLSAoc3RhdGljX2Nhc3Q8dW5zaWduZWQ+KEpzb25Fc2NhcGluZzo6a01pbkhpZ2hTdXJyb2dhdGUpIDw8IDEwKQorICAgICAgIC0gSnNvbkVzY2FwaW5nOjprTWluTG93U3Vycm9nYXRlKTsKK30KKworLy8gUmV0dXJucyB0aGUgbG93IHN1cnJvZ2F0ZSBmb3IgdGhlIGdpdmVuIHVuaWNvZGUgY29kZSBwb2ludC4gVGhlIHJlc3VsdCBpcworLy8gbWVhbmluZ2xlc3MgaWYgdGhlIGdpdmVuIGNvZGUgcG9pbnQgaXMgbm90IGEgc3VwcGxlbWVudGFyeSBjaGFyYWN0ZXIuCitpbmxpbmUgdWludDE2IFRvTG93U3Vycm9nYXRlKHVpbnQzMiBjcCkgeworICByZXR1cm4gKGNwICYgKEpzb25Fc2NhcGluZzo6a01heExvd1N1cnJvZ2F0ZQorICAgICAgICAgICAgICAgIC0gSnNvbkVzY2FwaW5nOjprTWluTG93U3Vycm9nYXRlKSkKKyAgICAgICsgSnNvbkVzY2FwaW5nOjprTWluTG93U3Vycm9nYXRlOworfQorCisvLyBSZXR1cm5zIHRoZSBoaWdoIHN1cnJvZ2F0ZSBmb3IgdGhlIGdpdmVuIHVuaWNvZGUgY29kZSBwb2ludC4gVGhlIHJlc3VsdCBpcworLy8gbWVhbmluZ2xlc3MgaWYgdGhlIGdpdmVuIGNvZGUgcG9pbnQgaXMgbm90IGEgc3VwcGxlbWVudGFyeSBjaGFyYWN0ZXIuCitpbmxpbmUgdWludDE2IFRvSGlnaFN1cnJvZ2F0ZSh1aW50MzIgY3ApIHsKKyAgcmV0dXJuIChjcCA+PiAxMCkgKyAoSnNvbkVzY2FwaW5nOjprTWluSGlnaFN1cnJvZ2F0ZSAtCisgICAgICAgICAgICAgICAgICAgICAgIChKc29uRXNjYXBpbmc6OmtNaW5TdXBwbGVtZW50YXJ5Q29kZVBvaW50ID4+IDEwKSk7Cit9CisKKy8vIElucHV0IHN0ciBpcyBlbmNvZGVkIGluIFVURi04LiBBIHVuaWNvZGUgY29kZSBwb2ludCBjb3VsZCBiZSBlbmNvZGVkIGluCisvLyBVVEYtOCB1c2luZyBhbnl3aGVyZSBmcm9tIDEgdG8gNCBjaGFyYWN0ZXJzLCBhbmQgaXQgY291bGQgc3BhbiBtdWx0aXBsZQorLy8gcmVhZHMgb2YgdGhlIEJ5dGVTb3VyY2UuCisvLworLy8gVGhpcyBmdW5jdGlvbiByZWFkcyB0aGUgbmV4dCB1bmljb2RlIGNvZGUgcG9pbnQgZnJvbSB0aGUgaW5wdXQgKHN0cikgYXQKKy8vIHRoZSBnaXZlbiBwb3NpdGlvbiAoaW5kZXgpLCB0YWtpbmcgaW50byBhY2NvdW50IGFueSBsZWZ0LW92ZXIgcGFydGlhbAorLy8gY29kZSBwb2ludCBmcm9tIHRoZSBwcmV2aW91cyBpdGVyYXRpb24gKGNwKSwgdG9nZXRoZXIgd2l0aCB0aGUgbnVtYmVyCisvLyBvZiBjaGFyYWN0ZXJzIGxlZnQgdG8gcmVhZCB0byBjb21wbGV0ZSB0aGlzIGNvZGUgcG9pbnQgKG51bV9sZWZ0KS4KKy8vCisvLyBUaGlzIGZ1bmN0aW9uIGFzc3VtZXMgdGhhdCB0aGUgaW5wdXQgKHN0cikgaXMgdmFsaWQgYXQgdGhlIGdpdmVuIHBvc2l0aW9uCisvLyAoaW5kZXgpLiBJbiBvcmRlciB3b3JkcywgYXQgbGVhc3Qgb25lIGNoYXJhY3RlciBjb3VsZCBiZSByZWFkIHN1Y2Nlc3NmdWxseS4KKy8vCisvLyBUaGUgY29kZSBwb2ludCByZWFkIChwYXJ0aWFsIG9yIGNvbXBsZXRlKSBpcyBzdG9yZWQgaW4gKGNwKS4gVXBvbiByZXR1cm4sCisvLyAobnVtX2xlZnQpIHN0b3JlcyB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdGhhdCBoYXMgeWV0IHRvIGJlIHJlYWQgaW4KKy8vIG9yZGVyIHRvIGNvbXBsZXRlIHRoZSBjdXJyZW50IHVuaWNvZGUgY29kZSBwb2ludC4gSWYgdGhlIHJlYWQgaXMgY29tcGxldGUsCisvLyB0aGVuIChudW1fbGVmdCkgaXMgMC4gQWxzbywgKG51bV9yZWFkKSBpcyB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgcmVhZC4KKy8vCisvLyBSZXR1cm5zIGZhbHNlIGlmIHdlIGVuY291bnRlciBhbiBpbnZhbGlkIFVURi04IHN0cmluZy4gUmV0dXJucyB0cnVlCisvLyBvdGhlcndpc2UsIGluY2x1ZGluZyB0aGUgY2FzZSB3aGVuIHdlIHJlYWNoIHRoZSBlbmQgb2YgdGhlIGlucHV0IChzdHIpCisvLyBiZWZvcmUgYSBjb21wbGV0ZSB1bmljb2RlIGNvZGUgcG9pbnQgaXMgcmVhZC4KK2Jvb2wgUmVhZENvZGVQb2ludChTdHJpbmdQaWVjZSBzdHIsIGludCBpbmRleCwKKyAgICAgICAgICAgICAgICAgICB1aW50MzIgKmNwLCBpbnQqIG51bV9sZWZ0LCBpbnQgKm51bV9yZWFkKSB7CisgIGlmICgqbnVtX2xlZnQgPT0gMCkgeworICAgIC8vIExhc3QgcmVhZCB3YXMgY29tcGxldGUuIFN0YXJ0IHJlYWRpbmcgYSBuZXcgdW5pY29kZSBjb2RlIHBvaW50LgorICAgICpjcCA9IHN0YXRpY19jYXN0PHVpbnQ4PihzdHJbaW5kZXgrK10pOworICAgICpudW1fcmVhZCA9IDE7CisgICAgLy8gVGhlIGxlbmd0aCBvZiB0aGUgY29kZSBwb2ludCBpcyBkZXRlcm1pbmVkIGZyb20gcmVhZGluZyB0aGUgZmlyc3QgYnl0ZS4KKyAgICAvLworICAgIC8vIElmIHRoZSBmaXJzdCBieXRlIGlzIGJldHdlZW46CisgICAgLy8gICAgMC4uMHg3ZjogdGhhdCdzIHRoZSB2YWx1ZSBvZiB0aGUgY29kZSBwb2ludC4KKyAgICAvLyAweDgwLi4weGJmOiA8aW52YWxpZD4KKyAgICAvLyAweGMwLi4weGRmOiAxMS1iaXQgY29kZSBwb2ludCBlbmNvZGVkIGluIDIgYnl0ZXMuCisgICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJpdCAxMC02LCBiaXQgNS0wCisgICAgLy8gMHhlMC4uMHhlZjogMTYtYml0IGNvZGUgcG9pbnQgZW5jb2RlZCBpbiAzIGJ5dGVzLgorICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgYml0IDE1LTEyLCBiaXQgMTEtNiwgYml0IDUtMAorICAgIC8vIDB4ZjAuLjB4Zjc6IDIxLWJpdCBjb2RlIHBvaW50IGVuY29kZWQgaW4gNCBieXRlcy4KKyAgICAvLyAgICAgICAgICAgICBiaXQgMjAtMTgsIGJpdCAxNy0xMiwgYml0IDExLTYsIGJpdCA1LTAKKyAgICAvLyAweGY4Li4weGZmOiA8aW52YWxpZD4KKyAgICAvLworICAgIC8vIE1lYW5pbmcgb2YgZWFjaCBiaXQ6CisgICAgLy8gPG1zYj4gYml0IDc6IDAgLSBzaW5nbGUgYnl0ZSBjb2RlIHBvaW50OiBiaXRzIDYtMCBhcmUgdmFsdWVzLgorICAgIC8vICAgICAgICAgICAgICAxIC0gbXVsdGlieXRlIGNvZGUgcG9pbnQKKyAgICAvLyAgICAgICBiaXQgNjogMCAtIHN1YnNlcXVlbnQgYnl0ZXMgb2YgbXVsdGlieXRlIGNvZGUgcG9pbnQ6CisgICAgLy8gICAgICAgICAgICAgICAgICBiaXRzIDUtMCBhcmUgdmFsdWVzLgorICAgIC8vICAgICAgICAgICAgICAxIC0gZmlyc3QgYnl0ZSBvZiBtdWx0aWJ5dGUgY29kZSBwb2ludAorICAgIC8vICAgICAgIGJpdCA1OiAwIC0gZmlyc3QgYnl0ZSBvZiAyLWJ5dGUgY29kZSBwb2ludDogYml0cyA0LTAgYXJlIHZhbHVlcy4KKyAgICAvLyAgICAgICAgICAgICAgMSAtIGZpcnN0IGJ5dGUgb2YgY29kZSBwb2ludCB3aXRoID49IDMgYnl0ZXMuCisgICAgLy8gICAgICAgYml0IDQ6IDAgLSBmaXJzdCBieXRlIG9mIDMtYnl0ZSBjb2RlIHBvaW50OiBiaXRzIDMtMCBhcmUgdmFsdWVzLgorICAgIC8vICAgICAgICAgICAgICAxIC0gZmlyc3QgYnl0ZSBvZiBjb2RlIHBvaW50IHdpdGggPj0gNCBieXRlcy4KKyAgICAvLyAgICAgICBiaXQgMzogMCAtIGZpcnN0IGJ5dGUgb2YgNC1ieXRlIGNvZGUgcG9pbnQ6IGJpdHMgMi0wIGFyZSB2YWx1ZXMuCisgICAgLy8gICAgICAgICAgICAgIDEgLSByZXNlcnZlZCBmb3IgZnV0dXJlIGV4cGFuc2lvbi4KKyAgICBpZiAoKmNwIDw9IDB4N2YpIHsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0gZWxzZSBpZiAoKmNwIDw9IDB4YmYpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9IGVsc2UgaWYgKCpjcCA8PSAweGRmKSB7CisgICAgICAqY3AgJj0gMHgxZjsKKyAgICAgICpudW1fbGVmdCA9IDE7CisgICAgfSBlbHNlIGlmICgqY3AgPD0gMHhlZikgeworICAgICAgKmNwICY9IDB4MGY7CisgICAgICAqbnVtX2xlZnQgPSAyOworICAgIH0gZWxzZSBpZiAoKmNwIDw9IDB4ZjcpIHsKKyAgICAgICpjcCAmPSAweDA3OworICAgICAgKm51bV9sZWZ0ID0gMzsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICAvLyBMYXN0IHJlYWQgd2FzIHBhcnRpYWwuIEluaXRpYWxpemUgbnVtX3JlYWQgdG8gMCBhbmQgY29udGludWUgcmVhZGluZworICAgIC8vIHRoZSBsYXN0IHVuaWNvZGUgY29kZSBwb2ludC4KKyAgICAqbnVtX3JlYWQgPSAwOworICB9CisgIHdoaWxlICgqbnVtX2xlZnQgPiAwICYmIGluZGV4IDwgc3RyLnNpemUoKSkgeworICAgIHVpbnQzMiBjaCA9IHN0YXRpY19jYXN0PHVpbnQ4PihzdHJbaW5kZXgrK10pOworICAgIC0tKCpudW1fbGVmdCk7CisgICAgKysoKm51bV9yZWFkKTsKKyAgICAqY3AgPSAoKmNwIDw8IDYpIHwgKGNoICYgMHgzZik7CisgICAgaWYgKGNoIDwgMHg4MCB8fCBjaCA+IDB4YmYpIHJldHVybiBmYWxzZTsKKyAgfQorICByZXR1cm4gKm51bV9sZWZ0ID4gMCB8fCAoIUlzU3Vycm9nYXRlKCpjcCkgJiYgSXNWYWxpZENvZGVQb2ludCgqY3ApKTsKK30KKworLy8gU3RvcmVzIHRoZSAxNi1iaXQgdW5pY29kZSBjb2RlIHBvaW50IGFzIGl0cyBoZXhhZGVjaW1hbCBkaWdpdHMgaW4gYnVmZmVyCisvLyBhbmQgcmV0dXJucyBhIFN0cmluZ1BpZWNlIHRoYXQgcG9pbnRzIHRvIHRoaXMgYnVmZmVyLiBUaGUgaW5wdXQgYnVmZmVyIG5lZWRzCisvLyB0byBiZSBhdCBsZWFzdCA2IGJ5dGVzIGxvbmcuCitTdHJpbmdQaWVjZSBUb0hleCh1aW50MTYgY3AsIGNoYXIqIGJ1ZmZlcikgeworICBidWZmZXJbNV0gPSBrSGV4W2NwICYgMHgwZl07CisgIGNwID4+PSA0OworICBidWZmZXJbNF0gPSBrSGV4W2NwICYgMHgwZl07CisgIGNwID4+PSA0OworICBidWZmZXJbM10gPSBrSGV4W2NwICYgMHgwZl07CisgIGNwID4+PSA0OworICBidWZmZXJbMl0gPSBrSGV4W2NwICYgMHgwZl07CisgIHJldHVybiBTdHJpbmdQaWVjZShidWZmZXIsIDAsIDYpOworfQorCisvLyBTdG9yZXMgdGhlIDMyLWJpdCB1bmljb2RlIGNvZGUgcG9pbnQgYXMgaXRzIGhleGFkZWNpbWFsIGRpZ2l0cyBpbiBidWZmZXIKKy8vIGFuZCByZXR1cm5zIGEgU3RyaW5nUGllY2UgdGhhdCBwb2ludHMgdG8gdGhpcyBidWZmZXIuIFRoZSBpbnB1dCBidWZmZXIgbmVlZHMKKy8vIHRvIGJlIGF0IGxlYXN0IDEyIGJ5dGVzIGxvbmcuCitTdHJpbmdQaWVjZSBUb1N1cnJvZ2F0ZUhleCh1aW50MzIgY3AsIGNoYXIqIGJ1ZmZlcikgeworICB1aW50MTYgbG93ID0gVG9Mb3dTdXJyb2dhdGUoY3ApOworICB1aW50MTYgaGlnaCA9IFRvSGlnaFN1cnJvZ2F0ZShjcCk7CisKKyAgYnVmZmVyWzExXSA9IGtIZXhbbG93ICYgMHgwZl07CisgIGxvdyA+Pj0gNDsKKyAgYnVmZmVyWzEwXSA9IGtIZXhbbG93ICYgMHgwZl07CisgIGxvdyA+Pj0gNDsKKyAgYnVmZmVyWzldID0ga0hleFtsb3cgJiAweDBmXTsKKyAgbG93ID4+PSA0OworICBidWZmZXJbOF0gPSBrSGV4W2xvdyAmIDB4MGZdOworCisgIGJ1ZmZlcls1XSA9IGtIZXhbaGlnaCAmIDB4MGZdOworICBoaWdoID4+PSA0OworICBidWZmZXJbNF0gPSBrSGV4W2hpZ2ggJiAweDBmXTsKKyAgaGlnaCA+Pj0gNDsKKyAgYnVmZmVyWzNdID0ga0hleFtoaWdoICYgMHgwZl07CisgIGhpZ2ggPj49IDQ7CisgIGJ1ZmZlclsyXSA9IGtIZXhbaGlnaCAmIDB4MGZdOworCisgIHJldHVybiBTdHJpbmdQaWVjZShidWZmZXIsIDEyKTsKK30KKworLy8gSWYgdGhlIGdpdmVuIHVuaWNvZGUgY29kZSBwb2ludCBuZWVkcyBlc2NhcGluZywgdGhlbiByZXR1cm5zIHRoZQorLy8gZXNjYXBlZCBmb3JtLiBUaGUgcmV0dXJuZWQgU3RyaW5nUGllY2UgZWl0aGVyIHBvaW50cyB0byBzdGF0aWNhbGx5CisvLyBwcmUtYWxsb2NhdGVkIGNoYXJbXSBvciB0byB0aGUgZ2l2ZW4gYnVmZmVyLiBUaGUgaW5wdXQgYnVmZmVyIG5lZWRzCisvLyB0byBiZSBhdCBsZWFzdCAxMiBieXRlcyBsb25nLgorLy8KKy8vIElmIHRoZSBnaXZlbiB1bmljb2RlIGNvZGUgcG9pbnQgZG9lcyBub3QgbmVlZCBlc2NhcGluZywgYW4gZW1wdHkKKy8vIFN0cmluZ1BpZWNlIGlzIHJldHVybmVkLgorU3RyaW5nUGllY2UgRXNjYXBlQ29kZVBvaW50KHVpbnQzMiBjcCwgY2hhciogYnVmZmVyKSB7CisgIGlmIChjcCA8IDB4YTApIHJldHVybiBrQ29tbW9uRXNjYXBlc1tjcF07CisgIHN3aXRjaCAoY3ApIHsKKyAgICAvLyBUaGVzZSBhcmUgbm90IHJlcXVpcmVkIGJ5IGpzb24gc3BlYworICAgIC8vIGJ1dCB1c2VkIHRvIHByZXZlbnQgc2VjdXJpdHkgYnVncyBpbiBqYXZhc2NyaXB0LgorICAgIGNhc2UgMHhmZWZmOiAgLy8gWmVybyB3aWR0aCBuby1icmVhayBzcGFjZQorICAgIGNhc2UgMHhmZmY5OiAgLy8gSW50ZXJsaW5lYXIgYW5ub3RhdGlvbiBhbmNob3IKKyAgICBjYXNlIDB4ZmZmYTogIC8vIEludGVybGluZWFyIGFubm90YXRpb24gc2VwYXJhdG9yCisgICAgY2FzZSAweGZmZmI6ICAvLyBJbnRlcmxpbmVhciBhbm5vdGF0aW9uIHRlcm1pbmF0b3IKKworICAgIGNhc2UgMHgwMGFkOiAgLy8gU29mdC1oeXBoZW4KKyAgICBjYXNlIDB4MDZkZDogIC8vIEFyYWJpYyBlbmQgb2YgYXlhaAorICAgIGNhc2UgMHgwNzBmOiAgLy8gU3lyaWFjIGFiYnJldmlhdGlvbiBtYXJrCisgICAgY2FzZSAweDE3YjQ6ICAvLyBLaG1lciB2b3dlbCBpbmhlcmVudCBBcQorICAgIGNhc2UgMHgxN2I1OiAgLy8gS2htZXIgdm93ZWwgaW5oZXJlbnQgQWEKKyAgICAgIHJldHVybiBUb0hleChjcCwgYnVmZmVyKTsKKworICAgIGRlZmF1bHQ6CisgICAgICBpZiAoKGNwID49IDB4MDYwMCAmJiBjcCA8PSAweDA2MDMpIHx8ICAvLyBBcmFiaWMgc2lnbnMKKyAgICAgICAgICAoY3AgPj0gMHgyMDBiICYmIGNwIDw9IDB4MjAwZikgfHwgIC8vIFplcm8gd2lkdGggZXRjLgorICAgICAgICAgIChjcCA+PSAweDIwMjggJiYgY3AgPD0gMHgyMDJlKSB8fCAgLy8gU2VwYXJhdG9ycyBldGMuCisgICAgICAgICAgKGNwID49IDB4MjA2MCAmJiBjcCA8PSAweDIwNjQpIHx8ICAvLyBJbnZpc2libGUgZXRjLgorICAgICAgICAgIChjcCA+PSAweDIwNmEgJiYgY3AgPD0gMHgyMDZmKSkgeyAgLy8gU2hhcGluZyBldGMuCisgICAgICAgIHJldHVybiBUb0hleChjcCwgYnVmZmVyKTsKKyAgICAgIH0KKworICAgICAgaWYgKGNwID09IDB4MDAwZTAwMDEgfHwgICAgICAgICAgICAgICAgICAgICAgICAvLyBMYW5ndWFnZSB0YWcKKyAgICAgICAgICAoY3AgPj0gMHgwMDAxZDE3MyAmJiBjcCA8PSAweDAwMDFkMTdhKSB8fCAgLy8gTXVzaWMgZm9ybWF0dGluZworICAgICAgICAgIChjcCA+PSAweDAwMGUwMDIwICYmIGNwIDw9IDB4MDAwZTAwN2YpKSB7ICAvLyBUQUcgc3ltYm9scworICAgICAgICByZXR1cm4gVG9TdXJyb2dhdGVIZXgoY3AsIGJ1ZmZlcik7CisgICAgICB9CisgIH0KKyAgcmV0dXJuIFN0cmluZ1BpZWNlKCk7Cit9CisKKy8vIFRyaWVzIHRvIGVzY2FwZSB0aGUgZ2l2ZW4gY29kZSBwb2ludCBmaXJzdC4gSWYgdGhlIGdpdmVuIGNvZGUgcG9pbnQKKy8vIGRvZXMgbm90IG5lZWQgdG8gYmUgZXNjYXBlZCwgYnV0IGZvcmNlX291dHB1dCBpcyB0cnVlLCB0aGVuIHJlbmRlcgorLy8gdGhlIGdpdmVuIG11bHRpLWJ5dGUgY29kZSBwb2ludCBpbiBVVEY4IGluIHRoZSBidWZmZXIgYW5kIHJldHVybnMgaXQuCitTdHJpbmdQaWVjZSBFc2NhcGVDb2RlUG9pbnQodWludDMyIGNwLCBjaGFyKiBidWZmZXIsIGJvb2wgZm9yY2Vfb3V0cHV0KSB7CisgIFN0cmluZ1BpZWNlIHNwID0gRXNjYXBlQ29kZVBvaW50KGNwLCBidWZmZXIpOworICBpZiAoZm9yY2Vfb3V0cHV0ICYmIHNwLmVtcHR5KCkpIHsKKyAgICBidWZmZXJbNV0gPSAoY3AgJiAweDNmKSB8IDB4ODA7CisgICAgY3AgPj49IDY7CisgICAgaWYgKGNwIDw9IDB4MWYpIHsKKyAgICAgIGJ1ZmZlcls0XSA9IGNwIHwgMHhjMDsKKyAgICAgIHNwLnNldChidWZmZXIgKyA0LCAyKTsKKyAgICAgIHJldHVybiBzcDsKKyAgICB9CisgICAgYnVmZmVyWzRdID0gKGNwICYgMHgzZikgfCAweDgwOworICAgIGNwID4+PSA2OworICAgIGlmIChjcCA8PSAweDBmKSB7CisgICAgICBidWZmZXJbM10gPSBjcCB8IDB4ZTA7CisgICAgICBzcC5zZXQoYnVmZmVyICsgMywgMyk7CisgICAgICByZXR1cm4gc3A7CisgICAgfQorICAgIGJ1ZmZlclszXSA9IChjcCAmIDB4M2YpIHwgMHg4MDsKKyAgICBidWZmZXJbMl0gPSAoKGNwID4+IDYpICYgMHgwNykgfCAweGYwOworICAgIHNwLnNldChidWZmZXIgKyAyLCA0KTsKKyAgfQorICByZXR1cm4gc3A7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCit2b2lkIEpzb25Fc2NhcGluZzo6RXNjYXBlKHN0cmluZ3M6OkJ5dGVTb3VyY2UqIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmdzOjpCeXRlU2luayogb3V0cHV0KSB7CisgIGNoYXIgYnVmZmVyWzEyXSA9ICJcXHVkZWFkXFx1YmVlIjsKKyAgdWludDMyIGNwID0gMDsgICAgIC8vIEN1cnJlbnQgdW5pY29kZSBjb2RlIHBvaW50LgorICBpbnQgbnVtX2xlZnQgPSAwOyAgLy8gTnVtIG9mIGNoYXJzIHRvIHJlYWQgdG8gY29tcGxldGUgdGhlIGNvZGUgcG9pbnQuCisgIHdoaWxlIChpbnB1dC0+QXZhaWxhYmxlKCkgPiAwKSB7CisgICAgU3RyaW5nUGllY2Ugc3RyID0gaW5wdXQtPlBlZWsoKTsKKyAgICBTdHJpbmdQaWVjZSBlc2NhcGVkOworICAgIGludCBpID0gMDsKKyAgICBpbnQgbnVtX3JlYWQ7CisgICAgYm9vbCBvazsKKyAgICBib29sIGNwX3dhc19zcGxpdCA9IG51bV9sZWZ0ID4gMDsKKyAgICAvLyBMb29wIHVudGlsIHdlIGVuY291bnRlciBlaXRoZXIKKyAgICAvLyAgIGkpIGEgY29kZSBwb2ludCB0aGF0IG5lZWRzIHRvIGJlIGVzY2FwZWQ7IG9yCisgICAgLy8gIGlpKSBhIHNwbGl0IGNvZGUgcG9pbnQgaXMgY29tcGxldGVseSByZWFkOyBvcgorICAgIC8vIGlpaSkgYSBjaGFyYWN0ZXIgdGhhdCBpcyBub3QgYSB2YWxpZCB1dGY4OyBvcgorICAgIC8vICBpdikgZW5kIG9mIHRoZSBTdHJpbmdQaWVjZSBzdHIgaXMgcmVhY2hlZC4KKyAgICBkbyB7CisgICAgICBvayA9IFJlYWRDb2RlUG9pbnQoc3RyLCBpLCAmY3AsICZudW1fbGVmdCwgJm51bV9yZWFkKTsKKyAgICAgIGlmIChudW1fbGVmdCA+IDAgfHwgIW9rKSBicmVhazsgIC8vIGNhc2UgaWlpIG9yIGl2CisgICAgICBlc2NhcGVkID0gRXNjYXBlQ29kZVBvaW50KGNwLCBidWZmZXIsIGNwX3dhc19zcGxpdCk7CisgICAgICBpZiAoIWVzY2FwZWQuZW1wdHkoKSkgYnJlYWs7ICAgICAvLyBjYXNlIGkgb3IgaWkKKyAgICAgIGkgKz0gbnVtX3JlYWQ7CisgICAgICBudW1fcmVhZCA9IDA7CisgICAgfSB3aGlsZSAoaSA8IHN0ci5sZW5ndGgoKSk7ICAgICAgICAvLyBjYXNlIGl2CisgICAgLy8gRmlyc3QgY29weSB0aGUgdW4tZXNjYXBlZCBwcmVmaXgsIGlmIGFueSwgdG8gdGhlIG91dHB1dCBCeXRlU2luay4KKyAgICBpZiAoaSA+IDApIGlucHV0LT5Db3B5VG8ob3V0cHV0LCBpKTsKKyAgICBpZiAobnVtX3JlYWQgPiAwKSBpbnB1dC0+U2tpcChudW1fcmVhZCk7CisgICAgaWYgKCFvaykgeworICAgICAgLy8gQ2FzZSBpaWk6IFJlcG9ydCBlcnJvci4KKyAgICAgIC8vIFRPRE8od3Bvb24pOiBBZGQgZXJyb3IgcmVwb3J0aW5nLgorICAgICAgbnVtX2xlZnQgPSAwOworICAgIH0gZWxzZSBpZiAobnVtX2xlZnQgPT0gMCAmJiAhZXNjYXBlZC5lbXB0eSgpKSB7CisgICAgICAvLyBDYXNlIGkgb3IgaWk6IEFwcGVuZCB0aGUgZXNjYXBlZCBjb2RlIHBvaW50IHRvIHRoZSBvdXRwdXQgQnl0ZVNpbmsuCisgICAgICBvdXRwdXQtPkFwcGVuZChlc2NhcGVkLmRhdGEoKSwgZXNjYXBlZC5zaXplKCkpOworICAgIH0KKyAgfQorICBpZiAobnVtX2xlZnQgPiAwKSB7CisgICAgLy8gVHJlYXQgYXMgY2FzZSBpaWk6IHJlcG9ydCBlcnJvci4KKyAgICAvLyBUT0RPKHdwb29uKTogQWRkIGVycm9yIHJlcG9ydGluZy4KKyAgfQorfQorCit9ICAvLyBuYW1lc3BhY2UgY29udmVydGVyCit9ICAvLyBuYW1lc3BhY2UgdXRpbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvanNvbl9lc2NhcGluZy5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL2pzb25fZXNjYXBpbmcuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lM2UzMjlmCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL2pzb25fZXNjYXBpbmcuaApAQCAtMCwwICsxLDkxIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2lmbmRlZiBORVRfUFJPVE8yX1VUSUxfQ09OVkVSVEVSX1NUUklOR1NfSlNPTl9FU0NBUElOR19IXworI2RlZmluZSBORVRfUFJPVE8yX1VUSUxfQ09OVkVSVEVSX1NUUklOR1NfSlNPTl9FU0NBUElOR19IXworCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9ieXRlc3RyZWFtLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSB1dGlsIHsKK25hbWVzcGFjZSBjb252ZXJ0ZXIgeworCitjbGFzcyBKc29uRXNjYXBpbmcgeworIHB1YmxpYzoKKyAgLy8gVGhlIG1pbmltdW0gdmFsdWUgb2YgYSB1bmljb2RlIGhpZ2gtc3Vycm9nYXRlIGNvZGUgdW5pdCBpbiB0aGUgdXRmLTE2CisgIC8vIGVuY29kaW5nLiBBIGhpZ2gtc3Vycm9nYXRlIGlzIGFsc28ga25vd24gYXMgYSBsZWFkaW5nLXN1cnJvZ2F0ZS4KKyAgLy8gU2VlIGh0dHA6Ly93d3cudW5pY29kZS5vcmcvZ2xvc3NhcnkvI2hpZ2hfc3Vycm9nYXRlX2NvZGVfdW5pdAorICBzdGF0aWMgY29uc3QgdWludDE2IGtNaW5IaWdoU3Vycm9nYXRlID0gMHhkODAwOworCisgIC8vIFRoZSBtYXhpbXVtIHZhbHVlIG9mIGEgdW5pY2lkZSBoaWdoLXN1cnJvZ2F0ZSBjb2RlIHVuaXQgaW4gdGhlIHV0Zi0xNgorICAvLyBlbmNvZGluZy4gQSBoaWdoLXN1cnJvZ2F0ZSBpcyBhbHNvIGtub3duIGFzIGEgbGVhZGluZy1zdXJyb2dhdGUuCisgIC8vIFNlZSBodHRwOi8vd3d3LnVuaWNvZGUub3JnL2dsb3NzYXJ5LyNoaWdoX3N1cnJvZ2F0ZV9jb2RlX3VuaXQKKyAgc3RhdGljIGNvbnN0IHVpbnQxNiBrTWF4SGlnaFN1cnJvZ2F0ZSA9IDB4ZGJmZjsKKworICAvLyBUaGUgbWluaW11bSB2YWx1ZSBvZiBhIHVuaWNvZGUgbG93LXN1cnJvZ2F0ZSBjb2RlIHVuaXQgaW4gdGhlIHV0Zi0xNgorICAvLyBlbmNvZGluZy4gQSBsb3ctc3Vycm9nYXRlIGlzIGFsc28ga25vd24gYXMgYSB0cmFpbGluZy1zdXJyb2dhdGUuCisgIC8vIFNlZSBodHRwOi8vd3d3LnVuaWNvZGUub3JnL2dsb3NzYXJ5LyNsb3dfc3Vycm9nYXRlX2NvZGVfdW5pdAorICBzdGF0aWMgY29uc3QgdWludDE2IGtNaW5Mb3dTdXJyb2dhdGUgPSAweGRjMDA7CisKKyAgLy8gVGhlIG1heGltdW0gdmFsdWUgb2YgYSB1bmljb2RlIGxvdy1zdXJyb2dhdGUgY29kZSB1bml0IGluIHRoZSB1dGYtMTYKKyAgLy8gZW5jb2RpbmcuIEEgbG93LXN1cnJvZ2F0ZSBpcyBhbHNvIGtub3duIGFzIGEgdHJhaWxpbmcgc3Vycm9nYXRlLgorICAvLyBTZWUgaHR0cDovL3d3dy51bmljb2RlLm9yZy9nbG9zc2FyeS8jbG93X3N1cnJvZ2F0ZV9jb2RlX3VuaXQKKyAgc3RhdGljIGNvbnN0IHVpbnQxNiBrTWF4TG93U3Vycm9nYXRlID0gMHhkZmZmOworCisgIC8vIFRoZSBtaW5pbXVtIHZhbHVlIG9mIGEgdW5pY29kZSBzdXBwbGVtZW50YXJ5IGNvZGUgcG9pbnQuCisgIC8vIFNlZSBodHRwOi8vd3d3LnVuaWNvZGUub3JnL2dsb3NzYXJ5LyNzdXBwbGVtZW50YXJ5X2NvZGVfcG9pbnQKKyAgc3RhdGljIGNvbnN0IHVpbnQzMiBrTWluU3VwcGxlbWVudGFyeUNvZGVQb2ludCA9IDB4MDEwMDAwOworCisgIC8vIFRoZSBtaW5pbXVtIHZhbHVlIG9mIGEgdW5pY29kZSBjb2RlIHBvaW50LgorICAvLyBTZWUgaHR0cDovL3d3dy51bmljb2RlLm9yZy9nbG9zc2FyeS8jY29kZV9wb2ludAorICBzdGF0aWMgY29uc3QgdWludDMyIGtNaW5Db2RlUG9pbnQgPSAweDAwMDAwMDsKKworICAvLyBUaGUgbWF4aW11bSB2YWx1ZSBvZiBhIHVuaWNvZGUgY29kZSBwb2ludC4KKyAgLy8gU2VlIGh0dHA6Ly93d3cudW5pY29kZS5vcmcvZ2xvc3NhcnkvI2NvZGVfcG9pbnQKKyAgc3RhdGljIGNvbnN0IHVpbnQzMiBrTWF4Q29kZVBvaW50ID0gMHgxMGZmZmY7CisKKyAgSnNvbkVzY2FwaW5nKCkge30KKyAgdmlydHVhbCB+SnNvbkVzY2FwaW5nKCkge30KKworICAvLyBFc2NhcGUgdGhlIGdpdmVuIEJ5dGVTb3VyY2UgdG8gdGhlIGdpdmVuIEJ5dGVTaW5rLgorICBzdGF0aWMgdm9pZCBFc2NhcGUoc3RyaW5nczo6Qnl0ZVNvdXJjZSogaW5wdXQsIHN0cmluZ3M6OkJ5dGVTaW5rKiBvdXRwdXQpOworCisgcHJpdmF0ZToKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKEpzb25Fc2NhcGluZyk7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgY29udmVydGVyCit9ICAvLyBuYW1lc3BhY2UgdXRpbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKKyNlbmRpZiAgLy8gTkVUX1BST1RPMl9VVElMX0NPTlZFUlRFUl9TVFJJTkdTX0pTT05fRVNDQVBJTkdfSF8KK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9qc29uX29iamVjdHdyaXRlci5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9qc29uX29iamVjdHdyaXRlci5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NGQyYWI3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL2pzb25fb2JqZWN0d3JpdGVyLmNjCkBAIC0wLDAgKzEsMTgxIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL2pzb25fb2JqZWN0d3JpdGVyLmg+CisKKyNpbmNsdWRlIDxtYXRoLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY2FzdHMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbG9nZ2luZy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC91dGlsaXR5Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvanNvbl9lc2NhcGluZy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL21hdGhsaW1pdHMuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIHV0aWwgeworbmFtZXNwYWNlIGNvbnZlcnRlciB7CisKK3VzaW5nIHN0cmluZ3M6OkFycmF5Qnl0ZVNvdXJjZTsKKworSnNvbk9iamVjdFdyaXRlcjo6fkpzb25PYmplY3RXcml0ZXIoKSB7CisgIGlmICghZWxlbWVudF8tPmlzX3Jvb3QoKSkgeworICAgIEdPT0dMRV9MT0coV0FSTklORykgPDwgIkpzb25PYmplY3RXcml0ZXIgd2FzIG5vdCBmdWxseSBjbG9zZWQuIjsKKyAgfQorfQorCitKc29uT2JqZWN0V3JpdGVyKiBKc29uT2JqZWN0V3JpdGVyOjpTdGFydE9iamVjdChTdHJpbmdQaWVjZSBuYW1lKSB7CisgIFdyaXRlUHJlZml4KG5hbWUpOworICBXcml0ZUNoYXIoJ3snKTsKKyAgUHVzaCgpOworICByZXR1cm4gdGhpczsKK30KKworSnNvbk9iamVjdFdyaXRlciogSnNvbk9iamVjdFdyaXRlcjo6RW5kT2JqZWN0KCkgeworICBQb3AoKTsKKyAgV3JpdGVDaGFyKCd9Jyk7CisgIGlmIChlbGVtZW50KCktPmlzX3Jvb3QoKSkgTmV3TGluZSgpOworICByZXR1cm4gdGhpczsKK30KKworSnNvbk9iamVjdFdyaXRlciogSnNvbk9iamVjdFdyaXRlcjo6U3RhcnRMaXN0KFN0cmluZ1BpZWNlIG5hbWUpIHsKKyAgV3JpdGVQcmVmaXgobmFtZSk7CisgIFdyaXRlQ2hhcignWycpOworICBQdXNoKCk7CisgIHJldHVybiB0aGlzOworfQorCitKc29uT2JqZWN0V3JpdGVyKiBKc29uT2JqZWN0V3JpdGVyOjpFbmRMaXN0KCkgeworICBQb3AoKTsKKyAgV3JpdGVDaGFyKCddJyk7CisgIGlmIChlbGVtZW50KCktPmlzX3Jvb3QoKSkgTmV3TGluZSgpOworICByZXR1cm4gdGhpczsKK30KKworSnNvbk9iamVjdFdyaXRlciogSnNvbk9iamVjdFdyaXRlcjo6UmVuZGVyQm9vbChTdHJpbmdQaWVjZSBuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIHZhbHVlKSB7CisgIHJldHVybiBSZW5kZXJTaW1wbGUobmFtZSwgdmFsdWUgPyAidHJ1ZSIgOiAiZmFsc2UiKTsKK30KKworSnNvbk9iamVjdFdyaXRlciogSnNvbk9iamVjdFdyaXRlcjo6UmVuZGVySW50MzIoU3RyaW5nUGllY2UgbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyIHZhbHVlKSB7CisgIHJldHVybiBSZW5kZXJTaW1wbGUobmFtZSwgU2ltcGxlSXRvYSh2YWx1ZSkpOworfQorCitKc29uT2JqZWN0V3JpdGVyKiBKc29uT2JqZWN0V3JpdGVyOjpSZW5kZXJVaW50MzIoU3RyaW5nUGllY2UgbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzIgdmFsdWUpIHsKKyAgcmV0dXJuIFJlbmRlclNpbXBsZShuYW1lLCBTaW1wbGVJdG9hKHZhbHVlKSk7Cit9CisKK0pzb25PYmplY3RXcml0ZXIqIEpzb25PYmplY3RXcml0ZXI6OlJlbmRlckludDY0KFN0cmluZ1BpZWNlIG5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQ2NCB2YWx1ZSkgeworICBXcml0ZVByZWZpeChuYW1lKTsKKyAgV3JpdGVDaGFyKCciJyk7CisgIHN0cmVhbV8tPldyaXRlU3RyaW5nKFNpbXBsZUl0b2EodmFsdWUpKTsKKyAgV3JpdGVDaGFyKCciJyk7CisgIHJldHVybiB0aGlzOworfQorCitKc29uT2JqZWN0V3JpdGVyKiBKc29uT2JqZWN0V3JpdGVyOjpSZW5kZXJVaW50NjQoU3RyaW5nUGllY2UgbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50NjQgdmFsdWUpIHsKKyAgV3JpdGVQcmVmaXgobmFtZSk7CisgIFdyaXRlQ2hhcignIicpOworICBzdHJlYW1fLT5Xcml0ZVN0cmluZyhTaW1wbGVJdG9hKHZhbHVlKSk7CisgIFdyaXRlQ2hhcignIicpOworICByZXR1cm4gdGhpczsKK30KKworSnNvbk9iamVjdFdyaXRlciogSnNvbk9iamVjdFdyaXRlcjo6UmVuZGVyRG91YmxlKFN0cmluZ1BpZWNlIG5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG91YmxlIHZhbHVlKSB7CisgIGlmIChNYXRoTGltaXRzPGRvdWJsZT46OklzRmluaXRlKHZhbHVlKSkgeworICAgIHJldHVybiBSZW5kZXJTaW1wbGUobmFtZSwgU2ltcGxlRHRvYSh2YWx1ZSkpOworICB9CisKKyAgLy8gUmVuZGVyIHF1b3RlZCB3aXRoIE5hTi9JbmZpbml0eS1hd2FyZSBEb3VibGVBc1N0cmluZy4KKyAgcmV0dXJuIFJlbmRlclN0cmluZyhuYW1lLCBEb3VibGVBc1N0cmluZyh2YWx1ZSkpOworfQorCitKc29uT2JqZWN0V3JpdGVyKiBKc29uT2JqZWN0V3JpdGVyOjpSZW5kZXJGbG9hdChTdHJpbmdQaWVjZSBuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmxvYXQgdmFsdWUpIHsKKyAgaWYgKE1hdGhMaW1pdHM8ZmxvYXQ+OjpJc0Zpbml0ZSh2YWx1ZSkpIHsKKyAgICByZXR1cm4gUmVuZGVyU2ltcGxlKG5hbWUsIFNpbXBsZUZ0b2EodmFsdWUpKTsKKyAgfQorCisgIC8vIFJlbmRlciBxdW90ZWQgd2l0aCBOYU4vSW5maW5pdHktYXdhcmUgRmxvYXRBc1N0cmluZy4KKyAgcmV0dXJuIFJlbmRlclN0cmluZyhuYW1lLCBGbG9hdEFzU3RyaW5nKHZhbHVlKSk7Cit9CisKK0pzb25PYmplY3RXcml0ZXIqIEpzb25PYmplY3RXcml0ZXI6OlJlbmRlclN0cmluZyhTdHJpbmdQaWVjZSBuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1BpZWNlIHZhbHVlKSB7CisgIFdyaXRlUHJlZml4KG5hbWUpOworICBXcml0ZUNoYXIoJyInKTsKKyAgQXJyYXlCeXRlU291cmNlIHNvdXJjZSh2YWx1ZSk7CisgIEpzb25Fc2NhcGluZzo6RXNjYXBlKCZzb3VyY2UsICZzaW5rXyk7CisgIFdyaXRlQ2hhcignIicpOworICByZXR1cm4gdGhpczsKK30KKworSnNvbk9iamVjdFdyaXRlciogSnNvbk9iamVjdFdyaXRlcjo6UmVuZGVyQnl0ZXMoU3RyaW5nUGllY2UgbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1BpZWNlIHZhbHVlKSB7CisgIFdyaXRlUHJlZml4KG5hbWUpOworICBzdHJpbmcgYmFzZTY0OworICBCYXNlNjRFc2NhcGUodmFsdWUsICZiYXNlNjQpOworICBXcml0ZUNoYXIoJyInKTsKKyAgLy8gVE9ETyh3cG9vbik6IENvbnNpZGVyIGEgQnl0ZVNpbmsgc29sdXRpb24gdGhhdCB3cml0ZXMgdGhlIGJhc2U2NCBieXRlcworICAvLyAgICAgICAgICAgICAgZGlyZWN0bHkgdG8gdGhlIHN0cmVhbSwgcmF0aGVyIHRoYW4gZmlyc3QgcHV0dGluZyB0aGVtCisgIC8vICAgICAgICAgICAgICBpbnRvIGEgc3RyaW5nIGFuZCB0aGVuIHdyaXRpbmcgdGhlbSB0byB0aGUgc3RyZWFtLgorICBzdHJlYW1fLT5Xcml0ZVJhdyhiYXNlNjQuZGF0YSgpLCBiYXNlNjQuc2l6ZSgpKTsKKyAgV3JpdGVDaGFyKCciJyk7CisgIHJldHVybiB0aGlzOworfQorCitKc29uT2JqZWN0V3JpdGVyKiBKc29uT2JqZWN0V3JpdGVyOjpSZW5kZXJOdWxsKFN0cmluZ1BpZWNlIG5hbWUpIHsKKyAgcmV0dXJuIFJlbmRlclNpbXBsZShuYW1lLCAibnVsbCIpOworfQorCit2b2lkIEpzb25PYmplY3RXcml0ZXI6OldyaXRlUHJlZml4KFN0cmluZ1BpZWNlIG5hbWUpIHsKKyAgYm9vbCBub3RfZmlyc3QgPSAhZWxlbWVudCgpLT5pc19maXJzdCgpOworICBpZiAobm90X2ZpcnN0KSBXcml0ZUNoYXIoJywnKTsKKyAgaWYgKG5vdF9maXJzdCB8fCAhZWxlbWVudCgpLT5pc19yb290KCkpIE5ld0xpbmUoKTsKKyAgaWYgKCFuYW1lLmVtcHR5KCkpIHsKKyAgICBXcml0ZUNoYXIoJyInKTsKKyAgICBBcnJheUJ5dGVTb3VyY2Ugc291cmNlKG5hbWUpOworICAgIEpzb25Fc2NhcGluZzo6RXNjYXBlKCZzb3VyY2UsICZzaW5rXyk7CisgICAgc3RyZWFtXy0+V3JpdGVTdHJpbmcoIlwiOiIpOworICAgIGlmICghaW5kZW50X3N0cmluZ18uZW1wdHkoKSkgV3JpdGVDaGFyKCcgJyk7CisgIH0KK30KKworfSAgLy8gbmFtZXNwYWNlIGNvbnZlcnRlcgorfSAgLy8gbmFtZXNwYWNlIHV0aWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL2pzb25fb2JqZWN0d3JpdGVyLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvanNvbl9vYmplY3R3cml0ZXIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NjFhMGExCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL2pzb25fb2JqZWN0d3JpdGVyLmgKQEAgLTAsMCArMSwyMDYgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9VVElMX0NPTlZFUlRFUl9KU09OX09CSkVDVFdSSVRFUl9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1VUSUxfQ09OVkVSVEVSX0pTT05fT0JKRUNUV1JJVEVSX0hfXworCisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorI2luY2x1ZGUgPHN0cmluZz4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9zdHJ1Y3R1cmVkX29iamVjdHdyaXRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9ieXRlc3RyZWFtLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSB1dGlsIHsKK25hbWVzcGFjZSBjb252ZXJ0ZXIgeworCisvLyBBbiBPYmplY3RXcml0ZXIgaW1wbGVtZW50YXRpb24gdGhhdCBvdXRwdXRzIEpTT04uIFRoaXMgT2JqZWN0V3JpdGVyCisvLyBzdXBwb3J0cyB3cml0aW5nIGEgY29tcGFjdCBmb3JtIG9yIGEgcHJldHR5IHByaW50ZWQgZm9ybS4KKy8vCisvLyBTYW1wbGUgdXNhZ2U6CisvLyAgIHN0cmluZyBvdXRwdXQ7CisvLyAgIFN0cmluZ091dHB1dFN0cmVhbSogc3RyX3N0cmVhbSA9IG5ldyBTdHJpbmdPdXRwdXRTdHJlYW0oJm91dHB1dCk7CisvLyAgIENvZGVkT3V0cHV0U3RyZWFtKiBvdXRfc3RyZWFtID0gbmV3IENvZGVkT3V0cHV0U3RyZWFtKHN0cl9zdHJlYW0pOworLy8gICBKc29uT2JqZWN0V3JpdGVyKiBvdyA9IG5ldyBKc29uT2JqZWN0V3JpdGVyKCIgICIsIG91dF9zdHJlYW0pOworLy8gICBvdy0+U3RhcnRPYmplY3QoIiIpCisvLyAgICAgICAtPlJlbmRlclN0cmluZygibmFtZSIsICJ2YWx1ZSIpCisvLyAgICAgICAtPlJlbmRlclN0cmluZygiZW1wdHlzdHJpbmciLCBzdHJpbmcoKSkKKy8vICAgICAgIC0+U3RhcnRPYmplY3QoIm5lc3RlZCIpCisvLyAgICAgICAgIC0+UmVuZGVySW50NjQoImxpZ2h0IiwgMjk5NzkyNDU4KTsKKy8vICAgICAgICAgLT5SZW5kZXJEb3VibGUoInBpIiwgMy4xNDE1OTI2NTM1ODk3OTMpOworLy8gICAgICAgLT5FbmRPYmplY3QoKQorLy8gICAgICAgLT5TdGFydExpc3QoImVtcHR5IikKKy8vICAgICAgIC0+RW5kTGlzdCgpCisvLyAgICAgLT5FbmRPYmplY3QoKTsKKy8vCisvLyBBbmQgdGhlbiB0aGUgb3V0cHV0IHN0cmluZyB3b3VsZCBiZWNvbWU6CisvLyB7CisvLyAgICJuYW1lIjogInZhbHVlIiwKKy8vICAgImVtcHR5c3RyaW5nIjogIiIsCisvLyAgICJuZXN0ZWQiOiB7CisvLyAgICAgImxpZ2h0IjogIjI5OTc5MjQ1OCIsCisvLyAgICAgInBpIjogMy4xNDE1OTI2NTM1ODk3OTMKKy8vICAgfSwKKy8vICAgImVtcHR5IjogW10KKy8vIH0KKy8vCisvLyBKc29uT2JqZWN0V3JpdGVyIGRvZXMgbm90IHZhbGlkYXRlIGlmIGNhbGxzIGFjdHVhbGx5IHJlc3VsdCBpbiB2YWxpZCBKU09OLgorLy8gRm9yIGV4YW1wbGUsIHBhc3NpbmcgYW4gZW1wdHkgbmFtZSB3aGVuIG9uZSB3b3VsZCBiZSByZXF1aXJlZCB3b24ndCByZXN1bHQKKy8vIGluIGFuIGVycm9yLCBqdXN0IGFuIGludmFsaWQgb3V0cHV0LgorLy8KKy8vIE5vdGUgdGhhdCBhbGwgaW50NjQgYW5kIHVpbnQ2NCBhcmUgcmVuZGVyZWQgYXMgc3RyaW5ncyBpbnN0ZWFkIG9mIG51bWJlcnMuCisvLyBUaGlzIGlzIGJlY2F1c2UgSmF2YVNjcmlwdCBwYXJzZXMgbnVtYmVycyBhcyA2NC1iaXQgZmxvYXQgdGh1cyBpbnQ2NCBhbmQKKy8vIHVpbnQ2NCB3b3VsZCBsb3NlIHByZWNpc2lvbiBpZiByZW5kZXJlZCBhcyBudW1iZXJzLgorLy8KKy8vIEpzb25PYmplY3RXcml0ZXIgaXMgdGhyZWFkLXVuc2FmZS4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBKc29uT2JqZWN0V3JpdGVyIDogcHVibGljIFN0cnVjdHVyZWRPYmplY3RXcml0ZXIgeworIHB1YmxpYzoKKyAgSnNvbk9iamVjdFdyaXRlcihTdHJpbmdQaWVjZSBpbmRlbnRfc3RyaW5nLAorICAgICAgICAgICAgICAgICAgIGdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0KQorICAgICAgOiBlbGVtZW50XyhuZXcgRWxlbWVudChOVUxMKSksCisgICAgICAgIHN0cmVhbV8ob3V0KSwgc2lua18ob3V0KSwKKyAgICAgICAgaW5kZW50X3N0cmluZ18oaW5kZW50X3N0cmluZy5Ub1N0cmluZygpKSB7CisgIH0KKyAgdmlydHVhbCB+SnNvbk9iamVjdFdyaXRlcigpOworCisgIC8vIE9iamVjdFdyaXRlciBtZXRob2RzLgorICB2aXJ0dWFsIEpzb25PYmplY3RXcml0ZXIqIFN0YXJ0T2JqZWN0KFN0cmluZ1BpZWNlIG5hbWUpOworICB2aXJ0dWFsIEpzb25PYmplY3RXcml0ZXIqIEVuZE9iamVjdCgpOworICB2aXJ0dWFsIEpzb25PYmplY3RXcml0ZXIqIFN0YXJ0TGlzdChTdHJpbmdQaWVjZSBuYW1lKTsKKyAgdmlydHVhbCBKc29uT2JqZWN0V3JpdGVyKiBFbmRMaXN0KCk7CisgIHZpcnR1YWwgSnNvbk9iamVjdFdyaXRlciogUmVuZGVyQm9vbChTdHJpbmdQaWVjZSBuYW1lLCBib29sIHZhbHVlKTsKKyAgdmlydHVhbCBKc29uT2JqZWN0V3JpdGVyKiBSZW5kZXJJbnQzMihTdHJpbmdQaWVjZSBuYW1lLCBpbnQzMiB2YWx1ZSk7CisgIHZpcnR1YWwgSnNvbk9iamVjdFdyaXRlciogUmVuZGVyVWludDMyKFN0cmluZ1BpZWNlIG5hbWUsIHVpbnQzMiB2YWx1ZSk7CisgIHZpcnR1YWwgSnNvbk9iamVjdFdyaXRlciogUmVuZGVySW50NjQoU3RyaW5nUGllY2UgbmFtZSwgaW50NjQgdmFsdWUpOworICB2aXJ0dWFsIEpzb25PYmplY3RXcml0ZXIqIFJlbmRlclVpbnQ2NChTdHJpbmdQaWVjZSBuYW1lLCB1aW50NjQgdmFsdWUpOworICB2aXJ0dWFsIEpzb25PYmplY3RXcml0ZXIqIFJlbmRlckRvdWJsZShTdHJpbmdQaWVjZSBuYW1lLCBkb3VibGUgdmFsdWUpOworICB2aXJ0dWFsIEpzb25PYmplY3RXcml0ZXIqIFJlbmRlckZsb2F0KFN0cmluZ1BpZWNlIG5hbWUsIGZsb2F0IHZhbHVlKTsKKyAgdmlydHVhbCBKc29uT2JqZWN0V3JpdGVyKiBSZW5kZXJTdHJpbmcoU3RyaW5nUGllY2UgbmFtZSwgU3RyaW5nUGllY2UgdmFsdWUpOworICB2aXJ0dWFsIEpzb25PYmplY3RXcml0ZXIqIFJlbmRlckJ5dGVzKFN0cmluZ1BpZWNlIG5hbWUsIFN0cmluZ1BpZWNlIHZhbHVlKTsKKyAgdmlydHVhbCBKc29uT2JqZWN0V3JpdGVyKiBSZW5kZXJOdWxsKFN0cmluZ1BpZWNlIG5hbWUpOworCisgcHJvdGVjdGVkOgorICBjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgRWxlbWVudCA6IHB1YmxpYyBCYXNlRWxlbWVudCB7CisgICBwdWJsaWM6CisgICAgZXhwbGljaXQgRWxlbWVudChFbGVtZW50KiBwYXJlbnQpIDogQmFzZUVsZW1lbnQocGFyZW50KSwgaXNfZmlyc3RfKHRydWUpIHt9CisKKyAgICAvLyBDYWxsZWQgYmVmb3JlIGVhY2ggZmllbGQgb2YgdGhlIEVsZW1lbnQgaXMgdG8gYmUgcHJvY2Vzc2VkLgorICAgIC8vIFJldHVybnMgdHJ1ZSBpZiB0aGlzIGlzIHRoZSBmaXJzdCBjYWxsIChwcm9jZXNzaW5nIHRoZSBmaXJzdCBmaWVsZCkuCisgICAgYm9vbCBpc19maXJzdCgpIHsKKyAgICAgIGlmIChpc19maXJzdF8pIHsKKyAgICAgICAgaXNfZmlyc3RfID0gZmFsc2U7CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgfQorICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgcHJpdmF0ZToKKyAgICBib29sIGlzX2ZpcnN0XzsKKworICAgIEdPT0dMRV9ESVNBTExPV19JTVBMSUNJVF9DT05TVFJVQ1RPUlMoRWxlbWVudCk7CisgIH07CisKKyAgdmlydHVhbCBFbGVtZW50KiBlbGVtZW50KCkgeyByZXR1cm4gZWxlbWVudF8uZ2V0KCk7IH0KKworIHByaXZhdGU6CisgIGNsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBCeXRlU2lua1dyYXBwZXIgOiBwdWJsaWMgc3RyaW5nczo6Qnl0ZVNpbmsgeworICAgcHVibGljOgorICAgIGV4cGxpY2l0IEJ5dGVTaW5rV3JhcHBlcihnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIHN0cmVhbSkKKyAgICAgICAgOiBzdHJlYW1fKHN0cmVhbSkge30KKyAgICB2aXJ0dWFsIH5CeXRlU2lua1dyYXBwZXIoKSB7fQorCisgICAgLy8gQnl0ZVNpbmsgbWV0aG9kcy4KKyAgICB2aXJ0dWFsIHZvaWQgQXBwZW5kKGNvbnN0IGNoYXIqIGJ5dGVzLCBzaXplX3QgbikgeworICAgICAgc3RyZWFtXy0+V3JpdGVSYXcoYnl0ZXMsIG4pOworICAgIH0KKworICAgcHJpdmF0ZToKKyAgICBnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIHN0cmVhbV87CisKKyAgICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoQnl0ZVNpbmtXcmFwcGVyKTsKKyAgfTsKKworICAvLyBSZW5kZXJzIGEgc2ltcGxlIHZhbHVlIGFzIGEgc3RyaW5nLiBCeSBkZWZhdWx0IGFsbCBub24tc3RyaW5nIFJlbmRlcgorICAvLyBtZXRob2RzIGNvbnZlcnQgdGhlaXIgYXJndW1lbnQgdG8gYSBzdHJpbmcgYW5kIGNhbGwgdGhpcyBtZXRob2QuIFRoaXMKKyAgLy8gbWV0aG9kIGNhbiB0aGVuIGJlIHVzZWQgdG8gcmVuZGVyIHRoZSBzaW1wbGUgdmFsdWUgd2l0aG91dCBlc2NhcGluZyBpdC4KKyAgSnNvbk9iamVjdFdyaXRlciogUmVuZGVyU2ltcGxlKFN0cmluZ1BpZWNlIG5hbWUsIGNvbnN0IHN0cmluZyYgdmFsdWUpIHsKKyAgICBXcml0ZVByZWZpeChuYW1lKTsKKyAgICBzdHJlYW1fLT5Xcml0ZVN0cmluZyh2YWx1ZSk7CisgICAgcmV0dXJuIHRoaXM7CisgIH0KKworICAvLyBQdXNoZXMgYSBuZXcgZWxlbWVudCB0byB0aGUgc3RhY2suCisgIHZvaWQgUHVzaCgpIHsgZWxlbWVudF8ucmVzZXQobmV3IEVsZW1lbnQoZWxlbWVudF8ucmVsZWFzZSgpKSk7IH0KKworICAvLyBQb3BzIGFuIGVsZW1lbnQgb2ZmIG9mIHRoZSBzdGFjayBhbmQgZGVsZXRlcyB0aGUgcG9wcGVkIGVsZW1lbnQuCisgIHZvaWQgUG9wKCkgeworICAgIGJvb2wgbmVlZHNfbmV3bGluZSA9ICFlbGVtZW50Xy0+aXNfZmlyc3QoKTsKKyAgICBlbGVtZW50Xy5yZXNldChlbGVtZW50Xy0+cG9wPEVsZW1lbnQ+KCkpOworICAgIGlmIChuZWVkc19uZXdsaW5lKSBOZXdMaW5lKCk7CisgIH0KKworICAvLyBJZiBwcmV0dHkgcHJpbnRpbmcgaXMgZW5hYmxlZCwgdGhpcyB3aWxsIHdyaXRlIGEgbmV3bGluZSB0byB0aGUgb3V0cHV0LAorICAvLyBmb2xsb3dlZCBieSBvcHRpb25hbCBpbmRlbnRhdGlvbi4gT3RoZXJ3aXNlIHRoaXMgbWV0aG9kIGlzIGEgbm9vcC4KKyAgdm9pZCBOZXdMaW5lKCkgeworICAgIGlmICghaW5kZW50X3N0cmluZ18uZW1wdHkoKSkgeworICAgICAgV3JpdGVDaGFyKCdcbicpOworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBlbGVtZW50KCktPmxldmVsKCk7IGkrKykgeworICAgICAgICBzdHJlYW1fLT5Xcml0ZVN0cmluZyhpbmRlbnRfc3RyaW5nXyk7CisgICAgICB9CisgICAgfQorICB9CisKKyAgLy8gV3JpdGVzIGEgcHJlZml4LiBUaGlzIHdpbGwgd3JpdGUgb3V0IGFueSBwcmV0dHkgcHJpbnRpbmcgYW5kCisgIC8vIGNvbW1hcyB0aGF0IGFyZSByZXF1aXJlZCwgZm9sbG93ZWQgYnkgdGhlIG5hbWUgYW5kIGEgJzonIGlmCisgIC8vIHRoZSBuYW1lIGlzIG5vdCBudWxsLgorICB2b2lkIFdyaXRlUHJlZml4KFN0cmluZ1BpZWNlIG5hbWUpOworCisgIC8vIFdyaXRlcyBhbiBpbmRpdmlkdWFsIGNoYXJhY3RlciB0byB0aGUgb3V0cHV0LgorICB2b2lkIFdyaXRlQ2hhcihjb25zdCBjaGFyIGMpIHsgc3RyZWFtXy0+V3JpdGVSYXcoJmMsIHNpemVvZihjKSk7IH0KKworICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPEVsZW1lbnQ+IGVsZW1lbnRfOworICBnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIHN0cmVhbV87CisgIEJ5dGVTaW5rV3JhcHBlciBzaW5rXzsKKyAgY29uc3Qgc3RyaW5nIGluZGVudF9zdHJpbmdfOworCisgIEdPT0dMRV9ESVNBTExPV19JTVBMSUNJVF9DT05TVFJVQ1RPUlMoSnNvbk9iamVjdFdyaXRlcik7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgY29udmVydGVyCit9ICAvLyBuYW1lc3BhY2UgdXRpbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX1VUSUxfQ09OVkVSVEVSX0pTT05fT0JKRUNUV1JJVEVSX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL2pzb25fb2JqZWN0d3JpdGVyX3Rlc3QuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvanNvbl9vYmplY3R3cml0ZXJfdGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ZDgyMDE2Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL2pzb25fb2JqZWN0d3JpdGVyX3Rlc3QuY2MKQEAgLTAsMCArMSwyODkgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvanNvbl9vYmplY3R3cml0ZXIuaD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX2ltcGxfbGl0ZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3V0aWxpdHkuaD4KKyNpbmNsdWRlIDxndGVzdC9ndGVzdC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgdXRpbCB7CituYW1lc3BhY2UgY29udmVydGVyIHsKKwordXNpbmcgZ29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtOwordXNpbmcgZ29vZ2xlOjpwcm90b2J1Zjo6aW86OlN0cmluZ091dHB1dFN0cmVhbTsKKworY2xhc3MgSnNvbk9iamVjdFdyaXRlclRlc3QgOiBwdWJsaWMgOjp0ZXN0aW5nOjpUZXN0IHsKKyBwcm90ZWN0ZWQ6CisgIEpzb25PYmplY3RXcml0ZXJUZXN0KCkKKyAgICAgIDogc3RyX3N0cmVhbV8obmV3IFN0cmluZ091dHB1dFN0cmVhbSgmb3V0cHV0XykpLAorICAgICAgICBvdXRfc3RyZWFtXyhuZXcgQ29kZWRPdXRwdXRTdHJlYW0oc3RyX3N0cmVhbV8pKSwKKyAgICAgICAgb3dfKE5VTEwpIHt9CisKKyAgdmlydHVhbCB+SnNvbk9iamVjdFdyaXRlclRlc3QoKSB7CisgICAgZGVsZXRlIG93XzsKKyAgICBkZWxldGUgb3V0X3N0cmVhbV87CisgICAgZGVsZXRlIHN0cl9zdHJlYW1fOworICB9CisKKyAgc3RyaW5nIG91dHB1dF87CisgIFN0cmluZ091dHB1dFN0cmVhbSogY29uc3Qgc3RyX3N0cmVhbV87CisgIENvZGVkT3V0cHV0U3RyZWFtKiBjb25zdCBvdXRfc3RyZWFtXzsKKyAgT2JqZWN0V3JpdGVyKiBvd187Cit9OworCitURVNUX0YoSnNvbk9iamVjdFdyaXRlclRlc3QsIEVtcHR5Um9vdE9iamVjdCkgeworICBvd18gPSBuZXcgSnNvbk9iamVjdFdyaXRlcigiIiwgb3V0X3N0cmVhbV8pOworICBvd18tPlN0YXJ0T2JqZWN0KCIiKS0+RW5kT2JqZWN0KCk7CisgIEVYUEVDVF9FUSgie30iLCBvdXRwdXRfLnN1YnN0cigwLCBvdXRfc3RyZWFtXy0+Qnl0ZUNvdW50KCkpKTsKK30KKworVEVTVF9GKEpzb25PYmplY3RXcml0ZXJUZXN0LCBFbXB0eU9iamVjdCkgeworICBvd18gPSBuZXcgSnNvbk9iamVjdFdyaXRlcigiIiwgb3V0X3N0cmVhbV8pOworICBvd18tPlN0YXJ0T2JqZWN0KCIiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoInRlc3QiLCAidmFsdWUiKQorICAgICAgLT5TdGFydE9iamVjdCgiZW1wdHkiKQorICAgICAgLT5FbmRPYmplY3QoKQorICAgICAgLT5FbmRPYmplY3QoKTsKKyAgRVhQRUNUX0VRKCJ7XCJ0ZXN0XCI6XCJ2YWx1ZVwiLFwiZW1wdHlcIjp7fX0iLAorICAgICAgICAgICAgb3V0cHV0Xy5zdWJzdHIoMCwgb3V0X3N0cmVhbV8tPkJ5dGVDb3VudCgpKSk7Cit9CisKK1RFU1RfRihKc29uT2JqZWN0V3JpdGVyVGVzdCwgRW1wdHlSb290TGlzdCkgeworICBvd18gPSBuZXcgSnNvbk9iamVjdFdyaXRlcigiIiwgb3V0X3N0cmVhbV8pOworICBvd18tPlN0YXJ0TGlzdCgiIiktPkVuZExpc3QoKTsKKyAgRVhQRUNUX0VRKCJbXSIsIG91dHB1dF8uc3Vic3RyKDAsIG91dF9zdHJlYW1fLT5CeXRlQ291bnQoKSkpOworfQorCitURVNUX0YoSnNvbk9iamVjdFdyaXRlclRlc3QsIEVtcHR5TGlzdCkgeworICBvd18gPSBuZXcgSnNvbk9iamVjdFdyaXRlcigiIiwgb3V0X3N0cmVhbV8pOworICBvd18tPlN0YXJ0T2JqZWN0KCIiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoInRlc3QiLCAidmFsdWUiKQorICAgICAgLT5TdGFydExpc3QoImVtcHR5IikKKyAgICAgIC0+RW5kTGlzdCgpCisgICAgICAtPkVuZE9iamVjdCgpOworICBFWFBFQ1RfRVEoIntcInRlc3RcIjpcInZhbHVlXCIsXCJlbXB0eVwiOltdfSIsCisgICAgICAgICAgICBvdXRwdXRfLnN1YnN0cigwLCBvdXRfc3RyZWFtXy0+Qnl0ZUNvdW50KCkpKTsKK30KKworVEVTVF9GKEpzb25PYmplY3RXcml0ZXJUZXN0LCBPYmplY3RJbk9iamVjdCkgeworICBvd18gPSBuZXcgSnNvbk9iamVjdFdyaXRlcigiIiwgb3V0X3N0cmVhbV8pOworICBvd18tPlN0YXJ0T2JqZWN0KCIiKQorICAgICAgLT5TdGFydE9iamVjdCgibmVzdGVkIikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJmaWVsZCIsICJ2YWx1ZSIpCisgICAgICAtPkVuZE9iamVjdCgpCisgICAgICAtPkVuZE9iamVjdCgpOworICBFWFBFQ1RfRVEoIntcIm5lc3RlZFwiOntcImZpZWxkXCI6XCJ2YWx1ZVwifX0iLAorICAgICAgICAgICAgb3V0cHV0Xy5zdWJzdHIoMCwgb3V0X3N0cmVhbV8tPkJ5dGVDb3VudCgpKSk7Cit9CisKK1RFU1RfRihKc29uT2JqZWN0V3JpdGVyVGVzdCwgTGlzdEluT2JqZWN0KSB7CisgIG93XyA9IG5ldyBKc29uT2JqZWN0V3JpdGVyKCIiLCBvdXRfc3RyZWFtXyk7CisgIG93Xy0+U3RhcnRPYmplY3QoIiIpCisgICAgICAtPlN0YXJ0TGlzdCgibmVzdGVkIikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCIiLCAidmFsdWUiKQorICAgICAgLT5FbmRMaXN0KCkKKyAgICAgIC0+RW5kT2JqZWN0KCk7CisgIEVYUEVDVF9FUSgie1wibmVzdGVkXCI6W1widmFsdWVcIl19IiwKKyAgICAgICAgICAgIG91dHB1dF8uc3Vic3RyKDAsIG91dF9zdHJlYW1fLT5CeXRlQ291bnQoKSkpOworfQorCitURVNUX0YoSnNvbk9iamVjdFdyaXRlclRlc3QsIE9iamVjdEluTGlzdCkgeworICBvd18gPSBuZXcgSnNvbk9iamVjdFdyaXRlcigiIiwgb3V0X3N0cmVhbV8pOworICBvd18tPlN0YXJ0TGlzdCgiIikKKyAgICAgIC0+U3RhcnRPYmplY3QoIiIpCisgICAgICAtPlJlbmRlclN0cmluZygiZmllbGQiLCAidmFsdWUiKQorICAgICAgLT5FbmRPYmplY3QoKQorICAgICAgLT5FbmRMaXN0KCk7CisgIEVYUEVDVF9FUSgiW3tcImZpZWxkXCI6XCJ2YWx1ZVwifV0iLAorICAgICAgICAgICAgb3V0cHV0Xy5zdWJzdHIoMCwgb3V0X3N0cmVhbV8tPkJ5dGVDb3VudCgpKSk7Cit9CisKK1RFU1RfRihKc29uT2JqZWN0V3JpdGVyVGVzdCwgTGlzdEluTGlzdCkgeworICBvd18gPSBuZXcgSnNvbk9iamVjdFdyaXRlcigiIiwgb3V0X3N0cmVhbV8pOworICBvd18tPlN0YXJ0TGlzdCgiIikKKyAgICAgIC0+U3RhcnRMaXN0KCIiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoIiIsICJ2YWx1ZSIpCisgICAgICAtPkVuZExpc3QoKQorICAgICAgLT5FbmRMaXN0KCk7CisgIEVYUEVDVF9FUSgiW1tcInZhbHVlXCJdXSIsIG91dHB1dF8uc3Vic3RyKDAsIG91dF9zdHJlYW1fLT5CeXRlQ291bnQoKSkpOworfQorCitURVNUX0YoSnNvbk9iamVjdFdyaXRlclRlc3QsIFJlbmRlclByaW1pdGl2ZXMpIHsKKyAgb3dfID0gbmV3IEpzb25PYmplY3RXcml0ZXIoIiIsIG91dF9zdHJlYW1fKTsKKyAgb3dfLT5TdGFydE9iamVjdCgiIikKKyAgICAgIC0+UmVuZGVyQm9vbCgiYm9vbCIsIHRydWUpCisgICAgICAtPlJlbmRlckRvdWJsZSgiZG91YmxlIiwgc3RkOjpudW1lcmljX2xpbWl0czxkb3VibGU+OjptYXgoKSkKKyAgICAgIC0+UmVuZGVyRmxvYXQoImZsb2F0Iiwgc3RkOjpudW1lcmljX2xpbWl0czxmbG9hdD46Om1heCgpKQorICAgICAgLT5SZW5kZXJJbnQzMigiaW50Iiwgc3RkOjpudW1lcmljX2xpbWl0czxpbnQzMj46Om1pbigpKQorICAgICAgLT5SZW5kZXJJbnQ2NCgibG9uZyIsIHN0ZDo6bnVtZXJpY19saW1pdHM8aW50NjQ+OjptaW4oKSkKKyAgICAgIC0+UmVuZGVyQnl0ZXMoImJ5dGVzIiwgImFicmFjYWRhYnJhIikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJzdHJpbmciLCAic3RyaW5nIikKKyAgICAgIC0+UmVuZGVyQnl0ZXMoImVtcHR5Ynl0ZXMiLCAiIikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJlbXB0eXN0cmluZyIsIHN0cmluZygpKQorICAgICAgLT5FbmRPYmplY3QoKTsKKyAgRVhQRUNUX0VRKAorICAgICAgIntcImJvb2xcIjp0cnVlLCIKKyAgICAgICJcImRvdWJsZVwiOiIgKworICAgICAgICAgIFZhbHVlQXNTdHJpbmc8ZG91YmxlPihzdGQ6Om51bWVyaWNfbGltaXRzPGRvdWJsZT46Om1heCgpKSArCisgICAgICAgICAgIiwiCisgICAgICAgICAgIlwiZmxvYXRcIjoiICsKKyAgICAgICAgICBWYWx1ZUFzU3RyaW5nPGZsb2F0PihzdGQ6Om51bWVyaWNfbGltaXRzPGZsb2F0Pjo6bWF4KCkpICsKKyAgICAgICAgICAiLCIKKyAgICAgICAgICAiXCJpbnRcIjotMjE0NzQ4MzY0OCwiCisgICAgICAgICAgIlwibG9uZ1wiOlwiLTkyMjMzNzIwMzY4NTQ3NzU4MDhcIiwiCisgICAgICAgICAgIlwiYnl0ZXNcIjpcIllXSnlZV05oWkdGaWNtRT1cIiwiCisgICAgICAgICAgIlwic3RyaW5nXCI6XCJzdHJpbmdcIiwiCisgICAgICAgICAgIlwiZW1wdHlieXRlc1wiOlwiXCIsIgorICAgICAgICAgICJcImVtcHR5c3RyaW5nXCI6XCJcIn0iLAorICAgICAgb3V0cHV0Xy5zdWJzdHIoMCwgb3V0X3N0cmVhbV8tPkJ5dGVDb3VudCgpKSk7Cit9CisKK1RFU1RfRihKc29uT2JqZWN0V3JpdGVyVGVzdCwgQnl0ZXNFbmNvZGVzQXNOb25XZWJTYWZlQmFzZTY0KSB7CisgIHN0cmluZyBzOworICBzLnB1c2hfYmFjaygnXDM3NycpOworICBzLnB1c2hfYmFjaygnXDM1NycpOworICBvd18gPSBuZXcgSnNvbk9iamVjdFdyaXRlcigiIiwgb3V0X3N0cmVhbV8pOworICBvd18tPlN0YXJ0T2JqZWN0KCIiKS0+UmVuZGVyQnl0ZXMoImJ5dGVzIiwgcyktPkVuZE9iamVjdCgpOworICAvLyBOb24td2ViLXNhZmUgd291bGQgZW5jb2RlIHRoaXMgYXMgIi8rOD0iCisgIEVYUEVDVF9FUSgie1wiYnl0ZXNcIjpcIi8rOD1cIn0iLAorICAgICAgICAgICAgb3V0cHV0Xy5zdWJzdHIoMCwgb3V0X3N0cmVhbV8tPkJ5dGVDb3VudCgpKSk7Cit9CisKK1RFU1RfRihKc29uT2JqZWN0V3JpdGVyVGVzdCwgUHJldHR5UHJpbnRMaXN0KSB7CisgIG93XyA9IG5ldyBKc29uT2JqZWN0V3JpdGVyKCIgIiwgb3V0X3N0cmVhbV8pOworICBvd18tPlN0YXJ0T2JqZWN0KCIiKQorICAgICAgLT5TdGFydExpc3QoIml0ZW1zIikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCIiLCAiaXRlbTEiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoIiIsICJpdGVtMiIpCisgICAgICAtPlJlbmRlclN0cmluZygiIiwgIml0ZW0zIikKKyAgICAgIC0+RW5kTGlzdCgpCisgICAgICAtPlN0YXJ0TGlzdCgiZW1wdHkiKQorICAgICAgLT5FbmRMaXN0KCkKKyAgICAgIC0+RW5kT2JqZWN0KCk7CisgIEVYUEVDVF9FUSgKKyAgICAgICJ7XG4iCisgICAgICAiIFwiaXRlbXNcIjogW1xuIgorICAgICAgIiAgXCJpdGVtMVwiLFxuIgorICAgICAgIiAgXCJpdGVtMlwiLFxuIgorICAgICAgIiAgXCJpdGVtM1wiXG4iCisgICAgICAiIF0sXG4iCisgICAgICAiIFwiZW1wdHlcIjogW11cbiIKKyAgICAgICJ9XG4iLAorICAgICAgb3V0cHV0Xy5zdWJzdHIoMCwgb3V0X3N0cmVhbV8tPkJ5dGVDb3VudCgpKSk7Cit9CisKK1RFU1RfRihKc29uT2JqZWN0V3JpdGVyVGVzdCwgUHJldHR5UHJpbnRPYmplY3QpIHsKKyAgb3dfID0gbmV3IEpzb25PYmplY3RXcml0ZXIoIiAiLCBvdXRfc3RyZWFtXyk7CisgIG93Xy0+U3RhcnRPYmplY3QoIiIpCisgICAgICAtPlN0YXJ0T2JqZWN0KCJpdGVtcyIpCisgICAgICAtPlJlbmRlclN0cmluZygia2V5MSIsICJpdGVtMSIpCisgICAgICAtPlJlbmRlclN0cmluZygia2V5MiIsICJpdGVtMiIpCisgICAgICAtPlJlbmRlclN0cmluZygia2V5MyIsICJpdGVtMyIpCisgICAgICAtPkVuZE9iamVjdCgpCisgICAgICAtPlN0YXJ0T2JqZWN0KCJlbXB0eSIpCisgICAgICAtPkVuZE9iamVjdCgpCisgICAgICAtPkVuZE9iamVjdCgpOworICBFWFBFQ1RfRVEoCisgICAgICAie1xuIgorICAgICAgIiBcIml0ZW1zXCI6IHtcbiIKKyAgICAgICIgIFwia2V5MVwiOiBcIml0ZW0xXCIsXG4iCisgICAgICAiICBcImtleTJcIjogXCJpdGVtMlwiLFxuIgorICAgICAgIiAgXCJrZXkzXCI6IFwiaXRlbTNcIlxuIgorICAgICAgIiB9LFxuIgorICAgICAgIiBcImVtcHR5XCI6IHt9XG4iCisgICAgICAifVxuIiwKKyAgICAgIG91dHB1dF8uc3Vic3RyKDAsIG91dF9zdHJlYW1fLT5CeXRlQ291bnQoKSkpOworfQorCitURVNUX0YoSnNvbk9iamVjdFdyaXRlclRlc3QsIFByZXR0eVByaW50RW1wdHlPYmplY3RJbkVtcHR5TGlzdCkgeworICBvd18gPSBuZXcgSnNvbk9iamVjdFdyaXRlcigiICIsIG91dF9zdHJlYW1fKTsKKyAgb3dfLT5TdGFydE9iamVjdCgiIikKKyAgICAgIC0+U3RhcnRMaXN0KCJsaXN0IikKKyAgICAgIC0+U3RhcnRPYmplY3QoIiIpCisgICAgICAtPkVuZE9iamVjdCgpCisgICAgICAtPkVuZExpc3QoKQorICAgICAgLT5FbmRPYmplY3QoKTsKKyAgRVhQRUNUX0VRKAorICAgICAgIntcbiIKKyAgICAgICIgXCJsaXN0XCI6IFtcbiIKKyAgICAgICIgIHt9XG4iCisgICAgICAiIF1cbiIKKyAgICAgICJ9XG4iLAorICAgICAgb3V0cHV0Xy5zdWJzdHIoMCwgb3V0X3N0cmVhbV8tPkJ5dGVDb3VudCgpKSk7Cit9CisKK1RFU1RfRihKc29uT2JqZWN0V3JpdGVyVGVzdCwgUHJldHR5UHJpbnREb3VibGVJbmRlbnQpIHsKKyAgb3dfID0gbmV3IEpzb25PYmplY3RXcml0ZXIoIiAgIiwgb3V0X3N0cmVhbV8pOworICBvd18tPlN0YXJ0T2JqZWN0KCIiKQorICAgICAgLT5SZW5kZXJCb29sKCJib29sIiwgdHJ1ZSkKKyAgICAgIC0+UmVuZGVySW50MzIoImludCIsIDQyKQorICAgICAgLT5FbmRPYmplY3QoKTsKKyAgRVhQRUNUX0VRKAorICAgICAgIntcbiIKKyAgICAgICIgIFwiYm9vbFwiOiB0cnVlLFxuIgorICAgICAgIiAgXCJpbnRcIjogNDJcbiIKKyAgICAgICJ9XG4iLAorICAgICAgb3V0cHV0Xy5zdWJzdHIoMCwgb3V0X3N0cmVhbV8tPkJ5dGVDb3VudCgpKSk7Cit9CisKK1RFU1RfRihKc29uT2JqZWN0V3JpdGVyVGVzdCwgU3RyaW5nc0VzY2FwZWRBbmRFbmNsb3NlZEluRG91YmxlUXVvdGVzKSB7CisgIG93XyA9IG5ldyBKc29uT2JqZWN0V3JpdGVyKCIiLCBvdXRfc3RyZWFtXyk7CisgIG93Xy0+U3RhcnRPYmplY3QoIiIpLT5SZW5kZXJTdHJpbmcoInN0cmluZyIsICInPD4mYW1wO1xcXCJcclxuIiktPkVuZE9iamVjdCgpOworICBFWFBFQ1RfRVEoIntcInN0cmluZ1wiOlwiJ1xcdTAwM2NcXHUwMDNlJmFtcDtcXFxcXFxcIlxcclxcblwifSIsCisgICAgICAgICAgICBvdXRwdXRfLnN1YnN0cigwLCBvdXRfc3RyZWFtXy0+Qnl0ZUNvdW50KCkpKTsKK30KKworVEVTVF9GKEpzb25PYmplY3RXcml0ZXJUZXN0LCBTdHJpbmdpZmljYXRpb24pIHsKKyAgb3dfID0gbmV3IEpzb25PYmplY3RXcml0ZXIoIiIsIG91dF9zdHJlYW1fKTsKKyAgb3dfLT5TdGFydE9iamVjdCgiIikKKyAgICAgIC0+UmVuZGVyRG91YmxlKCJkb3VibGVfbmFuIiwgc3RkOjpudW1lcmljX2xpbWl0czxkb3VibGU+OjpxdWlldF9OYU4oKSkKKyAgICAgIC0+UmVuZGVyRmxvYXQoImZsb2F0X25hbiIsIHN0ZDo6bnVtZXJpY19saW1pdHM8ZmxvYXQ+OjpxdWlldF9OYU4oKSkKKyAgICAgIC0+UmVuZGVyRG91YmxlKCJkb3VibGVfcG9zIiwgc3RkOjpudW1lcmljX2xpbWl0czxkb3VibGU+OjppbmZpbml0eSgpKQorICAgICAgLT5SZW5kZXJGbG9hdCgiZmxvYXRfcG9zIiwgc3RkOjpudW1lcmljX2xpbWl0czxmbG9hdD46OmluZmluaXR5KCkpCisgICAgICAtPlJlbmRlckRvdWJsZSgiZG91YmxlX25lZyIsIC1zdGQ6Om51bWVyaWNfbGltaXRzPGRvdWJsZT46OmluZmluaXR5KCkpCisgICAgICAtPlJlbmRlckZsb2F0KCJmbG9hdF9uZWciLCAtc3RkOjpudW1lcmljX2xpbWl0czxmbG9hdD46OmluZmluaXR5KCkpCisgICAgICAtPkVuZE9iamVjdCgpOworICBFWFBFQ1RfRVEoCisgICAgICAie1wiZG91YmxlX25hblwiOlwiTmFOXCIsIgorICAgICAgIlwiZmxvYXRfbmFuXCI6XCJOYU5cIiwiCisgICAgICAiXCJkb3VibGVfcG9zXCI6XCJJbmZpbml0eVwiLCIKKyAgICAgICJcImZsb2F0X3Bvc1wiOlwiSW5maW5pdHlcIiwiCisgICAgICAiXCJkb3VibGVfbmVnXCI6XCItSW5maW5pdHlcIiwiCisgICAgICAiXCJmbG9hdF9uZWdcIjpcIi1JbmZpbml0eVwifSIsCisgICAgICBvdXRwdXRfLnN1YnN0cigwLCBvdXRfc3RyZWFtXy0+Qnl0ZUNvdW50KCkpKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGNvbnZlcnRlcgorfSAgLy8gbmFtZXNwYWNlIHV0aWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL2pzb25fc3RyZWFtX3BhcnNlci5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9qc29uX3N0cmVhbV9wYXJzZXIuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGY5MTY3NQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9qc29uX3N0cmVhbV9wYXJzZXIuY2MKQEAgLTAsMCArMSw3NzQgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvanNvbl9zdHJlYW1fcGFyc2VyLmg+CisKKyNpbmNsdWRlIDxhbGdvcml0aG0+CisjaW5jbHVkZSA8Y2N0eXBlPgorI2luY2x1ZGUgPGNlcnJubz4KKyNpbmNsdWRlIDxjc3RkbGliPgorI2luY2x1ZGUgPGNzdHJpbmc+CisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2xvZ2dpbmcuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9vYmplY3Rfd3JpdGVyLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSB1dGlsIHsKKworLy8gQWxsb3cgdGhlc2Ugc3ltYm9scyB0byBiZSByZWZlcmVuY2VkIGFzIHV0aWw6OlN0YXR1cywgdXRpbDo6ZXJyb3I6OiogaW4KKy8vIHRoaXMgZmlsZS4KK3VzaW5nIHV0aWw6OlN0YXR1czsKK25hbWVzcGFjZSBlcnJvciB7Cit1c2luZyB1dGlsOjplcnJvcjo6SU5URVJOQUw7Cit1c2luZyB1dGlsOjplcnJvcjo6SU5WQUxJRF9BUkdVTUVOVDsKK30gIC8vIG5hbWVzcGFjZSBlcnJvcgorCituYW1lc3BhY2UgY29udmVydGVyIHsKKworLy8gTnVtYmVyIG9mIGRpZ2l0cyBpbiBhIHVuaWNvZGUgZXNjYXBlIHNlcXVlbmNlICgvdVhYWFgpCitzdGF0aWMgY29uc3QgaW50IGtVbmljb2RlRXNjYXBlZExlbmd0aCA9IDY7CisKKy8vIExlbmd0aCBvZiB0aGUgdHJ1ZSwgZmFsc2UsIGFuZCBudWxsIGxpdGVyYWxzLgorc3RhdGljIGNvbnN0IGludCB0cnVlX2xlbiA9IHN0cmxlbigidHJ1ZSIpOworc3RhdGljIGNvbnN0IGludCBmYWxzZV9sZW4gPSBzdHJsZW4oImZhbHNlIik7CitzdGF0aWMgY29uc3QgaW50IG51bGxfbGVuID0gc3RybGVuKCJudWxsIik7CisKK2lubGluZSBib29sIElzTGV0dGVyKGNoYXIgYykgeworICByZXR1cm4gKCdhJyA8PSBjICYmIGMgPD0gJ3onKSB8fCAoJ0EnIDw9IGMgJiYgYyA8PSAnWicpIHx8IChjID09ICdfJykgfHwKKyAgICAgICAgIChjID09ICckJyk7Cit9CisKK2lubGluZSBib29sIElzQWxwaGFudW1lcmljKGNoYXIgYykgeworICByZXR1cm4gSXNMZXR0ZXIoYykgfHwgKCcwJyA8PSBjICYmIGMgPD0gJzknKTsKK30KKworc3RhdGljIGJvb2wgQ29uc3VtZUtleShTdHJpbmdQaWVjZSogaW5wdXQsIFN0cmluZ1BpZWNlKiBrZXkpIHsKKyAgaWYgKGlucHV0LT5lbXB0eSgpIHx8ICFJc0xldHRlcigoKmlucHV0KVswXSkpIHJldHVybiBmYWxzZTsKKyAgaW50IGxlbiA9IDE7CisgIGZvciAoOyBsZW4gPCBpbnB1dC0+c2l6ZSgpOyArK2xlbikgeworICAgIGlmICghSXNBbHBoYW51bWVyaWMoKCppbnB1dClbbGVuXSkpIHsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgfQorICAqa2V5ID0gU3RyaW5nUGllY2UoaW5wdXQtPmRhdGEoKSwgbGVuKTsKKyAgKmlucHV0ID0gU3RyaW5nUGllY2UoaW5wdXQtPmRhdGEoKSArIGxlbiwgaW5wdXQtPnNpemUoKSAtIGxlbik7CisgIHJldHVybiB0cnVlOworfQorCitzdGF0aWMgYm9vbCBNYXRjaEtleShTdHJpbmdQaWVjZSBpbnB1dCkgeworICByZXR1cm4gIWlucHV0LmVtcHR5KCkgJiYgSXNMZXR0ZXIoaW5wdXRbMF0pOworfQorCitKc29uU3RyZWFtUGFyc2VyOjpKc29uU3RyZWFtUGFyc2VyKE9iamVjdFdyaXRlciogb3cpCisgICAgOiBvd18ob3cpLAorICAgICAgc3RhY2tfKCksCisgICAgICBsZWZ0b3Zlcl8oKSwKKyAgICAgIGpzb25fKCksCisgICAgICBwXygpLAorICAgICAga2V5XygpLAorICAgICAga2V5X3N0b3JhZ2VfKCksCisgICAgICBmaW5pc2hpbmdfKGZhbHNlKSwKKyAgICAgIHBhcnNlZF8oKSwKKyAgICAgIHBhcnNlZF9zdG9yYWdlXygpLAorICAgICAgc3RyaW5nX29wZW5fKDApLAorICAgICAgY2h1bmtfc3RvcmFnZV8oKSwKKyAgICAgIGNvZXJjZV90b191dGY4XyhmYWxzZSkgeworICAvLyBJbml0aWFsaXplIHRoZSBzdGFjayB3aXRoIGEgc2luZ2xlIHZhbHVlIHRvIGJlIHBhcnNlZC4KKyAgc3RhY2tfLnB1c2goVkFMVUUpOworfQorCitKc29uU3RyZWFtUGFyc2VyOjp+SnNvblN0cmVhbVBhcnNlcigpIHt9CisKKwordXRpbDo6U3RhdHVzIEpzb25TdHJlYW1QYXJzZXI6OlBhcnNlKFN0cmluZ1BpZWNlIGpzb24pIHsKKyAgU3RyaW5nUGllY2UgY2h1bmsgPSBqc29uOworICAvLyBJZiB3ZSBoYXZlIGxlZnRvdmVycyBmcm9tIGEgcHJldmlvdXMgY2h1bmssIGFwcGVuZCB0aGUgbmV3IGNodW5rIHRvIGl0CisgIC8vIGFuZCBjcmVhdGUgYSBuZXcgU3RyaW5nUGllY2UgcG9pbnRpbmcgYXQgdGhlIHN0cmluZydzIGRhdGEuIFRoaXMgY291bGQKKyAgLy8gYmUgbGFyZ2UgYnV0IHdlIHJlbHkgb24gdGhlIGNodW5rcyB0byBiZSBzbWFsbCwgYXNzdW1pbmcgdGhleSBhcmUKKyAgLy8gZnJhZ21lbnRzIG9mIGEgQ29yZC4KKyAgaWYgKCFsZWZ0b3Zlcl8uZW1wdHkoKSkgeworICAgIC8vIERvbid0IHBvaW50IGNodW5rIHRvIGxlZnRvdmVyXyBiZWNhdXNlIGxlZnRvdmVyXyB3aWxsIGJlIHVwZGF0ZWQgaW4KKyAgICAvLyBQYXJzZUNodW5rKGNodW5rKS4KKyAgICBjaHVua19zdG9yYWdlXy5zd2FwKGxlZnRvdmVyXyk7CisgICAganNvbi5BcHBlbmRUb1N0cmluZygmY2h1bmtfc3RvcmFnZV8pOworICAgIGNodW5rID0gU3RyaW5nUGllY2UoY2h1bmtfc3RvcmFnZV8pOworICB9CisKKyAgLy8gRmluZCB0aGUgc3RydWN0dXJhbGx5IHZhbGlkIFVURjggcHJlZml4IGFuZCBwYXJzZSBvbmx5IHRoYXQuCisgIGludCBuID0gaW50ZXJuYWw6OlVURjhTcG5TdHJ1Y3R1cmFsbHlWYWxpZChjaHVuayk7CisgIGlmIChuID4gMCkgeworICAgIHV0aWw6OlN0YXR1cyBzdGF0dXMgPSBQYXJzZUNodW5rKGNodW5rLnN1YnN0cigwLCBuKSk7CisKKyAgICAvLyBBbnkgbGVmdG92ZXIgY2hhcmFjdGVycyBhcmUgc3Rhc2hlZCBpbiBsZWZ0b3Zlcl8gZm9yIGxhdGVyIHBhcnNpbmcgd2hlbgorICAgIC8vIHRoZXJlIGlzIG1vcmUgZGF0YSBhdmFpbGFibGUuCisgICAgY2h1bmsuc3Vic3RyKG4pLkFwcGVuZFRvU3RyaW5nKCZsZWZ0b3Zlcl8pOworICAgIHJldHVybiBzdGF0dXM7CisgIH0gZWxzZSB7CisgICAgY2h1bmsuQ29weVRvU3RyaW5nKCZsZWZ0b3Zlcl8pOworICAgIHJldHVybiB1dGlsOjpTdGF0dXM6Ok9LOworICB9Cit9CisKK3V0aWw6OlN0YXR1cyBKc29uU3RyZWFtUGFyc2VyOjpGaW5pc2hQYXJzZSgpIHsKKyAgLy8gSWYgd2UgZG8gbm90IGV4cGVjdCBhbnl0aGluZyBhbmQgdGhlcmUgaXMgbm90aGluZyBsZWZ0IHRvIHBhcnNlIHdlJ3JlIGFsbAorICAvLyBkb25lLgorICBpZiAoc3RhY2tfLmVtcHR5KCkgJiYgbGVmdG92ZXJfLmVtcHR5KCkpIHsKKyAgICByZXR1cm4gdXRpbDo6U3RhdHVzOjpPSzsKKyAgfQorCisgIC8vIFN0b3JhZ2UgZm9yIFVURjgtY29lcmNlZCBzdHJpbmcuCisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9hcnJheTxjaGFyPiB1dGY4OworICBpZiAoY29lcmNlX3RvX3V0ZjhfKSB7CisgICAgdXRmOC5yZXNldChuZXcgY2hhcltsZWZ0b3Zlcl8uc2l6ZSgpXSk7CisgICAgY2hhciogY29lcmNlZCA9IGludGVybmFsOjpVVEY4Q29lcmNlVG9TdHJ1Y3R1cmFsbHlWYWxpZChsZWZ0b3Zlcl8sIHV0ZjguZ2V0KCksICcgJyk7CisgICAgcF8gPSBqc29uXyA9IFN0cmluZ1BpZWNlKGNvZXJjZWQsIGxlZnRvdmVyXy5zaXplKCkpOworICB9IGVsc2UgeworICAgIHBfID0ganNvbl8gPSBsZWZ0b3Zlcl87CisgICAgaWYgKCFpbnRlcm5hbDo6SXNTdHJ1Y3R1cmFsbHlWYWxpZFVURjgobGVmdG92ZXJfKSkgeworICAgICAgcmV0dXJuIFJlcG9ydEZhaWx1cmUoIkVuY291bnRlcmVkIG5vbiBVVEYtOCBjb2RlIHBvaW50cy4iKTsKKyAgICB9CisgIH0KKworICAvLyBQYXJzZSB0aGUgcmVtYWluZGVyIGluIGZpbmlzaGluZyBtb2RlLCB3aGljaCByZXBvcnRzIGVycm9ycyBmb3IgdGhpbmdzIGxpa2UKKyAgLy8gdW50ZXJtaW5hdGVkIHN0cmluZ3Mgb3IgdW5rbm93biB0b2tlbnMgdGhhdCB3b3VsZCBub3JtYWxseSBiZSByZXRyaWVkLgorICBmaW5pc2hpbmdfID0gdHJ1ZTsKKyAgdXRpbDo6U3RhdHVzIHJlc3VsdCA9IFJ1blBhcnNlcigpOworICBpZiAocmVzdWx0Lm9rKCkpIHsKKyAgICBTa2lwV2hpdGVzcGFjZSgpOworICAgIGlmICghcF8uZW1wdHkoKSkgeworICAgICAgcmVzdWx0ID0gUmVwb3J0RmFpbHVyZSgiUGFyc2luZyB0ZXJtaW5hdGVkIGJlZm9yZSBlbmQgb2YgaW5wdXQuIik7CisgICAgfQorICB9CisgIHJldHVybiByZXN1bHQ7Cit9CisKK3V0aWw6OlN0YXR1cyBKc29uU3RyZWFtUGFyc2VyOjpQYXJzZUNodW5rKFN0cmluZ1BpZWNlIGNodW5rKSB7CisgIC8vIERvIG5vdCBkbyBhbnkgd29yayBpZiB0aGUgY2h1bmsgaXMgZW1wdHkuCisgIGlmIChjaHVuay5lbXB0eSgpKSByZXR1cm4gdXRpbDo6U3RhdHVzOjpPSzsKKworICBwXyA9IGpzb25fID0gY2h1bms7CisKKyAgZmluaXNoaW5nXyA9IGZhbHNlOworICB1dGlsOjpTdGF0dXMgcmVzdWx0ID0gUnVuUGFyc2VyKCk7CisgIGlmICghcmVzdWx0Lm9rKCkpIHJldHVybiByZXN1bHQ7CisKKyAgU2tpcFdoaXRlc3BhY2UoKTsKKyAgaWYgKHBfLmVtcHR5KCkpIHsKKyAgICAvLyBJZiB3ZSBwYXJzZWQgZXZlcnl0aGluZyB3ZSBoYWQsIGNsZWFyIHRoZSBsZWZ0b3Zlci4KKyAgICBsZWZ0b3Zlcl8uY2xlYXIoKTsKKyAgfSBlbHNlIHsKKyAgICAvLyBJZiB3ZSBkbyBub3QgZXhwZWN0IGFueXRoaW5nIGkuZS4gc3RhY2sgaXMgZW1wdHksIGFuZCB3ZSBoYXZlIG5vbi1lbXB0eQorICAgIC8vIHN0cmluZyBsZWZ0IHRvIHBhcnNlLCB3ZSByZXBvcnQgYW4gZXJyb3IuCisgICAgaWYgKHN0YWNrXy5lbXB0eSgpKSB7CisgICAgICByZXR1cm4gUmVwb3J0RmFpbHVyZSgiUGFyc2luZyB0ZXJtaW5hdGVkIGJlZm9yZSBlbmQgb2YgaW5wdXQuIik7CisgICAgfQorICAgIC8vIElmIHdlIGV4cGVjdCBmdXR1cmUgZGF0YSBpLmUuIHN0YWNrIGlzIG5vbi1lbXB0eSwgYW5kIHdlIGhhdmUgc29tZQorICAgIC8vIHVucGFyc2VkIGRhdGEgbGVmdCwgd2Ugc2F2ZSBpdCBmb3IgbGF0ZXIgcGFyc2UuCisgICAgbGVmdG92ZXJfID0gcF8uVG9TdHJpbmcoKTsKKyAgfQorICByZXR1cm4gdXRpbDo6U3RhdHVzOjpPSzsKK30KKwordXRpbDo6U3RhdHVzIEpzb25TdHJlYW1QYXJzZXI6OlJ1blBhcnNlcigpIHsKKyAgd2hpbGUgKCFzdGFja18uZW1wdHkoKSkgeworICAgIFBhcnNlVHlwZSB0eXBlID0gc3RhY2tfLnRvcCgpOworICAgIFRva2VuVHlwZSB0ID0gKHN0cmluZ19vcGVuXyA9PSAwKSA/IEdldE5leHRUb2tlblR5cGUoKSA6IEJFR0lOX1NUUklORzsKKyAgICBzdGFja18ucG9wKCk7CisgICAgdXRpbDo6U3RhdHVzIHJlc3VsdDsKKyAgICBzd2l0Y2ggKHR5cGUpIHsKKyAgICAgIGNhc2UgVkFMVUU6CisgICAgICAgIHJlc3VsdCA9IFBhcnNlVmFsdWUodCk7CisgICAgICAgIGJyZWFrOworCisgICAgICBjYXNlIE9CSl9NSUQ6CisgICAgICAgIHJlc3VsdCA9IFBhcnNlT2JqZWN0TWlkKHQpOworICAgICAgICBicmVhazsKKworICAgICAgY2FzZSBFTlRSWToKKyAgICAgICAgcmVzdWx0ID0gUGFyc2VFbnRyeSh0KTsKKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGNhc2UgRU5UUllfTUlEOgorICAgICAgICByZXN1bHQgPSBQYXJzZUVudHJ5TWlkKHQpOworICAgICAgICBicmVhazsKKworICAgICAgY2FzZSBBUlJBWV9WQUxVRToKKyAgICAgICAgcmVzdWx0ID0gUGFyc2VBcnJheVZhbHVlKHQpOworICAgICAgICBicmVhazsKKworICAgICAgY2FzZSBBUlJBWV9NSUQ6CisgICAgICAgIHJlc3VsdCA9IFBhcnNlQXJyYXlNaWQodCk7CisgICAgICAgIGJyZWFrOworCisgICAgICBkZWZhdWx0OgorICAgICAgICByZXN1bHQgPSB1dGlsOjpTdGF0dXModXRpbDo6ZXJyb3I6OklOVEVSTkFMLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyQ2F0KCJVbmtub3duIHBhcnNlIHR5cGU6ICIsIHR5cGUpKTsKKyAgICAgICAgYnJlYWs7CisgICAgfQorICAgIGlmICghcmVzdWx0Lm9rKCkpIHsKKyAgICAgIC8vIElmIHdlIHdlcmUgY2FuY2VsbGVkLCBzYXZlIG91ciBzdGF0ZSBhbmQgdHJ5IGFnYWluIGxhdGVyLgorICAgICAgaWYgKCFmaW5pc2hpbmdfICYmIHJlc3VsdCA9PSB1dGlsOjpTdGF0dXM6OkNBTkNFTExFRCkgeworICAgICAgICBzdGFja18ucHVzaCh0eXBlKTsKKyAgICAgICAgLy8gSWYgd2UgaGF2ZSBhIGtleSB3ZSBzdGlsbCBuZWVkIHRvIHJlbmRlciwgbWFrZSBzdXJlIHRvIHNhdmUgb2ZmIHRoZQorICAgICAgICAvLyBjb250ZW50cyBpbiBvdXIgb3duIHN0b3JhZ2UuCisgICAgICAgIGlmICgha2V5Xy5lbXB0eSgpICYmIGtleV9zdG9yYWdlXy5lbXB0eSgpKSB7CisgICAgICAgICAga2V5Xy5BcHBlbmRUb1N0cmluZygma2V5X3N0b3JhZ2VfKTsKKyAgICAgICAgICBrZXlfID0gU3RyaW5nUGllY2Uoa2V5X3N0b3JhZ2VfKTsKKyAgICAgICAgfQorICAgICAgICByZXN1bHQgPSB1dGlsOjpTdGF0dXM6Ok9LOworICAgICAgfQorICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisgIH0KKyAgcmV0dXJuIHV0aWw6OlN0YXR1czo6T0s7Cit9CisKK3V0aWw6OlN0YXR1cyBKc29uU3RyZWFtUGFyc2VyOjpQYXJzZVZhbHVlKFRva2VuVHlwZSB0eXBlKSB7CisgIHN3aXRjaCAodHlwZSkgeworICAgIGNhc2UgQkVHSU5fT0JKRUNUOgorICAgICAgcmV0dXJuIEhhbmRsZUJlZ2luT2JqZWN0KCk7CisgICAgY2FzZSBCRUdJTl9BUlJBWToKKyAgICAgIHJldHVybiBIYW5kbGVCZWdpbkFycmF5KCk7CisgICAgY2FzZSBCRUdJTl9TVFJJTkc6CisgICAgICByZXR1cm4gUGFyc2VTdHJpbmcoKTsKKyAgICBjYXNlIEJFR0lOX05VTUJFUjoKKyAgICAgIHJldHVybiBQYXJzZU51bWJlcigpOworICAgIGNhc2UgQkVHSU5fVFJVRToKKyAgICAgIHJldHVybiBQYXJzZVRydWUoKTsKKyAgICBjYXNlIEJFR0lOX0ZBTFNFOgorICAgICAgcmV0dXJuIFBhcnNlRmFsc2UoKTsKKyAgICBjYXNlIEJFR0lOX05VTEw6CisgICAgICByZXR1cm4gUGFyc2VOdWxsKCk7CisgICAgY2FzZSBVTktOT1dOOgorICAgICAgcmV0dXJuIFJlcG9ydFVua25vd24oIkV4cGVjdGVkIGEgdmFsdWUuIik7CisgICAgZGVmYXVsdDogeworICAgICAgLy8gU3BlY2lhbCBjYXNlIGZvciBoYXZpbmcgYmVlbiBjdXQgb2ZmIHdoaWxlIHBhcnNpbmcsIHdhaXQgZm9yIG1vcmUgZGF0YS4KKyAgICAgIC8vIFRoaXMgaGFuZGxlcyB0aGluZ3MgbGlrZSAnZmFscycgYmVpbmcgYXQgdGhlIGVuZCBvZiB0aGUgc3RyaW5nLCB3ZQorICAgICAgLy8gZG9uJ3Qga25vdyBpZiB0aGUgbmV4dCBjaGFyIHdvdWxkIGJlIGUsIGNvbXBsZXRpbmcgaXQsIG9yIHNvbWV0aGluZworICAgICAgLy8gZWxzZSwgbWFraW5nIGl0IGludmFsaWQuCisgICAgICBpZiAoIWZpbmlzaGluZ18gJiYgcF8ubGVuZ3RoKCkgPCBmYWxzZV9sZW4pIHsKKyAgICAgICAgcmV0dXJuIHV0aWw6OlN0YXR1czo6Q0FOQ0VMTEVEOworICAgICAgfQorICAgICAgcmV0dXJuIFJlcG9ydEZhaWx1cmUoIlVuZXhwZWN0ZWQgdG9rZW4uIik7CisgICAgfQorICB9Cit9CisKK3V0aWw6OlN0YXR1cyBKc29uU3RyZWFtUGFyc2VyOjpQYXJzZVN0cmluZygpIHsKKyAgdXRpbDo6U3RhdHVzIHJlc3VsdCA9IFBhcnNlU3RyaW5nSGVscGVyKCk7CisgIGlmIChyZXN1bHQub2soKSkgeworICAgIG93Xy0+UmVuZGVyU3RyaW5nKGtleV8sIHBhcnNlZF8pOworICAgIGtleV8uY2xlYXIoKTsKKyAgICBwYXJzZWRfLmNsZWFyKCk7CisgICAgcGFyc2VkX3N0b3JhZ2VfLmNsZWFyKCk7CisgIH0KKyAgcmV0dXJuIHJlc3VsdDsKK30KKwordXRpbDo6U3RhdHVzIEpzb25TdHJlYW1QYXJzZXI6OlBhcnNlU3RyaW5nSGVscGVyKCkgeworICAvLyBJZiB3ZSBoYXZlbid0IHNlZW4gdGhlIHN0YXJ0IHF1b3RlLCBncmFiIGl0IGFuZCByZW1lbWJlciBpdCBmb3IgbGF0ZXIuCisgIGlmIChzdHJpbmdfb3Blbl8gPT0gMCkgeworICAgIHN0cmluZ19vcGVuXyA9ICpwXy5kYXRhKCk7CisgICAgR09PR0xFX0RDSEVDSyhzdHJpbmdfb3Blbl8gPT0gJ1wiJyB8fCBzdHJpbmdfb3Blbl8gPT0gJ1wnJyk7CisgICAgQWR2YW5jZSgpOworICB9CisgIC8vIFRyYWNrIHdoZXJlIHdlIGxhc3QgY29waWVkIGRhdGEgZnJvbSBzbyB3ZSBjYW4gbWluaW1pemUgY29weWluZy4KKyAgY29uc3QgY2hhciogbGFzdCA9IHBfLmRhdGEoKTsKKyAgd2hpbGUgKCFwXy5lbXB0eSgpKSB7CisgICAgY29uc3QgY2hhciogZGF0YSA9IHBfLmRhdGEoKTsKKyAgICBpZiAoKmRhdGEgPT0gJ1xcJykgeworICAgICAgLy8gV2UncmUgYWJvdXQgdG8gaGFuZGxlIGFuIGVzY2FwZSwgY29weSBhbGwgYnl0ZXMgZnJvbSBsYXN0IHRvIGRhdGEuCisgICAgICBpZiAobGFzdCA8IGRhdGEpIHsKKyAgICAgICAgcGFyc2VkX3N0b3JhZ2VfLmFwcGVuZChsYXN0LCBkYXRhIC0gbGFzdCk7CisgICAgICAgIGxhc3QgPSBkYXRhOworICAgICAgfQorICAgICAgLy8gSWYgd2UgcmFuIG91dCBvZiBzdHJpbmcgYWZ0ZXIgdGhlIFwsIGNhbmNlbCBvciByZXBvcnQgYW4gZXJyb3IKKyAgICAgIC8vIGRlcGVuZGluZyBvbiBpZiB3ZSBleHBlY3QgbW9yZSBkYXRhIGxhdGVyLgorICAgICAgaWYgKHBfLmxlbmd0aCgpID09IDEpIHsKKyAgICAgICAgaWYgKCFmaW5pc2hpbmdfKSB7CisgICAgICAgICAgcmV0dXJuIHV0aWw6OlN0YXR1czo6Q0FOQ0VMTEVEOworICAgICAgICB9CisgICAgICAgIHJldHVybiBSZXBvcnRGYWlsdXJlKCJDbG9zaW5nIHF1b3RlIGV4cGVjdGVkIGluIHN0cmluZy4iKTsKKyAgICAgIH0KKyAgICAgIC8vIFBhcnNlIGEgdW5pY29kZSBlc2NhcGUgaWYgd2UgZm91bmQgXHUgaW4gdGhlIHN0cmluZy4KKyAgICAgIGlmIChkYXRhWzFdID09ICd1JykgeworICAgICAgICB1dGlsOjpTdGF0dXMgcmVzdWx0ID0gUGFyc2VVbmljb2RlRXNjYXBlKCk7CisgICAgICAgIGlmICghcmVzdWx0Lm9rKCkpIHsKKyAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisgICAgICAgIC8vIE1vdmUgbGFzdCBwb2ludGVyIHBhc3QgdGhlIHVuaWNvZGUgZXNjYXBlIGFuZCBjb250aW51ZS4KKyAgICAgICAgbGFzdCA9IHBfLmRhdGEoKTsKKyAgICAgICAgY29udGludWU7CisgICAgICB9CisgICAgICAvLyBIYW5kbGUgdGhlIHN0YW5kYXJkIHNldCBvZiBiYWNrc2xhc2gtZXNjYXBlZCBjaGFyYWN0ZXJzLgorICAgICAgc3dpdGNoIChkYXRhWzFdKSB7CisgICAgICAgIGNhc2UgJ2InOgorICAgICAgICAgIHBhcnNlZF9zdG9yYWdlXy5wdXNoX2JhY2soJ1xiJyk7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgJ2YnOgorICAgICAgICAgIHBhcnNlZF9zdG9yYWdlXy5wdXNoX2JhY2soJ1xmJyk7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgJ24nOgorICAgICAgICAgIHBhcnNlZF9zdG9yYWdlXy5wdXNoX2JhY2soJ1xuJyk7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgJ3InOgorICAgICAgICAgIHBhcnNlZF9zdG9yYWdlXy5wdXNoX2JhY2soJ1xyJyk7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgJ3QnOgorICAgICAgICAgIHBhcnNlZF9zdG9yYWdlXy5wdXNoX2JhY2soJ1x0Jyk7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgJ3YnOgorICAgICAgICAgIHBhcnNlZF9zdG9yYWdlXy5wdXNoX2JhY2soJ1x2Jyk7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgcGFyc2VkX3N0b3JhZ2VfLnB1c2hfYmFjayhkYXRhWzFdKTsKKyAgICAgIH0KKyAgICAgIC8vIFdlIGhhbmRsZWQgdHdvIGNoYXJhY3RlcnMsIHNvIGFkdmFuY2UgcGFzdCB0aGVtIGFuZCBjb250aW51ZS4KKyAgICAgIHBfLnJlbW92ZV9wcmVmaXgoMik7CisgICAgICBsYXN0ID0gcF8uZGF0YSgpOworICAgICAgY29udGludWU7CisgICAgfQorICAgIC8vIElmIHdlIGZvdW5kIHRoZSBjbG9zaW5nIHF1b3RlIG5vdGUgaXQsIGFkdmFuY2UgcGFzdCBpdCwgYW5kIHJldHVybi4KKyAgICBpZiAoKmRhdGEgPT0gc3RyaW5nX29wZW5fKSB7CisgICAgICAvLyBJZiB3ZSBkaWRuJ3QgY29weSBhbnl0aGluZywgcmV1c2UgdGhlIGlucHV0IGJ1ZmZlci4KKyAgICAgIGlmIChwYXJzZWRfc3RvcmFnZV8uZW1wdHkoKSkgeworICAgICAgICBwYXJzZWRfID0gU3RyaW5nUGllY2UobGFzdCwgZGF0YSAtIGxhc3QpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgaWYgKGxhc3QgPCBkYXRhKSB7CisgICAgICAgICAgcGFyc2VkX3N0b3JhZ2VfLmFwcGVuZChsYXN0LCBkYXRhIC0gbGFzdCk7CisgICAgICAgICAgbGFzdCA9IGRhdGE7CisgICAgICAgIH0KKyAgICAgICAgcGFyc2VkXyA9IFN0cmluZ1BpZWNlKHBhcnNlZF9zdG9yYWdlXyk7CisgICAgICB9CisgICAgICAvLyBDbGVhciB0aGUgcXVvdGUgY2hhciBzbyBuZXh0IHRpbWUgd2UgdHJ5IHRvIHBhcnNlIGEgc3RyaW5nIHdlJ2xsCisgICAgICAvLyBzdGFydCBmcmVzaC4KKyAgICAgIHN0cmluZ19vcGVuXyA9IDA7CisgICAgICBBZHZhbmNlKCk7CisgICAgICByZXR1cm4gdXRpbDo6U3RhdHVzOjpPSzsKKyAgICB9CisgICAgLy8gTm9ybWFsIGNoYXJhY3RlciwganVzdCBhZHZhbmNlIHBhc3QgaXQuCisgICAgQWR2YW5jZSgpOworICB9CisgIC8vIElmIHdlIHJhbiBvdXQgb2YgY2hhcmFjdGVycywgY29weSBvdmVyIHdoYXQgd2UgaGF2ZSBzbyBmYXIuCisgIGlmIChsYXN0IDwgcF8uZGF0YSgpKSB7CisgICAgcGFyc2VkX3N0b3JhZ2VfLmFwcGVuZChsYXN0LCBwXy5kYXRhKCkgLSBsYXN0KTsKKyAgfQorICAvLyBJZiB3ZSBkaWRuJ3QgZmluZCB0aGUgY2xvc2luZyBxdW90ZSBidXQgd2UgZXhwZWN0IG1vcmUgZGF0YSwgY2FuY2VsIGZvciBub3cKKyAgaWYgKCFmaW5pc2hpbmdfKSB7CisgICAgcmV0dXJuIHV0aWw6OlN0YXR1czo6Q0FOQ0VMTEVEOworICB9CisgIC8vIEVuZCBvZiBzdHJpbmcgcmVhY2hlZCB3aXRob3V0IGEgY2xvc2luZyBxdW90ZSwgcmVwb3J0IGFuIGVycm9yLgorICBzdHJpbmdfb3Blbl8gPSAwOworICByZXR1cm4gUmVwb3J0RmFpbHVyZSgiQ2xvc2luZyBxdW90ZSBleHBlY3RlZCBpbiBzdHJpbmcuIik7Cit9CisKKy8vIENvbnZlcnRzIGEgdW5pY29kZSBlc2NhcGVkIGNoYXJhY3RlciB0byBhIGRlY2ltYWwgdmFsdWUgc3RvcmVkIGluIGEgY2hhcjMyCisvLyBmb3IgdXNlIGluIFVURjggZW5jb2RpbmcgdXRpbGl0eS4gIFdlIGFzc3VtZSB0aGF0IHN0ciBiZWdpbnMgd2l0aCBcdWhoaGggYW5kCisvLyBjb252ZXJ0IHRoYXQgZnJvbSB0aGUgaGV4IG51bWJlciB0byBhIGRlY2ltYWwgdmFsdWUuCisvLworLy8gVGhlcmUgYXJlIHNvbWUgc2VjdXJpdHkgZXhwbG9pdHMgd2l0aCBVVEYtOCB0aGF0IHdlIHNob3VsZCBiZSBjYXJlZnVsIG9mOgorLy8gICAtIGh0dHA6Ly93d3cudW5pY29kZS5vcmcvcmVwb3J0cy90cjM2LyNVVEYtOF9FeHBsb2l0CisvLyAgIC0gaHR0cDovL3NpdGVzL2ludGwtZW5nL2Rlc2lnbi1ndWlkZS9jb3JlLWFwcGxpY2F0aW9uCit1dGlsOjpTdGF0dXMgSnNvblN0cmVhbVBhcnNlcjo6UGFyc2VVbmljb2RlRXNjYXBlKCkgeworICBpZiAocF8ubGVuZ3RoKCkgPCBrVW5pY29kZUVzY2FwZWRMZW5ndGgpIHsKKyAgICBpZiAoIWZpbmlzaGluZ18pIHsKKyAgICAgIHJldHVybiB1dGlsOjpTdGF0dXM6OkNBTkNFTExFRDsKKyAgICB9CisgICAgcmV0dXJuIFJlcG9ydEZhaWx1cmUoIklsbGVnYWwgaGV4IHN0cmluZy4iKTsKKyAgfQorICBHT09HTEVfRENIRUNLX0VRKCdcXCcsIHBfLmRhdGEoKVswXSk7CisgIEdPT0dMRV9EQ0hFQ0tfRVEoJ3UnLCBwXy5kYXRhKClbMV0pOworICB1aW50MzIgY29kZSA9IDA7CisgIGZvciAoaW50IGkgPSAyOyBpIDwga1VuaWNvZGVFc2NhcGVkTGVuZ3RoOyArK2kpIHsKKyAgICBpZiAoIWlzeGRpZ2l0KHBfLmRhdGEoKVtpXSkpIHsKKyAgICAgIHJldHVybiBSZXBvcnRGYWlsdXJlKCJJbnZhbGlkIGVzY2FwZSBzZXF1ZW5jZS4iKTsKKyAgICB9CisgICAgY29kZSA9IChjb2RlIDw8IDQpICsgaGV4X2RpZ2l0X3RvX2ludChwXy5kYXRhKClbaV0pOworICB9CisgIGNoYXIgYnVmW1VURm1heF07CisgIGludCBsZW4gPSBFbmNvZGVBc1VURjhDaGFyKGNvZGUsIGJ1Zik7CisgIC8vIEFkdmFuY2UgcGFzdCB0aGUgdW5pY29kZSBlc2NhcGUuCisgIHBfLnJlbW92ZV9wcmVmaXgoa1VuaWNvZGVFc2NhcGVkTGVuZ3RoKTsKKyAgcGFyc2VkX3N0b3JhZ2VfLmFwcGVuZChidWYsIGxlbik7CisgIHJldHVybiB1dGlsOjpTdGF0dXM6Ok9LOworfQorCit1dGlsOjpTdGF0dXMgSnNvblN0cmVhbVBhcnNlcjo6UGFyc2VOdW1iZXIoKSB7CisgIE51bWJlclJlc3VsdCBudW1iZXI7CisgIHV0aWw6OlN0YXR1cyByZXN1bHQgPSBQYXJzZU51bWJlckhlbHBlcigmbnVtYmVyKTsKKyAgaWYgKHJlc3VsdC5vaygpKSB7CisgICAgc3dpdGNoIChudW1iZXIudHlwZSkgeworICAgICAgY2FzZSBOdW1iZXJSZXN1bHQ6OkRPVUJMRToKKyAgICAgICAgb3dfLT5SZW5kZXJEb3VibGUoa2V5XywgbnVtYmVyLmRvdWJsZV92YWwpOworICAgICAgICBrZXlfLmNsZWFyKCk7CisgICAgICAgIGJyZWFrOworCisgICAgICBjYXNlIE51bWJlclJlc3VsdDo6SU5UOgorICAgICAgICBvd18tPlJlbmRlckludDY0KGtleV8sIG51bWJlci5pbnRfdmFsKTsKKyAgICAgICAga2V5Xy5jbGVhcigpOworICAgICAgICBicmVhazsKKworICAgICAgY2FzZSBOdW1iZXJSZXN1bHQ6OlVJTlQ6CisgICAgICAgIG93Xy0+UmVuZGVyVWludDY0KGtleV8sIG51bWJlci51aW50X3ZhbCk7CisgICAgICAgIGtleV8uY2xlYXIoKTsKKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHJldHVybiBSZXBvcnRGYWlsdXJlKCJVbmFibGUgdG8gcGFyc2UgbnVtYmVyLiIpOworICAgIH0KKyAgfQorICByZXR1cm4gcmVzdWx0OworfQorCit1dGlsOjpTdGF0dXMgSnNvblN0cmVhbVBhcnNlcjo6UGFyc2VOdW1iZXJIZWxwZXIoTnVtYmVyUmVzdWx0KiByZXN1bHQpIHsKKyAgY29uc3QgY2hhciogZGF0YSA9IHBfLmRhdGEoKTsKKyAgaW50IGxlbmd0aCA9IHBfLmxlbmd0aCgpOworCisgIC8vIExvb2sgZm9yIHRoZSBmaXJzdCBub24tbnVtZXJpYyBjaGFyYWN0ZXIsIG9yIHRoZSBlbmQgb2YgdGhlIHN0cmluZy4KKyAgaW50IGluZGV4ID0gMDsKKyAgYm9vbCBmbG9hdGluZyA9IGZhbHNlOworICBib29sIG5lZ2F0aXZlID0gZGF0YVtpbmRleF0gPT0gJy0nOworICAvLyBGaW5kIHRoZSBmaXJzdCBjaGFyYWN0ZXIgdGhhdCBjYW5ub3QgYmUgcGFydCBvZiB0aGUgbnVtYmVyLiBBbG9uZyB0aGUgd2F5CisgIC8vIGRldGVjdCBpZiB0aGUgbnVtYmVyIG5lZWRzIHRvIGJlIHBhcnNlZCBhcyBhIGRvdWJsZS4KKyAgLy8gTm90ZSB0aGF0IHRoaXMgcmVzdHJpY3RzIG51bWJlcnMgdG8gdGhlIEpTT04gc3BlY2lmaWNhdGlvbiwgc28gZm9yIGV4YW1wbGUKKyAgLy8gd2UgZG8gbm90IHN1cHBvcnQgaGV4IG9yIG9jdGFsIG5vdGF0aW9ucy4KKyAgZm9yICg7IGluZGV4IDwgbGVuZ3RoOyArK2luZGV4KSB7CisgICAgY2hhciBjID0gZGF0YVtpbmRleF07CisgICAgaWYgKGlzZGlnaXQoYykpIGNvbnRpbnVlOworICAgIGlmIChjID09ICcuJyB8fCBjID09ICdlJyB8fCBjID09ICdFJykgeworICAgICAgZmxvYXRpbmcgPSB0cnVlOworICAgICAgY29udGludWU7CisgICAgfQorICAgIGlmIChjID09ICcrJyB8fCBjID09ICctJykgY29udGludWU7CisgICAgLy8gTm90IGEgdmFsaWQgbnVtYmVyIGNoYXJhY3RlciwgYnJlYWsgb3V0LgorICAgIGJyZWFrOworICB9CisKKyAgLy8gSWYgdGhlIGVudGlyZSBpbnB1dCBpcyBhIHZhbGlkIG51bWJlciwgYW5kIHdlIG1heSBoYXZlIG1vcmUgY29udGVudCBpbiB0aGUKKyAgLy8gZnV0dXJlLCB3ZSBhYm9ydCBmb3Igbm93IGFuZCByZXN1bWUgd2hlbiB3ZSBrbm93IG1vcmUuCisgIGlmIChpbmRleCA9PSBsZW5ndGggJiYgIWZpbmlzaGluZ18pIHsKKyAgICByZXR1cm4gdXRpbDo6U3RhdHVzOjpDQU5DRUxMRUQ7CisgIH0KKworICAvLyBDcmVhdGUgYSBzdHJpbmcgY29udGFpbmluZyBqdXN0IHRoZSBudW1iZXIsIHNvIHdlIGNhbiB1c2Ugc2FmZV9zdHJ0b1gKKyAgc3RyaW5nIG51bWJlciA9IHBfLnN1YnN0cigwLCBpbmRleCkuVG9TdHJpbmcoKTsKKworICAvLyBGbG9hdGluZyBwb2ludCBudW1iZXIsIHBhcnNlIGFzIGEgZG91YmxlLgorICBpZiAoZmxvYXRpbmcpIHsKKyAgICBpZiAoIXNhZmVfc3RydG9kKG51bWJlciwgJnJlc3VsdC0+ZG91YmxlX3ZhbCkpIHsKKyAgICAgIHJldHVybiBSZXBvcnRGYWlsdXJlKCJVbmFibGUgdG8gcGFyc2UgbnVtYmVyLiIpOworICAgIH0KKyAgICByZXN1bHQtPnR5cGUgPSBOdW1iZXJSZXN1bHQ6OkRPVUJMRTsKKyAgICBwXy5yZW1vdmVfcHJlZml4KGluZGV4KTsKKyAgICByZXR1cm4gdXRpbDo6U3RhdHVzOjpPSzsKKyAgfQorCisgIC8vIFBvc2l0aXZlIG5vbi1mbG9hdGluZyBwb2ludCBudW1iZXIsIHBhcnNlIGFzIGEgdWludDY0LgorICBpZiAoIW5lZ2F0aXZlKSB7CisgICAgaWYgKCFzYWZlX3N0cnRvdTY0KG51bWJlciwgJnJlc3VsdC0+dWludF92YWwpKSB7CisgICAgICByZXR1cm4gUmVwb3J0RmFpbHVyZSgiVW5hYmxlIHRvIHBhcnNlIG51bWJlci4iKTsKKyAgICB9CisgICAgcmVzdWx0LT50eXBlID0gTnVtYmVyUmVzdWx0OjpVSU5UOworICAgIHBfLnJlbW92ZV9wcmVmaXgoaW5kZXgpOworICAgIHJldHVybiB1dGlsOjpTdGF0dXM6Ok9LOworICB9CisKKyAgLy8gTmVnYXRpdmUgbm9uLWZsb2F0aW5nIHBvaW50IG51bWJlciwgcGFyc2UgYXMgYW4gaW50NjQuCisgIGlmICghc2FmZV9zdHJ0bzY0KG51bWJlciwgJnJlc3VsdC0+aW50X3ZhbCkpIHsKKyAgICByZXR1cm4gUmVwb3J0RmFpbHVyZSgiVW5hYmxlIHRvIHBhcnNlIG51bWJlci4iKTsKKyAgfQorICByZXN1bHQtPnR5cGUgPSBOdW1iZXJSZXN1bHQ6OklOVDsKKyAgcF8ucmVtb3ZlX3ByZWZpeChpbmRleCk7CisgIHJldHVybiB1dGlsOjpTdGF0dXM6Ok9LOworfQorCit1dGlsOjpTdGF0dXMgSnNvblN0cmVhbVBhcnNlcjo6SGFuZGxlQmVnaW5PYmplY3QoKSB7CisgIEdPT0dMRV9EQ0hFQ0tfRVEoJ3snLCAqcF8uZGF0YSgpKTsKKyAgQWR2YW5jZSgpOworICBvd18tPlN0YXJ0T2JqZWN0KGtleV8pOworICBrZXlfLmNsZWFyKCk7CisgIHN0YWNrXy5wdXNoKEVOVFJZKTsKKyAgcmV0dXJuIHV0aWw6OlN0YXR1czo6T0s7Cit9CisKK3V0aWw6OlN0YXR1cyBKc29uU3RyZWFtUGFyc2VyOjpQYXJzZU9iamVjdE1pZChUb2tlblR5cGUgdHlwZSkgeworICBpZiAodHlwZSA9PSBVTktOT1dOKSB7CisgICAgcmV0dXJuIFJlcG9ydFVua25vd24oIkV4cGVjdGVkICwgb3IgfSBhZnRlciBrZXk6dmFsdWUgcGFpci4iKTsKKyAgfQorCisgIC8vIE9iamVjdCBpcyBjb21wbGV0ZSwgYWR2YW5jZSBwYXN0IHRoZSBjb21tYSBhbmQgcmVuZGVyIHRoZSBFbmRPYmplY3QuCisgIGlmICh0eXBlID09IEVORF9PQkpFQ1QpIHsKKyAgICBBZHZhbmNlKCk7CisgICAgb3dfLT5FbmRPYmplY3QoKTsKKyAgICByZXR1cm4gdXRpbDo6U3RhdHVzOjpPSzsKKyAgfQorICAvLyBGb3VuZCBhIGNvbW1hLCBhZHZhbmNlIHBhc3QgaXQgYW5kIGdldCByZWFkeSBmb3IgYW4gZW50cnkuCisgIGlmICh0eXBlID09IFZBTFVFX1NFUEFSQVRPUikgeworICAgIEFkdmFuY2UoKTsKKyAgICBzdGFja18ucHVzaChFTlRSWSk7CisgICAgcmV0dXJuIHV0aWw6OlN0YXR1czo6T0s7CisgIH0KKyAgLy8gSWxsZWdhbCB0b2tlbiBhZnRlciBrZXk6dmFsdWUgcGFpci4KKyAgcmV0dXJuIFJlcG9ydEZhaWx1cmUoIkV4cGVjdGVkICwgb3IgfSBhZnRlciBrZXk6dmFsdWUgcGFpci4iKTsKK30KKwordXRpbDo6U3RhdHVzIEpzb25TdHJlYW1QYXJzZXI6OlBhcnNlRW50cnkoVG9rZW5UeXBlIHR5cGUpIHsKKyAgaWYgKHR5cGUgPT0gVU5LTk9XTikgeworICAgIHJldHVybiBSZXBvcnRVbmtub3duKCJFeHBlY3RlZCBhbiBvYmplY3Qga2V5IG9yIH0uIik7CisgIH0KKworICAvLyBDbG9zZSB0aGUgb2JqZWN0IGFuZCByZXR1cm4uIFRoaXMgYWxsb3dzIGZvciB0cmFpbGluZyBjb21tYXMuCisgIGlmICh0eXBlID09IEVORF9PQkpFQ1QpIHsKKyAgICBvd18tPkVuZE9iamVjdCgpOworICAgIEFkdmFuY2UoKTsKKyAgICByZXR1cm4gdXRpbDo6U3RhdHVzOjpPSzsKKyAgfQorCisgIHV0aWw6OlN0YXR1cyByZXN1bHQ7CisgIGlmICh0eXBlID09IEJFR0lOX1NUUklORykgeworICAgIC8vIEtleSBpcyBhIHN0cmluZyAoc3RhbmRhcmQgSlNPTiksIHBhcnNlIGl0IGFuZCBzdG9yZSB0aGUgc3RyaW5nLgorICAgIHJlc3VsdCA9IFBhcnNlU3RyaW5nSGVscGVyKCk7CisgICAgaWYgKHJlc3VsdC5vaygpKSB7CisgICAgICBrZXlfc3RvcmFnZV8uY2xlYXIoKTsKKyAgICAgIGlmICghcGFyc2VkX3N0b3JhZ2VfLmVtcHR5KCkpIHsKKyAgICAgICAgcGFyc2VkX3N0b3JhZ2VfLnN3YXAoa2V5X3N0b3JhZ2VfKTsKKyAgICAgICAga2V5XyA9IFN0cmluZ1BpZWNlKGtleV9zdG9yYWdlXyk7CisgICAgICB9IGVsc2UgeworICAgICAgICBrZXlfID0gcGFyc2VkXzsKKyAgICAgIH0KKyAgICAgIHBhcnNlZF8uY2xlYXIoKTsKKyAgICB9CisgIH0gZWxzZSBpZiAodHlwZSA9PSBCRUdJTl9LRVkpIHsKKyAgICAvLyBLZXkgaXMgYSBiYXJlIGtleSAoYmFjayBjb21wYXQpLCBjcmVhdGUgYSBTdHJpbmdQaWVjZSBwb2ludGluZyB0byBpdC4KKyAgICByZXN1bHQgPSBQYXJzZUtleSgpOworICB9IGVsc2UgeworICAgIC8vIFVua25vd24ga2V5IHR5cGUsIHJlcG9ydCBhbiBlcnJvci4KKyAgICByZXN1bHQgPSBSZXBvcnRGYWlsdXJlKCJFeHBlY3RlZCBhbiBvYmplY3Qga2V5IG9yIH0uIik7CisgIH0KKyAgLy8gT24gc3VjY2VzcyB3ZSBuZXh0IGV4cGVjdCBhbiBlbnRyeSBtaWQgJzonIHRoZW4gYW4gb2JqZWN0IG1pZCAnLCcgb3IgJ30nCisgIGlmIChyZXN1bHQub2soKSkgeworICAgIHN0YWNrXy5wdXNoKE9CSl9NSUQpOworICAgIHN0YWNrXy5wdXNoKEVOVFJZX01JRCk7CisgIH0KKyAgcmV0dXJuIHJlc3VsdDsKK30KKwordXRpbDo6U3RhdHVzIEpzb25TdHJlYW1QYXJzZXI6OlBhcnNlRW50cnlNaWQoVG9rZW5UeXBlIHR5cGUpIHsKKyAgaWYgKHR5cGUgPT0gVU5LTk9XTikgeworICAgIHJldHVybiBSZXBvcnRVbmtub3duKCJFeHBlY3RlZCA6IGJldHdlZW4ga2V5OnZhbHVlIHBhaXIuIik7CisgIH0KKyAgaWYgKHR5cGUgPT0gRU5UUllfU0VQQVJBVE9SKSB7CisgICAgQWR2YW5jZSgpOworICAgIHN0YWNrXy5wdXNoKFZBTFVFKTsKKyAgICByZXR1cm4gdXRpbDo6U3RhdHVzOjpPSzsKKyAgfQorICByZXR1cm4gUmVwb3J0RmFpbHVyZSgiRXhwZWN0ZWQgOiBiZXR3ZWVuIGtleTp2YWx1ZSBwYWlyLiIpOworfQorCit1dGlsOjpTdGF0dXMgSnNvblN0cmVhbVBhcnNlcjo6SGFuZGxlQmVnaW5BcnJheSgpIHsKKyAgR09PR0xFX0RDSEVDS19FUSgnWycsICpwXy5kYXRhKCkpOworICBBZHZhbmNlKCk7CisgIG93Xy0+U3RhcnRMaXN0KGtleV8pOworICBrZXlfLmNsZWFyKCk7CisgIHN0YWNrXy5wdXNoKEFSUkFZX1ZBTFVFKTsKKyAgcmV0dXJuIHV0aWw6OlN0YXR1czo6T0s7Cit9CisKK3V0aWw6OlN0YXR1cyBKc29uU3RyZWFtUGFyc2VyOjpQYXJzZUFycmF5VmFsdWUoVG9rZW5UeXBlIHR5cGUpIHsKKyAgaWYgKHR5cGUgPT0gVU5LTk9XTikgeworICAgIHJldHVybiBSZXBvcnRVbmtub3duKCJFeHBlY3RlZCBhIHZhbHVlIG9yIF0gd2l0aGluIGFuIGFycmF5LiIpOworICB9CisKKyAgaWYgKHR5cGUgPT0gRU5EX0FSUkFZKSB7CisgICAgb3dfLT5FbmRMaXN0KCk7CisgICAgQWR2YW5jZSgpOworICAgIHJldHVybiB1dGlsOjpTdGF0dXM6Ok9LOworICB9CisKKyAgLy8gVGhlIFBhcnNlVmFsdWUgY2FsbCBtYXkgcHVzaCBzb21ldGhpbmcgb250byB0aGUgc3RhY2sgc28gd2UgbmVlZCB0byBtYWtlCisgIC8vIHN1cmUgYW4gQVJSQVlfTUlEIGlzIGFmdGVyIGl0LCBzbyB3ZSBwdXNoIGl0IG9uIG5vdy4KKyAgc3RhY2tfLnB1c2goQVJSQVlfTUlEKTsKKyAgdXRpbDo6U3RhdHVzIHJlc3VsdCA9IFBhcnNlVmFsdWUodHlwZSk7CisgIGlmIChyZXN1bHQgPT0gdXRpbDo6U3RhdHVzOjpDQU5DRUxMRUQpIHsKKyAgICAvLyBJZiB3ZSB3ZXJlIGNhbmNlbGxlZCwgcG9wIGJhY2sgb2ZmIHRoZSBBUlJBWV9NSUQgc28gd2UgZG9uJ3QgdHJ5IHRvCisgICAgLy8gcHVzaCBpdCBvbiBhZ2FpbiB3aGVuIHdlIHRyeSBvdmVyLgorICAgIHN0YWNrXy5wb3AoKTsKKyAgfQorICByZXR1cm4gcmVzdWx0OworfQorCit1dGlsOjpTdGF0dXMgSnNvblN0cmVhbVBhcnNlcjo6UGFyc2VBcnJheU1pZChUb2tlblR5cGUgdHlwZSkgeworICBpZiAodHlwZSA9PSBVTktOT1dOKSB7CisgICAgcmV0dXJuIFJlcG9ydFVua25vd24oIkV4cGVjdGVkICwgb3IgXSBhZnRlciBhcnJheSB2YWx1ZS4iKTsKKyAgfQorCisgIGlmICh0eXBlID09IEVORF9BUlJBWSkgeworICAgIG93Xy0+RW5kTGlzdCgpOworICAgIEFkdmFuY2UoKTsKKyAgICByZXR1cm4gdXRpbDo6U3RhdHVzOjpPSzsKKyAgfQorCisgIC8vIEZvdW5kIGEgY29tbWEsIGFkdmFuY2UgcGFzdCBpdCBhbmQgZXhwZWN0IGFuIGFycmF5IHZhbHVlIG5leHQuCisgIGlmICh0eXBlID09IFZBTFVFX1NFUEFSQVRPUikgeworICAgIEFkdmFuY2UoKTsKKyAgICBzdGFja18ucHVzaChBUlJBWV9WQUxVRSk7CisgICAgcmV0dXJuIHV0aWw6OlN0YXR1czo6T0s7CisgIH0KKyAgLy8gSWxsZWdhbCB0b2tlbiBhZnRlciBhcnJheSB2YWx1ZS4KKyAgcmV0dXJuIFJlcG9ydEZhaWx1cmUoIkV4cGVjdGVkICwgb3IgXSBhZnRlciBhcnJheSB2YWx1ZS4iKTsKK30KKwordXRpbDo6U3RhdHVzIEpzb25TdHJlYW1QYXJzZXI6OlBhcnNlVHJ1ZSgpIHsKKyAgb3dfLT5SZW5kZXJCb29sKGtleV8sIHRydWUpOworICBrZXlfLmNsZWFyKCk7CisgIHBfLnJlbW92ZV9wcmVmaXgodHJ1ZV9sZW4pOworICByZXR1cm4gdXRpbDo6U3RhdHVzOjpPSzsKK30KKwordXRpbDo6U3RhdHVzIEpzb25TdHJlYW1QYXJzZXI6OlBhcnNlRmFsc2UoKSB7CisgIG93Xy0+UmVuZGVyQm9vbChrZXlfLCBmYWxzZSk7CisgIGtleV8uY2xlYXIoKTsKKyAgcF8ucmVtb3ZlX3ByZWZpeChmYWxzZV9sZW4pOworICByZXR1cm4gdXRpbDo6U3RhdHVzOjpPSzsKK30KKwordXRpbDo6U3RhdHVzIEpzb25TdHJlYW1QYXJzZXI6OlBhcnNlTnVsbCgpIHsKKyAgb3dfLT5SZW5kZXJOdWxsKGtleV8pOworICBrZXlfLmNsZWFyKCk7CisgIHBfLnJlbW92ZV9wcmVmaXgobnVsbF9sZW4pOworICByZXR1cm4gdXRpbDo6U3RhdHVzOjpPSzsKK30KKwordXRpbDo6U3RhdHVzIEpzb25TdHJlYW1QYXJzZXI6OlJlcG9ydEZhaWx1cmUoU3RyaW5nUGllY2UgbWVzc2FnZSkgeworICBzdGF0aWMgY29uc3QgaW50IGtDb250ZXh0TGVuZ3RoID0gMjA7CisgIGNvbnN0IGNoYXIqIHBfc3RhcnQgPSBwXy5kYXRhKCk7CisgIGNvbnN0IGNoYXIqIGpzb25fc3RhcnQgPSBqc29uXy5kYXRhKCk7CisgIGNvbnN0IGNoYXIqIGJlZ2luID0gbWF4KHBfc3RhcnQgLSBrQ29udGV4dExlbmd0aCwganNvbl9zdGFydCk7CisgIGNvbnN0IGNoYXIqIGVuZCA9IG1pbihwX3N0YXJ0ICsga0NvbnRleHRMZW5ndGgsIGpzb25fc3RhcnQgKyBqc29uXy5zaXplKCkpOworICBTdHJpbmdQaWVjZSBzZWdtZW50KGJlZ2luLCBlbmQgLSBiZWdpbik7CisgIHN0cmluZyBsb2NhdGlvbihwX3N0YXJ0IC0gYmVnaW4sICcgJyk7CisgIGxvY2F0aW9uLnB1c2hfYmFjaygnXicpOworICByZXR1cm4gdXRpbDo6U3RhdHVzKHV0aWw6OmVycm9yOjpJTlZBTElEX0FSR1VNRU5ULAorICAgICAgICAgICAgICAgICAgICAgIFN0ckNhdChtZXNzYWdlLCAiXG4iLCBzZWdtZW50LCAiXG4iLCBsb2NhdGlvbikpOworfQorCit1dGlsOjpTdGF0dXMgSnNvblN0cmVhbVBhcnNlcjo6UmVwb3J0VW5rbm93bihTdHJpbmdQaWVjZSBtZXNzYWdlKSB7CisgIC8vIElmIHdlIGFyZW4ndCBmaW5pc2hpbmcgdGhlIHBhcnNlLCBjYW5jZWwgcGFyc2luZyBhbmQgdHJ5IGxhdGVyLgorICBpZiAoIWZpbmlzaGluZ18pIHsKKyAgICByZXR1cm4gdXRpbDo6U3RhdHVzOjpDQU5DRUxMRUQ7CisgIH0KKyAgaWYgKHBfLmVtcHR5KCkpIHsKKyAgICByZXR1cm4gUmVwb3J0RmFpbHVyZShTdHJDYXQoIlVuZXhwZWN0ZWQgZW5kIG9mIHN0cmluZy4gIiwgbWVzc2FnZSkpOworICB9CisgIHJldHVybiBSZXBvcnRGYWlsdXJlKG1lc3NhZ2UpOworfQorCit2b2lkIEpzb25TdHJlYW1QYXJzZXI6OlNraXBXaGl0ZXNwYWNlKCkgeworICB3aGlsZSAoIXBfLmVtcHR5KCkgJiYgYXNjaWlfaXNzcGFjZSgqcF8uZGF0YSgpKSkgeworICAgIEFkdmFuY2UoKTsKKyAgfQorfQorCit2b2lkIEpzb25TdHJlYW1QYXJzZXI6OkFkdmFuY2UoKSB7CisgIC8vIEFkdmFuY2UgYnkgbW92aW5nIG9uZSBVVEY4IGNoYXJhY3RlciB3aGlsZSBtYWtpbmcgc3VyZSB3ZSBkb24ndCBnbyBiZXlvbmQKKyAgLy8gdGhlIGxlbmd0aCBvZiBTdHJpbmdQaWVjZS4KKyAgcF8ucmVtb3ZlX3ByZWZpeCgKKyAgICAgIG1pbjxpbnQ+KHBfLmxlbmd0aCgpLCBVVEY4Rmlyc3RMZXR0ZXJOdW1CeXRlcyhwXy5kYXRhKCksIHBfLmxlbmd0aCgpKSkpOworfQorCit1dGlsOjpTdGF0dXMgSnNvblN0cmVhbVBhcnNlcjo6UGFyc2VLZXkoKSB7CisgIFN0cmluZ1BpZWNlIG9yaWdpbmFsID0gcF87CisgIGlmICghQ29uc3VtZUtleSgmcF8sICZrZXlfKSkgeworICAgIHJldHVybiBSZXBvcnRGYWlsdXJlKCJJbnZhbGlkIGtleSBvciB2YXJpYWJsZSBuYW1lLiIpOworICB9CisgIC8vIElmIHdlIGNvbnN1bWVkIGV2ZXJ5dGhpbmcgYnV0IGV4cGVjdCBtb3JlIGRhdGEsIHJlc2V0IHBfIGFuZCBjYW5jZWwgc2luY2UKKyAgLy8gd2UgY2FuJ3Qga25vdyBpZiB0aGUga2V5IHdhcyBjb21wbGV0ZSBvciBub3QuCisgIGlmICghZmluaXNoaW5nXyAmJiBwXy5lbXB0eSgpKSB7CisgICAgcF8gPSBvcmlnaW5hbDsKKyAgICByZXR1cm4gdXRpbDo6U3RhdHVzOjpDQU5DRUxMRUQ7CisgIH0KKyAgLy8gU2luY2Ugd2UgYXJlbid0IHVzaW5nIHRoZSBrZXkgc3RvcmFnZSwgY2xlYXIgaXQgb3V0LgorICBrZXlfc3RvcmFnZV8uY2xlYXIoKTsKKyAgcmV0dXJuIHV0aWw6OlN0YXR1czo6T0s7Cit9CisKK0pzb25TdHJlYW1QYXJzZXI6OlRva2VuVHlwZSBKc29uU3RyZWFtUGFyc2VyOjpHZXROZXh0VG9rZW5UeXBlKCkgeworICBTa2lwV2hpdGVzcGFjZSgpOworCisgIGludCBzaXplID0gcF8uc2l6ZSgpOworICBpZiAoc2l6ZSA9PSAwKSB7CisgICAgLy8gSWYgd2UgcmFuIG91dCBvZiBkYXRhLCByZXBvcnQgdW5rbm93biBhbmQgd2UnbGwgcGxhY2UgdGhlIHByZXZpb3VzIHBhcnNlCisgICAgLy8gdHlwZSBvbnRvIHRoZSBzdGFjayBhbmQgdHJ5IGFnYWluIHdoZW4gd2UgaGF2ZSBtb3JlIGRhdGEuCisgICAgcmV0dXJuIFVOS05PV047CisgIH0KKyAgLy8gVE9ETyhzdmVuKTogU3BsaXQgdGhpcyBtZXRob2QgYmFzZWQgb24gY29udGV4dCBzaW5jZSBkaWZmZXJlbnQgY29udGV4dHMKKyAgLy8gc3VwcG9ydCBkaWZmZXJlbnQgdG9rZW5zLiBXb3VsZCBzbGlnaHRseSBzcGVlZCB1cCBwcm9jZXNzaW5nPworICBjb25zdCBjaGFyKiBkYXRhID0gcF8uZGF0YSgpOworICBpZiAoKmRhdGEgPT0gJ1wiJyB8fCAqZGF0YSA9PSAnXCcnKSByZXR1cm4gQkVHSU5fU1RSSU5HOworICBpZiAoKmRhdGEgPT0gJy0nIHx8ICgnMCcgPD0gKmRhdGEgJiYgKmRhdGEgPD0gJzknKSkgeworICAgIHJldHVybiBCRUdJTl9OVU1CRVI7CisgIH0KKyAgaWYgKHNpemUgPj0gdHJ1ZV9sZW4gJiYgIXN0cm5jbXAoZGF0YSwgInRydWUiLCB0cnVlX2xlbikpIHsKKyAgICByZXR1cm4gQkVHSU5fVFJVRTsKKyAgfQorICBpZiAoc2l6ZSA+PSBmYWxzZV9sZW4gJiYgIXN0cm5jbXAoZGF0YSwgImZhbHNlIiwgZmFsc2VfbGVuKSkgeworICAgIHJldHVybiBCRUdJTl9GQUxTRTsKKyAgfQorICBpZiAoc2l6ZSA+PSBudWxsX2xlbiAmJiAhc3RybmNtcChkYXRhLCAibnVsbCIsIG51bGxfbGVuKSkgeworICAgIHJldHVybiBCRUdJTl9OVUxMOworICB9CisgIGlmICgqZGF0YSA9PSAneycpIHJldHVybiBCRUdJTl9PQkpFQ1Q7CisgIGlmICgqZGF0YSA9PSAnfScpIHJldHVybiBFTkRfT0JKRUNUOworICBpZiAoKmRhdGEgPT0gJ1snKSByZXR1cm4gQkVHSU5fQVJSQVk7CisgIGlmICgqZGF0YSA9PSAnXScpIHJldHVybiBFTkRfQVJSQVk7CisgIGlmICgqZGF0YSA9PSAnOicpIHJldHVybiBFTlRSWV9TRVBBUkFUT1I7CisgIGlmICgqZGF0YSA9PSAnLCcpIHJldHVybiBWQUxVRV9TRVBBUkFUT1I7CisgIGlmIChNYXRjaEtleShwXykpIHsKKyAgICByZXR1cm4gQkVHSU5fS0VZOworICB9CisKKyAgLy8gV2UgZG9uJ3Qga25vdyB0aGF0IHdlIG5lY2Vzc2FyaWx5IGhhdmUgYW4gaW52YWxpZCB0b2tlbiBoZXJlLCBqdXN0IHRoYXQgd2UKKyAgLy8gY2FuJ3QgcGFyc2Ugd2hhdCB3ZSBoYXZlIHNvIGZhci4gU28gd2UgZG9uJ3QgcmVwb3J0IGFuIGVycm9yIGFuZCBqdXN0CisgIC8vIHJldHVybiBVTktOT1dOIHNvIHdlIGNhbiB0cnkgYWdhaW4gbGF0ZXIgd2hlbiB3ZSBoYXZlIG1vcmUgZGF0YSwgb3IgaWYgd2UKKyAgLy8gZmluaXNoIGFuZCB3ZSBoYXZlIGxlZnRvdmVycy4KKyAgcmV0dXJuIFVOS05PV047Cit9CisKK30gIC8vIG5hbWVzcGFjZSBjb252ZXJ0ZXIKK30gIC8vIG5hbWVzcGFjZSB1dGlsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9qc29uX3N0cmVhbV9wYXJzZXIuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9qc29uX3N0cmVhbV9wYXJzZXIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMjc4YzI4Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL2pzb25fc3RyZWFtX3BhcnNlci5oCkBAIC0wLDAgKzEsMjU4IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfVVRJTF9DT05WRVJURVJfSlNPTl9TVFJFQU1fUEFSU0VSX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfVVRJTF9DT05WRVJURVJfSlNPTl9TVFJFQU1fUEFSU0VSX0hfXworCisjaW5jbHVkZSA8c3RhY2s+CisjaW5jbHVkZSA8c3RyaW5nPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJpbmdwaWVjZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdGF0dXMuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgdXRpbCB7CitjbGFzcyBTdGF0dXM7Cit9ICAvLyBuYW1lc3BhY2UgdXRpbAorCituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIHV0aWwgeworbmFtZXNwYWNlIGNvbnZlcnRlciB7CisKK2NsYXNzIE9iamVjdFdyaXRlcjsKKworLy8gQSBKU09OIHBhcnNlciB0aGF0IGNhbiBwYXJzZSBhIHN0cmVhbSBvZiBKU09OIGNodW5rcyByYXRoZXIgdGhhbiBuZWVkaW5nIHRoZQorLy8gZW50aXJlIEpTT04gc3RyaW5nIHVwIGZyb250LiBJdCBpcyBhIG1vZGlmaWVkIHZlcnNpb24gb2YgdGhlIHBhcnNlciBpbgorLy8gLy9uZXQvcHJvdG8vanNvbi9qc29uLXBhcnNlci5oIHRoYXQgaGFzIGJlZW4gY2hhbmdlZCBpbiB0aGUgZm9sbG93aW5nIHdheXM6CisvLyAtIENoYW5nZWQgZnJvbSByZWN1cnNpb24gdG8gYW4gZXhwbGljaXQgc3RhY2sgdG8gYWxsb3cgcmVzdW1wdGlvbgorLy8gLSBBZGRlZCBzdXBwb3J0IGZvciBpbnQ2NCBhbmQgdWludDY0IG51bWJlcnMKKy8vIC0gUmVtb3ZlZCBzdXBwb3J0IGZvciBvY3RhbCBhbmQgZGVjaW1hbCBlc2NhcGVzCisvLyAtIFJlbW92ZWQgc3VwcG9ydCBmb3IgbnVtZXJpYyBrZXlzCisvLyAtIFJlbW92ZWQgc3VwcG9ydCBmb3IgZnVuY3Rpb25zIChqYXZhc2NyaXB0KQorLy8gLSBSZW1vdmVkIHNvbWUgbGF4LWNvbW1hIHN1cHBvcnQgKGJ1dCBrZXB0IHRyYWlsaW5nIGNvbW1hIHN1cHBvcnQpCisvLyAtIFdyaXRlcyBkaXJlY3RseSB0byBhbiBPYmplY3RXcml0ZXIgcmF0aGVyIHRoYW4gdXNpbmcgc3ViY2xhc3NpbmcKKy8vCisvLyBIZXJlIGlzIGFuIGV4YW1wbGUgdXNhZ2U6CisvLyBKc29uU3RyZWFtUGFyc2VyIHBhcnNlcihvd18uZ2V0KCkpOworLy8gdXRpbDo6U3RhdHVzIHJlc3VsdCA9IHBhcnNlci5QYXJzZShjaHVuazEpOworLy8gcmVzdWx0LlVwZGF0ZShwYXJzZXIuUGFyc2UoY2h1bmsyKSk7CisvLyByZXN1bHQuVXBkYXRlKHBhcnNlci5GaW5pc2hQYXJzZSgpKTsKKy8vIEdPT0dMRV9EQ0hFQ0socmVzdWx0Lm9rKCkpIDw8ICJGYWlsZWQgdG8gcGFyc2UgSlNPTiI7CisvLworLy8gVGhpcyBwYXJzZXIgaXMgdGhyZWFkLWNvbXBhdGlibGUgYXMgbG9uZyBhcyBvbmx5IG9uZSB0aHJlYWQgaXMgY2FsbGluZyBhCisvLyBQYXJzZSgpIG1ldGhvZCBhdCBhIHRpbWUuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgSnNvblN0cmVhbVBhcnNlciB7CisgcHVibGljOgorICAvLyBDcmVhdGVzIGEgSnNvblN0cmVhbVBhcnNlciB0aGF0IHdpbGwgd3JpdGUgdG8gdGhlIGdpdmVuIE9iamVjdFdyaXRlci4KKyAgZXhwbGljaXQgSnNvblN0cmVhbVBhcnNlcihPYmplY3RXcml0ZXIqIG93KTsKKyAgdmlydHVhbCB+SnNvblN0cmVhbVBhcnNlcigpOworCisgIC8vIFBhcnNlcyBhIFVURi04IGVuY29kZWQgSlNPTiBzdHJpbmcgZnJvbSBhIFN0cmluZ1BpZWNlLgorICB1dGlsOjpTdGF0dXMgUGFyc2UoU3RyaW5nUGllY2UganNvbik7CisKKworICAvLyBGaW5pc2ggcGFyc2luZyB0aGUgSlNPTiBzdHJpbmcuCisgIHV0aWw6OlN0YXR1cyBGaW5pc2hQYXJzZSgpOworCisKKyBwcml2YXRlOgorICBlbnVtIFRva2VuVHlwZSB7CisgICAgQkVHSU5fU1RSSU5HLCAgICAgLy8gIiBvciAnCisgICAgQkVHSU5fTlVNQkVSLCAgICAgLy8gLSBvciBkaWdpdAorICAgIEJFR0lOX1RSVUUsICAgICAgIC8vIHRydWUKKyAgICBCRUdJTl9GQUxTRSwgICAgICAvLyBmYWxzZQorICAgIEJFR0lOX05VTEwsICAgICAgIC8vIG51bGwKKyAgICBCRUdJTl9PQkpFQ1QsICAgICAvLyB7CisgICAgRU5EX09CSkVDVCwgICAgICAgLy8gfQorICAgIEJFR0lOX0FSUkFZLCAgICAgIC8vIFsKKyAgICBFTkRfQVJSQVksICAgICAgICAvLyBdCisgICAgRU5UUllfU0VQQVJBVE9SLCAgLy8gOgorICAgIFZBTFVFX1NFUEFSQVRPUiwgIC8vICwKKyAgICBCRUdJTl9LRVksICAgICAgICAvLyBsZXR0ZXIsIF8sICQgb3IgZGlnaXQuICBNdXN0IGJlZ2luIHdpdGggbm9uLWRpZ2l0CisgICAgVU5LTk9XTiAgICAgICAgICAgLy8gVW5rbm93biB0b2tlbiBvciB3ZSByYW4gb3V0IG9mIHRoZSBzdHJlYW0uCisgIH07CisKKyAgZW51bSBQYXJzZVR5cGUgeworICAgIFZBTFVFLCAgICAgICAgLy8gRXhwZWN0cyBhIHssIFssIHRydWUsIGZhbHNlLCBudWxsLCBzdHJpbmcgb3IgbnVtYmVyCisgICAgT0JKX01JRCwgICAgICAvLyBFeHBlY3RzIGEgJywnIG9yIH0KKyAgICBFTlRSWSwgICAgICAgIC8vIEV4cGVjdHMgYSBrZXkgb3IgfQorICAgIEVOVFJZX01JRCwgICAgLy8gRXhwZWN0cyBhIDoKKyAgICBBUlJBWV9WQUxVRSwgIC8vIEV4cGVjdHMgYSB2YWx1ZSBvciBdCisgICAgQVJSQVlfTUlEICAgICAvLyBFeHBlY3RzIGEgJywnIG9yIF0KKyAgfTsKKworICAvLyBIb2xkcyB0aGUgcmVzdWx0IG9mIHBhcnNpbmcgYSBudW1iZXIKKyAgc3RydWN0IE51bWJlclJlc3VsdCB7CisgICAgZW51bSBUeXBlIHsgRE9VQkxFLCBJTlQsIFVJTlQgfTsKKyAgICBUeXBlIHR5cGU7CisgICAgdW5pb24geworICAgICAgZG91YmxlIGRvdWJsZV92YWw7CisgICAgICBpbnQ2NCBpbnRfdmFsOworICAgICAgdWludDY0IHVpbnRfdmFsOworICAgIH07CisgIH07CisKKyAgLy8gUGFyc2VzIGEgc2luZ2xlIGNodW5rIG9mIEpTT04sIHJldHVybmluZyBhbiBlcnJvciBpZiB0aGUgSlNPTiB3YXMgaW52YWxpZC4KKyAgdXRpbDo6U3RhdHVzIFBhcnNlQ2h1bmsoU3RyaW5nUGllY2UganNvbik7CisKKyAgLy8gUnVucyB0aGUgcGFyc2VyIGJhc2VkIG9uIHN0YWNrXyBhbmQgcF8sIHVudGlsIHRoZSBzdGFjayBpcyBlbXB0eSBvciBwXyBydW5zCisgIC8vIG91dCBvZiBkYXRhLiBJZiB3ZSB1bmV4cGVjdGVkbHkgcnVuIG91dCBvZiBwXyB3ZSBwdXNoIHRoZSBsYXRlc3QgYmFjayBvbnRvCisgIC8vIHRoZSBzdGFjayBhbmQgcmV0dXJuLgorICB1dGlsOjpTdGF0dXMgUnVuUGFyc2VyKCk7CisKKyAgLy8gUGFyc2VzIGEgdmFsdWUgZnJvbSBwXyBhbmQgd3JpdGVzIGl0IHRvIG93Xy4KKyAgLy8gQSB2YWx1ZSBtYXkgYmUgYW4gb2JqZWN0LCBhcnJheSwgdHJ1ZSwgZmFsc2UsIG51bGwsIHN0cmluZyBvciBudW1iZXIuCisgIHV0aWw6OlN0YXR1cyBQYXJzZVZhbHVlKFRva2VuVHlwZSB0eXBlKTsKKworICAvLyBQYXJzZXMgYSBzdHJpbmcgYW5kIHdyaXRlcyBpdCBvdXQgdG8gdGhlIG93Xy4KKyAgdXRpbDo6U3RhdHVzIFBhcnNlU3RyaW5nKCk7CisKKyAgLy8gUGFyc2VzIGEgc3RyaW5nLCBzdG9yaW5nIHRoZSByZXN1bHQgaW4gcGFyc2VkXy4KKyAgdXRpbDo6U3RhdHVzIFBhcnNlU3RyaW5nSGVscGVyKCk7CisKKyAgLy8gVGhpcyBmdW5jdGlvbiBwYXJzZXMgdW5pY29kZSBlc2NhcGUgc2VxdWVuY2VzIGluIHN0cmluZ3MuIEl0IHJldHVybnMgYW4KKyAgLy8gZXJyb3Igd2hlbiB0aGVyZSdzIGEgcGFyc2luZyBlcnJvciwgZWl0aGVyIHRoZSBzaXplIGlzIG5vdCB0aGUgZXhwZWN0ZWQKKyAgLy8gc2l6ZSBvciBhIGNoYXJhY3RlciBpcyBub3QgYSBoZXggZGlnaXQuICBXaGVuIGl0IHJldHVybnMgc3RyIHdpbGwgY29udGFpbgorICAvLyB3aGF0IGhhcyBiZWVuIHN1Y2Nlc3NmdWxseSBwYXJzZWQgc28gZmFyLgorICB1dGlsOjpTdGF0dXMgUGFyc2VVbmljb2RlRXNjYXBlKCk7CisKKyAgLy8gRXhwZWN0cyBwXyB0byBwb2ludCB0byBhIEpTT04gbnVtYmVyLCB3cml0ZXMgdGhlIG51bWJlciB0byB0aGUgd3JpdGVyIHVzaW5nCisgIC8vIHRoZSBhcHByb3ByaWF0ZSBSZW5kZXIgbWV0aG9kIGJhc2VkIG9uIHRoZSB0eXBlIG9mIG51bWJlci4KKyAgdXRpbDo6U3RhdHVzIFBhcnNlTnVtYmVyKCk7CisKKyAgLy8gUGFyc2UgYSBudW1iZXIgaW50byBhIE51bWJlclJlc3VsdCwgcmVwb3J0aW5nIGFuIGVycm9yIGlmIG5vIG51bWJlciBjb3VsZAorICAvLyBiZSBwYXJzZWQuIFRoaXMgbWV0aG9kIHdpbGwgdHJ5IHRvIHBhcnNlIGludG8gYSB1aW50NjQsIGludDY0LCBvciBkb3VibGUKKyAgLy8gYmFzZWQgb24gd2hldGhlciB0aGUgbnVtYmVyIHdhcyBwb3NpdGl2ZSBvciBuZWdhdGl2ZSBvciBoYWQgYSBkZWNpbWFsCisgIC8vIGNvbXBvbmVudC4KKyAgdXRpbDo6U3RhdHVzIFBhcnNlTnVtYmVySGVscGVyKE51bWJlclJlc3VsdCogcmVzdWx0KTsKKworICAvLyBIYW5kbGVzIGEgeyBkdXJpbmcgcGFyc2luZyBvZiBhIHZhbHVlLgorICB1dGlsOjpTdGF0dXMgSGFuZGxlQmVnaW5PYmplY3QoKTsKKworICAvLyBQYXJzZXMgZnJvbSB0aGUgRU5UUlkgc3RhdGUuCisgIHV0aWw6OlN0YXR1cyBQYXJzZUVudHJ5KFRva2VuVHlwZSB0eXBlKTsKKworICAvLyBQYXJzZXMgZnJvbSB0aGUgRU5UUllfTUlEIHN0YXRlLgorICB1dGlsOjpTdGF0dXMgUGFyc2VFbnRyeU1pZChUb2tlblR5cGUgdHlwZSk7CisKKyAgLy8gUGFyc2VzIGZyb20gdGhlIE9CSl9NSUQgc3RhdGUuCisgIHV0aWw6OlN0YXR1cyBQYXJzZU9iamVjdE1pZChUb2tlblR5cGUgdHlwZSk7CisKKyAgLy8gSGFuZGxlcyBhIFsgZHVyaW5nIHBhcnNpbmcgb2YgYSB2YWx1ZS4KKyAgdXRpbDo6U3RhdHVzIEhhbmRsZUJlZ2luQXJyYXkoKTsKKworICAvLyBQYXJzZXMgZnJvbSB0aGUgQVJSQVlfVkFMVUUgc3RhdGUuCisgIHV0aWw6OlN0YXR1cyBQYXJzZUFycmF5VmFsdWUoVG9rZW5UeXBlIHR5cGUpOworCisgIC8vIFBhcnNlcyBmcm9tIHRoZSBBUlJBWV9NSUQgc3RhdGUuCisgIHV0aWw6OlN0YXR1cyBQYXJzZUFycmF5TWlkKFRva2VuVHlwZSB0eXBlKTsKKworICAvLyBFeHBlY3RzIHBfIHRvIHBvaW50IHRvIGFuIHVucXVvdGVkIGxpdGVyYWwKKyAgdXRpbDo6U3RhdHVzIFBhcnNlVHJ1ZSgpOworICB1dGlsOjpTdGF0dXMgUGFyc2VGYWxzZSgpOworICB1dGlsOjpTdGF0dXMgUGFyc2VOdWxsKCk7CisKKyAgLy8gUmVwb3J0IGEgZmFpbHVyZSBhcyBhIHV0aWw6OlN0YXR1cy4KKyAgdXRpbDo6U3RhdHVzIFJlcG9ydEZhaWx1cmUoU3RyaW5nUGllY2UgbWVzc2FnZSk7CisKKyAgLy8gUmVwb3J0IGEgZmFpbHVyZSBkdWUgdG8gYW4gVU5LTk9XTiB0b2tlbiB0eXBlLiBXZSBjaGVjayBpZiB3ZSBoaXQgdGhlCisgIC8vIGVuZCBvZiB0aGUgc3RyZWFtIGFuZCBpZiB3ZSdyZSBmaW5pc2hpbmcgb3Igbm90IHRvIGRldGVjdCB3aGF0IHR5cGUgb2YKKyAgLy8gc3RhdHVzIHRvIHJldHVybiBpbiB0aGlzIGNhc2UuCisgIHV0aWw6OlN0YXR1cyBSZXBvcnRVbmtub3duKFN0cmluZ1BpZWNlIG1lc3NhZ2UpOworCisgIC8vIEFkdmFuY2UgcF8gcGFzdCBhbGwgd2hpdGVzcGFjZSBvciB1bnRpbCB0aGUgZW5kIG9mIHRoZSBzdHJpbmcuCisgIHZvaWQgU2tpcFdoaXRlc3BhY2UoKTsKKworICAvLyBBZHZhbmNlIHBfIG9uZSBVVEYtOCBjaGFyYWN0ZXIKKyAgdm9pZCBBZHZhbmNlKCk7CisKKyAgLy8gRXhwZWN0cyBwXyB0byBwb2ludCB0byB0aGUgYmVnaW5uaW5nIG9mIGEga2V5LgorICB1dGlsOjpTdGF0dXMgUGFyc2VLZXkoKTsKKworICAvLyBSZXR1cm4gdGhlIHR5cGUgb2YgdGhlIG5leHQgdG9rZW4gYXQgcF8uCisgIFRva2VuVHlwZSBHZXROZXh0VG9rZW5UeXBlKCk7CisKKyAgLy8gVGhlIG9iamVjdCB3cml0ZXIgdG8gd3JpdGUgcGFyc2UgZXZlbnRzIHRvLgorICBPYmplY3RXcml0ZXIqIG93XzsKKworICAvLyBUaGUgc3RhY2sgb2YgcGFyc2luZyB3ZSBzdGlsbCBuZWVkIHRvIGRvLiBXaGVuIHRoZSBzdGFjayBydW5zIGVtcHR5IHdlIHdpbGwKKyAgLy8gaGF2ZSBwYXJzZWQgYSBzaW5nbGUgdmFsdWUgZnJvbSB0aGUgcm9vdCAoZS5nLiBhbiBvYmplY3Qgb3IgbGlzdCkuCisgIHN0ZDo6c3RhY2s8UGFyc2VUeXBlPiBzdGFja187CisKKyAgLy8gQ29udGFpbnMgYW55IGxlZnRvdmVyIHRleHQgZnJvbSBhIHByZXZpb3VzIGNodW5rIHRoYXQgd2Ugd2VyZW4ndCBhYmxlIHRvCisgIC8vIGZ1bGx5IHBhcnNlLCBmb3IgZXhhbXBsZSB0aGUgc3RhcnQgb2YgYSBrZXkgb3IgbnVtYmVyLgorICBzdHJpbmcgbGVmdG92ZXJfOworCisgIC8vIFRoZSBjdXJyZW50IGNodW5rIG9mIEpTT04gYmVpbmcgcGFyc2VkLiBQcmltYXJpbHkgdXNlZCBmb3IgcHJvdmlkaW5nCisgIC8vIGNvbnRleHQgZHVyaW5nIGVycm9yIHJlcG9ydGluZy4KKyAgU3RyaW5nUGllY2UganNvbl87CisKKyAgLy8gQSBwb2ludGVyIHdpdGhpbiB0aGUgY3VycmVudCBKU09OIGJlaW5nIHBhcnNlZCwgdXNlZCB0byB0cmFjayBsb2NhdGlvbi4KKyAgU3RyaW5nUGllY2UgcF87CisKKyAgLy8gU3RvcmVzIHRoZSBsYXN0IGtleSByZWFkLCBhcyB3ZSBzZXBhcmF0ZSBwYXJzaW5nIG9mIGtleXMgYW5kIHZhbHVlcy4KKyAgU3RyaW5nUGllY2Uga2V5XzsKKworICAvLyBTdG9yYWdlIGZvciBrZXlfIGlmIHdlIG5lZWQgdG8ga2VlcCBvd25lcnNoaXAsIGZvciBleGFtcGxlIGJldHdlZW4gY2h1bmtzCisgIC8vIG9yIGlmIHRoZSBrZXkgd2FzIHVuZXNjYXBlZCBmcm9tIGEgSlNPTiBzdHJpbmcuCisgIHN0cmluZyBrZXlfc3RvcmFnZV87CisKKyAgLy8gVHJ1ZSBkdXJpbmcgdGhlIEZpbmlzaFBhcnNlKCkgY2FsbCwgc28gd2Uga25vdyB0aGF0IGFueSBlcnJvcnMgYXJlIGZhdGFsLgorICAvLyBGb3IgZXhhbXBsZSBhbiB1bnRlcm1pbmF0ZWQgc3RyaW5nIHdpbGwgbm9ybWFsbHkgcmVzdWx0IGluIGNhbmNlbGxpbmcgYW5kCisgIC8vIHRyeWluZyBkdXJpbmcgdGhlIG5leHQgY2h1bmssIGJ1dCBkdXJpbmcgRmluaXNoUGFyc2UoKSBpdCBpcyBhbiBlcnJvci4KKyAgYm9vbCBmaW5pc2hpbmdfOworCisgIC8vIFN0cmluZyB3ZSBwYXJzZWQgZHVyaW5nIGEgY2FsbCB0byBQYXJzZVN0cmluZ0hlbHBlcigpLgorICBTdHJpbmdQaWVjZSBwYXJzZWRfOworCisgIC8vIFN0b3JhZ2UgZm9yIHRoZSBzdHJpbmcgd2UgcGFyc2VkLiBUaGlzIG1heSBiZSBlbXB0eSBpZiB0aGUgc3RyaW5nIHdhcyBhYmxlCisgIC8vIHRvIGJlIHBhcnNlZCBkaXJlY3RseSBmcm9tIHRoZSBpbnB1dC4KKyAgc3RyaW5nIHBhcnNlZF9zdG9yYWdlXzsKKworICAvLyBUaGUgY2hhcmFjdGVyIHRoYXQgb3BlbmVkIHRoZSBzdHJpbmcsIGVpdGhlciAnIG9yICIuCisgIC8vIEEgdmFsdWUgb2YgMCBpbmRpY2F0ZXMgdGhhdCBzdHJpbmcgcGFyc2luZyBpcyBub3QgaW4gcHJvY2Vzcy4KKyAgY2hhciBzdHJpbmdfb3Blbl87CisKKyAgLy8gU3RvcmFnZSBmb3IgdGhlIGNodW5rIHRoYXQgYXJlIGJlaW5nIHBhcnNlZCBpbiBQYXJzZUNodW5rKCkuCisgIHN0cmluZyBjaHVua19zdG9yYWdlXzsKKworICAvLyBXaGV0aGVyIHRvIGFsbG93IG5vbiBVVEYtOCBlbmNvZGVkIGlucHV0IGFuZCByZXBsYWNlIGludmFsaWQgY29kZSBwb2ludHMuCisgIGJvb2wgY29lcmNlX3RvX3V0ZjhfOworCisgIEdPT0dMRV9ESVNBTExPV19JTVBMSUNJVF9DT05TVFJVQ1RPUlMoSnNvblN0cmVhbVBhcnNlcik7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgY29udmVydGVyCit9ICAvLyBuYW1lc3BhY2UgdXRpbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX1VUSUxfQ09OVkVSVEVSX0pTT05fU1RSRUFNX1BBUlNFUl9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9qc29uX3N0cmVhbV9wYXJzZXJfdGVzdC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9qc29uX3N0cmVhbV9wYXJzZXJfdGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNDE0ODI2Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL2pzb25fc3RyZWFtX3BhcnNlcl90ZXN0LmNjCkBAIC0wLDAgKzEsNzE2IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL2pzb25fc3RyZWFtX3BhcnNlci5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2xvZ2dpbmcuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3RpbWUuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9leHBlY3Rpbmdfb2JqZWN0d3JpdGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvb2JqZWN0X3dyaXRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RhdHVzLmg+CisKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIHV0aWwgewordXNpbmcgdXRpbDo6U3RhdHVzOworbmFtZXNwYWNlIGVycm9yIHsKK3VzaW5nIHV0aWw6OmVycm9yOjpJTlZBTElEX0FSR1VNRU5UOworfSAgLy8gbmFtZXNwYWNlIGVycm9yCituYW1lc3BhY2UgY29udmVydGVyIHsKKwordXNpbmcgdXRpbDo6U3RhdHVzOworCisvLyBUZXN0cyBmb3IgdGhlIEpTT04gU3RyZWFtIFBhcnNlci4gVGhlc2UgdGVzdHMgYXJlIGludGVuZGVkIHRvIGJlCisvLyBjb21wcmVoZW5zaXZlIGFuZCBjb3ZlciB0aGUgZm9sbG93aW5nOgorLy8KKy8vIFBvc2l0aXZlIHRlc3RzOgorLy8gLSB0cnVlLCBmYWxzZSwgbnVsbAorLy8gLSBlbXB0eSBvYmplY3Qgb3IgYXJyYXkuCisvLyAtIG5lZ2F0aXZlIGFuZCBwb3NpdGl2ZSBkb3VibGUgYW5kIGludCwgdW5zaWduZWQgaW50CisvLyAtIHNpbmdsZSBhbmQgZG91YmxlIHF1b3RlZCBzdHJpbmdzCisvLyAtIHN0cmluZyBrZXksIHVucXVvdGVkIGtleSwgbnVtZXJpYyBrZXkKKy8vIC0gYXJyYXkgY29udGFpbmluZyBhcnJheSwgb2JqZWN0LCB2YWx1ZQorLy8gLSBvYmplY3QgY29udGFpbmluZyBhcnJheSwgb2JqZWN0LCB2YWx1ZQorLy8gLSB1bmljb2RlIGhhbmRsaW5nIGluIHN0cmluZ3MKKy8vIC0gYXNjaWkgZXNjYXBpbmcgKFxiLCBcZiwgXG4sIFxyLCBcdCwgXHYpCisvLyAtIHRyYWlsaW5nIGNvbW1hcworLy8KKy8vIE5lZ2F0aXZlIHRlc3RzOgorLy8gLSBpbGxlZ2FsIGxpdGVyYWxzCisvLyAtIG1pc21hdGNoZWQgcXVvdGVzIGZhaWx1cmUgb24gc3RyaW5ncworLy8gLSB1bnRlcm1pbmF0ZWQgc3RyaW5nIGZhaWx1cmUKKy8vIC0gdW5leHBlY3RlZCBlbmQgb2Ygc3RyaW5nIGZhaWx1cmUKKy8vIC0gbWlzbWF0Y2hlZCBvYmplY3QgYW5kIGFycmF5IGNsb3NpbmcKKy8vIC0gRmFpbHVyZSB0byBjbG9zZSBhcnJheSBvciBvYmplY3QKKy8vIC0gbnVtYmVycyB0b28gbGFyZ2UKKy8vIC0gaW52YWxpZCB1bmljb2RlIGVzY2FwZXMuCisvLyAtIGludmFsaWQgdW5pY29kZSBzZXF1ZW5jZXMuCisvLyAtIG51bWJlcnMgYXMga2V5cworLy8KKy8vIEZvciBlYWNoIHRlc3Qgd2Ugc3BsaXQgdGhlIGlucHV0IHN0cmluZyBvbiBldmVyeSBwb3NzaWJsZSBjaGFyYWN0ZXIgdG8gZW5zdXJlCisvLyB0aGUgcGFyc2VyIGlzIGFibGUgdG8gaGFuZGxlIGFyYml0cmFyaWx5IHNwbGl0IGlucHV0IGZvciBhbGwgY2FzZXMuIFdlIGFsc28KKy8vIGRvIGEgZmluYWwgdGVzdCBvZiB0aGUgZW50aXJlIHRlc3QgY2FzZSBvbmUgY2hhcmFjdGVyIGF0IGEgdGltZS4KK2NsYXNzIEpzb25TdHJlYW1QYXJzZXJUZXN0IDogcHVibGljIDo6dGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICBKc29uU3RyZWFtUGFyc2VyVGVzdCgpIDogbW9ja18oKSwgb3dfKCZtb2NrXykge30KKyAgdmlydHVhbCB+SnNvblN0cmVhbVBhcnNlclRlc3QoKSB7fQorCisgIHV0aWw6OlN0YXR1cyBSdW5UZXN0KFN0cmluZ1BpZWNlIGpzb24sIGludCBzcGxpdCwgYm9vbCBjb2VyY2VfdXRmOCA9IGZhbHNlKSB7CisgICAgSnNvblN0cmVhbVBhcnNlciBwYXJzZXIoJm1vY2tfKTsKKworICAgIC8vIFNwZWNpYWwgY2FzZSBmb3Igc3BsaXQgPT0gbGVuZ3RoLCB0ZXN0IHBhcnNpbmcgb25lIGNoYXJhY3RlciBhdCBhIHRpbWUuCisgICAgaWYgKHNwbGl0ID09IGpzb24ubGVuZ3RoKCkpIHsKKyAgICAgIEdPT0dMRV9MT0coSU5GTykgPDwgIlRlc3Rpbmcgc3BsaXQgZXZlcnkgY2hhcjogIiA8PCBqc29uOworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBqc29uLmxlbmd0aCgpOyArK2kpIHsKKyAgICAgICAgU3RyaW5nUGllY2Ugc2luZ2xlID0ganNvbi5zdWJzdHIoaSwgMSk7CisgICAgICAgIHV0aWw6OlN0YXR1cyByZXN1bHQgPSBwYXJzZXIuUGFyc2Uoc2luZ2xlKTsKKyAgICAgICAgaWYgKCFyZXN1bHQub2soKSkgeworICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIHJldHVybiBwYXJzZXIuRmluaXNoUGFyc2UoKTsKKyAgICB9CisKKyAgICAvLyBOb3JtYWwgY2FzZSwgc3BsaXQgYXQgdGhlIHNwbGl0IHBvaW50IGFuZCBwYXJzZSB0d28gc3Vic3RyaW5ncy4KKyAgICBTdHJpbmdQaWVjZSBmaXJzdCA9IGpzb24uc3Vic3RyKDAsIHNwbGl0KTsKKyAgICBTdHJpbmdQaWVjZSByZXN0ID0ganNvbi5zdWJzdHIoc3BsaXQpOworICAgIEdPT0dMRV9MT0coSU5GTykgPDwgIlRlc3Rpbmcgc3BsaXQ6ICIgPDwgZmlyc3QgPDwgIj48IiA8PCByZXN0OworICAgIHV0aWw6OlN0YXR1cyByZXN1bHQgPSBwYXJzZXIuUGFyc2UoZmlyc3QpOworICAgIGlmIChyZXN1bHQub2soKSkgeworICAgICAgcmVzdWx0ID0gcGFyc2VyLlBhcnNlKHJlc3QpOworICAgICAgaWYgKHJlc3VsdC5vaygpKSB7CisgICAgICAgIHJlc3VsdCA9IHBhcnNlci5GaW5pc2hQYXJzZSgpOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gcmVzdWx0OworICB9CisKKyAgdm9pZCBEb1Rlc3QoU3RyaW5nUGllY2UganNvbiwgaW50IHNwbGl0LCBib29sIGNvZXJjZV91dGY4ID0gZmFsc2UpIHsKKyAgICB1dGlsOjpTdGF0dXMgcmVzdWx0ID0gUnVuVGVzdChqc29uLCBzcGxpdCwgY29lcmNlX3V0ZjgpOworICAgIGlmICghcmVzdWx0Lm9rKCkpIHsKKyAgICAgIEdPT0dMRV9MT0coV0FSTklORykgPDwgcmVzdWx0OworICAgIH0KKyAgICBFWFBFQ1RfT0socmVzdWx0KTsKKyAgfQorCisgIHZvaWQgRG9FcnJvclRlc3QoU3RyaW5nUGllY2UganNvbiwgaW50IHNwbGl0LCBTdHJpbmdQaWVjZSBlcnJvcl9wcmVmaXgpIHsKKyAgICB1dGlsOjpTdGF0dXMgcmVzdWx0ID0gUnVuVGVzdChqc29uLCBzcGxpdCk7CisgICAgRVhQRUNUX0VRKHV0aWw6OmVycm9yOjpJTlZBTElEX0FSR1VNRU5ULCByZXN1bHQuZXJyb3JfY29kZSgpKTsKKyAgICBTdHJpbmdQaWVjZSBlcnJvcl9tZXNzYWdlKHJlc3VsdC5lcnJvcl9tZXNzYWdlKCkpOworICAgIEVYUEVDVF9FUShlcnJvcl9wcmVmaXgsIGVycm9yX21lc3NhZ2Uuc3Vic3RyKDAsIGVycm9yX3ByZWZpeC5zaXplKCkpKTsKKyAgfQorCisKKyAgTW9ja09iamVjdFdyaXRlciBtb2NrXzsKKyAgRXhwZWN0aW5nT2JqZWN0V3JpdGVyIG93XzsKK307CisKKworLy8gUG9zaXRpdmUgdGVzdHMKKworLy8gLSB0cnVlLCBmYWxzZSwgbnVsbAorVEVTVF9GKEpzb25TdHJlYW1QYXJzZXJUZXN0LCBTaW1wbGVUcnVlKSB7CisgIFN0cmluZ1BpZWNlIHN0ciA9ICJ0cnVlIjsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPD0gc3RyLmxlbmd0aCgpOyArK2kpIHsKKyAgICBvd18uUmVuZGVyQm9vbCgiIiwgdHJ1ZSk7CisgICAgRG9UZXN0KHN0ciwgaSk7CisgIH0KK30KKworVEVTVF9GKEpzb25TdHJlYW1QYXJzZXJUZXN0LCBTaW1wbGVGYWxzZSkgeworICBTdHJpbmdQaWVjZSBzdHIgPSAiZmFsc2UiOworICBmb3IgKGludCBpID0gMDsgaSA8PSBzdHIubGVuZ3RoKCk7ICsraSkgeworICAgIG93Xy5SZW5kZXJCb29sKCIiLCBmYWxzZSk7CisgICAgRG9UZXN0KHN0ciwgaSk7CisgIH0KK30KKworVEVTVF9GKEpzb25TdHJlYW1QYXJzZXJUZXN0LCBTaW1wbGVOdWxsKSB7CisgIFN0cmluZ1BpZWNlIHN0ciA9ICJudWxsIjsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPD0gc3RyLmxlbmd0aCgpOyArK2kpIHsKKyAgICBvd18uUmVuZGVyTnVsbCgiIik7CisgICAgRG9UZXN0KHN0ciwgaSk7CisgIH0KK30KKworLy8gLSBlbXB0eSBvYmplY3QgYW5kIGFycmF5LgorVEVTVF9GKEpzb25TdHJlYW1QYXJzZXJUZXN0LCBFbXB0eU9iamVjdCkgeworICBTdHJpbmdQaWVjZSBzdHIgPSAie30iOworICBmb3IgKGludCBpID0gMDsgaSA8PSBzdHIubGVuZ3RoKCk7ICsraSkgeworICAgIG93Xy5TdGFydE9iamVjdCgiIiktPkVuZE9iamVjdCgpOworICAgIERvVGVzdChzdHIsIGkpOworICB9Cit9CisKK1RFU1RfRihKc29uU3RyZWFtUGFyc2VyVGVzdCwgRW1wdHlMaXN0KSB7CisgIFN0cmluZ1BpZWNlIHN0ciA9ICJbXSI7CisgIGZvciAoaW50IGkgPSAwOyBpIDw9IHN0ci5sZW5ndGgoKTsgKytpKSB7CisgICAgb3dfLlN0YXJ0TGlzdCgiIiktPkVuZExpc3QoKTsKKyAgICBEb1Rlc3Qoc3RyLCBpKTsKKyAgfQorfQorCisvLyAtIG5lZ2F0aXZlIGFuZCBwb3NpdGl2ZSBkb3VibGUgYW5kIGludCwgdW5zaWduZWQgaW50CitURVNUX0YoSnNvblN0cmVhbVBhcnNlclRlc3QsIFNpbXBsZURvdWJsZSkgeworICBTdHJpbmdQaWVjZSBzdHIgPSAiNDIuNSI7CisgIGZvciAoaW50IGkgPSAwOyBpIDw9IHN0ci5sZW5ndGgoKTsgKytpKSB7CisgICAgb3dfLlJlbmRlckRvdWJsZSgiIiwgNDIuNSk7CisgICAgRG9UZXN0KHN0ciwgaSk7CisgIH0KK30KKworVEVTVF9GKEpzb25TdHJlYW1QYXJzZXJUZXN0LCBTY2llbnRpZmljRG91YmxlKSB7CisgIFN0cmluZ1BpZWNlIHN0ciA9ICIxLjIzNDVlLTEwIjsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBzdHIubGVuZ3RoKCk7ICsraSkgeworICAgIG93Xy5SZW5kZXJEb3VibGUoIiIsIDEuMjM0NWUtMTApOworICAgIERvVGVzdChzdHIsIGkpOworICB9Cit9CisKK1RFU1RfRihKc29uU3RyZWFtUGFyc2VyVGVzdCwgU2ltcGxlTmVnYXRpdmVEb3VibGUpIHsKKyAgU3RyaW5nUGllY2Ugc3RyID0gIi0xMDQ1LjIzNSI7CisgIGZvciAoaW50IGkgPSAwOyBpIDw9IHN0ci5sZW5ndGgoKTsgKytpKSB7CisgICAgb3dfLlJlbmRlckRvdWJsZSgiIiwgLTEwNDUuMjM1KTsKKyAgICBEb1Rlc3Qoc3RyLCBpKTsKKyAgfQorfQorCitURVNUX0YoSnNvblN0cmVhbVBhcnNlclRlc3QsIFNpbXBsZUludCkgeworICBTdHJpbmdQaWVjZSBzdHIgPSAiMTIzNDU2IjsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPD0gc3RyLmxlbmd0aCgpOyArK2kpIHsKKyAgICBvd18uUmVuZGVyVWludDY0KCIiLCAxMjM0NTYpOworICAgIERvVGVzdChzdHIsIGkpOworICB9Cit9CisKK1RFU1RfRihKc29uU3RyZWFtUGFyc2VyVGVzdCwgU2ltcGxlTmVnYXRpdmVJbnQpIHsKKyAgU3RyaW5nUGllY2Ugc3RyID0gIi03OTQ5NzgyMzU1MzE2Mjc2NSI7CisgIGZvciAoaW50IGkgPSAwOyBpIDw9IHN0ci5sZW5ndGgoKTsgKytpKSB7CisgICAgb3dfLlJlbmRlckludDY0KCIiLCAtNzk0OTc4MjM1NTMxNjI3NjVMTCk7CisgICAgRG9UZXN0KHN0ciwgaSk7CisgIH0KK30KKworVEVTVF9GKEpzb25TdHJlYW1QYXJzZXJUZXN0LCBTaW1wbGVVbnNpZ25lZEludCkgeworICBTdHJpbmdQaWVjZSBzdHIgPSAiMTE3Nzk0OTc4MjM1NTMxNjI3NjUiOworICBmb3IgKGludCBpID0gMDsgaSA8PSBzdHIubGVuZ3RoKCk7ICsraSkgeworICAgIG93Xy5SZW5kZXJVaW50NjQoIiIsIDExNzc5NDk3ODIzNTUzMTYyNzY1VUxMKTsKKyAgICBEb1Rlc3Qoc3RyLCBpKTsKKyAgfQorfQorCisvLyAtIHNpbmdsZSBhbmQgZG91YmxlIHF1b3RlZCBzdHJpbmdzCitURVNUX0YoSnNvblN0cmVhbVBhcnNlclRlc3QsIEVtcHR5RG91YmxlUXVvdGVkU3RyaW5nKSB7CisgIFN0cmluZ1BpZWNlIHN0ciA9ICJcIlwiIjsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPD0gc3RyLmxlbmd0aCgpOyArK2kpIHsKKyAgICBvd18uUmVuZGVyU3RyaW5nKCIiLCAiIik7CisgICAgRG9UZXN0KHN0ciwgaSk7CisgIH0KK30KKworVEVTVF9GKEpzb25TdHJlYW1QYXJzZXJUZXN0LCBFbXB0eVNpbmdsZVF1b3RlZFN0cmluZykgeworICBTdHJpbmdQaWVjZSBzdHIgPSAiJyciOworICBmb3IgKGludCBpID0gMDsgaSA8PSBzdHIubGVuZ3RoKCk7ICsraSkgeworICAgIG93Xy5SZW5kZXJTdHJpbmcoIiIsICIiKTsKKyAgICBEb1Rlc3Qoc3RyLCBpKTsKKyAgfQorfQorCitURVNUX0YoSnNvblN0cmVhbVBhcnNlclRlc3QsIFNpbXBsZURvdWJsZVF1b3RlZFN0cmluZykgeworICBTdHJpbmdQaWVjZSBzdHIgPSAiXCJTb21lIFN0cmluZ1wiIjsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPD0gc3RyLmxlbmd0aCgpOyArK2kpIHsKKyAgICBvd18uUmVuZGVyU3RyaW5nKCIiLCAiU29tZSBTdHJpbmciKTsKKyAgICBEb1Rlc3Qoc3RyLCBpKTsKKyAgfQorfQorCitURVNUX0YoSnNvblN0cmVhbVBhcnNlclRlc3QsIFNpbXBsZVNpbmdsZVF1b3RlZFN0cmluZykgeworICBTdHJpbmdQaWVjZSBzdHIgPSAiJ0Fub3RoZXIgU3RyaW5nJyI7CisgIGZvciAoaW50IGkgPSAwOyBpIDw9IHN0ci5sZW5ndGgoKTsgKytpKSB7CisgICAgb3dfLlJlbmRlclN0cmluZygiIiwgIkFub3RoZXIgU3RyaW5nIik7CisgICAgRG9UZXN0KHN0ciwgaSk7CisgIH0KK30KKworLy8gLSBzdHJpbmcga2V5LCB1bnF1b3RlZCBrZXksIG51bWVyaWMga2V5CitURVNUX0YoSnNvblN0cmVhbVBhcnNlclRlc3QsIE9iamVjdEtleVR5cGVzKSB7CisgIFN0cmluZ1BpZWNlIHN0ciA9CisgICAgICAieydzJzogdHJ1ZSwgXCJkXCI6IGZhbHNlLCBrZXk6IG51bGwsIHNuYWtlX2tleTogW10sIGNhbWVsS2V5OiB7fX0iOworICBmb3IgKGludCBpID0gMDsgaSA8PSBzdHIubGVuZ3RoKCk7ICsraSkgeworICAgIG93Xy5TdGFydE9iamVjdCgiIikKKyAgICAgICAgLT5SZW5kZXJCb29sKCJzIiwgdHJ1ZSkKKyAgICAgICAgLT5SZW5kZXJCb29sKCJkIiwgZmFsc2UpCisgICAgICAgIC0+UmVuZGVyTnVsbCgia2V5IikKKyAgICAgICAgLT5TdGFydExpc3QoInNuYWtlX2tleSIpCisgICAgICAgIC0+RW5kTGlzdCgpCisgICAgICAgIC0+U3RhcnRPYmplY3QoImNhbWVsS2V5IikKKyAgICAgICAgLT5FbmRPYmplY3QoKQorICAgICAgICAtPkVuZE9iamVjdCgpOworICAgIERvVGVzdChzdHIsIGkpOworICB9Cit9CisKKy8vIC0gYXJyYXkgY29udGFpbmluZyBhcnJheSwgb2JqZWN0LCB2YWx1ZXMgKHRydWUsIGZhbHNlLCBudWxsLCBudW0sIHN0cmluZykKK1RFU1RfRihKc29uU3RyZWFtUGFyc2VyVGVzdCwgQXJyYXlWYWx1ZXMpIHsKKyAgU3RyaW5nUGllY2Ugc3RyID0KKyAgICAgICJbdHJ1ZSwgZmFsc2UsIG51bGwsICdhIHN0cmluZycsIFwiYW5vdGhlciBzdHJpbmdcIiwgWzIyLCAtMTI3LCA0NS4zLCAiCisgICAgICAiLTEwNTYuNCwgMTE3Nzk0OTc4MjM1NTMxNjI3NjVdLCB7J2tleSc6IHRydWV9XSI7CisgIGZvciAoaW50IGkgPSAwOyBpIDw9IHN0ci5sZW5ndGgoKTsgKytpKSB7CisgICAgb3dfLlN0YXJ0TGlzdCgiIikKKyAgICAgICAgLT5SZW5kZXJCb29sKCIiLCB0cnVlKQorICAgICAgICAtPlJlbmRlckJvb2woIiIsIGZhbHNlKQorICAgICAgICAtPlJlbmRlck51bGwoIiIpCisgICAgICAgIC0+UmVuZGVyU3RyaW5nKCIiLCAiYSBzdHJpbmciKQorICAgICAgICAtPlJlbmRlclN0cmluZygiIiwgImFub3RoZXIgc3RyaW5nIikKKyAgICAgICAgLT5TdGFydExpc3QoIiIpCisgICAgICAgIC0+UmVuZGVyVWludDY0KCIiLCAyMikKKyAgICAgICAgLT5SZW5kZXJJbnQ2NCgiIiwgLTEyNykKKyAgICAgICAgLT5SZW5kZXJEb3VibGUoIiIsIDQ1LjMpCisgICAgICAgIC0+UmVuZGVyRG91YmxlKCIiLCAtMTA1Ni40KQorICAgICAgICAtPlJlbmRlclVpbnQ2NCgiIiwgMTE3Nzk0OTc4MjM1NTMxNjI3NjVVTEwpCisgICAgICAgIC0+RW5kTGlzdCgpCisgICAgICAgIC0+U3RhcnRPYmplY3QoIiIpCisgICAgICAgIC0+UmVuZGVyQm9vbCgia2V5IiwgdHJ1ZSkKKyAgICAgICAgLT5FbmRPYmplY3QoKQorICAgICAgICAtPkVuZExpc3QoKTsKKyAgICBEb1Rlc3Qoc3RyLCBpKTsKKyAgfQorfQorCisvLyAtIG9iamVjdCBjb250YWluaW5nIGFycmF5LCBvYmplY3QsIHZhbHVlICh0cnVlLCBmYWxzZSwgbnVsbCwgbnVtLCBzdHJpbmcpCitURVNUX0YoSnNvblN0cmVhbVBhcnNlclRlc3QsIE9iamVjdFZhbHVlcykgeworICBTdHJpbmdQaWVjZSBzdHIgPQorICAgICAgInt0OiB0cnVlLCBmOiBmYWxzZSwgbjogbnVsbCwgczogJ2Egc3RyaW5nJywgZDogXCJhbm90aGVyIHN0cmluZ1wiLCBwaTogIgorICAgICAgIjIyLCBuaTogLTEyNywgcGQ6IDQ1LjMsIG5kOiAtMTA1Ni40LCBwbDogMTE3Nzk0OTc4MjM1NTMxNjI3NjUsIGw6IFtbXV0sICIKKyAgICAgICJvOiB7J2tleSc6IHRydWV9fSI7CisgIGZvciAoaW50IGkgPSAwOyBpIDw9IHN0ci5sZW5ndGgoKTsgKytpKSB7CisgICAgb3dfLlN0YXJ0T2JqZWN0KCIiKQorICAgICAgICAtPlJlbmRlckJvb2woInQiLCB0cnVlKQorICAgICAgICAtPlJlbmRlckJvb2woImYiLCBmYWxzZSkKKyAgICAgICAgLT5SZW5kZXJOdWxsKCJuIikKKyAgICAgICAgLT5SZW5kZXJTdHJpbmcoInMiLCAiYSBzdHJpbmciKQorICAgICAgICAtPlJlbmRlclN0cmluZygiZCIsICJhbm90aGVyIHN0cmluZyIpCisgICAgICAgIC0+UmVuZGVyVWludDY0KCJwaSIsIDIyKQorICAgICAgICAtPlJlbmRlckludDY0KCJuaSIsIC0xMjcpCisgICAgICAgIC0+UmVuZGVyRG91YmxlKCJwZCIsIDQ1LjMpCisgICAgICAgIC0+UmVuZGVyRG91YmxlKCJuZCIsIC0xMDU2LjQpCisgICAgICAgIC0+UmVuZGVyVWludDY0KCJwbCIsIDExNzc5NDk3ODIzNTUzMTYyNzY1VUxMKQorICAgICAgICAtPlN0YXJ0TGlzdCgibCIpCisgICAgICAgIC0+U3RhcnRMaXN0KCIiKQorICAgICAgICAtPkVuZExpc3QoKQorICAgICAgICAtPkVuZExpc3QoKQorICAgICAgICAtPlN0YXJ0T2JqZWN0KCJvIikKKyAgICAgICAgLT5SZW5kZXJCb29sKCJrZXkiLCB0cnVlKQorICAgICAgICAtPkVuZE9iamVjdCgpCisgICAgICAgIC0+RW5kT2JqZWN0KCk7CisgICAgRG9UZXN0KHN0ciwgaSk7CisgIH0KK30KKworCitURVNUX0YoSnNvblN0cmVhbVBhcnNlclRlc3QsIFJlamVjdE5vblV0ZjhXaGVuTm90Q29lcmNlZCkgeworICBTdHJpbmdQaWVjZSBqc29uID0gIntcImFkZHJlc3NcIjpceEZGXCLXl9eo15XXqdeqIDIzLCDXqNei16DXoNeULCDXmdep16jXkNecXCJ9IjsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPD0ganNvbi5sZW5ndGgoKTsgKytpKSB7CisgICAgRG9FcnJvclRlc3QoanNvbiwgaSwgIkVuY291bnRlcmVkIG5vbiBVVEYtOCBjb2RlIHBvaW50cy4iKTsKKyAgfQorICBqc29uID0gIntcImFkZHJlc3NcIjogXCLXl9eo15XXqdeqIDIzLFx4RkbXqNei16DXoNeULCDXmdep16jXkNecXCJ9IjsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPD0ganNvbi5sZW5ndGgoKTsgKytpKSB7CisgICAgRG9FcnJvclRlc3QoanNvbiwgaSwgIkVuY291bnRlcmVkIG5vbiBVVEYtOCBjb2RlIHBvaW50cy4iKTsKKyAgfQorICBEb0Vycm9yVGVzdCgiXHhGRnt9IiwgMCwgIkVuY291bnRlcmVkIG5vbiBVVEYtOCBjb2RlIHBvaW50cy4iKTsKK30KKworI2lmbmRlZiBfTVNDX1ZFUgorLy8gLSB1bmljb2RlIGhhbmRsaW5nIGluIHN0cmluZ3MKK1RFU1RfRihKc29uU3RyZWFtUGFyc2VyVGVzdCwgVW5pY29kZUVzY2FwaW5nKSB7CisgIFN0cmluZ1BpZWNlIHN0ciA9ICJbXCJcXHUwNjM5XFx1MDYzMVxcdTA2MjhcXHUwNjQ5XCJdIjsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPD0gc3RyLmxlbmd0aCgpOyArK2kpIHsKKyAgICAvLyBUT0RPKHhpYW9mZW5nKTogRmlndXJlIG91dCB3aGF0IGRlZmF1bHQgZW5jb2RpbmcgdG8gdXNlIGZvciBKU09OIHN0cmluZ3MuCisgICAgLy8gSW4gcHJvdG9idWYgd2UgdXNlIFVURi04IGZvciBzdHJpbmdzLCBidXQgZm9yIEpTT04gd2UgcHJvYmFibHkgc2hvdWxkCisgICAgLy8gYWxsb3cgZGlmZmVyZW50IGVuY29kaW5ncz8KKyAgICBvd18uU3RhcnRMaXN0KCIiKS0+UmVuZGVyU3RyaW5nKCIiLCAiXHUwNjM5XHUwNjMxXHUwNjI4XHUwNjQ5IiktPkVuZExpc3QoKTsKKyAgICBEb1Rlc3Qoc3RyLCBpKTsKKyAgfQorfQorI2VuZGlmCisKKy8vIC0gYXNjaWkgZXNjYXBpbmcgKFxiLCBcZiwgXG4sIFxyLCBcdCwgXHYpCitURVNUX0YoSnNvblN0cmVhbVBhcnNlclRlc3QsIEFzY2lpRXNjYXBpbmcpIHsKKyAgU3RyaW5nUGllY2Ugc3RyID0KKyAgICAgICJbXCJcXGJcIiwgXCJcXG5pbmdcIiwgXCJ0ZXN0XFxmXCIsIFwiXFxyXFx0XCIsIFwidGVzdFxcXFxcXHZpbmdcIl0iOworICBmb3IgKGludCBpID0gMDsgaSA8PSBzdHIubGVuZ3RoKCk7ICsraSkgeworICAgIG93Xy5TdGFydExpc3QoIiIpCisgICAgICAgIC0+UmVuZGVyU3RyaW5nKCIiLCAiXGIiKQorICAgICAgICAtPlJlbmRlclN0cmluZygiIiwgIlxuaW5nIikKKyAgICAgICAgLT5SZW5kZXJTdHJpbmcoIiIsICJ0ZXN0XGYiKQorICAgICAgICAtPlJlbmRlclN0cmluZygiIiwgIlxyXHQiKQorICAgICAgICAtPlJlbmRlclN0cmluZygiIiwgInRlc3RcXFx2aW5nIikKKyAgICAgICAgLT5FbmRMaXN0KCk7CisgICAgRG9UZXN0KHN0ciwgaSk7CisgIH0KK30KKworLy8gLSB0cmFpbGluZyBjb21tYXMsIHdlIHN1cHBvcnQgYSBzaW5nbGUgdHJhaWxpbmcgY29tbWEgYnV0IG5vIGludGVybmFsIGNvbW1hcy4KK1RFU1RfRihKc29uU3RyZWFtUGFyc2VyVGVzdCwgVHJhaWxpbmdDb21tYXMpIHsKKyAgU3RyaW5nUGllY2Ugc3RyID0gIltbJ2EnLHRydWUsXSwge2I6IG51bGwsfSxdIjsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPD0gc3RyLmxlbmd0aCgpOyArK2kpIHsKKyAgICBvd18uU3RhcnRMaXN0KCIiKQorICAgICAgICAtPlN0YXJ0TGlzdCgiIikKKyAgICAgICAgLT5SZW5kZXJTdHJpbmcoIiIsICJhIikKKyAgICAgICAgLT5SZW5kZXJCb29sKCIiLCB0cnVlKQorICAgICAgICAtPkVuZExpc3QoKQorICAgICAgICAtPlN0YXJ0T2JqZWN0KCIiKQorICAgICAgICAtPlJlbmRlck51bGwoImIiKQorICAgICAgICAtPkVuZE9iamVjdCgpCisgICAgICAgIC0+RW5kTGlzdCgpOworICAgIERvVGVzdChzdHIsIGkpOworICB9Cit9CisKKy8vIE5lZ2F0aXZlIHRlc3RzCisKKy8vIGlsbGVnYWwgbGl0ZXJhbHMKK1RFU1RfRihKc29uU3RyZWFtUGFyc2VyVGVzdCwgRXh0cmFUZXh0QWZ0ZXJUcnVlKSB7CisgIFN0cmluZ1BpZWNlIHN0ciA9ICJ0cnVlZSI7CisgIGZvciAoaW50IGkgPSAwOyBpIDw9IHN0ci5sZW5ndGgoKTsgKytpKSB7CisgICAgb3dfLlJlbmRlckJvb2woIiIsIHRydWUpOworICAgIERvRXJyb3JUZXN0KHN0ciwgaSwgIlBhcnNpbmcgdGVybWluYXRlZCBiZWZvcmUgZW5kIG9mIGlucHV0LiIpOworICB9Cit9CisKK1RFU1RfRihKc29uU3RyZWFtUGFyc2VyVGVzdCwgSW52YWxpZE51bWJlckRhc2hPbmx5KSB7CisgIFN0cmluZ1BpZWNlIHN0ciA9ICItIjsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPD0gc3RyLmxlbmd0aCgpOyArK2kpIHsKKyAgICBEb0Vycm9yVGVzdChzdHIsIGksICJVbmFibGUgdG8gcGFyc2UgbnVtYmVyLiIpOworICB9Cit9CisKK1RFU1RfRihKc29uU3RyZWFtUGFyc2VyVGVzdCwgSW52YWxpZE51bWJlckRhc2hOYW1lKSB7CisgIFN0cmluZ1BpZWNlIHN0ciA9ICItZm9vIjsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPD0gc3RyLmxlbmd0aCgpOyArK2kpIHsKKyAgICBEb0Vycm9yVGVzdChzdHIsIGksICJVbmFibGUgdG8gcGFyc2UgbnVtYmVyLiIpOworICB9Cit9CisKK1RFU1RfRihKc29uU3RyZWFtUGFyc2VyVGVzdCwgSW52YWxpZExpdGVyYWxJbkFycmF5KSB7CisgIFN0cmluZ1BpZWNlIHN0ciA9ICJbbnVsZV0iOworICBmb3IgKGludCBpID0gMDsgaSA8PSBzdHIubGVuZ3RoKCk7ICsraSkgeworICAgIG93Xy5TdGFydExpc3QoIiIpOworICAgIERvRXJyb3JUZXN0KHN0ciwgaSwgIlVuZXhwZWN0ZWQgdG9rZW4uIik7CisgIH0KK30KKworVEVTVF9GKEpzb25TdHJlYW1QYXJzZXJUZXN0LCBJbnZhbGlkTGl0ZXJhbEluT2JqZWN0KSB7CisgIFN0cmluZ1BpZWNlIHN0ciA9ICJ7MTIzZmFsc2V9IjsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPD0gc3RyLmxlbmd0aCgpOyArK2kpIHsKKyAgICBvd18uU3RhcnRPYmplY3QoIiIpOworICAgIERvRXJyb3JUZXN0KHN0ciwgaSwgIkV4cGVjdGVkIGFuIG9iamVjdCBrZXkgb3IgfS4iKTsKKyAgfQorfQorCisvLyBtaXNtYXRjaGVkIHF1b3RlcyBmYWlsdXJlIG9uIHN0cmluZ3MKK1RFU1RfRihKc29uU3RyZWFtUGFyc2VyVGVzdCwgTWlzbWF0Y2hlZFNpbmdsZVF1b3RlZExpdGVyYWwpIHsKKyAgU3RyaW5nUGllY2Ugc3RyID0gIidTb21lIHN0clwiIjsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPD0gc3RyLmxlbmd0aCgpOyArK2kpIHsKKyAgICBEb0Vycm9yVGVzdChzdHIsIGksICJDbG9zaW5nIHF1b3RlIGV4cGVjdGVkIGluIHN0cmluZy4iKTsKKyAgfQorfQorCitURVNUX0YoSnNvblN0cmVhbVBhcnNlclRlc3QsIE1pc21hdGNoZWREb3VibGVRdW90ZWRMaXRlcmFsKSB7CisgIFN0cmluZ1BpZWNlIHN0ciA9ICJcIkFub3RoZXIgc3RyaW5nIHRoYXQgZW5kcyBwb29ybHkhJyI7CisgIGZvciAoaW50IGkgPSAwOyBpIDw9IHN0ci5sZW5ndGgoKTsgKytpKSB7CisgICAgRG9FcnJvclRlc3Qoc3RyLCBpLCAiQ2xvc2luZyBxdW90ZSBleHBlY3RlZCBpbiBzdHJpbmcuIik7CisgIH0KK30KKworLy8gdW50ZXJtaW5hdGVkIHN0cmluZ3MKK1RFU1RfRihKc29uU3RyZWFtUGFyc2VyVGVzdCwgVW50ZXJtaW5hdGVkTGl0ZXJhbFN0cmluZykgeworICBTdHJpbmdQaWVjZSBzdHIgPSAiXCJGb3Jnb3QgdGhlIHJlc3Qgb2YgaSI7CisgIGZvciAoaW50IGkgPSAwOyBpIDw9IHN0ci5sZW5ndGgoKTsgKytpKSB7CisgICAgRG9FcnJvclRlc3Qoc3RyLCBpLCAiQ2xvc2luZyBxdW90ZSBleHBlY3RlZCBpbiBzdHJpbmcuIik7CisgIH0KK30KKworVEVTVF9GKEpzb25TdHJlYW1QYXJzZXJUZXN0LCBVbnRlcm1pbmF0ZWRTdHJpbmdFc2NhcGUpIHsKKyAgU3RyaW5nUGllY2Ugc3RyID0gIlwiRm9yZ290IHRoZSByZXN0IG9mIFxcIjsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPD0gc3RyLmxlbmd0aCgpOyArK2kpIHsKKyAgICBEb0Vycm9yVGVzdChzdHIsIGksICJDbG9zaW5nIHF1b3RlIGV4cGVjdGVkIGluIHN0cmluZy4iKTsKKyAgfQorfQorCitURVNUX0YoSnNvblN0cmVhbVBhcnNlclRlc3QsIFVudGVybWluYXRlZFN0cmluZ0luQXJyYXkpIHsKKyAgU3RyaW5nUGllY2Ugc3RyID0gIltcIkZvcmdvdCB0byBjbG9zZSB0aGUgc3RyaW5nXSI7CisgIGZvciAoaW50IGkgPSAwOyBpIDw9IHN0ci5sZW5ndGgoKTsgKytpKSB7CisgICAgb3dfLlN0YXJ0TGlzdCgiIik7CisgICAgRG9FcnJvclRlc3Qoc3RyLCBpLCAiQ2xvc2luZyBxdW90ZSBleHBlY3RlZCBpbiBzdHJpbmcuIik7CisgIH0KK30KKworVEVTVF9GKEpzb25TdHJlYW1QYXJzZXJUZXN0LCBVbnRlcm1pbmF0ZWRTdHJpbmdJbk9iamVjdCkgeworICBTdHJpbmdQaWVjZSBzdHIgPSAie2Y6IFwiRm9yZ290IHRvIGNsb3NlIHRoZSBzdHJpbmd9IjsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPD0gc3RyLmxlbmd0aCgpOyArK2kpIHsKKyAgICBvd18uU3RhcnRPYmplY3QoIiIpOworICAgIERvRXJyb3JUZXN0KHN0ciwgaSwgIkNsb3NpbmcgcXVvdGUgZXhwZWN0ZWQgaW4gc3RyaW5nLiIpOworICB9Cit9CisKK1RFU1RfRihKc29uU3RyZWFtUGFyc2VyVGVzdCwgVW50ZXJtaW5hdGVkT2JqZWN0KSB7CisgIFN0cmluZ1BpZWNlIHN0ciA9ICJ7IjsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPD0gc3RyLmxlbmd0aCgpOyArK2kpIHsKKyAgICBvd18uU3RhcnRPYmplY3QoIiIpOworICAgIERvRXJyb3JUZXN0KHN0ciwgaSwgIlVuZXhwZWN0ZWQgZW5kIG9mIHN0cmluZy4iKTsKKyAgfQorfQorCisKKy8vIG1pc21hdGNoZWQgb2JqZWN0IGFuZCBhcnJheSBjbG9zaW5nCitURVNUX0YoSnNvblN0cmVhbVBhcnNlclRlc3QsIE1pc21hdGNoZWRDbG9zZU9iamVjdCkgeworICBTdHJpbmdQaWVjZSBzdHIgPSAieydrZXknOiB0cnVlXSI7CisgIGZvciAoaW50IGkgPSAwOyBpIDw9IHN0ci5sZW5ndGgoKTsgKytpKSB7CisgICAgb3dfLlN0YXJ0T2JqZWN0KCIiKS0+UmVuZGVyQm9vbCgia2V5IiwgdHJ1ZSk7CisgICAgRG9FcnJvclRlc3Qoc3RyLCBpLCAiRXhwZWN0ZWQgLCBvciB9IGFmdGVyIGtleTp2YWx1ZSBwYWlyLiIpOworICB9Cit9CisKK1RFU1RfRihKc29uU3RyZWFtUGFyc2VyVGVzdCwgTWlzbWF0Y2hlZENsb3NlQXJyYXkpIHsKKyAgU3RyaW5nUGllY2Ugc3RyID0gIlt0cnVlLCBudWxsfSI7CisgIGZvciAoaW50IGkgPSAwOyBpIDw9IHN0ci5sZW5ndGgoKTsgKytpKSB7CisgICAgb3dfLlN0YXJ0TGlzdCgiIiktPlJlbmRlckJvb2woIiIsIHRydWUpLT5SZW5kZXJOdWxsKCIiKTsKKyAgICBEb0Vycm9yVGVzdChzdHIsIGksICJFeHBlY3RlZCAsIG9yIF0gYWZ0ZXIgYXJyYXkgdmFsdWUuIik7CisgIH0KK30KKworLy8gSW52YWxpZCBvYmplY3Qga2V5cy4KK1RFU1RfRihKc29uU3RyZWFtUGFyc2VyVGVzdCwgSW52YWxpZE51bWVyaWNPYmplY3RLZXkpIHsKKyAgU3RyaW5nUGllY2Ugc3RyID0gIns0MjogdHJ1ZX0iOworICBmb3IgKGludCBpID0gMDsgaSA8PSBzdHIubGVuZ3RoKCk7ICsraSkgeworICAgIG93Xy5TdGFydE9iamVjdCgiIik7CisgICAgRG9FcnJvclRlc3Qoc3RyLCBpLCAiRXhwZWN0ZWQgYW4gb2JqZWN0IGtleSBvciB9LiIpOworICB9Cit9CisKK1RFU1RfRihKc29uU3RyZWFtUGFyc2VyVGVzdCwgSW52YWxpZExpdGVyYWxPYmplY3RJbk9iamVjdCkgeworICBTdHJpbmdQaWVjZSBzdHIgPSAie3tib2I6IHRydWV9fSI7CisgIGZvciAoaW50IGkgPSAwOyBpIDw9IHN0ci5sZW5ndGgoKTsgKytpKSB7CisgICAgb3dfLlN0YXJ0T2JqZWN0KCIiKTsKKyAgICBEb0Vycm9yVGVzdChzdHIsIGksICJFeHBlY3RlZCBhbiBvYmplY3Qga2V5IG9yIH0uIik7CisgIH0KK30KKworVEVTVF9GKEpzb25TdHJlYW1QYXJzZXJUZXN0LCBJbnZhbGlkTGl0ZXJhbEFycmF5SW5PYmplY3QpIHsKKyAgU3RyaW5nUGllY2Ugc3RyID0gIntbbnVsbF19IjsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPD0gc3RyLmxlbmd0aCgpOyArK2kpIHsKKyAgICBvd18uU3RhcnRPYmplY3QoIiIpOworICAgIERvRXJyb3JUZXN0KHN0ciwgaSwgIkV4cGVjdGVkIGFuIG9iamVjdCBrZXkgb3IgfS4iKTsKKyAgfQorfQorCitURVNUX0YoSnNvblN0cmVhbVBhcnNlclRlc3QsIEludmFsaWRMaXRlcmFsVmFsdWVJbk9iamVjdCkgeworICBTdHJpbmdQaWVjZSBzdHIgPSAie2ZhbHNlfSI7CisgIGZvciAoaW50IGkgPSAwOyBpIDw9IHN0ci5sZW5ndGgoKTsgKytpKSB7CisgICAgb3dfLlN0YXJ0T2JqZWN0KCIiKTsKKyAgICBEb0Vycm9yVGVzdChzdHIsIGksICJFeHBlY3RlZCBhbiBvYmplY3Qga2V5IG9yIH0uIik7CisgIH0KK30KKworVEVTVF9GKEpzb25TdHJlYW1QYXJzZXJUZXN0LCBNaXNzaW5nQ29sb25BZnRlclN0cmluZ0luT2JqZWN0KSB7CisgIFN0cmluZ1BpZWNlIHN0ciA9ICJ7XCJrZXlcIn0iOworICBmb3IgKGludCBpID0gMDsgaSA8PSBzdHIubGVuZ3RoKCk7ICsraSkgeworICAgIG93Xy5TdGFydE9iamVjdCgiIik7CisgICAgRG9FcnJvclRlc3Qoc3RyLCBpLCAiRXhwZWN0ZWQgOiBiZXR3ZWVuIGtleTp2YWx1ZSBwYWlyLiIpOworICB9Cit9CisKK1RFU1RfRihKc29uU3RyZWFtUGFyc2VyVGVzdCwgTWlzc2luZ0NvbG9uQWZ0ZXJLZXlJbk9iamVjdCkgeworICBTdHJpbmdQaWVjZSBzdHIgPSAie2tleX0iOworICBmb3IgKGludCBpID0gMDsgaSA8PSBzdHIubGVuZ3RoKCk7ICsraSkgeworICAgIG93Xy5TdGFydE9iamVjdCgiIik7CisgICAgRG9FcnJvclRlc3Qoc3RyLCBpLCAiRXhwZWN0ZWQgOiBiZXR3ZWVuIGtleTp2YWx1ZSBwYWlyLiIpOworICB9Cit9CisKK1RFU1RfRihKc29uU3RyZWFtUGFyc2VyVGVzdCwgRW5kT2ZUZXh0QWZ0ZXJLZXlJbk9iamVjdCkgeworICBTdHJpbmdQaWVjZSBzdHIgPSAie2tleSI7CisgIGZvciAoaW50IGkgPSAwOyBpIDw9IHN0ci5sZW5ndGgoKTsgKytpKSB7CisgICAgb3dfLlN0YXJ0T2JqZWN0KCIiKTsKKyAgICBEb0Vycm9yVGVzdChzdHIsIGksICJVbmV4cGVjdGVkIGVuZCBvZiBzdHJpbmcuIik7CisgIH0KK30KKworVEVTVF9GKEpzb25TdHJlYW1QYXJzZXJUZXN0LCBNaXNzaW5nVmFsdWVBZnRlckNvbG9uSW5PYmplY3QpIHsKKyAgU3RyaW5nUGllY2Ugc3RyID0gIntrZXk6fSI7CisgIGZvciAoaW50IGkgPSAwOyBpIDw9IHN0ci5sZW5ndGgoKTsgKytpKSB7CisgICAgb3dfLlN0YXJ0T2JqZWN0KCIiKTsKKyAgICBEb0Vycm9yVGVzdChzdHIsIGksICJVbmV4cGVjdGVkIHRva2VuLiIpOworICB9Cit9CisKK1RFU1RfRihKc29uU3RyZWFtUGFyc2VyVGVzdCwgTWlzc2luZ0NvbW1hQmV0d2Vlbk9iamVjdEVudHJpZXMpIHsKKyAgU3RyaW5nUGllY2Ugc3RyID0gIntrZXk6MjAgJ2hlbGxvJzogdHJ1ZX0iOworICBmb3IgKGludCBpID0gMDsgaSA8PSBzdHIubGVuZ3RoKCk7ICsraSkgeworICAgIG93Xy5TdGFydE9iamVjdCgiIiktPlJlbmRlclVpbnQ2NCgia2V5IiwgMjApOworICAgIERvRXJyb3JUZXN0KHN0ciwgaSwgIkV4cGVjdGVkICwgb3IgfSBhZnRlciBrZXk6dmFsdWUgcGFpci4iKTsKKyAgfQorfQorCitURVNUX0YoSnNvblN0cmVhbVBhcnNlclRlc3QsIEludmFsaWRMaXRlcmFsQXNPYmplY3RLZXkpIHsKKyAgU3RyaW5nUGllY2Ugc3RyID0gIntmYWxzZTogMjB9IjsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPD0gc3RyLmxlbmd0aCgpOyArK2kpIHsKKyAgICBvd18uU3RhcnRPYmplY3QoIiIpOworICAgIERvRXJyb3JUZXN0KHN0ciwgaSwgIkV4cGVjdGVkIGFuIG9iamVjdCBrZXkgb3IgfS4iKTsKKyAgfQorfQorCitURVNUX0YoSnNvblN0cmVhbVBhcnNlclRlc3QsIEV4dHJhQ2hhcmFjdGVyc0FmdGVyT2JqZWN0KSB7CisgIFN0cmluZ1BpZWNlIHN0ciA9ICJ7fX0iOworICBmb3IgKGludCBpID0gMDsgaSA8PSBzdHIubGVuZ3RoKCk7ICsraSkgeworICAgIG93Xy5TdGFydE9iamVjdCgiIiktPkVuZE9iamVjdCgpOworICAgIERvRXJyb3JUZXN0KHN0ciwgaSwgIlBhcnNpbmcgdGVybWluYXRlZCBiZWZvcmUgZW5kIG9mIGlucHV0LiIpOworICB9Cit9CisKKy8vIG51bWJlcnMgdG9vIGxhcmdlCitURVNUX0YoSnNvblN0cmVhbVBhcnNlclRlc3QsIFBvc2l0aXZlTnVtYmVyVG9vQmlnKSB7CisgIFN0cmluZ1BpZWNlIHN0ciA9ICJbMTg0NDY3NDQwNzM3MDk1NTE2MTZdIjsgIC8vIDJeNjQKKyAgZm9yIChpbnQgaSA9IDA7IGkgPD0gc3RyLmxlbmd0aCgpOyArK2kpIHsKKyAgICBvd18uU3RhcnRMaXN0KCIiKTsKKyAgICBEb0Vycm9yVGVzdChzdHIsIGksICJVbmFibGUgdG8gcGFyc2UgbnVtYmVyLiIpOworICB9Cit9CisKK1RFU1RfRihKc29uU3RyZWFtUGFyc2VyVGVzdCwgTmVnYXRpdmVOdW1iZXJUb29CaWcpIHsKKyAgU3RyaW5nUGllY2Ugc3RyID0gIlstMTg0NDY3NDQwNzM3MDk1NTE2MTZdIjsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPD0gc3RyLmxlbmd0aCgpOyArK2kpIHsKKyAgICBvd18uU3RhcnRMaXN0KCIiKTsKKyAgICBEb0Vycm9yVGVzdChzdHIsIGksICJVbmFibGUgdG8gcGFyc2UgbnVtYmVyLiIpOworICB9Cit9CisKKy8qCitUT0RPKHN2ZW4pOiBGYWlsIHBhcnNpbmcgd2hlbiBwYXJzaW5nIGEgZG91YmxlIHRoYXQgaXMgdG9vIGxhcmdlLgorCitURVNUX0YoSnNvblN0cmVhbVBhcnNlclRlc3QsIERvdWJsZVRvb0JpZykgeworICBTdHJpbmdQaWVjZSBzdHIgPSAiWzE4NDQ2NDA3MzcwOTU1MTIzMjMyMTYxNi40NV0iOworICBmb3IgKGludCBpID0gMDsgaSA8PSBzdHIubGVuZ3RoKCk7ICsraSkgeworICAgIG93Xy5TdGFydExpc3QoIiIpOworICAgIERvRXJyb3JUZXN0KHN0ciwgaSwgIlVuYWJsZSB0byBwYXJzZSBudW1iZXIiKTsKKyAgfQorfQorKi8KKworLy8gaW52YWxpZCB1bmljb2RlIHNlcXVlbmNlLgorVEVTVF9GKEpzb25TdHJlYW1QYXJzZXJUZXN0LCBVbmljb2RlRXNjYXBlQ3V0T2ZmKSB7CisgIFN0cmluZ1BpZWNlIHN0ciA9ICJcIlxcdTEyIjsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPD0gc3RyLmxlbmd0aCgpOyArK2kpIHsKKyAgICBEb0Vycm9yVGVzdChzdHIsIGksICJJbGxlZ2FsIGhleCBzdHJpbmcuIik7CisgIH0KK30KKworVEVTVF9GKEpzb25TdHJlYW1QYXJzZXJUZXN0LCBVbmljb2RlRXNjYXBlSW52YWxpZENoYXJhY3RlcnMpIHsKKyAgU3RyaW5nUGllY2Ugc3RyID0gIlwiXFx1MTIkNGhlbGxvIjsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPD0gc3RyLmxlbmd0aCgpOyArK2kpIHsKKyAgICBEb0Vycm9yVGVzdChzdHIsIGksICJJbnZhbGlkIGVzY2FwZSBzZXF1ZW5jZS4iKTsKKyAgfQorfQorCisvLyBFeHRyYSBjb21tYXMgd2l0aCBhbiBvYmplY3Qgb3IgYXJyYXkuCitURVNUX0YoSnNvblN0cmVhbVBhcnNlclRlc3QsIEV4dHJhQ29tbWFJbk9iamVjdCkgeworICBTdHJpbmdQaWVjZSBzdHIgPSAieydrMSc6IHRydWUsLCdrMic6IGZhbHNlfSI7CisgIGZvciAoaW50IGkgPSAwOyBpIDw9IHN0ci5sZW5ndGgoKTsgKytpKSB7CisgICAgb3dfLlN0YXJ0T2JqZWN0KCIiKS0+UmVuZGVyQm9vbCgiazEiLCB0cnVlKTsKKyAgICBEb0Vycm9yVGVzdChzdHIsIGksICJFeHBlY3RlZCBhbiBvYmplY3Qga2V5IG9yIH0uIik7CisgIH0KK30KKworVEVTVF9GKEpzb25TdHJlYW1QYXJzZXJUZXN0LCBFeHRyYUNvbW1hSW5BcnJheSkgeworICBTdHJpbmdQaWVjZSBzdHIgPSAiW3RydWUsLGZhbHNlfSI7CisgIGZvciAoaW50IGkgPSAwOyBpIDw9IHN0ci5sZW5ndGgoKTsgKytpKSB7CisgICAgb3dfLlN0YXJ0TGlzdCgiIiktPlJlbmRlckJvb2woIiIsIHRydWUpOworICAgIERvRXJyb3JUZXN0KHN0ciwgaSwgIlVuZXhwZWN0ZWQgdG9rZW4uIik7CisgIH0KK30KKworLy8gRXh0cmEgdGV4dCBiZXlvbmQgZW5kIG9mIHZhbHVlLgorVEVTVF9GKEpzb25TdHJlYW1QYXJzZXJUZXN0LCBFeHRyYVRleHRBZnRlckxpdGVyYWwpIHsKKyAgU3RyaW5nUGllY2Ugc3RyID0gIidoZWxsbycsICd3b3JsZCciOworICBmb3IgKGludCBpID0gMDsgaSA8PSBzdHIubGVuZ3RoKCk7ICsraSkgeworICAgIG93Xy5SZW5kZXJTdHJpbmcoIiIsICJoZWxsbyIpOworICAgIERvRXJyb3JUZXN0KHN0ciwgaSwgIlBhcnNpbmcgdGVybWluYXRlZCBiZWZvcmUgZW5kIG9mIGlucHV0LiIpOworICB9Cit9CisKK1RFU1RfRihKc29uU3RyZWFtUGFyc2VyVGVzdCwgRXh0cmFUZXh0QWZ0ZXJPYmplY3QpIHsKKyAgU3RyaW5nUGllY2Ugc3RyID0gInsna2V5JzogdHJ1ZX0gJ29vcHMnIjsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPD0gc3RyLmxlbmd0aCgpOyArK2kpIHsKKyAgICBvd18uU3RhcnRPYmplY3QoIiIpLT5SZW5kZXJCb29sKCJrZXkiLCB0cnVlKS0+RW5kT2JqZWN0KCk7CisgICAgRG9FcnJvclRlc3Qoc3RyLCBpLCAiUGFyc2luZyB0ZXJtaW5hdGVkIGJlZm9yZSBlbmQgb2YgaW5wdXQuIik7CisgIH0KK30KKworVEVTVF9GKEpzb25TdHJlYW1QYXJzZXJUZXN0LCBFeHRyYVRleHRBZnRlckFycmF5KSB7CisgIFN0cmluZ1BpZWNlIHN0ciA9ICJbbnVsbF0gJ29vcHMnIjsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPD0gc3RyLmxlbmd0aCgpOyArK2kpIHsKKyAgICBvd18uU3RhcnRMaXN0KCIiKS0+UmVuZGVyTnVsbCgiIiktPkVuZExpc3QoKTsKKyAgICBEb0Vycm9yVGVzdChzdHIsIGksICJQYXJzaW5nIHRlcm1pbmF0ZWQgYmVmb3JlIGVuZCBvZiBpbnB1dC4iKTsKKyAgfQorfQorCisvLyBSYW5kb20gdW5rbm93biB0ZXh0IGluIHRoZSB2YWx1ZS4KK1RFU1RfRihKc29uU3RyZWFtUGFyc2VyVGVzdCwgVW5rbm93bkNoYXJhY3RlcnNBc1ZhbHVlKSB7CisgIFN0cmluZ1BpZWNlIHN0ciA9ICIqJiMyNSI7CisgIGZvciAoaW50IGkgPSAwOyBpIDw9IHN0ci5sZW5ndGgoKTsgKytpKSB7CisgICAgRG9FcnJvclRlc3Qoc3RyLCBpLCAiRXhwZWN0ZWQgYSB2YWx1ZS4iKTsKKyAgfQorfQorCitURVNUX0YoSnNvblN0cmVhbVBhcnNlclRlc3QsIFVua25vd25DaGFyYWN0ZXJzSW5BcnJheSkgeworICBTdHJpbmdQaWVjZSBzdHIgPSAiWyomIzI1XSI7CisgIGZvciAoaW50IGkgPSAwOyBpIDw9IHN0ci5sZW5ndGgoKTsgKytpKSB7CisgICAgb3dfLlN0YXJ0TGlzdCgiIik7CisgICAgRG9FcnJvclRlc3Qoc3RyLCBpLCAiRXhwZWN0ZWQgYSB2YWx1ZSBvciBdIHdpdGhpbiBhbiBhcnJheS4iKTsKKyAgfQorfQorCitURVNUX0YoSnNvblN0cmVhbVBhcnNlclRlc3QsIFVua25vd25DaGFyYWN0ZXJzSW5PYmplY3QpIHsKKyAgU3RyaW5nUGllY2Ugc3RyID0gInsna2V5JzogKiYjMjV9IjsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPD0gc3RyLmxlbmd0aCgpOyArK2kpIHsKKyAgICBvd18uU3RhcnRPYmplY3QoIiIpOworICAgIERvRXJyb3JUZXN0KHN0ciwgaSwgIkV4cGVjdGVkIGEgdmFsdWUuIik7CisgIH0KK30KKworfSAgLy8gbmFtZXNwYWNlIGNvbnZlcnRlcgorfSAgLy8gbmFtZXNwYWNlIHV0aWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL2xvY2F0aW9uX3RyYWNrZXIuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9sb2NhdGlvbl90cmFja2VyLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDg2NGIwNQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9sb2NhdGlvbl90cmFja2VyLmgKQEAgLTAsMCArMSw2NSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX1VUSUxfQ09OVkVSVEVSX0xPQ0FUSU9OX1RSQUNLRVJfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9VVElMX0NPTlZFUlRFUl9MT0NBVElPTl9UUkFDS0VSX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgdXRpbCB7CituYW1lc3BhY2UgY29udmVydGVyIHsKKworLy8gTG9jYXRpb25UcmFja2VySW50ZXJmYWNlIGlzIGFuIGludGVyZmFjZSBmb3IgY2xhc3NlcyB0aGF0IHRyYWNrCisvLyB0aGUgbG9jYXRpb24gaW5mb3JtYXRpb24gZm9yIHRoZSBwdXJwb3NlIG9mIGVycm9yIHJlcG9ydGluZy4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBMb2NhdGlvblRyYWNrZXJJbnRlcmZhY2UgeworIHB1YmxpYzoKKyAgdmlydHVhbCB+TG9jYXRpb25UcmFja2VySW50ZXJmYWNlKCkge30KKworICAvLyBSZXR1cm5zIHRoZSBvYmplY3QgbG9jYXRpb24gYXMgaHVtYW4gcmVhZGFibGUgc3RyaW5nLgorICB2aXJ0dWFsIHN0cmluZyBUb1N0cmluZygpIGNvbnN0ID0gMDsKKworIHByb3RlY3RlZDoKKyAgTG9jYXRpb25UcmFja2VySW50ZXJmYWNlKCkge30KKworIHByaXZhdGU6CisgIC8vIFBsZWFzZSBkbyBub3QgYWRkIGFueSBkYXRhIG1lbWJlcnMgdG8gdGhpcyBjbGFzcy4KKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKExvY2F0aW9uVHJhY2tlckludGVyZmFjZSk7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgY29udmVydGVyCit9ICAvLyBuYW1lc3BhY2UgdXRpbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX1VUSUxfQ09OVkVSVEVSX0xPQ0FUSU9OX1RSQUNLRVJfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvbW9ja19lcnJvcl9saXN0ZW5lci5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL21vY2tfZXJyb3JfbGlzdGVuZXIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41OTFjMzVkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL21vY2tfZXJyb3JfbGlzdGVuZXIuaApAQCAtMCwwICsxLDYzIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfVVRJTF9DT05WRVJURVJfTU9DS19FUlJPUl9MSVNURU5FUl9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1VUSUxfQ09OVkVSVEVSX01PQ0tfRVJST1JfTElTVEVORVJfSF9fCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RyaW5ncGllY2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9lcnJvcl9saXN0ZW5lci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL2xvY2F0aW9uX3RyYWNrZXIuaD4KKyNpbmNsdWRlIDxnbW9jay9nbW9jay5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgdXRpbCB7CituYW1lc3BhY2UgY29udmVydGVyIHsKKworY2xhc3MgTW9ja0Vycm9yTGlzdGVuZXIgOiBwdWJsaWMgRXJyb3JMaXN0ZW5lciB7CisgcHVibGljOgorICBNb2NrRXJyb3JMaXN0ZW5lcigpIHt9CisgIHZpcnR1YWwgfk1vY2tFcnJvckxpc3RlbmVyKCkge30KKworICBNT0NLX01FVEhPRDMoSW52YWxpZE5hbWUsIHZvaWQoY29uc3QgTG9jYXRpb25UcmFja2VySW50ZXJmYWNlJiBsb2MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdQaWVjZSB1bmtub3duX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdQaWVjZSBtZXNzYWdlKSk7CisgIE1PQ0tfTUVUSE9EMyhJbnZhbGlkVmFsdWUsIHZvaWQoY29uc3QgTG9jYXRpb25UcmFja2VySW50ZXJmYWNlJiBsb2MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UgdHlwZV9uYW1lLCBTdHJpbmdQaWVjZSB2YWx1ZSkpOworICBNT0NLX01FVEhPRDIoTWlzc2luZ0ZpZWxkLCB2b2lkKGNvbnN0IExvY2F0aW9uVHJhY2tlckludGVyZmFjZSYgbG9jLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1BpZWNlIG1pc3NpbmdfbmFtZSkpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGNvbnZlcnRlcgorfSAgLy8gbmFtZXNwYWNlIHV0aWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9VVElMX0NPTlZFUlRFUl9NT0NLX0VSUk9SX0xJU1RFTkVSX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL29iamVjdF9sb2NhdGlvbl90cmFja2VyLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvb2JqZWN0X2xvY2F0aW9uX3RyYWNrZXIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NTg2Y2VjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL29iamVjdF9sb2NhdGlvbl90cmFja2VyLmgKQEAgLTAsMCArMSw2NCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX1VUSUxfQ09OVkVSVEVSX09CSkVDVF9MT0NBVElPTl9UUkFDS0VSX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfVVRJTF9DT05WRVJURVJfT0JKRUNUX0xPQ0FUSU9OX1RSQUNLRVJfSF9fCisKKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvbG9jYXRpb25fdHJhY2tlci5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgdXRpbCB7CituYW1lc3BhY2UgY29udmVydGVyIHsKKworLy8gQW4gZW1wdHkgY29uY3JldGUgaW1wbGVtZW50YXRpb24gb2YgTG9jYXRpb25UcmFja2VySW50ZXJmYWNlLgorY2xhc3MgT2JqZWN0TG9jYXRpb25UcmFja2VyIDogcHVibGljIExvY2F0aW9uVHJhY2tlckludGVyZmFjZSB7CisgcHVibGljOgorICAvLyBDcmVhdGVzIGFuIGVtcHR5IGxvY2F0aW9uIHRyYWNrZXIuCisgIE9iamVjdExvY2F0aW9uVHJhY2tlcigpIHt9CisKKyAgdmlydHVhbCB+T2JqZWN0TG9jYXRpb25UcmFja2VyKCkge30KKworICAvLyBSZXR1cm5zIGVtcHR5IGJlY2F1c2Ugbm90aGluZyBpcyB0cmFja2VkLgorICB2aXJ0dWFsIHN0cmluZyBUb1N0cmluZygpIGNvbnN0IHsgcmV0dXJuICIiOyB9CisKKyBwcml2YXRlOgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoT2JqZWN0TG9jYXRpb25UcmFja2VyKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBjb252ZXJ0ZXIKK30gIC8vIG5hbWVzcGFjZSB1dGlsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfVVRJTF9DT05WRVJURVJfT0JKRUNUX0xPQ0FUSU9OX1RSQUNLRVJfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvb2JqZWN0X3NvdXJjZS5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL29iamVjdF9zb3VyY2UuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYzMxY2ZiCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL29iamVjdF9zb3VyY2UuaApAQCAtMCwwICsxLDc5IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfVVRJTF9DT05WRVJURVJfT0JKRUNUX1NPVVJDRV9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1VUSUxfQ09OVkVSVEVSX09CSkVDVF9TT1VSQ0VfSF9fCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cmluZ3BpZWNlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0YXR1cy5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgdXRpbCB7CituYW1lc3BhY2UgY29udmVydGVyIHsKKworY2xhc3MgT2JqZWN0V3JpdGVyOworCisvLyBBbiBPYmplY3RTb3VyY2UgaXMgYW55dGhpbmcgdGhhdCBjYW4gd3JpdGUgdG8gYW4gT2JqZWN0V3JpdGVyLgorLy8gSW1wbGVtZW50YXRpb24gb2YgdGhpcyBpbnRlcmZhY2UgdHlwaWNhbGx5IHByb3ZpZGUgY29uc3RydWN0b3JzIG9yCisvLyBmYWN0b3J5IG1ldGhvZHMgdG8gY3JlYXRlIGFuIGluc3RhbmNlIGJhc2VkIG9uIHNvbWUgc291cmNlIGRhdGEsIGZvcgorLy8gZXhhbXBsZSwgYSBjaGFyYWN0ZXIgc3RyZWFtLCBvciBwcm90b2J1Zi4KKy8vCisvLyBEZXJpdmVkIGNsYXNzZXMgY291bGQgYmUgdGhyZWFkLXVuc2FmZS4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBPYmplY3RTb3VyY2UgeworIHB1YmxpYzoKKyAgdmlydHVhbCB+T2JqZWN0U291cmNlKCkge30KKworICAvLyBXcml0ZXMgdG8gdGhlIE9iamVjdFdyaXRlcgorICB2aXJ0dWFsIHV0aWw6OlN0YXR1cyBXcml0ZVRvKE9iamVjdFdyaXRlciogb3cpIGNvbnN0IHsKKyAgICByZXR1cm4gTmFtZWRXcml0ZVRvKCIiLCBvdyk7CisgIH0KKworICAvLyBXcml0ZXMgdG8gdGhlIE9iamVjdFdyaXRlciB3aXRoIGEgY3VzdG9tIG5hbWUgZm9yIHRoZSBtZXNzYWdlLgorICAvLyBUaGlzIGlzIHVzZWZ1bCB3aGVuIHlvdSBjaGFpbiBPYmplY3RTb3VyY2UgdG9nZXRoZXIgYnkgZW1iZWRkaW5nIG9uZQorICAvLyB3aXRoaW4gYW5vdGhlci4KKyAgdmlydHVhbCB1dGlsOjpTdGF0dXMgTmFtZWRXcml0ZVRvKFN0cmluZ1BpZWNlIG5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdFdyaXRlciogb3cpIGNvbnN0ID0gMDsKKworIHByb3RlY3RlZDoKKyAgT2JqZWN0U291cmNlKCkge30KKworIHByaXZhdGU6CisgIC8vIERvIG5vdCBhZGQgYW55IGRhdGEgbWVtYmVycyB0byB0aGlzIGNsYXNzLgorICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoT2JqZWN0U291cmNlKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBjb252ZXJ0ZXIKK30gIC8vIG5hbWVzcGFjZSB1dGlsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfVVRJTF9DT05WRVJURVJfT0JKRUNUX1NPVVJDRV9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9vYmplY3Rfd3JpdGVyLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL29iamVjdF93cml0ZXIuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTdjYzA4YQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9vYmplY3Rfd3JpdGVyLmNjCkBAIC0wLDAgKzEsOTIgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvb2JqZWN0X3dyaXRlci5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvZGF0YXBpZWNlLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSB1dGlsIHsKK25hbWVzcGFjZSBjb252ZXJ0ZXIgeworCisvLyBzdGF0aWMKK3ZvaWQgT2JqZWN0V3JpdGVyOjpSZW5kZXJEYXRhUGllY2VUbyhjb25zdCBEYXRhUGllY2UmIGRhdGEsIFN0cmluZ1BpZWNlIG5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0V3JpdGVyKiBvdykgeworICBzd2l0Y2ggKGRhdGEudHlwZSgpKSB7CisgICAgY2FzZSBEYXRhUGllY2U6OlRZUEVfSU5UMzI6IHsKKyAgICAgIG93LT5SZW5kZXJJbnQzMihuYW1lLCBkYXRhLlRvSW50MzIoKS5WYWx1ZU9yRGllKCkpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgRGF0YVBpZWNlOjpUWVBFX0lOVDY0OiB7CisgICAgICBvdy0+UmVuZGVySW50NjQobmFtZSwgZGF0YS5Ub0ludDY0KCkuVmFsdWVPckRpZSgpKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIERhdGFQaWVjZTo6VFlQRV9VSU5UMzI6IHsKKyAgICAgIG93LT5SZW5kZXJVaW50MzIobmFtZSwgZGF0YS5Ub1VpbnQzMigpLlZhbHVlT3JEaWUoKSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBEYXRhUGllY2U6OlRZUEVfVUlOVDY0OiB7CisgICAgICBvdy0+UmVuZGVyVWludDY0KG5hbWUsIGRhdGEuVG9VaW50NjQoKS5WYWx1ZU9yRGllKCkpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgRGF0YVBpZWNlOjpUWVBFX0RPVUJMRTogeworICAgICAgb3ctPlJlbmRlckRvdWJsZShuYW1lLCBkYXRhLlRvRG91YmxlKCkuVmFsdWVPckRpZSgpKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIERhdGFQaWVjZTo6VFlQRV9GTE9BVDogeworICAgICAgb3ctPlJlbmRlckZsb2F0KG5hbWUsIGRhdGEuVG9GbG9hdCgpLlZhbHVlT3JEaWUoKSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBEYXRhUGllY2U6OlRZUEVfQk9PTDogeworICAgICAgb3ctPlJlbmRlckJvb2wobmFtZSwgZGF0YS5Ub0Jvb2woKS5WYWx1ZU9yRGllKCkpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgRGF0YVBpZWNlOjpUWVBFX1NUUklORzogeworICAgICAgb3ctPlJlbmRlclN0cmluZyhuYW1lLCBkYXRhLlRvU3RyaW5nKCkuVmFsdWVPckRpZSgpKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIERhdGFQaWVjZTo6VFlQRV9CWVRFUzogeworICAgICAgb3ctPlJlbmRlckJ5dGVzKG5hbWUsIGRhdGEuVG9CeXRlcygpLlZhbHVlT3JEaWUoKSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBEYXRhUGllY2U6OlRZUEVfTlVMTDogeworICAgICAgb3ctPlJlbmRlck51bGwobmFtZSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgZGVmYXVsdDoKKyAgICAgIGJyZWFrOworICB9Cit9CisKK30gIC8vIG5hbWVzcGFjZSBjb252ZXJ0ZXIKK30gIC8vIG5hbWVzcGFjZSB1dGlsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9vYmplY3Rfd3JpdGVyLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvb2JqZWN0X3dyaXRlci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU2OTVmNDUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvb2JqZWN0X3dyaXRlci5oCkBAIC0wLDAgKzEsMTIxIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfVVRJTF9DT05WRVJURVJfT0JKRUNUX1dSSVRFUl9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1VUSUxfQ09OVkVSVEVSX09CSkVDVF9XUklURVJfSF9fCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cmluZ3BpZWNlLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSB1dGlsIHsKK25hbWVzcGFjZSBjb252ZXJ0ZXIgeworCitjbGFzcyBEYXRhUGllY2U7CisKKy8vIEFuIE9iamVjdFdyaXRlciBpcyBhbiBpbnRlcmZhY2UgZm9yIHdyaXRpbmcgYSBzdHJlYW0gb2YgZXZlbnRzCisvLyByZXByZXNlbnRpbmcgb2JqZWN0cyBhbmQgY29sbGVjdGlvbnMuIEltcGxlbWVudGF0aW9uIG9mIHRoaXMKKy8vIGludGVyZmFjZSBjYW4gYmUgdXNlZCB0byB3cml0ZSBhbiBvYmplY3Qgc3RyZWFtIHRvIGFuIGluLW1lbW9yeQorLy8gc3RydWN0dXJlLCBwcm90b2J1ZnMsIEpTT04sIFhNTCwgb3IgYW55IG90aGVyIG91dHB1dCBmb3JtYXQKKy8vIGRlc2lyZWQuIFRoZSBPYmplY3RTb3VyY2UgaW50ZXJmYWNlIGlzIHR5cGljYWxseSB1c2VkIGFzIHRoZQorLy8gc291cmNlIG9mIGFuIG9iamVjdCBzdHJlYW0uCisvLworLy8gU2VlIEpzb25PYmplY3RXcml0ZXIgZm9yIGEgc2FtcGxlIGltcGxlbWVudGF0aW9uIG9mIE9iamVjdFdyaXRlcgorLy8gYW5kIGl0cyB1c2UuCisvLworLy8gRGVyaXZlZCBjbGFzc2VzIGNvdWxkIGJlIHRocmVhZC11bnNhZmUuCisvLworLy8gVE9ETyh4aW5iKTogc2VlbXMgbGlrZSBhIHByaW1lIGNhbmRpZGF0ZSB0byBhcHBseSB0aGUgUkFJSSBwYXJhZGlnbQorLy8gYW5kIGdldCByaWQgdGhlIG5lZWQgdG8gY2FsbCBFbmRYWFgoKS4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBPYmplY3RXcml0ZXIgeworIHB1YmxpYzoKKyAgdmlydHVhbCB+T2JqZWN0V3JpdGVyKCkge30KKworICAvLyBTdGFydHMgYW4gb2JqZWN0LiBJZiB0aGUgbmFtZSBpcyBlbXB0eSwgdGhlIG9iamVjdCB3aWxsIG5vdCBiZSBuYW1lZC4KKyAgdmlydHVhbCBPYmplY3RXcml0ZXIqIFN0YXJ0T2JqZWN0KFN0cmluZ1BpZWNlIG5hbWUpID0gMDsKKworICAvLyBFbmRzIGFuIG9iamVjdC4KKyAgdmlydHVhbCBPYmplY3RXcml0ZXIqIEVuZE9iamVjdCgpID0gMDsKKworICAvLyBTdGFydHMgYSBsaXN0LiBJZiB0aGUgbmFtZSBpcyBlbXB0eSwgdGhlIGxpc3Qgd2lsbCBub3QgYmUgbmFtZWQuCisgIHZpcnR1YWwgT2JqZWN0V3JpdGVyKiBTdGFydExpc3QoU3RyaW5nUGllY2UgbmFtZSkgPSAwOworCisgIC8vIEVuZHMgYSBsaXN0LgorICB2aXJ0dWFsIE9iamVjdFdyaXRlciogRW5kTGlzdCgpID0gMDsKKworICAvLyBSZW5kZXJzIGEgYm9vbGVhbiB2YWx1ZS4KKyAgdmlydHVhbCBPYmplY3RXcml0ZXIqIFJlbmRlckJvb2woU3RyaW5nUGllY2UgbmFtZSwgYm9vbCB2YWx1ZSkgPSAwOworCisgIC8vIFJlbmRlcnMgYW4gMzItYml0IGludGVnZXIgdmFsdWUuCisgIHZpcnR1YWwgT2JqZWN0V3JpdGVyKiBSZW5kZXJJbnQzMihTdHJpbmdQaWVjZSBuYW1lLCBpbnQzMiB2YWx1ZSkgPSAwOworCisgIC8vIFJlbmRlcnMgYW4gMzItYml0IHVuc2lnbmVkIGludGVnZXIgdmFsdWUuCisgIHZpcnR1YWwgT2JqZWN0V3JpdGVyKiBSZW5kZXJVaW50MzIoU3RyaW5nUGllY2UgbmFtZSwgdWludDMyIHZhbHVlKSA9IDA7CisKKyAgLy8gUmVuZGVycyBhIDY0LWJpdCBpbnRlZ2VyIHZhbHVlLgorICB2aXJ0dWFsIE9iamVjdFdyaXRlciogUmVuZGVySW50NjQoU3RyaW5nUGllY2UgbmFtZSwgaW50NjQgdmFsdWUpID0gMDsKKworICAvLyBSZW5kZXJzIGFuIDY0LWJpdCB1bnNpZ25lZCBpbnRlZ2VyIHZhbHVlLgorICB2aXJ0dWFsIE9iamVjdFdyaXRlciogUmVuZGVyVWludDY0KFN0cmluZ1BpZWNlIG5hbWUsIHVpbnQ2NCB2YWx1ZSkgPSAwOworCisgIC8vIFJlbmRlcnMgYSBkb3VibGUgdmFsdWUuCisgIHZpcnR1YWwgT2JqZWN0V3JpdGVyKiBSZW5kZXJEb3VibGUoU3RyaW5nUGllY2UgbmFtZSwgZG91YmxlIHZhbHVlKSA9IDA7CisKKyAgLy8gUmVuZGVycyBhIGZsb2F0IHZhbHVlLgorICB2aXJ0dWFsIE9iamVjdFdyaXRlciogUmVuZGVyRmxvYXQoU3RyaW5nUGllY2UgbmFtZSwgZmxvYXQgdmFsdWUpID0gMDsKKworICAvLyBSZW5kZXJzIGEgU3RyaW5nUGllY2UgdmFsdWUuIFRoaXMgaXMgZm9yIHJlbmRlcmluZyBzdHJpbmdzLgorICB2aXJ0dWFsIE9iamVjdFdyaXRlciogUmVuZGVyU3RyaW5nKFN0cmluZ1BpZWNlIG5hbWUsIFN0cmluZ1BpZWNlIHZhbHVlKSA9IDA7CisKKyAgLy8gUmVuZGVycyBhIGJ5dGVzIHZhbHVlLgorICB2aXJ0dWFsIE9iamVjdFdyaXRlciogUmVuZGVyQnl0ZXMoU3RyaW5nUGllY2UgbmFtZSwgU3RyaW5nUGllY2UgdmFsdWUpID0gMDsKKworICAvLyBSZW5kZXJzIGEgTnVsbCB2YWx1ZS4KKyAgdmlydHVhbCBPYmplY3RXcml0ZXIqIFJlbmRlck51bGwoU3RyaW5nUGllY2UgbmFtZSkgPSAwOworCisgIC8vIFJlbmRlcnMgYSBEYXRhUGllY2Ugb2JqZWN0IHRvIGEgT2JqZWN0V3JpdGVyLgorICBzdGF0aWMgdm9pZCBSZW5kZXJEYXRhUGllY2VUbyhjb25zdCBEYXRhUGllY2UmIGRhdGEsIFN0cmluZ1BpZWNlIG5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdFdyaXRlciogb3cpOworCisgcHJvdGVjdGVkOgorICBPYmplY3RXcml0ZXIoKSB7fQorCisgcHJpdmF0ZToKKyAgLy8gRG8gbm90IGFkZCBhbnkgZGF0YSBtZW1iZXJzIHRvIHRoaXMgY2xhc3MuCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhPYmplY3RXcml0ZXIpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGNvbnZlcnRlcgorfSAgLy8gbmFtZXNwYWNlIHV0aWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9VVElMX0NPTlZFUlRFUl9PQkpFQ1RfV1JJVEVSX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3Byb3RvX3dyaXRlci5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9wcm90b193cml0ZXIuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDdlMDAwOQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9wcm90b193cml0ZXIuY2MKQEAgLTAsMCArMSw3NDQgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvcHJvdG9fd3JpdGVyLmg+CisKKyNpbmNsdWRlIDxmdW5jdGlvbmFsPgorI2luY2x1ZGUgPHN0YWNrPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL29uY2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvdGltZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdF9saXRlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvZmllbGRfbWFza191dGlsaXR5Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvb2JqZWN0X2xvY2F0aW9uX3RyYWNrZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9jb25zdGFudHMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC91dGlsaXR5Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbWFwX3V0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RhdHVzb3IuaD4KKworCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgdXRpbCB7CituYW1lc3BhY2UgY29udmVydGVyIHsKKwordXNpbmcgZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOwordXNpbmcgZ29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtOwordXNpbmcgdXRpbDo6ZXJyb3I6OklOVkFMSURfQVJHVU1FTlQ7Cit1c2luZyB1dGlsOjpTdGF0dXM7Cit1c2luZyB1dGlsOjpTdGF0dXNPcjsKKworCitQcm90b1dyaXRlcjo6UHJvdG9Xcml0ZXIoVHlwZVJlc29sdmVyKiB0eXBlX3Jlc29sdmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlR5cGUmIHR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nczo6Qnl0ZVNpbmsqIG91dHB1dCwgRXJyb3JMaXN0ZW5lciogbGlzdGVuZXIpCisgICAgOiBtYXN0ZXJfdHlwZV8odHlwZSksCisgICAgICB0eXBlaW5mb18oVHlwZUluZm86Ok5ld1R5cGVJbmZvKHR5cGVfcmVzb2x2ZXIpKSwKKyAgICAgIG93bl90eXBlaW5mb18odHJ1ZSksCisgICAgICBkb25lXyhmYWxzZSksCisgICAgICBlbGVtZW50XyhOVUxMKSwKKyAgICAgIHNpemVfaW5zZXJ0XygpLAorICAgICAgb3V0cHV0XyhvdXRwdXQpLAorICAgICAgYnVmZmVyXygpLAorICAgICAgYWRhcHRlcl8oJmJ1ZmZlcl8pLAorICAgICAgc3RyZWFtXyhuZXcgQ29kZWRPdXRwdXRTdHJlYW0oJmFkYXB0ZXJfKSksCisgICAgICBsaXN0ZW5lcl8obGlzdGVuZXIpLAorICAgICAgaW52YWxpZF9kZXB0aF8oMCksCisgICAgICB0cmFja2VyXyhuZXcgT2JqZWN0TG9jYXRpb25UcmFja2VyKCkpIHt9CisKK1Byb3RvV3JpdGVyOjpQcm90b1dyaXRlcihjb25zdCBUeXBlSW5mbyogdHlwZWluZm8sCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6VHlwZSYgdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmdzOjpCeXRlU2luayogb3V0cHV0LCBFcnJvckxpc3RlbmVyKiBsaXN0ZW5lcikKKyAgICA6IG1hc3Rlcl90eXBlXyh0eXBlKSwKKyAgICAgIHR5cGVpbmZvXyh0eXBlaW5mbyksCisgICAgICBvd25fdHlwZWluZm9fKGZhbHNlKSwKKyAgICAgIGRvbmVfKGZhbHNlKSwKKyAgICAgIGVsZW1lbnRfKE5VTEwpLAorICAgICAgc2l6ZV9pbnNlcnRfKCksCisgICAgICBvdXRwdXRfKG91dHB1dCksCisgICAgICBidWZmZXJfKCksCisgICAgICBhZGFwdGVyXygmYnVmZmVyXyksCisgICAgICBzdHJlYW1fKG5ldyBDb2RlZE91dHB1dFN0cmVhbSgmYWRhcHRlcl8pKSwKKyAgICAgIGxpc3RlbmVyXyhsaXN0ZW5lciksCisgICAgICBpbnZhbGlkX2RlcHRoXygwKSwKKyAgICAgIHRyYWNrZXJfKG5ldyBPYmplY3RMb2NhdGlvblRyYWNrZXIoKSkge30KKworUHJvdG9Xcml0ZXI6On5Qcm90b1dyaXRlcigpIHsKKyAgaWYgKG93bl90eXBlaW5mb18pIHsKKyAgICBkZWxldGUgdHlwZWluZm9fOworICB9CisgIGlmIChlbGVtZW50XyA9PSBOVUxMKSByZXR1cm47CisgIC8vIENsZWFudXAgZXhwbGljaXRseSBpbiBvcmRlciB0byBhdm9pZCBkZXN0cnVjdG9yIHN0YWNrIG92ZXJmbG93IHdoZW4gaW5wdXQKKyAgLy8gaXMgZGVlcGx5IG5lc3RlZC4KKyAgLy8gQ2FzdCB0byBCYXNlRWxlbWVudCB0byBhdm9pZCBkb2luZyBhZGRpdGlvbmFsIGNoZWNrcyAobGlrZSBtaXNzaW5nIGZpZWxkcykKKyAgLy8gZHVyaW5nIHBvcCgpLgorICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPEJhc2VFbGVtZW50PiBlbGVtZW50KAorICAgICAgc3RhdGljX2Nhc3Q8QmFzZUVsZW1lbnQqPihlbGVtZW50Xy5nZXQoKSktPnBvcDxCYXNlRWxlbWVudD4oKSk7CisgIHdoaWxlIChlbGVtZW50ICE9IE5VTEwpIHsKKyAgICBlbGVtZW50LnJlc2V0KGVsZW1lbnQtPnBvcDxCYXNlRWxlbWVudD4oKSk7CisgIH0KK30KKworbmFtZXNwYWNlIHsKKworLy8gV3JpdGVzIGFuIElOVDMyIGZpZWxkLCBpbmNsdWRpbmcgdGFnIHRvIHRoZSBzdHJlYW0uCitpbmxpbmUgU3RhdHVzIFdyaXRlSW50MzIoaW50IGZpZWxkX251bWJlciwgY29uc3QgRGF0YVBpZWNlJiBkYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgIENvZGVkT3V0cHV0U3RyZWFtKiBzdHJlYW0pIHsKKyAgU3RhdHVzT3I8aW50MzI+IGkzMiA9IGRhdGEuVG9JbnQzMigpOworICBpZiAoaTMyLm9rKCkpIHsKKyAgICBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVJbnQzMihmaWVsZF9udW1iZXIsIGkzMi5WYWx1ZU9yRGllKCksIHN0cmVhbSk7CisgIH0KKyAgcmV0dXJuIGkzMi5zdGF0dXMoKTsKK30KKworLy8gd3JpdGVzIGFuIFNGSVhFRDMyIGZpZWxkLCBpbmNsdWRpbmcgdGFnLCB0byB0aGUgc3RyZWFtLgoraW5saW5lIFN0YXR1cyBXcml0ZVNGaXhlZDMyKGludCBmaWVsZF9udW1iZXIsIGNvbnN0IERhdGFQaWVjZSYgZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2RlZE91dHB1dFN0cmVhbSogc3RyZWFtKSB7CisgIFN0YXR1c09yPGludDMyPiBpMzIgPSBkYXRhLlRvSW50MzIoKTsKKyAgaWYgKGkzMi5vaygpKSB7CisgICAgV2lyZUZvcm1hdExpdGU6OldyaXRlU0ZpeGVkMzIoZmllbGRfbnVtYmVyLCBpMzIuVmFsdWVPckRpZSgpLCBzdHJlYW0pOworICB9CisgIHJldHVybiBpMzIuc3RhdHVzKCk7Cit9CisKKy8vIFdyaXRlcyBhbiBTSU5UMzIgZmllbGQsIGluY2x1ZGluZyB0YWcsIHRvIHRoZSBzdHJlYW0uCitpbmxpbmUgU3RhdHVzIFdyaXRlU0ludDMyKGludCBmaWVsZF9udW1iZXIsIGNvbnN0IERhdGFQaWVjZSYgZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgQ29kZWRPdXRwdXRTdHJlYW0qIHN0cmVhbSkgeworICBTdGF0dXNPcjxpbnQzMj4gaTMyID0gZGF0YS5Ub0ludDMyKCk7CisgIGlmIChpMzIub2soKSkgeworICAgIFdpcmVGb3JtYXRMaXRlOjpXcml0ZVNJbnQzMihmaWVsZF9udW1iZXIsIGkzMi5WYWx1ZU9yRGllKCksIHN0cmVhbSk7CisgIH0KKyAgcmV0dXJuIGkzMi5zdGF0dXMoKTsKK30KKworLy8gV3JpdGVzIGEgRklYRUQzMiBmaWVsZCwgaW5jbHVkaW5nIHRhZywgdG8gdGhlIHN0cmVhbS4KK2lubGluZSBTdGF0dXMgV3JpdGVGaXhlZDMyKGludCBmaWVsZF9udW1iZXIsIGNvbnN0IERhdGFQaWVjZSYgZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIENvZGVkT3V0cHV0U3RyZWFtKiBzdHJlYW0pIHsKKyAgU3RhdHVzT3I8dWludDMyPiB1MzIgPSBkYXRhLlRvVWludDMyKCk7CisgIGlmICh1MzIub2soKSkgeworICAgIFdpcmVGb3JtYXRMaXRlOjpXcml0ZUZpeGVkMzIoZmllbGRfbnVtYmVyLCB1MzIuVmFsdWVPckRpZSgpLCBzdHJlYW0pOworICB9CisgIHJldHVybiB1MzIuc3RhdHVzKCk7Cit9CisKKy8vIFdyaXRlcyBhIFVJTlQzMiBmaWVsZCwgaW5jbHVkaW5nIHRhZywgdG8gdGhlIHN0cmVhbS4KK2lubGluZSBTdGF0dXMgV3JpdGVVSW50MzIoaW50IGZpZWxkX251bWJlciwgY29uc3QgRGF0YVBpZWNlJiBkYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgICBDb2RlZE91dHB1dFN0cmVhbSogc3RyZWFtKSB7CisgIFN0YXR1c09yPHVpbnQzMj4gdTMyID0gZGF0YS5Ub1VpbnQzMigpOworICBpZiAodTMyLm9rKCkpIHsKKyAgICBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVVSW50MzIoZmllbGRfbnVtYmVyLCB1MzIuVmFsdWVPckRpZSgpLCBzdHJlYW0pOworICB9CisgIHJldHVybiB1MzIuc3RhdHVzKCk7Cit9CisKKy8vIFdyaXRlcyBhbiBJTlQ2NCBmaWVsZCwgaW5jbHVkaW5nIHRhZywgdG8gdGhlIHN0cmVhbS4KK2lubGluZSBTdGF0dXMgV3JpdGVJbnQ2NChpbnQgZmllbGRfbnVtYmVyLCBjb25zdCBEYXRhUGllY2UmIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgQ29kZWRPdXRwdXRTdHJlYW0qIHN0cmVhbSkgeworICBTdGF0dXNPcjxpbnQ2ND4gaTY0ID0gZGF0YS5Ub0ludDY0KCk7CisgIGlmIChpNjQub2soKSkgeworICAgIFdpcmVGb3JtYXRMaXRlOjpXcml0ZUludDY0KGZpZWxkX251bWJlciwgaTY0LlZhbHVlT3JEaWUoKSwgc3RyZWFtKTsKKyAgfQorICByZXR1cm4gaTY0LnN0YXR1cygpOworfQorCisvLyBXcml0ZXMgYW4gU0ZJWEVENjQgZmllbGQsIGluY2x1ZGluZyB0YWcsIHRvIHRoZSBzdHJlYW0uCitpbmxpbmUgU3RhdHVzIFdyaXRlU0ZpeGVkNjQoaW50IGZpZWxkX251bWJlciwgY29uc3QgRGF0YVBpZWNlJiBkYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvZGVkT3V0cHV0U3RyZWFtKiBzdHJlYW0pIHsKKyAgU3RhdHVzT3I8aW50NjQ+IGk2NCA9IGRhdGEuVG9JbnQ2NCgpOworICBpZiAoaTY0Lm9rKCkpIHsKKyAgICBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTRml4ZWQ2NChmaWVsZF9udW1iZXIsIGk2NC5WYWx1ZU9yRGllKCksIHN0cmVhbSk7CisgIH0KKyAgcmV0dXJuIGk2NC5zdGF0dXMoKTsKK30KKworLy8gV3JpdGVzIGFuIFNJTlQ2NCBmaWVsZCwgaW5jbHVkaW5nIHRhZywgdG8gdGhlIHN0cmVhbS4KK2lubGluZSBTdGF0dXMgV3JpdGVTSW50NjQoaW50IGZpZWxkX251bWJlciwgY29uc3QgRGF0YVBpZWNlJiBkYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgICBDb2RlZE91dHB1dFN0cmVhbSogc3RyZWFtKSB7CisgIFN0YXR1c09yPGludDY0PiBpNjQgPSBkYXRhLlRvSW50NjQoKTsKKyAgaWYgKGk2NC5vaygpKSB7CisgICAgV2lyZUZvcm1hdExpdGU6OldyaXRlU0ludDY0KGZpZWxkX251bWJlciwgaTY0LlZhbHVlT3JEaWUoKSwgc3RyZWFtKTsKKyAgfQorICByZXR1cm4gaTY0LnN0YXR1cygpOworfQorCisvLyBXcml0ZXMgYSBGSVhFRDY0IGZpZWxkLCBpbmNsdWRpbmcgdGFnLCB0byB0aGUgc3RyZWFtLgoraW5saW5lIFN0YXR1cyBXcml0ZUZpeGVkNjQoaW50IGZpZWxkX251bWJlciwgY29uc3QgRGF0YVBpZWNlJiBkYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29kZWRPdXRwdXRTdHJlYW0qIHN0cmVhbSkgeworICBTdGF0dXNPcjx1aW50NjQ+IHU2NCA9IGRhdGEuVG9VaW50NjQoKTsKKyAgaWYgKHU2NC5vaygpKSB7CisgICAgV2lyZUZvcm1hdExpdGU6OldyaXRlRml4ZWQ2NChmaWVsZF9udW1iZXIsIHU2NC5WYWx1ZU9yRGllKCksIHN0cmVhbSk7CisgIH0KKyAgcmV0dXJuIHU2NC5zdGF0dXMoKTsKK30KKworLy8gV3JpdGVzIGEgVUlOVDY0IGZpZWxkLCBpbmNsdWRpbmcgdGFnLCB0byB0aGUgc3RyZWFtLgoraW5saW5lIFN0YXR1cyBXcml0ZVVJbnQ2NChpbnQgZmllbGRfbnVtYmVyLCBjb25zdCBEYXRhUGllY2UmIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgIENvZGVkT3V0cHV0U3RyZWFtKiBzdHJlYW0pIHsKKyAgU3RhdHVzT3I8dWludDY0PiB1NjQgPSBkYXRhLlRvVWludDY0KCk7CisgIGlmICh1NjQub2soKSkgeworICAgIFdpcmVGb3JtYXRMaXRlOjpXcml0ZVVJbnQ2NChmaWVsZF9udW1iZXIsIHU2NC5WYWx1ZU9yRGllKCksIHN0cmVhbSk7CisgIH0KKyAgcmV0dXJuIHU2NC5zdGF0dXMoKTsKK30KKworLy8gV3JpdGVzIGEgRE9VQkxFIGZpZWxkLCBpbmNsdWRpbmcgdGFnLCB0byB0aGUgc3RyZWFtLgoraW5saW5lIFN0YXR1cyBXcml0ZURvdWJsZShpbnQgZmllbGRfbnVtYmVyLCBjb25zdCBEYXRhUGllY2UmIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgIENvZGVkT3V0cHV0U3RyZWFtKiBzdHJlYW0pIHsKKyAgU3RhdHVzT3I8ZG91YmxlPiBkID0gZGF0YS5Ub0RvdWJsZSgpOworICBpZiAoZC5vaygpKSB7CisgICAgV2lyZUZvcm1hdExpdGU6OldyaXRlRG91YmxlKGZpZWxkX251bWJlciwgZC5WYWx1ZU9yRGllKCksIHN0cmVhbSk7CisgIH0KKyAgcmV0dXJuIGQuc3RhdHVzKCk7Cit9CisKKy8vIFdyaXRlcyBhIEZMT0FUIGZpZWxkLCBpbmNsdWRpbmcgdGFnLCB0byB0aGUgc3RyZWFtLgoraW5saW5lIFN0YXR1cyBXcml0ZUZsb2F0KGludCBmaWVsZF9udW1iZXIsIGNvbnN0IERhdGFQaWVjZSYgZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBDb2RlZE91dHB1dFN0cmVhbSogc3RyZWFtKSB7CisgIFN0YXR1c09yPGZsb2F0PiBmID0gZGF0YS5Ub0Zsb2F0KCk7CisgIGlmIChmLm9rKCkpIHsKKyAgICBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVGbG9hdChmaWVsZF9udW1iZXIsIGYuVmFsdWVPckRpZSgpLCBzdHJlYW0pOworICB9CisgIHJldHVybiBmLnN0YXR1cygpOworfQorCisvLyBXcml0ZXMgYSBCT09MIGZpZWxkLCBpbmNsdWRpbmcgdGFnLCB0byB0aGUgc3RyZWFtLgoraW5saW5lIFN0YXR1cyBXcml0ZUJvb2woaW50IGZpZWxkX251bWJlciwgY29uc3QgRGF0YVBpZWNlJiBkYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgQ29kZWRPdXRwdXRTdHJlYW0qIHN0cmVhbSkgeworICBTdGF0dXNPcjxib29sPiBiID0gZGF0YS5Ub0Jvb2woKTsKKyAgaWYgKGIub2soKSkgeworICAgIFdpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2woZmllbGRfbnVtYmVyLCBiLlZhbHVlT3JEaWUoKSwgc3RyZWFtKTsKKyAgfQorICByZXR1cm4gYi5zdGF0dXMoKTsKK30KKworLy8gV3JpdGVzIGEgQllURVMgZmllbGQsIGluY2x1ZGluZyB0YWcsIHRvIHRoZSBzdHJlYW0uCitpbmxpbmUgU3RhdHVzIFdyaXRlQnl0ZXMoaW50IGZpZWxkX251bWJlciwgY29uc3QgRGF0YVBpZWNlJiBkYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgIENvZGVkT3V0cHV0U3RyZWFtKiBzdHJlYW0pIHsKKyAgU3RhdHVzT3I8c3RyaW5nPiBjID0gZGF0YS5Ub0J5dGVzKCk7CisgIGlmIChjLm9rKCkpIHsKKyAgICBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCeXRlcyhmaWVsZF9udW1iZXIsIGMuVmFsdWVPckRpZSgpLCBzdHJlYW0pOworICB9CisgIHJldHVybiBjLnN0YXR1cygpOworfQorCisvLyBXcml0ZXMgYSBTVFJJTkcgZmllbGQsIGluY2x1ZGluZyB0YWcsIHRvIHRoZSBzdHJlYW0uCitpbmxpbmUgU3RhdHVzIFdyaXRlU3RyaW5nKGludCBmaWVsZF9udW1iZXIsIGNvbnN0IERhdGFQaWVjZSYgZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgQ29kZWRPdXRwdXRTdHJlYW0qIHN0cmVhbSkgeworICBTdGF0dXNPcjxzdHJpbmc+IHMgPSBkYXRhLlRvU3RyaW5nKCk7CisgIGlmIChzLm9rKCkpIHsKKyAgICBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmcoZmllbGRfbnVtYmVyLCBzLlZhbHVlT3JEaWUoKSwgc3RyZWFtKTsKKyAgfQorICByZXR1cm4gcy5zdGF0dXMoKTsKK30KKworLy8gV3JpdGVzIGFuIEVOVU0gZmllbGQsIGluY2x1ZGluZyB0YWcsIHRvIHRoZSBzdHJlYW0uCitpbmxpbmUgU3RhdHVzIFdyaXRlRW51bShpbnQgZmllbGRfbnVtYmVyLCBjb25zdCBEYXRhUGllY2UmIGRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpFbnVtKiBlbnVtX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICBDb2RlZE91dHB1dFN0cmVhbSogc3RyZWFtKSB7CisgIFN0YXR1c09yPGludD4gZSA9IGRhdGEuVG9FbnVtKGVudW1fdHlwZSk7CisgIGlmIChlLm9rKCkpIHsKKyAgICBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVFbnVtKGZpZWxkX251bWJlciwgZS5WYWx1ZU9yRGllKCksIHN0cmVhbSk7CisgIH0KKyAgcmV0dXJuIGUuc3RhdHVzKCk7Cit9CisKKy8vIEdpdmVuIGEgZ29vZ2xlOjpwcm90b2J1Zjo6VHlwZSwgcmV0dXJucyB0aGUgc2V0IG9mIGFsbCByZXF1aXJlZCBmaWVsZHMuCitzdGQ6OnNldDxjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZCo+IEdldFJlcXVpcmVkRmllbGRzKAorICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlR5cGUmIHR5cGUpIHsKKyAgc3RkOjpzZXQ8Y29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGQqPiByZXF1aXJlZDsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB0eXBlLmZpZWxkc19zaXplKCk7IGkrKykgeworICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkJiBmaWVsZCA9IHR5cGUuZmllbGRzKGkpOworICAgIGlmIChmaWVsZC5jYXJkaW5hbGl0eSgpID09CisgICAgICAgIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0NhcmRpbmFsaXR5X0NBUkRJTkFMSVRZX1JFUVVJUkVEKSB7CisgICAgICByZXF1aXJlZC5pbnNlcnQoJmZpZWxkKTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIHJlcXVpcmVkOworfQorCit9ICAvLyBuYW1lc3BhY2UKKworUHJvdG9Xcml0ZXI6OlByb3RvRWxlbWVudDo6UHJvdG9FbGVtZW50KGNvbnN0IFR5cGVJbmZvKiB0eXBlaW5mbywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlJiB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFByb3RvV3JpdGVyKiBlbmNsb3NpbmcpCisgICAgOiBCYXNlRWxlbWVudChOVUxMKSwKKyAgICAgIG93XyhlbmNsb3NpbmcpLAorICAgICAgcGFyZW50X2ZpZWxkXyhOVUxMKSwKKyAgICAgIHR5cGVpbmZvXyh0eXBlaW5mbyksCisgICAgICB0eXBlXyh0eXBlKSwKKyAgICAgIHJlcXVpcmVkX2ZpZWxkc18oR2V0UmVxdWlyZWRGaWVsZHModHlwZSkpLAorICAgICAgc2l6ZV9pbmRleF8oLTEpLAorICAgICAgYXJyYXlfaW5kZXhfKC0xKSB7fQorCitQcm90b1dyaXRlcjo6UHJvdG9FbGVtZW50OjpQcm90b0VsZW1lbnQoUHJvdG9Xcml0ZXI6OlByb3RvRWxlbWVudCogcGFyZW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlJiB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaXNfbGlzdCkKKyAgICA6IEJhc2VFbGVtZW50KHBhcmVudCksCisgICAgICBvd18odGhpcy0+cGFyZW50KCktPm93XyksCisgICAgICBwYXJlbnRfZmllbGRfKGZpZWxkKSwKKyAgICAgIHR5cGVpbmZvXyh0aGlzLT5wYXJlbnQoKS0+dHlwZWluZm9fKSwKKyAgICAgIHR5cGVfKHR5cGUpLAorICAgICAgc2l6ZV9pbmRleF8oCisgICAgICAgICAgIWlzX2xpc3QgJiYgZmllbGQtPmtpbmQoKSA9PSBnb29nbGU6OnByb3RvYnVmOjpGaWVsZF9LaW5kX1RZUEVfTUVTU0FHRQorICAgICAgICAgICAgICA/IG93Xy0+c2l6ZV9pbnNlcnRfLnNpemUoKQorICAgICAgICAgICAgICA6IC0xKSwKKyAgICAgIGFycmF5X2luZGV4Xyhpc19saXN0ID8gMCA6IC0xKSB7CisgIGlmICghaXNfbGlzdCkgeworICAgIGlmIChvd18tPklzUmVwZWF0ZWQoKmZpZWxkKSkgeworICAgICAgLy8gVXBkYXRlIGFycmF5X2luZGV4XyBpZiBpdCBpcyBhbiBleHBsaWNpdCBsaXN0LgorICAgICAgaWYgKHRoaXMtPnBhcmVudCgpLT5hcnJheV9pbmRleF8gPj0gMCkgdGhpcy0+cGFyZW50KCktPmFycmF5X2luZGV4XysrOworICAgIH0gZWxzZSB7CisgICAgICB0aGlzLT5wYXJlbnQoKS0+UmVnaXN0ZXJGaWVsZChmaWVsZCk7CisgICAgfQorCisgICAgaWYgKGZpZWxkLT5raW5kKCkgPT0gZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGRfS2luZF9UWVBFX01FU1NBR0UpIHsKKyAgICAgIHJlcXVpcmVkX2ZpZWxkc18gPSBHZXRSZXF1aXJlZEZpZWxkcyh0eXBlXyk7CisgICAgICBpbnQgc3RhcnRfcG9zID0gb3dfLT5zdHJlYW1fLT5CeXRlQ291bnQoKTsKKyAgICAgIC8vIGxlbmd0aCBvZiBzZXJpYWxpemVkIG1lc3NhZ2UgaXMgdGhlIGZpbmFsIGJ1ZmZlciBwb3NpdGlvbiBtaW51cworICAgICAgLy8gc3RhcnRpbmcgYnVmZmVyIHBvc2l0aW9uLCBwbHVzIGxlbmd0aCBhZGp1c3RtZW50cyBmb3Igc2l6ZSBmaWVsZHMKKyAgICAgIC8vIG9mIGFueSBuZXN0ZWQgbWVzc2FnZXMuIFdlIHN0YXJ0IHdpdGggLXN0YXJ0X3BvcyBoZXJlLCBzbyB3ZSBvbmx5CisgICAgICAvLyBuZWVkIHRvIGFkZCB0aGUgZmluYWwgYnVmZmVyIHBvc2l0aW9uIHRvIGl0IGF0IHRoZSBlbmQuCisgICAgICBTaXplSW5mbyBpbmZvID0ge3N0YXJ0X3BvcywgLXN0YXJ0X3Bvc307CisgICAgICBvd18tPnNpemVfaW5zZXJ0Xy5wdXNoX2JhY2soaW5mbyk7CisgICAgfQorICB9Cit9CisKK1Byb3RvV3JpdGVyOjpQcm90b0VsZW1lbnQqIFByb3RvV3JpdGVyOjpQcm90b0VsZW1lbnQ6OnBvcCgpIHsKKyAgLy8gQ2FsbHMgdGhlIHJlZ2lzdGVyZWQgZXJyb3IgbGlzdGVuZXIgZm9yIGFueSByZXF1aXJlZCBmaWVsZChzKSBub3QgeWV0CisgIC8vIHNlZW4uCisgIGZvciAoc2V0PGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkKj46Oml0ZXJhdG9yIGl0ID0KKyAgICAgICAgICAgcmVxdWlyZWRfZmllbGRzXy5iZWdpbigpOworICAgICAgIGl0ICE9IHJlcXVpcmVkX2ZpZWxkc18uZW5kKCk7ICsraXQpIHsKKyAgICBvd18tPk1pc3NpbmdGaWVsZCgoKml0KS0+bmFtZSgpKTsKKyAgfQorICAvLyBDb21wdXRlcyB0aGUgdG90YWwgbnVtYmVyIG9mIHByb3RvIGJ5dGVzIHVzZWQgYnkgYSBtZXNzYWdlLCBhbHNvIGFkanVzdHMKKyAgLy8gdGhlIHNpemUgb2YgYWxsIHBhcmVudCBtZXNzYWdlcyBieSB0aGUgbGVuZ3RoIG9mIHRoaXMgc2l6ZSBmaWVsZC4KKyAgLy8gSWYgc2l6ZV9pbmRleF8gPCAwLCB0aGlzIGlzIG5vdCBhIG1lc3NhZ2UsIHNvIG5vIHNpemUgZmllbGQgaXMgYWRkZWQuCisgIGlmIChzaXplX2luZGV4XyA+PSAwKSB7CisgICAgLy8gQWRkIHRoZSBmaW5hbCBidWZmZXIgcG9zaXRpb24gdG8gY29tcHV0ZSB0aGUgdG90YWwgbGVuZ3RoIG9mIHRoaXMKKyAgICAvLyBzZXJpYWxpemVkIG1lc3NhZ2UuIFRoZSBzdG9yZWQgdmFsdWUgKGJlZm9yZSB0aGlzIGFkZGl0aW9uKSBhbHJlYWR5CisgICAgLy8gY29udGFpbnMgdGhlIHRvdGFsIGxlbmd0aCBvZiB0aGUgc2l6ZSBmaWVsZHMgb2YgYWxsIG5lc3RlZCBtZXNzYWdlcworICAgIC8vIG1pbnVzIHRoZSBpbml0aWFsIGJ1ZmZlciBwb3NpdGlvbi4KKyAgICBvd18tPnNpemVfaW5zZXJ0X1tzaXplX2luZGV4X10uc2l6ZSArPSBvd18tPnN0cmVhbV8tPkJ5dGVDb3VudCgpOworICAgIC8vIENhbGN1bGF0ZSB0aGUgbGVuZ3RoIHJlcXVpcmVkIHRvIHNlcmlhbGl6ZSB0aGUgc2l6ZSBmaWVsZCBvZiB0aGUKKyAgICAvLyBtZXNzYWdlLCBhbmQgcHJvcGFnYXRlIHRoaXMgYWRkaXRpb25hbCBzaXplIGluZm9ybWF0aW9uIHVwd2FyZCB0bworICAgIC8vIGFsbCBlbmNsb3NpbmcgbWVzc2FnZXMuCisgICAgaW50IHNpemUgPSBvd18tPnNpemVfaW5zZXJ0X1tzaXplX2luZGV4X10uc2l6ZTsKKyAgICBpbnQgbGVuZ3RoID0gQ29kZWRPdXRwdXRTdHJlYW06OlZhcmludFNpemUzMihzaXplKTsKKyAgICBmb3IgKFByb3RvRWxlbWVudCogZSA9IHBhcmVudCgpOyBlICE9IE5VTEw7IGUgPSBlLT5wYXJlbnQoKSkgeworICAgICAgLy8gT25seSBuZXN0ZWQgbWVzc2FnZXMgaGF2ZSBzaXplIGZpZWxkLCBsaXN0cyBkbyBub3QgaGF2ZSBzaXplIGZpZWxkLgorICAgICAgaWYgKGUtPnNpemVfaW5kZXhfID49IDApIHsKKyAgICAgICAgb3dfLT5zaXplX2luc2VydF9bZS0+c2l6ZV9pbmRleF9dLnNpemUgKz0gbGVuZ3RoOworICAgICAgfQorICAgIH0KKyAgfQorICByZXR1cm4gQmFzZUVsZW1lbnQ6OnBvcDxQcm90b0VsZW1lbnQ+KCk7Cit9CisKK3ZvaWQgUHJvdG9Xcml0ZXI6OlByb3RvRWxlbWVudDo6UmVnaXN0ZXJGaWVsZCgKKyAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZCogZmllbGQpIHsKKyAgaWYgKCFyZXF1aXJlZF9maWVsZHNfLmVtcHR5KCkgJiYKKyAgICAgIGZpZWxkLT5jYXJkaW5hbGl0eSgpID09CisgICAgICAgICAgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGRfQ2FyZGluYWxpdHlfQ0FSRElOQUxJVFlfUkVRVUlSRUQpIHsKKyAgICByZXF1aXJlZF9maWVsZHNfLmVyYXNlKGZpZWxkKTsKKyAgfQorfQorCitzdHJpbmcgUHJvdG9Xcml0ZXI6OlByb3RvRWxlbWVudDo6VG9TdHJpbmcoKSBjb25zdCB7CisgIGlmIChwYXJlbnQoKSA9PSBOVUxMKSByZXR1cm4gIiI7CisgIHN0cmluZyBsb2MgPSBwYXJlbnQoKS0+VG9TdHJpbmcoKTsKKyAgaWYgKCFvd18tPklzUmVwZWF0ZWQoKnBhcmVudF9maWVsZF8pIHx8CisgICAgICBwYXJlbnQoKS0+cGFyZW50X2ZpZWxkXyAhPSBwYXJlbnRfZmllbGRfKSB7CisgICAgc3RyaW5nIG5hbWUgPSBwYXJlbnRfZmllbGRfLT5uYW1lKCk7CisgICAgaW50IGkgPSAwOworICAgIHdoaWxlIChpIDwgbmFtZS5zaXplKCkgJiYgKGFzY2lpX2lzYWxudW0obmFtZVtpXSkgfHwgbmFtZVtpXSA9PSAnXycpKSArK2k7CisgICAgaWYgKGkgPiAwICYmIGkgPT0gbmFtZS5zaXplKCkpIHsgIC8vIHNhZmUgZmllbGQgbmFtZQorICAgICAgaWYgKGxvYy5lbXB0eSgpKSB7CisgICAgICAgIGxvYyA9IG5hbWU7CisgICAgICB9IGVsc2UgeworICAgICAgICBTdHJBcHBlbmQoJmxvYywgIi4iLCBuYW1lKTsKKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgU3RyQXBwZW5kKCZsb2MsICJbXCIiLCBDRXNjYXBlKG5hbWUpLCAiXCJdIik7CisgICAgfQorICB9CisgIGlmIChvd18tPklzUmVwZWF0ZWQoKnBhcmVudF9maWVsZF8pICYmIGFycmF5X2luZGV4XyA+IDApIHsKKyAgICBTdHJBcHBlbmQoJmxvYywgIlsiLCBhcnJheV9pbmRleF8gLSAxLCAiXSIpOworICB9CisgIHJldHVybiBsb2MuZW1wdHkoKSA/ICIuIiA6IGxvYzsKK30KKworYm9vbCBQcm90b1dyaXRlcjo6UHJvdG9FbGVtZW50OjpJc09uZW9mSW5kZXhUYWtlbihpbnQzMiBpbmRleCkgeworICByZXR1cm4gQ29udGFpbnNLZXkob25lb2ZfaW5kaWNlc18sIGluZGV4KTsKK30KKwordm9pZCBQcm90b1dyaXRlcjo6UHJvdG9FbGVtZW50OjpUYWtlT25lb2ZJbmRleChpbnQzMiBpbmRleCkgeworICBJbnNlcnRJZk5vdFByZXNlbnQoJm9uZW9mX2luZGljZXNfLCBpbmRleCk7Cit9CisKK3ZvaWQgUHJvdG9Xcml0ZXI6OkludmFsaWROYW1lKFN0cmluZ1BpZWNlIHVua25vd25fbmFtZSwgU3RyaW5nUGllY2UgbWVzc2FnZSkgeworICBsaXN0ZW5lcl8tPkludmFsaWROYW1lKGxvY2F0aW9uKCksIFRvU25ha2VDYXNlKHVua25vd25fbmFtZSksIG1lc3NhZ2UpOworfQorCit2b2lkIFByb3RvV3JpdGVyOjpJbnZhbGlkVmFsdWUoU3RyaW5nUGllY2UgdHlwZV9uYW1lLCBTdHJpbmdQaWVjZSB2YWx1ZSkgeworICBsaXN0ZW5lcl8tPkludmFsaWRWYWx1ZShsb2NhdGlvbigpLCB0eXBlX25hbWUsIHZhbHVlKTsKK30KKwordm9pZCBQcm90b1dyaXRlcjo6TWlzc2luZ0ZpZWxkKFN0cmluZ1BpZWNlIG1pc3NpbmdfbmFtZSkgeworICBsaXN0ZW5lcl8tPk1pc3NpbmdGaWVsZChsb2NhdGlvbigpLCBtaXNzaW5nX25hbWUpOworfQorCitQcm90b1dyaXRlciogUHJvdG9Xcml0ZXI6OlN0YXJ0T2JqZWN0KFN0cmluZ1BpZWNlIG5hbWUpIHsKKyAgLy8gU3RhcnRpbmcgdGhlIHJvb3QgbWVzc2FnZS4gQ3JlYXRlIHRoZSByb290IFByb3RvRWxlbWVudCBhbmQgcmV0dXJuLgorICBpZiAoZWxlbWVudF8gPT0gTlVMTCkgeworICAgIGlmICghbmFtZS5lbXB0eSgpKSB7CisgICAgICBJbnZhbGlkTmFtZShuYW1lLCAiUm9vdCBlbGVtZW50IHNob3VsZCBub3QgYmUgbmFtZWQuIik7CisgICAgfQorICAgIGVsZW1lbnRfLnJlc2V0KG5ldyBQcm90b0VsZW1lbnQodHlwZWluZm9fLCBtYXN0ZXJfdHlwZV8sIHRoaXMpKTsKKyAgICByZXR1cm4gdGhpczsKKyAgfQorCisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkKiBmaWVsZCA9IE5VTEw7CisgIGZpZWxkID0gQmVnaW5OYW1lZChuYW1lLCBmYWxzZSk7CisgIGlmIChmaWVsZCA9PSBOVUxMKSByZXR1cm4gdGhpczsKKworICAvLyBDaGVjayB0byBzZWUgaWYgdGhpcyBmaWVsZCBpcyBhIG9uZW9mIGFuZCB0aGF0IG5vIG9uZW9mIGluIHRoYXQgZ3JvdXAgaGFzCisgIC8vIGFscmVhZHkgYmVlbiBzZXQuCisgIGlmICghVmFsaWRPbmVvZigqZmllbGQsIG5hbWUpKSB7CisgICAgKytpbnZhbGlkX2RlcHRoXzsKKyAgICByZXR1cm4gdGhpczsKKyAgfQorCisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlR5cGUqIHR5cGUgPSBMb29rdXBUeXBlKGZpZWxkKTsKKyAgaWYgKHR5cGUgPT0gTlVMTCkgeworICAgICsraW52YWxpZF9kZXB0aF87CisgICAgSW52YWxpZE5hbWUobmFtZSwKKyAgICAgICAgICAgICAgICBTdHJDYXQoIk1pc3NpbmcgZGVzY3JpcHRvciBmb3IgZmllbGQ6ICIsIGZpZWxkLT50eXBlX3VybCgpKSk7CisgICAgcmV0dXJuIHRoaXM7CisgIH0KKworICAgIFdyaXRlVGFnKCpmaWVsZCk7CisgIGVsZW1lbnRfLnJlc2V0KG5ldyBQcm90b0VsZW1lbnQoZWxlbWVudF8ucmVsZWFzZSgpLCBmaWVsZCwgKnR5cGUsIGZhbHNlKSk7CisgIHJldHVybiB0aGlzOworfQorCitQcm90b1dyaXRlciogUHJvdG9Xcml0ZXI6OkVuZE9iamVjdCgpIHsKKyAgaWYgKGludmFsaWRfZGVwdGhfID4gMCkgeworICAgIC0taW52YWxpZF9kZXB0aF87CisgICAgcmV0dXJuIHRoaXM7CisgIH0KKworICBpZiAoZWxlbWVudF8gIT0gTlVMTCkgeworICAgIGVsZW1lbnRfLnJlc2V0KGVsZW1lbnRfLT5wb3AoKSk7CisgIH0KKworCisgIC8vIElmIGVuZGluZyB0aGUgcm9vdCBlbGVtZW50LAorICAvLyB0aGVuIHNlcmlhbGl6ZSB0aGUgZnVsbCBtZXNzYWdlIHdpdGggY2FsY3VsYXRlZCBzaXplcy4KKyAgaWYgKGVsZW1lbnRfID09IE5VTEwpIHsKKyAgICBXcml0ZVJvb3RNZXNzYWdlKCk7CisgIH0KKyAgcmV0dXJuIHRoaXM7Cit9CisKK1Byb3RvV3JpdGVyKiBQcm90b1dyaXRlcjo6U3RhcnRMaXN0KFN0cmluZ1BpZWNlIG5hbWUpIHsKKyAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGQqIGZpZWxkID0gQmVnaW5OYW1lZChuYW1lLCB0cnVlKTsKKyAgaWYgKGZpZWxkID09IE5VTEwpIHJldHVybiB0aGlzOworCisgIGlmICghVmFsaWRPbmVvZigqZmllbGQsIG5hbWUpKSB7CisgICAgKytpbnZhbGlkX2RlcHRoXzsKKyAgICByZXR1cm4gdGhpczsKKyAgfQorCisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlR5cGUqIHR5cGUgPSBMb29rdXBUeXBlKGZpZWxkKTsKKyAgaWYgKHR5cGUgPT0gTlVMTCkgeworICAgICsraW52YWxpZF9kZXB0aF87CisgICAgSW52YWxpZE5hbWUobmFtZSwKKyAgICAgICAgICAgICAgICBTdHJDYXQoIk1pc3NpbmcgZGVzY3JpcHRvciBmb3IgZmllbGQ6ICIsIGZpZWxkLT50eXBlX3VybCgpKSk7CisgICAgcmV0dXJuIHRoaXM7CisgIH0KKworICBlbGVtZW50Xy5yZXNldChuZXcgUHJvdG9FbGVtZW50KGVsZW1lbnRfLnJlbGVhc2UoKSwgZmllbGQsICp0eXBlLCB0cnVlKSk7CisgIHJldHVybiB0aGlzOworfQorCitQcm90b1dyaXRlciogUHJvdG9Xcml0ZXI6OkVuZExpc3QoKSB7CisgIGlmIChpbnZhbGlkX2RlcHRoXyA+IDApIHsKKyAgICAtLWludmFsaWRfZGVwdGhfOworICB9IGVsc2UgaWYgKGVsZW1lbnRfICE9IE5VTEwpIHsKKyAgICBlbGVtZW50Xy5yZXNldChlbGVtZW50Xy0+cG9wKCkpOworICB9CisgIHJldHVybiB0aGlzOworfQorCitQcm90b1dyaXRlciogUHJvdG9Xcml0ZXI6OlJlbmRlckRhdGFQaWVjZShTdHJpbmdQaWVjZSBuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGF0YVBpZWNlJiBkYXRhKSB7CisgIFN0YXR1cyBzdGF0dXM7CisgIGlmIChpbnZhbGlkX2RlcHRoXyA+IDApIHJldHVybiB0aGlzOworCisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkKiBmaWVsZCA9IExvb2t1cChuYW1lKTsKKyAgaWYgKGZpZWxkID09IE5VTEwpIHJldHVybiB0aGlzOworCisgIGlmICghVmFsaWRPbmVvZigqZmllbGQsIG5hbWUpKSByZXR1cm4gdGhpczsKKworICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlKiB0eXBlID0gTG9va3VwVHlwZShmaWVsZCk7CisgIGlmICh0eXBlID09IE5VTEwpIHsKKyAgICBJbnZhbGlkTmFtZShuYW1lLAorICAgICAgICAgICAgICAgIFN0ckNhdCgiTWlzc2luZyBkZXNjcmlwdG9yIGZvciBmaWVsZDogIiwgZmllbGQtPnR5cGVfdXJsKCkpKTsKKyAgICByZXR1cm4gdGhpczsKKyAgfQorCisgIC8vIFB1c2hpbmcgYSBQcm90b0VsZW1lbnQgYW5kIHRoZW4gcG9wIGl0IG9mZiBhdCB0aGUgZW5kIGZvciAyIHB1cnBvc2VzOgorICAvLyBlcnJvciBsb2NhdGlvbiByZXBvcnRpbmcgYW5kIHJlcXVpcmVkIGZpZWxkIGFjY291bnRpbmcuCisgIGVsZW1lbnRfLnJlc2V0KG5ldyBQcm90b0VsZW1lbnQoZWxlbWVudF8ucmVsZWFzZSgpLCBmaWVsZCwgKnR5cGUsIGZhbHNlKSk7CisKKyAgaWYgKGZpZWxkLT5raW5kKCkgPT0gZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGRfS2luZF9UWVBFX1VOS05PV04gfHwKKyAgICAgIGZpZWxkLT5raW5kKCkgPT0gZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGRfS2luZF9UWVBFX01FU1NBR0UpIHsKKyAgICBJbnZhbGlkVmFsdWUoZmllbGQtPnR5cGVfdXJsKCkuZW1wdHkoKQorICAgICAgICAgICAgICAgICAgICAgPyBnb29nbGU6OnByb3RvYnVmOjpGaWVsZF9LaW5kX05hbWUoZmllbGQtPmtpbmQoKSkKKyAgICAgICAgICAgICAgICAgICAgIDogZmllbGQtPnR5cGVfdXJsKCksCisgICAgICAgICAgICAgICAgIGRhdGEuVmFsdWVBc1N0cmluZ09yRGVmYXVsdCgiIikpOworICAgIGVsZW1lbnRfLnJlc2V0KGVsZW1lbnQoKS0+cG9wKCkpOworICAgIHJldHVybiB0aGlzOworICB9CisKKyAgc3dpdGNoIChmaWVsZC0+a2luZCgpKSB7CisgICAgY2FzZSBnb29nbGU6OnByb3RvYnVmOjpGaWVsZF9LaW5kX1RZUEVfSU5UMzI6IHsKKyAgICAgIHN0YXR1cyA9IFdyaXRlSW50MzIoZmllbGQtPm51bWJlcigpLCBkYXRhLCBzdHJlYW1fLmdldCgpKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0tpbmRfVFlQRV9TRklYRUQzMjogeworICAgICAgc3RhdHVzID0gV3JpdGVTRml4ZWQzMihmaWVsZC0+bnVtYmVyKCksIGRhdGEsIHN0cmVhbV8uZ2V0KCkpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGRfS2luZF9UWVBFX1NJTlQzMjogeworICAgICAgc3RhdHVzID0gV3JpdGVTSW50MzIoZmllbGQtPm51bWJlcigpLCBkYXRhLCBzdHJlYW1fLmdldCgpKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0tpbmRfVFlQRV9GSVhFRDMyOiB7CisgICAgICBzdGF0dXMgPSBXcml0ZUZpeGVkMzIoZmllbGQtPm51bWJlcigpLCBkYXRhLCBzdHJlYW1fLmdldCgpKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0tpbmRfVFlQRV9VSU5UMzI6IHsKKyAgICAgIHN0YXR1cyA9IFdyaXRlVUludDMyKGZpZWxkLT5udW1iZXIoKSwgZGF0YSwgc3RyZWFtXy5nZXQoKSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBnb29nbGU6OnByb3RvYnVmOjpGaWVsZF9LaW5kX1RZUEVfSU5UNjQ6IHsKKyAgICAgIHN0YXR1cyA9IFdyaXRlSW50NjQoZmllbGQtPm51bWJlcigpLCBkYXRhLCBzdHJlYW1fLmdldCgpKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0tpbmRfVFlQRV9TRklYRUQ2NDogeworICAgICAgc3RhdHVzID0gV3JpdGVTRml4ZWQ2NChmaWVsZC0+bnVtYmVyKCksIGRhdGEsIHN0cmVhbV8uZ2V0KCkpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGRfS2luZF9UWVBFX1NJTlQ2NDogeworICAgICAgc3RhdHVzID0gV3JpdGVTSW50NjQoZmllbGQtPm51bWJlcigpLCBkYXRhLCBzdHJlYW1fLmdldCgpKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0tpbmRfVFlQRV9GSVhFRDY0OiB7CisgICAgICBzdGF0dXMgPSBXcml0ZUZpeGVkNjQoZmllbGQtPm51bWJlcigpLCBkYXRhLCBzdHJlYW1fLmdldCgpKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0tpbmRfVFlQRV9VSU5UNjQ6IHsKKyAgICAgIHN0YXR1cyA9IFdyaXRlVUludDY0KGZpZWxkLT5udW1iZXIoKSwgZGF0YSwgc3RyZWFtXy5nZXQoKSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBnb29nbGU6OnByb3RvYnVmOjpGaWVsZF9LaW5kX1RZUEVfRE9VQkxFOiB7CisgICAgICBzdGF0dXMgPSBXcml0ZURvdWJsZShmaWVsZC0+bnVtYmVyKCksIGRhdGEsIHN0cmVhbV8uZ2V0KCkpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGRfS2luZF9UWVBFX0ZMT0FUOiB7CisgICAgICBzdGF0dXMgPSBXcml0ZUZsb2F0KGZpZWxkLT5udW1iZXIoKSwgZGF0YSwgc3RyZWFtXy5nZXQoKSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBnb29nbGU6OnByb3RvYnVmOjpGaWVsZF9LaW5kX1RZUEVfQk9PTDogeworICAgICAgc3RhdHVzID0gV3JpdGVCb29sKGZpZWxkLT5udW1iZXIoKSwgZGF0YSwgc3RyZWFtXy5nZXQoKSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBnb29nbGU6OnByb3RvYnVmOjpGaWVsZF9LaW5kX1RZUEVfQllURVM6IHsKKyAgICAgIHN0YXR1cyA9IFdyaXRlQnl0ZXMoZmllbGQtPm51bWJlcigpLCBkYXRhLCBzdHJlYW1fLmdldCgpKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0tpbmRfVFlQRV9TVFJJTkc6IHsKKyAgICAgIHN0YXR1cyA9IFdyaXRlU3RyaW5nKGZpZWxkLT5udW1iZXIoKSwgZGF0YSwgc3RyZWFtXy5nZXQoKSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBnb29nbGU6OnByb3RvYnVmOjpGaWVsZF9LaW5kX1RZUEVfRU5VTTogeworICAgICAgc3RhdHVzID0gV3JpdGVFbnVtKGZpZWxkLT5udW1iZXIoKSwgZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlaW5mb18tPkdldEVudW1CeVR5cGVVcmwoZmllbGQtPnR5cGVfdXJsKCkpLAorICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbV8uZ2V0KCkpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGRlZmF1bHQ6ICAvLyBUWVBFX0dST1VQIG9yIFRZUEVfTUVTU0FHRQorICAgICAgc3RhdHVzID0gU3RhdHVzKElOVkFMSURfQVJHVU1FTlQsIGRhdGEuVG9TdHJpbmcoKS5WYWx1ZU9yRGllKCkpOworICB9CisKKyAgaWYgKCFzdGF0dXMub2soKSkgeworICAgIEludmFsaWRWYWx1ZShnb29nbGU6OnByb3RvYnVmOjpGaWVsZF9LaW5kX05hbWUoZmllbGQtPmtpbmQoKSksCisgICAgICAgICAgICAgICAgIHN0YXR1cy5lcnJvcl9tZXNzYWdlKCkpOworICB9CisKKyAgZWxlbWVudF8ucmVzZXQoZWxlbWVudCgpLT5wb3AoKSk7CisgIHJldHVybiB0aGlzOworfQorCitib29sIFByb3RvV3JpdGVyOjpWYWxpZE9uZW9mKGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkJiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UgdW5ub3JtYWxpemVkX25hbWUpIHsKKyAgaWYgKGVsZW1lbnRfID09IE5VTEwpIHJldHVybiB0cnVlOworCisgIGlmIChmaWVsZC5vbmVvZl9pbmRleCgpID4gMCkgeworICAgIGlmIChlbGVtZW50Xy0+SXNPbmVvZkluZGV4VGFrZW4oZmllbGQub25lb2ZfaW5kZXgoKSkpIHsKKyAgICAgIEludmFsaWRWYWx1ZSgKKyAgICAgICAgICAib25lb2YiLAorICAgICAgICAgIFN0ckNhdCgib25lb2YgZmllbGQgJyIsCisgICAgICAgICAgICAgICAgIGVsZW1lbnRfLT50eXBlKCkub25lb2ZzKGZpZWxkLm9uZW9mX2luZGV4KCkgLSAxKSwKKyAgICAgICAgICAgICAgICAgIicgaXMgYWxyZWFkeSBzZXQuIENhbm5vdCBzZXQgJyIsIHVubm9ybWFsaXplZF9uYW1lLCAiJyIpKTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgZWxlbWVudF8tPlRha2VPbmVvZkluZGV4KGZpZWxkLm9uZW9mX2luZGV4KCkpOworICB9CisgIHJldHVybiB0cnVlOworfQorCitib29sIFByb3RvV3JpdGVyOjpJc1JlcGVhdGVkKGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkJiBmaWVsZCkgeworICByZXR1cm4gZmllbGQuY2FyZGluYWxpdHkoKSA9PQorICAgICAgICAgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGRfQ2FyZGluYWxpdHlfQ0FSRElOQUxJVFlfUkVQRUFURUQ7Cit9CisKK2NvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkKiBQcm90b1dyaXRlcjo6QmVnaW5OYW1lZChTdHJpbmdQaWVjZSBuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaXNfbGlzdCkgeworICBpZiAoaW52YWxpZF9kZXB0aF8gPiAwKSB7CisgICAgKytpbnZhbGlkX2RlcHRoXzsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZCogZmllbGQgPSBMb29rdXAobmFtZSk7CisgIGlmIChmaWVsZCA9PSBOVUxMKSB7CisgICAgKytpbnZhbGlkX2RlcHRoXzsKKyAgICAvLyBJbnZhbGlkTmFtZSgpIGFscmVhZHkgY2FsbGVkIGluIExvb2t1cCgpLgorICAgIHJldHVybiBOVUxMOworICB9CisgIGlmIChpc19saXN0ICYmICFJc1JlcGVhdGVkKCpmaWVsZCkpIHsKKyAgICArK2ludmFsaWRfZGVwdGhfOworICAgIEludmFsaWROYW1lKG5hbWUsICJQcm90byBmaWVsZCBpcyBub3QgcmVwZWF0aW5nLCBjYW5ub3Qgc3RhcnQgbGlzdC4iKTsKKyAgICByZXR1cm4gTlVMTDsKKyAgfQorICByZXR1cm4gZmllbGQ7Cit9CisKK2NvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkKiBQcm90b1dyaXRlcjo6TG9va3VwKAorICAgIFN0cmluZ1BpZWNlIHVubm9ybWFsaXplZF9uYW1lKSB7CisgIFByb3RvRWxlbWVudCogZSA9IGVsZW1lbnQoKTsKKyAgaWYgKGUgPT0gTlVMTCkgeworICAgIEludmFsaWROYW1lKHVubm9ybWFsaXplZF9uYW1lLCAiUm9vdCBlbGVtZW50IG11c3QgYmUgYSBtZXNzYWdlLiIpOworICAgIHJldHVybiBOVUxMOworICB9CisgIGlmICh1bm5vcm1hbGl6ZWRfbmFtZS5lbXB0eSgpKSB7CisgICAgLy8gT2JqZWN0cyBpbiByZXBlYXRlZCBmaWVsZCBpbmhlcml0IHRoZSBzYW1lIGZpZWxkIGRlc2NyaXB0b3IuCisgICAgaWYgKGUtPnBhcmVudF9maWVsZCgpID09IE5VTEwpIHsKKyAgICAgIEludmFsaWROYW1lKHVubm9ybWFsaXplZF9uYW1lLCAiUHJvdG8gZmllbGRzIG11c3QgaGF2ZSBhIG5hbWUuIik7CisgICAgfSBlbHNlIGlmICghSXNSZXBlYXRlZCgqZS0+cGFyZW50X2ZpZWxkKCkpKSB7CisgICAgICBJbnZhbGlkTmFtZSh1bm5vcm1hbGl6ZWRfbmFtZSwgIlByb3RvIGZpZWxkcyBtdXN0IGhhdmUgYSBuYW1lLiIpOworICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJldHVybiBlLT5wYXJlbnRfZmllbGQoKTsKKyAgfQorICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZCogZmllbGQgPQorICAgICAgdHlwZWluZm9fLT5GaW5kRmllbGQoJmUtPnR5cGUoKSwgdW5ub3JtYWxpemVkX25hbWUpOworICBpZiAoZmllbGQgPT0gTlVMTCkgSW52YWxpZE5hbWUodW5ub3JtYWxpemVkX25hbWUsICJDYW5ub3QgZmluZCBmaWVsZC4iKTsKKyAgcmV0dXJuIGZpZWxkOworfQorCitjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlKiBQcm90b1dyaXRlcjo6TG9va3VwVHlwZSgKKyAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZCogZmllbGQpIHsKKyAgcmV0dXJuICgoZmllbGQtPmtpbmQoKSA9PSBnb29nbGU6OnByb3RvYnVmOjpGaWVsZF9LaW5kX1RZUEVfTUVTU0FHRSB8fAorICAgICAgICAgICBmaWVsZC0+a2luZCgpID09IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0tpbmRfVFlQRV9HUk9VUCkKKyAgICAgICAgICAgICAgPyB0eXBlaW5mb18tPkdldFR5cGVCeVR5cGVVcmwoZmllbGQtPnR5cGVfdXJsKCkpCisgICAgICAgICAgICAgIDogJmVsZW1lbnRfLT50eXBlKCkpOworfQorCit2b2lkIFByb3RvV3JpdGVyOjpXcml0ZVJvb3RNZXNzYWdlKCkgeworICBHT09HTEVfRENIRUNLKCFkb25lXyk7CisgIGludCBjdXJyX3BvcyA9IDA7CisgIC8vIENhbGxzIHRoZSBkZXN0cnVjdG9yIG9mIENvZGVkT3V0cHV0U3RyZWFtIHRvIHJlbW92ZSBhbnkgdW5pbml0aWFsaXplZAorICAvLyBtZW1vcnkgZnJvbSB0aGUgQ29yZCBiZWZvcmUgd2UgcmVhZCBpdC4KKyAgc3RyZWFtXy5yZXNldChOVUxMKTsKKyAgY29uc3Qgdm9pZCogZGF0YTsKKyAgaW50IGxlbmd0aDsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6aW86OkFycmF5SW5wdXRTdHJlYW0gaW5wdXRfc3RyZWFtKGJ1ZmZlcl8uZGF0YSgpLCBidWZmZXJfLnNpemUoKSk7CisgIHdoaWxlIChpbnB1dF9zdHJlYW0uTmV4dCgmZGF0YSwgJmxlbmd0aCkpIHsKKyAgICBpZiAobGVuZ3RoID09IDApIGNvbnRpbnVlOworICAgIGludCBudW1fYnl0ZXMgPSBsZW5ndGg7CisgICAgLy8gV3JpdGUgdXAgdG8gd2hlcmUgd2UgbmVlZCB0byBpbnNlcnQgdGhlIHNpemUgZmllbGQuCisgICAgLy8gVGhlIG51bWJlciBvZiBieXRlcyB3ZSBtYXkgd3JpdGUgaXMgdGhlIHNtYWxsZXIgb2Y6CisgICAgLy8gICAtIHRoZSBjdXJyZW50IGZyYWdtZW50IHNpemUKKyAgICAvLyAgIC0gdGhlIGRpc3RhbmNlIHRvIHRoZSBuZXh0IHBvc2l0aW9uIHdoZXJlIGEgc2l6ZSBmaWVsZCBuZWVkcyB0byBiZQorICAgIC8vICAgICBpbnNlcnRlZC4KKyAgICBpZiAoIXNpemVfaW5zZXJ0Xy5lbXB0eSgpICYmCisgICAgICAgIHNpemVfaW5zZXJ0Xy5mcm9udCgpLnBvcyAtIGN1cnJfcG9zIDwgbnVtX2J5dGVzKSB7CisgICAgICBudW1fYnl0ZXMgPSBzaXplX2luc2VydF8uZnJvbnQoKS5wb3MgLSBjdXJyX3BvczsKKyAgICB9CisgICAgb3V0cHV0Xy0+QXBwZW5kKHN0YXRpY19jYXN0PGNvbnN0IGNoYXIqPihkYXRhKSwgbnVtX2J5dGVzKTsKKyAgICBpZiAobnVtX2J5dGVzIDwgbGVuZ3RoKSB7CisgICAgICBpbnB1dF9zdHJlYW0uQmFja1VwKGxlbmd0aCAtIG51bV9ieXRlcyk7CisgICAgfQorICAgIGN1cnJfcG9zICs9IG51bV9ieXRlczsKKyAgICAvLyBJbnNlcnQgdGhlIHNpemUgZmllbGQuCisgICAgLy8gICBzaXplX2luc2VydF8uZnJvbnQoKTogICAgICB0aGUgbmV4dCA8aW5kZXgsIHNpemU+IHBhaXIgdG8gYmUgd3JpdHRlbi4KKyAgICAvLyAgIHNpemVfaW5zZXJ0Xy5mcm9udCgpLnBvczogIHBvc2l0aW9uIG9mIHRoZSBzaXplIGZpZWxkLgorICAgIC8vICAgc2l6ZV9pbnNlcnRfLmZyb250KCkuc2l6ZTogdGhlIHNpemUgKGludGVnZXIpIHRvIGJlIGluc2VydGVkLgorICAgIGlmICghc2l6ZV9pbnNlcnRfLmVtcHR5KCkgJiYgY3Vycl9wb3MgPT0gc2l6ZV9pbnNlcnRfLmZyb250KCkucG9zKSB7CisgICAgICAvLyBWYXJpbnQzMiBvY2N1cGllcyBhdCBtb3N0IDEwIGJ5dGVzLgorICAgICAgdWludDggaW5zZXJ0X2J1ZmZlclsxMF07CisgICAgICB1aW50OCogaW5zZXJ0X2J1ZmZlcl9wb3MgPSBDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVWYXJpbnQzMlRvQXJyYXkoCisgICAgICAgICAgc2l6ZV9pbnNlcnRfLmZyb250KCkuc2l6ZSwgaW5zZXJ0X2J1ZmZlcik7CisgICAgICBvdXRwdXRfLT5BcHBlbmQocmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4oaW5zZXJ0X2J1ZmZlciksCisgICAgICAgICAgICAgICAgICAgICAgaW5zZXJ0X2J1ZmZlcl9wb3MgLSBpbnNlcnRfYnVmZmVyKTsKKyAgICAgIHNpemVfaW5zZXJ0Xy5wb3BfZnJvbnQoKTsKKyAgICB9CisgIH0KKyAgb3V0cHV0Xy0+Rmx1c2goKTsKKyAgc3RyZWFtXy5yZXNldChuZXcgQ29kZWRPdXRwdXRTdHJlYW0oJmFkYXB0ZXJfKSk7CisgIGRvbmVfID0gdHJ1ZTsKK30KKwordm9pZCBQcm90b1dyaXRlcjo6V3JpdGVUYWcoY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGQmIGZpZWxkKSB7CisgIFdpcmVGb3JtYXRMaXRlOjpXaXJlVHlwZSB3aXJlX3R5cGUgPSBXaXJlRm9ybWF0TGl0ZTo6V2lyZVR5cGVGb3JGaWVsZFR5cGUoCisgICAgICBzdGF0aWNfY2FzdDxXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlPihmaWVsZC5raW5kKCkpKTsKKyAgc3RyZWFtXy0+V3JpdGVUYWcoV2lyZUZvcm1hdExpdGU6Ok1ha2VUYWcoZmllbGQubnVtYmVyKCksIHdpcmVfdHlwZSkpOworfQorCisKK30gIC8vIG5hbWVzcGFjZSBjb252ZXJ0ZXIKK30gIC8vIG5hbWVzcGFjZSB1dGlsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9wcm90b193cml0ZXIuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9wcm90b193cml0ZXIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNjMxZTU2Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3Byb3RvX3dyaXRlci5oCkBAIC0wLDAgKzEsMzE1IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfVVRJTF9DT05WRVJURVJfUFJPVE9fV1JJVEVSX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfVVRJTF9DT05WRVJURVJfUFJPVE9fV1JJVEVSX0hfXworCisjaW5jbHVkZSA8ZGVxdWU+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2hhc2guaD4KKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX2ltcGwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3R5cGVfaW5mby5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL2RhdGFwaWVjZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL2Vycm9yX2xpc3RlbmVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvc3RydWN0dXJlZF9vYmplY3R3cml0ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC90eXBlX3Jlc29sdmVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2J5dGVzdHJlYW0uaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGlvIHsKK2NsYXNzIENvZGVkT3V0cHV0U3RyZWFtOworfSAgLy8gbmFtZXNwYWNlIGlvCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworCituYW1lc3BhY2UgcHJvdG9idWYgeworY2xhc3MgVHlwZTsKK2NsYXNzIEZpZWxkOworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKKworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSB1dGlsIHsKK25hbWVzcGFjZSBjb252ZXJ0ZXIgeworCitjbGFzcyBPYmplY3RMb2NhdGlvblRyYWNrZXI7CisKKy8vIEFuIE9iamVjdFdyaXRlciB0aGF0IGNhbiB3cml0ZSBwcm90b2J1ZiBieXRlcyBkaXJlY3RseSBmcm9tIHdyaXRlciBldmVudHMuCisvLyBUaGlzIGNsYXNzIGRvZXMgbm90IHN1cHBvcnQgc3BlY2lhbCB0eXBlcyBsaWtlIFN0cnVjdCBvciBNYXAuIEhvd2V2ZXIsIHNpbmNlCisvLyB0aGlzIGNsYXNzIHN1cHBvcnRzIHJhdyBwcm90b2J1ZiwgaXQgY2FuIGJlIHVzZWQgdG8gcHJvdmlkZSBzdXBwb3J0IGZvcgorLy8gc3BlY2lhbCB0eXBlcyBieSBpbmhlcml0aW5nIGZyb20gaXQgb3IgYnkgd3JhcHBpbmcgaXQuCisvLworLy8gSXQgYWxzbyBzdXBwb3J0cyBzdHJlYW1pbmcuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgUHJvdG9Xcml0ZXIgOiBwdWJsaWMgU3RydWN0dXJlZE9iamVjdFdyaXRlciB7CisgcHVibGljOgorLy8gQ29uc3RydWN0b3IuIERvZXMgbm90IHRha2Ugb3duZXJzaGlwIG9mIGFueSBwYXJhbWV0ZXIgcGFzc2VkIGluLgorICBQcm90b1dyaXRlcihUeXBlUmVzb2x2ZXIqIHR5cGVfcmVzb2x2ZXIsIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlR5cGUmIHR5cGUsCisgICAgICAgICAgICAgIHN0cmluZ3M6OkJ5dGVTaW5rKiBvdXRwdXQsIEVycm9yTGlzdGVuZXIqIGxpc3RlbmVyKTsKKyAgdmlydHVhbCB+UHJvdG9Xcml0ZXIoKTsKKworICAvLyBPYmplY3RXcml0ZXIgbWV0aG9kcy4KKyAgdmlydHVhbCBQcm90b1dyaXRlciogU3RhcnRPYmplY3QoU3RyaW5nUGllY2UgbmFtZSk7CisgIHZpcnR1YWwgUHJvdG9Xcml0ZXIqIEVuZE9iamVjdCgpOworICB2aXJ0dWFsIFByb3RvV3JpdGVyKiBTdGFydExpc3QoU3RyaW5nUGllY2UgbmFtZSk7CisgIHZpcnR1YWwgUHJvdG9Xcml0ZXIqIEVuZExpc3QoKTsKKyAgdmlydHVhbCBQcm90b1dyaXRlciogUmVuZGVyQm9vbChTdHJpbmdQaWVjZSBuYW1lLCBib29sIHZhbHVlKSB7CisgICAgcmV0dXJuIFJlbmRlckRhdGFQaWVjZShuYW1lLCBEYXRhUGllY2UodmFsdWUpKTsKKyAgfQorICB2aXJ0dWFsIFByb3RvV3JpdGVyKiBSZW5kZXJJbnQzMihTdHJpbmdQaWVjZSBuYW1lLCBpbnQzMiB2YWx1ZSkgeworICAgIHJldHVybiBSZW5kZXJEYXRhUGllY2UobmFtZSwgRGF0YVBpZWNlKHZhbHVlKSk7CisgIH0KKyAgdmlydHVhbCBQcm90b1dyaXRlciogUmVuZGVyVWludDMyKFN0cmluZ1BpZWNlIG5hbWUsIHVpbnQzMiB2YWx1ZSkgeworICAgIHJldHVybiBSZW5kZXJEYXRhUGllY2UobmFtZSwgRGF0YVBpZWNlKHZhbHVlKSk7CisgIH0KKyAgdmlydHVhbCBQcm90b1dyaXRlciogUmVuZGVySW50NjQoU3RyaW5nUGllY2UgbmFtZSwgaW50NjQgdmFsdWUpIHsKKyAgICByZXR1cm4gUmVuZGVyRGF0YVBpZWNlKG5hbWUsIERhdGFQaWVjZSh2YWx1ZSkpOworICB9CisgIHZpcnR1YWwgUHJvdG9Xcml0ZXIqIFJlbmRlclVpbnQ2NChTdHJpbmdQaWVjZSBuYW1lLCB1aW50NjQgdmFsdWUpIHsKKyAgICByZXR1cm4gUmVuZGVyRGF0YVBpZWNlKG5hbWUsIERhdGFQaWVjZSh2YWx1ZSkpOworICB9CisgIHZpcnR1YWwgUHJvdG9Xcml0ZXIqIFJlbmRlckRvdWJsZShTdHJpbmdQaWVjZSBuYW1lLCBkb3VibGUgdmFsdWUpIHsKKyAgICByZXR1cm4gUmVuZGVyRGF0YVBpZWNlKG5hbWUsIERhdGFQaWVjZSh2YWx1ZSkpOworICB9CisgIHZpcnR1YWwgUHJvdG9Xcml0ZXIqIFJlbmRlckZsb2F0KFN0cmluZ1BpZWNlIG5hbWUsIGZsb2F0IHZhbHVlKSB7CisgICAgcmV0dXJuIFJlbmRlckRhdGFQaWVjZShuYW1lLCBEYXRhUGllY2UodmFsdWUpKTsKKyAgfQorICB2aXJ0dWFsIFByb3RvV3JpdGVyKiBSZW5kZXJTdHJpbmcoU3RyaW5nUGllY2UgbmFtZSwgU3RyaW5nUGllY2UgdmFsdWUpIHsKKyAgICByZXR1cm4gUmVuZGVyRGF0YVBpZWNlKG5hbWUsIERhdGFQaWVjZSh2YWx1ZSkpOworICB9CisgIHZpcnR1YWwgUHJvdG9Xcml0ZXIqIFJlbmRlckJ5dGVzKFN0cmluZ1BpZWNlIG5hbWUsIFN0cmluZ1BpZWNlIHZhbHVlKSB7CisgICAgcmV0dXJuIFJlbmRlckRhdGFQaWVjZShuYW1lLCBEYXRhUGllY2UodmFsdWUsIGZhbHNlKSk7CisgIH0KKyAgdmlydHVhbCBQcm90b1dyaXRlciogUmVuZGVyTnVsbChTdHJpbmdQaWVjZSBuYW1lKSB7CisgICAgcmV0dXJuIFJlbmRlckRhdGFQaWVjZShuYW1lLCBEYXRhUGllY2U6Ok51bGxEYXRhKCkpOworICB9CisKKyAgLy8gUmVuZGVycyBhIERhdGFQaWVjZSAndmFsdWUnIGludG8gYSBmaWVsZCB3aG9zZSB3aXJlIHR5cGUgaXMgZGV0ZXJtaW5lZAorICAvLyBmcm9tIHRoZSBnaXZlbiBmaWVsZCAnbmFtZScuCisgIHZpcnR1YWwgUHJvdG9Xcml0ZXIqIFJlbmRlckRhdGFQaWVjZShTdHJpbmdQaWVjZSBuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGF0YVBpZWNlJiB2YWx1ZSk7CisKKyAgLy8gUmV0dXJucyB0aGUgbG9jYXRpb24gdHJhY2tlciB0byB1c2UgZm9yIHRyYWNraW5nIGxvY2F0aW9ucyBmb3IgZXJyb3JzLgorICBjb25zdCBMb2NhdGlvblRyYWNrZXJJbnRlcmZhY2UmIGxvY2F0aW9uKCkgeworICAgIHJldHVybiBlbGVtZW50XyAhPSBOVUxMID8gKmVsZW1lbnRfIDogKnRyYWNrZXJfOworICB9CisKKyAgLy8gV2hlbiB0cnVlLCB3ZSBmaW5pc2hlZCB3cml0aW5nIHRvIG91dHB1dCBhIGNvbXBsZXRlIG1lc3NhZ2UuCisgIGJvb2wgZG9uZSgpIGNvbnN0IHsgcmV0dXJuIGRvbmVfOyB9CisKKyAgLy8gUmV0dXJucyB0aGUgcHJvdG8gc3RyZWFtIG9iamVjdC4KKyAgZ29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBzdHJlYW0oKSB7IHJldHVybiBzdHJlYW1fLmdldCgpOyB9CisKKyAgLy8gR2V0dGVycyBhbmQgbXV0YXRvcnMgb2YgaW52YWxpZF9kZXB0aF8uCisgIHZvaWQgSW5jcmVtZW50SW52YWxpZERlcHRoKCkgeyArK2ludmFsaWRfZGVwdGhfOyB9CisgIHZvaWQgRGVjcmVtZW50SW52YWxpZERlcHRoKCkgeyAtLWludmFsaWRfZGVwdGhfOyB9CisgIGludCBpbnZhbGlkX2RlcHRoKCkgeyByZXR1cm4gaW52YWxpZF9kZXB0aF87IH0KKworICBFcnJvckxpc3RlbmVyKiBsaXN0ZW5lcigpIHsgcmV0dXJuIGxpc3RlbmVyXzsgfQorCisgIGNvbnN0IFR5cGVJbmZvKiB0eXBlaW5mbygpIHsgcmV0dXJuIHR5cGVpbmZvXzsgfQorCisgcHJvdGVjdGVkOgorICBjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgUHJvdG9FbGVtZW50IDogcHVibGljIEJhc2VFbGVtZW50LCBwdWJsaWMgTG9jYXRpb25UcmFja2VySW50ZXJmYWNlIHsKKyAgIHB1YmxpYzoKKyAgICAvLyBDb25zdHJ1Y3RvciBmb3IgdGhlIHJvb3QgZWxlbWVudC4gTm8gcGFyZW50IG5vciBmaWVsZC4KKyAgICBQcm90b0VsZW1lbnQoY29uc3QgVHlwZUluZm8qIHR5cGVpbmZvLCBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlJiB0eXBlLAorICAgICAgICAgICAgICAgICBQcm90b1dyaXRlciogZW5jbG9zaW5nKTsKKworICAgIC8vIENvbnN0cnVjdG9yIGZvciBhIGZpZWxkIG9mIGFuIGVsZW1lbnQuCisgICAgUHJvdG9FbGVtZW50KFByb3RvRWxlbWVudCogcGFyZW50LCBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZCogZmllbGQsCisgICAgICAgICAgICAgICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlR5cGUmIHR5cGUsIGJvb2wgaXNfbGlzdCk7CisKKyAgICB2aXJ0dWFsIH5Qcm90b0VsZW1lbnQoKSB7fQorCisgICAgLy8gQ2FsbGVkIGp1c3QgYmVmb3JlIHRoZSBkZXN0cnVjdG9yIGZvciBjbGVhbiB1cDoKKyAgICAvLyAgIC0gcmVwb3J0cyBhbnkgbWlzc2luZyByZXF1aXJlZCBmaWVsZHMKKyAgICAvLyAgIC0gY29tcHV0ZXMgdGhlIHNwYWNlIG5lZWRlZCBieSB0aGUgc2l6ZSBmaWVsZCwgYW5kIGF1Z21lbnQgdGhlCisgICAgLy8gICAgIGxlbmd0aCBvZiBhbGwgcGFyZW50IG1lc3NhZ2VzIGJ5IHRoaXMgYWRkaXRpb25hbCBzcGFjZS4KKyAgICAvLyAgIC0gcmVsZWFzZXMgYW5kIHJldHVybnMgdGhlIHBhcmVudCBwb2ludGVyLgorICAgIFByb3RvRWxlbWVudCogcG9wKCk7CisKKyAgICAvLyBBY2Nlc3NvcnMKKyAgICAvLyBwYXJlbnRfZmllbGQoKSBtYXkgYmUgTlVMTCBpZiB3ZSBhcmUgYXQgcm9vdC4KKyAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZCogcGFyZW50X2ZpZWxkKCkgY29uc3QgeworICAgICAgcmV0dXJuIHBhcmVudF9maWVsZF87CisgICAgfQorICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlR5cGUmIHR5cGUoKSBjb25zdCB7IHJldHVybiB0eXBlXzsgfQorCisgICAgLy8gUmVnaXN0ZXJzIGZpZWxkIGZvciBhY2NvdW50aW5nIHJlcXVpcmVkIGZpZWxkcy4KKyAgICB2b2lkIFJlZ2lzdGVyRmllbGQoY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGQqIGZpZWxkKTsKKworICAgIC8vIFRvIHJlcG9ydCBsb2NhdGlvbiBvbiBlcnJvciBtZXNzYWdlcy4KKyAgICB2aXJ0dWFsIHN0cmluZyBUb1N0cmluZygpIGNvbnN0OworCisgICAgdmlydHVhbCBQcm90b0VsZW1lbnQqIHBhcmVudCgpIGNvbnN0IHsKKyAgICAgIHJldHVybiBzdGF0aWNfY2FzdDxQcm90b0VsZW1lbnQqPihCYXNlRWxlbWVudDo6cGFyZW50KCkpOworICAgIH0KKworICAgIC8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgaW5kZXggaXMgYWxyZWFkeSB0YWtlbiBieSBhIHByZWNlZWRpbmcgb25lb2YgaW5wdXQuCisgICAgYm9vbCBJc09uZW9mSW5kZXhUYWtlbihpbnQzMiBpbmRleCk7CisKKyAgICAvLyBNYXJrcyB0aGUgb25lb2YgJ2luZGV4JyBhcyB0YWtlbi4gRnV0dXJlIGlucHV0cyB0byB0aGlzIG9uZW9mIHdpbGwKKyAgICAvLyBnZW5lcmF0ZSBhbiBlcnJvci4KKyAgICB2b2lkIFRha2VPbmVvZkluZGV4KGludDMyIGluZGV4KTsKKworICAgcHJpdmF0ZToKKyAgICAvLyBVc2VkIGZvciBhY2Nlc3MgdG8gdmFyaWFibGVzIG9mIHRoZSBlbmNsb3NpbmcgaW5zdGFuY2Ugb2YKKyAgICAvLyBQcm90b1dyaXRlci4KKyAgICBQcm90b1dyaXRlciogb3dfOworCisgICAgLy8gRGVzY3JpYmVzIHRoZSBlbGVtZW50IGFzIGEgZmllbGQgaW4gdGhlIHBhcmVudCBtZXNzYWdlLgorICAgIC8vIHBhcmVudF9maWVsZF8gaXMgTlVMTCBpZiBhbmQgb25seSBpZiB0aGlzIGVsZW1lbnQgaXMgdGhlIHJvb3QgZWxlbWVudC4KKyAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZCogcGFyZW50X2ZpZWxkXzsKKworICAgIC8vIFR5cGVJbmZvIHRvIGxvb2t1cCB0eXBlcy4KKyAgICBjb25zdCBUeXBlSW5mbyogdHlwZWluZm9fOworCisgICAgLy8gQWRkaXRpb25hbCB2YXJpYWJsZXMgaWYgdGhpcyBlbGVtZW50IGlzIGEgbWVzc2FnZToKKyAgICAvLyAoUm9vdCBlbGVtZW50IGlzIGFsd2F5cyBhIG1lc3NhZ2UpLgorICAgIC8vIHR5cGVfICAgICAgICAgICAgIDogdGhlIHR5cGUgb2YgdGhpcyBlbGVtZW50LgorICAgIC8vIHJlcXVpcmVkX2ZpZWxkc18gIDogc2V0IG9mIHJlcXVpcmVkIGZpZWxkcy4KKyAgICAvLyBzaXplX2luZGV4XyAgICAgICA6IGluZGV4IGludG8gUHJvdG9Xcml0ZXI6OnNpemVfaW5zZXJ0XworICAgIC8vICAgICAgICAgICAgICAgICAgICAgZm9yIGxhdGVyIGluc2VydGlvbiBvZiBzZXJpYWxpemVkIG1lc3NhZ2UgbGVuZ3RoLgorICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlR5cGUmIHR5cGVfOworICAgIHN0ZDo6c2V0PGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkKj4gcmVxdWlyZWRfZmllbGRzXzsKKyAgICBjb25zdCBpbnQgc2l6ZV9pbmRleF87CisKKyAgICAvLyBUcmFja3MgcG9zaXRpb24gaW4gcmVwZWF0ZWQgZmllbGRzLCBuZWVkZWQgZm9yIExvY2F0aW9uVHJhY2tlckludGVyZmFjZS4KKyAgICBpbnQgYXJyYXlfaW5kZXhfOworCisgICAgLy8gU2V0IG9mIG9uZW9mIGluZGljZXMgYWxyZWFkeSBzZWVuIGZvciB0aGUgdHlwZV8uIFVzZWQgdG8gdmFsaWRhdGUKKyAgICAvLyBpbmNvbWluZyBtZXNzYWdlcyBzbyBubyBtb3JlIHRoYW4gb25lIG9uZW9mIGlzIHNldC4KKyAgICBoYXNoX3NldDxpbnQzMj4gb25lb2ZfaW5kaWNlc187CisKKyAgICBHT09HTEVfRElTQUxMT1dfSU1QTElDSVRfQ09OU1RSVUNUT1JTKFByb3RvRWxlbWVudCk7CisgIH07CisKKyAgLy8gQ29udGFpbmVyIGZvciBpbnNlcnRpbmcgJ3NpemUnIGluZm9ybWF0aW9uIGF0IHRoZSAncG9zJyBwb3NpdGlvbi4KKyAgc3RydWN0IFNpemVJbmZvIHsKKyAgICBjb25zdCBpbnQgcG9zOworICAgIGludCBzaXplOworICB9OworCisgIFByb3RvV3JpdGVyKGNvbnN0IFR5cGVJbmZvKiB0eXBlaW5mbywgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6VHlwZSYgdHlwZSwKKyAgICAgICAgICAgICAgc3RyaW5nczo6Qnl0ZVNpbmsqIG91dHB1dCwgRXJyb3JMaXN0ZW5lciogbGlzdGVuZXIpOworCisgIHZpcnR1YWwgUHJvdG9FbGVtZW50KiBlbGVtZW50KCkgeyByZXR1cm4gZWxlbWVudF8uZ2V0KCk7IH0KKworICAvLyBIZWxwZXIgbWV0aG9kcyBmb3IgY2FsbGluZyBFcnJvckxpc3RlbmVyLiBTZWUgZXJyb3JfbGlzdGVuZXIuaC4KKyAgdm9pZCBJbnZhbGlkTmFtZShTdHJpbmdQaWVjZSB1bmtub3duX25hbWUsIFN0cmluZ1BpZWNlIG1lc3NhZ2UpOworICB2b2lkIEludmFsaWRWYWx1ZShTdHJpbmdQaWVjZSB0eXBlX25hbWUsIFN0cmluZ1BpZWNlIHZhbHVlKTsKKyAgdm9pZCBNaXNzaW5nRmllbGQoU3RyaW5nUGllY2UgbWlzc2luZ19uYW1lKTsKKworICAvLyBDb21tb24gY29kZSBmb3IgQmVnaW5PYmplY3QoKSBhbmQgQmVnaW5MaXN0KCkgdGhhdCBkb2VzIGludmFsaWRfZGVwdGhfCisgIC8vIGJvb2trZWVwaW5nIGFzc29jaWF0ZWQgd2l0aCBuYW1lIGxvb2t1cC4KKyAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGQqIEJlZ2luTmFtZWQoU3RyaW5nUGllY2UgbmFtZSwgYm9vbCBpc19saXN0KTsKKworICAvLyBMb29rdXAgdGhlIGZpZWxkIGluIHRoZSBjdXJyZW50IGVsZW1lbnQuIExvb2tzIGluIHRoZSBiYXNlIGRlc2NyaXB0b3IKKyAgLy8gYW5kIGluIGFueSBleHRlbnNpb24uIFRoaXMgd2lsbCByZXBvcnQgYW4gZXJyb3IgaWYgdGhlIGZpZWxkIGNhbm5vdCBiZQorICAvLyBmb3VuZCBvciBpZiBtdWx0aXBsZSBtYXRjaGluZyBleHRlbnNpb25zIGFyZSBmb3VuZC4KKyAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGQqIExvb2t1cChTdHJpbmdQaWVjZSBuYW1lKTsKKworICAvLyBMb29rdXAgdGhlIGZpZWxkIHR5cGUgaW4gdGhlIHR5cGUgZGVzY3JpcHRvci4gUmV0dXJucyBOVUxMIGlmIHRoZSB0eXBlCisgIC8vIGlzIG5vdCBrbm93bi4KKyAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6VHlwZSogTG9va3VwVHlwZSgKKyAgICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkKiBmaWVsZCk7CisKKyAgLy8gV3JpdGUgc2VyaWFsaXplZCBvdXRwdXQgdG8gdGhlIGZpbmFsIG91dHB1dCBCeXRlU2luaywgaW5zZXJ0aW5nIGFsbAorICAvLyB0aGUgc2l6ZSBpbmZvcm1hdGlvbiBmb3IgbmVzdGVkIG1lc3NhZ2VzIHRoYXQgYXJlIG1pc3NpbmcgZnJvbSB0aGUKKyAgLy8gaW50ZXJtZWRpYXRlIENvcmQgYnVmZmVyLgorICB2b2lkIFdyaXRlUm9vdE1lc3NhZ2UoKTsKKworICAvLyBIZWxwZXIgbWV0aG9kIHRvIHdyaXRlIHByb3RvIHRhZ3MgYmFzZWQgb24gdGhlIGdpdmVuIGZpZWxkLgorICB2b2lkIFdyaXRlVGFnKGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkJiBmaWVsZCk7CisKKworICAvLyBSZXR1cm5zIHRydWUgaWYgdGhlIGZpZWxkIGZvciB0eXBlXyBjYW4gYmUgc2V0IGFzIGEgb25lb2YuIElmIGZpZWxkIGlzIG5vdAorICAvLyBhIG9uZW9mIHR5cGUsIHRoaXMgZnVuY3Rpb24gZG9lcyBub3RoaW5nIGFuZCByZXR1cm5zIHRydWUuCisgIC8vIElmIGFub3RoZXIgZmllbGQgZm9yIHRoaXMgb25lb2YgaXMgYWxyZWFkeSBzZXQsIHRoaXMgZnVuY3Rpb24gcmV0dXJucworICAvLyBmYWxzZS4gSXQgYWxzbyBjYWxscyB0aGUgYXBwcm9wcmlhdGUgZXJyb3IgY2FsbGJhY2suCisgIC8vIHVubm9ybWFsaXplZF9uYW1lIGlzIHVzZWQgZm9yIGVycm9yIHN0cmluZy4KKyAgYm9vbCBWYWxpZE9uZW9mKGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkJiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgIFN0cmluZ1BpZWNlIHVubm9ybWFsaXplZF9uYW1lKTsKKworICAvLyBSZXR1cm5zIHRydWUgaWYgdGhlIGZpZWxkIGlzIHJlcGVhdGVkLgorICBib29sIElzUmVwZWF0ZWQoY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGQmIGZpZWxkKTsKKworIHByaXZhdGU6CisgIC8vIFZhcmlhYmxlcyBmb3IgZGVzY3JpYmluZyB0aGUgc3RydWN0dXJlIG9mIHRoZSBpbnB1dCB0cmVlOgorICAvLyBtYXN0ZXJfdHlwZV86IGRlc2NyaXB0b3IgZm9yIHRoZSB3aG9sZSBwcm90b2J1ZiBtZXNzYWdlLgorICAvLyB0eXBlaW5mb18gOiB0aGUgVHlwZUluZm8gb2JqZWN0IHRvIGxvb2t1cCB0eXBlcy4KKyAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6VHlwZSYgbWFzdGVyX3R5cGVfOworICBjb25zdCBUeXBlSW5mbyogdHlwZWluZm9fOworICAvLyBXaGV0aGVyIHdlIG93biB0aGUgdHlwZWluZm9fIG9iamVjdC4KKyAgYm9vbCBvd25fdHlwZWluZm9fOworCisgIC8vIEluZGljYXRlcyB3aGV0aGVyIHdlIGZpbmlzaGVkIHdyaXRpbmcgcm9vdCBtZXNzYWdlIGNvbXBsZXRlbHkuCisgIGJvb2wgZG9uZV87CisKKyAgLy8gVmFyaWFibGUgZm9yIGludGVybmFsIHN0YXRlIHByb2Nlc3Npbmc6CisgIC8vIGVsZW1lbnRfICAgIDogdGhlIGN1cnJlbnQgZWxlbWVudC4KKyAgLy8gc2l6ZV9pbnNlcnRfOiBzaXplcyBvZiBuZXN0ZWQgbWVzc2FnZXMuCisgIC8vICAgICAgICAgICAgICAgcG9zICAtIHBvc2l0aW9uIHRvIGluc2VydCB0aGUgc2l6ZSBmaWVsZC4KKyAgLy8gICAgICAgICAgICAgICBzaXplIC0gc2l6ZSB2YWx1ZSB0byBiZSBpbnNlcnRlZC4KKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxQcm90b0VsZW1lbnQ+IGVsZW1lbnRfOworICBzdGQ6OmRlcXVlPFNpemVJbmZvPiBzaXplX2luc2VydF87CisKKyAgLy8gVmFyaWFibGVzIGZvciBvdXRwdXQgZ2VuZXJhdGlvbjoKKyAgLy8gb3V0cHV0XyAgOiBwb2ludGVyIHRvIGFuIGV4dGVybmFsIEJ5dGVTaW5rIGZvciBmaW5hbCB1c2VyLXZpc2libGUgb3V0cHV0LgorICAvLyBidWZmZXJfICA6IGJ1ZmZlciBob2xkaW5nIHBhcnRpYWwgbWVzc2FnZSBiZWZvcmUgYmVpbmcgcmVhZHkgZm9yIG91dHB1dF8uCisgIC8vIGFkYXB0ZXJfIDogaW50ZXJuYWwgYWRhcHRlciBiZXR3ZWVuIENvZGVkT3V0cHV0U3RyZWFtIGFuZCBidWZmZXJfLgorICAvLyBzdHJlYW1fICA6IHdyYXBwZXIgZm9yIHdyaXRpbmcgdGFncyBhbmQgb3RoZXIgZW5jb2RpbmdzIGluIHdpcmUgZm9ybWF0LgorICBzdHJpbmdzOjpCeXRlU2luayogb3V0cHV0XzsKKyAgc3RyaW5nIGJ1ZmZlcl87CisgIGdvb2dsZTo6cHJvdG9idWY6OmlvOjpTdHJpbmdPdXRwdXRTdHJlYW0gYWRhcHRlcl87CisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtPiBzdHJlYW1fOworCisgIC8vIFZhcmlhYmxlcyBmb3IgZXJyb3IgdHJhY2tpbmcgYW5kIHJlcG9ydGluZzoKKyAgLy8gbGlzdGVuZXJfICAgICA6IGEgcGxhY2UgdG8gcmVwb3J0IGFueSBlcnJvcnMgZm91bmQuCisgIC8vIGludmFsaWRfZGVwdGhfOiBudW1iZXIgb2YgZW5jbG9zaW5nIGludmFsaWQgbmVzdGVkIG1lc3NhZ2VzLgorICAvLyB0cmFja2VyXyAgICAgIDogdGhlIHJvb3QgbG9jYXRpb24gdHJhY2tlciBpbnRlcmZhY2UuCisgIEVycm9yTGlzdGVuZXIqIGxpc3RlbmVyXzsKKyAgaW50IGludmFsaWRfZGVwdGhfOworICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPExvY2F0aW9uVHJhY2tlckludGVyZmFjZT4gdHJhY2tlcl87CisKKyAgR09PR0xFX0RJU0FMTE9XX0lNUExJQ0lUX0NPTlNUUlVDVE9SUyhQcm90b1dyaXRlcik7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgY29udmVydGVyCit9ICAvLyBuYW1lc3BhY2UgdXRpbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX1VUSUxfQ09OVkVSVEVSX1BST1RPX1dSSVRFUl9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9wcm90b3N0cmVhbV9vYmplY3Rzb3VyY2UuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvcHJvdG9zdHJlYW1fb2JqZWN0c291cmNlLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAzNGQ2MTYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvcHJvdG9zdHJlYW1fb2JqZWN0c291cmNlLmNjCkBAIC0wLDAgKzEsMTA0NSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9wcm90b3N0cmVhbV9vYmplY3Rzb3VyY2UuaD4KKworI2luY2x1ZGUgPHV0aWxpdHk+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY2FzdHMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbG9nZ2luZy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RyaW5ncHJpbnRmLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3RpbWUuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0X2xpdGUuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9maWVsZF9tYXNrX3V0aWxpdHkuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9jb25zdGFudHMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC91dGlsaXR5Lmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbWFwX3V0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RhdHVzX21hY3Jvcy5oPgorCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSB1dGlsIHsKK3VzaW5nIHV0aWw6OlN0YXR1czsKK3VzaW5nIHV0aWw6OlN0YXR1c09yOworbmFtZXNwYWNlIGVycm9yIHsKK3VzaW5nIHV0aWw6OmVycm9yOjpDb2RlOwordXNpbmcgdXRpbDo6ZXJyb3I6OklOVEVSTkFMOworfQorbmFtZXNwYWNlIGNvbnZlcnRlciB7CisKK3VzaW5nIGdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3I7Cit1c2luZyBnb29nbGU6OnByb3RvYnVmOjpFbnVtVmFsdWVEZXNjcmlwdG9yOwordXNpbmcgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGREZXNjcmlwdG9yOwordXNpbmcgZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXQ7Cit1c2luZyBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU7Cit1c2luZyB1dGlsOjpTdGF0dXM7Cit1c2luZyB1dGlsOjpTdGF0dXNPcjsKKworbmFtZXNwYWNlIHsKKy8vIEZpbmRzIGEgZmllbGQgd2l0aCB0aGUgZ2l2ZW4gbnVtYmVyLiBOVUxMIGlmIG5vbmUgZm91bmQuCitjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZCogRmluZEZpZWxkQnlOdW1iZXIoCisgICAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6VHlwZSYgdHlwZSwgaW50IG51bWJlcik7CisKKy8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgZmllbGQgaXMgcGFja2FibGUuCitib29sIElzUGFja2FibGUoY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGQmIGZpZWxkKTsKKworLy8gRmluZHMgYW4gZW51bSB2YWx1ZSB3aXRoIHRoZSBnaXZlbiBudW1iZXIuIE5VTEwgaWYgbm9uZSBmb3VuZC4KK2NvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZSogRmluZEVudW1WYWx1ZUJ5TnVtYmVyKAorICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkVudW0mIHRlY2hfZW51bSwgaW50IG51bWJlcik7CisKKy8vIFV0aWxpdHkgZnVuY3Rpb24gdG8gZm9ybWF0IG5hbm9zLgorY29uc3Qgc3RyaW5nIEZvcm1hdE5hbm9zKHVpbnQzMiBuYW5vcyk7Cit9ICAvLyBuYW1lc3BhY2UKKworCitQcm90b1N0cmVhbU9iamVjdFNvdXJjZTo6UHJvdG9TdHJlYW1PYmplY3RTb3VyY2UoCisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIHN0cmVhbSwgVHlwZVJlc29sdmVyKiB0eXBlX3Jlc29sdmVyLAorICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlR5cGUmIHR5cGUpCisgICAgOiBzdHJlYW1fKHN0cmVhbSksCisgICAgICB0eXBlaW5mb18oVHlwZUluZm86Ok5ld1R5cGVJbmZvKHR5cGVfcmVzb2x2ZXIpKSwKKyAgICAgIG93bl90eXBlaW5mb18odHJ1ZSksCisgICAgICB0eXBlXyh0eXBlKSB7CisgIEdPT0dMRV9MT0dfSUYoREZBVEFMLCBzdHJlYW0gPT0gTlVMTCkgPDwgIklucHV0IHN0cmVhbSBpcyBOVUxMLiI7Cit9CisKK1Byb3RvU3RyZWFtT2JqZWN0U291cmNlOjpQcm90b1N0cmVhbU9iamVjdFNvdXJjZSgKKyAgICBnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogc3RyZWFtLCBjb25zdCBUeXBlSW5mbyogdHlwZWluZm8sCisgICAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6VHlwZSYgdHlwZSkKKyAgICA6IHN0cmVhbV8oc3RyZWFtKSwgdHlwZWluZm9fKHR5cGVpbmZvKSwgb3duX3R5cGVpbmZvXyhmYWxzZSksIHR5cGVfKHR5cGUpIHsKKyAgR09PR0xFX0xPR19JRihERkFUQUwsIHN0cmVhbSA9PSBOVUxMKSA8PCAiSW5wdXQgc3RyZWFtIGlzIE5VTEwuIjsKK30KKworUHJvdG9TdHJlYW1PYmplY3RTb3VyY2U6On5Qcm90b1N0cmVhbU9iamVjdFNvdXJjZSgpIHsKKyAgaWYgKG93bl90eXBlaW5mb18pIHsKKyAgICBkZWxldGUgdHlwZWluZm9fOworICB9Cit9CisKK1N0YXR1cyBQcm90b1N0cmVhbU9iamVjdFNvdXJjZTo6TmFtZWRXcml0ZVRvKFN0cmluZ1BpZWNlIG5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3RXcml0ZXIqIG93KSBjb25zdCB7CisgIHJldHVybiBXcml0ZU1lc3NhZ2UodHlwZV8sIG5hbWUsIDAsIHRydWUsIG93KTsKK30KKworY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGQqIFByb3RvU3RyZWFtT2JqZWN0U291cmNlOjpGaW5kQW5kVmVyaWZ5RmllbGQoCisgICAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6VHlwZSYgdHlwZSwgdWludDMyIHRhZykgY29uc3QgeworICAvLyBMb29rdXAgdGhlIG5ldyBmaWVsZCBpbiB0aGUgdHlwZSBieSB0YWcgbnVtYmVyLgorICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZCogZmllbGQgPSBGaW5kRmllbGRCeU51bWJlcih0eXBlLCB0YWcgPj4gMyk7CisgIC8vIFZlcmlmeSBpZiB0aGUgZmllbGQgY29ycmVzcG9uZHMgdG8gdGhlIHdpcmUgdHlwZSBpbiB0YWcuCisgIC8vIElmIHRoZXJlIGlzIGFueSBkaXNjcmVwYW5jeSwgbWFyayB0aGUgZmllbGQgYXMgbm90IGZvdW5kLgorICBpZiAoZmllbGQgIT0gTlVMTCkgeworICAgIFdpcmVGb3JtYXRMaXRlOjpXaXJlVHlwZSBleHBlY3RlZF90eXBlID0KKyAgICAgICAgV2lyZUZvcm1hdExpdGU6OldpcmVUeXBlRm9yRmllbGRUeXBlKAorICAgICAgICAgICAgc3RhdGljX2Nhc3Q8V2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZT4oZmllbGQtPmtpbmQoKSkpOworICAgIFdpcmVGb3JtYXRMaXRlOjpXaXJlVHlwZSBhY3R1YWxfdHlwZSA9IFdpcmVGb3JtYXRMaXRlOjpHZXRUYWdXaXJlVHlwZSh0YWcpOworICAgIGlmIChhY3R1YWxfdHlwZSAhPSBleHBlY3RlZF90eXBlICYmCisgICAgICAgICghSXNQYWNrYWJsZSgqZmllbGQpIHx8CisgICAgICAgICBhY3R1YWxfdHlwZSAhPSBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCkpIHsKKyAgICAgIGZpZWxkID0gTlVMTDsKKyAgICB9CisgIH0KKyAgcmV0dXJuIGZpZWxkOworfQorCitTdGF0dXMgUHJvdG9TdHJlYW1PYmplY3RTb3VyY2U6OldyaXRlTWVzc2FnZShjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlJiB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UgbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVpbnQzMiBlbmRfdGFnLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpbmNsdWRlX3N0YXJ0X2FuZF9lbmQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3RXcml0ZXIqIG93KSBjb25zdCB7CisKKyAgICBjb25zdCBUeXBlUmVuZGVyZXIqIHR5cGVfcmVuZGVyZXIgPSBGaW5kVHlwZVJlbmRlcmVyKHR5cGUubmFtZSgpKTsKKyAgICBpZiAodHlwZV9yZW5kZXJlciAhPSBOVUxMKSB7CisgICAgICByZXR1cm4gKCp0eXBlX3JlbmRlcmVyKSh0aGlzLCB0eXBlLCBuYW1lLCBvdyk7CisgICAgfQorCisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkKiBmaWVsZCA9IE5VTEw7CisgIHN0cmluZyBmaWVsZF9uYW1lOworICAvLyBsYXN0X3RhZyBzZXQgdG8gZHVtbXkgdmFsdWUgdGhhdCBpcyBkaWZmZXJlbnQgZnJvbSB0YWcuCisgIHVpbnQzMiB0YWcgPSBzdHJlYW1fLT5SZWFkVGFnKCksIGxhc3RfdGFnID0gdGFnICsgMTsKKworICBpZiAoaW5jbHVkZV9zdGFydF9hbmRfZW5kKSB7CisgICAgb3ctPlN0YXJ0T2JqZWN0KG5hbWUpOworICB9CisgIHdoaWxlICh0YWcgIT0gZW5kX3RhZykgeworICAgIGlmICh0YWcgIT0gbGFzdF90YWcpIHsgIC8vIFVwZGF0ZSBmaWVsZCBvbmx5IGlmIHRhZyBpcyBjaGFuZ2VkLgorICAgICAgbGFzdF90YWcgPSB0YWc7CisgICAgICBmaWVsZCA9IEZpbmRBbmRWZXJpZnlGaWVsZCh0eXBlLCB0YWcpOworICAgICAgaWYgKGZpZWxkICE9IE5VTEwpIHsKKyAgICAgICAgZmllbGRfbmFtZSA9IGZpZWxkLT5qc29uX25hbWUoKTsKKyAgICAgIH0KKyAgICB9CisgICAgaWYgKGZpZWxkID09IE5VTEwpIHsKKyAgICAgIC8vIElmIHdlIGRpZG4ndCBmaW5kIGEgZmllbGQsIHNraXAgdGhpcyB1bmtub3duIHRhZy4KKyAgICAgIC8vIFRPRE8od3Bvb24pOiBDaGVjayByZXR1cm4gYm9vbGVhbiB2YWx1ZS4KKyAgICAgIFdpcmVGb3JtYXQ6OlNraXBGaWVsZChzdHJlYW1fLCB0YWcsIE5VTEwpOworICAgICAgdGFnID0gc3RyZWFtXy0+UmVhZFRhZygpOworICAgICAgY29udGludWU7CisgICAgfQorCisgICAgaWYgKGZpZWxkLT5jYXJkaW5hbGl0eSgpID09CisgICAgICAgIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0NhcmRpbmFsaXR5X0NBUkRJTkFMSVRZX1JFUEVBVEVEKSB7CisgICAgICBib29sIGNoZWNrX21hcHMgPSB0cnVlOworCisgICAgICBpZiAoY2hlY2tfbWFwcyAmJiBJc01hcCgqZmllbGQpKSB7CisgICAgICAgIG93LT5TdGFydE9iamVjdChmaWVsZF9uYW1lKTsKKyAgICAgICAgQVNTSUdOX09SX1JFVFVSTih0YWcsIFJlbmRlck1hcChmaWVsZCwgZmllbGRfbmFtZSwgdGFnLCBvdykpOworICAgICAgICBvdy0+RW5kT2JqZWN0KCk7CisgICAgICB9IGVsc2UgeworICAgICAgICBBU1NJR05fT1JfUkVUVVJOKHRhZywgUmVuZGVyTGlzdChmaWVsZCwgZmllbGRfbmFtZSwgdGFnLCBvdykpOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICAvLyBSZW5kZXIgdGhlIGZpZWxkLgorICAgICAgUkVUVVJOX0lGX0VSUk9SKFJlbmRlckZpZWxkKGZpZWxkLCBmaWVsZF9uYW1lLCBvdykpOworICAgICAgdGFnID0gc3RyZWFtXy0+UmVhZFRhZygpOworICAgIH0KKyAgfQorICBpZiAoaW5jbHVkZV9zdGFydF9hbmRfZW5kKSB7CisgICAgb3ctPkVuZE9iamVjdCgpOworICB9CisgIHJldHVybiBTdGF0dXM6Ok9LOworfQorCitTdGF0dXNPcjx1aW50MzI+IFByb3RvU3RyZWFtT2JqZWN0U291cmNlOjpSZW5kZXJMaXN0KAorICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkKiBmaWVsZCwgU3RyaW5nUGllY2UgbmFtZSwgdWludDMyIGxpc3RfdGFnLAorICAgIE9iamVjdFdyaXRlciogb3cpIGNvbnN0IHsKKyAgdWludDMyIHRhZ190b19yZXR1cm4gPSAwOworICBvdy0+U3RhcnRMaXN0KG5hbWUpOworICBpZiAoSXNQYWNrYWJsZSgqZmllbGQpICYmCisgICAgICBsaXN0X3RhZyA9PQorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpNYWtlVGFnKGZpZWxkLT5udW1iZXIoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCkpIHsKKyAgICBSRVRVUk5fSUZfRVJST1IoUmVuZGVyUGFja2VkKGZpZWxkLCBvdykpOworICAgIC8vIFNpbmNlIHBhY2tlZCBmaWVsZHMgaGF2ZSBhIHNpbmdsZSB0YWcsIHJlYWQgYW5vdGhlciB0YWcgZnJvbSBzdHJlYW0gdG8KKyAgICAvLyByZXR1cm4uCisgICAgdGFnX3RvX3JldHVybiA9IHN0cmVhbV8tPlJlYWRUYWcoKTsKKyAgfSBlbHNlIHsKKyAgICBkbyB7CisgICAgICBSRVRVUk5fSUZfRVJST1IoUmVuZGVyRmllbGQoZmllbGQsICIiLCBvdykpOworICAgIH0gd2hpbGUgKCh0YWdfdG9fcmV0dXJuID0gc3RyZWFtXy0+UmVhZFRhZygpKSA9PSBsaXN0X3RhZyk7CisgIH0KKyAgb3ctPkVuZExpc3QoKTsKKyAgcmV0dXJuIHRhZ190b19yZXR1cm47Cit9CisKK1N0YXR1c09yPHVpbnQzMj4gUHJvdG9TdHJlYW1PYmplY3RTb3VyY2U6OlJlbmRlck1hcCgKKyAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZCogZmllbGQsIFN0cmluZ1BpZWNlIG5hbWUsIHVpbnQzMiBsaXN0X3RhZywKKyAgICBPYmplY3RXcml0ZXIqIG93KSBjb25zdCB7CisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlR5cGUqIGZpZWxkX3R5cGUgPQorICAgICAgdHlwZWluZm9fLT5HZXRUeXBlQnlUeXBlVXJsKGZpZWxkLT50eXBlX3VybCgpKTsKKyAgdWludDMyIHRhZ190b19yZXR1cm4gPSAwOworICBkbyB7CisgICAgLy8gUmVuZGVyIG1hcCBlbnRyeSBtZXNzYWdlIHR5cGUuCisgICAgdWludDMyIGJ1ZmZlcjMyOworICAgIHN0cmVhbV8tPlJlYWRWYXJpbnQzMigmYnVmZmVyMzIpOyAgLy8gbWVzc2FnZSBsZW5ndGgKKyAgICBpbnQgb2xkX2xpbWl0ID0gc3RyZWFtXy0+UHVzaExpbWl0KGJ1ZmZlcjMyKTsKKyAgICBzdHJpbmcgbWFwX2tleTsKKyAgICBmb3IgKHVpbnQzMiB0YWcgPSBzdHJlYW1fLT5SZWFkVGFnKCk7IHRhZyAhPSAwOyB0YWcgPSBzdHJlYW1fLT5SZWFkVGFnKCkpIHsKKyAgICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkKiBmaWVsZCA9CisgICAgICAgICAgRmluZEFuZFZlcmlmeUZpZWxkKCpmaWVsZF90eXBlLCB0YWcpOworICAgICAgaWYgKGZpZWxkID09IE5VTEwpIHsKKyAgICAgICAgV2lyZUZvcm1hdDo6U2tpcEZpZWxkKHN0cmVhbV8sIHRhZywgTlVMTCk7CisgICAgICAgIGNvbnRpbnVlOworICAgICAgfQorICAgICAgLy8gTWFwIGZpZWxkIG51bWJlcnMgYXJlIGtleSA9IDEgYW5kIHZhbHVlID0gMgorICAgICAgaWYgKGZpZWxkLT5udW1iZXIoKSA9PSAxKSB7CisgICAgICAgIG1hcF9rZXkgPSBSZWFkRmllbGRWYWx1ZUFzU3RyaW5nKCpmaWVsZCk7CisgICAgICB9IGVsc2UgaWYgKGZpZWxkLT5udW1iZXIoKSA9PSAyKSB7CisgICAgICAgIGlmIChtYXBfa2V5LmVtcHR5KCkpIHsKKyAgICAgICAgICByZXR1cm4gU3RhdHVzKHV0aWw6OmVycm9yOjpJTlRFUk5BTCwgIk1hcCBrZXkgbXVzdCBiZSBub24tZW1wdHkiKTsKKyAgICAgICAgfQorICAgICAgICBSRVRVUk5fSUZfRVJST1IoUmVuZGVyRmllbGQoZmllbGQsIG1hcF9rZXksIG93KSk7CisgICAgICB9CisgICAgfQorICAgIHN0cmVhbV8tPlBvcExpbWl0KG9sZF9saW1pdCk7CisgIH0gd2hpbGUgKCh0YWdfdG9fcmV0dXJuID0gc3RyZWFtXy0+UmVhZFRhZygpKSA9PSBsaXN0X3RhZyk7CisgIHJldHVybiB0YWdfdG9fcmV0dXJuOworfQorCitTdGF0dXMgUHJvdG9TdHJlYW1PYmplY3RTb3VyY2U6OlJlbmRlclBhY2tlZCgKKyAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZCogZmllbGQsIE9iamVjdFdyaXRlciogb3cpIGNvbnN0IHsKKyAgdWludDMyIGxlbmd0aDsKKyAgc3RyZWFtXy0+UmVhZFZhcmludDMyKCZsZW5ndGgpOworICBpbnQgb2xkX2xpbWl0ID0gc3RyZWFtXy0+UHVzaExpbWl0KGxlbmd0aCk7CisgIHdoaWxlIChzdHJlYW1fLT5CeXRlc1VudGlsTGltaXQoKSA+IDApIHsKKyAgICBSRVRVUk5fSUZfRVJST1IoUmVuZGVyRmllbGQoZmllbGQsIFN0cmluZ1BpZWNlKCksIG93KSk7CisgIH0KKyAgc3RyZWFtXy0+UG9wTGltaXQob2xkX2xpbWl0KTsKKyAgcmV0dXJuIFN0YXR1czo6T0s7Cit9CisKK1N0YXR1cyBQcm90b1N0cmVhbU9iamVjdFNvdXJjZTo6UmVuZGVyVGltZXN0YW1wKAorICAgIGNvbnN0IFByb3RvU3RyZWFtT2JqZWN0U291cmNlKiBvcywgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6VHlwZSYgdHlwZSwKKyAgICBTdHJpbmdQaWVjZSBmaWVsZF9uYW1lLCBPYmplY3RXcml0ZXIqIG93KSB7CisgIHBhaXI8aW50NjQsIGludDMyPiBwID0gb3MtPlJlYWRTZWNvbmRzQW5kTmFub3ModHlwZSk7CisgIGludDY0IHNlY29uZHMgPSBwLmZpcnN0OworICBpbnQzMiBuYW5vcyA9IHAuc2Vjb25kOworICBpZiAoc2Vjb25kcyA+IGtNYXhTZWNvbmRzIHx8IHNlY29uZHMgPCBrTWluU2Vjb25kcykgeworICAgIHJldHVybiBTdGF0dXMoCisgICAgICAgIHV0aWw6OmVycm9yOjpJTlRFUk5BTCwKKyAgICAgICAgU3RyQ2F0KCJUaW1lc3RhbXAgc2Vjb25kcyBleGNlZWRzIGxpbWl0IGZvciBmaWVsZDogIiwgZmllbGRfbmFtZSkpOworICB9CisKKyAgaWYgKG5hbm9zIDwgMCB8fCBuYW5vcyA+PSBrTmFub3NQZXJTZWNvbmQpIHsKKyAgICByZXR1cm4gU3RhdHVzKAorICAgICAgICB1dGlsOjplcnJvcjo6SU5URVJOQUwsCisgICAgICAgIFN0ckNhdCgiVGltZXN0YW1wIG5hbm9zIGV4Y2VlZHMgbGltaXQgZm9yIGZpZWxkOiAiLCBmaWVsZF9uYW1lKSk7CisgIH0KKworICBvdy0+UmVuZGVyU3RyaW5nKGZpZWxkX25hbWUsCisgICAgICAgICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6Rm9ybWF0VGltZShzZWNvbmRzLCBuYW5vcykpOworCisgIHJldHVybiBTdGF0dXM6Ok9LOworfQorCitTdGF0dXMgUHJvdG9TdHJlYW1PYmplY3RTb3VyY2U6OlJlbmRlckR1cmF0aW9uKAorICAgIGNvbnN0IFByb3RvU3RyZWFtT2JqZWN0U291cmNlKiBvcywgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6VHlwZSYgdHlwZSwKKyAgICBTdHJpbmdQaWVjZSBmaWVsZF9uYW1lLCBPYmplY3RXcml0ZXIqIG93KSB7CisgIHBhaXI8aW50NjQsIGludDMyPiBwID0gb3MtPlJlYWRTZWNvbmRzQW5kTmFub3ModHlwZSk7CisgIGludDY0IHNlY29uZHMgPSBwLmZpcnN0OworICBpbnQzMiBuYW5vcyA9IHAuc2Vjb25kOworICBpZiAoc2Vjb25kcyA+IGtNYXhTZWNvbmRzIHx8IHNlY29uZHMgPCBrTWluU2Vjb25kcykgeworICAgIHJldHVybiBTdGF0dXMoCisgICAgICAgIHV0aWw6OmVycm9yOjpJTlRFUk5BTCwKKyAgICAgICAgU3RyQ2F0KCJEdXJhdGlvbiBzZWNvbmRzIGV4Y2VlZHMgbGltaXQgZm9yIGZpZWxkOiAiLCBmaWVsZF9uYW1lKSk7CisgIH0KKworICBpZiAobmFub3MgPD0gLWtOYW5vc1BlclNlY29uZCB8fCBuYW5vcyA+PSBrTmFub3NQZXJTZWNvbmQpIHsKKyAgICByZXR1cm4gU3RhdHVzKAorICAgICAgICB1dGlsOjplcnJvcjo6SU5URVJOQUwsCisgICAgICAgIFN0ckNhdCgiRHVyYXRpb24gbmFub3MgZXhjZWVkcyBsaW1pdCBmb3IgZmllbGQ6ICIsIGZpZWxkX25hbWUpKTsKKyAgfQorCisgIHN0cmluZyBzaWduID0gIiI7CisgIGlmIChzZWNvbmRzIDwgMCkgeworICAgIGlmIChuYW5vcyA+IDApIHsKKyAgICAgIHJldHVybiBTdGF0dXModXRpbDo6ZXJyb3I6OklOVEVSTkFMLAorICAgICAgICAgICAgICAgICAgICBTdHJDYXQoIkR1cmF0aW9uIG5hbm9zIGlzIG5vbi1uZWdhdGl2ZSwgYnV0IHNlY29uZHMgaXMgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIm5lZ2F0aXZlIGZvciBmaWVsZDogIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkX25hbWUpKTsKKyAgICB9CisgICAgc2lnbiA9ICItIjsKKyAgICBzZWNvbmRzID0gLXNlY29uZHM7CisgICAgbmFub3MgPSAtbmFub3M7CisgIH0gZWxzZSBpZiAoc2Vjb25kcyA9PSAwICYmIG5hbm9zIDwgMCkgeworICAgIHNpZ24gPSAiLSI7CisgICAgbmFub3MgPSAtbmFub3M7CisgIH0KKyAgc3RyaW5nIGZvcm1hdHRlZF9kdXJhdGlvbiA9IFN0cmluZ1ByaW50ZigiJXMlbGxkJXNzIiwgc2lnbi5jX3N0cigpLCBzZWNvbmRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZvcm1hdE5hbm9zKG5hbm9zKS5jX3N0cigpKTsKKyAgb3ctPlJlbmRlclN0cmluZyhmaWVsZF9uYW1lLCBmb3JtYXR0ZWRfZHVyYXRpb24pOworICByZXR1cm4gU3RhdHVzOjpPSzsKK30KKworU3RhdHVzIFByb3RvU3RyZWFtT2JqZWN0U291cmNlOjpSZW5kZXJEb3VibGUoY29uc3QgUHJvdG9TdHJlYW1PYmplY3RTb3VyY2UqIG9zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6VHlwZSYgdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1BpZWNlIGZpZWxkX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3RXcml0ZXIqIG93KSB7CisgIHVpbnQzMiB0YWcgPSBvcy0+c3RyZWFtXy0+UmVhZFRhZygpOworICB1aW50NjQgYnVmZmVyNjQgPSAwOyAgLy8gZGVmYXVsdCB2YWx1ZSBvZiBEb3VibGUgd3JhcHBlciB2YWx1ZQorICBpZiAodGFnICE9IDApIHsKKyAgICBvcy0+c3RyZWFtXy0+UmVhZExpdHRsZUVuZGlhbjY0KCZidWZmZXI2NCk7CisgICAgb3MtPnN0cmVhbV8tPlJlYWRUYWcoKTsKKyAgfQorICBvdy0+UmVuZGVyRG91YmxlKGZpZWxkX25hbWUsIGJpdF9jYXN0PGRvdWJsZT4oYnVmZmVyNjQpKTsKKyAgcmV0dXJuIFN0YXR1czo6T0s7Cit9CisKK1N0YXR1cyBQcm90b1N0cmVhbU9iamVjdFNvdXJjZTo6UmVuZGVyRmxvYXQoY29uc3QgUHJvdG9TdHJlYW1PYmplY3RTb3VyY2UqIG9zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlJiB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdQaWVjZSBmaWVsZF9uYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3RXcml0ZXIqIG93KSB7CisgIHVpbnQzMiB0YWcgPSBvcy0+c3RyZWFtXy0+UmVhZFRhZygpOworICB1aW50MzIgYnVmZmVyMzIgPSAwOyAgLy8gZGVmYXVsdCB2YWx1ZSBvZiBGbG9hdCB3cmFwcGVyIHZhbHVlCisgIGlmICh0YWcgIT0gMCkgeworICAgIG9zLT5zdHJlYW1fLT5SZWFkTGl0dGxlRW5kaWFuMzIoJmJ1ZmZlcjMyKTsKKyAgICBvcy0+c3RyZWFtXy0+UmVhZFRhZygpOworICB9CisgIG93LT5SZW5kZXJGbG9hdChmaWVsZF9uYW1lLCBiaXRfY2FzdDxmbG9hdD4oYnVmZmVyMzIpKTsKKyAgcmV0dXJuIFN0YXR1czo6T0s7Cit9CisKK1N0YXR1cyBQcm90b1N0cmVhbU9iamVjdFNvdXJjZTo6UmVuZGVySW50NjQoY29uc3QgUHJvdG9TdHJlYW1PYmplY3RTb3VyY2UqIG9zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlJiB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdQaWVjZSBmaWVsZF9uYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3RXcml0ZXIqIG93KSB7CisgIHVpbnQzMiB0YWcgPSBvcy0+c3RyZWFtXy0+UmVhZFRhZygpOworICB1aW50NjQgYnVmZmVyNjQgPSAwOyAgLy8gZGVmYXVsdCB2YWx1ZSBvZiBJbnQ2NCB3cmFwcGVyIHZhbHVlCisgIGlmICh0YWcgIT0gMCkgeworICAgIG9zLT5zdHJlYW1fLT5SZWFkVmFyaW50NjQoJmJ1ZmZlcjY0KTsKKyAgICBvcy0+c3RyZWFtXy0+UmVhZFRhZygpOworICB9CisgIG93LT5SZW5kZXJJbnQ2NChmaWVsZF9uYW1lLCBiaXRfY2FzdDxpbnQ2ND4oYnVmZmVyNjQpKTsKKyAgcmV0dXJuIFN0YXR1czo6T0s7Cit9CisKK1N0YXR1cyBQcm90b1N0cmVhbU9iamVjdFNvdXJjZTo6UmVuZGVyVUludDY0KGNvbnN0IFByb3RvU3RyZWFtT2JqZWN0U291cmNlKiBvcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlR5cGUmIHR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdQaWVjZSBmaWVsZF9uYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0V3JpdGVyKiBvdykgeworICB1aW50MzIgdGFnID0gb3MtPnN0cmVhbV8tPlJlYWRUYWcoKTsKKyAgdWludDY0IGJ1ZmZlcjY0ID0gMDsgIC8vIGRlZmF1bHQgdmFsdWUgb2YgVUludDY0IHdyYXBwZXIgdmFsdWUKKyAgaWYgKHRhZyAhPSAwKSB7CisgICAgb3MtPnN0cmVhbV8tPlJlYWRWYXJpbnQ2NCgmYnVmZmVyNjQpOworICAgIG9zLT5zdHJlYW1fLT5SZWFkVGFnKCk7CisgIH0KKyAgb3ctPlJlbmRlclVpbnQ2NChmaWVsZF9uYW1lLCBiaXRfY2FzdDx1aW50NjQ+KGJ1ZmZlcjY0KSk7CisgIHJldHVybiBTdGF0dXM6Ok9LOworfQorCitTdGF0dXMgUHJvdG9TdHJlYW1PYmplY3RTb3VyY2U6OlJlbmRlckludDMyKGNvbnN0IFByb3RvU3RyZWFtT2JqZWN0U291cmNlKiBvcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6VHlwZSYgdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UgZmllbGRfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0V3JpdGVyKiBvdykgeworICB1aW50MzIgdGFnID0gb3MtPnN0cmVhbV8tPlJlYWRUYWcoKTsKKyAgdWludDMyIGJ1ZmZlcjMyID0gMDsgIC8vIGRlZmF1bHQgdmFsdWUgb2YgSW50MzIgd3JhcHBlciB2YWx1ZQorICBpZiAodGFnICE9IDApIHsKKyAgICBvcy0+c3RyZWFtXy0+UmVhZFZhcmludDMyKCZidWZmZXIzMik7CisgICAgb3MtPnN0cmVhbV8tPlJlYWRUYWcoKTsKKyAgfQorICBvdy0+UmVuZGVySW50MzIoZmllbGRfbmFtZSwgYml0X2Nhc3Q8aW50MzI+KGJ1ZmZlcjMyKSk7CisgIHJldHVybiBTdGF0dXM6Ok9LOworfQorCitTdGF0dXMgUHJvdG9TdHJlYW1PYmplY3RTb3VyY2U6OlJlbmRlclVJbnQzMihjb25zdCBQcm90b1N0cmVhbU9iamVjdFNvdXJjZSogb3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlJiB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UgZmllbGRfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdFdyaXRlciogb3cpIHsKKyAgdWludDMyIHRhZyA9IG9zLT5zdHJlYW1fLT5SZWFkVGFnKCk7CisgIHVpbnQzMiBidWZmZXIzMiA9IDA7ICAvLyBkZWZhdWx0IHZhbHVlIG9mIFVJbnQzMiB3cmFwcGVyIHZhbHVlCisgIGlmICh0YWcgIT0gMCkgeworICAgIG9zLT5zdHJlYW1fLT5SZWFkVmFyaW50MzIoJmJ1ZmZlcjMyKTsKKyAgICBvcy0+c3RyZWFtXy0+UmVhZFRhZygpOworICB9CisgIG93LT5SZW5kZXJVaW50MzIoZmllbGRfbmFtZSwgYml0X2Nhc3Q8dWludDMyPihidWZmZXIzMikpOworICByZXR1cm4gU3RhdHVzOjpPSzsKK30KKworU3RhdHVzIFByb3RvU3RyZWFtT2JqZWN0U291cmNlOjpSZW5kZXJCb29sKGNvbnN0IFByb3RvU3RyZWFtT2JqZWN0U291cmNlKiBvcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlJiB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1BpZWNlIGZpZWxkX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0V3JpdGVyKiBvdykgeworICB1aW50MzIgdGFnID0gb3MtPnN0cmVhbV8tPlJlYWRUYWcoKTsKKyAgdWludDY0IGJ1ZmZlcjY0ID0gMDsgIC8vIHJlc3VsdHMgaW4gJ2ZhbHNlJyB2YWx1ZSBhcyBkZWZhdWx0LCB3aGljaCBpcyB0aGUKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRlZmF1bHQgdmFsdWUgb2YgQm9vbCB3cmFwcGVyCisgIGlmICh0YWcgIT0gMCkgeworICAgIG9zLT5zdHJlYW1fLT5SZWFkVmFyaW50NjQoJmJ1ZmZlcjY0KTsKKyAgICBvcy0+c3RyZWFtXy0+UmVhZFRhZygpOworICB9CisgIG93LT5SZW5kZXJCb29sKGZpZWxkX25hbWUsIGJ1ZmZlcjY0ICE9IDApOworICByZXR1cm4gU3RhdHVzOjpPSzsKK30KKworU3RhdHVzIFByb3RvU3RyZWFtT2JqZWN0U291cmNlOjpSZW5kZXJTdHJpbmcoY29uc3QgUHJvdG9TdHJlYW1PYmplY3RTb3VyY2UqIG9zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6VHlwZSYgdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1BpZWNlIGZpZWxkX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3RXcml0ZXIqIG93KSB7CisgIHVpbnQzMiB0YWcgPSBvcy0+c3RyZWFtXy0+UmVhZFRhZygpOworICB1aW50MzIgYnVmZmVyMzI7CisgIHN0cmluZyBzdHI7ICAvLyBkZWZhdWx0IHZhbHVlIG9mIGVtcHR5IGZvciBTdHJpbmcgd3JhcHBlcgorICBpZiAodGFnICE9IDApIHsKKyAgICBvcy0+c3RyZWFtXy0+UmVhZFZhcmludDMyKCZidWZmZXIzMik7ICAvLyBzdHJpbmcgc2l6ZS4KKyAgICBvcy0+c3RyZWFtXy0+UmVhZFN0cmluZygmc3RyLCBidWZmZXIzMik7CisgICAgb3MtPnN0cmVhbV8tPlJlYWRUYWcoKTsKKyAgfQorICBvdy0+UmVuZGVyU3RyaW5nKGZpZWxkX25hbWUsIHN0cik7CisgIHJldHVybiBTdGF0dXM6Ok9LOworfQorCitTdGF0dXMgUHJvdG9TdHJlYW1PYmplY3RTb3VyY2U6OlJlbmRlckJ5dGVzKGNvbnN0IFByb3RvU3RyZWFtT2JqZWN0U291cmNlKiBvcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6VHlwZSYgdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UgZmllbGRfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0V3JpdGVyKiBvdykgeworICB1aW50MzIgdGFnID0gb3MtPnN0cmVhbV8tPlJlYWRUYWcoKTsKKyAgdWludDMyIGJ1ZmZlcjMyOworICBzdHJpbmcgc3RyOworICBpZiAodGFnICE9IDApIHsKKyAgICBvcy0+c3RyZWFtXy0+UmVhZFZhcmludDMyKCZidWZmZXIzMik7CisgICAgb3MtPnN0cmVhbV8tPlJlYWRTdHJpbmcoJnN0ciwgYnVmZmVyMzIpOworICAgIG9zLT5zdHJlYW1fLT5SZWFkVGFnKCk7CisgIH0KKyAgb3ctPlJlbmRlckJ5dGVzKGZpZWxkX25hbWUsIHN0cik7CisgIHJldHVybiBTdGF0dXM6Ok9LOworfQorCitTdGF0dXMgUHJvdG9TdHJlYW1PYmplY3RTb3VyY2U6OlJlbmRlclN0cnVjdChjb25zdCBQcm90b1N0cmVhbU9iamVjdFNvdXJjZSogb3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlJiB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UgZmllbGRfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdFdyaXRlciogb3cpIHsKKyAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGQqIGZpZWxkID0gTlVMTDsKKyAgdWludDMyIHRhZyA9IG9zLT5zdHJlYW1fLT5SZWFkVGFnKCk7CisgIG93LT5TdGFydE9iamVjdChmaWVsZF9uYW1lKTsKKyAgd2hpbGUgKHRhZyAhPSAwKSB7CisgICAgZmllbGQgPSBvcy0+RmluZEFuZFZlcmlmeUZpZWxkKHR5cGUsIHRhZyk7CisgICAgLy8gZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCBoYXMgb25seSBvbmUgZmllbGQgdGhhdCBpcyBhIG1hcC4gSGVuY2Ugd2UgdXNlCisgICAgLy8gUmVuZGVyTWFwIHRvIHJlbmRlciB0aGF0IGZpZWxkLgorICAgIGlmIChvcy0+SXNNYXAoKmZpZWxkKSkgeworICAgICAgQVNTSUdOX09SX1JFVFVSTih0YWcsIG9zLT5SZW5kZXJNYXAoZmllbGQsIGZpZWxkX25hbWUsIHRhZywgb3cpKTsKKyAgICB9CisgIH0KKyAgb3ctPkVuZE9iamVjdCgpOworICByZXR1cm4gU3RhdHVzOjpPSzsKK30KKworU3RhdHVzIFByb3RvU3RyZWFtT2JqZWN0U291cmNlOjpSZW5kZXJTdHJ1Y3RWYWx1ZSgKKyAgICBjb25zdCBQcm90b1N0cmVhbU9iamVjdFNvdXJjZSogb3MsIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlR5cGUmIHR5cGUsCisgICAgU3RyaW5nUGllY2UgZmllbGRfbmFtZSwgT2JqZWN0V3JpdGVyKiBvdykgeworICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZCogZmllbGQgPSBOVUxMOworICBmb3IgKHVpbnQzMiB0YWcgPSBvcy0+c3RyZWFtXy0+UmVhZFRhZygpOyB0YWcgIT0gMDsKKyAgICAgICB0YWcgPSBvcy0+c3RyZWFtXy0+UmVhZFRhZygpKSB7CisgICAgZmllbGQgPSBvcy0+RmluZEFuZFZlcmlmeUZpZWxkKHR5cGUsIHRhZyk7CisgICAgaWYgKGZpZWxkID09IE5VTEwpIHsKKyAgICAgIFdpcmVGb3JtYXQ6OlNraXBGaWVsZChvcy0+c3RyZWFtXywgdGFnLCBOVUxMKTsKKyAgICAgIGNvbnRpbnVlOworICAgIH0KKyAgICBSRVRVUk5fSUZfRVJST1Iob3MtPlJlbmRlckZpZWxkKGZpZWxkLCBmaWVsZF9uYW1lLCBvdykpOworICB9CisgIHJldHVybiBTdGF0dXM6Ok9LOworfQorCisvLyBUT0RPKHNrYXJ2YWplKTogQXZvaWQgY29kZSBkdXBsaWNhdGlvbiBvZiBmb3IgbG9vcHMgYW5kIFNraXBGaWVsZCBsb2dpYy4KK1N0YXR1cyBQcm90b1N0cmVhbU9iamVjdFNvdXJjZTo6UmVuZGVyU3RydWN0TGlzdFZhbHVlKAorICAgIGNvbnN0IFByb3RvU3RyZWFtT2JqZWN0U291cmNlKiBvcywgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6VHlwZSYgdHlwZSwKKyAgICBTdHJpbmdQaWVjZSBmaWVsZF9uYW1lLCBPYmplY3RXcml0ZXIqIG93KSB7CisgIHVpbnQzMiB0YWcgPSBvcy0+c3RyZWFtXy0+UmVhZFRhZygpOworCisgIC8vIFJlbmRlciBlbXB0eSBsaXN0IHdoZW4gd2UgZmluZCBlbXB0eSBMaXN0VmFsdWUgbWVzc2FnZS4KKyAgaWYgKHRhZyA9PSAwKSB7CisgICAgb3ctPlN0YXJ0TGlzdChmaWVsZF9uYW1lKTsKKyAgICBvdy0+RW5kTGlzdCgpOworICAgIHJldHVybiBTdGF0dXM6Ok9LOworICB9CisKKyAgd2hpbGUgKHRhZyAhPSAwKSB7CisgICAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGQqIGZpZWxkID0gb3MtPkZpbmRBbmRWZXJpZnlGaWVsZCh0eXBlLCB0YWcpOworICAgIGlmIChmaWVsZCA9PSBOVUxMKSB7CisgICAgICBXaXJlRm9ybWF0OjpTa2lwRmllbGQob3MtPnN0cmVhbV8sIHRhZywgTlVMTCk7CisgICAgICB0YWcgPSBvcy0+c3RyZWFtXy0+UmVhZFRhZygpOworICAgICAgY29udGludWU7CisgICAgfQorICAgIEFTU0lHTl9PUl9SRVRVUk4odGFnLCBvcy0+UmVuZGVyTGlzdChmaWVsZCwgZmllbGRfbmFtZSwgdGFnLCBvdykpOworICB9CisgIHJldHVybiBTdGF0dXM6Ok9LOworfQorCitTdGF0dXMgUHJvdG9TdHJlYW1PYmplY3RTb3VyY2U6OlJlbmRlckFueShjb25zdCBQcm90b1N0cmVhbU9iamVjdFNvdXJjZSogb3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlJiB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UgZmllbGRfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdFdyaXRlciogb3cpIHsKKyAgLy8gQW4gQW55IGlzIG9mIHRoZSBmb3JtIHsgc3RyaW5nIHR5cGVfdXJsID0gMTsgYnl0ZXMgdmFsdWUgPSAyOyB9CisgIHVpbnQzMiB0YWc7CisgIHN0cmluZyB0eXBlX3VybDsKKyAgc3RyaW5nIHZhbHVlOworCisgIC8vIEZpcnN0IHJlYWQgb3V0IHRoZSB0eXBlX3VybCBhbmQgdmFsdWUgZnJvbSB0aGUgcHJvdG8gc3RyZWFtCisgIGZvciAodGFnID0gb3MtPnN0cmVhbV8tPlJlYWRUYWcoKTsgdGFnICE9IDA7IHRhZyA9IG9zLT5zdHJlYW1fLT5SZWFkVGFnKCkpIHsKKyAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZCogZmllbGQgPSBvcy0+RmluZEFuZFZlcmlmeUZpZWxkKHR5cGUsIHRhZyk7CisgICAgaWYgKGZpZWxkID09IE5VTEwpIHsKKyAgICAgIFdpcmVGb3JtYXQ6OlNraXBGaWVsZChvcy0+c3RyZWFtXywgdGFnLCBOVUxMKTsKKyAgICAgIGNvbnRpbnVlOworICAgIH0KKyAgICAvLyAndHlwZV91cmwnIGhhcyBmaWVsZCBudW1iZXIgb2YgMSBhbmQgJ3ZhbHVlJyBoYXMgZmllbGQgbnVtYmVyIDIKKyAgICAvLyAvL2dvb2dsZS9wcm90b2J1Zi9hbnkucHJvdG8KKyAgICBpZiAoZmllbGQtPm51bWJlcigpID09IDEpIHsKKyAgICAgIC8vIHJlYWQgdHlwZV91cmwKKyAgICAgIHVpbnQzMiB0eXBlX3VybF9zaXplOworICAgICAgb3MtPnN0cmVhbV8tPlJlYWRWYXJpbnQzMigmdHlwZV91cmxfc2l6ZSk7CisgICAgICBvcy0+c3RyZWFtXy0+UmVhZFN0cmluZygmdHlwZV91cmwsIHR5cGVfdXJsX3NpemUpOworICAgIH0gZWxzZSBpZiAoZmllbGQtPm51bWJlcigpID09IDIpIHsKKyAgICAgIC8vIHJlYWQgdmFsdWUKKyAgICAgIHVpbnQzMiB2YWx1ZV9zaXplOworICAgICAgb3MtPnN0cmVhbV8tPlJlYWRWYXJpbnQzMigmdmFsdWVfc2l6ZSk7CisgICAgICBvcy0+c3RyZWFtXy0+UmVhZFN0cmluZygmdmFsdWUsIHZhbHVlX3NpemUpOworICAgIH0KKyAgfQorCisgIC8vIElmIHRoZXJlIGlzIG5vIHZhbHVlLCB3ZSBkb24ndCBsb29rdXAgdGhlIHR5cGUsIHdlIGp1c3Qgb3V0cHV0IGl0IChpZgorICAvLyBwcmVzZW50KS4gSWYgYm90aCB0eXBlIGFuZCB2YWx1ZSBhcmUgZW1wdHkgd2Ugb3V0cHV0IGFuIGVtcHR5IG9iamVjdC4KKyAgaWYgKHZhbHVlLmVtcHR5KCkpIHsKKyAgICBvdy0+U3RhcnRPYmplY3QoZmllbGRfbmFtZSk7CisgICAgaWYgKCF0eXBlX3VybC5lbXB0eSgpKSB7CisgICAgICBvdy0+UmVuZGVyU3RyaW5nKCJAdHlwZSIsIHR5cGVfdXJsKTsKKyAgICB9CisgICAgb3ctPkVuZE9iamVjdCgpOworICAgIHJldHVybiB1dGlsOjpTdGF0dXM6Ok9LOworICB9CisKKyAgLy8gSWYgdGhlcmUgaXMgYSB2YWx1ZSBidXQgbm8gdHlwZSwgd2UgY2Fubm90IHJlbmRlciBpdCwgc28gcmVwb3J0IGFuIGVycm9yLgorICBpZiAodHlwZV91cmwuZW1wdHkoKSkgeworICAgIC8vIFRPRE8oc3Zlbik6IEFkZCBhbiBleHRlcm5hbCBtZXNzYWdlIG9uY2UgdGhvc2UgYXJlIHJlYWR5LgorICAgIHJldHVybiB1dGlsOjpTdGF0dXModXRpbDo6ZXJyb3I6OklOVEVSTkFMLAorICAgICAgICAgICAgICAgICAgICAgICAgIkludmFsaWQgQW55LCB0aGUgdHlwZV91cmwgaXMgbWlzc2luZy4iKTsKKyAgfQorCisgIHV0aWw6OlN0YXR1c09yPGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlR5cGUqPiByZXNvbHZlZF90eXBlID0KKyAgICAgIG9zLT50eXBlaW5mb18tPlJlc29sdmVUeXBlVXJsKHR5cGVfdXJsKTsKKworICBpZiAoIXJlc29sdmVkX3R5cGUub2soKSkgeworICAgIC8vIENvbnZlcnQgaW50byBhbiBpbnRlcm5hbCBlcnJvciwgc2luY2UgdGhpcyBtZWFucyB0aGUgYmFja2VuZCBnYXZlIHVzCisgICAgLy8gYW4gaW52YWxpZCByZXNwb25zZSAobWlzc2luZyBvciBpbnZhbGlkIHR5cGUgaW5mb3JtYXRpb24pLgorICAgIHJldHVybiB1dGlsOjpTdGF0dXModXRpbDo6ZXJyb3I6OklOVEVSTkFMLAorICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZWRfdHlwZS5zdGF0dXMoKS5lcnJvcl9tZXNzYWdlKCkpOworICB9CisgIC8vIG5lc3RlZF90eXBlIGNhbm5vdCBiZSBudWxsIGF0IHRoaXMgdGltZS4KKyAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6VHlwZSogbmVzdGVkX3R5cGUgPSByZXNvbHZlZF90eXBlLlZhbHVlT3JEaWUoKTsKKworICBnb29nbGU6OnByb3RvYnVmOjppbzo6QXJyYXlJbnB1dFN0cmVhbSB6ZXJvX2NvcHlfc3RyZWFtKHZhbHVlLmRhdGEoKSwgdmFsdWUuc2l6ZSgpKTsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0gaW5fc3RyZWFtKCZ6ZXJvX2NvcHlfc3RyZWFtKTsKKyAgLy8gV2Uga25vdyB0aGUgdHlwZSBzbyB3ZSBjYW4gcmVuZGVyIGl0LiBSZWN1cnNpdmVseSBwYXJzZSB0aGUgbmVzdGVkIHN0cmVhbQorICAvLyB1c2luZyBhIG5lc3RlZCBQcm90b1N0cmVhbU9iamVjdFNvdXJjZSB1c2luZyBvdXIgbmVzdGVkIHR5cGUgaW5mb3JtYXRpb24uCisgIFByb3RvU3RyZWFtT2JqZWN0U291cmNlIG5lc3RlZF9vcygmaW5fc3RyZWFtLCBvcy0+dHlwZWluZm9fLCAqbmVzdGVkX3R5cGUpOworCisgIC8vIFdlIG1hbnVhbGx5IGNhbGwgc3RhcnQgYW5kIGVuZCBvYmplY3QgaGVyZSBzbyB3ZSBjYW4gaW5qZWN0IHRoZSBAdHlwZS4KKyAgb3ctPlN0YXJ0T2JqZWN0KGZpZWxkX25hbWUpOworICBvdy0+UmVuZGVyU3RyaW5nKCJAdHlwZSIsIHR5cGVfdXJsKTsKKyAgdXRpbDo6U3RhdHVzIHJlc3VsdCA9CisgICAgICBuZXN0ZWRfb3MuV3JpdGVNZXNzYWdlKG5lc3RlZF9vcy50eXBlXywgInZhbHVlIiwgMCwgZmFsc2UsIG93KTsKKyAgb3ctPkVuZE9iamVjdCgpOworICByZXR1cm4gcmVzdWx0OworfQorCitTdGF0dXMgUHJvdG9TdHJlYW1PYmplY3RTb3VyY2U6OlJlbmRlckZpZWxkTWFzaygKKyAgICBjb25zdCBQcm90b1N0cmVhbU9iamVjdFNvdXJjZSogb3MsIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlR5cGUmIHR5cGUsCisgICAgU3RyaW5nUGllY2UgZmllbGRfbmFtZSwgT2JqZWN0V3JpdGVyKiBvdykgeworICBzdHJpbmcgY29tYmluZWQ7CisgIHVpbnQzMiBidWZmZXIzMjsKKyAgdWludDMyIHBhdGhzX2ZpZWxkX3RhZyA9IDA7CisgIGZvciAodWludDMyIHRhZyA9IG9zLT5zdHJlYW1fLT5SZWFkVGFnKCk7IHRhZyAhPSAwOworICAgICAgIHRhZyA9IG9zLT5zdHJlYW1fLT5SZWFkVGFnKCkpIHsKKyAgICBpZiAocGF0aHNfZmllbGRfdGFnID09IDApIHsKKyAgICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkKiBmaWVsZCA9IG9zLT5GaW5kQW5kVmVyaWZ5RmllbGQodHlwZSwgdGFnKTsKKyAgICAgIGlmIChmaWVsZCAhPSBOVUxMICYmIGZpZWxkLT5udW1iZXIoKSA9PSAxICYmCisgICAgICAgICAgZmllbGQtPm5hbWUoKSA9PSAicGF0aHMiKSB7CisgICAgICAgIHBhdGhzX2ZpZWxkX3RhZyA9IHRhZzsKKyAgICAgIH0KKyAgICB9CisgICAgaWYgKHBhdGhzX2ZpZWxkX3RhZyAhPSB0YWcpIHsKKyAgICAgIHJldHVybiB1dGlsOjpTdGF0dXModXRpbDo6ZXJyb3I6OklOVEVSTkFMLAorICAgICAgICAgICAgICAgICAgICAgICAgICAiSW52YWxpZCBGaWVsZE1hc2ssIHVuZXhwZWN0ZWQgZmllbGQuIik7CisgICAgfQorICAgIHN0cmluZyBzdHI7CisgICAgb3MtPnN0cmVhbV8tPlJlYWRWYXJpbnQzMigmYnVmZmVyMzIpOyAgLy8gc3RyaW5nIHNpemUuCisgICAgb3MtPnN0cmVhbV8tPlJlYWRTdHJpbmcoJnN0ciwgYnVmZmVyMzIpOworICAgIGlmICghY29tYmluZWQuZW1wdHkoKSkgeworICAgICAgY29tYmluZWQuYXBwZW5kKCIsIik7CisgICAgfQorICAgIGNvbWJpbmVkLmFwcGVuZChDb252ZXJ0RmllbGRNYXNrUGF0aChzdHIsICZUb0NhbWVsQ2FzZSkpOworICB9CisgIG93LT5SZW5kZXJTdHJpbmcoZmllbGRfbmFtZSwgY29tYmluZWQpOworICByZXR1cm4gU3RhdHVzOjpPSzsKK30KKworCitoYXNoX21hcDxzdHJpbmcsIFByb3RvU3RyZWFtT2JqZWN0U291cmNlOjpUeXBlUmVuZGVyZXI+KgorICAgIFByb3RvU3RyZWFtT2JqZWN0U291cmNlOjpyZW5kZXJlcnNfID0gTlVMTDsKK0dPT0dMRV9QUk9UT0JVRl9ERUNMQVJFX09OQ0Uoc291cmNlX3JlbmRlcmVyc19pbml0Xyk7CisKK3ZvaWQgUHJvdG9TdHJlYW1PYmplY3RTb3VyY2U6OkluaXRSZW5kZXJlck1hcCgpIHsKKyAgcmVuZGVyZXJzXyA9IG5ldyBoYXNoX21hcDxzdHJpbmcsIFByb3RvU3RyZWFtT2JqZWN0U291cmNlOjpUeXBlUmVuZGVyZXI+KCk7CisgICgqcmVuZGVyZXJzXylbImdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAiXSA9CisgICAgICAmUHJvdG9TdHJlYW1PYmplY3RTb3VyY2U6OlJlbmRlclRpbWVzdGFtcDsKKyAgKCpyZW5kZXJlcnNfKVsiZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uIl0gPQorICAgICAgJlByb3RvU3RyZWFtT2JqZWN0U291cmNlOjpSZW5kZXJEdXJhdGlvbjsKKyAgKCpyZW5kZXJlcnNfKVsiZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlIl0gPQorICAgICAgJlByb3RvU3RyZWFtT2JqZWN0U291cmNlOjpSZW5kZXJEb3VibGU7CisgICgqcmVuZGVyZXJzXylbImdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlIl0gPQorICAgICAgJlByb3RvU3RyZWFtT2JqZWN0U291cmNlOjpSZW5kZXJGbG9hdDsKKyAgKCpyZW5kZXJlcnNfKVsiZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUiXSA9CisgICAgICAmUHJvdG9TdHJlYW1PYmplY3RTb3VyY2U6OlJlbmRlckludDY0OworICAoKnJlbmRlcmVyc18pWyJnb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUiXSA9CisgICAgICAmUHJvdG9TdHJlYW1PYmplY3RTb3VyY2U6OlJlbmRlclVJbnQ2NDsKKyAgKCpyZW5kZXJlcnNfKVsiZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUiXSA9CisgICAgICAmUHJvdG9TdHJlYW1PYmplY3RTb3VyY2U6OlJlbmRlckludDMyOworICAoKnJlbmRlcmVyc18pWyJnb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUiXSA9CisgICAgICAmUHJvdG9TdHJlYW1PYmplY3RTb3VyY2U6OlJlbmRlclVJbnQzMjsKKyAgKCpyZW5kZXJlcnNfKVsiZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSJdID0KKyAgICAgICZQcm90b1N0cmVhbU9iamVjdFNvdXJjZTo6UmVuZGVyQm9vbDsKKyAgKCpyZW5kZXJlcnNfKVsiZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIl0gPQorICAgICAgJlByb3RvU3RyZWFtT2JqZWN0U291cmNlOjpSZW5kZXJTdHJpbmc7CisgICgqcmVuZGVyZXJzXylbImdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIl0gPQorICAgICAgJlByb3RvU3RyZWFtT2JqZWN0U291cmNlOjpSZW5kZXJCeXRlczsKKyAgKCpyZW5kZXJlcnNfKVsiZ29vZ2xlLnByb3RvYnVmLkFueSJdID0gJlByb3RvU3RyZWFtT2JqZWN0U291cmNlOjpSZW5kZXJBbnk7CisgICgqcmVuZGVyZXJzXylbImdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QiXSA9CisgICAgICAmUHJvdG9TdHJlYW1PYmplY3RTb3VyY2U6OlJlbmRlclN0cnVjdDsKKyAgKCpyZW5kZXJlcnNfKVsiZ29vZ2xlLnByb3RvYnVmLlZhbHVlIl0gPQorICAgICAgJlByb3RvU3RyZWFtT2JqZWN0U291cmNlOjpSZW5kZXJTdHJ1Y3RWYWx1ZTsKKyAgKCpyZW5kZXJlcnNfKVsiZ29vZ2xlLnByb3RvYnVmLkxpc3RWYWx1ZSJdID0KKyAgICAgICZQcm90b1N0cmVhbU9iamVjdFNvdXJjZTo6UmVuZGVyU3RydWN0TGlzdFZhbHVlOworICAoKnJlbmRlcmVyc18pWyJnb29nbGUucHJvdG9idWYuRmllbGRNYXNrIl0gPQorICAgICAgJlByb3RvU3RyZWFtT2JqZWN0U291cmNlOjpSZW5kZXJGaWVsZE1hc2s7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6Ok9uU2h1dGRvd24oJkRlbGV0ZVJlbmRlcmVyTWFwKTsKK30KKwordm9pZCBQcm90b1N0cmVhbU9iamVjdFNvdXJjZTo6RGVsZXRlUmVuZGVyZXJNYXAoKSB7CisgIGRlbGV0ZSBQcm90b1N0cmVhbU9iamVjdFNvdXJjZTo6cmVuZGVyZXJzXzsKKyAgcmVuZGVyZXJzXyA9IE5VTEw7Cit9CisKKy8vIHN0YXRpYworUHJvdG9TdHJlYW1PYmplY3RTb3VyY2U6OlR5cGVSZW5kZXJlcioKK1Byb3RvU3RyZWFtT2JqZWN0U291cmNlOjpGaW5kVHlwZVJlbmRlcmVyKGNvbnN0IHN0cmluZyYgdHlwZV91cmwpIHsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpHb29nbGVPbmNlSW5pdCgmc291cmNlX3JlbmRlcmVyc19pbml0XywgJkluaXRSZW5kZXJlck1hcCk7CisgIHJldHVybiBGaW5kT3JOdWxsKCpyZW5kZXJlcnNfLCB0eXBlX3VybCk7Cit9CisKK1N0YXR1cyBQcm90b1N0cmVhbU9iamVjdFNvdXJjZTo6UmVuZGVyRmllbGQoCisgICAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGQqIGZpZWxkLCBTdHJpbmdQaWVjZSBmaWVsZF9uYW1lLAorICAgIE9iamVjdFdyaXRlciogb3cpIGNvbnN0IHsKKyAgLy8gU2hvcnQtY2lyY3VpdCBtZXNzYWdlIHR5cGVzIGFzIGl0IHRlbmRzIHRvIGNhbGwgV3JpdGVNZXNzYWdlIHJlY3Vyc2l2ZWx5CisgIC8vIGFuZCBlbmRzIHVwIHVzaW5nIGEgbG90IG9mIHN0YWNrIHNwYWNlLiBLZWVwIHRoZSBzdGFjayB1c2FnZSBvZiB0aGlzCisgIC8vIG1lc3NhZ2Ugc21hbGwgaW4gb3JkZXIgdG8gcHJlc2VydmUgc3RhY2sgc3BhY2UgYW5kIG5vdCBjcmFzaC4KKyAgaWYgKGZpZWxkLT5raW5kKCkgPT0gZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGRfS2luZF9UWVBFX01FU1NBR0UpIHsKKyAgICB1aW50MzIgYnVmZmVyMzI7CisgICAgc3RyZWFtXy0+UmVhZFZhcmludDMyKCZidWZmZXIzMik7ICAvLyBtZXNzYWdlIGxlbmd0aAorICAgIGludCBvbGRfbGltaXQgPSBzdHJlYW1fLT5QdXNoTGltaXQoYnVmZmVyMzIpOworICAgIC8vIEdldCB0aGUgbmVzdGVkIG1lc3NhZ2UgdHlwZSBmb3IgdGhpcyBmaWVsZC4KKyAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlKiB0eXBlID0KKyAgICAgICAgdHlwZWluZm9fLT5HZXRUeXBlQnlUeXBlVXJsKGZpZWxkLT50eXBlX3VybCgpKTsKKyAgICBpZiAodHlwZSA9PSBOVUxMKSB7CisgICAgICByZXR1cm4gU3RhdHVzKHV0aWw6OmVycm9yOjpJTlRFUk5BTCwKKyAgICAgICAgICAgICAgICAgICAgU3RyQ2F0KCJJbnZhbGlkIGNvbmZpZ3VyYXRpb24uIENvdWxkIG5vdCBmaW5kIHRoZSB0eXBlOiAiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGQtPnR5cGVfdXJsKCkpKTsKKyAgICB9CisKKyAgICAvLyBTaG9ydC1jaXJjdWl0IGFueSBzcGVjaWFsIHR5cGUgcmVuZGVyaW5nIHRvIHNhdmUgY2FsbC1zdGFjayBzcGFjZS4KKyAgICBjb25zdCBUeXBlUmVuZGVyZXIqIHR5cGVfcmVuZGVyZXIgPSBGaW5kVHlwZVJlbmRlcmVyKHR5cGUtPm5hbWUoKSk7CisKKyAgICBib29sIHVzZV90eXBlX3JlbmRlcmVyID0gdHlwZV9yZW5kZXJlciAhPSBOVUxMOworCisgICAgaWYgKHVzZV90eXBlX3JlbmRlcmVyKSB7CisgICAgICBSRVRVUk5fSUZfRVJST1IoKCp0eXBlX3JlbmRlcmVyKSh0aGlzLCAqdHlwZSwgZmllbGRfbmFtZSwgb3cpKTsKKyAgICB9IGVsc2UgeworICAgICAgUkVUVVJOX0lGX0VSUk9SKFdyaXRlTWVzc2FnZSgqdHlwZSwgZmllbGRfbmFtZSwgMCwgdHJ1ZSwgb3cpKTsKKyAgICB9CisgICAgaWYgKCFzdHJlYW1fLT5Db25zdW1lZEVudGlyZU1lc3NhZ2UoKSkgeworICAgICAgcmV0dXJuIFN0YXR1cyh1dGlsOjplcnJvcjo6SU5WQUxJRF9BUkdVTUVOVCwKKyAgICAgICAgICAgICAgICAgICAgIk5lc3RlZCBwcm90b2NvbCBtZXNzYWdlIG5vdCBwYXJzZWQgaW4gaXRzIGVudGlyZXR5LiIpOworICAgIH0KKyAgICBzdHJlYW1fLT5Qb3BMaW1pdChvbGRfbGltaXQpOworICB9IGVsc2UgeworICAgIC8vIFJlbmRlciBhbGwgb3RoZXIgbm9uLW1lc3NhZ2UgdHlwZXMuCisgICAgcmV0dXJuIFJlbmRlck5vbk1lc3NhZ2VGaWVsZChmaWVsZCwgZmllbGRfbmFtZSwgb3cpOworICB9CisgIHJldHVybiBTdGF0dXM6Ok9LOworfQorCitTdGF0dXMgUHJvdG9TdHJlYW1PYmplY3RTb3VyY2U6OlJlbmRlck5vbk1lc3NhZ2VGaWVsZCgKKyAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZCogZmllbGQsIFN0cmluZ1BpZWNlIGZpZWxkX25hbWUsCisgICAgT2JqZWN0V3JpdGVyKiBvdykgY29uc3QgeworICAvLyBUZW1wb3JhcnkgYnVmZmVycyBvZiBkaWZmZXJlbnQgdHlwZXMuCisgIHVpbnQzMiBidWZmZXIzMjsKKyAgdWludDY0IGJ1ZmZlcjY0OworICBzdHJpbmcgc3RyYnVmZmVyOworICBzd2l0Y2ggKGZpZWxkLT5raW5kKCkpIHsKKyAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0tpbmRfVFlQRV9CT09MOiB7CisgICAgICBzdHJlYW1fLT5SZWFkVmFyaW50NjQoJmJ1ZmZlcjY0KTsKKyAgICAgIG93LT5SZW5kZXJCb29sKGZpZWxkX25hbWUsIGJ1ZmZlcjY0ICE9IDApOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGRfS2luZF9UWVBFX0lOVDMyOiB7CisgICAgICBzdHJlYW1fLT5SZWFkVmFyaW50MzIoJmJ1ZmZlcjMyKTsKKyAgICAgIG93LT5SZW5kZXJJbnQzMihmaWVsZF9uYW1lLCBiaXRfY2FzdDxpbnQzMj4oYnVmZmVyMzIpKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0tpbmRfVFlQRV9JTlQ2NDogeworICAgICAgc3RyZWFtXy0+UmVhZFZhcmludDY0KCZidWZmZXI2NCk7CisgICAgICBvdy0+UmVuZGVySW50NjQoZmllbGRfbmFtZSwgYml0X2Nhc3Q8aW50NjQ+KGJ1ZmZlcjY0KSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBnb29nbGU6OnByb3RvYnVmOjpGaWVsZF9LaW5kX1RZUEVfVUlOVDMyOiB7CisgICAgICBzdHJlYW1fLT5SZWFkVmFyaW50MzIoJmJ1ZmZlcjMyKTsKKyAgICAgIG93LT5SZW5kZXJVaW50MzIoZmllbGRfbmFtZSwgYml0X2Nhc3Q8dWludDMyPihidWZmZXIzMikpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGRfS2luZF9UWVBFX1VJTlQ2NDogeworICAgICAgc3RyZWFtXy0+UmVhZFZhcmludDY0KCZidWZmZXI2NCk7CisgICAgICBvdy0+UmVuZGVyVWludDY0KGZpZWxkX25hbWUsIGJpdF9jYXN0PHVpbnQ2ND4oYnVmZmVyNjQpKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0tpbmRfVFlQRV9TSU5UMzI6IHsKKyAgICAgIHN0cmVhbV8tPlJlYWRWYXJpbnQzMigmYnVmZmVyMzIpOworICAgICAgb3ctPlJlbmRlckludDMyKGZpZWxkX25hbWUsIFdpcmVGb3JtYXRMaXRlOjpaaWdaYWdEZWNvZGUzMihidWZmZXIzMikpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGRfS2luZF9UWVBFX1NJTlQ2NDogeworICAgICAgc3RyZWFtXy0+UmVhZFZhcmludDY0KCZidWZmZXI2NCk7CisgICAgICBvdy0+UmVuZGVySW50NjQoZmllbGRfbmFtZSwgV2lyZUZvcm1hdExpdGU6OlppZ1phZ0RlY29kZTY0KGJ1ZmZlcjY0KSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBnb29nbGU6OnByb3RvYnVmOjpGaWVsZF9LaW5kX1RZUEVfU0ZJWEVEMzI6IHsKKyAgICAgIHN0cmVhbV8tPlJlYWRMaXR0bGVFbmRpYW4zMigmYnVmZmVyMzIpOworICAgICAgb3ctPlJlbmRlckludDMyKGZpZWxkX25hbWUsIGJpdF9jYXN0PGludDMyPihidWZmZXIzMikpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGRfS2luZF9UWVBFX1NGSVhFRDY0OiB7CisgICAgICBzdHJlYW1fLT5SZWFkTGl0dGxlRW5kaWFuNjQoJmJ1ZmZlcjY0KTsKKyAgICAgIG93LT5SZW5kZXJJbnQ2NChmaWVsZF9uYW1lLCBiaXRfY2FzdDxpbnQ2ND4oYnVmZmVyNjQpKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0tpbmRfVFlQRV9GSVhFRDMyOiB7CisgICAgICBzdHJlYW1fLT5SZWFkTGl0dGxlRW5kaWFuMzIoJmJ1ZmZlcjMyKTsKKyAgICAgIG93LT5SZW5kZXJVaW50MzIoZmllbGRfbmFtZSwgYml0X2Nhc3Q8dWludDMyPihidWZmZXIzMikpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGRfS2luZF9UWVBFX0ZJWEVENjQ6IHsKKyAgICAgIHN0cmVhbV8tPlJlYWRMaXR0bGVFbmRpYW42NCgmYnVmZmVyNjQpOworICAgICAgb3ctPlJlbmRlclVpbnQ2NChmaWVsZF9uYW1lLCBiaXRfY2FzdDx1aW50NjQ+KGJ1ZmZlcjY0KSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBnb29nbGU6OnByb3RvYnVmOjpGaWVsZF9LaW5kX1RZUEVfRkxPQVQ6IHsKKyAgICAgIHN0cmVhbV8tPlJlYWRMaXR0bGVFbmRpYW4zMigmYnVmZmVyMzIpOworICAgICAgb3ctPlJlbmRlckZsb2F0KGZpZWxkX25hbWUsIGJpdF9jYXN0PGZsb2F0PihidWZmZXIzMikpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGRfS2luZF9UWVBFX0RPVUJMRTogeworICAgICAgc3RyZWFtXy0+UmVhZExpdHRsZUVuZGlhbjY0KCZidWZmZXI2NCk7CisgICAgICBvdy0+UmVuZGVyRG91YmxlKGZpZWxkX25hbWUsIGJpdF9jYXN0PGRvdWJsZT4oYnVmZmVyNjQpKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0tpbmRfVFlQRV9FTlVNOiB7CisgICAgICBzdHJlYW1fLT5SZWFkVmFyaW50MzIoJmJ1ZmZlcjMyKTsKKworICAgICAgLy8gSWYgdGhlIGZpZWxkIHJlcHJlc2VudHMgYW4gZXhwbGljaXQgTlVMTCB2YWx1ZSwgcmVuZGVyIG51bGwuCisgICAgICBpZiAoZmllbGQtPnR5cGVfdXJsKCkgPT0ga1N0cnVjdE51bGxWYWx1ZVR5cGVVcmwpIHsKKyAgICAgICAgb3ctPlJlbmRlck51bGwoZmllbGRfbmFtZSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBHZXQgdGhlIG5lc3RlZCBlbnVtIHR5cGUgZm9yIHRoaXMgZmllbGQuCisgICAgICAvLyBUT0RPKHNrYXJ2YWplKTogQXZvaWQgc3RyaW5nIG1hbmlwdWxhdGlvbi4gRmluZCB3YXlzIHRvIHNwZWVkIHRoaXMKKyAgICAgIC8vIHVwLgorICAgICAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RW51bSogZW4gPQorICAgICAgICAgIHR5cGVpbmZvXy0+R2V0RW51bUJ5VHlwZVVybChmaWVsZC0+dHlwZV91cmwoKSk7CisgICAgICAvLyBMb29rdXAgdGhlIG5hbWUgb2YgdGhlIGVudW0sIGFuZCByZW5kZXIgdGhhdC4gU2tpcHMgdW5rbm93biBlbnVtcy4KKyAgICAgIGlmIChlbiAhPSBOVUxMKSB7CisgICAgICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZSogZW51bV92YWx1ZSA9CisgICAgICAgICAgICBGaW5kRW51bVZhbHVlQnlOdW1iZXIoKmVuLCBidWZmZXIzMik7CisgICAgICAgIGlmIChlbnVtX3ZhbHVlICE9IE5VTEwpIHsKKyAgICAgICAgICBvdy0+UmVuZGVyU3RyaW5nKGZpZWxkX25hbWUsIGVudW1fdmFsdWUtPm5hbWUoKSk7CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSB7CisgICAgICAgIEdPT0dMRV9MT0coSU5GTykgPDwgIlVua25vd24gZW51bSBza2lwcGVkOiAiIDw8IGZpZWxkLT50eXBlX3VybCgpOworICAgICAgfQorICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGRfS2luZF9UWVBFX1NUUklORzogeworICAgICAgc3RyZWFtXy0+UmVhZFZhcmludDMyKCZidWZmZXIzMik7ICAvLyBzdHJpbmcgc2l6ZS4KKyAgICAgIHN0cmVhbV8tPlJlYWRTdHJpbmcoJnN0cmJ1ZmZlciwgYnVmZmVyMzIpOworICAgICAgb3ctPlJlbmRlclN0cmluZyhmaWVsZF9uYW1lLCBzdHJidWZmZXIpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGRfS2luZF9UWVBFX0JZVEVTOiB7CisgICAgICBzdHJlYW1fLT5SZWFkVmFyaW50MzIoJmJ1ZmZlcjMyKTsgIC8vIGJ5dGVzIHNpemUuCisgICAgICBzdHJlYW1fLT5SZWFkU3RyaW5nKCZzdHJidWZmZXIsIGJ1ZmZlcjMyKTsKKyAgICAgIG93LT5SZW5kZXJCeXRlcyhmaWVsZF9uYW1lLCBzdHJidWZmZXIpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGRlZmF1bHQ6CisgICAgICBicmVhazsKKyAgfQorICByZXR1cm4gU3RhdHVzOjpPSzsKK30KKworLy8gVE9ETyhza2FydmFqZSk6IEZpeCB0aGlzIHRvIGF2b2lkIGNvZGUgZHVwbGljYXRpb24uCitjb25zdCBzdHJpbmcgUHJvdG9TdHJlYW1PYmplY3RTb3VyY2U6OlJlYWRGaWVsZFZhbHVlQXNTdHJpbmcoCisgICAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGQmIGZpZWxkKSBjb25zdCB7CisgIHN0cmluZyByZXN1bHQ7CisgIHN3aXRjaCAoZmllbGQua2luZCgpKSB7CisgICAgY2FzZSBnb29nbGU6OnByb3RvYnVmOjpGaWVsZF9LaW5kX1RZUEVfQk9PTDogeworICAgICAgdWludDY0IGJ1ZmZlcjY0OworICAgICAgc3RyZWFtXy0+UmVhZFZhcmludDY0KCZidWZmZXI2NCk7CisgICAgICByZXN1bHQgPSBidWZmZXI2NCAhPSAwID8gInRydWUiIDogImZhbHNlIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0tpbmRfVFlQRV9JTlQzMjogeworICAgICAgdWludDMyIGJ1ZmZlcjMyOworICAgICAgc3RyZWFtXy0+UmVhZFZhcmludDMyKCZidWZmZXIzMik7CisgICAgICByZXN1bHQgPSBTaW1wbGVJdG9hKGJpdF9jYXN0PGludDMyPihidWZmZXIzMikpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGRfS2luZF9UWVBFX0lOVDY0OiB7CisgICAgICB1aW50NjQgYnVmZmVyNjQ7CisgICAgICBzdHJlYW1fLT5SZWFkVmFyaW50NjQoJmJ1ZmZlcjY0KTsKKyAgICAgIHJlc3VsdCA9IFNpbXBsZUl0b2EoYml0X2Nhc3Q8aW50NjQ+KGJ1ZmZlcjY0KSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBnb29nbGU6OnByb3RvYnVmOjpGaWVsZF9LaW5kX1RZUEVfVUlOVDMyOiB7CisgICAgICB1aW50MzIgYnVmZmVyMzI7CisgICAgICBzdHJlYW1fLT5SZWFkVmFyaW50MzIoJmJ1ZmZlcjMyKTsKKyAgICAgIHJlc3VsdCA9IFNpbXBsZUl0b2EoYml0X2Nhc3Q8dWludDMyPihidWZmZXIzMikpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGRfS2luZF9UWVBFX1VJTlQ2NDogeworICAgICAgdWludDY0IGJ1ZmZlcjY0OworICAgICAgc3RyZWFtXy0+UmVhZFZhcmludDY0KCZidWZmZXI2NCk7CisgICAgICByZXN1bHQgPSBTaW1wbGVJdG9hKGJpdF9jYXN0PHVpbnQ2ND4oYnVmZmVyNjQpKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0tpbmRfVFlQRV9TSU5UMzI6IHsKKyAgICAgIHVpbnQzMiBidWZmZXIzMjsKKyAgICAgIHN0cmVhbV8tPlJlYWRWYXJpbnQzMigmYnVmZmVyMzIpOworICAgICAgcmVzdWx0ID0gU2ltcGxlSXRvYShXaXJlRm9ybWF0TGl0ZTo6WmlnWmFnRGVjb2RlMzIoYnVmZmVyMzIpKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0tpbmRfVFlQRV9TSU5UNjQ6IHsKKyAgICAgIHVpbnQ2NCBidWZmZXI2NDsKKyAgICAgIHN0cmVhbV8tPlJlYWRWYXJpbnQ2NCgmYnVmZmVyNjQpOworICAgICAgcmVzdWx0ID0gU2ltcGxlSXRvYShXaXJlRm9ybWF0TGl0ZTo6WmlnWmFnRGVjb2RlNjQoYnVmZmVyNjQpKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0tpbmRfVFlQRV9TRklYRUQzMjogeworICAgICAgdWludDMyIGJ1ZmZlcjMyOworICAgICAgc3RyZWFtXy0+UmVhZExpdHRsZUVuZGlhbjMyKCZidWZmZXIzMik7CisgICAgICByZXN1bHQgPSBTaW1wbGVJdG9hKGJpdF9jYXN0PGludDMyPihidWZmZXIzMikpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGRfS2luZF9UWVBFX1NGSVhFRDY0OiB7CisgICAgICB1aW50NjQgYnVmZmVyNjQ7CisgICAgICBzdHJlYW1fLT5SZWFkTGl0dGxlRW5kaWFuNjQoJmJ1ZmZlcjY0KTsKKyAgICAgIHJlc3VsdCA9IFNpbXBsZUl0b2EoYml0X2Nhc3Q8aW50NjQ+KGJ1ZmZlcjY0KSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBnb29nbGU6OnByb3RvYnVmOjpGaWVsZF9LaW5kX1RZUEVfRklYRUQzMjogeworICAgICAgdWludDMyIGJ1ZmZlcjMyOworICAgICAgc3RyZWFtXy0+UmVhZExpdHRsZUVuZGlhbjMyKCZidWZmZXIzMik7CisgICAgICByZXN1bHQgPSBTaW1wbGVJdG9hKGJpdF9jYXN0PHVpbnQzMj4oYnVmZmVyMzIpKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0tpbmRfVFlQRV9GSVhFRDY0OiB7CisgICAgICB1aW50NjQgYnVmZmVyNjQ7CisgICAgICBzdHJlYW1fLT5SZWFkTGl0dGxlRW5kaWFuNjQoJmJ1ZmZlcjY0KTsKKyAgICAgIHJlc3VsdCA9IFNpbXBsZUl0b2EoYml0X2Nhc3Q8dWludDY0PihidWZmZXI2NCkpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGRfS2luZF9UWVBFX0ZMT0FUOiB7CisgICAgICB1aW50MzIgYnVmZmVyMzI7CisgICAgICBzdHJlYW1fLT5SZWFkTGl0dGxlRW5kaWFuMzIoJmJ1ZmZlcjMyKTsKKyAgICAgIHJlc3VsdCA9IFNpbXBsZUZ0b2EoYml0X2Nhc3Q8ZmxvYXQ+KGJ1ZmZlcjMyKSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBnb29nbGU6OnByb3RvYnVmOjpGaWVsZF9LaW5kX1RZUEVfRE9VQkxFOiB7CisgICAgICB1aW50NjQgYnVmZmVyNjQ7CisgICAgICBzdHJlYW1fLT5SZWFkTGl0dGxlRW5kaWFuNjQoJmJ1ZmZlcjY0KTsKKyAgICAgIHJlc3VsdCA9IFNpbXBsZUR0b2EoYml0X2Nhc3Q8ZG91YmxlPihidWZmZXI2NCkpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGRfS2luZF9UWVBFX0VOVU06IHsKKyAgICAgIHVpbnQzMiBidWZmZXIzMjsKKyAgICAgIHN0cmVhbV8tPlJlYWRWYXJpbnQzMigmYnVmZmVyMzIpOworICAgICAgLy8gR2V0IHRoZSBuZXN0ZWQgZW51bSB0eXBlIGZvciB0aGlzIGZpZWxkLgorICAgICAgLy8gVE9ETyhza2FydmFqZSk6IEF2b2lkIHN0cmluZyBtYW5pcHVsYXRpb24uIEZpbmQgd2F5cyB0byBzcGVlZCB0aGlzCisgICAgICAvLyB1cC4KKyAgICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkVudW0qIGVuID0KKyAgICAgICAgICB0eXBlaW5mb18tPkdldEVudW1CeVR5cGVVcmwoZmllbGQudHlwZV91cmwoKSk7CisgICAgICAvLyBMb29rdXAgdGhlIG5hbWUgb2YgdGhlIGVudW0sIGFuZCByZW5kZXIgdGhhdC4gU2tpcHMgdW5rbm93biBlbnVtcy4KKyAgICAgIGlmIChlbiAhPSBOVUxMKSB7CisgICAgICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZSogZW51bV92YWx1ZSA9CisgICAgICAgICAgICBGaW5kRW51bVZhbHVlQnlOdW1iZXIoKmVuLCBidWZmZXIzMik7CisgICAgICAgIGlmIChlbnVtX3ZhbHVlICE9IE5VTEwpIHsKKyAgICAgICAgICByZXN1bHQgPSBlbnVtX3ZhbHVlLT5uYW1lKCk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0tpbmRfVFlQRV9TVFJJTkc6IHsKKyAgICAgIHVpbnQzMiBidWZmZXIzMjsKKyAgICAgIHN0cmVhbV8tPlJlYWRWYXJpbnQzMigmYnVmZmVyMzIpOyAgLy8gc3RyaW5nIHNpemUuCisgICAgICBzdHJlYW1fLT5SZWFkU3RyaW5nKCZyZXN1bHQsIGJ1ZmZlcjMyKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0tpbmRfVFlQRV9CWVRFUzogeworICAgICAgdWludDMyIGJ1ZmZlcjMyOworICAgICAgc3RyZWFtXy0+UmVhZFZhcmludDMyKCZidWZmZXIzMik7ICAvLyBieXRlcyBzaXplLgorICAgICAgc3RyZWFtXy0+UmVhZFN0cmluZygmcmVzdWx0LCBidWZmZXIzMik7CisgICAgICBicmVhazsKKyAgICB9CisgICAgZGVmYXVsdDoKKyAgICAgIGJyZWFrOworICB9CisgIHJldHVybiByZXN1bHQ7Cit9CisKKy8vIEZpZWxkIGlzIGEgbWFwIGlmIGl0IGlzIGEgcmVwZWF0ZWQgbWVzc2FnZSBhbmQgaXQgaGFzIGFuIG9wdGlvbiAibWFwX3R5cGUiLgorLy8gVE9ETyhza2FydmFqZSk6IENvbnNpZGVyIHByZS1jb21wdXRpbmcgdGhlIElzTWFwKCkgaW50byBGaWVsZCBkaXJlY3RseS4KK2Jvb2wgUHJvdG9TdHJlYW1PYmplY3RTb3VyY2U6OklzTWFwKAorICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkJiBmaWVsZCkgY29uc3QgeworICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlKiBmaWVsZF90eXBlID0KKyAgICAgIHR5cGVpbmZvXy0+R2V0VHlwZUJ5VHlwZVVybChmaWVsZC50eXBlX3VybCgpKTsKKworICAvLyBUT0RPKHhpYW9mZW5nKTogVW5pZnkgb3B0aW9uIG5hbWVzLgorICByZXR1cm4gZmllbGQua2luZCgpID09IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0tpbmRfVFlQRV9NRVNTQUdFICYmCisgICAgICAgICAoR2V0Qm9vbE9wdGlvbk9yRGVmYXVsdChmaWVsZF90eXBlLT5vcHRpb25zKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zLm1hcF9lbnRyeSIsIGZhbHNlKSB8fAorICAgICAgICAgIEdldEJvb2xPcHRpb25PckRlZmF1bHQoZmllbGRfdHlwZS0+b3B0aW9ucygpLCAibWFwX2VudHJ5IiwgZmFsc2UpKTsKK30KKworc3RkOjpwYWlyPGludDY0LCBpbnQzMj4gUHJvdG9TdHJlYW1PYmplY3RTb3VyY2U6OlJlYWRTZWNvbmRzQW5kTmFub3MoCisgICAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6VHlwZSYgdHlwZSkgY29uc3QgeworICB1aW50NjQgc2Vjb25kcyA9IDA7CisgIHVpbnQzMiBuYW5vcyA9IDA7CisgIHVpbnQzMiB0YWcgPSAwOworICBpbnQ2NCBzaWduZWRfc2Vjb25kcyA9IDA7CisgIGludDMyIHNpZ25lZF9uYW5vcyA9IDA7CisKKyAgZm9yICh0YWcgPSBzdHJlYW1fLT5SZWFkVGFnKCk7IHRhZyAhPSAwOyB0YWcgPSBzdHJlYW1fLT5SZWFkVGFnKCkpIHsKKyAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZCogZmllbGQgPSBGaW5kQW5kVmVyaWZ5RmllbGQodHlwZSwgdGFnKTsKKyAgICBpZiAoZmllbGQgPT0gTlVMTCkgeworICAgICAgV2lyZUZvcm1hdDo6U2tpcEZpZWxkKHN0cmVhbV8sIHRhZywgTlVMTCk7CisgICAgICBjb250aW51ZTsKKyAgICB9CisgICAgLy8gJ3NlY29uZHMnIGhhcyBmaWVsZCBudW1iZXIgb2YgMSBhbmQgJ25hbm9zJyBoYXMgZmllbGQgbnVtYmVyIDIKKyAgICAvLyAvL2dvb2dsZS9wcm90b2J1Zi90aW1lc3RhbXAucHJvdG8gJiBkdXJhdGlvbi5wcm90bworICAgIGlmIChmaWVsZC0+bnVtYmVyKCkgPT0gMSkgeworICAgICAgLy8gcmVhZCBzZWNvbmRzCisgICAgICBzdHJlYW1fLT5SZWFkVmFyaW50NjQoJnNlY29uZHMpOworICAgICAgc2lnbmVkX3NlY29uZHMgPSBiaXRfY2FzdDxpbnQ2ND4oc2Vjb25kcyk7CisgICAgfSBlbHNlIGlmIChmaWVsZC0+bnVtYmVyKCkgPT0gMikgeworICAgICAgLy8gcmVhZCBuYW5vcworICAgICAgc3RyZWFtXy0+UmVhZFZhcmludDMyKCZuYW5vcyk7CisgICAgICBzaWduZWRfbmFub3MgPSBiaXRfY2FzdDxpbnQzMj4obmFub3MpOworICAgIH0KKyAgfQorICByZXR1cm4gc3RkOjpwYWlyPGludDY0LCBpbnQzMj4oc2lnbmVkX3NlY29uZHMsIHNpZ25lZF9uYW5vcyk7Cit9CisKK25hbWVzcGFjZSB7CisvLyBUT0RPKHNrYXJ2YWplKTogU3BlZWQgdGhpcyB1cCBieSBub3QgZG9pbmcgYSBsaW5lYXIgc2Nhbi4KK2NvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkKiBGaW5kRmllbGRCeU51bWJlcigKKyAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlJiB0eXBlLCBpbnQgbnVtYmVyKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdHlwZS5maWVsZHNfc2l6ZSgpOyArK2kpIHsKKyAgICBpZiAodHlwZS5maWVsZHMoaSkubnVtYmVyKCkgPT0gbnVtYmVyKSB7CisgICAgICByZXR1cm4gJnR5cGUuZmllbGRzKGkpOworICAgIH0KKyAgfQorICByZXR1cm4gTlVMTDsKK30KKworLy8gVE9ETyhza2FydmFqZSk6IFJlcGxhY2UgRmllbGREZXNjcmlwdG9yIGJ5IGltcGxlbWVudGluZyBJc1R5cGVQYWNrYWJsZSgpCisvLyB1c2luZyB0ZWNoIEZpZWxkLgorYm9vbCBJc1BhY2thYmxlKGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkJiBmaWVsZCkgeworICByZXR1cm4gZmllbGQuY2FyZGluYWxpdHkoKSA9PQorICAgICAgICAgICAgIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0NhcmRpbmFsaXR5X0NBUkRJTkFMSVRZX1JFUEVBVEVEICYmCisgICAgICAgICBnb29nbGU6OnByb3RvYnVmOjpGaWVsZERlc2NyaXB0b3I6OklzVHlwZVBhY2thYmxlKAorICAgICAgICAgICAgIHN0YXRpY19jYXN0PGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvcjo6VHlwZT4oZmllbGQua2luZCgpKSk7Cit9CisKKy8vIFRPRE8oc2thcnZhamUpOiBTcGVlZCB0aGlzIHVwIGJ5IG5vdCBkb2luZyBhIGxpbmVhciBzY2FuLgorY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlKiBGaW5kRW51bVZhbHVlQnlOdW1iZXIoCisgICAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RW51bSYgdGVjaF9lbnVtLCBpbnQgbnVtYmVyKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdGVjaF9lbnVtLmVudW12YWx1ZV9zaXplKCk7ICsraSkgeworICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZSYgZXYgPSB0ZWNoX2VudW0uZW51bXZhbHVlKGkpOworICAgIGlmIChldi5udW1iZXIoKSA9PSBudW1iZXIpIHsKKyAgICAgIHJldHVybiAmZXY7CisgICAgfQorICB9CisgIHJldHVybiBOVUxMOworfQorCisvLyBUT0RPKHNrYXJ2YWplKTogTG9vayBpbnRvIG9wdGltaXppbmcgdGhpcyBieSBub3QgZG9pbmcgY29tcHV0YXRpb24gb24KKy8vIGRvdWJsZS4KK2NvbnN0IHN0cmluZyBGb3JtYXROYW5vcyh1aW50MzIgbmFub3MpIHsKKyAgY29uc3QgY2hhciogZm9ybWF0ID0KKyAgICAgIChuYW5vcyAlIDEwMDAgIT0gMCkgPyAiJS45ZiIgOiAobmFub3MgJSAxMDAwMDAwICE9IDApID8gIiUuNmYiIDogIiUuM2YiOworICBzdHJpbmcgZm9ybWF0dGVkID0KKyAgICAgIFN0cmluZ1ByaW50Zihmb3JtYXQsIHN0YXRpY19jYXN0PGRvdWJsZT4obmFub3MpIC8ga05hbm9zUGVyU2Vjb25kKTsKKyAgLy8gcmVtb3ZlIHRoZSBsZWFkaW5nIDAgYmVmb3JlIGRlY2ltYWwuCisgIHJldHVybiBmb3JtYXR0ZWQuc3Vic3RyKDEpOworfQorfSAgLy8gbmFtZXNwYWNlCisKK30gIC8vIG5hbWVzcGFjZSBjb252ZXJ0ZXIKK30gIC8vIG5hbWVzcGFjZSB1dGlsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9wcm90b3N0cmVhbV9vYmplY3Rzb3VyY2UuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9wcm90b3N0cmVhbV9vYmplY3Rzb3VyY2UuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43OGRlZmExCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3Byb3Rvc3RyZWFtX29iamVjdHNvdXJjZS5oCkBAIC0wLDAgKzEsMjQ4IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfVVRJTF9DT05WRVJURVJfUFJPVE9TVFJFQU1fT0JKRUNUU09VUkNFX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfVVRJTF9DT05WRVJURVJfUFJPVE9TVFJFQU1fT0JKRUNUU09VUkNFX0hfXworCisjaW5jbHVkZSA8ZnVuY3Rpb25hbD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvaGFzaC5oPgorI2luY2x1ZGUgPHN0cmluZz4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdHlwZS5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL29iamVjdF9zb3VyY2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9vYmplY3Rfd3JpdGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvdHlwZV9pbmZvLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3V0aWwvdHlwZV9yZXNvbHZlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJpbmdwaWVjZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdGF0dXMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RhdHVzb3IuaD4KKworCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CitjbGFzcyBGaWVsZDsKK2NsYXNzIFR5cGU7Cit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworCituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIHV0aWwgeworbmFtZXNwYWNlIGNvbnZlcnRlciB7CisKK2NsYXNzIFR5cGVJbmZvOworCisvLyBBbiBPYmplY3RTb3VyY2UgdGhhdCBjYW4gcGFyc2UgYSBzdHJlYW0gb2YgYnl0ZXMgYXMgYSBwcm90b2NvbCBidWZmZXIuCisvLyBJdHMgV3JpdGVUbygpIG1ldGhvZCBjYW4gYmUgZ2l2ZW4gYW4gT2JqZWN0V3JpdGVyLgorLy8gVGhpcyBpbXBsZW1lbnRhdGlvbiB1c2VzIGEgZ29vZ2xlLnByb3RvYnVmLlR5cGUgZm9yIHRhZyBhbmQgbmFtZSBsb29rdXAuCisvLyBUaGUgZmllbGQgbmFtZXMgYXJlIGNvbnZlcnRlZCBpbnRvIGxvd2VyIGNhbWVsLWNhc2Ugd2hlbiB3cml0aW5nIHRvIHRoZQorLy8gT2JqZWN0V3JpdGVyLgorLy8KKy8vIFNhbXBsZSB1c2FnZTogKHN1cHBvc2UgaW5wdXQgaXM6IHN0cmluZyBwcm90bykKKy8vICAgQXJyYXlJbnB1dFN0cmVhbSBhcnJfc3RyZWFtKHByb3RvLmRhdGEoKSwgcHJvdG8uc2l6ZSgpKTsKKy8vICAgQ29kZWRJbnB1dFN0cmVhbSBpbl9zdHJlYW0oJmFycl9zdHJlYW0pOworLy8gICBQcm90b1N0cmVhbU9iamVjdFNvdXJjZSBvcygmaW5fc3RyZWFtLCAvKlNlcnZpY2VUeXBlSW5mbyovIHR5cGVpbmZvLAorLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8eW91ciBtZXNzYWdlIGdvb2dsZTo6cHJvdG9idWY6OlR5cGU+KTsKKy8vCisvLyAgIFN0YXR1cyBzdGF0dXMgPSBvcy5Xcml0ZVRvKDxzb21lIE9iamVjdFdyaXRlcj4pOworY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFByb3RvU3RyZWFtT2JqZWN0U291cmNlIDogcHVibGljIE9iamVjdFNvdXJjZSB7CisgcHVibGljOgorICBQcm90b1N0cmVhbU9iamVjdFNvdXJjZShnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogc3RyZWFtLAorICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlUmVzb2x2ZXIqIHR5cGVfcmVzb2x2ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlR5cGUmIHR5cGUpOworCisgIHZpcnR1YWwgflByb3RvU3RyZWFtT2JqZWN0U291cmNlKCk7CisKKyAgdmlydHVhbCB1dGlsOjpTdGF0dXMgTmFtZWRXcml0ZVRvKFN0cmluZ1BpZWNlIG5hbWUsIE9iamVjdFdyaXRlciogb3cpIGNvbnN0OworCisgcHJvdGVjdGVkOgorICAvLyBXcml0ZXMgYSBwcm90bzIgTWVzc2FnZSB0byB0aGUgT2JqZWN0V3JpdGVyLiBXaGVuIHRoZSBnaXZlbiBlbmRfdGFnIGlzCisgIC8vIGZvdW5kIHRoaXMgbWV0aG9kIHdpbGwgY29tcGxldGUsIGFsbG93aW5nIGl0IHRvIGJlIHVzZWQgZm9yIHBhcnNpbmcgYm90aAorICAvLyBuZXN0ZWQgbWVzc2FnZXMgKGVuZCB3aXRoIDApIGFuZCBuZXN0ZWQgZ3JvdXBzIChlbmQgd2l0aCBncm91cCBlbmQgdGFnKS4KKyAgLy8gVGhlIGluY2x1ZGVfc3RhcnRfYW5kX2VuZCBwYXJhbWV0ZXIgYWxsb3dzIHRoaXMgbWV0aG9kIHRvIGJlIGNhbGxlZCB3aGVuCisgIC8vIGFscmVhZHkgaW5zaWRlIG9mIGFuIG9iamVjdCwgYW5kIHNraXAgY2FsbGluZyBTdGFydE9iamVjdCBhbmQgRW5kT2JqZWN0LgorICB2aXJ0dWFsIHV0aWw6OlN0YXR1cyBXcml0ZU1lc3NhZ2UoY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6VHlwZSYgZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UgbmFtZSwgY29uc3QgdWludDMyIGVuZF90YWcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaW5jbHVkZV9zdGFydF9hbmRfZW5kLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3RXcml0ZXIqIG93KSBjb25zdDsKKworIHByaXZhdGU6CisgIFByb3RvU3RyZWFtT2JqZWN0U291cmNlKGdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBzdHJlYW0sCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFR5cGVJbmZvKiB0eXBlaW5mbywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6VHlwZSYgdHlwZSk7CisgIC8vIEZ1bmN0aW9uIHRoYXQgcmVuZGVycyBhIHdlbGwga25vd24gdHlwZSB3aXRoIGEgbW9kaWZpZWQgYmVoYXZpb3IuCisgIHR5cGVkZWYgdXRpbDo6U3RhdHVzICgqVHlwZVJlbmRlcmVyKShjb25zdCBQcm90b1N0cmVhbU9iamVjdFNvdXJjZSosCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlR5cGUmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdQaWVjZSwgT2JqZWN0V3JpdGVyKik7CisKKyAgLy8gTG9va3MgdXAgYSBmaWVsZCBhbmQgdmVyaWZ5IGl0cyBjb25zaXN0ZW5jeSB3aXRoIHdpcmUgdHlwZSBpbiB0YWcuCisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkKiBGaW5kQW5kVmVyaWZ5RmllbGQoCisgICAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlJiB0eXBlLCB1aW50MzIgdGFnKSBjb25zdDsKKworICAvLyBUT0RPKHNrYXJ2YWplKTogTWFyayB0aGVzZSBtZXRob2RzIGFzIG5vbi1jb25zdCBhcyB0aGV5IG1vZGlmeSBpbnRlcm5hbAorICAvLyBzdGF0ZSAoc3RyZWFtXykuCisgIC8vCisgIC8vIFJlbmRlcnMgYSByZXBlYXRpbmcgZmllbGQgKHBhY2tlZCBvciB1bnBhY2tlZCkuCisgIC8vIFJldHVybnMgdGhlIG5leHQgdGFnIGFmdGVyIHJlYWRpbmcgYWxsIHNlcXVlbnRpYWwgcmVwZWF0aW5nIGVsZW1lbnRzLiBUaGUKKyAgLy8gY2FsbGVyIHNob3VsZCB1c2UgdGhpcyB0YWcgYmVmb3JlIHJlYWRpbmcgbW9yZSB0YWdzIGZyb20gdGhlIHN0cmVhbS4KKyAgdXRpbDo6U3RhdHVzT3I8dWludDMyPiBSZW5kZXJMaXN0KGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UgbmFtZSwgdWludDMyIGxpc3RfdGFnLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3RXcml0ZXIqIG93KSBjb25zdDsKKyAgLy8gUmVuZGVycyBhIE5XUCBtYXAuCisgIC8vIFJldHVybnMgdGhlIG5leHQgdGFnIGFmdGVyIHJlYWRpbmcgYWxsIG1hcCBlbnRyaWVzLiBUaGUgY2FsbGVyIHNob3VsZCB1c2UKKyAgLy8gdGhpcyB0YWcgYmVmb3JlIHJlYWRpbmcgbW9yZSB0YWdzIGZyb20gdGhlIHN0cmVhbS4KKyAgdXRpbDo6U3RhdHVzT3I8dWludDMyPiBSZW5kZXJNYXAoY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGQqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1BpZWNlIG5hbWUsIHVpbnQzMiBsaXN0X3RhZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3RXcml0ZXIqIG93KSBjb25zdDsKKworICAvLyBSZW5kZXJzIGEgcGFja2VkIHJlcGVhdGluZyBmaWVsZC4gQSBwYWNrZWQgZmllbGQgaXMgc3RvcmVkIGFzOgorICAvLyB7dGFnIGxlbmd0aCBpdGVtMSBpdGVtMiBpdGVtM30gaW5zdGVhZCBvZiB0aGUgbGVzcyBlZmZpY2llbnQKKyAgLy8ge3RhZyBpdGVtMSB0YWcgaXRlbTIgdGFnIGl0ZW0zfS4KKyAgdXRpbDo6U3RhdHVzIFJlbmRlclBhY2tlZChjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZCogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3RXcml0ZXIqIG93KSBjb25zdDsKKworICAvLyBSZW5kZXJzIGEgZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCB2YWx1ZSB0byBPYmplY3RXcml0ZXIKKyAgc3RhdGljIHV0aWw6OlN0YXR1cyBSZW5kZXJUaW1lc3RhbXAoY29uc3QgUHJvdG9TdHJlYW1PYmplY3RTb3VyY2UqIG9zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlR5cGUmIHR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UgbmFtZSwgT2JqZWN0V3JpdGVyKiBvdyk7CisKKyAgLy8gUmVuZGVycyBhIGdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiB2YWx1ZSB0byBPYmplY3RXcml0ZXIKKyAgc3RhdGljIHV0aWw6OlN0YXR1cyBSZW5kZXJEdXJhdGlvbihjb25zdCBQcm90b1N0cmVhbU9iamVjdFNvdXJjZSogb3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlJiB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UgbmFtZSwgT2JqZWN0V3JpdGVyKiBvdyk7CisKKyAgLy8gRm9sbG93aW5nIFJlbmRlclRZUEUgZnVuY3Rpb25zIHJlbmRlciB3ZWxsIGtub3duIHR5cGVzIGluCisgIC8vIGdvb2dsZS9wcm90b2J1Zi93cmFwcGVycy5wcm90byBjb3JyZXNwb25kaW5nIHRvIFRZUEUuCisgIHN0YXRpYyB1dGlsOjpTdGF0dXMgUmVuZGVyRG91YmxlKGNvbnN0IFByb3RvU3RyZWFtT2JqZWN0U291cmNlKiBvcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlJiB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1BpZWNlIG5hbWUsIE9iamVjdFdyaXRlciogb3cpOworICBzdGF0aWMgdXRpbDo6U3RhdHVzIFJlbmRlckZsb2F0KGNvbnN0IFByb3RvU3RyZWFtT2JqZWN0U291cmNlKiBvcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlR5cGUmIHR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdQaWVjZSBuYW1lLCBPYmplY3RXcml0ZXIqIG93KTsKKyAgc3RhdGljIHV0aWw6OlN0YXR1cyBSZW5kZXJJbnQ2NChjb25zdCBQcm90b1N0cmVhbU9iamVjdFNvdXJjZSogb3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlJiB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UgbmFtZSwgT2JqZWN0V3JpdGVyKiBvdyk7CisgIHN0YXRpYyB1dGlsOjpTdGF0dXMgUmVuZGVyVUludDY0KGNvbnN0IFByb3RvU3RyZWFtT2JqZWN0U291cmNlKiBvcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlJiB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1BpZWNlIG5hbWUsIE9iamVjdFdyaXRlciogb3cpOworICBzdGF0aWMgdXRpbDo6U3RhdHVzIFJlbmRlckludDMyKGNvbnN0IFByb3RvU3RyZWFtT2JqZWN0U291cmNlKiBvcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlR5cGUmIHR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdQaWVjZSBuYW1lLCBPYmplY3RXcml0ZXIqIG93KTsKKyAgc3RhdGljIHV0aWw6OlN0YXR1cyBSZW5kZXJVSW50MzIoY29uc3QgUHJvdG9TdHJlYW1PYmplY3RTb3VyY2UqIG9zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlR5cGUmIHR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UgbmFtZSwgT2JqZWN0V3JpdGVyKiBvdyk7CisgIHN0YXRpYyB1dGlsOjpTdGF0dXMgUmVuZGVyQm9vbChjb25zdCBQcm90b1N0cmVhbU9iamVjdFNvdXJjZSogb3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlR5cGUmIHR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1BpZWNlIG5hbWUsIE9iamVjdFdyaXRlciogb3cpOworICBzdGF0aWMgdXRpbDo6U3RhdHVzIFJlbmRlclN0cmluZyhjb25zdCBQcm90b1N0cmVhbU9iamVjdFNvdXJjZSogb3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6VHlwZSYgdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdQaWVjZSBuYW1lLCBPYmplY3RXcml0ZXIqIG93KTsKKyAgc3RhdGljIHV0aWw6OlN0YXR1cyBSZW5kZXJCeXRlcyhjb25zdCBQcm90b1N0cmVhbU9iamVjdFNvdXJjZSogb3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlJiB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UgbmFtZSwgT2JqZWN0V3JpdGVyKiBvdyk7CisKKyAgLy8gUmVuZGVycyBhIGdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QgdG8gT2JqZWN0V3JpdGVyLgorICBzdGF0aWMgdXRpbDo6U3RhdHVzIFJlbmRlclN0cnVjdChjb25zdCBQcm90b1N0cmVhbU9iamVjdFNvdXJjZSogb3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6VHlwZSYgdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdQaWVjZSBuYW1lLCBPYmplY3RXcml0ZXIqIG93KTsKKworICAvLyBIZWxwZXIgdG8gcmVuZGVyIGdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QncyBWYWx1ZSBmaWVsZHMgdG8gT2JqZWN0V3JpdGVyLgorICBzdGF0aWMgdXRpbDo6U3RhdHVzIFJlbmRlclN0cnVjdFZhbHVlKGNvbnN0IFByb3RvU3RyZWFtT2JqZWN0U291cmNlKiBvcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlR5cGUmIHR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdQaWVjZSBuYW1lLCBPYmplY3RXcml0ZXIqIG93KTsKKworICAvLyBIZWxwZXIgdG8gcmVuZGVyIGdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QncyBMaXN0VmFsdWUgZmllbGRzIHRvIE9iamVjdFdyaXRlci4KKyAgc3RhdGljIHV0aWw6OlN0YXR1cyBSZW5kZXJTdHJ1Y3RMaXN0VmFsdWUoCisgICAgICBjb25zdCBQcm90b1N0cmVhbU9iamVjdFNvdXJjZSogb3MsIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlR5cGUmIHR5cGUsCisgICAgICBTdHJpbmdQaWVjZSBuYW1lLCBPYmplY3RXcml0ZXIqIG93KTsKKworICAvLyBSZW5kZXIgdGhlICJBbnkiIHR5cGUuCisgIHN0YXRpYyB1dGlsOjpTdGF0dXMgUmVuZGVyQW55KGNvbnN0IFByb3RvU3RyZWFtT2JqZWN0U291cmNlKiBvcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlJiB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1BpZWNlIG5hbWUsIE9iamVjdFdyaXRlciogb3cpOworCisgIC8vIFJlbmRlciB0aGUgIkZpZWxkTWFzayIgdHlwZS4KKyAgc3RhdGljIHV0aWw6OlN0YXR1cyBSZW5kZXJGaWVsZE1hc2soY29uc3QgUHJvdG9TdHJlYW1PYmplY3RTb3VyY2UqIG9zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlR5cGUmIHR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UgbmFtZSwgT2JqZWN0V3JpdGVyKiBvdyk7CisKKyAgc3RhdGljIGhhc2hfbWFwPHN0cmluZywgVHlwZVJlbmRlcmVyPiogcmVuZGVyZXJzXzsKKyAgc3RhdGljIHZvaWQgSW5pdFJlbmRlcmVyTWFwKCk7CisgIHN0YXRpYyB2b2lkIERlbGV0ZVJlbmRlcmVyTWFwKCk7CisgIHN0YXRpYyBUeXBlUmVuZGVyZXIqIEZpbmRUeXBlUmVuZGVyZXIoY29uc3Qgc3RyaW5nJiB0eXBlX3VybCk7CisKKyAgLy8gUmVuZGVycyBhIGZpZWxkIHZhbHVlIHRvIHRoZSBPYmplY3RXcml0ZXIuCisgIHV0aWw6OlN0YXR1cyBSZW5kZXJGaWVsZChjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZCogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1BpZWNlIGZpZWxkX25hbWUsIE9iamVjdFdyaXRlciogb3cpIGNvbnN0OworCisgIC8vIFNhbWUgYXMgYWJvdmUgYnV0IHJlbmRlcnMgYWxsIG5vbi1tZXNzYWdlIGZpZWxkIHR5cGVzLiBDYWxsZXJzIGRvbid0IGNhbGwKKyAgLy8gdGhpcyBmdW5jdGlvbiBkaXJlY3RseS4gVGhleSBqdXN0IHVzZSBSZW5kZXJGaWVsZC4KKyAgdXRpbDo6U3RhdHVzIFJlbmRlck5vbk1lc3NhZ2VGaWVsZChjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZCogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdQaWVjZSBmaWVsZF9uYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0V3JpdGVyKiBvdykgY29uc3Q7CisKKworICAvLyBSZWFkcyBmaWVsZCB2YWx1ZSBhY2NvcmRpbmcgdG8gRmllbGQgc3BlYyBpbiAnZmllbGQnIGFuZCByZXR1cm5zIHRoZSByZWFkCisgIC8vIHZhbHVlIGFzIHN0cmluZy4gVGhpcyBvbmx5IHdvcmtzIGZvciBwcmltaXRpdmUgZGF0YXR5cGVzIChubyBtZXNzYWdlCisgIC8vIHR5cGVzKS4KKyAgY29uc3Qgc3RyaW5nIFJlYWRGaWVsZFZhbHVlQXNTdHJpbmcoCisgICAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZCYgZmllbGQpIGNvbnN0OworCisgIC8vIFV0aWxpdHkgZnVuY3Rpb24gdG8gZGV0ZWN0IHByb3RvIG1hcHMuIFRoZSAnZmllbGQnIE1VU1QgYmUgcmVwZWF0ZWQuCisgIGJvb2wgSXNNYXAoY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGQmIGZpZWxkKSBjb25zdDsKKworICAvLyBVdGlsaXR5IHRvIHJlYWQgaW50NjQgYW5kIGludDMyIHZhbHVlcyBmcm9tIGEgbWVzc2FnZSB0eXBlIGluIHN0cmVhbV8uCisgIC8vIFVzZWQgZm9yIHJlYWRpbmcgZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCBhbmQgRHVyYXRpb24gbWVzc2FnZXMuCisgIHN0ZDo6cGFpcjxpbnQ2NCwgaW50MzI+IFJlYWRTZWNvbmRzQW5kTmFub3MoCisgICAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlJiB0eXBlKSBjb25zdDsKKworICAvLyBJbnB1dCBzdHJlYW0gdG8gcmVhZCBmcm9tLiBPd25lcnNoaXAgcmVzdHMgd2l0aCB0aGUgY2FsbGVyLgorICBnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogc3RyZWFtXzsKKworICAvLyBUeXBlIGluZm9ybWF0aW9uIGZvciBhbGwgdGhlIHR5cGVzIHVzZWQgaW4gdGhlIGRlc2NyaXB0b3IuIFVzZWQgdG8gZmluZAorICAvLyBnb29nbGU6OnByb3RvYnVmOjpUeXBlIG9mIG5lc3RlZCBtZXNzYWdlcy9lbnVtcy4KKyAgY29uc3QgVHlwZUluZm8qIHR5cGVpbmZvXzsKKyAgLy8gV2hldGhlciB0aGlzIGNsYXNzIG93bnMgdGhlIHR5cGVpbmZvXyBvYmplY3QuIElmIHRydWUgdGhlIHR5cGVpbmZvXyBvYmplY3QKKyAgLy8gc2hvdWxkIGJlIGRlbGV0ZWQgaW4gdGhlIGRlc3RydWN0b3IuCisgIGJvb2wgb3duX3R5cGVpbmZvXzsKKworICAvLyBnb29nbGU6OnByb3RvYnVmOjpUeXBlIG9mIHRoZSBtZXNzYWdlIHNvdXJjZS4KKyAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6VHlwZSYgdHlwZV87CisKKworICBHT09HTEVfRElTQUxMT1dfSU1QTElDSVRfQ09OU1RSVUNUT1JTKFByb3RvU3RyZWFtT2JqZWN0U291cmNlKTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBjb252ZXJ0ZXIKK30gIC8vIG5hbWVzcGFjZSB1dGlsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfVVRJTF9DT05WRVJURVJfUFJPVE9TVFJFQU1fT0JKRUNUU09VUkNFX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3Byb3Rvc3RyZWFtX29iamVjdHNvdXJjZV90ZXN0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3Byb3Rvc3RyZWFtX29iamVjdHNvdXJjZV90ZXN0LmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU2MWY2NzYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvcHJvdG9zdHJlYW1fb2JqZWN0c291cmNlX3Rlc3QuY2MKQEAgLTAsMCArMSw4MzAgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvcHJvdG9zdHJlYW1fb2JqZWN0c291cmNlLmg+CisKKyNpbmNsdWRlIDxtZW1vcnk+CisjaWZuZGVmIF9TSEFSRURfUFRSX0gKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc2hhcmVkX3B0ci5oPgorI2VuZGlmCisjaW5jbHVkZSA8c3N0cmVhbT4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jYXN0cy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9hbnkucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbF9saXRlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9leHBlY3Rpbmdfb2JqZWN0d3JpdGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvdGVzdGRhdGEvYm9va3MucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90ZXN0ZGF0YS9maWVsZF9tYXNrLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvdHlwZV9pbmZvX3Rlc3RfaGVscGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvY29uc3RhbnRzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90ZXN0ZGF0YS9hbnlzLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvdGVzdGRhdGEvbWFwcy5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3Rlc3RkYXRhL3N0cnVjdC5wYi5oPgorI2luY2x1ZGUgPGd0ZXN0L2d0ZXN0Lmg+CisKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIHV0aWwgeworbmFtZXNwYWNlIGNvbnZlcnRlciB7CisKK3VzaW5nIGdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3I7Cit1c2luZyBnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUG9vbDsKK3VzaW5nIGdvb2dsZTo6cHJvdG9idWY6OkZpbGVEZXNjcmlwdG9yUHJvdG87Cit1c2luZyBnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlOwordXNpbmcgZ29vZ2xlOjpwcm90b2J1Zjo6aW86OkFycmF5SW5wdXRTdHJlYW07Cit1c2luZyBnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbTsKK3VzaW5nIHV0aWw6OlN0YXR1czsKK3VzaW5nIGdvb2dsZTo6cHJvdG9idWY6OnRlc3Rpbmc6OkF1dGhvcjsKK3VzaW5nIGdvb2dsZTo6cHJvdG9idWY6OnRlc3Rpbmc6OkJhZEF1dGhvcjsKK3VzaW5nIGdvb2dsZTo6cHJvdG9idWY6OnRlc3Rpbmc6OkJhZE5lc3RlZEJvb2s7Cit1c2luZyBnb29nbGU6OnByb3RvYnVmOjp0ZXN0aW5nOjpCb29rOwordXNpbmcgZ29vZ2xlOjpwcm90b2J1Zjo6dGVzdGluZzo6Qm9va19MYWJlbDsKK3VzaW5nIGdvb2dsZTo6cHJvdG9idWY6OnRlc3Rpbmc6Ok5lc3RlZEJvb2s7Cit1c2luZyBnb29nbGU6OnByb3RvYnVmOjp0ZXN0aW5nOjpQYWNrZWRQcmltaXRpdmU7Cit1c2luZyBnb29nbGU6OnByb3RvYnVmOjp0ZXN0aW5nOjpQcmltaXRpdmU7Cit1c2luZyBnb29nbGU6OnByb3RvYnVmOjp0ZXN0aW5nOjptb3JlX2F1dGhvcjsKK3VzaW5nIGdvb2dsZTo6cHJvdG9idWY6OnRlc3Rpbmc6Om1hcHM6Ok1hcE91dDsKK3VzaW5nIGdvb2dsZTo6cHJvdG9idWY6OnRlc3Rpbmc6OmFueXM6OkFueU91dDsKK3VzaW5nIGdvb2dsZTo6cHJvdG9idWY6OnRlc3Rpbmc6OmFueXM6OkFueU07Cit1c2luZyBnb29nbGU6OnByb3RvYnVmOjp0ZXN0aW5nOjpGaWVsZE1hc2tUZXN0OwordXNpbmcgZ29vZ2xlOjpwcm90b2J1Zjo6dGVzdGluZzo6TmVzdGVkRmllbGRNYXNrOwordXNpbmcgZ29vZ2xlOjpwcm90b2J1Zjo6dGVzdGluZzo6c3RydWN0czo6U3RydWN0VHlwZTsKK3VzaW5nIDo6dGVzdGluZzo6XzsKKworCituYW1lc3BhY2Ugeworc3RyaW5nIEdldFR5cGVVcmwoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICByZXR1cm4gc3RyaW5nKGtUeXBlU2VydmljZUJhc2VVcmwpICsgIi8iICsgZGVzY3JpcHRvci0+ZnVsbF9uYW1lKCk7Cit9Cit9ICAvLyBuYW1lc3BhY2UKKworY2xhc3MgUHJvdG9zdHJlYW1PYmplY3RTb3VyY2VUZXN0CisgICAgOiBwdWJsaWMgOjp0ZXN0aW5nOjpUZXN0V2l0aFBhcmFtPHRlc3Rpbmc6OlR5cGVJbmZvU291cmNlPiB7CisgcHJvdGVjdGVkOgorICBQcm90b3N0cmVhbU9iamVjdFNvdXJjZVRlc3QoKSA6IGhlbHBlcl8oR2V0UGFyYW0oKSksIG1vY2tfKCksIG93XygmbW9ja18pIHsKKyAgICBoZWxwZXJfLlJlc2V0VHlwZUluZm8oQm9vazo6ZGVzY3JpcHRvcigpKTsKKyAgfQorCisgIHZpcnR1YWwgflByb3Rvc3RyZWFtT2JqZWN0U291cmNlVGVzdCgpIHt9CisKKyAgdm9pZCBEb1Rlc3QoY29uc3QgTWVzc2FnZSYgbXNnLCBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgICAgU3RhdHVzIHN0YXR1cyA9IEV4ZWN1dGVUZXN0KG1zZywgZGVzY3JpcHRvcik7CisgICAgRVhQRUNUX0VRKFN0YXR1czo6T0ssIHN0YXR1cyk7CisgIH0KKworICBTdGF0dXMgRXhlY3V0ZVRlc3QoY29uc3QgTWVzc2FnZSYgbXNnLCBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgICAgb3N0cmluZ3N0cmVhbSBvc3M7CisgICAgbXNnLlNlcmlhbGl6ZVBhcnRpYWxUb09zdHJlYW0oJm9zcyk7CisgICAgc3RyaW5nIHByb3RvID0gb3NzLnN0cigpOworICAgIEFycmF5SW5wdXRTdHJlYW0gYXJyX3N0cmVhbShwcm90by5kYXRhKCksIHByb3RvLnNpemUoKSk7CisgICAgQ29kZWRJbnB1dFN0cmVhbSBpbl9zdHJlYW0oJmFycl9zdHJlYW0pOworCisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxQcm90b1N0cmVhbU9iamVjdFNvdXJjZT4gb3MoCisgICAgICAgIGhlbHBlcl8uTmV3UHJvdG9Tb3VyY2UoJmluX3N0cmVhbSwgR2V0VHlwZVVybChkZXNjcmlwdG9yKSkpOworICAgIHJldHVybiBvcy0+V3JpdGVUbygmbW9ja18pOworICB9CisKKyAgdm9pZCBQcmVwYXJlRXhwZWN0aW5nT2JqZWN0V3JpdGVyRm9yUmVwZWF0ZWRQcmltaXRpdmUoKSB7CisgICAgb3dfLlN0YXJ0T2JqZWN0KCIiKQorICAgICAgICAtPlN0YXJ0TGlzdCgicmVwRml4MzIiKQorICAgICAgICAtPlJlbmRlclVpbnQzMigiIiwgYml0X2Nhc3Q8dWludDMyPigzMjAxKSkKKyAgICAgICAgLT5SZW5kZXJVaW50MzIoIiIsIGJpdF9jYXN0PHVpbnQzMj4oMCkpCisgICAgICAgIC0+UmVuZGVyVWludDMyKCIiLCBiaXRfY2FzdDx1aW50MzI+KDMyMDIpKQorICAgICAgICAtPkVuZExpc3QoKQorICAgICAgICAtPlN0YXJ0TGlzdCgicmVwVTMyIikKKyAgICAgICAgLT5SZW5kZXJVaW50MzIoIiIsIGJpdF9jYXN0PHVpbnQzMj4oMzIwMykpCisgICAgICAgIC0+UmVuZGVyVWludDMyKCIiLCBiaXRfY2FzdDx1aW50MzI+KDApKQorICAgICAgICAtPkVuZExpc3QoKQorICAgICAgICAtPlN0YXJ0TGlzdCgicmVwSTMyIikKKyAgICAgICAgLT5SZW5kZXJJbnQzMigiIiwgMCkKKyAgICAgICAgLT5SZW5kZXJJbnQzMigiIiwgMzIwNCkKKyAgICAgICAgLT5SZW5kZXJJbnQzMigiIiwgMzIwNSkKKyAgICAgICAgLT5FbmRMaXN0KCkKKyAgICAgICAgLT5TdGFydExpc3QoInJlcFNmMzIiKQorICAgICAgICAtPlJlbmRlckludDMyKCIiLCAzMjA2KQorICAgICAgICAtPlJlbmRlckludDMyKCIiLCAwKQorICAgICAgICAtPkVuZExpc3QoKQorICAgICAgICAtPlN0YXJ0TGlzdCgicmVwUzMyIikKKyAgICAgICAgLT5SZW5kZXJJbnQzMigiIiwgMCkKKyAgICAgICAgLT5SZW5kZXJJbnQzMigiIiwgMzIwNykKKyAgICAgICAgLT5SZW5kZXJJbnQzMigiIiwgMzIwOCkKKyAgICAgICAgLT5FbmRMaXN0KCkKKyAgICAgICAgLT5TdGFydExpc3QoInJlcEZpeDY0IikKKyAgICAgICAgLT5SZW5kZXJVaW50NjQoIiIsIGJpdF9jYXN0PHVpbnQ2ND4oNjQwMUxMKSkKKyAgICAgICAgLT5SZW5kZXJVaW50NjQoIiIsIGJpdF9jYXN0PHVpbnQ2ND4oMExMKSkKKyAgICAgICAgLT5FbmRMaXN0KCkKKyAgICAgICAgLT5TdGFydExpc3QoInJlcFU2NCIpCisgICAgICAgIC0+UmVuZGVyVWludDY0KCIiLCBiaXRfY2FzdDx1aW50NjQ+KDBMTCkpCisgICAgICAgIC0+UmVuZGVyVWludDY0KCIiLCBiaXRfY2FzdDx1aW50NjQ+KDY0MDJMTCkpCisgICAgICAgIC0+UmVuZGVyVWludDY0KCIiLCBiaXRfY2FzdDx1aW50NjQ+KDY0MDNMTCkpCisgICAgICAgIC0+RW5kTGlzdCgpCisgICAgICAgIC0+U3RhcnRMaXN0KCJyZXBJNjQiKQorICAgICAgICAtPlJlbmRlckludDY0KCIiLCA2NDA0TCkKKyAgICAgICAgLT5SZW5kZXJJbnQ2NCgiIiwgMEwpCisgICAgICAgIC0+RW5kTGlzdCgpCisgICAgICAgIC0+U3RhcnRMaXN0KCJyZXBTZjY0IikKKyAgICAgICAgLT5SZW5kZXJJbnQ2NCgiIiwgMEwpCisgICAgICAgIC0+UmVuZGVySW50NjQoIiIsIDY0MDVMKQorICAgICAgICAtPlJlbmRlckludDY0KCIiLCA2NDA2TCkKKyAgICAgICAgLT5FbmRMaXN0KCkKKyAgICAgICAgLT5TdGFydExpc3QoInJlcFM2NCIpCisgICAgICAgIC0+UmVuZGVySW50NjQoIiIsIDY0MDdMKQorICAgICAgICAtPlJlbmRlckludDY0KCIiLCAwTCkKKyAgICAgICAgLT5FbmRMaXN0KCkKKyAgICAgICAgLT5TdGFydExpc3QoInJlcEZsb2F0IikKKyAgICAgICAgLT5SZW5kZXJGbG9hdCgiIiwgMC4wZikKKyAgICAgICAgLT5SZW5kZXJGbG9hdCgiIiwgMzIuMWYpCisgICAgICAgIC0+UmVuZGVyRmxvYXQoIiIsIDMyLjJmKQorICAgICAgICAtPkVuZExpc3QoKQorICAgICAgICAtPlN0YXJ0TGlzdCgicmVwRG91YmxlIikKKyAgICAgICAgLT5SZW5kZXJEb3VibGUoIiIsIDY0LjFMKQorICAgICAgICAtPlJlbmRlckRvdWJsZSgiIiwgMC4wTCkKKyAgICAgICAgLT5FbmRMaXN0KCkKKyAgICAgICAgLT5TdGFydExpc3QoInJlcEJvb2wiKQorICAgICAgICAtPlJlbmRlckJvb2woIiIsIHRydWUpCisgICAgICAgIC0+UmVuZGVyQm9vbCgiIiwgZmFsc2UpCisgICAgICAgIC0+RW5kTGlzdCgpCisgICAgICAgIC0+RW5kT2JqZWN0KCk7CisgIH0KKworICBQcmltaXRpdmUgUHJlcGFyZVJlcGVhdGVkUHJpbWl0aXZlKCkgeworICAgIFByaW1pdGl2ZSBwcmltaXRpdmU7CisgICAgcHJpbWl0aXZlLmFkZF9yZXBfZml4MzIoMzIwMSk7CisgICAgcHJpbWl0aXZlLmFkZF9yZXBfZml4MzIoMCk7CisgICAgcHJpbWl0aXZlLmFkZF9yZXBfZml4MzIoMzIwMik7CisgICAgcHJpbWl0aXZlLmFkZF9yZXBfdTMyKDMyMDMpOworICAgIHByaW1pdGl2ZS5hZGRfcmVwX3UzMigwKTsKKyAgICBwcmltaXRpdmUuYWRkX3JlcF9pMzIoMCk7CisgICAgcHJpbWl0aXZlLmFkZF9yZXBfaTMyKDMyMDQpOworICAgIHByaW1pdGl2ZS5hZGRfcmVwX2kzMigzMjA1KTsKKyAgICBwcmltaXRpdmUuYWRkX3JlcF9zZjMyKDMyMDYpOworICAgIHByaW1pdGl2ZS5hZGRfcmVwX3NmMzIoMCk7CisgICAgcHJpbWl0aXZlLmFkZF9yZXBfczMyKDApOworICAgIHByaW1pdGl2ZS5hZGRfcmVwX3MzMigzMjA3KTsKKyAgICBwcmltaXRpdmUuYWRkX3JlcF9zMzIoMzIwOCk7CisgICAgcHJpbWl0aXZlLmFkZF9yZXBfZml4NjQoNjQwMUwpOworICAgIHByaW1pdGl2ZS5hZGRfcmVwX2ZpeDY0KDBMKTsKKyAgICBwcmltaXRpdmUuYWRkX3JlcF91NjQoMEwpOworICAgIHByaW1pdGl2ZS5hZGRfcmVwX3U2NCg2NDAyTCk7CisgICAgcHJpbWl0aXZlLmFkZF9yZXBfdTY0KDY0MDNMKTsKKyAgICBwcmltaXRpdmUuYWRkX3JlcF9pNjQoNjQwNEwpOworICAgIHByaW1pdGl2ZS5hZGRfcmVwX2k2NCgwTCk7CisgICAgcHJpbWl0aXZlLmFkZF9yZXBfc2Y2NCgwTCk7CisgICAgcHJpbWl0aXZlLmFkZF9yZXBfc2Y2NCg2NDA1TCk7CisgICAgcHJpbWl0aXZlLmFkZF9yZXBfc2Y2NCg2NDA2TCk7CisgICAgcHJpbWl0aXZlLmFkZF9yZXBfczY0KDY0MDdMKTsKKyAgICBwcmltaXRpdmUuYWRkX3JlcF9zNjQoMEwpOworICAgIHByaW1pdGl2ZS5hZGRfcmVwX2Zsb2F0KDAuMGYpOworICAgIHByaW1pdGl2ZS5hZGRfcmVwX2Zsb2F0KDMyLjFmKTsKKyAgICBwcmltaXRpdmUuYWRkX3JlcF9mbG9hdCgzMi4yZik7CisgICAgcHJpbWl0aXZlLmFkZF9yZXBfZG91YmxlKDY0LjFMKTsKKyAgICBwcmltaXRpdmUuYWRkX3JlcF9kb3VibGUoMC4wKTsKKyAgICBwcmltaXRpdmUuYWRkX3JlcF9ib29sKHRydWUpOworICAgIHByaW1pdGl2ZS5hZGRfcmVwX2Jvb2woZmFsc2UpOworCisgICAgUHJlcGFyZUV4cGVjdGluZ09iamVjdFdyaXRlckZvclJlcGVhdGVkUHJpbWl0aXZlKCk7CisgICAgcmV0dXJuIHByaW1pdGl2ZTsKKyAgfQorCisgIFBhY2tlZFByaW1pdGl2ZSBQcmVwYXJlUGFja2VkUHJpbWl0aXZlKCkgeworICAgIFBhY2tlZFByaW1pdGl2ZSBwcmltaXRpdmU7CisgICAgcHJpbWl0aXZlLmFkZF9yZXBfZml4MzIoMzIwMSk7CisgICAgcHJpbWl0aXZlLmFkZF9yZXBfZml4MzIoMCk7CisgICAgcHJpbWl0aXZlLmFkZF9yZXBfZml4MzIoMzIwMik7CisgICAgcHJpbWl0aXZlLmFkZF9yZXBfdTMyKDMyMDMpOworICAgIHByaW1pdGl2ZS5hZGRfcmVwX3UzMigwKTsKKyAgICBwcmltaXRpdmUuYWRkX3JlcF9pMzIoMCk7CisgICAgcHJpbWl0aXZlLmFkZF9yZXBfaTMyKDMyMDQpOworICAgIHByaW1pdGl2ZS5hZGRfcmVwX2kzMigzMjA1KTsKKyAgICBwcmltaXRpdmUuYWRkX3JlcF9zZjMyKDMyMDYpOworICAgIHByaW1pdGl2ZS5hZGRfcmVwX3NmMzIoMCk7CisgICAgcHJpbWl0aXZlLmFkZF9yZXBfczMyKDApOworICAgIHByaW1pdGl2ZS5hZGRfcmVwX3MzMigzMjA3KTsKKyAgICBwcmltaXRpdmUuYWRkX3JlcF9zMzIoMzIwOCk7CisgICAgcHJpbWl0aXZlLmFkZF9yZXBfZml4NjQoNjQwMUwpOworICAgIHByaW1pdGl2ZS5hZGRfcmVwX2ZpeDY0KDBMKTsKKyAgICBwcmltaXRpdmUuYWRkX3JlcF91NjQoMEwpOworICAgIHByaW1pdGl2ZS5hZGRfcmVwX3U2NCg2NDAyTCk7CisgICAgcHJpbWl0aXZlLmFkZF9yZXBfdTY0KDY0MDNMKTsKKyAgICBwcmltaXRpdmUuYWRkX3JlcF9pNjQoNjQwNEwpOworICAgIHByaW1pdGl2ZS5hZGRfcmVwX2k2NCgwTCk7CisgICAgcHJpbWl0aXZlLmFkZF9yZXBfc2Y2NCgwTCk7CisgICAgcHJpbWl0aXZlLmFkZF9yZXBfc2Y2NCg2NDA1TCk7CisgICAgcHJpbWl0aXZlLmFkZF9yZXBfc2Y2NCg2NDA2TCk7CisgICAgcHJpbWl0aXZlLmFkZF9yZXBfczY0KDY0MDdMKTsKKyAgICBwcmltaXRpdmUuYWRkX3JlcF9zNjQoMEwpOworICAgIHByaW1pdGl2ZS5hZGRfcmVwX2Zsb2F0KDAuMGYpOworICAgIHByaW1pdGl2ZS5hZGRfcmVwX2Zsb2F0KDMyLjFmKTsKKyAgICBwcmltaXRpdmUuYWRkX3JlcF9mbG9hdCgzMi4yZik7CisgICAgcHJpbWl0aXZlLmFkZF9yZXBfZG91YmxlKDY0LjFMKTsKKyAgICBwcmltaXRpdmUuYWRkX3JlcF9kb3VibGUoMC4wKTsKKyAgICBwcmltaXRpdmUuYWRkX3JlcF9ib29sKHRydWUpOworICAgIHByaW1pdGl2ZS5hZGRfcmVwX2Jvb2woZmFsc2UpOworCisgICAgUHJlcGFyZUV4cGVjdGluZ09iamVjdFdyaXRlckZvclJlcGVhdGVkUHJpbWl0aXZlKCk7CisgICAgcmV0dXJuIHByaW1pdGl2ZTsKKyAgfQorCisgIHRlc3Rpbmc6OlR5cGVJbmZvVGVzdEhlbHBlciBoZWxwZXJfOworCisgIDo6dGVzdGluZzo6TmljZU1vY2s8TW9ja09iamVjdFdyaXRlcj4gbW9ja187CisgIEV4cGVjdGluZ09iamVjdFdyaXRlciBvd187Cit9OworCitJTlNUQU5USUFURV9URVNUX0NBU0VfUChEaWZmZXJlbnRUeXBlSW5mb1NvdXJjZVRlc3QsCisgICAgICAgICAgICAgICAgICAgICAgICBQcm90b3N0cmVhbU9iamVjdFNvdXJjZVRlc3QsCisgICAgICAgICAgICAgICAgICAgICAgICA6OnRlc3Rpbmc6OlZhbHVlcygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXN0aW5nOjpVU0VfVFlQRV9SRVNPTFZFUikpOworCitURVNUX1AoUHJvdG9zdHJlYW1PYmplY3RTb3VyY2VUZXN0LCBFbXB0eU1lc3NhZ2UpIHsKKyAgQm9vayBlbXB0eTsKKyAgb3dfLlN0YXJ0T2JqZWN0KCIiKS0+RW5kT2JqZWN0KCk7CisgIERvVGVzdChlbXB0eSwgQm9vazo6ZGVzY3JpcHRvcigpKTsKK30KKworVEVTVF9QKFByb3Rvc3RyZWFtT2JqZWN0U291cmNlVGVzdCwgUHJpbWl0aXZlcykgeworICBQcmltaXRpdmUgcHJpbWl0aXZlOworICBwcmltaXRpdmUuc2V0X2ZpeDMyKDMyMDEpOworICBwcmltaXRpdmUuc2V0X3UzMigzMjAyKTsKKyAgcHJpbWl0aXZlLnNldF9pMzIoMzIwMyk7CisgIHByaW1pdGl2ZS5zZXRfc2YzMigzMjA0KTsKKyAgcHJpbWl0aXZlLnNldF9zMzIoMzIwNSk7CisgIHByaW1pdGl2ZS5zZXRfZml4NjQoNjQwMUwpOworICBwcmltaXRpdmUuc2V0X3U2NCg2NDAyTCk7CisgIHByaW1pdGl2ZS5zZXRfaTY0KDY0MDNMKTsKKyAgcHJpbWl0aXZlLnNldF9zZjY0KDY0MDRMKTsKKyAgcHJpbWl0aXZlLnNldF9zNjQoNjQwNUwpOworICBwcmltaXRpdmUuc2V0X3N0cigiU3RyaW5nIFZhbHVlIik7CisgIHByaW1pdGl2ZS5zZXRfYnl0ZXMoIlNvbWUgQnl0ZXMiKTsKKyAgcHJpbWl0aXZlLnNldF9mbG9hdF8oMzIuMWYpOworICBwcmltaXRpdmUuc2V0X2RvdWJsZV8oNjQuMUwpOworICBwcmltaXRpdmUuc2V0X2Jvb2xfKHRydWUpOworCisgIG93Xy5TdGFydE9iamVjdCgiIikKKyAgICAgIC0+UmVuZGVyVWludDMyKCJmaXgzMiIsIGJpdF9jYXN0PHVpbnQzMj4oMzIwMSkpCisgICAgICAtPlJlbmRlclVpbnQzMigidTMyIiwgYml0X2Nhc3Q8dWludDMyPigzMjAyKSkKKyAgICAgIC0+UmVuZGVySW50MzIoImkzMiIsIDMyMDMpCisgICAgICAtPlJlbmRlckludDMyKCJzZjMyIiwgMzIwNCkKKyAgICAgIC0+UmVuZGVySW50MzIoInMzMiIsIDMyMDUpCisgICAgICAtPlJlbmRlclVpbnQ2NCgiZml4NjQiLCBiaXRfY2FzdDx1aW50NjQ+KDY0MDFMTCkpCisgICAgICAtPlJlbmRlclVpbnQ2NCgidTY0IiwgYml0X2Nhc3Q8dWludDY0Pig2NDAyTEwpKQorICAgICAgLT5SZW5kZXJJbnQ2NCgiaTY0IiwgNjQwM0wpCisgICAgICAtPlJlbmRlckludDY0KCJzZjY0IiwgNjQwNEwpCisgICAgICAtPlJlbmRlckludDY0KCJzNjQiLCA2NDA1TCkKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJzdHIiLCAiU3RyaW5nIFZhbHVlIikKKyAgICAgIC0+UmVuZGVyQnl0ZXMoImJ5dGVzIiwgIlNvbWUgQnl0ZXMiKQorICAgICAgLT5SZW5kZXJGbG9hdCgiZmxvYXQiLCAzMi4xZikKKyAgICAgIC0+UmVuZGVyRG91YmxlKCJkb3VibGUiLCA2NC4xTCkKKyAgICAgIC0+UmVuZGVyQm9vbCgiYm9vbCIsIHRydWUpCisgICAgICAtPkVuZE9iamVjdCgpOworICBEb1Rlc3QocHJpbWl0aXZlLCBQcmltaXRpdmU6OmRlc2NyaXB0b3IoKSk7Cit9CisKK1RFU1RfUChQcm90b3N0cmVhbU9iamVjdFNvdXJjZVRlc3QsIFJlcGVhdGluZ1ByaW1pdGl2ZXMpIHsKKyAgUHJpbWl0aXZlIHByaW1pdGl2ZSA9IFByZXBhcmVSZXBlYXRlZFByaW1pdGl2ZSgpOworICBwcmltaXRpdmUuYWRkX3JlcF9zdHIoIlN0cmluZyBPbmUiKTsKKyAgcHJpbWl0aXZlLmFkZF9yZXBfc3RyKCJTdHJpbmcgVHdvIik7CisgIHByaW1pdGl2ZS5hZGRfcmVwX2J5dGVzKCJTb21lIEJ5dGVzIik7CisKKyAgb3dfLlN0YXJ0TGlzdCgicmVwU3RyIikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCIiLCAiU3RyaW5nIE9uZSIpCisgICAgICAtPlJlbmRlclN0cmluZygiIiwgIlN0cmluZyBUd28iKQorICAgICAgLT5FbmRMaXN0KCkKKyAgICAgIC0+U3RhcnRMaXN0KCJyZXBCeXRlcyIpCisgICAgICAtPlJlbmRlckJ5dGVzKCIiLCAiU29tZSBCeXRlcyIpCisgICAgICAtPkVuZExpc3QoKTsKKyAgRG9UZXN0KHByaW1pdGl2ZSwgUHJpbWl0aXZlOjpkZXNjcmlwdG9yKCkpOworfQorCitURVNUX1AoUHJvdG9zdHJlYW1PYmplY3RTb3VyY2VUZXN0LCBDdXN0b21Kc29uTmFtZSkgeworICBBdXRob3IgYXV0aG9yOworICBhdXRob3Iuc2V0X2lkKDEyMzQ1KTsKKworICBvd18uU3RhcnRPYmplY3QoIiIpLT5SZW5kZXJVaW50NjQoIkBpZCIsIDEyMzQ1KS0+RW5kT2JqZWN0KCk7CisgIERvVGVzdChhdXRob3IsIEF1dGhvcjo6ZGVzY3JpcHRvcigpKTsKK30KKworVEVTVF9QKFByb3Rvc3RyZWFtT2JqZWN0U291cmNlVGVzdCwgTmVzdGVkTWVzc2FnZSkgeworICBBdXRob3IqIGF1dGhvciA9IG5ldyBBdXRob3IoKTsKKyAgYXV0aG9yLT5zZXRfbmFtZSgiVG9sc3RveSIpOworICBCb29rIGJvb2s7CisgIGJvb2suc2V0X3RpdGxlKCJNeSBCb29rIik7CisgIGJvb2suc2V0X2FsbG9jYXRlZF9hdXRob3IoYXV0aG9yKTsKKworICBvd18uU3RhcnRPYmplY3QoIiIpCisgICAgICAtPlJlbmRlclN0cmluZygidGl0bGUiLCAiTXkgQm9vayIpCisgICAgICAtPlN0YXJ0T2JqZWN0KCJhdXRob3IiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoIm5hbWUiLCAiVG9sc3RveSIpCisgICAgICAtPkVuZE9iamVjdCgpCisgICAgICAtPkVuZE9iamVjdCgpOworICBEb1Rlc3QoYm9vaywgQm9vazo6ZGVzY3JpcHRvcigpKTsKK30KKworVEVTVF9QKFByb3Rvc3RyZWFtT2JqZWN0U291cmNlVGVzdCwgUmVwZWF0aW5nRmllbGQpIHsKKyAgQXV0aG9yIGF1dGhvcjsKKyAgYXV0aG9yLnNldF9hbGl2ZShmYWxzZSk7CisgIGF1dGhvci5zZXRfbmFtZSgiam9obiIpOworICBhdXRob3IuYWRkX3BzZXVkb255bSgicGhpbCIpOworICBhdXRob3IuYWRkX3BzZXVkb255bSgiYm9iIik7CisKKyAgb3dfLlN0YXJ0T2JqZWN0KCIiKQorICAgICAgLT5SZW5kZXJCb29sKCJhbGl2ZSIsIGZhbHNlKQorICAgICAgLT5SZW5kZXJTdHJpbmcoIm5hbWUiLCAiam9obiIpCisgICAgICAtPlN0YXJ0TGlzdCgicHNldWRvbnltIikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCIiLCAicGhpbCIpCisgICAgICAtPlJlbmRlclN0cmluZygiIiwgImJvYiIpCisgICAgICAtPkVuZExpc3QoKQorICAgICAgLT5FbmRPYmplY3QoKTsKKyAgRG9UZXN0KGF1dGhvciwgQXV0aG9yOjpkZXNjcmlwdG9yKCkpOworfQorCitURVNUX1AoUHJvdG9zdHJlYW1PYmplY3RTb3VyY2VUZXN0LCBQYWNrZWRSZXBlYXRpbmdGaWVsZHMpIHsKKyAgRG9UZXN0KFByZXBhcmVQYWNrZWRQcmltaXRpdmUoKSwgUGFja2VkUHJpbWl0aXZlOjpkZXNjcmlwdG9yKCkpOworfQorCitURVNUX1AoUHJvdG9zdHJlYW1PYmplY3RTb3VyY2VUZXN0LCBOb25QYWNrZWRQYWNrYWJsZUZpZWxkc0FjdHVhbGx5UGFja2VkKSB7CisgIC8vIFByb3Rvc3RyZWFtIGlzIHBhY2tlZCwgYnV0IHBhcnNlIHdpdGggbm9uLXBhY2tlZCBQcmltaXRpdmUuCisgIERvVGVzdChQcmVwYXJlUGFja2VkUHJpbWl0aXZlKCksIFByaW1pdGl2ZTo6ZGVzY3JpcHRvcigpKTsKK30KKworVEVTVF9QKFByb3Rvc3RyZWFtT2JqZWN0U291cmNlVGVzdCwgUGFja2VkUGFja2FibGVGaWVsZE5vdEFjdHVhbGx5UGFja2VkKSB7CisgIC8vIFByb3Rvc3RyZWFtIGlzIG5vdCBwYWNrZWQsIGJ1dCBwYXJzZSB3aXRoIFBhY2tlZFByaW1pdGl2ZS4KKyAgRG9UZXN0KFByZXBhcmVSZXBlYXRlZFByaW1pdGl2ZSgpLCBQYWNrZWRQcmltaXRpdmU6OmRlc2NyaXB0b3IoKSk7Cit9CisKK1RFU1RfUChQcm90b3N0cmVhbU9iamVjdFNvdXJjZVRlc3QsIEJhZEF1dGhvcikgeworICBBdXRob3IgYXV0aG9yOworICBhdXRob3Iuc2V0X2FsaXZlKGZhbHNlKTsKKyAgYXV0aG9yLnNldF9uYW1lKCJqb2huIik7CisgIGF1dGhvci5zZXRfaWQoMTIzNEwpOworICBhdXRob3IuYWRkX3BzZXVkb255bSgicGhpbCIpOworICBhdXRob3IuYWRkX3BzZXVkb255bSgiYm9iIik7CisKKyAgb3dfLlN0YXJ0T2JqZWN0KCIiKQorICAgICAgLT5TdGFydExpc3QoImFsaXZlIikKKyAgICAgIC0+UmVuZGVyQm9vbCgiIiwgZmFsc2UpCisgICAgICAtPkVuZExpc3QoKQorICAgICAgLT5TdGFydExpc3QoIm5hbWUiKQorICAgICAgLT5SZW5kZXJVaW50NjQoIiIsIHN0YXRpY19jYXN0PHVpbnQ2ND4oJ2onKSkKKyAgICAgIC0+UmVuZGVyVWludDY0KCIiLCBzdGF0aWNfY2FzdDx1aW50NjQ+KCdvJykpCisgICAgICAtPlJlbmRlclVpbnQ2NCgiIiwgc3RhdGljX2Nhc3Q8dWludDY0PignaCcpKQorICAgICAgLT5SZW5kZXJVaW50NjQoIiIsIHN0YXRpY19jYXN0PHVpbnQ2ND4oJ24nKSkKKyAgICAgIC0+RW5kTGlzdCgpCisgICAgICAtPlJlbmRlclN0cmluZygicHNldWRvbnltIiwgInBoaWwiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoInBzZXVkb255bSIsICJib2IiKQorICAgICAgLT5FbmRPYmplY3QoKTsKKyAgLy8gUHJvdG9zdHJlYW0gY3JlYXRlZCB3aXRoIEF1dGhvciwgYnV0IHBhcnNlZCB3aXRoIEJhZEF1dGhvci4KKyAgRG9UZXN0KGF1dGhvciwgQmFkQXV0aG9yOjpkZXNjcmlwdG9yKCkpOworfQorCitURVNUX1AoUHJvdG9zdHJlYW1PYmplY3RTb3VyY2VUZXN0LCBOZXN0ZWRCb29rVG9CYWROZXN0ZWRCb29rKSB7CisgIEJvb2sqIGJvb2sgPSBuZXcgQm9vaygpOworICBib29rLT5zZXRfbGVuZ3RoKDI1MCk7CisgIGJvb2stPnNldF9wdWJsaXNoZWQoMjAxNEwpOworICBOZXN0ZWRCb29rIG5lc3RlZDsKKyAgbmVzdGVkLnNldF9hbGxvY2F0ZWRfYm9vayhib29rKTsKKworICBvd18uU3RhcnRPYmplY3QoIiIpCisgICAgICAtPlN0YXJ0TGlzdCgiYm9vayIpCisgICAgICAtPlJlbmRlclVpbnQzMigiIiwgMjQpICAvLyB0YWcgZm9yIGZpZWxkIGxlbmd0aCAoMyA8PCAzKQorICAgICAgLT5SZW5kZXJVaW50MzIoIiIsIDI1MCkKKyAgICAgIC0+UmVuZGVyVWludDMyKCIiLCAzMikgIC8vIHRhZyBmb3IgZmllbGQgcHVibGlzaGVkICg0IDw8IDMpCisgICAgICAtPlJlbmRlclVpbnQzMigiIiwgMjAxNCkKKyAgICAgIC0+RW5kTGlzdCgpCisgICAgICAtPkVuZE9iamVjdCgpOworICAvLyBQcm90b3N0cmVhbSBjcmVhdGVkIHdpdGggTmVzdGVkQm9vaywgYnV0IHBhcnNlZCB3aXRoIEJhZE5lc3RlZEJvb2suCisgIERvVGVzdChuZXN0ZWQsIEJhZE5lc3RlZEJvb2s6OmRlc2NyaXB0b3IoKSk7Cit9CisKK1RFU1RfUChQcm90b3N0cmVhbU9iamVjdFNvdXJjZVRlc3QsIEJhZE5lc3RlZEJvb2tUb05lc3RlZEJvb2spIHsKKyAgQmFkTmVzdGVkQm9vayBuZXN0ZWQ7CisgIG5lc3RlZC5hZGRfYm9vaygxKTsKKyAgbmVzdGVkLmFkZF9ib29rKDIpOworICBuZXN0ZWQuYWRkX2Jvb2soMyk7CisgIG5lc3RlZC5hZGRfYm9vayg0KTsKKyAgbmVzdGVkLmFkZF9ib29rKDUpOworICBuZXN0ZWQuYWRkX2Jvb2soNik7CisgIG5lc3RlZC5hZGRfYm9vayg3KTsKKworICBvd18uU3RhcnRPYmplY3QoIiIpLT5TdGFydE9iamVjdCgiYm9vayIpLT5FbmRPYmplY3QoKS0+RW5kT2JqZWN0KCk7CisgIC8vIFByb3Rvc3RyZWFtIGNyZWF0ZWQgd2l0aCBCYWROZXN0ZWRCb29rLCBidXQgcGFyc2VkIHdpdGggTmVzdGVkQm9vay4KKyAgRG9UZXN0KG5lc3RlZCwgTmVzdGVkQm9vazo6ZGVzY3JpcHRvcigpKTsKK30KKworVEVTVF9QKFByb3Rvc3RyZWFtT2JqZWN0U291cmNlVGVzdCwKKyAgICAgICBMb25nUmVwZWF0ZWRMaXN0RG9lc05vdEJyZWFrSW50b011bHRpcGxlSnNvbkxpc3RzKSB7CisgIEJvb2sgYm9vazsKKworICBpbnQgcmVwZWF0ID0gMTAwMDA7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0OyArK2kpIHsKKyAgICBCb29rX0xhYmVsKiBsYWJlbCA9IGJvb2suYWRkX2xhYmVscygpOworICAgIGxhYmVsLT5zZXRfa2V5KFN0ckNhdCgiaSIsIGkpKTsKKyAgICBsYWJlbC0+c2V0X3ZhbHVlKFN0ckNhdCgidiIsIGkpKTsKKyAgfQorCisgIC8vIE1ha2Ugc3VyZSBTdGFydExpc3QgYW5kIEVuZExpc3QgYXJlIGNhbGxlZCBleGFjdGx5IG9uY2UgKHNlZSBiLzE4MjI3NDk5IGZvcgorICAvLyBwcm9ibGVtcyB3aGVuIHRoaXMgZG9lc24ndCBoYXBwZW4pCisgIEVYUEVDVF9DQUxMKG1vY2tfLCBTdGFydExpc3QoXykpLlRpbWVzKDEpOworICBFWFBFQ1RfQ0FMTChtb2NrXywgRW5kTGlzdCgpKS5UaW1lcygxKTsKKworICBEb1Rlc3QoYm9vaywgQm9vazo6ZGVzY3JpcHRvcigpKTsKK30KKworY2xhc3MgUHJvdG9zdHJlYW1PYmplY3RTb3VyY2VNYXBzVGVzdCA6IHB1YmxpYyBQcm90b3N0cmVhbU9iamVjdFNvdXJjZVRlc3QgeworIHByb3RlY3RlZDoKKyAgUHJvdG9zdHJlYW1PYmplY3RTb3VyY2VNYXBzVGVzdCgpIHsKKyAgICBoZWxwZXJfLlJlc2V0VHlwZUluZm8oTWFwT3V0OjpkZXNjcmlwdG9yKCkpOworICB9Cit9OworCitJTlNUQU5USUFURV9URVNUX0NBU0VfUChEaWZmZXJlbnRUeXBlSW5mb1NvdXJjZVRlc3QsCisgICAgICAgICAgICAgICAgICAgICAgICBQcm90b3N0cmVhbU9iamVjdFNvdXJjZU1hcHNUZXN0LAorICAgICAgICAgICAgICAgICAgICAgICAgOjp0ZXN0aW5nOjpWYWx1ZXMoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVzdGluZzo6VVNFX1RZUEVfUkVTT0xWRVIpKTsKKworLy8gVGVzdHMgSlNPTiBtYXAuCisvLworLy8gVGhpcyBpcyB0aGUgZXhhbXBsZSBleHBlY3RlZCBvdXRwdXQuCisvLyB7CisvLyAgICJtYXAxIjogeworLy8gICAgICJrZXkxIjogeworLy8gICAgICAgImZvbyI6ICJmb292YWx1ZSIKKy8vICAgICB9LAorLy8gICAgICJrZXkyIjogeworLy8gICAgICAgImZvbyI6ICJiYXJ2YWx1ZSIKKy8vICAgICB9CisvLyAgIH0sCisvLyAgICJtYXAyIjogeworLy8gICAgICJuZXN0ZWRzZWxmIjogeworLy8gICAgICAgIm1hcDEiOiB7CisvLyAgICAgICAgICJuZXN0ZWRfa2V5MSI6IHsKKy8vICAgICAgICAgICAiZm9vIjogIm5lc3RlZF9mb28iCisvLyAgICAgICAgIH0KKy8vICAgICAgIH0sCisvLyAgICAgICAiYmFyIjogIm5lc3RlZF9iYXJfc3RyaW5nIgorLy8gICAgIH0KKy8vICAgfSwKKy8vICAgIm1hcDMiOiB7CisvLyAgICAgIjExMSI6ICJvbmUgb25lIG9uZSIKKy8vICAgfSwKKy8vICAgImJhciI6ICJ0b3AgYmFyIgorLy8gfQorVEVTVF9QKFByb3Rvc3RyZWFtT2JqZWN0U291cmNlTWFwc1Rlc3QsIE1hcHNUZXN0KSB7CisgIE1hcE91dCBvdXQ7CisgICgqb3V0Lm11dGFibGVfbWFwMSgpKVsia2V5MSJdLnNldF9mb28oImZvb3ZhbHVlIik7CisgICgqb3V0Lm11dGFibGVfbWFwMSgpKVsia2V5MiJdLnNldF9mb28oImJhcnZhbHVlIik7CisKKyAgTWFwT3V0KiBuZXN0ZWRfdmFsdWUgPSAmKCpvdXQubXV0YWJsZV9tYXAyKCkpWyJuZXN0ZWRzZWxmIl07CisgICgqbmVzdGVkX3ZhbHVlLT5tdXRhYmxlX21hcDEoKSlbIm5lc3RlZF9rZXkxIl0uc2V0X2ZvbygibmVzdGVkX2ZvbyIpOworICBuZXN0ZWRfdmFsdWUtPnNldF9iYXIoIm5lc3RlZF9iYXJfc3RyaW5nIik7CisKKyAgKCpvdXQubXV0YWJsZV9tYXAzKCkpWzExMV0gPSAib25lIG9uZSBvbmUiOworCisgIG91dC5zZXRfYmFyKCJ0b3AgYmFyIik7CisKKyAgb3dfLlN0YXJ0T2JqZWN0KCIiKQorICAgICAgLT5TdGFydE9iamVjdCgibWFwMSIpCisgICAgICAtPlN0YXJ0T2JqZWN0KCJrZXkxIikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJmb28iLCAiZm9vdmFsdWUiKQorICAgICAgLT5FbmRPYmplY3QoKQorICAgICAgLT5TdGFydE9iamVjdCgia2V5MiIpCisgICAgICAtPlJlbmRlclN0cmluZygiZm9vIiwgImJhcnZhbHVlIikKKyAgICAgIC0+RW5kT2JqZWN0KCkKKyAgICAgIC0+U3RhcnRPYmplY3QoIm1hcDIiKQorICAgICAgLT5TdGFydE9iamVjdCgibmVzdGVkc2VsZiIpCisgICAgICAtPlN0YXJ0T2JqZWN0KCJtYXAxIikKKyAgICAgIC0+U3RhcnRPYmplY3QoIm5lc3RlZF9rZXkxIikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJmb28iLCAibmVzdGVkX2ZvbyIpCisgICAgICAtPkVuZE9iamVjdCgpCisgICAgICAtPkVuZE9iamVjdCgpCisgICAgICAtPlJlbmRlclN0cmluZygiYmFyIiwgIm5lc3RlZF9iYXJfc3RyaW5nIikKKyAgICAgIC0+RW5kT2JqZWN0KCkKKyAgICAgIC0+RW5kT2JqZWN0KCkKKyAgICAgIC0+U3RhcnRPYmplY3QoIm1hcDMiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoIjExMSIsICJvbmUgb25lIG9uZSIpCisgICAgICAtPkVuZE9iamVjdCgpCisgICAgICAtPkVuZE9iamVjdCgpCisgICAgICAtPlJlbmRlclN0cmluZygiYmFyIiwgInRvcCBiYXIiKQorICAgICAgLT5FbmRPYmplY3QoKTsKKworICBEb1Rlc3Qob3V0LCBNYXBPdXQ6OmRlc2NyaXB0b3IoKSk7Cit9CisKK2NsYXNzIFByb3Rvc3RyZWFtT2JqZWN0U291cmNlQW55c1Rlc3QgOiBwdWJsaWMgUHJvdG9zdHJlYW1PYmplY3RTb3VyY2VUZXN0IHsKKyBwcm90ZWN0ZWQ6CisgIFByb3Rvc3RyZWFtT2JqZWN0U291cmNlQW55c1Rlc3QoKSB7CisgICAgaGVscGVyXy5SZXNldFR5cGVJbmZvKEFueU91dDo6ZGVzY3JpcHRvcigpLAorICAgICAgICAgICAgICAgICAgICAgICAgICBnb29nbGU6OnByb3RvYnVmOjpBbnk6OmRlc2NyaXB0b3IoKSk7CisgIH0KK307CisKK0lOU1RBTlRJQVRFX1RFU1RfQ0FTRV9QKERpZmZlcmVudFR5cGVJbmZvU291cmNlVGVzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgIFByb3Rvc3RyZWFtT2JqZWN0U291cmNlQW55c1Rlc3QsCisgICAgICAgICAgICAgICAgICAgICAgICA6OnRlc3Rpbmc6OlZhbHVlcygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXN0aW5nOjpVU0VfVFlQRV9SRVNPTFZFUikpOworCisvLyBUZXN0cyBKU09OIGFueSBzdXBwb3J0LgorLy8KKy8vIFRoaXMgaXMgdGhlIGV4YW1wbGUgZXhwZWN0ZWQgb3V0cHV0LgorLy8geworLy8gICAiYW55IjogeworLy8gICAgICJAdHlwZSI6ICJ0eXBlLmdvb2dsZWFwaXMuY29tL2dvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLmFueXMuQW55TSIKKy8vICAgICAiZm9vIjogImZvb3ZhbHVlIgorLy8gICB9CisvLyB9CitURVNUX1AoUHJvdG9zdHJlYW1PYmplY3RTb3VyY2VBbnlzVGVzdCwgQmFzaWNBbnkpIHsKKyAgQW55T3V0IG91dDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpBbnkqIGFueSA9IG91dC5tdXRhYmxlX2FueSgpOworCisgIEFueU0gbTsKKyAgbS5zZXRfZm9vKCJmb292YWx1ZSIpOworICBhbnktPlBhY2tGcm9tKG0pOworCisgIG93Xy5TdGFydE9iamVjdCgiIikKKyAgICAgIC0+U3RhcnRPYmplY3QoImFueSIpCisgICAgICAtPlJlbmRlclN0cmluZygiQHR5cGUiLAorICAgICAgICAgICAgICAgICAgICAgInR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuYW55cy5BbnlNIikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJmb28iLCAiZm9vdmFsdWUiKQorICAgICAgLT5FbmRPYmplY3QoKQorICAgICAgLT5FbmRPYmplY3QoKTsKKworICBEb1Rlc3Qob3V0LCBBbnlPdXQ6OmRlc2NyaXB0b3IoKSk7Cit9CisKK1RFU1RfUChQcm90b3N0cmVhbU9iamVjdFNvdXJjZUFueXNUZXN0LCBSZWN1cnNpdmVBbnkpIHsKKyAgQW55T3V0IG91dDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpBbnkqIGFueSA9IG91dC5tdXRhYmxlX2FueSgpOworICBhbnktPnNldF90eXBlX3VybCgidHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUucHJvdG9idWYuQW55Iik7CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpBbnkgbmVzdGVkX2FueTsKKyAgbmVzdGVkX2FueS5zZXRfdHlwZV91cmwoCisgICAgICAidHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUucHJvdG9idWYudGVzdGluZy5hbnlzLkFueU0iKTsKKworICBBbnlNIG07CisgIG0uc2V0X2ZvbygiZm9vdmFsdWUiKTsKKyAgbmVzdGVkX2FueS5zZXRfdmFsdWUobS5TZXJpYWxpemVBc1N0cmluZygpKTsKKworICBhbnktPnNldF92YWx1ZShuZXN0ZWRfYW55LlNlcmlhbGl6ZUFzU3RyaW5nKCkpOworCisgIG93Xy5TdGFydE9iamVjdCgiIikKKyAgICAgIC0+U3RhcnRPYmplY3QoImFueSIpCisgICAgICAtPlJlbmRlclN0cmluZygiQHR5cGUiLCAidHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUucHJvdG9idWYuQW55IikKKyAgICAgIC0+U3RhcnRPYmplY3QoInZhbHVlIikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJAdHlwZSIsCisgICAgICAgICAgICAgICAgICAgICAidHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUucHJvdG9idWYudGVzdGluZy5hbnlzLkFueU0iKQorICAgICAgLT5SZW5kZXJTdHJpbmcoImZvbyIsICJmb292YWx1ZSIpCisgICAgICAtPkVuZE9iamVjdCgpCisgICAgICAtPkVuZE9iamVjdCgpCisgICAgICAtPkVuZE9iamVjdCgpOworCisgIERvVGVzdChvdXQsIEFueU91dDo6ZGVzY3JpcHRvcigpKTsKK30KKworVEVTVF9QKFByb3Rvc3RyZWFtT2JqZWN0U291cmNlQW55c1Rlc3QsIERvdWJsZVJlY3Vyc2l2ZUFueSkgeworICBBbnlPdXQgb3V0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OkFueSogYW55ID0gb3V0Lm11dGFibGVfYW55KCk7CisgIGFueS0+c2V0X3R5cGVfdXJsKCJ0eXBlLmdvb2dsZWFwaXMuY29tL2dvb2dsZS5wcm90b2J1Zi5BbnkiKTsKKworICA6Omdvb2dsZTo6cHJvdG9idWY6OkFueSBuZXN0ZWRfYW55OworICBuZXN0ZWRfYW55LnNldF90eXBlX3VybCgidHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUucHJvdG9idWYuQW55Iik7CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpBbnkgc2Vjb25kX25lc3RlZF9hbnk7CisgIHNlY29uZF9uZXN0ZWRfYW55LnNldF90eXBlX3VybCgKKyAgICAgICJ0eXBlLmdvb2dsZWFwaXMuY29tL2dvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLmFueXMuQW55TSIpOworCisgIEFueU0gbTsKKyAgbS5zZXRfZm9vKCJmb292YWx1ZSIpOworICBzZWNvbmRfbmVzdGVkX2FueS5zZXRfdmFsdWUobS5TZXJpYWxpemVBc1N0cmluZygpKTsKKyAgbmVzdGVkX2FueS5zZXRfdmFsdWUoc2Vjb25kX25lc3RlZF9hbnkuU2VyaWFsaXplQXNTdHJpbmcoKSk7CisgIGFueS0+c2V0X3ZhbHVlKG5lc3RlZF9hbnkuU2VyaWFsaXplQXNTdHJpbmcoKSk7CisKKyAgb3dfLlN0YXJ0T2JqZWN0KCIiKQorICAgICAgLT5TdGFydE9iamVjdCgiYW55IikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJAdHlwZSIsICJ0eXBlLmdvb2dsZWFwaXMuY29tL2dvb2dsZS5wcm90b2J1Zi5BbnkiKQorICAgICAgLT5TdGFydE9iamVjdCgidmFsdWUiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoIkB0eXBlIiwgInR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLnByb3RvYnVmLkFueSIpCisgICAgICAtPlN0YXJ0T2JqZWN0KCJ2YWx1ZSIpCisgICAgICAtPlJlbmRlclN0cmluZygiQHR5cGUiLAorICAgICAgICAgICAgICAgICAgICAgInR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuYW55cy5BbnlNIikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJmb28iLCAiZm9vdmFsdWUiKQorICAgICAgLT5FbmRPYmplY3QoKQorICAgICAgLT5FbmRPYmplY3QoKQorICAgICAgLT5FbmRPYmplY3QoKQorICAgICAgLT5FbmRPYmplY3QoKTsKKworICBEb1Rlc3Qob3V0LCBBbnlPdXQ6OmRlc2NyaXB0b3IoKSk7Cit9CisKK1RFU1RfUChQcm90b3N0cmVhbU9iamVjdFNvdXJjZUFueXNUZXN0LCBFbXB0eUFueU91dHB1dHNFbXB0eU9iamVjdCkgeworICBBbnlPdXQgb3V0OworICBvdXQubXV0YWJsZV9hbnkoKTsKKworICBvd18uU3RhcnRPYmplY3QoIiIpLT5TdGFydE9iamVjdCgiYW55IiktPkVuZE9iamVjdCgpLT5FbmRPYmplY3QoKTsKKworICBEb1Rlc3Qob3V0LCBBbnlPdXQ6OmRlc2NyaXB0b3IoKSk7Cit9CisKK1RFU1RfUChQcm90b3N0cmVhbU9iamVjdFNvdXJjZUFueXNUZXN0LCBFbXB0eVdpdGhUeXBlQW5kTm9WYWx1ZU91dHB1dHNUeXBlKSB7CisgIEFueU91dCBvdXQ7CisgIG91dC5tdXRhYmxlX2FueSgpLT5zZXRfdHlwZV91cmwoImZvby5nb29nbGVhcGlzLmNvbS9teS5UeXBlIik7CisKKyAgb3dfLlN0YXJ0T2JqZWN0KCIiKQorICAgICAgLT5TdGFydE9iamVjdCgiYW55IikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJAdHlwZSIsICJmb28uZ29vZ2xlYXBpcy5jb20vbXkuVHlwZSIpCisgICAgICAtPkVuZE9iamVjdCgpCisgICAgICAtPkVuZE9iamVjdCgpOworCisgIERvVGVzdChvdXQsIEFueU91dDo6ZGVzY3JpcHRvcigpKTsKK30KKworVEVTVF9QKFByb3Rvc3RyZWFtT2JqZWN0U291cmNlQW55c1Rlc3QsIE1pc3NpbmdUeXBlVXJsRXJyb3IpIHsKKyAgQW55T3V0IG91dDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpBbnkqIGFueSA9IG91dC5tdXRhYmxlX2FueSgpOworCisgIEFueU0gbTsKKyAgbS5zZXRfZm9vKCJmb292YWx1ZSIpOworICBhbnktPnNldF92YWx1ZShtLlNlcmlhbGl6ZUFzU3RyaW5nKCkpOworCisgIC8vIFdlIHN0YXJ0IHRoZSAiQW55T3V0IiBwYXJ0IGFuZCB0aGVuIGZhaWwgd2hlbiB3ZSBoaXQgdGhlIEFueSBvYmplY3QuCisgIG93Xy5TdGFydE9iamVjdCgiIik7CisKKyAgU3RhdHVzIHN0YXR1cyA9IEV4ZWN1dGVUZXN0KG91dCwgQW55T3V0OjpkZXNjcmlwdG9yKCkpOworICBFWFBFQ1RfRVEodXRpbDo6ZXJyb3I6OklOVEVSTkFMLCBzdGF0dXMuZXJyb3JfY29kZSgpKTsKK30KKworVEVTVF9QKFByb3Rvc3RyZWFtT2JqZWN0U291cmNlQW55c1Rlc3QsIFVua25vd25UeXBlU2VydmljZUVycm9yKSB7CisgIEFueU91dCBvdXQ7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QW55KiBhbnkgPSBvdXQubXV0YWJsZV9hbnkoKTsKKyAgYW55LT5zZXRfdHlwZV91cmwoImZvby5nb29nbGVhcGlzLmNvbS9teS5vd24uVHlwZSIpOworCisgIEFueU0gbTsKKyAgbS5zZXRfZm9vKCJmb292YWx1ZSIpOworICBhbnktPnNldF92YWx1ZShtLlNlcmlhbGl6ZUFzU3RyaW5nKCkpOworCisgIC8vIFdlIHN0YXJ0IHRoZSAiQW55T3V0IiBwYXJ0IGFuZCB0aGVuIGZhaWwgd2hlbiB3ZSBoaXQgdGhlIEFueSBvYmplY3QuCisgIG93Xy5TdGFydE9iamVjdCgiIik7CisKKyAgU3RhdHVzIHN0YXR1cyA9IEV4ZWN1dGVUZXN0KG91dCwgQW55T3V0OjpkZXNjcmlwdG9yKCkpOworICBFWFBFQ1RfRVEodXRpbDo6ZXJyb3I6OklOVEVSTkFMLCBzdGF0dXMuZXJyb3JfY29kZSgpKTsKK30KKworVEVTVF9QKFByb3Rvc3RyZWFtT2JqZWN0U291cmNlQW55c1Rlc3QsIFVua25vd25UeXBlRXJyb3IpIHsKKyAgQW55T3V0IG91dDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpBbnkqIGFueSA9IG91dC5tdXRhYmxlX2FueSgpOworICBhbnktPnNldF90eXBlX3VybCgidHlwZS5nb29nbGVhcGlzLmNvbS91bmtub3duLlR5cGUiKTsKKworICBBbnlNIG07CisgIG0uc2V0X2ZvbygiZm9vdmFsdWUiKTsKKyAgYW55LT5zZXRfdmFsdWUobS5TZXJpYWxpemVBc1N0cmluZygpKTsKKworICAvLyBXZSBzdGFydCB0aGUgIkFueU91dCIgcGFydCBhbmQgdGhlbiBmYWlsIHdoZW4gd2UgaGl0IHRoZSBBbnkgb2JqZWN0LgorICBvd18uU3RhcnRPYmplY3QoIiIpOworCisgIFN0YXR1cyBzdGF0dXMgPSBFeGVjdXRlVGVzdChvdXQsIEFueU91dDo6ZGVzY3JpcHRvcigpKTsKKyAgRVhQRUNUX0VRKHV0aWw6OmVycm9yOjpJTlRFUk5BTCwgc3RhdHVzLmVycm9yX2NvZGUoKSk7Cit9CisKK2NsYXNzIFByb3Rvc3RyZWFtT2JqZWN0U291cmNlU3RydWN0VGVzdCA6IHB1YmxpYyBQcm90b3N0cmVhbU9iamVjdFNvdXJjZVRlc3QgeworIHByb3RlY3RlZDoKKyAgUHJvdG9zdHJlYW1PYmplY3RTb3VyY2VTdHJ1Y3RUZXN0KCkgeworICAgIGhlbHBlcl8uUmVzZXRUeXBlSW5mbyhTdHJ1Y3RUeXBlOjpkZXNjcmlwdG9yKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgIGdvb2dsZTo6cHJvdG9idWY6OlN0cnVjdDo6ZGVzY3JpcHRvcigpKTsKKyAgfQorfTsKKworSU5TVEFOVElBVEVfVEVTVF9DQVNFX1AoRGlmZmVyZW50VHlwZUluZm9Tb3VyY2VUZXN0LAorICAgICAgICAgICAgICAgICAgICAgICAgUHJvdG9zdHJlYW1PYmplY3RTb3VyY2VTdHJ1Y3RUZXN0LAorICAgICAgICAgICAgICAgICAgICAgICAgOjp0ZXN0aW5nOjpWYWx1ZXMoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVzdGluZzo6VVNFX1RZUEVfUkVTT0xWRVIpKTsKKworLy8gVGVzdHMgc3RydWN0CisvLworLy8gICJvYmplY3QiOiB7CisvLyAgICAiazEiOiAxMjMsCisvLyAgICAiazIiOiB0cnVlCisvLyAgfQorVEVTVF9QKFByb3Rvc3RyZWFtT2JqZWN0U291cmNlU3RydWN0VGVzdCwgU3RydWN0UmVuZGVyU3VjY2VzcykgeworICBTdHJ1Y3RUeXBlIG91dDsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6U3RydWN0KiBzID0gb3V0Lm11dGFibGVfb2JqZWN0KCk7CisgIHMtPm11dGFibGVfZmllbGRzKCktPm9wZXJhdG9yW10oImsxIikuc2V0X251bWJlcl92YWx1ZSgxMjMpOworICBzLT5tdXRhYmxlX2ZpZWxkcygpLT5vcGVyYXRvcltdKCJrMiIpLnNldF9ib29sX3ZhbHVlKHRydWUpOworCisgIG93Xy5TdGFydE9iamVjdCgiIikKKyAgICAgIC0+U3RhcnRPYmplY3QoIm9iamVjdCIpCisgICAgICAtPlJlbmRlckRvdWJsZSgiazEiLCAxMjMpCisgICAgICAtPlJlbmRlckJvb2woImsyIiwgdHJ1ZSkKKyAgICAgIC0+RW5kT2JqZWN0KCkKKyAgICAgIC0+RW5kT2JqZWN0KCk7CisKKyAgRG9UZXN0KG91dCwgU3RydWN0VHlwZTo6ZGVzY3JpcHRvcigpKTsKK30KKworVEVTVF9QKFByb3Rvc3RyZWFtT2JqZWN0U291cmNlU3RydWN0VGVzdCwgTWlzc2luZ1ZhbHVlU2tpcHNGaWVsZCkgeworICBTdHJ1Y3RUeXBlIG91dDsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6U3RydWN0KiBzID0gb3V0Lm11dGFibGVfb2JqZWN0KCk7CisgIHMtPm11dGFibGVfZmllbGRzKCktPm9wZXJhdG9yW10oImsxIik7CisKKyAgb3dfLlN0YXJ0T2JqZWN0KCIiKS0+U3RhcnRPYmplY3QoIm9iamVjdCIpLT5FbmRPYmplY3QoKS0+RW5kT2JqZWN0KCk7CisKKyAgRG9UZXN0KG91dCwgU3RydWN0VHlwZTo6ZGVzY3JpcHRvcigpKTsKK30KKworY2xhc3MgUHJvdG9zdHJlYW1PYmplY3RTb3VyY2VGaWVsZE1hc2tUZXN0CisgICAgOiBwdWJsaWMgUHJvdG9zdHJlYW1PYmplY3RTb3VyY2VUZXN0IHsKKyBwcm90ZWN0ZWQ6CisgIFByb3Rvc3RyZWFtT2JqZWN0U291cmNlRmllbGRNYXNrVGVzdCgpIHsKKyAgICBoZWxwZXJfLlJlc2V0VHlwZUluZm8oRmllbGRNYXNrVGVzdDo6ZGVzY3JpcHRvcigpLAorICAgICAgICAgICAgICAgICAgICAgICAgICBnb29nbGU6OnByb3RvYnVmOjpGaWVsZE1hc2s6OmRlc2NyaXB0b3IoKSk7CisgIH0KK307CisKK0lOU1RBTlRJQVRFX1RFU1RfQ0FTRV9QKERpZmZlcmVudFR5cGVJbmZvU291cmNlVGVzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgIFByb3Rvc3RyZWFtT2JqZWN0U291cmNlRmllbGRNYXNrVGVzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgIDo6dGVzdGluZzo6VmFsdWVzKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlc3Rpbmc6OlVTRV9UWVBFX1JFU09MVkVSKSk7CisKK1RFU1RfUChQcm90b3N0cmVhbU9iamVjdFNvdXJjZUZpZWxkTWFza1Rlc3QsIEZpZWxkTWFza1JlbmRlclN1Y2Nlc3MpIHsKKyAgRmllbGRNYXNrVGVzdCBvdXQ7CisgIG91dC5zZXRfaWQoIjEiKTsKKyAgb3V0Lm11dGFibGVfc2luZ2xlX21hc2soKS0+YWRkX3BhdGhzKCJwYXRoMSIpOworICBvdXQubXV0YWJsZV9zaW5nbGVfbWFzaygpLT5hZGRfcGF0aHMoInNuYWtlX2Nhc2VfcGF0aDIiKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpGaWVsZE1hc2sqIG1hc2sgPSBvdXQuYWRkX3JlcGVhdGVkX21hc2soKTsKKyAgbWFzay0+YWRkX3BhdGhzKCJwYXRoMyIpOworICBtYXNrID0gb3V0LmFkZF9yZXBlYXRlZF9tYXNrKCk7CisgIG1hc2stPmFkZF9wYXRocygic25ha2VfY2FzZV9wYXRoNCIpOworICBtYXNrLT5hZGRfcGF0aHMoInBhdGg1Iik7CisgIE5lc3RlZEZpZWxkTWFzayogbmVzdGVkID0gb3V0LmFkZF9uZXN0ZWRfbWFzaygpOworICBuZXN0ZWQtPnNldF9kYXRhKCJkYXRhIik7CisgIG5lc3RlZC0+bXV0YWJsZV9zaW5nbGVfbWFzaygpLT5hZGRfcGF0aHMoIm5lc3RlZC5wYXRoMSIpOworICBuZXN0ZWQtPm11dGFibGVfc2luZ2xlX21hc2soKS0+YWRkX3BhdGhzKCJuZXN0ZWRfZmllbGQuc25ha2VfY2FzZV9wYXRoMiIpOworICBtYXNrID0gbmVzdGVkLT5hZGRfcmVwZWF0ZWRfbWFzaygpOworICBtYXNrLT5hZGRfcGF0aHMoIm5lc3RlZF9maWVsZC5wYXRoMyIpOworICBtYXNrLT5hZGRfcGF0aHMoIm5lc3RlZC5zbmFrZV9jYXNlX3BhdGg0Iik7CisgIG1hc2sgPSBuZXN0ZWQtPmFkZF9yZXBlYXRlZF9tYXNrKCk7CisgIG1hc2stPmFkZF9wYXRocygibmVzdGVkLnBhdGg1Iik7CisgIG1hc2sgPSBuZXN0ZWQtPmFkZF9yZXBlYXRlZF9tYXNrKCk7CisgIG1hc2stPmFkZF9wYXRocygKKyAgICAgICJzbmFrZV9jYXNlLm1hcF9maWVsZFtcIm1hcF9rZXlfc2hvdWxkX2JlX2lnbm9yZWRcIl0ubmVzdGVkX3NuYWtlX2Nhc2UuIgorICAgICAgIm1hcF9maWVsZFtcIm1hcF9rZXlfc2hvXFxcInVsZF9iZV9pZ25vcmVkXCJdIik7CisKKyAgb3dfLlN0YXJ0T2JqZWN0KCIiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoImlkIiwgIjEiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoInNpbmdsZU1hc2siLCAicGF0aDEsc25ha2VDYXNlUGF0aDIiKQorICAgICAgLT5TdGFydExpc3QoInJlcGVhdGVkTWFzayIpCisgICAgICAtPlJlbmRlclN0cmluZygiIiwgInBhdGgzIikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCIiLCAic25ha2VDYXNlUGF0aDQscGF0aDUiKQorICAgICAgLT5FbmRMaXN0KCkKKyAgICAgIC0+U3RhcnRMaXN0KCJuZXN0ZWRNYXNrIikKKyAgICAgIC0+U3RhcnRPYmplY3QoIiIpCisgICAgICAtPlJlbmRlclN0cmluZygiZGF0YSIsICJkYXRhIikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJzaW5nbGVNYXNrIiwgIm5lc3RlZC5wYXRoMSxuZXN0ZWRGaWVsZC5zbmFrZUNhc2VQYXRoMiIpCisgICAgICAtPlN0YXJ0TGlzdCgicmVwZWF0ZWRNYXNrIikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCIiLCAibmVzdGVkRmllbGQucGF0aDMsbmVzdGVkLnNuYWtlQ2FzZVBhdGg0IikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCIiLCAibmVzdGVkLnBhdGg1IikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCIiLAorICAgICAgICAgICAgICAgICAgICAgInNuYWtlQ2FzZS5tYXBGaWVsZFtcIm1hcF9rZXlfc2hvdWxkX2JlX2lnbm9yZWRcIl0uIgorICAgICAgICAgICAgICAgICAgICAgIm5lc3RlZFNuYWtlQ2FzZS5tYXBGaWVsZFtcIm1hcF9rZXlfc2hvXFxcInVsZF9iZV8iCisgICAgICAgICAgICAgICAgICAgICAiaWdub3JlZFwiXSIpCisgICAgICAtPkVuZExpc3QoKQorICAgICAgLT5FbmRPYmplY3QoKQorICAgICAgLT5FbmRMaXN0KCkKKyAgICAgIC0+RW5kT2JqZWN0KCk7CisKKyAgRG9UZXN0KG91dCwgRmllbGRNYXNrVGVzdDo6ZGVzY3JpcHRvcigpKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIGNvbnZlcnRlcgorfSAgLy8gbmFtZXNwYWNlIHV0aWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3Byb3Rvc3RyZWFtX29iamVjdHdyaXRlci5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9wcm90b3N0cmVhbV9vYmplY3R3cml0ZXIuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzg2YmYwYgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9wcm90b3N0cmVhbV9vYmplY3R3cml0ZXIuY2MKQEAgLTAsMCArMSwxMTMzIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3Byb3Rvc3RyZWFtX29iamVjdHdyaXRlci5oPgorCisjaW5jbHVkZSA8ZnVuY3Rpb25hbD4KKyNpbmNsdWRlIDxzdGFjaz4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9vbmNlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3RpbWUuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL2ZpZWxkX21hc2tfdXRpbGl0eS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL29iamVjdF9sb2NhdGlvbl90cmFja2VyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvY29uc3RhbnRzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvdXRpbGl0eS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJ1dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL21hcF91dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0YXR1c29yLmg+CisKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIHV0aWwgeworbmFtZXNwYWNlIGNvbnZlcnRlciB7CisKK3VzaW5nIGdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTsKK3VzaW5nIHV0aWw6OmVycm9yOjpJTlZBTElEX0FSR1VNRU5UOwordXNpbmcgdXRpbDo6U3RhdHVzOwordXNpbmcgdXRpbDo6U3RhdHVzT3I7CisKKworUHJvdG9TdHJlYW1PYmplY3RXcml0ZXI6OlByb3RvU3RyZWFtT2JqZWN0V3JpdGVyKAorICAgIFR5cGVSZXNvbHZlciogdHlwZV9yZXNvbHZlciwgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6VHlwZSYgdHlwZSwKKyAgICBzdHJpbmdzOjpCeXRlU2luayogb3V0cHV0LCBFcnJvckxpc3RlbmVyKiBsaXN0ZW5lcikKKyAgICA6IFByb3RvV3JpdGVyKHR5cGVfcmVzb2x2ZXIsIHR5cGUsIG91dHB1dCwgbGlzdGVuZXIpLAorICAgICAgbWFzdGVyX3R5cGVfKHR5cGUpLAorICAgICAgY3VycmVudF8oTlVMTCkge30KKworUHJvdG9TdHJlYW1PYmplY3RXcml0ZXI6OlByb3RvU3RyZWFtT2JqZWN0V3JpdGVyKAorICAgIGNvbnN0IFR5cGVJbmZvKiB0eXBlaW5mbywgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6VHlwZSYgdHlwZSwKKyAgICBzdHJpbmdzOjpCeXRlU2luayogb3V0cHV0LCBFcnJvckxpc3RlbmVyKiBsaXN0ZW5lcikKKyAgICA6IFByb3RvV3JpdGVyKHR5cGVpbmZvLCB0eXBlLCBvdXRwdXQsIGxpc3RlbmVyKSwKKyAgICAgIG1hc3Rlcl90eXBlXyh0eXBlKSwKKyAgICAgIGN1cnJlbnRfKE5VTEwpIHt9CisKK1Byb3RvU3RyZWFtT2JqZWN0V3JpdGVyOjp+UHJvdG9TdHJlYW1PYmplY3RXcml0ZXIoKSB7CisgIGlmIChjdXJyZW50XyA9PSBOVUxMKSByZXR1cm47CisgIC8vIENsZWFudXAgZXhwbGljaXRseSBpbiBvcmRlciB0byBhdm9pZCBkZXN0cnVjdG9yIHN0YWNrIG92ZXJmbG93IHdoZW4gaW5wdXQKKyAgLy8gaXMgZGVlcGx5IG5lc3RlZC4KKyAgLy8gQ2FzdCB0byBCYXNlRWxlbWVudCB0byBhdm9pZCBkb2luZyBhZGRpdGlvbmFsIGNoZWNrcyAobGlrZSBtaXNzaW5nIGZpZWxkcykKKyAgLy8gZHVyaW5nIHBvcCgpLgorICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPEJhc2VFbGVtZW50PiBlbGVtZW50KAorICAgICAgc3RhdGljX2Nhc3Q8QmFzZUVsZW1lbnQqPihjdXJyZW50Xy5nZXQoKSktPnBvcDxCYXNlRWxlbWVudD4oKSk7CisgIHdoaWxlIChlbGVtZW50ICE9IE5VTEwpIHsKKyAgICBlbGVtZW50LnJlc2V0KGVsZW1lbnQtPnBvcDxCYXNlRWxlbWVudD4oKSk7CisgIH0KK30KKworbmFtZXNwYWNlIHsKKy8vIFV0aWxpdHkgbWV0aG9kIHRvIHNwbGl0IGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIFRpbWVzdGFtcCBvciBEdXJhdGlvbiBhbmQKKy8vIHJldHVybiB0aGUgcGFydHMuCit2b2lkIFNwbGl0U2Vjb25kc0FuZE5hbm9zKFN0cmluZ1BpZWNlIGlucHV0LCBTdHJpbmdQaWVjZSogc2Vjb25kcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UqIG5hbm9zKSB7CisgIHNpemVfdCBpZHggPSBpbnB1dC5yZmluZCgnLicpOworICBpZiAoaWR4ICE9IHN0cmluZzo6bnBvcykgeworICAgICpzZWNvbmRzID0gaW5wdXQuc3Vic3RyKDAsIGlkeCk7CisgICAgKm5hbm9zID0gaW5wdXQuc3Vic3RyKGlkeCArIDEpOworICB9IGVsc2UgeworICAgICpzZWNvbmRzID0gaW5wdXQ7CisgICAgKm5hbm9zID0gU3RyaW5nUGllY2UoKTsKKyAgfQorfQorCitTdGF0dXMgR2V0TmFub3NGcm9tU3RyaW5nUGllY2UoU3RyaW5nUGllY2Ugc19uYW5vcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiBwYXJzZV9mYWlsdXJlX21lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogZXhjZWVkZWRfbGltaXRfbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMiogbmFub3MpIHsKKyAgKm5hbm9zID0gMDsKKworICAvLyBDb3VudCB0aGUgbnVtYmVyIG9mIGxlYWRpbmcgMHMgYW5kIGNvbnN1bWUgdGhlbS4KKyAgaW50IG51bV9sZWFkaW5nX3plcm9zID0gMDsKKyAgd2hpbGUgKHNfbmFub3MuQ29uc3VtZSgiMCIpKSB7CisgICAgbnVtX2xlYWRpbmdfemVyb3MrKzsKKyAgfQorICBpbnQzMiBpX25hbm9zID0gMDsKKyAgLy8gJ3NfbmFub3MnIGNvbnRhaW5zIGZyYWN0aW9uYWwgc2Vjb25kcyAtLSBpLmUuICduYW5vcycgaXMgZXF1YWwgdG8KKyAgLy8gIjAuIiArIHNfbmFub3MuVG9TdHJpbmcoKSBzZWNvbmRzLiBBbiBpbnQzMiBpcyB1c2VkIGZvciB0aGUKKyAgLy8gY29udmVyc2lvbiB0byAnbmFub3MnLCByYXRoZXIgdGhhbiBhIGRvdWJsZSwgc28gdGhhdCB0aGVyZSBpcyBubworICAvLyBsb3NzIG9mIHByZWNpc2lvbi4KKyAgaWYgKCFzX25hbm9zLmVtcHR5KCkgJiYgIXNhZmVfc3RydG8zMihzX25hbm9zLlRvU3RyaW5nKCksICZpX25hbm9zKSkgeworICAgIHJldHVybiBTdGF0dXMoSU5WQUxJRF9BUkdVTUVOVCwgcGFyc2VfZmFpbHVyZV9tZXNzYWdlKTsKKyAgfQorICBpZiAoaV9uYW5vcyA+IGtOYW5vc1BlclNlY29uZCB8fCBpX25hbm9zIDwgMCkgeworICAgIHJldHVybiBTdGF0dXMoSU5WQUxJRF9BUkdVTUVOVCwgZXhjZWVkZWRfbGltaXRfbWVzc2FnZSk7CisgIH0KKyAgLy8gc19uYW5vcyBzaG91bGQgb25seSBoYXZlIGRpZ2l0cy4gTm8gd2hpdGVzcGFjZS4KKyAgaWYgKHNfbmFub3MuZmluZF9maXJzdF9ub3Rfb2YoIjAxMjM0NTY3ODkiKSAhPSBTdHJpbmdQaWVjZTo6bnBvcykgeworICAgIHJldHVybiBTdGF0dXMoSU5WQUxJRF9BUkdVTUVOVCwgcGFyc2VfZmFpbHVyZV9tZXNzYWdlKTsKKyAgfQorCisgIGlmIChpX25hbm9zID4gMCkgeworICAgIC8vICdzY2FsZScgaXMgdGhlIG51bWJlciBvZiBkaWdpdHMgdG8gdGhlIHJpZ2h0IG9mIHRoZSBkZWNpbWFsCisgICAgLy8gcG9pbnQgaW4gIjAuIiArIHNfbmFub3MuVG9TdHJpbmcoKQorICAgIGludDMyIHNjYWxlID0gbnVtX2xlYWRpbmdfemVyb3MgKyBzX25hbm9zLnNpemUoKTsKKyAgICAvLyAnY29udmVyc2lvbicgY29udmVydHMgaV9uYW5vcyBpbnRvIG5hbm9zZWNvbmRzLgorICAgIC8vIGNvbnZlcnNpb24gPSBrTmFub3NQZXJTZWNvbmQgLyBzdGF0aWNfY2FzdDxpbnQzMj4oc3RkOjpwb3coMTAsIHNjYWxlKSkKKyAgICAvLyBGb3IgZWZmaWNpZW5jeSwgd2UgcHJlY29tcHV0ZSB0aGUgY29udmVyc2lvbiBmYWN0b3IuCisgICAgaW50MzIgY29udmVyc2lvbiA9IDA7CisgICAgc3dpdGNoIChzY2FsZSkgeworICAgICAgY2FzZSAxOgorICAgICAgICBjb252ZXJzaW9uID0gMTAwMDAwMDAwOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgMjoKKyAgICAgICAgY29udmVyc2lvbiA9IDEwMDAwMDAwOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgMzoKKyAgICAgICAgY29udmVyc2lvbiA9IDEwMDAwMDA7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSA0OgorICAgICAgICBjb252ZXJzaW9uID0gMTAwMDAwOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgNToKKyAgICAgICAgY29udmVyc2lvbiA9IDEwMDAwOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgNjoKKyAgICAgICAgY29udmVyc2lvbiA9IDEwMDA7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSA3OgorICAgICAgICBjb252ZXJzaW9uID0gMTAwOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgODoKKyAgICAgICAgY29udmVyc2lvbiA9IDEwOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgOToKKyAgICAgICAgY29udmVyc2lvbiA9IDE7CisgICAgICAgIGJyZWFrOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgcmV0dXJuIFN0YXR1cyhJTlZBTElEX0FSR1VNRU5ULCBleGNlZWRlZF9saW1pdF9tZXNzYWdlKTsKKyAgICB9CisgICAgKm5hbm9zID0gaV9uYW5vcyAqIGNvbnZlcnNpb247CisgIH0KKworICByZXR1cm4gU3RhdHVzOjpPSzsKK30KKworfSAgLy8gbmFtZXNwYWNlCisKK1Byb3RvU3RyZWFtT2JqZWN0V3JpdGVyOjpBbnlXcml0ZXI6OkFueVdyaXRlcihQcm90b1N0cmVhbU9iamVjdFdyaXRlciogcGFyZW50KQorICAgIDogcGFyZW50XyhwYXJlbnQpLAorICAgICAgb3dfKCksCisgICAgICBpbnZhbGlkXyhmYWxzZSksCisgICAgICBkYXRhXygpLAorICAgICAgb3V0cHV0XygmZGF0YV8pLAorICAgICAgZGVwdGhfKDApLAorICAgICAgaGFzX2luamVjdGVkX3ZhbHVlX21lc3NhZ2VfKGZhbHNlKSB7fQorCitQcm90b1N0cmVhbU9iamVjdFdyaXRlcjo6QW55V3JpdGVyOjp+QW55V3JpdGVyKCkge30KKwordm9pZCBQcm90b1N0cmVhbU9iamVjdFdyaXRlcjo6QW55V3JpdGVyOjpTdGFydE9iamVjdChTdHJpbmdQaWVjZSBuYW1lKSB7CisgICsrZGVwdGhfOworICAvLyBJZiBhbiBvYmplY3Qgd3JpdGVyIGlzIGFic2VudCwgdGhhdCBtZWFucyB3ZSBoYXZlIG5vdCBjYWxsZWQgU3RhcnRBbnkoKQorICAvLyBiZWZvcmUgcmVhY2hpbmcgaGVyZS4gVGhpcyBpcyBhbiBpbnZhbGlkIHN0YXRlLiBTdGFydEFueSgpIGdldHMgY2FsbGVkCisgIC8vIHdoZW5ldmVyIHdlIHNlZSBhbiAiQHR5cGUiIGJlaW5nIHJlbmRlcmVkIChzZWUgQW55V3JpdGVyOjpSZW5kZXJEYXRhUGllY2UpLgorICBpZiAob3dfID09IE5VTEwpIHsKKyAgICAvLyBNYWtlIHN1cmUgd2UgYXJlIG5vdCBhbHJlYWR5IGluIGFuIGludmFsaWQgc3RhdGUuIFRoaXMgYXZvaWRzIG1ha2luZworICAgIC8vIG11bHRpcGxlIHVubmVjZXNzYXJ5IEludmFsaWRWYWx1ZSBjYWxscy4KKyAgICBpZiAoIWludmFsaWRfKSB7CisgICAgICBwYXJlbnRfLT5JbnZhbGlkVmFsdWUoIkFueSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyQ2F0KCJNaXNzaW5nIG9yIGludmFsaWQgQHR5cGUgZm9yIGFueSBmaWVsZCBpbiAiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnRfLT5tYXN0ZXJfdHlwZV8ubmFtZSgpKSk7CisgICAgICBpbnZhbGlkXyA9IHRydWU7CisgICAgfQorICB9IGVsc2UgaWYgKCFoYXNfaW5qZWN0ZWRfdmFsdWVfbWVzc2FnZV8gfHwgZGVwdGhfICE9IDEgfHwgbmFtZSAhPSAidmFsdWUiKSB7CisgICAgLy8gV2UgZG9uJ3QgcHJvcGFnYXRlIHRvIG93XyBTdGFydE9iamVjdCgidmFsdWUiKSBjYWxscyBmb3IgbmVzdGVkIEFueXMgb3IKKyAgICAvLyBTdHJ1Y3QgYXQgZGVwdGggMSBhcyB0aGV5IGFyZSBuZXN0ZWQgb25lIGxldmVsIGRlZXAgd2l0aCBhbiBpbmplY3RlZAorICAgIC8vICJ2YWx1ZSIgZmllbGQuCisgICAgb3dfLT5TdGFydE9iamVjdChuYW1lKTsKKyAgfQorfQorCitib29sIFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyOjpBbnlXcml0ZXI6OkVuZE9iamVjdCgpIHsKKyAgLS1kZXB0aF87CisgIC8vIEFzIGxvbmcgYXMgZGVwdGhfID49IDAsIHdlIGtub3cgd2UgaGF2ZW4ndCByZWFjaGVkIHRoZSBlbmQgb2YgQW55LgorICAvLyBQcm9wYWdhdGUgdGhlc2UgRW5kT2JqZWN0KCkgY2FsbHMgdG8gdGhlIGNvbnRhaW5lZCBvd18uICBJZiB3ZSBhcmUgaW4gYQorICAvLyBuZXN0ZWQgQW55IG9yIFN0cnVjdCB0eXBlLCBpZ25vcmUgdGhlIHNlY29uZCB0byBsYXN0IEVuZE9iamVjdCBjYWxsIChkZXB0aF8KKyAgLy8gPT0gLTEpCisgIGlmIChvd18gIT0gTlVMTCAmJiAoIWhhc19pbmplY3RlZF92YWx1ZV9tZXNzYWdlXyB8fCBkZXB0aF8gPj0gMCkpIHsKKyAgICBvd18tPkVuZE9iamVjdCgpOworICB9CisgIC8vIEEgbmVnYXRpdmUgZGVwdGhfIGltcGxpZXMgdGhhdCB3ZSBoYXZlIHJlYWNoZWQgdGhlIGVuZCBvZiBBbnkKKyAgLy8gb2JqZWN0LiBOb3cgd2Ugd3JpdGUgb3V0IGl0cyBjb250ZW50cy4KKyAgaWYgKGRlcHRoXyA8IDApIHsKKyAgICBXcml0ZUFueSgpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICByZXR1cm4gdHJ1ZTsKK30KKwordm9pZCBQcm90b1N0cmVhbU9iamVjdFdyaXRlcjo6QW55V3JpdGVyOjpTdGFydExpc3QoU3RyaW5nUGllY2UgbmFtZSkgeworICArK2RlcHRoXzsKKyAgLy8gV2UgZXhwZWN0IG93XyB0byBiZSBwcmVzZW50IGFzIHRoaXMgY2FsbCBvbmx5IG1ha2VzIHNlbnNlIGluc2lkZSBhbiBBbnkuCisgIGlmIChvd18gPT0gTlVMTCkgeworICAgIGlmICghaW52YWxpZF8pIHsKKyAgICAgIHBhcmVudF8tPkludmFsaWRWYWx1ZSgiQW55IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJDYXQoIk1pc3Npbmcgb3IgaW52YWxpZCBAdHlwZSBmb3IgYW55IGZpZWxkIGluICIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudF8tPm1hc3Rlcl90eXBlXy5uYW1lKCkpKTsKKyAgICAgIGludmFsaWRfID0gdHJ1ZTsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgb3dfLT5TdGFydExpc3QobmFtZSk7CisgIH0KK30KKwordm9pZCBQcm90b1N0cmVhbU9iamVjdFdyaXRlcjo6QW55V3JpdGVyOjpFbmRMaXN0KCkgeworICAtLWRlcHRoXzsKKyAgaWYgKGRlcHRoXyA8IDApIHsKKyAgICBHT09HTEVfTE9HKERGQVRBTCkgPDwgIk1pc21hdGNoZWQgRW5kTGlzdCBmb3VuZCwgc2hvdWxkIG5vdCBiZSBwb3NzaWJsZSI7CisgICAgZGVwdGhfID0gMDsKKyAgfQorICAvLyBXZSBkb24ndCB3cml0ZSBhbiBlcnJvciBvbiB0aGUgY2xvc2UsIG9ubHkgb24gdGhlIG9wZW4KKyAgaWYgKG93XyAhPSBOVUxMKSB7CisgICAgb3dfLT5FbmRMaXN0KCk7CisgIH0KK30KKwordm9pZCBQcm90b1N0cmVhbU9iamVjdFdyaXRlcjo6QW55V3JpdGVyOjpSZW5kZXJEYXRhUGllY2UoCisgICAgU3RyaW5nUGllY2UgbmFtZSwgY29uc3QgRGF0YVBpZWNlJiB2YWx1ZSkgeworICAvLyBTdGFydCBhbiBBbnkgb25seSBhdCBkZXB0aF8gMC4gT3RoZXIgUmVuZGVyRGF0YVBpZWNlIGNhbGxzIHdpdGggIkB0eXBlIgorICAvLyBzaG91bGQgZ28gdG8gdGhlIGNvbnRhaW5lZCBvd18gYXMgdGhleSBpbmRpY2F0ZSBuZXN0ZWQgQW55cy4KKyAgaWYgKGRlcHRoXyA9PSAwICYmIG93XyA9PSBOVUxMICYmIG5hbWUgPT0gIkB0eXBlIikgeworICAgIFN0YXJ0QW55KHZhbHVlKTsKKyAgfSBlbHNlIGlmIChvd18gPT0gTlVMTCkgeworICAgIGlmICghaW52YWxpZF8pIHsKKyAgICAgIHBhcmVudF8tPkludmFsaWRWYWx1ZSgiQW55IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJDYXQoIk1pc3Npbmcgb3IgaW52YWxpZCBAdHlwZSBmb3IgYW55IGZpZWxkIGluICIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudF8tPm1hc3Rlcl90eXBlXy5uYW1lKCkpKTsKKyAgICAgIGludmFsaWRfID0gdHJ1ZTsKKyAgICB9CisgIH0gZWxzZSB7CisgICAgLy8gQ2hlY2sgdG8gc2VlIGlmIHRoZSBkYXRhIG5lZWRzIHRvIGJlIHJlbmRlcmVkIHdpdGggd2VsbC1rbm93bi10eXBlCisgICAgLy8gcmVuZGVyZXIuCisgICAgY29uc3QgVHlwZVJlbmRlcmVyKiB0eXBlX3JlbmRlcmVyID0KKyAgICAgICAgRmluZFR5cGVSZW5kZXJlcihHZXRGdWxsVHlwZVdpdGhVcmwob3dfLT5tYXN0ZXJfdHlwZV8ubmFtZSgpKSk7CisgICAgaWYgKHR5cGVfcmVuZGVyZXIpIHsKKyAgICAgIFN0YXR1cyBzdGF0dXMgPSAoKnR5cGVfcmVuZGVyZXIpKG93Xy5nZXQoKSwgdmFsdWUpOworICAgICAgaWYgKCFzdGF0dXMub2soKSkgb3dfLT5JbnZhbGlkVmFsdWUoIkFueSIsIHN0YXR1cy5lcnJvcl9tZXNzYWdlKCkpOworICAgIH0gZWxzZSB7CisgICAgICBvd18tPlJlbmRlckRhdGFQaWVjZShuYW1lLCB2YWx1ZSk7CisgICAgfQorICB9Cit9CisKK3ZvaWQgUHJvdG9TdHJlYW1PYmplY3RXcml0ZXI6OkFueVdyaXRlcjo6U3RhcnRBbnkoY29uc3QgRGF0YVBpZWNlJiB2YWx1ZSkgeworICAvLyBGaWd1cmUgb3V0IHRoZSB0eXBlIHVybC4gVGhpcyBpcyBhIGNvcHktcGFzdGUgZnJvbSBXcml0ZVN0cmluZyBidXQgd2UgYWxzbworICAvLyBuZWVkIHRoZSB2YWx1ZSwgc28gd2UgY2FuJ3QganVzdCBjYWxsIHRocm91Z2ggdG8gdGhhdC4KKyAgaWYgKHZhbHVlLnR5cGUoKSA9PSBEYXRhUGllY2U6OlRZUEVfU1RSSU5HKSB7CisgICAgdHlwZV91cmxfID0gdmFsdWUuc3RyKCkuVG9TdHJpbmcoKTsKKyAgfSBlbHNlIHsKKyAgICBTdGF0dXNPcjxzdHJpbmc+IHMgPSB2YWx1ZS5Ub1N0cmluZygpOworICAgIGlmICghcy5vaygpKSB7CisgICAgICBwYXJlbnRfLT5JbnZhbGlkVmFsdWUoIlN0cmluZyIsIHMuc3RhdHVzKCkuZXJyb3JfbWVzc2FnZSgpKTsKKyAgICAgIGludmFsaWRfID0gdHJ1ZTsKKyAgICAgIHJldHVybjsKKyAgICB9CisgICAgdHlwZV91cmxfID0gcy5WYWx1ZU9yRGllKCk7CisgIH0KKyAgLy8gUmVzb2x2ZSB0aGUgdHlwZSB1cmwsIGFuZCByZXBvcnQgYW4gZXJyb3IgaWYgd2UgZmFpbGVkIHRvIHJlc29sdmUgaXQuCisgIFN0YXR1c09yPGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlR5cGUqPiByZXNvbHZlZF90eXBlID0KKyAgICAgIHBhcmVudF8tPnR5cGVpbmZvKCktPlJlc29sdmVUeXBlVXJsKHR5cGVfdXJsXyk7CisgIGlmICghcmVzb2x2ZWRfdHlwZS5vaygpKSB7CisgICAgcGFyZW50Xy0+SW52YWxpZFZhbHVlKCJBbnkiLCByZXNvbHZlZF90eXBlLnN0YXR1cygpLmVycm9yX21lc3NhZ2UoKSk7CisgICAgaW52YWxpZF8gPSB0cnVlOworICAgIHJldHVybjsKKyAgfQorICAvLyBBdCB0aGlzIHBvaW50LCB0eXBlIGlzIG5ldmVyIG51bGwuCisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlR5cGUqIHR5cGUgPSByZXNvbHZlZF90eXBlLlZhbHVlT3JEaWUoKTsKKworICAvLyBJZiB0aGlzIGlzIHRoZSBjYXNlIG9mIGFuIEFueSBpbiBhbiBBbnkgb3IgU3RydWN0IGluIGFuIEFueSwgd2UgbmVlZCB0bworICAvLyBleHBlY3QgYSBTdGFydE9iamVjdCBjYWxsIHdpdGggInZhbHVlIiB3aGlsZSB3ZSdyZSBhdCBkZXB0aF8gMCwgd2hpY2ggd2UKKyAgLy8gc2hvdWxkIGlnbm9yZSAobm90IHByb3BhZ2F0ZSB0byBvdXIgbmVzdGVkIG9iamVjdCB3cml0ZXIpLiBXZSBhbHNvIG5lZWQgdG8KKyAgLy8gaWdub3JlIHRoZSBzZWNvbmQtdG8tbGFzdCBFbmRPYmplY3QgY2FsbCwgYW5kIG5vdCBwcm9wYWdhdGUgdGhhdCBlaXRoZXIuCisgIGlmICh0eXBlLT5uYW1lKCkgPT0ga0FueVR5cGUgfHwgdHlwZS0+bmFtZSgpID09IGtTdHJ1Y3RUeXBlKSB7CisgICAgaGFzX2luamVjdGVkX3ZhbHVlX21lc3NhZ2VfID0gdHJ1ZTsKKyAgfQorCisgIC8vIENyZWF0ZSBvdXIgb2JqZWN0IHdyaXRlciBhbmQgaW5pdGlhbGl6ZSBpdCB3aXRoIHRoZSBmaXJzdCBTdGFydE9iamVjdAorICAvLyBjYWxsLgorICBvd18ucmVzZXQobmV3IFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyKHBhcmVudF8tPnR5cGVpbmZvKCksICp0eXBlLCAmb3V0cHV0XywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnRfLT5saXN0ZW5lcigpKSk7CisgIG93Xy0+U3RhcnRPYmplY3QoIiIpOworfQorCit2b2lkIFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyOjpBbnlXcml0ZXI6OldyaXRlQW55KCkgeworICBpZiAob3dfID09IE5VTEwpIHsKKyAgICAvLyBJZiB3ZSBoYWQgbm8gb2JqZWN0IHdyaXRlciwgd2UgbmV2ZXIgZ290IGFueSBjb250ZW50LCBzbyBqdXN0IHJldHVybgorICAgIC8vIGltbWVkaWF0ZWx5LCB3aGljaCBpcyBlcXVpdmFsZW50IHRvIHdyaXRpbmcgYW4gZW1wdHkgQW55LgorICAgIHJldHVybjsKKyAgfQorICAvLyBSZW5kZXIgdGhlIHR5cGVfdXJsIGFuZCB2YWx1ZSBmaWVsZHMgZGlyZWN0bHkgdG8gdGhlIHN0cmVhbS4KKyAgLy8gdHlwZV91cmwgaGFzIHRhZyAxIGFuZCB2YWx1ZSBoYXMgdGFnIDIuCisgIFdpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZygxLCB0eXBlX3VybF8sIHBhcmVudF8tPnN0cmVhbSgpKTsKKyAgaWYgKCFkYXRhXy5lbXB0eSgpKSB7CisgICAgV2lyZUZvcm1hdExpdGU6OldyaXRlQnl0ZXMoMiwgZGF0YV8sIHBhcmVudF8tPnN0cmVhbSgpKTsKKyAgfQorfQorCitQcm90b1N0cmVhbU9iamVjdFdyaXRlcjo6SXRlbTo6SXRlbShQcm90b1N0cmVhbU9iamVjdFdyaXRlciogZW5jbG9zaW5nLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSXRlbVR5cGUgaXRlbV90eXBlLCBib29sIGlzX3BsYWNlaG9sZGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc19saXN0KQorICAgIDogQmFzZUVsZW1lbnQoTlVMTCksCisgICAgICBvd18oZW5jbG9zaW5nKSwKKyAgICAgIGFueV8oKSwKKyAgICAgIGl0ZW1fdHlwZV8oaXRlbV90eXBlKSwKKyAgICAgIGlzX3BsYWNlaG9sZGVyXyhpc19wbGFjZWhvbGRlciksCisgICAgICBpc19saXN0Xyhpc19saXN0KSB7CisgIGlmIChpdGVtX3R5cGVfID09IEFOWSkgeworICAgIGFueV8ucmVzZXQobmV3IEFueVdyaXRlcihvd18pKTsKKyAgfQorfQorCitQcm90b1N0cmVhbU9iamVjdFdyaXRlcjo6SXRlbTo6SXRlbShQcm90b1N0cmVhbU9iamVjdFdyaXRlcjo6SXRlbSogcGFyZW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSXRlbVR5cGUgaXRlbV90eXBlLCBib29sIGlzX3BsYWNlaG9sZGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc19saXN0KQorICAgIDogQmFzZUVsZW1lbnQocGFyZW50KSwKKyAgICAgIG93Xyh0aGlzLT5wYXJlbnQoKS0+b3dfKSwKKyAgICAgIGFueV8oKSwKKyAgICAgIGl0ZW1fdHlwZV8oaXRlbV90eXBlKSwKKyAgICAgIGlzX3BsYWNlaG9sZGVyXyhpc19wbGFjZWhvbGRlciksCisgICAgICBpc19saXN0Xyhpc19saXN0KSB7CisgIGlmIChpdGVtX3R5cGUgPT0gQU5ZKSB7CisgICAgYW55Xy5yZXNldChuZXcgQW55V3JpdGVyKG93XykpOworICB9Cit9CisKK2Jvb2wgUHJvdG9TdHJlYW1PYmplY3RXcml0ZXI6Okl0ZW06Okluc2VydE1hcEtleUlmTm90UHJlc2VudCgKKyAgICBTdHJpbmdQaWVjZSBtYXBfa2V5KSB7CisgIHJldHVybiBJbnNlcnRJZk5vdFByZXNlbnQoJm1hcF9rZXlzXywgbWFwX2tleS5Ub1N0cmluZygpKTsKK30KKworUHJvdG9TdHJlYW1PYmplY3RXcml0ZXIqIFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyOjpTdGFydE9iamVjdCgKKyAgICBTdHJpbmdQaWVjZSBuYW1lKSB7CisgIGlmIChpbnZhbGlkX2RlcHRoKCkgPiAwKSB7CisgICAgSW5jcmVtZW50SW52YWxpZERlcHRoKCk7CisgICAgcmV0dXJuIHRoaXM7CisgIH0KKworICAvLyBTdGFydGluZyB0aGUgcm9vdCBtZXNzYWdlLiBDcmVhdGUgdGhlIHJvb3QgSXRlbSBhbmQgcmV0dXJuLgorICAvLyBBTlkgbWVzc2FnZSB0eXBlIGRvZXMgbm90IG5lZWQgc3BlY2lhbCBoYW5kbGluZywganVzdCBzZXQgdGhlIEl0ZW1UeXBlCisgIC8vIHRvIEFOWS4KKyAgaWYgKGN1cnJlbnRfID09IE5VTEwpIHsKKyAgICBQcm90b1dyaXRlcjo6U3RhcnRPYmplY3QobmFtZSk7CisgICAgY3VycmVudF8ucmVzZXQobmV3IEl0ZW0oCisgICAgICAgIHRoaXMsIG1hc3Rlcl90eXBlXy5uYW1lKCkgPT0ga0FueVR5cGUgPyBJdGVtOjpBTlkgOiBJdGVtOjpNRVNTQUdFLAorICAgICAgICBmYWxzZSwgZmFsc2UpKTsKKworICAgIC8vIElmIG1hc3RlciB0eXBlIGlzIGEgc3BlY2lhbCB0eXBlIHRoYXQgbmVlZHMgZXh0cmEgdmFsdWVzIHRvIGJlIHdyaXR0ZW4gdG8KKyAgICAvLyBzdHJlYW0sIHdlIHdyaXRlIHRob3NlIHZhbHVlcy4KKyAgICBpZiAobWFzdGVyX3R5cGVfLm5hbWUoKSA9PSBrU3RydWN0VHlwZSkgeworICAgICAgLy8gU3RydWN0IGhhcyBhIG1hcDxzdHJpbmcsIFZhbHVlPiBmaWVsZCBjYWxsZWQgImZpZWxkcyIuCisgICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL3Byb3RvYnVmL2Jsb2IvbWFzdGVyL3NyYy9nb29nbGUvcHJvdG9idWYvc3RydWN0LnByb3RvCisgICAgICAvLyAiZmllbGRzIjogWworICAgICAgUHVzaCgiZmllbGRzIiwgSXRlbTo6TUFQLCB0cnVlLCB0cnVlKTsKKyAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIGlmIChtYXN0ZXJfdHlwZV8ubmFtZSgpID09IGtTdHJ1Y3RWYWx1ZVR5cGUpIHsKKyAgICAgIC8vIFdlIGdvdCBhIFN0YXJ0T2JqZWN0IGNhbGwgd2l0aCBnb29nbGUucHJvdG9idWYuVmFsdWUgZmllbGQuIFRoZSBvbmx5CisgICAgICAvLyBvYmplY3Qgd2l0aGluIHRoYXQgdHlwZSBpcyBhIHN0cnVjdCB0eXBlLiBTbyBzdGFydCBhIHN0cnVjdC4KKyAgICAgIC8vCisgICAgICAvLyBUaGUgc3RydWN0IGZpZWxkIGluIFZhbHVlIHR5cGUgaXMgbmFtZWQgInN0cnVjdF92YWx1ZSIKKyAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvcHJvdG9idWYvYmxvYi9tYXN0ZXIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHJ1Y3QucHJvdG8KKyAgICAgIC8vIEFsc28gc3RhcnQgdGhlIG1hcCBmaWVsZCAiZmllbGRzIiB3aXRoaW4gdGhlIHN0cnVjdC4KKyAgICAgIC8vICJzdHJ1Y3RfdmFsdWUiOiB7CisgICAgICAvLyAgICJmaWVsZHMiOiBbCisgICAgICBQdXNoKCJzdHJ1Y3RfdmFsdWUiLCBJdGVtOjpNRVNTQUdFLCB0cnVlLCBmYWxzZSk7CisgICAgICBQdXNoKCJmaWVsZHMiLCBJdGVtOjpNQVAsIHRydWUsIHRydWUpOworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgaWYgKG1hc3Rlcl90eXBlXy5uYW1lKCkgPT0ga1N0cnVjdExpc3RWYWx1ZVR5cGUpIHsKKyAgICAgIEludmFsaWRWYWx1ZShrU3RydWN0TGlzdFZhbHVlVHlwZSwKKyAgICAgICAgICAgICAgICAgICAiQ2Fubm90IHN0YXJ0IHJvb3QgbWVzc2FnZSB3aXRoIExpc3RWYWx1ZS4iKTsKKyAgICB9CisKKyAgICByZXR1cm4gdGhpczsKKyAgfQorCisgIC8vIFNlbmQgYWxsIEFOWSBldmVudHMgdG8gQW55V3JpdGVyLgorICBpZiAoY3VycmVudF8tPklzQW55KCkpIHsKKyAgICBjdXJyZW50Xy0+YW55KCktPlN0YXJ0T2JqZWN0KG5hbWUpOworICAgIHJldHVybiB0aGlzOworICB9CisKKyAgLy8gSWYgd2UgYXJlIHdpdGhpbiBhIG1hcCwgd2UgcmVuZGVyIG5hbWUgYXMga2V5cyBhbmQgc2VuZCBTdGFydE9iamVjdCB0byB0aGUKKyAgLy8gdmFsdWUgZmllbGQuCisgIGlmIChjdXJyZW50Xy0+SXNNYXAoKSkgeworICAgIGlmICghVmFsaWRNYXBLZXkobmFtZSkpIHsKKyAgICAgIEluY3JlbWVudEludmFsaWREZXB0aCgpOworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLy8gTWFwIGlzIGEgcmVwZWF0ZWQgZmllbGQgb2YgbWVzc2FnZSB0eXBlIHdpdGggYSAia2V5IiBhbmQgYSAidmFsdWUiIGZpZWxkLgorICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvZG9jcy9wcm90bzM/aGw9ZW4jbWFwcworICAgIC8vIG1lc3NhZ2UgTWFwRmllbGRFbnRyeSB7CisgICAgLy8gICBrZXlfdHlwZSBrZXkgPSAxOworICAgIC8vICAgdmFsdWVfdHlwZSB2YWx1ZSA9IDI7CisgICAgLy8gfQorICAgIC8vCisgICAgLy8gcmVwZWF0ZWQgTWFwRmllbGRFbnRyeSBtYXBfZmllbGQgPSBOOworICAgIC8vCisgICAgLy8gVGhhdCBtZWFucywgd2UgcmVuZGVyIHRoZSBmb2xsb3dpbmcgZWxlbWVudCB3aXRoaW4gYSBsaXN0IChoZW5jZSBubworICAgIC8vIG5hbWUpOgorICAgIC8vIHsgImtleSI6ICI8bmFtZT4iLCAidmFsdWUiOiB7CisgICAgUHVzaCgiIiwgSXRlbTo6TUVTU0FHRSwgZmFsc2UsIGZhbHNlKTsKKyAgICBQcm90b1dyaXRlcjo6UmVuZGVyRGF0YVBpZWNlKCJrZXkiLCBEYXRhUGllY2UobmFtZSkpOworICAgIFB1c2goInZhbHVlIiwgSXRlbTo6TUVTU0FHRSwgdHJ1ZSwgZmFsc2UpOworCisgICAgLy8gTWFrZSBzdXJlIHdlIGFyZSB2YWxpZCBzbyBmYXIgYWZ0ZXIgc3RhcnRpbmcgbWFwIGZpZWxkcy4KKyAgICBpZiAoaW52YWxpZF9kZXB0aCgpID4gMCkgcmV0dXJuIHRoaXM7CisKKyAgICAvLyBJZiB0b3Agb2Ygc3RhY2sgaXMgZy5wLlN0cnVjdCB0eXBlLCBzdGFydCB0aGUgc3RydWN0IHRoZSBtYXAgZmllbGQgd2l0aGluCisgICAgLy8gaXQuCisgICAgaWYgKGVsZW1lbnQoKSAhPSBOVUxMICYmIElzU3RydWN0KCplbGVtZW50KCktPnBhcmVudF9maWVsZCgpKSkgeworICAgICAgLy8gUmVuZGVyICJmaWVsZHMiOiBbCisgICAgICBQdXNoKCJmaWVsZHMiLCBJdGVtOjpNQVAsIHRydWUsIHRydWUpOworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLy8gSWYgdG9wIG9mIHN0YWNrIGlzIGcucC5WYWx1ZSB0eXBlLCBzdGFydCB0aGUgU3RydWN0IHdpdGhpbiBpdC4KKyAgICBpZiAoZWxlbWVudCgpICE9IE5VTEwgJiYgSXNTdHJ1Y3RWYWx1ZSgqZWxlbWVudCgpLT5wYXJlbnRfZmllbGQoKSkpIHsKKyAgICAgIC8vIFJlbmRlcgorICAgICAgLy8gInN0cnVjdF92YWx1ZSI6IHsKKyAgICAgIC8vICAgImZpZWxkcyI6IFsKKyAgICAgIFB1c2goInN0cnVjdF92YWx1ZSIsIEl0ZW06Ok1FU1NBR0UsIHRydWUsIGZhbHNlKTsKKyAgICAgIFB1c2goImZpZWxkcyIsIEl0ZW06Ok1BUCwgdHJ1ZSwgdHJ1ZSk7CisgICAgfQorICAgIHJldHVybiB0aGlzOworICB9CisKKyAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGQqIGZpZWxkID0gQmVnaW5OYW1lZChuYW1lLCBmYWxzZSk7CisgIGlmIChmaWVsZCA9PSBOVUxMKSByZXR1cm4gdGhpczsKKworICBpZiAoSXNTdHJ1Y3QoKmZpZWxkKSkgeworICAgIC8vIFN0YXJ0IGEgc3RydWN0IG9iamVjdC4KKyAgICAvLyBSZW5kZXIKKyAgICAvLyAiPG5hbWU+IjogeworICAgIC8vICAgImZpZWxkcyI6IHsKKyAgICBQdXNoKG5hbWUsIEl0ZW06Ok1FU1NBR0UsIGZhbHNlLCBmYWxzZSk7CisgICAgUHVzaCgiZmllbGRzIiwgSXRlbTo6TUFQLCB0cnVlLCB0cnVlKTsKKyAgICByZXR1cm4gdGhpczsKKyAgfQorCisgIGlmIChJc1N0cnVjdFZhbHVlKCpmaWVsZCkpIHsKKyAgICAvLyBXZSBnb3QgYSBTdGFydE9iamVjdCBjYWxsIHdpdGggZ29vZ2xlLnByb3RvYnVmLlZhbHVlIGZpZWxkLiAgVGhlIG9ubHkKKyAgICAvLyBvYmplY3Qgd2l0aGluIHRoYXQgdHlwZSBpcyBhIHN0cnVjdCB0eXBlLiBTbyBzdGFydCBhIHN0cnVjdC4KKyAgICAvLyBSZW5kZXIKKyAgICAvLyAiPG5hbWU+IjogeworICAgIC8vICAgInN0cnVjdF92YWx1ZSI6IHsKKyAgICAvLyAgICAgImZpZWxkcyI6IHsKKyAgICBQdXNoKG5hbWUsIEl0ZW06Ok1FU1NBR0UsIGZhbHNlLCBmYWxzZSk7CisgICAgUHVzaCgic3RydWN0X3ZhbHVlIiwgSXRlbTo6TUVTU0FHRSwgdHJ1ZSwgZmFsc2UpOworICAgIFB1c2goImZpZWxkcyIsIEl0ZW06Ok1BUCwgdHJ1ZSwgdHJ1ZSk7CisgICAgcmV0dXJuIHRoaXM7CisgIH0KKworICBpZiAoSXNNYXAoKmZpZWxkKSkgeworICAgIC8vIEJlZ2luIGEgbWFwLiBBIG1hcCBpcyB0cmlnZ2VyZWQgYnkgYSBTdGFydE9iamVjdCgpIGNhbGwgaWYgdGhlIGN1cnJlbnQKKyAgICAvLyBmaWVsZCBoYXMgYSBtYXAgdHlwZS4KKyAgICAvLyBBIG1hcCB0eXBlIGlzIGFsd2F5cyByZXBlYXRlZCwgaGVuY2Ugc2V0IGlzX2xpc3QgdG8gdHJ1ZS4KKyAgICAvLyBSZW5kZXIKKyAgICAvLyAiPG5hbWU+IjogWworICAgIFB1c2gobmFtZSwgSXRlbTo6TUFQLCBmYWxzZSwgdHJ1ZSk7CisgICAgcmV0dXJuIHRoaXM7CisgIH0KKworICAvLyBBIHJlZ3VsYXIgbWVzc2FnZSB0eXBlLiBQYXNzIGl0IGRpcmVjdGx5IHRvIFByb3RvV3JpdGVyLgorICAvLyBSZW5kZXIKKyAgLy8gIjxuYW1lPiI6IHsKKyAgUHVzaChuYW1lLCBJc0FueSgqZmllbGQpID8gSXRlbTo6QU5ZIDogSXRlbTo6TUVTU0FHRSwgZmFsc2UsIGZhbHNlKTsKKyAgcmV0dXJuIHRoaXM7Cit9CisKK1Byb3RvU3RyZWFtT2JqZWN0V3JpdGVyKiBQcm90b1N0cmVhbU9iamVjdFdyaXRlcjo6RW5kT2JqZWN0KCkgeworICBpZiAoaW52YWxpZF9kZXB0aCgpID4gMCkgeworICAgIERlY3JlbWVudEludmFsaWREZXB0aCgpOworICAgIHJldHVybiB0aGlzOworICB9CisKKyAgaWYgKGN1cnJlbnRfID09IE5VTEwpIHJldHVybiB0aGlzOworCisgIGlmIChjdXJyZW50Xy0+SXNBbnkoKSkgeworICAgIGlmIChjdXJyZW50Xy0+YW55KCktPkVuZE9iamVjdCgpKSByZXR1cm4gdGhpczsKKyAgfQorCisgIFBvcCgpOworCisgIHJldHVybiB0aGlzOworfQorCitQcm90b1N0cmVhbU9iamVjdFdyaXRlciogUHJvdG9TdHJlYW1PYmplY3RXcml0ZXI6OlN0YXJ0TGlzdChTdHJpbmdQaWVjZSBuYW1lKSB7CisgIGlmIChpbnZhbGlkX2RlcHRoKCkgPiAwKSB7CisgICAgSW5jcmVtZW50SW52YWxpZERlcHRoKCk7CisgICAgcmV0dXJuIHRoaXM7CisgIH0KKworICAvLyBTaW5jZSB3ZSBjYW5ub3QgaGF2ZSBhIHRvcC1sZXZlbCByZXBlYXRlZCBpdGVtIGluIHByb3RvYnVmLCB0aGUgb25seSB3YXkKKyAgLy8gdGhpcyBpcyB2YWxpZCBpcyBpZiB3ZSBzdGFydCBhIHNwZWNpYWwgdHlwZSBnb29nbGUucHJvdG9idWYuTGlzdFZhbHVlIG9yCisgIC8vIGdvb2dsZS5wcm90b2J1Zi5WYWx1ZS4KKyAgaWYgKGN1cnJlbnRfID09IE5VTEwpIHsKKyAgICBpZiAoIW5hbWUuZW1wdHkoKSkgeworICAgICAgSW52YWxpZE5hbWUobmFtZSwgIlJvb3QgZWxlbWVudCBzaG91bGQgbm90IGJlIG5hbWVkLiIpOworICAgICAgSW5jcmVtZW50SW52YWxpZERlcHRoKCk7CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvLyBJZiBtYXN0ZXIgdHlwZSBpcyBhIHNwZWNpYWwgdHlwZSB0aGF0IG5lZWRzIGV4dHJhIHZhbHVlcyB0byBiZSB3cml0dGVuIHRvCisgICAgLy8gc3RyZWFtLCB3ZSB3cml0ZSB0aG9zZSB2YWx1ZXMuCisgICAgaWYgKG1hc3Rlcl90eXBlXy5uYW1lKCkgPT0ga1N0cnVjdFZhbHVlVHlwZSkgeworICAgICAgLy8gV2UgZ290IGEgU3RhcnRMaXN0IHdpdGggZ29vZ2xlLnByb3RvYnVmLlZhbHVlIG1hc3RlciB0eXBlLiBUaGlzIG1lYW5zCisgICAgICAvLyB3ZSBoYXZlIHRvIHN0YXJ0IHRoZSAibGlzdF92YWx1ZSIgd2l0aGluIGdvb2dsZS5wcm90b2J1Zi5WYWx1ZS4KKyAgICAgIC8vCisgICAgICAvLyBTZWUKKyAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvcHJvdG9idWYvYmxvYi9tYXN0ZXIvc3JjL2dvb2dsZS9wcm90b2J1Zi9zdHJ1Y3QucHJvdG8KKyAgICAgIC8vCisgICAgICAvLyBSZW5kZXIKKyAgICAgIC8vICI8bmFtZT4iOiB7CisgICAgICAvLyAgICJsaXN0X3ZhbHVlIjogeworICAgICAgLy8gICAgICJ2YWx1ZXMiOiBbICAvLyBTdGFydCB0aGlzIGxpc3QuCisgICAgICBQcm90b1dyaXRlcjo6U3RhcnRPYmplY3QobmFtZSk7CisgICAgICBjdXJyZW50Xy5yZXNldChuZXcgSXRlbSh0aGlzLCBJdGVtOjpNRVNTQUdFLCBmYWxzZSwgZmFsc2UpKTsKKyAgICAgIFB1c2goImxpc3RfdmFsdWUiLCBJdGVtOjpNRVNTQUdFLCB0cnVlLCBmYWxzZSk7CisgICAgICBQdXNoKCJ2YWx1ZXMiLCBJdGVtOjpNRVNTQUdFLCB0cnVlLCB0cnVlKTsKKyAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIGlmIChtYXN0ZXJfdHlwZV8ubmFtZSgpID09IGtTdHJ1Y3RMaXN0VmFsdWVUeXBlKSB7CisgICAgICAvLyBXZSBnb3QgYSBTdGFydExpc3Qgd2l0aCBnb29nbGUucHJvdG9idWYuTGlzdFZhbHVlIG1hc3RlciB0eXBlLiBUaGlzCisgICAgICAvLyBtZWFucyB3ZSBoYXZlIHRvIHN0YXJ0IHRoZSAidmFsdWVzIiB3aXRoaW4gZ29vZ2xlLnByb3RvYnVmLkxpc3RWYWx1ZS4KKyAgICAgIC8vCisgICAgICAvLyBSZW5kZXIKKyAgICAgIC8vICI8bmFtZT4iOiB7CisgICAgICAvLyAgICJ2YWx1ZXMiOiBbICAvLyBTdGFydCB0aGlzIGxpc3QuCisgICAgICBQcm90b1dyaXRlcjo6U3RhcnRPYmplY3QobmFtZSk7CisgICAgICBjdXJyZW50Xy5yZXNldChuZXcgSXRlbSh0aGlzLCBJdGVtOjpNRVNTQUdFLCBmYWxzZSwgZmFsc2UpKTsKKyAgICAgIFB1c2goInZhbHVlcyIsIEl0ZW06Ok1FU1NBR0UsIHRydWUsIHRydWUpOworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLy8gU2VuZCB0aGUgZXZlbnQgdG8gUHJvdG9Xcml0ZXIgc28gcHJvcGVyIGVycm9ycyBjYW4gYmUgcmVwb3J0ZWQuCisgICAgLy8KKyAgICAvLyBSZW5kZXIgYSByZWd1bGFyIGxpc3Q6CisgICAgLy8gIjxuYW1lPiI6IFsKKyAgICBQcm90b1dyaXRlcjo6U3RhcnRMaXN0KG5hbWUpOworICAgIGN1cnJlbnRfLnJlc2V0KG5ldyBJdGVtKHRoaXMsIEl0ZW06Ok1FU1NBR0UsIGZhbHNlLCB0cnVlKSk7CisgICAgcmV0dXJuIHRoaXM7CisgIH0KKworICBpZiAoY3VycmVudF8tPklzQW55KCkpIHsKKyAgICBjdXJyZW50Xy0+YW55KCktPlN0YXJ0TGlzdChuYW1lKTsKKyAgICByZXR1cm4gdGhpczsKKyAgfQorCisgIC8vIElmIHRoZSB0b3Agb2Ygc3RhY2sgaXMgYSBtYXAsIHdlIGFyZSBzdGFydGluZyBhIGxpc3QgdmFsdWUgd2l0aGluIGEgbWFwLgorICAvLyBTaW5jZSBtYXAgZG9lcyBub3QgYWxsb3cgcmVwZWF0ZWQgdmFsdWVzLCB0aGlzIGNhbiBvbmx5IGhhcHBlbiB3aGVuIHRoZSBtYXAKKyAgLy8gdmFsdWUgaXMgb2YgYSBzcGVjaWFsIHR5cGUgdGhhdCByZW5kZXJzIGEgbGlzdCBpbiBKU09OLiAgVGhlc2UgY2FuIGJlIG9uZQorICAvLyBvZiAzIGNhc2VzOgorICAvLyBpLiBXZSBhcmUgcmVuZGVyaW5nIGEgbGlzdCB2YWx1ZSB3aXRoaW4gZ29vZ2xlLnByb3RvYnVmLlN0cnVjdAorICAvLyBpaS4gV2UgYXJlIHJlbmRlcmluZyBhIGxpc3QgdmFsdWUgd2l0aGluIGdvb2dsZS5wcm90b2J1Zi5WYWx1ZQorICAvLyBpaWkuIFdlIGFyZSByZW5kZXJpbmcgYSBsaXN0IHZhbHVlIHdpdGggdHlwZSBnb29nbGUucHJvdG9idWYuTGlzdFZhbHVlLgorICBpZiAoY3VycmVudF8tPklzTWFwKCkpIHsKKyAgICBpZiAoIVZhbGlkTWFwS2V5KG5hbWUpKSB7CisgICAgICBJbmNyZW1lbnRJbnZhbGlkRGVwdGgoKTsKKyAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8vIFN0YXJ0IHRoZSByZXBlYXRlZCBtYXAgZW50cnkgb2JqZWN0LgorICAgIC8vIFJlbmRlcgorICAgIC8vIHsgImtleSI6ICI8bmFtZT4iLCAidmFsdWUiOiB7CisgICAgUHVzaCgiIiwgSXRlbTo6TUVTU0FHRSwgZmFsc2UsIGZhbHNlKTsKKyAgICBQcm90b1dyaXRlcjo6UmVuZGVyRGF0YVBpZWNlKCJrZXkiLCBEYXRhUGllY2UobmFtZSkpOworICAgIFB1c2goInZhbHVlIiwgSXRlbTo6TUVTU0FHRSwgdHJ1ZSwgZmFsc2UpOworCisgICAgLy8gTWFrZSBzdXJlIHdlIGFyZSB2YWxpZCBhZnRlciBwdXNoaW5nIGFsbCBhYm92ZSBpdGVtcy4KKyAgICBpZiAoaW52YWxpZF9kZXB0aCgpID4gMCkgcmV0dXJuIHRoaXM7CisKKyAgICAvLyBjYXNlIGkgYW5kIGlpIGFib3ZlLiBTdGFydCAibGlzdF92YWx1ZSIgZmllbGQgd2l0aGluIGcucC5WYWx1ZQorICAgIGlmIChlbGVtZW50KCkgIT0gTlVMTCAmJiBlbGVtZW50KCktPnBhcmVudF9maWVsZCgpICE9IE5VTEwpIHsKKyAgICAgIC8vIFJlbmRlcgorICAgICAgLy8gImxpc3RfdmFsdWUiOiB7CisgICAgICAvLyAgICJ2YWx1ZXMiOiBbICAvLyBTdGFydCB0aGlzIGxpc3QKKyAgICAgIGlmIChJc1N0cnVjdFZhbHVlKCplbGVtZW50KCktPnBhcmVudF9maWVsZCgpKSkgeworICAgICAgICBQdXNoKCJsaXN0X3ZhbHVlIiwgSXRlbTo6TUVTU0FHRSwgdHJ1ZSwgZmFsc2UpOworICAgICAgICBQdXNoKCJ2YWx1ZXMiLCBJdGVtOjpNRVNTQUdFLCB0cnVlLCB0cnVlKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICB9CisKKyAgICAgIC8vIFJlbmRlcgorICAgICAgLy8gInZhbHVlcyI6IFsKKyAgICAgIGlmIChJc1N0cnVjdExpc3RWYWx1ZSgqZWxlbWVudCgpLT5wYXJlbnRfZmllbGQoKSkpIHsKKyAgICAgICAgLy8gY2FzZSBpaWkgYWJvdmUuIEJpbmQgZGlyZWN0bHkgdG8gZy5wLkxpc3RWYWx1ZQorICAgICAgICBQdXNoKCJ2YWx1ZXMiLCBJdGVtOjpNRVNTQUdFLCB0cnVlLCB0cnVlKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICB9CisgICAgfQorCisgICAgLy8gUmVwb3J0IGFuIGVycm9yLgorICAgIEludmFsaWRWYWx1ZSgiTWFwIiwgU3RyQ2F0KCJDYW5ub3QgaGF2ZSByZXBlYXRlZCBpdGVtcyAoJyIsIG5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIicpIHdpdGhpbiBhIG1hcC4iKSk7CisgICAgcmV0dXJuIHRoaXM7CisgIH0KKworICAvLyBXaGVuIG5hbWUgaXMgZW1wdHkgYW5kIHN0YWNrIGlzIG5vdCBlbXB0eSwgd2UgYXJlIHJlbmRlcmluZyBhbiBpdGVtIHdpdGhpbgorICAvLyBhIGxpc3QuCisgIGlmIChuYW1lLmVtcHR5KCkpIHsKKyAgICBpZiAoZWxlbWVudCgpICE9IE5VTEwgJiYgZWxlbWVudCgpLT5wYXJlbnRfZmllbGQoKSAhPSBOVUxMKSB7CisgICAgICBpZiAoSXNTdHJ1Y3RWYWx1ZSgqZWxlbWVudCgpLT5wYXJlbnRfZmllbGQoKSkpIHsKKyAgICAgICAgLy8gU2luY2UgaXQgaXMgZy5wLlZhbHVlLCB3ZSBiaW5kIGRpcmVjdGx5IHRvIHRoZSBsaXN0X3ZhbHVlLgorICAgICAgICAvLyBSZW5kZXIKKyAgICAgICAgLy8geyAgLy8gZy5wLlZhbHVlIGl0ZW0gd2l0aGluIHRoZSBsaXN0CisgICAgICAgIC8vICAgImxpc3RfdmFsdWUiOiB7CisgICAgICAgIC8vICAgICAidmFsdWVzIjogWworICAgICAgICBQdXNoKCIiLCBJdGVtOjpNRVNTQUdFLCBmYWxzZSwgZmFsc2UpOworICAgICAgICBQdXNoKCJsaXN0X3ZhbHVlIiwgSXRlbTo6TUVTU0FHRSwgdHJ1ZSwgZmFsc2UpOworICAgICAgICBQdXNoKCJ2YWx1ZXMiLCBJdGVtOjpNRVNTQUdFLCB0cnVlLCB0cnVlKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICB9CisKKyAgICAgIGlmIChJc1N0cnVjdExpc3RWYWx1ZSgqZWxlbWVudCgpLT5wYXJlbnRfZmllbGQoKSkpIHsKKyAgICAgICAgLy8gU2luY2UgaXQgaXMgZy5wLkxpc3RWYWx1ZSwgd2UgYmluZCB0byBpdCBkaXJlY3RseS4KKyAgICAgICAgLy8gUmVuZGVyCisgICAgICAgIC8vIHsgIC8vIGcucC5MaXN0VmFsdWUgaXRlbSB3aXRoaW4gdGhlIGxpc3QKKyAgICAgICAgLy8gICAidmFsdWVzIjogWworICAgICAgICBQdXNoKCIiLCBJdGVtOjpNRVNTQUdFLCBmYWxzZSwgZmFsc2UpOworICAgICAgICBQdXNoKCJ2YWx1ZXMiLCBJdGVtOjpNRVNTQUdFLCB0cnVlLCB0cnVlKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICB9CisgICAgfQorCisgICAgLy8gUGFzcyB0aGUgZXZlbnQgdG8gdW5kZXJseWluZyBQcm90b1dyaXRlci4KKyAgICBQdXNoKG5hbWUsIEl0ZW06Ok1FU1NBR0UsIGZhbHNlLCB0cnVlKTsKKyAgICByZXR1cm4gdGhpczsKKyAgfQorCisgIC8vIG5hbWUgaXMgbm90IGVtcHR5CisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkKiBmaWVsZCA9IExvb2t1cChuYW1lKTsKKyAgaWYgKGZpZWxkID09IE5VTEwpIHsKKyAgICBJbmNyZW1lbnRJbnZhbGlkRGVwdGgoKTsKKyAgICByZXR1cm4gdGhpczsKKyAgfQorCisgIGlmIChJc1N0cnVjdFZhbHVlKCpmaWVsZCkpIHsKKyAgICAvLyBJZiBnLnAuVmFsdWUgaXMgcmVwZWF0ZWQsIHN0YXJ0IHRoYXQgbGlzdC4gT3RoZXJ3aXNlLCBzdGFydCB0aGUKKyAgICAvLyAibGlzdF92YWx1ZSIgd2l0aGluIGl0LgorICAgIGlmIChJc1JlcGVhdGVkKCpmaWVsZCkpIHsKKyAgICAgIC8vIFJlbmRlciBpdCBqdXN0IGxpa2UgYSByZWd1bGFyIHJlcGVhdGVkIGZpZWxkLgorICAgICAgLy8gIjxuYW1lPiI6IFsKKyAgICAgIFB1c2gobmFtZSwgSXRlbTo6TUVTU0FHRSwgZmFsc2UsIHRydWUpOworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLy8gU3RhcnQgdGhlICJsaXN0X3ZhbHVlIiBmaWVsZC4KKyAgICAvLyBSZW5kZXIKKyAgICAvLyAiPG5hbWU+IjogeworICAgIC8vICAgImxpc3RfdmFsdWUiOiB7CisgICAgLy8gICAgICJ2YWx1ZXMiOiBbCisgICAgUHVzaChuYW1lLCBJdGVtOjpNRVNTQUdFLCBmYWxzZSwgZmFsc2UpOworICAgIFB1c2goImxpc3RfdmFsdWUiLCBJdGVtOjpNRVNTQUdFLCB0cnVlLCBmYWxzZSk7CisgICAgUHVzaCgidmFsdWVzIiwgSXRlbTo6TUVTU0FHRSwgdHJ1ZSwgdHJ1ZSk7CisgICAgcmV0dXJuIHRoaXM7CisgIH0KKworICBpZiAoSXNTdHJ1Y3RMaXN0VmFsdWUoKmZpZWxkKSkgeworICAgIC8vIElmIGcucC5MaXN0VmFsdWUgaXMgcmVwZWF0ZWQsIHN0YXJ0IHRoYXQgbGlzdC4gT3RoZXJ3aXNlLCBzdGFydCB0aGUKKyAgICAvLyAidmFsdWVzIiB3aXRoaW4gaXQuCisgICAgaWYgKElzUmVwZWF0ZWQoKmZpZWxkKSkgeworICAgICAgLy8gUmVuZGVyIGl0IGp1c3QgbGlrZSBhIHJlZ3VsYXIgcmVwZWF0ZWQgZmllbGQuCisgICAgICAvLyAiPG5hbWU+IjogWworICAgICAgUHVzaChuYW1lLCBJdGVtOjpNRVNTQUdFLCBmYWxzZSwgdHJ1ZSk7CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvLyBTdGFydCB0aGUgInZhbHVlcyIgZmllbGQgd2l0aGluIGcucC5MaXN0VmFsdWUuCisgICAgLy8gUmVuZGVyCisgICAgLy8gIjxuYW1lPiI6IHsKKyAgICAvLyAgICJ2YWx1ZXMiOiBbCisgICAgUHVzaChuYW1lLCBJdGVtOjpNRVNTQUdFLCBmYWxzZSwgZmFsc2UpOworICAgIFB1c2goInZhbHVlcyIsIEl0ZW06Ok1FU1NBR0UsIHRydWUsIHRydWUpOworICAgIHJldHVybiB0aGlzOworICB9CisKKyAgLy8gSWYgd2UgYXJlIGhlcmUsIHRoZSBmaWVsZCBzaG91bGQgYmUgcmVwZWF0ZWQuIFJlcG9ydCBhbiBlcnJvciBvdGhlcndpc2UuCisgIGlmICghSXNSZXBlYXRlZCgqZmllbGQpKSB7CisgICAgSW5jcmVtZW50SW52YWxpZERlcHRoKCk7CisgICAgSW52YWxpZE5hbWUobmFtZSwgIlByb3RvIGZpZWxkIGlzIG5vdCByZXBlYXRpbmcsIGNhbm5vdCBzdGFydCBsaXN0LiIpOworICAgIHJldHVybiB0aGlzOworICB9CisKKyAgaWYgKElzTWFwKCpmaWVsZCkpIHsKKyAgICBJbnZhbGlkVmFsdWUoIk1hcCIsCisgICAgICAgICAgICAgICAgIFN0ckNhdCgiQ2Fubm90IGJpbmQgYSBsaXN0IHRvIG1hcCBmb3IgZmllbGQgJyIsIG5hbWUsICInLiIpKTsKKyAgICBJbmNyZW1lbnRJbnZhbGlkRGVwdGgoKTsKKyAgICByZXR1cm4gdGhpczsKKyAgfQorCisgIC8vIFBhc3MgdGhlIGV2ZW50IHRvIFByb3RvV3JpdGVyLgorICAvLyBSZW5kZXIKKyAgLy8gIjxuYW1lPiI6IFsKKyAgUHVzaChuYW1lLCBJdGVtOjpNRVNTQUdFLCBmYWxzZSwgdHJ1ZSk7CisgIHJldHVybiB0aGlzOworfQorCitQcm90b1N0cmVhbU9iamVjdFdyaXRlciogUHJvdG9TdHJlYW1PYmplY3RXcml0ZXI6OkVuZExpc3QoKSB7CisgIGlmIChpbnZhbGlkX2RlcHRoKCkgPiAwKSB7CisgICAgRGVjcmVtZW50SW52YWxpZERlcHRoKCk7CisgICAgcmV0dXJuIHRoaXM7CisgIH0KKworICBpZiAoY3VycmVudF8gPT0gTlVMTCkgcmV0dXJuIHRoaXM7CisKKyAgaWYgKGN1cnJlbnRfLT5Jc0FueSgpKSB7CisgICAgY3VycmVudF8tPmFueSgpLT5FbmRMaXN0KCk7CisgICAgcmV0dXJuIHRoaXM7CisgIH0KKworICBQb3AoKTsKKyAgcmV0dXJuIHRoaXM7Cit9CisKK1N0YXR1cyBQcm90b1N0cmVhbU9iamVjdFdyaXRlcjo6UmVuZGVyU3RydWN0VmFsdWUoUHJvdG9TdHJlYW1PYmplY3RXcml0ZXIqIG93LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEYXRhUGllY2UmIGRhdGEpIHsKKyAgc3RyaW5nIHN0cnVjdF9maWVsZF9uYW1lOworICBzd2l0Y2ggKGRhdGEudHlwZSgpKSB7CisgICAgLy8gT3VyIEpTT04gcGFyc2VyIHBhcnNlcyBudW1iZXJzIGFzIGVpdGhlciBpbnQ2NCwgdWludDY0LCBvciBkb3VibGUuCisgICAgY2FzZSBEYXRhUGllY2U6OlRZUEVfSU5UNjQ6CisgICAgY2FzZSBEYXRhUGllY2U6OlRZUEVfVUlOVDY0OgorICAgIGNhc2UgRGF0YVBpZWNlOjpUWVBFX0RPVUJMRTogeworICAgICAgc3RydWN0X2ZpZWxkX25hbWUgPSAibnVtYmVyX3ZhbHVlIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIERhdGFQaWVjZTo6VFlQRV9TVFJJTkc6IHsKKyAgICAgIHN0cnVjdF9maWVsZF9uYW1lID0gInN0cmluZ192YWx1ZSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBEYXRhUGllY2U6OlRZUEVfQk9PTDogeworICAgICAgc3RydWN0X2ZpZWxkX25hbWUgPSAiYm9vbF92YWx1ZSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBEYXRhUGllY2U6OlRZUEVfTlVMTDogeworICAgICAgc3RydWN0X2ZpZWxkX25hbWUgPSAibnVsbF92YWx1ZSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgZGVmYXVsdDogeworICAgICAgcmV0dXJuIFN0YXR1cyhJTlZBTElEX0FSR1VNRU5ULAorICAgICAgICAgICAgICAgICAgICAiSW52YWxpZCBzdHJ1Y3QgZGF0YSB0eXBlLiBPbmx5IG51bWJlciwgc3RyaW5nLCBib29sZWFuIG9yICIKKyAgICAgICAgICAgICAgICAgICAgIm51bGwgdmFsdWVzIGFyZSBzdXBwb3J0ZWQuIik7CisgICAgfQorICB9CisgIG93LT5Qcm90b1dyaXRlcjo6UmVuZGVyRGF0YVBpZWNlKHN0cnVjdF9maWVsZF9uYW1lLCBkYXRhKTsKKyAgcmV0dXJuIFN0YXR1czo6T0s7Cit9CisKK1N0YXR1cyBQcm90b1N0cmVhbU9iamVjdFdyaXRlcjo6UmVuZGVyVGltZXN0YW1wKFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyKiBvdywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERhdGFQaWVjZSYgZGF0YSkgeworICBpZiAoZGF0YS50eXBlKCkgIT0gRGF0YVBpZWNlOjpUWVBFX1NUUklORykgeworICAgIHJldHVybiBTdGF0dXMoSU5WQUxJRF9BUkdVTUVOVCwKKyAgICAgICAgICAgICAgICAgIFN0ckNhdCgiSW52YWxpZCBkYXRhIHR5cGUgZm9yIHRpbWVzdGFtcCwgdmFsdWUgaXMgIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhLlZhbHVlQXNTdHJpbmdPckRlZmF1bHQoIiIpKSk7CisgIH0KKworICBTdHJpbmdQaWVjZSB2YWx1ZShkYXRhLnN0cigpKTsKKworICBpbnQ2NCBzZWNvbmRzOworICBpbnQzMiBuYW5vczsKKyAgaWYgKCE6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpQYXJzZVRpbWUodmFsdWUuVG9TdHJpbmcoKSwgJnNlY29uZHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZuYW5vcykpIHsKKyAgICByZXR1cm4gU3RhdHVzKElOVkFMSURfQVJHVU1FTlQsIFN0ckNhdCgiSW52YWxpZCB0aW1lIGZvcm1hdDogIiwgdmFsdWUpKTsKKyAgfQorCisKKyAgb3ctPlByb3RvV3JpdGVyOjpSZW5kZXJEYXRhUGllY2UoInNlY29uZHMiLCBEYXRhUGllY2Uoc2Vjb25kcykpOworICBvdy0+UHJvdG9Xcml0ZXI6OlJlbmRlckRhdGFQaWVjZSgibmFub3MiLCBEYXRhUGllY2UobmFub3MpKTsKKyAgcmV0dXJuIFN0YXR1czo6T0s7Cit9CisKK3N0YXRpYyBpbmxpbmUgdXRpbDo6U3RhdHVzIFJlbmRlck9uZUZpZWxkUGF0aChQcm90b1N0cmVhbU9iamVjdFdyaXRlciogb3csCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdQaWVjZSBwYXRoKSB7CisgIG93LT5Qcm90b1dyaXRlcjo6UmVuZGVyRGF0YVBpZWNlKAorICAgICAgInBhdGhzIiwgRGF0YVBpZWNlKENvbnZlcnRGaWVsZE1hc2tQYXRoKHBhdGgsICZUb1NuYWtlQ2FzZSkpKTsKKyAgcmV0dXJuIFN0YXR1czo6T0s7Cit9CisKK1N0YXR1cyBQcm90b1N0cmVhbU9iamVjdFdyaXRlcjo6UmVuZGVyRmllbGRNYXNrKFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyKiBvdywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERhdGFQaWVjZSYgZGF0YSkgeworICBpZiAoZGF0YS50eXBlKCkgIT0gRGF0YVBpZWNlOjpUWVBFX1NUUklORykgeworICAgIHJldHVybiBTdGF0dXMoSU5WQUxJRF9BUkdVTUVOVCwKKyAgICAgICAgICAgICAgICAgIFN0ckNhdCgiSW52YWxpZCBkYXRhIHR5cGUgZm9yIGZpZWxkIG1hc2ssIHZhbHVlIGlzICIsCisgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YS5WYWx1ZUFzU3RyaW5nT3JEZWZhdWx0KCIiKSkpOworICB9CisKKy8vIFRPRE8odHN1bik6IGZpZ3VyZSBvdXQgaG93IHRvIGRvIHByb3RvIGRlc2NyaXB0b3IgYmFzZWQgc25ha2UgY2FzZQorLy8gY29udmVyc2lvbnMgYXMgbXVjaCBhcyBwb3NzaWJsZS4gQmVjYXVzZSBUb1NuYWtlQ2FzZSBzb21ldGltZXMgcmV0dXJucyB0aGUKKy8vIHdyb25nIHZhbHVlLgorICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPFJlc3VsdENhbGxiYWNrMTx1dGlsOjpTdGF0dXMsIFN0cmluZ1BpZWNlPiA+IGNhbGxiYWNrKAorICAgICAgZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6Ok5ld1Blcm1hbmVudENhbGxiYWNrKCZSZW5kZXJPbmVGaWVsZFBhdGgsIG93KSk7CisgIHJldHVybiBEZWNvZGVDb21wYWN0RmllbGRNYXNrUGF0aHMoZGF0YS5zdHIoKSwgY2FsbGJhY2suZ2V0KCkpOworfQorCitTdGF0dXMgUHJvdG9TdHJlYW1PYmplY3RXcml0ZXI6OlJlbmRlckR1cmF0aW9uKFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyKiBvdywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGF0YVBpZWNlJiBkYXRhKSB7CisgIGlmIChkYXRhLnR5cGUoKSAhPSBEYXRhUGllY2U6OlRZUEVfU1RSSU5HKSB7CisgICAgcmV0dXJuIFN0YXR1cyhJTlZBTElEX0FSR1VNRU5ULAorICAgICAgICAgICAgICAgICAgU3RyQ2F0KCJJbnZhbGlkIGRhdGEgdHlwZSBmb3IgZHVyYXRpb24sIHZhbHVlIGlzICIsCisgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YS5WYWx1ZUFzU3RyaW5nT3JEZWZhdWx0KCIiKSkpOworICB9CisKKyAgU3RyaW5nUGllY2UgdmFsdWUoZGF0YS5zdHIoKSk7CisKKyAgaWYgKCF2YWx1ZS5lbmRzX3dpdGgoInMiKSkgeworICAgIHJldHVybiBTdGF0dXMoSU5WQUxJRF9BUkdVTUVOVCwKKyAgICAgICAgICAgICAgICAgICJJbGxlZ2FsIGR1cmF0aW9uIGZvcm1hdDsgZHVyYXRpb24gbXVzdCBlbmQgd2l0aCAncyciKTsKKyAgfQorICB2YWx1ZSA9IHZhbHVlLnN1YnN0cigwLCB2YWx1ZS5zaXplKCkgLSAxKTsKKyAgaW50IHNpZ24gPSAxOworICBpZiAodmFsdWUuc3RhcnRzX3dpdGgoIi0iKSkgeworICAgIHNpZ24gPSAtMTsKKyAgICB2YWx1ZSA9IHZhbHVlLnN1YnN0cigxKTsKKyAgfQorCisgIFN0cmluZ1BpZWNlIHNfc2Vjcywgc19uYW5vczsKKyAgU3BsaXRTZWNvbmRzQW5kTmFub3ModmFsdWUsICZzX3NlY3MsICZzX25hbm9zKTsKKyAgdWludDY0IHVuc2lnbmVkX3NlY29uZHM7CisgIGlmICghc2FmZV9zdHJ0b3U2NChzX3NlY3MsICZ1bnNpZ25lZF9zZWNvbmRzKSkgeworICAgIHJldHVybiBTdGF0dXMoSU5WQUxJRF9BUkdVTUVOVCwKKyAgICAgICAgICAgICAgICAgICJJbnZhbGlkIGR1cmF0aW9uIGZvcm1hdCwgZmFpbGVkIHRvIHBhcnNlIHNlY29uZHMiKTsKKyAgfQorCisgIGludDMyIG5hbm9zID0gMDsKKyAgU3RhdHVzIG5hbm9zX3N0YXR1cyA9IEdldE5hbm9zRnJvbVN0cmluZ1BpZWNlKAorICAgICAgc19uYW5vcywgIkludmFsaWQgZHVyYXRpb24gZm9ybWF0LCBmYWlsZWQgdG8gcGFyc2UgbmFubyBzZWNvbmRzIiwKKyAgICAgICJEdXJhdGlvbiB2YWx1ZSBleGNlZWRzIGxpbWl0cyIsICZuYW5vcyk7CisgIGlmICghbmFub3Nfc3RhdHVzLm9rKCkpIHsKKyAgICByZXR1cm4gbmFub3Nfc3RhdHVzOworICB9CisgIG5hbm9zID0gc2lnbiAqIG5hbm9zOworCisgIGludDY0IHNlY29uZHMgPSBzaWduICogdW5zaWduZWRfc2Vjb25kczsKKyAgaWYgKHNlY29uZHMgPiBrTWF4U2Vjb25kcyB8fCBzZWNvbmRzIDwga01pblNlY29uZHMgfHwKKyAgICAgIG5hbm9zIDw9IC1rTmFub3NQZXJTZWNvbmQgfHwgbmFub3MgPj0ga05hbm9zUGVyU2Vjb25kKSB7CisgICAgcmV0dXJuIFN0YXR1cyhJTlZBTElEX0FSR1VNRU5ULCAiRHVyYXRpb24gdmFsdWUgZXhjZWVkcyBsaW1pdHMiKTsKKyAgfQorCisgIG93LT5Qcm90b1dyaXRlcjo6UmVuZGVyRGF0YVBpZWNlKCJzZWNvbmRzIiwgRGF0YVBpZWNlKHNlY29uZHMpKTsKKyAgb3ctPlByb3RvV3JpdGVyOjpSZW5kZXJEYXRhUGllY2UoIm5hbm9zIiwgRGF0YVBpZWNlKG5hbm9zKSk7CisgIHJldHVybiBTdGF0dXM6Ok9LOworfQorCitTdGF0dXMgUHJvdG9TdHJlYW1PYmplY3RXcml0ZXI6OlJlbmRlcldyYXBwZXJUeXBlKFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyKiBvdywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGF0YVBpZWNlJiBkYXRhKSB7CisgIG93LT5Qcm90b1dyaXRlcjo6UmVuZGVyRGF0YVBpZWNlKCJ2YWx1ZSIsIGRhdGEpOworICByZXR1cm4gU3RhdHVzOjpPSzsKK30KKworUHJvdG9TdHJlYW1PYmplY3RXcml0ZXIqIFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyOjpSZW5kZXJEYXRhUGllY2UoCisgICAgU3RyaW5nUGllY2UgbmFtZSwgY29uc3QgRGF0YVBpZWNlJiBkYXRhKSB7CisgIFN0YXR1cyBzdGF0dXM7CisgIGlmIChpbnZhbGlkX2RlcHRoKCkgPiAwKSByZXR1cm4gdGhpczsKKworICBpZiAoY3VycmVudF8gPT0gTlVMTCkgeworICAgIGNvbnN0IFR5cGVSZW5kZXJlciogdHlwZV9yZW5kZXJlciA9CisgICAgICAgIEZpbmRUeXBlUmVuZGVyZXIoR2V0RnVsbFR5cGVXaXRoVXJsKG1hc3Rlcl90eXBlXy5uYW1lKCkpKTsKKyAgICBpZiAodHlwZV9yZW5kZXJlciA9PSBOVUxMKSB7CisgICAgICBJbnZhbGlkTmFtZShuYW1lLCAiUm9vdCBlbGVtZW50IG11c3QgYmUgYSBtZXNzYWdlLiIpOworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorICAgIC8vIFJlbmRlciB0aGUgc3BlY2lhbCB0eXBlLgorICAgIC8vICI8bmFtZT4iOiB7CisgICAgLy8gICAuLi4gUmVuZGVyIHNwZWNpYWwgdHlwZSAuLi4KKyAgICAvLyB9CisgICAgUHJvdG9Xcml0ZXI6OlN0YXJ0T2JqZWN0KG5hbWUpOworICAgIHN0YXR1cyA9ICgqdHlwZV9yZW5kZXJlcikodGhpcywgZGF0YSk7CisgICAgaWYgKCFzdGF0dXMub2soKSkgeworICAgICAgSW52YWxpZFZhbHVlKG1hc3Rlcl90eXBlXy5uYW1lKCksCisgICAgICAgICAgICAgICAgICAgU3RyQ2F0KCJGaWVsZCAnIiwgbmFtZSwgIicsICIsIHN0YXR1cy5lcnJvcl9tZXNzYWdlKCkpKTsKKyAgICB9CisgICAgUHJvdG9Xcml0ZXI6OkVuZE9iamVjdCgpOworICAgIHJldHVybiB0aGlzOworICB9CisKKyAgaWYgKGN1cnJlbnRfLT5Jc0FueSgpKSB7CisgICAgY3VycmVudF8tPmFueSgpLT5SZW5kZXJEYXRhUGllY2UobmFtZSwgZGF0YSk7CisgICAgcmV0dXJuIHRoaXM7CisgIH0KKworICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZCogZmllbGQgPSBOVUxMOworICBpZiAoY3VycmVudF8tPklzTWFwKCkpIHsKKyAgICBpZiAoIVZhbGlkTWFwS2V5KG5hbWUpKSByZXR1cm4gdGhpczsKKworICAgIC8vIFJlbmRlciBhbiBpdGVtIGluIHJlcGVhdGVkIG1hcCBsaXN0LgorICAgIC8vIHsgImtleSI6ICI8bmFtZT4iLCAidmFsdWUiOgorICAgIFB1c2goIiIsIEl0ZW06Ok1FU1NBR0UsIGZhbHNlLCBmYWxzZSk7CisgICAgUHJvdG9Xcml0ZXI6OlJlbmRlckRhdGFQaWVjZSgia2V5IiwgRGF0YVBpZWNlKG5hbWUpKTsKKyAgICBmaWVsZCA9IExvb2t1cCgidmFsdWUiKTsKKyAgICBpZiAoZmllbGQgPT0gTlVMTCkgeworICAgICAgR09PR0xFX0xPRyhERkFUQUwpIDw8ICJNYXAgZG9lcyBub3QgaGF2ZSBhIHZhbHVlIGZpZWxkLiI7CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBjb25zdCBUeXBlUmVuZGVyZXIqIHR5cGVfcmVuZGVyZXIgPSBGaW5kVHlwZVJlbmRlcmVyKGZpZWxkLT50eXBlX3VybCgpKTsKKyAgICBpZiAodHlwZV9yZW5kZXJlciAhPSBOVUxMKSB7CisgICAgICAvLyBNYXAncyB2YWx1ZSB0eXBlIGlzIGEgc3BlY2lhbCB0eXBlLiBSZW5kZXIgaXQgbGlrZSBhIG1lc3NhZ2U6CisgICAgICAvLyAidmFsdWUiOiB7CisgICAgICAvLyAgIC4uLiBSZW5kZXIgc3BlY2lhbCB0eXBlIC4uLgorICAgICAgLy8gfQorICAgICAgUHVzaCgidmFsdWUiLCBJdGVtOjpNRVNTQUdFLCB0cnVlLCBmYWxzZSk7CisgICAgICBzdGF0dXMgPSAoKnR5cGVfcmVuZGVyZXIpKHRoaXMsIGRhdGEpOworICAgICAgaWYgKCFzdGF0dXMub2soKSkgeworICAgICAgICBJbnZhbGlkVmFsdWUoZmllbGQtPnR5cGVfdXJsKCksCisgICAgICAgICAgICAgICAgICAgICBTdHJDYXQoIkZpZWxkICciLCBuYW1lLCAiJywgIiwgc3RhdHVzLmVycm9yX21lc3NhZ2UoKSkpOworICAgICAgfQorICAgICAgUG9wKCk7CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvLyBJZiB3ZSBhcmUgcmVuZGVyaW5nIGV4cGxpY2l0IG51bGwgdmFsdWVzIGFuZCB0aGUgYmFja2VuZCBwcm90byBmaWVsZCBpcworICAgIC8vIG5vdCBvZiB0aGUgZ29vZ2xlLnByb3RvYnVmLk51bGxUeXBlIHR5cGUsIHdlIGRvIG5vdGhpbmcuCisgICAgaWYgKGRhdGEudHlwZSgpID09IERhdGFQaWVjZTo6VFlQRV9OVUxMICYmCisgICAgICAgIGZpZWxkLT50eXBlX3VybCgpICE9IGtTdHJ1Y3ROdWxsVmFsdWVUeXBlVXJsKSB7CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvLyBSZW5kZXIgdGhlIG1hcCB2YWx1ZSBhcyBhIHByaW1pdGl2ZSB0eXBlLgorICAgIFByb3RvV3JpdGVyOjpSZW5kZXJEYXRhUGllY2UoInZhbHVlIiwgZGF0YSk7CisgICAgUG9wKCk7CisgICAgcmV0dXJuIHRoaXM7CisgIH0KKworICBmaWVsZCA9IExvb2t1cChuYW1lKTsKKyAgaWYgKGZpZWxkID09IE5VTEwpIHJldHVybiB0aGlzOworCisgIC8vIENoZWNrIGlmIHRoZSBmaWVsZCBpcyBvZiBzcGVjaWFsIHR5cGUuIFJlbmRlciBpdCBhY2NvcmRpbmdseSBpZiBzby4KKyAgY29uc3QgVHlwZVJlbmRlcmVyKiB0eXBlX3JlbmRlcmVyID0gRmluZFR5cGVSZW5kZXJlcihmaWVsZC0+dHlwZV91cmwoKSk7CisgIGlmICh0eXBlX3JlbmRlcmVyICE9IE5VTEwpIHsKKyAgICBQdXNoKG5hbWUsIEl0ZW06Ok1FU1NBR0UsIGZhbHNlLCBmYWxzZSk7CisgICAgc3RhdHVzID0gKCp0eXBlX3JlbmRlcmVyKSh0aGlzLCBkYXRhKTsKKyAgICBpZiAoIXN0YXR1cy5vaygpKSB7CisgICAgICBJbnZhbGlkVmFsdWUoZmllbGQtPnR5cGVfdXJsKCksCisgICAgICAgICAgICAgICAgICAgU3RyQ2F0KCJGaWVsZCAnIiwgbmFtZSwgIicsICIsIHN0YXR1cy5lcnJvcl9tZXNzYWdlKCkpKTsKKyAgICB9CisgICAgUG9wKCk7CisgICAgcmV0dXJuIHRoaXM7CisgIH0KKworICAvLyBJZiB3ZSBhcmUgcmVuZGVyaW5nIGV4cGxpY2l0IG51bGwgdmFsdWVzIGFuZCB0aGUgYmFja2VuZCBwcm90byBmaWVsZCBpcworICAvLyBub3Qgb2YgdGhlIGdvb2dsZS5wcm90b2J1Zi5OdWxsVHlwZSB0eXBlLCB3ZSBkbyBub3RoaW5nLgorICBpZiAoZGF0YS50eXBlKCkgPT0gRGF0YVBpZWNlOjpUWVBFX05VTEwgJiYKKyAgICAgIGZpZWxkLT50eXBlX3VybCgpICE9IGtTdHJ1Y3ROdWxsVmFsdWVUeXBlVXJsKSB7CisgICAgcmV0dXJuIHRoaXM7CisgIH0KKworICBQcm90b1dyaXRlcjo6UmVuZGVyRGF0YVBpZWNlKG5hbWUsIGRhdGEpOworICByZXR1cm4gdGhpczsKK30KKworLy8gTWFwIG9mIGZ1bmN0aW9ucyB0aGF0IGFyZSByZXNwb25zaWJsZSBmb3IgcmVuZGVyaW5nIHdlbGwga25vd24gdHlwZQorLy8gcmVwcmVzZW50ZWQgYnkgdGhlIGtleS4KK2hhc2hfbWFwPHN0cmluZywgUHJvdG9TdHJlYW1PYmplY3RXcml0ZXI6OlR5cGVSZW5kZXJlcj4qCisgICAgUHJvdG9TdHJlYW1PYmplY3RXcml0ZXI6OnJlbmRlcmVyc18gPSBOVUxMOworR09PR0xFX1BST1RPQlVGX0RFQ0xBUkVfT05DRSh3cml0ZXJfcmVuZGVyZXJzX2luaXRfKTsKKwordm9pZCBQcm90b1N0cmVhbU9iamVjdFdyaXRlcjo6SW5pdFJlbmRlcmVyTWFwKCkgeworICByZW5kZXJlcnNfID0gbmV3IGhhc2hfbWFwPHN0cmluZywgUHJvdG9TdHJlYW1PYmplY3RXcml0ZXI6OlR5cGVSZW5kZXJlcj4oKTsKKyAgKCpyZW5kZXJlcnNfKVsidHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIl0gPQorICAgICAgJlByb3RvU3RyZWFtT2JqZWN0V3JpdGVyOjpSZW5kZXJUaW1lc3RhbXA7CisgICgqcmVuZGVyZXJzXylbInR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uIl0gPQorICAgICAgJlByb3RvU3RyZWFtT2JqZWN0V3JpdGVyOjpSZW5kZXJEdXJhdGlvbjsKKyAgKCpyZW5kZXJlcnNfKVsidHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIl0gPQorICAgICAgJlByb3RvU3RyZWFtT2JqZWN0V3JpdGVyOjpSZW5kZXJGaWVsZE1hc2s7CisgICgqcmVuZGVyZXJzXylbInR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLnByb3RvYnVmLkRvdWJsZSJdID0KKyAgICAgICZQcm90b1N0cmVhbU9iamVjdFdyaXRlcjo6UmVuZGVyV3JhcHBlclR5cGU7CisgICgqcmVuZGVyZXJzXylbInR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLnByb3RvYnVmLkZsb2F0Il0gPQorICAgICAgJlByb3RvU3RyZWFtT2JqZWN0V3JpdGVyOjpSZW5kZXJXcmFwcGVyVHlwZTsKKyAgKCpyZW5kZXJlcnNfKVsidHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUucHJvdG9idWYuSW50NjQiXSA9CisgICAgICAmUHJvdG9TdHJlYW1PYmplY3RXcml0ZXI6OlJlbmRlcldyYXBwZXJUeXBlOworICAoKnJlbmRlcmVyc18pWyJ0eXBlLmdvb2dsZWFwaXMuY29tL2dvb2dsZS5wcm90b2J1Zi5VSW50NjQiXSA9CisgICAgICAmUHJvdG9TdHJlYW1PYmplY3RXcml0ZXI6OlJlbmRlcldyYXBwZXJUeXBlOworICAoKnJlbmRlcmVyc18pWyJ0eXBlLmdvb2dsZWFwaXMuY29tL2dvb2dsZS5wcm90b2J1Zi5JbnQzMiJdID0KKyAgICAgICZQcm90b1N0cmVhbU9iamVjdFdyaXRlcjo6UmVuZGVyV3JhcHBlclR5cGU7CisgICgqcmVuZGVyZXJzXylbInR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLnByb3RvYnVmLlVJbnQzMiJdID0KKyAgICAgICZQcm90b1N0cmVhbU9iamVjdFdyaXRlcjo6UmVuZGVyV3JhcHBlclR5cGU7CisgICgqcmVuZGVyZXJzXylbInR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLnByb3RvYnVmLkJvb2wiXSA9CisgICAgICAmUHJvdG9TdHJlYW1PYmplY3RXcml0ZXI6OlJlbmRlcldyYXBwZXJUeXBlOworICAoKnJlbmRlcmVyc18pWyJ0eXBlLmdvb2dsZWFwaXMuY29tL2dvb2dsZS5wcm90b2J1Zi5TdHJpbmciXSA9CisgICAgICAmUHJvdG9TdHJlYW1PYmplY3RXcml0ZXI6OlJlbmRlcldyYXBwZXJUeXBlOworICAoKnJlbmRlcmVyc18pWyJ0eXBlLmdvb2dsZWFwaXMuY29tL2dvb2dsZS5wcm90b2J1Zi5CeXRlcyJdID0KKyAgICAgICZQcm90b1N0cmVhbU9iamVjdFdyaXRlcjo6UmVuZGVyV3JhcHBlclR5cGU7CisgICgqcmVuZGVyZXJzXylbInR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlIl0gPQorICAgICAgJlByb3RvU3RyZWFtT2JqZWN0V3JpdGVyOjpSZW5kZXJXcmFwcGVyVHlwZTsKKyAgKCpyZW5kZXJlcnNfKVsidHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSJdID0KKyAgICAgICZQcm90b1N0cmVhbU9iamVjdFdyaXRlcjo6UmVuZGVyV3JhcHBlclR5cGU7CisgICgqcmVuZGVyZXJzXylbInR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUiXSA9CisgICAgICAmUHJvdG9TdHJlYW1PYmplY3RXcml0ZXI6OlJlbmRlcldyYXBwZXJUeXBlOworICAoKnJlbmRlcmVyc18pWyJ0eXBlLmdvb2dsZWFwaXMuY29tL2dvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSJdID0KKyAgICAgICZQcm90b1N0cmVhbU9iamVjdFdyaXRlcjo6UmVuZGVyV3JhcHBlclR5cGU7CisgICgqcmVuZGVyZXJzXylbInR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUiXSA9CisgICAgICAmUHJvdG9TdHJlYW1PYmplY3RXcml0ZXI6OlJlbmRlcldyYXBwZXJUeXBlOworICAoKnJlbmRlcmVyc18pWyJ0eXBlLmdvb2dsZWFwaXMuY29tL2dvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSJdID0KKyAgICAgICZQcm90b1N0cmVhbU9iamVjdFdyaXRlcjo6UmVuZGVyV3JhcHBlclR5cGU7CisgICgqcmVuZGVyZXJzXylbInR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSJdID0KKyAgICAgICZQcm90b1N0cmVhbU9iamVjdFdyaXRlcjo6UmVuZGVyV3JhcHBlclR5cGU7CisgICgqcmVuZGVyZXJzXylbInR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIl0gPQorICAgICAgJlByb3RvU3RyZWFtT2JqZWN0V3JpdGVyOjpSZW5kZXJXcmFwcGVyVHlwZTsKKyAgKCpyZW5kZXJlcnNfKVsidHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSJdID0KKyAgICAgICZQcm90b1N0cmVhbU9iamVjdFdyaXRlcjo6UmVuZGVyV3JhcHBlclR5cGU7CisgICgqcmVuZGVyZXJzXylbInR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLnByb3RvYnVmLlZhbHVlIl0gPQorICAgICAgJlByb3RvU3RyZWFtT2JqZWN0V3JpdGVyOjpSZW5kZXJTdHJ1Y3RWYWx1ZTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6T25TaHV0ZG93bigmRGVsZXRlUmVuZGVyZXJNYXApOworfQorCit2b2lkIFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyOjpEZWxldGVSZW5kZXJlck1hcCgpIHsKKyAgZGVsZXRlIFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyOjpyZW5kZXJlcnNfOworICByZW5kZXJlcnNfID0gTlVMTDsKK30KKworUHJvdG9TdHJlYW1PYmplY3RXcml0ZXI6OlR5cGVSZW5kZXJlcioKK1Byb3RvU3RyZWFtT2JqZWN0V3JpdGVyOjpGaW5kVHlwZVJlbmRlcmVyKGNvbnN0IHN0cmluZyYgdHlwZV91cmwpIHsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpHb29nbGVPbmNlSW5pdCgmd3JpdGVyX3JlbmRlcmVyc19pbml0XywgJkluaXRSZW5kZXJlck1hcCk7CisgIHJldHVybiBGaW5kT3JOdWxsKCpyZW5kZXJlcnNfLCB0eXBlX3VybCk7Cit9CisKK2Jvb2wgUHJvdG9TdHJlYW1PYmplY3RXcml0ZXI6OlZhbGlkTWFwS2V5KFN0cmluZ1BpZWNlIHVubm9ybWFsaXplZF9uYW1lKSB7CisgIGlmIChjdXJyZW50XyA9PSBOVUxMKSByZXR1cm4gdHJ1ZTsKKworICBpZiAoIWN1cnJlbnRfLT5JbnNlcnRNYXBLZXlJZk5vdFByZXNlbnQodW5ub3JtYWxpemVkX25hbWUpKSB7CisgICAgbGlzdGVuZXIoKS0+SW52YWxpZE5hbWUoCisgICAgICAgIGxvY2F0aW9uKCksIHVubm9ybWFsaXplZF9uYW1lLAorICAgICAgICBTdHJDYXQoIlJlcGVhdGVkIG1hcCBrZXk6ICciLCB1bm5vcm1hbGl6ZWRfbmFtZSwgIicgaXMgYWxyZWFkeSBzZXQuIikpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIHJldHVybiB0cnVlOworfQorCit2b2lkIFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyOjpQdXNoKFN0cmluZ1BpZWNlIG5hbWUsIEl0ZW06Okl0ZW1UeXBlIGl0ZW1fdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc19wbGFjZWhvbGRlciwgYm9vbCBpc19saXN0KSB7CisgIGlzX2xpc3QgPyBQcm90b1dyaXRlcjo6U3RhcnRMaXN0KG5hbWUpIDogUHJvdG9Xcml0ZXI6OlN0YXJ0T2JqZWN0KG5hbWUpOworCisgIC8vIGludmFsaWRfZGVwdGggPT0gMCBtZWFucyBpdCBpcyBhIHN1Y2Nlc3NmdWwgU3RhcnRPYmplY3Qgb3IgU3RhcnRMaXN0LgorICBpZiAoaW52YWxpZF9kZXB0aCgpID09IDApCisgICAgY3VycmVudF8ucmVzZXQoCisgICAgICAgIG5ldyBJdGVtKGN1cnJlbnRfLnJlbGVhc2UoKSwgaXRlbV90eXBlLCBpc19wbGFjZWhvbGRlciwgaXNfbGlzdCkpOworfQorCit2b2lkIFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyOjpQb3AoKSB7CisgIC8vIFBvcCBhbGwgcGxhY2Vob2xkZXIgaXRlbXMgc2VuZGluZyBTdGFydE9iamVjdCBvciBTdGFydExpc3QgZXZlbnRzIHRvCisgIC8vIFByb3RvV3JpdGVyIGFjY29yZGluZyB0byBpc19saXN0IHZhbHVlLgorICB3aGlsZSAoY3VycmVudF8gIT0gTlVMTCAmJiBjdXJyZW50Xy0+aXNfcGxhY2Vob2xkZXIoKSkgeworICAgIFBvcE9uZUVsZW1lbnQoKTsKKyAgfQorICBpZiAoY3VycmVudF8gIT0gTlVMTCkgeworICAgIFBvcE9uZUVsZW1lbnQoKTsKKyAgfQorfQorCit2b2lkIFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyOjpQb3BPbmVFbGVtZW50KCkgeworICBjdXJyZW50Xy0+aXNfbGlzdCgpID8gUHJvdG9Xcml0ZXI6OkVuZExpc3QoKSA6IFByb3RvV3JpdGVyOjpFbmRPYmplY3QoKTsKKyAgY3VycmVudF8ucmVzZXQoY3VycmVudF8tPnBvcDxJdGVtPigpKTsKK30KKworYm9vbCBQcm90b1N0cmVhbU9iamVjdFdyaXRlcjo6SXNNYXAoY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGQmIGZpZWxkKSB7CisgIGlmIChmaWVsZC50eXBlX3VybCgpLmVtcHR5KCkgfHwKKyAgICAgIGZpZWxkLmtpbmQoKSAhPSBnb29nbGU6OnByb3RvYnVmOjpGaWVsZF9LaW5kX1RZUEVfTUVTU0FHRSB8fAorICAgICAgZmllbGQuY2FyZGluYWxpdHkoKSAhPQorICAgICAgICAgIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkX0NhcmRpbmFsaXR5X0NBUkRJTkFMSVRZX1JFUEVBVEVEKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlR5cGUqIGZpZWxkX3R5cGUgPQorICAgICAgdHlwZWluZm8oKS0+R2V0VHlwZUJ5VHlwZVVybChmaWVsZC50eXBlX3VybCgpKTsKKworICAvLyBUT0RPKHhpYW9mZW5nKTogVW5pZnkgb3B0aW9uIG5hbWVzLgorICByZXR1cm4gR2V0Qm9vbE9wdGlvbk9yRGVmYXVsdChmaWVsZF90eXBlLT5vcHRpb25zKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJnb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMubWFwX2VudHJ5IiwgZmFsc2UpIHx8CisgICAgICAgICBHZXRCb29sT3B0aW9uT3JEZWZhdWx0KGZpZWxkX3R5cGUtPm9wdGlvbnMoKSwgIm1hcF9lbnRyeSIsIGZhbHNlKTsKK30KKworYm9vbCBQcm90b1N0cmVhbU9iamVjdFdyaXRlcjo6SXNBbnkoY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGQmIGZpZWxkKSB7CisgIHJldHVybiBHZXRUeXBlV2l0aG91dFVybChmaWVsZC50eXBlX3VybCgpKSA9PSBrQW55VHlwZTsKK30KKworYm9vbCBQcm90b1N0cmVhbU9iamVjdFdyaXRlcjo6SXNTdHJ1Y3QoY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGQmIGZpZWxkKSB7CisgIHJldHVybiBHZXRUeXBlV2l0aG91dFVybChmaWVsZC50eXBlX3VybCgpKSA9PSBrU3RydWN0VHlwZTsKK30KKworYm9vbCBQcm90b1N0cmVhbU9iamVjdFdyaXRlcjo6SXNTdHJ1Y3RWYWx1ZSgKKyAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZCYgZmllbGQpIHsKKyAgcmV0dXJuIEdldFR5cGVXaXRob3V0VXJsKGZpZWxkLnR5cGVfdXJsKCkpID09IGtTdHJ1Y3RWYWx1ZVR5cGU7Cit9CisKK2Jvb2wgUHJvdG9TdHJlYW1PYmplY3RXcml0ZXI6OklzU3RydWN0TGlzdFZhbHVlKAorICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkJiBmaWVsZCkgeworICByZXR1cm4gR2V0VHlwZVdpdGhvdXRVcmwoZmllbGQudHlwZV91cmwoKSkgPT0ga1N0cnVjdExpc3RWYWx1ZVR5cGU7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBjb252ZXJ0ZXIKK30gIC8vIG5hbWVzcGFjZSB1dGlsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9wcm90b3N0cmVhbV9vYmplY3R3cml0ZXIuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9wcm90b3N0cmVhbV9vYmplY3R3cml0ZXIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wOGFjNmUzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3Byb3Rvc3RyZWFtX29iamVjdHdyaXRlci5oCkBAIC0wLDAgKzEsMzEyIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfVVRJTF9DT05WRVJURVJfUFJPVE9TVFJFQU1fT0JKRUNUV1JJVEVSX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfVVRJTF9DT05WRVJURVJfUFJPVE9TVFJFQU1fT0JKRUNUV1JJVEVSX0hfXworCisjaW5jbHVkZSA8ZGVxdWU+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2hhc2guaD4KKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX2ltcGwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3R5cGVfaW5mby5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL2RhdGFwaWVjZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL2Vycm9yX2xpc3RlbmVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvcHJvdG9fd3JpdGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvc3RydWN0dXJlZF9vYmplY3R3cml0ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC90eXBlX3Jlc29sdmVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2J5dGVzdHJlYW0uaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGlvIHsKK2NsYXNzIENvZGVkT3V0cHV0U3RyZWFtOworfSAgLy8gbmFtZXNwYWNlIGlvCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworCituYW1lc3BhY2UgcHJvdG9idWYgeworY2xhc3MgVHlwZTsKK2NsYXNzIEZpZWxkOworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKKworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSB1dGlsIHsKK25hbWVzcGFjZSBjb252ZXJ0ZXIgeworCitjbGFzcyBPYmplY3RMb2NhdGlvblRyYWNrZXI7CisKKy8vIEFuIE9iamVjdFdyaXRlciB0aGF0IGNhbiB3cml0ZSBwcm90b2J1ZiBieXRlcyBkaXJlY3RseSBmcm9tIHdyaXRlciBldmVudHMuCisvLyBUaGlzIGNsYXNzIHN1cHBvcnRzIGFsbCBzcGVjaWFsIHR5cGVzIGxpa2UgU3RydWN0IGFuZCBNYXAuIEl0IHVzZXMKKy8vIHRoZSBQcm90b1dyaXRlciBjbGFzcyB0byB3cml0ZSByYXcgcHJvdG8gYnl0ZXMuCisvLworLy8gSXQgYWxzbyBzdXBwb3J0cyBzdHJlYW1pbmcuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgUHJvdG9TdHJlYW1PYmplY3RXcml0ZXIgOiBwdWJsaWMgUHJvdG9Xcml0ZXIgeworIHB1YmxpYzoKKy8vIENvbnN0cnVjdG9yLiBEb2VzIG5vdCB0YWtlIG93bmVyc2hpcCBvZiBhbnkgcGFyYW1ldGVyIHBhc3NlZCBpbi4KKyAgUHJvdG9TdHJlYW1PYmplY3RXcml0ZXIoVHlwZVJlc29sdmVyKiB0eXBlX3Jlc29sdmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlJiB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmdzOjpCeXRlU2luayogb3V0cHV0LCBFcnJvckxpc3RlbmVyKiBsaXN0ZW5lcik7CisgIHZpcnR1YWwgflByb3RvU3RyZWFtT2JqZWN0V3JpdGVyKCk7CisKKyAgLy8gT2JqZWN0V3JpdGVyIG1ldGhvZHMuCisgIHZpcnR1YWwgUHJvdG9TdHJlYW1PYmplY3RXcml0ZXIqIFN0YXJ0T2JqZWN0KFN0cmluZ1BpZWNlIG5hbWUpOworICB2aXJ0dWFsIFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyKiBFbmRPYmplY3QoKTsKKyAgdmlydHVhbCBQcm90b1N0cmVhbU9iamVjdFdyaXRlciogU3RhcnRMaXN0KFN0cmluZ1BpZWNlIG5hbWUpOworICB2aXJ0dWFsIFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyKiBFbmRMaXN0KCk7CisKKyAgLy8gUmVuZGVycyBhIERhdGFQaWVjZSAndmFsdWUnIGludG8gYSBmaWVsZCB3aG9zZSB3aXJlIHR5cGUgaXMgZGV0ZXJtaW5lZAorICAvLyBmcm9tIHRoZSBnaXZlbiBmaWVsZCAnbmFtZScuCisgIHZpcnR1YWwgUHJvdG9TdHJlYW1PYmplY3RXcml0ZXIqIFJlbmRlckRhdGFQaWVjZShTdHJpbmdQaWVjZSBuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGF0YVBpZWNlJiB2YWx1ZSk7CisKKyBwcm90ZWN0ZWQ6CisgIC8vIEZ1bmN0aW9uIHRoYXQgcmVuZGVycyBhIHdlbGwga25vd24gdHlwZSB3aXRoIG1vZGlmaWVkIGJlaGF2aW9yLgorICB0eXBlZGVmIHV0aWw6OlN0YXR1cyAoKlR5cGVSZW5kZXJlcikoUHJvdG9TdHJlYW1PYmplY3RXcml0ZXIqLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEYXRhUGllY2UmKTsKKworICAvLyBIYW5kbGVzIHdyaXRpbmcgQW55cyBvdXQgdXNpbmcgbmVzdGVkIG9iamVjdCB3cml0ZXJzIGFuZCB0aGUgbGlrZS4KKyAgY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEFueVdyaXRlciB7CisgICBwdWJsaWM6CisgICAgZXhwbGljaXQgQW55V3JpdGVyKFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyKiBwYXJlbnQpOworICAgIH5BbnlXcml0ZXIoKTsKKworICAgIC8vIFBhc3NlcyBhIFN0YXJ0T2JqZWN0IGNhbGwgdGhyb3VnaCB0byB0aGUgQW55IHdyaXRlci4KKyAgICB2b2lkIFN0YXJ0T2JqZWN0KFN0cmluZ1BpZWNlIG5hbWUpOworCisgICAgLy8gUGFzc2VzIGFuIEVuZE9iamVjdCBjYWxsIHRocm91Z2ggdG8gdGhlIEFueS4gUmV0dXJucyB0cnVlIGlmIHRoZSBhbnkKKyAgICAvLyBoYW5kbGVkIHRoZSBFbmRPYmplY3QgY2FsbCwgZmFsc2UgaWYgdGhlIEFueSBpcyBub3cgYWxsIGRvbmUgYW5kIGlzIG5vCisgICAgLy8gbG9uZ2VyIG5lZWRlZC4KKyAgICBib29sIEVuZE9iamVjdCgpOworCisgICAgLy8gUGFzc2VzIGEgU3RhcnRMaXN0IGNhbGwgdGhyb3VnaCB0byB0aGUgQW55IHdyaXRlci4KKyAgICB2b2lkIFN0YXJ0TGlzdChTdHJpbmdQaWVjZSBuYW1lKTsKKworICAgIC8vIFBhc3NlcyBhbiBFbmRMaXN0IGNhbGwgdGhyb3VnaCB0byB0aGUgQW55IHdyaXRlci4KKyAgICB2b2lkIEVuZExpc3QoKTsKKworICAgIC8vIFJlbmRlcnMgYSBkYXRhIHBpZWNlIG9uIHRoZSBhbnkuCisgICAgdm9pZCBSZW5kZXJEYXRhUGllY2UoU3RyaW5nUGllY2UgbmFtZSwgY29uc3QgRGF0YVBpZWNlJiB2YWx1ZSk7CisKKyAgIHByaXZhdGU6CisgICAgLy8gSGFuZGxlcyBzdGFydGluZyB1cCB0aGUgYW55IG9uY2Ugd2UgaGF2ZSBhIHR5cGUuCisgICAgdm9pZCBTdGFydEFueShjb25zdCBEYXRhUGllY2UmIHZhbHVlKTsKKworICAgIC8vIFdyaXRlcyB0aGUgQW55IG91dCB0byB0aGUgcGFyZW50IHdyaXRlciBpbiBpdHMgc2VyaWFsaXplZCBmb3JtLgorICAgIHZvaWQgV3JpdGVBbnkoKTsKKworICAgIC8vIFRoZSBwYXJlbnQgb2YgdGhpcyB3cml0ZXIsIG5lZWRlZCBmb3IgdmFyaW91cyBiaXRzIHN1Y2ggYXMgdHlwZSBpbmZvIGFuZAorICAgIC8vIHRoZSBsaXN0ZW5lcnMuCisgICAgUHJvdG9TdHJlYW1PYmplY3RXcml0ZXIqIHBhcmVudF87CisKKyAgICAvLyBUaGUgbmVzdGVkIG9iamVjdCB3cml0ZXIsIHVzZWQgdG8gd3JpdGUgZXZlbnRzLgorICAgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8UHJvdG9TdHJlYW1PYmplY3RXcml0ZXI+IG93XzsKKworICAgIC8vIFRoZSB0eXBlX3VybF8gdGhhdCB0aGlzIEFueSByZXByZXNlbnRzLgorICAgIHN0cmluZyB0eXBlX3VybF87CisKKyAgICAvLyBXaGV0aGVyIHRoaXMgYW55IGlzIGludmFsaWQuIFRoaXMgYWxsb3dzIHVzIHRvIG9ubHkgcmVwb3J0IGFuIGludmFsaWQKKyAgICAvLyBBbnkgbWVzc2FnZSBhIHNpbmdsZSB0aW1lIHJhdGhlciB0aGFuIGV2ZXJ5IHRpbWUgd2UgZ2V0IGEgbmVzdGVkIGZpZWxkLgorICAgIGJvb2wgaW52YWxpZF87CisKKyAgICAvLyBUaGUgb3V0cHV0IGRhdGEgYW5kIHdyYXBwaW5nIEJ5dGVTaW5rLgorICAgIHN0cmluZyBkYXRhXzsKKyAgICBzdHJpbmdzOjpTdHJpbmdCeXRlU2luayBvdXRwdXRfOworCisgICAgLy8gVGhlIGRlcHRoIHdpdGhpbiB0aGUgQW55LCBzbyB3ZSBjYW4gdHJhY2sgd2hlbiB3ZSdyZSBkb25lLgorICAgIGludCBkZXB0aF87CisKKyAgICAvLyBUcnVlIGlmIHRoZSBtZXNzYWdlIHR5cGUgY29udGFpbmVkIGluIEFueSBoYXMgYSBzcGVjaWFsICJ2YWx1ZSIgbWVzc2FnZQorICAgIC8vIGluamVjdGVkLiBUaGlzIGlzIHRydWUgZm9yIHdlbGwta25vd24gbWVzc2FnZSB0eXBlcyBsaWtlIEFueSBvciBTdHJ1Y3QuCisgICAgYm9vbCBoYXNfaW5qZWN0ZWRfdmFsdWVfbWVzc2FnZV87CisgIH07CisKKyAgLy8gUmVwcmVzZW50cyBhbiBpdGVtIGluIGEgc3RhY2sgb2YgaXRlbXMgdXNlZCB0byBrZWVwIHN0YXRlIGJldHdlZW4KKyAgLy8gT2JqZWN0V3JpZXIgZXZlbnRzLgorICBjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgSXRlbSA6IHB1YmxpYyBCYXNlRWxlbWVudCB7CisgICBwdWJsaWM6CisgICAgLy8gSW5kaWNhdGVzIHRoZSB0eXBlIG9mIGl0ZW0uCisgICAgZW51bSBJdGVtVHlwZSB7CisgICAgICBNRVNTQUdFLCAgLy8gU2ltcGxlIG1lc3NhZ2UKKyAgICAgIE1BUCwgICAgICAvLyBQcm90bzMgbWFwIHR5cGUKKyAgICAgIEFOWSwgICAgICAvLyBQcm90bzMgQW55IHR5cGUKKyAgICB9OworCisgICAgLy8gQ29uc3RydWN0b3IgZm9yIHRoZSByb290IGl0ZW0uCisgICAgSXRlbShQcm90b1N0cmVhbU9iamVjdFdyaXRlciogZW5jbG9zaW5nLCBJdGVtVHlwZSBpdGVtX3R5cGUsCisgICAgICAgICBib29sIGlzX3BsYWNlaG9sZGVyLCBib29sIGlzX2xpc3QpOworCisgICAgLy8gQ29uc3RydWN0b3IgZm9yIGEgZmllbGQgb2YgYSBtZXNzYWdlLgorICAgIEl0ZW0oSXRlbSogcGFyZW50LCBJdGVtVHlwZSBpdGVtX3R5cGUsIGJvb2wgaXNfcGxhY2Vob2xkZXIsIGJvb2wgaXNfbGlzdCk7CisKKyAgICB2aXJ0dWFsIH5JdGVtKCkge30KKworICAgIC8vIFRoZXNlIGZ1bmN0aW9ucyByZXR1cm4gdHJ1ZSBpZiB0aGUgZWxlbWVudCB0eXBlIGlzIGNvcnJlc3BvbmRpbmcgdG8gdGhlCisgICAgLy8gdHlwZSBpbiBmdW5jdGlvbiBuYW1lLgorICAgIGJvb2wgSXNNYXAoKSB7IHJldHVybiBpdGVtX3R5cGVfID09IE1BUDsgfQorICAgIGJvb2wgSXNBbnkoKSB7IHJldHVybiBpdGVtX3R5cGVfID09IEFOWTsgfQorCisgICAgQW55V3JpdGVyKiBhbnkoKSBjb25zdCB7IHJldHVybiBhbnlfLmdldCgpOyB9CisKKyAgICB2aXJ0dWFsIEl0ZW0qIHBhcmVudCgpIGNvbnN0IHsKKyAgICAgIHJldHVybiBzdGF0aWNfY2FzdDxJdGVtKj4oQmFzZUVsZW1lbnQ6OnBhcmVudCgpKTsKKyAgICB9CisKKyAgICAvLyBJbnNlcnRzIG1hcCBrZXkgaW50byBoYXNoIHNldCBpZiBhbmQgb25seSBpZiB0aGUga2V5IGRpZCBOT1QgYWxyZWFkeQorICAgIC8vIGV4aXN0IGluIGhhc2ggc2V0LgorICAgIC8vIFRoZSBoYXNoIHNldCAobWFwX2tleXNfKSBpcyBPTkxZIHVzZWQgdG8ga2VlcCB0cmFjayBvZiBtYXAga2V5cy4KKyAgICAvLyBSZXR1cm4gdHJ1ZSBpZiBpbnNlcnQgc3VjY2Vzc2Z1bGx5OyByZXR1cm5zIGZhbHNlIGlmIHRoZSBtYXAga2V5IHdhcworICAgIC8vIGFscmVhZHkgcHJlc2VudC4KKyAgICBib29sIEluc2VydE1hcEtleUlmTm90UHJlc2VudChTdHJpbmdQaWVjZSBtYXBfa2V5KTsKKworICAgIGJvb2wgaXNfcGxhY2Vob2xkZXIoKSBjb25zdCB7IHJldHVybiBpc19wbGFjZWhvbGRlcl87IH0KKyAgICBib29sIGlzX2xpc3QoKSBjb25zdCB7IHJldHVybiBpc19saXN0XzsgfQorCisgICBwcml2YXRlOgorICAgIC8vIFVzZWQgZm9yIGFjY2VzcyB0byB2YXJpYWJsZXMgb2YgdGhlIGVuY2xvc2luZyBpbnN0YW5jZSBvZgorICAgIC8vIFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyLgorICAgIFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyKiBvd187CisKKyAgICAvLyBBIHdyaXRlciBmb3IgQW55IG9iamVjdHMsIGhhbmRsZXMgYWxsIEFueS1yZWxhdGVkIG5vbnNlbnNlLgorICAgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8QW55V3JpdGVyPiBhbnlfOworCisgICAgLy8gVGhlIHR5cGUgb2YgdGhpcyBlbGVtZW50LCBzZWUgZW51bSBmb3IgcGVybWlzc2libGUgdHlwZXMuCisgICAgSXRlbVR5cGUgaXRlbV90eXBlXzsKKworICAgIC8vIFNldCBvZiBtYXAga2V5cyBhbHJlYWR5IHNlZW4gZm9yIHRoZSB0eXBlXy4gVXNlZCB0byB2YWxpZGF0ZSBpbmNvbWluZworICAgIC8vIG1lc3NhZ2VzIHNvIG5vIG1hcCBrZXkgYXBwZWFycyBtb3JlIHRoYW4gb25jZS4KKyAgICBoYXNoX3NldDxzdHJpbmc+IG1hcF9rZXlzXzsKKworICAgIC8vIENvbnZleXMgd2hldGhlciB0aGlzIEl0ZW0gaXMgYSBwbGFjZWhvbGRlciBvciBub3QuIFBsYWNlaG9sZGVyIGl0ZW1zIGFyZQorICAgIC8vIHB1c2hlZCB0byBzdGFjayB0byBhY2NvdW50IGZvciBzcGVjaWFsIHR5cGVzLgorICAgIGJvb2wgaXNfcGxhY2Vob2xkZXJfOworCisgICAgLy8gQ29udmV5cyB3aGV0aGVyIHRoaXMgSXRlbSBpcyBhIGxpc3Qgb3Igbm90LiBUaGlzIGlzIHVzZWQgdG8gc2VuZAorICAgIC8vIFN0YXJ0TGlzdCBvciBFbmRMaXN0IGNhbGxzIHRvIHVuZGVybHlpbmcgT2JqZWN0V3JpdGVyLgorICAgIGJvb2wgaXNfbGlzdF87CisKKyAgICBHT09HTEVfRElTQUxMT1dfSU1QTElDSVRfQ09OU1RSVUNUT1JTKEl0ZW0pOworICB9OworCisgIFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyKGNvbnN0IFR5cGVJbmZvKiB0eXBlaW5mbywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6VHlwZSYgdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nczo6Qnl0ZVNpbmsqIG91dHB1dCwgRXJyb3JMaXN0ZW5lciogbGlzdGVuZXIpOworCisgIC8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgZmllbGQgaXMgYSBtYXAuCisgIGJvb2wgSXNNYXAoY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGQmIGZpZWxkKTsKKworICAvLyBSZXR1cm5zIHRydWUgaWYgdGhlIGZpZWxkIGlzIGFuIGFueS4KKyAgYm9vbCBJc0FueShjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZCYgZmllbGQpOworCisgIC8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgZmllbGQgaXMgZ29vZ2xlLnByb3RvYnVmLlN0cnVjdC4KKyAgYm9vbCBJc1N0cnVjdChjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZCYgZmllbGQpOworCisgIC8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgZmllbGQgaXMgZ29vZ2xlLnByb3RvYnVmLlZhbHVlLgorICBib29sIElzU3RydWN0VmFsdWUoY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGQmIGZpZWxkKTsKKworICAvLyBSZXR1cm5zIHRydWUgaWYgdGhlIGZpZWxkIGlzIGdvb2dsZS5wcm90b2J1Zi5MaXN0VmFsdWUuCisgIGJvb2wgSXNTdHJ1Y3RMaXN0VmFsdWUoY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGQmIGZpZWxkKTsKKworICAvLyBSZW5kZXJzIGdvb2dsZS5wcm90b2J1Zi5WYWx1ZSBpbiBzdHJ1Y3QucHJvdG8uIEl0IHBpY2tzIHRoZSByaWdodCBvbmVvZgorICAvLyB0eXBlIGJhc2VkIG9uIHZhbHVlJ3MgdHlwZS4KKyAgc3RhdGljIHV0aWw6OlN0YXR1cyBSZW5kZXJTdHJ1Y3RWYWx1ZShQcm90b1N0cmVhbU9iamVjdFdyaXRlciogb3csCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEYXRhUGllY2UmIHZhbHVlKTsKKworICAvLyBSZW5kZXJzIGdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAgdmFsdWUuCisgIHN0YXRpYyB1dGlsOjpTdGF0dXMgUmVuZGVyVGltZXN0YW1wKFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyKiBvdywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEYXRhUGllY2UmIHZhbHVlKTsKKworICAvLyBSZW5kZXJzIGdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2sgdmFsdWUuCisgIHN0YXRpYyB1dGlsOjpTdGF0dXMgUmVuZGVyRmllbGRNYXNrKFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyKiBvdywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEYXRhUGllY2UmIHZhbHVlKTsKKworICAvLyBSZW5kZXJzIGdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiB2YWx1ZS4KKyAgc3RhdGljIHV0aWw6OlN0YXR1cyBSZW5kZXJEdXJhdGlvbihQcm90b1N0cmVhbU9iamVjdFdyaXRlciogb3csCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEYXRhUGllY2UmIHZhbHVlKTsKKworICAvLyBSZW5kZXJzIHdyYXBwZXIgbWVzc2FnZSB0eXBlcyBmb3IgcHJpbWl0aXZlIHR5cGVzIGluCisgIC8vIGdvb2dsZS9wcm90b2J1Zi93cmFwcGVycy5wcm90by4KKyAgc3RhdGljIHV0aWw6OlN0YXR1cyBSZW5kZXJXcmFwcGVyVHlwZShQcm90b1N0cmVhbU9iamVjdFdyaXRlciogb3csCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEYXRhUGllY2UmIHZhbHVlKTsKKworICBzdGF0aWMgdm9pZCBJbml0UmVuZGVyZXJNYXAoKTsKKyAgc3RhdGljIHZvaWQgRGVsZXRlUmVuZGVyZXJNYXAoKTsKKyAgc3RhdGljIFR5cGVSZW5kZXJlciogRmluZFR5cGVSZW5kZXJlcihjb25zdCBzdHJpbmcmIHR5cGVfdXJsKTsKKworICAvLyBSZXR1cm5zIHRydWUgaWYgdGhlIG1hcCBrZXkgZm9yIHR5cGVfIGlzIG5vdCBkdXBsaWNhdGVkIGtleS4KKyAgLy8gSWYgbWFwIGtleSBpcyBkdXBsaWNhdGVkIGtleSwgdGhpcyBmdW5jdGlvbiByZXR1cm5zIGZhbHNlLgorICAvLyBOb3RlIHRoYXQgY2FsbGVyIHNob3VsZCBtYWtlIHN1cmUgdGhhdCB0aGUgY3VycmVudCBwcm90byBlbGVtZW50IChjdXJyZW50XykKKyAgLy8gaXMgb2YgZWxlbWVudCB0eXBlIE1BUCBvciBTVFJVQ1RfTUFQLgorICAvLyBJdCBhbHNvIGNhbGxzIHRoZSBhcHByb3ByaWF0ZSBlcnJvciBjYWxsYmFjayBhbmQgdW5ub3JtYWx6aWVkX25hbWUgaXMgdXNlZAorICAvLyBmb3IgZXJyb3Igc3RyaW5nLgorICBib29sIFZhbGlkTWFwS2V5KFN0cmluZ1BpZWNlIHVubm9ybWFsaXplZF9uYW1lKTsKKworICAvLyBQdXNoZXMgYW4gaXRlbSBvbiB0byB0aGUgc3RhY2suIEFsc28gY2FsbHMgZWl0aGVyIFN0YXJ0T2JqZWN0IG9yIFN0YXJ0TGlzdAorICAvLyBvbiB0aGUgdW5kZXJseWluZyBPYmplY3RXcml0ZXIgZGVwZW5kaW5nIG9uIHdoZXRoZXIgaXNfbGlzdCBpcyBmYWxzZSBvcgorICAvLyBub3QuCisgIC8vIGlzX3BsYWNlaG9sZGVyIGNvbnZleXMgd2hldGhlciB0aGUgaXRlbSBpcyBhIHBsYWNlaG9sZGVyIGl0ZW0gb3Igbm90LgorICAvLyBQbGFjZWhvbGRlciBpdGVtcyBhcmUgcHVzaGVkIHdoZW4gYWRkaW5nIGF1eGlsbGFyeSB0eXBlcycgU3RhcnRPYmplY3Qgb3IKKyAgLy8gU3RhcnRMaXN0IGNhbGxzLgorICB2b2lkIFB1c2goU3RyaW5nUGllY2UgbmFtZSwgSXRlbTo6SXRlbVR5cGUgaXRlbV90eXBlLCBib29sIGlzX3BsYWNlaG9sZGVyLAorICAgICAgICAgICAgYm9vbCBpc19saXN0KTsKKworICAvLyBQb3BzIGl0ZW1zIGZyb20gdGhlIHN0YWNrLiBBbGwgcGxhY2Vob2xkZXIgaXRlbXMgYXJlIHBvcHBlZCB1bnRpbCBhCisgIC8vIG5vbi1wbGFjZWhvbGRlciBpdGVtIGlzIGZvdW5kLgorICB2b2lkIFBvcCgpOworCisgIC8vIFBvcHMgb25lIGVsZW1lbnQgZnJvbSB0aGUgc3RhY2suIENhbGxzIEVuZE9iamVjdCgpIG9yIEVuZExpc3QoKSBvbiB0aGUKKyAgLy8gdW5kZXJseWluZyBPYmplY3RXcml0ZXIgZGVwZW5kaW5nIG9uIHRoZSB2YWx1ZSBvZiBpc19saXN0Xy4KKyAgdm9pZCBQb3BPbmVFbGVtZW50KCk7CisKKyBwcml2YXRlOgorICAvLyBIZWxwZXIgZnVuY3Rpb25zIHRvIGNyZWF0ZSB0aGUgbWFwIGFuZCBmaW5kIGZ1bmN0aW9ucyByZXNwb25zaWJsZSBmb3IKKyAgLy8gcmVuZGVyaW5nIHdlbGwga25vd24gdHlwZXMsIGtleWVkIGJ5IHR5cGUgVVJMLgorICBzdGF0aWMgaGFzaF9tYXA8c3RyaW5nLCBUeXBlUmVuZGVyZXI+KiByZW5kZXJlcnNfOworCisgIC8vIFZhcmlhYmxlcyBmb3IgZGVzY3JpYmluZyB0aGUgc3RydWN0dXJlIG9mIHRoZSBpbnB1dCB0cmVlOgorICAvLyBtYXN0ZXJfdHlwZV86IGRlc2NyaXB0b3IgZm9yIHRoZSB3aG9sZSBwcm90b2J1ZiBtZXNzYWdlLgorICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlJiBtYXN0ZXJfdHlwZV87CisKKyAgLy8gVGhlIGN1cnJlbnQgZWxlbWVudCwgdmFyaWFibGUgZm9yIGludGVybmFsIHN0YXRlIHByb2Nlc3NpbmcuCisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8SXRlbT4gY3VycmVudF87CisKKyAgR09PR0xFX0RJU0FMTE9XX0lNUExJQ0lUX0NPTlNUUlVDVE9SUyhQcm90b1N0cmVhbU9iamVjdFdyaXRlcik7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgY29udmVydGVyCit9ICAvLyBuYW1lc3BhY2UgdXRpbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX1VUSUxfQ09OVkVSVEVSX1BST1RPU1RSRUFNX09CSkVDVFdSSVRFUl9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9wcm90b3N0cmVhbV9vYmplY3R3cml0ZXJfdGVzdC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9wcm90b3N0cmVhbV9vYmplY3R3cml0ZXJfdGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ZjlmZmI5Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3Byb3Rvc3RyZWFtX29iamVjdHdyaXRlcl90ZXN0LmNjCkBAIC0wLDAgKzEsMTg5NSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9wcm90b3N0cmVhbV9vYmplY3R3cml0ZXIuaD4KKworI2luY2x1ZGUgPHN0ZGRlZi5oPiAgLy8gRm9yIHNpemVfdAorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2ZpZWxkX21hc2sucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGltZXN0YW1wLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dyYXBwZXJzLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbF9saXRlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9keW5hbWljX21lc3NhZ2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWVzc2FnZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL21vY2tfZXJyb3JfbGlzdGVuZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90ZXN0ZGF0YS9ib29rcy5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3Rlc3RkYXRhL2ZpZWxkX21hc2sucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90eXBlX2luZm9fdGVzdF9oZWxwZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9jb25zdGFudHMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9tZXNzYWdlX2RpZmZlcmVuY2VyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2J5dGVzdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3Rlc3RkYXRhL2FueXMucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90ZXN0ZGF0YS9tYXBzLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvdGVzdGRhdGEvb25lb2ZzLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvdGVzdGRhdGEvc3RydWN0LnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvdGVzdGRhdGEvdGltZXN0YW1wX2R1cmF0aW9uLnBiLmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKworCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgdXRpbCB7CituYW1lc3BhY2UgY29udmVydGVyIHsKKwordXNpbmcgZ29vZ2xlOjpwcm90b2J1Zjo6dGVzdGluZzo6QXV0aG9yOwordXNpbmcgZ29vZ2xlOjpwcm90b2J1Zjo6dGVzdGluZzo6Qm9vazsKK3VzaW5nIGdvb2dsZTo6cHJvdG9idWY6OnRlc3Rpbmc6OkJvb2tfRGF0YTsKK3VzaW5nIGdvb2dsZTo6cHJvdG9idWY6OnRlc3Rpbmc6OlByaW1pdGl2ZTsKK3VzaW5nIGdvb2dsZTo6cHJvdG9idWY6OnRlc3Rpbmc6OlB1Ymxpc2hlcjsKK3VzaW5nIGdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3I7Cit1c2luZyBnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUG9vbDsKK3VzaW5nIGdvb2dsZTo6cHJvdG9idWY6OkR5bmFtaWNNZXNzYWdlRmFjdG9yeTsKK3VzaW5nIGdvb2dsZTo6cHJvdG9idWY6OkZpbGVEZXNjcmlwdG9yUHJvdG87Cit1c2luZyBnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlOwordXNpbmcgZ29vZ2xlOjpwcm90b2J1Zjo6aW86OkFycmF5SW5wdXRTdHJlYW07Cit1c2luZyBzdHJpbmdzOjpHcm93aW5nQXJyYXlCeXRlU2luazsKK3VzaW5nIDo6dGVzdGluZzo6XzsKK3VzaW5nIDo6dGVzdGluZzo6QXJnczsKK3VzaW5nIGdvb2dsZTo6cHJvdG9idWY6OnRlc3Rpbmc6OmFueXM6OkFueU07Cit1c2luZyBnb29nbGU6OnByb3RvYnVmOjp0ZXN0aW5nOjphbnlzOjpBbnlPdXQ7Cit1c2luZyBnb29nbGU6OnByb3RvYnVmOjp0ZXN0aW5nOjpvbmVvZnM6Ok9uZU9mc1JlcXVlc3Q7Cit1c2luZyBnb29nbGU6OnByb3RvYnVmOjp0ZXN0aW5nOjpGaWVsZE1hc2tUZXN0OwordXNpbmcgZ29vZ2xlOjpwcm90b2J1Zjo6dGVzdGluZzo6bWFwczo6TWFwSW47Cit1c2luZyBnb29nbGU6OnByb3RvYnVmOjp0ZXN0aW5nOjpzdHJ1Y3RzOjpTdHJ1Y3RUeXBlOwordXNpbmcgZ29vZ2xlOjpwcm90b2J1Zjo6dGVzdGluZzo6dGltZXN0YW1wZHVyYXRpb246OlRpbWVzdGFtcER1cmF0aW9uOworCisKK25hbWVzcGFjZSB7CitzdHJpbmcgR2V0VHlwZVVybChjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKSB7CisgIHJldHVybiBzdHJpbmcoa1R5cGVTZXJ2aWNlQmFzZVVybCkgKyAiLyIgKyBkZXNjcmlwdG9yLT5mdWxsX25hbWUoKTsKK30KK30gIC8vIG5hbWVzcGFjZQorCitjbGFzcyBCYXNlUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJUZXN0CisgICAgOiBwdWJsaWMgOjp0ZXN0aW5nOjpUZXN0V2l0aFBhcmFtPHRlc3Rpbmc6OlR5cGVJbmZvU291cmNlPiB7CisgcHJvdGVjdGVkOgorICBCYXNlUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJUZXN0KCkKKyAgICAgIDogaGVscGVyXyhHZXRQYXJhbSgpKSwKKyAgICAgICAgbGlzdGVuZXJfKCksCisgICAgICAgIG91dHB1dF8obmV3IEdyb3dpbmdBcnJheUJ5dGVTaW5rKDEwMDApKSwKKyAgICAgICAgb3dfKCkge30KKworICBleHBsaWNpdCBCYXNlUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJUZXN0KGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpCisgICAgICA6IGhlbHBlcl8oR2V0UGFyYW0oKSksCisgICAgICAgIGxpc3RlbmVyXygpLAorICAgICAgICBvdXRwdXRfKG5ldyBHcm93aW5nQXJyYXlCeXRlU2luaygxMDAwKSksCisgICAgICAgIG93XygpIHsKKyAgICB2ZWN0b3I8Y29uc3QgRGVzY3JpcHRvcio+IGRlc2NyaXB0b3JzOworICAgIGRlc2NyaXB0b3JzLnB1c2hfYmFjayhkZXNjcmlwdG9yKTsKKyAgICBSZXNldFR5cGVJbmZvKGRlc2NyaXB0b3JzKTsKKyAgfQorCisgIGV4cGxpY2l0IEJhc2VQcm90b1N0cmVhbU9iamVjdFdyaXRlclRlc3QoCisgICAgICB2ZWN0b3I8Y29uc3QgRGVzY3JpcHRvcio+IGRlc2NyaXB0b3JzKQorICAgICAgOiBoZWxwZXJfKEdldFBhcmFtKCkpLAorICAgICAgICBsaXN0ZW5lcl8oKSwKKyAgICAgICAgb3V0cHV0XyhuZXcgR3Jvd2luZ0FycmF5Qnl0ZVNpbmsoMTAwMCkpLAorICAgICAgICBvd18oKSB7CisgICAgUmVzZXRUeXBlSW5mbyhkZXNjcmlwdG9ycyk7CisgIH0KKworICB2b2lkIFJlc2V0VHlwZUluZm8odmVjdG9yPGNvbnN0IERlc2NyaXB0b3IqPiBkZXNjcmlwdG9ycykgeworICAgIEdPT0dMRV9DSEVDSyghZGVzY3JpcHRvcnMuZW1wdHkoKSkgPDwgIk11c3QgaGF2ZSBhdCBsZWFzdCBvbmUgZGVzY3JpcHRvciEiOworICAgIGhlbHBlcl8uUmVzZXRUeXBlSW5mbyhkZXNjcmlwdG9ycyk7CisgICAgb3dfLnJlc2V0KGhlbHBlcl8uTmV3UHJvdG9Xcml0ZXIoR2V0VHlwZVVybChkZXNjcmlwdG9yc1swXSksIG91dHB1dF8uZ2V0KCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmxpc3RlbmVyXykpOworICB9CisKKyAgdmlydHVhbCB+QmFzZVByb3RvU3RyZWFtT2JqZWN0V3JpdGVyVGVzdCgpIHt9CisKKyAgdm9pZCBDaGVja091dHB1dChjb25zdCBNZXNzYWdlJiBleHBlY3RlZCwgaW50IGV4cGVjdGVkX2xlbmd0aCkgeworICAgIHNpemVfdCBuYnl0ZXM7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX2FycmF5PGNoYXI+IGJ1ZmZlcihvdXRwdXRfLT5HZXRCdWZmZXIoJm5ieXRlcykpOworICAgIGlmIChleHBlY3RlZF9sZW5ndGggPj0gMCkgeworICAgICAgRVhQRUNUX0VRKGV4cGVjdGVkX2xlbmd0aCwgbmJ5dGVzKTsKKyAgICB9CisgICAgc3RyaW5nIHN0cihidWZmZXIuZ2V0KCksIG5ieXRlcyk7CisKKyAgICBzdGQ6OnN0cmluZ2J1ZiBzdHJfYnVmKHN0ciwgc3RkOjppb3NfYmFzZTo6aW4pOworICAgIHN0ZDo6aXN0cmVhbSBpc3RyZWFtKCZzdHJfYnVmKTsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPE1lc3NhZ2U+IG1lc3NhZ2UoZXhwZWN0ZWQuTmV3KCkpOworICAgIG1lc3NhZ2UtPlBhcnNlUGFydGlhbEZyb21Jc3RyZWFtKCZpc3RyZWFtKTsKKworICAgIGlmICghTWVzc2FnZURpZmZlcmVuY2VyOjpFcXVpdmFsZW50KGV4cGVjdGVkLCAqbWVzc2FnZSkpIHsKKyAgICAgIEVYUEVDVF9FUShleHBlY3RlZC5EZWJ1Z1N0cmluZygpLCBtZXNzYWdlLT5EZWJ1Z1N0cmluZygpKTsKKyAgICB9CisgIH0KKworICB2b2lkIENoZWNrT3V0cHV0KGNvbnN0IE1lc3NhZ2UmIGV4cGVjdGVkKSB7IENoZWNrT3V0cHV0KGV4cGVjdGVkLCAtMSk7IH0KKworICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlKiBHZXRUeXBlKGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgICByZXR1cm4gaGVscGVyXy5HZXRUeXBlSW5mbygpLT5HZXRUeXBlQnlUeXBlVXJsKEdldFR5cGVVcmwoZGVzY3JpcHRvcikpOworICB9CisKKyAgdGVzdGluZzo6VHlwZUluZm9UZXN0SGVscGVyIGhlbHBlcl87CisgIE1vY2tFcnJvckxpc3RlbmVyIGxpc3RlbmVyXzsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxHcm93aW5nQXJyYXlCeXRlU2luaz4gb3V0cHV0XzsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxQcm90b1N0cmVhbU9iamVjdFdyaXRlcj4gb3dfOworfTsKKworTUFUQ0hFUl9QKEhhc09iamVjdExvY2F0aW9uLCBleHBlY3RlZCwKKyAgICAgICAgICAiVmVyaWZpZXMgdGhlIGV4cGVjdGVkIG9iamVjdCBsb2NhdGlvbiIpIHsKKyAgc3RyaW5nIGFjdHVhbDsKKyNpZiBfX2NwbHVzcGx1cyA+PSAyMDExMDNMCisgIGFjdHVhbCA9IHN0ZDo6Z2V0PDA+KGFyZykuVG9TdHJpbmcoKTsKKyNlbHNlCisgIGFjdHVhbCA9IHN0ZDo6dHIxOjpnZXQ8MD4oYXJnKS5Ub1N0cmluZygpOworI2VuZGlmCisgIGlmIChhY3R1YWwuY29tcGFyZShleHBlY3RlZCkgPT0gMCkgcmV0dXJuIHRydWU7CisgICpyZXN1bHRfbGlzdGVuZXIgPDwgImFjdHVhbCBsb2NhdGlvbiBpczogIiA8PCBhY3R1YWw7CisgIHJldHVybiBmYWxzZTsKK30KKworY2xhc3MgUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJUZXN0IDogcHVibGljIEJhc2VQcm90b1N0cmVhbU9iamVjdFdyaXRlclRlc3QgeworIHByb3RlY3RlZDoKKyAgUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJUZXN0KCkKKyAgICAgIDogQmFzZVByb3RvU3RyZWFtT2JqZWN0V3JpdGVyVGVzdChCb29rOjpkZXNjcmlwdG9yKCkpIHt9CisKKyAgdmlydHVhbCB+UHJvdG9TdHJlYW1PYmplY3RXcml0ZXJUZXN0KCkge30KK307CisKK0lOU1RBTlRJQVRFX1RFU1RfQ0FTRV9QKERpZmZlcmVudFR5cGVJbmZvU291cmNlVGVzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgIFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyVGVzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgIDo6dGVzdGluZzo6VmFsdWVzKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlc3Rpbmc6OlVTRV9UWVBFX1JFU09MVkVSKSk7CisKK1RFU1RfUChQcm90b1N0cmVhbU9iamVjdFdyaXRlclRlc3QsIEVtcHR5T2JqZWN0KSB7CisgIEJvb2sgZW1wdHk7CisgIG93Xy0+U3RhcnRPYmplY3QoIiIpLT5FbmRPYmplY3QoKTsKKyAgQ2hlY2tPdXRwdXQoZW1wdHksIDApOworfQorCitURVNUX1AoUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJUZXN0LCBTaW1wbGVPYmplY3QpIHsKKyAgc3RyaW5nIGNvbnRlbnQoIk15IGNvbnRlbnQiKTsKKworICBCb29rIGJvb2s7CisgIGJvb2suc2V0X3RpdGxlKCJNeSBUaXRsZSIpOworICBib29rLnNldF9sZW5ndGgoMjIyKTsKKyAgYm9vay5zZXRfY29udGVudChjb250ZW50KTsKKworICBvd18tPlN0YXJ0T2JqZWN0KCIiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoInRpdGxlIiwgIk15IFRpdGxlIikKKyAgICAgIC0+UmVuZGVySW50MzIoImxlbmd0aCIsIDIyMikKKyAgICAgIC0+UmVuZGVyQnl0ZXMoImNvbnRlbnQiLCBjb250ZW50KQorICAgICAgLT5FbmRPYmplY3QoKTsKKyAgQ2hlY2tPdXRwdXQoYm9vayk7Cit9CisKK1RFU1RfUChQcm90b1N0cmVhbU9iamVjdFdyaXRlclRlc3QsIFNpbXBsZU1lc3NhZ2UpIHsKKyAgQm9vayBib29rOworICBib29rLnNldF90aXRsZSgiU29tZSBCb29rIik7CisgIGJvb2suc2V0X2xlbmd0aCgxMDIpOworICBQdWJsaXNoZXIqIHB1Ymxpc2hlciA9IGJvb2subXV0YWJsZV9wdWJsaXNoZXIoKTsKKyAgcHVibGlzaGVyLT5zZXRfbmFtZSgiTXkgUHVibGlzaGVyIik7CisgIEF1dGhvciogcm9iZXJ0ID0gYm9vay5tdXRhYmxlX2F1dGhvcigpOworICByb2JlcnQtPnNldF9hbGl2ZSh0cnVlKTsKKyAgcm9iZXJ0LT5zZXRfbmFtZSgicm9iZXJ0Iik7CisgIHJvYmVydC0+YWRkX3BzZXVkb255bSgiYm9iIik7CisgIHJvYmVydC0+YWRkX3BzZXVkb255bSgiYm9iYnkiKTsKKyAgcm9iZXJ0LT5hZGRfZnJpZW5kXygpLT5zZXRfbmFtZSgiam9obiIpOworCisgIG93Xy0+U3RhcnRPYmplY3QoIiIpCisgICAgICAtPlJlbmRlclN0cmluZygidGl0bGUiLCAiU29tZSBCb29rIikKKyAgICAgIC0+UmVuZGVySW50MzIoImxlbmd0aCIsIDEwMikKKyAgICAgIC0+U3RhcnRPYmplY3QoInB1Ymxpc2hlciIpCisgICAgICAtPlJlbmRlclN0cmluZygibmFtZSIsICJNeSBQdWJsaXNoZXIiKQorICAgICAgLT5FbmRPYmplY3QoKQorICAgICAgLT5TdGFydE9iamVjdCgiYXV0aG9yIikKKyAgICAgIC0+UmVuZGVyQm9vbCgiYWxpdmUiLCB0cnVlKQorICAgICAgLT5SZW5kZXJTdHJpbmcoIm5hbWUiLCAicm9iZXJ0IikKKyAgICAgIC0+U3RhcnRMaXN0KCJwc2V1ZG9ueW0iKQorICAgICAgLT5SZW5kZXJTdHJpbmcoIiIsICJib2IiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoIiIsICJib2JieSIpCisgICAgICAtPkVuZExpc3QoKQorICAgICAgLT5TdGFydExpc3QoImZyaWVuZCIpCisgICAgICAtPlN0YXJ0T2JqZWN0KCIiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoIm5hbWUiLCAiam9obiIpCisgICAgICAtPkVuZE9iamVjdCgpCisgICAgICAtPkVuZExpc3QoKQorICAgICAgLT5FbmRPYmplY3QoKQorICAgICAgLT5FbmRPYmplY3QoKTsKKyAgQ2hlY2tPdXRwdXQoYm9vayk7Cit9CisKK1RFU1RfUChQcm90b1N0cmVhbU9iamVjdFdyaXRlclRlc3QsIEN1c3RvbUpzb25OYW1lKSB7CisgIEJvb2sgYm9vazsKKyAgQXV0aG9yKiByb2JlcnQgPSBib29rLm11dGFibGVfYXV0aG9yKCk7CisgIHJvYmVydC0+c2V0X2lkKDEyMzQ1KTsKKyAgcm9iZXJ0LT5zZXRfbmFtZSgicm9iZXJ0Iik7CisKKyAgb3dfLT5TdGFydE9iamVjdCgiIikKKyAgICAgIC0+U3RhcnRPYmplY3QoImF1dGhvciIpCisgICAgICAtPlJlbmRlclVpbnQ2NCgiQGlkIiwgMTIzNDUpCisgICAgICAtPlJlbmRlclN0cmluZygibmFtZSIsICJyb2JlcnQiKQorICAgICAgLT5FbmRPYmplY3QoKQorICAgICAgLT5FbmRPYmplY3QoKTsKKyAgQ2hlY2tPdXRwdXQoYm9vayk7Cit9CisKK1RFU1RfUChQcm90b1N0cmVhbU9iamVjdFdyaXRlclRlc3QsIFByaW1pdGl2ZUZyb21TdHJpbmdDb252ZXJzaW9uKSB7CisgIFByaW1pdGl2ZSBmdWxsOworICBmdWxsLnNldF9maXgzMigxMDEpOworICBmdWxsLnNldF91MzIoMTAyKTsKKyAgZnVsbC5zZXRfaTMyKC0xMDMpOworICBmdWxsLnNldF9zZjMyKC0xMDQpOworICBmdWxsLnNldF9zMzIoLTEwNSk7CisgIGZ1bGwuc2V0X2ZpeDY0KDQwMDAwMDAwMDAxTCk7CisgIGZ1bGwuc2V0X3U2NCg0MDAwMDAwMDAwMkwpOworICBmdWxsLnNldF9pNjQoLTQwMDAwMDAwMDAzTCk7CisgIGZ1bGwuc2V0X3NmNjQoLTQwMDAwMDAwMDA0TCk7CisgIGZ1bGwuc2V0X3M2NCgtNDAwMDAwMDAwMDVMKTsKKyAgZnVsbC5zZXRfc3RyKCJzdHJpbmcxIik7CisgIGZ1bGwuc2V0X2J5dGVzKCJTb21lIEJ5dGVzIik7CisgIGZ1bGwuc2V0X2Zsb2F0XygzLjE0Zik7CisgIGZ1bGwuc2V0X2RvdWJsZV8oLTQuMDVMKTsKKyAgZnVsbC5zZXRfYm9vbF8odHJ1ZSk7CisgIGZ1bGwuYWRkX3JlcF9maXgzMigyMDEpOworICBmdWxsLmFkZF9yZXBfdTMyKDIwMik7CisgIGZ1bGwuYWRkX3JlcF9pMzIoLTIwMyk7CisgIGZ1bGwuYWRkX3JlcF9zZjMyKC0yMDQpOworICBmdWxsLmFkZF9yZXBfczMyKC0yMDUpOworICBmdWxsLmFkZF9yZXBfZml4NjQoODAwMDAwMDAwMDFMKTsKKyAgZnVsbC5hZGRfcmVwX3U2NCg4MDAwMDAwMDAwMkwpOworICBmdWxsLmFkZF9yZXBfaTY0KC04MDAwMDAwMDAwM0wpOworICBmdWxsLmFkZF9yZXBfc2Y2NCgtODAwMDAwMDAwMDRMKTsKKyAgZnVsbC5hZGRfcmVwX3M2NCgtODAwMDAwMDAwMDVMKTsKKyAgZnVsbC5hZGRfcmVwX3N0cigic3RyaW5nMiIpOworICBmdWxsLmFkZF9yZXBfYnl0ZXMoIk1vcmUgQnl0ZXMiKTsKKyAgZnVsbC5hZGRfcmVwX2Zsb2F0KDYuMTRmKTsKKyAgZnVsbC5hZGRfcmVwX2RvdWJsZSgtOC4wNUwpOworICBmdWxsLmFkZF9yZXBfYm9vbChmYWxzZSk7CisKKyAgb3dfLnJlc2V0KGhlbHBlcl8uTmV3UHJvdG9Xcml0ZXIoR2V0VHlwZVVybChQcmltaXRpdmU6OmRlc2NyaXB0b3IoKSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dF8uZ2V0KCksICZsaXN0ZW5lcl8pKTsKKworICBvd18tPlN0YXJ0T2JqZWN0KCIiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoImZpeDMyIiwgIjEwMSIpCisgICAgICAtPlJlbmRlclN0cmluZygidTMyIiwgIjEwMiIpCisgICAgICAtPlJlbmRlclN0cmluZygiaTMyIiwgIi0xMDMiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoInNmMzIiLCAiLTEwNCIpCisgICAgICAtPlJlbmRlclN0cmluZygiczMyIiwgIi0xMDUiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoImZpeDY0IiwgIjQwMDAwMDAwMDAxIikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJ1NjQiLCAiNDAwMDAwMDAwMDIiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoImk2NCIsICItNDAwMDAwMDAwMDMiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoInNmNjQiLCAiLTQwMDAwMDAwMDA0IikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJzNjQiLCAiLTQwMDAwMDAwMDA1IikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJzdHIiLCAic3RyaW5nMSIpCisgICAgICAtPlJlbmRlclN0cmluZygiYnl0ZXMiLCAiVTI5dFpTQkNlWFJsY3c9PSIpICAvLyAiU29tZSBCeXRlcyIKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJmbG9hdCIsICIzLjE0IikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJkb3VibGUiLCAiLTQuMDUiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoImJvb2wiLCAidHJ1ZSIpCisgICAgICAtPlN0YXJ0TGlzdCgicmVwX2ZpeDMyIikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCIiLCAiMjAxIikKKyAgICAgIC0+RW5kTGlzdCgpCisgICAgICAtPlN0YXJ0TGlzdCgicmVwX3UzMiIpCisgICAgICAtPlJlbmRlclN0cmluZygiIiwgIjIwMiIpCisgICAgICAtPkVuZExpc3QoKQorICAgICAgLT5TdGFydExpc3QoInJlcF9pMzIiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoIiIsICItMjAzIikKKyAgICAgIC0+RW5kTGlzdCgpCisgICAgICAtPlN0YXJ0TGlzdCgicmVwX3NmMzIiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoIiIsICItMjA0IikKKyAgICAgIC0+RW5kTGlzdCgpCisgICAgICAtPlN0YXJ0TGlzdCgicmVwX3MzMiIpCisgICAgICAtPlJlbmRlclN0cmluZygiIiwgIi0yMDUiKQorICAgICAgLT5FbmRMaXN0KCkKKyAgICAgIC0+U3RhcnRMaXN0KCJyZXBfZml4NjQiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoIiIsICI4MDAwMDAwMDAwMSIpCisgICAgICAtPkVuZExpc3QoKQorICAgICAgLT5TdGFydExpc3QoInJlcF91NjQiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoIiIsICI4MDAwMDAwMDAwMiIpCisgICAgICAtPkVuZExpc3QoKQorICAgICAgLT5TdGFydExpc3QoInJlcF9pNjQiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoIiIsICItODAwMDAwMDAwMDMiKQorICAgICAgLT5FbmRMaXN0KCkKKyAgICAgIC0+U3RhcnRMaXN0KCJyZXBfc2Y2NCIpCisgICAgICAtPlJlbmRlclN0cmluZygiIiwgIi04MDAwMDAwMDAwNCIpCisgICAgICAtPkVuZExpc3QoKQorICAgICAgLT5TdGFydExpc3QoInJlcF9zNjQiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoIiIsICItODAwMDAwMDAwMDUiKQorICAgICAgLT5FbmRMaXN0KCkKKyAgICAgIC0+U3RhcnRMaXN0KCJyZXBfc3RyIikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCIiLCAic3RyaW5nMiIpCisgICAgICAtPkVuZExpc3QoKQorICAgICAgLT5TdGFydExpc3QoInJlcF9ieXRlcyIpCisgICAgICAtPlJlbmRlclN0cmluZygiIiwgIlRXOXlaU0JDZVhSbGN3PT0iKSAgLy8gIk1vcmUgQnl0ZXMiCisgICAgICAtPkVuZExpc3QoKQorICAgICAgLT5TdGFydExpc3QoInJlcF9mbG9hdCIpCisgICAgICAtPlJlbmRlclN0cmluZygiIiwgIjYuMTQiKQorICAgICAgLT5FbmRMaXN0KCkKKyAgICAgIC0+U3RhcnRMaXN0KCJyZXBfZG91YmxlIikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCIiLCAiLTguMDUiKQorICAgICAgLT5FbmRMaXN0KCkKKyAgICAgIC0+U3RhcnRMaXN0KCJyZXBfYm9vbCIpCisgICAgICAtPlJlbmRlclN0cmluZygiIiwgImZhbHNlIikKKyAgICAgIC0+RW5kTGlzdCgpCisgICAgICAtPkVuZE9iamVjdCgpOworICBDaGVja091dHB1dChmdWxsKTsKK30KKworVEVTVF9QKFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyVGVzdCwgSW5maW5pdHlJbnB1dFRlc3QpIHsKKyAgUHJpbWl0aXZlIGZ1bGw7CisgIGZ1bGwuc2V0X2RvdWJsZV8oc3RkOjpudW1lcmljX2xpbWl0czxkb3VibGU+OjppbmZpbml0eSgpKTsKKyAgZnVsbC5zZXRfZmxvYXRfKHN0ZDo6bnVtZXJpY19saW1pdHM8ZmxvYXQ+OjppbmZpbml0eSgpKTsKKyAgZnVsbC5zZXRfc3RyKCItSW5maW5pdHkiKTsKKworICBvd18ucmVzZXQoaGVscGVyXy5OZXdQcm90b1dyaXRlcihHZXRUeXBlVXJsKFByaW1pdGl2ZTo6ZGVzY3JpcHRvcigpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0Xy5nZXQoKSwgJmxpc3RlbmVyXykpOworCisgIEVYUEVDVF9DQUxMKGxpc3RlbmVyXywgSW52YWxpZFZhbHVlKF8sIFN0cmluZ1BpZWNlKCJUWVBFX0lOVDMyIiksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1BpZWNlKCJcIkluZmluaXR5XCIiKSkpCisgICAgICAuV2l0aChBcmdzPDA+KEhhc09iamVjdExvY2F0aW9uKCJpMzIiKSkpOworICBFWFBFQ1RfQ0FMTChsaXN0ZW5lcl8sIEludmFsaWRWYWx1ZShfLCBTdHJpbmdQaWVjZSgiVFlQRV9VSU5UMzIiKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UoIlwiSW5maW5pdHlcIiIpKSkKKyAgICAgIC5XaXRoKEFyZ3M8MD4oSGFzT2JqZWN0TG9jYXRpb24oInUzMiIpKSk7CisgIEVYUEVDVF9DQUxMKGxpc3RlbmVyXywgSW52YWxpZFZhbHVlKF8sIFN0cmluZ1BpZWNlKCJUWVBFX1NGSVhFRDY0IiksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1BpZWNlKCJcIi1JbmZpbml0eVwiIikpKQorICAgICAgLldpdGgoQXJnczwwPihIYXNPYmplY3RMb2NhdGlvbigic2Y2NCIpKSk7CisgIEVYUEVDVF9DQUxMKGxpc3RlbmVyXywgSW52YWxpZFZhbHVlKF8sIFN0cmluZ1BpZWNlKCJUWVBFX0JPT0wiKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UoIlwiSW5maW5pdHlcIiIpKSkKKyAgICAgIC5XaXRoKEFyZ3M8MD4oSGFzT2JqZWN0TG9jYXRpb24oImJvb2wiKSkpOworCisgIG93Xy0+U3RhcnRPYmplY3QoIiIpCisgICAgICAtPlJlbmRlclN0cmluZygiZG91YmxlIiwgIkluZmluaXR5IikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJmbG9hdCIsICJJbmZpbml0eSIpCisgICAgICAtPlJlbmRlclN0cmluZygiaTMyIiwgIkluZmluaXR5IikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJ1MzIiLCAiSW5maW5pdHkiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoInNmNjQiLCAiLUluZmluaXR5IikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJzdHIiLCAiLUluZmluaXR5IikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJib29sIiwgIkluZmluaXR5IikKKyAgICAgIC0+RW5kT2JqZWN0KCk7CisgIENoZWNrT3V0cHV0KGZ1bGwpOworfQorCitURVNUX1AoUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJUZXN0LCBOYU5JbnB1dFRlc3QpIHsKKyAgUHJpbWl0aXZlIGZ1bGw7CisgIGZ1bGwuc2V0X2RvdWJsZV8oc3RkOjpudW1lcmljX2xpbWl0czxkb3VibGU+OjpxdWlldF9OYU4oKSk7CisgIGZ1bGwuc2V0X2Zsb2F0XyhzdGQ6Om51bWVyaWNfbGltaXRzPGZsb2F0Pjo6cXVpZXRfTmFOKCkpOworICBmdWxsLnNldF9zdHIoIk5hTiIpOworCisgIG93Xy5yZXNldChoZWxwZXJfLk5ld1Byb3RvV3JpdGVyKEdldFR5cGVVcmwoUHJpbWl0aXZlOjpkZXNjcmlwdG9yKCkpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXRfLmdldCgpLCAmbGlzdGVuZXJfKSk7CisKKyAgRVhQRUNUX0NBTEwobGlzdGVuZXJfLCBJbnZhbGlkVmFsdWUoXywgU3RyaW5nUGllY2UoIlRZUEVfSU5UMzIiKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UoIlwiTmFOXCIiKSkpCisgICAgICAuV2l0aChBcmdzPDA+KEhhc09iamVjdExvY2F0aW9uKCJpMzIiKSkpOworICBFWFBFQ1RfQ0FMTChsaXN0ZW5lcl8sIEludmFsaWRWYWx1ZShfLCBTdHJpbmdQaWVjZSgiVFlQRV9VSU5UMzIiKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UoIlwiTmFOXCIiKSkpCisgICAgICAuV2l0aChBcmdzPDA+KEhhc09iamVjdExvY2F0aW9uKCJ1MzIiKSkpOworICBFWFBFQ1RfQ0FMTChsaXN0ZW5lcl8sIEludmFsaWRWYWx1ZShfLCBTdHJpbmdQaWVjZSgiVFlQRV9TRklYRUQ2NCIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdQaWVjZSgiXCJOYU5cIiIpKSkKKyAgICAgIC5XaXRoKEFyZ3M8MD4oSGFzT2JqZWN0TG9jYXRpb24oInNmNjQiKSkpOworICBFWFBFQ1RfQ0FMTChsaXN0ZW5lcl8sCisgICAgICAgICAgICAgIEludmFsaWRWYWx1ZShfLCBTdHJpbmdQaWVjZSgiVFlQRV9CT09MIiksIFN0cmluZ1BpZWNlKCJcIk5hTlwiIikpKQorICAgICAgLldpdGgoQXJnczwwPihIYXNPYmplY3RMb2NhdGlvbigiYm9vbCIpKSk7CisKKyAgb3dfLT5TdGFydE9iamVjdCgiIikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJkb3VibGUiLCAiTmFOIikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJmbG9hdCIsICJOYU4iKQorICAgICAgLT5SZW5kZXJTdHJpbmcoImkzMiIsICJOYU4iKQorICAgICAgLT5SZW5kZXJTdHJpbmcoInUzMiIsICJOYU4iKQorICAgICAgLT5SZW5kZXJTdHJpbmcoInNmNjQiLCAiTmFOIikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJzdHIiLCAiTmFOIikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJib29sIiwgIk5hTiIpCisgICAgICAtPkVuZE9iamVjdCgpOworCisgIENoZWNrT3V0cHV0KGZ1bGwpOworfQorCitURVNUX1AoUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJUZXN0LCBJbXBsaWNpdFByaW1pdGl2ZUxpc3QpIHsKKyAgQm9vayBleHBlY3RlZDsKKyAgQXV0aG9yKiBhdXRob3IgPSBleHBlY3RlZC5tdXRhYmxlX2F1dGhvcigpOworICBhdXRob3ItPnNldF9uYW1lKCJUaGUgQXV0aG9yIik7CisgIGF1dGhvci0+YWRkX3BzZXVkb255bSgiZmlyc3QiKTsKKyAgYXV0aG9yLT5hZGRfcHNldWRvbnltKCJzZWNvbmQiKTsKKworICBvd18tPlN0YXJ0T2JqZWN0KCIiKQorICAgICAgLT5TdGFydE9iamVjdCgiYXV0aG9yIikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJuYW1lIiwgIlRoZSBBdXRob3IiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoInBzZXVkb255bSIsICJmaXJzdCIpCisgICAgICAtPlJlbmRlclN0cmluZygicHNldWRvbnltIiwgInNlY29uZCIpCisgICAgICAtPkVuZE9iamVjdCgpCisgICAgICAtPkVuZE9iamVjdCgpOworICBDaGVja091dHB1dChleHBlY3RlZCk7Cit9CisKK1RFU1RfUChQcm90b1N0cmVhbU9iamVjdFdyaXRlclRlc3QsCisgICAgICAgTGFzdFdyaXRlV2luc09uTm9uUmVwZWF0ZWRQcmltaXRpdmVGaWVsZFdpdGhEdXBsaWNhdGVzKSB7CisgIEJvb2sgZXhwZWN0ZWQ7CisgIEF1dGhvciogYXV0aG9yID0gZXhwZWN0ZWQubXV0YWJsZV9hdXRob3IoKTsKKyAgYXV0aG9yLT5zZXRfbmFtZSgic2Vjb25kIik7CisKKyAgb3dfLT5TdGFydE9iamVjdCgiIikKKyAgICAgIC0+U3RhcnRPYmplY3QoImF1dGhvciIpCisgICAgICAtPlJlbmRlclN0cmluZygibmFtZSIsICJmaXJzdCIpCisgICAgICAtPlJlbmRlclN0cmluZygibmFtZSIsICJzZWNvbmQiKQorICAgICAgLT5FbmRPYmplY3QoKQorICAgICAgLT5FbmRPYmplY3QoKTsKKyAgQ2hlY2tPdXRwdXQoZXhwZWN0ZWQpOworfQorCitURVNUX1AoUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJUZXN0LCBFeHBsaWNpdFByaW1pdGl2ZUxpc3QpIHsKKyAgQm9vayBleHBlY3RlZDsKKyAgQXV0aG9yKiBhdXRob3IgPSBleHBlY3RlZC5tdXRhYmxlX2F1dGhvcigpOworICBhdXRob3ItPnNldF9uYW1lKCJUaGUgQXV0aG9yIik7CisgIGF1dGhvci0+YWRkX3BzZXVkb255bSgiZmlyc3QiKTsKKyAgYXV0aG9yLT5hZGRfcHNldWRvbnltKCJzZWNvbmQiKTsKKworICBvd18tPlN0YXJ0T2JqZWN0KCIiKQorICAgICAgLT5TdGFydE9iamVjdCgiYXV0aG9yIikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJuYW1lIiwgIlRoZSBBdXRob3IiKQorICAgICAgLT5TdGFydExpc3QoInBzZXVkb255bSIpCisgICAgICAtPlJlbmRlclN0cmluZygiIiwgImZpcnN0IikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCIiLCAic2Vjb25kIikKKyAgICAgIC0+RW5kTGlzdCgpCisgICAgICAtPkVuZE9iamVjdCgpCisgICAgICAtPkVuZE9iamVjdCgpOworICBDaGVja091dHB1dChleHBlY3RlZCk7Cit9CisKK1RFU1RfUChQcm90b1N0cmVhbU9iamVjdFdyaXRlclRlc3QsIE5vblJlcGVhdGVkRXhwbGljaXRQcmltaXRpdmVMaXN0KSB7CisgIEJvb2sgZXhwZWN0ZWQ7CisgIGV4cGVjdGVkLnNldF9hbGxvY2F0ZWRfYXV0aG9yKG5ldyBBdXRob3IoKSk7CisKKyAgRVhQRUNUX0NBTEwoCisgICAgICBsaXN0ZW5lcl8sCisgICAgICBJbnZhbGlkTmFtZSgKKyAgICAgICAgICBfLCBTdHJpbmdQaWVjZSgibmFtZSIpLAorICAgICAgICAgIFN0cmluZ1BpZWNlKCJQcm90byBmaWVsZCBpcyBub3QgcmVwZWF0aW5nLCBjYW5ub3Qgc3RhcnQgbGlzdC4iKSkpCisgICAgICAuV2l0aChBcmdzPDA+KEhhc09iamVjdExvY2F0aW9uKCJhdXRob3IiKSkpOworICBvd18tPlN0YXJ0T2JqZWN0KCIiKQorICAgICAgLT5TdGFydE9iamVjdCgiYXV0aG9yIikKKyAgICAgIC0+U3RhcnRMaXN0KCJuYW1lIikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCIiLCAiZmlyc3QiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoIiIsICJzZWNvbmQiKQorICAgICAgLT5FbmRMaXN0KCkKKyAgICAgIC0+RW5kT2JqZWN0KCkKKyAgICAgIC0+RW5kT2JqZWN0KCk7CisgIENoZWNrT3V0cHV0KGV4cGVjdGVkKTsKK30KKworVEVTVF9QKFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyVGVzdCwgSW1wbGljaXRNZXNzYWdlTGlzdCkgeworICBCb29rIGV4cGVjdGVkOworICBBdXRob3IqIG91dGVyID0gZXhwZWN0ZWQubXV0YWJsZV9hdXRob3IoKTsKKyAgb3V0ZXItPnNldF9uYW1lKCJvdXRlciIpOworICBvdXRlci0+c2V0X2FsaXZlKHRydWUpOworICBBdXRob3IqIGZpcnN0ID0gb3V0ZXItPmFkZF9mcmllbmRfKCk7CisgIGZpcnN0LT5zZXRfbmFtZSgiZmlyc3QiKTsKKyAgQXV0aG9yKiBzZWNvbmQgPSBvdXRlci0+YWRkX2ZyaWVuZF8oKTsKKyAgc2Vjb25kLT5zZXRfbmFtZSgic2Vjb25kIik7CisKKyAgb3dfLT5TdGFydE9iamVjdCgiIikKKyAgICAgIC0+U3RhcnRPYmplY3QoImF1dGhvciIpCisgICAgICAtPlJlbmRlclN0cmluZygibmFtZSIsICJvdXRlciIpCisgICAgICAtPlJlbmRlckJvb2woImFsaXZlIiwgdHJ1ZSkKKyAgICAgIC0+U3RhcnRPYmplY3QoImZyaWVuZCIpCisgICAgICAtPlJlbmRlclN0cmluZygibmFtZSIsICJmaXJzdCIpCisgICAgICAtPkVuZE9iamVjdCgpCisgICAgICAtPlN0YXJ0T2JqZWN0KCJmcmllbmQiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoIm5hbWUiLCAic2Vjb25kIikKKyAgICAgIC0+RW5kT2JqZWN0KCkKKyAgICAgIC0+RW5kT2JqZWN0KCkKKyAgICAgIC0+RW5kT2JqZWN0KCk7CisgIENoZWNrT3V0cHV0KGV4cGVjdGVkKTsKK30KKworVEVTVF9QKFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyVGVzdCwKKyAgICAgICBMYXN0V3JpdGVXaW5zT25Ob25SZXBlYXRlZE1lc3NhZ2VGaWVsZFdpdGhEdXBsaWNhdGVzKSB7CisgIEJvb2sgZXhwZWN0ZWQ7CisgIEF1dGhvciogYXV0aG9yID0gZXhwZWN0ZWQubXV0YWJsZV9hdXRob3IoKTsKKyAgYXV0aG9yLT5zZXRfbmFtZSgiVGhlIEF1dGhvciIpOworICBQdWJsaXNoZXIqIHB1Ymxpc2hlciA9IGV4cGVjdGVkLm11dGFibGVfcHVibGlzaGVyKCk7CisgIHB1Ymxpc2hlci0+c2V0X25hbWUoInNlY29uZCIpOworCisgIG93Xy0+U3RhcnRPYmplY3QoIiIpCisgICAgICAtPlN0YXJ0T2JqZWN0KCJhdXRob3IiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoIm5hbWUiLCAiVGhlIEF1dGhvciIpCisgICAgICAtPkVuZE9iamVjdCgpCisgICAgICAtPlN0YXJ0T2JqZWN0KCJwdWJsaXNoZXIiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoIm5hbWUiLCAiZmlyc3QiKQorICAgICAgLT5FbmRPYmplY3QoKQorICAgICAgLT5TdGFydE9iamVjdCgicHVibGlzaGVyIikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJuYW1lIiwgInNlY29uZCIpCisgICAgICAtPkVuZE9iamVjdCgpCisgICAgICAtPkVuZE9iamVjdCgpOworICBDaGVja091dHB1dChleHBlY3RlZCk7Cit9CisKK1RFU1RfUChQcm90b1N0cmVhbU9iamVjdFdyaXRlclRlc3QsIEV4cGxpY2l0TWVzc2FnZUxpc3QpIHsKKyAgQm9vayBleHBlY3RlZDsKKyAgQXV0aG9yKiBvdXRlciA9IGV4cGVjdGVkLm11dGFibGVfYXV0aG9yKCk7CisgIG91dGVyLT5zZXRfbmFtZSgib3V0ZXIiKTsKKyAgb3V0ZXItPnNldF9hbGl2ZSh0cnVlKTsKKyAgQXV0aG9yKiBmaXJzdCA9IG91dGVyLT5hZGRfZnJpZW5kXygpOworICBmaXJzdC0+c2V0X25hbWUoImZpcnN0Iik7CisgIEF1dGhvciogc2Vjb25kID0gb3V0ZXItPmFkZF9mcmllbmRfKCk7CisgIHNlY29uZC0+c2V0X25hbWUoInNlY29uZCIpOworCisgIG93Xy0+U3RhcnRPYmplY3QoIiIpCisgICAgICAtPlN0YXJ0T2JqZWN0KCJhdXRob3IiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoIm5hbWUiLCAib3V0ZXIiKQorICAgICAgLT5SZW5kZXJCb29sKCJhbGl2ZSIsIHRydWUpCisgICAgICAtPlN0YXJ0TGlzdCgiZnJpZW5kIikKKyAgICAgIC0+U3RhcnRPYmplY3QoIiIpCisgICAgICAtPlJlbmRlclN0cmluZygibmFtZSIsICJmaXJzdCIpCisgICAgICAtPkVuZE9iamVjdCgpCisgICAgICAtPlN0YXJ0T2JqZWN0KCIiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoIm5hbWUiLCAic2Vjb25kIikKKyAgICAgIC0+RW5kT2JqZWN0KCkKKyAgICAgIC0+RW5kTGlzdCgpCisgICAgICAtPkVuZE9iamVjdCgpCisgICAgICAtPkVuZE9iamVjdCgpOworICBDaGVja091dHB1dChleHBlY3RlZCk7Cit9CisKK1RFU1RfUChQcm90b1N0cmVhbU9iamVjdFdyaXRlclRlc3QsIE5vblJlcGVhdGVkRXhwbGljaXRNZXNzYWdlTGlzdCkgeworICBCb29rIGV4cGVjdGVkOworICBBdXRob3IqIGF1dGhvciA9IGV4cGVjdGVkLm11dGFibGVfYXV0aG9yKCk7CisgIGF1dGhvci0+c2V0X25hbWUoIlRoZSBBdXRob3IiKTsKKworICBFWFBFQ1RfQ0FMTCgKKyAgICAgIGxpc3RlbmVyXywKKyAgICAgIEludmFsaWROYW1lKAorICAgICAgICAgIF8sIFN0cmluZ1BpZWNlKCJwdWJsaXNoZXIiKSwKKyAgICAgICAgICBTdHJpbmdQaWVjZSgiUHJvdG8gZmllbGQgaXMgbm90IHJlcGVhdGluZywgY2Fubm90IHN0YXJ0IGxpc3QuIikpKQorICAgICAgLldpdGgoQXJnczwwPihIYXNPYmplY3RMb2NhdGlvbigiIikpKTsKKyAgb3dfLT5TdGFydE9iamVjdCgiIikKKyAgICAgIC0+U3RhcnRPYmplY3QoImF1dGhvciIpCisgICAgICAtPlJlbmRlclN0cmluZygibmFtZSIsICJUaGUgQXV0aG9yIikKKyAgICAgIC0+RW5kT2JqZWN0KCkKKyAgICAgIC0+U3RhcnRMaXN0KCJwdWJsaXNoZXIiKQorICAgICAgLT5TdGFydE9iamVjdCgiIikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJuYW1lIiwgImZpcnN0IikKKyAgICAgIC0+RW5kT2JqZWN0KCkKKyAgICAgIC0+U3RhcnRPYmplY3QoIiIpCisgICAgICAtPlJlbmRlclN0cmluZygibmFtZSIsICJzZWNvbmQiKQorICAgICAgLT5FbmRPYmplY3QoKQorICAgICAgLT5FbmRMaXN0KCkKKyAgICAgIC0+RW5kT2JqZWN0KCk7CisgIENoZWNrT3V0cHV0KGV4cGVjdGVkKTsKK30KKworVEVTVF9QKFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyVGVzdCwgVW5rbm93bkZpZWxkQXRSb290KSB7CisgIEJvb2sgZW1wdHk7CisKKyAgRVhQRUNUX0NBTEwobGlzdGVuZXJfLCBJbnZhbGlkTmFtZShfLCBTdHJpbmdQaWVjZSgidW5rbm93biIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1BpZWNlKCJDYW5ub3QgZmluZCBmaWVsZC4iKSkpCisgICAgICAuV2l0aChBcmdzPDA+KEhhc09iamVjdExvY2F0aW9uKCIiKSkpOworICBvd18tPlN0YXJ0T2JqZWN0KCIiKS0+UmVuZGVyU3RyaW5nKCJ1bmtub3duIiwgIk5vcGUhIiktPkVuZE9iamVjdCgpOworICBDaGVja091dHB1dChlbXB0eSwgMCk7Cit9CisKK1RFU1RfUChQcm90b1N0cmVhbU9iamVjdFdyaXRlclRlc3QsIFVua25vd25GaWVsZEF0QXV0aG9yRnJpZW5kKSB7CisgIEJvb2sgZXhwZWN0ZWQ7CisgIEF1dGhvciogcGF1bCA9IGV4cGVjdGVkLm11dGFibGVfYXV0aG9yKCk7CisgIHBhdWwtPnNldF9uYW1lKCJQYXVsIik7CisgIEF1dGhvciogbWFyayA9IHBhdWwtPmFkZF9mcmllbmRfKCk7CisgIG1hcmstPnNldF9uYW1lKCJNYXJrIik7CisgIEF1dGhvciogam9obiA9IHBhdWwtPmFkZF9mcmllbmRfKCk7CisgIGpvaG4tPnNldF9uYW1lKCJKb2huIik7CisgIEF1dGhvciogbHVrZSA9IHBhdWwtPmFkZF9mcmllbmRfKCk7CisgIGx1a2UtPnNldF9uYW1lKCJMdWtlIik7CisKKyAgRVhQRUNUX0NBTEwobGlzdGVuZXJfLCBJbnZhbGlkTmFtZShfLCBTdHJpbmdQaWVjZSgiYWRkcmVzcyIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1BpZWNlKCJDYW5ub3QgZmluZCBmaWVsZC4iKSkpCisgICAgICAuV2l0aChBcmdzPDA+KEhhc09iamVjdExvY2F0aW9uKCJhdXRob3IuZnJpZW5kWzFdIikpKTsKKyAgb3dfLT5TdGFydE9iamVjdCgiIikKKyAgICAgIC0+U3RhcnRPYmplY3QoImF1dGhvciIpCisgICAgICAtPlJlbmRlclN0cmluZygibmFtZSIsICJQYXVsIikKKyAgICAgIC0+U3RhcnRMaXN0KCJmcmllbmQiKQorICAgICAgLT5TdGFydE9iamVjdCgiIikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJuYW1lIiwgIk1hcmsiKQorICAgICAgLT5FbmRPYmplY3QoKQorICAgICAgLT5TdGFydE9iamVjdCgiIikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJuYW1lIiwgIkpvaG4iKQorICAgICAgLT5SZW5kZXJTdHJpbmcoImFkZHJlc3MiLCAiUGF0bW9zIikKKyAgICAgIC0+RW5kT2JqZWN0KCkKKyAgICAgIC0+U3RhcnRPYmplY3QoIiIpCisgICAgICAtPlJlbmRlclN0cmluZygibmFtZSIsICJMdWtlIikKKyAgICAgIC0+RW5kT2JqZWN0KCkKKyAgICAgIC0+RW5kTGlzdCgpCisgICAgICAtPkVuZE9iamVjdCgpCisgICAgICAtPkVuZE9iamVjdCgpOworICBDaGVja091dHB1dChleHBlY3RlZCk7Cit9CisKK1RFU1RfUChQcm90b1N0cmVhbU9iamVjdFdyaXRlclRlc3QsIFVua25vd25PYmplY3RBdFJvb3QpIHsKKyAgQm9vayBlbXB0eTsKKworICBFWFBFQ1RfQ0FMTChsaXN0ZW5lcl8sIEludmFsaWROYW1lKF8sIFN0cmluZ1BpZWNlKCJ1bmtub3duIiksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UoIkNhbm5vdCBmaW5kIGZpZWxkLiIpKSkKKyAgICAgIC5XaXRoKEFyZ3M8MD4oSGFzT2JqZWN0TG9jYXRpb24oIiIpKSk7CisgIG93Xy0+U3RhcnRPYmplY3QoIiIpLT5TdGFydE9iamVjdCgidW5rbm93biIpLT5FbmRPYmplY3QoKS0+RW5kT2JqZWN0KCk7CisgIENoZWNrT3V0cHV0KGVtcHR5LCAwKTsKK30KKworVEVTVF9QKFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyVGVzdCwgVW5rbm93bk9iamVjdEF0QXV0aG9yKSB7CisgIEJvb2sgZXhwZWN0ZWQ7CisgIEF1dGhvciogYXV0aG9yID0gZXhwZWN0ZWQubXV0YWJsZV9hdXRob3IoKTsKKyAgYXV0aG9yLT5zZXRfbmFtZSgiV2lsbGlhbSIpOworICBhdXRob3ItPmFkZF9wc2V1ZG9ueW0oIkJpbGwiKTsKKworICBFWFBFQ1RfQ0FMTChsaXN0ZW5lcl8sIEludmFsaWROYW1lKF8sIFN0cmluZ1BpZWNlKCJ3aWZlIiksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UoIkNhbm5vdCBmaW5kIGZpZWxkLiIpKSkKKyAgICAgIC5XaXRoKEFyZ3M8MD4oSGFzT2JqZWN0TG9jYXRpb24oImF1dGhvciIpKSk7CisgIG93Xy0+U3RhcnRPYmplY3QoIiIpCisgICAgICAtPlN0YXJ0T2JqZWN0KCJhdXRob3IiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoIm5hbWUiLCAiV2lsbGlhbSIpCisgICAgICAtPlN0YXJ0T2JqZWN0KCJ3aWZlIikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJuYW1lIiwgIkhpbGFyeSIpCisgICAgICAtPkVuZE9iamVjdCgpCisgICAgICAtPlJlbmRlclN0cmluZygicHNldWRvbnltIiwgIkJpbGwiKQorICAgICAgLT5FbmRPYmplY3QoKQorICAgICAgLT5FbmRPYmplY3QoKTsKKyAgQ2hlY2tPdXRwdXQoZXhwZWN0ZWQpOworfQorCitURVNUX1AoUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJUZXN0LCBVbmtub3duTGlzdEF0Um9vdCkgeworICBCb29rIGVtcHR5OworCisgIEVYUEVDVF9DQUxMKGxpc3RlbmVyXywgSW52YWxpZE5hbWUoXywgU3RyaW5nUGllY2UoInVua25vd24iKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdQaWVjZSgiQ2Fubm90IGZpbmQgZmllbGQuIikpKQorICAgICAgLldpdGgoQXJnczwwPihIYXNPYmplY3RMb2NhdGlvbigiIikpKTsKKyAgb3dfLT5TdGFydE9iamVjdCgiIiktPlN0YXJ0TGlzdCgidW5rbm93biIpLT5FbmRMaXN0KCktPkVuZE9iamVjdCgpOworICBDaGVja091dHB1dChlbXB0eSwgMCk7Cit9CisKK1RFU1RfUChQcm90b1N0cmVhbU9iamVjdFdyaXRlclRlc3QsIFVua25vd25MaXN0QXRQdWJsaXNoZXIpIHsKKyAgQm9vayBleHBlY3RlZDsKKyAgZXhwZWN0ZWQuc2V0X3RpdGxlKCJCcmFpbndhc2hpbmciKTsKKyAgUHVibGlzaGVyKiBwdWJsaXNoZXIgPSBleHBlY3RlZC5tdXRhYmxlX3B1Ymxpc2hlcigpOworICBwdWJsaXNoZXItPnNldF9uYW1lKCJwcm9wYWdhbmRhIik7CisKKyAgRVhQRUNUX0NBTEwobGlzdGVuZXJfLCBJbnZhbGlkTmFtZShfLCBTdHJpbmdQaWVjZSgiYWxsaWFuY2UiKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdQaWVjZSgiQ2Fubm90IGZpbmQgZmllbGQuIikpKQorICAgICAgLldpdGgoQXJnczwwPihIYXNPYmplY3RMb2NhdGlvbigicHVibGlzaGVyIikpKTsKKyAgb3dfLT5TdGFydE9iamVjdCgiIikKKyAgICAgIC0+U3RhcnRPYmplY3QoInB1Ymxpc2hlciIpCisgICAgICAtPlJlbmRlclN0cmluZygibmFtZSIsICJwcm9wYWdhbmRhIikKKyAgICAgIC0+U3RhcnRMaXN0KCJhbGxpYW5jZSIpCisgICAgICAtPkVuZExpc3QoKQorICAgICAgLT5FbmRPYmplY3QoKQorICAgICAgLT5SZW5kZXJTdHJpbmcoInRpdGxlIiwgIkJyYWlud2FzaGluZyIpCisgICAgICAtPkVuZE9iamVjdCgpOworICBDaGVja091dHB1dChleHBlY3RlZCk7Cit9CisKK1RFU1RfUChQcm90b1N0cmVhbU9iamVjdFdyaXRlclRlc3QsIE1pc3NpbmdSZXF1aXJlZEZpZWxkKSB7CisgIEJvb2sgZXhwZWN0ZWQ7CisgIGV4cGVjdGVkLnNldF90aXRsZSgiTXkgVGl0bGUiKTsKKyAgZXhwZWN0ZWQuc2V0X2FsbG9jYXRlZF9wdWJsaXNoZXIobmV3IFB1Ymxpc2hlcigpKTsKKworICBFWFBFQ1RfQ0FMTChsaXN0ZW5lcl8sIE1pc3NpbmdGaWVsZChfLCBTdHJpbmdQaWVjZSgibmFtZSIpKSkKKyAgICAgIC5XaXRoKEFyZ3M8MD4oSGFzT2JqZWN0TG9jYXRpb24oInB1Ymxpc2hlciIpKSk7CisgIG93Xy0+U3RhcnRPYmplY3QoIiIpCisgICAgICAtPlN0YXJ0T2JqZWN0KCJwdWJsaXNoZXIiKQorICAgICAgLT5FbmRPYmplY3QoKQorICAgICAgLT5SZW5kZXJTdHJpbmcoInRpdGxlIiwgIk15IFRpdGxlIikKKyAgICAgIC0+RW5kT2JqZWN0KCk7CisgIENoZWNrT3V0cHV0KGV4cGVjdGVkKTsKK30KKworVEVTVF9QKFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyVGVzdCwgSW52YWxpZEZpZWxkVmFsdWVBdFJvb3QpIHsKKyAgQm9vayBlbXB0eTsKKworICBFWFBFQ1RfQ0FMTChsaXN0ZW5lcl8sIEludmFsaWRWYWx1ZShfLCBTdHJpbmdQaWVjZSgiVFlQRV9VSU5UMzIiKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UoIlwiZ2FyYmFnZVwiIikpKQorICAgICAgLldpdGgoQXJnczwwPihIYXNPYmplY3RMb2NhdGlvbigibGVuZ3RoIikpKTsKKyAgb3dfLT5TdGFydE9iamVjdCgiIiktPlJlbmRlclN0cmluZygibGVuZ3RoIiwgImdhcmJhZ2UiKS0+RW5kT2JqZWN0KCk7CisgIENoZWNrT3V0cHV0KGVtcHR5LCAwKTsKK30KKworVEVTVF9QKFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyVGVzdCwgTXVsdGlwbGVJbnZhbGlkRmllbGRWYWx1ZXMpIHsKKyAgQm9vayBleHBlY3RlZDsKKyAgZXhwZWN0ZWQuc2V0X3RpdGxlKCJNeSBUaXRsZSIpOworCisgIEVYUEVDVF9DQUxMKGxpc3RlbmVyXywgSW52YWxpZFZhbHVlKF8sIFN0cmluZ1BpZWNlKCJUWVBFX1VJTlQzMiIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdQaWVjZSgiXCItNDAwXCIiKSkpCisgICAgICAuV2l0aChBcmdzPDA+KEhhc09iamVjdExvY2F0aW9uKCJsZW5ndGgiKSkpOworICBFWFBFQ1RfQ0FMTChsaXN0ZW5lcl8sIEludmFsaWRWYWx1ZShfLCBTdHJpbmdQaWVjZSgiVFlQRV9JTlQ2NCIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdQaWVjZSgiXCIzLjE0XCIiKSkpCisgICAgICAuV2l0aChBcmdzPDA+KEhhc09iamVjdExvY2F0aW9uKCJwdWJsaXNoZWQiKSkpOworICBvd18tPlN0YXJ0T2JqZWN0KCIiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoImxlbmd0aCIsICItNDAwIikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJwdWJsaXNoZWQiLCAiMy4xNCIpCisgICAgICAtPlJlbmRlclN0cmluZygidGl0bGUiLCAiTXkgVGl0bGUiKQorICAgICAgLT5FbmRPYmplY3QoKTsKKyAgQ2hlY2tPdXRwdXQoZXhwZWN0ZWQpOworfQorCitURVNUX1AoUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJUZXN0LCBVbm5hbWVkRmllbGRBdFJvb3QpIHsKKyAgQm9vayBlbXB0eTsKKworICBFWFBFQ1RfQ0FMTChsaXN0ZW5lcl8sCisgICAgICAgICAgICAgIEludmFsaWROYW1lKF8sIFN0cmluZ1BpZWNlKCIiKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UoIlByb3RvIGZpZWxkcyBtdXN0IGhhdmUgYSBuYW1lLiIpKSkKKyAgICAgIC5XaXRoKEFyZ3M8MD4oSGFzT2JqZWN0TG9jYXRpb24oIiIpKSk7CisgIG93Xy0+U3RhcnRPYmplY3QoIiIpLT5SZW5kZXJGbG9hdCgiIiwgMy4xNCktPkVuZE9iamVjdCgpOworICBDaGVja091dHB1dChlbXB0eSwgMCk7Cit9CisKK1RFU1RfUChQcm90b1N0cmVhbU9iamVjdFdyaXRlclRlc3QsIFVubmFtZWRGaWVsZEF0QXV0aG9yKSB7CisgIEJvb2sgZXhwZWN0ZWQ7CisgIGV4cGVjdGVkLnNldF90aXRsZSgibm9uYW1lIik7CisgIGV4cGVjdGVkLnNldF9hbGxvY2F0ZWRfYXV0aG9yKG5ldyBBdXRob3IoKSk7CisKKyAgRVhQRUNUX0NBTEwobGlzdGVuZXJfLAorICAgICAgICAgICAgICBJbnZhbGlkTmFtZShfLCBTdHJpbmdQaWVjZSgiIiksCisgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1BpZWNlKCJQcm90byBmaWVsZHMgbXVzdCBoYXZlIGEgbmFtZS4iKSkpCisgICAgICAuV2l0aChBcmdzPDA+KEhhc09iamVjdExvY2F0aW9uKCJhdXRob3IiKSkpOworICBvd18tPlN0YXJ0T2JqZWN0KCIiKQorICAgICAgLT5TdGFydE9iamVjdCgiYXV0aG9yIikKKyAgICAgIC0+UmVuZGVySW50MzIoIiIsIDEyMykKKyAgICAgIC0+RW5kT2JqZWN0KCkKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJ0aXRsZSIsICJub25hbWUiKQorICAgICAgLT5FbmRPYmplY3QoKTsKKyAgQ2hlY2tPdXRwdXQoZXhwZWN0ZWQpOworfQorCitURVNUX1AoUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJUZXN0LCBVbm5hbWVkTGlzdEF0Um9vdCkgeworICBCb29rIGV4cGVjdGVkOworICBleHBlY3RlZC5zZXRfdGl0bGUoIm5vbmFtZSIpOworCisgIEVYUEVDVF9DQUxMKGxpc3RlbmVyXywKKyAgICAgICAgICAgICAgSW52YWxpZE5hbWUoXywgU3RyaW5nUGllY2UoIiIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdQaWVjZSgiUHJvdG8gZmllbGRzIG11c3QgaGF2ZSBhIG5hbWUuIikpKQorICAgICAgLldpdGgoQXJnczwwPihIYXNPYmplY3RMb2NhdGlvbigiIikpKTsKKyAgb3dfLT5TdGFydE9iamVjdCgiIikKKyAgICAgIC0+U3RhcnRMaXN0KCIiKQorICAgICAgLT5FbmRMaXN0KCkKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJ0aXRsZSIsICJub25hbWUiKQorICAgICAgLT5FbmRPYmplY3QoKTsKKyAgQ2hlY2tPdXRwdXQoZXhwZWN0ZWQpOworfQorCitURVNUX1AoUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJUZXN0LCBSb290TmFtZWRPYmplY3QpIHsKKyAgQm9vayBleHBlY3RlZDsKKyAgZXhwZWN0ZWQuc2V0X3RpdGxlKCJBbm5pZSIpOworCisgIEVYUEVDVF9DQUxMKGxpc3RlbmVyXywKKyAgICAgICAgICAgICAgSW52YWxpZE5hbWUoXywgU3RyaW5nUGllY2UoIm9vcHMiKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UoIlJvb3QgZWxlbWVudCBzaG91bGQgbm90IGJlIG5hbWVkLiIpKSkKKyAgICAgIC5XaXRoKEFyZ3M8MD4oSGFzT2JqZWN0TG9jYXRpb24oIiIpKSk7CisgIG93Xy0+U3RhcnRPYmplY3QoIm9vcHMiKS0+UmVuZGVyU3RyaW5nKCJ0aXRsZSIsICJBbm5pZSIpLT5FbmRPYmplY3QoKTsKKyAgQ2hlY2tPdXRwdXQoZXhwZWN0ZWQsIDcpOworfQorCitURVNUX1AoUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJUZXN0LCBSb290TmFtZWRMaXN0KSB7CisgIEJvb2sgZW1wdHk7CisKKyAgRVhQRUNUX0NBTEwobGlzdGVuZXJfLAorICAgICAgICAgICAgICBJbnZhbGlkTmFtZShfLCBTdHJpbmdQaWVjZSgib29wcyIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdQaWVjZSgiUm9vdCBlbGVtZW50IHNob3VsZCBub3QgYmUgbmFtZWQuIikpKQorICAgICAgLldpdGgoQXJnczwwPihIYXNPYmplY3RMb2NhdGlvbigiIikpKTsKKyAgb3dfLT5TdGFydExpc3QoIm9vcHMiKS0+UmVuZGVyU3RyaW5nKCIiLCAiaXRlbSIpLT5FbmRMaXN0KCk7CisgIENoZWNrT3V0cHV0KGVtcHR5LCAwKTsKK30KKworVEVTVF9QKFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyVGVzdCwgUm9vdFVubmFtZWRGaWVsZCkgeworICBCb29rIGVtcHR5OworCisgIEVYUEVDVF9DQUxMKGxpc3RlbmVyXywKKyAgICAgICAgICAgICAgSW52YWxpZE5hbWUoXywgU3RyaW5nUGllY2UoIiIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdQaWVjZSgiUm9vdCBlbGVtZW50IG11c3QgYmUgYSBtZXNzYWdlLiIpKSkKKyAgICAgIC5XaXRoKEFyZ3M8MD4oSGFzT2JqZWN0TG9jYXRpb24oIiIpKSk7CisgIG93Xy0+UmVuZGVyQm9vbCgiIiwgdHJ1ZSk7CisgIENoZWNrT3V0cHV0KGVtcHR5LCAwKTsKK30KKworVEVTVF9QKFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyVGVzdCwgUm9vdE5hbWVkRmllbGQpIHsKKyAgQm9vayBlbXB0eTsKKworICBFWFBFQ1RfQ0FMTChsaXN0ZW5lcl8sCisgICAgICAgICAgICAgIEludmFsaWROYW1lKF8sIFN0cmluZ1BpZWNlKCJvb3BzIiksCisgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1BpZWNlKCJSb290IGVsZW1lbnQgbXVzdCBiZSBhIG1lc3NhZ2UuIikpKQorICAgICAgLldpdGgoQXJnczwwPihIYXNPYmplY3RMb2NhdGlvbigiIikpKTsKKyAgb3dfLT5SZW5kZXJCb29sKCJvb3BzIiwgdHJ1ZSk7CisgIENoZWNrT3V0cHV0KGVtcHR5LCAwKTsKK30KKworVEVTVF9QKFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyVGVzdCwgTnVsbFZhbHVlKSB7CisgIEJvb2sgZW1wdHk7CisKKyAgb3dfLT5SZW5kZXJOdWxsKCIiKTsKKyAgQ2hlY2tPdXRwdXQoZW1wdHksIDApOworfQorCitURVNUX1AoUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJUZXN0LCBOdWxsVmFsdWVGb3JNZXNzYWdlRmllbGQpIHsKKyAgQm9vayBlbXB0eTsKKworICBvd18tPlJlbmRlck51bGwoImF1dGhvciIpOworICBDaGVja091dHB1dChlbXB0eSwgMCk7Cit9CisKK1RFU1RfUChQcm90b1N0cmVhbU9iamVjdFdyaXRlclRlc3QsIE51bGxWYWx1ZUZvclByaW1pdGl2ZUZpZWxkKSB7CisgIEJvb2sgZW1wdHk7CisKKyAgb3dfLT5SZW5kZXJOdWxsKCJsZW5ndGgiKTsKKyAgQ2hlY2tPdXRwdXQoZW1wdHksIDApOworfQorCitjbGFzcyBQcm90b1N0cmVhbU9iamVjdFdyaXRlclRpbWVzdGFtcER1cmF0aW9uVGVzdAorICAgIDogcHVibGljIEJhc2VQcm90b1N0cmVhbU9iamVjdFdyaXRlclRlc3QgeworIHByb3RlY3RlZDoKKyAgUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJUaW1lc3RhbXBEdXJhdGlvblRlc3QoKSB7CisgICAgdmVjdG9yPGNvbnN0IERlc2NyaXB0b3IqPiBkZXNjcmlwdG9yczsKKyAgICBkZXNjcmlwdG9ycy5wdXNoX2JhY2soVGltZXN0YW1wRHVyYXRpb246OmRlc2NyaXB0b3IoKSk7CisgICAgZGVzY3JpcHRvcnMucHVzaF9iYWNrKGdvb2dsZTo6cHJvdG9idWY6OlRpbWVzdGFtcDo6ZGVzY3JpcHRvcigpKTsKKyAgICBkZXNjcmlwdG9ycy5wdXNoX2JhY2soZ29vZ2xlOjpwcm90b2J1Zjo6RHVyYXRpb246OmRlc2NyaXB0b3IoKSk7CisgICAgUmVzZXRUeXBlSW5mbyhkZXNjcmlwdG9ycyk7CisgIH0KK307CisKK0lOU1RBTlRJQVRFX1RFU1RfQ0FTRV9QKERpZmZlcmVudFR5cGVJbmZvU291cmNlVGVzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgIFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyVGltZXN0YW1wRHVyYXRpb25UZXN0LAorICAgICAgICAgICAgICAgICAgICAgICAgOjp0ZXN0aW5nOjpWYWx1ZXMoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVzdGluZzo6VVNFX1RZUEVfUkVTT0xWRVIpKTsKKworVEVTVF9QKFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyVGltZXN0YW1wRHVyYXRpb25UZXN0LCBQYXJzZVRpbWVzdGFtcCkgeworICBUaW1lc3RhbXBEdXJhdGlvbiB0aW1lc3RhbXA7CisgIGdvb2dsZTo6cHJvdG9idWY6OlRpbWVzdGFtcCogdHMgPSB0aW1lc3RhbXAubXV0YWJsZV90cygpOworICB0cy0+c2V0X3NlY29uZHMoMTQ0ODI0OTg1NSk7CisgIHRzLT5zZXRfbmFub3MoMzMxNTUwMDApOworCisgIG93Xy0+U3RhcnRPYmplY3QoIiIpCisgICAgICAtPlJlbmRlclN0cmluZygidHMiLCAiMjAxNS0xMS0yM1QwMzozNzozNS4wMzMxNTVaIikKKyAgICAgIC0+RW5kT2JqZWN0KCk7CisgIENoZWNrT3V0cHV0KHRpbWVzdGFtcCk7Cit9CisKK1RFU1RfUChQcm90b1N0cmVhbU9iamVjdFdyaXRlclRpbWVzdGFtcER1cmF0aW9uVGVzdCwgSW52YWxpZFRpbWVzdGFtcEVycm9yMSkgeworICBUaW1lc3RhbXBEdXJhdGlvbiB0aW1lc3RhbXA7CisKKyAgRVhQRUNUX0NBTEwoCisgICAgICBsaXN0ZW5lcl8sCisgICAgICBJbnZhbGlkVmFsdWUoXywKKyAgICAgICAgICAgICAgICAgICBTdHJpbmdQaWVjZSgidHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIiksCisgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UoIkZpZWxkICd0cycsIEludmFsaWQgdGltZSBmb3JtYXQ6ICIpKSk7CisKKyAgb3dfLT5TdGFydE9iamVjdCgiIiktPlJlbmRlclN0cmluZygidHMiLCAiIiktPkVuZE9iamVjdCgpOworICBDaGVja091dHB1dCh0aW1lc3RhbXApOworfQorCitURVNUX1AoUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJUaW1lc3RhbXBEdXJhdGlvblRlc3QsIEludmFsaWRUaW1lc3RhbXBFcnJvcjIpIHsKKyAgVGltZXN0YW1wRHVyYXRpb24gdGltZXN0YW1wOworCisgIEVYUEVDVF9DQUxMKAorICAgICAgbGlzdGVuZXJfLAorICAgICAgSW52YWxpZFZhbHVlKF8sCisgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UoInR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCIpLAorICAgICAgICAgICAgICAgICAgIFN0cmluZ1BpZWNlKCJGaWVsZCAndHMnLCBJbnZhbGlkIHRpbWUgZm9ybWF0OiBaIikpKTsKKworICBvd18tPlN0YXJ0T2JqZWN0KCIiKS0+UmVuZGVyU3RyaW5nKCJ0cyIsICJaIiktPkVuZE9iamVjdCgpOworICBDaGVja091dHB1dCh0aW1lc3RhbXApOworfQorCitURVNUX1AoUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJUaW1lc3RhbXBEdXJhdGlvblRlc3QsIEludmFsaWRUaW1lc3RhbXBFcnJvcjMpIHsKKyAgVGltZXN0YW1wRHVyYXRpb24gdGltZXN0YW1wOworCisgIEVYUEVDVF9DQUxMKAorICAgICAgbGlzdGVuZXJfLAorICAgICAgSW52YWxpZFZhbHVlKF8sCisgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UoInR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCIpLAorICAgICAgICAgICAgICAgICAgIFN0cmluZ1BpZWNlKCJGaWVsZCAndHMnLCBJbnZhbGlkIHRpbWUgZm9ybWF0OiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjE5NzAtMDEtMDFUMDA6MDA6MDAuQUJaIikpKTsKKworICBvd18tPlN0YXJ0T2JqZWN0KCIiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoInRzIiwgIjE5NzAtMDEtMDFUMDA6MDA6MDAuQUJaIikKKyAgICAgIC0+RW5kT2JqZWN0KCk7CisgIENoZWNrT3V0cHV0KHRpbWVzdGFtcCk7Cit9CisKK1RFU1RfUChQcm90b1N0cmVhbU9iamVjdFdyaXRlclRpbWVzdGFtcER1cmF0aW9uVGVzdCwgSW52YWxpZFRpbWVzdGFtcEVycm9yNCkgeworICBUaW1lc3RhbXBEdXJhdGlvbiB0aW1lc3RhbXA7CisKKyAgRVhQRUNUX0NBTEwoCisgICAgICBsaXN0ZW5lcl8sCisgICAgICBJbnZhbGlkVmFsdWUoXywKKyAgICAgICAgICAgICAgICAgICBTdHJpbmdQaWVjZSgidHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIiksCisgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UoIkZpZWxkICd0cycsIEludmFsaWQgdGltZSBmb3JtYXQ6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLTgwMzItMTAtMThUMDA6MDA6MDAuMDAwWiIpKSk7CisKKyAgb3dfLT5TdGFydE9iamVjdCgiIikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJ0cyIsICItODAzMi0xMC0xOFQwMDowMDowMC4wMDBaIikKKyAgICAgIC0+RW5kT2JqZWN0KCk7CisgIENoZWNrT3V0cHV0KHRpbWVzdGFtcCk7Cit9CisKK1RFU1RfUChQcm90b1N0cmVhbU9iamVjdFdyaXRlclRpbWVzdGFtcER1cmF0aW9uVGVzdCwgSW52YWxpZFRpbWVzdGFtcEVycm9yNSkgeworICBUaW1lc3RhbXBEdXJhdGlvbiB0aW1lc3RhbXA7CisKKyAgRVhQRUNUX0NBTEwoCisgICAgICBsaXN0ZW5lcl8sCisgICAgICBJbnZhbGlkVmFsdWUoXywKKyAgICAgICAgICAgICAgICAgICBTdHJpbmdQaWVjZSgidHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIiksCisgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UoIkZpZWxkICd0cycsIEludmFsaWQgdGltZSBmb3JtYXQ6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMjAxNS0xMS0yM1QwMzozNzozNS4wMzMxNTUgICBaIikpKTsKKworICBvd18tPlN0YXJ0T2JqZWN0KCIiKQorICAgICAgLy8gV2hpdGVzcGFjZSBpbiB0aGUgVGltZXN0YW1wIG5hbm9zIGlzIG5vdCBhbGxvd2VkLgorICAgICAgLT5SZW5kZXJTdHJpbmcoInRzIiwgIjIwMTUtMTEtMjNUMDM6Mzc6MzUuMDMzMTU1ICAgWiIpCisgICAgICAtPkVuZE9iamVjdCgpOworICBDaGVja091dHB1dCh0aW1lc3RhbXApOworfQorCitURVNUX1AoUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJUaW1lc3RhbXBEdXJhdGlvblRlc3QsIEludmFsaWRUaW1lc3RhbXBFcnJvcjYpIHsKKyAgVGltZXN0YW1wRHVyYXRpb24gdGltZXN0YW1wOworCisgIEVYUEVDVF9DQUxMKAorICAgICAgbGlzdGVuZXJfLAorICAgICAgSW52YWxpZFZhbHVlKF8sCisgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UoInR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCIpLAorICAgICAgICAgICAgICAgICAgIFN0cmluZ1BpZWNlKCJGaWVsZCAndHMnLCBJbnZhbGlkIHRpbWUgZm9ybWF0OiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjIwMTUtMTEtMjNUMDM6Mzc6MzUuMDMzMTU1IDEyMzRaIikpKTsKKworICBvd18tPlN0YXJ0T2JqZWN0KCIiKQorICAgICAgLy8gV2hpdGVzcGFjZSBpbiB0aGUgVGltZXN0YW1wIG5hbm9zIGlzIG5vdCBhbGxvd2VkLgorICAgICAgLT5SZW5kZXJTdHJpbmcoInRzIiwgIjIwMTUtMTEtMjNUMDM6Mzc6MzUuMDMzMTU1IDEyMzRaIikKKyAgICAgIC0+RW5kT2JqZWN0KCk7CisgIENoZWNrT3V0cHV0KHRpbWVzdGFtcCk7Cit9CisKK1RFU1RfUChQcm90b1N0cmVhbU9iamVjdFdyaXRlclRpbWVzdGFtcER1cmF0aW9uVGVzdCwgSW52YWxpZFRpbWVzdGFtcEVycm9yNykgeworICBUaW1lc3RhbXBEdXJhdGlvbiB0aW1lc3RhbXA7CisKKyAgRVhQRUNUX0NBTEwoCisgICAgICBsaXN0ZW5lcl8sCisgICAgICBJbnZhbGlkVmFsdWUoXywKKyAgICAgICAgICAgICAgICAgICBTdHJpbmdQaWVjZSgidHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIiksCisgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UoIkZpZWxkICd0cycsIEludmFsaWQgdGltZSBmb3JtYXQ6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMjAxNS0xMS0yM1QwMzozNzozNS4wMzNhYmMxNTVaIikpKTsKKworICBvd18tPlN0YXJ0T2JqZWN0KCIiKQorICAgICAgLy8gTm9uLW51bWVyaWMgY2hhcmFjdGVycyBpbiB0aGUgVGltZXN0YW1wIG5hbm9zIGlzIG5vdCBhbGxvd2VkLgorICAgICAgLT5SZW5kZXJTdHJpbmcoInRzIiwgIjIwMTUtMTEtMjNUMDM6Mzc6MzUuMDMzYWJjMTU1WiIpCisgICAgICAtPkVuZE9iamVjdCgpOworICBDaGVja091dHB1dCh0aW1lc3RhbXApOworfQorCitURVNUX1AoUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJUaW1lc3RhbXBEdXJhdGlvblRlc3QsIFBhcnNlRHVyYXRpb24pIHsKKyAgVGltZXN0YW1wRHVyYXRpb24gZHVyYXRpb247CisgIGdvb2dsZTo6cHJvdG9idWY6OkR1cmF0aW9uKiBkdXIgPSBkdXJhdGlvbi5tdXRhYmxlX2R1cigpOworICBkdXItPnNldF9zZWNvbmRzKDE0NDgyMTY5MzApOworICBkdXItPnNldF9uYW5vcygxMzIyNjIwMDApOworCisgIG93Xy0+U3RhcnRPYmplY3QoIiIpLT5SZW5kZXJTdHJpbmcoImR1ciIsICIxNDQ4MjE2OTMwLjEzMjI2MnMiKS0+RW5kT2JqZWN0KCk7CisgIENoZWNrT3V0cHV0KGR1cmF0aW9uKTsKK30KKworVEVTVF9QKFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyVGltZXN0YW1wRHVyYXRpb25UZXN0LCBJbnZhbGlkRHVyYXRpb25FcnJvcjEpIHsKKyAgVGltZXN0YW1wRHVyYXRpb24gZHVyYXRpb247CisKKyAgRVhQRUNUX0NBTEwoCisgICAgICBsaXN0ZW5lcl8sCisgICAgICBJbnZhbGlkVmFsdWUoCisgICAgICAgICAgXywgU3RyaW5nUGllY2UoInR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uIiksCisgICAgICAgICAgU3RyaW5nUGllY2UoIkZpZWxkICdkdXInLCBJbGxlZ2FsIGR1cmF0aW9uIGZvcm1hdDsgZHVyYXRpb24gbXVzdCAiCisgICAgICAgICAgICAgICAgICAgICAgImVuZCB3aXRoICdzJyIpKSk7CisKKyAgb3dfLT5TdGFydE9iamVjdCgiIiktPlJlbmRlclN0cmluZygiZHVyIiwgIiIpLT5FbmRPYmplY3QoKTsKKyAgQ2hlY2tPdXRwdXQoZHVyYXRpb24pOworfQorCitURVNUX1AoUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJUaW1lc3RhbXBEdXJhdGlvblRlc3QsIEludmFsaWREdXJhdGlvbkVycm9yMikgeworICBUaW1lc3RhbXBEdXJhdGlvbiBkdXJhdGlvbjsKKworICBFWFBFQ1RfQ0FMTCgKKyAgICAgIGxpc3RlbmVyXywKKyAgICAgIEludmFsaWRWYWx1ZSgKKyAgICAgICAgICBfLCBTdHJpbmdQaWVjZSgidHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUucHJvdG9idWYuRHVyYXRpb24iKSwKKyAgICAgICAgICBTdHJpbmdQaWVjZSgiRmllbGQgJ2R1cicsIEludmFsaWQgZHVyYXRpb24gZm9ybWF0LCBmYWlsZWQgdG8gcGFyc2UgIgorICAgICAgICAgICAgICAgICAgICAgICJzZWNvbmRzIikpKTsKKworICBvd18tPlN0YXJ0T2JqZWN0KCIiKS0+UmVuZGVyU3RyaW5nKCJkdXIiLCAicyIpLT5FbmRPYmplY3QoKTsKKyAgQ2hlY2tPdXRwdXQoZHVyYXRpb24pOworfQorCitURVNUX1AoUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJUaW1lc3RhbXBEdXJhdGlvblRlc3QsIEludmFsaWREdXJhdGlvbkVycm9yMykgeworICBUaW1lc3RhbXBEdXJhdGlvbiBkdXJhdGlvbjsKKworICBFWFBFQ1RfQ0FMTCgKKyAgICAgIGxpc3RlbmVyXywKKyAgICAgIEludmFsaWRWYWx1ZSgKKyAgICAgICAgICBfLCBTdHJpbmdQaWVjZSgidHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUucHJvdG9idWYuRHVyYXRpb24iKSwKKyAgICAgICAgICBTdHJpbmdQaWVjZSgiRmllbGQgJ2R1cicsIEludmFsaWQgZHVyYXRpb24gZm9ybWF0LCBmYWlsZWQgdG8gIgorICAgICAgICAgICAgICAgICAgICAgICJwYXJzZSBuYW5vIHNlY29uZHMiKSkpOworCisgIG93Xy0+U3RhcnRPYmplY3QoIiIpLT5SZW5kZXJTdHJpbmcoImR1ciIsICIxMjMuREVGcyIpLT5FbmRPYmplY3QoKTsKKyAgQ2hlY2tPdXRwdXQoZHVyYXRpb24pOworfQorCitURVNUX1AoUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJUaW1lc3RhbXBEdXJhdGlvblRlc3QsIEludmFsaWREdXJhdGlvbkVycm9yNCkgeworICBUaW1lc3RhbXBEdXJhdGlvbiBkdXJhdGlvbjsKKworICBFWFBFQ1RfQ0FMTCgKKyAgICAgIGxpc3RlbmVyXywKKyAgICAgIEludmFsaWRWYWx1ZShfLAorICAgICAgICAgICAgICAgICAgIFN0cmluZ1BpZWNlKCJ0eXBlLmdvb2dsZWFwaXMuY29tL2dvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiIpLAorICAgICAgICAgICAgICAgICAgIFN0cmluZ1BpZWNlKCJGaWVsZCAnZHVyJywgRHVyYXRpb24gdmFsdWUgZXhjZWVkcyBsaW1pdHMiKSkpOworCisgIG93Xy0+U3RhcnRPYmplY3QoIiIpLT5SZW5kZXJTdHJpbmcoImR1ciIsICIzMTU1NzYwMDAwMDJzIiktPkVuZE9iamVjdCgpOworICBDaGVja091dHB1dChkdXJhdGlvbik7Cit9CisKK1RFU1RfUChQcm90b1N0cmVhbU9iamVjdFdyaXRlclRpbWVzdGFtcER1cmF0aW9uVGVzdCwgSW52YWxpZER1cmF0aW9uRXJyb3I1KSB7CisgIFRpbWVzdGFtcER1cmF0aW9uIGR1cmF0aW9uOworCisgIEVYUEVDVF9DQUxMKAorICAgICAgbGlzdGVuZXJfLAorICAgICAgSW52YWxpZFZhbHVlKF8sCisgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UoInR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uIiksCisgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UoIkZpZWxkICdkdXInLCBEdXJhdGlvbiB2YWx1ZSBleGNlZWRzIGxpbWl0cyIpKSk7CisKKyAgb3dfLT5TdGFydE9iamVjdCgiIiktPlJlbmRlclN0cmluZygiZHVyIiwgIjAuMTAwMDAwMDAwMXMiKS0+RW5kT2JqZWN0KCk7CisgIENoZWNrT3V0cHV0KGR1cmF0aW9uKTsKK30KKworVEVTVF9QKFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyVGltZXN0YW1wRHVyYXRpb25UZXN0LAorICAgICAgIE1pc21hdGNoZWRUaW1lc3RhbXBUeXBlSW5wdXQpIHsKKyAgVGltZXN0YW1wRHVyYXRpb24gdGltZXN0YW1wOworICBFWFBFQ1RfQ0FMTCgKKyAgICAgIGxpc3RlbmVyXywKKyAgICAgIEludmFsaWRWYWx1ZSgKKyAgICAgICAgICBfLCBTdHJpbmdQaWVjZSgidHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIiksCisgICAgICAgICAgU3RyaW5nUGllY2UoCisgICAgICAgICAgICAgICJGaWVsZCAndHMnLCBJbnZhbGlkIGRhdGEgdHlwZSBmb3IgdGltZXN0YW1wLCB2YWx1ZSBpcyBudWxsIikpKQorICAgICAgLldpdGgoQXJnczwwPihIYXNPYmplY3RMb2NhdGlvbigidHMiKSkpOworICBvd18tPlN0YXJ0T2JqZWN0KCIiKS0+UmVuZGVyTnVsbCgidHMiKS0+RW5kT2JqZWN0KCk7CisgIENoZWNrT3V0cHV0KHRpbWVzdGFtcCk7Cit9CisKK1RFU1RfUChQcm90b1N0cmVhbU9iamVjdFdyaXRlclRpbWVzdGFtcER1cmF0aW9uVGVzdCwKKyAgICAgICBNaXNtYXRjaGVkRHVyYXRpb25UeXBlSW5wdXQpIHsKKyAgVGltZXN0YW1wRHVyYXRpb24gZHVyYXRpb247CisgIEVYUEVDVF9DQUxMKAorICAgICAgbGlzdGVuZXJfLAorICAgICAgSW52YWxpZFZhbHVlKAorICAgICAgICAgIF8sIFN0cmluZ1BpZWNlKCJ0eXBlLmdvb2dsZWFwaXMuY29tL2dvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiIpLAorICAgICAgICAgIFN0cmluZ1BpZWNlKAorICAgICAgICAgICAgICAiRmllbGQgJ2R1cicsIEludmFsaWQgZGF0YSB0eXBlIGZvciBkdXJhdGlvbiwgdmFsdWUgaXMgbnVsbCIpKSkKKyAgICAgIC5XaXRoKEFyZ3M8MD4oSGFzT2JqZWN0TG9jYXRpb24oImR1ciIpKSk7CisgIG93Xy0+U3RhcnRPYmplY3QoIiIpLT5SZW5kZXJOdWxsKCJkdXIiKS0+RW5kT2JqZWN0KCk7CisgIENoZWNrT3V0cHV0KGR1cmF0aW9uKTsKK30KKworY2xhc3MgUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJTdHJ1Y3RUZXN0CisgICAgOiBwdWJsaWMgQmFzZVByb3RvU3RyZWFtT2JqZWN0V3JpdGVyVGVzdCB7CisgcHJvdGVjdGVkOgorICBQcm90b1N0cmVhbU9iamVjdFdyaXRlclN0cnVjdFRlc3QoKSB7CisgICAgdmVjdG9yPGNvbnN0IERlc2NyaXB0b3IqPiBkZXNjcmlwdG9yczsKKyAgICBkZXNjcmlwdG9ycy5wdXNoX2JhY2soU3RydWN0VHlwZTo6ZGVzY3JpcHRvcigpKTsKKyAgICBkZXNjcmlwdG9ycy5wdXNoX2JhY2soZ29vZ2xlOjpwcm90b2J1Zjo6U3RydWN0OjpkZXNjcmlwdG9yKCkpOworICAgIFJlc2V0VHlwZUluZm8oZGVzY3JpcHRvcnMpOworICB9Cit9OworCitJTlNUQU5USUFURV9URVNUX0NBU0VfUChEaWZmZXJlbnRUeXBlSW5mb1NvdXJjZVRlc3QsCisgICAgICAgICAgICAgICAgICAgICAgICBQcm90b1N0cmVhbU9iamVjdFdyaXRlclN0cnVjdFRlc3QsCisgICAgICAgICAgICAgICAgICAgICAgICA6OnRlc3Rpbmc6OlZhbHVlcygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXN0aW5nOjpVU0VfVFlQRV9SRVNPTFZFUikpOworCisvLyBUT0RPKHNrYXJ2YWplKTogV3JpdGUgdGVzdHMgZm9yIGZhaWx1cmUgY2FzZXMuCitURVNUX1AoUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJTdHJ1Y3RUZXN0LCBTdHJ1Y3RSZW5kZXJTdWNjZXNzKSB7CisgIFN0cnVjdFR5cGUgc3RydWN0X3R5cGU7CisgIGdvb2dsZTo6cHJvdG9idWY6OlN0cnVjdCogcyA9IHN0cnVjdF90eXBlLm11dGFibGVfb2JqZWN0KCk7CisgIHMtPm11dGFibGVfZmllbGRzKCktPm9wZXJhdG9yW10oImsxIikuc2V0X251bWJlcl92YWx1ZSgxMjMpOworICBzLT5tdXRhYmxlX2ZpZWxkcygpLT5vcGVyYXRvcltdKCJrMiIpLnNldF9ib29sX3ZhbHVlKHRydWUpOworCisgIG93Xy0+U3RhcnRPYmplY3QoIiIpCisgICAgICAtPlN0YXJ0T2JqZWN0KCJvYmplY3QiKQorICAgICAgLT5SZW5kZXJEb3VibGUoImsxIiwgMTIzKQorICAgICAgLT5SZW5kZXJCb29sKCJrMiIsIHRydWUpCisgICAgICAtPkVuZE9iamVjdCgpCisgICAgICAtPkVuZE9iamVjdCgpOworICBDaGVja091dHB1dChzdHJ1Y3RfdHlwZSk7Cit9CisKK1RFU1RfUChQcm90b1N0cmVhbU9iamVjdFdyaXRlclN0cnVjdFRlc3QsIFN0cnVjdE51bGxJbnB1dFN1Y2Nlc3MpIHsKKyAgU3RydWN0VHlwZSBzdHJ1Y3RfdHlwZTsKKyAgRVhQRUNUX0NBTEwobGlzdGVuZXJfLAorICAgICAgICAgICAgICBJbnZhbGlkTmFtZShfLCBTdHJpbmdQaWVjZSgiIiksCisgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1BpZWNlKCJQcm90byBmaWVsZHMgbXVzdCBoYXZlIGEgbmFtZS4iKSkpCisgICAgICAuV2l0aChBcmdzPDA+KEhhc09iamVjdExvY2F0aW9uKCIiKSkpOworICBvd18tPlN0YXJ0T2JqZWN0KCIiKS0+UmVuZGVyTnVsbCgiIiktPkVuZE9iamVjdCgpOworICBDaGVja091dHB1dChzdHJ1Y3RfdHlwZSk7Cit9CisKK1RFU1RfUChQcm90b1N0cmVhbU9iamVjdFdyaXRlclN0cnVjdFRlc3QsIFN0cnVjdEludmFsaWRJbnB1dEZhaWx1cmUpIHsKKyAgU3RydWN0VHlwZSBzdHJ1Y3RfdHlwZTsKKyAgRVhQRUNUX0NBTEwoCisgICAgICBsaXN0ZW5lcl8sCisgICAgICBJbnZhbGlkVmFsdWUoXywgU3RyaW5nUGllY2UoInR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCIpLAorICAgICAgICAgICAgICAgICAgIFN0cmluZ1BpZWNlKCJ0cnVlIikpKQorICAgICAgLldpdGgoQXJnczwwPihIYXNPYmplY3RMb2NhdGlvbigib2JqZWN0IikpKTsKKworICBvd18tPlN0YXJ0T2JqZWN0KCIiKS0+UmVuZGVyQm9vbCgib2JqZWN0IiwgdHJ1ZSktPkVuZE9iamVjdCgpOworICBDaGVja091dHB1dChzdHJ1Y3RfdHlwZSk7Cit9CisKK1RFU1RfUChQcm90b1N0cmVhbU9iamVjdFdyaXRlclN0cnVjdFRlc3QsIFNpbXBsZVJlcGVhdGVkU3RydWN0TWFwS2V5VGVzdCkgeworICBFWFBFQ1RfQ0FMTCgKKyAgICAgIGxpc3RlbmVyXywKKyAgICAgIEludmFsaWROYW1lKF8sIFN0cmluZ1BpZWNlKCJnQmlrZSIpLAorICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UoIlJlcGVhdGVkIG1hcCBrZXk6ICdnQmlrZScgaXMgYWxyZWFkeSBzZXQuIikpKTsKKyAgb3dfLT5TdGFydE9iamVjdCgiIikKKyAgICAgIC0+U3RhcnRPYmplY3QoIm9iamVjdCIpCisgICAgICAtPlJlbmRlclN0cmluZygiZ0Jpa2UiLCAidjEiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoImdCaWtlIiwgInYyIikKKyAgICAgIC0+RW5kT2JqZWN0KCkKKyAgICAgIC0+RW5kT2JqZWN0KCk7Cit9CisKK1RFU1RfUChQcm90b1N0cmVhbU9iamVjdFdyaXRlclN0cnVjdFRlc3QsIFJlcGVhdGVkU3RydWN0TWFwTGlzdEtleVRlc3QpIHsKKyAgRVhQRUNUX0NBTEwoCisgICAgICBsaXN0ZW5lcl8sCisgICAgICBJbnZhbGlkTmFtZShfLCBTdHJpbmdQaWVjZSgiazEiKSwKKyAgICAgICAgICAgICAgICAgIFN0cmluZ1BpZWNlKCJSZXBlYXRlZCBtYXAga2V5OiAnazEnIGlzIGFscmVhZHkgc2V0LiIpKSk7CisgIG93Xy0+U3RhcnRPYmplY3QoIiIpCisgICAgICAtPlN0YXJ0T2JqZWN0KCJvYmplY3QiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoImsxIiwgInYxIikKKyAgICAgIC0+U3RhcnRMaXN0KCJrMSIpCisgICAgICAtPlJlbmRlclN0cmluZygiIiwgInYyIikKKyAgICAgIC0+RW5kTGlzdCgpCisgICAgICAtPkVuZE9iamVjdCgpCisgICAgICAtPkVuZE9iamVjdCgpOworfQorCitURVNUX1AoUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJTdHJ1Y3RUZXN0LCBSZXBlYXRlZFN0cnVjdE1hcE9iamVjdEtleVRlc3QpIHsKKyAgRVhQRUNUX0NBTEwoCisgICAgICBsaXN0ZW5lcl8sCisgICAgICBJbnZhbGlkTmFtZShfLCBTdHJpbmdQaWVjZSgiazEiKSwKKyAgICAgICAgICAgICAgICAgIFN0cmluZ1BpZWNlKCJSZXBlYXRlZCBtYXAga2V5OiAnazEnIGlzIGFscmVhZHkgc2V0LiIpKSk7CisgIG93Xy0+U3RhcnRPYmplY3QoIiIpCisgICAgICAtPlN0YXJ0T2JqZWN0KCJvYmplY3QiKQorICAgICAgLT5TdGFydE9iamVjdCgiazEiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoInN1Yl9rMSIsICJ2MSIpCisgICAgICAtPkVuZE9iamVjdCgpCisgICAgICAtPlN0YXJ0T2JqZWN0KCJrMSIpCisgICAgICAtPlJlbmRlclN0cmluZygic3ViX2syIiwgInYyIikKKyAgICAgIC0+RW5kT2JqZWN0KCkKKyAgICAgIC0+RW5kT2JqZWN0KCkKKyAgICAgIC0+RW5kT2JqZWN0KCk7Cit9CisKK2NsYXNzIFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyTWFwVGVzdCA6IHB1YmxpYyBCYXNlUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJUZXN0IHsKKyBwcm90ZWN0ZWQ6CisgIFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyTWFwVGVzdCgpCisgICAgICA6IEJhc2VQcm90b1N0cmVhbU9iamVjdFdyaXRlclRlc3QoTWFwSW46OmRlc2NyaXB0b3IoKSkge30KK307CisKK0lOU1RBTlRJQVRFX1RFU1RfQ0FTRV9QKERpZmZlcmVudFR5cGVJbmZvU291cmNlVGVzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgIFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyTWFwVGVzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgIDo6dGVzdGluZzo6VmFsdWVzKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlc3Rpbmc6OlVTRV9UWVBFX1JFU09MVkVSKSk7CisKK1RFU1RfUChQcm90b1N0cmVhbU9iamVjdFdyaXRlck1hcFRlc3QsIE1hcFNob3VsZE5vdEFjY2VwdExpc3QpIHsKKyAgTWFwSW4gbW07CisgIEVYUEVDVF9DQUxMKAorICAgICAgbGlzdGVuZXJfLAorICAgICAgSW52YWxpZFZhbHVlKAorICAgICAgICAgIF8sIFN0cmluZ1BpZWNlKCJNYXAiKSwKKyAgICAgICAgICBTdHJpbmdQaWVjZSgiQ2Fubm90IGJpbmQgYSBsaXN0IHRvIG1hcCBmb3IgZmllbGQgJ21hcF9pbnB1dCcuIikpKTsKKyAgb3dfLT5TdGFydE9iamVjdCgiIikKKyAgICAgIC0+U3RhcnRMaXN0KCJtYXBfaW5wdXQiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoImEiLCAiYiIpCisgICAgICAtPkVuZExpc3QoKQorICAgICAgLT5FbmRPYmplY3QoKTsKKyAgQ2hlY2tPdXRwdXQobW0pOworfQorCitURVNUX1AoUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJNYXBUZXN0LCBSZXBlYXRlZE1hcEtleVRlc3QpIHsKKyAgRVhQRUNUX0NBTEwoCisgICAgICBsaXN0ZW5lcl8sCisgICAgICBJbnZhbGlkTmFtZShfLCBTdHJpbmdQaWVjZSgiazEiKSwKKyAgICAgICAgICAgICAgICAgIFN0cmluZ1BpZWNlKCJSZXBlYXRlZCBtYXAga2V5OiAnazEnIGlzIGFscmVhZHkgc2V0LiIpKSk7CisgIG93Xy0+U3RhcnRPYmplY3QoIiIpCisgICAgICAtPlJlbmRlclN0cmluZygib3RoZXIiLCAidGVzdCIpCisgICAgICAtPlN0YXJ0T2JqZWN0KCJtYXBfaW5wdXQiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoImsxIiwgInYxIikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJrMSIsICJ2MiIpCisgICAgICAtPkVuZE9iamVjdCgpCisgICAgICAtPkVuZE9iamVjdCgpOworfQorCitjbGFzcyBQcm90b1N0cmVhbU9iamVjdFdyaXRlckFueVRlc3QgOiBwdWJsaWMgQmFzZVByb3RvU3RyZWFtT2JqZWN0V3JpdGVyVGVzdCB7CisgcHJvdGVjdGVkOgorICBQcm90b1N0cmVhbU9iamVjdFdyaXRlckFueVRlc3QoKSB7CisgICAgdmVjdG9yPGNvbnN0IERlc2NyaXB0b3IqPiBkZXNjcmlwdG9yczsKKyAgICBkZXNjcmlwdG9ycy5wdXNoX2JhY2soQW55T3V0OjpkZXNjcmlwdG9yKCkpOworICAgIGRlc2NyaXB0b3JzLnB1c2hfYmFjayhnb29nbGU6OnByb3RvYnVmOjpEb3VibGVWYWx1ZTo6ZGVzY3JpcHRvcigpKTsKKyAgICBkZXNjcmlwdG9ycy5wdXNoX2JhY2soZ29vZ2xlOjpwcm90b2J1Zjo6VGltZXN0YW1wOjpkZXNjcmlwdG9yKCkpOworICAgIGRlc2NyaXB0b3JzLnB1c2hfYmFjayhnb29nbGU6OnByb3RvYnVmOjpBbnk6OmRlc2NyaXB0b3IoKSk7CisgICAgUmVzZXRUeXBlSW5mbyhkZXNjcmlwdG9ycyk7CisgIH0KK307CisKK0lOU1RBTlRJQVRFX1RFU1RfQ0FTRV9QKERpZmZlcmVudFR5cGVJbmZvU291cmNlVGVzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgIFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyQW55VGVzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgIDo6dGVzdGluZzo6VmFsdWVzKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlc3Rpbmc6OlVTRV9UWVBFX1JFU09MVkVSKSk7CisKK1RFU1RfUChQcm90b1N0cmVhbU9iamVjdFdyaXRlckFueVRlc3QsIEFueVJlbmRlclN1Y2Nlc3MpIHsKKyAgQW55T3V0IGFueTsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6QW55KiBhbnlfdHlwZSA9IGFueS5tdXRhYmxlX2FueSgpOworICBhbnlfdHlwZS0+c2V0X3R5cGVfdXJsKCJ0eXBlLmdvb2dsZWFwaXMuY29tL2dvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSIpOworICBnb29nbGU6OnByb3RvYnVmOjpEb3VibGVWYWx1ZSBkOworICBkLnNldF92YWx1ZSg0MC4yKTsKKyAgYW55X3R5cGUtPnNldF92YWx1ZShkLlNlcmlhbGl6ZUFzU3RyaW5nKCkpOworCisgIG93Xy0+U3RhcnRPYmplY3QoIiIpCisgICAgICAtPlN0YXJ0T2JqZWN0KCJhbnkiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoIkB0eXBlIiwgInR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlIikKKyAgICAgIC0+UmVuZGVyRG91YmxlKCJ2YWx1ZSIsIDQwLjIpCisgICAgICAtPkVuZE9iamVjdCgpCisgICAgICAtPkVuZE9iamVjdCgpOworICBDaGVja091dHB1dChhbnkpOworfQorCitURVNUX1AoUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJBbnlUZXN0LCBSZWN1cnNpdmVBbnkpIHsKKyAgQW55T3V0IG91dDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpBbnkqIGFueSA9IG91dC5tdXRhYmxlX2FueSgpOworICBhbnktPnNldF90eXBlX3VybCgidHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUucHJvdG9idWYuQW55Iik7CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpBbnkgbmVzdGVkX2FueTsKKyAgbmVzdGVkX2FueS5zZXRfdHlwZV91cmwoCisgICAgICAidHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUucHJvdG9idWYudGVzdGluZy5hbnlzLkFueU0iKTsKKworICBBbnlNIG07CisgIG0uc2V0X2ZvbygiZm9vdmFsdWUiKTsKKyAgbmVzdGVkX2FueS5zZXRfdmFsdWUobS5TZXJpYWxpemVBc1N0cmluZygpKTsKKworICBhbnktPnNldF92YWx1ZShuZXN0ZWRfYW55LlNlcmlhbGl6ZUFzU3RyaW5nKCkpOworCisgIG93Xy0+U3RhcnRPYmplY3QoIiIpCisgICAgICAtPlN0YXJ0T2JqZWN0KCJhbnkiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoIkB0eXBlIiwgInR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLnByb3RvYnVmLkFueSIpCisgICAgICAtPlN0YXJ0T2JqZWN0KCJ2YWx1ZSIpCisgICAgICAtPlJlbmRlclN0cmluZygiQHR5cGUiLAorICAgICAgICAgICAgICAgICAgICAgInR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuYW55cy5BbnlNIikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJmb28iLCAiZm9vdmFsdWUiKQorICAgICAgLT5FbmRPYmplY3QoKQorICAgICAgLT5FbmRPYmplY3QoKQorICAgICAgLT5FbmRPYmplY3QoKTsKK30KKworVEVTVF9QKFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyQW55VGVzdCwgRG91YmxlUmVjdXJzaXZlQW55KSB7CisgIEFueU91dCBvdXQ7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QW55KiBhbnkgPSBvdXQubXV0YWJsZV9hbnkoKTsKKyAgYW55LT5zZXRfdHlwZV91cmwoInR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLnByb3RvYnVmLkFueSIpOworCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QW55IG5lc3RlZF9hbnk7CisgIG5lc3RlZF9hbnkuc2V0X3R5cGVfdXJsKCJ0eXBlLmdvb2dsZWFwaXMuY29tL2dvb2dsZS5wcm90b2J1Zi5BbnkiKTsKKworICA6Omdvb2dsZTo6cHJvdG9idWY6OkFueSBzZWNvbmRfbmVzdGVkX2FueTsKKyAgc2Vjb25kX25lc3RlZF9hbnkuc2V0X3R5cGVfdXJsKAorICAgICAgInR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuYW55cy5BbnlNIik7CisKKyAgQW55TSBtOworICBtLnNldF9mb28oImZvb3ZhbHVlIik7CisgIHNlY29uZF9uZXN0ZWRfYW55LnNldF92YWx1ZShtLlNlcmlhbGl6ZUFzU3RyaW5nKCkpOworCisgIG5lc3RlZF9hbnkuc2V0X3ZhbHVlKHNlY29uZF9uZXN0ZWRfYW55LlNlcmlhbGl6ZUFzU3RyaW5nKCkpOworICBhbnktPnNldF92YWx1ZShuZXN0ZWRfYW55LlNlcmlhbGl6ZUFzU3RyaW5nKCkpOworCisgIG93Xy0+U3RhcnRPYmplY3QoIiIpCisgICAgICAtPlN0YXJ0T2JqZWN0KCJhbnkiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoIkB0eXBlIiwgInR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLnByb3RvYnVmLkFueSIpCisgICAgICAtPlN0YXJ0T2JqZWN0KCJ2YWx1ZSIpCisgICAgICAtPlJlbmRlclN0cmluZygiQHR5cGUiLCAidHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUucHJvdG9idWYuQW55IikKKyAgICAgIC0+U3RhcnRPYmplY3QoInZhbHVlIikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJAdHlwZSIsCisgICAgICAgICAgICAgICAgICAgICAidHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUucHJvdG9idWYudGVzdGluZy5hbnlzLkFueU0iKQorICAgICAgLT5SZW5kZXJTdHJpbmcoImZvbyIsICJmb292YWx1ZSIpCisgICAgICAtPkVuZE9iamVjdCgpCisgICAgICAtPkVuZE9iamVjdCgpCisgICAgICAtPkVuZE9iamVjdCgpCisgICAgICAtPkVuZE9iamVjdCgpOworfQorCitURVNUX1AoUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJBbnlUZXN0LCBFbXB0eUFueUZyb21FbXB0eU9iamVjdCkgeworICBBbnlPdXQgb3V0OworICBvdXQubXV0YWJsZV9hbnkoKTsKKworICBvd18tPlN0YXJ0T2JqZWN0KCIiKS0+U3RhcnRPYmplY3QoImFueSIpLT5FbmRPYmplY3QoKS0+RW5kT2JqZWN0KCk7CisKKyAgQ2hlY2tPdXRwdXQob3V0LCAyKTsKK30KKworVEVTVF9QKFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyQW55VGVzdCwgQW55V2l0aG91dFR5cGVVcmxGYWlsczEpIHsKKyAgQW55T3V0IGFueTsKKworICBFWFBFQ1RfQ0FMTCgKKyAgICAgIGxpc3RlbmVyXywKKyAgICAgIEludmFsaWRWYWx1ZShfLCBTdHJpbmdQaWVjZSgiQW55IiksCisgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UoIk1pc3Npbmcgb3IgaW52YWxpZCBAdHlwZSBmb3IgYW55IGZpZWxkIGluICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcuYW55cy5BbnlPdXQiKSkpOworCisgIG93Xy0+U3RhcnRPYmplY3QoIiIpCisgICAgICAtPlN0YXJ0T2JqZWN0KCJhbnkiKQorICAgICAgLT5TdGFydE9iamVjdCgiYW5vdGhlciIpCisgICAgICAtPkVuZE9iamVjdCgpCisgICAgICAtPkVuZE9iamVjdCgpCisgICAgICAtPkVuZE9iamVjdCgpOworICBDaGVja091dHB1dChhbnkpOworfQorCitURVNUX1AoUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJBbnlUZXN0LCBBbnlXaXRob3V0VHlwZVVybEZhaWxzMikgeworICBBbnlPdXQgYW55OworCisgIEVYUEVDVF9DQUxMKAorICAgICAgbGlzdGVuZXJfLAorICAgICAgSW52YWxpZFZhbHVlKF8sIFN0cmluZ1BpZWNlKCJBbnkiKSwKKyAgICAgICAgICAgICAgICAgICBTdHJpbmdQaWVjZSgiTWlzc2luZyBvciBpbnZhbGlkIEB0eXBlIGZvciBhbnkgZmllbGQgaW4gIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJnb29nbGUucHJvdG9idWYudGVzdGluZy5hbnlzLkFueU91dCIpKSk7CisKKyAgb3dfLT5TdGFydE9iamVjdCgiIikKKyAgICAgIC0+U3RhcnRPYmplY3QoImFueSIpCisgICAgICAtPlN0YXJ0TGlzdCgiYW5vdGhlciIpCisgICAgICAtPkVuZE9iamVjdCgpCisgICAgICAtPkVuZE9iamVjdCgpCisgICAgICAtPkVuZE9iamVjdCgpOworICBDaGVja091dHB1dChhbnkpOworfQorCitURVNUX1AoUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJBbnlUZXN0LCBBbnlXaXRob3V0VHlwZVVybEZhaWxzMykgeworICBBbnlPdXQgYW55OworCisgIEVYUEVDVF9DQUxMKAorICAgICAgbGlzdGVuZXJfLAorICAgICAgSW52YWxpZFZhbHVlKF8sIFN0cmluZ1BpZWNlKCJBbnkiKSwKKyAgICAgICAgICAgICAgICAgICBTdHJpbmdQaWVjZSgiTWlzc2luZyBvciBpbnZhbGlkIEB0eXBlIGZvciBhbnkgZmllbGQgaW4gIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJnb29nbGUucHJvdG9idWYudGVzdGluZy5hbnlzLkFueU91dCIpKSk7CisKKyAgb3dfLT5TdGFydE9iamVjdCgiIikKKyAgICAgIC0+U3RhcnRPYmplY3QoImFueSIpCisgICAgICAtPlJlbmRlclN0cmluZygidmFsdWUiLCAic29tZXZhbHVlIikKKyAgICAgIC0+RW5kT2JqZWN0KCkKKyAgICAgIC0+RW5kT2JqZWN0KCk7CisgIENoZWNrT3V0cHV0KGFueSk7Cit9CisKK1RFU1RfUChQcm90b1N0cmVhbU9iamVjdFdyaXRlckFueVRlc3QsIEFueVdpdGhJbnZhbGlkVHlwZVVybEZhaWxzKSB7CisgIEFueU91dCBhbnk7CisKKyAgRVhQRUNUX0NBTEwobGlzdGVuZXJfLAorICAgICAgICAgICAgICBJbnZhbGlkVmFsdWUoCisgICAgICAgICAgICAgICAgICBfLCBTdHJpbmdQaWVjZSgiQW55IiksCisgICAgICAgICAgICAgICAgICBTdHJpbmdQaWVjZSgiSW52YWxpZCB0eXBlIFVSTCwgdHlwZSBVUkxzIG11c3QgYmUgb2YgdGhlIGZvcm0gIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIid0eXBlLmdvb2dsZWFwaXMuY29tLzx0eXBlbmFtZT4nLCBnb3Q6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlLm90aGVyLmNvbS9zb21lLlR5cGUiKSkpOworCisgIG93Xy0+U3RhcnRPYmplY3QoIiIpCisgICAgICAtPlN0YXJ0T2JqZWN0KCJhbnkiKQorICAgICAgLT5SZW5kZXJTdHJpbmcoIkB0eXBlIiwgInR5cGUub3RoZXIuY29tL3NvbWUuVHlwZSIpCisgICAgICAtPlJlbmRlckRvdWJsZSgidmFsdWUiLCA0MC4yKQorICAgICAgLT5FbmRPYmplY3QoKQorICAgICAgLT5FbmRPYmplY3QoKTsKKyAgQ2hlY2tPdXRwdXQoYW55KTsKK30KKworVEVTVF9QKFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyQW55VGVzdCwgQW55V2l0aFVua25vd25UeXBlRmFpbHMpIHsKKyAgQW55T3V0IGFueTsKKworICBFWFBFQ1RfQ0FMTCgKKyAgICAgIGxpc3RlbmVyXywKKyAgICAgIEludmFsaWRWYWx1ZShfLCBTdHJpbmdQaWVjZSgiQW55IiksCisgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UoIkludmFsaWQgdHlwZSBVUkwsIHVua25vd24gdHlwZTogc29tZS5UeXBlIikpKTsKKyAgb3dfLT5TdGFydE9iamVjdCgiIikKKyAgICAgIC0+U3RhcnRPYmplY3QoImFueSIpCisgICAgICAtPlJlbmRlclN0cmluZygiQHR5cGUiLCAidHlwZS5nb29nbGVhcGlzLmNvbS9zb21lLlR5cGUiKQorICAgICAgLT5SZW5kZXJEb3VibGUoInZhbHVlIiwgNDAuMikKKyAgICAgIC0+RW5kT2JqZWN0KCkKKyAgICAgIC0+RW5kT2JqZWN0KCk7CisgIENoZWNrT3V0cHV0KGFueSk7Cit9CisKK1RFU1RfUChQcm90b1N0cmVhbU9iamVjdFdyaXRlckFueVRlc3QsIEFueU51bGxJbnB1dEZhaWxzKSB7CisgIEFueU91dCBhbnk7CisKKyAgb3dfLT5TdGFydE9iamVjdCgiIiktPlJlbmRlck51bGwoImFueSIpLT5FbmRPYmplY3QoKTsKKyAgQ2hlY2tPdXRwdXQoYW55KTsKK30KKworVEVTVF9QKFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyQW55VGVzdCwgQW55V2VsbEtub3duVHlwZUVycm9yVGVzdCkgeworICBFWFBFQ1RfQ0FMTChsaXN0ZW5lcl8sIEludmFsaWRWYWx1ZShfLCBTdHJpbmdQaWVjZSgiQW55IiksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1BpZWNlKCJJbnZhbGlkIHRpbWUgZm9ybWF0OiAiKSkpOworCisgIEFueU91dCBhbnk7CisgIGdvb2dsZTo6cHJvdG9idWY6OkFueSogYW55X3R5cGUgPSBhbnkubXV0YWJsZV9hbnkoKTsKKyAgYW55X3R5cGUtPnNldF90eXBlX3VybCgidHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIik7CisKKyAgb3dfLT5TdGFydE9iamVjdCgiIikKKyAgICAgIC0+U3RhcnRPYmplY3QoImFueSIpCisgICAgICAtPlJlbmRlclN0cmluZygiQHR5cGUiLCAidHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIikKKyAgICAgIC0+UmVuZGVyU3RyaW5nKCJ2YWx1ZSIsICIiKQorICAgICAgLT5FbmRPYmplY3QoKQorICAgICAgLT5FbmRPYmplY3QoKTsKKyAgQ2hlY2tPdXRwdXQoYW55KTsKK30KKworY2xhc3MgUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJGaWVsZE1hc2tUZXN0CisgICAgOiBwdWJsaWMgQmFzZVByb3RvU3RyZWFtT2JqZWN0V3JpdGVyVGVzdCB7CisgcHJvdGVjdGVkOgorICBQcm90b1N0cmVhbU9iamVjdFdyaXRlckZpZWxkTWFza1Rlc3QoKSB7CisgICAgdmVjdG9yPGNvbnN0IERlc2NyaXB0b3IqPiBkZXNjcmlwdG9yczsKKyAgICBkZXNjcmlwdG9ycy5wdXNoX2JhY2soRmllbGRNYXNrVGVzdDo6ZGVzY3JpcHRvcigpKTsKKyAgICBkZXNjcmlwdG9ycy5wdXNoX2JhY2soZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGRNYXNrOjpkZXNjcmlwdG9yKCkpOworICAgIFJlc2V0VHlwZUluZm8oZGVzY3JpcHRvcnMpOworICB9Cit9OworCitJTlNUQU5USUFURV9URVNUX0NBU0VfUChEaWZmZXJlbnRUeXBlSW5mb1NvdXJjZVRlc3QsCisgICAgICAgICAgICAgICAgICAgICAgICBQcm90b1N0cmVhbU9iamVjdFdyaXRlckZpZWxkTWFza1Rlc3QsCisgICAgICAgICAgICAgICAgICAgICAgICA6OnRlc3Rpbmc6OlZhbHVlcygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXN0aW5nOjpVU0VfVFlQRV9SRVNPTFZFUikpOworCitURVNUX1AoUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJGaWVsZE1hc2tUZXN0LCBTaW1wbGVGaWVsZE1hc2tUZXN0KSB7CisgIEZpZWxkTWFza1Rlc3QgZXhwZWN0ZWQ7CisgIGV4cGVjdGVkLnNldF9pZCgiMSIpOworICBleHBlY3RlZC5tdXRhYmxlX3NpbmdsZV9tYXNrKCktPmFkZF9wYXRocygicGF0aDEiKTsKKworICBvd18tPlN0YXJ0T2JqZWN0KCIiKTsKKyAgb3dfLT5SZW5kZXJTdHJpbmcoImlkIiwgIjEiKTsKKyAgb3dfLT5SZW5kZXJTdHJpbmcoInNpbmdsZV9tYXNrIiwgInBhdGgxIik7CisgIG93Xy0+RW5kT2JqZWN0KCk7CisKKyAgQ2hlY2tPdXRwdXQoZXhwZWN0ZWQpOworfQorCitURVNUX1AoUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJGaWVsZE1hc2tUZXN0LCBNdXRpcGxlTWFza3NJbkNvbXBhY3RGb3JtKSB7CisgIEZpZWxkTWFza1Rlc3QgZXhwZWN0ZWQ7CisgIGV4cGVjdGVkLnNldF9pZCgiMSIpOworICBleHBlY3RlZC5tdXRhYmxlX3NpbmdsZV9tYXNrKCktPmFkZF9wYXRocygiY2FtZWxfY2FzZTEiKTsKKyAgZXhwZWN0ZWQubXV0YWJsZV9zaW5nbGVfbWFzaygpLT5hZGRfcGF0aHMoImNhbWVsX2Nhc2UyIik7CisgIGV4cGVjdGVkLm11dGFibGVfc2luZ2xlX21hc2soKS0+YWRkX3BhdGhzKCJjYW1lbF9jYXNlMyIpOworCisgIG93Xy0+U3RhcnRPYmplY3QoIiIpOworICBvd18tPlJlbmRlclN0cmluZygiaWQiLCAiMSIpOworICBvd18tPlJlbmRlclN0cmluZygic2luZ2xlX21hc2siLCAiY2FtZWxDYXNlMSxjYW1lbENhc2UyLGNhbWVsQ2FzZTMiKTsKKyAgb3dfLT5FbmRPYmplY3QoKTsKKworICBDaGVja091dHB1dChleHBlY3RlZCk7Cit9CisKK1RFU1RfUChQcm90b1N0cmVhbU9iamVjdFdyaXRlckZpZWxkTWFza1Rlc3QsIFJlcGVhdGVkRmllbGRNYXNrVGVzdCkgeworICBGaWVsZE1hc2tUZXN0IGV4cGVjdGVkOworICBleHBlY3RlZC5zZXRfaWQoIjEiKTsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGRNYXNrKiBtYXNrID0gZXhwZWN0ZWQuYWRkX3JlcGVhdGVkX21hc2soKTsKKyAgbWFzay0+YWRkX3BhdGhzKCJmaWVsZDEiKTsKKyAgbWFzay0+YWRkX3BhdGhzKCJmaWVsZDIiKTsKKyAgZXhwZWN0ZWQuYWRkX3JlcGVhdGVkX21hc2soKS0+YWRkX3BhdGhzKCJmaWVsZDMiKTsKKworICBvd18tPlN0YXJ0T2JqZWN0KCIiKTsKKyAgb3dfLT5SZW5kZXJTdHJpbmcoImlkIiwgIjEiKTsKKyAgb3dfLT5TdGFydExpc3QoInJlcGVhdGVkX21hc2siKTsKKyAgb3dfLT5SZW5kZXJTdHJpbmcoIiIsICJmaWVsZDEsZmllbGQyIik7CisgIG93Xy0+UmVuZGVyU3RyaW5nKCIiLCAiZmllbGQzIik7CisgIG93Xy0+RW5kTGlzdCgpOworICBvd18tPkVuZE9iamVjdCgpOworCisgIENoZWNrT3V0cHV0KGV4cGVjdGVkKTsKK30KKworVEVTVF9QKFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyRmllbGRNYXNrVGVzdCwgRW1wdHlGaWVsZE1hc2tUZXN0KSB7CisgIEZpZWxkTWFza1Rlc3QgZXhwZWN0ZWQ7CisgIGV4cGVjdGVkLnNldF9pZCgiMSIpOworCisgIG93Xy0+U3RhcnRPYmplY3QoIiIpOworICBvd18tPlJlbmRlclN0cmluZygiaWQiLCAiMSIpOworICBvd18tPlJlbmRlclN0cmluZygic2luZ2xlX21hc2siLCAiIik7CisgIG93Xy0+RW5kT2JqZWN0KCk7CisKKyAgQ2hlY2tPdXRwdXQoZXhwZWN0ZWQpOworfQorCitURVNUX1AoUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJGaWVsZE1hc2tUZXN0LCBNYXNrVXNpbmdBcGlhcnlTdHlsZVNob3VsZFdvcmspIHsKKyAgRmllbGRNYXNrVGVzdCBleHBlY3RlZDsKKyAgZXhwZWN0ZWQuc2V0X2lkKCIxIik7CisKKyAgb3dfLT5TdGFydE9iamVjdCgiIik7CisgIG93Xy0+UmVuZGVyU3RyaW5nKCJpZCIsICIxIik7CisgIC8vIENhc2UxCisgIG93Xy0+UmVuZGVyU3RyaW5nKCJzaW5nbGVfbWFzayIsCisgICAgICAgICAgICAgICAgICAgICJvdXRlckZpZWxkKGNhbWVsQ2FzZTEsY2FtZWxDYXNlMixjYW1lbENhc2UzKSIpOworICBleHBlY3RlZC5tdXRhYmxlX3NpbmdsZV9tYXNrKCktPmFkZF9wYXRocygib3V0ZXJfZmllbGQuY2FtZWxfY2FzZTEiKTsKKyAgZXhwZWN0ZWQubXV0YWJsZV9zaW5nbGVfbWFzaygpLT5hZGRfcGF0aHMoIm91dGVyX2ZpZWxkLmNhbWVsX2Nhc2UyIik7CisgIGV4cGVjdGVkLm11dGFibGVfc2luZ2xlX21hc2soKS0+YWRkX3BhdGhzKCJvdXRlcl9maWVsZC5jYW1lbF9jYXNlMyIpOworCisgIG93Xy0+U3RhcnRMaXN0KCJyZXBlYXRlZF9tYXNrIik7CisKKyAgb3dfLT5SZW5kZXJTdHJpbmcoIiIsICJhKGZpZWxkMSxmaWVsZDIpIik7CisgIGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkTWFzayogbWFzayA9IGV4cGVjdGVkLmFkZF9yZXBlYXRlZF9tYXNrKCk7CisgIG1hc2stPmFkZF9wYXRocygiYS5maWVsZDEiKTsKKyAgbWFzay0+YWRkX3BhdGhzKCJhLmZpZWxkMiIpOworCisgIG93Xy0+UmVuZGVyU3RyaW5nKCIiLCAiYShmaWVsZDMpIik7CisgIG1hc2sgPSBleHBlY3RlZC5hZGRfcmVwZWF0ZWRfbWFzaygpOworICBtYXNrLT5hZGRfcGF0aHMoImEuZmllbGQzIik7CisKKyAgb3dfLT5SZW5kZXJTdHJpbmcoIiIsICJhKCkiKTsKKyAgZXhwZWN0ZWQuYWRkX3JlcGVhdGVkX21hc2soKTsKKworICBvd18tPlJlbmRlclN0cmluZygiIiwgImEoLCkiKTsKKyAgZXhwZWN0ZWQuYWRkX3JlcGVhdGVkX21hc2soKTsKKworICBvd18tPlJlbmRlclN0cmluZygiIiwgImEoZmllbGQxKGZpZWxkMihmaWVsZDMpKSkiKTsKKyAgbWFzayA9IGV4cGVjdGVkLmFkZF9yZXBlYXRlZF9tYXNrKCk7CisgIG1hc2stPmFkZF9wYXRocygiYS5maWVsZDEuZmllbGQyLmZpZWxkMyIpOworCisgIG93Xy0+UmVuZGVyU3RyaW5nKCIiLCAiYShmaWVsZDEoZmllbGQyKGZpZWxkMyxmaWVsZDQpLGZpZWxkNSksZmllbGQ2KSIpOworICBtYXNrID0gZXhwZWN0ZWQuYWRkX3JlcGVhdGVkX21hc2soKTsKKyAgbWFzay0+YWRkX3BhdGhzKCJhLmZpZWxkMS5maWVsZDIuZmllbGQzIik7CisgIG1hc2stPmFkZF9wYXRocygiYS5maWVsZDEuZmllbGQyLmZpZWxkNCIpOworICBtYXNrLT5hZGRfcGF0aHMoImEuZmllbGQxLmZpZWxkNSIpOworICBtYXNrLT5hZGRfcGF0aHMoImEuZmllbGQ2Iik7CisKKyAgb3dfLT5SZW5kZXJTdHJpbmcoIiIsICJhKGlkLGZpZWxkMShpZCxmaWVsZDIoZmllbGQzLGZpZWxkNCksZmllbGQ1KSxmaWVsZDYpIik7CisgIG1hc2sgPSBleHBlY3RlZC5hZGRfcmVwZWF0ZWRfbWFzaygpOworICBtYXNrLT5hZGRfcGF0aHMoImEuaWQiKTsKKyAgbWFzay0+YWRkX3BhdGhzKCJhLmZpZWxkMS5pZCIpOworICBtYXNrLT5hZGRfcGF0aHMoImEuZmllbGQxLmZpZWxkMi5maWVsZDMiKTsKKyAgbWFzay0+YWRkX3BhdGhzKCJhLmZpZWxkMS5maWVsZDIuZmllbGQ0Iik7CisgIG1hc2stPmFkZF9wYXRocygiYS5maWVsZDEuZmllbGQ1Iik7CisgIG1hc2stPmFkZF9wYXRocygiYS5maWVsZDYiKTsKKworICBvd18tPlJlbmRlclN0cmluZygiIiwgImEoKChmaWVsZDMsZmllbGQ0KSkpIik7CisgIG1hc2sgPSBleHBlY3RlZC5hZGRfcmVwZWF0ZWRfbWFzaygpOworICBtYXNrLT5hZGRfcGF0aHMoImEuZmllbGQzIik7CisgIG1hc2stPmFkZF9wYXRocygiYS5maWVsZDQiKTsKKworICBvd18tPkVuZExpc3QoKTsKKyAgb3dfLT5FbmRPYmplY3QoKTsKKworICBDaGVja091dHB1dChleHBlY3RlZCk7Cit9CisKK1RFU1RfUChQcm90b1N0cmVhbU9iamVjdFdyaXRlckZpZWxkTWFza1Rlc3QsIE1vcmVDbG9zZVRoYW5PcGVuUGFyZW50aGVzZXMpIHsKKyAgRVhQRUNUX0NBTEwoCisgICAgICBsaXN0ZW5lcl8sCisgICAgICBJbnZhbGlkVmFsdWUoCisgICAgICAgICAgXywgU3RyaW5nUGllY2UoInR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayIpLAorICAgICAgICAgIFN0cmluZ1BpZWNlKCJGaWVsZCAnc2luZ2xlX21hc2snLCBJbnZhbGlkIEZpZWxkTWFzayAnYShiLGMpKScuICIKKyAgICAgICAgICAgICAgICAgICAgICAiQ2Fubm90IGZpbmQgbWF0Y2hpbmcgJygnIGZvciBhbGwgJyknLiIpKSk7CisKKyAgb3dfLT5TdGFydE9iamVjdCgiIik7CisgIG93Xy0+UmVuZGVyU3RyaW5nKCJpZCIsICIxIik7CisgIG93Xy0+UmVuZGVyU3RyaW5nKCJzaW5nbGVfbWFzayIsICJhKGIsYykpIik7CisgIG93Xy0+RW5kT2JqZWN0KCk7Cit9CisKK1RFU1RfUChQcm90b1N0cmVhbU9iamVjdFdyaXRlckZpZWxkTWFza1Rlc3QsIE1vcmVPcGVuVGhhbkNsb3NlUGFyZW50aGVzZXMpIHsKKyAgRVhQRUNUX0NBTEwoCisgICAgICBsaXN0ZW5lcl8sCisgICAgICBJbnZhbGlkVmFsdWUoCisgICAgICAgICAgXywgU3RyaW5nUGllY2UoInR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayIpLAorICAgICAgICAgIFN0cmluZ1BpZWNlKAorICAgICAgICAgICAgICAiRmllbGQgJ3NpbmdsZV9tYXNrJywgSW52YWxpZCBGaWVsZE1hc2sgJ2EoKChiLGMpJy4gQ2Fubm90ICIKKyAgICAgICAgICAgICAgImZpbmQgbWF0Y2hpbmcgJyknIGZvciBhbGwgJygnLiIpKSk7CisKKyAgb3dfLT5TdGFydE9iamVjdCgiIik7CisgIG93Xy0+UmVuZGVyU3RyaW5nKCJpZCIsICIxIik7CisgIG93Xy0+UmVuZGVyU3RyaW5nKCJzaW5nbGVfbWFzayIsICJhKCgoYixjKSIpOworICBvd18tPkVuZE9iamVjdCgpOworfQorCitURVNUX1AoUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJGaWVsZE1hc2tUZXN0LCBQYXRoV2l0aE1hcEtleVNob3VsZFdvcmspIHsKKyAgRmllbGRNYXNrVGVzdCBleHBlY3RlZDsKKyAgZXhwZWN0ZWQubXV0YWJsZV9zaW5nbGVfbWFzaygpLT5hZGRfcGF0aHMoInBhdGgudG8ubWFwW1wia2V5MVwiXSIpOworICBleHBlY3RlZC5tdXRhYmxlX3NpbmdsZV9tYXNrKCktPmFkZF9wYXRocygKKyAgICAgICJwYXRoLnRvLm1hcFtcImVcXFwiW11dW3NjYXBlXFxcIlwiXSIpOworICBleHBlY3RlZC5tdXRhYmxlX3NpbmdsZV9tYXNrKCktPmFkZF9wYXRocygicGF0aC50by5tYXBbXCJrZXkyXCJdIik7CisKKyAgb3dfLT5TdGFydE9iamVjdCgiIik7CisgIG93Xy0+UmVuZGVyU3RyaW5nKCJzaW5nbGVfbWFzayIsCisgICAgICAgICAgICAgICAgICAgICJwYXRoLnRvLm1hcFtcImtleTFcIl0scGF0aC50by5tYXBbXCJlXFxcIltdXVtzY2FwZVxcXCJcIl0sIgorICAgICAgICAgICAgICAgICAgICAicGF0aC50by5tYXBbXCJrZXkyXCJdIik7CisgIG93Xy0+RW5kT2JqZWN0KCk7CisKKyAgQ2hlY2tPdXRwdXQoZXhwZWN0ZWQpOworfQorCitURVNUX1AoUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJGaWVsZE1hc2tUZXN0LAorICAgICAgIE1hcEtleU11c3RCZUF0VGhlRW5kT2ZBUGF0aFNlZ21lbnQpIHsKKyAgRVhQRUNUX0NBTEwoCisgICAgICBsaXN0ZW5lcl8sCisgICAgICBJbnZhbGlkVmFsdWUoCisgICAgICAgICAgXywgU3RyaW5nUGllY2UoInR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayIpLAorICAgICAgICAgIFN0cmluZ1BpZWNlKCJGaWVsZCAnc2luZ2xlX21hc2snLCBJbnZhbGlkIEZpZWxkTWFzayAiCisgICAgICAgICAgICAgICAgICAgICAgIidwYXRoLnRvLm1hcFtcImtleTFcIl1hLHBhdGgudG8ubWFwW1wia2V5MlwiXScuICIKKyAgICAgICAgICAgICAgICAgICAgICAiTWFwIGtleXMgc2hvdWxkIGJlIGF0IHRoZSBlbmQgb2YgYSBwYXRoIHNlZ21lbnQuIikpKTsKKworICBvd18tPlN0YXJ0T2JqZWN0KCIiKTsKKyAgb3dfLT5SZW5kZXJTdHJpbmcoInNpbmdsZV9tYXNrIiwKKyAgICAgICAgICAgICAgICAgICAgInBhdGgudG8ubWFwW1wia2V5MVwiXWEscGF0aC50by5tYXBbXCJrZXkyXCJdIik7CisgIG93Xy0+RW5kT2JqZWN0KCk7Cit9CisKK1RFU1RfUChQcm90b1N0cmVhbU9iamVjdFdyaXRlckZpZWxkTWFza1Rlc3QsIE1hcEtleU11c3RFbmQpIHsKKyAgRVhQRUNUX0NBTEwoCisgICAgICBsaXN0ZW5lcl8sCisgICAgICBJbnZhbGlkVmFsdWUoXywKKyAgICAgICAgICAgICAgICAgICBTdHJpbmdQaWVjZSgidHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIiksCisgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UoIkZpZWxkICdzaW5nbGVfbWFzaycsIEludmFsaWQgRmllbGRNYXNrICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJ3BhdGgudG8ubWFwW1wia2V5MVwiJy4gTWFwIGtleXMgc2hvdWxkIGJlICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicmVwcmVzZW50ZWQgYXMgW1wic29tZV9rZXlcIl0uIikpKTsKKworICBvd18tPlN0YXJ0T2JqZWN0KCIiKTsKKyAgb3dfLT5SZW5kZXJTdHJpbmcoInNpbmdsZV9tYXNrIiwgInBhdGgudG8ubWFwW1wia2V5MVwiIik7CisgIG93Xy0+RW5kT2JqZWN0KCk7Cit9CisKK1RFU1RfUChQcm90b1N0cmVhbU9iamVjdFdyaXRlckZpZWxkTWFza1Rlc3QsIE1hcEtleU11c3RCZUVzY2FwZWRDb3JyZWN0bHkpIHsKKyAgRVhQRUNUX0NBTEwoCisgICAgICBsaXN0ZW5lcl8sCisgICAgICBJbnZhbGlkVmFsdWUoXywKKyAgICAgICAgICAgICAgICAgICBTdHJpbmdQaWVjZSgidHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIiksCisgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UoIkZpZWxkICdzaW5nbGVfbWFzaycsIEludmFsaWQgRmllbGRNYXNrICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJ3BhdGgudG8ubWFwW1wia2VcInkxXCJdJy4gTWFwIGtleXMgc2hvdWxkIGJlICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicmVwcmVzZW50ZWQgYXMgW1wic29tZV9rZXlcIl0uIikpKTsKKworICBvd18tPlN0YXJ0T2JqZWN0KCIiKTsKKyAgb3dfLT5SZW5kZXJTdHJpbmcoInNpbmdsZV9tYXNrIiwgInBhdGgudG8ubWFwW1wia2VcInkxXCJdIik7CisgIG93Xy0+RW5kT2JqZWN0KCk7Cit9CisKK1RFU1RfUChQcm90b1N0cmVhbU9iamVjdFdyaXRlckZpZWxkTWFza1Rlc3QsIE1hcEtleUNhbkNvbnRhaW5BbnlDaGFycykgeworICBGaWVsZE1hc2tUZXN0IGV4cGVjdGVkOworICBleHBlY3RlZC5tdXRhYmxlX3NpbmdsZV9tYXNrKCktPmFkZF9wYXRocygKKyAgICAgIC8vIFx4RTVceEFEXHg5OSBpcyB0aGUgVVRGLTggYnl0ZSBzZXF1ZW5jZSBmb3IgY2hpbmVzZSBjaGFyYWN0ZXIg5a2ZLgorICAgICAgLy8gV2UgY2Fubm90IGVtYmVkIG5vbi1BU0NJSSBjaGFyYWN0ZXJzIGluIHRoZSBjb2RlIGRpcmVjdGx5IGJlY2F1c2UKKyAgICAgIC8vIHNvbWUgd2luZG93cyBjb21waWxlcnMgd2lsbCB0cnkgdG8gaW50ZXJwcmV0IHRoZW0gdXNpbmcgdGhlIHN5c3RlbSdzCisgICAgICAvLyBjdXJyZW50IGVuY29kaW5nIGFuZCBlbmQgdXAgd2l0aCBpbnZhbGlkIFVURi04IGJ5dGUgc2VxdWVuY2UuCisgICAgICAicGF0aC50by5tYXBbXCIoKSxbXSxcXFwiJyFAIyQlXiYqMTIzX3xXYXJceEU1XHhBRFx4OTksLi8/PjxcXFxcXCJdIik7CisgIGV4cGVjdGVkLm11dGFibGVfc2luZ2xlX21hc2soKS0+YWRkX3BhdGhzKCJwYXRoLnRvLm1hcFtcImtleTJcIl0iKTsKKworICBvd18tPlN0YXJ0T2JqZWN0KCIiKTsKKyAgb3dfLT5SZW5kZXJTdHJpbmcoCisgICAgICAic2luZ2xlX21hc2siLAorICAgICAgInBhdGgudG8ubWFwW1wiKCksW10sXFxcIichQCMkJV4mKjEyM198V2FyXHhFNVx4QURceDk5LC4vPz48XFxcXFwiXSwiCisgICAgICAicGF0aC50by5tYXBbXCJrZXkyXCJdIik7CisgIG93Xy0+RW5kT2JqZWN0KCk7CisKKyAgQ2hlY2tPdXRwdXQoZXhwZWN0ZWQpOworfQorCitjbGFzcyBQcm90b1N0cmVhbU9iamVjdFdyaXRlck9uZU9mc1Rlc3QKKyAgICA6IHB1YmxpYyBCYXNlUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJUZXN0IHsKKyBwcm90ZWN0ZWQ6CisgIFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyT25lT2ZzVGVzdCgpIHsKKyAgICB2ZWN0b3I8Y29uc3QgRGVzY3JpcHRvcio+IGRlc2NyaXB0b3JzOworICAgIGRlc2NyaXB0b3JzLnB1c2hfYmFjayhPbmVPZnNSZXF1ZXN0OjpkZXNjcmlwdG9yKCkpOworICAgIGRlc2NyaXB0b3JzLnB1c2hfYmFjayhnb29nbGU6OnByb3RvYnVmOjpTdHJ1Y3Q6OmRlc2NyaXB0b3IoKSk7CisgICAgUmVzZXRUeXBlSW5mbyhkZXNjcmlwdG9ycyk7CisgIH0KK307CisKK0lOU1RBTlRJQVRFX1RFU1RfQ0FTRV9QKERpZmZlcmVudFR5cGVJbmZvU291cmNlVGVzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgIFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyT25lT2ZzVGVzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgIDo6dGVzdGluZzo6VmFsdWVzKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlc3Rpbmc6OlVTRV9UWVBFX1JFU09MVkVSKSk7CisKK1RFU1RfUChQcm90b1N0cmVhbU9iamVjdFdyaXRlck9uZU9mc1Rlc3QsCisgICAgICAgTXVsdGlwbGVPbmVvZnNGYWlsRm9yUHJpbWl0aXZlVHlwZXNUZXN0KSB7CisgIEVYUEVDVF9DQUxMKAorICAgICAgbGlzdGVuZXJfLAorICAgICAgSW52YWxpZFZhbHVlKAorICAgICAgICAgIF8sIFN0cmluZ1BpZWNlKCJvbmVvZiIpLAorICAgICAgICAgIFN0cmluZ1BpZWNlKAorICAgICAgICAgICAgICAib25lb2YgZmllbGQgJ2RhdGEnIGlzIGFscmVhZHkgc2V0LiBDYW5ub3Qgc2V0ICdpbnREYXRhJyIpKSk7CisKKyAgb3dfLT5TdGFydE9iamVjdCgiIik7CisgIG93Xy0+UmVuZGVyU3RyaW5nKCJzdHJEYXRhIiwgImJsYWgiKTsKKyAgb3dfLT5SZW5kZXJTdHJpbmcoImludERhdGEiLCAiMTIzIik7CisgIG93Xy0+RW5kT2JqZWN0KCk7Cit9CisKK1RFU1RfUChQcm90b1N0cmVhbU9iamVjdFdyaXRlck9uZU9mc1Rlc3QsCisgICAgICAgTXVsdGlwbGVPbmVvZnNGYWlsRm9yTWVzc2FnZVR5cGVzUHJpbWl0aXZlRmlyc3RUZXN0KSB7CisgIC8vIFRlc3QgZm9yIHNldHRpbmcgcHJpbWl0aXZlIG9uZW9mIGZpZWxkIGZpcnN0IGFuZCB0aGVuIG1lc3NhZ2UgZmllbGQuCisgIEVYUEVDVF9DQUxMKGxpc3RlbmVyXywKKyAgICAgICAgICAgICAgSW52YWxpZFZhbHVlKF8sIFN0cmluZ1BpZWNlKCJvbmVvZiIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UoIm9uZW9mIGZpZWxkICdkYXRhJyBpcyBhbHJlYWR5IHNldC4gIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNhbm5vdCBzZXQgJ21lc3NhZ2VEYXRhJyIpKSk7CisKKyAgLy8gSlNPTjogeyAic3RyRGF0YSI6ICJibGFoIiwgIm1lc3NhZ2VEYXRhIjogeyAiZGF0YVZhbHVlIjogMTIzIH0gfQorICBvd18tPlN0YXJ0T2JqZWN0KCIiKTsKKyAgb3dfLT5SZW5kZXJTdHJpbmcoInN0ckRhdGEiLCAiYmxhaCIpOworICBvd18tPlN0YXJ0T2JqZWN0KCJtZXNzYWdlRGF0YSIpOworICBvd18tPlJlbmRlckludDMyKCJkYXRhVmFsdWUiLCAxMjMpOworICBvd18tPkVuZE9iamVjdCgpOworICBvd18tPkVuZE9iamVjdCgpOworfQorCitURVNUX1AoUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJPbmVPZnNUZXN0LAorICAgICAgIE11bHRpcGxlT25lb2ZzRmFpbEZvck1lc3NhZ2VUeXBlc01lc3NhZ2VGaXJzdFRlc3QpIHsKKyAgLy8gVGVzdCBmb3Igc2V0dGluZyBtZXNzYWdlIG9uZW9mIGZpZWxkIGZpcnN0IGFuZCB0aGVuIHByaW1pdGl2ZSBmaWVsZC4KKyAgRVhQRUNUX0NBTEwobGlzdGVuZXJfLAorICAgICAgICAgICAgICBJbnZhbGlkVmFsdWUoXywgU3RyaW5nUGllY2UoIm9uZW9mIiksCisgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdQaWVjZSgib25lb2YgZmllbGQgJ2RhdGEnIGlzIGFscmVhZHkgc2V0LiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ2Fubm90IHNldCAnc3RyRGF0YSciKSkpOworCisgIC8vIEpTT046IHsgIm1lc3NhZ2VEYXRhIjogeyAiZGF0YVZhbHVlIjogMTIzIH0sICJzdHJEYXRhIjogImJsYWgiIH0KKyAgb3dfLT5TdGFydE9iamVjdCgiIik7CisgIG93Xy0+U3RhcnRPYmplY3QoIm1lc3NhZ2VEYXRhIik7CisgIG93Xy0+UmVuZGVySW50MzIoImRhdGFWYWx1ZSIsIDEyMyk7CisgIG93Xy0+RW5kT2JqZWN0KCk7CisgIG93Xy0+UmVuZGVyU3RyaW5nKCJzdHJEYXRhIiwgImJsYWgiKTsKKyAgb3dfLT5FbmRPYmplY3QoKTsKK30KKworVEVTVF9QKFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyT25lT2ZzVGVzdCwKKyAgICAgICBNdWx0aXBsZU9uZW9mc0ZhaWxGb3JTdHJ1Y3RUeXBlc1ByaW1pdGl2ZUZpcnN0VGVzdCkgeworICBFWFBFQ1RfQ0FMTChsaXN0ZW5lcl8sCisgICAgICAgICAgICAgIEludmFsaWRWYWx1ZShfLCBTdHJpbmdQaWVjZSgib25lb2YiKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1BpZWNlKCJvbmVvZiBmaWVsZCAnZGF0YScgaXMgYWxyZWFkeSBzZXQuICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDYW5ub3Qgc2V0ICdzdHJ1Y3REYXRhJyIpKSk7CisKKyAgLy8gSlNPTjogeyAic3RyRGF0YSI6ICJibGFoIiwgInN0cnVjdERhdGEiOiB7ICJhIjogImIiIH0gfQorICBvd18tPlN0YXJ0T2JqZWN0KCIiKTsKKyAgb3dfLT5SZW5kZXJTdHJpbmcoInN0ckRhdGEiLCAiYmxhaCIpOworICBvd18tPlN0YXJ0T2JqZWN0KCJzdHJ1Y3REYXRhIik7CisgIG93Xy0+UmVuZGVyU3RyaW5nKCJhIiwgImIiKTsKKyAgb3dfLT5FbmRPYmplY3QoKTsKKyAgb3dfLT5FbmRPYmplY3QoKTsKK30KKworVEVTVF9QKFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyT25lT2ZzVGVzdCwKKyAgICAgICBNdWx0aXBsZU9uZW9mc0ZhaWxGb3JTdHJ1Y3RUeXBlc1N0cnVjdEZpcnN0VGVzdCkgeworICBFWFBFQ1RfQ0FMTChsaXN0ZW5lcl8sCisgICAgICAgICAgICAgIEludmFsaWRWYWx1ZShfLCBTdHJpbmdQaWVjZSgib25lb2YiKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1BpZWNlKCJvbmVvZiBmaWVsZCAnZGF0YScgaXMgYWxyZWFkeSBzZXQuICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDYW5ub3Qgc2V0ICdzdHJEYXRhJyIpKSk7CisKKyAgLy8gSlNPTjogeyAic3RydWN0RGF0YSI6IHsgImEiOiAiYiIgfSwgInN0ckRhdGEiOiAiYmxhaCIgfQorICBvd18tPlN0YXJ0T2JqZWN0KCIiKTsKKyAgb3dfLT5TdGFydE9iamVjdCgic3RydWN0RGF0YSIpOworICBvd18tPlJlbmRlclN0cmluZygiYSIsICJiIik7CisgIG93Xy0+RW5kT2JqZWN0KCk7CisgIG93Xy0+UmVuZGVyU3RyaW5nKCJzdHJEYXRhIiwgImJsYWgiKTsKKyAgb3dfLT5FbmRPYmplY3QoKTsKK30KKworVEVTVF9QKFByb3RvU3RyZWFtT2JqZWN0V3JpdGVyT25lT2ZzVGVzdCwKKyAgICAgICBNdWx0aXBsZU9uZW9mc0ZhaWxGb3JTdHJ1Y3RWYWx1ZVR5cGVzVGVzdCkgeworICBFWFBFQ1RfQ0FMTChsaXN0ZW5lcl8sCisgICAgICAgICAgICAgIEludmFsaWRWYWx1ZShfLCBTdHJpbmdQaWVjZSgib25lb2YiKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1BpZWNlKCJvbmVvZiBmaWVsZCAnZGF0YScgaXMgYWxyZWFkeSBzZXQuICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDYW5ub3Qgc2V0ICd2YWx1ZURhdGEnIikpKTsKKworICAvLyBKU09OOiB7ICJtZXNzYWdlRGF0YSI6IHsgImRhdGFWYWx1ZSI6IDEyMyB9LCAidmFsdWVEYXRhIjogeyAiYSI6ICJiIiB9IH0KKyAgb3dfLT5TdGFydE9iamVjdCgiIik7CisgIG93Xy0+U3RhcnRPYmplY3QoIm1lc3NhZ2VEYXRhIik7CisgIG93Xy0+UmVuZGVySW50MzIoImRhdGFWYWx1ZSIsIDEyMyk7CisgIG93Xy0+RW5kT2JqZWN0KCk7CisgIG93Xy0+U3RhcnRPYmplY3QoInZhbHVlRGF0YSIpOworICBvd18tPlJlbmRlclN0cmluZygiYSIsICJiIik7CisgIG93Xy0+RW5kT2JqZWN0KCk7CisgIG93Xy0+RW5kT2JqZWN0KCk7Cit9CisKK1RFU1RfUChQcm90b1N0cmVhbU9iamVjdFdyaXRlck9uZU9mc1Rlc3QsCisgICAgICAgTXVsdGlwbGVPbmVvZnNGYWlsRm9yV2VsbEtub3duVHlwZXNQcmltaXRpdmVGaXJzdFRlc3QpIHsKKyAgRVhQRUNUX0NBTEwobGlzdGVuZXJfLAorICAgICAgICAgICAgICBJbnZhbGlkVmFsdWUoXywgU3RyaW5nUGllY2UoIm9uZW9mIiksCisgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdQaWVjZSgib25lb2YgZmllbGQgJ2RhdGEnIGlzIGFscmVhZHkgc2V0LiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ2Fubm90IHNldCAndHNEYXRhJyIpKSk7CisKKyAgLy8gSlNPTjogeyAiaW50RGF0YSI6IDEyMywgInRzRGF0YSI6ICIxOTcwLTAxLTAyVDAxOjAwOjAwLjAwMFoiIH0KKyAgb3dfLT5TdGFydE9iamVjdCgiIik7CisgIG93Xy0+UmVuZGVySW50MzIoImludERhdGEiLCAxMjMpOworICBvd18tPlJlbmRlclN0cmluZygidHNEYXRhIiwgIjE5NzAtMDEtMDJUMDE6MDA6MDAuMDAwWiIpOworICBvd18tPkVuZE9iamVjdCgpOworfQorCitURVNUX1AoUHJvdG9TdHJlYW1PYmplY3RXcml0ZXJPbmVPZnNUZXN0LAorICAgICAgIE11bHRpcGxlT25lb2ZzRmFpbEZvcldlbGxLbm93blR5cGVzV2t0Rmlyc3RUZXN0KSB7CisgIEVYUEVDVF9DQUxMKGxpc3RlbmVyXywKKyAgICAgICAgICAgICAgSW52YWxpZFZhbHVlKF8sIFN0cmluZ1BpZWNlKCJvbmVvZiIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UoIm9uZW9mIGZpZWxkICdkYXRhJyBpcyBhbHJlYWR5IHNldC4gIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNhbm5vdCBzZXQgJ2ludERhdGEnIikpKTsKKworICAvLyBKU09OOiB7ICJ0c0RhdGEiOiAiMTk3MC0wMS0wMlQwMTowMDowMC4wMDBaIiwgImludERhdGEiOiAxMjMgfQorICBvd18tPlN0YXJ0T2JqZWN0KCIiKTsKKyAgb3dfLT5SZW5kZXJTdHJpbmcoInRzRGF0YSIsICIxOTcwLTAxLTAyVDAxOjAwOjAwLjAwMFoiKTsKKyAgb3dfLT5SZW5kZXJJbnQzMigiaW50RGF0YSIsIDEyMyk7CisgIG93Xy0+RW5kT2JqZWN0KCk7Cit9CisKK1RFU1RfUChQcm90b1N0cmVhbU9iamVjdFdyaXRlck9uZU9mc1Rlc3QsCisgICAgICAgTXVsdGlwbGVPbmVvZnNGYWlsRm9yV2VsbEtub3duVHlwZXNBbmRNZXNzYWdlVGVzdCkgeworICBFWFBFQ1RfQ0FMTChsaXN0ZW5lcl8sCisgICAgICAgICAgICAgIEludmFsaWRWYWx1ZShfLCBTdHJpbmdQaWVjZSgib25lb2YiKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1BpZWNlKCJvbmVvZiBmaWVsZCAnZGF0YScgaXMgYWxyZWFkeSBzZXQuICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDYW5ub3Qgc2V0ICdtZXNzYWdlRGF0YSciKSkpOworCisgIC8vIEpTT046IHsgInRzRGF0YSI6ICIxOTcwLTAxLTAyVDAxOjAwOjAwLjAwMFoiLAorICAvLyAgICAgICAgICJtZXNzYWdlRGF0YSI6IHsgImRhdGFWYWx1ZSI6IDEyMyB9IH0KKyAgb3dfLT5TdGFydE9iamVjdCgiIik7CisgIG93Xy0+UmVuZGVyU3RyaW5nKCJ0c0RhdGEiLCAiMTk3MC0wMS0wMlQwMTowMDowMC4wMDBaIik7CisgIG93Xy0+U3RhcnRPYmplY3QoIm1lc3NhZ2VEYXRhIik7CisgIG93Xy0+UmVuZGVySW50MzIoImRhdGFWYWx1ZSIsIDEyMyk7CisgIG93Xy0+RW5kT2JqZWN0KCk7CisgIG93Xy0+RW5kT2JqZWN0KCk7Cit9CisKK1RFU1RfUChQcm90b1N0cmVhbU9iamVjdFdyaXRlck9uZU9mc1Rlc3QsCisgICAgICAgTXVsdGlwbGVPbmVvZnNGYWlsRm9yT25lb2ZXaXRoaW5BbnlUZXN0KSB7CisgIEVYUEVDVF9DQUxMKGxpc3RlbmVyXywKKyAgICAgICAgICAgICAgSW52YWxpZFZhbHVlKF8sIFN0cmluZ1BpZWNlKCJvbmVvZiIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nUGllY2UoIm9uZW9mIGZpZWxkICdkYXRhJyBpcyBhbHJlYWR5IHNldC4gIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNhbm5vdCBzZXQgJ2ludERhdGEnIikpKTsKKworICB1c2luZyBnb29nbGU6OnByb3RvYnVmOjp0ZXN0aW5nOjpvbmVvZnM6Ok9uZU9mc1JlcXVlc3Q7CisgIC8vIEpTT046CisgIC8vIHsgImFueURhdGEiOgorICAvLyAgICB7ICJAdHlwZSI6CisgIC8vICAgICAgICJ0eXBlLmdvb2dsZWFwaXMuY29tL2dvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLm9uZW9mcy5PbmVPZnNSZXF1ZXN0IiwKKyAgLy8gICAgICJzdHJEYXRhIjogImJsYWgiLAorICAvLyAgICAgImludERhdGEiOiAxMjMKKyAgLy8gICAgfQorICAvLyB9CisgIG93Xy0+U3RhcnRPYmplY3QoIiIpOworICBvd18tPlN0YXJ0T2JqZWN0KCJhbnlEYXRhIik7CisgIG93Xy0+UmVuZGVyU3RyaW5nKAorICAgICAgIkB0eXBlIiwKKyAgICAgICJ0eXBlLmdvb2dsZWFwaXMuY29tL2dvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLm9uZW9mcy5PbmVPZnNSZXF1ZXN0Iik7CisgIG93Xy0+UmVuZGVyU3RyaW5nKCJzdHJEYXRhIiwgImJsYWgiKTsKKyAgb3dfLT5SZW5kZXJJbnQzMigiaW50RGF0YSIsIDEyMyk7CisgIG93Xy0+RW5kT2JqZWN0KCk7CisgIG93Xy0+RW5kT2JqZWN0KCk7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBjb252ZXJ0ZXIKK30gIC8vIG5hbWVzcGFjZSB1dGlsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9zdHJ1Y3R1cmVkX29iamVjdHdyaXRlci5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3N0cnVjdHVyZWRfb2JqZWN0d3JpdGVyLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2YwNjVkNgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9zdHJ1Y3R1cmVkX29iamVjdHdyaXRlci5oCkBAIC0wLDAgKzEsMTE4IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2lmbmRlZiBHT09HTEVfUFJPVE9CVUZfVVRJTF9DT05WRVJURVJfU1RSVUNUVVJFRF9PQkpFQ1RXUklURVJfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9VVElMX0NPTlZFUlRFUl9TVFJVQ1RVUkVEX09CSkVDVFdSSVRFUl9IX18KKworI2luY2x1ZGUgPG1lbW9yeT4KKyNpZm5kZWYgX1NIQVJFRF9QVFJfSAorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaGFyZWRfcHRyLmg+CisjZW5kaWYKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jYXN0cy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9vYmplY3Rfd3JpdGVyLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSB1dGlsIHsKK25hbWVzcGFjZSBjb252ZXJ0ZXIgeworCisvLyBBbiBTdHJ1Y3R1cmVkT2JqZWN0V3JpdGVyIGlzIGFuIE9iamVjdFdyaXRlciBmb3Igd3JpdGluZworLy8gdHJlZS1zdHJ1Y3R1cmVkIGRhdGEgaW4gYSBzdHJlYW0gb2YgZXZlbnRzIHJlcHJlc2VudGluZyBvYmplY3RzCisvLyBhbmQgY29sbGVjdGlvbnMuIEltcGxlbWVudGF0aW9uIG9mIHRoaXMgaW50ZXJmYWNlIGNhbiBiZSB1c2VkIHRvCisvLyB3cml0ZSBhbiBvYmplY3Qgc3RyZWFtIHRvIGFuIGluLW1lbW9yeSBzdHJ1Y3R1cmUsIHByb3RvYnVmcywKKy8vIEpTT04sIFhNTCwgb3IgYW55IG90aGVyIG91dHB1dCBmb3JtYXQgZGVzaXJlZC4gVGhlIE9iamVjdFNvdXJjZQorLy8gaW50ZXJmYWNlIGlzIHR5cGljYWxseSB1c2VkIGFzIHRoZSBzb3VyY2Ugb2YgYW4gb2JqZWN0IHN0cmVhbS4KKy8vCisvLyBTZWUgSnNvbk9iamVjdFdyaXRlciBmb3IgYSBzYW1wbGUgaW1wbGVtZW50YXRpb24gb2YKKy8vIFN0cnVjdHVyZWRPYmplY3RXcml0ZXIgYW5kIGl0cyB1c2UuCisvLworLy8gRGVyaXZlZCBjbGFzc2VzIGNvdWxkIGJlIHRocmVhZC11bnNhZmUuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgU3RydWN0dXJlZE9iamVjdFdyaXRlciA6IHB1YmxpYyBPYmplY3RXcml0ZXIgeworIHB1YmxpYzoKKyAgdmlydHVhbCB+U3RydWN0dXJlZE9iamVjdFdyaXRlcigpIHt9CisKKyBwcm90ZWN0ZWQ6CisgIC8vIEEgYmFzZSBlbGVtZW50IGNsYXNzIGZvciBzdWJjbGFzc2VzIHRvIGV4dGVuZCwgbWFrZXMgdHJhY2tpbmcgc3RhdGUgZWFzaWVyLgorICAvLworICAvLyBTdHJ1Y3R1cmVkT2JqZWN0V3JpdGVyIGJlaGF2ZXMgYXMgYSB2aXNpdG9yLiBCYXNlRWxlbWVudCByZXByZXNlbnRzIGEgbm9kZQorICAvLyBpbiB0aGUgaW5wdXQgdHJlZS4gSW1wbGVtZW50YXRpb24gb2YgU3RydWN0dXJlZE9iamVjdFdyaXRlciBzaG91bGQgYWxzbworICAvLyBleHRlbmQgQmFzZUVsZW1lbnQgdG8ga2VlcCB0cmFjayBvZiB0aGUgbG9jYXRpb24gaW4gdGhlIGlucHV0IHRyZWUuCisgIGNsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBCYXNlRWxlbWVudCB7CisgICBwdWJsaWM6CisgICAgLy8gVGFrZXMgb3duZXJzaGlwIG9mIHRoZSBwYXJlbnQgRWxlbWVudC4KKyAgICBleHBsaWNpdCBCYXNlRWxlbWVudChCYXNlRWxlbWVudCogcGFyZW50KQorICAgICAgICA6IHBhcmVudF8ocGFyZW50KSwgbGV2ZWxfKHBhcmVudCA9PSBOVUxMID8gMCA6IHBhcmVudC0+bGV2ZWwoKSArIDEpIHt9CisgICAgdmlydHVhbCB+QmFzZUVsZW1lbnQoKSB7fQorCisgICAgLy8gUmVsZWFzZXMgb3duZXJzaGlwIG9mIHRoZSBwYXJlbnQgYW5kIHJldHVybnMgYSBwb2ludGVyIHRvIGl0LgorICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBFbGVtZW50VHlwZT4KKyAgICBFbGVtZW50VHlwZSogcG9wKCkgeworICAgICAgcmV0dXJuIGRvd25fY2FzdDxFbGVtZW50VHlwZSo+KHBhcmVudF8ucmVsZWFzZSgpKTsKKyAgICB9CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgdGhpcyBlbGVtZW50IGlzIHRoZSByb290LgorICAgIGJvb2wgaXNfcm9vdCgpIGNvbnN0IHsgcmV0dXJuIHBhcmVudF8gPT0gTlVMTDsgfQorCisgICAgLy8gUmV0dXJucyB0aGUgbnVtYmVyIG9mIGhvcHMgZnJvbSB0aGlzIGVsZW1lbnQgdG8gdGhlIHJvb3QgZWxlbWVudC4KKyAgICBpbnQgbGV2ZWwoKSBjb25zdCB7IHJldHVybiBsZXZlbF87IH0KKworICAgcHJvdGVjdGVkOgorICAgIC8vIFJldHVybnMgcG9pbnRlciB0byBwYXJlbnQgZWxlbWVudCB3aXRob3V0IHJlbGVhc2luZyBvd25lcnNoaXAuCisgICAgdmlydHVhbCBCYXNlRWxlbWVudCogcGFyZW50KCkgY29uc3QgeyByZXR1cm4gcGFyZW50Xy5nZXQoKTsgfQorCisgICBwcml2YXRlOgorICAgIC8vIFBvaW50ZXIgdG8gdGhlIHBhcmVudCBFbGVtZW50LgorICAgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8QmFzZUVsZW1lbnQ+IHBhcmVudF87CisKKyAgICAvLyBOdW1iZXIgb2YgaG9wcyB0byB0aGUgcm9vdCBFbGVtZW50LgorICAgIC8vIFRoZSByb290IEVsZW1lbnQgaGFzIE5VTEwgcGFyZW50XyBhbmQgYSBsZXZlbF8gb2YgMC4KKyAgICBjb25zdCBpbnQgbGV2ZWxfOworCisgICAgR09PR0xFX0RJU0FMTE9XX0lNUExJQ0lUX0NPTlNUUlVDVE9SUyhCYXNlRWxlbWVudCk7CisgIH07CisKKyAgU3RydWN0dXJlZE9iamVjdFdyaXRlcigpIHt9CisKKyAgLy8gUmV0dXJucyB0aGUgY3VycmVudCBlbGVtZW50LiBVc2VkIGZvciBpbmRlbnRhdGlvbiBhbmQgbmFtZSBvdmVycmlkZXMuCisgIHZpcnR1YWwgQmFzZUVsZW1lbnQqIGVsZW1lbnQoKSA9IDA7CisKKyBwcml2YXRlOgorICAvLyBEbyBub3QgYWRkIGFueSBkYXRhIG1lbWJlcnMgdG8gdGhpcyBjbGFzcy4KKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFN0cnVjdHVyZWRPYmplY3RXcml0ZXIpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIGNvbnZlcnRlcgorfSAgLy8gbmFtZXNwYWNlIHV0aWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9VVElMX0NPTlZFUlRFUl9TVFJVQ1RVUkVEX09CSkVDVFdSSVRFUl9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90ZXN0ZGF0YS9hbnlzLnByb3RvIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3Rlc3RkYXRhL2FueXMucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMThjNTljYgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90ZXN0ZGF0YS9hbnlzLnByb3RvCkBAIC0wLDAgKzEsNTMgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBQcm90byB0byB0ZXN0IFByb3RvMyBBbnkgc2VyaWFsaXphdGlvbi4KK3N5bnRheCA9ICJwcm90bzMiOworCitwYWNrYWdlIGdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLmFueXM7CitvcHRpb24gamF2YV9wYWNrYWdlID0gImNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5hbnlzIjsKKworaW1wb3J0ICJnb29nbGUvcHJvdG9idWYvYW55LnByb3RvIjsKKworbWVzc2FnZSBBbnlJbiB7CisgIHN0cmluZyBzb21ldGhpbmcgPSAxOworfQorCittZXNzYWdlIEFueU91dCB7CisgIGdvb2dsZS5wcm90b2J1Zi5BbnkgYW55ID0gMTsKK30KKworbWVzc2FnZSBBbnlNIHsKKyAgc3RyaW5nIGZvbyA9IDE7Cit9CisKK3NlcnZpY2UgVGVzdFNlcnZpY2UgeworICBycGMgQ2FsbChBbnlJbikgcmV0dXJucyAoQW55T3V0KTsKK30KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90ZXN0ZGF0YS9ib29rcy5wcm90byBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90ZXN0ZGF0YS9ib29rcy5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MmI4MTc2Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3Rlc3RkYXRhL2Jvb2tzLnByb3RvCkBAIC0wLDAgKzEsMTcxIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBzdmVuQGdvb2dsZS5jb20gKFN2ZW4gTWF3c29uKQorLy8KKy8vIFNhbXBsZSBwcm90b3MgZm9yIHRlc3RpbmcuCitzeW50YXggPSAicHJvdG8yIjsKKworcGFja2FnZSBnb29nbGUucHJvdG9idWYudGVzdGluZzsKKworLy8gQSBib29rCittZXNzYWdlIEJvb2sgeworICBvcHRpb25hbCBzdHJpbmcgdGl0bGUgPSAxOworICBvcHRpb25hbCBBdXRob3IgYXV0aG9yID0gMjsKKyAgb3B0aW9uYWwgdWludDMyIGxlbmd0aCA9IDM7CisgIG9wdGlvbmFsIGludDY0IHB1Ymxpc2hlZCA9IDQ7CisgIG9wdGlvbmFsIGJ5dGVzIGNvbnRlbnQgPSA1OworCisgIG9wdGlvbmFsIGdyb3VwIERhdGEgPSA2IHsKKyAgICBvcHRpb25hbCB1aW50MzIgeWVhciA9IDc7CisgICAgb3B0aW9uYWwgc3RyaW5nIGNvcHlyaWdodCA9IDg7CisgIH0KKworICBtZXNzYWdlIExhYmVsIHsKKyAgICBvcHRpb25hbCBzdHJpbmcga2V5ID0gMTsKKyAgICBvcHRpb25hbCBzdHJpbmcgdmFsdWUgPSAyOworICB9CisKKyAgb3B0aW9uYWwgUHVibGlzaGVyIHB1Ymxpc2hlciA9IDk7CisgIHJlcGVhdGVkIExhYmVsIGxhYmVscyA9IDEwOworCisgIGV4dGVuc2lvbnMgMjAwIHRvIDQ5OTsKK30KKworLy8gQSBwdWJsaXNoZXIgb2YgYSBib29rLCB0ZXN0cyByZXF1aXJlZCBmaWVsZHMuCittZXNzYWdlIFB1Ymxpc2hlciB7CisgIHJlcXVpcmVkIHN0cmluZyBuYW1lID0gMTsKK30KKworLy8gQW4gYXV0aG9yIG9mIGEgYm9vaworbWVzc2FnZSBBdXRob3IgeworICBvcHRpb25hbCB1aW50NjQgaWQgPSAxIFtqc29uX25hbWUgPSAiQGlkIl07CisgIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMjsKKyAgcmVwZWF0ZWQgc3RyaW5nIHBzZXVkb255bSA9IDM7CisgIG9wdGlvbmFsIGJvb2wgYWxpdmUgPSA0OworICByZXBlYXRlZCBBdXRob3IgZnJpZW5kID0gNTsKK30KKworLy8gRm9yIHRlc3RpbmcgcmVzaWxpZW5jeSBvZiBvdXIgcHJvdG9zdHJlYW0gcGFyc2VyLgorLy8gRmllbGQgbnVtYmVycyBvZiBBdXRob3IgYXJlIHJldXNlZCBmb3Igc29tZXRoaW5nIGVsc2UuCittZXNzYWdlIEJhZEF1dGhvciB7CisgIG9wdGlvbmFsIHN0cmluZyBpZCA9IDE7ICAvLyBub24tbGVuZ3RoLWRlbGltaXRlZCB0byBsZW5ndGgtZGVsaW1pdGVkLgorICByZXBlYXRlZCB1aW50NjQgbmFtZSA9IDI7ICAvLyBzdHJpbmcgdG8gcmVwZWF0ZWQgKGJvdGggbGVuZ3RoLWRlbGltaXRlZCkuCisgIG9wdGlvbmFsIHN0cmluZyBwc2V1ZG9ueW0gPSAzOyAgLy8gUmVwZWF0ZWQgdG8gb3B0aW9uYWwuCisgIHJlcGVhdGVkIGJvb2wgYWxpdmUgPSA0IFtwYWNrZWQ9dHJ1ZV07ICAvLyBPcHRpb25hbCB0byByZXBlYXRlZC4KK30KKworLy8gQWxsIHByaW1pdGl2ZSB0eXBlcworbWVzc2FnZSBQcmltaXRpdmUgeworICAvLyAzMiBiaXQgbnVtYmVyczoKKyAgb3B0aW9uYWwgZml4ZWQzMiBmaXgzMiA9IDE7CisgIG9wdGlvbmFsIHVpbnQzMiB1MzIgPSAyOworICBvcHRpb25hbCBpbnQzMiBpMzIgPSAzOworICBvcHRpb25hbCBzZml4ZWQzMiBzZjMyID0gNDsKKyAgb3B0aW9uYWwgc2ludDMyIHMzMiA9IDU7CisKKyAgLy8gNjQgYml0IG51bWJlcnM6CisgIG9wdGlvbmFsIGZpeGVkNjQgZml4NjQgPSA2OworICBvcHRpb25hbCB1aW50NjQgdTY0ID0gNzsKKyAgb3B0aW9uYWwgaW50NjQgaTY0ID0gODsKKyAgb3B0aW9uYWwgc2ZpeGVkNjQgc2Y2NCA9IDk7CisgIG9wdGlvbmFsIHNpbnQ2NCBzNjQgPSAxMDsKKworICAvLyBUaGUgb3RoZXIgc3R1ZmYuCisgIG9wdGlvbmFsIHN0cmluZyBzdHIgPSAxMTsKKyAgb3B0aW9uYWwgYnl0ZXMgYnl0ZXMgPSAxMjsKKyAgb3B0aW9uYWwgZmxvYXQgZmxvYXQgPSAxMzsKKyAgb3B0aW9uYWwgZG91YmxlIGRvdWJsZSA9IDE0OworICBvcHRpb25hbCBib29sIGJvb2wgPSAxNTsKKworICAvLyByZXBlYXRlZCAzMiBiaXQgbnVtYmVyczoKKyAgcmVwZWF0ZWQgZml4ZWQzMiByZXBfZml4MzIgPSAxNjsKKyAgcmVwZWF0ZWQgdWludDMyIHJlcF91MzIgPSAxNzsKKyAgcmVwZWF0ZWQgaW50MzIgcmVwX2kzMiA9IDE4OworICByZXBlYXRlZCBzZml4ZWQzMiByZXBfc2YzMiA9IDE5OworICByZXBlYXRlZCBzaW50MzIgcmVwX3MzMiA9IDIwOworCisgIC8vIHJlcGVhdGVkIDY0IGJpdCBudW1iZXJzOgorICByZXBlYXRlZCBmaXhlZDY0IHJlcF9maXg2NCA9IDIxOworICByZXBlYXRlZCB1aW50NjQgcmVwX3U2NCA9IDIyOworICByZXBlYXRlZCBpbnQ2NCByZXBfaTY0ID0gMjM7CisgIHJlcGVhdGVkIHNmaXhlZDY0IHJlcF9zZjY0ID0gMjQ7CisgIHJlcGVhdGVkIHNpbnQ2NCByZXBfczY0ID0gMjU7CisKKyAgLy8gcmVwZWF0ZWQgb3RoZXIgc3R1ZmY6CisgIHJlcGVhdGVkIHN0cmluZyByZXBfc3RyID0gMjY7CisgIHJlcGVhdGVkIGJ5dGVzIHJlcF9ieXRlcyA9IDI3OworICByZXBlYXRlZCBmbG9hdCByZXBfZmxvYXQgPSAyODsKKyAgcmVwZWF0ZWQgZG91YmxlIHJlcF9kb3VibGUgPSAyOTsKKyAgcmVwZWF0ZWQgYm9vbCByZXBfYm9vbCA9IDMwOworfQorCisvLyBUZXN0IHBhY2tlZCB2ZXJzaW9ucyBvZiBhbGwgcmVwZWF0ZWQgcHJpbWl0aXZlcy4KKy8vIFRoZSBmaWVsZCBudW1iZXJzIHNob3VsZCBtYXRjaCB0aGVpciBub24tcGFja2VkIHZlcnNpb24gaW4gUHJpbWl0aXZlIG1lc3NhZ2UuCittZXNzYWdlIFBhY2tlZFByaW1pdGl2ZSB7CisgIC8vIHJlcGVhdGVkIDMyIGJpdCBudW1iZXJzOgorICByZXBlYXRlZCBmaXhlZDMyIHJlcF9maXgzMiA9IDE2IFtwYWNrZWQ9dHJ1ZV07CisgIHJlcGVhdGVkIHVpbnQzMiByZXBfdTMyID0gMTcgW3BhY2tlZD10cnVlXTsKKyAgcmVwZWF0ZWQgaW50MzIgcmVwX2kzMiA9IDE4IFtwYWNrZWQ9dHJ1ZV07CisgIHJlcGVhdGVkIHNmaXhlZDMyIHJlcF9zZjMyID0gMTkgW3BhY2tlZD10cnVlXTsKKyAgcmVwZWF0ZWQgc2ludDMyIHJlcF9zMzIgPSAyMCBbcGFja2VkPXRydWVdOworCisgIC8vIHJlcGVhdGVkIDY0IGJpdCBudW1iZXJzOgorICByZXBlYXRlZCBmaXhlZDY0IHJlcF9maXg2NCA9IDIxIFtwYWNrZWQ9dHJ1ZV07CisgIHJlcGVhdGVkIHVpbnQ2NCByZXBfdTY0ID0gMjIgW3BhY2tlZD10cnVlXTsKKyAgcmVwZWF0ZWQgaW50NjQgcmVwX2k2NCA9IDIzIFtwYWNrZWQ9dHJ1ZV07CisgIHJlcGVhdGVkIHNmaXhlZDY0IHJlcF9zZjY0ID0gMjQgW3BhY2tlZD10cnVlXTsKKyAgcmVwZWF0ZWQgc2ludDY0IHJlcF9zNjQgPSAyNSBbcGFja2VkPXRydWVdOworCisgIC8vIHJlcGVhdGVkIG90aGVyIHN0dWZmOgorICByZXBlYXRlZCBmbG9hdCByZXBfZmxvYXQgPSAyOCBbcGFja2VkPXRydWVdOworICByZXBlYXRlZCBkb3VibGUgcmVwX2RvdWJsZSA9IDI5IFtwYWNrZWQ9dHJ1ZV07CisgIHJlcGVhdGVkIGJvb2wgcmVwX2Jvb2wgPSAzMCBbcGFja2VkPXRydWVdOworfQorCisvLyBUZXN0IGV4dGVuc2lvbnMuCitleHRlbmQgQm9vayB7CisgIHJlcGVhdGVkIEF1dGhvciBtb3JlX2F1dGhvciA9IDIwMTsKK30KKworLy8gVGVzdCBuZXN0ZWQgZXh0ZW5zaW9ucy4KK21lc3NhZ2UgTmVzdGVkQm9vayB7CisgIGV4dGVuZCBCb29rIHsKKyAgICBvcHRpb25hbCBOZXN0ZWRCb29rIGFub3RoZXJfYm9vayA9IDMwMTsKKyAgfQorICAvLyBSZWN1cnNlCisgIG9wdGlvbmFsIEJvb2sgYm9vayA9IDE7Cit9CisKKy8vIEZvciB0ZXN0aW5nIHJlc2lsaWVuY3kgb2Ygb3VyIHByb3Rvc3RyZWFtIHBhcnNlci4KKy8vIEZpZWxkIG51bWJlciBvZiBOZXN0ZWRCb29rIGlzIHJldXNlZCBmb3Igc29tZXRoaW5nIGVsc2UuCittZXNzYWdlIEJhZE5lc3RlZEJvb2sgeworICByZXBlYXRlZCB1aW50MzIgYm9vayA9IDEgW3BhY2tlZD10cnVlXTsgIC8vIFBhY2tlZCB0byBvcHRpb25hbCBtZXNzYWdlLgorfQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3Rlc3RkYXRhL2RlZmF1bHRfdmFsdWUucHJvdG8gYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvdGVzdGRhdGEvZGVmYXVsdF92YWx1ZS5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jY2NjNzQxCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3Rlc3RkYXRhL2RlZmF1bHRfdmFsdWUucHJvdG8KQEAgLTAsMCArMSwxNzAgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitzeW50YXggPSAicHJvdG8zIjsKKworcGFja2FnZSBnb29nbGUucHJvdG9idWYudGVzdGluZzsKKworaW1wb3J0ICJnb29nbGUvcHJvdG9idWYvYW55LnByb3RvIjsKK2ltcG9ydCAiZ29vZ2xlL3Byb3RvYnVmL3N0cnVjdC5wcm90byI7CitpbXBvcnQgImdvb2dsZS9wcm90b2J1Zi93cmFwcGVycy5wcm90byI7CisKK21lc3NhZ2UgRGVmYXVsdFZhbHVlVGVzdENhc2VzIHsKKyAgRG91YmxlTWVzc2FnZSBlbXB0eV9kb3VibGUgPSAxOworICBEb3VibGVNZXNzYWdlIGRvdWJsZV93aXRoX2RlZmF1bHRfdmFsdWUgPSAyOworICBEb3VibGVNZXNzYWdlIGRvdWJsZV93aXRoX25vbmRlZmF1bHRfdmFsdWUgPSAzOworICBEb3VibGVNZXNzYWdlIHJlcGVhdGVkX2RvdWJsZSA9IDQ7CisgIERvdWJsZU1lc3NhZ2UgbmVzdGVkX21lc3NhZ2UgPSA1OworICBEb3VibGVNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNjsKKyAgRG91YmxlTWVzc2FnZSBkb3VibGVfbWVzc2FnZV93aXRoX29uZW9mID0gNzsKKyAgU3RydWN0TWVzc2FnZSBlbXB0eV9zdHJ1Y3QgPSAyMDE7CisgIFN0cnVjdE1lc3NhZ2UgZW1wdHlfc3RydWN0MiA9IDIwMjsKKyAgU3RydWN0TWVzc2FnZSBzdHJ1Y3Rfd2l0aF9udWxsX3ZhbHVlID0gMjAzOworICBTdHJ1Y3RNZXNzYWdlIHN0cnVjdF93aXRoX3ZhbHVlcyA9IDIwNDsKKyAgU3RydWN0TWVzc2FnZSBzdHJ1Y3Rfd2l0aF9uZXN0ZWRfc3RydWN0ID0gMjA1OworICBTdHJ1Y3RNZXNzYWdlIHN0cnVjdF93aXRoX25lc3RlZF9saXN0ID0gMjA2OworICBTdHJ1Y3RNZXNzYWdlIHN0cnVjdF93aXRoX2xpc3Rfb2ZfbnVsbHMgPSAyMDc7CisgIFN0cnVjdE1lc3NhZ2Ugc3RydWN0X3dpdGhfbGlzdF9vZl9saXN0cyA9IDIwODsKKyAgU3RydWN0TWVzc2FnZSBzdHJ1Y3Rfd2l0aF9saXN0X29mX3N0cnVjdHMgPSAyMDk7CisgIGdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QgdG9wX2xldmVsX3N0cnVjdCA9IDIxMDsKKyAgVmFsdWVNZXNzYWdlIHZhbHVlX3dyYXBwZXJfc2ltcGxlID0gMjEyOworICBWYWx1ZU1lc3NhZ2UgdmFsdWVfd3JhcHBlcl93aXRoX3N0cnVjdCA9IDIxMzsKKyAgVmFsdWVNZXNzYWdlIHZhbHVlX3dyYXBwZXJfd2l0aF9saXN0ID0gMjE0OworICBMaXN0VmFsdWVNZXNzYWdlIGxpc3RfdmFsdWVfd3JhcHBlciA9IDIxNTsKKyAgZ29vZ2xlLnByb3RvYnVmLlZhbHVlIHRvcF9sZXZlbF92YWx1ZV9zaW1wbGUgPSAyMTY7CisgIGdvb2dsZS5wcm90b2J1Zi5WYWx1ZSB0b3BfbGV2ZWxfdmFsdWVfd2l0aF9zdHJ1Y3QgPSAyMTc7CisgIGdvb2dsZS5wcm90b2J1Zi5WYWx1ZSB0b3BfbGV2ZWxfdmFsdWVfd2l0aF9saXN0ID0gMjE4OworICBnb29nbGUucHJvdG9idWYuTGlzdFZhbHVlIHRvcF9sZXZlbF9saXN0dmFsdWUgPSAyMTk7CisgIEFueU1lc3NhZ2UgZW1wdHlfYW55ID0gMzAxOworICBBbnlNZXNzYWdlIHR5cGVfb25seV9hbnkgPSAzMDI7CisgIEFueU1lc3NhZ2UgcmVjdXJzaXZlX2FueSA9IDMwMzsKKyAgQW55TWVzc2FnZSBhbnlfd2l0aF9tZXNzYWdlX3ZhbHVlID0gMzA0OworICBBbnlNZXNzYWdlIGFueV93aXRoX25lc3RlZF9tZXNzYWdlID0gMzA1OworICBBbnlNZXNzYWdlIGFueV93aXRoX21lc3NhZ2VfY29udGFpbmluZ19tYXAgPSAzMDY7CisgIEFueU1lc3NhZ2UgYW55X3dpdGhfbWVzc2FnZV9jb250YWluaW5nX3N0cnVjdCA9IDMwNzsKKyAgZ29vZ2xlLnByb3RvYnVmLkFueSB0b3BfbGV2ZWxfYW55ID0gMzA4OworICBTdHJpbmd0b0ludE1hcCBlbXB0eV9tYXAgPSA0MDE7CisgIFN0cmluZ3RvSW50TWFwIHN0cmluZ190b19pbnQgPSA0MDI7CisgIEludFRvU3RyaW5nTWFwIGludF90b19zdHJpbmcgPSA0MDM7CisgIE1peGVkTWFwIG1peGVkMSA9IDQwNDsKKyAgTWl4ZWRNYXAyIG1peGVkMiA9IDQwNTsKKyAgTWl4ZWRNYXAyIGVtcHR5X21peGVkMiA9IDQwNjsKKyAgTWVzc2FnZU1hcCBtYXBfb2Zfb2JqZWN0cyA9IDQwNzsKKyAgTWl4ZWRNYXAgbWl4ZWRfZW1wdHkgPSA0MDg7CisgIE1lc3NhZ2VNYXAgbWVzc2FnZV9tYXBfZW1wdHkgPSA0MDk7CisgIERvdWJsZVZhbHVlTWVzc2FnZSBkb3VibGVfdmFsdWUgPSA1MDE7CisgIERvdWJsZVZhbHVlTWVzc2FnZSBkb3VibGVfdmFsdWVfZGVmYXVsdCA9IDUwMjsKK30KKworbWVzc2FnZSBEb3VibGVNZXNzYWdlIHsKKyAgZG91YmxlIGRvdWJsZV92YWx1ZSA9IDE7CisgIHJlcGVhdGVkIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgPSAyOworICBEb3VibGVNZXNzYWdlIG5lc3RlZF9tZXNzYWdlID0gMzsKKyAgcmVwZWF0ZWQgRG91YmxlTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ7CisgIGdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBkb3VibGVfd3JhcHBlciA9IDEwMDsKKyAgb25lb2YgdmFsdWUgeworICAgIHN0cmluZyBzdHJfdmFsdWUgPSAxMTI7CisgICAgaW50NjQgbnVtX3ZhbHVlID0gMTEzOworICB9Cit9CisKK21lc3NhZ2UgU3RydWN0TWVzc2FnZSB7CisgIGdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3Qgc3RydWN0ID0gMTsKK30KKworbWVzc2FnZSBWYWx1ZU1lc3NhZ2UgeworICBnb29nbGUucHJvdG9idWYuVmFsdWUgdmFsdWUgPSAxOworfQorCittZXNzYWdlIExpc3RWYWx1ZU1lc3NhZ2UgeworICBnb29nbGUucHJvdG9idWYuTGlzdFZhbHVlIHNob3BwaW5nX2xpc3QgPSAxOworfQorbWVzc2FnZSBSZXF1ZXN0TWVzc2FnZSB7CisgIHN0cmluZyBjb250ZW50ID0gMTsKK30KKworLy8gQSB0ZXN0IHNlcnZpY2UuCitzZXJ2aWNlIERlZmF1bHRWYWx1ZVRlc3RTZXJ2aWNlIHsKKyAgLy8gQSB0ZXN0IG1ldGhvZC4KKyAgcnBjIENhbGwoUmVxdWVzdE1lc3NhZ2UpIHJldHVybnMgKERlZmF1bHRWYWx1ZVRlc3RDYXNlcyk7Cit9CisKK21lc3NhZ2UgQW55TWVzc2FnZSB7CisgIGdvb2dsZS5wcm90b2J1Zi5BbnkgYW55ID0gMTsKKyAgQW55RGF0YSBkYXRhID0gMjsKK30KKworbWVzc2FnZSBBbnlEYXRhIHsKKyAgaW50MzIgYXR0ciA9IDE7CisgIHN0cmluZyBzdHIgPSAyOworICByZXBlYXRlZCBzdHJpbmcgbXNncyA9IDM7CisgIEFueURhdGEgbmVzdGVkX2RhdGEgPSA0OworICBtYXA8c3RyaW5nLCBzdHJpbmc+IG1hcF9kYXRhID0gNzsKKyAgZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCBzdHJ1Y3RfZGF0YSA9IDg7CisgIHJlcGVhdGVkIEFueURhdGEgcmVwZWF0ZWRfZGF0YSA9IDk7Cit9CisKK21lc3NhZ2UgU3RyaW5ndG9JbnRNYXAgeworICBtYXA8c3RyaW5nLCBpbnQzMj4gbWFwID0gMTsKK30KKworbWVzc2FnZSBJbnRUb1N0cmluZ01hcCB7CisgIG1hcDxpbnQzMiwgc3RyaW5nPiBtYXAgPSAxOworfQorCittZXNzYWdlIE1peGVkTWFwIHsKKyAgc3RyaW5nIG1zZyA9IDE7CisgIG1hcDxzdHJpbmcsIGZsb2F0PiBtYXAgPSAyOworICBpbnQzMiBpbnRfdmFsdWUgPSAzOworfQorCittZXNzYWdlIE1peGVkTWFwMiB7CisgIGVudW0gRSB7CisgICAgRTAgPSAwOworICAgIEUxID0gMTsKKyAgICBFMiA9IDI7CisgICAgRTMgPSAzOworICB9CisgIG1hcDxpbnQzMiwgYm9vbD4gbWFwID0gMTsKKyAgRSBlZSA9IDI7CisgIHN0cmluZyBtc2cgPSA0OworfQorCittZXNzYWdlIE1lc3NhZ2VNYXAgeworICBtZXNzYWdlIE0geworICAgIGludDMyIGlubmVyX2ludCA9IDE7CisgICAgc3RyaW5nIGlubmVyX3RleHQgPSAyOworICB9CisgIG1hcDxzdHJpbmcsIE0+IG1hcCA9IDE7Cit9CisKK21lc3NhZ2UgRG91YmxlVmFsdWVNZXNzYWdlIHsKKyAgZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlIGRvdWJsZSA9IDE7Cit9CmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvdGVzdGRhdGEvZGVmYXVsdF92YWx1ZV90ZXN0LnByb3RvIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3Rlc3RkYXRhL2RlZmF1bHRfdmFsdWVfdGVzdC5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45MzI4ODM0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3Rlc3RkYXRhL2RlZmF1bHRfdmFsdWVfdGVzdC5wcm90bwpAQCAtMCwwICsxLDUzIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworc3ludGF4ID0gInByb3RvMyI7CisKK3BhY2thZ2UgZ29vZ2xlLnByb3RvYnVmLnRlc3Rpbmc7CisKK21lc3NhZ2UgRGVmYXVsdFZhbHVlVGVzdCB7CisgIGRvdWJsZSBkb3VibGVfdmFsdWUgPSAxOworICByZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gMjsKKyAgZmxvYXQgZmxvYXRfdmFsdWUgPSAzOworICBpbnQ2NCBpbnQ2NF92YWx1ZSA9IDU7CisgIHVpbnQ2NCB1aW50NjRfdmFsdWUgPSA3OworICBpbnQzMiBpbnQzMl92YWx1ZSA9IDk7CisgIHVpbnQzMiB1aW50MzJfdmFsdWUgPSAxMTsKKyAgYm9vbCBib29sX3ZhbHVlID0gMTM7CisgIHN0cmluZyBzdHJpbmdfdmFsdWUgPSAxNTsKKyAgYnl0ZXMgYnl0ZXNfdmFsdWUgPSAxNyBbY3R5cGUgPSBDT1JEXTsKKworICBlbnVtIEVudW1EZWZhdWx0IHsKKyAgICBFTlVNX0ZJUlNUID0gMDsKKyAgICBFTlVNX1NFQ09ORCA9IDE7CisgICAgRU5VTV9USElSRCA9IDI7CisgIH0KKyAgRW51bURlZmF1bHQgZW51bV92YWx1ZSA9IDE4OworfQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3Rlc3RkYXRhL2ZpZWxkX21hc2sucHJvdG8gYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvdGVzdGRhdGEvZmllbGRfbWFzay5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lOGIyYmM1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3Rlc3RkYXRhL2ZpZWxkX21hc2sucHJvdG8KQEAgLTAsMCArMSw3MSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3N5bnRheCA9ICJwcm90bzMiOworCitwYWNrYWdlIGdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nOworCitpbXBvcnQgImdvb2dsZS9wcm90b2J1Zi9maWVsZF9tYXNrLnByb3RvIjsKKworbWVzc2FnZSBOZXN0ZWRGaWVsZE1hc2sgeworICBzdHJpbmcgZGF0YSA9IDE7CisgIGdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2sgc2luZ2xlX21hc2sgPSAyOworICByZXBlYXRlZCBnb29nbGUucHJvdG9idWYuRmllbGRNYXNrIHJlcGVhdGVkX21hc2sgPSAzOworfQorCittZXNzYWdlIEZpZWxkTWFza1Rlc3QgeworICBzdHJpbmcgaWQgPSAxOworICBnb29nbGUucHJvdG9idWYuRmllbGRNYXNrIHNpbmdsZV9tYXNrID0gMjsKKyAgcmVwZWF0ZWQgZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayByZXBlYXRlZF9tYXNrID0gMzsKKyAgcmVwZWF0ZWQgTmVzdGVkRmllbGRNYXNrIG5lc3RlZF9tYXNrID0gNDsKK30KKworbWVzc2FnZSBGaWVsZE1hc2tUZXN0Q2FzZXMgeworICBGaWVsZE1hc2tXcmFwcGVyIHNpbmdsZV9tYXNrID0gMTsKKyAgRmllbGRNYXNrV3JhcHBlciBtdWx0aXBsZV9tYXNrID0gMjsKKyAgRmllbGRNYXNrV3JhcHBlciBzbmFrZV9jYW1lbCA9IDM7CisgIEZpZWxkTWFza1dyYXBwZXIgZW1wdHlfZmllbGQgPSA0OworICBGaWVsZE1hc2tXcmFwcGVyIGFwaWFyeV9mb3JtYXQxID0gNTsKKyAgRmllbGRNYXNrV3JhcHBlciBhcGlhcnlfZm9ybWF0MiA9IDY7CisgIEZpZWxkTWFza1dyYXBwZXIgYXBpYXJ5X2Zvcm1hdDMgPSA3OworICBGaWVsZE1hc2tXcmFwcGVyIG1hcF9rZXkxID0gODsKKyAgRmllbGRNYXNrV3JhcHBlciBtYXBfa2V5MiA9IDk7CisgIEZpZWxkTWFza1dyYXBwZXIgbWFwX2tleTMgPSAxMDsKKyAgRmllbGRNYXNrV3JhcHBlciBtYXBfa2V5NCA9IDExOworICBGaWVsZE1hc2tXcmFwcGVyIG1hcF9rZXk1ID0gMTI7Cit9CisKK21lc3NhZ2UgRmllbGRNYXNrV3JhcHBlciB7CisgIGdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2sgbWFzayA9IDE7Cit9CisKK3NlcnZpY2UgRmllbGRNYXNrVGVzdFNlcnZpY2UgeworICBycGMgQ2FsbChGaWVsZE1hc2tUZXN0Q2FzZXMpIHJldHVybnMgKEZpZWxkTWFza1Rlc3RDYXNlcyk7Cit9CmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvdGVzdGRhdGEvbWFwcy5wcm90byBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90ZXN0ZGF0YS9tYXBzLnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY0NzVlY2QKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvdGVzdGRhdGEvbWFwcy5wcm90bwpAQCAtMCwwICsxLDg2IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gUHJvdG8gdG8gdGVzdCBwcm90bzMgbWFwcy4KK3N5bnRheCA9ICJwcm90bzMiOworCitwYWNrYWdlIGdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLm1hcHM7CitvcHRpb24gamF2YV9wYWNrYWdlID0gImNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5tYXBzIjsKKworbWVzc2FnZSBNYXBJbiB7CisgIHN0cmluZyBvdGhlciA9IDE7CisgIHJlcGVhdGVkIHN0cmluZyB0aGluZ3MgPSAyOworICBtYXA8c3RyaW5nLCBzdHJpbmc+IG1hcF9pbnB1dCA9IDM7Cit9CisKK21lc3NhZ2UgTWFwT3V0IHsKKyAgbWFwPHN0cmluZywgTWFwTT4gbWFwMSA9IDE7CisgIG1hcDxzdHJpbmcsIE1hcE91dD4gbWFwMiA9IDI7CisgIG1hcDxpbnQzMiwgc3RyaW5nPiBtYXAzID0gMzsKKyAgbWFwPGJvb2wsIHN0cmluZz4gbWFwNCA9IDU7CisgIHN0cmluZyBiYXIgPSA0OworfQorCisvLyBBIG1lc3NhZ2Ugd2l0aCBleGFjdGx5IHRoZSBzYW1lIHdpcmUgcmVwcmVzZW50YXRpb24gYXMgTWFwT3V0LCBidXQgdXNpbmcKKy8vIHJlcGVhdGVkIG1lc3NhZ2UgZmllbGRzIGluc3RlYWQgb2YgbWFwIGZpZWxkcy4gV2UgdXNlIHRoaXMgbWVzc2FnZSB0byB0ZXN0CisvLyB0aGUgd2lyZS1mb3JtYXQgY29tcGF0aWJpbGl0eSBvZiB0aGUgSlNPTiB0cmFuc2NvZGVyIChlLmcuLCB3aGV0aGVyIGl0CisvLyBoYW5kbGVzIG1pc3Npbmcga2V5cyBjb3JyZWN0bHkpLgorbWVzc2FnZSBNYXBPdXRXaXJlRm9ybWF0IHsKKyAgbWVzc2FnZSBNYXAxRW50cnkgeworICAgIHN0cmluZyBrZXkgPSAxOworICAgIE1hcE0gdmFsdWUgPSAyOworICB9CisgIHJlcGVhdGVkIE1hcDFFbnRyeSBtYXAxID0gMTsKKyAgbWVzc2FnZSBNYXAyRW50cnkgeworICAgIHN0cmluZyBrZXkgPSAxOworICAgIE1hcE91dCB2YWx1ZSA9IDI7CisgIH0KKyAgcmVwZWF0ZWQgTWFwMkVudHJ5IG1hcDIgPSAyOworICBtZXNzYWdlIE1hcDNFbnRyeSB7CisgICAgaW50MzIga2V5ID0gMTsKKyAgICBzdHJpbmcgdmFsdWUgPSAyOworICB9CisgIHJlcGVhdGVkIE1hcDNFbnRyeSBtYXAzID0gMzsKKyAgbWVzc2FnZSBNYXA0RW50cnkgeworICAgIGJvb2wga2V5ID0gMTsKKyAgICBzdHJpbmcgdmFsdWUgPSAyOworICB9CisgIHJlcGVhdGVkIE1hcDRFbnRyeSBtYXA0ID0gNTsKKyAgc3RyaW5nIGJhciA9IDQ7Cit9CisKK21lc3NhZ2UgTWFwTSB7CisgIHN0cmluZyBmb28gPSAxOworfQorCitzZXJ2aWNlIFRlc3RTZXJ2aWNlIHsKKyAgcnBjIENhbGwxKE1hcEluKSByZXR1cm5zIChNYXBPdXQpOworICBycGMgQ2FsbDIoTWFwSW4pIHJldHVybnMgKE1hcE91dCk7Cit9CmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvdGVzdGRhdGEvb25lb2ZzLnByb3RvIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3Rlc3RkYXRhL29uZW9mcy5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YmM5ZmEwCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3Rlc3RkYXRhL29uZW9mcy5wcm90bwpAQCAtMCwwICsxLDY4IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gUHJvdG8gdG8gdGVzdCBvbmVvZnMuCitzeW50YXggPSAicHJvdG8zIjsKKworaW1wb3J0ICJnb29nbGUvcHJvdG9idWYvYW55LnByb3RvIjsKK2ltcG9ydCAiZ29vZ2xlL3Byb3RvYnVmL3N0cnVjdC5wcm90byI7CitpbXBvcnQgImdvb2dsZS9wcm90b2J1Zi90aW1lc3RhbXAucHJvdG8iOworCitwYWNrYWdlIGdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLm9uZW9mczsKK29wdGlvbiBqYXZhX3BhY2thZ2UgPSAiY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLm9uZW9mcyI7CisKK21lc3NhZ2UgT25lT2ZzUmVxdWVzdCB7CisgIHN0cmluZyB2YWx1ZSA9IDE7CisgIG9uZW9mIGRhdGEgeworICAgIHN0cmluZyBzdHJfZGF0YSA9IDI7CisgICAgaW50MzIgaW50X2RhdGEgPSAzOworICAgIC8vIFNpbXBsZSBtZXNzYWdlCisgICAgRGF0YSBtZXNzYWdlX2RhdGEgPSA0OworICAgIC8vIFdlbGwga25vd24gdHlwZXMKKyAgICBnb29nbGUucHJvdG9idWYuU3RydWN0IHN0cnVjdF9kYXRhID0gNTsKKyAgICBnb29nbGUucHJvdG9idWYuVmFsdWUgdmFsdWVfZGF0YSA9IDY7CisgICAgZ29vZ2xlLnByb3RvYnVmLkxpc3RWYWx1ZSBsaXN0X3ZhbHVlX2RhdGEgPSA3OworICAgIGdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAgdHNfZGF0YSA9IDg7CisgIH0KKyAgZ29vZ2xlLnByb3RvYnVmLkFueSBhbnlfZGF0YSA9IDE5OworfQorCittZXNzYWdlIERhdGEgeworICBpbnQzMiBkYXRhX3ZhbHVlID0gMTsKK30KKworbWVzc2FnZSBSZXNwb25zZSB7CisgIHN0cmluZyB2YWx1ZSA9IDE7Cit9CisKK3NlcnZpY2UgVGVzdFNlcnZpY2UgeworICAvLyBUZXN0IGNhbGwuCisgIHJwYyBDYWxsKE9uZU9mc1JlcXVlc3QpIHJldHVybnMgKFJlc3BvbnNlKTsKK30KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90ZXN0ZGF0YS9zdHJ1Y3QucHJvdG8gYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvdGVzdGRhdGEvc3RydWN0LnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMxNWFiYTAKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvdGVzdGRhdGEvc3RydWN0LnByb3RvCkBAIC0wLDAgKzEsNDUgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBQcm90byB0byB0ZXN0IHByb3RvMyBzdHJ1Y3QuCitzeW50YXggPSAicHJvdG8zIjsKKworcGFja2FnZSBnb29nbGUucHJvdG9idWYudGVzdGluZy5zdHJ1Y3RzOworb3B0aW9uIGphdmFfcGFja2FnZSA9ICJjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3Rpbmcuc3RydWN0cyI7CisKK2ltcG9ydCAiZ29vZ2xlL3Byb3RvYnVmL3N0cnVjdC5wcm90byI7CisKK21lc3NhZ2UgU3RydWN0VHlwZSB7CisgIGdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3Qgb2JqZWN0ID0gMTsKK30KKworc2VydmljZSBUZXN0U2VydmljZSB7CisgIHJwYyBDYWxsKFN0cnVjdFR5cGUpIHJldHVybnMgKFN0cnVjdFR5cGUpOworfQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3Rlc3RkYXRhL3RpbWVzdGFtcF9kdXJhdGlvbi5wcm90byBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90ZXN0ZGF0YS90aW1lc3RhbXBfZHVyYXRpb24ucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTYzNTFmMQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90ZXN0ZGF0YS90aW1lc3RhbXBfZHVyYXRpb24ucHJvdG8KQEAgLTAsMCArMSw0NyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIFByb3RvIHRvIHRlc3QgcHJvdG8zIFRpbWVzdGFtcCBhbmQgRHVyYXRpb24uCitzeW50YXggPSAicHJvdG8zIjsKKworcGFja2FnZSBnb29nbGUucHJvdG9idWYudGVzdGluZy50aW1lc3RhbXBkdXJhdGlvbjsKK29wdGlvbiBqYXZhX3BhY2thZ2UgPSAiY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnRpbWVzdGFtcGR1cmF0aW9uIjsKKworaW1wb3J0ICJnb29nbGUvcHJvdG9idWYvdGltZXN0YW1wLnByb3RvIjsKK2ltcG9ydCAiZ29vZ2xlL3Byb3RvYnVmL2R1cmF0aW9uLnByb3RvIjsKKworbWVzc2FnZSBUaW1lc3RhbXBEdXJhdGlvbiB7CisgIGdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAgdHMgPSAxOworICBnb29nbGUucHJvdG9idWYuRHVyYXRpb24gZHVyID0gMjsKK30KKworc2VydmljZSBUZXN0U2VydmljZSB7CisgIHJwYyBDYWxsKFRpbWVzdGFtcER1cmF0aW9uKSByZXR1cm5zIChUaW1lc3RhbXBEdXJhdGlvbik7Cit9CmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvdGVzdGRhdGEvd3JhcHBlcnMucHJvdG8gYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvdGVzdGRhdGEvd3JhcHBlcnMucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWFiYzk5ZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90ZXN0ZGF0YS93cmFwcGVycy5wcm90bwpAQCAtMCwwICsxLDEwMCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKK3N5bnRheCA9ICJwcm90bzMiOworCitwYWNrYWdlIGdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nOworCitpbXBvcnQgImdvb2dsZS9wcm90b2J1Zi93cmFwcGVycy5wcm90byI7CisKKy8vIFRvcC1sZXZlbCB0ZXN0IGNhc2VzIHByb3RvIHVzZWQgYnkgTWFyc2hhbGxpbmdUZXN0LiBTZWUgZGVzY3JpcHRpb24KKy8vIGF0IHRoZSB0b3Agb2YgdGhlIGNsYXNzIE1hcnNoYWxsaW5nVGVzdCBmb3IgZGV0YWlscyBvbiBob3cgdG8gd3JpdGUKKy8vIHRlc3QgY2FzZXMuCittZXNzYWdlIFdyYXBwZXJzVGVzdENhc2VzIHsKKyAgRG91YmxlV3JhcHBlciBkb3VibGVfd3JhcHBlciA9IDE7CisgIEZsb2F0V3JhcHBlciBmbG9hdF93cmFwcGVyID0gMjsKKyAgSW50NjRXcmFwcGVyIGludDY0X3dyYXBwZXIgPSAzOworICBVSW50NjRXcmFwcGVyIHVpbnQ2NF93cmFwcGVyID0gNDsKKyAgSW50MzJXcmFwcGVyIGludDMyX3dyYXBwZXIgPSA1OworICBVSW50MzJXcmFwcGVyIHVpbnQzMl93cmFwcGVyID0gNjsKKyAgQm9vbFdyYXBwZXIgYm9vbF93cmFwcGVyID0gNzsKKyAgU3RyaW5nV3JhcHBlciBzdHJpbmdfd3JhcHBlciA9IDg7CisgIEJ5dGVzV3JhcHBlciBieXRlc193cmFwcGVyID0gOTsKKworICBEb3VibGVXcmFwcGVyIGRvdWJsZV93cmFwcGVyX2RlZmF1bHQgPSAxMDsKKyAgRmxvYXRXcmFwcGVyIGZsb2F0X3dyYXBwZXJfZGVmYXVsdCA9IDExOworICBJbnQ2NFdyYXBwZXIgaW50NjRfd3JhcHBlcl9kZWZhdWx0ID0gMTI7CisgIFVJbnQ2NFdyYXBwZXIgdWludDY0X3dyYXBwZXJfZGVmYXVsdCA9IDEzOworICBJbnQzMldyYXBwZXIgaW50MzJfd3JhcHBlcl9kZWZhdWx0ID0gMTQ7CisgIFVJbnQzMldyYXBwZXIgdWludDMyX3dyYXBwZXJfZGVmYXVsdCA9IDE1OworICBCb29sV3JhcHBlciBib29sX3dyYXBwZXJfZGVmYXVsdCA9IDE2OworICBTdHJpbmdXcmFwcGVyIHN0cmluZ193cmFwcGVyX2RlZmF1bHQgPSAxNzsKKyAgQnl0ZXNXcmFwcGVyIGJ5dGVzX3dyYXBwZXJfZGVmYXVsdCA9IDE4OworfQorCittZXNzYWdlIERvdWJsZVdyYXBwZXIgeworICBnb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgZG91YmxlID0gMTsKK30KKworbWVzc2FnZSBGbG9hdFdyYXBwZXIgeworICBnb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSBmbG9hdCA9IDE7Cit9CisKK21lc3NhZ2UgSW50NjRXcmFwcGVyIHsKKyAgZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUgaW50NjQgPSAxOworfQorCittZXNzYWdlIFVJbnQ2NFdyYXBwZXIgeworICBnb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUgdWludDY0ID0gMTsKK30KKworbWVzc2FnZSBJbnQzMldyYXBwZXIgeworICBnb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBpbnQzMiA9IDE7Cit9CisKK21lc3NhZ2UgVUludDMyV3JhcHBlciB7CisgIGdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSB1aW50MzIgPSAxOworfQorCittZXNzYWdlIEJvb2xXcmFwcGVyIHsKKyAgZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSBib29sID0gMTsKK30KKworbWVzc2FnZSBTdHJpbmdXcmFwcGVyIHsKKyAgZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIHN0cmluZyA9IDE7Cit9CisKK21lc3NhZ2UgQnl0ZXNXcmFwcGVyIHsKKyAgZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUgYnl0ZXMgPSAxOworfQorCitzZXJ2aWNlIFdyYXBwZXJzVGVzdFNlcnZpY2UgeworICBycGMgQ2FsbChXcmFwcGVyc1Rlc3RDYXNlcykgcmV0dXJucyAoV3JhcHBlcnNUZXN0Q2FzZXMpOworfQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3R5cGVfaW5mby5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90eXBlX2luZm8uY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDBhOGVlNwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90eXBlX2luZm8uY2MKQEAgLTAsMCArMSwxNzEgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvdHlwZV9pbmZvLmg+CisKKyNpbmNsdWRlIDxtYXA+CisjaW5jbHVkZSA8c2V0PgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90eXBlLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvdXRpbGl0eS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJpbmdwaWVjZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9tYXBfdXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdGF0dXMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RhdHVzb3IuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIHV0aWwgeworbmFtZXNwYWNlIGNvbnZlcnRlciB7CisKK25hbWVzcGFjZSB7CisvLyBBIFR5cGVJbmZvIHRoYXQgbG9va3MgdXAgaW5mb3JtYXRpb24gcHJvdmlkZWQgYnkgYSBUeXBlUmVzb2x2ZXIuCitjbGFzcyBUeXBlSW5mb0ZvclR5cGVSZXNvbHZlciA6IHB1YmxpYyBUeXBlSW5mbyB7CisgcHVibGljOgorICBleHBsaWNpdCBUeXBlSW5mb0ZvclR5cGVSZXNvbHZlcihUeXBlUmVzb2x2ZXIqIHR5cGVfcmVzb2x2ZXIpCisgICAgICA6IHR5cGVfcmVzb2x2ZXJfKHR5cGVfcmVzb2x2ZXIpIHt9CisKKyAgdmlydHVhbCB+VHlwZUluZm9Gb3JUeXBlUmVzb2x2ZXIoKSB7CisgICAgRGVsZXRlQ2FjaGVkVHlwZXMoJmNhY2hlZF90eXBlc18pOworICAgIERlbGV0ZUNhY2hlZFR5cGVzKCZjYWNoZWRfZW51bXNfKTsKKyAgfQorCisgIHZpcnR1YWwgdXRpbDo6U3RhdHVzT3I8Y29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6VHlwZSo+IFJlc29sdmVUeXBlVXJsKAorICAgICAgU3RyaW5nUGllY2UgdHlwZV91cmwpIGNvbnN0IHsKKyAgICBtYXA8U3RyaW5nUGllY2UsIFN0YXR1c09yVHlwZT46Oml0ZXJhdG9yIGl0ID0gY2FjaGVkX3R5cGVzXy5maW5kKHR5cGVfdXJsKTsKKyAgICBpZiAoaXQgIT0gY2FjaGVkX3R5cGVzXy5lbmQoKSkgeworICAgICAgcmV0dXJuIGl0LT5zZWNvbmQ7CisgICAgfQorICAgIC8vIFN0b3JlcyB0aGUgc3RyaW5nIHZhbHVlIHNvIGl0IGNhbiBiZSByZWZlcmVuY2VkIHVzaW5nIFN0cmluZ1BpZWNlIGluIHRoZQorICAgIC8vIGNhY2hlZF90eXBlc18gbWFwLgorICAgIGNvbnN0IHN0cmluZyYgc3RyaW5nX3R5cGVfdXJsID0KKyAgICAgICAgKnN0cmluZ19zdG9yYWdlXy5pbnNlcnQodHlwZV91cmwuVG9TdHJpbmcoKSkuZmlyc3Q7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxnb29nbGU6OnByb3RvYnVmOjpUeXBlPiB0eXBlKG5ldyBnb29nbGU6OnByb3RvYnVmOjpUeXBlKCkpOworICAgIHV0aWw6OlN0YXR1cyBzdGF0dXMgPQorICAgICAgICB0eXBlX3Jlc29sdmVyXy0+UmVzb2x2ZU1lc3NhZ2VUeXBlKHN0cmluZ190eXBlX3VybCwgdHlwZS5nZXQoKSk7CisgICAgU3RhdHVzT3JUeXBlIHJlc3VsdCA9CisgICAgICAgIHN0YXR1cy5vaygpID8gU3RhdHVzT3JUeXBlKHR5cGUucmVsZWFzZSgpKSA6IFN0YXR1c09yVHlwZShzdGF0dXMpOworICAgIGNhY2hlZF90eXBlc19bc3RyaW5nX3R5cGVfdXJsXSA9IHJlc3VsdDsKKyAgICByZXR1cm4gcmVzdWx0OworICB9CisKKyAgdmlydHVhbCBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlKiBHZXRUeXBlQnlUeXBlVXJsKAorICAgICAgU3RyaW5nUGllY2UgdHlwZV91cmwpIGNvbnN0IHsKKyAgICBTdGF0dXNPclR5cGUgcmVzdWx0ID0gUmVzb2x2ZVR5cGVVcmwodHlwZV91cmwpOworICAgIHJldHVybiByZXN1bHQub2soKSA/IHJlc3VsdC5WYWx1ZU9yRGllKCkgOiBOVUxMOworICB9CisKKyAgdmlydHVhbCBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpFbnVtKiBHZXRFbnVtQnlUeXBlVXJsKAorICAgICAgU3RyaW5nUGllY2UgdHlwZV91cmwpIGNvbnN0IHsKKyAgICBtYXA8U3RyaW5nUGllY2UsIFN0YXR1c09yRW51bT46Oml0ZXJhdG9yIGl0ID0gY2FjaGVkX2VudW1zXy5maW5kKHR5cGVfdXJsKTsKKyAgICBpZiAoaXQgIT0gY2FjaGVkX2VudW1zXy5lbmQoKSkgeworICAgICAgcmV0dXJuIGl0LT5zZWNvbmQub2soKSA/IGl0LT5zZWNvbmQuVmFsdWVPckRpZSgpIDogTlVMTDsKKyAgICB9CisgICAgLy8gU3RvcmVzIHRoZSBzdHJpbmcgdmFsdWUgc28gaXQgY2FuIGJlIHJlZmVyZW5jZWQgdXNpbmcgU3RyaW5nUGllY2UgaW4gdGhlCisgICAgLy8gY2FjaGVkX2VudW1zXyBtYXAuCisgICAgY29uc3Qgc3RyaW5nJiBzdHJpbmdfdHlwZV91cmwgPQorICAgICAgICAqc3RyaW5nX3N0b3JhZ2VfLmluc2VydCh0eXBlX3VybC5Ub1N0cmluZygpKS5maXJzdDsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPGdvb2dsZTo6cHJvdG9idWY6OkVudW0+IGVudW1fdHlwZSgKKyAgICAgICAgbmV3IGdvb2dsZTo6cHJvdG9idWY6OkVudW0oKSk7CisgICAgdXRpbDo6U3RhdHVzIHN0YXR1cyA9CisgICAgICAgIHR5cGVfcmVzb2x2ZXJfLT5SZXNvbHZlRW51bVR5cGUoc3RyaW5nX3R5cGVfdXJsLCBlbnVtX3R5cGUuZ2V0KCkpOworICAgIFN0YXR1c09yRW51bSByZXN1bHQgPQorICAgICAgICBzdGF0dXMub2soKSA/IFN0YXR1c09yRW51bShlbnVtX3R5cGUucmVsZWFzZSgpKSA6IFN0YXR1c09yRW51bShzdGF0dXMpOworICAgIGNhY2hlZF9lbnVtc19bc3RyaW5nX3R5cGVfdXJsXSA9IHJlc3VsdDsKKyAgICByZXR1cm4gcmVzdWx0Lm9rKCkgPyByZXN1bHQuVmFsdWVPckRpZSgpIDogTlVMTDsKKyAgfQorCisgIHZpcnR1YWwgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGQqIEZpbmRGaWVsZCgKKyAgICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlR5cGUqIHR5cGUsIFN0cmluZ1BpZWNlIGNhbWVsX2Nhc2VfbmFtZSkgY29uc3QgeworICAgIGlmIChpbmRleGVkX3R5cGVzXy5maW5kKHR5cGUpID09IGluZGV4ZWRfdHlwZXNfLmVuZCgpKSB7CisgICAgICBQb3B1bGF0ZU5hbWVMb29rdXBUYWJsZSh0eXBlKTsKKyAgICAgIGluZGV4ZWRfdHlwZXNfLmluc2VydCh0eXBlKTsKKyAgICB9CisgICAgU3RyaW5nUGllY2UgbmFtZSA9CisgICAgICAgIEZpbmRXaXRoRGVmYXVsdChjYW1lbF9jYXNlX25hbWVfdGFibGVfLCBjYW1lbF9jYXNlX25hbWUsIFN0cmluZ1BpZWNlKCkpOworICAgIGlmIChuYW1lLmVtcHR5KCkpIHsKKyAgICAgIC8vIERpZG4ndCBmaW5kIGEgbWFwcGluZy4gVXNlIHdoYXRldmVyIHByb3ZpZGVkLgorICAgICAgbmFtZSA9IGNhbWVsX2Nhc2VfbmFtZTsKKyAgICB9CisgICAgcmV0dXJuIEZpbmRGaWVsZEluVHlwZU9yTnVsbCh0eXBlLCBuYW1lKTsKKyAgfQorCisgcHJpdmF0ZToKKyAgdHlwZWRlZiB1dGlsOjpTdGF0dXNPcjxjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlKj4gU3RhdHVzT3JUeXBlOworICB0eXBlZGVmIHV0aWw6OlN0YXR1c09yPGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkVudW0qPiBTdGF0dXNPckVudW07CisKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CisgIHN0YXRpYyB2b2lkIERlbGV0ZUNhY2hlZFR5cGVzKG1hcDxTdHJpbmdQaWVjZSwgVD4qIGNhY2hlZF90eXBlcykgeworICAgIGZvciAodHlwZW5hbWUgbWFwPFN0cmluZ1BpZWNlLCBUPjo6aXRlcmF0b3IgaXQgPSBjYWNoZWRfdHlwZXMtPmJlZ2luKCk7CisgICAgICAgICBpdCAhPSBjYWNoZWRfdHlwZXMtPmVuZCgpOyArK2l0KSB7CisgICAgICBpZiAoaXQtPnNlY29uZC5vaygpKSB7CisgICAgICAgIGRlbGV0ZSBpdC0+c2Vjb25kLlZhbHVlT3JEaWUoKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICB2b2lkIFBvcHVsYXRlTmFtZUxvb2t1cFRhYmxlKGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlR5cGUqIHR5cGUpIGNvbnN0IHsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHR5cGUtPmZpZWxkc19zaXplKCk7ICsraSkgeworICAgICAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGQmIGZpZWxkID0gdHlwZS0+ZmllbGRzKGkpOworICAgICAgU3RyaW5nUGllY2UgbmFtZSA9IGZpZWxkLm5hbWUoKTsKKyAgICAgIFN0cmluZ1BpZWNlIGNhbWVsX2Nhc2VfbmFtZSA9IGZpZWxkLmpzb25fbmFtZSgpOworICAgICAgY29uc3QgU3RyaW5nUGllY2UqIGV4aXN0aW5nID0gSW5zZXJ0T3JSZXR1cm5FeGlzdGluZygKKyAgICAgICAgICAmY2FtZWxfY2FzZV9uYW1lX3RhYmxlXywgY2FtZWxfY2FzZV9uYW1lLCBuYW1lKTsKKyAgICAgIGlmIChleGlzdGluZyAmJiAqZXhpc3RpbmcgIT0gbmFtZSkgeworICAgICAgICBHT09HTEVfTE9HKFdBUk5JTkcpIDw8ICJGaWVsZCAnIiA8PCBuYW1lIDw8ICInIGFuZCAnIiA8PCAqZXhpc3RpbmcKKyAgICAgICAgICAgICAgICAgICAgIDw8ICInIG1hcCB0byB0aGUgc2FtZSBjYW1lbCBjYXNlIG5hbWUgJyIgPDwgY2FtZWxfY2FzZV9uYW1lCisgICAgICAgICAgICAgICAgICAgICA8PCAiJy4iOworICAgICAgfQorICAgIH0KKyAgfQorCisgIFR5cGVSZXNvbHZlciogdHlwZV9yZXNvbHZlcl87CisKKyAgLy8gU3RvcmVzIHN0cmluZyB2YWx1ZXMgdGhhdCB3aWxsIGJlIHJlZmVyZW5jZWQgYnkgU3RyaW5nUGllY2VzIGluCisgIC8vIGNhY2hlZF90eXBlc18sIGNhY2hlZF9lbnVtc18gYW5kIGNhbWVsX2Nhc2VfbmFtZV90YWJsZV8uCisgIG11dGFibGUgc2V0PHN0cmluZz4gc3RyaW5nX3N0b3JhZ2VfOworCisgIG11dGFibGUgbWFwPFN0cmluZ1BpZWNlLCBTdGF0dXNPclR5cGU+IGNhY2hlZF90eXBlc187CisgIG11dGFibGUgbWFwPFN0cmluZ1BpZWNlLCBTdGF0dXNPckVudW0+IGNhY2hlZF9lbnVtc187CisKKyAgbXV0YWJsZSBzZXQ8Y29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6VHlwZSo+IGluZGV4ZWRfdHlwZXNfOworICBtdXRhYmxlIG1hcDxTdHJpbmdQaWVjZSwgU3RyaW5nUGllY2U+IGNhbWVsX2Nhc2VfbmFtZV90YWJsZV87Cit9OworfSAgLy8gbmFtZXNwYWNlCisKK1R5cGVJbmZvKiBUeXBlSW5mbzo6TmV3VHlwZUluZm8oVHlwZVJlc29sdmVyKiB0eXBlX3Jlc29sdmVyKSB7CisgIHJldHVybiBuZXcgVHlwZUluZm9Gb3JUeXBlUmVzb2x2ZXIodHlwZV9yZXNvbHZlcik7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBjb252ZXJ0ZXIKK30gIC8vIG5hbWVzcGFjZSB1dGlsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90eXBlX2luZm8uaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90eXBlX2luZm8uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kODEzMzE3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3R5cGVfaW5mby5oCkBAIC0wLDAgKzEsOTIgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9VVElMX0NPTlZFUlRFUl9UWVBFX0lORk9fSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9VVElMX0NPTlZFUlRFUl9UWVBFX0lORk9fSF9fCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3R5cGUucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC90eXBlX3Jlc29sdmVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cmluZ3BpZWNlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0YXR1cy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdGF0dXNvci5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgdXRpbCB7CituYW1lc3BhY2UgY29udmVydGVyIHsKKy8vIEludGVybmFsIGhlbHBlciBjbGFzcyBmb3IgdHlwZSByZXNvbHZpbmcuIE5vdGUgdGhhdCB0aGlzIGNsYXNzIGlzIG5vdAorLy8gdGhyZWFkLXNhZmUgYW5kIHNob3VsZCBvbmx5IGJlIGFjY2Vzc2VkIGluIG9uZSB0aHJlYWQuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgVHlwZUluZm8geworIHB1YmxpYzoKKyAgVHlwZUluZm8oKSB7fQorICB2aXJ0dWFsIH5UeXBlSW5mbygpIHt9CisKKyAgLy8gUmVzb2x2ZXMgYSB0eXBlIHVybCBpbnRvIGEgVHlwZS4gSWYgdGhlIHR5cGUgdXJsIGlzIGludmFsaWQsIHJldHVybnMKKyAgLy8gSU5WQUxJRF9BUkdVTUVOVCBlcnJvciBzdGF0dXMuIElmIHRoZSB0eXBlIHVybCBpcyB2YWxpZCBidXQgdGhlCisgIC8vIGNvcnJlc3BvbmRpbmcgdHlwZSBjYW5ub3QgYmUgZm91bmQsIHJldHVybnMgYSBOT1RfRk9VTkQgZXJyb3Igc3RhdHVzLgorICAvLworICAvLyBUaGlzIFR5cGVJbmZvIGNsYXNzIHJldGFpbnMgdGhlIG93bmVyc2hpcCBvZiB0aGUgcmV0dXJuZWQgcG9pbnRlci4KKyAgdmlydHVhbCB1dGlsOjpTdGF0dXNPcjxjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlKj4gUmVzb2x2ZVR5cGVVcmwoCisgICAgICBTdHJpbmdQaWVjZSB0eXBlX3VybCkgY29uc3QgPSAwOworCisgIC8vIFJlc29sdmVzIGEgdHlwZSB1cmwgaW50byBhIFR5cGUuIExpa2UgUmVzb2x2ZVR5cGVVcmwoKSBidXQgcmV0dXJucworICAvLyBOVUxMIGlmIHRoZSB0eXBlIHVybCBpcyBpbnZhbGlkIG9yIHRoZSB0eXBlIGNhbm5vdCBiZSBmb3VuZC4KKyAgLy8KKyAgLy8gVGhpcyBUeXBlSW5mbyBjbGFzcyByZXRhaW5zIHRoZSBvd25lcnNoaXAgb2YgdGhlIHJldHVybmVkIHBvaW50ZXIuCisgIHZpcnR1YWwgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6VHlwZSogR2V0VHlwZUJ5VHlwZVVybCgKKyAgICAgIFN0cmluZ1BpZWNlIHR5cGVfdXJsKSBjb25zdCA9IDA7CisKKyAgLy8gUmVzb2x2ZXMgYSB0eXBlIHVybCBmb3IgYW4gZW51bS4gUmV0dXJucyBOVUxMIGlmIHRoZSB0eXBlIHVybCBpcworICAvLyBpbnZhbGlkIG9yIHRoZSB0eXBlIGNhbm5vdCBiZSBmb3VuZC4KKyAgLy8KKyAgLy8gVGhpcyBUeXBlSW5mbyBjbGFzcyByZXRhaW5zIHRoZSBvd25lcnNoaXAgb2YgdGhlIHJldHVybmVkIHBvaW50ZXIuCisgIHZpcnR1YWwgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RW51bSogR2V0RW51bUJ5VHlwZVVybCgKKyAgICAgIFN0cmluZ1BpZWNlIHR5cGVfdXJsKSBjb25zdCA9IDA7CisKKyAgLy8gTG9va3MgdXAgYSBmaWVsZCBpbiB0aGUgc3BlY2lmaWVkIHR5cGUgZ2l2ZW4gYSBDYW1lbENhc2UgbmFtZS4KKyAgdmlydHVhbCBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZCogRmluZEZpZWxkKAorICAgICAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6VHlwZSogdHlwZSwKKyAgICAgIFN0cmluZ1BpZWNlIGNhbWVsX2Nhc2VfbmFtZSkgY29uc3QgPSAwOworCisgIC8vIENyZWF0ZXMgYSBUeXBlSW5mbyBvYmplY3QgdGhhdCBsb29rcyB1cCB0eXBlIGluZm9ybWF0aW9uIGZyb20gYQorICAvLyBUeXBlUmVzb2x2ZXIuIENhbGxlciB0YWtlcyBvd25lcnNoaXAgb2YgdGhlIHJldHVybmVkIHBvaW50ZXIuCisgIHN0YXRpYyBUeXBlSW5mbyogTmV3VHlwZUluZm8oVHlwZVJlc29sdmVyKiB0eXBlX3Jlc29sdmVyKTsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhUeXBlSW5mbyk7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgY29udmVydGVyCit9ICAvLyBuYW1lc3BhY2UgdXRpbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX1VUSUxfQ09OVkVSVEVSX1RZUEVfSU5GT19IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90eXBlX2luZm9fdGVzdF9oZWxwZXIuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvdHlwZV9pbmZvX3Rlc3RfaGVscGVyLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFiOWM1MTUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvdHlwZV9pbmZvX3Rlc3RfaGVscGVyLmNjCkBAIC0wLDAgKzEsMTM0IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3R5cGVfaW5mb190ZXN0X2hlbHBlci5oPgorCisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorI2luY2x1ZGUgPHZlY3Rvcj4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9sb2dnaW5nLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvZGVmYXVsdF92YWx1ZV9vYmplY3R3cml0ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90eXBlX2luZm8uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9jb25zdGFudHMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9wcm90b3N0cmVhbV9vYmplY3Rzb3VyY2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9wcm90b3N0cmVhbV9vYmplY3R3cml0ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC90eXBlX3Jlc29sdmVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3V0aWwvdHlwZV9yZXNvbHZlcl91dGlsLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSB1dGlsIHsKK25hbWVzcGFjZSBjb252ZXJ0ZXIgeworbmFtZXNwYWNlIHRlc3RpbmcgeworCisKK3ZvaWQgVHlwZUluZm9UZXN0SGVscGVyOjpSZXNldFR5cGVJbmZvKAorICAgIGNvbnN0IHZlY3Rvcjxjb25zdCBEZXNjcmlwdG9yKj4mIGRlc2NyaXB0b3JzKSB7CisgIHN3aXRjaCAodHlwZV8pIHsKKyAgICBjYXNlIFVTRV9UWVBFX1JFU09MVkVSOiB7CisgICAgICBjb25zdCBEZXNjcmlwdG9yUG9vbCogcG9vbCA9IGRlc2NyaXB0b3JzWzBdLT5maWxlKCktPnBvb2woKTsKKyAgICAgIGZvciAoaW50IGkgPSAxOyBpIDwgZGVzY3JpcHRvcnMuc2l6ZSgpOyArK2kpIHsKKyAgICAgICAgR09PR0xFX0NIRUNLKHBvb2wgPT0gZGVzY3JpcHRvcnNbaV0tPmZpbGUoKS0+cG9vbCgpKQorICAgICAgICAgICAgPDwgIkRlc2NyaXB0b3JzIGZyb20gZGlmZmVyZW50IHBvb2xzIGFyZSBub3Qgc3VwcG9ydGVkLiI7CisgICAgICB9CisgICAgICB0eXBlX3Jlc29sdmVyXy5yZXNldCgKKyAgICAgICAgICBOZXdUeXBlUmVzb2x2ZXJGb3JEZXNjcmlwdG9yUG9vbChrVHlwZVNlcnZpY2VCYXNlVXJsLCBwb29sKSk7CisgICAgICB0eXBlaW5mb18ucmVzZXQoVHlwZUluZm86Ok5ld1R5cGVJbmZvKHR5cGVfcmVzb2x2ZXJfLmdldCgpKSk7CisgICAgICByZXR1cm47CisgICAgfQorICB9CisgIEdPT0dMRV9MT0coRkFUQUwpIDw8ICJDYW4gbm90IHJlYWNoIGhlcmUuIjsKK30KKwordm9pZCBUeXBlSW5mb1Rlc3RIZWxwZXI6OlJlc2V0VHlwZUluZm8oY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICB2ZWN0b3I8Y29uc3QgRGVzY3JpcHRvcio+IGRlc2NyaXB0b3JzOworICBkZXNjcmlwdG9ycy5wdXNoX2JhY2soZGVzY3JpcHRvcik7CisgIFJlc2V0VHlwZUluZm8oZGVzY3JpcHRvcnMpOworfQorCit2b2lkIFR5cGVJbmZvVGVzdEhlbHBlcjo6UmVzZXRUeXBlSW5mbyhjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IyKSB7CisgIHZlY3Rvcjxjb25zdCBEZXNjcmlwdG9yKj4gZGVzY3JpcHRvcnM7CisgIGRlc2NyaXB0b3JzLnB1c2hfYmFjayhkZXNjcmlwdG9yMSk7CisgIGRlc2NyaXB0b3JzLnB1c2hfYmFjayhkZXNjcmlwdG9yMik7CisgIFJlc2V0VHlwZUluZm8oZGVzY3JpcHRvcnMpOworfQorCitUeXBlSW5mbyogVHlwZUluZm9UZXN0SGVscGVyOjpHZXRUeXBlSW5mbygpIHsgcmV0dXJuIHR5cGVpbmZvXy5nZXQoKTsgfQorCitQcm90b1N0cmVhbU9iamVjdFNvdXJjZSogVHlwZUluZm9UZXN0SGVscGVyOjpOZXdQcm90b1NvdXJjZSgKKyAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSogY29kZWRfaW5wdXQsIGNvbnN0IHN0cmluZyYgdHlwZV91cmwpIHsKKyAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6VHlwZSogdHlwZSA9IHR5cGVpbmZvXy0+R2V0VHlwZUJ5VHlwZVVybCh0eXBlX3VybCk7CisgIHN3aXRjaCAodHlwZV8pIHsKKyAgICBjYXNlIFVTRV9UWVBFX1JFU09MVkVSOiB7CisgICAgICByZXR1cm4gbmV3IFByb3RvU3RyZWFtT2JqZWN0U291cmNlKGNvZGVkX2lucHV0LCB0eXBlX3Jlc29sdmVyXy5nZXQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKnR5cGUpOworICAgIH0KKyAgfQorICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ2FuIG5vdCByZWFjaCBoZXJlLiI7CisgIHJldHVybiBOVUxMOworfQorCitQcm90b1N0cmVhbU9iamVjdFdyaXRlciogVHlwZUluZm9UZXN0SGVscGVyOjpOZXdQcm90b1dyaXRlcigKKyAgICBjb25zdCBzdHJpbmcmIHR5cGVfdXJsLCBzdHJpbmdzOjpCeXRlU2luayogb3V0cHV0LAorICAgIEVycm9yTGlzdGVuZXIqIGxpc3RlbmVyKSB7CisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlR5cGUqIHR5cGUgPSB0eXBlaW5mb18tPkdldFR5cGVCeVR5cGVVcmwodHlwZV91cmwpOworICBzd2l0Y2ggKHR5cGVfKSB7CisgICAgY2FzZSBVU0VfVFlQRV9SRVNPTFZFUjogeworICAgICAgcmV0dXJuIG5ldyBQcm90b1N0cmVhbU9iamVjdFdyaXRlcih0eXBlX3Jlc29sdmVyXy5nZXQoKSwgKnR5cGUsIG91dHB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXIpOworICAgIH0KKyAgfQorICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ2FuIG5vdCByZWFjaCBoZXJlLiI7CisgIHJldHVybiBOVUxMOworfQorCitEZWZhdWx0VmFsdWVPYmplY3RXcml0ZXIqIFR5cGVJbmZvVGVzdEhlbHBlcjo6TmV3RGVmYXVsdFZhbHVlV3JpdGVyKAorICAgIGNvbnN0IHN0cmluZyYgdHlwZV91cmwsIE9iamVjdFdyaXRlciogd3JpdGVyKSB7CisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlR5cGUqIHR5cGUgPSB0eXBlaW5mb18tPkdldFR5cGVCeVR5cGVVcmwodHlwZV91cmwpOworICBzd2l0Y2ggKHR5cGVfKSB7CisgICAgY2FzZSBVU0VfVFlQRV9SRVNPTFZFUjogeworICAgICAgcmV0dXJuIG5ldyBEZWZhdWx0VmFsdWVPYmplY3RXcml0ZXIodHlwZV9yZXNvbHZlcl8uZ2V0KCksICp0eXBlLCB3cml0ZXIpOworICAgIH0KKyAgfQorICBHT09HTEVfTE9HKEZBVEFMKSA8PCAiQ2FuIG5vdCByZWFjaCBoZXJlLiI7CisgIHJldHVybiBOVUxMOworfQorCit9ICAvLyBuYW1lc3BhY2UgdGVzdGluZworfSAgLy8gbmFtZXNwYWNlIGNvbnZlcnRlcgorfSAgLy8gbmFtZXNwYWNlIHV0aWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3R5cGVfaW5mb190ZXN0X2hlbHBlci5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3R5cGVfaW5mb190ZXN0X2hlbHBlci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY5MTZhNzMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvdHlwZV9pbmZvX3Rlc3RfaGVscGVyLmgKQEAgLTAsMCArMSw5OCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX1VUSUxfQ09OVkVSVEVSX1RZUEVfSU5GT19URVNUX0hFTFBFUl9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1VUSUxfQ09OVkVSVEVSX1RZUEVfSU5GT19URVNUX0hFTFBFUl9IX18KKworI2luY2x1ZGUgPG1lbW9yeT4KKyNpZm5kZWYgX1NIQVJFRF9QVFJfSAorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaGFyZWRfcHRyLmg+CisjZW5kaWYKKyNpbmNsdWRlIDx2ZWN0b3I+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC90eXBlX2luZm8uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9kZWZhdWx0X3ZhbHVlX29iamVjdHdyaXRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3Byb3Rvc3RyZWFtX29iamVjdHNvdXJjZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3Byb3Rvc3RyZWFtX29iamVjdHdyaXRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL3R5cGVfcmVzb2x2ZXIuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIHV0aWwgeworbmFtZXNwYWNlIGNvbnZlcnRlciB7CituYW1lc3BhY2UgdGVzdGluZyB7CisKK2VudW0gVHlwZUluZm9Tb3VyY2UgeworICBVU0VfVFlQRV9SRVNPTFZFUiwKK307CisKKy8vIEluIHRoZSB1bml0LXRlc3RzIHdlIHdhbnQgdG8gdGVzdCB0d28gc2NlbmFyaW9zOiBvbmUgd2l0aCB0eXBlIGluZm8gZnJvbQorLy8gU2VydmljZVR5cGVJbmZvLCB0aGUgb3RoZXIgd2l0aCB0eXBlIGluZm8gZnJvbSBUeXBlUmVzb2x2ZXIuIFRoaXMgY2xhc3MKKy8vIHdyYXBzIHRoZSBkZXRhaWwgb2Ygd2hlcmUgdGhlIHR5cGUgaW5mbyBpcyBmcm9tIGFuZCBwcm92aWRlcyB0aGUgc2FtZQorLy8gaW50ZXJmYWNlIHNvIHRoZSBzYW1lIHVuaXQtdGVzdCBjb2RlIGNhbiB0ZXN0IGJvdGggc2NlbmFyaW9zLgorY2xhc3MgVHlwZUluZm9UZXN0SGVscGVyIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IFR5cGVJbmZvVGVzdEhlbHBlcihUeXBlSW5mb1NvdXJjZSB0eXBlKSA6IHR5cGVfKHR5cGUpIHt9CisKKyAgLy8gQ3JlYXRlcyBhIFR5cGVJbmZvIG9iamVjdCBmb3IgdGhlIGdpdmVuIHNldCBvZiBkZXNjcmlwdG9ycy4KKyAgdm9pZCBSZXNldFR5cGVJbmZvKGNvbnN0IHZlY3Rvcjxjb25zdCBEZXNjcmlwdG9yKj4mIGRlc2NyaXB0b3JzKTsKKworICAvLyBDb252aW5lbnQgb3ZlcmxvYWRzLgorICB2b2lkIFJlc2V0VHlwZUluZm8oY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcik7CisgIHZvaWQgUmVzZXRUeXBlSW5mbyhjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yMSwKKyAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IyKTsKKworICAvLyBSZXR1cm5zIHRoZSBUeXBlSW5mbyBjcmVhdGVkIGFmdGVyIFJlc2V0VHlwZUluZm8uCisgIFR5cGVJbmZvKiBHZXRUeXBlSW5mbygpOworCisgIFByb3RvU3RyZWFtT2JqZWN0U291cmNlKiBOZXdQcm90b1NvdXJjZShpbzo6Q29kZWRJbnB1dFN0cmVhbSogY29kZWRfaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHR5cGVfdXJsKTsKKworICBQcm90b1N0cmVhbU9iamVjdFdyaXRlciogTmV3UHJvdG9Xcml0ZXIoY29uc3Qgc3RyaW5nJiB0eXBlX3VybCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ3M6OkJ5dGVTaW5rKiBvdXRwdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFcnJvckxpc3RlbmVyKiBsaXN0ZW5lcik7CisKKyAgRGVmYXVsdFZhbHVlT2JqZWN0V3JpdGVyKiBOZXdEZWZhdWx0VmFsdWVXcml0ZXIoY29uc3Qgc3RyaW5nJiB0eXBlX3VybCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0V3JpdGVyKiB3cml0ZXIpOworCisgcHJpdmF0ZToKKyAgVHlwZUluZm9Tb3VyY2UgdHlwZV87CisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8VHlwZUluZm8+IHR5cGVpbmZvXzsKKyAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxUeXBlUmVzb2x2ZXI+IHR5cGVfcmVzb2x2ZXJfOworfTsKK30gIC8vIG5hbWVzcGFjZSB0ZXN0aW5nCit9ICAvLyBuYW1lc3BhY2UgY29udmVydGVyCit9ICAvLyBuYW1lc3BhY2UgdXRpbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX1VUSUxfQ09OVkVSVEVSX1RZUEVfSU5GT19URVNUX0hFTFBFUl9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC91dGlsaXR5LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3V0aWxpdHkuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWRkZjI0OAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC91dGlsaXR5LmNjCkBAIC0wLDAgKzEsMzU2IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3V0aWxpdHkuaD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jYWxsYmFjay5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbG9nZ2luZy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi93cmFwcGVycy5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9jb25zdGFudHMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9tYXBfdXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9tYXRobGltaXRzLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSB1dGlsIHsKK25hbWVzcGFjZSBjb252ZXJ0ZXIgeworCituYW1lc3BhY2UgeworY29uc3QgU3RyaW5nUGllY2UgU2tpcFdoaXRlU3BhY2UoU3RyaW5nUGllY2Ugc3RyKSB7CisgIFN0cmluZ1BpZWNlOjpzaXplX3R5cGUgaTsKKyAgZm9yIChpID0gMDsgaSA8IHN0ci5zaXplKCkgJiYgaXNzcGFjZShzdHJbaV0pOyArK2kpIHsKKyAgfQorICBHT09HTEVfRENIRUNLKGkgPT0gc3RyLnNpemUoKSB8fCAhaXNzcGFjZShzdHJbaV0pKTsKKyAgcmV0dXJuIFN0cmluZ1BpZWNlKHN0ciwgaSk7Cit9Cit9ICAvLyBuYW1lc3BhY2UKKworYm9vbCBHZXRCb29sT3B0aW9uT3JEZWZhdWx0KAorICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8Z29vZ2xlOjpwcm90b2J1Zjo6T3B0aW9uPiYgb3B0aW9ucywKKyAgICBjb25zdCBzdHJpbmcmIG9wdGlvbl9uYW1lLCBib29sIGRlZmF1bHRfdmFsdWUpIHsKKyAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6T3B0aW9uKiBvcHQgPSBGaW5kT3B0aW9uT3JOdWxsKG9wdGlvbnMsIG9wdGlvbl9uYW1lKTsKKyAgaWYgKG9wdCA9PSBOVUxMKSB7CisgICAgcmV0dXJuIGRlZmF1bHRfdmFsdWU7CisgIH0KKyAgcmV0dXJuIEdldEJvb2xGcm9tQW55KG9wdC0+dmFsdWUoKSk7Cit9CisKK2ludDY0IEdldEludDY0T3B0aW9uT3JEZWZhdWx0KAorICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8Z29vZ2xlOjpwcm90b2J1Zjo6T3B0aW9uPiYgb3B0aW9ucywKKyAgICBjb25zdCBzdHJpbmcmIG9wdGlvbl9uYW1lLCBpbnQ2NCBkZWZhdWx0X3ZhbHVlKSB7CisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbiogb3B0ID0gRmluZE9wdGlvbk9yTnVsbChvcHRpb25zLCBvcHRpb25fbmFtZSk7CisgIGlmIChvcHQgPT0gTlVMTCkgeworICAgIHJldHVybiBkZWZhdWx0X3ZhbHVlOworICB9CisgIHJldHVybiBHZXRJbnQ2NEZyb21Bbnkob3B0LT52YWx1ZSgpKTsKK30KKworZG91YmxlIEdldERvdWJsZU9wdGlvbk9yRGVmYXVsdCgKKyAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPGdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbj4mIG9wdGlvbnMsCisgICAgY29uc3Qgc3RyaW5nJiBvcHRpb25fbmFtZSwgZG91YmxlIGRlZmF1bHRfdmFsdWUpIHsKKyAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6T3B0aW9uKiBvcHQgPSBGaW5kT3B0aW9uT3JOdWxsKG9wdGlvbnMsIG9wdGlvbl9uYW1lKTsKKyAgaWYgKG9wdCA9PSBOVUxMKSB7CisgICAgcmV0dXJuIGRlZmF1bHRfdmFsdWU7CisgIH0KKyAgcmV0dXJuIEdldERvdWJsZUZyb21Bbnkob3B0LT52YWx1ZSgpKTsKK30KKworc3RyaW5nIEdldFN0cmluZ09wdGlvbk9yRGVmYXVsdCgKKyAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPGdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbj4mIG9wdGlvbnMsCisgICAgY29uc3Qgc3RyaW5nJiBvcHRpb25fbmFtZSwgY29uc3Qgc3RyaW5nJiBkZWZhdWx0X3ZhbHVlKSB7CisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbiogb3B0ID0gRmluZE9wdGlvbk9yTnVsbChvcHRpb25zLCBvcHRpb25fbmFtZSk7CisgIGlmIChvcHQgPT0gTlVMTCkgeworICAgIHJldHVybiBkZWZhdWx0X3ZhbHVlOworICB9CisgIHJldHVybiBHZXRTdHJpbmdGcm9tQW55KG9wdC0+dmFsdWUoKSk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBUPgordm9pZCBQYXJzZUZyb21BbnkoY29uc3Qgc3RyaW5nJiBkYXRhLCBUKiByZXN1bHQpIHsKKyAgcmVzdWx0LT5QYXJzZUZyb21TdHJpbmcoZGF0YSk7Cit9CisKKy8vIFJldHVybnMgYSBib29sZWFuIHZhbHVlIGNvbnRhaW5lZCBpbiBBbnkgdHlwZS4KKy8vIFRPRE8oc2thcnZhamUpOiBBZGQgdHlwZSBjaGVja2luZyAmIGVycm9yIG1lc3NhZ2VzIGhlcmUuCitib29sIEdldEJvb2xGcm9tQW55KGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkFueSYgYW55KSB7CisgIGdvb2dsZTo6cHJvdG9idWY6OkJvb2xWYWx1ZSBiOworICBQYXJzZUZyb21BbnkoYW55LnZhbHVlKCksICZiKTsKKyAgcmV0dXJuIGIudmFsdWUoKTsKK30KKworaW50NjQgR2V0SW50NjRGcm9tQW55KGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkFueSYgYW55KSB7CisgIGdvb2dsZTo6cHJvdG9idWY6OkludDY0VmFsdWUgaTsKKyAgUGFyc2VGcm9tQW55KGFueS52YWx1ZSgpLCAmaSk7CisgIHJldHVybiBpLnZhbHVlKCk7Cit9CisKK2RvdWJsZSBHZXREb3VibGVGcm9tQW55KGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkFueSYgYW55KSB7CisgIGdvb2dsZTo6cHJvdG9idWY6OkRvdWJsZVZhbHVlIGk7CisgIFBhcnNlRnJvbUFueShhbnkudmFsdWUoKSwgJmkpOworICByZXR1cm4gaS52YWx1ZSgpOworfQorCitzdHJpbmcgR2V0U3RyaW5nRnJvbUFueShjb25zdCBnb29nbGU6OnByb3RvYnVmOjpBbnkmIGFueSkgeworICBnb29nbGU6OnByb3RvYnVmOjpTdHJpbmdWYWx1ZSBzOworICBQYXJzZUZyb21BbnkoYW55LnZhbHVlKCksICZzKTsKKyAgcmV0dXJuIHMudmFsdWUoKTsKK30KKworY29uc3QgU3RyaW5nUGllY2UgR2V0VHlwZVdpdGhvdXRVcmwoU3RyaW5nUGllY2UgdHlwZV91cmwpIHsKKyAgc2l6ZV90IGlkeCA9IHR5cGVfdXJsLnJmaW5kKCcvJyk7CisgIHJldHVybiB0eXBlX3VybC5zdWJzdHIoaWR4ICsgMSk7Cit9CisKK2NvbnN0IHN0cmluZyBHZXRGdWxsVHlwZVdpdGhVcmwoU3RyaW5nUGllY2Ugc2ltcGxlX3R5cGUpIHsKKyAgcmV0dXJuIFN0ckNhdChrVHlwZVNlcnZpY2VCYXNlVXJsLCAiLyIsIHNpbXBsZV90eXBlKTsKK30KKworY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6T3B0aW9uKiBGaW5kT3B0aW9uT3JOdWxsKAorICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8Z29vZ2xlOjpwcm90b2J1Zjo6T3B0aW9uPiYgb3B0aW9ucywKKyAgICBjb25zdCBzdHJpbmcmIG9wdGlvbl9uYW1lKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgb3B0aW9ucy5zaXplKCk7ICsraSkgeworICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbiYgb3B0ID0gb3B0aW9ucy5HZXQoaSk7CisgICAgaWYgKG9wdC5uYW1lKCkgPT0gb3B0aW9uX25hbWUpIHsKKyAgICAgIHJldHVybiAmb3B0OworICAgIH0KKyAgfQorICByZXR1cm4gTlVMTDsKK30KKworY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGQqIEZpbmRGaWVsZEluVHlwZU9yTnVsbCgKKyAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlKiB0eXBlLCBTdHJpbmdQaWVjZSBmaWVsZF9uYW1lKSB7CisgIGlmICh0eXBlICE9IE5VTEwpIHsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHR5cGUtPmZpZWxkc19zaXplKCk7ICsraSkgeworICAgICAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGQmIGZpZWxkID0gdHlwZS0+ZmllbGRzKGkpOworICAgICAgaWYgKGZpZWxkLm5hbWUoKSA9PSBmaWVsZF9uYW1lKSB7CisgICAgICAgIHJldHVybiAmZmllbGQ7CisgICAgICB9CisgICAgfQorICB9CisgIHJldHVybiBOVUxMOworfQorCitjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZCogRmluZEpzb25GaWVsZEluVHlwZU9yTnVsbCgKKyAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlKiB0eXBlLCBTdHJpbmdQaWVjZSBqc29uX25hbWUpIHsKKyAgaWYgKHR5cGUgIT0gTlVMTCkgeworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdHlwZS0+ZmllbGRzX3NpemUoKTsgKytpKSB7CisgICAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZCYgZmllbGQgPSB0eXBlLT5maWVsZHMoaSk7CisgICAgICBpZiAoZmllbGQuanNvbl9uYW1lKCkgPT0ganNvbl9uYW1lKSB7CisgICAgICAgIHJldHVybiAmZmllbGQ7CisgICAgICB9CisgICAgfQorICB9CisgIHJldHVybiBOVUxMOworfQorCitjb25zdCBnb29nbGU6OnByb3RvYnVmOjpFbnVtVmFsdWUqIEZpbmRFbnVtVmFsdWVCeU5hbWVPck51bGwoCisgICAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RW51bSogZW51bV90eXBlLCBTdHJpbmdQaWVjZSBlbnVtX25hbWUpIHsKKyAgaWYgKGVudW1fdHlwZSAhPSBOVUxMKSB7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBlbnVtX3R5cGUtPmVudW12YWx1ZV9zaXplKCk7ICsraSkgeworICAgICAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlJiBlbnVtX3ZhbHVlID0gZW51bV90eXBlLT5lbnVtdmFsdWUoaSk7CisgICAgICBpZiAoZW51bV92YWx1ZS5uYW1lKCkgPT0gZW51bV9uYW1lKSB7CisgICAgICAgIHJldHVybiAmZW51bV92YWx1ZTsKKyAgICAgIH0KKyAgICB9CisgIH0KKyAgcmV0dXJuIE5VTEw7Cit9CisKK2NvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZSogRmluZEVudW1WYWx1ZUJ5TnVtYmVyT3JOdWxsKAorICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkVudW0qIGVudW1fdHlwZSwgaW50MzIgdmFsdWUpIHsKKyAgaWYgKGVudW1fdHlwZSAhPSBOVUxMKSB7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBlbnVtX3R5cGUtPmVudW12YWx1ZV9zaXplKCk7ICsraSkgeworICAgICAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlJiBlbnVtX3ZhbHVlID0gZW51bV90eXBlLT5lbnVtdmFsdWUoaSk7CisgICAgICBpZiAoZW51bV92YWx1ZS5udW1iZXIoKSA9PSB2YWx1ZSkgeworICAgICAgICByZXR1cm4gJmVudW1fdmFsdWU7CisgICAgICB9CisgICAgfQorICB9CisgIHJldHVybiBOVUxMOworfQorCitzdHJpbmcgVG9DYW1lbENhc2UoY29uc3QgU3RyaW5nUGllY2UgaW5wdXQpIHsKKyAgYm9vbCBjYXBpdGFsaXplX25leHQgPSBmYWxzZTsKKyAgYm9vbCB3YXNfY2FwID0gdHJ1ZTsKKyAgYm9vbCBpc19jYXAgPSBmYWxzZTsKKyAgYm9vbCBmaXJzdF93b3JkID0gdHJ1ZTsKKyAgc3RyaW5nIHJlc3VsdDsKKyAgcmVzdWx0LnJlc2VydmUoaW5wdXQuc2l6ZSgpKTsKKworICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IGlucHV0LnNpemUoKTsgKytpLCB3YXNfY2FwID0gaXNfY2FwKSB7CisgICAgaXNfY2FwID0gYXNjaWlfaXN1cHBlcihpbnB1dFtpXSk7CisgICAgaWYgKGlucHV0W2ldID09ICdfJykgeworICAgICAgY2FwaXRhbGl6ZV9uZXh0ID0gdHJ1ZTsKKyAgICAgIGlmICghcmVzdWx0LmVtcHR5KCkpIGZpcnN0X3dvcmQgPSBmYWxzZTsKKyAgICAgIGNvbnRpbnVlOworICAgIH0gZWxzZSBpZiAoZmlyc3Rfd29yZCkgeworICAgICAgLy8gQ29uc2lkZXIgd2hlbiB0aGUgY3VycmVudCBjaGFyYWN0ZXIgQiBpcyBjYXBpdGFsaXplZCwKKyAgICAgIC8vIGZpcnN0IHdvcmQgZW5kcyB3aGVuOgorICAgICAgLy8gMSkgZm9sbG93aW5nIGEgbG93ZXJjYXNlOiAgICIuLi5hQi4uLiIKKyAgICAgIC8vIDIpIGZvbGxvd2VkIGJ5IGEgbG93ZXJjYXNlOiAiLi4uQUJjLi4uIgorICAgICAgaWYgKCFyZXN1bHQuZW1wdHkoKSAmJiBpc19jYXAgJiYKKyAgICAgICAgICAoIXdhc19jYXAgfHwgKGkgKyAxIDwgaW5wdXQuc2l6ZSgpICYmIGFzY2lpX2lzbG93ZXIoaW5wdXRbaSArIDFdKSkpKSB7CisgICAgICAgIGZpcnN0X3dvcmQgPSBmYWxzZTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJlc3VsdC5wdXNoX2JhY2soYXNjaWlfdG9sb3dlcihpbnB1dFtpXSkpOworICAgICAgICBjb250aW51ZTsKKyAgICAgIH0KKyAgICB9IGVsc2UgaWYgKGNhcGl0YWxpemVfbmV4dCkgeworICAgICAgY2FwaXRhbGl6ZV9uZXh0ID0gZmFsc2U7CisgICAgICBpZiAoYXNjaWlfaXNsb3dlcihpbnB1dFtpXSkpIHsKKyAgICAgICAgcmVzdWx0LnB1c2hfYmFjayhhc2NpaV90b3VwcGVyKGlucHV0W2ldKSk7CisgICAgICAgIGNvbnRpbnVlOworICAgICAgfQorICAgIH0KKyAgICByZXN1bHQucHVzaF9iYWNrKGlucHV0W2ldKTsKKyAgfQorICByZXR1cm4gcmVzdWx0OworfQorCitzdHJpbmcgVG9TbmFrZUNhc2UoU3RyaW5nUGllY2UgaW5wdXQpIHsKKyAgYm9vbCB3YXNfbm90X3VuZGVyc2NvcmUgPSBmYWxzZTsgIC8vIEluaXRpYWxpemUgdG8gZmFsc2UgZm9yIGNhc2UgMSAoYmVsb3cpCisgIGJvb2wgd2FzX25vdF9jYXAgPSBmYWxzZTsKKyAgc3RyaW5nIHJlc3VsdDsKKyAgcmVzdWx0LnJlc2VydmUoaW5wdXQuc2l6ZSgpIDw8IDEpOworCisgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgaW5wdXQuc2l6ZSgpOyArK2kpIHsKKyAgICBpZiAoYXNjaWlfaXN1cHBlcihpbnB1dFtpXSkpIHsKKyAgICAgIC8vIENvbnNpZGVyIHdoZW4gdGhlIGN1cnJlbnQgY2hhcmFjdGVyIEIgaXMgY2FwaXRhbGl6ZWQ6CisgICAgICAvLyAxKSBBdCBiZWdpbm5pbmcgb2YgaW5wdXQ6ICAgIkIuLi4iID0+ICJiLi4uIgorICAgICAgLy8gICAgKGUuZy4gIkJpc2N1aXQiID0+ICJiaXNjdWl0IikKKyAgICAgIC8vIDIpIEZvbGxvd2luZyBhIGxvd2VyY2FzZTogICAiLi4uYUIuLi4iID0+ICIuLi5hX2IuLi4iCisgICAgICAvLyAgICAoZS5nLiAiZ0Jpa2UiID0+ICJnX2Jpa2UiKQorICAgICAgLy8gMykgQXQgdGhlIGVuZCBvZiBpbnB1dDogICAgICIuLi5BQiIgPT4gIi4uLmFiIgorICAgICAgLy8gICAgKGUuZy4gIkdvb2dsZUxBQiIgPT4gImdvb2dsZV9sYWIiKQorICAgICAgLy8gNCkgRm9sbG93ZWQgYnkgYSBsb3dlcmNhc2U6ICIuLi5BQmMuLi4iID0+ICIuLi5hX2JjLi4uIgorICAgICAgLy8gICAgKGUuZy4gIkdCaWtlIiA9PiAiZ19iaWtlIikKKyAgICAgIGlmICh3YXNfbm90X3VuZGVyc2NvcmUgJiYgICAgICAgICAgICAgICAvLyAgICAgICAgICAgIGNhc2UgMSBvdXQKKyAgICAgICAgICAod2FzX25vdF9jYXAgfHwgICAgICAgICAgICAgICAgICAgICAvLyBjYXNlIDIgaW4sIGNhc2UgMyBvdXQKKyAgICAgICAgICAgKGkgKyAxIDwgaW5wdXQuc2l6ZSgpICYmICAgICAgICAgICAvLyAgICAgICAgICAgIGNhc2UgMyBvdXQKKyAgICAgICAgICAgIGFzY2lpX2lzbG93ZXIoaW5wdXRbaSArIDFdKSkpKSB7ICAvLyBjYXNlIDQgaW4KKyAgICAgICAgLy8gV2UgYWRkIGFuIHVuZGVyc2NvcmUgZm9yIGNhc2UgMiBhbmQgY2FzZSA0LgorICAgICAgICByZXN1bHQucHVzaF9iYWNrKCdfJyk7CisgICAgICB9CisgICAgICByZXN1bHQucHVzaF9iYWNrKGFzY2lpX3RvbG93ZXIoaW5wdXRbaV0pKTsKKyAgICAgIHdhc19ub3RfdW5kZXJzY29yZSA9IHRydWU7CisgICAgICB3YXNfbm90X2NhcCA9IGZhbHNlOworICAgIH0gZWxzZSB7CisgICAgICByZXN1bHQucHVzaF9iYWNrKGlucHV0W2ldKTsKKyAgICAgIHdhc19ub3RfdW5kZXJzY29yZSA9IGlucHV0W2ldICE9ICdfJzsKKyAgICAgIHdhc19ub3RfY2FwID0gdHJ1ZTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIHJlc3VsdDsKK30KKworc2V0PHN0cmluZz4qIHdlbGxfa25vd25fdHlwZXNfID0gTlVMTDsKK0dPT0dMRV9QUk9UT0JVRl9ERUNMQVJFX09OQ0Uod2VsbF9rbm93bl90eXBlc19pbml0Xyk7Citjb25zdCBjaGFyKiB3ZWxsX2tub3duX3R5cGVzX25hbWVfYXJyYXlfW10gPSB7CisgICAgImdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAiLCAgICJnb29nbGUucHJvdG9idWYuRHVyYXRpb24iLAorICAgICJnb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUiLCAiZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUiLAorICAgICJnb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSIsICAiZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIiwKKyAgICAiZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUiLCAgImdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSIsCisgICAgImdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUiLCAgICJnb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUiLAorICAgICJnb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSIsICAiZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayJ9OworCit2b2lkIERlbGV0ZVdlbGxLbm93blR5cGVzKCkgeyBkZWxldGUgd2VsbF9rbm93bl90eXBlc187IH0KKwordm9pZCBJbml0V2VsbEtub3duVHlwZXMoKSB7CisgIHdlbGxfa25vd25fdHlwZXNfID0gbmV3IHNldDxzdHJpbmc+OworICBmb3IgKGludCBpID0gMDsgaSA8IEdPT0dMRV9BUlJBWVNJWkUod2VsbF9rbm93bl90eXBlc19uYW1lX2FycmF5Xyk7ICsraSkgeworICAgIHdlbGxfa25vd25fdHlwZXNfLT5pbnNlcnQod2VsbF9rbm93bl90eXBlc19uYW1lX2FycmF5X1tpXSk7CisgIH0KKyAgZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6Ok9uU2h1dGRvd24oJkRlbGV0ZVdlbGxLbm93blR5cGVzKTsKK30KKworYm9vbCBJc1dlbGxLbm93blR5cGUoY29uc3Qgc3RyaW5nJiB0eXBlX25hbWUpIHsKKyAgSW5pdFdlbGxLbm93blR5cGVzKCk7CisgIHJldHVybiBDb250YWluc0tleSgqd2VsbF9rbm93bl90eXBlc18sIHR5cGVfbmFtZSk7Cit9CisKK2Jvb2wgSXNWYWxpZEJvb2xTdHJpbmcoY29uc3Qgc3RyaW5nJiBib29sX3N0cmluZykgeworICByZXR1cm4gYm9vbF9zdHJpbmcgPT0gInRydWUiIHx8IGJvb2xfc3RyaW5nID09ICJmYWxzZSIgfHwKKyAgICAgICAgIGJvb2xfc3RyaW5nID09ICIxIiB8fCBib29sX3N0cmluZyA9PSAiMCI7Cit9CisKK2Jvb2wgSXNNYXAoY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGQmIGZpZWxkLAorICAgICAgICAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlJiB0eXBlKSB7CisgIHJldHVybiAoZmllbGQuY2FyZGluYWxpdHkoKSA9PQorICAgICAgICAgICAgICBnb29nbGU6OnByb3RvYnVmOjpGaWVsZF9DYXJkaW5hbGl0eV9DQVJESU5BTElUWV9SRVBFQVRFRCAmJgorICAgICAgICAgIEdldEJvb2xPcHRpb25PckRlZmF1bHQodHlwZS5vcHRpb25zKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zLm1hcF9lbnRyeSIsIGZhbHNlKSk7Cit9CisKK2Jvb2wgSXNNZXNzYWdlU2V0V2lyZUZvcm1hdChjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlJiB0eXBlKSB7CisgIHJldHVybiBHZXRCb29sT3B0aW9uT3JEZWZhdWx0KAorICAgICAgdHlwZS5vcHRpb25zKCksICJnb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMubWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQiLCBmYWxzZSk7Cit9CisKK3N0cmluZyBEb3VibGVBc1N0cmluZyhkb3VibGUgdmFsdWUpIHsKKyAgaWYgKE1hdGhMaW1pdHM8ZG91YmxlPjo6SXNQb3NJbmYodmFsdWUpKSByZXR1cm4gIkluZmluaXR5IjsKKyAgaWYgKE1hdGhMaW1pdHM8ZG91YmxlPjo6SXNOZWdJbmYodmFsdWUpKSByZXR1cm4gIi1JbmZpbml0eSI7CisgIGlmIChNYXRoTGltaXRzPGRvdWJsZT46OklzTmFOKHZhbHVlKSkgcmV0dXJuICJOYU4iOworCisgIHJldHVybiBTaW1wbGVEdG9hKHZhbHVlKTsKK30KKworc3RyaW5nIEZsb2F0QXNTdHJpbmcoZmxvYXQgdmFsdWUpIHsKKyAgaWYgKE1hdGhMaW1pdHM8ZmxvYXQ+OjpJc0Zpbml0ZSh2YWx1ZSkpIHJldHVybiBTaW1wbGVGdG9hKHZhbHVlKTsKKyAgcmV0dXJuIERvdWJsZUFzU3RyaW5nKHZhbHVlKTsKK30KKworYm9vbCBTYWZlU3RyVG9GbG9hdChTdHJpbmdQaWVjZSBzdHIsIGZsb2F0KiB2YWx1ZSkgeworICBkb3VibGUgZG91YmxlX3ZhbHVlOworICBpZiAoIXNhZmVfc3RydG9kKHN0ciwgJmRvdWJsZV92YWx1ZSkpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBpZiAoTWF0aExpbWl0czxkb3VibGU+OjpJc0luZihkb3VibGVfdmFsdWUpIHx8CisgICAgICBNYXRoTGltaXRzPGRvdWJsZT46OklzTmFOKGRvdWJsZV92YWx1ZSkpCisgICAgcmV0dXJuIGZhbHNlOworCisgIC8vIEZhaWwgaWYgdGhlIHZhbHVlIGlzIG5vdCByZXByZXNlbnRhYmxlIGluIGZsb2F0LgorICBpZiAoZG91YmxlX3ZhbHVlID4gc3RkOjpudW1lcmljX2xpbWl0czxmbG9hdD46Om1heCgpIHx8CisgICAgICBkb3VibGVfdmFsdWUgPCAtc3RkOjpudW1lcmljX2xpbWl0czxmbG9hdD46Om1heCgpKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgKnZhbHVlID0gc3RhdGljX2Nhc3Q8ZmxvYXQ+KGRvdWJsZV92YWx1ZSk7CisgIHJldHVybiB0cnVlOworfQorCit9ICAvLyBuYW1lc3BhY2UgY29udmVydGVyCit9ICAvLyBuYW1lc3BhY2UgdXRpbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvdXRpbGl0eS5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3V0aWxpdHkuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zM2RmOGVkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3V0aWxpdHkuaApAQCAtMCwwICsxLDE5MyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX1VUSUxfQ09OVkVSVEVSX1VUSUxJVFlfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9VVElMX0NPTlZFUlRFUl9VVElMSVRZX0hfXworCisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDx1dGlsaXR5PgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9sb2dnaW5nLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3R5cGUucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvcmVwZWF0ZWRfZmllbGQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RyaW5ncGllY2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdGF0dXMuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RhdHVzb3IuaD4KKworCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CitjbGFzcyBNZXRob2Q7CitjbGFzcyBBbnk7CitjbGFzcyBCb29sOworY2xhc3MgT3B0aW9uOworY2xhc3MgRmllbGQ7CitjbGFzcyBUeXBlOworY2xhc3MgRW51bTsKK2NsYXNzIEVudW1WYWx1ZTsKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgdXRpbCB7CituYW1lc3BhY2UgY29udmVydGVyIHsKKy8vIEZpbmRzIHRoZSB0ZWNoIG9wdGlvbiBpZGVudGlmaWVkIGJ5IG9wdGlvbl9uYW1lLiBQYXJzZXMgdGhlIGJvb2xlYW4gdmFsdWUgYW5kCisvLyByZXR1cm5zIGl0LgorLy8gV2hlbiB0aGUgb3B0aW9uIHdpdGggdGhlIGdpdmVuIG5hbWUgaXMgbm90IGZvdW5kLCBkZWZhdWx0X3ZhbHVlIGlzIHJldHVybmVkLgorTElCUFJPVE9CVUZfRVhQT1JUIGJvb2wgR2V0Qm9vbE9wdGlvbk9yRGVmYXVsdCgKKyAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPGdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbj4mIG9wdGlvbnMsCisgICAgY29uc3Qgc3RyaW5nJiBvcHRpb25fbmFtZSwgYm9vbCBkZWZhdWx0X3ZhbHVlKTsKKworLy8gUmV0dXJucyBpbnQ2NCBvcHRpb24gdmFsdWUuIElmIHRoZSBvcHRpb24gaXNuJ3QgZm91bmQsIHJldHVybnMgdGhlCisvLyBkZWZhdWx0X3ZhbHVlLgorTElCUFJPVE9CVUZfRVhQT1JUIGludDY0IEdldEludDY0T3B0aW9uT3JEZWZhdWx0KAorICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8Z29vZ2xlOjpwcm90b2J1Zjo6T3B0aW9uPiYgb3B0aW9ucywKKyAgICBjb25zdCBzdHJpbmcmIG9wdGlvbl9uYW1lLCBpbnQ2NCBkZWZhdWx0X3ZhbHVlKTsKKworLy8gUmV0dXJucyBkb3VibGUgb3B0aW9uIHZhbHVlLiBJZiB0aGUgb3B0aW9uIGlzbid0IGZvdW5kLCByZXR1cm5zIHRoZQorLy8gZGVmYXVsdF92YWx1ZS4KK0xJQlBST1RPQlVGX0VYUE9SVCBkb3VibGUgR2V0RG91YmxlT3B0aW9uT3JEZWZhdWx0KAorICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8Z29vZ2xlOjpwcm90b2J1Zjo6T3B0aW9uPiYgb3B0aW9ucywKKyAgICBjb25zdCBzdHJpbmcmIG9wdGlvbl9uYW1lLCBkb3VibGUgZGVmYXVsdF92YWx1ZSk7CisKKy8vIFJldHVybnMgc3RyaW5nIG9wdGlvbiB2YWx1ZS4gSWYgdGhlIG9wdGlvbiBpc24ndCBmb3VuZCwgcmV0dXJucyB0aGUKKy8vIGRlZmF1bHRfdmFsdWUuCitMSUJQUk9UT0JVRl9FWFBPUlQgc3RyaW5nIEdldFN0cmluZ09wdGlvbk9yRGVmYXVsdCgKKyAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpSZXBlYXRlZFB0ckZpZWxkPGdvb2dsZTo6cHJvdG9idWY6Ok9wdGlvbj4mIG9wdGlvbnMsCisgICAgY29uc3Qgc3RyaW5nJiBvcHRpb25fbmFtZSwgY29uc3Qgc3RyaW5nJiBkZWZhdWx0X3ZhbHVlKTsKKworLy8gUmV0dXJucyBhIGJvb2xlYW4gdmFsdWUgY29udGFpbmVkIGluIEFueSB0eXBlLgorLy8gVE9ETyhza2FydmFqZSk6IE1ha2UgdGhlc2UgdXRpbGl0aWVzIGRlYWxpbmcgd2l0aCBBbnkgdHlwZXMgbW9yZSBnZW5lcmljLAorLy8gYWRkIG1vcmUgZXJyb3IgY2hlY2tpbmcgYW5kIG1vdmUgdG8gYSBtb3JlIHB1YmxpYy9zaGFyYWJsZSBsb2NhdGlvbiBzbyBvdGhlcnMKKy8vIGNhbiB1c2UuCitMSUJQUk9UT0JVRl9FWFBPUlQgYm9vbCBHZXRCb29sRnJvbUFueShjb25zdCBnb29nbGU6OnByb3RvYnVmOjpBbnkmIGFueSk7CisKKy8vIFJldHVybnMgaW50NjQgdmFsdWUgY29udGFpbmVkIGluIEFueSB0eXBlLgorTElCUFJPVE9CVUZfRVhQT1JUIGludDY0IEdldEludDY0RnJvbUFueShjb25zdCBnb29nbGU6OnByb3RvYnVmOjpBbnkmIGFueSk7CisKKy8vIFJldHVybnMgZG91YmxlIHZhbHVlIGNvbnRhaW5lZCBpbiBBbnkgdHlwZS4KK0xJQlBST1RPQlVGX0VYUE9SVCBkb3VibGUgR2V0RG91YmxlRnJvbUFueShjb25zdCBnb29nbGU6OnByb3RvYnVmOjpBbnkmIGFueSk7CisKKy8vIFJldHVybnMgc3RyaW5nIHZhbHVlIGNvbnRhaW5lZCBpbiBBbnkgdHlwZS4KK0xJQlBST1RPQlVGX0VYUE9SVCBzdHJpbmcgR2V0U3RyaW5nRnJvbUFueShjb25zdCBnb29nbGU6OnByb3RvYnVmOjpBbnkmIGFueSk7CisKKy8vIFJldHVybnMgdGhlIHR5cGUgc3RyaW5nIHdpdGhvdXQgdGhlIHVybCBwcmVmaXguIGUuZy46IElmIHRoZSBwYXNzZWQgdHlwZSBpcworLy8gJ3R5cGUuZ29vZ2xlYXBpcy5jb20vdGVjaC50eXBlLkJvb2wnLCB0aGUgcmV0dXJuZWQgdmFsdWUgaXMgJ3RlY2gudHlwZS5Cb29sJy4KK0xJQlBST1RPQlVGX0VYUE9SVCBjb25zdCBTdHJpbmdQaWVjZSBHZXRUeXBlV2l0aG91dFVybChTdHJpbmdQaWVjZSB0eXBlX3VybCk7CisKKy8vIFJldHVybnMgdGhlIHNpbXBsZV90eXBlIHdpdGggdGhlIGJhc2UgdHlwZSB1cmwgKGtUeXBlU2VydmljZUJhc2VVcmwpCisvLyBwcmVmaXhlZC4KKy8vCisvLyBFLmc6CisvLyBHZXRGdWxsVHlwZVdpdGhVcmwoImdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAiKSByZXR1cm5zIHRoZSBzdHJpbmcKKy8vICJ0eXBlLmdvb2dsZWFwaXMuY29tL2dvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAiLgorTElCUFJPVE9CVUZfRVhQT1JUIGNvbnN0IHN0cmluZyBHZXRGdWxsVHlwZVdpdGhVcmwoU3RyaW5nUGllY2Ugc2ltcGxlX3R5cGUpOworCisvLyBGaW5kcyBhbmQgcmV0dXJucyBvcHRpb24gaWRlbnRpZmllZCBieSBuYW1lIGFuZCBvcHRpb25fbmFtZSB3aXRoaW4gdGhlCisvLyBwcm92aWRlZCBtYXAuIFJldHVybnMgTlVMTCBpZiBub25lIGZvdW5kLgorY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6T3B0aW9uKiBGaW5kT3B0aW9uT3JOdWxsKAorICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlJlcGVhdGVkUHRyRmllbGQ8Z29vZ2xlOjpwcm90b2J1Zjo6T3B0aW9uPiYgb3B0aW9ucywKKyAgICBjb25zdCBzdHJpbmcmIG9wdGlvbl9uYW1lKTsKKworLy8gRmluZHMgYW5kIHJldHVybnMgdGhlIGZpZWxkIGlkZW50aWZpZWQgYnkgZmllbGRfbmFtZSBpbiB0aGUgcGFzc2VkIHRlY2ggVHlwZQorLy8gb2JqZWN0LiBSZXR1cm5zIE5VTEwgaWYgbm9uZSBmb3VuZC4KK2NvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkKiBGaW5kRmllbGRJblR5cGVPck51bGwoCisgICAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6VHlwZSogdHlwZSwgU3RyaW5nUGllY2UgZmllbGRfbmFtZSk7CisKKy8vIFNpbWlsYXIgdG8gRmluZEZpZWxkSW5UeXBlT3JOdWxsLCBidXQgdGhpcyBsb29rcyB1cCBmaWVsZHMgd2l0aCBnaXZlbgorLy8ganNvbl9uYW1lLgorY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGQqIEZpbmRKc29uRmllbGRJblR5cGVPck51bGwoCisgICAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6VHlwZSogdHlwZSwgU3RyaW5nUGllY2UganNvbl9uYW1lKTsKKworLy8gRmluZHMgYW5kIHJldHVybnMgdGhlIEVudW1WYWx1ZSBpZGVudGlmaWVkIGJ5IGVudW1fbmFtZSBpbiB0aGUgcGFzc2VkIHRlY2gKKy8vIEVudW0gb2JqZWN0LiBSZXR1cm5zIE5VTEwgaWYgbm9uZSBmb3VuZC4KK2NvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZSogRmluZEVudW1WYWx1ZUJ5TmFtZU9yTnVsbCgKKyAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpFbnVtKiBlbnVtX3R5cGUsIFN0cmluZ1BpZWNlIGVudW1fbmFtZSk7CisKKy8vIEZpbmRzIGFuZCByZXR1cm5zIHRoZSBFbnVtVmFsdWUgaWRlbnRpZmllZCBieSB2YWx1ZSBpbiB0aGUgcGFzc2VkIHRlY2gKKy8vIEVudW0gb2JqZWN0LiBSZXR1cm5zIE5VTEwgaWYgbm9uZSBmb3VuZC4KK2NvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkVudW1WYWx1ZSogRmluZEVudW1WYWx1ZUJ5TnVtYmVyT3JOdWxsKAorICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkVudW0qIGVudW1fdHlwZSwgaW50MzIgdmFsdWUpOworCisvLyBDb252ZXJ0cyBpbnB1dCB0byBjYW1lbC1jYXNlIGFuZCByZXR1cm5zIGl0LgorTElCUFJPVE9CVUZfRVhQT1JUIHN0cmluZyBUb0NhbWVsQ2FzZShjb25zdCBTdHJpbmdQaWVjZSBpbnB1dCk7CisKKy8vIENvbnZlcnRzIGlucHV0IHRvIHNuYWtlX2Nhc2UgYW5kIHJldHVybnMgaXQuCitMSUJQUk9UT0JVRl9FWFBPUlQgc3RyaW5nIFRvU25ha2VDYXNlKFN0cmluZ1BpZWNlIGlucHV0KTsKKworLy8gUmV0dXJucyB0cnVlIGlmIHR5cGVfbmFtZSByZXByZXNlbnRzIGEgd2VsbC1rbm93biB0eXBlLgorTElCUFJPVE9CVUZfRVhQT1JUIGJvb2wgSXNXZWxsS25vd25UeXBlKGNvbnN0IHN0cmluZyYgdHlwZV9uYW1lKTsKKworLy8gUmV0dXJucyB0cnVlIGlmICdib29sX3N0cmluZycgcmVwcmVzZW50cyBhIHZhbGlkIGJvb2xlYW4gdmFsdWUuIE9ubHkgInRydWUiLAorLy8gImZhbHNlIiwgIjAiIGFuZCAiMSIgYXJlIGFsbG93ZWQuCitMSUJQUk9UT0JVRl9FWFBPUlQgYm9vbCBJc1ZhbGlkQm9vbFN0cmluZyhjb25zdCBzdHJpbmcmIGJvb2xfc3RyaW5nKTsKKworLy8gUmV0dXJucyB0cnVlIGlmICJmaWVsZCIgaXMgYSBwcm90b2J1ZiBtYXAgZmllbGQgYmFzZWQgb24gaXRzIHR5cGUuCitMSUJQUk9UT0JVRl9FWFBPUlQgYm9vbCBJc01hcChjb25zdCBnb29nbGU6OnByb3RvYnVmOjpGaWVsZCYgZmllbGQsCisgICAgICAgICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlR5cGUmIHR5cGUpOworCisvLyBSZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIHR5cGUgaGFzIHNwZWNpYWwgTWVzc2FnZVNldCB3aXJlIGZvcm1hdC4KK2Jvb2wgSXNNZXNzYWdlU2V0V2lyZUZvcm1hdChjb25zdCBnb29nbGU6OnByb3RvYnVmOjpUeXBlJiB0eXBlKTsKKworLy8gSW5maW5pdHkvTmFOLWF3YXJlIGNvbnZlcnNpb24gdG8gc3RyaW5nLgorTElCUFJPVE9CVUZfRVhQT1JUIHN0cmluZyBEb3VibGVBc1N0cmluZyhkb3VibGUgdmFsdWUpOworTElCUFJPVE9CVUZfRVhQT1JUIHN0cmluZyBGbG9hdEFzU3RyaW5nKGZsb2F0IHZhbHVlKTsKKworLy8gQ29udmVydCBmcm9tIGludDMyLCBpbnQ2NCwgdWludDMyLCB1aW50NjQsIGRvdWJsZSBvciBmbG9hdCB0byBzdHJpbmcuCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4KK3N0cmluZyBWYWx1ZUFzU3RyaW5nKFQgdmFsdWUpIHsKKyAgcmV0dXJuIFNpbXBsZUl0b2EodmFsdWUpOworfQorCit0ZW1wbGF0ZSA8PgoraW5saW5lIHN0cmluZyBWYWx1ZUFzU3RyaW5nKGZsb2F0IHZhbHVlKSB7CisgIHJldHVybiBGbG9hdEFzU3RyaW5nKHZhbHVlKTsKK30KKwordGVtcGxhdGUgPD4KK2lubGluZSBzdHJpbmcgVmFsdWVBc1N0cmluZyhkb3VibGUgdmFsdWUpIHsKKyAgcmV0dXJuIERvdWJsZUFzU3RyaW5nKHZhbHVlKTsKK30KKworLy8gQ29udmVydHMgYSBzdHJpbmcgdG8gZmxvYXQuIFVubGlrZSBzYWZlX3N0cnRvZiwgY29udmVyc2lvbiB3aWxsIGZhaWwgaWYgdGhlCisvLyB2YWx1ZSBmaXRzIGludG8gZG91YmxlIGJ1dCBub3QgZmxvYXQgKGUuZy4sIERCTF9NQVgpLgorTElCUFJPVE9CVUZfRVhQT1JUIGJvb2wgU2FmZVN0clRvRmxvYXQoU3RyaW5nUGllY2Ugc3RyLCBmbG9hdCogdmFsdWUpOworfSAgLy8gbmFtZXNwYWNlIGNvbnZlcnRlcgorfSAgLy8gbmFtZXNwYWNlIHV0aWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9VVElMX0NPTlZFUlRFUl9VVElMSVRZX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2pzb25fZm9ybWF0X3Byb3RvMy5wcm90byBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9qc29uX2Zvcm1hdF9wcm90bzMucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTFlMjRjMQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9qc29uX2Zvcm1hdF9wcm90bzMucHJvdG8KQEAgLTAsMCArMSwxNzYgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCitzeW50YXggPSAicHJvdG8zIjsKKworcGFja2FnZSBwcm90bzM7CisKKworaW1wb3J0ICJnb29nbGUvcHJvdG9idWYvZHVyYXRpb24ucHJvdG8iOworaW1wb3J0ICJnb29nbGUvcHJvdG9idWYvdGltZXN0YW1wLnByb3RvIjsKK2ltcG9ydCAiZ29vZ2xlL3Byb3RvYnVmL3dyYXBwZXJzLnByb3RvIjsKK2ltcG9ydCAiZ29vZ2xlL3Byb3RvYnVmL3N0cnVjdC5wcm90byI7CitpbXBvcnQgImdvb2dsZS9wcm90b2J1Zi9hbnkucHJvdG8iOworaW1wb3J0ICJnb29nbGUvcHJvdG9idWYvZmllbGRfbWFzay5wcm90byI7CisKK2VudW0gRW51bVR5cGUgeworICBGT08gPSAwOworICBCQVIgPSAxOworfQorCittZXNzYWdlIE1lc3NhZ2VUeXBlIHsKKyAgaW50MzIgdmFsdWUgPSAxOworfQorCittZXNzYWdlIFRlc3RNZXNzYWdlIHsKKyAgYm9vbCBib29sX3ZhbHVlID0gMTsKKyAgaW50MzIgaW50MzJfdmFsdWUgPSAyOworICBpbnQ2NCBpbnQ2NF92YWx1ZSA9IDM7CisgIHVpbnQzMiB1aW50MzJfdmFsdWUgPSA0OworICB1aW50NjQgdWludDY0X3ZhbHVlID0gNTsKKyAgZmxvYXQgZmxvYXRfdmFsdWUgPSA2OworICBkb3VibGUgZG91YmxlX3ZhbHVlID0gNzsKKyAgc3RyaW5nIHN0cmluZ192YWx1ZSA9IDg7CisgIGJ5dGVzIGJ5dGVzX3ZhbHVlID0gOTsKKyAgRW51bVR5cGUgZW51bV92YWx1ZSA9IDEwOworICBNZXNzYWdlVHlwZSBtZXNzYWdlX3ZhbHVlID0gMTE7CisKKyAgcmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sX3ZhbHVlID0gMjE7CisgIHJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyX3ZhbHVlID0gMjI7CisgIHJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0X3ZhbHVlID0gMjM7CisgIHJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzJfdmFsdWUgPSAyNDsKKyAgcmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NF92YWx1ZSA9IDI1OworICByZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdF92YWx1ZSA9IDI2OworICByZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlX3ZhbHVlID0gMjc7CisgIHJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfdmFsdWUgPSAyODsKKyAgcmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXNfdmFsdWUgPSAyOTsKKyAgcmVwZWF0ZWQgRW51bVR5cGUgcmVwZWF0ZWRfZW51bV92YWx1ZSA9IDMwOworICByZXBlYXRlZCBNZXNzYWdlVHlwZSByZXBlYXRlZF9tZXNzYWdlX3ZhbHVlID0gMzE7Cit9CisKK21lc3NhZ2UgVGVzdE9uZW9mIHsKKyAgLy8gSW4gSlNPTiBmb3JtYXQgb25lb2YgZmllbGRzIGJlaGF2ZSBtb3N0bHkgdGhlIHNhbWUgYXMgb3B0aW9uYWwKKyAgLy8gZmllbGRzIGV4Y2VwdCB0aGF0OgorICAvLyAgIDEuIE9uZW9mIGZpZWxkcyBoYXZlIGZpZWxkIHByZXNlbmNlIGluZm9ybWF0aW9uIGFuZCB3aWxsIGJlCisgIC8vICAgICAgcHJpbnRlZCBpZiBpdCdzIHNldCBubyBtYXR0ZXIgd2hldGhlciBpdCdzIHRoZSBkZWZhdWx0IHZhbHVlLgorICAvLyAgIDIuIE11bHRpcGxlIG9uZW9mIGZpZWxkcyBpbiB0aGUgc2FtZSBvbmVvZiBjYW5ub3QgYXBwZWFyIGF0IHRoZQorICAvLyAgICAgIHNhbWUgdGltZSBpbiB0aGUgaW5wdXQuCisgIG9uZW9mIG9uZW9mX3ZhbHVlIHsKKyAgICBpbnQzMiBvbmVvZl9pbnQzMl92YWx1ZSA9IDE7CisgICAgc3RyaW5nIG9uZW9mX3N0cmluZ192YWx1ZSA9IDI7CisgICAgYnl0ZXMgb25lb2ZfYnl0ZXNfdmFsdWUgPSAzOworICAgIEVudW1UeXBlIG9uZW9mX2VudW1fdmFsdWUgPSA0OworICAgIE1lc3NhZ2VUeXBlIG9uZW9mX21lc3NhZ2VfdmFsdWUgPSA1OworICB9Cit9CisKK21lc3NhZ2UgVGVzdE1hcCB7CisgIG1hcDxib29sLCBpbnQzMj4gYm9vbF9tYXAgPSAxOworICBtYXA8aW50MzIsIGludDMyPiBpbnQzMl9tYXAgPSAyOworICBtYXA8aW50NjQsIGludDMyPiBpbnQ2NF9tYXAgPSAzOworICBtYXA8dWludDMyLCBpbnQzMj4gdWludDMyX21hcCA9IDQ7CisgIG1hcDx1aW50NjQsIGludDMyPiB1aW50NjRfbWFwID0gNTsKKyAgbWFwPHN0cmluZywgaW50MzI+IHN0cmluZ19tYXAgPSA2OworfQorCittZXNzYWdlIFRlc3ROZXN0ZWRNYXAgeworICBtYXA8Ym9vbCwgaW50MzI+IGJvb2xfbWFwID0gMTsKKyAgbWFwPGludDMyLCBpbnQzMj4gaW50MzJfbWFwID0gMjsKKyAgbWFwPGludDY0LCBpbnQzMj4gaW50NjRfbWFwID0gMzsKKyAgbWFwPHVpbnQzMiwgaW50MzI+IHVpbnQzMl9tYXAgPSA0OworICBtYXA8dWludDY0LCBpbnQzMj4gdWludDY0X21hcCA9IDU7CisgIG1hcDxzdHJpbmcsIGludDMyPiBzdHJpbmdfbWFwID0gNjsKKyAgbWFwPHN0cmluZywgVGVzdE5lc3RlZE1hcD4gbWFwX21hcCA9IDc7Cit9CisKK21lc3NhZ2UgVGVzdFdyYXBwZXIgeworICBnb29nbGUucHJvdG9idWYuQm9vbFZhbHVlIGJvb2xfdmFsdWUgPSAxOworICBnb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBpbnQzMl92YWx1ZSA9IDI7CisgIGdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGludDY0X3ZhbHVlID0gMzsKKyAgZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlIHVpbnQzMl92YWx1ZSA9IDQ7CisgIGdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSB1aW50NjRfdmFsdWUgPSA1OworICBnb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSBmbG9hdF92YWx1ZSA9IDY7CisgIGdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBkb3VibGVfdmFsdWUgPSA3OworICBnb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUgc3RyaW5nX3ZhbHVlID0gODsKKyAgZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUgYnl0ZXNfdmFsdWUgPSA5OworCisgIHJlcGVhdGVkIGdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgcmVwZWF0ZWRfYm9vbF92YWx1ZSA9IDExOworICByZXBlYXRlZCBnb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSByZXBlYXRlZF9pbnQzMl92YWx1ZSA9IDEyOworICByZXBlYXRlZCBnb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSByZXBlYXRlZF9pbnQ2NF92YWx1ZSA9IDEzOworICByZXBlYXRlZCBnb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgcmVwZWF0ZWRfdWludDMyX3ZhbHVlID0gMTQ7CisgIHJlcGVhdGVkIGdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSByZXBlYXRlZF91aW50NjRfdmFsdWUgPSAxNTsKKyAgcmVwZWF0ZWQgZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgcmVwZWF0ZWRfZmxvYXRfdmFsdWUgPSAxNjsKKyAgcmVwZWF0ZWQgZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlIHJlcGVhdGVkX2RvdWJsZV92YWx1ZSA9IDE3OworICByZXBlYXRlZCBnb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUgcmVwZWF0ZWRfc3RyaW5nX3ZhbHVlID0gMTg7CisgIHJlcGVhdGVkIGdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIHJlcGVhdGVkX2J5dGVzX3ZhbHVlID0gMTk7Cit9CisKK21lc3NhZ2UgVGVzdFRpbWVzdGFtcCB7CisgIGdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAgdmFsdWUgPSAxOworICByZXBlYXRlZCBnb29nbGUucHJvdG9idWYuVGltZXN0YW1wIHJlcGVhdGVkX3ZhbHVlID0gMjsKK30KKworbWVzc2FnZSBUZXN0RHVyYXRpb24geworICBnb29nbGUucHJvdG9idWYuRHVyYXRpb24gdmFsdWUgPSAxOworICByZXBlYXRlZCBnb29nbGUucHJvdG9idWYuRHVyYXRpb24gcmVwZWF0ZWRfdmFsdWUgPSAyOworfQorCittZXNzYWdlIFRlc3RGaWVsZE1hc2sgeworICBnb29nbGUucHJvdG9idWYuRmllbGRNYXNrIHZhbHVlID0gMTsKK30KKworbWVzc2FnZSBUZXN0U3RydWN0IHsKKyAgZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCB2YWx1ZSA9IDE7CisgIHJlcGVhdGVkIGdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QgcmVwZWF0ZWRfdmFsdWUgPSAyOworfQorCittZXNzYWdlIFRlc3RBbnkgeworICBnb29nbGUucHJvdG9idWYuQW55IHZhbHVlID0gMTsKKyAgcmVwZWF0ZWQgZ29vZ2xlLnByb3RvYnVmLkFueSByZXBlYXRlZF92YWx1ZSA9IDI7Cit9CisKK21lc3NhZ2UgVGVzdFZhbHVlIHsKKyAgZ29vZ2xlLnByb3RvYnVmLlZhbHVlIHZhbHVlID0gMTsKKyAgcmVwZWF0ZWQgZ29vZ2xlLnByb3RvYnVmLlZhbHVlIHJlcGVhdGVkX3ZhbHVlID0gMjsKK30KKworbWVzc2FnZSBUZXN0TGlzdFZhbHVlIHsKKyAgZ29vZ2xlLnByb3RvYnVmLkxpc3RWYWx1ZSB2YWx1ZSA9IDE7CisgIHJlcGVhdGVkIGdvb2dsZS5wcm90b2J1Zi5MaXN0VmFsdWUgcmVwZWF0ZWRfdmFsdWUgPSAyOworfQorCittZXNzYWdlIFRlc3RCb29sVmFsdWUgeworICBib29sIGJvb2xfdmFsdWUgPSAxOworICBtYXA8Ym9vbCwgaW50MzI+IGJvb2xfbWFwID0gMjsKK30KKworbWVzc2FnZSBUZXN0Q3VzdG9tSnNvbk5hbWUgeworICBpbnQzMiB2YWx1ZSA9IDEgW2pzb25fbmFtZSA9ICJAdmFsdWUiXTsKK30KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9qc29uX3V0aWwuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvanNvbl91dGlsLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMzYjhkNTAKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvanNvbl91dGlsLmNjCkBAIC0wLDAgKzEsMTQwIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2pzb25fdXRpbC5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL2RlZmF1bHRfdmFsdWVfb2JqZWN0d3JpdGVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3V0aWwvaW50ZXJuYWwvZXJyb3JfbGlzdGVuZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9pbnRlcm5hbC9qc29uX29iamVjdHdyaXRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL2pzb25fc3RyZWFtX3BhcnNlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3Byb3Rvc3RyZWFtX29iamVjdHNvdXJjZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3Byb3Rvc3RyZWFtX29iamVjdHdyaXRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL3R5cGVfcmVzb2x2ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC90eXBlX3Jlc29sdmVyX3V0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvYnl0ZXN0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdGF0dXNfbWFjcm9zLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSB1dGlsIHsKKworbmFtZXNwYWNlIGludGVybmFsIHsKK3ZvaWQgWmVyb0NvcHlTdHJlYW1CeXRlU2luazo6QXBwZW5kKGNvbnN0IGNoYXIqIGJ5dGVzLCBzaXplX3QgbGVuKSB7CisgIHdoaWxlIChsZW4gPiAwKSB7CisgICAgdm9pZCogYnVmZmVyOworICAgIGludCBsZW5ndGg7CisgICAgaWYgKCFzdHJlYW1fLT5OZXh0KCZidWZmZXIsICZsZW5ndGgpKSB7CisgICAgICAvLyBUaGVyZSBpc24ndCBhIHdheSBmb3IgQnl0ZVNpbmsgdG8gcmVwb3J0IGVycm9ycy4KKyAgICAgIHJldHVybjsKKyAgICB9CisgICAgaWYgKGxlbiA8IGxlbmd0aCkgeworICAgICAgbWVtY3B5KGJ1ZmZlciwgYnl0ZXMsIGxlbik7CisgICAgICBzdHJlYW1fLT5CYWNrVXAobGVuZ3RoIC0gbGVuKTsKKyAgICAgIGJyZWFrOworICAgIH0gZWxzZSB7CisgICAgICBtZW1jcHkoYnVmZmVyLCBieXRlcywgbGVuZ3RoKTsKKyAgICAgIGJ5dGVzICs9IGxlbmd0aDsKKyAgICAgIGxlbiAtPSBsZW5ndGg7CisgICAgfQorICB9Cit9Cit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKKwordXRpbDo6U3RhdHVzIEJpbmFyeVRvSnNvblN0cmVhbShUeXBlUmVzb2x2ZXIqIHJlc29sdmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgdHlwZV91cmwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86Olplcm9Db3B5SW5wdXRTdHJlYW0qIGJpbmFyeV9pbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0qIGpzb25fb3V0cHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEpzb25PcHRpb25zJiBvcHRpb25zKSB7CisgIGlvOjpDb2RlZElucHV0U3RyZWFtIGluX3N0cmVhbShiaW5hcnlfaW5wdXQpOworICBnb29nbGU6OnByb3RvYnVmOjpUeXBlIHR5cGU7CisgIFJFVFVSTl9JRl9FUlJPUihyZXNvbHZlci0+UmVzb2x2ZU1lc3NhZ2VUeXBlKHR5cGVfdXJsLCAmdHlwZSkpOworICBjb252ZXJ0ZXI6OlByb3RvU3RyZWFtT2JqZWN0U291cmNlIHByb3RvX3NvdXJjZSgmaW5fc3RyZWFtLCByZXNvbHZlciwgdHlwZSk7CisgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSBvdXRfc3RyZWFtKGpzb25fb3V0cHV0KTsKKyAgY29udmVydGVyOjpKc29uT2JqZWN0V3JpdGVyIGpzb25fd3JpdGVyKG9wdGlvbnMuYWRkX3doaXRlc3BhY2UgPyAiICIgOiAiIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZvdXRfc3RyZWFtKTsKKyAgaWYgKG9wdGlvbnMuYWx3YXlzX3ByaW50X3ByaW1pdGl2ZV9maWVsZHMpIHsKKyAgICBjb252ZXJ0ZXI6OkRlZmF1bHRWYWx1ZU9iamVjdFdyaXRlciBkZWZhdWx0X3ZhbHVlX3dyaXRlcigKKyAgICAgICAgcmVzb2x2ZXIsIHR5cGUsICZqc29uX3dyaXRlcik7CisgICAgcmV0dXJuIHByb3RvX3NvdXJjZS5Xcml0ZVRvKCZkZWZhdWx0X3ZhbHVlX3dyaXRlcik7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIHByb3RvX3NvdXJjZS5Xcml0ZVRvKCZqc29uX3dyaXRlcik7CisgIH0KK30KKwordXRpbDo6U3RhdHVzIEJpbmFyeVRvSnNvblN0cmluZyhUeXBlUmVzb2x2ZXIqIHJlc29sdmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgdHlwZV91cmwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBiaW5hcnlfaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nKiBqc29uX291dHB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBKc29uT3B0aW9ucyYgb3B0aW9ucykgeworICBpbzo6QXJyYXlJbnB1dFN0cmVhbSBpbnB1dF9zdHJlYW0oYmluYXJ5X2lucHV0LmRhdGEoKSwgYmluYXJ5X2lucHV0LnNpemUoKSk7CisgIGlvOjpTdHJpbmdPdXRwdXRTdHJlYW0gb3V0cHV0X3N0cmVhbShqc29uX291dHB1dCk7CisgIHJldHVybiBCaW5hcnlUb0pzb25TdHJlYW0ocmVzb2x2ZXIsIHR5cGVfdXJsLCAmaW5wdXRfc3RyZWFtLCAmb3V0cHV0X3N0cmVhbSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zKTsKK30KKwordXRpbDo6U3RhdHVzIEpzb25Ub0JpbmFyeVN0cmVhbShUeXBlUmVzb2x2ZXIqIHJlc29sdmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgdHlwZV91cmwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86Olplcm9Db3B5SW5wdXRTdHJlYW0qIGpzb25faW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86Olplcm9Db3B5T3V0cHV0U3RyZWFtKiBiaW5hcnlfb3V0cHV0KSB7CisgIGdvb2dsZTo6cHJvdG9idWY6OlR5cGUgdHlwZTsKKyAgUkVUVVJOX0lGX0VSUk9SKHJlc29sdmVyLT5SZXNvbHZlTWVzc2FnZVR5cGUodHlwZV91cmwsICZ0eXBlKSk7CisgIGludGVybmFsOjpaZXJvQ29weVN0cmVhbUJ5dGVTaW5rIHNpbmsoYmluYXJ5X291dHB1dCk7CisgIGNvbnZlcnRlcjo6Tm9vcEVycm9yTGlzdGVuZXIgbGlzdGVuZXI7CisgIGNvbnZlcnRlcjo6UHJvdG9TdHJlYW1PYmplY3RXcml0ZXIgcHJvdG9fd3JpdGVyKHJlc29sdmVyLCB0eXBlLCAmc2luaywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmxpc3RlbmVyKTsKKworICBjb252ZXJ0ZXI6Okpzb25TdHJlYW1QYXJzZXIgcGFyc2VyKCZwcm90b193cml0ZXIpOworICBjb25zdCB2b2lkKiBidWZmZXI7CisgIGludCBsZW5ndGg7CisgIHdoaWxlIChqc29uX2lucHV0LT5OZXh0KCZidWZmZXIsICZsZW5ndGgpKSB7CisgICAgaWYgKGxlbmd0aCA9PSAwKSBjb250aW51ZTsKKyAgICBSRVRVUk5fSUZfRVJST1IoCisgICAgICAgIHBhcnNlci5QYXJzZShTdHJpbmdQaWVjZShzdGF0aWNfY2FzdDxjb25zdCBjaGFyKj4oYnVmZmVyKSwgbGVuZ3RoKSkpOworICB9CisgIFJFVFVSTl9JRl9FUlJPUihwYXJzZXIuRmluaXNoUGFyc2UoKSk7CisKKyAgcmV0dXJuIHV0aWw6OlN0YXR1czo6T0s7Cit9CisKK3V0aWw6OlN0YXR1cyBKc29uVG9CaW5hcnlTdHJpbmcoVHlwZVJlc29sdmVyKiByZXNvbHZlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHR5cGVfdXJsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYganNvbl9pbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcqIGJpbmFyeV9vdXRwdXQpIHsKKyAgaW86OkFycmF5SW5wdXRTdHJlYW0gaW5wdXRfc3RyZWFtKGpzb25faW5wdXQuZGF0YSgpLCBqc29uX2lucHV0LnNpemUoKSk7CisgIGlvOjpTdHJpbmdPdXRwdXRTdHJlYW0gb3V0cHV0X3N0cmVhbShiaW5hcnlfb3V0cHV0KTsKKyAgcmV0dXJuIEpzb25Ub0JpbmFyeVN0cmVhbShyZXNvbHZlciwgdHlwZV91cmwsICZpbnB1dF9zdHJlYW0sICZvdXRwdXRfc3RyZWFtKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIHV0aWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2pzb25fdXRpbC5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2pzb25fdXRpbC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE3MThiZmIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvanNvbl91dGlsLmgKQEAgLTAsMCArMSwxMzYgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBVdGlsaXR5IGZ1bmN0aW9ucyB0byBjb252ZXJ0IGJldHdlZW4gcHJvdG9idWYgYmluYXJ5IGZvcm1hdCBhbmQgcHJvdG8zIEpTT04KKy8vIGZvcm1hdC4KKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX1VUSUxfSlNPTl9VVElMX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfVVRJTF9KU09OX1VUSUxfSF9fCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC90eXBlX3Jlc29sdmVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2J5dGVzdHJlYW0uaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGlvIHsKK2NsYXNzIFplcm9Db3B5SW5wdXRTdHJlYW07CitjbGFzcyBaZXJvQ29weU91dHB1dFN0cmVhbTsKK30gIC8vIG5hbWVzcGFjZSBpbworbmFtZXNwYWNlIHV0aWwgeworCitzdHJ1Y3QgSnNvbk9wdGlvbnMgeworICAvLyBXaGV0aGVyIHRvIGFkZCBzcGFjZXMsIGxpbmUgYnJlYWtzIGFuZCBpbmRlbnRhdGlvbiB0byBtYWtlIHRoZSBKU09OIG91dHB1dAorICAvLyBlYXN5IHRvIHJlYWQuCisgIGJvb2wgYWRkX3doaXRlc3BhY2U7CisgIC8vIFdoZXRoZXIgdG8gYWx3YXlzIHByaW50IHByaW1pdGl2ZSBmaWVsZHMuIEJ5IGRlZmF1bHQgcHJpbWl0aXZlIGZpZWxkcyB3aXRoCisgIC8vIGRlZmF1bHQgdmFsdWVzIHdpbGwgYmUgb21pdHRlZCBpbiBKU09OIGpvdXRwdXQuIEZvciBleGFtcGxlLCBhbiBpbnQzMiBmaWVsZAorICAvLyBzZXQgdG8gMCB3aWxsIGJlIG9taXR0ZWQuIFNldCB0aGlzIGZsYWcgdG8gdHJ1ZSB3aWxsIG92ZXJyaWRlIHRoZSBkZWZhdWx0CisgIC8vIGJlaGF2aW9yIGFuZCBwcmludCBwcmltaXRpdmUgZmllbGRzIHJlZ2FyZGxlc3Mgb2YgdGhlaXIgdmFsdWVzLgorICBib29sIGFsd2F5c19wcmludF9wcmltaXRpdmVfZmllbGRzOworCisgIEpzb25PcHRpb25zKCkgOiBhZGRfd2hpdGVzcGFjZShmYWxzZSksCisgICAgICAgICAgICAgICAgICBhbHdheXNfcHJpbnRfcHJpbWl0aXZlX2ZpZWxkcyhmYWxzZSkgeworICB9Cit9OworCisvLyBDb252ZXJ0cyBwcm90b2J1ZiBiaW5hcnkgZGF0YSB0byBKU09OLgorLy8gVGhlIGNvbnZlcnNpb24gd2lsbCBmYWlsIGlmOgorLy8gICAxLiBUeXBlUmVzb2x2ZXIgZmFpbHMgdG8gcmVzb2x2ZSBhIHR5cGUuCisvLyAgIDIuIGlucHV0IGlzIG5vdCB2YWxpZCBwcm90b2J1ZiB3aXJlIGZvcm1hdCwgb3IgY29uZmxpY3RzIHdpdGggdGhlIHR5cGUKKy8vICAgICAgaW5mb3JtYXRpb24gcmV0dXJuZWQgYnkgVHlwZVJlc29sdmVyLgorLy8gTm90ZSB0aGF0IHVua25vd24gZmllbGRzIHdpbGwgYmUgZGlzY2FyZGVkIHNpbGVudGx5LgordXRpbDo6U3RhdHVzIEJpbmFyeVRvSnNvblN0cmVhbSgKKyAgICBUeXBlUmVzb2x2ZXIqIHJlc29sdmVyLAorICAgIGNvbnN0IHN0cmluZyYgdHlwZV91cmwsCisgICAgaW86Olplcm9Db3B5SW5wdXRTdHJlYW0qIGJpbmFyeV9pbnB1dCwKKyAgICBpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0qIGpzb25fb3V0cHV0LAorICAgIGNvbnN0IEpzb25PcHRpb25zJiBvcHRpb25zKTsKKworaW5saW5lIHV0aWw6OlN0YXR1cyBCaW5hcnlUb0pzb25TdHJlYW0oCisgICAgVHlwZVJlc29sdmVyKiByZXNvbHZlciwgY29uc3Qgc3RyaW5nJiB0eXBlX3VybCwKKyAgICBpbzo6WmVyb0NvcHlJbnB1dFN0cmVhbSogYmluYXJ5X2lucHV0LAorICAgIGlvOjpaZXJvQ29weU91dHB1dFN0cmVhbSoganNvbl9vdXRwdXQpIHsKKyAgcmV0dXJuIEJpbmFyeVRvSnNvblN0cmVhbShyZXNvbHZlciwgdHlwZV91cmwsIGJpbmFyeV9pbnB1dCwganNvbl9vdXRwdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgSnNvbk9wdGlvbnMoKSk7Cit9CisKK0xJQlBST1RPQlVGX0VYUE9SVCB1dGlsOjpTdGF0dXMgQmluYXJ5VG9Kc29uU3RyaW5nKAorICAgIFR5cGVSZXNvbHZlciogcmVzb2x2ZXIsCisgICAgY29uc3Qgc3RyaW5nJiB0eXBlX3VybCwKKyAgICBjb25zdCBzdHJpbmcmIGJpbmFyeV9pbnB1dCwKKyAgICBzdHJpbmcqIGpzb25fb3V0cHV0LAorICAgIGNvbnN0IEpzb25PcHRpb25zJiBvcHRpb25zKTsKKworaW5saW5lIHV0aWw6OlN0YXR1cyBCaW5hcnlUb0pzb25TdHJpbmcoVHlwZVJlc29sdmVyKiByZXNvbHZlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiB0eXBlX3VybCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBiaW5hcnlfaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyoganNvbl9vdXRwdXQpIHsKKyAgcmV0dXJuIEJpbmFyeVRvSnNvblN0cmluZyhyZXNvbHZlciwgdHlwZV91cmwsIGJpbmFyeV9pbnB1dCwganNvbl9vdXRwdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgSnNvbk9wdGlvbnMoKSk7Cit9CisKKy8vIENvbnZlcnRzIEpTT04gZGF0YSB0byBwcm90b2J1ZiBiaW5hcnkgZm9ybWF0LgorLy8gVGhlIGNvbnZlcnNpb24gd2lsbCBmYWlsIGlmOgorLy8gICAxLiBUeXBlUmVzb2x2ZXIgZmFpbHMgdG8gcmVzb2x2ZSBhIHR5cGUuCisvLyAgIDIuIGlucHV0IGlzIG5vdCB2YWxpZCBKU09OIGZvcm1hdCwgb3IgY29uZmxpY3RzIHdpdGggdGhlIHR5cGUKKy8vICAgICAgaW5mb3JtYXRpb24gcmV0dXJuZWQgYnkgVHlwZVJlc29sdmVyLgorLy8gICAzLiBpbnB1dCBoYXMgdW5rbm93biBmaWVsZHMuCit1dGlsOjpTdGF0dXMgSnNvblRvQmluYXJ5U3RyZWFtKAorICAgIFR5cGVSZXNvbHZlciogcmVzb2x2ZXIsCisgICAgY29uc3Qgc3RyaW5nJiB0eXBlX3VybCwKKyAgICBpbzo6WmVyb0NvcHlJbnB1dFN0cmVhbSoganNvbl9pbnB1dCwKKyAgICBpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0qIGJpbmFyeV9vdXRwdXQpOworCitMSUJQUk9UT0JVRl9FWFBPUlQgdXRpbDo6U3RhdHVzIEpzb25Ub0JpbmFyeVN0cmluZygKKyAgICBUeXBlUmVzb2x2ZXIqIHJlc29sdmVyLAorICAgIGNvbnN0IHN0cmluZyYgdHlwZV91cmwsCisgICAgY29uc3Qgc3RyaW5nJiBqc29uX2lucHV0LAorICAgIHN0cmluZyogYmluYXJ5X291dHB1dCk7CisKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisvLyBJbnRlcm5hbCBoZWxwZXIgY2xhc3MuIFB1dCBpbiB0aGUgaGVhZGVyIHNvIHdlIGNhbiB3cml0ZSB1bml0LXRlc3RzIGZvciBpdC4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBaZXJvQ29weVN0cmVhbUJ5dGVTaW5rIDogcHVibGljIHN0cmluZ3M6OkJ5dGVTaW5rIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IFplcm9Db3B5U3RyZWFtQnl0ZVNpbmsoaW86Olplcm9Db3B5T3V0cHV0U3RyZWFtKiBzdHJlYW0pCisgICAgICA6IHN0cmVhbV8oc3RyZWFtKSB7fQorCisgIHZpcnR1YWwgdm9pZCBBcHBlbmQoY29uc3QgY2hhciogYnl0ZXMsIHNpemVfdCBsZW4pOworCisgcHJpdmF0ZToKKyAgaW86Olplcm9Db3B5T3V0cHV0U3RyZWFtKiBzdHJlYW1fOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhaZXJvQ29weVN0cmVhbUJ5dGVTaW5rKTsKK307Cit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKKworfSAgLy8gbmFtZXNwYWNlIHV0aWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9VVElMX0pTT05fVVRJTF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9qc29uX3V0aWxfdGVzdC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9qc29uX3V0aWxfdGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kYTY4NDk1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL2pzb25fdXRpbF90ZXN0LmNjCkBAIC0wLDAgKzEsMjg5IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2pzb25fdXRpbC5oPgorCisjaW5jbHVkZSA8bGlzdD4KKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vemVyb19jb3B5X3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2pzb25fZm9ybWF0X3Byb3RvMy5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL3R5cGVfcmVzb2x2ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC90eXBlX3Jlc29sdmVyX3V0aWwuaD4KKyNpbmNsdWRlIDxndGVzdC9ndGVzdC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgdXRpbCB7CituYW1lc3BhY2UgeworCit1c2luZyBwcm90bzM6OkZPTzsKK3VzaW5nIHByb3RvMzo6QkFSOwordXNpbmcgcHJvdG8zOjpUZXN0TWVzc2FnZTsKK3VzaW5nIHByb3RvMzo6VGVzdE1hcDsKKworc3RhdGljIGNvbnN0IGNoYXIga1R5cGVVcmxQcmVmaXhbXSA9ICJ0eXBlLmdvb2dsZWFwaXMuY29tIjsKKworc3RhdGljIHN0cmluZyBHZXRUeXBlVXJsKGNvbnN0IERlc2NyaXB0b3IqIG1lc3NhZ2UpIHsKKyAgcmV0dXJuIHN0cmluZyhrVHlwZVVybFByZWZpeCkgKyAiLyIgKyBtZXNzYWdlLT5mdWxsX25hbWUoKTsKK30KKworLy8gQXMgZnVuY3Rpb25zIGRlZmluZWQgaW4ganNvbl91dGlsLmggYXJlIGp1c3QgdGhpbiB3cmFwcGVycyBhcm91bmQgdGhlCisvLyBKU09OIGNvbnZlcnNpb24gY29kZSBpbiAvL25ldC9wcm90bzIvdXRpbC9jb252ZXJ0ZXIsIGluIHRoaXMgdGVzdCB3ZQorLy8gb25seSBjb3ZlciBzb21lIHZlcnkgYmFzaWMgY2FzZXMgdG8gbWFrZSBzdXJlIHRoZSB3cmFwcGVycyBoYXZlIGZvcndhcmRlZAorLy8gcGFyYW1ldGVycyB0byB0aGUgdW5kZXJseWluZyBpbXBsZW1lbnRhdGlvbiBjb3JyZWN0bHkuIE1vcmUgZGV0YWlsZWQKKy8vIHRlc3RzIGFyZSBjb250YWluZWQgaW4gdGhlIC8vbmV0L3Byb3RvMi91dGlsL2NvbnZlcnRlciBkaXJlY3RvcnkuCitjbGFzcyBKc29uVXRpbFRlc3QgOiBwdWJsaWMgdGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICBKc29uVXRpbFRlc3QoKSB7CisgICAgcmVzb2x2ZXJfLnJlc2V0KE5ld1R5cGVSZXNvbHZlckZvckRlc2NyaXB0b3JQb29sKAorICAgICAgICBrVHlwZVVybFByZWZpeCwgRGVzY3JpcHRvclBvb2w6OmdlbmVyYXRlZF9wb29sKCkpKTsKKyAgfQorCisgIHN0cmluZyBUb0pzb24oY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwgY29uc3QgSnNvbk9wdGlvbnMmIG9wdGlvbnMpIHsKKyAgICBzdHJpbmcgcmVzdWx0OworICAgIEdPT0dMRV9DSEVDS19PSyhCaW5hcnlUb0pzb25TdHJpbmcocmVzb2x2ZXJfLmdldCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZXRUeXBlVXJsKG1lc3NhZ2UuR2V0RGVzY3JpcHRvcigpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5TZXJpYWxpemVBc1N0cmluZygpLCAmcmVzdWx0LCBvcHRpb25zKSk7CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorCisgIGJvb2wgRnJvbUpzb24oY29uc3Qgc3RyaW5nJiBqc29uLCBNZXNzYWdlKiBtZXNzYWdlKSB7CisgICAgc3RyaW5nIGJpbmFyeTsKKyAgICBHT09HTEVfQ0hFQ0tfT0soSnNvblRvQmluYXJ5U3RyaW5nKAorICAgICAgICByZXNvbHZlcl8uZ2V0KCksIEdldFR5cGVVcmwobWVzc2FnZS0+R2V0RGVzY3JpcHRvcigpKSwganNvbiwgJmJpbmFyeSkpOworICAgIHJldHVybiBtZXNzYWdlLT5QYXJzZUZyb21TdHJpbmcoYmluYXJ5KTsKKyAgfQorCisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8VHlwZVJlc29sdmVyPiByZXNvbHZlcl87Cit9OworCitURVNUX0YoSnNvblV0aWxUZXN0LCBUZXN0V2hpdGVzcGFjZXMpIHsKKyAgVGVzdE1lc3NhZ2UgbTsKKyAgbS5tdXRhYmxlX21lc3NhZ2VfdmFsdWUoKTsKKworICBKc29uT3B0aW9ucyBvcHRpb25zOworICBFWFBFQ1RfRVEoIntcIm1lc3NhZ2VWYWx1ZVwiOnt9fSIsIFRvSnNvbihtLCBvcHRpb25zKSk7CisgIG9wdGlvbnMuYWRkX3doaXRlc3BhY2UgPSB0cnVlOworICBFWFBFQ1RfRVEoCisgICAgICAie1xuIgorICAgICAgIiBcIm1lc3NhZ2VWYWx1ZVwiOiB7fVxuIgorICAgICAgIn1cbiIsCisgICAgICBUb0pzb24obSwgb3B0aW9ucykpOworfQorCisvLyBUT0RPKHNrYXJ2YWplKTogVW5jb21tZW50IGFmdGVyIGNsLzk2MjMyOTE1IGlzIHN1Ym1pdHRlZC4KKy8vIFRFU1RfRihKc29uVXRpbFRlc3QsIFRlc3REZWZhdWx0VmFsdWVzKSB7CisgIC8vIFRlc3RNZXNzYWdlIG07CisgIC8vIEpzb25PcHRpb25zIG9wdGlvbnM7CisgIC8vIEVYUEVDVF9FUSgie30iLCBUb0pzb24obSwgb3B0aW9ucykpOworICAvLyBvcHRpb25zLmFsd2F5c19wcmludF9wcmltaXRpdmVfZmllbGRzID0gdHJ1ZTsKKyAgLy8gRVhQRUNUX0VRKAorICAgICAgLy8gIntcImJvb2xWYWx1ZVwiOmZhbHNlLCIKKyAgICAgIC8vICJcImludDMyVmFsdWVcIjowLCIKKyAgICAgIC8vICJcImludDY0VmFsdWVcIjpcIjBcIiwiCisgICAgICAvLyAiXCJ1aW50MzJWYWx1ZVwiOjAsIgorICAgICAgLy8gIlwidWludDY0VmFsdWVcIjpcIjBcIiwiCisgICAgICAvLyAiXCJmbG9hdFZhbHVlXCI6MCwiCisgICAgICAvLyAiXCJkb3VibGVWYWx1ZVwiOjAsIgorICAgICAgLy8gIlwic3RyaW5nVmFsdWVcIjpcIlwiLCIKKyAgICAgIC8vICJcImJ5dGVzVmFsdWVcIjpcIlwiLCIKKyAgICAgIC8vIC8vIFRPRE8oeGlhb2ZlbmcpOiBUaGUgZGVmYXVsdCBlbnVtIHZhbHVlIHNob3VsZCBiZSBGT08uIEkgYmVsaWV2ZQorICAgICAgLy8gLy8gdGhpcyBpcyBhIGJ1ZyBpbiBEZWZhdWx0VmFsdWVPYmplY3RXcml0ZXIuCisgICAgICAvLyAiXCJlbnVtVmFsdWVcIjpudWxsIgorICAgICAgLy8gIn0iLAorICAgICAgLy8gVG9Kc29uKG0sIG9wdGlvbnMpKTsKKy8vIH0KKworVEVTVF9GKEpzb25VdGlsVGVzdCwgUGFyc2VNZXNzYWdlKSB7CisgIC8vIFNvbWUgcmFuZG9tIG1lc3NhZ2UgYnV0IGdvb2QgZW5vdWdoIHRvIHZlcmlmeSB0aGF0IHRoZSBwYXJzaW5nIHdhcnBwZXIKKyAgLy8gZnVuY3Rpb25zIGFyZSB3b3JraW5nIHByb3Blcmx5LgorICBzdHJpbmcgaW5wdXQgPQorICAgICAgIntcbiIKKyAgICAgICIgIFwiaW50MzJWYWx1ZVwiOiAxMDI0LFxuIgorICAgICAgIiAgXCJyZXBlYXRlZEludDMyVmFsdWVcIjogWzEsIDJdLFxuIgorICAgICAgIiAgXCJtZXNzYWdlVmFsdWVcIjoge1xuIgorICAgICAgIiAgICBcInZhbHVlXCI6IDIwNDhcbiIKKyAgICAgICIgIH0sXG4iCisgICAgICAiICBcInJlcGVhdGVkTWVzc2FnZVZhbHVlXCI6IFtcbiIKKyAgICAgICIgICAge1widmFsdWVcIjogNDB9LCB7XCJ2YWx1ZVwiOiA5Nn1cbiIKKyAgICAgICIgIF1cbiIKKyAgICAgICJ9XG4iOworICBUZXN0TWVzc2FnZSBtOworICBBU1NFUlRfVFJVRShGcm9tSnNvbihpbnB1dCwgJm0pKTsKKyAgRVhQRUNUX0VRKDEwMjQsIG0uaW50MzJfdmFsdWUoKSk7CisgIEFTU0VSVF9FUSgyLCBtLnJlcGVhdGVkX2ludDMyX3ZhbHVlX3NpemUoKSk7CisgIEVYUEVDVF9FUSgxLCBtLnJlcGVhdGVkX2ludDMyX3ZhbHVlKDApKTsKKyAgRVhQRUNUX0VRKDIsIG0ucmVwZWF0ZWRfaW50MzJfdmFsdWUoMSkpOworICBFWFBFQ1RfRVEoMjA0OCwgbS5tZXNzYWdlX3ZhbHVlKCkudmFsdWUoKSk7CisgIEFTU0VSVF9FUSgyLCBtLnJlcGVhdGVkX21lc3NhZ2VfdmFsdWVfc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDQwLCBtLnJlcGVhdGVkX21lc3NhZ2VfdmFsdWUoMCkudmFsdWUoKSk7CisgIEVYUEVDVF9FUSg5NiwgbS5yZXBlYXRlZF9tZXNzYWdlX3ZhbHVlKDEpLnZhbHVlKCkpOworfQorCitURVNUX0YoSnNvblV0aWxUZXN0LCBQYXJzZU1hcCkgeworICBUZXN0TWFwIG1lc3NhZ2U7CisgICgqbWVzc2FnZS5tdXRhYmxlX3N0cmluZ19tYXAoKSlbImhlbGxvIl0gPSAxMjM0OworICBKc29uT3B0aW9ucyBvcHRpb25zOworICBFWFBFQ1RfRVEoIntcInN0cmluZ01hcFwiOntcImhlbGxvXCI6MTIzNH19IiwgVG9Kc29uKG1lc3NhZ2UsIG9wdGlvbnMpKTsKKyAgVGVzdE1hcCBvdGhlcjsKKyAgQVNTRVJUX1RSVUUoRnJvbUpzb24oVG9Kc29uKG1lc3NhZ2UsIG9wdGlvbnMpLCAmb3RoZXIpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2UuRGVidWdTdHJpbmcoKSwgb3RoZXIuRGVidWdTdHJpbmcoKSk7Cit9CisKK3R5cGVkZWYgcGFpcjxjaGFyKiwgaW50PiBTZWdtZW50OworLy8gQSBaZXJvQ29weU91dHB1dFN0cmVhbSB0aGF0IHdyaXRlcyB0byBtdWx0aXBsZSBidWZmZXJzLgorY2xhc3MgU2VnbWVudGVkWmVyb0NvcHlPdXRwdXRTdHJlYW0gOiBwdWJsaWMgaW86Olplcm9Db3B5T3V0cHV0U3RyZWFtIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IFNlZ21lbnRlZFplcm9Db3B5T3V0cHV0U3RyZWFtKGxpc3Q8U2VnbWVudD4gc2VnbWVudHMpCisgICAgICA6IHNlZ21lbnRzXyhzZWdtZW50cyksIGxhc3Rfc2VnbWVudF8oc3RhdGljX2Nhc3Q8Y2hhcio+KE5VTEwpLCAwKSwgYnl0ZV9jb3VudF8oMCkge30KKworICB2aXJ0dWFsIGJvb2wgTmV4dCh2b2lkKiogYnVmZmVyLCBpbnQqIGxlbmd0aCkgeworICAgIGlmIChzZWdtZW50c18uZW1wdHkoKSkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBsYXN0X3NlZ21lbnRfID0gc2VnbWVudHNfLmZyb250KCk7CisgICAgc2VnbWVudHNfLnBvcF9mcm9udCgpOworICAgICpidWZmZXIgPSBsYXN0X3NlZ21lbnRfLmZpcnN0OworICAgICpsZW5ndGggPSBsYXN0X3NlZ21lbnRfLnNlY29uZDsKKyAgICBieXRlX2NvdW50XyArPSAqbGVuZ3RoOworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgdmlydHVhbCB2b2lkIEJhY2tVcChpbnQgbGVuZ3RoKSB7CisgICAgR09PR0xFX0NIRUNLKGxlbmd0aCA8PSBsYXN0X3NlZ21lbnRfLnNlY29uZCk7CisgICAgc2VnbWVudHNfLnB1c2hfZnJvbnQoCisgICAgICAgIFNlZ21lbnQobGFzdF9zZWdtZW50Xy5maXJzdCArIGxhc3Rfc2VnbWVudF8uc2Vjb25kIC0gbGVuZ3RoLCBsZW5ndGgpKTsKKyAgICBsYXN0X3NlZ21lbnRfID0gU2VnbWVudChsYXN0X3NlZ21lbnRfLmZpcnN0LCBsYXN0X3NlZ21lbnRfLnNlY29uZCAtIGxlbmd0aCk7CisgICAgYnl0ZV9jb3VudF8gLT0gbGVuZ3RoOworICB9CisKKyAgdmlydHVhbCBpbnQ2NCBCeXRlQ291bnQoKSBjb25zdCB7IHJldHVybiBieXRlX2NvdW50XzsgfQorCisgcHJpdmF0ZToKKyAgbGlzdDxTZWdtZW50PiBzZWdtZW50c187CisgIFNlZ21lbnQgbGFzdF9zZWdtZW50XzsKKyAgaW50NjQgYnl0ZV9jb3VudF87Cit9OworCisvLyBUaGlzIHRlc3Qgc3BsaXRzIHRoZSBvdXRwdXQgYnVmZmVyIGFuZCBhbHNvIHRoZSBpbnB1dCBkYXRhIGludG8gbXVsdGlwbGUKKy8vIHNlZ21lbnRzIGFuZCBjaGVja3MgdGhhdCB0aGUgaW1wbGVtZW50YXRpb24gb2YgWmVyb0NvcHlTdHJlYW1CeXRlU2luaworLy8gaGFuZGxlcyBhbGwgcG9zc2libGUgY2FzZXMgY29ycmVjdGx5LgorVEVTVChaZXJvQ29weVN0cmVhbUJ5dGVTaW5rVGVzdCwgVGVzdEFsbElucHV0T3V0cHV0UGF0dGVybnMpIHsKKyAgc3RhdGljIGNvbnN0IGludCBrT3V0cHV0QnVmZmVyTGVuZ3RoID0gMTA7CisgIC8vIEFuIGV4aGF1c3RpdmUgdGVzdCB0YWtlcyB0b28gbG9uZywgc2tpcCBzb21lIGNvbWJpbmF0aW9ucyB0byBtYWtlIHRoZSB0ZXN0CisgIC8vIHJ1biBmYXN0ZXIuCisgIHN0YXRpYyBjb25zdCBpbnQga1NraXBwZWRQYXR0ZXJuQ291bnQgPSA3OworCisgIGNoYXIgYnVmZmVyW2tPdXRwdXRCdWZmZXJMZW5ndGhdOworICBmb3IgKGludCBzcGxpdF9wYXR0ZXJuID0gMDsgc3BsaXRfcGF0dGVybiA8ICgxIDw8IChrT3V0cHV0QnVmZmVyTGVuZ3RoIC0gMSkpOworICAgICAgIHNwbGl0X3BhdHRlcm4gKz0ga1NraXBwZWRQYXR0ZXJuQ291bnQpIHsKKyAgICAvLyBTcGxpdCB0aGUgYnVmZmVyIGludG8gc21hbGwgc2VnbWVudHMgYWNjb3JkaW5nIHRvIHRoZSBzcGxpdF9wYXR0ZXJuLgorICAgIGxpc3Q8U2VnbWVudD4gc2VnbWVudHM7CisgICAgaW50IHNlZ21lbnRfc3RhcnQgPSAwOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwga091dHB1dEJ1ZmZlckxlbmd0aCAtIDE7ICsraSkgeworICAgICAgaWYgKHNwbGl0X3BhdHRlcm4gJiAoMSA8PCBpKSkgeworICAgICAgICBzZWdtZW50cy5wdXNoX2JhY2soCisgICAgICAgICAgICBTZWdtZW50KGJ1ZmZlciArIHNlZ21lbnRfc3RhcnQsIGkgLSBzZWdtZW50X3N0YXJ0ICsgMSkpOworICAgICAgICBzZWdtZW50X3N0YXJ0ID0gaSArIDE7CisgICAgICB9CisgICAgfQorICAgIHNlZ21lbnRzLnB1c2hfYmFjaygKKyAgICAgICAgU2VnbWVudChidWZmZXIgKyBzZWdtZW50X3N0YXJ0LCBrT3V0cHV0QnVmZmVyTGVuZ3RoIC0gc2VnbWVudF9zdGFydCkpOworCisgICAgLy8gV3JpdGUgZXhhY3RseSAxMCBieXRlcyB0aHJvdWdoIHRoZSBCeXRlU2luay4KKyAgICBzdHJpbmcgaW5wdXRfZGF0YSA9ICIwMTIzNDU2Nzg5IjsKKyAgICBmb3IgKGludCBpbnB1dF9wYXR0ZXJuID0gMDsgaW5wdXRfcGF0dGVybiA8ICgxIDw8IChpbnB1dF9kYXRhLnNpemUoKSAtIDEpKTsKKyAgICAgICAgIGlucHV0X3BhdHRlcm4gKz0ga1NraXBwZWRQYXR0ZXJuQ291bnQpIHsKKyAgICAgIG1lbXNldChidWZmZXIsIDAsIHNpemVvZihidWZmZXIpKTsKKyAgICAgIHsKKyAgICAgICAgU2VnbWVudGVkWmVyb0NvcHlPdXRwdXRTdHJlYW0gb3V0cHV0X3N0cmVhbShzZWdtZW50cyk7CisgICAgICAgIGludGVybmFsOjpaZXJvQ29weVN0cmVhbUJ5dGVTaW5rIGJ5dGVfc2luaygmb3V0cHV0X3N0cmVhbSk7CisgICAgICAgIGludCBzdGFydCA9IDA7CisgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgaW5wdXRfZGF0YS5sZW5ndGgoKSAtIDE7ICsraikgeworICAgICAgICAgIGlmIChpbnB1dF9wYXR0ZXJuICYgKDEgPDwgaikpIHsKKyAgICAgICAgICAgIGJ5dGVfc2luay5BcHBlbmQoJmlucHV0X2RhdGFbc3RhcnRdLCBqIC0gc3RhcnQgKyAxKTsKKyAgICAgICAgICAgIHN0YXJ0ID0gaiArIDE7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGJ5dGVfc2luay5BcHBlbmQoJmlucHV0X2RhdGFbc3RhcnRdLCBpbnB1dF9kYXRhLmxlbmd0aCgpIC0gc3RhcnQpOworICAgICAgfQorICAgICAgRVhQRUNUX0VRKGlucHV0X2RhdGEsIHN0cmluZyhidWZmZXIsIGlucHV0X2RhdGEubGVuZ3RoKCkpKTsKKyAgICB9CisKKyAgICAvLyBXcml0ZSBvbmx5IDkgYnl0ZXMgdGhyb3VnaCB0aGUgQnl0ZVNpbmsuCisgICAgaW5wdXRfZGF0YSA9ICIwMTIzNDU2NzgiOworICAgIGZvciAoaW50IGlucHV0X3BhdHRlcm4gPSAwOyBpbnB1dF9wYXR0ZXJuIDwgKDEgPDwgKGlucHV0X2RhdGEuc2l6ZSgpIC0gMSkpOworICAgICAgICAgaW5wdXRfcGF0dGVybiArPSBrU2tpcHBlZFBhdHRlcm5Db3VudCkgeworICAgICAgbWVtc2V0KGJ1ZmZlciwgMCwgc2l6ZW9mKGJ1ZmZlcikpOworICAgICAgeworICAgICAgICBTZWdtZW50ZWRaZXJvQ29weU91dHB1dFN0cmVhbSBvdXRwdXRfc3RyZWFtKHNlZ21lbnRzKTsKKyAgICAgICAgaW50ZXJuYWw6Olplcm9Db3B5U3RyZWFtQnl0ZVNpbmsgYnl0ZV9zaW5rKCZvdXRwdXRfc3RyZWFtKTsKKyAgICAgICAgaW50IHN0YXJ0ID0gMDsKKyAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBpbnB1dF9kYXRhLmxlbmd0aCgpIC0gMTsgKytqKSB7CisgICAgICAgICAgaWYgKGlucHV0X3BhdHRlcm4gJiAoMSA8PCBqKSkgeworICAgICAgICAgICAgYnl0ZV9zaW5rLkFwcGVuZCgmaW5wdXRfZGF0YVtzdGFydF0sIGogLSBzdGFydCArIDEpOworICAgICAgICAgICAgc3RhcnQgPSBqICsgMTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYnl0ZV9zaW5rLkFwcGVuZCgmaW5wdXRfZGF0YVtzdGFydF0sIGlucHV0X2RhdGEubGVuZ3RoKCkgLSBzdGFydCk7CisgICAgICB9CisgICAgICBFWFBFQ1RfRVEoaW5wdXRfZGF0YSwgc3RyaW5nKGJ1ZmZlciwgaW5wdXRfZGF0YS5sZW5ndGgoKSkpOworICAgICAgRVhQRUNUX0VRKDAsIGJ1ZmZlcltpbnB1dF9kYXRhLmxlbmd0aCgpXSk7CisgICAgfQorCisgICAgLy8gV3JpdGUgMTEgYnl0ZXMgdGhyb3VnaCB0aGUgQnl0ZVNpbmsuIFRoZSBleHRyYSBieXRlIHdpbGwganVzdAorICAgIC8vIGJlIGlnbm9yZWQuCisgICAgaW5wdXRfZGF0YSA9ICIwMTIzNDU2Nzg5QSI7CisgICAgZm9yIChpbnQgaW5wdXRfcGF0dGVybiA9IDA7IGlucHV0X3BhdHRlcm4gPCAoMSA8PCAoaW5wdXRfZGF0YS5zaXplKCkgLSAxKSk7CisgICAgICAgICBpbnB1dF9wYXR0ZXJuICs9IGtTa2lwcGVkUGF0dGVybkNvdW50KSB7CisgICAgICBtZW1zZXQoYnVmZmVyLCAwLCBzaXplb2YoYnVmZmVyKSk7CisgICAgICB7CisgICAgICAgIFNlZ21lbnRlZFplcm9Db3B5T3V0cHV0U3RyZWFtIG91dHB1dF9zdHJlYW0oc2VnbWVudHMpOworICAgICAgICBpbnRlcm5hbDo6WmVyb0NvcHlTdHJlYW1CeXRlU2luayBieXRlX3NpbmsoJm91dHB1dF9zdHJlYW0pOworICAgICAgICBpbnQgc3RhcnQgPSAwOworICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGlucHV0X2RhdGEubGVuZ3RoKCkgLSAxOyArK2opIHsKKyAgICAgICAgICBpZiAoaW5wdXRfcGF0dGVybiAmICgxIDw8IGopKSB7CisgICAgICAgICAgICBieXRlX3NpbmsuQXBwZW5kKCZpbnB1dF9kYXRhW3N0YXJ0XSwgaiAtIHN0YXJ0ICsgMSk7CisgICAgICAgICAgICBzdGFydCA9IGogKyAxOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBieXRlX3NpbmsuQXBwZW5kKCZpbnB1dF9kYXRhW3N0YXJ0XSwgaW5wdXRfZGF0YS5sZW5ndGgoKSAtIHN0YXJ0KTsKKyAgICAgIH0KKyAgICAgIEVYUEVDVF9FUShpbnB1dF9kYXRhLnN1YnN0cigwLCBrT3V0cHV0QnVmZmVyTGVuZ3RoKSwKKyAgICAgICAgICAgICAgICBzdHJpbmcoYnVmZmVyLCBrT3V0cHV0QnVmZmVyTGVuZ3RoKSk7CisgICAgfQorICB9Cit9CisKK30gIC8vIG5hbWVzcGFjZQorfSAgLy8gbmFtZXNwYWNlIHV0aWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL21lc3NhZ2VfZGlmZmVyZW5jZXIuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvbWVzc2FnZV9kaWZmZXJlbmNlci5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wZjg3OWRjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL21lc3NhZ2VfZGlmZmVyZW5jZXIuY2MKQEAgLTAsMCArMSwxNjg2IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBqc2Nob3JyQGdvb2dsZS5jb20gKEpvc2VwaCBTY2hvcnIpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBUaGlzIGZpbGUgZGVmaW5lcyBzdGF0aWMgbWV0aG9kcyBhbmQgY2xhc3NlcyBmb3IgY29tcGFyaW5nIFByb3RvY29sCisvLyBNZXNzYWdlcyAoc2VlIC8vZ29vZ2xlL3Byb3RvYnVmL3V0aWwvbWVzc2FnZV9kaWZmZXJlbmNlci5oIGZvciBtb3JlCisvLyBpbmZvcm1hdGlvbikuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9tZXNzYWdlX2RpZmZlcmVuY2VyLmg+CisKKyNpbmNsdWRlIDxhbGdvcml0aG0+CisjaW5jbHVkZSA8bWVtb3J5PgorI2lmbmRlZiBfU0hBUkVEX1BUUl9ICisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3NoYXJlZF9wdHIuaD4KKyNlbmRpZgorI2luY2x1ZGUgPHV0aWxpdHk+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY2FsbGJhY2suaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cmluZ3ByaW50Zi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9hbnkuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vcHJpbnRlci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9keW5hbWljX21lc3NhZ2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGV4dF9mb3JtYXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9maWVsZF9jb21wYXJhdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCituYW1lc3BhY2UgdXRpbCB7CisKKy8vIFdoZW4gY29tcGFyaW5nIGEgcmVwZWF0ZWQgZmllbGQgYXMgbWFwLCBNdWx0aXBsZUZpZWxkTWFwS2V5Q29tcGFyYXRvciBjYW4KKy8vIGJlIHVzZWQgdG8gc3BlY2lmeSBtdWx0aXBsZSBmaWVsZHMgYXMga2V5IGZvciBrZXkgY29tcGFyaXNvbi4KKy8vIFR3byBlbGVtZW50cyBvZiBhIHJlcGVhdGVkIGZpZWxkIHdpbGwgYmUgcmVnYXJkZWQgYXMgaGF2aW5nIHRoZSBzYW1lIGtleQorLy8gaWZmIHRoZXkgaGF2ZSB0aGUgc2FtZSB2YWx1ZSBmb3IgZXZlcnkgc3BlY2lmaWVkIGtleSBmaWVsZC4KKy8vIE5vdGUgdGhhdCB5b3UgY2FuIGFsc28gc3BlY2lmeSBvbmx5IG9uZSBmaWVsZCBhcyBrZXkuCitjbGFzcyBNZXNzYWdlRGlmZmVyZW5jZXI6Ok11bHRpcGxlRmllbGRzTWFwS2V5Q29tcGFyYXRvcgorICAgIDogcHVibGljIE1lc3NhZ2VEaWZmZXJlbmNlcjo6TWFwS2V5Q29tcGFyYXRvciB7CisgcHVibGljOgorICBNdWx0aXBsZUZpZWxkc01hcEtleUNvbXBhcmF0b3IoCisgICAgICBNZXNzYWdlRGlmZmVyZW5jZXIqIG1lc3NhZ2VfZGlmZmVyZW5jZXIsCisgICAgICBjb25zdCB2ZWN0b3I8dmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+ID4mIGtleV9maWVsZF9wYXRocykKKyAgICAgICAgOiBtZXNzYWdlX2RpZmZlcmVuY2VyXyhtZXNzYWdlX2RpZmZlcmVuY2VyKSwKKyAgICAgICAgICBrZXlfZmllbGRfcGF0aHNfKGtleV9maWVsZF9wYXRocykgeworICAgIEdPT0dMRV9DSEVDSygha2V5X2ZpZWxkX3BhdGhzXy5lbXB0eSgpKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGtleV9maWVsZF9wYXRoc18uc2l6ZSgpOyArK2kpIHsKKyAgICAgIEdPT0dMRV9DSEVDSygha2V5X2ZpZWxkX3BhdGhzX1tpXS5lbXB0eSgpKTsKKyAgICB9CisgIH0KKyAgTXVsdGlwbGVGaWVsZHNNYXBLZXlDb21wYXJhdG9yKAorICAgICAgTWVzc2FnZURpZmZlcmVuY2VyKiBtZXNzYWdlX2RpZmZlcmVuY2VyLAorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBrZXkpCisgICAgICAgIDogbWVzc2FnZV9kaWZmZXJlbmNlcl8obWVzc2FnZV9kaWZmZXJlbmNlcikgeworICAgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBrZXlfZmllbGRfcGF0aDsKKyAgICBrZXlfZmllbGRfcGF0aC5wdXNoX2JhY2soa2V5KTsKKyAgICBrZXlfZmllbGRfcGF0aHNfLnB1c2hfYmFjayhrZXlfZmllbGRfcGF0aCk7CisgIH0KKyAgdmlydHVhbCBib29sIElzTWF0Y2goCisgICAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlMSwKKyAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UyLAorICAgICAgY29uc3QgdmVjdG9yPFNwZWNpZmljRmllbGQ+JiBwYXJlbnRfZmllbGRzKSBjb25zdCB7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBrZXlfZmllbGRfcGF0aHNfLnNpemUoKTsgKytpKSB7CisgICAgICBpZiAoIUlzTWF0Y2hJbnRlcm5hbChtZXNzYWdlMSwgbWVzc2FnZTIsIHBhcmVudF9maWVsZHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXlfZmllbGRfcGF0aHNfW2ldLCAwKSkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiB0cnVlOworICB9CisgcHJpdmF0ZToKKyAgYm9vbCBJc01hdGNoSW50ZXJuYWwoCisgICAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlMSwKKyAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UyLAorICAgICAgY29uc3QgdmVjdG9yPFNwZWNpZmljRmllbGQ+JiBwYXJlbnRfZmllbGRzLAorICAgICAgY29uc3QgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+JiBrZXlfZmllbGRfcGF0aCwKKyAgICAgIGludCBwYXRoX2luZGV4KSBjb25zdCB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IGtleV9maWVsZF9wYXRoW3BhdGhfaW5kZXhdOworICAgIHZlY3RvcjxTcGVjaWZpY0ZpZWxkPiBjdXJyZW50X3BhcmVudF9maWVsZHMocGFyZW50X2ZpZWxkcyk7CisgICAgaWYgKHBhdGhfaW5kZXggPT0ga2V5X2ZpZWxkX3BhdGguc2l6ZSgpIC0gMSkgeworICAgICAgaWYgKGZpZWxkLT5pc19yZXBlYXRlZCgpKSB7CisgICAgICAgIGlmICghbWVzc2FnZV9kaWZmZXJlbmNlcl8tPkNvbXBhcmVSZXBlYXRlZEZpZWxkKAorICAgICAgICAgICAgbWVzc2FnZTEsIG1lc3NhZ2UyLCBmaWVsZCwgJmN1cnJlbnRfcGFyZW50X2ZpZWxkcykpIHsKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGlmICghbWVzc2FnZV9kaWZmZXJlbmNlcl8tPkNvbXBhcmVGaWVsZFZhbHVlVXNpbmdQYXJlbnRGaWVsZHMoCisgICAgICAgICAgICBtZXNzYWdlMSwgbWVzc2FnZTIsIGZpZWxkLCAtMSwgLTEsICZjdXJyZW50X3BhcmVudF9maWVsZHMpKSB7CisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICB9CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9IGVsc2UgeworICAgICAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbjEgPSBtZXNzYWdlMS5HZXRSZWZsZWN0aW9uKCk7CisgICAgICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uMiA9IG1lc3NhZ2UyLkdldFJlZmxlY3Rpb24oKTsKKyAgICAgIGJvb2wgaGFzX2ZpZWxkMSA9IHJlZmxlY3Rpb24xLT5IYXNGaWVsZChtZXNzYWdlMSwgZmllbGQpOworICAgICAgYm9vbCBoYXNfZmllbGQyID0gcmVmbGVjdGlvbjItPkhhc0ZpZWxkKG1lc3NhZ2UyLCBmaWVsZCk7CisgICAgICBpZiAoIWhhc19maWVsZDEgJiYgIWhhc19maWVsZDIpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICB9CisgICAgICBpZiAoaGFzX2ZpZWxkMSAhPSBoYXNfZmllbGQyKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICAgIFNwZWNpZmljRmllbGQgc3BlY2lmaWNfZmllbGQ7CisgICAgICBzcGVjaWZpY19maWVsZC5maWVsZCA9IGZpZWxkOworICAgICAgY3VycmVudF9wYXJlbnRfZmllbGRzLnB1c2hfYmFjayhzcGVjaWZpY19maWVsZCk7CisgICAgICByZXR1cm4gSXNNYXRjaEludGVybmFsKAorICAgICAgICAgIHJlZmxlY3Rpb24xLT5HZXRNZXNzYWdlKG1lc3NhZ2UxLCBmaWVsZCksCisgICAgICAgICAgcmVmbGVjdGlvbjItPkdldE1lc3NhZ2UobWVzc2FnZTIsIGZpZWxkKSwKKyAgICAgICAgICBjdXJyZW50X3BhcmVudF9maWVsZHMsCisgICAgICAgICAga2V5X2ZpZWxkX3BhdGgsCisgICAgICAgICAgcGF0aF9pbmRleCArIDEpOworICAgIH0KKyAgfQorICBNZXNzYWdlRGlmZmVyZW5jZXIqIG1lc3NhZ2VfZGlmZmVyZW5jZXJfOworICB2ZWN0b3I8dmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+ID4ga2V5X2ZpZWxkX3BhdGhzXzsKKyAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKE11bHRpcGxlRmllbGRzTWFwS2V5Q29tcGFyYXRvcik7Cit9OworCitib29sIE1lc3NhZ2VEaWZmZXJlbmNlcjo6RXF1YWxzKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlMikgeworICBNZXNzYWdlRGlmZmVyZW5jZXIgZGlmZmVyZW5jZXI7CisKKyAgcmV0dXJuIGRpZmZlcmVuY2VyLkNvbXBhcmUobWVzc2FnZTEsIG1lc3NhZ2UyKTsKK30KKworYm9vbCBNZXNzYWdlRGlmZmVyZW5jZXI6OkVxdWl2YWxlbnQoY29uc3QgTWVzc2FnZSYgbWVzc2FnZTEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlMikgeworICBNZXNzYWdlRGlmZmVyZW5jZXIgZGlmZmVyZW5jZXI7CisgIGRpZmZlcmVuY2VyLnNldF9tZXNzYWdlX2ZpZWxkX2NvbXBhcmlzb24oTWVzc2FnZURpZmZlcmVuY2VyOjpFUVVJVkFMRU5UKTsKKworICByZXR1cm4gZGlmZmVyZW5jZXIuQ29tcGFyZShtZXNzYWdlMSwgbWVzc2FnZTIpOworfQorCitib29sIE1lc3NhZ2VEaWZmZXJlbmNlcjo6QXBwcm94aW1hdGVseUVxdWFscyhjb25zdCBNZXNzYWdlJiBtZXNzYWdlMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UyKSB7CisgIE1lc3NhZ2VEaWZmZXJlbmNlciBkaWZmZXJlbmNlcjsKKyAgZGlmZmVyZW5jZXIuc2V0X2Zsb2F0X2NvbXBhcmlzb24oCisgICAgICBNZXNzYWdlRGlmZmVyZW5jZXI6OkFQUFJPWElNQVRFKTsKKworICByZXR1cm4gZGlmZmVyZW5jZXIuQ29tcGFyZShtZXNzYWdlMSwgbWVzc2FnZTIpOworfQorCitib29sIE1lc3NhZ2VEaWZmZXJlbmNlcjo6QXBwcm94aW1hdGVseUVxdWl2YWxlbnQoY29uc3QgTWVzc2FnZSYgbWVzc2FnZTEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZTIpIHsKKyAgTWVzc2FnZURpZmZlcmVuY2VyIGRpZmZlcmVuY2VyOworICBkaWZmZXJlbmNlci5zZXRfbWVzc2FnZV9maWVsZF9jb21wYXJpc29uKE1lc3NhZ2VEaWZmZXJlbmNlcjo6RVFVSVZBTEVOVCk7CisgIGRpZmZlcmVuY2VyLnNldF9mbG9hdF9jb21wYXJpc29uKE1lc3NhZ2VEaWZmZXJlbmNlcjo6QVBQUk9YSU1BVEUpOworCisgIHJldHVybiBkaWZmZXJlbmNlci5Db21wYXJlKG1lc3NhZ2UxLCBtZXNzYWdlMik7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitNZXNzYWdlRGlmZmVyZW5jZXI6Ok1lc3NhZ2VEaWZmZXJlbmNlcigpCisgICAgOiByZXBvcnRlcl8oTlVMTCksCisgICAgICBmaWVsZF9jb21wYXJhdG9yXyhOVUxMKSwKKyAgICAgIG1lc3NhZ2VfZmllbGRfY29tcGFyaXNvbl8oRVFVQUwpLAorICAgICAgc2NvcGVfKEZVTEwpLAorICAgICAgcmVwZWF0ZWRfZmllbGRfY29tcGFyaXNvbl8oQVNfTElTVCksCisgICAgICByZXBvcnRfbWF0Y2hlc18oZmFsc2UpLAorICAgICAgb3V0cHV0X3N0cmluZ18oTlVMTCkgeyB9CisKK01lc3NhZ2VEaWZmZXJlbmNlcjo6fk1lc3NhZ2VEaWZmZXJlbmNlcigpIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBvd25lZF9rZXlfY29tcGFyYXRvcnNfLnNpemUoKTsgKytpKSB7CisgICAgZGVsZXRlIG93bmVkX2tleV9jb21wYXJhdG9yc19baV07CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBpZ25vcmVfY3JpdGVyaWFfLnNpemUoKTsgKytpKSB7CisgICAgZGVsZXRlIGlnbm9yZV9jcml0ZXJpYV9baV07CisgIH0KK30KKwordm9pZCBNZXNzYWdlRGlmZmVyZW5jZXI6OnNldF9maWVsZF9jb21wYXJhdG9yKEZpZWxkQ29tcGFyYXRvciogY29tcGFyYXRvcikgeworICBHT09HTEVfQ0hFQ0soY29tcGFyYXRvcikgPDwgIkZpZWxkIGNvbXBhcmF0b3IgY2FuJ3QgYmUgTlVMTC4iOworICBmaWVsZF9jb21wYXJhdG9yXyA9IGNvbXBhcmF0b3I7Cit9CisKK3ZvaWQgTWVzc2FnZURpZmZlcmVuY2VyOjpzZXRfbWVzc2FnZV9maWVsZF9jb21wYXJpc29uKAorICAgIE1lc3NhZ2VGaWVsZENvbXBhcmlzb24gY29tcGFyaXNvbikgeworICBtZXNzYWdlX2ZpZWxkX2NvbXBhcmlzb25fID0gY29tcGFyaXNvbjsKK30KKwordm9pZCBNZXNzYWdlRGlmZmVyZW5jZXI6OnNldF9zY29wZShTY29wZSBzY29wZSkgeworICBzY29wZV8gPSBzY29wZTsKK30KKworTWVzc2FnZURpZmZlcmVuY2VyOjpTY29wZSBNZXNzYWdlRGlmZmVyZW5jZXI6OnNjb3BlKCkgeworICByZXR1cm4gc2NvcGVfOworfQorCit2b2lkIE1lc3NhZ2VEaWZmZXJlbmNlcjo6c2V0X2Zsb2F0X2NvbXBhcmlzb24oRmxvYXRDb21wYXJpc29uIGNvbXBhcmlzb24pIHsKKyAgZGVmYXVsdF9maWVsZF9jb21wYXJhdG9yXy5zZXRfZmxvYXRfY29tcGFyaXNvbigKKyAgICAgIGNvbXBhcmlzb24gPT0gRVhBQ1QgPworICAgICAgRGVmYXVsdEZpZWxkQ29tcGFyYXRvcjo6RVhBQ1QgOiBEZWZhdWx0RmllbGRDb21wYXJhdG9yOjpBUFBST1hJTUFURSk7Cit9CisKK3ZvaWQgTWVzc2FnZURpZmZlcmVuY2VyOjpzZXRfcmVwZWF0ZWRfZmllbGRfY29tcGFyaXNvbigKKyAgICBSZXBlYXRlZEZpZWxkQ29tcGFyaXNvbiBjb21wYXJpc29uKSB7CisgIHJlcGVhdGVkX2ZpZWxkX2NvbXBhcmlzb25fID0gY29tcGFyaXNvbjsKK30KKwordm9pZCBNZXNzYWdlRGlmZmVyZW5jZXI6OlRyZWF0QXNTZXQoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICBHT09HTEVfQ0hFQ0soZmllbGQtPmlzX3JlcGVhdGVkKCkpIDw8ICJGaWVsZCBtdXN0IGJlIHJlcGVhdGVkOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPDwgZmllbGQtPmZ1bGxfbmFtZSgpOworICBjb25zdCBNYXBLZXlDb21wYXJhdG9yKiBrZXlfY29tcGFyYXRvciA9IEdldE1hcEtleUNvbXBhcmF0b3IoZmllbGQpOworICBHT09HTEVfQ0hFQ0soa2V5X2NvbXBhcmF0b3IgPT0gTlVMTCkKKyAgICAgIDw8ICJDYW5ub3QgdHJlYXQgdGhpcyByZXBlYXRlZCBmaWVsZCBhcyBib3RoIE1hcCBhbmQgU2V0IGZvciIKKyAgICAgIDw8ICIgY29tcGFyaXNvbi4gIEZpZWxkIG5hbWUgaXM6ICIgPDwgZmllbGQtPmZ1bGxfbmFtZSgpOworICBHT09HTEVfQ0hFQ0sobGlzdF9maWVsZHNfLmZpbmQoZmllbGQpID09IGxpc3RfZmllbGRzXy5lbmQoKSkKKyAgICAgIDw8ICJDYW5ub3QgdHJlYXQgdGhlIHNhbWUgZmllbGQgYXMgYm90aCBTRVQgYW5kIExJU1QuIEZpZWxkIG5hbWUgaXM6ICIKKyAgICAgIDw8IGZpZWxkLT5mdWxsX25hbWUoKTsKKyAgc2V0X2ZpZWxkc18uaW5zZXJ0KGZpZWxkKTsKK30KKwordm9pZCBNZXNzYWdlRGlmZmVyZW5jZXI6OlRyZWF0QXNMaXN0KGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgR09PR0xFX0NIRUNLKGZpZWxkLT5pc19yZXBlYXRlZCgpKSA8PCAiRmllbGQgbXVzdCBiZSByZXBlYXRlZDogIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPDwgZmllbGQtPmZ1bGxfbmFtZSgpOworICBjb25zdCBNYXBLZXlDb21wYXJhdG9yKiBrZXlfY29tcGFyYXRvciA9IEdldE1hcEtleUNvbXBhcmF0b3IoZmllbGQpOworICBHT09HTEVfQ0hFQ0soa2V5X2NvbXBhcmF0b3IgPT0gTlVMTCkKKyAgICAgIDw8ICJDYW5ub3QgdHJlYXQgdGhpcyByZXBlYXRlZCBmaWVsZCBhcyBib3RoIE1hcCBhbmQgU2V0IGZvciIKKyAgICAgIDw8ICIgY29tcGFyaXNvbi4gIEZpZWxkIG5hbWUgaXM6ICIgPDwgZmllbGQtPmZ1bGxfbmFtZSgpOworICBHT09HTEVfQ0hFQ0soc2V0X2ZpZWxkc18uZmluZChmaWVsZCkgPT0gc2V0X2ZpZWxkc18uZW5kKCkpCisgICAgICA8PCAiQ2Fubm90IHRyZWF0IHRoZSBzYW1lIGZpZWxkIGFzIGJvdGggU0VUIGFuZCBMSVNULiBGaWVsZCBuYW1lIGlzOiAiCisgICAgICA8PCBmaWVsZC0+ZnVsbF9uYW1lKCk7CisgIGxpc3RfZmllbGRzXy5pbnNlcnQoZmllbGQpOworfQorCit2b2lkIE1lc3NhZ2VEaWZmZXJlbmNlcjo6VHJlYXRBc01hcChjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBrZXkpIHsKKyAgR09PR0xFX0NIRUNLKGZpZWxkLT5pc19yZXBlYXRlZCgpKSA8PCAiRmllbGQgbXVzdCBiZSByZXBlYXRlZDogIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDw8IGZpZWxkLT5mdWxsX25hbWUoKTsKKyAgR09PR0xFX0NIRUNLX0VRKEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFLCBmaWVsZC0+Y3BwX3R5cGUoKSkKKyAgICAgIDw8ICJGaWVsZCBoYXMgdG8gYmUgbWVzc2FnZSB0eXBlLiAgRmllbGQgbmFtZSBpczogIgorICAgICAgPDwgZmllbGQtPmZ1bGxfbmFtZSgpOworICBHT09HTEVfQ0hFQ0soa2V5LT5jb250YWluaW5nX3R5cGUoKSA9PSBmaWVsZC0+bWVzc2FnZV90eXBlKCkpCisgICAgICA8PCBrZXktPmZ1bGxfbmFtZSgpCisgICAgICA8PCAiIG11c3QgYmUgYSBkaXJlY3Qgc3ViZmllbGQgd2l0aGluIHRoZSByZXBlYXRlZCBmaWVsZCAiCisgICAgICA8PCBmaWVsZC0+ZnVsbF9uYW1lKCkgPDwgIiwgbm90ICIgPDwga2V5LT5jb250YWluaW5nX3R5cGUoKS0+ZnVsbF9uYW1lKCk7CisgIEdPT0dMRV9DSEVDSyhzZXRfZmllbGRzXy5maW5kKGZpZWxkKSA9PSBzZXRfZmllbGRzXy5lbmQoKSkKKyAgICAgIDw8ICJDYW5ub3QgdHJlYXQgdGhpcyByZXBlYXRlZCBmaWVsZCBhcyBib3RoIE1hcCBhbmQgU2V0IGZvciAiCisgICAgICA8PCAiY29tcGFyaXNvbi4iOworICBHT09HTEVfQ0hFQ0sobGlzdF9maWVsZHNfLmZpbmQoZmllbGQpID09IGxpc3RfZmllbGRzXy5lbmQoKSkKKyAgICAgIDw8ICJDYW5ub3QgdHJlYXQgdGhpcyByZXBlYXRlZCBmaWVsZCBhcyBib3RoIE1hcCBhbmQgTGlzdCBmb3IgIgorICAgICAgPDwgImNvbXBhcmlzb24uIjsKKyAgTWFwS2V5Q29tcGFyYXRvcioga2V5X2NvbXBhcmF0b3IgPQorICAgICAgbmV3IE11bHRpcGxlRmllbGRzTWFwS2V5Q29tcGFyYXRvcih0aGlzLCBrZXkpOworICBvd25lZF9rZXlfY29tcGFyYXRvcnNfLnB1c2hfYmFjayhrZXlfY29tcGFyYXRvcik7CisgIG1hcF9maWVsZF9rZXlfY29tcGFyYXRvcl9bZmllbGRdID0ga2V5X2NvbXBhcmF0b3I7Cit9CisKK3ZvaWQgTWVzc2FnZURpZmZlcmVuY2VyOjpUcmVhdEFzTWFwV2l0aE11bHRpcGxlRmllbGRzQXNLZXkoCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICBjb25zdCB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4mIGtleV9maWVsZHMpIHsKKyAgdmVjdG9yPHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiA+IGtleV9maWVsZF9wYXRoczsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBrZXlfZmllbGRzLnNpemUoKTsgKytpKSB7CisgICAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+IGtleV9maWVsZF9wYXRoOworICAgIGtleV9maWVsZF9wYXRoLnB1c2hfYmFjayhrZXlfZmllbGRzW2ldKTsKKyAgICBrZXlfZmllbGRfcGF0aHMucHVzaF9iYWNrKGtleV9maWVsZF9wYXRoKTsKKyAgfQorICBUcmVhdEFzTWFwV2l0aE11bHRpcGxlRmllbGRQYXRoc0FzS2V5KGZpZWxkLCBrZXlfZmllbGRfcGF0aHMpOworfQorCit2b2lkIE1lc3NhZ2VEaWZmZXJlbmNlcjo6VHJlYXRBc01hcFdpdGhNdWx0aXBsZUZpZWxkUGF0aHNBc0tleSgKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgIGNvbnN0IHZlY3Rvcjx2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4gPiYga2V5X2ZpZWxkX3BhdGhzKSB7CisgIEdPT0dMRV9DSEVDSyhmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgPDwgIkZpZWxkIG11c3QgYmUgcmVwZWF0ZWQ6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDw8IGZpZWxkLT5mdWxsX25hbWUoKTsKKyAgR09PR0xFX0NIRUNLX0VRKEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFLCBmaWVsZC0+Y3BwX3R5cGUoKSkKKyAgICAgIDw8ICJGaWVsZCBoYXMgdG8gYmUgbWVzc2FnZSB0eXBlLiAgRmllbGQgbmFtZSBpczogIgorICAgICAgPDwgZmllbGQtPmZ1bGxfbmFtZSgpOworICBmb3IgKGludCBpID0gMDsgaSA8IGtleV9maWVsZF9wYXRocy5zaXplKCk7ICsraSkgeworICAgIGNvbnN0IHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiYga2V5X2ZpZWxkX3BhdGggPSBrZXlfZmllbGRfcGF0aHNbaV07CisgICAgZm9yIChpbnQgaiA9IDA7IGogPCBrZXlfZmllbGRfcGF0aC5zaXplKCk7ICsraikgeworICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBwYXJlbnRfZmllbGQgPQorICAgICAgICAgIGogPT0gMCA/IGZpZWxkIDoga2V5X2ZpZWxkX3BhdGhbaiAtIDFdOworICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBjaGlsZF9maWVsZCA9IGtleV9maWVsZF9wYXRoW2pdOworICAgICAgR09PR0xFX0NIRUNLKGNoaWxkX2ZpZWxkLT5jb250YWluaW5nX3R5cGUoKSA9PSBwYXJlbnRfZmllbGQtPm1lc3NhZ2VfdHlwZSgpKQorICAgICAgICAgIDw8IGNoaWxkX2ZpZWxkLT5mdWxsX25hbWUoKQorICAgICAgICAgIDw8ICIgbXVzdCBiZSBhIGRpcmVjdCBzdWJmaWVsZCB3aXRoaW4gdGhlIGZpZWxkOiAiCisgICAgICAgICAgPDwgcGFyZW50X2ZpZWxkLT5mdWxsX25hbWUoKTsKKyAgICAgIGlmIChqICE9IDApIHsKKyAgICAgICAgR09PR0xFX0NIRUNLX0VRKEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFLCBwYXJlbnRfZmllbGQtPmNwcF90eXBlKCkpCisgICAgICAgICAgICA8PCBwYXJlbnRfZmllbGQtPmZ1bGxfbmFtZSgpIDw8ICIgaGFzIHRvIGJlIG9mIHR5cGUgbWVzc2FnZS4iOworICAgICAgICBHT09HTEVfQ0hFQ0soIXBhcmVudF9maWVsZC0+aXNfcmVwZWF0ZWQoKSkKKyAgICAgICAgICAgIDw8IHBhcmVudF9maWVsZC0+ZnVsbF9uYW1lKCkgPDwgIiBjYW5ub3QgYmUgYSByZXBlYXRlZCBmaWVsZC4iOworICAgICAgfQorICAgIH0KKyAgfQorICBHT09HTEVfQ0hFQ0soc2V0X2ZpZWxkc18uZmluZChmaWVsZCkgPT0gc2V0X2ZpZWxkc18uZW5kKCkpCisgICAgICA8PCAiQ2Fubm90IHRyZWF0IHRoaXMgcmVwZWF0ZWQgZmllbGQgYXMgYm90aCBNYXAgYW5kIFNldCBmb3IgIgorICAgICAgPDwgImNvbXBhcmlzb24uIjsKKyAgTWFwS2V5Q29tcGFyYXRvcioga2V5X2NvbXBhcmF0b3IgPQorICAgICAgbmV3IE11bHRpcGxlRmllbGRzTWFwS2V5Q29tcGFyYXRvcih0aGlzLCBrZXlfZmllbGRfcGF0aHMpOworICBvd25lZF9rZXlfY29tcGFyYXRvcnNfLnB1c2hfYmFjayhrZXlfY29tcGFyYXRvcik7CisgIG1hcF9maWVsZF9rZXlfY29tcGFyYXRvcl9bZmllbGRdID0ga2V5X2NvbXBhcmF0b3I7Cit9CisKK3ZvaWQgTWVzc2FnZURpZmZlcmVuY2VyOjpUcmVhdEFzTWFwVXNpbmdLZXlDb21wYXJhdG9yKAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgY29uc3QgTWFwS2V5Q29tcGFyYXRvcioga2V5X2NvbXBhcmF0b3IpIHsKKyAgR09PR0xFX0NIRUNLKGZpZWxkLT5pc19yZXBlYXRlZCgpKSA8PCAiRmllbGQgbXVzdCBiZSByZXBlYXRlZDogIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDw8IGZpZWxkLT5mdWxsX25hbWUoKTsKKyAgR09PR0xFX0NIRUNLX0VRKEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFLCBmaWVsZC0+Y3BwX3R5cGUoKSkKKyAgICAgIDw8ICJGaWVsZCBoYXMgdG8gYmUgbWVzc2FnZSB0eXBlLiAgRmllbGQgbmFtZSBpczogIgorICAgICAgPDwgZmllbGQtPmZ1bGxfbmFtZSgpOworICBHT09HTEVfQ0hFQ0soc2V0X2ZpZWxkc18uZmluZChmaWVsZCkgPT0gc2V0X2ZpZWxkc18uZW5kKCkpCisgICAgICA8PCAiQ2Fubm90IHRyZWF0IHRoaXMgcmVwZWF0ZWQgZmllbGQgYXMgYm90aCBNYXAgYW5kIFNldCBmb3IgIgorICAgICAgPDwgImNvbXBhcmlzb24uIjsKKyAgbWFwX2ZpZWxkX2tleV9jb21wYXJhdG9yX1tmaWVsZF0gPSBrZXlfY29tcGFyYXRvcjsKK30KKwordm9pZCBNZXNzYWdlRGlmZmVyZW5jZXI6OkFkZElnbm9yZUNyaXRlcmlhKElnbm9yZUNyaXRlcmlhKiBpZ25vcmVfY3JpdGVyaWEpIHsKKyAgaWdub3JlX2NyaXRlcmlhXy5wdXNoX2JhY2soaWdub3JlX2NyaXRlcmlhKTsKK30KKwordm9pZCBNZXNzYWdlRGlmZmVyZW5jZXI6Oklnbm9yZUZpZWxkKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgaWdub3JlZF9maWVsZHNfLmluc2VydChmaWVsZCk7Cit9CisKK3ZvaWQgTWVzc2FnZURpZmZlcmVuY2VyOjpTZXRGcmFjdGlvbkFuZE1hcmdpbihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvdWJsZSBmcmFjdGlvbiwgZG91YmxlIG1hcmdpbikgeworICBkZWZhdWx0X2ZpZWxkX2NvbXBhcmF0b3JfLlNldEZyYWN0aW9uQW5kTWFyZ2luKGZpZWxkLCBmcmFjdGlvbiwgbWFyZ2luKTsKK30KKwordm9pZCBNZXNzYWdlRGlmZmVyZW5jZXI6OlJlcG9ydERpZmZlcmVuY2VzVG9TdHJpbmcoc3RyaW5nKiBvdXRwdXQpIHsKKyAgR09PR0xFX0RDSEVDSyhvdXRwdXQpIDw8ICJTcGVjaWZpZWQgb3V0cHV0IHN0cmluZyB3YXMgTlVMTCI7CisKKyAgb3V0cHV0X3N0cmluZ18gPSBvdXRwdXQ7CisgIG91dHB1dF9zdHJpbmdfLT5jbGVhcigpOworfQorCit2b2lkIE1lc3NhZ2VEaWZmZXJlbmNlcjo6UmVwb3J0RGlmZmVyZW5jZXNUbyhSZXBvcnRlciogcmVwb3J0ZXIpIHsKKyAgLy8gSWYgYW4gb3V0cHV0IHN0cmluZyBpcyBzZXQsIGNsZWFyIGl0IHRvIHByZXZlbnQKKyAgLy8gaXQgc3VwZXJjZWRpbmcgdGhlIHNwZWNpZmllZCByZXBvcnRlci4KKyAgaWYgKG91dHB1dF9zdHJpbmdfKSB7CisgICAgb3V0cHV0X3N0cmluZ18gPSBOVUxMOworICB9CisKKyAgcmVwb3J0ZXJfID0gcmVwb3J0ZXI7Cit9CisKK2Jvb2wgTWVzc2FnZURpZmZlcmVuY2VyOjpGaWVsZEJlZm9yZShjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkMikgeworICAvLyBIYW5kbGUgc2VudGluZWwgdmFsdWVzIChpLmUuIG1ha2Ugc3VyZSBOVUxMcyBhcmUgYWx3YXlzIG9yZGVyZWQKKyAgLy8gYXQgdGhlIGVuZCBvZiB0aGUgbGlzdCkuCisgIGlmIChmaWVsZDEgPT0gTlVMTCkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIGlmIChmaWVsZDIgPT0gTlVMTCkgeworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgLy8gQWx3YXlzIG9yZGVyIGZpZWxkcyBieSB0aGVpciB0YWcgbnVtYmVyCisgIHJldHVybiAoZmllbGQxLT5udW1iZXIoKSA8IGZpZWxkMi0+bnVtYmVyKCkpOworfQorCitib29sIE1lc3NhZ2VEaWZmZXJlbmNlcjo6Q29tcGFyZShjb25zdCBNZXNzYWdlJiBtZXNzYWdlMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UyKSB7CisgIHZlY3RvcjxTcGVjaWZpY0ZpZWxkPiBwYXJlbnRfZmllbGRzOworCisgIGJvb2wgcmVzdWx0ID0gZmFsc2U7CisKKyAgLy8gU2V0dXAgdGhlIGludGVybmFsIHJlcG9ydGVyIGlmIG5lZWQgYmUuCisgIGlmIChvdXRwdXRfc3RyaW5nXykgeworICAgIGlvOjpTdHJpbmdPdXRwdXRTdHJlYW0gb3V0cHV0X3N0cmVhbShvdXRwdXRfc3RyaW5nXyk7CisgICAgU3RyZWFtUmVwb3J0ZXIgcmVwb3J0ZXIoJm91dHB1dF9zdHJlYW0pOworICAgIHJlcG9ydGVyXyA9ICZyZXBvcnRlcjsKKyAgICByZXN1bHQgPSBDb21wYXJlKG1lc3NhZ2UxLCBtZXNzYWdlMiwgJnBhcmVudF9maWVsZHMpOworICAgIHJlcG9ydGVyXyA9IE5VTEw7CisgIH0gZWxzZSB7CisgICAgcmVzdWx0ID0gQ29tcGFyZShtZXNzYWdlMSwgbWVzc2FnZTIsICZwYXJlbnRfZmllbGRzKTsKKyAgfQorCisgIHJldHVybiByZXN1bHQ7Cit9CisKK2Jvb2wgTWVzc2FnZURpZmZlcmVuY2VyOjpDb21wYXJlV2l0aEZpZWxkcygKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlMSwKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlMiwKKyAgICBjb25zdCB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4mIG1lc3NhZ2UxX2ZpZWxkc19hcmcsCisgICAgY29uc3QgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+JiBtZXNzYWdlMl9maWVsZHNfYXJnKSB7CisgIGlmIChtZXNzYWdlMS5HZXREZXNjcmlwdG9yKCkgIT0gbWVzc2FnZTIuR2V0RGVzY3JpcHRvcigpKSB7CisgICAgR09PR0xFX0xPRyhERkFUQUwpIDw8ICJDb21wYXJpc29uIGJldHdlZW4gdHdvIG1lc3NhZ2VzIHdpdGggZGlmZmVyZW50ICIKKyAgICAgICAgICAgICAgICA8PCAiZGVzY3JpcHRvcnMuIjsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICB2ZWN0b3I8U3BlY2lmaWNGaWVsZD4gcGFyZW50X2ZpZWxkczsKKworICBib29sIHJlc3VsdCA9IGZhbHNlOworCisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBtZXNzYWdlMV9maWVsZHMobWVzc2FnZTFfZmllbGRzX2FyZyk7CisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBtZXNzYWdlMl9maWVsZHMobWVzc2FnZTJfZmllbGRzX2FyZyk7CisKKyAgc3RkOjpzb3J0KG1lc3NhZ2UxX2ZpZWxkcy5iZWdpbigpLCBtZXNzYWdlMV9maWVsZHMuZW5kKCksIEZpZWxkQmVmb3JlKTsKKyAgc3RkOjpzb3J0KG1lc3NhZ2UyX2ZpZWxkcy5iZWdpbigpLCBtZXNzYWdlMl9maWVsZHMuZW5kKCksIEZpZWxkQmVmb3JlKTsKKyAgLy8gQXBwZW5kIE5VTEwgc2VudGluZWwgdmFsdWVzLgorICBtZXNzYWdlMV9maWVsZHMucHVzaF9iYWNrKE5VTEwpOworICBtZXNzYWdlMl9maWVsZHMucHVzaF9iYWNrKE5VTEwpOworCisgIC8vIFNldHVwIHRoZSBpbnRlcm5hbCByZXBvcnRlciBpZiBuZWVkIGJlLgorICBpZiAob3V0cHV0X3N0cmluZ18pIHsKKyAgICBpbzo6U3RyaW5nT3V0cHV0U3RyZWFtIG91dHB1dF9zdHJlYW0ob3V0cHV0X3N0cmluZ18pOworICAgIFN0cmVhbVJlcG9ydGVyIHJlcG9ydGVyKCZvdXRwdXRfc3RyZWFtKTsKKyAgICByZXBvcnRlcl8gPSAmcmVwb3J0ZXI7CisgICAgcmVzdWx0ID0gQ29tcGFyZVJlcXVlc3RlZEZpZWxkc1VzaW5nU2V0dGluZ3MoCisgICAgICAgIG1lc3NhZ2UxLCBtZXNzYWdlMiwgbWVzc2FnZTFfZmllbGRzLCBtZXNzYWdlMl9maWVsZHMsICZwYXJlbnRfZmllbGRzKTsKKyAgICByZXBvcnRlcl8gPSBOVUxMOworICB9IGVsc2UgeworICAgIHJlc3VsdCA9IENvbXBhcmVSZXF1ZXN0ZWRGaWVsZHNVc2luZ1NldHRpbmdzKAorICAgICAgICBtZXNzYWdlMSwgbWVzc2FnZTIsIG1lc3NhZ2UxX2ZpZWxkcywgbWVzc2FnZTJfZmllbGRzLCAmcGFyZW50X2ZpZWxkcyk7CisgIH0KKworICByZXR1cm4gcmVzdWx0OworfQorCitib29sIE1lc3NhZ2VEaWZmZXJlbmNlcjo6Q29tcGFyZSgKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlMSwKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlMiwKKyAgICB2ZWN0b3I8U3BlY2lmaWNGaWVsZD4qIHBhcmVudF9maWVsZHMpIHsKKyAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcjEgPSBtZXNzYWdlMS5HZXREZXNjcmlwdG9yKCk7CisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IyID0gbWVzc2FnZTIuR2V0RGVzY3JpcHRvcigpOworICBpZiAoZGVzY3JpcHRvcjEgIT0gZGVzY3JpcHRvcjIpIHsKKyAgICBHT09HTEVfTE9HKERGQVRBTCkgPDwgIkNvbXBhcmlzb24gYmV0d2VlbiB0d28gbWVzc2FnZXMgd2l0aCBkaWZmZXJlbnQgIgorICAgICAgICAgICAgICAgIDw8ICJkZXNjcmlwdG9ycy4iOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICAvLyBFeHBhbmQgZ29vZ2xlLnByb3RvYnVmLkFueSBwYXlsb2FkIGlmIHBvc3NpYmxlLgorICBpZiAoZGVzY3JpcHRvcjEtPmZ1bGxfbmFtZSgpID09IGludGVybmFsOjprQW55RnVsbFR5cGVOYW1lKSB7CisgICAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxNZXNzYWdlPiBkYXRhMTsKKyAgICBnb29nbGU6OnByb3RvYnVmOjpzY29wZWRfcHRyPE1lc3NhZ2U+IGRhdGEyOworICAgIGlmIChVbnBhY2tBbnkobWVzc2FnZTEsICZkYXRhMSkgJiYgVW5wYWNrQW55KG1lc3NhZ2UyLCAmZGF0YTIpKSB7CisgICAgICByZXR1cm4gQ29tcGFyZSgqZGF0YTEsICpkYXRhMiwgcGFyZW50X2ZpZWxkcyk7CisgICAgfQorICB9CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24xID0gbWVzc2FnZTEuR2V0UmVmbGVjdGlvbigpOworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uMiA9IG1lc3NhZ2UyLkdldFJlZmxlY3Rpb24oKTsKKworICAvLyBSZXRyaWV2ZSBhbGwgdGhlIHNldCBmaWVsZHMsIGluY2x1ZGluZyBleHRlbnNpb25zLgorICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4gbWVzc2FnZTFfZmllbGRzOworICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4gbWVzc2FnZTJfZmllbGRzOworCisgIHJlZmxlY3Rpb24xLT5MaXN0RmllbGRzKG1lc3NhZ2UxLCAmbWVzc2FnZTFfZmllbGRzKTsKKyAgcmVmbGVjdGlvbjItPkxpc3RGaWVsZHMobWVzc2FnZTIsICZtZXNzYWdlMl9maWVsZHMpOworCisgIC8vIEFkZCBzZW50aW5lbCB2YWx1ZXMgdG8gZGVhbCB3aXRoIHRoZQorICAvLyBjYXNlIHdoZXJlIHRoZSBudW1iZXIgb2YgdGhlIGZpZWxkcyBpbgorICAvLyBlYWNoIGxpc3QgYXJlIGRpZmZlcmVudC4KKyAgbWVzc2FnZTFfZmllbGRzLnB1c2hfYmFjayhOVUxMKTsKKyAgbWVzc2FnZTJfZmllbGRzLnB1c2hfYmFjayhOVUxMKTsKKworICBib29sIHVua25vd25fY29tcGFyZV9yZXN1bHQgPSB0cnVlOworICAvLyBJZ25vcmUgdW5rbm93biBmaWVsZHMgaW4gRVFVSVZBTEVOVCBtb2RlCisgIGlmIChtZXNzYWdlX2ZpZWxkX2NvbXBhcmlzb25fICE9IEVRVUlWQUxFTlQpIHsKKyAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpVbmtub3duRmllbGRTZXQqIHVua25vd25fZmllbGRfc2V0MSA9CisgICAgICAgICZyZWZsZWN0aW9uMS0+R2V0VW5rbm93bkZpZWxkcyhtZXNzYWdlMSk7CisgICAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6VW5rbm93bkZpZWxkU2V0KiB1bmtub3duX2ZpZWxkX3NldDIgPQorICAgICAgICAmcmVmbGVjdGlvbjItPkdldFVua25vd25GaWVsZHMobWVzc2FnZTIpOworICAgIGlmICghQ29tcGFyZVVua25vd25GaWVsZHMobWVzc2FnZTEsIG1lc3NhZ2UyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKnVua25vd25fZmllbGRfc2V0MSwgKnVua25vd25fZmllbGRfc2V0MiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudF9maWVsZHMpKSB7CisgICAgICBpZiAocmVwb3J0ZXJfID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfTsKKyAgICAgIHVua25vd25fY29tcGFyZV9yZXN1bHQgPSBmYWxzZTsKKyAgICB9CisgIH0KKworICByZXR1cm4gQ29tcGFyZVJlcXVlc3RlZEZpZWxkc1VzaW5nU2V0dGluZ3MoCisgICAgICBtZXNzYWdlMSwgbWVzc2FnZTIsCisgICAgICBtZXNzYWdlMV9maWVsZHMsIG1lc3NhZ2UyX2ZpZWxkcywKKyAgICAgIHBhcmVudF9maWVsZHMpICYmIHVua25vd25fY29tcGFyZV9yZXN1bHQ7Cit9CisKK2Jvb2wgTWVzc2FnZURpZmZlcmVuY2VyOjpDb21wYXJlUmVxdWVzdGVkRmllbGRzVXNpbmdTZXR0aW5ncygKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlMSwKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlMiwKKyAgICBjb25zdCB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4mIG1lc3NhZ2UxX2ZpZWxkcywKKyAgICBjb25zdCB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4mIG1lc3NhZ2UyX2ZpZWxkcywKKyAgICB2ZWN0b3I8U3BlY2lmaWNGaWVsZD4qIHBhcmVudF9maWVsZHMpIHsKKyAgaWYgKHNjb3BlXyA9PSBGVUxMKSB7CisgICAgaWYgKG1lc3NhZ2VfZmllbGRfY29tcGFyaXNvbl8gPT0gRVFVSVZBTEVOVCkgeworICAgICAgLy8gV2UgbmVlZCB0byBtZXJnZSB0aGUgZmllbGQgbGlzdHMgb2YgYm90aCBtZXNzYWdlcyAoaS5lLgorICAgICAgLy8gd2UgYXJlIG1lcmVseSBjaGVja2luZyBmb3IgYSBkaWZmZXJlbmNlIGluIGZpZWxkIHZhbHVlcywKKyAgICAgIC8vIHJhdGhlciB0aGFuIHRoZSBhZGRpdGlvbiBvciBkZWxldGlvbiBvZiBmaWVsZHMpLgorICAgICAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+IGZpZWxkc191bmlvbjsKKyAgICAgIENvbWJpbmVGaWVsZHMobWVzc2FnZTFfZmllbGRzLCBGVUxMLCBtZXNzYWdlMl9maWVsZHMsIEZVTEwsCisgICAgICAgICAgICAgICAgICAgICZmaWVsZHNfdW5pb24pOworICAgICAgcmV0dXJuIENvbXBhcmVXaXRoRmllbGRzSW50ZXJuYWwobWVzc2FnZTEsIG1lc3NhZ2UyLCBmaWVsZHNfdW5pb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZHNfdW5pb24sIHBhcmVudF9maWVsZHMpOworICAgIH0gZWxzZSB7CisgICAgICAvLyBTaW1wbGUgZXF1YWxpdHkgY29tcGFyaXNvbiwgdXNlIHRoZSB1bmFsdGVyZWQgZmllbGQgbGlzdHMuCisgICAgICByZXR1cm4gQ29tcGFyZVdpdGhGaWVsZHNJbnRlcm5hbChtZXNzYWdlMSwgbWVzc2FnZTIsIG1lc3NhZ2UxX2ZpZWxkcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UyX2ZpZWxkcywgcGFyZW50X2ZpZWxkcyk7CisgICAgfQorICB9IGVsc2UgeworICAgIGlmIChtZXNzYWdlX2ZpZWxkX2NvbXBhcmlzb25fID09IEVRVUlWQUxFTlQpIHsKKyAgICAgIC8vIFdlIHVzZSB0aGUgbGlzdCBvZiBmaWVsZHMgZm9yIG1lc3NhZ2UxIGZvciBib3RoIG1lc3NhZ2VzIHdoZW4KKyAgICAgIC8vIGNvbXBhcmluZy4gIFRoaXMgd2F5LCBleHRyYSBmaWVsZHMgaW4gbWVzc2FnZTIgYXJlIGlnbm9yZWQsCisgICAgICAvLyBhbmQgbWlzc2luZyBmaWVsZHMgaW4gbWVzc2FnZTIgdXNlIHRoZWlyIGRlZmF1bHQgdmFsdWUuCisgICAgICByZXR1cm4gQ29tcGFyZVdpdGhGaWVsZHNJbnRlcm5hbChtZXNzYWdlMSwgbWVzc2FnZTIsIG1lc3NhZ2UxX2ZpZWxkcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UxX2ZpZWxkcywgcGFyZW50X2ZpZWxkcyk7CisgICAgfSBlbHNlIHsKKyAgICAgIC8vIFdlIG5lZWQgdG8gY29uc2lkZXIgdGhlIGZ1bGwgbGlzdCBvZiBmaWVsZHMgZm9yIG1lc3NhZ2UxCisgICAgICAvLyBidXQgb25seSB0aGUgaW50ZXJzZWN0aW9uIGZvciBtZXNzYWdlMi4gIFRoaXMgd2F5LCBhbnkgZmllbGRzCisgICAgICAvLyBvbmx5IHByZXNlbnQgaW4gbWVzc2FnZTIgd2lsbCBiZSBpZ25vcmVkLCBidXQgYW55IGZpZWxkcyBvbmx5CisgICAgICAvLyBwcmVzZW50IGluIG1lc3NhZ2UxIHdpbGwgYmUgbWFya2VkIGFzIGEgZGlmZmVyZW5jZS4KKyAgICAgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBmaWVsZHNfaW50ZXJzZWN0aW9uOworICAgICAgQ29tYmluZUZpZWxkcyhtZXNzYWdlMV9maWVsZHMsIFBBUlRJQUwsIG1lc3NhZ2UyX2ZpZWxkcywgUEFSVElBTCwKKyAgICAgICAgICAgICAgICAgICAgJmZpZWxkc19pbnRlcnNlY3Rpb24pOworICAgICAgcmV0dXJuIENvbXBhcmVXaXRoRmllbGRzSW50ZXJuYWwobWVzc2FnZTEsIG1lc3NhZ2UyLCBtZXNzYWdlMV9maWVsZHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZHNfaW50ZXJzZWN0aW9uLCBwYXJlbnRfZmllbGRzKTsKKyAgICB9CisgIH0KK30KKwordm9pZCBNZXNzYWdlRGlmZmVyZW5jZXI6OkNvbWJpbmVGaWVsZHMoCisgICAgY29uc3QgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+JiBmaWVsZHMxLAorICAgIFNjb3BlIGZpZWxkczFfc2NvcGUsCisgICAgY29uc3QgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+JiBmaWVsZHMyLAorICAgIFNjb3BlIGZpZWxkczJfc2NvcGUsCisgICAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+KiBjb21iaW5lZF9maWVsZHMpIHsKKworICBpbnQgaW5kZXgxID0gMDsKKyAgaW50IGluZGV4MiA9IDA7CisKKyAgd2hpbGUgKGluZGV4MSA8IGZpZWxkczEuc2l6ZSgpICYmIGluZGV4MiA8IGZpZWxkczIuc2l6ZSgpKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZDEgPSBmaWVsZHMxW2luZGV4MV07CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZDIgPSBmaWVsZHMyW2luZGV4Ml07CisKKyAgICBpZiAoRmllbGRCZWZvcmUoZmllbGQxLCBmaWVsZDIpKSB7CisgICAgICBpZiAoZmllbGRzMV9zY29wZSA9PSBGVUxMKSB7CisgICAgICAgIGNvbWJpbmVkX2ZpZWxkcy0+cHVzaF9iYWNrKGZpZWxkczFbaW5kZXgxXSk7CisgICAgICB9CisgICAgICArK2luZGV4MTsKKyAgICB9IGVsc2UgaWYgKEZpZWxkQmVmb3JlKGZpZWxkMiwgZmllbGQxKSkgeworICAgICAgaWYgKGZpZWxkczJfc2NvcGUgPT0gRlVMTCkgeworICAgICAgICBjb21iaW5lZF9maWVsZHMtPnB1c2hfYmFjayhmaWVsZHMyW2luZGV4Ml0pOworICAgICAgfQorICAgICAgKytpbmRleDI7CisgICAgfSBlbHNlIHsKKyAgICAgIGNvbWJpbmVkX2ZpZWxkcy0+cHVzaF9iYWNrKGZpZWxkczFbaW5kZXgxXSk7CisgICAgICArK2luZGV4MTsKKyAgICAgICsraW5kZXgyOworICAgIH0KKyAgfQorfQorCitib29sIE1lc3NhZ2VEaWZmZXJlbmNlcjo6Q29tcGFyZVdpdGhGaWVsZHNJbnRlcm5hbCgKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlMSwKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlMiwKKyAgICBjb25zdCB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4mIG1lc3NhZ2UxX2ZpZWxkcywKKyAgICBjb25zdCB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4mIG1lc3NhZ2UyX2ZpZWxkcywKKyAgICB2ZWN0b3I8U3BlY2lmaWNGaWVsZD4qIHBhcmVudF9maWVsZHMpIHsKKyAgYm9vbCBpc0RpZmZlcmVudCA9IGZhbHNlOworICBpbnQgZmllbGRfaW5kZXgxID0gMDsKKyAgaW50IGZpZWxkX2luZGV4MiA9IDA7CisKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbjEgPSBtZXNzYWdlMS5HZXRSZWZsZWN0aW9uKCk7CisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24yID0gbWVzc2FnZTIuR2V0UmVmbGVjdGlvbigpOworCisgIHdoaWxlICh0cnVlKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZDEgPSBtZXNzYWdlMV9maWVsZHNbZmllbGRfaW5kZXgxXTsKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkMiA9IG1lc3NhZ2UyX2ZpZWxkc1tmaWVsZF9pbmRleDJdOworCisgICAgLy8gT25jZSB3ZSBoYXZlIHJlYWNoZWQgc2VudGluZWwgdmFsdWVzLCB3ZSBhcmUgZG9uZSB0aGUgY29tcGFyaXNvbi4KKyAgICBpZiAoZmllbGQxID09IE5VTEwgJiYgZmllbGQyID09IE5VTEwpIHsKKyAgICAgIGJyZWFrOworICAgIH0KKworICAgIC8vIENoZWNrIGZvciBkaWZmZXJlbmNlcyBpbiB0aGUgZmllbGQgaXRzZWxmLgorICAgIGlmIChGaWVsZEJlZm9yZShmaWVsZDEsIGZpZWxkMikpIHsKKyAgICAgIC8vIEZpZWxkIDEgaXMgbm90IGluIHRoZSBmaWVsZCBsaXN0IGZvciBtZXNzYWdlIDIuCisgICAgICBpZiAoSXNJZ25vcmVkKG1lc3NhZ2UxLCBtZXNzYWdlMiwgZmllbGQxLCAqcGFyZW50X2ZpZWxkcykpIHsKKyAgICAgICAgLy8gV2UgYXJlIGlnbm9yaW5nIGZpZWxkMS4gUmVwb3J0IHRoZSBpZ25vcmUgYW5kIG1vdmUgb24gdG8KKyAgICAgICAgLy8gdGhlIG5leHQgZmllbGQgaW4gbWVzc2FnZTFfZmllbGRzLgorICAgICAgICBpZiAocmVwb3J0ZXJfICE9IE5VTEwpIHsKKyAgICAgICAgICBTcGVjaWZpY0ZpZWxkIHNwZWNpZmljX2ZpZWxkOworICAgICAgICAgIHNwZWNpZmljX2ZpZWxkLmZpZWxkID0gZmllbGQxOworCisgICAgICAgICAgcGFyZW50X2ZpZWxkcy0+cHVzaF9iYWNrKHNwZWNpZmljX2ZpZWxkKTsKKyAgICAgICAgICByZXBvcnRlcl8tPlJlcG9ydElnbm9yZWQobWVzc2FnZTEsIG1lc3NhZ2UyLCAqcGFyZW50X2ZpZWxkcyk7CisgICAgICAgICAgcGFyZW50X2ZpZWxkcy0+cG9wX2JhY2soKTsKKyAgICAgICAgfQorICAgICAgICArK2ZpZWxkX2luZGV4MTsKKyAgICAgICAgY29udGludWU7CisgICAgICB9CisKKyAgICAgIGlmIChyZXBvcnRlcl8gIT0gTlVMTCkgeworICAgICAgICBpbnQgY291bnQgPSBmaWVsZDEtPmlzX3JlcGVhdGVkKCkgPworICAgICAgICAgICAgcmVmbGVjdGlvbjEtPkZpZWxkU2l6ZShtZXNzYWdlMSwgZmllbGQxKSA6IDE7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgKytpKSB7CisgICAgICAgICAgU3BlY2lmaWNGaWVsZCBzcGVjaWZpY19maWVsZDsKKyAgICAgICAgICBzcGVjaWZpY19maWVsZC5maWVsZCA9IGZpZWxkMTsKKyAgICAgICAgICBzcGVjaWZpY19maWVsZC5pbmRleCA9IGZpZWxkMS0+aXNfcmVwZWF0ZWQoKSA/IGkgOiAtMTsKKworICAgICAgICAgIHBhcmVudF9maWVsZHMtPnB1c2hfYmFjayhzcGVjaWZpY19maWVsZCk7CisgICAgICAgICAgcmVwb3J0ZXJfLT5SZXBvcnREZWxldGVkKG1lc3NhZ2UxLCBtZXNzYWdlMiwgKnBhcmVudF9maWVsZHMpOworICAgICAgICAgIHBhcmVudF9maWVsZHMtPnBvcF9iYWNrKCk7CisgICAgICAgIH0KKworICAgICAgICBpc0RpZmZlcmVudCA9IHRydWU7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisKKyAgICAgICsrZmllbGRfaW5kZXgxOworICAgICAgY29udGludWU7CisgICAgfSBlbHNlIGlmIChGaWVsZEJlZm9yZShmaWVsZDIsIGZpZWxkMSkpIHsKKyAgICAgIC8vIEZpZWxkIDIgaXMgbm90IGluIHRoZSBmaWVsZCBsaXN0IGZvciBtZXNzYWdlIDEuCisgICAgICBpZiAoSXNJZ25vcmVkKG1lc3NhZ2UxLCBtZXNzYWdlMiwgZmllbGQyLCAqcGFyZW50X2ZpZWxkcykpIHsKKyAgICAgICAgLy8gV2UgYXJlIGlnbm9yaW5nIGZpZWxkMi4gUmVwb3J0IHRoZSBpZ25vcmUgYW5kIG1vdmUgb24gdG8KKyAgICAgICAgLy8gdGhlIG5leHQgZmllbGQgaW4gbWVzc2FnZTJfZmllbGRzLgorICAgICAgICBpZiAocmVwb3J0ZXJfICE9IE5VTEwpIHsKKyAgICAgICAgICBTcGVjaWZpY0ZpZWxkIHNwZWNpZmljX2ZpZWxkOworICAgICAgICAgIHNwZWNpZmljX2ZpZWxkLmZpZWxkID0gZmllbGQyOworCisgICAgICAgICAgcGFyZW50X2ZpZWxkcy0+cHVzaF9iYWNrKHNwZWNpZmljX2ZpZWxkKTsKKyAgICAgICAgICByZXBvcnRlcl8tPlJlcG9ydElnbm9yZWQobWVzc2FnZTEsIG1lc3NhZ2UyLCAqcGFyZW50X2ZpZWxkcyk7CisgICAgICAgICAgcGFyZW50X2ZpZWxkcy0+cG9wX2JhY2soKTsKKyAgICAgICAgfQorICAgICAgICArK2ZpZWxkX2luZGV4MjsKKyAgICAgICAgY29udGludWU7CisgICAgICB9CisKKyAgICAgIGlmIChyZXBvcnRlcl8gIT0gTlVMTCkgeworICAgICAgICBpbnQgY291bnQgPSBmaWVsZDItPmlzX3JlcGVhdGVkKCkgPworICAgICAgICAgICAgcmVmbGVjdGlvbjItPkZpZWxkU2l6ZShtZXNzYWdlMiwgZmllbGQyKSA6IDE7CisKKyAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgKytpKSB7CisgICAgICAgICAgU3BlY2lmaWNGaWVsZCBzcGVjaWZpY19maWVsZDsKKyAgICAgICAgICBzcGVjaWZpY19maWVsZC5maWVsZCA9IGZpZWxkMjsKKyAgICAgICAgICBzcGVjaWZpY19maWVsZC5pbmRleCA9IGZpZWxkMi0+aXNfcmVwZWF0ZWQoKSA/IGkgOiAtMTsKKyAgICAgICAgICBzcGVjaWZpY19maWVsZC5uZXdfaW5kZXggPSBzcGVjaWZpY19maWVsZC5pbmRleDsKKworICAgICAgICAgIHBhcmVudF9maWVsZHMtPnB1c2hfYmFjayhzcGVjaWZpY19maWVsZCk7CisgICAgICAgICAgcmVwb3J0ZXJfLT5SZXBvcnRBZGRlZChtZXNzYWdlMSwgbWVzc2FnZTIsICpwYXJlbnRfZmllbGRzKTsKKyAgICAgICAgICBwYXJlbnRfZmllbGRzLT5wb3BfYmFjaygpOworICAgICAgICB9CisKKyAgICAgICAgaXNEaWZmZXJlbnQgPSB0cnVlOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorCisgICAgICArK2ZpZWxkX2luZGV4MjsKKyAgICAgIGNvbnRpbnVlOworICAgIH0KKworICAgIC8vIEJ5IHRoaXMgcG9pbnQsIGZpZWxkMSBhbmQgZmllbGQyIGFyZSBndWFyZW50ZWVkIHRvIHBvaW50IHRvIHRoZSBzYW1lCisgICAgLy8gZmllbGQsIHNvIHdlIGNhbiBub3cgY29tcGFyZSB0aGUgdmFsdWVzLgorICAgIGlmIChJc0lnbm9yZWQobWVzc2FnZTEsIG1lc3NhZ2UyLCBmaWVsZDEsICpwYXJlbnRfZmllbGRzKSkgeworICAgICAgLy8gSWdub3JlIHRoaXMgZmllbGQuIFJlcG9ydCBhbmQgbW92ZSBvbi4KKyAgICAgIGlmIChyZXBvcnRlcl8gIT0gTlVMTCkgeworICAgICAgICBTcGVjaWZpY0ZpZWxkIHNwZWNpZmljX2ZpZWxkOworICAgICAgICBzcGVjaWZpY19maWVsZC5maWVsZCA9IGZpZWxkMTsKKworICAgICAgICBwYXJlbnRfZmllbGRzLT5wdXNoX2JhY2soc3BlY2lmaWNfZmllbGQpOworICAgICAgICByZXBvcnRlcl8tPlJlcG9ydElnbm9yZWQobWVzc2FnZTEsIG1lc3NhZ2UyLCAqcGFyZW50X2ZpZWxkcyk7CisgICAgICAgIHBhcmVudF9maWVsZHMtPnBvcF9iYWNrKCk7CisgICAgICB9CisKKyAgICAgICsrZmllbGRfaW5kZXgxOworICAgICAgKytmaWVsZF9pbmRleDI7CisgICAgICBjb250aW51ZTsKKyAgICB9CisKKyAgICBib29sIGZpZWxkRGlmZmVyZW50ID0gZmFsc2U7CisgICAgaWYgKGZpZWxkMS0+aXNfcmVwZWF0ZWQoKSkgeworICAgICAgZmllbGREaWZmZXJlbnQgPSAhQ29tcGFyZVJlcGVhdGVkRmllbGQobWVzc2FnZTEsIG1lc3NhZ2UyLCBmaWVsZDEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnRfZmllbGRzKTsKKyAgICAgIGlmIChmaWVsZERpZmZlcmVudCkgeworICAgICAgICBpZiAocmVwb3J0ZXJfID09IE5VTEwpIHJldHVybiBmYWxzZTsKKyAgICAgICAgaXNEaWZmZXJlbnQgPSB0cnVlOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICBmaWVsZERpZmZlcmVudCA9ICFDb21wYXJlRmllbGRWYWx1ZVVzaW5nUGFyZW50RmllbGRzKAorICAgICAgICAgIG1lc3NhZ2UxLCBtZXNzYWdlMiwgZmllbGQxLCAtMSwgLTEsIHBhcmVudF9maWVsZHMpOworCisgICAgICAvLyBJZiB3ZSBoYXZlIGZvdW5kIGRpZmZlcmVuY2VzLCBlaXRoZXIgcmVwb3J0IHRoZW0gb3IgdGVybWluYXRlIGlmCisgICAgICAvLyBubyByZXBvcnRlciBpcyBwcmVzZW50LgorICAgICAgaWYgKGZpZWxkRGlmZmVyZW50ICYmIHJlcG9ydGVyXyA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKworICAgICAgaWYgKHJlcG9ydGVyXyAhPSBOVUxMKSB7CisgICAgICAgIFNwZWNpZmljRmllbGQgc3BlY2lmaWNfZmllbGQ7CisgICAgICAgIHNwZWNpZmljX2ZpZWxkLmZpZWxkID0gZmllbGQxOworICAgICAgICBwYXJlbnRfZmllbGRzLT5wdXNoX2JhY2soc3BlY2lmaWNfZmllbGQpOworICAgICAgICBpZiAoZmllbGREaWZmZXJlbnQpIHsKKyAgICAgICAgICByZXBvcnRlcl8tPlJlcG9ydE1vZGlmaWVkKG1lc3NhZ2UxLCBtZXNzYWdlMiwgKnBhcmVudF9maWVsZHMpOworICAgICAgICAgIGlzRGlmZmVyZW50ID0gdHJ1ZTsKKyAgICAgICAgfSBlbHNlIGlmIChyZXBvcnRfbWF0Y2hlc18pIHsKKyAgICAgICAgICByZXBvcnRlcl8tPlJlcG9ydE1hdGNoZWQobWVzc2FnZTEsIG1lc3NhZ2UyLCAqcGFyZW50X2ZpZWxkcyk7CisgICAgICAgIH0KKyAgICAgICAgcGFyZW50X2ZpZWxkcy0+cG9wX2JhY2soKTsKKyAgICAgIH0KKyAgICB9CisgICAgLy8gSW5jcmVtZW50IHRoZSBmaWVsZCBpbmRpY2llcy4KKyAgICArK2ZpZWxkX2luZGV4MTsKKyAgICArK2ZpZWxkX2luZGV4MjsKKyAgfQorCisgIHJldHVybiAhaXNEaWZmZXJlbnQ7Cit9CisKK2Jvb2wgTWVzc2FnZURpZmZlcmVuY2VyOjpJc01hdGNoKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogcmVwZWF0ZWRfZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNYXBLZXlDb21wYXJhdG9yKiBrZXlfY29tcGFyYXRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2UqIG1lc3NhZ2UxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZSogbWVzc2FnZTIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2ZWN0b3I8U3BlY2lmaWNGaWVsZD4mIHBhcmVudF9maWVsZHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXgxLCBpbnQgaW5kZXgyKSB7CisgIHZlY3RvcjxTcGVjaWZpY0ZpZWxkPiBjdXJyZW50X3BhcmVudF9maWVsZHMocGFyZW50X2ZpZWxkcyk7CisgIGlmIChyZXBlYXRlZF9maWVsZC0+Y3BwX3R5cGUoKSAhPSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSkgeworICAgIHJldHVybiBDb21wYXJlRmllbGRWYWx1ZVVzaW5nUGFyZW50RmllbGRzKAorICAgICAgICAqbWVzc2FnZTEsICptZXNzYWdlMiwgcmVwZWF0ZWRfZmllbGQsIGluZGV4MSwgaW5kZXgyLAorICAgICAgICAmY3VycmVudF9wYXJlbnRfZmllbGRzKTsKKyAgfQorICAvLyBCYWNrIHVwIHRoZSBSZXBvcnRlciBhbmQgb3V0cHV0X3N0cmluZ18uICBUaGV5IHdpbGwgYmUgcmVzZXQgaW4gdGhlCisgIC8vIGZvbGxvd2luZyBjb2RlLgorICBSZXBvcnRlciogYmFja3VwX3JlcG9ydGVyID0gcmVwb3J0ZXJfOworICBzdHJpbmcqIG91dHB1dF9zdHJpbmcgPSBvdXRwdXRfc3RyaW5nXzsKKyAgcmVwb3J0ZXJfID0gTlVMTDsKKyAgb3V0cHV0X3N0cmluZ18gPSBOVUxMOworICBib29sIG1hdGNoOworCisgIGlmIChrZXlfY29tcGFyYXRvciA9PSBOVUxMKSB7CisgICAgbWF0Y2ggPSBDb21wYXJlRmllbGRWYWx1ZVVzaW5nUGFyZW50RmllbGRzKAorICAgICAgICAqbWVzc2FnZTEsICptZXNzYWdlMiwgcmVwZWF0ZWRfZmllbGQsIGluZGV4MSwgaW5kZXgyLAorICAgICAgICAmY3VycmVudF9wYXJlbnRfZmllbGRzKTsKKyAgfSBlbHNlIHsKKyAgICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uMSA9IG1lc3NhZ2UxLT5HZXRSZWZsZWN0aW9uKCk7CisgICAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbjIgPSBtZXNzYWdlMi0+R2V0UmVmbGVjdGlvbigpOworICAgIGNvbnN0IE1lc3NhZ2UmIG0xID0KKyAgICAgICAgcmVmbGVjdGlvbjEtPkdldFJlcGVhdGVkTWVzc2FnZSgqbWVzc2FnZTEsIHJlcGVhdGVkX2ZpZWxkLCBpbmRleDEpOworICAgIGNvbnN0IE1lc3NhZ2UmIG0yID0KKyAgICAgICAgcmVmbGVjdGlvbjItPkdldFJlcGVhdGVkTWVzc2FnZSgqbWVzc2FnZTIsIHJlcGVhdGVkX2ZpZWxkLCBpbmRleDIpOworICAgIFNwZWNpZmljRmllbGQgc3BlY2lmaWNfZmllbGQ7CisgICAgc3BlY2lmaWNfZmllbGQuZmllbGQgPSByZXBlYXRlZF9maWVsZDsKKyAgICBjdXJyZW50X3BhcmVudF9maWVsZHMucHVzaF9iYWNrKHNwZWNpZmljX2ZpZWxkKTsKKyAgICBtYXRjaCA9IGtleV9jb21wYXJhdG9yLT5Jc01hdGNoKG0xLCBtMiwgY3VycmVudF9wYXJlbnRfZmllbGRzKTsKKyAgfQorCisgIHJlcG9ydGVyXyA9IGJhY2t1cF9yZXBvcnRlcjsKKyAgb3V0cHV0X3N0cmluZ18gPSBvdXRwdXRfc3RyaW5nOworICByZXR1cm4gbWF0Y2g7Cit9CisKK2Jvb2wgTWVzc2FnZURpZmZlcmVuY2VyOjpDb21wYXJlUmVwZWF0ZWRGaWVsZCgKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlMSwKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlMiwKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHJlcGVhdGVkX2ZpZWxkLAorICAgIHZlY3RvcjxTcGVjaWZpY0ZpZWxkPiogcGFyZW50X2ZpZWxkcykgeworICAvLyB0aGUgaW5wdXQgRmllbGREZXNjcmlwdG9yIGlzIGd1YXJhbnRlZWQgdG8gYmUgcmVwZWF0ZWQgZmllbGQuCisgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24xID0gbWVzc2FnZTEuR2V0UmVmbGVjdGlvbigpOworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uMiA9IG1lc3NhZ2UyLkdldFJlZmxlY3Rpb24oKTsKKyAgY29uc3QgaW50IGNvdW50MSA9IHJlZmxlY3Rpb24xLT5GaWVsZFNpemUobWVzc2FnZTEsIHJlcGVhdGVkX2ZpZWxkKTsKKyAgY29uc3QgaW50IGNvdW50MiA9IHJlZmxlY3Rpb24yLT5GaWVsZFNpemUobWVzc2FnZTIsIHJlcGVhdGVkX2ZpZWxkKTsKKyAgY29uc3QgYm9vbCB0cmVhdGVkX2FzX3N1YnNldCA9IElzVHJlYXRlZEFzU3Vic2V0KHJlcGVhdGVkX2ZpZWxkKTsKKworICAvLyBJZiB0aGUgZmllbGQgaXMgbm90IHRyZWF0ZWQgYXMgc3Vic2V0IGFuZCBubyBkZXRhaWxlZCByZXBvcnRzIGlzIG5lZWRlZCwKKyAgLy8gd2UgZG8gYSBxdWljayBjaGVjayBvbiB0aGUgbnVtYmVyIG9mIHRoZSBlbGVtZW50cyB0byBhdm9pZCB1bm5lY2Vzc2FyeQorICAvLyBjb21wYXJpc29uLgorICBpZiAoY291bnQxICE9IGNvdW50MiAmJiByZXBvcnRlcl8gPT0gTlVMTCAmJiAhdHJlYXRlZF9hc19zdWJzZXQpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgLy8gQSBtYXRjaCBjYW4gbmV2ZXIgYmUgZm91bmQgaWYgbWVzc2FnZTEgaGFzIG1vcmUgaXRlbXMgdGhhbiBtZXNzYWdlMi4KKyAgaWYgKGNvdW50MSA+IGNvdW50MiAmJiByZXBvcnRlcl8gPT0gTlVMTCkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vIFRoZXNlIHR3byBsaXN0IGFyZSB1c2VkIGZvciBzdG9yZSB0aGUgaW5kZXggb2YgdGhlIGNvcnJlc3BvbmRlbnQKKyAgLy8gZWxlbWVudCBpbiBwZWVyIHJlcGVhdGVkIGZpZWxkLgorICB2ZWN0b3I8aW50PiBtYXRjaF9saXN0MTsKKyAgdmVjdG9yPGludD4gbWF0Y2hfbGlzdDI7CisKKyAgLy8gVHJ5IHRvIG1hdGNoIGluZGljZXMgb2YgdGhlIHJlcGVhdGVkIGZpZWxkcy4gUmV0dXJuIGZhbHNlIGlmIG1hdGNoIGZhaWxzCisgIC8vIGFuZCB0aGVyZSdzIG5vIGRldGFpbGVkIHJlcG9ydCBuZWVkZWQuCisgIGlmICghTWF0Y2hSZXBlYXRlZEZpZWxkSW5kaWNlcyhtZXNzYWdlMSwgbWVzc2FnZTIsIHJlcGVhdGVkX2ZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKnBhcmVudF9maWVsZHMsICZtYXRjaF9saXN0MSwgJm1hdGNoX2xpc3QyKSAmJgorICAgICAgcmVwb3J0ZXJfID09IE5VTEwpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBib29sIGZpZWxkRGlmZmVyZW50ID0gZmFsc2U7CisgIFNwZWNpZmljRmllbGQgc3BlY2lmaWNfZmllbGQ7CisgIHNwZWNpZmljX2ZpZWxkLmZpZWxkID0gcmVwZWF0ZWRfZmllbGQ7CisKKyAgLy8gQXQgdGhpcyBwb2ludCwgd2UgaGF2ZSBhbHJlYWR5IG1hdGNoZWQgcGFpcnMgb2YgZmllbGRzICh3aXRoIHRoZSByZXBvcnRpbmcKKyAgLy8gdG8gYmUgZG9uZSBsYXRlcikuIE5vdyB0byBjaGVjayBpZiB0aGUgcGFpcmVkIGVsZW1lbnRzIGFyZSBkaWZmZXJlbnQuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQxOyBpKyspIHsKKyAgICBpZiAobWF0Y2hfbGlzdDFbaV0gPT0gLTEpIGNvbnRpbnVlOworICAgIHNwZWNpZmljX2ZpZWxkLmluZGV4ID0gaTsKKyAgICBzcGVjaWZpY19maWVsZC5uZXdfaW5kZXggPSBtYXRjaF9saXN0MVtpXTsKKworICAgIGNvbnN0IGJvb2wgcmVzdWx0ID0gQ29tcGFyZUZpZWxkVmFsdWVVc2luZ1BhcmVudEZpZWxkcygKKyAgICAgICAgbWVzc2FnZTEsIG1lc3NhZ2UyLCByZXBlYXRlZF9maWVsZCwgaSwgc3BlY2lmaWNfZmllbGQubmV3X2luZGV4LAorICAgICAgICBwYXJlbnRfZmllbGRzKTsKKworICAgIC8vIElmIHdlIGhhdmUgZm91bmQgZGlmZmVyZW5jZXMsIGVpdGhlciByZXBvcnQgdGhlbSBvciB0ZXJtaW5hdGUgaWYKKyAgICAvLyBubyByZXBvcnRlciBpcyBwcmVzZW50LiBOb3RlIHRoYXQgUmVwb3J0TW9kaWZpZWQsIFJlcG9ydE1vdmVkLCBhbmQKKyAgICAvLyBSZXBvcnRNYXRjaGVkIGFyZSBhbGwgbXV0dWFsbHkgZXhjbHVzaXZlLgorICAgIGlmICghcmVzdWx0KSB7CisgICAgICBpZiAocmVwb3J0ZXJfID09IE5VTEwpIHJldHVybiBmYWxzZTsKKyAgICAgIHBhcmVudF9maWVsZHMtPnB1c2hfYmFjayhzcGVjaWZpY19maWVsZCk7CisgICAgICByZXBvcnRlcl8tPlJlcG9ydE1vZGlmaWVkKG1lc3NhZ2UxLCBtZXNzYWdlMiwgKnBhcmVudF9maWVsZHMpOworICAgICAgcGFyZW50X2ZpZWxkcy0+cG9wX2JhY2soKTsKKyAgICAgIGZpZWxkRGlmZmVyZW50ID0gdHJ1ZTsKKyAgICB9IGVsc2UgaWYgKHJlcG9ydGVyXyAhPSBOVUxMICYmCisgICAgICAgICAgICAgICBzcGVjaWZpY19maWVsZC5pbmRleCAhPSBzcGVjaWZpY19maWVsZC5uZXdfaW5kZXgpIHsKKyAgICAgIHBhcmVudF9maWVsZHMtPnB1c2hfYmFjayhzcGVjaWZpY19maWVsZCk7CisgICAgICByZXBvcnRlcl8tPlJlcG9ydE1vdmVkKG1lc3NhZ2UxLCBtZXNzYWdlMiwgKnBhcmVudF9maWVsZHMpOworICAgICAgcGFyZW50X2ZpZWxkcy0+cG9wX2JhY2soKTsKKyAgICB9IGVsc2UgaWYgKHJlcG9ydF9tYXRjaGVzXyAmJiByZXBvcnRlcl8gIT0gTlVMTCkgeworICAgICAgcGFyZW50X2ZpZWxkcy0+cHVzaF9iYWNrKHNwZWNpZmljX2ZpZWxkKTsKKyAgICAgIHJlcG9ydGVyXy0+UmVwb3J0TWF0Y2hlZChtZXNzYWdlMSwgbWVzc2FnZTIsICpwYXJlbnRfZmllbGRzKTsKKyAgICAgIHBhcmVudF9maWVsZHMtPnBvcF9iYWNrKCk7CisgICAgfQorICB9CisKKyAgLy8gUmVwb3J0IGFueSByZW1haW5pbmcgYWRkaXRpb25zIG9yIGRlbGV0aW9ucy4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDI7ICsraSkgeworICAgIGlmIChtYXRjaF9saXN0MltpXSAhPSAtMSkgY29udGludWU7CisgICAgaWYgKCF0cmVhdGVkX2FzX3N1YnNldCkgeworICAgICAgZmllbGREaWZmZXJlbnQgPSB0cnVlOworICAgIH0KKworICAgIGlmIChyZXBvcnRlcl8gPT0gTlVMTCkgY29udGludWU7CisgICAgc3BlY2lmaWNfZmllbGQuaW5kZXggPSBpOworICAgIHNwZWNpZmljX2ZpZWxkLm5ld19pbmRleCA9IGk7CisgICAgcGFyZW50X2ZpZWxkcy0+cHVzaF9iYWNrKHNwZWNpZmljX2ZpZWxkKTsKKyAgICByZXBvcnRlcl8tPlJlcG9ydEFkZGVkKG1lc3NhZ2UxLCBtZXNzYWdlMiwgKnBhcmVudF9maWVsZHMpOworICAgIHBhcmVudF9maWVsZHMtPnBvcF9iYWNrKCk7CisgIH0KKworICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50MTsgKytpKSB7CisgICAgaWYgKG1hdGNoX2xpc3QxW2ldICE9IC0xKSBjb250aW51ZTsKKyAgICBzcGVjaWZpY19maWVsZC5pbmRleCA9IGk7CisgICAgcGFyZW50X2ZpZWxkcy0+cHVzaF9iYWNrKHNwZWNpZmljX2ZpZWxkKTsKKyAgICByZXBvcnRlcl8tPlJlcG9ydERlbGV0ZWQobWVzc2FnZTEsIG1lc3NhZ2UyLCAqcGFyZW50X2ZpZWxkcyk7CisgICAgcGFyZW50X2ZpZWxkcy0+cG9wX2JhY2soKTsKKyAgICBmaWVsZERpZmZlcmVudCA9IHRydWU7CisgIH0KKyAgcmV0dXJuICFmaWVsZERpZmZlcmVudDsKK30KKworYm9vbCBNZXNzYWdlRGlmZmVyZW5jZXI6OkNvbXBhcmVGaWVsZFZhbHVlKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGluZGV4MSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXgyKSB7CisgIHJldHVybiBDb21wYXJlRmllbGRWYWx1ZVVzaW5nUGFyZW50RmllbGRzKG1lc3NhZ2UxLCBtZXNzYWdlMiwgZmllbGQsIGluZGV4MSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXgyLCBOVUxMKTsKK30KKworYm9vbCBNZXNzYWdlRGlmZmVyZW5jZXI6OkNvbXBhcmVGaWVsZFZhbHVlVXNpbmdQYXJlbnRGaWVsZHMoCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZTEsIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UyLAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGludCBpbmRleDEsIGludCBpbmRleDIsCisgICAgdmVjdG9yPFNwZWNpZmljRmllbGQ+KiBwYXJlbnRfZmllbGRzKSB7CisgIEZpZWxkQ29udGV4dCBmaWVsZF9jb250ZXh0KHBhcmVudF9maWVsZHMpOworICBGaWVsZENvbXBhcmF0b3I6OkNvbXBhcmlzb25SZXN1bHQgcmVzdWx0ID0gR2V0RmllbGRDb21wYXJpc29uUmVzdWx0KAorICAgICAgbWVzc2FnZTEsIG1lc3NhZ2UyLCBmaWVsZCwgaW5kZXgxLCBpbmRleDIsICZmaWVsZF9jb250ZXh0KTsKKworICBpZiAoZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UgJiYKKyAgICAgIHJlc3VsdCA9PSBGaWVsZENvbXBhcmF0b3I6OlJFQ1VSU0UpIHsKKyAgICAvLyBHZXQgdGhlIG5lc3RlZCBtZXNzYWdlcyBhbmQgY29tcGFyZSB0aGVtIHVzaW5nIG9uZSBvZiB0aGUgQ29tcGFyZQorICAgIC8vIG1ldGhvZHMuCisgICAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbjEgPSBtZXNzYWdlMS5HZXRSZWZsZWN0aW9uKCk7CisgICAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbjIgPSBtZXNzYWdlMi5HZXRSZWZsZWN0aW9uKCk7CisgICAgY29uc3QgTWVzc2FnZSYgbTEgPSBmaWVsZC0+aXNfcmVwZWF0ZWQoKSA/CisgICAgICAgIHJlZmxlY3Rpb24xLT5HZXRSZXBlYXRlZE1lc3NhZ2UobWVzc2FnZTEsIGZpZWxkLCBpbmRleDEpIDoKKyAgICAgICAgcmVmbGVjdGlvbjEtPkdldE1lc3NhZ2UobWVzc2FnZTEsIGZpZWxkKTsKKyAgICBjb25zdCBNZXNzYWdlJiBtMiA9IGZpZWxkLT5pc19yZXBlYXRlZCgpID8KKyAgICAgICAgcmVmbGVjdGlvbjItPkdldFJlcGVhdGVkTWVzc2FnZShtZXNzYWdlMiwgZmllbGQsIGluZGV4MikgOgorICAgICAgICByZWZsZWN0aW9uMi0+R2V0TWVzc2FnZShtZXNzYWdlMiwgZmllbGQpOworCisgICAgLy8gcGFyZW50X2ZpZWxkcyBpcyB1c2VkIGluIGNhbGxzIHRvIFJlcG9ydGVyIG1ldGhvZHMuCisgICAgaWYgKHBhcmVudF9maWVsZHMgIT0gTlVMTCkgeworICAgICAgLy8gQXBwZW5kIGN1cnJlbnRseSBjb21wYXJlZCBmaWVsZCB0byB0aGUgZW5kIG9mIHBhcmVudF9maWVsZHMuCisgICAgICBTcGVjaWZpY0ZpZWxkIHNwZWNpZmljX2ZpZWxkOworICAgICAgc3BlY2lmaWNfZmllbGQuZmllbGQgPSBmaWVsZDsKKyAgICAgIHNwZWNpZmljX2ZpZWxkLmluZGV4ID0gaW5kZXgxOworICAgICAgc3BlY2lmaWNfZmllbGQubmV3X2luZGV4ID0gaW5kZXgyOworICAgICAgcGFyZW50X2ZpZWxkcy0+cHVzaF9iYWNrKHNwZWNpZmljX2ZpZWxkKTsKKyAgICAgIGNvbnN0IGJvb2wgY29tcGFyZV9yZXN1bHQgPSBDb21wYXJlKG0xLCBtMiwgcGFyZW50X2ZpZWxkcyk7CisgICAgICBwYXJlbnRfZmllbGRzLT5wb3BfYmFjaygpOworICAgICAgcmV0dXJuIGNvbXBhcmVfcmVzdWx0OworICAgIH0gZWxzZSB7CisgICAgICAvLyBSZWNyZWF0ZXMgcGFyZW50X2ZpZWxkcyBhcyBpZiBtMSBhbmQgbTIgaGFkIG5vIHBhcmVudHMuCisgICAgICByZXR1cm4gQ29tcGFyZShtMSwgbTIpOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gKHJlc3VsdCA9PSBGaWVsZENvbXBhcmF0b3I6OlNBTUUpOworICB9Cit9CisKK2Jvb2wgTWVzc2FnZURpZmZlcmVuY2VyOjpDaGVja1BhdGhDaGFuZ2VkKAorICAgIGNvbnN0IHZlY3RvcjxTcGVjaWZpY0ZpZWxkPiYgZmllbGRfcGF0aCkgeworICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkX3BhdGguc2l6ZSgpOyArK2kpIHsKKyAgICBpZiAoZmllbGRfcGF0aFtpXS5pbmRleCAhPSBmaWVsZF9wYXRoW2ldLm5ld19pbmRleCkgcmV0dXJuIHRydWU7CisgIH0KKyAgcmV0dXJuIGZhbHNlOworfQorCitib29sIE1lc3NhZ2VEaWZmZXJlbmNlcjo6SXNUcmVhdGVkQXNTZXQoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICBpZiAoIWZpZWxkLT5pc19yZXBlYXRlZCgpKSByZXR1cm4gZmFsc2U7CisgIGlmIChmaWVsZC0+aXNfbWFwKCkpIHJldHVybiB0cnVlOworICBpZiAocmVwZWF0ZWRfZmllbGRfY29tcGFyaXNvbl8gPT0gQVNfU0VUKQorICAgIHJldHVybiBsaXN0X2ZpZWxkc18uZmluZChmaWVsZCkgPT0gbGlzdF9maWVsZHNfLmVuZCgpOworICByZXR1cm4gKHNldF9maWVsZHNfLmZpbmQoZmllbGQpICE9IHNldF9maWVsZHNfLmVuZCgpKTsKK30KKworYm9vbCBNZXNzYWdlRGlmZmVyZW5jZXI6OklzVHJlYXRlZEFzU3Vic2V0KGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgcmV0dXJuIHNjb3BlXyA9PSBQQVJUSUFMICYmCisgICAgICAoSXNUcmVhdGVkQXNTZXQoZmllbGQpIHx8IEdldE1hcEtleUNvbXBhcmF0b3IoZmllbGQpICE9IE5VTEwpOworfQorCitib29sIE1lc3NhZ2VEaWZmZXJlbmNlcjo6SXNJZ25vcmVkKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UxLAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UyLAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgY29uc3QgdmVjdG9yPFNwZWNpZmljRmllbGQ+JiBwYXJlbnRfZmllbGRzKSB7CisgIGlmIChpZ25vcmVkX2ZpZWxkc18uZmluZChmaWVsZCkgIT0gaWdub3JlZF9maWVsZHNfLmVuZCgpKSB7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBpZ25vcmVfY3JpdGVyaWFfLnNpemUoKTsgKytpKSB7CisgICAgaWYgKGlnbm9yZV9jcml0ZXJpYV9baV0tPklzSWdub3JlZChtZXNzYWdlMSwgbWVzc2FnZTIsIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50X2ZpZWxkcykpIHsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgfQorICByZXR1cm4gZmFsc2U7Cit9CisKK2Jvb2wgTWVzc2FnZURpZmZlcmVuY2VyOjpJc1Vua25vd25GaWVsZElnbm9yZWQoCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZTEsIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UyLAorICAgIGNvbnN0IFNwZWNpZmljRmllbGQmIGZpZWxkLCBjb25zdCB2ZWN0b3I8U3BlY2lmaWNGaWVsZD4mIHBhcmVudF9maWVsZHMpIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBpZ25vcmVfY3JpdGVyaWFfLnNpemUoKTsgKytpKSB7CisgICAgaWYgKGlnbm9yZV9jcml0ZXJpYV9baV0tPklzVW5rbm93bkZpZWxkSWdub3JlZChtZXNzYWdlMSwgbWVzc2FnZTIsIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50X2ZpZWxkcykpIHsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgfQorICByZXR1cm4gZmFsc2U7Cit9CisKK2NvbnN0IE1lc3NhZ2VEaWZmZXJlbmNlcjo6TWFwS2V5Q29tcGFyYXRvciogTWVzc2FnZURpZmZlcmVuY2VyCisgICAgOjpHZXRNYXBLZXlDb21wYXJhdG9yKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgaWYgKCFmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgcmV0dXJuIE5VTEw7CisgIGlmIChtYXBfZmllbGRfa2V5X2NvbXBhcmF0b3JfLmZpbmQoZmllbGQpICE9CisgICAgICBtYXBfZmllbGRfa2V5X2NvbXBhcmF0b3JfLmVuZCgpKSB7CisgICAgcmV0dXJuIG1hcF9maWVsZF9rZXlfY29tcGFyYXRvcl9bZmllbGRdOworICB9CisgIHJldHVybiBOVUxMOworfQorCituYW1lc3BhY2UgeworCit0eXBlZGVmIHBhaXI8aW50LCBjb25zdCBVbmtub3duRmllbGQqPiBJbmRleFVua25vd25GaWVsZFBhaXI7CisKK3N0cnVjdCBVbmtub3duRmllbGRPcmRlcmluZyB7CisgIGlubGluZSBib29sIG9wZXJhdG9yKCkoY29uc3QgSW5kZXhVbmtub3duRmllbGRQYWlyJiBhLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEluZGV4VW5rbm93bkZpZWxkUGFpciYgYikgY29uc3QgeworICAgIGlmIChhLnNlY29uZC0+bnVtYmVyKCkgPCBiLnNlY29uZC0+bnVtYmVyKCkpIHJldHVybiB0cnVlOworICAgIGlmIChhLnNlY29uZC0+bnVtYmVyKCkgPiBiLnNlY29uZC0+bnVtYmVyKCkpIHJldHVybiBmYWxzZTsKKyAgICByZXR1cm4gYS5zZWNvbmQtPnR5cGUoKSA8IGIuc2Vjb25kLT50eXBlKCk7CisgIH0KK307CisKK30gIC8vIG5hbWVzcGFjZQorCitib29sIE1lc3NhZ2VEaWZmZXJlbmNlcjo6VW5wYWNrQW55KGNvbnN0IE1lc3NhZ2UmIGFueSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxNZXNzYWdlPiogZGF0YSkgeworICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uID0gYW55LkdldFJlZmxlY3Rpb24oKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiB0eXBlX3VybF9maWVsZDsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiB2YWx1ZV9maWVsZDsKKyAgaWYgKCFpbnRlcm5hbDo6R2V0QW55RmllbGREZXNjcmlwdG9ycyhhbnksICZ0eXBlX3VybF9maWVsZCwgJnZhbHVlX2ZpZWxkKSkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICBjb25zdCBzdHJpbmcmIHR5cGVfdXJsID0gcmVmbGVjdGlvbi0+R2V0U3RyaW5nKGFueSwgdHlwZV91cmxfZmllbGQpOworICBzdHJpbmcgZnVsbF90eXBlX25hbWU7CisgIGlmICghaW50ZXJuYWw6OlBhcnNlQW55VHlwZVVybCh0eXBlX3VybCwgJmZ1bGxfdHlwZV9uYW1lKSkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIGRlc2MgPQorICAgICAgYW55LkdldERlc2NyaXB0b3IoKS0+ZmlsZSgpLT5wb29sKCktPkZpbmRNZXNzYWdlVHlwZUJ5TmFtZSgKKyAgICAgICAgICBmdWxsX3R5cGVfbmFtZSk7CisgIGlmIChkZXNjID09IE5VTEwpIHsKKyAgICBHT09HTEVfTE9HKEVSUk9SKSA8PCAiUHJvdG8gdHlwZSAnIiA8PCBmdWxsX3R5cGVfbmFtZSA8PCAiJyBub3QgZm91bmQiOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIGlmIChkeW5hbWljX21lc3NhZ2VfZmFjdG9yeV8gPT0gTlVMTCkgeworICAgIGR5bmFtaWNfbWVzc2FnZV9mYWN0b3J5Xy5yZXNldChuZXcgRHluYW1pY01lc3NhZ2VGYWN0b3J5KCkpOworICB9CisgIGRhdGEtPnJlc2V0KGR5bmFtaWNfbWVzc2FnZV9mYWN0b3J5Xy0+R2V0UHJvdG90eXBlKGRlc2MpLT5OZXcoKSk7CisgIHN0cmluZyBzZXJpYWxpemVkX3ZhbHVlID0gcmVmbGVjdGlvbi0+R2V0U3RyaW5nKGFueSwgdmFsdWVfZmllbGQpOworICBpZiAoISgqZGF0YSktPlBhcnNlRnJvbVN0cmluZyhzZXJpYWxpemVkX3ZhbHVlKSkgeworICAgIEdPT0dMRV9MT0coRVJST1IpIDw8ICJGYWlsZWQgdG8gcGFyc2UgdmFsdWUgZm9yICIgPDwgZnVsbF90eXBlX25hbWU7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIHJldHVybiB0cnVlOworfQorCitib29sIE1lc3NhZ2VEaWZmZXJlbmNlcjo6Q29tcGFyZVVua25vd25GaWVsZHMoCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZTEsIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UyLAorICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlVua25vd25GaWVsZFNldCYgdW5rbm93bl9maWVsZF9zZXQxLAorICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlVua25vd25GaWVsZFNldCYgdW5rbm93bl9maWVsZF9zZXQyLAorICAgIHZlY3RvcjxTcGVjaWZpY0ZpZWxkPiogcGFyZW50X2ZpZWxkKSB7CisgIC8vIElnbm9yZSB1bmtub3duIGZpZWxkcyBpbiBFUVVJVkFMRU5UIG1vZGUuCisgIGlmIChtZXNzYWdlX2ZpZWxkX2NvbXBhcmlzb25fID09IEVRVUlWQUxFTlQpIHJldHVybiB0cnVlOworCisgIGlmICh1bmtub3duX2ZpZWxkX3NldDEuZW1wdHkoKSAmJiB1bmtub3duX2ZpZWxkX3NldDIuZW1wdHkoKSkgeworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgYm9vbCBpc19kaWZmZXJlbnQgPSBmYWxzZTsKKworICAvLyBXZSBmaXJzdCBzb3J0IHRoZSB1bmtub3duIGZpZWxkcyBieSBmaWVsZCBudW1iZXIgYW5kIHR5cGUgKGluIG90aGVyIHdvcmRzLAorICAvLyBpbiB0YWcgb3JkZXIpLCBtYWtpbmcgc3VyZSB0byBwcmVzZXJ2ZSBvcmRlcmluZyBvZiB2YWx1ZXMgd2l0aCB0aGUgc2FtZQorICAvLyB0YWcuICBUaGlzIGFsbG93cyB1cyB0byByZXBvcnQgb25seSBtZWFuaW5nZnVsIGRpZmZlcmVuY2VzIGJldHdlZW4gdGhlCisgIC8vIHR3byBzZXRzIC0tIHRoYXQgaXMsIGRpZmZlcmluZyB2YWx1ZXMgZm9yIHRoZSBzYW1lIHRhZy4gIFdlIHVzZQorICAvLyBJbmRleFVua25vd25GaWVsZFBhaXJzIHRvIGtlZXAgdHJhY2sgb2YgdGhlIGZpZWxkJ3Mgb3JpZ2luYWwgaW5kZXggZm9yCisgIC8vIHJlcG9ydGluZyBwdXJwb3Nlcy4KKyAgdmVjdG9yPEluZGV4VW5rbm93bkZpZWxkUGFpcj4gZmllbGRzMTsgIC8vIHVua25vd25fZmllbGRfc2V0MSwgc29ydGVkCisgIHZlY3RvcjxJbmRleFVua25vd25GaWVsZFBhaXI+IGZpZWxkczI7ICAvLyB1bmtub3duX2ZpZWxkX3NldDIsIHNvcnRlZAorICBmaWVsZHMxLnJlc2VydmUodW5rbm93bl9maWVsZF9zZXQxLmZpZWxkX2NvdW50KCkpOworICBmaWVsZHMyLnJlc2VydmUodW5rbm93bl9maWVsZF9zZXQyLmZpZWxkX2NvdW50KCkpOworCisgIGZvciAoaW50IGkgPSAwOyBpIDwgdW5rbm93bl9maWVsZF9zZXQxLmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGZpZWxkczEucHVzaF9iYWNrKHN0ZDo6bWFrZV9wYWlyKGksICZ1bmtub3duX2ZpZWxkX3NldDEuZmllbGQoaSkpKTsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IHVua25vd25fZmllbGRfc2V0Mi5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBmaWVsZHMyLnB1c2hfYmFjayhzdGQ6Om1ha2VfcGFpcihpLCAmdW5rbm93bl9maWVsZF9zZXQyLmZpZWxkKGkpKSk7CisgIH0KKworICBVbmtub3duRmllbGRPcmRlcmluZyBpc19iZWZvcmU7CisgIHN0ZDo6c3RhYmxlX3NvcnQoZmllbGRzMS5iZWdpbigpLCBmaWVsZHMxLmVuZCgpLCBpc19iZWZvcmUpOworICBzdGQ6OnN0YWJsZV9zb3J0KGZpZWxkczIuYmVnaW4oKSwgZmllbGRzMi5lbmQoKSwgaXNfYmVmb3JlKTsKKworICAvLyBJbiBvcmRlciB0byBmaWxsIGluIFNwZWNpZmljRmllbGQ6OmluZGV4LCB3ZSBoYXZlIHRvIGtlZXAgdHJhY2sgb2YgaG93CisgIC8vIG1hbnkgdmFsdWVzIHdlJ3ZlIHNlZW4gd2l0aCB0aGUgc2FtZSBmaWVsZCBudW1iZXIgYW5kIHR5cGUuCisgIC8vIGN1cnJlbnRfcmVwZWF0ZWQgcG9pbnRzIGF0IHRoZSBmaXJzdCBmaWVsZCBpbiB0aGlzIHJhbmdlLCBhbmQKKyAgLy8gY3VycmVudF9yZXBlYXRlZF9zdGFydHsxLDJ9IGFyZSB0aGUgaW5kZXhlcyBvZiB0aGUgZmlyc3QgZmllbGQgaW4gdGhlCisgIC8vIHJhbmdlIHdpdGhpbiBmaWVsZHMxIGFuZCBmaWVsZHMyLgorICBjb25zdCBVbmtub3duRmllbGQqIGN1cnJlbnRfcmVwZWF0ZWQgPSBOVUxMOworICBpbnQgY3VycmVudF9yZXBlYXRlZF9zdGFydDEgPSAwOworICBpbnQgY3VycmVudF9yZXBlYXRlZF9zdGFydDIgPSAwOworCisgIC8vIE5vdyB0aGF0IHdlIGhhdmUgdHdvIHNvcnRlZCBsaXN0cywgd2UgY2FuIGRldGVjdCBmaWVsZHMgd2hpY2ggYXBwZWFyIG9ubHkKKyAgLy8gaW4gb25lIGxpc3Qgb3IgdGhlIG90aGVyIGJ5IHRyYXZlcnNpbmcgdGhlbSBzaW11bHRhbmVvdXNseS4KKyAgaW50IGluZGV4MSA9IDA7CisgIGludCBpbmRleDIgPSAwOworICB3aGlsZSAoaW5kZXgxIDwgZmllbGRzMS5zaXplKCkgfHwgaW5kZXgyIDwgZmllbGRzMi5zaXplKCkpIHsKKyAgICBlbnVtIHsgQURESVRJT04sIERFTEVUSU9OLCBNT0RJRklDQVRJT04sIENPTVBBUkVfR1JPVVBTLAorICAgICAgTk9fQ0hBTkdFIH0gY2hhbmdlX3R5cGU7CisKKyAgICAvLyBmb2N1c19maWVsZCBpcyB0aGUgZmllbGQgd2UncmUgY3VycmVudGx5IHJlcG9ydGluZyBvbi4gIChJbiB0aGUgY2FzZQorICAgIC8vIG9mIGEgbW9kaWZpY2F0aW9uLCBpdCdzIHRoZSBmaWVsZCBvbiB0aGUgbGVmdCBzaWRlLikKKyAgICBjb25zdCBVbmtub3duRmllbGQqIGZvY3VzX2ZpZWxkOworICAgIGJvb2wgbWF0Y2ggPSBmYWxzZTsKKworICAgIGlmIChpbmRleDIgPT0gZmllbGRzMi5zaXplKCkgfHwKKyAgICAgICAgKGluZGV4MSA8IGZpZWxkczEuc2l6ZSgpICYmCisgICAgICAgICAgaXNfYmVmb3JlKGZpZWxkczFbaW5kZXgxXSwgZmllbGRzMltpbmRleDJdKSkpIHsKKyAgICAgIC8vIGZpZWxkczFbaW5kZXgxXSBpcyBub3QgcHJlc2VudCBpbiBmaWVsZHMyLgorICAgICAgY2hhbmdlX3R5cGUgPSBERUxFVElPTjsKKyAgICAgIGZvY3VzX2ZpZWxkID0gZmllbGRzMVtpbmRleDFdLnNlY29uZDsKKyAgICB9IGVsc2UgaWYgKGluZGV4MSA9PSBmaWVsZHMxLnNpemUoKSB8fAorICAgICAgICAgICAgICAgaXNfYmVmb3JlKGZpZWxkczJbaW5kZXgyXSwgZmllbGRzMVtpbmRleDFdKSkgeworICAgICAgLy8gZmllbGRzMltpbmRleDJdIGlzIG5vdCBwcmVzZW50IGluIGZpZWxkczEuCisgICAgICBpZiAoc2NvcGVfID09IFBBUlRJQUwpIHsKKyAgICAgICAgLy8gSWdub3JlLgorICAgICAgICArK2luZGV4MjsKKyAgICAgICAgY29udGludWU7CisgICAgICB9CisgICAgICBjaGFuZ2VfdHlwZSA9IEFERElUSU9OOworICAgICAgZm9jdXNfZmllbGQgPSBmaWVsZHMyW2luZGV4Ml0uc2Vjb25kOworICAgIH0gZWxzZSB7CisgICAgICAvLyBGaWVsZCB0eXBlIGFuZCBudW1iZXIgYXJlIHRoZSBzYW1lLiAgU2VlIGlmIHRoZSB2YWx1ZXMgZGlmZmVyLgorICAgICAgY2hhbmdlX3R5cGUgPSBNT0RJRklDQVRJT047CisgICAgICBmb2N1c19maWVsZCA9IGZpZWxkczFbaW5kZXgxXS5zZWNvbmQ7CisKKyAgICAgIHN3aXRjaCAoZm9jdXNfZmllbGQtPnR5cGUoKSkgeworICAgICAgICBjYXNlIFVua25vd25GaWVsZDo6VFlQRV9WQVJJTlQ6CisgICAgICAgICAgbWF0Y2ggPSBmaWVsZHMxW2luZGV4MV0uc2Vjb25kLT52YXJpbnQoKSA9PQorICAgICAgICAgICAgICAgICAgZmllbGRzMltpbmRleDJdLnNlY29uZC0+dmFyaW50KCk7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgVW5rbm93bkZpZWxkOjpUWVBFX0ZJWEVEMzI6CisgICAgICAgICAgbWF0Y2ggPSBmaWVsZHMxW2luZGV4MV0uc2Vjb25kLT5maXhlZDMyKCkgPT0KKyAgICAgICAgICAgICAgICAgIGZpZWxkczJbaW5kZXgyXS5zZWNvbmQtPmZpeGVkMzIoKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBVbmtub3duRmllbGQ6OlRZUEVfRklYRUQ2NDoKKyAgICAgICAgICBtYXRjaCA9IGZpZWxkczFbaW5kZXgxXS5zZWNvbmQtPmZpeGVkNjQoKSA9PQorICAgICAgICAgICAgICAgICAgZmllbGRzMltpbmRleDJdLnNlY29uZC0+Zml4ZWQ2NCgpOworICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFVua25vd25GaWVsZDo6VFlQRV9MRU5HVEhfREVMSU1JVEVEOgorICAgICAgICAgIG1hdGNoID0gZmllbGRzMVtpbmRleDFdLnNlY29uZC0+bGVuZ3RoX2RlbGltaXRlZCgpID09CisgICAgICAgICAgICAgICAgICBmaWVsZHMyW2luZGV4Ml0uc2Vjb25kLT5sZW5ndGhfZGVsaW1pdGVkKCk7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgVW5rbm93bkZpZWxkOjpUWVBFX0dST1VQOgorICAgICAgICAgIC8vIFdlIG11c3QgZGVhbCB3aXRoIHRoaXMgbGF0ZXIsIGFmdGVyIGJ1aWxkaW5nIHRoZSBTcGVjaWZpY0ZpZWxkLgorICAgICAgICAgIGNoYW5nZV90eXBlID0gQ09NUEFSRV9HUk9VUFM7CisgICAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgICBpZiAobWF0Y2ggJiYgY2hhbmdlX3R5cGUgIT0gQ09NUEFSRV9HUk9VUFMpIHsKKyAgICAgICAgY2hhbmdlX3R5cGUgPSBOT19DSEFOR0U7CisgICAgICB9CisgICAgfQorCisgICAgaWYgKGN1cnJlbnRfcmVwZWF0ZWQgPT0gTlVMTCB8fAorICAgICAgICBmb2N1c19maWVsZC0+bnVtYmVyKCkgIT0gY3VycmVudF9yZXBlYXRlZC0+bnVtYmVyKCkgfHwKKyAgICAgICAgZm9jdXNfZmllbGQtPnR5cGUoKSAhPSBjdXJyZW50X3JlcGVhdGVkLT50eXBlKCkpIHsKKyAgICAgIC8vIFdlJ3ZlIHN0YXJ0ZWQgYSBuZXcgcmVwZWF0ZWQgZmllbGQuCisgICAgICBjdXJyZW50X3JlcGVhdGVkID0gZm9jdXNfZmllbGQ7CisgICAgICBjdXJyZW50X3JlcGVhdGVkX3N0YXJ0MSA9IGluZGV4MTsKKyAgICAgIGN1cnJlbnRfcmVwZWF0ZWRfc3RhcnQyID0gaW5kZXgyOworICAgIH0KKworICAgIGlmIChjaGFuZ2VfdHlwZSA9PSBOT19DSEFOR0UgJiYgcmVwb3J0ZXJfID09IE5VTEwpIHsKKyAgICAgIC8vIEZpZWxkcyB3ZXJlIGFscmVhZHkgY29tcGFyZWQgYW5kIG1hdGNoZWQgYW5kIHdlIGhhdmUgbm8gcmVwb3J0ZXIuCisgICAgICArK2luZGV4MTsKKyAgICAgICsraW5kZXgyOworICAgICAgY29udGludWU7CisgICAgfQorCisgICAgLy8gQnVpbGQgdGhlIFNwZWNpZmljRmllbGQuICBUaGlzIGlzIHNsaWdodGx5IGNvbXBsaWNhdGVkLgorICAgIFNwZWNpZmljRmllbGQgc3BlY2lmaWNfZmllbGQ7CisgICAgc3BlY2lmaWNfZmllbGQudW5rbm93bl9maWVsZF9udW1iZXIgPSBmb2N1c19maWVsZC0+bnVtYmVyKCk7CisgICAgc3BlY2lmaWNfZmllbGQudW5rbm93bl9maWVsZF90eXBlID0gZm9jdXNfZmllbGQtPnR5cGUoKTsKKworICAgIHNwZWNpZmljX2ZpZWxkLnVua25vd25fZmllbGRfc2V0MSA9ICZ1bmtub3duX2ZpZWxkX3NldDE7CisgICAgc3BlY2lmaWNfZmllbGQudW5rbm93bl9maWVsZF9zZXQyID0gJnVua25vd25fZmllbGRfc2V0MjsKKworICAgIGlmIChjaGFuZ2VfdHlwZSAhPSBBRERJVElPTikgeworICAgICAgc3BlY2lmaWNfZmllbGQudW5rbm93bl9maWVsZF9pbmRleDEgPSBmaWVsZHMxW2luZGV4MV0uZmlyc3Q7CisgICAgfQorICAgIGlmIChjaGFuZ2VfdHlwZSAhPSBERUxFVElPTikgeworICAgICAgc3BlY2lmaWNfZmllbGQudW5rbm93bl9maWVsZF9pbmRleDIgPSBmaWVsZHMyW2luZGV4Ml0uZmlyc3Q7CisgICAgfQorCisgICAgLy8gQ2FsY3VsYXRlIHRoZSBmaWVsZCBpbmRleC4KKyAgICBpZiAoY2hhbmdlX3R5cGUgPT0gQURESVRJT04pIHsKKyAgICAgIHNwZWNpZmljX2ZpZWxkLmluZGV4ID0gaW5kZXgyIC0gY3VycmVudF9yZXBlYXRlZF9zdGFydDI7CisgICAgICBzcGVjaWZpY19maWVsZC5uZXdfaW5kZXggPSBpbmRleDIgLSBjdXJyZW50X3JlcGVhdGVkX3N0YXJ0MjsKKyAgICB9IGVsc2UgeworICAgICAgc3BlY2lmaWNfZmllbGQuaW5kZXggPSBpbmRleDEgLSBjdXJyZW50X3JlcGVhdGVkX3N0YXJ0MTsKKyAgICAgIHNwZWNpZmljX2ZpZWxkLm5ld19pbmRleCA9IGluZGV4MiAtIGN1cnJlbnRfcmVwZWF0ZWRfc3RhcnQyOworICAgIH0KKworICAgIGlmIChJc1Vua25vd25GaWVsZElnbm9yZWQobWVzc2FnZTEsIG1lc3NhZ2UyLCBzcGVjaWZpY19maWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpwYXJlbnRfZmllbGQpKSB7CisgICAgICBpZiAocmVwb3J0ZXJfICE9IE5VTEwpIHsKKyAgICAgICAgcGFyZW50X2ZpZWxkLT5wdXNoX2JhY2soc3BlY2lmaWNfZmllbGQpOworICAgICAgICByZXBvcnRlcl8tPlJlcG9ydFVua25vd25GaWVsZElnbm9yZWQobWVzc2FnZTEsIG1lc3NhZ2UyLCAqcGFyZW50X2ZpZWxkKTsKKyAgICAgICAgcGFyZW50X2ZpZWxkLT5wb3BfYmFjaygpOworICAgICAgfQorICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgaWYgKGNoYW5nZV90eXBlID09IEFERElUSU9OIHx8IGNoYW5nZV90eXBlID09IERFTEVUSU9OIHx8CisgICAgICAgIGNoYW5nZV90eXBlID09IE1PRElGSUNBVElPTikgeworICAgICAgaWYgKHJlcG9ydGVyXyA9PSBOVUxMKSB7CisgICAgICAgIC8vIFdlIGZvdW5kIGEgZGlmZmVyZW5jZSBhbmQgd2UgaGF2ZSBubyByZXByb3Rlci4KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgICAgaXNfZGlmZmVyZW50ID0gdHJ1ZTsKKyAgICB9CisKKyAgICBwYXJlbnRfZmllbGQtPnB1c2hfYmFjayhzcGVjaWZpY19maWVsZCk7CisKKyAgICBzd2l0Y2ggKGNoYW5nZV90eXBlKSB7CisgICAgICBjYXNlIEFERElUSU9OOgorICAgICAgICByZXBvcnRlcl8tPlJlcG9ydEFkZGVkKG1lc3NhZ2UxLCBtZXNzYWdlMiwgKnBhcmVudF9maWVsZCk7CisgICAgICAgICsraW5kZXgyOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgREVMRVRJT046CisgICAgICAgIHJlcG9ydGVyXy0+UmVwb3J0RGVsZXRlZChtZXNzYWdlMSwgbWVzc2FnZTIsICpwYXJlbnRfZmllbGQpOworICAgICAgICArK2luZGV4MTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIE1PRElGSUNBVElPTjoKKyAgICAgICAgcmVwb3J0ZXJfLT5SZXBvcnRNb2RpZmllZChtZXNzYWdlMSwgbWVzc2FnZTIsICpwYXJlbnRfZmllbGQpOworICAgICAgICArK2luZGV4MTsKKyAgICAgICAgKytpbmRleDI7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBDT01QQVJFX0dST1VQUzoKKyAgICAgICAgaWYgKCFDb21wYXJlVW5rbm93bkZpZWxkcyhtZXNzYWdlMSwgbWVzc2FnZTIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGRzMVtpbmRleDFdLnNlY29uZC0+Z3JvdXAoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZHMyW2luZGV4Ml0uc2Vjb25kLT5ncm91cCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudF9maWVsZCkpIHsKKyAgICAgICAgICBpZiAocmVwb3J0ZXJfID09IE5VTEwpIHJldHVybiBmYWxzZTsKKyAgICAgICAgICBpc19kaWZmZXJlbnQgPSB0cnVlOworICAgICAgICAgIHJlcG9ydGVyXy0+UmVwb3J0TW9kaWZpZWQobWVzc2FnZTEsIG1lc3NhZ2UyLCAqcGFyZW50X2ZpZWxkKTsKKyAgICAgICAgfQorICAgICAgICArK2luZGV4MTsKKyAgICAgICAgKytpbmRleDI7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBOT19DSEFOR0U6CisgICAgICAgICsraW5kZXgxOworICAgICAgICArK2luZGV4MjsKKyAgICAgICAgaWYgKHJlcG9ydF9tYXRjaGVzXykgeworICAgICAgICAgIHJlcG9ydGVyXy0+UmVwb3J0TWF0Y2hlZChtZXNzYWdlMSwgbWVzc2FnZTIsICpwYXJlbnRfZmllbGQpOworICAgICAgICB9CisgICAgfQorCisgICAgcGFyZW50X2ZpZWxkLT5wb3BfYmFjaygpOworICB9CisKKyAgcmV0dXJuICFpc19kaWZmZXJlbnQ7Cit9CisKK25hbWVzcGFjZSB7CisKKy8vIEZpbmQgbWF4aW11bSBiaXBhcnRpdGUgbWF0Y2hpbmcgdXNpbmcgdGhlIGFyZ3VtZW50aW5nIHBhdGggYWxnb3JpdGhtLgorY2xhc3MgTWF4aW11bU1hdGNoZXIgeworIHB1YmxpYzoKKyAgdHlwZWRlZiBSZXN1bHRDYWxsYmFjazI8Ym9vbCwgaW50LCBpbnQ+IE5vZGVNYXRjaENhbGxiYWNrOworICAvLyBNYXhpbXVtTWF0Y2hlciB0YWtlcyBvd25lcnNoaXAgb2YgdGhlIHBhc3NlZCBpbiBjYWxsYmFjayBhbmQgdXNlcyBpdCB0bworICAvLyBkZXRlcm1pbmUgd2hldGhlciBhIG5vZGUgb24gdGhlIGxlZnQgc2lkZSBvZiB0aGUgYmlwYXJ0aWFsIGdyYXBoIG1hdGNoZXMKKyAgLy8gYSBub2RlIG9uIHRoZSByaWdodCBzaWRlLiBjb3VudDEgaXMgdGhlIG51bWJlciBvZiBub2RlcyBvbiB0aGUgbGVmdCBzaWRlCisgIC8vIG9mIHRoZSBncmFwaCBhbmQgY291bnQyIHRvIGlzIHRoZSBudW1iZXIgb2Ygbm9kZXMgb24gdGhlIHJpZ2h0IHNpZGUuCisgIC8vIEV2ZXJ5IG5vZGUgaXMgcmVmZXJyZWQgdG8gdXNpbmcgMC1iYXNlZCBpbmRpY2VzLgorICAvLyBJZiBhIG1heGltdW0gbWF0Y2ggaXMgZm91bmQsIHRoZSByZXN1bHQgd2lsbCBiZSBzdG9yZWQgaW4gbWF0Y2hfbGlzdDEgYW5kCisgIC8vIG1hdGNoX2xpc3QyLiBtYXRjaF9saXN0MVtpXSA9PSBqIG1lYW5zIHRoZSBpLXRoIG5vZGUgb24gdGhlIGxlZnQgc2lkZSBpcworICAvLyBtYXRjaGVkIHRvIHRoZSBqLXRoIG5vZGUgb24gdGhlIHJpZ2h0IHNpZGUgYW5kIG1hdGNoX2xpc3QyW3hdID09IHkgbWVhbnMKKyAgLy8gdGhlIHgtdGggbm9kZSBvbiB0aGUgcmlnaHQgc2lkZSBpcyBtYXRjaGVkIHRvIHktdGggbm9kZSBvbiB0aGUgbGVmdCBzaWRlLgorICAvLyBtYXRjaF9saXN0MVtpXSA9PSAtMSBtZWFucyB0aGUgbm9kZSBpcyBub3QgbWF0Y2hlZC4gU2FtZSB3aXRoIG1hdGNoX2xpc3QyLgorICBNYXhpbXVtTWF0Y2hlcihpbnQgY291bnQxLCBpbnQgY291bnQyLCBOb2RlTWF0Y2hDYWxsYmFjayogY2FsbGJhY2ssCisgICAgICAgICAgICAgICAgIHZlY3RvcjxpbnQ+KiBtYXRjaF9saXN0MSwgdmVjdG9yPGludD4qIG1hdGNoX2xpc3QyKTsKKyAgLy8gRmluZCBhIG1heGltdW0gbWF0Y2ggYW5kIHJldHVybiB0aGUgbnVtYmVyIG9mIG1hdGNoZWQgbm9kZSBwYWlycy4KKyAgLy8gSWYgZWFybHlfcmV0dXJuIGlzIHRydWUsIHRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuIDAgaW1tZWRpYXRlbHkgd2hlbiBpdAorICAvLyBmaW5kcyB0aGF0IG5vdCBhbGwgbm9kZXMgb24gdGhlIGxlZnQgc2lkZSBjYW4gYmUgbWF0Y2hlZC4KKyAgaW50IEZpbmRNYXhpbXVtTWF0Y2goYm9vbCBlYXJseV9yZXR1cm4pOworIHByaXZhdGU6CisgIC8vIERldGVybWluZXMgd2hldGhlciB0aGUgbm9kZSBvbiB0aGUgbGVmdCBzaWRlIG9mIHRoZSBiaXBhcnRpYWwgZ3JhcGgKKyAgLy8gbWF0Y2hlcyB0aGUgb25lIG9uIHRoZSByaWdodCBzaWRlLgorICBib29sIE1hdGNoKGludCBsZWZ0LCBpbnQgcmlnaHQpOworICAvLyBGaW5kIGFuIGFyZ3VtZW50aW5nIHBhdGggc3RhcnRpbmcgZnJvbSB0aGUgbm9kZSB2IG9uIHRoZSBsZWZ0IHNpZGUuIElmIGEKKyAgLy8gcGF0aCBjYW4gYmUgZm91bmQsIHVwZGF0ZSBtYXRjaF9saXN0Ml8gdG8gcmVmbGVjdCB0aGUgcGF0aCBhbmQgcmV0dXJuCisgIC8vIHRydWUuCisgIGJvb2wgRmluZEFyZ3VtZW50UGF0aERGUyhpbnQgdiwgdmVjdG9yPGJvb2w+KiB2aXNpdGVkKTsKKworICBpbnQgY291bnQxXzsKKyAgaW50IGNvdW50Ml87CisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8Tm9kZU1hdGNoQ2FsbGJhY2s+IG1hdGNoX2NhbGxiYWNrXzsKKyAgbWFwPHBhaXI8aW50LCBpbnQ+LCBib29sPiBjYWNoZWRfbWF0Y2hfcmVzdWx0c187CisgIHZlY3RvcjxpbnQ+KiBtYXRjaF9saXN0MV87CisgIHZlY3RvcjxpbnQ+KiBtYXRjaF9saXN0Ml87CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhNYXhpbXVtTWF0Y2hlcik7Cit9OworCitNYXhpbXVtTWF0Y2hlcjo6TWF4aW11bU1hdGNoZXIoaW50IGNvdW50MSwgaW50IGNvdW50MiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOb2RlTWF0Y2hDYWxsYmFjayogY2FsbGJhY2ssCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjdG9yPGludD4qIG1hdGNoX2xpc3QxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlY3RvcjxpbnQ+KiBtYXRjaF9saXN0MikKKyAgICA6IGNvdW50MV8oY291bnQxKSwgY291bnQyXyhjb3VudDIpLCBtYXRjaF9jYWxsYmFja18oY2FsbGJhY2spLAorICAgICAgbWF0Y2hfbGlzdDFfKG1hdGNoX2xpc3QxKSwgbWF0Y2hfbGlzdDJfKG1hdGNoX2xpc3QyKSB7CisgIG1hdGNoX2xpc3QxXy0+YXNzaWduKGNvdW50MSwgLTEpOworICBtYXRjaF9saXN0Ml8tPmFzc2lnbihjb3VudDIsIC0xKTsKK30KKworaW50IE1heGltdW1NYXRjaGVyOjpGaW5kTWF4aW11bU1hdGNoKGJvb2wgZWFybHlfcmV0dXJuKSB7CisgIGludCByZXN1bHQgPSAwOworICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50MV87ICsraSkgeworICAgIHZlY3Rvcjxib29sPiB2aXNpdGVkKGNvdW50MV8pOworICAgIGlmIChGaW5kQXJndW1lbnRQYXRoREZTKGksICZ2aXNpdGVkKSkgeworICAgICAgKytyZXN1bHQ7CisgICAgfSBlbHNlIGlmIChlYXJseV9yZXR1cm4pIHsKKyAgICAgIHJldHVybiAwOworICAgIH0KKyAgfQorICAvLyBCYWNrZmlsbCBtYXRjaF9saXN0MV8gYXMgd2Ugb25seSBmaWxsZWQgbWF0Y2hfbGlzdDJfIHdoZW4gZmluZGluZworICAvLyBhcmd1bWVudGluZyBwYXRoZXMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQyXzsgKytpKSB7CisgICAgaWYgKCgqbWF0Y2hfbGlzdDJfKVtpXSAhPSAtMSkgeworICAgICAgKCptYXRjaF9saXN0MV8pWygqbWF0Y2hfbGlzdDJfKVtpXV0gPSBpOworICAgIH0KKyAgfQorICByZXR1cm4gcmVzdWx0OworfQorCitib29sIE1heGltdW1NYXRjaGVyOjpNYXRjaChpbnQgbGVmdCwgaW50IHJpZ2h0KSB7CisgIHBhaXI8aW50LCBpbnQ+IHAobGVmdCwgcmlnaHQpOworICBtYXA8cGFpcjxpbnQsIGludD4sIGJvb2w+OjppdGVyYXRvciBpdCA9IGNhY2hlZF9tYXRjaF9yZXN1bHRzXy5maW5kKHApOworICBpZiAoaXQgIT0gY2FjaGVkX21hdGNoX3Jlc3VsdHNfLmVuZCgpKSB7CisgICAgcmV0dXJuIGl0LT5zZWNvbmQ7CisgIH0KKyAgY2FjaGVkX21hdGNoX3Jlc3VsdHNfW3BdID0gbWF0Y2hfY2FsbGJhY2tfLT5SdW4obGVmdCwgcmlnaHQpOworICByZXR1cm4gY2FjaGVkX21hdGNoX3Jlc3VsdHNfW3BdOworfQorCitib29sIE1heGltdW1NYXRjaGVyOjpGaW5kQXJndW1lbnRQYXRoREZTKGludCB2LCB2ZWN0b3I8Ym9vbD4qIHZpc2l0ZWQpIHsKKyAgKCp2aXNpdGVkKVt2XSA9IHRydWU7CisgIC8vIFdlIHRyeSB0byBtYXRjaCB0aG9zZSB1bi1tYXRjaGVkIG5vZGVzIG9uIHRoZSByaWdodCBzaWRlIGZpcnN0LiBUaGlzIGlzCisgIC8vIHRoZSBzdGVwIHRoYXQgdGhlIG5hdmllIGdyZWVkeSBtYXRjaGluZyBhbGdvcml0aG0gdXNlcy4gSW4gdGhlIGJlc3QgY2FzZXMKKyAgLy8gd2hlcmUgdGhlIGdyZWVkeSBhbGdvcml0aG0gY2FuIGZpbmQgYSBtYXhpbXVtIG1hdGNoaW5nLCB3ZSB3aWxsIGFsd2F5cworICAvLyBmaW5kIGEgbWF0Y2ggaW4gdGhpcyBzdGVwIGFuZCB0aGUgcGVyZm9ybWFuY2Ugd2lsbCBiZSBpZGVudGljYWwgdG8gdGhlCisgIC8vIGdyZWVkeSBhbGdvcml0aG0uCisgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQyXzsgKytpKSB7CisgICAgaW50IG1hdGNoZWQgPSAoKm1hdGNoX2xpc3QyXylbaV07CisgICAgaWYgKG1hdGNoZWQgPT0gLTEgJiYgTWF0Y2godiwgaSkpIHsKKyAgICAgICgqbWF0Y2hfbGlzdDJfKVtpXSA9IHY7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgIH0KKyAgLy8gVGhlbiB3ZSB0cnkgdGhvc2UgYWxyZWFkeSBtYXRjaGVkIG5vZGVzIGFuZCBzZWUgaWYgd2UgY2FuIGZpbmQgYW4KKyAgLy8gYWx0ZXJuYWl2ZSBtYXRjaCBmb3IgdGhlIG5vZGUgbWF0Y2hlZCB0byB0aGVtLgorICAvLyBUaGUgZ3JlZWR5IGFsZ29yaXRobSB3aWxsIHN0b3AgYmVmb3JlIHRoaXMgYW5kIGZhaWwgdG8gcHJvZHVjZSB0aGUKKyAgLy8gY29ycmVjdCByZXN1bHQuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgY291bnQyXzsgKytpKSB7CisgICAgaW50IG1hdGNoZWQgPSAoKm1hdGNoX2xpc3QyXylbaV07CisgICAgaWYgKG1hdGNoZWQgIT0gLTEgJiYgTWF0Y2godiwgaSkpIHsKKyAgICAgIGlmICghKCp2aXNpdGVkKVttYXRjaGVkXSAmJiBGaW5kQXJndW1lbnRQYXRoREZTKG1hdGNoZWQsIHZpc2l0ZWQpKSB7CisgICAgICAgICgqbWF0Y2hfbGlzdDJfKVtpXSA9IHY7CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgfQorICAgIH0KKyAgfQorICByZXR1cm4gZmFsc2U7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorCitib29sIE1lc3NhZ2VEaWZmZXJlbmNlcjo6TWF0Y2hSZXBlYXRlZEZpZWxkSW5kaWNlcygKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlMSwKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlMiwKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHJlcGVhdGVkX2ZpZWxkLAorICAgIGNvbnN0IHZlY3RvcjxTcGVjaWZpY0ZpZWxkPiYgcGFyZW50X2ZpZWxkcywKKyAgICB2ZWN0b3I8aW50PiogbWF0Y2hfbGlzdDEsCisgICAgdmVjdG9yPGludD4qIG1hdGNoX2xpc3QyKSB7CisgIGNvbnN0IGludCBjb3VudDEgPQorICAgICAgbWVzc2FnZTEuR2V0UmVmbGVjdGlvbigpLT5GaWVsZFNpemUobWVzc2FnZTEsIHJlcGVhdGVkX2ZpZWxkKTsKKyAgY29uc3QgaW50IGNvdW50MiA9CisgICAgICBtZXNzYWdlMi5HZXRSZWZsZWN0aW9uKCktPkZpZWxkU2l6ZShtZXNzYWdlMiwgcmVwZWF0ZWRfZmllbGQpOworICBjb25zdCBNYXBLZXlDb21wYXJhdG9yKiBrZXlfY29tcGFyYXRvciA9IEdldE1hcEtleUNvbXBhcmF0b3IocmVwZWF0ZWRfZmllbGQpOworCisgIG1hdGNoX2xpc3QxLT5hc3NpZ24oY291bnQxLCAtMSk7CisgIG1hdGNoX2xpc3QyLT5hc3NpZ24oY291bnQyLCAtMSk7CisKKyAgU3BlY2lmaWNGaWVsZCBzcGVjaWZpY19maWVsZDsKKyAgc3BlY2lmaWNfZmllbGQuZmllbGQgPSByZXBlYXRlZF9maWVsZDsKKworICBib29sIHN1Y2Nlc3MgPSB0cnVlOworICAvLyBGaW5kIHBvdGVudGlhbCBtYXRjaCBpZiB0aGlzIGlzIGEgc3BlY2lhbCByZXBlYXRlZCBmaWVsZC4KKyAgaWYgKGtleV9jb21wYXJhdG9yICE9IE5VTEwgfHwgSXNUcmVhdGVkQXNTZXQocmVwZWF0ZWRfZmllbGQpKSB7CisgICAgaWYgKHNjb3BlXyA9PSBQQVJUSUFMKSB7CisgICAgICAvLyBXaGVuIHBhcnRpYWwgbWF0Y2hpbmcgaXMgZW5hYmxlZCwgQ29tcGFyZShhLCBiKSAmJiBDb21wYXJlKGEsIGMpCisgICAgICAvLyBkb2Vzbid0IG5lY2Nlc3NhcmlseSBpbXBseSBDb21wYXJlKGIsIGMpLiBUaGVyZWZvcmUgYSBuYWl2ZSBncmVlZHkKKyAgICAgIC8vIGFsZ29yaXRobSB3aWxsIGZhaWwgdG8gZmluZCBhIG1heGltdW0gbWF0Y2hpbmcuCisgICAgICAvLyBIZXJlIHdlIHVzZSB0aGUgYXJndW1lbnRpbmcgcGF0aCBhbGdvcml0aG0uCisgICAgICBNYXhpbXVtTWF0Y2hlcjo6Tm9kZU1hdGNoQ2FsbGJhY2sqIGNhbGxiYWNrID0KKyAgICAgICAgICBnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6TmV3UGVybWFuZW50Q2FsbGJhY2soCisgICAgICAgICAgICAgIHRoaXMsICZNZXNzYWdlRGlmZmVyZW5jZXI6OklzTWF0Y2gsCisgICAgICAgICAgICAgIHJlcGVhdGVkX2ZpZWxkLCBrZXlfY29tcGFyYXRvciwKKyAgICAgICAgICAgICAgJm1lc3NhZ2UxLCAmbWVzc2FnZTIsIHBhcmVudF9maWVsZHMpOworICAgICAgTWF4aW11bU1hdGNoZXIgbWF0Y2hlcihjb3VudDEsIGNvdW50MiwgY2FsbGJhY2ssIG1hdGNoX2xpc3QxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRjaF9saXN0Mik7CisgICAgICAvLyBJZiBkaWZmIGluZm8gaXMgbm90IG5lZWRlZCwgd2Ugc2hvdWxkIGVuZCB0aGUgbWF0Y2hpbmcgcHJvY2VzcyBhcworICAgICAgLy8gc29vbiBhcyBwb3NzaWJsZSBpZiBub3QgYWxsIGl0ZW1zIGNhbiBiZSBtYXRjaGVkLgorICAgICAgYm9vbCBlYXJseV9yZXR1cm4gPSAocmVwb3J0ZXJfID09IE5VTEwpOworICAgICAgaW50IG1hdGNoX2NvdW50ID0gbWF0Y2hlci5GaW5kTWF4aW11bU1hdGNoKGVhcmx5X3JldHVybik7CisgICAgICBpZiAobWF0Y2hfY291bnQgIT0gY291bnQxICYmIHJlcG9ydGVyXyA9PSBOVUxMKSByZXR1cm4gZmFsc2U7CisgICAgICBzdWNjZXNzID0gc3VjY2VzcyAmJiAobWF0Y2hfY291bnQgPT0gY291bnQxKTsKKyAgICB9IGVsc2UgeworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDE7ICsraSkgeworICAgICAgICAvLyBJbmRpY2F0ZXMgYW55IG1hdGNoZWQgZWxlbWVudHMgZm9yIHRoaXMgcmVwZWF0ZWQgZmllbGQuCisgICAgICAgIGJvb2wgbWF0Y2ggPSBmYWxzZTsKKworICAgICAgICBzcGVjaWZpY19maWVsZC5pbmRleCA9IGk7CisgICAgICAgIHNwZWNpZmljX2ZpZWxkLm5ld19pbmRleCA9IGk7CisKKyAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBjb3VudDI7IGorKykgeworICAgICAgICAgIGlmIChtYXRjaF9saXN0Mi0+YXQoaikgIT0gLTEpIGNvbnRpbnVlOworICAgICAgICAgIHNwZWNpZmljX2ZpZWxkLmluZGV4ID0gaTsKKyAgICAgICAgICBzcGVjaWZpY19maWVsZC5uZXdfaW5kZXggPSBqOworCisgICAgICAgICAgbWF0Y2ggPSBJc01hdGNoKHJlcGVhdGVkX2ZpZWxkLCBrZXlfY29tcGFyYXRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgJm1lc3NhZ2UxLCAmbWVzc2FnZTIsIHBhcmVudF9maWVsZHMsIGksIGopOworCisgICAgICAgICAgaWYgKG1hdGNoKSB7CisgICAgICAgICAgICBtYXRjaF9saXN0MS0+YXQoc3BlY2lmaWNfZmllbGQuaW5kZXgpID0gc3BlY2lmaWNfZmllbGQubmV3X2luZGV4OworICAgICAgICAgICAgbWF0Y2hfbGlzdDItPmF0KHNwZWNpZmljX2ZpZWxkLm5ld19pbmRleCkgPSBzcGVjaWZpY19maWVsZC5pbmRleDsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoIW1hdGNoICYmIHJlcG9ydGVyXyA9PSBOVUxMKSByZXR1cm4gZmFsc2U7CisgICAgICAgIHN1Y2Nlc3MgPSBzdWNjZXNzICYmIG1hdGNoOworICAgICAgfQorICAgIH0KKyAgfSBlbHNlIHsKKyAgICAvLyBJZiB0aGlzIGZpZWxkIHNob3VsZCBiZSB0cmVhdGVkIGFzIGxpc3QsIGp1c3QgbGFiZWwgdGhlIG1hdGNoX2xpc3QuCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDEgJiYgaSA8IGNvdW50MjsgaSsrKSB7CisgICAgICBtYXRjaF9saXN0MS0+YXQoaSkgPSBpOworICAgICAgbWF0Y2hfbGlzdDItPmF0KGkpID0gaTsKKyAgICB9CisgIH0KKworICByZXR1cm4gc3VjY2VzczsKK30KKworRmllbGRDb21wYXJhdG9yOjpDb21wYXJpc29uUmVzdWx0IE1lc3NhZ2VEaWZmZXJlbmNlcjo6R2V0RmllbGRDb21wYXJpc29uUmVzdWx0KAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UxLCBjb25zdCBNZXNzYWdlJiBtZXNzYWdlMiwKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCBpbnQgaW5kZXgxLCBpbnQgaW5kZXgyLAorICAgIGNvbnN0IEZpZWxkQ29udGV4dCogZmllbGRfY29udGV4dCkgeworICBGaWVsZENvbXBhcmF0b3IqIGNvbXBhcmF0b3IgPSBmaWVsZF9jb21wYXJhdG9yXyAhPSBOVUxMID8KKyAgICAgIGZpZWxkX2NvbXBhcmF0b3JfIDogJmRlZmF1bHRfZmllbGRfY29tcGFyYXRvcl87CisgIHJldHVybiBjb21wYXJhdG9yLT5Db21wYXJlKG1lc3NhZ2UxLCBtZXNzYWdlMiwgZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4MSwgaW5kZXgyLCBmaWVsZF9jb250ZXh0KTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK01lc3NhZ2VEaWZmZXJlbmNlcjo6UmVwb3J0ZXI6OlJlcG9ydGVyKCkgeyB9CitNZXNzYWdlRGlmZmVyZW5jZXI6OlJlcG9ydGVyOjp+UmVwb3J0ZXIoKSB7fQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworTWVzc2FnZURpZmZlcmVuY2VyOjpNYXBLZXlDb21wYXJhdG9yOjpNYXBLZXlDb21wYXJhdG9yKCkge30KK01lc3NhZ2VEaWZmZXJlbmNlcjo6TWFwS2V5Q29tcGFyYXRvcjo6fk1hcEtleUNvbXBhcmF0b3IoKSB7fQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworTWVzc2FnZURpZmZlcmVuY2VyOjpJZ25vcmVDcml0ZXJpYTo6SWdub3JlQ3JpdGVyaWEoKSB7fQorTWVzc2FnZURpZmZlcmVuY2VyOjpJZ25vcmVDcml0ZXJpYTo6fklnbm9yZUNyaXRlcmlhKCkge30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKy8vIE5vdGUgdGhhdCB0aGUgcHJpbnRlcidzIGRlbGltaXRlciBpcyBub3QgdXNlZCwgYmVjYXVzZSBpZiB3ZSBhcmUgZ2l2ZW4gYQorLy8gcHJpbnRlciwgd2UgZG9uJ3Qga25vdyBpdHMgZGVsaW1pdGVyLgorTWVzc2FnZURpZmZlcmVuY2VyOjpTdHJlYW1SZXBvcnRlcjo6U3RyZWFtUmVwb3J0ZXIoCisgICAgaW86Olplcm9Db3B5T3V0cHV0U3RyZWFtKiBvdXRwdXQpIDogcHJpbnRlcl8obmV3IGlvOjpQcmludGVyKG91dHB1dCwgJyQnKSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlX3ByaW50ZXJfKHRydWUpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydF9tb2RpZmllZF9hZ2dyZWdhdGVzXyhmYWxzZSkgeyB9CisKK01lc3NhZ2VEaWZmZXJlbmNlcjo6U3RyZWFtUmVwb3J0ZXI6OlN0cmVhbVJlcG9ydGVyKAorICAgIGlvOjpQcmludGVyKiBwcmludGVyKSA6IHByaW50ZXJfKHByaW50ZXIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZV9wcmludGVyXyhmYWxzZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0X21vZGlmaWVkX2FnZ3JlZ2F0ZXNfKGZhbHNlKSB7IH0KKworTWVzc2FnZURpZmZlcmVuY2VyOjpTdHJlYW1SZXBvcnRlcjo6flN0cmVhbVJlcG9ydGVyKCkgeworICBpZiAoZGVsZXRlX3ByaW50ZXJfKSBkZWxldGUgcHJpbnRlcl87Cit9CisKK3ZvaWQgTWVzc2FnZURpZmZlcmVuY2VyOjpTdHJlYW1SZXBvcnRlcjo6UHJpbnRQYXRoKAorICAgIGNvbnN0IHZlY3RvcjxTcGVjaWZpY0ZpZWxkPiYgZmllbGRfcGF0aCwgYm9vbCBsZWZ0X3NpZGUpIHsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZF9wYXRoLnNpemUoKTsgKytpKSB7CisgICAgaWYgKGkgPiAwKSB7CisgICAgICBwcmludGVyXy0+UHJpbnQoIi4iKTsKKyAgICB9CisKKyAgICBTcGVjaWZpY0ZpZWxkIHNwZWNpZmljX2ZpZWxkID0gZmllbGRfcGF0aFtpXTsKKworICAgIGlmIChzcGVjaWZpY19maWVsZC5maWVsZCAhPSBOVUxMKSB7CisgICAgICBpZiAoc3BlY2lmaWNfZmllbGQuZmllbGQtPmlzX2V4dGVuc2lvbigpKSB7CisgICAgICAgIHByaW50ZXJfLT5QcmludCgiKCRuYW1lJCkiLCAibmFtZSIsCisgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWZpY19maWVsZC5maWVsZC0+ZnVsbF9uYW1lKCkpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcHJpbnRlcl8tPlByaW50UmF3KHNwZWNpZmljX2ZpZWxkLmZpZWxkLT5uYW1lKCkpOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICBwcmludGVyXy0+UHJpbnRSYXcoU2ltcGxlSXRvYShzcGVjaWZpY19maWVsZC51bmtub3duX2ZpZWxkX251bWJlcikpOworICAgIH0KKyAgICBpZiAobGVmdF9zaWRlICYmIHNwZWNpZmljX2ZpZWxkLmluZGV4ID49IDApIHsKKyAgICAgIHByaW50ZXJfLT5QcmludCgiWyRuYW1lJF0iLCAibmFtZSIsIFNpbXBsZUl0b2Eoc3BlY2lmaWNfZmllbGQuaW5kZXgpKTsKKyAgICB9CisgICAgaWYgKCFsZWZ0X3NpZGUgJiYgc3BlY2lmaWNfZmllbGQubmV3X2luZGV4ID49IDApIHsKKyAgICAgIHByaW50ZXJfLT5QcmludCgiWyRuYW1lJF0iLCAibmFtZSIsIFNpbXBsZUl0b2Eoc3BlY2lmaWNfZmllbGQubmV3X2luZGV4KSk7CisgICAgfQorICB9Cit9CisKK3ZvaWQgTWVzc2FnZURpZmZlcmVuY2VyOjoKK1N0cmVhbVJlcG9ydGVyOjpQcmludFZhbHVlKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2ZWN0b3I8U3BlY2lmaWNGaWVsZD4mIGZpZWxkX3BhdGgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGxlZnRfc2lkZSkgeworICBjb25zdCBTcGVjaWZpY0ZpZWxkJiBzcGVjaWZpY19maWVsZCA9IGZpZWxkX3BhdGguYmFjaygpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gc3BlY2lmaWNfZmllbGQuZmllbGQ7CisgIGlmIChmaWVsZCAhPSBOVUxMKSB7CisgICAgc3RyaW5nIG91dHB1dDsKKyAgICBpbnQgaW5kZXggPSBsZWZ0X3NpZGUgPyBzcGVjaWZpY19maWVsZC5pbmRleCA6IHNwZWNpZmljX2ZpZWxkLm5ld19pbmRleDsKKyAgICBpZiAoZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UpIHsKKyAgICAgIGNvbnN0IFJlZmxlY3Rpb24qIHJlZmxlY3Rpb24gPSBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKTsKKyAgICAgIGNvbnN0IE1lc3NhZ2UmIGZpZWxkX21lc3NhZ2UgPSBmaWVsZC0+aXNfcmVwZWF0ZWQoKSA/CisgICAgICAgICAgcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRNZXNzYWdlKG1lc3NhZ2UsIGZpZWxkLCBpbmRleCkgOgorICAgICAgICAgIHJlZmxlY3Rpb24tPkdldE1lc3NhZ2UobWVzc2FnZSwgZmllbGQpOworICAgICAgb3V0cHV0ID0gZmllbGRfbWVzc2FnZS5TaG9ydERlYnVnU3RyaW5nKCk7CisgICAgICBpZiAob3V0cHV0LmVtcHR5KCkpIHsKKyAgICAgICAgcHJpbnRlcl8tPlByaW50KCJ7IH0iKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHByaW50ZXJfLT5QcmludCgieyAkbmFtZSQgfSIsICJuYW1lIiwgb3V0cHV0KTsKKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgVGV4dEZvcm1hdDo6UHJpbnRGaWVsZFZhbHVlVG9TdHJpbmcobWVzc2FnZSwgZmllbGQsIGluZGV4LCAmb3V0cHV0KTsKKyAgICAgIHByaW50ZXJfLT5QcmludFJhdyhvdXRwdXQpOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICBjb25zdCBVbmtub3duRmllbGRTZXQqIHVua25vd25fZmllbGRzID0KKyAgICAgICAgKGxlZnRfc2lkZSA/CisgICAgICAgICBzcGVjaWZpY19maWVsZC51bmtub3duX2ZpZWxkX3NldDEgOgorICAgICAgICAgc3BlY2lmaWNfZmllbGQudW5rbm93bl9maWVsZF9zZXQyKTsKKyAgICBjb25zdCBVbmtub3duRmllbGQqIHVua25vd25fZmllbGQgPSAmdW5rbm93bl9maWVsZHMtPmZpZWxkKAorICAgICAgICBsZWZ0X3NpZGUgPworICAgICAgICBzcGVjaWZpY19maWVsZC51bmtub3duX2ZpZWxkX2luZGV4MSA6CisgICAgICAgIHNwZWNpZmljX2ZpZWxkLnVua25vd25fZmllbGRfaW5kZXgyKTsKKyAgICBQcmludFVua25vd25GaWVsZFZhbHVlKHVua25vd25fZmllbGQpOworICB9Cit9CisKK3ZvaWQgTWVzc2FnZURpZmZlcmVuY2VyOjoKK1N0cmVhbVJlcG9ydGVyOjpQcmludFVua25vd25GaWVsZFZhbHVlKGNvbnN0IFVua25vd25GaWVsZCogdW5rbm93bl9maWVsZCkgeworICBHT09HTEVfQ0hFQ0sodW5rbm93bl9maWVsZCAhPSBOVUxMKSA8PCAiIENhbm5vdCBwcmludCBOVUxMIHVua25vd25fZmllbGQuIjsKKworICBzdHJpbmcgb3V0cHV0OworICBzd2l0Y2ggKHVua25vd25fZmllbGQtPnR5cGUoKSkgeworICAgIGNhc2UgVW5rbm93bkZpZWxkOjpUWVBFX1ZBUklOVDoKKyAgICAgIG91dHB1dCA9IFNpbXBsZUl0b2EodW5rbm93bl9maWVsZC0+dmFyaW50KCkpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBVbmtub3duRmllbGQ6OlRZUEVfRklYRUQzMjoKKyAgICAgIG91dHB1dCA9IFN0ckNhdCgiMHgiLCBzdHJpbmdzOjpIZXgodW5rbm93bl9maWVsZC0+Zml4ZWQzMigpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmdzOjpaRVJPX1BBRF84KSk7CisgICAgICBicmVhazsKKyAgICBjYXNlIFVua25vd25GaWVsZDo6VFlQRV9GSVhFRDY0OgorICAgICAgb3V0cHV0ID0gU3RyQ2F0KCIweCIsIHN0cmluZ3M6OkhleCh1bmtub3duX2ZpZWxkLT5maXhlZDY0KCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ3M6OlpFUk9fUEFEXzE2KSk7CisgICAgICBicmVhazsKKyAgICBjYXNlIFVua25vd25GaWVsZDo6VFlQRV9MRU5HVEhfREVMSU1JVEVEOgorICAgICAgb3V0cHV0ID0gU3RyaW5nUHJpbnRmKCJcIiVzXCIiLAorICAgICAgICAgIENFc2NhcGUodW5rbm93bl9maWVsZC0+bGVuZ3RoX2RlbGltaXRlZCgpKS5jX3N0cigpKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgVW5rbm93bkZpZWxkOjpUWVBFX0dST1VQOgorICAgICAgLy8gVE9ETyhrZW50b24pOiAgUHJpbnQgdGhlIGNvbnRlbnRzIG9mIHRoZSBncm91cCBsaWtlIHdlIGRvIGZvcgorICAgICAgLy8gICBtZXNzYWdlcy4gIFJlcXVpcmVzIGFuIGVxdWl2YWxlbnQgb2YgU2hvcnREZWJ1Z1N0cmluZygpIGZvcgorICAgICAgLy8gICBVbmtub3duRmllbGRTZXQuCisgICAgICBvdXRwdXQgPSAieyAuLi4gfSI7CisgICAgICBicmVhazsKKyAgfQorICBwcmludGVyXy0+UHJpbnRSYXcob3V0cHV0KTsKK30KKwordm9pZCBNZXNzYWdlRGlmZmVyZW5jZXI6OlN0cmVhbVJlcG9ydGVyOjpQcmludChjb25zdCBzdHJpbmcmIHN0cikgeworICBwcmludGVyXy0+UHJpbnQoc3RyLmNfc3RyKCkpOworfQorCit2b2lkIE1lc3NhZ2VEaWZmZXJlbmNlcjo6U3RyZWFtUmVwb3J0ZXI6OlJlcG9ydEFkZGVkKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UxLAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UyLAorICAgIGNvbnN0IHZlY3RvcjxTcGVjaWZpY0ZpZWxkPiYgZmllbGRfcGF0aCkgeworICBwcmludGVyXy0+UHJpbnQoImFkZGVkOiAiKTsKKyAgUHJpbnRQYXRoKGZpZWxkX3BhdGgsIGZhbHNlKTsKKyAgcHJpbnRlcl8tPlByaW50KCI6ICIpOworICBQcmludFZhbHVlKG1lc3NhZ2UyLCBmaWVsZF9wYXRoLCBmYWxzZSk7CisgIHByaW50ZXJfLT5QcmludCgiXG4iKTsgIC8vIFByaW50IGZvciBuZXdsaW5lcy4KK30KKwordm9pZCBNZXNzYWdlRGlmZmVyZW5jZXI6OlN0cmVhbVJlcG9ydGVyOjpSZXBvcnREZWxldGVkKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UxLAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UyLAorICAgIGNvbnN0IHZlY3RvcjxTcGVjaWZpY0ZpZWxkPiYgZmllbGRfcGF0aCkgeworICBwcmludGVyXy0+UHJpbnQoImRlbGV0ZWQ6ICIpOworICBQcmludFBhdGgoZmllbGRfcGF0aCwgdHJ1ZSk7CisgIHByaW50ZXJfLT5QcmludCgiOiAiKTsKKyAgUHJpbnRWYWx1ZShtZXNzYWdlMSwgZmllbGRfcGF0aCwgdHJ1ZSk7CisgIHByaW50ZXJfLT5QcmludCgiXG4iKTsgIC8vIFByaW50IGZvciBuZXdsaW5lcworfQorCit2b2lkIE1lc3NhZ2VEaWZmZXJlbmNlcjo6U3RyZWFtUmVwb3J0ZXI6OlJlcG9ydE1vZGlmaWVkKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UxLAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UyLAorICAgIGNvbnN0IHZlY3RvcjxTcGVjaWZpY0ZpZWxkPiYgZmllbGRfcGF0aCkgeworICBpZiAoIXJlcG9ydF9tb2RpZmllZF9hZ2dyZWdhdGVzXyAmJiBmaWVsZF9wYXRoLmJhY2soKS5maWVsZCA9PSBOVUxMKSB7CisgICAgaWYgKGZpZWxkX3BhdGguYmFjaygpLnVua25vd25fZmllbGRfdHlwZSA9PSBVbmtub3duRmllbGQ6OlRZUEVfR1JPVVApIHsKKyAgICAgIC8vIEFueSBjaGFuZ2VzIHRvIHRoZSBzdWJmaWVsZHMgaGF2ZSBhbHJlYWR5IGJlZW4gcHJpbnRlZC4KKyAgICAgIHJldHVybjsKKyAgICB9CisgIH0gZWxzZSBpZiAoIXJlcG9ydF9tb2RpZmllZF9hZ2dyZWdhdGVzXykgeworICAgIGlmIChmaWVsZF9wYXRoLmJhY2soKS5maWVsZC0+Y3BwX3R5cGUoKSA9PQorICAgICAgICBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSkgeworICAgICAgLy8gQW55IGNoYW5nZXMgdG8gdGhlIHN1YmZpZWxkcyBoYXZlIGFscmVhZHkgYmVlbiBwcmludGVkLgorICAgICAgcmV0dXJuOworICAgIH0KKyAgfQorCisgIHByaW50ZXJfLT5QcmludCgibW9kaWZpZWQ6ICIpOworICBQcmludFBhdGgoZmllbGRfcGF0aCwgdHJ1ZSk7CisgIGlmIChDaGVja1BhdGhDaGFuZ2VkKGZpZWxkX3BhdGgpKSB7CisgICAgcHJpbnRlcl8tPlByaW50KCIgLT4gIik7CisgICAgUHJpbnRQYXRoKGZpZWxkX3BhdGgsIGZhbHNlKTsKKyAgfQorICBwcmludGVyXy0+UHJpbnQoIjogIik7CisgIFByaW50VmFsdWUobWVzc2FnZTEsIGZpZWxkX3BhdGgsIHRydWUpOworICBwcmludGVyXy0+UHJpbnQoIiAtPiAiKTsKKyAgUHJpbnRWYWx1ZShtZXNzYWdlMiwgZmllbGRfcGF0aCwgZmFsc2UpOworICBwcmludGVyXy0+UHJpbnQoIlxuIik7ICAvLyBQcmludCBmb3IgbmV3bGluZXMuCit9CisKK3ZvaWQgTWVzc2FnZURpZmZlcmVuY2VyOjpTdHJlYW1SZXBvcnRlcjo6UmVwb3J0TW92ZWQoCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZTEsCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZTIsCisgICAgY29uc3QgdmVjdG9yPFNwZWNpZmljRmllbGQ+JiBmaWVsZF9wYXRoKSB7CisgIHByaW50ZXJfLT5QcmludCgibW92ZWQ6ICIpOworICBQcmludFBhdGgoZmllbGRfcGF0aCwgdHJ1ZSk7CisgIHByaW50ZXJfLT5QcmludCgiIC0+ICIpOworICBQcmludFBhdGgoZmllbGRfcGF0aCwgZmFsc2UpOworICBwcmludGVyXy0+UHJpbnQoIiA6ICIpOworICBQcmludFZhbHVlKG1lc3NhZ2UxLCBmaWVsZF9wYXRoLCB0cnVlKTsKKyAgcHJpbnRlcl8tPlByaW50KCJcbiIpOyAgLy8gUHJpbnQgZm9yIG5ld2xpbmVzLgorfQorCit2b2lkIE1lc3NhZ2VEaWZmZXJlbmNlcjo6U3RyZWFtUmVwb3J0ZXI6OlJlcG9ydE1hdGNoZWQoCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZTEsCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZTIsCisgICAgY29uc3QgdmVjdG9yPFNwZWNpZmljRmllbGQ+JiBmaWVsZF9wYXRoKSB7CisgIHByaW50ZXJfLT5QcmludCgibWF0Y2hlZDogIik7CisgIFByaW50UGF0aChmaWVsZF9wYXRoLCB0cnVlKTsKKyAgaWYgKENoZWNrUGF0aENoYW5nZWQoZmllbGRfcGF0aCkpIHsKKyAgICBwcmludGVyXy0+UHJpbnQoIiAtPiAiKTsKKyAgICBQcmludFBhdGgoZmllbGRfcGF0aCwgZmFsc2UpOworICB9CisgIHByaW50ZXJfLT5QcmludCgiIDogIik7CisgIFByaW50VmFsdWUobWVzc2FnZTEsIGZpZWxkX3BhdGgsIHRydWUpOworICBwcmludGVyXy0+UHJpbnQoIlxuIik7ICAvLyBQcmludCBmb3IgbmV3bGluZXMuCit9CisKK3ZvaWQgTWVzc2FnZURpZmZlcmVuY2VyOjpTdHJlYW1SZXBvcnRlcjo6UmVwb3J0SWdub3JlZCgKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlMSwKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlMiwKKyAgICBjb25zdCB2ZWN0b3I8U3BlY2lmaWNGaWVsZD4mIGZpZWxkX3BhdGgpIHsKKyAgcHJpbnRlcl8tPlByaW50KCJpZ25vcmVkOiAiKTsKKyAgUHJpbnRQYXRoKGZpZWxkX3BhdGgsIHRydWUpOworICBpZiAoQ2hlY2tQYXRoQ2hhbmdlZChmaWVsZF9wYXRoKSkgeworICAgIHByaW50ZXJfLT5QcmludCgiIC0+ICIpOworICAgIFByaW50UGF0aChmaWVsZF9wYXRoLCBmYWxzZSk7CisgIH0KKyAgcHJpbnRlcl8tPlByaW50KCJcbiIpOyAgLy8gUHJpbnQgZm9yIG5ld2xpbmVzLgorfQorCit2b2lkIE1lc3NhZ2VEaWZmZXJlbmNlcjo6U3RyZWFtUmVwb3J0ZXI6OlJlcG9ydFVua25vd25GaWVsZElnbm9yZWQoCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZTEsIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UyLAorICAgIGNvbnN0IHZlY3RvcjxTcGVjaWZpY0ZpZWxkPiYgZmllbGRfcGF0aCkgeworICBwcmludGVyXy0+UHJpbnQoImlnbm9yZWQ6ICIpOworICBQcmludFBhdGgoZmllbGRfcGF0aCwgdHJ1ZSk7CisgIGlmIChDaGVja1BhdGhDaGFuZ2VkKGZpZWxkX3BhdGgpKSB7CisgICAgcHJpbnRlcl8tPlByaW50KCIgLT4gIik7CisgICAgUHJpbnRQYXRoKGZpZWxkX3BhdGgsIGZhbHNlKTsKKyAgfQorICBwcmludGVyXy0+UHJpbnQoIlxuIik7ICAvLyBQcmludCBmb3IgbmV3bGluZXMuCit9CisKK30gIC8vIG5hbWVzcGFjZSB1dGlsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9tZXNzYWdlX2RpZmZlcmVuY2VyLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvbWVzc2FnZV9kaWZmZXJlbmNlci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNlYTc0ZTYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvbWVzc2FnZV9kaWZmZXJlbmNlci5oCkBAIC0wLDAgKzEsODQzIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBqc2Nob3JyQGdvb2dsZS5jb20gKEpvc2VwaCBTY2hvcnIpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKy8vCisvLyBUaGlzIGZpbGUgZGVmaW5lcyBzdGF0aWMgbWV0aG9kcyBhbmQgY2xhc3NlcyBmb3IgY29tcGFyaW5nIFByb3RvY29sCisvLyBNZXNzYWdlcy4KKy8vCisvLyBBdWcuIDIwMDg6IEFkZGVkIFVua25vd24gRmllbGRzIENvbXBhcmlzb24gZm9yIG1lc3NhZ2VzLgorLy8gQXVnLiAyMDA5OiBBZGRlZCBkaWZmZXJlbnQgb3B0aW9ucyB0byBjb21wYXJlIHJlcGVhdGVkIGZpZWxkcy4KKy8vIEFwci4gMjAxMDogTW92ZWQgZmllbGQgY29tcGFyaXNvbiB0byBGaWVsZENvbXBhcmF0b3IuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX1VUSUxfTUVTU0FHRV9ESUZGRVJFTkNFUl9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1VUSUxfTUVTU0FHRV9ESUZGRVJFTkNFUl9IX18KKworI2luY2x1ZGUgPG1hcD4KKyNpbmNsdWRlIDxzZXQ+CisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPHZlY3Rvcj4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPiAgLy8gRmllbGREZXNjcmlwdG9yCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21lc3NhZ2UuaD4gIC8vIE1lc3NhZ2UKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdW5rbm93bl9maWVsZF9zZXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9maWVsZF9jb21wYXJhdG9yLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworY2xhc3MgRHluYW1pY01lc3NhZ2VGYWN0b3J5OworY2xhc3MgRmllbGREZXNjcmlwdG9yOworCituYW1lc3BhY2UgaW8geworY2xhc3MgWmVyb0NvcHlPdXRwdXRTdHJlYW07CitjbGFzcyBQcmludGVyOworfQorCituYW1lc3BhY2UgdXRpbCB7CisKK2NsYXNzIEZpZWxkQ29udGV4dDsgIC8vIGRlY2xhcmVkIGJlbG93IE1lc3NhZ2VEaWZmZXJlbmNlcgorCisvLyBBIGJhc2ljIGRpZmZlcmVuY2VyIHRoYXQgY2FuIGJlIHVzZWQgdG8gZGV0ZXJtaW5lCisvLyB0aGUgZGlmZmVyZW5jZXMgYmV0d2VlbiB0d28gc3BlY2lmaWVkIFByb3RvY29sIE1lc3NhZ2VzLiBJZiBhbnkgZGlmZmVyZW5jZXMKKy8vIGFyZSBmb3VuZCwgdGhlIENvbXBhcmUgbWV0aG9kIHdpbGwgcmV0dXJuIGZhbHNlLCBhbmQgYW55IGRpZmZlcmVuY2VyIHJlcG9ydGVyCisvLyBzcGVjaWZpZWQgdmlhIFJlcG9ydERpZmZlcmVuY2VzVG8gd2lsbCBoYXZlIGl0cyByZXBvcnRpbmcgbWV0aG9kcyBjYWxsZWQgKHNlZQorLy8gYmVsb3cgZm9yIGltcGxlbWVudGF0aW9uIG9mIHRoZSByZXBvcnQpLiBCYXNlZCBvZmYgb2YgdGhlIG9yaWdpbmFsCisvLyBQcm90b2NvbERpZmZlcmVuY2VyIGltcGxlbWVudGF0aW9uIGluIC8vbmV0L3Byb3RvL3Byb3RvY29sLWRpZmZlcmVuY2VyLmgKKy8vIChUaGFua3MgVG9kZCEpLgorLy8KKy8vIE1lc3NhZ2VEaWZmZXJlbmNlciBSRVFVSVJFUyB0aGF0IGNvbXBhcmVkIG1lc3NhZ2VzIGJlIHRoZSBzYW1lIHR5cGUsIGRlZmluZWQKKy8vIGFzIG1lc3NhZ2VzIHRoYXQgc2hhcmUgdGhlIHNhbWUgZGVzY3JpcHRvci4gIElmIG5vdCwgdGhlIGJlaGF2aW9yIG9mIHRoaXMKKy8vIGNsYXNzIGlzIHVuZGVmaW5lZC4KKy8vCisvLyBQZW9wbGUgZGlzYWdyZWUgb24gd2hhdCBNZXNzYWdlRGlmZmVyZW5jZXIgc2hvdWxkIGRvIHdoZW4gYXNrZWQgdG8gY29tcGFyZQorLy8gbWVzc2FnZXMgd2l0aCBkaWZmZXJlbnQgZGVzY3JpcHRvcnMuICBTb21lIHBlb3BsZSB0aGluayBpdCBzaG91bGQgYWx3YXlzCisvLyByZXR1cm4gZmFsc2UuICBPdGhlcnMgZXhwZWN0IGl0IHRvIHRyeSB0byBsb29rIGZvciBzaW1pbGFyIGZpZWxkcyBhbmQKKy8vIGNvbXBhcmUgdGhlbSBhbnl3YXkgLS0gZXNwZWNpYWxseSBpZiB0aGUgZGVzY3JpcHRvcnMgaGFwcGVuIHRvIGJlIGlkZW50aWNhbC4KKy8vIElmIHdlIGNob3NlIGVpdGhlciBvZiB0aGVzZSBiZWhhdmlvcnMsIHNvbWUgc2V0IG9mIHBlb3BsZSB3b3VsZCBmaW5kIGl0CisvLyBzdXJwcmlzaW5nLCBhbmQgY291bGQgZW5kIHVwIHdyaXRpbmcgY29kZSBleHBlY3RpbmcgdGhlIG90aGVyIGJlaGF2aW9yCisvLyB3aXRob3V0IHJlYWxpemluZyB0aGVpciBlcnJvci4gIFRoZXJlZm9yZSwgd2UgZm9yYmlkIHRoYXQgdXNhZ2UuCisvLworLy8gVGhpcyBjbGFzcyBpcyBpbXBsZW1lbnRlZCBiYXNlZCBvbiB0aGUgcHJvdG8yIHJlZmxlY3Rpb24uIFRoZSBwZXJmb3JtYW5jZQorLy8gc2hvdWxkIGJlIGdvb2QgZW5vdWdoIGZvciBub3JtYWwgdXNhZ2VzLiBIb3dldmVyLCBmb3IgcGxhY2VzIHdoZXJlIHRoZQorLy8gcGVyZm9ybWFuY2UgaXMgZXh0cmVtZWx5IHNlbnNpdGl2ZSwgdGhlcmUgYXJlIHNldmVyYWwgYWx0ZXJuYXRpdmVzOgorLy8gLSBDb21wYXJpbmcgc2VyaWFsaXplZCBzdHJpbmcKKy8vIERvd25zaWRlOiBmYWxzZSBuZWdhdGl2ZXMgKHRoZXJlIGFyZSBtZXNzYWdlcyB0aGF0IGFyZSB0aGUgc2FtZSBidXQgdGhlaXIKKy8vIHNlcmlhbGl6ZWQgc3RyaW5ncyBhcmUgZGlmZmVyZW50KS4KKy8vIC0gRXF1YWxzIGNvZGUgZ2VuZXJhdG9yIGJ5IGNvbXBpbGVyIHBsdWdpbiAobmV0L3Byb3RvMi9jb250cmliL2VxdWFsc19wbHVnaW4pCisvLyBEb3duc2lkZTogbW9yZSBnZW5lcmF0ZWQgY29kZTsgbWFpbnRlbmFuY2Ugb3ZlcmhlYWQgZm9yIHRoZSBhZGRpdGlvbmFsIHJ1bGUKKy8vIChtdXN0IGJlIGluIHN5bmMgd2l0aCB0aGUgb3JpZ2luYWwgcHJvdG9fbGlicmFyeSkuCisvLworLy8gTm90ZSBvbiBoYW5kbGluZyBvZiBnb29nbGUucHJvdG9idWYuQW55OiBNZXNzYWdlRGlmZmVyZW5jZXIgYXV0b21hdGljYWxseQorLy8gdW5wYWNrcyBBbnk6OnZhbHVlIGludG8gYSBNZXNzYWdlIGFuZCBjb21wYXJlcyBpdHMgaW5kaXZpZHVhbCBmaWVsZHMuCisvLyBNZXNzYWdlcyBlbmNvZGVkIGluIGEgcmVwZWF0ZWQgQW55IGNhbm5vdCBiZSBjb21wYXJlZCB1c2luZyBUcmVhdEFzTWFwLgorLy8KKy8vCisvLyBOb3RlIG9uIHRocmVhZC1zYWZldHk6IE1lc3NhZ2VEaWZmZXJlbmNlciBpcyAqbm90KiB0aHJlYWQtc2FmZS4gWW91IG5lZWQgdG8KKy8vIGd1YXJkIGl0IHdpdGggYSBsb2NrIHRvIHVzZSB0aGUgc2FtZSBNZXNzYWdlRGlmZmVyZW5jZXIgaW5zdGFuY2UgZnJvbQorLy8gbXVsdGlwbGUgdGhyZWFkcy4gTm90ZSB0aGF0IGl0J3MgZmluZSB0byBjYWxsIHN0YXRpYyBjb21wYXJpc29uIG1ldGhvZHMKKy8vIChsaWtlIE1lc3NhZ2VEaWZmZXJlbmNlcjo6RXF1YWxzKSBjb25jdXJyZW50bHkuCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgTWVzc2FnZURpZmZlcmVuY2VyIHsKKyBwdWJsaWM6CisgIC8vIERldGVybWluZXMgd2hldGhlciB0aGUgc3VwcGxpZWQgbWVzc2FnZXMgYXJlIGVxdWFsLiBFcXVhbGl0eSBpcyBkZWZpbmVkIGFzCisgIC8vIGFsbCBmaWVsZHMgd2l0aGluIHRoZSB0d28gbWVzc2FnZXMgYmVpbmcgc2V0IHRvIHRoZSBzYW1lIHZhbHVlLiBQcmltaXRpdmUKKyAgLy8gZmllbGRzIGFuZCBzdHJpbmdzIGFyZSBjb21wYXJlZCBieSB2YWx1ZSB3aGlsZSBlbWJlZGRlZCBtZXNzYWdlcy9ncm91cHMKKyAgLy8gYXJlIGNvbXBhcmVkIGFzIGlmIHZpYSBhIHJlY3Vyc2l2ZSBjYWxsLiBVc2UgSWdub3JlRmllbGQoKSBhbmQgQ29tcGFyZSgpCisgIC8vIGlmIHNvbWUgZmllbGRzIHNob3VsZCBiZSBpZ25vcmVkIGluIHRoZSBjb21wYXJpc29uLgorICAvLworICAvLyBUaGlzIG1ldGhvZCBSRVFVSVJFUyB0aGF0IHRoZSB0d28gbWVzc2FnZXMgaGF2ZSB0aGUgc2FtZQorICAvLyBEZXNjcmlwdG9yIChtZXNzYWdlMS5HZXREZXNjcmlwdG9yKCkgPT0gbWVzc2FnZTIuR2V0RGVzY3JpcHRvcigpKS4KKyAgc3RhdGljIGJvb2wgRXF1YWxzKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UxLCBjb25zdCBNZXNzYWdlJiBtZXNzYWdlMik7CisKKyAgLy8gRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBzdXBwbGllZCBtZXNzYWdlcyBhcmUgZXF1aXZhbGVudC4gRXF1aXZhbGVuY3kgaXMKKyAgLy8gZGVmaW5lZCBhcyBhbGwgZmllbGRzIHdpdGhpbiB0aGUgdHdvIG1lc3NhZ2VzIGhhdmluZyB0aGUgc2FtZSB2YWx1ZS4gVGhpcworICAvLyBkaWZmZXJzIGZyb20gdGhlIEVxdWFscyBtZXRob2QgYWJvdmUgaW4gdGhhdCBmaWVsZHMgd2l0aCBkZWZhdWx0IHZhbHVlcworICAvLyBhcmUgY29uc2lkZXJlZCBzZXQgdG8gc2FpZCB2YWx1ZSBhdXRvbWF0aWNhbGx5LiBGb3IgZGV0YWlscyBvbiBob3cgZGVmYXVsdAorICAvLyB2YWx1ZXMgYXJlIGRlZmluZWQgZm9yIGVhY2ggZmllbGQgdHlwZSwgc2VlIGh0dHA6Ly9zaG9ydG4vX3gyR3Y2WEZyV3QuCisgIC8vIEFsc28sIEVxdWl2YWxlbnQoKSBpZ25vcmVzIHVua25vd24gZmllbGRzLiBVc2UgSWdub3JlRmllbGQoKSBhbmQgQ29tcGFyZSgpCisgIC8vIGlmIHNvbWUgZmllbGRzIHNob3VsZCBiZSBpZ25vcmVkIGluIHRoZSBjb21wYXJpc29uLgorICAvLworICAvLyBUaGlzIG1ldGhvZCBSRVFVSVJFUyB0aGF0IHRoZSB0d28gbWVzc2FnZXMgaGF2ZSB0aGUgc2FtZQorICAvLyBEZXNjcmlwdG9yIChtZXNzYWdlMS5HZXREZXNjcmlwdG9yKCkgPT0gbWVzc2FnZTIuR2V0RGVzY3JpcHRvcigpKS4KKyAgc3RhdGljIGJvb2wgRXF1aXZhbGVudChjb25zdCBNZXNzYWdlJiBtZXNzYWdlMSwgY29uc3QgTWVzc2FnZSYgbWVzc2FnZTIpOworCisgIC8vIERldGVybWluZXMgd2hldGhlciB0aGUgc3VwcGxpZWQgbWVzc2FnZXMgYXJlIGFwcHJveGltYXRlbHkgZXF1YWwuCisgIC8vIEFwcHJveGltYXRlIGVxdWFsaXR5IGlzIGRlZmluZWQgYXMgYWxsIGZpZWxkcyB3aXRoaW4gdGhlIHR3byBtZXNzYWdlcworICAvLyBiZWluZyBhcHByb3hpbWF0ZWx5IGVxdWFsLiAgUHJpbWl0aXZlIChub24tZmxvYXQpIGZpZWxkcyBhbmQgc3RyaW5ncyBhcmUKKyAgLy8gY29tcGFyZWQgYnkgdmFsdWUsIGZsb2F0cyBhcmUgY29tcGFyZWQgdXNpbmcgTWF0aFV0aWw6OkFsbW9zdEVxdWFscygpIGFuZAorICAvLyBlbWJlZGRlZCBtZXNzYWdlcy9ncm91cHMgYXJlIGNvbXBhcmVkIGFzIGlmIHZpYSBhIHJlY3Vyc2l2ZSBjYWxsLiBVc2UKKyAgLy8gSWdub3JlRmllbGQoKSBhbmQgQ29tcGFyZSgpIGlmIHNvbWUgZmllbGRzIHNob3VsZCBiZSBpZ25vcmVkIGluIHRoZQorICAvLyBjb21wYXJpc29uLgorICAvLworICAvLyBUaGlzIG1ldGhvZCBSRVFVSVJFUyB0aGF0IHRoZSB0d28gbWVzc2FnZXMgaGF2ZSB0aGUgc2FtZQorICAvLyBEZXNjcmlwdG9yIChtZXNzYWdlMS5HZXREZXNjcmlwdG9yKCkgPT0gbWVzc2FnZTIuR2V0RGVzY3JpcHRvcigpKS4KKyAgc3RhdGljIGJvb2wgQXBwcm94aW1hdGVseUVxdWFscyhjb25zdCBNZXNzYWdlJiBtZXNzYWdlMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlMik7CisKKyAgLy8gRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBzdXBwbGllZCBtZXNzYWdlcyBhcmUgYXBwcm94aW1hdGVseSBlcXVpdmFsZW50LgorICAvLyBBcHByb3hpbWF0ZSBlcXVpdmFsZW5jeSBpcyBkZWZpbmVkIGFzIGFsbCBmaWVsZHMgd2l0aGluIHRoZSB0d28gbWVzc2FnZXMKKyAgLy8gYmVpbmcgYXBwcm94aW1hdGVseSBlcXVpdmFsZW50LiBBcyBpbgorICAvLyBNZXNzYWdlRGlmZmVyZW5jZXI6OkFwcHJveGltYXRlbHlFcXVhbHMsIHByaW1pdGl2ZSAobm9uLWZsb2F0KSBmaWVsZHMgYW5kCisgIC8vIHN0cmluZ3MgYXJlIGNvbXBhcmVkIGJ5IHZhbHVlLCBmbG9hdHMgYXJlIGNvbXBhcmVkIHVzaW5nCisgIC8vIE1hdGhVdGlsOjpBbG1vc3RFcXVhbHMoKSBhbmQgZW1iZWRkZWQgbWVzc2FnZXMvZ3JvdXBzIGFyZSBjb21wYXJlZCBhcyBpZgorICAvLyB2aWEgYSByZWN1cnNpdmUgY2FsbC4gSG93ZXZlciwgZmllbGRzIHdpdGggZGVmYXVsdCB2YWx1ZXMgYXJlIGNvbnNpZGVyZWQKKyAgLy8gc2V0IHRvIHNhaWQgdmFsdWUsIGFzIHBlciBNZXNzYWdlRGlmZmVuY2VyOjpFcXVpdmFsZW50LiBVc2UgSWdub3JlRmllbGQoKQorICAvLyBhbmQgQ29tcGFyZSgpIGlmIHNvbWUgZmllbGRzIHNob3VsZCBiZSBpZ25vcmVkIGluIHRoZSBjb21wYXJpc29uLgorICAvLworICAvLyBUaGlzIG1ldGhvZCBSRVFVSVJFUyB0aGF0IHRoZSB0d28gbWVzc2FnZXMgaGF2ZSB0aGUgc2FtZQorICAvLyBEZXNjcmlwdG9yIChtZXNzYWdlMS5HZXREZXNjcmlwdG9yKCkgPT0gbWVzc2FnZTIuR2V0RGVzY3JpcHRvcigpKS4KKyAgc3RhdGljIGJvb2wgQXBwcm94aW1hdGVseUVxdWl2YWxlbnQoY29uc3QgTWVzc2FnZSYgbWVzc2FnZTEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UyKTsKKworICAvLyBJZGVudGlmaWVzIGFuIGluZGl2aWR1YWwgZmllbGQgaW4gYSBtZXNzYWdlIGluc3RhbmNlLiAgVXNlZCBmb3IgZmllbGRfcGF0aCwKKyAgLy8gYmVsb3cuCisgIHN0cnVjdCBTcGVjaWZpY0ZpZWxkIHsKKyAgICAvLyBGb3Iga25vd24gZmllbGRzLCAiZmllbGQiIGlzIGZpbGxlZCBpbiBhbmQgInVua25vd25fZmllbGRfbnVtYmVyIiBpcyAtMS4KKyAgICAvLyBGb3IgdW5rbm93biBmaWVsZHMsICJmaWVsZCIgaXMgTlVMTCwgInVua25vd25fZmllbGRfbnVtYmVyIiBpcyB0aGUgZmllbGQKKyAgICAvLyBudW1iZXIsIGFuZCAidW5rbm93bl9maWVsZF90eXBlIiBpcyBpdHMgdHlwZS4KKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkOworICAgIGludCB1bmtub3duX2ZpZWxkX251bWJlcjsKKyAgICBVbmtub3duRmllbGQ6OlR5cGUgdW5rbm93bl9maWVsZF90eXBlOworCisgICAgLy8gSWYgdGhpcyBhIHJlcGVhdGVkIGZpZWxkLCAiaW5kZXgiIGlzIHRoZSBpbmRleCB3aXRoaW4gaXQuICBGb3IgdW5rbm93bgorICAgIC8vIGZpZWxkcywgdGhpcyBpcyB0aGUgaW5kZXggb2YgdGhlIGZpZWxkIGFtb25nIGFsbCB1bmtub3duIGZpZWxkcyBvZiB0aGUKKyAgICAvLyBzYW1lIGZpZWxkIG51bWJlciBhbmQgdHlwZS4KKyAgICBpbnQgaW5kZXg7CisKKyAgICAvLyBJZiAiZmllbGQiIGlzIGEgcmVwZWF0ZWQgZmllbGQgd2hpY2ggaXMgYmVpbmcgdHJlYXRlZCBhcyBhIG1hcCBvcgorICAgIC8vIGEgc2V0IChzZWUgVHJlYXRBc01hcCgpIGFuZCBUcmVhdEFzU2V0KCksIGJlbG93KSwgbmV3X2luZGV4IGluZGljYXRlcworICAgIC8vIHRoZSBpbmRleCB0aGUgcG9zaXRpb24gdG8gd2hpY2ggdGhlIGVsZW1lbnQgaGFzIG1vdmVkLiAgVGhpcyBvbmx5CisgICAgLy8gYXBwbGllcyB0byBSZXBvcnRNb3ZlZCgpIGFuZCAoaW4gdGhlIGNhc2Ugb2YgVHJlYXRBc01hcCgpKQorICAgIC8vIFJlcG9ydE1vZGlmaWVkKCkuICBJbiBhbGwgb3RoZXIgY2FzZXMsICJuZXdfaW5kZXgiIHdpbGwgaGF2ZSB0aGUgc2FtZQorICAgIC8vIHZhbHVlIGFzICJpbmRleCIuCisgICAgaW50IG5ld19pbmRleDsKKworICAgIC8vIEZvciB1bmtub3duIGZpZWxkcywgdGhlc2UgYXJlIHRoZSBwb2ludGVycyB0byB0aGUgVW5rbm93bkZpZWxkU2V0CisgICAgLy8gY29udGFpbmluZyB0aGUgdW5rbm93biBmaWVsZHMuIEluIGNlcnRhaW4gY2FzZXMgKGUuZy4gcHJvdG8xJ3MKKyAgICAvLyBNZXNzYWdlU2V0LCBvciBuZXN0ZWQgZ3JvdXBzIG9mIHVua25vd24gZmllbGRzKSwgdGhlc2UgbWF5IGRpZmZlciBmcm9tCisgICAgLy8gdGhlIG1lc3NhZ2VzJyBpbnRlcm5hbCBVbmtub3duRmllbGRTZXRzLgorICAgIGNvbnN0IFVua25vd25GaWVsZFNldCogdW5rbm93bl9maWVsZF9zZXQxOworICAgIGNvbnN0IFVua25vd25GaWVsZFNldCogdW5rbm93bl9maWVsZF9zZXQyOworCisgICAgLy8gRm9yIHVua25vd24gZmllbGRzLCB0aGVzZSBhcmUgdGhlIGluZGV4IG9mIHRoZSBmaWVsZCB3aXRoaW4gdGhlCisgICAgLy8gVW5rbm93bkZpZWxkU2V0cy4gT25lIG9yIHRoZSBvdGhlciB3aWxsIGJlIC0xIHdoZW4KKyAgICAvLyByZXBvcnRpbmcgYW4gYWRkaXRpb24gb3IgZGVsZXRpb24uCisgICAgaW50IHVua25vd25fZmllbGRfaW5kZXgxOworICAgIGludCB1bmtub3duX2ZpZWxkX2luZGV4MjsKKworICAgIFNwZWNpZmljRmllbGQoKQorICAgICAgICA6IGZpZWxkKE5VTEwpLAorICAgICAgICAgIHVua25vd25fZmllbGRfbnVtYmVyKC0xKSwKKyAgICAgICAgICBpbmRleCgtMSksCisgICAgICAgICAgbmV3X2luZGV4KC0xKSwKKyAgICAgICAgICB1bmtub3duX2ZpZWxkX3NldDEoTlVMTCksCisgICAgICAgICAgdW5rbm93bl9maWVsZF9zZXQyKE5VTEwpLAorICAgICAgICAgIHVua25vd25fZmllbGRfaW5kZXgxKC0xKSwKKyAgICAgICAgICB1bmtub3duX2ZpZWxkX2luZGV4MigtMSkge30KKyAgfTsKKworICAvLyBBYnN0cmFjdCBiYXNlIGNsYXNzIGZyb20gd2hpY2ggYWxsIE1lc3NhZ2VEaWZmZXJlbmNlcgorICAvLyByZXBvcnRlcnMgZGVyaXZlLiBUaGUgZml2ZSBSZXBvcnQqIG1ldGhvZHMgYmVsb3cgd2lsbCBiZSBjYWxsZWQgd2hlbgorICAvLyBhIGZpZWxkIGhhcyBiZWVuIGFkZGVkLCBkZWxldGVkLCBtb2RpZmllZCwgbW92ZWQsIG9yIG1hdGNoZWQuIFRoZSB0aGlyZAorICAvLyBhcmd1bWVudCBpcyBhIHZlY3RvciBvZiBGaWVsZERlc2NyaXB0b3IgcG9pbnRlcnMgd2hpY2ggZGVzY3JpYmVzIHRoZSBjaGFpbgorICAvLyBvZiBmaWVsZHMgdGhhdCB3YXMgdGFrZW4gdG8gZmluZCB0aGUgY3VycmVudCBmaWVsZC4gRm9yIGV4YW1wbGUsIGZvciBhCisgIC8vIGZpZWxkIGZvdW5kIGluIGFuIGVtYmVkZGVkIG1lc3NhZ2UsIHRoZSB2ZWN0b3Igd2lsbCBjb250YWluIHR3bworICAvLyBGaWVsZERlc2NyaXB0b3JzLiBUaGUgZmlyc3Qgd2lsbCBiZSB0aGUgZmllbGQgb2YgdGhlIGVtYmVkZGVkIG1lc3NhZ2UKKyAgLy8gaXRzZWxmIGFuZCB0aGUgc2Vjb25kIHdpbGwgYmUgdGhlIGFjdHVhbCBmaWVsZCBpbiB0aGUgZW1iZWRkZWQgbWVzc2FnZQorICAvLyB0aGF0IHdhcyBhZGRlZC9kZWxldGVkL21vZGlmaWVkLgorICBjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgUmVwb3J0ZXIgeworICAgcHVibGljOgorICAgIFJlcG9ydGVyKCk7CisgICAgdmlydHVhbCB+UmVwb3J0ZXIoKTsKKworICAgIC8vIFJlcG9ydHMgdGhhdCBhIGZpZWxkIGhhcyBiZWVuIGFkZGVkIGludG8gTWVzc2FnZTIuCisgICAgdmlydHVhbCB2b2lkIFJlcG9ydEFkZGVkKAorICAgICAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlMSwgY29uc3QgTWVzc2FnZSYgbWVzc2FnZTIsCisgICAgICAgIGNvbnN0IHZlY3RvcjxTcGVjaWZpY0ZpZWxkPiYgZmllbGRfcGF0aCkgPSAwOworCisgICAgLy8gUmVwb3J0cyB0aGF0IGEgZmllbGQgaGFzIGJlZW4gZGVsZXRlZCBmcm9tIE1lc3NhZ2UxLgorICAgIHZpcnR1YWwgdm9pZCBSZXBvcnREZWxldGVkKAorICAgICAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlMSwKKyAgICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZTIsCisgICAgICAgIGNvbnN0IHZlY3RvcjxTcGVjaWZpY0ZpZWxkPiYgZmllbGRfcGF0aCkgPSAwOworCisgICAgLy8gUmVwb3J0cyB0aGF0IHRoZSB2YWx1ZSBvZiBhIGZpZWxkIGhhcyBiZWVuIG1vZGlmaWVkLgorICAgIHZpcnR1YWwgdm9pZCBSZXBvcnRNb2RpZmllZCgKKyAgICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZTEsCisgICAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UyLAorICAgICAgICBjb25zdCB2ZWN0b3I8U3BlY2lmaWNGaWVsZD4mIGZpZWxkX3BhdGgpID0gMDsKKworICAgIC8vIFJlcG9ydHMgdGhhdCBhIHJlcGVhdGVkIGZpZWxkIGhhcyBiZWVuIG1vdmVkIHRvIGFub3RoZXIgbG9jYXRpb24uICBUaGlzCisgICAgLy8gb25seSBhcHBsaWVzIHdoZW4gdXNpbmcgVHJlYXRBc1NldCBvciBUcmVhdEFzTWFwKCkgIC0tIHNlZSBiZWxvdy4gQWxzbworICAgIC8vIG5vdGUgdGhhdCBmb3IgYW55IGdpdmVuIGZpZWxkLCBSZXBvcnRNb2RpZmllZCBhbmQgUmVwb3J0TW92ZWQgYXJlCisgICAgLy8gbXV0dWFsbHkgZXhjbHVzaXZlLiBJZiBhIGZpZWxkIGhhcyBiZWVuIGJvdGggbW92ZWQgYW5kIG1vZGlmaWVkLCB0aGVuCisgICAgLy8gb25seSBSZXBvcnRNb2RpZmllZCB3aWxsIGJlIGNhbGxlZC4KKyAgICB2aXJ0dWFsIHZvaWQgUmVwb3J0TW92ZWQoCisgICAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UxLAorICAgICAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlMiwKKyAgICAgICAgY29uc3QgdmVjdG9yPFNwZWNpZmljRmllbGQ+JiBmaWVsZF9wYXRoKSB7IH0KKworICAgIC8vIFJlcG9ydHMgdGhhdCB0d28gZmllbGRzIG1hdGNoLiBVc2VmdWwgZm9yIGRvaW5nIHNpZGUtYnktc2lkZSBkaWZmcy4KKyAgICAvLyBUaGlzIGZ1bmN0aW9uIGlzIG11dHVhbGx5IGV4Y2x1c2l2ZSB3aXRoIFJlcG9ydE1vZGlmaWVkIGFuZCBSZXBvcnRNb3ZlZC4KKyAgICAvLyBOb3RlIHRoYXQgeW91IG11c3QgY2FsbCBzZXRfcmVwb3J0X21hdGNoZXModHJ1ZSkgYmVmb3JlIGNhbGxpbmcgQ29tcGFyZQorICAgIC8vIHRvIG1ha2UgdXNlIG9mIHRoaXMgZnVuY3Rpb24uCisgICAgdmlydHVhbCB2b2lkIFJlcG9ydE1hdGNoZWQoCisgICAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UxLAorICAgICAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlMiwKKyAgICAgICAgY29uc3QgdmVjdG9yPFNwZWNpZmljRmllbGQ+JiBmaWVsZF9wYXRoKSB7IH0KKworICAgIC8vIFJlcG9ydHMgdGhhdCB0d28gZmllbGRzIHdvdWxkIGhhdmUgYmVlbiBjb21wYXJlZCwgYnV0IHRoZQorICAgIC8vIGNvbXBhcmlzb24gaGFzIGJlZW4gc2tpcHBlZCBiZWNhdXNlIHRoZSBmaWVsZCB3YXMgbWFya2VkIGFzCisgICAgLy8gJ2lnbm9yZWQnIHVzaW5nIElnbm9yZUZpZWxkKCkuICBUaGlzIGZ1bmN0aW9uIGlzIG11dHVhbGx5CisgICAgLy8gZXhjbHVzaXZlIHdpdGggYWxsIHRoZSBvdGhlciBSZXBvcnQoKSBmdW5jdGlvbnMuCisgICAgLy8KKyAgICAvLyBUaGUgY29udHJhY3Qgb2YgUmVwb3J0SWdub3JlZCBpcyBzbGlnaHRseSBkaWZmZXJlbnQgdGhhbiB0aGUKKyAgICAvLyBvdGhlciBSZXBvcnQoKSBmdW5jdGlvbnMsIGluIHRoYXQgfGZpZWxkX3BhdGguYmFjaygpLmluZGV4fCBpcworICAgIC8vIGFsd2F5cyBlcXVhbCB0byAtMSwgZXZlbiBpZiB0aGUgbGFzdCBmaWVsZCBpcyByZXBlYXRlZC4gVGhpcyBpcworICAgIC8vIGJlY2F1c2Ugd2hpbGUgdGhlIG90aGVyIFJlcG9ydCgpIGZ1bmN0aW9ucyBpbmRpY2F0ZSB3aGVyZSBpbiBhCisgICAgLy8gcmVwZWF0ZWQgZmllbGQgdGhlIGFjdGlvbiAoQWRkaXRpb24sIERlbGV0aW9uLCBldGMuLi4pCisgICAgLy8gaGFwcGVuZWQsIHdoZW4gYSByZXBlYXRlZCBmaWVsZCBpcyAnaWdub3JlZCcsIHRoZSBkaWZmZXJlbmNlcgorICAgIC8vIHNpbXBseSBjYWxscyBSZXBvcnRJZ25vcmVkIG9uIHRoZSByZXBlYXRlZCBmaWVsZCBhcyBhIHdob2xlIGFuZAorICAgIC8vIG1vdmVzIG9uIHdpdGhvdXQgbG9va2luZyBhdCBpdHMgaW5kaXZpZHVhbCBlbGVtZW50cy4KKyAgICAvLworICAgIC8vIEZ1cnRoZXJtb3JlLCBSZXBvcnRJZ25vcmVkKCkgZG9lcyBub3QgaW5kaWNhdGUgd2hldGhlciB0aGUKKyAgICAvLyBmaWVsZHMgd2VyZSBpbiBmYWN0IGVxdWFsIG9yIG5vdCwgYXMgQ29tcGFyZSgpIGRvZXMgbm90IGluc3BlY3QKKyAgICAvLyB0aGVzZSBmaWVsZHMgYXQgYWxsLiBJdCBpcyB1cCB0byB0aGUgUmVwb3J0ZXIgdG8gZGVjaWRlIHdoZXRoZXIKKyAgICAvLyB0aGUgZmllbGRzIGFyZSBlcXVhbCBvciBub3QgKHBlcmhhcHMgd2l0aCBhIHNlY29uZCBjYWxsIHRvCisgICAgLy8gQ29tcGFyZSgpKSwgaWYgaXQgY2FyZXMuCisgICAgdmlydHVhbCB2b2lkIFJlcG9ydElnbm9yZWQoCisgICAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UxLAorICAgICAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlMiwKKyAgICAgICAgY29uc3QgdmVjdG9yPFNwZWNpZmljRmllbGQ+JiBmaWVsZF9wYXRoKSB7IH0KKworICAgIC8vIFJlcG9ydCB0aGF0IGFuIHVua293biBmaWVsZCBpcyBpZ25vcmVkLiAoc2VlIGNvbW1lbnQgYWJvdmUpLgorICAgIC8vIE5vdGUgdGhpcyBpcyBhIGRpZmZlcmVudCBmdW5jdGlvbiBzaW5jZSB0aGUgbGFzdCBTcGVjaWZpY0ZpZWxkIGluIGZpZWxkCisgICAgLy8gcGF0aCBoYXMgYSBudWxsIGZpZWxkLiAgVGhpcyBjb3VsZCBicmVhayBleGlzdGluZyBSZXBvcnRlci4KKyAgICB2aXJ0dWFsIHZvaWQgUmVwb3J0VW5rbm93bkZpZWxkSWdub3JlZCgKKyAgICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZTEsIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UyLAorICAgICAgICBjb25zdCB2ZWN0b3I8U3BlY2lmaWNGaWVsZD4mIGZpZWxkX3BhdGgpIHt9CisKKyAgIHByaXZhdGU6CisgICAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFJlcG9ydGVyKTsKKyAgfTsKKworICAvLyBNYXBLZXlDb21wYXJhdG9yIGlzIHVzZWQgdG8gZGV0ZXJtaW5lIGlmIHR3byBlbGVtZW50cyBoYXZlIHRoZSBzYW1lIGtleQorICAvLyB3aGVuIGNvbXBhcmluZyBlbGVtZW50cyBvZiBhIHJlcGVhdGVkIGZpZWxkIGFzIGEgbWFwLgorICBjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgTWFwS2V5Q29tcGFyYXRvciB7CisgICBwdWJsaWM6CisgICAgTWFwS2V5Q29tcGFyYXRvcigpOworICAgIHZpcnR1YWwgfk1hcEtleUNvbXBhcmF0b3IoKTsKKworICAgIHZpcnR1YWwgYm9vbCBJc01hdGNoKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UxLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UyLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZlY3RvcjxTcGVjaWZpY0ZpZWxkPiYgcGFyZW50X2ZpZWxkcykgY29uc3QgeworICAgICAgR09PR0xFX0NIRUNLKGZhbHNlKSA8PCAiSXNNYXRjaCgpIGlzIG5vdCBpbXBsZW1lbnRlZC4iOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgcHJpdmF0ZToKKyAgICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoTWFwS2V5Q29tcGFyYXRvcik7CisgIH07CisKKyAgLy8gQWJzdHJhY3QgYmFzZSBjbGFzcyBmcm9tIHdoaWNoIGFsbCBJZ25vcmVDcml0ZXJpYSBkZXJpdmUuCisgIC8vIEJ5IGFkZGluZyBJZ25vcmVDcml0ZXJpYSBtb3JlIGNvbXBsZXggaWdub3JlIGxvZ2ljIGNhbiBiZSBpbXBsZW1lbnRlZC4KKyAgLy8gSWdub3JlQ3JpdGVyaWEgYXJlIHJlZ2lzdGVkIHdpdGggQWRkSWdub3JlQ3JpdGVyaWEuIEZvciBlYWNoIGNvbXBhcmVkCisgIC8vIGZpZWxkIElzSWdub3JlZCBpcyBjYWxsZWQgb24gZWFjaCBhZGRlZCBJZ25vcmVDcml0ZXJpYSB1bnRpbCBvbmUgcmV0dXJucworICAvLyB0cnVlIG9yIGFsbCByZXR1cm4gZmFsc2UuCisgIC8vIElzSWdub3JlZCBpcyBjYWxsZWQgZm9yIGZpZWxkcyB3aGVyZSBhdCBsZWFzdCBvbmUgc2lkZSBoYXMgYSB2YWx1ZS4KKyAgY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIElnbm9yZUNyaXRlcmlhIHsKKyAgIHB1YmxpYzoKKyAgICBJZ25vcmVDcml0ZXJpYSgpOworICAgIHZpcnR1YWwgfklnbm9yZUNyaXRlcmlhKCk7CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgdGhlIGZpZWxkIHNob3VsZCBiZSBpZ25vcmVkLgorICAgIHZpcnR1YWwgYm9vbCBJc0lnbm9yZWQoCisgICAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UxLAorICAgICAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlMiwKKyAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgY29uc3QgdmVjdG9yPFNwZWNpZmljRmllbGQ+JiBwYXJlbnRfZmllbGRzKSA9IDA7CisKKyAgICAvLyBSZXR1cm5zIHRydWUgaWYgdGhlIHVua25vd24gZmllbGQgc2hvdWxkIGJlIGlnbm9yZWQuCisgICAgLy8gTm90ZTogVGhpcyB3aWxsIGJlIGNhbGxlZCBmb3IgdW5rbm93biBmaWVsZHMgYXMgd2VsbCBpbiB3aGljaCBjYXNlCisgICAgLy8gICAgICAgZmllbGQuZmllbGQgd2lsbCBiZSBudWxsLgorICAgIHZpcnR1YWwgYm9vbCBJc1Vua25vd25GaWVsZElnbm9yZWQoCisgICAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UxLCBjb25zdCBNZXNzYWdlJiBtZXNzYWdlMiwKKyAgICAgICAgY29uc3QgU3BlY2lmaWNGaWVsZCYgZmllbGQsCisgICAgICAgIGNvbnN0IHZlY3RvcjxTcGVjaWZpY0ZpZWxkPiYgcGFyZW50X2ZpZWxkcykgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgfTsKKworICAvLyBUbyBhZGQgYSBSZXBvcnRlciwgY29uc3RydWN0IGRlZmF1bHQgaGVyZSwgdGhlbiB1c2UgUmVwb3J0RGlmZmVyZW5jZXNUbyBvcgorICAvLyBSZXBvcnREaWZmZXJlbmNlc1RvU3RyaW5nLgorICBleHBsaWNpdCBNZXNzYWdlRGlmZmVyZW5jZXIoKTsKKworICB+TWVzc2FnZURpZmZlcmVuY2VyKCk7CisKKyAgZW51bSBNZXNzYWdlRmllbGRDb21wYXJpc29uIHsKKyAgICBFUVVBTCwgICAgICAgLy8gRmllbGRzIG11c3QgYmUgcHJlc2VudCBpbiBib3RoIG1lc3NhZ2VzCisgICAgICAgICAgICAgICAgIC8vIGZvciB0aGUgbWVzc2FnZXMgdG8gYmUgY29uc2lkZXJlZCB0aGUgc2FtZS4KKyAgICBFUVVJVkFMRU5ULCAgLy8gRmllbGRzIHdpdGggZGVmYXVsdCB2YWx1ZXMgYXJlIGNvbnNpZGVyZWQgc2V0CisgICAgICAgICAgICAgICAgIC8vIGZvciBjb21wYXJpc29uIHB1cnBvc2VzIGV2ZW4gaWYgbm90IGV4cGxpY2l0bHkKKyAgICAgICAgICAgICAgICAgLy8gc2V0IGluIHRoZSBtZXNzYWdlcyB0aGVtc2VsdmVzLiAgVW5rbm93biBmaWVsZHMKKyAgICAgICAgICAgICAgICAgLy8gYXJlIGlnbm9yZWQuCisgIH07CisKKyAgZW51bSBTY29wZSB7CisgICAgRlVMTCwgICAgLy8gQWxsIGZpZWxkcyBvZiBib3RoIG1lc3NhZ2VzIGFyZSBjb25zaWRlcmVkIGluIHRoZSBjb21wYXJpc29uLgorICAgIFBBUlRJQUwgIC8vIE9ubHkgZmllbGRzIHByZXNlbnQgaW4gdGhlIGZpcnN0IG1lc3NhZ2UgYXJlIGNvbnNpZGVyZWQ7IGZpZWxkcworICAgICAgICAgICAgIC8vIHNldCBvbmx5IGluIHRoZSBzZWNvbmQgbWVzc2FnZSB3aWxsIGJlIHNraXBwZWQgZHVyaW5nCisgICAgICAgICAgICAgLy8gY29tcGFyaXNvbi4KKyAgfTsKKworICAvLyBERVBSRUNBVEVELiBVc2UgRmllbGRDb21wYXJhdG9yOjpGbG9hdENvbXBhcmlzb24gaW5zdGVhZC4KKyAgZW51bSBGbG9hdENvbXBhcmlzb24geworICAgIEVYQUNULCAgICAgICAvLyBGbG9hdHMgYW5kIGRvdWJsZXMgYXJlIGNvbXBhcmVkIGV4YWN0bHkuCisgICAgQVBQUk9YSU1BVEUgIC8vIEZsb2F0cyBhbmQgZG91YmxlcyBhcmUgY29tcGFyZWQgdXNpbmcgdGhlCisgICAgICAgICAgICAgICAgIC8vIE1hdGhVdGlsOjpBbG1vc3RFcXVhbHMgbWV0aG9kLgorICB9OworCisgIGVudW0gUmVwZWF0ZWRGaWVsZENvbXBhcmlzb24geworICAgIEFTX0xJU1QsICAgICAvLyBSZXBlYXRlZCBmaWVsZHMgYXJlIGNvbXBhcmVkIGluIG9yZGVyLiAgRGlmZmVyaW5nIHZhbHVlcyBhdAorICAgICAgICAgICAgICAgICAvLyB0aGUgc2FtZSBpbmRleCBhcmUgcmVwb3J0ZWQgdXNpbmcgUmVwb3J0TW9kaWZpZWQoKS4gIElmIHRoZQorICAgICAgICAgICAgICAgICAvLyByZXBlYXRlZCBmaWVsZHMgaGF2ZSBkaWZmZXJlbnQgbnVtYmVycyBvZiBlbGVtZW50cywgdGhlCisgICAgICAgICAgICAgICAgIC8vIHVucGFpcmVkIGVsZW1lbnRzIGFyZSByZXBvcnRlZCB1c2luZyBSZXBvcnRBZGRlZCgpIG9yCisgICAgICAgICAgICAgICAgIC8vIFJlcG9ydERlbGV0ZWQoKS4KKyAgICBBU19TRVQsICAgICAgLy8gVHJlYXQgYWxsIHRoZSByZXBlYXRlZCBmaWVsZHMgYXMgc2V0cyBieSBkZWZhdWx0LgorICAgICAgICAgICAgICAgICAvLyBTZWUgVHJlYXRBc1NldCgpLCBhcyBiZWxvdy4KKyAgfTsKKworICAvLyBUaGUgZWxlbWVudHMgb2YgdGhlIGdpdmVuIHJlcGVhdGVkIGZpZWxkIHdpbGwgYmUgdHJlYXRlZCBhcyBhIHNldCBmb3IKKyAgLy8gZGlmZmluZyBwdXJwb3Nlcywgc28gZGlmZmVyZW50IG9yZGVyaW5ncyBvZiB0aGUgc2FtZSBlbGVtZW50cyB3aWxsIGJlCisgIC8vIGNvbnNpZGVyZWQgZXF1YWwuICBFbGVtZW50cyB3aGljaCBhcmUgcHJlc2VudCBvbiBib3RoIHNpZGVzIG9mIHRoZQorICAvLyBjb21wYXJpc29uIGJ1dCB3aGljaCBoYXZlIGNoYW5nZWQgcG9zaXRpb24gd2lsbCBiZSByZXBvcnRlZCB3aXRoCisgIC8vIFJlcG9ydE1vdmVkKCkuICBFbGVtZW50cyB3aGljaCBvbmx5IGV4aXN0IG9uIG9uZSBzaWRlIG9yIHRoZSBvdGhlciBhcmUKKyAgLy8gcmVwb3J0ZWQgd2l0aCBSZXBvcnRBZGRlZCgpIGFuZCBSZXBvcnREZWxldGVkKCkgcmVnYXJkbGVzcyBvZiB0aGVpcgorICAvLyBwb3NpdGlvbnMuICBSZXBvcnRNb2RpZmllZCgpIGlzIG5ldmVyIHVzZWQgZm9yIHRoaXMgcmVwZWF0ZWQgZmllbGQuICBJZgorICAvLyB0aGUgb25seSBkaWZmZXJlbmNlcyBiZXR3ZWVuIHRoZSBjb21wYXJlZCBtZXNzYWdlcyBpcyB0aGF0IHNvbWUgZmllbGRzCisgIC8vIGhhdmUgYmVlbiBtb3ZlZCwgdGhlbiB0aGUgY29tcGFyaXNvbiByZXR1cm5zIHRydWUuCisgIC8vCisgIC8vIElmIHRoZSBzY29wZSBvZiBjb21wYXJpc29uIGlzIHNldCB0byBQQVJUSUFMLCB0aGVuIGluIGFkZGl0aW9uIHRvIHdoYXQncworICAvLyBhYm92ZSwgZXh0cmEgdmFsdWVzIGFkZGVkIHRvIHJlcGVhdGVkIGZpZWxkcyBvZiB0aGUgc2Vjb25kIG1lc3NhZ2Ugd2lsbAorICAvLyBub3QgY2F1c2UgdGhlIGNvbXBhcmlzb24gdG8gZmFpbC4KKyAgLy8KKyAgLy8gTm90ZSB0aGF0IHNldCBjb21wYXJpc29uIGlzIGN1cnJlbnRseSBPKGsgKiBuXjIpICh3aGVyZSBuIGlzIHRoZSB0b3RhbAorICAvLyBudW1iZXIgb2YgZWxlbWVudHMsIGFuZCBrIGlzIHRoZSBhdmVyYWdlIHNpemUgb2YgZWFjaCBlbGVtZW50KS4gSW4gdGhlb3J5CisgIC8vIGl0IGNvdWxkIGJlIG1hZGUgTyhuICogaykgd2l0aCBhIG1vcmUgY29tcGxleCBoYXNoaW5nIGltcGxlbWVudGF0aW9uLiBGZWVsCisgIC8vIGZyZWUgdG8gY29udHJpYnV0ZSBvbmUgaWYgdGhlIGN1cnJlbnQgaW1wbGVtZW50YXRpb24gaXMgdG9vIHNsb3cgZm9yIHlvdS4KKyAgLy8gSWYgcGFydGlhbCBtYXRjaGluZyBpcyBhbHNvIGVuYWJsZWQsIHRoZSB0aW1lIGNvbXBsZXhpdHkgd2lsbCBiZSBPKGsgKiBuXjIKKyAgLy8gKyBuXjMpIGluIHdoaWNoIG5eMyBpcyB0aGUgdGltZSBjb21wbGV4aXR5IG9mIHRoZSBtYXhpbXVtIG1hdGNoaW5nCisgIC8vIGFsZ29yaXRobS4KKyAgLy8KKyAgLy8gUkVRVUlSRVM6ICBmaWVsZC0+aXNfcmVwZWF0ZWQoKSBhbmQgZmllbGQgbm90IHJlZ2lzdGVyZWQgd2l0aCBUcmVhdEFzTGlzdAorICB2b2lkIFRyZWF0QXNTZXQoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCk7CisKKyAgLy8gVGhlIGVsZW1lbnRzIG9mIHRoZSBnaXZlbiByZXBlYXRlZCBmaWVsZCB3aWxsIGJlIHRyZWF0ZWQgYXMgYSBsaXN0IGZvcgorICAvLyBkaWZmaW5nIHB1cnBvc2VzLCBzbyBkaWZmZXJlbnQgb3JkZXJpbmdzIG9mIHRoZSBzYW1lIGVsZW1lbnRzIHdpbGwgTk9UIGJlCisgIC8vIGNvbnNpZGVyZWQgZXF1YWwuCisgIC8vCisgIC8vIFJFUVVJUkVEOiBmaWVsZC0+aXNfcmVwZWF0ZWQoKSBhbmQgZmllbGQgbm90IHJlZ2lzdGVyZWQgd2l0aCBUcmVhdEFzU2V0CisgIHZvaWQgVHJlYXRBc0xpc3QoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCk7CisKKyAgLy8gVGhlIGVsZW1lbnRzIG9mIHRoZSBnaXZlbiByZXBlYXRlZCBmaWVsZCB3aWxsIGJlIHRyZWF0ZWQgYXMgYSBtYXAgZm9yCisgIC8vIGRpZmZpbmcgcHVycG9zZXMsIHdpdGggfGtleXwgYmVpbmcgdGhlIG1hcCBrZXkuICBUaHVzLCBlbGVtZW50cyB3aXRoIHRoZQorICAvLyBzYW1lIGtleSB3aWxsIGJlIGNvbXBhcmVkIGV2ZW4gaWYgdGhleSBkbyBub3QgYXBwZWFyIGF0IHRoZSBzYW1lIGluZGV4LgorICAvLyBEaWZmZXJlbmNlcyBhcmUgcmVwb3J0ZWQgc2ltaWxhcmx5IHRvIFRyZWF0QXNTZXQoKSwgZXhjZXB0IHRoYXQKKyAgLy8gUmVwb3J0TW9kaWZpZWQoKSBpcyB1c2VkIHRvIHJlcG9ydCBlbGVtZW50cyB3aXRoIHRoZSBzYW1lIGtleSBidXQKKyAgLy8gZGlmZmVyZW50IHZhbHVlcy4gIE5vdGUgdGhhdCBpZiBhbiBlbGVtZW50IGlzIGJvdGggbW92ZWQgYW5kIG1vZGlmaWVkLAorICAvLyBvbmx5IFJlcG9ydE1vZGlmaWVkKCkgd2lsbCBiZSBjYWxsZWQuICBBcyB3aXRoIFRyZWF0QXNTZXQsIGlmIHRoZSBvbmx5CisgIC8vIGRpZmZlcmVuY2VzIGJldHdlZW4gdGhlIGNvbXBhcmVkIG1lc3NhZ2VzIGlzIHRoYXQgc29tZSBmaWVsZHMgaGF2ZSBiZWVuCisgIC8vIG1vdmVkLCB0aGVuIHRoZSBjb21wYXJpc29uIHJldHVybnMgdHJ1ZS4gU2VlIFRyZWF0QXNTZXQgZm9yIG5vdGVzIG9uCisgIC8vIHBlcmZvcm1hbmNlLgorICAvLworICAvLyBSRVFVSVJFUzogIGZpZWxkLT5pc19yZXBlYXRlZCgpCisgIC8vIFJFUVVJUkVTOiAgZmllbGQtPmNwcF90eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX01FU1NBR0UKKyAgLy8gUkVRVUlSRVM6ICBrZXktPmNvbnRhaW5pbmdfdHlwZSgpID09IGZpZWxkLT5tZXNzYWdlX3R5cGUoKQorICB2b2lkIFRyZWF0QXNNYXAoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgY29uc3QgRmllbGREZXNjcmlwdG9yKiBrZXkpOworICAvLyBTYW1lIGFzIFRyZWF0QXNNYXAgZXhjZXB0IHRoYXQgdGhpcyBtZXRob2Qgd2lsbCB1c2UgbXVsdGlwbGUgZmllbGRzIGFzCisgIC8vIHRoZSBrZXkgaW4gY29tcGFyaXNvbi4gQWxsIHNwZWNpZmllZCBmaWVsZHMgaW4gJ2tleV9maWVsZHMnIHNob3VsZCBiZQorICAvLyBwcmVzZW50IGluIHRoZSBjb21wYXJlZCBlbGVtZW50cy4gVHdvIGVsZW1lbnRzIHdpbGwgYmUgdHJlYXRlZCBhcyBoYXZpbmcKKyAgLy8gdGhlIHNhbWUga2V5IGlmZiB0aGV5IGhhdmUgdGhlIHNhbWUgdmFsdWUgZm9yIGV2ZXJ5IHNwZWNpZmllZCBmaWVsZC4gVGhlcmUKKyAgLy8gYXJlIHR3byBzdGVwcyBpbiB0aGUgY29tcGFyaXNvbiBwcm9jZXNzLiBUaGUgZmlyc3Qgb25lIGlzIGtleSBtYXRjaGluZy4KKyAgLy8gRXZlcnkgZWxlbWVudCBmcm9tIG9uZSBtZXNzYWdlIHdpbGwgYmUgY29tcGFyZWQgdG8gZXZlcnkgZWxlbWVudCBmcm9tCisgIC8vIHRoZSBvdGhlciBtZXNzYWdlLiBPbmx5IGZpZWxkcyBpbiAna2V5X2ZpZWxkcycgYXJlIGNvbXBhcmVkIGluIHRoaXMgc3RlcAorICAvLyB0byBkZWNpZGUgaWYgdHdvIGVsZW1lbnRzIGhhdmUgdGhlIHNhbWUga2V5LiBUaGUgc2Vjb25kIHN0ZXAgaXMgdmFsdWUKKyAgLy8gY29tcGFyaXNvbi4gVGhvc2UgcGFpcnMgb2YgZWxlbWVudHMgd2l0aCB0aGUgc2FtZSBrZXkgKHdpdGggZXF1YWwgdmFsdWUKKyAgLy8gZm9yIGV2ZXJ5IGZpZWxkIGluICdrZXlfZmllbGRzJykgd2lsbCBiZSBjb21wYXJlZCBpbiB0aGlzIHN0ZXAuCisgIC8vIFRpbWUgY29tcGxleGl0eSBvZiB0aGUgZmlyc3Qgc3RlcCBpcyBPKHMgKiBtICogbiBeIDIpIHdoZXJlIHMgaXMgdGhlCisgIC8vIGF2ZXJhZ2Ugc2l6ZSBvZiB0aGUgZmllbGRzIHNwZWNpZmllZCBpbiAna2V5X2ZpZWxkcycsIG0gaXMgdGhlIG51bWJlciBvZgorICAvLyBmaWVsZHMgaW4gJ2tleV9maWVsZHMnIGFuZCBuIGlzIHRoZSBudW1iZXIgb2YgZWxlbWVudHMuIElmIHBhcnRpYWwKKyAgLy8gbWF0Y2hpbmcgaXMgZW5hYmxlZCwgYW4gZXh0cmEgTyhuXjMpIHdpbGwgYmUgaW5jdXJlZCBieSB0aGUgbWF4aW11bQorICAvLyBtYXRjaGluZyBhbGdvcml0aG0uIFRoZSBzZWNvbmQgc3RlcCBpcyBPKGsgKiBuKSB3aGVyZSBrIGlzIHRoZSBhdmVyYWdlCisgIC8vIHNpemUgb2YgZWFjaCBlbGVtZW50LgorICB2b2lkIFRyZWF0QXNNYXBXaXRoTXVsdGlwbGVGaWVsZHNBc0tleSgKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICBjb25zdCB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4mIGtleV9maWVsZHMpOworICAvLyBTYW1lIGFzIFRyZWF0QXNNYXBXaXRoTXVsdGlwbGVGaWVsZHNBc0tleSwgZXhjZXB0IHRoYXQgZWFjaCBvZiB0aGUgZmllbGQKKyAgLy8gZG8gbm90IG5lY2Vzc2FyaWx5IG5lZWQgdG8gYmUgYSBkaXJlY3Qgc3ViZmllbGQuIEVhY2ggZWxlbWVudCBpbgorICAvLyBrZXlfZmllbGRfcGF0aHMgaW5kaWNhdGUgYSBwYXRoIGZyb20gdGhlIG1lc3NhZ2UgYmVpbmcgY29tcGFyZWQsIGxpc3RpbmcKKyAgLy8gc3VjY2Vzc2l2ZSBzdWJmaWVsZCB0byByZWFjaCB0aGUga2V5IGZpZWxkLgorICAvLworICAvLyBSRVFVSVJFUzoKKyAgLy8gICBmb3Iga2V5X2ZpZWxkX3BhdGggaW4ga2V5X2ZpZWxkX3BhdGhzOgorICAvLyAgICAga2V5X2ZpZWxkX3BhdGhbMF0tPmNvbnRhaW5pbmdfdHlwZSgpID09IGZpZWxkLT5tZXNzYWdlX3R5cGUoKQorICAvLyAgICAgZm9yIGkgaW4gWzAsIGtleV9maWVsZF9wYXRoLnNpemUoKSAtIDEpOgorICAvLyAgICAgICBrZXlfZmllbGRfcGF0aFtpKzFdLT5jb250YWluaW5nX3R5cGUoKSA9PQorICAvLyAgICAgICAgICAga2V5X2ZpZWxkX3BhdGhbaV0tPm1lc3NhZ2VfdHlwZSgpCisgIC8vICAgICAgIGtleV9maWVsZF9wYXRoW2ldLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFCisgIC8vICAgICAgICFrZXlfZmllbGRfcGF0aFtpXS0+aXNfcmVwZWF0ZWQoKQorICB2b2lkIFRyZWF0QXNNYXBXaXRoTXVsdGlwbGVGaWVsZFBhdGhzQXNLZXkoCisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgY29uc3QgdmVjdG9yPHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiA+JiBrZXlfZmllbGRfcGF0aHMpOworCisgIC8vIFVzZXMgYSBjdXN0b20gTWFwS2V5Q29tcGFyYXRvciB0byBkZXRlcm1pbmUgaWYgdHdvIGVsZW1lbnRzIGhhdmUgdGhlIHNhbWUKKyAgLy8ga2V5IHdoZW4gY29tcGFyaW5nIGEgcmVwZWF0ZWQgZmllbGQgYXMgYSBtYXAuCisgIC8vIFRoZSBjYWxsZXIgaXMgcmVzcG9uc2libGUgdG8gZGVsZXRlIHRoZSBrZXlfY29tcGFyYXRvci4KKyAgLy8gVGhpcyBtZXRob2QgdmFyaWVzIGZyb20gVHJlYXRBc01hcFdpdGhNdWx0aXBsZUZpZWxkc0FzS2V5IG9ubHkgaW4gdGhlCisgIC8vIGZpcnN0IGtleSBtYXRjaGluZyBzdGVwLiBSYXRoZXIgdGhhbiBjb21wYXJpbmcgc29tZSBzcGVjaWZpZWQgZmllbGRzLCBpdAorICAvLyB3aWxsIGludm9rZSB0aGUgSXNNYXRjaCBtZXRob2Qgb2YgdGhlIGdpdmVuICdrZXlfY29tcGFyYXRvcicgdG8gZGVjaWRlIGlmCisgIC8vIHR3byBlbGVtZW50cyBoYXZlIHRoZSBzYW1lIGtleS4KKyAgdm9pZCBUcmVhdEFzTWFwVXNpbmdLZXlDb21wYXJhdG9yKAorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgIGNvbnN0IE1hcEtleUNvbXBhcmF0b3IqIGtleV9jb21wYXJhdG9yKTsKKworICAvLyBBZGQgYSBjdXN0b20gaWdub3JlIGNyaXRlcmlhIHRoYXQgaXMgZXZhbHVhdGVkIGluIGFkZGl0aW9uIHRvIHRoZQorICAvLyBpZ25vcmVkIGZpZWxkcyBhZGRlZCB3aXRoIElnbm9yZUZpZWxkLgorICAvLyBUYWtlcyBvd25lcnNoaXAgb2YgaWdub3JlX2NyaXRlcmlhLgorICB2b2lkIEFkZElnbm9yZUNyaXRlcmlhKElnbm9yZUNyaXRlcmlhKiBpZ25vcmVfY3JpdGVyaWEpOworCisgIC8vIEluZGljYXRlcyB0aGF0IGFueSBmaWVsZCB3aXRoIHRoZSBnaXZlbiBkZXNjcmlwdG9yIHNob3VsZCBiZQorICAvLyBpZ25vcmVkIGZvciB0aGUgcHVycG9zZXMgb2YgY29tcGFyaW5nIHR3byBtZXNzYWdlcy4gVGhpcyBhcHBsaWVzCisgIC8vIHRvIGZpZWxkcyBuZXN0ZWQgaW4gdGhlIG1lc3NhZ2Ugc3RydWN0dXJlIGFzIHdlbGwgYXMgdG9wIGxldmVsCisgIC8vIG9uZXMuIFdoZW4gdGhlIE1lc3NhZ2VEaWZmZXJlbmNlciBlbmNvdW50ZXJzIGFuIGlnbm9yZWQgZmllbGQsCisgIC8vIFJlcG9ydElnbm9yZWQgaXMgY2FsbGVkIG9uIHRoZSByZXBvcnRlciwgaWYgb25lIGlzIHNwZWNpZmllZC4KKyAgLy8KKyAgLy8gVGhlIG9ubHkgcGxhY2Ugd2hlcmUgdGhlIGZpZWxkJ3MgJ2lnbm9yZWQnIHN0YXR1cyBpcyBub3QgYXBwbGllZCBpcyB3aGVuCisgIC8vIGl0IGlzIGJlaW5nIHVzZWQgYXMgYSBrZXkgaW4gYSBmaWVsZCBwYXNzZWQgdG8gVHJlYXRBc01hcCBvciBpcyBvbmUgb2YKKyAgLy8gdGhlIGZpZWxkcyBwYXNzZWQgdG8gVHJlYXRBc01hcFdpdGhNdWx0aXBsZUZpZWxkc0FzS2V5LgorICAvLyBJbiB0aGlzIGNhc2UgaXQgaXMgY29tcGFyZWQgaW4ga2V5IG1hdGNoaW5nIGJ1dCBhZnRlciB0aGF0IGl0J3MgaWdub3JlZAorICAvLyBpbiB2YWx1ZSBjb21wYXJpc29uLgorICB2b2lkIElnbm9yZUZpZWxkKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpOworCisgIC8vIFNldHMgdGhlIGZpZWxkIGNvbXBhcmF0b3IgdXNlZCB0byBkZXRlcm1pbmUgZGlmZmVyZW5jZXMgYmV0d2VlbiBwcm90b2NvbAorICAvLyBidWZmZXIgZmllbGRzLiBCeSBkZWZhdWx0IGl0J3Mgc2V0IHRvIGEgRGVmYXVsdEZpZWxkQ29tcGFyYXRvciBpbnN0YW5jZS4KKyAgLy8gTWVzc2FnZURpZmZlcmVuY2VyIGRvZXNuJ3QgdGFrZSBvd25lcnNoaXAgb3ZlciB0aGUgcGFzc2VkIG9iamVjdC4KKyAgLy8gTm90ZSB0aGF0IHRoaXMgbWV0aG9kIG11c3QgYmUgY2FsbGVkIGJlZm9yZSBDb21wYXJlIGZvciB0aGUgY29tcGFyYXRvciB0bworICAvLyBiZSB1c2VkLgorICB2b2lkIHNldF9maWVsZF9jb21wYXJhdG9yKEZpZWxkQ29tcGFyYXRvciogY29tcGFyYXRvcik7CisKKyAgLy8gREVQUkVDQVRFRC4gUGFzcyBhIERlZmF1bHRGaWVsZENvbXBhcmF0b3IgaW5zdGFuY2UgaW5zdGVhZC4KKyAgLy8gU2V0cyB0aGUgZnJhY3Rpb24gYW5kIG1hcmdpbiBmb3IgdGhlIGZsb2F0IGNvbXBhcmlzb24gb2YgYSBnaXZlbiBmaWVsZC4KKyAgLy8gVXNlcyBNYXRoVXRpbDo6V2l0aGluRnJhY3Rpb25Pck1hcmdpbiB0byBjb21wYXJlIHRoZSB2YWx1ZXMuCisgIC8vIE5PVEU6IHRoaXMgbWV0aG9kIGRvZXMgbm90aGluZyBpZiBkaWZmZXJlbmNlcidzIGZpZWxkIGNvbXBhcmF0b3IgaGFzIGJlZW4KKyAgLy8gICAgICAgc2V0IHRvIGEgY3VzdG9tIG9iamVjdC4KKyAgLy8KKyAgLy8gUkVRVUlSRVM6IGZpZWxkLT5jcHBfdHlwZSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRE9VQkxFIG9yCisgIC8vICAgICAgICAgICBmaWVsZC0+Y3BwX3R5cGUgPT0gRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0ZMT0FUCisgIC8vIFJFUVVJUkVTOiBmbG9hdF9jb21wYXJpc29uXyA9PSBBUFBST1hJTUFURQorICB2b2lkIFNldEZyYWN0aW9uQW5kTWFyZ2luKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsIGRvdWJsZSBmcmFjdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb3VibGUgbWFyZ2luKTsKKworICAvLyBTZXRzIHRoZSB0eXBlIG9mIGNvbXBhcmlzb24gKGFzIGRlZmluZWQgaW4gdGhlIE1lc3NhZ2VGaWVsZENvbXBhcmlzb24KKyAgLy8gZW51bWVyYXRpb24gYWJvdmUpIHRoYXQgaXMgdXNlZCBieSB0aGlzIGRpZmZlcmVuY2VyIHdoZW4gZGV0ZXJtaW5pbmcgaG93CisgIC8vIHRvIGNvbXBhcmUgZmllbGRzIGluIG1lc3NhZ2VzLgorICB2b2lkIHNldF9tZXNzYWdlX2ZpZWxkX2NvbXBhcmlzb24oTWVzc2FnZUZpZWxkQ29tcGFyaXNvbiBjb21wYXJpc29uKTsKKworICAvLyBUZWxscyB0aGUgZGlmZmVyZW5jZXIgd2hldGhlciBvciBub3QgdG8gcmVwb3J0IG1hdGNoZXMuIFRoaXMgbWV0aG9kIG11c3QKKyAgLy8gYmUgY2FsbGVkIGJlZm9yZSBDb21wYXJlLiBUaGUgZGVmYXVsdCBmb3IgYSBuZXcgZGlmZmVyZW5jZXIgaXMgZmFsc2UuCisgIHZvaWQgc2V0X3JlcG9ydF9tYXRjaGVzKGJvb2wgcmVwb3J0X21hdGNoZXMpIHsKKyAgICByZXBvcnRfbWF0Y2hlc18gPSByZXBvcnRfbWF0Y2hlczsKKyAgfQorCisgIC8vIFNldHMgdGhlIHNjb3BlIG9mIHRoZSBjb21wYXJpc29uIChhcyBkZWZpbmVkIGluIHRoZSBTY29wZSBlbnVtZXJhdGlvbgorICAvLyBhYm92ZSkgdGhhdCBpcyB1c2VkIGJ5IHRoaXMgZGlmZmVyZW5jZXIgd2hlbiBkZXRlcm1pbmluZyB3aGljaCBmaWVsZHMgdG8KKyAgLy8gY29tcGFyZSBiZXR3ZWVuIHRoZSBtZXNzYWdlcy4KKyAgdm9pZCBzZXRfc2NvcGUoU2NvcGUgc2NvcGUpOworCisgIC8vIFJldHVybnMgdGhlIGN1cnJlbnQgc2NvcGUgdXNlZCBieSB0aGlzIGRpZmZlcmVuY2VyLgorICBTY29wZSBzY29wZSgpOworCisgIC8vIERFUFJFQ0FURUQuIFBhc3MgYSBEZWZhdWx0RmllbGRDb21wYXJhdG9yIGluc3RhbmNlIGluc3RlYWQuCisgIC8vIFNldHMgdGhlIHR5cGUgb2YgY29tcGFyaXNvbiAoYXMgZGVmaW5lZCBpbiB0aGUgRmxvYXRDb21wYXJpc29uIGVudW1lcmF0aW9uCisgIC8vIGFib3ZlKSB0aGF0IGlzIHVzZWQgYnkgdGhpcyBkaWZmZXJlbmNlciB3aGVuIGNvbXBhcmluZyBmbG9hdCAoYW5kIGRvdWJsZSkKKyAgLy8gZmllbGRzIGluIG1lc3NhZ2VzLgorICAvLyBOT1RFOiB0aGlzIG1ldGhvZCBkb2VzIG5vdGhpbmcgaWYgZGlmZmVyZW5jZXIncyBmaWVsZCBjb21wYXJhdG9yIGhhcyBiZWVuCisgIC8vICAgICAgIHNldCB0byBhIGN1c3RvbSBvYmplY3QuCisgIHZvaWQgc2V0X2Zsb2F0X2NvbXBhcmlzb24oRmxvYXRDb21wYXJpc29uIGNvbXBhcmlzb24pOworCisgIC8vIFNldHMgdGhlIHR5cGUgb2YgY29tcGFyaXNvbiBmb3IgcmVwZWF0ZWQgZmllbGQgKGFzIGRlZmluZWQgaW4gdGhlCisgIC8vIFJlcGVhdGVkRmllbGRDb21wYXJpc29uIGVudW1lcmF0aW9uIGFib3ZlKSB0aGF0IGlzIHVzZWQgYnkgdGhpcworICAvLyBkaWZmZXJlbmNlciB3aGVuIGNvbXBhcmUgcmVwZWF0ZWQgZmllbGRzIGluIG1lc3NhZ2VzLgorICB2b2lkIHNldF9yZXBlYXRlZF9maWVsZF9jb21wYXJpc29uKFJlcGVhdGVkRmllbGRDb21wYXJpc29uIGNvbXBhcmlzb24pOworCisgIC8vIENvbXBhcmVzIHRoZSB0d28gc3BlY2lmaWVkIG1lc3NhZ2VzLCByZXR1cm5pbmcgdHJ1ZSBpZiB0aGV5IGFyZSB0aGUgc2FtZSwKKyAgLy8gZmFsc2Ugb3RoZXJ3aXNlLiBJZiB0aGlzIG1ldGhvZCByZXR1cm5zIGZhbHNlLCBhbnkgY2hhbmdlcyBiZXR3ZWVuIHRoZQorICAvLyB0d28gbWVzc2FnZXMgd2lsbCBiZSByZXBvcnRlZCBpZiBhIFJlcG9ydGVyIHdhcyBzcGVjaWZpZWQgdmlhCisgIC8vIFJlcG9ydERpZmZlcmVuY2VzVG8gKHNlZSBhbHNvIFJlcG9ydERpZmZlcmVuY2VzVG9TdHJpbmcpLgorICAvLworICAvLyBUaGlzIG1ldGhvZCBSRVFVSVJFUyB0aGF0IHRoZSB0d28gbWVzc2FnZXMgaGF2ZSB0aGUgc2FtZQorICAvLyBEZXNjcmlwdG9yIChtZXNzYWdlMS5HZXREZXNjcmlwdG9yKCkgPT0gbWVzc2FnZTIuR2V0RGVzY3JpcHRvcigpKS4KKyAgYm9vbCBDb21wYXJlKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UxLCBjb25zdCBNZXNzYWdlJiBtZXNzYWdlMik7CisKKyAgLy8gU2FtZSBhcyBhYm92ZSwgZXhjZXB0IGNvbXBhcmluZyBvbmx5IHRoZSBsaXN0IG9mIGZpZWxkcyBzcGVjaWZpZWQgYnkgdGhlCisgIC8vIHR3byB2ZWN0b3JzIG9mIEZpZWxkRGVzY3JpcHRvcnMuCisgIGJvb2wgQ29tcGFyZVdpdGhGaWVsZHMoY29uc3QgTWVzc2FnZSYgbWVzc2FnZTEsIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UyLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiYgbWVzc2FnZTFfZmllbGRzLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiYgbWVzc2FnZTJfZmllbGRzKTsKKworICAvLyBBdXRvbWF0aWNhbGx5IGNyZWF0ZXMgYSByZXBvcnRlciB0aGF0IHdpbGwgb3V0cHV0IHRoZSBkaWZmZXJlbmNlcworICAvLyBmb3VuZCAoaWYgYW55KSB0byB0aGUgc3BlY2lmaWVkIG91dHB1dCBzdHJpbmcgcG9pbnRlci4gTm90ZSB0aGF0IHRoaXMKKyAgLy8gbWV0aG9kIG11c3QgYmUgY2FsbGVkIGJlZm9yZSBDb21wYXJlLgorICB2b2lkIFJlcG9ydERpZmZlcmVuY2VzVG9TdHJpbmcoc3RyaW5nKiBvdXRwdXQpOworCisgIC8vIFRlbGxzIHRoZSBNZXNzYWdlRGlmZmVyZW5jZXIgdG8gcmVwb3J0IGRpZmZlcmVuY2VzIHZpYSB0aGUgc3BlY2lmaWVkCisgIC8vIHJlcG9ydGVyLiBOb3RlIHRoYXQgdGhpcyBtZXRob2QgbXVzdCBiZSBjYWxsZWQgYmVmb3JlIENvbXBhcmUgZm9yCisgIC8vIHRoZSByZXBvcnRlciB0byBiZSB1c2VkLiBJdCBpcyB0aGUgcmVzcG9uc2liaWxpdHkgb2YgdGhlIGNhbGxlciB0byBkZWxldGUKKyAgLy8gdGhpcyBvYmplY3QuCisgIC8vIElmIHRoZSBwcm92aWRlZCBwb2ludGVyIGVxdWFscyBOVUxMLCB0aGUgTWVzc2FnZURpZmZlcmVuY2VyIHN0b3BzIHJlcG9ydGluZworICAvLyBkaWZmZXJlbmNlcyB0byBhbnkgcHJldmlvdXNseSBzZXQgcmVwb3J0ZXJzIG9yIG91dHB1dCBzdHJpbmdzLgorICB2b2lkIFJlcG9ydERpZmZlcmVuY2VzVG8oUmVwb3J0ZXIqIHJlcG9ydGVyKTsKKworICAvLyBBbiBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgTWVzc2FnZURpZmZlcmVuY2VyIFJlcG9ydGVyIHRoYXQgb3V0cHV0cworICAvLyBhbnkgZGlmZmVyZW5jZXMgZm91bmQgaW4gaHVtYW4tcmVhZGFibGUgZm9ybSB0byB0aGUgc3VwcGxpZWQKKyAgLy8gWmVyb0NvcHlPdXRwdXRTdHJlYW0gb3IgUHJpbnRlci4gSWYgYSBwcmludGVyIGlzIHVzZWQsIHRoZSBkZWxpbWl0ZXIKKyAgLy8gKm11c3QqIGJlICckJy4KKyAgY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFN0cmVhbVJlcG9ydGVyIDogcHVibGljIFJlcG9ydGVyIHsKKyAgIHB1YmxpYzoKKyAgICBleHBsaWNpdCBTdHJlYW1SZXBvcnRlcihpbzo6WmVyb0NvcHlPdXRwdXRTdHJlYW0qIG91dHB1dCk7CisgICAgZXhwbGljaXQgU3RyZWFtUmVwb3J0ZXIoaW86OlByaW50ZXIqIHByaW50ZXIpOyAgLy8gZGVsaW1pdGVyICckJworICAgIHZpcnR1YWwgflN0cmVhbVJlcG9ydGVyKCk7CisKKyAgICAvLyBXaGVuIHNldCB0byB0cnVlLCB0aGUgc3RyZWFtIHJlcG9ydGVyIHdpbGwgYWxzbyBvdXRwdXQgYWdncmVnYXRlcyBub2RlcworICAgIC8vIChpLmUuIG1lc3NhZ2VzIGFuZCBncm91cHMpIHdob3NlIHN1YmZpZWxkcyBoYXZlIGJlZW4gbW9kaWZpZWQuIFdoZW4KKyAgICAvLyBmYWxzZSwgd2lsbCBvbmx5IHJlcG9ydCB0aGUgaW5kaXZpZHVhbCBzdWJmaWVsZHMuIERlZmF1bHRzIHRvIGZhbHNlLgorICAgIHZvaWQgc2V0X3JlcG9ydF9tb2RpZmllZF9hZ2dyZWdhdGVzKGJvb2wgcmVwb3J0KSB7CisgICAgICByZXBvcnRfbW9kaWZpZWRfYWdncmVnYXRlc18gPSByZXBvcnQ7CisgICAgfQorCisgICAgLy8gVGhlIGZvbGxvd2luZyBhcmUgaW1wbGVtZW50YXRpb25zIG9mIHRoZSBtZXRob2RzIGRlc2NyaWJlZCBhYm92ZS4KKyAgICB2aXJ0dWFsIHZvaWQgUmVwb3J0QWRkZWQoY29uc3QgTWVzc2FnZSYgbWVzc2FnZTEsIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2ZWN0b3I8U3BlY2lmaWNGaWVsZD4mIGZpZWxkX3BhdGgpOworCisgICAgdmlydHVhbCB2b2lkIFJlcG9ydERlbGV0ZWQoY29uc3QgTWVzc2FnZSYgbWVzc2FnZTEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZTIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmVjdG9yPFNwZWNpZmljRmllbGQ+JiBmaWVsZF9wYXRoKTsKKworICAgIHZpcnR1YWwgdm9pZCBSZXBvcnRNb2RpZmllZChjb25zdCBNZXNzYWdlJiBtZXNzYWdlMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZTIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZlY3RvcjxTcGVjaWZpY0ZpZWxkPiYgZmllbGRfcGF0aCk7CisKKyAgICB2aXJ0dWFsIHZvaWQgUmVwb3J0TW92ZWQoY29uc3QgTWVzc2FnZSYgbWVzc2FnZTEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2ZWN0b3I8U3BlY2lmaWNGaWVsZD4mIGZpZWxkX3BhdGgpOworCisgICAgdmlydHVhbCB2b2lkIFJlcG9ydE1hdGNoZWQoY29uc3QgTWVzc2FnZSYgbWVzc2FnZTEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZTIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmVjdG9yPFNwZWNpZmljRmllbGQ+JiBmaWVsZF9wYXRoKTsKKworICAgIHZpcnR1YWwgdm9pZCBSZXBvcnRJZ25vcmVkKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZlY3RvcjxTcGVjaWZpY0ZpZWxkPiYgZmllbGRfcGF0aCk7CisKKyAgICB2aXJ0dWFsIHZvaWQgUmVwb3J0VW5rbm93bkZpZWxkSWdub3JlZCgKKyAgICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZTEsIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UyLAorICAgICAgICBjb25zdCB2ZWN0b3I8U3BlY2lmaWNGaWVsZD4mIGZpZWxkX3BhdGgpOworCisgICBwcm90ZWN0ZWQ6CisgICAgLy8gUHJpbnRzIHRoZSBzcGVjaWZpZWQgcGF0aCBvZiBmaWVsZHMgdG8gdGhlIGJ1ZmZlci4KKyAgICB2aXJ0dWFsIHZvaWQgUHJpbnRQYXRoKGNvbnN0IHZlY3RvcjxTcGVjaWZpY0ZpZWxkPiYgZmllbGRfcGF0aCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgbGVmdF9zaWRlKTsKKworICAgIC8vIFByaW50cyB0aGUgdmFsdWUgb2YgZmllbGRzIHRvIHRoZSBidWZmZXIuICBsZWZ0X3NpZGUgaXMgdHJ1ZSBpZiB0aGUKKyAgICAvLyBnaXZlbiBtZXNzYWdlIGlzIGZyb20gdGhlIGxlZnQgc2lkZSBvZiB0aGUgY29tcGFyaXNvbiwgZmFsc2UgaWYgaXQKKyAgICAvLyB3YXMgdGhlIHJpZ2h0LiAgVGhpcyBpcyByZWxldmFudCBvbmx5IHRvIGRlY2lkZSB3aGV0aGVyIHRvIGZvbGxvdworICAgIC8vIHVua25vd25fZmllbGRfaW5kZXgxIG9yIHVua25vd25fZmllbGRfaW5kZXgyIHdoZW4gYW4gdW5rbm93biBmaWVsZAorICAgIC8vIGlzIGVuY291bnRlcmVkIGluIGZpZWxkX3BhdGguCisgICAgdmlydHVhbCB2b2lkIFByaW50VmFsdWUoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2ZWN0b3I8U3BlY2lmaWNGaWVsZD4mIGZpZWxkX3BhdGgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBsZWZ0X3NpZGUpOworCisgICAgLy8gUHJpbnRzIHRoZSBzcGVjaWZpZWQgcGF0aCBvZiB1bmtub3duIGZpZWxkcyB0byB0aGUgYnVmZmVyLgorICAgIHZpcnR1YWwgdm9pZCBQcmludFVua25vd25GaWVsZFZhbHVlKGNvbnN0IFVua25vd25GaWVsZCogdW5rbm93bl9maWVsZCk7CisKKyAgICAvLyBKdXN0IHByaW50IGEgc3RyaW5nCisgICAgdm9pZCBQcmludChjb25zdCBzdHJpbmcmIHN0cik7CisKKyAgIHByaXZhdGU6CisgICAgaW86OlByaW50ZXIqIHByaW50ZXJfOworICAgIGJvb2wgZGVsZXRlX3ByaW50ZXJfOworICAgIGJvb2wgcmVwb3J0X21vZGlmaWVkX2FnZ3JlZ2F0ZXNfOworCisgICAgR09PR0xFX0RJU0FMTE9XX0VWSUxfQ09OU1RSVUNUT1JTKFN0cmVhbVJlcG9ydGVyKTsKKyAgfTsKKworIHByaXZhdGU6CisgIC8vIEEgTWFwS2V5Q29tcGFyYXRvciB0byBiZSB1c2VkIGluIFRyZWF0QXNNYXBVc2luZ0tleUNvbXBhcmF0b3IuCisgIC8vIEltcGxlbWVudGF0aW9uIG9mIHRoaXMgY2xhc3MgbmVlZHMgdG8gZG8gZmllbGQgdmFsdWUgY29tcGFyaXNvbiB3aGljaAorICAvLyByZWxpZXMgb24gc29tZSBwcml2YXRlIG1ldGhvZHMgb2YgTWVzc2FnZURpZmZlcmVuY2VyLiBUaGF0J3Mgd2h5IHRoaXMKKyAgLy8gY2xhc3MgaXMgZGVjbGFyZWQgYXMgYSBuZXN0ZWQgY2xhc3Mgb2YgTWVzc2FnZURpZmZlcmVuY2VyLgorICBjbGFzcyBNdWx0aXBsZUZpZWxkc01hcEtleUNvbXBhcmF0b3I7CisgIC8vIFJldHVybnMgdHJ1ZSBpZiBmaWVsZDEncyBudW1iZXIoKSBpcyBsZXNzIHRoYW4gZmllbGQyJ3MuCisgIHN0YXRpYyBib29sIEZpZWxkQmVmb3JlKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQxLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkMik7CisKKyAgLy8gQ29tYmluZSB0aGUgdHdvIGxpc3RzIG9mIGZpZWxkcyBpbnRvIHRoZSBjb21iaW5lZF9maWVsZHMgb3V0cHV0IHZlY3Rvci4KKyAgLy8gQWxsIGZpZWxkcyBwcmVzZW50IGluIGJvdGggbGlzdHMgd2lsbCBhbHdheXMgYmUgaW5jbHVkZWQgaW4gdGhlIGNvbWJpbmVkCisgIC8vIGxpc3QuICBGaWVsZHMgb25seSBwcmVzZW50IGluIG9uZSBvZiB0aGUgbGlzdHMgd2lsbCBvbmx5IGFwcGVhciBpbiB0aGUKKyAgLy8gY29tYmluZWQgbGlzdCBpZiB0aGUgY29ycmVzcG9uZGluZyBmaWVsZHNfc2NvcGUgb3B0aW9uIGlzIHNldCB0byBGVUxMLgorICB2b2lkIENvbWJpbmVGaWVsZHMoY29uc3QgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+JiBmaWVsZHMxLAorICAgICAgICAgICAgICAgICAgICAgU2NvcGUgZmllbGRzMV9zY29wZSwKKyAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiYgZmllbGRzMiwKKyAgICAgICAgICAgICAgICAgICAgIFNjb3BlIGZpZWxkczJfc2NvcGUsCisgICAgICAgICAgICAgICAgICAgICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4qIGNvbWJpbmVkX2ZpZWxkcyk7CisKKyAgLy8gSW50ZXJuYWwgdmVyc2lvbiBvZiB0aGUgQ29tcGFyZSBtZXRob2Qgd2hpY2ggcGVyZm9ybXMgdGhlIGFjdHVhbAorICAvLyBjb21wYXJpc29uLiBUaGUgcGFyZW50X2ZpZWxkcyB2ZWN0b3IgaXMgYSB2ZWN0b3IgY29udGFpbmluZyBmaWVsZAorICAvLyBkZXNjcmlwdG9ycyBvZiBhbGwgZmllbGRzIGFjY2Vzc2VkIHRvIGdldCB0byB0aGlzIGNvbXBhcmlzb24gb3BlcmF0aW9uCisgIC8vIChpLmUuIGlmIHRoZSBjdXJyZW50IG1lc3NhZ2UgaXMgYW4gZW1iZWRkZWQgbWVzc2FnZSwgdGhlIHBhcmVudF9maWVsZHMKKyAgLy8gdmVjdG9yIHdpbGwgY29udGFpbiB0aGUgZmllbGQgdGhhdCBoYXMgdGhpcyBlbWJlZGRlZCBtZXNzYWdlKS4KKyAgYm9vbCBDb21wYXJlKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UxLCBjb25zdCBNZXNzYWdlJiBtZXNzYWdlMiwKKyAgICAgICAgICAgICAgIHZlY3RvcjxTcGVjaWZpY0ZpZWxkPiogcGFyZW50X2ZpZWxkcyk7CisKKyAgLy8gQ29tcGFyZXMgYWxsIHRoZSB1bmtub3duIGZpZWxkcyBpbiB0d28gbWVzc2FnZXMuCisgIGJvb2wgQ29tcGFyZVVua25vd25GaWVsZHMoY29uc3QgTWVzc2FnZSYgbWVzc2FnZTEsIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OlVua25vd25GaWVsZFNldCYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZ29vZ2xlOjpwcm90b2J1Zjo6VW5rbm93bkZpZWxkU2V0JiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWN0b3I8U3BlY2lmaWNGaWVsZD4qIHBhcmVudF9maWVsZHMpOworCisgIC8vIENvbXBhcmVzIHRoZSBzcGVjaWZpZWQgbWVzc2FnZXMgZm9yIHRoZSByZXF1ZXN0ZWQgZmllbGQgbGlzdHMuIFRoZSBmaWVsZAorICAvLyBsaXN0cyBhcmUgbW9kaWZpZWQgZGVwZW5kaW5nIG9uIGNvbXBhcmlzb24gc2V0dGluZ3MsIGFuZCB0aGVuIHBhc3NlZCB0bworICAvLyBDb21wYXJlV2l0aEZpZWxkc0ludGVybmFsLgorICBib29sIENvbXBhcmVSZXF1ZXN0ZWRGaWVsZHNVc2luZ1NldHRpbmdzKAorICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZTEsIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UyLAorICAgICAgY29uc3QgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+JiBtZXNzYWdlMV9maWVsZHMsCisgICAgICBjb25zdCB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4mIG1lc3NhZ2UyX2ZpZWxkcywKKyAgICAgIHZlY3RvcjxTcGVjaWZpY0ZpZWxkPiogcGFyZW50X2ZpZWxkcyk7CisKKyAgLy8gQ29tcGFyZXMgdGhlIHNwZWNpZmllZCBtZXNzYWdlcyB3aXRoIHRoZSBzcGVjaWZpZWQgZmllbGQgbGlzdHMuCisgIGJvb2wgQ29tcGFyZVdpdGhGaWVsZHNJbnRlcm5hbCgKKyAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UxLCBjb25zdCBNZXNzYWdlJiBtZXNzYWdlMiwKKyAgICAgIGNvbnN0IHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiYgbWVzc2FnZTFfZmllbGRzLAorICAgICAgY29uc3QgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+JiBtZXNzYWdlMl9maWVsZHMsCisgICAgICB2ZWN0b3I8U3BlY2lmaWNGaWVsZD4qIHBhcmVudF9maWVsZHMpOworCisgIC8vIENvbXBhcmVzIHRoZSByZXBlYXRlZCBmaWVsZHMsIGFuZCByZXBvcnQgdGhlIGVycm9yLgorICBib29sIENvbXBhcmVSZXBlYXRlZEZpZWxkKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UxLCBjb25zdCBNZXNzYWdlJiBtZXNzYWdlMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlY3RvcjxTcGVjaWZpY0ZpZWxkPiogcGFyZW50X2ZpZWxkcyk7CisKKyAgLy8gU2hvcnRoYW5kIGZvciBDb21wYXJlRmllbGRWYWx1ZVVzaW5nUGFyZW50RmllbGRzIHdpdGggTlVMTCBwYXJlbnRfZmllbGRzLgorICBib29sIENvbXBhcmVGaWVsZFZhbHVlKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UxLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UyLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGluZGV4MSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXgyKTsKKworICAvLyBDb21wYXJlcyB0aGUgc3BlY2lmaWVkIGZpZWxkIG9uIHRoZSB0d28gbWVzc2FnZXMsIHJldHVybmluZworICAvLyB0cnVlIGlmIHRoZXkgYXJlIHRoZSBzYW1lLCBmYWxzZSBvdGhlcndpc2UuIEZvciByZXBlYXRlZCBmaWVsZHMsCisgIC8vIHRoaXMgbWV0aG9kIG9ubHkgY29tcGFyZXMgdGhlIHZhbHVlIGluIHRoZSBzcGVjaWZpZWQgaW5kZXguIFRoaXMgbWV0aG9kCisgIC8vIHVzZXMgQ29tcGFyZSBmdW5jdGlvbnMgdG8gcmVjdXJzZSBpbnRvIHN1Ym1lc3NhZ2VzLgorICAvLyBUaGUgcGFyZW50X2ZpZWxkcyB2ZWN0b3IgaXMgdXNlZCBpbiBjYWxscyB0byBhIFJlcG9ydGVyIGluc3RhbmNlIGNhbGxzLgorICAvLyBJdCBjYW4gYmUgTlVMTCwgaW4gd2hpY2ggY2FzZSB0aGUgTWVzc2FnZURpZmZlcmVuY2VyIHdpbGwgY3JlYXRlIG5ldworICAvLyBsaXN0IG9mIHBhcmVudCBtZXNzYWdlcyBpZiBpdCBuZWVkcyB0byByZWN1cnNpdmVseSBjb21wYXJlIHRoZSBnaXZlbiBmaWVsZC4KKyAgLy8gVG8gYXZvaWQgY29uZnVzaW5nIHVzZXJzIHlvdSBzaG91bGQgbm90IHNldCBpdCB0byBOVUxMIHVubGVzcyB5b3UgbW9kaWZpZWQKKyAgLy8gUmVwb3J0ZXIgdG8gaGFuZGxlIHRoZSBjaGFuZ2Ugb2YgcGFyZW50X2ZpZWxkcyBjb3JyZWN0bHkuCisgIGJvb2wgQ29tcGFyZUZpZWxkVmFsdWVVc2luZ1BhcmVudEZpZWxkcyhjb25zdCBNZXNzYWdlJiBtZXNzYWdlMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleDEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXgyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjdG9yPFNwZWNpZmljRmllbGQ+KiBwYXJlbnRfZmllbGRzKTsKKworICAvLyBDb21wYXJlcyB0aGUgc3BlY2lmaWVkIGZpZWxkIG9uIHRoZSB0d28gbWVzc2FnZXMsIHJldHVybmluZyBjb21wYXJpc29uCisgIC8vIHJlc3VsdCwgYXMgcmV0dXJuZWQgYnkgYXBwcm9wcmlhdGUgRmllbGRDb21wYXJhdG9yLgorICBGaWVsZENvbXBhcmF0b3I6OkNvbXBhcmlzb25SZXN1bHQgR2V0RmllbGRDb21wYXJpc29uUmVzdWx0KAorICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZTEsIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UyLAorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgaW50IGluZGV4MSwgaW50IGluZGV4MiwKKyAgICAgIGNvbnN0IEZpZWxkQ29udGV4dCogZmllbGRfY29udGV4dCk7CisKKyAgLy8gQ2hlY2sgaWYgdGhlIHR3byBlbGVtZW50cyBpbiB0aGUgcmVwZWF0ZWQgZmllbGQgYXJlIG1hdGNoIHRvIGVhY2ggb3RoZXIuCisgIC8vIGlmIHRoZSBrZXlfY29tcHJhdG9yIGlzIE5VTEwsIHRoaXMgZnVuY3Rpb24gcmV0dXJucyB0cnVlIHdoZW4gdGhlIHR3bworICAvLyBlbGVtZW50cyBhcmUgZXF1YWwuCisgIGJvb2wgSXNNYXRjaChjb25zdCBGaWVsZERlc2NyaXB0b3IqIHJlcGVhdGVkX2ZpZWxkLAorICAgICAgICAgICAgICAgY29uc3QgTWFwS2V5Q29tcGFyYXRvcioga2V5X2NvbXBhcmF0b3IsCisgICAgICAgICAgICAgICBjb25zdCBNZXNzYWdlKiBtZXNzYWdlMSwgY29uc3QgTWVzc2FnZSogbWVzc2FnZTIsCisgICAgICAgICAgICAgICBjb25zdCB2ZWN0b3I8U3BlY2lmaWNGaWVsZD4mIHBhcmVudF9maWVsZHMsCisgICAgICAgICAgICAgICBpbnQgaW5kZXgxLCBpbnQgaW5kZXgyKTsKKworICAvLyBSZXR1cm5zIHRydWUgd2hlbiB0aGlzIHJlcGVhdGVkIGZpZWxkIGhhcyBiZWVuIGNvbmZpZ3VyZWQgdG8gYmUgdHJlYXRlZAorICAvLyBhcyBhIHNldC4KKyAgYm9vbCBJc1RyZWF0ZWRBc1NldChjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKTsKKworICAvLyBSZXR1cm5zIHRydWUgd2hlbiB0aGlzIHJlcGVhdGVkIGZpZWxkIGlzIHRvIGJlIGNvbXBhcmVkIGFzIGEgc3Vic2V0LCBpZS4KKyAgLy8gaGFzIGJlZW4gY29uZmlndXJlZCB0byBiZSB0cmVhdGVkIGFzIGEgc2V0IG9yIG1hcCBhbmQgc2NvcGUgaXMgc2V0IHRvCisgIC8vIFBBUlRJQUwuCisgIGJvb2wgSXNUcmVhdGVkQXNTdWJzZXQoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCk7CisKKyAgLy8gUmV0dXJucyB0cnVlIGlmIHRoaXMgZmllbGQgaXMgdG8gYmUgaWdub3JlZCB3aGVuIHRoaXMKKyAgLy8gTWVzc2FnZURpZmZlcmVuY2VyIGNvbXBhcmVzIG1lc3NhZ2VzLgorICBib29sIElzSWdub3JlZCgKKyAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UxLAorICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZTIsCisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgY29uc3QgdmVjdG9yPFNwZWNpZmljRmllbGQ+JiBwYXJlbnRfZmllbGRzKTsKKworICAvLyBSZXR1cm5zIHRydWUgaWYgdGhpcyB1bmtub3duIGZpZWxkIGlzIHRvIGJlIGlnbm9yZWQgd2hlbiB0aGlzCisgIC8vIE1lc3NhZ2VEaWZmZXJlbmNlciBjb21wYXJlcyBtZXNzYWdlcy4KKyAgYm9vbCBJc1Vua25vd25GaWVsZElnbm9yZWQoY29uc3QgTWVzc2FnZSYgbWVzc2FnZTEsIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBTcGVjaWZpY0ZpZWxkJiBmaWVsZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmVjdG9yPFNwZWNpZmljRmllbGQ+JiBwYXJlbnRfZmllbGRzKTsKKworICAvLyBSZXR1cm5zIE1hcEtleUNvbXBhcmF0b3IqIHdoZW4gdGhpcyBmaWVsZCBoYXMgYmVlbiBjb25maWd1cmVkIHRvCisgIC8vIGJlIHRyZWF0ZWQgYXMgYSBtYXAuICBJZiBub3QsIHJldHVybnMgTlVMTC4KKyAgY29uc3QgTWFwS2V5Q29tcGFyYXRvciogR2V0TWFwS2V5Q29tcGFyYXRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkKTsKKworICAvLyBBdHRlbXB0cyB0byBtYXRjaCBpbmRpY2VzIG9mIGEgcmVwZWF0ZWQgZmllbGQsIHNvIHRoYXQgdGhlIGNvbnRhaW5lZCB2YWx1ZXMKKyAgLy8gbWF0Y2guIENsZWFycyBvdXRwdXQgdmVjdG9ycyBhbmQgc2V0cyB0aGVpciB2YWx1ZXMgdG8gaW5kaWNlcyBvZiBwYWlyZWQKKyAgLy8gbWVzc2FnZXMsIGllLiBpZiBtZXNzYWdlMVswXSBtYXRjaGVzIG1lc3NhZ2UyWzFdLCB0aGVuIG1hdGNoX2xpc3QxWzBdID09IDEKKyAgLy8gYW5kIG1hdGNoX2xpc3QyWzFdID09IDAuIFRoZSB1bm1hdGNoZWQgaW5kaWNlcyBhcmUgaW5kaWNhdGVkIGJ5IC0xLgorICAvLyBUaGlzIG1ldGhvZCByZXR1cm5zIGZhbHNlIGlmIHRoZSBtYXRjaCBmYWlsZWQuIEhvd2V2ZXIsIGl0IGRvZXNuJ3QgbWVhbgorICAvLyB0aGF0IHRoZSBjb21wYXJpc29uIHN1Y2NlZWRzIHdoZW4gdGhpcyBtZXRob2QgcmV0dXJucyB0cnVlICh5b3UgbmVlZCB0bworICAvLyBkb3VibGUtY2hlY2sgaW4gdGhpcyBjYXNlKS4KKyAgYm9vbCBNYXRjaFJlcGVhdGVkRmllbGRJbmRpY2VzKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZTIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHJlcGVhdGVkX2ZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmVjdG9yPFNwZWNpZmljRmllbGQ+JiBwYXJlbnRfZmllbGRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjdG9yPGludD4qIG1hdGNoX2xpc3QxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjdG9yPGludD4qIG1hdGNoX2xpc3QyKTsKKworICAvLyBJZiAiYW55IiBpcyBvZiB0eXBlIGdvb2dsZS5wcm90b2J1Zi5BbnksIGV4dHJhY3QgaXRzIHBheWxvYWQgdXNpbmcKKyAgLy8gRHluYW1pY01lc3NhZ2VGYWN0b3J5IGFuZCBzdG9yZSBpbiAiZGF0YSIuCisgIGJvb2wgVW5wYWNrQW55KGNvbnN0IE1lc3NhZ2UmIGFueSwgZ29vZ2xlOjpwcm90b2J1Zjo6c2NvcGVkX3B0cjxNZXNzYWdlPiogZGF0YSk7CisKKyAgLy8gQ2hlY2tzIGlmIGluZGV4IGlzIGVxdWFsIHRvIG5ld19pbmRleCBpbiBhbGwgdGhlIHNwZWNpZmljIGZpZWxkcy4KKyAgc3RhdGljIGJvb2wgQ2hlY2tQYXRoQ2hhbmdlZChjb25zdCB2ZWN0b3I8U3BlY2lmaWNGaWVsZD4mIHBhcmVudF9maWVsZHMpOworCisgIC8vIERlZmluZXMgYSBtYXAgYmV0d2VlbiBmaWVsZCBkZXNjcmlwdG9ycyBhbmQgdGhlaXIgTWFwS2V5Q29tcGFyYXRvcnMuCisgIC8vIFVzZWQgZm9yIHJlcGVhdGVkIGZpZWxkcyB3aGVuIHRoZXkgYXJlIGNvbmZpZ3VyZWQgYXMgVHJlYXRBc01hcC4KKyAgdHlwZWRlZiBtYXA8Y29uc3QgRmllbGREZXNjcmlwdG9yKiwKKyAgICAgICAgICAgICAgY29uc3QgTWFwS2V5Q29tcGFyYXRvcio+IEZpZWxkS2V5Q29tcGFyYXRvck1hcDsKKworICAvLyBEZWZpbmVzIGEgc2V0IHRvIHN0b3JlIGZpZWxkIGRlc2NyaXB0b3JzLiAgVXNlZCBmb3IgcmVwZWF0ZWQgZmllbGRzIHdoZW4KKyAgLy8gdGhleSBhcmUgY29uZmlndXJlZCBhcyBUcmVhdEFzU2V0LgorICB0eXBlZGVmIHNldDxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBGaWVsZFNldDsKKworICBSZXBvcnRlciogcmVwb3J0ZXJfOworICBEZWZhdWx0RmllbGRDb21wYXJhdG9yIGRlZmF1bHRfZmllbGRfY29tcGFyYXRvcl87CisgIEZpZWxkQ29tcGFyYXRvciogZmllbGRfY29tcGFyYXRvcl87CisgIE1lc3NhZ2VGaWVsZENvbXBhcmlzb24gbWVzc2FnZV9maWVsZF9jb21wYXJpc29uXzsKKyAgU2NvcGUgc2NvcGVfOworICBSZXBlYXRlZEZpZWxkQ29tcGFyaXNvbiByZXBlYXRlZF9maWVsZF9jb21wYXJpc29uXzsKKworICBGaWVsZFNldCBzZXRfZmllbGRzXzsKKyAgRmllbGRTZXQgbGlzdF9maWVsZHNfOworICAvLyBLZWVwcyB0cmFjayBvZiBNYXBLZXlDb21wYXJhdG9ycyB0aGF0IGFyZSBjcmVhdGVkIHdpdGhpbgorICAvLyBNZXNzYWdlRGlmZmVyZW5jZXIuIFRoZXNlIE1hcEtleUNvbXBhcmF0b3JzIHNob3VsZCBiZSBkZWxldGVkCisgIC8vIGJlZm9yZSBNZXNzYWdlRGlmZmVyZW5jZXIgaXMgZGVzdHJveWVkLgorICAvLyBXaGVuIFRyZWF0QXNNYXAgb3IgVHJlYXRBc01hcFdpdGhNdWx0aXBsZUZpZWxkc0FzS2V5IGlzIGNhbGxlZCwgd2UgZG9uJ3QKKyAgLy8gc3RvcmUgdGhlIHN1cHBsaWVkIEZpZWxkRGVzY3JpcHRvcnMgZGlyZWN0bHkuIEluc3RlYWQsIGEgbmV3CisgIC8vIE1hcEtleUNvbXBhcmF0b3IgaXMgY3JlYXRlZCBmb3IgY29tcGFyaXNvbiBwdXJwb3NlLgorICB2ZWN0b3I8TWFwS2V5Q29tcGFyYXRvcio+IG93bmVkX2tleV9jb21wYXJhdG9yc187CisgIEZpZWxkS2V5Q29tcGFyYXRvck1hcCBtYXBfZmllbGRfa2V5X2NvbXBhcmF0b3JfOworICB2ZWN0b3I8SWdub3JlQ3JpdGVyaWEqPiBpZ25vcmVfY3JpdGVyaWFfOworCisgIEZpZWxkU2V0IGlnbm9yZWRfZmllbGRzXzsKKworICBib29sIGNvbXBhcmVfdW5rbm93bl9maWVsZHNfOworICBib29sIHJlcG9ydF9tYXRjaGVzXzsKKworICBzdHJpbmcqIG91dHB1dF9zdHJpbmdfOworCisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8RHluYW1pY01lc3NhZ2VGYWN0b3J5PiBkeW5hbWljX21lc3NhZ2VfZmFjdG9yeV87CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhNZXNzYWdlRGlmZmVyZW5jZXIpOworfTsKKworLy8gVGhpcyBjbGFzcyBwcm92aWRlcyBleHRyYSBpbmZvcm1hdGlvbiB0byB0aGUgRmllbGRDb21wYXJhdG9yOjpDb21wYXJlCisvLyBmdW5jdGlvbi4KK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBGaWVsZENvbnRleHQgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgRmllbGRDb250ZXh0KAorICAgICAgdmVjdG9yPE1lc3NhZ2VEaWZmZXJlbmNlcjo6U3BlY2lmaWNGaWVsZD4qIHBhcmVudF9maWVsZHMpCisgICAgICA6IHBhcmVudF9maWVsZHNfKHBhcmVudF9maWVsZHMpIHt9CisKKyAgdmVjdG9yPE1lc3NhZ2VEaWZmZXJlbmNlcjo6U3BlY2lmaWNGaWVsZD4qIHBhcmVudF9maWVsZHMoKSBjb25zdCB7CisgICAgcmV0dXJuIHBhcmVudF9maWVsZHNfOworICB9CisKKyBwcml2YXRlOgorICB2ZWN0b3I8TWVzc2FnZURpZmZlcmVuY2VyOjpTcGVjaWZpY0ZpZWxkPiogcGFyZW50X2ZpZWxkc187Cit9OworCit9Cit9CisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX1VUSUxfTUVTU0FHRV9ESUZGRVJFTkNFUl9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9tZXNzYWdlX2RpZmZlcmVuY2VyX3VuaXR0ZXN0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL21lc3NhZ2VfZGlmZmVyZW5jZXJfdW5pdHRlc3QuY2MKbmV3IGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMDAwMDAwMC4uYTg2N2M4OAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC9tZXNzYWdlX2RpZmZlcmVuY2VyX3VuaXR0ZXN0LmNjCkBAIC0wLDAgKzEsMzE1MSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoganNjaG9yckBnb29nbGUuY29tIChKb3NlcGggU2Nob3JyKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisvLworLy8gVE9ETyhrc3Jva2EpOiBNb3ZlIHNvbWUgb2YgdGhlc2UgdGVzdHMgdG8gZmllbGRfY29tcGFyYXRvcl90ZXN0LmNjLgorCisjaW5jbHVkZSA8YWxnb3JpdGhtPgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDx2ZWN0b3I+CisKKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2ZpZWxkX2NvbXBhcmF0b3IuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC9tZXNzYWdlX2RpZmZlcmVuY2VyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3V0aWwvbWVzc2FnZV9kaWZmZXJlbmNlcl91bml0dGVzdC5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXh0X2Zvcm1hdC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX2ltcGwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2FueV90ZXN0LnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21hcF91bml0dGVzdC5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tYXBfdGVzdF91dGlsLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RfdXRpbC5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2xvZ2dpbmcuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0Lmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCituYW1lc3BhY2UgeworCisKK2NvbnN0IEZpZWxkRGVzY3JpcHRvciogR2V0RmllbGREZXNjcmlwdG9yKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsIGNvbnN0IHN0cmluZyYgZmllbGRfbmFtZSkgeworICB2ZWN0b3I8c3RyaW5nPiBmaWVsZF9wYXRoID0KKyAgICAgIFNwbGl0KGZpZWxkX25hbWUsICIuIiwgdHJ1ZSk7CisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBtZXNzYWdlLkdldERlc2NyaXB0b3IoKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9IE5VTEw7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRfcGF0aC5zaXplKCk7IGkrKykgeworICAgIGZpZWxkID0gZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKGZpZWxkX3BhdGhbaV0pOworICAgIGRlc2NyaXB0b3IgPSBmaWVsZC0+bWVzc2FnZV90eXBlKCk7CisgIH0KKyAgcmV0dXJuIGZpZWxkOworfQorCit2b2lkIEV4cGVjdEVxdWFsc1dpdGhEaWZmZXJlbmNlcih1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXIqIGRpZmZlcmVuY2VyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZSYgbXNnMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2UmIG1zZzIpIHsKKyAgZGlmZmVyZW5jZXItPnNldF9zY29wZSh1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXI6OkZVTEwpOworICBFWFBFQ1RfVFJVRShkaWZmZXJlbmNlci0+Q29tcGFyZShtc2cxLCBtc2cyKSk7CisKKyAgZGlmZmVyZW5jZXItPnNldF9zY29wZSh1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXI6OlBBUlRJQUwpOworICBFWFBFQ1RfVFJVRShkaWZmZXJlbmNlci0+Q29tcGFyZShtc2cxLCBtc2cyKSk7Cit9CisKK1RFU1QoTWVzc2FnZURpZmZlcmVuY2VyVGVzdCwgQmFzaWNFcXVhbGl0eVRlc3QpIHsKKyAgLy8gQ3JlYXRlIHRoZSB0ZXN0aW5nIHByb3RvcworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1zZzE7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbXNnMjsKKworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZtc2cxKTsKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbXNnMik7CisKKyAgLy8gQ29tcGFyZQorICBFWFBFQ1RfVFJVRSh1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXI6OkVxdWFscyhtc2cxLCBtc2cyKSk7Cit9CisKK1RFU1QoTWVzc2FnZURpZmZlcmVuY2VyVGVzdCwgQmFzaWNJbmVxdWFsaXR5VGVzdCkgeworICAvLyBDcmVhdGUgdGhlIHRlc3RpbmcgcHJvdG9zCisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbXNnMTsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtc2cyOworCisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1zZzEpOworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZtc2cyKTsKKworICBtc2cxLnNldF9vcHRpb25hbF9pbnQzMigtMSk7CisKKyAgLy8gQ29tcGFyZQorICBFWFBFQ1RfRkFMU0UodXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyOjpFcXVhbHMobXNnMSwgbXNnMikpOworfQorCitURVNUKE1lc3NhZ2VEaWZmZXJlbmNlclRlc3QsIFJlcGVhdGVkRmllbGRJbmVxdWFsaXR5VGVzdCkgeworICAvLyBDcmVhdGUgdGhlIHRlc3RpbmcgcHJvdG9zCisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbXNnMTsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtc2cyOworCisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1zZzEpOworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZtc2cyKTsKKworICBtc2cxLmFkZF9yZXBlYXRlZF9pbnQzMigtMSk7CisKKyAgLy8gQ29tcGFyZQorICBFWFBFQ1RfRkFMU0UodXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyOjpFcXVhbHMobXNnMSwgbXNnMikpOworfQorCitURVNUKE1lc3NhZ2VEaWZmZXJlbmNlclRlc3QsIE1hcEZpZWxkRXF1YWxpdHlUZXN0KSB7CisgIC8vIENyZWF0ZSB0aGUgdGVzdGluZyBwcm90b3MKKyAgdW5pdHRlc3Q6OlRlc3RNYXAgbXNnMTsKKyAgdW5pdHRlc3Q6OlRlc3RNYXAgbXNnMjsKKworICBNYXBSZWZsZWN0aW9uVGVzdGVyIHRlc3Rlcih1bml0dGVzdDo6VGVzdE1hcDo6ZGVzY3JpcHRvcigpKTsKKyAgdGVzdGVyLlNldE1hcEZpZWxkc1ZpYVJlZmxlY3Rpb24oJm1zZzEpOworICB0ZXN0ZXIuU2V0TWFwRmllbGRzVmlhUmVmbGVjdGlvbigmbXNnMik7CisgIHRlc3Rlci5Td2FwTWFwc1ZpYVJlZmxlY3Rpb24oJm1zZzEpOworCisgIC8vIENvbXBhcmUKKyAgRVhQRUNUX1RSVUUodXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyOjpFcXVhbHMobXNnMSwgbXNnMikpOworfQorCitURVNUKE1lc3NhZ2VEaWZmZXJlbmNlclRlc3QsIEJhc2ljUGFydGlhbEVxdWFsaXR5VGVzdCkgeworICAvLyBDcmVhdGUgdGhlIHRlc3RpbmcgcHJvdG9zCisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbXNnMTsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtc2cyOworCisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1zZzEpOworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZtc2cyKTsKKworICAvLyBDb21wYXJlCisgIHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlciBkaWZmZXJlbmNlcjsKKyAgZGlmZmVyZW5jZXIuc2V0X3Njb3BlKHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlcjo6UEFSVElBTCk7CisgIEVYUEVDVF9UUlVFKGRpZmZlcmVuY2VyLkNvbXBhcmUobXNnMSwgbXNnMikpOworfQorCitURVNUKE1lc3NhZ2VEaWZmZXJlbmNlclRlc3QsIFBhcnRpYWxFcXVhbGl0eVRlc3RFeHRyYUZpZWxkKSB7CisgIC8vIENyZWF0ZSB0aGUgdGVzdGluZyBwcm90b3MKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtc2cxOworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1zZzI7CisKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbXNnMSk7CisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1zZzIpOworCisgIG1zZzEuY2xlYXJfb3B0aW9uYWxfaW50MzIoKTsKKworICAvLyBDb21wYXJlCisgIHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlciBkaWZmZXJlbmNlcjsKKyAgZGlmZmVyZW5jZXIuc2V0X3Njb3BlKHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlcjo6UEFSVElBTCk7CisgIEVYUEVDVF9UUlVFKGRpZmZlcmVuY2VyLkNvbXBhcmUobXNnMSwgbXNnMikpOworfQorCitURVNUKE1lc3NhZ2VEaWZmZXJlbmNlclRlc3QsIFBhcnRpYWxFcXVhbGl0eVRlc3RTa2lwUmVxdWlyZWRGaWVsZCkgeworICAvLyBDcmVhdGUgdGhlIHRlc3RpbmcgcHJvdG9zCisgIHVuaXR0ZXN0OjpUZXN0UmVxdWlyZWQgbXNnMTsKKyAgdW5pdHRlc3Q6OlRlc3RSZXF1aXJlZCBtc2cyOworCisgIG1zZzEuc2V0X2EoNDAxKTsKKyAgbXNnMi5zZXRfYSg0MDEpOworICBtc2cyLnNldF9iKDQwMik7CisKKyAgLy8gQ29tcGFyZQorICB1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXIgZGlmZmVyZW5jZXI7CisgIGRpZmZlcmVuY2VyLnNldF9zY29wZSh1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXI6OlBBUlRJQUwpOworICBFWFBFQ1RfVFJVRShkaWZmZXJlbmNlci5Db21wYXJlKG1zZzEsIG1zZzIpKTsKK30KKworVEVTVChNZXNzYWdlRGlmZmVyZW5jZXJUZXN0LCBCYXNpY1BhcnRpYWxJbmVxdWFsaXR5VGVzdCkgeworICAvLyBDcmVhdGUgdGhlIHRlc3RpbmcgcHJvdG9zCisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbXNnMTsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtc2cyOworCisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1zZzEpOworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZtc2cyKTsKKworICBtc2cxLnNldF9vcHRpb25hbF9pbnQzMigtMSk7CisKKyAgLy8gQ29tcGFyZQorICB1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXIgZGlmZmVyZW5jZXI7CisgIGRpZmZlcmVuY2VyLnNldF9zY29wZSh1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXI6OlBBUlRJQUwpOworICBFWFBFQ1RfRkFMU0UoZGlmZmVyZW5jZXIuQ29tcGFyZShtc2cxLCBtc2cyKSk7Cit9CisKK1RFU1QoTWVzc2FnZURpZmZlcmVuY2VyVGVzdCwgUGFydGlhbEluZXF1YWxpdHlNaXNzaW5nRmllbGRUZXN0KSB7CisgIC8vIENyZWF0ZSB0aGUgdGVzdGluZyBwcm90b3MKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtc2cxOworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1zZzI7CisKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbXNnMSk7CisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1zZzIpOworCisgIG1zZzIuY2xlYXJfb3B0aW9uYWxfaW50MzIoKTsKKworICAvLyBDb21wYXJlCisgIHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlciBkaWZmZXJlbmNlcjsKKyAgZGlmZmVyZW5jZXIuc2V0X3Njb3BlKHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlcjo6UEFSVElBTCk7CisgIEVYUEVDVF9GQUxTRShkaWZmZXJlbmNlci5Db21wYXJlKG1zZzEsIG1zZzIpKTsKK30KKworVEVTVChNZXNzYWdlRGlmZmVyZW5jZXJUZXN0LCBSZXBlYXRlZEZpZWxkUGFydGlhbEluZXF1YWxpdHlUZXN0KSB7CisgIC8vIENyZWF0ZSB0aGUgdGVzdGluZyBwcm90b3MKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtc2cxOworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1zZzI7CisKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbXNnMSk7CisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1zZzIpOworCisgIG1zZzEuYWRkX3JlcGVhdGVkX2ludDMyKC0xKTsKKworICAvLyBDb21wYXJlCisgIHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlciBkaWZmZXJlbmNlcjsKKyAgZGlmZmVyZW5jZXIuc2V0X3Njb3BlKHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlcjo6UEFSVElBTCk7CisgIEVYUEVDVF9GQUxTRShkaWZmZXJlbmNlci5Db21wYXJlKG1zZzEsIG1zZzIpKTsKK30KKworVEVTVChNZXNzYWdlRGlmZmVyZW5jZXJUZXN0LCBCYXNpY0VxdWl2YWxlbmN5VGVzdCkgeworICAvLyBDcmVhdGUgdGhlIHRlc3RpbmcgcHJvdG9zCisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbXNnMTsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtc2cyOworCisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1zZzEpOworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZtc2cyKTsKKworICAvLyBDb21wYXJlCisgIEVYUEVDVF9UUlVFKHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlcjo6RXF1aXZhbGVudChtc2cxLCBtc2cyKSk7Cit9CisKK1RFU1QoTWVzc2FnZURpZmZlcmVuY2VyVGVzdCwgRXF1aXZhbGVuY3lOb3RFcXVhbFRlc3QpIHsKKyAgLy8gQ3JlYXRlIHRoZSB0ZXN0aW5nIHByb3RvcworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1zZzE7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbXNnMjsKKworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZtc2cxKTsKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbXNnMik7CisKKyAgbXNnMS5jbGVhcl9vcHRpb25hbF9pbnQzMigpOworICBtc2cyLnNldF9vcHRpb25hbF9pbnQzMigwKTsKKworICAvLyBDb21wYXJlCisgIEVYUEVDVF9GQUxTRSh1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXI6OkVxdWFscyhtc2cxLCBtc2cyKSk7CisgIEVYUEVDVF9UUlVFKHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlcjo6RXF1aXZhbGVudChtc2cxLCBtc2cyKSk7Cit9CisKK1RFU1QoTWVzc2FnZURpZmZlcmVuY2VyVGVzdCwgQmFzaWNJbmVxdWl2YWxlbmN5VGVzdCkgeworICAvLyBDcmVhdGUgdGhlIHRlc3RpbmcgcHJvdG9zCisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbXNnMTsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtc2cyOworCisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1zZzEpOworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZtc2cyKTsKKworICBtc2cxLnNldF9vcHRpb25hbF9pbnQzMigtMSk7CisKKyAgLy8gQ29tcGFyZQorICBFWFBFQ1RfRkFMU0UodXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyOjpFcXVpdmFsZW50KG1zZzEsIG1zZzIpKTsKK30KKworCitURVNUKE1lc3NhZ2VEaWZmZXJlbmNlclRlc3QsIEJhc2ljRXF1aXZhbGVuY3lOb25TZXRUZXN0KSB7CisgIC8vIENyZWF0ZSB0aGUgdGVzdGluZyBwcm90b3MKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtc2cxOworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1zZzI7CisKKyAgLy8gQ29tcGFyZQorICBFWFBFQ1RfVFJVRSh1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXI6OkVxdWl2YWxlbnQobXNnMSwgbXNnMikpOworfQorCisKK1RFU1QoTWVzc2FnZURpZmZlcmVuY2VyVGVzdCwgQmFzaWNJbmVxdWl2YWxlbmN5Tm9uU2V0VGVzdCkgeworICAvLyBDcmVhdGUgdGhlIHRlc3RpbmcgcHJvdG9zCisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbXNnMTsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtc2cyOworCisgIG1zZzEuc2V0X29wdGlvbmFsX2ludDMyKC0xKTsKKworICAvLyBDb21wYXJlCisgIEVYUEVDVF9GQUxTRSh1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXI6OkVxdWl2YWxlbnQobXNnMSwgbXNnMikpOworfQorCisKK1RFU1QoTWVzc2FnZURpZmZlcmVuY2VyVGVzdCwgQmFzaWNQYXJ0aWFsRXF1aXZhbGVuY3lUZXN0KSB7CisgIC8vIENyZWF0ZSB0aGUgdGVzdGluZyBwcm90b3MKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtc2cxOworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1zZzI7CisKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbXNnMSk7CisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1zZzIpOworCisgIC8vIENvbXBhcmUKKyAgdXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyIGRpZmZlcmVuY2VyOworICBkaWZmZXJlbmNlci5zZXRfbWVzc2FnZV9maWVsZF9jb21wYXJpc29uKAorICAgICAgdXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyOjpFUVVJVkFMRU5UKTsKKyAgZGlmZmVyZW5jZXIuc2V0X3Njb3BlKHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlcjo6UEFSVElBTCk7CisgIEVYUEVDVF9UUlVFKGRpZmZlcmVuY2VyLkNvbXBhcmUobXNnMSwgbXNnMikpOworfQorCitURVNUKE1lc3NhZ2VEaWZmZXJlbmNlclRlc3QsIFBhcnRpYWxFcXVpdmFsZW5jeU5vdEVxdWFsVGVzdCkgeworICAvLyBDcmVhdGUgdGhlIHRlc3RpbmcgcHJvdG9zCisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbXNnMTsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtc2cyOworCisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1zZzEpOworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZtc2cyKTsKKworICBtc2cxLnNldF9vcHRpb25hbF9pbnQzMigwKTsKKyAgbXNnMi5jbGVhcl9vcHRpb25hbF9pbnQzMigpOworCisgIC8vIENvbXBhcmUKKyAgRVhQRUNUX0ZBTFNFKHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlcjo6RXF1YWxzKG1zZzEsIG1zZzIpKTsKKyAgdXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyIGRpZmZlcmVuY2VyOworICBkaWZmZXJlbmNlci5zZXRfbWVzc2FnZV9maWVsZF9jb21wYXJpc29uKAorICAgICAgdXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyOjpFUVVJVkFMRU5UKTsKKyAgZGlmZmVyZW5jZXIuc2V0X3Njb3BlKHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlcjo6UEFSVElBTCk7CisgIEVYUEVDVF9UUlVFKGRpZmZlcmVuY2VyLkNvbXBhcmUobXNnMSwgbXNnMikpOworfQorCitURVNUKE1lc3NhZ2VEaWZmZXJlbmNlclRlc3QsIFBhcnRpYWxFcXVpdmFsZW5jeVRlc3RFeHRyYUZpZWxkKSB7CisgIC8vIENyZWF0ZSB0aGUgdGVzdGluZyBwcm90b3MKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtc2cxOworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1zZzI7CisKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbXNnMSk7CisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1zZzIpOworCisgIG1zZzEuY2xlYXJfb3B0aW9uYWxfaW50MzIoKTsKKworICAvLyBDb21wYXJlCisgIHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlciBkaWZmZXJlbmNlcjsKKyAgZGlmZmVyZW5jZXIuc2V0X21lc3NhZ2VfZmllbGRfY29tcGFyaXNvbigKKyAgICAgIHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlcjo6RVFVSVZBTEVOVCk7CisgIGRpZmZlcmVuY2VyLnNldF9zY29wZSh1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXI6OlBBUlRJQUwpOworICBFWFBFQ1RfVFJVRShkaWZmZXJlbmNlci5Db21wYXJlKG1zZzEsIG1zZzIpKTsKK30KKworVEVTVChNZXNzYWdlRGlmZmVyZW5jZXJUZXN0LCBQYXJ0aWFsRXF1aXZhbGVuY3lUZXN0U2tpcFJlcXVpcmVkRmllbGQpIHsKKyAgLy8gQ3JlYXRlIHRoZSB0ZXN0aW5nIHByb3RvcworICB1bml0dGVzdDo6VGVzdFJlcXVpcmVkIG1zZzE7CisgIHVuaXR0ZXN0OjpUZXN0UmVxdWlyZWQgbXNnMjsKKworICBtc2cxLnNldF9hKDQwMSk7CisgIG1zZzIuc2V0X2EoNDAxKTsKKyAgbXNnMi5zZXRfYig0MDIpOworCisgIC8vIENvbXBhcmUKKyAgdXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyIGRpZmZlcmVuY2VyOworICBkaWZmZXJlbmNlci5zZXRfbWVzc2FnZV9maWVsZF9jb21wYXJpc29uKAorICAgICAgdXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyOjpFUVVJVkFMRU5UKTsKKyAgZGlmZmVyZW5jZXIuc2V0X3Njb3BlKHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlcjo6UEFSVElBTCk7CisgIEVYUEVDVF9UUlVFKGRpZmZlcmVuY2VyLkNvbXBhcmUobXNnMSwgbXNnMikpOworfQorCitURVNUKE1lc3NhZ2VEaWZmZXJlbmNlclRlc3QsIEJhc2ljUGFydGlhbEluZXF1aXZhbGVuY3lUZXN0KSB7CisgIC8vIENyZWF0ZSB0aGUgdGVzdGluZyBwcm90b3MKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtc2cxOworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1zZzI7CisKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbXNnMSk7CisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1zZzIpOworCisgIG1zZzEuc2V0X29wdGlvbmFsX2ludDMyKC0xKTsKKworICAvLyBDb21wYXJlCisgIHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlciBkaWZmZXJlbmNlcjsKKyAgZGlmZmVyZW5jZXIuc2V0X21lc3NhZ2VfZmllbGRfY29tcGFyaXNvbigKKyAgICAgIHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlcjo6RVFVSVZBTEVOVCk7CisgIGRpZmZlcmVuY2VyLnNldF9zY29wZSh1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXI6OlBBUlRJQUwpOworICBFWFBFQ1RfRkFMU0UoZGlmZmVyZW5jZXIuQ29tcGFyZShtc2cxLCBtc2cyKSk7Cit9CisKK1RFU1QoTWVzc2FnZURpZmZlcmVuY2VyVGVzdCwgQmFzaWNQYXJ0aWFsRXF1aXZhbGVuY3lOb25TZXRUZXN0KSB7CisgIC8vIENyZWF0ZSB0aGUgdGVzdGluZyBwcm90b3MKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtc2cxOworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1zZzI7CisKKyAgLy8gQ29tcGFyZQorICB1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXIgZGlmZmVyZW5jZXI7CisgIGRpZmZlcmVuY2VyLnNldF9tZXNzYWdlX2ZpZWxkX2NvbXBhcmlzb24oCisgICAgICB1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXI6OkVRVUlWQUxFTlQpOworICBkaWZmZXJlbmNlci5zZXRfc2NvcGUodXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyOjpQQVJUSUFMKTsKKyAgRVhQRUNUX1RSVUUoZGlmZmVyZW5jZXIuQ29tcGFyZShtc2cxLCBtc2cyKSk7Cit9CisKK1RFU1QoTWVzc2FnZURpZmZlcmVuY2VyVGVzdCwgQmFzaWNQYXJ0aWFsSW5lcXVpdmFsZW5jeU5vblNldFRlc3QpIHsKKyAgLy8gQ3JlYXRlIHRoZSB0ZXN0aW5nIHByb3RvcworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1zZzE7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbXNnMjsKKworICBtc2cxLnNldF9vcHRpb25hbF9pbnQzMigtMSk7CisKKyAgLy8gQ29tcGFyZQorICB1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXIgZGlmZmVyZW5jZXI7CisgIGRpZmZlcmVuY2VyLnNldF9tZXNzYWdlX2ZpZWxkX2NvbXBhcmlzb24oCisgICAgICB1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXI6OkVRVUlWQUxFTlQpOworICBkaWZmZXJlbmNlci5zZXRfc2NvcGUodXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyOjpQQVJUSUFMKTsKKyAgRVhQRUNUX0ZBTFNFKGRpZmZlcmVuY2VyLkNvbXBhcmUobXNnMSwgbXNnMikpOworfQorCitURVNUKE1lc3NhZ2VEaWZmZXJlbmNlclRlc3QsIEFwcHJveGltYXRlRXF1YWxpdHlUZXN0KSB7CisgIC8vIENyZWF0ZSB0aGUgdGVzdGluZyBwcm90b3MKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtc2cxOworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1zZzI7CisKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbXNnMSk7CisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1zZzIpOworCisgIC8vIENvbXBhcmUKKyAgRVhQRUNUX1RSVUUodXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyOjpBcHByb3hpbWF0ZWx5RXF1YWxzKG1zZzEsIG1zZzIpKTsKK30KKworVEVTVChNZXNzYWdlRGlmZmVyZW5jZXJUZXN0LCBBcHByb3hpbWF0ZU1vZGlmaWVkRXF1YWxpdHlUZXN0KSB7CisgIC8vIENyZWF0ZSB0aGUgdGVzdGluZyBwcm90b3MKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtc2cxOworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1zZzI7CisKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbXNnMSk7CisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1zZzIpOworCisgIGNvbnN0IGZsb2F0IHYxID0gMi4zMDAwMDVmOworICBjb25zdCBmbG9hdCB2MiA9IDIuMzAwMDA2ZjsKKyAgbXNnMS5zZXRfb3B0aW9uYWxfZmxvYXQodjEpOworICBtc2cyLnNldF9vcHRpb25hbF9mbG9hdCh2Mik7CisKKyAgLy8gQ29tcGFyZQorICBBU1NFUlRfTkUodjEsIHYyKSA8PCAiU2hvdWxkIG5vdCBiZSB0aGUgc2FtZTogIiA8PCB2MSA8PCAiLCAiIDw8IHYyOworICBBU1NFUlRfRkxPQVRfRVEodjEsIHYyKSA8PCAiU2hvdWxkIGJlIGFwcHJveC4gZXF1YWw6ICIgPDwgdjEgPDwgIiwgIiA8PCB2MjsKKyAgRVhQRUNUX0ZBTFNFKHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlcjo6RXF1YWxzKG1zZzEsIG1zZzIpKTsKKyAgRVhQRUNUX1RSVUUodXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyOjpBcHByb3hpbWF0ZWx5RXF1YWxzKG1zZzEsIG1zZzIpKTsKK30KKworVEVTVChNZXNzYWdlRGlmZmVyZW5jZXJUZXN0LCBBcHByb3hpbWF0ZUVxdWl2YWxlbmN5VGVzdCkgeworICAvLyBDcmVhdGUgdGhlIHRlc3RpbmcgcHJvdG9zCisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbXNnMTsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtc2cyOworCisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1zZzEpOworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZtc2cyKTsKKworICAvLyBDb21wYXJlCisgIEVYUEVDVF9UUlVFKHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlcjo6QXBwcm94aW1hdGVseUVxdWl2YWxlbnQobXNnMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtc2cyKSk7Cit9CisKK1RFU1QoTWVzc2FnZURpZmZlcmVuY2VyVGVzdCwgQXBwcm94aW1hdGVNb2RpZmllZEVxdWl2YWxlbmN5VGVzdCkgeworICAvLyBDcmVhdGUgdGhlIHRlc3RpbmcgcHJvdG9zCisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbXNnMTsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtc2cyOworCisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1zZzEpOworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZtc2cyKTsKKworICAvLyBNb2RpZnkgdGhlIGFwcHJveGltYXRlbmVzcyByZXF1aXJlbWVudAorICBjb25zdCBmbG9hdCB2MSA9IDIuMzAwMDA1ZjsKKyAgY29uc3QgZmxvYXQgdjIgPSAyLjMwMDAwNmY7CisgIG1zZzEuc2V0X29wdGlvbmFsX2Zsb2F0KHYxKTsKKyAgbXNnMi5zZXRfb3B0aW9uYWxfZmxvYXQodjIpOworCisgIC8vIENvbXBhcmUKKyAgQVNTRVJUX05FKHYxLCB2MikgPDwgIlNob3VsZCBub3QgYmUgdGhlIHNhbWU6ICIgPDwgdjEgPDwgIiwgIiA8PCB2MjsKKyAgQVNTRVJUX0ZMT0FUX0VRKHYxLCB2MikgPDwgIlNob3VsZCBiZSBhcHByb3guIGVxdWFsOiAiIDw8IHYxIDw8ICIsICIgPDwgdjI7CisgIEVYUEVDVF9GQUxTRSh1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXI6OkVxdWFscyhtc2cxLCBtc2cyKSk7CisgIEVYUEVDVF9UUlVFKHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlcjo6QXBwcm94aW1hdGVseUVxdWl2YWxlbnQobXNnMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtc2cyKSk7CisKKyAgLy8gTW9kaWZ5IHRoZSBlcXVpdmFsZW5jeSByZXF1aXJlbWVudCB0b28KKyAgbXNnMS5jbGVhcl9vcHRpb25hbF9pbnQzMigpOworICBtc2cyLnNldF9vcHRpb25hbF9pbnQzMigwKTsKKworICAvLyBDb21wYXJlLiBOb3cgc2hvdWxkIG9ubHkgcGFzcyBvbiBBcHByb3hpbWF0ZWx5RXF1aXZhbGVudAorICBFWFBFQ1RfRkFMU0UodXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyOjpFcXVhbHMobXNnMSwgbXNnMikpOworICBFWFBFQ1RfRkFMU0UodXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyOjpFcXVpdmFsZW50KG1zZzEsIG1zZzIpKTsKKyAgRVhQRUNUX0ZBTFNFKHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlcjo6QXBwcm94aW1hdGVseUVxdWFscyhtc2cxLCBtc2cyKSk7CisgIEVYUEVDVF9UUlVFKHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlcjo6QXBwcm94aW1hdGVseUVxdWl2YWxlbnQobXNnMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtc2cyKSk7Cit9CisKK1RFU1QoTWVzc2FnZURpZmZlcmVuY2VyVGVzdCwgQXBwcm94aW1hdGVJbmVxdWl2YWxlbmN5VGVzdCkgeworICAvLyBDcmVhdGUgdGhlIHRlc3RpbmcgcHJvdG9zCisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbXNnMTsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtc2cyOworCisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1zZzEpOworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZtc2cyKTsKKworICAvLyBTaG91bGQgZmFpbCBvbiBlcXVpdmFsZW5jeQorICBtc2cxLnNldF9vcHRpb25hbF9pbnQzMigtMSk7CisgIEVYUEVDVF9GQUxTRSh1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXI6OkFwcHJveGltYXRlbHlFcXVpdmFsZW50KG1zZzEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1zZzIpKTsKKworICAvLyBNYWtlIHRoZXNlIGZpZWxkcyB0aGUgc2FtZSBhZ2Fpbi4KKyAgbXNnMS5zZXRfb3B0aW9uYWxfaW50MzIoMCk7CisgIG1zZzIuc2V0X29wdGlvbmFsX2ludDMyKDApOworICBFWFBFQ1RfVFJVRSh1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXI6OkFwcHJveGltYXRlbHlFcXVpdmFsZW50KG1zZzEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXNnMikpOworCisgIC8vIFNob3VsZCBmYWlsIG9uIGFwcHJveGltYXRlIGVxdWFsaXR5IGNoZWNrCisgIGNvbnN0IGZsb2F0IHYxID0gMi4zZjsKKyAgY29uc3QgZmxvYXQgdjIgPSA5LjNmOworICBtc2cxLnNldF9vcHRpb25hbF9mbG9hdCh2MSk7CisgIG1zZzIuc2V0X29wdGlvbmFsX2Zsb2F0KHYyKTsKKyAgRVhQRUNUX0ZBTFNFKHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlcjo6QXBwcm94aW1hdGVseUVxdWl2YWxlbnQobXNnMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXNnMikpOworfQorCitURVNUKE1lc3NhZ2VEaWZmZXJlbmNlclRlc3QsIFdpdGhpbkZyYWN0aW9uT3JNYXJnaW5GbG9hdFRlc3QpIHsKKyAgLy8gQ3JlYXRlIHRoZSB0ZXN0aW5nIHByb3RvcworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1zZzE7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbXNnMjsKKworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZtc2cxKTsKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbXNnMik7CisKKyAgLy8gU2hvdWxkIGZhaWwgb24gYXBwcm94aW1hdGUgZXF1YWxpdHkgY2hlY2sKKyAgY29uc3QgZmxvYXQgdjEgPSAxMDAuMGY7CisgIGNvbnN0IGZsb2F0IHYyID0gMTA5LjlmOworICBtc2cxLnNldF9vcHRpb25hbF9mbG9hdCh2MSk7CisgIG1zZzIuc2V0X29wdGlvbmFsX2Zsb2F0KHYyKTsKKworICAvLyBDb21wYXJlCisgIHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlciBkaWZmZXJlbmNlcjsKKyAgRVhQRUNUX0ZBTFNFKGRpZmZlcmVuY2VyLkNvbXBhcmUobXNnMSwgbXNnMikpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZkID0KKyAgICAgIG1zZzEuR2V0RGVzY3JpcHRvcigpLT5GaW5kRmllbGRCeU5hbWUoIm9wdGlvbmFsX2Zsb2F0Iik7CisKKyAgLy8gU2V0IGZsb2F0IGNvbXBhcmlzb24gdG8gZXhhY3QsIG1hcmdpbiBhbmQgZnJhY3Rpb24gdmFsdWUgc2hvdWxkIG5vdCBtYXR0ZXIuCisgIGRpZmZlcmVuY2VyLnNldF9mbG9hdF9jb21wYXJpc29uKHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlcjo6RVhBQ1QpOworICAvLyBTZXQgbWFyZ2luIGZvciBmbG9hdCBjb21wYXJpc29uLgorICBkaWZmZXJlbmNlci5TZXRGcmFjdGlvbkFuZE1hcmdpbihmZCwgMC4wLCAxMC4wKTsKKyAgRVhQRUNUX0ZBTFNFKGRpZmZlcmVuY2VyLkNvbXBhcmUobXNnMSwgbXNnMikpOworCisgIC8vIE1hcmdpbiBhbmQgZnJhY3Rpb24gZmxvYXQgY29tcGFyaXNvbiBpcyBhY3RpdmF0ZWQgd2hlbiBmbG9hdCBjb21wYXJpc29uIGlzCisgIC8vIHNldCB0byBhcHByb3hpbWF0ZS4KKyAgZGlmZmVyZW5jZXIuc2V0X2Zsb2F0X2NvbXBhcmlzb24odXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyOjpBUFBST1hJTUFURSk7CisgIEVYUEVDVF9UUlVFKGRpZmZlcmVuY2VyLkNvbXBhcmUobXNnMSwgbXNnMikpOworCisgIC8vIFRlc3Qgb3V0IGZsb2F0IGNvbXBhcmlzb24gd2l0aCBmcmFjdGlvbi4KKyAgZGlmZmVyZW5jZXIuU2V0RnJhY3Rpb25BbmRNYXJnaW4oZmQsIDAuMiwgMC4wKTsKKyAgRVhQRUNUX1RSVUUoZGlmZmVyZW5jZXIuQ29tcGFyZShtc2cxLCBtc2cyKSk7CisKKyAgLy8gU2hvdWxkIGZhaWwgc2luY2UgdGhlIGZyYWN0aW9uIGlzIHNtYWxsZXIgdGhhbiBlcnJvci4KKyAgZGlmZmVyZW5jZXIuU2V0RnJhY3Rpb25BbmRNYXJnaW4oZmQsIDAuMDEsIDAuMCk7CisgIEVYUEVDVF9GQUxTRShkaWZmZXJlbmNlci5Db21wYXJlKG1zZzEsIG1zZzIpKTsKKworICAvLyBTaG91bGQgcGFzcyBpZiBlaXRoZXIgZnJhY3Rpb24gb3IgbWFyZ2luIGFyZSBzYXRpc2ZpZWQuCisgIGRpZmZlcmVuY2VyLlNldEZyYWN0aW9uQW5kTWFyZ2luKGZkLCAwLjAxLCAxMC4wKTsKKyAgRVhQRUNUX1RSVUUoZGlmZmVyZW5jZXIuQ29tcGFyZShtc2cxLCBtc2cyKSk7CisKKyAgLy8gTWFrZSBzdXJlIHRoYXQgdGhlIG1hcmdpbiBhbmQgZnJhY3Rpb24gb25seSBhZmZlY3RzIHRoZSBmaWVsZCB0aGF0IGl0IHdhcworICAvLyBzZXQgZm9yLgorICBtc2cxLnNldF9kZWZhdWx0X2Zsb2F0KHYxKTsKKyAgbXNnMi5zZXRfZGVmYXVsdF9mbG9hdCh2Mik7CisgIEVYUEVDVF9GQUxTRShkaWZmZXJlbmNlci5Db21wYXJlKG1zZzEsIG1zZzIpKTsKKyAgbXNnMS5zZXRfZGVmYXVsdF9mbG9hdCh2MSk7CisgIG1zZzIuc2V0X2RlZmF1bHRfZmxvYXQodjEpOworICBFWFBFQ1RfVFJVRShkaWZmZXJlbmNlci5Db21wYXJlKG1zZzEsIG1zZzIpKTsKK30KKworVEVTVChNZXNzYWdlRGlmZmVyZW5jZXJUZXN0LCBXaXRoaW5GcmFjdGlvbk9yTWFyZ2luRG91YmxlVGVzdCkgeworICAvLyBDcmVhdGUgdGhlIHRlc3RpbmcgcHJvdG9zCisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbXNnMTsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtc2cyOworCisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1zZzEpOworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZtc2cyKTsKKworICAvLyBTaG91bGQgZmFpbCBvbiBhcHByb3hpbWF0ZSBlcXVhbGl0eSBjaGVjaworICBjb25zdCBkb3VibGUgdjEgPSAxMDAuMDsKKyAgY29uc3QgZG91YmxlIHYyID0gMTA5Ljk7CisgIG1zZzEuc2V0X29wdGlvbmFsX2RvdWJsZSh2MSk7CisgIG1zZzIuc2V0X29wdGlvbmFsX2RvdWJsZSh2Mik7CisKKyAgLy8gQ29tcGFyZQorICB1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXIgZGlmZmVyZW5jZXI7CisgIEVYUEVDVF9GQUxTRShkaWZmZXJlbmNlci5Db21wYXJlKG1zZzEsIG1zZzIpKTsKKworICAvLyBTZXQgY29tcGFyaXNvbiB0byBleGFjdCwgbWFyZ2luIGFuZCBmcmFjdGlvbiB2YWx1ZSBzaG91bGQgbm90IG1hdHRlci4KKyAgZGlmZmVyZW5jZXIuc2V0X2Zsb2F0X2NvbXBhcmlzb24odXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyOjpFWEFDVCk7CisgIC8vIFNldCBtYXJnaW4gZm9yIGZsb2F0IGNvbXBhcmlzb24uCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmQgPQorICAgICAgbXNnMS5HZXREZXNjcmlwdG9yKCktPkZpbmRGaWVsZEJ5TmFtZSgib3B0aW9uYWxfZG91YmxlIik7CisgIGRpZmZlcmVuY2VyLlNldEZyYWN0aW9uQW5kTWFyZ2luKGZkLCAwLjAsIDEwLjApOworICBFWFBFQ1RfRkFMU0UoZGlmZmVyZW5jZXIuQ29tcGFyZShtc2cxLCBtc2cyKSk7CisKKyAgLy8gTWFyZ2luIGFuZCBmcmFjdGlvbiBjb21wYXJpc29uIGlzIGFjdGl2YXRlZCB3aGVuIGZsb2F0IGNvbXBhcmlzb24gaXMKKyAgLy8gc2V0IHRvIGFwcHJveGltYXRlLgorICBkaWZmZXJlbmNlci5zZXRfZmxvYXRfY29tcGFyaXNvbih1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXI6OkFQUFJPWElNQVRFKTsKKyAgRVhQRUNUX1RSVUUoZGlmZmVyZW5jZXIuQ29tcGFyZShtc2cxLCBtc2cyKSk7CisKKyAgLy8gVGVzdCBvdXQgY29tcGFyaXNvbiB3aXRoIGZyYWN0aW9uLgorICBkaWZmZXJlbmNlci5TZXRGcmFjdGlvbkFuZE1hcmdpbihmZCwgMC4yLCAwLjApOworICBFWFBFQ1RfVFJVRShkaWZmZXJlbmNlci5Db21wYXJlKG1zZzEsIG1zZzIpKTsKKworICAvLyBTaG91bGQgZmFpbCBzaW5jZSB0aGUgZnJhY3Rpb24gaXMgc21hbGxlciB0aGFuIGVycm9yLgorICBkaWZmZXJlbmNlci5TZXRGcmFjdGlvbkFuZE1hcmdpbihmZCwgMC4wMSwgMC4wKTsKKyAgRVhQRUNUX0ZBTFNFKGRpZmZlcmVuY2VyLkNvbXBhcmUobXNnMSwgbXNnMikpOworCisgIC8vIFNob3VsZCBwYXNzIGlmIGVpdGhlciBmcmFjdGlvbiBvciBtYXJnaW4gYXJlIHNhdGlzZmllZC4KKyAgZGlmZmVyZW5jZXIuU2V0RnJhY3Rpb25BbmRNYXJnaW4oZmQsIDAuMDEsIDEwLjApOworICBFWFBFQ1RfVFJVRShkaWZmZXJlbmNlci5Db21wYXJlKG1zZzEsIG1zZzIpKTsKKworICAvLyBNYWtlIHN1cmUgdGhhdCB0aGUgbWFyZ2luIGFuZCBmcmFjdGlvbiBvbmx5IGFmZmVjdHMgdGhlIGZpZWxkIHRoYXQgaXQgd2FzCisgIC8vIHNldCBmb3IuCisgIG1zZzEuc2V0X2RlZmF1bHRfZG91YmxlKHYxKTsKKyAgbXNnMi5zZXRfZGVmYXVsdF9kb3VibGUodjIpOworICBFWFBFQ1RfRkFMU0UoZGlmZmVyZW5jZXIuQ29tcGFyZShtc2cxLCBtc2cyKSk7CisgIG1zZzEuc2V0X2RlZmF1bHRfZG91YmxlKHYxKTsKKyAgbXNnMi5zZXRfZGVmYXVsdF9kb3VibGUodjEpOworICBFWFBFQ1RfVFJVRShkaWZmZXJlbmNlci5Db21wYXJlKG1zZzEsIG1zZzIpKTsKK30KKworVEVTVChNZXNzYWdlRGlmZmVyZW5jZXJUZXN0LCBXaXRoaW5EZWZhdWx0RnJhY3Rpb25Pck1hcmdpbkRvdWJsZVRlc3QpIHsKKyAgLy8gQ3JlYXRlIHRoZSB0ZXN0aW5nIHByb3RvcworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1zZzE7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbXNnMjsKKworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZtc2cxKTsKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbXNnMik7CisKKyAgLy8gU2hvdWxkIGZhaWwgb24gYXBwcm94aW1hdGUgZXF1YWxpdHkgY2hlY2sKKyAgY29uc3QgZG91YmxlIHYxID0gMTAwLjA7CisgIGNvbnN0IGRvdWJsZSB2MiA9IDEwOS45OworICBtc2cxLnNldF9vcHRpb25hbF9kb3VibGUodjEpOworICBtc2cyLnNldF9vcHRpb25hbF9kb3VibGUodjIpOworCisgIHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlciBkaWZmZXJlbmNlcjsKKworICAvLyBDb21wYXJlCisgIEVYUEVDVF9GQUxTRShkaWZmZXJlbmNlci5Db21wYXJlKG1zZzEsIG1zZzIpKTsKKworICAvLyBTZXQgdXAgYSBjdXN0b20gZmllbGQgY29tcGFyaXRvciwgd2l0aCBhIGRlZmF1bHQgZnJhY3Rpb24gYW5kIG1hcmdpbiBmb3IKKyAgLy8gZmxvYXQgYW5kIGRvdWJsZSBjb21wYXJpc29uLgorICB1dGlsOjpEZWZhdWx0RmllbGRDb21wYXJhdG9yIGZpZWxkX2NvbXBhcml0b3I7CisgIGZpZWxkX2NvbXBhcml0b3IuU2V0RGVmYXVsdEZyYWN0aW9uQW5kTWFyZ2luKDAuMCwgMTAuMCk7CisgIGRpZmZlcmVuY2VyLnNldF9maWVsZF9jb21wYXJhdG9yKCZmaWVsZF9jb21wYXJpdG9yKTsKKworICAvLyBTZXQgY29tcGFyaXNvbiB0byBleGFjdCwgbWFyZ2luIGFuZCBmcmFjdGlvbiB2YWx1ZSBzaG91bGQgbm90IG1hdHRlci4KKyAgZmllbGRfY29tcGFyaXRvci5zZXRfZmxvYXRfY29tcGFyaXNvbih1dGlsOjpEZWZhdWx0RmllbGRDb21wYXJhdG9yOjpFWEFDVCk7CisgIEVYUEVDVF9GQUxTRShkaWZmZXJlbmNlci5Db21wYXJlKG1zZzEsIG1zZzIpKTsKKworICAvLyBNYXJnaW4gYW5kIGZyYWN0aW9uIGNvbXBhcmlzb24gaXMgYWN0aXZhdGVkIHdoZW4gZmxvYXQgY29tcGFyaXNvbiBpcworICAvLyBzZXQgdG8gYXBwcm94aW1hdGUuCisgIGZpZWxkX2NvbXBhcml0b3Iuc2V0X2Zsb2F0X2NvbXBhcmlzb24oCisgICAgICB1dGlsOjpEZWZhdWx0RmllbGRDb21wYXJhdG9yOjpBUFBST1hJTUFURSk7CisgIEVYUEVDVF9UUlVFKGRpZmZlcmVuY2VyLkNvbXBhcmUobXNnMSwgbXNnMikpOworCisgIC8vIFRlc3Qgb3V0IGNvbXBhcmlzb24gd2l0aCBmcmFjdGlvbi4KKyAgZmllbGRfY29tcGFyaXRvci5TZXREZWZhdWx0RnJhY3Rpb25BbmRNYXJnaW4oMC4yLCAwLjApOworICBFWFBFQ1RfVFJVRShkaWZmZXJlbmNlci5Db21wYXJlKG1zZzEsIG1zZzIpKTsKKworICAvLyBTaG91bGQgZmFpbCBzaW5jZSB0aGUgZnJhY3Rpb24gaXMgc21hbGxlciB0aGFuIGVycm9yLgorICBmaWVsZF9jb21wYXJpdG9yLlNldERlZmF1bHRGcmFjdGlvbkFuZE1hcmdpbigwLjAxLCAwLjApOworICBFWFBFQ1RfRkFMU0UoZGlmZmVyZW5jZXIuQ29tcGFyZShtc2cxLCBtc2cyKSk7CisKKyAgLy8gU2hvdWxkIHBhc3MgaWYgZWl0aGVyIGZyYWN0aW9uIG9yIG1hcmdpbiBhcmUgc2F0aXNmaWVkLgorICBmaWVsZF9jb21wYXJpdG9yLlNldERlZmF1bHRGcmFjdGlvbkFuZE1hcmdpbigwLjAxLCAxMC4wKTsKKyAgRVhQRUNUX1RSVUUoZGlmZmVyZW5jZXIuQ29tcGFyZShtc2cxLCBtc2cyKSk7CisKKyAgLy8gTWFrZSBzdXJlIHRoYXQgdGhlIGRlZmF1bHQgbWFyZ2luIGFuZCBmcmFjdGlvbiBhZmZlY3RzIGFsbCBmaWVsZHMKKyAgbXNnMS5zZXRfZGVmYXVsdF9kb3VibGUodjEpOworICBtc2cyLnNldF9kZWZhdWx0X2RvdWJsZSh2Mik7CisgIEVYUEVDVF9UUlVFKGRpZmZlcmVuY2VyLkNvbXBhcmUobXNnMSwgbXNnMikpOworfQorCitURVNUKE1lc3NhZ2VEaWZmZXJlbmNlclRlc3QsIEJhc2ljRmllbGRPcmRlcmluZ3NUZXN0KSB7CisgIC8vIENyZWF0ZSB0aGUgdGVzdGluZyBwcm90b3MKKyAgdW5pdHRlc3Q6OlRlc3RGaWVsZE9yZGVyaW5ncyBtc2cxOworICB1bml0dGVzdDo6VGVzdEZpZWxkT3JkZXJpbmdzIG1zZzI7CisKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkc0FuZEV4dGVuc2lvbnMoJm1zZzEpOworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzQW5kRXh0ZW5zaW9ucygmbXNnMik7CisKKyAgLy8gQ29tcGFyZQorICBFWFBFQ1RfVFJVRSh1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXI6OkVxdWFscyhtc2cxLCBtc2cyKSk7Cit9CisKKworVEVTVChNZXNzYWdlRGlmZmVyZW5jZXJUZXN0LCBCYXNpY0ZpZWxkT3JkZXJpbmdJbmVxdWFsaXR5VGVzdCkgeworICAvLyBDcmVhdGUgdGhlIHRlc3RpbmcgcHJvdG9zCisgIHVuaXR0ZXN0OjpUZXN0RmllbGRPcmRlcmluZ3MgbXNnMTsKKyAgdW5pdHRlc3Q6OlRlc3RGaWVsZE9yZGVyaW5ncyBtc2cyOworCisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHNBbmRFeHRlbnNpb25zKCZtc2cxKTsKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkc0FuZEV4dGVuc2lvbnMoJm1zZzIpOworCisgIG1zZzEuc2V0X215X2Zsb2F0KDE1LjAwKTsKKyAgbXNnMi5zZXRfbXlfZmxvYXQoMTYuMDApOworCisgIC8vIENvbXBhcmUKKyAgRVhQRUNUX0ZBTFNFKHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlcjo6RXF1YWxzKG1zZzEsIG1zZzIpKTsKK30KKworVEVTVChNZXNzYWdlRGlmZmVyZW5jZXJUZXN0LCBCYXNpY0V4dGVuc2lvblRlc3QpIHsKKyAgLy8gQ3JlYXRlIHRoZSB0ZXN0aW5nIHByb3RvcworICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbXNnMTsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIG1zZzI7CisKKyAgVGVzdFV0aWw6OlNldEFsbEV4dGVuc2lvbnMoJm1zZzEpOworICBUZXN0VXRpbDo6U2V0QWxsRXh0ZW5zaW9ucygmbXNnMik7CisKKyAgLy8gQ29tcGFyZQorICBFWFBFQ1RfVFJVRSh1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXI6OkVxdWFscyhtc2cxLCBtc2cyKSk7Cit9CisKKworVEVTVChNZXNzYWdlRGlmZmVyZW5jZXJUZXN0LCBCYXNpY0V4dGVuc2lvbkluZXF1YWxpdHlUZXN0KSB7CisgIC8vIENyZWF0ZSB0aGUgdGVzdGluZyBwcm90b3MKKyAgdW5pdHRlc3Q6OlRlc3RBbGxFeHRlbnNpb25zIG1zZzE7CisgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyBtc2cyOworCisgIFRlc3RVdGlsOjpTZXRBbGxFeHRlbnNpb25zKCZtc2cxKTsKKyAgVGVzdFV0aWw6OlNldEFsbEV4dGVuc2lvbnMoJm1zZzIpOworCisgIG1zZzEuU2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbnQzMl9leHRlbnNpb24sIDEwMSk7CisgIG1zZzIuU2V0RXh0ZW5zaW9uKHVuaXR0ZXN0OjpvcHRpb25hbF9pbnQzMl9leHRlbnNpb24sIDEwMik7CisKKyAgLy8gQ29tcGFyZQorICBFWFBFQ1RfRkFMU0UodXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyOjpFcXVhbHMobXNnMSwgbXNnMikpOworfQorCitURVNUKE1lc3NhZ2VEaWZmZXJlbmNlclRlc3QsIE9uZW9mVGVzdCkgeworICAvLyBDcmVhdGUgdGhlIHRlc3RpbmcgcHJvdG9zCisgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIG1zZzE7CisgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIG1zZzI7CisKKyAgVGVzdFV0aWw6OlNldE9uZW9mMSgmbXNnMSk7CisgIFRlc3RVdGlsOjpTZXRPbmVvZjEoJm1zZzIpOworCisgIC8vIENvbXBhcmUKKyAgRVhQRUNUX1RSVUUodXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyOjpFcXVhbHMobXNnMSwgbXNnMikpOworfQorCitURVNUKE1lc3NhZ2VEaWZmZXJlbmNlclRlc3QsIE9uZW9mSW5lcXVhbGl0eVRlc3QpIHsKKyAgLy8gQ3JlYXRlIHRoZSB0ZXN0aW5nIHByb3RvcworICB1bml0dGVzdDo6VGVzdE9uZW9mMiBtc2cxOworICB1bml0dGVzdDo6VGVzdE9uZW9mMiBtc2cyOworCisgIFRlc3RVdGlsOjpTZXRPbmVvZjEoJm1zZzEpOworICBUZXN0VXRpbDo6U2V0T25lb2YyKCZtc2cyKTsKKworICAvLyBDb21wYXJlCisgIEVYUEVDVF9GQUxTRSh1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXI6OkVxdWFscyhtc2cxLCBtc2cyKSk7Cit9CisKK1RFU1QoTWVzc2FnZURpZmZlcmVuY2VyVGVzdCwgVW5rbm93bkZpZWxkUGFydGlhbEVxdWFsVGVzdCkgeworICB1bml0dGVzdDo6VGVzdEVtcHR5TWVzc2FnZSBlbXB0eTE7CisgIHVuaXR0ZXN0OjpUZXN0RW1wdHlNZXNzYWdlIGVtcHR5MjsKKworICBVbmtub3duRmllbGRTZXQqIHVua25vd24xID0gZW1wdHkxLm11dGFibGVfdW5rbm93bl9maWVsZHMoKTsKKyAgVW5rbm93bkZpZWxkU2V0KiB1bmtub3duMiA9IGVtcHR5Mi5tdXRhYmxlX3Vua25vd25fZmllbGRzKCk7CisKKyAgdW5rbm93bjEtPkFkZFZhcmludCgyNDMsIDEyMik7CisgIHVua25vd24xLT5BZGRMZW5ndGhEZWxpbWl0ZWQoMjQ1LCAiYWJjIik7CisgIHVua25vd24xLT5BZGRHcm91cCgyNDYpLT5BZGRGaXhlZDMyKDI0OCwgMSk7CisgIHVua25vd24xLT5tdXRhYmxlX2ZpZWxkKDIpLT5tdXRhYmxlX2dyb3VwKCktPkFkZEZpeGVkMzIoMjQ4LCAyKTsKKworICB1bmtub3duMi0+QWRkVmFyaW50KDI0MywgMTIyKTsKKyAgdW5rbm93bjItPkFkZExlbmd0aERlbGltaXRlZCgyNDUsICJhYmMiKTsKKyAgdW5rbm93bjItPkFkZEdyb3VwKDI0NiktPkFkZEZpeGVkMzIoMjQ4LCAxKTsKKyAgdW5rbm93bjItPm11dGFibGVfZmllbGQoMiktPm11dGFibGVfZ3JvdXAoKS0+QWRkRml4ZWQzMigyNDgsIDIpOworCisgIHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlciBkaWZmZXJlbmNlcjsKKyAgZGlmZmVyZW5jZXIuc2V0X3Njb3BlKHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlcjo6UEFSVElBTCk7CisgIEVYUEVDVF9UUlVFKGRpZmZlcmVuY2VyLkNvbXBhcmUoZW1wdHkxLCBlbXB0eTIpKTsKK30KKworVEVTVChNZXNzYWdlRGlmZmVyZW5jZXJUZXN0LCBTcGVjaWZpZWRGaWVsZHNFcXVhbGl0eUFsbFRlc3QpIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtc2cxOworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1zZzI7CisKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbXNnMSk7CisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1zZzIpOworCisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBmaWVsZHMxOworICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4gZmllbGRzMjsKKyAgbXNnMS5HZXRSZWZsZWN0aW9uKCktPkxpc3RGaWVsZHMobXNnMSwgJmZpZWxkczEpOworICBtc2cyLkdldFJlZmxlY3Rpb24oKS0+TGlzdEZpZWxkcyhtc2cyLCAmZmllbGRzMik7CisKKyAgdXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyIGRpZmZlcmVuY2VyOworICBFWFBFQ1RfVFJVRShkaWZmZXJlbmNlci5Db21wYXJlV2l0aEZpZWxkcyhtc2cxLCBtc2cyLCBmaWVsZHMxLCBmaWVsZHMyKSk7Cit9CisKK1RFU1QoTWVzc2FnZURpZmZlcmVuY2VyVGVzdCwgU3BlY2lmaWVkRmllbGRzSW5lcXVhbGl0eUFsbFRlc3QpIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtc2cxOworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1zZzI7CisKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbXNnMSk7CisKKyAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+IGZpZWxkczE7CisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBmaWVsZHMyOworICBtc2cxLkdldFJlZmxlY3Rpb24oKS0+TGlzdEZpZWxkcyhtc2cxLCAmZmllbGRzMSk7CisgIG1zZzIuR2V0UmVmbGVjdGlvbigpLT5MaXN0RmllbGRzKG1zZzIsICZmaWVsZHMyKTsKKworICB1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXIgZGlmZmVyZW5jZXI7CisgIEVYUEVDVF9GQUxTRShkaWZmZXJlbmNlci5Db21wYXJlV2l0aEZpZWxkcyhtc2cxLCBtc2cyLCBmaWVsZHMxLCBmaWVsZHMyKSk7Cit9CisKK1RFU1QoTWVzc2FnZURpZmZlcmVuY2VyVGVzdCwgU3BlY2lmaWVkRmllbGRzRW1wdHlMaXN0QWx3YXlzU3VjY2VlZHMpIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtc2cxOworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1zZzI7CisKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbXNnMSk7CisKKyAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+IGVtcHR5X2ZpZWxkczsKKworICB1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXIgZGlmZmVyZW5jZXI7CisgIEVYUEVDVF9UUlVFKGRpZmZlcmVuY2VyLkNvbXBhcmVXaXRoRmllbGRzKG1zZzEsIG1zZzIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVtcHR5X2ZpZWxkcywgZW1wdHlfZmllbGRzKSk7CisKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbXNnMik7CisgIEVYUEVDVF9UUlVFKGRpZmZlcmVuY2VyLkNvbXBhcmVXaXRoRmllbGRzKG1zZzEsIG1zZzIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVtcHR5X2ZpZWxkcywgZW1wdHlfZmllbGRzKSk7Cit9CisKK1RFU1QoTWVzc2FnZURpZmZlcmVuY2VyVGVzdCwgU3BlY2lmaWVkRmllbGRzQ29tcGFyZVdpdGhTZWxmKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbXNnMTsKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbXNnMSk7CisKKyAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+IGZpZWxkczsKKyAgbXNnMS5HZXRSZWZsZWN0aW9uKCktPkxpc3RGaWVsZHMobXNnMSwgJmZpZWxkcyk7CisKKyAgdXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyIGRpZmZlcmVuY2VyOworICBFWFBFQ1RfVFJVRShkaWZmZXJlbmNlci5Db21wYXJlV2l0aEZpZWxkcyhtc2cxLCBtc2cxLCBmaWVsZHMsIGZpZWxkcykpOworCisgIHsKKyAgICAvLyBDb21wYXJlIHdpdGggYSBzdWJzZXQgb2YgZmllbGRzLgorICAgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBjb21wYXJlX2ZpZWxkczsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkcy5zaXplKCk7ICsraSkgeworICAgICAgaWYgKGkgJSAyID09IDApIHsKKyAgICAgICAgY29tcGFyZV9maWVsZHMucHVzaF9iYWNrKGZpZWxkc1tpXSk7CisgICAgICB9CisgICAgfQorICAgIEVYUEVDVF9UUlVFKGRpZmZlcmVuY2VyLkNvbXBhcmVXaXRoRmllbGRzKG1zZzEsIG1zZzEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcGFyZV9maWVsZHMsIGNvbXBhcmVfZmllbGRzKSk7CisgIH0KKyAgeworICAgIC8vIFNwZWNpZnkgYSBkaWZmZXJlbnQgc2V0IG9mIGZpZWxkcyB0byBjb21wYXJlLCBldmVuIHRob3VnaCB3ZSdyZSB1c2luZyB0aGUKKyAgICAvLyBzYW1lIG1lc3NhZ2UuIFRoaXMgc2hvdWxkIGZhaWwsIHNpbmNlIHdlIGFyZSBleHBsaWNpdGx5IHNheWluZyB0aGF0IHRoZQorICAgIC8vIHNldCBvZiBmaWVsZHMgYXJlIGRpZmZlcmVudC4KKyAgICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4gY29tcGFyZV9maWVsZHMxOworICAgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBjb21wYXJlX2ZpZWxkczI7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZHMuc2l6ZSgpOyArK2kpIHsKKyAgICAgIGlmIChpICUgMiA9PSAwKSB7CisgICAgICAgIGNvbXBhcmVfZmllbGRzMS5wdXNoX2JhY2soZmllbGRzW2ldKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGNvbXBhcmVfZmllbGRzMi5wdXNoX2JhY2soZmllbGRzW2ldKTsKKyAgICAgIH0KKyAgICB9CisgICAgRVhQRUNUX0ZBTFNFKGRpZmZlcmVuY2VyLkNvbXBhcmVXaXRoRmllbGRzKAorICAgICAgICBtc2cxLCBtc2cxLCBjb21wYXJlX2ZpZWxkczEsIGNvbXBhcmVfZmllbGRzMikpOworICB9Cit9CisKK1RFU1QoTWVzc2FnZURpZmZlcmVuY2VyVGVzdCwgU3BlY2lmaWVkRmllbGRzRXF1YWxpdHlBbGxTaHVmZmxlZFRlc3QpIHsKKyAgLy8gVGhpcyBpcyBhIHB1YmxpYyBmdW5jdGlvbiwgc28gbWFrZSBzdXJlIHRoZXJlIGFyZSBubyBhc3N1bXB0aW9ucyBhYm91dCB0aGUKKyAgLy8gbGlzdCBvZiBmaWVsZHMuIFJhbmRvbWx5IHNodWZmbGUgdGhlbSB0byBtYWtlIHN1cmUgdGhhdCB0aGV5IGFyZSBwcm9wZXJseQorICAvLyBvcmRlcmVkIGZvciBjb21wYXJpc29uLgorICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1zZzE7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbXNnMjsKKworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZtc2cxKTsKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbXNnMik7CisKKyAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+IGZpZWxkczE7CisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBmaWVsZHMyOworICBtc2cxLkdldFJlZmxlY3Rpb24oKS0+TGlzdEZpZWxkcyhtc2cxLCAmZmllbGRzMSk7CisgIG1zZzIuR2V0UmVmbGVjdGlvbigpLT5MaXN0RmllbGRzKG1zZzIsICZmaWVsZHMyKTsKKworICBzdGQ6OnJhbmRvbV9zaHVmZmxlKGZpZWxkczEuYmVnaW4oKSwgZmllbGRzMS5lbmQoKSk7CisgIHN0ZDo6cmFuZG9tX3NodWZmbGUoZmllbGRzMi5iZWdpbigpLCBmaWVsZHMyLmVuZCgpKTsKKworICB1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXIgZGlmZmVyZW5jZXI7CisgIEVYUEVDVF9UUlVFKGRpZmZlcmVuY2VyLkNvbXBhcmVXaXRoRmllbGRzKG1zZzEsIG1zZzIsIGZpZWxkczEsIGZpZWxkczIpKTsKK30KKworVEVTVChNZXNzYWdlRGlmZmVyZW5jZXJUZXN0LCBTcGVjaWZpZWRGaWVsZHNTdWJzZXRFcXVhbGl0eVRlc3QpIHsKKyAgLy8gU3BlY2lmeSBhIHNldCBvZiBmaWVsZHMgdG8gY29tcGFyZS4gQWxsIHRoZSBmaWVsZHMgYXJlIGVxdWFsLgorICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1zZzE7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbXNnMjsKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbXNnMSk7CisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1zZzIpOworCisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBmaWVsZHMxOworICBtc2cxLkdldFJlZmxlY3Rpb24oKS0+TGlzdEZpZWxkcyhtc2cxLCAmZmllbGRzMSk7CisKKyAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+IGNvbXBhcmVfZmllbGRzOworICAvLyBPbmx5IGNvbXBhcmUgdGhlIGZpZWxkIGRlc2NyaXB0b3JzIHdpdGggZXZlbiBpbmRpY2VzLgorICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkczEuc2l6ZSgpOyArK2kpIHsKKyAgICBpZiAoaSAlIDIgPT0gMCkgeworICAgICAgY29tcGFyZV9maWVsZHMucHVzaF9iYWNrKGZpZWxkczFbaV0pOworICAgIH0KKyAgfQorCisgIHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlciBkaWZmZXJlbmNlcjsKKyAgRVhQRUNUX1RSVUUoZGlmZmVyZW5jZXIuQ29tcGFyZVdpdGhGaWVsZHMobXNnMSwgbXNnMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcGFyZV9maWVsZHMsIGNvbXBhcmVfZmllbGRzKSk7Cit9CisKK1RFU1QoTWVzc2FnZURpZmZlcmVuY2VyVGVzdCwKKyAgICAgU3BlY2lmaWVkRmllbGRzU3Vic2V0SWdub3Jlc090aGVyRmllbGREaWZmZXJlbmNlc1Rlc3QpIHsKKyAgLy8gU3BlY2lmeSBhIHNldCBvZiBmaWVsZHMgdG8gY29tcGFyZSwgYnV0IGNsZWFyIGFsbCB0aGUgb3RoZXIgZmllbGRzIGluIG9uZQorICAvLyBvZiB0aGUgbWVzc2FnZXMuIFRoaXMgc2hvdWxkIGZhaWwgYSByZWd1bGFyIGNvbXBhcmUsIGJ1dCBDb21wYXJlV2l0aEZpZWxkcworICAvLyBzaG91bGQgc3VjY2VlZC4KKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtc2cxOworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1zZzI7CisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1zZzEpOworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZtc2cyKTsKKworICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4gZmllbGRzMTsKKyAgY29uc3QgUmVmbGVjdGlvbiogcmVmbGVjdGlvbiA9IG1zZzEuR2V0UmVmbGVjdGlvbigpOworICByZWZsZWN0aW9uLT5MaXN0RmllbGRzKG1zZzEsICZmaWVsZHMxKTsKKworICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4gY29tcGFyZV9maWVsZHM7CisgIC8vIE9ubHkgY29tcGFyZSB0aGUgZmllbGQgZGVzY3JpcHRvcnMgd2l0aCBldmVuIGluZGljZXMuCisgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRzMS5zaXplKCk7ICsraSkgeworICAgIGlmIChpICUgMiA9PSAwKSB7CisgICAgICBjb21wYXJlX2ZpZWxkcy5wdXNoX2JhY2soZmllbGRzMVtpXSk7CisgICAgfSBlbHNlIHsKKyAgICAgIHJlZmxlY3Rpb24tPkNsZWFyRmllbGQoJm1zZzIsIGZpZWxkczFbaV0pOworICAgIH0KKyAgfQorCisgIHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlciBkaWZmZXJlbmNlcjsKKyAgRVhQRUNUX0ZBTFNFKGRpZmZlcmVuY2VyLkNvbXBhcmUobXNnMSwgbXNnMikpOworICBFWFBFQ1RfVFJVRShkaWZmZXJlbmNlci5Db21wYXJlV2l0aEZpZWxkcyhtc2cxLCBtc2cyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wYXJlX2ZpZWxkcywgY29tcGFyZV9maWVsZHMpKTsKK30KKworVEVTVChNZXNzYWdlRGlmZmVyZW5jZXJUZXN0LCBTcGVjaWZpZWRGaWVsZHNEZXRlY3RzRGlmZmVyZW5jZXNUZXN0KSB7CisgIC8vIENoYW5nZSBhbGwgb2YgdGhlIHJlcGVhdGVkIGZpZWxkcyBpbiBvbmUgb2YgdGhlIG1lc3NhZ2VzLCBhbmQgdXNlIG9ubHkKKyAgLy8gdGhvc2UgZmllbGRzIGZvciBjb21wYXJpc29uLgorICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1zZzE7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgbXNnMjsKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbXNnMSk7CisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1zZzIpOworICBUZXN0VXRpbDo6TW9kaWZ5UmVwZWF0ZWRGaWVsZHMoJm1zZzIpOworCisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBmaWVsZHMxOworICBtc2cxLkdldFJlZmxlY3Rpb24oKS0+TGlzdEZpZWxkcyhtc2cxLCAmZmllbGRzMSk7CisKKyAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+IGNvbXBhcmVfZmllbGRzOworICAvLyBPbmx5IGNvbXBhcmUgdGhlIHJlcGVhdGVkIGZpZWxkIGRlc2NyaXB0b3JzLgorICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkczEuc2l6ZSgpOyArK2kpIHsKKyAgICBpZiAoZmllbGRzMVtpXS0+aXNfcmVwZWF0ZWQoKSkgeworICAgICAgY29tcGFyZV9maWVsZHMucHVzaF9iYWNrKGZpZWxkczFbaV0pOworICAgIH0KKyAgfQorCisgIHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlciBkaWZmZXJlbmNlcjsKKyAgRVhQRUNUX0ZBTFNFKGRpZmZlcmVuY2VyLkNvbXBhcmVXaXRoRmllbGRzKG1zZzEsIG1zZzIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wYXJlX2ZpZWxkcywgY29tcGFyZV9maWVsZHMpKTsKK30KKworVEVTVChNZXNzYWdlRGlmZmVyZW5jZXJUZXN0LCBTcGVjaWZpZWRGaWVsZHNFcXVpdmFsZW5jZUFsbFRlc3QpIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtc2cxOworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1zZzI7CisKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkcygmbXNnMSk7CisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1zZzIpOworCisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBmaWVsZHMxOworICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4gZmllbGRzMjsKKyAgbXNnMS5HZXRSZWZsZWN0aW9uKCktPkxpc3RGaWVsZHMobXNnMSwgJmZpZWxkczEpOworICBtc2cyLkdldFJlZmxlY3Rpb24oKS0+TGlzdEZpZWxkcyhtc2cyLCAmZmllbGRzMik7CisKKyAgdXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyIGRpZmZlcmVuY2VyOworICBkaWZmZXJlbmNlci5zZXRfbWVzc2FnZV9maWVsZF9jb21wYXJpc29uKAorICAgICAgdXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyOjpFUVVJVkFMRU5UKTsKKyAgRVhQRUNUX1RSVUUoZGlmZmVyZW5jZXIuQ29tcGFyZVdpdGhGaWVsZHMobXNnMSwgbXNnMiwgZmllbGRzMSwgZmllbGRzMikpOworfQorCitURVNUKE1lc3NhZ2VEaWZmZXJlbmNlclRlc3QsCisgICAgIFNwZWNpZmllZEZpZWxkc0VxdWl2YWxlbmNlSWdub3Jlc090aGVyRmllbGREaWZmZXJlbmNlc1Rlc3QpIHsKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBtc2cxOworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1zZzI7CisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2MgPSBtc2cxLkdldERlc2NyaXB0b3IoKTsKKworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIG9wdGlvbmFsX2ludDMyX2Rlc2MgPQorICAgICAgZGVzYy0+RmluZEZpZWxkQnlOYW1lKCJvcHRpb25hbF9pbnQzMiIpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIG9wdGlvbmFsX2ludDY0X2Rlc2MgPQorICAgICAgZGVzYy0+RmluZEZpZWxkQnlOYW1lKCJvcHRpb25hbF9pbnQ2NCIpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlZmF1bHRfaW50NjRfZGVzYyA9CisgICAgICBkZXNjLT5GaW5kRmllbGRCeU5hbWUoImRlZmF1bHRfaW50NjQiKTsKKyAgQVNTRVJUX1RSVUUob3B0aW9uYWxfaW50MzJfZGVzYyAhPSBOVUxMKTsKKyAgQVNTRVJUX1RSVUUob3B0aW9uYWxfaW50NjRfZGVzYyAhPSBOVUxMKTsKKyAgQVNTRVJUX1RSVUUoZGVmYXVsdF9pbnQ2NF9kZXNjICE9IE5VTEwpOworICBtc2cxLnNldF9vcHRpb25hbF9pbnQzMigwKTsKKyAgbXNnMi5zZXRfb3B0aW9uYWxfaW50NjQoMCk7CisgIG1zZzEuc2V0X2RlZmF1bHRfaW50NjQoZGVmYXVsdF9pbnQ2NF9kZXNjLT5kZWZhdWx0X3ZhbHVlX2ludDY0KCkpOworCisgIC8vIFNldCBhIGZpZWxkIHRvIGEgbm9uLWRlZmF1bHQgdmFsdWUgc28gd2Uga25vdyB0aGF0IGZpZWxkIHNlbGVjdGlvbiBpcworICAvLyBhY3R1YWxseSBkb2luZyBzb21ldGhpbmcuCisgIG1zZzIuc2V0X29wdGlvbmFsX3VpbnQ2NCgyMyk7CisKKyAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+IGZpZWxkczE7CisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBmaWVsZHMyOworICBmaWVsZHMxLnB1c2hfYmFjayhvcHRpb25hbF9pbnQzMl9kZXNjKTsKKyAgZmllbGRzMS5wdXNoX2JhY2soZGVmYXVsdF9pbnQ2NF9kZXNjKTsKKworICBmaWVsZHMyLnB1c2hfYmFjayhvcHRpb25hbF9pbnQ2NF9kZXNjKTsKKworICB1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXIgZGlmZmVyZW5jZXI7CisgIEVYUEVDVF9GQUxTRShkaWZmZXJlbmNlci5Db21wYXJlV2l0aEZpZWxkcyhtc2cxLCBtc2cyLCBmaWVsZHMxLCBmaWVsZHMyKSk7CisgIGRpZmZlcmVuY2VyLnNldF9tZXNzYWdlX2ZpZWxkX2NvbXBhcmlzb24oCisgICAgICB1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXI6OkVRVUlWQUxFTlQpOworICBFWFBFQ1RfRkFMU0UoZGlmZmVyZW5jZXIuQ29tcGFyZShtc2cxLCBtc2cyKSk7CisgIEVYUEVDVF9UUlVFKGRpZmZlcmVuY2VyLkNvbXBhcmVXaXRoRmllbGRzKG1zZzEsIG1zZzIsIGZpZWxkczEsIGZpZWxkczIpKTsKK30KKworVEVTVChNZXNzYWdlRGlmZmVyZW5jZXJUZXN0LCBSZXBlYXRlZEZpZWxkU2V0VGVzdF9TZXRPZlNldCkgeworICAvLyBDcmVhdGUgdGhlIHRlc3RpbmcgcHJvdG9zCisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0RGlmZk1lc3NhZ2UgbXNnMTsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3REaWZmTWVzc2FnZSBtc2cyOworCisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0RGlmZk1lc3NhZ2U6Okl0ZW0qIGl0ZW0gPSBtc2cxLmFkZF9pdGVtKCk7CisgIGl0ZW0tPmFkZF9yYSgxKTsgaXRlbS0+YWRkX3JhKDIpOyBpdGVtLT5hZGRfcmEoMyk7CisgIGl0ZW0gPSBtc2cxLmFkZF9pdGVtKCk7CisgIGl0ZW0tPmFkZF9yYSg1KTsgaXRlbS0+YWRkX3JhKDYpOworICBpdGVtID0gbXNnMS5hZGRfaXRlbSgpOworICBpdGVtLT5hZGRfcmEoMSk7IGl0ZW0tPmFkZF9yYSgzKTsKKyAgaXRlbSA9IG1zZzEuYWRkX2l0ZW0oKTsKKyAgaXRlbS0+YWRkX3JhKDYpOyBpdGVtLT5hZGRfcmEoNyk7IGl0ZW0tPmFkZF9yYSg4KTsKKworICBpdGVtID0gbXNnMi5hZGRfaXRlbSgpOworICBpdGVtLT5hZGRfcmEoNik7IGl0ZW0tPmFkZF9yYSg1KTsKKyAgaXRlbSA9IG1zZzIuYWRkX2l0ZW0oKTsKKyAgaXRlbS0+YWRkX3JhKDYpOyBpdGVtLT5hZGRfcmEoOCk7IGl0ZW0tPmFkZF9yYSg3KTsKKyAgaXRlbSA9IG1zZzIuYWRkX2l0ZW0oKTsKKyAgaXRlbS0+YWRkX3JhKDEpOyBpdGVtLT5hZGRfcmEoMyk7CisgIGl0ZW0gPSBtc2cyLmFkZF9pdGVtKCk7CisgIGl0ZW0tPmFkZF9yYSgzKTsgaXRlbS0+YWRkX3JhKDIpOyBpdGVtLT5hZGRfcmEoMSk7CisKKyAgLy8gQ29tcGFyZQorICB1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXIgZGlmZmVyZW5jZXI7CisgIGRpZmZlcmVuY2VyLnNldF9yZXBlYXRlZF9maWVsZF9jb21wYXJpc29uKHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlcjo6QVNfU0VUKTsKKyAgRVhQRUNUX1RSVUUoZGlmZmVyZW5jZXIuQ29tcGFyZShtc2cxLCBtc2cyKSk7Cit9CisKK1RFU1QoTWVzc2FnZURpZmZlcmVuY2VyVGVzdCwgUmVwZWF0ZWRGaWVsZFNldFRlc3RfQ29tYmluYXRpb24pIHsKKyAgLy8gQ3JlYXRlIHRoZSB0ZXN0aW5nIHByb3RvcworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdERpZmZNZXNzYWdlIG1zZzE7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0RGlmZk1lc3NhZ2UgbXNnMjsKKyAgLy8gVHJlYXQgIml0ZW0iIGFzIE1hcCwgd2l0aCBrZXkgPSAiYSIKKyAgLy8gVHJlYXQgIml0ZW0ucmEiIGFsc28gYXMgU2V0CisgIC8vIFRyZWF0ICJydiIgYXMgU2V0CisgIC8vIFRyZWF0ICJydyIgYXMgTGlzdAorICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdERpZmZNZXNzYWdlOjpJdGVtKiBpdGVtID0gbXNnMS5hZGRfaXRlbSgpOworICBpdGVtLT5zZXRfYSgzKTsKKyAgaXRlbS0+YWRkX3JhKDEpOyBpdGVtLT5hZGRfcmEoMik7IGl0ZW0tPmFkZF9yYSgzKTsKKyAgaXRlbSA9IG1zZzEuYWRkX2l0ZW0oKTsKKyAgaXRlbS0+c2V0X2EoNCk7CisgIGl0ZW0tPmFkZF9yYSg1KTsgaXRlbS0+YWRkX3JhKDYpOworICBpdGVtID0gbXNnMS5hZGRfaXRlbSgpOworICBpdGVtLT5zZXRfYSgxKTsKKyAgaXRlbS0+YWRkX3JhKDEpOyBpdGVtLT5hZGRfcmEoMyk7CisgIGl0ZW0gPSBtc2cxLmFkZF9pdGVtKCk7CisgIGl0ZW0tPnNldF9hKDIpOworICBpdGVtLT5hZGRfcmEoNik7IGl0ZW0tPmFkZF9yYSg3KTsgaXRlbS0+YWRkX3JhKDgpOworCisgIGl0ZW0gPSBtc2cyLmFkZF9pdGVtKCk7CisgIGl0ZW0tPnNldF9hKDQpOworICBpdGVtLT5hZGRfcmEoNik7IGl0ZW0tPmFkZF9yYSg1KTsKKyAgaXRlbSA9IG1zZzIuYWRkX2l0ZW0oKTsKKyAgaXRlbS0+c2V0X2EoMik7CisgIGl0ZW0tPmFkZF9yYSg2KTsgaXRlbS0+YWRkX3JhKDgpOyBpdGVtLT5hZGRfcmEoNyk7CisgIGl0ZW0gPSBtc2cyLmFkZF9pdGVtKCk7CisgIGl0ZW0tPnNldF9hKDEpOworICBpdGVtLT5hZGRfcmEoMSk7IGl0ZW0tPmFkZF9yYSgzKTsKKyAgaXRlbSA9IG1zZzIuYWRkX2l0ZW0oKTsKKyAgaXRlbS0+c2V0X2EoMyk7CisgIGl0ZW0tPmFkZF9yYSgzKTsgaXRlbS0+YWRkX3JhKDIpOyBpdGVtLT5hZGRfcmEoMSk7CisKKyAgbXNnMS5hZGRfcnYoMyk7CisgIG1zZzEuYWRkX3J2KDQpOworICBtc2cxLmFkZF9ydig3KTsKKyAgbXNnMS5hZGRfcnYoMCk7CisgIG1zZzIuYWRkX3J2KDQpOworICBtc2cyLmFkZF9ydigzKTsKKyAgbXNnMi5hZGRfcnYoMCk7CisgIG1zZzIuYWRkX3J2KDcpOworCisgIG1zZzEuYWRkX3J3KCJub3RoaW5nIik7IG1zZzIuYWRkX3J3KCJub3RoaW5nIik7CisgIG1zZzEuYWRkX3J3KCJzaG91bGQiKTsgbXNnMi5hZGRfcncoInNob3VsZCIpOworICBtc2cxLmFkZF9ydygiY2hhbmdlIik7IG1zZzIuYWRkX3J3KCJjaGFuZ2UiKTsKKworICAvLyBDb21wYXJlCisgIHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlciBkaWZmZXJlbmNlcjE7CisgIGRpZmZlcmVuY2VyMS5UcmVhdEFzTWFwKG1zZzEuR2V0RGVzY3JpcHRvcigpLT5GaW5kRmllbGRCeU5hbWUoIml0ZW0iKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbS0+R2V0RGVzY3JpcHRvcigpLT5GaW5kRmllbGRCeU5hbWUoImEiKSk7CisgIGRpZmZlcmVuY2VyMS5UcmVhdEFzU2V0KG1zZzEuR2V0RGVzY3JpcHRvcigpLT5GaW5kRmllbGRCeU5hbWUoInJ2IikpOworICBkaWZmZXJlbmNlcjEuVHJlYXRBc1NldChpdGVtLT5HZXREZXNjcmlwdG9yKCktPkZpbmRGaWVsZEJ5TmFtZSgicmEiKSk7CisgIEVYUEVDVF9UUlVFKGRpZmZlcmVuY2VyMS5Db21wYXJlKG1zZzEsIG1zZzIpKTsKKworICB1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXIgZGlmZmVyZW5jZXIyOworICBkaWZmZXJlbmNlcjIuVHJlYXRBc01hcChtc2cxLkdldERlc2NyaXB0b3IoKS0+RmluZEZpZWxkQnlOYW1lKCJpdGVtIiksCisgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0tPkdldERlc2NyaXB0b3IoKS0+RmluZEZpZWxkQnlOYW1lKCJhIikpOworICBkaWZmZXJlbmNlcjIuc2V0X3JlcGVhdGVkX2ZpZWxkX2NvbXBhcmlzb24odXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyOjpBU19TRVQpOworICBkaWZmZXJlbmNlcjIuVHJlYXRBc0xpc3QobXNnMS5HZXREZXNjcmlwdG9yKCktPkZpbmRGaWVsZEJ5TmFtZSgicnciKSk7CisgIEVYUEVDVF9UUlVFKGRpZmZlcmVuY2VyMi5Db21wYXJlKG1zZzEsIG1zZzIpKTsKK30KKworVEVTVChNZXNzYWdlRGlmZmVyZW5jZXJUZXN0LCBSZXBlYXRlZEZpZWxkTWFwVGVzdF9QYXJ0aWFsKSB7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0RGlmZk1lc3NhZ2UgbXNnMTsKKyAgLy8gbWVzc2FnZSBtc2cxIHsKKyAgLy8gICBpdGVtIHsgYTogMTsgYjogIjExIiB9CisgIC8vIH0KKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3REaWZmTWVzc2FnZTo6SXRlbSogaXRlbSA9IG1zZzEuYWRkX2l0ZW0oKTsKKyAgaXRlbS0+c2V0X2EoMSk7CisgIGl0ZW0tPnNldF9iKCIxMSIpOworCisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0RGlmZk1lc3NhZ2UgbXNnMjsKKyAgLy8gbWVzc2FnZSBtc2cyIHsKKyAgLy8gICBpdGVtIHsgYTogMjsgYjogIjIyIiB9CisgIC8vICAgaXRlbSB7IGE6IDE7IGI6ICIxMSIgfQorICAvLyB9CisgIGl0ZW0gPSBtc2cyLmFkZF9pdGVtKCk7CisgIGl0ZW0tPnNldF9hKDIpOworICBpdGVtLT5zZXRfYigiMjIiKTsKKyAgaXRlbSA9IG1zZzIuYWRkX2l0ZW0oKTsKKyAgaXRlbS0+c2V0X2EoMSk7CisgIGl0ZW0tPnNldF9iKCIxMSIpOworCisgIC8vIENvbXBhcmUKKyAgdXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyIGRpZmZlcmVuY2VyOworICBkaWZmZXJlbmNlci5UcmVhdEFzTWFwKEdldEZpZWxkRGVzY3JpcHRvcihtc2cxLCAiaXRlbSIpLAorICAgICAgICAgICAgICAgICAgICAgICAgIEdldEZpZWxkRGVzY3JpcHRvcihtc2cxLCAiaXRlbS5hIikpOworICBkaWZmZXJlbmNlci5zZXRfc2NvcGUodXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyOjpQQVJUSUFMKTsKKyAgRVhQRUNUX1RSVUUoZGlmZmVyZW5jZXIuQ29tcGFyZShtc2cxLCBtc2cyKSk7Cit9CisKK1RFU1QoTWVzc2FnZURpZmZlcmVuY2VyVGVzdCwgUmVwZWF0ZWRGaWVsZFNldFRlc3RfRHVwbGljYXRlcykgeworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdERpZmZNZXNzYWdlIGEsIGIsIGM7CisgIC8vIG1lc3NhZ2UgYTogeworICAvLyAgIHJ2OiAwCisgIC8vICAgcnY6IDEKKyAgLy8gICBydjogMAorICAvLyB9CisgIGEuYWRkX3J2KDApOworICBhLmFkZF9ydigxKTsKKyAgYS5hZGRfcnYoMCk7CisgIC8vIG1lc3NhZ2UgYjogeworICAvLyAgIHJ2OiAwCisgIC8vICAgcnY6IDAKKyAgLy8gICBydjogMQorICAvLyB9CisgIGIuYWRkX3J2KDApOworICBiLmFkZF9ydigwKTsKKyAgYi5hZGRfcnYoMSk7CisgIC8vIG1lc3NhZ2UgYzogeworICAvLyAgIHJ2OiAwCisgIC8vICAgcnY6IDEKKyAgLy8gfQorICBjLmFkZF9ydigwKTsKKyAgYy5hZGRfcnYoMSk7CisgIHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlciBkaWZmZXJlbmNlcjsKKyAgZGlmZmVyZW5jZXIuVHJlYXRBc1NldChHZXRGaWVsZERlc2NyaXB0b3IoYSwgInJ2IikpOworICBFWFBFQ1RfVFJVRShkaWZmZXJlbmNlci5Db21wYXJlKGIsIGEpKTsKKyAgRVhQRUNUX0ZBTFNFKGRpZmZlcmVuY2VyLkNvbXBhcmUoYywgYSkpOworCisgIHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlciBkaWZmZXJlbmNlcjE7CisgIGRpZmZlcmVuY2VyMS5zZXRfcmVwZWF0ZWRfZmllbGRfY29tcGFyaXNvbih1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXI6OkFTX1NFVCk7CisgIEVYUEVDVF9UUlVFKGRpZmZlcmVuY2VyMS5Db21wYXJlKGIsIGEpKTsKKyAgRVhQRUNUX0ZBTFNFKGRpZmZlcmVuY2VyMS5Db21wYXJlKGMsIGEpKTsKK30KKworVEVTVChNZXNzYWdlRGlmZmVyZW5jZXJUZXN0LCBSZXBlYXRlZEZpZWxkU2V0VGVzdF9QYXJ0aWFsU2ltcGxlKSB7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0RGlmZk1lc3NhZ2UgYSwgYiwgYzsKKyAgLy8gbWVzc2FnZSBhOiB7CisgIC8vICAgcm0geyBjOiAxIH0KKyAgLy8gICBybSB7IGM6IDAgfQorICAvLyB9CisgIGEuYWRkX3JtKCktPnNldF9jKDEpOworICBhLmFkZF9ybSgpLT5zZXRfYygwKTsKKyAgLy8gbWVzc2FnZSBiOiB7CisgIC8vICAgcm0geyBjOiAxIH0KKyAgLy8gICBybSB7fQorICAvLyB9CisgIGIuYWRkX3JtKCktPnNldF9jKDEpOworICBiLmFkZF9ybSgpOworICAvLyBtZXNzYWdlIGM6IHsKKyAgLy8gICBybSB7fQorICAvLyAgIHJtIHsgYzogMSB9CisgIC8vIH0KKyAgYy5hZGRfcm0oKTsKKyAgYy5hZGRfcm0oKS0+c2V0X2MoMSk7CisgIHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlciBkaWZmZXJlbmNlcjsKKyAgZGlmZmVyZW5jZXIuc2V0X3Njb3BlKHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlcjo6UEFSVElBTCk7CisgIGRpZmZlcmVuY2VyLlRyZWF0QXNTZXQoR2V0RmllbGREZXNjcmlwdG9yKGEsICJybSIpKTsKKyAgRVhQRUNUX1RSVUUoZGlmZmVyZW5jZXIuQ29tcGFyZShiLCBhKSk7CisgIEVYUEVDVF9UUlVFKGRpZmZlcmVuY2VyLkNvbXBhcmUoYywgYSkpOworfQorCitURVNUKE1lc3NhZ2VEaWZmZXJlbmNlclRlc3QsIFJlcGVhdGVkRmllbGRTZXRUZXN0X1BhcnRpYWwpIHsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3REaWZmTWVzc2FnZSBtc2cxLCBtc2cyOworICAvLyBtZXNzYWdlIG1zZzE6IHsKKyAgLy8gICBybSB7IGE6IDEgfQorICAvLyAgIHJtIHsgYjogMiB9CisgIC8vICAgcm0geyBjOiAzIH0KKyAgLy8gfQorICBtc2cxLmFkZF9ybSgpLT5zZXRfYSgxKTsKKyAgbXNnMS5hZGRfcm0oKS0+c2V0X2IoMik7CisgIG1zZzEuYWRkX3JtKCktPnNldF9jKDMpOworICAvLyBtZXNzYWdlIG1zZzI6IHsKKyAgLy8gICBybSB7IGE6IDE7IGM6IDMgfQorICAvLyAgIHJtIHsgYjogMjsgYzogMyB9CisgIC8vICAgcm0geyBiOiAyIH0KKyAgLy8gfQorICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEZpZWxkKiBmaWVsZCA9IG1zZzIuYWRkX3JtKCk7CisgIGZpZWxkLT5zZXRfYSgxKTsKKyAgZmllbGQtPnNldF9jKDMpOworICBmaWVsZCA9IG1zZzIuYWRkX3JtKCk7CisgIGZpZWxkLT5zZXRfYigyKTsKKyAgZmllbGQtPnNldF9jKDMpOworICBmaWVsZCA9IG1zZzIuYWRkX3JtKCk7CisgIGZpZWxkLT5zZXRfYigyKTsKKworICB1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXIgZGlmZmVyZW5jZXI7CisgIGRpZmZlcmVuY2VyLnNldF9zY29wZSh1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXI6OlBBUlRJQUwpOworICBkaWZmZXJlbmNlci5UcmVhdEFzU2V0KEdldEZpZWxkRGVzY3JpcHRvcihtc2cxLCAicm0iKSk7CisgIEVYUEVDVF9UUlVFKGRpZmZlcmVuY2VyLkNvbXBhcmUobXNnMSwgbXNnMikpOworfQorCitURVNUKE1lc3NhZ2VEaWZmZXJlbmNlclRlc3QsIFJlcGVhdGVkRmllbGRNYXBUZXN0X011bHRpcGxlRmllbGRzQXNLZXkpIHsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3REaWZmTWVzc2FnZSBtc2cxOworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdERpZmZNZXNzYWdlIG1zZzI7CisgIC8vIFRyZWF0ICJpdGVtIiBhcyBNYXAsIHdpdGgga2V5ID0gKCJhIiwgInJhIikKKyAgLy8gVHJlYXQgIml0ZW0ucmEiIGFzIFNldAorICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdERpZmZNZXNzYWdlOjpJdGVtKiBpdGVtID0gbXNnMS5hZGRfaXRlbSgpOworICAvLyBrZXkgPT4gdmFsdWU6ICgxLCB7MiwgM30pID0+ICJhIgorICBpdGVtLT5zZXRfYSgxKTsKKyAgaXRlbS0+YWRkX3JhKDIpOworICBpdGVtLT5hZGRfcmEoMyk7CisgIGl0ZW0tPnNldF9iKCJhIik7CisgIGl0ZW0gPSBtc2cxLmFkZF9pdGVtKCk7CisgIC8vIGtleSA9PiB2YWx1ZTogKDIsIHsxLCAzfSkgPT4gImIiCisgIGl0ZW0tPnNldF9hKDIpOworICBpdGVtLT5hZGRfcmEoMSk7CisgIGl0ZW0tPmFkZF9yYSgzKTsKKyAgaXRlbS0+c2V0X2IoImIiKTsKKyAgaXRlbSA9IG1zZzEuYWRkX2l0ZW0oKTsKKyAgLy8ga2V5ID0+IHZhbHVlOiAoMSwgezEsIDN9KSA9PiAiYyIKKyAgaXRlbS0+c2V0X2EoMSk7CisgIGl0ZW0tPmFkZF9yYSgxKTsKKyAgaXRlbS0+YWRkX3JhKDMpOworICBpdGVtLT5zZXRfYigiYyIpOworCisgIGl0ZW0gPSBtc2cyLmFkZF9pdGVtKCk7CisgIC8vIGtleSA9PiB2YWx1ZTogKDEsIHsxLCAzfSkgPT4gImMiCisgIGl0ZW0tPnNldF9hKDEpOworICBpdGVtLT5hZGRfcmEoMyk7CisgIGl0ZW0tPmFkZF9yYSgxKTsKKyAgaXRlbS0+c2V0X2IoImMiKTsKKyAgaXRlbSA9IG1zZzIuYWRkX2l0ZW0oKTsKKyAgLy8ga2V5ID0+IHZhbHVlOiAoMSwgezIsIDN9KSA9PiAiYSIKKyAgaXRlbS0+c2V0X2EoMSk7CisgIGl0ZW0tPmFkZF9yYSgzKTsKKyAgaXRlbS0+YWRkX3JhKDIpOworICBpdGVtLT5zZXRfYigiYSIpOworICBpdGVtID0gbXNnMi5hZGRfaXRlbSgpOworICAvLyBrZXkgPT4gdmFsdWU6ICgyLCB7MSwgM30pID0+ICJiIgorICBpdGVtLT5zZXRfYSgyKTsKKyAgaXRlbS0+YWRkX3JhKDMpOworICBpdGVtLT5hZGRfcmEoMSk7CisgIGl0ZW0tPnNldF9iKCJiIik7CisKKyAgLy8gQ29tcGFyZQorICB1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXIgZGlmZmVyZW5jZXI7CisgIGRpZmZlcmVuY2VyLlRyZWF0QXNTZXQoR2V0RmllbGREZXNjcmlwdG9yKG1zZzEsICJpdGVtLnJhIikpOworICBFWFBFQ1RfRkFMU0UoZGlmZmVyZW5jZXIuQ29tcGFyZShtc2cxLCBtc2cyKSk7CisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBrZXlfZmllbGRzOworICBrZXlfZmllbGRzLnB1c2hfYmFjayhHZXRGaWVsZERlc2NyaXB0b3IobXNnMSwgIml0ZW0uYSIpKTsKKyAga2V5X2ZpZWxkcy5wdXNoX2JhY2soR2V0RmllbGREZXNjcmlwdG9yKG1zZzEsICJpdGVtLnJhIikpOworICBkaWZmZXJlbmNlci5UcmVhdEFzTWFwV2l0aE11bHRpcGxlRmllbGRzQXNLZXkoCisgICAgICBHZXRGaWVsZERlc2NyaXB0b3IobXNnMSwgIml0ZW0iKSwga2V5X2ZpZWxkcyk7CisgIEVYUEVDVF9UUlVFKGRpZmZlcmVuY2VyLkNvbXBhcmUobXNnMSwgbXNnMikpOworCisgIC8vIEludHJvZHVjZSBzb21lIGRpZmZlcmVuY2VzLgorICBtc2cxLmNsZWFyX2l0ZW0oKTsKKyAgbXNnMi5jbGVhcl9pdGVtKCk7CisgIGl0ZW0gPSBtc2cxLmFkZF9pdGVtKCk7CisgIGl0ZW0tPnNldF9hKDQpOworICBpdGVtLT5hZGRfcmEoNSk7CisgIGl0ZW0tPmFkZF9yYSg2KTsKKyAgaXRlbS0+c2V0X2IoImhlbGxvIik7CisgIGl0ZW0gPSBtc2cyLmFkZF9pdGVtKCk7CisgIGl0ZW0tPnNldF9hKDQpOworICBpdGVtLT5hZGRfcmEoNik7CisgIGl0ZW0tPmFkZF9yYSg1KTsKKyAgaXRlbS0+c2V0X2IoIndvcmxkIik7CisgIHN0cmluZyBvdXRwdXQ7CisgIGRpZmZlcmVuY2VyLlJlcG9ydERpZmZlcmVuY2VzVG9TdHJpbmcoJm91dHB1dCk7CisgIEVYUEVDVF9GQUxTRShkaWZmZXJlbmNlci5Db21wYXJlKG1zZzEsIG1zZzIpKTsKKyAgRVhQRUNUX0VRKAorICAgICAgIm1vdmVkOiBpdGVtWzBdLnJhWzBdIC0+IGl0ZW1bMF0ucmFbMV0gOiA1XG4iCisgICAgICAibW92ZWQ6IGl0ZW1bMF0ucmFbMV0gLT4gaXRlbVswXS5yYVswXSA6IDZcbiIKKyAgICAgICJtb2RpZmllZDogaXRlbVswXS5iOiBcImhlbGxvXCIgLT4gXCJ3b3JsZFwiXG4iLAorICAgICAgb3V0cHV0KTsKK30KKworVEVTVChNZXNzYWdlRGlmZmVyZW5jZXJUZXN0LCBSZXBlYXRlZEZpZWxkTWFwVGVzdF9NdWx0aXBsZUZpZWxkUGF0aHNBc0tleSkgeworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdERpZmZNZXNzYWdlIG1zZzE7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0RGlmZk1lc3NhZ2UgbXNnMjsKKyAgLy8gVHJlYXQgIml0ZW0iIGFzIE1hcCwgd2l0aCBrZXkgPSAoIm0uYSIsICJtLnJjIikKKyAgLy8gVHJlYXQgIml0ZW0ubS5yYyIgYXMgU2V0CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0RGlmZk1lc3NhZ2U6Okl0ZW0qIGl0ZW0gPSBtc2cxLmFkZF9pdGVtKCk7CisgIC8vIGtleSA9PiB2YWx1ZTogKDEsIHsyLCAzfSkgPT4gImEiCisgIGl0ZW0tPm11dGFibGVfbSgpLT5zZXRfYSgxKTsKKyAgaXRlbS0+bXV0YWJsZV9tKCktPmFkZF9yYygyKTsKKyAgaXRlbS0+bXV0YWJsZV9tKCktPmFkZF9yYygzKTsKKyAgaXRlbS0+c2V0X2IoImEiKTsKKyAgaXRlbSA9IG1zZzEuYWRkX2l0ZW0oKTsKKyAgLy8ga2V5ID0+IHZhbHVlOiAoMiwgezEsIDN9KSA9PiAiYiIKKyAgaXRlbS0+bXV0YWJsZV9tKCktPnNldF9hKDIpOworICBpdGVtLT5tdXRhYmxlX20oKS0+YWRkX3JjKDEpOworICBpdGVtLT5tdXRhYmxlX20oKS0+YWRkX3JjKDMpOworICBpdGVtLT5zZXRfYigiYiIpOworICBpdGVtID0gbXNnMS5hZGRfaXRlbSgpOworICAvLyBrZXkgPT4gdmFsdWU6ICgxLCB7MSwgM30pID0+ICJjIgorICBpdGVtLT5tdXRhYmxlX20oKS0+c2V0X2EoMSk7CisgIGl0ZW0tPm11dGFibGVfbSgpLT5hZGRfcmMoMSk7CisgIGl0ZW0tPm11dGFibGVfbSgpLT5hZGRfcmMoMyk7CisgIGl0ZW0tPnNldF9iKCJjIik7CisKKyAgaXRlbSA9IG1zZzIuYWRkX2l0ZW0oKTsKKyAgLy8ga2V5ID0+IHZhbHVlOiAoMSwgezEsIDN9KSA9PiAiYyIKKyAgaXRlbS0+bXV0YWJsZV9tKCktPnNldF9hKDEpOworICBpdGVtLT5tdXRhYmxlX20oKS0+YWRkX3JjKDMpOworICBpdGVtLT5tdXRhYmxlX20oKS0+YWRkX3JjKDEpOworICBpdGVtLT5zZXRfYigiYyIpOworICBpdGVtID0gbXNnMi5hZGRfaXRlbSgpOworICAvLyBrZXkgPT4gdmFsdWU6ICgxLCB7MiwgM30pID0+ICJhIgorICBpdGVtLT5tdXRhYmxlX20oKS0+c2V0X2EoMSk7CisgIGl0ZW0tPm11dGFibGVfbSgpLT5hZGRfcmMoMyk7CisgIGl0ZW0tPm11dGFibGVfbSgpLT5hZGRfcmMoMik7CisgIGl0ZW0tPnNldF9iKCJhIik7CisgIGl0ZW0gPSBtc2cyLmFkZF9pdGVtKCk7CisgIC8vIGtleSA9PiB2YWx1ZTogKDIsIHsxLCAzfSkgPT4gImIiCisgIGl0ZW0tPm11dGFibGVfbSgpLT5zZXRfYSgyKTsKKyAgaXRlbS0+bXV0YWJsZV9tKCktPmFkZF9yYygzKTsKKyAgaXRlbS0+bXV0YWJsZV9tKCktPmFkZF9yYygxKTsKKyAgaXRlbS0+c2V0X2IoImIiKTsKKworICAvLyBDb21wYXJlCisgIHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlciBkaWZmZXJlbmNlcjsKKyAgZGlmZmVyZW5jZXIuVHJlYXRBc1NldChHZXRGaWVsZERlc2NyaXB0b3IobXNnMSwgIml0ZW0ubS5yYyIpKTsKKyAgRVhQRUNUX0ZBTFNFKGRpZmZlcmVuY2VyLkNvbXBhcmUobXNnMSwgbXNnMikpOworICB2ZWN0b3I8dmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+ID4ga2V5X2ZpZWxkX3BhdGhzOworICB2ZWN0b3I8Y29uc3QgRmllbGREZXNjcmlwdG9yKj4ga2V5X2ZpZWxkX3BhdGgxOworICBrZXlfZmllbGRfcGF0aDEucHVzaF9iYWNrKEdldEZpZWxkRGVzY3JpcHRvcihtc2cxLCAiaXRlbS5tIikpOworICBrZXlfZmllbGRfcGF0aDEucHVzaF9iYWNrKEdldEZpZWxkRGVzY3JpcHRvcihtc2cxLCAiaXRlbS5tLmEiKSk7CisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBrZXlfZmllbGRfcGF0aDI7CisgIGtleV9maWVsZF9wYXRoMi5wdXNoX2JhY2soR2V0RmllbGREZXNjcmlwdG9yKG1zZzEsICJpdGVtLm0iKSk7CisgIGtleV9maWVsZF9wYXRoMi5wdXNoX2JhY2soR2V0RmllbGREZXNjcmlwdG9yKG1zZzEsICJpdGVtLm0ucmMiKSk7CisgIGtleV9maWVsZF9wYXRocy5wdXNoX2JhY2soa2V5X2ZpZWxkX3BhdGgxKTsKKyAga2V5X2ZpZWxkX3BhdGhzLnB1c2hfYmFjayhrZXlfZmllbGRfcGF0aDIpOworICBkaWZmZXJlbmNlci5UcmVhdEFzTWFwV2l0aE11bHRpcGxlRmllbGRQYXRoc0FzS2V5KAorICAgICAgR2V0RmllbGREZXNjcmlwdG9yKG1zZzEsICJpdGVtIiksIGtleV9maWVsZF9wYXRocyk7CisgIEVYUEVDVF9UUlVFKGRpZmZlcmVuY2VyLkNvbXBhcmUobXNnMSwgbXNnMikpOworCisgIC8vIEludHJvZHVjZSBzb21lIGRpZmZlcmVuY2VzLgorICBtc2cxLmNsZWFyX2l0ZW0oKTsKKyAgbXNnMi5jbGVhcl9pdGVtKCk7CisgIGl0ZW0gPSBtc2cxLmFkZF9pdGVtKCk7CisgIGl0ZW0tPm11dGFibGVfbSgpLT5zZXRfYSg0KTsKKyAgaXRlbS0+bXV0YWJsZV9tKCktPmFkZF9yYyg1KTsKKyAgaXRlbS0+bXV0YWJsZV9tKCktPmFkZF9yYyg2KTsKKyAgaXRlbS0+c2V0X2IoImhlbGxvIik7CisgIGl0ZW0gPSBtc2cyLmFkZF9pdGVtKCk7CisgIGl0ZW0tPm11dGFibGVfbSgpLT5zZXRfYSg0KTsKKyAgaXRlbS0+bXV0YWJsZV9tKCktPmFkZF9yYyg2KTsKKyAgaXRlbS0+bXV0YWJsZV9tKCktPmFkZF9yYyg1KTsKKyAgaXRlbS0+c2V0X2IoIndvcmxkIik7CisgIHN0cmluZyBvdXRwdXQ7CisgIGRpZmZlcmVuY2VyLlJlcG9ydERpZmZlcmVuY2VzVG9TdHJpbmcoJm91dHB1dCk7CisgIEVYUEVDVF9GQUxTRShkaWZmZXJlbmNlci5Db21wYXJlKG1zZzEsIG1zZzIpKTsKKyAgRVhQRUNUX0VRKAorICAgICAgIm1vZGlmaWVkOiBpdGVtWzBdLmI6IFwiaGVsbG9cIiAtPiBcIndvcmxkXCJcbiIKKyAgICAgICJtb3ZlZDogaXRlbVswXS5tLnJjWzBdIC0+IGl0ZW1bMF0ubS5yY1sxXSA6IDVcbiIKKyAgICAgICJtb3ZlZDogaXRlbVswXS5tLnJjWzFdIC0+IGl0ZW1bMF0ubS5yY1swXSA6IDZcbiIsCisgICAgICBvdXRwdXQpOworfQorCitURVNUKE1lc3NhZ2VEaWZmZXJlbmNlclRlc3QsIFJlcGVhdGVkRmllbGRNYXBUZXN0X0lnbm9yZWRLZXlGaWVsZHMpIHsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3REaWZmTWVzc2FnZSBtc2cxOworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdERpZmZNZXNzYWdlIG1zZzI7CisgIC8vIFRyZWF0ICJpdGVtIiBhcyBNYXAsIHdpdGgga2V5ID0gKCJhIiwgInJhIikKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3REaWZmTWVzc2FnZTo6SXRlbSogaXRlbSA9IG1zZzEuYWRkX2l0ZW0oKTsKKyAgaXRlbS0+c2V0X2EoMSk7CisgIGl0ZW0tPmFkZF9yYSgyKTsKKyAgaXRlbS0+c2V0X2IoImhlbGxvIik7CisgIGl0ZW0gPSBtc2cyLmFkZF9pdGVtKCk7CisgIGl0ZW0tPnNldF9hKDEpOworICBpdGVtLT5hZGRfcmEoMyk7CisgIGl0ZW0tPnNldF9iKCJ3b3JsZCIpOworICAvLyBDb21wYXJlCisgIHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlciBkaWZmZXJlbmNlcjsKKyAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+IGtleV9maWVsZHM7CisgIGtleV9maWVsZHMucHVzaF9iYWNrKEdldEZpZWxkRGVzY3JpcHRvcihtc2cxLCAiaXRlbS5hIikpOworICBrZXlfZmllbGRzLnB1c2hfYmFjayhHZXRGaWVsZERlc2NyaXB0b3IobXNnMSwgIml0ZW0ucmEiKSk7CisgIGRpZmZlcmVuY2VyLlRyZWF0QXNNYXBXaXRoTXVsdGlwbGVGaWVsZHNBc0tleSgKKyAgICAgIEdldEZpZWxkRGVzY3JpcHRvcihtc2cxLCAiaXRlbSIpLCBrZXlfZmllbGRzKTsKKyAgc3RyaW5nIG91dHB1dDsKKyAgZGlmZmVyZW5jZXIuUmVwb3J0RGlmZmVyZW5jZXNUb1N0cmluZygmb3V0cHV0KTsKKyAgRVhQRUNUX0ZBTFNFKGRpZmZlcmVuY2VyLkNvbXBhcmUobXNnMSwgbXNnMikpOworICBFWFBFQ1RfRVEoCisgICAgICAiYWRkZWQ6IGl0ZW1bMF06IHsgYTogMSByYTogMyBiOiBcIndvcmxkXCIgfVxuIgorICAgICAgImRlbGV0ZWQ6IGl0ZW1bMF06IHsgYTogMSByYTogMiBiOiBcImhlbGxvXCIgfVxuIiwKKyAgICAgIG91dHB1dCk7CisgIC8vIElnbm9yZWQgZmllbGRzIHRoYXQgYXJlIGxpc3RlZCBhcyBwYXJ0cyBvZiB0aGUga2V5IGFyZSBzdGlsbCB1c2VkCisgIC8vIGluIGtleSBjb21wYXJpc29uLCBidXQgdGhleSdyZSBub3QgdXNlZCBpbiB2YWx1ZSBjb21wYXJpc29uLgorICBkaWZmZXJlbmNlci5JZ25vcmVGaWVsZChHZXRGaWVsZERlc2NyaXB0b3IobXNnMSwgIml0ZW0ucmEiKSk7CisgIG91dHB1dC5jbGVhcigpOworICBFWFBFQ1RfRkFMU0UoZGlmZmVyZW5jZXIuQ29tcGFyZShtc2cxLCBtc2cyKSk7CisgIEVYUEVDVF9FUSgKKyAgICAgICJhZGRlZDogaXRlbVswXTogeyBhOiAxIHJhOiAzIGI6IFwid29ybGRcIiB9XG4iCisgICAgICAiZGVsZXRlZDogaXRlbVswXTogeyBhOiAxIHJhOiAyIGI6IFwiaGVsbG9cIiB9XG4iLAorICAgICAgb3V0cHV0KTsKKyAgLy8gSWdub3JpbmcgYSBmaWVsZCBpbiB0aGUga2V5IGlzIGRpZmZlcmVudCBmcm9tIHRyZWF0aW5nIHRoZSBsZWZ0IGZpZWxkcworICAvLyBhcyBrZXkuIFRoYXQgaXM6CisgIC8vICAgKGtleSA9ICgiYSIsICJyYSIpICYmIGlnbm9yZSAicmEiKSAhPSAoa2V5ID0gKCJhIikgJiYgaWdub3JlICJyYSIpCisgIHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlciBkaWZmZXJlbmNlcjI7CisgIGRpZmZlcmVuY2VyMi5UcmVhdEFzTWFwKEdldEZpZWxkRGVzY3JpcHRvcihtc2cxLCAiaXRlbSIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICBHZXRGaWVsZERlc2NyaXB0b3IobXNnMSwgIml0ZW0uYSIpKTsKKyAgZGlmZmVyZW5jZXIyLklnbm9yZUZpZWxkKEdldEZpZWxkRGVzY3JpcHRvcihtc2cxLCAiaXRlbS5yYSIpKTsKKyAgb3V0cHV0LmNsZWFyKCk7CisgIGRpZmZlcmVuY2VyMi5SZXBvcnREaWZmZXJlbmNlc1RvU3RyaW5nKCZvdXRwdXQpOworICBFWFBFQ1RfRkFMU0UoZGlmZmVyZW5jZXIyLkNvbXBhcmUobXNnMSwgbXNnMikpOworICBFWFBFQ1RfRVEoCisgICAgICAiaWdub3JlZDogaXRlbVswXS5yYVxuIgorICAgICAgIm1vZGlmaWVkOiBpdGVtWzBdLmI6IFwiaGVsbG9cIiAtPiBcIndvcmxkXCJcbiIsCisgICAgICBvdXRwdXQpOworfQorCitzdGF0aWMgY29uc3QgY2hhciogY29uc3Qga0lnbm9yZWRGaWVsZHNbXSA9IHsicm0uYiIsICJybS5tLmIifTsKKworY2xhc3MgVGVzdElnbm9yZXIgOiBwdWJsaWMgdXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyOjpJZ25vcmVDcml0ZXJpYSB7CisgcHVibGljOgorICB2aXJ0dWFsIGJvb2wgSXNJZ25vcmVkKAorICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZTEsIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UyLAorICAgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICAgIGNvbnN0IHZlY3Rvcjx1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXI6OlNwZWNpZmljRmllbGQ+JiBwYXJlbnRfZmllbGRzKSB7CisgICAgc3RyaW5nIG5hbWUgPSAiIjsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhcmVudF9maWVsZHMuc2l6ZSgpOyArK2kpIHsKKyAgICAgIG5hbWUgKz0gcGFyZW50X2ZpZWxkc1tpXS5maWVsZC0+bmFtZSgpICsgIi4iOworICAgIH0KKyAgICBuYW1lICs9IGZpZWxkLT5uYW1lKCk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBHT09HTEVfQVJSQVlTSVpFKGtJZ25vcmVkRmllbGRzKTsgKytpKSB7CisgICAgICBpZiAobmFtZS5jb21wYXJlKGtJZ25vcmVkRmllbGRzW2ldKSA9PSAwKSB7CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gZmFsc2U7CisgIH0KK307CisKK1RFU1QoTWVzc2FnZURpZmZlcmVuY2VyVGVzdCwgVHJlYXRSZXBlYXRlZEZpZWxkQXNTZXRXaXRoSWdub3JlZEZpZWxkcykgeworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdERpZmZNZXNzYWdlIG1zZzE7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0RGlmZk1lc3NhZ2UgbXNnMjsKKyAgVGV4dEZvcm1hdDo6TWVyZ2VGcm9tU3RyaW5nKCJybSB7IGE6IDExXG4gYjogMTIgfSIsICZtc2cxKTsKKyAgVGV4dEZvcm1hdDo6TWVyZ2VGcm9tU3RyaW5nKCJybSB7IGE6IDExXG4gYjogMTMgfSIsICZtc2cyKTsKKyAgdXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyIGRpZmZlcjsKKyAgZGlmZmVyLlRyZWF0QXNTZXQoR2V0RmllbGREZXNjcmlwdG9yKG1zZzEsICJybSIpKTsKKyAgZGlmZmVyLkFkZElnbm9yZUNyaXRlcmlhKG5ldyBUZXN0SWdub3Jlcik7CisgIEVYUEVDVF9UUlVFKGRpZmZlci5Db21wYXJlKG1zZzEsIG1zZzIpKTsKK30KKworVEVTVChNZXNzYWdlRGlmZmVyZW5jZXJUZXN0LCBUcmVhdFJlcGVhdGVkRmllbGRBc01hcFdpdGhJZ25vcmVkS2V5RmllbGRzKSB7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0RGlmZk1lc3NhZ2UgbXNnMTsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3REaWZmTWVzc2FnZSBtc2cyOworICBUZXh0Rm9ybWF0OjpNZXJnZUZyb21TdHJpbmcoInJtIHsgYTogMTFcbiBtIHsgYTogMTJcbiBiOiAxM1xuIH0gfSIsICZtc2cxKTsKKyAgVGV4dEZvcm1hdDo6TWVyZ2VGcm9tU3RyaW5nKCJybSB7IGE6IDExXG4gbSB7IGE6IDEyXG4gYjogMTRcbiB9IH0iLCAmbXNnMik7CisgIHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlciBkaWZmZXI7CisgIGRpZmZlci5UcmVhdEFzTWFwKEdldEZpZWxkRGVzY3JpcHRvcihtc2cxLCAicm0iKSwKKyAgICAgICAgICAgICAgICAgICAgR2V0RmllbGREZXNjcmlwdG9yKG1zZzEsICJybS5tIikpOworICBkaWZmZXIuQWRkSWdub3JlQ3JpdGVyaWEobmV3IFRlc3RJZ25vcmVyKTsKKyAgRVhQRUNUX1RSVUUoZGlmZmVyLkNvbXBhcmUobXNnMSwgbXNnMikpOworfQorCisvLyBUYWtlcyB0aGUgcHJvZHVjdCBvZiBhbGwgZWxlbWVudHMgb2YgaXRlbS5yYSBhcyB0aGUga2V5IGZvciBrZXkgY29tcGFyaXNvbi4KK2NsYXNzIFZhbHVlUHJvZHVjdE1hcEtleUNvbXBhcmF0b3IKKyAgICA6IHB1YmxpYyB1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXI6Ok1hcEtleUNvbXBhcmF0b3IgeworIHB1YmxpYzoKKyAgdHlwZWRlZiB1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXI6OlNwZWNpZmljRmllbGQgU3BlY2lmaWNGaWVsZDsKKyAgdmlydHVhbCBib29sIElzTWF0Y2goCisgICAgICBjb25zdCBNZXNzYWdlICZtZXNzYWdlMSwgY29uc3QgTWVzc2FnZSAmbWVzc2FnZTIsCisgICAgICBjb25zdCB2ZWN0b3I8U3BlY2lmaWNGaWVsZD4mIHBhcmVudF9maWVsZHMpIGNvbnN0IHsKKyAgICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uMSA9IG1lc3NhZ2UxLkdldFJlZmxlY3Rpb24oKTsKKyAgICBjb25zdCBSZWZsZWN0aW9uKiByZWZsZWN0aW9uMiA9IG1lc3NhZ2UyLkdldFJlZmxlY3Rpb24oKTsKKyAgICAvLyBGaWVsZERlc2NyaXB0b3IgZm9yIGl0ZW0ucmEKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIHJhX2ZpZWxkID0KKyAgICAgICAgbWVzc2FnZTEuR2V0RGVzY3JpcHRvcigpLT5GaW5kRmllbGRCeU5hbWUoInJhIik7CisgICAgLy8gR2V0IHRoZSBwcm9kdWN0IG9mIGFsbCBlbGVtZW50cyBpbiBpdGVtLnJhCisgICAgaW50IHJlc3VsdDEgPSAxLCByZXN1bHQyID0gMTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlZmxlY3Rpb24xLT5GaWVsZFNpemUobWVzc2FnZTEsIHJhX2ZpZWxkKTsgKytpKSB7CisgICAgICByZXN1bHQxICo9IHJlZmxlY3Rpb24xLT5HZXRSZXBlYXRlZEludDMyKG1lc3NhZ2UxLCByYV9maWVsZCwgaSk7CisgICAgfQorICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVmbGVjdGlvbjItPkZpZWxkU2l6ZShtZXNzYWdlMiwgcmFfZmllbGQpOyArK2kpIHsKKyAgICAgIHJlc3VsdDIgKj0gcmVmbGVjdGlvbjItPkdldFJlcGVhdGVkSW50MzIobWVzc2FnZTIsIHJhX2ZpZWxkLCBpKTsKKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdDEgPT0gcmVzdWx0MjsKKyAgfQorfTsKKworVEVTVChNZXNzYWdlRGlmZmVyZW5jZXJUZXN0LCBSZXBlYXRlZEZpZWxkTWFwVGVzdF9DdXN0b21NYXBLZXlDb21wYXJhdG9yKSB7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0RGlmZk1lc3NhZ2UgbXNnMTsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3REaWZmTWVzc2FnZSBtc2cyOworICAvLyBUcmVhdCAiaXRlbSIgYXMgTWFwLCB1c2luZyBjdXN0b20ga2V5IGNvbXBhcmF0b3IgdG8gZGV0ZXJtaW5lIGlmIHR3bworICAvLyBlbGVtZW50cyBoYXZlIHRoZSBzYW1lIGtleS4KKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3REaWZmTWVzc2FnZTo6SXRlbSogaXRlbSA9IG1zZzEuYWRkX2l0ZW0oKTsKKyAgaXRlbS0+YWRkX3JhKDYpOworICBpdGVtLT5hZGRfcmEoMzUpOworICBpdGVtLT5zZXRfYigiaGVsbG8iKTsKKyAgaXRlbSA9IG1zZzIuYWRkX2l0ZW0oKTsKKyAgaXRlbS0+YWRkX3JhKDEwKTsKKyAgaXRlbS0+YWRkX3JhKDIxKTsKKyAgaXRlbS0+c2V0X2IoImhlbGxvIik7CisgIHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlciBkaWZmZXJlbmNlcjsKKyAgVmFsdWVQcm9kdWN0TWFwS2V5Q29tcGFyYXRvciBrZXlfY29tcGFyYXRvcjsKKyAgZGlmZmVyZW5jZXIuVHJlYXRBc01hcFVzaW5nS2V5Q29tcGFyYXRvcigKKyAgICAgIEdldEZpZWxkRGVzY3JpcHRvcihtc2cxLCAiaXRlbSIpLCAma2V5X2NvbXBhcmF0b3IpOworICBzdHJpbmcgb3V0cHV0OworICBkaWZmZXJlbmNlci5SZXBvcnREaWZmZXJlbmNlc1RvU3RyaW5nKCZvdXRwdXQpOworICAvLyBUaG91Z2ggdGhlIGFib3ZlIHR3byBtZXNzYWdlcyBoYXZlIGRpZmZlcmVudCB2YWx1ZXMgZm9yIGl0ZW0ucmEsIHRoZXkKKyAgLy8gYXJlIHJlZ2FyZGVkIGFzIGhhdmluZyB0aGUgc2FtZSBrZXkgYmVjYXVzZSA2ICogMzUgPT0gMTAgKiAyMS4gVGhhdCdzCisgIC8vIGhvdyB0aGUga2V5IGNvbXBhcmF0b3IgZGV0ZXJtaW5lcyBpZiB0aGUgdHdvIGhhdmUgdGhlIHNhbWUga2V5LgorICAvLyBIb3dldmVyLCBpbiB2YWx1ZSBjb21wYXJpc29uLCBhbGwgZmllbGRzIG9mIHRoZSBtZXNzYWdlIGFyZSB0YWtlbiBpbnRvCisgIC8vIGNvbnNpZGVyYXRpb24sIHNvIHRoZXkgYXJlIGRpZmZlcmVudCBiZWNhdXNlIHRoZWlyIGl0ZW0ucmEgZmllbGRzIGhhdmUKKyAgLy8gZGlmZmVyZW50IHZhbHVlcyB1c2luZyBub3JtYWwgdmFsdWUgY29tcGFyaXNvbi4KKyAgRVhQRUNUX0ZBTFNFKGRpZmZlcmVuY2VyLkNvbXBhcmUobXNnMSwgbXNnMikpOworICBFWFBFQ1RfRVEoCisgICAgICAibW9kaWZpZWQ6IGl0ZW1bMF0ucmFbMF06IDYgLT4gMTBcbiIKKyAgICAgICJtb2RpZmllZDogaXRlbVswXS5yYVsxXTogMzUgLT4gMjFcbiIsCisgICAgICBvdXRwdXQpOworICBkaWZmZXJlbmNlci5JZ25vcmVGaWVsZChHZXRGaWVsZERlc2NyaXB0b3IobXNnMSwgIml0ZW0ucmEiKSk7CisgIG91dHB1dC5jbGVhcigpOworICAvLyBpdGVtLnJhIGlzIGlnbm9yZWQgaW4gdmFsdWUgY29tcGFyaXNvbiwgc28gdGhlIHR3byBtZXNzYWdlcyBlcXVhbC4KKyAgRVhQRUNUX1RSVUUoZGlmZmVyZW5jZXIuQ29tcGFyZShtc2cxLCBtc2cyKSk7CisgIEVYUEVDVF9FUSgiaWdub3JlZDogaXRlbVswXS5yYVxuIiwgb3V0cHV0KTsKK30KKworVEVTVChNZXNzYWdlRGlmZmVyZW5jZXJUZXN0LCBSZXBlYXRlZEZpZWxkU2V0VGVzdF9TdWJzZXQpIHsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3REaWZmTWVzc2FnZSBtc2cxOworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdERpZmZNZXNzYWdlIG1zZzI7CisKKyAgbXNnMS5hZGRfcnYoMyk7CisgIG1zZzEuYWRkX3J2KDgpOworICBtc2cxLmFkZF9ydigyKTsKKyAgbXNnMi5hZGRfcnYoMik7CisgIG1zZzIuYWRkX3J2KDMpOworICBtc2cyLmFkZF9ydig1KTsKKyAgbXNnMi5hZGRfcnYoOCk7CisKKyAgdXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyIGRpZmZlcmVuY2VyOworCisgIC8vIEZhaWwgd2l0aCBvbmx5IHBhcnRpYWwgc2NvcGUgc2V0LgorICBkaWZmZXJlbmNlci5zZXRfc2NvcGUodXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyOjpQQVJUSUFMKTsKKyAgZGlmZmVyZW5jZXIuc2V0X3JlcGVhdGVkX2ZpZWxkX2NvbXBhcmlzb24odXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyOjpBU19MSVNUKTsKKyAgRVhQRUNUX0ZBTFNFKGRpZmZlcmVuY2VyLkNvbXBhcmUobXNnMSwgbXNnMikpOworCisgIC8vIEZhaWwgd2l0aCBvbmx5IHNldC1saWtlIGNvbXBhcmlzb24gc2V0LgorICBkaWZmZXJlbmNlci5zZXRfc2NvcGUodXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyOjpGVUxMKTsKKyAgZGlmZmVyZW5jZXIuc2V0X3JlcGVhdGVkX2ZpZWxkX2NvbXBhcmlzb24odXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyOjpBU19TRVQpOworICBFWFBFQ1RfRkFMU0UoZGlmZmVyZW5jZXIuQ29tcGFyZShtc2cxLCBtc2cyKSk7CisKKyAgLy8gU3VjY2VlZCB3aXRoIHNjb3BlIGFuZCByZXBlYXRlZCBmaWVsZCBjb21wYXJpc29uIHNldCBwcm9wZXJseS4KKyAgZGlmZmVyZW5jZXIuc2V0X3Njb3BlKHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlcjo6UEFSVElBTCk7CisgIGRpZmZlcmVuY2VyLnNldF9yZXBlYXRlZF9maWVsZF9jb21wYXJpc29uKHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlcjo6QVNfU0VUKTsKKyAgRVhQRUNUX1RSVUUoZGlmZmVyZW5jZXIuQ29tcGFyZShtc2cxLCBtc2cyKSk7Cit9CisKK1RFU1QoTWVzc2FnZURpZmZlcmVuY2VyVGVzdCwgSWdub3JlRmllbGRfU2luZ2xlKSB7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0RmllbGQgbXNnMTsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RGaWVsZCBtc2cyOworCisgIG1zZzEuc2V0X2MoMyk7CisgIG1zZzEuYWRkX3JjKDEpOworCisgIG1zZzIuc2V0X2MoNSk7CisgIG1zZzIuYWRkX3JjKDEpOworCisgIHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlciBkaWZmZXJlbmNlcjsKKyAgZGlmZmVyZW5jZXIuSWdub3JlRmllbGQoR2V0RmllbGREZXNjcmlwdG9yKG1zZzEsICJjIikpOworCisgIEV4cGVjdEVxdWFsc1dpdGhEaWZmZXJlbmNlcigmZGlmZmVyZW5jZXIsIG1zZzEsIG1zZzIpOworfQorCitURVNUKE1lc3NhZ2VEaWZmZXJlbmNlclRlc3QsIElnbm9yZUZpZWxkX1JlcGVhdGVkKSB7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0RmllbGQgbXNnMTsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RGaWVsZCBtc2cyOworCisgIG1zZzEuc2V0X2MoMyk7CisgIG1zZzEuYWRkX3JjKDEpOworICBtc2cxLmFkZF9yYygyKTsKKworICBtc2cyLnNldF9jKDMpOworICBtc2cyLmFkZF9yYygxKTsKKyAgbXNnMi5hZGRfcmMoMyk7CisKKyAgdXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyIGRpZmZlcmVuY2VyOworICBkaWZmZXJlbmNlci5JZ25vcmVGaWVsZChHZXRGaWVsZERlc2NyaXB0b3IobXNnMSwgInJjIikpOworCisgIEV4cGVjdEVxdWFsc1dpdGhEaWZmZXJlbmNlcigmZGlmZmVyZW5jZXIsIG1zZzEsIG1zZzIpOworfQorCitURVNUKE1lc3NhZ2VEaWZmZXJlbmNlclRlc3QsIElnbm9yZUZpZWxkX01lc3NhZ2UpIHsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3REaWZmTWVzc2FnZSBtc2cxOworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdERpZmZNZXNzYWdlIG1zZzI7CisKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RGaWVsZCogZmllbGQ7CisKKyAgZmllbGQgPSBtc2cxLmFkZF9ybSgpOworICBmaWVsZC0+c2V0X2MoMyk7CisKKyAgZmllbGQgPSBtc2cyLmFkZF9ybSgpOworICBmaWVsZC0+c2V0X2MoNCk7CisKKyAgdXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyIGRpZmZlcmVuY2VyOworICBkaWZmZXJlbmNlci5JZ25vcmVGaWVsZChHZXRGaWVsZERlc2NyaXB0b3IobXNnMSwgInJtIikpOworCisgIEV4cGVjdEVxdWFsc1dpdGhEaWZmZXJlbmNlcigmZGlmZmVyZW5jZXIsIG1zZzEsIG1zZzIpOworfQorCitURVNUKE1lc3NhZ2VEaWZmZXJlbmNlclRlc3QsIElnbm9yZUZpZWxkX0dyb3VwKSB7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0RGlmZk1lc3NhZ2UgbXNnMTsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3REaWZmTWVzc2FnZSBtc2cyOworCisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0RGlmZk1lc3NhZ2U6Okl0ZW0qIGl0ZW07CisKKyAgaXRlbSA9IG1zZzEuYWRkX2l0ZW0oKTsKKyAgaXRlbS0+c2V0X2EoMyk7CisKKyAgaXRlbSA9IG1zZzIuYWRkX2l0ZW0oKTsKKyAgaXRlbS0+c2V0X2EoNCk7CisKKyAgdXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyIGRpZmZlcmVuY2VyOworICBkaWZmZXJlbmNlci5JZ25vcmVGaWVsZChHZXRGaWVsZERlc2NyaXB0b3IobXNnMSwgIml0ZW0iKSk7CisKKyAgRXhwZWN0RXF1YWxzV2l0aERpZmZlcmVuY2VyKCZkaWZmZXJlbmNlciwgbXNnMSwgbXNnMik7Cit9CisKK1RFU1QoTWVzc2FnZURpZmZlcmVuY2VyVGVzdCwgSWdub3JlRmllbGRfTWlzc2luZykgeworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEZpZWxkIG1zZzE7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0RmllbGQgbXNnMjsKKworICBtc2cxLnNldF9jKDMpOworICBtc2cxLmFkZF9yYygxKTsKKworICBtc2cyLmFkZF9yYygxKTsKKworICB1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXIgZGlmZmVyZW5jZXI7CisgIGRpZmZlcmVuY2VyLklnbm9yZUZpZWxkKEdldEZpZWxkRGVzY3JpcHRvcihtc2cxLCAiYyIpKTsKKworICBFeHBlY3RFcXVhbHNXaXRoRGlmZmVyZW5jZXIoJmRpZmZlcmVuY2VyLCBtc2cxLCBtc2cyKTsKKyAgRXhwZWN0RXF1YWxzV2l0aERpZmZlcmVuY2VyKCZkaWZmZXJlbmNlciwgbXNnMiwgbXNnMSk7Cit9CisKK1RFU1QoTWVzc2FnZURpZmZlcmVuY2VyVGVzdCwgSWdub3JlRmllbGRfTXVsdGlwbGUpIHsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RGaWVsZCBtc2cxOworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEZpZWxkIG1zZzI7CisKKyAgbXNnMS5zZXRfYygzKTsKKyAgbXNnMS5hZGRfcmMoMSk7CisgIG1zZzEuYWRkX3JjKDIpOworCisgIG1zZzIuc2V0X2MoNSk7CisgIG1zZzIuYWRkX3JjKDEpOworICBtc2cyLmFkZF9yYygzKTsKKworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGMgPSBHZXRGaWVsZERlc2NyaXB0b3IobXNnMSwgImMiKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiByYyA9IEdldEZpZWxkRGVzY3JpcHRvcihtc2cxLCAicmMiKTsKKworICB7IC8vIElnbm9yZSBjCisgICAgdXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyIGRpZmZlcmVuY2VyOworICAgIGRpZmZlcmVuY2VyLklnbm9yZUZpZWxkKGMpOworCisgICAgRVhQRUNUX0ZBTFNFKGRpZmZlcmVuY2VyLkNvbXBhcmUobXNnMSwgbXNnMikpOworICB9CisgIHsgLy8gSWdub3JlIHJjCisgICAgdXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyIGRpZmZlcmVuY2VyOworICAgIGRpZmZlcmVuY2VyLklnbm9yZUZpZWxkKHJjKTsKKworICAgIEVYUEVDVF9GQUxTRShkaWZmZXJlbmNlci5Db21wYXJlKG1zZzEsIG1zZzIpKTsKKyAgfQorICB7IC8vIElnbm9yZSBib3RoCisgICAgdXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyIGRpZmZlcmVuY2VyOworICAgIGRpZmZlcmVuY2VyLklnbm9yZUZpZWxkKGMpOworICAgIGRpZmZlcmVuY2VyLklnbm9yZUZpZWxkKHJjKTsKKworICAgIEV4cGVjdEVxdWFsc1dpdGhEaWZmZXJlbmNlcigmZGlmZmVyZW5jZXIsIG1zZzEsIG1zZzIpOworICB9Cit9CisKK1RFU1QoTWVzc2FnZURpZmZlcmVuY2VyVGVzdCwgSWdub3JlRmllbGRfTmVzdGVkTWVzc2FnZSkgeworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdERpZmZNZXNzYWdlIG1zZzE7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0RGlmZk1lc3NhZ2UgbXNnMjsKKworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEZpZWxkKiBmaWVsZDsKKworICBmaWVsZCA9IG1zZzEuYWRkX3JtKCk7CisgIGZpZWxkLT5zZXRfYygzKTsKKyAgZmllbGQtPmFkZF9yYygxKTsKKworICBmaWVsZCA9IG1zZzIuYWRkX3JtKCk7CisgIGZpZWxkLT5zZXRfYyg0KTsKKyAgZmllbGQtPmFkZF9yYygxKTsKKworICB1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXIgZGlmZmVyZW5jZXI7CisgIGRpZmZlcmVuY2VyLklnbm9yZUZpZWxkKEdldEZpZWxkRGVzY3JpcHRvcihtc2cxLCAicm0uYyIpKTsKKworICBFeHBlY3RFcXVhbHNXaXRoRGlmZmVyZW5jZXIoJmRpZmZlcmVuY2VyLCBtc2cxLCBtc2cyKTsKK30KKworVEVTVChNZXNzYWdlRGlmZmVyZW5jZXJUZXN0LCBJZ25vcmVGaWVsZF9OZXN0ZWRHcm91cCkgeworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdERpZmZNZXNzYWdlIG1zZzE7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0RGlmZk1lc3NhZ2UgbXNnMjsKKworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdERpZmZNZXNzYWdlOjpJdGVtKiBpdGVtOworCisgIGl0ZW0gPSBtc2cxLmFkZF9pdGVtKCk7CisgIGl0ZW0tPnNldF9hKDMpOworICBpdGVtLT5zZXRfYigiZm9vIik7CisKKyAgaXRlbSA9IG1zZzIuYWRkX2l0ZW0oKTsKKyAgaXRlbS0+c2V0X2EoNCk7CisgIGl0ZW0tPnNldF9iKCJmb28iKTsKKworICB1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXIgZGlmZmVyZW5jZXI7CisgIGRpZmZlcmVuY2VyLklnbm9yZUZpZWxkKEdldEZpZWxkRGVzY3JpcHRvcihtc2cxLCAiaXRlbS5hIikpOworCisgIEV4cGVjdEVxdWFsc1dpdGhEaWZmZXJlbmNlcigmZGlmZmVyZW5jZXIsIG1zZzEsIG1zZzIpOworfQorCitURVNUKE1lc3NhZ2VEaWZmZXJlbmNlclRlc3QsIElnbm9yZUZpZWxkX0luc2lkZVNldCkgeworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdERpZmZNZXNzYWdlIG1zZzE7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0RGlmZk1lc3NhZ2UgbXNnMjsKKworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdERpZmZNZXNzYWdlOjpJdGVtKiBpdGVtOworCisgIGl0ZW0gPSBtc2cxLmFkZF9pdGVtKCk7CisgIGl0ZW0tPnNldF9hKDEpOworICBpdGVtLT5zZXRfYigiZm9vIik7CisgIGl0ZW0tPmFkZF9yYSgxKTsKKworICBpdGVtID0gbXNnMS5hZGRfaXRlbSgpOworICBpdGVtLT5zZXRfYSgyKTsKKyAgaXRlbS0+c2V0X2IoImJhciIpOworICBpdGVtLT5hZGRfcmEoMik7CisKKyAgaXRlbSA9IG1zZzIuYWRkX2l0ZW0oKTsKKyAgaXRlbS0+c2V0X2EoMik7CisgIGl0ZW0tPnNldF9iKCJiYXIiKTsKKyAgaXRlbS0+YWRkX3JhKDIpOworCisgIGl0ZW0gPSBtc2cyLmFkZF9pdGVtKCk7CisgIGl0ZW0tPnNldF9hKDEpOworICBpdGVtLT5zZXRfYigiYmF6Iik7CisgIGl0ZW0tPmFkZF9yYSgxKTsKKworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGl0ZW1fZGVzYyA9IEdldEZpZWxkRGVzY3JpcHRvcihtc2cxLCAiaXRlbSIpOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGIgPSBHZXRGaWVsZERlc2NyaXB0b3IobXNnMSwgIml0ZW0uYiIpOworCisgIHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlciBkaWZmZXJlbmNlcjsKKyAgZGlmZmVyZW5jZXIuSWdub3JlRmllbGQoYik7CisgIGRpZmZlcmVuY2VyLlRyZWF0QXNTZXQoaXRlbV9kZXNjKTsKKworICBFeHBlY3RFcXVhbHNXaXRoRGlmZmVyZW5jZXIoJmRpZmZlcmVuY2VyLCBtc2cxLCBtc2cyKTsKK30KKworVEVTVChNZXNzYWdlRGlmZmVyZW5jZXJUZXN0LCBJZ25vcmVGaWVsZF9JbnNpZGVNYXApIHsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3REaWZmTWVzc2FnZSBtc2cxOworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdERpZmZNZXNzYWdlIG1zZzI7CisKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3REaWZmTWVzc2FnZTo6SXRlbSogaXRlbTsKKworICBpdGVtID0gbXNnMS5hZGRfaXRlbSgpOworICBpdGVtLT5zZXRfYSgxKTsKKyAgaXRlbS0+c2V0X2IoImZvbyIpOworICBpdGVtLT5hZGRfcmEoMSk7CisKKyAgaXRlbSA9IG1zZzEuYWRkX2l0ZW0oKTsKKyAgaXRlbS0+c2V0X2EoMik7CisgIGl0ZW0tPnNldF9iKCJiYXIiKTsKKyAgaXRlbS0+YWRkX3JhKDIpOworCisgIGl0ZW0gPSBtc2cyLmFkZF9pdGVtKCk7CisgIGl0ZW0tPnNldF9hKDIpOworICBpdGVtLT5zZXRfYigiYmFyIik7CisgIGl0ZW0tPmFkZF9yYSgyKTsKKworICBpdGVtID0gbXNnMi5hZGRfaXRlbSgpOworICBpdGVtLT5zZXRfYSgxKTsKKyAgaXRlbS0+c2V0X2IoImJheiIpOworICBpdGVtLT5hZGRfcmEoMSk7CisKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBpdGVtX2Rlc2MgPSBHZXRGaWVsZERlc2NyaXB0b3IobXNnMSwgIml0ZW0iKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBhID0gR2V0RmllbGREZXNjcmlwdG9yKG1zZzEsICJpdGVtLmEiKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBiID0gR2V0RmllbGREZXNjcmlwdG9yKG1zZzEsICJpdGVtLmIiKTsKKworICB1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXIgZGlmZmVyZW5jZXI7CisgIGRpZmZlcmVuY2VyLklnbm9yZUZpZWxkKGIpOworICBkaWZmZXJlbmNlci5UcmVhdEFzTWFwKGl0ZW1fZGVzYywgYSk7CisKKyAgRXhwZWN0RXF1YWxzV2l0aERpZmZlcmVuY2VyKCZkaWZmZXJlbmNlciwgbXNnMSwgbXNnMik7Cit9CisKK1RFU1QoTWVzc2FnZURpZmZlcmVuY2VyVGVzdCwgSWdub3JlRmllbGRfRG9lc05vdElnbm9yZUtleSkgeworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdERpZmZNZXNzYWdlIG1zZzE7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0RGlmZk1lc3NhZ2UgbXNnMjsKKworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdERpZmZNZXNzYWdlOjpJdGVtKiBpdGVtOworCisgIGl0ZW0gPSBtc2cxLmFkZF9pdGVtKCk7CisgIGl0ZW0tPnNldF9hKDEpOworICBpdGVtLT5zZXRfYigiZm9vIik7CisgIGl0ZW0tPmFkZF9yYSgxKTsKKworICBpdGVtID0gbXNnMi5hZGRfaXRlbSgpOworICBpdGVtLT5zZXRfYSgyKTsKKyAgaXRlbS0+c2V0X2IoImZvbyIpOworICBpdGVtLT5hZGRfcmEoMSk7CisKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBpdGVtX2Rlc2MgPSBHZXRGaWVsZERlc2NyaXB0b3IobXNnMSwgIml0ZW0iKTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBhID0gR2V0RmllbGREZXNjcmlwdG9yKG1zZzEsICJpdGVtLmEiKTsKKworICB1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXIgZGlmZmVyZW5jZXI7CisgIGRpZmZlcmVuY2VyLklnbm9yZUZpZWxkKGEpOworICBkaWZmZXJlbmNlci5UcmVhdEFzTWFwKGl0ZW1fZGVzYywgYSk7CisKKyAgRVhQRUNUX0ZBTFNFKGRpZmZlcmVuY2VyLkNvbXBhcmUobXNnMSwgbXNnMikpOworfQorCitURVNUKE1lc3NhZ2VEaWZmZXJlbmNlclRlc3QsIElnbm9yZUZpZWxkX1RydW1wc0NvbXBhcmVXaXRoRmllbGRzKSB7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0RmllbGQgbXNnMTsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RGaWVsZCBtc2cyOworCisgIG1zZzEuc2V0X2MoMyk7CisgIG1zZzEuYWRkX3JjKDEpOworICBtc2cxLmFkZF9yYygyKTsKKworICBtc2cyLnNldF9jKDMpOworICBtc2cyLmFkZF9yYygxKTsKKyAgbXNnMi5hZGRfcmMoMyk7CisKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBjID0gR2V0RmllbGREZXNjcmlwdG9yKG1zZzEsICJjIik7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogcmMgPSBHZXRGaWVsZERlc2NyaXB0b3IobXNnMSwgInJjIik7CisKKyAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+IGZpZWxkczsKKyAgZmllbGRzLnB1c2hfYmFjayhjKTsKKyAgZmllbGRzLnB1c2hfYmFjayhyYyk7CisKKyAgdXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyIGRpZmZlcmVuY2VyOworICBkaWZmZXJlbmNlci5JZ25vcmVGaWVsZChyYyk7CisKKyAgZGlmZmVyZW5jZXIuc2V0X3Njb3BlKHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlcjo6RlVMTCk7CisgIEVYUEVDVF9UUlVFKGRpZmZlcmVuY2VyLkNvbXBhcmVXaXRoRmllbGRzKG1zZzEsIG1zZzIsIGZpZWxkcywgZmllbGRzKSk7CisKKyAgZGlmZmVyZW5jZXIuc2V0X3Njb3BlKHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlcjo6UEFSVElBTCk7CisgIEVYUEVDVF9UUlVFKGRpZmZlcmVuY2VyLkNvbXBhcmVXaXRoRmllbGRzKG1zZzEsIG1zZzIsIGZpZWxkcywgZmllbGRzKSk7Cit9CisKKworLy8gVGVzdCBjbGFzcyB0byBzYXZlIGEgY29weSBvZiB0aGUgbGFzdCBmaWVsZF9jb250ZXh0LnBhcmVudF9maWVsZHMoKSB2ZWN0b3IKKy8vIHBhc3NlZCB0byB0aGUgY29tcGFyaXNvbiBmdW5jdGlvbi4KK2NsYXNzIFBhcmVudFNhdmluZ0ZpZWxkQ29tcGFyYXRvciA6IHB1YmxpYyB1dGlsOjpGaWVsZENvbXBhcmF0b3IgeworIHB1YmxpYzoKKyAgUGFyZW50U2F2aW5nRmllbGRDb21wYXJhdG9yKCkge30KKworICB2aXJ0dWFsIENvbXBhcmlzb25SZXN1bHQgQ29tcGFyZSgKKyAgICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIG1lc3NhZ2VfMSwKKyAgICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIG1lc3NhZ2VfMiwKKyAgICAgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICBpbnQgaW5kZXhfMSwgaW50IGluZGV4XzIsCisgICAgICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjp1dGlsOjpGaWVsZENvbnRleHQqIGZpZWxkX2NvbnRleHQpIHsKKyAgICBpZiAoZmllbGRfY29udGV4dCkKKyAgICAgIHBhcmVudF9maWVsZHNfID0gKihmaWVsZF9jb250ZXh0LT5wYXJlbnRfZmllbGRzKCkpOworICAgIGlmIChmaWVsZC0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSkgeworICAgICAgcmV0dXJuIFJFQ1VSU0U7CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiBTQU1FOworICAgIH0KKyAgfQorCisgIHZlY3Rvcjxnb29nbGU6OnByb3RvYnVmOjp1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXI6OlNwZWNpZmljRmllbGQ+IHBhcmVudF9maWVsZHMoKSB7CisgICAgcmV0dXJuIHBhcmVudF9maWVsZHNfOworICB9CisKKyBwcml2YXRlOgorICB2ZWN0b3I8Z29vZ2xlOjpwcm90b2J1Zjo6dXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyOjpTcGVjaWZpY0ZpZWxkPiBwYXJlbnRfZmllbGRzXzsKK307CisKKy8vIFRlc3RzIGlmIE1lc3NhZ2VEaWZmZXJlbmNlciBzZW5kcyB0aGUgcGFyZW50IGZpZWxkcyBpbiB0aGUgRmllbGRDb250ZXh0CisvLyBwYXJhbWV0ZXIuCitURVNUKE1lc3NhZ2VEaWZmZXJlbmNlclRlc3QsIEZpZWxkQ29udGV4dFBhcmVudEZpZWxkc1Rlc3QpIHsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3REaWZmTWVzc2FnZSBtc2cxOworICBtc2cxLmFkZF9ybSgpLT5zZXRfYygxKTsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3REaWZmTWVzc2FnZSBtc2cyOworICBtc2cyLmFkZF9ybSgpLT5zZXRfYygxKTsKKworICBQYXJlbnRTYXZpbmdGaWVsZENvbXBhcmF0b3IgZmllbGRfY29tcGFyYXRvcjsKKyAgdXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyIGRpZmZlcmVuY2VyOworICBkaWZmZXJlbmNlci5zZXRfZmllbGRfY29tcGFyYXRvcigmZmllbGRfY29tcGFyYXRvcik7CisgIGRpZmZlcmVuY2VyLkNvbXBhcmUobXNnMSwgbXNnMik7CisKKyAgLy8gV2Ugd2FudCBvbmx5IG9uZSBwYXJlbnQgd2l0aCB0aGUgbmFtZSAicm0iCisgIEFTU0VSVF9FUSgxLCBmaWVsZF9jb21wYXJhdG9yLnBhcmVudF9maWVsZHMoKS5zaXplKCkpOworICBFWFBFQ1RfRVEoInJtIiwgZmllbGRfY29tcGFyYXRvci5wYXJlbnRfZmllbGRzKClbMF0uZmllbGQtPm5hbWUoKSk7Cit9CisKKworY2xhc3MgQ29tcGFyaXNvblRlc3QgOiBwdWJsaWMgdGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICBDb21wYXJpc29uVGVzdCgpIDogdXNlX2VxdWl2YWxlbmN5XyhmYWxzZSksIHJlcGVhdGVkX2ZpZWxkX2FzX3NldF8oZmFsc2UpIHsKKyAgICAvLyBTZXR1cCB0aGUgdGVzdC4KKyAgICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZwcm90bzFfKTsKKyAgICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZwcm90bzJfKTsKKworICAgIFRlc3RVdGlsOjpTZXRBbGxFeHRlbnNpb25zKCZwcm90bzFleF8pOworICAgIFRlc3RVdGlsOjpTZXRBbGxFeHRlbnNpb25zKCZwcm90bzJleF8pOworCisgICAgVGVzdFV0aWw6OlNldEFsbEZpZWxkc0FuZEV4dGVuc2lvbnMoJm9yZGVyaW5nc19wcm90bzFfKTsKKyAgICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzQW5kRXh0ZW5zaW9ucygmb3JkZXJpbmdzX3Byb3RvMl8pOworCisgICAgdW5rbm93bjFfID0gZW1wdHkxXy5tdXRhYmxlX3Vua25vd25fZmllbGRzKCk7CisgICAgdW5rbm93bjJfID0gZW1wdHkyXy5tdXRhYmxlX3Vua25vd25fZmllbGRzKCk7CisgIH0KKworICB+Q29tcGFyaXNvblRlc3QoKSB7IH0KKworICB2b2lkIFNldFNwZWNpYWxGaWVsZE9wdGlvbihjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyKiBkKSB7CisgICAgaWYgKCFpZ25vcmVkX2ZpZWxkXy5lbXB0eSgpKSB7CisgICAgICBkLT5JZ25vcmVGaWVsZChHZXRGaWVsZERlc2NyaXB0b3IobWVzc2FnZSwgaWdub3JlZF9maWVsZF8pKTsKKyAgICB9CisKKyAgICBpZiAocmVwZWF0ZWRfZmllbGRfYXNfc2V0XykgeworICAgICAgZC0+c2V0X3JlcGVhdGVkX2ZpZWxkX2NvbXBhcmlzb24odXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyOjpBU19TRVQpOworICAgIH0KKworICAgIGlmICghc2V0X2ZpZWxkXy5lbXB0eSgpKSB7CisgICAgICBkLT5UcmVhdEFzU2V0KEdldEZpZWxkRGVzY3JpcHRvcihtZXNzYWdlLCBzZXRfZmllbGRfKSk7CisgICAgfQorCisgICAgaWYgKCFtYXBfZmllbGRfLmVtcHR5KCkgJiYgIW1hcF9rZXlfLmVtcHR5KCkpIHsKKyAgICAgIGQtPlRyZWF0QXNNYXAoR2V0RmllbGREZXNjcmlwdG9yKG1lc3NhZ2UsIG1hcF9maWVsZF8pLAorICAgICAgICAgICAgICAgICAgICBHZXRGaWVsZERlc2NyaXB0b3IobWVzc2FnZSwgbWFwX2ZpZWxkXyArICIuIiArIG1hcF9rZXlfKSk7CisgICAgfQorICB9CisKKyAgc3RyaW5nIFJ1bihjb25zdCBNZXNzYWdlJiBtc2cxLCBjb25zdCBNZXNzYWdlJiBtc2cyKSB7CisgICAgc3RyaW5nIG91dHB1dDsKKworICAgIC8vIFNldHVwIHRoZSBjb21wYXJpc29uLgorICAgIHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlciBkaWZmZXJlbmNlcjsKKyAgICBkaWZmZXJlbmNlci5SZXBvcnREaWZmZXJlbmNlc1RvU3RyaW5nKCZvdXRwdXQpOworCisgICAgaWYgKHVzZV9lcXVpdmFsZW5jeV8pIHsKKyAgICAgIGRpZmZlcmVuY2VyLnNldF9tZXNzYWdlX2ZpZWxkX2NvbXBhcmlzb24oCisgICAgICAgICAgdXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyOjpFUVVJVkFMRU5UKTsKKyAgICB9CisKKyAgICBTZXRTcGVjaWFsRmllbGRPcHRpb24obXNnMSwgJmRpZmZlcmVuY2VyKTsKKworICAgIC8vIENvbmR1Y3QgdGhlIGNvbXBhcmlzb24uCisgICAgRVhQRUNUX0ZBTFNFKGRpZmZlcmVuY2VyLkNvbXBhcmUobXNnMSwgbXNnMikpOworCisgICAgcmV0dXJuIG91dHB1dDsKKyAgfQorCisgIHN0cmluZyBSdW4oKSB7CisgICAgcmV0dXJuIFJ1bihwcm90bzFfLCBwcm90bzJfKTsKKyAgfQorCisgIHN0cmluZyBSdW5PcmRlcigpIHsKKyAgICByZXR1cm4gUnVuKG9yZGVyaW5nc19wcm90bzFfLCBvcmRlcmluZ3NfcHJvdG8yXyk7CisgIH0KKworICBzdHJpbmcgUnVuRXgoKSB7CisgICAgcmV0dXJuIFJ1bihwcm90bzFleF8sIHByb3RvMmV4Xyk7CisgIH0KKworICBzdHJpbmcgUnVuRGlmZigpIHsKKyAgICByZXR1cm4gUnVuKHByb3RvMWRpZmZfLCBwcm90bzJkaWZmXyk7CisgIH0KKworICBzdHJpbmcgUnVuVW4oKSB7CisgICAgcmV0dXJuIFJ1bihlbXB0eTFfLCBlbXB0eTJfKTsKKyAgfQorCisgIHZvaWQgdXNlX2VxdWl2YWxlbmN5KCkgeworICAgIHVzZV9lcXVpdmFsZW5jeV8gPSB0cnVlOworICB9CisKKyAgdm9pZCByZXBlYXRlZF9maWVsZF9hc19zZXQoKSB7CisgICAgcmVwZWF0ZWRfZmllbGRfYXNfc2V0XyA9IHRydWU7CisgIH0KKworICB2b2lkIGZpZWxkX2FzX3NldChjb25zdCBzdHJpbmcmIGZpZWxkKSB7CisgICAgc2V0X2ZpZWxkXyA9IGZpZWxkOworICB9CisKKyAgdm9pZCBmaWVsZF9hc19tYXAoY29uc3Qgc3RyaW5nJiBmaWVsZCwgY29uc3Qgc3RyaW5nJiBrZXkpIHsKKyAgICBtYXBfZmllbGRfID0gZmllbGQ7CisgICAgbWFwX2tleV8gICA9IGtleTsKKyAgfQorCisgIHZvaWQgaWdub3JlX2ZpZWxkKGNvbnN0IHN0cmluZyYgZmllbGQpIHsKKyAgICBpZ25vcmVkX2ZpZWxkXyA9IGZpZWxkOworICB9CisKKyAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcyBwcm90bzFfOworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIHByb3RvMl87CisKKyAgdW5pdHRlc3Q6OlRlc3RGaWVsZE9yZGVyaW5ncyBvcmRlcmluZ3NfcHJvdG8xXzsKKyAgdW5pdHRlc3Q6OlRlc3RGaWVsZE9yZGVyaW5ncyBvcmRlcmluZ3NfcHJvdG8yXzsKKworICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgcHJvdG8xZXhfOworICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgcHJvdG8yZXhfOworCisgIHVuaXR0ZXN0OjpUZXN0RGlmZk1lc3NhZ2UgcHJvdG8xZGlmZl87CisgIHVuaXR0ZXN0OjpUZXN0RGlmZk1lc3NhZ2UgcHJvdG8yZGlmZl87CisKKyAgdW5pdHRlc3Q6OlRlc3RFbXB0eU1lc3NhZ2UgZW1wdHkxXzsKKyAgdW5pdHRlc3Q6OlRlc3RFbXB0eU1lc3NhZ2UgZW1wdHkyXzsKKworICBVbmtub3duRmllbGRTZXQqIHVua25vd24xXzsKKyAgVW5rbm93bkZpZWxkU2V0KiB1bmtub3duMl87CisKKyAgYm9vbCB1c2VfZXF1aXZhbGVuY3lfOworICBib29sIHJlcGVhdGVkX2ZpZWxkX2FzX3NldF87CisKKyAgc3RyaW5nIHNldF9maWVsZF87CisgIHN0cmluZyBtYXBfZmllbGRfOworICBzdHJpbmcgbWFwX2tleV87CisgIHN0cmluZyBpZ25vcmVkX2ZpZWxkXzsKK307CisKKy8vIEJhc2ljIHRlc3RzLgorVEVTVF9GKENvbXBhcmlzb25UZXN0LCBBZGRpdGlvblRlc3QpIHsKKyAgcHJvdG8xXy5jbGVhcl9vcHRpb25hbF9pbnQzMigpOworCisgIEVYUEVDVF9FUSgiYWRkZWQ6IG9wdGlvbmFsX2ludDMyOiAxMDFcbiIsCisgICAgICAgICAgICBSdW4oKSk7Cit9CisKK1RFU1RfRihDb21wYXJpc29uVGVzdCwgQWRkaXRpb25fT3JkZXJUZXN0KSB7CisgIG9yZGVyaW5nc19wcm90bzFfLmNsZWFyX215X2ludCgpOworCisgIEVYUEVDVF9FUSgiYWRkZWQ6IG15X2ludDogMVxuIiwKKyAgICAgICAgICAgIFJ1bk9yZGVyKCkpOworfQorCitURVNUX0YoQ29tcGFyaXNvblRlc3QsIERlbGV0aW9uVGVzdCkgeworICBwcm90bzJfLmNsZWFyX29wdGlvbmFsX2ludDMyKCk7CisKKyAgRVhQRUNUX0VRKCJkZWxldGVkOiBvcHRpb25hbF9pbnQzMjogMTAxXG4iLAorICAgICAgICAgICAgUnVuKCkpOworfQorCitURVNUX0YoQ29tcGFyaXNvblRlc3QsIERlbGV0aW9uX09yZGVyVGVzdCkgeworICBvcmRlcmluZ3NfcHJvdG8yXy5jbGVhcl9teV9zdHJpbmcoKTsKKworICBFWFBFQ1RfRVEoImRlbGV0ZWQ6IG15X3N0cmluZzogXCJmb29cIlxuIiwKKyAgICAgICAgICAgIFJ1bk9yZGVyKCkpOworfQorCitURVNUX0YoQ29tcGFyaXNvblRlc3QsIFJlcGVhdGVkRGVsZXRpb25UZXN0KSB7CisgIHByb3RvMl8uY2xlYXJfcmVwZWF0ZWRfaW50MzIoKTsKKworICBFWFBFQ1RfRVEoImRlbGV0ZWQ6IHJlcGVhdGVkX2ludDMyWzBdOiAyMDFcbiIKKyAgICAgICAgICAgICJkZWxldGVkOiByZXBlYXRlZF9pbnQzMlsxXTogMzAxXG4iLAorICAgICAgICAgICAgUnVuKCkpOworfQorCitURVNUX0YoQ29tcGFyaXNvblRlc3QsIE1vZGlmaWNhdGlvblRlc3QpIHsKKyAgcHJvdG8xXy5zZXRfb3B0aW9uYWxfaW50MzIoLTEpOworCisgIEVYUEVDVF9FUSgibW9kaWZpZWQ6IG9wdGlvbmFsX2ludDMyOiAtMSAtPiAxMDFcbiIsCisgICAgICAgICAgICBSdW4oKSk7Cit9CisKKy8vIEJhc2ljIGVxdWl2YWxlbmN5IHRlc3RzLgorVEVTVF9GKENvbXBhcmlzb25UZXN0LCBFcXVpdmFsZW5jeUFkZGl0aW9uVGVzdCkgeworICB1c2VfZXF1aXZhbGVuY3koKTsKKworICBwcm90bzFfLmNsZWFyX29wdGlvbmFsX2ludDMyKCk7CisKKyAgRVhQRUNUX0VRKCJtb2RpZmllZDogb3B0aW9uYWxfaW50MzI6IDAgLT4gMTAxXG4iLAorICAgICAgICAgICAgUnVuKCkpOworfQorCitURVNUX0YoQ29tcGFyaXNvblRlc3QsIEVxdWl2YWxlbmN5RGVsZXRpb25UZXN0KSB7CisgIHVzZV9lcXVpdmFsZW5jeSgpOworCisgIHByb3RvMl8uY2xlYXJfb3B0aW9uYWxfaW50MzIoKTsKKworICBFWFBFQ1RfRVEoIm1vZGlmaWVkOiBvcHRpb25hbF9pbnQzMjogMTAxIC0+IDBcbiIsCisgICAgICAgICAgICBSdW4oKSk7Cit9CisKKy8vIEdyb3VwIHRlc3RzLgorVEVTVF9GKENvbXBhcmlzb25UZXN0LCBHcm91cEFkZGl0aW9uVGVzdCkgeworICBwcm90bzFfLm11dGFibGVfb3B0aW9uYWxncm91cCgpLT5jbGVhcl9hKCk7CisKKyAgRVhQRUNUX0VRKCJhZGRlZDogb3B0aW9uYWxncm91cC5hOiAxMTdcbiIsCisgICAgICAgICAgICBSdW4oKSk7Cit9CisKK1RFU1RfRihDb21wYXJpc29uVGVzdCwgR3JvdXBEZWxldGlvblRlc3QpIHsKKyAgcHJvdG8yXy5tdXRhYmxlX29wdGlvbmFsZ3JvdXAoKS0+Y2xlYXJfYSgpOworCisgIEVYUEVDVF9FUSgiZGVsZXRlZDogb3B0aW9uYWxncm91cC5hOiAxMTdcbiIsCisgICAgICAgICAgICBSdW4oKSk7Cit9CisKK1RFU1RfRihDb21wYXJpc29uVGVzdCwgR3JvdXBNb2RpZmljYXRpb25UZXN0KSB7CisgIHByb3RvMV8ubXV0YWJsZV9vcHRpb25hbGdyb3VwKCktPnNldF9hKDIpOworCisgIEVYUEVDVF9FUSgibW9kaWZpZWQ6IG9wdGlvbmFsZ3JvdXAuYTogMiAtPiAxMTdcbiIsCisgICAgICAgICAgICBSdW4oKSk7Cit9CisKK1RFU1RfRihDb21wYXJpc29uVGVzdCwgR3JvdXBGdWxsQWRkaXRpb25UZXN0KSB7CisgIHByb3RvMV8uY2xlYXJfb3B0aW9uYWxncm91cCgpOworCisgIC8vIE5vdGUgdGhlIGRpZmZlcmVuY2UgaW4gdGhlIG91dHB1dCBiZXR3ZWVuIHRoaXMgYW5kIEdyb3VwQWRkaXRpb25UZXN0LgorICBFWFBFQ1RfRVEoImFkZGVkOiBvcHRpb25hbGdyb3VwOiB7IGE6IDExNyB9XG4iLAorICAgICAgICAgICAgUnVuKCkpOworfQorCitURVNUX0YoQ29tcGFyaXNvblRlc3QsIEdyb3VwRnVsbERlbGV0aW9uVGVzdCkgeworICBwcm90bzJfLmNsZWFyX29wdGlvbmFsZ3JvdXAoKTsKKworICBFWFBFQ1RfRVEoImRlbGV0ZWQ6IG9wdGlvbmFsZ3JvdXA6IHsgYTogMTE3IH1cbiIsCisgICAgICAgICAgICBSdW4oKSk7Cit9CisKK1RFU1RfRihDb21wYXJpc29uVGVzdCwgUmVwZWF0ZWRTZXRPcHRpb25UZXN0KSB7CisgIHJlcGVhdGVkX2ZpZWxkX2FzX3NldCgpOworCisgIHByb3RvMl8uY2xlYXJfcmVwZWF0ZWRncm91cCgpOworICBwcm90bzFfLmNsZWFyX3JlcGVhdGVkZ3JvdXAoKTsKKyAgcHJvdG8xXy5hZGRfcmVwZWF0ZWRncm91cCgpLT5zZXRfYSgzMTcpOworICBwcm90bzJfLmFkZF9yZXBlYXRlZGdyb3VwKCktPnNldF9hKDkwOSk7CisgIHByb3RvMl8uYWRkX3JlcGVhdGVkZ3JvdXAoKS0+c2V0X2EoOTA3KTsKKyAgcHJvdG8xXy5hZGRfcmVwZWF0ZWRncm91cCgpLT5zZXRfYSg5MDQpOworICBwcm90bzFfLmFkZF9yZXBlYXRlZGdyb3VwKCktPnNldF9hKDkwNyk7CisgIHByb3RvMV8uYWRkX3JlcGVhdGVkZ3JvdXAoKS0+c2V0X2EoOTA5KTsKKworICBFWFBFQ1RfRVEoIm1vdmVkOiByZXBlYXRlZGdyb3VwWzJdIC0+IHJlcGVhdGVkZ3JvdXBbMV0gOiB7IGE6IDkwNyB9XG4iCisgICAgICAgICAgICAibW92ZWQ6IHJlcGVhdGVkZ3JvdXBbM10gLT4gcmVwZWF0ZWRncm91cFswXSA6IHsgYTogOTA5IH1cbiIKKyAgICAgICAgICAgICJkZWxldGVkOiByZXBlYXRlZGdyb3VwWzBdOiB7IGE6IDMxNyB9XG4iCisgICAgICAgICAgICAiZGVsZXRlZDogcmVwZWF0ZWRncm91cFsxXTogeyBhOiA5MDQgfVxuIiwKKyAgICAgICAgICAgIFJ1bigpKTsKK30KKworVEVTVF9GKENvbXBhcmlzb25UZXN0LCBSZXBlYXRlZFNldE9wdGlvblRlc3RfRXgpIHsKKyAgcmVwZWF0ZWRfZmllbGRfYXNfc2V0KCk7CisKKyAgcHJvdG8xZXhfLkNsZWFyRXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0OjpyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb24pOworICBwcm90bzJleF8uQ2xlYXJFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbik7CisgIHByb3RvMmV4Xy5BZGRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbikKKyAgICAgIC0+c2V0X2JiKDkwOSk7CisgIHByb3RvMmV4Xy5BZGRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbikKKyAgICAgIC0+c2V0X2JiKDkwNyk7CisgIHByb3RvMWV4Xy5BZGRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbikKKyAgICAgIC0+c2V0X2JiKDkwNCk7CisgIHByb3RvMWV4Xy5BZGRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbikKKyAgICAgIC0+c2V0X2JiKDkwNyk7CisgIHByb3RvMWV4Xy5BZGRFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3Q6OnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbikKKyAgICAgIC0+c2V0X2JiKDkwOSk7CisKKyAgRVhQRUNUX0VRKCJtb3ZlZDogKHByb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbilbMl0gLT4iCisgICAgICAgICAgICAiIChwcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb24pWzBdIDoiCisgICAgICAgICAgICAiIHsgYmI6IDkwOSB9XG4iCisgICAgICAgICAgICAiZGVsZXRlZDogKHByb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbilbMF06IgorICAgICAgICAgICAgIiB7IGJiOiA5MDQgfVxuIiwKKyAgICAgICAgICAgIFJ1bkV4KCkpOworfQorCitURVNUX0YoQ29tcGFyaXNvblRlc3QsIFJlcGVhdGVkTWFwRmllbGRUZXN0X0dyb3VwKSB7CisgIGZpZWxkX2FzX21hcCgicmVwZWF0ZWRncm91cCIsICJhIik7CisgIHByb3RvMV8uY2xlYXJfcmVwZWF0ZWRncm91cCgpOworICBwcm90bzJfLmNsZWFyX3JlcGVhdGVkZ3JvdXAoKTsKKworICBwcm90bzFfLmFkZF9yZXBlYXRlZGdyb3VwKCktPnNldF9hKDMxNyk7ICAvLyBkZWxldGVkCisgIHByb3RvMV8uYWRkX3JlcGVhdGVkZ3JvdXAoKS0+c2V0X2EoOTA0KTsgIC8vIGRlbGV0ZWQKKyAgcHJvdG8xXy5hZGRfcmVwZWF0ZWRncm91cCgpLT5zZXRfYSg5MDcpOyAgLy8gbW92ZWQgZnJvbQorICBwcm90bzFfLmFkZF9yZXBlYXRlZGdyb3VwKCktPnNldF9hKDkwOSk7ICAvLyBtb3ZlZCBmcm9tCisKKyAgcHJvdG8yXy5hZGRfcmVwZWF0ZWRncm91cCgpLT5zZXRfYSg5MDkpOyAgLy8gbW92ZWQgdG8KKyAgcHJvdG8yXy5hZGRfcmVwZWF0ZWRncm91cCgpLT5zZXRfYSgzMTgpOyAgLy8gYWRkZWQKKyAgcHJvdG8yXy5hZGRfcmVwZWF0ZWRncm91cCgpLT5zZXRfYSg5MDcpOyAgLy8gbW92ZWQgdG8KKworICBFWFBFQ1RfRVEoIm1vdmVkOiByZXBlYXRlZGdyb3VwWzNdIC0+IHJlcGVhdGVkZ3JvdXBbMF0gOiB7IGE6IDkwOSB9XG4iCisgICAgICAgICAgICAiYWRkZWQ6IHJlcGVhdGVkZ3JvdXBbMV06IHsgYTogMzE4IH1cbiIKKyAgICAgICAgICAgICJkZWxldGVkOiByZXBlYXRlZGdyb3VwWzBdOiB7IGE6IDMxNyB9XG4iCisgICAgICAgICAgICAiZGVsZXRlZDogcmVwZWF0ZWRncm91cFsxXTogeyBhOiA5MDQgfVxuIiwKKyAgICAgICAgICAgIFJ1bigpKTsKK30KKworVEVTVF9GKENvbXBhcmlzb25UZXN0LCBSZXBlYXRlZE1hcEZpZWxkVGVzdF9NZXNzYWdlS2V5KSB7CisgIC8vIFVzZSBtIGFzIGtleSwgYnV0IHVzZSBiIGFzIHZhbHVlLgorICBmaWVsZF9hc19tYXAoIml0ZW0iLCAibSIpOworCisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0RGlmZk1lc3NhZ2UgbXNnMTsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3REaWZmTWVzc2FnZSBtc2cyOworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdERpZmZNZXNzYWdlOjpJdGVtKiBpdGVtID0gbXNnMS5hZGRfaXRlbSgpOworCisgIC8vIFRoZSBmb2xsb3dpbmcgY29kZSBjcmVhdGVzIG9uZSBkZWxldGlvbiwgb25lIGFkZGl0aW9uIGFuZCB0d28gbW92ZWQgZmllbGRzCisgIC8vIG9uIHRoZSBtZXNzYWdlcy4KKyAgaXRlbS0+bXV0YWJsZV9tKCktPnNldF9jKDApOworICBpdGVtLT5zZXRfYigiZmlyc3QiKTsKKyAgaXRlbSA9IG1zZzEuYWRkX2l0ZW0oKTsKKyAgaXRlbS0+bXV0YWJsZV9tKCktPnNldF9jKDIpOworICBpdGVtLT5zZXRfYigic2Vjb25kIik7CisgIGl0ZW0gPSBtc2cxLmFkZF9pdGVtKCk7IGl0ZW0tPnNldF9iKCJudWxsIik7ICAvLyBlbXB0eSBrZXkgbW92ZWQKKyAgaXRlbSA9IG1zZzEuYWRkX2l0ZW0oKTsKKyAgaXRlbS0+bXV0YWJsZV9tKCktPnNldF9jKDMpOworICBpdGVtLT5zZXRfYigidGhpcmQiKTsgICAvLyBkZWxldGlvbgorICBpdGVtID0gbXNnMS5hZGRfaXRlbSgpOworICBpdGVtLT5tdXRhYmxlX20oKS0+c2V0X2MoMik7CisgIGl0ZW0tPnNldF9iKCJzZWNvbmQiKTsgIC8vIGR1cGxpY2F0ZWQga2V5ICggZGVsZXRpb24gKQorICBpdGVtID0gbXNnMi5hZGRfaXRlbSgpOworICBpdGVtLT5tdXRhYmxlX20oKS0+c2V0X2MoMik7CisgIGl0ZW0tPnNldF9iKCJzZWNvbmQiKTsgIC8vIG1vZGlmaWNhdGlvbgorICBpdGVtID0gbXNnMi5hZGRfaXRlbSgpOworICBpdGVtLT5tdXRhYmxlX20oKS0+c2V0X2MoNCk7CisgIGl0ZW0tPnNldF9iKCJmb3VydGgiKTsgIC8vIGFkZGl0aW9uCisgIGl0ZW0gPSBtc2cyLmFkZF9pdGVtKCk7CisgIGl0ZW0tPm11dGFibGVfbSgpLT5zZXRfYygwKTsKKyAgaXRlbS0+c2V0X2IoImZpc3QiKTsgICAgLy8gbW92ZSB3aXRoIGNoYW5nZQorICBpdGVtID0gbXNnMi5hZGRfaXRlbSgpOyBpdGVtLT5zZXRfYigibnVsbCIpOworCisgIEVYUEVDVF9FUSgKKyAgICAgICJtb2RpZmllZDogaXRlbVswXS5iIC0+IGl0ZW1bMl0uYjogXCJmaXJzdFwiIC0+IFwiZmlzdFwiXG4iCisgICAgICAibW92ZWQ6IGl0ZW1bMV0gLT4gaXRlbVswXSA6IHsgYjogXCJzZWNvbmRcIiBtIHsgYzogMiB9IH1cbiIKKyAgICAgICJtb3ZlZDogaXRlbVsyXSAtPiBpdGVtWzNdIDogeyBiOiBcIm51bGxcIiB9XG4iCisgICAgICAiYWRkZWQ6IGl0ZW1bMV06IHsgYjogXCJmb3VydGhcIiBtIHsgYzogNCB9IH1cbiIKKyAgICAgICJkZWxldGVkOiBpdGVtWzNdOiB7IGI6IFwidGhpcmRcIiBtIHsgYzogMyB9IH1cbiIKKyAgICAgICJkZWxldGVkOiBpdGVtWzRdOiB7IGI6IFwic2Vjb25kXCIgbSB7IGM6IDIgfSB9XG4iLAorICAgICAgUnVuKG1zZzEsIG1zZzIpKTsKK30KKworVEVTVF9GKENvbXBhcmlzb25UZXN0LCBSZXBlYXRlZEZpZWxkU2V0VGVzdF9TZXRPZlNldCkgeworICByZXBlYXRlZF9maWVsZF9hc19zZXQoKTsKKyAgLy8gQ3JlYXRlIHRoZSB0ZXN0aW5nIHByb3RvcworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdERpZmZNZXNzYWdlIG1zZzE7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0RGlmZk1lc3NhZ2UgbXNnMjsKKworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdERpZmZNZXNzYWdlOjpJdGVtKiBpdGVtID0gbXNnMS5hZGRfaXRlbSgpOworICBpdGVtLT5hZGRfcmEoMSk7IGl0ZW0tPmFkZF9yYSgyKTsgaXRlbS0+YWRkX3JhKDMpOworICBpdGVtID0gbXNnMS5hZGRfaXRlbSgpOworICBpdGVtLT5hZGRfcmEoNSk7IGl0ZW0tPmFkZF9yYSg2KTsKKyAgaXRlbSA9IG1zZzEuYWRkX2l0ZW0oKTsKKyAgaXRlbS0+YWRkX3JhKDEpOyBpdGVtLT5hZGRfcmEoMyk7CisgIGl0ZW0gPSBtc2cxLmFkZF9pdGVtKCk7CisgIGl0ZW0tPmFkZF9yYSg2KTsgaXRlbS0+YWRkX3JhKDcpOyBpdGVtLT5hZGRfcmEoOCk7CisKKyAgaXRlbSA9IG1zZzIuYWRkX2l0ZW0oKTsKKyAgaXRlbS0+YWRkX3JhKDYpOyBpdGVtLT5hZGRfcmEoNSk7CisgIGl0ZW0gPSBtc2cyLmFkZF9pdGVtKCk7CisgIGl0ZW0tPmFkZF9yYSg2KTsgaXRlbS0+YWRkX3JhKDgpOworICBpdGVtID0gbXNnMi5hZGRfaXRlbSgpOworICBpdGVtLT5hZGRfcmEoMSk7IGl0ZW0tPmFkZF9yYSgzKTsKKyAgaXRlbSA9IG1zZzIuYWRkX2l0ZW0oKTsKKyAgaXRlbS0+YWRkX3JhKDMpOyBpdGVtLT5hZGRfcmEoMik7IGl0ZW0tPmFkZF9yYSgxKTsKKworICAvLyBDb21wYXJlCisgIEVYUEVDVF9FUSgibW92ZWQ6IGl0ZW1bMF0ucmFbMF0gLT4gaXRlbVszXS5yYVsyXSA6IDFcbiIKKyAgICAgICAgICAgICJtb3ZlZDogaXRlbVswXS5yYVsyXSAtPiBpdGVtWzNdLnJhWzBdIDogM1xuIgorICAgICAgICAgICAgIm1vdmVkOiBpdGVtWzBdIC0+IGl0ZW1bM10gOiB7IHJhOiAxIHJhOiAyIHJhOiAzIH1cbiIKKyAgICAgICAgICAgICJtb3ZlZDogaXRlbVsxXS5yYVswXSAtPiBpdGVtWzBdLnJhWzFdIDogNVxuIgorICAgICAgICAgICAgIm1vdmVkOiBpdGVtWzFdLnJhWzFdIC0+IGl0ZW1bMF0ucmFbMF0gOiA2XG4iCisgICAgICAgICAgICAibW92ZWQ6IGl0ZW1bMV0gLT4gaXRlbVswXSA6IHsgcmE6IDUgcmE6IDYgfVxuIgorICAgICAgICAgICAgImFkZGVkOiBpdGVtWzFdOiB7IHJhOiA2IHJhOiA4IH1cbiIKKyAgICAgICAgICAgICJkZWxldGVkOiBpdGVtWzNdOiB7IHJhOiA2IHJhOiA3IHJhOiA4IH1cbiIsCisgICAgICAgICAgICBSdW4obXNnMSwgbXNnMikpOworfQorCitURVNUX0YoQ29tcGFyaXNvblRlc3QsIFJlcGVhdGVkTWFwRmllbGRUZXN0X1JlcGVhdGVkS2V5KSB7CisgIC8vIHVzZWQgcmIgYXMgYSBrZXksIGJ1dCBiIGlzIHRoZSB2YWx1ZS4KKyAgcmVwZWF0ZWRfZmllbGRfYXNfc2V0KCk7CisgIGZpZWxkX2FzX21hcCgiaXRlbSIsICJyYiIpOworCisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0RGlmZk1lc3NhZ2UgbXNnMTsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3REaWZmTWVzc2FnZSBtc2cyOworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdERpZmZNZXNzYWdlOjpJdGVtKiBpdGVtID0gbXNnMS5hZGRfaXRlbSgpOworICBpdGVtLT5hZGRfcmIoImEiKTsKKyAgaXRlbS0+YWRkX3JiKCJiIik7CisgIGl0ZW0tPnNldF9iKCJmaXJzdCIpOworCisgIGl0ZW0gPSBtc2cyLmFkZF9pdGVtKCk7CisgIGl0ZW0tPmFkZF9yYigiYyIpOworICBpdGVtLT5zZXRfYigic2Vjb25kIik7CisKKyAgaXRlbSA9IG1zZzIuYWRkX2l0ZW0oKTsKKyAgaXRlbS0+YWRkX3JiKCJiIik7CisgIGl0ZW0tPmFkZF9yYigiYSIpOworICBpdGVtLT5zZXRfYigiZmlzdCIpOworCisKKyAgRVhQRUNUX0VRKCJtb2RpZmllZDogaXRlbVswXS5iIC0+IGl0ZW1bMV0uYjogXCJmaXJzdFwiIC0+IFwiZmlzdFwiXG4iCisgICAgICAgICAgICAibW92ZWQ6IGl0ZW1bMF0ucmJbMF0gLT4gaXRlbVsxXS5yYlsxXSA6IFwiYVwiXG4iCisgICAgICAgICAgICAibW92ZWQ6IGl0ZW1bMF0ucmJbMV0gLT4gaXRlbVsxXS5yYlswXSA6IFwiYlwiXG4iCisgICAgICAgICAgICAiYWRkZWQ6IGl0ZW1bMF06IHsgYjogXCJzZWNvbmRcIiByYjogXCJjXCIgfVxuIiwKKyAgICAgICAgICAgIFJ1bihtc2cxLCBtc2cyKSk7Cit9CisKK1RFU1RfRihDb21wYXJpc29uVGVzdCwgUmVwZWF0ZWRNYXBGaWVsZFRlc3RfUmVwZWF0ZWRNZXNzYWdlS2V5KSB7CisgIGZpZWxkX2FzX21hcCgiaXRlbSIsICJybSIpOworCisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0RGlmZk1lc3NhZ2UgbXNnMTsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3REaWZmTWVzc2FnZSBtc2cyOworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdERpZmZNZXNzYWdlOjpJdGVtKiBpdGVtID0gbXNnMS5hZGRfaXRlbSgpOworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEZpZWxkKiBrZXkgPSBpdGVtLT5hZGRfcm0oKTsKKyAga2V5LT5zZXRfYygyKTsga2V5LT5hZGRfcmMoMTApOyBrZXktPmFkZF9yYygxMCk7CisgIGl0ZW0gPSBtc2cxLmFkZF9pdGVtKCk7IGtleSA9IGl0ZW0tPmFkZF9ybSgpOworICBrZXktPnNldF9jKDApOyBrZXktPmFkZF9yYygxKTsga2V5LT5hZGRfcmMoMik7CisgIGtleSA9IGl0ZW0tPmFkZF9ybSgpOworICBrZXktPnNldF9jKDApOworICBpdGVtLT5hZGRfcmIoImZpcnN0Iik7CisKKyAgaXRlbSA9IG1zZzIuYWRkX2l0ZW0oKTsKKyAgaXRlbS0+Q29weUZyb20obXNnMS5pdGVtKDEpKTsKKyAgaXRlbS0+YWRkX3JiKCJzZWNvbmQiKTsKKworICBFWFBFQ1RfRVEoImFkZGVkOiBpdGVtWzBdLnJiWzFdOiBcInNlY29uZFwiXG4iCisgICAgICAgICAgICAiZGVsZXRlZDogaXRlbVswXTogeyBybSB7IGM6IDIgcmM6IDEwIHJjOiAxMCB9IH1cbiIsCisgICAgICAgICAgICBSdW4obXNnMSwgbXNnMikpOworfQorCitURVNUX0YoQ29tcGFyaXNvblRlc3QsIFJlcGVhdGVkU2V0T3B0aW9uVGVzdF9Vbmtub3duKSB7CisgIC8vIEN1cnJlbnRseSwgYXNfc2V0IG9wdGlvbiBkb2Vucyd0IGhhdmUgYWZmZWN0cyBvbiB1bmtub3duIGZpZWxkLgorICAvLyBJZiBuZWVkZWQsIHRoaXMgZmVhdHVyZSB3aWxsIGJlIGFkZGVkIGJ5IHJlcXVlc3QuCisgIHJlcGVhdGVkX2ZpZWxkX2FzX3NldCgpOworICB1bmtub3duMV8tPkFkZEdyb3VwKDI0NSktPkFkZEZpeGVkMzIoMjQ4LCAxKTsKKyAgdW5rbm93bjJfLT5BZGRHcm91cCgyNDUpLT5BZGRGaXhlZDMyKDI0OCwgMyk7CisgIHVua25vd24yXy0+QWRkR3JvdXAoMjQ1KS0+QWRkRml4ZWQzMigyNDgsIDEpOworCisgIC8vIFdlIGV4cGVjdCBpdCBiZWhhdmVzIHRoZSBzYW1lIGFzIG5vcm1hbCBjb21wYXJpc29uLgorICBFWFBFQ1RfRVEoIm1vZGlmaWVkOiAyNDVbMF0uMjQ4WzBdOiAweDAwMDAwMDAxIC0+IDB4MDAwMDAwMDNcbiIKKyAgICAgICAgICAgICJhZGRlZDogMjQ1WzFdOiB7IC4uLiB9XG4iLAorICAgICAgICAgICAgUnVuVW4oKSk7Cit9CisKK1RFU1RfRihDb21wYXJpc29uVGVzdCwgTWF0Y2hpbmdfVW5rbm93bikgeworICB1bmtub3duMV8tPkFkZEdyb3VwKDI0NSktPkFkZEZpeGVkMzIoMjQ4LCAxKTsKKyAgdW5rbm93bjJfLT5BZGRHcm91cCgyNDUpLT5BZGRGaXhlZDMyKDI0OCwgMSk7CisgIHVua25vd24xXy0+QWRkR3JvdXAoMjQ1KS0+QWRkRml4ZWQzMigyNDgsIDMpOworICB1bmtub3duMl8tPkFkZEdyb3VwKDI0NSktPkFkZEZpeGVkMzIoMjQ4LCAzKTsKKyAgdW5rbm93bjJfLT5BZGRMZW5ndGhEZWxpbWl0ZWQoMjQyLCAiY2F0Iik7CisgIHVua25vd24yXy0+QWRkR3JvdXAoMjQ2KS0+QWRkRml4ZWQzMigyNDgsIDQpOworCisgIC8vIHJlcG9ydF9tYXRjaCBpcyBmYWxzZSBzbyBvbmx5IGFkZGVkL21vZGlmaWVkIGZpZWxkcyBhcmUgZXhwZWN0ZWQuCisgIEVYUEVDVF9FUSgiYWRkZWQ6IDI0MlswXTogXCJjYXRcIlxuIgorICAgICAgICAgICAgImFkZGVkOiAyNDZbMF06IHsgLi4uIH1cbiIsCisgICAgICAgICAgICBSdW5VbigpKTsKK30KKworVEVTVF9GKENvbXBhcmlzb25UZXN0LCBSZXBlYXRlZFNldEZpZWxkVGVzdCkgeworICBmaWVsZF9hc19zZXQoInJlcGVhdGVkZ3JvdXAiKTsKKworICBwcm90bzFfLmNsZWFyX3JlcGVhdGVkZ3JvdXAoKTsKKyAgcHJvdG8yXy5jbGVhcl9yZXBlYXRlZGdyb3VwKCk7CisgIHByb3RvMl8uYWRkX3JlcGVhdGVkZ3JvdXAoKS0+c2V0X2EoOTA5KTsKKyAgcHJvdG8yXy5hZGRfcmVwZWF0ZWRncm91cCgpLT5zZXRfYSg5MDcpOworICBwcm90bzFfLmFkZF9yZXBlYXRlZGdyb3VwKCktPnNldF9hKDMxNyk7CisgIHByb3RvMV8uYWRkX3JlcGVhdGVkZ3JvdXAoKS0+c2V0X2EoOTA0KTsKKyAgcHJvdG8xXy5hZGRfcmVwZWF0ZWRncm91cCgpLT5zZXRfYSg5MDcpOworICBwcm90bzFfLmFkZF9yZXBlYXRlZGdyb3VwKCktPnNldF9hKDkwOSk7CisKKyAgRVhQRUNUX0VRKCJtb3ZlZDogcmVwZWF0ZWRncm91cFsyXSAtPiByZXBlYXRlZGdyb3VwWzFdIDogeyBhOiA5MDcgfVxuIgorICAgICAgICAgICAgIm1vdmVkOiByZXBlYXRlZGdyb3VwWzNdIC0+IHJlcGVhdGVkZ3JvdXBbMF0gOiB7IGE6IDkwOSB9XG4iCisgICAgICAgICAgICAiZGVsZXRlZDogcmVwZWF0ZWRncm91cFswXTogeyBhOiAzMTcgfVxuIgorICAgICAgICAgICAgImRlbGV0ZWQ6IHJlcGVhdGVkZ3JvdXBbMV06IHsgYTogOTA0IH1cbiIsCisgICAgICAgICAgICBSdW4oKSk7Cit9CisKKy8vIEVtYmVkZGVkIG1lc3NhZ2UgdGVzdHMuCitURVNUX0YoQ29tcGFyaXNvblRlc3QsIEVtYmVkZGVkQWRkaXRpb25UZXN0KSB7CisgIHByb3RvMV8ubXV0YWJsZV9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpLT5jbGVhcl9iYigpOworCisgIEVYUEVDVF9FUSgiYWRkZWQ6IG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlLmJiOiAxMThcbiIsCisgICAgICAgICAgICBSdW4oKSk7Cit9CisKK1RFU1RfRihDb21wYXJpc29uVGVzdCwgRW1iZWRkZWREZWxldGlvblRlc3QpIHsKKyAgcHJvdG8yXy5tdXRhYmxlX29wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCktPmNsZWFyX2JiKCk7CisKKyAgRVhQRUNUX0VRKCJkZWxldGVkOiBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZS5iYjogMTE4XG4iLAorICAgICAgICAgICAgUnVuKCkpOworfQorCitURVNUX0YoQ29tcGFyaXNvblRlc3QsIEVtYmVkZGVkTW9kaWZpY2F0aW9uVGVzdCkgeworICBwcm90bzFfLm11dGFibGVfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKS0+c2V0X2JiKDIpOworCisgIEVYUEVDVF9FUSgibW9kaWZpZWQ6IG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlLmJiOiAyIC0+IDExOFxuIiwKKyAgICAgICAgICAgIFJ1bigpKTsKK30KKworVEVTVF9GKENvbXBhcmlzb25UZXN0LCBFbWJlZGRlZEZ1bGxBZGRpdGlvblRlc3QpIHsKKyAgcHJvdG8xXy5jbGVhcl9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpOworCisgIEVYUEVDVF9FUSgiYWRkZWQ6IG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlOiB7IGJiOiAxMTggfVxuIiwKKyAgICAgICAgICAgIFJ1bigpKTsKK30KKworVEVTVF9GKENvbXBhcmlzb25UZXN0LCBFbWJlZGRlZFBhcnRpYWxBZGRpdGlvblRlc3QpIHsKKyAgcHJvdG8xXy5jbGVhcl9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSgpOworICBwcm90bzJfLm11dGFibGVfb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UoKS0+Y2xlYXJfYmIoKTsKKworICBFWFBFQ1RfRVEoImFkZGVkOiBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZTogeyB9XG4iLAorICAgICAgICAgICAgUnVuKCkpOworfQorCitURVNUX0YoQ29tcGFyaXNvblRlc3QsIEVtYmVkZGVkRnVsbERlbGV0aW9uVGVzdCkgeworICBwcm90bzJfLmNsZWFyX29wdGlvbmFsX25lc3RlZF9tZXNzYWdlKCk7CisKKyAgRVhQRUNUX0VRKCJkZWxldGVkOiBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZTogeyBiYjogMTE4IH1cbiIsCisgICAgICAgICAgICBSdW4oKSk7Cit9CisKKy8vIFJlcGVhdGVkIGVsZW1lbnQgdGVzdHMuCitURVNUX0YoQ29tcGFyaXNvblRlc3QsIEJhc2ljUmVwZWF0ZWRUZXN0KSB7CisgIHByb3RvMV8uY2xlYXJfcmVwZWF0ZWRfaW50MzIoKTsKKyAgcHJvdG8yXy5jbGVhcl9yZXBlYXRlZF9pbnQzMigpOworCisgIHByb3RvMV8uYWRkX3JlcGVhdGVkX2ludDMyKDUwMCk7CisgIHByb3RvMV8uYWRkX3JlcGVhdGVkX2ludDMyKDUwMSk7CisgIHByb3RvMV8uYWRkX3JlcGVhdGVkX2ludDMyKDUwMik7CisgIHByb3RvMV8uYWRkX3JlcGVhdGVkX2ludDMyKDUwMyk7CisgIHByb3RvMV8uYWRkX3JlcGVhdGVkX2ludDMyKDUwMCk7CisKKyAgcHJvdG8yXy5hZGRfcmVwZWF0ZWRfaW50MzIoNTAwKTsKKyAgcHJvdG8yXy5hZGRfcmVwZWF0ZWRfaW50MzIoNTA5KTsKKyAgcHJvdG8yXy5hZGRfcmVwZWF0ZWRfaW50MzIoNTAyKTsKKyAgcHJvdG8yXy5hZGRfcmVwZWF0ZWRfaW50MzIoNTA0KTsKKworICBFWFBFQ1RfRVEoIm1vZGlmaWVkOiByZXBlYXRlZF9pbnQzMlsxXTogNTAxIC0+IDUwOVxuIgorICAgICAgICAgICAgIm1vZGlmaWVkOiByZXBlYXRlZF9pbnQzMlszXTogNTAzIC0+IDUwNFxuIgorICAgICAgICAgICAgImRlbGV0ZWQ6IHJlcGVhdGVkX2ludDMyWzRdOiA1MDBcbiIsCisgICAgICAgICAgICBSdW4oKSk7Cit9CisKK1RFU1RfRihDb21wYXJpc29uVGVzdCwgQmFzaWNSZXBlYXRlZFRlc3RfU2V0T3B0aW9uKSB7CisgIHJlcGVhdGVkX2ZpZWxkX2FzX3NldCgpOworICBwcm90bzFfLmNsZWFyX3JlcGVhdGVkX2ludDMyKCk7CisgIHByb3RvMl8uY2xlYXJfcmVwZWF0ZWRfaW50MzIoKTsKKworICBwcm90bzFfLmFkZF9yZXBlYXRlZF9pbnQzMig1MDEpOworICBwcm90bzFfLmFkZF9yZXBlYXRlZF9pbnQzMig1MDIpOworICBwcm90bzFfLmFkZF9yZXBlYXRlZF9pbnQzMig1MDMpOworICBwcm90bzFfLmFkZF9yZXBlYXRlZF9pbnQzMig1MDApOworICBwcm90bzFfLmFkZF9yZXBlYXRlZF9pbnQzMig1MDApOworCisgIHByb3RvMl8uYWRkX3JlcGVhdGVkX2ludDMyKDUwMCk7CisgIHByb3RvMl8uYWRkX3JlcGVhdGVkX2ludDMyKDUwOSk7CisgIHByb3RvMl8uYWRkX3JlcGVhdGVkX2ludDMyKDUwMyk7CisgIHByb3RvMl8uYWRkX3JlcGVhdGVkX2ludDMyKDUwMik7CisgIHByb3RvMl8uYWRkX3JlcGVhdGVkX2ludDMyKDUwNCk7CisKKyAgRVhQRUNUX0VRKCJtb3ZlZDogcmVwZWF0ZWRfaW50MzJbMV0gLT4gcmVwZWF0ZWRfaW50MzJbM10gOiA1MDJcbiIKKyAgICAgICAgICAgICJtb3ZlZDogcmVwZWF0ZWRfaW50MzJbM10gLT4gcmVwZWF0ZWRfaW50MzJbMF0gOiA1MDBcbiIKKyAgICAgICAgICAgICJhZGRlZDogcmVwZWF0ZWRfaW50MzJbMV06IDUwOVxuIgorICAgICAgICAgICAgImFkZGVkOiByZXBlYXRlZF9pbnQzMls0XTogNTA0XG4iCisgICAgICAgICAgICAiZGVsZXRlZDogcmVwZWF0ZWRfaW50MzJbMF06IDUwMVxuIgorICAgICAgICAgICAgImRlbGV0ZWQ6IHJlcGVhdGVkX2ludDMyWzRdOiA1MDBcbiIsCisgICAgICAgICAgICBSdW4oKSk7Cit9CisKK1RFU1RfRihDb21wYXJpc29uVGVzdCwgQmFzaWNSZXBlYXRlZFRlc3RfU2V0RmllbGQpIHsKKyAgZmllbGRfYXNfc2V0KCJyZXBlYXRlZF9pbnQzMiIpOworICBwcm90bzFfLmNsZWFyX3JlcGVhdGVkX2ludDMyKCk7CisgIHByb3RvMl8uY2xlYXJfcmVwZWF0ZWRfaW50MzIoKTsKKworICBwcm90bzFfLmFkZF9yZXBlYXRlZF9pbnQzMig1MDEpOworICBwcm90bzFfLmFkZF9yZXBlYXRlZF9pbnQzMig1MDIpOworICBwcm90bzFfLmFkZF9yZXBlYXRlZF9pbnQzMig1MDMpOworICBwcm90bzFfLmFkZF9yZXBlYXRlZF9pbnQzMig1MDApOworICBwcm90bzFfLmFkZF9yZXBlYXRlZF9pbnQzMig1MDApOworCisgIHByb3RvMl8uYWRkX3JlcGVhdGVkX2ludDMyKDUwMCk7CisgIHByb3RvMl8uYWRkX3JlcGVhdGVkX2ludDMyKDUwOSk7CisgIHByb3RvMl8uYWRkX3JlcGVhdGVkX2ludDMyKDUwMyk7CisgIHByb3RvMl8uYWRkX3JlcGVhdGVkX2ludDMyKDUwMik7CisgIHByb3RvMl8uYWRkX3JlcGVhdGVkX2ludDMyKDUwNCk7CisKKyAgRVhQRUNUX0VRKCJtb3ZlZDogcmVwZWF0ZWRfaW50MzJbMV0gLT4gcmVwZWF0ZWRfaW50MzJbM10gOiA1MDJcbiIKKyAgICAgICAgICAgICJtb3ZlZDogcmVwZWF0ZWRfaW50MzJbM10gLT4gcmVwZWF0ZWRfaW50MzJbMF0gOiA1MDBcbiIKKyAgICAgICAgICAgICJhZGRlZDogcmVwZWF0ZWRfaW50MzJbMV06IDUwOVxuIgorICAgICAgICAgICAgImFkZGVkOiByZXBlYXRlZF9pbnQzMls0XTogNTA0XG4iCisgICAgICAgICAgICAiZGVsZXRlZDogcmVwZWF0ZWRfaW50MzJbMF06IDUwMVxuIgorICAgICAgICAgICAgImRlbGV0ZWQ6IHJlcGVhdGVkX2ludDMyWzRdOiA1MDBcbiIsCisgICAgICAgICAgICBSdW4oKSk7Cit9CisKKy8vIE11bHRpcGxlIGFjdGlvbiB0ZXN0cy4KK1RFU1RfRihDb21wYXJpc29uVGVzdCwgQWRkRGVsZXRlVGVzdCkgeworICBwcm90bzFfLmNsZWFyX29wdGlvbmFsX2ludDMyKCk7CisgIHByb3RvMl8uY2xlYXJfb3B0aW9uYWxfaW50NjQoKTsKKworICBFWFBFQ1RfRVEoImFkZGVkOiBvcHRpb25hbF9pbnQzMjogMTAxXG4iCisgICAgICAgICAgICAiZGVsZXRlZDogb3B0aW9uYWxfaW50NjQ6IDEwMlxuIiwKKyAgICAgICAgICAgIFJ1bigpKTsKK30KKworVEVTVF9GKENvbXBhcmlzb25UZXN0LCBBZGREZWxldGVfRmllbGRPcmRlcmluZ1Rlc3QpIHsKKyAgb3JkZXJpbmdzX3Byb3RvMV8uQ2xlYXJFeHRlbnNpb24odW5pdHRlc3Q6Om15X2V4dGVuc2lvbl9zdHJpbmcpOworICBvcmRlcmluZ3NfcHJvdG8yXy5jbGVhcl9teV9pbnQoKTsKKworICBFWFBFQ1RfRVEoImRlbGV0ZWQ6IG15X2ludDogMVxuIgorICAgICAgICAgICAgImFkZGVkOiAocHJvdG9idWZfdW5pdHRlc3QubXlfZXh0ZW5zaW9uX3N0cmluZyk6IFwiYmFyXCJcbiIsCisgICAgICAgICAgICBSdW5PcmRlcigpKTsKK30KKworVEVTVF9GKENvbXBhcmlzb25UZXN0LCBBbGxUaHJlZVRlc3QpIHsKKyAgcHJvdG8xXy5jbGVhcl9vcHRpb25hbF9pbnQzMigpOworICBwcm90bzJfLmNsZWFyX29wdGlvbmFsX2Zsb2F0KCk7CisgIHByb3RvMl8uc2V0X29wdGlvbmFsX3N0cmluZygiaGVsbG8gd29ybGQhIik7CisKKyAgRVhQRUNUX0VRKCJhZGRlZDogb3B0aW9uYWxfaW50MzI6IDEwMVxuIgorICAgICAgICAgICAgImRlbGV0ZWQ6IG9wdGlvbmFsX2Zsb2F0OiAxMTFcbiIKKyAgICAgICAgICAgICJtb2RpZmllZDogb3B0aW9uYWxfc3RyaW5nOiBcIjExNVwiIC0+IFwiaGVsbG8gd29ybGQhXCJcbiIsCisgICAgICAgICAgICBSdW4oKSk7Cit9CisKK1RFU1RfRihDb21wYXJpc29uVGVzdCwgU2FuZHdoaWNoVGVzdCkgeworICBwcm90bzFfLmNsZWFyX29wdGlvbmFsX2ludDY0KCk7CisgIHByb3RvMV8uY2xlYXJfb3B0aW9uYWxfdWludDMyKCk7CisKKyAgcHJvdG8yXy5jbGVhcl9vcHRpb25hbF91aW50NjQoKTsKKworICBFWFBFQ1RfRVEoImFkZGVkOiBvcHRpb25hbF9pbnQ2NDogMTAyXG4iCisgICAgICAgICAgICAiYWRkZWQ6IG9wdGlvbmFsX3VpbnQzMjogMTAzXG4iCisgICAgICAgICAgICAiZGVsZXRlZDogb3B0aW9uYWxfdWludDY0OiAxMDRcbiIsCisgICAgICAgICAgICBSdW4oKSk7Cit9CisKK1RFU1RfRihDb21wYXJpc29uVGVzdCwgSWdub3JlZE5vQ2hhbmdlVGVzdCkgeworICBwcm90bzFkaWZmXy5zZXRfdigzKTsKKyAgcHJvdG8yZGlmZl8uc2V0X3YoMyk7CisgIHByb3RvMmRpZmZfLnNldF93KCJmb28iKTsKKworICBpZ25vcmVfZmllbGQoInYiKTsKKworICBFWFBFQ1RfRVEoImlnbm9yZWQ6IHZcbiIKKyAgICAgICAgICAgICJhZGRlZDogdzogXCJmb29cIlxuIiwKKyAgICAgICAgICAgIFJ1bkRpZmYoKSk7Cit9CisKK1RFU1RfRihDb21wYXJpc29uVGVzdCwgSWdub3JlZEFkZFRlc3QpIHsKKyAgcHJvdG8yZGlmZl8uc2V0X3YoMyk7CisgIHByb3RvMmRpZmZfLnNldF93KCJmb28iKTsKKworICBpZ25vcmVfZmllbGQoInYiKTsKKworICBFWFBFQ1RfRVEoImlnbm9yZWQ6IHZcbiIKKyAgICAgICAgICAgICJhZGRlZDogdzogXCJmb29cIlxuIiwKKyAgICAgICAgICAgIFJ1bkRpZmYoKSk7Cit9CisKK1RFU1RfRihDb21wYXJpc29uVGVzdCwgSWdub3JlZERlbGV0ZVRlc3QpIHsKKyAgcHJvdG8xZGlmZl8uc2V0X3YoMyk7CisgIHByb3RvMmRpZmZfLnNldF93KCJmb28iKTsKKworICBpZ25vcmVfZmllbGQoInYiKTsKKworICBFWFBFQ1RfRVEoImlnbm9yZWQ6IHZcbiIKKyAgICAgICAgICAgICJhZGRlZDogdzogXCJmb29cIlxuIiwKKyAgICAgICAgICAgIFJ1bkRpZmYoKSk7Cit9CisKK1RFU1RfRihDb21wYXJpc29uVGVzdCwgSWdub3JlZE1vZGlmeVRlc3QpIHsKKyAgcHJvdG8xZGlmZl8uc2V0X3YoMyk7CisgIHByb3RvMmRpZmZfLnNldF92KDQpOworICBwcm90bzJkaWZmXy5zZXRfdygiZm9vIik7CisKKyAgaWdub3JlX2ZpZWxkKCJ2Iik7CisKKyAgRVhQRUNUX0VRKCJpZ25vcmVkOiB2XG4iCisgICAgICAgICAgICAiYWRkZWQ6IHc6IFwiZm9vXCJcbiIsCisgICAgICAgICAgICBSdW5EaWZmKCkpOworfQorCitURVNUX0YoQ29tcGFyaXNvblRlc3QsIElnbm9yZWRSZXBlYXRlZEFkZFRlc3QpIHsKKyAgcHJvdG8xZGlmZl8uYWRkX3J2KDMpOworICBwcm90bzFkaWZmXy5hZGRfcnYoNCk7CisKKyAgcHJvdG8yZGlmZl8uYWRkX3J2KDMpOworICBwcm90bzJkaWZmXy5hZGRfcnYoNCk7CisgIHByb3RvMmRpZmZfLmFkZF9ydig1KTsKKworICBwcm90bzJkaWZmXy5zZXRfdygiZm9vIik7CisKKyAgaWdub3JlX2ZpZWxkKCJydiIpOworCisgIEVYUEVDVF9FUSgiaWdub3JlZDogcnZcbiIKKyAgICAgICAgICAgICJhZGRlZDogdzogXCJmb29cIlxuIiwKKyAgICAgICAgICAgIFJ1bkRpZmYoKSk7Cit9CisKK1RFU1RfRihDb21wYXJpc29uVGVzdCwgSWdub3JlZFJlcGVhdGVkRGVsZXRlVGVzdCkgeworICBwcm90bzFkaWZmXy5hZGRfcnYoMyk7CisgIHByb3RvMWRpZmZfLmFkZF9ydig0KTsKKyAgcHJvdG8xZGlmZl8uYWRkX3J2KDUpOworCisgIHByb3RvMmRpZmZfLmFkZF9ydigzKTsKKyAgcHJvdG8yZGlmZl8uYWRkX3J2KDQpOworCisgIHByb3RvMmRpZmZfLnNldF93KCJmb28iKTsKKworICBpZ25vcmVfZmllbGQoInJ2Iik7CisKKyAgRVhQRUNUX0VRKCJpZ25vcmVkOiBydlxuIgorICAgICAgICAgICAgImFkZGVkOiB3OiBcImZvb1wiXG4iLAorICAgICAgICAgICAgUnVuRGlmZigpKTsKK30KKworVEVTVF9GKENvbXBhcmlzb25UZXN0LCBJZ25vcmVkUmVwZWF0ZWRNb2RpZnlUZXN0KSB7CisgIHByb3RvMWRpZmZfLmFkZF9ydigzKTsKKyAgcHJvdG8xZGlmZl8uYWRkX3J2KDQpOworCisgIHByb3RvMmRpZmZfLmFkZF9ydigzKTsKKyAgcHJvdG8yZGlmZl8uYWRkX3J2KDUpOworCisgIHByb3RvMmRpZmZfLnNldF93KCJmb28iKTsKKworICBpZ25vcmVfZmllbGQoInJ2Iik7CisKKyAgRVhQRUNUX0VRKCJpZ25vcmVkOiBydlxuIgorICAgICAgICAgICAgImFkZGVkOiB3OiBcImZvb1wiXG4iLAorICAgICAgICAgICAgUnVuRGlmZigpKTsKK30KKworVEVTVF9GKENvbXBhcmlzb25UZXN0LCBJZ25vcmVkV2hvbGVOZXN0ZWRNZXNzYWdlKSB7CisgIHByb3RvMWRpZmZfLm11dGFibGVfbSgpLT5zZXRfYygzKTsKKyAgcHJvdG8yZGlmZl8ubXV0YWJsZV9tKCktPnNldF9jKDQpOworCisgIHByb3RvMmRpZmZfLnNldF93KCJmb28iKTsKKworICBpZ25vcmVfZmllbGQoIm0iKTsKKworICBFWFBFQ1RfRVEoImFkZGVkOiB3OiBcImZvb1wiXG4iCisgICAgICAgICAgICAiaWdub3JlZDogbVxuIiwKKyAgICAgICAgICAgIFJ1bkRpZmYoKSk7Cit9CisKK1RFU1RfRihDb21wYXJpc29uVGVzdCwgSWdub3JlZE5lc3RlZEZpZWxkKSB7CisgIHByb3RvMWRpZmZfLm11dGFibGVfbSgpLT5zZXRfYygzKTsKKyAgcHJvdG8yZGlmZl8ubXV0YWJsZV9tKCktPnNldF9jKDQpOworCisgIHByb3RvMmRpZmZfLnNldF93KCJmb28iKTsKKworICBpZ25vcmVfZmllbGQoIm0uYyIpOworCisgIEVYUEVDVF9FUSgiYWRkZWQ6IHc6IFwiZm9vXCJcbiIKKyAgICAgICAgICAgICJpZ25vcmVkOiBtLmNcbiIsCisgICAgICAgICAgICBSdW5EaWZmKCkpOworfQorCitURVNUX0YoQ29tcGFyaXNvblRlc3QsIElnbm9yZWRSZXBlYXRlZE5lc3RlZCkgeworICBwcm90bzFkaWZmXy5hZGRfcm0oKS0+c2V0X2MoMCk7CisgIHByb3RvMWRpZmZfLmFkZF9ybSgpLT5zZXRfYygxKTsKKyAgcHJvdG8yZGlmZl8uYWRkX3JtKCktPnNldF9jKDIpOworICBwcm90bzJkaWZmXy5hZGRfcm0oKS0+c2V0X2MoMyk7CisKKyAgcHJvdG8yZGlmZl8uc2V0X3coImZvbyIpOworCisgIGlnbm9yZV9maWVsZCgicm0uYyIpOworCisgIEVYUEVDVF9FUSgiaWdub3JlZDogcm1bMF0uY1xuIgorICAgICAgICAgICAgImlnbm9yZWQ6IHJtWzFdLmNcbiIKKyAgICAgICAgICAgICJhZGRlZDogdzogXCJmb29cIlxuIiwKKyAgICAgICAgICAgIFJ1bkRpZmYoKSk7Cit9CisKK1RFU1RfRihDb21wYXJpc29uVGVzdCwgSWdub3JlZE5lc3RlZFJlcGVhdGVkKSB7CisgIHByb3RvMWRpZmZfLm11dGFibGVfbSgpLT5hZGRfcmMoMjMpOworICBwcm90bzFkaWZmXy5tdXRhYmxlX20oKS0+YWRkX3JjKDI0KTsKKyAgcHJvdG8yZGlmZl8ubXV0YWJsZV9tKCktPmFkZF9yYygyNSk7CisKKyAgcHJvdG8yZGlmZl8uc2V0X3coImZvbyIpOworCisgIGlnbm9yZV9maWVsZCgibS5yYyIpOworCisgIEVYUEVDVF9FUSgiYWRkZWQ6IHc6IFwiZm9vXCJcbiIKKyAgICAgICAgICAgICJpZ25vcmVkOiBtLnJjXG4iLAorICAgICAgICAgICAgUnVuRGlmZigpKTsKK30KKworVEVTVF9GKENvbXBhcmlzb25UZXN0LCBFeHRlbnNpb25UZXN0KSB7CisgIHByb3RvMWV4Xy5TZXRFeHRlbnNpb24odW5pdHRlc3Q6Om9wdGlvbmFsX2ludDMyX2V4dGVuc2lvbiwgNDAxKTsKKyAgcHJvdG8yZXhfLlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW50MzJfZXh0ZW5zaW9uLCA0MDIpOworCisgIHByb3RvMWV4Xy5DbGVhckV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW50NjRfZXh0ZW5zaW9uKTsKKyAgcHJvdG8yZXhfLlNldEV4dGVuc2lvbih1bml0dGVzdDo6b3B0aW9uYWxfaW50NjRfZXh0ZW5zaW9uLCA0MDMpOworCisgIEVYUEVDVF9FUSgKKyAgICAgICJtb2RpZmllZDogKHByb3RvYnVmX3VuaXR0ZXN0Lm9wdGlvbmFsX2ludDMyX2V4dGVuc2lvbik6IDQwMSAtPiA0MDJcbiIKKyAgICAgICJhZGRlZDogKHByb3RvYnVmX3VuaXR0ZXN0Lm9wdGlvbmFsX2ludDY0X2V4dGVuc2lvbik6IDQwM1xuIiwKKyAgICAgIFJ1bkV4KCkpOworfQorCitURVNUX0YoQ29tcGFyaXNvblRlc3QsIE1hdGNoZWRVbmtub3duRmllbGRUYWdUZXN0KSB7CisgIHVua25vd24xXy0+QWRkVmFyaW50KDI0MCwgMTIyKTsKKyAgdW5rbm93bjJfLT5BZGRWYXJpbnQoMjQwLCAxMjEpOworICB1bmtub3duMV8tPkFkZEZpeGVkMzIoMjQxLCAxKTsKKyAgdW5rbm93bjJfLT5BZGRGaXhlZDY0KDI0MSwgMik7CisgIHVua25vd24xXy0+QWRkTGVuZ3RoRGVsaW1pdGVkKDI0MiwgImNhdCIpOworICB1bmtub3duMl8tPkFkZExlbmd0aERlbGltaXRlZCgyNDIsICJkb2ciKTsKKworICBFWFBFQ1RfRVEoCisgICAgICAibW9kaWZpZWQ6IDI0MFswXTogMTIyIC0+IDEyMVxuIgorICAgICAgImRlbGV0ZWQ6IDI0MVswXTogMHgwMDAwMDAwMVxuIgorICAgICAgImFkZGVkOiAyNDFbMF06IDB4MDAwMDAwMDAwMDAwMDAwMlxuIgorICAgICAgIm1vZGlmaWVkOiAyNDJbMF06IFwiY2F0XCIgLT4gXCJkb2dcIlxuIiwKKyAgICAgIFJ1blVuKCkpOworfQorCitURVNUX0YoQ29tcGFyaXNvblRlc3QsIFVubWF0Y2hlZFVua25vd25GaWVsZFRhZ1Rlc3QpIHsKKyAgdW5rbm93bjFfLT5BZGRGaXhlZDMyKDI0MywgMSk7CisgIHVua25vd24yXy0+QWRkVmFyaW50KDI0NCwgMik7CisgIHVua25vd24yXy0+QWRkVmFyaW50KDI0NCwgNCk7CisKKyAgRVhQRUNUX0VRKAorICAgICAgImRlbGV0ZWQ6IDI0M1swXTogMHgwMDAwMDAwMVxuIgorICAgICAgImFkZGVkOiAyNDRbMF06IDJcbiIKKyAgICAgICJhZGRlZDogMjQ0WzFdOiA0XG4iLAorICAgICAgUnVuVW4oKSk7Cit9CisKK1RFU1RfRihDb21wYXJpc29uVGVzdCwgRGlmZmVyZW50U2l6ZWRVbmtub3duRmllbGRUZXN0KSB7CisgIHVua25vd24xXy0+QWRkVmFyaW50KDI0MCwgMSk7CisgIHVua25vd24xXy0+QWRkVmFyaW50KDI0MCwgMyk7CisgIHVua25vd24xXy0+QWRkVmFyaW50KDI0MCwgNCk7CisgIHVua25vd24yXy0+QWRkVmFyaW50KDI0MCwgMik7CisgIHVua25vd24yXy0+QWRkVmFyaW50KDI0MCwgMyk7CisgIHVua25vd24yXy0+QWRkVmFyaW50KDI0MCwgMik7CisgIHVua25vd24yXy0+QWRkVmFyaW50KDI0MCwgNSk7CisKKyAgRVhQRUNUX0VRKAorICAgICAgIm1vZGlmaWVkOiAyNDBbMF06IDEgLT4gMlxuIgorICAgICAgIm1vZGlmaWVkOiAyNDBbMl06IDQgLT4gMlxuIgorICAgICAgImFkZGVkOiAyNDBbM106IDVcbiIsCisgICAgICBSdW5VbigpKTsKK30KKworVEVTVF9GKENvbXBhcmlzb25UZXN0LCBVbmtub3duRmllbGRzQWxsKSB7CisgIHVua25vd24xXy0+QWRkVmFyaW50KDI0MywgMTIyKTsKKyAgdW5rbm93bjFfLT5BZGRGaXhlZDY0KDI0NCwgMHgwMTcyMzU2KTsKKyAgdW5rbm93bjFfLT5BZGRGaXhlZDY0KDI0NCwgMHgwOTgpOworICB1bmtub3duMV8tPkFkZEdyb3VwKDI0NSktPkFkZEZpeGVkMzIoMjQ4LCAxKTsKKyAgdW5rbm93bjFfLT5tdXRhYmxlX2ZpZWxkKDMpLT5tdXRhYmxlX2dyb3VwKCktPkFkZEZpeGVkMzIoMjQ4LCAyKTsKKyAgdW5rbm93bjFfLT5BZGRHcm91cCgyNDkpLT5BZGRGaXhlZDY0KDI1MCwgMSk7CisKKyAgdW5rbm93bjJfLT5BZGRWYXJpbnQoMjQzLCAxMjEpOworICB1bmtub3duMl8tPkFkZExlbmd0aERlbGltaXRlZCg3Mzg4MiwgInRlc3QgMTIzIik7CisgIHVua25vd24yXy0+QWRkR3JvdXAoMjQ1KS0+QWRkRml4ZWQzMigyNDgsIDMpOworICB1bmtub3duMl8tPkFkZEdyb3VwKDI0Nyk7CisKKyAgRVhQRUNUX0VRKAorICAgICAgIm1vZGlmaWVkOiAyNDNbMF06IDEyMiAtPiAxMjFcbiIKKyAgICAgICJkZWxldGVkOiAyNDRbMF06IDB4MDAwMDAwMDAwMDE3MjM1NlxuIgorICAgICAgImRlbGV0ZWQ6IDI0NFsxXTogMHgwMDAwMDAwMDAwMDAwMDk4XG4iCisgICAgICAibW9kaWZpZWQ6IDI0NVswXS4yNDhbMF06IDB4MDAwMDAwMDEgLT4gMHgwMDAwMDAwM1xuIgorICAgICAgImRlbGV0ZWQ6IDI0NVswXS4yNDhbMV06IDB4MDAwMDAwMDJcbiIKKyAgICAgICJhZGRlZDogMjQ3WzBdOiB7IC4uLiB9XG4iCisgICAgICAiZGVsZXRlZDogMjQ5WzBdOiB7IC4uLiB9XG4iCisgICAgICAiYWRkZWQ6IDczODgyWzBdOiBcInRlc3QgMTIzXCJcbiIsCisgICAgICBSdW5VbigpKTsKK30KKworVEVTVF9GKENvbXBhcmlzb25UZXN0LCBFcXVpdmFsZW50SWdub3Jlc1Vua25vd24pIHsKKyAgdW5pdHRlc3Q6OkZvcmVpZ25NZXNzYWdlIG1lc3NhZ2UxLCBtZXNzYWdlMjsKKworICBtZXNzYWdlMS5zZXRfYyg1KTsKKyAgbWVzc2FnZTEubXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5BZGRWYXJpbnQoMTIzLCA0NTYpOworICBtZXNzYWdlMi5zZXRfYyg1KTsKKyAgbWVzc2FnZTIubXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5BZGRWYXJpbnQoMzIxLCA2NTQpOworCisgIEVYUEVDVF9GQUxTRSh1dGlsOjpNZXNzYWdlRGlmZmVyZW5jZXI6OkVxdWFscyhtZXNzYWdlMSwgbWVzc2FnZTIpKTsKKyAgRVhQRUNUX1RSVUUodXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyOjpFcXVpdmFsZW50KG1lc3NhZ2UxLCBtZXNzYWdlMikpOworfQorCitjbGFzcyBNYXRjaGluZ1Rlc3QgOiBwdWJsaWMgdGVzdGluZzo6VGVzdCB7CisgcHVibGljOgorICB0eXBlZGVmIHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlciBNZXNzYWdlRGlmZmVyZW5jZXI7CisKKyBwcm90ZWN0ZWQ6CisgIE1hdGNoaW5nVGVzdCgpIHsKKyAgfQorCisgIH5NYXRjaGluZ1Rlc3QoKSB7CisgIH0KKworICBzdHJpbmcgUnVuV2l0aFJlc3VsdChNZXNzYWdlRGlmZmVyZW5jZXIqIGRpZmZlcmVuY2VyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZSYgbXNnMSwgY29uc3QgTWVzc2FnZSYgbXNnMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgcmVzdWx0KSB7CisgICAgc3RyaW5nIG91dHB1dDsKKyAgICB7CisgICAgICAvLyBCZWZvcmUgd2UgcmV0dXJuIHRoZSAib3V0cHV0IiBzdHJpbmcsIHdlIG11c3QgbWFrZSBzdXJlIHRoZQorICAgICAgLy8gU3RyZWFtUmVwb3J0ZXIgaXMgZGVzdHJ1Y3RvcmVkIGJlY2F1c2UgaXRzIGRlc3RydWN0b3Igd2lsbAorICAgICAgLy8gZmx1c2ggdGhlIHN0cmVhbS4KKyAgICAgIGlvOjpTdHJpbmdPdXRwdXRTdHJlYW0gb3V0cHV0X3N0cmVhbSgmb3V0cHV0KTsKKyAgICAgIE1lc3NhZ2VEaWZmZXJlbmNlcjo6U3RyZWFtUmVwb3J0ZXIgcmVwb3J0ZXIoJm91dHB1dF9zdHJlYW0pOworICAgICAgcmVwb3J0ZXIuc2V0X3JlcG9ydF9tb2RpZmllZF9hZ2dyZWdhdGVzKHRydWUpOworICAgICAgZGlmZmVyZW5jZXItPnNldF9yZXBvcnRfbWF0Y2hlcyh0cnVlKTsKKyAgICAgIGRpZmZlcmVuY2VyLT5SZXBvcnREaWZmZXJlbmNlc1RvKCZyZXBvcnRlcik7CisgICAgICBpZiAocmVzdWx0KSB7CisgICAgICAgIEVYUEVDVF9UUlVFKGRpZmZlcmVuY2VyLT5Db21wYXJlKG1zZzEsIG1zZzIpKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIEVYUEVDVF9GQUxTRShkaWZmZXJlbmNlci0+Q29tcGFyZShtc2cxLCBtc2cyKSk7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBvdXRwdXQ7CisgIH0KKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhNYXRjaGluZ1Rlc3QpOworfTsKKworVEVTVF9GKE1hdGNoaW5nVGVzdCwgU3RyZWFtUmVwb3J0ZXJNYXRjaGluZykgeworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEZpZWxkIG1zZzEsIG1zZzI7CisgIG1zZzEuc2V0X2MoNzIpOworICBtc2cyLnNldF9jKDcyKTsKKyAgbXNnMS5hZGRfcmMoMTMpOworICBtc2cyLmFkZF9yYygxMyk7CisgIG1zZzEuYWRkX3JjKDE3KTsKKyAgbXNnMi5hZGRfcmMoMTcpOworICBzdHJpbmcgb3V0cHV0OworICBNZXNzYWdlRGlmZmVyZW5jZXIgZGlmZmVyZW5jZXI7CisgIGRpZmZlcmVuY2VyLnNldF9yZXBvcnRfbWF0Y2hlcyh0cnVlKTsKKyAgZGlmZmVyZW5jZXIuUmVwb3J0RGlmZmVyZW5jZXNUb1N0cmluZygmb3V0cHV0KTsKKyAgRVhQRUNUX1RSVUUoZGlmZmVyZW5jZXIuQ29tcGFyZShtc2cxLCBtc2cyKSk7CisgIEVYUEVDVF9FUSgKKyAgICAgICJtYXRjaGVkOiBjIDogNzJcbiIKKyAgICAgICJtYXRjaGVkOiByY1swXSA6IDEzXG4iCisgICAgICAibWF0Y2hlZDogcmNbMV0gOiAxN1xuIiwKKyAgICAgIG91dHB1dCk7Cit9CisKK1RFU1RfRihNYXRjaGluZ1Rlc3QsIERvbnRSZXBvcnRNYXRjaGVkV2hlbklnbm9yaW5nKSB7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0RmllbGQgbXNnMSwgbXNnMjsKKyAgbXNnMS5zZXRfYyg3Mik7CisgIG1zZzIuc2V0X2MoNzIpOworICBtc2cxLmFkZF9yYygxMyk7CisgIG1zZzIuYWRkX3JjKDEzKTsKKyAgbXNnMS5hZGRfcmMoMTcpOworICBtc2cyLmFkZF9yYygxNyk7CisgIHN0cmluZyBvdXRwdXQ7CisgIE1lc3NhZ2VEaWZmZXJlbmNlciBkaWZmZXJlbmNlcjsKKyAgZGlmZmVyZW5jZXIuc2V0X3JlcG9ydF9tYXRjaGVzKHRydWUpOworICBkaWZmZXJlbmNlci5SZXBvcnREaWZmZXJlbmNlc1RvU3RyaW5nKCZvdXRwdXQpOworCisgIGRpZmZlcmVuY2VyLklnbm9yZUZpZWxkKG1zZzEuR2V0RGVzY3JpcHRvcigpLT5GaW5kRmllbGRCeU5hbWUoImMiKSk7CisKKyAgRVhQRUNUX1RSVUUoZGlmZmVyZW5jZXIuQ29tcGFyZShtc2cxLCBtc2cyKSk7CisgIEVYUEVDVF9FUSgKKyAgICAgICJpZ25vcmVkOiBjXG4iCisgICAgICAibWF0Y2hlZDogcmNbMF0gOiAxM1xuIgorICAgICAgIm1hdGNoZWQ6IHJjWzFdIDogMTdcbiIsCisgICAgICBvdXRwdXQpOworfQorCitURVNUX0YoTWF0Y2hpbmdUZXN0LCBSZXBvcnRNYXRjaGVkRm9yTW92ZWRGaWVsZHMpIHsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3REaWZmTWVzc2FnZSBtc2cxLCBtc2cyOworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdERpZmZNZXNzYWdlOjpJdGVtKiBpdGVtID0gbXNnMS5hZGRfaXRlbSgpOworICBpdGVtLT5zZXRfYSg1Myk7CisgIGl0ZW0tPnNldF9iKCJoZWxsbyIpOworICBpdGVtID0gbXNnMi5hZGRfaXRlbSgpOworICBpdGVtLT5zZXRfYSgyNyk7CisgIGl0ZW0gPSBtc2cyLmFkZF9pdGVtKCk7CisgIGl0ZW0tPnNldF9hKDUzKTsKKyAgaXRlbS0+c2V0X2IoImhlbGxvIik7CisgIGl0ZW0gPSBtc2cxLmFkZF9pdGVtKCk7CisgIGl0ZW0tPnNldF9hKDI3KTsKKyAgTWVzc2FnZURpZmZlcmVuY2VyIGRpZmZlcmVuY2VyOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2M7CisgIGRlc2MgPSBtc2cxLkdldERlc2NyaXB0b3IoKS0+RmluZEZpZWxkQnlOYW1lKCJpdGVtIik7CisgIGRpZmZlcmVuY2VyLlRyZWF0QXNTZXQoZGVzYyk7CisKKyAgRVhQRUNUX0VRKAorICAgICAgIm1hdGNoZWQ6IGl0ZW1bMF0uYSAtPiBpdGVtWzFdLmEgOiA1M1xuIgorICAgICAgIm1hdGNoZWQ6IGl0ZW1bMF0uYiAtPiBpdGVtWzFdLmIgOiBcImhlbGxvXCJcbiIKKyAgICAgICJtb3ZlZDogaXRlbVswXSAtPiBpdGVtWzFdIDogeyBhOiA1MyBiOiBcImhlbGxvXCIgfVxuIgorICAgICAgIm1hdGNoZWQ6IGl0ZW1bMV0uYSAtPiBpdGVtWzBdLmEgOiAyN1xuIgorICAgICAgIm1vdmVkOiBpdGVtWzFdIC0+IGl0ZW1bMF0gOiB7IGE6IDI3IH1cbiIsCisgICAgICBSdW5XaXRoUmVzdWx0KCZkaWZmZXJlbmNlciwgbXNnMSwgbXNnMiwgdHJ1ZSkpOworfQorCitURVNUX0YoTWF0Y2hpbmdUZXN0LCBNYXRjaGVzQXBwZWFySW5Qb3N0VHJhdmVyc2FsT3JkZXJGb3JNb3ZlZEZpZWxkcykgeworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdERpZmZNZXNzYWdlIG1zZzEsIG1zZzI7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0RGlmZk1lc3NhZ2U6Okl0ZW0qIGl0ZW07CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0RmllbGQqIGZpZWxkOworCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZGVzYzsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBuZXN0ZWRfZGVzYzsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkb3VibGVfbmVzdGVkX2Rlc2M7CisgIGRlc2MgPSBtc2cxLkdldERlc2NyaXB0b3IoKS0+RmluZEZpZWxkQnlOYW1lKCJpdGVtIik7CisgIG5lc3RlZF9kZXNjID0gZGVzYy0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgicm0iKTsKKyAgZG91YmxlX25lc3RlZF9kZXNjID0gbmVzdGVkX2Rlc2MtPm1lc3NhZ2VfdHlwZSgpLT5GaW5kRmllbGRCeU5hbWUoInJjIik7CisgIE1lc3NhZ2VEaWZmZXJlbmNlciBkaWZmZXJlbmNlcjsKKyAgZGlmZmVyZW5jZXIuVHJlYXRBc1NldChkZXNjKTsKKyAgZGlmZmVyZW5jZXIuVHJlYXRBc1NldChuZXN0ZWRfZGVzYyk7CisgIGRpZmZlcmVuY2VyLlRyZWF0QXNTZXQoZG91YmxlX25lc3RlZF9kZXNjKTsKKworICBpdGVtID0gbXNnMS5hZGRfaXRlbSgpOworICBmaWVsZCA9IGl0ZW0tPmFkZF9ybSgpOworICBmaWVsZC0+c2V0X2MoMSk7CisgIGZpZWxkLT5hZGRfcmMoMik7CisgIGZpZWxkLT5hZGRfcmMoMyk7CisgIGZpZWxkID0gaXRlbS0+YWRkX3JtKCk7CisgIGZpZWxkLT5zZXRfYyg0KTsKKyAgZmllbGQtPmFkZF9yYyg1KTsKKyAgZmllbGQtPmFkZF9yYyg2KTsKKyAgZmllbGQtPmFkZF9yYyg3KTsKKyAgaXRlbSA9IG1zZzIuYWRkX2l0ZW0oKTsKKyAgZmllbGQgPSBpdGVtLT5hZGRfcm0oKTsKKyAgZmllbGQtPnNldF9jKDQpOworICBmaWVsZC0+YWRkX3JjKDcpOworICBmaWVsZC0+YWRkX3JjKDYpOworICBmaWVsZC0+YWRkX3JjKDUpOworICBmaWVsZCA9IGl0ZW0tPmFkZF9ybSgpOworICBmaWVsZC0+c2V0X2MoMSk7CisgIGZpZWxkLT5hZGRfcmMoMyk7CisgIGZpZWxkLT5hZGRfcmMoMik7CisgIGl0ZW0gPSBtc2cxLmFkZF9pdGVtKCk7CisgIGZpZWxkID0gaXRlbS0+YWRkX3JtKCk7CisgIGZpZWxkLT5zZXRfYyg4KTsKKyAgZmllbGQtPmFkZF9yYygxMCk7CisgIGZpZWxkLT5hZGRfcmMoMTEpOworICBmaWVsZC0+YWRkX3JjKDkpOworICBpdGVtID0gbXNnMi5hZGRfaXRlbSgpOworICBmaWVsZCA9IGl0ZW0tPmFkZF9ybSgpOworICBmaWVsZC0+c2V0X2MoOCk7CisgIGZpZWxkLT5hZGRfcmMoOSk7CisgIGZpZWxkLT5hZGRfcmMoMTApOworICBmaWVsZC0+YWRkX3JjKDExKTsKKworICBFWFBFQ1RfRVEoCisgICAgICAibWF0Y2hlZDogaXRlbVswXS5ybVswXS5jIC0+IGl0ZW1bMF0ucm1bMV0uYyA6IDFcbiIKKyAgICAgICJtb3ZlZDogaXRlbVswXS5ybVswXS5yY1swXSAtPiBpdGVtWzBdLnJtWzFdLnJjWzFdIDogMlxuIgorICAgICAgIm1vdmVkOiBpdGVtWzBdLnJtWzBdLnJjWzFdIC0+IGl0ZW1bMF0ucm1bMV0ucmNbMF0gOiAzXG4iCisgICAgICAibW92ZWQ6IGl0ZW1bMF0ucm1bMF0gLT4gaXRlbVswXS5ybVsxXSA6IHsgYzogMSByYzogMiByYzogMyB9XG4iCisgICAgICAibWF0Y2hlZDogaXRlbVswXS5ybVsxXS5jIC0+IGl0ZW1bMF0ucm1bMF0uYyA6IDRcbiIKKyAgICAgICJtb3ZlZDogaXRlbVswXS5ybVsxXS5yY1swXSAtPiBpdGVtWzBdLnJtWzBdLnJjWzJdIDogNVxuIgorICAgICAgIm1hdGNoZWQ6IGl0ZW1bMF0ucm1bMV0ucmNbMV0gLT4gaXRlbVswXS5ybVswXS5yY1sxXSA6IDZcbiIKKyAgICAgICJtb3ZlZDogaXRlbVswXS5ybVsxXS5yY1syXSAtPiBpdGVtWzBdLnJtWzBdLnJjWzBdIDogN1xuIgorICAgICAgIm1vdmVkOiBpdGVtWzBdLnJtWzFdIC0+IGl0ZW1bMF0ucm1bMF0gOiB7IGM6IDQgcmM6IDUgcmM6IDYgcmM6IDcgfVxuIgorICAgICAgIm1hdGNoZWQ6IGl0ZW1bMF0gOiB7IHJtIHsgYzogMSByYzogMiByYzogMyB9IgorICAgICAgICAgICAgICAgICAgICAgICAgICAiIHJtIHsgYzogNCByYzogNSByYzogNiByYzogNyB9IH1cbiIKKyAgICAgICJtYXRjaGVkOiBpdGVtWzFdLnJtWzBdLmMgOiA4XG4iCisgICAgICAibW92ZWQ6IGl0ZW1bMV0ucm1bMF0ucmNbMF0gLT4gaXRlbVsxXS5ybVswXS5yY1sxXSA6IDEwXG4iCisgICAgICAibW92ZWQ6IGl0ZW1bMV0ucm1bMF0ucmNbMV0gLT4gaXRlbVsxXS5ybVswXS5yY1syXSA6IDExXG4iCisgICAgICAibW92ZWQ6IGl0ZW1bMV0ucm1bMF0ucmNbMl0gLT4gaXRlbVsxXS5ybVswXS5yY1swXSA6IDlcbiIKKyAgICAgICJtYXRjaGVkOiBpdGVtWzFdLnJtWzBdIDogeyBjOiA4IHJjOiAxMCByYzogMTEgcmM6IDkgfVxuIgorICAgICAgIm1hdGNoZWQ6IGl0ZW1bMV0gOiB7IHJtIHsgYzogOCByYzogMTAgcmM6IDExIHJjOiA5IH0gfVxuIiwKKyAgICAgIFJ1bldpdGhSZXN1bHQoJmRpZmZlcmVuY2VyLCBtc2cxLCBtc2cyLCB0cnVlKSk7Cit9CisKK1RFU1RfRihNYXRjaGluZ1Rlc3QsIE1hdGNoQW5kTW9kaWZpZWRJbnRlcmxlYXZlUHJvcGVybHkpIHsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3REaWZmTWVzc2FnZSBtc2cxLCBtc2cyOworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdERpZmZNZXNzYWdlOjpJdGVtKiBpdGVtOworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEZpZWxkKiBmaWVsZDsKKworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2M7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogbmVzdGVkX2tleTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBuZXN0ZWRfZGVzYzsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkb3VibGVfbmVzdGVkX2tleTsKKyAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBkb3VibGVfbmVzdGVkX2Rlc2M7CisgIGRlc2MgPSBtc2cxLkdldERlc2NyaXB0b3IoKS0+RmluZEZpZWxkQnlOYW1lKCJpdGVtIik7CisgIG5lc3RlZF9rZXkgPSBkZXNjLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJhIik7CisgIG5lc3RlZF9kZXNjID0gZGVzYy0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgicm0iKTsKKyAgZG91YmxlX25lc3RlZF9rZXkgPSBuZXN0ZWRfZGVzYy0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgiYyIpOworICBkb3VibGVfbmVzdGVkX2Rlc2MgPSBuZXN0ZWRfZGVzYy0+bWVzc2FnZV90eXBlKCktPkZpbmRGaWVsZEJ5TmFtZSgicmMiKTsKKworICBNZXNzYWdlRGlmZmVyZW5jZXIgZGlmZmVyZW5jZXI7CisgIGRpZmZlcmVuY2VyLlRyZWF0QXNNYXAoZGVzYywgbmVzdGVkX2tleSk7CisgIGRpZmZlcmVuY2VyLlRyZWF0QXNNYXAobmVzdGVkX2Rlc2MsIGRvdWJsZV9uZXN0ZWRfa2V5KTsKKyAgZGlmZmVyZW5jZXIuVHJlYXRBc1NldChkb3VibGVfbmVzdGVkX2Rlc2MpOworCisgIGl0ZW0gPSBtc2cxLmFkZF9pdGVtKCk7CisgIGl0ZW0tPnNldF9hKDEpOworICBmaWVsZCA9IGl0ZW0tPmFkZF9ybSgpOworICBmaWVsZC0+c2V0X2MoMik7CisgIGZpZWxkLT5hZGRfcmMoMyk7CisgIGZpZWxkLT5hZGRfcmMoNCk7CisgIGZpZWxkID0gaXRlbS0+YWRkX3JtKCk7CisgIGZpZWxkLT5zZXRfYyg1KTsKKyAgZmllbGQtPmFkZF9yYyg2KTsKKyAgZmllbGQtPmFkZF9yYyg3KTsKKyAgZmllbGQtPmFkZF9yYyg4KTsKKyAgaXRlbSA9IG1zZzEuYWRkX2l0ZW0oKTsKKyAgaXRlbS0+c2V0X2EoOSk7CisgIGZpZWxkID0gaXRlbS0+YWRkX3JtKCk7CisgIGZpZWxkLT5zZXRfYygxMCk7CisgIGZpZWxkLT5hZGRfcmMoMTEpOworICBmaWVsZC0+YWRkX3JjKDEyKTsKKyAgZmllbGQgPSBpdGVtLT5hZGRfcm0oKTsKKyAgZmllbGQtPnNldF9jKDEzKTsKKworICBpdGVtID0gbXNnMi5hZGRfaXRlbSgpOworICBpdGVtLT5zZXRfYSgxKTsKKyAgZmllbGQgPSBpdGVtLT5hZGRfcm0oKTsKKyAgZmllbGQtPnNldF9jKDUpOworICBmaWVsZC0+YWRkX3JjKDgpOworICBmaWVsZC0+YWRkX3JjKDgpOworICBmaWVsZC0+YWRkX3JjKDYpOworICBmaWVsZCA9IGl0ZW0tPmFkZF9ybSgpOworICBmaWVsZC0+c2V0X2MoMyk7CisgIGZpZWxkLT5hZGRfcmMoMik7CisgIGZpZWxkLT5hZGRfcmMoNCk7CisgIGl0ZW0gPSBtc2cyLmFkZF9pdGVtKCk7CisgIGl0ZW0tPnNldF9hKDkpOworICBmaWVsZCA9IGl0ZW0tPmFkZF9ybSgpOworICBmaWVsZC0+c2V0X2MoMTApOworICBmaWVsZC0+YWRkX3JjKDEyKTsKKyAgZmllbGQtPmFkZF9yYygxMSk7CisgIGZpZWxkID0gaXRlbS0+YWRkX3JtKCk7CisgIGZpZWxkLT5zZXRfYygxMyk7CisKKyAgRVhQRUNUX0VRKAorICAgICAgIm1hdGNoZWQ6IGl0ZW1bMF0uYSA6IDFcbiIKKyAgICAgICJtYXRjaGVkOiBpdGVtWzBdLnJtWzFdLmMgLT4gaXRlbVswXS5ybVswXS5jIDogNVxuIgorICAgICAgIm1vdmVkOiBpdGVtWzBdLnJtWzFdLnJjWzBdIC0+IGl0ZW1bMF0ucm1bMF0ucmNbMl0gOiA2XG4iCisgICAgICAibW92ZWQ6IGl0ZW1bMF0ucm1bMV0ucmNbMl0gLT4gaXRlbVswXS5ybVswXS5yY1swXSA6IDhcbiIKKyAgICAgICJhZGRlZDogaXRlbVswXS5ybVswXS5yY1sxXTogOFxuIgorICAgICAgImRlbGV0ZWQ6IGl0ZW1bMF0ucm1bMV0ucmNbMV06IDdcbiIKKyAgICAgICJtb2RpZmllZDogaXRlbVswXS5ybVsxXSAtPiBpdGVtWzBdLnJtWzBdOiB7IGM6IDUgcmM6IDYgcmM6IDcgcmM6IDggfSAtPiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiB7IGM6IDUgcmM6IDggcmM6IDggcmM6IDYgfVxuIgorICAgICAgImFkZGVkOiBpdGVtWzBdLnJtWzFdOiB7IGM6IDMgcmM6IDIgcmM6IDQgfVxuIgorICAgICAgImRlbGV0ZWQ6IGl0ZW1bMF0ucm1bMF06IHsgYzogMiByYzogMyByYzogNCB9XG4iCisgICAgICAibW9kaWZpZWQ6IGl0ZW1bMF06IHsgYTogMSBybSB7IGM6IDIgcmM6IDMgcmM6IDQgfSIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIHJtIHsgYzogNSByYzogNiByYzogNyByYzogOCB9IH0gLT4iCisgICAgICAgICAgICAgICAgICAgICAgICAiIHsgYTogMSBybSB7IGM6IDUgcmM6IDggcmM6IDggcmM6IDYgfSIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIHJtIHsgYzogMyByYzogMiByYzogNCB9IH1cbiIKKyAgICAgICJtYXRjaGVkOiBpdGVtWzFdLmEgOiA5XG4iCisgICAgICAibWF0Y2hlZDogaXRlbVsxXS5ybVswXS5jIDogMTBcbiIKKyAgICAgICJtb3ZlZDogaXRlbVsxXS5ybVswXS5yY1swXSAtPiBpdGVtWzFdLnJtWzBdLnJjWzFdIDogMTFcbiIKKyAgICAgICJtb3ZlZDogaXRlbVsxXS5ybVswXS5yY1sxXSAtPiBpdGVtWzFdLnJtWzBdLnJjWzBdIDogMTJcbiIKKyAgICAgICJtYXRjaGVkOiBpdGVtWzFdLnJtWzBdIDogeyBjOiAxMCByYzogMTEgcmM6IDEyIH1cbiIKKyAgICAgICJtYXRjaGVkOiBpdGVtWzFdLnJtWzFdLmMgOiAxM1xuIgorICAgICAgIm1hdGNoZWQ6IGl0ZW1bMV0ucm1bMV0gOiB7IGM6IDEzIH1cbiIKKyAgICAgICJtYXRjaGVkOiBpdGVtWzFdIDogeyBhOiA5IHJtIHsgYzogMTAgcmM6IDExIHJjOiAxMiB9IHJtIHsgYzogMTMgfSB9XG4iLAorICAgICAgUnVuV2l0aFJlc3VsdCgmZGlmZmVyZW5jZXIsIG1zZzEsIG1zZzIsIGZhbHNlKSk7Cit9CisKK1RFU1RfRihNYXRjaGluZ1Rlc3QsIE1hdGNoaW5nV29ya3NXaXRoRXh0ZW5zaW9ucykgeworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgbXNnMSwgbXNnMjsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6TmVzdGVkTWVzc2FnZSogbmVzdGVkOworICB1c2luZyBwcm90b2J1Zl91bml0dGVzdDo6cmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uOworCisgIGNvbnN0IEZpbGVEZXNjcmlwdG9yKiBkZXNjcmlwdG9yOworICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2M7CisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogbmVzdGVkX2tleTsKKyAgZGVzY3JpcHRvciA9IG1zZzEuR2V0RGVzY3JpcHRvcigpLT5maWxlKCk7CisgIGRlc2MgPSBkZXNjcmlwdG9yLT5GaW5kRXh0ZW5zaW9uQnlOYW1lKCJyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb24iKTsKKyAgQVNTRVJUX0ZBTFNFKGRlc2MgPT0gTlVMTCk7CisgIG5lc3RlZF9rZXkgPSBkZXNjLT5tZXNzYWdlX3R5cGUoKS0+RmluZEZpZWxkQnlOYW1lKCJiYiIpOworCisgIE1lc3NhZ2VEaWZmZXJlbmNlciBkaWZmZXJlbmNlcjsKKyAgZGlmZmVyZW5jZXIuVHJlYXRBc01hcChkZXNjLCBuZXN0ZWRfa2V5KTsKKworICBuZXN0ZWQgPSBtc2cxLkFkZEV4dGVuc2lvbihyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb24pOworICBuZXN0ZWQtPnNldF9iYig3KTsKKyAgbmVzdGVkID0gbXNnMS5BZGRFeHRlbnNpb24ocmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uKTsKKyAgbmVzdGVkLT5zZXRfYmIoMTMpOworICBuZXN0ZWQgPSBtc2cxLkFkZEV4dGVuc2lvbihyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb24pOworICBuZXN0ZWQtPnNldF9iYigxMSk7CisgIG5lc3RlZCA9IG1zZzIuQWRkRXh0ZW5zaW9uKHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbik7CisgIG5lc3RlZC0+c2V0X2JiKDExKTsKKyAgbmVzdGVkID0gbXNnMi5BZGRFeHRlbnNpb24ocmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uKTsKKyAgbmVzdGVkLT5zZXRfYmIoMTMpOworICBuZXN0ZWQgPSBtc2cyLkFkZEV4dGVuc2lvbihyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb24pOworICBuZXN0ZWQtPnNldF9iYig3KTsKKworICBFWFBFQ1RfRVEoCisgICAgICAibWF0Y2hlZDogKHByb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbilbMF0uYmIgLT4iCisgICAgICAgICAgICAgICIgKHByb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbilbMl0uYmIgOiA3XG4iCisgICAgICAibW92ZWQ6IChwcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb24pWzBdIC0+IgorICAgICAgICAgICAgIiAocHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uKVsyXSA6IgorICAgICAgICAgICAgICAgICIgeyBiYjogNyB9XG4iCisgICAgICAibWF0Y2hlZDogKHByb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbilbMV0uYmIgOiIKKyAgICAgICAgICAgICAgICAgICIgMTNcbiIKKyAgICAgICJtYXRjaGVkOiAocHJvdG9idWZfdW5pdHRlc3QucmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uKVsxXSA6IgorICAgICAgICAgICAgICAgICAgIiB7IGJiOiAxMyB9XG4iCisgICAgICAibWF0Y2hlZDogKHByb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbilbMl0uYmIgLT4iCisgICAgICAgICAgICAgICIgKHByb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbilbMF0uYmIgOiIKKyAgICAgICAgICAgICAgICAgICIgMTFcbiIKKyAgICAgICJtb3ZlZDogKHByb3RvYnVmX3VuaXR0ZXN0LnJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvbilbMl0gLT4iCisgICAgICAgICAgICAiIChwcm90b2J1Zl91bml0dGVzdC5yZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb24pWzBdIDoiCisgICAgICAgICAgICAgICAgIiB7IGJiOiAxMSB9XG4iLAorICAgICAgUnVuV2l0aFJlc3VsdCgmZGlmZmVyZW5jZXIsIG1zZzEsIG1zZzIsIHRydWUpKTsKK30KKworVEVTVChBbnlUZXN0LCBTaW1wbGUpIHsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RGaWVsZCB2YWx1ZTEsIHZhbHVlMjsKKyAgdmFsdWUxLnNldF9hKDIwKTsKKyAgdmFsdWUyLnNldF9hKDIxKTsKKworICBwcm90b2J1Zl91bml0dGVzdDo6VGVzdEFueSBtMSwgbTI7CisgIG0xLm11dGFibGVfYW55X3ZhbHVlKCktPlBhY2tGcm9tKHZhbHVlMSk7CisgIG0yLm11dGFibGVfYW55X3ZhbHVlKCktPlBhY2tGcm9tKHZhbHVlMik7CisgIHV0aWw6Ok1lc3NhZ2VEaWZmZXJlbmNlciBtZXNzYWdlX2RpZmZlcmVuY2VyOworICBzdHJpbmcgZGlmZmVyZW5jZV9zdHJpbmc7CisgIG1lc3NhZ2VfZGlmZmVyZW5jZXIuUmVwb3J0RGlmZmVyZW5jZXNUb1N0cmluZygmZGlmZmVyZW5jZV9zdHJpbmcpOworICBFWFBFQ1RfRkFMU0UobWVzc2FnZV9kaWZmZXJlbmNlci5Db21wYXJlKG0xLCBtMikpOworICBFWFBFQ1RfRVEoIm1vZGlmaWVkOiBhbnlfdmFsdWUuYTogMjAgLT4gMjFcbiIsIGRpZmZlcmVuY2Vfc3RyaW5nKTsKK30KKworVEVTVChBbnl0ZXN0LCBUcmVhdEFzU2V0KSB7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0RmllbGQgdmFsdWUxLCB2YWx1ZTI7CisgIHZhbHVlMS5zZXRfYSgyMCk7CisgIHZhbHVlMS5zZXRfYigzMCk7CisgIHZhbHVlMi5zZXRfYSgyMCk7CisgIHZhbHVlMi5zZXRfYigzMSk7CisKKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RBbnkgbTEsIG0yOworICBtMS5hZGRfcmVwZWF0ZWRfYW55X3ZhbHVlKCktPlBhY2tGcm9tKHZhbHVlMSk7CisgIG0xLmFkZF9yZXBlYXRlZF9hbnlfdmFsdWUoKS0+UGFja0Zyb20odmFsdWUyKTsKKyAgbTIuYWRkX3JlcGVhdGVkX2FueV92YWx1ZSgpLT5QYWNrRnJvbSh2YWx1ZTIpOworICBtMi5hZGRfcmVwZWF0ZWRfYW55X3ZhbHVlKCktPlBhY2tGcm9tKHZhbHVlMSk7CisKKyAgdXRpbDo6TWVzc2FnZURpZmZlcmVuY2VyIG1lc3NhZ2VfZGlmZmVyZW5jZXI7CisgIG1lc3NhZ2VfZGlmZmVyZW5jZXIuVHJlYXRBc1NldChHZXRGaWVsZERlc2NyaXB0b3IobTEsICJyZXBlYXRlZF9hbnlfdmFsdWUiKSk7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2VfZGlmZmVyZW5jZXIuQ29tcGFyZShtMSwgbTIpKTsKK30KKworCit9ICAvLyBuYW1lc3BhY2UKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL21lc3NhZ2VfZGlmZmVyZW5jZXJfdW5pdHRlc3QucHJvdG8gYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvbWVzc2FnZV9kaWZmZXJlbmNlcl91bml0dGVzdC5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42OTg3NzVmCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL21lc3NhZ2VfZGlmZmVyZW5jZXJfdW5pdHRlc3QucHJvdG8KQEAgLTAsMCArMSw3NCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorLy8KKy8vIFRoaXMgZmlsZSBjb250YWlucyBtZXNzYWdlcyBmb3IgdGVzdGluZyByZXBlYXRlZCBmaWVsZCBjb21wYXJpc29uCisKK3N5bnRheCA9ICJwcm90bzIiOworcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdDsKKworb3B0aW9uIG9wdGltaXplX2ZvciA9IFNQRUVEOworCittZXNzYWdlIFRlc3RGaWVsZCB7CisgIG9wdGlvbmFsIGludDMyIGEgPSAzOworICBvcHRpb25hbCBpbnQzMiBiID0gNDsKKyAgb3B0aW9uYWwgaW50MzIgYyA9IDE7CisgIHJlcGVhdGVkIGludDMyIHJjID0gMjsKKyAgb3B0aW9uYWwgVGVzdEZpZWxkIG0gPSA1OworCisgIGV4dGVuZCBUZXN0RGlmZk1lc3NhZ2UgeworICAgIG9wdGlvbmFsIFRlc3RGaWVsZCB0ZiA9IDEwMDsKKyAgfQorfQorCittZXNzYWdlIFRlc3REaWZmTWVzc2FnZSB7CisgIHJlcGVhdGVkIGdyb3VwIEl0ZW0gPSAxIHsKKyAgICBvcHRpb25hbCBpbnQzMiAgYSAgPSAgMjsgICAgIC8vIFRlc3QgYmFzaWMgcmVwZWF0ZWQgZmllbGQgY29tcGFyaXNvbi4KKyAgICBvcHRpb25hbCBzdHJpbmcgYiAgPSAgNDsgICAgIC8vIFRlc3QgYmFzaWMgcmVwZWF0ZWQgZmllbGQgY29tcGFyaXNvbi4KKyAgICByZXBlYXRlZCBpbnQzMiAgcmEgPSAgMzsgICAgIC8vIFRlc3QgU2V0T2ZTZXQgQ29tcGFyaXNvbi4KKyAgICByZXBlYXRlZCBzdHJpbmcgcmIgPSAgNTsgICAgIC8vIFRlc3QgVHJlYXRBc01hcCB3aGVuIGtleSBpcyByZXBlYXRlZAorICAgIG9wdGlvbmFsIFRlc3RGaWVsZCBtICA9IDY7ICAgLy8gVGVzdCBUcmVhdEFzTWFwIHdoZW4ga2V5IGlzIGEgbWVzc2FnZQorICAgIHJlcGVhdGVkIFRlc3RGaWVsZCBybSA9IDc7ICAgLy8gVGVzdCBUcmVhdEFzTWFwIHdoZW4ga2V5IGlzIGEgcmVwZWF0ZWQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1lc3NhZ2UKKyAgfQorCisgIG9wdGlvbmFsIGludDMyICB2ICA9IDEzIFtkZXByZWNhdGVkID0gdHJ1ZV07CisgIG9wdGlvbmFsIHN0cmluZyB3ICA9IDE0OworICBvcHRpb25hbCBUZXN0RmllbGQgbSAgPSAxNTsKKyAgcmVwZWF0ZWQgaW50MzIgIHJ2ID0gMTE7ICAgICAgIC8vIFRlc3QgZm9yIGNvbWJpbmF0aW9ucworICByZXBlYXRlZCBzdHJpbmcgcncgPSAxMDsgICAgICAgLy8gVGVzdCBmb3IgY29tYmluYXRpb25zCisgIHJlcGVhdGVkIFRlc3RGaWVsZCBybSA9IDEyIFtkZXByZWNhdGVkID0gdHJ1ZV07ICAgIC8vIFRlc3QgZm9yIGNvbWJpbmF0aW9ucworCisgIGV4dGVuc2lvbnMgMTAwIHRvIDE5OTsKK30KKwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL3RpbWVfdXRpbC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC90aW1lX3V0aWwuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzc4MmQ2OQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC90aW1lX3V0aWwuY2MKQEAgLTAsMCArMSw1MjUgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3V0aWwvdGltZV91dGlsLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvdGltZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9pbnQxMjguaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RydXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJpbmdwcmludGYuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZHVyYXRpb24ucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGltZXN0YW1wLnBiLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSB1dGlsIHsKKwordXNpbmcgZ29vZ2xlOjpwcm90b2J1Zjo6VGltZXN0YW1wOwordXNpbmcgZ29vZ2xlOjpwcm90b2J1Zjo6RHVyYXRpb247CisKK25hbWVzcGFjZSB7CitzdGF0aWMgY29uc3QgaW50IGtOYW5vc1BlclNlY29uZCA9IDEwMDAwMDAwMDA7CitzdGF0aWMgY29uc3QgaW50IGtNaWNyb3NQZXJTZWNvbmQgPSAxMDAwMDAwOworc3RhdGljIGNvbnN0IGludCBrTWlsbGlzUGVyU2Vjb25kID0gMTAwMDsKK3N0YXRpYyBjb25zdCBpbnQga05hbm9zUGVyTWlsbGlzZWNvbmQgPSAxMDAwMDAwOworc3RhdGljIGNvbnN0IGludCBrTWljcm9zUGVyTWlsbGlzZWNvbmQgPSAxMDAwOworc3RhdGljIGNvbnN0IGludCBrTmFub3NQZXJNaWNyb3NlY29uZCA9IDEwMDA7CitzdGF0aWMgY29uc3QgaW50IGtTZWNvbmRzUGVyTWludXRlID0gNjA7ICAvLyBOb3RlIHRoYXQgd2UgaWdub3JlIGxlYXAgc2Vjb25kcy4KK3N0YXRpYyBjb25zdCBpbnQga1NlY29uZHNQZXJIb3VyID0gMzYwMDsKK3N0YXRpYyBjb25zdCBjaGFyIGtUaW1lc3RhbXBGb3JtYXRbXSA9ICIlRTRZLSVtLSVkVCVIOiVNOiVTIjsKKwordGVtcGxhdGUgPHR5cGVuYW1lIFQ+CitUIENyZWF0ZU5vcm1hbGl6ZWQoaW50NjQgc2Vjb25kcywgaW50NjQgbmFub3MpOworCit0ZW1wbGF0ZSA8PgorVGltZXN0YW1wIENyZWF0ZU5vcm1hbGl6ZWQoaW50NjQgc2Vjb25kcywgaW50NjQgbmFub3MpIHsKKyAgLy8gTWFrZSBzdXJlIG5hbm9zIGlzIGluIHRoZSByYW5nZS4KKyAgaWYgKG5hbm9zIDw9IC1rTmFub3NQZXJTZWNvbmQgfHwgbmFub3MgPj0ga05hbm9zUGVyU2Vjb25kKSB7CisgICAgc2Vjb25kcyArPSBuYW5vcyAvIGtOYW5vc1BlclNlY29uZDsKKyAgICBuYW5vcyA9IG5hbm9zICUga05hbm9zUGVyU2Vjb25kOworICB9CisgIC8vIEZvciBUaW1lc3RhbXAgbmFub3Mgc2hvdWxkIGJlIGluIHRoZSByYW5nZSBbMCwgOTk5OTk5OTk5XQorICBpZiAobmFub3MgPCAwKSB7CisgICAgc2Vjb25kcyAtPSAxOworICAgIG5hbm9zICs9IGtOYW5vc1BlclNlY29uZDsKKyAgfQorICBHT09HTEVfRENIRUNLKHNlY29uZHMgPj0gVGltZVV0aWw6OmtUaW1lc3RhbXBNaW5TZWNvbmRzICYmCisgICAgICAgICBzZWNvbmRzIDw9IFRpbWVVdGlsOjprVGltZXN0YW1wTWF4U2Vjb25kcyk7CisgIFRpbWVzdGFtcCByZXN1bHQ7CisgIHJlc3VsdC5zZXRfc2Vjb25kcyhzZWNvbmRzKTsKKyAgcmVzdWx0LnNldF9uYW5vcyhzdGF0aWNfY2FzdDxpbnQzMj4obmFub3MpKTsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKwordGVtcGxhdGUgPD4KK0R1cmF0aW9uIENyZWF0ZU5vcm1hbGl6ZWQoaW50NjQgc2Vjb25kcywgaW50NjQgbmFub3MpIHsKKyAgLy8gTWFrZSBzdXJlIG5hbm9zIGlzIGluIHRoZSByYW5nZS4KKyAgaWYgKG5hbm9zIDw9IC1rTmFub3NQZXJTZWNvbmQgfHwgbmFub3MgPj0ga05hbm9zUGVyU2Vjb25kKSB7CisgICAgc2Vjb25kcyArPSBuYW5vcyAvIGtOYW5vc1BlclNlY29uZDsKKyAgICBuYW5vcyA9IG5hbm9zICUga05hbm9zUGVyU2Vjb25kOworICB9CisgIC8vIG5hbm9zIHNob3VsZCBoYXZlIHRoZSBzYW1lIHNpZ24gYXMgc2Vjb25kcy4KKyAgaWYgKHNlY29uZHMgPCAwICYmIG5hbm9zID4gMCkgeworICAgIHNlY29uZHMgKz0gMTsKKyAgICBuYW5vcyAtPSBrTmFub3NQZXJTZWNvbmQ7CisgIH0gZWxzZSBpZiAoc2Vjb25kcyA+IDAgJiYgbmFub3MgPCAwKSB7CisgICAgc2Vjb25kcyAtPSAxOworICAgIG5hbm9zICs9IGtOYW5vc1BlclNlY29uZDsKKyAgfQorICBHT09HTEVfRENIRUNLKHNlY29uZHMgPj0gVGltZVV0aWw6OmtEdXJhdGlvbk1pblNlY29uZHMgJiYKKyAgICAgICAgIHNlY29uZHMgPD0gVGltZVV0aWw6OmtEdXJhdGlvbk1heFNlY29uZHMpOworICBEdXJhdGlvbiByZXN1bHQ7CisgIHJlc3VsdC5zZXRfc2Vjb25kcyhzZWNvbmRzKTsKKyAgcmVzdWx0LnNldF9uYW5vcyhzdGF0aWNfY2FzdDxpbnQzMj4obmFub3MpKTsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworLy8gRm9ybWF0IG5hbm9zZWNvbmRzIHdpdGggZWl0aGVyIDMsIDYsIG9yIDkgZGlnaXRzIGRlcGVuZGluZyBvbiB0aGUgcmVxdWlyZWQKKy8vIHByZWNpc2lvbiB0byByZXByZXNlbnQgdGhlIGV4YWN0IHZhbHVlLgorc3RyaW5nIEZvcm1hdE5hbm9zKGludDMyIG5hbm9zKSB7CisgIGlmIChuYW5vcyAlIGtOYW5vc1Blck1pbGxpc2Vjb25kID09IDApIHsKKyAgICByZXR1cm4gU3RyaW5nUHJpbnRmKCIlMDNkIiwgbmFub3MgLyBrTmFub3NQZXJNaWxsaXNlY29uZCk7CisgIH0gZWxzZSBpZiAobmFub3MgJSBrTmFub3NQZXJNaWNyb3NlY29uZCA9PSAwKSB7CisgICAgcmV0dXJuIFN0cmluZ1ByaW50ZigiJTA2ZCIsIG5hbm9zIC8ga05hbm9zUGVyTWljcm9zZWNvbmQpOworICB9IGVsc2UgeworICAgIHJldHVybiBTdHJpbmdQcmludGYoIiUwOWQiLCBuYW5vcyk7CisgIH0KK30KKworc3RyaW5nIEZvcm1hdFRpbWUoaW50NjQgc2Vjb25kcywgaW50MzIgbmFub3MpIHsKKyAgcmV0dXJuIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkZvcm1hdFRpbWUoc2Vjb25kcywgbmFub3MpOworfQorCitib29sIFBhcnNlVGltZShjb25zdCBzdHJpbmcmIHZhbHVlLCBpbnQ2NCogc2Vjb25kcywgaW50MzIqIG5hbm9zKSB7CisgIHJldHVybiA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpQYXJzZVRpbWUodmFsdWUsIHNlY29uZHMsIG5hbm9zKTsKK30KKwordm9pZCBDdXJyZW50VGltZShpbnQ2NCogc2Vjb25kcywgaW50MzIqIG5hbm9zKSB7CisgIHJldHVybiA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRDdXJyZW50VGltZShzZWNvbmRzLCBuYW5vcyk7Cit9CisKKy8vIFRydW5jYXRlcyB0aGUgcmVtYWluZGVyIHBhcnQgYWZ0ZXIgZGl2aXNpb24uCitpbnQ2NCBSb3VuZFRvd2FyZFplcm8oaW50NjQgdmFsdWUsIGludDY0IGRpdmlkZXIpIHsKKyAgaW50NjQgcmVzdWx0ID0gdmFsdWUgLyBkaXZpZGVyOworICBpbnQ2NCByZW1haW5kZXIgPSB2YWx1ZSAlIGRpdmlkZXI7CisgIC8vIEJlZm9yZSBDKysxMSwgdGhlIHNpZ24gb2YgdGhlIHJlbWFpbmRlciBpcyBpbXBsZW1lbnRhdGlvbiBkZXBlbmRlbnQgaWYKKyAgLy8gYW55IG9mIHRoZSBvcGVyYW5kcyBpcyBuZWdhdGl2ZS4gSGVyZSB3ZSB0cnkgdG8gZW5mb3JjZSBDKysxMSdzICJyb3VuZGVkCisgIC8vIHRvd2FyZCB6ZXJvIiBzZW1hbnRpY3MuIEZvciBleGFtcGxlLCBmb3IgKC01KSAvIDIgYW4gaW1wbGVtZW50YXRpb24gbWF5CisgIC8vIGdpdmUgLTMgYXMgdGhlIHJlc3VsdCB3aXRoIHRoZSByZW1haW5kZXIgYmVpbmcgMS4gVGhpcyBmdW5jdGlvbiBlbnN1cmVzCisgIC8vIHdlIGFsd2F5cyByZXR1cm4gLTIgKGNsb3NlciB0byB6ZXJvKSByZWdhcmRsZXNzIG9mIHRoZSBpbXBsZW1lbnRhdGlvbi4KKyAgaWYgKHJlc3VsdCA8IDAgJiYgcmVtYWluZGVyID4gMCkgeworICAgIHJldHVybiByZXN1bHQgKyAxOworICB9IGVsc2UgeworICAgIHJldHVybiByZXN1bHQ7CisgIH0KK30KK30gIC8vIG5hbWVzcGFjZQorCitzdHJpbmcgVGltZVV0aWw6OlRvU3RyaW5nKGNvbnN0IFRpbWVzdGFtcCYgdGltZXN0YW1wKSB7CisgIHJldHVybiBGb3JtYXRUaW1lKHRpbWVzdGFtcC5zZWNvbmRzKCksIHRpbWVzdGFtcC5uYW5vcygpKTsKK30KKworYm9vbCBUaW1lVXRpbDo6RnJvbVN0cmluZyhjb25zdCBzdHJpbmcmIHZhbHVlLCBUaW1lc3RhbXAqIHRpbWVzdGFtcCkgeworICBpbnQ2NCBzZWNvbmRzOworICBpbnQzMiBuYW5vczsKKyAgaWYgKCFQYXJzZVRpbWUodmFsdWUsICZzZWNvbmRzLCAmbmFub3MpKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgICp0aW1lc3RhbXAgPSBDcmVhdGVOb3JtYWxpemVkPFRpbWVzdGFtcD4oc2Vjb25kcywgbmFub3MpOworICByZXR1cm4gdHJ1ZTsKK30KKworVGltZXN0YW1wIFRpbWVVdGlsOjpHZXRDdXJyZW50VGltZSgpIHsKKyAgaW50NjQgc2Vjb25kczsKKyAgaW50MzIgbmFub3M7CisgIEN1cnJlbnRUaW1lKCZzZWNvbmRzLCAmbmFub3MpOworICByZXR1cm4gQ3JlYXRlTm9ybWFsaXplZDxUaW1lc3RhbXA+KHNlY29uZHMsIG5hbm9zKTsKK30KKworVGltZXN0YW1wIFRpbWVVdGlsOjpHZXRFcG9jaCgpIHsgcmV0dXJuIFRpbWVzdGFtcCgpOyB9CisKK3N0cmluZyBUaW1lVXRpbDo6VG9TdHJpbmcoY29uc3QgRHVyYXRpb24mIGR1cmF0aW9uKSB7CisgIHN0cmluZyByZXN1bHQ7CisgIGludDY0IHNlY29uZHMgPSBkdXJhdGlvbi5zZWNvbmRzKCk7CisgIGludDMyIG5hbm9zID0gZHVyYXRpb24ubmFub3MoKTsKKyAgaWYgKHNlY29uZHMgPCAwIHx8IG5hbm9zIDwgMCkgeworICAgIHJlc3VsdCArPSAiLSI7CisgICAgc2Vjb25kcyA9IC1zZWNvbmRzOworICAgIG5hbm9zID0gLW5hbm9zOworICB9CisgIHJlc3VsdCArPSBTdHJpbmdQcmludGYoIiUiIEdPT0dMRV9MTF9GT1JNQVQgImQiLCBzZWNvbmRzKTsKKyAgaWYgKG5hbm9zICE9IDApIHsKKyAgICByZXN1bHQgKz0gIi4iICsgRm9ybWF0TmFub3MobmFub3MpOworICB9CisgIHJlc3VsdCArPSAicyI7CisgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0YXRpYyBpbnQ2NCBQb3coaW50NjQgeCwgaW50IHkpIHsKKyAgaW50NjQgcmVzdWx0ID0gMTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB5OyArK2kpIHsKKyAgICByZXN1bHQgKj0geDsKKyAgfQorICByZXR1cm4gcmVzdWx0OworfQorCitib29sIFRpbWVVdGlsOjpGcm9tU3RyaW5nKGNvbnN0IHN0cmluZyYgdmFsdWUsIER1cmF0aW9uKiBkdXJhdGlvbikgeworICBpZiAodmFsdWUubGVuZ3RoKCkgPD0gMSB8fCB2YWx1ZVt2YWx1ZS5sZW5ndGgoKSAtIDFdICE9ICdzJykgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICBib29sIG5lZ2F0aXZlID0gKHZhbHVlWzBdID09ICctJyk7CisgIGludCBzaWduX2xlbmd0aCA9IChuZWdhdGl2ZSA/IDEgOiAwKTsKKyAgLy8gUGFyc2UgdGhlIGR1cmF0aW9uIHZhbHVlIGFzIHR3byBpbnRlZ2VycyByYXRoZXIgdGhhbiBhIGZsb2F0IHZhbHVlCisgIC8vIHRvIGF2b2lkIHByZWNpc2lvbiBsb3NzLgorICBzdHJpbmcgc2Vjb25kc19wYXJ0LCBuYW5vc19wYXJ0OworICBzaXplX3QgcG9zID0gdmFsdWUuZmluZF9sYXN0X29mKCIuIik7CisgIGlmIChwb3MgPT0gc3RyaW5nOjpucG9zKSB7CisgICAgc2Vjb25kc19wYXJ0ID0gdmFsdWUuc3Vic3RyKHNpZ25fbGVuZ3RoLCB2YWx1ZS5sZW5ndGgoKSAtIDEgLSBzaWduX2xlbmd0aCk7CisgICAgbmFub3NfcGFydCA9ICIwIjsKKyAgfSBlbHNlIHsKKyAgICBzZWNvbmRzX3BhcnQgPSB2YWx1ZS5zdWJzdHIoc2lnbl9sZW5ndGgsIHBvcyAtIHNpZ25fbGVuZ3RoKTsKKyAgICBuYW5vc19wYXJ0ID0gdmFsdWUuc3Vic3RyKHBvcyArIDEsIHZhbHVlLmxlbmd0aCgpIC0gcG9zIC0gMik7CisgIH0KKyAgY2hhciogZW5kOworICBpbnQ2NCBzZWNvbmRzID0gc3RydG82NChzZWNvbmRzX3BhcnQuY19zdHIoKSwgJmVuZCwgMTApOworICBpZiAoZW5kICE9IHNlY29uZHNfcGFydC5jX3N0cigpICsgc2Vjb25kc19wYXJ0Lmxlbmd0aCgpKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIGludDY0IG5hbm9zID0gc3RydG82NChuYW5vc19wYXJ0LmNfc3RyKCksICZlbmQsIDEwKTsKKyAgaWYgKGVuZCAhPSBuYW5vc19wYXJ0LmNfc3RyKCkgKyBuYW5vc19wYXJ0Lmxlbmd0aCgpKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIG5hbm9zID0gbmFub3MgKiBQb3coMTAsIDkgLSBuYW5vc19wYXJ0Lmxlbmd0aCgpKTsKKyAgaWYgKG5lZ2F0aXZlKSB7CisgICAgLy8gSWYgYSBEdXJhdGlvbiBpcyBuZWdhdGl2ZSwgYm90aCBzZWNvbmRzIGFuZCBuYW5vcyBzaG91bGQgYmUgbmVnYXRpdmUuCisgICAgc2Vjb25kcyA9IC1zZWNvbmRzOworICAgIG5hbm9zID0gLW5hbm9zOworICB9CisgIGR1cmF0aW9uLT5zZXRfc2Vjb25kcyhzZWNvbmRzKTsKKyAgZHVyYXRpb24tPnNldF9uYW5vcyhzdGF0aWNfY2FzdDxpbnQzMj4obmFub3MpKTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK0R1cmF0aW9uIFRpbWVVdGlsOjpOYW5vc2Vjb25kc1RvRHVyYXRpb24oaW50NjQgbmFub3MpIHsKKyAgcmV0dXJuIENyZWF0ZU5vcm1hbGl6ZWQ8RHVyYXRpb24+KG5hbm9zIC8ga05hbm9zUGVyU2Vjb25kLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFub3MgJSBrTmFub3NQZXJTZWNvbmQpOworfQorCitEdXJhdGlvbiBUaW1lVXRpbDo6TWljcm9zZWNvbmRzVG9EdXJhdGlvbihpbnQ2NCBtaWNyb3MpIHsKKyAgcmV0dXJuIENyZWF0ZU5vcm1hbGl6ZWQ8RHVyYXRpb24+KAorICAgICAgbWljcm9zIC8ga01pY3Jvc1BlclNlY29uZCwKKyAgICAgIChtaWNyb3MgJSBrTWljcm9zUGVyU2Vjb25kKSAqIGtOYW5vc1Blck1pY3Jvc2Vjb25kKTsKK30KKworRHVyYXRpb24gVGltZVV0aWw6Ok1pbGxpc2Vjb25kc1RvRHVyYXRpb24oaW50NjQgbWlsbGlzKSB7CisgIHJldHVybiBDcmVhdGVOb3JtYWxpemVkPER1cmF0aW9uPigKKyAgICAgIG1pbGxpcyAvIGtNaWxsaXNQZXJTZWNvbmQsCisgICAgICAobWlsbGlzICUga01pbGxpc1BlclNlY29uZCkgKiBrTmFub3NQZXJNaWxsaXNlY29uZCk7Cit9CisKK0R1cmF0aW9uIFRpbWVVdGlsOjpTZWNvbmRzVG9EdXJhdGlvbihpbnQ2NCBzZWNvbmRzKSB7CisgIHJldHVybiBDcmVhdGVOb3JtYWxpemVkPER1cmF0aW9uPihzZWNvbmRzLCAwKTsKK30KKworRHVyYXRpb24gVGltZVV0aWw6Ok1pbnV0ZXNUb0R1cmF0aW9uKGludDY0IG1pbnV0ZXMpIHsKKyAgcmV0dXJuIENyZWF0ZU5vcm1hbGl6ZWQ8RHVyYXRpb24+KG1pbnV0ZXMgKiBrU2Vjb25kc1Blck1pbnV0ZSwgMCk7Cit9CisKK0R1cmF0aW9uIFRpbWVVdGlsOjpIb3Vyc1RvRHVyYXRpb24oaW50NjQgaG91cnMpIHsKKyAgcmV0dXJuIENyZWF0ZU5vcm1hbGl6ZWQ8RHVyYXRpb24+KGhvdXJzICoga1NlY29uZHNQZXJIb3VyLCAwKTsKK30KKworaW50NjQgVGltZVV0aWw6OkR1cmF0aW9uVG9OYW5vc2Vjb25kcyhjb25zdCBEdXJhdGlvbiYgZHVyYXRpb24pIHsKKyAgcmV0dXJuIGR1cmF0aW9uLnNlY29uZHMoKSAqIGtOYW5vc1BlclNlY29uZCArIGR1cmF0aW9uLm5hbm9zKCk7Cit9CisKK2ludDY0IFRpbWVVdGlsOjpEdXJhdGlvblRvTWljcm9zZWNvbmRzKGNvbnN0IER1cmF0aW9uJiBkdXJhdGlvbikgeworICByZXR1cm4gZHVyYXRpb24uc2Vjb25kcygpICoga01pY3Jvc1BlclNlY29uZCArCisgICAgICAgICBSb3VuZFRvd2FyZFplcm8oZHVyYXRpb24ubmFub3MoKSwga05hbm9zUGVyTWljcm9zZWNvbmQpOworfQorCitpbnQ2NCBUaW1lVXRpbDo6RHVyYXRpb25Ub01pbGxpc2Vjb25kcyhjb25zdCBEdXJhdGlvbiYgZHVyYXRpb24pIHsKKyAgcmV0dXJuIGR1cmF0aW9uLnNlY29uZHMoKSAqIGtNaWxsaXNQZXJTZWNvbmQgKworICAgICAgICAgUm91bmRUb3dhcmRaZXJvKGR1cmF0aW9uLm5hbm9zKCksIGtOYW5vc1Blck1pbGxpc2Vjb25kKTsKK30KKworaW50NjQgVGltZVV0aWw6OkR1cmF0aW9uVG9TZWNvbmRzKGNvbnN0IER1cmF0aW9uJiBkdXJhdGlvbikgeworICByZXR1cm4gZHVyYXRpb24uc2Vjb25kcygpOworfQorCitpbnQ2NCBUaW1lVXRpbDo6RHVyYXRpb25Ub01pbnV0ZXMoY29uc3QgRHVyYXRpb24mIGR1cmF0aW9uKSB7CisgIHJldHVybiBSb3VuZFRvd2FyZFplcm8oZHVyYXRpb24uc2Vjb25kcygpLCBrU2Vjb25kc1Blck1pbnV0ZSk7Cit9CisKK2ludDY0IFRpbWVVdGlsOjpEdXJhdGlvblRvSG91cnMoY29uc3QgRHVyYXRpb24mIGR1cmF0aW9uKSB7CisgIHJldHVybiBSb3VuZFRvd2FyZFplcm8oZHVyYXRpb24uc2Vjb25kcygpLCBrU2Vjb25kc1BlckhvdXIpOworfQorCitUaW1lc3RhbXAgVGltZVV0aWw6Ok5hbm9zZWNvbmRzVG9UaW1lc3RhbXAoaW50NjQgbmFub3MpIHsKKyAgcmV0dXJuIENyZWF0ZU5vcm1hbGl6ZWQ8VGltZXN0YW1wPihuYW5vcyAvIGtOYW5vc1BlclNlY29uZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW5vcyAlIGtOYW5vc1BlclNlY29uZCk7Cit9CisKK1RpbWVzdGFtcCBUaW1lVXRpbDo6TWljcm9zZWNvbmRzVG9UaW1lc3RhbXAoaW50NjQgbWljcm9zKSB7CisgIHJldHVybiBDcmVhdGVOb3JtYWxpemVkPFRpbWVzdGFtcD4oCisgICAgICBtaWNyb3MgLyBrTWljcm9zUGVyU2Vjb25kLAorICAgICAgbWljcm9zICUga01pY3Jvc1BlclNlY29uZCAqIGtOYW5vc1Blck1pY3Jvc2Vjb25kKTsKK30KKworVGltZXN0YW1wIFRpbWVVdGlsOjpNaWxsaXNlY29uZHNUb1RpbWVzdGFtcChpbnQ2NCBtaWxsaXMpIHsKKyAgcmV0dXJuIENyZWF0ZU5vcm1hbGl6ZWQ8VGltZXN0YW1wPigKKyAgICAgIG1pbGxpcyAvIGtNaWxsaXNQZXJTZWNvbmQsCisgICAgICBtaWxsaXMgJSBrTWlsbGlzUGVyU2Vjb25kICoga05hbm9zUGVyTWlsbGlzZWNvbmQpOworfQorCitUaW1lc3RhbXAgVGltZVV0aWw6OlNlY29uZHNUb1RpbWVzdGFtcChpbnQ2NCBzZWNvbmRzKSB7CisgIHJldHVybiBDcmVhdGVOb3JtYWxpemVkPFRpbWVzdGFtcD4oc2Vjb25kcywgMCk7Cit9CisKK2ludDY0IFRpbWVVdGlsOjpUaW1lc3RhbXBUb05hbm9zZWNvbmRzKGNvbnN0IFRpbWVzdGFtcCYgdGltZXN0YW1wKSB7CisgIHJldHVybiB0aW1lc3RhbXAuc2Vjb25kcygpICoga05hbm9zUGVyU2Vjb25kICsgdGltZXN0YW1wLm5hbm9zKCk7Cit9CisKK2ludDY0IFRpbWVVdGlsOjpUaW1lc3RhbXBUb01pY3Jvc2Vjb25kcyhjb25zdCBUaW1lc3RhbXAmIHRpbWVzdGFtcCkgeworICByZXR1cm4gdGltZXN0YW1wLnNlY29uZHMoKSAqIGtNaWNyb3NQZXJTZWNvbmQgKworICAgICAgICAgUm91bmRUb3dhcmRaZXJvKHRpbWVzdGFtcC5uYW5vcygpLCBrTmFub3NQZXJNaWNyb3NlY29uZCk7Cit9CisKK2ludDY0IFRpbWVVdGlsOjpUaW1lc3RhbXBUb01pbGxpc2Vjb25kcyhjb25zdCBUaW1lc3RhbXAmIHRpbWVzdGFtcCkgeworICByZXR1cm4gdGltZXN0YW1wLnNlY29uZHMoKSAqIGtNaWxsaXNQZXJTZWNvbmQgKworICAgICAgICAgUm91bmRUb3dhcmRaZXJvKHRpbWVzdGFtcC5uYW5vcygpLCBrTmFub3NQZXJNaWxsaXNlY29uZCk7Cit9CisKK2ludDY0IFRpbWVVdGlsOjpUaW1lc3RhbXBUb1NlY29uZHMoY29uc3QgVGltZXN0YW1wJiB0aW1lc3RhbXApIHsKKyAgcmV0dXJuIHRpbWVzdGFtcC5zZWNvbmRzKCk7Cit9CisKK1RpbWVzdGFtcCBUaW1lVXRpbDo6VGltZVRUb1RpbWVzdGFtcCh0aW1lX3QgdmFsdWUpIHsKKyAgcmV0dXJuIENyZWF0ZU5vcm1hbGl6ZWQ8VGltZXN0YW1wPihzdGF0aWNfY2FzdDxpbnQ2ND4odmFsdWUpLCAwKTsKK30KKwordGltZV90IFRpbWVVdGlsOjpUaW1lc3RhbXBUb1RpbWVUKGNvbnN0IFRpbWVzdGFtcCYgdmFsdWUpIHsKKyAgcmV0dXJuIHN0YXRpY19jYXN0PHRpbWVfdD4odmFsdWUuc2Vjb25kcygpKTsKK30KKworVGltZXN0YW1wIFRpbWVVdGlsOjpUaW1ldmFsVG9UaW1lc3RhbXAoY29uc3QgdGltZXZhbCYgdmFsdWUpIHsKKyAgcmV0dXJuIENyZWF0ZU5vcm1hbGl6ZWQ8VGltZXN0YW1wPih2YWx1ZS50dl9zZWMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUudHZfdXNlYyAqIGtOYW5vc1Blck1pY3Jvc2Vjb25kKTsKK30KKwordGltZXZhbCBUaW1lVXRpbDo6VGltZXN0YW1wVG9UaW1ldmFsKGNvbnN0IFRpbWVzdGFtcCYgdmFsdWUpIHsKKyAgdGltZXZhbCByZXN1bHQ7CisgIHJlc3VsdC50dl9zZWMgPSB2YWx1ZS5zZWNvbmRzKCk7CisgIHJlc3VsdC50dl91c2VjID0gUm91bmRUb3dhcmRaZXJvKHZhbHVlLm5hbm9zKCksIGtOYW5vc1Blck1pY3Jvc2Vjb25kKTsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworRHVyYXRpb24gVGltZVV0aWw6OlRpbWV2YWxUb0R1cmF0aW9uKGNvbnN0IHRpbWV2YWwmIHZhbHVlKSB7CisgIHJldHVybiBDcmVhdGVOb3JtYWxpemVkPER1cmF0aW9uPih2YWx1ZS50dl9zZWMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZS50dl91c2VjICoga05hbm9zUGVyTWljcm9zZWNvbmQpOworfQorCit0aW1ldmFsIFRpbWVVdGlsOjpEdXJhdGlvblRvVGltZXZhbChjb25zdCBEdXJhdGlvbiYgdmFsdWUpIHsKKyAgdGltZXZhbCByZXN1bHQ7CisgIHJlc3VsdC50dl9zZWMgPSB2YWx1ZS5zZWNvbmRzKCk7CisgIHJlc3VsdC50dl91c2VjID0gUm91bmRUb3dhcmRaZXJvKHZhbHVlLm5hbm9zKCksIGtOYW5vc1Blck1pY3Jvc2Vjb25kKTsKKyAgLy8gdGltZXZhbC50dl91c2VjJ3MgcmFuZ2UgaXMgWzAsIDEwMDAwMDApCisgIGlmIChyZXN1bHQudHZfdXNlYyA8IDApIHsKKyAgICByZXN1bHQudHZfc2VjIC09IDE7CisgICAgcmVzdWx0LnR2X3VzZWMgKz0ga01pY3Jvc1BlclNlY29uZDsKKyAgfQorICByZXR1cm4gcmVzdWx0OworfQorCit9ICAvLyBuYW1lc3BhY2UgdXRpbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKKworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSB7Cit1c2luZyBnb29nbGU6OnByb3RvYnVmOjp1dGlsOjprTmFub3NQZXJTZWNvbmQ7Cit1c2luZyBnb29nbGU6OnByb3RvYnVmOjp1dGlsOjpDcmVhdGVOb3JtYWxpemVkOworCisvLyBDb252ZXJ0IGEgVGltZXN0YW1wIHRvIHVpbnQxMjguCit2b2lkIFRvVWludDEyOChjb25zdCBUaW1lc3RhbXAmIHZhbHVlLCB1aW50MTI4KiByZXN1bHQsIGJvb2wqIG5lZ2F0aXZlKSB7CisgIGlmICh2YWx1ZS5zZWNvbmRzKCkgPCAwKSB7CisgICAgKm5lZ2F0aXZlID0gdHJ1ZTsKKyAgICAqcmVzdWx0ID0gc3RhdGljX2Nhc3Q8dWludDY0PigtdmFsdWUuc2Vjb25kcygpKTsKKyAgICAqcmVzdWx0ID0gKnJlc3VsdCAqIGtOYW5vc1BlclNlY29uZCAtIHN0YXRpY19jYXN0PHVpbnQzMj4odmFsdWUubmFub3MoKSk7CisgIH0gZWxzZSB7CisgICAgKm5lZ2F0aXZlID0gZmFsc2U7CisgICAgKnJlc3VsdCA9IHN0YXRpY19jYXN0PHVpbnQ2ND4odmFsdWUuc2Vjb25kcygpKTsKKyAgICAqcmVzdWx0ID0gKnJlc3VsdCAqIGtOYW5vc1BlclNlY29uZCArIHN0YXRpY19jYXN0PHVpbnQzMj4odmFsdWUubmFub3MoKSk7CisgIH0KK30KKworLy8gQ29udmVydCBhIER1cmF0aW9uIHRvIHVpbnQxMjguCit2b2lkIFRvVWludDEyOChjb25zdCBEdXJhdGlvbiYgdmFsdWUsIHVpbnQxMjgqIHJlc3VsdCwgYm9vbCogbmVnYXRpdmUpIHsKKyAgaWYgKHZhbHVlLnNlY29uZHMoKSA8IDAgfHwgdmFsdWUubmFub3MoKSA8IDApIHsKKyAgICAqbmVnYXRpdmUgPSB0cnVlOworICAgICpyZXN1bHQgPSBzdGF0aWNfY2FzdDx1aW50NjQ+KC12YWx1ZS5zZWNvbmRzKCkpOworICAgICpyZXN1bHQgPSAqcmVzdWx0ICoga05hbm9zUGVyU2Vjb25kICsgc3RhdGljX2Nhc3Q8dWludDMyPigtdmFsdWUubmFub3MoKSk7CisgIH0gZWxzZSB7CisgICAgKm5lZ2F0aXZlID0gZmFsc2U7CisgICAgKnJlc3VsdCA9IHN0YXRpY19jYXN0PHVpbnQ2ND4odmFsdWUuc2Vjb25kcygpKTsKKyAgICAqcmVzdWx0ID0gKnJlc3VsdCAqIGtOYW5vc1BlclNlY29uZCArIHN0YXRpY19jYXN0PHVpbnQzMj4odmFsdWUubmFub3MoKSk7CisgIH0KK30KKwordm9pZCBUb1RpbWVzdGFtcChjb25zdCB1aW50MTI4JiB2YWx1ZSwgYm9vbCBuZWdhdGl2ZSwgVGltZXN0YW1wKiB0aW1lc3RhbXApIHsKKyAgaW50NjQgc2Vjb25kcyA9IHN0YXRpY19jYXN0PGludDY0PihVaW50MTI4TG93NjQodmFsdWUgLyBrTmFub3NQZXJTZWNvbmQpKTsKKyAgaW50MzIgbmFub3MgPSBzdGF0aWNfY2FzdDxpbnQzMj4oVWludDEyOExvdzY0KHZhbHVlICUga05hbm9zUGVyU2Vjb25kKSk7CisgIGlmIChuZWdhdGl2ZSkgeworICAgIHNlY29uZHMgPSAtc2Vjb25kczsKKyAgICBuYW5vcyA9IC1uYW5vczsKKyAgICBpZiAobmFub3MgPCAwKSB7CisgICAgICBuYW5vcyArPSBrTmFub3NQZXJTZWNvbmQ7CisgICAgICBzZWNvbmRzIC09IDE7CisgICAgfQorICB9CisgIHRpbWVzdGFtcC0+c2V0X3NlY29uZHMoc2Vjb25kcyk7CisgIHRpbWVzdGFtcC0+c2V0X25hbm9zKG5hbm9zKTsKK30KKwordm9pZCBUb0R1cmF0aW9uKGNvbnN0IHVpbnQxMjgmIHZhbHVlLCBib29sIG5lZ2F0aXZlLCBEdXJhdGlvbiogZHVyYXRpb24pIHsKKyAgaW50NjQgc2Vjb25kcyA9IHN0YXRpY19jYXN0PGludDY0PihVaW50MTI4TG93NjQodmFsdWUgLyBrTmFub3NQZXJTZWNvbmQpKTsKKyAgaW50MzIgbmFub3MgPSBzdGF0aWNfY2FzdDxpbnQzMj4oVWludDEyOExvdzY0KHZhbHVlICUga05hbm9zUGVyU2Vjb25kKSk7CisgIGlmIChuZWdhdGl2ZSkgeworICAgIHNlY29uZHMgPSAtc2Vjb25kczsKKyAgICBuYW5vcyA9IC1uYW5vczsKKyAgfQorICBkdXJhdGlvbi0+c2V0X3NlY29uZHMoc2Vjb25kcyk7CisgIGR1cmF0aW9uLT5zZXRfbmFub3MobmFub3MpOworfQorfSAgLy8gbmFtZXNwYWNlCisKK0R1cmF0aW9uJiBvcGVyYXRvcis9KER1cmF0aW9uJiBkMSwgY29uc3QgRHVyYXRpb24mIGQyKSB7CisgIGQxID0gQ3JlYXRlTm9ybWFsaXplZDxEdXJhdGlvbj4oZDEuc2Vjb25kcygpICsgZDIuc2Vjb25kcygpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQxLm5hbm9zKCkgKyBkMi5uYW5vcygpKTsKKyAgcmV0dXJuIGQxOworfQorCitEdXJhdGlvbiYgb3BlcmF0b3ItPShEdXJhdGlvbiYgZDEsIGNvbnN0IER1cmF0aW9uJiBkMikgeyAgLy8gTk9MSU5UCisgIGQxID0gQ3JlYXRlTm9ybWFsaXplZDxEdXJhdGlvbj4oZDEuc2Vjb25kcygpIC0gZDIuc2Vjb25kcygpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQxLm5hbm9zKCkgLSBkMi5uYW5vcygpKTsKKyAgcmV0dXJuIGQxOworfQorCitEdXJhdGlvbiYgb3BlcmF0b3IqPShEdXJhdGlvbiYgZCwgaW50NjQgcikgeyAgLy8gTk9MSU5UCisgIGJvb2wgbmVnYXRpdmU7CisgIHVpbnQxMjggdmFsdWU7CisgIFRvVWludDEyOChkLCAmdmFsdWUsICZuZWdhdGl2ZSk7CisgIGlmIChyID4gMCkgeworICAgIHZhbHVlICo9IHN0YXRpY19jYXN0PHVpbnQ2ND4ocik7CisgIH0gZWxzZSB7CisgICAgbmVnYXRpdmUgPSAhbmVnYXRpdmU7CisgICAgdmFsdWUgKj0gc3RhdGljX2Nhc3Q8dWludDY0Pigtcik7CisgIH0KKyAgVG9EdXJhdGlvbih2YWx1ZSwgbmVnYXRpdmUsICZkKTsKKyAgcmV0dXJuIGQ7Cit9CisKK0R1cmF0aW9uJiBvcGVyYXRvcio9KER1cmF0aW9uJiBkLCBkb3VibGUgcikgeyAgLy8gTk9MSU5UCisgIGRvdWJsZSByZXN1bHQgPSAoZC5zZWNvbmRzKCkgKiAxLjAgKyAxLjAgKiBkLm5hbm9zKCkgLyBrTmFub3NQZXJTZWNvbmQpICogcjsKKyAgaW50NjQgc2Vjb25kcyA9IHN0YXRpY19jYXN0PGludDY0PihyZXN1bHQpOworICBpbnQzMiBuYW5vcyA9IHN0YXRpY19jYXN0PGludDMyPigocmVzdWx0IC0gc2Vjb25kcykgKiBrTmFub3NQZXJTZWNvbmQpOworICAvLyBOb3RlIHRoYXQgd2Ugbm9ybWFsaXplIGhlcmUgbm90IGp1c3QgYmVjYXVzZSBuYW5vcyBjYW4gaGF2ZSBhIGRpZmZlcmVudAorICAvLyBzaWduIGZyb20gc2Vjb25kcyBidXQgYWxzbyB0aGF0IG5hbm9zIGNhbiBiZSBhbnkgYXJiaXRyYXJ5IHZhbHVlIHdoZW4KKyAgLy8gb3ZlcmZsb3cgaGFwcGVucyAoaS5lLiwgdGhlIHJlc3VsdCBpcyBhIG11Y2ggbGFyZ2VyIHZhbHVlIHRoYW4gd2hhdAorICAvLyBpbnQ2NCBjYW4gcmVwcmVzZW50KS4KKyAgZCA9IENyZWF0ZU5vcm1hbGl6ZWQ8RHVyYXRpb24+KHNlY29uZHMsIG5hbm9zKTsKKyAgcmV0dXJuIGQ7Cit9CisKK0R1cmF0aW9uJiBvcGVyYXRvci89KER1cmF0aW9uJiBkLCBpbnQ2NCByKSB7ICAvLyBOT0xJTlQKKyAgYm9vbCBuZWdhdGl2ZTsKKyAgdWludDEyOCB2YWx1ZTsKKyAgVG9VaW50MTI4KGQsICZ2YWx1ZSwgJm5lZ2F0aXZlKTsKKyAgaWYgKHIgPiAwKSB7CisgICAgdmFsdWUgLz0gc3RhdGljX2Nhc3Q8dWludDY0PihyKTsKKyAgfSBlbHNlIHsKKyAgICBuZWdhdGl2ZSA9ICFuZWdhdGl2ZTsKKyAgICB2YWx1ZSAvPSBzdGF0aWNfY2FzdDx1aW50NjQ+KC1yKTsKKyAgfQorICBUb0R1cmF0aW9uKHZhbHVlLCBuZWdhdGl2ZSwgJmQpOworICByZXR1cm4gZDsKK30KKworRHVyYXRpb24mIG9wZXJhdG9yLz0oRHVyYXRpb24mIGQsIGRvdWJsZSByKSB7ICAvLyBOT0xJTlQKKyAgcmV0dXJuIGQgKj0gMS4wIC8gcjsKK30KKworRHVyYXRpb24mIG9wZXJhdG9yJT0oRHVyYXRpb24mIGQxLCBjb25zdCBEdXJhdGlvbiYgZDIpIHsgIC8vIE5PTElOVAorICBib29sIG5lZ2F0aXZlMSwgbmVnYXRpdmUyOworICB1aW50MTI4IHZhbHVlMSwgdmFsdWUyOworICBUb1VpbnQxMjgoZDEsICZ2YWx1ZTEsICZuZWdhdGl2ZTEpOworICBUb1VpbnQxMjgoZDIsICZ2YWx1ZTIsICZuZWdhdGl2ZTIpOworICB1aW50MTI4IHJlc3VsdCA9IHZhbHVlMSAlIHZhbHVlMjsKKyAgLy8gV2hlbiBuZWdhdGl2ZSB2YWx1ZXMgYXJlIGludm9sdmVkIGluIGRpdmlzaW9uLCB3ZSByb3VuZCB0aGUgZGl2aXNpb24KKyAgLy8gcmVzdWx0IHRvd2FyZHMgemVyby4gV2l0aCB0aGlzIHNlbWFudGljcywgc2lnbiBvZiB0aGUgcmVtYWluZGVyIGlzIHRoZQorICAvLyBzYW1lIGFzIHRoZSBkaXZpZGVuZC4gRm9yIGV4YW1wbGU6CisgIC8vICAgICAtNSAvIDEwICAgID0gMCwgLTUgJSAxMCAgICA9IC01CisgIC8vICAgICAtNSAvICgtMTApID0gMCwgLTUgJSAoLTEwKSA9IC01CisgIC8vICAgICAgNSAvICgtMTApID0gMCwgIDUgJSAoLTEwKSA9IDUKKyAgVG9EdXJhdGlvbihyZXN1bHQsIG5lZ2F0aXZlMSwgJmQxKTsKKyAgcmV0dXJuIGQxOworfQorCitpbnQ2NCBvcGVyYXRvci8oY29uc3QgRHVyYXRpb24mIGQxLCBjb25zdCBEdXJhdGlvbiYgZDIpIHsKKyAgYm9vbCBuZWdhdGl2ZTEsIG5lZ2F0aXZlMjsKKyAgdWludDEyOCB2YWx1ZTEsIHZhbHVlMjsKKyAgVG9VaW50MTI4KGQxLCAmdmFsdWUxLCAmbmVnYXRpdmUxKTsKKyAgVG9VaW50MTI4KGQyLCAmdmFsdWUyLCAmbmVnYXRpdmUyKTsKKyAgaW50NjQgcmVzdWx0ID0gVWludDEyOExvdzY0KHZhbHVlMSAvIHZhbHVlMik7CisgIGlmIChuZWdhdGl2ZTEgIT0gbmVnYXRpdmUyKSB7CisgICAgcmVzdWx0ID0gLXJlc3VsdDsKKyAgfQorICByZXR1cm4gcmVzdWx0OworfQorCitUaW1lc3RhbXAmIG9wZXJhdG9yKz0oVGltZXN0YW1wJiB0LCBjb25zdCBEdXJhdGlvbiYgZCkgeyAgLy8gTk9MSU5UCisgIHQgPSBDcmVhdGVOb3JtYWxpemVkPFRpbWVzdGFtcD4odC5zZWNvbmRzKCkgKyBkLnNlY29uZHMoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0Lm5hbm9zKCkgKyBkLm5hbm9zKCkpOworICByZXR1cm4gdDsKK30KKworVGltZXN0YW1wJiBvcGVyYXRvci09KFRpbWVzdGFtcCYgdCwgY29uc3QgRHVyYXRpb24mIGQpIHsgIC8vIE5PTElOVAorICB0ID0gQ3JlYXRlTm9ybWFsaXplZDxUaW1lc3RhbXA+KHQuc2Vjb25kcygpIC0gZC5zZWNvbmRzKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdC5uYW5vcygpIC0gZC5uYW5vcygpKTsKKyAgcmV0dXJuIHQ7Cit9CisKK0R1cmF0aW9uIG9wZXJhdG9yLShjb25zdCBUaW1lc3RhbXAmIHQxLCBjb25zdCBUaW1lc3RhbXAmIHQyKSB7CisgIHJldHVybiBDcmVhdGVOb3JtYWxpemVkPER1cmF0aW9uPih0MS5zZWNvbmRzKCkgLSB0Mi5zZWNvbmRzKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0MS5uYW5vcygpIC0gdDIubmFub3MoKSk7Cit9Cit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL3RpbWVfdXRpbC5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL3RpbWVfdXRpbC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFiYWMwODkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvdGltZV91dGlsLmgKQEAgLTAsMCArMSwyOTMgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9VVElMX1RJTUVfVVRJTF9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1VUSUxfVElNRV9VVElMX0hfXworCisjaW5jbHVkZSA8Y3RpbWU+CisjaW5jbHVkZSA8b3N0cmVhbT4KKyNpbmNsdWRlIDxzdHJpbmc+CisjaWZkZWYgX01TQ19WRVIKKyNpbmNsdWRlIDx3aW5zb2NrMi5oPgorI2Vsc2UKKyNpbmNsdWRlIDxzeXMvdGltZS5oPgorI2VuZGlmCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZHVyYXRpb24ucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGltZXN0YW1wLnBiLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSB1dGlsIHsKKworY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFRpbWVVdGlsIHsKKyAgdHlwZWRlZiBnb29nbGU6OnByb3RvYnVmOjpUaW1lc3RhbXAgVGltZXN0YW1wOworICB0eXBlZGVmIGdvb2dsZTo6cHJvdG9idWY6OkR1cmF0aW9uIER1cmF0aW9uOworCisgcHVibGljOgorICAvLyBUaGUgbWluL21heCBUaW1lc3RhbXAvRHVyYXRpb24gdmFsdWVzIHdlIHN1cHBvcnQuCisgIC8vCisgIC8vIEZvciAiMDAwMS0wMS0wMVQwMDowMDowMFoiLgorICBzdGF0aWMgY29uc3QgaW50NjQga1RpbWVzdGFtcE1pblNlY29uZHMgPSAtNjIxMzU1OTY4MDBMTDsKKyAgLy8gRm9yICI5OTk5LTEyLTMxVDIzOjU5OjU5Ljk5OTk5OTk5OVoiLgorICBzdGF0aWMgY29uc3QgaW50NjQga1RpbWVzdGFtcE1heFNlY29uZHMgPSAyNTM0MDIzMDA3OTlMTDsKKyAgc3RhdGljIGNvbnN0IGludDY0IGtEdXJhdGlvbk1pblNlY29uZHMgPSAtMzE1NTc2MDAwMDAwTEw7CisgIHN0YXRpYyBjb25zdCBpbnQ2NCBrRHVyYXRpb25NYXhTZWNvbmRzID0gMzE1NTc2MDAwMDAwTEw7CisKKyAgLy8gQ29udmVydHMgVGltZXN0YW1wIHRvL2Zyb20gUkZDIDMzMzkgZGF0ZSBzdHJpbmcgZm9ybWF0LgorICAvLyBHZW5lcmF0ZWQgb3V0cHV0IHdpbGwgYWx3YXlzIGJlIFotbm9ybWFsaXplZCBhbmQgdXNlcyAzLCA2IG9yIDkKKyAgLy8gZnJhY3Rpb25hbCBkaWdpdHMgYXMgcmVxdWlyZWQgdG8gcmVwcmVzZW50IHRoZSBleGFjdCB0aW1lLiBXaGVuCisgIC8vIHBhcnNpbmcsIGFueSBmcmFjdGlvbmFsIGRpZ2l0cyAob3Igbm9uZSkgYW5kIGFueSBvZmZzZXQgYXJlCisgIC8vIGFjY2VwdGVkIGFzIGxvbmcgYXMgdGhleSBmaXQgaW50byBuYW5vLXNlY29uZHMgcHJlY2lzaW9uLgorICAvLyBOb3RlIHRoYXQgVGltZXN0YW1wIGNhbiBvbmx5IHJlcHJlc2VudCB0aW1lIGZyb20KKyAgLy8gMDAwMS0wMS0wMVQwMDowMDowMFogdG8gOTk5OS0xMi0zMVQyMzo1OTo1OS45OTk5OTk5OTlaLiBDb252ZXJ0aW5nCisgIC8vIGEgVGltZXN0YW1wIG91dHNpZGUgb2YgdGhpcyByYW5nZSBpcyB1bmRlZmluZWQgYmVoYXZpb3IuCisgIC8vIFNlZSBodHRwczovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzMzOS50eHQKKyAgLy8KKyAgLy8gRXhhbXBsZSBvZiBnZW5lcmF0ZWQgZm9ybWF0OgorICAvLyAgICIxOTcyLTAxLTAxVDEwOjAwOjIwLjAyMVoiCisgIC8vCisgIC8vIEV4YW1wbGUgb2YgYWNjZXB0ZWQgZm9ybWF0OgorICAvLyAgICIxOTcyLTAxLTAxVDEwOjAwOjIwLjAyMS0wNTowMCIKKyAgc3RhdGljIHN0cmluZyBUb1N0cmluZyhjb25zdCBUaW1lc3RhbXAmIHRpbWVzdGFtcCk7CisgIHN0YXRpYyBib29sIEZyb21TdHJpbmcoY29uc3Qgc3RyaW5nJiB2YWx1ZSwgVGltZXN0YW1wKiB0aW1lc3RhbXApOworCisgIC8vIENvbnZlcnRzIER1cmF0aW9uIHRvL2Zyb20gc3RyaW5nIGZvcm1hdC4gVGhlIHN0cmluZyBmb3JtYXQgd2lsbCBjb250YWlucworICAvLyAzLCA2LCBvciA5IGZyYWN0aW9uYWwgZGlnaXRzIGRlcGVuZGluZyBvbiB0aGUgcHJlY2lzaW9uIHJlcXVpcmVkIHRvCisgIC8vIHJlcHJlc2VudCB0aGUgZXhhY3QgRHVyYXRpb24gdmFsdWUuIEZvciBleGFtcGxlOgorICAvLyAgICIxcyIsICIxLjAxMHMiLCAiMS4wMDAwMDAxMDBzIiwgIi0zLjEwMHMiCisgIC8vIFRoZSByYW5nZSB0aGF0IGNhbiBiZSByZXByZXNlbnRlZCBieSBEdXJhdGlvbiBpcyBmcm9tIC0zMTUsNTc2LDAwMCwwMDAKKyAgLy8gdG8gKzMxNSw1NzYsMDAwLDAwMCBpbmNsdXNpdmUgKGluIHNlY29uZHMpLgorICBzdGF0aWMgc3RyaW5nIFRvU3RyaW5nKGNvbnN0IER1cmF0aW9uJiBkdXJhdGlvbik7CisgIHN0YXRpYyBib29sIEZyb21TdHJpbmcoY29uc3Qgc3RyaW5nJiB2YWx1ZSwgRHVyYXRpb24qIHRpbWVzdGFtcCk7CisKKyNpZmRlZiBHZXRDdXJyZW50VGltZQorI3VuZGVmIEdldEN1cnJlbnRUaW1lICAvLyBWaXN1YWwgU3R1ZGlvIGhhcyBtYWNybyBHZXRDdXJyZW50VGltZQorI2VuZGlmCisgIC8vIEdldHMgdGhlIGN1cnJlbnQgVVRDIHRpbWUuCisgIHN0YXRpYyBUaW1lc3RhbXAgR2V0Q3VycmVudFRpbWUoKTsKKyAgLy8gUmV0dXJucyB0aGUgVGltZSByZXByZXNlbnRpbmcgIjE5NzAtMDEtMDEgMDA6MDA6MDAiLgorICBzdGF0aWMgVGltZXN0YW1wIEdldEVwb2NoKCk7CisKKyAgLy8gQ29udmVydHMgYmV0d2VlbiBEdXJhdGlvbiBhbmQgaW50ZWdlciB0eXBlcy4gVGhlIGJlaGF2aW9yIGlzIHVuZGVmaW5lZCBpZgorICAvLyB0aGUgaW5wdXQgdmFsdWUgaXMgbm90IGluIHRoZSB2YWxpZCByYW5nZSBvZiBEdXJhdGlvbi4KKyAgc3RhdGljIER1cmF0aW9uIE5hbm9zZWNvbmRzVG9EdXJhdGlvbihpbnQ2NCBuYW5vcyk7CisgIHN0YXRpYyBEdXJhdGlvbiBNaWNyb3NlY29uZHNUb0R1cmF0aW9uKGludDY0IG1pY3Jvcyk7CisgIHN0YXRpYyBEdXJhdGlvbiBNaWxsaXNlY29uZHNUb0R1cmF0aW9uKGludDY0IG1pbGxpcyk7CisgIHN0YXRpYyBEdXJhdGlvbiBTZWNvbmRzVG9EdXJhdGlvbihpbnQ2NCBzZWNvbmRzKTsKKyAgc3RhdGljIER1cmF0aW9uIE1pbnV0ZXNUb0R1cmF0aW9uKGludDY0IG1pbnV0ZXMpOworICBzdGF0aWMgRHVyYXRpb24gSG91cnNUb0R1cmF0aW9uKGludDY0IGhvdXJzKTsKKyAgLy8gUmVzdWx0IHdpbGwgYmUgdHJ1bmNhdGVkIHRvd2FyZHMgemVyby4gRm9yIGV4YW1wbGUsICItMS41cyIgd2lsbCBiZQorICAvLyB0cnVuY2F0ZWQgdG8gIi0xcyIsIGFuZCAiMS41cyIgdG8gIjFzIiB3aGVuIGNvbnZlcnRpbmcgdG8gc2Vjb25kcy4KKyAgLy8gSXQncyB1bmRlZmluZWQgYmVoYXZpb3IgaWYgdGhlIGlucHV0IGR1cmF0aW9uIGlzIG5vdCB2YWxpZCBvciB0aGUgcmVzdWx0CisgIC8vIGV4Y2VlZHMgdGhlIHJhbmdlIG9mIGludDY0LiBBIGR1cmF0aW9uIGlzIG5vdCB2YWxpZCBpZiBpdCdzIG5vdCBpbiB0aGUKKyAgLy8gdmFsaWQgcmFuZ2Ugb2YgRHVyYXRpb24sIG9yIGhhdmUgYW4gaW52YWxpZCBuYW5vcyB2YWx1ZSAoaS5lLiwgbGFyZ2VyCisgIC8vIHRoYW4gOTk5OTk5OTk5LCBsZXNzIHRoYW4gLTk5OTk5OTk5OSwgb3IgaGF2ZSBhIGRpZmZlcmVudCBzaWduIGZyb20gdGhlCisgIC8vIHNlY29uZHMgcGFydCkuCisgIHN0YXRpYyBpbnQ2NCBEdXJhdGlvblRvTmFub3NlY29uZHMoY29uc3QgRHVyYXRpb24mIGR1cmF0aW9uKTsKKyAgc3RhdGljIGludDY0IER1cmF0aW9uVG9NaWNyb3NlY29uZHMoY29uc3QgRHVyYXRpb24mIGR1cmF0aW9uKTsKKyAgc3RhdGljIGludDY0IER1cmF0aW9uVG9NaWxsaXNlY29uZHMoY29uc3QgRHVyYXRpb24mIGR1cmF0aW9uKTsKKyAgc3RhdGljIGludDY0IER1cmF0aW9uVG9TZWNvbmRzKGNvbnN0IER1cmF0aW9uJiBkdXJhdGlvbik7CisgIHN0YXRpYyBpbnQ2NCBEdXJhdGlvblRvTWludXRlcyhjb25zdCBEdXJhdGlvbiYgZHVyYXRpb24pOworICBzdGF0aWMgaW50NjQgRHVyYXRpb25Ub0hvdXJzKGNvbnN0IER1cmF0aW9uJiBkdXJhdGlvbik7CisgIC8vIENyZWF0ZXMgVGltZXN0YW1wIGZyb20gaW50ZWdlciB0eXBlcy4gVGhlIGludGVnZXIgdmFsdWUgaW5kaWNhdGVzIHRoZQorICAvLyB0aW1lIGVsYXBzZWQgZnJvbSBFcG9jaCB0aW1lLiBUaGUgYmVoYXZpb3IgaXMgdW5kZWZpbmVkIGlmIHRoZSBpbnB1dAorICAvLyB2YWx1ZSBpcyBub3QgaW4gdGhlIHZhbGlkIHJhbmdlIG9mIFRpbWVzdGFtcC4KKyAgc3RhdGljIFRpbWVzdGFtcCBOYW5vc2Vjb25kc1RvVGltZXN0YW1wKGludDY0IG5hbm9zKTsKKyAgc3RhdGljIFRpbWVzdGFtcCBNaWNyb3NlY29uZHNUb1RpbWVzdGFtcChpbnQ2NCBtaWNyb3MpOworICBzdGF0aWMgVGltZXN0YW1wIE1pbGxpc2Vjb25kc1RvVGltZXN0YW1wKGludDY0IG1pbGxpcyk7CisgIHN0YXRpYyBUaW1lc3RhbXAgU2Vjb25kc1RvVGltZXN0YW1wKGludDY0IHNlY29uZHMpOworICAvLyBSZXN1bHQgd2lsbCBiZSB0cnVuY2F0ZWQgZG93biB0byB0aGUgbmVhcmVzdCBpbnRlZ2VyIHZhbHVlLiBGb3IgZXhhbXBsZSwKKyAgLy8gd2l0aCAiMTk2OS0xMi0zMVQyMzo1OTo1OS45WiIsIFRpbWVzdGFtcFRvTWlsbGlzZWNvbmRzKCkgcmV0dXJucyAtMTAwCisgIC8vIGFuZCBUaW1lc3RhbXBUb1NlY29uZHMoKSByZXR1cm5zIC0xLiBJdCdzIHVuZGVmaW5lZCBiZWhhdmlvciBpZiB0aGUgaW5wdXQKKyAgLy8gVGltZXN0YW1wIGlzIG5vdCB2YWxpZCAoaS5lLiwgaXRzIHNlY29uZHMgcGFydCBvciBuYW5vcyBwYXJ0IGRvZXMgbm90IGZhbGwKKyAgLy8gaW4gdGhlIHZhbGlkIHJhbmdlKSBvciB0aGUgcmV0dXJuIHZhbHVlIGRvZXNuJ3QgZml0IGludG8gaW50NjQuCisgIHN0YXRpYyBpbnQ2NCBUaW1lc3RhbXBUb05hbm9zZWNvbmRzKGNvbnN0IFRpbWVzdGFtcCYgdGltZXN0YW1wKTsKKyAgc3RhdGljIGludDY0IFRpbWVzdGFtcFRvTWljcm9zZWNvbmRzKGNvbnN0IFRpbWVzdGFtcCYgdGltZXN0YW1wKTsKKyAgc3RhdGljIGludDY0IFRpbWVzdGFtcFRvTWlsbGlzZWNvbmRzKGNvbnN0IFRpbWVzdGFtcCYgdGltZXN0YW1wKTsKKyAgc3RhdGljIGludDY0IFRpbWVzdGFtcFRvU2Vjb25kcyhjb25zdCBUaW1lc3RhbXAmIHRpbWVzdGFtcCk7CisKKyAgLy8gQ29udmVyc2lvbiB0by9mcm9tIG90aGVyIHRpbWUvZGF0ZSB0eXBlcy4gTm90ZSB0aGF0IHRoZXNlIHR5cGVzIG1heQorICAvLyBoYXZlIGEgZGlmZmVyZW50IHByZWNpc2lvbiBhbmQgdGltZSByYW5nZSBmcm9tIFRpbWVzdGFtcC9EdXJhdGlvbi4KKyAgLy8gV2hlbiBjb252ZXJ0aW5nIHRvIGEgbG93ZXIgcHJlY2lzaW9uIHR5cGUsIHRoZSB2YWx1ZSB3aWxsIGJlIHRydW5jYXRlZAorICAvLyB0byB0aGUgbmVhcmVzdCB2YWx1ZSB0aGF0IGNhbiBiZSByZXByZXNlbnRlZC4gSWYgdGhlIHZhbHVlIGlzCisgIC8vIG91dCBvZiB0aGUgcmFuZ2Ugb2YgdGhlIHJlc3VsdCB0eXBlLCB0aGUgcmV0dXJuIHZhbHVlIGlzIHVuZGVmaW5lZC4KKyAgLy8KKyAgLy8gQ29udmVyc2lvbiB0by9mcm9tIHRpbWVfdAorICBzdGF0aWMgVGltZXN0YW1wIFRpbWVUVG9UaW1lc3RhbXAodGltZV90IHZhbHVlKTsKKyAgc3RhdGljIHRpbWVfdCBUaW1lc3RhbXBUb1RpbWVUKGNvbnN0IFRpbWVzdGFtcCYgdmFsdWUpOworCisgIC8vIENvbnZlcnNpb24gdG8vZnJvbSB0aW1ldmFsCisgIHN0YXRpYyBUaW1lc3RhbXAgVGltZXZhbFRvVGltZXN0YW1wKGNvbnN0IHRpbWV2YWwmIHZhbHVlKTsKKyAgc3RhdGljIHRpbWV2YWwgVGltZXN0YW1wVG9UaW1ldmFsKGNvbnN0IFRpbWVzdGFtcCYgdmFsdWUpOworICBzdGF0aWMgRHVyYXRpb24gVGltZXZhbFRvRHVyYXRpb24oY29uc3QgdGltZXZhbCYgdmFsdWUpOworICBzdGF0aWMgdGltZXZhbCBEdXJhdGlvblRvVGltZXZhbChjb25zdCBEdXJhdGlvbiYgdmFsdWUpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIHV0aWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisvLyBPdmVybG9hZGVkIG9wZXJhdG9ycyBmb3IgRHVyYXRpb24uCisvLworLy8gQXNzaWdubWVudCBvcGVyYXRvcnMuCitMSUJQUk9UT0JVRl9FWFBPUlQgRHVyYXRpb24mIG9wZXJhdG9yKz0oRHVyYXRpb24mIGQxLCBjb25zdCBEdXJhdGlvbiYgZDIpOyAgLy8gTk9MSU5UCitMSUJQUk9UT0JVRl9FWFBPUlQgRHVyYXRpb24mIG9wZXJhdG9yLT0oRHVyYXRpb24mIGQxLCBjb25zdCBEdXJhdGlvbiYgZDIpOyAgLy8gTk9MSU5UCitMSUJQUk9UT0JVRl9FWFBPUlQgRHVyYXRpb24mIG9wZXJhdG9yKj0oRHVyYXRpb24mIGQsIGludDY0IHIpOyAgLy8gTk9MSU5UCitMSUJQUk9UT0JVRl9FWFBPUlQgRHVyYXRpb24mIG9wZXJhdG9yKj0oRHVyYXRpb24mIGQsIGRvdWJsZSByKTsgIC8vIE5PTElOVAorTElCUFJPVE9CVUZfRVhQT1JUIER1cmF0aW9uJiBvcGVyYXRvci89KER1cmF0aW9uJiBkLCBpbnQ2NCByKTsgIC8vIE5PTElOVAorTElCUFJPVE9CVUZfRVhQT1JUIER1cmF0aW9uJiBvcGVyYXRvci89KER1cmF0aW9uJiBkLCBkb3VibGUgcik7ICAvLyBOT0xJTlQKKy8vIE92ZXJsb2FkIGZvciBvdGhlciBpbnRlZ2VyIHR5cGVzLgordGVtcGxhdGUgPHR5cGVuYW1lIFQ+CitEdXJhdGlvbiYgb3BlcmF0b3IqPShEdXJhdGlvbiYgZCwgVCByKSB7ICAvLyBOT0xJTlQKKyAgaW50NjQgeCA9IHI7CisgIHJldHVybiBkICo9IHg7Cit9Cit0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4KK0R1cmF0aW9uJiBvcGVyYXRvci89KER1cmF0aW9uJiBkLCBUIHIpIHsgIC8vIE5PTElOVAorICBpbnQ2NCB4ID0gcjsKKyAgcmV0dXJuIGQgLz0geDsKK30KK0xJQlBST1RPQlVGX0VYUE9SVCBEdXJhdGlvbiYgb3BlcmF0b3IlPShEdXJhdGlvbiYgZDEsIGNvbnN0IER1cmF0aW9uJiBkMik7ICAvLyBOT0xJTlQKKy8vIFJlbGF0aW9uYWwgb3BlcmF0b3JzLgoraW5saW5lIGJvb2wgb3BlcmF0b3I8KGNvbnN0IER1cmF0aW9uJiBkMSwgY29uc3QgRHVyYXRpb24mIGQyKSB7CisgIGlmIChkMS5zZWNvbmRzKCkgPT0gZDIuc2Vjb25kcygpKSB7CisgICAgcmV0dXJuIGQxLm5hbm9zKCkgPCBkMi5uYW5vcygpOworICB9CisgIHJldHVybiBkMS5zZWNvbmRzKCkgPCBkMi5zZWNvbmRzKCk7Cit9CitpbmxpbmUgYm9vbCBvcGVyYXRvcj4oY29uc3QgRHVyYXRpb24mIGQxLCBjb25zdCBEdXJhdGlvbiYgZDIpIHsKKyAgcmV0dXJuIGQyIDwgZDE7Cit9CitpbmxpbmUgYm9vbCBvcGVyYXRvcj49KGNvbnN0IER1cmF0aW9uJiBkMSwgY29uc3QgRHVyYXRpb24mIGQyKSB7CisgIHJldHVybiAhKGQxIDwgZDIpOworfQoraW5saW5lIGJvb2wgb3BlcmF0b3I8PShjb25zdCBEdXJhdGlvbiYgZDEsIGNvbnN0IER1cmF0aW9uJiBkMikgeworICByZXR1cm4gIShkMiA8IGQxKTsKK30KK2lubGluZSBib29sIG9wZXJhdG9yPT0oY29uc3QgRHVyYXRpb24mIGQxLCBjb25zdCBEdXJhdGlvbiYgZDIpIHsKKyAgcmV0dXJuIGQxLnNlY29uZHMoKSA9PSBkMi5zZWNvbmRzKCkgJiYgZDEubmFub3MoKSA9PSBkMi5uYW5vcygpOworfQoraW5saW5lIGJvb2wgb3BlcmF0b3IhPShjb25zdCBEdXJhdGlvbiYgZDEsIGNvbnN0IER1cmF0aW9uJiBkMikgeworICByZXR1cm4gIShkMSA9PSBkMik7Cit9CisvLyBBZGRpdGl2ZSBvcGVyYXRvcnMKK2lubGluZSBEdXJhdGlvbiBvcGVyYXRvci0oY29uc3QgRHVyYXRpb24mIGQpIHsKKyAgRHVyYXRpb24gcmVzdWx0OworICByZXN1bHQuc2V0X3NlY29uZHMoLWQuc2Vjb25kcygpKTsKKyAgcmVzdWx0LnNldF9uYW5vcygtZC5uYW5vcygpKTsKKyAgcmV0dXJuIHJlc3VsdDsKK30KK2lubGluZSBEdXJhdGlvbiBvcGVyYXRvcisoY29uc3QgRHVyYXRpb24mIGQxLCBjb25zdCBEdXJhdGlvbiYgZDIpIHsKKyAgRHVyYXRpb24gcmVzdWx0ID0gZDE7CisgIHJldHVybiByZXN1bHQgKz0gZDI7Cit9CitpbmxpbmUgRHVyYXRpb24gb3BlcmF0b3ItKGNvbnN0IER1cmF0aW9uJiBkMSwgY29uc3QgRHVyYXRpb24mIGQyKSB7CisgIER1cmF0aW9uIHJlc3VsdCA9IGQxOworICByZXR1cm4gcmVzdWx0IC09IGQyOworfQorLy8gTXVsdGlwbGljYXRpdmUgb3BlcmF0b3JzCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPgoraW5saW5lIER1cmF0aW9uIG9wZXJhdG9yKihEdXJhdGlvbiBkLCBUIHIpIHsKKyAgcmV0dXJuIGQgKj0gcjsKK30KK3RlbXBsYXRlPHR5cGVuYW1lIFQ+CitpbmxpbmUgRHVyYXRpb24gb3BlcmF0b3IqKFQgciwgRHVyYXRpb24gZCkgeworICByZXR1cm4gZCAqPSByOworfQordGVtcGxhdGU8dHlwZW5hbWUgVD4KK2lubGluZSBEdXJhdGlvbiBvcGVyYXRvci8oRHVyYXRpb24gZCwgVCByKSB7CisgIHJldHVybiBkIC89IHI7Cit9CitMSUJQUk9UT0JVRl9FWFBPUlQgaW50NjQgb3BlcmF0b3IvKGNvbnN0IER1cmF0aW9uJiBkMSwgY29uc3QgRHVyYXRpb24mIGQyKTsKKworaW5saW5lIER1cmF0aW9uIG9wZXJhdG9yJShjb25zdCBEdXJhdGlvbiYgZDEsIGNvbnN0IER1cmF0aW9uJiBkMikgeworICBEdXJhdGlvbiByZXN1bHQgPSBkMTsKKyAgcmV0dXJuIHJlc3VsdCAlPSBkMjsKK30KKworaW5saW5lIG9zdHJlYW0mIG9wZXJhdG9yPDwob3N0cmVhbSYgb3V0LCBjb25zdCBEdXJhdGlvbiYgZCkgeworICBvdXQgPDwgZ29vZ2xlOjpwcm90b2J1Zjo6dXRpbDo6VGltZVV0aWw6OlRvU3RyaW5nKGQpOworICByZXR1cm4gb3V0OworfQorCisvLyBPdmVybG9hZGVkIG9wZXJhdG9ycyBmb3IgVGltZXN0YW1wCisvLworLy8gQXNzaWduZW1lbnQgb3BlcmF0b3JzLgorTElCUFJPVE9CVUZfRVhQT1JUIFRpbWVzdGFtcCYgb3BlcmF0b3IrPShUaW1lc3RhbXAmIHQsIGNvbnN0IER1cmF0aW9uJiBkKTsgIC8vIE5PTElOVAorTElCUFJPVE9CVUZfRVhQT1JUIFRpbWVzdGFtcCYgb3BlcmF0b3ItPShUaW1lc3RhbXAmIHQsIGNvbnN0IER1cmF0aW9uJiBkKTsgIC8vIE5PTElOVAorLy8gUmVsYXRpb25hbCBvcGVyYXRvcnMuCitpbmxpbmUgYm9vbCBvcGVyYXRvcjwoY29uc3QgVGltZXN0YW1wJiB0MSwgY29uc3QgVGltZXN0YW1wJiB0MikgeworICBpZiAodDEuc2Vjb25kcygpID09IHQyLnNlY29uZHMoKSkgeworICAgIHJldHVybiB0MS5uYW5vcygpIDwgdDIubmFub3MoKTsKKyAgfQorICByZXR1cm4gdDEuc2Vjb25kcygpIDwgdDIuc2Vjb25kcygpOworfQoraW5saW5lIGJvb2wgb3BlcmF0b3I+KGNvbnN0IFRpbWVzdGFtcCYgdDEsIGNvbnN0IFRpbWVzdGFtcCYgdDIpIHsKKyAgcmV0dXJuIHQyIDwgdDE7Cit9CitpbmxpbmUgYm9vbCBvcGVyYXRvcj49KGNvbnN0IFRpbWVzdGFtcCYgdDEsIGNvbnN0IFRpbWVzdGFtcCYgdDIpIHsKKyAgcmV0dXJuICEodDEgPCB0Mik7Cit9CitpbmxpbmUgYm9vbCBvcGVyYXRvcjw9KGNvbnN0IFRpbWVzdGFtcCYgdDEsIGNvbnN0IFRpbWVzdGFtcCYgdDIpIHsKKyAgcmV0dXJuICEodDIgPCB0MSk7Cit9CitpbmxpbmUgYm9vbCBvcGVyYXRvcj09KGNvbnN0IFRpbWVzdGFtcCYgdDEsIGNvbnN0IFRpbWVzdGFtcCYgdDIpIHsKKyAgcmV0dXJuIHQxLnNlY29uZHMoKSA9PSB0Mi5zZWNvbmRzKCkgJiYgdDEubmFub3MoKSA9PSB0Mi5uYW5vcygpOworfQoraW5saW5lIGJvb2wgb3BlcmF0b3IhPShjb25zdCBUaW1lc3RhbXAmIHQxLCBjb25zdCBUaW1lc3RhbXAmIHQyKSB7CisgIHJldHVybiAhKHQxID09IHQyKTsKK30KKy8vIEFkZGl0aXZlIG9wZXJhdG9ycy4KK2lubGluZSBUaW1lc3RhbXAgb3BlcmF0b3IrKGNvbnN0IFRpbWVzdGFtcCYgdCwgY29uc3QgRHVyYXRpb24mIGQpIHsKKyAgVGltZXN0YW1wIHJlc3VsdCA9IHQ7CisgIHJldHVybiByZXN1bHQgKz0gZDsKK30KK2lubGluZSBUaW1lc3RhbXAgb3BlcmF0b3IrKGNvbnN0IER1cmF0aW9uJiBkLCBjb25zdCBUaW1lc3RhbXAmIHQpIHsKKyAgVGltZXN0YW1wIHJlc3VsdCA9IHQ7CisgIHJldHVybiByZXN1bHQgKz0gZDsKK30KK2lubGluZSBUaW1lc3RhbXAgb3BlcmF0b3ItKGNvbnN0IFRpbWVzdGFtcCYgdCwgY29uc3QgRHVyYXRpb24mIGQpIHsKKyAgVGltZXN0YW1wIHJlc3VsdCA9IHQ7CisgIHJldHVybiByZXN1bHQgLT0gZDsKK30KK0xJQlBST1RPQlVGX0VYUE9SVCBEdXJhdGlvbiBvcGVyYXRvci0oY29uc3QgVGltZXN0YW1wJiB0MSwgY29uc3QgVGltZXN0YW1wJiB0Mik7CisKK2lubGluZSBvc3RyZWFtJiBvcGVyYXRvcjw8KG9zdHJlYW0mIG91dCwgY29uc3QgVGltZXN0YW1wJiB0KSB7CisgIG91dCA8PCBnb29nbGU6OnByb3RvYnVmOjp1dGlsOjpUaW1lVXRpbDo6VG9TdHJpbmcodCk7CisgIHJldHVybiBvdXQ7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX1VUSUxfVElNRV9VVElMX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL3RpbWVfdXRpbF90ZXN0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL3RpbWVfdXRpbF90ZXN0LmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI4NTc0MGEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvdGltZV91dGlsX3Rlc3QuY2MKQEAgLTAsMCArMSwzODAgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3V0aWwvdGltZV91dGlsLmg+CisKKyNpbmNsdWRlIDxjdGltZT4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90aW1lc3RhbXAucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZHVyYXRpb24ucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0Lmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIHV0aWwgeworCit1c2luZyBnb29nbGU6OnByb3RvYnVmOjpUaW1lc3RhbXA7Cit1c2luZyBnb29nbGU6OnByb3RvYnVmOjpEdXJhdGlvbjsKKworbmFtZXNwYWNlIHsKKworVEVTVChUaW1lVXRpbFRlc3QsIFRpbWVzdGFtcFN0cmluZ0Zvcm1hdCkgeworICBUaW1lc3RhbXAgYmVnaW4sIGVuZDsKKyAgRVhQRUNUX1RSVUUoVGltZVV0aWw6OkZyb21TdHJpbmcoIjAwMDEtMDEtMDFUMDA6MDA6MDBaIiwgJmJlZ2luKSk7CisgIEVYUEVDVF9FUShUaW1lVXRpbDo6a1RpbWVzdGFtcE1pblNlY29uZHMsIGJlZ2luLnNlY29uZHMoKSk7CisgIEVYUEVDVF9FUSgwLCBiZWdpbi5uYW5vcygpKTsKKyAgRVhQRUNUX1RSVUUoVGltZVV0aWw6OkZyb21TdHJpbmcoIjk5OTktMTItMzFUMjM6NTk6NTkuOTk5OTk5OTk5WiIsICZlbmQpKTsKKyAgRVhQRUNUX0VRKFRpbWVVdGlsOjprVGltZXN0YW1wTWF4U2Vjb25kcywgZW5kLnNlY29uZHMoKSk7CisgIEVYUEVDVF9FUSg5OTk5OTk5OTksIGVuZC5uYW5vcygpKTsKKyAgRVhQRUNUX0VRKCIwMDAxLTAxLTAxVDAwOjAwOjAwWiIsIFRpbWVVdGlsOjpUb1N0cmluZyhiZWdpbikpOworICBFWFBFQ1RfRVEoIjk5OTktMTItMzFUMjM6NTk6NTkuOTk5OTk5OTk5WiIsIFRpbWVVdGlsOjpUb1N0cmluZyhlbmQpKTsKKworICAvLyBUZXN0IG5lZ2F0aXZlIHRpbWVzdGFtcHMuCisgIFRpbWVzdGFtcCB0aW1lID0gVGltZVV0aWw6Ok5hbm9zZWNvbmRzVG9UaW1lc3RhbXAoLTEpOworICBFWFBFQ1RfRVEoLTEsIHRpbWUuc2Vjb25kcygpKTsKKyAgLy8gVGltZXN0YW1wJ3MgbmFubyBwYXJ0IGlzIGFsd2F5cyBub24tbmVnYXRpdmUuCisgIEVYUEVDVF9FUSg5OTk5OTk5OTksIHRpbWUubmFub3MoKSk7CisgIEVYUEVDVF9FUSgiMTk2OS0xMi0zMVQyMzo1OTo1OS45OTk5OTk5OTlaIiwgVGltZVV0aWw6OlRvU3RyaW5nKHRpbWUpKTsKKworICAvLyBHZW5lcmF0ZWQgb3V0cHV0IHNob3VsZCBjb250YWluIDMsIDYsIG9yIDkgZnJhY3Rpb25hbCBkaWdpdHMuCisgIEVYUEVDVF9FUSgiMTk3MC0wMS0wMVQwMDowMDowMFoiLAorICAgICAgICAgICAgVGltZVV0aWw6OlRvU3RyaW5nKFRpbWVVdGlsOjpOYW5vc2Vjb25kc1RvVGltZXN0YW1wKDApKSk7CisgIEVYUEVDVF9FUSgiMTk3MC0wMS0wMVQwMDowMDowMC4wMTBaIiwKKyAgICAgICAgICAgIFRpbWVVdGlsOjpUb1N0cmluZyhUaW1lVXRpbDo6TmFub3NlY29uZHNUb1RpbWVzdGFtcCgxMDAwMDAwMCkpKTsKKyAgRVhQRUNUX0VRKCIxOTcwLTAxLTAxVDAwOjAwOjAwLjAwMDAxMFoiLAorICAgICAgICAgICAgVGltZVV0aWw6OlRvU3RyaW5nKFRpbWVVdGlsOjpOYW5vc2Vjb25kc1RvVGltZXN0YW1wKDEwMDAwKSkpOworICBFWFBFQ1RfRVEoIjE5NzAtMDEtMDFUMDA6MDA6MDAuMDAwMDAwMDEwWiIsCisgICAgICAgICAgICBUaW1lVXRpbDo6VG9TdHJpbmcoVGltZVV0aWw6Ok5hbm9zZWNvbmRzVG9UaW1lc3RhbXAoMTApKSk7CisKKyAgLy8gUGFyc2luZyBhY2NlcHRzIGFuIGZyYWN0aW9uYWwgZGlnaXRzIGFzIGxvbmcgYXMgdGhleSBmaXQgaW50byBuYW5vCisgIC8vIHByZWNpc2lvbi4KKyAgRVhQRUNUX1RSVUUoVGltZVV0aWw6OkZyb21TdHJpbmcoIjE5NzAtMDEtMDFUMDA6MDA6MDAuMVoiLCAmdGltZSkpOworICBFWFBFQ1RfRVEoMTAwMDAwMDAwLCBUaW1lVXRpbDo6VGltZXN0YW1wVG9OYW5vc2Vjb25kcyh0aW1lKSk7CisgIEVYUEVDVF9UUlVFKFRpbWVVdGlsOjpGcm9tU3RyaW5nKCIxOTcwLTAxLTAxVDAwOjAwOjAwLjAwMDFaIiwgJnRpbWUpKTsKKyAgRVhQRUNUX0VRKDEwMDAwMCwgVGltZVV0aWw6OlRpbWVzdGFtcFRvTmFub3NlY29uZHModGltZSkpOworICBFWFBFQ1RfVFJVRShUaW1lVXRpbDo6RnJvbVN0cmluZygiMTk3MC0wMS0wMVQwMDowMDowMC4wMDAwMDAxWiIsICZ0aW1lKSk7CisgIEVYUEVDVF9FUSgxMDAsIFRpbWVVdGlsOjpUaW1lc3RhbXBUb05hbm9zZWNvbmRzKHRpbWUpKTsKKworICAvLyBBbHNvIGFjY3BldHMgb2Zmc2V0cy4KKyAgRVhQRUNUX1RSVUUoVGltZVV0aWw6OkZyb21TdHJpbmcoIjE5NzAtMDEtMDFUMDA6MDA6MDAtMDg6MDAiLCAmdGltZSkpOworICBFWFBFQ1RfRVEoOCAqIDM2MDAsIFRpbWVVdGlsOjpUaW1lc3RhbXBUb1NlY29uZHModGltZSkpOworfQorCitURVNUKFRpbWVVdGlsVGVzdCwgRHVyYXRpb25TdHJpbmdGb3JtYXQpIHsKKyAgVGltZXN0YW1wIGJlZ2luLCBlbmQ7CisgIEVYUEVDVF9UUlVFKFRpbWVVdGlsOjpGcm9tU3RyaW5nKCIwMDAxLTAxLTAxVDAwOjAwOjAwWiIsICZiZWdpbikpOworICBFWFBFQ1RfVFJVRShUaW1lVXRpbDo6RnJvbVN0cmluZygiOTk5OS0xMi0zMVQyMzo1OTo1OS45OTk5OTk5OTlaIiwgJmVuZCkpOworCisgIEVYUEVDVF9FUSgiMzE1NTM3ODk3NTk5Ljk5OTk5OTk5OXMiLCBUaW1lVXRpbDo6VG9TdHJpbmcoZW5kIC0gYmVnaW4pKTsKKyAgRVhQRUNUX0VRKDk5OTk5OTk5OSwgKGVuZCAtIGJlZ2luKS5uYW5vcygpKTsKKyAgRVhQRUNUX0VRKCItMzE1NTM3ODk3NTk5Ljk5OTk5OTk5OXMiLCBUaW1lVXRpbDo6VG9TdHJpbmcoYmVnaW4gLSBlbmQpKTsKKyAgRVhQRUNUX0VRKC05OTk5OTk5OTksIChiZWdpbiAtIGVuZCkubmFub3MoKSk7CisKKyAgLy8gR2VuZXJhdGVkIG91dHB1dCBzaG91bGQgY29udGFpbiAzLCA2LCBvciA5IGZyYWN0aW9uYWwgZGlnaXRzLgorICBFWFBFQ1RfRVEoIjFzIiwgVGltZVV0aWw6OlRvU3RyaW5nKFRpbWVVdGlsOjpTZWNvbmRzVG9EdXJhdGlvbigxKSkpOworICBFWFBFQ1RfRVEoIjAuMDEwcyIsIFRpbWVVdGlsOjpUb1N0cmluZyhUaW1lVXRpbDo6TWlsbGlzZWNvbmRzVG9EdXJhdGlvbigxMCkpKTsKKyAgRVhQRUNUX0VRKCIwLjAwMDAxMHMiLAorICAgICAgICAgICAgVGltZVV0aWw6OlRvU3RyaW5nKFRpbWVVdGlsOjpNaWNyb3NlY29uZHNUb0R1cmF0aW9uKDEwKSkpOworICBFWFBFQ1RfRVEoIjAuMDAwMDAwMDEwcyIsCisgICAgICAgICAgICBUaW1lVXRpbDo6VG9TdHJpbmcoVGltZVV0aWw6Ok5hbm9zZWNvbmRzVG9EdXJhdGlvbigxMCkpKTsKKworICAvLyBQYXJzaW5nIGFjY2VwdHMgYW4gZnJhY3Rpb25hbCBkaWdpdHMgYXMgbG9uZyBhcyB0aGV5IGZpdCBpbnRvIG5hbm8KKyAgLy8gcHJlY2lzaW9uLgorICBEdXJhdGlvbiBkOworICBFWFBFQ1RfVFJVRShUaW1lVXRpbDo6RnJvbVN0cmluZygiMC4xcyIsICZkKSk7CisgIEVYUEVDVF9FUSgxMDAsIFRpbWVVdGlsOjpEdXJhdGlvblRvTWlsbGlzZWNvbmRzKGQpKTsKKyAgRVhQRUNUX1RSVUUoVGltZVV0aWw6OkZyb21TdHJpbmcoIjAuMDAwMXMiLCAmZCkpOworICBFWFBFQ1RfRVEoMTAwLCBUaW1lVXRpbDo6RHVyYXRpb25Ub01pY3Jvc2Vjb25kcyhkKSk7CisgIEVYUEVDVF9UUlVFKFRpbWVVdGlsOjpGcm9tU3RyaW5nKCIwLjAwMDAwMDFzIiwgJmQpKTsKKyAgRVhQRUNUX0VRKDEwMCwgVGltZVV0aWw6OkR1cmF0aW9uVG9OYW5vc2Vjb25kcyhkKSk7CisKKyAgLy8gRHVyYXRpb24gbXVzdCBzdXBwb3J0IHJhbmdlIGZyb20gLTMxNSw1NzYsMDAwLDAwMHMgdG8gKzMxNTU3NjAwMDAwMHMKKyAgLy8gd2hpY2ggaW5jbHVkZXMgbmVnYXRpdmUgdmFsdWVzLgorICBFWFBFQ1RfVFJVRShUaW1lVXRpbDo6RnJvbVN0cmluZygiMzE1NTc2MDAwMDAwLjk5OTk5OTk5OXMiLCAmZCkpOworICBFWFBFQ1RfRVEoMzE1NTc2MDAwMDAwTEwsIGQuc2Vjb25kcygpKTsKKyAgRVhQRUNUX0VRKDk5OTk5OTk5OSwgZC5uYW5vcygpKTsKKyAgRVhQRUNUX1RSVUUoVGltZVV0aWw6OkZyb21TdHJpbmcoIi0zMTU1NzYwMDAwMDAuOTk5OTk5OTk5cyIsICZkKSk7CisgIEVYUEVDVF9FUSgtMzE1NTc2MDAwMDAwTEwsIGQuc2Vjb25kcygpKTsKKyAgRVhQRUNUX0VRKC05OTk5OTk5OTksIGQubmFub3MoKSk7Cit9CisKK1RFU1QoVGltZVV0aWxUZXN0LCBHZXRFcG9jaCkgeworICBFWFBFQ1RfRVEoMCwgVGltZVV0aWw6OlRpbWVzdGFtcFRvTmFub3NlY29uZHMoVGltZVV0aWw6OkdldEVwb2NoKCkpKTsKK30KKworVEVTVChUaW1lVXRpbFRlc3QsIER1cmF0aW9uSW50ZWdlckNvbnZlcnNpb24pIHsKKyAgRVhQRUNUX0VRKCIwLjAwMDAwMDAwMXMiLAorICAgICAgICAgICAgVGltZVV0aWw6OlRvU3RyaW5nKFRpbWVVdGlsOjpOYW5vc2Vjb25kc1RvRHVyYXRpb24oMSkpKTsKKyAgRVhQRUNUX0VRKCItMC4wMDAwMDAwMDFzIiwKKyAgICAgICAgICAgIFRpbWVVdGlsOjpUb1N0cmluZyhUaW1lVXRpbDo6TmFub3NlY29uZHNUb0R1cmF0aW9uKC0xKSkpOworICBFWFBFQ1RfRVEoIjAuMDAwMDAxcyIsCisgICAgICAgICAgICBUaW1lVXRpbDo6VG9TdHJpbmcoVGltZVV0aWw6Ok1pY3Jvc2Vjb25kc1RvRHVyYXRpb24oMSkpKTsKKyAgRVhQRUNUX0VRKCItMC4wMDAwMDFzIiwKKyAgICAgICAgICAgIFRpbWVVdGlsOjpUb1N0cmluZyhUaW1lVXRpbDo6TWljcm9zZWNvbmRzVG9EdXJhdGlvbigtMSkpKTsKKyAgRVhQRUNUX0VRKCIwLjAwMXMiLCBUaW1lVXRpbDo6VG9TdHJpbmcoVGltZVV0aWw6Ok1pbGxpc2Vjb25kc1RvRHVyYXRpb24oMSkpKTsKKyAgRVhQRUNUX0VRKCItMC4wMDFzIiwKKyAgICAgICAgICAgIFRpbWVVdGlsOjpUb1N0cmluZyhUaW1lVXRpbDo6TWlsbGlzZWNvbmRzVG9EdXJhdGlvbigtMSkpKTsKKyAgRVhQRUNUX0VRKCIxcyIsIFRpbWVVdGlsOjpUb1N0cmluZyhUaW1lVXRpbDo6U2Vjb25kc1RvRHVyYXRpb24oMSkpKTsKKyAgRVhQRUNUX0VRKCItMXMiLCBUaW1lVXRpbDo6VG9TdHJpbmcoVGltZVV0aWw6OlNlY29uZHNUb0R1cmF0aW9uKC0xKSkpOworICBFWFBFQ1RfRVEoIjYwcyIsIFRpbWVVdGlsOjpUb1N0cmluZyhUaW1lVXRpbDo6TWludXRlc1RvRHVyYXRpb24oMSkpKTsKKyAgRVhQRUNUX0VRKCItNjBzIiwgVGltZVV0aWw6OlRvU3RyaW5nKFRpbWVVdGlsOjpNaW51dGVzVG9EdXJhdGlvbigtMSkpKTsKKyAgRVhQRUNUX0VRKCIzNjAwcyIsIFRpbWVVdGlsOjpUb1N0cmluZyhUaW1lVXRpbDo6SG91cnNUb0R1cmF0aW9uKDEpKSk7CisgIEVYUEVDVF9FUSgiLTM2MDBzIiwgVGltZVV0aWw6OlRvU3RyaW5nKFRpbWVVdGlsOjpIb3Vyc1RvRHVyYXRpb24oLTEpKSk7CisKKyAgRVhQRUNUX0VRKAorICAgICAgMSwgVGltZVV0aWw6OkR1cmF0aW9uVG9OYW5vc2Vjb25kcyhUaW1lVXRpbDo6TmFub3NlY29uZHNUb0R1cmF0aW9uKDEpKSk7CisgIEVYUEVDVF9FUSgKKyAgICAgIC0xLCBUaW1lVXRpbDo6RHVyYXRpb25Ub05hbm9zZWNvbmRzKFRpbWVVdGlsOjpOYW5vc2Vjb25kc1RvRHVyYXRpb24oLTEpKSk7CisgIEVYUEVDVF9FUSgKKyAgICAgIDEsIFRpbWVVdGlsOjpEdXJhdGlvblRvTWljcm9zZWNvbmRzKFRpbWVVdGlsOjpNaWNyb3NlY29uZHNUb0R1cmF0aW9uKDEpKSk7CisgIEVYUEVDVF9FUSgtMSwgVGltZVV0aWw6OkR1cmF0aW9uVG9NaWNyb3NlY29uZHMoCisgICAgICAgICAgICAgICAgICAgIFRpbWVVdGlsOjpNaWNyb3NlY29uZHNUb0R1cmF0aW9uKC0xKSkpOworICBFWFBFQ1RfRVEoCisgICAgICAxLCBUaW1lVXRpbDo6RHVyYXRpb25Ub01pbGxpc2Vjb25kcyhUaW1lVXRpbDo6TWlsbGlzZWNvbmRzVG9EdXJhdGlvbigxKSkpOworICBFWFBFQ1RfRVEoLTEsIFRpbWVVdGlsOjpEdXJhdGlvblRvTWlsbGlzZWNvbmRzKAorICAgICAgICAgICAgICAgICAgICBUaW1lVXRpbDo6TWlsbGlzZWNvbmRzVG9EdXJhdGlvbigtMSkpKTsKKyAgRVhQRUNUX0VRKDEsIFRpbWVVdGlsOjpEdXJhdGlvblRvU2Vjb25kcyhUaW1lVXRpbDo6U2Vjb25kc1RvRHVyYXRpb24oMSkpKTsKKyAgRVhQRUNUX0VRKC0xLCBUaW1lVXRpbDo6RHVyYXRpb25Ub1NlY29uZHMoVGltZVV0aWw6OlNlY29uZHNUb0R1cmF0aW9uKC0xKSkpOworICBFWFBFQ1RfRVEoMSwgVGltZVV0aWw6OkR1cmF0aW9uVG9NaW51dGVzKFRpbWVVdGlsOjpNaW51dGVzVG9EdXJhdGlvbigxKSkpOworICBFWFBFQ1RfRVEoLTEsIFRpbWVVdGlsOjpEdXJhdGlvblRvTWludXRlcyhUaW1lVXRpbDo6TWludXRlc1RvRHVyYXRpb24oLTEpKSk7CisgIEVYUEVDVF9FUSgxLCBUaW1lVXRpbDo6RHVyYXRpb25Ub0hvdXJzKFRpbWVVdGlsOjpIb3Vyc1RvRHVyYXRpb24oMSkpKTsKKyAgRVhQRUNUX0VRKC0xLCBUaW1lVXRpbDo6RHVyYXRpb25Ub0hvdXJzKFRpbWVVdGlsOjpIb3Vyc1RvRHVyYXRpb24oLTEpKSk7CisKKyAgLy8gVGVzdCB0cnVuY2F0aW9uIGJlaGF2aW9yLgorICBFWFBFQ1RfRVEoMSwgVGltZVV0aWw6OkR1cmF0aW9uVG9NaWNyb3NlY29uZHMoCisgICAgICAgICAgICAgICAgICAgVGltZVV0aWw6Ok5hbm9zZWNvbmRzVG9EdXJhdGlvbigxOTk5KSkpOworICAvLyBGb3IgbmVnYXRpdmUgdmFsdWVzLCBEdXJhdGlvbiB3aWxsIGJlIHJvdW5kZWQgdG93YXJkcyAwLgorICBFWFBFQ1RfRVEoLTEsIFRpbWVVdGlsOjpEdXJhdGlvblRvTWljcm9zZWNvbmRzKAorICAgICAgICAgICAgICAgICAgICBUaW1lVXRpbDo6TmFub3NlY29uZHNUb0R1cmF0aW9uKC0xOTk5KSkpOworfQorCitURVNUKFRlc3RVdGlsVGVzdCwgVGltZXN0YW1wSW50ZWdlckNvbnZlcnNpb24pIHsKKyAgRVhQRUNUX0VRKCIxOTcwLTAxLTAxVDAwOjAwOjAwLjAwMDAwMDAwMVoiLAorICAgICAgICAgICAgVGltZVV0aWw6OlRvU3RyaW5nKFRpbWVVdGlsOjpOYW5vc2Vjb25kc1RvVGltZXN0YW1wKDEpKSk7CisgIEVYUEVDVF9FUSgiMTk2OS0xMi0zMVQyMzo1OTo1OS45OTk5OTk5OTlaIiwKKyAgICAgICAgICAgIFRpbWVVdGlsOjpUb1N0cmluZyhUaW1lVXRpbDo6TmFub3NlY29uZHNUb1RpbWVzdGFtcCgtMSkpKTsKKyAgRVhQRUNUX0VRKCIxOTcwLTAxLTAxVDAwOjAwOjAwLjAwMDAwMVoiLAorICAgICAgICAgICAgVGltZVV0aWw6OlRvU3RyaW5nKFRpbWVVdGlsOjpNaWNyb3NlY29uZHNUb1RpbWVzdGFtcCgxKSkpOworICBFWFBFQ1RfRVEoIjE5NjktMTItMzFUMjM6NTk6NTkuOTk5OTk5WiIsCisgICAgICAgICAgICBUaW1lVXRpbDo6VG9TdHJpbmcoVGltZVV0aWw6Ok1pY3Jvc2Vjb25kc1RvVGltZXN0YW1wKC0xKSkpOworICBFWFBFQ1RfRVEoIjE5NzAtMDEtMDFUMDA6MDA6MDAuMDAxWiIsCisgICAgICAgICAgICBUaW1lVXRpbDo6VG9TdHJpbmcoVGltZVV0aWw6Ok1pbGxpc2Vjb25kc1RvVGltZXN0YW1wKDEpKSk7CisgIEVYUEVDVF9FUSgiMTk2OS0xMi0zMVQyMzo1OTo1OS45OTlaIiwKKyAgICAgICAgICAgIFRpbWVVdGlsOjpUb1N0cmluZyhUaW1lVXRpbDo6TWlsbGlzZWNvbmRzVG9UaW1lc3RhbXAoLTEpKSk7CisgIEVYUEVDVF9FUSgiMTk3MC0wMS0wMVQwMDowMDowMVoiLAorICAgICAgICAgICAgVGltZVV0aWw6OlRvU3RyaW5nKFRpbWVVdGlsOjpTZWNvbmRzVG9UaW1lc3RhbXAoMSkpKTsKKyAgRVhQRUNUX0VRKCIxOTY5LTEyLTMxVDIzOjU5OjU5WiIsCisgICAgICAgICAgICBUaW1lVXRpbDo6VG9TdHJpbmcoVGltZVV0aWw6OlNlY29uZHNUb1RpbWVzdGFtcCgtMSkpKTsKKworICBFWFBFQ1RfRVEoCisgICAgICAxLCBUaW1lVXRpbDo6VGltZXN0YW1wVG9OYW5vc2Vjb25kcyhUaW1lVXRpbDo6TmFub3NlY29uZHNUb1RpbWVzdGFtcCgxKSkpOworICBFWFBFQ1RfRVEoLTEsIFRpbWVVdGlsOjpUaW1lc3RhbXBUb05hbm9zZWNvbmRzKAorICAgICAgICAgICAgICAgICAgICBUaW1lVXRpbDo6TmFub3NlY29uZHNUb1RpbWVzdGFtcCgtMSkpKTsKKyAgRVhQRUNUX0VRKDEsIFRpbWVVdGlsOjpUaW1lc3RhbXBUb01pY3Jvc2Vjb25kcygKKyAgICAgICAgICAgICAgICAgICBUaW1lVXRpbDo6TWljcm9zZWNvbmRzVG9UaW1lc3RhbXAoMSkpKTsKKyAgRVhQRUNUX0VRKC0xLCBUaW1lVXRpbDo6VGltZXN0YW1wVG9NaWNyb3NlY29uZHMoCisgICAgICAgICAgICAgICAgICAgIFRpbWVVdGlsOjpNaWNyb3NlY29uZHNUb1RpbWVzdGFtcCgtMSkpKTsKKyAgRVhQRUNUX0VRKDEsIFRpbWVVdGlsOjpUaW1lc3RhbXBUb01pbGxpc2Vjb25kcygKKyAgICAgICAgICAgICAgICAgICBUaW1lVXRpbDo6TWlsbGlzZWNvbmRzVG9UaW1lc3RhbXAoMSkpKTsKKyAgRVhQRUNUX0VRKC0xLCBUaW1lVXRpbDo6VGltZXN0YW1wVG9NaWxsaXNlY29uZHMoCisgICAgICAgICAgICAgICAgICAgIFRpbWVVdGlsOjpNaWxsaXNlY29uZHNUb1RpbWVzdGFtcCgtMSkpKTsKKyAgRVhQRUNUX0VRKDEsIFRpbWVVdGlsOjpUaW1lc3RhbXBUb1NlY29uZHMoVGltZVV0aWw6OlNlY29uZHNUb1RpbWVzdGFtcCgxKSkpOworICBFWFBFQ1RfRVEoLTEsIFRpbWVVdGlsOjpUaW1lc3RhbXBUb1NlY29uZHMoVGltZVV0aWw6OlNlY29uZHNUb1RpbWVzdGFtcCgtMSkpKTsKKworICAvLyBUZXN0IHRydW5jYXRpb24gYmVoYXZpb3IuCisgIEVYUEVDVF9FUSgxLCBUaW1lVXRpbDo6VGltZXN0YW1wVG9NaWNyb3NlY29uZHMoCisgICAgICAgICAgICAgICAgICAgVGltZVV0aWw6Ok5hbm9zZWNvbmRzVG9UaW1lc3RhbXAoMTk5OSkpKTsKKyAgLy8gRm9yIG5lZ2F0aXZlIHZhbHVlcywgVGltZXN0YW1wIHdpbGwgYmUgcm91bmRlZCBkb3duLgorICAvLyBGb3IgZXhhbXBsZSwgIjE5NjktMTItMzFUMjM6NTk6NTkuNVoiIChpLmUuLCAtMC41cykgcm91bmRlZCB0byBzZWNvbmRzCisgIC8vIHdpbGwgYmUgIjE5NjktMTItMzFUMjM6NTk6NTlaIiAoaS5lLiwgLTFzKSByYXRoZXIgdGhhbgorICAvLyAiMTk3MC0wMS0wMVQwMDowMDowMFoiIChpLmUuLCAwcykuCisgIEVYUEVDVF9FUSgtMiwgVGltZVV0aWw6OlRpbWVzdGFtcFRvTWljcm9zZWNvbmRzKAorICAgICAgICAgICAgICAgICAgICBUaW1lVXRpbDo6TmFub3NlY29uZHNUb1RpbWVzdGFtcCgtMTk5OSkpKTsKK30KKworVEVTVChUaW1lVXRpbFRlc3QsIFRpbWVUQ29udmVyc2lvbikgeworICB0aW1lX3QgdmFsdWUgPSB0aW1lKE5VTEwpOworICBFWFBFQ1RfRVEodmFsdWUsCisgICAgICAgICAgICBUaW1lVXRpbDo6VGltZXN0YW1wVG9UaW1lVChUaW1lVXRpbDo6VGltZVRUb1RpbWVzdGFtcCh2YWx1ZSkpKTsKKyAgRVhQRUNUX0VRKAorICAgICAgMSwgVGltZVV0aWw6OlRpbWVzdGFtcFRvVGltZVQoVGltZVV0aWw6Ok1pbGxpc2Vjb25kc1RvVGltZXN0YW1wKDE5OTkpKSk7Cit9CisKK1RFU1QoVGltZVV0aWxUZXN0LCBUaW1ldmFsQ29udmVyc2lvbikgeworICB0aW1ldmFsIHZhbHVlID0gVGltZVV0aWw6OlRpbWVzdGFtcFRvVGltZXZhbCgKKyAgICAgIFRpbWVVdGlsOjpOYW5vc2Vjb25kc1RvVGltZXN0YW1wKDE5OTk5OTk5OTkpKTsKKyAgRVhQRUNUX0VRKDEsIHZhbHVlLnR2X3NlYyk7CisgIEVYUEVDVF9FUSg5OTk5OTksIHZhbHVlLnR2X3VzZWMpOworICB2YWx1ZSA9IFRpbWVVdGlsOjpUaW1lc3RhbXBUb1RpbWV2YWwoCisgICAgICBUaW1lVXRpbDo6TmFub3NlY29uZHNUb1RpbWVzdGFtcCgtMTk5OTk5OTk5OSkpOworICBFWFBFQ1RfRVEoLTIsIHZhbHVlLnR2X3NlYyk7CisgIEVYUEVDVF9FUSgwLCB2YWx1ZS50dl91c2VjKTsKKworICB2YWx1ZSA9CisgICAgICBUaW1lVXRpbDo6RHVyYXRpb25Ub1RpbWV2YWwoVGltZVV0aWw6Ok5hbm9zZWNvbmRzVG9EdXJhdGlvbigxOTk5OTk5OTk5KSk7CisgIEVYUEVDVF9FUSgxLCB2YWx1ZS50dl9zZWMpOworICBFWFBFQ1RfRVEoOTk5OTk5LCB2YWx1ZS50dl91c2VjKTsKKyAgdmFsdWUgPQorICAgICAgVGltZVV0aWw6OkR1cmF0aW9uVG9UaW1ldmFsKFRpbWVVdGlsOjpOYW5vc2Vjb25kc1RvRHVyYXRpb24oLTE5OTk5OTk5OTkpKTsKKyAgRVhQRUNUX0VRKC0yLCB2YWx1ZS50dl9zZWMpOworICBFWFBFQ1RfRVEoMSwgdmFsdWUudHZfdXNlYyk7Cit9CisKK1RFU1QoVGltZVV0aWxUZXN0LCBEdXJhdGlvbk9wZXJhdG9ycykgeworICBEdXJhdGlvbiBvbmVfc2Vjb25kID0gVGltZVV0aWw6OlNlY29uZHNUb0R1cmF0aW9uKDEpOworICBEdXJhdGlvbiBvbmVfbmFubyA9IFRpbWVVdGlsOjpOYW5vc2Vjb25kc1RvRHVyYXRpb24oMSk7CisKKyAgLy8gVGVzdCArLy0KKyAgRHVyYXRpb24gYSA9IG9uZV9zZWNvbmQ7CisgIGEgKz0gb25lX3NlY29uZDsKKyAgYSAtPSBvbmVfbmFubzsKKyAgRVhQRUNUX0VRKCIxLjk5OTk5OTk5OXMiLCBUaW1lVXRpbDo6VG9TdHJpbmcoYSkpOworICBEdXJhdGlvbiBiID0gLWE7CisgIEVYUEVDVF9FUSgiLTEuOTk5OTk5OTk5cyIsIFRpbWVVdGlsOjpUb1N0cmluZyhiKSk7CisgIEVYUEVDVF9FUSgiMy45OTk5OTk5OThzIiwgVGltZVV0aWw6OlRvU3RyaW5nKGEgKyBhKSk7CisgIEVYUEVDVF9FUSgiMHMiLCBUaW1lVXRpbDo6VG9TdHJpbmcoYSArIGIpKTsKKyAgRVhQRUNUX0VRKCIwcyIsIFRpbWVVdGlsOjpUb1N0cmluZyhiICsgYSkpOworICBFWFBFQ1RfRVEoIi0zLjk5OTk5OTk5OHMiLCBUaW1lVXRpbDo6VG9TdHJpbmcoYiArIGIpKTsKKyAgRVhQRUNUX0VRKCIzLjk5OTk5OTk5OHMiLCBUaW1lVXRpbDo6VG9TdHJpbmcoYSAtIGIpKTsKKyAgRVhQRUNUX0VRKCIwcyIsIFRpbWVVdGlsOjpUb1N0cmluZyhhIC0gYSkpOworICBFWFBFQ1RfRVEoIjBzIiwgVGltZVV0aWw6OlRvU3RyaW5nKGIgLSBiKSk7CisgIEVYUEVDVF9FUSgiLTMuOTk5OTk5OTk4cyIsIFRpbWVVdGlsOjpUb1N0cmluZyhiIC0gYSkpOworCisgIC8vIFRlc3QgKgorICBFWFBFQ1RfRVEoYSArIGEsIGEgKiAyKTsKKyAgRVhQRUNUX0VRKGIgKyBiLCBhICogKC0yKSk7CisgIEVYUEVDVF9FUShiICsgYiwgYiAqIDIpOworICBFWFBFQ1RfRVEoYSArIGEsIGIgKiAoLTIpKTsKKyAgRVhQRUNUX0VRKCIwLjk5OTk5OTk5OXMiLCBUaW1lVXRpbDo6VG9TdHJpbmcoYSAqIDAuNSkpOworICBFWFBFQ1RfRVEoIi0wLjk5OTk5OTk5OXMiLCBUaW1lVXRpbDo6VG9TdHJpbmcoYiAqIDAuNSkpOworICAvLyBNdWx0aXBsaWNhdGlvbiBzaG91bGQgbm90IG92ZXJmbG93IGlmIHRoZSByZXN1bHQgZml0cyBpbnRvIHRoZSBzdXBwb3J0ZWQKKyAgLy8gcmFuZ2Ugb2YgRHVyYXRpb24gKGludGVybWVkaWF0ZSByZXN1bHQgbWF5IGJlIGxhcmdlciB0aGFuIGludDY0KS4KKyAgRVhQRUNUX0VRKCIzMTU1NzU5OTk2ODQuNDI0cyIsCisgICAgICAgICAgICBUaW1lVXRpbDo6VG9TdHJpbmcoKG9uZV9zZWNvbmQgLSBvbmVfbmFubykgKiAzMTU1NzYwMDAwMDBMTCkpOworICBFWFBFQ1RfRVEoIi0zMTU1NzU5OTk2ODQuNDI0cyIsCisgICAgICAgICAgICBUaW1lVXRpbDo6VG9TdHJpbmcoKG9uZV9uYW5vIC0gb25lX3NlY29uZCkgKiAzMTU1NzYwMDAwMDBMTCkpOworICBFWFBFQ1RfRVEoIi0zMTU1NzU5OTk2ODQuNDI0cyIsCisgICAgICAgICAgICBUaW1lVXRpbDo6VG9TdHJpbmcoKG9uZV9zZWNvbmQgLSBvbmVfbmFubykgKiAoLTMxNTU3NjAwMDAwMExMKSkpOworCisgIC8vIFRlc3QgLyBhbmQgJQorICBFWFBFQ1RfRVEoIjAuOTk5OTk5OTk5cyIsIFRpbWVVdGlsOjpUb1N0cmluZyhhIC8gMikpOworICBFWFBFQ1RfRVEoIi0wLjk5OTk5OTk5OXMiLCBUaW1lVXRpbDo6VG9TdHJpbmcoYiAvIDIpKTsKKyAgRHVyYXRpb24gbGFyZ2UgPSBUaW1lVXRpbDo6U2Vjb25kc1RvRHVyYXRpb24oMzE1NTc2MDAwMDAwTEwpIC0gb25lX25hbm87CisgIC8vIFdlIGhhdmUgdG8gaGFuZGxlIGRpdmlzaW9uIHdpdGggdmFsdWVzIGJleW9uZCA2NCBiaXRzLgorICBFWFBFQ1RfRVEoIjAuOTk5OTk5OTk5cyIsIFRpbWVVdGlsOjpUb1N0cmluZyhsYXJnZSAvIDMxNTU3NjAwMDAwMExMKSk7CisgIEVYUEVDVF9FUSgiLTAuOTk5OTk5OTk5cyIsIFRpbWVVdGlsOjpUb1N0cmluZygoLWxhcmdlKSAvIDMxNTU3NjAwMDAwMExMKSk7CisgIEVYUEVDVF9FUSgiLTAuOTk5OTk5OTk5cyIsIFRpbWVVdGlsOjpUb1N0cmluZyhsYXJnZSAvICgtMzE1NTc2MDAwMDAwTEwpKSk7CisgIER1cmF0aW9uIGxhcmdlMiA9IGxhcmdlICsgb25lX25hbm87CisgIEVYUEVDVF9FUShsYXJnZSwgbGFyZ2UgJSBsYXJnZTIpOworICBFWFBFQ1RfRVEoLWxhcmdlLCAoLWxhcmdlKSAlIGxhcmdlMik7CisgIEVYUEVDVF9FUShsYXJnZSwgbGFyZ2UgJSAoLWxhcmdlMikpOworICBFWFBFQ1RfRVEob25lX25hbm8sIGxhcmdlMiAlIGxhcmdlKTsKKyAgRVhQRUNUX0VRKC1vbmVfbmFubywgKC1sYXJnZTIpICUgbGFyZ2UpOworICBFWFBFQ1RfRVEob25lX25hbm8sIGxhcmdlMiAlICgtbGFyZ2UpKTsKKyAgLy8gU29tZSBjb3JuZXIgY2FzZXMgYWJvdXQgbmVnYXRpdmUgdmFsdWVzLgorICAvLworICAvLyAoLTUpIC8gMiA9IC0yLCByZW1haW5kZXIgPSAtMQorICAvLyAoLTUpIC8gKC0yKSA9IDIsIHJlbWFpbmRlciA9IC0xCisgIGEgPSBUaW1lVXRpbDo6TmFub3NlY29uZHNUb0R1cmF0aW9uKC01KTsKKyAgRVhQRUNUX0VRKFRpbWVVdGlsOjpOYW5vc2Vjb25kc1RvRHVyYXRpb24oLTIpLCBhIC8gMik7CisgIEVYUEVDVF9FUShUaW1lVXRpbDo6TmFub3NlY29uZHNUb0R1cmF0aW9uKDIpLCBhIC8gKC0yKSk7CisgIGIgPSBUaW1lVXRpbDo6TmFub3NlY29uZHNUb0R1cmF0aW9uKDIpOworICBFWFBFQ1RfRVEoLTIsIGEgLyBiKTsKKyAgRVhQRUNUX0VRKFRpbWVVdGlsOjpOYW5vc2Vjb25kc1RvRHVyYXRpb24oLTEpLCBhICUgYik7CisgIEVYUEVDVF9FUSgyLCBhIC8gKC1iKSk7CisgIEVYUEVDVF9FUShUaW1lVXRpbDo6TmFub3NlY29uZHNUb0R1cmF0aW9uKC0xKSwgYSAlICgtYikpOworCisgIC8vIFRlc3QgcmVsYXRpb25hbCBvcGVyYXRvcnMuCisgIEVYUEVDVF9UUlVFKG9uZV9uYW5vIDwgb25lX3NlY29uZCk7CisgIEVYUEVDVF9GQUxTRShvbmVfc2Vjb25kIDwgb25lX3NlY29uZCk7CisgIEVYUEVDVF9GQUxTRShvbmVfc2Vjb25kIDwgb25lX25hbm8pOworICBFWFBFQ1RfRkFMU0UoLW9uZV9uYW5vIDwgLW9uZV9zZWNvbmQpOworICBFWFBFQ1RfRkFMU0UoLW9uZV9zZWNvbmQgPCAtb25lX3NlY29uZCk7CisgIEVYUEVDVF9UUlVFKC1vbmVfc2Vjb25kIDwgLW9uZV9uYW5vKTsKKyAgRVhQRUNUX1RSVUUoLW9uZV9uYW5vIDwgb25lX25hbm8pOworICBFWFBFQ1RfRkFMU0Uob25lX25hbm8gPCAtb25lX25hbm8pOworCisgIEVYUEVDVF9GQUxTRShvbmVfbmFubyA+IG9uZV9zZWNvbmQpOworICBFWFBFQ1RfRkFMU0Uob25lX25hbm8gPiBvbmVfbmFubyk7CisgIEVYUEVDVF9UUlVFKG9uZV9zZWNvbmQgPiBvbmVfbmFubyk7CisKKyAgRVhQRUNUX0ZBTFNFKG9uZV9uYW5vID49IG9uZV9zZWNvbmQpOworICBFWFBFQ1RfVFJVRShvbmVfbmFubyA+PSBvbmVfbmFubyk7CisgIEVYUEVDVF9UUlVFKG9uZV9zZWNvbmQgPj0gb25lX25hbm8pOworCisgIEVYUEVDVF9UUlVFKG9uZV9uYW5vIDw9IG9uZV9zZWNvbmQpOworICBFWFBFQ1RfVFJVRShvbmVfbmFubyA8PSBvbmVfbmFubyk7CisgIEVYUEVDVF9GQUxTRShvbmVfc2Vjb25kIDw9IG9uZV9uYW5vKTsKKworICBFWFBFQ1RfVFJVRShvbmVfbmFubyA9PSBvbmVfbmFubyk7CisgIEVYUEVDVF9GQUxTRShvbmVfbmFubyA9PSBvbmVfc2Vjb25kKTsKKworICBFWFBFQ1RfRkFMU0Uob25lX25hbm8gIT0gb25lX25hbm8pOworICBFWFBFQ1RfVFJVRShvbmVfbmFubyAhPSBvbmVfc2Vjb25kKTsKK30KKworVEVTVChUaW1lVXRpbFRlc3QsIFRpbWVzdGFtcE9wZXJhdG9ycykgeworICBUaW1lc3RhbXAgYmVnaW4sIGVuZDsKKyAgRVhQRUNUX1RSVUUoVGltZVV0aWw6OkZyb21TdHJpbmcoIjAwMDEtMDEtMDFUMDA6MDA6MDBaIiwgJmJlZ2luKSk7CisgIEVYUEVDVF9UUlVFKFRpbWVVdGlsOjpGcm9tU3RyaW5nKCI5OTk5LTEyLTMxVDIzOjU5OjU5Ljk5OTk5OTk5OVoiLCAmZW5kKSk7CisgIER1cmF0aW9uIGQgPSBlbmQgLSBiZWdpbjsKKyAgRVhQRUNUX1RSVUUoZW5kID09IGJlZ2luICsgZCk7CisgIEVYUEVDVF9UUlVFKGVuZCA9PSBkICsgYmVnaW4pOworICBFWFBFQ1RfVFJVRShiZWdpbiA9PSBlbmQgLSBkKTsKKworICAvLyBUZXN0IHJlbGF0aW9uYWwgb3BlcmF0b3JzCisgIFRpbWVzdGFtcCB0MSA9IGJlZ2luICsgZCAvIDQ7CisgIFRpbWVzdGFtcCB0MiA9IGVuZCAtIGQgLyA0OworICBFWFBFQ1RfVFJVRSh0MSA8IHQyKTsKKyAgRVhQRUNUX0ZBTFNFKHQxIDwgdDEpOworICBFWFBFQ1RfRkFMU0UodDIgPCB0MSk7CisgIEVYUEVDVF9GQUxTRSh0MSA+IHQyKTsKKyAgRVhQRUNUX0ZBTFNFKHQxID4gdDEpOworICBFWFBFQ1RfVFJVRSh0MiA+IHQxKTsKKyAgRVhQRUNUX0ZBTFNFKHQxID49IHQyKTsKKyAgRVhQRUNUX1RSVUUodDEgPj0gdDEpOworICBFWFBFQ1RfVFJVRSh0MiA+PSB0MSk7CisgIEVYUEVDVF9UUlVFKHQxIDw9IHQyKTsKKyAgRVhQRUNUX1RSVUUodDEgPD0gdDEpOworICBFWFBFQ1RfRkFMU0UodDIgPD0gdDEpOworCisgIEVYUEVDVF9GQUxTRSh0MSA9PSB0Mik7CisgIEVYUEVDVF9UUlVFKHQxID09IHQxKTsKKyAgRVhQRUNUX0ZBTFNFKHQyID09IHQxKTsKKyAgRVhQRUNUX1RSVUUodDEgIT0gdDIpOworICBFWFBFQ1RfRkFMU0UodDEgIT0gdDEpOworICBFWFBFQ1RfVFJVRSh0MiAhPSB0MSk7Cit9CisKK30gIC8vIG5hbWVzcGFjZQorfSAgLy8gbmFtZXNwYWNlIHV0aWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL3R5cGVfcmVzb2x2ZXIuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC90eXBlX3Jlc29sdmVyLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzdkNDQxNgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC90eXBlX3Jlc29sdmVyLmgKQEAgLTAsMCArMSw3NSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX1VUSUxfVFlQRV9SRVNPTFZFUl9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1VUSUxfVFlQRV9SRVNPTFZFUl9IX18KKworI2luY2x1ZGUgPHN0cmluZz4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RhdHVzLmg+CisKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworY2xhc3MgVHlwZTsKK2NsYXNzIEVudW07Cit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworCituYW1lc3BhY2UgcHJvdG9idWYgeworY2xhc3MgRGVzY3JpcHRvclBvb2w7CituYW1lc3BhY2UgdXRpbCB7CisKKy8vIEFic3RyYWN0IGludGVyZmFjZSBmb3IgYSB0eXBlIHJlc292bGVyLgorLy8KKy8vIEltcGxlbWVudGF0aW9ucyBvZiB0aGlzIGludGVyZmFjZSBtdXN0IGJlIHRocmVhZC1zYWZlLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFR5cGVSZXNvbHZlciB7CisgcHVibGljOgorICBUeXBlUmVzb2x2ZXIoKSB7fQorICB2aXJ0dWFsIH5UeXBlUmVzb2x2ZXIoKSB7fQorCisgIC8vIFJlc29sdmVzIGEgdHlwZSB1cmwgZm9yIGEgbWVzc2FnZSB0eXBlLgorICB2aXJ0dWFsIHV0aWw6OlN0YXR1cyBSZXNvbHZlTWVzc2FnZVR5cGUoCisgICAgICBjb25zdCBzdHJpbmcmIHR5cGVfdXJsLCBnb29nbGU6OnByb3RvYnVmOjpUeXBlKiBtZXNzYWdlX3R5cGUpID0gMDsKKworICAvLyBSZXNvbHZlcyBhIHR5cGUgdXJsIGZvciBhbiBlbnVtIHR5cGUuCisgIHZpcnR1YWwgdXRpbDo6U3RhdHVzIFJlc29sdmVFbnVtVHlwZShjb25zdCBzdHJpbmcmIHR5cGVfdXJsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnb29nbGU6OnByb3RvYnVmOjpFbnVtKiBlbnVtX3R5cGUpID0gMDsKKworIHByaXZhdGU6CisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhUeXBlUmVzb2x2ZXIpOworfTsKKworfSAgLy8gbmFtZXNwYWNlIHV0aWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9VVElMX1RZUEVfUkVTT0xWRVJfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvdHlwZV9yZXNvbHZlcl91dGlsLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL3R5cGVfcmVzb2x2ZXJfdXRpbC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NjM5MzkwCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL3R5cGVfcmVzb2x2ZXJfdXRpbC5jYwpAQCAtMCwwICsxLDI1OSBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC90eXBlX3Jlc29sdmVyX3V0aWwuaD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90eXBlLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dyYXBwZXJzLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2ludGVybmFsL3V0aWxpdHkuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdXRpbC90eXBlX3Jlc29sdmVyLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3N0cnV0aWwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RhdHVzLmg+CisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSB1dGlsIHsKK25hbWVzcGFjZSB7Cit1c2luZyBnb29nbGU6OnByb3RvYnVmOjpCb29sVmFsdWU7Cit1c2luZyBnb29nbGU6OnByb3RvYnVmOjpFbnVtOwordXNpbmcgZ29vZ2xlOjpwcm90b2J1Zjo6RW51bVZhbHVlOwordXNpbmcgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGQ7Cit1c2luZyBnb29nbGU6OnByb3RvYnVmOjpPcHRpb247Cit1c2luZyBnb29nbGU6OnByb3RvYnVmOjpUeXBlOworCit1c2luZyB1dGlsOjpTdGF0dXM7Cit1c2luZyB1dGlsOjplcnJvcjo6SU5WQUxJRF9BUkdVTUVOVDsKK3VzaW5nIHV0aWw6OmVycm9yOjpOT1RfRk9VTkQ7CisKK2Jvb2wgU3BsaXRUeXBlVXJsKGNvbnN0IHN0cmluZyYgdHlwZV91cmwsIHN0cmluZyogdXJsX3ByZWZpeCwKKyAgICAgICAgICAgICAgICAgIHN0cmluZyogbWVzc2FnZV9uYW1lKSB7CisgIHNpemVfdCBwb3MgPSB0eXBlX3VybC5maW5kX2xhc3Rfb2YoIi8iKTsKKyAgaWYgKHBvcyA9PSBzdHJpbmc6Om5wb3MpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgKnVybF9wcmVmaXggPSB0eXBlX3VybC5zdWJzdHIoMCwgcG9zKTsKKyAgKm1lc3NhZ2VfbmFtZSA9IHR5cGVfdXJsLnN1YnN0cihwb3MgKyAxKTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK2NsYXNzIERlc2NyaXB0b3JQb29sVHlwZVJlc29sdmVyIDogcHVibGljIFR5cGVSZXNvbHZlciB7CisgcHVibGljOgorICBEZXNjcmlwdG9yUG9vbFR5cGVSZXNvbHZlcihjb25zdCBzdHJpbmcmIHVybF9wcmVmaXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlc2NyaXB0b3JQb29sKiBwb29sKQorICAgICAgOiB1cmxfcHJlZml4Xyh1cmxfcHJlZml4KSwgcG9vbF8ocG9vbCkge30KKworICBTdGF0dXMgUmVzb2x2ZU1lc3NhZ2VUeXBlKGNvbnN0IHN0cmluZyYgdHlwZV91cmwsIFR5cGUqIHR5cGUpIHsKKyAgICBzdHJpbmcgdXJsX3ByZWZpeCwgbWVzc2FnZV9uYW1lOworICAgIGlmICghU3BsaXRUeXBlVXJsKHR5cGVfdXJsLCAmdXJsX3ByZWZpeCwgJm1lc3NhZ2VfbmFtZSkgfHwKKyAgICAgICAgdXJsX3ByZWZpeCAhPSB1cmxfcHJlZml4XykgeworICAgICAgcmV0dXJuIFN0YXR1cyhJTlZBTElEX0FSR1VNRU5ULAorICAgICAgICAgICAgICAgICAgICBTdHJDYXQoIkludmFsaWQgdHlwZSBVUkwsIHR5cGUgVVJMcyBtdXN0IGJlIG9mIHRoZSBmb3JtICciLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgdXJsX3ByZWZpeF8sICIvPHR5cGVuYW1lPicsIGdvdDogIiwgdHlwZV91cmwpKTsKKyAgICB9CisgICAgaWYgKHVybF9wcmVmaXggIT0gdXJsX3ByZWZpeF8pIHsKKyAgICAgIHJldHVybiBTdGF0dXMoSU5WQUxJRF9BUkdVTUVOVCwKKyAgICAgICAgICAgICAgICAgICAgIkNhbm5vdCByZXNvbHZlIHR5cGVzIGZyb20gVVJMOiAiICsgdXJsX3ByZWZpeCk7CisgICAgfQorICAgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBwb29sXy0+RmluZE1lc3NhZ2VUeXBlQnlOYW1lKG1lc3NhZ2VfbmFtZSk7CisgICAgaWYgKGRlc2NyaXB0b3IgPT0gTlVMTCkgeworICAgICAgcmV0dXJuIFN0YXR1cyhOT1RfRk9VTkQsCisgICAgICAgICAgICAgICAgICAgICJJbnZhbGlkIHR5cGUgVVJMLCB1bmtub3duIHR5cGU6ICIgKyBtZXNzYWdlX25hbWUpOworICAgIH0KKyAgICBDb252ZXJ0RGVzY3JpcHRvcihkZXNjcmlwdG9yLCB0eXBlKTsKKyAgICByZXR1cm4gU3RhdHVzKCk7CisgIH0KKworICBTdGF0dXMgUmVzb2x2ZUVudW1UeXBlKGNvbnN0IHN0cmluZyYgdHlwZV91cmwsIEVudW0qIGVudW1fdHlwZSkgeworICAgIHN0cmluZyB1cmxfcHJlZml4LCB0eXBlX25hbWU7CisgICAgaWYgKCFTcGxpdFR5cGVVcmwodHlwZV91cmwsICZ1cmxfcHJlZml4LCAmdHlwZV9uYW1lKSB8fAorICAgICAgICB1cmxfcHJlZml4ICE9IHVybF9wcmVmaXhfKSB7CisgICAgICByZXR1cm4gU3RhdHVzKElOVkFMSURfQVJHVU1FTlQsCisgICAgICAgICAgICAgICAgICAgIFN0ckNhdCgiSW52YWxpZCB0eXBlIFVSTCwgdHlwZSBVUkxzIG11c3QgYmUgb2YgdGhlIGZvcm0gJyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICB1cmxfcHJlZml4XywgIi88dHlwZW5hbWU+JywgZ290OiAiLCB0eXBlX3VybCkpOworICAgIH0KKyAgICBpZiAodXJsX3ByZWZpeCAhPSB1cmxfcHJlZml4XykgeworICAgICAgcmV0dXJuIFN0YXR1cyhJTlZBTElEX0FSR1VNRU5ULAorICAgICAgICAgICAgICAgICAgICAiQ2Fubm90IHJlc29sdmUgdHlwZXMgZnJvbSBVUkw6ICIgKyB1cmxfcHJlZml4KTsKKyAgICB9CisgICAgY29uc3QgRW51bURlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBwb29sXy0+RmluZEVudW1UeXBlQnlOYW1lKHR5cGVfbmFtZSk7CisgICAgaWYgKGRlc2NyaXB0b3IgPT0gTlVMTCkgeworICAgICAgcmV0dXJuIFN0YXR1cyhOT1RfRk9VTkQsICJJbnZhbGlkIHR5cGUgVVJMLCB1bmtub3duIHR5cGU6ICIgKyB0eXBlX25hbWUpOworICAgIH0KKyAgICBDb252ZXJ0RW51bURlc2NyaXB0b3IoZGVzY3JpcHRvciwgZW51bV90eXBlKTsKKyAgICByZXR1cm4gU3RhdHVzKCk7CisgIH0KKworIHByaXZhdGU6CisgIHZvaWQgQ29udmVydERlc2NyaXB0b3IoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciwgVHlwZSogdHlwZSkgeworICAgIHR5cGUtPkNsZWFyKCk7CisgICAgdHlwZS0+c2V0X25hbWUoZGVzY3JpcHRvci0+ZnVsbF9uYW1lKCkpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvci0+ZmllbGRfY291bnQoKTsgKytpKSB7CisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gZGVzY3JpcHRvci0+ZmllbGQoaSk7CisgICAgICBpZiAoZmllbGQtPnR5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfR1JPVVApIHsKKyAgICAgICAgLy8gR3JvdXAgZmllbGRzIGNhbm5vdCBiZSByZXByZXNlbnRlZCB3aXRoIFR5cGUuIFdlIGRpc2NhcmQgdGhlbS4KKyAgICAgICAgY29udGludWU7CisgICAgICB9CisgICAgICBDb252ZXJ0RmllbGREZXNjcmlwdG9yKGRlc2NyaXB0b3ItPmZpZWxkKGkpLCB0eXBlLT5hZGRfZmllbGRzKCkpOworICAgIH0KKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGRlc2NyaXB0b3ItPm9uZW9mX2RlY2xfY291bnQoKTsgKytpKSB7CisgICAgICB0eXBlLT5hZGRfb25lb2ZzKGRlc2NyaXB0b3ItPm9uZW9mX2RlY2woaSktPm5hbWUoKSk7CisgICAgfQorICAgIHR5cGUtPm11dGFibGVfc291cmNlX2NvbnRleHQoKS0+c2V0X2ZpbGVfbmFtZShkZXNjcmlwdG9yLT5maWxlKCktPm5hbWUoKSk7CisgICAgQ29udmVydE1lc3NhZ2VPcHRpb25zKGRlc2NyaXB0b3ItPm9wdGlvbnMoKSwgdHlwZS0+bXV0YWJsZV9vcHRpb25zKCkpOworICB9CisKKyAgdm9pZCBDb252ZXJ0TWVzc2FnZU9wdGlvbnMoY29uc3QgTWVzc2FnZU9wdGlvbnMmIG9wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlcGVhdGVkUHRyRmllbGQ8T3B0aW9uPiogb3V0cHV0KSB7CisgICAgaWYgKG9wdGlvbnMubWFwX2VudHJ5KCkpIHsKKyAgICAgIE9wdGlvbiogb3B0aW9uID0gb3V0cHV0LT5BZGQoKTsKKyAgICAgIG9wdGlvbi0+c2V0X25hbWUoIm1hcF9lbnRyeSIpOworICAgICAgQm9vbFZhbHVlIHZhbHVlOworICAgICAgdmFsdWUuc2V0X3ZhbHVlKHRydWUpOworICAgICAgb3B0aW9uLT5tdXRhYmxlX3ZhbHVlKCktPlBhY2tGcm9tKHZhbHVlKTsKKyAgICB9CisKKyAgICAvLyBUT0RPKHhpYW9mZW5nKTogU2V0IG90aGVyICJvcHRpb25zIj8KKyAgfQorCisgIHZvaWQgQ29udmVydEZpZWxkRGVzY3JpcHRvcihjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IsIEZpZWxkKiBmaWVsZCkgeworICAgIGZpZWxkLT5zZXRfa2luZChzdGF0aWNfY2FzdDxGaWVsZDo6S2luZD4oZGVzY3JpcHRvci0+dHlwZSgpKSk7CisgICAgc3dpdGNoIChkZXNjcmlwdG9yLT5sYWJlbCgpKSB7CisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6TEFCRUxfT1BUSU9OQUw6CisgICAgICAgIGZpZWxkLT5zZXRfY2FyZGluYWxpdHkoRmllbGQ6OkNBUkRJTkFMSVRZX09QVElPTkFMKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6TEFCRUxfUkVQRUFURUQ6CisgICAgICAgIGZpZWxkLT5zZXRfY2FyZGluYWxpdHkoRmllbGQ6OkNBUkRJTkFMSVRZX1JFUEVBVEVEKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6TEFCRUxfUkVRVUlSRUQ6CisgICAgICAgIGZpZWxkLT5zZXRfY2FyZGluYWxpdHkoRmllbGQ6OkNBUkRJTkFMSVRZX1JFUVVJUkVEKTsKKyAgICAgICAgYnJlYWs7CisgICAgfQorICAgIGZpZWxkLT5zZXRfbnVtYmVyKGRlc2NyaXB0b3ItPm51bWJlcigpKTsKKyAgICBmaWVsZC0+c2V0X25hbWUoZGVzY3JpcHRvci0+bmFtZSgpKTsKKyAgICBmaWVsZC0+c2V0X2pzb25fbmFtZShkZXNjcmlwdG9yLT5qc29uX25hbWUoKSk7CisgICAgaWYgKGRlc2NyaXB0b3ItPmhhc19kZWZhdWx0X3ZhbHVlKCkpIHsKKyAgICAgIGZpZWxkLT5zZXRfZGVmYXVsdF92YWx1ZShEZWZhdWx0VmFsdWVBc1N0cmluZyhkZXNjcmlwdG9yKSk7CisgICAgfQorICAgIGlmIChkZXNjcmlwdG9yLT50eXBlKCkgPT0gRmllbGREZXNjcmlwdG9yOjpUWVBFX01FU1NBR0UpIHsKKyAgICAgIGZpZWxkLT5zZXRfdHlwZV91cmwoR2V0VHlwZVVybChkZXNjcmlwdG9yLT5tZXNzYWdlX3R5cGUoKSkpOworICAgIH0gZWxzZSBpZiAoZGVzY3JpcHRvci0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9FTlVNKSB7CisgICAgICBmaWVsZC0+c2V0X3R5cGVfdXJsKEdldFR5cGVVcmwoZGVzY3JpcHRvci0+ZW51bV90eXBlKCkpKTsKKyAgICB9CisgICAgaWYgKGRlc2NyaXB0b3ItPmNvbnRhaW5pbmdfb25lb2YoKSAhPSBOVUxMKSB7CisgICAgICBmaWVsZC0+c2V0X29uZW9mX2luZGV4KGRlc2NyaXB0b3ItPmNvbnRhaW5pbmdfb25lb2YoKS0+aW5kZXgoKSArIDEpOworICAgIH0KKyAgICBpZiAoZGVzY3JpcHRvci0+aXNfcGFja2VkKCkpIHsKKyAgICAgIGZpZWxkLT5zZXRfcGFja2VkKHRydWUpOworICAgIH0KKworICAgIC8vIFRPRE8oeGlhb2ZlbmcpOiBTZXQgb3RoZXIgZmllbGQgIm9wdGlvbnMiPworICB9CisKKyAgdm9pZCBDb252ZXJ0RW51bURlc2NyaXB0b3IoY29uc3QgRW51bURlc2NyaXB0b3IqIGRlc2NyaXB0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVudW0qIGVudW1fdHlwZSkgeworICAgIGVudW1fdHlwZS0+Q2xlYXIoKTsKKyAgICBlbnVtX3R5cGUtPnNldF9uYW1lKGRlc2NyaXB0b3ItPmZ1bGxfbmFtZSgpKTsKKyAgICBlbnVtX3R5cGUtPm11dGFibGVfc291cmNlX2NvbnRleHQoKS0+c2V0X2ZpbGVfbmFtZSgKKyAgICAgICAgZGVzY3JpcHRvci0+ZmlsZSgpLT5uYW1lKCkpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVzY3JpcHRvci0+dmFsdWVfY291bnQoKTsgKytpKSB7CisgICAgICBjb25zdCBFbnVtVmFsdWVEZXNjcmlwdG9yKiB2YWx1ZV9kZXNjcmlwdG9yID0gZGVzY3JpcHRvci0+dmFsdWUoaSk7CisgICAgICBFbnVtVmFsdWUqIHZhbHVlID0gZW51bV90eXBlLT5tdXRhYmxlX2VudW12YWx1ZSgpLT5BZGQoKTsKKyAgICAgIHZhbHVlLT5zZXRfbmFtZSh2YWx1ZV9kZXNjcmlwdG9yLT5uYW1lKCkpOworICAgICAgdmFsdWUtPnNldF9udW1iZXIodmFsdWVfZGVzY3JpcHRvci0+bnVtYmVyKCkpOworCisgICAgICAvLyBUT0RPKHhpYW9mZW5nKTogU2V0IEVudW1WYWx1ZSBvcHRpb25zLgorICAgIH0KKyAgICAvLyBUT0RPKHhpYW9mZW5nKTogU2V0IEVudW0gIm9wdGlvbnMiLgorICB9CisKKyAgc3RyaW5nIEdldFR5cGVVcmwoY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvcikgeworICAgIHJldHVybiB1cmxfcHJlZml4XyArICIvIiArIGRlc2NyaXB0b3ItPmZ1bGxfbmFtZSgpOworICB9CisKKyAgc3RyaW5nIEdldFR5cGVVcmwoY29uc3QgRW51bURlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgICByZXR1cm4gdXJsX3ByZWZpeF8gKyAiLyIgKyBkZXNjcmlwdG9yLT5mdWxsX25hbWUoKTsKKyAgfQorCisgIHN0cmluZyBEZWZhdWx0VmFsdWVBc1N0cmluZyhjb25zdCBGaWVsZERlc2NyaXB0b3IqIGRlc2NyaXB0b3IpIHsKKyAgICBzd2l0Y2ggKGRlc2NyaXB0b3ItPmNwcF90eXBlKCkpIHsKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0lOVDMyOgorICAgICAgICByZXR1cm4gU2ltcGxlSXRvYShkZXNjcmlwdG9yLT5kZWZhdWx0X3ZhbHVlX2ludDMyKCkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0lOVDY0OgorICAgICAgICByZXR1cm4gU2ltcGxlSXRvYShkZXNjcmlwdG9yLT5kZWZhdWx0X3ZhbHVlX2ludDY0KCkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX1VJTlQzMjoKKyAgICAgICAgcmV0dXJuIFNpbXBsZUl0b2EoZGVzY3JpcHRvci0+ZGVmYXVsdF92YWx1ZV91aW50MzIoKSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfVUlOVDY0OgorICAgICAgICByZXR1cm4gU2ltcGxlSXRvYShkZXNjcmlwdG9yLT5kZWZhdWx0X3ZhbHVlX3VpbnQ2NCgpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9GTE9BVDoKKyAgICAgICAgcmV0dXJuIFNpbXBsZUZ0b2EoZGVzY3JpcHRvci0+ZGVmYXVsdF92YWx1ZV9mbG9hdCgpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9ET1VCTEU6CisgICAgICAgIHJldHVybiBTaW1wbGVEdG9hKGRlc2NyaXB0b3ItPmRlZmF1bHRfdmFsdWVfZG91YmxlKCkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpDUFBUWVBFX0JPT0w6CisgICAgICAgIHJldHVybiBkZXNjcmlwdG9yLT5kZWZhdWx0X3ZhbHVlX2Jvb2woKSA/ICJ0cnVlIiA6ICJmYWxzZSI7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfU1RSSU5HOgorICAgICAgICBpZiAoZGVzY3JpcHRvci0+dHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9CWVRFUykgeworICAgICAgICAgIHJldHVybiBDRXNjYXBlKGRlc2NyaXB0b3ItPmRlZmF1bHRfdmFsdWVfc3RyaW5nKCkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHJldHVybiBkZXNjcmlwdG9yLT5kZWZhdWx0X3ZhbHVlX3N0cmluZygpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfRU5VTToKKyAgICAgICAgcmV0dXJuIGRlc2NyaXB0b3ItPmRlZmF1bHRfdmFsdWVfZW51bSgpLT5uYW1lKCk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRToKKyAgICAgICAgR09PR0xFX0xPRyhERkFUQUwpIDw8ICJNZXNzYWdlcyBjYW4ndCBoYXZlIGRlZmF1bHQgdmFsdWVzISI7CisgICAgICAgIGJyZWFrOworICAgIH0KKyAgICByZXR1cm4gIiI7CisgIH0KKworICBzdHJpbmcgdXJsX3ByZWZpeF87CisgIGNvbnN0IERlc2NyaXB0b3JQb29sKiBwb29sXzsKK307CisKK30gIC8vIG5hbWVzcGFjZQorCitUeXBlUmVzb2x2ZXIqIE5ld1R5cGVSZXNvbHZlckZvckRlc2NyaXB0b3JQb29sKGNvbnN0IHN0cmluZyYgdXJsX3ByZWZpeCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVzY3JpcHRvclBvb2wqIHBvb2wpIHsKKyAgcmV0dXJuIG5ldyBEZXNjcmlwdG9yUG9vbFR5cGVSZXNvbHZlcih1cmxfcHJlZml4LCBwb29sKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIHV0aWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL3R5cGVfcmVzb2x2ZXJfdXRpbC5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL3R5cGVfcmVzb2x2ZXJfdXRpbC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMwZWYzYzEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3V0aWwvdHlwZV9yZXNvbHZlcl91dGlsLmgKQEAgLTAsMCArMSw1MiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX1VUSUxfVFlQRV9SRVNPTFZFUl9VVElMX0hfXworI2RlZmluZSBHT09HTEVfUFJPVE9CVUZfVVRJTF9UWVBFX1JFU09MVkVSX1VUSUxfSF9fCisKKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CitjbGFzcyBEZXNjcmlwdG9yUG9vbDsKK25hbWVzcGFjZSB1dGlsIHsKK2NsYXNzIFR5cGVSZXNvbHZlcjsKKworLy8gQ3JlYXRlcyBhIFR5cGVSZXNvbHZlciB0aGF0IHNlcnZlcyB0eXBlIGluZm9ybWF0aW9uIGluIHRoZSBnaXZlbiBkZXNjcmlwdG9yCisvLyBwb29sLiBDYWxsZXIgdGFrZXMgb3duZXJzaGlwIG9mIHRoZSByZXR1cm5lZCBUeXBlUmVzb2x2ZXIuCitMSUJQUk9UT0JVRl9FWFBPUlQgVHlwZVJlc29sdmVyKiBOZXdUeXBlUmVzb2x2ZXJGb3JEZXNjcmlwdG9yUG9vbCgKKyAgICBjb25zdCBzdHJpbmcmIHVybF9wcmVmaXgsIGNvbnN0IERlc2NyaXB0b3JQb29sKiBwb29sKTsKKworfSAgLy8gbmFtZXNwYWNlIHV0aWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9VVElMX1RZUEVfUkVTT0xWRVJfVVRJTF9IX18KZGlmZiAtLWdpdCBhL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC90eXBlX3Jlc29sdmVyX3V0aWxfdGVzdC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvdXRpbC90eXBlX3Jlc29sdmVyX3V0aWxfdGVzdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YTBiZjY1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi91dGlsL3R5cGVfcmVzb2x2ZXJfdXRpbF90ZXN0LmNjCkBAIC0wLDAgKzEsMzUyIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL3R5cGVfcmVzb2x2ZXJfdXRpbC5oPgorCisjaW5jbHVkZSA8bGltaXRzPgorI2luY2x1ZGUgPG1lbW9yeT4KKyNpZm5kZWYgX1NIQVJFRF9QVFJfSAorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zaGFyZWRfcHRyLmg+CisjZW5kaWYKKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8dmVjdG9yPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3R5cGUucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd3JhcHBlcnMucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWFwX3VuaXR0ZXN0LnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3Rlc3RfdXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL2pzb25fZm9ybWF0X3Byb3RvMy5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91dGlsL3R5cGVfcmVzb2x2ZXIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0Lmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIHV0aWwgeworbmFtZXNwYWNlIHsKK3VzaW5nIGdvb2dsZTo6cHJvdG9idWY6OlR5cGU7Cit1c2luZyBnb29nbGU6OnByb3RvYnVmOjpFbnVtOwordXNpbmcgZ29vZ2xlOjpwcm90b2J1Zjo6RmllbGQ7Cit1c2luZyBnb29nbGU6OnByb3RvYnVmOjpPcHRpb247Cit1c2luZyBnb29nbGU6OnByb3RvYnVmOjpCb29sVmFsdWU7CisKK3N0YXRpYyBjb25zdCBjaGFyIGtVcmxQcmVmaXhbXSA9ICJ0eXBlLmdvb2dsZWFwaXMuY29tIjsKKworY2xhc3MgRGVzY3JpcHRvclBvb2xUeXBlUmVzb2x2ZXJUZXN0IDogcHVibGljIHRlc3Rpbmc6OlRlc3QgeworIHB1YmxpYzoKKyAgRGVzY3JpcHRvclBvb2xUeXBlUmVzb2x2ZXJUZXN0KCkgeworICAgIHJlc29sdmVyXy5yZXNldChOZXdUeXBlUmVzb2x2ZXJGb3JEZXNjcmlwdG9yUG9vbCgKKyAgICAgICAga1VybFByZWZpeCwgRGVzY3JpcHRvclBvb2w6OmdlbmVyYXRlZF9wb29sKCkpKTsKKyAgfQorCisgIGNvbnN0IEZpZWxkKiBGaW5kRmllbGQoY29uc3QgVHlwZSYgdHlwZSwgY29uc3Qgc3RyaW5nJiBuYW1lKSB7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0eXBlLmZpZWxkc19zaXplKCk7ICsraSkgeworICAgICAgY29uc3QgRmllbGQmIGZpZWxkID0gdHlwZS5maWVsZHMoaSk7CisgICAgICBpZiAoZmllbGQubmFtZSgpID09IG5hbWUpIHsKKyAgICAgICAgcmV0dXJuICZmaWVsZDsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIE5VTEw7CisgIH0KKworICBib29sIEhhc0ZpZWxkKGNvbnN0IFR5cGUmIHR5cGUsIGNvbnN0IHN0cmluZyYgbmFtZSkgeworICAgIHJldHVybiBGaW5kRmllbGQodHlwZSwgbmFtZSkgIT0gTlVMTDsKKyAgfQorCisgIGJvb2wgSGFzRmllbGQoY29uc3QgVHlwZSYgdHlwZSwgRmllbGQ6OkNhcmRpbmFsaXR5IGNhcmRpbmFsaXR5LAorICAgICAgICAgICAgICAgIEZpZWxkOjpLaW5kIGtpbmQsIGNvbnN0IHN0cmluZyYgbmFtZSwgaW50IG51bWJlcikgeworICAgIGNvbnN0IEZpZWxkKiBmaWVsZCA9IEZpbmRGaWVsZCh0eXBlLCBuYW1lKTsKKyAgICBpZiAoZmllbGQgPT0gTlVMTCkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICByZXR1cm4gZmllbGQtPmNhcmRpbmFsaXR5KCkgPT0gY2FyZGluYWxpdHkgJiYKKyAgICAgICAgZmllbGQtPmtpbmQoKSA9PSBraW5kICYmIGZpZWxkLT5udW1iZXIoKSA9PSBudW1iZXI7CisgIH0KKworICBib29sIENoZWNrRmllbGRUeXBlVXJsKGNvbnN0IFR5cGUmIHR5cGUsIGNvbnN0IHN0cmluZyYgbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIHR5cGVfdXJsKSB7CisgICAgY29uc3QgRmllbGQqIGZpZWxkID0gRmluZEZpZWxkKHR5cGUsIG5hbWUpOworICAgIGlmIChmaWVsZCA9PSBOVUxMKSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIHJldHVybiBmaWVsZC0+dHlwZV91cmwoKSA9PSB0eXBlX3VybDsKKyAgfQorCisgIGJvb2wgRmllbGRJbk9uZW9mKGNvbnN0IFR5cGUmIHR5cGUsIGNvbnN0IHN0cmluZyYgbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiBvbmVvZl9uYW1lKSB7CisgICAgY29uc3QgRmllbGQqIGZpZWxkID0gRmluZEZpZWxkKHR5cGUsIG5hbWUpOworICAgIGlmIChmaWVsZCA9PSBOVUxMIHx8IGZpZWxkLT5vbmVvZl9pbmRleCgpIDw9IDAgfHwKKyAgICAgICAgZmllbGQtPm9uZW9mX2luZGV4KCkgPiB0eXBlLm9uZW9mc19zaXplKCkpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgcmV0dXJuIHR5cGUub25lb2ZzKGZpZWxkLT5vbmVvZl9pbmRleCgpIC0gMSkgPT0gb25lb2ZfbmFtZTsKKyAgfQorCisgIGJvb2wgSXNQYWNrZWQoY29uc3QgVHlwZSYgdHlwZSwgY29uc3Qgc3RyaW5nJiBuYW1lKSB7CisgICAgY29uc3QgRmllbGQqIGZpZWxkID0gRmluZEZpZWxkKHR5cGUsIG5hbWUpOworICAgIGlmIChmaWVsZCA9PSBOVUxMKSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIHJldHVybiBmaWVsZC0+cGFja2VkKCk7CisgIH0KKworICBib29sIEVudW1IYXNWYWx1ZShjb25zdCBFbnVtJiB0eXBlLCBjb25zdCBzdHJpbmcmIG5hbWUsIGludCBudW1iZXIpIHsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHR5cGUuZW51bXZhbHVlX3NpemUoKTsgKytpKSB7CisgICAgICBpZiAodHlwZS5lbnVtdmFsdWUoaSkubmFtZSgpID09IG5hbWUgJiYKKyAgICAgICAgICB0eXBlLmVudW12YWx1ZShpKS5udW1iZXIoKSA9PSBudW1iZXIpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIGJvb2wgSGFzQm9vbE9wdGlvbihjb25zdCBSZXBlYXRlZFB0ckZpZWxkPE9wdGlvbj4mIG9wdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcmIG5hbWUsIGJvb2wgdmFsdWUpIHsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IG9wdGlvbnMuc2l6ZSgpOyArK2kpIHsKKyAgICAgIGNvbnN0IE9wdGlvbiYgb3B0aW9uID0gb3B0aW9ucy5HZXQoaSk7CisgICAgICBpZiAob3B0aW9uLm5hbWUoKSA9PSBuYW1lKSB7CisgICAgICAgIEJvb2xWYWx1ZSBib29sX3ZhbHVlOworICAgICAgICBpZiAob3B0aW9uLnZhbHVlKCkuVW5wYWNrVG8oJmJvb2xfdmFsdWUpICYmCisgICAgICAgICAgICBib29sX3ZhbHVlLnZhbHVlKCkgPT0gdmFsdWUpIHsKKyAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBzdHJpbmcgR2V0VHlwZVVybChzdHJpbmcgZnVsbF9uYW1lKSB7CisgICAgcmV0dXJuIGtVcmxQcmVmaXggKyBzdHJpbmcoIi8iKSArIGZ1bGxfbmFtZTsKKyAgfQorCisgIHRlbXBsYXRlPHR5cGVuYW1lIFQ+CisgIHN0cmluZyBHZXRUeXBlVXJsKCkgeworICAgIHJldHVybiBHZXRUeXBlVXJsKFQ6OmRlc2NyaXB0b3IoKS0+ZnVsbF9uYW1lKCkpOworICB9CisKKyBwcm90ZWN0ZWQ6CisgIGdvb2dsZTo6cHJvdG9idWY6OnNjb3BlZF9wdHI8VHlwZVJlc29sdmVyPiByZXNvbHZlcl87Cit9OworCitURVNUX0YoRGVzY3JpcHRvclBvb2xUeXBlUmVzb2x2ZXJUZXN0LCBUZXN0QWxsVHlwZXMpIHsKKyAgVHlwZSB0eXBlOworICBBU1NFUlRfVFJVRShyZXNvbHZlcl8tPlJlc29sdmVNZXNzYWdlVHlwZSgKKyAgICAgIEdldFR5cGVVcmw8cHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RBbGxUeXBlcz4oKSwgJnR5cGUpLm9rKCkpOworICAvLyBDaGVjayBhbGwgb3B0aW9uYWwgZmllbGRzLgorICBFWFBFQ1RfVFJVRShIYXNGaWVsZCh0eXBlLCBGaWVsZDo6Q0FSRElOQUxJVFlfT1BUSU9OQUwsCisgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkOjpUWVBFX0lOVDMyLCAib3B0aW9uYWxfaW50MzIiLCAxKSk7CisgIEVYUEVDVF9UUlVFKEhhc0ZpZWxkKHR5cGUsIEZpZWxkOjpDQVJESU5BTElUWV9PUFRJT05BTCwKKyAgICAgICAgICAgICAgICAgICAgICAgRmllbGQ6OlRZUEVfSU5UNjQsICJvcHRpb25hbF9pbnQ2NCIsIDIpKTsKKyAgRVhQRUNUX1RSVUUoSGFzRmllbGQodHlwZSwgRmllbGQ6OkNBUkRJTkFMSVRZX09QVElPTkFMLAorICAgICAgICAgICAgICAgICAgICAgICBGaWVsZDo6VFlQRV9VSU5UMzIsICJvcHRpb25hbF91aW50MzIiLCAzKSk7CisgIEVYUEVDVF9UUlVFKEhhc0ZpZWxkKHR5cGUsIEZpZWxkOjpDQVJESU5BTElUWV9PUFRJT05BTCwKKyAgICAgICAgICAgICAgICAgICAgICAgRmllbGQ6OlRZUEVfVUlOVDY0LCAib3B0aW9uYWxfdWludDY0IiwgNCkpOworICBFWFBFQ1RfVFJVRShIYXNGaWVsZCh0eXBlLCBGaWVsZDo6Q0FSRElOQUxJVFlfT1BUSU9OQUwsCisgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkOjpUWVBFX1NJTlQzMiwgIm9wdGlvbmFsX3NpbnQzMiIsIDUpKTsKKyAgRVhQRUNUX1RSVUUoSGFzRmllbGQodHlwZSwgRmllbGQ6OkNBUkRJTkFMSVRZX09QVElPTkFMLAorICAgICAgICAgICAgICAgICAgICAgICBGaWVsZDo6VFlQRV9TSU5UNjQsICJvcHRpb25hbF9zaW50NjQiLCA2KSk7CisgIEVYUEVDVF9UUlVFKEhhc0ZpZWxkKHR5cGUsIEZpZWxkOjpDQVJESU5BTElUWV9PUFRJT05BTCwKKyAgICAgICAgICAgICAgICAgICAgICAgRmllbGQ6OlRZUEVfRklYRUQzMiwgIm9wdGlvbmFsX2ZpeGVkMzIiLCA3KSk7CisgIEVYUEVDVF9UUlVFKEhhc0ZpZWxkKHR5cGUsIEZpZWxkOjpDQVJESU5BTElUWV9PUFRJT05BTCwKKyAgICAgICAgICAgICAgICAgICAgICAgRmllbGQ6OlRZUEVfRklYRUQ2NCwgIm9wdGlvbmFsX2ZpeGVkNjQiLCA4KSk7CisgIEVYUEVDVF9UUlVFKEhhc0ZpZWxkKHR5cGUsIEZpZWxkOjpDQVJESU5BTElUWV9PUFRJT05BTCwKKyAgICAgICAgICAgICAgICAgICAgICAgRmllbGQ6OlRZUEVfU0ZJWEVEMzIsICJvcHRpb25hbF9zZml4ZWQzMiIsIDkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzRmllbGQodHlwZSwgRmllbGQ6OkNBUkRJTkFMSVRZX09QVElPTkFMLAorICAgICAgICAgICAgICAgICAgICAgICBGaWVsZDo6VFlQRV9TRklYRUQ2NCwgIm9wdGlvbmFsX3NmaXhlZDY0IiwgMTApKTsKKyAgRVhQRUNUX1RSVUUoSGFzRmllbGQodHlwZSwgRmllbGQ6OkNBUkRJTkFMSVRZX09QVElPTkFMLAorICAgICAgICAgICAgICAgICAgICAgICBGaWVsZDo6VFlQRV9GTE9BVCwgIm9wdGlvbmFsX2Zsb2F0IiwgMTEpKTsKKyAgRVhQRUNUX1RSVUUoSGFzRmllbGQodHlwZSwgRmllbGQ6OkNBUkRJTkFMSVRZX09QVElPTkFMLAorICAgICAgICAgICAgICAgICAgICAgICBGaWVsZDo6VFlQRV9ET1VCTEUsICJvcHRpb25hbF9kb3VibGUiLCAxMikpOworICBFWFBFQ1RfVFJVRShIYXNGaWVsZCh0eXBlLCBGaWVsZDo6Q0FSRElOQUxJVFlfT1BUSU9OQUwsCisgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkOjpUWVBFX0JPT0wsICJvcHRpb25hbF9ib29sIiwgMTMpKTsKKyAgRVhQRUNUX1RSVUUoSGFzRmllbGQodHlwZSwgRmllbGQ6OkNBUkRJTkFMSVRZX09QVElPTkFMLAorICAgICAgICAgICAgICAgICAgICAgICBGaWVsZDo6VFlQRV9TVFJJTkcsICJvcHRpb25hbF9zdHJpbmciLCAxNCkpOworICBFWFBFQ1RfVFJVRShIYXNGaWVsZCh0eXBlLCBGaWVsZDo6Q0FSRElOQUxJVFlfT1BUSU9OQUwsCisgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkOjpUWVBFX0JZVEVTLCAib3B0aW9uYWxfYnl0ZXMiLCAxNSkpOworCisgIEVYUEVDVF9UUlVFKEhhc0ZpZWxkKHR5cGUsIEZpZWxkOjpDQVJESU5BTElUWV9PUFRJT05BTCwKKyAgICAgICAgICAgICAgICAgICAgICAgRmllbGQ6OlRZUEVfTUVTU0FHRSwgIm9wdGlvbmFsX25lc3RlZF9tZXNzYWdlIiwgMTgpKTsKKyAgRVhQRUNUX1RSVUUoSGFzRmllbGQodHlwZSwgRmllbGQ6OkNBUkRJTkFMSVRZX09QVElPTkFMLAorICAgICAgICAgICAgICAgICAgICAgICBGaWVsZDo6VFlQRV9NRVNTQUdFLCAib3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlIiwgMTkpKTsKKworICBFWFBFQ1RfVFJVRShDaGVja0ZpZWxkVHlwZVVybCgKKyAgICAgIHR5cGUsICJvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSIsCisgICAgICBHZXRUeXBlVXJsPHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2U+KCkpKTsKKyAgRVhQRUNUX1RSVUUoQ2hlY2tGaWVsZFR5cGVVcmwoCisgICAgICB0eXBlLCAib3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlIiwKKyAgICAgIEdldFR5cGVVcmw8cHJvdG9idWZfdW5pdHRlc3Q6OkZvcmVpZ25NZXNzYWdlPigpKSk7CisKKyAgRVhQRUNUX1RSVUUoSGFzRmllbGQodHlwZSwgRmllbGQ6OkNBUkRJTkFMSVRZX09QVElPTkFMLAorICAgICAgICAgICAgICAgICAgICAgICBGaWVsZDo6VFlQRV9FTlVNLCAib3B0aW9uYWxfbmVzdGVkX2VudW0iLCAyMSkpOworICBFWFBFQ1RfVFJVRShIYXNGaWVsZCh0eXBlLCBGaWVsZDo6Q0FSRElOQUxJVFlfT1BUSU9OQUwsCisgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkOjpUWVBFX0VOVU0sICJvcHRpb25hbF9mb3JlaWduX2VudW0iLCAyMikpOworCisgIEVYUEVDVF9UUlVFKENoZWNrRmllbGRUeXBlVXJsKAorICAgICAgdHlwZSwgIm9wdGlvbmFsX25lc3RlZF9lbnVtIiwKKyAgICAgIEdldFR5cGVVcmwoInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIikpKTsKKyAgRVhQRUNUX1RSVUUoQ2hlY2tGaWVsZFR5cGVVcmwoCisgICAgICB0eXBlLCAib3B0aW9uYWxfZm9yZWlnbl9lbnVtIiwKKyAgICAgIEdldFR5cGVVcmwoInByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIikpKTsKKworICAvLyBDaGVjayBhbGwgcmVwZWF0ZWQgZmllbGRzLgorICBFWFBFQ1RfVFJVRShIYXNGaWVsZCh0eXBlLCBGaWVsZDo6Q0FSRElOQUxJVFlfUkVQRUFURUQsCisgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkOjpUWVBFX0lOVDMyLCAicmVwZWF0ZWRfaW50MzIiLCAzMSkpOworICBFWFBFQ1RfVFJVRShIYXNGaWVsZCh0eXBlLCBGaWVsZDo6Q0FSRElOQUxJVFlfUkVQRUFURUQsCisgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkOjpUWVBFX0lOVDY0LCAicmVwZWF0ZWRfaW50NjQiLCAzMikpOworICBFWFBFQ1RfVFJVRShIYXNGaWVsZCh0eXBlLCBGaWVsZDo6Q0FSRElOQUxJVFlfUkVQRUFURUQsCisgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkOjpUWVBFX1VJTlQzMiwgInJlcGVhdGVkX3VpbnQzMiIsIDMzKSk7CisgIEVYUEVDVF9UUlVFKEhhc0ZpZWxkKHR5cGUsIEZpZWxkOjpDQVJESU5BTElUWV9SRVBFQVRFRCwKKyAgICAgICAgICAgICAgICAgICAgICAgRmllbGQ6OlRZUEVfVUlOVDY0LCAicmVwZWF0ZWRfdWludDY0IiwgMzQpKTsKKyAgRVhQRUNUX1RSVUUoSGFzRmllbGQodHlwZSwgRmllbGQ6OkNBUkRJTkFMSVRZX1JFUEVBVEVELAorICAgICAgICAgICAgICAgICAgICAgICBGaWVsZDo6VFlQRV9TSU5UMzIsICJyZXBlYXRlZF9zaW50MzIiLCAzNSkpOworICBFWFBFQ1RfVFJVRShIYXNGaWVsZCh0eXBlLCBGaWVsZDo6Q0FSRElOQUxJVFlfUkVQRUFURUQsCisgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkOjpUWVBFX1NJTlQ2NCwgInJlcGVhdGVkX3NpbnQ2NCIsIDM2KSk7CisgIEVYUEVDVF9UUlVFKEhhc0ZpZWxkKHR5cGUsIEZpZWxkOjpDQVJESU5BTElUWV9SRVBFQVRFRCwKKyAgICAgICAgICAgICAgICAgICAgICAgRmllbGQ6OlRZUEVfRklYRUQzMiwgInJlcGVhdGVkX2ZpeGVkMzIiLCAzNykpOworICBFWFBFQ1RfVFJVRShIYXNGaWVsZCh0eXBlLCBGaWVsZDo6Q0FSRElOQUxJVFlfUkVQRUFURUQsCisgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkOjpUWVBFX0ZJWEVENjQsICJyZXBlYXRlZF9maXhlZDY0IiwgMzgpKTsKKyAgRVhQRUNUX1RSVUUoSGFzRmllbGQodHlwZSwgRmllbGQ6OkNBUkRJTkFMSVRZX1JFUEVBVEVELAorICAgICAgICAgICAgICAgICAgICAgICBGaWVsZDo6VFlQRV9TRklYRUQzMiwgInJlcGVhdGVkX3NmaXhlZDMyIiwgMzkpKTsKKyAgRVhQRUNUX1RSVUUoSGFzRmllbGQodHlwZSwgRmllbGQ6OkNBUkRJTkFMSVRZX1JFUEVBVEVELAorICAgICAgICAgICAgICAgICAgICAgICBGaWVsZDo6VFlQRV9TRklYRUQ2NCwgInJlcGVhdGVkX3NmaXhlZDY0IiwgNDApKTsKKyAgRVhQRUNUX1RSVUUoSGFzRmllbGQodHlwZSwgRmllbGQ6OkNBUkRJTkFMSVRZX1JFUEVBVEVELAorICAgICAgICAgICAgICAgICAgICAgICBGaWVsZDo6VFlQRV9GTE9BVCwgInJlcGVhdGVkX2Zsb2F0IiwgNDEpKTsKKyAgRVhQRUNUX1RSVUUoSGFzRmllbGQodHlwZSwgRmllbGQ6OkNBUkRJTkFMSVRZX1JFUEVBVEVELAorICAgICAgICAgICAgICAgICAgICAgICBGaWVsZDo6VFlQRV9ET1VCTEUsICJyZXBlYXRlZF9kb3VibGUiLCA0MikpOworICBFWFBFQ1RfVFJVRShIYXNGaWVsZCh0eXBlLCBGaWVsZDo6Q0FSRElOQUxJVFlfUkVQRUFURUQsCisgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkOjpUWVBFX0JPT0wsICJyZXBlYXRlZF9ib29sIiwgNDMpKTsKKyAgRVhQRUNUX1RSVUUoSGFzRmllbGQodHlwZSwgRmllbGQ6OkNBUkRJTkFMSVRZX1JFUEVBVEVELAorICAgICAgICAgICAgICAgICAgICAgICBGaWVsZDo6VFlQRV9TVFJJTkcsICJyZXBlYXRlZF9zdHJpbmciLCA0NCkpOworICBFWFBFQ1RfVFJVRShIYXNGaWVsZCh0eXBlLCBGaWVsZDo6Q0FSRElOQUxJVFlfUkVQRUFURUQsCisgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkOjpUWVBFX0JZVEVTLCAicmVwZWF0ZWRfYnl0ZXMiLCA0NSkpOworCisgIEVYUEVDVF9UUlVFKEhhc0ZpZWxkKHR5cGUsIEZpZWxkOjpDQVJESU5BTElUWV9SRVBFQVRFRCwKKyAgICAgICAgICAgICAgICAgICAgICAgRmllbGQ6OlRZUEVfTUVTU0FHRSwgInJlcGVhdGVkX25lc3RlZF9tZXNzYWdlIiwgNDgpKTsKKyAgRVhQRUNUX1RSVUUoSGFzRmllbGQodHlwZSwgRmllbGQ6OkNBUkRJTkFMSVRZX1JFUEVBVEVELAorICAgICAgICAgICAgICAgICAgICAgICBGaWVsZDo6VFlQRV9NRVNTQUdFLCAicmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlIiwgNDkpKTsKKworICBFWFBFQ1RfVFJVRShDaGVja0ZpZWxkVHlwZVVybCgKKyAgICAgIHR5cGUsICJyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSIsCisgICAgICBHZXRUeXBlVXJsPHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6Ok5lc3RlZE1lc3NhZ2U+KCkpKTsKKyAgRVhQRUNUX1RSVUUoQ2hlY2tGaWVsZFR5cGVVcmwoCisgICAgICB0eXBlLCAicmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlIiwKKyAgICAgIEdldFR5cGVVcmw8cHJvdG9idWZfdW5pdHRlc3Q6OkZvcmVpZ25NZXNzYWdlPigpKSk7CisKKyAgRVhQRUNUX1RSVUUoSGFzRmllbGQodHlwZSwgRmllbGQ6OkNBUkRJTkFMSVRZX1JFUEVBVEVELAorICAgICAgICAgICAgICAgICAgICAgICBGaWVsZDo6VFlQRV9FTlVNLCAicmVwZWF0ZWRfbmVzdGVkX2VudW0iLCA1MSkpOworICBFWFBFQ1RfVFJVRShIYXNGaWVsZCh0eXBlLCBGaWVsZDo6Q0FSRElOQUxJVFlfUkVQRUFURUQsCisgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkOjpUWVBFX0VOVU0sICJyZXBlYXRlZF9mb3JlaWduX2VudW0iLCA1MikpOworCisgIEVYUEVDVF9UUlVFKENoZWNrRmllbGRUeXBlVXJsKAorICAgICAgdHlwZSwgInJlcGVhdGVkX25lc3RlZF9lbnVtIiwKKyAgICAgIEdldFR5cGVVcmwoInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIikpKTsKKyAgRVhQRUNUX1RSVUUoQ2hlY2tGaWVsZFR5cGVVcmwoCisgICAgICB0eXBlLCAicmVwZWF0ZWRfZm9yZWlnbl9lbnVtIiwKKyAgICAgIEdldFR5cGVVcmwoInByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIikpKTsKKworICAvLyBHcm91cHMgYXJlIGRpc2NhcmRlZCB3aGVuIGNvbnZlcnRpbmcgdG8gVHlwZS4KKyAgY29uc3QgRGVzY3JpcHRvciogZGVzY3JpcHRvciA9IHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXM6OmRlc2NyaXB0b3IoKTsKKyAgRVhQRUNUX1RSVUUoZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOYW1lKCJvcHRpb25hbGdyb3VwIikgIT0gTlVMTCk7CisgIEVYUEVDVF9UUlVFKGRlc2NyaXB0b3ItPkZpbmRGaWVsZEJ5TmFtZSgicmVwZWF0ZWRncm91cCIpICE9IE5VTEwpOworICBBU1NFUlRfRkFMU0UoSGFzRmllbGQodHlwZSwgIm9wdGlvbmFsZ3JvdXAiKSk7CisgIEFTU0VSVF9GQUxTRShIYXNGaWVsZCh0eXBlLCAicmVwZWF0ZWRncm91cCIpKTsKK30KKworVEVTVF9GKERlc2NyaXB0b3JQb29sVHlwZVJlc29sdmVyVGVzdCwgVGVzdFBhY2tlZEZpZWxkKSB7CisgIFR5cGUgdHlwZTsKKyAgQVNTRVJUX1RSVUUocmVzb2x2ZXJfLT5SZXNvbHZlTWVzc2FnZVR5cGUoCisgICAgICBHZXRUeXBlVXJsPHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0UGFja2VkVHlwZXM+KCksICZ0eXBlKS5vaygpKTsKKyAgRVhQRUNUX1RSVUUoSGFzRmllbGQodHlwZSwgRmllbGQ6OkNBUkRJTkFMSVRZX1JFUEVBVEVELAorICAgICAgICAgICAgICAgICAgICAgICBGaWVsZDo6VFlQRV9JTlQzMiwgInBhY2tlZF9pbnQzMiIsIDkwKSk7CisgIEVYUEVDVF9UUlVFKElzUGFja2VkKHR5cGUsICJwYWNrZWRfaW50MzIiKSk7Cit9CisKK1RFU1RfRihEZXNjcmlwdG9yUG9vbFR5cGVSZXNvbHZlclRlc3QsIFRlc3RPbmVvZikgeworICBUeXBlIHR5cGU7CisgIEFTU0VSVF9UUlVFKHJlc29sdmVyXy0+UmVzb2x2ZU1lc3NhZ2VUeXBlKAorICAgICAgR2V0VHlwZVVybDxwcm90b2J1Zl91bml0dGVzdDo6VGVzdEFsbFR5cGVzPigpLCAmdHlwZSkub2soKSk7CisgIEVYUEVDVF9UUlVFKEhhc0ZpZWxkKHR5cGUsIEZpZWxkOjpDQVJESU5BTElUWV9PUFRJT05BTCwKKyAgICAgICAgICAgICAgICAgICAgICAgRmllbGQ6OlRZUEVfVUlOVDMyLCAib25lb2ZfdWludDMyIiwgMTExKSk7CisgIEVYUEVDVF9UUlVFKEhhc0ZpZWxkKHR5cGUsIEZpZWxkOjpDQVJESU5BTElUWV9PUFRJT05BTCwKKyAgICAgICAgICAgICAgICAgICAgICAgRmllbGQ6OlRZUEVfTUVTU0FHRSwgIm9uZW9mX25lc3RlZF9tZXNzYWdlIiwgMTEyKSk7CisgIEVYUEVDVF9UUlVFKEhhc0ZpZWxkKHR5cGUsIEZpZWxkOjpDQVJESU5BTElUWV9PUFRJT05BTCwKKyAgICAgICAgICAgICAgICAgICAgICAgRmllbGQ6OlRZUEVfU1RSSU5HLCAib25lb2Zfc3RyaW5nIiwgMTEzKSk7CisgIEVYUEVDVF9UUlVFKEhhc0ZpZWxkKHR5cGUsIEZpZWxkOjpDQVJESU5BTElUWV9PUFRJT05BTCwKKyAgICAgICAgICAgICAgICAgICAgICAgRmllbGQ6OlRZUEVfQllURVMsICJvbmVvZl9ieXRlcyIsIDExNCkpOworICBFWFBFQ1RfVFJVRShGaWVsZEluT25lb2YodHlwZSwgIm9uZW9mX3VpbnQzMiIsICJvbmVvZl9maWVsZCIpKTsKKyAgRVhQRUNUX1RSVUUoRmllbGRJbk9uZW9mKHR5cGUsICJvbmVvZl9uZXN0ZWRfbWVzc2FnZSIsICJvbmVvZl9maWVsZCIpKTsKKyAgRVhQRUNUX1RSVUUoRmllbGRJbk9uZW9mKHR5cGUsICJvbmVvZl9zdHJpbmciLCAib25lb2ZfZmllbGQiKSk7CisgIEVYUEVDVF9UUlVFKEZpZWxkSW5PbmVvZih0eXBlLCAib25lb2ZfYnl0ZXMiLCAib25lb2ZfZmllbGQiKSk7Cit9CisKK1RFU1RfRihEZXNjcmlwdG9yUG9vbFR5cGVSZXNvbHZlclRlc3QsIFRlc3RNYXApIHsKKyAgVHlwZSB0eXBlOworICBBU1NFUlRfVFJVRShyZXNvbHZlcl8tPlJlc29sdmVNZXNzYWdlVHlwZSgKKyAgICAgIEdldFR5cGVVcmw8cHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RNYXA+KCksICZ0eXBlKS5vaygpKTsKKyAgRVhQRUNUX1RSVUUoSGFzRmllbGQodHlwZSwgRmllbGQ6OkNBUkRJTkFMSVRZX1JFUEVBVEVELAorICAgICAgICAgICAgICAgICAgICAgICBGaWVsZDo6VFlQRV9NRVNTQUdFLCAibWFwX2ludDMyX2ludDMyIiwgMSkpOworICBFWFBFQ1RfVFJVRShDaGVja0ZpZWxkVHlwZVVybCgKKyAgICAgIHR5cGUsICJtYXBfaW50MzJfaW50MzIiLAorICAgICAgR2V0VHlwZVVybCgicHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcC5NYXBJbnQzMkludDMyRW50cnkiKSkpOworCisgIEFTU0VSVF9UUlVFKHJlc29sdmVyXy0+UmVzb2x2ZU1lc3NhZ2VUeXBlKAorICAgICAgR2V0VHlwZVVybCgicHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcC5NYXBJbnQzMkludDMyRW50cnkiKSwKKyAgICAgICZ0eXBlKS5vaygpKTsKKyAgRVhQRUNUX1RSVUUoSGFzQm9vbE9wdGlvbih0eXBlLm9wdGlvbnMoKSwgIm1hcF9lbnRyeSIsIHRydWUpKTsKK30KKworVEVTVF9GKERlc2NyaXB0b3JQb29sVHlwZVJlc29sdmVyVGVzdCwgVGVzdEVudW0pIHsKKyAgRW51bSB0eXBlOworICBBU1NFUlRfVFJVRShyZXNvbHZlcl8tPlJlc29sdmVFbnVtVHlwZSgKKyAgICAgIEdldFR5cGVVcmwoInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIiksICZ0eXBlKS5vaygpKTsKKyAgRW51bUhhc1ZhbHVlKHR5cGUsICJGT08iLCAxKTsKKyAgRW51bUhhc1ZhbHVlKHR5cGUsICJCQVIiLCAyKTsKKyAgRW51bUhhc1ZhbHVlKHR5cGUsICJCQVoiLCAzKTsKKyAgRW51bUhhc1ZhbHVlKHR5cGUsICJORUciLCAtMSk7Cit9CisKK1RFU1RfRihEZXNjcmlwdG9yUG9vbFR5cGVSZXNvbHZlclRlc3QsIFRlc3RKc29uTmFtZSkgeworICBUeXBlIHR5cGU7CisgIEFTU0VSVF9UUlVFKHJlc29sdmVyXy0+UmVzb2x2ZU1lc3NhZ2VUeXBlKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgR2V0VHlwZVVybDxwcm90b2J1Zl91bml0dGVzdDo6VGVzdEFsbFR5cGVzPigpLCAmdHlwZSkKKyAgICAgICAgICAgICAgICAgIC5vaygpKTsKKyAgRVhQRUNUX0VRKCJvcHRpb25hbEludDMyIiwgRmluZEZpZWxkKHR5cGUsICJvcHRpb25hbF9pbnQzMiIpLT5qc29uX25hbWUoKSk7CisKKyAgQVNTRVJUX1RSVUUocmVzb2x2ZXJfLT5SZXNvbHZlTWVzc2FnZVR5cGUoCisgICAgICAgICAgICAgICAgICAgICAgICAgICBHZXRUeXBlVXJsPHByb3RvMzo6VGVzdEN1c3RvbUpzb25OYW1lPigpLCAmdHlwZSkKKyAgICAgICAgICAgICAgICAgIC5vaygpKTsKKyAgRVhQRUNUX0VRKCJAdmFsdWUiLCBGaW5kRmllbGQodHlwZSwgInZhbHVlIiktPmpzb25fbmFtZSgpKTsKK30KKworfSAgLy8gbmFtZXNwYWNlCit9ICAvLyBuYW1lc3BhY2UgdXRpbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3dlbGxfa25vd25fdHlwZXNfdW5pdHRlc3QuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3dlbGxfa25vd25fdHlwZXNfdW5pdHRlc3QuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzlhOWFhMQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvd2VsbF9rbm93bl90eXBlc191bml0dGVzdC5jYwpAQCAtMCwwICsxLDYwIEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfd2VsbF9rbm93bl90eXBlcy5wYi5oPgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL2dvb2dsZXRlc3QuaD4KKyNpbmNsdWRlIDxndGVzdC9ndGVzdC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdGxfdXRpbC5oPgorCituYW1lc3BhY2UgZ29vZ2xlIHsKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgeworCisvLyBUaGlzIHRlc3Qgb25seSBjaGVja3Mgd2hldGhlciB3ZWxsLWtub3duIHR5cGVzIGFyZSBpbmNsdWRlZCBpbiBwcm90b2J1ZgorLy8gcnVudGltZSBsaWJyYXJ5LiBUaGUgdGVzdCBwYXNzZXMgaWYgaXQgY29tcGlsZXMuCitURVNUKFdlbGxLbm93blR5cGVzVGVzdCwgQWxsS25vd25UeXBlc0FyZUluY2x1ZGVkKSB7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpUZXN0V2VsbEtub3duVHlwZXMgbWVzc2FnZTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuYW55X2ZpZWxkKCkuQnl0ZVNpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLmFwaV9maWVsZCgpLkJ5dGVTaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5kdXJhdGlvbl9maWVsZCgpLkJ5dGVTaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5lbXB0eV9maWVsZCgpLkJ5dGVTaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5maWVsZF9tYXNrX2ZpZWxkKCkuQnl0ZVNpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnNvdXJjZV9jb250ZXh0X2ZpZWxkKCkuQnl0ZVNpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBtZXNzYWdlLnN0cnVjdF9maWVsZCgpLkJ5dGVTaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS50aW1lc3RhbXBfZmllbGQoKS5CeXRlU2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UudHlwZV9maWVsZCgpLkJ5dGVTaXplKCkpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5pbnQzMl9maWVsZCgpLkJ5dGVTaXplKCkpOworfQorCit9ICAvLyBuYW1lc3BhY2UKKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0LmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdC5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ZWU0ZTI1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdC5jYwpAQCAtMCwwICsxLDExMzMgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgQmFzZWQgb24gb3JpZ2luYWwgUHJvdG9jb2wgQnVmZmVycyBkZXNpZ24gYnkKKy8vICBTYW5qYXkgR2hlbWF3YXQsIEplZmYgRGVhbiwgYW5kIG90aGVycy4KKworI2luY2x1ZGUgPHN0YWNrPgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDx2ZWN0b3I+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuaD4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9sb2dnaW5nLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJpbmdwcmludGYuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdF9saXRlX2lubC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bmtub3duX2ZpZWxkX3NldC5oPgorCisKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitib29sIFVua25vd25GaWVsZFNldEZpZWxkU2tpcHBlcjo6U2tpcEZpZWxkKAorICAgIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwgdWludDMyIHRhZykgeworICByZXR1cm4gV2lyZUZvcm1hdDo6U2tpcEZpZWxkKGlucHV0LCB0YWcsIHVua25vd25fZmllbGRzXyk7Cit9CisKK2Jvb2wgVW5rbm93bkZpZWxkU2V0RmllbGRTa2lwcGVyOjpTa2lwTWVzc2FnZShpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyAgcmV0dXJuIFdpcmVGb3JtYXQ6OlNraXBNZXNzYWdlKGlucHV0LCB1bmtub3duX2ZpZWxkc18pOworfQorCit2b2lkIFVua25vd25GaWVsZFNldEZpZWxkU2tpcHBlcjo6U2tpcFVua25vd25FbnVtKAorICAgIGludCBmaWVsZF9udW1iZXIsIGludCB2YWx1ZSkgeworICB1bmtub3duX2ZpZWxkc18tPkFkZFZhcmludChmaWVsZF9udW1iZXIsIHZhbHVlKTsKK30KKworYm9vbCBXaXJlRm9ybWF0OjpTa2lwRmllbGQoaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LCB1aW50MzIgdGFnLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgVW5rbm93bkZpZWxkU2V0KiB1bmtub3duX2ZpZWxkcykgeworICBpbnQgbnVtYmVyID0gV2lyZUZvcm1hdExpdGU6OkdldFRhZ0ZpZWxkTnVtYmVyKHRhZyk7CisKKyAgc3dpdGNoIChXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnV2lyZVR5cGUodGFnKSkgeworICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX1ZBUklOVDogeworICAgICAgdWludDY0IHZhbHVlOworICAgICAgaWYgKCFpbnB1dC0+UmVhZFZhcmludDY0KCZ2YWx1ZSkpIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICh1bmtub3duX2ZpZWxkcyAhPSBOVUxMKSB1bmtub3duX2ZpZWxkcy0+QWRkVmFyaW50KG51bWJlciwgdmFsdWUpOworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0ZJWEVENjQ6IHsKKyAgICAgIHVpbnQ2NCB2YWx1ZTsKKyAgICAgIGlmICghaW5wdXQtPlJlYWRMaXR0bGVFbmRpYW42NCgmdmFsdWUpKSByZXR1cm4gZmFsc2U7CisgICAgICBpZiAodW5rbm93bl9maWVsZHMgIT0gTlVMTCkgdW5rbm93bl9maWVsZHMtPkFkZEZpeGVkNjQobnVtYmVyLCB2YWx1ZSk7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRDogeworICAgICAgdWludDMyIGxlbmd0aDsKKyAgICAgIGlmICghaW5wdXQtPlJlYWRWYXJpbnQzMigmbGVuZ3RoKSkgcmV0dXJuIGZhbHNlOworICAgICAgaWYgKHVua25vd25fZmllbGRzID09IE5VTEwpIHsKKyAgICAgICAgaWYgKCFpbnB1dC0+U2tpcChsZW5ndGgpKSByZXR1cm4gZmFsc2U7CisgICAgICB9IGVsc2UgeworICAgICAgICBpZiAoIWlucHV0LT5SZWFkU3RyaW5nKHVua25vd25fZmllbGRzLT5BZGRMZW5ndGhEZWxpbWl0ZWQobnVtYmVyKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGgpKSB7CisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICB9CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfU1RBUlRfR1JPVVA6IHsKKyAgICAgIGlmICghaW5wdXQtPkluY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCkpIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICghU2tpcE1lc3NhZ2UoaW5wdXQsICh1bmtub3duX2ZpZWxkcyA9PSBOVUxMKSA/CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMIDogdW5rbm93bl9maWVsZHMtPkFkZEdyb3VwKG51bWJlcikpKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICAgIGlucHV0LT5EZWNyZW1lbnRSZWN1cnNpb25EZXB0aCgpOworICAgICAgLy8gQ2hlY2sgdGhhdCB0aGUgZW5kaW5nIHRhZyBtYXRjaGVkIHRoZSBzdGFydGluZyB0YWcuCisgICAgICBpZiAoIWlucHV0LT5MYXN0VGFnV2FzKFdpcmVGb3JtYXRMaXRlOjpNYWtlVGFnKAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpHZXRUYWdGaWVsZE51bWJlcih0YWcpLAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVApKSkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRU5EX0dST1VQOiB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0ZJWEVEMzI6IHsKKyAgICAgIHVpbnQzMiB2YWx1ZTsKKyAgICAgIGlmICghaW5wdXQtPlJlYWRMaXR0bGVFbmRpYW4zMigmdmFsdWUpKSByZXR1cm4gZmFsc2U7CisgICAgICBpZiAodW5rbm93bl9maWVsZHMgIT0gTlVMTCkgdW5rbm93bl9maWVsZHMtPkFkZEZpeGVkMzIobnVtYmVyLCB2YWx1ZSk7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgICAgZGVmYXVsdDogeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgfQorfQorCitib29sIFdpcmVGb3JtYXQ6OlNraXBNZXNzYWdlKGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVW5rbm93bkZpZWxkU2V0KiB1bmtub3duX2ZpZWxkcykgeworICB3aGlsZSAodHJ1ZSkgeworICAgIHVpbnQzMiB0YWcgPSBpbnB1dC0+UmVhZFRhZygpOworICAgIGlmICh0YWcgPT0gMCkgeworICAgICAgLy8gRW5kIG9mIGlucHV0LiAgVGhpcyBpcyBhIHZhbGlkIHBsYWNlIHRvIGVuZCwgc28gcmV0dXJuIHRydWUuCisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBXaXJlRm9ybWF0TGl0ZTo6V2lyZVR5cGUgd2lyZV90eXBlID0gV2lyZUZvcm1hdExpdGU6OkdldFRhZ1dpcmVUeXBlKHRhZyk7CisKKyAgICBpZiAod2lyZV90eXBlID09IFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVApIHsKKyAgICAgIC8vIE11c3QgYmUgdGhlIGVuZCBvZiB0aGUgbWVzc2FnZS4KKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIGlmICghU2tpcEZpZWxkKGlucHV0LCB0YWcsIHVua25vd25fZmllbGRzKSkgcmV0dXJuIGZhbHNlOworICB9Cit9CisKK2Jvb2wgV2lyZUZvcm1hdDo6UmVhZFBhY2tlZEVudW1QcmVzZXJ2ZVVua25vd25zKGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMiBmaWVsZF9udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sICgqaXNfdmFsaWQpKGludCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVbmtub3duRmllbGRTZXQqIHVua25vd25fZmllbGRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVwZWF0ZWRGaWVsZDxpbnQ+KiB2YWx1ZXMpIHsKKyAgdWludDMyIGxlbmd0aDsKKyAgaWYgKCFpbnB1dC0+UmVhZFZhcmludDMyKCZsZW5ndGgpKSByZXR1cm4gZmFsc2U7CisgIGlvOjpDb2RlZElucHV0U3RyZWFtOjpMaW1pdCBsaW1pdCA9IGlucHV0LT5QdXNoTGltaXQobGVuZ3RoKTsKKyAgd2hpbGUgKGlucHV0LT5CeXRlc1VudGlsTGltaXQoKSA+IDApIHsKKyAgICBpbnQgdmFsdWU7CisgICAgaWYgKCFnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgIGludCwgV2lyZUZvcm1hdExpdGU6OlRZUEVfRU5VTT4oaW5wdXQsICZ2YWx1ZSkpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgaWYgKGlzX3ZhbGlkID09IE5VTEwgfHwgaXNfdmFsaWQodmFsdWUpKSB7CisgICAgICB2YWx1ZXMtPkFkZCh2YWx1ZSk7CisgICAgfSBlbHNlIHsKKyAgICAgIHVua25vd25fZmllbGRzLT5BZGRWYXJpbnQoZmllbGRfbnVtYmVyLCB2YWx1ZSk7CisgICAgfQorICB9CisgIGlucHV0LT5Qb3BMaW1pdChsaW1pdCk7CisgIHJldHVybiB0cnVlOworfQorCisKK3ZvaWQgV2lyZUZvcm1hdDo6U2VyaWFsaXplVW5rbm93bkZpZWxkcyhjb25zdCBVbmtub3duRmllbGRTZXQmIHVua25vd25fZmllbGRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgdW5rbm93bl9maWVsZHMuZmllbGRfY291bnQoKTsgaSsrKSB7CisgICAgY29uc3QgVW5rbm93bkZpZWxkJiBmaWVsZCA9IHVua25vd25fZmllbGRzLmZpZWxkKGkpOworICAgIHN3aXRjaCAoZmllbGQudHlwZSgpKSB7CisgICAgICBjYXNlIFVua25vd25GaWVsZDo6VFlQRV9WQVJJTlQ6CisgICAgICAgIG91dHB1dC0+V3JpdGVWYXJpbnQzMihXaXJlRm9ybWF0TGl0ZTo6TWFrZVRhZyhmaWVsZC5udW1iZXIoKSwKKyAgICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9WQVJJTlQpKTsKKyAgICAgICAgb3V0cHV0LT5Xcml0ZVZhcmludDY0KGZpZWxkLnZhcmludCgpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIFVua25vd25GaWVsZDo6VFlQRV9GSVhFRDMyOgorICAgICAgICBvdXRwdXQtPldyaXRlVmFyaW50MzIoV2lyZUZvcm1hdExpdGU6Ok1ha2VUYWcoZmllbGQubnVtYmVyKCksCisgICAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRklYRUQzMikpOworICAgICAgICBvdXRwdXQtPldyaXRlTGl0dGxlRW5kaWFuMzIoZmllbGQuZml4ZWQzMigpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIFVua25vd25GaWVsZDo6VFlQRV9GSVhFRDY0OgorICAgICAgICBvdXRwdXQtPldyaXRlVmFyaW50MzIoV2lyZUZvcm1hdExpdGU6Ok1ha2VUYWcoZmllbGQubnVtYmVyKCksCisgICAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRklYRUQ2NCkpOworICAgICAgICBvdXRwdXQtPldyaXRlTGl0dGxlRW5kaWFuNjQoZmllbGQuZml4ZWQ2NCgpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIFVua25vd25GaWVsZDo6VFlQRV9MRU5HVEhfREVMSU1JVEVEOgorICAgICAgICBvdXRwdXQtPldyaXRlVmFyaW50MzIoV2lyZUZvcm1hdExpdGU6Ok1ha2VUYWcoZmllbGQubnVtYmVyKCksCisgICAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCkpOworICAgICAgICBvdXRwdXQtPldyaXRlVmFyaW50MzIoZmllbGQubGVuZ3RoX2RlbGltaXRlZCgpLnNpemUoKSk7CisgICAgICAgIG91dHB1dC0+V3JpdGVSYXdNYXliZUFsaWFzZWQoZmllbGQubGVuZ3RoX2RlbGltaXRlZCgpLmRhdGEoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZC5sZW5ndGhfZGVsaW1pdGVkKCkuc2l6ZSgpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIFVua25vd25GaWVsZDo6VFlQRV9HUk9VUDoKKyAgICAgICAgb3V0cHV0LT5Xcml0ZVZhcmludDMyKFdpcmVGb3JtYXRMaXRlOjpNYWtlVGFnKGZpZWxkLm51bWJlcigpLAorICAgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX1NUQVJUX0dST1VQKSk7CisgICAgICAgIFNlcmlhbGl6ZVVua25vd25GaWVsZHMoZmllbGQuZ3JvdXAoKSwgb3V0cHV0KTsKKyAgICAgICAgb3V0cHV0LT5Xcml0ZVZhcmludDMyKFdpcmVGb3JtYXRMaXRlOjpNYWtlVGFnKGZpZWxkLm51bWJlcigpLAorICAgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0VORF9HUk9VUCkpOworICAgICAgICBicmVhazsKKyAgICB9CisgIH0KK30KKwordWludDgqIFdpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25GaWVsZHNUb0FycmF5KAorICAgIGNvbnN0IFVua25vd25GaWVsZFNldCYgdW5rbm93bl9maWVsZHMsCisgICAgdWludDgqIHRhcmdldCkgeworICBmb3IgKGludCBpID0gMDsgaSA8IHVua25vd25fZmllbGRzLmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IFVua25vd25GaWVsZCYgZmllbGQgPSB1bmtub3duX2ZpZWxkcy5maWVsZChpKTsKKworICAgIHN3aXRjaCAoZmllbGQudHlwZSgpKSB7CisgICAgICBjYXNlIFVua25vd25GaWVsZDo6VFlQRV9WQVJJTlQ6CisgICAgICAgIHRhcmdldCA9IFdpcmVGb3JtYXRMaXRlOjpXcml0ZUludDY0VG9BcnJheSgKKyAgICAgICAgICAgIGZpZWxkLm51bWJlcigpLCBmaWVsZC52YXJpbnQoKSwgdGFyZ2V0KTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIFVua25vd25GaWVsZDo6VFlQRV9GSVhFRDMyOgorICAgICAgICB0YXJnZXQgPSBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVGaXhlZDMyVG9BcnJheSgKKyAgICAgICAgICAgIGZpZWxkLm51bWJlcigpLCBmaWVsZC5maXhlZDMyKCksIHRhcmdldCk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBVbmtub3duRmllbGQ6OlRZUEVfRklYRUQ2NDoKKyAgICAgICAgdGFyZ2V0ID0gV2lyZUZvcm1hdExpdGU6OldyaXRlRml4ZWQ2NFRvQXJyYXkoCisgICAgICAgICAgICBmaWVsZC5udW1iZXIoKSwgZmllbGQuZml4ZWQ2NCgpLCB0YXJnZXQpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgVW5rbm93bkZpZWxkOjpUWVBFX0xFTkdUSF9ERUxJTUlURUQ6CisgICAgICAgIHRhcmdldCA9IFdpcmVGb3JtYXRMaXRlOjpXcml0ZUJ5dGVzVG9BcnJheSgKKyAgICAgICAgICAgIGZpZWxkLm51bWJlcigpLCBmaWVsZC5sZW5ndGhfZGVsaW1pdGVkKCksIHRhcmdldCk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBVbmtub3duRmllbGQ6OlRZUEVfR1JPVVA6CisgICAgICAgIHRhcmdldCA9IFdpcmVGb3JtYXRMaXRlOjpXcml0ZVRhZ1RvQXJyYXkoCisgICAgICAgICAgICBmaWVsZC5udW1iZXIoKSwgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX1NUQVJUX0dST1VQLCB0YXJnZXQpOworICAgICAgICB0YXJnZXQgPSBTZXJpYWxpemVVbmtub3duRmllbGRzVG9BcnJheShmaWVsZC5ncm91cCgpLCB0YXJnZXQpOworICAgICAgICB0YXJnZXQgPSBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVUYWdUb0FycmF5KAorICAgICAgICAgICAgZmllbGQubnVtYmVyKCksIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVAsIHRhcmdldCk7CisgICAgICAgIGJyZWFrOworICAgIH0KKyAgfQorICByZXR1cm4gdGFyZ2V0OworfQorCit2b2lkIFdpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25NZXNzYWdlU2V0SXRlbXMoCisgICAgY29uc3QgVW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcywKKyAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgeworICBmb3IgKGludCBpID0gMDsgaSA8IHVua25vd25fZmllbGRzLmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IFVua25vd25GaWVsZCYgZmllbGQgPSB1bmtub3duX2ZpZWxkcy5maWVsZChpKTsKKyAgICAvLyBUaGUgb25seSB1bmtub3duIGZpZWxkcyB0aGF0IGFyZSBhbGxvd2VkIHRvIGV4aXN0IGluIGEgTWVzc2FnZVNldCBhcmUKKyAgICAvLyBtZXNzYWdlcywgd2hpY2ggYXJlIGxlbmd0aC1kZWxpbWl0ZWQuCisgICAgaWYgKGZpZWxkLnR5cGUoKSA9PSBVbmtub3duRmllbGQ6OlRZUEVfTEVOR1RIX0RFTElNSVRFRCkgeworICAgICAgLy8gU3RhcnQgZ3JvdXAuCisgICAgICBvdXRwdXQtPldyaXRlVmFyaW50MzIoV2lyZUZvcm1hdExpdGU6OmtNZXNzYWdlU2V0SXRlbVN0YXJ0VGFnKTsKKworICAgICAgLy8gV3JpdGUgdHlwZSBJRC4KKyAgICAgIG91dHB1dC0+V3JpdGVWYXJpbnQzMihXaXJlRm9ybWF0TGl0ZTo6a01lc3NhZ2VTZXRUeXBlSWRUYWcpOworICAgICAgb3V0cHV0LT5Xcml0ZVZhcmludDMyKGZpZWxkLm51bWJlcigpKTsKKworICAgICAgLy8gV3JpdGUgbWVzc2FnZS4KKyAgICAgIG91dHB1dC0+V3JpdGVWYXJpbnQzMihXaXJlRm9ybWF0TGl0ZTo6a01lc3NhZ2VTZXRNZXNzYWdlVGFnKTsKKyAgICAgIGZpZWxkLlNlcmlhbGl6ZUxlbmd0aERlbGltaXRlZE5vVGFnKG91dHB1dCk7CisKKyAgICAgIC8vIEVuZCBncm91cC4KKyAgICAgIG91dHB1dC0+V3JpdGVWYXJpbnQzMihXaXJlRm9ybWF0TGl0ZTo6a01lc3NhZ2VTZXRJdGVtRW5kVGFnKTsKKyAgICB9CisgIH0KK30KKwordWludDgqIFdpcmVGb3JtYXQ6OlNlcmlhbGl6ZVVua25vd25NZXNzYWdlU2V0SXRlbXNUb0FycmF5KAorICAgIGNvbnN0IFVua25vd25GaWVsZFNldCYgdW5rbm93bl9maWVsZHMsCisgICAgdWludDgqIHRhcmdldCkgeworICBmb3IgKGludCBpID0gMDsgaSA8IHVua25vd25fZmllbGRzLmZpZWxkX2NvdW50KCk7IGkrKykgeworICAgIGNvbnN0IFVua25vd25GaWVsZCYgZmllbGQgPSB1bmtub3duX2ZpZWxkcy5maWVsZChpKTsKKworICAgIC8vIFRoZSBvbmx5IHVua25vd24gZmllbGRzIHRoYXQgYXJlIGFsbG93ZWQgdG8gZXhpc3QgaW4gYSBNZXNzYWdlU2V0IGFyZQorICAgIC8vIG1lc3NhZ2VzLCB3aGljaCBhcmUgbGVuZ3RoLWRlbGltaXRlZC4KKyAgICBpZiAoZmllbGQudHlwZSgpID09IFVua25vd25GaWVsZDo6VFlQRV9MRU5HVEhfREVMSU1JVEVEKSB7CisgICAgICAvLyBTdGFydCBncm91cC4KKyAgICAgIHRhcmdldCA9IGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVUYWdUb0FycmF5KAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjprTWVzc2FnZVNldEl0ZW1TdGFydFRhZywgdGFyZ2V0KTsKKworICAgICAgLy8gV3JpdGUgdHlwZSBJRC4KKyAgICAgIHRhcmdldCA9IGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVUYWdUb0FycmF5KAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjprTWVzc2FnZVNldFR5cGVJZFRhZywgdGFyZ2V0KTsKKyAgICAgIHRhcmdldCA9IGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVWYXJpbnQzMlRvQXJyYXkoCisgICAgICAgICAgZmllbGQubnVtYmVyKCksIHRhcmdldCk7CisKKyAgICAgIC8vIFdyaXRlIG1lc3NhZ2UuCisgICAgICB0YXJnZXQgPSBpbzo6Q29kZWRPdXRwdXRTdHJlYW06OldyaXRlVGFnVG9BcnJheSgKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6a01lc3NhZ2VTZXRNZXNzYWdlVGFnLCB0YXJnZXQpOworICAgICAgdGFyZ2V0ID0gZmllbGQuU2VyaWFsaXplTGVuZ3RoRGVsaW1pdGVkTm9UYWdUb0FycmF5KHRhcmdldCk7CisKKyAgICAgIC8vIEVuZCBncm91cC4KKyAgICAgIHRhcmdldCA9IGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVUYWdUb0FycmF5KAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjprTWVzc2FnZVNldEl0ZW1FbmRUYWcsIHRhcmdldCk7CisgICAgfQorICB9CisKKyAgcmV0dXJuIHRhcmdldDsKK30KKworaW50IFdpcmVGb3JtYXQ6OkNvbXB1dGVVbmtub3duRmllbGRzU2l6ZSgKKyAgICBjb25zdCBVbmtub3duRmllbGRTZXQmIHVua25vd25fZmllbGRzKSB7CisgIGludCBzaXplID0gMDsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB1bmtub3duX2ZpZWxkcy5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBVbmtub3duRmllbGQmIGZpZWxkID0gdW5rbm93bl9maWVsZHMuZmllbGQoaSk7CisKKyAgICBzd2l0Y2ggKGZpZWxkLnR5cGUoKSkgeworICAgICAgY2FzZSBVbmtub3duRmllbGQ6OlRZUEVfVkFSSU5UOgorICAgICAgICBzaXplICs9IGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6VmFyaW50U2l6ZTMyKAorICAgICAgICAgICAgV2lyZUZvcm1hdExpdGU6Ok1ha2VUYWcoZmllbGQubnVtYmVyKCksCisgICAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfVkFSSU5UKSk7CisgICAgICAgIHNpemUgKz0gaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpWYXJpbnRTaXplNjQoZmllbGQudmFyaW50KCkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgVW5rbm93bkZpZWxkOjpUWVBFX0ZJWEVEMzI6CisgICAgICAgIHNpemUgKz0gaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpWYXJpbnRTaXplMzIoCisgICAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6TWFrZVRhZyhmaWVsZC5udW1iZXIoKSwKKyAgICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9GSVhFRDMyKSk7CisgICAgICAgIHNpemUgKz0gc2l6ZW9mKGludDMyKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIFVua25vd25GaWVsZDo6VFlQRV9GSVhFRDY0OgorICAgICAgICBzaXplICs9IGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6VmFyaW50U2l6ZTMyKAorICAgICAgICAgICAgV2lyZUZvcm1hdExpdGU6Ok1ha2VUYWcoZmllbGQubnVtYmVyKCksCisgICAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRklYRUQ2NCkpOworICAgICAgICBzaXplICs9IHNpemVvZihpbnQ2NCk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBVbmtub3duRmllbGQ6OlRZUEVfTEVOR1RIX0RFTElNSVRFRDoKKyAgICAgICAgc2l6ZSArPSBpbzo6Q29kZWRPdXRwdXRTdHJlYW06OlZhcmludFNpemUzMigKKyAgICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpNYWtlVGFnKGZpZWxkLm51bWJlcigpLAorICAgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQpKTsKKyAgICAgICAgc2l6ZSArPSBpbzo6Q29kZWRPdXRwdXRTdHJlYW06OlZhcmludFNpemUzMigKKyAgICAgICAgICAgIGZpZWxkLmxlbmd0aF9kZWxpbWl0ZWQoKS5zaXplKCkpOworICAgICAgICBzaXplICs9IGZpZWxkLmxlbmd0aF9kZWxpbWl0ZWQoKS5zaXplKCk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBVbmtub3duRmllbGQ6OlRZUEVfR1JPVVA6CisgICAgICAgIHNpemUgKz0gaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpWYXJpbnRTaXplMzIoCisgICAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6TWFrZVRhZyhmaWVsZC5udW1iZXIoKSwKKyAgICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9TVEFSVF9HUk9VUCkpOworICAgICAgICBzaXplICs9IENvbXB1dGVVbmtub3duRmllbGRzU2l6ZShmaWVsZC5ncm91cCgpKTsKKyAgICAgICAgc2l6ZSArPSBpbzo6Q29kZWRPdXRwdXRTdHJlYW06OlZhcmludFNpemUzMigKKyAgICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpNYWtlVGFnKGZpZWxkLm51bWJlcigpLAorICAgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0VORF9HUk9VUCkpOworICAgICAgICBicmVhazsKKyAgICB9CisgIH0KKworICByZXR1cm4gc2l6ZTsKK30KKworaW50IFdpcmVGb3JtYXQ6OkNvbXB1dGVVbmtub3duTWVzc2FnZVNldEl0ZW1zU2l6ZSgKKyAgICBjb25zdCBVbmtub3duRmllbGRTZXQmIHVua25vd25fZmllbGRzKSB7CisgIGludCBzaXplID0gMDsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCB1bmtub3duX2ZpZWxkcy5maWVsZF9jb3VudCgpOyBpKyspIHsKKyAgICBjb25zdCBVbmtub3duRmllbGQmIGZpZWxkID0gdW5rbm93bl9maWVsZHMuZmllbGQoaSk7CisKKyAgICAvLyBUaGUgb25seSB1bmtub3duIGZpZWxkcyB0aGF0IGFyZSBhbGxvd2VkIHRvIGV4aXN0IGluIGEgTWVzc2FnZVNldCBhcmUKKyAgICAvLyBtZXNzYWdlcywgd2hpY2ggYXJlIGxlbmd0aC1kZWxpbWl0ZWQuCisgICAgaWYgKGZpZWxkLnR5cGUoKSA9PSBVbmtub3duRmllbGQ6OlRZUEVfTEVOR1RIX0RFTElNSVRFRCkgeworICAgICAgc2l6ZSArPSBXaXJlRm9ybWF0TGl0ZTo6a01lc3NhZ2VTZXRJdGVtVGFnc1NpemU7CisgICAgICBzaXplICs9IGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6VmFyaW50U2l6ZTMyKGZpZWxkLm51bWJlcigpKTsKKworICAgICAgaW50IGZpZWxkX3NpemUgPSBmaWVsZC5HZXRMZW5ndGhEZWxpbWl0ZWRTaXplKCk7CisgICAgICBzaXplICs9IGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6VmFyaW50U2l6ZTMyKGZpZWxkX3NpemUpOworICAgICAgc2l6ZSArPSBmaWVsZF9zaXplOworICAgIH0KKyAgfQorCisgIHJldHVybiBzaXplOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK2Jvb2wgV2lyZUZvcm1hdDo6UGFyc2VBbmRNZXJnZVBhcnRpYWwoaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlKiBtZXNzYWdlKSB7CisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBtZXNzYWdlLT5HZXREZXNjcmlwdG9yKCk7CisgIGNvbnN0IFJlZmxlY3Rpb24qIG1lc3NhZ2VfcmVmbGVjdGlvbiA9IG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKTsKKworICB3aGlsZSh0cnVlKSB7CisgICAgdWludDMyIHRhZyA9IGlucHV0LT5SZWFkVGFnKCk7CisgICAgaWYgKHRhZyA9PSAwKSB7CisgICAgICAvLyBFbmQgb2YgaW5wdXQuICBUaGlzIGlzIGEgdmFsaWQgcGxhY2UgdG8gZW5kLCBzbyByZXR1cm4gdHJ1ZS4KKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIGlmIChXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnV2lyZVR5cGUodGFnKSA9PQorICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRU5EX0dST1VQKSB7CisgICAgICAvLyBNdXN0IGJlIHRoZSBlbmQgb2YgdGhlIG1lc3NhZ2UuCisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkID0gTlVMTDsKKworICAgIGlmIChkZXNjcmlwdG9yICE9IE5VTEwpIHsKKyAgICAgIGludCBmaWVsZF9udW1iZXIgPSBXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnRmllbGROdW1iZXIodGFnKTsKKyAgICAgIGZpZWxkID0gZGVzY3JpcHRvci0+RmluZEZpZWxkQnlOdW1iZXIoZmllbGRfbnVtYmVyKTsKKworICAgICAgLy8gSWYgdGhhdCBmYWlsZWQsIGNoZWNrIGlmIHRoZSBmaWVsZCBpcyBhbiBleHRlbnNpb24uCisgICAgICBpZiAoZmllbGQgPT0gTlVMTCAmJiBkZXNjcmlwdG9yLT5Jc0V4dGVuc2lvbk51bWJlcihmaWVsZF9udW1iZXIpKSB7CisgICAgICAgIGlmIChpbnB1dC0+R2V0RXh0ZW5zaW9uUG9vbCgpID09IE5VTEwpIHsKKyAgICAgICAgICBmaWVsZCA9IG1lc3NhZ2VfcmVmbGVjdGlvbi0+RmluZEtub3duRXh0ZW5zaW9uQnlOdW1iZXIoZmllbGRfbnVtYmVyKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBmaWVsZCA9IGlucHV0LT5HZXRFeHRlbnNpb25Qb29sKCkKKyAgICAgICAgICAgICAgICAgICAgICAgLT5GaW5kRXh0ZW5zaW9uQnlOdW1iZXIoZGVzY3JpcHRvciwgZmllbGRfbnVtYmVyKTsKKyAgICAgICAgfQorICAgICAgfQorCisgICAgICAvLyBJZiB0aGF0IGZhaWxlZCwgYnV0IHdlJ3JlIGEgTWVzc2FnZVNldCwgYW5kIHRoaXMgaXMgdGhlIHRhZyBmb3IgYQorICAgICAgLy8gTWVzc2FnZVNldCBpdGVtLCB0aGVuIHBhcnNlIHRoYXQuCisgICAgICBpZiAoZmllbGQgPT0gTlVMTCAmJgorICAgICAgICAgIGRlc2NyaXB0b3ItPm9wdGlvbnMoKS5tZXNzYWdlX3NldF93aXJlX2Zvcm1hdCgpICYmCisgICAgICAgICAgdGFnID09IFdpcmVGb3JtYXRMaXRlOjprTWVzc2FnZVNldEl0ZW1TdGFydFRhZykgeworICAgICAgICBpZiAoIVBhcnNlQW5kTWVyZ2VNZXNzYWdlU2V0SXRlbShpbnB1dCwgbWVzc2FnZSkpIHsKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgY29udGludWU7ICAvLyBTa2lwIFBhcnNlQW5kTWVyZ2VGaWVsZCgpOyBhbHJlYWR5IHRha2VuIGNhcmUgb2YuCisgICAgICB9CisgICAgfQorCisgICAgaWYgKCFQYXJzZUFuZE1lcmdlRmllbGQodGFnLCBmaWVsZCwgbWVzc2FnZSwgaW5wdXQpKSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICB9Cit9CisKK2Jvb2wgV2lyZUZvcm1hdDo6U2tpcE1lc3NhZ2VTZXRGaWVsZChpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDMyIGZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVbmtub3duRmllbGRTZXQqIHVua25vd25fZmllbGRzKSB7CisgIHVpbnQzMiBsZW5ndGg7CisgIGlmICghaW5wdXQtPlJlYWRWYXJpbnQzMigmbGVuZ3RoKSkgcmV0dXJuIGZhbHNlOworICByZXR1cm4gaW5wdXQtPlJlYWRTdHJpbmcoCisgICAgICB1bmtub3duX2ZpZWxkcy0+QWRkTGVuZ3RoRGVsaW1pdGVkKGZpZWxkX251bWJlciksIGxlbmd0aCk7Cit9CisKK2Jvb2wgV2lyZUZvcm1hdDo6UGFyc2VBbmRNZXJnZU1lc3NhZ2VTZXRGaWVsZCh1aW50MzIgZmllbGRfbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZSogbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyAgY29uc3QgUmVmbGVjdGlvbiogbWVzc2FnZV9yZWZsZWN0aW9uID0gbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpOworICBpZiAoZmllbGQgPT0gTlVMTCkgeworICAgIC8vIFdlIHN0b3JlIHVua25vd24gTWVzc2FnZVNldCBleHRlbnNpb25zIGFzIGdyb3Vwcy4KKyAgICByZXR1cm4gU2tpcE1lc3NhZ2VTZXRGaWVsZCgKKyAgICAgICAgaW5wdXQsIGZpZWxkX251bWJlciwgbWVzc2FnZV9yZWZsZWN0aW9uLT5NdXRhYmxlVW5rbm93bkZpZWxkcyhtZXNzYWdlKSk7CisgIH0gZWxzZSBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkgfHwKKyAgICAgICAgICAgICBmaWVsZC0+dHlwZSgpICE9IEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9NRVNTQUdFKSB7CisgICAgLy8gVGhpcyBzaG91bGRuJ3QgaGFwcGVuIGFzIHdlIG9ubHkgYWxsb3cgb3B0aW9uYWwgbWVzc2FnZSBleHRlbnNpb25zIHRvCisgICAgLy8gTWVzc2FnZVNldC4KKyAgICBHT09HTEVfTE9HKEVSUk9SKSA8PCAiRXh0ZW5zaW9ucyBvZiBNZXNzYWdlU2V0cyBtdXN0IGJlIG9wdGlvbmFsIG1lc3NhZ2VzLiI7CisgICAgcmV0dXJuIGZhbHNlOworICB9IGVsc2UgeworICAgIE1lc3NhZ2UqIHN1Yl9tZXNzYWdlID0gbWVzc2FnZV9yZWZsZWN0aW9uLT5NdXRhYmxlTWVzc2FnZSgKKyAgICAgICAgbWVzc2FnZSwgZmllbGQsIGlucHV0LT5HZXRFeHRlbnNpb25GYWN0b3J5KCkpOworICAgIHJldHVybiBXaXJlRm9ybWF0TGl0ZTo6UmVhZE1lc3NhZ2UoaW5wdXQsIHN1Yl9tZXNzYWdlKTsKKyAgfQorfQorCitzdGF0aWMgYm9vbCBTdHJpY3RVdGY4Q2hlY2soY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICByZXR1cm4gZmllbGQtPmZpbGUoKS0+c3ludGF4KCkgPT0gRmlsZURlc2NyaXB0b3I6OlNZTlRBWF9QUk9UTzM7Cit9CisKK2Jvb2wgV2lyZUZvcm1hdDo6UGFyc2VBbmRNZXJnZUZpZWxkKAorICAgIHVpbnQzMiB0YWcsCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwgICAgICAgIC8vIE1heSBiZSBOVUxMIGZvciB1bmtub3duCisgICAgTWVzc2FnZSogbWVzc2FnZSwKKyAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyAgY29uc3QgUmVmbGVjdGlvbiogbWVzc2FnZV9yZWZsZWN0aW9uID0gbWVzc2FnZS0+R2V0UmVmbGVjdGlvbigpOworCisgIGVudW0geyBVTktOT1dOLCBOT1JNQUxfRk9STUFULCBQQUNLRURfRk9STUFUIH0gdmFsdWVfZm9ybWF0OworCisgIGlmIChmaWVsZCA9PSBOVUxMKSB7CisgICAgdmFsdWVfZm9ybWF0ID0gVU5LTk9XTjsKKyAgfSBlbHNlIGlmIChXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnV2lyZVR5cGUodGFnKSA9PQorICAgICAgICAgICAgIFdpcmVUeXBlRm9yRmllbGRUeXBlKGZpZWxkLT50eXBlKCkpKSB7CisgICAgdmFsdWVfZm9ybWF0ID0gTk9STUFMX0ZPUk1BVDsKKyAgfSBlbHNlIGlmIChmaWVsZC0+aXNfcGFja2FibGUoKSAmJgorICAgICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpHZXRUYWdXaXJlVHlwZSh0YWcpID09CisgICAgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQpIHsKKyAgICB2YWx1ZV9mb3JtYXQgPSBQQUNLRURfRk9STUFUOworICB9IGVsc2UgeworICAgIC8vIFdlIGRvbid0IHJlY29nbml6ZSB0aGlzIGZpZWxkLiBFaXRoZXIgdGhlIGZpZWxkIG51bWJlciBpcyB1bmtub3duCisgICAgLy8gb3IgdGhlIHdpcmUgdHlwZSBkb2Vzbid0IG1hdGNoLiBQdXQgaXQgaW4gb3VyIHVua25vd24gZmllbGQgc2V0LgorICAgIHZhbHVlX2Zvcm1hdCA9IFVOS05PV047CisgIH0KKworICBpZiAodmFsdWVfZm9ybWF0ID09IFVOS05PV04pIHsKKyAgICByZXR1cm4gU2tpcEZpZWxkKGlucHV0LCB0YWcsCisgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlX3JlZmxlY3Rpb24tPk11dGFibGVVbmtub3duRmllbGRzKG1lc3NhZ2UpKTsKKyAgfSBlbHNlIGlmICh2YWx1ZV9mb3JtYXQgPT0gUEFDS0VEX0ZPUk1BVCkgeworICAgIHVpbnQzMiBsZW5ndGg7CisgICAgaWYgKCFpbnB1dC0+UmVhZFZhcmludDMyKCZsZW5ndGgpKSByZXR1cm4gZmFsc2U7CisgICAgaW86OkNvZGVkSW5wdXRTdHJlYW06OkxpbWl0IGxpbWl0ID0gaW5wdXQtPlB1c2hMaW1pdChsZW5ndGgpOworCisgICAgc3dpdGNoIChmaWVsZC0+dHlwZSgpKSB7CisjZGVmaW5lIEhBTkRMRV9QQUNLRURfVFlQRShUWVBFLCBDUFBUWVBFLCBDUFBUWVBFX01FVEhPRCkgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfIyNUWVBFOiB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgd2hpbGUgKGlucHV0LT5CeXRlc1VudGlsTGltaXQoKSA+IDApIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgQ1BQVFlQRSB2YWx1ZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgIGlmICghV2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICBDUFBUWVBFLCBXaXJlRm9ybWF0TGl0ZTo6VFlQRV8jI1RZUEU+KGlucHV0LCAmdmFsdWUpKSAgICAgICAgICBcCisgICAgICAgICAgICByZXR1cm4gZmFsc2U7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgIG1lc3NhZ2VfcmVmbGVjdGlvbi0+QWRkIyNDUFBUWVBFX01FVEhPRChtZXNzYWdlLCBmaWVsZCwgdmFsdWUpOyAgICAgIFwKKyAgICAgICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGJyZWFrOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgfQorCisgICAgICBIQU5ETEVfUEFDS0VEX1RZUEUoIElOVDMyLCAgaW50MzIsICBJbnQzMikKKyAgICAgIEhBTkRMRV9QQUNLRURfVFlQRSggSU5UNjQsICBpbnQ2NCwgIEludDY0KQorICAgICAgSEFORExFX1BBQ0tFRF9UWVBFKFNJTlQzMiwgIGludDMyLCAgSW50MzIpCisgICAgICBIQU5ETEVfUEFDS0VEX1RZUEUoU0lOVDY0LCAgaW50NjQsICBJbnQ2NCkKKyAgICAgIEhBTkRMRV9QQUNLRURfVFlQRShVSU5UMzIsIHVpbnQzMiwgVUludDMyKQorICAgICAgSEFORExFX1BBQ0tFRF9UWVBFKFVJTlQ2NCwgdWludDY0LCBVSW50NjQpCisKKyAgICAgIEhBTkRMRV9QQUNLRURfVFlQRSggRklYRUQzMiwgdWludDMyLCBVSW50MzIpCisgICAgICBIQU5ETEVfUEFDS0VEX1RZUEUoIEZJWEVENjQsIHVpbnQ2NCwgVUludDY0KQorICAgICAgSEFORExFX1BBQ0tFRF9UWVBFKFNGSVhFRDMyLCAgaW50MzIsICBJbnQzMikKKyAgICAgIEhBTkRMRV9QQUNLRURfVFlQRShTRklYRUQ2NCwgIGludDY0LCAgSW50NjQpCisKKyAgICAgIEhBTkRMRV9QQUNLRURfVFlQRShGTE9BVCAsIGZsb2F0ICwgRmxvYXQgKQorICAgICAgSEFORExFX1BBQ0tFRF9UWVBFKERPVUJMRSwgZG91YmxlLCBEb3VibGUpCisKKyAgICAgIEhBTkRMRV9QQUNLRURfVFlQRShCT09MLCBib29sLCBCb29sKQorI3VuZGVmIEhBTkRMRV9QQUNLRURfVFlQRQorCisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9FTlVNOiB7CisgICAgICAgIHdoaWxlIChpbnB1dC0+Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CisgICAgICAgICAgaW50IHZhbHVlOworICAgICAgICAgIGlmICghV2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8aW50LCBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9FTlVNPigKKyAgICAgICAgICAgICAgICAgIGlucHV0LCAmdmFsdWUpKSByZXR1cm4gZmFsc2U7CisgICAgICAgICAgaWYgKG1lc3NhZ2UtPkdldERlc2NyaXB0b3IoKS0+ZmlsZSgpLT5zeW50YXgoKSA9PQorICAgICAgICAgICAgICBGaWxlRGVzY3JpcHRvcjo6U1lOVEFYX1BST1RPMykgeworICAgICAgICAgICAgbWVzc2FnZV9yZWZsZWN0aW9uLT5BZGRFbnVtVmFsdWUobWVzc2FnZSwgZmllbGQsIHZhbHVlKTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogZW51bV92YWx1ZSA9CisgICAgICAgICAgICAgICAgZmllbGQtPmVudW1fdHlwZSgpLT5GaW5kVmFsdWVCeU51bWJlcih2YWx1ZSk7CisgICAgICAgICAgICBpZiAoZW51bV92YWx1ZSAhPSBOVUxMKSB7CisgICAgICAgICAgICAgIG1lc3NhZ2VfcmVmbGVjdGlvbi0+QWRkRW51bShtZXNzYWdlLCBmaWVsZCwgZW51bV92YWx1ZSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAvLyBUaGUgZW51bSB2YWx1ZSBpcyBub3Qgb25lIG9mIHRoZSBrbm93biB2YWx1ZXMuICBBZGQgaXQgdG8gdGhlCisgICAgICAgICAgICAgIC8vIFVua25vd25GaWVsZFNldC4KKyAgICAgICAgICAgICAgaW50NjQgc2lnbl9leHRlbmRlZF92YWx1ZSA9IHN0YXRpY19jYXN0PGludDY0Pih2YWx1ZSk7CisgICAgICAgICAgICAgIG1lc3NhZ2VfcmVmbGVjdGlvbi0+TXV0YWJsZVVua25vd25GaWVsZHMobWVzc2FnZSkKKyAgICAgICAgICAgICAgICAgIC0+QWRkVmFyaW50KAorICAgICAgICAgICAgICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpHZXRUYWdGaWVsZE51bWJlcih0YWcpLAorICAgICAgICAgICAgICAgICAgICAgIHNpZ25fZXh0ZW5kZWRfdmFsdWUpOworICAgICAgICAgICAgfQorICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9TVFJJTkc6CisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9HUk9VUDoKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX01FU1NBR0U6CisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9CWVRFUzoKKyAgICAgICAgLy8gQ2FuJ3QgaGF2ZSBwYWNrZWQgZmllbGRzIG9mIHRoZXNlIHR5cGVzOiB0aGVzZSBzaG91bGQgYmUgY2F1Z2h0IGJ5CisgICAgICAgIC8vIHRoZSBwcm90b2NvbCBjb21waWxlci4KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBicmVhazsKKyAgICB9CisKKyAgICBpbnB1dC0+UG9wTGltaXQobGltaXQpOworICB9IGVsc2UgeworICAgIC8vIE5vbi1wYWNrZWQgdmFsdWUgKHZhbHVlX2Zvcm1hdCA9PSBOT1JNQUxfRk9STUFUKQorICAgIHN3aXRjaCAoZmllbGQtPnR5cGUoKSkgeworI2RlZmluZSBIQU5ETEVfVFlQRShUWVBFLCBDUFBUWVBFLCBDUFBUWVBFX01FVEhPRCkgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfIyNUWVBFOiB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBDUFBUWVBFIHZhbHVlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBpZiAoIVdpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgIENQUFRZUEUsIFdpcmVGb3JtYXRMaXRlOjpUWVBFXyMjVFlQRT4oaW5wdXQsICZ2YWx1ZSkpICAgICAgICAgXAorICAgICAgICAgIHJldHVybiBmYWxzZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgIG1lc3NhZ2VfcmVmbGVjdGlvbi0+QWRkIyNDUFBUWVBFX01FVEhPRChtZXNzYWdlLCBmaWVsZCwgdmFsdWUpOyAgICAgXAorICAgICAgICB9IGVsc2UgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgIG1lc3NhZ2VfcmVmbGVjdGlvbi0+U2V0IyNDUFBUWVBFX01FVEhPRChtZXNzYWdlLCBmaWVsZCwgdmFsdWUpOyAgICAgXAorICAgICAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBicmVhazsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgfQorCisgICAgICBIQU5ETEVfVFlQRSggSU5UMzIsICBpbnQzMiwgIEludDMyKQorICAgICAgSEFORExFX1RZUEUoIElOVDY0LCAgaW50NjQsICBJbnQ2NCkKKyAgICAgIEhBTkRMRV9UWVBFKFNJTlQzMiwgIGludDMyLCAgSW50MzIpCisgICAgICBIQU5ETEVfVFlQRShTSU5UNjQsICBpbnQ2NCwgIEludDY0KQorICAgICAgSEFORExFX1RZUEUoVUlOVDMyLCB1aW50MzIsIFVJbnQzMikKKyAgICAgIEhBTkRMRV9UWVBFKFVJTlQ2NCwgdWludDY0LCBVSW50NjQpCisKKyAgICAgIEhBTkRMRV9UWVBFKCBGSVhFRDMyLCB1aW50MzIsIFVJbnQzMikKKyAgICAgIEhBTkRMRV9UWVBFKCBGSVhFRDY0LCB1aW50NjQsIFVJbnQ2NCkKKyAgICAgIEhBTkRMRV9UWVBFKFNGSVhFRDMyLCAgaW50MzIsICBJbnQzMikKKyAgICAgIEhBTkRMRV9UWVBFKFNGSVhFRDY0LCAgaW50NjQsICBJbnQ2NCkKKworICAgICAgSEFORExFX1RZUEUoRkxPQVQgLCBmbG9hdCAsIEZsb2F0ICkKKyAgICAgIEhBTkRMRV9UWVBFKERPVUJMRSwgZG91YmxlLCBEb3VibGUpCisKKyAgICAgIEhBTkRMRV9UWVBFKEJPT0wsIGJvb2wsIEJvb2wpCisjdW5kZWYgSEFORExFX1RZUEUKKworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfRU5VTTogeworICAgICAgICBpbnQgdmFsdWU7CisgICAgICAgIGlmICghV2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8aW50LCBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9FTlVNPigKKyAgICAgICAgICAgICAgICBpbnB1dCwgJnZhbHVlKSkgcmV0dXJuIGZhbHNlOworICAgICAgICBpZiAobWVzc2FnZS0+R2V0RGVzY3JpcHRvcigpLT5maWxlKCktPnN5bnRheCgpID09CisgICAgICAgICAgICBGaWxlRGVzY3JpcHRvcjo6U1lOVEFYX1BST1RPMykgeworICAgICAgICAgIGlmIChmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgeworICAgICAgICAgICAgbWVzc2FnZV9yZWZsZWN0aW9uLT5BZGRFbnVtVmFsdWUobWVzc2FnZSwgZmllbGQsIHZhbHVlKTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgbWVzc2FnZV9yZWZsZWN0aW9uLT5TZXRFbnVtVmFsdWUobWVzc2FnZSwgZmllbGQsIHZhbHVlKTsKKyAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogZW51bV92YWx1ZSA9CisgICAgICAgICAgICAgIGZpZWxkLT5lbnVtX3R5cGUoKS0+RmluZFZhbHVlQnlOdW1iZXIodmFsdWUpOworICAgICAgICAgIGlmIChlbnVtX3ZhbHVlICE9IE5VTEwpIHsKKyAgICAgICAgICAgIGlmIChmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgeworICAgICAgICAgICAgICBtZXNzYWdlX3JlZmxlY3Rpb24tPkFkZEVudW0obWVzc2FnZSwgZmllbGQsIGVudW1fdmFsdWUpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgbWVzc2FnZV9yZWZsZWN0aW9uLT5TZXRFbnVtKG1lc3NhZ2UsIGZpZWxkLCBlbnVtX3ZhbHVlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gVGhlIGVudW0gdmFsdWUgaXMgbm90IG9uZSBvZiB0aGUga25vd24gdmFsdWVzLiAgQWRkIGl0IHRvIHRoZQorICAgICAgICAgICAgLy8gVW5rbm93bkZpZWxkU2V0LgorICAgICAgICAgICAgaW50NjQgc2lnbl9leHRlbmRlZF92YWx1ZSA9IHN0YXRpY19jYXN0PGludDY0Pih2YWx1ZSk7CisgICAgICAgICAgICBtZXNzYWdlX3JlZmxlY3Rpb24tPk11dGFibGVVbmtub3duRmllbGRzKG1lc3NhZ2UpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtPkFkZFZhcmludCgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnRmllbGROdW1iZXIodGFnKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaWduX2V4dGVuZGVkX3ZhbHVlKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIC8vIEhhbmRsZSBzdHJpbmdzIHNlcGFyYXRlbHkgc28gdGhhdCB3ZSBjYW4gb3B0aW1pemUgdGhlIGN0eXBlPUNPUkQgY2FzZS4KKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NUUklORzogeworICAgICAgICBib29sIHN0cmljdF91dGY4X2NoZWNrID0gU3RyaWN0VXRmOENoZWNrKGZpZWxkKTsKKyAgICAgICAgc3RyaW5nIHZhbHVlOworICAgICAgICBpZiAoIVdpcmVGb3JtYXRMaXRlOjpSZWFkU3RyaW5nKGlucHV0LCAmdmFsdWUpKSByZXR1cm4gZmFsc2U7CisgICAgICAgIGlmIChzdHJpY3RfdXRmOF9jaGVjaykgeworICAgICAgICAgIGlmICghV2lyZUZvcm1hdExpdGU6OlZlcmlmeVV0ZjhTdHJpbmcoCisgICAgICAgICAgICAgICAgICB2YWx1ZS5kYXRhKCksIHZhbHVlLmxlbmd0aCgpLCBXaXJlRm9ybWF0TGl0ZTo6UEFSU0UsCisgICAgICAgICAgICAgICAgICBmaWVsZC0+ZnVsbF9uYW1lKCkuY19zdHIoKSkpIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICB9CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgVmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQodmFsdWUuZGF0YSgpLCB2YWx1ZS5sZW5ndGgoKSwgUEFSU0UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGQtPmZ1bGxfbmFtZSgpLmNfc3RyKCkpOworICAgICAgICB9CisgICAgICAgIGlmIChmaWVsZC0+aXNfcmVwZWF0ZWQoKSkgeworICAgICAgICAgIG1lc3NhZ2VfcmVmbGVjdGlvbi0+QWRkU3RyaW5nKG1lc3NhZ2UsIGZpZWxkLCB2YWx1ZSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgbWVzc2FnZV9yZWZsZWN0aW9uLT5TZXRTdHJpbmcobWVzc2FnZSwgZmllbGQsIHZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfQllURVM6IHsKKyAgICAgICAgc3RyaW5nIHZhbHVlOworICAgICAgICBpZiAoIVdpcmVGb3JtYXRMaXRlOjpSZWFkQnl0ZXMoaW5wdXQsICZ2YWx1ZSkpIHJldHVybiBmYWxzZTsKKyAgICAgICAgaWYgKGZpZWxkLT5pc19yZXBlYXRlZCgpKSB7CisgICAgICAgICAgbWVzc2FnZV9yZWZsZWN0aW9uLT5BZGRTdHJpbmcobWVzc2FnZSwgZmllbGQsIHZhbHVlKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBtZXNzYWdlX3JlZmxlY3Rpb24tPlNldFN0cmluZyhtZXNzYWdlLCBmaWVsZCwgdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9HUk9VUDogeworICAgICAgICBNZXNzYWdlKiBzdWJfbWVzc2FnZTsKKyAgICAgICAgaWYgKGZpZWxkLT5pc19yZXBlYXRlZCgpKSB7CisgICAgICAgICAgc3ViX21lc3NhZ2UgPSBtZXNzYWdlX3JlZmxlY3Rpb24tPkFkZE1lc3NhZ2UoCisgICAgICAgICAgICAgIG1lc3NhZ2UsIGZpZWxkLCBpbnB1dC0+R2V0RXh0ZW5zaW9uRmFjdG9yeSgpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzdWJfbWVzc2FnZSA9IG1lc3NhZ2VfcmVmbGVjdGlvbi0+TXV0YWJsZU1lc3NhZ2UoCisgICAgICAgICAgICAgIG1lc3NhZ2UsIGZpZWxkLCBpbnB1dC0+R2V0RXh0ZW5zaW9uRmFjdG9yeSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICghV2lyZUZvcm1hdExpdGU6OlJlYWRHcm91cChXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnRmllbGROdW1iZXIodGFnKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0LCBzdWJfbWVzc2FnZSkpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfTUVTU0FHRTogeworICAgICAgICBNZXNzYWdlKiBzdWJfbWVzc2FnZTsKKyAgICAgICAgaWYgKGZpZWxkLT5pc19yZXBlYXRlZCgpKSB7CisgICAgICAgICAgc3ViX21lc3NhZ2UgPSBtZXNzYWdlX3JlZmxlY3Rpb24tPkFkZE1lc3NhZ2UoCisgICAgICAgICAgICAgIG1lc3NhZ2UsIGZpZWxkLCBpbnB1dC0+R2V0RXh0ZW5zaW9uRmFjdG9yeSgpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBzdWJfbWVzc2FnZSA9IG1lc3NhZ2VfcmVmbGVjdGlvbi0+TXV0YWJsZU1lc3NhZ2UoCisgICAgICAgICAgICAgIG1lc3NhZ2UsIGZpZWxkLCBpbnB1dC0+R2V0RXh0ZW5zaW9uRmFjdG9yeSgpKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICghV2lyZUZvcm1hdExpdGU6OlJlYWRNZXNzYWdlKGlucHV0LCBzdWJfbWVzc2FnZSkpIHJldHVybiBmYWxzZTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK2Jvb2wgV2lyZUZvcm1hdDo6UGFyc2VBbmRNZXJnZU1lc3NhZ2VTZXRJdGVtKAorICAgIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICBNZXNzYWdlKiBtZXNzYWdlKSB7CisgIGNvbnN0IFJlZmxlY3Rpb24qIG1lc3NhZ2VfcmVmbGVjdGlvbiA9IG1lc3NhZ2UtPkdldFJlZmxlY3Rpb24oKTsKKworICAvLyBUaGlzIG1ldGhvZCBwYXJzZXMgYSBncm91cCB3aGljaCBzaG91bGQgY29udGFpbiB0d28gZmllbGRzOgorICAvLyAgIHJlcXVpcmVkIGludDMyIHR5cGVfaWQgPSAyOworICAvLyAgIHJlcXVpcmVkIGRhdGEgbWVzc2FnZSA9IDM7CisKKyAgdWludDMyIGxhc3RfdHlwZV9pZCA9IDA7CisKKyAgLy8gT25jZSB3ZSBzZWUgYSB0eXBlX2lkLCB3ZSdsbCBsb29rIHVwIHRoZSBGaWVsZERlc2NyaXB0b3IgZm9yIHRoZQorICAvLyBleHRlbnNpb24uCisgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPSBOVUxMOworCisgIC8vIElmIHdlIHNlZSBtZXNzYWdlIGRhdGEgYmVmb3JlIHRoZSB0eXBlX2lkLCB3ZSdsbCBhcHBlbmQgaXQgdG8gdGhpcyBzbworICAvLyB3ZSBjYW4gcGFyc2UgaXQgbGF0ZXIuCisgIHN0cmluZyBtZXNzYWdlX2RhdGE7CisKKyAgd2hpbGUgKHRydWUpIHsKKyAgICB1aW50MzIgdGFnID0gaW5wdXQtPlJlYWRUYWcoKTsKKyAgICBpZiAodGFnID09IDApIHJldHVybiBmYWxzZTsKKworICAgIHN3aXRjaCAodGFnKSB7CisgICAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjprTWVzc2FnZVNldFR5cGVJZFRhZzogeworICAgICAgICB1aW50MzIgdHlwZV9pZDsKKyAgICAgICAgaWYgKCFpbnB1dC0+UmVhZFZhcmludDMyKCZ0eXBlX2lkKSkgcmV0dXJuIGZhbHNlOworICAgICAgICBsYXN0X3R5cGVfaWQgPSB0eXBlX2lkOworICAgICAgICBmaWVsZCA9IG1lc3NhZ2VfcmVmbGVjdGlvbi0+RmluZEtub3duRXh0ZW5zaW9uQnlOdW1iZXIodHlwZV9pZCk7CisKKyAgICAgICAgaWYgKCFtZXNzYWdlX2RhdGEuZW1wdHkoKSkgeworICAgICAgICAgIC8vIFdlIHNhdyBzb21lIG1lc3NhZ2UgZGF0YSBiZWZvcmUgdGhlIHR5cGVfaWQuICBIYXZlIHRvIHBhcnNlIGl0CisgICAgICAgICAgLy8gbm93LgorICAgICAgICAgIGlvOjpBcnJheUlucHV0U3RyZWFtIHJhd19pbnB1dChtZXNzYWdlX2RhdGEuZGF0YSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlX2RhdGEuc2l6ZSgpKTsKKyAgICAgICAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSBzdWJfaW5wdXQoJnJhd19pbnB1dCk7CisgICAgICAgICAgaWYgKCFQYXJzZUFuZE1lcmdlTWVzc2FnZVNldEZpZWxkKGxhc3RfdHlwZV9pZCwgZmllbGQsIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZzdWJfaW5wdXQpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgfQorICAgICAgICAgIG1lc3NhZ2VfZGF0YS5jbGVhcigpOworICAgICAgICB9CisKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OmtNZXNzYWdlU2V0TWVzc2FnZVRhZzogeworICAgICAgICBpZiAobGFzdF90eXBlX2lkID09IDApIHsKKyAgICAgICAgICAvLyBXZSBoYXZlbid0IHNlZW4gYSB0eXBlX2lkIHlldC4gIEFwcGVuZCB0aGlzIGRhdGEgdG8gbWVzc2FnZV9kYXRhLgorICAgICAgICAgIHN0cmluZyB0ZW1wOworICAgICAgICAgIHVpbnQzMiBsZW5ndGg7CisgICAgICAgICAgaWYgKCFpbnB1dC0+UmVhZFZhcmludDMyKCZsZW5ndGgpKSByZXR1cm4gZmFsc2U7CisgICAgICAgICAgaWYgKCFpbnB1dC0+UmVhZFN0cmluZygmdGVtcCwgbGVuZ3RoKSkgcmV0dXJuIGZhbHNlOworICAgICAgICAgIGlvOjpTdHJpbmdPdXRwdXRTdHJlYW0gb3V0cHV0X3N0cmVhbSgmbWVzc2FnZV9kYXRhKTsKKyAgICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0gY29kZWRfb3V0cHV0KCZvdXRwdXRfc3RyZWFtKTsKKyAgICAgICAgICBjb2RlZF9vdXRwdXQuV3JpdGVWYXJpbnQzMihsZW5ndGgpOworICAgICAgICAgIGNvZGVkX291dHB1dC5Xcml0ZVN0cmluZyh0ZW1wKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAvLyBBbHJlYWR5IHNhdyB0eXBlX2lkLCBzbyB3ZSBjYW4gcGFyc2UgdGhpcyBkaXJlY3RseS4KKyAgICAgICAgICBpZiAoIVBhcnNlQW5kTWVyZ2VNZXNzYWdlU2V0RmllbGQobGFzdF90eXBlX2lkLCBmaWVsZCwgbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQpKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OmtNZXNzYWdlU2V0SXRlbUVuZFRhZzogeworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0KKworICAgICAgZGVmYXVsdDogeworICAgICAgICBpZiAoIVNraXBGaWVsZChpbnB1dCwgdGFnLCBOVUxMKSkgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgIH0KKyAgfQorfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK3ZvaWQgV2lyZUZvcm1hdDo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgaW50IHNpemUsIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSB7CisgIGNvbnN0IERlc2NyaXB0b3IqIGRlc2NyaXB0b3IgPSBtZXNzYWdlLkdldERlc2NyaXB0b3IoKTsKKyAgY29uc3QgUmVmbGVjdGlvbiogbWVzc2FnZV9yZWZsZWN0aW9uID0gbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCk7CisgIGludCBleHBlY3RlZF9lbmRwb2ludCA9IG91dHB1dC0+Qnl0ZUNvdW50KCkgKyBzaXplOworCisgIHZlY3Rvcjxjb25zdCBGaWVsZERlc2NyaXB0b3IqPiBmaWVsZHM7CisgIG1lc3NhZ2VfcmVmbGVjdGlvbi0+TGlzdEZpZWxkcyhtZXNzYWdlLCAmZmllbGRzKTsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZHMuc2l6ZSgpOyBpKyspIHsKKyAgICBTZXJpYWxpemVGaWVsZFdpdGhDYWNoZWRTaXplcyhmaWVsZHNbaV0sIG1lc3NhZ2UsIG91dHB1dCk7CisgIH0KKworICBpZiAoZGVzY3JpcHRvci0+b3B0aW9ucygpLm1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KCkpIHsKKyAgICBTZXJpYWxpemVVbmtub3duTWVzc2FnZVNldEl0ZW1zKAorICAgICAgICBtZXNzYWdlX3JlZmxlY3Rpb24tPkdldFVua25vd25GaWVsZHMobWVzc2FnZSksIG91dHB1dCk7CisgIH0gZWxzZSB7CisgICAgU2VyaWFsaXplVW5rbm93bkZpZWxkcygKKyAgICAgICAgbWVzc2FnZV9yZWZsZWN0aW9uLT5HZXRVbmtub3duRmllbGRzKG1lc3NhZ2UpLCBvdXRwdXQpOworICB9CisKKyAgR09PR0xFX0NIRUNLX0VRKG91dHB1dC0+Qnl0ZUNvdW50KCksIGV4cGVjdGVkX2VuZHBvaW50KQorICAgIDw8ICI6IFByb3RvY29sIG1lc3NhZ2Ugc2VyaWFsaXplZCB0byBhIHNpemUgZGlmZmVyZW50IGZyb20gd2hhdCB3YXMgIgorICAgICAgICJvcmlnaW5hbGx5IGV4cGVjdGVkLiAgUGVyaGFwcyBpdCB3YXMgbW9kaWZpZWQgYnkgYW5vdGhlciB0aHJlYWQgIgorICAgICAgICJkdXJpbmcgc2VyaWFsaXphdGlvbj8iOworfQorCit2b2lkIFdpcmVGb3JtYXQ6OlNlcmlhbGl6ZUZpZWxkV2l0aENhY2hlZFNpemVzKAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgeworICBjb25zdCBSZWZsZWN0aW9uKiBtZXNzYWdlX3JlZmxlY3Rpb24gPSBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKTsKKworICBpZiAoZmllbGQtPmlzX2V4dGVuc2lvbigpICYmCisgICAgICBmaWVsZC0+Y29udGFpbmluZ190eXBlKCktPm9wdGlvbnMoKS5tZXNzYWdlX3NldF93aXJlX2Zvcm1hdCgpICYmCisgICAgICBmaWVsZC0+Y3BwX3R5cGUoKSA9PSBGaWVsZERlc2NyaXB0b3I6OkNQUFRZUEVfTUVTU0FHRSAmJgorICAgICAgIWZpZWxkLT5pc19yZXBlYXRlZCgpKSB7CisgICAgU2VyaWFsaXplTWVzc2FnZVNldEl0ZW1XaXRoQ2FjaGVkU2l6ZXMoZmllbGQsIG1lc3NhZ2UsIG91dHB1dCk7CisgICAgcmV0dXJuOworICB9CisKKyAgaW50IGNvdW50ID0gMDsKKworICBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkpIHsKKyAgICBjb3VudCA9IG1lc3NhZ2VfcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIGZpZWxkKTsKKyAgfSBlbHNlIGlmIChtZXNzYWdlX3JlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIGZpZWxkKSkgeworICAgIGNvdW50ID0gMTsKKyAgfQorCisgIGNvbnN0IGJvb2wgaXNfcGFja2VkID0gZmllbGQtPmlzX3BhY2tlZCgpOworICBpZiAoaXNfcGFja2VkICYmIGNvdW50ID4gMCkgeworICAgIFdpcmVGb3JtYXRMaXRlOjpXcml0ZVRhZyhmaWVsZC0+bnVtYmVyKCksCisgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVELCBvdXRwdXQpOworICAgIGNvbnN0IGludCBkYXRhX3NpemUgPSBGaWVsZERhdGFPbmx5Qnl0ZVNpemUoZmllbGQsIG1lc3NhZ2UpOworICAgIG91dHB1dC0+V3JpdGVWYXJpbnQzMihkYXRhX3NpemUpOworICB9CisKKyAgZm9yIChpbnQgaiA9IDA7IGogPCBjb3VudDsgaisrKSB7CisgICAgc3dpdGNoIChmaWVsZC0+dHlwZSgpKSB7CisjZGVmaW5lIEhBTkRMRV9QUklNSVRJVkVfVFlQRShUWVBFLCBDUFBUWVBFLCBUWVBFX01FVEhPRCwgQ1BQVFlQRV9NRVRIT0QpICAgICAgXAorICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfIyNUWVBFOiB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgY29uc3QgQ1BQVFlQRSB2YWx1ZSA9IGZpZWxkLT5pc19yZXBlYXRlZCgpID8gICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlX3JlZmxlY3Rpb24tPkdldFJlcGVhdGVkIyNDUFBUWVBFX01FVEhPRCggXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLCBmaWVsZCwgaikgOiAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2VfcmVmbGVjdGlvbi0+R2V0IyNDUFBUWVBFX01FVEhPRCggICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UsIGZpZWxkKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBpZiAoaXNfcGFja2VkKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6V3JpdGUjI1RZUEVfTUVUSE9EIyNOb1RhZyh2YWx1ZSwgb3V0cHV0KTsgICAgICAgICAgICBcCisgICAgICAgIH0gZWxzZSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpXcml0ZSMjVFlQRV9NRVRIT0QoZmllbGQtPm51bWJlcigpLCB2YWx1ZSwgb3V0cHV0KTsgIFwKKyAgICAgICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGJyZWFrOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgfQorCisgICAgICBIQU5ETEVfUFJJTUlUSVZFX1RZUEUoIElOVDMyLCAgaW50MzIsICBJbnQzMiwgIEludDMyKQorICAgICAgSEFORExFX1BSSU1JVElWRV9UWVBFKCBJTlQ2NCwgIGludDY0LCAgSW50NjQsICBJbnQ2NCkKKyAgICAgIEhBTkRMRV9QUklNSVRJVkVfVFlQRShTSU5UMzIsICBpbnQzMiwgU0ludDMyLCAgSW50MzIpCisgICAgICBIQU5ETEVfUFJJTUlUSVZFX1RZUEUoU0lOVDY0LCAgaW50NjQsIFNJbnQ2NCwgIEludDY0KQorICAgICAgSEFORExFX1BSSU1JVElWRV9UWVBFKFVJTlQzMiwgdWludDMyLCBVSW50MzIsIFVJbnQzMikKKyAgICAgIEhBTkRMRV9QUklNSVRJVkVfVFlQRShVSU5UNjQsIHVpbnQ2NCwgVUludDY0LCBVSW50NjQpCisKKyAgICAgIEhBTkRMRV9QUklNSVRJVkVfVFlQRSggRklYRUQzMiwgdWludDMyLCAgRml4ZWQzMiwgVUludDMyKQorICAgICAgSEFORExFX1BSSU1JVElWRV9UWVBFKCBGSVhFRDY0LCB1aW50NjQsICBGaXhlZDY0LCBVSW50NjQpCisgICAgICBIQU5ETEVfUFJJTUlUSVZFX1RZUEUoU0ZJWEVEMzIsICBpbnQzMiwgU0ZpeGVkMzIsICBJbnQzMikKKyAgICAgIEhBTkRMRV9QUklNSVRJVkVfVFlQRShTRklYRUQ2NCwgIGludDY0LCBTRml4ZWQ2NCwgIEludDY0KQorCisgICAgICBIQU5ETEVfUFJJTUlUSVZFX1RZUEUoRkxPQVQgLCBmbG9hdCAsIEZsb2F0ICwgRmxvYXQgKQorICAgICAgSEFORExFX1BSSU1JVElWRV9UWVBFKERPVUJMRSwgZG91YmxlLCBEb3VibGUsIERvdWJsZSkKKworICAgICAgSEFORExFX1BSSU1JVElWRV9UWVBFKEJPT0wsIGJvb2wsIEJvb2wsIEJvb2wpCisjdW5kZWYgSEFORExFX1BSSU1JVElWRV9UWVBFCisKKyNkZWZpbmUgSEFORExFX1RZUEUoVFlQRSwgVFlQRV9NRVRIT0QsIENQUFRZUEVfTUVUSE9EKSAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfIyNUWVBFOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpXcml0ZSMjVFlQRV9NRVRIT0QoICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgZmllbGQtPm51bWJlcigpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICBmaWVsZC0+aXNfcmVwZWF0ZWQoKSA/ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgbWVzc2FnZV9yZWZsZWN0aW9uLT5HZXRSZXBlYXRlZCMjQ1BQVFlQRV9NRVRIT0QoICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgIG1lc3NhZ2UsIGZpZWxkLCBqKSA6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgIG1lc3NhZ2VfcmVmbGVjdGlvbi0+R2V0IyNDUFBUWVBFX01FVEhPRChtZXNzYWdlLCBmaWVsZCksICAgICBcCisgICAgICAgICAgICAgIG91dHB1dCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgYnJlYWs7CisKKyAgICAgIEhBTkRMRV9UWVBFKEdST1VQICAsIEdyb3VwICAsIE1lc3NhZ2UpCisgICAgICBIQU5ETEVfVFlQRShNRVNTQUdFLCBNZXNzYWdlLCBNZXNzYWdlKQorI3VuZGVmIEhBTkRMRV9UWVBFCisKKyAgICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX0VOVU06IHsKKyAgICAgICAgY29uc3QgRW51bVZhbHVlRGVzY3JpcHRvciogdmFsdWUgPSBmaWVsZC0+aXNfcmVwZWF0ZWQoKSA/CisgICAgICAgICAgbWVzc2FnZV9yZWZsZWN0aW9uLT5HZXRSZXBlYXRlZEVudW0obWVzc2FnZSwgZmllbGQsIGopIDoKKyAgICAgICAgICBtZXNzYWdlX3JlZmxlY3Rpb24tPkdldEVudW0obWVzc2FnZSwgZmllbGQpOworICAgICAgICBpZiAoaXNfcGFja2VkKSB7CisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OldyaXRlRW51bU5vVGFnKHZhbHVlLT5udW1iZXIoKSwgb3V0cHV0KTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVFbnVtKGZpZWxkLT5udW1iZXIoKSwgdmFsdWUtPm51bWJlcigpLCBvdXRwdXQpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICAvLyBIYW5kbGUgc3RyaW5ncyBzZXBhcmF0ZWx5IHNvIHRoYXQgd2UgY2FuIGdldCBzdHJpbmcgcmVmZXJlbmNlcworICAgICAgLy8gaW5zdGVhZCBvZiBjb3B5aW5nLgorICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU1RSSU5HOiB7CisgICAgICAgIGJvb2wgc3RyaWN0X3V0ZjhfY2hlY2sgPSBTdHJpY3RVdGY4Q2hlY2soZmllbGQpOworICAgICAgICBzdHJpbmcgc2NyYXRjaDsKKyAgICAgICAgY29uc3Qgc3RyaW5nJiB2YWx1ZSA9IGZpZWxkLT5pc19yZXBlYXRlZCgpID8KKyAgICAgICAgICBtZXNzYWdlX3JlZmxlY3Rpb24tPkdldFJlcGVhdGVkU3RyaW5nUmVmZXJlbmNlKAorICAgICAgICAgICAgbWVzc2FnZSwgZmllbGQsIGosICZzY3JhdGNoKSA6CisgICAgICAgICAgbWVzc2FnZV9yZWZsZWN0aW9uLT5HZXRTdHJpbmdSZWZlcmVuY2UobWVzc2FnZSwgZmllbGQsICZzY3JhdGNoKTsKKyAgICAgICAgaWYgKHN0cmljdF91dGY4X2NoZWNrKSB7CisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OlZlcmlmeVV0ZjhTdHJpbmcodmFsdWUuZGF0YSgpLCB2YWx1ZS5sZW5ndGgoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6U0VSSUFMSVpFLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkLT5mdWxsX25hbWUoKS5jX3N0cigpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCh2YWx1ZS5kYXRhKCksIHZhbHVlLmxlbmd0aCgpLCBTRVJJQUxJWkUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGQtPmZ1bGxfbmFtZSgpLmNfc3RyKCkpOworICAgICAgICB9CisgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpXcml0ZVN0cmluZyhmaWVsZC0+bnVtYmVyKCksIHZhbHVlLCBvdXRwdXQpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfQllURVM6IHsKKyAgICAgICAgc3RyaW5nIHNjcmF0Y2g7CisgICAgICAgIGNvbnN0IHN0cmluZyYgdmFsdWUgPSBmaWVsZC0+aXNfcmVwZWF0ZWQoKSA/CisgICAgICAgICAgbWVzc2FnZV9yZWZsZWN0aW9uLT5HZXRSZXBlYXRlZFN0cmluZ1JlZmVyZW5jZSgKKyAgICAgICAgICAgIG1lc3NhZ2UsIGZpZWxkLCBqLCAmc2NyYXRjaCkgOgorICAgICAgICAgIG1lc3NhZ2VfcmVmbGVjdGlvbi0+R2V0U3RyaW5nUmVmZXJlbmNlKG1lc3NhZ2UsIGZpZWxkLCAmc2NyYXRjaCk7CisgICAgICAgIFdpcmVGb3JtYXRMaXRlOjpXcml0ZUJ5dGVzKGZpZWxkLT5udW1iZXIoKSwgdmFsdWUsIG91dHB1dCk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgfQorfQorCit2b2lkIFdpcmVGb3JtYXQ6OlNlcmlhbGl6ZU1lc3NhZ2VTZXRJdGVtV2l0aENhY2hlZFNpemVzKAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgeworICBjb25zdCBSZWZsZWN0aW9uKiBtZXNzYWdlX3JlZmxlY3Rpb24gPSBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKTsKKworICAvLyBTdGFydCBncm91cC4KKyAgb3V0cHV0LT5Xcml0ZVZhcmludDMyKFdpcmVGb3JtYXRMaXRlOjprTWVzc2FnZVNldEl0ZW1TdGFydFRhZyk7CisKKyAgLy8gV3JpdGUgdHlwZSBJRC4KKyAgb3V0cHV0LT5Xcml0ZVZhcmludDMyKFdpcmVGb3JtYXRMaXRlOjprTWVzc2FnZVNldFR5cGVJZFRhZyk7CisgIG91dHB1dC0+V3JpdGVWYXJpbnQzMihmaWVsZC0+bnVtYmVyKCkpOworCisgIC8vIFdyaXRlIG1lc3NhZ2UuCisgIG91dHB1dC0+V3JpdGVWYXJpbnQzMihXaXJlRm9ybWF0TGl0ZTo6a01lc3NhZ2VTZXRNZXNzYWdlVGFnKTsKKworICBjb25zdCBNZXNzYWdlJiBzdWJfbWVzc2FnZSA9IG1lc3NhZ2VfcmVmbGVjdGlvbi0+R2V0TWVzc2FnZShtZXNzYWdlLCBmaWVsZCk7CisgIG91dHB1dC0+V3JpdGVWYXJpbnQzMihzdWJfbWVzc2FnZS5HZXRDYWNoZWRTaXplKCkpOworICBzdWJfbWVzc2FnZS5TZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMob3V0cHV0KTsKKworICAvLyBFbmQgZ3JvdXAuCisgIG91dHB1dC0+V3JpdGVWYXJpbnQzMihXaXJlRm9ybWF0TGl0ZTo6a01lc3NhZ2VTZXRJdGVtRW5kVGFnKTsKK30KKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitpbnQgV2lyZUZvcm1hdDo6Qnl0ZVNpemUoY29uc3QgTWVzc2FnZSYgbWVzc2FnZSkgeworICBjb25zdCBEZXNjcmlwdG9yKiBkZXNjcmlwdG9yID0gbWVzc2FnZS5HZXREZXNjcmlwdG9yKCk7CisgIGNvbnN0IFJlZmxlY3Rpb24qIG1lc3NhZ2VfcmVmbGVjdGlvbiA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpOworCisgIGludCBvdXJfc2l6ZSA9IDA7CisKKyAgdmVjdG9yPGNvbnN0IEZpZWxkRGVzY3JpcHRvcio+IGZpZWxkczsKKyAgbWVzc2FnZV9yZWZsZWN0aW9uLT5MaXN0RmllbGRzKG1lc3NhZ2UsICZmaWVsZHMpOworICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkcy5zaXplKCk7IGkrKykgeworICAgIG91cl9zaXplICs9IEZpZWxkQnl0ZVNpemUoZmllbGRzW2ldLCBtZXNzYWdlKTsKKyAgfQorCisgIGlmIChkZXNjcmlwdG9yLT5vcHRpb25zKCkubWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQoKSkgeworICAgIG91cl9zaXplICs9IENvbXB1dGVVbmtub3duTWVzc2FnZVNldEl0ZW1zU2l6ZSgKKyAgICAgIG1lc3NhZ2VfcmVmbGVjdGlvbi0+R2V0VW5rbm93bkZpZWxkcyhtZXNzYWdlKSk7CisgIH0gZWxzZSB7CisgICAgb3VyX3NpemUgKz0gQ29tcHV0ZVVua25vd25GaWVsZHNTaXplKAorICAgICAgbWVzc2FnZV9yZWZsZWN0aW9uLT5HZXRVbmtub3duRmllbGRzKG1lc3NhZ2UpKTsKKyAgfQorCisgIHJldHVybiBvdXJfc2l6ZTsKK30KKworaW50IFdpcmVGb3JtYXQ6OkZpZWxkQnl0ZVNpemUoCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCwKKyAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlKSB7CisgIGNvbnN0IFJlZmxlY3Rpb24qIG1lc3NhZ2VfcmVmbGVjdGlvbiA9IG1lc3NhZ2UuR2V0UmVmbGVjdGlvbigpOworCisgIGlmIChmaWVsZC0+aXNfZXh0ZW5zaW9uKCkgJiYKKyAgICAgIGZpZWxkLT5jb250YWluaW5nX3R5cGUoKS0+b3B0aW9ucygpLm1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0KCkgJiYKKyAgICAgIGZpZWxkLT5jcHBfdHlwZSgpID09IEZpZWxkRGVzY3JpcHRvcjo6Q1BQVFlQRV9NRVNTQUdFICYmCisgICAgICAhZmllbGQtPmlzX3JlcGVhdGVkKCkpIHsKKyAgICByZXR1cm4gTWVzc2FnZVNldEl0ZW1CeXRlU2l6ZShmaWVsZCwgbWVzc2FnZSk7CisgIH0KKworICBpbnQgY291bnQgPSAwOworICBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkpIHsKKyAgICBjb3VudCA9IG1lc3NhZ2VfcmVmbGVjdGlvbi0+RmllbGRTaXplKG1lc3NhZ2UsIGZpZWxkKTsKKyAgfSBlbHNlIGlmIChtZXNzYWdlX3JlZmxlY3Rpb24tPkhhc0ZpZWxkKG1lc3NhZ2UsIGZpZWxkKSkgeworICAgIGNvdW50ID0gMTsKKyAgfQorCisgIGNvbnN0IGludCBkYXRhX3NpemUgPSBGaWVsZERhdGFPbmx5Qnl0ZVNpemUoZmllbGQsIG1lc3NhZ2UpOworICBpbnQgb3VyX3NpemUgPSBkYXRhX3NpemU7CisgIGlmIChmaWVsZC0+aXNfcGFja2VkKCkpIHsKKyAgICBpZiAoZGF0YV9zaXplID4gMCkgeworICAgICAgLy8gUGFja2VkIGZpZWxkcyBnZXQgc2VyaWFsaXplZCBsaWtlIGEgc3RyaW5nLCBub3QgdGhlaXIgbmF0aXZlIHR5cGUuCisgICAgICAvLyBUZWNobmljYWxseSB0aGlzIGRvZXNuJ3QgcmVhbGx5IG1hdHRlcjsgdGhlIHNpemUgb25seSBjaGFuZ2VzIGlmIGl0J3MKKyAgICAgIC8vIGEgR1JPVVAKKyAgICAgIG91cl9zaXplICs9IFRhZ1NpemUoZmllbGQtPm51bWJlcigpLCBGaWVsZERlc2NyaXB0b3I6OlRZUEVfU1RSSU5HKTsKKyAgICAgIG91cl9zaXplICs9IGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6VmFyaW50U2l6ZTMyKGRhdGFfc2l6ZSk7CisgICAgfQorICB9IGVsc2UgeworICAgIG91cl9zaXplICs9IGNvdW50ICogVGFnU2l6ZShmaWVsZC0+bnVtYmVyKCksIGZpZWxkLT50eXBlKCkpOworICB9CisgIHJldHVybiBvdXJfc2l6ZTsKK30KKworaW50IFdpcmVGb3JtYXQ6OkZpZWxkRGF0YU9ubHlCeXRlU2l6ZSgKKyAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UpIHsKKyAgY29uc3QgUmVmbGVjdGlvbiogbWVzc2FnZV9yZWZsZWN0aW9uID0gbWVzc2FnZS5HZXRSZWZsZWN0aW9uKCk7CisKKyAgaW50IGNvdW50ID0gMDsKKyAgaWYgKGZpZWxkLT5pc19yZXBlYXRlZCgpKSB7CisgICAgY291bnQgPSBtZXNzYWdlX3JlZmxlY3Rpb24tPkZpZWxkU2l6ZShtZXNzYWdlLCBmaWVsZCk7CisgIH0gZWxzZSBpZiAobWVzc2FnZV9yZWZsZWN0aW9uLT5IYXNGaWVsZChtZXNzYWdlLCBmaWVsZCkpIHsKKyAgICBjb3VudCA9IDE7CisgIH0KKworICBpbnQgZGF0YV9zaXplID0gMDsKKyAgc3dpdGNoIChmaWVsZC0+dHlwZSgpKSB7CisjZGVmaW5lIEhBTkRMRV9UWVBFKFRZUEUsIFRZUEVfTUVUSE9ELCBDUFBUWVBFX01FVEhPRCkgICAgICAgICAgICAgICAgICAgICBcCisgICAgY2FzZSBGaWVsZERlc2NyaXB0b3I6OlRZUEVfIyNUWVBFOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgY291bnQ7IGorKykgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgZGF0YV9zaXplICs9IFdpcmVGb3JtYXRMaXRlOjpUWVBFX01FVEhPRCMjU2l6ZSggICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICBtZXNzYWdlX3JlZmxlY3Rpb24tPkdldFJlcGVhdGVkIyNDUFBUWVBFX01FVEhPRCggICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgIG1lc3NhZ2UsIGZpZWxkLCBqKSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICB9IGVsc2UgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGRhdGFfc2l6ZSArPSBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9NRVRIT0QjI1NpemUoICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgbWVzc2FnZV9yZWZsZWN0aW9uLT5HZXQjI0NQUFRZUEVfTUVUSE9EKG1lc3NhZ2UsIGZpZWxkKSk7ICAgICAgICBcCisgICAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICBicmVhazsKKworI2RlZmluZSBIQU5ETEVfRklYRURfVFlQRShUWVBFLCBUWVBFX01FVEhPRCkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFXyMjVFlQRTogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgZGF0YV9zaXplICs9IGNvdW50ICogV2lyZUZvcm1hdExpdGU6OmsjI1RZUEVfTUVUSE9EIyNTaXplOyAgICAgICAgICAgXAorICAgICAgYnJlYWs7CisKKyAgICBIQU5ETEVfVFlQRSggSU5UMzIsICBJbnQzMiwgIEludDMyKQorICAgIEhBTkRMRV9UWVBFKCBJTlQ2NCwgIEludDY0LCAgSW50NjQpCisgICAgSEFORExFX1RZUEUoU0lOVDMyLCBTSW50MzIsICBJbnQzMikKKyAgICBIQU5ETEVfVFlQRShTSU5UNjQsIFNJbnQ2NCwgIEludDY0KQorICAgIEhBTkRMRV9UWVBFKFVJTlQzMiwgVUludDMyLCBVSW50MzIpCisgICAgSEFORExFX1RZUEUoVUlOVDY0LCBVSW50NjQsIFVJbnQ2NCkKKworICAgIEhBTkRMRV9GSVhFRF9UWVBFKCBGSVhFRDMyLCAgRml4ZWQzMikKKyAgICBIQU5ETEVfRklYRURfVFlQRSggRklYRUQ2NCwgIEZpeGVkNjQpCisgICAgSEFORExFX0ZJWEVEX1RZUEUoU0ZJWEVEMzIsIFNGaXhlZDMyKQorICAgIEhBTkRMRV9GSVhFRF9UWVBFKFNGSVhFRDY0LCBTRml4ZWQ2NCkKKworICAgIEhBTkRMRV9GSVhFRF9UWVBFKEZMT0FUICwgRmxvYXQgKQorICAgIEhBTkRMRV9GSVhFRF9UWVBFKERPVUJMRSwgRG91YmxlKQorCisgICAgSEFORExFX0ZJWEVEX1RZUEUoQk9PTCwgQm9vbCkKKworICAgIEhBTkRMRV9UWVBFKEdST1VQICAsIEdyb3VwICAsIE1lc3NhZ2UpCisgICAgSEFORExFX1RZUEUoTUVTU0FHRSwgTWVzc2FnZSwgTWVzc2FnZSkKKyN1bmRlZiBIQU5ETEVfVFlQRQorI3VuZGVmIEhBTkRMRV9GSVhFRF9UWVBFCisKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9FTlVNOiB7CisgICAgICBpZiAoZmllbGQtPmlzX3JlcGVhdGVkKCkpIHsKKyAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBjb3VudDsgaisrKSB7CisgICAgICAgICAgZGF0YV9zaXplICs9IFdpcmVGb3JtYXRMaXRlOjpFbnVtU2l6ZSgKKyAgICAgICAgICAgIG1lc3NhZ2VfcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRFbnVtKG1lc3NhZ2UsIGZpZWxkLCBqKS0+bnVtYmVyKCkpOworICAgICAgICB9CisgICAgICB9IGVsc2UgeworICAgICAgICBkYXRhX3NpemUgKz0gV2lyZUZvcm1hdExpdGU6OkVudW1TaXplKAorICAgICAgICAgIG1lc3NhZ2VfcmVmbGVjdGlvbi0+R2V0RW51bShtZXNzYWdlLCBmaWVsZCktPm51bWJlcigpKTsKKyAgICAgIH0KKyAgICAgIGJyZWFrOworICAgIH0KKworICAgIC8vIEhhbmRsZSBzdHJpbmdzIHNlcGFyYXRlbHkgc28gdGhhdCB3ZSBjYW4gZ2V0IHN0cmluZyByZWZlcmVuY2VzCisgICAgLy8gaW5zdGVhZCBvZiBjb3B5aW5nLgorICAgIGNhc2UgRmllbGREZXNjcmlwdG9yOjpUWVBFX1NUUklORzoKKyAgICBjYXNlIEZpZWxkRGVzY3JpcHRvcjo6VFlQRV9CWVRFUzogeworICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBjb3VudDsgaisrKSB7CisgICAgICAgIHN0cmluZyBzY3JhdGNoOworICAgICAgICBjb25zdCBzdHJpbmcmIHZhbHVlID0gZmllbGQtPmlzX3JlcGVhdGVkKCkgPworICAgICAgICAgIG1lc3NhZ2VfcmVmbGVjdGlvbi0+R2V0UmVwZWF0ZWRTdHJpbmdSZWZlcmVuY2UoCisgICAgICAgICAgICBtZXNzYWdlLCBmaWVsZCwgaiwgJnNjcmF0Y2gpIDoKKyAgICAgICAgICBtZXNzYWdlX3JlZmxlY3Rpb24tPkdldFN0cmluZ1JlZmVyZW5jZShtZXNzYWdlLCBmaWVsZCwgJnNjcmF0Y2gpOworICAgICAgICBkYXRhX3NpemUgKz0gV2lyZUZvcm1hdExpdGU6OlN0cmluZ1NpemUodmFsdWUpOworICAgICAgfQorICAgICAgYnJlYWs7CisgICAgfQorICB9CisgIHJldHVybiBkYXRhX3NpemU7Cit9CisKK2ludCBXaXJlRm9ybWF0OjpNZXNzYWdlU2V0SXRlbUJ5dGVTaXplKAorICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSkgeworICBjb25zdCBSZWZsZWN0aW9uKiBtZXNzYWdlX3JlZmxlY3Rpb24gPSBtZXNzYWdlLkdldFJlZmxlY3Rpb24oKTsKKworICBpbnQgb3VyX3NpemUgPSBXaXJlRm9ybWF0TGl0ZTo6a01lc3NhZ2VTZXRJdGVtVGFnc1NpemU7CisKKyAgLy8gdHlwZV9pZAorICBvdXJfc2l6ZSArPSBpbzo6Q29kZWRPdXRwdXRTdHJlYW06OlZhcmludFNpemUzMihmaWVsZC0+bnVtYmVyKCkpOworCisgIC8vIG1lc3NhZ2UKKyAgY29uc3QgTWVzc2FnZSYgc3ViX21lc3NhZ2UgPSBtZXNzYWdlX3JlZmxlY3Rpb24tPkdldE1lc3NhZ2UobWVzc2FnZSwgZmllbGQpOworICBpbnQgbWVzc2FnZV9zaXplID0gc3ViX21lc3NhZ2UuQnl0ZVNpemUoKTsKKworICBvdXJfc2l6ZSArPSBpbzo6Q29kZWRPdXRwdXRTdHJlYW06OlZhcmludFNpemUzMihtZXNzYWdlX3NpemUpOworICBvdXJfc2l6ZSArPSBtZXNzYWdlX3NpemU7CisKKyAgcmV0dXJuIG91cl9zaXplOworfQorCit9ICAvLyBuYW1lc3BhY2UgaW50ZXJuYWwKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdC5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk0MWJlNzUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0LmgKQEAgLTAsMCArMSwzMzcgQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBBdXRob3I6IGtlbnRvbkBnb29nbGUuY29tIChLZW50b24gVmFyZGEpCisvLyAgICAgICAgIGF0ZW5hc2lvQGdvb2dsZS5jb20gKENocmlzIEF0ZW5hc2lvKSAoWmlnWmFnIHRyYW5zZm9ybSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorLy8KKy8vIFRoaXMgaGVhZGVyIGlzIGxvZ2ljYWxseSBpbnRlcm5hbCwgYnV0IGlzIG1hZGUgcHVibGljIGJlY2F1c2UgaXQgaXMgdXNlZAorLy8gZnJvbSBwcm90b2NvbC1jb21waWxlci1nZW5lcmF0ZWQgY29kZSwgd2hpY2ggbWF5IHJlc2lkZSBpbiBvdGhlciBjb21wb25lbnRzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9XSVJFX0ZPUk1BVF9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1dJUkVfRk9STUFUX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21lc3NhZ2UuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZS5oPgorCisvLyBEbyBVVEYtOCB2YWxpZGF0aW9uIG9uIHN0cmluZyB0eXBlIGluIERlYnVnIGJ1aWxkIG9ubHkKKyNpZm5kZWYgTkRFQlVHCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9VVEY4X1ZBTElEQVRJT05fRU5BQkxFRAorI2VuZGlmCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKyAgbmFtZXNwYWNlIGlvIHsKKyAgICBjbGFzcyBDb2RlZElucHV0U3RyZWFtOyAgICAgIC8vIGNvZGVkX3N0cmVhbS5oCisgICAgY2xhc3MgQ29kZWRPdXRwdXRTdHJlYW07ICAgICAvLyBjb2RlZF9zdHJlYW0uaAorICB9CisgIGNsYXNzIFVua25vd25GaWVsZFNldDsgICAgICAgICAvLyB1bmtub3duX2ZpZWxkX3NldC5oCit9CisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CituYW1lc3BhY2UgaW50ZXJuYWwgeworCisvLyBUaGlzIGNsYXNzIGlzIGZvciBpbnRlcm5hbCB1c2UgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBsaWJyYXJ5IGFuZCBieQorLy8gcHJvdG9jb2wtY29tcGxpZXItZ2VuZXJhdGVkIG1lc3NhZ2UgY2xhc3Nlcy4gIEl0IG11c3Qgbm90IGJlIGNhbGxlZAorLy8gZGlyZWN0bHkgYnkgY2xpZW50cy4KKy8vCisvLyBUaGlzIGNsYXNzIGNvbnRhaW5zIGNvZGUgZm9yIGltcGxlbWVudGluZyB0aGUgYmluYXJ5IHByb3RvY29sIGJ1ZmZlcgorLy8gd2lyZSBmb3JtYXQgdmlhIHJlZmxlY3Rpb24uICBUaGUgV2lyZUZvcm1hdExpdGUgY2xhc3MgaW1wbGVtZW50cyB0aGUKKy8vIG5vbi1yZWZsZWN0aW9uIGJhc2VkIHJvdXRpbmVzLgorLy8KKy8vIFRoaXMgY2xhc3MgaXMgcmVhbGx5IGEgbmFtZXNwYWNlIHRoYXQgY29udGFpbnMgb25seSBzdGF0aWMgbWV0aG9kcworY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFdpcmVGb3JtYXQgeworIHB1YmxpYzoKKworICAvLyBHaXZlbiBhIGZpZWxkIHJldHVybiBpdHMgV2lyZVR5cGUKKyAgc3RhdGljIGlubGluZSBXaXJlRm9ybWF0TGl0ZTo6V2lyZVR5cGUgV2lyZVR5cGVGb3JGaWVsZCgKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpOworCisgIC8vIEdpdmVuIGEgRmllbGREZXNjcmlwdG9yOjpUeXBlIHJldHVybiBpdHMgV2lyZVR5cGUKKyAgc3RhdGljIGlubGluZSBXaXJlRm9ybWF0TGl0ZTo6V2lyZVR5cGUgV2lyZVR5cGVGb3JGaWVsZFR5cGUoCisgICAgICBGaWVsZERlc2NyaXB0b3I6OlR5cGUgdHlwZSk7CisKKyAgLy8gQ29tcHV0ZSB0aGUgYnl0ZSBzaXplIG9mIGEgdGFnLiAgRm9yIGdyb3VwcywgdGhpcyBpbmNsdWRlcyBib3RoIHRoZSBzdGFydAorICAvLyBhbmQgZW5kIHRhZ3MuCisgIHN0YXRpYyBpbmxpbmUgaW50IFRhZ1NpemUoaW50IGZpZWxkX251bWJlciwgRmllbGREZXNjcmlwdG9yOjpUeXBlIHR5cGUpOworCisgIC8vIFRoZXNlIHByb2NlZHVyZXMgY2FuIGJlIHVzZWQgdG8gaW1wbGVtZW50IHRoZSBtZXRob2RzIG9mIE1lc3NhZ2Ugd2hpY2gKKyAgLy8gaGFuZGxlIHBhcnNpbmcgYW5kIHNlcmlhbGl6YXRpb24gb2YgdGhlIHByb3RvY29sIGJ1ZmZlciB3aXJlIGZvcm1hdAorICAvLyB1c2luZyBvbmx5IHRoZSBSZWZsZWN0aW9uIGludGVyZmFjZS4gIFdoZW4geW91IGFzayB0aGUgcHJvdG9jb2wKKyAgLy8gY29tcGlsZXIgdG8gb3B0aW1pemUgZm9yIGNvZGUgc2l6ZSByYXRoZXIgdGhhbiBzcGVlZCwgaXQgd2lsbCBpbXBsZW1lbnQKKyAgLy8gdGhvc2UgbWV0aG9kcyBpbiB0ZXJtcyBvZiB0aGVzZSBwcm9jZWR1cmVzLiAgT2YgY291cnNlLCB0aGVzZSBhcmUgbXVjaAorICAvLyBzbG93ZXIgdGhhbiB0aGUgc3BlY2lhbGl6ZWQgaW1wbGVtZW50YXRpb25zIHdoaWNoIHRoZSBwcm90b2NvbCBjb21waWxlcgorICAvLyBnZW5lcmF0ZXMgd2hlbiB0b2xkIHRvIG9wdGltaXplIGZvciBzcGVlZC4KKworICAvLyBSZWFkIGEgbWVzc2FnZSBpbiBwcm90b2NvbCBidWZmZXIgd2lyZSBmb3JtYXQuCisgIC8vCisgIC8vIFRoaXMgcHJvY2VkdXJlIHJlYWRzIGVpdGhlciB0byB0aGUgZW5kIG9mIHRoZSBpbnB1dCBzdHJlYW0gb3IgdGhyb3VnaAorICAvLyBhIFdJUkVUWVBFX0VORF9HUk9VUCB0YWcgZW5kaW5nIHRoZSBtZXNzYWdlLCB3aGljaGV2ZXIgY29tZXMgZmlyc3QuCisgIC8vIEl0IHJldHVybnMgZmFsc2UgaWYgdGhlIGlucHV0IGlzIGludmFsaWQuCisgIC8vCisgIC8vIFJlcXVpcmVkIGZpZWxkcyBhcmUgTk9UIGNoZWNrZWQgYnkgdGhpcyBtZXRob2QuICBZb3UgbXVzdCBjYWxsCisgIC8vIElzSW5pdGlhbGl6ZWQoKSBvbiB0aGUgcmVzdWx0aW5nIG1lc3NhZ2UgeW91cnNlbGYuCisgIHN0YXRpYyBib29sIFBhcnNlQW5kTWVyZ2VQYXJ0aWFsKGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZSogbWVzc2FnZSk7CisKKyAgLy8gU2VyaWFsaXplIGEgbWVzc2FnZSBpbiBwcm90b2NvbCBidWZmZXIgd2lyZSBmb3JtYXQuCisgIC8vCisgIC8vIEFueSBlbWJlZGRlZCBtZXNzYWdlcyB3aXRoaW4gdGhlIG1lc3NhZ2UgbXVzdCBoYXZlIHRoZWlyIGNvcnJlY3Qgc2l6ZXMKKyAgLy8gY2FjaGVkLiAgSG93ZXZlciwgdGhlIHRvcC1sZXZlbCBtZXNzYWdlIG5lZWQgbm90OyBpdHMgc2l6ZSBpcyBwYXNzZWQgYXMKKyAgLy8gYSBwYXJhbWV0ZXIgdG8gdGhpcyBwcm9jZWR1cmUuCisgIC8vCisgIC8vIFRoZXNlIHJldHVybiBmYWxzZSBpZmYgdGhlIHVuZGVybHlpbmcgc3RyZWFtIHJldHVybnMgYSB3cml0ZSBlcnJvci4KKyAgc3RhdGljIHZvaWQgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSwKKyAgICAgIGludCBzaXplLCBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCk7CisKKyAgLy8gSW1wbGVtZW50cyBNZXNzYWdlOjpCeXRlU2l6ZSgpIHZpYSByZWZsZWN0aW9uLiAgV0FSTklORzogIFRoZSByZXN1bHQKKyAgLy8gb2YgdGhpcyBtZXRob2QgaXMgKm5vdCogY2FjaGVkIGFueXdoZXJlLiAgSG93ZXZlciwgYWxsIGVtYmVkZGVkIG1lc3NhZ2VzCisgIC8vIHdpbGwgaGF2ZSB0aGVpciBCeXRlU2l6ZSgpIG1ldGhvZHMgY2FsbGVkLCBzbyB0aGVpciBzaXplcyB3aWxsIGJlIGNhY2hlZC4KKyAgLy8gVGhlcmVmb3JlLCBjYWxsaW5nIHRoaXMgbWV0aG9kIGlzIHN1ZmZpY2llbnQgdG8gYWxsb3cgeW91IHRvIGNhbGwKKyAgLy8gV2lyZUZvcm1hdDo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzKCkgb24gdGhlIHNhbWUgb2JqZWN0LgorICBzdGF0aWMgaW50IEJ5dGVTaXplKGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UpOworCisgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8vIEhlbHBlcnMgZm9yIGRlYWxpbmcgd2l0aCB1bmtub3duIGZpZWxkcworCisgIC8vIFNraXBzIGEgZmllbGQgdmFsdWUgb2YgdGhlIGdpdmVuIFdpcmVUeXBlLiAgVGhlIGlucHV0IHNob3VsZCBzdGFydAorICAvLyBwb3NpdGlvbmVkIGltbWVkaWF0ZWx5IGFmdGVyIHRoZSB0YWcuICBJZiB1bmtub3duX2ZpZWxkcyBpcyBub24tTlVMTCwKKyAgLy8gdGhlIGNvbnRlbnRzIG9mIHRoZSBmaWVsZCB3aWxsIGJlIGFkZGVkIHRvIGl0LgorICBzdGF0aWMgYm9vbCBTa2lwRmllbGQoaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LCB1aW50MzIgdGFnLAorICAgICAgICAgICAgICAgICAgICAgICAgVW5rbm93bkZpZWxkU2V0KiB1bmtub3duX2ZpZWxkcyk7CisKKyAgLy8gUmVhZHMgYW5kIGlnbm9yZXMgYSBtZXNzYWdlIGZyb20gdGhlIGlucHV0LiAgSWYgdW5rbm93bl9maWVsZHMgaXMgbm9uLU5VTEwsCisgIC8vIHRoZSBjb250ZW50cyB3aWxsIGJlIGFkZGVkIHRvIGl0LgorICBzdGF0aWMgYm9vbCBTa2lwTWVzc2FnZShpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgIFVua25vd25GaWVsZFNldCogdW5rbm93bl9maWVsZHMpOworCisgIC8vIFJlYWQgYSBwYWNrZWQgZW51bSBmaWVsZC4gSWYgdGhlIGlzX3ZhbGlkIGZ1bmN0aW9uIGlzIG5vdCBOVUxMLCB2YWx1ZXMgZm9yCisgIC8vIHdoaWNoIGlzX3ZhbGlkKHZhbHVlKSByZXR1cm5zIGZhbHNlIGFyZSBhcHBlbmRlZCB0byB1bmtub3duX2ZpZWxkc19zdHJlYW0uCisgIHN0YXRpYyBib29sIFJlYWRQYWNrZWRFbnVtUHJlc2VydmVVbmtub3ducyhpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzIgZmllbGRfbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCAoKmlzX3ZhbGlkKShpbnQpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVW5rbm93bkZpZWxkU2V0KiB1bmtub3duX2ZpZWxkcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlcGVhdGVkRmllbGQ8aW50PiogdmFsdWVzKTsKKworICAvLyBXcml0ZSB0aGUgY29udGVudHMgb2YgYW4gVW5rbm93bkZpZWxkU2V0IHRvIHRoZSBvdXRwdXQuCisgIHN0YXRpYyB2b2lkIFNlcmlhbGl6ZVVua25vd25GaWVsZHMoY29uc3QgVW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCk7CisgIC8vIFNhbWUgYXMgYWJvdmUsIGV4Y2VwdCB3cml0aW5nIGRpcmVjdGx5IHRvIHRoZSBwcm92aWRlZCBidWZmZXIuCisgIC8vIFJlcXVpcmVzIHRoYXQgdGhlIGJ1ZmZlciBoYXZlIHN1ZmZpY2llbnQgY2FwYWNpdHkgZm9yCisgIC8vIENvbXB1dGVVbmtub3duRmllbGRzU2l6ZSh1bmtub3duX2ZpZWxkcykuCisgIC8vCisgIC8vIFJldHVybnMgYSBwb2ludGVyIHBhc3QgdGhlIGxhc3Qgd3JpdHRlbiBieXRlLgorICBzdGF0aWMgdWludDgqIFNlcmlhbGl6ZVVua25vd25GaWVsZHNUb0FycmF5KAorICAgICAgY29uc3QgVW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcywKKyAgICAgIHVpbnQ4KiB0YXJnZXQpOworCisgIC8vIFNhbWUgdGhpbmcgZXhjZXB0IGZvciBtZXNzYWdlcyB0aGF0IGhhdmUgdGhlIG1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0CisgIC8vIG9wdGlvbi4KKyAgc3RhdGljIHZvaWQgU2VyaWFsaXplVW5rbm93bk1lc3NhZ2VTZXRJdGVtcygKKyAgICAgIGNvbnN0IFVua25vd25GaWVsZFNldCYgdW5rbm93bl9maWVsZHMsCisgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCk7CisgIC8vIFNhbWUgYXMgYWJvdmUsIGV4Y2VwdCB3cml0aW5nIGRpcmVjdGx5IHRvIHRoZSBwcm92aWRlZCBidWZmZXIuCisgIC8vIFJlcXVpcmVzIHRoYXQgdGhlIGJ1ZmZlciBoYXZlIHN1ZmZpY2llbnQgY2FwYWNpdHkgZm9yCisgIC8vIENvbXB1dGVVbmtub3duTWVzc2FnZVNldEl0ZW1zU2l6ZSh1bmtub3duX2ZpZWxkcykuCisgIC8vCisgIC8vIFJldHVybnMgYSBwb2ludGVyIHBhc3QgdGhlIGxhc3Qgd3JpdHRlbiBieXRlLgorICBzdGF0aWMgdWludDgqIFNlcmlhbGl6ZVVua25vd25NZXNzYWdlU2V0SXRlbXNUb0FycmF5KAorICAgICAgY29uc3QgVW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcywKKyAgICAgIHVpbnQ4KiB0YXJnZXQpOworCisgIC8vIENvbXB1dGUgdGhlIHNpemUgb2YgdGhlIFVua25vd25GaWVsZFNldCBvbiB0aGUgd2lyZS4KKyAgc3RhdGljIGludCBDb21wdXRlVW5rbm93bkZpZWxkc1NpemUoY29uc3QgVW5rbm93bkZpZWxkU2V0JiB1bmtub3duX2ZpZWxkcyk7CisKKyAgLy8gU2FtZSB0aGluZyBleGNlcHQgZm9yIG1lc3NhZ2VzIHRoYXQgaGF2ZSB0aGUgbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQKKyAgLy8gb3B0aW9uLgorICBzdGF0aWMgaW50IENvbXB1dGVVbmtub3duTWVzc2FnZVNldEl0ZW1zU2l6ZSgKKyAgICAgIGNvbnN0IFVua25vd25GaWVsZFNldCYgdW5rbm93bl9maWVsZHMpOworCisKKyAgLy8gSGVscGVyIGZ1bmN0aW9ucyBmb3IgZW5jb2RpbmcgYW5kIGRlY29kaW5nIHRhZ3MuICAoSW5saW5lZCBiZWxvdyBhbmQgaW4KKyAgLy8gX2lubC5oKQorICAvLworICAvLyBUaGlzIGlzIGRpZmZlcmVudCBmcm9tIE1ha2VUYWcoZmllbGQtPm51bWJlcigpLCBmaWVsZC0+dHlwZSgpKSBpbiB0aGUgY2FzZQorICAvLyBvZiBwYWNrZWQgcmVwZWF0ZWQgZmllbGRzLgorICBzdGF0aWMgdWludDMyIE1ha2VUYWcoY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCk7CisKKyAgLy8gUGFyc2UgYSBzaW5nbGUgZmllbGQuICBUaGUgaW5wdXQgc2hvdWxkIHN0YXJ0IG91dCBwb3NpdGlvbmVkIGltbWVkaWF0ZWx5CisgIC8vIGFmdGVyIHRoZSB0YWcuCisgIHN0YXRpYyBib29sIFBhcnNlQW5kTWVyZ2VGaWVsZCgKKyAgICAgIHVpbnQzMiB0YWcsCisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCAgICAgICAgLy8gTWF5IGJlIE5VTEwgZm9yIHVua25vd24KKyAgICAgIE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpOworCisgIC8vIFNlcmlhbGl6ZSBhIHNpbmdsZSBmaWVsZC4KKyAgc3RhdGljIHZvaWQgU2VyaWFsaXplRmllbGRXaXRoQ2FjaGVkU2l6ZXMoCisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCAgICAgICAgLy8gQ2Fubm90IGJlIE5VTEwKKyAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UsCisgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCk7CisKKyAgLy8gQ29tcHV0ZSBzaXplIG9mIGEgc2luZ2xlIGZpZWxkLiAgSWYgdGhlIGZpZWxkIGlzIGEgbWVzc2FnZSB0eXBlLCB0aGlzCisgIC8vIHdpbGwgY2FsbCBCeXRlU2l6ZSgpIGZvciB0aGUgZW1iZWRkZWQgbWVzc2FnZSwgaW5zdXJpbmcgdGhhdCBpdCBjYWNoZXMKKyAgLy8gaXRzIHNpemUuCisgIHN0YXRpYyBpbnQgRmllbGRCeXRlU2l6ZSgKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsICAgICAgICAvLyBDYW5ub3QgYmUgTlVMTAorICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSk7CisKKyAgLy8gUGFyc2Uvc2VyaWFsaXplIGEgTWVzc2FnZVNldDo6SXRlbSBncm91cC4gIFVzZWQgd2l0aCBtZXNzYWdlcyB0aGF0IHVzZQorICAvLyBvcGlvbiBtZXNzYWdlX3NldF93aXJlX2Zvcm1hdCA9IHRydWUuCisgIHN0YXRpYyBib29sIFBhcnNlQW5kTWVyZ2VNZXNzYWdlU2V0SXRlbSgKKyAgICAgIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICAgIE1lc3NhZ2UqIG1lc3NhZ2UpOworICBzdGF0aWMgdm9pZCBTZXJpYWxpemVNZXNzYWdlU2V0SXRlbVdpdGhDYWNoZWRTaXplcygKKyAgICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQsCisgICAgICBjb25zdCBNZXNzYWdlJiBtZXNzYWdlLAorICAgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpOworICBzdGF0aWMgaW50IE1lc3NhZ2VTZXRJdGVtQnl0ZVNpemUoCisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgY29uc3QgTWVzc2FnZSYgbWVzc2FnZSk7CisKKyAgLy8gQ29tcHV0ZXMgdGhlIGJ5dGUgc2l6ZSBvZiBhIGZpZWxkLCBleGNsdWRpbmcgdGFncy4gRm9yIHBhY2tlZCBmaWVsZHMsIGl0CisgIC8vIG9ubHkgaW5jbHVkZXMgdGhlIHNpemUgb2YgdGhlIHJhdyBkYXRhLCBhbmQgbm90IHRoZSBzaXplIG9mIHRoZSB0b3RhbAorICAvLyBsZW5ndGgsIGJ1dCBmb3Igb3RoZXIgbGVuZ3RoLWRlbGltaXRlZCB0eXBlcywgdGhlIHNpemUgb2YgdGhlIGxlbmd0aCBpcworICAvLyBpbmNsdWRlZC4KKyAgc3RhdGljIGludCBGaWVsZERhdGFPbmx5Qnl0ZVNpemUoCisgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLCAgICAgICAgLy8gQ2Fubm90IGJlIE5VTEwKKyAgICAgIGNvbnN0IE1lc3NhZ2UmIG1lc3NhZ2UpOworCisgIGVudW0gT3BlcmF0aW9uIHsKKyAgICBQQVJTRSA9IDAsCisgICAgU0VSSUFMSVpFID0gMSwKKyAgfTsKKworICAvLyBWZXJpZmllcyB0aGF0IGEgc3RyaW5nIGZpZWxkIGlzIHZhbGlkIFVURjgsIGxvZ2dpbmcgYW4gZXJyb3IgaWYgbm90LgorICAvLyBUaGlzIGZ1bmN0aW9uIHdpbGwgbm90IGJlIGNhbGxlZCBieSBuZXdseSBnZW5lcmF0ZWQgcHJvdG9idWYgY29kZQorICAvLyBidXQgcmVtYWlucyBwcmVzZW50IHRvIHN1cHBvcnQgZXhpc3RpbmcgY29kZS4KKyAgc3RhdGljIHZvaWQgVmVyaWZ5VVRGOFN0cmluZyhjb25zdCBjaGFyKiBkYXRhLCBpbnQgc2l6ZSwgT3BlcmF0aW9uIG9wKTsKKyAgLy8gVGhlIE5hbWVkRmllbGQgdmFyaWFudCB0YWtlcyBhIGZpZWxkIG5hbWUgaW4gb3JkZXIgdG8gcHJvZHVjZSBhbgorICAvLyBpbmZvcm1hdGl2ZSBlcnJvciBtZXNzYWdlIGlmIHZlcmlmaWNhdGlvbiBmYWlscy4KKyAgc3RhdGljIHZvaWQgVmVyaWZ5VVRGOFN0cmluZ05hbWVkRmllbGQoY29uc3QgY2hhciogZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9wZXJhdGlvbiBvcCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogZmllbGRfbmFtZSk7CisKKyBwcml2YXRlOgorICAvLyBTa2lwIGEgTWVzc2FnZVNldCBmaWVsZC4KKyAgc3RhdGljIGJvb2wgU2tpcE1lc3NhZ2VTZXRGaWVsZChpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDMyIGZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVbmtub3duRmllbGRTZXQqIHVua25vd25fZmllbGRzKTsKKworICAvLyBQYXJzZSBhIE1lc3NhZ2VTZXQgZmllbGQuCisgIHN0YXRpYyBib29sIFBhcnNlQW5kTWVyZ2VNZXNzYWdlU2V0RmllbGQodWludDMyIGZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGaWVsZERlc2NyaXB0b3IqIGZpZWxkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UqIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KTsKKworICBHT09HTEVfRElTQUxMT1dfRVZJTF9DT05TVFJVQ1RPUlMoV2lyZUZvcm1hdCk7Cit9OworCisvLyBTdWJjbGFzcyBvZiBGaWVsZFNraXBwZXIgd2hpY2ggc2F2ZXMgc2tpcHBlZCBmaWVsZHMgdG8gYW4gVW5rbm93bkZpZWxkU2V0LgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFVua25vd25GaWVsZFNldEZpZWxkU2tpcHBlciA6IHB1YmxpYyBGaWVsZFNraXBwZXIgeworIHB1YmxpYzoKKyAgVW5rbm93bkZpZWxkU2V0RmllbGRTa2lwcGVyKFVua25vd25GaWVsZFNldCogdW5rbm93bl9maWVsZHMpCisgICAgICA6IHVua25vd25fZmllbGRzXyh1bmtub3duX2ZpZWxkcykge30KKyAgdmlydHVhbCB+VW5rbm93bkZpZWxkU2V0RmllbGRTa2lwcGVyKCkge30KKworICAvLyBpbXBsZW1lbnRzIEZpZWxkU2tpcHBlciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICB2aXJ0dWFsIGJvb2wgU2tpcEZpZWxkKGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwgdWludDMyIHRhZyk7CisgIHZpcnR1YWwgYm9vbCBTa2lwTWVzc2FnZShpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpOworICB2aXJ0dWFsIHZvaWQgU2tpcFVua25vd25FbnVtKGludCBmaWVsZF9udW1iZXIsIGludCB2YWx1ZSk7CisKKyBwcm90ZWN0ZWQ6CisgIFVua25vd25GaWVsZFNldCogdW5rbm93bl9maWVsZHNfOworfTsKKworLy8gaW5saW5lIG1ldGhvZHMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitpbmxpbmUgV2lyZUZvcm1hdExpdGU6OldpcmVUeXBlIFdpcmVGb3JtYXQ6OldpcmVUeXBlRm9yRmllbGQoCisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCkgeworICBpZiAoZmllbGQtPmlzX3BhY2tlZCgpKSB7CisgICAgcmV0dXJuIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVEOworICB9IGVsc2UgeworICAgIHJldHVybiBXaXJlVHlwZUZvckZpZWxkVHlwZShmaWVsZC0+dHlwZSgpKTsKKyAgfQorfQorCitpbmxpbmUgV2lyZUZvcm1hdExpdGU6OldpcmVUeXBlIFdpcmVGb3JtYXQ6OldpcmVUeXBlRm9yRmllbGRUeXBlKAorICAgIEZpZWxkRGVzY3JpcHRvcjo6VHlwZSB0eXBlKSB7CisgIC8vIFNvbWUgY29tcGlsZXJzIGRvbid0IGxpa2UgZW51bSAtPiBlbnVtIGNhc3RzLCBzbyB3ZSBpbXBsaWNpdF9jYXN0IHRvCisgIC8vIGludCBmaXJzdC4KKyAgcmV0dXJuIFdpcmVGb3JtYXRMaXRlOjpXaXJlVHlwZUZvckZpZWxkVHlwZSgKKyAgICAgIHN0YXRpY19jYXN0PFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGU+KAorICAgICAgICBpbXBsaWNpdF9jYXN0PGludD4odHlwZSkpKTsKK30KKworaW5saW5lIHVpbnQzMiBXaXJlRm9ybWF0OjpNYWtlVGFnKGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQpIHsKKyAgcmV0dXJuIFdpcmVGb3JtYXRMaXRlOjpNYWtlVGFnKGZpZWxkLT5udW1iZXIoKSwgV2lyZVR5cGVGb3JGaWVsZChmaWVsZCkpOworfQorCitpbmxpbmUgaW50IFdpcmVGb3JtYXQ6OlRhZ1NpemUoaW50IGZpZWxkX251bWJlciwgRmllbGREZXNjcmlwdG9yOjpUeXBlIHR5cGUpIHsKKyAgLy8gU29tZSBjb21waWxlcnMgZG9uJ3QgbGlrZSBlbnVtIC0+IGVudW0gY2FzdHMsIHNvIHdlIGltcGxpY2l0X2Nhc3QgdG8KKyAgLy8gaW50IGZpcnN0LgorICByZXR1cm4gV2lyZUZvcm1hdExpdGU6OlRhZ1NpemUoZmllbGRfbnVtYmVyLAorICAgICAgc3RhdGljX2Nhc3Q8V2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZT4oCisgICAgICAgIGltcGxpY2l0X2Nhc3Q8aW50Pih0eXBlKSkpOworfQorCitpbmxpbmUgdm9pZCBXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nKGNvbnN0IGNoYXIqIGRhdGEsIGludCBzaXplLAorICAgIFdpcmVGb3JtYXQ6Ok9wZXJhdGlvbiBvcCkgeworI2lmZGVmIEdPT0dMRV9QUk9UT0JVRl9VVEY4X1ZBTElEQVRJT05fRU5BQkxFRAorICBXaXJlRm9ybWF0TGl0ZTo6VmVyaWZ5VXRmOFN0cmluZygKKyAgICAgIGRhdGEsIHNpemUsIHN0YXRpY19jYXN0PFdpcmVGb3JtYXRMaXRlOjpPcGVyYXRpb24+KG9wKSwgTlVMTCk7CisjZWxzZQorICAvLyBBdm9pZCB0aGUgY29tcGlsZXIgd2FybmluZyBhYm91dCB1bnN1ZWQgdmFyaWFibGVzLgorICAodm9pZClkYXRhOyAodm9pZClzaXplOyAodm9pZClvcDsKKyNlbmRpZgorfQorCitpbmxpbmUgdm9pZCBXaXJlRm9ybWF0OjpWZXJpZnlVVEY4U3RyaW5nTmFtZWRGaWVsZCgKKyAgICBjb25zdCBjaGFyKiBkYXRhLCBpbnQgc2l6ZSwgV2lyZUZvcm1hdDo6T3BlcmF0aW9uIG9wLAorICAgIGNvbnN0IGNoYXIqIGZpZWxkX25hbWUpIHsKKyNpZmRlZiBHT09HTEVfUFJPVE9CVUZfVVRGOF9WQUxJREFUSU9OX0VOQUJMRUQKKyAgV2lyZUZvcm1hdExpdGU6OlZlcmlmeVV0ZjhTdHJpbmcoCisgICAgICBkYXRhLCBzaXplLCBzdGF0aWNfY2FzdDxXaXJlRm9ybWF0TGl0ZTo6T3BlcmF0aW9uPihvcCksIGZpZWxkX25hbWUpOworI2VuZGlmCit9CisKKworfSAgLy8gbmFtZXNwYWNlIGludGVybmFsCit9ICAvLyBuYW1lc3BhY2UgcHJvdG9idWYKKworfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfV0lSRV9GT1JNQVRfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0X2xpdGUuY2MgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0X2xpdGUuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2YxMDkzYwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZS5jYwpAQCAtMCwwICsxLDU0MyBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0X2xpdGVfaW5sLmg+CisKKyNpbmNsdWRlIDxzdGFjaz4KKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8dmVjdG9yPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9sb2dnaW5nLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9zdHJpbmdwcmludGYuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtX2lubC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL3plcm9fY29weV9zdHJlYW1faW1wbF9saXRlLmg+CisKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKworCisjaWYgIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKKy8vIE9sZCB2ZXJzaW9uIG9mIE1TVkMgZG9lc24ndCBsaWtlIGRlZmluaXRpb25zIG9mIGlubGluZSBjb25zdGFudHMsIEdDQworLy8gcmVxdWlyZXMgdGhlbS4KK2NvbnN0IGludCBXaXJlRm9ybWF0TGl0ZTo6a01lc3NhZ2VTZXRJdGVtU3RhcnRUYWc7Citjb25zdCBpbnQgV2lyZUZvcm1hdExpdGU6OmtNZXNzYWdlU2V0SXRlbUVuZFRhZzsKK2NvbnN0IGludCBXaXJlRm9ybWF0TGl0ZTo6a01lc3NhZ2VTZXRUeXBlSWRUYWc7Citjb25zdCBpbnQgV2lyZUZvcm1hdExpdGU6OmtNZXNzYWdlU2V0TWVzc2FnZVRhZzsKKworI2VuZGlmCisKKy8vIElCTSB4bEMgcmVxdWlyZXMgcHJlZml4aW5nIGNvbnN0YW50cyB3aXRoIFdpcmVGb3JtYXRMaXRlOjoKK2NvbnN0IGludCBXaXJlRm9ybWF0TGl0ZTo6a01lc3NhZ2VTZXRJdGVtVGFnc1NpemUgPQorICBpbzo6Q29kZWRPdXRwdXRTdHJlYW06OlN0YXRpY1ZhcmludFNpemUzMjwKKyAgICAgIFdpcmVGb3JtYXRMaXRlOjprTWVzc2FnZVNldEl0ZW1TdGFydFRhZz46OnZhbHVlICsKKyAgaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpTdGF0aWNWYXJpbnRTaXplMzI8CisgICAgICBXaXJlRm9ybWF0TGl0ZTo6a01lc3NhZ2VTZXRJdGVtRW5kVGFnPjo6dmFsdWUgKworICBpbzo6Q29kZWRPdXRwdXRTdHJlYW06OlN0YXRpY1ZhcmludFNpemUzMjwKKyAgICAgIFdpcmVGb3JtYXRMaXRlOjprTWVzc2FnZVNldFR5cGVJZFRhZz46OnZhbHVlICsKKyAgaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpTdGF0aWNWYXJpbnRTaXplMzI8CisgICAgICBXaXJlRm9ybWF0TGl0ZTo6a01lc3NhZ2VTZXRNZXNzYWdlVGFnPjo6dmFsdWU7CisKK2NvbnN0IFdpcmVGb3JtYXRMaXRlOjpDcHBUeXBlCitXaXJlRm9ybWF0TGl0ZTo6a0ZpZWxkVHlwZVRvQ3BwVHlwZU1hcFtNQVhfRklFTERfVFlQRSArIDFdID0geworICBzdGF0aWNfY2FzdDxDcHBUeXBlPigwKSwgIC8vIDAgaXMgcmVzZXJ2ZWQgZm9yIGVycm9ycworCisgIENQUFRZUEVfRE9VQkxFLCAgIC8vIFRZUEVfRE9VQkxFCisgIENQUFRZUEVfRkxPQVQsICAgIC8vIFRZUEVfRkxPQVQKKyAgQ1BQVFlQRV9JTlQ2NCwgICAgLy8gVFlQRV9JTlQ2NAorICBDUFBUWVBFX1VJTlQ2NCwgICAvLyBUWVBFX1VJTlQ2NAorICBDUFBUWVBFX0lOVDMyLCAgICAvLyBUWVBFX0lOVDMyCisgIENQUFRZUEVfVUlOVDY0LCAgIC8vIFRZUEVfRklYRUQ2NAorICBDUFBUWVBFX1VJTlQzMiwgICAvLyBUWVBFX0ZJWEVEMzIKKyAgQ1BQVFlQRV9CT09MLCAgICAgLy8gVFlQRV9CT09MCisgIENQUFRZUEVfU1RSSU5HLCAgIC8vIFRZUEVfU1RSSU5HCisgIENQUFRZUEVfTUVTU0FHRSwgIC8vIFRZUEVfR1JPVVAKKyAgQ1BQVFlQRV9NRVNTQUdFLCAgLy8gVFlQRV9NRVNTQUdFCisgIENQUFRZUEVfU1RSSU5HLCAgIC8vIFRZUEVfQllURVMKKyAgQ1BQVFlQRV9VSU5UMzIsICAgLy8gVFlQRV9VSU5UMzIKKyAgQ1BQVFlQRV9FTlVNLCAgICAgLy8gVFlQRV9FTlVNCisgIENQUFRZUEVfSU5UMzIsICAgIC8vIFRZUEVfU0ZJWEVEMzIKKyAgQ1BQVFlQRV9JTlQ2NCwgICAgLy8gVFlQRV9TRklYRUQ2NAorICBDUFBUWVBFX0lOVDMyLCAgICAvLyBUWVBFX1NJTlQzMgorICBDUFBUWVBFX0lOVDY0LCAgICAvLyBUWVBFX1NJTlQ2NAorfTsKKworY29uc3QgV2lyZUZvcm1hdExpdGU6OldpcmVUeXBlCitXaXJlRm9ybWF0TGl0ZTo6a1dpcmVUeXBlRm9yRmllbGRUeXBlW01BWF9GSUVMRF9UWVBFICsgMV0gPSB7CisgIHN0YXRpY19jYXN0PFdpcmVGb3JtYXRMaXRlOjpXaXJlVHlwZT4oLTEpLCAgLy8gaW52YWxpZAorICBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRklYRUQ2NCwgICAgICAgICAgIC8vIFRZUEVfRE9VQkxFCisgIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9GSVhFRDMyLCAgICAgICAgICAgLy8gVFlQRV9GTE9BVAorICBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfVkFSSU5ULCAgICAgICAgICAgIC8vIFRZUEVfSU5UNjQKKyAgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX1ZBUklOVCwgICAgICAgICAgICAvLyBUWVBFX1VJTlQ2NAorICBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfVkFSSU5ULCAgICAgICAgICAgIC8vIFRZUEVfSU5UMzIKKyAgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0ZJWEVENjQsICAgICAgICAgICAvLyBUWVBFX0ZJWEVENjQKKyAgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0ZJWEVEMzIsICAgICAgICAgICAvLyBUWVBFX0ZJWEVEMzIKKyAgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX1ZBUklOVCwgICAgICAgICAgICAvLyBUWVBFX0JPT0wKKyAgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQsICAvLyBUWVBFX1NUUklORworICBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfU1RBUlRfR1JPVVAsICAgICAgIC8vIFRZUEVfR1JPVVAKKyAgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQsICAvLyBUWVBFX01FU1NBR0UKKyAgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQsICAvLyBUWVBFX0JZVEVTCisgIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9WQVJJTlQsICAgICAgICAgICAgLy8gVFlQRV9VSU5UMzIKKyAgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX1ZBUklOVCwgICAgICAgICAgICAvLyBUWVBFX0VOVU0KKyAgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0ZJWEVEMzIsICAgICAgICAgICAvLyBUWVBFX1NGSVhFRDMyCisgIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9GSVhFRDY0LCAgICAgICAgICAgLy8gVFlQRV9TRklYRUQ2NAorICBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfVkFSSU5ULCAgICAgICAgICAgIC8vIFRZUEVfU0lOVDMyCisgIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9WQVJJTlQsICAgICAgICAgICAgLy8gVFlQRV9TSU5UNjQKK307CisKK2Jvb2wgV2lyZUZvcm1hdExpdGU6OlNraXBGaWVsZCgKKyAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsIHVpbnQzMiB0YWcpIHsKKyAgc3dpdGNoIChXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnV2lyZVR5cGUodGFnKSkgeworICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX1ZBUklOVDogeworICAgICAgdWludDY0IHZhbHVlOworICAgICAgaWYgKCFpbnB1dC0+UmVhZFZhcmludDY0KCZ2YWx1ZSkpIHJldHVybiBmYWxzZTsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9GSVhFRDY0OiB7CisgICAgICB1aW50NjQgdmFsdWU7CisgICAgICBpZiAoIWlucHV0LT5SZWFkTGl0dGxlRW5kaWFuNjQoJnZhbHVlKSkgcmV0dXJuIGZhbHNlOworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQ6IHsKKyAgICAgIHVpbnQzMiBsZW5ndGg7CisgICAgICBpZiAoIWlucHV0LT5SZWFkVmFyaW50MzIoJmxlbmd0aCkpIHJldHVybiBmYWxzZTsKKyAgICAgIGlmICghaW5wdXQtPlNraXAobGVuZ3RoKSkgcmV0dXJuIGZhbHNlOworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICAgIGNhc2UgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX1NUQVJUX0dST1VQOiB7CisgICAgICBpZiAoIWlucHV0LT5JbmNyZW1lbnRSZWN1cnNpb25EZXB0aCgpKSByZXR1cm4gZmFsc2U7CisgICAgICBpZiAoIVNraXBNZXNzYWdlKGlucHV0KSkgcmV0dXJuIGZhbHNlOworICAgICAgaW5wdXQtPkRlY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCk7CisgICAgICAvLyBDaGVjayB0aGF0IHRoZSBlbmRpbmcgdGFnIG1hdGNoZWQgdGhlIHN0YXJ0aW5nIHRhZy4KKyAgICAgIGlmICghaW5wdXQtPkxhc3RUYWdXYXMoV2lyZUZvcm1hdExpdGU6Ok1ha2VUYWcoCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkdldFRhZ0ZpZWxkTnVtYmVyKHRhZyksCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0VORF9HUk9VUCkpKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVA6IHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRklYRUQzMjogeworICAgICAgdWludDMyIHZhbHVlOworICAgICAgaWYgKCFpbnB1dC0+UmVhZExpdHRsZUVuZGlhbjMyKCZ2YWx1ZSkpIHJldHVybiBmYWxzZTsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgICBkZWZhdWx0OiB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICB9Cit9CisKK2Jvb2wgV2lyZUZvcm1hdExpdGU6OlNraXBGaWVsZCgKKyAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsIHVpbnQzMiB0YWcsIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSB7CisgIHN3aXRjaCAoV2lyZUZvcm1hdExpdGU6OkdldFRhZ1dpcmVUeXBlKHRhZykpIHsKKyAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9WQVJJTlQ6IHsKKyAgICAgIHVpbnQ2NCB2YWx1ZTsKKyAgICAgIGlmICghaW5wdXQtPlJlYWRWYXJpbnQ2NCgmdmFsdWUpKSByZXR1cm4gZmFsc2U7CisgICAgICBvdXRwdXQtPldyaXRlVmFyaW50MzIodGFnKTsKKyAgICAgIG91dHB1dC0+V3JpdGVWYXJpbnQ2NCh2YWx1ZSk7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRklYRUQ2NDogeworICAgICAgdWludDY0IHZhbHVlOworICAgICAgaWYgKCFpbnB1dC0+UmVhZExpdHRsZUVuZGlhbjY0KCZ2YWx1ZSkpIHJldHVybiBmYWxzZTsKKyAgICAgIG91dHB1dC0+V3JpdGVWYXJpbnQzMih0YWcpOworICAgICAgb3V0cHV0LT5Xcml0ZUxpdHRsZUVuZGlhbjY0KHZhbHVlKTsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9MRU5HVEhfREVMSU1JVEVEOiB7CisgICAgICB1aW50MzIgbGVuZ3RoOworICAgICAgaWYgKCFpbnB1dC0+UmVhZFZhcmludDMyKCZsZW5ndGgpKSByZXR1cm4gZmFsc2U7CisgICAgICBvdXRwdXQtPldyaXRlVmFyaW50MzIodGFnKTsKKyAgICAgIG91dHB1dC0+V3JpdGVWYXJpbnQzMihsZW5ndGgpOworICAgICAgLy8gVE9ETyhta2lsYXZ1eik6IFByb3ZpZGUgQVBJIHRvIHByZXZlbnQgZXh0cmEgc3RyaW5nIGNvcHlpbmcuCisgICAgICBzdHJpbmcgdGVtcDsKKyAgICAgIGlmICghaW5wdXQtPlJlYWRTdHJpbmcoJnRlbXAsIGxlbmd0aCkpIHJldHVybiBmYWxzZTsKKyAgICAgIG91dHB1dC0+V3JpdGVTdHJpbmcodGVtcCk7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfU1RBUlRfR1JPVVA6IHsKKyAgICAgIG91dHB1dC0+V3JpdGVWYXJpbnQzMih0YWcpOworICAgICAgaWYgKCFpbnB1dC0+SW5jcmVtZW50UmVjdXJzaW9uRGVwdGgoKSkgcmV0dXJuIGZhbHNlOworICAgICAgaWYgKCFTa2lwTWVzc2FnZShpbnB1dCwgb3V0cHV0KSkgcmV0dXJuIGZhbHNlOworICAgICAgaW5wdXQtPkRlY3JlbWVudFJlY3Vyc2lvbkRlcHRoKCk7CisgICAgICAvLyBDaGVjayB0aGF0IHRoZSBlbmRpbmcgdGFnIG1hdGNoZWQgdGhlIHN0YXJ0aW5nIHRhZy4KKyAgICAgIGlmICghaW5wdXQtPkxhc3RUYWdXYXMoV2lyZUZvcm1hdExpdGU6Ok1ha2VUYWcoCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkdldFRhZ0ZpZWxkTnVtYmVyKHRhZyksCisgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0VORF9HUk9VUCkpKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgICBjYXNlIFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVA6IHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgY2FzZSBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRklYRUQzMjogeworICAgICAgdWludDMyIHZhbHVlOworICAgICAgaWYgKCFpbnB1dC0+UmVhZExpdHRsZUVuZGlhbjMyKCZ2YWx1ZSkpIHJldHVybiBmYWxzZTsKKyAgICAgIG91dHB1dC0+V3JpdGVWYXJpbnQzMih0YWcpOworICAgICAgb3V0cHV0LT5Xcml0ZUxpdHRsZUVuZGlhbjMyKHZhbHVlKTsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgICBkZWZhdWx0OiB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICB9Cit9CisKK2Jvb2wgV2lyZUZvcm1hdExpdGU6OlNraXBNZXNzYWdlKGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCkgeworICB3aGlsZSAodHJ1ZSkgeworICAgIHVpbnQzMiB0YWcgPSBpbnB1dC0+UmVhZFRhZygpOworICAgIGlmICh0YWcgPT0gMCkgeworICAgICAgLy8gRW5kIG9mIGlucHV0LiAgVGhpcyBpcyBhIHZhbGlkIHBsYWNlIHRvIGVuZCwgc28gcmV0dXJuIHRydWUuCisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBXaXJlRm9ybWF0TGl0ZTo6V2lyZVR5cGUgd2lyZV90eXBlID0gV2lyZUZvcm1hdExpdGU6OkdldFRhZ1dpcmVUeXBlKHRhZyk7CisKKyAgICBpZiAod2lyZV90eXBlID09IFdpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVApIHsKKyAgICAgIC8vIE11c3QgYmUgdGhlIGVuZCBvZiB0aGUgbWVzc2FnZS4KKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIGlmICghU2tpcEZpZWxkKGlucHV0LCB0YWcpKSByZXR1cm4gZmFsc2U7CisgIH0KK30KKworYm9vbCBXaXJlRm9ybWF0TGl0ZTo6U2tpcE1lc3NhZ2UoaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSB7CisgIHdoaWxlICh0cnVlKSB7CisgICAgdWludDMyIHRhZyA9IGlucHV0LT5SZWFkVGFnKCk7CisgICAgaWYgKHRhZyA9PSAwKSB7CisgICAgICAvLyBFbmQgb2YgaW5wdXQuICBUaGlzIGlzIGEgdmFsaWQgcGxhY2UgdG8gZW5kLCBzbyByZXR1cm4gdHJ1ZS4KKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworICAgIFdpcmVGb3JtYXRMaXRlOjpXaXJlVHlwZSB3aXJlX3R5cGUgPSBXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnV2lyZVR5cGUodGFnKTsKKworICAgIGlmICh3aXJlX3R5cGUgPT0gV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0VORF9HUk9VUCkgeworICAgICAgb3V0cHV0LT5Xcml0ZVZhcmludDMyKHRhZyk7CisgICAgICAvLyBNdXN0IGJlIHRoZSBlbmQgb2YgdGhlIG1lc3NhZ2UuCisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICBpZiAoIVNraXBGaWVsZChpbnB1dCwgdGFnLCBvdXRwdXQpKSByZXR1cm4gZmFsc2U7CisgIH0KK30KKworYm9vbCBGaWVsZFNraXBwZXI6OlNraXBGaWVsZCgKKyAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsIHVpbnQzMiB0YWcpIHsKKyAgcmV0dXJuIFdpcmVGb3JtYXRMaXRlOjpTa2lwRmllbGQoaW5wdXQsIHRhZyk7Cit9CisKK2Jvb2wgRmllbGRTa2lwcGVyOjpTa2lwTWVzc2FnZShpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyAgcmV0dXJuIFdpcmVGb3JtYXRMaXRlOjpTa2lwTWVzc2FnZShpbnB1dCk7Cit9CisKK3ZvaWQgRmllbGRTa2lwcGVyOjpTa2lwVW5rbm93bkVudW0oCisgICAgaW50IC8qIGZpZWxkX251bWJlciAqLywgaW50IC8qIHZhbHVlICovKSB7CisgIC8vIE5vdGhpbmcuCit9CisKK2Jvb2wgQ29kZWRPdXRwdXRTdHJlYW1GaWVsZFNraXBwZXI6OlNraXBGaWVsZCgKKyAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsIHVpbnQzMiB0YWcpIHsKKyAgcmV0dXJuIFdpcmVGb3JtYXRMaXRlOjpTa2lwRmllbGQoaW5wdXQsIHRhZywgdW5rbm93bl9maWVsZHNfKTsKK30KKworYm9vbCBDb2RlZE91dHB1dFN0cmVhbUZpZWxkU2tpcHBlcjo6U2tpcE1lc3NhZ2UoaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KSB7CisgIHJldHVybiBXaXJlRm9ybWF0TGl0ZTo6U2tpcE1lc3NhZ2UoaW5wdXQsIHVua25vd25fZmllbGRzXyk7Cit9CisKK3ZvaWQgQ29kZWRPdXRwdXRTdHJlYW1GaWVsZFNraXBwZXI6OlNraXBVbmtub3duRW51bSgKKyAgICBpbnQgZmllbGRfbnVtYmVyLCBpbnQgdmFsdWUpIHsKKyAgdW5rbm93bl9maWVsZHNfLT5Xcml0ZVZhcmludDMyKGZpZWxkX251bWJlcik7CisgIHVua25vd25fZmllbGRzXy0+V3JpdGVWYXJpbnQ2NCh2YWx1ZSk7Cit9CisKK2Jvb2wgV2lyZUZvcm1hdExpdGU6OlJlYWRQYWNrZWRFbnVtTm9JbmxpbmUoaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sICgqaXNfdmFsaWQpKGludCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlcGVhdGVkRmllbGQ8aW50PiogdmFsdWVzKSB7CisgIHVpbnQzMiBsZW5ndGg7CisgIGlmICghaW5wdXQtPlJlYWRWYXJpbnQzMigmbGVuZ3RoKSkgcmV0dXJuIGZhbHNlOworICBpbzo6Q29kZWRJbnB1dFN0cmVhbTo6TGltaXQgbGltaXQgPSBpbnB1dC0+UHVzaExpbWl0KGxlbmd0aCk7CisgIHdoaWxlIChpbnB1dC0+Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CisgICAgaW50IHZhbHVlOworICAgIGlmICghZ29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPAorICAgICAgICBpbnQsIFdpcmVGb3JtYXRMaXRlOjpUWVBFX0VOVU0+KGlucHV0LCAmdmFsdWUpKSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIGlmIChpc192YWxpZCA9PSBOVUxMIHx8IGlzX3ZhbGlkKHZhbHVlKSkgeworICAgICAgdmFsdWVzLT5BZGQodmFsdWUpOworICAgIH0KKyAgfQorICBpbnB1dC0+UG9wTGltaXQobGltaXQpOworICByZXR1cm4gdHJ1ZTsKK30KKworYm9vbCBXaXJlRm9ybWF0TGl0ZTo6UmVhZFBhY2tlZEVudW1QcmVzZXJ2ZVVua25vd25zKAorICAgIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICBpbnQgZmllbGRfbnVtYmVyLAorICAgIGJvb2wgKCppc192YWxpZCkoaW50KSwKKyAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIHVua25vd25fZmllbGRzX3N0cmVhbSwKKyAgICBSZXBlYXRlZEZpZWxkPGludD4qIHZhbHVlcykgeworICB1aW50MzIgbGVuZ3RoOworICBpZiAoIWlucHV0LT5SZWFkVmFyaW50MzIoJmxlbmd0aCkpIHJldHVybiBmYWxzZTsKKyAgaW86OkNvZGVkSW5wdXRTdHJlYW06OkxpbWl0IGxpbWl0ID0gaW5wdXQtPlB1c2hMaW1pdChsZW5ndGgpOworICB3aGlsZSAoaW5wdXQtPkJ5dGVzVW50aWxMaW1pdCgpID4gMCkgeworICAgIGludCB2YWx1ZTsKKyAgICBpZiAoIWdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgaW50LCBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9FTlVNPihpbnB1dCwgJnZhbHVlKSkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBpZiAoaXNfdmFsaWQgPT0gTlVMTCB8fCBpc192YWxpZCh2YWx1ZSkpIHsKKyAgICAgIHZhbHVlcy0+QWRkKHZhbHVlKTsKKyAgICB9IGVsc2UgeworICAgICAgdWludDMyIHRhZyA9IFdpcmVGb3JtYXRMaXRlOjpNYWtlVGFnKGZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfVkFSSU5UKTsKKyAgICAgIHVua25vd25fZmllbGRzX3N0cmVhbS0+V3JpdGVWYXJpbnQzMih0YWcpOworICAgICAgdW5rbm93bl9maWVsZHNfc3RyZWFtLT5Xcml0ZVZhcmludDMyKHZhbHVlKTsKKyAgICB9CisgIH0KKyAgaW5wdXQtPlBvcExpbWl0KGxpbWl0KTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgV2lyZUZvcm1hdExpdGU6OldyaXRlSW50MzIoaW50IGZpZWxkX251bWJlciwgaW50MzIgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSB7CisgIFdyaXRlVGFnKGZpZWxkX251bWJlciwgV0lSRVRZUEVfVkFSSU5ULCBvdXRwdXQpOworICBXcml0ZUludDMyTm9UYWcodmFsdWUsIG91dHB1dCk7Cit9Cit2b2lkIFdpcmVGb3JtYXRMaXRlOjpXcml0ZUludDY0KGludCBmaWVsZF9udW1iZXIsIGludDY0IHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgeworICBXcml0ZVRhZyhmaWVsZF9udW1iZXIsIFdJUkVUWVBFX1ZBUklOVCwgb3V0cHV0KTsKKyAgV3JpdGVJbnQ2NE5vVGFnKHZhbHVlLCBvdXRwdXQpOworfQordm9pZCBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVVSW50MzIoaW50IGZpZWxkX251bWJlciwgdWludDMyIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIHsKKyAgV3JpdGVUYWcoZmllbGRfbnVtYmVyLCBXSVJFVFlQRV9WQVJJTlQsIG91dHB1dCk7CisgIFdyaXRlVUludDMyTm9UYWcodmFsdWUsIG91dHB1dCk7Cit9Cit2b2lkIFdpcmVGb3JtYXRMaXRlOjpXcml0ZVVJbnQ2NChpbnQgZmllbGRfbnVtYmVyLCB1aW50NjQgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgeworICBXcml0ZVRhZyhmaWVsZF9udW1iZXIsIFdJUkVUWVBFX1ZBUklOVCwgb3V0cHV0KTsKKyAgV3JpdGVVSW50NjROb1RhZyh2YWx1ZSwgb3V0cHV0KTsKK30KK3ZvaWQgV2lyZUZvcm1hdExpdGU6OldyaXRlU0ludDMyKGludCBmaWVsZF9udW1iZXIsIGludDMyIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIHsKKyAgV3JpdGVUYWcoZmllbGRfbnVtYmVyLCBXSVJFVFlQRV9WQVJJTlQsIG91dHB1dCk7CisgIFdyaXRlU0ludDMyTm9UYWcodmFsdWUsIG91dHB1dCk7Cit9Cit2b2lkIFdpcmVGb3JtYXRMaXRlOjpXcml0ZVNJbnQ2NChpbnQgZmllbGRfbnVtYmVyLCBpbnQ2NCB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSB7CisgIFdyaXRlVGFnKGZpZWxkX251bWJlciwgV0lSRVRZUEVfVkFSSU5ULCBvdXRwdXQpOworICBXcml0ZVNJbnQ2NE5vVGFnKHZhbHVlLCBvdXRwdXQpOworfQordm9pZCBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVGaXhlZDMyKGludCBmaWVsZF9udW1iZXIsIHVpbnQzMiB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgeworICBXcml0ZVRhZyhmaWVsZF9udW1iZXIsIFdJUkVUWVBFX0ZJWEVEMzIsIG91dHB1dCk7CisgIFdyaXRlRml4ZWQzMk5vVGFnKHZhbHVlLCBvdXRwdXQpOworfQordm9pZCBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVGaXhlZDY0KGludCBmaWVsZF9udW1iZXIsIHVpbnQ2NCB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgeworICBXcml0ZVRhZyhmaWVsZF9udW1iZXIsIFdJUkVUWVBFX0ZJWEVENjQsIG91dHB1dCk7CisgIFdyaXRlRml4ZWQ2NE5vVGFnKHZhbHVlLCBvdXRwdXQpOworfQordm9pZCBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTRml4ZWQzMihpbnQgZmllbGRfbnVtYmVyLCBpbnQzMiB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIHsKKyAgV3JpdGVUYWcoZmllbGRfbnVtYmVyLCBXSVJFVFlQRV9GSVhFRDMyLCBvdXRwdXQpOworICBXcml0ZVNGaXhlZDMyTm9UYWcodmFsdWUsIG91dHB1dCk7Cit9Cit2b2lkIFdpcmVGb3JtYXRMaXRlOjpXcml0ZVNGaXhlZDY0KGludCBmaWVsZF9udW1iZXIsIGludDY0IHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgeworICBXcml0ZVRhZyhmaWVsZF9udW1iZXIsIFdJUkVUWVBFX0ZJWEVENjQsIG91dHB1dCk7CisgIFdyaXRlU0ZpeGVkNjROb1RhZyh2YWx1ZSwgb3V0cHV0KTsKK30KK3ZvaWQgV2lyZUZvcm1hdExpdGU6OldyaXRlRmxvYXQoaW50IGZpZWxkX251bWJlciwgZmxvYXQgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSB7CisgIFdyaXRlVGFnKGZpZWxkX251bWJlciwgV0lSRVRZUEVfRklYRUQzMiwgb3V0cHV0KTsKKyAgV3JpdGVGbG9hdE5vVGFnKHZhbHVlLCBvdXRwdXQpOworfQordm9pZCBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVEb3VibGUoaW50IGZpZWxkX251bWJlciwgZG91YmxlIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIHsKKyAgV3JpdGVUYWcoZmllbGRfbnVtYmVyLCBXSVJFVFlQRV9GSVhFRDY0LCBvdXRwdXQpOworICBXcml0ZURvdWJsZU5vVGFnKHZhbHVlLCBvdXRwdXQpOworfQordm9pZCBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCb29sKGludCBmaWVsZF9udW1iZXIsIGJvb2wgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIHsKKyAgV3JpdGVUYWcoZmllbGRfbnVtYmVyLCBXSVJFVFlQRV9WQVJJTlQsIG91dHB1dCk7CisgIFdyaXRlQm9vbE5vVGFnKHZhbHVlLCBvdXRwdXQpOworfQordm9pZCBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVFbnVtKGludCBmaWVsZF9udW1iZXIsIGludCB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgeworICBXcml0ZVRhZyhmaWVsZF9udW1iZXIsIFdJUkVUWVBFX1ZBUklOVCwgb3V0cHV0KTsKKyAgV3JpdGVFbnVtTm9UYWcodmFsdWUsIG91dHB1dCk7Cit9CisKK3ZvaWQgV2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nKGludCBmaWVsZF9udW1iZXIsIGNvbnN0IHN0cmluZyYgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgeworICAvLyBTdHJpbmcgaXMgZm9yIFVURi04IHRleHQgb25seQorICBXcml0ZVRhZyhmaWVsZF9udW1iZXIsIFdJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQsIG91dHB1dCk7CisgIEdPT0dMRV9DSEVDSyh2YWx1ZS5zaXplKCkgPD0ga2ludDMybWF4KTsKKyAgb3V0cHV0LT5Xcml0ZVZhcmludDMyKHZhbHVlLnNpemUoKSk7CisgIG91dHB1dC0+V3JpdGVTdHJpbmcodmFsdWUpOworfQordm9pZCBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdNYXliZUFsaWFzZWQoCisgICAgaW50IGZpZWxkX251bWJlciwgY29uc3Qgc3RyaW5nJiB2YWx1ZSwKKyAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgeworICAvLyBTdHJpbmcgaXMgZm9yIFVURi04IHRleHQgb25seQorICBXcml0ZVRhZyhmaWVsZF9udW1iZXIsIFdJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQsIG91dHB1dCk7CisgIEdPT0dMRV9DSEVDSyh2YWx1ZS5zaXplKCkgPD0ga2ludDMybWF4KTsKKyAgb3V0cHV0LT5Xcml0ZVZhcmludDMyKHZhbHVlLnNpemUoKSk7CisgIG91dHB1dC0+V3JpdGVSYXdNYXliZUFsaWFzZWQodmFsdWUuZGF0YSgpLCB2YWx1ZS5zaXplKCkpOworfQordm9pZCBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCeXRlcyhpbnQgZmllbGRfbnVtYmVyLCBjb25zdCBzdHJpbmcmIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgeworICBXcml0ZVRhZyhmaWVsZF9udW1iZXIsIFdJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQsIG91dHB1dCk7CisgIEdPT0dMRV9DSEVDSyh2YWx1ZS5zaXplKCkgPD0ga2ludDMybWF4KTsKKyAgb3V0cHV0LT5Xcml0ZVZhcmludDMyKHZhbHVlLnNpemUoKSk7CisgIG91dHB1dC0+V3JpdGVTdHJpbmcodmFsdWUpOworfQordm9pZCBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCeXRlc01heWJlQWxpYXNlZCgKKyAgICBpbnQgZmllbGRfbnVtYmVyLCBjb25zdCBzdHJpbmcmIHZhbHVlLAorICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSB7CisgIFdyaXRlVGFnKGZpZWxkX251bWJlciwgV0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCwgb3V0cHV0KTsKKyAgR09PR0xFX0NIRUNLKHZhbHVlLnNpemUoKSA8PSBraW50MzJtYXgpOworICBvdXRwdXQtPldyaXRlVmFyaW50MzIodmFsdWUuc2l6ZSgpKTsKKyAgb3V0cHV0LT5Xcml0ZVJhd01heWJlQWxpYXNlZCh2YWx1ZS5kYXRhKCksIHZhbHVlLnNpemUoKSk7Cit9CisKKwordm9pZCBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVHcm91cChpbnQgZmllbGRfbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNZXNzYWdlTGl0ZSYgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSB7CisgIFdyaXRlVGFnKGZpZWxkX251bWJlciwgV0lSRVRZUEVfU1RBUlRfR1JPVVAsIG91dHB1dCk7CisgIHZhbHVlLlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcyhvdXRwdXQpOworICBXcml0ZVRhZyhmaWVsZF9udW1iZXIsIFdJUkVUWVBFX0VORF9HUk9VUCwgb3V0cHV0KTsKK30KKwordm9pZCBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlKGludCBmaWVsZF9udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZUxpdGUmIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSB7CisgIFdyaXRlVGFnKGZpZWxkX251bWJlciwgV0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCwgb3V0cHV0KTsKKyAgY29uc3QgaW50IHNpemUgPSB2YWx1ZS5HZXRDYWNoZWRTaXplKCk7CisgIG91dHB1dC0+V3JpdGVWYXJpbnQzMihzaXplKTsKKyAgdmFsdWUuU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKG91dHB1dCk7Cit9CisKK3ZvaWQgV2lyZUZvcm1hdExpdGU6OldyaXRlR3JvdXBNYXliZVRvQXJyYXkoaW50IGZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZUxpdGUmIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgeworICBXcml0ZVRhZyhmaWVsZF9udW1iZXIsIFdJUkVUWVBFX1NUQVJUX0dST1VQLCBvdXRwdXQpOworICBjb25zdCBpbnQgc2l6ZSA9IHZhbHVlLkdldENhY2hlZFNpemUoKTsKKyAgdWludDgqIHRhcmdldCA9IG91dHB1dC0+R2V0RGlyZWN0QnVmZmVyRm9yTkJ5dGVzQW5kQWR2YW5jZShzaXplKTsKKyAgaWYgKHRhcmdldCAhPSBOVUxMKSB7CisgICAgdWludDgqIGVuZCA9IHZhbHVlLlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkodGFyZ2V0KTsKKyAgICBHT09HTEVfRENIRUNLX0VRKGVuZCAtIHRhcmdldCwgc2l6ZSk7CisgIH0gZWxzZSB7CisgICAgdmFsdWUuU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKG91dHB1dCk7CisgIH0KKyAgV3JpdGVUYWcoZmllbGRfbnVtYmVyLCBXSVJFVFlQRV9FTkRfR1JPVVAsIG91dHB1dCk7Cit9CisKK3ZvaWQgV2lyZUZvcm1hdExpdGU6OldyaXRlTWVzc2FnZU1heWJlVG9BcnJheShpbnQgZmllbGRfbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2VMaXRlJiB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgeworICBXcml0ZVRhZyhmaWVsZF9udW1iZXIsIFdJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQsIG91dHB1dCk7CisgIGNvbnN0IGludCBzaXplID0gdmFsdWUuR2V0Q2FjaGVkU2l6ZSgpOworICBvdXRwdXQtPldyaXRlVmFyaW50MzIoc2l6ZSk7CisgIHVpbnQ4KiB0YXJnZXQgPSBvdXRwdXQtPkdldERpcmVjdEJ1ZmZlckZvck5CeXRlc0FuZEFkdmFuY2Uoc2l6ZSk7CisgIGlmICh0YXJnZXQgIT0gTlVMTCkgeworICAgIHVpbnQ4KiBlbmQgPSB2YWx1ZS5TZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KHRhcmdldCk7CisgICAgR09PR0xFX0RDSEVDS19FUShlbmQgLSB0YXJnZXQsIHNpemUpOworICB9IGVsc2UgeworICAgIHZhbHVlLlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcyhvdXRwdXQpOworICB9Cit9CisKK0dPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORSBzdGF0aWMgYm9vbCBSZWFkQnl0ZXNUb1N0cmluZygKKyAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsIHN0cmluZyogdmFsdWUpOworaW5saW5lIHN0YXRpYyBib29sIFJlYWRCeXRlc1RvU3RyaW5nKGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcqIHZhbHVlKSB7CisgIHVpbnQzMiBsZW5ndGg7CisgIHJldHVybiBpbnB1dC0+UmVhZFZhcmludDMyKCZsZW5ndGgpICYmCisgICAgICBpbnB1dC0+SW50ZXJuYWxSZWFkU3RyaW5nSW5saW5lKHZhbHVlLCBsZW5ndGgpOworfQorCitib29sIFdpcmVGb3JtYXRMaXRlOjpSZWFkQnl0ZXMoaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LCBzdHJpbmcqIHZhbHVlKSB7CisgIHJldHVybiBSZWFkQnl0ZXNUb1N0cmluZyhpbnB1dCwgdmFsdWUpOworfQorCitib29sIFdpcmVGb3JtYXRMaXRlOjpSZWFkQnl0ZXMoaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LCBzdHJpbmcqKiBwKSB7CisgIGlmICgqcCA9PSAmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpIHsKKyAgICAqcCA9IG5ldyA6OnN0ZDo6c3RyaW5nKCk7CisgIH0KKyAgcmV0dXJuIFJlYWRCeXRlc1RvU3RyaW5nKGlucHV0LCAqcCk7Cit9CisKK2Jvb2wgV2lyZUZvcm1hdExpdGU6OlZlcmlmeVV0ZjhTdHJpbmcoY29uc3QgY2hhciogZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9wZXJhdGlvbiBvcCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogZmllbGRfbmFtZSkgeworICBpZiAoIUlzU3RydWN0dXJhbGx5VmFsaWRVVEY4KGRhdGEsIHNpemUpKSB7CisgICAgY29uc3QgY2hhciogb3BlcmF0aW9uX3N0ciA9IE5VTEw7CisgICAgc3dpdGNoIChvcCkgeworICAgICAgY2FzZSBQQVJTRToKKyAgICAgICAgb3BlcmF0aW9uX3N0ciA9ICJwYXJzaW5nIjsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIFNFUklBTElaRToKKyAgICAgICAgb3BlcmF0aW9uX3N0ciA9ICJzZXJpYWxpemluZyI7CisgICAgICAgIGJyZWFrOworICAgICAgLy8gbm8gZGVmYXVsdCBjYXNlOiBoYXZlIHRoZSBjb21waWxlciB3YXJuIGlmIGEgY2FzZSBpcyBub3QgY292ZXJlZC4KKyAgICB9CisgICAgc3RyaW5nIHF1b3RlZF9maWVsZF9uYW1lID0gIiI7CisgICAgaWYgKGZpZWxkX25hbWUgIT0gTlVMTCkgeworICAgICAgcXVvdGVkX2ZpZWxkX25hbWUgPSBTdHJpbmdQcmludGYoIiAnJXMnIiwgZmllbGRfbmFtZSk7CisgICAgfQorICAgIC8vIG5vIHNwYWNlIGJlbG93IHRvIGF2b2lkIGRvdWJsZSBzcGFjZSB3aGVuIHRoZSBmaWVsZCBuYW1lIGlzIG1pc3NpbmcuCisgICAgR09PR0xFX0xPRyhFUlJPUikgPDwgIlN0cmluZyBmaWVsZCIgPDwgcXVvdGVkX2ZpZWxkX25hbWUgPDwgIiBjb250YWlucyBpbnZhbGlkICIKKyAgICAgICAgICAgICAgIDw8ICJVVEYtOCBkYXRhIHdoZW4gIiA8PCBvcGVyYXRpb25fc3RyIDw8ICIgYSBwcm90b2NvbCAiCisgICAgICAgICAgICAgICA8PCAiYnVmZmVyLiBVc2UgdGhlICdieXRlcycgdHlwZSBpZiB5b3UgaW50ZW5kIHRvIHNlbmQgcmF3ICIKKyAgICAgICAgICAgICAgIDw8ICJieXRlcy4gIjsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0X2xpdGUuaCBiL3NyYy9nb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU1ZmM3ZWMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0X2xpdGUuaApAQCAtMCwwICsxLDY5NiBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICAgICAgICAgYXRlbmFzaW9AZ29vZ2xlLmNvbSAoQ2hyaXMgQXRlbmFzaW8pIChaaWdaYWcgdHJhbnNmb3JtKQorLy8gICAgICAgICB3aW5rQGdvb2dsZS5jb20gKFdpbmsgU2F2aWxsZSkgKHJlZmFjdG9yZWQgZnJvbSB3aXJlX2Zvcm1hdC5oKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisvLworLy8gVGhpcyBoZWFkZXIgaXMgbG9naWNhbGx5IGludGVybmFsLCBidXQgaXMgbWFkZSBwdWJsaWMgYmVjYXVzZSBpdCBpcyB1c2VkCisvLyBmcm9tIHByb3RvY29sLWNvbXBpbGVyLWdlbmVyYXRlZCBjb2RlLCB3aGljaCBtYXkgcmVzaWRlIGluIG90aGVyIGNvbXBvbmVudHMuCisKKyNpZm5kZWYgR09PR0xFX1BST1RPQlVGX1dJUkVfRk9STUFUX0xJVEVfSF9fCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9XSVJFX0ZPUk1BVF9MSVRFX0hfXworCisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvbWVzc2FnZV9saXRlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5oPiAgLy8gZm9yIENvZGVkT3V0cHV0U3RyZWFtOjpWYXJpbnQzMlNpemUKKworbmFtZXNwYWNlIGdvb2dsZSB7CisKK25hbWVzcGFjZSBwcm90b2J1ZiB7CisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUPiBjbGFzcyBSZXBlYXRlZEZpZWxkOyAgLy8gcmVwZWF0ZWRfZmllbGQuaAorfQorCituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKKworY2xhc3MgU3RyaW5nUGllY2VGaWVsZDsKKworLy8gVGhpcyBjbGFzcyBpcyBmb3IgaW50ZXJuYWwgdXNlIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgbGlicmFyeSBhbmQgYnkKKy8vIHByb3RvY29sLWNvbXBsaWVyLWdlbmVyYXRlZCBtZXNzYWdlIGNsYXNzZXMuICBJdCBtdXN0IG5vdCBiZSBjYWxsZWQKKy8vIGRpcmVjdGx5IGJ5IGNsaWVudHMuCisvLworLy8gVGhpcyBjbGFzcyBjb250YWlucyBoZWxwZXJzIGZvciBpbXBsZW1lbnRpbmcgdGhlIGJpbmFyeSBwcm90b2NvbCBidWZmZXIKKy8vIHdpcmUgZm9ybWF0IHdpdGhvdXQgdGhlIG5lZWQgZm9yIHJlZmxlY3Rpb24uIFVzZSBXaXJlRm9ybWF0IHdoZW4gdXNpbmcKKy8vIHJlZmxlY3Rpb24uCisvLworLy8gVGhpcyBjbGFzcyBpcyByZWFsbHkgYSBuYW1lc3BhY2UgdGhhdCBjb250YWlucyBvbmx5IHN0YXRpYyBtZXRob2RzLgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFdpcmVGb3JtYXRMaXRlIHsKKyBwdWJsaWM6CisKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgLy8gSGVscGVyIGNvbnN0YW50cyBhbmQgZnVuY3Rpb25zIHJlbGF0ZWQgdG8gdGhlIGZvcm1hdC4gIFRoZXNlIGFyZQorICAvLyBtb3N0bHkgbWVhbnQgZm9yIGludGVybmFsIGFuZCBnZW5lcmF0ZWQgY29kZSB0byB1c2UuCisKKyAgLy8gVGhlIHdpcmUgZm9ybWF0IGlzIGNvbXBvc2VkIG9mIGEgc2VxdWVuY2Ugb2YgdGFnL3ZhbHVlIHBhaXJzLCBlYWNoCisgIC8vIG9mIHdoaWNoIGNvbnRhaW5zIHRoZSB2YWx1ZSBvZiBvbmUgZmllbGQgKG9yIG9uZSBlbGVtZW50IG9mIGEgcmVwZWF0ZWQKKyAgLy8gZmllbGQpLiAgRWFjaCB0YWcgaXMgZW5jb2RlZCBhcyBhIHZhcmludC4gIFRoZSBsb3dlciBiaXRzIG9mIHRoZSB0YWcKKyAgLy8gaWRlbnRpZnkgaXRzIHdpcmUgdHlwZSwgd2hpY2ggc3BlY2lmaWVzIHRoZSBmb3JtYXQgb2YgdGhlIGRhdGEgdG8gZm9sbG93LgorICAvLyBUaGUgcmVzdCBvZiB0aGUgYml0cyBjb250YWluIHRoZSBmaWVsZCBudW1iZXIuICBFYWNoIHR5cGUgb2YgZmllbGQgKGFzCisgIC8vIGRlY2xhcmVkIGJ5IEZpZWxkRGVzY3JpcHRvcjo6VHlwZSwgaW4gZGVzY3JpcHRvci5oKSBtYXBzIHRvIG9uZSBvZgorICAvLyB0aGVzZSB3aXJlIHR5cGVzLiAgSW1tZWRpYXRlbHkgZm9sbG93aW5nIGVhY2ggdGFnIGlzIHRoZSBmaWVsZCdzIHZhbHVlLAorICAvLyBlbmNvZGVkIGluIHRoZSBmb3JtYXQgc3BlY2lmaWVkIGJ5IHRoZSB3aXJlIHR5cGUuICBCZWNhdXNlIHRoZSB0YWcKKyAgLy8gaWRlbnRpZmllcyB0aGUgZW5jb2Rpbmcgb2YgdGhpcyBkYXRhLCBpdCBpcyBwb3NzaWJsZSB0byBza2lwCisgIC8vIHVucmVjb2duaXplZCBmaWVsZHMgZm9yIGZvcndhcmRzIGNvbXBhdGliaWxpdHkuCisKKyAgZW51bSBXaXJlVHlwZSB7CisgICAgV0lSRVRZUEVfVkFSSU5UICAgICAgICAgICA9IDAsCisgICAgV0lSRVRZUEVfRklYRUQ2NCAgICAgICAgICA9IDEsCisgICAgV0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCA9IDIsCisgICAgV0lSRVRZUEVfU1RBUlRfR1JPVVAgICAgICA9IDMsCisgICAgV0lSRVRZUEVfRU5EX0dST1VQICAgICAgICA9IDQsCisgICAgV0lSRVRZUEVfRklYRUQzMiAgICAgICAgICA9IDUsCisgIH07CisKKyAgLy8gTGl0ZSBhbHRlcm5hdGl2ZSB0byBGaWVsZERlc2NyaXB0b3I6OlR5cGUuICBNdXN0IGJlIGtlcHQgaW4gc3luYy4KKyAgZW51bSBGaWVsZFR5cGUgeworICAgIFRZUEVfRE9VQkxFICAgICAgICAgPSAxLAorICAgIFRZUEVfRkxPQVQgICAgICAgICAgPSAyLAorICAgIFRZUEVfSU5UNjQgICAgICAgICAgPSAzLAorICAgIFRZUEVfVUlOVDY0ICAgICAgICAgPSA0LAorICAgIFRZUEVfSU5UMzIgICAgICAgICAgPSA1LAorICAgIFRZUEVfRklYRUQ2NCAgICAgICAgPSA2LAorICAgIFRZUEVfRklYRUQzMiAgICAgICAgPSA3LAorICAgIFRZUEVfQk9PTCAgICAgICAgICAgPSA4LAorICAgIFRZUEVfU1RSSU5HICAgICAgICAgPSA5LAorICAgIFRZUEVfR1JPVVAgICAgICAgICAgPSAxMCwKKyAgICBUWVBFX01FU1NBR0UgICAgICAgID0gMTEsCisgICAgVFlQRV9CWVRFUyAgICAgICAgICA9IDEyLAorICAgIFRZUEVfVUlOVDMyICAgICAgICAgPSAxMywKKyAgICBUWVBFX0VOVU0gICAgICAgICAgID0gMTQsCisgICAgVFlQRV9TRklYRUQzMiAgICAgICA9IDE1LAorICAgIFRZUEVfU0ZJWEVENjQgICAgICAgPSAxNiwKKyAgICBUWVBFX1NJTlQzMiAgICAgICAgID0gMTcsCisgICAgVFlQRV9TSU5UNjQgICAgICAgICA9IDE4LAorICAgIE1BWF9GSUVMRF9UWVBFICAgICAgPSAxOCwKKyAgfTsKKworICAvLyBMaXRlIGFsdGVybmF0aXZlIHRvIEZpZWxkRGVzY3JpcHRvcjo6Q3BwVHlwZS4gIE11c3QgYmUga2VwdCBpbiBzeW5jLgorICBlbnVtIENwcFR5cGUgeworICAgIENQUFRZUEVfSU5UMzIgICAgICAgPSAxLAorICAgIENQUFRZUEVfSU5UNjQgICAgICAgPSAyLAorICAgIENQUFRZUEVfVUlOVDMyICAgICAgPSAzLAorICAgIENQUFRZUEVfVUlOVDY0ICAgICAgPSA0LAorICAgIENQUFRZUEVfRE9VQkxFICAgICAgPSA1LAorICAgIENQUFRZUEVfRkxPQVQgICAgICAgPSA2LAorICAgIENQUFRZUEVfQk9PTCAgICAgICAgPSA3LAorICAgIENQUFRZUEVfRU5VTSAgICAgICAgPSA4LAorICAgIENQUFRZUEVfU1RSSU5HICAgICAgPSA5LAorICAgIENQUFRZUEVfTUVTU0FHRSAgICAgPSAxMCwKKyAgICBNQVhfQ1BQVFlQRSAgICAgICAgID0gMTAsCisgIH07CisKKyAgLy8gSGVscGVyIG1ldGhvZCB0byBnZXQgdGhlIENwcFR5cGUgZm9yIGEgcGFydGljdWxhciBUeXBlLgorICBzdGF0aWMgQ3BwVHlwZSBGaWVsZFR5cGVUb0NwcFR5cGUoRmllbGRUeXBlIHR5cGUpOworCisgIC8vIEdpdmVuIGEgRmllbGRTZXNjcmlwdG9yOjpUeXBlIHJldHVybiBpdHMgV2lyZVR5cGUKKyAgc3RhdGljIGlubGluZSBXaXJlRm9ybWF0TGl0ZTo6V2lyZVR5cGUgV2lyZVR5cGVGb3JGaWVsZFR5cGUoCisgICAgICBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIHR5cGUpIHsKKyAgICByZXR1cm4ga1dpcmVUeXBlRm9yRmllbGRUeXBlW3R5cGVdOworICB9CisKKyAgLy8gTnVtYmVyIG9mIGJpdHMgaW4gYSB0YWcgd2hpY2ggaWRlbnRpZnkgdGhlIHdpcmUgdHlwZS4KKyAgc3RhdGljIGNvbnN0IGludCBrVGFnVHlwZUJpdHMgPSAzOworICAvLyBNYXNrIGZvciB0aG9zZSBiaXRzLgorICBzdGF0aWMgY29uc3QgdWludDMyIGtUYWdUeXBlTWFzayA9ICgxIDw8IGtUYWdUeXBlQml0cykgLSAxOworCisgIC8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIGVuY29kaW5nIGFuZCBkZWNvZGluZyB0YWdzLiAgKElubGluZWQgYmVsb3cgYW5kIGluCisgIC8vIF9pbmwuaCkKKyAgLy8KKyAgLy8gVGhpcyBpcyBkaWZmZXJlbnQgZnJvbSBNYWtlVGFnKGZpZWxkLT5udW1iZXIoKSwgZmllbGQtPnR5cGUoKSkgaW4gdGhlIGNhc2UKKyAgLy8gb2YgcGFja2VkIHJlcGVhdGVkIGZpZWxkcy4KKyAgc3RhdGljIHVpbnQzMiBNYWtlVGFnKGludCBmaWVsZF9udW1iZXIsIFdpcmVUeXBlIHR5cGUpOworICBzdGF0aWMgV2lyZVR5cGUgR2V0VGFnV2lyZVR5cGUodWludDMyIHRhZyk7CisgIHN0YXRpYyBpbnQgR2V0VGFnRmllbGROdW1iZXIodWludDMyIHRhZyk7CisKKyAgLy8gQ29tcHV0ZSB0aGUgYnl0ZSBzaXplIG9mIGEgdGFnLiAgRm9yIGdyb3VwcywgdGhpcyBpbmNsdWRlcyBib3RoIHRoZSBzdGFydAorICAvLyBhbmQgZW5kIHRhZ3MuCisgIHN0YXRpYyBpbmxpbmUgaW50IFRhZ1NpemUoaW50IGZpZWxkX251bWJlciwgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSB0eXBlKTsKKworICAvLyBTa2lwcyBhIGZpZWxkIHZhbHVlIHdpdGggdGhlIGdpdmVuIHRhZy4gIFRoZSBpbnB1dCBzaG91bGQgc3RhcnQKKyAgLy8gcG9zaXRpb25lZCBpbW1lZGlhdGVseSBhZnRlciB0aGUgdGFnLiAgU2tpcHBlZCB2YWx1ZXMgYXJlIHNpbXBseSBkaXNjYXJkZWQsCisgIC8vIG5vdCByZWNvcmRlZCBhbnl3aGVyZS4gIFNlZSBXaXJlRm9ybWF0OjpTa2lwRmllbGQoKSBmb3IgYSB2ZXJzaW9uIHRoYXQKKyAgLy8gcmVjb3JkcyB0byBhbiBVbmtub3duRmllbGRTZXQuCisgIHN0YXRpYyBib29sIFNraXBGaWVsZChpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsIHVpbnQzMiB0YWcpOworCisgIC8vIFNraXBzIGEgZmllbGQgdmFsdWUgd2l0aCB0aGUgZ2l2ZW4gdGFnLiAgVGhlIGlucHV0IHNob3VsZCBzdGFydAorICAvLyBwb3NpdGlvbmVkIGltbWVkaWF0ZWx5IGFmdGVyIHRoZSB0YWcuIFNraXBwZWQgdmFsdWVzIGFyZSByZWNvcmRlZCB0byBhCisgIC8vIENvZGVkT3V0cHV0U3RyZWFtLgorICBzdGF0aWMgYm9vbCBTa2lwRmllbGQoaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LCB1aW50MzIgdGFnLAorICAgICAgICAgICAgICAgICAgICAgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpOworCisgIC8vIFJlYWRzIGFuZCBpZ25vcmVzIGEgbWVzc2FnZSBmcm9tIHRoZSBpbnB1dC4gIFNraXBwZWQgdmFsdWVzIGFyZSBzaW1wbHkKKyAgLy8gZGlzY2FyZGVkLCBub3QgcmVjb3JkZWQgYW55d2hlcmUuICBTZWUgV2lyZUZvcm1hdDo6U2tpcE1lc3NhZ2UoKSBmb3IgYQorICAvLyB2ZXJzaW9uIHRoYXQgcmVjb3JkcyB0byBhbiBVbmtub3duRmllbGRTZXQuCisgIHN0YXRpYyBib29sIFNraXBNZXNzYWdlKGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCk7CisKKyAgLy8gUmVhZHMgYW5kIGlnbm9yZXMgYSBtZXNzYWdlIGZyb20gdGhlIGlucHV0LiAgU2tpcHBlZCB2YWx1ZXMgYXJlIHJlY29yZGVkCisgIC8vIHRvIGEgQ29kZWRPdXRwdXRTdHJlYW0uCisgIHN0YXRpYyBib29sIFNraXBNZXNzYWdlKGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpOworCisvLyBUaGlzIG1hY3JvIGRvZXMgdGhlIHNhbWUgdGhpbmcgYXMgV2lyZUZvcm1hdExpdGU6Ok1ha2VUYWcoKSwgYnV0IHRoZQorLy8gcmVzdWx0IGlzIHVzYWJsZSBhcyBhIGNvbXBpbGUtdGltZSBjb25zdGFudCwgd2hpY2ggbWFrZXMgaXQgdXNhYmxlCisvLyBhcyBhIHN3aXRjaCBjYXNlIG9yIGEgdGVtcGxhdGUgaW5wdXQuICBXaXJlRm9ybWF0TGl0ZTo6TWFrZVRhZygpIGlzIG1vcmUKKy8vIHR5cGUtc2FmZSwgdGhvdWdoLCBzbyBwcmVmZXIgaXQgaWYgcG9zc2libGUuCisjZGVmaW5lIEdPT0dMRV9QUk9UT0JVRl9XSVJFX0ZPUk1BVF9NQUtFX1RBRyhGSUVMRF9OVU1CRVIsIFRZUEUpICAgICAgICAgICAgICAgICAgXAorICBzdGF0aWNfY2FzdDx1aW50MzI+KCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAoKEZJRUxEX05VTUJFUikgPDwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OmtUYWdUeXBlQml0cykgXAorICAgICAgfCAoVFlQRSkpCisKKyAgLy8gVGhlc2UgYXJlIHRoZSB0YWdzIGZvciB0aGUgb2xkIE1lc3NhZ2VTZXQgZm9ybWF0LCB3aGljaCB3YXMgZGVmaW5lZCBhczoKKyAgLy8gICBtZXNzYWdlIE1lc3NhZ2VTZXQgeworICAvLyAgICAgcmVwZWF0ZWQgZ3JvdXAgSXRlbSA9IDEgeworICAvLyAgICAgICByZXF1aXJlZCBpbnQzMiB0eXBlX2lkID0gMjsKKyAgLy8gICAgICAgcmVxdWlyZWQgc3RyaW5nIG1lc3NhZ2UgPSAzOworICAvLyAgICAgfQorICAvLyAgIH0KKyAgc3RhdGljIGNvbnN0IGludCBrTWVzc2FnZVNldEl0ZW1OdW1iZXIgPSAxOworICBzdGF0aWMgY29uc3QgaW50IGtNZXNzYWdlU2V0VHlwZUlkTnVtYmVyID0gMjsKKyAgc3RhdGljIGNvbnN0IGludCBrTWVzc2FnZVNldE1lc3NhZ2VOdW1iZXIgPSAzOworICBzdGF0aWMgY29uc3QgaW50IGtNZXNzYWdlU2V0SXRlbVN0YXJ0VGFnID0KKyAgICBHT09HTEVfUFJPVE9CVUZfV0lSRV9GT1JNQVRfTUFLRV9UQUcoa01lc3NhZ2VTZXRJdGVtTnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfU1RBUlRfR1JPVVApOworICBzdGF0aWMgY29uc3QgaW50IGtNZXNzYWdlU2V0SXRlbUVuZFRhZyA9CisgICAgR09PR0xFX1BST1RPQlVGX1dJUkVfRk9STUFUX01BS0VfVEFHKGtNZXNzYWdlU2V0SXRlbU51bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0VORF9HUk9VUCk7CisgIHN0YXRpYyBjb25zdCBpbnQga01lc3NhZ2VTZXRUeXBlSWRUYWcgPQorICAgIEdPT0dMRV9QUk9UT0JVRl9XSVJFX0ZPUk1BVF9NQUtFX1RBRyhrTWVzc2FnZVNldFR5cGVJZE51bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX1ZBUklOVCk7CisgIHN0YXRpYyBjb25zdCBpbnQga01lc3NhZ2VTZXRNZXNzYWdlVGFnID0KKyAgICBHT09HTEVfUFJPVE9CVUZfV0lSRV9GT1JNQVRfTUFLRV9UQUcoa01lc3NhZ2VTZXRNZXNzYWdlTnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCk7CisKKyAgLy8gQnl0ZSBzaXplIG9mIGFsbCB0YWdzIG9mIGEgTWVzc2FnZVNldDo6SXRlbSBjb21iaW5lZC4KKyAgc3RhdGljIGNvbnN0IGludCBrTWVzc2FnZVNldEl0ZW1UYWdzU2l6ZTsKKworICAvLyBIZWxwZXIgZnVuY3Rpb25zIGZvciBjb252ZXJ0aW5nIGJldHdlZW4gZmxvYXRzL2RvdWJsZXMgYW5kIElFRUUtNzU0CisgIC8vIHVpbnQzMnMvdWludDY0cyBzbyB0aGF0IHRoZXkgY2FuIGJlIHdyaXR0ZW4uICAoQXNzdW1lcyB5b3VyIHBsYXRmb3JtCisgIC8vIHVzZXMgSUVFRS03NTQgZmxvYXRzLikKKyAgc3RhdGljIHVpbnQzMiBFbmNvZGVGbG9hdChmbG9hdCB2YWx1ZSk7CisgIHN0YXRpYyBmbG9hdCBEZWNvZGVGbG9hdCh1aW50MzIgdmFsdWUpOworICBzdGF0aWMgdWludDY0IEVuY29kZURvdWJsZShkb3VibGUgdmFsdWUpOworICBzdGF0aWMgZG91YmxlIERlY29kZURvdWJsZSh1aW50NjQgdmFsdWUpOworCisgIC8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIG1hcHBpbmcgc2lnbmVkIGludGVnZXJzIHRvIHVuc2lnbmVkIGludGVnZXJzIGluCisgIC8vIHN1Y2ggYSB3YXkgdGhhdCBudW1iZXJzIHdpdGggc21hbGwgbWFnbml0dWRlcyB3aWxsIGVuY29kZSB0byBzbWFsbGVyCisgIC8vIHZhcmludHMuICBJZiB5b3Ugc2ltcGx5IHN0YXRpY19jYXN0IGEgbmVnYXRpdmUgbnVtYmVyIHRvIGFuIHVuc2lnbmVkCisgIC8vIG51bWJlciBhbmQgdmFyaW50LWVuY29kZSBpdCwgaXQgd2lsbCBhbHdheXMgdGFrZSAxMCBieXRlcywgZGVmZWF0aW5nCisgIC8vIHRoZSBwdXJwb3NlIG9mIHZhcmludC4gIFNvLCBmb3IgdGhlICJzaW50MzIiIGFuZCAic2ludDY0IiBmaWVsZCB0eXBlcywKKyAgLy8gd2UgWmlnWmFnLWVuY29kZSB0aGUgdmFsdWVzLgorICBzdGF0aWMgdWludDMyIFppZ1phZ0VuY29kZTMyKGludDMyIG4pOworICBzdGF0aWMgaW50MzIgIFppZ1phZ0RlY29kZTMyKHVpbnQzMiBuKTsKKyAgc3RhdGljIHVpbnQ2NCBaaWdaYWdFbmNvZGU2NChpbnQ2NCBuKTsKKyAgc3RhdGljIGludDY0ICBaaWdaYWdEZWNvZGU2NCh1aW50NjQgbik7CisKKyAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyAgLy8gTWV0aG9kcyBmb3IgcmVhZGluZy93cml0aW5nIGluZGl2aWR1YWwgZmllbGQuICBUaGUgaW1wbGVtZW50YXRpb25zCisgIC8vIG9mIHRoZXNlIG1ldGhvZHMgYXJlIGRlZmluZWQgaW4gd2lyZV9mb3JtYXRfbGl0ZV9pbmwuaDsgeW91IG11c3QgI2luY2x1ZGUKKyAgLy8gdGhhdCBmaWxlIHRvIHVzZSB0aGVzZS4KKworLy8gQXZvaWQgdWdseSBsaW5lIHdyYXBwaW5nCisjZGVmaW5lIGlucHV0ICBpbzo6Q29kZWRJbnB1dFN0cmVhbSogIGlucHV0X2FyZworI2RlZmluZSBvdXRwdXQgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXRfYXJnCisjZGVmaW5lIGZpZWxkX251bWJlciBpbnQgZmllbGRfbnVtYmVyX2FyZworI2RlZmluZSBJTkwgR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FCisKKyAgLy8gUmVhZCBmaWVsZHMsIG5vdCBpbmNsdWRpbmcgdGFncy4gIFRoZSBhc3N1bXB0aW9uIGlzIHRoYXQgeW91IGFscmVhZHkKKyAgLy8gcmVhZCB0aGUgdGFnIHRvIGRldGVybWluZSB3aGF0IGZpZWxkIHRvIHJlYWQuCisKKyAgLy8gRm9yIHByaW1pdGl2ZSBmaWVsZHMsIHdlIGp1c3QgdXNlIGEgdGVtcGxhdGl6ZWQgcm91dGluZSBwYXJhbWV0ZXJpemVkIGJ5CisgIC8vIHRoZSByZXByZXNlbnRlZCB0eXBlIGFuZCB0aGUgRmllbGRUeXBlLiBUaGVzZSBhcmUgc3BlY2lhbGl6ZWQgd2l0aCB0aGUKKyAgLy8gYXBwcm9wcmlhdGUgZGVmaW5pdGlvbiBmb3IgZWFjaCBkZWNsYXJlZCB0eXBlLgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgQ1R5cGUsIGVudW0gRmllbGRUeXBlIERlY2xhcmVkVHlwZT4gSU5MCisgIHN0YXRpYyBib29sIFJlYWRQcmltaXRpdmUoaW5wdXQsIENUeXBlKiB2YWx1ZSk7CisKKyAgLy8gUmVhZHMgcmVwZWF0ZWQgcHJpbWl0aXZlIHZhbHVlcywgd2l0aCBvcHRpbWl6YXRpb25zIGZvciByZXBlYXRzLgorICAvLyB0YWdfc2l6ZSBhbmQgdGFnIHNob3VsZCBib3RoIGJlIGNvbXBpbGUtdGltZSBjb25zdGFudHMgcHJvdmlkZWQgYnkgdGhlCisgIC8vIHByb3RvY29sIGNvbXBpbGVyLgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgQ1R5cGUsIGVudW0gRmllbGRUeXBlIERlY2xhcmVkVHlwZT4gSU5MCisgIHN0YXRpYyBib29sIFJlYWRSZXBlYXRlZFByaW1pdGl2ZShpbnQgdGFnX3NpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzIgdGFnLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXBlYXRlZEZpZWxkPENUeXBlPiogdmFsdWUpOworCisgIC8vIElkZW50aWNhbCB0byBSZWFkUmVwZWF0ZWRQcmltaXRpdmUsIGV4Y2VwdCB3aWxsIG5vdCBpbmxpbmUgdGhlCisgIC8vIGltcGxlbWVudGF0aW9uLgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgQ1R5cGUsIGVudW0gRmllbGRUeXBlIERlY2xhcmVkVHlwZT4KKyAgc3RhdGljIGJvb2wgUmVhZFJlcGVhdGVkUHJpbWl0aXZlTm9JbmxpbmUoaW50IHRhZ19zaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzIgdGFnLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVwZWF0ZWRGaWVsZDxDVHlwZT4qIHZhbHVlKTsKKworICAvLyBSZWFkcyBhIHByaW1pdGl2ZSB2YWx1ZSBkaXJlY3RseSBmcm9tIHRoZSBwcm92aWRlZCBidWZmZXIuIEl0IHJldHVybnMgYQorICAvLyBwb2ludGVyIHBhc3QgdGhlIHNlZ21lbnQgb2YgZGF0YSB0aGF0IHdhcyByZWFkLgorICAvLworICAvLyBUaGlzIGlzIG9ubHkgaW1wbGVtZW50ZWQgZm9yIHRoZSB0eXBlcyB3aXRoIGZpeGVkIHdpcmUgc2l6ZSwgZS5nLgorICAvLyBmbG9hdCwgZG91YmxlLCBhbmQgdGhlIChzKWZpeGVkKiB0eXBlcy4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIENUeXBlLCBlbnVtIEZpZWxkVHlwZSBEZWNsYXJlZFR5cGU+IElOTAorICBzdGF0aWMgY29uc3QgdWludDgqIFJlYWRQcmltaXRpdmVGcm9tQXJyYXkoY29uc3QgdWludDgqIGJ1ZmZlciwgQ1R5cGUqIHZhbHVlKTsKKworICAvLyBSZWFkcyBhIHByaW1pdGl2ZSBwYWNrZWQgZmllbGQuCisgIC8vCisgIC8vIFRoaXMgaXMgb25seSBpbXBsZW1lbnRlZCBmb3IgcGFja2FibGUgdHlwZXMuCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBDVHlwZSwgZW51bSBGaWVsZFR5cGUgRGVjbGFyZWRUeXBlPiBJTkwKKyAgc3RhdGljIGJvb2wgUmVhZFBhY2tlZFByaW1pdGl2ZShpbnB1dCwgUmVwZWF0ZWRGaWVsZDxDVHlwZT4qIHZhbHVlKTsKKworICAvLyBJZGVudGljYWwgdG8gUmVhZFBhY2tlZFByaW1pdGl2ZSwgZXhjZXB0IHdpbGwgbm90IGlubGluZSB0aGUKKyAgLy8gaW1wbGVtZW50YXRpb24uCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBDVHlwZSwgZW51bSBGaWVsZFR5cGUgRGVjbGFyZWRUeXBlPgorICBzdGF0aWMgYm9vbCBSZWFkUGFja2VkUHJpbWl0aXZlTm9JbmxpbmUoaW5wdXQsIFJlcGVhdGVkRmllbGQ8Q1R5cGU+KiB2YWx1ZSk7CisKKyAgLy8gUmVhZCBhIHBhY2tlZCBlbnVtIGZpZWxkLiBJZiB0aGUgaXNfdmFsaWQgZnVuY3Rpb24gaXMgbm90IE5VTEwsIHZhbHVlcyBmb3IKKyAgLy8gd2hpY2ggaXNfdmFsaWQodmFsdWUpIHJldHVybnMgZmFsc2UgYXJlIHNpbGVudGx5IGRyb3BwZWQuCisgIHN0YXRpYyBib29sIFJlYWRQYWNrZWRFbnVtTm9JbmxpbmUoaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCAoKmlzX3ZhbGlkKShpbnQpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlcGVhdGVkRmllbGQ8aW50PiogdmFsdWVzKTsKKworICAvLyBSZWFkIGEgcGFja2VkIGVudW0gZmllbGQuIElmIHRoZSBpc192YWxpZCBmdW5jdGlvbiBpcyBub3QgTlVMTCwgdmFsdWVzIGZvcgorICAvLyB3aGljaCBpc192YWxpZCh2YWx1ZSkgcmV0dXJucyBmYWxzZSBhcmUgYXBwZW5kZWQgdG8gdW5rbm93bl9maWVsZHNfc3RyZWFtLgorICBzdGF0aWMgYm9vbCBSZWFkUGFja2VkRW51bVByZXNlcnZlVW5rbm93bnMoCisgICAgICBpbnB1dCwKKyAgICAgIGZpZWxkX251bWJlciwKKyAgICAgIGJvb2wgKCppc192YWxpZCkoaW50KSwKKyAgICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogdW5rbm93bl9maWVsZHNfc3RyZWFtLAorICAgICAgUmVwZWF0ZWRGaWVsZDxpbnQ+KiB2YWx1ZXMpOworCisgIC8vIFJlYWQgYSBzdHJpbmcuICBSZWFkU3RyaW5nKC4uLiwgc3RyaW5nKiB2YWx1ZSkgcmVxdWlyZXMgYW4gZXhpc3Rpbmcgc3RyaW5nLgorICBzdGF0aWMgaW5saW5lIGJvb2wgUmVhZFN0cmluZyhpbnB1dCwgc3RyaW5nKiB2YWx1ZSk7CisgIC8vIFJlYWRTdHJpbmcoLi4uLCBzdHJpbmcqKiBwKSBpcyBpbnRlcm5hbC1vbmx5LCBhbmQgc2hvdWxkIG9ubHkgYmUgY2FsbGVkCisgIC8vIGZyb20gZ2VuZXJhdGVkIGNvZGUuIEl0IHN0YXJ0cyBieSBzZXR0aW5nICpwIHRvICJuZXcgc3RyaW5nIgorICAvLyBpZiAqcCA9PSAmR2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkuICBJdCB0aGVuIGludm9rZXMKKyAgLy8gUmVhZFN0cmluZyhpbnB1dCwgKnApLiAgVGhpcyBpcyB1c2VmdWwgZm9yIHJlZHVjaW5nIGNvZGUgc2l6ZS4KKyAgc3RhdGljIGlubGluZSBib29sIFJlYWRTdHJpbmcoaW5wdXQsIHN0cmluZyoqIHApOworICAvLyBBbmFsb2dvdXMgdG8gUmVhZFN0cmluZygpLgorICBzdGF0aWMgYm9vbCBSZWFkQnl0ZXMoaW5wdXQsIHN0cmluZyogdmFsdWUpOworICBzdGF0aWMgYm9vbCBSZWFkQnl0ZXMoaW5wdXQsIHN0cmluZyoqIHApOworCisKKyAgZW51bSBPcGVyYXRpb24geworICAgIFBBUlNFID0gMCwKKyAgICBTRVJJQUxJWkUgPSAxLAorICB9OworCisgIC8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgZGF0YSBpcyB2YWxpZCBVVEYtOC4KKyAgc3RhdGljIGJvb2wgVmVyaWZ5VXRmOFN0cmluZyhjb25zdCBjaGFyKiBkYXRhLCBpbnQgc2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPcGVyYXRpb24gb3AsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogZmllbGRfbmFtZSk7CisKKyAgc3RhdGljIGlubGluZSBib29sIFJlYWRHcm91cCAgKGZpZWxkX251bWJlciwgaW5wdXQsIE1lc3NhZ2VMaXRlKiB2YWx1ZSk7CisgIHN0YXRpYyBpbmxpbmUgYm9vbCBSZWFkTWVzc2FnZShpbnB1dCwgTWVzc2FnZUxpdGUqIHZhbHVlKTsKKworICAvLyBMaWtlIGFib3ZlLCBidXQgZGUtdmlydHVhbGl6ZSB0aGUgY2FsbCB0byBNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oKS4KKyAgLy8gVGhlIHBvaW50ZXIgbXVzdCBwb2ludCBhdCBhbiBpbnN0YW5jZSBvZiBNZXNzYWdlVHlwZSwgKm5vdCogYSBzdWJjbGFzcyAob3IKKyAgLy8gdGhlIHN1YmNsYXNzIG11c3Qgbm90IG92ZXJyaWRlIE1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgpKS4KKyAgdGVtcGxhdGU8dHlwZW5hbWUgTWVzc2FnZVR5cGU+CisgIHN0YXRpYyBpbmxpbmUgYm9vbCBSZWFkR3JvdXBOb1ZpcnR1YWwoZmllbGRfbnVtYmVyLCBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlVHlwZSogdmFsdWUpOworICB0ZW1wbGF0ZTx0eXBlbmFtZSBNZXNzYWdlVHlwZT4KKyAgc3RhdGljIGlubGluZSBib29sIFJlYWRNZXNzYWdlTm9WaXJ0dWFsKGlucHV0LCBNZXNzYWdlVHlwZSogdmFsdWUpOworCisgIC8vIFRoZSBzYW1lLCBidXQgZG8gbm90IG1vZGlmeSBpbnB1dCdzIHJlY3Vyc2lvbiBkZXB0aC4gIFRoaXMgaXMgdXNlZnVsCisgIC8vIHdoZW4gcmVhZGluZyBhIGJ1bmNoIG9mIGdyb3VwcyBvciBtZXNzYWdlcyBpbiBhIGxvb3AsIGJlY2F1c2UgdGhlbiB0aGUKKyAgLy8gcmVjdXJzaW9uIGRlcHRoIGNhbiBiZSBpbmNyZW1lbnRlZCBiZWZvcmUgdGhlIGxvb3AgYW5kIGRlY3JlbWVudGVkIGFmdGVyLgorICB0ZW1wbGF0ZTx0eXBlbmFtZSBNZXNzYWdlVHlwZT4KKyAgc3RhdGljIGlubGluZSBib29sIFJlYWRHcm91cE5vVmlydHVhbE5vUmVjdXJzaW9uRGVwdGgoZmllbGRfbnVtYmVyLCBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZVR5cGUqIHZhbHVlKTsKKworICB0ZW1wbGF0ZTx0eXBlbmFtZSBNZXNzYWdlVHlwZT4KKyAgc3RhdGljIGlubGluZSBib29sIFJlYWRNZXNzYWdlTm9WaXJ0dWFsTm9SZWN1cnNpb25EZXB0aChpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlVHlwZSogdmFsdWUpOworCisgIC8vIFdyaXRlIGEgdGFnLiAgVGhlIFdyaXRlKigpIGZ1bmN0aW9ucyB0eXBpY2FsbHkgaW5jbHVkZSB0aGUgdGFnLCBzbworICAvLyBub3JtYWxseSB0aGVyZSdzIG5vIG5lZWQgdG8gY2FsbCB0aGlzIHVubGVzcyB1c2luZyB0aGUgV3JpdGUqTm9UYWcoKQorICAvLyB2YXJpYW50cy4KKyAgSU5MIHN0YXRpYyB2b2lkIFdyaXRlVGFnKGZpZWxkX251bWJlciwgV2lyZVR5cGUgdHlwZSwgb3V0cHV0KTsKKworICAvLyBXcml0ZSBmaWVsZHMsIHdpdGhvdXQgdGFncy4KKyAgSU5MIHN0YXRpYyB2b2lkIFdyaXRlSW50MzJOb1RhZyAgIChpbnQzMiB2YWx1ZSwgb3V0cHV0KTsKKyAgSU5MIHN0YXRpYyB2b2lkIFdyaXRlSW50NjROb1RhZyAgIChpbnQ2NCB2YWx1ZSwgb3V0cHV0KTsKKyAgSU5MIHN0YXRpYyB2b2lkIFdyaXRlVUludDMyTm9UYWcgICh1aW50MzIgdmFsdWUsIG91dHB1dCk7CisgIElOTCBzdGF0aWMgdm9pZCBXcml0ZVVJbnQ2NE5vVGFnICAodWludDY0IHZhbHVlLCBvdXRwdXQpOworICBJTkwgc3RhdGljIHZvaWQgV3JpdGVTSW50MzJOb1RhZyAgKGludDMyIHZhbHVlLCBvdXRwdXQpOworICBJTkwgc3RhdGljIHZvaWQgV3JpdGVTSW50NjROb1RhZyAgKGludDY0IHZhbHVlLCBvdXRwdXQpOworICBJTkwgc3RhdGljIHZvaWQgV3JpdGVGaXhlZDMyTm9UYWcgKHVpbnQzMiB2YWx1ZSwgb3V0cHV0KTsKKyAgSU5MIHN0YXRpYyB2b2lkIFdyaXRlRml4ZWQ2NE5vVGFnICh1aW50NjQgdmFsdWUsIG91dHB1dCk7CisgIElOTCBzdGF0aWMgdm9pZCBXcml0ZVNGaXhlZDMyTm9UYWcoaW50MzIgdmFsdWUsIG91dHB1dCk7CisgIElOTCBzdGF0aWMgdm9pZCBXcml0ZVNGaXhlZDY0Tm9UYWcoaW50NjQgdmFsdWUsIG91dHB1dCk7CisgIElOTCBzdGF0aWMgdm9pZCBXcml0ZUZsb2F0Tm9UYWcgICAoZmxvYXQgdmFsdWUsIG91dHB1dCk7CisgIElOTCBzdGF0aWMgdm9pZCBXcml0ZURvdWJsZU5vVGFnICAoZG91YmxlIHZhbHVlLCBvdXRwdXQpOworICBJTkwgc3RhdGljIHZvaWQgV3JpdGVCb29sTm9UYWcgICAgKGJvb2wgdmFsdWUsIG91dHB1dCk7CisgIElOTCBzdGF0aWMgdm9pZCBXcml0ZUVudW1Ob1RhZyAgICAoaW50IHZhbHVlLCBvdXRwdXQpOworCisgIC8vIFdyaXRlIGZpZWxkcywgaW5jbHVkaW5nIHRhZ3MuCisgIHN0YXRpYyB2b2lkIFdyaXRlSW50MzIgICAoZmllbGRfbnVtYmVyLCAgaW50MzIgdmFsdWUsIG91dHB1dCk7CisgIHN0YXRpYyB2b2lkIFdyaXRlSW50NjQgICAoZmllbGRfbnVtYmVyLCAgaW50NjQgdmFsdWUsIG91dHB1dCk7CisgIHN0YXRpYyB2b2lkIFdyaXRlVUludDMyICAoZmllbGRfbnVtYmVyLCB1aW50MzIgdmFsdWUsIG91dHB1dCk7CisgIHN0YXRpYyB2b2lkIFdyaXRlVUludDY0ICAoZmllbGRfbnVtYmVyLCB1aW50NjQgdmFsdWUsIG91dHB1dCk7CisgIHN0YXRpYyB2b2lkIFdyaXRlU0ludDMyICAoZmllbGRfbnVtYmVyLCAgaW50MzIgdmFsdWUsIG91dHB1dCk7CisgIHN0YXRpYyB2b2lkIFdyaXRlU0ludDY0ICAoZmllbGRfbnVtYmVyLCAgaW50NjQgdmFsdWUsIG91dHB1dCk7CisgIHN0YXRpYyB2b2lkIFdyaXRlRml4ZWQzMiAoZmllbGRfbnVtYmVyLCB1aW50MzIgdmFsdWUsIG91dHB1dCk7CisgIHN0YXRpYyB2b2lkIFdyaXRlRml4ZWQ2NCAoZmllbGRfbnVtYmVyLCB1aW50NjQgdmFsdWUsIG91dHB1dCk7CisgIHN0YXRpYyB2b2lkIFdyaXRlU0ZpeGVkMzIoZmllbGRfbnVtYmVyLCAgaW50MzIgdmFsdWUsIG91dHB1dCk7CisgIHN0YXRpYyB2b2lkIFdyaXRlU0ZpeGVkNjQoZmllbGRfbnVtYmVyLCAgaW50NjQgdmFsdWUsIG91dHB1dCk7CisgIHN0YXRpYyB2b2lkIFdyaXRlRmxvYXQgICAoZmllbGRfbnVtYmVyLCAgZmxvYXQgdmFsdWUsIG91dHB1dCk7CisgIHN0YXRpYyB2b2lkIFdyaXRlRG91YmxlICAoZmllbGRfbnVtYmVyLCBkb3VibGUgdmFsdWUsIG91dHB1dCk7CisgIHN0YXRpYyB2b2lkIFdyaXRlQm9vbCAgICAoZmllbGRfbnVtYmVyLCAgIGJvb2wgdmFsdWUsIG91dHB1dCk7CisgIHN0YXRpYyB2b2lkIFdyaXRlRW51bSAgICAoZmllbGRfbnVtYmVyLCAgICBpbnQgdmFsdWUsIG91dHB1dCk7CisKKyAgc3RhdGljIHZvaWQgV3JpdGVTdHJpbmcoZmllbGRfbnVtYmVyLCBjb25zdCBzdHJpbmcmIHZhbHVlLCBvdXRwdXQpOworICBzdGF0aWMgdm9pZCBXcml0ZUJ5dGVzIChmaWVsZF9udW1iZXIsIGNvbnN0IHN0cmluZyYgdmFsdWUsIG91dHB1dCk7CisgIHN0YXRpYyB2b2lkIFdyaXRlU3RyaW5nTWF5YmVBbGlhc2VkKAorICAgICAgZmllbGRfbnVtYmVyLCBjb25zdCBzdHJpbmcmIHZhbHVlLCBvdXRwdXQpOworICBzdGF0aWMgdm9pZCBXcml0ZUJ5dGVzTWF5YmVBbGlhc2VkKAorICAgICAgZmllbGRfbnVtYmVyLCBjb25zdCBzdHJpbmcmIHZhbHVlLCBvdXRwdXQpOworCisgIHN0YXRpYyB2b2lkIFdyaXRlR3JvdXAoCisgICAgZmllbGRfbnVtYmVyLCBjb25zdCBNZXNzYWdlTGl0ZSYgdmFsdWUsIG91dHB1dCk7CisgIHN0YXRpYyB2b2lkIFdyaXRlTWVzc2FnZSgKKyAgICBmaWVsZF9udW1iZXIsIGNvbnN0IE1lc3NhZ2VMaXRlJiB2YWx1ZSwgb3V0cHV0KTsKKyAgLy8gTGlrZSBhYm92ZSwgYnV0IHRoZXNlIHdpbGwgY2hlY2sgaWYgdGhlIG91dHB1dCBzdHJlYW0gaGFzIGVub3VnaAorICAvLyBzcGFjZSB0byB3cml0ZSBkaXJlY3RseSB0byBhIGZsYXQgYXJyYXkuCisgIHN0YXRpYyB2b2lkIFdyaXRlR3JvdXBNYXliZVRvQXJyYXkoCisgICAgZmllbGRfbnVtYmVyLCBjb25zdCBNZXNzYWdlTGl0ZSYgdmFsdWUsIG91dHB1dCk7CisgIHN0YXRpYyB2b2lkIFdyaXRlTWVzc2FnZU1heWJlVG9BcnJheSgKKyAgICBmaWVsZF9udW1iZXIsIGNvbnN0IE1lc3NhZ2VMaXRlJiB2YWx1ZSwgb3V0cHV0KTsKKworICAvLyBMaWtlIGFib3ZlLCBidXQgZGUtdmlydHVhbGl6ZSB0aGUgY2FsbCB0byBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoKS4gIFRoZQorICAvLyBwb2ludGVyIG11c3QgcG9pbnQgYXQgYW4gaW5zdGFuY2Ugb2YgTWVzc2FnZVR5cGUsICpub3QqIGEgc3ViY2xhc3MgKG9yCisgIC8vIHRoZSBzdWJjbGFzcyBtdXN0IG5vdCBvdmVycmlkZSBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoKSkuCisgIHRlbXBsYXRlPHR5cGVuYW1lIE1lc3NhZ2VUeXBlPgorICBzdGF0aWMgaW5saW5lIHZvaWQgV3JpdGVHcm91cE5vVmlydHVhbCgKKyAgICBmaWVsZF9udW1iZXIsIGNvbnN0IE1lc3NhZ2VUeXBlJiB2YWx1ZSwgb3V0cHV0KTsKKyAgdGVtcGxhdGU8dHlwZW5hbWUgTWVzc2FnZVR5cGU+CisgIHN0YXRpYyBpbmxpbmUgdm9pZCBXcml0ZU1lc3NhZ2VOb1ZpcnR1YWwoCisgICAgZmllbGRfbnVtYmVyLCBjb25zdCBNZXNzYWdlVHlwZSYgdmFsdWUsIG91dHB1dCk7CisKKyN1bmRlZiBvdXRwdXQKKyNkZWZpbmUgb3V0cHV0IHVpbnQ4KiB0YXJnZXQKKworICAvLyBMaWtlIGFib3ZlLCBidXQgdXNlIG9ubHkgKlRvQXJyYXkgbWV0aG9kcyBvZiBDb2RlZE91dHB1dFN0cmVhbS4KKyAgSU5MIHN0YXRpYyB1aW50OCogV3JpdGVUYWdUb0FycmF5KGZpZWxkX251bWJlciwgV2lyZVR5cGUgdHlwZSwgb3V0cHV0KTsKKworICAvLyBXcml0ZSBmaWVsZHMsIHdpdGhvdXQgdGFncy4KKyAgSU5MIHN0YXRpYyB1aW50OCogV3JpdGVJbnQzMk5vVGFnVG9BcnJheSAgIChpbnQzMiB2YWx1ZSwgb3V0cHV0KTsKKyAgSU5MIHN0YXRpYyB1aW50OCogV3JpdGVJbnQ2NE5vVGFnVG9BcnJheSAgIChpbnQ2NCB2YWx1ZSwgb3V0cHV0KTsKKyAgSU5MIHN0YXRpYyB1aW50OCogV3JpdGVVSW50MzJOb1RhZ1RvQXJyYXkgICh1aW50MzIgdmFsdWUsIG91dHB1dCk7CisgIElOTCBzdGF0aWMgdWludDgqIFdyaXRlVUludDY0Tm9UYWdUb0FycmF5ICAodWludDY0IHZhbHVlLCBvdXRwdXQpOworICBJTkwgc3RhdGljIHVpbnQ4KiBXcml0ZVNJbnQzMk5vVGFnVG9BcnJheSAgKGludDMyIHZhbHVlLCBvdXRwdXQpOworICBJTkwgc3RhdGljIHVpbnQ4KiBXcml0ZVNJbnQ2NE5vVGFnVG9BcnJheSAgKGludDY0IHZhbHVlLCBvdXRwdXQpOworICBJTkwgc3RhdGljIHVpbnQ4KiBXcml0ZUZpeGVkMzJOb1RhZ1RvQXJyYXkgKHVpbnQzMiB2YWx1ZSwgb3V0cHV0KTsKKyAgSU5MIHN0YXRpYyB1aW50OCogV3JpdGVGaXhlZDY0Tm9UYWdUb0FycmF5ICh1aW50NjQgdmFsdWUsIG91dHB1dCk7CisgIElOTCBzdGF0aWMgdWludDgqIFdyaXRlU0ZpeGVkMzJOb1RhZ1RvQXJyYXkoaW50MzIgdmFsdWUsIG91dHB1dCk7CisgIElOTCBzdGF0aWMgdWludDgqIFdyaXRlU0ZpeGVkNjROb1RhZ1RvQXJyYXkoaW50NjQgdmFsdWUsIG91dHB1dCk7CisgIElOTCBzdGF0aWMgdWludDgqIFdyaXRlRmxvYXROb1RhZ1RvQXJyYXkgICAoZmxvYXQgdmFsdWUsIG91dHB1dCk7CisgIElOTCBzdGF0aWMgdWludDgqIFdyaXRlRG91YmxlTm9UYWdUb0FycmF5ICAoZG91YmxlIHZhbHVlLCBvdXRwdXQpOworICBJTkwgc3RhdGljIHVpbnQ4KiBXcml0ZUJvb2xOb1RhZ1RvQXJyYXkgICAgKGJvb2wgdmFsdWUsIG91dHB1dCk7CisgIElOTCBzdGF0aWMgdWludDgqIFdyaXRlRW51bU5vVGFnVG9BcnJheSAgICAoaW50IHZhbHVlLCBvdXRwdXQpOworCisgIC8vIFdyaXRlIGZpZWxkcywgaW5jbHVkaW5nIHRhZ3MuCisgIElOTCBzdGF0aWMgdWludDgqIFdyaXRlSW50MzJUb0FycmF5KGZpZWxkX251bWJlciwgaW50MzIgdmFsdWUsIG91dHB1dCk7CisgIElOTCBzdGF0aWMgdWludDgqIFdyaXRlSW50NjRUb0FycmF5KGZpZWxkX251bWJlciwgaW50NjQgdmFsdWUsIG91dHB1dCk7CisgIElOTCBzdGF0aWMgdWludDgqIFdyaXRlVUludDMyVG9BcnJheShmaWVsZF9udW1iZXIsIHVpbnQzMiB2YWx1ZSwgb3V0cHV0KTsKKyAgSU5MIHN0YXRpYyB1aW50OCogV3JpdGVVSW50NjRUb0FycmF5KGZpZWxkX251bWJlciwgdWludDY0IHZhbHVlLCBvdXRwdXQpOworICBJTkwgc3RhdGljIHVpbnQ4KiBXcml0ZVNJbnQzMlRvQXJyYXkoZmllbGRfbnVtYmVyLCBpbnQzMiB2YWx1ZSwgb3V0cHV0KTsKKyAgSU5MIHN0YXRpYyB1aW50OCogV3JpdGVTSW50NjRUb0FycmF5KGZpZWxkX251bWJlciwgaW50NjQgdmFsdWUsIG91dHB1dCk7CisgIElOTCBzdGF0aWMgdWludDgqIFdyaXRlRml4ZWQzMlRvQXJyYXkoZmllbGRfbnVtYmVyLCB1aW50MzIgdmFsdWUsIG91dHB1dCk7CisgIElOTCBzdGF0aWMgdWludDgqIFdyaXRlRml4ZWQ2NFRvQXJyYXkoZmllbGRfbnVtYmVyLCB1aW50NjQgdmFsdWUsIG91dHB1dCk7CisgIElOTCBzdGF0aWMgdWludDgqIFdyaXRlU0ZpeGVkMzJUb0FycmF5KGZpZWxkX251bWJlciwgaW50MzIgdmFsdWUsIG91dHB1dCk7CisgIElOTCBzdGF0aWMgdWludDgqIFdyaXRlU0ZpeGVkNjRUb0FycmF5KGZpZWxkX251bWJlciwgaW50NjQgdmFsdWUsIG91dHB1dCk7CisgIElOTCBzdGF0aWMgdWludDgqIFdyaXRlRmxvYXRUb0FycmF5KGZpZWxkX251bWJlciwgZmxvYXQgdmFsdWUsIG91dHB1dCk7CisgIElOTCBzdGF0aWMgdWludDgqIFdyaXRlRG91YmxlVG9BcnJheShmaWVsZF9udW1iZXIsIGRvdWJsZSB2YWx1ZSwgb3V0cHV0KTsKKyAgSU5MIHN0YXRpYyB1aW50OCogV3JpdGVCb29sVG9BcnJheShmaWVsZF9udW1iZXIsIGJvb2wgdmFsdWUsIG91dHB1dCk7CisgIElOTCBzdGF0aWMgdWludDgqIFdyaXRlRW51bVRvQXJyYXkoZmllbGRfbnVtYmVyLCBpbnQgdmFsdWUsIG91dHB1dCk7CisKKyAgSU5MIHN0YXRpYyB1aW50OCogV3JpdGVTdHJpbmdUb0FycmF5KAorICAgIGZpZWxkX251bWJlciwgY29uc3Qgc3RyaW5nJiB2YWx1ZSwgb3V0cHV0KTsKKyAgSU5MIHN0YXRpYyB1aW50OCogV3JpdGVCeXRlc1RvQXJyYXkoCisgICAgZmllbGRfbnVtYmVyLCBjb25zdCBzdHJpbmcmIHZhbHVlLCBvdXRwdXQpOworCisgIElOTCBzdGF0aWMgdWludDgqIFdyaXRlR3JvdXBUb0FycmF5KAorICAgICAgZmllbGRfbnVtYmVyLCBjb25zdCBNZXNzYWdlTGl0ZSYgdmFsdWUsIG91dHB1dCk7CisgIElOTCBzdGF0aWMgdWludDgqIFdyaXRlTWVzc2FnZVRvQXJyYXkoCisgICAgICBmaWVsZF9udW1iZXIsIGNvbnN0IE1lc3NhZ2VMaXRlJiB2YWx1ZSwgb3V0cHV0KTsKKworICAvLyBMaWtlIGFib3ZlLCBidXQgZGUtdmlydHVhbGl6ZSB0aGUgY2FsbCB0byBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoKS4gIFRoZQorICAvLyBwb2ludGVyIG11c3QgcG9pbnQgYXQgYW4gaW5zdGFuY2Ugb2YgTWVzc2FnZVR5cGUsICpub3QqIGEgc3ViY2xhc3MgKG9yCisgIC8vIHRoZSBzdWJjbGFzcyBtdXN0IG5vdCBvdmVycmlkZSBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoKSkuCisgIHRlbXBsYXRlPHR5cGVuYW1lIE1lc3NhZ2VUeXBlPgorICBJTkwgc3RhdGljIHVpbnQ4KiBXcml0ZUdyb3VwTm9WaXJ0dWFsVG9BcnJheSgKKyAgICBmaWVsZF9udW1iZXIsIGNvbnN0IE1lc3NhZ2VUeXBlJiB2YWx1ZSwgb3V0cHV0KTsKKyAgdGVtcGxhdGU8dHlwZW5hbWUgTWVzc2FnZVR5cGU+CisgIElOTCBzdGF0aWMgdWludDgqIFdyaXRlTWVzc2FnZU5vVmlydHVhbFRvQXJyYXkoCisgICAgZmllbGRfbnVtYmVyLCBjb25zdCBNZXNzYWdlVHlwZSYgdmFsdWUsIG91dHB1dCk7CisKKyN1bmRlZiBvdXRwdXQKKyN1bmRlZiBpbnB1dAorI3VuZGVmIElOTAorCisjdW5kZWYgZmllbGRfbnVtYmVyCisKKyAgLy8gQ29tcHV0ZSB0aGUgYnl0ZSBzaXplIG9mIGEgZmllbGQuICBUaGUgWHhTaXplKCkgZnVuY3Rpb25zIGRvIE5PVCBpbmNsdWRlCisgIC8vIHRoZSB0YWcsIHNvIHlvdSBtdXN0IGFsc28gY2FsbCBUYWdTaXplKCkuICAoVGhpcyBpcyBiZWNhdXNlLCBmb3IgcmVwZWF0ZWQKKyAgLy8gZmllbGRzLCB5b3Ugc2hvdWxkIG9ubHkgY2FsbCBUYWdTaXplKCkgb25jZSBhbmQgbXVsdGlwbHkgaXQgYnkgdGhlIGVsZW1lbnQKKyAgLy8gY291bnQsIGJ1dCB5b3UgbWF5IGhhdmUgdG8gY2FsbCBYeFNpemUoKSBmb3IgZWFjaCBpbmRpdmlkdWFsIGVsZW1lbnQuKQorICBzdGF0aWMgaW5saW5lIGludCBJbnQzMlNpemUgICAoIGludDMyIHZhbHVlKTsKKyAgc3RhdGljIGlubGluZSBpbnQgSW50NjRTaXplICAgKCBpbnQ2NCB2YWx1ZSk7CisgIHN0YXRpYyBpbmxpbmUgaW50IFVJbnQzMlNpemUgICh1aW50MzIgdmFsdWUpOworICBzdGF0aWMgaW5saW5lIGludCBVSW50NjRTaXplICAodWludDY0IHZhbHVlKTsKKyAgc3RhdGljIGlubGluZSBpbnQgU0ludDMyU2l6ZSAgKCBpbnQzMiB2YWx1ZSk7CisgIHN0YXRpYyBpbmxpbmUgaW50IFNJbnQ2NFNpemUgICggaW50NjQgdmFsdWUpOworICBzdGF0aWMgaW5saW5lIGludCBFbnVtU2l6ZSAgICAoICAgaW50IHZhbHVlKTsKKworICAvLyBUaGVzZSB0eXBlcyBhbHdheXMgaGF2ZSB0aGUgc2FtZSBzaXplLgorICBzdGF0aWMgY29uc3QgaW50IGtGaXhlZDMyU2l6ZSAgPSA0OworICBzdGF0aWMgY29uc3QgaW50IGtGaXhlZDY0U2l6ZSAgPSA4OworICBzdGF0aWMgY29uc3QgaW50IGtTRml4ZWQzMlNpemUgPSA0OworICBzdGF0aWMgY29uc3QgaW50IGtTRml4ZWQ2NFNpemUgPSA4OworICBzdGF0aWMgY29uc3QgaW50IGtGbG9hdFNpemUgICAgPSA0OworICBzdGF0aWMgY29uc3QgaW50IGtEb3VibGVTaXplICAgPSA4OworICBzdGF0aWMgY29uc3QgaW50IGtCb29sU2l6ZSAgICAgPSAxOworCisgIHN0YXRpYyBpbmxpbmUgaW50IFN0cmluZ1NpemUoY29uc3Qgc3RyaW5nJiB2YWx1ZSk7CisgIHN0YXRpYyBpbmxpbmUgaW50IEJ5dGVzU2l6ZSAoY29uc3Qgc3RyaW5nJiB2YWx1ZSk7CisKKyAgc3RhdGljIGlubGluZSBpbnQgR3JvdXBTaXplICAoY29uc3QgTWVzc2FnZUxpdGUmIHZhbHVlKTsKKyAgc3RhdGljIGlubGluZSBpbnQgTWVzc2FnZVNpemUoY29uc3QgTWVzc2FnZUxpdGUmIHZhbHVlKTsKKworICAvLyBMaWtlIGFib3ZlLCBidXQgZGUtdmlydHVhbGl6ZSB0aGUgY2FsbCB0byBCeXRlU2l6ZSgpLiAgVGhlCisgIC8vIHBvaW50ZXIgbXVzdCBwb2ludCBhdCBhbiBpbnN0YW5jZSBvZiBNZXNzYWdlVHlwZSwgKm5vdCogYSBzdWJjbGFzcyAob3IKKyAgLy8gdGhlIHN1YmNsYXNzIG11c3Qgbm90IG92ZXJyaWRlIEJ5dGVTaXplKCkpLgorICB0ZW1wbGF0ZTx0eXBlbmFtZSBNZXNzYWdlVHlwZT4KKyAgc3RhdGljIGlubGluZSBpbnQgR3JvdXBTaXplTm9WaXJ0dWFsICAoY29uc3QgTWVzc2FnZVR5cGUmIHZhbHVlKTsKKyAgdGVtcGxhdGU8dHlwZW5hbWUgTWVzc2FnZVR5cGU+CisgIHN0YXRpYyBpbmxpbmUgaW50IE1lc3NhZ2VTaXplTm9WaXJ0dWFsKGNvbnN0IE1lc3NhZ2VUeXBlJiB2YWx1ZSk7CisKKyAgLy8gR2l2ZW4gdGhlIGxlbmd0aCBvZiBkYXRhLCBjYWxjdWxhdGUgdGhlIGJ5dGUgc2l6ZSBvZiB0aGUgZGF0YSBvbiB0aGUKKyAgLy8gd2lyZSBpZiB3ZSBlbmNvZGUgdGhlIGRhdGEgYXMgYSBsZW5ndGggZGVsaW1pdGVkIGZpZWxkLgorICBzdGF0aWMgaW5saW5lIGludCBMZW5ndGhEZWxpbWl0ZWRTaXplKGludCBsZW5ndGgpOworCisgcHJpdmF0ZToKKyAgLy8gQSBoZWxwZXIgbWV0aG9kIGZvciB0aGUgcmVwZWF0ZWQgcHJpbWl0aXZlIHJlYWRlci4gVGhpcyBtZXRob2QgaGFzCisgIC8vIG9wdGltaXphdGlvbnMgZm9yIHByaW1pdGl2ZSB0eXBlcyB0aGF0IGhhdmUgZml4ZWQgc2l6ZSBvbiB0aGUgd2lyZSwgYW5kCisgIC8vIGNhbiBiZSByZWFkIHVzaW5nIHBvdGVudGlhbGx5IGZhc3RlciBwYXRocy4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIENUeXBlLCBlbnVtIEZpZWxkVHlwZSBEZWNsYXJlZFR5cGU+IEdPT0dMRV9BVFRSSUJVVEVfQUxXQVlTX0lOTElORQorICBzdGF0aWMgYm9vbCBSZWFkUmVwZWF0ZWRGaXhlZFNpemVQcmltaXRpdmUoCisgICAgICBpbnQgdGFnX3NpemUsCisgICAgICB1aW50MzIgdGFnLAorICAgICAgZ29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgUmVwZWF0ZWRGaWVsZDxDVHlwZT4qIHZhbHVlKTsKKworICAvLyBMaWtlIFJlYWRSZXBlYXRlZEZpeGVkU2l6ZVByaW1pdGl2ZSBidXQgZm9yIHBhY2tlZCBwcmltaXRpdmUgZmllbGRzLgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgQ1R5cGUsIGVudW0gRmllbGRUeXBlIERlY2xhcmVkVHlwZT4gR09PR0xFX0FUVFJJQlVURV9BTFdBWVNfSU5MSU5FCisgIHN0YXRpYyBib29sIFJlYWRQYWNrZWRGaXhlZFNpemVQcmltaXRpdmUoZ29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlcGVhdGVkRmllbGQ8Q1R5cGU+KiB2YWx1ZSk7CisKKyAgc3RhdGljIGNvbnN0IENwcFR5cGUga0ZpZWxkVHlwZVRvQ3BwVHlwZU1hcFtdOworICBzdGF0aWMgY29uc3QgV2lyZUZvcm1hdExpdGU6OldpcmVUeXBlIGtXaXJlVHlwZUZvckZpZWxkVHlwZVtdOworCisgIEdPT0dMRV9ESVNBTExPV19FVklMX0NPTlNUUlVDVE9SUyhXaXJlRm9ybWF0TGl0ZSk7Cit9OworCisvLyBBIGNsYXNzIHdoaWNoIGRlYWxzIHdpdGggdW5rbm93biB2YWx1ZXMuICBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBqdXN0CisvLyBkaXNjYXJkcyB0aGVtLiAgV2lyZUZvcm1hdCBkZWZpbmVzIGEgc3ViY2xhc3Mgd2hpY2ggd3JpdGVzIHRvIGFuCisvLyBVbmtub3duRmllbGRTZXQuICBUaGlzIGNsYXNzIGlzIHVzZWQgYnkgRXh0ZW5zaW9uU2V0OjpQYXJzZUZpZWxkKCksIHNpbmNlCisvLyBFeHRlbnNpb25TZXQgaXMgcGFydCBvZiB0aGUgbGl0ZSBsaWJyYXJ5IGJ1dCBVbmtub3duRmllbGRTZXQgaXMgbm90LgorY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEZpZWxkU2tpcHBlciB7CisgcHVibGljOgorICBGaWVsZFNraXBwZXIoKSB7fQorICB2aXJ0dWFsIH5GaWVsZFNraXBwZXIoKSB7fQorCisgIC8vIFNraXAgYSBmaWVsZCB3aG9zZSB0YWcgaGFzIGFscmVhZHkgYmVlbiBjb25zdW1lZC4KKyAgdmlydHVhbCBib29sIFNraXBGaWVsZChpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsIHVpbnQzMiB0YWcpOworCisgIC8vIFNraXAgYW4gZW50aXJlIG1lc3NhZ2Ugb3IgZ3JvdXAsIHVwIHRvIGFuIGVuZC1ncm91cCB0YWcgKHdoaWNoIGlzIGNvbnN1bWVkKQorICAvLyBvciBlbmQtb2Ytc3RyZWFtLgorICB2aXJ0dWFsIGJvb2wgU2tpcE1lc3NhZ2UoaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KTsKKworICAvLyBEZWFsIHdpdGggYW4gYWxyZWFkeS1wYXJzZWQgdW5yZWNvZ25pemVkIGVudW0gdmFsdWUuICBUaGUgZGVmYXVsdAorICAvLyBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdGhpbmcsIGJ1dCB0aGUgVW5rbm93bkZpZWxkU2V0LWJhc2VkIGltcGxlbWVudGF0aW9uCisgIC8vIHNhdmVzIGl0IGFzIGFuIHVua25vd24gdmFyaW50LgorICB2aXJ0dWFsIHZvaWQgU2tpcFVua25vd25FbnVtKGludCBmaWVsZF9udW1iZXIsIGludCB2YWx1ZSk7Cit9OworCisvLyBTdWJjbGFzcyBvZiBGaWVsZFNraXBwZXIgd2hpY2ggc2F2ZXMgc2tpcHBlZCBmaWVsZHMgdG8gYSBDb2RlZE91dHB1dFN0cmVhbS4KKworY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIENvZGVkT3V0cHV0U3RyZWFtRmllbGRTa2lwcGVyIDogcHVibGljIEZpZWxkU2tpcHBlciB7CisgcHVibGljOgorICBleHBsaWNpdCBDb2RlZE91dHB1dFN0cmVhbUZpZWxkU2tpcHBlcihpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIHVua25vd25fZmllbGRzKQorICAgICAgOiB1bmtub3duX2ZpZWxkc18odW5rbm93bl9maWVsZHMpIHt9CisgIHZpcnR1YWwgfkNvZGVkT3V0cHV0U3RyZWFtRmllbGRTa2lwcGVyKCkge30KKworICAvLyBpbXBsZW1lbnRzIEZpZWxkU2tpcHBlciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICB2aXJ0dWFsIGJvb2wgU2tpcEZpZWxkKGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwgdWludDMyIHRhZyk7CisgIHZpcnR1YWwgYm9vbCBTa2lwTWVzc2FnZShpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpOworICB2aXJ0dWFsIHZvaWQgU2tpcFVua25vd25FbnVtKGludCBmaWVsZF9udW1iZXIsIGludCB2YWx1ZSk7CisKKyBwcm90ZWN0ZWQ6CisgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogdW5rbm93bl9maWVsZHNfOworfTsKKworCisvLyBpbmxpbmUgbWV0aG9kcyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK2lubGluZSBXaXJlRm9ybWF0TGl0ZTo6Q3BwVHlwZQorV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZVRvQ3BwVHlwZShGaWVsZFR5cGUgdHlwZSkgeworICByZXR1cm4ga0ZpZWxkVHlwZVRvQ3BwVHlwZU1hcFt0eXBlXTsKK30KKworaW5saW5lIHVpbnQzMiBXaXJlRm9ybWF0TGl0ZTo6TWFrZVRhZyhpbnQgZmllbGRfbnVtYmVyLCBXaXJlVHlwZSB0eXBlKSB7CisgIHJldHVybiBHT09HTEVfUFJPVE9CVUZfV0lSRV9GT1JNQVRfTUFLRV9UQUcoZmllbGRfbnVtYmVyLCB0eXBlKTsKK30KKworaW5saW5lIFdpcmVGb3JtYXRMaXRlOjpXaXJlVHlwZSBXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnV2lyZVR5cGUodWludDMyIHRhZykgeworICByZXR1cm4gc3RhdGljX2Nhc3Q8V2lyZVR5cGU+KHRhZyAmIGtUYWdUeXBlTWFzayk7Cit9CisKK2lubGluZSBpbnQgV2lyZUZvcm1hdExpdGU6OkdldFRhZ0ZpZWxkTnVtYmVyKHVpbnQzMiB0YWcpIHsKKyAgcmV0dXJuIHN0YXRpY19jYXN0PGludD4odGFnID4+IGtUYWdUeXBlQml0cyk7Cit9CisKK2lubGluZSBpbnQgV2lyZUZvcm1hdExpdGU6OlRhZ1NpemUoaW50IGZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSB0eXBlKSB7CisgIGludCByZXN1bHQgPSBpbzo6Q29kZWRPdXRwdXRTdHJlYW06OlZhcmludFNpemUzMigKKyAgICBmaWVsZF9udW1iZXIgPDwga1RhZ1R5cGVCaXRzKTsKKyAgaWYgKHR5cGUgPT0gVFlQRV9HUk9VUCkgeworICAgIC8vIEdyb3VwcyBoYXZlIGJvdGggYSBzdGFydCBhbmQgYW4gZW5kIHRhZy4KKyAgICByZXR1cm4gcmVzdWx0ICogMjsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gcmVzdWx0OworICB9Cit9CisKK2lubGluZSB1aW50MzIgV2lyZUZvcm1hdExpdGU6OkVuY29kZUZsb2F0KGZsb2F0IHZhbHVlKSB7CisgIHVuaW9uIHtmbG9hdCBmOyB1aW50MzIgaTt9OworICBmID0gdmFsdWU7CisgIHJldHVybiBpOworfQorCitpbmxpbmUgZmxvYXQgV2lyZUZvcm1hdExpdGU6OkRlY29kZUZsb2F0KHVpbnQzMiB2YWx1ZSkgeworICB1bmlvbiB7ZmxvYXQgZjsgdWludDMyIGk7fTsKKyAgaSA9IHZhbHVlOworICByZXR1cm4gZjsKK30KKworaW5saW5lIHVpbnQ2NCBXaXJlRm9ybWF0TGl0ZTo6RW5jb2RlRG91YmxlKGRvdWJsZSB2YWx1ZSkgeworICB1bmlvbiB7ZG91YmxlIGY7IHVpbnQ2NCBpO307CisgIGYgPSB2YWx1ZTsKKyAgcmV0dXJuIGk7Cit9CisKK2lubGluZSBkb3VibGUgV2lyZUZvcm1hdExpdGU6OkRlY29kZURvdWJsZSh1aW50NjQgdmFsdWUpIHsKKyAgdW5pb24ge2RvdWJsZSBmOyB1aW50NjQgaTt9OworICBpID0gdmFsdWU7CisgIHJldHVybiBmOworfQorCisvLyBaaWdaYWcgVHJhbnNmb3JtOiAgRW5jb2RlcyBzaWduZWQgaW50ZWdlcnMgc28gdGhhdCB0aGV5IGNhbiBiZQorLy8gZWZmZWN0aXZlbHkgdXNlZCB3aXRoIHZhcmludCBlbmNvZGluZy4KKy8vCisvLyB2YXJpbnQgb3BlcmF0ZXMgb24gdW5zaWduZWQgaW50ZWdlcnMsIGVuY29kaW5nIHNtYWxsZXIgbnVtYmVycyBpbnRvCisvLyBmZXdlciBieXRlcy4gIElmIHlvdSB0cnkgdG8gdXNlIGl0IG9uIGEgc2lnbmVkIGludGVnZXIsIGl0IHdpbGwgdHJlYXQKKy8vIHRoaXMgbnVtYmVyIGFzIGEgdmVyeSBsYXJnZSB1bnNpZ25lZCBpbnRlZ2VyLCB3aGljaCBtZWFucyB0aGF0IGV2ZW4KKy8vIHNtYWxsIHNpZ25lZCBudW1iZXJzIGxpa2UgLTEgd2lsbCB0YWtlIHRoZSBtYXhpbXVtIG51bWJlciBvZiBieXRlcworLy8gKDEwKSB0byBlbmNvZGUuICBaaWdaYWdFbmNvZGUoKSBtYXBzIHNpZ25lZCBpbnRlZ2VycyB0byB1bnNpZ25lZAorLy8gaW4gc3VjaCBhIHdheSB0aGF0IHRob3NlIHdpdGggYSBzbWFsbCBhYnNvbHV0ZSB2YWx1ZSB3aWxsIGhhdmUgc21hbGxlcgorLy8gZW5jb2RlZCB2YWx1ZXMsIG1ha2luZyB0aGVtIGFwcHJvcHJpYXRlIGZvciBlbmNvZGluZyB1c2luZyB2YXJpbnQuCisvLworLy8gICAgICAgaW50MzIgLT4gICAgIHVpbnQzMgorLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gICAgICAgICAgIDAgLT4gICAgICAgICAgMAorLy8gICAgICAgICAgLTEgLT4gICAgICAgICAgMQorLy8gICAgICAgICAgIDEgLT4gICAgICAgICAgMgorLy8gICAgICAgICAgLTIgLT4gICAgICAgICAgMworLy8gICAgICAgICAuLi4gLT4gICAgICAgIC4uLgorLy8gIDIxNDc0ODM2NDcgLT4gNDI5NDk2NzI5NAorLy8gLTIxNDc0ODM2NDggLT4gNDI5NDk2NzI5NQorLy8KKy8vICAgICAgICA+PiBlbmNvZGUgPj4KKy8vICAgICAgICA8PCBkZWNvZGUgPDwKKworaW5saW5lIHVpbnQzMiBXaXJlRm9ybWF0TGl0ZTo6WmlnWmFnRW5jb2RlMzIoaW50MzIgbikgeworICAvLyBOb3RlOiAgdGhlIHJpZ2h0LXNoaWZ0IG11c3QgYmUgYXJpdGhtZXRpYworICByZXR1cm4gKHN0YXRpY19jYXN0PHVpbnQzMj4obikgPDwgMSkgXiAobiA+PiAzMSk7Cit9CisKK2lubGluZSBpbnQzMiBXaXJlRm9ybWF0TGl0ZTo6WmlnWmFnRGVjb2RlMzIodWludDMyIG4pIHsKKyAgcmV0dXJuIChuID4+IDEpIF4gLXN0YXRpY19jYXN0PGludDMyPihuICYgMSk7Cit9CisKK2lubGluZSB1aW50NjQgV2lyZUZvcm1hdExpdGU6OlppZ1phZ0VuY29kZTY0KGludDY0IG4pIHsKKyAgLy8gTm90ZTogIHRoZSByaWdodC1zaGlmdCBtdXN0IGJlIGFyaXRobWV0aWMKKyAgcmV0dXJuIChzdGF0aWNfY2FzdDx1aW50NjQ+KG4pIDw8IDEpIF4gKG4gPj4gNjMpOworfQorCitpbmxpbmUgaW50NjQgV2lyZUZvcm1hdExpdGU6OlppZ1phZ0RlY29kZTY0KHVpbnQ2NCBuKSB7CisgIHJldHVybiAobiA+PiAxKSBeIC1zdGF0aWNfY2FzdDxpbnQ2ND4obiAmIDEpOworfQorCisvLyBTdHJpbmcgaXMgZm9yIFVURi04IHRleHQgb25seSwgYnV0LCBldmVuIHNvLCBSZWFkU3RyaW5nKCkgY2FuIHNpbXBseQorLy8gY2FsbCBSZWFkQnl0ZXMoKS4KKworaW5saW5lIGJvb2wgV2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nKiB2YWx1ZSkgeworICByZXR1cm4gUmVhZEJ5dGVzKGlucHV0LCB2YWx1ZSk7Cit9CisKK2lubGluZSBib29sIFdpcmVGb3JtYXRMaXRlOjpSZWFkU3RyaW5nKGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyoqIHApIHsKKyAgcmV0dXJuIFJlYWRCeXRlcyhpbnB1dCwgcCk7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX1dJUkVfRk9STUFUX0xJVEVfSF9fCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0X2xpdGVfaW5sLmggYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0X2xpdGVfaW5sLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzk0OTNjYQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZV9pbmwuaApAQCAtMCwwICsxLDg3OCBAQAorLy8gUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CisvLyBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCisvLworLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisvLyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCisvLyBtZXQ6CisvLworLy8gICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKy8vIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKKy8vIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKKy8vIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKy8vIGRpc3RyaWJ1dGlvbi4KKy8vICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKKy8vIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCisvLyB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorLy8KKy8vIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKKy8vICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKKy8vIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCisvLyBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKy8vIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAorLy8gREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCisvLyBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisvLyAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKKy8vIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisKKy8vIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKKy8vICAgICAgICAgd2lua0Bnb29nbGUuY29tIChXaW5rIFNhdmlsbGUpIChyZWZhY3RvcmVkIGZyb20gd2lyZV9mb3JtYXQuaCkKKy8vICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQorLy8gIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgorCisjaWZuZGVmIEdPT0dMRV9QUk9UT0JVRl9XSVJFX0ZPUk1BVF9MSVRFX0lOTF9IX18KKyNkZWZpbmUgR09PR0xFX1BST1RPQlVGX1dJUkVfRk9STUFUX0xJVEVfSU5MX0hfXworCisjaWZkZWYgX01TQ19WRVIKKy8vIFRoaXMgaXMgcmVxdWlyZWQgZm9yIG1pbi9tYXggb24gVlMyMDEzIG9ubHkuCisjaW5jbHVkZSA8YWxnb3JpdGhtPgorI2VuZGlmCisKKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL2NvbW1vbi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9sb2dnaW5nLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL21lc3NhZ2VfbGl0ZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9yZXBlYXRlZF9maWVsZC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdF9saXRlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9hcmVuYXN0cmluZy5oPgorCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKK25hbWVzcGFjZSBpbnRlcm5hbCB7CisKKy8vIEltcGxlbWVudGF0aW9uIGRldGFpbHMgb2YgUmVhZFByaW1pdGl2ZS4KKwordGVtcGxhdGUgPD4KK2lubGluZSBib29sIFdpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPGludDMyLCBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9JTlQzMj4oCisgICAgaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgIGludDMyKiB2YWx1ZSkgeworICB1aW50MzIgdGVtcDsKKyAgaWYgKCFpbnB1dC0+UmVhZFZhcmludDMyKCZ0ZW1wKSkgcmV0dXJuIGZhbHNlOworICAqdmFsdWUgPSBzdGF0aWNfY2FzdDxpbnQzMj4odGVtcCk7CisgIHJldHVybiB0cnVlOworfQordGVtcGxhdGUgPD4KK2lubGluZSBib29sIFdpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPGludDY0LCBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9JTlQ2ND4oCisgICAgaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgIGludDY0KiB2YWx1ZSkgeworICB1aW50NjQgdGVtcDsKKyAgaWYgKCFpbnB1dC0+UmVhZFZhcmludDY0KCZ0ZW1wKSkgcmV0dXJuIGZhbHNlOworICAqdmFsdWUgPSBzdGF0aWNfY2FzdDxpbnQ2ND4odGVtcCk7CisgIHJldHVybiB0cnVlOworfQordGVtcGxhdGUgPD4KK2lubGluZSBib29sIFdpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPHVpbnQzMiwgV2lyZUZvcm1hdExpdGU6OlRZUEVfVUlOVDMyPigKKyAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsCisgICAgdWludDMyKiB2YWx1ZSkgeworICByZXR1cm4gaW5wdXQtPlJlYWRWYXJpbnQzMih2YWx1ZSk7Cit9Cit0ZW1wbGF0ZSA8PgoraW5saW5lIGJvb2wgV2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8dWludDY0LCBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9VSU5UNjQ+KAorICAgIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICB1aW50NjQqIHZhbHVlKSB7CisgIHJldHVybiBpbnB1dC0+UmVhZFZhcmludDY0KHZhbHVlKTsKK30KK3RlbXBsYXRlIDw+CitpbmxpbmUgYm9vbCBXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTxpbnQzMiwgV2lyZUZvcm1hdExpdGU6OlRZUEVfU0lOVDMyPigKKyAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsCisgICAgaW50MzIqIHZhbHVlKSB7CisgIHVpbnQzMiB0ZW1wOworICBpZiAoIWlucHV0LT5SZWFkVmFyaW50MzIoJnRlbXApKSByZXR1cm4gZmFsc2U7CisgICp2YWx1ZSA9IFppZ1phZ0RlY29kZTMyKHRlbXApOworICByZXR1cm4gdHJ1ZTsKK30KK3RlbXBsYXRlIDw+CitpbmxpbmUgYm9vbCBXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTxpbnQ2NCwgV2lyZUZvcm1hdExpdGU6OlRZUEVfU0lOVDY0PigKKyAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsCisgICAgaW50NjQqIHZhbHVlKSB7CisgIHVpbnQ2NCB0ZW1wOworICBpZiAoIWlucHV0LT5SZWFkVmFyaW50NjQoJnRlbXApKSByZXR1cm4gZmFsc2U7CisgICp2YWx1ZSA9IFppZ1phZ0RlY29kZTY0KHRlbXApOworICByZXR1cm4gdHJ1ZTsKK30KK3RlbXBsYXRlIDw+CitpbmxpbmUgYm9vbCBXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTx1aW50MzIsIFdpcmVGb3JtYXRMaXRlOjpUWVBFX0ZJWEVEMzI+KAorICAgIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICB1aW50MzIqIHZhbHVlKSB7CisgIHJldHVybiBpbnB1dC0+UmVhZExpdHRsZUVuZGlhbjMyKHZhbHVlKTsKK30KK3RlbXBsYXRlIDw+CitpbmxpbmUgYm9vbCBXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTx1aW50NjQsIFdpcmVGb3JtYXRMaXRlOjpUWVBFX0ZJWEVENjQ+KAorICAgIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICB1aW50NjQqIHZhbHVlKSB7CisgIHJldHVybiBpbnB1dC0+UmVhZExpdHRsZUVuZGlhbjY0KHZhbHVlKTsKK30KK3RlbXBsYXRlIDw+CitpbmxpbmUgYm9vbCBXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTxpbnQzMiwgV2lyZUZvcm1hdExpdGU6OlRZUEVfU0ZJWEVEMzI+KAorICAgIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICBpbnQzMiogdmFsdWUpIHsKKyAgdWludDMyIHRlbXA7CisgIGlmICghaW5wdXQtPlJlYWRMaXR0bGVFbmRpYW4zMigmdGVtcCkpIHJldHVybiBmYWxzZTsKKyAgKnZhbHVlID0gc3RhdGljX2Nhc3Q8aW50MzI+KHRlbXApOworICByZXR1cm4gdHJ1ZTsKK30KK3RlbXBsYXRlIDw+CitpbmxpbmUgYm9vbCBXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTxpbnQ2NCwgV2lyZUZvcm1hdExpdGU6OlRZUEVfU0ZJWEVENjQ+KAorICAgIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICBpbnQ2NCogdmFsdWUpIHsKKyAgdWludDY0IHRlbXA7CisgIGlmICghaW5wdXQtPlJlYWRMaXR0bGVFbmRpYW42NCgmdGVtcCkpIHJldHVybiBmYWxzZTsKKyAgKnZhbHVlID0gc3RhdGljX2Nhc3Q8aW50NjQ+KHRlbXApOworICByZXR1cm4gdHJ1ZTsKK30KK3RlbXBsYXRlIDw+CitpbmxpbmUgYm9vbCBXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTxmbG9hdCwgV2lyZUZvcm1hdExpdGU6OlRZUEVfRkxPQVQ+KAorICAgIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICBmbG9hdCogdmFsdWUpIHsKKyAgdWludDMyIHRlbXA7CisgIGlmICghaW5wdXQtPlJlYWRMaXR0bGVFbmRpYW4zMigmdGVtcCkpIHJldHVybiBmYWxzZTsKKyAgKnZhbHVlID0gRGVjb2RlRmxvYXQodGVtcCk7CisgIHJldHVybiB0cnVlOworfQordGVtcGxhdGUgPD4KK2lubGluZSBib29sIFdpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPGRvdWJsZSwgV2lyZUZvcm1hdExpdGU6OlRZUEVfRE9VQkxFPigKKyAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsCisgICAgZG91YmxlKiB2YWx1ZSkgeworICB1aW50NjQgdGVtcDsKKyAgaWYgKCFpbnB1dC0+UmVhZExpdHRsZUVuZGlhbjY0KCZ0ZW1wKSkgcmV0dXJuIGZhbHNlOworICAqdmFsdWUgPSBEZWNvZGVEb3VibGUodGVtcCk7CisgIHJldHVybiB0cnVlOworfQordGVtcGxhdGUgPD4KK2lubGluZSBib29sIFdpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPGJvb2wsIFdpcmVGb3JtYXRMaXRlOjpUWVBFX0JPT0w+KAorICAgIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICBib29sKiB2YWx1ZSkgeworICB1aW50NjQgdGVtcDsKKyAgaWYgKCFpbnB1dC0+UmVhZFZhcmludDY0KCZ0ZW1wKSkgcmV0dXJuIGZhbHNlOworICAqdmFsdWUgPSB0ZW1wICE9IDA7CisgIHJldHVybiB0cnVlOworfQordGVtcGxhdGUgPD4KK2lubGluZSBib29sIFdpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPGludCwgV2lyZUZvcm1hdExpdGU6OlRZUEVfRU5VTT4oCisgICAgaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgIGludCogdmFsdWUpIHsKKyAgdWludDMyIHRlbXA7CisgIGlmICghaW5wdXQtPlJlYWRWYXJpbnQzMigmdGVtcCkpIHJldHVybiBmYWxzZTsKKyAgKnZhbHVlID0gc3RhdGljX2Nhc3Q8aW50Pih0ZW1wKTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK3RlbXBsYXRlIDw+CitpbmxpbmUgY29uc3QgdWludDgqIFdpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlRnJvbUFycmF5PAorICB1aW50MzIsIFdpcmVGb3JtYXRMaXRlOjpUWVBFX0ZJWEVEMzI+KAorICAgIGNvbnN0IHVpbnQ4KiBidWZmZXIsCisgICAgdWludDMyKiB2YWx1ZSkgeworICByZXR1cm4gaW86OkNvZGVkSW5wdXRTdHJlYW06OlJlYWRMaXR0bGVFbmRpYW4zMkZyb21BcnJheShidWZmZXIsIHZhbHVlKTsKK30KK3RlbXBsYXRlIDw+CitpbmxpbmUgY29uc3QgdWludDgqIFdpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlRnJvbUFycmF5PAorICB1aW50NjQsIFdpcmVGb3JtYXRMaXRlOjpUWVBFX0ZJWEVENjQ+KAorICAgIGNvbnN0IHVpbnQ4KiBidWZmZXIsCisgICAgdWludDY0KiB2YWx1ZSkgeworICByZXR1cm4gaW86OkNvZGVkSW5wdXRTdHJlYW06OlJlYWRMaXR0bGVFbmRpYW42NEZyb21BcnJheShidWZmZXIsIHZhbHVlKTsKK30KK3RlbXBsYXRlIDw+CitpbmxpbmUgY29uc3QgdWludDgqIFdpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlRnJvbUFycmF5PAorICBpbnQzMiwgV2lyZUZvcm1hdExpdGU6OlRZUEVfU0ZJWEVEMzI+KAorICAgIGNvbnN0IHVpbnQ4KiBidWZmZXIsCisgICAgaW50MzIqIHZhbHVlKSB7CisgIHVpbnQzMiB0ZW1wOworICBidWZmZXIgPSBpbzo6Q29kZWRJbnB1dFN0cmVhbTo6UmVhZExpdHRsZUVuZGlhbjMyRnJvbUFycmF5KGJ1ZmZlciwgJnRlbXApOworICAqdmFsdWUgPSBzdGF0aWNfY2FzdDxpbnQzMj4odGVtcCk7CisgIHJldHVybiBidWZmZXI7Cit9Cit0ZW1wbGF0ZSA8PgoraW5saW5lIGNvbnN0IHVpbnQ4KiBXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZUZyb21BcnJheTwKKyAgaW50NjQsIFdpcmVGb3JtYXRMaXRlOjpUWVBFX1NGSVhFRDY0PigKKyAgICBjb25zdCB1aW50OCogYnVmZmVyLAorICAgIGludDY0KiB2YWx1ZSkgeworICB1aW50NjQgdGVtcDsKKyAgYnVmZmVyID0gaW86OkNvZGVkSW5wdXRTdHJlYW06OlJlYWRMaXR0bGVFbmRpYW42NEZyb21BcnJheShidWZmZXIsICZ0ZW1wKTsKKyAgKnZhbHVlID0gc3RhdGljX2Nhc3Q8aW50NjQ+KHRlbXApOworICByZXR1cm4gYnVmZmVyOworfQordGVtcGxhdGUgPD4KK2lubGluZSBjb25zdCB1aW50OCogV2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmVGcm9tQXJyYXk8CisgIGZsb2F0LCBXaXJlRm9ybWF0TGl0ZTo6VFlQRV9GTE9BVD4oCisgICAgY29uc3QgdWludDgqIGJ1ZmZlciwKKyAgICBmbG9hdCogdmFsdWUpIHsKKyAgdWludDMyIHRlbXA7CisgIGJ1ZmZlciA9IGlvOjpDb2RlZElucHV0U3RyZWFtOjpSZWFkTGl0dGxlRW5kaWFuMzJGcm9tQXJyYXkoYnVmZmVyLCAmdGVtcCk7CisgICp2YWx1ZSA9IERlY29kZUZsb2F0KHRlbXApOworICByZXR1cm4gYnVmZmVyOworfQordGVtcGxhdGUgPD4KK2lubGluZSBjb25zdCB1aW50OCogV2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmVGcm9tQXJyYXk8CisgIGRvdWJsZSwgV2lyZUZvcm1hdExpdGU6OlRZUEVfRE9VQkxFPigKKyAgICBjb25zdCB1aW50OCogYnVmZmVyLAorICAgIGRvdWJsZSogdmFsdWUpIHsKKyAgdWludDY0IHRlbXA7CisgIGJ1ZmZlciA9IGlvOjpDb2RlZElucHV0U3RyZWFtOjpSZWFkTGl0dGxlRW5kaWFuNjRGcm9tQXJyYXkoYnVmZmVyLCAmdGVtcCk7CisgICp2YWx1ZSA9IERlY29kZURvdWJsZSh0ZW1wKTsKKyAgcmV0dXJuIGJ1ZmZlcjsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIENUeXBlLCBlbnVtIFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUgRGVjbGFyZWRUeXBlPgoraW5saW5lIGJvb2wgV2lyZUZvcm1hdExpdGU6OlJlYWRSZXBlYXRlZFByaW1pdGl2ZSgKKyAgICBpbnQsICAvLyB0YWdfc2l6ZSwgdW51c2VkLgorICAgIHVpbnQzMiB0YWcsCisgICAgaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgIFJlcGVhdGVkRmllbGQ8Q1R5cGU+KiB2YWx1ZXMpIHsKKyAgQ1R5cGUgdmFsdWU7CisgIGlmICghUmVhZFByaW1pdGl2ZTxDVHlwZSwgRGVjbGFyZWRUeXBlPihpbnB1dCwgJnZhbHVlKSkgcmV0dXJuIGZhbHNlOworICB2YWx1ZXMtPkFkZCh2YWx1ZSk7CisgIGludCBlbGVtZW50c19hbHJlYWR5X3Jlc2VydmVkID0gdmFsdWVzLT5DYXBhY2l0eSgpIC0gdmFsdWVzLT5zaXplKCk7CisgIHdoaWxlIChlbGVtZW50c19hbHJlYWR5X3Jlc2VydmVkID4gMCAmJiBpbnB1dC0+RXhwZWN0VGFnKHRhZykpIHsKKyAgICBpZiAoIVJlYWRQcmltaXRpdmU8Q1R5cGUsIERlY2xhcmVkVHlwZT4oaW5wdXQsICZ2YWx1ZSkpIHJldHVybiBmYWxzZTsKKyAgICB2YWx1ZXMtPkFkZEFscmVhZHlSZXNlcnZlZCh2YWx1ZSk7CisgICAgZWxlbWVudHNfYWxyZWFkeV9yZXNlcnZlZC0tOworICB9CisgIHJldHVybiB0cnVlOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgQ1R5cGUsIGVudW0gV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBEZWNsYXJlZFR5cGU+CitpbmxpbmUgYm9vbCBXaXJlRm9ybWF0TGl0ZTo6UmVhZFJlcGVhdGVkRml4ZWRTaXplUHJpbWl0aXZlKAorICAgIGludCB0YWdfc2l6ZSwKKyAgICB1aW50MzIgdGFnLAorICAgIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICBSZXBlYXRlZEZpZWxkPENUeXBlPiogdmFsdWVzKSB7CisgIEdPT0dMRV9EQ0hFQ0tfRVEoVUludDMyU2l6ZSh0YWcpLCB0YWdfc2l6ZSk7CisgIENUeXBlIHZhbHVlOworICBpZiAoIVJlYWRQcmltaXRpdmU8Q1R5cGUsIERlY2xhcmVkVHlwZT4oaW5wdXQsICZ2YWx1ZSkpCisgICAgcmV0dXJuIGZhbHNlOworICB2YWx1ZXMtPkFkZCh2YWx1ZSk7CisKKyAgLy8gRm9yIGZpeGVkIHNpemUgdmFsdWVzLCByZXBlYXRlZCB2YWx1ZXMgY2FuIGJlIHJlYWQgbW9yZSBxdWlja2x5IGJ5CisgIC8vIHJlYWRpbmcgZGlyZWN0bHkgZnJvbSBhIHJhdyBhcnJheS4KKyAgLy8KKyAgLy8gV2UgY2FuIGdldCBhIHRpZ2h0IGxvb3AgYnkgb25seSByZWFkaW5nIGFzIG1hbnkgZWxlbWVudHMgYXMgY2FuIGJlCisgIC8vIGFkZGVkIHRvIHRoZSBSZXBlYXRlZEZpZWxkIHdpdGhvdXQgaGF2aW5nIHRvIGRvIGFueSByZXNpemluZy4gQWRkaXRpb25hbGx5LAorICAvLyB3ZSBvbmx5IHRyeSB0byByZWFkIGFzIG1hbnkgZWxlbWVudHMgYXMgYXJlIGF2YWlsYWJsZSBmcm9tIHRoZSBjdXJyZW50CisgIC8vIGJ1ZmZlciBzcGFjZS4gRG9pbmcgc28gYXZvaWRzIGhhdmluZyB0byBwZXJmb3JtIGJvdW5kYXJ5IGNoZWNrcyB3aGVuCisgIC8vIHJlYWRpbmcgdGhlIHZhbHVlOiB0aGUgbWF4aW11bSBudW1iZXIgb2YgZWxlbWVudHMgdGhhdCBjYW4gYmUgcmVhZCBpcworICAvLyBrbm93biBvdXRzaWRlIG9mIHRoZSBsb29wLgorICBjb25zdCB2b2lkKiB2b2lkX3BvaW50ZXI7CisgIGludCBzaXplOworICBpbnB1dC0+R2V0RGlyZWN0QnVmZmVyUG9pbnRlcklubGluZSgmdm9pZF9wb2ludGVyLCAmc2l6ZSk7CisgIGlmIChzaXplID4gMCkgeworICAgIGNvbnN0IHVpbnQ4KiBidWZmZXIgPSByZWludGVycHJldF9jYXN0PGNvbnN0IHVpbnQ4Kj4odm9pZF9wb2ludGVyKTsKKyAgICAvLyBUaGUgbnVtYmVyIG9mIGJ5dGVzIGVhY2ggdHlwZSBvY2N1cGllcyBvbiB0aGUgd2lyZS4KKyAgICBjb25zdCBpbnQgcGVyX3ZhbHVlX3NpemUgPSB0YWdfc2l6ZSArIHNpemVvZih2YWx1ZSk7CisKKyAgICBpbnQgZWxlbWVudHNfYXZhaWxhYmxlID0gbWluKHZhbHVlcy0+Q2FwYWNpdHkoKSAtIHZhbHVlcy0+c2l6ZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZSAvIHBlcl92YWx1ZV9zaXplKTsKKyAgICBpbnQgbnVtX3JlYWQgPSAwOworICAgIHdoaWxlIChudW1fcmVhZCA8IGVsZW1lbnRzX2F2YWlsYWJsZSAmJgorICAgICAgICAgICAoYnVmZmVyID0gaW86OkNvZGVkSW5wdXRTdHJlYW06OkV4cGVjdFRhZ0Zyb21BcnJheSgKKyAgICAgICAgICAgICAgIGJ1ZmZlciwgdGFnKSkgIT0gTlVMTCkgeworICAgICAgYnVmZmVyID0gUmVhZFByaW1pdGl2ZUZyb21BcnJheTxDVHlwZSwgRGVjbGFyZWRUeXBlPihidWZmZXIsICZ2YWx1ZSk7CisgICAgICB2YWx1ZXMtPkFkZEFscmVhZHlSZXNlcnZlZCh2YWx1ZSk7CisgICAgICArK251bV9yZWFkOworICAgIH0KKyAgICBjb25zdCBpbnQgcmVhZF9ieXRlcyA9IG51bV9yZWFkICogcGVyX3ZhbHVlX3NpemU7CisgICAgaWYgKHJlYWRfYnl0ZXMgPiAwKSB7CisgICAgICBpbnB1dC0+U2tpcChyZWFkX2J5dGVzKTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKKy8vIFNwZWNpYWxpemF0aW9ucyBvZiBSZWFkUmVwZWF0ZWRQcmltaXRpdmUgZm9yIHRoZSBmaXhlZCBzaXplIHR5cGVzLCB3aGljaCB1c2UKKy8vIHRoZSBvcHRpbWl6ZWQgY29kZSBwYXRoLgorI2RlZmluZSBSRUFEX1JFUEVBVEVEX0ZJWEVEX1NJWkVfUFJJTUlUSVZFKENQUFRZUEUsIERFQ0xBUkVEX1RZUEUpICAgICAgICAgICAgIFwKK3RlbXBsYXRlIDw+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCitpbmxpbmUgYm9vbCBXaXJlRm9ybWF0TGl0ZTo6UmVhZFJlcGVhdGVkUHJpbWl0aXZlPCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBDUFBUWVBFLCBXaXJlRm9ybWF0TGl0ZTo6REVDTEFSRURfVFlQRT4oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBpbnQgdGFnX3NpemUsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgdWludDMyIHRhZywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBSZXBlYXRlZEZpZWxkPENQUFRZUEU+KiB2YWx1ZXMpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIHJldHVybiBSZWFkUmVwZWF0ZWRGaXhlZFNpemVQcmltaXRpdmU8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIENQUFRZUEUsIFdpcmVGb3JtYXRMaXRlOjpERUNMQVJFRF9UWVBFPiggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgIHRhZ19zaXplLCB0YWcsIGlucHV0LCB2YWx1ZXMpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCit9CisKK1JFQURfUkVQRUFURURfRklYRURfU0laRV9QUklNSVRJVkUodWludDMyLCBUWVBFX0ZJWEVEMzIpCitSRUFEX1JFUEVBVEVEX0ZJWEVEX1NJWkVfUFJJTUlUSVZFKHVpbnQ2NCwgVFlQRV9GSVhFRDY0KQorUkVBRF9SRVBFQVRFRF9GSVhFRF9TSVpFX1BSSU1JVElWRShpbnQzMiwgVFlQRV9TRklYRUQzMikKK1JFQURfUkVQRUFURURfRklYRURfU0laRV9QUklNSVRJVkUoaW50NjQsIFRZUEVfU0ZJWEVENjQpCitSRUFEX1JFUEVBVEVEX0ZJWEVEX1NJWkVfUFJJTUlUSVZFKGZsb2F0LCBUWVBFX0ZMT0FUKQorUkVBRF9SRVBFQVRFRF9GSVhFRF9TSVpFX1BSSU1JVElWRShkb3VibGUsIFRZUEVfRE9VQkxFKQorCisjdW5kZWYgUkVBRF9SRVBFQVRFRF9GSVhFRF9TSVpFX1BSSU1JVElWRQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgQ1R5cGUsIGVudW0gV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBEZWNsYXJlZFR5cGU+Citib29sIFdpcmVGb3JtYXRMaXRlOjpSZWFkUmVwZWF0ZWRQcmltaXRpdmVOb0lubGluZSgKKyAgICBpbnQgdGFnX3NpemUsCisgICAgdWludDMyIHRhZywKKyAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsCisgICAgUmVwZWF0ZWRGaWVsZDxDVHlwZT4qIHZhbHVlKSB7CisgIHJldHVybiBSZWFkUmVwZWF0ZWRQcmltaXRpdmU8Q1R5cGUsIERlY2xhcmVkVHlwZT4oCisgICAgICB0YWdfc2l6ZSwgdGFnLCBpbnB1dCwgdmFsdWUpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgQ1R5cGUsIGVudW0gV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBEZWNsYXJlZFR5cGU+CitpbmxpbmUgYm9vbCBXaXJlRm9ybWF0TGl0ZTo6UmVhZFBhY2tlZFByaW1pdGl2ZShpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXBlYXRlZEZpZWxkPENUeXBlPiogdmFsdWVzKSB7CisgIHVpbnQzMiBsZW5ndGg7CisgIGlmICghaW5wdXQtPlJlYWRWYXJpbnQzMigmbGVuZ3RoKSkgcmV0dXJuIGZhbHNlOworICBpbzo6Q29kZWRJbnB1dFN0cmVhbTo6TGltaXQgbGltaXQgPSBpbnB1dC0+UHVzaExpbWl0KGxlbmd0aCk7CisgIHdoaWxlIChpbnB1dC0+Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CisgICAgQ1R5cGUgdmFsdWU7CisgICAgaWYgKCFSZWFkUHJpbWl0aXZlPENUeXBlLCBEZWNsYXJlZFR5cGU+KGlucHV0LCAmdmFsdWUpKSByZXR1cm4gZmFsc2U7CisgICAgdmFsdWVzLT5BZGQodmFsdWUpOworICB9CisgIGlucHV0LT5Qb3BMaW1pdChsaW1pdCk7CisgIHJldHVybiB0cnVlOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgQ1R5cGUsIGVudW0gV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZSBEZWNsYXJlZFR5cGU+CitpbmxpbmUgYm9vbCBXaXJlRm9ybWF0TGl0ZTo6UmVhZFBhY2tlZEZpeGVkU2l6ZVByaW1pdGl2ZSgKKyAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsIFJlcGVhdGVkRmllbGQ8Q1R5cGU+KiB2YWx1ZXMpIHsKKyAgdWludDMyIGxlbmd0aDsKKyAgaWYgKCFpbnB1dC0+UmVhZFZhcmludDMyKCZsZW5ndGgpKSByZXR1cm4gZmFsc2U7CisgIGNvbnN0IHVpbnQzMiBvbGRfZW50cmllcyA9IHZhbHVlcy0+c2l6ZSgpOworICBjb25zdCB1aW50MzIgbmV3X2VudHJpZXMgPSBsZW5ndGggLyBzaXplb2YoQ1R5cGUpOworICBjb25zdCB1aW50MzIgbmV3X2J5dGVzID0gbmV3X2VudHJpZXMgKiBzaXplb2YoQ1R5cGUpOworICBpZiAobmV3X2J5dGVzICE9IGxlbmd0aCkgcmV0dXJuIGZhbHNlOworICAvLyBXZSB3b3VsZCAqbGlrZSogdG8gcHJlLWFsbG9jYXRlIHRoZSBidWZmZXIgdG8gd3JpdGUgaW50byAoZm9yCisgIC8vIHNwZWVkKSwgYnV0ICptdXN0KiBhdm9pZCBwZXJmb3JtaW5nIGEgdmVyeSBsYXJnZSBhbGxvY2F0aW9uIGR1ZQorICAvLyB0byBhIG1hbGljaW91cyB1c2VyLXN1cHBsaWVkICJsZW5ndGgiIGFib3ZlLiAgU28gd2UgaGF2ZSBhIGZhc3QKKyAgLy8gcGF0aCB0aGF0IHByZS1hbGxvY2F0ZXMgd2hlbiB0aGUgImxlbmd0aCIgaXMgbGVzcyB0aGFuIGEgYm91bmQuCisgIC8vIFdlIGRldGVybWluZSB0aGUgYm91bmQgYnkgY2FsbGluZyBCeXRlc1VudGlsVG90YWxCeXRlc0xpbWl0KCkgYW5kCisgIC8vIEJ5dGVzVW50aWxMaW1pdCgpLiAgVGhlc2UgcmV0dXJuIC0xIHRvIG1lYW4gIm5vIGxpbWl0IHNldCIuCisgIC8vIFRoZXJlIGFyZSBmb3VyIGNhc2VzOgorICAvLyBUb3RhbEJ5dGVzTGltaXQgIExpbWl0CisgIC8vIC0xICAgICAgICAgICAgICAgLTEgICAgIFVzZSBzbG93IHBhdGguCisgIC8vIC0xICAgICAgICAgICAgICAgPj0gMCAgIFVzZSBmYXN0IHBhdGggaWYgbGVuZ3RoIDw9IExpbWl0LgorICAvLyA+PSAwICAgICAgICAgICAgIC0xICAgICBVc2Ugc2xvdyBwYXRoLgorICAvLyA+PSAwICAgICAgICAgICAgID49IDAgICBVc2UgZmFzdCBwYXRoIGlmIGxlbmd0aCA8PSBtaW4oYm90aCBsaW1pdHMpLgorICBpbnQ2NCBieXRlc19saW1pdCA9IGlucHV0LT5CeXRlc1VudGlsVG90YWxCeXRlc0xpbWl0KCk7CisgIGlmIChieXRlc19saW1pdCA9PSAtMSkgeworICAgIGJ5dGVzX2xpbWl0ID0gaW5wdXQtPkJ5dGVzVW50aWxMaW1pdCgpOworICB9IGVsc2UgeworICAgIGJ5dGVzX2xpbWl0ID0KKyAgICAgICAgbWluKGJ5dGVzX2xpbWl0LCBzdGF0aWNfY2FzdDxpbnQ2ND4oaW5wdXQtPkJ5dGVzVW50aWxMaW1pdCgpKSk7CisgIH0KKyAgaWYgKGJ5dGVzX2xpbWl0ID49IG5ld19ieXRlcykgeworICAgIC8vIEZhc3QtcGF0aCB0aGF0IHByZS1hbGxvY2F0ZXMgKnZhbHVlcyB0byB0aGUgZmluYWwgc2l6ZS4KKyNpZiBkZWZpbmVkKFBST1RPQlVGX0xJVFRMRV9FTkRJQU4pCisgICAgdmFsdWVzLT5SZXNpemUob2xkX2VudHJpZXMgKyBuZXdfZW50cmllcywgMCk7CisgICAgLy8gdmFsdWVzLT5tdXRhYmxlX2RhdGEoKSBtYXkgY2hhbmdlIGFmdGVyIFJlc2l6ZSgpLCBzbyBkbyB0aGlzIGFmdGVyOgorICAgIHZvaWQqIGRlc3QgPSByZWludGVycHJldF9jYXN0PHZvaWQqPih2YWx1ZXMtPm11dGFibGVfZGF0YSgpICsgb2xkX2VudHJpZXMpOworICAgIGlmICghaW5wdXQtPlJlYWRSYXcoZGVzdCwgbmV3X2J5dGVzKSkgeworICAgICAgdmFsdWVzLT5UcnVuY2F0ZShvbGRfZW50cmllcyk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorI2Vsc2UKKyAgICB2YWx1ZXMtPlJlc2VydmUob2xkX2VudHJpZXMgKyBuZXdfZW50cmllcyk7CisgICAgQ1R5cGUgdmFsdWU7CisgICAgZm9yICh1aW50MzIgaSA9IDA7IGkgPCBuZXdfZW50cmllczsgKytpKSB7CisgICAgICBpZiAoIVJlYWRQcmltaXRpdmU8Q1R5cGUsIERlY2xhcmVkVHlwZT4oaW5wdXQsICZ2YWx1ZSkpIHJldHVybiBmYWxzZTsKKyAgICAgIHZhbHVlcy0+QWRkQWxyZWFkeVJlc2VydmVkKHZhbHVlKTsKKyAgICB9CisjZW5kaWYKKyAgfSBlbHNlIHsKKyAgICAvLyBUaGlzIGlzIHRoZSBzbG93LXBhdGggY2FzZSB3aGVyZSAibGVuZ3RoIiBtYXkgYmUgdG9vIGxhcmdlIHRvCisgICAgLy8gc2FmZWx5IGFsbG9jYXRlLiAgV2UgcmVhZCBhcyBtdWNoIGFzIHdlIGNhbiBpbnRvICp2YWx1ZXMKKyAgICAvLyB3aXRob3V0IHByZS1hbGxvY2F0aW5nICJsZW5ndGgiIGJ5dGVzLgorICAgIENUeXBlIHZhbHVlOworICAgIGZvciAodWludDMyIGkgPSAwOyBpIDwgbmV3X2VudHJpZXM7ICsraSkgeworICAgICAgaWYgKCFSZWFkUHJpbWl0aXZlPENUeXBlLCBEZWNsYXJlZFR5cGU+KGlucHV0LCAmdmFsdWUpKSByZXR1cm4gZmFsc2U7CisgICAgICB2YWx1ZXMtPkFkZCh2YWx1ZSk7CisgICAgfQorICB9CisgIHJldHVybiB0cnVlOworfQorCisvLyBTcGVjaWFsaXphdGlvbnMgb2YgUmVhZFBhY2tlZFByaW1pdGl2ZSBmb3IgdGhlIGZpeGVkIHNpemUgdHlwZXMsIHdoaWNoIHVzZQorLy8gYW4gb3B0aW1pemVkIGNvZGUgcGF0aC4KKyNkZWZpbmUgUkVBRF9SRVBFQVRFRF9QQUNLRURfRklYRURfU0laRV9QUklNSVRJVkUoQ1BQVFlQRSwgREVDTEFSRURfVFlQRSkgICAgICBcCit0ZW1wbGF0ZSA8PiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAoraW5saW5lIGJvb2wgV2lyZUZvcm1hdExpdGU6OlJlYWRQYWNrZWRQcmltaXRpdmU8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgQ1BQVFlQRSwgV2lyZUZvcm1hdExpdGU6OkRFQ0xBUkVEX1RZUEU+KCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIFJlcGVhdGVkRmllbGQ8Q1BQVFlQRT4qIHZhbHVlcykgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgcmV0dXJuIFJlYWRQYWNrZWRGaXhlZFNpemVQcmltaXRpdmU8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICBDUFBUWVBFLCBXaXJlRm9ybWF0TGl0ZTo6REVDTEFSRURfVFlQRT4oaW5wdXQsIHZhbHVlcyk7ICAgICAgICAgICAgICAgICAgXAorfQorCitSRUFEX1JFUEVBVEVEX1BBQ0tFRF9GSVhFRF9TSVpFX1BSSU1JVElWRSh1aW50MzIsIFRZUEVfRklYRUQzMikKK1JFQURfUkVQRUFURURfUEFDS0VEX0ZJWEVEX1NJWkVfUFJJTUlUSVZFKHVpbnQ2NCwgVFlQRV9GSVhFRDY0KQorUkVBRF9SRVBFQVRFRF9QQUNLRURfRklYRURfU0laRV9QUklNSVRJVkUoaW50MzIsIFRZUEVfU0ZJWEVEMzIpCitSRUFEX1JFUEVBVEVEX1BBQ0tFRF9GSVhFRF9TSVpFX1BSSU1JVElWRShpbnQ2NCwgVFlQRV9TRklYRUQ2NCkKK1JFQURfUkVQRUFURURfUEFDS0VEX0ZJWEVEX1NJWkVfUFJJTUlUSVZFKGZsb2F0LCBUWVBFX0ZMT0FUKQorUkVBRF9SRVBFQVRFRF9QQUNLRURfRklYRURfU0laRV9QUklNSVRJVkUoZG91YmxlLCBUWVBFX0RPVUJMRSkKKworI3VuZGVmIFJFQURfUkVQRUFURURfUEFDS0VEX0ZJWEVEX1NJWkVfUFJJTUlUSVZFCisKK3RlbXBsYXRlIDx0eXBlbmFtZSBDVHlwZSwgZW51bSBXaXJlRm9ybWF0TGl0ZTo6RmllbGRUeXBlIERlY2xhcmVkVHlwZT4KK2Jvb2wgV2lyZUZvcm1hdExpdGU6OlJlYWRQYWNrZWRQcmltaXRpdmVOb0lubGluZShpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVwZWF0ZWRGaWVsZDxDVHlwZT4qIHZhbHVlcykgeworICByZXR1cm4gUmVhZFBhY2tlZFByaW1pdGl2ZTxDVHlwZSwgRGVjbGFyZWRUeXBlPihpbnB1dCwgdmFsdWVzKTsKK30KKworCisKK2lubGluZSBib29sIFdpcmVGb3JtYXRMaXRlOjpSZWFkR3JvdXAoaW50IGZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlTGl0ZSogdmFsdWUpIHsKKyAgaWYgKCFpbnB1dC0+SW5jcmVtZW50UmVjdXJzaW9uRGVwdGgoKSkgcmV0dXJuIGZhbHNlOworICBpZiAoIXZhbHVlLT5NZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oaW5wdXQpKSByZXR1cm4gZmFsc2U7CisgIGlucHV0LT5EZWNyZW1lbnRSZWN1cnNpb25EZXB0aCgpOworICAvLyBNYWtlIHN1cmUgdGhlIGxhc3QgdGhpbmcgcmVhZCB3YXMgYW4gZW5kIHRhZyBmb3IgdGhpcyBncm91cC4KKyAgaWYgKCFpbnB1dC0+TGFzdFRhZ1dhcyhNYWtlVGFnKGZpZWxkX251bWJlciwgV0lSRVRZUEVfRU5EX0dST1VQKSkpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CitpbmxpbmUgYm9vbCBXaXJlRm9ybWF0TGl0ZTo6UmVhZE1lc3NhZ2UoaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VMaXRlKiB2YWx1ZSkgeworICB1aW50MzIgbGVuZ3RoOworICBpZiAoIWlucHV0LT5SZWFkVmFyaW50MzIoJmxlbmd0aCkpIHJldHVybiBmYWxzZTsKKyAgc3RkOjpwYWlyPGlvOjpDb2RlZElucHV0U3RyZWFtOjpMaW1pdCwgaW50PiBwID0KKyAgICAgIGlucHV0LT5JbmNyZW1lbnRSZWN1cnNpb25EZXB0aEFuZFB1c2hMaW1pdChsZW5ndGgpOworICBpZiAocC5zZWNvbmQgPCAwIHx8ICF2YWx1ZS0+TWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKGlucHV0KSkgcmV0dXJuIGZhbHNlOworICAvLyBNYWtlIHN1cmUgdGhhdCBwYXJzaW5nIHN0b3BwZWQgd2hlbiB0aGUgbGltaXQgd2FzIGhpdCwgbm90IGF0IGFuIGVuZGdyb3VwCisgIC8vIHRhZy4KKyAgcmV0dXJuIGlucHV0LT5EZWNyZW1lbnRSZWN1cnNpb25EZXB0aEFuZFBvcExpbWl0KHAuZmlyc3QpOworfQorCisvLyBXZSBuYW1lIHRoZSB0ZW1wbGF0ZSBwYXJhbWV0ZXIgc29tZXRoaW5nIGxvbmcgYW5kIGV4dHJlbWVseSB1bmxpa2VseSB0byBvY2N1cgorLy8gZWxzZXdoZXJlIGJlY2F1c2UgYSAqcXVhbGlmaWVkKiBtZW1iZXIgYWNjZXNzIGV4cHJlc3Npb24gZGVzaWduZWQgdG8gYXZvaWQKKy8vIHZpcnR1YWwgZGlzcGF0Y2gsIEMrKzAzIFtiYXNpYy5sb29rdXAuY2xhc3NyZWZdIDMuNC41LzQgcmVxdWlyZXMgdGhhdCB0aGUKKy8vIG5hbWUgb2YgdGhlIHF1YWxpZnlpbmcgY2xhc3MgdG8gYmUgbG9va2VkIHVwIGJvdGggaW4gdGhlIGNvbnRleHQgb2YgdGhlIGZ1bGwKKy8vIGV4cHJlc3Npb24gKGZpbmRpbmcgdGhlIHRlbXBsYXRlIHBhcmFtZXRlcikgYW5kIGluIHRoZSBjb250ZXh0IG9mIHRoZSBvYmplY3QKKy8vIHdob3NlIG1lbWJlciB3ZSBhcmUgYWNjZXNzaW5nLiBUaGlzIGNvdWxkIHBvdGVudGlhbGx5IGZpbmQgYSBuZXN0ZWQgdHlwZQorLy8gd2l0aGluIHRoYXQgb2JqZWN0LiBUaGUgc3RhbmRhcmQgZ29lcyBvbiB0byByZXF1aXJlIHRoZXNlIG5hbWVzIHRvIHJlZmVyIHRvCisvLyB0aGUgc2FtZSBlbnRpdHksIHdoaWNoIHRoaXMgY29sbGlzaW9uIHdvdWxkIHZpb2xhdGUuIFRoZSBsYWNrIG9mIGEgc2FmZSB3YXkKKy8vIHRvIGF2b2lkIHRoaXMgY29sbGlzaW9uIGFwcGVhcnMgdG8gYmUgYSBkZWZlY3QgaW4gdGhlIHN0YW5kYXJkLCBidXQgdW50aWwgaXQKKy8vIGlzIGNvcnJlY3RlZCwgd2UgY2hvb3NlIHRoZSBuYW1lIHRvIGF2b2lkIGFjY2lkZW50YWwgY29sbGlzaW9ucy4KK3RlbXBsYXRlPHR5cGVuYW1lIE1lc3NhZ2VUeXBlX1dvcmtBcm91bmRDcHBMb29rdXBEZWZlY3Q+CitpbmxpbmUgYm9vbCBXaXJlRm9ybWF0TGl0ZTo6UmVhZEdyb3VwTm9WaXJ0dWFsKAorICAgIGludCBmaWVsZF9udW1iZXIsIGlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCwKKyAgICBNZXNzYWdlVHlwZV9Xb3JrQXJvdW5kQ3BwTG9va3VwRGVmZWN0KiB2YWx1ZSkgeworICBpZiAoIWlucHV0LT5JbmNyZW1lbnRSZWN1cnNpb25EZXB0aCgpKSByZXR1cm4gZmFsc2U7CisgIGlmICghdmFsdWUtPgorICAgICAgTWVzc2FnZVR5cGVfV29ya0Fyb3VuZENwcExvb2t1cERlZmVjdDo6TWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKGlucHV0KSkKKyAgICByZXR1cm4gZmFsc2U7CisgIGlucHV0LT5VbnNhZmVEZWNyZW1lbnRSZWN1cnNpb25EZXB0aCgpOworICAvLyBNYWtlIHN1cmUgdGhlIGxhc3QgdGhpbmcgcmVhZCB3YXMgYW4gZW5kIHRhZyBmb3IgdGhpcyBncm91cC4KKyAgaWYgKCFpbnB1dC0+TGFzdFRhZ1dhcyhNYWtlVGFnKGZpZWxkX251bWJlciwgV0lSRVRZUEVfRU5EX0dST1VQKSkpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9Cit0ZW1wbGF0ZTx0eXBlbmFtZSBNZXNzYWdlVHlwZV9Xb3JrQXJvdW5kQ3BwTG9va3VwRGVmZWN0PgoraW5saW5lIGJvb2wgV2lyZUZvcm1hdExpdGU6OlJlYWRHcm91cE5vVmlydHVhbE5vUmVjdXJzaW9uRGVwdGgoCisgICAgaW50IGZpZWxkX251bWJlciwgaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LAorICAgIE1lc3NhZ2VUeXBlX1dvcmtBcm91bmRDcHBMb29rdXBEZWZlY3QqIHZhbHVlKSB7CisgIHJldHVybiB2YWx1ZS0+TWVzc2FnZVR5cGVfV29ya0Fyb3VuZENwcExvb2t1cERlZmVjdDo6CisgICAgICAgICAgICAgTWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKGlucHV0KSAmJgorICAgICAgICAgaW5wdXQtPkxhc3RUYWdXYXMoTWFrZVRhZyhmaWVsZF9udW1iZXIsIFdJUkVUWVBFX0VORF9HUk9VUCkpOworfQordGVtcGxhdGU8dHlwZW5hbWUgTWVzc2FnZVR5cGVfV29ya0Fyb3VuZENwcExvb2t1cERlZmVjdD4KK2lubGluZSBib29sIFdpcmVGb3JtYXRMaXRlOjpSZWFkTWVzc2FnZU5vVmlydHVhbCgKKyAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQsIE1lc3NhZ2VUeXBlX1dvcmtBcm91bmRDcHBMb29rdXBEZWZlY3QqIHZhbHVlKSB7CisgIHVpbnQzMiBsZW5ndGg7CisgIGlmICghaW5wdXQtPlJlYWRWYXJpbnQzMigmbGVuZ3RoKSkgcmV0dXJuIGZhbHNlOworICBzdGQ6OnBhaXI8aW86OkNvZGVkSW5wdXRTdHJlYW06OkxpbWl0LCBpbnQ+IHAgPQorICAgICAgaW5wdXQtPkluY3JlbWVudFJlY3Vyc2lvbkRlcHRoQW5kUHVzaExpbWl0KGxlbmd0aCk7CisgIGlmIChwLnNlY29uZCA8IDAgfHwgIXZhbHVlLT4KKyAgICAgIE1lc3NhZ2VUeXBlX1dvcmtBcm91bmRDcHBMb29rdXBEZWZlY3Q6Ok1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbShpbnB1dCkpCisgICAgcmV0dXJuIGZhbHNlOworICAvLyBNYWtlIHN1cmUgdGhhdCBwYXJzaW5nIHN0b3BwZWQgd2hlbiB0aGUgbGltaXQgd2FzIGhpdCwgbm90IGF0IGFuIGVuZGdyb3VwCisgIC8vIHRhZy4KKyAgcmV0dXJuIGlucHV0LT5EZWNyZW1lbnRSZWN1cnNpb25EZXB0aEFuZFBvcExpbWl0KHAuZmlyc3QpOworfQordGVtcGxhdGU8dHlwZW5hbWUgTWVzc2FnZVR5cGVfV29ya0Fyb3VuZENwcExvb2t1cERlZmVjdD4KK2lubGluZSBib29sIFdpcmVGb3JtYXRMaXRlOjpSZWFkTWVzc2FnZU5vVmlydHVhbE5vUmVjdXJzaW9uRGVwdGgoCisgICAgaW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0LCBNZXNzYWdlVHlwZV9Xb3JrQXJvdW5kQ3BwTG9va3VwRGVmZWN0KiB2YWx1ZSkgeworICBpbzo6Q29kZWRJbnB1dFN0cmVhbTo6TGltaXQgb2xkX2xpbWl0ID0gaW5wdXQtPlJlYWRMZW5ndGhBbmRQdXNoTGltaXQoKTsKKyAgaWYgKCF2YWx1ZS0+CisgICAgICBNZXNzYWdlVHlwZV9Xb3JrQXJvdW5kQ3BwTG9va3VwRGVmZWN0OjpNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oaW5wdXQpKQorICAgIHJldHVybiBmYWxzZTsKKyAgLy8gTWFrZSBzdXJlIHRoYXQgcGFyc2luZyBzdG9wcGVkIHdoZW4gdGhlIGxpbWl0IHdhcyBoaXQsIG5vdCBhdCBhbiBlbmRncm91cAorICAvLyB0YWcuCisgIHJldHVybiBpbnB1dC0+Q2hlY2tFbnRpcmVNZXNzYWdlQ29uc3VtZWRBbmRQb3BMaW1pdChvbGRfbGltaXQpOworfQorCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKK2lubGluZSB2b2lkIFdpcmVGb3JtYXRMaXRlOjpXcml0ZVRhZyhpbnQgZmllbGRfbnVtYmVyLCBXaXJlVHlwZSB0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSB7CisgIG91dHB1dC0+V3JpdGVUYWcoTWFrZVRhZyhmaWVsZF9udW1iZXIsIHR5cGUpKTsKK30KKworaW5saW5lIHZvaWQgV2lyZUZvcm1hdExpdGU6OldyaXRlSW50MzJOb1RhZyhpbnQzMiB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIHsKKyAgb3V0cHV0LT5Xcml0ZVZhcmludDMyU2lnbkV4dGVuZGVkKHZhbHVlKTsKK30KK2lubGluZSB2b2lkIFdpcmVGb3JtYXRMaXRlOjpXcml0ZUludDY0Tm9UYWcoaW50NjQgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSB7CisgIG91dHB1dC0+V3JpdGVWYXJpbnQ2NChzdGF0aWNfY2FzdDx1aW50NjQ+KHZhbHVlKSk7Cit9CitpbmxpbmUgdm9pZCBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVVSW50MzJOb1RhZyh1aW50MzIgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgeworICBvdXRwdXQtPldyaXRlVmFyaW50MzIodmFsdWUpOworfQoraW5saW5lIHZvaWQgV2lyZUZvcm1hdExpdGU6OldyaXRlVUludDY0Tm9UYWcodWludDY0IHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIHsKKyAgb3V0cHV0LT5Xcml0ZVZhcmludDY0KHZhbHVlKTsKK30KK2lubGluZSB2b2lkIFdpcmVGb3JtYXRMaXRlOjpXcml0ZVNJbnQzMk5vVGFnKGludDMyIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIHsKKyAgb3V0cHV0LT5Xcml0ZVZhcmludDMyKFppZ1phZ0VuY29kZTMyKHZhbHVlKSk7Cit9CitpbmxpbmUgdm9pZCBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTSW50NjROb1RhZyhpbnQ2NCB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSB7CisgIG91dHB1dC0+V3JpdGVWYXJpbnQ2NChaaWdaYWdFbmNvZGU2NCh2YWx1ZSkpOworfQoraW5saW5lIHZvaWQgV2lyZUZvcm1hdExpdGU6OldyaXRlRml4ZWQzMk5vVGFnKHVpbnQzMiB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgeworICBvdXRwdXQtPldyaXRlTGl0dGxlRW5kaWFuMzIodmFsdWUpOworfQoraW5saW5lIHZvaWQgV2lyZUZvcm1hdExpdGU6OldyaXRlRml4ZWQ2NE5vVGFnKHVpbnQ2NCB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgeworICBvdXRwdXQtPldyaXRlTGl0dGxlRW5kaWFuNjQodmFsdWUpOworfQoraW5saW5lIHZvaWQgV2lyZUZvcm1hdExpdGU6OldyaXRlU0ZpeGVkMzJOb1RhZyhpbnQzMiB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIHsKKyAgb3V0cHV0LT5Xcml0ZUxpdHRsZUVuZGlhbjMyKHN0YXRpY19jYXN0PHVpbnQzMj4odmFsdWUpKTsKK30KK2lubGluZSB2b2lkIFdpcmVGb3JtYXRMaXRlOjpXcml0ZVNGaXhlZDY0Tm9UYWcoaW50NjQgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSB7CisgIG91dHB1dC0+V3JpdGVMaXR0bGVFbmRpYW42NChzdGF0aWNfY2FzdDx1aW50NjQ+KHZhbHVlKSk7Cit9CitpbmxpbmUgdm9pZCBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVGbG9hdE5vVGFnKGZsb2F0IHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgeworICBvdXRwdXQtPldyaXRlTGl0dGxlRW5kaWFuMzIoRW5jb2RlRmxvYXQodmFsdWUpKTsKK30KK2lubGluZSB2b2lkIFdpcmVGb3JtYXRMaXRlOjpXcml0ZURvdWJsZU5vVGFnKGRvdWJsZSB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSB7CisgIG91dHB1dC0+V3JpdGVMaXR0bGVFbmRpYW42NChFbmNvZGVEb3VibGUodmFsdWUpKTsKK30KK2lubGluZSB2b2lkIFdpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2xOb1RhZyhib29sIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSB7CisgIG91dHB1dC0+V3JpdGVWYXJpbnQzMih2YWx1ZSA/IDEgOiAwKTsKK30KK2lubGluZSB2b2lkIFdpcmVGb3JtYXRMaXRlOjpXcml0ZUVudW1Ob1RhZyhpbnQgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIHsKKyAgb3V0cHV0LT5Xcml0ZVZhcmludDMyU2lnbkV4dGVuZGVkKHZhbHVlKTsKK30KKworLy8gU2VlIGNvbW1lbnQgb24gUmVhZEdyb3VwTm9WaXJ0dWFsIHRvIHVuZGVyc3RhbmQgdGhlIG5lZWQgZm9yIHRoaXMgdGVtcGxhdGUKKy8vIHBhcmFtZXRlciBuYW1lLgordGVtcGxhdGU8dHlwZW5hbWUgTWVzc2FnZVR5cGVfV29ya0Fyb3VuZENwcExvb2t1cERlZmVjdD4KK2lubGluZSB2b2lkIFdpcmVGb3JtYXRMaXRlOjpXcml0ZUdyb3VwTm9WaXJ0dWFsKAorICAgIGludCBmaWVsZF9udW1iZXIsIGNvbnN0IE1lc3NhZ2VUeXBlX1dvcmtBcm91bmRDcHBMb29rdXBEZWZlY3QmIHZhbHVlLAorICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSB7CisgIFdyaXRlVGFnKGZpZWxkX251bWJlciwgV0lSRVRZUEVfU1RBUlRfR1JPVVAsIG91dHB1dCk7CisgIHZhbHVlLk1lc3NhZ2VUeXBlX1dvcmtBcm91bmRDcHBMb29rdXBEZWZlY3Q6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcyhvdXRwdXQpOworICBXcml0ZVRhZyhmaWVsZF9udW1iZXIsIFdJUkVUWVBFX0VORF9HUk9VUCwgb3V0cHV0KTsKK30KK3RlbXBsYXRlPHR5cGVuYW1lIE1lc3NhZ2VUeXBlX1dvcmtBcm91bmRDcHBMb29rdXBEZWZlY3Q+CitpbmxpbmUgdm9pZCBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTm9WaXJ0dWFsKAorICAgIGludCBmaWVsZF9udW1iZXIsIGNvbnN0IE1lc3NhZ2VUeXBlX1dvcmtBcm91bmRDcHBMb29rdXBEZWZlY3QmIHZhbHVlLAorICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSB7CisgIFdyaXRlVGFnKGZpZWxkX251bWJlciwgV0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCwgb3V0cHV0KTsKKyAgb3V0cHV0LT5Xcml0ZVZhcmludDMyKAorICAgICAgdmFsdWUuTWVzc2FnZVR5cGVfV29ya0Fyb3VuZENwcExvb2t1cERlZmVjdDo6R2V0Q2FjaGVkU2l6ZSgpKTsKKyAgdmFsdWUuTWVzc2FnZVR5cGVfV29ya0Fyb3VuZENwcExvb2t1cERlZmVjdDo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzKG91dHB1dCk7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworaW5saW5lIHVpbnQ4KiBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVUYWdUb0FycmF5KGludCBmaWVsZF9udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV2lyZVR5cGUgdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OCogdGFyZ2V0KSB7CisgIHJldHVybiBpbzo6Q29kZWRPdXRwdXRTdHJlYW06OldyaXRlVGFnVG9BcnJheShNYWtlVGFnKGZpZWxkX251bWJlciwgdHlwZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQpOworfQorCitpbmxpbmUgdWludDgqIFdpcmVGb3JtYXRMaXRlOjpXcml0ZUludDMyTm9UYWdUb0FycmF5KGludDMyIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OCogdGFyZ2V0KSB7CisgIHJldHVybiBpbzo6Q29kZWRPdXRwdXRTdHJlYW06OldyaXRlVmFyaW50MzJTaWduRXh0ZW5kZWRUb0FycmF5KHZhbHVlLCB0YXJnZXQpOworfQoraW5saW5lIHVpbnQ4KiBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVJbnQ2NE5vVGFnVG9BcnJheShpbnQ2NCB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDgqIHRhcmdldCkgeworICByZXR1cm4gaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZVZhcmludDY0VG9BcnJheSgKKyAgICAgIHN0YXRpY19jYXN0PHVpbnQ2ND4odmFsdWUpLCB0YXJnZXQpOworfQoraW5saW5lIHVpbnQ4KiBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVVSW50MzJOb1RhZ1RvQXJyYXkodWludDMyIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDgqIHRhcmdldCkgeworICByZXR1cm4gaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZVZhcmludDMyVG9BcnJheSh2YWx1ZSwgdGFyZ2V0KTsKK30KK2lubGluZSB1aW50OCogV2lyZUZvcm1hdExpdGU6OldyaXRlVUludDY0Tm9UYWdUb0FycmF5KHVpbnQ2NCB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4KiB0YXJnZXQpIHsKKyAgcmV0dXJuIGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVWYXJpbnQ2NFRvQXJyYXkodmFsdWUsIHRhcmdldCk7Cit9CitpbmxpbmUgdWludDgqIFdpcmVGb3JtYXRMaXRlOjpXcml0ZVNJbnQzMk5vVGFnVG9BcnJheShpbnQzMiB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4KiB0YXJnZXQpIHsKKyAgcmV0dXJuIGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVWYXJpbnQzMlRvQXJyYXkoWmlnWmFnRW5jb2RlMzIodmFsdWUpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQpOworfQoraW5saW5lIHVpbnQ4KiBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTSW50NjROb1RhZ1RvQXJyYXkoaW50NjQgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OCogdGFyZ2V0KSB7CisgIHJldHVybiBpbzo6Q29kZWRPdXRwdXRTdHJlYW06OldyaXRlVmFyaW50NjRUb0FycmF5KFppZ1phZ0VuY29kZTY0KHZhbHVlKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0KTsKK30KK2lubGluZSB1aW50OCogV2lyZUZvcm1hdExpdGU6OldyaXRlRml4ZWQzMk5vVGFnVG9BcnJheSh1aW50MzIgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDgqIHRhcmdldCkgeworICByZXR1cm4gaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZUxpdHRsZUVuZGlhbjMyVG9BcnJheSh2YWx1ZSwgdGFyZ2V0KTsKK30KK2lubGluZSB1aW50OCogV2lyZUZvcm1hdExpdGU6OldyaXRlRml4ZWQ2NE5vVGFnVG9BcnJheSh1aW50NjQgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDgqIHRhcmdldCkgeworICByZXR1cm4gaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZUxpdHRsZUVuZGlhbjY0VG9BcnJheSh2YWx1ZSwgdGFyZ2V0KTsKK30KK2lubGluZSB1aW50OCogV2lyZUZvcm1hdExpdGU6OldyaXRlU0ZpeGVkMzJOb1RhZ1RvQXJyYXkoaW50MzIgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4KiB0YXJnZXQpIHsKKyAgcmV0dXJuIGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVMaXR0bGVFbmRpYW4zMlRvQXJyYXkoCisgICAgICBzdGF0aWNfY2FzdDx1aW50MzI+KHZhbHVlKSwgdGFyZ2V0KTsKK30KK2lubGluZSB1aW50OCogV2lyZUZvcm1hdExpdGU6OldyaXRlU0ZpeGVkNjROb1RhZ1RvQXJyYXkoaW50NjQgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4KiB0YXJnZXQpIHsKKyAgcmV0dXJuIGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVMaXR0bGVFbmRpYW42NFRvQXJyYXkoCisgICAgICBzdGF0aWNfY2FzdDx1aW50NjQ+KHZhbHVlKSwgdGFyZ2V0KTsKK30KK2lubGluZSB1aW50OCogV2lyZUZvcm1hdExpdGU6OldyaXRlRmxvYXROb1RhZ1RvQXJyYXkoZmxvYXQgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4KiB0YXJnZXQpIHsKKyAgcmV0dXJuIGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVMaXR0bGVFbmRpYW4zMlRvQXJyYXkoRW5jb2RlRmxvYXQodmFsdWUpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQpOworfQoraW5saW5lIHVpbnQ4KiBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVEb3VibGVOb1RhZ1RvQXJyYXkoZG91YmxlIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDgqIHRhcmdldCkgeworICByZXR1cm4gaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZUxpdHRsZUVuZGlhbjY0VG9BcnJheShFbmNvZGVEb3VibGUodmFsdWUpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQpOworfQoraW5saW5lIHVpbnQ4KiBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCb29sTm9UYWdUb0FycmF5KGJvb2wgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDgqIHRhcmdldCkgeworICByZXR1cm4gaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpXcml0ZVZhcmludDMyVG9BcnJheSh2YWx1ZSA/IDEgOiAwLCB0YXJnZXQpOworfQoraW5saW5lIHVpbnQ4KiBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVFbnVtTm9UYWdUb0FycmF5KGludCB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OCogdGFyZ2V0KSB7CisgIHJldHVybiBpbzo6Q29kZWRPdXRwdXRTdHJlYW06OldyaXRlVmFyaW50MzJTaWduRXh0ZW5kZWRUb0FycmF5KHZhbHVlLCB0YXJnZXQpOworfQorCitpbmxpbmUgdWludDgqIFdpcmVGb3JtYXRMaXRlOjpXcml0ZUludDMyVG9BcnJheShpbnQgZmllbGRfbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzIgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OCogdGFyZ2V0KSB7CisgIHRhcmdldCA9IFdyaXRlVGFnVG9BcnJheShmaWVsZF9udW1iZXIsIFdJUkVUWVBFX1ZBUklOVCwgdGFyZ2V0KTsKKyAgcmV0dXJuIFdyaXRlSW50MzJOb1RhZ1RvQXJyYXkodmFsdWUsIHRhcmdldCk7Cit9CitpbmxpbmUgdWludDgqIFdpcmVGb3JtYXRMaXRlOjpXcml0ZUludDY0VG9BcnJheShpbnQgZmllbGRfbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50NjQgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OCogdGFyZ2V0KSB7CisgIHRhcmdldCA9IFdyaXRlVGFnVG9BcnJheShmaWVsZF9udW1iZXIsIFdJUkVUWVBFX1ZBUklOVCwgdGFyZ2V0KTsKKyAgcmV0dXJuIFdyaXRlSW50NjROb1RhZ1RvQXJyYXkodmFsdWUsIHRhcmdldCk7Cit9CitpbmxpbmUgdWludDgqIFdpcmVGb3JtYXRMaXRlOjpXcml0ZVVJbnQzMlRvQXJyYXkoaW50IGZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzIgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDgqIHRhcmdldCkgeworICB0YXJnZXQgPSBXcml0ZVRhZ1RvQXJyYXkoZmllbGRfbnVtYmVyLCBXSVJFVFlQRV9WQVJJTlQsIHRhcmdldCk7CisgIHJldHVybiBXcml0ZVVJbnQzMk5vVGFnVG9BcnJheSh2YWx1ZSwgdGFyZ2V0KTsKK30KK2lubGluZSB1aW50OCogV2lyZUZvcm1hdExpdGU6OldyaXRlVUludDY0VG9BcnJheShpbnQgZmllbGRfbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ2NCB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OCogdGFyZ2V0KSB7CisgIHRhcmdldCA9IFdyaXRlVGFnVG9BcnJheShmaWVsZF9udW1iZXIsIFdJUkVUWVBFX1ZBUklOVCwgdGFyZ2V0KTsKKyAgcmV0dXJuIFdyaXRlVUludDY0Tm9UYWdUb0FycmF5KHZhbHVlLCB0YXJnZXQpOworfQoraW5saW5lIHVpbnQ4KiBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTSW50MzJUb0FycmF5KGludCBmaWVsZF9udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzIgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDgqIHRhcmdldCkgeworICB0YXJnZXQgPSBXcml0ZVRhZ1RvQXJyYXkoZmllbGRfbnVtYmVyLCBXSVJFVFlQRV9WQVJJTlQsIHRhcmdldCk7CisgIHJldHVybiBXcml0ZVNJbnQzMk5vVGFnVG9BcnJheSh2YWx1ZSwgdGFyZ2V0KTsKK30KK2lubGluZSB1aW50OCogV2lyZUZvcm1hdExpdGU6OldyaXRlU0ludDY0VG9BcnJheShpbnQgZmllbGRfbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDY0IHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4KiB0YXJnZXQpIHsKKyAgdGFyZ2V0ID0gV3JpdGVUYWdUb0FycmF5KGZpZWxkX251bWJlciwgV0lSRVRZUEVfVkFSSU5ULCB0YXJnZXQpOworICByZXR1cm4gV3JpdGVTSW50NjROb1RhZ1RvQXJyYXkodmFsdWUsIHRhcmdldCk7Cit9CitpbmxpbmUgdWludDgqIFdpcmVGb3JtYXRMaXRlOjpXcml0ZUZpeGVkMzJUb0FycmF5KGludCBmaWVsZF9udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMiB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDgqIHRhcmdldCkgeworICB0YXJnZXQgPSBXcml0ZVRhZ1RvQXJyYXkoZmllbGRfbnVtYmVyLCBXSVJFVFlQRV9GSVhFRDMyLCB0YXJnZXQpOworICByZXR1cm4gV3JpdGVGaXhlZDMyTm9UYWdUb0FycmF5KHZhbHVlLCB0YXJnZXQpOworfQoraW5saW5lIHVpbnQ4KiBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVGaXhlZDY0VG9BcnJheShpbnQgZmllbGRfbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50NjQgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4KiB0YXJnZXQpIHsKKyAgdGFyZ2V0ID0gV3JpdGVUYWdUb0FycmF5KGZpZWxkX251bWJlciwgV0lSRVRZUEVfRklYRUQ2NCwgdGFyZ2V0KTsKKyAgcmV0dXJuIFdyaXRlRml4ZWQ2NE5vVGFnVG9BcnJheSh2YWx1ZSwgdGFyZ2V0KTsKK30KK2lubGluZSB1aW50OCogV2lyZUZvcm1hdExpdGU6OldyaXRlU0ZpeGVkMzJUb0FycmF5KGludCBmaWVsZF9udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMiB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4KiB0YXJnZXQpIHsKKyAgdGFyZ2V0ID0gV3JpdGVUYWdUb0FycmF5KGZpZWxkX251bWJlciwgV0lSRVRZUEVfRklYRUQzMiwgdGFyZ2V0KTsKKyAgcmV0dXJuIFdyaXRlU0ZpeGVkMzJOb1RhZ1RvQXJyYXkodmFsdWUsIHRhcmdldCk7Cit9CitpbmxpbmUgdWludDgqIFdpcmVGb3JtYXRMaXRlOjpXcml0ZVNGaXhlZDY0VG9BcnJheShpbnQgZmllbGRfbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50NjQgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OCogdGFyZ2V0KSB7CisgIHRhcmdldCA9IFdyaXRlVGFnVG9BcnJheShmaWVsZF9udW1iZXIsIFdJUkVUWVBFX0ZJWEVENjQsIHRhcmdldCk7CisgIHJldHVybiBXcml0ZVNGaXhlZDY0Tm9UYWdUb0FycmF5KHZhbHVlLCB0YXJnZXQpOworfQoraW5saW5lIHVpbnQ4KiBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVGbG9hdFRvQXJyYXkoaW50IGZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZsb2F0IHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDgqIHRhcmdldCkgeworICB0YXJnZXQgPSBXcml0ZVRhZ1RvQXJyYXkoZmllbGRfbnVtYmVyLCBXSVJFVFlQRV9GSVhFRDMyLCB0YXJnZXQpOworICByZXR1cm4gV3JpdGVGbG9hdE5vVGFnVG9BcnJheSh2YWx1ZSwgdGFyZ2V0KTsKK30KK2lubGluZSB1aW50OCogV2lyZUZvcm1hdExpdGU6OldyaXRlRG91YmxlVG9BcnJheShpbnQgZmllbGRfbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvdWJsZSB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OCogdGFyZ2V0KSB7CisgIHRhcmdldCA9IFdyaXRlVGFnVG9BcnJheShmaWVsZF9udW1iZXIsIFdJUkVUWVBFX0ZJWEVENjQsIHRhcmdldCk7CisgIHJldHVybiBXcml0ZURvdWJsZU5vVGFnVG9BcnJheSh2YWx1ZSwgdGFyZ2V0KTsKK30KK2lubGluZSB1aW50OCogV2lyZUZvcm1hdExpdGU6OldyaXRlQm9vbFRvQXJyYXkoaW50IGZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDgqIHRhcmdldCkgeworICB0YXJnZXQgPSBXcml0ZVRhZ1RvQXJyYXkoZmllbGRfbnVtYmVyLCBXSVJFVFlQRV9WQVJJTlQsIHRhcmdldCk7CisgIHJldHVybiBXcml0ZUJvb2xOb1RhZ1RvQXJyYXkodmFsdWUsIHRhcmdldCk7Cit9CitpbmxpbmUgdWludDgqIFdpcmVGb3JtYXRMaXRlOjpXcml0ZUVudW1Ub0FycmF5KGludCBmaWVsZF9udW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDgqIHRhcmdldCkgeworICB0YXJnZXQgPSBXcml0ZVRhZ1RvQXJyYXkoZmllbGRfbnVtYmVyLCBXSVJFVFlQRV9WQVJJTlQsIHRhcmdldCk7CisgIHJldHVybiBXcml0ZUVudW1Ob1RhZ1RvQXJyYXkodmFsdWUsIHRhcmdldCk7Cit9CisKK2lubGluZSB1aW50OCogV2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nVG9BcnJheShpbnQgZmllbGRfbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZyYgdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDgqIHRhcmdldCkgeworICAvLyBTdHJpbmcgaXMgZm9yIFVURi04IHRleHQgb25seQorICAvLyBXQVJOSU5HOiAgSW4gd2lyZV9mb3JtYXQuY2MsIGJvdGggc3RyaW5ncyBhbmQgYnl0ZXMgYXJlIGhhbmRsZWQgYnkKKyAgLy8gICBXcml0ZVN0cmluZygpIHRvIGF2b2lkIGNvZGUgZHVwbGljYXRpb24uICBJZiB0aGUgaW1wbGVtZW50YXRpb25zIGJlY29tZQorICAvLyAgIGRpZmZlcmVudCwgeW91IHdpbGwgbmVlZCB0byB1cGRhdGUgdGhhdCB1c2FnZS4KKyAgdGFyZ2V0ID0gV3JpdGVUYWdUb0FycmF5KGZpZWxkX251bWJlciwgV0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCwgdGFyZ2V0KTsKKyAgcmV0dXJuIGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVTdHJpbmdXaXRoU2l6ZVRvQXJyYXkodmFsdWUsIHRhcmdldCk7Cit9CitpbmxpbmUgdWludDgqIFdpcmVGb3JtYXRMaXRlOjpXcml0ZUJ5dGVzVG9BcnJheShpbnQgZmllbGRfbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaW5nJiB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4KiB0YXJnZXQpIHsKKyAgdGFyZ2V0ID0gV3JpdGVUYWdUb0FycmF5KGZpZWxkX251bWJlciwgV0lSRVRZUEVfTEVOR1RIX0RFTElNSVRFRCwgdGFyZ2V0KTsKKyAgcmV0dXJuIGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVTdHJpbmdXaXRoU2l6ZVRvQXJyYXkodmFsdWUsIHRhcmdldCk7Cit9CisKKworaW5saW5lIHVpbnQ4KiBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVHcm91cFRvQXJyYXkoaW50IGZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1lc3NhZ2VMaXRlJiB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4KiB0YXJnZXQpIHsKKyAgdGFyZ2V0ID0gV3JpdGVUYWdUb0FycmF5KGZpZWxkX251bWJlciwgV0lSRVRZUEVfU1RBUlRfR1JPVVAsIHRhcmdldCk7CisgIHRhcmdldCA9IHZhbHVlLlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkodGFyZ2V0KTsKKyAgcmV0dXJuIFdyaXRlVGFnVG9BcnJheShmaWVsZF9udW1iZXIsIFdJUkVUWVBFX0VORF9HUk9VUCwgdGFyZ2V0KTsKK30KK2lubGluZSB1aW50OCogV2lyZUZvcm1hdExpdGU6OldyaXRlTWVzc2FnZVRvQXJyYXkoaW50IGZpZWxkX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWVzc2FnZUxpdGUmIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OCogdGFyZ2V0KSB7CisgIHRhcmdldCA9IFdyaXRlVGFnVG9BcnJheShmaWVsZF9udW1iZXIsIFdJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQsIHRhcmdldCk7CisgIHRhcmdldCA9IGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVWYXJpbnQzMlRvQXJyYXkoCisgICAgdmFsdWUuR2V0Q2FjaGVkU2l6ZSgpLCB0YXJnZXQpOworICByZXR1cm4gdmFsdWUuU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSh0YXJnZXQpOworfQorCisvLyBTZWUgY29tbWVudCBvbiBSZWFkR3JvdXBOb1ZpcnR1YWwgdG8gdW5kZXJzdGFuZCB0aGUgbmVlZCBmb3IgdGhpcyB0ZW1wbGF0ZQorLy8gcGFyYW1ldGVyIG5hbWUuCit0ZW1wbGF0ZTx0eXBlbmFtZSBNZXNzYWdlVHlwZV9Xb3JrQXJvdW5kQ3BwTG9va3VwRGVmZWN0PgoraW5saW5lIHVpbnQ4KiBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVHcm91cE5vVmlydHVhbFRvQXJyYXkoCisgICAgaW50IGZpZWxkX251bWJlciwgY29uc3QgTWVzc2FnZVR5cGVfV29ya0Fyb3VuZENwcExvb2t1cERlZmVjdCYgdmFsdWUsCisgICAgdWludDgqIHRhcmdldCkgeworICB0YXJnZXQgPSBXcml0ZVRhZ1RvQXJyYXkoZmllbGRfbnVtYmVyLCBXSVJFVFlQRV9TVEFSVF9HUk9VUCwgdGFyZ2V0KTsKKyAgdGFyZ2V0ID0gdmFsdWUuTWVzc2FnZVR5cGVfV29ya0Fyb3VuZENwcExvb2t1cERlZmVjdAorICAgICAgOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KHRhcmdldCk7CisgIHJldHVybiBXcml0ZVRhZ1RvQXJyYXkoZmllbGRfbnVtYmVyLCBXSVJFVFlQRV9FTkRfR1JPVVAsIHRhcmdldCk7Cit9Cit0ZW1wbGF0ZTx0eXBlbmFtZSBNZXNzYWdlVHlwZV9Xb3JrQXJvdW5kQ3BwTG9va3VwRGVmZWN0PgoraW5saW5lIHVpbnQ4KiBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVNZXNzYWdlTm9WaXJ0dWFsVG9BcnJheSgKKyAgICBpbnQgZmllbGRfbnVtYmVyLCBjb25zdCBNZXNzYWdlVHlwZV9Xb3JrQXJvdW5kQ3BwTG9va3VwRGVmZWN0JiB2YWx1ZSwKKyAgICB1aW50OCogdGFyZ2V0KSB7CisgIHRhcmdldCA9IFdyaXRlVGFnVG9BcnJheShmaWVsZF9udW1iZXIsIFdJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQsIHRhcmdldCk7CisgIHRhcmdldCA9IGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6V3JpdGVWYXJpbnQzMlRvQXJyYXkoCisgICAgdmFsdWUuTWVzc2FnZVR5cGVfV29ya0Fyb3VuZENwcExvb2t1cERlZmVjdDo6R2V0Q2FjaGVkU2l6ZSgpLCB0YXJnZXQpOworICByZXR1cm4gdmFsdWUuTWVzc2FnZVR5cGVfV29ya0Fyb3VuZENwcExvb2t1cERlZmVjdAorICAgICAgOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KHRhcmdldCk7Cit9CisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworaW5saW5lIGludCBXaXJlRm9ybWF0TGl0ZTo6SW50MzJTaXplKGludDMyIHZhbHVlKSB7CisgIHJldHVybiBpbzo6Q29kZWRPdXRwdXRTdHJlYW06OlZhcmludFNpemUzMlNpZ25FeHRlbmRlZCh2YWx1ZSk7Cit9CitpbmxpbmUgaW50IFdpcmVGb3JtYXRMaXRlOjpJbnQ2NFNpemUoaW50NjQgdmFsdWUpIHsKKyAgcmV0dXJuIGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6VmFyaW50U2l6ZTY0KHN0YXRpY19jYXN0PHVpbnQ2ND4odmFsdWUpKTsKK30KK2lubGluZSBpbnQgV2lyZUZvcm1hdExpdGU6OlVJbnQzMlNpemUodWludDMyIHZhbHVlKSB7CisgIHJldHVybiBpbzo6Q29kZWRPdXRwdXRTdHJlYW06OlZhcmludFNpemUzMih2YWx1ZSk7Cit9CitpbmxpbmUgaW50IFdpcmVGb3JtYXRMaXRlOjpVSW50NjRTaXplKHVpbnQ2NCB2YWx1ZSkgeworICByZXR1cm4gaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpWYXJpbnRTaXplNjQodmFsdWUpOworfQoraW5saW5lIGludCBXaXJlRm9ybWF0TGl0ZTo6U0ludDMyU2l6ZShpbnQzMiB2YWx1ZSkgeworICByZXR1cm4gaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpWYXJpbnRTaXplMzIoWmlnWmFnRW5jb2RlMzIodmFsdWUpKTsKK30KK2lubGluZSBpbnQgV2lyZUZvcm1hdExpdGU6OlNJbnQ2NFNpemUoaW50NjQgdmFsdWUpIHsKKyAgcmV0dXJuIGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6VmFyaW50U2l6ZTY0KFppZ1phZ0VuY29kZTY0KHZhbHVlKSk7Cit9CitpbmxpbmUgaW50IFdpcmVGb3JtYXRMaXRlOjpFbnVtU2l6ZShpbnQgdmFsdWUpIHsKKyAgcmV0dXJuIGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6VmFyaW50U2l6ZTMyU2lnbkV4dGVuZGVkKHZhbHVlKTsKK30KKworaW5saW5lIGludCBXaXJlRm9ybWF0TGl0ZTo6U3RyaW5nU2l6ZShjb25zdCBzdHJpbmcmIHZhbHVlKSB7CisgIHJldHVybiBzdGF0aWNfY2FzdDxpbnQ+KAorICAgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtOjpWYXJpbnRTaXplMzIoc3RhdGljX2Nhc3Q8dWludDMyPih2YWx1ZS5zaXplKCkpKSArCisgICAgICB2YWx1ZS5zaXplKCkpOworfQoraW5saW5lIGludCBXaXJlRm9ybWF0TGl0ZTo6Qnl0ZXNTaXplKGNvbnN0IHN0cmluZyYgdmFsdWUpIHsKKyAgcmV0dXJuIHN0YXRpY19jYXN0PGludD4oCisgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW06OlZhcmludFNpemUzMihzdGF0aWNfY2FzdDx1aW50MzI+KHZhbHVlLnNpemUoKSkpICsKKyAgICAgIHZhbHVlLnNpemUoKSk7Cit9CisKKworaW5saW5lIGludCBXaXJlRm9ybWF0TGl0ZTo6R3JvdXBTaXplKGNvbnN0IE1lc3NhZ2VMaXRlJiB2YWx1ZSkgeworICByZXR1cm4gdmFsdWUuQnl0ZVNpemUoKTsKK30KK2lubGluZSBpbnQgV2lyZUZvcm1hdExpdGU6Ok1lc3NhZ2VTaXplKGNvbnN0IE1lc3NhZ2VMaXRlJiB2YWx1ZSkgeworICByZXR1cm4gTGVuZ3RoRGVsaW1pdGVkU2l6ZSh2YWx1ZS5CeXRlU2l6ZSgpKTsKK30KKworLy8gU2VlIGNvbW1lbnQgb24gUmVhZEdyb3VwTm9WaXJ0dWFsIHRvIHVuZGVyc3RhbmQgdGhlIG5lZWQgZm9yIHRoaXMgdGVtcGxhdGUKKy8vIHBhcmFtZXRlciBuYW1lLgordGVtcGxhdGU8dHlwZW5hbWUgTWVzc2FnZVR5cGVfV29ya0Fyb3VuZENwcExvb2t1cERlZmVjdD4KK2lubGluZSBpbnQgV2lyZUZvcm1hdExpdGU6Okdyb3VwU2l6ZU5vVmlydHVhbCgKKyAgICBjb25zdCBNZXNzYWdlVHlwZV9Xb3JrQXJvdW5kQ3BwTG9va3VwRGVmZWN0JiB2YWx1ZSkgeworICByZXR1cm4gdmFsdWUuTWVzc2FnZVR5cGVfV29ya0Fyb3VuZENwcExvb2t1cERlZmVjdDo6Qnl0ZVNpemUoKTsKK30KK3RlbXBsYXRlPHR5cGVuYW1lIE1lc3NhZ2VUeXBlX1dvcmtBcm91bmRDcHBMb29rdXBEZWZlY3Q+CitpbmxpbmUgaW50IFdpcmVGb3JtYXRMaXRlOjpNZXNzYWdlU2l6ZU5vVmlydHVhbCgKKyAgICBjb25zdCBNZXNzYWdlVHlwZV9Xb3JrQXJvdW5kQ3BwTG9va3VwRGVmZWN0JiB2YWx1ZSkgeworICByZXR1cm4gTGVuZ3RoRGVsaW1pdGVkU2l6ZSgKKyAgICAgIHZhbHVlLk1lc3NhZ2VUeXBlX1dvcmtBcm91bmRDcHBMb29rdXBEZWZlY3Q6OkJ5dGVTaXplKCkpOworfQorCitpbmxpbmUgaW50IFdpcmVGb3JtYXRMaXRlOjpMZW5ndGhEZWxpbWl0ZWRTaXplKGludCBsZW5ndGgpIHsKKyAgcmV0dXJuIGlvOjpDb2RlZE91dHB1dFN0cmVhbTo6VmFyaW50U2l6ZTMyKGxlbmd0aCkgKyBsZW5ndGg7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCisKK30gIC8vIG5hbWVzcGFjZSBnb29nbGUKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX1dJUkVfRk9STUFUX0xJVEVfSU5MX0hfXwpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdF91bml0dGVzdC5jYyBiL3NyYy9nb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfdW5pdHRlc3QuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTVjMzc1NQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfdW5pdHRlc3QuY2MKQEAgLTAsMCArMSwxMjg4IEBACisvLyBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKKy8vIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KKy8vCisvLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKy8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKKy8vIG1ldDoKKy8vCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorLy8gbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorLy8gICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQorLy8gY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgorLy8gaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQorLy8gZGlzdHJpYnV0aW9uLgorLy8gICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cworLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KKy8vIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisvLworLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworLy8gIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKy8vIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorLy8gQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKy8vIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorLy8gU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisvLyBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKy8vIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKy8vIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorLy8gT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKworLy8gQXV0aG9yOiBrZW50b25AZ29vZ2xlLmNvbSAoS2VudG9uIFZhcmRhKQorLy8gIEJhc2VkIG9uIG9yaWdpbmFsIFByb3RvY29sIEJ1ZmZlcnMgZGVzaWduIGJ5CisvLyAgU2FuamF5IEdoZW1hd2F0LCBKZWZmIERlYW4sIGFuZCBvdGhlcnMuCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZV9pbmwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby96ZXJvX2NvcHlfc3RyZWFtX2ltcGwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X3Byb3RvM19hcmVuYS5wYi5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9tc2V0LnBiLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X21zZXRfd2lyZV9mb3JtYXQucGIuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdF91dGlsLmg+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvbG9nZ2luZy5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdGVzdGluZy9nb29nbGV0ZXN0Lmg+CisjaW5jbHVkZSA8Z3Rlc3QvZ3Rlc3QuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvc3RsX3V0aWwuaD4KKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworbmFtZXNwYWNlIGludGVybmFsIHsKK25hbWVzcGFjZSB7CisKK1RFU1QoV2lyZUZvcm1hdFRlc3QsIEVudW1zSW5TeW5jKSB7CisgIC8vIFZlcmlmeSB0aGF0IFdpcmVGb3JtYXRMaXRlOjpGaWVsZFR5cGUgYW5kIFdpcmVGb3JtYXRMaXRlOjpDcHBUeXBlIG1hdGNoCisgIC8vIEZpZWxkRGVzY3JpcHRvcjo6VHlwZSBhbmQgRmllbGREZXNjcmlwdG9yOjpDcHBUeXBlLgorCisgIEVYUEVDVF9FUShpbXBsaWNpdF9jYXN0PGludD4oRmllbGREZXNjcmlwdG9yOjpNQVhfVFlQRSksCisgICAgICAgICAgICBpbXBsaWNpdF9jYXN0PGludD4oV2lyZUZvcm1hdExpdGU6Ok1BWF9GSUVMRF9UWVBFKSk7CisgIEVYUEVDVF9FUShpbXBsaWNpdF9jYXN0PGludD4oRmllbGREZXNjcmlwdG9yOjpNQVhfQ1BQVFlQRSksCisgICAgICAgICAgICBpbXBsaWNpdF9jYXN0PGludD4oV2lyZUZvcm1hdExpdGU6Ok1BWF9DUFBUWVBFKSk7CisKKyAgZm9yIChpbnQgaSA9IDE7IGkgPD0gV2lyZUZvcm1hdExpdGU6Ok1BWF9GSUVMRF9UWVBFOyBpKyspIHsKKyAgICBFWFBFQ1RfRVEoCisgICAgICBpbXBsaWNpdF9jYXN0PGludD4oRmllbGREZXNjcmlwdG9yOjpUeXBlVG9DcHBUeXBlKAorICAgICAgICBzdGF0aWNfY2FzdDxGaWVsZERlc2NyaXB0b3I6OlR5cGU+KGkpKSksCisgICAgICBpbXBsaWNpdF9jYXN0PGludD4oV2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZVRvQ3BwVHlwZSgKKyAgICAgICAgc3RhdGljX2Nhc3Q8V2lyZUZvcm1hdExpdGU6OkZpZWxkVHlwZT4oaSkpKSk7CisgIH0KK30KKworVEVTVChXaXJlRm9ybWF0VGVzdCwgTWF4RmllbGROdW1iZXIpIHsKKyAgLy8gTWFrZSBzdXJlIHRoZSBtYXggZmllbGQgbnVtYmVyIGNvbnN0YW50IGlzIGFjY3VyYXRlLgorICBFWFBFQ1RfRVEoKDEgPDwgKDMyIC0gV2lyZUZvcm1hdExpdGU6OmtUYWdUeXBlQml0cykpIC0gMSwKKyAgICAgICAgICAgIEZpZWxkRGVzY3JpcHRvcjo6a01heE51bWJlcik7Cit9CisKK1RFU1QoV2lyZUZvcm1hdFRlc3QsIFBhcnNlKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgc291cmNlLCBkZXN0OworICBzdHJpbmcgZGF0YTsKKworICAvLyBTZXJpYWxpemUgdXNpbmcgdGhlIGdlbmVyYXRlZCBjb2RlLgorICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZzb3VyY2UpOworICBzb3VyY2UuU2VyaWFsaXplVG9TdHJpbmcoJmRhdGEpOworCisgIC8vIFBhcnNlIHVzaW5nIFdpcmVGb3JtYXQuCisgIGlvOjpBcnJheUlucHV0U3RyZWFtIHJhd19pbnB1dChkYXRhLmRhdGEoKSwgZGF0YS5zaXplKCkpOworICBpbzo6Q29kZWRJbnB1dFN0cmVhbSBpbnB1dCgmcmF3X2lucHV0KTsKKyAgV2lyZUZvcm1hdDo6UGFyc2VBbmRNZXJnZVBhcnRpYWwoJmlucHV0LCAmZGVzdCk7CisKKyAgLy8gQ2hlY2suCisgIFRlc3RVdGlsOjpFeHBlY3RBbGxGaWVsZHNTZXQoZGVzdCk7Cit9CisKK1RFU1QoV2lyZUZvcm1hdFRlc3QsIFBhcnNlRXh0ZW5zaW9ucykgeworICB1bml0dGVzdDo6VGVzdEFsbEV4dGVuc2lvbnMgc291cmNlLCBkZXN0OworICBzdHJpbmcgZGF0YTsKKworICAvLyBTZXJpYWxpemUgdXNpbmcgdGhlIGdlbmVyYXRlZCBjb2RlLgorICBUZXN0VXRpbDo6U2V0QWxsRXh0ZW5zaW9ucygmc291cmNlKTsKKyAgc291cmNlLlNlcmlhbGl6ZVRvU3RyaW5nKCZkYXRhKTsKKworICAvLyBQYXJzZSB1c2luZyBXaXJlRm9ybWF0LgorICBpbzo6QXJyYXlJbnB1dFN0cmVhbSByYXdfaW5wdXQoZGF0YS5kYXRhKCksIGRhdGEuc2l6ZSgpKTsKKyAgaW86OkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQoJnJhd19pbnB1dCk7CisgIFdpcmVGb3JtYXQ6OlBhcnNlQW5kTWVyZ2VQYXJ0aWFsKCZpbnB1dCwgJmRlc3QpOworCisgIC8vIENoZWNrLgorICBUZXN0VXRpbDo6RXhwZWN0QWxsRXh0ZW5zaW9uc1NldChkZXN0KTsKK30KKworVEVTVChXaXJlRm9ybWF0VGVzdCwgUGFyc2VQYWNrZWQpIHsKKyAgdW5pdHRlc3Q6OlRlc3RQYWNrZWRUeXBlcyBzb3VyY2UsIGRlc3Q7CisgIHN0cmluZyBkYXRhOworCisgIC8vIFNlcmlhbGl6ZSB1c2luZyB0aGUgZ2VuZXJhdGVkIGNvZGUuCisgIFRlc3RVdGlsOjpTZXRQYWNrZWRGaWVsZHMoJnNvdXJjZSk7CisgIHNvdXJjZS5TZXJpYWxpemVUb1N0cmluZygmZGF0YSk7CisKKyAgLy8gUGFyc2UgdXNpbmcgV2lyZUZvcm1hdC4KKyAgaW86OkFycmF5SW5wdXRTdHJlYW0gcmF3X2lucHV0KGRhdGEuZGF0YSgpLCBkYXRhLnNpemUoKSk7CisgIGlvOjpDb2RlZElucHV0U3RyZWFtIGlucHV0KCZyYXdfaW5wdXQpOworICBXaXJlRm9ybWF0OjpQYXJzZUFuZE1lcmdlUGFydGlhbCgmaW5wdXQsICZkZXN0KTsKKworICAvLyBDaGVjay4KKyAgVGVzdFV0aWw6OkV4cGVjdFBhY2tlZEZpZWxkc1NldChkZXN0KTsKK30KKworVEVTVChXaXJlRm9ybWF0VGVzdCwgUGFyc2VQYWNrZWRGcm9tVW5wYWNrZWQpIHsKKyAgLy8gU2VyaWFsaXplIHVzaW5nIHRoZSBnZW5lcmF0ZWQgY29kZS4KKyAgdW5pdHRlc3Q6OlRlc3RVbnBhY2tlZFR5cGVzIHNvdXJjZTsKKyAgVGVzdFV0aWw6OlNldFVucGFja2VkRmllbGRzKCZzb3VyY2UpOworICBzdHJpbmcgZGF0YSA9IHNvdXJjZS5TZXJpYWxpemVBc1N0cmluZygpOworCisgIC8vIFBhcnNlIHVzaW5nIFdpcmVGb3JtYXQuCisgIHVuaXR0ZXN0OjpUZXN0UGFja2VkVHlwZXMgZGVzdDsKKyAgaW86OkFycmF5SW5wdXRTdHJlYW0gcmF3X2lucHV0KGRhdGEuZGF0YSgpLCBkYXRhLnNpemUoKSk7CisgIGlvOjpDb2RlZElucHV0U3RyZWFtIGlucHV0KCZyYXdfaW5wdXQpOworICBXaXJlRm9ybWF0OjpQYXJzZUFuZE1lcmdlUGFydGlhbCgmaW5wdXQsICZkZXN0KTsKKworICAvLyBDaGVjay4KKyAgVGVzdFV0aWw6OkV4cGVjdFBhY2tlZEZpZWxkc1NldChkZXN0KTsKK30KKworVEVTVChXaXJlRm9ybWF0VGVzdCwgUGFyc2VVbnBhY2tlZEZyb21QYWNrZWQpIHsKKyAgLy8gU2VyaWFsaXplIHVzaW5nIHRoZSBnZW5lcmF0ZWQgY29kZS4KKyAgdW5pdHRlc3Q6OlRlc3RQYWNrZWRUeXBlcyBzb3VyY2U7CisgIFRlc3RVdGlsOjpTZXRQYWNrZWRGaWVsZHMoJnNvdXJjZSk7CisgIHN0cmluZyBkYXRhID0gc291cmNlLlNlcmlhbGl6ZUFzU3RyaW5nKCk7CisKKyAgLy8gUGFyc2UgdXNpbmcgV2lyZUZvcm1hdC4KKyAgdW5pdHRlc3Q6OlRlc3RVbnBhY2tlZFR5cGVzIGRlc3Q7CisgIGlvOjpBcnJheUlucHV0U3RyZWFtIHJhd19pbnB1dChkYXRhLmRhdGEoKSwgZGF0YS5zaXplKCkpOworICBpbzo6Q29kZWRJbnB1dFN0cmVhbSBpbnB1dCgmcmF3X2lucHV0KTsKKyAgV2lyZUZvcm1hdDo6UGFyc2VBbmRNZXJnZVBhcnRpYWwoJmlucHV0LCAmZGVzdCk7CisKKyAgLy8gQ2hlY2suCisgIFRlc3RVdGlsOjpFeHBlY3RVbnBhY2tlZEZpZWxkc1NldChkZXN0KTsKK30KKworVEVTVChXaXJlRm9ybWF0VGVzdCwgUGFyc2VQYWNrZWRFeHRlbnNpb25zKSB7CisgIHVuaXR0ZXN0OjpUZXN0UGFja2VkRXh0ZW5zaW9ucyBzb3VyY2UsIGRlc3Q7CisgIHN0cmluZyBkYXRhOworCisgIC8vIFNlcmlhbGl6ZSB1c2luZyB0aGUgZ2VuZXJhdGVkIGNvZGUuCisgIFRlc3RVdGlsOjpTZXRQYWNrZWRFeHRlbnNpb25zKCZzb3VyY2UpOworICBzb3VyY2UuU2VyaWFsaXplVG9TdHJpbmcoJmRhdGEpOworCisgIC8vIFBhcnNlIHVzaW5nIFdpcmVGb3JtYXQuCisgIGlvOjpBcnJheUlucHV0U3RyZWFtIHJhd19pbnB1dChkYXRhLmRhdGEoKSwgZGF0YS5zaXplKCkpOworICBpbzo6Q29kZWRJbnB1dFN0cmVhbSBpbnB1dCgmcmF3X2lucHV0KTsKKyAgV2lyZUZvcm1hdDo6UGFyc2VBbmRNZXJnZVBhcnRpYWwoJmlucHV0LCAmZGVzdCk7CisKKyAgLy8gQ2hlY2suCisgIFRlc3RVdGlsOjpFeHBlY3RQYWNrZWRFeHRlbnNpb25zU2V0KGRlc3QpOworfQorCitURVNUKFdpcmVGb3JtYXRUZXN0LCBQYXJzZU9uZW9mKSB7CisgIHVuaXR0ZXN0OjpUZXN0T25lb2YyIHNvdXJjZSwgZGVzdDsKKyAgc3RyaW5nIGRhdGE7CisKKyAgLy8gU2VyaWFsaXplIHVzaW5nIHRoZSBnZW5lcmF0ZWQgY29kZS4KKyAgVGVzdFV0aWw6OlNldE9uZW9mMSgmc291cmNlKTsKKyAgc291cmNlLlNlcmlhbGl6ZVRvU3RyaW5nKCZkYXRhKTsKKworICAvLyBQYXJzZSB1c2luZyBXaXJlRm9ybWF0LgorICBpbzo6QXJyYXlJbnB1dFN0cmVhbSByYXdfaW5wdXQoZGF0YS5kYXRhKCksIGRhdGEuc2l6ZSgpKTsKKyAgaW86OkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQoJnJhd19pbnB1dCk7CisgIFdpcmVGb3JtYXQ6OlBhcnNlQW5kTWVyZ2VQYXJ0aWFsKCZpbnB1dCwgJmRlc3QpOworCisgIC8vIENoZWNrLgorICBUZXN0VXRpbDo6RXhwZWN0T25lb2ZTZXQxKGRlc3QpOworfQorCitURVNUKFdpcmVGb3JtYXRUZXN0LCBPbmVvZk9ubHlTZXRMYXN0KSB7CisgIHVuaXR0ZXN0OjpUZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlIHNvdXJjZTsKKyAgdW5pdHRlc3Q6OlRlc3RPbmVvZiBvbmVvZl9kZXN0OworICBzdHJpbmcgZGF0YTsKKworICAvLyBTZXQgdHdvIGZpZWxkcworICBzb3VyY2Uuc2V0X2Zvb19pbnQoMTAwKTsKKyAgc291cmNlLnNldF9mb29fc3RyaW5nKCIxMDEiKTsKKworICAvLyBTZXJpYWxpemUgYW5kIHBhcnNlIHRvIG9uZW9mIG1lc3NhZ2UuCisgIHNvdXJjZS5TZXJpYWxpemVUb1N0cmluZygmZGF0YSk7CisgIGlvOjpBcnJheUlucHV0U3RyZWFtIHJhd19pbnB1dChkYXRhLmRhdGEoKSwgZGF0YS5zaXplKCkpOworICBpbzo6Q29kZWRJbnB1dFN0cmVhbSBpbnB1dCgmcmF3X2lucHV0KTsKKyAgV2lyZUZvcm1hdDo6UGFyc2VBbmRNZXJnZVBhcnRpYWwoJmlucHV0LCAmb25lb2ZfZGVzdCk7CisKKyAgLy8gT25seSB0aGUgbGFzdCBmaWVsZCBpcyBzZXQuCisgIEVYUEVDVF9GQUxTRShvbmVvZl9kZXN0Lmhhc19mb29faW50KCkpOworICBFWFBFQ1RfVFJVRShvbmVvZl9kZXN0Lmhhc19mb29fc3RyaW5nKCkpOworfQorCitURVNUKFdpcmVGb3JtYXRUZXN0LCBCeXRlU2l6ZSkgeworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisgIFRlc3RVdGlsOjpTZXRBbGxGaWVsZHMoJm1lc3NhZ2UpOworCisgIEVYUEVDVF9FUShtZXNzYWdlLkJ5dGVTaXplKCksIFdpcmVGb3JtYXQ6OkJ5dGVTaXplKG1lc3NhZ2UpKTsKKyAgbWVzc2FnZS5DbGVhcigpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5CeXRlU2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIFdpcmVGb3JtYXQ6OkJ5dGVTaXplKG1lc3NhZ2UpKTsKK30KKworVEVTVChXaXJlRm9ybWF0VGVzdCwgQnl0ZVNpemVFeHRlbnNpb25zKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyBtZXNzYWdlOworICBUZXN0VXRpbDo6U2V0QWxsRXh0ZW5zaW9ucygmbWVzc2FnZSk7CisKKyAgRVhQRUNUX0VRKG1lc3NhZ2UuQnl0ZVNpemUoKSwKKyAgICAgICAgICAgIFdpcmVGb3JtYXQ6OkJ5dGVTaXplKG1lc3NhZ2UpKTsKKyAgbWVzc2FnZS5DbGVhcigpOworICBFWFBFQ1RfRVEoMCwgbWVzc2FnZS5CeXRlU2l6ZSgpKTsKKyAgRVhQRUNUX0VRKDAsIFdpcmVGb3JtYXQ6OkJ5dGVTaXplKG1lc3NhZ2UpKTsKK30KKworVEVTVChXaXJlRm9ybWF0VGVzdCwgQnl0ZVNpemVQYWNrZWQpIHsKKyAgdW5pdHRlc3Q6OlRlc3RQYWNrZWRUeXBlcyBtZXNzYWdlOworICBUZXN0VXRpbDo6U2V0UGFja2VkRmllbGRzKCZtZXNzYWdlKTsKKworICBFWFBFQ1RfRVEobWVzc2FnZS5CeXRlU2l6ZSgpLCBXaXJlRm9ybWF0OjpCeXRlU2l6ZShtZXNzYWdlKSk7CisgIG1lc3NhZ2UuQ2xlYXIoKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuQnl0ZVNpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBXaXJlRm9ybWF0OjpCeXRlU2l6ZShtZXNzYWdlKSk7Cit9CisKK1RFU1QoV2lyZUZvcm1hdFRlc3QsIEJ5dGVTaXplUGFja2VkRXh0ZW5zaW9ucykgeworICB1bml0dGVzdDo6VGVzdFBhY2tlZEV4dGVuc2lvbnMgbWVzc2FnZTsKKyAgVGVzdFV0aWw6OlNldFBhY2tlZEV4dGVuc2lvbnMoJm1lc3NhZ2UpOworCisgIEVYUEVDVF9FUShtZXNzYWdlLkJ5dGVTaXplKCksCisgICAgICAgICAgICBXaXJlRm9ybWF0OjpCeXRlU2l6ZShtZXNzYWdlKSk7CisgIG1lc3NhZ2UuQ2xlYXIoKTsKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuQnl0ZVNpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBXaXJlRm9ybWF0OjpCeXRlU2l6ZShtZXNzYWdlKSk7Cit9CisKK1RFU1QoV2lyZUZvcm1hdFRlc3QsIEJ5dGVTaXplT25lb2YpIHsKKyAgdW5pdHRlc3Q6OlRlc3RPbmVvZjIgbWVzc2FnZTsKKyAgVGVzdFV0aWw6OlNldE9uZW9mMSgmbWVzc2FnZSk7CisKKyAgRVhQRUNUX0VRKG1lc3NhZ2UuQnl0ZVNpemUoKSwKKyAgV2lyZUZvcm1hdDo6Qnl0ZVNpemUobWVzc2FnZSkpOworICBtZXNzYWdlLkNsZWFyKCk7CisKKyAgRVhQRUNUX0VRKDAsIG1lc3NhZ2UuQnl0ZVNpemUoKSk7CisgIEVYUEVDVF9FUSgwLCBXaXJlRm9ybWF0OjpCeXRlU2l6ZShtZXNzYWdlKSk7Cit9CisKK1RFU1QoV2lyZUZvcm1hdFRlc3QsIFNlcmlhbGl6ZSkgeworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisgIHN0cmluZyBnZW5lcmF0ZWRfZGF0YTsKKyAgc3RyaW5nIGR5bmFtaWNfZGF0YTsKKworICBUZXN0VXRpbDo6U2V0QWxsRmllbGRzKCZtZXNzYWdlKTsKKyAgaW50IHNpemUgPSBtZXNzYWdlLkJ5dGVTaXplKCk7CisKKyAgLy8gU2VyaWFsaXplIHVzaW5nIHRoZSBnZW5lcmF0ZWQgY29kZS4KKyAgeworICAgIGlvOjpTdHJpbmdPdXRwdXRTdHJlYW0gcmF3X291dHB1dCgmZ2VuZXJhdGVkX2RhdGEpOworICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSBvdXRwdXQoJnJhd19vdXRwdXQpOworICAgIG1lc3NhZ2UuU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKCZvdXRwdXQpOworICAgIEFTU0VSVF9GQUxTRShvdXRwdXQuSGFkRXJyb3IoKSk7CisgIH0KKworICAvLyBTZXJpYWxpemUgdXNpbmcgV2lyZUZvcm1hdC4KKyAgeworICAgIGlvOjpTdHJpbmdPdXRwdXRTdHJlYW0gcmF3X291dHB1dCgmZHluYW1pY19kYXRhKTsKKyAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KCZyYXdfb3V0cHV0KTsKKyAgICBXaXJlRm9ybWF0OjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMobWVzc2FnZSwgc2l6ZSwgJm91dHB1dCk7CisgICAgQVNTRVJUX0ZBTFNFKG91dHB1dC5IYWRFcnJvcigpKTsKKyAgfQorCisgIC8vIFNob3VsZCBiZSB0aGUgc2FtZS4KKyAgLy8gRG9uJ3QgdXNlIEVYUEVDVF9FUSBoZXJlIGJlY2F1c2Ugd2UncmUgY29tcGFyaW5nIHJhdyBiaW5hcnkgZGF0YSBhbmQKKyAgLy8gd2UgcmVhbGx5IGRvbid0IHdhbnQgaXQgZHVtcGVkIHRvIHN0ZG91dCBvbiBmYWlsdXJlLgorICBFWFBFQ1RfVFJVRShkeW5hbWljX2RhdGEgPT0gZ2VuZXJhdGVkX2RhdGEpOworfQorCitURVNUKFdpcmVGb3JtYXRUZXN0LCBTZXJpYWxpemVFeHRlbnNpb25zKSB7CisgIHVuaXR0ZXN0OjpUZXN0QWxsRXh0ZW5zaW9ucyBtZXNzYWdlOworICBzdHJpbmcgZ2VuZXJhdGVkX2RhdGE7CisgIHN0cmluZyBkeW5hbWljX2RhdGE7CisKKyAgVGVzdFV0aWw6OlNldEFsbEV4dGVuc2lvbnMoJm1lc3NhZ2UpOworICBpbnQgc2l6ZSA9IG1lc3NhZ2UuQnl0ZVNpemUoKTsKKworICAvLyBTZXJpYWxpemUgdXNpbmcgdGhlIGdlbmVyYXRlZCBjb2RlLgorICB7CisgICAgaW86OlN0cmluZ091dHB1dFN0cmVhbSByYXdfb3V0cHV0KCZnZW5lcmF0ZWRfZGF0YSk7CisgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCgmcmF3X291dHB1dCk7CisgICAgbWVzc2FnZS5TZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoJm91dHB1dCk7CisgICAgQVNTRVJUX0ZBTFNFKG91dHB1dC5IYWRFcnJvcigpKTsKKyAgfQorCisgIC8vIFNlcmlhbGl6ZSB1c2luZyBXaXJlRm9ybWF0LgorICB7CisgICAgaW86OlN0cmluZ091dHB1dFN0cmVhbSByYXdfb3V0cHV0KCZkeW5hbWljX2RhdGEpOworICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSBvdXRwdXQoJnJhd19vdXRwdXQpOworICAgIFdpcmVGb3JtYXQ6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcyhtZXNzYWdlLCBzaXplLCAmb3V0cHV0KTsKKyAgICBBU1NFUlRfRkFMU0Uob3V0cHV0LkhhZEVycm9yKCkpOworICB9CisKKyAgLy8gU2hvdWxkIGJlIHRoZSBzYW1lLgorICAvLyBEb24ndCB1c2UgRVhQRUNUX0VRIGhlcmUgYmVjYXVzZSB3ZSdyZSBjb21wYXJpbmcgcmF3IGJpbmFyeSBkYXRhIGFuZAorICAvLyB3ZSByZWFsbHkgZG9uJ3Qgd2FudCBpdCBkdW1wZWQgdG8gc3Rkb3V0IG9uIGZhaWx1cmUuCisgIEVYUEVDVF9UUlVFKGR5bmFtaWNfZGF0YSA9PSBnZW5lcmF0ZWRfZGF0YSk7Cit9CisKK1RFU1QoV2lyZUZvcm1hdFRlc3QsIFNlcmlhbGl6ZUZpZWxkc0FuZEV4dGVuc2lvbnMpIHsKKyAgdW5pdHRlc3Q6OlRlc3RGaWVsZE9yZGVyaW5ncyBtZXNzYWdlOworICBzdHJpbmcgZ2VuZXJhdGVkX2RhdGE7CisgIHN0cmluZyBkeW5hbWljX2RhdGE7CisKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkc0FuZEV4dGVuc2lvbnMoJm1lc3NhZ2UpOworICBpbnQgc2l6ZSA9IG1lc3NhZ2UuQnl0ZVNpemUoKTsKKworICAvLyBTZXJpYWxpemUgdXNpbmcgdGhlIGdlbmVyYXRlZCBjb2RlLgorICB7CisgICAgaW86OlN0cmluZ091dHB1dFN0cmVhbSByYXdfb3V0cHV0KCZnZW5lcmF0ZWRfZGF0YSk7CisgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCgmcmF3X291dHB1dCk7CisgICAgbWVzc2FnZS5TZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoJm91dHB1dCk7CisgICAgQVNTRVJUX0ZBTFNFKG91dHB1dC5IYWRFcnJvcigpKTsKKyAgfQorCisgIC8vIFNlcmlhbGl6ZSB1c2luZyBXaXJlRm9ybWF0LgorICB7CisgICAgaW86OlN0cmluZ091dHB1dFN0cmVhbSByYXdfb3V0cHV0KCZkeW5hbWljX2RhdGEpOworICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSBvdXRwdXQoJnJhd19vdXRwdXQpOworICAgIFdpcmVGb3JtYXQ6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcyhtZXNzYWdlLCBzaXplLCAmb3V0cHV0KTsKKyAgICBBU1NFUlRfRkFMU0Uob3V0cHV0LkhhZEVycm9yKCkpOworICB9CisKKyAgLy8gU2hvdWxkIGJlIHRoZSBzYW1lLgorICAvLyBEb24ndCB1c2UgRVhQRUNUX0VRIGhlcmUgYmVjYXVzZSB3ZSdyZSBjb21wYXJpbmcgcmF3IGJpbmFyeSBkYXRhIGFuZAorICAvLyB3ZSByZWFsbHkgZG9uJ3Qgd2FudCBpdCBkdW1wZWQgdG8gc3Rkb3V0IG9uIGZhaWx1cmUuCisgIEVYUEVDVF9UUlVFKGR5bmFtaWNfZGF0YSA9PSBnZW5lcmF0ZWRfZGF0YSk7CisKKyAgLy8gU2hvdWxkIG91dHB1dCBpbiBjYW5vbmljYWwgb3JkZXIuCisgIFRlc3RVdGlsOjpFeHBlY3RBbGxGaWVsZHNBbmRFeHRlbnNpb25zSW5PcmRlcihkeW5hbWljX2RhdGEpOworICBUZXN0VXRpbDo6RXhwZWN0QWxsRmllbGRzQW5kRXh0ZW5zaW9uc0luT3JkZXIoZ2VuZXJhdGVkX2RhdGEpOworfQorCitURVNUKFdpcmVGb3JtYXRUZXN0LCBTZXJpYWxpemVPbmVvZikgeworICB1bml0dGVzdDo6VGVzdE9uZW9mMiBtZXNzYWdlOworICBzdHJpbmcgZ2VuZXJhdGVkX2RhdGE7CisgIHN0cmluZyBkeW5hbWljX2RhdGE7CisKKyAgVGVzdFV0aWw6OlNldE9uZW9mMSgmbWVzc2FnZSk7CisgIGludCBzaXplID0gbWVzc2FnZS5CeXRlU2l6ZSgpOworCisgIC8vIFNlcmlhbGl6ZSB1c2luZyB0aGUgZ2VuZXJhdGVkIGNvZGUuCisgIHsKKyAgICBpbzo6U3RyaW5nT3V0cHV0U3RyZWFtIHJhd19vdXRwdXQoJmdlbmVyYXRlZF9kYXRhKTsKKyAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KCZyYXdfb3V0cHV0KTsKKyAgICBtZXNzYWdlLlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygmb3V0cHV0KTsKKyAgICBBU1NFUlRfRkFMU0Uob3V0cHV0LkhhZEVycm9yKCkpOworICB9CisKKyAgLy8gU2VyaWFsaXplIHVzaW5nIFdpcmVGb3JtYXQuCisgIHsKKyAgICBpbzo6U3RyaW5nT3V0cHV0U3RyZWFtIHJhd19vdXRwdXQoJmR5bmFtaWNfZGF0YSk7CisgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCgmcmF3X291dHB1dCk7CisgICAgV2lyZUZvcm1hdDo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzKG1lc3NhZ2UsIHNpemUsICZvdXRwdXQpOworICAgIEFTU0VSVF9GQUxTRShvdXRwdXQuSGFkRXJyb3IoKSk7CisgIH0KKworICAvLyBTaG91bGQgYmUgdGhlIHNhbWUuCisgIC8vIERvbid0IHVzZSBFWFBFQ1RfRVEgaGVyZSBiZWNhdXNlIHdlJ3JlIGNvbXBhcmluZyByYXcgYmluYXJ5IGRhdGEgYW5kCisgIC8vIHdlIHJlYWxseSBkb24ndCB3YW50IGl0IGR1bXBlZCB0byBzdGRvdXQgb24gZmFpbHVyZS4KKyAgRVhQRUNUX1RSVUUoZHluYW1pY19kYXRhID09IGdlbmVyYXRlZF9kYXRhKTsKK30KKworVEVTVChXaXJlRm9ybWF0VGVzdCwgUGFyc2VNdWx0aXBsZUV4dGVuc2lvblJhbmdlcykgeworICAvLyBNYWtlIHN1cmUgd2UgY2FuIHBhcnNlIGEgbWVzc2FnZSB0aGF0IGNvbnRhaW5zIG11bHRpcGxlIGV4dGVuc2lvbnMgcmFuZ2VzLgorICB1bml0dGVzdDo6VGVzdEZpZWxkT3JkZXJpbmdzIHNvdXJjZTsKKyAgc3RyaW5nIGRhdGE7CisKKyAgVGVzdFV0aWw6OlNldEFsbEZpZWxkc0FuZEV4dGVuc2lvbnMoJnNvdXJjZSk7CisgIHNvdXJjZS5TZXJpYWxpemVUb1N0cmluZygmZGF0YSk7CisKKyAgeworICAgIHVuaXR0ZXN0OjpUZXN0RmllbGRPcmRlcmluZ3MgZGVzdDsKKyAgICBFWFBFQ1RfVFJVRShkZXN0LlBhcnNlRnJvbVN0cmluZyhkYXRhKSk7CisgICAgRVhQRUNUX0VRKHNvdXJjZS5EZWJ1Z1N0cmluZygpLCBkZXN0LkRlYnVnU3RyaW5nKCkpOworICB9CisKKyAgLy8gQWxzbyB0ZXN0IHVzaW5nIHJlZmxlY3Rpb24tYmFzZWQgcGFyc2luZy4KKyAgeworICAgIHVuaXR0ZXN0OjpUZXN0RmllbGRPcmRlcmluZ3MgZGVzdDsKKyAgICBpbzo6QXJyYXlJbnB1dFN0cmVhbSByYXdfaW5wdXQoZGF0YS5kYXRhKCksIGRhdGEuc2l6ZSgpKTsKKyAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSBjb2RlZF9pbnB1dCgmcmF3X2lucHV0KTsKKyAgICBFWFBFQ1RfVFJVRShXaXJlRm9ybWF0OjpQYXJzZUFuZE1lcmdlUGFydGlhbCgmY29kZWRfaW5wdXQsICZkZXN0KSk7CisgICAgRVhQRUNUX0VRKHNvdXJjZS5EZWJ1Z1N0cmluZygpLCBkZXN0LkRlYnVnU3RyaW5nKCkpOworICB9Cit9CisKK2NvbnN0IGludCBrVW5rbm93blR5cGVJZCA9IDE1NTAwNTU7CisKK1RFU1QoV2lyZUZvcm1hdFRlc3QsIFNlcmlhbGl6ZU1lc3NhZ2VTZXQpIHsKKyAgLy8gU2V0IHVwIGEgVGVzdE1lc3NhZ2VTZXQgd2l0aCB0d28ga25vd24gbWVzc2FnZXMgYW5kIGFuIHVua25vd24gb25lLgorICBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdDo6VGVzdE1lc3NhZ2VTZXQgbWVzc2FnZV9zZXQ7CisgIG1lc3NhZ2Vfc2V0Lk11dGFibGVFeHRlbnNpb24oCisgICAgdW5pdHRlc3Q6OlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMTo6bWVzc2FnZV9zZXRfZXh0ZW5zaW9uKS0+c2V0X2koMTIzKTsKKyAgbWVzc2FnZV9zZXQuTXV0YWJsZUV4dGVuc2lvbigKKyAgICB1bml0dGVzdDo6VGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24yOjptZXNzYWdlX3NldF9leHRlbnNpb24pLT5zZXRfc3RyKCJmb28iKTsKKyAgbWVzc2FnZV9zZXQubXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5BZGRMZW5ndGhEZWxpbWl0ZWQoCisgICAga1Vua25vd25UeXBlSWQsICJiYXIiKTsKKworICBzdHJpbmcgZGF0YTsKKyAgQVNTRVJUX1RSVUUobWVzc2FnZV9zZXQuU2VyaWFsaXplVG9TdHJpbmcoJmRhdGEpKTsKKworICAvLyBQYXJzZSBiYWNrIHVzaW5nIFJhd01lc3NhZ2VTZXQgYW5kIGNoZWNrIHRoZSBjb250ZW50cy4KKyAgdW5pdHRlc3Q6OlJhd01lc3NhZ2VTZXQgcmF3OworICBBU1NFUlRfVFJVRShyYXcuUGFyc2VGcm9tU3RyaW5nKGRhdGEpKTsKKworICBFWFBFQ1RfRVEoMCwgcmF3LnVua25vd25fZmllbGRzKCkuZmllbGRfY291bnQoKSk7CisKKyAgQVNTRVJUX0VRKDMsIHJhdy5pdGVtX3NpemUoKSk7CisgIEVYUEVDVF9FUSgKKyAgICB1bml0dGVzdDo6VGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xOjpkZXNjcmlwdG9yKCktPmV4dGVuc2lvbigwKS0+bnVtYmVyKCksCisgICAgcmF3Lml0ZW0oMCkudHlwZV9pZCgpKTsKKyAgRVhQRUNUX0VRKAorICAgIHVuaXR0ZXN0OjpUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjI6OmRlc2NyaXB0b3IoKS0+ZXh0ZW5zaW9uKDApLT5udW1iZXIoKSwKKyAgICByYXcuaXRlbSgxKS50eXBlX2lkKCkpOworICBFWFBFQ1RfRVEoa1Vua25vd25UeXBlSWQsIHJhdy5pdGVtKDIpLnR5cGVfaWQoKSk7CisKKyAgdW5pdHRlc3Q6OlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMSBtZXNzYWdlMTsKKyAgRVhQRUNUX1RSVUUobWVzc2FnZTEuUGFyc2VGcm9tU3RyaW5nKHJhdy5pdGVtKDApLm1lc3NhZ2UoKSkpOworICBFWFBFQ1RfRVEoMTIzLCBtZXNzYWdlMS5pKCkpOworCisgIHVuaXR0ZXN0OjpUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjIgbWVzc2FnZTI7CisgIEVYUEVDVF9UUlVFKG1lc3NhZ2UyLlBhcnNlRnJvbVN0cmluZyhyYXcuaXRlbSgxKS5tZXNzYWdlKCkpKTsKKyAgRVhQRUNUX0VRKCJmb28iLCBtZXNzYWdlMi5zdHIoKSk7CisKKyAgRVhQRUNUX0VRKCJiYXIiLCByYXcuaXRlbSgyKS5tZXNzYWdlKCkpOworfQorCitURVNUKFdpcmVGb3JtYXRUZXN0LCBTZXJpYWxpemVNZXNzYWdlU2V0VmFyaW91c1dheXNBcmVFcXVhbCkgeworICAvLyBTZXJpYWxpemUgYSBNZXNzYWdlU2V0IHRvIGEgc3RyZWFtIGFuZCB0byBhIGZsYXQgYXJyYXkgdXNpbmcgZ2VuZXJhdGVkCisgIC8vIGNvZGUsIGFuZCBhbHNvIHVzaW5nIFdpcmVGb3JtYXQsIGFuZCBjaGVjayB0aGF0IHRoZSByZXN1bHRzIGFyZSBlcXVhbC4KKyAgLy8gU2V0IHVwIGEgVGVzdE1lc3NhZ2VTZXQgd2l0aCB0d28ga25vd24gbWVzc2FnZXMgYW5kIGFuIHVua25vd24gb25lLCBhcworICAvLyBhYm92ZS4KKworICBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdDo6VGVzdE1lc3NhZ2VTZXQgbWVzc2FnZV9zZXQ7CisgIG1lc3NhZ2Vfc2V0Lk11dGFibGVFeHRlbnNpb24oCisgICAgdW5pdHRlc3Q6OlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMTo6bWVzc2FnZV9zZXRfZXh0ZW5zaW9uKS0+c2V0X2koMTIzKTsKKyAgbWVzc2FnZV9zZXQuTXV0YWJsZUV4dGVuc2lvbigKKyAgICB1bml0dGVzdDo6VGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24yOjptZXNzYWdlX3NldF9leHRlbnNpb24pLT5zZXRfc3RyKCJmb28iKTsKKyAgbWVzc2FnZV9zZXQubXV0YWJsZV91bmtub3duX2ZpZWxkcygpLT5BZGRMZW5ndGhEZWxpbWl0ZWQoCisgICAga1Vua25vd25UeXBlSWQsICJiYXIiKTsKKworICBpbnQgc2l6ZSA9IG1lc3NhZ2Vfc2V0LkJ5dGVTaXplKCk7CisgIEVYUEVDVF9FUShzaXplLCBtZXNzYWdlX3NldC5HZXRDYWNoZWRTaXplKCkpOworICBBU1NFUlRfRVEoc2l6ZSwgV2lyZUZvcm1hdDo6Qnl0ZVNpemUobWVzc2FnZV9zZXQpKTsKKworICBzdHJpbmcgZmxhdF9kYXRhOworICBzdHJpbmcgc3RyZWFtX2RhdGE7CisgIHN0cmluZyBkeW5hbWljX2RhdGE7CisgIGZsYXRfZGF0YS5yZXNpemUoc2l6ZSk7CisgIHN0cmVhbV9kYXRhLnJlc2l6ZShzaXplKTsKKworICAvLyBTZXJpYWxpemUgdG8gZmxhdCBhcnJheQorICB7CisgICAgdWludDgqIHRhcmdldCA9IHJlaW50ZXJwcmV0X2Nhc3Q8dWludDgqPihzdHJpbmdfYXNfYXJyYXkoJmZsYXRfZGF0YSkpOworICAgIHVpbnQ4KiBlbmQgPSBtZXNzYWdlX3NldC5TZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KHRhcmdldCk7CisgICAgRVhQRUNUX0VRKHNpemUsIGVuZCAtIHRhcmdldCk7CisgIH0KKworICAvLyBTZXJpYWxpemUgdG8gYnVmZmVyCisgIHsKKyAgICBpbzo6QXJyYXlPdXRwdXRTdHJlYW0gYXJyYXlfc3RyZWFtKHN0cmluZ19hc19hcnJheSgmc3RyZWFtX2RhdGEpLCBzaXplLCAxKTsKKyAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0X3N0cmVhbSgmYXJyYXlfc3RyZWFtKTsKKyAgICBtZXNzYWdlX3NldC5TZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoJm91dHB1dF9zdHJlYW0pOworICAgIEFTU0VSVF9GQUxTRShvdXRwdXRfc3RyZWFtLkhhZEVycm9yKCkpOworICB9CisKKyAgLy8gU2VyaWFsaXplIHRvIGJ1ZmZlciB3aXRoIFdpcmVGb3JtYXQuCisgIHsKKyAgICBpbzo6U3RyaW5nT3V0cHV0U3RyZWFtIHN0cmluZ19zdHJlYW0oJmR5bmFtaWNfZGF0YSk7CisgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dF9zdHJlYW0oJnN0cmluZ19zdHJlYW0pOworICAgIFdpcmVGb3JtYXQ6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcyhtZXNzYWdlX3NldCwgc2l6ZSwgJm91dHB1dF9zdHJlYW0pOworICAgIEFTU0VSVF9GQUxTRShvdXRwdXRfc3RyZWFtLkhhZEVycm9yKCkpOworICB9CisKKyAgRVhQRUNUX1RSVUUoZmxhdF9kYXRhID09IHN0cmVhbV9kYXRhKTsKKyAgRVhQRUNUX1RSVUUoZmxhdF9kYXRhID09IGR5bmFtaWNfZGF0YSk7Cit9CisKK1RFU1QoV2lyZUZvcm1hdFRlc3QsIFBhcnNlTWVzc2FnZVNldCkgeworICAvLyBTZXQgdXAgYSBSYXdNZXNzYWdlU2V0IHdpdGggdHdvIGtub3duIG1lc3NhZ2VzIGFuZCBhbiB1bmtub3duIG9uZS4KKyAgdW5pdHRlc3Q6OlJhd01lc3NhZ2VTZXQgcmF3OworCisgIHsKKyAgICB1bml0dGVzdDo6UmF3TWVzc2FnZVNldDo6SXRlbSogaXRlbSA9IHJhdy5hZGRfaXRlbSgpOworICAgIGl0ZW0tPnNldF90eXBlX2lkKAorICAgICAgdW5pdHRlc3Q6OlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMTo6ZGVzY3JpcHRvcigpLT5leHRlbnNpb24oMCktPm51bWJlcigpKTsKKyAgICB1bml0dGVzdDo6VGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xIG1lc3NhZ2U7CisgICAgbWVzc2FnZS5zZXRfaSgxMjMpOworICAgIG1lc3NhZ2UuU2VyaWFsaXplVG9TdHJpbmcoaXRlbS0+bXV0YWJsZV9tZXNzYWdlKCkpOworICB9CisKKyAgeworICAgIHVuaXR0ZXN0OjpSYXdNZXNzYWdlU2V0OjpJdGVtKiBpdGVtID0gcmF3LmFkZF9pdGVtKCk7CisgICAgaXRlbS0+c2V0X3R5cGVfaWQoCisgICAgICB1bml0dGVzdDo6VGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24yOjpkZXNjcmlwdG9yKCktPmV4dGVuc2lvbigwKS0+bnVtYmVyKCkpOworICAgIHVuaXR0ZXN0OjpUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjIgbWVzc2FnZTsKKyAgICBtZXNzYWdlLnNldF9zdHIoImZvbyIpOworICAgIG1lc3NhZ2UuU2VyaWFsaXplVG9TdHJpbmcoaXRlbS0+bXV0YWJsZV9tZXNzYWdlKCkpOworICB9CisKKyAgeworICAgIHVuaXR0ZXN0OjpSYXdNZXNzYWdlU2V0OjpJdGVtKiBpdGVtID0gcmF3LmFkZF9pdGVtKCk7CisgICAgaXRlbS0+c2V0X3R5cGVfaWQoa1Vua25vd25UeXBlSWQpOworICAgIGl0ZW0tPnNldF9tZXNzYWdlKCJiYXIiKTsKKyAgfQorCisgIHN0cmluZyBkYXRhOworICBBU1NFUlRfVFJVRShyYXcuU2VyaWFsaXplVG9TdHJpbmcoJmRhdGEpKTsKKworICAvLyBQYXJzZSBhcyBhIFRlc3RNZXNzYWdlU2V0IGFuZCBjaGVjayB0aGUgY29udGVudHMuCisgIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0OjpUZXN0TWVzc2FnZVNldCBtZXNzYWdlX3NldDsKKyAgQVNTRVJUX1RSVUUobWVzc2FnZV9zZXQuUGFyc2VGcm9tU3RyaW5nKGRhdGEpKTsKKworICBFWFBFQ1RfRVEoMTIzLCBtZXNzYWdlX3NldC5HZXRFeHRlbnNpb24oCisgICAgdW5pdHRlc3Q6OlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMTo6bWVzc2FnZV9zZXRfZXh0ZW5zaW9uKS5pKCkpOworICBFWFBFQ1RfRVEoImZvbyIsIG1lc3NhZ2Vfc2V0LkdldEV4dGVuc2lvbigKKyAgICB1bml0dGVzdDo6VGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24yOjptZXNzYWdlX3NldF9leHRlbnNpb24pLnN0cigpKTsKKworICBBU1NFUlRfRVEoMSwgbWVzc2FnZV9zZXQudW5rbm93bl9maWVsZHMoKS5maWVsZF9jb3VudCgpKTsKKyAgQVNTRVJUX0VRKFVua25vd25GaWVsZDo6VFlQRV9MRU5HVEhfREVMSU1JVEVELAorICAgICAgICAgICAgbWVzc2FnZV9zZXQudW5rbm93bl9maWVsZHMoKS5maWVsZCgwKS50eXBlKCkpOworICBFWFBFQ1RfRVEoImJhciIsIG1lc3NhZ2Vfc2V0LnVua25vd25fZmllbGRzKCkuZmllbGQoMCkubGVuZ3RoX2RlbGltaXRlZCgpKTsKKworICAvLyBBbHNvIHBhcnNlIHVzaW5nIFdpcmVGb3JtYXQuCisgIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0OjpUZXN0TWVzc2FnZVNldCBkeW5hbWljX21lc3NhZ2Vfc2V0OworICBpbzo6Q29kZWRJbnB1dFN0cmVhbSBpbnB1dChyZWludGVycHJldF9jYXN0PGNvbnN0IHVpbnQ4Kj4oZGF0YS5kYXRhKCkpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhLnNpemUoKSk7CisgIEFTU0VSVF9UUlVFKFdpcmVGb3JtYXQ6OlBhcnNlQW5kTWVyZ2VQYXJ0aWFsKCZpbnB1dCwgJmR5bmFtaWNfbWVzc2FnZV9zZXQpKTsKKyAgRVhQRUNUX0VRKG1lc3NhZ2Vfc2V0LkRlYnVnU3RyaW5nKCksIGR5bmFtaWNfbWVzc2FnZV9zZXQuRGVidWdTdHJpbmcoKSk7Cit9CisKK1RFU1QoV2lyZUZvcm1hdFRlc3QsIFBhcnNlTWVzc2FnZVNldFdpdGhSZXZlcnNlVGFnT3JkZXIpIHsKKyAgc3RyaW5nIGRhdGE7CisgIHsKKyAgICB1bml0dGVzdDo6VGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xIG1lc3NhZ2U7CisgICAgbWVzc2FnZS5zZXRfaSgxMjMpOworICAgIC8vIEJ1aWxkIGEgTWVzc2FnZVNldCBtYW51YWxseSB3aXRoIGl0cyBtZXNzYWdlIGNvbnRlbnQgcHV0IGJlZm9yZSBpdHMKKyAgICAvLyB0eXBlX2lkLgorICAgIGlvOjpTdHJpbmdPdXRwdXRTdHJlYW0gb3V0cHV0X3N0cmVhbSgmZGF0YSk7CisgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtIGNvZGVkX291dHB1dCgmb3V0cHV0X3N0cmVhbSk7CisgICAgY29kZWRfb3V0cHV0LldyaXRlVGFnKFdpcmVGb3JtYXRMaXRlOjprTWVzc2FnZVNldEl0ZW1TdGFydFRhZyk7CisgICAgLy8gV3JpdGUgdGhlIG1lc3NhZ2UgY29udGVudCBmaXJzdC4KKyAgICBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVUYWcoV2lyZUZvcm1hdExpdGU6OmtNZXNzYWdlU2V0TWVzc2FnZU51bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0xFTkdUSF9ERUxJTUlURUQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZjb2RlZF9vdXRwdXQpOworICAgIGNvZGVkX291dHB1dC5Xcml0ZVZhcmludDMyKG1lc3NhZ2UuQnl0ZVNpemUoKSk7CisgICAgbWVzc2FnZS5TZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoJmNvZGVkX291dHB1dCk7CisgICAgLy8gV3JpdGUgdGhlIHR5cGUgaWQuCisgICAgdWludDMyIHR5cGVfaWQgPSBtZXNzYWdlLkdldERlc2NyaXB0b3IoKS0+ZXh0ZW5zaW9uKDApLT5udW1iZXIoKTsKKyAgICBXaXJlRm9ybWF0TGl0ZTo6V3JpdGVVSW50MzIoV2lyZUZvcm1hdExpdGU6OmtNZXNzYWdlU2V0VHlwZUlkTnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlX2lkLCAmY29kZWRfb3V0cHV0KTsKKyAgICBjb2RlZF9vdXRwdXQuV3JpdGVUYWcoV2lyZUZvcm1hdExpdGU6OmtNZXNzYWdlU2V0SXRlbUVuZFRhZyk7CisgIH0KKyAgeworICAgIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0OjpUZXN0TWVzc2FnZVNldCBtZXNzYWdlX3NldDsKKyAgICBBU1NFUlRfVFJVRShtZXNzYWdlX3NldC5QYXJzZUZyb21TdHJpbmcoZGF0YSkpOworCisgICAgRVhQRUNUX0VRKDEyMywgbWVzc2FnZV9zZXQuR2V0RXh0ZW5zaW9uKAorICAgICAgICB1bml0dGVzdDo6VGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xOjptZXNzYWdlX3NldF9leHRlbnNpb24pLmkoKSk7CisgIH0KKyAgeworICAgIC8vIFRlc3QgcGFyc2UgdGhlIG1lc3NhZ2UgdmlhIFJlZmxlY3Rpb24uCisgICAgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3Q6OlRlc3RNZXNzYWdlU2V0IG1lc3NhZ2Vfc2V0OworICAgIGlvOjpDb2RlZElucHV0U3RyZWFtIGlucHV0KAorICAgICAgICByZWludGVycHJldF9jYXN0PGNvbnN0IHVpbnQ4Kj4oZGF0YS5kYXRhKCkpLCBkYXRhLnNpemUoKSk7CisgICAgRVhQRUNUX1RSVUUoV2lyZUZvcm1hdDo6UGFyc2VBbmRNZXJnZVBhcnRpYWwoJmlucHV0LCAmbWVzc2FnZV9zZXQpKTsKKyAgICBFWFBFQ1RfVFJVRShpbnB1dC5Db25zdW1lZEVudGlyZU1lc3NhZ2UoKSk7CisKKyAgICBFWFBFQ1RfRVEoMTIzLCBtZXNzYWdlX3NldC5HZXRFeHRlbnNpb24oCisgICAgICAgIHVuaXR0ZXN0OjpUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjE6Om1lc3NhZ2Vfc2V0X2V4dGVuc2lvbikuaSgpKTsKKyAgfQorfQorCitURVNUKFdpcmVGb3JtYXRUZXN0LCBQYXJzZUJyb2tlbk1lc3NhZ2VTZXQpIHsKKyAgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3Q6OlRlc3RNZXNzYWdlU2V0IG1lc3NhZ2Vfc2V0OworICBzdHJpbmcgaW5wdXQoImdvb2RieWUiKTsgIC8vIEludmFsaWQgd2lyZSBmb3JtYXQgZGF0YS4KKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2Vfc2V0LlBhcnNlRnJvbVN0cmluZyhpbnB1dCkpOworfQorCitURVNUKFdpcmVGb3JtYXRUZXN0LCBSZWN1cnNpb25MaW1pdCkgeworICB1bml0dGVzdDo6VGVzdFJlY3Vyc2l2ZU1lc3NhZ2UgbWVzc2FnZTsKKyAgbWVzc2FnZS5tdXRhYmxlX2EoKS0+bXV0YWJsZV9hKCktPm11dGFibGVfYSgpLT5tdXRhYmxlX2EoKS0+c2V0X2koMSk7CisgIHN0cmluZyBkYXRhOworICBtZXNzYWdlLlNlcmlhbGl6ZVRvU3RyaW5nKCZkYXRhKTsKKworICB7CisgICAgaW86OkFycmF5SW5wdXRTdHJlYW0gcmF3X2lucHV0KGRhdGEuZGF0YSgpLCBkYXRhLnNpemUoKSk7CisgICAgaW86OkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQoJnJhd19pbnB1dCk7CisgICAgaW5wdXQuU2V0UmVjdXJzaW9uTGltaXQoNCk7CisgICAgdW5pdHRlc3Q6OlRlc3RSZWN1cnNpdmVNZXNzYWdlIG1lc3NhZ2UyOworICAgIEVYUEVDVF9UUlVFKG1lc3NhZ2UyLlBhcnNlRnJvbUNvZGVkU3RyZWFtKCZpbnB1dCkpOworICB9CisKKyAgeworICAgIGlvOjpBcnJheUlucHV0U3RyZWFtIHJhd19pbnB1dChkYXRhLmRhdGEoKSwgZGF0YS5zaXplKCkpOworICAgIGlvOjpDb2RlZElucHV0U3RyZWFtIGlucHV0KCZyYXdfaW5wdXQpOworICAgIGlucHV0LlNldFJlY3Vyc2lvbkxpbWl0KDMpOworICAgIHVuaXR0ZXN0OjpUZXN0UmVjdXJzaXZlTWVzc2FnZSBtZXNzYWdlMjsKKyAgICBFWFBFQ1RfRkFMU0UobWVzc2FnZTIuUGFyc2VGcm9tQ29kZWRTdHJlYW0oJmlucHV0KSk7CisgIH0KK30KKworVEVTVChXaXJlRm9ybWF0VGVzdCwgVW5rbm93bkZpZWxkUmVjdXJzaW9uTGltaXQpIHsKKyAgdW5pdHRlc3Q6OlRlc3RFbXB0eU1lc3NhZ2UgbWVzc2FnZTsKKyAgbWVzc2FnZS5tdXRhYmxlX3Vua25vd25fZmllbGRzKCkKKyAgICAgICAgLT5BZGRHcm91cCgxMjM0KQorICAgICAgICAtPkFkZEdyb3VwKDEyMzQpCisgICAgICAgIC0+QWRkR3JvdXAoMTIzNCkKKyAgICAgICAgLT5BZGRHcm91cCgxMjM0KQorICAgICAgICAtPkFkZFZhcmludCgxMjM0LCAxMjMpOworICBzdHJpbmcgZGF0YTsKKyAgbWVzc2FnZS5TZXJpYWxpemVUb1N0cmluZygmZGF0YSk7CisKKyAgeworICAgIGlvOjpBcnJheUlucHV0U3RyZWFtIHJhd19pbnB1dChkYXRhLmRhdGEoKSwgZGF0YS5zaXplKCkpOworICAgIGlvOjpDb2RlZElucHV0U3RyZWFtIGlucHV0KCZyYXdfaW5wdXQpOworICAgIGlucHV0LlNldFJlY3Vyc2lvbkxpbWl0KDQpOworICAgIHVuaXR0ZXN0OjpUZXN0RW1wdHlNZXNzYWdlIG1lc3NhZ2UyOworICAgIEVYUEVDVF9UUlVFKG1lc3NhZ2UyLlBhcnNlRnJvbUNvZGVkU3RyZWFtKCZpbnB1dCkpOworICB9CisKKyAgeworICAgIGlvOjpBcnJheUlucHV0U3RyZWFtIHJhd19pbnB1dChkYXRhLmRhdGEoKSwgZGF0YS5zaXplKCkpOworICAgIGlvOjpDb2RlZElucHV0U3RyZWFtIGlucHV0KCZyYXdfaW5wdXQpOworICAgIGlucHV0LlNldFJlY3Vyc2lvbkxpbWl0KDMpOworICAgIHVuaXR0ZXN0OjpUZXN0RW1wdHlNZXNzYWdlIG1lc3NhZ2UyOworICAgIEVYUEVDVF9GQUxTRShtZXNzYWdlMi5QYXJzZUZyb21Db2RlZFN0cmVhbSgmaW5wdXQpKTsKKyAgfQorfQorCitURVNUKFdpcmVGb3JtYXRUZXN0LCBaaWdaYWcpIHsKKy8vIGF2b2lkIGxpbmUtd3JhcHBpbmcKKyNkZWZpbmUgTEwoeCkgR09PR0xFX0xPTkdMT05HKHgpCisjZGVmaW5lIFVMTCh4KSBHT09HTEVfVUxPTkdMT05HKHgpCisjZGVmaW5lIFppZ1phZ0VuY29kZTMyKHgpIFdpcmVGb3JtYXRMaXRlOjpaaWdaYWdFbmNvZGUzMih4KQorI2RlZmluZSBaaWdaYWdEZWNvZGUzMih4KSBXaXJlRm9ybWF0TGl0ZTo6WmlnWmFnRGVjb2RlMzIoeCkKKyNkZWZpbmUgWmlnWmFnRW5jb2RlNjQoeCkgV2lyZUZvcm1hdExpdGU6OlppZ1phZ0VuY29kZTY0KHgpCisjZGVmaW5lIFppZ1phZ0RlY29kZTY0KHgpIFdpcmVGb3JtYXRMaXRlOjpaaWdaYWdEZWNvZGU2NCh4KQorCisgIEVYUEVDVF9FUSgwdSwgWmlnWmFnRW5jb2RlMzIoIDApKTsKKyAgRVhQRUNUX0VRKDF1LCBaaWdaYWdFbmNvZGUzMigtMSkpOworICBFWFBFQ1RfRVEoMnUsIFppZ1phZ0VuY29kZTMyKCAxKSk7CisgIEVYUEVDVF9FUSgzdSwgWmlnWmFnRW5jb2RlMzIoLTIpKTsKKyAgRVhQRUNUX0VRKDB4N0ZGRkZGRkV1LCBaaWdaYWdFbmNvZGUzMigweDNGRkZGRkZGKSk7CisgIEVYUEVDVF9FUSgweDdGRkZGRkZGdSwgWmlnWmFnRW5jb2RlMzIoMHhDMDAwMDAwMCkpOworICBFWFBFQ1RfRVEoMHhGRkZGRkZGRXUsIFppZ1phZ0VuY29kZTMyKDB4N0ZGRkZGRkYpKTsKKyAgRVhQRUNUX0VRKDB4RkZGRkZGRkZ1LCBaaWdaYWdFbmNvZGUzMigweDgwMDAwMDAwKSk7CisKKyAgRVhQRUNUX0VRKCAwLCBaaWdaYWdEZWNvZGUzMigwdSkpOworICBFWFBFQ1RfRVEoLTEsIFppZ1phZ0RlY29kZTMyKDF1KSk7CisgIEVYUEVDVF9FUSggMSwgWmlnWmFnRGVjb2RlMzIoMnUpKTsKKyAgRVhQRUNUX0VRKC0yLCBaaWdaYWdEZWNvZGUzMigzdSkpOworICBFWFBFQ1RfRVEoMHgzRkZGRkZGRiwgWmlnWmFnRGVjb2RlMzIoMHg3RkZGRkZGRXUpKTsKKyAgRVhQRUNUX0VRKDB4QzAwMDAwMDAsIFppZ1phZ0RlY29kZTMyKDB4N0ZGRkZGRkZ1KSk7CisgIEVYUEVDVF9FUSgweDdGRkZGRkZGLCBaaWdaYWdEZWNvZGUzMigweEZGRkZGRkZFdSkpOworICBFWFBFQ1RfRVEoMHg4MDAwMDAwMCwgWmlnWmFnRGVjb2RlMzIoMHhGRkZGRkZGRnUpKTsKKworICBFWFBFQ1RfRVEoMHUsIFppZ1phZ0VuY29kZTY0KCAwKSk7CisgIEVYUEVDVF9FUSgxdSwgWmlnWmFnRW5jb2RlNjQoLTEpKTsKKyAgRVhQRUNUX0VRKDJ1LCBaaWdaYWdFbmNvZGU2NCggMSkpOworICBFWFBFQ1RfRVEoM3UsIFppZ1phZ0VuY29kZTY0KC0yKSk7CisgIEVYUEVDVF9FUShVTEwoMHgwMDAwMDAwMDdGRkZGRkZFKSwgWmlnWmFnRW5jb2RlNjQoTEwoMHgwMDAwMDAwMDNGRkZGRkZGKSkpOworICBFWFBFQ1RfRVEoVUxMKDB4MDAwMDAwMDA3RkZGRkZGRiksIFppZ1phZ0VuY29kZTY0KExMKDB4RkZGRkZGRkZDMDAwMDAwMCkpKTsKKyAgRVhQRUNUX0VRKFVMTCgweDAwMDAwMDAwRkZGRkZGRkUpLCBaaWdaYWdFbmNvZGU2NChMTCgweDAwMDAwMDAwN0ZGRkZGRkYpKSk7CisgIEVYUEVDVF9FUShVTEwoMHgwMDAwMDAwMEZGRkZGRkZGKSwgWmlnWmFnRW5jb2RlNjQoTEwoMHhGRkZGRkZGRjgwMDAwMDAwKSkpOworICBFWFBFQ1RfRVEoVUxMKDB4RkZGRkZGRkZGRkZGRkZGRSksIFppZ1phZ0VuY29kZTY0KExMKDB4N0ZGRkZGRkZGRkZGRkZGRikpKTsKKyAgRVhQRUNUX0VRKFVMTCgweEZGRkZGRkZGRkZGRkZGRkYpLCBaaWdaYWdFbmNvZGU2NChMTCgweDgwMDAwMDAwMDAwMDAwMDApKSk7CisKKyAgRVhQRUNUX0VRKCAwLCBaaWdaYWdEZWNvZGU2NCgwdSkpOworICBFWFBFQ1RfRVEoLTEsIFppZ1phZ0RlY29kZTY0KDF1KSk7CisgIEVYUEVDVF9FUSggMSwgWmlnWmFnRGVjb2RlNjQoMnUpKTsKKyAgRVhQRUNUX0VRKC0yLCBaaWdaYWdEZWNvZGU2NCgzdSkpOworICBFWFBFQ1RfRVEoTEwoMHgwMDAwMDAwMDNGRkZGRkZGKSwgWmlnWmFnRGVjb2RlNjQoVUxMKDB4MDAwMDAwMDA3RkZGRkZGRSkpKTsKKyAgRVhQRUNUX0VRKExMKDB4RkZGRkZGRkZDMDAwMDAwMCksIFppZ1phZ0RlY29kZTY0KFVMTCgweDAwMDAwMDAwN0ZGRkZGRkYpKSk7CisgIEVYUEVDVF9FUShMTCgweDAwMDAwMDAwN0ZGRkZGRkYpLCBaaWdaYWdEZWNvZGU2NChVTEwoMHgwMDAwMDAwMEZGRkZGRkZFKSkpOworICBFWFBFQ1RfRVEoTEwoMHhGRkZGRkZGRjgwMDAwMDAwKSwgWmlnWmFnRGVjb2RlNjQoVUxMKDB4MDAwMDAwMDBGRkZGRkZGRikpKTsKKyAgRVhQRUNUX0VRKExMKDB4N0ZGRkZGRkZGRkZGRkZGRiksIFppZ1phZ0RlY29kZTY0KFVMTCgweEZGRkZGRkZGRkZGRkZGRkUpKSk7CisgIEVYUEVDVF9FUShMTCgweDgwMDAwMDAwMDAwMDAwMDApLCBaaWdaYWdEZWNvZGU2NChVTEwoMHhGRkZGRkZGRkZGRkZGRkZGKSkpOworCisgIC8vIFNvbWUgZWFzaWVyLXRvLXZlcmlmeSByb3VuZC10cmlwIHRlc3RzLiAgVGhlIGlucHV0cyAob3RoZXIgdGhhbiAwLCAxLCAtMSkKKyAgLy8gd2VyZSBjaG9zZW4gc2VtaS1yYW5kb21seSB2aWEga2V5Ym9hcmQgYmFzaGluZy4KKyAgRVhQRUNUX0VRKCAgICAwLCBaaWdaYWdEZWNvZGUzMihaaWdaYWdFbmNvZGUzMiggICAgMCkpKTsKKyAgRVhQRUNUX0VRKCAgICAxLCBaaWdaYWdEZWNvZGUzMihaaWdaYWdFbmNvZGUzMiggICAgMSkpKTsKKyAgRVhQRUNUX0VRKCAgIC0xLCBaaWdaYWdEZWNvZGUzMihaaWdaYWdFbmNvZGUzMiggICAtMSkpKTsKKyAgRVhQRUNUX0VRKDE0OTI3LCBaaWdaYWdEZWNvZGUzMihaaWdaYWdFbmNvZGUzMigxNDkyNykpKTsKKyAgRVhQRUNUX0VRKC0zNjEyLCBaaWdaYWdEZWNvZGUzMihaaWdaYWdFbmNvZGUzMigtMzYxMikpKTsKKworICBFWFBFQ1RfRVEoICAgIDAsIFppZ1phZ0RlY29kZTY0KFppZ1phZ0VuY29kZTY0KCAgICAwKSkpOworICBFWFBFQ1RfRVEoICAgIDEsIFppZ1phZ0RlY29kZTY0KFppZ1phZ0VuY29kZTY0KCAgICAxKSkpOworICBFWFBFQ1RfRVEoICAgLTEsIFppZ1phZ0RlY29kZTY0KFppZ1phZ0VuY29kZTY0KCAgIC0xKSkpOworICBFWFBFQ1RfRVEoMTQ5MjcsIFppZ1phZ0RlY29kZTY0KFppZ1phZ0VuY29kZTY0KDE0OTI3KSkpOworICBFWFBFQ1RfRVEoLTM2MTIsIFppZ1phZ0RlY29kZTY0KFppZ1phZ0VuY29kZTY0KC0zNjEyKSkpOworCisgIEVYUEVDVF9FUShMTCg4NTY5MTIzMDQ4MDE0MTYpLCBaaWdaYWdEZWNvZGU2NChaaWdaYWdFbmNvZGU2NCgKKyAgICAgICAgICAgIExMKDg1NjkxMjMwNDgwMTQxNikpKSk7CisgIEVYUEVDVF9FUShMTCgtNzUxMjM5MDU0Mzk1NzEyNTYpLCBaaWdaYWdEZWNvZGU2NChaaWdaYWdFbmNvZGU2NCgKKyAgICAgICAgICAgIExMKC03NTEyMzkwNTQzOTU3MTI1NikpKSk7Cit9CisKK1RFU1QoV2lyZUZvcm1hdFRlc3QsIFJlcGVhdGVkU2NhbGFyc0RpZmZlcmVudFRhZ1NpemVzKSB7CisgIC8vIEF0IG9uZSBwb2ludCBjaGVja3Mgd291bGQgdHJpZ2dlciB3aGVuIHBhcnNpbmcgcmVwZWF0ZWQgZml4ZWQgc2NhbGFyCisgIC8vIGZpZWxkcy4KKyAgcHJvdG9idWZfdW5pdHRlc3Q6OlRlc3RSZXBlYXRlZFNjYWxhckRpZmZlcmVudFRhZ1NpemVzIG1zZzEsIG1zZzI7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgMTAwOyArK2kpIHsKKyAgICBtc2cxLmFkZF9yZXBlYXRlZF9maXhlZDMyKGkpOworICAgIG1zZzEuYWRkX3JlcGVhdGVkX2ludDMyKGkpOworICAgIG1zZzEuYWRkX3JlcGVhdGVkX2ZpeGVkNjQoaSk7CisgICAgbXNnMS5hZGRfcmVwZWF0ZWRfaW50NjQoaSk7CisgICAgbXNnMS5hZGRfcmVwZWF0ZWRfZmxvYXQoaSk7CisgICAgbXNnMS5hZGRfcmVwZWF0ZWRfdWludDY0KGkpOworICB9CisKKyAgLy8gTWFrZSBzdXJlIHRoYXQgd2UgaGF2ZSBhIHZhcmlldHkgb2YgdGFnIHNpemVzLgorICBjb25zdCBnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBkZXNjID0gbXNnMS5HZXREZXNjcmlwdG9yKCk7CisgIGNvbnN0IGdvb2dsZTo6cHJvdG9idWY6OkZpZWxkRGVzY3JpcHRvciogZmllbGQ7CisgIGZpZWxkID0gZGVzYy0+RmluZEZpZWxkQnlOYW1lKCJyZXBlYXRlZF9maXhlZDMyIik7CisgIEFTU0VSVF9UUlVFKGZpZWxkICE9IE5VTEwpOworICBBU1NFUlRfRVEoMSwgV2lyZUZvcm1hdDo6VGFnU2l6ZShmaWVsZC0+bnVtYmVyKCksIGZpZWxkLT50eXBlKCkpKTsKKyAgZmllbGQgPSBkZXNjLT5GaW5kRmllbGRCeU5hbWUoInJlcGVhdGVkX2ludDMyIik7CisgIEFTU0VSVF9UUlVFKGZpZWxkICE9IE5VTEwpOworICBBU1NFUlRfRVEoMSwgV2lyZUZvcm1hdDo6VGFnU2l6ZShmaWVsZC0+bnVtYmVyKCksIGZpZWxkLT50eXBlKCkpKTsKKyAgZmllbGQgPSBkZXNjLT5GaW5kRmllbGRCeU5hbWUoInJlcGVhdGVkX2ZpeGVkNjQiKTsKKyAgQVNTRVJUX1RSVUUoZmllbGQgIT0gTlVMTCk7CisgIEFTU0VSVF9FUSgyLCBXaXJlRm9ybWF0OjpUYWdTaXplKGZpZWxkLT5udW1iZXIoKSwgZmllbGQtPnR5cGUoKSkpOworICBmaWVsZCA9IGRlc2MtPkZpbmRGaWVsZEJ5TmFtZSgicmVwZWF0ZWRfaW50NjQiKTsKKyAgQVNTRVJUX1RSVUUoZmllbGQgIT0gTlVMTCk7CisgIEFTU0VSVF9FUSgyLCBXaXJlRm9ybWF0OjpUYWdTaXplKGZpZWxkLT5udW1iZXIoKSwgZmllbGQtPnR5cGUoKSkpOworICBmaWVsZCA9IGRlc2MtPkZpbmRGaWVsZEJ5TmFtZSgicmVwZWF0ZWRfZmxvYXQiKTsKKyAgQVNTRVJUX1RSVUUoZmllbGQgIT0gTlVMTCk7CisgIEFTU0VSVF9FUSgzLCBXaXJlRm9ybWF0OjpUYWdTaXplKGZpZWxkLT5udW1iZXIoKSwgZmllbGQtPnR5cGUoKSkpOworICBmaWVsZCA9IGRlc2MtPkZpbmRGaWVsZEJ5TmFtZSgicmVwZWF0ZWRfdWludDY0Iik7CisgIEFTU0VSVF9UUlVFKGZpZWxkICE9IE5VTEwpOworICBBU1NFUlRfRVEoMywgV2lyZUZvcm1hdDo6VGFnU2l6ZShmaWVsZC0+bnVtYmVyKCksIGZpZWxkLT50eXBlKCkpKTsKKworICBFWFBFQ1RfVFJVRShtc2cyLlBhcnNlRnJvbVN0cmluZyhtc2cxLlNlcmlhbGl6ZUFzU3RyaW5nKCkpKTsKKyAgRVhQRUNUX0VRKG1zZzEuRGVidWdTdHJpbmcoKSwgbXNnMi5EZWJ1Z1N0cmluZygpKTsKK30KKworVEVTVChXaXJlRm9ybWF0VGVzdCwgQ29tcGF0aWJsZVR5cGVzKSB7CisgIGNvbnN0IGludDY0IGRhdGEgPSAweDEwMDAwMDAwMExMOworICB1bml0dGVzdDo6SW50NjRNZXNzYWdlIG1zZzE7CisgIG1zZzEuc2V0X2RhdGEoZGF0YSk7CisgIHN0cmluZyBzZXJpYWxpemVkOworICBtc2cxLlNlcmlhbGl6ZVRvU3RyaW5nKCZzZXJpYWxpemVkKTsKKworICAvLyBUZXN0IGludDY0IGlzIGNvbXBhdGlibGUgd2l0aCBib29sCisgIHVuaXR0ZXN0OjpCb29sTWVzc2FnZSBtc2cyOworICBBU1NFUlRfVFJVRShtc2cyLlBhcnNlRnJvbVN0cmluZyhzZXJpYWxpemVkKSk7CisgIEFTU0VSVF9FUShzdGF0aWNfY2FzdDxib29sPihkYXRhKSwgbXNnMi5kYXRhKCkpOworCisgIC8vIFRlc3QgaW50NjQgaXMgY29tcGF0aWJsZSB3aXRoIHVpbnQ2NAorICB1bml0dGVzdDo6VWludDY0TWVzc2FnZSBtc2czOworICBBU1NFUlRfVFJVRShtc2czLlBhcnNlRnJvbVN0cmluZyhzZXJpYWxpemVkKSk7CisgIEFTU0VSVF9FUShzdGF0aWNfY2FzdDx1aW50NjQ+KGRhdGEpLCBtc2czLmRhdGEoKSk7CisKKyAgLy8gVGVzdCBpbnQ2NCBpcyBjb21wYXRpYmxlIHdpdGggaW50MzIKKyAgdW5pdHRlc3Q6OkludDMyTWVzc2FnZSBtc2c0OworICBBU1NFUlRfVFJVRShtc2c0LlBhcnNlRnJvbVN0cmluZyhzZXJpYWxpemVkKSk7CisgIEFTU0VSVF9FUShzdGF0aWNfY2FzdDxpbnQzMj4oZGF0YSksIG1zZzQuZGF0YSgpKTsKKworICAvLyBUZXN0IGludDY0IGlzIGNvbXBhdGlibGUgd2l0aCB1aW50MzIKKyAgdW5pdHRlc3Q6OlVpbnQzMk1lc3NhZ2UgbXNnNTsKKyAgQVNTRVJUX1RSVUUobXNnNS5QYXJzZUZyb21TdHJpbmcoc2VyaWFsaXplZCkpOworICBBU1NFUlRfRVEoc3RhdGljX2Nhc3Q8dWludDMyPihkYXRhKSwgbXNnNS5kYXRhKCkpOworfQorCitjbGFzcyBQcm90bzNQcmltaXRpdmVSZXBlYXRlZFdpcmVGb3JtYXRUZXN0IDogcHVibGljIDo6dGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICBQcm90bzNQcmltaXRpdmVSZXBlYXRlZFdpcmVGb3JtYXRUZXN0KCkKKyAgICAgIDogcGFja2VkVGVzdEFsbFR5cGVzXygKKyAgICAgICAgICAgICJceEZBXHgwMVx4MDFceDAxIgorICAgICAgICAgICAgIlx4ODJceDAyXHgwMVx4MDEiCisgICAgICAgICAgICAiXHg4QVx4MDJceDAxXHgwMSIKKyAgICAgICAgICAgICJceDkyXHgwMlx4MDFceDAxIgorICAgICAgICAgICAgIlx4OUFceDAyXHgwMVx4MDIiCisgICAgICAgICAgICAiXHhBMlx4MDJceDAxXHgwMiIKKyAgICAgICAgICAgICJceEFBXHgwMlx4MDRceDAxXHgwMFx4MDBceDAwIgorICAgICAgICAgICAgIlx4QjJceDAyXHgwOFx4MDFceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwIgorICAgICAgICAgICAgIlx4QkFceDAyXHgwNFx4MDFceDAwXHgwMFx4MDAiCisgICAgICAgICAgICAiXHhDMlx4MDJceDA4XHgwMVx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDAiCisgICAgICAgICAgICAiXHhDQVx4MDJceDA0XHgwMFx4MDBceDgwXHgzZiIKKyAgICAgICAgICAgICJceEQyXHgwMlx4MDhceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceGYwXHgzZiIKKyAgICAgICAgICAgICJceERBXHgwMlx4MDFceDAxIgorICAgICAgICAgICAgIlx4OUFceDAzXHgwMVx4MDEiLAorICAgICAgICAgICAgODYpLAorICAgICAgICBwYWNrZWRUZXN0VW5wYWNrZWRUeXBlc18oCisgICAgICAgICAgICAiXHgwQVx4MDFceDAxIgorICAgICAgICAgICAgIlx4MTJceDAxXHgwMSIKKyAgICAgICAgICAgICJceDFBXHgwMVx4MDEiCisgICAgICAgICAgICAiXHgyMlx4MDFceDAxIgorICAgICAgICAgICAgIlx4MkFceDAxXHgwMiIKKyAgICAgICAgICAgICJceDMyXHgwMVx4MDIiCisgICAgICAgICAgICAiXHgzQVx4MDRceDAxXHgwMFx4MDBceDAwIgorICAgICAgICAgICAgIlx4NDJceDA4XHgwMVx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDAiCisgICAgICAgICAgICAiXHg0QVx4MDRceDAxXHgwMFx4MDBceDAwIgorICAgICAgICAgICAgIlx4NTJceDA4XHgwMVx4MDBceDAwXHgwMFx4MDBceDAwXHgwMFx4MDAiCisgICAgICAgICAgICAiXHg1QVx4MDRceDAwXHgwMFx4ODBceDNmIgorICAgICAgICAgICAgIlx4NjJceDA4XHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHhmMFx4M2YiCisgICAgICAgICAgICAiXHg2QVx4MDFceDAxIgorICAgICAgICAgICAgIlx4NzJceDAxXHgwMSIsCisgICAgICAgICAgICA3MiksCisgICAgICAgIHVucGFja2VkVGVzdEFsbFR5cGVzXygKKyAgICAgICAgICAgICJceEY4XHgwMVx4MDEiCisgICAgICAgICAgICAiXHg4MFx4MDJceDAxIgorICAgICAgICAgICAgIlx4ODhceDAyXHgwMSIKKyAgICAgICAgICAgICJceDkwXHgwMlx4MDEiCisgICAgICAgICAgICAiXHg5OFx4MDJceDAyIgorICAgICAgICAgICAgIlx4QTBceDAyXHgwMiIKKyAgICAgICAgICAgICJceEFEXHgwMlx4MDFceDAwXHgwMFx4MDAiCisgICAgICAgICAgICAiXHhCMVx4MDJceDAxXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMCIKKyAgICAgICAgICAgICJceEJEXHgwMlx4MDFceDAwXHgwMFx4MDAiCisgICAgICAgICAgICAiXHhDMVx4MDJceDAxXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMCIKKyAgICAgICAgICAgICJceENEXHgwMlx4MDBceDAwXHg4MFx4M2YiCisgICAgICAgICAgICAiXHhEMVx4MDJceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceGYwXHgzZiIKKyAgICAgICAgICAgICJceEQ4XHgwMlx4MDEiCisgICAgICAgICAgICAiXHg5OFx4MDNceDAxIiwKKyAgICAgICAgICAgIDcyKSwKKyAgICAgICAgdW5wYWNrZWRUZXN0VW5wYWNrZWRUeXBlc18oCisgICAgICAgICAgICAiXHgwOFx4MDEiCisgICAgICAgICAgICAiXHgxMFx4MDEiCisgICAgICAgICAgICAiXHgxOFx4MDEiCisgICAgICAgICAgICAiXHgyMFx4MDEiCisgICAgICAgICAgICAiXHgyOFx4MDIiCisgICAgICAgICAgICAiXHgzMFx4MDIiCisgICAgICAgICAgICAiXHgzRFx4MDFceDAwXHgwMFx4MDAiCisgICAgICAgICAgICAiXHg0MVx4MDFceDAwXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwIgorICAgICAgICAgICAgIlx4NERceDAxXHgwMFx4MDBceDAwIgorICAgICAgICAgICAgIlx4NTFceDAxXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHgwMCIKKyAgICAgICAgICAgICJceDVEXHgwMFx4MDBceDgwXHgzZiIKKyAgICAgICAgICAgICJceDYxXHgwMFx4MDBceDAwXHgwMFx4MDBceDAwXHhmMFx4M2YiCisgICAgICAgICAgICAiXHg2OFx4MDEiCisgICAgICAgICAgICAiXHg3MFx4MDEiLAorICAgICAgICAgICAgNTgpIHt9CisgIHRlbXBsYXRlIDxjbGFzcyBQcm90bz4KKyAgdm9pZCBTZXRQcm90bzNQcmltaXRpdmVSZXBlYXRlZEZpZWxkcyhQcm90byogbWVzc2FnZSkgeworICAgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9pbnQzMigxKTsKKyAgICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfaW50NjQoMSk7CisgICAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX3VpbnQzMigxKTsKKyAgICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfdWludDY0KDEpOworICAgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9zaW50MzIoMSk7CisgICAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX3NpbnQ2NCgxKTsKKyAgICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfZml4ZWQzMigxKTsKKyAgICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfZml4ZWQ2NCgxKTsKKyAgICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfc2ZpeGVkMzIoMSk7CisgICAgbWVzc2FnZS0+YWRkX3JlcGVhdGVkX3NmaXhlZDY0KDEpOworICAgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9mbG9hdCgxLjApOworICAgIG1lc3NhZ2UtPmFkZF9yZXBlYXRlZF9kb3VibGUoMS4wKTsKKyAgICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfYm9vbCh0cnVlKTsKKyAgICBtZXNzYWdlLT5hZGRfcmVwZWF0ZWRfbmVzdGVkX2VudW0oCisgICAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdDo6VGVzdEFsbFR5cGVzX05lc3RlZEVudW1fRk9PKTsKKyAgfQorCisgIHRlbXBsYXRlIDxjbGFzcyBQcm90bz4KKyAgdm9pZCBFeHBlY3RQcm90bzNQcmltaXRpdmVSZXBlYXRlZEZpZWxkc1NldChjb25zdCBQcm90byYgbWVzc2FnZSkgeworICAgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX2ludDMyKDApKTsKKyAgICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5yZXBlYXRlZF9pbnQ2NCgwKSk7CisgICAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UucmVwZWF0ZWRfdWludDMyKDApKTsKKyAgICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5yZXBlYXRlZF91aW50NjQoMCkpOworICAgIEVYUEVDVF9FUSgxLCBtZXNzYWdlLnJlcGVhdGVkX3NpbnQzMigwKSk7CisgICAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UucmVwZWF0ZWRfc2ludDY0KDApKTsKKyAgICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5yZXBlYXRlZF9maXhlZDMyKDApKTsKKyAgICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5yZXBlYXRlZF9maXhlZDY0KDApKTsKKyAgICBFWFBFQ1RfRVEoMSwgbWVzc2FnZS5yZXBlYXRlZF9zZml4ZWQzMigwKSk7CisgICAgRVhQRUNUX0VRKDEsIG1lc3NhZ2UucmVwZWF0ZWRfc2ZpeGVkNjQoMCkpOworICAgIEVYUEVDVF9FUSgxLjAsIG1lc3NhZ2UucmVwZWF0ZWRfZmxvYXQoMCkpOworICAgIEVYUEVDVF9FUSgxLjAsIG1lc3NhZ2UucmVwZWF0ZWRfZG91YmxlKDApKTsKKyAgICBFWFBFQ1RfRVEodHJ1ZSwgbWVzc2FnZS5yZXBlYXRlZF9ib29sKDApKTsKKyAgICBFWFBFQ1RfRVEocHJvdG8zX2FyZW5hX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXNfTmVzdGVkRW51bV9GT08sCisgICAgICAgICAgICAgIG1lc3NhZ2UucmVwZWF0ZWRfbmVzdGVkX2VudW0oMCkpOworICB9CisKKyAgdGVtcGxhdGUgPGNsYXNzIFByb3RvPgorICB2b2lkIFRlc3RTZXJpYWxpemF0aW9uKFByb3RvKiBtZXNzYWdlLCBjb25zdCBzdHJpbmcmIGV4cGVjdGVkKSB7CisgICAgU2V0UHJvdG8zUHJpbWl0aXZlUmVwZWF0ZWRGaWVsZHMobWVzc2FnZSk7CisKKyAgICBpbnQgc2l6ZSA9IG1lc3NhZ2UtPkJ5dGVTaXplKCk7CisKKyAgICAvLyBTZXJpYWxpemUgdXNpbmcgdGhlIGdlbmVyYXRlZCBjb2RlLgorICAgIHN0cmluZyBnZW5lcmF0ZWRfZGF0YTsKKyAgICB7CisgICAgICBpbzo6U3RyaW5nT3V0cHV0U3RyZWFtIHJhd19vdXRwdXQoJmdlbmVyYXRlZF9kYXRhKTsKKyAgICAgIGlvOjpDb2RlZE91dHB1dFN0cmVhbSBvdXRwdXQoJnJhd19vdXRwdXQpOworICAgICAgbWVzc2FnZS0+U2VyaWFsaXplV2l0aENhY2hlZFNpemVzKCZvdXRwdXQpOworICAgICAgQVNTRVJUX0ZBTFNFKG91dHB1dC5IYWRFcnJvcigpKTsKKyAgICB9CisgICAgRVhQRUNUX1RSVUUoZXhwZWN0ZWQgPT0gZ2VuZXJhdGVkX2RhdGEpOworCisgICAgLy8gU2VyaWFsaXplIHVzaW5nIHRoZSBkeW5hbWljIGNvZGUuCisgICAgc3RyaW5nIGR5bmFtaWNfZGF0YTsKKyAgICB7CisgICAgICBpbzo6U3RyaW5nT3V0cHV0U3RyZWFtIHJhd19vdXRwdXQoJmR5bmFtaWNfZGF0YSk7CisgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KCZyYXdfb3V0cHV0KTsKKyAgICAgIFdpcmVGb3JtYXQ6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygqbWVzc2FnZSwgc2l6ZSwgJm91dHB1dCk7CisgICAgICBBU1NFUlRfRkFMU0Uob3V0cHV0LkhhZEVycm9yKCkpOworICAgIH0KKyAgICBFWFBFQ1RfVFJVRShleHBlY3RlZCA9PSBkeW5hbWljX2RhdGEpOworICB9CisKKyAgdGVtcGxhdGUgPGNsYXNzIFByb3RvPgorICB2b2lkIFRlc3RQYXJzaW5nKFByb3RvKiBtZXNzYWdlLCBjb25zdCBzdHJpbmcmIGNvbXBhdGlibGVfZGF0YSkgeworICAgIG1lc3NhZ2UtPkNsZWFyKCk7CisgICAgbWVzc2FnZS0+UGFyc2VGcm9tU3RyaW5nKGNvbXBhdGlibGVfZGF0YSk7CisgICAgRXhwZWN0UHJvdG8zUHJpbWl0aXZlUmVwZWF0ZWRGaWVsZHNTZXQoKm1lc3NhZ2UpOworCisgICAgbWVzc2FnZS0+Q2xlYXIoKTsKKyAgICBpbzo6Q29kZWRJbnB1dFN0cmVhbSBpbnB1dCgKKyAgICAgICAgcmVpbnRlcnByZXRfY2FzdDxjb25zdCB1aW50OCo+KGNvbXBhdGlibGVfZGF0YS5kYXRhKCkpLAorICAgICAgICBjb21wYXRpYmxlX2RhdGEuc2l6ZSgpKTsKKyAgICBXaXJlRm9ybWF0OjpQYXJzZUFuZE1lcmdlUGFydGlhbCgmaW5wdXQsIG1lc3NhZ2UpOworICAgIEV4cGVjdFByb3RvM1ByaW1pdGl2ZVJlcGVhdGVkRmllbGRzU2V0KCptZXNzYWdlKTsKKyAgfQorCisgIGNvbnN0IHN0cmluZyBwYWNrZWRUZXN0QWxsVHlwZXNfOworICBjb25zdCBzdHJpbmcgcGFja2VkVGVzdFVucGFja2VkVHlwZXNfOworICBjb25zdCBzdHJpbmcgdW5wYWNrZWRUZXN0QWxsVHlwZXNfOworICBjb25zdCBzdHJpbmcgdW5wYWNrZWRUZXN0VW5wYWNrZWRUeXBlc187Cit9OworCitURVNUX0YoUHJvdG8zUHJpbWl0aXZlUmVwZWF0ZWRXaXJlRm9ybWF0VGVzdCwgUHJvdG8zUHJpbWl0aXZlUmVwZWF0ZWQpIHsKKyAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0OjpUZXN0QWxsVHlwZXMgcGFja2VkX21lc3NhZ2U7CisgIHByb3RvM19hcmVuYV91bml0dGVzdDo6VGVzdFVucGFja2VkVHlwZXMgdW5wYWNrZWRfbWVzc2FnZTsKKyAgVGVzdFNlcmlhbGl6YXRpb24oJnBhY2tlZF9tZXNzYWdlLCBwYWNrZWRUZXN0QWxsVHlwZXNfKTsKKyAgVGVzdFBhcnNpbmcoJnBhY2tlZF9tZXNzYWdlLCBwYWNrZWRUZXN0QWxsVHlwZXNfKTsKKyAgVGVzdFBhcnNpbmcoJnBhY2tlZF9tZXNzYWdlLCB1bnBhY2tlZFRlc3RBbGxUeXBlc18pOworICBUZXN0U2VyaWFsaXphdGlvbigmdW5wYWNrZWRfbWVzc2FnZSwgdW5wYWNrZWRUZXN0VW5wYWNrZWRUeXBlc18pOworICBUZXN0UGFyc2luZygmdW5wYWNrZWRfbWVzc2FnZSwgcGFja2VkVGVzdFVucGFja2VkVHlwZXNfKTsKKyAgVGVzdFBhcnNpbmcoJnVucGFja2VkX21lc3NhZ2UsIHVucGFja2VkVGVzdFVucGFja2VkVHlwZXNfKTsKK30KKworY2xhc3MgV2lyZUZvcm1hdEludmFsaWRJbnB1dFRlc3QgOiBwdWJsaWMgdGVzdGluZzo6VGVzdCB7CisgcHJvdGVjdGVkOgorICAvLyBNYWtlIGEgc2VyaWFsaXplZCBUZXN0QWxsVHlwZXMgaW4gd2hpY2ggdGhlIGZpZWxkIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlCisgIC8vIGNvbnRhaW5zIGV4YWN0bHkgdGhlIGdpdmVuIGJ5dGVzLCB3aGljaCBtYXkgYmUgaW52YWxpZC4KKyAgc3RyaW5nIE1ha2VJbnZhbGlkRW1iZWRkZWRNZXNzYWdlKGNvbnN0IGNoYXIqIGJ5dGVzLCBpbnQgc2l6ZSkgeworICAgIGNvbnN0IEZpZWxkRGVzY3JpcHRvciogZmllbGQgPQorICAgICAgdW5pdHRlc3Q6OlRlc3RBbGxUeXBlczo6ZGVzY3JpcHRvcigpLT5GaW5kRmllbGRCeU5hbWUoCisgICAgICAgICJvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSIpOworICAgIEdPT0dMRV9DSEVDSyhmaWVsZCAhPSBOVUxMKTsKKworICAgIHN0cmluZyByZXN1bHQ7CisKKyAgICB7CisgICAgICBpbzo6U3RyaW5nT3V0cHV0U3RyZWFtIHJhd19vdXRwdXQoJnJlc3VsdCk7CisgICAgICBpbzo6Q29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KCZyYXdfb3V0cHV0KTsKKworICAgICAgV2lyZUZvcm1hdExpdGU6OldyaXRlQnl0ZXMoZmllbGQtPm51bWJlcigpLCBzdHJpbmcoYnl0ZXMsIHNpemUpLCAmb3V0cHV0KTsKKyAgICB9CisKKyAgICByZXR1cm4gcmVzdWx0OworICB9CisKKyAgLy8gTWFrZSBhIHNlcmlhbGl6ZWQgVGVzdEFsbFR5cGVzIGluIHdoaWNoIHRoZSBmaWVsZCBvcHRpb25hbGdyb3VwCisgIC8vIGNvbnRhaW5zIGV4YWN0bHkgdGhlIGdpdmVuIGJ5dGVzIC0tIHdoaWNoIG1heSBiZSBpbnZhbGlkIC0tIGFuZAorICAvLyBwb3NzaWJseSBubyBlbmQgdGFnLgorICBzdHJpbmcgTWFrZUludmFsaWRHcm91cChjb25zdCBjaGFyKiBieXRlcywgaW50IHNpemUsIGJvb2wgaW5jbHVkZV9lbmRfdGFnKSB7CisgICAgY29uc3QgRmllbGREZXNjcmlwdG9yKiBmaWVsZCA9CisgICAgICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzOjpkZXNjcmlwdG9yKCktPkZpbmRGaWVsZEJ5TmFtZSgKKyAgICAgICAgIm9wdGlvbmFsZ3JvdXAiKTsKKyAgICBHT09HTEVfQ0hFQ0soZmllbGQgIT0gTlVMTCk7CisKKyAgICBzdHJpbmcgcmVzdWx0OworCisgICAgeworICAgICAgaW86OlN0cmluZ091dHB1dFN0cmVhbSByYXdfb3V0cHV0KCZyZXN1bHQpOworICAgICAgaW86OkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCgmcmF3X291dHB1dCk7CisKKyAgICAgIG91dHB1dC5Xcml0ZVZhcmludDMyKFdpcmVGb3JtYXQ6Ok1ha2VUYWcoZmllbGQpKTsKKyAgICAgIG91dHB1dC5Xcml0ZVN0cmluZyhzdHJpbmcoYnl0ZXMsIHNpemUpKTsKKyAgICAgIGlmIChpbmNsdWRlX2VuZF90YWcpIHsKKyAgICAgICAgb3V0cHV0LldyaXRlVmFyaW50MzIoV2lyZUZvcm1hdExpdGU6Ok1ha2VUYWcoCisgICAgICAgICAgZmllbGQtPm51bWJlcigpLCBXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRU5EX0dST1VQKSk7CisgICAgICB9CisgICAgfQorCisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorfTsKKworVEVTVF9GKFdpcmVGb3JtYXRJbnZhbGlkSW5wdXRUZXN0LCBJbnZhbGlkU3ViTWVzc2FnZSkgeworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisKKyAgLy8gQ29udHJvbCBjYXNlLgorICBFWFBFQ1RfVFJVRShtZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhNYWtlSW52YWxpZEVtYmVkZGVkTWVzc2FnZSgiIiwgMCkpKTsKKworICAvLyBUaGUgYnl0ZSBpcyBhIHZhbGlkIHZhcmludCwgYnV0IG5vdCBhIHZhbGlkIHRhZyAoemVybykuCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhNYWtlSW52YWxpZEVtYmVkZGVkTWVzc2FnZSgiXDAiLCAxKSkpOworCisgIC8vIFRoZSBieXRlIGlzIGEgbWFsZm9ybWVkIHZhcmludC4KKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKE1ha2VJbnZhbGlkRW1iZWRkZWRNZXNzYWdlKCJcMjAwIiwgMSkpKTsKKworICAvLyBUaGUgYnl0ZSBpcyBhbiBlbmRncm91cCB0YWcsIGJ1dCB3ZSBhcmVuJ3QgcGFyc2luZyBhIGdyb3VwLgorICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoTWFrZUludmFsaWRFbWJlZGRlZE1lc3NhZ2UoIlwwMTQiLCAxKSkpOworCisgIC8vIFRoZSBieXRlIGlzIGEgdmFsaWQgdmFyaW50IGJ1dCBub3QgYSB2YWxpZCB0YWcgKGJhZCB3aXJlIHR5cGUpLgorICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoTWFrZUludmFsaWRFbWJlZGRlZE1lc3NhZ2UoIlwwMTciLCAxKSkpOworfQorCitURVNUX0YoV2lyZUZvcm1hdEludmFsaWRJbnB1dFRlc3QsIEludmFsaWRHcm91cCkgeworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisKKyAgLy8gQ29udHJvbCBjYXNlLgorICBFWFBFQ1RfVFJVRShtZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhNYWtlSW52YWxpZEdyb3VwKCIiLCAwLCB0cnVlKSkpOworCisgIC8vIE1pc3NpbmcgZW5kIHRhZy4gIEdyb3VwcyBjYW5ub3QgZW5kIGF0IEVPRi4KKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKE1ha2VJbnZhbGlkR3JvdXAoIiIsIDAsIGZhbHNlKSkpOworCisgIC8vIFRoZSBieXRlIGlzIGEgdmFsaWQgdmFyaW50LCBidXQgbm90IGEgdmFsaWQgdGFnICh6ZXJvKS4KKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKE1ha2VJbnZhbGlkR3JvdXAoIlwwIiwgMSwgZmFsc2UpKSk7CisKKyAgLy8gVGhlIGJ5dGUgaXMgYSBtYWxmb3JtZWQgdmFyaW50LgorICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoTWFrZUludmFsaWRHcm91cCgiXDIwMCIsIDEsIGZhbHNlKSkpOworCisgIC8vIFRoZSBieXRlIGlzIGFuIGVuZGdyb3VwIHRhZywgYnV0IG5vdCB0aGUgcmlnaHQgb25lIGZvciB0aGlzIGdyb3VwLgorICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoTWFrZUludmFsaWRHcm91cCgiXDAxNCIsIDEsIGZhbHNlKSkpOworCisgIC8vIFRoZSBieXRlIGlzIGEgdmFsaWQgdmFyaW50IGJ1dCBub3QgYSB2YWxpZCB0YWcgKGJhZCB3aXJlIHR5cGUpLgorICBFWFBFQ1RfRkFMU0UobWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoTWFrZUludmFsaWRHcm91cCgiXDAxNyIsIDEsIHRydWUpKSk7Cit9CisKK1RFU1RfRihXaXJlRm9ybWF0SW52YWxpZElucHV0VGVzdCwgSW52YWxpZFVua25vd25Hcm91cCkgeworICAvLyBVc2UgVGVzdEVtcHR5TWVzc2FnZSBzbyB0aGF0IHRoZSBncm91cCBtYWRlIGJ5IE1ha2VJbnZhbGlkR3JvdXAgd2lsbCBub3QKKyAgLy8gYmUgYSBrbm93biB0YWcgbnVtYmVyLgorICB1bml0dGVzdDo6VGVzdEVtcHR5TWVzc2FnZSBtZXNzYWdlOworCisgIC8vIENvbnRyb2wgY2FzZS4KKyAgRVhQRUNUX1RSVUUobWVzc2FnZS5QYXJzZUZyb21TdHJpbmcoTWFrZUludmFsaWRHcm91cCgiIiwgMCwgdHJ1ZSkpKTsKKworICAvLyBNaXNzaW5nIGVuZCB0YWcuICBHcm91cHMgY2Fubm90IGVuZCBhdCBFT0YuCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhNYWtlSW52YWxpZEdyb3VwKCIiLCAwLCBmYWxzZSkpKTsKKworICAvLyBUaGUgYnl0ZSBpcyBhIHZhbGlkIHZhcmludCwgYnV0IG5vdCBhIHZhbGlkIHRhZyAoemVybykuCisgIEVYUEVDVF9GQUxTRShtZXNzYWdlLlBhcnNlRnJvbVN0cmluZyhNYWtlSW52YWxpZEdyb3VwKCJcMCIsIDEsIGZhbHNlKSkpOworCisgIC8vIFRoZSBieXRlIGlzIGEgbWFsZm9ybWVkIHZhcmludC4KKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKE1ha2VJbnZhbGlkR3JvdXAoIlwyMDAiLCAxLCBmYWxzZSkpKTsKKworICAvLyBUaGUgYnl0ZSBpcyBhbiBlbmRncm91cCB0YWcsIGJ1dCBub3QgdGhlIHJpZ2h0IG9uZSBmb3IgdGhpcyBncm91cC4KKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKE1ha2VJbnZhbGlkR3JvdXAoIlwwMTQiLCAxLCBmYWxzZSkpKTsKKworICAvLyBUaGUgYnl0ZSBpcyBhIHZhbGlkIHZhcmludCBidXQgbm90IGEgdmFsaWQgdGFnIChiYWQgd2lyZSB0eXBlKS4KKyAgRVhQRUNUX0ZBTFNFKG1lc3NhZ2UuUGFyc2VGcm9tU3RyaW5nKE1ha2VJbnZhbGlkR3JvdXAoIlwwMTciLCAxLCB0cnVlKSkpOworfQorCitURVNUX0YoV2lyZUZvcm1hdEludmFsaWRJbnB1dFRlc3QsIEludmFsaWRTdHJpbmdJblVua25vd25Hcm91cCkgeworICAvLyBUZXN0IGEgYnVnIGZpeDogIFNraXBNZXNzYWdlIHNob3VsZCBmYWlsIGlmIHRoZSBtZXNzYWdlIGNvbnRhaW5zIGEgc3RyaW5nCisgIC8vIHdob3NlIGxlbmd0aCB3b3VsZCBleHRlbmQgYmV5b25kIHRoZSBtZXNzYWdlIGVuZC4KKworICB1bml0dGVzdDo6VGVzdEFsbFR5cGVzIG1lc3NhZ2U7CisgIG1lc3NhZ2Uuc2V0X29wdGlvbmFsX3N0cmluZygiZm9vIGZvbyBmb28gZm9vIik7CisgIHN0cmluZyBkYXRhOworICBtZXNzYWdlLlNlcmlhbGl6ZVRvU3RyaW5nKCZkYXRhKTsKKworICAvLyBDaG9wIHNvbWUgYnl0ZXMgb2ZmIHRoZSBlbmQuCisgIGRhdGEucmVzaXplKGRhdGEuc2l6ZSgpIC0gNCk7CisKKyAgLy8gVHJ5IHRvIHNraXAgaXQuICBOb3RlIHRoYXQgdGhlIGJ1ZyB3YXMgb25seSBwcmVzZW50IHdoZW4gcGFyc2luZyB0byBhbgorICAvLyBVbmtub3duRmllbGRTZXQuCisgIGlvOjpBcnJheUlucHV0U3RyZWFtIHJhd19pbnB1dChkYXRhLmRhdGEoKSwgZGF0YS5zaXplKCkpOworICBpbzo6Q29kZWRJbnB1dFN0cmVhbSBjb2RlZF9pbnB1dCgmcmF3X2lucHV0KTsKKyAgVW5rbm93bkZpZWxkU2V0IHVua25vd25fZmllbGRzOworICBFWFBFQ1RfRkFMU0UoV2lyZUZvcm1hdDo6U2tpcE1lc3NhZ2UoJmNvZGVkX2lucHV0LCAmdW5rbm93bl9maWVsZHMpKTsKK30KKworLy8gVGVzdCBkaWZmZXJlbmNlcyBiZXR3ZWVuIHN0cmluZyBhbmQgYnl0ZXMuCisvLyBWYWx1ZSBvZiBhIHN0cmluZyB0eXBlIG11c3QgYmUgdmFsaWQgVVRGLTggc3RyaW5nLiAgV2hlbiBVVEYtOAorLy8gdmFsaWRhdGlvbiBpcyBlbmFibGVkIChHT09HTEVfUFJPVE9CVUZfVVRGOF9WQUxJREFUSU9OX0VOQUJMRUQpOgorLy8gV3JpdGVJbnZhbGlkVVRGOFN0cmluZzogIHNlZSBlcnJvciBtZXNzYWdlLgorLy8gUmVhZEludmFsaWRVVEY4U3RyaW5nOiAgc2VlIGVycm9yIG1lc3NhZ2UuCisvLyBXcml0ZVZhbGlkVVRGOFN0cmluZzogZmluZS4KKy8vIFJlYWRWYWxpZFVURjhTdHJpbmc6ICBmaW5lLgorLy8gV3JpdGVBbnlCeXRlczogZmluZS4KKy8vIFJlYWRBbnlCeXRlczogZmluZS4KK2NvbnN0IGNoYXIgKiBrSW52YWxpZFVURjhTdHJpbmcgPSAiSW52YWxpZCBVVEYtODogXHhBMFx4QjBceEMwXHhEMCI7CisvLyBUaGlzIHVzZWQgdG8gYmUgIlZhbGlkIFVURi04OiBceDAxXHgwMlx1OEMzN1x1NkI0QyIsIGJ1dCBNU1ZDIHNlZW1zIHRvCisvLyBpbnRlcnByZXQgXHUgZGlmZmVyZW50bHkgZnJvbSBHQ0MuCitjb25zdCBjaGFyICoga1ZhbGlkVVRGOFN0cmluZyA9ICJWYWxpZCBVVEYtODogXHgwMVx4MDJcMzUwXDI2MFwyNjdcMzQ2XDI1NVwyMTQiOworCit0ZW1wbGF0ZTx0eXBlbmFtZSBUPgorYm9vbCBXcml0ZU1lc3NhZ2UoY29uc3QgY2hhciAqdmFsdWUsIFQgKm1lc3NhZ2UsIHN0cmluZyAqd2lyZV9idWZmZXIpIHsKKyAgbWVzc2FnZS0+c2V0X2RhdGEodmFsdWUpOworICB3aXJlX2J1ZmZlci0+Y2xlYXIoKTsKKyAgbWVzc2FnZS0+QXBwZW5kVG9TdHJpbmcod2lyZV9idWZmZXIpOworICByZXR1cm4gKHdpcmVfYnVmZmVyLT5zaXplKCkgPiAwKTsKK30KKwordGVtcGxhdGU8dHlwZW5hbWUgVD4KK2Jvb2wgUmVhZE1lc3NhZ2UoY29uc3Qgc3RyaW5nICZ3aXJlX2J1ZmZlciwgVCAqbWVzc2FnZSkgeworICByZXR1cm4gbWVzc2FnZS0+UGFyc2VGcm9tQXJyYXkod2lyZV9idWZmZXIuZGF0YSgpLCB3aXJlX2J1ZmZlci5zaXplKCkpOworfQorCitib29sIFN0YXJ0c1dpdGgoY29uc3Qgc3RyaW5nJiBzLCBjb25zdCBzdHJpbmcmIHByZWZpeCkgeworICByZXR1cm4gcy5zdWJzdHIoMCwgcHJlZml4Lmxlbmd0aCgpKSA9PSBwcmVmaXg7Cit9CisKK2NsYXNzIFV0ZjhWYWxpZGF0aW9uVGVzdCA6IHB1YmxpYyA6OnRlc3Rpbmc6OlRlc3QgeworIHByb3RlY3RlZDoKKyAgVXRmOFZhbGlkYXRpb25UZXN0KCkge30KKyAgdmlydHVhbCB+VXRmOFZhbGlkYXRpb25UZXN0KCkge30KKyAgdmlydHVhbCB2b2lkIFNldFVwKCkgeworICB9CisKK307CisKK1RFU1RfRihVdGY4VmFsaWRhdGlvblRlc3QsIFdyaXRlSW52YWxpZFVURjhTdHJpbmcpIHsKKyAgc3RyaW5nIHdpcmVfYnVmZmVyOworICBwcm90b2J1Zl91bml0dGVzdDo6T25lU3RyaW5nIGlucHV0OworICB2ZWN0b3I8c3RyaW5nPiBlcnJvcnM7CisgIHsKKyAgICBTY29wZWRNZW1vcnlMb2cgbG9nOworICAgIFdyaXRlTWVzc2FnZShrSW52YWxpZFVURjhTdHJpbmcsICZpbnB1dCwgJndpcmVfYnVmZmVyKTsKKyAgICBlcnJvcnMgPSBsb2cuR2V0TWVzc2FnZXMoRVJST1IpOworICB9CisjaWZkZWYgR09PR0xFX1BST1RPQlVGX1VURjhfVkFMSURBVElPTl9FTkFCTEVECisgIEFTU0VSVF9FUSgxLCBlcnJvcnMuc2l6ZSgpKTsKKyAgRVhQRUNUX1RSVUUoU3RhcnRzV2l0aChlcnJvcnNbMF0sCisgICAgICAgICAgICAgICAgICAgICAgICAgIlN0cmluZyBmaWVsZCAncHJvdG9idWZfdW5pdHRlc3QuT25lU3RyaW5nLmRhdGEnICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAiY29udGFpbnMgaW52YWxpZCBVVEYtOCBkYXRhIHdoZW4gIgorICAgICAgICAgICAgICAgICAgICAgICAgICJzZXJpYWxpemluZyBhIHByb3RvY29sIGJ1ZmZlci4gVXNlIHRoZSAiCisgICAgICAgICAgICAgICAgICAgICAgICAgIidieXRlcycgdHlwZSBpZiB5b3UgaW50ZW5kIHRvIHNlbmQgcmF3IGJ5dGVzLiIpKTsKKyNlbHNlCisgIEFTU0VSVF9FUSgwLCBlcnJvcnMuc2l6ZSgpKTsKKyNlbmRpZiAgLy8gR09PR0xFX1BST1RPQlVGX1VURjhfVkFMSURBVElPTl9FTkFCTEVECit9CisKKworVEVTVF9GKFV0ZjhWYWxpZGF0aW9uVGVzdCwgUmVhZEludmFsaWRVVEY4U3RyaW5nKSB7CisgIHN0cmluZyB3aXJlX2J1ZmZlcjsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6Ok9uZVN0cmluZyBpbnB1dDsKKyAgV3JpdGVNZXNzYWdlKGtJbnZhbGlkVVRGOFN0cmluZywgJmlucHV0LCAmd2lyZV9idWZmZXIpOworICBwcm90b2J1Zl91bml0dGVzdDo6T25lU3RyaW5nIG91dHB1dDsKKyAgdmVjdG9yPHN0cmluZz4gZXJyb3JzOworICB7CisgICAgU2NvcGVkTWVtb3J5TG9nIGxvZzsKKyAgICBSZWFkTWVzc2FnZSh3aXJlX2J1ZmZlciwgJm91dHB1dCk7CisgICAgZXJyb3JzID0gbG9nLkdldE1lc3NhZ2VzKEVSUk9SKTsKKyAgfQorI2lmZGVmIEdPT0dMRV9QUk9UT0JVRl9VVEY4X1ZBTElEQVRJT05fRU5BQkxFRAorICBBU1NFUlRfRVEoMSwgZXJyb3JzLnNpemUoKSk7CisgIEVYUEVDVF9UUlVFKFN0YXJ0c1dpdGgoZXJyb3JzWzBdLAorICAgICAgICAgICAgICAgICAgICAgICAgICJTdHJpbmcgZmllbGQgJ3Byb3RvYnVmX3VuaXR0ZXN0Lk9uZVN0cmluZy5kYXRhJyAiCisgICAgICAgICAgICAgICAgICAgICAgICAgImNvbnRhaW5zIGludmFsaWQgVVRGLTggZGF0YSB3aGVuICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAicGFyc2luZyBhIHByb3RvY29sIGJ1ZmZlci4gVXNlIHRoZSAiCisgICAgICAgICAgICAgICAgICAgICAgICAgIidieXRlcycgdHlwZSBpZiB5b3UgaW50ZW5kIHRvIHNlbmQgcmF3IGJ5dGVzLiIpKTsKKworI2Vsc2UKKyAgQVNTRVJUX0VRKDAsIGVycm9ycy5zaXplKCkpOworI2VuZGlmICAvLyBHT09HTEVfUFJPVE9CVUZfVVRGOF9WQUxJREFUSU9OX0VOQUJMRUQKK30KKworCitURVNUX0YoVXRmOFZhbGlkYXRpb25UZXN0LCBXcml0ZVZhbGlkVVRGOFN0cmluZykgeworICBzdHJpbmcgd2lyZV9idWZmZXI7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpPbmVTdHJpbmcgaW5wdXQ7CisgIHZlY3RvcjxzdHJpbmc+IGVycm9yczsKKyAgeworICAgIFNjb3BlZE1lbW9yeUxvZyBsb2c7CisgICAgV3JpdGVNZXNzYWdlKGtWYWxpZFVURjhTdHJpbmcsICZpbnB1dCwgJndpcmVfYnVmZmVyKTsKKyAgICBlcnJvcnMgPSBsb2cuR2V0TWVzc2FnZXMoRVJST1IpOworICB9CisgIEFTU0VSVF9FUSgwLCBlcnJvcnMuc2l6ZSgpKTsKK30KKworVEVTVF9GKFV0ZjhWYWxpZGF0aW9uVGVzdCwgUmVhZFZhbGlkVVRGOFN0cmluZykgeworICBzdHJpbmcgd2lyZV9idWZmZXI7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpPbmVTdHJpbmcgaW5wdXQ7CisgIFdyaXRlTWVzc2FnZShrVmFsaWRVVEY4U3RyaW5nLCAmaW5wdXQsICZ3aXJlX2J1ZmZlcik7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpPbmVTdHJpbmcgb3V0cHV0OworICB2ZWN0b3I8c3RyaW5nPiBlcnJvcnM7CisgIHsKKyAgICBTY29wZWRNZW1vcnlMb2cgbG9nOworICAgIFJlYWRNZXNzYWdlKHdpcmVfYnVmZmVyLCAmb3V0cHV0KTsKKyAgICBlcnJvcnMgPSBsb2cuR2V0TWVzc2FnZXMoRVJST1IpOworICB9CisgIEFTU0VSVF9FUSgwLCBlcnJvcnMuc2l6ZSgpKTsKKyAgRVhQRUNUX0VRKGlucHV0LmRhdGEoKSwgb3V0cHV0LmRhdGEoKSk7Cit9CisKKy8vIEJ5dGVzOiBhbnl0aGluZyBjYW4gcGFzcyBhcyBieXRlcywgdXNlIGludmFsaWQgVVRGLTggc3RyaW5nIHRvIHRlc3QKK1RFU1RfRihVdGY4VmFsaWRhdGlvblRlc3QsIFdyaXRlQXJiaXRyYXJ5Qnl0ZXMpIHsKKyAgc3RyaW5nIHdpcmVfYnVmZmVyOworICBwcm90b2J1Zl91bml0dGVzdDo6T25lQnl0ZXMgaW5wdXQ7CisgIHZlY3RvcjxzdHJpbmc+IGVycm9yczsKKyAgeworICAgIFNjb3BlZE1lbW9yeUxvZyBsb2c7CisgICAgV3JpdGVNZXNzYWdlKGtJbnZhbGlkVVRGOFN0cmluZywgJmlucHV0LCAmd2lyZV9idWZmZXIpOworICAgIGVycm9ycyA9IGxvZy5HZXRNZXNzYWdlcyhFUlJPUik7CisgIH0KKyAgQVNTRVJUX0VRKDAsIGVycm9ycy5zaXplKCkpOworfQorCitURVNUX0YoVXRmOFZhbGlkYXRpb25UZXN0LCBSZWFkQXJiaXRyYXJ5Qnl0ZXMpIHsKKyAgc3RyaW5nIHdpcmVfYnVmZmVyOworICBwcm90b2J1Zl91bml0dGVzdDo6T25lQnl0ZXMgaW5wdXQ7CisgIFdyaXRlTWVzc2FnZShrSW52YWxpZFVURjhTdHJpbmcsICZpbnB1dCwgJndpcmVfYnVmZmVyKTsKKyAgcHJvdG9idWZfdW5pdHRlc3Q6Ok9uZUJ5dGVzIG91dHB1dDsKKyAgdmVjdG9yPHN0cmluZz4gZXJyb3JzOworICB7CisgICAgU2NvcGVkTWVtb3J5TG9nIGxvZzsKKyAgICBSZWFkTWVzc2FnZSh3aXJlX2J1ZmZlciwgJm91dHB1dCk7CisgICAgZXJyb3JzID0gbG9nLkdldE1lc3NhZ2VzKEVSUk9SKTsKKyAgfQorICBBU1NFUlRfRVEoMCwgZXJyb3JzLnNpemUoKSk7CisgIEVYUEVDVF9FUShpbnB1dC5kYXRhKCksIG91dHB1dC5kYXRhKCkpOworfQorCitURVNUX0YoVXRmOFZhbGlkYXRpb25UZXN0LCBQYXJzZVJlcGVhdGVkU3RyaW5nKSB7CisgIHByb3RvYnVmX3VuaXR0ZXN0OjpNb3JlQnl0ZXMgaW5wdXQ7CisgIGlucHV0LmFkZF9kYXRhKGtWYWxpZFVURjhTdHJpbmcpOworICBpbnB1dC5hZGRfZGF0YShrSW52YWxpZFVURjhTdHJpbmcpOworICBpbnB1dC5hZGRfZGF0YShrSW52YWxpZFVURjhTdHJpbmcpOworICBzdHJpbmcgd2lyZV9idWZmZXIgPSBpbnB1dC5TZXJpYWxpemVBc1N0cmluZygpOworCisgIHByb3RvYnVmX3VuaXR0ZXN0OjpNb3JlU3RyaW5nIG91dHB1dDsKKyAgdmVjdG9yPHN0cmluZz4gZXJyb3JzOworICB7CisgICAgU2NvcGVkTWVtb3J5TG9nIGxvZzsKKyAgICBSZWFkTWVzc2FnZSh3aXJlX2J1ZmZlciwgJm91dHB1dCk7CisgICAgZXJyb3JzID0gbG9nLkdldE1lc3NhZ2VzKEVSUk9SKTsKKyAgfQorI2lmZGVmIEdPT0dMRV9QUk9UT0JVRl9VVEY4X1ZBTElEQVRJT05fRU5BQkxFRAorICBBU1NFUlRfRVEoMiwgZXJyb3JzLnNpemUoKSk7CisjZWxzZQorICBBU1NFUlRfRVEoMCwgZXJyb3JzLnNpemUoKSk7CisjZW5kaWYgIC8vIEdPT0dMRV9QUk9UT0JVRl9VVEY4X1ZBTElEQVRJT05fRU5BQkxFRAorICBFWFBFQ1RfRVEod2lyZV9idWZmZXIsIG91dHB1dC5TZXJpYWxpemVBc1N0cmluZygpKTsKK30KKworLy8gVGVzdCB0aGUgb2xkIFZlcmlmeVVURjhTdHJpbmcoKSBmdW5jdGlvbiwgd2hpY2ggbWF5IHN0aWxsIGJlIGNhbGxlZCBieSBvbGQKKy8vIGdlbmVyYXRlZCBjb2RlLgorVEVTVF9GKFV0ZjhWYWxpZGF0aW9uVGVzdCwgT2xkVmVyaWZ5VVRGOFN0cmluZykgeworICBzdHJpbmcgZGF0YShrSW52YWxpZFVURjhTdHJpbmcpOworCisgIHZlY3RvcjxzdHJpbmc+IGVycm9yczsKKyAgeworICAgIFNjb3BlZE1lbW9yeUxvZyBsb2c7CisgICAgV2lyZUZvcm1hdDo6VmVyaWZ5VVRGOFN0cmluZyhkYXRhLmRhdGEoKSwgZGF0YS5zaXplKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXaXJlRm9ybWF0OjpTRVJJQUxJWkUpOworICAgIGVycm9ycyA9IGxvZy5HZXRNZXNzYWdlcyhFUlJPUik7CisgIH0KKyNpZmRlZiBHT09HTEVfUFJPVE9CVUZfVVRGOF9WQUxJREFUSU9OX0VOQUJMRUQKKyAgQVNTRVJUX0VRKDEsIGVycm9ycy5zaXplKCkpOworICBFWFBFQ1RfVFJVRShTdGFydHNXaXRoKGVycm9yc1swXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAiU3RyaW5nIGZpZWxkIGNvbnRhaW5zIGludmFsaWQgVVRGLTggZGF0YSB3aGVuICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAic2VyaWFsaXppbmcgYSBwcm90b2NvbCBidWZmZXIuIFVzZSB0aGUgIgorICAgICAgICAgICAgICAgICAgICAgICAgICInYnl0ZXMnIHR5cGUgaWYgeW91IGludGVuZCB0byBzZW5kIHJhdyBieXRlcy4iKSk7CisjZWxzZQorICBBU1NFUlRfRVEoMCwgZXJyb3JzLnNpemUoKSk7CisjZW5kaWYKK30KKworCit9ICAvLyBuYW1lc3BhY2UKK30gIC8vIG5hbWVzcGFjZSBpbnRlcm5hbAorfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCmRpZmYgLS1naXQgYS9zcmMvZ29vZ2xlL3Byb3RvYnVmL3dyYXBwZXJzLnBiLmNjIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi93cmFwcGVycy5wYi5jYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMTJkZDIxCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi93cmFwcGVycy5wYi5jYwpAQCAtMCwwICsxLDI2OTUgQEAKKy8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCisvLyBzb3VyY2U6IGdvb2dsZS9wcm90b2J1Zi93cmFwcGVycy5wcm90bworCisjZGVmaW5lIElOVEVSTkFMX1NVUFBSRVNTX1BST1RPQlVGX0ZJRUxEX0RFUFJFQ0FUSU9OCisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dyYXBwZXJzLnBiLmg+CisKKyNpbmNsdWRlIDxhbGdvcml0aG0+CisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvY29tbW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3N0dWJzL3BvcnQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvc3R1YnMvb25jZS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW0uaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZV9pbmwuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9nZW5lcmF0ZWRfbWVzc2FnZV9yZWZsZWN0aW9uLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3JlZmxlY3Rpb25fb3BzLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0Lmg+CisvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW5jbHVkZXMpCisKK25hbWVzcGFjZSBnb29nbGUgeworbmFtZXNwYWNlIHByb3RvYnVmIHsKKworbmFtZXNwYWNlIHsKKworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBEb3VibGVWYWx1ZV9kZXNjcmlwdG9yXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbioKKyAgRG91YmxlVmFsdWVfcmVmbGVjdGlvbl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBGbG9hdFZhbHVlX2Rlc2NyaXB0b3JfID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKgorICBGbG9hdFZhbHVlX3JlZmxlY3Rpb25fID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogSW50NjRWYWx1ZV9kZXNjcmlwdG9yXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbioKKyAgSW50NjRWYWx1ZV9yZWZsZWN0aW9uXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIFVJbnQ2NFZhbHVlX2Rlc2NyaXB0b3JfID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKgorICBVSW50NjRWYWx1ZV9yZWZsZWN0aW9uXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIEludDMyVmFsdWVfZGVzY3JpcHRvcl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24qCisgIEludDMyVmFsdWVfcmVmbGVjdGlvbl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBVSW50MzJWYWx1ZV9kZXNjcmlwdG9yXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbioKKyAgVUludDMyVmFsdWVfcmVmbGVjdGlvbl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBCb29sVmFsdWVfZGVzY3JpcHRvcl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24qCisgIEJvb2xWYWx1ZV9yZWZsZWN0aW9uXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIFN0cmluZ1ZhbHVlX2Rlc2NyaXB0b3JfID0gTlVMTDsKK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKgorICBTdHJpbmdWYWx1ZV9yZWZsZWN0aW9uXyA9IE5VTEw7Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIEJ5dGVzVmFsdWVfZGVzY3JpcHRvcl8gPSBOVUxMOworY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24qCisgIEJ5dGVzVmFsdWVfcmVmbGVjdGlvbl8gPSBOVUxMOworCit9ICAvLyBuYW1lc3BhY2UKKworCit2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZ3cmFwcGVyc18yZXByb3RvKCkgeworICBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmd3JhcHBlcnNfMmVwcm90bygpOworICBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkZpbGVEZXNjcmlwdG9yKiBmaWxlID0KKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3JQb29sOjpnZW5lcmF0ZWRfcG9vbCgpLT5GaW5kRmlsZUJ5TmFtZSgKKyAgICAgICJnb29nbGUvcHJvdG9idWYvd3JhcHBlcnMucHJvdG8iKTsKKyAgR09PR0xFX0NIRUNLKGZpbGUgIT0gTlVMTCk7CisgIERvdWJsZVZhbHVlX2Rlc2NyaXB0b3JfID0gZmlsZS0+bWVzc2FnZV90eXBlKDApOworICBzdGF0aWMgY29uc3QgaW50IERvdWJsZVZhbHVlX29mZnNldHNfWzFdID0geworICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRG91YmxlVmFsdWUsIHZhbHVlXyksCisgIH07CisgIERvdWJsZVZhbHVlX3JlZmxlY3Rpb25fID0KKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6TmV3R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24oCisgICAgICBEb3VibGVWYWx1ZV9kZXNjcmlwdG9yXywKKyAgICAgIERvdWJsZVZhbHVlOjpkZWZhdWx0X2luc3RhbmNlXywKKyAgICAgIERvdWJsZVZhbHVlX29mZnNldHNfLAorICAgICAgLTEsCisgICAgICAtMSwKKyAgICAgIC0xLAorICAgICAgc2l6ZW9mKERvdWJsZVZhbHVlKSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoRG91YmxlVmFsdWUsIF9pbnRlcm5hbF9tZXRhZGF0YV8pLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChEb3VibGVWYWx1ZSwgX2lzX2RlZmF1bHRfaW5zdGFuY2VfKSk7CisgIEZsb2F0VmFsdWVfZGVzY3JpcHRvcl8gPSBmaWxlLT5tZXNzYWdlX3R5cGUoMSk7CisgIHN0YXRpYyBjb25zdCBpbnQgRmxvYXRWYWx1ZV9vZmZzZXRzX1sxXSA9IHsKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZsb2F0VmFsdWUsIHZhbHVlXyksCisgIH07CisgIEZsb2F0VmFsdWVfcmVmbGVjdGlvbl8gPQorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uOjpOZXdHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbigKKyAgICAgIEZsb2F0VmFsdWVfZGVzY3JpcHRvcl8sCisgICAgICBGbG9hdFZhbHVlOjpkZWZhdWx0X2luc3RhbmNlXywKKyAgICAgIEZsb2F0VmFsdWVfb2Zmc2V0c18sCisgICAgICAtMSwKKyAgICAgIC0xLAorICAgICAgLTEsCisgICAgICBzaXplb2YoRmxvYXRWYWx1ZSksCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEZsb2F0VmFsdWUsIF9pbnRlcm5hbF9tZXRhZGF0YV8pLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChGbG9hdFZhbHVlLCBfaXNfZGVmYXVsdF9pbnN0YW5jZV8pKTsKKyAgSW50NjRWYWx1ZV9kZXNjcmlwdG9yXyA9IGZpbGUtPm1lc3NhZ2VfdHlwZSgyKTsKKyAgc3RhdGljIGNvbnN0IGludCBJbnQ2NFZhbHVlX29mZnNldHNfWzFdID0geworICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoSW50NjRWYWx1ZSwgdmFsdWVfKSwKKyAgfTsKKyAgSW50NjRWYWx1ZV9yZWZsZWN0aW9uXyA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok5ld0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKAorICAgICAgSW50NjRWYWx1ZV9kZXNjcmlwdG9yXywKKyAgICAgIEludDY0VmFsdWU6OmRlZmF1bHRfaW5zdGFuY2VfLAorICAgICAgSW50NjRWYWx1ZV9vZmZzZXRzXywKKyAgICAgIC0xLAorICAgICAgLTEsCisgICAgICAtMSwKKyAgICAgIHNpemVvZihJbnQ2NFZhbHVlKSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoSW50NjRWYWx1ZSwgX2ludGVybmFsX21ldGFkYXRhXyksCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKEludDY0VmFsdWUsIF9pc19kZWZhdWx0X2luc3RhbmNlXykpOworICBVSW50NjRWYWx1ZV9kZXNjcmlwdG9yXyA9IGZpbGUtPm1lc3NhZ2VfdHlwZSgzKTsKKyAgc3RhdGljIGNvbnN0IGludCBVSW50NjRWYWx1ZV9vZmZzZXRzX1sxXSA9IHsKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKFVJbnQ2NFZhbHVlLCB2YWx1ZV8pLAorICB9OworICBVSW50NjRWYWx1ZV9yZWZsZWN0aW9uXyA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok5ld0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKAorICAgICAgVUludDY0VmFsdWVfZGVzY3JpcHRvcl8sCisgICAgICBVSW50NjRWYWx1ZTo6ZGVmYXVsdF9pbnN0YW5jZV8sCisgICAgICBVSW50NjRWYWx1ZV9vZmZzZXRzXywKKyAgICAgIC0xLAorICAgICAgLTEsCisgICAgICAtMSwKKyAgICAgIHNpemVvZihVSW50NjRWYWx1ZSksCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKFVJbnQ2NFZhbHVlLCBfaW50ZXJuYWxfbWV0YWRhdGFfKSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoVUludDY0VmFsdWUsIF9pc19kZWZhdWx0X2luc3RhbmNlXykpOworICBJbnQzMlZhbHVlX2Rlc2NyaXB0b3JfID0gZmlsZS0+bWVzc2FnZV90eXBlKDQpOworICBzdGF0aWMgY29uc3QgaW50IEludDMyVmFsdWVfb2Zmc2V0c19bMV0gPSB7CisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChJbnQzMlZhbHVlLCB2YWx1ZV8pLAorICB9OworICBJbnQzMlZhbHVlX3JlZmxlY3Rpb25fID0KKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6TmV3R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24oCisgICAgICBJbnQzMlZhbHVlX2Rlc2NyaXB0b3JfLAorICAgICAgSW50MzJWYWx1ZTo6ZGVmYXVsdF9pbnN0YW5jZV8sCisgICAgICBJbnQzMlZhbHVlX29mZnNldHNfLAorICAgICAgLTEsCisgICAgICAtMSwKKyAgICAgIC0xLAorICAgICAgc2l6ZW9mKEludDMyVmFsdWUpLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChJbnQzMlZhbHVlLCBfaW50ZXJuYWxfbWV0YWRhdGFfKSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoSW50MzJWYWx1ZSwgX2lzX2RlZmF1bHRfaW5zdGFuY2VfKSk7CisgIFVJbnQzMlZhbHVlX2Rlc2NyaXB0b3JfID0gZmlsZS0+bWVzc2FnZV90eXBlKDUpOworICBzdGF0aWMgY29uc3QgaW50IFVJbnQzMlZhbHVlX29mZnNldHNfWzFdID0geworICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoVUludDMyVmFsdWUsIHZhbHVlXyksCisgIH07CisgIFVJbnQzMlZhbHVlX3JlZmxlY3Rpb25fID0KKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6TmV3R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24oCisgICAgICBVSW50MzJWYWx1ZV9kZXNjcmlwdG9yXywKKyAgICAgIFVJbnQzMlZhbHVlOjpkZWZhdWx0X2luc3RhbmNlXywKKyAgICAgIFVJbnQzMlZhbHVlX29mZnNldHNfLAorICAgICAgLTEsCisgICAgICAtMSwKKyAgICAgIC0xLAorICAgICAgc2l6ZW9mKFVJbnQzMlZhbHVlKSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoVUludDMyVmFsdWUsIF9pbnRlcm5hbF9tZXRhZGF0YV8pLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChVSW50MzJWYWx1ZSwgX2lzX2RlZmF1bHRfaW5zdGFuY2VfKSk7CisgIEJvb2xWYWx1ZV9kZXNjcmlwdG9yXyA9IGZpbGUtPm1lc3NhZ2VfdHlwZSg2KTsKKyAgc3RhdGljIGNvbnN0IGludCBCb29sVmFsdWVfb2Zmc2V0c19bMV0gPSB7CisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChCb29sVmFsdWUsIHZhbHVlXyksCisgIH07CisgIEJvb2xWYWx1ZV9yZWZsZWN0aW9uXyA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok5ld0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKAorICAgICAgQm9vbFZhbHVlX2Rlc2NyaXB0b3JfLAorICAgICAgQm9vbFZhbHVlOjpkZWZhdWx0X2luc3RhbmNlXywKKyAgICAgIEJvb2xWYWx1ZV9vZmZzZXRzXywKKyAgICAgIC0xLAorICAgICAgLTEsCisgICAgICAtMSwKKyAgICAgIHNpemVvZihCb29sVmFsdWUpLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChCb29sVmFsdWUsIF9pbnRlcm5hbF9tZXRhZGF0YV8pLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChCb29sVmFsdWUsIF9pc19kZWZhdWx0X2luc3RhbmNlXykpOworICBTdHJpbmdWYWx1ZV9kZXNjcmlwdG9yXyA9IGZpbGUtPm1lc3NhZ2VfdHlwZSg3KTsKKyAgc3RhdGljIGNvbnN0IGludCBTdHJpbmdWYWx1ZV9vZmZzZXRzX1sxXSA9IHsKKyAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKFN0cmluZ1ZhbHVlLCB2YWx1ZV8pLAorICB9OworICBTdHJpbmdWYWx1ZV9yZWZsZWN0aW9uXyA9CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb246Ok5ld0dlbmVyYXRlZE1lc3NhZ2VSZWZsZWN0aW9uKAorICAgICAgU3RyaW5nVmFsdWVfZGVzY3JpcHRvcl8sCisgICAgICBTdHJpbmdWYWx1ZTo6ZGVmYXVsdF9pbnN0YW5jZV8sCisgICAgICBTdHJpbmdWYWx1ZV9vZmZzZXRzXywKKyAgICAgIC0xLAorICAgICAgLTEsCisgICAgICAtMSwKKyAgICAgIHNpemVvZihTdHJpbmdWYWx1ZSksCisgICAgICBHT09HTEVfUFJPVE9CVUZfR0VORVJBVEVEX01FU1NBR0VfRklFTERfT0ZGU0VUKFN0cmluZ1ZhbHVlLCBfaW50ZXJuYWxfbWV0YWRhdGFfKSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoU3RyaW5nVmFsdWUsIF9pc19kZWZhdWx0X2luc3RhbmNlXykpOworICBCeXRlc1ZhbHVlX2Rlc2NyaXB0b3JfID0gZmlsZS0+bWVzc2FnZV90eXBlKDgpOworICBzdGF0aWMgY29uc3QgaW50IEJ5dGVzVmFsdWVfb2Zmc2V0c19bMV0gPSB7CisgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChCeXRlc1ZhbHVlLCB2YWx1ZV8pLAorICB9OworICBCeXRlc1ZhbHVlX3JlZmxlY3Rpb25fID0KKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZW5lcmF0ZWRNZXNzYWdlUmVmbGVjdGlvbjo6TmV3R2VuZXJhdGVkTWVzc2FnZVJlZmxlY3Rpb24oCisgICAgICBCeXRlc1ZhbHVlX2Rlc2NyaXB0b3JfLAorICAgICAgQnl0ZXNWYWx1ZTo6ZGVmYXVsdF9pbnN0YW5jZV8sCisgICAgICBCeXRlc1ZhbHVlX29mZnNldHNfLAorICAgICAgLTEsCisgICAgICAtMSwKKyAgICAgIC0xLAorICAgICAgc2l6ZW9mKEJ5dGVzVmFsdWUpLAorICAgICAgR09PR0xFX1BST1RPQlVGX0dFTkVSQVRFRF9NRVNTQUdFX0ZJRUxEX09GRlNFVChCeXRlc1ZhbHVlLCBfaW50ZXJuYWxfbWV0YWRhdGFfKSwKKyAgICAgIEdPT0dMRV9QUk9UT0JVRl9HRU5FUkFURURfTUVTU0FHRV9GSUVMRF9PRkZTRVQoQnl0ZXNWYWx1ZSwgX2lzX2RlZmF1bHRfaW5zdGFuY2VfKSk7Cit9CisKK25hbWVzcGFjZSB7CisKK0dPT0dMRV9QUk9UT0JVRl9ERUNMQVJFX09OQ0UocHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNfb25jZV8pOworaW5saW5lIHZvaWQgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCkgeworICA6Omdvb2dsZTo6cHJvdG9idWY6Okdvb2dsZU9uY2VJbml0KCZwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc19vbmNlXywKKyAgICAgICAgICAgICAgICAgJnByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZ3cmFwcGVyc18yZXByb3RvKTsKK30KKwordm9pZCBwcm90b2J1Zl9SZWdpc3RlclR5cGVzKGNvbnN0IDo6c3RkOjpzdHJpbmcmKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VGYWN0b3J5OjpJbnRlcm5hbFJlZ2lzdGVyR2VuZXJhdGVkTWVzc2FnZSgKKyAgICAgIERvdWJsZVZhbHVlX2Rlc2NyaXB0b3JfLCAmRG91YmxlVmFsdWU6OmRlZmF1bHRfaW5zdGFuY2UoKSk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZUZhY3Rvcnk6OkludGVybmFsUmVnaXN0ZXJHZW5lcmF0ZWRNZXNzYWdlKAorICAgICAgRmxvYXRWYWx1ZV9kZXNjcmlwdG9yXywgJkZsb2F0VmFsdWU6OmRlZmF1bHRfaW5zdGFuY2UoKSk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZUZhY3Rvcnk6OkludGVybmFsUmVnaXN0ZXJHZW5lcmF0ZWRNZXNzYWdlKAorICAgICAgSW50NjRWYWx1ZV9kZXNjcmlwdG9yXywgJkludDY0VmFsdWU6OmRlZmF1bHRfaW5zdGFuY2UoKSk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZUZhY3Rvcnk6OkludGVybmFsUmVnaXN0ZXJHZW5lcmF0ZWRNZXNzYWdlKAorICAgICAgVUludDY0VmFsdWVfZGVzY3JpcHRvcl8sICZVSW50NjRWYWx1ZTo6ZGVmYXVsdF9pbnN0YW5jZSgpKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZE1lc3NhZ2UoCisgICAgICBJbnQzMlZhbHVlX2Rlc2NyaXB0b3JfLCAmSW50MzJWYWx1ZTo6ZGVmYXVsdF9pbnN0YW5jZSgpKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZE1lc3NhZ2UoCisgICAgICBVSW50MzJWYWx1ZV9kZXNjcmlwdG9yXywgJlVJbnQzMlZhbHVlOjpkZWZhdWx0X2luc3RhbmNlKCkpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VGYWN0b3J5OjpJbnRlcm5hbFJlZ2lzdGVyR2VuZXJhdGVkTWVzc2FnZSgKKyAgICAgIEJvb2xWYWx1ZV9kZXNjcmlwdG9yXywgJkJvb2xWYWx1ZTo6ZGVmYXVsdF9pbnN0YW5jZSgpKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZE1lc3NhZ2UoCisgICAgICBTdHJpbmdWYWx1ZV9kZXNjcmlwdG9yXywgJlN0cmluZ1ZhbHVlOjpkZWZhdWx0X2luc3RhbmNlKCkpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2VGYWN0b3J5OjpJbnRlcm5hbFJlZ2lzdGVyR2VuZXJhdGVkTWVzc2FnZSgKKyAgICAgIEJ5dGVzVmFsdWVfZGVzY3JpcHRvcl8sICZCeXRlc1ZhbHVlOjpkZWZhdWx0X2luc3RhbmNlKCkpOworfQorCit9ICAvLyBuYW1lc3BhY2UKKwordm9pZCBwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZ3cmFwcGVyc18yZXByb3RvKCkgeworICBkZWxldGUgRG91YmxlVmFsdWU6OmRlZmF1bHRfaW5zdGFuY2VfOworICBkZWxldGUgRG91YmxlVmFsdWVfcmVmbGVjdGlvbl87CisgIGRlbGV0ZSBGbG9hdFZhbHVlOjpkZWZhdWx0X2luc3RhbmNlXzsKKyAgZGVsZXRlIEZsb2F0VmFsdWVfcmVmbGVjdGlvbl87CisgIGRlbGV0ZSBJbnQ2NFZhbHVlOjpkZWZhdWx0X2luc3RhbmNlXzsKKyAgZGVsZXRlIEludDY0VmFsdWVfcmVmbGVjdGlvbl87CisgIGRlbGV0ZSBVSW50NjRWYWx1ZTo6ZGVmYXVsdF9pbnN0YW5jZV87CisgIGRlbGV0ZSBVSW50NjRWYWx1ZV9yZWZsZWN0aW9uXzsKKyAgZGVsZXRlIEludDMyVmFsdWU6OmRlZmF1bHRfaW5zdGFuY2VfOworICBkZWxldGUgSW50MzJWYWx1ZV9yZWZsZWN0aW9uXzsKKyAgZGVsZXRlIFVJbnQzMlZhbHVlOjpkZWZhdWx0X2luc3RhbmNlXzsKKyAgZGVsZXRlIFVJbnQzMlZhbHVlX3JlZmxlY3Rpb25fOworICBkZWxldGUgQm9vbFZhbHVlOjpkZWZhdWx0X2luc3RhbmNlXzsKKyAgZGVsZXRlIEJvb2xWYWx1ZV9yZWZsZWN0aW9uXzsKKyAgZGVsZXRlIFN0cmluZ1ZhbHVlOjpkZWZhdWx0X2luc3RhbmNlXzsKKyAgZGVsZXRlIFN0cmluZ1ZhbHVlX3JlZmxlY3Rpb25fOworICBkZWxldGUgQnl0ZXNWYWx1ZTo6ZGVmYXVsdF9pbnN0YW5jZV87CisgIGRlbGV0ZSBCeXRlc1ZhbHVlX3JlZmxlY3Rpb25fOworfQorCit2b2lkIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZ3cmFwcGVyc18yZXByb3RvKCkgeworICBzdGF0aWMgYm9vbCBhbHJlYWR5X2hlcmUgPSBmYWxzZTsKKyAgaWYgKGFscmVhZHlfaGVyZSkgcmV0dXJuOworICBhbHJlYWR5X2hlcmUgPSB0cnVlOworICBHT09HTEVfUFJPVE9CVUZfVkVSSUZZX1ZFUlNJT047CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yUG9vbDo6SW50ZXJuYWxBZGRHZW5lcmF0ZWRGaWxlKAorICAgICJcblwwMzZnb29nbGUvcHJvdG9idWYvd3JhcHBlcnMucHJvdG9cMDIyXDAxN2dvb2dsZSIKKyAgICAiLnByb3RvYnVmXCJcMDM0XG5cMDEzRG91YmxlVmFsdWVcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAxIFwwMDEoXDAwMVwiIgorICAgICJcMDMzXG5cbkZsb2F0VmFsdWVcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAxIFwwMDEoXDAwMlwiXDAzM1xuXG5JbnQ2NFZhbCIKKyAgICAidWVcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAxIFwwMDEoXDAwM1wiXDAzNFxuXDAxM1VJbnQ2NFZhbHVlXDAyMlxyXG5cMDA1dmFsdSIKKyAgICAiZVwwMzBcMDAxIFwwMDEoXDAwNFwiXDAzM1xuXG5JbnQzMlZhbHVlXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMSBcMDAxKFwwMDVcIlwwMzRcblwwMTMiCisgICAgIlVJbnQzMlZhbHVlXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMSBcMDAxKFxyXCJcMDMyXG5cdEJvb2xWYWx1ZVwwMjIiCisgICAgIlxyXG5cMDA1dmFsdWVcMDMwXDAwMSBcMDAxKFwwMTBcIlwwMzRcblwwMTNTdHJpbmdWYWx1ZVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDEiCisgICAgIiBcMDAxKFx0XCJcMDMzXG5cbkJ5dGVzVmFsdWVcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAxIFwwMDEoXDAxNEJTXG5cMDIzY29tIgorICAgICIuZ29vZ2xlLnByb3RvYnVmQlxyV3JhcHBlcnNQcm90b1BcMDAxXDI0MFwwMDFcMDAxXDM3MFwwMDFcMDAxXDI0MiIKKyAgICAiXDAwMlwwMDNHUEJcMjUyXDAwMlwwMzZHb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlwZXNiXDAwNiIKKyAgICAicHJvdG8zIiwgNDA2KTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlRmFjdG9yeTo6SW50ZXJuYWxSZWdpc3RlckdlbmVyYXRlZEZpbGUoCisgICAgImdvb2dsZS9wcm90b2J1Zi93cmFwcGVycy5wcm90byIsICZwcm90b2J1Zl9SZWdpc3RlclR5cGVzKTsKKyAgRG91YmxlVmFsdWU6OmRlZmF1bHRfaW5zdGFuY2VfID0gbmV3IERvdWJsZVZhbHVlKCk7CisgIEZsb2F0VmFsdWU6OmRlZmF1bHRfaW5zdGFuY2VfID0gbmV3IEZsb2F0VmFsdWUoKTsKKyAgSW50NjRWYWx1ZTo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBuZXcgSW50NjRWYWx1ZSgpOworICBVSW50NjRWYWx1ZTo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBuZXcgVUludDY0VmFsdWUoKTsKKyAgSW50MzJWYWx1ZTo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBuZXcgSW50MzJWYWx1ZSgpOworICBVSW50MzJWYWx1ZTo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBuZXcgVUludDMyVmFsdWUoKTsKKyAgQm9vbFZhbHVlOjpkZWZhdWx0X2luc3RhbmNlXyA9IG5ldyBCb29sVmFsdWUoKTsKKyAgU3RyaW5nVmFsdWU6OmRlZmF1bHRfaW5zdGFuY2VfID0gbmV3IFN0cmluZ1ZhbHVlKCk7CisgIEJ5dGVzVmFsdWU6OmRlZmF1bHRfaW5zdGFuY2VfID0gbmV3IEJ5dGVzVmFsdWUoKTsKKyAgRG91YmxlVmFsdWU6OmRlZmF1bHRfaW5zdGFuY2VfLT5Jbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgRmxvYXRWYWx1ZTo6ZGVmYXVsdF9pbnN0YW5jZV8tPkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICBJbnQ2NFZhbHVlOjpkZWZhdWx0X2luc3RhbmNlXy0+SW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIFVJbnQ2NFZhbHVlOjpkZWZhdWx0X2luc3RhbmNlXy0+SW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIEludDMyVmFsdWU6OmRlZmF1bHRfaW5zdGFuY2VfLT5Jbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgVUludDMyVmFsdWU6OmRlZmF1bHRfaW5zdGFuY2VfLT5Jbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgQm9vbFZhbHVlOjpkZWZhdWx0X2luc3RhbmNlXy0+SW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIFN0cmluZ1ZhbHVlOjpkZWZhdWx0X2luc3RhbmNlXy0+SW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIEJ5dGVzVmFsdWU6OmRlZmF1bHRfaW5zdGFuY2VfLT5Jbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6T25TaHV0ZG93bigmcHJvdG9idWZfU2h1dGRvd25GaWxlX2dvb2dsZV8yZnByb3RvYnVmXzJmd3JhcHBlcnNfMmVwcm90byk7Cit9CisKKy8vIEZvcmNlIEFkZERlc2NyaXB0b3JzKCkgdG8gYmUgY2FsbGVkIGF0IHN0YXRpYyBpbml0aWFsaXphdGlvbiB0aW1lLgorc3RydWN0IFN0YXRpY0Rlc2NyaXB0b3JJbml0aWFsaXplcl9nb29nbGVfMmZwcm90b2J1Zl8yZndyYXBwZXJzXzJlcHJvdG8geworICBTdGF0aWNEZXNjcmlwdG9ySW5pdGlhbGl6ZXJfZ29vZ2xlXzJmcHJvdG9idWZfMmZ3cmFwcGVyc18yZXByb3RvKCkgeworICAgIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZ3cmFwcGVyc18yZXByb3RvKCk7CisgIH0KK30gc3RhdGljX2Rlc2NyaXB0b3JfaW5pdGlhbGl6ZXJfZ29vZ2xlXzJmcHJvdG9idWZfMmZ3cmFwcGVyc18yZXByb3RvXzsKKworbmFtZXNwYWNlIHsKKworc3RhdGljIHZvaWQgTWVyZ2VGcm9tRmFpbChpbnQgbGluZSkgR09PR0xFX0FUVFJJQlVURV9DT0xEOworc3RhdGljIHZvaWQgTWVyZ2VGcm9tRmFpbChpbnQgbGluZSkgeworICBHT09HTEVfQ0hFQ0soZmFsc2UpIDw8IF9fRklMRV9fIDw8ICI6IiA8PCBsaW5lOworfQorCit9ICAvLyBuYW1lc3BhY2UKKworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKyNpZiAhZGVmaW5lZChfTVNDX1ZFUikgfHwgX01TQ19WRVIgPj0gMTkwMAorY29uc3QgaW50IERvdWJsZVZhbHVlOjprVmFsdWVGaWVsZE51bWJlcjsKKyNlbmRpZiAgLy8gIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKKworRG91YmxlVmFsdWU6OkRvdWJsZVZhbHVlKCkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSkKK30KKworRG91YmxlVmFsdWU6OkRvdWJsZVZhbHVlKDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpLAorICBfaW50ZXJuYWxfbWV0YWRhdGFfKGFyZW5hKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgUmVnaXN0ZXJBcmVuYUR0b3IoYXJlbmEpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYXJlbmFfY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlKQorfQorCit2b2lkIERvdWJsZVZhbHVlOjpJbml0QXNEZWZhdWx0SW5zdGFuY2UoKSB7CisgIF9pc19kZWZhdWx0X2luc3RhbmNlXyA9IHRydWU7Cit9CisKK0RvdWJsZVZhbHVlOjpEb3VibGVWYWx1ZShjb25zdCBEb3VibGVWYWx1ZSYgZnJvbSkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwKKyAgICBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICBNZXJnZUZyb20oZnJvbSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb3B5X2NvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSkKK30KKwordm9pZCBEb3VibGVWYWx1ZTo6U2hhcmVkQ3RvcigpIHsKKyAgICBfaXNfZGVmYXVsdF9pbnN0YW5jZV8gPSBmYWxzZTsKKyAgX2NhY2hlZF9zaXplXyA9IDA7CisgIHZhbHVlXyA9IDA7Cit9CisKK0RvdWJsZVZhbHVlOjp+RG91YmxlVmFsdWUoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChkZXN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSkKKyAgU2hhcmVkRHRvcigpOworfQorCit2b2lkIERvdWJsZVZhbHVlOjpTaGFyZWREdG9yKCkgeworICBpZiAoR2V0QXJlbmFOb1ZpcnR1YWwoKSAhPSBOVUxMKSB7CisgICAgcmV0dXJuOworICB9CisKKyAgaWYgKHRoaXMgIT0gZGVmYXVsdF9pbnN0YW5jZV8pIHsKKyAgfQorfQorCit2b2lkIERvdWJsZVZhbHVlOjpBcmVuYUR0b3Iodm9pZCogb2JqZWN0KSB7CisgIERvdWJsZVZhbHVlKiBfdGhpcyA9IHJlaW50ZXJwcmV0X2Nhc3Q8IERvdWJsZVZhbHVlKiA+KG9iamVjdCk7CisgICh2b2lkKV90aGlzOworfQordm9pZCBEb3VibGVWYWx1ZTo6UmVnaXN0ZXJBcmVuYUR0b3IoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIHsKK30KK3ZvaWQgRG91YmxlVmFsdWU6OlNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0IHsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHNpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworfQorY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBEb3VibGVWYWx1ZTo6ZGVzY3JpcHRvcigpIHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIHJldHVybiBEb3VibGVWYWx1ZV9kZXNjcmlwdG9yXzsKK30KKworY29uc3QgRG91YmxlVmFsdWUmIERvdWJsZVZhbHVlOjpkZWZhdWx0X2luc3RhbmNlKCkgeworICBpZiAoZGVmYXVsdF9pbnN0YW5jZV8gPT0gTlVMTCkgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZndyYXBwZXJzXzJlcHJvdG8oKTsKKyAgcmV0dXJuICpkZWZhdWx0X2luc3RhbmNlXzsKK30KKworRG91YmxlVmFsdWUqIERvdWJsZVZhbHVlOjpkZWZhdWx0X2luc3RhbmNlXyA9IE5VTEw7CisKK0RvdWJsZVZhbHVlKiBEb3VibGVWYWx1ZTo6TmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdCB7CisgIHJldHVybiA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hOjpDcmVhdGVNZXNzYWdlPERvdWJsZVZhbHVlPihhcmVuYSk7Cit9CisKK3ZvaWQgRG91YmxlVmFsdWU6OkNsZWFyKCkgeworICB2YWx1ZV8gPSAwOworfQorCitib29sIERvdWJsZVZhbHVlOjpNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyNkZWZpbmUgRE9fKEVYUFJFU1NJT04pIGlmICghKEVYUFJFU1NJT04pKSBnb3RvIGZhaWx1cmUKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgdGFnOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlKQorICBmb3IgKDs7KSB7CisgICAgOjpzdGQ6OnBhaXI8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyLCBib29sPiBwID0gaW5wdXQtPlJlYWRUYWdXaXRoQ3V0b2ZmKDEyNyk7CisgICAgdGFnID0gcC5maXJzdDsKKyAgICBpZiAoIXAuc2Vjb25kKSBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgIHN3aXRjaCAoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ0ZpZWxkTnVtYmVyKHRhZykpIHsKKyAgICAgIC8vIG9wdGlvbmFsIGRvdWJsZSB2YWx1ZSA9IDE7CisgICAgICBjYXNlIDE6IHsKKyAgICAgICAgaWYgKHRhZyA9PSA5KSB7CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICBkb3VibGUsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0RPVUJMRT4oCisgICAgICAgICAgICAgICAgIGlucHV0LCAmdmFsdWVfKSkpOworCisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdEF0RW5kKCkpIGdvdG8gc3VjY2VzczsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGRlZmF1bHQ6IHsKKyAgICAgIGhhbmRsZV91bnVzdWFsOgorICAgICAgICBpZiAodGFnID09IDAgfHwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdXaXJlVHlwZSh0YWcpID09CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRU5EX0dST1VQKSB7CisgICAgICAgICAgZ290byBzdWNjZXNzOworICAgICAgICB9CisgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U2tpcEZpZWxkKGlucHV0LCB0YWcpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CitzdWNjZXNzOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3VjY2Vzczpnb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUpCisgIHJldHVybiB0cnVlOworZmFpbHVyZToKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX2ZhaWx1cmU6Z29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlKQorICByZXR1cm4gZmFsc2U7CisjdW5kZWYgRE9fCit9CisKK3ZvaWQgRG91YmxlVmFsdWU6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlKQorICAvLyBvcHRpb25hbCBkb3VibGUgdmFsdWUgPSAxOworICBpZiAodGhpcy0+dmFsdWUoKSAhPSAwKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlRG91YmxlKDEsIHRoaXMtPnZhbHVlKCksIG91dHB1dCk7CisgIH0KKworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX2VuZDpnb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUpCit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIERvdWJsZVZhbHVlOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIHRhcmdldCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSkKKyAgLy8gb3B0aW9uYWwgZG91YmxlIHZhbHVlID0gMTsKKyAgaWYgKHRoaXMtPnZhbHVlKCkgIT0gMCkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZURvdWJsZVRvQXJyYXkoMSwgdGhpcy0+dmFsdWUoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfZW5kOmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSkKKyAgcmV0dXJuIHRhcmdldDsKK30KKworaW50IERvdWJsZVZhbHVlOjpCeXRlU2l6ZSgpIGNvbnN0IHsKKyAgaW50IHRvdGFsX3NpemUgPSAwOworCisgIC8vIG9wdGlvbmFsIGRvdWJsZSB2YWx1ZSA9IDE7CisgIGlmICh0aGlzLT52YWx1ZSgpICE9IDApIHsKKyAgICB0b3RhbF9zaXplICs9IDEgKyA4OworICB9CisKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHRvdGFsX3NpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworICByZXR1cm4gdG90YWxfc2l6ZTsKK30KKwordm9pZCBEb3VibGVWYWx1ZTo6TWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBjb25zdCBEb3VibGVWYWx1ZSogc291cmNlID0gCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpEeW5hbWljQ2FzdFRvR2VuZXJhdGVkPGNvbnN0IERvdWJsZVZhbHVlPigKKyAgICAgICAgICAmZnJvbSk7CisgIGlmIChzb3VyY2UgPT0gTlVMTCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlJlZmxlY3Rpb25PcHM6Ok1lcmdlKGZyb20sIHRoaXMpOworICB9IGVsc2UgeworICAgIE1lcmdlRnJvbSgqc291cmNlKTsKKyAgfQorfQorCit2b2lkIERvdWJsZVZhbHVlOjpNZXJnZUZyb20oY29uc3QgRG91YmxlVmFsdWUmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgaWYgKGZyb20udmFsdWUoKSAhPSAwKSB7CisgICAgc2V0X3ZhbHVlKGZyb20udmFsdWUoKSk7CisgIH0KK30KKwordm9pZCBEb3VibGVWYWx1ZTo6Q29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKwordm9pZCBEb3VibGVWYWx1ZTo6Q29weUZyb20oY29uc3QgRG91YmxlVmFsdWUmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCitib29sIERvdWJsZVZhbHVlOjpJc0luaXRpYWxpemVkKCkgY29uc3QgeworCisgIHJldHVybiB0cnVlOworfQorCit2b2lkIERvdWJsZVZhbHVlOjpTd2FwKERvdWJsZVZhbHVlKiBvdGhlcikgeworICBpZiAob3RoZXIgPT0gdGhpcykgcmV0dXJuOworICBpZiAoR2V0QXJlbmFOb1ZpcnR1YWwoKSA9PSBvdGhlci0+R2V0QXJlbmFOb1ZpcnR1YWwoKSkgeworICAgIEludGVybmFsU3dhcChvdGhlcik7CisgIH0gZWxzZSB7CisgICAgRG91YmxlVmFsdWUgdGVtcDsKKyAgICB0ZW1wLk1lcmdlRnJvbSgqdGhpcyk7CisgICAgQ29weUZyb20oKm90aGVyKTsKKyAgICBvdGhlci0+Q29weUZyb20odGVtcCk7CisgIH0KK30KK3ZvaWQgRG91YmxlVmFsdWU6OlVuc2FmZUFyZW5hU3dhcChEb3VibGVWYWx1ZSogb3RoZXIpIHsKKyAgaWYgKG90aGVyID09IHRoaXMpIHJldHVybjsKKyAgR09PR0xFX0RDSEVDSyhHZXRBcmVuYU5vVmlydHVhbCgpID09IG90aGVyLT5HZXRBcmVuYU5vVmlydHVhbCgpKTsKKyAgSW50ZXJuYWxTd2FwKG90aGVyKTsKK30KK3ZvaWQgRG91YmxlVmFsdWU6OkludGVybmFsU3dhcChEb3VibGVWYWx1ZSogb3RoZXIpIHsKKyAgc3RkOjpzd2FwKHZhbHVlXywgb3RoZXItPnZhbHVlXyk7CisgIF9pbnRlcm5hbF9tZXRhZGF0YV8uU3dhcCgmb3RoZXItPl9pbnRlcm5hbF9tZXRhZGF0YV8pOworICBzdGQ6OnN3YXAoX2NhY2hlZF9zaXplXywgb3RoZXItPl9jYWNoZWRfc2l6ZV8pOworfQorCis6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIERvdWJsZVZhbHVlOjpHZXRNZXRhZGF0YSgpIGNvbnN0IHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgbWV0YWRhdGE7CisgIG1ldGFkYXRhLmRlc2NyaXB0b3IgPSBEb3VibGVWYWx1ZV9kZXNjcmlwdG9yXzsKKyAgbWV0YWRhdGEucmVmbGVjdGlvbiA9IERvdWJsZVZhbHVlX3JlZmxlY3Rpb25fOworICByZXR1cm4gbWV0YWRhdGE7Cit9CisKKyNpZiBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKy8vIERvdWJsZVZhbHVlCisKKy8vIG9wdGlvbmFsIGRvdWJsZSB2YWx1ZSA9IDE7Cit2b2lkIERvdWJsZVZhbHVlOjpjbGVhcl92YWx1ZSgpIHsKKyAgdmFsdWVfID0gMDsKK30KKyBkb3VibGUgRG91YmxlVmFsdWU6OnZhbHVlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZS52YWx1ZSkKKyAgcmV0dXJuIHZhbHVlXzsKK30KKyB2b2lkIERvdWJsZVZhbHVlOjpzZXRfdmFsdWUoZG91YmxlIHZhbHVlKSB7CisgIAorICB2YWx1ZV8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUudmFsdWUpCit9CisKKyNlbmRpZiAgLy8gUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworI2lmICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCitjb25zdCBpbnQgRmxvYXRWYWx1ZTo6a1ZhbHVlRmllbGROdW1iZXI7CisjZW5kaWYgIC8vICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCisKK0Zsb2F0VmFsdWU6OkZsb2F0VmFsdWUoKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpLCBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUpCit9CisKK0Zsb2F0VmFsdWU6OkZsb2F0VmFsdWUoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksCisgIF9pbnRlcm5hbF9tZXRhZGF0YV8oYXJlbmEpIHsKKyAgU2hhcmVkQ3RvcigpOworICBSZWdpc3RlckFyZW5hRHRvcihhcmVuYSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChhcmVuYV9jb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSkKK30KKwordm9pZCBGbG9hdFZhbHVlOjpJbml0QXNEZWZhdWx0SW5zdGFuY2UoKSB7CisgIF9pc19kZWZhdWx0X2luc3RhbmNlXyA9IHRydWU7Cit9CisKK0Zsb2F0VmFsdWU6OkZsb2F0VmFsdWUoY29uc3QgRmxvYXRWYWx1ZSYgZnJvbSkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwKKyAgICBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICBNZXJnZUZyb20oZnJvbSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb3B5X2NvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlKQorfQorCit2b2lkIEZsb2F0VmFsdWU6OlNoYXJlZEN0b3IoKSB7CisgICAgX2lzX2RlZmF1bHRfaW5zdGFuY2VfID0gZmFsc2U7CisgIF9jYWNoZWRfc2l6ZV8gPSAwOworICB2YWx1ZV8gPSAwOworfQorCitGbG9hdFZhbHVlOjp+RmxvYXRWYWx1ZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGRlc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUpCisgIFNoYXJlZER0b3IoKTsKK30KKwordm9pZCBGbG9hdFZhbHVlOjpTaGFyZWREdG9yKCkgeworICBpZiAoR2V0QXJlbmFOb1ZpcnR1YWwoKSAhPSBOVUxMKSB7CisgICAgcmV0dXJuOworICB9CisKKyAgaWYgKHRoaXMgIT0gZGVmYXVsdF9pbnN0YW5jZV8pIHsKKyAgfQorfQorCit2b2lkIEZsb2F0VmFsdWU6OkFyZW5hRHRvcih2b2lkKiBvYmplY3QpIHsKKyAgRmxvYXRWYWx1ZSogX3RoaXMgPSByZWludGVycHJldF9jYXN0PCBGbG9hdFZhbHVlKiA+KG9iamVjdCk7CisgICh2b2lkKV90aGlzOworfQordm9pZCBGbG9hdFZhbHVlOjpSZWdpc3RlckFyZW5hRHRvcig6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgeworfQordm9pZCBGbG9hdFZhbHVlOjpTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdCB7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSBzaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogRmxvYXRWYWx1ZTo6ZGVzY3JpcHRvcigpIHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIHJldHVybiBGbG9hdFZhbHVlX2Rlc2NyaXB0b3JfOworfQorCitjb25zdCBGbG9hdFZhbHVlJiBGbG9hdFZhbHVlOjpkZWZhdWx0X2luc3RhbmNlKCkgeworICBpZiAoZGVmYXVsdF9pbnN0YW5jZV8gPT0gTlVMTCkgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZndyYXBwZXJzXzJlcHJvdG8oKTsKKyAgcmV0dXJuICpkZWZhdWx0X2luc3RhbmNlXzsKK30KKworRmxvYXRWYWx1ZSogRmxvYXRWYWx1ZTo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBOVUxMOworCitGbG9hdFZhbHVlKiBGbG9hdFZhbHVlOjpOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0IHsKKyAgcmV0dXJuIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmE6OkNyZWF0ZU1lc3NhZ2U8RmxvYXRWYWx1ZT4oYXJlbmEpOworfQorCit2b2lkIEZsb2F0VmFsdWU6OkNsZWFyKCkgeworICB2YWx1ZV8gPSAwOworfQorCitib29sIEZsb2F0VmFsdWU6Ok1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCkgeworI2RlZmluZSBET18oRVhQUkVTU0lPTikgaWYgKCEoRVhQUkVTU0lPTikpIGdvdG8gZmFpbHVyZQorICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiB0YWc7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdGFydDpnb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSkKKyAgZm9yICg7OykgeworICAgIDo6c3RkOjpwYWlyPCA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiwgYm9vbD4gcCA9IGlucHV0LT5SZWFkVGFnV2l0aEN1dG9mZigxMjcpOworICAgIHRhZyA9IHAuZmlyc3Q7CisgICAgaWYgKCFwLnNlY29uZCkgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICBzd2l0Y2ggKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdGaWVsZE51bWJlcih0YWcpKSB7CisgICAgICAvLyBvcHRpb25hbCBmbG9hdCB2YWx1ZSA9IDE7CisgICAgICBjYXNlIDE6IHsKKyAgICAgICAgaWYgKHRhZyA9PSAxMykgeworICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgZmxvYXQsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX0ZMT0FUPigKKyAgICAgICAgICAgICAgICAgaW5wdXQsICZ2YWx1ZV8pKSk7CisKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0QXRFbmQoKSkgZ290byBzdWNjZXNzOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgZGVmYXVsdDogeworICAgICAgaGFuZGxlX3VudXN1YWw6CisgICAgICAgIGlmICh0YWcgPT0gMCB8fAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ1dpcmVUeXBlKHRhZykgPT0KKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVApIHsKKyAgICAgICAgICBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIH0KKyAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTa2lwRmllbGQoaW5wdXQsIHRhZykpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KK3N1Y2Nlc3M6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdWNjZXNzOmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlKQorICByZXR1cm4gdHJ1ZTsKK2ZhaWx1cmU6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9mYWlsdXJlOmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlKQorICByZXR1cm4gZmFsc2U7CisjdW5kZWYgRE9fCit9CisKK3ZvaWQgRmxvYXRWYWx1ZTo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9zdGFydDpnb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSkKKyAgLy8gb3B0aW9uYWwgZmxvYXQgdmFsdWUgPSAxOworICBpZiAodGhpcy0+dmFsdWUoKSAhPSAwKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlRmxvYXQoMSwgdGhpcy0+dmFsdWUoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfZW5kOmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlKQorfQorCis6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBGbG9hdFZhbHVlOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIHRhcmdldCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlKQorICAvLyBvcHRpb25hbCBmbG9hdCB2YWx1ZSA9IDE7CisgIGlmICh0aGlzLT52YWx1ZSgpICE9IDApIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVGbG9hdFRvQXJyYXkoMSwgdGhpcy0+dmFsdWUoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfZW5kOmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlKQorICByZXR1cm4gdGFyZ2V0OworfQorCitpbnQgRmxvYXRWYWx1ZTo6Qnl0ZVNpemUoKSBjb25zdCB7CisgIGludCB0b3RhbF9zaXplID0gMDsKKworICAvLyBvcHRpb25hbCBmbG9hdCB2YWx1ZSA9IDE7CisgIGlmICh0aGlzLT52YWx1ZSgpICE9IDApIHsKKyAgICB0b3RhbF9zaXplICs9IDEgKyA0OworICB9CisKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHRvdGFsX3NpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworICByZXR1cm4gdG90YWxfc2l6ZTsKK30KKwordm9pZCBGbG9hdFZhbHVlOjpNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGNvbnN0IEZsb2F0VmFsdWUqIHNvdXJjZSA9IAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RHluYW1pY0Nhc3RUb0dlbmVyYXRlZDxjb25zdCBGbG9hdFZhbHVlPigKKyAgICAgICAgICAmZnJvbSk7CisgIGlmIChzb3VyY2UgPT0gTlVMTCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlJlZmxlY3Rpb25PcHM6Ok1lcmdlKGZyb20sIHRoaXMpOworICB9IGVsc2UgeworICAgIE1lcmdlRnJvbSgqc291cmNlKTsKKyAgfQorfQorCit2b2lkIEZsb2F0VmFsdWU6Ok1lcmdlRnJvbShjb25zdCBGbG9hdFZhbHVlJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGlmIChmcm9tLnZhbHVlKCkgIT0gMCkgeworICAgIHNldF92YWx1ZShmcm9tLnZhbHVlKCkpOworICB9Cit9CisKK3ZvaWQgRmxvYXRWYWx1ZTo6Q29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKwordm9pZCBGbG9hdFZhbHVlOjpDb3B5RnJvbShjb25zdCBGbG9hdFZhbHVlJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKworYm9vbCBGbG9hdFZhbHVlOjpJc0luaXRpYWxpemVkKCkgY29uc3QgeworCisgIHJldHVybiB0cnVlOworfQorCit2b2lkIEZsb2F0VmFsdWU6OlN3YXAoRmxvYXRWYWx1ZSogb3RoZXIpIHsKKyAgaWYgKG90aGVyID09IHRoaXMpIHJldHVybjsKKyAgaWYgKEdldEFyZW5hTm9WaXJ0dWFsKCkgPT0gb3RoZXItPkdldEFyZW5hTm9WaXJ0dWFsKCkpIHsKKyAgICBJbnRlcm5hbFN3YXAob3RoZXIpOworICB9IGVsc2UgeworICAgIEZsb2F0VmFsdWUgdGVtcDsKKyAgICB0ZW1wLk1lcmdlRnJvbSgqdGhpcyk7CisgICAgQ29weUZyb20oKm90aGVyKTsKKyAgICBvdGhlci0+Q29weUZyb20odGVtcCk7CisgIH0KK30KK3ZvaWQgRmxvYXRWYWx1ZTo6VW5zYWZlQXJlbmFTd2FwKEZsb2F0VmFsdWUqIG90aGVyKSB7CisgIGlmIChvdGhlciA9PSB0aGlzKSByZXR1cm47CisgIEdPT0dMRV9EQ0hFQ0soR2V0QXJlbmFOb1ZpcnR1YWwoKSA9PSBvdGhlci0+R2V0QXJlbmFOb1ZpcnR1YWwoKSk7CisgIEludGVybmFsU3dhcChvdGhlcik7Cit9Cit2b2lkIEZsb2F0VmFsdWU6OkludGVybmFsU3dhcChGbG9hdFZhbHVlKiBvdGhlcikgeworICBzdGQ6OnN3YXAodmFsdWVfLCBvdGhlci0+dmFsdWVfKTsKKyAgX2ludGVybmFsX21ldGFkYXRhXy5Td2FwKCZvdGhlci0+X2ludGVybmFsX21ldGFkYXRhXyk7CisgIHN0ZDo6c3dhcChfY2FjaGVkX3NpemVfLCBvdGhlci0+X2NhY2hlZF9zaXplXyk7Cit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgRmxvYXRWYWx1ZTo6R2V0TWV0YWRhdGEoKSBjb25zdCB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIG1ldGFkYXRhOworICBtZXRhZGF0YS5kZXNjcmlwdG9yID0gRmxvYXRWYWx1ZV9kZXNjcmlwdG9yXzsKKyAgbWV0YWRhdGEucmVmbGVjdGlvbiA9IEZsb2F0VmFsdWVfcmVmbGVjdGlvbl87CisgIHJldHVybiBtZXRhZGF0YTsKK30KKworI2lmIFBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworLy8gRmxvYXRWYWx1ZQorCisvLyBvcHRpb25hbCBmbG9hdCB2YWx1ZSA9IDE7Cit2b2lkIEZsb2F0VmFsdWU6OmNsZWFyX3ZhbHVlKCkgeworICB2YWx1ZV8gPSAwOworfQorIGZsb2F0IEZsb2F0VmFsdWU6OnZhbHVlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlLnZhbHVlKQorICByZXR1cm4gdmFsdWVfOworfQorIHZvaWQgRmxvYXRWYWx1ZTo6c2V0X3ZhbHVlKGZsb2F0IHZhbHVlKSB7CisgIAorICB2YWx1ZV8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZS52YWx1ZSkKK30KKworI2VuZGlmICAvLyBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisjaWYgIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKK2NvbnN0IGludCBJbnQ2NFZhbHVlOjprVmFsdWVGaWVsZE51bWJlcjsKKyNlbmRpZiAgLy8gIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKKworSW50NjRWYWx1ZTo6SW50NjRWYWx1ZSgpCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgeworICBTaGFyZWRDdG9yKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSkKK30KKworSW50NjRWYWx1ZTo6SW50NjRWYWx1ZSg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwKKyAgX2ludGVybmFsX21ldGFkYXRhXyhhcmVuYSkgeworICBTaGFyZWRDdG9yKCk7CisgIFJlZ2lzdGVyQXJlbmFEdG9yKGFyZW5hKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGFyZW5hX2NvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlKQorfQorCit2b2lkIEludDY0VmFsdWU6OkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpIHsKKyAgX2lzX2RlZmF1bHRfaW5zdGFuY2VfID0gdHJ1ZTsKK30KKworSW50NjRWYWx1ZTo6SW50NjRWYWx1ZShjb25zdCBJbnQ2NFZhbHVlJiBmcm9tKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpLAorICAgIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgeworICBTaGFyZWRDdG9yKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvcHlfY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUpCit9CisKK3ZvaWQgSW50NjRWYWx1ZTo6U2hhcmVkQ3RvcigpIHsKKyAgICBfaXNfZGVmYXVsdF9pbnN0YW5jZV8gPSBmYWxzZTsKKyAgX2NhY2hlZF9zaXplXyA9IDA7CisgIHZhbHVlXyA9IEdPT0dMRV9MT05HTE9ORygwKTsKK30KKworSW50NjRWYWx1ZTo6fkludDY0VmFsdWUoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChkZXN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlKQorICBTaGFyZWREdG9yKCk7Cit9CisKK3ZvaWQgSW50NjRWYWx1ZTo6U2hhcmVkRHRvcigpIHsKKyAgaWYgKEdldEFyZW5hTm9WaXJ0dWFsKCkgIT0gTlVMTCkgeworICAgIHJldHVybjsKKyAgfQorCisgIGlmICh0aGlzICE9IGRlZmF1bHRfaW5zdGFuY2VfKSB7CisgIH0KK30KKwordm9pZCBJbnQ2NFZhbHVlOjpBcmVuYUR0b3Iodm9pZCogb2JqZWN0KSB7CisgIEludDY0VmFsdWUqIF90aGlzID0gcmVpbnRlcnByZXRfY2FzdDwgSW50NjRWYWx1ZSogPihvYmplY3QpOworICAodm9pZClfdGhpczsKK30KK3ZvaWQgSW50NjRWYWx1ZTo6UmVnaXN0ZXJBcmVuYUR0b3IoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIHsKK30KK3ZvaWQgSW50NjRWYWx1ZTo6U2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3QgeworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIEludDY0VmFsdWU6OmRlc2NyaXB0b3IoKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICByZXR1cm4gSW50NjRWYWx1ZV9kZXNjcmlwdG9yXzsKK30KKworY29uc3QgSW50NjRWYWx1ZSYgSW50NjRWYWx1ZTo6ZGVmYXVsdF9pbnN0YW5jZSgpIHsKKyAgaWYgKGRlZmF1bHRfaW5zdGFuY2VfID09IE5VTEwpIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZ3cmFwcGVyc18yZXByb3RvKCk7CisgIHJldHVybiAqZGVmYXVsdF9pbnN0YW5jZV87Cit9CisKK0ludDY0VmFsdWUqIEludDY0VmFsdWU6OmRlZmF1bHRfaW5zdGFuY2VfID0gTlVMTDsKKworSW50NjRWYWx1ZSogSW50NjRWYWx1ZTo6TmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdCB7CisgIHJldHVybiA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hOjpDcmVhdGVNZXNzYWdlPEludDY0VmFsdWU+KGFyZW5hKTsKK30KKwordm9pZCBJbnQ2NFZhbHVlOjpDbGVhcigpIHsKKyAgdmFsdWVfID0gR09PR0xFX0xPTkdMT05HKDApOworfQorCitib29sIEludDY0VmFsdWU6Ok1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCkgeworI2RlZmluZSBET18oRVhQUkVTU0lPTikgaWYgKCEoRVhQUkVTU0lPTikpIGdvdG8gZmFpbHVyZQorICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiB0YWc7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdGFydDpnb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSkKKyAgZm9yICg7OykgeworICAgIDo6c3RkOjpwYWlyPCA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiwgYm9vbD4gcCA9IGlucHV0LT5SZWFkVGFnV2l0aEN1dG9mZigxMjcpOworICAgIHRhZyA9IHAuZmlyc3Q7CisgICAgaWYgKCFwLnNlY29uZCkgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICBzd2l0Y2ggKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdGaWVsZE51bWJlcih0YWcpKSB7CisgICAgICAvLyBvcHRpb25hbCBpbnQ2NCB2YWx1ZSA9IDE7CisgICAgICBjYXNlIDE6IHsKKyAgICAgICAgaWYgKHRhZyA9PSA4KSB7CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludDY0LCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9JTlQ2ND4oCisgICAgICAgICAgICAgICAgIGlucHV0LCAmdmFsdWVfKSkpOworCisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdEF0RW5kKCkpIGdvdG8gc3VjY2VzczsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGRlZmF1bHQ6IHsKKyAgICAgIGhhbmRsZV91bnVzdWFsOgorICAgICAgICBpZiAodGFnID09IDAgfHwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdXaXJlVHlwZSh0YWcpID09CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRU5EX0dST1VQKSB7CisgICAgICAgICAgZ290byBzdWNjZXNzOworICAgICAgICB9CisgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U2tpcEZpZWxkKGlucHV0LCB0YWcpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CitzdWNjZXNzOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3VjY2Vzczpnb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSkKKyAgcmV0dXJuIHRydWU7CitmYWlsdXJlOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2VfZmFpbHVyZTpnb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSkKKyAgcmV0dXJuIGZhbHNlOworI3VuZGVmIERPXworfQorCit2b2lkIEludDY0VmFsdWU6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUpCisgIC8vIG9wdGlvbmFsIGludDY0IHZhbHVlID0gMTsKKyAgaWYgKHRoaXMtPnZhbHVlKCkgIT0gMCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUludDY0KDEsIHRoaXMtPnZhbHVlKCksIG91dHB1dCk7CisgIH0KKworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX2VuZDpnb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSkKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogSW50NjRWYWx1ZTo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiB0YXJnZXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9zdGFydDpnb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSkKKyAgLy8gb3B0aW9uYWwgaW50NjQgdmFsdWUgPSAxOworICBpZiAodGhpcy0+dmFsdWUoKSAhPSAwKSB7CisgICAgdGFyZ2V0ID0gOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlSW50NjRUb0FycmF5KDEsIHRoaXMtPnZhbHVlKCksIHRhcmdldCk7CisgIH0KKworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X2VuZDpnb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSkKKyAgcmV0dXJuIHRhcmdldDsKK30KKworaW50IEludDY0VmFsdWU6OkJ5dGVTaXplKCkgY29uc3QgeworICBpbnQgdG90YWxfc2l6ZSA9IDA7CisKKyAgLy8gb3B0aW9uYWwgaW50NjQgdmFsdWUgPSAxOworICBpZiAodGhpcy0+dmFsdWUoKSAhPSAwKSB7CisgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpJbnQ2NFNpemUoCisgICAgICAgIHRoaXMtPnZhbHVlKCkpOworICB9CisKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHRvdGFsX3NpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworICByZXR1cm4gdG90YWxfc2l6ZTsKK30KKwordm9pZCBJbnQ2NFZhbHVlOjpNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGNvbnN0IEludDY0VmFsdWUqIHNvdXJjZSA9IAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RHluYW1pY0Nhc3RUb0dlbmVyYXRlZDxjb25zdCBJbnQ2NFZhbHVlPigKKyAgICAgICAgICAmZnJvbSk7CisgIGlmIChzb3VyY2UgPT0gTlVMTCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlJlZmxlY3Rpb25PcHM6Ok1lcmdlKGZyb20sIHRoaXMpOworICB9IGVsc2UgeworICAgIE1lcmdlRnJvbSgqc291cmNlKTsKKyAgfQorfQorCit2b2lkIEludDY0VmFsdWU6Ok1lcmdlRnJvbShjb25zdCBJbnQ2NFZhbHVlJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGlmIChmcm9tLnZhbHVlKCkgIT0gMCkgeworICAgIHNldF92YWx1ZShmcm9tLnZhbHVlKCkpOworICB9Cit9CisKK3ZvaWQgSW50NjRWYWx1ZTo6Q29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKwordm9pZCBJbnQ2NFZhbHVlOjpDb3B5RnJvbShjb25zdCBJbnQ2NFZhbHVlJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKworYm9vbCBJbnQ2NFZhbHVlOjpJc0luaXRpYWxpemVkKCkgY29uc3QgeworCisgIHJldHVybiB0cnVlOworfQorCit2b2lkIEludDY0VmFsdWU6OlN3YXAoSW50NjRWYWx1ZSogb3RoZXIpIHsKKyAgaWYgKG90aGVyID09IHRoaXMpIHJldHVybjsKKyAgaWYgKEdldEFyZW5hTm9WaXJ0dWFsKCkgPT0gb3RoZXItPkdldEFyZW5hTm9WaXJ0dWFsKCkpIHsKKyAgICBJbnRlcm5hbFN3YXAob3RoZXIpOworICB9IGVsc2UgeworICAgIEludDY0VmFsdWUgdGVtcDsKKyAgICB0ZW1wLk1lcmdlRnJvbSgqdGhpcyk7CisgICAgQ29weUZyb20oKm90aGVyKTsKKyAgICBvdGhlci0+Q29weUZyb20odGVtcCk7CisgIH0KK30KK3ZvaWQgSW50NjRWYWx1ZTo6VW5zYWZlQXJlbmFTd2FwKEludDY0VmFsdWUqIG90aGVyKSB7CisgIGlmIChvdGhlciA9PSB0aGlzKSByZXR1cm47CisgIEdPT0dMRV9EQ0hFQ0soR2V0QXJlbmFOb1ZpcnR1YWwoKSA9PSBvdGhlci0+R2V0QXJlbmFOb1ZpcnR1YWwoKSk7CisgIEludGVybmFsU3dhcChvdGhlcik7Cit9Cit2b2lkIEludDY0VmFsdWU6OkludGVybmFsU3dhcChJbnQ2NFZhbHVlKiBvdGhlcikgeworICBzdGQ6OnN3YXAodmFsdWVfLCBvdGhlci0+dmFsdWVfKTsKKyAgX2ludGVybmFsX21ldGFkYXRhXy5Td2FwKCZvdGhlci0+X2ludGVybmFsX21ldGFkYXRhXyk7CisgIHN0ZDo6c3dhcChfY2FjaGVkX3NpemVfLCBvdGhlci0+X2NhY2hlZF9zaXplXyk7Cit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgSW50NjRWYWx1ZTo6R2V0TWV0YWRhdGEoKSBjb25zdCB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIG1ldGFkYXRhOworICBtZXRhZGF0YS5kZXNjcmlwdG9yID0gSW50NjRWYWx1ZV9kZXNjcmlwdG9yXzsKKyAgbWV0YWRhdGEucmVmbGVjdGlvbiA9IEludDY0VmFsdWVfcmVmbGVjdGlvbl87CisgIHJldHVybiBtZXRhZGF0YTsKK30KKworI2lmIFBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworLy8gSW50NjRWYWx1ZQorCisvLyBvcHRpb25hbCBpbnQ2NCB2YWx1ZSA9IDE7Cit2b2lkIEludDY0VmFsdWU6OmNsZWFyX3ZhbHVlKCkgeworICB2YWx1ZV8gPSBHT09HTEVfTE9OR0xPTkcoMCk7Cit9CisgOjpnb29nbGU6OnByb3RvYnVmOjppbnQ2NCBJbnQ2NFZhbHVlOjp2YWx1ZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZS52YWx1ZSkKKyAgcmV0dXJuIHZhbHVlXzsKK30KKyB2b2lkIEludDY0VmFsdWU6OnNldF92YWx1ZSg6Omdvb2dsZTo6cHJvdG9idWY6OmludDY0IHZhbHVlKSB7CisgIAorICB2YWx1ZV8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZS52YWx1ZSkKK30KKworI2VuZGlmICAvLyBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisjaWYgIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKK2NvbnN0IGludCBVSW50NjRWYWx1ZTo6a1ZhbHVlRmllbGROdW1iZXI7CisjZW5kaWYgIC8vICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCisKK1VJbnQ2NFZhbHVlOjpVSW50NjRWYWx1ZSgpCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgeworICBTaGFyZWRDdG9yKCk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUpCit9CisKK1VJbnQ2NFZhbHVlOjpVSW50NjRWYWx1ZSg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwKKyAgX2ludGVybmFsX21ldGFkYXRhXyhhcmVuYSkgeworICBTaGFyZWRDdG9yKCk7CisgIFJlZ2lzdGVyQXJlbmFEdG9yKGFyZW5hKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGFyZW5hX2NvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSkKK30KKwordm9pZCBVSW50NjRWYWx1ZTo6SW5pdEFzRGVmYXVsdEluc3RhbmNlKCkgeworICBfaXNfZGVmYXVsdF9pbnN0YW5jZV8gPSB0cnVlOworfQorCitVSW50NjRWYWx1ZTo6VUludDY0VmFsdWUoY29uc3QgVUludDY0VmFsdWUmIGZyb20pCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksCisgICAgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29weV9jb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUpCit9CisKK3ZvaWQgVUludDY0VmFsdWU6OlNoYXJlZEN0b3IoKSB7CisgICAgX2lzX2RlZmF1bHRfaW5zdGFuY2VfID0gZmFsc2U7CisgIF9jYWNoZWRfc2l6ZV8gPSAwOworICB2YWx1ZV8gPSBHT09HTEVfVUxPTkdMT05HKDApOworfQorCitVSW50NjRWYWx1ZTo6flVJbnQ2NFZhbHVlKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZGVzdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUpCisgIFNoYXJlZER0b3IoKTsKK30KKwordm9pZCBVSW50NjRWYWx1ZTo6U2hhcmVkRHRvcigpIHsKKyAgaWYgKEdldEFyZW5hTm9WaXJ0dWFsKCkgIT0gTlVMTCkgeworICAgIHJldHVybjsKKyAgfQorCisgIGlmICh0aGlzICE9IGRlZmF1bHRfaW5zdGFuY2VfKSB7CisgIH0KK30KKwordm9pZCBVSW50NjRWYWx1ZTo6QXJlbmFEdG9yKHZvaWQqIG9iamVjdCkgeworICBVSW50NjRWYWx1ZSogX3RoaXMgPSByZWludGVycHJldF9jYXN0PCBVSW50NjRWYWx1ZSogPihvYmplY3QpOworICAodm9pZClfdGhpczsKK30KK3ZvaWQgVUludDY0VmFsdWU6OlJlZ2lzdGVyQXJlbmFEdG9yKDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSB7Cit9Cit2b2lkIFVJbnQ2NFZhbHVlOjpTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdCB7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSBzaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogVUludDY0VmFsdWU6OmRlc2NyaXB0b3IoKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICByZXR1cm4gVUludDY0VmFsdWVfZGVzY3JpcHRvcl87Cit9CisKK2NvbnN0IFVJbnQ2NFZhbHVlJiBVSW50NjRWYWx1ZTo6ZGVmYXVsdF9pbnN0YW5jZSgpIHsKKyAgaWYgKGRlZmF1bHRfaW5zdGFuY2VfID09IE5VTEwpIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZ3cmFwcGVyc18yZXByb3RvKCk7CisgIHJldHVybiAqZGVmYXVsdF9pbnN0YW5jZV87Cit9CisKK1VJbnQ2NFZhbHVlKiBVSW50NjRWYWx1ZTo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBOVUxMOworCitVSW50NjRWYWx1ZSogVUludDY0VmFsdWU6Ok5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3QgeworICByZXR1cm4gOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYTo6Q3JlYXRlTWVzc2FnZTxVSW50NjRWYWx1ZT4oYXJlbmEpOworfQorCit2b2lkIFVJbnQ2NFZhbHVlOjpDbGVhcigpIHsKKyAgdmFsdWVfID0gR09PR0xFX1VMT05HTE9ORygwKTsKK30KKworYm9vbCBVSW50NjRWYWx1ZTo6TWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KSB7CisjZGVmaW5lIERPXyhFWFBSRVNTSU9OKSBpZiAoIShFWFBSRVNTSU9OKSkgZ290byBmYWlsdXJlCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIHRhZzsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSkKKyAgZm9yICg7OykgeworICAgIDo6c3RkOjpwYWlyPCA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiwgYm9vbD4gcCA9IGlucHV0LT5SZWFkVGFnV2l0aEN1dG9mZigxMjcpOworICAgIHRhZyA9IHAuZmlyc3Q7CisgICAgaWYgKCFwLnNlY29uZCkgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICBzd2l0Y2ggKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdGaWVsZE51bWJlcih0YWcpKSB7CisgICAgICAvLyBvcHRpb25hbCB1aW50NjQgdmFsdWUgPSAxOworICAgICAgY2FzZSAxOiB7CisgICAgICAgIGlmICh0YWcgPT0gOCkgeworICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50NjQsIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpUWVBFX1VJTlQ2ND4oCisgICAgICAgICAgICAgICAgIGlucHV0LCAmdmFsdWVfKSkpOworCisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICAgICAgfQorICAgICAgICBpZiAoaW5wdXQtPkV4cGVjdEF0RW5kKCkpIGdvdG8gc3VjY2VzczsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICAgIGRlZmF1bHQ6IHsKKyAgICAgIGhhbmRsZV91bnVzdWFsOgorICAgICAgICBpZiAodGFnID09IDAgfHwKKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdXaXJlVHlwZSh0YWcpID09CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V0lSRVRZUEVfRU5EX0dST1VQKSB7CisgICAgICAgICAgZ290byBzdWNjZXNzOworICAgICAgICB9CisgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6U2tpcEZpZWxkKGlucHV0LCB0YWcpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CitzdWNjZXNzOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3VjY2Vzczpnb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUpCisgIHJldHVybiB0cnVlOworZmFpbHVyZToKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX2ZhaWx1cmU6Z29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlKQorICByZXR1cm4gZmFsc2U7CisjdW5kZWYgRE9fCit9CisKK3ZvaWQgVUludDY0VmFsdWU6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlKQorICAvLyBvcHRpb25hbCB1aW50NjQgdmFsdWUgPSAxOworICBpZiAodGhpcy0+dmFsdWUoKSAhPSAwKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlVUludDY0KDEsIHRoaXMtPnZhbHVlKCksIG91dHB1dCk7CisgIH0KKworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX2VuZDpnb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUpCit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIFVJbnQ2NFZhbHVlOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIHRhcmdldCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSkKKyAgLy8gb3B0aW9uYWwgdWludDY0IHZhbHVlID0gMTsKKyAgaWYgKHRoaXMtPnZhbHVlKCkgIT0gMCkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVVJbnQ2NFRvQXJyYXkoMSwgdGhpcy0+dmFsdWUoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfZW5kOmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSkKKyAgcmV0dXJuIHRhcmdldDsKK30KKworaW50IFVJbnQ2NFZhbHVlOjpCeXRlU2l6ZSgpIGNvbnN0IHsKKyAgaW50IHRvdGFsX3NpemUgPSAwOworCisgIC8vIG9wdGlvbmFsIHVpbnQ2NCB2YWx1ZSA9IDE7CisgIGlmICh0aGlzLT52YWx1ZSgpICE9IDApIHsKKyAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlVJbnQ2NFNpemUoCisgICAgICAgIHRoaXMtPnZhbHVlKCkpOworICB9CisKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHRvdGFsX3NpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworICByZXR1cm4gdG90YWxfc2l6ZTsKK30KKwordm9pZCBVSW50NjRWYWx1ZTo6TWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBjb25zdCBVSW50NjRWYWx1ZSogc291cmNlID0gCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpEeW5hbWljQ2FzdFRvR2VuZXJhdGVkPGNvbnN0IFVJbnQ2NFZhbHVlPigKKyAgICAgICAgICAmZnJvbSk7CisgIGlmIChzb3VyY2UgPT0gTlVMTCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlJlZmxlY3Rpb25PcHM6Ok1lcmdlKGZyb20sIHRoaXMpOworICB9IGVsc2UgeworICAgIE1lcmdlRnJvbSgqc291cmNlKTsKKyAgfQorfQorCit2b2lkIFVJbnQ2NFZhbHVlOjpNZXJnZUZyb20oY29uc3QgVUludDY0VmFsdWUmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgaWYgKGZyb20udmFsdWUoKSAhPSAwKSB7CisgICAgc2V0X3ZhbHVlKGZyb20udmFsdWUoKSk7CisgIH0KK30KKwordm9pZCBVSW50NjRWYWx1ZTo6Q29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKwordm9pZCBVSW50NjRWYWx1ZTo6Q29weUZyb20oY29uc3QgVUludDY0VmFsdWUmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCitib29sIFVJbnQ2NFZhbHVlOjpJc0luaXRpYWxpemVkKCkgY29uc3QgeworCisgIHJldHVybiB0cnVlOworfQorCit2b2lkIFVJbnQ2NFZhbHVlOjpTd2FwKFVJbnQ2NFZhbHVlKiBvdGhlcikgeworICBpZiAob3RoZXIgPT0gdGhpcykgcmV0dXJuOworICBpZiAoR2V0QXJlbmFOb1ZpcnR1YWwoKSA9PSBvdGhlci0+R2V0QXJlbmFOb1ZpcnR1YWwoKSkgeworICAgIEludGVybmFsU3dhcChvdGhlcik7CisgIH0gZWxzZSB7CisgICAgVUludDY0VmFsdWUgdGVtcDsKKyAgICB0ZW1wLk1lcmdlRnJvbSgqdGhpcyk7CisgICAgQ29weUZyb20oKm90aGVyKTsKKyAgICBvdGhlci0+Q29weUZyb20odGVtcCk7CisgIH0KK30KK3ZvaWQgVUludDY0VmFsdWU6OlVuc2FmZUFyZW5hU3dhcChVSW50NjRWYWx1ZSogb3RoZXIpIHsKKyAgaWYgKG90aGVyID09IHRoaXMpIHJldHVybjsKKyAgR09PR0xFX0RDSEVDSyhHZXRBcmVuYU5vVmlydHVhbCgpID09IG90aGVyLT5HZXRBcmVuYU5vVmlydHVhbCgpKTsKKyAgSW50ZXJuYWxTd2FwKG90aGVyKTsKK30KK3ZvaWQgVUludDY0VmFsdWU6OkludGVybmFsU3dhcChVSW50NjRWYWx1ZSogb3RoZXIpIHsKKyAgc3RkOjpzd2FwKHZhbHVlXywgb3RoZXItPnZhbHVlXyk7CisgIF9pbnRlcm5hbF9tZXRhZGF0YV8uU3dhcCgmb3RoZXItPl9pbnRlcm5hbF9tZXRhZGF0YV8pOworICBzdGQ6OnN3YXAoX2NhY2hlZF9zaXplXywgb3RoZXItPl9jYWNoZWRfc2l6ZV8pOworfQorCis6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIFVJbnQ2NFZhbHVlOjpHZXRNZXRhZGF0YSgpIGNvbnN0IHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgbWV0YWRhdGE7CisgIG1ldGFkYXRhLmRlc2NyaXB0b3IgPSBVSW50NjRWYWx1ZV9kZXNjcmlwdG9yXzsKKyAgbWV0YWRhdGEucmVmbGVjdGlvbiA9IFVJbnQ2NFZhbHVlX3JlZmxlY3Rpb25fOworICByZXR1cm4gbWV0YWRhdGE7Cit9CisKKyNpZiBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKy8vIFVJbnQ2NFZhbHVlCisKKy8vIG9wdGlvbmFsIHVpbnQ2NCB2YWx1ZSA9IDE7Cit2b2lkIFVJbnQ2NFZhbHVlOjpjbGVhcl92YWx1ZSgpIHsKKyAgdmFsdWVfID0gR09PR0xFX1VMT05HTE9ORygwKTsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ2NCBVSW50NjRWYWx1ZTo6dmFsdWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlLnZhbHVlKQorICByZXR1cm4gdmFsdWVfOworfQorIHZvaWQgVUludDY0VmFsdWU6OnNldF92YWx1ZSg6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ2NCB2YWx1ZSkgeworICAKKyAgdmFsdWVfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlLnZhbHVlKQorfQorCisjZW5kaWYgIC8vIFBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKyNpZiAhZGVmaW5lZChfTVNDX1ZFUikgfHwgX01TQ19WRVIgPj0gMTkwMAorY29uc3QgaW50IEludDMyVmFsdWU6OmtWYWx1ZUZpZWxkTnVtYmVyOworI2VuZGlmICAvLyAhZGVmaW5lZChfTVNDX1ZFUikgfHwgX01TQ19WRVIgPj0gMTkwMAorCitJbnQzMlZhbHVlOjpJbnQzMlZhbHVlKCkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlKQorfQorCitJbnQzMlZhbHVlOjpJbnQzMlZhbHVlKDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpLAorICBfaW50ZXJuYWxfbWV0YWRhdGFfKGFyZW5hKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgUmVnaXN0ZXJBcmVuYUR0b3IoYXJlbmEpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYXJlbmFfY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUpCit9CisKK3ZvaWQgSW50MzJWYWx1ZTo6SW5pdEFzRGVmYXVsdEluc3RhbmNlKCkgeworICBfaXNfZGVmYXVsdF9pbnN0YW5jZV8gPSB0cnVlOworfQorCitJbnQzMlZhbHVlOjpJbnQzMlZhbHVlKGNvbnN0IEludDMyVmFsdWUmIGZyb20pCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksCisgICAgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29weV9jb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSkKK30KKwordm9pZCBJbnQzMlZhbHVlOjpTaGFyZWRDdG9yKCkgeworICAgIF9pc19kZWZhdWx0X2luc3RhbmNlXyA9IGZhbHNlOworICBfY2FjaGVkX3NpemVfID0gMDsKKyAgdmFsdWVfID0gMDsKK30KKworSW50MzJWYWx1ZTo6fkludDMyVmFsdWUoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChkZXN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlKQorICBTaGFyZWREdG9yKCk7Cit9CisKK3ZvaWQgSW50MzJWYWx1ZTo6U2hhcmVkRHRvcigpIHsKKyAgaWYgKEdldEFyZW5hTm9WaXJ0dWFsKCkgIT0gTlVMTCkgeworICAgIHJldHVybjsKKyAgfQorCisgIGlmICh0aGlzICE9IGRlZmF1bHRfaW5zdGFuY2VfKSB7CisgIH0KK30KKwordm9pZCBJbnQzMlZhbHVlOjpBcmVuYUR0b3Iodm9pZCogb2JqZWN0KSB7CisgIEludDMyVmFsdWUqIF90aGlzID0gcmVpbnRlcnByZXRfY2FzdDwgSW50MzJWYWx1ZSogPihvYmplY3QpOworICAodm9pZClfdGhpczsKK30KK3ZvaWQgSW50MzJWYWx1ZTo6UmVnaXN0ZXJBcmVuYUR0b3IoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIHsKK30KK3ZvaWQgSW50MzJWYWx1ZTo6U2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3QgeworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIEludDMyVmFsdWU6OmRlc2NyaXB0b3IoKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICByZXR1cm4gSW50MzJWYWx1ZV9kZXNjcmlwdG9yXzsKK30KKworY29uc3QgSW50MzJWYWx1ZSYgSW50MzJWYWx1ZTo6ZGVmYXVsdF9pbnN0YW5jZSgpIHsKKyAgaWYgKGRlZmF1bHRfaW5zdGFuY2VfID09IE5VTEwpIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZ3cmFwcGVyc18yZXByb3RvKCk7CisgIHJldHVybiAqZGVmYXVsdF9pbnN0YW5jZV87Cit9CisKK0ludDMyVmFsdWUqIEludDMyVmFsdWU6OmRlZmF1bHRfaW5zdGFuY2VfID0gTlVMTDsKKworSW50MzJWYWx1ZSogSW50MzJWYWx1ZTo6TmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdCB7CisgIHJldHVybiA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hOjpDcmVhdGVNZXNzYWdlPEludDMyVmFsdWU+KGFyZW5hKTsKK30KKwordm9pZCBJbnQzMlZhbHVlOjpDbGVhcigpIHsKKyAgdmFsdWVfID0gMDsKK30KKworYm9vbCBJbnQzMlZhbHVlOjpNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpIHsKKyNkZWZpbmUgRE9fKEVYUFJFU1NJT04pIGlmICghKEVYUFJFU1NJT04pKSBnb3RvIGZhaWx1cmUKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgdGFnOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2Vfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUpCisgIGZvciAoOzspIHsKKyAgICA6OnN0ZDo6cGFpcjwgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIsIGJvb2w+IHAgPSBpbnB1dC0+UmVhZFRhZ1dpdGhDdXRvZmYoMTI3KTsKKyAgICB0YWcgPSBwLmZpcnN0OworICAgIGlmICghcC5zZWNvbmQpIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgc3dpdGNoICg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnRmllbGROdW1iZXIodGFnKSkgeworICAgICAgLy8gb3B0aW9uYWwgaW50MzIgdmFsdWUgPSAxOworICAgICAgY2FzZSAxOiB7CisgICAgICAgIGlmICh0YWcgPT0gOCkgeworICAgICAgICAgIERPXygoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRQcmltaXRpdmU8CisgICAgICAgICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiwgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlRZUEVfSU5UMzI+KAorICAgICAgICAgICAgICAgICBpbnB1dCwgJnZhbHVlXykpKTsKKworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RBdEVuZCgpKSBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBkZWZhdWx0OiB7CisgICAgICBoYW5kbGVfdW51c3VhbDoKKyAgICAgICAgaWYgKHRhZyA9PSAwIHx8CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnV2lyZVR5cGUodGFnKSA9PQorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0VORF9HUk9VUCkgeworICAgICAgICAgIGdvdG8gc3VjY2VzczsKKyAgICAgICAgfQorICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlNraXBGaWVsZChpbnB1dCwgdGFnKSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgfQorc3VjY2VzczoKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N1Y2Nlc3M6Z29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUpCisgIHJldHVybiB0cnVlOworZmFpbHVyZToKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX2ZhaWx1cmU6Z29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUpCisgIHJldHVybiBmYWxzZTsKKyN1bmRlZiBET18KK30KKwordm9pZCBJbnQzMlZhbHVlOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlKQorICAvLyBvcHRpb25hbCBpbnQzMiB2YWx1ZSA9IDE7CisgIGlmICh0aGlzLT52YWx1ZSgpICE9IDApIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVJbnQzMigxLCB0aGlzLT52YWx1ZSgpLCBvdXRwdXQpOworICB9CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9lbmQ6Z29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUpCit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIEludDMyVmFsdWU6OlNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogdGFyZ2V0KSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfc3RhcnQ6Z29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUpCisgIC8vIG9wdGlvbmFsIGludDMyIHZhbHVlID0gMTsKKyAgaWYgKHRoaXMtPnZhbHVlKCkgIT0gMCkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUludDMyVG9BcnJheSgxLCB0aGlzLT52YWx1ZSgpLCB0YXJnZXQpOworICB9CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9lbmQ6Z29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUpCisgIHJldHVybiB0YXJnZXQ7Cit9CisKK2ludCBJbnQzMlZhbHVlOjpCeXRlU2l6ZSgpIGNvbnN0IHsKKyAgaW50IHRvdGFsX3NpemUgPSAwOworCisgIC8vIG9wdGlvbmFsIGludDMyIHZhbHVlID0gMTsKKyAgaWYgKHRoaXMtPnZhbHVlKCkgIT0gMCkgeworICAgIHRvdGFsX3NpemUgKz0gMSArCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6SW50MzJTaXplKAorICAgICAgICB0aGlzLT52YWx1ZSgpKTsKKyAgfQorCisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSB0b3RhbF9zaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKKyAgcmV0dXJuIHRvdGFsX3NpemU7Cit9CisKK3ZvaWQgSW50MzJWYWx1ZTo6TWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBjb25zdCBJbnQzMlZhbHVlKiBzb3VyY2UgPSAKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkR5bmFtaWNDYXN0VG9HZW5lcmF0ZWQ8Y29uc3QgSW50MzJWYWx1ZT4oCisgICAgICAgICAgJmZyb20pOworICBpZiAoc291cmNlID09IE5VTEwpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpSZWZsZWN0aW9uT3BzOjpNZXJnZShmcm9tLCB0aGlzKTsKKyAgfSBlbHNlIHsKKyAgICBNZXJnZUZyb20oKnNvdXJjZSk7CisgIH0KK30KKwordm9pZCBJbnQzMlZhbHVlOjpNZXJnZUZyb20oY29uc3QgSW50MzJWYWx1ZSYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBpZiAoZnJvbS52YWx1ZSgpICE9IDApIHsKKyAgICBzZXRfdmFsdWUoZnJvbS52YWx1ZSgpKTsKKyAgfQorfQorCit2b2lkIEludDMyVmFsdWU6OkNvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK3ZvaWQgSW50MzJWYWx1ZTo6Q29weUZyb20oY29uc3QgSW50MzJWYWx1ZSYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK2Jvb2wgSW50MzJWYWx1ZTo6SXNJbml0aWFsaXplZCgpIGNvbnN0IHsKKworICByZXR1cm4gdHJ1ZTsKK30KKwordm9pZCBJbnQzMlZhbHVlOjpTd2FwKEludDMyVmFsdWUqIG90aGVyKSB7CisgIGlmIChvdGhlciA9PSB0aGlzKSByZXR1cm47CisgIGlmIChHZXRBcmVuYU5vVmlydHVhbCgpID09IG90aGVyLT5HZXRBcmVuYU5vVmlydHVhbCgpKSB7CisgICAgSW50ZXJuYWxTd2FwKG90aGVyKTsKKyAgfSBlbHNlIHsKKyAgICBJbnQzMlZhbHVlIHRlbXA7CisgICAgdGVtcC5NZXJnZUZyb20oKnRoaXMpOworICAgIENvcHlGcm9tKCpvdGhlcik7CisgICAgb3RoZXItPkNvcHlGcm9tKHRlbXApOworICB9Cit9Cit2b2lkIEludDMyVmFsdWU6OlVuc2FmZUFyZW5hU3dhcChJbnQzMlZhbHVlKiBvdGhlcikgeworICBpZiAob3RoZXIgPT0gdGhpcykgcmV0dXJuOworICBHT09HTEVfRENIRUNLKEdldEFyZW5hTm9WaXJ0dWFsKCkgPT0gb3RoZXItPkdldEFyZW5hTm9WaXJ0dWFsKCkpOworICBJbnRlcm5hbFN3YXAob3RoZXIpOworfQordm9pZCBJbnQzMlZhbHVlOjpJbnRlcm5hbFN3YXAoSW50MzJWYWx1ZSogb3RoZXIpIHsKKyAgc3RkOjpzd2FwKHZhbHVlXywgb3RoZXItPnZhbHVlXyk7CisgIF9pbnRlcm5hbF9tZXRhZGF0YV8uU3dhcCgmb3RoZXItPl9pbnRlcm5hbF9tZXRhZGF0YV8pOworICBzdGQ6OnN3YXAoX2NhY2hlZF9zaXplXywgb3RoZXItPl9jYWNoZWRfc2l6ZV8pOworfQorCis6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEludDMyVmFsdWU6OkdldE1ldGFkYXRhKCkgY29uc3QgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBtZXRhZGF0YTsKKyAgbWV0YWRhdGEuZGVzY3JpcHRvciA9IEludDMyVmFsdWVfZGVzY3JpcHRvcl87CisgIG1ldGFkYXRhLnJlZmxlY3Rpb24gPSBJbnQzMlZhbHVlX3JlZmxlY3Rpb25fOworICByZXR1cm4gbWV0YWRhdGE7Cit9CisKKyNpZiBQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKy8vIEludDMyVmFsdWUKKworLy8gb3B0aW9uYWwgaW50MzIgdmFsdWUgPSAxOwordm9pZCBJbnQzMlZhbHVlOjpjbGVhcl92YWx1ZSgpIHsKKyAgdmFsdWVfID0gMDsKK30KKyA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIEludDMyVmFsdWU6OnZhbHVlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlLnZhbHVlKQorICByZXR1cm4gdmFsdWVfOworfQorIHZvaWQgSW50MzJWYWx1ZTo6c2V0X3ZhbHVlKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgdmFsdWUpIHsKKyAgCisgIHZhbHVlXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlLnZhbHVlKQorfQorCisjZW5kaWYgIC8vIFBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworCisvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKyNpZiAhZGVmaW5lZChfTVNDX1ZFUikgfHwgX01TQ19WRVIgPj0gMTkwMAorY29uc3QgaW50IFVJbnQzMlZhbHVlOjprVmFsdWVGaWVsZE51bWJlcjsKKyNlbmRpZiAgLy8gIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKKworVUludDMyVmFsdWU6OlVJbnQzMlZhbHVlKCkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSkKK30KKworVUludDMyVmFsdWU6OlVJbnQzMlZhbHVlKDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpLAorICBfaW50ZXJuYWxfbWV0YWRhdGFfKGFyZW5hKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgUmVnaXN0ZXJBcmVuYUR0b3IoYXJlbmEpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYXJlbmFfY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlKQorfQorCit2b2lkIFVJbnQzMlZhbHVlOjpJbml0QXNEZWZhdWx0SW5zdGFuY2UoKSB7CisgIF9pc19kZWZhdWx0X2luc3RhbmNlXyA9IHRydWU7Cit9CisKK1VJbnQzMlZhbHVlOjpVSW50MzJWYWx1ZShjb25zdCBVSW50MzJWYWx1ZSYgZnJvbSkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwKKyAgICBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICBNZXJnZUZyb20oZnJvbSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb3B5X2NvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSkKK30KKwordm9pZCBVSW50MzJWYWx1ZTo6U2hhcmVkQ3RvcigpIHsKKyAgICBfaXNfZGVmYXVsdF9pbnN0YW5jZV8gPSBmYWxzZTsKKyAgX2NhY2hlZF9zaXplXyA9IDA7CisgIHZhbHVlXyA9IDB1OworfQorCitVSW50MzJWYWx1ZTo6flVJbnQzMlZhbHVlKCkgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZGVzdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUpCisgIFNoYXJlZER0b3IoKTsKK30KKwordm9pZCBVSW50MzJWYWx1ZTo6U2hhcmVkRHRvcigpIHsKKyAgaWYgKEdldEFyZW5hTm9WaXJ0dWFsKCkgIT0gTlVMTCkgeworICAgIHJldHVybjsKKyAgfQorCisgIGlmICh0aGlzICE9IGRlZmF1bHRfaW5zdGFuY2VfKSB7CisgIH0KK30KKwordm9pZCBVSW50MzJWYWx1ZTo6QXJlbmFEdG9yKHZvaWQqIG9iamVjdCkgeworICBVSW50MzJWYWx1ZSogX3RoaXMgPSByZWludGVycHJldF9jYXN0PCBVSW50MzJWYWx1ZSogPihvYmplY3QpOworICAodm9pZClfdGhpczsKK30KK3ZvaWQgVUludDMyVmFsdWU6OlJlZ2lzdGVyQXJlbmFEdG9yKDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSB7Cit9Cit2b2lkIFVJbnQzMlZhbHVlOjpTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdCB7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSBzaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogVUludDMyVmFsdWU6OmRlc2NyaXB0b3IoKSB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICByZXR1cm4gVUludDMyVmFsdWVfZGVzY3JpcHRvcl87Cit9CisKK2NvbnN0IFVJbnQzMlZhbHVlJiBVSW50MzJWYWx1ZTo6ZGVmYXVsdF9pbnN0YW5jZSgpIHsKKyAgaWYgKGRlZmF1bHRfaW5zdGFuY2VfID09IE5VTEwpIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZ3cmFwcGVyc18yZXByb3RvKCk7CisgIHJldHVybiAqZGVmYXVsdF9pbnN0YW5jZV87Cit9CisKK1VJbnQzMlZhbHVlKiBVSW50MzJWYWx1ZTo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBOVUxMOworCitVSW50MzJWYWx1ZSogVUludDMyVmFsdWU6Ok5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3QgeworICByZXR1cm4gOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYTo6Q3JlYXRlTWVzc2FnZTxVSW50MzJWYWx1ZT4oYXJlbmEpOworfQorCit2b2lkIFVJbnQzMlZhbHVlOjpDbGVhcigpIHsKKyAgdmFsdWVfID0gMHU7Cit9CisKK2Jvb2wgVUludDMyVmFsdWU6Ok1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCkgeworI2RlZmluZSBET18oRVhQUkVTU0lPTikgaWYgKCEoRVhQUkVTU0lPTikpIGdvdG8gZmFpbHVyZQorICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiB0YWc7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdGFydDpnb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUpCisgIGZvciAoOzspIHsKKyAgICA6OnN0ZDo6cGFpcjwgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIsIGJvb2w+IHAgPSBpbnB1dC0+UmVhZFRhZ1dpdGhDdXRvZmYoMTI3KTsKKyAgICB0YWcgPSBwLmZpcnN0OworICAgIGlmICghcC5zZWNvbmQpIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgc3dpdGNoICg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnRmllbGROdW1iZXIodGFnKSkgeworICAgICAgLy8gb3B0aW9uYWwgdWludDMyIHZhbHVlID0gMTsKKyAgICAgIGNhc2UgMTogeworICAgICAgICBpZiAodGFnID09IDgpIHsKKyAgICAgICAgICBET18oKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkUHJpbWl0aXZlPAorICAgICAgICAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyLCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9VSU5UMzI+KAorICAgICAgICAgICAgICAgICBpbnB1dCwgJnZhbHVlXykpKTsKKworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RBdEVuZCgpKSBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBkZWZhdWx0OiB7CisgICAgICBoYW5kbGVfdW51c3VhbDoKKyAgICAgICAgaWYgKHRhZyA9PSAwIHx8CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnV2lyZVR5cGUodGFnKSA9PQorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0VORF9HUk9VUCkgeworICAgICAgICAgIGdvdG8gc3VjY2VzczsKKyAgICAgICAgfQorICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlNraXBGaWVsZChpbnB1dCwgdGFnKSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgfQorc3VjY2VzczoKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N1Y2Nlc3M6Z29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlKQorICByZXR1cm4gdHJ1ZTsKK2ZhaWx1cmU6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9mYWlsdXJlOmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSkKKyAgcmV0dXJuIGZhbHNlOworI3VuZGVmIERPXworfQorCit2b2lkIFVJbnQzMlZhbHVlOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSkKKyAgLy8gb3B0aW9uYWwgdWludDMyIHZhbHVlID0gMTsKKyAgaWYgKHRoaXMtPnZhbHVlKCkgIT0gMCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZVVJbnQzMigxLCB0aGlzLT52YWx1ZSgpLCBvdXRwdXQpOworICB9CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9lbmQ6Z29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlKQorfQorCis6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBVSW50MzJWYWx1ZTo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiB0YXJnZXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9zdGFydDpnb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUpCisgIC8vIG9wdGlvbmFsIHVpbnQzMiB2YWx1ZSA9IDE7CisgIGlmICh0aGlzLT52YWx1ZSgpICE9IDApIHsKKyAgICB0YXJnZXQgPSA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVVSW50MzJUb0FycmF5KDEsIHRoaXMtPnZhbHVlKCksIHRhcmdldCk7CisgIH0KKworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X2VuZDpnb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUpCisgIHJldHVybiB0YXJnZXQ7Cit9CisKK2ludCBVSW50MzJWYWx1ZTo6Qnl0ZVNpemUoKSBjb25zdCB7CisgIGludCB0b3RhbF9zaXplID0gMDsKKworICAvLyBvcHRpb25hbCB1aW50MzIgdmFsdWUgPSAxOworICBpZiAodGhpcy0+dmFsdWUoKSAhPSAwKSB7CisgICAgdG90YWxfc2l6ZSArPSAxICsKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpVSW50MzJTaXplKAorICAgICAgICB0aGlzLT52YWx1ZSgpKTsKKyAgfQorCisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSB0b3RhbF9zaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKKyAgcmV0dXJuIHRvdGFsX3NpemU7Cit9CisKK3ZvaWQgVUludDMyVmFsdWU6Ok1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgY29uc3QgVUludDMyVmFsdWUqIHNvdXJjZSA9IAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6RHluYW1pY0Nhc3RUb0dlbmVyYXRlZDxjb25zdCBVSW50MzJWYWx1ZT4oCisgICAgICAgICAgJmZyb20pOworICBpZiAoc291cmNlID09IE5VTEwpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpSZWZsZWN0aW9uT3BzOjpNZXJnZShmcm9tLCB0aGlzKTsKKyAgfSBlbHNlIHsKKyAgICBNZXJnZUZyb20oKnNvdXJjZSk7CisgIH0KK30KKwordm9pZCBVSW50MzJWYWx1ZTo6TWVyZ2VGcm9tKGNvbnN0IFVJbnQzMlZhbHVlJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGlmIChmcm9tLnZhbHVlKCkgIT0gMCkgeworICAgIHNldF92YWx1ZShmcm9tLnZhbHVlKCkpOworICB9Cit9CisKK3ZvaWQgVUludDMyVmFsdWU6OkNvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK3ZvaWQgVUludDMyVmFsdWU6OkNvcHlGcm9tKGNvbnN0IFVJbnQzMlZhbHVlJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKworYm9vbCBVSW50MzJWYWx1ZTo6SXNJbml0aWFsaXplZCgpIGNvbnN0IHsKKworICByZXR1cm4gdHJ1ZTsKK30KKwordm9pZCBVSW50MzJWYWx1ZTo6U3dhcChVSW50MzJWYWx1ZSogb3RoZXIpIHsKKyAgaWYgKG90aGVyID09IHRoaXMpIHJldHVybjsKKyAgaWYgKEdldEFyZW5hTm9WaXJ0dWFsKCkgPT0gb3RoZXItPkdldEFyZW5hTm9WaXJ0dWFsKCkpIHsKKyAgICBJbnRlcm5hbFN3YXAob3RoZXIpOworICB9IGVsc2UgeworICAgIFVJbnQzMlZhbHVlIHRlbXA7CisgICAgdGVtcC5NZXJnZUZyb20oKnRoaXMpOworICAgIENvcHlGcm9tKCpvdGhlcik7CisgICAgb3RoZXItPkNvcHlGcm9tKHRlbXApOworICB9Cit9Cit2b2lkIFVJbnQzMlZhbHVlOjpVbnNhZmVBcmVuYVN3YXAoVUludDMyVmFsdWUqIG90aGVyKSB7CisgIGlmIChvdGhlciA9PSB0aGlzKSByZXR1cm47CisgIEdPT0dMRV9EQ0hFQ0soR2V0QXJlbmFOb1ZpcnR1YWwoKSA9PSBvdGhlci0+R2V0QXJlbmFOb1ZpcnR1YWwoKSk7CisgIEludGVybmFsU3dhcChvdGhlcik7Cit9Cit2b2lkIFVJbnQzMlZhbHVlOjpJbnRlcm5hbFN3YXAoVUludDMyVmFsdWUqIG90aGVyKSB7CisgIHN0ZDo6c3dhcCh2YWx1ZV8sIG90aGVyLT52YWx1ZV8pOworICBfaW50ZXJuYWxfbWV0YWRhdGFfLlN3YXAoJm90aGVyLT5faW50ZXJuYWxfbWV0YWRhdGFfKTsKKyAgc3RkOjpzd2FwKF9jYWNoZWRfc2l6ZV8sIG90aGVyLT5fY2FjaGVkX3NpemVfKTsKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBVSW50MzJWYWx1ZTo6R2V0TWV0YWRhdGEoKSBjb25zdCB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIG1ldGFkYXRhOworICBtZXRhZGF0YS5kZXNjcmlwdG9yID0gVUludDMyVmFsdWVfZGVzY3JpcHRvcl87CisgIG1ldGFkYXRhLnJlZmxlY3Rpb24gPSBVSW50MzJWYWx1ZV9yZWZsZWN0aW9uXzsKKyAgcmV0dXJuIG1ldGFkYXRhOworfQorCisjaWYgUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisvLyBVSW50MzJWYWx1ZQorCisvLyBvcHRpb25hbCB1aW50MzIgdmFsdWUgPSAxOwordm9pZCBVSW50MzJWYWx1ZTo6Y2xlYXJfdmFsdWUoKSB7CisgIHZhbHVlXyA9IDB1OworfQorIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIFVJbnQzMlZhbHVlOjp2YWx1ZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUudmFsdWUpCisgIHJldHVybiB2YWx1ZV87Cit9Cisgdm9pZCBVSW50MzJWYWx1ZTo6c2V0X3ZhbHVlKDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIHZhbHVlKSB7CisgIAorICB2YWx1ZV8gPSB2YWx1ZTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUudmFsdWUpCit9CisKKyNlbmRpZiAgLy8gUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworI2lmICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCitjb25zdCBpbnQgQm9vbFZhbHVlOjprVmFsdWVGaWVsZE51bWJlcjsKKyNlbmRpZiAgLy8gIWRlZmluZWQoX01TQ19WRVIpIHx8IF9NU0NfVkVSID49IDE5MDAKKworQm9vbFZhbHVlOjpCb29sVmFsdWUoKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpLCBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSkKK30KKworQm9vbFZhbHVlOjpCb29sVmFsdWUoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksCisgIF9pbnRlcm5hbF9tZXRhZGF0YV8oYXJlbmEpIHsKKyAgU2hhcmVkQ3RvcigpOworICBSZWdpc3RlckFyZW5hRHRvcihhcmVuYSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChhcmVuYV9jb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuQm9vbFZhbHVlKQorfQorCit2b2lkIEJvb2xWYWx1ZTo6SW5pdEFzRGVmYXVsdEluc3RhbmNlKCkgeworICBfaXNfZGVmYXVsdF9pbnN0YW5jZV8gPSB0cnVlOworfQorCitCb29sVmFsdWU6OkJvb2xWYWx1ZShjb25zdCBCb29sVmFsdWUmIGZyb20pCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksCisgICAgX2ludGVybmFsX21ldGFkYXRhXyhOVUxMKSB7CisgIFNoYXJlZEN0b3IoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29weV9jb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuQm9vbFZhbHVlKQorfQorCit2b2lkIEJvb2xWYWx1ZTo6U2hhcmVkQ3RvcigpIHsKKyAgICBfaXNfZGVmYXVsdF9pbnN0YW5jZV8gPSBmYWxzZTsKKyAgX2NhY2hlZF9zaXplXyA9IDA7CisgIHZhbHVlXyA9IGZhbHNlOworfQorCitCb29sVmFsdWU6On5Cb29sVmFsdWUoKSB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChkZXN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUpCisgIFNoYXJlZER0b3IoKTsKK30KKwordm9pZCBCb29sVmFsdWU6OlNoYXJlZER0b3IoKSB7CisgIGlmIChHZXRBcmVuYU5vVmlydHVhbCgpICE9IE5VTEwpIHsKKyAgICByZXR1cm47CisgIH0KKworICBpZiAodGhpcyAhPSBkZWZhdWx0X2luc3RhbmNlXykgeworICB9Cit9CisKK3ZvaWQgQm9vbFZhbHVlOjpBcmVuYUR0b3Iodm9pZCogb2JqZWN0KSB7CisgIEJvb2xWYWx1ZSogX3RoaXMgPSByZWludGVycHJldF9jYXN0PCBCb29sVmFsdWUqID4ob2JqZWN0KTsKKyAgKHZvaWQpX3RoaXM7Cit9Cit2b2lkIEJvb2xWYWx1ZTo6UmVnaXN0ZXJBcmVuYUR0b3IoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIHsKK30KK3ZvaWQgQm9vbFZhbHVlOjpTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdCB7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSBzaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogQm9vbFZhbHVlOjpkZXNjcmlwdG9yKCkgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgcmV0dXJuIEJvb2xWYWx1ZV9kZXNjcmlwdG9yXzsKK30KKworY29uc3QgQm9vbFZhbHVlJiBCb29sVmFsdWU6OmRlZmF1bHRfaW5zdGFuY2UoKSB7CisgIGlmIChkZWZhdWx0X2luc3RhbmNlXyA9PSBOVUxMKSBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmd3JhcHBlcnNfMmVwcm90bygpOworICByZXR1cm4gKmRlZmF1bHRfaW5zdGFuY2VfOworfQorCitCb29sVmFsdWUqIEJvb2xWYWx1ZTo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBOVUxMOworCitCb29sVmFsdWUqIEJvb2xWYWx1ZTo6TmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdCB7CisgIHJldHVybiA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hOjpDcmVhdGVNZXNzYWdlPEJvb2xWYWx1ZT4oYXJlbmEpOworfQorCit2b2lkIEJvb2xWYWx1ZTo6Q2xlYXIoKSB7CisgIHZhbHVlXyA9IGZhbHNlOworfQorCitib29sIEJvb2xWYWx1ZTo6TWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KSB7CisjZGVmaW5lIERPXyhFWFBSRVNTSU9OKSBpZiAoIShFWFBSRVNTSU9OKSkgZ290byBmYWlsdXJlCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIHRhZzsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUpCisgIGZvciAoOzspIHsKKyAgICA6OnN0ZDo6cGFpcjwgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIsIGJvb2w+IHAgPSBpbnB1dC0+UmVhZFRhZ1dpdGhDdXRvZmYoMTI3KTsKKyAgICB0YWcgPSBwLmZpcnN0OworICAgIGlmICghcC5zZWNvbmQpIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgc3dpdGNoICg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnRmllbGROdW1iZXIodGFnKSkgeworICAgICAgLy8gb3B0aW9uYWwgYm9vbCB2YWx1ZSA9IDE7CisgICAgICBjYXNlIDE6IHsKKyAgICAgICAgaWYgKHRhZyA9PSA4KSB7CisgICAgICAgICAgRE9fKCg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6UmVhZFByaW1pdGl2ZTwKKyAgICAgICAgICAgICAgICAgICBib29sLCA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VFlQRV9CT09MPigKKyAgICAgICAgICAgICAgICAgaW5wdXQsICZ2YWx1ZV8pKSk7CisKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0QXRFbmQoKSkgZ290byBzdWNjZXNzOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgZGVmYXVsdDogeworICAgICAgaGFuZGxlX3VudXN1YWw6CisgICAgICAgIGlmICh0YWcgPT0gMCB8fAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ1dpcmVUeXBlKHRhZykgPT0KKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVApIHsKKyAgICAgICAgICBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIH0KKyAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTa2lwRmllbGQoaW5wdXQsIHRhZykpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KK3N1Y2Nlc3M6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdWNjZXNzOmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUpCisgIHJldHVybiB0cnVlOworZmFpbHVyZToKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX2ZhaWx1cmU6Z29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSkKKyAgcmV0dXJuIGZhbHNlOworI3VuZGVmIERPXworfQorCit2b2lkIEJvb2xWYWx1ZTo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9zdGFydDpnb29nbGUucHJvdG9idWYuQm9vbFZhbHVlKQorICAvLyBvcHRpb25hbCBib29sIHZhbHVlID0gMTsKKyAgaWYgKHRoaXMtPnZhbHVlKCkgIT0gMCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2woMSwgdGhpcy0+dmFsdWUoKSwgb3V0cHV0KTsKKyAgfQorCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfZW5kOmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUpCit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIEJvb2xWYWx1ZTo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiB0YXJnZXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9zdGFydDpnb29nbGUucHJvdG9idWYuQm9vbFZhbHVlKQorICAvLyBvcHRpb25hbCBib29sIHZhbHVlID0gMTsKKyAgaWYgKHRoaXMtPnZhbHVlKCkgIT0gMCkgeworICAgIHRhcmdldCA9IDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJvb2xUb0FycmF5KDEsIHRoaXMtPnZhbHVlKCksIHRhcmdldCk7CisgIH0KKworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3RvX2FycmF5X2VuZDpnb29nbGUucHJvdG9idWYuQm9vbFZhbHVlKQorICByZXR1cm4gdGFyZ2V0OworfQorCitpbnQgQm9vbFZhbHVlOjpCeXRlU2l6ZSgpIGNvbnN0IHsKKyAgaW50IHRvdGFsX3NpemUgPSAwOworCisgIC8vIG9wdGlvbmFsIGJvb2wgdmFsdWUgPSAxOworICBpZiAodGhpcy0+dmFsdWUoKSAhPSAwKSB7CisgICAgdG90YWxfc2l6ZSArPSAxICsgMTsKKyAgfQorCisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSB0b3RhbF9zaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKKyAgcmV0dXJuIHRvdGFsX3NpemU7Cit9CisKK3ZvaWQgQm9vbFZhbHVlOjpNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmIChHT09HTEVfUFJFRElDVF9GQUxTRSgmZnJvbSA9PSB0aGlzKSkgTWVyZ2VGcm9tRmFpbChfX0xJTkVfXyk7CisgIGNvbnN0IEJvb2xWYWx1ZSogc291cmNlID0gCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpEeW5hbWljQ2FzdFRvR2VuZXJhdGVkPGNvbnN0IEJvb2xWYWx1ZT4oCisgICAgICAgICAgJmZyb20pOworICBpZiAoc291cmNlID09IE5VTEwpIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpSZWZsZWN0aW9uT3BzOjpNZXJnZShmcm9tLCB0aGlzKTsKKyAgfSBlbHNlIHsKKyAgICBNZXJnZUZyb20oKnNvdXJjZSk7CisgIH0KK30KKwordm9pZCBCb29sVmFsdWU6Ok1lcmdlRnJvbShjb25zdCBCb29sVmFsdWUmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgaWYgKGZyb20udmFsdWUoKSAhPSAwKSB7CisgICAgc2V0X3ZhbHVlKGZyb20udmFsdWUoKSk7CisgIH0KK30KKwordm9pZCBCb29sVmFsdWU6OkNvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoJmZyb20gPT0gdGhpcykgcmV0dXJuOworICBDbGVhcigpOworICBNZXJnZUZyb20oZnJvbSk7Cit9CisKK3ZvaWQgQm9vbFZhbHVlOjpDb3B5RnJvbShjb25zdCBCb29sVmFsdWUmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCitib29sIEJvb2xWYWx1ZTo6SXNJbml0aWFsaXplZCgpIGNvbnN0IHsKKworICByZXR1cm4gdHJ1ZTsKK30KKwordm9pZCBCb29sVmFsdWU6OlN3YXAoQm9vbFZhbHVlKiBvdGhlcikgeworICBpZiAob3RoZXIgPT0gdGhpcykgcmV0dXJuOworICBpZiAoR2V0QXJlbmFOb1ZpcnR1YWwoKSA9PSBvdGhlci0+R2V0QXJlbmFOb1ZpcnR1YWwoKSkgeworICAgIEludGVybmFsU3dhcChvdGhlcik7CisgIH0gZWxzZSB7CisgICAgQm9vbFZhbHVlIHRlbXA7CisgICAgdGVtcC5NZXJnZUZyb20oKnRoaXMpOworICAgIENvcHlGcm9tKCpvdGhlcik7CisgICAgb3RoZXItPkNvcHlGcm9tKHRlbXApOworICB9Cit9Cit2b2lkIEJvb2xWYWx1ZTo6VW5zYWZlQXJlbmFTd2FwKEJvb2xWYWx1ZSogb3RoZXIpIHsKKyAgaWYgKG90aGVyID09IHRoaXMpIHJldHVybjsKKyAgR09PR0xFX0RDSEVDSyhHZXRBcmVuYU5vVmlydHVhbCgpID09IG90aGVyLT5HZXRBcmVuYU5vVmlydHVhbCgpKTsKKyAgSW50ZXJuYWxTd2FwKG90aGVyKTsKK30KK3ZvaWQgQm9vbFZhbHVlOjpJbnRlcm5hbFN3YXAoQm9vbFZhbHVlKiBvdGhlcikgeworICBzdGQ6OnN3YXAodmFsdWVfLCBvdGhlci0+dmFsdWVfKTsKKyAgX2ludGVybmFsX21ldGFkYXRhXy5Td2FwKCZvdGhlci0+X2ludGVybmFsX21ldGFkYXRhXyk7CisgIHN0ZDo6c3dhcChfY2FjaGVkX3NpemVfLCBvdGhlci0+X2NhY2hlZF9zaXplXyk7Cit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgQm9vbFZhbHVlOjpHZXRNZXRhZGF0YSgpIGNvbnN0IHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgbWV0YWRhdGE7CisgIG1ldGFkYXRhLmRlc2NyaXB0b3IgPSBCb29sVmFsdWVfZGVzY3JpcHRvcl87CisgIG1ldGFkYXRhLnJlZmxlY3Rpb24gPSBCb29sVmFsdWVfcmVmbGVjdGlvbl87CisgIHJldHVybiBtZXRhZGF0YTsKK30KKworI2lmIFBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworLy8gQm9vbFZhbHVlCisKKy8vIG9wdGlvbmFsIGJvb2wgdmFsdWUgPSAxOwordm9pZCBCb29sVmFsdWU6OmNsZWFyX3ZhbHVlKCkgeworICB2YWx1ZV8gPSBmYWxzZTsKK30KKyBib29sIEJvb2xWYWx1ZTo6dmFsdWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZS52YWx1ZSkKKyAgcmV0dXJuIHZhbHVlXzsKK30KKyB2b2lkIEJvb2xWYWx1ZTo6c2V0X3ZhbHVlKGJvb2wgdmFsdWUpIHsKKyAgCisgIHZhbHVlXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUudmFsdWUpCit9CisKKyNlbmRpZiAgLy8gUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworI2lmICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCitjb25zdCBpbnQgU3RyaW5nVmFsdWU6OmtWYWx1ZUZpZWxkTnVtYmVyOworI2VuZGlmICAvLyAhZGVmaW5lZChfTVNDX1ZFUikgfHwgX01TQ19WRVIgPj0gMTkwMAorCitTdHJpbmdWYWx1ZTo6U3RyaW5nVmFsdWUoKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpLCBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlKQorfQorCitTdHJpbmdWYWx1ZTo6U3RyaW5nVmFsdWUoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksCisgIF9pbnRlcm5hbF9tZXRhZGF0YV8oYXJlbmEpIHsKKyAgU2hhcmVkQ3RvcigpOworICBSZWdpc3RlckFyZW5hRHRvcihhcmVuYSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChhcmVuYV9jb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUpCit9CisKK3ZvaWQgU3RyaW5nVmFsdWU6OkluaXRBc0RlZmF1bHRJbnN0YW5jZSgpIHsKKyAgX2lzX2RlZmF1bHRfaW5zdGFuY2VfID0gdHJ1ZTsKK30KKworU3RyaW5nVmFsdWU6OlN0cmluZ1ZhbHVlKGNvbnN0IFN0cmluZ1ZhbHVlJiBmcm9tKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpLAorICAgIF9pbnRlcm5hbF9tZXRhZGF0YV8oTlVMTCkgeworICBTaGFyZWRDdG9yKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNvcHlfY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlKQorfQorCit2b2lkIFN0cmluZ1ZhbHVlOjpTaGFyZWRDdG9yKCkgeworICAgIF9pc19kZWZhdWx0X2luc3RhbmNlXyA9IGZhbHNlOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZygpOworICBfY2FjaGVkX3NpemVfID0gMDsKKyAgdmFsdWVfLlVuc2FmZVNldERlZmF1bHQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpKTsKK30KKworU3RyaW5nVmFsdWU6On5TdHJpbmdWYWx1ZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGRlc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlKQorICBTaGFyZWREdG9yKCk7Cit9CisKK3ZvaWQgU3RyaW5nVmFsdWU6OlNoYXJlZER0b3IoKSB7CisgIGlmIChHZXRBcmVuYU5vVmlydHVhbCgpICE9IE5VTEwpIHsKKyAgICByZXR1cm47CisgIH0KKworICB2YWx1ZV8uRGVzdHJveSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIEdldEFyZW5hTm9WaXJ0dWFsKCkpOworICBpZiAodGhpcyAhPSBkZWZhdWx0X2luc3RhbmNlXykgeworICB9Cit9CisKK3ZvaWQgU3RyaW5nVmFsdWU6OkFyZW5hRHRvcih2b2lkKiBvYmplY3QpIHsKKyAgU3RyaW5nVmFsdWUqIF90aGlzID0gcmVpbnRlcnByZXRfY2FzdDwgU3RyaW5nVmFsdWUqID4ob2JqZWN0KTsKKyAgKHZvaWQpX3RoaXM7Cit9Cit2b2lkIFN0cmluZ1ZhbHVlOjpSZWdpc3RlckFyZW5hRHRvcig6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgeworfQordm9pZCBTdHJpbmdWYWx1ZTo6U2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3QgeworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7Cit9Citjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIFN0cmluZ1ZhbHVlOjpkZXNjcmlwdG9yKCkgeworICBwcm90b2J1Zl9Bc3NpZ25EZXNjcmlwdG9yc09uY2UoKTsKKyAgcmV0dXJuIFN0cmluZ1ZhbHVlX2Rlc2NyaXB0b3JfOworfQorCitjb25zdCBTdHJpbmdWYWx1ZSYgU3RyaW5nVmFsdWU6OmRlZmF1bHRfaW5zdGFuY2UoKSB7CisgIGlmIChkZWZhdWx0X2luc3RhbmNlXyA9PSBOVUxMKSBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmd3JhcHBlcnNfMmVwcm90bygpOworICByZXR1cm4gKmRlZmF1bHRfaW5zdGFuY2VfOworfQorCitTdHJpbmdWYWx1ZSogU3RyaW5nVmFsdWU6OmRlZmF1bHRfaW5zdGFuY2VfID0gTlVMTDsKKworU3RyaW5nVmFsdWUqIFN0cmluZ1ZhbHVlOjpOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0IHsKKyAgcmV0dXJuIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmE6OkNyZWF0ZU1lc3NhZ2U8U3RyaW5nVmFsdWU+KGFyZW5hKTsKK30KKwordm9pZCBTdHJpbmdWYWx1ZTo6Q2xlYXIoKSB7CisgIHZhbHVlXy5DbGVhclRvRW1wdHkoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBHZXRBcmVuYU5vVmlydHVhbCgpKTsKK30KKworYm9vbCBTdHJpbmdWYWx1ZTo6TWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KSB7CisjZGVmaW5lIERPXyhFWFBSRVNTSU9OKSBpZiAoIShFWFBSRVNTSU9OKSkgZ290byBmYWlsdXJlCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIHRhZzsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSkKKyAgZm9yICg7OykgeworICAgIDo6c3RkOjpwYWlyPCA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQzMiwgYm9vbD4gcCA9IGlucHV0LT5SZWFkVGFnV2l0aEN1dG9mZigxMjcpOworICAgIHRhZyA9IHAuZmlyc3Q7CisgICAgaWYgKCFwLnNlY29uZCkgZ290byBoYW5kbGVfdW51c3VhbDsKKyAgICBzd2l0Y2ggKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpHZXRUYWdGaWVsZE51bWJlcih0YWcpKSB7CisgICAgICAvLyBvcHRpb25hbCBzdHJpbmcgdmFsdWUgPSAxOworICAgICAgY2FzZSAxOiB7CisgICAgICAgIGlmICh0YWcgPT0gMTApIHsKKyAgICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlJlYWRTdHJpbmcoCisgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPm11dGFibGVfdmFsdWUoKSkpOworICAgICAgICAgIERPXyg6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VmVyaWZ5VXRmOFN0cmluZygKKyAgICAgICAgICAgIHRoaXMtPnZhbHVlKCkuZGF0YSgpLCB0aGlzLT52YWx1ZSgpLmxlbmd0aCgpLAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlBBUlNFLAorICAgICAgICAgICAgImdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZS52YWx1ZSIpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgICAgICB9CisgICAgICAgIGlmIChpbnB1dC0+RXhwZWN0QXRFbmQoKSkgZ290byBzdWNjZXNzOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgZGVmYXVsdDogeworICAgICAgaGFuZGxlX3VudXN1YWw6CisgICAgICAgIGlmICh0YWcgPT0gMCB8fAorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ1dpcmVUeXBlKHRhZykgPT0KKyAgICAgICAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXSVJFVFlQRV9FTkRfR1JPVVApIHsKKyAgICAgICAgICBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIH0KKyAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpTa2lwRmllbGQoaW5wdXQsIHRhZykpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KK3N1Y2Nlc3M6CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChwYXJzZV9zdWNjZXNzOmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSkKKyAgcmV0dXJuIHRydWU7CitmYWlsdXJlOgorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQocGFyc2VfZmFpbHVyZTpnb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUpCisgIHJldHVybiBmYWxzZTsKKyN1bmRlZiBET18KK30KKwordm9pZCBTdHJpbmdWYWx1ZTo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9zdGFydDpnb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUpCisgIC8vIG9wdGlvbmFsIHN0cmluZyB2YWx1ZSA9IDE7CisgIGlmICh0aGlzLT52YWx1ZSgpLnNpemUoKSA+IDApIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VmVyaWZ5VXRmOFN0cmluZygKKyAgICAgIHRoaXMtPnZhbHVlKCkuZGF0YSgpLCB0aGlzLT52YWx1ZSgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUudmFsdWUiKTsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVTdHJpbmdNYXliZUFsaWFzZWQoCisgICAgICAxLCB0aGlzLT52YWx1ZSgpLCBvdXRwdXQpOworICB9CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV9lbmQ6Z29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlKQorfQorCis6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBTdHJpbmdWYWx1ZTo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiB0YXJnZXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9zdGFydDpnb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUpCisgIC8vIG9wdGlvbmFsIHN0cmluZyB2YWx1ZSA9IDE7CisgIGlmICh0aGlzLT52YWx1ZSgpLnNpemUoKSA+IDApIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6VmVyaWZ5VXRmOFN0cmluZygKKyAgICAgIHRoaXMtPnZhbHVlKCkuZGF0YSgpLCB0aGlzLT52YWx1ZSgpLmxlbmd0aCgpLAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlNFUklBTElaRSwKKyAgICAgICJnb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUudmFsdWUiKTsKKyAgICB0YXJnZXQgPQorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldyaXRlU3RyaW5nVG9BcnJheSgKKyAgICAgICAgMSwgdGhpcy0+dmFsdWUoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfZW5kOmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSkKKyAgcmV0dXJuIHRhcmdldDsKK30KKworaW50IFN0cmluZ1ZhbHVlOjpCeXRlU2l6ZSgpIGNvbnN0IHsKKyAgaW50IHRvdGFsX3NpemUgPSAwOworCisgIC8vIG9wdGlvbmFsIHN0cmluZyB2YWx1ZSA9IDE7CisgIGlmICh0aGlzLT52YWx1ZSgpLnNpemUoKSA+IDApIHsKKyAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlN0cmluZ1NpemUoCisgICAgICAgIHRoaXMtPnZhbHVlKCkpOworICB9CisKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfQkVHSU4oKTsKKyAgX2NhY2hlZF9zaXplXyA9IHRvdGFsX3NpemU7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0VORCgpOworICByZXR1cm4gdG90YWxfc2l6ZTsKK30KKwordm9pZCBTdHJpbmdWYWx1ZTo6TWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSkgeworICBpZiAoR09PR0xFX1BSRURJQ1RfRkFMU0UoJmZyb20gPT0gdGhpcykpIE1lcmdlRnJvbUZhaWwoX19MSU5FX18pOworICBjb25zdCBTdHJpbmdWYWx1ZSogc291cmNlID0gCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpEeW5hbWljQ2FzdFRvR2VuZXJhdGVkPGNvbnN0IFN0cmluZ1ZhbHVlPigKKyAgICAgICAgICAmZnJvbSk7CisgIGlmIChzb3VyY2UgPT0gTlVMTCkgeworICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OlJlZmxlY3Rpb25PcHM6Ok1lcmdlKGZyb20sIHRoaXMpOworICB9IGVsc2UgeworICAgIE1lcmdlRnJvbSgqc291cmNlKTsKKyAgfQorfQorCit2b2lkIFN0cmluZ1ZhbHVlOjpNZXJnZUZyb20oY29uc3QgU3RyaW5nVmFsdWUmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgaWYgKGZyb20udmFsdWUoKS5zaXplKCkgPiAwKSB7CisgICAgc2V0X3ZhbHVlKGZyb20udmFsdWUoKSk7CisgIH0KK30KKwordm9pZCBTdHJpbmdWYWx1ZTo6Q29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKSB7CisgIGlmICgmZnJvbSA9PSB0aGlzKSByZXR1cm47CisgIENsZWFyKCk7CisgIE1lcmdlRnJvbShmcm9tKTsKK30KKwordm9pZCBTdHJpbmdWYWx1ZTo6Q29weUZyb20oY29uc3QgU3RyaW5nVmFsdWUmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCitib29sIFN0cmluZ1ZhbHVlOjpJc0luaXRpYWxpemVkKCkgY29uc3QgeworCisgIHJldHVybiB0cnVlOworfQorCit2b2lkIFN0cmluZ1ZhbHVlOjpTd2FwKFN0cmluZ1ZhbHVlKiBvdGhlcikgeworICBpZiAob3RoZXIgPT0gdGhpcykgcmV0dXJuOworICBpZiAoR2V0QXJlbmFOb1ZpcnR1YWwoKSA9PSBvdGhlci0+R2V0QXJlbmFOb1ZpcnR1YWwoKSkgeworICAgIEludGVybmFsU3dhcChvdGhlcik7CisgIH0gZWxzZSB7CisgICAgU3RyaW5nVmFsdWUgdGVtcDsKKyAgICB0ZW1wLk1lcmdlRnJvbSgqdGhpcyk7CisgICAgQ29weUZyb20oKm90aGVyKTsKKyAgICBvdGhlci0+Q29weUZyb20odGVtcCk7CisgIH0KK30KK3ZvaWQgU3RyaW5nVmFsdWU6OlVuc2FmZUFyZW5hU3dhcChTdHJpbmdWYWx1ZSogb3RoZXIpIHsKKyAgaWYgKG90aGVyID09IHRoaXMpIHJldHVybjsKKyAgR09PR0xFX0RDSEVDSyhHZXRBcmVuYU5vVmlydHVhbCgpID09IG90aGVyLT5HZXRBcmVuYU5vVmlydHVhbCgpKTsKKyAgSW50ZXJuYWxTd2FwKG90aGVyKTsKK30KK3ZvaWQgU3RyaW5nVmFsdWU6OkludGVybmFsU3dhcChTdHJpbmdWYWx1ZSogb3RoZXIpIHsKKyAgdmFsdWVfLlN3YXAoJm90aGVyLT52YWx1ZV8pOworICBfaW50ZXJuYWxfbWV0YWRhdGFfLlN3YXAoJm90aGVyLT5faW50ZXJuYWxfbWV0YWRhdGFfKTsKKyAgc3RkOjpzd2FwKF9jYWNoZWRfc2l6ZV8sIG90aGVyLT5fY2FjaGVkX3NpemVfKTsKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBTdHJpbmdWYWx1ZTo6R2V0TWV0YWRhdGEoKSBjb25zdCB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIG1ldGFkYXRhOworICBtZXRhZGF0YS5kZXNjcmlwdG9yID0gU3RyaW5nVmFsdWVfZGVzY3JpcHRvcl87CisgIG1ldGFkYXRhLnJlZmxlY3Rpb24gPSBTdHJpbmdWYWx1ZV9yZWZsZWN0aW9uXzsKKyAgcmV0dXJuIG1ldGFkYXRhOworfQorCisjaWYgUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisvLyBTdHJpbmdWYWx1ZQorCisvLyBvcHRpb25hbCBzdHJpbmcgdmFsdWUgPSAxOwordm9pZCBTdHJpbmdWYWx1ZTo6Y2xlYXJfdmFsdWUoKSB7CisgIHZhbHVlXy5DbGVhclRvRW1wdHkoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBHZXRBcmVuYU5vVmlydHVhbCgpKTsKK30KKyBjb25zdCA6OnN0ZDo6c3RyaW5nJiBTdHJpbmdWYWx1ZTo6dmFsdWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlLnZhbHVlKQorICByZXR1cm4gdmFsdWVfLkdldCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorIHZvaWQgU3RyaW5nVmFsdWU6OnNldF92YWx1ZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSkgeworICAKKyAgdmFsdWVfLlNldCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIHZhbHVlLCBHZXRBcmVuYU5vVmlydHVhbCgpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldDpnb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUudmFsdWUpCit9Cisgdm9pZCBTdHJpbmdWYWx1ZTo6c2V0X3ZhbHVlKGNvbnN0IGNoYXIqIHZhbHVlKSB7CisgIAorICB2YWx1ZV8uU2V0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZyh2YWx1ZSksCisgICAgICAgICAgICAgIEdldEFyZW5hTm9WaXJ0dWFsKCkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2NoYXI6Z29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlLnZhbHVlKQorfQorIHZvaWQgU3RyaW5nVmFsdWU6OnNldF92YWx1ZShjb25zdCBjaGFyKiB2YWx1ZSwKKyAgICBzaXplX3Qgc2l6ZSkgeworICAKKyAgdmFsdWVfLlNldCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcoCisgICAgICByZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpLCBHZXRBcmVuYU5vVmlydHVhbCgpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZS52YWx1ZSkKK30KKyA6OnN0ZDo6c3RyaW5nKiBTdHJpbmdWYWx1ZTo6bXV0YWJsZV92YWx1ZSgpIHsKKyAgCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9tdXRhYmxlOmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZS52YWx1ZSkKKyAgcmV0dXJuIHZhbHVlXy5NdXRhYmxlKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgR2V0QXJlbmFOb1ZpcnR1YWwoKSk7Cit9CisgOjpzdGQ6OnN0cmluZyogU3RyaW5nVmFsdWU6OnJlbGVhc2VfdmFsdWUoKSB7CisgIAorICByZXR1cm4gdmFsdWVfLlJlbGVhc2UoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBHZXRBcmVuYU5vVmlydHVhbCgpKTsKK30KKyA6OnN0ZDo6c3RyaW5nKiBTdHJpbmdWYWx1ZTo6dW5zYWZlX2FyZW5hX3JlbGVhc2VfdmFsdWUoKSB7CisgIEdPT0dMRV9EQ0hFQ0soR2V0QXJlbmFOb1ZpcnR1YWwoKSAhPSBOVUxMKTsKKyAgCisgIHJldHVybiB2YWx1ZV8uVW5zYWZlQXJlbmFSZWxlYXNlKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIEdldEFyZW5hTm9WaXJ0dWFsKCkpOworfQorIHZvaWQgU3RyaW5nVmFsdWU6OnNldF9hbGxvY2F0ZWRfdmFsdWUoOjpzdGQ6OnN0cmluZyogdmFsdWUpIHsKKyAgaWYgKHZhbHVlICE9IE5VTEwpIHsKKyAgICAKKyAgfSBlbHNlIHsKKyAgICAKKyAgfQorICB2YWx1ZV8uU2V0QWxsb2NhdGVkKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUsCisgICAgICBHZXRBcmVuYU5vVmlydHVhbCgpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlLnZhbHVlKQorfQorIHZvaWQgU3RyaW5nVmFsdWU6OnVuc2FmZV9hcmVuYV9zZXRfYWxsb2NhdGVkX3ZhbHVlKAorICAgIDo6c3RkOjpzdHJpbmcqIHZhbHVlKSB7CisgIEdPT0dMRV9EQ0hFQ0soR2V0QXJlbmFOb1ZpcnR1YWwoKSAhPSBOVUxMKTsKKyAgaWYgKHZhbHVlICE9IE5VTEwpIHsKKyAgICAKKyAgfSBlbHNlIHsKKyAgICAKKyAgfQorICB2YWx1ZV8uVW5zYWZlQXJlbmFTZXRBbGxvY2F0ZWQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgdmFsdWUsIEdldEFyZW5hTm9WaXJ0dWFsKCkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUudmFsdWUpCit9CisKKyNlbmRpZiAgLy8gUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworI2lmICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCitjb25zdCBpbnQgQnl0ZXNWYWx1ZTo6a1ZhbHVlRmllbGROdW1iZXI7CisjZW5kaWYgIC8vICFkZWZpbmVkKF9NU0NfVkVSKSB8fCBfTVNDX1ZFUiA+PSAxOTAwCisKK0J5dGVzVmFsdWU6OkJ5dGVzVmFsdWUoKQorICA6IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSgpLCBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY29uc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUpCit9CisKK0J5dGVzVmFsdWU6OkJ5dGVzVmFsdWUoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpCisgIDogOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlKCksCisgIF9pbnRlcm5hbF9tZXRhZGF0YV8oYXJlbmEpIHsKKyAgU2hhcmVkQ3RvcigpOworICBSZWdpc3RlckFyZW5hRHRvcihhcmVuYSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChhcmVuYV9jb25zdHJ1Y3Rvcjpnb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSkKK30KKwordm9pZCBCeXRlc1ZhbHVlOjpJbml0QXNEZWZhdWx0SW5zdGFuY2UoKSB7CisgIF9pc19kZWZhdWx0X2luc3RhbmNlXyA9IHRydWU7Cit9CisKK0J5dGVzVmFsdWU6OkJ5dGVzVmFsdWUoY29uc3QgQnl0ZXNWYWx1ZSYgZnJvbSkKKyAgOiA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UoKSwKKyAgICBfaW50ZXJuYWxfbWV0YWRhdGFfKE5VTEwpIHsKKyAgU2hhcmVkQ3RvcigpOworICBNZXJnZUZyb20oZnJvbSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjb3B5X2NvbnN0cnVjdG9yOmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlKQorfQorCit2b2lkIEJ5dGVzVmFsdWU6OlNoYXJlZEN0b3IoKSB7CisgICAgX2lzX2RlZmF1bHRfaW5zdGFuY2VfID0gZmFsc2U7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSAwOworICB2YWx1ZV8uVW5zYWZlU2V0RGVmYXVsdCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCkpOworfQorCitCeXRlc1ZhbHVlOjp+Qnl0ZXNWYWx1ZSgpIHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGRlc3RydWN0b3I6Z29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUpCisgIFNoYXJlZER0b3IoKTsKK30KKwordm9pZCBCeXRlc1ZhbHVlOjpTaGFyZWREdG9yKCkgeworICBpZiAoR2V0QXJlbmFOb1ZpcnR1YWwoKSAhPSBOVUxMKSB7CisgICAgcmV0dXJuOworICB9CisKKyAgdmFsdWVfLkRlc3Ryb3koJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBHZXRBcmVuYU5vVmlydHVhbCgpKTsKKyAgaWYgKHRoaXMgIT0gZGVmYXVsdF9pbnN0YW5jZV8pIHsKKyAgfQorfQorCit2b2lkIEJ5dGVzVmFsdWU6OkFyZW5hRHRvcih2b2lkKiBvYmplY3QpIHsKKyAgQnl0ZXNWYWx1ZSogX3RoaXMgPSByZWludGVycHJldF9jYXN0PCBCeXRlc1ZhbHVlKiA+KG9iamVjdCk7CisgICh2b2lkKV90aGlzOworfQordm9pZCBCeXRlc1ZhbHVlOjpSZWdpc3RlckFyZW5hRHRvcig6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgeworfQordm9pZCBCeXRlc1ZhbHVlOjpTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdCB7CisgIEdPT0dMRV9TQUZFX0NPTkNVUlJFTlRfV1JJVEVTX0JFR0lOKCk7CisgIF9jYWNoZWRfc2l6ZV8gPSBzaXplOworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19FTkQoKTsKK30KK2NvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogQnl0ZXNWYWx1ZTo6ZGVzY3JpcHRvcigpIHsKKyAgcHJvdG9idWZfQXNzaWduRGVzY3JpcHRvcnNPbmNlKCk7CisgIHJldHVybiBCeXRlc1ZhbHVlX2Rlc2NyaXB0b3JfOworfQorCitjb25zdCBCeXRlc1ZhbHVlJiBCeXRlc1ZhbHVlOjpkZWZhdWx0X2luc3RhbmNlKCkgeworICBpZiAoZGVmYXVsdF9pbnN0YW5jZV8gPT0gTlVMTCkgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZndyYXBwZXJzXzJlcHJvdG8oKTsKKyAgcmV0dXJuICpkZWZhdWx0X2luc3RhbmNlXzsKK30KKworQnl0ZXNWYWx1ZSogQnl0ZXNWYWx1ZTo6ZGVmYXVsdF9pbnN0YW5jZV8gPSBOVUxMOworCitCeXRlc1ZhbHVlKiBCeXRlc1ZhbHVlOjpOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0IHsKKyAgcmV0dXJuIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmE6OkNyZWF0ZU1lc3NhZ2U8Qnl0ZXNWYWx1ZT4oYXJlbmEpOworfQorCit2b2lkIEJ5dGVzVmFsdWU6OkNsZWFyKCkgeworICB2YWx1ZV8uQ2xlYXJUb0VtcHR5KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgR2V0QXJlbmFOb1ZpcnR1YWwoKSk7Cit9CisKK2Jvb2wgQnl0ZXNWYWx1ZTo6TWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KSB7CisjZGVmaW5lIERPXyhFWFBSRVNTSU9OKSBpZiAoIShFWFBSRVNTSU9OKSkgZ290byBmYWlsdXJlCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIHRhZzsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlKQorICBmb3IgKDs7KSB7CisgICAgOjpzdGQ6OnBhaXI8IDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyLCBib29sPiBwID0gaW5wdXQtPlJlYWRUYWdXaXRoQ3V0b2ZmKDEyNyk7CisgICAgdGFnID0gcC5maXJzdDsKKyAgICBpZiAoIXAuc2Vjb25kKSBnb3RvIGhhbmRsZV91bnVzdWFsOworICAgIHN3aXRjaCAoOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkdldFRhZ0ZpZWxkTnVtYmVyKHRhZykpIHsKKyAgICAgIC8vIG9wdGlvbmFsIGJ5dGVzIHZhbHVlID0gMTsKKyAgICAgIGNhc2UgMTogeworICAgICAgICBpZiAodGFnID09IDEwKSB7CisgICAgICAgICAgRE9fKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpSZWFkQnl0ZXMoCisgICAgICAgICAgICAgICAgaW5wdXQsIHRoaXMtPm11dGFibGVfdmFsdWUoKSkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGdvdG8gaGFuZGxlX3VudXN1YWw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGlucHV0LT5FeHBlY3RBdEVuZCgpKSBnb3RvIHN1Y2Nlc3M7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBkZWZhdWx0OiB7CisgICAgICBoYW5kbGVfdW51c3VhbDoKKyAgICAgICAgaWYgKHRhZyA9PSAwIHx8CisgICAgICAgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6R2V0VGFnV2lyZVR5cGUodGFnKSA9PQorICAgICAgICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OldJUkVUWVBFX0VORF9HUk9VUCkgeworICAgICAgICAgIGdvdG8gc3VjY2VzczsKKyAgICAgICAgfQorICAgICAgICBET18oOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OlNraXBGaWVsZChpbnB1dCwgdGFnKSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgfQorc3VjY2VzczoKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX3N1Y2Nlc3M6Z29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUpCisgIHJldHVybiB0cnVlOworZmFpbHVyZToKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHBhcnNlX2ZhaWx1cmU6Z29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUpCisgIHJldHVybiBmYWxzZTsKKyN1bmRlZiBET18KK30KKwordm9pZCBCeXRlc1ZhbHVlOjpTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX3N0YXJ0Omdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlKQorICAvLyBvcHRpb25hbCBieXRlcyB2YWx1ZSA9IDE7CisgIGlmICh0aGlzLT52YWx1ZSgpLnNpemUoKSA+IDApIHsKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpXaXJlRm9ybWF0TGl0ZTo6V3JpdGVCeXRlc01heWJlQWxpYXNlZCgKKyAgICAgIDEsIHRoaXMtPnZhbHVlKCksIG91dHB1dCk7CisgIH0KKworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoc2VyaWFsaXplX2VuZDpnb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSkKK30KKworOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogQnl0ZXNWYWx1ZTo6U2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSgKKyAgICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiB0YXJnZXQpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KHNlcmlhbGl6ZV90b19hcnJheV9zdGFydDpnb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSkKKyAgLy8gb3B0aW9uYWwgYnl0ZXMgdmFsdWUgPSAxOworICBpZiAodGhpcy0+dmFsdWUoKS5zaXplKCkgPiAwKSB7CisgICAgdGFyZ2V0ID0KKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OldpcmVGb3JtYXRMaXRlOjpXcml0ZUJ5dGVzVG9BcnJheSgKKyAgICAgICAgMSwgdGhpcy0+dmFsdWUoKSwgdGFyZ2V0KTsKKyAgfQorCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChzZXJpYWxpemVfdG9fYXJyYXlfZW5kOmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlKQorICByZXR1cm4gdGFyZ2V0OworfQorCitpbnQgQnl0ZXNWYWx1ZTo6Qnl0ZVNpemUoKSBjb25zdCB7CisgIGludCB0b3RhbF9zaXplID0gMDsKKworICAvLyBvcHRpb25hbCBieXRlcyB2YWx1ZSA9IDE7CisgIGlmICh0aGlzLT52YWx1ZSgpLnNpemUoKSA+IDApIHsKKyAgICB0b3RhbF9zaXplICs9IDEgKworICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6V2lyZUZvcm1hdExpdGU6OkJ5dGVzU2l6ZSgKKyAgICAgICAgdGhpcy0+dmFsdWUoKSk7CisgIH0KKworICBHT09HTEVfU0FGRV9DT05DVVJSRU5UX1dSSVRFU19CRUdJTigpOworICBfY2FjaGVkX3NpemVfID0gdG90YWxfc2l6ZTsKKyAgR09PR0xFX1NBRkVfQ09OQ1VSUkVOVF9XUklURVNfRU5EKCk7CisgIHJldHVybiB0b3RhbF9zaXplOworfQorCit2b2lkIEJ5dGVzVmFsdWU6Ok1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgY29uc3QgQnl0ZXNWYWx1ZSogc291cmNlID0gCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpEeW5hbWljQ2FzdFRvR2VuZXJhdGVkPGNvbnN0IEJ5dGVzVmFsdWU+KAorICAgICAgICAgICZmcm9tKTsKKyAgaWYgKHNvdXJjZSA9PSBOVUxMKSB7CisgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6UmVmbGVjdGlvbk9wczo6TWVyZ2UoZnJvbSwgdGhpcyk7CisgIH0gZWxzZSB7CisgICAgTWVyZ2VGcm9tKCpzb3VyY2UpOworICB9Cit9CisKK3ZvaWQgQnl0ZXNWYWx1ZTo6TWVyZ2VGcm9tKGNvbnN0IEJ5dGVzVmFsdWUmIGZyb20pIHsKKyAgaWYgKEdPT0dMRV9QUkVESUNUX0ZBTFNFKCZmcm9tID09IHRoaXMpKSBNZXJnZUZyb21GYWlsKF9fTElORV9fKTsKKyAgaWYgKGZyb20udmFsdWUoKS5zaXplKCkgPiAwKSB7CisgICAgc2V0X3ZhbHVlKGZyb20udmFsdWUoKSk7CisgIH0KK30KKwordm9pZCBCeXRlc1ZhbHVlOjpDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCit2b2lkIEJ5dGVzVmFsdWU6OkNvcHlGcm9tKGNvbnN0IEJ5dGVzVmFsdWUmIGZyb20pIHsKKyAgaWYgKCZmcm9tID09IHRoaXMpIHJldHVybjsKKyAgQ2xlYXIoKTsKKyAgTWVyZ2VGcm9tKGZyb20pOworfQorCitib29sIEJ5dGVzVmFsdWU6OklzSW5pdGlhbGl6ZWQoKSBjb25zdCB7CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgQnl0ZXNWYWx1ZTo6U3dhcChCeXRlc1ZhbHVlKiBvdGhlcikgeworICBpZiAob3RoZXIgPT0gdGhpcykgcmV0dXJuOworICBpZiAoR2V0QXJlbmFOb1ZpcnR1YWwoKSA9PSBvdGhlci0+R2V0QXJlbmFOb1ZpcnR1YWwoKSkgeworICAgIEludGVybmFsU3dhcChvdGhlcik7CisgIH0gZWxzZSB7CisgICAgQnl0ZXNWYWx1ZSB0ZW1wOworICAgIHRlbXAuTWVyZ2VGcm9tKCp0aGlzKTsKKyAgICBDb3B5RnJvbSgqb3RoZXIpOworICAgIG90aGVyLT5Db3B5RnJvbSh0ZW1wKTsKKyAgfQorfQordm9pZCBCeXRlc1ZhbHVlOjpVbnNhZmVBcmVuYVN3YXAoQnl0ZXNWYWx1ZSogb3RoZXIpIHsKKyAgaWYgKG90aGVyID09IHRoaXMpIHJldHVybjsKKyAgR09PR0xFX0RDSEVDSyhHZXRBcmVuYU5vVmlydHVhbCgpID09IG90aGVyLT5HZXRBcmVuYU5vVmlydHVhbCgpKTsKKyAgSW50ZXJuYWxTd2FwKG90aGVyKTsKK30KK3ZvaWQgQnl0ZXNWYWx1ZTo6SW50ZXJuYWxTd2FwKEJ5dGVzVmFsdWUqIG90aGVyKSB7CisgIHZhbHVlXy5Td2FwKCZvdGhlci0+dmFsdWVfKTsKKyAgX2ludGVybmFsX21ldGFkYXRhXy5Td2FwKCZvdGhlci0+X2ludGVybmFsX21ldGFkYXRhXyk7CisgIHN0ZDo6c3dhcChfY2FjaGVkX3NpemVfLCBvdGhlci0+X2NhY2hlZF9zaXplXyk7Cit9CisKKzo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgQnl0ZXNWYWx1ZTo6R2V0TWV0YWRhdGEoKSBjb25zdCB7CisgIHByb3RvYnVmX0Fzc2lnbkRlc2NyaXB0b3JzT25jZSgpOworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIG1ldGFkYXRhOworICBtZXRhZGF0YS5kZXNjcmlwdG9yID0gQnl0ZXNWYWx1ZV9kZXNjcmlwdG9yXzsKKyAgbWV0YWRhdGEucmVmbGVjdGlvbiA9IEJ5dGVzVmFsdWVfcmVmbGVjdGlvbl87CisgIHJldHVybiBtZXRhZGF0YTsKK30KKworI2lmIFBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworLy8gQnl0ZXNWYWx1ZQorCisvLyBvcHRpb25hbCBieXRlcyB2YWx1ZSA9IDE7Cit2b2lkIEJ5dGVzVmFsdWU6OmNsZWFyX3ZhbHVlKCkgeworICB2YWx1ZV8uQ2xlYXJUb0VtcHR5KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgR2V0QXJlbmFOb1ZpcnR1YWwoKSk7Cit9CisgY29uc3QgOjpzdGQ6OnN0cmluZyYgQnl0ZXNWYWx1ZTo6dmFsdWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUudmFsdWUpCisgIHJldHVybiB2YWx1ZV8uR2V0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9Cisgdm9pZCBCeXRlc1ZhbHVlOjpzZXRfdmFsdWUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgCisgIHZhbHVlXy5TZXQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSwgR2V0QXJlbmFOb1ZpcnR1YWwoKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUudmFsdWUpCit9Cisgdm9pZCBCeXRlc1ZhbHVlOjpzZXRfdmFsdWUoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgCisgIHZhbHVlXy5TZXQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSwKKyAgICAgICAgICAgICAgR2V0QXJlbmFOb1ZpcnR1YWwoKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZS52YWx1ZSkKK30KKyB2b2lkIEJ5dGVzVmFsdWU6OnNldF92YWx1ZShjb25zdCB2b2lkKiB2YWx1ZSwKKyAgICBzaXplX3Qgc2l6ZSkgeworICAKKyAgdmFsdWVfLlNldCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcoCisgICAgICByZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpLCBHZXRBcmVuYU5vVmlydHVhbCgpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlLnZhbHVlKQorfQorIDo6c3RkOjpzdHJpbmcqIEJ5dGVzVmFsdWU6Om11dGFibGVfdmFsdWUoKSB7CisgIAorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZS52YWx1ZSkKKyAgcmV0dXJuIHZhbHVlXy5NdXRhYmxlKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgR2V0QXJlbmFOb1ZpcnR1YWwoKSk7Cit9CisgOjpzdGQ6OnN0cmluZyogQnl0ZXNWYWx1ZTo6cmVsZWFzZV92YWx1ZSgpIHsKKyAgCisgIHJldHVybiB2YWx1ZV8uUmVsZWFzZSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIEdldEFyZW5hTm9WaXJ0dWFsKCkpOworfQorIDo6c3RkOjpzdHJpbmcqIEJ5dGVzVmFsdWU6OnVuc2FmZV9hcmVuYV9yZWxlYXNlX3ZhbHVlKCkgeworICBHT09HTEVfRENIRUNLKEdldEFyZW5hTm9WaXJ0dWFsKCkgIT0gTlVMTCk7CisgIAorICByZXR1cm4gdmFsdWVfLlVuc2FmZUFyZW5hUmVsZWFzZSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICBHZXRBcmVuYU5vVmlydHVhbCgpKTsKK30KKyB2b2lkIEJ5dGVzVmFsdWU6OnNldF9hbGxvY2F0ZWRfdmFsdWUoOjpzdGQ6OnN0cmluZyogdmFsdWUpIHsKKyAgaWYgKHZhbHVlICE9IE5VTEwpIHsKKyAgICAKKyAgfSBlbHNlIHsKKyAgICAKKyAgfQorICB2YWx1ZV8uU2V0QWxsb2NhdGVkKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUsCisgICAgICBHZXRBcmVuYU5vVmlydHVhbCgpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUudmFsdWUpCit9Cisgdm9pZCBCeXRlc1ZhbHVlOjp1bnNhZmVfYXJlbmFfc2V0X2FsbG9jYXRlZF92YWx1ZSgKKyAgICA6OnN0ZDo6c3RyaW5nKiB2YWx1ZSkgeworICBHT09HTEVfRENIRUNLKEdldEFyZW5hTm9WaXJ0dWFsKCkgIT0gTlVMTCk7CisgIGlmICh2YWx1ZSAhPSBOVUxMKSB7CisgICAgCisgIH0gZWxzZSB7CisgICAgCisgIH0KKyAgdmFsdWVfLlVuc2FmZUFyZW5hU2V0QWxsb2NhdGVkKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIHZhbHVlLCBHZXRBcmVuYU5vVmlydHVhbCgpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUudmFsdWUpCit9CisKKyNlbmRpZiAgLy8gUFJPVE9CVUZfSU5MSU5FX05PVF9JTl9IRUFERVJTCisKKy8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChuYW1lc3BhY2Vfc2NvcGUpCisKK30gIC8vIG5hbWVzcGFjZSBwcm90b2J1ZgorfSAgLy8gbmFtZXNwYWNlIGdvb2dsZQorCisvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZ2xvYmFsX3Njb3BlKQpkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi93cmFwcGVycy5wYi5oIGIvc3JjL2dvb2dsZS9wcm90b2J1Zi93cmFwcGVycy5wYi5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdkY2E5MzgKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvZ29vZ2xlL3Byb3RvYnVmL3dyYXBwZXJzLnBiLmgKQEAgLTAsMCArMSwxMTc2IEBACisvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQorLy8gc291cmNlOiBnb29nbGUvcHJvdG9idWYvd3JhcHBlcnMucHJvdG8KKworI2lmbmRlZiBQUk9UT0JVRl9nb29nbGVfMmZwcm90b2J1Zl8yZndyYXBwZXJzXzJlcHJvdG9fX0lOQ0xVREVECisjZGVmaW5lIFBST1RPQlVGX2dvb2dsZV8yZnByb3RvYnVmXzJmd3JhcHBlcnNfMmVwcm90b19fSU5DTFVERUQKKworI2luY2x1ZGUgPHN0cmluZz4KKworI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9zdHVicy9jb21tb24uaD4KKworI2lmIEdPT0dMRV9QUk9UT0JVRl9WRVJTSU9OIDwgMzAwMDAwMAorI2Vycm9yIFRoaXMgZmlsZSB3YXMgZ2VuZXJhdGVkIGJ5IGEgbmV3ZXIgdmVyc2lvbiBvZiBwcm90b2Mgd2hpY2ggaXMKKyNlcnJvciBpbmNvbXBhdGlibGUgd2l0aCB5b3VyIFByb3RvY29sIEJ1ZmZlciBoZWFkZXJzLiAgUGxlYXNlIHVwZGF0ZQorI2Vycm9yIHlvdXIgaGVhZGVycy4KKyNlbmRpZgorI2lmIDMwMDAwMDAgPCBHT09HTEVfUFJPVE9CVUZfTUlOX1BST1RPQ19WRVJTSU9OCisjZXJyb3IgVGhpcyBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgYW4gb2xkZXIgdmVyc2lvbiBvZiBwcm90b2Mgd2hpY2ggaXMKKyNlcnJvciBpbmNvbXBhdGlibGUgd2l0aCB5b3VyIFByb3RvY29sIEJ1ZmZlciBoZWFkZXJzLiAgUGxlYXNlCisjZXJyb3IgcmVnZW5lcmF0ZSB0aGlzIGZpbGUgd2l0aCBhIG5ld2VyIHZlcnNpb24gb2YgcHJvdG9jLgorI2VuZGlmCisKKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvYXJlbmEuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvYXJlbmFzdHJpbmcuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvZ2VuZXJhdGVkX21lc3NhZ2VfdXRpbC5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tZXRhZGF0YS5oPgorI2luY2x1ZGUgPGdvb2dsZS9wcm90b2J1Zi9tZXNzYWdlLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL3JlcGVhdGVkX2ZpZWxkLmg+CisjaW5jbHVkZSA8Z29vZ2xlL3Byb3RvYnVmL2V4dGVuc2lvbl9zZXQuaD4KKyNpbmNsdWRlIDxnb29nbGUvcHJvdG9idWYvdW5rbm93bl9maWVsZF9zZXQuaD4KKy8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbmNsdWRlcykKKworbmFtZXNwYWNlIGdvb2dsZSB7CituYW1lc3BhY2UgcHJvdG9idWYgeworCisvLyBJbnRlcm5hbCBpbXBsZW1lbnRhdGlvbiBkZXRhaWwgLS0gZG8gbm90IGNhbGwgdGhlc2UuCit2b2lkIExJQlBST1RPQlVGX0VYUE9SVCBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmd3JhcHBlcnNfMmVwcm90bygpOwordm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmd3JhcHBlcnNfMmVwcm90bygpOwordm9pZCBwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZ3cmFwcGVyc18yZXByb3RvKCk7CisKK2NsYXNzIEJvb2xWYWx1ZTsKK2NsYXNzIEJ5dGVzVmFsdWU7CitjbGFzcyBEb3VibGVWYWx1ZTsKK2NsYXNzIEZsb2F0VmFsdWU7CitjbGFzcyBJbnQzMlZhbHVlOworY2xhc3MgSW50NjRWYWx1ZTsKK2NsYXNzIFN0cmluZ1ZhbHVlOworY2xhc3MgVUludDMyVmFsdWU7CitjbGFzcyBVSW50NjRWYWx1ZTsKKworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgRG91YmxlVmFsdWUgOiBwdWJsaWMgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlIHsKKyBwdWJsaWM6CisgIERvdWJsZVZhbHVlKCk7CisgIHZpcnR1YWwgfkRvdWJsZVZhbHVlKCk7CisKKyAgRG91YmxlVmFsdWUoY29uc3QgRG91YmxlVmFsdWUmIGZyb20pOworCisgIGlubGluZSBEb3VibGVWYWx1ZSYgb3BlcmF0b3I9KGNvbnN0IERvdWJsZVZhbHVlJiBmcm9tKSB7CisgICAgQ29weUZyb20oZnJvbSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hKCkgY29uc3QgeyByZXR1cm4gR2V0QXJlbmFOb1ZpcnR1YWwoKTsgfQorICBpbmxpbmUgdm9pZCogR2V0TWF5YmVBcmVuYVBvaW50ZXIoKSBjb25zdCB7CisgICAgcmV0dXJuIE1heWJlQXJlbmFQdHIoKTsKKyAgfQorICBzdGF0aWMgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKCk7CisgIHN0YXRpYyBjb25zdCBEb3VibGVWYWx1ZSYgZGVmYXVsdF9pbnN0YW5jZSgpOworCisgIHZvaWQgVW5zYWZlQXJlbmFTd2FwKERvdWJsZVZhbHVlKiBvdGhlcik7CisgIHZvaWQgU3dhcChEb3VibGVWYWx1ZSogb3RoZXIpOworCisgIC8vIGltcGxlbWVudHMgTWVzc2FnZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgaW5saW5lIERvdWJsZVZhbHVlKiBOZXcoKSBjb25zdCB7IHJldHVybiBOZXcoTlVMTCk7IH0KKworICBEb3VibGVWYWx1ZSogTmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdDsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIENvcHlGcm9tKGNvbnN0IERvdWJsZVZhbHVlJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgRG91YmxlVmFsdWUmIGZyb20pOworICB2b2lkIENsZWFyKCk7CisgIGJvb2wgSXNJbml0aWFsaXplZCgpIGNvbnN0OworCisgIGludCBCeXRlU2l6ZSgpIGNvbnN0OworICBib29sIE1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KTsKKyAgdm9pZCBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSg6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBvdXRwdXQpIGNvbnN0OworICBpbnQgR2V0Q2FjaGVkU2l6ZSgpIGNvbnN0IHsgcmV0dXJuIF9jYWNoZWRfc2l6ZV87IH0KKyAgcHJpdmF0ZToKKyAgdm9pZCBTaGFyZWRDdG9yKCk7CisgIHZvaWQgU2hhcmVkRHRvcigpOworICB2b2lkIFNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0OworICB2b2lkIEludGVybmFsU3dhcChEb3VibGVWYWx1ZSogb3RoZXIpOworICBwcm90ZWN0ZWQ6CisgIGV4cGxpY2l0IERvdWJsZVZhbHVlKDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKTsKKyAgcHJpdmF0ZToKKyAgc3RhdGljIHZvaWQgQXJlbmFEdG9yKHZvaWQqIG9iamVjdCk7CisgIGlubGluZSB2b2lkIFJlZ2lzdGVyQXJlbmFEdG9yKDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKTsKKyAgcHJpdmF0ZToKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hTm9WaXJ0dWFsKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLmFyZW5hKCk7CisgIH0KKyAgaW5saW5lIHZvaWQqIE1heWJlQXJlbmFQdHIoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ucmF3X2FyZW5hX3B0cigpOworICB9CisgIHB1YmxpYzoKKworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEdldE1ldGFkYXRhKCkgY29uc3Q7CisKKyAgLy8gbmVzdGVkIHR5cGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBhY2Nlc3NvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIG9wdGlvbmFsIGRvdWJsZSB2YWx1ZSA9IDE7CisgIHZvaWQgY2xlYXJfdmFsdWUoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrVmFsdWVGaWVsZE51bWJlciA9IDE7CisgIGRvdWJsZSB2YWx1ZSgpIGNvbnN0OworICB2b2lkIHNldF92YWx1ZShkb3VibGUgdmFsdWUpOworCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpnb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUpCisgcHJpdmF0ZToKKworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpJbnRlcm5hbE1ldGFkYXRhV2l0aEFyZW5hIF9pbnRlcm5hbF9tZXRhZGF0YV87CisgIGZyaWVuZCBjbGFzcyA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hOworICB0eXBlZGVmIHZvaWQgSW50ZXJuYWxBcmVuYUNvbnN0cnVjdGFibGVfOworICB0eXBlZGVmIHZvaWQgRGVzdHJ1Y3RvclNraXBwYWJsZV87CisgIGJvb2wgX2lzX2RlZmF1bHRfaW5zdGFuY2VfOworICBkb3VibGUgdmFsdWVfOworICBtdXRhYmxlIGludCBfY2FjaGVkX3NpemVfOworICBmcmllbmQgdm9pZCBMSUJQUk9UT0JVRl9FWFBPUlQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZndyYXBwZXJzXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfQXNzaWduRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZndyYXBwZXJzXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfU2h1dGRvd25GaWxlX2dvb2dsZV8yZnByb3RvYnVmXzJmd3JhcHBlcnNfMmVwcm90bygpOworCisgIHZvaWQgSW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIHN0YXRpYyBEb3VibGVWYWx1ZSogZGVmYXVsdF9pbnN0YW5jZV87Cit9OworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgRmxvYXRWYWx1ZSA6IHB1YmxpYyA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UgeworIHB1YmxpYzoKKyAgRmxvYXRWYWx1ZSgpOworICB2aXJ0dWFsIH5GbG9hdFZhbHVlKCk7CisKKyAgRmxvYXRWYWx1ZShjb25zdCBGbG9hdFZhbHVlJiBmcm9tKTsKKworICBpbmxpbmUgRmxvYXRWYWx1ZSYgb3BlcmF0b3I9KGNvbnN0IEZsb2F0VmFsdWUmIGZyb20pIHsKKyAgICBDb3B5RnJvbShmcm9tKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogR2V0QXJlbmEoKSBjb25zdCB7IHJldHVybiBHZXRBcmVuYU5vVmlydHVhbCgpOyB9CisgIGlubGluZSB2b2lkKiBHZXRNYXliZUFyZW5hUG9pbnRlcigpIGNvbnN0IHsKKyAgICByZXR1cm4gTWF5YmVBcmVuYVB0cigpOworICB9CisgIHN0YXRpYyBjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6OkRlc2NyaXB0b3IqIGRlc2NyaXB0b3IoKTsKKyAgc3RhdGljIGNvbnN0IEZsb2F0VmFsdWUmIGRlZmF1bHRfaW5zdGFuY2UoKTsKKworICB2b2lkIFVuc2FmZUFyZW5hU3dhcChGbG9hdFZhbHVlKiBvdGhlcik7CisgIHZvaWQgU3dhcChGbG9hdFZhbHVlKiBvdGhlcik7CisKKyAgLy8gaW1wbGVtZW50cyBNZXNzYWdlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICBpbmxpbmUgRmxvYXRWYWx1ZSogTmV3KCkgY29uc3QgeyByZXR1cm4gTmV3KE5VTEwpOyB9CisKKyAgRmxvYXRWYWx1ZSogTmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdDsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIENvcHlGcm9tKGNvbnN0IEZsb2F0VmFsdWUmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCBGbG9hdFZhbHVlJiBmcm9tKTsKKyAgdm9pZCBDbGVhcigpOworICBib29sIElzSW5pdGlhbGl6ZWQoKSBjb25zdDsKKworICBpbnQgQnl0ZVNpemUoKSBjb25zdDsKKyAgYm9vbCBNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCk7CisgIHZvaWQgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogb3V0cHV0KSBjb25zdDsKKyAgaW50IEdldENhY2hlZFNpemUoKSBjb25zdCB7IHJldHVybiBfY2FjaGVkX3NpemVfOyB9CisgIHByaXZhdGU6CisgIHZvaWQgU2hhcmVkQ3RvcigpOworICB2b2lkIFNoYXJlZER0b3IoKTsKKyAgdm9pZCBTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdDsKKyAgdm9pZCBJbnRlcm5hbFN3YXAoRmxvYXRWYWx1ZSogb3RoZXIpOworICBwcm90ZWN0ZWQ6CisgIGV4cGxpY2l0IEZsb2F0VmFsdWUoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpOworICBwcml2YXRlOgorICBzdGF0aWMgdm9pZCBBcmVuYUR0b3Iodm9pZCogb2JqZWN0KTsKKyAgaW5saW5lIHZvaWQgUmVnaXN0ZXJBcmVuYUR0b3IoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpOworICBwcml2YXRlOgorICBpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogR2V0QXJlbmFOb1ZpcnR1YWwoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8uYXJlbmEoKTsKKyAgfQorICBpbmxpbmUgdm9pZCogTWF5YmVBcmVuYVB0cigpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5yYXdfYXJlbmFfcHRyKCk7CisgIH0KKyAgcHVibGljOgorCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWV0YWRhdGEgR2V0TWV0YWRhdGEoKSBjb25zdDsKKworICAvLyBuZXN0ZWQgdHlwZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIGFjY2Vzc29ycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gb3B0aW9uYWwgZmxvYXQgdmFsdWUgPSAxOworICB2b2lkIGNsZWFyX3ZhbHVlKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga1ZhbHVlRmllbGROdW1iZXIgPSAxOworICBmbG9hdCB2YWx1ZSgpIGNvbnN0OworICB2b2lkIHNldF92YWx1ZShmbG9hdCB2YWx1ZSk7CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlKQorIHByaXZhdGU6CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6SW50ZXJuYWxNZXRhZGF0YVdpdGhBcmVuYSBfaW50ZXJuYWxfbWV0YWRhdGFfOworICBmcmllbmQgY2xhc3MgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYTsKKyAgdHlwZWRlZiB2b2lkIEludGVybmFsQXJlbmFDb25zdHJ1Y3RhYmxlXzsKKyAgdHlwZWRlZiB2b2lkIERlc3RydWN0b3JTa2lwcGFibGVfOworICBib29sIF9pc19kZWZhdWx0X2luc3RhbmNlXzsKKyAgZmxvYXQgdmFsdWVfOworICBtdXRhYmxlIGludCBfY2FjaGVkX3NpemVfOworICBmcmllbmQgdm9pZCBMSUJQUk9UT0JVRl9FWFBPUlQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZndyYXBwZXJzXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfQXNzaWduRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZndyYXBwZXJzXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfU2h1dGRvd25GaWxlX2dvb2dsZV8yZnByb3RvYnVmXzJmd3JhcHBlcnNfMmVwcm90bygpOworCisgIHZvaWQgSW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIHN0YXRpYyBGbG9hdFZhbHVlKiBkZWZhdWx0X2luc3RhbmNlXzsKK307CisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIExJQlBST1RPQlVGX0VYUE9SVCBJbnQ2NFZhbHVlIDogcHVibGljIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSB7CisgcHVibGljOgorICBJbnQ2NFZhbHVlKCk7CisgIHZpcnR1YWwgfkludDY0VmFsdWUoKTsKKworICBJbnQ2NFZhbHVlKGNvbnN0IEludDY0VmFsdWUmIGZyb20pOworCisgIGlubGluZSBJbnQ2NFZhbHVlJiBvcGVyYXRvcj0oY29uc3QgSW50NjRWYWx1ZSYgZnJvbSkgeworICAgIENvcHlGcm9tKGZyb20pOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYSgpIGNvbnN0IHsgcmV0dXJuIEdldEFyZW5hTm9WaXJ0dWFsKCk7IH0KKyAgaW5saW5lIHZvaWQqIEdldE1heWJlQXJlbmFQb2ludGVyKCkgY29uc3QgeworICAgIHJldHVybiBNYXliZUFyZW5hUHRyKCk7CisgIH0KKyAgc3RhdGljIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogZGVzY3JpcHRvcigpOworICBzdGF0aWMgY29uc3QgSW50NjRWYWx1ZSYgZGVmYXVsdF9pbnN0YW5jZSgpOworCisgIHZvaWQgVW5zYWZlQXJlbmFTd2FwKEludDY0VmFsdWUqIG90aGVyKTsKKyAgdm9pZCBTd2FwKEludDY0VmFsdWUqIG90aGVyKTsKKworICAvLyBpbXBsZW1lbnRzIE1lc3NhZ2UgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIGlubGluZSBJbnQ2NFZhbHVlKiBOZXcoKSBjb25zdCB7IHJldHVybiBOZXcoTlVMTCk7IH0KKworICBJbnQ2NFZhbHVlKiBOZXcoOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYSogYXJlbmEpIGNvbnN0OworICB2b2lkIENvcHlGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSYgZnJvbSk7CisgIHZvaWQgQ29weUZyb20oY29uc3QgSW50NjRWYWx1ZSYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IEludDY0VmFsdWUmIGZyb20pOworICB2b2lkIENsZWFyKCk7CisgIGJvb2wgSXNJbml0aWFsaXplZCgpIGNvbnN0OworCisgIGludCBCeXRlU2l6ZSgpIGNvbnN0OworICBib29sIE1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KTsKKyAgdm9pZCBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSg6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBvdXRwdXQpIGNvbnN0OworICBpbnQgR2V0Q2FjaGVkU2l6ZSgpIGNvbnN0IHsgcmV0dXJuIF9jYWNoZWRfc2l6ZV87IH0KKyAgcHJpdmF0ZToKKyAgdm9pZCBTaGFyZWRDdG9yKCk7CisgIHZvaWQgU2hhcmVkRHRvcigpOworICB2b2lkIFNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0OworICB2b2lkIEludGVybmFsU3dhcChJbnQ2NFZhbHVlKiBvdGhlcik7CisgIHByb3RlY3RlZDoKKyAgZXhwbGljaXQgSW50NjRWYWx1ZSg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSk7CisgIHByaXZhdGU6CisgIHN0YXRpYyB2b2lkIEFyZW5hRHRvcih2b2lkKiBvYmplY3QpOworICBpbmxpbmUgdm9pZCBSZWdpc3RlckFyZW5hRHRvcig6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSk7CisgIHByaXZhdGU6CisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYU5vVmlydHVhbCgpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5hcmVuYSgpOworICB9CisgIGlubGluZSB2b2lkKiBNYXliZUFyZW5hUHRyKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnJhd19hcmVuYV9wdHIoKTsKKyAgfQorICBwdWJsaWM6CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBHZXRNZXRhZGF0YSgpIGNvbnN0OworCisgIC8vIG5lc3RlZCB0eXBlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gYWNjZXNzb3JzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBvcHRpb25hbCBpbnQ2NCB2YWx1ZSA9IDE7CisgIHZvaWQgY2xlYXJfdmFsdWUoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrVmFsdWVGaWVsZE51bWJlciA9IDE7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50NjQgdmFsdWUoKSBjb25zdDsKKyAgdm9pZCBzZXRfdmFsdWUoOjpnb29nbGU6OnByb3RvYnVmOjppbnQ2NCB2YWx1ZSk7CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlKQorIHByaXZhdGU6CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6SW50ZXJuYWxNZXRhZGF0YVdpdGhBcmVuYSBfaW50ZXJuYWxfbWV0YWRhdGFfOworICBmcmllbmQgY2xhc3MgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYTsKKyAgdHlwZWRlZiB2b2lkIEludGVybmFsQXJlbmFDb25zdHJ1Y3RhYmxlXzsKKyAgdHlwZWRlZiB2b2lkIERlc3RydWN0b3JTa2lwcGFibGVfOworICBib29sIF9pc19kZWZhdWx0X2luc3RhbmNlXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnQ2NCB2YWx1ZV87CisgIG11dGFibGUgaW50IF9jYWNoZWRfc2l6ZV87CisgIGZyaWVuZCB2b2lkIExJQlBST1RPQlVGX0VYUE9SVCBwcm90b2J1Zl9BZGREZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmd3JhcHBlcnNfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9Bc3NpZ25EZXNjX2dvb2dsZV8yZnByb3RvYnVmXzJmd3JhcHBlcnNfMmVwcm90bygpOworICBmcmllbmQgdm9pZCBwcm90b2J1Zl9TaHV0ZG93bkZpbGVfZ29vZ2xlXzJmcHJvdG9idWZfMmZ3cmFwcGVyc18yZXByb3RvKCk7CisKKyAgdm9pZCBJbml0QXNEZWZhdWx0SW5zdGFuY2UoKTsKKyAgc3RhdGljIEludDY0VmFsdWUqIGRlZmF1bHRfaW5zdGFuY2VfOworfTsKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFVJbnQ2NFZhbHVlIDogcHVibGljIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSB7CisgcHVibGljOgorICBVSW50NjRWYWx1ZSgpOworICB2aXJ0dWFsIH5VSW50NjRWYWx1ZSgpOworCisgIFVJbnQ2NFZhbHVlKGNvbnN0IFVJbnQ2NFZhbHVlJiBmcm9tKTsKKworICBpbmxpbmUgVUludDY0VmFsdWUmIG9wZXJhdG9yPShjb25zdCBVSW50NjRWYWx1ZSYgZnJvbSkgeworICAgIENvcHlGcm9tKGZyb20pOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYSgpIGNvbnN0IHsgcmV0dXJuIEdldEFyZW5hTm9WaXJ0dWFsKCk7IH0KKyAgaW5saW5lIHZvaWQqIEdldE1heWJlQXJlbmFQb2ludGVyKCkgY29uc3QgeworICAgIHJldHVybiBNYXliZUFyZW5hUHRyKCk7CisgIH0KKyAgc3RhdGljIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogZGVzY3JpcHRvcigpOworICBzdGF0aWMgY29uc3QgVUludDY0VmFsdWUmIGRlZmF1bHRfaW5zdGFuY2UoKTsKKworICB2b2lkIFVuc2FmZUFyZW5hU3dhcChVSW50NjRWYWx1ZSogb3RoZXIpOworICB2b2lkIFN3YXAoVUludDY0VmFsdWUqIG90aGVyKTsKKworICAvLyBpbXBsZW1lbnRzIE1lc3NhZ2UgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIGlubGluZSBVSW50NjRWYWx1ZSogTmV3KCkgY29uc3QgeyByZXR1cm4gTmV3KE5VTEwpOyB9CisKKyAgVUludDY0VmFsdWUqIE5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3Q7CisgIHZvaWQgQ29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCBVSW50NjRWYWx1ZSYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IFVJbnQ2NFZhbHVlJiBmcm9tKTsKKyAgdm9pZCBDbGVhcigpOworICBib29sIElzSW5pdGlhbGl6ZWQoKSBjb25zdDsKKworICBpbnQgQnl0ZVNpemUoKSBjb25zdDsKKyAgYm9vbCBNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCk7CisgIHZvaWQgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogb3V0cHV0KSBjb25zdDsKKyAgaW50IEdldENhY2hlZFNpemUoKSBjb25zdCB7IHJldHVybiBfY2FjaGVkX3NpemVfOyB9CisgIHByaXZhdGU6CisgIHZvaWQgU2hhcmVkQ3RvcigpOworICB2b2lkIFNoYXJlZER0b3IoKTsKKyAgdm9pZCBTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdDsKKyAgdm9pZCBJbnRlcm5hbFN3YXAoVUludDY0VmFsdWUqIG90aGVyKTsKKyAgcHJvdGVjdGVkOgorICBleHBsaWNpdCBVSW50NjRWYWx1ZSg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSk7CisgIHByaXZhdGU6CisgIHN0YXRpYyB2b2lkIEFyZW5hRHRvcih2b2lkKiBvYmplY3QpOworICBpbmxpbmUgdm9pZCBSZWdpc3RlckFyZW5hRHRvcig6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSk7CisgIHByaXZhdGU6CisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYU5vVmlydHVhbCgpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5hcmVuYSgpOworICB9CisgIGlubGluZSB2b2lkKiBNYXliZUFyZW5hUHRyKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnJhd19hcmVuYV9wdHIoKTsKKyAgfQorICBwdWJsaWM6CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBHZXRNZXRhZGF0YSgpIGNvbnN0OworCisgIC8vIG5lc3RlZCB0eXBlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gYWNjZXNzb3JzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBvcHRpb25hbCB1aW50NjQgdmFsdWUgPSAxOworICB2b2lkIGNsZWFyX3ZhbHVlKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga1ZhbHVlRmllbGROdW1iZXIgPSAxOworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ2NCB2YWx1ZSgpIGNvbnN0OworICB2b2lkIHNldF92YWx1ZSg6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ2NCB2YWx1ZSk7CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSkKKyBwcml2YXRlOgorCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEgX2ludGVybmFsX21ldGFkYXRhXzsKKyAgZnJpZW5kIGNsYXNzIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmE7CisgIHR5cGVkZWYgdm9pZCBJbnRlcm5hbEFyZW5hQ29uc3RydWN0YWJsZV87CisgIHR5cGVkZWYgdm9pZCBEZXN0cnVjdG9yU2tpcHBhYmxlXzsKKyAgYm9vbCBfaXNfZGVmYXVsdF9pbnN0YW5jZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDY0IHZhbHVlXzsKKyAgbXV0YWJsZSBpbnQgX2NhY2hlZF9zaXplXzsKKyAgZnJpZW5kIHZvaWQgTElCUFJPVE9CVUZfRVhQT1JUIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZ3cmFwcGVyc18yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZ3cmFwcGVyc18yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZndyYXBwZXJzXzJlcHJvdG8oKTsKKworICB2b2lkIEluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICBzdGF0aWMgVUludDY0VmFsdWUqIGRlZmF1bHRfaW5zdGFuY2VfOworfTsKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEludDMyVmFsdWUgOiBwdWJsaWMgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlIHsKKyBwdWJsaWM6CisgIEludDMyVmFsdWUoKTsKKyAgdmlydHVhbCB+SW50MzJWYWx1ZSgpOworCisgIEludDMyVmFsdWUoY29uc3QgSW50MzJWYWx1ZSYgZnJvbSk7CisKKyAgaW5saW5lIEludDMyVmFsdWUmIG9wZXJhdG9yPShjb25zdCBJbnQzMlZhbHVlJiBmcm9tKSB7CisgICAgQ29weUZyb20oZnJvbSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hKCkgY29uc3QgeyByZXR1cm4gR2V0QXJlbmFOb1ZpcnR1YWwoKTsgfQorICBpbmxpbmUgdm9pZCogR2V0TWF5YmVBcmVuYVBvaW50ZXIoKSBjb25zdCB7CisgICAgcmV0dXJuIE1heWJlQXJlbmFQdHIoKTsKKyAgfQorICBzdGF0aWMgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKCk7CisgIHN0YXRpYyBjb25zdCBJbnQzMlZhbHVlJiBkZWZhdWx0X2luc3RhbmNlKCk7CisKKyAgdm9pZCBVbnNhZmVBcmVuYVN3YXAoSW50MzJWYWx1ZSogb3RoZXIpOworICB2b2lkIFN3YXAoSW50MzJWYWx1ZSogb3RoZXIpOworCisgIC8vIGltcGxlbWVudHMgTWVzc2FnZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgaW5saW5lIEludDMyVmFsdWUqIE5ldygpIGNvbnN0IHsgcmV0dXJuIE5ldyhOVUxMKTsgfQorCisgIEludDMyVmFsdWUqIE5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3Q7CisgIHZvaWQgQ29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCBJbnQzMlZhbHVlJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgSW50MzJWYWx1ZSYgZnJvbSk7CisgIHZvaWQgQ2xlYXIoKTsKKyAgYm9vbCBJc0luaXRpYWxpemVkKCkgY29uc3Q7CisKKyAgaW50IEJ5dGVTaXplKCkgY29uc3Q7CisgIGJvb2wgTWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpOworICB2b2lkIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIG91dHB1dCkgY29uc3Q7CisgIGludCBHZXRDYWNoZWRTaXplKCkgY29uc3QgeyByZXR1cm4gX2NhY2hlZF9zaXplXzsgfQorICBwcml2YXRlOgorICB2b2lkIFNoYXJlZEN0b3IoKTsKKyAgdm9pZCBTaGFyZWREdG9yKCk7CisgIHZvaWQgU2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3Q7CisgIHZvaWQgSW50ZXJuYWxTd2FwKEludDMyVmFsdWUqIG90aGVyKTsKKyAgcHJvdGVjdGVkOgorICBleHBsaWNpdCBJbnQzMlZhbHVlKDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKTsKKyAgcHJpdmF0ZToKKyAgc3RhdGljIHZvaWQgQXJlbmFEdG9yKHZvaWQqIG9iamVjdCk7CisgIGlubGluZSB2b2lkIFJlZ2lzdGVyQXJlbmFEdG9yKDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKTsKKyAgcHJpdmF0ZToKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hTm9WaXJ0dWFsKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLmFyZW5hKCk7CisgIH0KKyAgaW5saW5lIHZvaWQqIE1heWJlQXJlbmFQdHIoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ucmF3X2FyZW5hX3B0cigpOworICB9CisgIHB1YmxpYzoKKworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEdldE1ldGFkYXRhKCkgY29uc3Q7CisKKyAgLy8gbmVzdGVkIHR5cGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBhY2Nlc3NvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIG9wdGlvbmFsIGludDMyIHZhbHVlID0gMTsKKyAgdm9pZCBjbGVhcl92YWx1ZSgpOworICBzdGF0aWMgY29uc3QgaW50IGtWYWx1ZUZpZWxkTnVtYmVyID0gMTsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiB2YWx1ZSgpIGNvbnN0OworICB2b2lkIHNldF92YWx1ZSg6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlKTsKKworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6Z29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUpCisgcHJpdmF0ZToKKworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpJbnRlcm5hbE1ldGFkYXRhV2l0aEFyZW5hIF9pbnRlcm5hbF9tZXRhZGF0YV87CisgIGZyaWVuZCBjbGFzcyA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hOworICB0eXBlZGVmIHZvaWQgSW50ZXJuYWxBcmVuYUNvbnN0cnVjdGFibGVfOworICB0eXBlZGVmIHZvaWQgRGVzdHJ1Y3RvclNraXBwYWJsZV87CisgIGJvb2wgX2lzX2RlZmF1bHRfaW5zdGFuY2VfOworICA6Omdvb2dsZTo6cHJvdG9idWY6OmludDMyIHZhbHVlXzsKKyAgbXV0YWJsZSBpbnQgX2NhY2hlZF9zaXplXzsKKyAgZnJpZW5kIHZvaWQgTElCUFJPVE9CVUZfRVhQT1JUIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZ3cmFwcGVyc18yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZ3cmFwcGVyc18yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZndyYXBwZXJzXzJlcHJvdG8oKTsKKworICB2b2lkIEluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICBzdGF0aWMgSW50MzJWYWx1ZSogZGVmYXVsdF9pbnN0YW5jZV87Cit9OworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgVUludDMyVmFsdWUgOiBwdWJsaWMgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlIHsKKyBwdWJsaWM6CisgIFVJbnQzMlZhbHVlKCk7CisgIHZpcnR1YWwgflVJbnQzMlZhbHVlKCk7CisKKyAgVUludDMyVmFsdWUoY29uc3QgVUludDMyVmFsdWUmIGZyb20pOworCisgIGlubGluZSBVSW50MzJWYWx1ZSYgb3BlcmF0b3I9KGNvbnN0IFVJbnQzMlZhbHVlJiBmcm9tKSB7CisgICAgQ29weUZyb20oZnJvbSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hKCkgY29uc3QgeyByZXR1cm4gR2V0QXJlbmFOb1ZpcnR1YWwoKTsgfQorICBpbmxpbmUgdm9pZCogR2V0TWF5YmVBcmVuYVBvaW50ZXIoKSBjb25zdCB7CisgICAgcmV0dXJuIE1heWJlQXJlbmFQdHIoKTsKKyAgfQorICBzdGF0aWMgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKCk7CisgIHN0YXRpYyBjb25zdCBVSW50MzJWYWx1ZSYgZGVmYXVsdF9pbnN0YW5jZSgpOworCisgIHZvaWQgVW5zYWZlQXJlbmFTd2FwKFVJbnQzMlZhbHVlKiBvdGhlcik7CisgIHZvaWQgU3dhcChVSW50MzJWYWx1ZSogb3RoZXIpOworCisgIC8vIGltcGxlbWVudHMgTWVzc2FnZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgaW5saW5lIFVJbnQzMlZhbHVlKiBOZXcoKSBjb25zdCB7IHJldHVybiBOZXcoTlVMTCk7IH0KKworICBVSW50MzJWYWx1ZSogTmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdDsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIENvcHlGcm9tKGNvbnN0IFVJbnQzMlZhbHVlJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgVUludDMyVmFsdWUmIGZyb20pOworICB2b2lkIENsZWFyKCk7CisgIGJvb2wgSXNJbml0aWFsaXplZCgpIGNvbnN0OworCisgIGludCBCeXRlU2l6ZSgpIGNvbnN0OworICBib29sIE1lcmdlUGFydGlhbEZyb21Db2RlZFN0cmVhbSgKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkSW5wdXRTdHJlYW0qIGlucHV0KTsKKyAgdm9pZCBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXMoCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZE91dHB1dFN0cmVhbSogb3V0cHV0KSBjb25zdDsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogU2VyaWFsaXplV2l0aENhY2hlZFNpemVzVG9BcnJheSg6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBvdXRwdXQpIGNvbnN0OworICBpbnQgR2V0Q2FjaGVkU2l6ZSgpIGNvbnN0IHsgcmV0dXJuIF9jYWNoZWRfc2l6ZV87IH0KKyAgcHJpdmF0ZToKKyAgdm9pZCBTaGFyZWRDdG9yKCk7CisgIHZvaWQgU2hhcmVkRHRvcigpOworICB2b2lkIFNldENhY2hlZFNpemUoaW50IHNpemUpIGNvbnN0OworICB2b2lkIEludGVybmFsU3dhcChVSW50MzJWYWx1ZSogb3RoZXIpOworICBwcm90ZWN0ZWQ6CisgIGV4cGxpY2l0IFVJbnQzMlZhbHVlKDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKTsKKyAgcHJpdmF0ZToKKyAgc3RhdGljIHZvaWQgQXJlbmFEdG9yKHZvaWQqIG9iamVjdCk7CisgIGlubGluZSB2b2lkIFJlZ2lzdGVyQXJlbmFEdG9yKDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKTsKKyAgcHJpdmF0ZToKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hTm9WaXJ0dWFsKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLmFyZW5hKCk7CisgIH0KKyAgaW5saW5lIHZvaWQqIE1heWJlQXJlbmFQdHIoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ucmF3X2FyZW5hX3B0cigpOworICB9CisgIHB1YmxpYzoKKworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEdldE1ldGFkYXRhKCkgY29uc3Q7CisKKyAgLy8gbmVzdGVkIHR5cGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBhY2Nlc3NvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIG9wdGlvbmFsIHVpbnQzMiB2YWx1ZSA9IDE7CisgIHZvaWQgY2xlYXJfdmFsdWUoKTsKKyAgc3RhdGljIGNvbnN0IGludCBrVmFsdWVGaWVsZE51bWJlciA9IDE7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIHZhbHVlKCkgY29uc3Q7CisgIHZvaWQgc2V0X3ZhbHVlKDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDMyIHZhbHVlKTsKKworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6Z29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlKQorIHByaXZhdGU6CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6SW50ZXJuYWxNZXRhZGF0YVdpdGhBcmVuYSBfaW50ZXJuYWxfbWV0YWRhdGFfOworICBmcmllbmQgY2xhc3MgOjpnb29nbGU6OnByb3RvYnVmOjpBcmVuYTsKKyAgdHlwZWRlZiB2b2lkIEludGVybmFsQXJlbmFDb25zdHJ1Y3RhYmxlXzsKKyAgdHlwZWRlZiB2b2lkIERlc3RydWN0b3JTa2lwcGFibGVfOworICBib29sIF9pc19kZWZhdWx0X2luc3RhbmNlXzsKKyAgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgdmFsdWVfOworICBtdXRhYmxlIGludCBfY2FjaGVkX3NpemVfOworICBmcmllbmQgdm9pZCBMSUJQUk9UT0JVRl9FWFBPUlQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZndyYXBwZXJzXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfQXNzaWduRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZndyYXBwZXJzXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfU2h1dGRvd25GaWxlX2dvb2dsZV8yZnByb3RvYnVmXzJmd3JhcHBlcnNfMmVwcm90bygpOworCisgIHZvaWQgSW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIHN0YXRpYyBVSW50MzJWYWx1ZSogZGVmYXVsdF9pbnN0YW5jZV87Cit9OworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitjbGFzcyBMSUJQUk9UT0JVRl9FWFBPUlQgQm9vbFZhbHVlIDogcHVibGljIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSB7CisgcHVibGljOgorICBCb29sVmFsdWUoKTsKKyAgdmlydHVhbCB+Qm9vbFZhbHVlKCk7CisKKyAgQm9vbFZhbHVlKGNvbnN0IEJvb2xWYWx1ZSYgZnJvbSk7CisKKyAgaW5saW5lIEJvb2xWYWx1ZSYgb3BlcmF0b3I9KGNvbnN0IEJvb2xWYWx1ZSYgZnJvbSkgeworICAgIENvcHlGcm9tKGZyb20pOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYSgpIGNvbnN0IHsgcmV0dXJuIEdldEFyZW5hTm9WaXJ0dWFsKCk7IH0KKyAgaW5saW5lIHZvaWQqIEdldE1heWJlQXJlbmFQb2ludGVyKCkgY29uc3QgeworICAgIHJldHVybiBNYXliZUFyZW5hUHRyKCk7CisgIH0KKyAgc3RhdGljIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogZGVzY3JpcHRvcigpOworICBzdGF0aWMgY29uc3QgQm9vbFZhbHVlJiBkZWZhdWx0X2luc3RhbmNlKCk7CisKKyAgdm9pZCBVbnNhZmVBcmVuYVN3YXAoQm9vbFZhbHVlKiBvdGhlcik7CisgIHZvaWQgU3dhcChCb29sVmFsdWUqIG90aGVyKTsKKworICAvLyBpbXBsZW1lbnRzIE1lc3NhZ2UgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIGlubGluZSBCb29sVmFsdWUqIE5ldygpIGNvbnN0IHsgcmV0dXJuIE5ldyhOVUxMKTsgfQorCisgIEJvb2xWYWx1ZSogTmV3KDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKSBjb25zdDsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIE1lcmdlRnJvbShjb25zdCA6Omdvb2dsZTo6cHJvdG9idWY6Ok1lc3NhZ2UmIGZyb20pOworICB2b2lkIENvcHlGcm9tKGNvbnN0IEJvb2xWYWx1ZSYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IEJvb2xWYWx1ZSYgZnJvbSk7CisgIHZvaWQgQ2xlYXIoKTsKKyAgYm9vbCBJc0luaXRpYWxpemVkKCkgY29uc3Q7CisKKyAgaW50IEJ5dGVTaXplKCkgY29uc3Q7CisgIGJvb2wgTWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpOworICB2b2lkIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIG91dHB1dCkgY29uc3Q7CisgIGludCBHZXRDYWNoZWRTaXplKCkgY29uc3QgeyByZXR1cm4gX2NhY2hlZF9zaXplXzsgfQorICBwcml2YXRlOgorICB2b2lkIFNoYXJlZEN0b3IoKTsKKyAgdm9pZCBTaGFyZWREdG9yKCk7CisgIHZvaWQgU2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3Q7CisgIHZvaWQgSW50ZXJuYWxTd2FwKEJvb2xWYWx1ZSogb3RoZXIpOworICBwcm90ZWN0ZWQ6CisgIGV4cGxpY2l0IEJvb2xWYWx1ZSg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSk7CisgIHByaXZhdGU6CisgIHN0YXRpYyB2b2lkIEFyZW5hRHRvcih2b2lkKiBvYmplY3QpOworICBpbmxpbmUgdm9pZCBSZWdpc3RlckFyZW5hRHRvcig6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSk7CisgIHByaXZhdGU6CisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYU5vVmlydHVhbCgpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5hcmVuYSgpOworICB9CisgIGlubGluZSB2b2lkKiBNYXliZUFyZW5hUHRyKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnJhd19hcmVuYV9wdHIoKTsKKyAgfQorICBwdWJsaWM6CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBHZXRNZXRhZGF0YSgpIGNvbnN0OworCisgIC8vIG5lc3RlZCB0eXBlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gYWNjZXNzb3JzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBvcHRpb25hbCBib29sIHZhbHVlID0gMTsKKyAgdm9pZCBjbGVhcl92YWx1ZSgpOworICBzdGF0aWMgY29uc3QgaW50IGtWYWx1ZUZpZWxkTnVtYmVyID0gMTsKKyAgYm9vbCB2YWx1ZSgpIGNvbnN0OworICB2b2lkIHNldF92YWx1ZShib29sIHZhbHVlKTsKKworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6Z29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSkKKyBwcml2YXRlOgorCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEgX2ludGVybmFsX21ldGFkYXRhXzsKKyAgZnJpZW5kIGNsYXNzIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmE7CisgIHR5cGVkZWYgdm9pZCBJbnRlcm5hbEFyZW5hQ29uc3RydWN0YWJsZV87CisgIHR5cGVkZWYgdm9pZCBEZXN0cnVjdG9yU2tpcHBhYmxlXzsKKyAgYm9vbCBfaXNfZGVmYXVsdF9pbnN0YW5jZV87CisgIGJvb2wgdmFsdWVfOworICBtdXRhYmxlIGludCBfY2FjaGVkX3NpemVfOworICBmcmllbmQgdm9pZCBMSUJQUk9UT0JVRl9FWFBPUlQgcHJvdG9idWZfQWRkRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZndyYXBwZXJzXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfQXNzaWduRGVzY19nb29nbGVfMmZwcm90b2J1Zl8yZndyYXBwZXJzXzJlcHJvdG8oKTsKKyAgZnJpZW5kIHZvaWQgcHJvdG9idWZfU2h1dGRvd25GaWxlX2dvb2dsZV8yZnByb3RvYnVmXzJmd3JhcHBlcnNfMmVwcm90bygpOworCisgIHZvaWQgSW5pdEFzRGVmYXVsdEluc3RhbmNlKCk7CisgIHN0YXRpYyBCb29sVmFsdWUqIGRlZmF1bHRfaW5zdGFuY2VfOworfTsKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIFN0cmluZ1ZhbHVlIDogcHVibGljIDo6Z29vZ2xlOjpwcm90b2J1Zjo6TWVzc2FnZSB7CisgcHVibGljOgorICBTdHJpbmdWYWx1ZSgpOworICB2aXJ0dWFsIH5TdHJpbmdWYWx1ZSgpOworCisgIFN0cmluZ1ZhbHVlKGNvbnN0IFN0cmluZ1ZhbHVlJiBmcm9tKTsKKworICBpbmxpbmUgU3RyaW5nVmFsdWUmIG9wZXJhdG9yPShjb25zdCBTdHJpbmdWYWx1ZSYgZnJvbSkgeworICAgIENvcHlGcm9tKGZyb20pOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYSgpIGNvbnN0IHsgcmV0dXJuIEdldEFyZW5hTm9WaXJ0dWFsKCk7IH0KKyAgaW5saW5lIHZvaWQqIEdldE1heWJlQXJlbmFQb2ludGVyKCkgY29uc3QgeworICAgIHJldHVybiBNYXliZUFyZW5hUHRyKCk7CisgIH0KKyAgc3RhdGljIGNvbnN0IDo6Z29vZ2xlOjpwcm90b2J1Zjo6RGVzY3JpcHRvciogZGVzY3JpcHRvcigpOworICBzdGF0aWMgY29uc3QgU3RyaW5nVmFsdWUmIGRlZmF1bHRfaW5zdGFuY2UoKTsKKworICB2b2lkIFVuc2FmZUFyZW5hU3dhcChTdHJpbmdWYWx1ZSogb3RoZXIpOworICB2b2lkIFN3YXAoU3RyaW5nVmFsdWUqIG90aGVyKTsKKworICAvLyBpbXBsZW1lbnRzIE1lc3NhZ2UgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIGlubGluZSBTdHJpbmdWYWx1ZSogTmV3KCkgY29uc3QgeyByZXR1cm4gTmV3KE5VTEwpOyB9CisKKyAgU3RyaW5nVmFsdWUqIE5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3Q7CisgIHZvaWQgQ29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCBTdHJpbmdWYWx1ZSYgZnJvbSk7CisgIHZvaWQgTWVyZ2VGcm9tKGNvbnN0IFN0cmluZ1ZhbHVlJiBmcm9tKTsKKyAgdm9pZCBDbGVhcigpOworICBib29sIElzSW5pdGlhbGl6ZWQoKSBjb25zdDsKKworICBpbnQgQnl0ZVNpemUoKSBjb25zdDsKKyAgYm9vbCBNZXJnZVBhcnRpYWxGcm9tQ29kZWRTdHJlYW0oCisgICAgICA6Omdvb2dsZTo6cHJvdG9idWY6OmlvOjpDb2RlZElucHV0U3RyZWFtKiBpbnB1dCk7CisgIHZvaWQgU2VyaWFsaXplV2l0aENhY2hlZFNpemVzKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRPdXRwdXRTdHJlYW0qIG91dHB1dCkgY29uc3Q7CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplc1RvQXJyYXkoOjpnb29nbGU6OnByb3RvYnVmOjp1aW50OCogb3V0cHV0KSBjb25zdDsKKyAgaW50IEdldENhY2hlZFNpemUoKSBjb25zdCB7IHJldHVybiBfY2FjaGVkX3NpemVfOyB9CisgIHByaXZhdGU6CisgIHZvaWQgU2hhcmVkQ3RvcigpOworICB2b2lkIFNoYXJlZER0b3IoKTsKKyAgdm9pZCBTZXRDYWNoZWRTaXplKGludCBzaXplKSBjb25zdDsKKyAgdm9pZCBJbnRlcm5hbFN3YXAoU3RyaW5nVmFsdWUqIG90aGVyKTsKKyAgcHJvdGVjdGVkOgorICBleHBsaWNpdCBTdHJpbmdWYWx1ZSg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSk7CisgIHByaXZhdGU6CisgIHN0YXRpYyB2b2lkIEFyZW5hRHRvcih2b2lkKiBvYmplY3QpOworICBpbmxpbmUgdm9pZCBSZWdpc3RlckFyZW5hRHRvcig6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSk7CisgIHByaXZhdGU6CisgIGlubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBHZXRBcmVuYU5vVmlydHVhbCgpIGNvbnN0IHsKKyAgICByZXR1cm4gX2ludGVybmFsX21ldGFkYXRhXy5hcmVuYSgpOworICB9CisgIGlubGluZSB2b2lkKiBNYXliZUFyZW5hUHRyKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLnJhd19hcmVuYV9wdHIoKTsKKyAgfQorICBwdWJsaWM6CisKKyAgOjpnb29nbGU6OnByb3RvYnVmOjpNZXRhZGF0YSBHZXRNZXRhZGF0YSgpIGNvbnN0OworCisgIC8vIG5lc3RlZCB0eXBlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgLy8gYWNjZXNzb3JzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBvcHRpb25hbCBzdHJpbmcgdmFsdWUgPSAxOworICB2b2lkIGNsZWFyX3ZhbHVlKCk7CisgIHN0YXRpYyBjb25zdCBpbnQga1ZhbHVlRmllbGROdW1iZXIgPSAxOworICBjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSgpIGNvbnN0OworICB2b2lkIHNldF92YWx1ZShjb25zdCA6OnN0ZDo6c3RyaW5nJiB2YWx1ZSk7CisgIHZvaWQgc2V0X3ZhbHVlKGNvbnN0IGNoYXIqIHZhbHVlKTsKKyAgdm9pZCBzZXRfdmFsdWUoY29uc3QgY2hhciogdmFsdWUsIHNpemVfdCBzaXplKTsKKyAgOjpzdGQ6OnN0cmluZyogbXV0YWJsZV92YWx1ZSgpOworICA6OnN0ZDo6c3RyaW5nKiByZWxlYXNlX3ZhbHVlKCk7CisgIHZvaWQgc2V0X2FsbG9jYXRlZF92YWx1ZSg6OnN0ZDo6c3RyaW5nKiB2YWx1ZSk7CisgIDo6c3RkOjpzdHJpbmcqIHVuc2FmZV9hcmVuYV9yZWxlYXNlX3ZhbHVlKCk7CisgIHZvaWQgdW5zYWZlX2FyZW5hX3NldF9hbGxvY2F0ZWRfdmFsdWUoCisgICAgICA6OnN0ZDo6c3RyaW5nKiB2YWx1ZSk7CisKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSkKKyBwcml2YXRlOgorCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEgX2ludGVybmFsX21ldGFkYXRhXzsKKyAgZnJpZW5kIGNsYXNzIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmE7CisgIHR5cGVkZWYgdm9pZCBJbnRlcm5hbEFyZW5hQ29uc3RydWN0YWJsZV87CisgIHR5cGVkZWYgdm9pZCBEZXN0cnVjdG9yU2tpcHBhYmxlXzsKKyAgYm9vbCBfaXNfZGVmYXVsdF9pbnN0YW5jZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFyZW5hU3RyaW5nUHRyIHZhbHVlXzsKKyAgbXV0YWJsZSBpbnQgX2NhY2hlZF9zaXplXzsKKyAgZnJpZW5kIHZvaWQgTElCUFJPVE9CVUZfRVhQT1JUIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZ3cmFwcGVyc18yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZ3cmFwcGVyc18yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZndyYXBwZXJzXzJlcHJvdG8oKTsKKworICB2b2lkIEluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICBzdGF0aWMgU3RyaW5nVmFsdWUqIGRlZmF1bHRfaW5zdGFuY2VfOworfTsKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworY2xhc3MgTElCUFJPVE9CVUZfRVhQT1JUIEJ5dGVzVmFsdWUgOiBwdWJsaWMgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlIHsKKyBwdWJsaWM6CisgIEJ5dGVzVmFsdWUoKTsKKyAgdmlydHVhbCB+Qnl0ZXNWYWx1ZSgpOworCisgIEJ5dGVzVmFsdWUoY29uc3QgQnl0ZXNWYWx1ZSYgZnJvbSk7CisKKyAgaW5saW5lIEJ5dGVzVmFsdWUmIG9wZXJhdG9yPShjb25zdCBCeXRlc1ZhbHVlJiBmcm9tKSB7CisgICAgQ29weUZyb20oZnJvbSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hKCkgY29uc3QgeyByZXR1cm4gR2V0QXJlbmFOb1ZpcnR1YWwoKTsgfQorICBpbmxpbmUgdm9pZCogR2V0TWF5YmVBcmVuYVBvaW50ZXIoKSBjb25zdCB7CisgICAgcmV0dXJuIE1heWJlQXJlbmFQdHIoKTsKKyAgfQorICBzdGF0aWMgY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpEZXNjcmlwdG9yKiBkZXNjcmlwdG9yKCk7CisgIHN0YXRpYyBjb25zdCBCeXRlc1ZhbHVlJiBkZWZhdWx0X2luc3RhbmNlKCk7CisKKyAgdm9pZCBVbnNhZmVBcmVuYVN3YXAoQnl0ZXNWYWx1ZSogb3RoZXIpOworICB2b2lkIFN3YXAoQnl0ZXNWYWx1ZSogb3RoZXIpOworCisgIC8vIGltcGxlbWVudHMgTWVzc2FnZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgaW5saW5lIEJ5dGVzVmFsdWUqIE5ldygpIGNvbnN0IHsgcmV0dXJuIE5ldyhOVUxMKTsgfQorCisgIEJ5dGVzVmFsdWUqIE5ldyg6Omdvb2dsZTo6cHJvdG9idWY6OkFyZW5hKiBhcmVuYSkgY29uc3Q7CisgIHZvaWQgQ29weUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgOjpnb29nbGU6OnByb3RvYnVmOjpNZXNzYWdlJiBmcm9tKTsKKyAgdm9pZCBDb3B5RnJvbShjb25zdCBCeXRlc1ZhbHVlJiBmcm9tKTsKKyAgdm9pZCBNZXJnZUZyb20oY29uc3QgQnl0ZXNWYWx1ZSYgZnJvbSk7CisgIHZvaWQgQ2xlYXIoKTsKKyAgYm9vbCBJc0luaXRpYWxpemVkKCkgY29uc3Q7CisKKyAgaW50IEJ5dGVTaXplKCkgY29uc3Q7CisgIGJvb2wgTWVyZ2VQYXJ0aWFsRnJvbUNvZGVkU3RyZWFtKAorICAgICAgOjpnb29nbGU6OnByb3RvYnVmOjppbzo6Q29kZWRJbnB1dFN0cmVhbSogaW5wdXQpOworICB2b2lkIFNlcmlhbGl6ZVdpdGhDYWNoZWRTaXplcygKKyAgICAgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW86OkNvZGVkT3V0cHV0U3RyZWFtKiBvdXRwdXQpIGNvbnN0OworICA6Omdvb2dsZTo6cHJvdG9idWY6OnVpbnQ4KiBTZXJpYWxpemVXaXRoQ2FjaGVkU2l6ZXNUb0FycmF5KDo6Z29vZ2xlOjpwcm90b2J1Zjo6dWludDgqIG91dHB1dCkgY29uc3Q7CisgIGludCBHZXRDYWNoZWRTaXplKCkgY29uc3QgeyByZXR1cm4gX2NhY2hlZF9zaXplXzsgfQorICBwcml2YXRlOgorICB2b2lkIFNoYXJlZEN0b3IoKTsKKyAgdm9pZCBTaGFyZWREdG9yKCk7CisgIHZvaWQgU2V0Q2FjaGVkU2l6ZShpbnQgc2l6ZSkgY29uc3Q7CisgIHZvaWQgSW50ZXJuYWxTd2FwKEJ5dGVzVmFsdWUqIG90aGVyKTsKKyAgcHJvdGVjdGVkOgorICBleHBsaWNpdCBCeXRlc1ZhbHVlKDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKTsKKyAgcHJpdmF0ZToKKyAgc3RhdGljIHZvaWQgQXJlbmFEdG9yKHZvaWQqIG9iamVjdCk7CisgIGlubGluZSB2b2lkIFJlZ2lzdGVyQXJlbmFEdG9yKDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIGFyZW5hKTsKKyAgcHJpdmF0ZToKKyAgaW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmEqIEdldEFyZW5hTm9WaXJ0dWFsKCkgY29uc3QgeworICAgIHJldHVybiBfaW50ZXJuYWxfbWV0YWRhdGFfLmFyZW5hKCk7CisgIH0KKyAgaW5saW5lIHZvaWQqIE1heWJlQXJlbmFQdHIoKSBjb25zdCB7CisgICAgcmV0dXJuIF9pbnRlcm5hbF9tZXRhZGF0YV8ucmF3X2FyZW5hX3B0cigpOworICB9CisgIHB1YmxpYzoKKworICA6Omdvb2dsZTo6cHJvdG9idWY6Ok1ldGFkYXRhIEdldE1ldGFkYXRhKCkgY29uc3Q7CisKKyAgLy8gbmVzdGVkIHR5cGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAvLyBhY2Nlc3NvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgIC8vIG9wdGlvbmFsIGJ5dGVzIHZhbHVlID0gMTsKKyAgdm9pZCBjbGVhcl92YWx1ZSgpOworICBzdGF0aWMgY29uc3QgaW50IGtWYWx1ZUZpZWxkTnVtYmVyID0gMTsKKyAgY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUoKSBjb25zdDsKKyAgdm9pZCBzZXRfdmFsdWUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpOworICB2b2lkIHNldF92YWx1ZShjb25zdCBjaGFyKiB2YWx1ZSk7CisgIHZvaWQgc2V0X3ZhbHVlKGNvbnN0IHZvaWQqIHZhbHVlLCBzaXplX3Qgc2l6ZSk7CisgIDo6c3RkOjpzdHJpbmcqIG11dGFibGVfdmFsdWUoKTsKKyAgOjpzdGQ6OnN0cmluZyogcmVsZWFzZV92YWx1ZSgpOworICB2b2lkIHNldF9hbGxvY2F0ZWRfdmFsdWUoOjpzdGQ6OnN0cmluZyogdmFsdWUpOworICA6OnN0ZDo6c3RyaW5nKiB1bnNhZmVfYXJlbmFfcmVsZWFzZV92YWx1ZSgpOworICB2b2lkIHVuc2FmZV9hcmVuYV9zZXRfYWxsb2NhdGVkX3ZhbHVlKAorICAgICAgOjpzdGQ6OnN0cmluZyogdmFsdWUpOworCisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpnb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSkKKyBwcml2YXRlOgorCisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkludGVybmFsTWV0YWRhdGFXaXRoQXJlbmEgX2ludGVybmFsX21ldGFkYXRhXzsKKyAgZnJpZW5kIGNsYXNzIDo6Z29vZ2xlOjpwcm90b2J1Zjo6QXJlbmE7CisgIHR5cGVkZWYgdm9pZCBJbnRlcm5hbEFyZW5hQ29uc3RydWN0YWJsZV87CisgIHR5cGVkZWYgdm9pZCBEZXN0cnVjdG9yU2tpcHBhYmxlXzsKKyAgYm9vbCBfaXNfZGVmYXVsdF9pbnN0YW5jZV87CisgIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkFyZW5hU3RyaW5nUHRyIHZhbHVlXzsKKyAgbXV0YWJsZSBpbnQgX2NhY2hlZF9zaXplXzsKKyAgZnJpZW5kIHZvaWQgTElCUFJPVE9CVUZfRVhQT1JUIHByb3RvYnVmX0FkZERlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZ3cmFwcGVyc18yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX0Fzc2lnbkRlc2NfZ29vZ2xlXzJmcHJvdG9idWZfMmZ3cmFwcGVyc18yZXByb3RvKCk7CisgIGZyaWVuZCB2b2lkIHByb3RvYnVmX1NodXRkb3duRmlsZV9nb29nbGVfMmZwcm90b2J1Zl8yZndyYXBwZXJzXzJlcHJvdG8oKTsKKworICB2b2lkIEluaXRBc0RlZmF1bHRJbnN0YW5jZSgpOworICBzdGF0aWMgQnl0ZXNWYWx1ZSogZGVmYXVsdF9pbnN0YW5jZV87Cit9OworLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisKKy8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworI2lmICFQUk9UT0JVRl9JTkxJTkVfTk9UX0lOX0hFQURFUlMKKy8vIERvdWJsZVZhbHVlCisKKy8vIG9wdGlvbmFsIGRvdWJsZSB2YWx1ZSA9IDE7CitpbmxpbmUgdm9pZCBEb3VibGVWYWx1ZTo6Y2xlYXJfdmFsdWUoKSB7CisgIHZhbHVlXyA9IDA7Cit9CitpbmxpbmUgZG91YmxlIERvdWJsZVZhbHVlOjp2YWx1ZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUudmFsdWUpCisgIHJldHVybiB2YWx1ZV87Cit9CitpbmxpbmUgdm9pZCBEb3VibGVWYWx1ZTo6c2V0X3ZhbHVlKGRvdWJsZSB2YWx1ZSkgeworICAKKyAgdmFsdWVfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlLnZhbHVlKQorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIEZsb2F0VmFsdWUKKworLy8gb3B0aW9uYWwgZmxvYXQgdmFsdWUgPSAxOworaW5saW5lIHZvaWQgRmxvYXRWYWx1ZTo6Y2xlYXJfdmFsdWUoKSB7CisgIHZhbHVlXyA9IDA7Cit9CitpbmxpbmUgZmxvYXQgRmxvYXRWYWx1ZTo6dmFsdWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUudmFsdWUpCisgIHJldHVybiB2YWx1ZV87Cit9CitpbmxpbmUgdm9pZCBGbG9hdFZhbHVlOjpzZXRfdmFsdWUoZmxvYXQgdmFsdWUpIHsKKyAgCisgIHZhbHVlXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlLnZhbHVlKQorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIEludDY0VmFsdWUKKworLy8gb3B0aW9uYWwgaW50NjQgdmFsdWUgPSAxOworaW5saW5lIHZvaWQgSW50NjRWYWx1ZTo6Y2xlYXJfdmFsdWUoKSB7CisgIHZhbHVlXyA9IEdPT0dMRV9MT05HTE9ORygwKTsKK30KK2lubGluZSA6Omdvb2dsZTo6cHJvdG9idWY6OmludDY0IEludDY0VmFsdWU6OnZhbHVlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlLnZhbHVlKQorICByZXR1cm4gdmFsdWVfOworfQoraW5saW5lIHZvaWQgSW50NjRWYWx1ZTo6c2V0X3ZhbHVlKDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50NjQgdmFsdWUpIHsKKyAgCisgIHZhbHVlXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlLnZhbHVlKQorfQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIFVJbnQ2NFZhbHVlCisKKy8vIG9wdGlvbmFsIHVpbnQ2NCB2YWx1ZSA9IDE7CitpbmxpbmUgdm9pZCBVSW50NjRWYWx1ZTo6Y2xlYXJfdmFsdWUoKSB7CisgIHZhbHVlXyA9IEdPT0dMRV9VTE9OR0xPTkcoMCk7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50NjQgVUludDY0VmFsdWU6OnZhbHVlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZS52YWx1ZSkKKyAgcmV0dXJuIHZhbHVlXzsKK30KK2lubGluZSB2b2lkIFVJbnQ2NFZhbHVlOjpzZXRfdmFsdWUoOjpnb29nbGU6OnByb3RvYnVmOjp1aW50NjQgdmFsdWUpIHsKKyAgCisgIHZhbHVlXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZS52YWx1ZSkKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBJbnQzMlZhbHVlCisKKy8vIG9wdGlvbmFsIGludDMyIHZhbHVlID0gMTsKK2lubGluZSB2b2lkIEludDMyVmFsdWU6OmNsZWFyX3ZhbHVlKCkgeworICB2YWx1ZV8gPSAwOworfQoraW5saW5lIDo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50MzIgSW50MzJWYWx1ZTo6dmFsdWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUudmFsdWUpCisgIHJldHVybiB2YWx1ZV87Cit9CitpbmxpbmUgdm9pZCBJbnQzMlZhbHVlOjpzZXRfdmFsdWUoOjpnb29nbGU6OnByb3RvYnVmOjppbnQzMiB2YWx1ZSkgeworICAKKyAgdmFsdWVfID0gdmFsdWU7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUudmFsdWUpCit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gVUludDMyVmFsdWUKKworLy8gb3B0aW9uYWwgdWludDMyIHZhbHVlID0gMTsKK2lubGluZSB2b2lkIFVJbnQzMlZhbHVlOjpjbGVhcl92YWx1ZSgpIHsKKyAgdmFsdWVfID0gMHU7Cit9CitpbmxpbmUgOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgVUludDMyVmFsdWU6OnZhbHVlKCkgY29uc3QgeworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfZ2V0Omdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZS52YWx1ZSkKKyAgcmV0dXJuIHZhbHVlXzsKK30KK2lubGluZSB2b2lkIFVJbnQzMlZhbHVlOjpzZXRfdmFsdWUoOjpnb29nbGU6OnByb3RvYnVmOjp1aW50MzIgdmFsdWUpIHsKKyAgCisgIHZhbHVlXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZS52YWx1ZSkKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBCb29sVmFsdWUKKworLy8gb3B0aW9uYWwgYm9vbCB2YWx1ZSA9IDE7CitpbmxpbmUgdm9pZCBCb29sVmFsdWU6OmNsZWFyX3ZhbHVlKCkgeworICB2YWx1ZV8gPSBmYWxzZTsKK30KK2lubGluZSBib29sIEJvb2xWYWx1ZTo6dmFsdWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZS52YWx1ZSkKKyAgcmV0dXJuIHZhbHVlXzsKK30KK2lubGluZSB2b2lkIEJvb2xWYWx1ZTo6c2V0X3ZhbHVlKGJvb2wgdmFsdWUpIHsKKyAgCisgIHZhbHVlXyA9IHZhbHVlOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUudmFsdWUpCit9CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gU3RyaW5nVmFsdWUKKworLy8gb3B0aW9uYWwgc3RyaW5nIHZhbHVlID0gMTsKK2lubGluZSB2b2lkIFN0cmluZ1ZhbHVlOjpjbGVhcl92YWx1ZSgpIHsKKyAgdmFsdWVfLkNsZWFyVG9FbXB0eSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIEdldEFyZW5hTm9WaXJ0dWFsKCkpOworfQoraW5saW5lIGNvbnN0IDo6c3RkOjpzdHJpbmcmIFN0cmluZ1ZhbHVlOjp2YWx1ZSgpIGNvbnN0IHsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX2dldDpnb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUudmFsdWUpCisgIHJldHVybiB2YWx1ZV8uR2V0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBTdHJpbmdWYWx1ZTo6c2V0X3ZhbHVlKGNvbnN0IDo6c3RkOjpzdHJpbmcmIHZhbHVlKSB7CisgIAorICB2YWx1ZV8uU2V0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUsIEdldEFyZW5hTm9WaXJ0dWFsKCkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0Omdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZS52YWx1ZSkKK30KK2lubGluZSB2b2lkIFN0cmluZ1ZhbHVlOjpzZXRfdmFsdWUoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgCisgIHZhbHVlXy5TZXQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSwKKyAgICAgICAgICAgICAgR2V0QXJlbmFOb1ZpcnR1YWwoKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUudmFsdWUpCit9CitpbmxpbmUgdm9pZCBTdHJpbmdWYWx1ZTo6c2V0X3ZhbHVlKGNvbnN0IGNoYXIqIHZhbHVlLAorICAgIHNpemVfdCBzaXplKSB7CisgIAorICB2YWx1ZV8uU2V0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgOjpzdGQ6OnN0cmluZygKKyAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgY2hhcio+KHZhbHVlKSwgc2l6ZSksIEdldEFyZW5hTm9WaXJ0dWFsKCkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X3BvaW50ZXI6Z29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlLnZhbHVlKQorfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIFN0cmluZ1ZhbHVlOjptdXRhYmxlX3ZhbHVlKCkgeworICAKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX211dGFibGU6Z29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlLnZhbHVlKQorICByZXR1cm4gdmFsdWVfLk11dGFibGUoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCBHZXRBcmVuYU5vVmlydHVhbCgpKTsKK30KK2lubGluZSA6OnN0ZDo6c3RyaW5nKiBTdHJpbmdWYWx1ZTo6cmVsZWFzZV92YWx1ZSgpIHsKKyAgCisgIHJldHVybiB2YWx1ZV8uUmVsZWFzZSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIEdldEFyZW5hTm9WaXJ0dWFsKCkpOworfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIFN0cmluZ1ZhbHVlOjp1bnNhZmVfYXJlbmFfcmVsZWFzZV92YWx1ZSgpIHsKKyAgR09PR0xFX0RDSEVDSyhHZXRBcmVuYU5vVmlydHVhbCgpICE9IE5VTEwpOworICAKKyAgcmV0dXJuIHZhbHVlXy5VbnNhZmVBcmVuYVJlbGVhc2UoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLAorICAgICAgR2V0QXJlbmFOb1ZpcnR1YWwoKSk7Cit9CitpbmxpbmUgdm9pZCBTdHJpbmdWYWx1ZTo6c2V0X2FsbG9jYXRlZF92YWx1ZSg6OnN0ZDo6c3RyaW5nKiB2YWx1ZSkgeworICBpZiAodmFsdWUgIT0gTlVMTCkgeworICAgIAorICB9IGVsc2UgeworICAgIAorICB9CisgIHZhbHVlXy5TZXRBbGxvY2F0ZWQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSwKKyAgICAgIEdldEFyZW5hTm9WaXJ0dWFsKCkpOworICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfc2V0X2FsbG9jYXRlZDpnb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUudmFsdWUpCit9CitpbmxpbmUgdm9pZCBTdHJpbmdWYWx1ZTo6dW5zYWZlX2FyZW5hX3NldF9hbGxvY2F0ZWRfdmFsdWUoCisgICAgOjpzdGQ6OnN0cmluZyogdmFsdWUpIHsKKyAgR09PR0xFX0RDSEVDSyhHZXRBcmVuYU5vVmlydHVhbCgpICE9IE5VTEwpOworICBpZiAodmFsdWUgIT0gTlVMTCkgeworICAgIAorICB9IGVsc2UgeworICAgIAorICB9CisgIHZhbHVlXy5VbnNhZmVBcmVuYVNldEFsbG9jYXRlZCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICB2YWx1ZSwgR2V0QXJlbmFOb1ZpcnR1YWwoKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfYWxsb2NhdGVkOmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZS52YWx1ZSkKK30KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyBCeXRlc1ZhbHVlCisKKy8vIG9wdGlvbmFsIGJ5dGVzIHZhbHVlID0gMTsKK2lubGluZSB2b2lkIEJ5dGVzVmFsdWU6OmNsZWFyX3ZhbHVlKCkgeworICB2YWx1ZV8uQ2xlYXJUb0VtcHR5KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgR2V0QXJlbmFOb1ZpcnR1YWwoKSk7Cit9CitpbmxpbmUgY29uc3QgOjpzdGQ6OnN0cmluZyYgQnl0ZXNWYWx1ZTo6dmFsdWUoKSBjb25zdCB7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9nZXQ6Z29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUudmFsdWUpCisgIHJldHVybiB2YWx1ZV8uR2V0KCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSk7Cit9CitpbmxpbmUgdm9pZCBCeXRlc1ZhbHVlOjpzZXRfdmFsdWUoY29uc3QgOjpzdGQ6OnN0cmluZyYgdmFsdWUpIHsKKyAgCisgIHZhbHVlXy5TZXQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCB2YWx1ZSwgR2V0QXJlbmFOb1ZpcnR1YWwoKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXQ6Z29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUudmFsdWUpCit9CitpbmxpbmUgdm9pZCBCeXRlc1ZhbHVlOjpzZXRfdmFsdWUoY29uc3QgY2hhciogdmFsdWUpIHsKKyAgCisgIHZhbHVlXy5TZXQoJjo6Z29vZ2xlOjpwcm90b2J1Zjo6aW50ZXJuYWw6OkdldEVtcHR5U3RyaW5nQWxyZWFkeUluaXRlZCgpLCA6OnN0ZDo6c3RyaW5nKHZhbHVlKSwKKyAgICAgICAgICAgICAgR2V0QXJlbmFOb1ZpcnR1YWwoKSk7CisgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChmaWVsZF9zZXRfY2hhcjpnb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZS52YWx1ZSkKK30KK2lubGluZSB2b2lkIEJ5dGVzVmFsdWU6OnNldF92YWx1ZShjb25zdCB2b2lkKiB2YWx1ZSwKKyAgICBzaXplX3Qgc2l6ZSkgeworICAKKyAgdmFsdWVfLlNldCgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIDo6c3RkOjpzdHJpbmcoCisgICAgICByZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPih2YWx1ZSksIHNpemUpLCBHZXRBcmVuYU5vVmlydHVhbCgpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9wb2ludGVyOmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlLnZhbHVlKQorfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIEJ5dGVzVmFsdWU6Om11dGFibGVfdmFsdWUoKSB7CisgIAorICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZmllbGRfbXV0YWJsZTpnb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZS52YWx1ZSkKKyAgcmV0dXJuIHZhbHVlXy5NdXRhYmxlKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgR2V0QXJlbmFOb1ZpcnR1YWwoKSk7Cit9CitpbmxpbmUgOjpzdGQ6OnN0cmluZyogQnl0ZXNWYWx1ZTo6cmVsZWFzZV92YWx1ZSgpIHsKKyAgCisgIHJldHVybiB2YWx1ZV8uUmVsZWFzZSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksIEdldEFyZW5hTm9WaXJ0dWFsKCkpOworfQoraW5saW5lIDo6c3RkOjpzdHJpbmcqIEJ5dGVzVmFsdWU6OnVuc2FmZV9hcmVuYV9yZWxlYXNlX3ZhbHVlKCkgeworICBHT09HTEVfRENIRUNLKEdldEFyZW5hTm9WaXJ0dWFsKCkgIT0gTlVMTCk7CisgIAorICByZXR1cm4gdmFsdWVfLlVuc2FmZUFyZW5hUmVsZWFzZSgmOjpnb29nbGU6OnByb3RvYnVmOjppbnRlcm5hbDo6R2V0RW1wdHlTdHJpbmdBbHJlYWR5SW5pdGVkKCksCisgICAgICBHZXRBcmVuYU5vVmlydHVhbCgpKTsKK30KK2lubGluZSB2b2lkIEJ5dGVzVmFsdWU6OnNldF9hbGxvY2F0ZWRfdmFsdWUoOjpzdGQ6OnN0cmluZyogdmFsdWUpIHsKKyAgaWYgKHZhbHVlICE9IE5VTEwpIHsKKyAgICAKKyAgfSBlbHNlIHsKKyAgICAKKyAgfQorICB2YWx1ZV8uU2V0QWxsb2NhdGVkKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwgdmFsdWUsCisgICAgICBHZXRBcmVuYU5vVmlydHVhbCgpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUudmFsdWUpCit9CitpbmxpbmUgdm9pZCBCeXRlc1ZhbHVlOjp1bnNhZmVfYXJlbmFfc2V0X2FsbG9jYXRlZF92YWx1ZSgKKyAgICA6OnN0ZDo6c3RyaW5nKiB2YWx1ZSkgeworICBHT09HTEVfRENIRUNLKEdldEFyZW5hTm9WaXJ0dWFsKCkgIT0gTlVMTCk7CisgIGlmICh2YWx1ZSAhPSBOVUxMKSB7CisgICAgCisgIH0gZWxzZSB7CisgICAgCisgIH0KKyAgdmFsdWVfLlVuc2FmZUFyZW5hU2V0QWxsb2NhdGVkKCY6Omdvb2dsZTo6cHJvdG9idWY6OmludGVybmFsOjpHZXRFbXB0eVN0cmluZ0FscmVhZHlJbml0ZWQoKSwKKyAgICAgIHZhbHVlLCBHZXRBcmVuYU5vVmlydHVhbCgpKTsKKyAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGZpZWxkX3NldF9hbGxvY2F0ZWQ6Z29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUudmFsdWUpCit9CisKKyNlbmRpZiAgLy8gIVBST1RPQlVGX0lOTElORV9OT1RfSU5fSEVBREVSUworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKworLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG5hbWVzcGFjZV9zY29wZSkKKworfSAgLy8gbmFtZXNwYWNlIHByb3RvYnVmCit9ICAvLyBuYW1lc3BhY2UgZ29vZ2xlCisKKy8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChnbG9iYWxfc2NvcGUpCisKKyNlbmRpZiAgLy8gUFJPVE9CVUZfZ29vZ2xlXzJmcHJvdG9idWZfMmZ3cmFwcGVyc18yZXByb3RvX19JTkNMVURFRApkaWZmIC0tZ2l0IGEvc3JjL2dvb2dsZS9wcm90b2J1Zi93cmFwcGVycy5wcm90byBiL3NyYy9nb29nbGUvcHJvdG9idWYvd3JhcHBlcnMucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDQwZDhhMgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9nb29nbGUvcHJvdG9idWYvd3JhcHBlcnMucHJvdG8KQEAgLTAsMCArMSwxMTggQEAKKy8vIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAorLy8gQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLworLy8KKy8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQorLy8gbWV0OgorLy8KKy8vICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisvLyBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisvLyAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCisvLyBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCisvLyBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCisvLyBkaXN0cmlidXRpb24uCisvLyAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCisvLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQorLy8gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKy8vCisvLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisvLyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorLy8gTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisvLyBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorLy8gT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisvLyBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisvLyBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKy8vIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorLy8gVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorLy8gKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisvLyBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorCisvLyBXcmFwcGVycyBmb3IgcHJpbWl0aXZlIChub24tbWVzc2FnZSkgdHlwZXMuIFRoZXNlIHR5cGVzIGFyZSB1c2VmdWwKKy8vIGZvciBlbWJlZGRpbmcgcHJpbWl0aXZlcyBpbiB0aGUgYGdvb2dsZS5wcm90b2J1Zi5BbnlgIHR5cGUgYW5kIGZvciBwbGFjZXMKKy8vIHdoZXJlIHdlIG5lZWQgdG8gZGlzdGluZ3Vpc2ggYmV0d2VlbiB0aGUgYWJzZW5jZSBvZiBhIHByaW1pdGl2ZQorLy8gdHlwZWQgZmllbGQgYW5kIGl0cyBkZWZhdWx0IHZhbHVlLgorCitzeW50YXggPSAicHJvdG8zIjsKKworcGFja2FnZSBnb29nbGUucHJvdG9idWY7CisKK29wdGlvbiBjc2hhcnBfbmFtZXNwYWNlID0gIkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlcyI7CitvcHRpb24gY2NfZW5hYmxlX2FyZW5hcyA9IHRydWU7CitvcHRpb24gamF2YV9wYWNrYWdlID0gImNvbS5nb29nbGUucHJvdG9idWYiOworb3B0aW9uIGphdmFfb3V0ZXJfY2xhc3NuYW1lID0gIldyYXBwZXJzUHJvdG8iOworb3B0aW9uIGphdmFfbXVsdGlwbGVfZmlsZXMgPSB0cnVlOworb3B0aW9uIGphdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoID0gdHJ1ZTsKK29wdGlvbiBvYmpjX2NsYXNzX3ByZWZpeCA9ICJHUEIiOworCisvLyBXcmFwcGVyIG1lc3NhZ2UgZm9yIGBkb3VibGVgLgorLy8KKy8vIFRoZSBKU09OIHJlcHJlc2VudGF0aW9uIGZvciBgRG91YmxlVmFsdWVgIGlzIEpTT04gbnVtYmVyLgorbWVzc2FnZSBEb3VibGVWYWx1ZSB7CisgIC8vIFRoZSBkb3VibGUgdmFsdWUuCisgIGRvdWJsZSB2YWx1ZSA9IDE7Cit9CisKKy8vIFdyYXBwZXIgbWVzc2FnZSBmb3IgYGZsb2F0YC4KKy8vCisvLyBUaGUgSlNPTiByZXByZXNlbnRhdGlvbiBmb3IgYEZsb2F0VmFsdWVgIGlzIEpTT04gbnVtYmVyLgorbWVzc2FnZSBGbG9hdFZhbHVlIHsKKyAgLy8gVGhlIGZsb2F0IHZhbHVlLgorICBmbG9hdCB2YWx1ZSA9IDE7Cit9CisKKy8vIFdyYXBwZXIgbWVzc2FnZSBmb3IgYGludDY0YC4KKy8vCisvLyBUaGUgSlNPTiByZXByZXNlbnRhdGlvbiBmb3IgYEludDY0VmFsdWVgIGlzIEpTT04gc3RyaW5nLgorbWVzc2FnZSBJbnQ2NFZhbHVlIHsKKyAgLy8gVGhlIGludDY0IHZhbHVlLgorICBpbnQ2NCB2YWx1ZSA9IDE7Cit9CisKKy8vIFdyYXBwZXIgbWVzc2FnZSBmb3IgYHVpbnQ2NGAuCisvLworLy8gVGhlIEpTT04gcmVwcmVzZW50YXRpb24gZm9yIGBVSW50NjRWYWx1ZWAgaXMgSlNPTiBzdHJpbmcuCittZXNzYWdlIFVJbnQ2NFZhbHVlIHsKKyAgLy8gVGhlIHVpbnQ2NCB2YWx1ZS4KKyAgdWludDY0IHZhbHVlID0gMTsKK30KKworLy8gV3JhcHBlciBtZXNzYWdlIGZvciBgaW50MzJgLgorLy8KKy8vIFRoZSBKU09OIHJlcHJlc2VudGF0aW9uIGZvciBgSW50MzJWYWx1ZWAgaXMgSlNPTiBudW1iZXIuCittZXNzYWdlIEludDMyVmFsdWUgeworICAvLyBUaGUgaW50MzIgdmFsdWUuCisgIGludDMyIHZhbHVlID0gMTsKK30KKworLy8gV3JhcHBlciBtZXNzYWdlIGZvciBgdWludDMyYC4KKy8vCisvLyBUaGUgSlNPTiByZXByZXNlbnRhdGlvbiBmb3IgYFVJbnQzMlZhbHVlYCBpcyBKU09OIG51bWJlci4KK21lc3NhZ2UgVUludDMyVmFsdWUgeworICAvLyBUaGUgdWludDMyIHZhbHVlLgorICB1aW50MzIgdmFsdWUgPSAxOworfQorCisvLyBXcmFwcGVyIG1lc3NhZ2UgZm9yIGBib29sYC4KKy8vCisvLyBUaGUgSlNPTiByZXByZXNlbnRhdGlvbiBmb3IgYEJvb2xWYWx1ZWAgaXMgSlNPTiBgdHJ1ZWAgYW5kIGBmYWxzZWAuCittZXNzYWdlIEJvb2xWYWx1ZSB7CisgIC8vIFRoZSBib29sIHZhbHVlLgorICBib29sIHZhbHVlID0gMTsKK30KKworLy8gV3JhcHBlciBtZXNzYWdlIGZvciBgc3RyaW5nYC4KKy8vCisvLyBUaGUgSlNPTiByZXByZXNlbnRhdGlvbiBmb3IgYFN0cmluZ1ZhbHVlYCBpcyBKU09OIHN0cmluZy4KK21lc3NhZ2UgU3RyaW5nVmFsdWUgeworICAvLyBUaGUgc3RyaW5nIHZhbHVlLgorICBzdHJpbmcgdmFsdWUgPSAxOworfQorCisvLyBXcmFwcGVyIG1lc3NhZ2UgZm9yIGBieXRlc2AuCisvLworLy8gVGhlIEpTT04gcmVwcmVzZW50YXRpb24gZm9yIGBCeXRlc1ZhbHVlYCBpcyBKU09OIHN0cmluZy4KK21lc3NhZ2UgQnl0ZXNWYWx1ZSB7CisgIC8vIFRoZSBieXRlcyB2YWx1ZS4KKyAgYnl0ZXMgdmFsdWUgPSAxOworfQpkaWZmIC0tZ2l0IGEvc3JjL3NvbGFyaXMvbGlic3RkYysrLmxhIGIvc3JjL3NvbGFyaXMvbGlic3RkYysrLmxhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNlZGY0MjUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvc29sYXJpcy9saWJzdGRjKysubGEKQEAgLTAsMCArMSw1MSBAQAorIyBsaWJzdGRjKysubGEgLSBhIGxpYnRvb2wgbGlicmFyeSBmaWxlCisjIEdlbmVyYXRlZCBieSBsdG1haW4uc2ggLSBHTlUgbGlidG9vbCAxLjRhLUdDQzMuMCAoMS42NDEuMi4yNTYgMjAwMS8wNS8yOCAyMDowOTowNyB3aXRoIEdDQy1sb2NhbCBjaGFuZ2VzKQorIworIyBQbGVhc2UgRE8gTk9UIGRlbGV0ZSB0aGlzIGZpbGUhCisjIEl0IGlzIG5lY2Vzc2FyeSBmb3IgbGlua2luZyB0aGUgbGlicmFyeS4KKworIyAtLS0KKyMgTk9URTogVGhpcyBmaWxlIGxpdmVzIGluIC91c3Ivc2Z3L2xpYiBvbiBTb2xhcmlzIDEwLiAgVW5mb3J0dW5hdGVseSwKKyMgZHVlIHRvIGFuIGFwcGFyZW50IGJ1ZyBpbiB0aGUgU29sYXJpcyAxMCA2LzA2IHJlbGVhc2UsCisjIC91c3Ivc2Z3L2xpYi9saWJzdGRjKysubGEgaXMgZW1wdHkuICBCZWxvdyBpcyB0aGUgY29ycmVjdCBjb250ZW50LAorIyBhY2NvcmRpbmcgdG8KKyMgICAgaHR0cDovL2ZvcnVtLmphdmEuc3VuLmNvbS90aHJlYWQuanNwYT90aHJlYWRJRD01MDczMTUwCisjIEJ5IHBhc3NpbmcgTERGTEFHUz0nLUxzcmMvc29sYXJpcycgdG8gY29uZmlndXJlLCBtYWtlIHdpbGwgcGljayB1cAorIyB0aGlzIGNvcHkgb2YgdGhlIGZpbGUgcmF0aGVyIHRoYW4gdGhlIGVtcHR5IGNvcHkgaW4gL3Vzci9zZncvbGliLgorIworIyBBbHNvIHNlZQorIyAgIGh0dHA6Ly93d3cudGVjaG5pY2FsYXJ0aWNsZXMub3JnL2luZGV4LnBocC9Db21waWxpbmdfTXlTUUxfNS4wX29uX1NvbGFyaXNfMTAKKyMKKyMgTm90ZTogdGhpcyBpcyBmb3IgMzItYml0IHN5c3RlbXMuICBJZiB5b3UgaGF2ZSBhIDY0LWJpdCBzeXN0ZW0sCisjIHVuY29tbWVudCB0aGUgYXBwcm9wcmlhdGUgZGVwZW5kZW5jeV9saWJzIGxpbmUgYmVsb3cuCisjIC0tLS0KKworIyBUaGUgbmFtZSB0aGF0IHdlIGNhbiBkbG9wZW4oMykuCitkbG5hbWU9J2xpYnN0ZGMrKy5zby42JworCisjIE5hbWVzIG9mIHRoaXMgbGlicmFyeS4KK2xpYnJhcnlfbmFtZXM9J2xpYnN0ZGMrKy5zby42LjAuMyBsaWJzdGRjKysuc28uNiBsaWJzdGRjKysuc28nCisKKyMgVGhlIG5hbWUgb2YgdGhlIHN0YXRpYyBhcmNoaXZlLgorb2xkX2xpYnJhcnk9J2xpYnN0ZGMrKy5hJworCisjIExpYnJhcmllcyB0aGF0IHRoaXMgb25lIGRlcGVuZHMgdXBvbi4KKyMgMzItYml0IHZlcnNpb246CitkZXBlbmRlbmN5X2xpYnM9Jy1sYyAtbG0gLUwvdXNyL3Nmdy9saWIgLWxnY2NfcycKKyMgNjQtYml0IHZlcnNpb246CisjZGVwZW5kZW5jeV9saWJzPSctTC9saWIvNjQgLWxjIC1sbSAtTC91c3Ivc2Z3L2xpYi82NCAtbGdjY19zJworCisjIFZlcnNpb24gaW5mb3JtYXRpb24gZm9yIGxpYnN0ZGMrKy4KK2N1cnJlbnQ9NgorYWdlPTAKK3JldmlzaW9uPTMKKworIyBJcyB0aGlzIGFuIGFscmVhZHkgaW5zdGFsbGVkIGxpYnJhcnk/CitpbnN0YWxsZWQ9eWVzCisKKyMgRmlsZXMgdG8gZGxvcGVuL2RscHJlb3BlbgorZGxvcGVuPScnCitkbHByZW9wZW49JycKKworIyBEaXJlY3RvcnkgdGhhdCB0aGlzIGxpYnJhcnkgbmVlZHMgdG8gYmUgaW5zdGFsbGVkIGluOgorbGliZGlyPScvdXNyL3Nmdy9saWInCg==